{"version":3,"file":"8968.ab735109.js","mappings":"gGAEAA,EAAOC,QAAU,CACfC,MAAO,OACPC,MAAO,OACPC,QAAS,UACTC,YAAa,cACbC,QAAS,eACTC,OAAQ,CACN,YAAa,UACbC,KAAM,WAERC,KAAM,CACJ,GAAI,UACJ,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,WAEPC,IAAK,CACH,GAAI,UACJ,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,WAEPC,OAAQ,CACN,GAAI,UACJ,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,WAEPC,MAAO,CACL,GAAI,UACJ,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,WAEPC,OAAQ,CACN,GAAI,UACJ,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,WAEPC,aAAc,CACZ,GAAI,UACJ,IAAK,WAEPC,KAAM,CACJ,GAAI,UACJ,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,WAEPC,MAAO,CACL,GAAI,UACJ,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,WAEPC,QAAS,CACP,GAAI,UACJ,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,WAEPC,KAAM,CACJ,GAAI,UACJ,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,WAEPV,KAAM,CACJ,GAAI,UACJ,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,WAEPW,OAAQ,CACN,GAAI,UACJ,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,WAEPC,OAAQ,CACN,GAAI,UACJ,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,WAEPC,KAAM,CACJ,GAAI,UACJ,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,UACL,IAAK,W,ybCxKTC,MAAMC,UAAUC,KAAO,WACrB,OAAOC,KAAKA,KAAKC,OAAS,EAC5B,EAGAC,OAAOJ,UAAUK,QAAU,SAAUC,GACnC,OAAOF,OAAOE,EAAeJ,MAAMK,OAAOD,EAAaH,OACzD,EAGAC,OAAOJ,UAAUQ,WAAa,SAAUC,GACtC,OAA6B,IAAtBP,KAAKQ,QAAQD,EACtB,EAOA,MAAME,EAAsC,GAC5CC,IAAAA,WAAiBZ,UAAUa,KAAO,SAAUC,EAAIC,GAE9C,MAAMC,EAAOd,KACPe,EAAK,SAACC,GACV,GAAIA,EAAOF,EAAKG,QAA+BH,EAAKE,OAAOE,GAAI,SAAAC,EAAAC,UAAAnB,OAD7BoB,EAAI,IAAAxB,MAAAsB,EAAA,EAAAA,EAAA,KAAAG,EAAA,EAAAA,EAAAH,EAAAG,IAAJD,EAAIC,EAAA,GAAAF,UAAAE,GAEpC,OAAOT,EAASG,KAAWK,EAC7B,CACF,EAGA,OAFAZ,EAAec,KAAK,CAAEC,MAAOT,EAAIU,OAAQZ,IACzCb,KAAK0B,MAAMf,KAAKC,EAAIG,GACbf,IACT,EAEAU,IAAAA,WAAiBZ,UAAU6B,OAAS,SAAUf,EAAIC,GAChD,IAAIE,EACJ,IAAK,MAAMa,KAAQnB,EACjB,GAAImB,EAAKH,SAAWZ,EAAU,CAC5BE,EAAKa,EAAKJ,MACV,KACF,CAEF,OAAOxB,KAAK0B,MAAMC,OAAOf,EAAIG,EAC/B,EAEAL,IAAAA,MAAYmB,UAAY,SAAUC,GAChC,MAAMC,EAAW/B,KAAKgC,MACtB,IAAK,IAAIC,EAAQ,EAAGA,EAAQF,EAAS9B,OAAQgC,IAAS,CACpD,MAAMC,EAAKH,EAASE,GACpB,GAAIH,EAAQK,IAAID,GACd,OAAOD,CAEX,CACF,ECrDO,MAAMG,EAAW,CACtBC,SAAS,EACTC,WAAW,EACXC,UAAU,EACVC,WAAW,EACXC,WAAW,EACXC,gBAAgB,EAChBC,MAAO,MACPC,OAAQC,QACRC,cAAe,CAACpB,EAAOqB,KACrB,MAAMC,EAAQC,OAAOC,KAAKH,GAC1B,MAC6B,UAA3BrB,EAAMyB,YAAYC,MACS,UAA3B1B,EAAMyB,YAAYC,MACA,IAAjBJ,EAAM/C,SAA8B,UAAb+C,EAAM,IAA+B,eAAbA,EAAM,GACxD,EAEFK,iBAAmBC,GAAUA,EAC7BC,eAAgB,EAAGf,YAAWD,YAAYiB,EAAOC,EAAMC,KACrD,MAAMC,EAAQ,CAAC,SAQf,OAPAA,EAAMpC,KAAK,KAAKrB,OAAOsD,MACnBhB,GACFmB,EAAMpC,KAAK,OAAOkC,KAEhBlB,GACFoB,EAAMpC,KAAK,SAASmC,EAAKE,QAAQ,UAE5BD,EAAME,KAAK,IAAG,EAEvBC,OAAQ,CACNN,MAAO,IAAM,UACbO,UAAW,IAAM,UACjBC,OAAQ,IAAM,UACdC,UAAW,IAAM,UACjBX,MAAO,IAAM,YAKXY,EAAM,CAACC,EAAKC,EAAY,KAAMC,OADpB9D,EAC2B,IADtB+D,EAC2BF,EAAYD,EAAII,WAAWtE,OAD5C,IAAIJ,MAAMyE,EAAQ,GAAGT,KAAKtD,GAC4B4D,EADtE,IAAC5D,EAAK+D,CAErB,EAGaE,EAAgB,CAACC,EAAUC,EAAU,CAAC,KACjD,MAAM,OAAE9B,EAAM,UAAEH,EAAS,eAAEc,EAAc,UAAEjB,EAAS,UAAEE,EAAS,SAAED,EAAQ,eAAEG,EAAc,OAAEoB,EAAM,MAAEnB,GAAU,IACxGP,KACAsC,IAEC,YAAEC,EAAW,MAAEnB,EAAK,UAAEO,EAAS,KAAEa,EAAI,MAAEtB,EAAK,UAAEW,EAAS,KAAEP,GAASe,EAElEI,EATN,GAAGX,GADeT,EAUekB,GATrBG,eAAeZ,EAAIT,EAAKsB,iBAAiBb,EAAIT,EAAKuB,iBAAiBd,EAAIT,EAAKwB,kBAAmB,KAD1F,IAACxB,EAWlB,MAAMyB,EAAWpB,EAAON,MAAQ,UAAUM,EAAON,MAAMA,MAAY,GAC7D2B,EAAY,CAAC,sCACnBA,EAAU5D,KAAK2D,GACX1C,GACF2C,EAAU5D,KAAK,sCAEbgB,GACF4C,EAAU5D,KAAK,sCAEjB,MAAM6D,EAAiB7B,EAAenB,EAAUoB,EAAOqB,EAAenB,GAEtE,IACMpB,EACEwB,EAAON,MACTZ,EAAOyC,eAAe,MAAMD,OAAqBD,GAEjDvC,EAAOyC,eAAeD,GAEftB,EAAON,MAChBZ,EAAO0C,MAAM,MAAMF,OAAqBD,GAExCvC,EAAO0C,MAAMF,EAEjB,CAAE,MAAOG,GACP3C,EAAO4C,IAAIJ,EACb,CAEA,GAAItB,EAAOC,UAAW,CACpB,MAAM0B,EAAS,UAAU3B,EAAOC,UAAUA,wBAC1CnB,EAAOD,GAAO,gBAAiB8C,EAAQ1B,EACzC,MACEnB,EAAOD,GAAO,aAAcoB,GAG9B,GAAID,EAAOE,OAAQ,CACjB,MAAMyB,EAAS,UAAU3B,EAAOE,OAAOY,wBACvChC,EAAOD,GAAO,gBAAiB8C,EAAQb,EACzC,MACEhC,EAAOD,GAAO,aAAciC,GAG9B,GAAItB,GAASb,EACX,GAAIqB,EAAOR,MAAO,CAChB,MAAMmC,EAAS,UAAU3B,EAAOR,MAAMA,EAAOS,yBAC7CnB,EAAc,MAAE,gBAAiB6C,EAAQnC,EAC3C,MACEV,EAAc,MAAE,aAAcU,GAIlC,GAAIQ,EAAOG,UAAW,CACpB,MAAMwB,EAAS,UAAU3B,EAAOG,UAAUA,wBAC1CrB,EAAOD,GAAO,gBAAiB8C,EAAQxB,EACzC,MACErB,EAAOD,GAAO,aAAcsB,GAG1BvB,IACFE,EAAOyC,eAAe,SACtBzC,EAAO8C,QACP9C,EAAO+C,YAGT,IACE/C,EAAO+C,UACT,CAAE,MAAOJ,GACP3C,EAAO4C,IAAI,gBACb,GAGWI,EAAa,KACxBC,OAAe,OAAIzD,EAEnB,MAAM0D,EAAiB,UAAYhG,UAAUiG,KAC7C,UAAYjG,UAAUiG,KAAO,SAAUhD,GACrC,GAAIX,EAASC,UAAYD,EAASU,cAAc9C,KAAM+C,GAAQ,CAC5D,MAAMiD,EAAUC,KAAKC,MACfzB,EAAW,CACfjB,MAAO,GAAGxD,KAAKmD,YAAYC,SAASpD,KAAKkB,IAAMlB,KAAKmG,OACpDH,QAASA,EACTrB,YAAa,IAAIsB,KAAKD,GACtBjC,UAAW/D,KAAKoG,aAChBxB,KAAM7B,GAGR,IAAIsD,EACJ,IACEA,EAAgBP,EAAeQ,MAAMtG,KAAMoB,UAC7C,CAAE,MAAOmE,GACPd,EAASnB,MAAQiC,CACnB,CAMA,OAJAd,EAASR,UAAYjE,KAAKoG,aAC1B3B,EAASf,KAAOuC,KAAKC,MAAQzB,EAASuB,QAEtCxB,EAAcC,GACP4B,CACT,CACE,OAAOP,EAAeQ,MAAMtG,KAAMoB,UAEtC,G,4FC9IF,MAAMmF,EAAc,CAAC,EAIrB,SAASC,EAAoBxD,GAC3B,MAAQ,GAAEA,EAAMyD,aAAazD,EAAM0D,SAAS1D,EAAM2D,OACpD,CAmDA,MAAMC,UAA0BC,EAAAA,EAC9B,gBAAOC,CAAUC,GACf/G,KAAKgH,UAAU,oBAAqB,WAAY,aAAc,SAAU,SAAU,aAClFhH,KAAKiH,UAAU,OAAQF,EACzB,CAGAG,OAAS,EAETC,uBAAAA,CAAwBnE,GACtB,MAAMoE,EAAWZ,EAAoBxD,GAC/BqE,EAAad,EAAYa,GAC/B,GAAIC,EAEF,OAAIA,EAAWC,UAAYD,EAAWE,MAAMC,MAAQ,GAAKH,EAAWE,MAAME,OAAS,EAC1EJ,EAAWE,WAEpB,GAlENG,eAA4CC,GAAuD,IAAtD,gBAAEC,GAAkDD,EAE/F,GAAsB,oBAAX9B,OACT,OAIF,MAAM,gBAAEgC,SAA0B,yCAC5B,oBAAEC,SAA8BD,EAAgBE,EAAAA,EAAuBC,UAEvEC,EAAqBA,KACOhF,OAAOiF,OAAO3B,GAAa4B,MAAKC,IAAA,IAAC,SAAEd,GAAUc,EAAA,YAAkBC,IAAbf,CAAsB,KAEtGM,GACF,EAGF3E,OAAOiF,OAAOI,EAAAA,IAAsBC,SAASC,IAC3CvF,OAAOiF,OAAOO,EAAAA,IAAqBF,SAAS9B,IAC1CxD,OAAOiF,OAAOQ,EAAAA,IAAOH,SAAS7B,IAC5B,MAAMU,EAAWZ,EAAoB,CACnCC,YACAE,MAAO6B,EACP9B,UAEIiC,EAAUb,EAAoBrB,GAAW,CAC7CE,MAAO6B,EACP9B,QACAc,MAAOoB,EAAAA,KAEHC,EAAM,IAAIC,MAChBD,EAAIE,IAAO,sBAAqBC,mBAAmBL,KACnDE,EAAII,OAAS,KACX1C,EAAYa,GAAUE,UAAW,EACjCW,GAAoB,EAEtBY,EAAIK,QAAU,KACZ3C,EAAYa,GAAUE,UAAW,EACjCW,KACAkB,EAAAA,EAAAA,IAAiB,IAAIC,MAAO,wBAAuBhC,gBAAwB,CAAEiC,MAAO,CAAEN,IAAKF,EAAIE,MAAQ,EAEzGxC,EAAYa,GAAY,CACtBG,MAAOsB,EACR,GACD,GACF,GAEN,CAsBSS,CAA8B,CACjC1B,gBAAiBA,IAAM5H,KAAKuJ,QAAQ,SAAUvJ,OAElD,CAEAwJ,iBAAAA,GACE,OAAOxJ,KAAKyJ,SAAS/H,MAClBgI,QACAC,SACCC,aAAaC,MAAMC,GAAeA,EAAWC,YAAc/J,MAAM+J,WACvE,CAEAC,QAAAA,GACE,MAAO,IACFC,MAAMD,WACT9C,OAAQlH,KAAKkH,OAEjB,CAEAgD,QAAAA,GACE,MAAO,IACFD,MAAMC,WACThD,OAAQlH,KAAKkH,OAEjB,EAGF,U,0BC/GA,MAAMiD,UAAkBzJ,IAAAA,MACtB,gBAAOoG,CAAUsD,GACfpK,KAAKgH,UAAU,YAAa,YAC5BhH,KAAKiH,UAAU,QAASmD,EAC1B,EAOF,UCXA,MAAMC,UAAgB3J,IAAAA,MACpB,gBAAOoG,CAAUsD,GACfpK,KAAKgH,UAAU,UAAW,WAC1BhH,KAAKiH,UAAU,QAASmD,EAC1B,EAMF,U,0BCCAE,EAAAA,EAAMxD,UAAUyD,EAAAA,EAAMC,EAAAA,EAAOC,EAAAA,GAC7BA,EAAAA,EAAY3D,UAAUwD,EAAAA,EAAOI,EAAAA,GAC7BA,EAAAA,EAAsB5D,YACtB6D,EAAAA,EAAQ7D,UAAUyD,EAAAA,GAClB3D,EAAkBE,UAAUyD,EAAAA,GAC5BJ,EAAUrD,UAAUwD,EAAAA,GACpBD,EAAQvD,UAAUwD,EAAAA,GAClBC,EAAAA,EAAKzD,UAAU6D,EAAAA,EAAS/D,EAAmB0D,EAAAA,GClBR,cAA/BM,SAASC,SAASC,UACpBlF,I,iFCAF,MAAMmF,EAASC,EAAAA,GAAMD,SACfE,EAAwB,qBAEvB,SAASC,IACd,MAAOC,EAAcC,GAAmBC,EAAAA,UAAeC,EAAAA,EAAAA,OACjDC,GAAoBC,EAAAA,EAAAA,IAAqBZ,SAASa,iBAClDC,GAAiBC,EAAAA,EAAAA,MAEjBC,EAAUP,EAAAA,QAAa,MACvBC,EAAAA,EAAAA,MACFI,EAAeG,KAAKjB,UAEpBW,EAAkBM,KAAKjB,SAASa,gBAClC,IAuBF,OApBAJ,EAAAA,WAAgB,KACd,MAAMS,EAAkBA,KAClBf,KACEO,EAAAA,EAAAA,MACFV,SAASmB,KAAKC,UAAUC,IAAIhB,GAE5BL,SAASmB,KAAKC,UAAUE,OAAOjB,IAGnCG,GAAgBE,EAAAA,EAAAA,MAAsB,EAKxC,OAFAV,SAASuB,iBAAiB,yBAA0BL,GACpDlB,SAASuB,iBAAiB,mBAAoBL,GACvC,KACLlB,SAASwB,oBAAoB,yBAA0BN,GACvDlB,SAASwB,oBAAoB,mBAAoBN,EAAgB,CAClE,GACA,IAEEP,GAGHc,EAAAA,EAAAA,KAACC,EAAAA,IAAM,CACL5F,MAAM,aACN,cAAY,0BACZ6F,YAAapB,EAAe,iBAAmB,aAC/CqB,aAAa,iBACbhJ,MAAO2H,EAAe,mBAAqB,cAC3CS,QAASA,EAAQ/M,QAAQ4N,SAExBtB,EAAe,mBAAqB,gBAXV,IAcjC,C,mDClCA,MAAMuB,EClBC,SACLC,GAEA,IADAjI,EAA+EtD,UAAAnB,OAAA,QAAAoI,IAAAjH,UAAA,GAAAA,UAAA,GAAG,GAElF,OAAOuL,EAAIC,MAAK,CAACC,EAAGC,IAClBpI,EAAQqI,QAAO,CAACC,EAAKC,KACnB,MAAM,OAAEC,EAAM,cAAEC,EAAgBC,EAAAA,GAAeC,KAAQJ,EACjDK,EAAsBH,IAAkBC,EAAAA,GAAeC,IAAM,GAAK,EACxE,OAAe,IAARL,GAAaH,EAAEK,GAAUJ,EAAEI,IAAWI,EAAsBN,CAAG,GACrE,IAEP,CDO2BO,CACzBtK,OAAOuK,QAAQC,EAAAA,IAASC,KAAI/F,IAAA,IAAEgG,EAAKC,GAAMjG,EAAA,MAAM,IAAKiG,EAAOD,MAAK,IAChE,CAAC,CAAET,OAAQ,WAAa,CAAEA,OAAQ,WAClCQ,KAAItF,IAAA,IAAC,IAAEuF,GAAKvF,EAAA,OAAKuF,CAAG,IAEf,SAASE,EAAmBC,GAAoC,IAAnC,MAAEpM,GAA+BoM,EACnE,MAAMjD,GAAWkD,EAAAA,EAAAA,MACXC,GAAWC,EAAAA,EAAAA,MACXC,GAAcC,EAAAA,EAAAA,KAAkBtD,EAASuD,QACzCC,GAAmBC,EAAAA,EAAAA,GAAc5M,EAAO,CAAE6M,gBAAiB,CAAC,SAAU,qBACtE,gBAAEC,IAAoBC,EAAAA,EAAAA,GAAsB,CAAEJ,qBAC9C1H,GAAQ+H,EAAAA,EAAAA,KAAiB,CAAEC,UAAW,SAAUC,YAAa,eAEnE,OACEvC,EAAAA,EAAAA,KAACwC,EAAAA,IAAQ,CACPlI,MAAOA,EACP,aAAW,SACXmI,OACEzC,EAAAA,EAAAA,KAACC,EAAAA,IAAM,CACL5F,MAAM,aACN,cAAY,sBACZ6F,YAAc,SAAQ2B,EAAYa,IAClCvC,aAAa,iBACbhJ,MAAM,gBAAeiJ,SACtB,WAGFA,UAEDuC,EAAAA,EAAAA,MAAA,OAAAvC,SAAA,EACEJ,EAAAA,EAAAA,KAAA,OAAK4C,UAAU,OAAMxC,SAClBC,EAAmBgB,KAAKwB,IACvB7C,EAAAA,EAAAA,KAAC8C,EAAAA,IAAY,CAEXC,WAAW,SACX,cAAc,gBAAeF,IAC7BtD,QAASA,KACPoC,EAASQ,EAAgB,CAAEU,WAAU,EACrCzC,UAEFJ,EAAAA,EAAAA,KAACgD,EAAAA,IAAI,CAACjM,KAAO,SAAQ8L,IAA0BD,UAAU,mCAPpDC,QAWX7C,EAAAA,EAAAA,KAACiD,EAAAA,IAAiB,KAClBN,EAAAA,EAAAA,MAAA,OAAKC,UAAU,iBAAgBxC,SAAA,EAC7BJ,EAAAA,EAAAA,KAAA,OAAK4C,UAAU,wCAAuCxC,UACpDJ,EAAAA,EAAAA,KAACkD,EAAAA,IAAS,CAACC,KAAK,QAAO/C,SAAC,YAEzBgD,EAAAA,GAAmB/B,KAAIgC,IAAsB,IAArB,MAAE9B,EAAK,MAAEkB,GAAOY,EACvC,MAAMC,EAAoBtB,EAAiBuB,qBAAqBhC,GAChE,OACEvB,EAAAA,EAAAA,KAACC,EAAAA,IAAM,CAEL5F,MAAM,OACN8I,KAAK,UACLK,OAAQF,EACR,cAAc,kBAAiB/B,IAC/BhC,QAASA,KACPyC,EAAiByB,kBAAkBlC,GAAQ+B,GACtCA,GAAmB9J,OAAOkK,OAAO,QAAS,OAAQ,CAAEC,YAAapC,GAAQ,EAC9EnB,SAEDqC,GAVIlB,EAWE,WAOvB,C,0BErFO,SAASqC,EAAiBtI,GAAoC,IAAnC,MAAEjG,GAA+BiG,EACjE,MAAM0G,GAAmBC,EAAAA,EAAAA,GAAc5M,EAAO,CAAE6M,gBAAiB,CAAC,WAC5D2B,EAA6B,SAAhBxO,EAAMgF,MAezB,OAAK2H,GAKHhC,EAAAA,EAAAA,KAACC,EAAAA,IAAM,CACL5F,MAAM,aACN0I,WAAW,SACX,cAAY,qBACZ5L,MAAO0M,EAAa,oBAAsB,mBAC1CtE,QAvBYA,KACd,MAAMlF,EAAQwJ,EAAa,QAAU,OACrC7B,EAAiB8B,iBAAiB,CAAEzJ,QAAO0J,UAAUC,EAAAA,EAAAA,IAAehC,EAAkB3H,KACtF2H,EAAiB9E,QAAQ,QAAS8E,IAClCiC,EAAAA,EAAAA,KAAiB,cAAe5J,GAAO6J,OAAM,SAEzCL,EACFtF,SAASa,gBAAgBO,UAAUE,OAAO,QAE1CtB,SAASa,gBAAgBO,UAAUC,IAAI,OACzC,EAcEM,YAAa2D,EAAa,YAAc,aAVnC,IAaX,C,eC1BA,MAAMM,EAAgC,CACpC,CAAEC,UAAWC,IAAUC,iBAAiB,EAAOC,WAAY,YAC3D,CAAEH,SAAU,IAAKE,iBAAiB,EAAOC,WAAY,SACrD,CAAEH,SAAU,IAAKE,iBAAiB,EAAOC,WAAY,QACrD,CAAEH,SAAU,IAAKE,iBAAiB,EAAMC,WAAY,SAS/C,SAASC,EAA0BlJ,GAA2E,IAA1E,MAAEjG,EAAK,eAAEoP,EAAiBA,SAAQ,WAAEC,GAAoCpJ,EACjH,MAAMqJ,GAAc1C,EAAAA,EAAAA,GAAc5M,EAAO,CAAE6M,gBAAiB,CAAC,UAE7D,OACES,EAAAA,EAAAA,MAAAiC,EAAAA,SAAA,CAAAxE,SAAA,EACEJ,EAAAA,EAAAA,KAAA,OAAK4C,UAAU,mCAAkCxC,UAC/CJ,EAAAA,EAAAA,KAAC6E,EAAAA,EAAa,CAACxP,MAAOsP,EAAatK,MAAM,aAAY+F,SAAC,aAIxDuC,EAAAA,EAAAA,MAAA,OAAKC,UAAU,+CAA8CxC,SAAA,EAC3DJ,EAAAA,EAAAA,KAAC8E,EAAAA,EAAU,CAACC,KAAM1P,EAAM2P,2BAA4B3K,MAAM,aAAauI,UAAU,gBAAexC,SAAC,gBAGjGJ,EAAAA,EAAAA,KAACwB,EAAmB,CAACnM,MAAOsP,KAC5B3E,EAAAA,EAAAA,KAACnB,EAAgB,IAChB6F,IACC1E,EAAAA,EAAAA,KAACiF,EAAAA,EAAO,CAAC5P,MAAOsP,EAAa,cAAY,wBAAwBtK,MAAM,aAAY+F,SAAC,WAItFJ,EAAAA,EAAAA,KAAC4D,EAAiB,CAACvO,MAAOsP,KAC1B3E,EAAAA,EAAAA,KAACC,EAAAA,IAAM,CACL8C,WAAW,SACX7C,YAAY,gBACZ7F,MAAM,aACN,cAAY,0BACZlD,MAAM,WACNyL,UAAU,kBACVrD,QAASkF,EACTS,WAAYP,EAAYQ,MAAMtQ,MAEhCmL,EAAAA,EAAAA,KAACoF,EAAAA,IAAI,CACHvQ,GAAG,OACHwQ,eAAe,SACfzC,UAAU,mDACV0C,YAAanB,SAKvB,CAEO,MAAMoB,EAAoBvG,EAAAA,KAC/BwF,GACA,CAACgB,EAAWC,IACVD,EAAUnQ,QAAUoQ,EAAUpQ,OAC9BmQ,EAAUf,iBAAmBgB,EAAUhB,gBACvCe,EAAUd,aAAee,EAAUf,a,oDC8ChC,MAAMgB,IAA0BC,EAAAA,EAAAA,MArGvC,SAAmCrK,GAkBhC,IAlBiC,KAClC6H,EAAO,UAAS,UAChBP,EAAY,iBAAgB,qBAC5BgD,EAAoB,UACpBC,EAAS,kBACTC,EAAiB,wBACjBC,GAA0B,EAAK,kBAC/BC,EAAoBA,SAAQ,kBAC5BC,EAAoBA,UAUrB3K,EACC,MAAM,iBAAE0G,IAAqBkE,EAAAA,GAAAA,KACvBC,EAAsBnH,EAAAA,SAAc,IAAMgD,GAAkBoE,eAAe,IAAM,MAAM,CAACpE,KACxF,mBAAEqE,EAAkB,wBAAEC,IAA4BC,EAAAA,EAAAA,KAAsBV,GACxE9H,GAAakE,EAAAA,EAAAA,GAAckE,EAAqB,CACpDjE,gBAAiB,CAAC,YAAa,gBAE3B,WAAEsE,EAAaC,EAAAA,GAAWC,OAAU3I,GAAYT,SAAW,CAAC,GAC5D,UAAEqJ,IAAcC,EAAAA,GAAAA,GAAiB,CACrC7I,aACA8I,cAAejB,KAGX,WACJkB,EAAU,8BACVC,EAA6B,wBAC7BC,EAAuB,wBACvBC,EAAuB,WACvBC,EAAU,gCACVC,IACEC,EAAAA,GAAAA,GAAmC,CAAErJ,aAAY8H,eAC/C,eAAEwB,EAAc,2BAAEC,EAA0B,sBAAEC,EAAqB,sBAAEC,IACzEC,EAAAA,EAAAA,IAAyB,CACvBjB,aACAM,aACAY,cAAeX,IAGbY,EAAkBV,EAAwB,CAAEpB,YAAW+B,YAAa7J,GAAY8J,UAAWrB,eAC3FsB,EAAkBd,EAAwBnB,GAUhD,OACElD,EAAAA,EAAAA,MAAAiC,EAAAA,SAAA,CAAAxE,SAAA,EACEJ,EAAAA,EAAAA,KAAC+H,EAAAA,IAAY,CACXlC,UAAWA,EACX1C,KAAMA,EACN6E,WAAY,EACZC,UAAUC,EAAAA,EAAAA,MAAsB,UAAY,OAC5CJ,gBAAiBA,EACjBH,gBAAiBA,EACjBQ,kBAAmBpK,GAAYqK,WAAa,GAC5CC,kBAAmBtK,GAAY8J,WAAa,KAC5CxB,mBAAoBA,EACpBiC,iBAAkBxC,GAAqBa,EAAY5I,GAAYqK,eAAYpM,EAC3EiK,kBAAoB1E,IAClBgG,EAAsBhG,GACtB0E,IAAoB1E,EAAM,EAE5BgH,uBAAwBA,KAClB1C,GAAWyB,EAA2BkB,MAAM,EAElDxC,kBAAmBA,EACnByC,0BAA2B1M,IAAkC,IAAjC,MAAEwF,GAA0BxF,EACtDuK,EAAwB/E,EAAmB,EAE7CqE,qBAAsBA,EACtB8C,iBAAkBnK,SAASmB,KAC3BkD,UAAWA,EACX+F,mBAAoB9C,EACpBE,wBAAyBA,IAG1BhI,IACCiC,EAAAA,EAAAA,KAAC4I,EAAAA,IAAe,CACdC,YAAavB,EACbO,UAAW9J,GAAY8J,UACvBf,WAAYA,EACZO,eA5CRhM,eAAuCQ,GACrC,MAAMiN,EAAqBtB,EAAsB3L,EAAOgM,WACxD,IAAKiB,EAAoB,aAEH3B,EAAgC2B,IACzCzB,EAAeyB,EAAoB7C,EAClD,EAuCQiB,WAAYA,MAKtB,I,4BC7GA,SAAS6B,GACPC,EACAC,EACA5Q,GAEA,GAAuB,QAAnB4Q,EAAUlS,KAAgB,CAC5B,MAAMmS,EAAU7Q,GAAS8Q,MAAQ,GACV,IAAnBD,EAAQtV,QACVsV,EAAQhU,KAAK,IAEfgU,EAAQhN,SAAQ,SAAUkN,IAf9B,SAA4BJ,EAA+BI,GACzD,OAAOJ,EAAMlN,MAAKR,IAAA,IAAC,SAAE+N,GAAU/N,EAAA,OAC7B+N,EAASvN,MAAMrG,GAAYA,EAAQ6T,OAASC,EAAAA,GAAcC,KAAO/T,EAAQ2T,OAASA,GAAK,GAE3F,EAYWK,CAAmBT,EAAOI,IAC7BJ,EAAM9T,KAAK,CACTkG,OAAQsO,EAAAA,GAAoBT,UAC5BI,SAAU,CACR,CACEC,KAAMC,EAAAA,GAAcC,IACpBJ,UAKV,GACF,MACEJ,EAAM9T,KAAK,CACTkG,OAAQsO,EAAAA,GAAoBT,UAC5BI,SAAU,CACR,CACEC,KAAO,cAAgBL,EAAUlS,KACjC4S,OAAQV,EAAUW,cAK5B,CAEA,SAASC,GAA4BC,GAQnC,MAPqB,CACnBC,YAAaC,EAAAA,GAAiBC,YAC9BC,WAAYF,EAAAA,GAAiBG,WAC7BC,kBAAmBJ,EAAAA,GAAiBK,kBACpCC,KAAMN,EAAAA,GAAiBO,UACvBC,KAAMR,EAAAA,GAAiBS,WAELX,EACtB,CAcO,MAAMY,GAAwB,SACnCC,EACAC,EACAvS,GAEA,MAAM2Q,EAAQ2B,EAAYE,OAAO,GAAG7B,MAC9B3L,EAAQsN,EAAYE,OAAO,GAlBnC,IAAsCC,EAoBpCzN,EAAMyN,OApB8BA,EAoBOF,EAASE,MAnB9B,CACpBC,OAAQC,EAAAA,GAAUC,OAClBC,WAAYF,EAAAA,GAAUG,WACtBC,YAAaJ,EAAAA,GAAUK,aAEJP,IAAwCE,EAAAA,GAAUC,QAgBvEL,EAASU,WACNC,QAAQtC,GAAcA,EAAUuC,WAAaC,EAAAA,GAASC,QACtDxP,SAAS+M,IACRF,GAAeC,EAAOC,EAAW5Q,EAAQ,IAG7C,MAAMsT,EAAWf,EAASe,SAAStK,KAAI,SAAUuK,GAC/C,MAAO,CACLtC,KAAO,YAAcsC,EAAQ7U,KAC7B4S,OAAQiC,EAAQhC,YAAc,GAC9BiC,MAAOD,EAAQC,OAAS,GAE5B,IACA7C,EAAM9T,KAAK,CACTkG,OAAQsO,EAAAA,GAAoBrM,MAC5BgM,SAAU,CACR,CACEC,KAAMO,GAA4Be,EAASd,OAC3C6B,SAAUA,MAKhBf,EAASU,WACNC,QAAQtC,GAAcA,EAAUuC,WAAaC,EAAAA,GAASK,QACtD5P,SAAS+M,IACRF,GAAeC,EAAOC,EAAW5Q,EAAQ,IAG7CsS,EAAYvP,OAASiC,EAAMjC,OAASsO,EAAAA,GAAoBrM,OAAS2L,EAAMpV,OAAS,GAAK8V,EAAAA,GAAoBT,SAC3G,EAEa8C,GAAW,SAAkBnB,GACxC,MAAMvS,EAAU,CAAC,EACX2Q,EAAgC,GAEtC4B,EAASU,WACNC,QAAQtC,GAAcA,EAAUuC,WAAaC,EAAAA,GAASC,QACtDxP,SAAS+M,IACRF,GAAeC,EAAOC,EAAW5Q,EAAQ,IAG7C,MAAMsT,EAAWf,EAASe,SAAStK,KAAI,SAAUuK,GAC/C,MAAO,CACLtC,KAAO,YAAcsC,EAAQ7U,KAC7B4S,OAAQiC,EAAQhC,YAAc,GAC9BiC,MAAOD,EAAQC,OAAS,GAE5B,IAiBA,OAhBA7C,EAAM9T,KAAK,CACTkG,OAAQsO,EAAAA,GAAoBrM,MAC5BgM,SAAU,CACR,CACEC,KAAMO,GAA4Be,EAASd,OAC3C6B,SAAUA,MAKhBf,EAASU,WACNC,QAAQtC,GAAcA,EAAUuC,WAAaC,EAAAA,GAASK,QACtD5P,SAAS+M,IACRF,GAAeC,EAAOC,EAAW5Q,EAAQ,IAGtC2Q,CACT,E,wCC7IO,IAAKgD,GAAW,SAAXA,GAAW,OAAXA,EAAW,cAAXA,EAAW,gBAAXA,CAAW,MAKXC,GAAgB,SAAhBA,GAAgB,OAAhBA,EAAAA,EAAgB,uBAAhBA,EAAAA,EAAgB,2BAAhBA,CAAgB,K,gDCPrB,MAAMC,EAAyB,CACpCvQ,SAAUA,IAAM,qHAChBZ,SAAU,e,gDCFL,MAAMoR,EAA6B,CACxCxQ,SAAUA,IAAM,0LAChBZ,SAAU,oB,mECFL,IAAKqR,EAAW,SAAXA,GAAW,OAAXA,EAAAA,EAAW,eAAXA,EAAAA,EAAW,uCAAXA,EAAAA,EAAW,uBAAXA,CAAW,MAMhB,SAASC,IACd,OAAIC,eAAeC,eAAuBH,EAAYI,KAEnB,IAA/BF,eAAeG,YACVL,EAAYM,SAGdN,EAAYO,gBACrB,CAKO,SAASC,EAAcjW,GAC5B,MAAM,SAAEkW,EAAWrT,OAAOgF,SAASqO,SAAQ,MAAEC,EAAQtT,OAAOgF,SAASuD,OAAM,iBAAEgL,GAAmB,GAASpW,EAEzG6C,OAAOkK,OAAO,MAAO,YAAc,GAAEmJ,IAAWC,EAAMlZ,OAAS,IAAM,KAAKkZ,EAAME,QAAQ,MAAO,OAC/FxT,OAAOkK,OAAO,QAAS,aAEnBqJ,GAAoBV,MAAqBD,EAAYM,UACvDlT,OAAOyT,UAAUC,MAAMhY,MAAK,IAAM+X,SAASE,iBAE/C,C,0rCC5BO,MAAMC,EAAqC,CAChDzR,SAAUA,IAAM,wDAChBZ,SAAU,6B,+ECyBL,MAAMsS,EAAS,CAAEC,KAAI,EAAEC,W,y6BCtBvB,SAASC,EAAiB7W,GAC/B,MAAM,aAAE8W,GAAe,EAAK,mBAAEC,GAAqB,GAAS/W,GAAS,CAAC,EAChEgX,EAAgB3O,EAAAA,OAAayO,GAC7BjP,GAAWkD,EAAAA,EAAAA,MAEXkM,EAAkB5O,EAAAA,aAAkB,KACxC6O,EAAAA,GAAuB,CAAEhB,SAAUrO,EAASqO,SAAUC,MAAOtO,EAASuD,QAAS,GAC9E,CAACvD,EAASqO,SAAUrO,EAASuD,SAQhC,OANA/C,EAAAA,WAAgB,KACT0O,IACDC,EAAcnb,SAASob,IAC3BD,EAAcnb,SAAU,EAAI,GAC3B,CAACkb,EAAoBE,EAAiBH,IAElCG,CACT,C,kICjBO,IAAKE,EAAc,SAAdA,GAAc,OAAdA,EAAc,SAAdA,EAAc,eAAdA,EAAc,kBAAdA,EAAc,UAAdA,EAAc,YAAdA,EAAc,UAAdA,EAAc,eAAdA,EAAc,kBAAdA,EAAc,cAAdA,CAAc,MAYdC,EAAmB,SAAnBA,GAAmB,OAAnBA,EAAmB,qBAAnBA,EAAmB,YAAnBA,CAAmB,MAKnBC,EAAa,SAAbA,GAAa,OAAbA,EAAa,SAAbA,EAAa,SAAbA,CAAa,MAKbC,EAAkB,SAAlBA,GAAkB,OAAlBA,EAAkB,WAAlBA,EAAkB,UAAlBA,CAAkB,MAKvB,MAAMC,EAA2B,CACtC,CAACD,EAAmBE,QAAS,UAC7B,CAACF,EAAmBG,OAAQ,UAGvB,IAAKC,EAAmB,SAAnBA,GAAmB,OAAnBA,EAAmB,cAAnBA,EAAmB,YAAnBA,CAAmB,MAKnBC,EAAoB,SAApBA,GAAoB,OAApBA,EAAAA,EAAoB,iBAApBA,EAAAA,EAAoB,aAApBA,EAAAA,EAAoB,iBAApBA,EAAAA,EAAoB,+BAApBA,EAAAA,EAAoB,iCAApBA,EAAAA,EAAoB,6BAApBA,EAAAA,EAAoB,uBAApBA,CAAoB,MA8IpBC,EAAQ,SAARA,GAAQ,OAARA,EAAQ,gBAARA,EAAQ,gBAARA,EAAQ,kBAARA,EAAQ,sBAARA,EAAQ,kBAARA,EAAQ,wBAARA,EAAQ,8BAARA,EAAQ,wBAARA,EAAQ,0BAARA,EAAQ,YAARA,EAAQ,gBAARA,EAAQ,cAARA,EAAQ,sBAARA,EAAQ,gBAARA,EAAQ,0BAARA,EAAQ,8BAARA,EAAQ,8BAARA,EAAQ,wCAARA,EAAQ,4BAARA,EAAQ,sCAARA,EAAQ,cAARA,CAAQ,MAwBRC,EAAO,SAAPA,GAAO,OAAPA,EAAAA,EAAO,iBAAPA,EAAAA,EAAO,6BAAPA,EAAAA,EAAO,qBAAPA,EAAAA,EAAO,yBAAPA,EAAAA,EAAO,iBAAPA,CAAO,MA8CPC,EAAU,SAAVA,GAAU,OAAVA,EAAAA,EAAU,2BAAVA,EAAAA,EAAU,+BAAVA,EAAAA,EAAU,mCAAVA,EAAAA,EAAU,qCAAVA,EAAAA,EAAU,yCAAVA,EAAAA,EAAU,mCAAVA,EAAAA,EAAU,yCAAVA,CAAU,K,6HCtPtB,MAAMC,EAAa,CAAC,EACdC,EAAmB,CAAC,EAAC,IAEtBC,EAAa,SAAbA,GAAa,OAAbA,EAAAA,EAAa,mBAAbA,EAAAA,EAAa,eAAbA,CAAa,EAAbA,GAAa,IAKlB,SAASC,EAAwBC,EAAkBC,GAI/CvV,OAAOwV,OAAOlS,iBAAiBgS,EAAWC,EAE9C,CAwBO,SAASE,EAAc3T,GAcqC,IAdH,SAC9DK,EAAQ,QACRuT,EAAO,cACPC,EAAa,SACbpU,EAAQ,iBACR+B,EAAmB+R,EAAuB,iBAC1CO,GAAmB,EAAK,eACxBC,GAAiB,GAO8C/T,EAC/D,MAAMgU,GAAsBC,EAAAA,EAAAA,OACrB5I,EAAW6I,GAAgBxQ,EAAAA,UAAe,IAC1CyQ,EAASC,GAAc1Q,EAAAA,UAAe,GACvC2Q,GAAeC,EAAAA,EAAAA,KAEfC,EAAcA,KAClBX,MACAQ,GAAW,QAEW1T,IAAlBmT,IAIAP,EAAcO,KAAmBP,EAAckB,OACjDtW,OAAOuW,wBACPvW,OAAOwW,yBAGLpB,EAAcO,KAAmBP,EAAcqB,QACjDX,EAAoB9G,MAClBxI,EAAAA,EAAAA,KAACkQ,EAAAA,GAAY,CAACC,YAAa,IAAK/P,UAC9BuC,EAAAA,EAAAA,MAACO,EAAAA,GAAS,CAACN,UAAU,gBAAexC,SAAA,CAAC,2EACoCJ,EAAAA,EAAAA,KAAA,SAAM,sCACnE,KACVA,EAAAA,EAAAA,KAAA,QAAM4C,UAAU,2BAA2BrD,QAASA,IAAM/F,OAAOgF,SAAS4R,SAAShQ,SAAC,qBAE5E,IAAI,iCAKpB,EAGIiQ,EAAahV,UACjB,GAAIqT,EAAM3T,GACR,OAAO2T,EAAM3T,GAGfyU,GAAa,GAEb,IACEd,EAAM3T,SAAkBS,EAAAA,EAAAA,GAAgBG,EAC1C,CAAE,MAAO1E,GACP6F,EAAiB7F,GACjB4Y,GACF,CAAE,QACIF,KACFH,GAAa,EAEjB,CAEA,OAAOd,EAAM3T,EAAS,EAGxBiE,EAAAA,WAAgB,KACVoQ,GACFiB,GACF,GAGC,CAACjB,IAEJ,MAAMkB,EAAe5B,EAAM3T,GAC3B,GAAIsU,EAAgB,CAClB,GAAIV,EAAY5T,GAAW,MAAM4T,EAAY5T,GAC7C,IAAKuV,EACH,MAAM3U,IACH4U,MAAMC,GAAS9B,EAAM3T,GAAYyV,IACjCtM,OAAOuM,IACNZ,IACAlB,EAAY5T,GAAY0V,CAAG,GAGnC,CAEA,MAAO,CAACH,GAAgB,KAAM,CAAE3J,YAAW0J,aAAYZ,WAIzD,CAOO,SAAS9J,EACd+K,GAEA,IADAC,EAAyB5b,UAAAnB,OAAA,QAAAoI,IAAAjH,UAAA,GAAAA,UAAA,GAAG,KAE5B,OAAO,SAA0B4B,GAC/B,OACEqJ,EAAAA,EAAAA,KAAChB,EAAAA,SAAc,CAAC2R,SAAUA,EAASvQ,UACjCJ,EAAAA,EAAAA,KAAC0Q,EAAS,IAAK/Z,KAGrB,CACF,C,gDC9JA,MAAMia,EAAiB,EAEhB,SAASpV,EAA6BG,GAAyC,IAAbkV,EAAO9b,UAAAnB,OAAA,QAAAoI,IAAAjH,UAAA,GAAAA,UAAA,GAAG,EAWjF,OAVe4G,IAAWuI,OAAM7I,UAC9B,GAAIwV,EAAUD,EACZ,MAAMH,EAKR,aAFM,IAAIK,SAASC,GAAMC,WAAWD,EAAG,IAAOF,KAEvCrV,EAAgBG,EAAUkV,EAAU,EAAE,GAIjD,C,yGCEA,MAAMI,UAAyC3S,EAAAA,EAC7C4S,YAAcC,EAAAA,GAAkBC,MAGhCra,KAAO,QAEPD,WAAAA,CAAY+E,EAAwBxG,GAClCuI,MAAM/B,EAAQxG,GACd1B,KAAK0d,cAAgB1d,KAAK0d,cAAc/c,KAAKX,MAC7CA,KAAK2d,OAAS3d,KAAK2d,OAAOhd,KAAKX,MAC/BA,KAAK4d,QAAU,CACb,IAAIC,EAAAA,EACF,KACA,IAAM7d,KAAK+C,MAAM+a,KACjB,IAAM9d,KAAK+C,MAAMgb,IACjB/d,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,KACA,IAAM7d,KAAK+C,MAAMib,KACjB,IAAMhe,KAAK+C,MAAMkb,IACjBje,KAAK2d,OACL3d,KAAK0B,QAGT1B,KAAKmX,MAAMnX,KAAKke,uBAClB,CAEAC,WAAAA,GACE,MAAO,CACLC,OAAQ,CACN5W,MAAO,EACP0Q,MAAOlY,KAAKqe,yBAAyBC,gBAAgBC,OAAO5H,MAGlE,CAEAuH,qBAAuBA,KAAA,CAASM,EAAG,CAAC,KAAM,MAAOC,EAAG,CAAC,KAAM,QAE3Df,aAAAA,CAAcgB,GACZ,MAAM,GAAEZ,EAAE,GAAEE,EAAE,GAAED,EAAE,GAAEE,GAAOje,KAAK2e,OAC1BC,GAAYC,EAAAA,EAAAA,IAAiB,CAAEf,KAAIE,KAAID,KAAIE,OAC3Ca,GAAcC,EAAAA,EAAAA,IAAoB,CAAEC,UAAWhf,KAAK+C,MAAMqb,OAAO5W,SAAUoX,IAEjFF,EAAQO,UAAUH,EAAYN,EAAGM,EAAYL,GAC7CC,EAAQQ,YACRR,EAAQS,IAAI,UAAW,SACvBT,EAAQS,IAAI,YAAanf,KAAK+C,MAAMqb,OAAO5W,OAC3CkX,EAAQS,IAAI,cAAenf,KAAK+C,MAAMqb,OAAOlG,OAE7C,MAAMkH,EAAQC,KAAKC,GAAK,EAGxBZ,EAAQQ,YACRR,EAAQa,OAAOX,EAAUd,GAAIc,EAAUb,IACvCW,EAAQc,OAAOZ,EAAUZ,GAAIY,EAAUX,IACvCS,EAAQe,SAER,MAAMC,EAAYL,KAAKM,MAAMf,EAAUX,GAAKW,EAAUb,GAAIa,EAAUZ,GAAKY,EAAUd,IAC7E8B,EAAIP,KAAKQ,IARL,GAQaR,KAAKS,IAAIV,IAE1BW,EAASL,EAAYN,EACrBY,EAAOpB,EAAUd,GAAKuB,KAAKS,IAAIC,GAAUH,EACzCK,EAAOrB,EAAUb,GAAKsB,KAAKa,IAAIH,GAAUH,EACzCO,EAAST,EAAYN,EACrBgB,EAAOxB,EAAUd,GAAKuB,KAAKS,IAAIK,GAAUP,EACzCS,EAAOzB,EAAUb,GAAKsB,KAAKa,IAAIC,GAAUP,EAE/ClB,EAAQQ,YACRR,EAAQa,OAAOS,EAAMC,GACrBvB,EAAQc,OAAOZ,EAAUd,GAAIc,EAAUb,IACvCW,EAAQc,OAAOY,EAAMC,GACrB3B,EAAQe,SACRf,EAAQO,WAA2B,EAAjBH,EAAYN,GAAyB,EAAjBM,EAAYL,GAE9Cze,KAAKsgB,yBACPtgB,KAAKugB,aAAa7B,EAEtB,CAEA8B,MAAAA,CAAOhC,EAAWC,GAChBze,KAAK+C,MAAM+a,IAAMU,EACjBxe,KAAK+C,MAAMib,IAAMQ,EACjBxe,KAAK+C,MAAMgb,IAAMU,EACjBze,KAAK+C,MAAMkb,IAAMQ,CACnB,CAEAd,MAAAA,CAAMhW,GAAqD,IAApD,KAAEgO,EAAI,KAAE8K,EAAI,KAAEC,GAAoC/Y,EAC1C,MAATgO,GACF3V,KAAK+C,MAAM+a,IAAM2C,EACjBzgB,KAAK+C,MAAMgb,IAAM2C,IAEjB1gB,KAAK+C,MAAMib,IAAMyC,EACjBzgB,KAAK+C,MAAMkb,IAAMyC,EAErB,CAEAC,QAAAA,CAASC,GACP,OAAI3W,MAAM4W,sCACNC,EAAAA,GAAKC,kBAAkBH,EAAKjC,OAAQ3e,KAAK2e,SAAW,IAGjD1U,MAAM0W,SAASC,GACxB,EAGFtD,EAAMxd,UAAUkhB,YAAc,CAC5BC,OAAQ,CAAC,CAAEtL,KAAM,OAAQvS,KAAM,YAGjC,S,yGC7GA,MAAM8d,UAAuDvW,EAAAA,EAC3D4S,YAAcC,EAAAA,GAAkB2D,QAEhCC,oBAAuD,KAEvDhe,KAAO,QAEPie,UAA2B,KAE3BC,WAAa,CACXC,aAAc,GACdC,kBAAkB,GAGpBre,WAAAA,CAAY+E,EAAwBxG,GAClCuI,MAAM/B,EAAQxG,GACd1B,KAAKohB,qBAAsBK,EAAAA,EAAAA,GAAoB7W,SAAS8W,cAAc,WACtE1hB,KAAK2hB,cACP,CAEAxD,WAAAA,GACE,MAAM,gBAAEG,GAAoBte,KAAKqe,yBACjC,MAAO,CACLuD,KAAMtD,EAAgBuD,uBACtBzD,OAAQ,CACN5W,MAAO,EACP0Q,MAAOoG,EAAgBC,OAAOH,QAEhC0D,kBAAkB,EAEtB,CAEAH,YAAAA,GACE3hB,KAAKshB,WAAWC,aAAevhB,KAAK+C,MAAM6e,KACX,IAA3B5hB,KAAK+C,MAAM6e,KAAK3hB,OAClBD,KAAKshB,WAAWE,iBAAgD,OAA7BxhB,KAAK+C,MAAM6e,KAAKvhB,MAAM,GAEzDL,KAAKshB,WAAWE,kBAAmB,CAEvC,CAEAO,mBAAAA,GAIE,OAHI/hB,KAAK+C,MAAM6e,OAAS5hB,KAAKshB,WAAWC,cACtCvhB,KAAK2hB,eAEA3hB,KAAKshB,WAAWE,gBACzB,CAEA9D,aAAAA,CAAcgB,GACa,MAArB1e,KAAK+C,MAAMqb,QACbM,EAAQS,IAAI,cAAenf,KAAK+C,MAAMqb,OAAOlG,OAE/CwG,EAAQS,IAAI,UAAW,SACvBT,EAAQS,IAAI,WAAY,SAExB,MAAMkC,EAAY,IAAIW,QAChB,OAAEC,GAAWjiB,KAAK+C,MAGxB,IAAImf,EACJ,GAHAxD,EAAQQ,YACRmC,EAAU9B,OAAOvf,KAAKmiB,GAAGF,EAAO,GAAG,IAAKjiB,KAAKoiB,GAAGH,EAAO,GAAG,KAEtDA,EAAOhiB,OAAS,EAAG,CACrB,IAAKiiB,EAAI,EAAGA,EAAID,EAAOhiB,OAAS,EAAGiiB,IAAK,CACtC,MAAMG,GAAMriB,KAAKmiB,GAAGF,EAAOC,GAAG,IAAMliB,KAAKmiB,GAAGF,EAAOC,EAAI,GAAG,KAAO,EAC3DI,GAAMtiB,KAAKoiB,GAAGH,EAAOC,GAAG,IAAMliB,KAAKoiB,GAAGH,EAAOC,EAAI,GAAG,KAAO,EACjEb,EAAUkB,iBAAiBviB,KAAKmiB,GAAGF,EAAOC,GAAG,IAAKliB,KAAKoiB,GAAGH,EAAOC,GAAG,IAAKG,EAAIC,EAC/E,CACAjB,EAAUkB,iBACRviB,KAAKmiB,GAAGF,EAAOC,GAAG,IAClBliB,KAAKoiB,GAAGH,EAAOC,GAAG,IAClBliB,KAAKmiB,GAAGF,EAAOC,EAAI,GAAG,IACtBliB,KAAKoiB,GAAGH,EAAOC,EAAI,GAAG,IAE1B,MACE,IAAK,MAAMM,KAASP,EAClBZ,EAAU7B,OAAOxf,KAAKmiB,GAAGK,EAAM,IAAKxiB,KAAKoiB,GAAGI,EAAM,KAIlDxiB,KAAK+C,MAAM+e,kBACbT,EAAUoB,YAEZziB,KAAKqhB,UAAYA,EACbrhB,KAAK+C,MAAM6e,MAAQ5hB,KAAK+hB,wBAC1BrD,EAAQS,IAAI,YAAanf,KAAK+C,MAAM6e,MACpClD,EAAQkD,KAAKP,IAEXrhB,KAAK+C,OAAOqb,QAAQ5W,QACtBkX,EAAQS,IAAI,YAAanf,KAAK+C,MAAMqb,OAAO5W,OAC3CkX,EAAQe,OAAO4B,IAEbrhB,KAAKsgB,yBACPtgB,KAAKugB,aAAa7B,EAEtB,CAEAgE,SAAAA,GACE,MAAOC,EAAQC,GAAU5iB,KAAK+C,MAAMkf,OAAO,IACpCY,EAAOC,GAAS9iB,KAAK+C,MAAMkf,OAAOjiB,KAAK+C,MAAMkf,OAAOhiB,OAAS,GAEpE,MAAO,CACL,IAAI4d,EAAAA,EACF,SACA,IAAM8E,IACN,IAAMC,GACN5iB,KAAK+iB,YACL/iB,KAAK0B,OAEP,IAAImc,EAAAA,EACF,QACA,IAAMgF,IACN,IAAMC,GACN9iB,KAAK+iB,YACL/iB,KAAK0B,OAGX,CAEAqhB,YAAcpb,IAA2E,IAA1E,KAAE8Y,EAAI,KAAEC,GAA6D/Y,EAClF3H,KAAKwgB,OAAOC,EAAMC,EAAK,EAGzBF,MAAAA,CAAOhC,EAAWC,GAChB,IAAIze,KAAKgjB,eACT,IAAK,MAAMR,KAASxiB,KAAK+C,MAAMkf,OAC7BO,EAAM,IAAMhE,EACZgE,EAAM,IAAM/D,CAEhB,CAEAwE,SAAAA,GACE,MAAOC,EAAkBC,GAAoBnjB,KAAK0B,MAAMyV,MAAMsH,EAAE2E,SAChE,IAAK,MAAMZ,KAASxiB,KAAK+C,MAAMkf,OAC7BO,EAAM,GAAKxiB,KAAKqjB,aAAab,EAAM,GAAI,GACvCA,EAAM,GAAKxiB,KAAKsjB,OAAOd,EAAM,GAAIU,EAAmBC,GAEtDlZ,MAAMgZ,WACR,CAEAtC,QAAAA,CAASC,GACP,GAAI3W,MAAM4W,oCAAqC,OAAO,EACtD,MAAM,OAAEoB,GAAWjiB,KAAK+C,MACxB,IACG/C,KAAK+hB,uBAAyB/hB,KAAK+C,MAAM+e,mBAC1C9hB,KAAKqhB,WACLrhB,KAAKohB,qBAAqBmC,cAAcvjB,KAAKqhB,UAAWT,EAAKjC,OAAOH,EAAGoC,EAAKjC,OAAOF,GAEnF,OAAO,EACF,GAAIwD,EAAOhiB,OAAS,EACzB,IAAK,IAAIiiB,EAAI,EAAGA,EAAID,EAAOhiB,OAAS,EAAGiiB,IACrC,GACEpB,EAAAA,GAAKC,kBAAkBH,EAAKjC,OAAQ,CAClCb,GAAI9d,KAAKmiB,GAAGF,EAAOC,GAAG,IACtBnE,GAAI/d,KAAKoiB,GAAGH,EAAOC,GAAG,IACtBlE,GAAIhe,KAAKmiB,GAAGF,EAAOC,EAAI,GAAG,IAC1BjE,GAAIje,KAAKoiB,GAAGH,EAAOC,EAAI,GAAG,OACtB,GAEN,OAAO,EAIb,OAAOjY,MAAM0W,SAASC,EACxB,CAEA4C,4BAA8BA,KAC5B,MAAM7Z,EAAQ3J,KAAK0B,OAAOgI,SAASC,QACnC,GAAIA,EAAO,CACT,MAAM8Z,EAA2BzjB,KAAK+C,MAAMkf,OAAOvU,KAAItF,IAAA,IAAEoW,EAAGC,GAAErW,EAAA,MAAK,CAACuB,EAAM+Z,yBAAyBlF,GAAIC,EAAE,IACzGze,KAAKmf,IAAI,CAAEsE,4BACb,GAGFE,YAAAA,GACE,MAAMha,EAAQ3J,KAAK0B,MAAMgI,QAAQC,SAC3B,yBAAE8Z,GAA6BzjB,KAAK+C,MAC1C,IAAK4G,IAAU8Z,EAGb,OAEF,MAAMxB,EAASwB,EAAyB/V,KAAII,IAAA,IAAE0Q,EAAGC,GAAE3Q,EAAA,MAAK,CAACnE,EAAMia,0BAA0BpF,GAAIC,EAAE,IAC/Fze,KAAKmf,IAAI,CAAE8C,UACb,CAEAoB,aAAeA,CAACzV,EAAeiW,IAAmBC,OAAOC,WAAWjD,EAAAA,GAAKkD,MAAM,CAAEpW,QAAOqW,eAAgBJ,KAExGP,OAASA,CAAC7E,EAAWyF,KACnB,GAAIA,EAAa,EAAG,CAClB,MAAMC,EAAuB9E,KAAKQ,IAAIR,KAAK+E,MAAM/E,KAAKgF,MAAMhF,KAAKQ,IAAIqE,IAAe,IACpF,OAAIC,EAAuB,EAClBnkB,KAAKqjB,aAAa5E,EAAG0F,EAAuB,GAE5CnkB,KAAKqjB,aAAa5E,EAAG0F,EAAuB,EAEvD,CAAO,OAAID,EAAa,GACflkB,KAAKqjB,aAAa5E,EAAG,GAEvBze,KAAKqjB,aAAa5E,EAAG,EAAE,EAGhC6F,4BAAAA,GACE,MAAO,CAAC,SACV,CAEAC,eAAAA,GACE,GAA0B,OAAtBvkB,KAAKwkB,aAAuB,CAC9B,MAAMA,EAAe,CAAC,EACtBxkB,KAAK+C,MAAMkf,OAAO1Z,SAAQmH,IAAY,IAAV8O,EAAGC,GAAE/O,EAC/B8U,EAAaC,KAAOpF,KAAKqF,IAAIlG,EAAGgG,EAAaC,MAAQjG,GACrDgG,EAAaG,KAAOtF,KAAKqF,IAAIjG,EAAG+F,EAAaG,MAAQlG,GACrD+F,EAAaI,KAAOvF,KAAKwF,IAAIrG,EAAGgG,EAAaI,MAAQpG,GACrDgG,EAAaM,KAAOzF,KAAKwF,IAAIpG,EAAG+F,EAAaM,MAAQrG,EAAE,IAGzDze,KAAKwkB,aAAeA,CACtB,CAEA,OAAOxkB,KAAKwkB,YACd,EAGFtD,EAAMphB,UAAUkhB,YAAc,CAC5BC,OAAQ,CACN,CAAEtL,KAAM,aAAcvS,KAAM,QAC5B,CAAEuS,KAAM,SAAUvS,KAAM,SAAUshB,IAAK,EAAGG,IAAK,GAAIE,QAAS,CAAC,GAC7D,CAAEpP,KAAM,WAAYvS,KAAM,mBAAoB0L,MAAO,gBAIzD,S,kHCjOO,IAAKkW,EAAa,SAAbA,GAAa,OAAbA,EAAAA,EAAa,mBAAbA,EAAAA,EAAa,iCAAbA,EAAAA,EAAa,mCAAbA,EAAAA,EAAa,uCAAbA,EAAAA,EAAa,yCAAbA,EAAAA,EAAa,qBAAbA,EAAAA,EAAa,yBAAbA,EAAAA,EAAa,2BAAbA,EAAAA,EAAa,uBAAbA,CAAa,MAYlB,MAoEDC,EAAmBA,CAACC,EAAmBC,EAAkBC,KAC7D,MAAMC,EAAOvE,EAAAA,GAAKwE,SAASH,EAAIC,GAC/B,OAAIC,EAAmB,EAAZH,EACFG,EAAO,EAEPH,CACT,ECvEF,MAAMK,UAAmEC,EAAAA,EACvEjI,YAAcC,EAAAA,GAAkBiI,UAEhCriB,KAAO,UAcPD,WAAAA,CAAY+E,EAAwBxG,GAClCuI,MAAM/B,EAAQxG,GACd1B,KAAK2d,OAAS3d,KAAK2d,OAAOhd,KAAKX,MAC/BA,KAAK4d,QAAU,CACb,IAAIC,EAAAA,EACF,QACA,IAAM7d,KAAK+C,MAAM+a,KACjB,IAAM9d,KAAK+C,MAAMgb,IACjB/d,KAAK2d,OACL3d,KAAK0B,QAGT1B,KAAKmX,MAAMnX,KAAKke,uBAClB,CAEAA,qBAAuBA,KAAA,CAASM,EAAG,CAAC,KAAM,MAAOC,EAAG,CAAC,KAAM,QAE3DiH,kBAAAA,GACE,MAAO,CACLzE,OAAQ,CACN,CAAEtL,KAAM,mBAAoBvS,KAAM,OAAQuiB,UAAU,GACpD,CAAEhQ,KAAM,OAAQvS,KAAM,QACtB,CACEuS,KAAM,aACNvS,KAAM,YACN0L,MAAO,QACPiW,QAAS/kB,KAAKqe,yBAAyBC,gBAAgBC,OAAOqH,uBAEhE,CACEjQ,KAAM,aACNvS,KAAM,aACN0L,MAAO,aACPiW,QAAS,iBAEX,CACEpP,KAAM,SACNvS,KAAM,SACNshB,IAAK,IAIb,CAEAvG,WAAAA,GACE,MAAM,gBAAEG,GAAoBte,KAAKqe,yBACjC,MAAO,CACLwH,KAAM,GACNC,KAAM,CACJtW,KAAM,GACNuW,OAAQ,QACR5P,MAAO,SACP6P,OAAQ,UAEVC,UAAW3H,EAAgBC,OAAOqH,sBAClCM,WAAY,GAEZC,UAAW,OAEXC,aAAc,aACdC,QAAS,CACPC,IAAK,EACLC,MAAO,EACPC,OAAQ,EACRC,KAAM,GAERC,WAAYpI,EAAgBqI,YAC5BvI,OAAQ,CAAElG,MAAOoG,EAAgBC,OAAO5H,KAAMnP,MAAO,GAEzD,CAEAof,YAAAA,CAAalI,GACX1e,KAAK0e,QAAUA,EACfA,EAAQS,IAAI,OAAQnf,KAAK8lB,MACzBpH,EAAQS,IAAI,YAAanf,KAAK+C,MAAMkjB,WACpCvH,EAAQS,IAAI,YAAanf,KAAK+C,MAAMojB,WACpCzH,EAAQS,IAAI,eAAgBnf,KAAK+C,MAAMqjB,cACvCpmB,KAAK6mB,uBACP,CAEAA,qBAAAA,GACE,MAAMC,EAAM9mB,KAAK0e,QAGd1e,KAAK+C,MAAM8iB,OAAS7lB,KAAK+mB,WAAWlB,MACnCmB,KAAKC,UAAUjnB,KAAK+C,MAAM+iB,QAAUkB,KAAKC,UAAUjnB,KAAK+mB,WAAWjB,QACrEgB,IAEA9mB,KAAK+mB,UAAYG,IAAM,CAAC,EAAGlnB,KAAK+C,OAChC/C,KAAKmnB,MAAQnnB,KAAKonB,WAAW1Z,KAAKiJ,IAAI,CACpCkP,KAAMlP,EACN0Q,QAASP,EAAIQ,YAAY3Q,OAE3B3W,KAAKunB,eAAiBvnB,KAAKmnB,MAAMpa,QAAO,CAACC,EAAKnO,EAAS2oB,IAK9Cxa,GAHLnO,EAAQwoB,QAAQI,wBAChB5oB,EAAQwoB,QAAQK,0BACfF,IAAiBxnB,KAAKmnB,MAAMlnB,OAAS,EAAI0nB,EAAAA,GAAQC,EAAI,KAEvD,GAEP,CAEAlK,aAAAA,CAAcgB,GACZ1e,KAAK6nB,OAAOnJ,GACR1e,KAAKsgB,yBACPtgB,KAAKugB,aAAa7B,EAEtB,CAEAoJ,UAAAA,GACE,IAAK9nB,KAAK0e,QAAS,OACnB,IAAID,EAAIze,KAAK2e,OAAOV,GAAKje,KAAK+C,MAAMsjB,QAAQC,IACxCyB,EAAkB,EACtB,IAAK,IAAI7F,EAAI,EAAGA,EAAIliB,KAAKmnB,MAAMlnB,OAAQiiB,IACrCzD,GAAW,IAANyD,EAAU,EAAIliB,KAAKmnB,MAAMjF,GAAGmF,QAAQI,wBAA0BM,EAAkBJ,EAAAA,GAAQC,EAC7F5nB,KAAK0e,QAAQsJ,SAAShoB,KAAKmnB,MAAMjF,GAAG2D,KAAM7lB,KAAK2e,OAAOX,GAAKhe,KAAK+C,MAAMsjB,QAAQI,KAAMhI,GACpFsJ,EAAkB/nB,KAAKmnB,MAAMjF,GAAGmF,QAAQK,wBAE5C,CAEAO,oBAAAA,GACE,MAAMC,EAAgC,KAApBloB,KAAK+C,MAAM8iB,KAAqC,EAAvB7lB,KAAK+C,MAAM+iB,KAAKtW,KAAWxP,KAAKwH,MACrE2gB,EAA+C,GAAvBnoB,KAAK+C,MAAM+iB,KAAKtW,KACxC6W,EAAUrmB,KAAK+C,MAAMqb,OAAO5W,MAAQ,EAA2B,GAAvBxH,KAAK+C,MAAM+iB,KAAKtW,KACxD4Y,EAASF,EAAYC,EAAwBD,EAAY,EAAIC,EAE7DZ,EAAiBvnB,KAAKunB,eAAiBY,EAAiC,EAATC,EAAapoB,KAAKunB,eACjFtJ,EAAKje,KAAK2e,OAAOV,IAAMje,KAAKmnB,QAAQ,IAAIE,QAAQI,yBAA2BF,GAY3Ec,ED/JkC1gB,KAAA,IAAC,QAC3C0e,EAAO,OACP+B,EAAM,GACNpK,EAAE,GACFC,EAAE,UACFiK,EAAS,eACTX,GAQD5f,EAAA,MAAkC,CACjC2gB,QAAS,CACP9J,EAAGR,EAAKqI,EAAU+B,EAClB3J,EAAGR,EAAKoI,GAEVkC,SAAU,CACR/J,EAAGR,EAAKkK,EAAY7B,EAAU+B,EAC9B3J,EAAGR,EAAKoI,GAEVmC,SAAU,CACRhK,EAAGR,EAAKkK,EAAY7B,EACpB5H,EAAGR,EAAKoI,EAAU+B,GAEpBK,YAAa,CACXjK,EAAGR,EAAKkK,EAAY7B,EACpB5H,EAAGR,EAAKoI,EAAUkB,EAAiBa,GAErCM,YAAa,CACXlK,EAAGR,EAAKkK,EAAY7B,EAAU+B,EAC9B3J,EAAGR,EAAKoI,EAAUkB,GAEpBoB,WAAY,CACVnK,EAAGR,EAAKqI,EAAU+B,EAClB3J,EAAGR,EAAKoI,EAAUkB,GAEpBqB,WAAY,CACVpK,EAAGR,EAAKqI,EACR5H,EAAGR,EAAKoI,EAAUkB,EAAiBa,GAErCS,QAAS,CACPrK,EAAGR,EAAKqI,EACR5H,EAAGR,EAAKoI,EAAU+B,GAErB,ECgH0BU,CAA6B,CAClDzC,UACA+B,SACApK,GAAIhe,KAAK2e,OAAOX,GAChBC,KACAiK,YACAX,mBAEIwB,EDtHwB3gB,KAAA,IAAC,eACjCigB,EAAc,GACdvK,EAAE,GACFC,GAKD3V,EAAA,MAAwB,CACvB4gB,SAAU,CACRxK,EAAG6J,EAAeC,QAAQ9J,GAAK6J,EAAeE,SAAS/J,EAAI6J,EAAeC,QAAQ9J,GAAK,EACvFC,EAAG4J,EAAeQ,QAAQpK,GAAK4J,EAAeO,WAAWnK,EAAI4J,EAAeQ,QAAQpK,GAAK,GAE3FwK,QAAS,CACPzK,EAAGV,EACHW,EAAGV,GAEN,ECqGgBmL,CAAmB,CAAEb,iBAAgBvK,GAAI9d,KAAK2e,OAAOb,GAAIC,GAAI/d,KAAK2e,OAAOZ,KAChFoL,ED3F+Brb,KAMpB,IANqB,KACxCib,EAAI,eACJV,GAIDva,EACC,MAAM,QAAEwa,EAAO,SAAEC,EAAQ,SAAEC,EAAQ,YAAEC,EAAW,YAAEC,EAAW,WAAEC,EAAU,WAAEC,EAAU,QAAEC,GAAYR,GAC7F,QAAEY,EAAO,SAAED,GAAaD,EAC9B,OAAIjI,EAAAA,GAAKsI,4BAA4BH,EAASD,EAAUV,EAASO,GACxD7D,EAAcqE,cACZvI,EAAAA,GAAKsI,4BAA4BH,EAASD,EAAUT,EAAUC,GAChExD,EAAcsE,eACZxI,EAAAA,GAAKsI,4BAA4BH,EAASD,EAAUL,EAAYC,GAClE5D,EAAcuE,iBACZzI,EAAAA,GAAKsI,4BAA4BH,EAASD,EAAUN,EAAaD,GACnEzD,EAAcwE,kBACZ1I,EAAAA,GAAKsI,4BAA4BH,EAASD,EAAUV,EAASC,GAC/DvD,EAAcyE,QACZ3I,EAAAA,GAAKsI,4BAA4BH,EAASD,EAAUR,EAAUC,GAChEzD,EAAc0E,UACZ5I,EAAAA,GAAKsI,4BAA4BH,EAASD,EAAUL,EAAYD,GAClE1D,EAAc2E,WACZ7I,EAAAA,GAAKsI,4BAA4BH,EAASD,EAAUH,EAASD,GAC/D5D,EAAc4E,SAEd5E,EAAc6E,MACvB,ECgEwBC,CAA0B,CAAEf,OAAMV,mBAExD,MAAO,CACLD,SACAD,wBACAE,iBACAU,OACAI,gBAEJ,CAEAY,gBAAAA,GACE,IAAK/pB,KAAK+C,MAAM2jB,aAAe1mB,KAAK0e,QAClC,OAGF,MAAM,OAAE0J,EAAM,sBAAED,EAAqB,KAAEY,EAAI,cAAEI,EAAa,eAAEd,GAAmBroB,KAAKioB,uBAEpFjoB,KAAK0e,QAAQQ,YACblf,KAAK0e,QAAQS,IAAI,YAAanf,KAAK+C,MAAM2jB,YACzC1mB,KAAK0e,QAAQsL,SAAW,QDxECta,KAOD,IAPE,QAC5BgP,EAAO,OACP0J,EAAM,sBACND,EAAqB,KACrBY,EAAI,eACJV,EAAc,cACdc,GACezZ,EACf,MAAM,QAAE4Y,EAAO,SAAEC,EAAQ,SAAEC,EAAQ,YAAEC,EAAW,YAAEC,EAAW,WAAEC,EAAU,WAAEC,EAAU,QAAEC,GAAYR,GAC7F,QAAEY,EAAO,SAAED,GAAaD,EAgB9B,GAVII,IAAkBnE,EAAcqE,eAClC3K,EAAQa,OAAOsJ,EAAQrK,EAAGqK,EAAQpK,GAClCC,EAAQc,OAAOyJ,EAAQzK,EAAGyK,EAAQxK,GAClCC,EAAQc,OAAO8I,EAAQ9J,EAAG8J,EAAQ7J,KAElCC,EAAQa,OAAOsJ,EAAQrK,EAAGqK,EAAQpK,GAClCC,EAAQuL,MAAMpB,EAAQrK,EAAG8J,EAAQ7J,EAAG6J,EAAQ9J,EAAG8J,EAAQ7J,EAAG2J,IAIxDe,IAAkBnE,EAAcyE,QAAS,CAC3C,MAAMS,EAAgCpJ,EAAAA,GAAKsI,4BAA4BH,EAASD,EAAUV,EAASC,GACnG,IAAK2B,EAEH,YADAxL,EAAQc,OAAO+I,EAAS/J,EAAG+J,EAAS9J,GAGtC,MAAM0L,EAAgBlF,EAAiBkD,EAAuBG,EAASC,GACnE2B,EAA8B1L,EAAI2L,EAAgB7B,EAAQ9J,GAC5DE,EAAQc,OAAOyJ,EAAQzK,EAAGyK,EAAQxK,GAClCC,EAAQc,OAAO8I,EAAQ9J,EAAoB,EAAhB2L,EAAmBD,EAA8BzL,IACnEyL,EAA8B1L,EAAI2L,EAAgB5B,EAAS/J,GACpEE,EAAQc,OAAO+I,EAAS/J,EAAoB,EAAhB2L,EAAmBD,EAA8BzL,GAC7EC,EAAQc,OAAOyJ,EAAQzK,EAAGyK,EAAQxK,GAClCC,EAAQc,OAAO+I,EAAS/J,EAAG0L,EAA8BzL,KAEzDC,EAAQc,OAAO0K,EAA8B1L,EAAI2L,EAAeD,EAA8BzL,GAC9FC,EAAQc,OAAOyJ,EAAQzK,EAAGyK,EAAQxK,GAClCC,EAAQc,OAAO0K,EAA8B1L,EAAI2L,EAAeD,EAA8BzL,GAC9FC,EAAQc,OAAO+I,EAAS/J,EAAG+J,EAAS9J,GAExC,MACEC,EAAQc,OAAO+I,EAAS/J,EAAG+J,EAAS9J,GAatC,GATI0K,IAAkBnE,EAAcsE,gBAClC5K,EAAQc,OAAO+I,EAAS/J,EAAG+J,EAAS9J,GACpCC,EAAQc,OAAOyJ,EAAQzK,EAAGyK,EAAQxK,GAClCC,EAAQc,OAAOgJ,EAAShK,EAAGgK,EAAS/J,IAEpCC,EAAQuL,MAAMzB,EAAShK,EAAG+J,EAAS9J,EAAG+J,EAAShK,EAAGgK,EAAS/J,EAAG2J,GAI5De,IAAkBnE,EAAc0E,UAAW,CAC7C,MAAMU,EAAkCtJ,EAAAA,GAAKsI,4BAA4BH,EAASD,EAAUR,EAAUC,GACtG,IAAK2B,EAEH,YADA1L,EAAQc,OAAOiJ,EAAYjK,EAAGiK,EAAYhK,GAG5C,MAAM0L,EAAgBlF,EAAiBkD,EAAuBK,EAAUC,GACpE2B,EAAgC3L,EAAI0L,EAAgB3B,EAAS/J,GAC/DC,EAAQc,OAAOyJ,EAAQzK,EAAGyK,EAAQxK,GAClCC,EAAQc,OAAOgJ,EAAShK,EAAGgK,EAAS/J,EAAoB,EAAhB0L,IAC/BC,EAAgC3L,EAAI0L,EAAgB1B,EAAYhK,GACzEC,EAAQc,OAAOiJ,EAAYjK,EAAGiK,EAAYhK,EAAoB,EAAhB0L,GAC9CzL,EAAQc,OAAOyJ,EAAQzK,EAAGyK,EAAQxK,GAClCC,EAAQc,OAAOiJ,EAAYjK,EAAGiK,EAAYhK,KAE1CC,EAAQc,OAAO4K,EAAgC5L,EAAG4L,EAAgC3L,EAAI0L,GACtFzL,EAAQc,OAAOyJ,EAAQzK,EAAGyK,EAAQxK,GAClCC,EAAQc,OAAO4K,EAAgC5L,EAAG4L,EAAgC3L,EAAI0L,GACtFzL,EAAQc,OAAOiJ,EAAYjK,EAAGiK,EAAYhK,GAE9C,MACEC,EAAQc,OAAOiJ,EAAYjK,EAAGiK,EAAYhK,GAa5C,GATI0K,IAAkBnE,EAAcwE,mBAClC9K,EAAQc,OAAOiJ,EAAYjK,EAAGiK,EAAYhK,GAC1CC,EAAQc,OAAOyJ,EAAQzK,EAAGyK,EAAQxK,GAClCC,EAAQc,OAAOkJ,EAAYlK,EAAGkK,EAAYjK,IAE1CC,EAAQuL,MAAMxB,EAAYjK,EAAGkK,EAAYjK,EAAGiK,EAAYlK,EAAGkK,EAAYjK,EAAG2J,GAIxEe,IAAkBnE,EAAc2E,WAAY,CAC9C,MAAMU,EAAmCvJ,EAAAA,GAAKsI,4BAC5CH,EACAD,EACAL,EACAD,GAEF,IAAK2B,EAEH,YADA3L,EAAQc,OAAOmJ,EAAWnK,EAAGmK,EAAWlK,GAG1C,MAAM0L,EAAgBlF,EAAiBkD,EAAuBQ,EAAYD,GACtE2B,EAAiC7L,EAAI2L,EAAgBzB,EAAYlK,GACnEE,EAAQc,OAAOyJ,EAAQzK,EAAGyK,EAAQxK,GAClCC,EAAQc,OAAOkJ,EAAYlK,EAAoB,EAAhB2L,EAAmBE,EAAiC5L,IAC1E4L,EAAiC7L,EAAI2L,EAAgBxB,EAAWnK,GACzEE,EAAQc,OAAOmJ,EAAWnK,EAAoB,EAAhB2L,EAAmBE,EAAiC5L,GAClFC,EAAQc,OAAOyJ,EAAQzK,EAAGyK,EAAQxK,GAClCC,EAAQc,OAAOmJ,EAAWnK,EAAG6L,EAAiC5L,KAE9DC,EAAQc,OAAO6K,EAAiC7L,EAAI2L,EAAeE,EAAiC5L,GACpGC,EAAQc,OAAOyJ,EAAQzK,EAAGyK,EAAQxK,GAClCC,EAAQc,OAAO6K,EAAiC7L,EAAI2L,EAAeE,EAAiC5L,GACpGC,EAAQc,OAAOmJ,EAAWnK,EAAGmK,EAAWlK,GAE5C,MACEC,EAAQc,OAAOmJ,EAAWnK,EAAGmK,EAAWlK,GAa1C,GATI0K,IAAkBnE,EAAcuE,kBAClC7K,EAAQc,OAAOmJ,EAAWnK,EAAGmK,EAAWlK,GACxCC,EAAQc,OAAOyJ,EAAQzK,EAAGyK,EAAQxK,GAClCC,EAAQc,OAAOoJ,EAAWpK,EAAGoK,EAAWnK,IAExCC,EAAQuL,MAAMrB,EAAWpK,EAAGmK,EAAWlK,EAAGmK,EAAWpK,EAAGoK,EAAWnK,EAAG2J,GAIpEe,IAAkBnE,EAAc4E,SAAU,CAC5C,MAAMU,EAAiCxJ,EAAAA,GAAKsI,4BAA4BH,EAASD,EAAUH,EAASD,GACpG,IAAK0B,EAEH,YADA5L,EAAQc,OAAOqJ,EAAQrK,EAAGqK,EAAQpK,GAGpC,MAAM0L,EAAgBlF,EAAiBkD,EAAuBU,EAASD,GACnE0B,EAA+B7L,EAAI0L,EAAgBvB,EAAWnK,GAChEC,EAAQc,OAAOyJ,EAAQzK,EAAGyK,EAAQxK,GAClCC,EAAQc,OAAOoJ,EAAWpK,EAAGoK,EAAWnK,EAAoB,EAAhB0L,IACnCG,EAA+B7L,EAAI0L,EAAgBtB,EAAQpK,GACpEC,EAAQc,OAAOqJ,EAAQrK,EAAGqK,EAAQpK,EAAoB,EAAhB0L,GACtCzL,EAAQc,OAAOyJ,EAAQzK,EAAGyK,EAAQxK,GAClCC,EAAQc,OAAOqJ,EAAQrK,EAAGqK,EAAQpK,KAElCC,EAAQc,OAAO8K,EAA+B9L,EAAG8L,EAA+B7L,EAAI0L,GACpFzL,EAAQc,OAAOyJ,EAAQzK,EAAGyK,EAAQxK,GAClCC,EAAQc,OAAO8K,EAA+B9L,EAAG8L,EAA+B7L,EAAI0L,GACpFzL,EAAQc,OAAOqJ,EAAQrK,EAAGqK,EAAQpK,GAEtC,MACEC,EAAQc,OAAOqJ,EAAQrK,EAAGqK,EAAQpK,EACpC,ECjFE8L,CAAc,CACZ7L,QAAS1e,KAAK0e,QACd0J,SACAD,wBACAY,OACAV,iBACAc,kBAEFnpB,KAAK0e,QAAQ+D,YACbziB,KAAK0e,QAAQkD,OACb5hB,KAAK0e,QAAQS,IAAI,YAAanf,KAAK+C,MAAMkjB,WACzCjmB,KAAKwqB,cACP,CAEA7J,QAAAA,CAASC,GACP,GAAI3W,MAAM4W,oCAAqC,OAAO,EAEtD,MAAM,KAAEkI,EAAI,eAAEV,EAAc,sBAAEF,GAA0BnoB,KAAKioB,uBAC7D,GACEjoB,KAAKmnB,OACLkB,GACAA,EAAeQ,QAAQrK,EAAIoC,EAAKjC,OAAOH,GACvC6J,EAAeC,QAAQ7J,EAAImC,EAAKjC,OAAOF,GACvC4J,EAAeI,YAAYjK,EAAIoC,EAAKjC,OAAOH,GAC3C6J,EAAeK,YAAYjK,EAAImC,EAAKjC,OAAOF,EAE3C,OAAO,EAGT,GAAIsK,EAAM,CACR,MAAM0B,EAAS3J,EAAAA,GAAK4J,yBAAyB,CAC3CpF,SAAU6C,EACVxR,KAAM,CAAEmH,GAAIiL,EAAKE,QAAQzK,EAAGT,GAAIgL,EAAKE,QAAQxK,EAAGT,GAAI+K,EAAKC,SAASxK,EAAGP,GAAI8K,EAAKC,SAASvK,KAEnFkM,EAAeF,EAAOjM,EAAIuK,EAAKC,SAASxK,EACxCoM,EAAeH,EAAOhM,EAAIsK,EAAKC,SAASvK,EACxCoM,EAAS,CAAErM,EAAGuK,EAAKC,SAASxK,GAAK,EAAImM,EAAclM,EAAGsK,EAAKC,SAASvK,GAAK,EAAImM,GAC7EE,EAAU,CAAC/B,EAAKE,QAASwB,EAAQI,GACvC,GAAI/J,EAAAA,GAAKiK,eAAenK,EAAKjC,OAAQmM,GACnC,OAAO,CAEX,CACA,OAAO7gB,MAAM0W,SAASC,EACxB,CAEAJ,MAAAA,CAAOhC,EAAWC,GAChBze,KAAK+C,MAAMib,IAAMQ,EACjBxe,KAAK+C,MAAMkb,IAAMQ,CACnB,CAEAd,MAAAA,CAAMhW,GAAqD,IAApD,KAAEgO,EAAI,KAAE8K,EAAI,KAAEC,GAAoC/Y,EAC1C,SAATgO,IACF3V,KAAK+C,MAAM+a,IAAM2C,EACjBzgB,KAAK+C,MAAMgb,IAAM2C,EAErB,CAEAsK,gBAAAA,CAAiBthB,GACf,GAAI1J,KAAKgjB,iBAAmBhjB,KAAKmnB,MAC/B,OAAO,EAGT,MAAM,KAAE4B,EAAI,eAAEV,GAAmBroB,KAAKioB,uBAEtC,MAAO,IAAIhlB,OAAOiF,OAAOmgB,GAAiBU,EAAKC,SAAUD,EAAKE,SAAS9gB,MACrEC,IAAA,IAAC,EAAEoW,EAAC,EAAEC,GAAGrW,EAAA,OAAKoW,IAAM9U,EAAMuhB,WAAavhB,EAAMlC,OAASgX,IAAM9U,EAAMuhB,YAAcxM,GAAK,GAAKA,GAAKze,KAAK0B,MAAM+F,MAAM,GAEpH,EAGF,S,8FC9QA,MAAMyjB,UAAuDvgB,EAAAA,EAC3D4S,YAAcC,EAAAA,GAAkB2N,MAEhC/nB,KAAO,QAIPD,WAAAA,CAAY+E,EAAwBxG,GAClCuI,MAAM/B,EAAQxG,GACd1B,KAAK6nB,OAAS7nB,KAAK6nB,OAAOlnB,KAAKX,MAC/BA,KAAK2d,OAAS3d,KAAK2d,OAAOhd,KAAKX,MAC/BA,KAAK4d,QAAU,CACb,IAAIC,EAAAA,EACF,KACA,IAAM7d,KAAK+C,MAAM+a,KACjB,IAAM9d,KAAK+C,MAAMgb,IACjB/d,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,KACA,IAAM7d,KAAK+C,MAAMib,KACjB,IAAMhe,KAAK+C,MAAMkb,IACjBje,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,KACA,IAAM7d,KAAK+C,MAAMqoB,IAAMprB,KAAK+C,MAAMib,KAClC,IAAMhe,KAAK+C,MAAMsoB,IAAMrrB,KAAK+C,MAAMkb,IAClCje,KAAK2d,OACL3d,KAAK0B,QAGT1B,KAAKmX,MAAMnX,KAAKke,uBAClB,CAEAC,WAAAA,GACE,MAAO,CACLC,OAAQ,CACN5W,MAAO,EACP0Q,MAAOlY,KAAKqe,yBAAyBC,gBAAgBC,OAAO5H,MAGlE,CAEAuH,qBAAuBA,KAAA,CAASM,EAAG,CAAC,KAAM,KAAM,MAAOC,EAAG,CAAC,KAAM,KAAM,QAEvE6M,kBAAAA,CAAmB5M,EAAmCyM,GACpD,MAAM,OAAElJ,GAAWkJ,EACnBzM,EAAQQ,YACRR,EAAQa,OAAO0C,EAAO,GAAGzD,EAAGyD,EAAO,GAAGxD,GACtCC,EAAQ6D,iBAAiBN,EAAO,GAAGzD,EAAGyD,EAAO,GAAGxD,EAAGwD,EAAO,GAAGzD,EAAGyD,EAAO,GAAGxD,GAC1EC,EAAQe,QACV,CAEA/B,aAAAA,CAAcgB,GACZ,MAAM,GAAEZ,EAAE,GAAEE,EAAE,GAAEoN,EAAE,GAAErN,EAAE,GAAEE,EAAE,GAAEoN,GAAOrrB,KAAK2e,OACxCD,EAAQO,UAAU,GAAK,IACvBP,EAAQS,IAAI,YAAanf,KAAK+C,MAAMqb,OAAO5W,OAC3CkX,EAAQS,IAAI,cAAenf,KAAK+C,MAAMqb,OAAOlG,OACxCkT,GAAOC,GAOVrrB,KAAKmrB,MAAQI,EAAAA,EAAOC,oBAAoB,CAAEhN,EAAGV,EAAIW,EAAGV,GAAM,CAAES,EAAGR,EAAIS,EAAGR,GAAM,CAAEO,EAAG4M,EAAI3M,EAAG4M,GAAM,IAC9FrrB,KAAKsrB,mBAAmB5M,EAAS1e,KAAKmrB,SAPtCzM,EAAQQ,YACRR,EAAQa,OAAOzB,EAAIC,GACnBW,EAAQc,OAAOxB,EAAIC,GACnBS,EAAQc,OAAO4L,EAAIC,GACnB3M,EAAQe,UAMVf,EAAQO,WAAW,IAAM,IACrBjf,KAAKsgB,yBACPtgB,KAAKugB,aAAa7B,EAEtB,CAEA8B,MAAAA,CAAOhC,EAAWC,GAChBze,KAAK+C,MAAM+a,IAAMU,EACjBxe,KAAK+C,MAAMib,IAAMQ,EACjBxe,KAAK+C,MAAMqoB,IAAM5M,EACjBxe,KAAK+C,MAAM0oB,MAAQjN,EACnBxe,KAAK+C,MAAM2oB,MAAQlN,EAEnBxe,KAAK+C,MAAMgb,IAAMU,EACjBze,KAAK+C,MAAMkb,IAAMQ,EACjBze,KAAK+C,MAAMsoB,IAAM5M,EACjBze,KAAK+C,MAAM4oB,MAAQlN,EACnBze,KAAK+C,MAAM6oB,MAAQnN,CACrB,CAEAd,MAAAA,CAAMhW,GAAqD,IAApD,KAAEgO,EAAI,KAAE8K,EAAI,KAAEC,GAAoC/Y,EACvD,OAAQgO,GACN,IAAK,IACH3V,KAAK+C,MAAM+a,IAAM2C,EACjBzgB,KAAK+C,MAAMgb,IAAM2C,EACjB,MACF,IAAK,IACH1gB,KAAK+C,MAAMib,IAAMyC,EACjBzgB,KAAK+C,MAAMkb,IAAMyC,EACjB,MACF,IAAK,IACH1gB,KAAK+C,MAAMqoB,IAAM3K,EACjBzgB,KAAK+C,MAAMsoB,IAAM3K,EAKvB,CAEAC,QAAAA,CAASC,GACP,OAAI3W,MAAM4W,yCACN7gB,KAAKmrB,OAASnrB,KAAKmrB,MAAMU,QAAQjL,EAAKjC,QAAQmN,GAAM,KAGjD9rB,KAAK+rB,gBAAgBnL,GAC9B,CAEAoK,gBAAAA,CAAiBthB,GACf,GAAI1J,KAAKgjB,eACP,OAAO,EAGT,MAAM,GAAElF,EAAE,GAAEE,EAAE,GAAEoN,EAAE,GAAErN,EAAE,GAAEE,EAAE,GAAEoN,GAAOrrB,KAAK2e,OACxC,IAAKyM,IAAOC,EACV,OAAO,EAOT,OAJEE,EAAAA,EAAOC,oBAAoB,CAAEhN,EAAGV,EAAIW,EAAGV,GAAM,CAAES,EAAGR,EAAIS,EAAGR,GAAM,CAAEO,EAAG4M,EAAI3M,EAAG4M,GAAM,IAAKpJ,OAAO9Z,MAC3FC,IAAA,IAAC,EAAEoW,EAAC,EAAEC,GAAGrW,EAAA,OAAKoW,IAAM9U,EAAMuhB,WAAavhB,EAAMlC,OAASgX,IAAM9U,EAAMuhB,YAAcxM,GAAK,GAAKA,GAAKze,KAAK0B,MAAM+F,MAAM,MAC7G,CAGT,EAGFyjB,EAAMprB,UAAUkhB,YAAc,CAC5BC,OAAQ,CAAC,CAAEtL,KAAM,OAAQvS,KAAM,YAGjC,S,0ICzHA,MAAM4oB,UAA6DrhB,EAAAA,EACjE4S,YAAcC,EAAAA,GAAkByO,QAEhC7oB,KAAO,UAIPD,WAAAA,CAAY+E,EAAwBxG,GAClCuI,MAAM/B,EAAQxG,GACd1B,KAAK2d,OAAS3d,KAAK2d,OAAOhd,KAAKX,MAC/BA,KAAK4d,QAAU,CACb,IAAIC,EAAAA,EACF,MACA,IAAM7d,KAAK+C,MAAM+a,KACjB,IAAM9d,KAAK+C,MAAMgb,IACjB/d,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,MACA,IAAM7d,KAAK+C,MAAMib,KACjB,IAAMhe,KAAK+C,MAAMkb,IACjBje,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,MACA,IAAM7d,KAAK0B,MAAMyV,MAAMqH,EAAE0N,OAAOlsB,KAAKmsB,iBAAiBC,eACtD,IAAMpsB,KAAK0B,MAAMyV,MAAMsH,EAAEyN,OAAOlsB,KAAKmsB,iBAAiBE,cACtDrsB,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,MACA,IAAM7d,KAAK0B,MAAMyV,MAAMqH,EAAE0N,OAAOlsB,KAAKmsB,iBAAiBG,gBACtD,IAAMtsB,KAAK0B,MAAMyV,MAAMsH,EAAEyN,OAAOlsB,KAAKmsB,iBAAiBI,eACtDvsB,KAAK2d,OACL3d,KAAK0B,QAGT,MAAM8qB,EAAoBxsB,KAAKke,uBAC/Ble,KAAKmX,MAAM,CAAEqH,EAAG,IAAIgO,EAAkBhO,EAAG,SAAUC,EAAG+N,EAAkB/N,GAC1E,CAEAN,WAAAA,GACE,MAAM,gBAAEG,GAAoBte,KAAKqe,yBACjC,MAAO,CACLuD,KAAMtD,EAAgBqI,YACtBvI,OAAQ,CACN5W,MAAO,EACP0Q,MAAOoG,EAAgBC,OAAO5H,MAGpC,CAEAuH,qBAAuBA,KAAA,CAASM,EAAG,CAAC,KAAM,MAAOC,EAAG,CAAC,KAAM,QAE3Df,aAAAA,CAAcgB,GACZ,MAAM+N,EAAIzsB,KAAKmsB,iBAEfzN,EAAQS,IAAI,YAAanf,KAAK+C,MAAM6e,MAEpClD,EAAQQ,YACRR,EAAQa,OAAOkN,EAAEC,cAAeD,EAAEE,eAClCjO,EAAQkO,cAAcH,EAAEI,aAAcJ,EAAEK,aAAcL,EAAEM,UAAWN,EAAEO,UAAWP,EAAEQ,WAAYR,EAAES,YAChGxO,EAAQkO,cAAcH,EAAEU,SAAUV,EAAEW,SAAUX,EAAEY,YAAaZ,EAAEa,YAAab,EAAEC,cAAeD,EAAEE,eAC/FjO,EAAQ+D,YACR/D,EAAQkD,OAERlD,EAAQS,IAAI,YAAanf,KAAK+C,MAAMqb,OAAO5W,OAC3CkX,EAAQS,IAAI,cAAenf,KAAK+C,MAAMqb,OAAOlG,OAC6B,KAAhD,MAArBlY,KAAK+C,MAAMqb,OAAiBpe,KAAK+C,MAAMqb,OAAO5W,WAAQa,IACzDqW,EAAQe,SAGNzf,KAAKsgB,yBACPtgB,KAAKugB,aAAa7B,EAEtB,CAEA8B,MAAAA,CAAOhC,EAAWC,GAChBze,KAAK+C,MAAM+a,IAAMU,EACjBxe,KAAK+C,MAAMgb,IAAMU,EACjBze,KAAK+C,MAAMib,IAAMQ,EACjBxe,KAAK+C,MAAMkb,IAAMQ,CACnB,CAEAd,MAAAA,CAAMhW,GAAqD,IAApD,KAAEgO,EAAI,KAAE8K,EAAI,KAAEC,GAAoC/Y,EACvD,OAAQgO,GACN,IAAK,KACH3V,KAAK+C,MAAM+a,IAAM2C,EACjBzgB,KAAK+C,MAAMgb,IAAM2C,EACjB,MACF,IAAK,KACH1gB,KAAK+C,MAAMib,IAAMyC,EACjBzgB,KAAK+C,MAAMkb,IAAMyC,EACjB,MACF,IAAK,KACH1gB,KAAK+C,MAAMyE,OAASiZ,EACpB,MACF,IAAK,KACHzgB,KAAK+C,MAAMyE,OAASiZ,EAK1B,CAEA0L,cAAAA,GAGE,MAAMoB,EACJlO,KAAKC,GAAKD,KAAKmO,MAAM,IAAMxtB,KAAK2e,OAAOV,GAAKje,KAAK2e,OAAOZ,KAAO/d,KAAK2e,OAAOX,GAAKhe,KAAK2e,OAAOb,MAExF2P,EAAOztB,KAAK2e,OAAOZ,GAAK/d,KAAK2e,OAAOV,GAAK,GAAK,EAC9CyP,EAAU1tB,KAAK2e,OAAOnX,MAAQ,EACpC,IAAImmB,EAAWF,EAAOpO,KAAKQ,IAAI7f,KAAK2e,OAAOZ,GAAK/d,KAAK2e,OAAOV,IAAOoB,KAAKS,IAAIyN,GAAiB,EACzFvtB,KAAK2e,OAAOZ,KAAO/d,KAAK2e,OAAOV,KACjC0P,EAAUtO,KAAKQ,IAAI7f,KAAK2e,OAAOb,GAAK9d,KAAK2e,OAAOX,IAAM,GAGxD,MAAM4P,EAA8B,EAAVF,EAAe,EAEnCG,EAAMxO,KAAKa,IAAIqN,GAAiBI,EAChCG,EAAMzO,KAAKS,IAAIyN,GAAiBI,EAChCI,EAAM1O,KAAKS,IAAIyN,GAAiBK,EAChCI,EAAM3O,KAAKa,IAAIqN,GAAiBK,EAEhCpP,EAAIxe,KAAK2e,OAAOb,GAAK+P,EACrBpP,EAAIze,KAAK2e,OAAOZ,GAAK+P,EAErBb,EAAazO,EAAIqP,EACjBX,EAAazO,EAAIqP,EAMjBpB,EAAgBlO,EAAIqP,EACpBlB,EAAgBlO,EAAIqP,EAW1B,MAAO,CACLb,aACAC,aACAH,UApBgBE,EAAac,EAqB7Bf,UApBgBE,EAAac,EAqB7Bb,SApBeF,EAAac,EAqB5BX,SApBeF,EAAac,EAqB5B5B,YAVkB5N,EAAIuP,EAWtB1B,YAVkB5N,EAAIuP,EAWtB1B,aAdmB9N,EAAIuP,EAevBxB,aAdmB9N,EAAIuP,EAevBtB,gBACAC,gBACAU,YArBkBX,EAAgBqB,EAsBlCT,YArBkBX,EAAgBqB,EAsBlCnB,aAzBmBH,EAAgBqB,EA0BnCjB,aAzBmBH,EAAgBqB,EA2BvC,CAEArN,QAAAA,CAASC,GACP,GAAI3W,MAAM4W,oCAAqC,OAAO,EACtD,MAAM4L,EAAIzsB,KAAKmsB,iBACT1F,EAAOpH,KAAKqF,IAAI1kB,KAAK2e,OAAOb,GAAI9d,KAAK2e,OAAOX,GAAIyO,EAAEH,cAClD/F,EAAQlH,KAAKwF,IAAI7kB,KAAK2e,OAAOb,GAAI9d,KAAK2e,OAAOX,GAAIyO,EAAEL,aACnD9F,EAAMjH,KAAKqF,IAAI1kB,KAAK2e,OAAOZ,GAAI/d,KAAK2e,OAAOV,GAAIwO,EAAEF,cACjD/F,EAASnH,KAAKwF,IAAI7kB,KAAK2e,OAAOZ,GAAI/d,KAAK2e,OAAOV,GAAIwO,EAAEJ,aAC1D,OAAI5F,EAAO7F,EAAKjC,OAAOH,GAAKoC,EAAKjC,OAAOH,EAAI+H,GAASD,EAAM1F,EAAKjC,OAAOF,GAAKmC,EAAKjC,OAAOF,EAAI+H,GAGrFvc,MAAM0W,SAASC,EACxB,CAEAoK,gBAAAA,GACE,OAAO,CACT,EAGFgB,EAAQlsB,UAAUkhB,YAAc,CAC9BC,OAAQ,CACN,CAAEtL,KAAM,aAAcvS,KAAM,QAC5B,CAAEuS,KAAM,SAAUvS,KAAM,SAAUshB,IAAK,EAAGK,QAAS,CAAC,KAIxD,U,iHCzNA,MAAMkJ,UAAwFtjB,EAAAA,EAC5F4S,YAAcC,EAAAA,GAAkB0Q,iBAEhC9qB,KAAO,oBAIPD,WAAAA,CAAY+E,EAAwBxG,GAClCuI,MAAM/B,EAAQxG,GACd1B,KAAK2d,OAAS3d,KAAK2d,OAAOhd,KAAKX,MAC/B,MAAMwe,EAAIxe,KAAK0B,MAAMyV,MAAMqH,EAAE0N,OACvBzN,EAAIze,KAAK0B,MAAMyV,MAAMsH,EAAEyN,OAC7BlsB,KAAK4d,QAAU,CACb,IAAIC,EAAAA,EACF,MACA,IAAM7d,KAAK+C,MAAM+a,KACjB,IAAM9d,KAAK+C,MAAMgb,IACjB/d,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,MACA,IAAM7d,KAAK+C,MAAMib,KACjB,IAAMhe,KAAK+C,MAAMkb,IACjBje,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,MACA,IAAMW,EAAExe,KAAKmuB,qBAAqB,GAAG,MACrC,IAAM1P,EAAEze,KAAKmuB,qBAAqB,GAAG,KACrCnuB,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,MACA,IAAMW,EAAExe,KAAKmuB,qBAAqB,GAAG,MACrC,IAAM1P,EAAEze,KAAKmuB,qBAAqB,GAAG,KACrCnuB,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,MACA,IAAMW,EAAExe,KAAKmuB,qBAAqB,GAAG,MACrC,IAAM1P,EAAEze,KAAKmuB,qBAAqB,GAAG,KACrCnuB,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,MACA,IAAMW,EAAExe,KAAKmuB,qBAAqB,GAAG,MACrC,IAAM1P,EAAEze,KAAKmuB,qBAAqB,GAAG,KACrCnuB,KAAK2d,OACL3d,KAAK0B,QAGT,MAAM8qB,EAAoBxsB,KAAKke,uBAC/Ble,KAAKmX,MAAM,CAAEqH,EAAG,IAAIgO,EAAkBhO,EAAG,UAAWC,EAAG+N,EAAkB/N,GAC3E,CAEAN,WAAAA,GACE,MAAM,gBAAEG,GAAoBte,KAAKqe,yBACjC,MAAO,CACLuD,KAAMtD,EAAgBqI,YACtBvI,OAAQ,CACN5W,MAAO,EACP0Q,MAAOoG,EAAgBC,OAAOH,QAGpC,CAEAF,qBAAuBA,KAAA,CAASM,EAAG,CAAC,KAAM,MAAOC,EAAG,CAAC,KAAM,QAE3Df,aAAAA,CAAcgB,GACZA,EAAQS,IAAI,YAAanf,KAAK+C,MAAM6e,MAEpClD,EAAQQ,YACR,MAAMkP,EAASpuB,KAAKmuB,qBACpB,IAAK,MAAM3L,KAAS4L,EAClB1P,EAAQc,OAAOgD,EAAM,GAAIA,EAAM,IAEjC9D,EAAQc,OAAO4O,EAAO,GAAG,GAAIA,EAAO,GAAG,IACvC1P,EAAQkD,OAERlD,EAAQS,IAAI,YAAanf,KAAK+C,MAAMqb,OAAO5W,OAC3CkX,EAAQS,IAAI,cAAenf,KAAK+C,MAAMqb,OAAOlG,OAC6B,KAAhD,MAArBlY,KAAK+C,MAAMqb,OAAiBpe,KAAK+C,MAAMqb,OAAO5W,WAAQa,IACzDqW,EAAQe,SAGNzf,KAAKsgB,yBACPtgB,KAAKugB,aAAa7B,EAEtB,CAEAyP,kBAAAA,GACE,MAAME,EAAMruB,KAAK2e,OAAOb,GAClBwQ,EAAMtuB,KAAK2e,OAAOX,GAClBuQ,EAAMvuB,KAAK2e,OAAOZ,GAClByQ,EAAMxuB,KAAK2e,OAAOV,IAClB,OAAExW,GAAWzH,KAAK2e,OAGlB8P,GAAM,IADDD,EAAMD,IAAQD,EAAMD,IAIzBK,GADOH,EAAMC,EAAM,GAAK,GACXnP,KAAKsP,KAAMlnB,EAASA,GAAW,EAAIgnB,EAAKA,IAAQ,EAC7DG,EAAKH,EAAKC,EAEhB,IAAI5Q,EAAKuQ,EAAMK,EACX3Q,EAAKwQ,EAAMK,EACX5Q,EAAKsQ,EAAMI,EACXzQ,EAAKuQ,EAAMI,EAEXxD,EAAKkD,EAAMI,EACXrD,EAAKmD,EAAMI,EACXC,EAAKR,EAAMK,EACXI,EAAKP,EAAMK,EAcf,OAZIL,IAAQC,IACV1Q,EAAKuQ,EACLtQ,EAAKwQ,EAAM9mB,EAAS,EACpBuW,EAAKsQ,EACLrQ,EAAKuQ,EAAM/mB,EAAS,EAEpB2jB,EAAKkD,EACLjD,EAAKmD,EAAM/mB,EAAS,EACpBonB,EAAKR,EACLS,EAAKP,EAAM9mB,EAAS,GAGf,CACL,CAACqW,EAAIC,GACL,CAACC,EAAIC,GACL,CAACmN,EAAIC,GACL,CAACwD,EAAIC,GAET,CAEAtO,MAAAA,CAAOhC,EAAWC,GAChBze,KAAK+C,MAAM+a,IAAMU,EACjBxe,KAAK+C,MAAMgb,IAAMU,EACjBze,KAAK+C,MAAMib,IAAMQ,EACjBxe,KAAK+C,MAAMkb,IAAMQ,CACnB,CAEAd,MAAAA,CAAMhW,GAAqD,IAApD,KAAEgO,EAAI,KAAE8K,EAAI,KAAEC,GAAoC/Y,EACvD,OAAQgO,GACN,IAAK,KACH3V,KAAK+C,MAAM+a,IAAM2C,EACjBzgB,KAAK+C,MAAMgb,IAAM2C,EACjB,MACF,IAAK,KACH1gB,KAAK+C,MAAMib,IAAMyC,EACjBzgB,KAAK+C,MAAMkb,IAAMyC,EACjB,MACF,IAAK,KACL,IAAK,KACH1gB,KAAK+C,MAAM0E,QAAUiZ,EACrB,MACF,IAAK,KACL,IAAK,KACH1gB,KAAK+C,MAAM0E,QAAUiZ,EACrB,MACF,QACE,OAEN,CAEAC,QAAAA,CAASC,GACP,GAAI3W,MAAM4W,oCAAqC,OAAO,EACtD,MACMiK,EADS9qB,KAAKmuB,qBACGzgB,KAAK+e,IAAC,CAAQjO,EAAGiO,EAAE,GAAIhO,EAAGgO,EAAE,OACnD,QAAI3L,EAAAA,GAAKiK,eAAenK,EAAKjC,OAAQmM,IAG9B7gB,MAAM0W,SAASC,EACxB,CAEAoK,gBAAAA,GACE,OAAO,CACT,EAGFiD,EAAiBnuB,UAAUkhB,YAAc,CACvCC,OAAQ,CACN,CAAEtL,KAAM,aAAcvS,KAAM,QAC5B,CAAEuS,KAAM,SAAUvS,KAAM,SAAUshB,IAAK,EAAGK,QAAS,CAAC,KAIxD,U,qCClMA,MAAMgK,UAAiEpkB,EAAAA,EACrE4S,YAAcC,EAAAA,GAAkBwR,OAEhC5rB,KAAO,SAMPD,WAAAA,CAAY+E,EAAwBxG,GAClCuI,MAAM/B,EAAQxG,GAEd1B,KAAK2d,OAAS3d,KAAK2d,OAAOhd,KAAKX,MAE/B,MAAMivB,EAAMxB,GACVztB,KAAKkvB,sBAAsBlvB,KAAK2e,OAAOb,GAAK2P,GAAQztB,KAAKkoB,UAAY,GAAKloB,KAAK+C,MAAMosB,OAAQnvB,KAAK2e,OAAOZ,IACrGqR,EAAM3B,GACVztB,KAAKkvB,sBAAsBlvB,KAAK2e,OAAOb,GAAI9d,KAAK2e,OAAOZ,GAAK0P,GAAQztB,KAAKqvB,WAAa,GAAKrvB,KAAK+C,MAAMusB,QACxGtvB,KAAK4d,QAAU,CACb,IAAIC,EAAAA,EACF,MACA,IAAM7d,KAAK0B,MAAMyV,MAAMqH,EAAE0N,OAAO+C,EAAG,GAAIzQ,KACvC,IAAMxe,KAAK0B,MAAMyV,MAAMsH,EAAEyN,OAAO+C,EAAG,GAAIxQ,IACvCze,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,MACA,IAAM7d,KAAK0B,MAAMyV,MAAMqH,EAAE0N,OAAO+C,GAAI,GAAGzQ,KACvC,IAAMxe,KAAK0B,MAAMyV,MAAMsH,EAAEyN,OAAO+C,GAAI,GAAGxQ,IACvCze,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,MACA,IAAM7d,KAAK0B,MAAMyV,MAAMqH,EAAE0N,OAAOkD,EAAG,GAAI5Q,KACvC,IAAMxe,KAAK0B,MAAMyV,MAAMsH,EAAEyN,OAAOkD,EAAG,GAAI3Q,IACvCze,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,MACA,IAAM7d,KAAK0B,MAAMyV,MAAMqH,EAAE0N,OAAOkD,GAAI,GAAG5Q,KACvC,IAAMxe,KAAK0B,MAAMyV,MAAMsH,EAAEyN,OAAOkD,GAAI,GAAG3Q,IACvCze,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,KACA,IAAM7d,KAAK+C,MAAM+a,KACjB,IAAM9d,KAAK+C,MAAMgb,IACjB/d,KAAK2d,OACL3d,KAAK0B,QAGT1B,KAAKmX,MAAMnX,KAAKke,wBAChBle,KAAK+C,MAAMqc,MAAQpf,KAAK+C,MAAMqc,OAAS,CACzC,CAEAlB,qBAAuBA,KAAA,CAASM,EAAG,CAAC,MAAOC,EAAG,CAAC,QAE/Cf,aAAAA,CAAcgB,GACZA,EAAQS,IAAI,OAAQ,oBACpBT,EAAQS,IAAI,YAAanf,KAAK+C,MAAM6e,MACpClD,EAAQS,IAAI,YAAa,QACzBT,EAAQS,IAAI,eAAgB,OAE5Bnf,KAAKkoB,UAAYxJ,EAAQ4I,YAAYtnB,KAAK+C,MAAMisB,QAAQxnB,MACxDxH,KAAKqvB,WAAa,GAClB,MAAME,EAASvvB,KAAK+C,MAAMosB,OACpBK,EAASxvB,KAAK+C,MAAMusB,OAEpBG,EAAUzvB,KAAKkoB,WAAa,EAC5BwH,EAAU1vB,KAAKqvB,YAAc,EAEnC3Q,EAAQiR,OACRjR,EAAQO,UAAUjf,KAAK2e,OAAOb,GAAI9d,KAAK2e,OAAOZ,IAC9CW,EAAQkR,OAAO5vB,KAAK+C,MAAMqc,OAC1BV,EAAQvH,MAAMoY,EAAQC,GACtB9Q,EAAQsJ,SAAShoB,KAAK+C,MAAMisB,OAAQS,EAASC,GAC7ChR,EAAQmR,UAEJ7vB,KAAKsgB,yBACPtgB,KAAKugB,aAAa7B,EAEtB,CAEAwQ,qBAAAA,CAAsB1Q,EAAWC,GAC/B,MAAMqR,EAAK9vB,KAAK2e,OAAOb,GACjBiS,EAAK/vB,KAAK2e,OAAOZ,GACjB2Q,EAAKlQ,EAAIsR,EACTlB,EAAKnQ,EAAIsR,EAGf,MAAO,CAAEvR,EAAGsR,GAFDpB,EAAKrP,KAAKS,IAAI9f,KAAK+C,MAAMqc,OAASwP,EAAKvP,KAAKa,IAAIlgB,KAAK+C,MAAMqc,QAEjDX,EAAGsR,GADbnB,EAAKvP,KAAKS,IAAI9f,KAAK+C,MAAMqc,OAASsP,EAAKrP,KAAKa,IAAIlgB,KAAK+C,MAAMqc,QAExE,CAEAoB,MAAAA,CAAOhC,EAAWC,GAEhB,OADAze,KAAK+C,MAAM+a,IAAMU,EACTxe,KAAK+C,MAAMgb,IAAMU,CAC3B,CAEAd,MAAAA,CAAMhW,GAAqD,IAApD,KAAEgO,EAAI,KAAE8K,EAAI,KAAEC,GAAoC/Y,EACvD,OAAQgO,GACN,IAAK,KACH3V,KAAK+C,MAAMosB,QAAU1O,EACrB,MACF,IAAK,KACHzgB,KAAK+C,MAAMosB,QAAU1O,EACrB,MACF,IAAK,KACHzgB,KAAK+C,MAAMusB,QAAU5O,EACrB,MACF,IAAK,KACH1gB,KAAK+C,MAAMusB,QAAU5O,EACrB,MACF,IAAK,IACH1gB,KAAK+C,MAAMqc,OAASqB,EAAO,EAKjC,CAEAE,QAAAA,CAASC,GACP,GAAI3W,MAAM4W,oCAAqC,OAAO,EACtD,MAAMqE,EAAallB,KAAKkoB,UAAY,EAAKloB,KAAK+C,MAAMosB,OAC9Ca,EAAchwB,KAAKqvB,WAAa,EAAKrvB,KAAK+C,MAAMusB,OAChD7I,EAAOpH,KAAKqF,IAAI1kB,KAAK2e,OAAOb,GAAKoH,EAAWllB,KAAK2e,OAAOb,GAAKoH,GAC7DqB,EAAQlH,KAAKwF,IAAI7kB,KAAK2e,OAAOb,GAAKoH,EAAWllB,KAAK2e,OAAOb,GAAKoH,GAC9DoB,EAAMjH,KAAKqF,IAAI1kB,KAAK2e,OAAOZ,GAAKiS,EAAYhwB,KAAK2e,OAAOZ,GAAKiS,GAC7DxJ,EAASnH,KAAKwF,IAAI7kB,KAAK2e,OAAOZ,GAAKiS,EAAYhwB,KAAK2e,OAAOZ,GAAKiS,GACtE,OAAIvJ,EAAO7F,EAAKjC,OAAOH,GAAKoC,EAAKjC,OAAOH,EAAI+H,GAASD,EAAM1F,EAAKjC,OAAOF,GAAKmC,EAAKjC,OAAOF,EAAI+H,GAGrFvc,MAAM0W,SAASC,EACxB,EAGFmO,EAAcjvB,UAAUsC,SAAW,CAAEwf,KAAM,iBAE3CmN,EAAcjvB,UAAUkhB,YAAc,CACpCC,OAAQ,CAAC,CAAEtL,KAAM,aAAcvS,KAAM,OAAQ0L,MAAO,UAGtD,U,gDCxIO,MAAMmhB,EAAqBhtB,OAAOitB,OAAO,CAC9C,CAAC1S,EAAAA,GAAkB1b,SAAUA,EAAAA,EAC7B,CAAC0b,EAAAA,GAAkBC,OAAQA,EAAAA,EAC3B,CAACD,EAAAA,GAAkB2D,SAAUgP,EAAAA,EAC7B,CAAC3S,EAAAA,GAAkBiI,WAAY2K,EAAAA,EAC/B,CAAC5S,EAAAA,GAAkB2N,OAAQA,EAAAA,EAC3B,CAAC3N,EAAAA,GAAkB6S,cAAeA,EAAAA,EAClC,CAAC7S,EAAAA,GAAkByO,SAAUA,EAC7B,CAACzO,EAAAA,GAAkB8S,WAAYC,EAAAA,EAC/B,CAAC/S,EAAAA,GAAkBgT,uBAAwBC,EAAAA,EAC3C,CAACjT,EAAAA,GAAkBkT,gBAAiBA,EAAAA,EACpC,CAAClT,EAAAA,GAAkB7G,MAAOA,EAAAA,EAC1B,CAAC6G,EAAAA,GAAkBmT,SAAUA,EAAAA,EAC7B,CAACnT,EAAAA,GAAkBoT,aAAcC,EAAAA,EACjC,CAACrT,EAAAA,GAAkBsN,SAAUA,EAAAA,EAC7B,CAACtN,EAAAA,GAAkB3F,UAAWA,EAAAA,EAC9B,CAAC2F,EAAAA,GAAkBsT,WAAYA,EAAAA,EAC/B,CAACtT,EAAAA,GAAkB0Q,kBAAmBA,EACtC,CAAC1Q,EAAAA,GAAkBuT,oBAAqBC,EAAAA,EACxC,CAACxT,EAAAA,GAAkByT,YAAaA,EAAAA,EAChC,CAACzT,EAAAA,GAAkB0T,YAAaA,EAAAA,EAChC,CAAC1T,EAAAA,GAAkBwR,QAASmC,EAC5B,CAAC3T,EAAAA,GAAkBqI,MAAOA,EAAAA,EAC1B,CAACrI,EAAAA,GAAkB4T,UAAWA,EAAAA,EAC9B,CAAC5T,EAAAA,GAAkB6T,cAAeA,EAAAA,EAClC,CAAC7T,EAAAA,GAAkB8T,OAAQA,EAAAA,G,8KCX7B,MAAM3mB,UAAgGjK,IAAAA,OACpG6c,YACEC,EAAAA,GAAkB1b,QAEpB,iBAAOyvB,CAA8BC,EAAiB9vB,GACpD,OAAO,IAAI1B,KAAKwxB,EAAK9vB,EACvB,CAEA,yBAAO+vB,CACLC,GAEA,OAAO,CACT,CAEAC,WAAY,EACZC,qBAAsB,EACtB7uB,MAAe,CAAC,EAEhBrB,MACAkc,QAmBAiU,YAA4B,KAC5BC,aAAc,EACdC,YAAa,EACbC,WAAY,EACZC,kBAAmB,EACnBzN,aAAkC,KAKlCrhB,WAAAA,CAAY+E,EAAwBxG,GAClCuI,MAAM/B,EAAQxG,GACd1B,KAAK0B,MAAQA,EACT1B,KAAKme,YACPne,KAAKmf,IAAInf,KAAKme,eAAiB,CAAC,GAEhCne,KAAKmf,IAAInf,KAAKoC,UAAY,CAAC,GAE7BpC,KAAKmf,IAAIjX,GACTlI,KAAK4d,QAAU,GAEf5d,KAAKkyB,YAAclyB,KAAKkyB,YAAYvxB,KAAKX,MACzCA,KAAKmyB,YAAcnyB,KAAKmyB,YAAYxxB,KAAKX,MACzCA,KAAKijB,UAAYjjB,KAAKijB,UAAUtiB,KAAKX,MACrCA,KAAKW,KAAK,YAAaX,KAAKkyB,aAC5BlyB,KAAKW,KAAK,YAAaX,KAAKmyB,aAC5BnyB,KAAKW,KAAK,UAAWX,KAAKijB,WAC1BjjB,KAAKW,KAAK,UAAU,KAElB,MAAMmB,EAAU9B,KAAKoyB,kBACjBpyB,KAAK0B,MAAMkI,iBAAiByoB,gBAAgB,WAAYryB,MACxDA,KAAK0B,MAAMgU,cAAc2c,gBAAgB,WAAYryB,MAEzD8B,GAASyH,QAAQ,SAAUzH,EAAQ,GAEvC,CAEA,QAAI6T,GACF,OAAQ3V,KAAKmD,YAA+BwS,IAC9C,CAEA+M,SAAAA,GACE,OAAO1iB,KAAK4d,OACd,CAEA4C,MAAAA,CAAOkR,EAAWY,GAAa,CAE/BC,aAAAA,CAAcR,GACZ/xB,KAAK+xB,WAAaA,EAClB/xB,KAAKuJ,QAAQ,SACf,CAEAipB,YAAAA,CAAaR,GACXhyB,KAAKgyB,UAAYA,EACjBhyB,KAAKuJ,QAAQ,SACf,CAEA+W,qBAAAA,GACE,OAAOtgB,KAAK+xB,YAAc/xB,KAAKgyB,SACjC,CAEAS,kBAAAA,GACE,MAAM1rB,EAAY/G,KAAK0B,MAAMgU,WAAW2c,gBAAgB,WAAYryB,OAAO0yB,OAC3E,OAAO3rB,GAAW4rB,YAAc3yB,IAClC,CAEAmf,GAAAA,CAAIqS,GACF,MAAMoB,EAAc3vB,OAAOC,KAAKsuB,GAAKzkB,QACnC,CAACC,EAAKW,KAAQ,IAAMX,EAAK,CAACW,GAAM3N,KAAK+C,MAAM4K,MAC3C,CAAC,GAEH,GAAIqZ,KAAKC,UAAUuK,KAASxK,KAAKC,UAAU2L,GAAc,CACvD,MAAMC,EAAaA,CAACC,EAA0BC,EAA0BplB,KACtE,GAAI3N,KAAKgzB,gBAA0B,eAARrlB,EACzB,OAAOolB,GAAY,CAAC,CACtB,EAEFE,IAAUjzB,KAAK+C,MAAOyuB,EAAKqB,GACvB7yB,KAAKyyB,uBAAyBzyB,KAAKgjB,gBACrChjB,KAAKwjB,8BAEPxjB,KAAKuJ,QAAQ,SAAUvJ,KACzB,CAEA,OADAA,KAAKwkB,aAAe,KACbxkB,IACT,CAEAkzB,GAAAA,CAA2BvlB,GACzB,OAAO3N,KAAK+C,MAAM4K,EACpB,CAEAuQ,qBAAuBA,OAEvBiE,GAAM3D,GAAcxe,KAAK0B,MAAMyV,MAAMqH,EAAEA,GAEvC4D,GAAM3D,GAAcze,KAAK0B,MAAMyV,MAAMsH,EAAEA,GAEvCtH,KAAAA,CAAKxP,GAAyC,IAAxC,EAAE6W,EAAC,EAAEC,GAAiC9W,EAC1C3H,KAAK2e,OAAS,CAAC,EACfH,EAAEjW,SAASrG,IACTe,OAAOkwB,eAAenzB,KAAK2e,OAAQzc,EAAI,CACrCgxB,IAAKA,IAAMlzB,KAAKmiB,GAAGniB,KAAK+C,MAAMb,KAC9B,IAGJuc,EAAElW,SAASrG,IACTe,OAAOkwB,eAAenzB,KAAK2e,OAAQzc,EAAI,CACrCgxB,IAAKA,IAAMlzB,KAAKoiB,GAAGpiB,KAAK+C,MAAMb,KAC9B,GAEN,CAEA2lB,MAAAA,CAAO6J,GAA4B,CAEnCnR,YAAAA,CAAa7B,GACiB1e,KAAKgyB,YAAchyB,KAAK+xB,aAElDrT,EAAQ0U,YAAc,IAExBpzB,KAAK0iB,YAAYhV,KAAK2lB,GAAUA,EAAMxL,OAAOnJ,KAC7CA,EAAQ0U,YAAc,CACxB,CAEAlB,WAAAA,CAAYtR,GACV5gB,KAAK8xB,aAAc,EACnB9xB,KAAKiyB,kBAAmB,EACxB,IAAK,MAAMoB,KAASrzB,KAAK0iB,YACvB,GAAI2Q,EAAM1S,SAASC,GAGjB,OAFA5gB,KAAK6xB,YAAcwB,OACnBrzB,KAAK6xB,YAAYyB,aAAa1S,EAIpC,CAEAuR,WAAAA,CAAYvR,GACLA,EAAK2S,WAGc,MAApBvzB,KAAK6xB,cACP7xB,KAAK6xB,YAAYtS,OAAOqB,GACxB5gB,KAAKuJ,QAAQ,UAEjB,CAEA0Z,SAAAA,CAAUyO,GACR1xB,KAAK8xB,aAAc,EACnB9xB,KAAKiyB,kBAAmB,EACxBjyB,KAAK6xB,YAAc,KACd7xB,KAAKgjB,gBAAmBhjB,KAAKoyB,mBAChCpyB,KAAKwjB,8BAEPxjB,KAAKuJ,QAAQ,SAAUvJ,KACzB,CAEAwjB,4BAA8BA,KAC5B,MAAM7Z,EAAQ3J,KAAK0B,OAAOgI,QAAQC,QAClC,GAAIA,EAAO,CACT,MAAQ6U,EAAGgV,GAAexzB,KAAKke,uBACzBuV,EAAqBD,EAAWzmB,QAAO,CAACC,EAAKW,KACjD,MAAM+lB,EAAY1zB,KAAK+C,MAAM4K,GAE7B,MAAO,IACFX,EACH,CAACW,GAHe+lB,GAAa/pB,EAAM+Z,yBAAyBgQ,GAI7D,GACA,CAAC,GACJ1zB,KAAKmf,IAAI,CAAEsU,sBACb,GAGF9P,YAAAA,GACE,MAAMha,EAAQ3J,KAAK0B,MAAMgI,QAAQC,SAC3B,mBAAE8pB,GAAuBzzB,KAAK+C,MACpC,IAAK4G,IAAU8pB,EAGb,OAEF,MAAME,EAA6B1wB,OAAOuK,QAAQimB,GAAoB1mB,QACpE,CAACC,EAAG5E,KAAA,IAAGuF,EAAKnL,GAAU4F,EAAA,MAAM,IACvB4E,EACH,CAACW,GAAMnL,GAAamH,EAAMia,0BAA0BphB,GACrD,GACD,CAAC,GAEHxC,KAAKmf,IAAIwU,EACX,CAEA5H,eAAAA,CAAgBnL,GACd,IAAK,MAAMyS,KAASrzB,KAAK0iB,YACvB,GAAI2Q,EAAM1S,SAASC,GACjB,OAAO,EAGX,OAAO,CACT,CAEAD,QAAAA,CAASC,GACP,OAAO5gB,KAAK+rB,gBAAgBnL,EAC9B,CAEAC,iCAAAA,GACE,OAAO7gB,KAAK0B,MAAMgI,QAAQkqB,eAAeC,uBAAyB7zB,KAAK8zB,cACzE,CAEAC,cAAAA,GACE,IAAIC,EAEFA,EADEh0B,KAAK0lB,mBACEwB,IAAM,CAAC,EAAGlnB,KAAK0lB,sBAEfwB,IAAM,CAAC,EAAGlnB,KAAKghB,aAEtBhhB,KAAKgzB,gBACPgB,EAAO/S,OAAO1f,KAAK,CAAEoU,KAAM,aAAcvS,KAAM,aAAc0L,MAAO,eAElD,MAAhBklB,EAAOxwB,QACTwwB,EAAOxwB,MAAQxD,KAAKoD,MAEtB,IAAK,MAAM6wB,KAASD,EAAO/S,OACJ,MAAjBgT,EAAMlP,UACRkP,EAAMrmB,MAAQqmB,EAAMlP,SAEQ,MAA1B/kB,KAAK+C,MAAMkxB,EAAM7wB,QACnB6wB,EAAMrmB,MAAQ5N,KAAK+C,MAAMkxB,EAAM7wB,OAGnC,OAAO4wB,CACT,CAEAhqB,QAAAA,GACE,OAAOkd,IAAM,CAAC,EAAGlnB,KAAK+C,MAAO,CAAE4S,KAAM3V,KAAK2V,MAC5C,CAEAzL,QAAAA,GACE,OAAOlK,KAAKgK,UACd,CAEAsa,4BAAAA,GACE,OAAOtkB,KAAK+C,MAAM0wB,mBAAqBxwB,OAAOC,KAAKlD,KAAK+C,MAAM0wB,oBAAsB,EACtF,CAEAS,gBAAAA,GAGE,OAAOC,IAAKn0B,KAAKkK,WAAYlK,KAAKskB,+BACpC,CAEA8P,aAAAA,CAActyB,GACZub,YAAW,KACTvb,EAAQ0hB,8BACR,MAAMthB,EAAKlC,KAAK0B,MAAMgU,WAAW2c,gBAAgB,WAAYryB,MACxDkC,EAwBHA,EAAGmX,QAAQvX,GArBX+D,OAAOwV,QAAQgZ,eAAe,2BAA4B,CACxDhrB,MAAO,CACLirB,WAAY,CACV3e,KAAM3V,MAAM2V,KACZgc,UAAW3xB,MAAM2xB,UACjBG,YAAa9xB,MAAM8xB,YACnBC,WAAY/xB,MAAM+xB,WAClBC,UAAWhyB,MAAMgyB,UACjBC,iBAAkBjyB,MAAMiyB,kBAE1BsC,WAAY,CACV5e,KAAM7T,GAAS6T,KACfgc,UAAW7vB,GAAS6vB,UACpBG,YAAahwB,GAASgwB,YACtBC,WAAYjwB,GAASiwB,WACrBC,UAAWlwB,GAASkwB,UACpBC,iBAAkBnwB,GAASmwB,oBAMnC,GAEJ,CAEA1tB,QAAAA,GACE,OAAOvE,KAAKoD,IACd,CAEA4f,YAAAA,GACE,OAAOhjB,KAAK2xB,SACd,CAEA6C,sBAAAA,GACE,OAAOx0B,KAAK4xB,mBACd,CAEA6C,OAAAA,GACEz0B,KAAKwjB,8BACLxjB,KAAK2B,QACP,CAEA0c,sBAAAA,GACE,OAAOA,EAAAA,EAAAA,IAAuBre,KAAK0B,MAAMgI,QAAQkqB,eACnD,CAEAZ,YAAAA,GACE,QAAShzB,KAAK2V,KAAKrV,WAAW,UAChC,CAEA8xB,eAAAA,GACE,QAASpyB,MAAM2V,KAAKrV,WAAW,cACjC,CAEAwzB,YAAAA,GACE,MAAM,MAAEY,EAAK,MAAEC,GAAUC,EAAAA,GAAoB50B,KAAK0B,MAAMgI,QAAQC,QAAQ8K,WAClEogB,EAAa70B,KAAK+C,MAAM8xB,aAAaF,GAG3C,YAAmBtsB,IAAfwsB,GAEmC,IAAnC5xB,OAAOC,KAAK2xB,GAAY50B,SAErB60B,EAAAA,EAAAA,IAAU,CAAElnB,MAAO8mB,EAAOhQ,IAAKmQ,EAAWE,KAAMlQ,IAAKgQ,EAAWG,IACzE,CAEAC,eAAAA,CAAgBC,GACd,MAAM,MAAEP,EAAK,MAAED,GAAUE,EAAAA,GAAoB50B,KAAK0B,MAAMgI,QAAQC,QAAQ8K,WAClE+S,EAAevkB,OAAOC,KAAKiyB,EAAAA,IAAgB30B,QAAQm0B,GAEzD,IAAIS,EAA4B,GAC5BC,EAA6C,CAAC,EAElD,OAAQH,GACN,KAAKI,EAAAA,GAAgBC,gBACnBH,EAAkBnyB,OAAOC,KAAKiyB,EAAAA,IAAgBvd,QAAO,CAACjK,EAAK1L,IAAUA,EAAQulB,IAC7E6N,EAAa,CAAEN,KAAML,GACrB,MAEF,KAAKY,EAAAA,GAAgBE,gBACnBJ,EAAkBnyB,OAAOC,KAAKiyB,EAAAA,IAAgBvd,QAAO,CAACjK,EAAK1L,IAAUA,EAAQulB,IAC7E6N,EAAa,CAAEL,GAAIN,GACnB,MAEF,KAAKY,EAAAA,GAAgBG,YACnBL,EAAkBnyB,OAAOC,KAAKiyB,EAAAA,IAAgBvd,QAAO,CAACjK,EAAK1L,IAAUA,IAAUulB,IAC/E6N,EAAa,CAAEN,KAAML,EAAOM,GAAIN,GAChC,MAEF,KAAKY,EAAAA,GAAgBtzB,IACrB,QAEE,YADAhC,KAAKmf,IAAI,CAAE0V,WAAY,CAAC,IAK5B70B,KAAKmf,IAAI,CACP0V,WAAY5xB,OAAOyyB,OAAO,CAAC,KAAMN,EAAgB1nB,KAAK9L,IAAI,CAAQ,CAACA,GAAO,CAAC,MAAO,CAAE,CAAC+yB,GAAQU,KAEjG,CAEA9Q,eAAAA,GACE,MAAQ/F,EAAGmX,EAASlX,EAAGmX,GAAY51B,KAAKke,wBAA0B,CAAC,EACnE,GAA0B,OAAtBle,KAAKwkB,aAAuB,CAC9B,MAAMA,EAAe,CAAC,EACtBmR,GAASptB,SAASoF,IAChB,MAAM+lB,EAAY1zB,KAAK+C,MAAM4K,QACXtF,IAAdqrB,IACFlP,EAAaC,KAAOpF,KAAKqF,IAAIgP,EAAWlP,EAAaC,MAAQiP,GAC7DlP,EAAaI,KAAOvF,KAAKwF,IAAI6O,EAAWlP,EAAaI,MAAQ8O,GAC/D,IAEFkC,GAASrtB,SAASoF,IAChB,MAAMkoB,EAAY71B,KAAK+C,MAAM4K,QACXtF,IAAdwtB,IACFrR,EAAaG,KAAOtF,KAAKqF,IAAImR,EAAWrR,EAAaG,MAAQkR,GAC7DrR,EAAaM,KAAOzF,KAAKwF,IAAIgR,EAAWrR,EAAaM,MAAQ+Q,GAC/D,IAGF71B,KAAKwkB,aAAeA,CACtB,CAEA,OAAOxkB,KAAKwkB,YACd,CAEAwG,gBAAAA,CAAiBthB,EAAchF,GAC7B,MAAM,KAAE+f,EAAI,KAAEG,EAAI,KAAED,EAAI,KAAEG,GAAS9kB,KAAKukB,kBAExC,GAAIvkB,KAAKgjB,eACP,OAAO,EAGT,IAAKte,GAASoxB,MAAO,CACnB,MAAMC,OAAyB1tB,IAATuc,GAAsBoR,MAAMpR,GAC5CqR,OAAyB5tB,IAAToc,GAAsBuR,MAAMvR,GAClD,KACGsR,GACAE,GACCj2B,KAAKmiB,GAAGyC,KAAUlb,EAAMuhB,YAAcjrB,KAAKmiB,GAAGsC,KAAU/a,EAAMuhB,WAAavhB,EAAMlC,OAEnF,OAAO,CAEX,CAEA,IAAK9C,GAASwxB,MAAO,CACnB,QAAa7tB,IAATsc,QAA+Btc,IAATyc,EACxB,OAAO,EAGT,MAAMqR,EAAWn2B,KAAK0B,MAAMyV,MAAMsH,EAAEyN,OAAO,GACrCkK,EAAcp2B,KAAK0B,MAAMyV,MAAMsH,EAAEyN,OAAOlsB,KAAK0B,MAAM+F,QACzD,OAAO0uB,GAAYxR,GAAQyR,GAAetR,CAC5C,CAGA,OAAO,CACT,EAGF,S,oHCheA,MAAMuR,UAA4E1rB,EAAAA,EAChF4S,YAAcC,EAAAA,GAAkB6S,aAEhCjtB,KAAO,eACPkzB,MAAQ,CAAC,GAAI,IAAK,KAAM,MAAO,KAAM,KAErCnzB,WAAAA,CAAY+E,EAAwBxG,GAClCuI,MAAM/B,EAAQxG,GACd1B,KAAK2d,OAAS3d,KAAK2d,OAAOhd,KAAKX,KACjC,CAEAme,WAAAA,GACE,MAAO,CACLC,OAAQ,CACN5W,MAAO,EACP0Q,MAAOlY,KAAKqe,yBAAyBC,gBAAgBC,OAAO5H,MAGlE,CAEA+G,aAAAA,CAAcgB,GACZ,MAAM6X,GAASC,EAAAA,EAAAA,IAAuBx2B,KAAK+C,MAAMqb,OAAO5W,OACxDkX,EAAQS,IAAI,YAAanf,KAAK+C,MAAMqb,OAAO5W,OAC3CkX,EAAQS,IAAI,cAAenf,KAAK+C,MAAMqb,OAAOlG,OAE7CwG,EAAQO,UAAUsX,EAAQA,GAC1B7X,EAAQQ,YACRR,EAAQa,OAAOF,KAAK2E,MAAMhkB,KAAKmiB,GAAGniB,KAAK+C,MAAMuzB,MAAM,GAAG9X,IAAKa,KAAK2E,MAAMhkB,KAAKoiB,GAAGpiB,KAAK+C,MAAMuzB,MAAM,GAAG7X,KAClG,IAAK,MAAMgY,KAAKz2B,KAAK+C,MAAMuzB,MAAMj2B,MAAM,GACrCqe,EAAQc,OAAOH,KAAK2E,MAAMhkB,KAAKmiB,GAAGsU,EAAEjY,IAAKa,KAAK2E,MAAMhkB,KAAKoiB,GAAGqU,EAAEhY,KAEhEC,EAAQe,SACRf,EAAQO,WAAoB,EAAVsX,GAAuB,EAAVA,GAE/B,MAAM1Q,EAAO,IAAIL,EAAAA,EACf,CACEM,KAAM,CAAEtW,KAAM,EAAG2G,MAAO,QACxBiQ,aAAcsQ,EAAAA,GAAaC,OAC3BxQ,UAAWyQ,EAAAA,GAAUC,OACrB5Q,UAAWjmB,KAAKqe,yBAAyBC,gBAAgBC,OAAOqH,uBAElE5lB,KAAK0B,OAEP,IAAK,IAAIwgB,EAAI,EAAGA,EAAIliB,KAAK+C,MAAMuzB,MAAMr2B,OAAQiiB,IAAK,CAChD,IAAIzD,EACJ,MAAMgY,EAAIz2B,KAAK+C,MAAMuzB,MAAMpU,GAEzBzD,EADEyD,EAAI,GAAKliB,KAAK+C,MAAMuzB,MAAMpU,EAAI,GAAGzD,EAAIgY,EAAEhY,EACrCze,KAAKoiB,GAAGqU,EAAEhY,GAAK,EAEfze,KAAKoiB,GAAGqU,EAAEhY,GAAK,EAErBoH,EAAK1G,IAAI,CAAE0G,KAAM7lB,KAAKs2B,MAAMpU,GAAI1D,EAAGxe,KAAKmiB,GAAGsU,EAAEjY,GAAIC,MACjDoH,EAAKgC,OAAOnJ,EACd,CAEI1e,KAAKsgB,yBACPtgB,KAAKugB,aAAa7B,EAEtB,CAEAgE,SAAAA,GACE,OAAO1iB,KAAK+C,MAAMuzB,MAAM5oB,KACtB,CAACopB,EAAM70B,IACL,IAAI4b,EAAAA,EACD,GAAE5b,KACH,IAAM60B,EAAKtY,IACX,IAAMsY,EAAKrY,GACXze,KAAK2d,OACL3d,KAAK0B,QAGb,CAEA8hB,4BAA8BA,KAC5B,MAAM7Z,EAAQ3J,KAAK0B,OAAOgI,QAAQC,QAClC,GAAIA,EAAO,CACT,MAAMotB,EAA0B/2B,KAAK+C,MAAMuzB,MAAM5oB,KAAKopB,IAAI,IACrDA,EACHtY,EAAG7U,EAAM+Z,yBAAyBoT,EAAKtY,OAGzCxe,KAAKmf,IAAI,CAAE4X,2BACb,GAGFpT,YAAAA,GACE,MAAMha,EAAQ3J,KAAK0B,MAAMgI,QAAQC,SAC3B,wBAAEotB,GAA4B/2B,KAAK+C,MACzC,IAAK4G,IAAUotB,EAGb,OAEF,MAAMT,EAAQS,EAAwBrpB,KAAKopB,IAAI,IAC1CA,EACHtY,EAAG7U,EAAMia,0BAA0BkT,EAAKtY,OAE1Cxe,KAAKmf,IAAI,CAAEmX,SACb,CAEA9V,MAAAA,CAAOhC,EAAWC,GAChB,IAAK,MAAM+D,KAASxiB,KAAK+C,MAAMuzB,MAC7B9T,EAAMhE,GAAKA,EACXgE,EAAM/D,GAAKA,CAEf,CAEAd,MAAAA,CAAMhW,GAAqD,IAApD,KAAEgO,EAAI,KAAE8K,EAAI,KAAEC,GAAoC/Y,EACvD3H,KAAK+C,MAAMuzB,OAAO3gB,GAAM6I,GAAKiC,EAC7BzgB,KAAK+C,MAAMuzB,OAAO3gB,GAAM8I,GAAKiC,CAC/B,CAEAC,QAAAA,CAASC,GACP,GAAI3W,MAAM4W,oCAAqC,OAAO,EACtD,MAAMyV,EAAQt2B,KAAK+C,MAAMuzB,MACzB,IAAK,IAAIpU,EAAI,EAAGA,EAAIoU,EAAMr2B,OAAS,EAAGiiB,IACpC,GACEpB,EAAAA,GAAKC,kBAAkBH,EAAKjC,OAAQ,CAClCb,GAAI9d,KAAKmiB,GAAGmU,EAAMpU,GAAG1D,GACrBT,GAAI/d,KAAKoiB,GAAGkU,EAAMpU,GAAGzD,GACrBT,GAAIhe,KAAKmiB,GAAGmU,EAAMpU,EAAI,GAAG1D,GACzBP,GAAIje,KAAKoiB,GAAGkU,EAAMpU,EAAI,GAAGzD,MACrB,GAEN,OAAO,EAGX,OAAOxU,MAAM0W,SAASC,EACxB,CAEA0D,4BAAAA,GACE,MAAO,CAAC,QACV,EAGF+R,EAAav2B,UAAUkhB,YAAc,CACnCC,OAAQ,CAAC,CAAEtL,KAAM,OAAQvS,KAAM,YAGjC,S,yGC3HA,MAAM4zB,UAA+DrsB,EAAAA,EACnE4S,YAAcC,EAAAA,GAAkB8S,UAEhCltB,KAAO,UAEPge,oBAAuD,KAIvDje,WAAAA,CAAY+E,EAAwBxG,GAClCuI,MAAM/B,EAAQxG,GACd1B,KAAK2d,OAAS3d,KAAK2d,OAAOhd,KAAKX,MAC/BA,KAAKohB,qBAAsBK,EAAAA,EAAAA,GAAoB7W,SAAS8W,cAAc,WACtE1hB,KAAK4d,QAAU,CACb,IAAIC,EAAAA,EACF,QACA,IAAM7d,KAAK+C,MAAM+a,KACjB,IAAM9d,KAAK+C,MAAMgb,IACjB/d,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,SACA,IAAM7d,KAAK+C,MAAMib,KACjB,IAAMhe,KAAK+C,MAAMkb,IACjBje,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,OACA,IAAM7d,KAAKi3B,kBAAiB,GAAMC,GAAG1Y,GAAKxe,KAAK+C,MAAM+a,KACrD,IAAM9d,KAAKi3B,kBAAiB,GAAMC,GAAGzY,GAAKze,KAAK+C,MAAMgb,IACrD/d,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,UACA,IAAM7d,KAAKi3B,kBAAiB,GAAME,GAAG3Y,GAAKxe,KAAK+C,MAAMib,KACrD,IAAMhe,KAAKi3B,kBAAiB,GAAME,GAAG1Y,GAAKze,KAAK+C,MAAMkb,IACrDje,KAAK2d,OACL3d,KAAK0B,QAGT1B,KAAKmX,MAAMnX,KAAKke,uBAClB,CAEAC,WAAAA,GACE,MAAM,gBAAEG,GAAoBte,KAAKqe,yBACjC,MAAO,CACLuD,KAAMtD,EAAgBqI,YACtBvI,OAAQ,CACN5W,MAAO,EACP0Q,MAAOoG,EAAgBC,OAAOH,QAGpC,CAEAF,qBAAuBA,KAAA,CAASM,EAAG,CAAC,KAAM,KAAM,iBAAkBC,EAAG,CAAC,KAAM,KAAM,mBAElFf,aAAAA,CAAcgB,GACZ,MAAM0Y,EAAcp3B,KAAKi3B,mBACnBhL,EAAU,IAAIjK,OACpBtD,EAAQS,IAAI,YAAanf,KAAK+C,MAAM6e,MACpClD,EAAQQ,YACJkY,EAAYF,GAAG1Y,IAAM4Y,EAAYC,GAAG7Y,GAAK4Y,EAAYF,GAAGzY,IAAM2Y,EAAYC,GAAG5Y,GAC/EwN,EAAQzM,OAAO4X,EAAYE,GAAG9Y,EAAG4Y,EAAYE,GAAG7Y,GAChDwN,EAAQzM,OAAO4X,EAAYF,GAAG1Y,EAAG4Y,EAAYF,GAAGzY,KAEhDwN,EAAQ1M,OAAO6X,EAAYD,GAAG3Y,EAAG4Y,EAAYD,GAAG1Y,GAChDwN,EAAQW,cACNwK,EAAYG,IAAI/Y,EAChB4Y,EAAYG,IAAI9Y,EAChB2Y,EAAYI,IAAIhZ,EAChB4Y,EAAYI,IAAI/Y,EAChB2Y,EAAYF,GAAG1Y,EACf4Y,EAAYF,GAAGzY,GAEjBwN,EAAQW,cACNwK,EAAYK,IAAIjZ,EAChB4Y,EAAYK,IAAIhZ,EAChB2Y,EAAYM,IAAIlZ,EAChB4Y,EAAYM,IAAIjZ,EAChB2Y,EAAYD,GAAG3Y,EACf4Y,EAAYD,GAAG1Y,GAEjBwN,EAAQxJ,YACRziB,KAAK23B,YAAc1L,EACnBvN,EAAQkD,KAAKqK,IAGfvN,EAAQS,IAAI,YAAanf,KAAK+C,MAAMqb,OAAO5W,OAC3CkX,EAAQS,IAAI,cAAenf,KAAK+C,MAAMqb,OAAOlG,OAC7CwG,EAAQe,OAAOwM,GAEXjsB,KAAKsgB,yBACPtgB,KAAKugB,aAAa7B,EAEtB,CAEAuY,gBAAAA,GAAmC,IAAlBW,EAAQx2B,UAAAnB,OAAA,QAAAoI,IAAAjH,UAAA,IAAAA,UAAA,GACvB,MAAM,GAAE0c,EAAE,GAAEE,EAAE,GAAED,EAAE,GAAEE,EAAE,cAAE4Z,EAAa,cAAEC,GAAkB93B,KAAK2e,OAExD2Y,EAAK,CAAE9Y,EAAGR,EAAIS,EAAGR,GACjBoZ,EAAK,CAAE7Y,EAAGV,EAAIW,EAAGV,GAEvB,IAAIga,EACJ,GAAK/B,MAAM6B,IAAmB7B,MAAM8B,GASlC,MAAO,CACLR,GAAID,EACJH,GAAII,EACJD,GAAIC,EACJH,GAAIE,GAb4C,CAClD,MAAMW,EAAS,CAAExZ,EAAGqZ,EAAepZ,EAAGqZ,GAChCnhB,EAAO,CAAEmH,KAAIC,KAAIC,KAAIC,MACrBqH,EAAWxE,EAAAA,GAAKmX,eAAeD,EAAQrhB,GAC7CohB,EAAqBjX,EAAAA,GAAK4J,yBAAyB,CACjDpF,WACA3O,QAEJ,CASA,MAAMuhB,GAAeZ,EAAG9Y,EAAI6Y,EAAG7Y,GAAK,EAC9B2Z,GAAeb,EAAG7Y,EAAI4Y,EAAG5Y,GAAK,EAC9BkM,EAAeoN,EAAmBvZ,EAAI8Y,EAAG9Y,EACzCoM,EAAemN,EAAmBtZ,EAAI6Y,EAAG7Y,EAEzCyY,EAAK,CAAE1Y,EAAG0Z,EAAcvN,EAAclM,EAAG0Z,EAAcvN,GACvDuM,EAAK,CAAE3Y,EAAG0Z,GAAe,EAAIvN,EAAclM,EAAG0Z,GAAe,EAAIvN,GACjEwN,EAAUp4B,KAAK0B,MAAMyV,MAAMqH,EAAE0N,OAC7BmM,EAAUr4B,KAAK0B,MAAMyV,MAAMsH,EAAEyN,OACnC,GAAI0L,EACF,MAAO,CACLV,GAAI,CAAE1Y,EAAG4Z,EAAQlB,EAAG1Y,GAAIC,EAAG4Z,EAAQnB,EAAGzY,IACtC0Y,GAAI,CAAE3Y,EAAG4Z,EAAQjB,EAAG3Y,GAAIC,EAAG4Z,EAAQlB,EAAG1Y,KAI1C,MAAM6Z,GAAoCP,EAAmBvZ,EAAI0Y,EAAG1Y,GAAK,KAAQuZ,EAAmBvZ,EAAI0Y,EAAG1Y,GACrG+Z,GAAoCR,EAAmBtZ,EAAIyY,EAAGzY,GAAK,KAAQsZ,EAAmBtZ,EAAIyY,EAAGzY,GAErG+Z,EAAgBlB,EAAG9Y,EAAI8Z,EACvBG,EAAgBnB,EAAG7Y,EAAI8Z,EAEvBG,EAAgBrB,EAAG7Y,EAAI8Z,EACvBK,EAAgBtB,EAAG5Y,EAAI8Z,EAEvBf,EAAM,CACVhZ,EAAGuZ,EAAmBvZ,EAAI8Z,EAC1B7Z,EAAGsZ,EAAmBtZ,EAAI8Z,GAEtBK,EAAsBpB,EAAIhZ,EAAIga,EAC9BK,EAAsBrB,EAAI/Y,EAAIga,EAMpC,MAAO,CACLnB,KACAJ,KACAG,KACAF,KACAK,MACAC,IAVU,CAAEjZ,EAAGka,EAAgBE,EAAqBna,EAAGka,EAAgBE,GAWvEnB,IAVU,CAAElZ,EAAGka,GAAiB,EAAIE,EAAqBna,EAAGka,GAAiB,EAAIE,GAWjFtB,IAVU,CAAE/Y,EAAGga,GAAiB,EAAII,EAAqBna,EAAGga,GAAiB,EAAII,GAYrF,CAEAC,2BAA6BnxB,IAUvB,IAVwB,kBAC5BoxB,EAAiB,cACjBC,EAAa,aACbC,EAAY,aACZC,GAMDvxB,EACC,MAAMyX,EAAQ0B,EAAAA,GAAKqY,sBAAsB,CACvCC,YAAaL,EACbE,eACAC,iBAEIG,EAAyBvY,EAAAA,GAAKwY,wBAAwB,CAC1DP,oBACA3Z,QACA4Z,kBAEF,MAAO,CACLxa,EAAGxe,KAAK0B,MAAMyV,MAAMqH,EAAE0N,OAAOmN,EAAuB7a,GACpDC,EAAGze,KAAK0B,MAAMyV,MAAMsH,EAAEyN,OAAOmN,EAAuB5a,GACrD,EAGH+B,MAAAA,CAAOhC,EAAWC,GAChBze,KAAK+C,MAAM+a,IAAMU,EACjBxe,KAAK+C,MAAMgb,IAAMU,EACjBze,KAAK+C,MAAMib,IAAMQ,EACjBxe,KAAK+C,MAAMkb,IAAMQ,EACjBze,KAAK+C,MAAM80B,eAAiBrZ,EAC5Bxe,KAAK+C,MAAM+0B,eAAiBrZ,CAC9B,CAEAd,MAAAA,CAAMvV,GAA2D,IAA1D,KAAEuN,EAAI,KAAE8K,EAAI,KAAEC,EAAI,KAAEE,GAAoCxY,EAC7D,OAAQuN,GACN,IAAK,OACH,MAAM4jB,EAAe,CACnB/a,EAAGxe,KAAK+C,MAAM+a,GAAK2C,EACnBhC,EAAGze,KAAK+C,MAAMgb,GAAK2C,GAEf8Y,EAAyBx5B,KAAK84B,2BAA2B,CAC7DC,kBAAmB,CAAEva,EAAGxe,KAAK2e,OAAOX,GAAIS,EAAGze,KAAK2e,OAAOV,IACvD+a,cAAe,CACbxa,EAAGxe,KAAK2e,OAAOkZ,cACfpZ,EAAGze,KAAK2e,OAAOmZ,eAEjBmB,aAAc,CAAEza,EAAGxe,KAAK2e,OAAOb,GAAIW,EAAGze,KAAK2e,OAAOZ,IAClDmb,aAAc,CAAE1a,EAAGxe,KAAK0B,MAAMyV,MAAMqH,EAAE+a,EAAa/a,GAAIC,EAAGze,KAAK0B,MAAMyV,MAAMsH,EAAE8a,EAAa9a,MAE5Fze,KAAK+C,MAAQ,IACR/C,KAAK+C,MACR+a,GAAIyb,EAAa/a,EACjBT,GAAIwb,EAAa9a,EACjBoZ,cAAe2B,EAAuBhb,EACtCsZ,cAAe0B,EAAuB/a,GAExC,MACF,IAAK,QACH,MAAMgb,EAAgB,CACpBjb,EAAGxe,KAAK+C,MAAMib,GAAKyC,EACnBhC,EAAGze,KAAK+C,MAAMkb,GAAKyC,GAEfgZ,EAA0B15B,KAAK84B,2BAA2B,CAC9DC,kBAAmB,CAAEva,EAAGxe,KAAK2e,OAAOb,GAAIW,EAAGze,KAAK2e,OAAOZ,IACvDib,cAAe,CACbxa,EAAGxe,KAAK2e,OAAOkZ,cACfpZ,EAAGze,KAAK2e,OAAOmZ,eAEjBmB,aAAc,CAAEza,EAAGxe,KAAK2e,OAAOX,GAAIS,EAAGze,KAAK2e,OAAOV,IAClDib,aAAc,CAAE1a,EAAGxe,KAAK0B,MAAMyV,MAAMqH,EAAEib,EAAcjb,GAAIC,EAAGze,KAAK0B,MAAMyV,MAAMsH,EAAEgb,EAAchb,MAE9Fze,KAAK+C,MAAQ,IACR/C,KAAK+C,MACRib,GAAIyb,EAAcjb,EAClBP,GAAIwb,EAAchb,EAClBoZ,cAAe6B,EAAwBlb,EACvCsZ,cAAe4B,EAAwBjb,GAEzC,MACF,IAAK,MACL,IAAK,SACHze,KAAK+C,MAAQ,IACR/C,KAAK+C,MACR80B,cAAejX,EAAKpC,EACpBsZ,cAAelX,EAAKnC,GAM5B,CAEAkC,QAAAA,CAASC,GACP,OAAI3W,MAAM4W,yCACN7gB,KAAK23B,cAAe33B,KAAKohB,qBAAqBmC,cAAcvjB,KAAK23B,YAAa/W,EAAKjC,OAAOH,EAAGoC,EAAKjC,OAAOF,KAGtGxU,MAAM0W,SAASC,GACxB,CAEAoK,gBAAAA,GACE,OAAO,CACT,EAGFgM,EAAUl3B,UAAUkhB,YAAc,CAChCC,OAAQ,CACN,CAAEtL,KAAM,aAAcvS,KAAM,QAC5B,CAAEuS,KAAM,SAAUvS,KAAM,SAAUshB,IAAK,EAAGK,QAAS,CAAC,KAIxD,S,yGC1SA,MAAM4U,UAEIhvB,EAAAA,EACR4S,YAAcC,EAAAA,GAAkBgT,sBAEhCptB,KAAO,yBAIPD,WAAAA,CAAY+E,EAAwBxG,GAClCuI,MAAM/B,EAAQxG,GACd1B,KAAK2d,OAAS3d,KAAK2d,OAAOhd,KAAKX,MAC/BA,KAAK4d,QAAU,CACb,IAAIC,EAAAA,EACF,oBACA,IAAM7d,KAAK+C,MAAM+a,KACjB,IAAM9d,KAAK+C,MAAMgb,IACjB/d,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,oBACA,IAAM7d,KAAK+C,MAAMib,KACjB,IAAMhe,KAAK+C,MAAMgb,IACjB/d,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,qBACA,IAAM7d,KAAK+C,MAAM+a,KACjB,IAAM9d,KAAK+C,MAAMkb,IACjBje,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,qBACA,IAAM7d,KAAK+C,MAAMib,KACjB,IAAMhe,KAAK+C,MAAMkb,IACjBje,KAAK2d,OACL3d,KAAK0B,QAGT1B,KAAK45B,kBAAkB55B,KAAK+C,MAAM82B,cAClC75B,KAAKmX,MAAMnX,KAAKke,uBAClB,CAEAC,WAAAA,GACE,MAAO,CACLC,OAAQ,CACN5W,MAAO,EACP0Q,MAAOlY,KAAKqe,yBAAyBC,gBAAgBC,OAAO5H,MAE9DkjB,aAAc,CAAC,EAAG,KAAO,KAAO,GAAK,KAAO,GAAGt1B,WAEnD,CAEA2Z,qBAAuBA,KAAA,CAASM,EAAG,CAAC,KAAM,MAAOC,EAAG,CAAC,KAAM,QAE3Dmb,iBAAAA,CAAkBC,GAChB,IAAK75B,KAAK65B,cAAgBA,IAAiB75B,KAAK65B,aAAa9U,QAAS,CACpE,MAAM+U,EAASD,EAAaE,MAAM,KAAKrsB,KAAK8Q,GAAMuF,WAAWvF,EAAEwb,UAC/Dh6B,KAAK65B,aAAe,CAAE9U,QAAS8U,EAAcC,SAAQjV,IAAKxF,KAAKwF,OAAOiV,GAASpV,IAAKrF,KAAKqF,OAAOoV,GAClG,CACF,CAEAG,0BAAAA,GACE,OAAOj6B,KAAK0B,MAAMyV,MAAMsH,EAAEyN,OAAOlsB,KAAK2e,OAAOV,GAAKje,KAAK65B,aAAahV,KAAO7kB,KAAK2e,OAAOV,GAAKje,KAAK2e,OAAOZ,IAC1G,CAEAmc,0BAAAA,GACE,OAAOl6B,KAAK0B,MAAMyV,MAAMsH,EAAEyN,OAAOlsB,KAAK2e,OAAOV,GAAKje,KAAK65B,aAAanV,KAAO1kB,KAAK2e,OAAOV,GAAKje,KAAK2e,OAAOZ,IAC1G,CAEAL,aAAAA,CAAcgB,GACZ,MAAM,GAAEZ,EAAE,GAAEE,EAAE,GAAED,EAAE,GAAEE,GAAOje,KAAK2e,OAC1BC,GAAYC,EAAAA,EAAAA,IAAiB,CAAEf,KAAIE,KAAID,KAAIE,OAC3Ca,GAAcC,EAAAA,EAAAA,IAAoB,CAAEC,UAAWhf,KAAK+C,MAAMqb,OAAO5W,SAAUoX,EAAWX,GAAIW,EAAUb,KAE1GW,EAAQS,IAAI,YAAanf,KAAK+C,MAAMqb,OAAO5W,OAC3CkX,EAAQS,IAAI,cAAenf,KAAK+C,MAAMqb,OAAOlG,OAC7ClY,KAAK45B,kBAAkB55B,KAAK+C,MAAM82B,cAElC,MAAMpyB,EAASzH,KAAK+C,MAAMkb,GAAKje,KAAK+C,MAAMgb,GACpCoc,EAAevb,EAAUX,GAAKW,EAAUb,GAE9CW,EAAQO,UAAUH,EAAYN,EAAGM,EAAYL,GAC7CC,EAAQQ,YACR,IAAK,MAAMuX,KAAKz2B,KAAK65B,aAAaC,OAChCpb,EAAQa,OAAOX,EAAUd,GAAIuB,KAAK2E,MAAM/F,EAAKwY,EAAI0D,IACjDzb,EAAQc,OAAOZ,EAAUZ,GAAIqB,KAAK2E,MAAM/F,EAAKwY,EAAI0D,IAEnDzb,EAAQe,SACRf,EAAQO,WAA2B,EAAjBH,EAAYN,GAAyB,EAAjBM,EAAYL,GAElD,MAAMoH,EAAO,IAAIL,EAAAA,EACf,CACEhH,EAAGI,EAAUd,GACbgI,KAAM,CAAEtW,KAAM,EAAG2G,MAAO,QACxBiQ,aAAcsQ,EAAAA,GAAalQ,OAC3BP,UAAWjmB,KAAK+C,MAAMqb,OAAOlG,MAC7BiO,UAAWyQ,EAAAA,GAAUnQ,MAEvBzmB,KAAK0B,OAEHkd,EAAUd,GAAKc,EAAUZ,IAC3B6H,EAAK1G,IAAI,CAAEgH,UAAWyQ,EAAAA,GAAUrQ,QAGlC,IAAK,MAAMkQ,KAAKz2B,KAAK65B,aAAaC,OAAQ,CACxC,MAAMrb,EAAIze,KAAK+C,MAAMkb,GAAKwY,EAAIhvB,EAC9Boe,EAAK1G,IAAI,CACP0G,MAAW,IAAJ4Q,GAAS7yB,QAAQ,GAAK,MAAQ6a,EAAE7a,QAAQ,GAC/C6a,EAAGY,KAAK2E,MAAMhkB,KAAKoiB,GAAG3D,GAAKze,KAAK+C,MAAMqb,OAAO5W,MAAQ,KAEvDqe,EAAKgC,OAAOnJ,EACd,CAEI1e,KAAKsgB,yBACPtgB,KAAKugB,aAAa7B,EAEtB,CAEAgE,SAAAA,GA+CE,OA9CI1iB,KAAK65B,aAAahV,IAAM,IAAM7kB,KAAK4d,QAAQzV,MAAKR,IAAA,IAAC,KAAEgO,GAAMhO,EAAA,OAAKgO,EAAKykB,SAAS,iBAAiB,MAC/Fp6B,KAAK4d,QAAU,IACV5d,KAAK4d,QACR,IAAIC,EAAAA,EACF,oBACA,IAAM7d,KAAK+C,MAAM+a,KACjB,IAAM9d,KAAKi6B,8BACXj6B,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,oBACA,IAAM7d,KAAK+C,MAAMib,KACjB,IAAMhe,KAAKi6B,8BACXj6B,KAAK2d,OACL3d,KAAK0B,SAIP1B,KAAK65B,aAAahV,KAAO,GAAK7kB,KAAK4d,QAAQzV,MAAKC,IAAA,IAAC,KAAEuN,GAAMvN,EAAA,OAAKuN,EAAKykB,SAAS,iBAAiB,MAC/Fp6B,KAAK4d,QAAU5d,KAAK4d,QAAQhG,QAAO9J,IAAA,IAAC,KAAE6H,GAAM7H,EAAA,OAAM6H,EAAKykB,SAAS,iBAAiB,KAG/Ep6B,KAAK65B,aAAanV,IAAM,IAAM1kB,KAAK4d,QAAQzV,MAAKuH,IAAA,IAAC,KAAEiG,GAAMjG,EAAA,OAAKiG,EAAKykB,SAAS,iBAAiB,MAC/Fp6B,KAAK4d,QAAU,IACV5d,KAAK4d,QACR,IAAIC,EAAAA,EACF,oBACA,IAAM7d,KAAK+C,MAAM+a,KACjB,IAAM9d,KAAKk6B,8BACXl6B,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,oBACA,IAAM7d,KAAK+C,MAAMib,KACjB,IAAMhe,KAAKk6B,8BACXl6B,KAAK2d,OACL3d,KAAK0B,SAIP1B,KAAK65B,aAAanV,KAAO,GAAK1kB,KAAK4d,QAAQzV,MAAKkyB,IAAA,IAAC,KAAE1kB,GAAM0kB,EAAA,OAAK1kB,EAAKykB,SAAS,iBAAiB,MAC/Fp6B,KAAK4d,QAAU5d,KAAK4d,QAAQhG,QAAO0iB,IAAA,IAAC,KAAE3kB,GAAM2kB,EAAA,OAAM3kB,EAAKykB,SAAS,iBAAiB,KAG5Ep6B,KAAK4d,OACd,CAEA4C,MAAAA,CAAOhC,EAAWC,GAChBze,KAAK+C,MAAM+a,IAAMU,EACjBxe,KAAK+C,MAAMib,IAAMQ,EACjBxe,KAAK+C,MAAMgb,IAAMU,EACjBze,KAAK+C,MAAMkb,IAAMQ,CACnB,CAEAd,MAAAA,CAAM4c,GAAqD,IAApD,KAAE5kB,EAAI,KAAE8K,EAAI,KAAEC,GAAoC6Z,EACvD,OAAQ5kB,GACN,IAAK,mBACH3V,KAAK+C,MAAM+a,IAAM2C,EACjBzgB,KAAK+C,MAAMgb,IAAM2C,EACjB,MACF,IAAK,mBACH1gB,KAAK+C,MAAMib,IAAMyC,EACjBzgB,KAAK+C,MAAMgb,IAAM2C,EACjB,MACF,IAAK,oBACH1gB,KAAK+C,MAAM+a,IAAM2C,EACjBzgB,KAAK+C,MAAMkb,IAAMyC,EACjB,MACF,IAAK,oBACH1gB,KAAK+C,MAAMib,IAAMyC,EACjBzgB,KAAK+C,MAAMkb,IAAMyC,EACjB,MACF,IAAK,mBACH1gB,KAAK+C,MAAM+a,IAAM2C,EACjBzgB,KAAK+C,MAAMgb,IAAM2C,EAAO1gB,KAAK65B,aAAahV,IAC1C,MACF,IAAK,mBACH7kB,KAAK+C,MAAMib,IAAMyC,EACjBzgB,KAAK+C,MAAMgb,IAAM2C,EAAO1gB,KAAK65B,aAAahV,IAC1C,MACF,IAAK,mBACH7kB,KAAK+C,MAAM+a,IAAM2C,EACjBzgB,KAAK+C,MAAMkb,IAAMyC,GAAQrB,KAAKQ,IAAI7f,KAAK65B,aAAanV,KAAO,GAC3D,MACF,IAAK,mBACH1kB,KAAK+C,MAAMib,IAAMyC,EACjBzgB,KAAK+C,MAAMkb,IAAMyC,GAAQrB,KAAKQ,IAAI7f,KAAK65B,aAAanV,KAAO,GAKjE,CAEA/D,QAAAA,CAASC,GACP,GAAI3W,MAAM4W,oCAAqC,OAAO,EACtD,MAAM2Z,EAAkBx6B,KAAK65B,aAAahV,IAAM,GAAK7kB,KAAKi6B,6BACpDQ,EAAkBz6B,KAAK65B,aAAanV,IAAM,GAAK1kB,KAAKk6B,6BACpDzT,EAAOpH,KAAKqF,IAAI1kB,KAAK+C,MAAM+a,GAAI9d,KAAK+C,MAAMib,IAC1CuI,EAAQlH,KAAKwF,IAAI7kB,KAAK+C,MAAM+a,GAAI9d,KAAK+C,MAAMib,IAC3C0c,EAAa,CAAC16B,KAAK+C,MAAMgb,GAAI/d,KAAK+C,MAAMkb,GAAIuc,EAAiBC,GAAiB7iB,QAAQhW,IAAkB,IAATA,IAC/F0kB,EAAMjH,KAAKqF,OAAOgW,GAClBlU,EAASnH,KAAKwF,OAAO6V,GAE3B,OAAIjU,EAAO7F,EAAKpC,GAAKoC,EAAKpC,EAAI+H,GAASD,EAAM1F,EAAKnC,GAAKmC,EAAKnC,EAAI+H,GAGzDvc,MAAM0W,SAASC,EACxB,CAEA2D,eAAAA,GACEvkB,KAAKwkB,aAAeva,MAAMsa,kBAI1B,MAAMG,EAAM1kB,KAAKk6B,6BACXrV,EAAM7kB,KAAKi6B,6BAOjB,OALKjE,MAAMtR,IAASsR,MAAMnR,KACxB7kB,KAAKwkB,aAAaG,KAAOtF,KAAKqF,IAAIA,EAAKG,GACvC7kB,KAAKwkB,aAAaM,KAAOzF,KAAKwF,IAAIH,EAAKG,IAGlC7kB,KAAKwkB,YACd,EAGFmV,EAAsB75B,UAAUkhB,YAAc,CAC5CC,OAAQ,CACN,CAAEtL,KAAM,OAAQvS,KAAM,UACtB,CAAEuS,KAAM,SAAUvS,KAAM,eAAgB0L,MAAO,kBAInD,S,+FC3QA,MAAM6rB,UAA0EC,EAAAA,EAC9Erd,YAAcC,EAAAA,GAAkBkT,eAEhCttB,KAAO,kBACPy3B,cAN6B,EAU7B13B,WAAAA,CAAY+E,EAAwBxG,GAQlC,GAPAuI,MAAM/B,EAAQxG,GAEd1B,KAAK86B,sBAED96B,KAAK+C,MAAMgb,KACb/d,KAAK+C,MAAMgb,GAAK+F,OAAOhD,EAAAA,GAAKkD,MAAM,CAAEpW,MAAO5N,KAAK+C,MAAMgb,GAAIkG,eAAgBjkB,KAAK66B,kBAE7E76B,KAAKghB,YAAa,CACpB,MAAM+Z,EAAQ,KAAI,IAAI12B,OAAOrE,KAAK66B,cAAgB,MAClD76B,KAAKghB,YAAYC,OAAO,GAAK,IACxBjhB,KAAKghB,YAAYC,OAAO,GAC3B8Z,OACArW,IAAKZ,OAAOiX,GAEhB,CACA/6B,KAAK0d,cAAgB1d,KAAK0d,cAAc/c,KAAKX,MAC7CA,KAAK4d,QAAU,EACjB,CAEAM,qBAAuBA,KAAA,CAASM,EAAG,CAAC,KAAM,MAAOC,EAAG,CAAC,KAAM,QAE3Dqc,mBAAAA,GACE,MAAMnxB,EAAQ3J,KAAK0B,MAAMgI,QAAQC,QACjC3J,KAAK66B,cAAgBlxB,EACjBmX,EAAAA,GAAKka,2BAA2B,CAC9BnoB,WAAYlJ,EAAMkJ,WAClBjF,MAAOjE,EAAMsxB,YArCQ,CAwC7B,CAEAvd,aAAAA,CAAcgB,GACZ,MAAM,cAAEwc,GAAkBl7B,KAAKqe,yBAC/Bre,KAAK+C,MAAMkb,GAAKje,KAAK+C,MAAMgb,GAE3B/d,KAAK+C,MAAM+a,IAAiC,EAA5Bod,EAAczU,KAAKjf,MACnCxH,KAAK+C,MAAMib,GACThe,KAAK0B,MACFgI,QACAC,QACAwxB,YAAYn7B,KAAK0B,MAAMgI,QAAQC,QAAQyxB,MAAMn7B,OAAS,GAAKD,KAAK0B,MAAMgI,QAAQlC,MACnFyC,MAAMyT,cAAcgB,EACtB,CAEA2c,YAAAA,CAAa3c,GACX,GAAI1e,KAAK+C,MAAMgb,GAAI,CACjB/d,KAAK86B,sBACL,MAAM,cAAEI,EAAa,kBAAEI,GAAsBt7B,KAAKqe,yBAK5CjO,EAJkBpQ,KAAK0B,MAC1BgU,WACA1T,MACAmG,MAAMrG,GAAYA,EAAQy5B,gBACMD,EAAoBJ,EACvDxc,EAAQO,UAAUjf,KAAK0B,MAAMgI,QAAQlC,MAAQ4I,EAASmW,MAAM/e,MAAO4I,EAASkW,IAAI7e,QAChF,IAAI+d,EAAAA,EACF,CACEhH,EAAG,EACHC,EAAGze,KAAK2e,OAAOZ,GACf+H,KAAM,CAAEtW,KAAM,EAAG2G,MAAO,QACxB+P,WAAY,EACZG,QAAS,CACPC,IAAK,EACLC,MAAO,EACPC,OAAQ,EACRC,KAAM,GAERR,UAAW,OACXS,WAAY,OACZN,aAAcsQ,EAAAA,GAAaC,OAC3B9Q,KAAM7lB,KAAK+C,MAAMgb,GAAGna,QAAQ5D,KAAK66B,eAAet2B,YAElDvE,KAAK0B,OACLmmB,OAAOnJ,EACX,CACF,CAEA8B,MAAAA,CAAOhC,EAAkBC,GACvBze,KAAK+C,MAAMgb,IAAMU,CACnB,CAEAd,MAAAA,CAAMhW,GAAyD,IAAxD,KAAE+Y,GAAoD/Y,EAC3D3H,KAAKwgB,OAAO,EAAGE,EACjB,CAEAsK,gBAAAA,CAAiBthB,GACf,OAAOO,MAAM+gB,iBAAiBthB,EAAO,CAAEosB,OAAO,GAChD,EAGF6E,EAAe76B,UAAUkhB,YAAc,CACrCC,OAAQ,CACN,CAAEtL,KAAM,OAAQvS,KAAM,UACtB,CAAEuS,KAAM,SAAUvS,KAAM,KAAM0L,MAAO,QAAS0sB,cAAc,KAIhE,S,yGCjGA,MAAMC,UAAoD9wB,EAAAA,EACxD4S,YAAcC,EAAAA,GAAkB7G,KAEhCxT,WAAAA,CAAY+E,EAAwBxG,GAClCuI,MAAM/B,EAAQxG,GACd1B,KAAK6nB,OAAS7nB,KAAK6nB,OAAOlnB,KAAKX,MAC/BA,KAAK2d,OAAS3d,KAAK2d,OAAOhd,KAAKX,MAC/BA,KAAK4d,QAAU,CACb,IAAIC,EAAAA,EACF,KACA,IAAM7d,KAAK+C,MAAM+a,KACjB,IAAM9d,KAAK+C,MAAMgb,IACjB/d,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,KACA,IAAM7d,KAAK+C,MAAMib,KACjB,IAAMhe,KAAK+C,MAAMkb,IACjBje,KAAK2d,OACL3d,KAAK0B,OAGX,CAEAyc,WAAAA,GACE,MAAO,CACLa,UAAW,EACX0c,YAAa17B,KAAKqe,yBAAyBC,gBAAgBC,OAAO5H,KAEtE,CAEAuH,qBAAuBA,KAAA,CAASM,EAAG,CAAC,KAAM,MAAOC,EAAG,CAAC,KAAM,QAE3DoJ,MAAAA,CAAOnJ,GACL,MAAM,GAAEZ,EAAE,GAAEC,EAAE,GAAEC,EAAE,GAAEC,EAAE,UAAEe,GAAchf,KAAK+C,MACrC6b,GAAYC,EAAAA,EAAAA,IAAiB,CAAEf,KAAIC,KAAIC,KAAIC,OAC3Ca,GAAcC,EAAAA,EAAAA,IAAoB,CAAEC,eAAcJ,IAExDF,EAAQO,UAAUH,EAAYN,EAAGM,EAAYL,GAC7CC,EAAQQ,YACRR,EAAQS,IAAI,YAAanf,KAAK+C,MAAMic,WACpCN,EAAQS,IAAI,cAAenf,KAAK+C,MAAM24B,aAEtChd,EAAQa,OAAOX,EAAUd,GAAIc,EAAUb,IACnC/d,KAAK+C,MAAM44B,YACbjd,EAAQkd,YAAY,CAAC57B,KAAK+C,MAAM44B,aAElCjd,EAAQc,OAAOZ,EAAUZ,GAAIY,EAAUX,IACvCS,EAAQe,SACJzf,KAAK+C,MAAM44B,YACbjd,EAAQkd,YAAY,IAEtBld,EAAQO,WAA2B,EAAjBH,EAAYN,GAAyB,EAAjBM,EAAYL,GAE9Cze,KAAKsgB,yBACPtgB,KAAKugB,aAAa7B,EAEtB,CAEA8B,MAAAA,CAAOhC,EAAWC,GAChBze,KAAK+C,MAAM+a,IAAMU,EACjBxe,KAAK+C,MAAMib,IAAMQ,EACjBxe,KAAK+C,MAAMgb,IAAMU,EACjBze,KAAK+C,MAAMkb,IAAMQ,CACnB,CAEAd,MAAAA,CAAMhW,GAAqD,IAApD,KAAEgO,EAAI,KAAE8K,EAAI,KAAEC,GAAoC/Y,EAC1C,MAATgO,GACF3V,KAAK+C,MAAM+a,IAAM2C,EACjBzgB,KAAK+C,MAAMgb,IAAM2C,IAEjB1gB,KAAK+C,MAAMib,IAAMyC,EACjBzgB,KAAK+C,MAAMkb,IAAMyC,EAErB,CAEAC,QAAAA,CAASC,GACP,OAAI3W,MAAM4W,sCACNC,EAAAA,GAAKC,kBAAkBH,EAAM5gB,KAAK+C,QAAU,IAGzCkH,MAAM0W,SAASC,GACxB,EAGF,S,+HCnFA,MAAMib,UAA6DlxB,EAAAA,EACjE4S,YAAcC,EAAAA,GAAkBmT,QAEhCvtB,KAAO,UAGP04B,MACAC,MACAC,WACAC,WAEA94B,WAAAA,CAAY+E,EAAwBxG,GAClCuI,MAAM/B,EAAQxG,GACd1B,KAAK2d,OAAS3d,KAAK2d,OAAOhd,KAAKX,MAC/BA,KAAK4d,QAAU,CACb,IAAIC,EAAAA,EACF,MACA,IAAM7d,KAAK+C,MAAM+a,KACjB,IAAM9d,KAAK+C,MAAMgb,IACjB/d,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,MACA,IAAM7d,KAAK+C,MAAMib,KACjB,IAAMhe,KAAK+C,MAAMkb,IACjBje,KAAK2d,OACL3d,KAAK0B,QAGT1B,KAAKmX,MAAMnX,KAAKke,wBAChBle,KAAK87B,MAAQ97B,KAAK+7B,MAAQ,EAE1B/7B,KAAKg8B,WAAah8B,KAAK+C,MAAM+a,GAC7B9d,KAAKi8B,WAAaj8B,KAAK+C,MAAMib,EAC/B,CAEAE,qBAAuBA,KAAA,CAASM,EAAG,CAAC,KAAM,MAAOC,EAAG,CAAC,KAAM,QAE3Dyd,mBAAqBA,KACnB,MAAM,OAAEC,EAAM,SAAEC,GAAuDp8B,KAAK0B,MAAMgI,QAAQC,QACpF0yB,EAAYhd,KAAK2E,MAAMhkB,KAAK+C,MAAM+a,IAClCwe,EAAYjd,KAAK2E,MAAMhkB,KAAK+C,MAAMib,IAGlCue,EAAgBH,EAAS,GAAK,EAC9BI,EAAgBJ,EAASA,EAASn8B,OAAS,GAAK,EAChDw8B,EAAcpd,KAAKqF,IAAIrF,KAAKwF,IAAIxF,KAAKqF,IAAI2X,EAAWC,GAAYC,GAAgBC,GAChFE,EAAcrd,KAAKqF,IAAIrF,KAAKwF,IAAIxF,KAAKwF,IAAIwX,EAAWC,GAAYC,GAAgBC,GAEtF,IAAIG,EAAY,EAChB,IAAK,IAAIza,EAAIua,EAAava,GAAKwa,EAAaxa,IAAK,CAC/C,MAAM0a,EAAcR,EAAS57B,QAAQ0hB,GACjC0a,GAAe,IACjBD,GAAaR,EAAOS,GAExB,CAEA,MAAQ,QAAMC,EAAAA,EAAAA,IAA8BF,IAAY,EAG1Djf,aAAAA,CAAcgB,GACZA,EAAQS,IAAI,YAAanf,KAAK+C,MAAM6e,MACpC,MAAM,GAAE9D,EAAE,GAAEE,EAAE,GAAED,EAAE,GAAEE,GAAOje,KAAK2e,OAC1BC,GAAYC,EAAAA,EAAAA,IAAiB,CAAEf,KAAIE,KAAID,KAAIE,OAE3CzW,EAAQoX,EAAUZ,GAAKY,EAAUd,GACjCrW,EAASmX,EAAUX,GAAKW,EAAUb,GACxCW,EAAQoe,SAAShf,EAAIc,EAAUb,GAAIvW,EAAOC,GAE1C,MAAMs1B,EAAW/8B,KAAK+C,MAAMkb,GAAKje,KAAK+C,MAAMgb,GACtCxG,EAAc,IAAMvX,KAAK+C,MAAMgb,GAAMgf,EACrCC,EAAa,GAAED,EAASn5B,QAAQ,OAAO2T,EAAW3T,QAAQ,OAE1DiiB,EAAO,IAAIL,EAAAA,EACf,CACEK,KAAO,IAAEoX,EAAAA,EAAAA,IAAiB,CAAEC,OAAQ7d,KAAKQ,IAAI7f,KAAK+C,MAAMib,GAAKhe,KAAK+C,MAAM+a,IAAKqf,mBAAoB,WACjGlX,UAAW,OACXH,KAAM,CAAEtW,KAAM,GAAIuW,OAAQ,QAASC,OAAQ,QAC3CI,aAAcsQ,EAAAA,GAAaC,QAE7B32B,KAAK0B,OAED07B,EAAQtf,EAAKtW,EAAQ,EACrB61B,EAAQze,EAAUb,GAAKtW,EAAS,EACtC,IAAIygB,EAAYrC,EAAK8K,QAAQjS,GAC7BmH,EAAK1G,IAAI,CACPX,EAAG4e,EAAQlV,EAAY,EACvBzJ,EAAG4e,EAAQxX,EAAKyX,cAElBzX,EAAKgC,OAAOnJ,GAEZmH,EAAK1G,IAAI,CAAE0G,KAAMmX,IACjB9U,EAAYrC,EAAK8K,QAAQjS,GACzBmH,EAAK1G,IAAI,CACPX,EAAG4e,EAAQlV,EAAY,EACvBzJ,IAEFoH,EAAKgC,OAAOnJ,GAEZmH,EAAK1G,IAAI,CAAE0G,KAAM7lB,KAAKk8B,uBACtBhU,EAAYrC,EAAK8K,QAAQjS,GACzBmH,EAAK1G,IAAI,CACPX,EAAG4e,EAAQlV,EAAY,EACvBzJ,EAAG4e,EAAQxX,EAAKyX,cAElBzX,EAAKgC,OAAOnJ,GAER1e,KAAKsgB,yBACPtgB,KAAKugB,aAAa7B,EAEtB,CAEA6e,gBAAAA,CAAiBC,GACfx9B,KAAK+C,MAAMgb,IAAMyf,EAAKzf,IAAM,EAC5B/d,KAAK+C,MAAMkb,IAAMuf,EAAKvf,IAAM,EAE5Bje,KAAK87B,OAAS0B,EAAK1f,IAAM,EACzB9d,KAAK+7B,OAASyB,EAAKxf,IAAM,EAGzB,MAAMyf,KAAWz9B,KAAKg8B,WAAah8B,KAAK87B,QAAU97B,KAAK87B,MAAQ,EAAI,EAAI,KACjE97B,KAAK+C,MAAM+a,GAAK2f,GAAU,IAC9Bz9B,KAAK+C,MAAM+a,GAAK2f,GAElB,MAAMC,KAAW19B,KAAKi8B,WAAaj8B,KAAK+7B,QAAU/7B,KAAK+7B,MAAQ,EAAI,EAAI,KACjE/7B,KAAK+C,MAAMib,GAAK0f,GAAU,IAC9B19B,KAAK+C,MAAMib,GAAK0f,EAEpB,CAEAld,MAAAA,CAAOhC,EAAWC,GAChB,OAAOze,KAAKu9B,iBAAiB,CAC3Bzf,GAAIU,EACJT,GAAIU,EACJT,GAAIQ,EACJP,GAAIQ,GAER,CAEAd,MAAAA,CAAMhW,GAAqD,IAApD,KAAEgO,EAAI,KAAE8K,EAAI,KAAEC,GAAoC/Y,EAC1C,OAATgO,EACF3V,KAAKu9B,iBAAiB,CAAEzf,GAAI2C,EAAM1C,GAAI2C,IAEtC1gB,KAAKu9B,iBAAiB,CAAEvf,GAAIyC,EAAMxC,GAAIyC,GAE1C,CAEAC,QAAAA,CAASC,GACP,GAAI3W,MAAM4W,oCAAqC,OAAO,EACtD,MAAM/C,EAAKuB,KAAK2E,MAAMhkB,KAAK+C,MAAM+a,IAC3BE,EAAKqB,KAAK2E,MAAMhkB,KAAK+C,MAAMib,IAE3ByI,EAAOpH,KAAKqF,IAAI5G,EAAIE,GACpBuI,EAAQlH,KAAKwF,IAAI/G,EAAIE,GACrBsI,EAAMjH,KAAKqF,IAAI1kB,KAAK+C,MAAMgb,GAAI/d,KAAK+C,MAAMkb,IACzCuI,EAASnH,KAAKwF,IAAI7kB,KAAK+C,MAAMgb,GAAI/d,KAAK+C,MAAMkb,IAClD,OAAIwI,EAAO7F,EAAKpC,GAAKoC,EAAKpC,EAAI+H,GAASD,EAAM1F,EAAKnC,GAAKmC,EAAKnC,EAAI+H,GAGzDvc,MAAM0W,SAASC,EACxB,CAEAsR,WAAAA,CAAYyL,GACV1zB,MAAMioB,YAAYyL,GAClB39B,KAAKg8B,WAAah8B,KAAK+C,MAAM+a,GAC7B9d,KAAKi8B,WAAaj8B,KAAK+C,MAAMib,EAC/B,CAEAiF,SAAAA,CAAU0a,GACR1zB,MAAMgZ,UAAU0a,GAChB39B,KAAK87B,MAAQ97B,KAAK+7B,MAAQ,CAC5B,EAGFF,EAAQ/7B,UAAUsC,SAAW,CAAEwf,KAAM,yBAErCia,EAAQ/7B,UAAUkhB,YAAc,CAC9BC,OAAQ,CAAC,CAAEtL,KAAM,aAAcvS,KAAM,UAGvC,S,+HC7LO,MAAMw6B,EAA2Bj2B,IAA4E,IAA3E,MAAEk2B,EAAK,UAAEC,EAAS,aAAEC,GAAkDp2B,EAC7G,GAAIm2B,EAAUtf,IAAMuf,EAAavf,GAAKsf,EAAUrf,IAAMsf,EAAatf,EAAG,OAAOsf,EAE7E,IAAIC,EAAeD,EACfE,EAAuB,EAC3B,IAAK,IAAIh8B,EAAQ,EAAGA,EAAQ47B,EAAM59B,OAAQgC,IAAS,CACjD,MAAMi8B,EAAwBpd,EAAAA,GAAKqd,gCACjCL,EACAC,EACAF,EAAM57B,GAAO,GACb47B,EAAM57B,GAAO,IAEf,GAAIi8B,EAAuB,CACzB,MAAM5Y,EAAWxE,EAAAA,GAAKwE,SAAS4Y,EAAuBJ,GAClDxY,EAAW2Y,IAAwBnJ,EAAAA,EAAAA,IAAU,CAAElnB,MAAO0X,MACxD2Y,EAAuB3Y,EACvB0Y,EAAe,CAAExf,EAAG0f,EAAsB1f,EAAGC,EAAGyf,EAAsBzf,GAE1E,CACF,CAEA,OAAOuf,CAAY,EA4DRI,EAA0Bh2B,IAOP,IAPQ,UACtCrB,EAAS,UACT+2B,EAAS,0BACTO,EAAyB,0BACzBC,EAAyB,OACzBC,EAAM,OACNC,GACyBp2B,EACzB,MAAMy1B,EAjEsC92B,KAC5C,MAAM,KAAE0f,EAAI,MAAEF,EAAK,IAAED,EAAG,OAAEE,GAAWzf,EAAUsX,yBAAyB6c,eAClE,WAAEjQ,EAAU,MAAEzjB,GAAUT,EAAU2C,QAElC+0B,EAAwBpf,KAAKQ,IAAIoL,GACjCyT,EAAyBD,EAAwBj3B,EAAQif,EAAKjf,MAAQ+e,EAAM/e,MAE5Em3B,EAA0B53B,EAAUU,OAAS6e,EAAI7e,OAAS+e,EAAO/e,OAEjEm3B,EAA+B,CACnCpgB,EAAGigB,EACHhgB,EAL2B,GAOvBogB,EAAgC,CACpCrgB,EAAGkgB,EACHjgB,EAT2B,GAWvBqgB,EAAkC,CACtCtgB,EAAGigB,EACHhgB,EAAGkgB,GAECI,EAAmC,CACvCvgB,EAAGkgB,EACHjgB,EAAGkgB,GASL,MAFc,CALE,CAACC,EAA8BC,GAC7B,CAACA,EAA+BE,GAC/B,CAACD,EAAiCC,GACpC,CAACH,EAA8BE,GAIpC,EAiCEE,CAA8Bj4B,GAEtCqwB,EAA4B,CAChC6H,UAAW,CAAE3H,GAAIwG,EAAW5G,GAAImH,GAChCa,gBAAY72B,EACZ82B,gBAAY92B,EACZ+2B,gBAAY/2B,EACZg3B,gBAAYh3B,GAId,IAAKi2B,EAWH,OAVAlH,EAAY6H,UAAY,CACtB3H,IAAIzY,EAAAA,EAAAA,IAAiBif,GACrB5G,IAAIrY,EAAAA,EAAAA,IACF+e,EAAyB,CACvBC,QACAC,YACAC,aAAcM,MAIbjH,EAGT,MAAMkI,EAA0Bxe,EAAAA,GAAKye,4BAA4BlB,EAA2BC,GACtFkB,EAAgC,CACpChhB,EAAG8gB,EAAwB9gB,EAAIsf,EAAUtf,EACzCC,EAAG6gB,EAAwB7gB,EAAIqf,EAAUrf,GAGrCghB,EAA0C,CAC9CjhB,EAAG6f,EAA0B7f,EAAI8f,EAA0B9f,EAC3DC,EAAG4f,EAA0B5f,EAAI6f,EAA0B7f,GAGvDihB,EAAoD5e,EAAAA,GAAK6e,gBAC7DF,GAGIG,EAA6D9e,EAAAA,GAAKwE,SACtEga,EACAjB,GAaF,GAVAjH,EAAY6H,UAAY,CACtB3H,IAAIzY,EAAAA,EAAAA,IAAiBif,GACrB5G,IAAIrY,EAAAA,EAAAA,IACF+e,EAAyB,CACvBC,QACAC,YACAC,aAAcuB,MAIhBf,EAAO1uB,OAAQ,CACjB,MAAMgwB,EAAYC,EAAuB,CACvCC,MAAOxB,EAAOwB,MACdC,6BAA8BJ,EAC9BK,sCAAuCP,EACvCF,gCACAF,0BACAzB,UAGFzG,EAAY8H,WAAaW,EAAUK,UACnC9I,EAAYgI,WAAaS,EAAUM,SACrC,CACA,GAAI3B,EAAO3uB,OAAQ,CACjB,MAAMuwB,EAAYN,EAAuB,CACvCC,MAAOvB,EAAOuB,MACdC,6BAA8BJ,EAC9BK,sCAAuCP,EACvCF,gCACAF,0BACAzB,UAGFzG,EAAY+H,WAAaiB,EAAUF,UACnC9I,EAAYiI,WAAae,EAAUD,SACrC,CAEA,OAAO/I,CAAW,EAYd0I,EAAyBhyB,IAOA,IAPC,MAC9BiyB,EAAK,6BACLC,EAA4B,sCAC5BC,EAAqC,8BACrCT,EAA6B,wBAC7BF,EAAuB,MACvBzB,GACwB/vB,EACxB,MAAMuyB,EAA4BL,EAA+BD,EAE3DO,EAAuBxf,EAAAA,GAAKyf,UAChCjB,EACAxe,EAAAA,GAAK0f,uBAAuBP,EAAuCI,IAE/DI,EAA6B3f,EAAAA,GAAK4f,eACtCpB,EACAxe,EAAAA,GAAK0f,uBAAuBP,EAAuCI,IAG/DM,EAA+B,CACnCniB,EAAG8hB,EAAqB9hB,EAAIghB,EAA8BhhB,EAC1DC,EAAG6hB,EAAqB7hB,EAAI+gB,EAA8B/gB,GAEtDmiB,EAA+B,CACnCpiB,EAAGiiB,EAA2BjiB,EAAIghB,EAA8BhhB,EAChEC,EAAGgiB,EAA2BhiB,EAAI+gB,EAA8B/gB,GAGlE,MAAO,CACLyhB,UAAW,CACT5I,IAAIzY,EAAAA,EAAAA,IAAiByhB,GACrBpJ,IAAIrY,EAAAA,EAAAA,IACF+e,EAAyB,CACvBC,QACAC,UAAWwC,EACXvC,aAAc4C,MAIpBR,UAAW,CACT7I,IAAIzY,EAAAA,EAAAA,IAAiB4hB,GACrBvJ,IAAIrY,EAAAA,EAAAA,IACF+e,EAAyB,CACvBC,QACAC,UAAW2C,EACX1C,aAAc6C,MAIrB,ECxNH,MAAMC,UAAmEl2B,EAAAA,EACvE4S,YAAcC,EAAAA,GAAkBoT,YAGhCxtB,KAAO,YAEPD,WAAAA,CAAY+E,EAAwBxG,GAClCuI,MAAM/B,EAAQxG,GAEd1B,KAAK2d,OAAS3d,KAAK2d,OAAOhd,KAAKX,MAE/BA,KAAK4d,QAAU,CACb,IAAIC,EAAAA,EACF,mBACA,IAAM7d,KAAK+C,MAAM+a,KACjB,IAAM9d,KAAK+C,MAAMgb,IACjB/d,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,6BACA,IAAM7d,KAAK+C,MAAMib,KACjB,IAAMhe,KAAK+C,MAAMkb,IACjBje,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,6BACA,IAAM7d,KAAK+C,MAAMqoB,KACjB,IAAMprB,KAAK+C,MAAMsoB,IACjBrrB,KAAK2d,OACL3d,KAAK0B,QAGT1B,KAAKmX,MAAMnX,KAAKke,uBAClB,CAEAC,WAAAA,GACE,MAAO,CACL2iB,OAAQ,CAAE5oB,MAAO,UAAW1Q,MAAO,GACnC+2B,OAAQ,CACNrmB,MAAO,YACPrI,QAAQ,EACRkwB,MAAO,GAETvB,OAAQ,CACNtmB,MAAO,YACPrI,QAAQ,EACRkwB,MAAO,IAGb,CAEA7hB,qBAAuBA,KAAA,CAASM,EAAG,CAAC,KAAM,KAAM,MAAOC,EAAG,CAAC,KAAM,KAAM,QAEvEf,aAAAA,CAAcgB,GACZ,MAAM,GAAEZ,EAAE,GAAEE,EAAE,GAAEoN,EAAE,GAAErN,EAAE,GAAEE,EAAE,GAAEoN,GAAOrrB,KAAK2e,OAElC4X,GAASC,EAAAA,EAAAA,IAAuBx2B,KAAK+C,MAAM+9B,OAAOt5B,OACxDkX,EAAQO,UAAUsX,EAAQA,GAE1B,MAAM,UAAE0I,EAAS,WAAEC,EAAU,WAAEE,EAAU,WAAED,EAAU,WAAEE,GAAejB,EAAwB,CAC5Fr3B,UAAW/G,KAAK0B,MAChBo8B,UAAW,CAAEtf,EAAGV,EAAIW,EAAGV,GACvBsgB,0BAA2B,CAAE7f,EAAGR,EAAIS,EAAGR,GACvCqgB,0BAA2Bxa,OAAOkS,MAAM5K,IAAOtH,OAAOkS,MAAM3K,QAAMhjB,EAAY,CAAEmW,EAAG4M,EAAI3M,EAAG4M,GAC1FkT,OAAQv+B,KAAK+C,MAAMw7B,OACnBC,OAAQx+B,KAAK+C,MAAMy7B,SAGrB9f,EAAQS,IAAI,YAAanf,KAAK+C,MAAM+9B,OAAOt5B,OAE3C,MAAMu5B,EAAa,CACjB,CAAEhB,MAAO//B,KAAK+C,MAAMw7B,OAAQyC,MAAO9B,EAAY+B,MAAO7B,GACtD,CAAEW,MAAO//B,KAAK+C,MAAMy7B,OAAQwC,MAAO7B,EAAY8B,MAAO5B,IACtDzyB,MAAK,CAACC,EAAGC,IACLuS,KAAKQ,IAAIhT,EAAEkzB,MAAMA,OAAS1gB,KAAKQ,IAAI/S,EAAEizB,MAAMA,QACrC,EAEN1gB,KAAKQ,IAAIhT,EAAEkzB,MAAMA,OAAS1gB,KAAKQ,IAAI/S,EAAEizB,MAAMA,OACtC,EAEF,IAITgB,EAAWx4B,SAAQ,CAAC24B,EAAWC,KAC7B,GAAID,EAAUF,OAASE,EAAUD,MAAO,CACtC,MAAM,MAAED,EAAK,MAAEC,GAAUC,EACnBE,GAAkBC,EAAAA,EAAAA,IAAwBH,EAAUnB,MAAM7nB,OAC1DopB,EAAgBP,EAAWI,EAAiB,GAElDziB,EAAQQ,YACRR,EAAQa,OAAOyhB,EAAM1J,GAAG9Y,EAAGwiB,EAAM1J,GAAG7Y,GACpCC,EAAQc,OAAOwhB,EAAM9J,GAAG1Y,EAAGwiB,EAAM9J,GAAGzY,GAChC0iB,IAAmBJ,EAAW9gC,OAAS,GAAKqhC,EAAcN,OAASM,EAAcL,QACnFviB,EAAQc,OAAO8hB,EAAcN,MAAM9J,GAAG1Y,EAAG8iB,EAAcN,MAAM9J,GAAGzY,GAChEC,EAAQc,OAAO8hB,EAAcN,MAAM1J,GAAG9Y,EAAG8iB,EAAcN,MAAM1J,GAAG7Y,GAChEC,EAAQa,OAAO+hB,EAAcL,MAAM3J,GAAG9Y,EAAG8iB,EAAcL,MAAM3J,GAAG7Y,GAChEC,EAAQc,OAAO8hB,EAAcL,MAAM/J,GAAG1Y,EAAG8iB,EAAcL,MAAM/J,GAAGzY,IAElEC,EAAQc,OAAOyhB,EAAM/J,GAAG1Y,EAAGyiB,EAAM/J,GAAGzY,GACpCC,EAAQc,OAAOyhB,EAAM3J,GAAG9Y,EAAGyiB,EAAM3J,GAAG7Y,GACpCC,EAAQ+D,YACR/D,EAAQS,IAAI,YAAa+hB,EAAUnB,MAAM7nB,OACzCwG,EAAQkD,OAERlD,EAAQQ,YACRR,EAAQa,OAAOyhB,EAAM1J,GAAG9Y,EAAGwiB,EAAM1J,GAAG7Y,GACpCC,EAAQc,OAAOwhB,EAAM9J,GAAG1Y,EAAGwiB,EAAM9J,GAAGzY,GACpCC,EAAQa,OAAO0hB,EAAM3J,GAAG9Y,EAAGyiB,EAAM3J,GAAG7Y,GACpCC,EAAQc,OAAOyhB,EAAM/J,GAAG1Y,EAAGyiB,EAAM/J,GAAGzY,GACpCC,EAAQS,IAAI,cAAeiiB,GAC3B1iB,EAAQe,QACV,KAIFf,EAAQQ,YACRR,EAAQa,OAAO0f,EAAU3H,GAAG9Y,EAAGygB,EAAU3H,GAAG7Y,GAC5CC,EAAQc,OAAOyf,EAAU/H,GAAG1Y,EAAGygB,EAAU/H,GAAGzY,GAG5C,MAAM8iB,EACJR,EAAWnpB,QACRhW,GAASA,EAAKo/B,OAASp/B,EAAKq/B,OAASr/B,EAAKm+B,MAAMlwB,QAAUwP,KAAKQ,IAAIje,EAAKm+B,MAAMA,QAAU,IACzF,IAAM,CAAC,EAEPwB,EAAgBP,OAASO,EAAgBN,OAC3CviB,EAAQa,OAAOgiB,EAAgBP,MAAM1J,GAAG9Y,EAAG+iB,EAAgBP,MAAM1J,GAAG7Y,GACpEC,EAAQc,OAAO+hB,EAAgBN,MAAM3J,GAAG9Y,EAAG+iB,EAAgBN,MAAM3J,GAAG7Y,IAC1DqF,OAAOkS,MAAM5K,IAAQtH,OAAOkS,MAAM3K,KAC5C3M,EAAQa,OAAOvB,EAAIC,GACnBS,EAAQc,OAAO4L,EAAIC,IAGrB3M,EAAQS,IAAI,cAAenf,KAAK+C,MAAM+9B,OAAO5oB,OAC7CwG,EAAQe,SAERf,EAAQO,WAAoB,EAAVsX,GAAuB,EAAVA,GAE3Bv2B,KAAKsgB,yBACPtgB,KAAKugB,aAAa7B,EAEtB,CAEA8B,MAAAA,CAAOhC,EAAWC,GAChBze,KAAK+C,MAAM+a,IAAMU,EACjBxe,KAAK+C,MAAMgb,IAAMU,EACjBze,KAAK+C,MAAMib,IAAMQ,EACjBxe,KAAK+C,MAAMkb,IAAMQ,EACjBze,KAAK+C,MAAMqoB,IAAM5M,EACjBxe,KAAK+C,MAAMsoB,IAAM5M,CACnB,CAEAd,MAAAA,CAAMhW,GAAqD,IAApD,KAAEgO,EAAI,KAAE8K,EAAI,KAAEC,GAAoC/Y,EACvD,OAAQgO,GACN,IAAK,kBACH3V,KAAK+C,MAAM+a,IAAM2C,EACjBzgB,KAAK+C,MAAMgb,IAAM2C,EACjB,MACF,IAAK,4BACH1gB,KAAK+C,MAAMib,IAAMyC,EACjBzgB,KAAK+C,MAAMkb,IAAMyC,EACjB,MACF,IAAK,4BACH1gB,KAAK+C,MAAMqoB,IAAM3K,EACjBzgB,KAAK+C,MAAMsoB,IAAM3K,EAKvB,CAEAC,QAAAA,CAASC,GACP,GAAI3W,MAAM4W,oCAAqC,OAAO,EACtD,MAAM,GAAE/C,EAAE,GAAEE,EAAE,GAAEoN,EAAE,GAAErN,EAAE,GAAEE,EAAE,GAAEoN,GAAOrrB,KAAK2e,QAClC,UAAEsgB,EAAS,WAAEC,EAAU,WAAEE,EAAU,WAAED,EAAU,WAAEE,GAAejB,EAAwB,CAC5Fr3B,UAAW/G,KAAK0B,MAChBo8B,UAAW,CAAEtf,EAAGV,EAAIW,EAAGV,GACvBsgB,0BAA2B,CAAE7f,EAAGR,EAAIS,EAAGR,GACvCqgB,0BAA2Bxa,OAAOkS,MAAM5K,IAAOtH,OAAOkS,MAAM3K,QAAMhjB,EAAY,CAAEmW,EAAG4M,EAAI3M,EAAG4M,GAC1FkT,OAAQv+B,KAAK+C,MAAMw7B,OACnBC,OAAQx+B,KAAK+C,MAAMy7B,SAEf+C,EACJliB,KAAKQ,IAAI7f,KAAK+C,MAAMw7B,OAAOwB,OAAS1gB,KAAKQ,IAAI7f,KAAK+C,MAAMy7B,OAAOuB,OAC3D,CAAEiB,MAAO9B,EAAY+B,MAAO7B,GAC5B,CAAE4B,MAAO7B,EAAY8B,MAAO5B,GAElC,OACEve,EAAAA,GAAKC,kBAAkBH,EAAKjC,OAAQ,CAClCb,GAAImhB,EAAU3H,GAAG9Y,EACjBT,GAAIkhB,EAAU3H,GAAG7Y,EACjBT,GAAIihB,EAAU/H,GAAG1Y,EACjBP,GAAIghB,EAAU/H,GAAGzY,KACb,MAKLqF,OAAOkS,MAAM5K,KACbtH,OAAOkS,MAAM3K,IACdvK,EAAAA,GAAKC,kBAAkBH,EAAKjC,OAAQ,CAClCb,GAAIE,EACJD,GAAIE,EACJD,GAAIoN,EACJnN,GAAIoN,KACA,QAKNkW,EAAgBP,OAChBO,EAAgBN,OAChBngB,EAAAA,GAAKiK,eAAenK,EAAKjC,OAAQ,CAC/B4iB,EAAgBP,MAAM1J,GACtBiK,EAAgBP,MAAM9J,GACtBqK,EAAgBN,MAAM/J,GACtBqK,EAAgBN,MAAM3J,OAMnBrtB,MAAM0W,SAASC,IACxB,CAEAoK,gBAAAA,CAAiB0G,GACf,OAAO,CACT,EAGFmP,EAAU/gC,UAAUkhB,YAAc,CAChCC,OAAQ,CACN,CAAEtL,KAAM,OAAQvS,KAAM,UACtB,CAAEuS,KAAM,QAASvS,KAAM,UACvB,CAAEuS,KAAM,QAASvS,KAAM,YAI3B,S,yGC7PA,MAAMo+B,UAA6D72B,EAAAA,EACjE4S,YAAcC,EAAAA,GAAkBsN,QAEhC1nB,KAAO,UAEPD,WAAAA,CAAY+E,EAAwBxG,GAClCuI,MAAM/B,EAAQxG,GACd1B,KAAK2d,OAAS3d,KAAK2d,OAAOhd,KAAKX,MAC/BA,KAAK+C,MAAM6e,KAAO5hB,KAAK+C,MAAM6e,MAAQ,uBACvC,CAEAzD,WAAAA,GACE,MAAM,gBAAEG,GAAoBte,KAAKqe,yBACjC,MAAO,CACLuD,KAAMtD,EAAgBqI,YACtBvI,OAAQ,CACN5W,MAAO,EACP0Q,MAAOoG,EAAgBC,OAAOH,QAGpC,CAEAV,aAAAA,CAAcgB,GACZA,EAAQS,IAAI,YAAanf,KAAK+C,MAAM6e,MACpClD,EAAQS,IAAI,YAAanf,KAAK+C,MAAMqb,OAAO5W,OAC3CkX,EAAQS,IAAI,cAAenf,KAAK+C,MAAMqb,OAAOlG,OAE7C,MAAMqe,GAASC,EAAAA,EAAAA,IAAuBx2B,KAAK+C,MAAMqb,OAAO5W,OACxDkX,EAAQO,UAAUsX,EAAQA,GAE1B,MAAM,OAAEtU,GAAWjiB,KAAK+C,MACxB2b,EAAQQ,YACRR,EAAQa,OAAOvf,KAAKmiB,GAAGF,EAAO,GAAGzD,GAAIxe,KAAKoiB,GAAGH,EAAO,GAAGxD,IACvD,IAAK,MAAMgY,KAAKxU,EAAO5hB,MAAM,GAC3Bqe,EAAQc,OAAOxf,KAAKmiB,GAAGsU,EAAEjY,GAAIxe,KAAKoiB,GAAGqU,EAAEhY,IAGrCze,KAAKyhC,cACP/iB,EAAQ+D,YACR/D,EAAQkD,QAEVlD,EAAQO,WAAoB,EAAVsX,GAAuB,EAAVA,GAC2C,KAAhD,MAArBv2B,KAAK+C,MAAMqb,OAAiBpe,KAAK+C,MAAMqb,OAAO5W,WAAQa,IACzDqW,EAAQe,SAGNzf,KAAKsgB,yBACPtgB,KAAKugB,aAAa7B,EAEtB,CAEAgE,SAAAA,GACE,OAAO1iB,KAAK+C,MAAMkf,OAAOvU,KACvB,CAAC8U,EAAOvgB,IACN,IAAI4b,EAAAA,EACD,GAAE5b,KACH,IAAMugB,EAAMhE,IACZ,IAAMgE,EAAM/D,GACZze,KAAK2d,OACL3d,KAAK0B,QAGb,CAEA8hB,4BAA8BA,KAC5B,MAAM7Z,EAAQ3J,KAAK0B,OAAOgI,SAASC,QACnC,GAAIA,EAAO,CACT,MAAM8Z,EAA2BzjB,KAAK+C,MAAMkf,OAAOvU,KAAK8U,IAAK,IACxDA,EACHhE,EAAG7U,EAAM+Z,yBAAyBlB,EAAMhE,OAG1Cxe,KAAKmf,IAAI,CAAEsE,4BACb,GAGFE,YAAAA,GACE,MAAMha,EAAQ3J,KAAK0B,MAAMgI,QAAQC,SAC3B,yBAAE8Z,GAA6BzjB,KAAK+C,MAC1C,IAAK4G,IAAU8Z,EAGb,OAEF,MAAMxB,EAASwB,EAAyB/V,KAAK8U,IAAK,IAC7CA,EACHhE,EAAG7U,EAAMia,0BAA0BpB,EAAMhE,OAE3Cxe,KAAKmf,IAAI,CAAE8C,UACb,CAEAzB,MAAAA,CAAOhC,EAAWC,GAChB,IAAK,MAAM+D,KAASxiB,KAAK+C,MAAMkf,OAC7BO,EAAMhE,GAAKA,EACXgE,EAAM/D,GAAKA,CAEf,CAEAd,MAAAA,CAAMhW,GAAqD,IAApD,KAAEgO,EAAI,KAAE8K,EAAI,KAAEC,GAAoC/Y,EACvD,MAAM5H,EAAOC,KAAK+C,MAAMkf,OAAOhiB,OAAS,GACpCD,KAAKyhC,aAA0B,IAAT9rB,IAAeA,IAAS5V,GAMhDC,KAAK+C,MAAMkf,QAAQtM,GAAM6I,GAAKiC,EAC9BzgB,KAAK+C,MAAMkf,QAAQtM,GAAM8I,GAAKiC,IAN9B1gB,KAAK+C,MAAMkf,OAAO,GAAGzD,GAAKiC,EAC1BzgB,KAAK+C,MAAMkf,OAAO,GAAGxD,GAAKiC,EAC1B1gB,KAAK+C,MAAMkf,OAAOliB,GAAMye,GAAKiC,EAC7BzgB,KAAK+C,MAAMkf,OAAOliB,GAAM0e,GAAKiC,EAKjC,CAEA+gB,SAAAA,GACE,OACEzhC,KAAK+C,MAAMkf,OAAO,GAAGzD,IAAMxe,KAAK+C,MAAMkf,OAAOliB,QAAQye,GAAKxe,KAAK+C,MAAMkf,OAAO,GAAGxD,IAAMze,KAAK+C,MAAMkf,OAAOliB,QAAQ0e,CAEnH,CAEAkC,QAAAA,CAASC,GACP,GAAI3W,MAAM4W,oCAAqC,OAAO,EACtD,MAAM6gB,EAAe1hC,KAAK+C,MAAMkf,OAAOvU,KAAK+oB,IAAC,CAC3CjY,EAAGxe,KAAKmiB,GAAGsU,EAAEjY,GACbC,EAAGze,KAAKoiB,GAAGqU,EAAEhY,OAEf,GAAIze,KAAKyhC,aACP,GAAI3gB,EAAAA,GAAKiK,eAAenK,EAAKjC,OAAQ+iB,GACnC,OAAO,OAGT,IAAK,IAAIxf,EAAI,EAAGA,EAAIwf,EAAazhC,OAAS,EAAGiiB,IAC3C,GACEpB,EAAAA,GAAKC,kBAAkBH,EAAKjC,OAAQ,CAClCb,GAAI4jB,EAAaxf,GAAG1D,EACpBT,GAAI2jB,EAAaxf,GAAGzD,EACpBT,GAAI0jB,EAAaxf,EAAI,GAAG1D,EACxBP,GAAIyjB,EAAaxf,EAAI,GAAGzD,KACpB,GAEN,OAAO,EAKb,OAAOxU,MAAM0W,SAASC,EACxB,CAEA0D,4BAAAA,GACE,MAAO,CAAC,SACV,CAEAC,eAAAA,GACE,GAA0B,OAAtBvkB,KAAKwkB,aAAuB,CAC9B,MAAMA,EAAe,CAAC,EACtBxkB,KAAK+C,MAAMkf,OAAO1Z,SAAQH,IAAc,IAAb,EAAEoW,EAAC,EAAEC,GAAGrW,EACjC,MAAMu5B,EAASnjB,EACTojB,EAASnjB,EACf+F,EAAaC,KAAOpF,KAAKqF,IAAIid,EAAQnd,EAAaC,MAAQkd,GAC1Dnd,EAAaG,KAAOtF,KAAKqF,IAAIkd,EAAQpd,EAAaG,MAAQid,GAC1Dpd,EAAaI,KAAOvF,KAAKwF,IAAI8c,EAAQnd,EAAaI,MAAQ+c,GAC1Dnd,EAAaM,KAAOzF,KAAKwF,IAAI+c,EAAQpd,EAAaM,MAAQ8c,EAAO,IAGnE5hC,KAAKwkB,aAAeA,CACtB,CAEA,OAAOxkB,KAAKwkB,YACd,EAGFgd,EAAQ1hC,UAAUkhB,YAAc,CAC9BC,OAAQ,CACN,CAAEtL,KAAM,aAAcvS,KAAM,QAC5B,CAAEuS,KAAM,SAAUvS,KAAM,SAAUshB,IAAK,EAAGK,QAAS,CAAC,KAIxD,S,yGCzKA,MAAMjN,UAAgEnN,EAAAA,EACpE4S,YAAcC,EAAAA,GAAkB3F,SAEhCzU,KAAO,WAIP04B,MACAC,MAEA54B,WAAAA,CAAY+E,EAAwBxG,GAClCuI,MAAM/B,EAAQxG,GACd1B,KAAK2d,OAAS3d,KAAK2d,OAAOhd,KAAKX,MAC/BA,KAAK4d,QAAU,CACb,IAAIC,EAAAA,EACF,MACA,IAAM7d,KAAK+C,MAAM+a,KACjB,IAAM9d,KAAK+C,MAAM8+B,SACjB7hC,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,MACA,IAAM7d,KAAK+C,MAAMib,KACjB,IAAMhe,KAAK+C,MAAM8+B,SACjB7hC,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,MACA,IAAM7d,KAAK+C,MAAM+a,KACjB,IAAM9d,KAAK+C,MAAM++B,OACjB9hC,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,MACA,IAAM7d,KAAK+C,MAAMib,KACjB,IAAMhe,KAAK+C,MAAM++B,OACjB9hC,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,MACA,IAAM7d,KAAK+C,MAAM+a,KACjB,IAAM9d,KAAK+C,MAAMg/B,SACjB/hC,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,MACA,IAAM7d,KAAK+C,MAAMib,KACjB,IAAMhe,KAAK+C,MAAMg/B,SACjB/hC,KAAK2d,OACL3d,KAAK0B,QAGT1B,KAAKmX,MAAMnX,KAAKke,wBAChBle,KAAK87B,MAAQ97B,KAAK+7B,MAAQ,CAC5B,CAEA7d,qBAAuBA,KAAA,CAASM,EAAG,CAAC,KAAM,MAAOC,EAAG,CAAC,UAAW,UAAW,WAE3Ef,aAAAA,CAAcgB,GACZ,MAAM,GAAEZ,EAAE,GAAEE,EAAE,QAAE6jB,EAAO,QAAEE,EAAO,MAAED,GAAU9hC,KAAK2e,OAC3CC,GAAYC,EAAAA,EAAAA,IAAiB,CAAEf,KAAIE,KAAI6jB,UAASE,UAASD,UAC/D,IAAIrU,EAAMuU,EAAcC,EACxB,MAAMz6B,EAAQoX,EAAUZ,GAAKY,EAAUd,GAEvCY,EAAQS,IAAI,YAAanf,KAAK+C,MAAMm/B,aACpCxjB,EAAQoe,SAASle,EAAUd,GAAIc,EAAUijB,QAASr6B,EAAOoX,EAAUmjB,QAAUnjB,EAAUijB,SAEvFnjB,EAAQS,IAAI,YAAanf,KAAK+C,MAAMo/B,WACpCzjB,EAAQoe,SAASle,EAAUd,GAAIc,EAAUmjB,QAASv6B,EAAOoX,EAAUkjB,MAAQljB,EAAUmjB,SAErF,MAAMK,EAAY/iB,KAAKQ,IAAI7f,KAAK+C,MAAM8+B,QAAU7hC,KAAK+C,MAAMg/B,SACrDM,EAAc,IAAMriC,KAAK+C,MAAMg/B,QAAWK,EAC1CE,EAAa,WAAUF,EAAUx+B,QAAQ,OAAOy+B,EAAWz+B,QAAQ,OAEnE2+B,EAAUljB,KAAKQ,IAAI7f,KAAK+C,MAAM++B,MAAQ9hC,KAAK+C,MAAMg/B,SACjDS,EAAY,IAAMxiC,KAAK+C,MAAMg/B,QAAWQ,EACxCE,EAAW,SAAQF,EAAQ3+B,QAAQ,OAAO4+B,EAAS5+B,QAAQ,OAE7D5D,KAAK+C,MAAM8+B,QAAU7hC,KAAK+C,MAAMg/B,SAClCtU,EAAO,EACPwU,EAAiBvL,EAAAA,GAAalQ,OAC9Bwb,EAAetL,EAAAA,GAAapQ,MAE5BmH,GAAQ,EACRwU,EAAiBvL,EAAAA,GAAapQ,IAC9B0b,EAAetL,EAAAA,GAAalQ,QAG9B,MAAMX,EAAO,IAAIL,EAAAA,EACf,CACEK,KAAMyc,EACNrc,UAAWjmB,KAAKqe,yBAAyBC,gBAAgBC,OAAOqH,sBAChEE,KAAM,CAAEtW,KAAM,GAAIuW,OAAQ,QAASC,OAAQ,QAC3CvH,EAAGG,EAAUijB,QAAiB,EAAPpU,EACvBrH,aAAc6b,GAEhBjiC,KAAK0B,OAEP,IAAIwmB,EAAYrC,EAAK8K,QAAQjS,GAC7BmH,EAAK1G,IAAI,CAAEX,EAAGI,EAAUd,GAAKtW,EAAQ,EAAI0gB,EAAY,IACrDrC,EAAKgC,OAAOnJ,GAEZmH,EAAK1G,IAAI,CACP0G,KAAM4c,EACNhkB,EAAGG,EAAUkjB,MAAe,EAAPrU,EACrBrH,aAAc4b,IAEhB9Z,EAAYrC,EAAK8K,QAAQjS,GACzBmH,EAAK1G,IAAI,CAAEX,EAAGI,EAAUd,GAAKtW,EAAQ,EAAI0gB,EAAY,IACrDrC,EAAKgC,OAAOnJ,GAER1e,KAAKsgB,yBACPtgB,KAAKugB,aAAa7B,EAEtB,CAEA6e,gBAAAA,CAAiBC,GACf,IAAI7G,EAAQ+L,EAASC,EACjBnF,EAAKqE,UACPc,EAAS3iC,KAAK+C,MAAM8+B,QAAUrE,EAAKqE,SAEhC7hC,KAAK+C,MAAM8+B,QAAU7hC,KAAK+C,MAAMg/B,SAAWY,EAAS3iC,KAAK+C,MAAMg/B,SAC/D/hC,KAAK+C,MAAM8+B,QAAU7hC,KAAK+C,MAAMg/B,SAAWY,EAAS3iC,KAAK+C,MAAMg/B,WAEhE/hC,KAAK+C,MAAM++B,MAAQ9hC,KAAK+C,MAAMg/B,SAAW/hC,KAAK+C,MAAM++B,MAAQ9hC,KAAK+C,MAAMg/B,UAEzE/hC,KAAK+C,MAAM8+B,QAAUc,GAGnBnF,EAAKsE,QACPa,EAAS3iC,KAAK+C,MAAM++B,MAAQtE,EAAKsE,OAE9B9hC,KAAK+C,MAAM++B,MAAQ9hC,KAAK+C,MAAMg/B,SAAWY,EAAS3iC,KAAK+C,MAAMg/B,SAC7D/hC,KAAK+C,MAAM++B,MAAQ9hC,KAAK+C,MAAMg/B,SAAWY,EAAS3iC,KAAK+C,MAAMg/B,WAE9D/hC,KAAK+C,MAAM8+B,QAAU7hC,KAAK+C,MAAMg/B,SAAW/hC,KAAK+C,MAAM8+B,QAAU7hC,KAAK+C,MAAMg/B,UAE7E/hC,KAAK+C,MAAM++B,MAAQa,GAInBnF,EAAKuE,UACH/hC,KAAK+C,MAAM++B,OAASnL,EAAS32B,KAAK+C,MAAMg/B,QAAUvE,EAAKuE,UAAYpL,EAAS32B,KAAK+C,MAAM8+B,SACtF7hC,KAAK+C,MAAM++B,OAASY,EAAU1iC,KAAK+C,MAAMg/B,QAAUvE,EAAKuE,UAAYW,EAAU1iC,KAAK+C,MAAM8+B,WAE5F7hC,KAAK+C,MAAMg/B,SAAWvE,EAAKuE,SAG7B/hC,KAAK87B,OAAS0B,EAAK1f,IAAM,EACzB9d,KAAK+7B,OAASyB,EAAKxf,IAAM,EACzB,MAAM4kB,IAAa5iC,KAAK87B,SAAW97B,KAAK+7B,MACvB,IAAb6G,IACa,MAAXpF,EAAK1f,KACP9d,KAAK+C,MAAM+a,IAAM8kB,GAEJ,MAAXpF,EAAKxf,KACPhe,KAAK+C,MAAMib,IAAM4kB,GAEnB5iC,KAAK87B,MAAQ97B,KAAK+7B,MAAQ,EAE9B,CAEAvb,MAAAA,CAAOhC,EAAWC,GAChB,OAAOze,KAAKu9B,iBAAiB,CAC3Bzf,GAAIU,EACJR,GAAIQ,EACJqjB,QAASpjB,EACTsjB,QAAStjB,EACTqjB,MAAOrjB,GAEX,CAEAd,MAAAA,CAAMhW,GAAqD,IAApD,KAAEgO,EAAI,KAAE8K,EAAI,KAAEC,GAAoC/Y,EACvD,MAAOk7B,EAAWC,GAAentB,EAAgBokB,MAAM,IAEjDvI,EAA+B,CACnC,CAAE,IAAGsR,KAAeriB,EACpB,CAHoD,CAAEsiB,EAAG,UAAWtW,EAAG,UAAWuW,EAAG,SAG5EH,IAAaniB,GAExB,OAAO1gB,KAAKu9B,iBAAiB/L,EAC/B,CAEA7Q,QAAAA,CAASC,GACP,GAAI3W,MAAM4W,oCAAqC,OAAO,EACtD,MAAM/C,EAAKuB,KAAK2E,MAAMhkB,KAAK+C,MAAM+a,IAC3BE,EAAKqB,KAAK2E,MAAMhkB,KAAK+C,MAAMib,IAC3ByI,EAAOpH,KAAKqF,IAAI5G,EAAIE,GACpBuI,EAAQlH,KAAKwF,IAAI/G,EAAIE,GACrBsI,EAAMjH,KAAKqF,IAAI1kB,KAAK+C,MAAM8+B,QAAS7hC,KAAK+C,MAAM++B,OAC9Ctb,EAASnH,KAAKwF,IAAI7kB,KAAK+C,MAAM8+B,QAAS7hC,KAAK+C,MAAM++B,OACvD,OAAIrb,EAAO7F,EAAKpC,GAAKoC,EAAKpC,EAAI+H,GAASD,EAAM1F,EAAKnC,GAAKmC,EAAKnC,EAAI+H,GAGzDvc,MAAM0W,SAASC,EACxB,EAGF9I,EAAShY,UAAUsC,SAAW,CAC5B8/B,YAAa,oBACbC,UAAW,qBAGbrqB,EAAShY,UAAUkhB,YAAc,CAC/BC,OAAQ,CACN,CAAEtL,KAAM,aAAcvS,KAAM,eAC5B,CAAEuS,KAAM,aAAcvS,KAAM,eAIhC,S,8FC7NA,MAAM6/B,UAAmEt4B,EAAAA,EACvE4S,YAAcC,EAAAA,GAAkBsT,UAEhC1tB,KAAO,YAIPD,WAAAA,CAAY+E,EAAwBxG,GAClCuI,MAAM/B,EAAQxG,GACd1B,KAAK2d,OAAS3d,KAAK2d,OAAOhd,KAAKX,MAC/BA,KAAK4d,QAAU,CACb,IAAIC,EAAAA,EACF,MACA,IAAM7d,KAAK+C,MAAMib,KACjB,IAAMhe,KAAK+C,MAAMkb,IACjBje,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,MACA,IAAM7d,KAAK+C,MAAM+a,KACjB,IAAM9d,KAAK+C,MAAMgb,IACjB/d,KAAK2d,OACL3d,KAAK0B,QAGT1B,KAAKmX,MAAMnX,KAAKke,uBAClB,CAEAC,WAAAA,GACE,MAAM,gBAAEG,GAAoBte,KAAKqe,yBACjC,MAAO,CACLuD,KAAMtD,EAAgBqI,YACtBvI,OAAQ,CACN5W,MAAO,EACP0Q,MAAOoG,EAAgBC,OAAOH,QAGpC,CAEAF,qBAAuBA,KAAA,CAASM,EAAG,CAAC,KAAM,MAAOC,EAAG,CAAC,KAAM,QAE3Df,aAAAA,CAAcgB,GACZ,MAAM,GAAEZ,EAAE,GAAEE,EAAE,GAAED,EAAE,GAAEE,GAAOje,KAAK2e,OAC1BC,GAAYC,EAAAA,EAAAA,IAAiB,CAAEf,KAAIE,KAAID,KAAIE,OAC3CzW,EAAQoX,EAAUZ,GAAKY,EAAUd,GACjCrW,EAASmX,EAAUX,GAAKW,EAAUb,GAMxC,GAJAW,EAAQS,IAAI,YAAanf,KAAK+C,MAAM6e,MAEpClD,EAAQoe,SAASle,EAAUd,GAAIc,EAAUb,GAAIvW,EAAOC,GAEsB,KAAhD,MAArBzH,KAAK+C,MAAMqb,OAAiBpe,KAAK+C,MAAMqb,OAAO5W,WAAQa,GAAkB,CAC3EqW,EAAQS,IAAI,YAAanf,KAAK+C,MAAMqb,OAAO5W,OAC3CkX,EAAQS,IAAI,cAAenf,KAAK+C,MAAMqb,OAAOlG,OAC7C,MAAMqe,GAASC,EAAAA,EAAAA,IAAuBx2B,KAAK+C,MAAMqb,OAAO5W,OACxDkX,EAAQwkB,WAAWtkB,EAAUd,GAAKyY,EAAQ3X,EAAUb,GAAKwY,EAAQ/uB,EAAOC,EAC1E,CAEIzH,KAAKsgB,yBACPtgB,KAAKugB,aAAa7B,EAEtB,CAEA8B,MAAAA,CAAOhC,EAAWC,GAChBze,KAAK+C,MAAM+a,IAAMU,EACjBxe,KAAK+C,MAAMib,IAAMQ,EACjBxe,KAAK+C,MAAMgb,IAAMU,EACjBze,KAAK+C,MAAMkb,IAAMQ,CAMnB,CAEAd,MAAAA,CAAMhW,GAAqD,IAApD,KAAEgO,EAAI,KAAE8K,EAAI,KAAEC,GAAoC/Y,EACvD,GAAa,OAATgO,EAEF,OADA3V,KAAK+C,MAAM+a,IAAM2C,EACTzgB,KAAK+C,MAAMgb,IAAM2C,EAEzB1gB,KAAK+C,MAAMib,IAAMyC,EACjBzgB,KAAK+C,MAAMkb,IAAMyC,CAErB,CAEAC,QAAAA,CAASC,GACP,GAAI3W,MAAM4W,oCAAqC,OAAO,EACtD,MAAM4F,EAAOpH,KAAKqF,IAAI1kB,KAAK+C,MAAM+a,GAAI9d,KAAK+C,MAAMib,IAC1CuI,EAAQlH,KAAKwF,IAAI7kB,KAAK+C,MAAM+a,GAAI9d,KAAK+C,MAAMib,IAC3CsI,EAAMjH,KAAKqF,IAAI1kB,KAAK+C,MAAMgb,GAAI/d,KAAK+C,MAAMkb,IACzCuI,EAASnH,KAAKwF,IAAI7kB,KAAK+C,MAAMgb,GAAI/d,KAAK+C,MAAMkb,IAClD,OAAIwI,EAAO7F,EAAKpC,GAAKoC,EAAKpC,EAAI+H,GAASD,EAAM1F,EAAKnC,GAAKmC,EAAKnC,EAAI+H,GAGzDvc,MAAM0W,SAASC,EACxB,EAGFqiB,EAAUnjC,UAAUkhB,YAAc,CAChCC,OAAQ,CACN,CAAEtL,KAAM,aAAcvS,KAAM,QAC5B,CAAEuS,KAAM,SAAUvS,KAAM,SAAUshB,IAAK,EAAGK,QAAS,CAAC,KAIxD,S,yGCvGA,MAAMoe,UAA8Fx4B,EAAAA,EAClG4S,YAAcC,EAAAA,GAAkBuT,mBAEhC3tB,KAAO,wBAIPD,WAAAA,CAAY+E,EAAwBxG,GAClCuI,MAAM/B,EAAQxG,GACd1B,KAAK2d,OAAS3d,KAAK2d,OAAOhd,KAAKX,MAC/BA,KAAK4d,QAAU,CACb,IAAIC,EAAAA,EACF,cACA,IAAM7d,KAAK+C,MAAM+a,KACjB,IAAM9d,KAAK+C,MAAMgb,IACjB/d,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,eACA,IAAM7d,KAAK+C,MAAMib,KACjB,IAAMhe,KAAK+C,MAAMkb,IACjBje,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,YACA,IAAM7d,KAAKmuB,oBAAmB,GAAMmJ,GAAG9Y,GAAKxe,KAAK+C,MAAMib,KACvD,IAAMhe,KAAKmuB,oBAAmB,GAAMmJ,GAAG7Y,GAAKze,KAAK+C,MAAMkb,IACvDje,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,WACA,IAAM7d,KAAKmuB,oBAAmB,GAAM+I,GAAG1Y,GAAKxe,KAAK+C,MAAMib,KACvD,IAAMhe,KAAKmuB,oBAAmB,GAAM+I,GAAGzY,GAAKze,KAAK+C,MAAMkb,IACvDje,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,cACA,IAAM7d,KAAKmuB,oBAAmB,GAAMkJ,GAAG7Y,GAAKxe,KAAK+C,MAAM+a,KACvD,IAAM9d,KAAKmuB,oBAAmB,GAAMkJ,GAAG5Y,GAAKze,KAAK+C,MAAMgb,IACvD/d,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,eACA,IAAM7d,KAAKmuB,oBAAmB,GAAMgJ,GAAG3Y,GAAKxe,KAAK+C,MAAM+a,KACvD,IAAM9d,KAAKmuB,oBAAmB,GAAMgJ,GAAG1Y,GAAKze,KAAK+C,MAAMgb,IACvD/d,KAAK2d,OACL3d,KAAK0B,QAGT1B,KAAKmX,MAAMnX,KAAKke,uBAClB,CAEAC,WAAAA,GACE,MAAM,gBAAEG,GAAoBte,KAAKqe,yBACjC,MAAO,CACLuD,KAAMtD,EAAgBqI,YACtBvI,OAAQ,CACN5W,MAAO,EACP0Q,MAAOoG,EAAgBC,OAAOH,QAGpC,CAEAF,qBAAuBA,KAAA,CAASM,EAAG,CAAC,KAAM,KAAM,iBAAkBC,EAAG,CAAC,KAAM,KAAM,mBAElFf,aAAAA,CAAcgB,GACZ,MAAM,GAAE4Y,EAAE,GAAEJ,EAAE,GAAEG,EAAE,GAAEF,GAAOn3B,KAAKmuB,qBAC1BvP,EAAY,CAChB0Y,IAAIzY,EAAAA,EAAAA,IAAiByY,GACrBJ,IAAIrY,EAAAA,EAAAA,IAAiBqY,GACrBG,IAAIxY,EAAAA,EAAAA,IAAiBwY,GACrBF,IAAItY,EAAAA,EAAAA,IAAiBsY,IAEjBZ,GAASC,EAAAA,EAAAA,IAAuBx2B,KAAK+C,MAAMqb,OAAO5W,OACxDkX,EAAQS,IAAI,YAAanf,KAAK+C,MAAM6e,MAEpClD,EAAQO,UAAUsX,EAAQA,GAC1B7X,EAAQQ,YACJN,EAAU0Y,GAAG9Y,IAAMI,EAAUuY,GAAG3Y,GAAKI,EAAU0Y,GAAG7Y,IAAMG,EAAUuY,GAAG1Y,GACvEC,EAAQc,OAAOZ,EAAU0Y,GAAG9Y,EAAGI,EAAU0Y,GAAG7Y,GAC5CC,EAAQc,OAAOZ,EAAUsY,GAAG1Y,EAAGI,EAAUsY,GAAGzY,KAE5CC,EAAQc,OAAOZ,EAAU0Y,GAAG9Y,EAAGI,EAAU0Y,GAAG7Y,GAC5CC,EAAQc,OAAOZ,EAAUsY,GAAG1Y,EAAGI,EAAUsY,GAAGzY,GAC5CC,EAAQc,OAAOZ,EAAUyY,GAAG7Y,EAAGI,EAAUyY,GAAG5Y,GAC5CC,EAAQc,OAAOZ,EAAUuY,GAAG3Y,EAAGI,EAAUuY,GAAG1Y,GAC5CC,EAAQ+D,YACR/D,EAAQkD,QAEVlD,EAAQO,WAAoB,EAAVsX,GAAuB,EAAVA,GAE/B7X,EAAQS,IAAI,YAAanf,KAAK+C,MAAMqb,OAAO5W,OAC3CkX,EAAQS,IAAI,cAAenf,KAAK+C,MAAMqb,OAAOlG,OAC7CwG,EAAQe,SAEJzf,KAAKsgB,yBACPtgB,KAAKugB,aAAa7B,EAEtB,CAEAyP,kBAAAA,GAAqC,IAAlByJ,EAAQx2B,UAAAnB,OAAA,QAAAoI,IAAAjH,UAAA,IAAAA,UAAA,GACzB,MAAM,GAAE0c,EAAE,GAAEE,EAAE,GAAED,EAAE,GAAEE,EAAE,cAAE4Z,EAAa,cAAEC,GAAkB93B,KAAK2e,OAC9D,IAAIoZ,EACJ,GAAK/B,MAAM6B,IAAmB7B,MAAM8B,GASlC,MAAO,CACLR,GAAI,CAAE9Y,EAAGR,EAAIS,EAAGR,GAChBiZ,GAAI,CAAE1Y,EAAGV,EAAIW,EAAGV,GAChBsZ,GAAI,CAAE7Y,EAAGV,EAAIW,EAAGV,GAChBoZ,GAAI,CAAE3Y,EAAGR,EAAIS,EAAGR,IAbgC,CAClD,MAAM+Z,EAAS,CAAExZ,EAAGqZ,EAAepZ,EAAGqZ,GAChCnhB,EAAO,CAAEmH,KAAIC,KAAIC,KAAIC,MACrBqH,EAAWxE,EAAAA,GAAKmX,eAAeD,EAAQrhB,GAC7CohB,EAAqBjX,EAAAA,GAAK4J,yBAAyB,CACjDpF,WACA3O,QAEJ,CASA,MAAMgU,EAAeoN,EAAmBvZ,EAAIR,EACtC4M,EAAemN,EAAmBtZ,EAAIR,EAEtCqZ,EAAK,CAAE9Y,EAAGR,EAAK2M,EAAclM,EAAGR,EAAK2M,GACrCsM,EAAK,CAAE1Y,EAAGV,EAAK6M,EAAclM,EAAGV,EAAK6M,GACrCyM,EAAK,CAAE7Y,EAAGV,GAAM,EAAI6M,EAAclM,EAAGV,GAAM,EAAI6M,GAC/CuM,EAAK,CAAE3Y,EAAGR,GAAM,EAAI2M,EAAclM,EAAGR,GAAM,EAAI2M,GAE/CwN,EAAUp4B,KAAK0B,MAAMyV,MAAMqH,EAAE0N,OAC7BmM,EAAUr4B,KAAK0B,MAAMyV,MAAMsH,EAAEyN,OACnC,OAAI0L,EACK,CACLN,GAAI,CAAE9Y,EAAG4Z,EAAQd,EAAG9Y,GAAIC,EAAG4Z,EAAQf,EAAG7Y,IACtCyY,GAAI,CAAE1Y,EAAG4Z,EAAQlB,EAAG1Y,GAAIC,EAAG4Z,EAAQnB,EAAGzY,IACtC4Y,GAAI,CAAE7Y,EAAG4Z,EAAQf,EAAG7Y,GAAIC,EAAG4Z,EAAQhB,EAAG5Y,IACtC0Y,GAAI,CAAE3Y,EAAG4Z,EAAQjB,EAAG3Y,GAAIC,EAAG4Z,EAAQlB,EAAG1Y,KAGnC,CAAE6Y,KAAIJ,KAAIG,KAAIF,KACvB,CAEA2B,2BAA6BnxB,IAUvB,IAVwB,kBAC5BoxB,EAAiB,cACjBC,EAAa,aACbC,EAAY,aACZC,GAMDvxB,EACC,MAAMyX,EAAQ0B,EAAAA,GAAKqY,sBAAsB,CACvCC,YAAaL,EACbE,eACAC,iBAEIG,EAAyBvY,EAAAA,GAAKwY,wBAAwB,CAC1DP,oBACA3Z,QACA4Z,kBAEF,MAAO,CACLxa,EAAGxe,KAAK0B,MAAMyV,MAAMqH,EAAE0N,OAAOmN,EAAuB7a,GACpDC,EAAGze,KAAK0B,MAAMyV,MAAMsH,EAAEyN,OAAOmN,EAAuB5a,GACrD,EAGH+B,MAAAA,CAAOhC,EAAWC,GAChBze,KAAK+C,MAAM+a,IAAMU,EACjBxe,KAAK+C,MAAMgb,IAAMU,EACjBze,KAAK+C,MAAMib,IAAMQ,EACjBxe,KAAK+C,MAAMkb,IAAMQ,EACjBze,KAAK+C,MAAM80B,eAAiBrZ,EAC5Bxe,KAAK+C,MAAM+0B,eAAiBrZ,CAC9B,CAEAd,MAAAA,CAAMvV,GAA2D,IAA1D,KAAEuN,EAAI,KAAE8K,EAAI,KAAEC,EAAI,KAAEE,GAAoCxY,EAC7D,OAAQuN,GACN,IAAK,aACH,MAAMytB,EAAqB,CACzB5kB,EAAGxe,KAAK+C,MAAM+a,GAAK2C,EACnBhC,EAAGze,KAAK+C,MAAMgb,GAAK2C,GAEf2iB,EAA+BrjC,KAAK84B,2BAA2B,CACnEC,kBAAmB,CAAEva,EAAGxe,KAAK2e,OAAOX,GAAIS,EAAGze,KAAK2e,OAAOV,IACvD+a,cAAe,CACbxa,EAAGxe,KAAK2e,OAAOkZ,cACfpZ,EAAGze,KAAK2e,OAAOmZ,eAEjBmB,aAAc,CAAEza,EAAGxe,KAAK2e,OAAOb,GAAIW,EAAGze,KAAK2e,OAAOZ,IAClDmb,aAAc,CAAE1a,EAAGxe,KAAK0B,MAAMyV,MAAMqH,EAAE4kB,EAAmB5kB,GAAIC,EAAGze,KAAK0B,MAAMyV,MAAMsH,EAAE2kB,EAAmB3kB,MAExGze,KAAK+C,MAAQ,IACR/C,KAAK+C,MACR+a,GAAIslB,EAAmB5kB,EACvBT,GAAIqlB,EAAmB3kB,EACvBoZ,cAAewL,EAA6B7kB,EAC5CsZ,cAAeuL,EAA6B5kB,GAE9C,MACF,IAAK,cACH,MAAM6kB,EAAsB,CAC1B9kB,EAAGxe,KAAK+C,MAAMib,GAAKyC,EACnBhC,EAAGze,KAAK+C,MAAMkb,GAAKyC,GAEf6iB,EAAgCvjC,KAAK84B,2BAA2B,CACpEC,kBAAmB,CAAEva,EAAGxe,KAAK2e,OAAOb,GAAIW,EAAGze,KAAK2e,OAAOZ,IACvDib,cAAe,CACbxa,EAAGxe,KAAK2e,OAAOkZ,cACfpZ,EAAGze,KAAK2e,OAAOmZ,eAEjBmB,aAAc,CAAEza,EAAGxe,KAAK2e,OAAOX,GAAIS,EAAGze,KAAK2e,OAAOV,IAClDib,aAAc,CAAE1a,EAAGxe,KAAK0B,MAAMyV,MAAMqH,EAAE8kB,EAAoB9kB,GAAIC,EAAGze,KAAK0B,MAAMyV,MAAMsH,EAAE6kB,EAAoB7kB,MAE1Gze,KAAK+C,MAAQ,IACR/C,KAAK+C,MACRib,GAAIslB,EAAoB9kB,EACxBP,GAAIqlB,EAAoB7kB,EACxBoZ,cAAe0L,EAA8B/kB,EAC7CsZ,cAAeyL,EAA8B9kB,GAE/C,MACF,IAAK,WACL,IAAK,UACL,IAAK,aACL,IAAK,cACHze,KAAK+C,MAAQ,IACR/C,KAAK+C,MACR80B,cAAejX,EAAKpC,EACpBsZ,cAAelX,EAAKnC,GAM5B,CAEAkC,QAAAA,CAASC,GACP,GAAI3W,MAAM4W,oCAAqC,OAAO,EACtD,MAAMuW,EAAcp3B,KAAKmuB,qBACnBrD,EAAU7nB,OAAOC,KAAKk0B,GAAa1pB,KAAK8U,IAAK,CACjDhE,EAAG4Y,EAAY5U,GAAoChE,EACnDC,EAAG2Y,EAAY5U,GAAoC/D,MAErD,QAAIqC,EAAAA,GAAKiK,eAAenK,EAAKjC,OAAQmM,IAG9B7gB,MAAM0W,SAASC,EACxB,CAEAoK,gBAAAA,GACE,OAAO,CACT,EAGFmY,EAAmBrjC,UAAUkhB,YAAc,CACzCC,OAAQ,CACN,CAAEtL,KAAM,aAAcvS,KAAM,QAC5B,CAAEuS,KAAM,SAAUvS,KAAM,SAAUshB,IAAK,EAAGK,QAAS,CAAC,KAIxD,S,gGC7QA,MAAM6V,UAAsEa,EAAAA,EAC1Ele,YAAcC,EAAAA,GAAkByT,WAEhC7tB,KAAO,OAIPD,WAAAA,CAAY+E,EAAwBxG,GAClCuI,MAAM/B,EAAQxG,GACd1B,KAAK0d,cAAgB1d,KAAK0d,cAAc/c,KAAKX,MAC7CA,KAAKmX,MAAMnX,KAAKke,uBAClB,CAEAC,WAAAA,GACE,MAAO,CACLC,OAAQ,CACN5W,MAAO,EACP0Q,MAAOlY,KAAKqe,yBAAyBC,gBAAgBC,OAAOH,QAGlE,CAEAF,qBAAuBA,KAAA,CAASM,EAAG,CAAC,KAAM,MAAOC,EAAG,CAAC,KAAM,QAE3Df,aAAAA,CAAcgB,GACZ,MAAM,GAAEZ,EAAE,GAAEE,EAAE,GAAED,EAAE,GAAEE,GAAOje,KAAK2e,OAC1BC,GAAYC,EAAAA,EAAAA,IAAiB,CAAEf,KAAIE,KAAID,KAAIE,OAC3Ca,GAAcC,EAAAA,EAAAA,IAAoB,CAAEC,UAAWhf,KAAK+C,MAAMqb,OAAO5W,SAAUoX,IAEjFF,EAAQO,UAAUH,EAAYN,EAAGM,EAAYL,GAC7CC,EAAQQ,YACRR,EAAQS,IAAI,YAAanf,KAAK+C,MAAMqb,OAAO5W,OAC3CkX,EAAQS,IAAI,cAAenf,KAAK+C,MAAMqb,OAAOlG,OAE7CwG,EAAQa,OAAOX,EAAUd,GAAIc,EAAUb,IACnC/d,KAAK+C,MAAM44B,YACbjd,EAAQkd,YAAY,CAAC57B,KAAK+C,MAAM44B,aAElCjd,EAAQc,OAAOZ,EAAUZ,GAAIY,EAAUX,IACvCS,EAAQe,SACRf,EAAQO,WAA2B,EAAjBH,EAAYN,GAAyB,EAAjBM,EAAYL,GAE9Cze,KAAKsgB,yBACPtgB,KAAKugB,aAAa7B,EAEtB,CAEAiC,QAAAA,CAASC,GACP,OAAI3W,MAAM4W,sCACNC,EAAAA,GAAKC,kBAAkBH,EAAKjC,OAAQ3e,KAAK2e,SAAW,IAGjD3e,KAAK+rB,gBAAgBnL,GAC9B,EAGFga,EAAW96B,UAAUkhB,YAAc,CACjCC,OAAQ,CAAC,CAAEtL,KAAM,OAAQvS,KAAM,YAGjC,S,8FC1DA,MAAMogC,UAA0Dhe,EAAAA,EAC9DjI,YAAcC,EAAAA,GAAkB0T,WAEhC9tB,KAAO,OAaPD,WAAAA,CAAY+E,EAAwBxG,GAClCuI,MAAM/B,EAAQxG,GACd1B,KAAKmX,MAAM,CAAEqH,EAAG,CAAC,KAAMC,EAAG,CAAC,MAC7B,CAEAP,qBAAuBA,KAAA,CAASM,EAAG,CAAC,KAAMC,EAAG,CAAC,OAE9Cf,aAAAA,CAAcgB,GACZ1e,KAAK6nB,OAAOnJ,EACd,CAEAmI,qBAAAA,GACE,MAAMC,EAAM9mB,KAAK0e,QAGd1e,KAAK+C,MAAM8iB,OAAS7lB,KAAK+mB,WAAWlB,MACnCmB,KAAKC,UAAUjnB,KAAK+C,MAAM+iB,QAAUkB,KAAKC,UAAUjnB,KAAK+mB,WAAWjB,QACrEgB,IAEA9mB,KAAK+mB,UAAYG,IAAM,CAAC,EAAGlnB,KAAK+C,OAChC/C,KAAKmnB,MAAQnnB,KAAKonB,WAAW1Z,KAAKiJ,IAAI,CACpCkP,KAAMlP,EACN0Q,QAASP,EAAIQ,YAAY3Q,OAE3B3W,KAAKunB,eAAiBvnB,KAAKmnB,MAAMpa,QAAO,CAACC,EAAKnO,EAAS2oB,IAK9Cxa,GAHLnO,EAAQwoB,QAAQI,wBAChB5oB,EAAQwoB,QAAQK,0BACfF,IAAiBxnB,KAAKmnB,MAAMlnB,OAAS,EAAI0nB,EAAAA,GAAQ8b,KAAO,KAE1D,GAEP,CAGA7c,YAAAA,CAAalI,GACX1e,KAAK0e,QAAUA,EACfA,EAAQS,IAAI,OAAQnf,KAAK8lB,MACzBpH,EAAQS,IAAI,YAAanf,KAAK+C,MAAMkjB,WACpCvH,EAAQS,IAAI,YAAanf,KAAK+C,MAAMojB,WACpCzH,EAAQS,IAAI,eAAgBnf,KAAK+C,MAAMqjB,cACvCpmB,KAAK6mB,uBACP,CAGAiB,UAAAA,GACE,IAAK9nB,KAAK0e,QAAS,OACnB,IAAID,EAAIze,KAAK2e,OAAOF,EAAKze,KAAK+C,MAAMsjB,QAAQC,IACxCyB,EAAkB,EACtB,IAAK,IAAI7F,EAAI,EAAGA,EAAIliB,KAAKmnB,MAAMlnB,OAAQiiB,IACrCzD,GAAW,IAANyD,EAAU,EAAIliB,KAAKmnB,MAAMjF,GAAGmF,QAAQI,wBAA0BM,EAAkBJ,EAAAA,GAAQ8b,KAC7FzjC,KAAK0e,QAAQsJ,SAAShoB,KAAKmnB,MAAMjF,GAAG2D,KAAM7lB,KAAK2e,OAAOH,EAAKxe,KAAK+C,MAAMsjB,QAAQI,KAAMhI,GACpFsJ,EAAkB/nB,KAAKmnB,MAAMjF,GAAGmF,QAAQK,wBAE5C,CAGAqC,gBAAAA,GACE,IAAK/pB,KAAK+C,MAAM2jB,aAAe1mB,KAAK0e,QAClC,OAEF,MAAM2H,EAAUrmB,KAAK+C,MAAMqb,OAAQ5W,MAAQ,EAAImgB,EAAAA,GAAQ+b,IAEvD1jC,KAAK0e,QAAQQ,YACblf,KAAK0e,QAAQilB,KACX3jC,KAAK2e,OAAOH,EAAK6H,EACjBrmB,KAAK2e,OAAOF,EAAKze,KAAKmnB,MAAM,GAAGE,QAAQI,wBAA0BpB,EACjErmB,KAAKwH,MAAkB,EAAV6e,EACbrmB,KAAKunB,eAA2B,EAAVlB,GAExBrmB,KAAK0e,QAAQS,IAAI,YAAanf,KAAK+C,MAAM2jB,YACzC1mB,KAAK0e,QAAQkD,OACb5hB,KAAK0e,QAAQS,IAAI,YAAanf,KAAK+C,MAAMkjB,WACzCjmB,KAAKwqB,eACLxqB,KAAK0e,QAAQ+D,WACf,CAEA9B,QAAAA,CAASC,GACP,OAAI3W,MAAM4W,yCAKR7gB,KAAKmnB,OACLnnB,KAAK2e,OAAOH,EAAKoC,EAAKjC,OAAOH,GAC7BoC,EAAKjC,OAAOH,EAAIxe,KAAK2e,OAAOH,EAAKxe,KAAKwH,OACtCxH,KAAK2e,OAAOF,EAAKze,KAAKmnB,MAAM,GAAGE,QAAQI,wBAA0B7G,EAAKjC,OAAOF,GAC7EmC,EAAKjC,OAAOF,EAAIze,KAAK2e,OAAOF,EAAKze,KAAKmnB,MAAM,GAAGE,QAAQI,wBAA0BznB,KAAKunB,iBAIjFvnB,KAAK+rB,gBAAgBnL,GAC9B,CAEAoK,gBAAAA,CAAiBthB,GACf,GAAI1J,KAAKgjB,eACP,OAAO,EAGT,IAAKhjB,KAAKmnB,MACR,OAAO,EAGT,MAAMd,EAAUrmB,KAAK+C,MAAMqb,OAAQ5W,MAAQ,EAAImgB,EAAAA,GAAQ+b,IACjDE,EAAW5jC,KAAK2e,OAAOH,EAAK6H,EAC5Bwd,EAAW7jC,KAAK2e,OAAOF,EAAKze,KAAKmnB,MAAM,GAAGE,QAAQI,wBAA0BpB,EAC5Eyd,EAAe9jC,KAAKwH,MAAkB,EAAV6e,EAC5B0d,EAAgB/jC,KAAKunB,eAA2B,EAAVlB,EAE5C,OACEud,IAAal6B,EAAMuhB,WAAavhB,EAAMlC,OACtCo8B,EAAWE,IAAiBp6B,EAAMuhB,YAClC4Y,GAAY7jC,KAAK0B,MAAM+F,QACvBo8B,EAAWE,GAAiB,CAMhC,CAEAvjB,MAAAA,CAAOhC,EAAWC,GAChBze,KAAK+C,MAAMyb,GAAMA,EACjBxe,KAAK+C,MAAM0b,GAAMA,CACnB,EAGF,S,0ECxJA,MAAMulB,EAA+B,CACnCne,KAAM,GACNC,KAAM,CACJtW,KAAM,GACNuW,OAAQ,QACR5P,MAAO,SACP6P,OAAQ,UAEVE,WAAY,GAEZC,UAAWyQ,EAAAA,GAAUnQ,KAErBL,aAAcsQ,EAAAA,GAAauN,WAC3B5d,QAAS,CACPC,IAAK,EACLC,MAAO,EACPC,OAAQ,EACRC,KAAM,IAIV,MAAMjB,UAAoD7a,EAAAA,EACxD4S,YAAcC,EAAAA,GAAkBqI,KAEhC,iCAAOqe,CACLC,GAEA,IADAnhC,EAA4B5B,UAAAnB,OAAA,QAAAoI,IAAAjH,UAAA,GAAAA,UAAA,GAAG,CAAC,EAEhC,MAAO,IACF4iC,EAASG,MACTlhC,OAAOuK,QAAQxK,GAAO+J,QAAO,CAACC,EAAGrF,KAAA,IAAGgG,EAAKC,GAAMjG,EAAA,OAAMiG,EAAQ,IAAKZ,EAAK,CAACW,GAAMC,GAAUZ,CAAG,GAAG,CAAC,GAEtG,CAEA5J,KAAO,gBAMP,gBAAO0D,GACL7D,OAAOkwB,eAAenzB,KAAKF,UAAW,QAAS,CAC7CozB,GAAAA,GAKE,OAHIlzB,KAAK0e,SACP1e,KAAK4mB,aAAa5mB,KAAK0e,SAElB1e,KAAK2wB,UAAY3wB,KAAK+C,MAAMsjB,QAAQI,KAAOzmB,KAAK+C,MAAMsjB,QAAQE,KACvE,IAGFtjB,OAAOkwB,eAAenzB,KAAKF,UAAW,SAAU,CAC9CozB,GAAAA,GACE,MAAMkR,EAAQpkC,KAAKonB,WAAWnnB,OAC9B,OAAOD,KAAK+C,MAAMmjB,WAAake,EAAQpkC,KAAK+C,MAAMsjB,QAAQC,IAAMtmB,KAAK+C,MAAMsjB,QAAQG,MACrF,IAGFvjB,OAAOkwB,eAAenzB,KAAKF,UAAW,OAAQ,CAC5CozB,GAAAA,GACE,MAAMmR,EAAIrkC,KAAK+C,MAAM+iB,KACrB,MAAQ,GAAEue,EAAEluB,SAASkuB,EAAEre,UAAUqe,EAAE70B,UAAU60B,EAAEte,QACjD,GAEJ,CAEAL,kBAAAA,GACE,MAAO,CACLzE,OAAQ,CACN,CAAEtL,KAAM,mBAAoBvS,KAAM,OAAQuiB,UAAU,GACpD,CAAEhQ,KAAM,OAAQvS,KAAM,QACtB,CACEuS,KAAM,aACNvS,KAAM,YACN0L,MAAO,QACPiW,QAAS/kB,KAAKqe,yBAAyBC,gBAAgBC,OAAOqH,uBAEhE,CACEjQ,KAAM,aACNvS,KAAM,aACN0L,MAAO,aACPiW,QAAS,iBAEX,CACEpP,KAAM,SACNvS,KAAM,SACNshB,IAAK,EACLK,QAAS,CAAE7M,MAAO,cAAe1Q,MAAO,KAIhD,CAEA2W,WAAAA,GACE,MAAO,IACF6lB,EACH/d,UAAWjmB,KAAKqe,yBAAyBC,gBAAgBC,OAAOqH,sBAEpE,CAEA1H,qBAAuBA,KAAA,CAASM,EAAG,CAAC,KAAMC,EAAG,CAAC,OAE9CU,GAAAA,CAAIqS,GAKF,OAJAvnB,MAAMkV,IAAIqS,GACNA,EAAI1L,MAAMtW,OAASgiB,EAAItL,aACzBlmB,KAAK+C,MAAMmjB,WAAa7G,KAAKwF,IAAI2M,EAAI1L,KAAKtW,KAAMxP,KAAK+C,MAAMmjB,aAEtDlmB,IACT,CAEA6nB,MAAAA,CAAOnJ,GACL1e,KAAK4mB,aAAalI,GACd1e,KAAK+C,MAAMqc,OAASpf,KAAK0e,SAE3B1e,KAAK0e,QAAQiR,OACb3vB,KAAK0e,QAAQO,UAAUjf,KAAK+C,MAAMyb,EAAIxe,KAAK+C,MAAM0b,GACjDze,KAAK0e,QAAQkR,OAAQ5vB,KAAK+C,MAAMqc,MAAQC,KAAKC,GAAM,KACnDtf,KAAK0e,QAAQsJ,SAAShoB,KAAK+C,MAAM8iB,KAAM,EAAG,GAC1C7lB,KAAK0e,QAAQmR,YAEb7vB,KAAK+pB,mBACL/pB,KAAK8nB,aAET,CAEA6I,OAAAA,CAAQjS,GACFA,GACF1e,KAAK4mB,aAAalI,GAEpB,MAAMyI,EAAQnnB,KAAKonB,WACnB,IAAIvC,EAAM,EACV,IAAK,MAAMlO,KAAQwQ,EACjBtC,EAAMxF,KAAKwF,IAAI7kB,KAAK0e,SAAS4I,YAAY3Q,GAAMnP,OAASsc,OAAOwgB,iBAAkBzf,GAEnF,QAASA,CACX,CAEAlE,QAAAA,CAAS4jB,GACP,MAAM3jB,EAAO5gB,KAAKwkC,YAAYD,GAE9B,OACEvkC,KAAK+C,MAAMyb,EAAKoC,EAAKpC,GACrBoC,EAAKpC,EAAIxe,KAAK+C,MAAMyb,EAAKxe,KAAKwH,OAC9BxH,KAAK+C,MAAM0b,EAAKze,KAAK+C,MAAM+iB,KAAKtW,KAAOoR,EAAKnC,GAC5CmC,EAAKnC,EAAIze,KAAK+C,MAAM0b,EAAKze,KAAK+C,MAAM+iB,KAAKtW,KAAOxP,KAAKyH,QAIhDwC,MAAM0W,SAAS4jB,EACxB,CAEA3d,YAAAA,CAAalI,GACX1e,KAAK0e,QAAUA,EACfA,EAAQS,IAAI,OAAQnf,KAAK8lB,MACzBpH,EAAQS,IAAI,YAAanf,KAAK+C,MAAMkjB,WACpCvH,EAAQS,IAAI,YAAanf,KAAK+C,MAAMojB,WACpCzH,EAAQS,IAAI,eAAgBnf,KAAK+C,MAAMqjB,aACzC,CAEAgB,QAAAA,GACE,OAAOpnB,KAAK+C,MAAM8iB,KAAKthB,WAAWw1B,MAAM,KAC1C,CAEAjS,UAAAA,GACE,IAAK9nB,KAAK0e,QAAS,OACnB,IAAI,EAAED,GAAMze,KAAK+C,MACjB,IAAK,MAAM4T,KAAQ3W,KAAKonB,WACtBpnB,KAAK0e,QAAQsJ,SAASrR,EAAM3W,KAAK+C,MAAMyb,EAAKxe,KAAK+C,MAAMsjB,QAAQI,KAAMhI,GACrEA,GAAMze,KAAK+C,MAAMmjB,UAErB,CAEA6D,gBAAAA,GACE,IAAK/pB,KAAK+C,MAAM2jB,aAAe1mB,KAAK0e,QAClC,OAGF,MAAM,MAAElX,GAAUxH,MACZ,OAAEyH,GAAWzH,KACbykC,EAAWh9B,EAASzH,KAAK+C,MAAMsjB,QAAQC,IAAMtmB,KAAK+C,MAAMsjB,QAAQG,QAChE,EAAEhI,GAAMxe,KAAK+C,MACnB,IAAI0b,EAAIze,KAAK+C,MAAM0b,EAAKhX,EAEQ,WAA5BzH,KAAK+C,MAAMqjB,aACb3H,EAAIze,KAAK+C,MAAM0b,EAAKgmB,EAAW,EAAIzkC,KAAK+C,MAAMsjB,QAAQC,IAAM,EACvB,eAA5BtmB,KAAK+C,MAAMqjB,eACpB3H,EAAIze,KAAK+C,MAAM0b,EAAKze,KAAK+C,MAAMmjB,YAGjClmB,KAAK0e,QAAQQ,YACblf,KAAK0e,QAAQS,IAAI,YAAanf,KAAK+C,MAAM2jB,YACzC1mB,KAAK0e,QAAQilB,KAAKnlB,EAAIC,EAAGjX,EAAOC,GAChCzH,KAAK0e,QAAQkD,OACb5hB,KAAK0e,QAAQS,IAAI,YAAanf,KAAK+C,MAAMkjB,WACzCjmB,KAAKwqB,eACLxqB,KAAK0e,QAAQ+D,WACf,CAEA+H,YAAAA,GACE,MAAM,UAAExL,EAAY,EAAC,YAAE0c,EAAW,OAAEtd,GAAWpe,KAAK+C,MAC9C2hC,EAActmB,GAAQ5W,OAAS,GAEhCwX,GAAahf,KAAK+C,MAAM24B,aAAegJ,EAAc,IAAM1kC,KAAK0e,UACnE1e,KAAK0e,QAAQS,IAAI,cAAeuc,GAAetd,GAAQlG,OAAS,IAChElY,KAAK0e,QAAQS,IAAI,YAAaE,KAAKwF,IAAI7F,EAAW0lB,IAClD1kC,KAAK0e,QAAQe,SAEjB,CAEQ+kB,WAAAA,CAAY5jB,GAClB,MAAM,cAAEsa,GAAkBl7B,KAAKqe,yBAC/B,MAAO,CACLG,EAAGxe,KAAK0B,MAAMyV,MAAMqH,EAAEoC,EAAKpC,GAAKxe,KAAK0B,MAAMgI,QAAQuhB,WAAaiQ,EAAczU,KAAKjf,MACnFiX,EAAGze,KAAK0B,MAAMyV,MAAMsH,EAAEmC,EAAKnC,GAAKyc,EAAc5U,IAAI7e,OAEtD,CAEA+Y,MAAAA,CAAOhC,EAAWC,GAChBze,KAAK+C,MAAMyb,GAAMxe,KAAK0B,MAAMyV,MAAMqH,EAAEA,GAAK,EACzCxe,KAAK+C,MAAM0b,GAAMze,KAAK0B,MAAMyV,MAAMsH,EAAEA,GAAKze,KAAK0B,MAAMyV,MAAMsH,EAAE,EAC9D,CAEA6e,SAAAA,GACE,OAAOt9B,KAAKyH,MACd,EAGF+d,EAAK1e,YAEL,S,6DC5JA,QA5EA,MACE6O,KACAkN,MAAQ,EACRC,MAAQ,EACRX,GACAC,GACAzE,OACAjc,MAEAyB,WAAAA,CAAYwS,EAAiBwM,EAAeC,EAAezE,EAAoBjc,GAC7E1B,KAAK2V,KAAOA,EACZ3V,KAAKmiB,GAAKA,EACVniB,KAAKoiB,GAAKA,EACVpiB,KAAK2d,OAASA,EACd3d,KAAK0B,MAAQA,CACf,CAEAmmB,MAAAA,CAAOnJ,GACL,MAAM,cAAEimB,GAAkB3kC,KAAK0B,MAAM2c,yBACrCK,EAAQS,IAAI,YAAawlB,EAAczsB,OACvCwG,EAAQS,IAAI,cAAewlB,EAAcC,aACzClmB,EAAQS,IAAI,YAAawlB,EAAcD,aACvC,MAAMlmB,IAAMxe,KAAKwe,IACXC,IAAMze,KAAKye,IACXomB,EAAa7kC,KAAK8kC,gBAClBvO,GAASC,EAAAA,EAAAA,IAAuBmO,EAAcD,aACpDhmB,EAAQQ,YACRR,EAAQilB,KAAKnlB,EAAI+X,EAAQ9X,EAAI8X,EAAQsO,EAAYA,GACjDnmB,EAAQkD,OACRlD,EAAQe,QACV,CAEA6T,YAAAA,CAAa1S,GAEX,OADA5gB,KAAK6iB,MAAQjC,EAAKpC,EACVxe,KAAK8iB,MAAQlC,EAAKnC,CAC5B,CAEAc,MAAAA,CAAOqB,GACL,MAAMH,EAAOG,EAAKpC,EAAIxe,KAAK6iB,MACrBnC,EAAOE,EAAKnC,EAAIze,KAAK8iB,MAC3B9iB,KAAK2d,OAAO,CAAEhI,KAAM3V,KAAK2V,KAAM8K,OAAMC,OAAME,SAC3C5gB,KAAK6iB,MAAQjC,EAAKpC,EAClBxe,KAAK8iB,MAAQlC,EAAKnC,CACpB,CAEAkC,QAAAA,CAASC,GACP,MAAMpZ,EAAQxH,KAAK0B,MAAMyV,MAAMqH,EAAE0N,OAAOlsB,KAAK8kC,iBACvCr9B,EAASzH,KAAK0B,MAAMyV,MAAMsH,EAAEyN,OAAO,GAAKlsB,KAAK0B,MAAMyV,MAAMsH,EAAEyN,OAAOlsB,KAAK8kC,iBAE7E,OACE9kC,KAAKmiB,KAAO3a,EAAQ,GAAKoZ,EAAKpC,GAC9Bxe,KAAKmiB,KAAO3a,EAAQ,GAAKoZ,EAAKpC,GAC9Bxe,KAAKoiB,KAAO3a,EAAS,EAAImZ,EAAKnC,GAC9Bze,KAAKoiB,KAAO3a,EAAS,EAAImZ,EAAKnC,CAKlC,CAEAqmB,aAAAA,GACE,MAAM,cAAEH,GAAkB3kC,KAAK0B,MAAM2c,yBACrC,OAAOsmB,EAAcn1B,KAAmC,EAA5Bm1B,EAAcD,WAC5C,CAEAlmB,CAAAA,GACE,MAAM,cAAEmmB,GAAkB3kC,KAAK0B,MAAM2c,yBACrC,OAAOre,KAAK0B,MAAMyV,MAAMqH,EAAExe,KAAKmiB,MAAQwiB,EAAcn1B,KAAO,CAC9D,CAEAiP,CAAAA,GACE,MAAM,cAAEkmB,GAAkB3kC,KAAK0B,MAAM2c,yBACrC,OAAOre,KAAK0B,MAAMyV,MAAMsH,EAAEze,KAAKoiB,MAAQuiB,EAAcn1B,KAAO,CAC9D,E,yGC9DF,MAAMu1B,UAAgEp6B,EAAAA,EACpE4S,YAAcC,EAAAA,GAAkB4T,SAGhChuB,KAAO,WAEPD,WAAAA,CAAY+E,EAAwBxG,GAClCuI,MAAM/B,EAAQxG,GAEd1B,KAAK2d,OAAS3d,KAAK2d,OAAOhd,KAAKX,MAE/BA,KAAK4d,QAAU,CACb,IAAIC,EAAAA,EACF,KACA,IAAM7d,KAAK+C,MAAM+a,KACjB,IAAM9d,KAAK+C,MAAMgb,IACjB/d,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,KACA,IAAM7d,KAAK+C,MAAMib,KACjB,IAAMhe,KAAK+C,MAAMkb,IACjBje,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,KACA,IAAM7d,KAAK+C,MAAMqoB,KACjB,IAAMprB,KAAK+C,MAAMsoB,IACjBrrB,KAAK2d,OACL3d,KAAK0B,QAGT1B,KAAKmX,MAAMnX,KAAKke,uBAClB,CAEAC,WAAAA,GACE,MAAM,gBAAEG,GAAoBte,KAAKqe,yBACjC,MAAO,CAAEuD,KAAMtD,EAAgBqI,YAAavI,OAAQE,EAAgBC,OAAOH,OAC7E,CAEAF,qBAAuBA,KAAA,CAASM,EAAG,CAAC,KAAM,KAAM,MAAOC,EAAG,CAAC,KAAM,KAAM,QAEvEf,aAAAA,CAAcgB,GACZ,MAAM,GAAEZ,EAAE,GAAEE,EAAE,GAAEoN,EAAE,GAAErN,EAAE,GAAEE,EAAE,GAAEoN,GAAOrrB,KAAK2e,OAClCC,GAAYC,EAAAA,EAAAA,IAAiB,CAAEf,KAAIE,KAAIoN,KAAIrN,KAAIE,KAAIoN,OAEzD3M,EAAQS,IAAI,YAAanf,KAAK+C,MAAM6e,MAEpC,MAAM2U,EAASv2B,KAAKsgB,yBAA0BkW,EAAAA,EAAAA,IAAuB,GAAK,EAE1E9X,EAAQO,UAAUsX,EAAQA,GAC1B7X,EAAQQ,YACRR,EAAQa,OAAOX,EAAUd,GAAIc,EAAUb,IACvCW,EAAQc,OAAOZ,EAAUZ,GAAIY,EAAUX,IACvCS,EAAQc,OAAOZ,EAAUwM,GAAIxM,EAAUyM,IACvC3M,EAAQc,OAAOZ,EAAUd,GAAIc,EAAUb,IACvCW,EAAQkD,OACRlD,EAAQO,WAAoB,EAAVsX,GAAuB,EAAVA,GAE3Bv2B,KAAKsgB,0BACP5B,EAAQS,IAAI,cAAenf,KAAK+C,MAAMqb,QACtCM,EAAQe,SACRzf,KAAKugB,aAAa7B,GAEtB,CAEA8B,MAAAA,CAAOhC,EAAWC,GAChBze,KAAK+C,MAAM+a,IAAMU,EACjBxe,KAAK+C,MAAMgb,IAAMU,EACjBze,KAAK+C,MAAMib,IAAMQ,EACjBxe,KAAK+C,MAAMkb,IAAMQ,EACjBze,KAAK+C,MAAMqoB,IAAM5M,EACjBxe,KAAK+C,MAAMsoB,IAAM5M,CACnB,CAEAd,MAAAA,CAAMhW,GAAqD,IAApD,KAAEgO,EAAI,KAAE8K,EAAI,KAAEC,GAAoC/Y,EACvD,OAAQgO,GACN,IAAK,IACH3V,KAAK+C,MAAM+a,IAAM2C,EACjBzgB,KAAK+C,MAAMgb,IAAM2C,EACjB,MACF,IAAK,IACH1gB,KAAK+C,MAAMib,IAAMyC,EACjBzgB,KAAK+C,MAAMkb,IAAMyC,EACjB,MACF,IAAK,IACH1gB,KAAK+C,MAAMqoB,IAAM3K,EACjBzgB,KAAK+C,MAAMsoB,IAAM3K,EAKvB,CAEAC,QAAAA,CAASC,GACP,GAAI3W,MAAM4W,oCAAqC,OAAO,EACtD,MAAMiK,EAAU,CAAC,EAAG,EAAG,GAAGpd,KAAKwU,IAAC,CAC9B1D,EAAGxe,KAAK2e,OAAQ,IAAGuD,KACnBzD,EAAGze,KAAK2e,OAAQ,IAAGuD,SAErB,QAAIpB,EAAAA,GAAKiK,eAAenK,EAAKjC,OAAQmM,IAG9B7gB,MAAM0W,SAASC,EACxB,EAGFmkB,EAASjlC,UAAUkhB,YAAc,CAC/BC,OAAQ,CAAC,CAAEtL,KAAM,aAAcvS,KAAM,UAGvC,S,0EC9HA,MAAM4hC,UAAwEpK,EAAAA,EAC5Erd,YAAcC,EAAAA,GAAkB6T,aAEhCjuB,KAAO,gBAEPD,WAAAA,CAAY+E,EAAwBxG,GAClCuI,MAAM/B,EAAQxG,GAEd1B,KAAK0d,cAAgB1d,KAAK0d,cAAc/c,KAAKX,MAE7CA,KAAK+C,MAAMib,GAAKhe,KAAK+C,MAAM+a,GAC3B9d,KAAK4d,QAAU,CAAC5d,KAAK4d,QAAQ,GAC/B,CAEAM,qBAAuBA,KAAA,CAASM,EAAG,CAAC,KAAM,MAAOC,EAAG,CAAC,KAAM,QAE3Df,aAAAA,CAAcgB,GACZ,MAAM0E,EAASpjB,KAAK0B,MAAMyV,MAAMsH,EAAE2E,SAClCpjB,KAAK+C,MAAMgb,GAAKqF,EAAO,GACvBpjB,KAAK+C,MAAMkb,GAAKmF,EAAO,GACvBpjB,KAAK4d,QAAQ,GAAGwE,GAAK,KAAOpiB,KAAK+C,MAAMgb,GAAK/d,KAAK+C,MAAMkb,IAAM,EAC7DhU,MAAMyT,cAAcgB,EACtB,CAEA8B,MAAAA,CAAOhC,GACL,OAAQxe,KAAK+C,MAAM+a,GAAK9d,KAAK+C,MAAMib,IAAMQ,CAC3C,CAEAb,MAAAA,CAAMhW,GAAyD,IAAxD,KAAE8Y,GAAoD9Y,EAC3D,OAAO3H,KAAKwgB,OAAOC,EACrB,CAEAuK,gBAAAA,CAAiBthB,GACf,OAAOO,MAAM+gB,iBAAiBthB,EAAO,CAAEwsB,OAAO,GAChD,EAGF,S,6HCZA,MAAM+O,UAAuDt6B,EAAAA,EAC3D4S,YAAcC,EAAAA,GAAkB8T,MAEhCluB,KAAO,gBAIPD,WAAAA,CAAY+E,EAAwBxG,GAClCuI,MAAM/B,EAAQxG,GAEd1B,KAAK2d,OAAS3d,KAAK2d,OAAOhd,KAAKX,MAE/BA,KAAK4d,QAAU,CACb,IAAIC,EAAAA,EACF,KACA,IAAM7d,KAAK+C,MAAMmiC,KACjB,IAAMllC,KAAK+C,MAAMoiC,IACjBnlC,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,KACA,IAAM7d,KAAK+C,MAAMqiC,KACjB,IAAMplC,KAAK+C,MAAMsiC,IACjBrlC,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,KACA,IAAM7d,KAAK+C,MAAMuiC,KACjB,IAAMtlC,KAAK+C,MAAMwiC,IACjBvlC,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,KACA,IAAM7d,KAAK+C,MAAM+sB,KACjB,IAAM9vB,KAAK+C,MAAMgtB,IACjB/vB,KAAK2d,OACL3d,KAAK0B,OAEP,IAAImc,EAAAA,EACF,KACA,IAAM7d,KAAK+C,MAAM2rB,KACjB,IAAM1uB,KAAK+C,MAAM6rB,IACjB5uB,KAAK2d,OACL3d,KAAK0B,QAGmB,MAAxB1B,KAAK+C,MAAMic,YACbhf,KAAK+C,MAAMic,UAAY,GAEzBhf,KAAKmX,MAAMnX,KAAKke,uBAClB,CAEAC,WAAAA,GACE,MAAM,gBAAEG,GAAoBte,KAAKqe,yBACjC,MAAO,CACLuD,KAAMtD,EAAgBqI,YACtBvI,OAAQ,CACN5W,MAAO,EACP0Q,MAAOoG,EAAgBC,OAAOH,QAGpC,CAEAF,qBAAuBA,KAAA,CACrBM,EAAG,CAAC,KAAM,KAAM,KAAM,KAAM,MAC5BC,EAAG,CAAC,KAAM,KAAM,KAAM,KAAM,QAG9Bf,aAAAA,CAAcgB,GACZ,MAAM,GAAEwmB,EAAE,GAAEC,EAAE,GAAEC,EAAE,GAAEC,EAAE,GAAEC,EAAE,GAAEC,EAAE,GAAEzV,EAAE,GAAEC,EAAE,GAAErB,EAAE,GAAEE,GAAO5uB,KAAK2e,OAClDC,GAAYC,EAAAA,EAAAA,IAAiB,CAAEqmB,KAAIC,KAAIC,KAAIC,KAAIC,KAAIC,KAAIzV,KAAIC,KAAIrB,KAAIE,OAEzElQ,EAAQS,IAAI,YAAanf,KAAK+C,MAAM6e,MACpClD,EAAQS,IAAI,YAAanf,KAAK+C,MAAMqb,OAAO5W,OAC3CkX,EAAQS,IAAI,cAAenf,KAAK+C,MAAMqb,OAAOlG,OAE7C,MAAMqe,GAASC,EAAAA,EAAAA,IAAuBx2B,KAAK+C,MAAMqb,OAAO5W,OACxDkX,EAAQO,UAAUsX,EAAQA,GAE1B7X,EAAQQ,YACRR,EAAQa,OAAOX,EAAUsmB,GAAItmB,EAAUumB,IACvCzmB,EAAQc,OAAOZ,EAAUwmB,GAAIxmB,EAAUymB,IACvC3mB,EAAQc,OAAOZ,EAAU0mB,GAAI1mB,EAAU2mB,IACvC7mB,EAAQc,OAAOZ,EAAUsmB,GAAItmB,EAAUumB,IACvCzmB,EAAQkD,OACkE,KAAhD,MAArB5hB,KAAK+C,MAAMqb,OAAiBpe,KAAK+C,MAAMqb,OAAO5W,WAAQa,IACzDqW,EAAQe,SAGVf,EAAQQ,YACRR,EAAQa,OAAOX,EAAU0mB,GAAI1mB,EAAU2mB,IACvC7mB,EAAQc,OAAOZ,EAAUkR,GAAIlR,EAAUmR,IACvCrR,EAAQc,OAAOZ,EAAU8P,GAAI9P,EAAUgQ,IACvClQ,EAAQc,OAAOZ,EAAU0mB,GAAI1mB,EAAU2mB,IACvC7mB,EAAQkD,OACkE,KAAhD,MAArB5hB,KAAK+C,MAAMqb,OAAiBpe,KAAK+C,MAAMqb,OAAO5W,WAAQa,IACzDqW,EAAQe,SAGVf,EAAQQ,YACRR,EAAQa,OAAOX,EAAUwmB,GAAIxmB,EAAUymB,IACvC3mB,EAAQc,OAAOZ,EAAUkR,GAAIlR,EAAUmR,IACvCrR,EAAQa,OAAOX,EAAUsmB,GAAItmB,EAAUumB,IACvCzmB,EAAQc,OAAOZ,EAAU8P,GAAI9P,EAAUgQ,IACvClQ,EAAQe,SAER,MAAMoG,EAAO,IAAIL,EAAAA,EACf,CACEM,KAAM,CAAEtW,KAAM,EAAG2G,MAAO,QACxB+P,WAAY,EACZG,QAAS,CACPC,IAAK,EACLC,MAAO,EACPC,OAAQ,EACRC,KAAM,GAERL,aAAcsQ,EAAAA,GAAaC,OAC3BxQ,UAAWyQ,EAAAA,GAAU4O,MACrBvf,UAAW,UACXS,WAAY1mB,KAAK+C,MAAM6e,MAAQ,WAEjC5hB,KAAK0B,OAGP,IAAK,MAAMqhC,KAAKljC,MAAMk1B,KAAK,SACzBlP,EACG1G,IAAI,CACH0G,KAAMkd,EAAE0C,cACRjnB,EAAGI,EAAWmkB,EAAI,KAAmB,EACrCtkB,EAAGG,EAAWmkB,EAAI,KAAmB,KAEtClb,OAAOnJ,GAGZ,MAAMgnB,EAAWA,CAAC3nB,EAAYE,EAAYoN,KACxC,MAAMsa,EAAMtmB,KAAKQ,IAAI7f,KAAK+C,MAAOgb,EAAK,KAAmB/d,KAAK+C,MAAOkb,EAAK,MACpE2nB,EAAMvmB,KAAKQ,IAAI7f,KAAK+C,MAAOsoB,EAAK,KAAmBrrB,KAAK+C,MAAOkb,EAAK,MAAoB0nB,EACxFnnB,GAAKI,EAAWb,EAAK,KAAmBa,EAAWyM,EAAK,MAAoB,EAC5E5M,GAAKG,EAAWb,EAAK,KAAmBa,EAAWyM,EAAK,MAAoB,EAClF,OAAOxF,EACJ1G,IAAI,CACH0G,KAAM+f,EAAIhiC,QAAQ,GAClB4a,IACAC,MAEDoJ,OAAOnJ,EAAQ,EAGpBgnB,EAAS,IAAK,IAAK,KACnBA,EAAS,IAAK,IAAK,KACnBA,EAAS,IAAK,IAAK,KACnBA,EAAS,IAAK,IAAK,KAEf1lC,KAAKsgB,yBACPtgB,KAAKugB,aAAa7B,GAEpBA,EAAQO,WAAoB,EAAVsX,GAAuB,EAAVA,EACjC,CAEA/V,MAAAA,CAAOhC,EAAWC,GAChB,IAAK,MAAMskB,KAAKljC,MAAMk1B,KAAK,SACzB/0B,KAAK+C,MAAOggC,EAAI,MAAoBvkB,EACpCxe,KAAK+C,MAAOggC,EAAI,MAAoBtkB,CAExC,CAEAd,MAAAA,CAAMhW,GAAqD,IAApD,KAAEgO,EAAI,KAAE8K,EAAI,KAAEC,GAAoC/Y,EAEvD,OADA3H,KAAK+C,MAAO4S,EAAO,MAAoB8K,EAC/BzgB,KAAK+C,MAAO4S,EAAO,MAAoB+K,CACjD,CAEAC,QAAAA,CAASC,GACP,GAAI3W,MAAM4W,oCAAqC,OAAO,EACtD,IAAIkiB,EACJ,MAAM8C,EAAM,MACV,MAAMlD,EAAS,GACf,IAAKI,KAAKljC,MAAMk1B,KAAK,OACnB4N,EAAOphC,KAAK,CAAEid,EAAGxe,KAAK2e,OAAQokB,EAAI,KAAkBtkB,EAAGze,KAAK2e,OAAQokB,EAAI,OAE1E,OAAOJ,CACR,EANW,GAONmD,EAAM,MACV,MAAMC,EAAU,GAChB,IAAKhD,KAAKljC,MAAMk1B,KAAK,OACnBgR,EAAQxkC,KAAK,CAAEid,EAAGxe,KAAK2e,OAAQokB,EAAI,KAAkBtkB,EAAGze,KAAK2e,OAAQokB,EAAI,OAE3E,OAAOgD,CACR,EANW,GAOZ,SAAIjlB,EAAAA,GAAKiK,eAAenK,EAAKjC,OAAQknB,KAAQ/kB,EAAAA,GAAKiK,eAAenK,EAAKjC,OAAQmnB,KAGvE77B,MAAM0W,SAASC,EACxB,EAGFqkB,EAAMnlC,UAAUkhB,YAAc,CAC5BC,OAAQ,CACN,CAAEtL,KAAM,aAAcvS,KAAM,QAC5B,CAAEuS,KAAM,SAAUvS,KAAM,SAAUshB,IAAK,KAI3C,S,gMCvJA,QAjFA,MACE,WAAAvhB,GACEnD,KAAKgmC,QAAS,UAAa,KAAOp7B,SAAS8W,cAAc,SAC3D,CAEA,GAAAvC,CAAIte,EAAU2G,EAAOC,GACnBzH,KAAKa,SAAWA,EAChBb,KAAKwH,MAAQA,EACbxH,KAAKyH,OAASA,EACdzH,KAAKimC,UAAW,CAClB,CAEA,MAAApe,CAAOnJ,EAASF,EAAGC,GAUjB,GATS,MAALD,IACFA,EAAI,GAEG,MAALC,IACFA,EAAI,GAEDze,KAAKimC,UACRjmC,KAAKkmC,YAEHlmC,KAAKwH,MAAQ,GAAKxH,KAAKyH,OAAS,GAIpC,IACMzH,KAAKmmC,OAAS,GAAKnmC,KAAKgmC,OAC1BtnB,EAAQ0nB,UACNpmC,KAAKgmC,OACL,EACA,KACGhmC,KAAKwH,MAAQxH,KAAKmmC,UAClBnmC,KAAKyH,OAASzH,KAAKmmC,OACtB3nB,EACAC,EACAze,KAAKwH,MACLxH,KAAKyH,SAGPiX,EAAQiR,OACRjR,EAAQO,UAAUT,EAAGC,GACrBze,KAAKa,SAAS6d,GACdA,EAAQmR,UAEZ,CAAE,MAAOtqB,IACP,QACEA,EACAvF,KAAKgmC,OACD,CACE38B,MAAO,CACL7B,MAAOxH,KAAKwH,MACZC,OAAQzH,KAAKyH,OACb0+B,MAAOnmC,KAAKmmC,MACZE,OAAQrmC,KAAKgmC,OAAOx+B,MACpB8+B,QAAStmC,KAAKgmC,OAAOv+B,OACrB8+B,OAAQ1gC,OAAO2gC,OAAOh/B,MACtBi/B,QAAS5gC,OAAO2gC,OAAO/+B,SAG3B,CAAC,EAET,CACF,CAEA,OAAAy+B,IACM,YAGJlmC,KAAKgmC,OAAOx+B,MAAQxH,KAAKwH,MACzBxH,KAAKgmC,OAAOv+B,OAASzH,KAAKyH,OAC1BzH,KAAK0e,SAAU,OAAoB1e,KAAKgmC,QACxChmC,KAAKmmC,MAAQ,KAAMO,gBACnB,KAAMC,uBAAuB,CAAEC,cAAe5mC,KAAKgmC,OAAQx+B,MAAOxH,KAAKwH,MAAOC,OAAQzH,KAAKyH,SAC3FzH,KAAK0e,QAAQvH,MAAMnX,KAAKmmC,MAAOnmC,KAAKmmC,OAEpCnmC,KAAKa,SAASb,KAAK0e,SACnB1e,KAAKimC,UAAW,EAClB,G,oEC9EK,IAAKY,EAAQ,SAARA,GAAQ,OAARA,EAAQ,wBAARA,EAAQ,oBAARA,EAAQ,oBAARA,CAAQ,M,sECJb,IAAKC,EAAwB,SAAxBA,GAAwB,OAAxBA,EAAAA,EAAwB,WAAxBA,EAAAA,EAAwB,WAAxBA,EAAAA,EAAwB,WAAxBA,EAAAA,EAAwB,YAAxBA,CAAwB,MAO7B,SAASC,EAAoBC,GAClC,MAAO,CACLC,KAAMD,GAAkBF,EAAyBI,GACjDC,IAAKH,GAAkBF,EAAyB9D,EAChDoE,IAAKJ,GAAkBF,EAAyBO,EAChDC,IAAKN,GAAkBF,EAAyB/3B,EAEpD,CCqGA,MAAMw4B,EAAgB5/B,IAA+D,IAA9D,KAAE6/B,EAAI,UAAE/yB,GAAiD9M,EAC1E8/B,EAAa,GACjB,MAAMC,EAAQF,EAAKG,WACbC,EAAOJ,EAAKK,cACZC,EAAMN,EAAKO,UACjB,OAAQtzB,GACN,KAAKuzB,EAAAA,GAAUC,GACf,KAAKD,EAAAA,GAAUE,GACf,KAAKF,EAAAA,GAAUG,GACf,KAAKH,EAAAA,GAAUI,GACf,KAAKJ,EAAAA,GAAUK,IACf,KAAKL,EAAAA,GAAUM,IACf,KAAKN,EAAAA,GAAUO,IACf,KAAKP,EAAAA,GAAUpoB,EACf,KAAKooB,EAAAA,GAAUQ,GACf,KAAKR,EAAAA,GAAUS,GACb,MAAM1F,IACDyE,EAAK1iC,WAAa,IAAM,GAAM,GAAGP,WAAWpE,QAAQ,MACvD,IACAqnC,EAAKziC,aAAaR,WAAWpE,QAAQ,OACpCqnC,EAAK1iC,WAAa,GAAK,KAAO,MACjC2iC,EAAc,GAAEiB,EAAAA,GAAOhB,MAAUI,KAAO/E,IACxC,MACF,KAAKiF,EAAAA,GAAUlc,EACf,KAAKkc,EAAAA,GAAUW,EACblB,EAAc,GAAEiB,EAAAA,GAAOhB,MAAUI,IACjC,MACF,KAAKE,EAAAA,GAAUX,EACbI,EAAc,GAAEiB,EAAAA,GAAOhB,MAAUE,IAMrC,OAAOH,CAAU,EAkBnB,SAASmB,EACPC,EACAC,EACA3sB,EACA4sB,GAEA,MAAMC,EAAmBH,EAAkB,EACrCI,EAAeH,EAAkB3sB,EAAKlc,OAAS,EACrD,IAAIipC,EAAWL,EACXM,EAAWL,EAQf,OAPIE,IACFE,GAAY,GAEVD,IACFE,GAAY,GAGVJ,EAAIG,KAAc/sB,EAAKgtB,KAAcH,GAAoBC,GACpDL,EAAsCM,EAAUC,EAAUhtB,EAAM4sB,GAGlEA,EAAIG,GAAY/sB,EAAKgtB,GAAY,CAAED,WAAUC,YAAa,CAAED,SAAUC,EAAUA,SAAUD,EACnG,CAEA,MAEME,EAAUC,IAAAA,KAAoB,KAEpC,MAAMC,UAA6D3+B,EAAAA,EACjE,gBAAO7D,GACL7D,OAAOkwB,eAAenzB,KAAKF,UAAW,QAAS,CAC7CozB,GAAAA,GACE,MAAM,cAAEgI,GAAkBl7B,KAAKqe,yBAC/B,OAAOre,KAAK0B,MAAM8F,MAAQ0zB,EAAczU,KAAKjf,MAAQ0zB,EAAc3U,MAAM/e,KAC3E,IAGFvE,OAAOkwB,eAAenzB,KAAKF,UAAW,SAAU,CAC9CozB,GAAAA,GACE,MAAM,cAAEgI,GAAkBl7B,KAAKqe,yBAC/B,OAAOre,KAAK+G,UAAUU,OAASyzB,EAAc5U,IAAI7e,OAASyzB,EAAc1U,OAAO/e,MACjF,GAEJ,CAEA,yBAAOgqB,CAAkB/hB,GAAsE,IAArE,SAAEsI,GAAiEtI,EAC3F,OAAO2P,KAAKwF,IAAI,KAAM7M,EAAStK,KAAKuK,GAAYsxB,EAAAA,EAAetxB,EAAQtC,MAAM8b,mBAAmBxZ,KAClG,CAEAsF,aAAe,QACfA,gBAAkB,GAElBxW,UACArF,MACAkD,KACAyM,2BACAm4B,YAAc,EACdC,YAAc,EACdC,SAA0C,GAC1C1xB,SAAsB,GACtB2xB,aACAC,oBAAqB,EACrBC,YAIW,KAYX1mC,WAAAA,CAAY+E,EAAoBnB,GAC9BkD,MAAM/B,EAAQnB,GAEd/G,KAAK+G,UAAYA,EACjB/G,KAAK0B,MAAQ1B,KAAK+G,UAAU2C,QAC5B1J,KAAK4E,KAAO5E,KAAK0B,MAAMiI,QACvB,MAAM0E,EAAmBrO,KAAK0B,MAAMkyB,eAMpC,GALA5zB,KAAKqR,2BAA6BhD,EAAiBgD,2BACnDrR,KAAK2pC,aAAet7B,EAAiBs7B,aACrC3pC,KAAK8pC,SAAWC,EAAAA,GAAMD,UAAS,GAE/B9pC,KAAKgY,SAAW,GACZ9P,EAAO8P,SAAU,CACnB,IAAK,MAAMgyB,KAAqB9hC,EAAO8P,SAAU,CAO/C,MAAMC,EAAUsxB,EAAAA,EAAeS,EAAkBr0B,MAAM4b,WACrD,IACKyY,EACH9xB,OACG8xB,EAAkB9xB,OAAS8xB,EAAkB9xB,MAAMkiB,SAAS,KACzD,IACA6P,EAAAA,EAAAA,IAAkBD,EAAkB9xB,QAE5ClY,KAAK+G,WAEP/G,KAAKkqC,WAAWjyB,EAClB,QACO/P,EAAO8P,QAChB,CAEAhY,KAAKmqC,YAAcnqC,KAAKmqC,YAAYxpC,KAAKX,MACzCA,KAAK8nB,WAAa9nB,KAAK8nB,WAAWnnB,KAAKX,MACvCA,KAAKoqC,gBAAkBpqC,KAAKoqC,gBAAgBzpC,KAAKX,MACjDA,KAAKqqC,WAAarqC,KAAKqqC,WAAW1pC,KAAKX,MACvCA,KAAKsqC,qBAAuBtqC,KAAKsqC,qBAAqB3pC,KAAKX,MAG3DA,KAAK+G,UAAUpG,KAAK,SAAUX,KAAKqqC,YACnCrqC,KAAK+G,UAAUpG,KAAK,SAAUX,KAAKuJ,QAAQ5I,KAAKX,KAAM,WACtDA,KAAK0B,MAAQ1B,KAAK+G,UAAU2C,QAE5B1J,KAAK0B,MAAMf,KAAK,SAAUX,KAAKqqC,YAC/BrqC,KAAK0B,MAAMf,KAAK,SAAUX,KAAKuJ,QAAQ5I,KAAKX,KAAM,WAClDA,KAAK0B,MAAMf,KAAK4pC,EAAAA,GAAkBC,iBAAkBxqC,KAAKyqC,uBAAuB9pC,KAAKX,OACrF,MAAM0qC,EAA0B1qC,KAAKuJ,QAAQ5I,KAAKX,KAAM,SAAU,SAClEA,KAAK0B,MAAMf,KAAK,WAAW,KACzBX,KAAK0B,MAAMC,OAAO,SAAU3B,KAAKqqC,YACjCrqC,KAAK0B,MAAMC,OAAO4oC,EAAAA,GAAkBC,iBAAkBxqC,KAAKyqC,uBAAuB9pC,KAAKX,OACvF2qC,EAAAA,EAAWhpC,OAAO,SAAU+oC,IAC5BE,EAAAA,EAAAA,IAAc5qC,KAAK6qC,UAAU7E,OAAO,IAEtC2E,EAAAA,EAAWhqC,KAAK,SAAU+pC,GAE1B1qC,KAAK0B,MAAMkyB,eAAejzB,KAAK,QAASX,KAAKqqC,YAC7CrqC,KAAK0B,MAAMkyB,eAAejzB,KAAK,SAAUX,KAAK8qC,yBAAyBnqC,KAAKX,OAE5EA,KAAKqqC,YACP,CAEAU,WAAAA,GACE,MAAM3hC,MAAM,wBACd,CAEAye,MAAAA,CAAOnJ,GAKL,GAJA1e,KAAK4E,KAAO5E,KAAK0B,MAAMiI,QACvB3J,KAAKirB,WAAajrB,KAAK0B,MAAMupB,WAC7BjrB,KAAK0e,QAAUA,EAEgB,IAA3B1e,KAAK4E,KAAKw2B,MAAMn7B,OAGlB,OAFAD,KAAKgrC,+BACAhrC,KAAKirC,wBAAwBjrC,KAAKkrC,aAAaxsB,IAItD1e,KAAK0e,QAAQiR,OACb3vB,KAAKmrC,OACLnrC,KAAKorC,eACLprC,KAAK+qC,cACL/qC,KAAKqrC,iBACLrrC,KAAKsrC,kBACLtrC,KAAKurC,0BACLvrC,KAAK0e,QAAQmR,UACR7vB,KAAKirC,wBAAwBjrC,KAAKkrC,aAAaxsB,EACtD,CAEA8sB,UAAAA,CAAW9sB,GACT1e,KAAK4E,KAAO5E,KAAK0B,MAAMiI,QACvB3J,KAAKirB,WAAajrB,KAAK0B,MAAMupB,WAC7BjrB,KAAK0e,QAAUA,EAEf1e,KAAKyrC,cACLzrC,KAAK6qC,UAAUhjB,OAAOnJ,EACxB,CAEAwsB,YAAAA,CAAaxsB,GACX,GAAI1e,KAAK0rC,WAAY,CACnB,MAAM,cAAExQ,GAAkBl7B,KAAKqe,yBAI/B,GAHAK,EAAQO,UAAUic,EAAczU,KAAKjf,MAAO,GAC5CxH,KAAK0rC,WAAW7jB,OAAOnJ,IAEnBitB,EAAAA,EAAAA,IAAqB3rC,KAAKqR,6BAAoD,iBAArBrR,KAAK4E,KAAKgnC,OAA2B,CAChG,MAAM,OAAErtB,GAAW2c,EAAc2Q,QACjC,IAAIrmB,EAAAA,EACF,CACEK,KAAM,MACNrH,EAAG0c,EAAc5U,IAAIslB,OAAOE,OAAOrlB,KACnChI,EAAGyc,EAAc5U,IAAIslB,OAAOE,OAAOxlB,IAAOylB,EAAAA,GAAUrI,IAAMsI,EAAAA,GAAOtI,IACjE5d,KAAM,CAAEtW,KAAMu8B,EAAAA,GAAUrI,KACxBzd,UAAW1H,EAAOsH,KAClBO,aAAc8U,EAAc5U,IAAI2lB,UAElCjsC,KAAK+G,WACL8gB,OAAOnJ,EACX,CAEAA,EAAQO,WAAWic,EAAczU,KAAKjf,MAAO,EAC/C,CACF,CAEA0kC,eAAAA,CAAgBxtB,GACd,MAAM,cAAEwc,GAAkBl7B,KAAKqe,0BACzB,OAAEE,GAAW2c,EAAc2Q,QAC3BliC,EAAQ3J,KAAK0B,MAAMiI,QACnB8U,GAAKze,KAAKyH,OAASzH,KAAKmsC,SAASC,QAAQ,GAAK,GAAK,EAEzD,OAAO,IAAI5mB,EAAAA,EACT,CACEK,KAAMlc,EAAMkJ,aAAeC,EAAAA,GAAWu5B,MAAQ,sBAAuBC,EAAAA,EAAAA,IAAkB3iC,EAAM8K,WAC7F+J,EAAG0c,EAAczU,KAAKhS,UAAUq3B,OAAOrlB,KACvChI,EAAGyc,EAAc5U,IAAI7e,OAASgX,GAAKyc,EAAczU,KAAKhS,UAAUq3B,OAAOxlB,KAAO,GAC9ElH,OAAQ,GACR0G,KAAMN,EAAAA,EAAK0e,2BAA2B,OAAQhJ,EAAczU,KAAKhS,UAAUqR,MAC3EG,UAAW1H,EAAOguB,cAClBpmB,UAAWyQ,EAAAA,GAAUC,OACrBzQ,aAAcsQ,EAAAA,GAAauN,YAE7BjkC,KAAK+G,WACL8gB,OAAOnJ,EACX,CAEAoJ,UAAAA,CAAWpJ,GACT,MAAM,cAAEwc,EAAa,iBAAEsR,GAAqBxsC,KAAKqe,0BAC3C,OAAEE,GAAW2c,EAAc2Q,QA+BjC,GA9BAntB,EAAQiR,OACRjR,EAAQO,UAAUic,EAAczU,KAAKjf,MAAO,IAEvCmkC,EAAAA,EAAAA,IAAqB3rC,KAAKqR,4BAa7BrR,KAAK0rC,WAAa,IAAIlmB,EAAAA,EACpB,CACEK,KAAM7lB,KAAK4E,KAAKxB,MAAQpD,KAAK4E,KAAKgnC,OAClCptB,EAAG0c,EAAc5U,IAAIslB,OAAOE,OAAOrlB,KACnChI,EAAGyc,EAAc5U,IAAIslB,OAAOE,OAAOxlB,IACnCR,KAAM,CAAEtW,KAAMu8B,EAAAA,GAAUU,EAAGt2B,MAAO,QAClC8P,UAAW1H,EAAOsH,MAEpB7lB,KAAK+G,WApBP/G,KAAK0rC,WAAa,IAAIlmB,EAAAA,EACpB,CACEK,KAAM7lB,KAAK4E,KAAKxB,MAAQpD,KAAK4E,KAAKgnC,OAClCptB,EAAG0c,EAAc5U,IAAIslB,OAAOE,OAAOrlB,KACnChI,EAAGyc,EAAc5U,IAAIslB,OAAOE,OAAOxlB,IACnCR,KAAMN,EAAAA,EAAK0e,2BAA2B,OAAQhJ,EAAc5U,IAAIslB,OAAO9lB,MACvEM,aAAc8U,EAAc5U,IAAI2lB,SAChChmB,UAAW1H,EAAOsH,MAEpB7lB,KAAK+G,WAcT/G,KAAKwpC,YAAcxpC,KAAK0rC,WAAW/a,QAAQjS,GAGvC1e,KAAKqR,6BAA+Bq7B,EAAAA,GAA2BC,UAAW,CAC5E,IAAIjd,EAAU,EACT8c,IACH9c,EAAU1vB,KAAK2pC,cAAgB,GAAK,GAEtC,IAAInkB,EAAAA,EACF,CACEK,KAAM,eACNrH,EAAGxe,KAAKwH,MAAQ0zB,EAAc3U,MAAM/e,MAAQ,EAC5CiX,EAAG,EAAIiR,EACP5J,KAAM,CAAEtW,KAAMg9B,EAAmBT,EAAAA,GAAUa,GAAKb,EAAAA,GAAUc,GAC1D1mB,UAAWyQ,EAAAA,GAAUrQ,MACrBH,aAAcsQ,EAAAA,GAAapQ,IAC3BL,UAAWumB,EAAmB,qBAAuBnD,IAAAA,OAAsBtqC,MAE7EiB,KAAK+G,WACL8gB,OAAOnJ,EACX,CAEK1e,KAAKirC,yBACRjrC,KAAK8sC,aAAa,CAAEpuB,YACf1e,KAAK0pC,SAAS,IACjB1pC,KAAK+sC,QAAQ,CAAEruB,UAASsuB,cAAc,IAExChtC,KAAK+sC,QAAQ,CAAEruB,aAGjBA,EAAQmR,UACH7vB,KAAKirC,yBAA2BU,EAAAA,EAAAA,IAAqB3rC,KAAKqR,6BAC7DrR,KAAKksC,gBAAgBxtB,EAEzB,CAEAquB,OAAAA,CAAO1S,GAoBJ,IApBK,QACN3b,EAAO,aACPsuB,GAAe,EAAI,KACnBpoC,EAAI,KACJ4iC,EAAI,WACJC,EAAa,KAAI,iBACjBwF,EAAmB,MAcpB5S,EACC,IAAKr6B,KAAK4E,KAAKsoC,SAAU,OAGzB,MAAMA,EAAY,GAAExE,EAAAA,MAAW1oC,KAAK4E,KAAKsoC,SAAW,KAAO,IAAO,MAAMltC,KAAK4E,KAAKsoC,SAAW,OACzFvB,EAAAA,EAAAA,IAAqB3rC,KAAKqR,4BAC5BrR,KAAKmtC,WAAW,CACdzuB,UACA8oB,KAAM0F,EACNE,mBAAmB,EACnBC,cAAc,EACdL,iBAEOpoC,GAAQ4iC,EACjBxnC,KAAKmtC,WAAW,CACdzuB,UACA8oB,KAAMD,EAAc,CAAEC,OAAM/yB,UAAWzU,KAAK4E,KAAK6P,YACjD64B,KAAM1oC,EAAK0oC,KACXnxB,KAAMvX,EAAKuX,KACX4sB,IAAKnkC,EAAKmkC,IACV3N,MAAOx2B,EAAKw2B,MACZe,QAAQU,EAAAA,EAAAA,IAA8B/Y,OAAOlf,EAAKu3B,SAClD6Q,eACAC,qBAEsB,OAAfxF,EACTznC,KAAKmtC,WAAW,CACdzuB,UACA8oB,KAAMC,EACN6F,KAAM,KACNnxB,KAAM,KACN4sB,IAAK,KACL3N,MAAO,KACPe,OAAQ,KACR6Q,iBAGFhtC,KAAKmtC,WAAW,CACdzuB,UACA8oB,KAAM0F,EACNK,UACEzpB,OAAO0pB,SAASxtC,KAAK4E,KAAK6oC,aAAeztC,KAAK4E,KAAK6oC,aAAeztC,KAAK4E,KAAKq2B,UACxEj7B,KAAK0tC,UAAU1tC,KAAK4E,KAAK6oC,iBACzBplC,EACN8zB,QAAQU,EAAAA,EAAAA,IAA8B78B,KAAK4E,KAAK+oC,YAChDN,cAAc,EACd5pC,KAAMsmC,EAAAA,GAAAA,sBAA4B/pC,KAAK4E,KAAK4iC,KAAKznC,QAAS6tC,mBAAmB,QAAS,CACpFC,KAAM,UACNC,OAAQ,YAEVd,kBACGhtC,KAAK+tC,sBAGd,CAEAA,kBAAAA,GACE,MAAO,CACLT,KAAMttC,KAAK0tC,UAAU1tC,KAAK4E,KAAKopC,UAC/B7xB,KAAMnc,KAAK0tC,UAAU1tC,KAAK4E,KAAKqpC,UAC/BlF,IAAK/oC,KAAK0tC,UAAU1tC,KAAK4E,KAAKspC,SAC9B9S,MAAOp7B,KAAK0tC,UAAU1tC,KAAK4E,KAAKq2B,WAEpC,CAEAqP,oBAAAA,CAAqB5rB,GACd1e,KAAKirC,uBAE4B,IAA3BjrC,KAAK4E,KAAKw2B,MAAMn7B,QACzBD,KAAKmuC,+BAA+BzvB,GAFpC1e,KAAKouC,8BAA8B1vB,EAIvC,CAEA0vB,6BAAAA,CAA8B1vB,GAC5B,MAAM,cAAEwc,GAAkBl7B,KAAKqe,yBACzBwH,EAAO,IAAIL,EAAAA,EACf,CACEhH,EAAG0c,EAAczU,KAAK4nB,aAAavC,OAAOrlB,KAC1ChI,EAAGyc,EAAc5U,IAAI7e,OAASyzB,EAAczU,KAAK4nB,aAAavC,OAAOxlB,IACrER,KAAMN,EAAAA,EAAK0e,2BAA2B,OAAQhJ,EAAczU,KAAK4nB,aAAavoB,MAC9EM,aAAcsQ,EAAAA,GAAapQ,KAE7BtmB,KAAK+G,WAEP,IAAK,MAAMkR,KAAWjY,KAAKgY,SACpBC,EAAQq2B,2BAGbzoB,EACG1G,IAAI,CACH0G,KAAM5N,EAAQ1T,WACdka,EAAGoH,EAAKqN,IAAI,KAAQgI,EAAczU,KAAK4nB,aAAaE,aACpDtoB,UAAWhO,EAAQu2B,kBAEpB3mB,OAAOnJ,EAEd,CAEA+vB,kBAAAA,GACE,OAAIzuC,KAAK4E,KAAKiO,aAAeC,EAAAA,GAAW47B,QAAU1uC,KAAK4E,KAAKq2B,WAAa,KAChE,EAEF,CACT,CAEA0T,sBAAAA,CAAsBrU,GAA6F,IAA5F,UAAEW,EAAS,kBAAE2T,GAA6EtU,EAC/G,MAAiC,iBAAtBsU,GAAkC5uC,KAAK0B,MAAMyV,QAAUE,EAAAA,GAAUG,WAClE,GAAExX,KAAKgkB,OAAM6qB,EAAAA,EAAAA,IAAuB,CAAE3R,OAAQjC,EAAW6T,KAAMF,IAAsB,MAExF5uC,KAAKgkB,MAAMiX,EACpB,CAEAkP,WAAAA,CACEzrB,GAGA,IAFA,UAAEuc,GAAsD75B,UAAAnB,OAAA,QAAAoI,IAAAjH,UAAA,GAAAA,UAAA,GAAGpB,KAAK4E,KAChEy2B,IAAYj6B,UAAAnB,OAAA,QAAAoI,IAAAjH,UAAA,KAAAA,UAAA,GAEZ,MAAM,cAAE85B,GAAkBl7B,KAAKqe,0BACzB,OAAEE,GAAW2c,EAAc2Q,QACjC,IAAIptB,EAAGswB,EAAWC,EAAWC,EAC7B,MAAMhwB,GAAYiwB,EAAAA,EAAAA,IAAa,CAAExwB,UAAS+Q,QAASyL,EAAczU,KAAKjf,MAAOkoB,QAASwL,EAAc5U,IAAI7e,SACxGwX,EAAUkwB,KACV,MAAMC,EAAY/vB,KAAK+E,MAAMpkB,KAAK+G,UAAUU,OAAS,IAC/C4nC,EAASrvC,KAAKsvC,aACd,kBAAEV,GAAsBS,EACxB5nC,EAASzH,KAAKyH,OACpB,IACI8nC,EADAC,EAAY,EAGhB,OAAQxvC,KAAK0B,MAAMyV,OACjB,KAAKE,EAAAA,GAAUG,WAAY,CACzB,IAAKo3B,EAAmB,OAExB,MAAMa,EAAazvC,KAAK+G,UAAU0oC,YAC5B,IAAE/qB,EAAG,IAAEG,GAAQ4qB,GAAcJ,EAEnCrvC,KAAK0B,MAAMguC,gBAAgB,gBAAiBd,GAE5C,MAAMe,GAAUd,EAAAA,EAAAA,IAAuB,CAAE3R,OAAQxY,EAAKoqB,KAAMF,IACtDgB,GAAUf,EAAAA,EAAAA,IAAuB,CAAE3R,OAAQrY,EAAKiqB,KAAMF,IAG5DI,EADkBa,EAAAA,MAAiBzD,MAAM,CAAC,EAAGpsC,KAAKyH,SAAS2b,OAAO,CAACwsB,EAASD,IAAUG,KAAK,IACrEC,MAAM1wB,KAAKqF,IAAI0qB,EAAW,IAChDL,EAAYC,EAAUthC,KAAKsiC,IAASC,EAAAA,EAAAA,IAAuB,CAAE/S,OAAQ8S,EAAMlB,KAAMF,MACjFK,EAAiBjvC,KAAK2uC,uBAAuB,CAAE1T,YAAW2T,sBAC1D,KACF,CACA,KAAKv3B,EAAAA,GAAUK,YAAa,CAC1B,IAAKk3B,EAAmB,OAExB,MAAMa,EAAazvC,KAAK+G,UAAU0oC,YAC5B,IAAE/qB,EAAG,IAAEG,GAAQ4qB,GAAcJ,EACnCN,EAAY,CAAC1vB,KAAK+E,MAAMM,IACxB,MAAMwrB,EAAW,GAEXC,EAAgB,GACtB,GAAIzrB,EAAM,EAAG,CACX,IAAI0rB,EAAuB/wB,KAAKqF,IAAI,EAAGG,GACvC,KAAO7kB,KAAK+G,UAAUoQ,MAAMsH,EAAE2xB,GAAwBF,EAAWlwC,KAAK+G,UAAUoQ,MAAMsH,EAAEiG,IAAM,CAC5F,MAAMsrB,EAAOhwC,KAAK+G,UAAUoQ,MAAMsH,EAAEyN,OAAOlsB,KAAK+G,UAAUoQ,MAAMsH,EAAE2xB,GAAwBF,GAC1F,GAAIE,IAAyBJ,EAC3B,MAEF,MAAM5D,EAAQyD,EAAAA,KAASO,GAAuBJ,EAAM,GACpDI,GAAwBhE,EAAMA,EAAMnsC,OAAS,GAC7CkwC,EAAcE,QAAQD,EACxB,CACF,CAEA,MAAME,EAAgB,GAItB,IAHIzrB,EAAM,GACRyrB,EAAc/uC,KAAK8d,KAAKwF,IAAI7kB,KAAK+G,UAAUoQ,MAAMsH,EAAEyN,OAAOlsB,KAAK+G,UAAUoQ,MAAMsH,EAAEiG,GAAOwrB,GAAW,IAE9FlwC,KAAK+G,UAAUoQ,MAAMsH,EAAE6xB,EAAcA,EAAcrwC,OAAS,IAAMiwC,EAAW,GAAG,CACrF,MAAMK,EAAeD,EAAcA,EAAcrwC,OAAS,GACpDuwC,EAAiBxwC,KAAK+G,UAAUoQ,MAAMsH,EAAE6xB,EAAcA,EAAcrwC,OAAS,IAC7E+vC,EAAOhwC,KAAK+G,UAAUoQ,MAAMsH,EAAEyN,OAAOskB,EAAiBN,GAC5D,GAAIK,IAAiBP,EACnB,MAGF,MAAM5D,EAAQyD,EAAAA,IAAQU,EAAcP,EAAM,GAC1CM,EAAc/uC,KAAK6qC,EAAMA,EAAMnsC,OAAS,GAC1C,CACA8uC,EAAY,IAAIoB,KAAkBG,GAClCtB,EAAYD,EACZE,EAAiBjvC,KAAK2uC,uBAAuB,CAAE1T,cAC/C,KACF,CACA,QAEE8T,EAAY/uC,KAAK+G,UAAUoQ,MAAMsH,EAAEsxB,MAAM1wB,KAAKqF,IAAI0qB,EAAW,IAC7DJ,EAAYD,EACZE,EAAiBjvC,KAAK2uC,uBAAuB,CAAE1T,cAG/C+T,EAAU/uC,QAAU,IACtBuvC,EAAYnwB,KAAKQ,IAAImvB,EAAU,GAAKA,EAAU,MAG9CQ,EAAY,KACX7D,EAAAA,EAAAA,IAAqB3rC,KAAKqR,6BAA+BgO,KAAK2E,MAAMgrB,EAAU,IAAIzqC,WAAWtE,OAAS,KAEvGsvC,EAAa,GAGf,MAAMkB,EAAeA,CAACC,EAAa7sB,IACzB7jB,KAAK0B,MAAMyV,QACZE,EAAAA,GAAUG,WACL,GAAEk5B,KAEH1wC,KAAKgkB,MAAM0sB,EAAK7sB,GAIvB8sB,EAAY,IAAInrB,EAAAA,EACpB,CACEhH,EAAGxe,KAAKwH,MAAQxH,KAAKyuC,qBAAuBvT,EAAc3U,MAAMqqB,KAAK9E,OAAOrlB,KAC5EX,KAAMN,EAAAA,EAAK0e,2BAA2B,OAAQhJ,EAAc3U,MAAMqqB,KAAK9qB,MACvEG,UAAW1H,EAAOsH,KAClBO,aAAcsQ,EAAAA,GAAaC,QAE7B32B,KAAK+G,WAGP,IAAI8pC,EAAY7wC,KAAK8wC,WACrB,MAAMC,EAAoBA,KACxBJ,EAAUxxB,IAAI,CACZ2G,KAAMN,EAAAA,EAAK0e,2BAA2B,OAAQhJ,EAAc3U,MAAMqqB,KAAK9qB,MACvEG,UAAW1H,EAAOsH,KAClBO,aAAcsQ,EAAAA,GAAaC,SAE7Bka,EAAY7wC,KAAK8wC,UAAU,EAE7B,IAAK,IAAI5uB,EAAI,EAAGA,EAAI6sB,EAAU9uC,OAAQiiB,IACpCzD,EAAIY,KAAK2E,MAAMhkB,KAAKoiB,GAAG2sB,EAAU7sB,KAC7BzD,EAAI,GAAKA,EAAIhX,IACjBopC,EAAU1xB,IAAI,CAAEpB,GAAIU,EAAGR,GAAIQ,IAC3BkyB,EAAUxxB,IAAI,CACZ0G,KAAM4qB,EAAazB,EAAU9sB,GAAIqtB,GACjC9wB,MAEEze,KAAK0B,MAAMyV,QAAUE,EAAAA,GAAUG,YAA+B,IAAjBw3B,EAAU9sB,IACzD2uB,EAAU1xB,IAAI,CAAEuc,YAAand,EAAOsH,OACpC8qB,EAAUxxB,IAAI,CACZ2G,KAAM,CAAEE,OAAQ,OAAQxW,KAAMmhC,EAAU5tC,MAAM+iB,KAAKtW,MACnDyW,UAAW1H,EAAOyyB,yBAEpBH,EAAUhpB,OAAOnJ,GACjBiyB,EAAU9oB,OAAOnJ,GACjBqyB,MAEAF,EAAUhpB,OAAOnJ,GACjBiyB,EAAU9oB,OAAOnJ,KAGrBO,EAAUgyB,OAEN5V,GACFr7B,KAAKkxC,iBAAiB,CAAExyB,UAASyyB,YAAa9xB,KAAK2E,MAAMhkB,KAAKoiB,GAAG6Y,IAAansB,MAAOmgC,GAazF,CAEAmC,gCAAAA,GACE,OAAOC,EAAAA,EAAAA,IACL,KACKC,EAAAA,EAAAA,IAAiBtxC,KAAKqe,yBAAyB6c,cAAc2Q,QAAQttB,OAAOgzB,mBAC/EvO,EAAG,IAEL,MAEJ,CAEAwO,iCAAAA,CAAiCjX,GAM9B,IAN+B,eAChCkX,EAAc,oBACdC,GAIDnX,EACC,MAAM,cAAEW,GAAkBl7B,KAAKqe,0BACzB,WAAE6H,GAAegV,EAAc3U,MAAMqqB,KAAK9qB,KAC1CO,EAAUb,EAAAA,EAAK0e,2BAA2B,UAAWhJ,EAAc3U,MAAMqqB,KAAK9qB,KAAKO,SAEnFsrB,EAAYtyB,KAAKoO,KAAKgkB,EAAiBC,IAAwB,EAC/Dnb,GAAUrQ,GAAc0rB,EAAAA,GAAYhqB,IAAMvB,EAAQC,KAAOqB,EAAAA,GAAQ+b,MAAQrd,EAAQG,QAAUmB,EAAAA,GAAQ+b,KACnGmO,EAAyBxyB,KAAK2E,MAAMhkB,KAAKoiB,GAAGqvB,IAC5CK,EAA8BzyB,KAAK2E,MAAMhkB,KAAKoiB,GAAGsvB,IACjDK,EAAYF,EAAyBtb,EAASob,EAEpD,OAAOtyB,KAAKQ,IAAIiyB,EAA8BD,GAA0Btb,EACpEub,EACAC,CACN,CAEAb,gBAAAA,CAAgBc,GAUb,IAVc,QACftzB,EAAO,YACPyyB,EAAW,MACXriC,EAAK,WACL4X,GAMDsrB,EACC,MAAM,cAAE9W,GAAkBl7B,KAAKqe,yBACzBY,GAAYiwB,EAAAA,EAAAA,IAAa,CAAExwB,UAAS+Q,QAASyL,EAAczU,KAAKjf,MAAOkoB,QAASwL,EAAc5U,IAAI7e,UAClG,OAAE8W,GAAW2c,EAAc2Q,SAC3B,KAAEr8B,EAAI,WAAE0W,GAAegV,EAAc3U,MAAMqqB,KAAK9qB,KAChDO,EAAUb,EAAAA,EAAK0e,2BAA2B,UAAWhJ,EAAc3U,MAAMqqB,KAAK9qB,KAAKO,SAEzFpH,EAAUkwB,KACV,IAAI3pB,EAAAA,EACF,CACEK,KAAM/W,EACN0P,EAAGxe,KAAKwH,MAAQxH,KAAKyuC,qBAAuBpoB,EAAQI,KAAOyU,EAAc3U,MAAMqqB,KAAK9E,OAAOrlB,KAC3FhI,EAAG0yB,EACHrrB,KAAMN,EAAAA,EAAK0e,2BAA2B,OAAQ,CAAE10B,OAAM2G,MAAO,SAC7D+P,aACAG,UACAD,aAAcsQ,EAAAA,GAAaC,OAC3B1Q,UACEjmB,KAAKqR,6BAA+Bq7B,EAAAA,GAA2BC,UAAY,QAAUpuB,EAAO0zB,YAC9FvrB,WAAYA,GAAcnI,EAAOgzB,mBAEnCvxC,KAAK+G,WACL8gB,OAAOnJ,GACTO,EAAUgyB,MACZ,CAEAxF,WAAAA,GACE,MAAM,WAAExgB,EAAU,MAAEzjB,GAAUxH,MACxB,cAAEk7B,GAAkBl7B,KAAKqe,0BACzB,OAAEE,GAAW2c,EAAc2Q,QAEjC7rC,KAAK0e,QAAQiR,OAEiB,IAA5B3vB,KAAK4E,KAAKstC,gBACTvG,EAAAA,EAAAA,IAAqB3rC,KAAKqR,6BAC3BrR,KAAK4E,KAAKiO,aAAeC,EAAAA,GAAWq/B,iBAEpCnyC,KAAKmrC,MAAK,GAEZnrC,KAAK0e,QAAQO,UAAUic,EAAczU,KAAKjf,MAAO0zB,EAAc5U,IAAI7e,QACnE,MAAM2qC,EAAe,IAAI5sB,EAAAA,EACvB,CACE/G,EAAGze,KAAKyH,OAASyzB,EAAc1U,OAAOoqB,KAAK9E,OAAOxlB,IAClDR,KAAMN,EAAAA,EAAK0e,2BAA2B,OAAQ,CAAE10B,KAAM0rB,EAAc1U,OAAOoqB,KAAK9qB,KAAKtW,OACrFyW,UAAW1H,EAAOsH,KAClBO,aAAcsQ,EAAAA,GAAapQ,IAC3BH,UAAWyQ,EAAAA,GAAUC,QAEvB72B,KAAK+G,WAQDsrC,EAAgBhzB,KAAKwF,KACzBytB,EAAAA,EAAAA,IAA2B,CACzB3oC,MAAO3J,KAAK4E,KACZmC,UAAW/G,KAAK+G,UAChBkkB,eACChpB,MAAQ,EACX,GAGIswC,EAAclzB,KAAKqF,KACvB4tB,EAAAA,EAAAA,IAA2B,CACzB3oC,MAAO3J,KAAK4E,KACZmC,UAAW/G,KAAK+G,UAChBkkB,aACAunB,WAAYhrC,IACXvF,MAAQ,EACXjC,KAAK4E,KAAKw2B,MAAMn7B,OAAS,GAG3B,OAAQD,KAAK4E,KAAK6P,WAChB,KAAKuzB,EAAAA,GAAUC,GACf,KAAKD,EAAAA,GAAUE,GACf,KAAKF,EAAAA,GAAUG,GACf,KAAKH,EAAAA,GAAUI,GACTpoC,KAAK4E,KAAKiO,aAAeC,EAAAA,GAAWC,MAEpC/S,KAAK2V,OAASU,EAAAA,GAAiBO,WAC/B5W,KAAKqR,6BAA+Bq7B,EAAAA,GAA2BC,WACvC,OAAxB3sC,KAAK4E,KAAK6P,UAEVzU,KAAKyyC,iBAAiB,CAAEL,eAAcC,gBAAeE,gBAErDvyC,KAAK0yC,oBAAoBN,GAG3BpyC,KAAK2yC,2BAA2B,CAAEP,eAAcC,gBAAeE,gBAEjE,MACF,KAAKvK,EAAAA,GAAUK,KACTsD,EAAAA,EAAAA,IAAqB3rC,KAAKqR,4BAC5BrR,KAAK0yC,oBAAoBN,GAEzBpyC,KAAKyyC,iBAAiB,CAAEL,eAAcC,gBAAeE,gBAEvD,MACF,KAAKvK,EAAAA,GAAUM,IACf,KAAKN,EAAAA,GAAUO,IACf,KAAKP,EAAAA,GAAUpoB,EACf,KAAKooB,EAAAA,GAAUQ,GACf,KAAKR,EAAAA,GAAUS,GACbzoC,KAAKyyC,iBAAiB,CAAEL,eAAcC,gBAAeE,gBACrD,MACF,KAAKvK,EAAAA,GAAUlc,EACb9rB,KAAK4yC,iBAAiB,CAAER,eAAcC,gBAAeE,gBACrD,MACF,KAAKvK,EAAAA,GAAUW,EACb3oC,KAAK6yC,kBAAkB,CAAET,eAAcC,gBAAeE,gBACtD,MACF,KAAKvK,EAAAA,GAAUX,EACbrnC,KAAK8yC,mBAAmB,CAAEV,eAAcC,gBAAeE,gBAK3DvyC,KAAK0e,QAAQmR,SACf,CAEAkjB,eAAAA,CAAgBv0B,GAAuB,IAAZw0B,EAAM5xC,UAAAnB,OAAA,QAAAoI,IAAAjH,UAAA,GAAAA,UAAA,GAAG,EAClC,OAAOod,GAAK,EAAIw0B,GAAUx0B,GAAKxe,KAAKwH,MAAQwrC,CAC9C,CAEAC,iBAAAA,CAAiBC,GAQd,IARe,OAChBC,EAAM,aACNf,EAAY,gBACZgB,EAAkB,GAKnBF,EACC,MAAMG,EAA6B,GAC7BC,EAA2D,GACjEH,EAAOI,UAAUhrC,SAASuG,IACxBsjC,EAAajzB,IAAI,CAAE0G,KAAM/W,EAAM+W,OAC/B,MAAMqC,EAAY7I,KAAK+E,MAAMguB,EAAazhB,QAAQ3wB,KAAK0e,UACjD80B,EAAW,IAAK1kC,EAAOoZ,aACzBpZ,EAAM2kC,YACRJ,EAAahD,QAAQmD,GAErBH,EAAa9xC,KAAKiyC,EACpB,IAGFH,EAAa9qC,SAAQmrC,IAA4B,IAA3B,EAAEl1B,EAAC,KAAEqH,EAAI,UAAEqC,GAAWwrB,EAC1C,IAAK1zC,KAAK+yC,gBAAgBv0B,EAAG40B,GAC3B,OAEF,MAAMO,EAAkBzrB,EAAY,EAC9B0rB,EAAep1B,EAAIm1B,EAAkBP,EACrCS,EAAgB7zC,KAAKwH,OAASgX,EAAIm1B,GAAmBP,EAC3D,IAAIU,EAASt1B,EACTo1B,EAAe,EACjBE,EAASz0B,KAAK2E,MAAMxF,EAAIo1B,GACfC,EAAgB,IACzBC,EAASz0B,KAAK2E,MAAMxF,EAAIq1B,IAhyBPzrC,KAAA,IAAC,EACxBoW,EAAC,UACD0J,EAAS,oBACTorB,GAKDlrC,EAAA,OACCkrC,EAAoBnrC,MAAK2F,IAAkB,IAAjB,KAAEinB,EAAI,GAAEC,GAAIlnB,EACpC,MAAM2W,EAAOjG,EAAI0J,EAAY,EACvBtD,EAAOpG,EAAI0J,EAAY,EAC7B,OAAQ6M,EAAOnQ,GAAQA,EAAOoQ,GAAQD,EAAOtQ,GAAQA,EAAOuQ,CAAG,GAC/D,EAqxBM+e,CAAiB,CAAEv1B,EAAGs1B,EAAQ5rB,YAAWorB,0BAG7CA,EAAoB/xC,KAAK,CACvBwzB,KAAM+e,EAASH,EAAkB3H,EAAAA,GAAOa,EACxC7X,GAAI8e,EAASH,EAAkB3H,EAAAA,GAAOa,IAExCuF,EAAajzB,IAAI,CAAE0G,OAAMrH,EAAGs1B,IAC5B1B,EAAavqB,OAAO7nB,KAAK0e,SAAQ,GAErC,CAEAg0B,mBAAAA,CAAoBN,GAClB,MAAM4B,EAAWC,EAAAA,GAA0Bj0C,KAAK4E,KAAK6P,WAC/Cy/B,KAAqBl0C,KAAK4E,KAAKuvC,mBAAqB,IAC1D,IAAIC,EAAgB,GAAK/0B,KAAKg1B,KAAKr0C,KAAK4E,KAAK0vC,yBAA2B,IACxE,MAAMnB,EAAS,IACXxH,EAAAA,EAAAA,IAAqB3rC,KAAKqR,8BAC5B+iC,EAAgB,IAGlB,MAAMG,EAAQv0C,KAAKw0C,WACbC,GAAWC,EAAAA,EAAAA,IAAsB,CACrCC,WAAY30C,KAAK0B,MAAMizC,WACvB3jC,YAAahR,KAAK0B,MAAMkyB,iBAGpBghB,EAAc50C,KAAK4E,KAAKiwC,iBACxBzH,GAAoBzB,EAAAA,EAAAA,IAAqB3rC,KAAKqR,4BAC9C+hC,EAAkBhG,EAxxBW,GAwxB0C,EAC7E,IAAK,MAAMtF,KAAO8M,EAAa,CAC7B,MAAME,EAAWF,EAAY9M,GACvBN,GAAOuN,EAAAA,EAAAA,IAAmBjN,GAEhC,IAAK,IAAI5lB,EAAIgyB,EAAiBhyB,GAAKkyB,EAAelyB,IAAK,CACrD,IAAI1D,GACI,GAAJ0D,EAASliB,KAAK4E,KAAKuvC,oBAAsBH,EAAYS,EACvDK,GAAY90C,KAAK4E,KAAKowC,kBAAoBhB,GAAYS,EACtDz0C,KAAKirB,WACP,IAAKjrB,KAAK+yC,gBAAgBv0B,EAAG40B,GAC3B,SAEF,IAAI6B,EAAW51B,KAAK2E,MAAMxF,GAE1B,GAAI0D,IAAMgyB,EAAiB,CACzB,GAAI9G,EAAmB,CACrB6H,EAAW51B,KAAK2E,MAAMxF,EAAI,EAAK,GAAKw1B,EAAYS,GAEhDF,EACGp1B,IAAI,CACHrB,GAAIm3B,EACJj3B,GAAIi3B,IAELptB,OAAO7nB,KAAK0e,SACf,QACF,CACyC,IAArC1e,KAAK4E,KAAKswC,yBAEZ12B,GAAM,GAAKw1B,EAAYS,GAEzBQ,EAAW51B,KAAK2E,MAAMxF,GACtB+1B,EAAMp1B,IAAI,CAAErB,GAAIm3B,EAAUj3B,GAAIi3B,IAAYptB,OAAO7nB,KAAK0e,SACtDy0B,EAAO5xC,KAAK,CACVkyC,aAAa,EACb5tB,KAAM6iB,EAAAA,GAAOlB,EAAKG,YAAc,IAAMH,EAAKO,UAAUxjC,WAAWpE,QAAQ,MACxEqe,EAAGy2B,GAEP,MACEV,EAAMp1B,IAAI,CAAErB,GAAIm3B,EAAUj3B,GAAIi3B,IAAYptB,OAAO7nB,KAAK0e,SACtDy0B,EAAO5xC,KAAK,CACVskB,MAAQ3D,EAAI,IAAM,GAAM,GAAKA,EAAI,GAAK,KAAO,MAC7C1D,EAAGy2B,GAGT,CACF,CACAj1C,KAAKizC,kBAAkB,CAAEE,SAAQf,eAAcgB,mBACjD,CAEAT,0BAAAA,CAA0BwC,GAAkE,IAAjE,aAAE/C,EAAY,cAAEC,EAAa,YAAEE,GAAgC4C,EACpFC,EAAU,GACVC,EAAYC,IAEhB,MAAMnC,EAAS,GACToB,EAAQv0C,KAAKw0C,WACnB,IAAK,IAAItyB,EAAImwB,EAAenwB,GAAKqwB,EAAarwB,IAAK,CACjD,MAAMslB,EAAOuC,EAAAA,GAAAA,sBAA4B/pC,KAAK4E,KAAK4iC,KAAKtlB,IAClD4lB,EAAMN,EAAKO,UAAY,IAAMP,EAAKG,WAClC4N,EAAQ/N,EAAK1iC,WACb0Z,EAAIa,KAAK2E,MAAMhkB,KAAKmiB,GAAGD,GAAKliB,KAAKirB,YAEvC,GAAI6c,IAAQsN,EAAS,CAGnB,GAFAA,EAAUtN,EACVuN,EAAYE,GACPv1C,KAAK+yC,gBAAgBv0B,GACxB,SAEF+1B,EAAMp1B,IAAI,CAAErB,GAAIU,EAAGR,GAAIQ,IAAKqJ,OAAO7nB,KAAK0e,SACxCy0B,EAAO5xC,KAAK,CACVid,IACAqH,KAAM6iB,EAAAA,GAAOlB,EAAKG,YAAc,IAAMH,EAAKO,UAAUxjC,WAAWpE,QAAQ,OAE5E,MAAO,GAAIo1C,EAAQ,GAAM,GAAKA,IAAUF,EAAW,CAEjD,GADAA,EAAYE,GACPv1C,KAAK+yC,gBAAgBv0B,GACxB,SAEF+1B,EAAMp1B,IAAI,CAAErB,GAAIU,EAAGR,GAAIQ,IAAKqJ,OAAO7nB,KAAK0e,SACxCy0B,EAAO5xC,KAAK,CAAEid,IAAGqH,MAAQ0vB,EAAQ,IAAM,GAAM,GAAKA,EAAQ,GAAK,KAAO,OACxE,CACF,CACAv1C,KAAKizC,kBAAkB,CAAEE,SAAQf,gBACnC,CAEAK,gBAAAA,CAAgB+C,GAAkE,IAAjE,aAAEpD,EAAY,cAAEC,EAAa,YAAEE,GAAgCiD,EAC1EJ,EAAU,GACV52B,EAAI,EAER,MAAM20B,EAAS,GACToB,EAAQv0C,KAAKw0C,WACnB,IAAK,IAAItyB,EAAImwB,EAAenwB,GAAKqwB,EAAarwB,IAAK,CACjD,MAAMslB,EAAOuC,EAAAA,GAAAA,sBAA4B/pC,KAAK4E,KAAK4iC,KAAKtlB,IAClD4lB,EAAMN,EAAKO,UAAY,IAAMP,EAAKG,WACxC,GAAIG,IAAQsN,EAAS,CAEnB,GADAA,EAAUtN,EACN9nC,KAAK4E,KAAKiO,aAAeC,EAAAA,GAAWC,MAAO,CAC7C,MACM0iC,GADcjO,EAAKziC,aAAiC,GAAlByiC,EAAK1iC,WACV9E,KAAK4E,KAAKuvC,oBAAsBn0C,KAAK4E,KAAKovC,SAC7Ex1B,EAAIa,KAAK2E,MAAMhkB,KAAK+G,UAAUoQ,MAAMqH,EAAExe,KAAK4E,KAAKw3B,SAASla,GAAKuzB,GAAez1C,KAAKirB,WACpF,MACEzM,EAAIa,KAAK2E,MAAMhkB,KAAKmiB,GAAGD,GAAKliB,KAAKirB,YAEnC,IAAKjrB,KAAK+yC,gBAAgBv0B,GACxB,SAEF+1B,EAAMp1B,IAAI,CAAErB,GAAIU,EAAGR,GAAIQ,IAAKqJ,OAAO7nB,KAAK0e,SACxCy0B,EAAO5xC,KAAK,CACVskB,KAAM6iB,EAAAA,GAAOlB,EAAKG,YAAc,IAAMH,EAAKO,UAAUxjC,WAAWpE,QAAQ,MACxEqe,KAEJ,CACF,CAGA,GAAIxe,KAAKqR,6BAA+Bq7B,EAAAA,GAA2BC,UAAW,CAC5E,MAAMO,EAAY,GAAExE,EAAAA,MAAW1oC,KAAK4E,KAAKsoC,SAAW,KAAO,IAAO,OAAOltC,KAAK4E,KAAKsoC,SAAW,KAC3F3oC,WACApE,QAAQ,QAEX,GAAIgzC,EAAOlzC,OAAS,GAAKkzC,EAAOA,EAAOlzC,OAAS,GAAG4lB,OAASqnB,EAAU,CAOpE1uB,GANkBxe,KAAK4E,KAAK8wC,gBACXhB,EAAAA,EAAAA,IAAsB,CACrCC,WAAY30C,KAAK0B,MAAMizC,WACvB3jC,YAAahR,KAAK0B,MAAMkyB,iBAI1Buf,EAAO5xC,KAAK,CACVskB,KAAMqnB,EACN1uB,MAEF+1B,EAAMp1B,IAAI,CAAErB,GAAIU,EAAGR,GAAIQ,IAAKqJ,OAAO7nB,KAAK0e,QAC1C,CACF,CAEA1e,KAAKizC,kBAAkB,CAAEE,SAAQf,gBACnC,CAEAQ,gBAAAA,CAAgB+C,GAAkE,IAAjE,aAAEvD,EAAY,cAAEC,EAAa,YAAEE,GAAgCoD,EAC1EC,EAAY,GAEhB,MAAMzC,EAAS,GACToB,EAAQv0C,KAAKw0C,WACnB,IAAK,IAAItyB,EAAImwB,EAAenwB,GAAKqwB,EAAarwB,IAAK,CACjD,MAAMslB,EAAOuC,EAAAA,GAAAA,sBAA4B/pC,KAAK4E,KAAK4iC,KAAKtlB,IAClDwlB,EAAQF,EAAKG,WAAa,IAAMH,EAAKK,cAC3C,GAAIH,IAAUkO,EAAW,CACvBA,EAAYlO,EACZ,MAAMlpB,EAAIa,KAAK2E,MAAMhkB,KAAKmiB,GAAGD,GAAKliB,KAAKirB,YACvC,IAAKjrB,KAAK+yC,gBAAgBv0B,GACxB,SAEF+1B,EAAMp1B,IAAI,CAAErB,GAAIU,EAAGR,GAAIQ,IAAKqJ,OAAO7nB,KAAK0e,SACxCy0B,EAAO5xC,KAAK,CACVkyC,YAAiC,IAApBjM,EAAKG,WAClB9hB,KAA0B,IAApB2hB,EAAKG,WAAmBH,EAAKK,cAActjC,WAAamkC,EAAAA,GAAOlB,EAAKG,YAC1EnpB,KAEJ,CACF,CACAxe,KAAKizC,kBAAkB,CAAEE,SAAQf,gBACnC,CAEAS,iBAAAA,CAAiBgD,GAAkE,IAAjE,aAAEzD,EAAY,cAAEC,EAAa,YAAEE,GAAgCsD,EAC3ED,EAAY,GAEhB,MAAMzC,EAAS,GACToB,EAAQv0C,KAAKw0C,YACb,OAAEj2B,GAAWve,KAAKqe,yBAAyB6c,cAAc2Q,QAC/D,IAAK,IAAI3pB,EAAImwB,EAAenwB,GAAKqwB,EAAarwB,IAAK,CACjD,MAAMslB,EAAOuC,EAAAA,GAAAA,sBAA4B/pC,KAAK4E,KAAK4iC,KAAKtlB,IAClDwlB,EAAQF,EAAKG,WAAa,IAAMH,EAAKK,cAC3C,GAAIH,IAAUkO,EAAW,CACvBA,EAAYlO,EACZ,MAAMlpB,EAAIa,KAAK2E,MAAMhkB,KAAKmiB,GAAGD,GAAKliB,KAAKirB,YACvC,IAAKjrB,KAAK+yC,gBAAgBv0B,GACxB,SAEEgpB,EAAKG,WAAa,GAAM,EAC1B4M,EAAMp1B,IAAI,CAAErB,GAAIU,EAAGR,GAAIQ,IAAKqJ,OAAO7nB,KAAK0e,SAExC,IAAI+c,EAAAA,EACF,CACE3d,GAAIU,EACJR,GAAIQ,EACJT,GAAI,EACJE,GAAIje,KAAKyH,OACTi0B,YAAand,EAAOu3B,cACpBna,WAAY,GAEd37B,KAAK+G,WACL8gB,OAAO7nB,KAAK0e,SAEhB,MAAMq3B,EAAkC,IAApBvO,EAAKG,WACzBwL,EAAO5xC,KAAK,CACVskB,KAAMkwB,EAAcvO,EAAKK,cAActjC,WAAWyxC,UAAU,GAAKtN,EAAAA,GAAOlB,EAAKG,YAAY,GACzF8L,YAAasC,EACbv3B,KAEJ,CACF,CACAxe,KAAKizC,kBAAkB,CAAEE,SAAQf,gBACnC,CAEAU,kBAAAA,CAAkBmD,GAAkE,IAAjE,aAAE7D,EAAY,cAAEC,EAAa,YAAEE,GAAgC0D,EAC5EC,EAAW,KAEf,MAAM/C,EAAS,GACToB,EAAQv0C,KAAKw0C,WACnB,IAAK,IAAItyB,EAAImwB,EAAenwB,GAAKqwB,EAAarwB,IAAK,CACjD,MAAMslB,EAAOuC,EAAAA,GAAAA,sBAA4B/pC,KAAK4E,KAAK4iC,KAAKtlB,IAClD0lB,EAAOJ,EAAKK,cACZsO,EAAgC,IAApB3O,EAAKG,WACvB,GAAIC,IAASsO,IAA+B,IAAlB/C,EAAOlzC,QAAgBk2C,GAAY,CAC3DD,EAAWtO,EACX,MAAMppB,EAAIa,KAAK2E,MAAMhkB,KAAKmiB,GAAGD,GAAKliB,KAAKirB,YACvC,IAAKjrB,KAAK+yC,gBAAgBv0B,GACxB,SAEF+1B,EAAMp1B,IAAI,CAAErB,GAAIU,EAAGR,GAAIQ,IAAKqJ,OAAO7nB,KAAK0e,SACxCy0B,EAAO5xC,KAAK,CACVskB,KAAM2hB,EAAKK,cAActjC,WACzBia,KAEJ,CACF,CACAxe,KAAKizC,kBAAkB,CAAEE,SAAQf,gBACnC,CAEA3H,sBAAAA,GACEzqC,KAAK8qC,2BACL9qC,KAAKqqC,aACLrqC,KAAKuJ,QAAQ,SACf,CAEAuhC,wBAAAA,GACE9qC,KAAK4pC,oBAAsB5pC,KAAK0B,MAAMkyB,eAAewiB,sBAAsBxgC,EAAAA,GAAcygC,IAC3F,CAEAC,cAAAA,CAAelS,EAAemS,EAAmBC,GAG3CpS,EAFa,IAGfA,EAHe,GAKjB,MAAM2L,EAAQ/vC,KAAKmsC,SAAS4D,MAAM3L,GAAOxsB,QAAQo4B,GAAkB,IAATA,IAC1D,OAAI5L,GALa,EAMR,CAAC2L,EAAMA,EAAM9vC,OAAS,IAK3B8vC,EAAM9vC,OAASu2C,EAAkC,GAApBzG,EAAM9vC,OAAS,GAASs2C,EAChDv2C,KAAKs2C,eAAelS,EAAQ,EAAGmS,EAAWC,GAE5CzG,CACT,CAEA0G,gBAAAA,CAAiB/3B,GACf,MAAM,cAAEwc,GAAkBl7B,KAAKqe,0BACzB,OAAEE,GAAW2c,EAAc2Q,QACjC,IAAIF,EAAAA,EAAAA,IAAqB3rC,KAAKqR,4BAA6B,CACzDqN,EAAQiR,OACR,MAAM+mB,EAAiBr3B,KAAKwF,IAAI,EAAGxF,KAAKqF,IAAI,EAAG1kB,KAAK4E,KAAK8xC,iBAEnDl4B,EAAI,GACJ4D,EAAM3D,GAAcyc,EAAc5U,IAAI7e,OAASzH,KAAKyH,OAASzH,KAAKyH,QAAU,GAAMgX,GAClFhX,EAASzH,KAAKyH,QAAU,GAAMivC,GAE9B5nC,EAAQ,IAAI0W,EAAAA,EAChB,CACEhH,EAAG,GACHsH,KAAM,CAAEtW,KAAM,GACdyW,UAAW1H,EAAOsH,KAClBO,aAAcsQ,EAAAA,GAAaC,OAC3BxQ,UAAWyQ,EAAAA,GAAUrQ,OAEvBvmB,KAAK+G,WAEP,IAAK,IAAImb,EAAI,GAAKA,GAAK,EAAGA,GAAK,GAAK,CAClC,MAAMzD,EAAIY,KAAK2E,MAAM5B,EAAGF,IACxBpT,EACGqQ,IAAI,CACH0G,KAAM3D,EAAEte,QAAQ,GAChB6a,EAAGA,IAEJoJ,OAAOnJ,GAEVA,EAAQS,IAAI,cAAe,sBAC3BT,EAAQQ,YACRR,EAAQkd,YAAY,CAAC,EAAG,IACxBld,EAAQO,UAAU,EAAG,IACrBP,EAAQa,OAAOf,EAAGC,GAClBC,EAAQc,OAAOhB,EAAI,EAAGC,GACtBC,EAAQO,UAAU,GAAI,IACtBP,EAAQe,QACV,CA0BA,OAxBAf,EAAQS,IAAI,YAAa,2BACzBT,EAAQS,IAAI,YAAa,GACzBT,EAAQS,IAAI,cAAeZ,EAAOo4B,MAClCj4B,EAAQkd,YAAY,IAEpBld,EAAQoe,SAASte,EAAGa,KAAK2E,MAAMkX,EAAc5U,IAAI7e,OAASzH,KAAKyH,OAASA,GAAS,EAAG4X,KAAK2E,MAAMvc,IAC/FiX,EAAQO,UAAU,GAAK,IACvBP,EAAQwkB,WAAW1kB,EAAG0c,EAAc5U,IAAI7e,OAAQ,EAAGzH,KAAKyH,QACxDiX,EAAQO,WAAW,IAAM,IAEzB,IAAIuG,EAAAA,EACF,CACEK,KAAM,mBACNrH,EAAG,GACHC,EAAGyc,EAAc5U,IAAI7e,OAASzH,KAAKyH,OAAS,EAC5Cqe,KAAM,CAAEtW,KAAMu8B,EAAAA,GAAUrI,KACxBxd,WAAY0rB,EAAAA,GAAYhF,GACxB3mB,UAAW1H,EAAOsH,KAClBO,aAAcsQ,EAAAA,GAAapQ,IAC3BH,UAAWyQ,EAAAA,GAAUrQ,OAEvBvmB,KAAK+G,WACL8gB,OAAOnJ,QACTA,EAAQmR,SAEV,CACA,MAAM+mB,EAAW52C,KAAKmsC,SAASC,QAAQ,GACjCyK,EAAqB3b,EAAczU,KAAKqwB,WAAWhxB,KAAKtW,KACxD4/B,EAAY/vB,KAAK+E,MAAMwyB,EAAWC,GAClC9G,EAAQ/vC,KAAKs2C,eAAelH,EAAWwH,EAAUC,GACjDE,EAAS/2C,KAAKmsC,SAAS6K,WAAW,EAAG,KACrCnxB,EAAO,IAAIL,EAAAA,EACf,CACEhH,EAAG0c,EAAczU,KAAKqwB,WAAWhL,OAAOrlB,KACxCX,KAAMN,EAAAA,EAAK0e,2BAA2B,OAAQ,CAAE10B,KAAM0rB,EAAczU,KAAKqwB,WAAWhxB,KAAKtW,OACzFyW,UAAW1H,EAAOsH,KAClBO,aAAcsQ,EAAAA,GAAaC,OAC3BxQ,UAAWyQ,EAAAA,GAAUrQ,OAEvBvmB,KAAK+G,WAEPgpC,EAAMxnC,SAASynC,GACbnqB,EACG1G,IAAI,CACH0G,KAAMkxB,EAAO/G,GAAM32B,QAAQ,IAAK,KAChCoF,EAAGyc,EAAc5U,IAAI7e,OAASzH,KAAKyH,OAASzH,KAAKmsC,SAAS6D,KAE3DnoB,OAAOnJ,IAEd,CAEA0sB,YAAAA,GACE,IAAKprC,KAAK4pC,mBAAoB,OAE9B,MAAM,cAAE1O,GAAkBl7B,KAAKqe,0BACzB,OAAEE,GAAW2c,EAAc2Q,SAE1BoL,EAAYC,GAAYl3C,KAAKmsC,SAAS/oB,SAC7C,GAAIpjB,KAAKm3C,qBAAuBn3C,KAAK4E,KAAK6P,WAAawiC,IAAeC,EACpE,OAEF,MAAMj4B,GAAYiwB,EAAAA,EAAAA,IAAa,CAC7BxwB,QAAS1e,KAAK0e,QACd+Q,QAASzvB,KAAKirB,WAAaiQ,EAAczU,KAAKjf,MAC9CkoB,QAASwL,EAAc5U,IAAI7e,OAASzH,KAAKyH,OAAS,KAEpDwX,EAAUkwB,KACV,MAAMiI,GAAeC,EAAAA,EAAAA,IAAgBr3C,KAAK0B,OACpC41C,GAAwBC,EAAAA,EAAAA,IAAyBv3C,KAAK0B,QAC5D81C,EAAAA,EAAAA,IAAkB,CAChB7tC,MAAO3J,KAAK4E,KACZmC,UAAW/G,KAAK+G,UAChBkkB,WAAYjrB,KAAKirB,WACjBzjB,MAAOxH,KAAKwH,MACZiwC,gBAAiBA,CAACv1B,EAAG1D,KAEnB,GAAIxe,KAAK4E,KAAKu3B,OAAOja,IAAM,EACzB,OAGFliB,KAAK0e,QAAQuH,UAAYjmB,KAAK4E,KAAKw2B,MAAMlZ,GAAKliB,KAAK4E,KAAK0oC,KAAKprB,GAAK3D,EAAOm5B,gBAAkBn5B,EAAOo5B,cAClG,MAAMl5B,EAAIY,KAAK2E,MAAMhkB,KAAKmsC,SAASnsC,KAAK4E,KAAKu3B,OAAOja,KACpDliB,KAAK0e,QAAQoe,SAASte,EAAI44B,EAAc,GAAIE,GAAwB74B,EAAE,IAG1EQ,EAAUgyB,MACZ,CAEA5F,cAAAA,GACE,MAAM,cAAEnQ,GAAkBl7B,KAAKqe,yBACzBY,GAAYiwB,EAAAA,EAAAA,IAAa,CAC7BxwB,QAAS1e,KAAK0e,QACd+Q,QAASzvB,KAAKirB,WAAaiQ,EAAczU,KAAKjf,MAC9CkoB,QAASwL,EAAc5U,IAAI7e,SAE7BwX,EAAUkwB,KACV,IAAK,MAAMl3B,KAAWjY,KAAKgY,SACzBC,EAAQyF,cAAc1d,KAAK0e,SAE7BO,EAAUgyB,MACZ,CAEA2G,WAAAA,CAAYl5B,GACV,MAAMm5B,GAAaD,EAAAA,EAAAA,IAAY,CAC7Bl5B,UACAisB,WAAU,IACV5jC,UAAW/G,KAAK+G,UAChB+wC,aAAc93C,KAAKwH,MACnBuwC,cAAe/3C,KAAKyH,OACpBkC,MAAO3J,KAAK4E,KACZozC,sBAAwBC,GAAUj4C,KAAKk4C,mBAAmBD,GAC1DE,kBAAoBn4C,KAAKirC,4BAAgD5iC,EAAvBrI,KAAKoqC,kBAErDpqC,KAAKirC,wBACPjrC,KAAKoqC,gBAAgB1rB,EAASisB,EAAAA,EAAWyN,qBAAqBp4C,KAAK+G,iBAGlDsB,IAAfwvC,IACFQ,EAAAA,EAAAA,GAAiB,CACftuC,UAAW/J,KAAK0B,MAAMkyB,eAAe0kB,mBACrCtgB,OAAQ6f,EAAa,YAAc,UACnCU,kBAAmB,YAGzB,CAEAC,mBAAAA,CAAoBC,EAAoB9qC,GAAoD,IAAlC+qC,IAAyBt3C,UAAAnB,OAAA,QAAAoI,IAAAjH,UAAA,KAAAA,UAAA,GACjF,MAAMu3C,EAAI34C,KAAK4E,KAAKg0C,kBAAkBjrC,EAAK8qC,GAC3C,GAAU,OAANE,EACF,OAAOD,EAA4B14C,KAAK0tC,UAAUiL,GAAM,GAAEA,GAE9D,CAEAE,mBAAAA,CAAoBJ,GAClB,MAAMK,EAAiB94C,KAAK4E,KAAKm0C,uBAAuBN,GAClDO,EAAah5C,KAAK4E,KAAKw2B,MAAM0d,IAAmB,KAChDG,EAAgBj5C,KAAK4E,KAAKw2B,MAAM0d,EAAiB,IAAM,KAC7D,OAAmB,OAAfE,GAAyC,OAAlBC,GAClBC,EAAAA,EAAAA,IAA+B,CAAEt0C,KAAM5E,KAAK4E,KAAMu0C,YAAaH,EAAYI,UAAWH,IAGxF,IACT,CAEA7O,eAAAA,CAAgB1rB,EAAmC+5B,GACjD,MAAM,cAAEvd,GAAkBl7B,KAAKqe,yBAI/B,GAHAK,EAAQiR,OACRjR,EAAQO,UAAUic,EAAczU,KAAKjf,MAAO,GAExCxH,KAAKirC,yBACPjrC,KAAKsqC,qBAAqB5rB,GACtBoF,OAAOkS,MAAMyiB,IAGf,OAFAz4C,KAAK+sC,QAAQ,CAAEruB,iBACfA,EAAQmR,UAKZ,MAAMwpB,EAAiBr5C,KAAK4E,KAAKg0C,kBAAkB,OAAQH,GACrDjR,EAAO6R,EAAiBtP,EAAAA,GAAAA,sBAA4BsP,GAAkB,KAE5E,GAAa,OAAT7R,EAAe,CACjB,MAAM8R,EACJt5C,KAAK4E,KAAK4iC,KAAKvnC,OAAS,GACpBs5C,EAAAA,EAAAA,IAA+B,CAC7BC,UAAWx5C,KAAK4E,KAAK4iC,KAAK,GAC1BiS,QAASz5C,KAAK4E,KAAK4iC,KAAKxnC,KAAK4E,KAAK4iC,KAAKvnC,OAAS,GAChD0J,MAAO3J,KAAK4E,OAEd,GAWN,OAVA5E,KAAK+sC,QAAQ,CACXruB,UACA+oB,WAAY6R,EAAmBb,GAC3BlR,EAAc,CACZC,KAAMuC,EAAAA,GAAAA,sBAA4BuP,EAAmBb,IACrDhkC,UAAWzU,KAAK4E,KAAK6P,YAEvB,YAENiK,EAAQmR,SAEV,CAEA7vB,KAAK+sC,QAAQ,CACXruB,UACA8oB,OACA5iC,KAAM,CACJ0oC,KAAMttC,KAAKw4C,oBAAoBC,EAAY,QAC3Ct8B,KAAMnc,KAAKw4C,oBAAoBC,EAAY,QAC3C1P,IAAK/oC,KAAKw4C,oBAAoBC,EAAY,OAC1Crd,MAAOp7B,KAAKw4C,oBAAoBC,EAAY,SAC5Ctc,OAAQn8B,KAAKw4C,oBAAoBC,EAAY,UAAU,IAEzDxL,iBAAkBjtC,KAAK64C,oBAAoBJ,KAG7C/5B,EAAQmR,SACV,CAEAid,YAAAA,CAAY4M,GAAqD,IAApD,QAAEh7B,GAAgDg7B,EAC7D,MACM,cAAExe,EAAa,iBAAEsR,GAAqBxsC,KAAKqe,0BAC3C,OAAEutB,EAAM,OAAE+N,EAAM,KAAE9iC,GAASqkB,EAAc5U,KACzC,aAAEszB,EAAY,kBAAEC,IAAsBC,EAAAA,EAAAA,IAAgB,CAAEl1C,KAAM5E,KAAK4E,OAEzE,IAAKg1C,EACH,OAGF,MAAMG,EAAc/5C,KAAKqR,6BAA+Bq7B,EAAAA,GAA2BC,UAC7EqN,EAAoBh6C,KAAK4E,KAAKiO,aAAeC,EAAAA,GAAWu5B,MACxD4N,GAAyBF,GAAevN,GAAoBxsC,KAAK2pC,aAAe,EAAI,GACpFuQ,EAAa,IAAI10B,EAAAA,EACrB,CACEK,KAAMk0B,GAAeC,EAAoBJ,EAAaO,cAAgBP,EAAaQ,OACnF57B,GAAImtB,EAAAA,EAAAA,IAAqB3rC,KAAKqR,4BAE1BrR,KAAKwH,MADLxH,KAAKwH,MAAQ0zB,EAAc5U,IAAIqzB,OAAO7N,OAAOvlB,MAAS0zB,EAE1Dx7B,EAAGyc,EAAc5U,IAAIqzB,OAAO7N,OAAOxlB,IACnCR,KAAMN,EAAAA,EAAK0e,2BAA2B,OAAQhJ,EAAc5U,IAAIqzB,OAAO7zB,MACvEK,UAAWyQ,EAAAA,GAAUrQ,MACrBH,aAAc8U,EAAc5U,IAAI2lB,SAChChmB,WAAWo0B,EAAAA,EAAAA,IAAe,CAAEV,OAAQC,EAAa33B,OAAQiZ,mBAE3Dl7B,KAAK+G,WAKP,GAHA/G,KAAKypC,YAAcyQ,EAAWvpB,QAAQjS,GACtCw7B,EAAWryB,OAAOnJ,KAEdq7B,GAAiB/5C,KAAK2pC,eAAgBqQ,IAGtCH,EAAmB,CACrB,MAAMS,EAAkB,IAAI90B,EAAAA,EAC1B,CACEK,KAAMg0B,GAAmBO,OACzBt0B,KAAMN,EAAAA,EAAK0e,2BAA2B,OAAQhJ,EAAc5U,IAAIqzB,OAAO7zB,MACvEK,UAAWyQ,EAAAA,GAAUrQ,MACrBH,aAAc8U,EAAc5U,IAAI2lB,SAChChmB,WAAWo0B,EAAAA,EAAAA,IAAe,CAAEV,OAAQE,EAAkB53B,OAAQiZ,mBAEhEl7B,KAAK+G,WAEDwzC,EAAuBD,EAAgB3pB,QAAQjS,GAC/C87B,EAAuBx6C,KAAKypC,YA5Cd,GA4C4C8Q,EAG9Drf,EAAczU,KAAKjf,MAAQxH,KAAKwpC,YAAcoC,EAAOE,OAAOrlB,KAAQulB,EAAAA,GAAOpkB,EAC3EsT,EAAczU,KAAKjf,MAAQxH,KAAKwH,MAAQgzC,EAAuBb,EAAO7N,OAAOvlB,OAE7E+zB,EACGn7B,IAAI,CACHX,EAAGxe,KAAKwH,MAAQ0zB,EAAc5U,IAAIqzB,OAAO7N,OAAOvlB,MAASvmB,KAAKypC,YApDhD,GAqDdhrB,EAAGyc,EAAc5U,IAAIqzB,OAAO7N,OAAOxlB,MAEpCuB,OAAOnJ,GACV1e,KAAK6pC,YAAc,KACnB7pC,KAAKypC,YAAc+Q,GAEnBx6C,KAAK0pC,SAAS,IACdxO,EAAczU,KAAKjf,MACjBxH,KAAKwpC,YACLoC,EAAOE,OAAOrlB,KACdzmB,KAAK0pC,SAAS,GAAGliC,MACjBqP,EAAKi1B,OAAOrlB,KACZ5P,EAAKi1B,OAAOvlB,MACZ2U,EAAczU,KAAKjf,MAAQxH,KAAKwH,MAAQ+yC,EAAuBZ,EAAO7N,OAAOvlB,QAE/E+zB,EACGn7B,IAAI,CACHX,EAAGxe,KAAKwH,MAAQ0zB,EAAc5U,IAAIqzB,OAAO7N,OAAOvlB,MAChD9H,EAAGyc,EAAc5U,IAAIqzB,OAAO7N,OAAOxlB,IAAO4U,EAAc5U,IAAIqzB,OAAO7zB,KAAKtW,KAAQw8B,EAAAA,GAAOpkB,IAExFC,OAAOnJ,GACV1e,KAAKypC,YAAcpqB,KAAKwF,IAAI7kB,KAAKypC,YAAa8Q,GAC9Cv6C,KAAK6pC,YAAc,CACjBrrB,EAAGxe,KAAKwH,MAAQ0zB,EAAc5U,IAAIqzB,OAAO7N,OAAOvlB,MAChD9H,EAAGyc,EAAc5U,IAAIqzB,OAAO7N,OAAOxlB,IAAO4U,EAAc5U,IAAIqzB,OAAO7zB,KAAKtW,KAAQw8B,EAAAA,GAAOpkB,EACvFpgB,MAAO+yC,GAGb,CACF,CAEApN,UAAAA,CAAWl3B,GACJjW,KAAKirC,uBAGRjrC,KAAKy6C,qBAAqBxkC,GAF1BjW,KAAK06C,oBAAoBzkC,EAI7B,CAEAwkC,oBAAAA,CAAoBE,GAA6F,IAA5F,QAAEj8B,EAAO,KAAE8oB,EAAI,KAAE8F,EAAI,KAAEnxB,EAAI,IAAE4sB,EAAG,MAAE3N,EAAK,OAAEe,EAAM,iBAAE8Q,GAAyC0N,EAC7G,MAAMC,EAAmB7T,EAAoB/mC,KAAKwH,QAC5C,cAAE0zB,GAAkBl7B,KAAKqe,0BACzB,OAAEE,GAAW2c,EAAc2Q,QAE3BgP,EAAW,IAAIr1B,EAAAA,EACnB,CACEM,KAAM,CAAEtW,KAAMu8B,EAAAA,GAAUnkB,GACxB1B,WAAY,GACZD,UAAW1H,EAAOsH,KAClBM,UAAWyQ,EAAAA,GAAUnQ,KACrBL,aAAcsQ,EAAAA,GAAaC,OAC3BjQ,YAAY2a,EAAAA,EAAAA,IAAwB9iB,EAAOu8B,WAAY,KAEzD96C,KAAK+G,WAGDg0C,EAAevT,EAAO,CAAC,CAAE3hB,KAAM2hB,EAAMtvB,MAAOkxB,IAAa,GACzD4R,GAAc1N,GAAQ,IAAMlS,GAAS,GAAKiO,IAAAA,IAAmB,KAAOA,IAAAA,MAAqB,KACzF4R,EAAY3N,EACd,CACE,CAAEznB,KAAM,IAAK3N,MAAOkxB,GACpB,CAAEvjB,KAAMynB,EAAMp1B,MAAO8iC,IAEvB,GACEE,EAAY/+B,EACd,CACE,CAAE0J,KAAM,IAAK3N,MAAOkxB,GACpB,CAAEvjB,KAAM1J,EAAMjE,MAAO8iC,IAEvB,GACEG,EAAYpS,EACd,CACE,CAAEljB,KAAM,IAAK3N,MAAOkxB,GACpB,CAAEvjB,KAAMkjB,EAAK7wB,MAAO8iC,IAEtB,GACEI,EAAYhgB,EACd,CACE,CAAEvV,KAAM,IAAK3N,MAAOkxB,GACpB,CAAEvjB,KAAMuV,EAAOljB,MAAO8iC,IAExB,GACEK,EAAclf,EAChB,CACE,CAAEtW,KAAM,MAAO3N,MAAOkxB,GACtB,CAAEvjB,KAAMsW,EAAQjkB,MAAO8iC,IAEzB,GACEM,EAAqC,MAApBrO,EAA2B,CAAC,CAAEpnB,KAAMonB,EAAiBmN,OAAQliC,MAAO8iC,IAAgB,GAErG7zB,EAA4B,GAE5Bo0B,EAA8BC,GAClCA,EAAaC,SAAQ,CAAC/lC,EAAUzT,IAC9BA,EAAQ,EAAK,IAAKyT,EAASzV,OAAS,EAAI,CAAC,SAAW,MAAQyV,GAAiCA,IAE7FklC,EAAiBxT,IACnBjgB,EAAM5lB,KACJg6C,EAA2B,CACzBR,EACAE,EACAC,EACAC,EACAC,EACAC,EACAC,KAGKV,EAAiBzT,KAC1BhgB,EAAM5lB,KAAKg6C,EAA2B,CAACR,EAAcO,KACrDn0B,EAAM5lB,KAAKg6C,EAA2B,CAACN,EAAWC,EAAWC,EAAWC,EAAWC,OAEnFl0B,EAAM5lB,KAAKg6C,EAA2B,CAACR,EAAcM,EAAaC,KAClEn0B,EAAM5lB,KAAKg6C,EAA2B,CAACN,EAAWC,EAAWC,EAAWC,MAG1E,MAAMM,EAAS1P,EAAAA,GAAOa,EAAI3R,EAAczU,KAAKjf,MAC7C,IAAIgX,EAAIk9B,EACJj9B,EAAIutB,EAAAA,GAAOa,EAAIgO,EAAS93C,MAAMmjB,WAAa,EAE/CiB,EAAM5e,SAASoO,IACb6H,EAAIk9B,EACJ/kC,EAAKpO,SAAQ,CAACozC,EAAa15C,EAAOu5C,KAChC,MAAMn1B,EAAU,CAAEI,KAAM,EAAGF,MAAO,EAAGD,IAAK,EAAGE,OAAQ,IAC/C,KAAEX,EAAO,GAAE,MAAE3N,GAAsC,UAAhByjC,EAA0B,CAAC,EAAIA,EAC1D,IAAV15C,EACFokB,EAAQI,KAAO,EACNxkB,IAAUu5C,EAAav7C,OAAS,EACzComB,EAAQE,MAAQ,EACS,UAAhBo1B,IACTt1B,EAAQI,KAAO,EACfJ,EAAQE,MAAQ,EACXq0B,EAAiBzT,MACpB9gB,EAAQI,KAAO,EACfJ,EAAQE,MAAQ,IAGpBs0B,EAAS17B,IAAI,CAAE0G,OAAMI,UAAW/N,EAAOsG,IAAGC,IAAG4H,YAC7Cw0B,EAAShzB,OAAOnJ,GAChBF,GAAKq8B,EAASrzC,KAAK,IAErBiX,GAAKo8B,EAAS93C,MAAMmjB,UAAU,GAElC,CAEAioB,8BAAAA,CAA+BzvB,GAC7B,MAAM,cAAEwc,GAAkBl7B,KAAKqe,yBACzBu8B,EAAmB7T,EAAoB/mC,KAAKwH,OAC5Co0C,EAAa,IAAIp2B,EAAAA,EACrB,CACEM,KAAM,CAAEtW,KAAMu8B,EAAAA,GAAUnkB,GACxB1B,WAAY,GACZC,UAAWyQ,EAAAA,GAAUnQ,KACrBL,aAAcsQ,EAAAA,GAAaC,OAC3BjQ,YAAY2a,EAAAA,EAAAA,IAAwBnG,EAAc2Q,QAAQttB,OAAOu8B,WAAY,IAE7Et8B,EAAGwtB,EAAAA,GAAOa,EAAI3R,EAAczU,KAAKjf,MACjC6e,QAAS,CAAEI,KAAMkB,EAAAA,GAAQC,EAAGrB,MAAOoB,EAAAA,GAAQC,EAAGtB,IAAK,EAAGE,OAAQ,IAEhExmB,KAAK+G,WAGP,IAAI80C,EAAuB,EACvBjB,EAAiBxT,IACnByU,EAAuB,EACdjB,EAAiBzT,MAC1B0U,EAAuB,GAIzB,MAAM,WAAE31B,GAAe01B,EAAW74C,MAClC,IAAI0b,EAAIyH,EAAa21B,EAAuB31B,EAAa,EAAI8lB,EAAAA,GAAOa,EAEpE,IAAK,MAAM50B,KAAWjY,KAAKgY,SACpBC,EAAQq2B,4BAGbsN,EAAWz8B,IAAI,CACb0G,KAAM5N,EAAQ1T,WACdka,IACAwH,UAAWhO,EAAQu2B,kBAClB3mB,OAAOnJ,GACVD,GAAKyH,EAET,CAEAw0B,mBAAAA,CAAmBoB,GAcO,IAdN,QAClBp9B,EAAO,KACP8oB,EAAI,KACJ8F,EAAI,KACJnxB,EAAI,IACJ4sB,EAAG,MACH3N,EAAK,OACLe,EAAM,UACNoR,EAAS,kBACTH,GAAoB,EAAK,aACzBC,GAAe,EAAK,KACpB5pC,EAAI,aACJupC,GAAe,EAAK,iBACpBC,GACsB6O,EACtB,MAAM,cAAE5gB,GAAkBl7B,KAAKqe,0BACzB,OAAEE,GAAW2c,EAAc2Q,SAC3B,KAAEh1B,GAASqkB,EAAc5U,IACzByzB,EAAc/5C,KAAKqR,6BAA+Bq7B,EAAAA,GAA2BC,UAC7EqN,EAAoBh6C,KAAK4E,KAAKiO,aAAeC,EAAAA,GAAWu5B,MAC1D0N,GAAeC,EACjBnjC,EAAKlB,KAAOkxB,EAASkV,SACZhC,GAAe/5C,KAAK4E,KAAKiO,aAAeC,EAAAA,GAAWC,OAAStP,IACrEoT,EAAKlB,KAAOkxB,EAASmV,UAGvB,MAAMC,EAAWplC,EAAKlB,KAAOkB,EAAKi1B,OAAOxlB,IAAMzP,EAAKi1B,OAAOxlB,IAAO4U,EAAc5U,IAAIslB,OAAO9lB,KAAKtW,KAC1F0sC,EAAerlC,EAAKiP,KAAKtW,KACzB2sC,EACJn8C,KAAKwpC,YACLtO,EAAc5U,IAAIslB,OAAOE,OAAOrlB,MAC/BzmB,KAAKwH,OACHxH,KAAKwpC,YACJtO,EAAc5U,IAAIslB,OAAOE,OAAOrlB,KAChCzmB,KAAKypC,aACJ2D,EAAoB,EAAIlS,EAAc5U,IAAIqzB,OAAO7N,OAAOvlB,SAC3D,EACE61B,EAAcp8C,KAAKwpC,YAActO,EAAc5U,IAAIslB,OAAOE,OAAOrlB,KAAQ5P,EAAKi1B,OAAOrlB,KAErF41B,GADW,CAAC/O,EAAMnxB,EAAM4sB,EAAK3N,EAAOe,GAAQh0B,MAAMm0C,IAAgBA,IAEpE,CACE9U,KAAM,CAACA,GAAQ,IACf+U,WAAY,CACT,GAAE/U,YAAe8F,QAAWnxB,QAAW4sB,QAAU3N,IAChDmS,EAAa,QAAOA,IAAc,eACvBpR,UAKb8Q,EAAmBA,EAAiBmN,YAAS/xC,GAC7CuP,QAAQhK,QAAoBvF,IAAVuF,KAEtB,CACE45B,KAAM,CAACA,GAAQ,IACf+U,WAAY,CAAE,GAAE/U,GAAQ,OAGxBgV,EAAY,IAAIh3B,EAAAA,EACpB,CACEM,KAAM,CAAEtW,KAAM0sC,IAEhBl8C,KAAK+G,WAGD01C,EAAcA,IACbrP,EAGEvG,EAASkV,SAFPlV,EAAS0V,WAoEflP,EAsBHrtC,KAAK0pC,SAAW,IArBhBhrB,EAAQuH,UAAY1H,EAAOu8B,WAC3B96C,KAAK0pC,SAASnhC,SAASoO,IACrB,MAAM6H,EAAK7H,EAAKwP,YAAcyQ,EAAAA,GAAUnQ,KAAO9P,EAAK6H,EAAI7H,EAAK6H,EAAK7H,EAAKnP,MAAS,EAC1EiX,EAAK9H,EAAKyP,eAAiBsQ,EAAAA,GAAapQ,IAAM3P,EAAK8H,EAAI9H,EAAK8H,EAAKy9B,EACvEx9B,EAAQoe,SACNte,EAAImJ,EAAAA,GAAQ+b,IACZjlB,EAAIkJ,EAAAA,GAAQ+b,IACZ/b,EAAAA,GAAQ+b,IAAM/sB,EAAKnP,MAASmgB,EAAAA,GAAQ+b,IACpC/b,EAAAA,GAAQ+b,IAAMwY,EAAev0B,EAAAA,GAAQ+b,IACtC,IAGC1jC,KAAK6pC,aACPnrB,EAAQoe,SACN98B,KAAK6pC,YAAYrrB,EAAIxe,KAAK6pC,YAAYriC,MAAQmgB,EAAAA,GAAQ+b,IACtD1jC,KAAK6pC,YAAYprB,EAAIyc,EAAc5U,IAAIqzB,OAAO7zB,KAAKtW,KAAQmY,EAAAA,GAAQ+b,IACnE/b,EAAAA,GAAQ+b,IAAM1jC,KAAK6pC,YAAYriC,MAAQmgB,EAAAA,GAAQ+b,IAC/C/b,EAAAA,GAAQ+b,IAAMxI,EAAc5U,IAAIqzB,OAAO7zB,KAAKtW,KAAQmY,EAAAA,GAAQilB,KAOlE,MAAM8P,EAxFkBC,MACtB,OAAQ9lC,EAAKlB,MAAQ8mC,KACnB,KAAK5V,EAAS0V,WACZ,MAAO,CACL12B,KAAMw2B,EAAKE,WACX/9B,EAAG,CAAC49B,EAAaA,GACjB39B,EAAG,CAAC5H,EAAKi1B,OAAOxlB,KAChBH,UAAWyQ,EAAAA,GAAUnQ,KACrBL,aAAc,CAACsQ,EAAAA,GAAauN,aAEhC,KAAK4C,EAASkV,SACZ,GAAIhC,GAAeC,EAAmB,CACpC,MAAMn0B,EAAQ,GAAEw2B,EAAK7U,kCAAkCrL,IACjDjU,EAAYs0B,EAAUr9B,IAAI,CAAE0G,SAAQ8K,QAAQjS,GAClD,MAAO,CACLmH,KAAM,CAACA,GACPrH,EAAG,CACDxe,KAAKwH,MAAQ0zB,EAAc5U,IAAIqzB,OAAO7N,OAAOvlB,MAASvmB,KAAKypC,YAAcvhB,EAAY00B,EAAAA,GAAaC,KAEpGp+B,EAAG,CAAC5H,EAAKi1B,OAAOxlB,KAChBH,UAAWyQ,EAAAA,GAAUC,OACrBzQ,aAAc,CAACsQ,EAAAA,GAAauN,YAEhC,CAAO,GAAImJ,EACT,MAAO,CACLvnB,KAAMw2B,EAAK7U,KACXhpB,EAAG,CAAC29B,GACJ19B,EAAG,CAAC5H,EAAKi1B,OAAOxlB,KAChBH,UAAWyQ,EAAAA,GAAUC,OACrBzQ,aAAc,CAACsQ,EAAAA,GAAauN,aAEzB,CACL,MASM6Y,IARJ98C,KAAKwH,OACFxH,KAAKwpC,YACJtO,EAAc5U,IAAIslB,OAAOE,OAAOrlB,KAChC5P,EAAKi1B,OAAOrlB,KACZ5P,EAAKi1B,OAAOvlB,MACZvmB,KAAKypC,YACLvO,EAAc5U,IAAIqzB,OAAO7N,OAAOvlB,OACpCi2B,EAAUr9B,IAAI,CAAE0G,KAAMw2B,EAAK7U,KAAK,KAAM7W,QAAQjS,KACb7H,EAAKiP,KAAKmmB,WAAavV,EAAAA,GAAapQ,IACvE,MAAO,CACLT,KAAMw2B,EAAK7U,KACXhpB,EAAG,CAAC49B,GACJ39B,EAAGq+B,EAAW,CAACb,GAAY,CAACplC,EAAKi1B,OAAOxlB,KACxCH,UAAWyQ,EAAAA,GAAUnQ,KACrBL,aAAc02B,EAAW,CAACpmB,EAAAA,GAAapQ,KAAO,CAACoQ,EAAAA,GAAauN,YAEhE,CACF,KAAK4C,EAASmV,SACZ,MAAO,CACLn2B,KAAM,CAACpiB,GACP+a,EAAG,CAAC29B,EAAgBK,EAAUr9B,IAAI,CAAE0G,KAAMpiB,IAAQktB,QAAQjS,GAAW,GACrED,EAAG,CAACw9B,GACJ91B,UAAWyQ,EAAAA,GAAUC,OACrBzQ,aAAc,CAACvP,EAAKiP,KAAKmmB,WAE7B,QACE,OACJ,EA4BmB0Q,GAEfI,EAAqBC,IAYrB,IAZsB,QAC1BC,EAAO,OACPp1B,GAAS,GAUVm1B,EACC,MAAME,GAA0BrmC,EAAKlB,MAAQ8mC,OAAmB5V,EAAS0V,YAActP,EACvFgQ,GAASp3B,KAAKtd,SAAQ,CAACoO,EAA0B1U,KAC/C,IAAIigB,EAAIjgB,EACJgpB,EAAa,EACbhF,EAAY1H,EAAOsH,KACnBA,EAAOlP,EACP1U,EAAQ,GAAKi7C,IACfh7B,GAAK,EACL+I,EAAauxB,EAAU7rB,QAAQjS,GAC/BmH,EAAOlP,EAEPsP,GAAYo0B,EAAAA,EAAAA,IAAe,CAAEV,OAAQ1M,EAAiBhrB,OAAQiZ,mBAEhE,MAAMx2B,EAAU,CACdmhB,OACArH,EAAGy+B,EAAQz+B,EAAE0D,GAAK+I,EAClBxM,EAAGw+B,EAAQx+B,EAAEyD,GACbkE,aAAcvP,EAAKiP,KAAKmmB,SAAWp1B,EAAKiP,KAAKmmB,SAAWgR,EAAQ72B,aAAalE,GAC7EiE,UAAWtP,EAAKiP,KAAKK,UAAYtP,EAAKiP,KAAKK,UAAY82B,EAAQ92B,UAC/DF,aAEFu2B,EAAUr9B,IAAIza,GACV2oC,IACFrtC,KAAK0pC,SAASxnB,GAAK,CAAE1a,MAAOg1C,EAAU7rB,QAAQjS,MAAaha,IAEzDmjB,GACF20B,EAAU30B,OAAOnJ,EACnB,GACA,EAIJ,OAFAq+B,EAAmB,CAAEE,QAASP,EAAc70B,OAAQmlB,IAE7C,CACL0P,eACAK,qBAEJ,CAGAxR,uBAAAA,GACE,MAAM,cAAErQ,GAAkBl7B,KAAKqe,0BACzB,OAAEE,GAAW2c,EAAc2Q,QAC3B71B,EAAShW,KAAK0B,MAAMiI,QAAQ8K,UAClC,GAAIzU,KAAK4E,KAAKiO,aAAeC,EAAAA,GAAWC,MACtC,OAEF,IAAK,CAACi1B,EAAAA,GAAUC,GAAID,EAAAA,GAAUE,GAAIF,EAAAA,GAAUG,GAAIH,EAAAA,GAAUI,IAAIhO,SAASpkB,GACrE,OAGF,MAAMg+B,EAAWmJ,SAASnnC,EAAOggC,UAAU,GAAI,IACzCpB,EAAc50C,KAAK4E,KAAKiwC,iBACxB51B,GAAYiwB,EAAAA,EAAAA,IAAa,CAC7BxwB,QAAS1e,KAAK0e,QACd+Q,QAASzvB,KAAKirB,WAAaiQ,EAAczU,KAAKjf,MAC9CkoB,QAASwL,EAAc5U,IAAI7e,SAE7BwX,EAAUkwB,KACV,MAAMiI,GAAeC,EAAAA,EAAAA,IAAgBr3C,KAAK0B,OAC1C,IAAK,MAAMomC,KAAO8M,EAAa,CAE7B,MAAME,EAAWF,EAAY9M,GAC7B,IAAIsV,EAAMp9C,KAAK4E,KAAKowC,kBAAoBhB,EAAYc,EAChDuI,EAAKr9C,KAAK4E,KAAKswC,uBAAyBlB,EAAWoJ,EACnDE,EAAKt9C,KAAK+G,UAAUoQ,MAAMqH,EAAE4+B,GAAMhG,EAClC5vC,EAAQxH,KAAK+G,UAAUoQ,MAAMqH,EAAE6+B,GAAMr9C,KAAK+G,UAAUoQ,MAAMqH,EAAE4+B,GAChEp9C,KAAK0e,QAAQS,IAAI,YAAaZ,EAAOg/B,eACrCv9C,KAAK0e,QAAQoe,SAASwgB,EAAI,EAAG91C,EAAOxH,KAAKyH,OAAS,GAE9CzH,KAAK4E,KAAK0vC,yBAA2B,IACvC8I,EACGp9C,KAAK4E,KAAKowC,kBAAoBhB,EAAYc,GAC1C90C,KAAK4E,KAAKowC,kBAAoBh1C,KAAK4E,KAAK0vC,0BAA4BN,EACvEqJ,EAAKr9C,KAAK4E,KAAK0vC,yBAA2BN,EAAWoJ,EACrDE,EAAKt9C,KAAK+G,UAAUoQ,MAAMqH,EAAE4+B,GAAMhG,EAClC5vC,EAAQxH,KAAK+G,UAAUoQ,MAAMqH,EAAE6+B,GAAMr9C,KAAK+G,UAAUoQ,MAAMqH,EAAE4+B,GAE5Dp9C,KAAK0e,QAAQS,IAAI,YAAaZ,EAAOi/B,iBACrCx9C,KAAK0e,QAAQoe,SAASwgB,EAAI,EAAG91C,EAAOxH,KAAKyH,OAAS,GAEtD,CACAwX,EAAUgyB,MACZ,CAEAwM,mBAAAA,GACE,MAAM9zC,EAAQ3J,KAAK0B,MAAMiI,QACnB+zC,EAAU/zC,EAAMkJ,aAAeC,EAAAA,GAAWC,MAC1C4qC,EAA0BC,EAAAA,GAA2BxjB,SAASzwB,EAAM8K,WACpEopC,EAAe79C,KAAKqR,6BAA+Bq7B,EAAAA,GAA2BoR,WAEpF,OAAOJ,IAAYC,GAA2BE,EAChD,CAEAvS,eAAAA,GACE,MAAM,cAAEpQ,GAAkBl7B,KAAKqe,0BACzB,OAAEE,GAAW2c,EAAc2Q,QACjC,IAAK7rC,KAAKy9C,sBACR,OAEF,MAAMx+B,GAAYiwB,EAAAA,EAAAA,IAAa,CAC7BxwB,QAAS1e,KAAK0e,QACd+Q,QAASyL,EAAczU,KAAKjf,MAC5BkoB,QAASwL,EAAc5U,IAAI7e,SAE7BwX,EAAUkwB,KAEV,IAAI1wB,EAAIY,KAAK2E,MAAMhkB,KAAKoiB,GAAGpiB,KAAK0B,MAAMiI,QAAQyvC,YAC1C36B,IAAMze,KAAKyH,SAAQgX,GAAK,GAE5B,IAAIgd,EAAAA,EACF,CACE3d,GAAI,EACJE,GAAIhe,KAAKwH,MACTuW,GAAIU,EACJR,GAAIQ,EACJid,YAAand,EAAO66B,UACpBzd,WAAY,GAEd37B,KAAK+G,WACL8gB,OAAO7nB,KAAK0e,SACdO,EAAUgyB,MACZ,CAEAjG,uBAAAA,GACE,MAAM,cAAE9P,GAAkBl7B,KAAKqe,0BACzB,OAAEE,GAAW2c,EAAc2Q,QAC3BrtB,MAAQ0c,EAAczU,KAAKjf,MAAQ0zB,EAAc3U,MAAM/e,MAAQxH,KAAKwH,OAAS,GAC7EiX,MAAQyc,EAAc5U,IAAI7e,OAASyzB,EAAc1U,OAAO/e,OAASzH,KAAKyH,QAAU,GACtF,IAAI+d,EAAAA,EACF,CACEK,KAAM,sBACNrH,IACAC,IACAqH,KAAM,CAAEtW,KAAMu8B,EAAAA,GAAUc,EAAG12B,MAAO,QAClC8P,UAAW1H,EAAOsH,KAClBM,UAAWyQ,EAAAA,GAAUC,OACrBzQ,aAAcsQ,EAAAA,GAAaC,QAE7B32B,KAAK+G,WACL8gB,OAAO7nB,KAAK0e,QAChB,CAGA2rB,UAAAA,GACE,MAAM,cAAEnP,GAAkBl7B,KAAKqe,yBAQ/Bre,KAAK6qC,UAAY7qC,KAAK6qC,WAAa,IAAIkT,EAEvC/9C,KAAK6qC,UAAU1rB,KACZT,IACgC,IAA3B1e,KAAK4E,KAAKw2B,MAAMn7B,QAIpBD,KAAKmqC,YAAYzrB,GACjB1e,KAAK8nB,WAAWpJ,IACX1e,KAAKg+C,wBAA0Bh+C,KAAK4pC,oBACvC5pC,KAAKy2C,iBAAiB/3B,GAEnB1e,KAAKirC,wBACRjrC,KAAKsqC,qBAAqB5rB,IAT1B1e,KAAK8nB,WAAWpJ,EAUlB,GAEF1e,KAAKwH,MAAQ0zB,EAAczU,KAAKjf,MAAQ0zB,EAAc3U,MAAM/e,MAC5DxH,KAAKyH,OAASyzB,EAAc5U,IAAI7e,OAASyzB,EAAc1U,OAAO/e,OAElE,CAGAw2C,SAAAA,CAAU97B,GACRniB,KAAK4E,KAAO5E,KAAK0B,MAAMiI,QACvB,MAAM,aAAEu0C,GAAiBl+C,KAAKqe,yBAAyB6c,cAAcrE,OAErE,GAAkB,mBAAP1U,EACT,OAGF,MAAMg8B,GAAwB7L,EAAAA,EAAAA,IAA2B,CACvDrnB,WAAYjrB,KAAK0B,MAAMupB,WACvBlkB,UAAW/G,KAAK+G,UAChB4C,MAAO3J,KAAK4E,OAGRw5C,GAAuB9L,EAAAA,EAAAA,IAA2B,CACtDrnB,WAAYjrB,KAAK0B,MAAMupB,WACvBlkB,UAAW/G,KAAK+G,UAChB4C,MAAO3J,KAAK4E,KACZ4tC,WAAYxyC,KAAKwH,QAKb62C,EAAU,GAChB,IAHyBC,EAAAA,EAAAA,IAAoBH,EAAuBC,GAIlEC,EAAQ98C,KACNvB,KAAK4E,KAAKu3B,OAAOgiB,EAAsBl8C,OACvCod,KAAKqF,IAAI05B,EAAqBn8C,MAAOjC,KAAK4E,KAAKw3B,SAASn8B,OAAS,SAGnE,IAAK,IAAIiiB,EAAIi8B,EAAsBl8C,MAAOigB,GAAKk8B,EAAqBn8C,MAAOigB,IACzEm8B,EAAQ98C,KAAKvB,KAAK4E,KAAKu3B,OAAOja,IAIlC,MAAM2C,EAAMklB,EAAAA,GAAMllB,IAAIw5B,IAAY,EAC5BzH,EAAWsH,GAAgB,GACjCl+C,KAAKmsC,SAAW0D,EAAAA,MAAiBzD,MAAM,CAAC,EAAGwK,IAAWxzB,OAAO,CAAC,EAAGyB,IAAMirB,KAAK,GAC5E9vC,KAAKm3C,mBAAqBn3C,KAAK4E,KAAK6P,SACtC,CAGA02B,IAAAA,CAAKoT,GACH,MAAM,cAAErjB,GAAkBl7B,KAAKqe,yBACR,MAAnBkgC,IACFA,GAAkB,GAEpBv+C,KAAK0e,QAAQQ,YACb,IAAIs/B,EAAe,EACfD,IACFC,EAAetjB,EAAc1U,OAAO/e,QAItCzH,KAAK0e,QAAQilB,KAAKzI,EAAczU,KAAKjf,MAAO0zB,EAAc5U,IAAI7e,OAAQzH,KAAKwH,MAAOxH,KAAKyH,OAAS+2C,EAAe,GAC/Gx+C,KAAK0e,QAAQysB,MACf,CAEAjB,UAAAA,CAAWjyB,GAGT,OAFAA,EAAQvO,MAAQ1J,KAChBA,KAAKgY,SAASzW,KAAK0W,GACZjY,KAAKuJ,QAAQ,SACtB,CAEAk1C,WAAAA,CAAYzmC,GAEV,OADAhY,KAAKgY,SAAWA,EACThY,KAAKuJ,QAAQ,SACtB,CAEAm1C,aAAAA,CAAczmC,GACZ,IAAK,IAAIhW,EAAQ,EAAGA,EAAQjC,KAAKgY,SAAS/X,OAAQgC,IAAS,CAEzD,GADWjC,KAAKgY,SAAS/V,KACdgW,EAAS,CAClBjY,KAAK+C,MAAMiV,SAAS2mC,OAAO18C,EAAO,GAClCjC,KAAKgY,SAAS2mC,OAAO18C,EAAO,GAC5BjC,KAAKuJ,QAAQ,UACb,KACF,CACF,CACF,CAEA+lC,SAAAA,GACEtvC,KAAK4E,KAAO5E,KAAK0B,MAAMiI,QACvB,IAAI+a,EAAMZ,OAAO86B,UACb/5B,EAAMf,OAAO+6B,UACb3V,GAAY,EACZC,GAAY,EACZyF,EAAoB,KAExB,MAAMuP,GAAwB7L,EAAAA,EAAAA,IAA2B,CACvDrnB,WAAYjrB,KAAK0B,MAAMupB,WACvBlkB,UAAW/G,KAAK+G,UAChB4C,MAAO3J,KAAK4E,OAERw5C,GAAuB9L,EAAAA,EAAAA,IAA2B,CACtDrnB,WAAYjrB,KAAK0B,MAAMupB,WACvBlkB,UAAW/G,KAAK+G,UAChB4C,MAAO3J,KAAK4E,KACZ4tC,WAAYxyC,KAAKwH,QAMnB,IAHyB82C,EAAAA,EAAAA,IAAoBH,EAAuBC,GAG9C,CAGpB,GAFA15B,EAAM1kB,KAAK4E,KAAKmkC,IAAIoV,EAAsBl8C,OAC1C4iB,EAAM7kB,KAAK4E,KAAKuX,KAAKkD,KAAKqF,IAAI05B,EAAqBn8C,MAAOjC,KAAK4E,KAAKw3B,SAASn8B,OAAS,IAClFykB,EAAMG,EAAK,CACb,MAAMi6B,EAAUp6B,EAChBA,EAAMG,EACNA,EAAMi6B,CACR,CACAlQ,EAAoB5uC,KAAK4E,KAAKw2B,MAAM+iB,EAAsBl8C,MAC5D,KAAO,CACL,IAAK,IAAIigB,EAAIi8B,EAAsBl8C,MAAOigB,GAAKk8B,EAAqBn8C,MAAOigB,MACvD,IAAdgnB,GAAmBlpC,KAAK4E,KAAKmkC,IAAIG,GAAYlpC,KAAK4E,KAAKmkC,IAAI7mB,MAC7DgnB,EAAWhnB,KAEK,IAAdinB,GAAmBnpC,KAAK4E,KAAKuX,KAAKgtB,GAAYnpC,KAAK4E,KAAKuX,KAAK+F,MAC/DinB,EAAWjnB,GAKf,GAAIliB,KAAK4E,KAAKmkC,IAAIG,KAAclpC,KAAK4E,KAAKuX,KAAKgtB,GAAW,CACxD,MAAM4V,EAAuBnW,EAC3BM,EACAC,EACAnpC,KAAK4E,KAAKuX,KACVnc,KAAK4E,KAAKmkC,KAEZG,EAAW6V,EAAqB7V,SAChCC,EAAW4V,EAAqB5V,QAClC,CAEAzkB,EAAM1kB,KAAK4E,KAAKmkC,IAAIG,GACpBrkB,EAAM7kB,KAAK4E,KAAKuX,KAAKgtB,GAErByF,EAAoB5uC,KAAK4E,KAAKw2B,MAAM+iB,EAAsBl8C,MAC5D,CAoBA,OAjBIyiB,IAAQG,IACVH,GAAO,IACPG,GAAO,MAIL7kB,KAAKy9C,uBAAiD,OAAxBz9C,KAAK4E,KAAKw0C,YAC1C10B,EAAMrF,KAAKqF,IAAIA,EAAK1kB,KAAK4E,KAAKw0C,WAC9Bv0B,EAAMxF,KAAKwF,IAAIA,EAAK7kB,KAAK4E,KAAKw0C,YAI5Bp5C,KAAKqR,6BAA+Bq7B,EAAAA,GAA2BC,WAAc3sC,KAAK0B,MAAMwS,YAC1FwQ,EAAMrF,KAAKqF,IAAIA,EAAK1kB,KAAK4E,KAAKq2B,WAC9BpW,EAAMxF,KAAKwF,IAAIA,EAAK7kB,KAAK4E,KAAKq2B,YAGzB,CAAEvW,MAAKG,MAAK+pB,oBACrB,CAEApuB,MAAAA,GAAU,CAEVG,QAAAA,GACE,OAAO,CACT,CAEAwB,GAAM3D,GAAcxe,KAAK+G,UAAUoQ,MAAMqH,EAAExe,KAAK4E,KAAKw3B,SAAS5d,IAE9D4D,GAAM3D,GAAcze,KAAK+G,UAAUoQ,MAAMsH,EAAEA,GAE3CuF,KAAAA,CAAM20B,EAAW10B,GACf,OAAOD,EAAAA,EAAAA,IAAM,CAAEpf,KAAM5E,KAAK4E,KAAMT,IAAKw0C,EAAG10B,eAAgBA,GAAkBjkB,KAAKk4C,sBACjF,CAEAxK,SAAAA,CAAUiL,GACR,MAAMqG,EAAkBh/C,KAAKk4C,qBAC7B,OAAOl0B,EAAAA,EAAAA,IAAM,CACXpf,KAAM5E,KAAK4E,KACXT,IAAKw0C,EACL10B,eAAgB+6B,EAAkB3/B,KAAKwF,IAAIm6B,EAAiB,QAAK32C,GAErE,CAEA2B,QAAAA,GACE,MAAMgO,EAAWhY,KAAKgY,SAAStK,KAAKuK,GAAYA,EAAQjO,aACxD,OAAOkd,IAAM,CAAC,EAAGlnB,KAAK+C,MAAO,CAAE4S,KAAM3V,KAAK2V,KAAMqC,YAClD,CAEA9N,QAAAA,GACE,MAAM8N,EAAWhY,KAAKgY,SAAStK,KAAKuK,GAAYA,EAAQ/N,aACxD,OAAOgd,IAAM,CAAC,EAAGlnB,KAAK+C,MAAO,CAAE4S,KAAM3V,KAAK2V,KAAMqC,YAClD,CAEAkgC,kBAAAA,CAAmBD,GACjB,MAAM,UAAEhd,EAAS,WAAEpoB,GAAe7S,KAAK4E,KACjCq6C,EAAWhH,GAAS54B,KAAKQ,IAAIo4B,GACnC,OAAIhd,GAAa,IACR,EACEA,GAAa,IACf,EACEpoB,IAAeC,EAAAA,GAAWC,QAAUksC,GAAYhkB,GAAa,EAC/D,OACgB5yB,IAAd4yB,EAEF,OAFF,CAMT,CAEAikB,UAAAA,CAAWvpC,GACT,OAAO3V,KAAKgY,SAAS7P,MAAMqW,GAAMA,EAAE7I,OAAS,YAAcA,GAC5D,CAEA6+B,QAAAA,GACE,OAAO,IAAI/Y,EAAAA,EACT,CACE1d,GAAI,EACJE,GAAIje,KAAKyH,OACTi0B,YAAa17B,KAAKqe,yBAAyB6c,cAAc2Q,QAAQttB,OAAOo4B,KACxEhb,WAAY,GAEd37B,KAAK+G,UAET,CAEA+pC,QAAAA,GACE,OAAO,IAAIrV,EAAAA,EACT,CACE3d,GAAI,EACJE,GAAIhe,KAAKwH,MACTk0B,YAAa17B,KAAKqe,yBAAyB6c,cAAc2Q,QAAQttB,OAAOo4B,KACxEhb,WAAY,GAEd37B,KAAK+G,UAET,CAEAsX,sBAAAA,GACE,OAAOA,EAAAA,EAAAA,IAAuBre,KAAK0B,MAAMkyB,eAC3C,CAEAoqB,oBAAAA,GACE,OACEh+C,KAAK8pC,UAAY9pC,KAAK0B,MAAMkyB,eAAeviB,6BAA+Bq7B,EAAAA,GAA2ByS,SAEzG,CAEAC,kCAAAA,GACE,MAAM,cAAElkB,GAAkBl7B,KAAKqe,0BACzB,OAAEE,GAAW2c,EAAc2Q,SAC3B,MAAEnlC,EAAK,2BAAE2K,GAA+BrR,KAAK0B,MAAMkyB,eACzD,IAAI9vB,EAASya,EACb,MAAM8gC,GAAoBC,EAAAA,EAAAA,GAAmB,CAC3Cx7C,SACA4C,UAEI64C,EAAuBt8C,OAAOC,KAAKm8C,GACnCG,EAA4B,CAAC,WAAY,SAAU,aAAc,WAAY,UAAW,aAAar3C,MACxGs3C,GAAaF,EAAqBnlB,SAASqlB,KAI5C/4C,IAAUgC,EAAAA,GAAMg3C,QAChBC,EAAAA,EAAAA,IAA6B,CAC3BtuC,2BAA4BA,EAC5BuuC,cAAe1kB,EAAcrE,OAAO4d,SAAyC,EAA9BvZ,EAAcrE,OAAOzY,WAG1CohC,IAC5B17C,EAAS,IAAKA,KAAW+7C,EAAAA,KAQ3B,OALExuC,IAA+Bq7B,EAAAA,GAA2BC,WAA6C,IAAhCzR,EAAcrE,OAAOzY,SAC9DohC,IAC9B17C,EAAS,IAAKA,KAAWg8C,EAAAA,MAA0BT,IAG9Cv7C,CACT,CAEAmnC,oBAAAA,GACE,OAAOjrC,KAAKqR,6BAA+Bq7B,EAAAA,GAA2ByS,YAAaY,EAAAA,EAAAA,IAAiB//C,KACtG,EAGFspC,EAAUxiC,YAEV,UC9yEA,MAAMwP,UAAoBhM,EACxBiT,YAAclH,EAAAA,GAAiBC,YAC/BiH,aAAe,SACfA,gBAAkB,iBAElByiC,sBAAAA,CAAsBr4C,GAA0E,IAAzE,MAAE1F,EAAK,oBAAEg+C,EAAmB,iBAAEC,GAAyCv4C,EAC5F,MAAM,UAAEw4C,EAAS,QAAEC,EAAO,WAAEC,EAAU,SAAEC,EAAQ,SAAEC,EAAQ,OAAEC,GAAWP,EACjE3S,EAAOttC,KAAK4E,KAAK0oC,KAAKrrC,GACtBm5B,EAAQp7B,KAAK4E,KAAKw2B,MAAMn5B,GACxB+4C,EAAa5f,EAAQkS,EAAO6S,EAAYC,EACxCK,EAAYrlB,EAAQkS,EAAOiT,EAAWC,EAC5C,MAAO,CACLlT,OACAlS,QACAjf,KAAMnc,KAAK4E,KAAKuX,KAAKla,GACrB8mC,IAAK/oC,KAAK4E,KAAKmkC,IAAI9mC,GACnBy+C,aAAc1F,EACdpW,YAAaxJ,EAAQkS,EAAO+S,EAAaC,EACzCG,UAAWP,EAAmBO,EAAYzF,EAE9C,CAEAjQ,WAAAA,GACE,GAAI/qC,KAAKm3C,qBAAuBn3C,KAAK4E,KAAK6P,UACxC,OAEF,MAAM,cAAEymB,GAAkBl7B,KAAKqe,yBACzBE,EAASve,KAAKo/C,sCACd,aAAEuB,EAAY,eAAEC,IAAmBC,EAAAA,EAAAA,IAA6B,CACpE7vC,YAAahR,KAAK0B,MAAMkyB,eACxB+gB,WAAY30C,KAAK0B,MAAMizC,aAEnBmM,EACJH,EAAgC,EAAjBC,GAAsB,KACnC5gD,KAAK2V,OAASU,EAAAA,GAAiBK,mBAAwC,IAAnBkqC,GAClD3hC,GAAYiwB,EAAAA,EAAAA,IAAa,CAC7BxwB,QAAS1e,KAAK0e,QACd+Q,QAASzvB,KAAKirB,WAAaiQ,EAAczU,KAAKjf,MAC9CkoB,QAASwL,EAAc5U,IAAI7e,SAEvBs5C,GAAmB7R,EAAAA,EAAAA,IAAa,CACpCxwB,QAAS1e,KAAK0e,QACd+Q,QAASuxB,GACTtxB,QAAS,IAGXzQ,EAAUkwB,MACVqI,EAAAA,EAAAA,IAAkB,CAChB7tC,MAAO3J,KAAK4E,KACZmC,UAAW/G,KAAK+G,UAChBkkB,WAAYjrB,KAAKirB,WACjBzjB,MAAOxH,KAAKwH,MACZiwC,gBAAiBA,CAACv1B,EAAW2U,KAC3B,MAAM,KAAEyW,EAAI,MAAElS,EAAK,KAAEjf,EAAI,IAAE4sB,EAAG,UAAE0X,EAAS,YAAE7b,EAAW,aAAE8b,GAAiB1gD,KAAKggD,uBAAuB,CACnG/9C,MAAOigB,EACP+9B,oBAAqB1hC,EACrB2hC,iBAAkBY,IAGdG,EAAiB5hC,KAAK2E,MAAMhkB,KAAKoiB,GAAG2nB,EAAAA,GAAMllB,IAAIyoB,EAAMlS,KACpD8lB,EAAgB7hC,KAAK2E,MAAMhkB,KAAKoiB,GAAG2nB,EAAAA,GAAMrlB,IAAI4oB,EAAMlS,KACnD+lB,EAAiB9hC,KAAK2E,MAAMhkB,KAAKoiB,GAAGjG,IACpCilC,EAAgB/hC,KAAK2E,MAAMhkB,KAAKoiB,GAAG2mB,IAEnCsY,EAAmBH,EAAgBD,EACnCK,EAAkBzqB,EAASxX,KAAK+E,MAAMw8B,EAAiBD,EAAe,GACtEY,EAAkBX,EAAiB,EAIzC,IAAIY,EAAAA,EAAAA,OAAcF,EAAkBthD,KAAKirB,WAAa,EACpD,OAGF,MAAMw2B,EAAoCJ,GAAqC,EAAjBT,EACxDc,GAAoCZ,GAA6BM,EAAgBD,EAAiB,EAiBxG,GAfAJ,EAAiB5R,KACjBnvC,KAAK0e,QAAQS,IAAI,cAAeshC,GAChCzgD,KAAK0e,QAAQQ,YACblf,KAAK0e,QAAQa,OAAOsX,EAAQsqB,GACxBL,IACF9gD,KAAK0e,QAAQc,OAAOqX,EAAQoqB,GAC5BjhD,KAAK0e,QAAQa,OACXsX,EACAoqB,GAAkBQ,EAAoCJ,EAvF/C,KA0FXrhD,KAAK0e,QAAQc,OAAOqX,EAAQ6qB,EAAmCP,EAAiB,EAAIC,GACpFphD,KAAK0e,QAAQe,SACbshC,EAAiB9P,OAEb6P,EAA2B,CAC7B,MAAMa,EAAYf,EAAiB,EAC/Be,IACF3hD,KAAK0e,QAAQS,IAAI,cAAeylB,GAC5B6c,GACFzhD,KAAK0e,QAAQS,IAAI,YAAayhC,GAC9B5gD,KAAK0e,QAAQwkB,WACXoe,EAAkBC,EAClBN,EAAiBM,EACjBZ,EAAe,EAAIY,EACnBF,EAAmB,EAAIE,GAEzBvhD,KAAK0e,QAAQS,IAAI,YA1GZ,KA4GLnf,KAAK0e,QAAQQ,YACblf,KAAK0e,QAAQa,OAAO+hC,EAAiBL,EAAiBD,IACtDhhD,KAAK0e,QAAQc,OAAO8hC,EAAkBX,EAAe,EAAIC,EAAgBK,EAAiBD,IAC1FhhD,KAAK0e,QAAQe,WAIjB,MAAMmiC,EAAaP,EAAmB,EAAIT,EACpCiB,EAAUD,EAAa,GACzBC,GAAYF,IACd3hD,KAAK0e,QAAQS,IAAI,YAAa0iC,EAAUnB,EAAe9b,GACvD5kC,KAAK0e,QAAQoe,SACXwkB,EAAkBV,EAClBK,EAAiBL,EACjBD,EACAkB,EAAUD,EA3HL,GA8HX,KAGJ3iC,EAAUgyB,MACZ,CAEA1sC,QAAAA,GACE,MAAQ,gBAAevE,KAAK4E,KAAKgnC,QACnC,EAGF,UC9IA,MAAMl1B,UAA0BJ,EAC9BiH,YAAclH,EAAAA,GAAiBK,kBAC/B6G,aAAe,gBACfA,gBAAkB,kBAElB,yBAAOkU,CAAmB3vB,GACxB,OAAOud,KAAKwF,IAAI,EAAG5a,MAAMwnB,mBAAmB3vB,GAC9C,CAEAk+C,sBAAAA,CAAsBr4C,GAAwD,IAAvD,MAAE1F,EAAK,oBAAEg+C,GAA4Ct4C,EAC1E,MAAM2lC,EAAOttC,KAAK4E,KAAK0oC,KAAKrrC,GACtBm5B,EAAQp7B,KAAK4E,KAAKw2B,MAAMn5B,GACxB6/C,EAAW1mB,EAAQkS,EACnByU,EACJ3mB,EAAQp7B,KAAK4E,KAAKw2B,MAAMn5B,EAAQ,GAAKg+C,EAAoB+B,YAAc/B,EAAoBgC,cACvFjH,EAAuB,IAAV/4C,EAAcg+C,EAAoBiC,WAAaH,EAClE,MAAO,CACLzU,OACAlS,QACAjf,KAAMnc,KAAK4E,KAAKuX,KAAKla,GACrB8mC,IAAK/oC,KAAK4E,KAAKmkC,IAAI9mC,GAEnBy+C,aAAcoB,EAAW,mBAAqB9G,EAC9CpW,YAAaoW,EACbyF,UAAWzF,EAEf,CAEAz2C,QAAAA,GACE,MAAQ,uBAAsBvE,KAAK4E,KAAKgnC,QAC1C,EAGF,UC7BA,MAAMp1B,UAAmBF,EACvBiH,YAAclH,EAAAA,GAAiBG,WAC/B+G,aAAe,cACfA,gBAAkB,sBAElB,yBAAOkU,CAAmB3vB,GACxB,OAAOud,KAAKwF,IAAI,EAAG5a,MAAMwnB,mBAAmB3vB,GAC9C,CAEAk+C,uBAAyBr4C,IAA6E,IAA5E,MAAE1F,EAAK,oBAAEg+C,EAAmB,iBAAEC,GAAyCv4C,EAC/F,MAAMw6C,EAASniD,KAAK4E,KAAKw9C,oBAEnB9U,EAAO6U,EAAO7U,KAAKrrC,GACnBm5B,EAAQ+mB,EAAO/mB,MAAMn5B,GACrB+4C,EAAa5f,EAAQkS,EAAO2S,EAAoBE,UAAYF,EAAoBG,QAChFK,EAAYrlB,EAAQkS,EAAO2S,EAAoBM,SAAWN,EAAoBO,OACpF,MAAO,CACLlT,OACAlS,QACAjf,KAAMkD,KAAKwF,IAAI7kB,KAAK4E,KAAKuX,KAAKla,GAAQqrC,EAAMlS,GAC5C2N,IAAK1pB,KAAKqF,IAAI4oB,EAAMlS,EAAOp7B,KAAK4E,KAAKmkC,IAAI9mC,IACzCy+C,aAAc1F,EACdpW,YAAaxJ,EAAQkS,EAAO2S,EAAoBI,WAAaJ,EAAoBK,SACjFG,UAAWP,EAAmBO,EAAYzF,EAC3C,EAGHqH,cAAgBA,KACd,MAAM9jC,EAASve,KAAKo/C,sCAElB9R,KAAMU,EACN5S,MAAOH,EACP9e,KAAM8xB,EACNlF,IAAKmF,GACHluC,KAAKggD,uBAAuB,CAC9B/9C,MAAOjC,KAAK4E,KAAK4iC,KAAKvnC,OAAS,EAC/BggD,oBAAqB1hC,IAGvB,MAAO,CAAEyvB,WAAU/S,YAAWgT,WAAUC,UAAS,EAGnDH,kBAAAA,GACE,MAAMrE,EAAW1pC,KAAKqiD,gBACtB,MAAO,CACL/U,KAAMttC,KAAK0tC,UAAUhE,EAASsE,UAC9B7xB,KAAMnc,KAAK0tC,UAAUhE,EAASuE,UAC9BlF,IAAK/oC,KAAK0tC,UAAUhE,EAASwE,SAC7B9S,MAAOp7B,KAAK0tC,UAAUhE,EAASzO,WAEnC,CAEAkP,YAAezrB,IACb,MAAM,UAAEuc,GAAcj7B,KAAKqiD,gBAC3Bp4C,MAAMkgC,YAAYzrB,EAAS,CAAEuc,cAAa,GAE1C,MAAM,kBAAE2T,GAAsB5uC,KAAKsvC,YACnC,GAAItvC,KAAK0B,MAAMyV,QAAUE,EAAAA,GAAUG,aAAeo3B,EAAmB,OAErE,MAAM0T,EAAsBtiD,KAAK4E,KAAKw2B,MAAMp7B,KAAK4E,KAAKw2B,MAAMn7B,OAAS,GAC/DsiD,EAAyBviD,KAAK2uC,uBAAuB,CAAE1T,YAAW2T,sBAClE4T,EAA2BxiD,KAAK2uC,uBAAuB,CAAE1T,UAAWqnB,EAAqB1T,sBAE/F5uC,KAAKkxC,iBAAiB,CAAExyB,UAASyyB,YAAa9xB,KAAK2E,MAAMhkB,KAAKoiB,GAAG6Y,IAAansB,MAAOyzC,IAEjFA,IAA2BC,GAE/BxiD,KAAKkxC,iBAAiB,CACpBxyB,UACAyyB,YAAanxC,KAAKwxC,kCAAkC,CAClDC,eAAgBxW,EAChByW,oBAAqB4Q,IAEvBxzC,MAAO0zC,EACP97B,WAAY1mB,KAAKoxC,oCACjB,EAGJoH,mBAAAA,CAAoBC,EAAoB9qC,GAAoD,IAAlC+qC,IAAyBt3C,UAAAnB,OAAA,QAAAoI,IAAAjH,UAAA,KAAAA,UAAA,GACjF,MAAMmd,EAASve,KAAKo/C,qCACdhjB,EAAWp8B,KAAK4E,KAAKm0C,uBAAuBN,GAClD,GAAIrc,GAAY,EAAG,CACjB,IAAIxuB,EAAQ,KACZ,GAAI,CAAC,OAAQ,MAAO,OAAQ,SAASwsB,SAASzsB,GAAM,CAElDC,EADa5N,KAAKggD,uBAAuB,CAAE/9C,MAAOm6B,EAAU6jB,oBAAqB1hC,IACpE5Q,EACf,CAEA,GADAC,EAAkB,OAAVA,EAAiB5N,KAAK4E,KAAKg0C,kBAAkBjrC,EAAK8qC,GAAc7qC,EAC1D,OAAVA,EACF,OAAO8qC,EAA4B14C,KAAK0tC,UAAU9/B,GAAU,GAAEA,GAElE,CACF,CAEAirC,mBAAAA,CAAoBJ,GAClB,MAAMrc,EAAWp8B,KAAK4E,KAAKm0C,uBAAuBN,GAC5C0J,EAASniD,KAAK4E,KAAKw9C,oBACnBpJ,EAAamJ,EAAO/mB,MAAMgB,IAAa,KACvC6c,EAAgBkJ,EAAO/mB,MAAMgB,EAAW,IAAM,KACpD,OAAmB,OAAf4c,GAAyC,OAAlBC,GAClBC,EAAAA,EAAAA,IAA+B,CAAEt0C,KAAM5E,KAAK4E,KAAMu0C,YAAaH,EAAYI,UAAWH,IAGxF,IACT,CAEA10C,QAAAA,GACE,MAAQ,mBAAkBvE,KAAK4E,KAAKgnC,QACtC,EAGF,UClHA,MAAMh1B,UAAkBtM,EACtBiT,YAAclH,EAAAA,GAAiBO,UAC/B2G,aAAe,OACfA,gBAAkB,gBAElBwtB,WAAAA,GACE,MAAM,cAAE7P,GAAkBl7B,KAAKqe,0BACzB,OAAEE,GAAW2c,EAAc2Q,QACjC,IAAI4W,EAA2B1iD,EAC/B,MAAMkf,GAAYiwB,EAAAA,EAAAA,IAAa,CAC7BxwB,QAAS1e,KAAK0e,QACd+Q,QAASzvB,KAAKirB,WAAaiQ,EAAczU,KAAKjf,MAAQ,GACtDkoB,QAASwL,EAAc5U,IAAI7e,OAAS,KAEtCwX,EAAUkwB,KACVnvC,KAAK0e,QAAQQ,YACblf,KAAK0e,QAAQS,IAAI,YAAa,GAC9Bnf,KAAK0e,QAAQS,IAAI,cAAeZ,EAAO5H,OACvC6gC,EAAAA,EAAAA,IAAkB,CAChB7tC,MAAO3J,KAAK4E,KACZmC,UAAW/G,KAAK+G,UAChBkkB,WAAYjrB,KAAKirB,WACjBzjB,MAAOxH,KAAKwH,MACZiwC,gBAAiBA,CAACv1B,EAAW1D,KAC3B,MAAMC,EAAIY,KAAK2E,MAAMhkB,KAAKoiB,GAAGpiB,KAAK4E,KAAKw2B,MAAMlZ,KAC7CliB,KAAK0e,QAAQc,OAAOhB,EAAGC,GACvB1e,EAAOye,OACOnW,IAAVo6C,IACFA,EAAQjkC,EACV,SAGUnW,IAAVo6C,QAAgCp6C,IAATtI,IACzBC,KAAK0e,QAAQe,SACbzf,KAAK0e,QAAQS,IAAI,YAAaZ,EAAOmI,YACrC1mB,KAAK0e,QAAQc,OAAOzf,EAAOC,KAAKyH,QAChCzH,KAAK0e,QAAQc,OAAOijC,EAAQziD,KAAKyH,QACjCzH,KAAK0e,QAAQkD,QAGf3C,EAAUgyB,MACZ,CAEA1sC,QAAAA,GACE,MAAQ,cAAavE,KAAK4E,KAAKgnC,QACjC,EAGF,UC1CM8W,EAAU,iBAEVC,EAAY,iBAElB,MAAMxQ,UAAwB7nC,EAC5BiT,YAAclH,EAAAA,GAAiB87B,gBAE/B,gBAAOrrC,GACL7D,OAAOkwB,eAAenzB,KAAKF,UAAW,QAAS,CAC7CozB,GAAAA,GACE,MAAM,wBAAE0vB,GAA4B5iD,KAAKqe,yBACzC,OAAOre,KAAK0B,MAAM8F,MAAQo7C,EAAwBn8B,KAAKjf,MAAQo7C,EAAwBr8B,MAAM/e,KAC/F,IAGFvE,OAAOkwB,eAAenzB,KAAKF,UAAW,SAAU,CAC9CozB,GAAAA,GACE,MAAM,wBAAE0vB,GAA4B5iD,KAAKqe,yBACzC,OAAOre,KAAK+G,UAAUU,OAASm7C,EAAwBt8B,IAAI7e,OAASm7C,EAAwBp8B,OAAO/e,MACrG,GAEJ,CAKAtE,WAAAA,CAAY+E,EAAiCxG,GAC3CuI,MAAM/B,EAAQxG,GACd1B,KAAK8nB,WAAa9nB,KAAK8nB,WAAWnnB,KAAKX,MACvCA,KAAKsqC,qBAAuBtqC,KAAKsqC,qBAAqB3pC,KAAKX,MAC3DA,KAAKmqC,YAAcnqC,KAAKmqC,YAAYxpC,KAAKX,MACzCA,KAAKqqC,WAAarqC,KAAKqqC,WAAW1pC,KAAKX,KACzC,CAEAqqC,UAAAA,GAEE,GADApgC,MAAMogC,cACDrqC,KAAK4E,KACR,OAEF,MAAM+H,EAAgB,GACtB3M,KAAK4E,KAAKw2B,MAAM7yB,SAAQ,CAACs6C,EAAK3gC,KAC5BvV,EAAIuV,GAAK2gC,EAAM7iD,KAAK4E,KAAKu3B,OAAOja,EAAE,IAEpCliB,KAAK8iD,MAAQn2C,EAEb,IAAIo2C,EAAY,KAChB,IAAK,IAAI7gC,EAAIliB,KAAK4E,KAAKu3B,OAAOl8B,OAAS,EAAGiiB,GAAK,EAAGA,IAChD,GAA4B,IAAxBliB,KAAK4E,KAAKu3B,OAAOja,GAAU,CAC7B6gC,EAAY7gC,EACZ,KACF,CAEFliB,KAAKgjD,eACW,OAAdD,EACI,KACA1jC,KAAKqF,IAAIq+B,EAAW1jC,KAAK2E,OAAOhkB,KAAK4E,KAAKowC,kBAAoBh1C,KAAK4E,KAAKuvC,oBA3DjE,GA4Df,CAEApJ,WAAAA,GACE,MAAM,wBAAE6X,GAA4B5iD,KAAKqe,yBACnCY,GAAYiwB,EAAAA,EAAAA,IAAa,CAC7BxwB,QAAS1e,KAAK0e,QACd+Q,QAASzvB,KAAKirB,WAAa23B,EAAwBn8B,KAAKjf,MAAQ,GAChEkoB,QAASkzB,EAAwBt8B,IAAI7e,OAAS,KAEhDwX,EAAUkwB,KACVnvC,KAAKijD,mBAAmBjjD,KAAK0e,QAAS1e,KAAK8iD,MAAO,EAAG,EAAG,GACxD7jC,EAAUgyB,MACZ,CAEAgS,kBAAAA,CACEvkC,EACAwkC,EACAnuB,EACAouB,EACAC,GAEA,GAA4B,OAAxBpjD,KAAKgjD,eACP,OAEF,MAAMK,GAAa9uC,EAAAA,EAAAA,OACb,cAAE2mB,GAAkBl7B,KAAKqe,0BACzB,OAAEE,GAAW2c,EAAc2Q,QAE3BzoB,EAAS,CAtFD,GADA,GAyFd1E,EAAQiR,OACRjR,EAAQQ,YACRR,EAAQilB,MACL3jC,KAAKirB,WACNjrB,KAAKoiB,GAAGgB,EAAO,IACfpjB,KAAKmiB,GAAGniB,KAAKgjD,gBACb3jC,KAAK2E,MAAMhkB,KAAKoiB,GAAG+gC,GAAYnjD,KAAKoiB,GAAGgB,EAAO,KAAO,IAEvD1E,EAAQysB,OACRzsB,EAAQS,IAAI,YAhGJ,0BAiGRT,EAAQS,IAAI,cAAekkC,EAAa9kC,EAAO+kC,WAAaZ,GAC5DhkC,EAAQQ,YACRR,EAAQa,OAAOvf,KAAKmiB,GAAG,GAAI9C,KAAK2E,MAAMhkB,KAAKoiB,GAAGgB,EAAO,MACrD,IAAK,IAAIlB,EAAI6S,EAAM7S,EAAIliB,KAAK4E,KAAKw2B,MAAMn7B,OAAQiiB,IAC7CxD,EAAQc,OAAOxf,KAAKmiB,GAAGD,GAAI7C,KAAK2E,MAAMhkB,KAAKoiB,GAAG8gC,EAAMhhC,MAEtDxD,EAAQc,OAAOxf,KAAKmiB,GAAGniB,KAAK4E,KAAKw2B,MAAMn7B,OAAS,GAAIof,KAAK2E,MAAMhkB,KAAKoiB,GAAGgB,EAAO,MAC9E1E,EAAQkD,OACRlD,EAAQe,SACRf,EAAQmR,UAERnR,EAAQiR,OACRjR,EAAQQ,YACRR,EAAQilB,MACL3jC,KAAKirB,WACNjrB,KAAKoiB,GAAGgB,EAAO,IACfpjB,KAAKmiB,GAAGniB,KAAKgjD,gBACb3jC,KAAK2E,MAAMhkB,KAAKoiB,GAAGghC,IAAe,IAEpC1kC,EAAQysB,OACRzsB,EAAQS,IAAI,YAnHF,0BAoHVT,EAAQS,IAAI,cAAekkC,EAAa9kC,EAAOglC,SAAWZ,GAC1DjkC,EAAQQ,YACRR,EAAQa,OAAOvf,KAAKmiB,GAAG,GAAI9C,KAAK2E,MAAMhkB,KAAKoiB,GAAGgB,EAAO,MACrD,IAAK,IAAIlB,EAAI6S,EAAM7S,EAAIliB,KAAK4E,KAAKw2B,MAAMn7B,OAAQiiB,IAC7CxD,EAAQc,OAAOxf,KAAKmiB,GAAGD,GAAI7C,KAAK2E,MAAMhkB,KAAKoiB,GAAG8gC,EAAMhhC,MAEtDxD,EAAQc,OAAOxf,KAAKmiB,GAAGniB,KAAK4E,KAAKw2B,MAAMn7B,OAAS,GAAIof,KAAK2E,MAAMhkB,KAAKoiB,GAAGgB,EAAO,MAC9E1E,EAAQkD,OACRlD,EAAQe,SACRf,EAAQmR,SACV,CAEA4b,WAAAA,GACE,MAAM,wBAAEmX,GAA4B5iD,KAAKqe,0BACnC,OAAEE,GAAWqkC,EAAwB/W,QACrC5sB,GAAYiwB,EAAAA,EAAAA,IAAa,CAC7BxwB,QAAS1e,KAAK0e,QACd+Q,QAASzvB,KAAKirB,WAAa23B,EAAwBn8B,KAAKjf,MACxDkoB,QAASkzB,EAAwBt8B,IAAI7e,SAEvCwX,EAAUkwB,KAEV,MAAMoF,EAAQv0C,KAAKw0C,WACb3uB,EAAO,IAAIL,EAAAA,EACf,CACE/G,EAAGze,KAAKyH,OAAS,GACjBqe,KAAM,CAAEtW,KAAM,GACdyW,UAAW1H,EAAOsH,KAClBO,aAAcsQ,EAAAA,GAAalQ,OAC3BL,UAAWyQ,EAAAA,GAAUC,QAEvB72B,KAAK+G,WAEP,IAAIyX,EAEJA,EAAIxe,KAAKmiB,GAAG,GACZoyB,EAAMp1B,IAAI,CAAErB,GAAIU,EAAGR,GAAIQ,IAAKqJ,OAAO7nB,KAAK0e,SAExCF,EAAIxe,KAAKmiB,GAAG,IAAM,EAClB0D,EAAK1G,IAAI,CAAE0G,KAAM,OAAQrH,MAAKqJ,OAAO7nB,KAAK0e,SAC1C61B,EAAMp1B,IAAI,CAAErB,GAAIU,EAAGR,GAAIQ,IAAKqJ,OAAO7nB,KAAK0e,SAExCF,EAAIxe,KAAKmiB,GAAG,IACZoyB,EAAMp1B,IAAI,CAAErB,GAAIU,EAAGR,GAAIQ,IAAKqJ,OAAO7nB,KAAK0e,SAExCF,EAAIxe,KAAKmiB,GAAG,IACZ0D,EAAK1G,IAAI,CAAE0G,KAAM,OAAQrH,MAAKqJ,OAAO7nB,KAAK0e,SAC1C61B,EAAMp1B,IAAI,CAAErB,GAAIU,EAAGR,GAAIQ,IAAKqJ,OAAO7nB,KAAK0e,SAExCF,EAAIxe,KAAKmiB,GAAG,IACZoyB,EAAMp1B,IAAI,CAAErB,GAAIU,EAAGR,GAAIQ,IAAKqJ,OAAO7nB,KAAK0e,SAExCF,EAAIxe,KAAKmiB,GAAG,IACZ0D,EAAK1G,IAAI,CAAE0G,KAAM,MAAOrH,MAAKqJ,OAAO7nB,KAAK0e,SACzC61B,EAAMp1B,IAAI,CAAErB,GAAIU,EAAGR,GAAIQ,IAAKqJ,OAAO7nB,KAAK0e,SAExCF,EAAIxe,KAAKmiB,GAAG,KACZoyB,EAAMp1B,IAAI,CAAErB,GAAIU,EAAGR,GAAIQ,IAAKqJ,OAAO7nB,KAAK0e,SAExCF,EAAIxe,KAAKmiB,GAAG,KACZ0D,EAAK1G,IAAI,CAAE0G,KAAM,MAAOrH,MAAKqJ,OAAO7nB,KAAK0e,SACzC61B,EAAMp1B,IAAI,CAAErB,GAAIU,EAAGR,GAAIQ,IAAKqJ,OAAO7nB,KAAK0e,SAExCO,EAAUgyB,MACZ,CAEAnpB,UAAAA,GAAc,CAEdsiB,eAAAA,GAAmB,CAEnBE,oBAAAA,GAAwB,CAExBkZ,QAAAA,GACE,MAAO,CAAE9+B,KAjMK,EAiMWG,IAhMX,EAiMhB,CAEA4+B,oBAAAA,GACE,OAAOzjD,KAAKwjD,UACd,CAEArZ,WAAAA,CAAYzrB,GACV,MAAM,wBAAEkkC,EAAuB,cAAE1nB,GAAkBl7B,KAAKqe,0BAClD,OAAEE,GAAW2c,EAAc2Q,QAC3BwX,GAAa9uC,EAAAA,EAAAA,MACb0K,GAAYiwB,EAAAA,EAAAA,IAAa,CAC7BxwB,QAAS1e,KAAK0e,QACd+Q,QAASmzB,EAAwBn8B,KAAKjf,MACtCkoB,QAASkzB,EAAwBt8B,IAAI7e,SAEvCwX,EAAUkwB,KAEV,MAAMuU,EAAQ1jD,KAAK8wC,WACnB,IAAK,MAAMd,IAAQ,EApNL,EAoNiB,EAnNjB,GAmNgC,CAC5C,MAAMvxB,EAAIY,KAAK2E,MAAMhkB,KAAKoiB,GAAG4tB,IAC7B0T,EAAMvkC,IAAI,CAAEpB,GAAIU,EAAGR,GAAIQ,IAAKoJ,OAAOnJ,EACrC,CAEA,MAAMmH,EAAO,IAAIL,EAAAA,EACf,CACEhH,EAAGxe,KAAKwH,MAAQ,GAChBse,KAAM,CAAEtW,KAAM,GACd4W,aAAcsQ,EAAAA,GAAaC,OAC3BxQ,UAAWyQ,EAAAA,GAAUrQ,OAEvBvmB,KAAK+G,WAGD48C,EAASN,EAAa9kC,EAAOglC,SAAWZ,EACxCiB,EAAWP,EAAa9kC,EAAO+kC,WAAaZ,EAC5C3iD,EAAOC,KAAK8iD,MAAM9iD,KAAKgjD,gBACvBa,EAAkC,OAAxB7jD,KAAKgjD,eAA0B3jC,KAAK+E,MAAa,GAAPrkB,EAAY,IAAM,GAC5E8lB,EAAK1G,IAAI,CAAEV,EAAGze,KAAKoiB,GAAG,GAAK,EAAG6D,UAAW09B,EAAQ99B,KAAO,GAAEg+B,OAAch8B,OAAOnJ,GAC/EmH,EAAK1G,IAAI,CAAEV,EAAGze,KAAKoiB,GAAG,GAAK,EAAG6D,UAAW29B,EAAU/9B,KAAS,IAAMg+B,EAAR,MAAsBh8B,OAAOnJ,GAEvFO,EAAUgyB,MACZ,CAEA9F,IAAAA,GACE,MAAM,wBAAEyX,GAA4B5iD,KAAKqe,yBACzCre,KAAK0e,QAAQQ,YACblf,KAAK0e,QAAQilB,KAAKif,EAAwBn8B,KAAKjf,MAAOo7C,EAAwBt8B,IAAI7e,OAAQzH,KAAKwH,MAAOxH,KAAKyH,QAC3GzH,KAAK0e,QAAQysB,MACf,CAEAmE,SAAAA,GACE,OAAOtvC,KAAKwjD,UACd,CAEA/M,gBAAAA,GAAoB,CAEpBrL,YAAAA,GAAgB,CAEhB7mC,QAAAA,GACE,MAAQ,wBACV,EAEF4tC,EAAgBrrC,YAEhB,U,eC1PA,MAAMg9C,EAAS,CAAC,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,OAE7F,MAAMC,UAAuBz5C,EAC3BiT,YAAclH,EAAAA,GAAiB0tC,eAC/BC,kBAA8B,GAE9B7gD,WAAAA,CAAY+E,EAAsCxG,GAChDuI,MAAM/B,EAAQxG,GACd1B,KAAK8nB,WAAa9nB,KAAK8nB,WAAWnnB,KAAKX,KACzC,CAEA+qC,WAAAA,GACE,MAAM,cAAE7P,EAAa,eAAE+oB,GAAmBjkD,KAAKqe,yBACzCY,GAAYiwB,EAAAA,EAAAA,IAAa,CAC7BxwB,QAAS1e,KAAK0e,QACd+Q,QAASzvB,KAAKirB,WAAaiQ,EAAczU,KAAKjf,MAAQ,GACtDkoB,QAASwL,EAAc5U,IAAI7e,OAAS,KAEtCwX,EAAUkwB,KAEVnvC,KAAK0e,QAAQS,IAAI,YAAa,GAE9B,MAAM+kC,EAA4B,CAAC,EACnC,IAAK,MAAMv6C,KAAS3J,KAAKmkD,YACvBD,EAAOv6C,EAAMiiC,QAAUjiC,EAGzB,IAAK,IAAI1H,EAAQjC,KAAK+C,MAAMqhD,QAAQnkD,OAAS,EAAGgC,GAAS,EAAGA,IAAS,CACnE,MACM0H,EAAQu6C,EADClkD,KAAK+C,MAAMqhD,QAAQniD,IAElCjC,KAAK0e,QAAQS,IAAI,cAAe8kC,EAAehiD,EAAQgiD,EAAehkD,SACtED,KAAK0e,QAAQQ,YACb,IAAK,IAAIgD,EAAI,EAAGmiC,EAAM16C,EAAMyxB,MAAMn7B,OAAQqkD,EAAMD,GAAO,EAAGC,EAAMpiC,EAAImiC,EAAMniC,EAAImiC,EAAKC,EAAMpiC,IAAMA,IAAK,CAClG,MAAM1D,EAAIxe,KAAKmiB,GAAGD,GAClB,GAAI1D,EAAIxe,KAAKirB,YAAc,IAAMzM,EAAIxe,KAAKirB,WAAajrB,KAAK0B,MAAM8F,MAAQ,GAExE,SAEF,MAAMiX,EAAIY,KAAK2E,MAAMhkB,KAAKoiB,GAAGzY,EAAMyxB,MAAMlZ,KACzCliB,KAAK0e,QAAQc,OAAOhB,EAAGC,EACzB,CACAze,KAAK0e,QAAQe,QACf,CAEAR,EAAUgyB,MACZ,CAEAnpB,UAAAA,CAAWpJ,GACT,MAAM,cAAEwc,GAAkBl7B,KAAKqe,0BACzB,OAAEE,GAAW2c,EAAc2Q,QAC3BhmB,EAAO7lB,KAAK+C,MAAM+L,OAAS,GAC3B2P,GAAKze,KAAKyH,OAAS,GAAK,EAc9B,OAbA,IAAI+d,EAAAA,EACF,CACEK,OACArH,EAAG,GACHC,EAAGyc,EAAc5U,IAAI7e,OAASgX,EAC9BW,OAAQ,GACR0G,KAAM,CAAEtW,KAAM,GAAIwW,OAAQ,MAAOD,OAAQ,oBACzCE,UAAW1H,EAAOguB,cAClBpmB,UAAWyQ,EAAAA,GAAUC,OACrBzQ,aAAcsQ,EAAAA,GAAauN,YAE7BjkC,KAAK+G,WACL8gB,OAAOnJ,GACF1e,KAAKoqC,gBAAgB1rB,EAAS1e,KAAK4E,KAAKw2B,MAAMn7B,OAAS,EAChE,CAEAmqC,eAAAA,CAAgB1rB,EAAmC+5B,GACjD,MAAM,cAAEvd,EAAa,eAAE+oB,GAAmBjkD,KAAKqe,0BACzC,OAAEE,GAAW2c,EAAc2Q,QAC3B0Y,EAAkBxa,EAAAA,GAAMllB,IAAI7kB,KAAK+C,MAAMqhD,QAAQ12C,KAAKq1B,GAAMA,EAAE9iC,UAE5DunC,EAAOuC,EAAAA,GAAAA,sBAA4B/pC,KAAK4E,KAAKg0C,kBAAkB,OAAQH,IAAe,GACtF/Q,EAAQF,EAAKG,WACbC,EAAOJ,EAAKK,cACZC,EAAMN,EAAKO,UACXyc,EAAa/L,IAAez4C,KAAK4E,KAAKw2B,MAAMn7B,OAAS,EAE3D,IAAIulB,EAAAA,EACF,CACEK,KAAO,GAAEi+B,EAAOpc,MAAUI,KAAOF,iBACjCppB,EAAG0c,EAAczU,KAAKjf,OAAS+8C,EAAkB,GAAK,IAAM,KAC5D9lC,EAAG,GACHqH,KAAM,CAAEtW,KAAM,GACdyW,UAAW1H,EAAOsH,KAClBa,WAAYnI,EAAOu8B,YAErB96C,KAAK+G,WACL8gB,OAAOnJ,GAET,MAAMwlC,EAA4B,CAAC,EACnC,IAAK,MAAMv6C,KAAS3J,KAAKmkD,YACvBD,EAAOv6C,EAAMiiC,QAAUjiC,EAEzB,IAAK,IAAI1H,EAAQ,EAAGA,EAAQjC,KAAK+C,MAAMqhD,QAAQnkD,OAAQgC,IAAS,CAC9D,MAAMwc,EAAIkJ,EAAAA,GAAQC,GAAKD,EAAAA,GAAQC,EAAIgqB,EAAAA,GAAY/E,GAAK5qC,EAChDjC,KAAKgkD,kBAAkB/hD,KACzByc,EAAQuH,UAAY1H,EAAOu8B,WAC3Bp8B,EAAQoe,SACN5B,EAAczU,KAAKjf,MAAQmgB,EAAAA,GAAQ8b,KACnChlB,EAAIkJ,EAAAA,GAAQ8b,KACZ9b,EAAAA,GAAQ8b,KAAOzjC,KAAKgkD,kBAAkB/hD,GAAS0lB,EAAAA,GAAQ8b,KACvD9b,EAAAA,GAAQ8b,KAAOsI,EAAAA,GAAUc,EAAIllB,EAAAA,GAAQ8b,OAGzC,MAAMmI,EAAS5rC,KAAK+C,MAAMqhD,QAAQniD,GAC5BwiD,EAAaP,EAAOtY,GAAQxQ,MAAMqd,GAClC5yB,EAAO,IAAIL,EAAAA,EACf,CACEK,KAAO,GAAE+lB,KAAgC,iBAAf6Y,EAA0BA,EAAW7gD,QAAQ,GAAK0xC,QAC5E92B,EAAG0c,EAAczU,KAAKjf,MACtBiX,IACAqH,KAAM,CAAEtW,KAAMu8B,EAAAA,GAAUc,EAAG12B,MAAO,QAClC+P,WAAY0rB,EAAAA,GAAY/E,EACxB5mB,UAAWg+B,EAAehiD,EAAQgiD,EAAehkD,QACjDkmB,UAAWyQ,EAAAA,GAAUnQ,KACrBL,aAAcsQ,EAAAA,GAAapQ,KAE7BtmB,KAAK+G,WAEHy9C,IACFxkD,KAAKgkD,kBAAkB/hD,GAAS4jB,EAAK8K,QAAQjS,IAE/CmH,EAAKgC,OAAOnJ,EACd,CACF,CAEA+kC,oBAAAA,GACE,IAAI/+B,EAAMZ,OAAO86B,UACb/5B,EAAMf,OAAO+6B,UAEjB,MAAM,WAAE5zB,GAAejrB,KAAK0B,MAAK,QAAAP,EAAAC,UAAAnB,OAJXykD,EAAM,IAAA7kD,MAAAsB,GAAAG,EAAA,EAAAA,EAAAH,EAAAG,IAANojD,EAAMpjD,GAAAF,UAAAE,GAK5B,IAAK,MAAMqL,KAAO+3C,EAChB,IAAK,IAAIxiC,EAAI,EAAGmiC,EAAM13C,EAAI1M,OAAQqkD,EAAMD,GAAO,EAAGC,EAAMpiC,EAAImiC,EAAMniC,EAAImiC,EAAKC,EAAMpiC,IAAMA,IAAK,CAC1F,MAAM2U,EAAS72B,KAAKmiB,GAAGD,GACnB2U,EAAS5L,EAAa,GAAK4L,EAAS5L,EAAajrB,KAAKwH,QAKtDkd,EAAM/X,EAAIuV,KACZwC,EAAM/X,EAAIuV,IAER2C,EAAMlY,EAAIuV,KACZ2C,EAAMlY,EAAIuV,IAEd,CAGF,MAAO,CAAEwC,MAAKG,MAChB,CAEAyqB,SAAAA,GACE,MAAM4U,EAASlkD,KAAKmkD,YACpB,IAAI,IAAEz/B,EAAG,IAAEG,GAAQ7kB,KAAKyjD,wBAAwBS,EAAOx2C,KAAKi3C,GAAMA,EAAEvpB,SAOpE,YAN8B,IAAnBp7B,KAAK+C,MAAM2hB,MACpBA,EAAM1kB,KAAK+C,MAAM2hB,UAEW,IAAnB1kB,KAAK+C,MAAM8hB,MACpBA,EAAM7kB,KAAK+C,MAAM8hB,KAEZ,CAAEH,MAAKG,MAChB,CAEA4xB,gBAAAA,GAAoB,CAEpBrL,YAAAA,GAAgB,CAEhB+Y,SAAAA,GACE,OAAO35C,EAAAA,EAAMo6C,QACVD,GACC3kD,KAAK+C,MAAMqhD,QAAQhqB,SAASuqB,EAAE/Y,SAC9B+Y,EAAElwC,YAAczU,KAAK4E,MAAM6P,WAC3BzU,KAAK0B,MAAMkyB,eAAeixB,SAASF,EAAEG,SAE3C,CAEAvgD,QAAAA,GACE,MAAQ,cAAavE,KAAK4E,KAAKgnC,QACjC,EAGF,UCjMA,MAAMmZ,UAAkBz6C,EACtBiT,YAAclH,EAAAA,GAAiBS,UAC/ByG,aAAe,OACfA,gBAAkB,gBAElBwtB,WAAAA,GACE,MAAM,cAAE7P,GAAkBl7B,KAAKqe,0BACzB,OAAEE,GAAW2c,EAAc2Q,QAC3B5sB,GAAYiwB,EAAAA,EAAAA,IAAa,CAC7BxwB,QAAS1e,KAAK0e,QACd+Q,QAASzvB,KAAKirB,WAAaiQ,EAAczU,KAAKjf,MAC9CkoB,QAASwL,EAAc5U,IAAI7e,SAE7BwX,EAAUkwB,KAEV,MAAM6V,GAAwBzN,EAAAA,EAAAA,IAAyBv3C,KAAK0B,OAE5D,IAAIsd,EAAY,EACZgmC,GAAyB,GAC3BhmC,EAAY,EACHgmC,GAAyB,GAClChmC,EAAY,EACHgmC,GAAyB,KAClChmC,EAAY,GAEd,MAAMimC,EAAgBjmC,EAAY,EAC5BkmC,EAAuB7lC,KAAK2E,MAAMghC,EAAwB,EAAIC,GAC9DE,EAAanmC,EAAY,GAAM,EAAI,EAAI,GAC7Chf,KAAK0e,QAAQS,IAAI,YAAaH,IAE9Bw4B,EAAAA,EAAAA,IAAkB,CAChB7tC,MAAO3J,KAAK4E,KACZmC,UAAW/G,KAAK+G,UAChBkkB,WAAYjrB,KAAKirB,WACjBzjB,MAAOxH,KAAKwH,MACZiwC,gBAAiBA,CAACv1B,EAAW1D,KAC3B,MAAM4mC,KAAU5mC,EAAI,GAAK2mC,EAWzB,GATAnlD,KAAK0e,QAAQQ,YACblf,KAAK0e,QAAQS,IACX,cACAnf,KAAK4E,KAAKw2B,MAAMlZ,GAAKliB,KAAK4E,KAAK0oC,KAAKprB,GAAK3D,EAAO0jC,cAAgB1jC,EAAOyjC,aAGzEhiD,KAAK0e,QAAQa,OAAO6lC,EAAM/lC,KAAK2E,MAAMhkB,KAAKoiB,GAAGpiB,KAAK4E,KAAKuX,KAAK+F,MAC5DliB,KAAK0e,QAAQc,OAAO4lC,EAAM/lC,KAAK2E,MAAMhkB,KAAKoiB,GAAGpiB,KAAK4E,KAAKmkC,IAAI7mB,MAEvDgjC,GAAwB,EAAG,CAC7B,MAAM5X,EAAOjuB,KAAK2E,MAAMhkB,KAAKoiB,GAAGpiB,KAAK4E,KAAK0oC,KAAKprB,KAC/CliB,KAAK0e,QAAQa,OAAO6lC,EAAOH,EAAe3X,EAAO6X,GACjDnlD,KAAK0e,QAAQc,OAAO4lC,EAAOH,EAAgBC,EAAsB5X,EAAO6X,GAExE,MAAM/pB,EAAQ/b,KAAK2E,MAAMhkB,KAAKoiB,GAAGpiB,KAAK4E,KAAKw2B,MAAMlZ,KACjDliB,KAAK0e,QAAQa,OAAO6lC,EAAOH,EAAe7pB,EAAQ+pB,GAClDnlD,KAAK0e,QAAQc,OAAO4lC,EAAOH,EAAgBC,EAAsB9pB,EAAQ+pB,EAC3E,CAEAnlD,KAAK0e,QAAQe,QAAQ,IAIzBR,EAAUgyB,MACZ,CAEA1sC,QAAAA,GACE,MAAQ,QAAOvE,KAAK4E,KAAKgnC,QAC3B,EAGF,UChEMkY,EAAS,CAAC,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,OAW7F,MAAMuB,WAAkB/6C,EACtBiT,YAAclH,EAAAA,GAAiBgvC,UAE/BC,kBACAC,KAA6B,CAAC,EAE9BpiD,WAAAA,CAAY+E,EAAiCxG,GAC3CuI,MAAM/B,EAAQxG,GACd1B,KAAK8nB,WAAa9nB,KAAK8nB,WAAWnnB,KAAKX,MACvCA,KAAKsqC,qBAAuBtqC,KAAKsqC,qBAAqB3pC,KAAKX,MAC3DA,KAAKmqC,YAAcnqC,KAAKmqC,YAAYxpC,KAAKX,MACzCA,KAAKslD,kBAAoB,CAAC,CAC5B,CAEAva,WAAAA,GACE,MAAM,cAAE7P,EAAa,eAAE+oB,GAAmBjkD,KAAKqe,yBACzCY,GAAYiwB,EAAAA,EAAAA,IAAa,CAC7BxwB,QAAS1e,KAAK0e,QACd+Q,QAASzvB,KAAKirB,WAAaiQ,EAAczU,KAAKjf,MAAQ,GACtDkoB,QAASwL,EAAc5U,IAAI7e,OAAS,KAEtCwX,EAAUkwB,KAEVnvC,KAAK0e,QAAQQ,YACblf,KAAK0e,QAAQS,IAAI,YAAa,GAC9B,IAAK,IAAIld,EAAQ,EAAGA,EAAQjC,KAAK+C,MAAMqhD,QAAQnkD,OAAQgC,IAAS,CAC9D,MAAM2pC,EAAS5rC,KAAK+C,MAAMqhD,QAAQniD,GAClC,IAA0B,MAArBjC,KAAKulD,KAAK3Z,GAAkB5rC,KAAKulD,KAAK3Z,GAAQ3rC,OAAS,GAAK,EAAG,CAClED,KAAK0e,QAAQS,IAAI,cAAe8kC,EAAehiD,EAAQgiD,EAAehkD,SACtED,KAAK0e,QAAQQ,YACb,IAAK,IAAIgD,EAAI,EAAGmiC,EAAMrkD,KAAK4E,KAAKw2B,MAAMn7B,OAAQqkD,EAAMD,GAAO,EAAGC,EAAMpiC,EAAImiC,EAAMniC,EAAImiC,EAAKC,EAAMpiC,IAAMA,IACjGliB,KAAK0e,QAAQc,OAAOxf,KAAKmiB,GAAGD,GAAI7C,KAAK2E,MAAMhkB,KAAKoiB,GAAGpiB,KAAKulD,KAAK3Z,GAAQ1pB,MAEvEliB,KAAK0e,QAAQe,QACf,CACF,CAEAR,EAAUgyB,MACZ,CAEAnpB,UAAAA,CAAWpJ,GACT,MAAM,cAAEwc,GAAkBl7B,KAAKqe,0BACzB,OAAEE,GAAW2c,EAAc2Q,QAC3B71B,EAAS,MACb,OAAQhW,KAAK0B,MAAMiI,QAAQ8K,WACzB,IAAK,IACH,MAAO,QACT,IAAK,IACH,MAAO,SACT,IAAK,IACH,MAAO,UACT,QACE,OAEL,EAXc,GAYTgK,GAAKze,KAAKyH,OAAS,GAAK,EAC9B,IAAI+d,EAAAA,EACF,CACEK,KAAM7P,EACNwI,EAAG,GACHC,EAAGyc,EAAc5U,IAAI7e,OAASgX,EAC9BW,OAAQ,GACR0G,KAAM,CAAEtW,KAAM,GAAIwW,OAAQ,MAAOD,OAAQ,oBACzCE,UAAW1H,EAAOguB,cAClBpmB,UAAWyQ,EAAAA,GAAUC,OACrBzQ,aAAcsQ,EAAAA,GAAauN,YAE7BjkC,KAAK+G,WACL8gB,OAAOnJ,EACX,CAEA0rB,eAAAA,CAAgB1rB,EAAmC+5B,GACjD,MAAM,cAAEvd,EAAa,eAAE+oB,GAAmBjkD,KAAKqe,0BACzC,OAAEE,GAAW2c,EAAc2Q,QAC3BrE,EAAOuC,EAAAA,GAAAA,sBAA4B/pC,KAAK4E,KAAKg0C,kBAAkB,OAAQH,IAAe,GAC5F,IAAIhR,EAAa,GACjB,MAAMC,EAAQF,EAAKG,WACbC,EAAOJ,EAAKK,cACZC,EAAMN,EAAKO,UACjB,OAAQ/nC,KAAK4E,KAAK6P,WAChB,IAAK,IACL,IAAK,IACHgzB,EAAc,GAAEqc,EAAOpc,MAAUI,IACjC,MACF,IAAK,IACHL,EAAc,GAAEqc,EAAOpc,MAAUE,IACjC,MACF,QACE,OAGJ,IAAI4d,GAAmB,EACvB,IAAK,IAAIvjD,EAAQ,EAAGA,EAAQjC,KAAK+C,MAAMqhD,QAAQnkD,OAAQgC,IAAS,CAC9D,MAAM2pC,EAAS5rC,KAAK+C,MAAMqhD,QAAQniD,GAC5BwjD,EAAazlD,KAAKulD,KAAK3Z,GAC7B,GAAI6Z,GAAYxlD,OAAQ,CACtBye,EAAQuH,UAAY1H,EAAOu8B,WAC3Bp8B,EAAQoe,SACN5B,EAAczU,KAAKjf,MAAQmgB,EAAAA,GAAQ8b,KACnCuI,EAAAA,GAAOa,GAAKd,EAAAA,GAAUc,EAAI6Y,EAAAA,GAAO9Y,IAAM3qC,EAAQ0lB,EAAAA,GAAQ8b,KACvD9b,EAAAA,GAAQ8b,KAAOzjC,KAAKslD,kBAAkB1Z,GAAUjkB,EAAAA,GAAQ8b,KACxD9b,EAAAA,GAAQ8b,KAAOsI,EAAAA,GAAUc,EAAIllB,EAAAA,GAAQ8b,MAEvC,MAAMkiB,EAAU7hC,OAAO0pB,SAASiY,EAAWhN,IACrCmN,EAAiBD,EAAW,GAAEF,EAAWhN,GAAY70C,QAAQ,MAAQ,GAC3E4hD,EAAmBA,GAAoBG,EACvC,IAAIngC,EAAAA,EACF,CACEK,KAAO,GAAE+lB,KAAUga,IACnBpnC,EAAG0c,EAAczU,KAAKjf,MACtBiX,EAAGutB,EAAAA,GAAOa,GAAKd,EAAAA,GAAUc,EAAI6Y,EAAAA,GAAO9Y,IAAM3qC,EAC1C6jB,KAAM,CAAEtW,KAAMu8B,EAAAA,GAAUc,EAAG12B,MAAO,QAClC8P,UAAWg+B,EAAehiD,EAAQgiD,EAAehkD,QACjDkmB,UAAWyQ,EAAAA,GAAUnQ,KACrBL,aAAcsQ,EAAAA,GAAapQ,KAE7BtmB,KAAK+G,WACL8gB,OAAOnJ,EACX,CACF,CAEI8mC,GACF,IAAIhgC,EAAAA,EACF,CACEK,KAAO,GAAE4hB,iBACTjpB,EAAG0c,EAAczU,KAAKjf,MAAQ,IAC9BiX,EAAG,GACHqH,KAAM,CAAEtW,KAAM,GACdyW,UAAW1H,EAAOsH,KAClBa,WAAYnI,EAAOu8B,YAErB96C,KAAK+G,WACL8gB,OAAOnJ,EAEb,CAEA4rB,oBAAAA,CAAqB5rB,GACnBzU,MAAMqgC,qBAAqB5rB,GAC3B,MAAM,cAAEwc,EAAa,eAAE+oB,GAAmBjkD,KAAKqe,yBAE/C,IAAK,IAAIpc,EAAQ,EAAGA,EAAQjC,KAAK+C,MAAMqhD,QAAQnkD,OAAQgC,IAAS,CAC9D,MAAM2pC,EAAS5rC,KAAK+C,MAAMqhD,QAAQniD,GAC5BwjD,EAAazlD,KAAKulD,KAAK3Z,GAC7B,GAAI6Z,GAAYxlD,OAAQ,CACtB,MAAM4lD,EAAiB7lD,KAAKulD,KAAK3Z,GAAQ3rC,OAAS,EAE5C2lD,EADU9hC,OAAO0pB,SAASiY,EAAWI,IACT,GAAEJ,EAAWI,GAAgBjiD,QAAQ,MAAQ,GACzEiiB,EAAO,IAAIL,EAAAA,EACf,CACEK,KAAO,GAAE+lB,KAAUga,IACnBpnC,EAAG0c,EAAczU,KAAKjf,MACtBiX,EAAGutB,EAAAA,GAAOa,GAAKd,EAAAA,GAAUc,EAAI6Y,EAAAA,GAAO9Y,IAAM3qC,EAC1C6jB,KAAM,CAAEtW,KAAMu8B,EAAAA,GAAUc,EAAG12B,MAAO,QAClC8P,UAAWg+B,EAAehiD,EAAQgiD,EAAehkD,QACjDkmB,UAAWyQ,EAAAA,GAAUnQ,KACrBL,aAAcsQ,EAAAA,GAAapQ,KAE7BtmB,KAAK+G,WAEP/G,KAAKslD,kBAAoB,IAAKtlD,KAAKslD,kBAAmB,CAAC1Z,GAAS/lB,EAAK8K,QAAQjS,IAC7EmH,EAAKgC,OAAOnJ,EACd,CACF,CACF,CAEA8kC,QAAAA,GACExjD,KAAKulD,KAAO,CAAC,EACb,MAAMrB,EAASlkD,KAAKmkD,YAEd2B,EAAW,IAAI7/C,KAAKjG,KAAK+C,MAAM+iD,SAAW,UAC1CC,EAAS,IAAI9/C,KAAKjG,KAAK+C,MAAMgjD,OAAS,UACtCC,EAAiB,GACvB,IAAK,MAAMr8C,KAASu6C,EAAQ,CAC1B,MAAM+B,EAAS,GACf,IAAK,IAAI/jC,EAAI,EAAGmiC,EAAM16C,EAAMyxB,MAAMn7B,OAAQqkD,EAAMD,GAAO,EAAGC,EAAMpiC,EAAImiC,EAAMniC,EAAImiC,EAAKC,EAAMpiC,IAAMA,IAAK,CAClG,MAAMslB,EAAOuC,EAAAA,GAAAA,sBAA4BpgC,EAAM69B,KAAKtlB,IAChD4jC,GAAYte,GAAQA,GAAQue,GAC9BE,EAAO1kD,KAAKoI,EAAMyxB,MAAMlZ,GAE5B,CACA8jC,EAAezkD,KAAK,CAAEqqC,OAAQjiC,EAAMiiC,OAAQxQ,MAAO6qB,GACrD,CAEA,MAAMC,EAAYrW,EAAAA,IAAOmW,GAAiBrB,GAAMA,EAAEvpB,MAAMn7B,UAAW,EACnE,IAAK,MAAM0J,KAASq8C,EAAgB,CAClChmD,KAAKulD,KAAK57C,EAAMiiC,QAAU,GAC1B,MAAM6W,EAAQ94C,EAAMyxB,MAAM,GAC1B,IAAI7E,EAAS,EACb,GAAI2vB,EAAYv8C,EAAMyxB,MAAMn7B,OAAQ,CAClCs2B,EAAS2vB,EAAYv8C,EAAMyxB,MAAMn7B,OACjC,IAAK,IAAIiiB,EAAI,EAAGikC,EAAO5vB,EAAQ6vB,EAAOD,GAAQ,EAAGC,EAAOlkC,EAAIikC,EAAOjkC,EAAIikC,EAAMC,EAAOlkC,IAAMA,IACxFliB,KAAKulD,KAAK57C,EAAMiiC,QAAQ1pB,GAAKozB,GAEjC,CACA,IAAK,IAAIpzB,EAAI,EAAGmkC,EAAO18C,EAAMyxB,MAAMn7B,OAAQqmD,EAAOD,GAAQ,EAAGC,EAAOpkC,EAAImkC,EAAOnkC,EAAImkC,EAAMC,EAAOpkC,IAAMA,IACpGliB,KAAKulD,KAAK57C,EAAMiiC,QAAQrV,EAASrU,GAAuB,IAAjBvY,EAAMyxB,MAAMlZ,GAAYugC,EAAQ,GAE3E,CACA,MAAM,IAAE/9B,EAAG,IAAEG,GAAQ7kB,KAAKyjD,wBAAwBxgD,OAAOC,KAAKlD,KAAKulD,MAAM73C,KAAK8Q,GAAMxe,KAAKulD,KAAK/mC,MAC9F,MAAO,CAAEkG,MAAKG,MAChB,CAGA4+B,oBAAAA,GACE,IAAI/+B,EAAMZ,OAAO86B,UACb/5B,EAAMf,OAAO+6B,UAEjB,MAAM,WAAE5zB,GAAejrB,KAAK0B,MAAK,QAAAP,EAAAC,UAAAnB,OAJXykD,EAAM,IAAA7kD,MAAAsB,GAAAG,EAAA,EAAAA,EAAAH,EAAAG,IAANojD,EAAMpjD,GAAAF,UAAAE,GAK5B,IAAK,MAAMqL,KAAO+3C,EAChB,IAAK,IAAIxiC,EAAI,EAAGmiC,EAAM13C,EAAI1M,OAAQqkD,EAAMD,GAAO,EAAGC,EAAMpiC,EAAImiC,EAAMniC,EAAImiC,EAAKC,EAAMpiC,IAAMA,IAAK,CAC1F,MAAM2U,EAAS72B,KAAKmiB,GAAGD,GACnB2U,EAAS5L,EAAa,GAAK4L,EAAS5L,EAAajrB,KAAKwH,QAKtDkd,EAAM/X,EAAIuV,KACZwC,EAAM/X,EAAIuV,IAER2C,EAAMlY,EAAIuV,KACZ2C,EAAMlY,EAAIuV,IAEd,CAGF,MAAO,CAAEwC,MAAKG,MAChB,CAEAslB,WAAAA,CAAYzrB,GACV,MAAM,cAAEwc,GAAkBl7B,KAAKqe,0BACzB,OAAEE,GAAW2c,EAAc2Q,QAC3B5sB,GAAYiwB,EAAAA,EAAAA,IAAa,CAC7BxwB,UACA+Q,QAASyL,EAAczU,KAAKjf,MAC5BkoB,QAASwL,EAAc5U,IAAI7e,SAE7BwX,EAAUkwB,KACV,MAAMY,EAAQ/vC,KAAK+G,UAAUoQ,MAAMsH,EAAEsxB,MAAM,IACrC2T,EAAQ1jD,KAAK8wC,WACbjrB,EAAO,IAAIL,EAAAA,EACf,CACEhH,EAAGxe,KAAKwH,MAAQ,EAChBse,KAAM,CAAEtW,KAAM,GACdyW,UAAW1H,EAAOsH,KAClBO,aAAcsQ,EAAAA,GAAaC,QAE7B32B,KAAK+G,WAEP,IAAK,MAAMipC,KAAQD,EAAO,CACxB,MAAMtxB,EAAIY,KAAK2E,MAAMhkB,KAAKoiB,GAAG4tB,IAC7B0T,EAAMvkC,IAAI,CAAEpB,GAAIU,EAAGR,GAAIQ,IAAKoJ,OAAOnJ,GACnCmH,EAAK1G,IAAI,CAAE0G,KAAMmqB,EAAKpsC,QAAQ,GAAI6a,MAAKoJ,OAAOnJ,EAChD,CACAO,EAAUgyB,MACZ,CAEAxF,WAAAA,GACE,MAAM,cAAEvQ,GAAkBl7B,KAAKqe,0BACzB,OAAEE,GAAW2c,EAAc2Q,QAC3B5sB,GAAYiwB,EAAAA,EAAAA,IAAa,CAC7BxwB,QAAS1e,KAAK0e,QACd+Q,QAASzvB,KAAKirB,WAAaiQ,EAAczU,KAAKjf,MAC9CkoB,QAASwL,EAAc5U,IAAI7e,SAE7BwX,EAAUkwB,KACV,MAAMtpB,EAAO,IAAIL,EAAAA,EACf,CACE/G,EAAGze,KAAKyH,OAAS,GACjBqe,KAAM,CAAEtW,KAAM,GACdyW,UAAW1H,EAAOsH,KAClBO,aAAcsQ,EAAAA,GAAalQ,OAC3BL,UAAWyQ,EAAAA,GAAUC,QAEvB72B,KAAK+G,WAEDmhB,EAAYrC,EAAK1G,IAAI,CAAE0G,KAAM,SAAU8K,QAAQ3wB,KAAK0e,SAE1D,IAAI8oB,EAAO,IAAIvhC,KAAyB,IAApBjG,KAAK4E,KAAK4iC,KAAK,IAC/BoO,EAAYpO,EAAKG,WAAa,IAAMH,EAAKK,cAEzC0e,EAAe,EACnBvmD,KAAK4E,KAAK4iC,KAAKj/B,SAAQ,CAACujB,EAAG7pB,KACzB,GAAIA,EAAQ,EACV,OAGF,MAAMulC,EAAO,IAAIvhC,KAAS,IAAJ6lB,GAChB4b,EAAQF,EAAKG,WAAa,IAAMH,EAAKK,cACvCH,IAAUkO,GACZ2Q,IAEF3Q,EAAYlO,CAAK,IAGnB,MAAM8e,KAAwBxmD,KAAKwH,MAAQ0gB,GACrCu+B,EAAgBF,EAAeC,EACrC,IAAIE,EAEFA,EADED,GAAiB,EACLC,KAAM,EACXD,GAAiB,EACXjoC,GAAcA,EAAI,GAAM,EAC9BioC,GAAiB,EACXjoC,GAAcA,EAAI,GAAM,EAC9BioC,GAAiB,EACXjoC,GAAcA,EAAI,GAAM,EAC9BioC,GAAiB,EACXjoC,GAAcA,EAAI,GAAM,EAExBA,GAAoB,IAANA,EAG/BgpB,EAAO,IAAIvhC,KAAyB,IAApBjG,KAAK4E,KAAK4iC,KAAK,IAC/BoO,EAAYpO,EAAKG,WAAa,IAAMH,EAAKK,cAEzC,MAAM0M,EAAQv0C,KAAKw0C,WAEnB,IAAK,IAAItyB,EAAI,EAAGA,EAAIliB,KAAK4E,KAAK4iC,KAAKvnC,OAAQiiB,IAAK,CAC9CslB,EAAO,IAAIvhC,KAAyB,IAApBjG,KAAK4E,KAAK4iC,KAAKtlB,IAC/B,MAAMwlB,EAAQF,EAAKG,WAAa,IAAMH,EAAKK,cAC3C,GAAIH,IAAUkO,EAAW,CACvBA,EAAYlO,EACZ,MAAMlpB,EAAIxe,KAAKmiB,GAAGD,GAClB,GAAI1D,EAAIxe,KAAKirB,YAAc,IAAMzM,EAAIxe,KAAKirB,WAAajrB,KAAKwH,MAAQ,GAElE,SAIF,GAFA+sC,EAAMp1B,IAAI,CAAErB,GAAIU,EAAGR,GAAIQ,IAAKqJ,OAAO7nB,KAAK0e,UAEnCgoC,EAAYlf,EAAKG,YACpB,SAGF9hB,EACG1G,IAAI,CACH0G,KAA0B,IAApB2hB,EAAKG,WAAmBH,EAAKK,cAActjC,WAAau/C,EAAOtc,EAAKG,YAC1EnpB,EAAGA,IAEJqJ,OAAO7nB,KAAK0e,QACjB,CACF,CAEAO,EAAUgyB,MACZ,CAEA3B,SAAAA,GACE,OAAOtvC,KAAKwjD,UACd,CAEA/M,gBAAAA,GAAoB,CAEpBrL,YAAAA,GAAgB,CAEhB+Y,SAAAA,GACE,OAAO35C,EAAAA,EAAMo6C,QACVD,GACC3kD,KAAK+C,MAAMqhD,QAAQhqB,SAASuqB,EAAE/Y,SAC9B+Y,EAAElwC,YAAczU,KAAK4E,MAAM6P,WAC3BzU,KAAK0B,MAAMkyB,eAAeixB,SAASF,EAAEG,SAE3C,CAEAvgD,QAAAA,GACE,MAAQ,cAAavE,KAAK4E,KAAKgnC,QACjC,EAGF,YC1Xa+a,GAAe1jD,OAAOitB,OAAO,CACxC,CAAC7Z,EAAAA,GAAiBC,aAAcswC,EAChC,CAACvwC,EAAAA,GAAiBG,YAAaqwC,EAC/B,CAACxwC,EAAAA,GAAiBK,mBAAoBowC,EACtC,CAACzwC,EAAAA,GAAiBO,WAAYmwC,EAC9B,CAAC1wC,EAAAA,GAAiB87B,iBAAkB6U,EACpC,CAAC3wC,EAAAA,GAAiB0tC,gBAAiBkD,EACnC,CAAC5wC,EAAAA,GAAiBS,WAAYowC,EAC9B,CAAC7wC,EAAAA,GAAiBgvC,WAAY8B,I,ieClBzB,MAAMpb,EAAY,CACvBrI,IAAK,EACLkJ,GAAI,EACJhlB,EAAG,EACHilB,EAAG,GACHJ,EAAG,GACHoQ,IAAK,GACLuK,KAAM,IAEKxV,EAAc,CACzBhF,GAAI,EACJhlB,EAAG,EACHilB,EAAG,IAEQllB,EAAU,CACrB8b,KAAM,EACNC,IAAK,EACLkJ,GAAI,EACJhlB,EAAG,GAEQ89B,EAAS,CACpB9Y,GAAI,GAEOgQ,EAAe,CAC1Bh1B,EAAG,GACHilB,EAAG,GACHJ,EAAG,GACH4a,GAAI,GACJxK,IAAK,IAEMyK,EAAkB,GAClBC,EAAiC,GACjCvb,EAAS,CACpBtI,IAAK,EACLkJ,GAAI,EACJhlB,EAAG,EACHilB,EAAG,EACHgQ,IAAK,IAEMnU,EAAS,CAAC,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,OAE7F,IAAK8e,EAAe,SAAfA,GAAe,OAAfA,EAAe,kBAAfA,EAAe,cAAfA,EAAe,cAAfA,EAAe,oBAAfA,EAAe,sBAAfA,CAAe,MAQfC,EAAU,SAAVA,GAAU,OAAVA,EAAU,eAAVA,EAAU,eAAVA,EAAU,eAAVA,EAAU,eAAVA,EAAU,eAAVA,EAAU,eAAVA,EAAU,eAAVA,EAAU,eAAVA,EAAU,eAAVA,CAAU,MAYVjqC,EAAiB,SAAjBA,GAAiB,OAAjBA,EAAiB,yBAAjBA,EAAiB,qBAAjBA,EAAiB,gCAAjBA,EAAiB,qBAAjBA,EAAiB,yBAAjBA,EAAiB,sDAAjBA,EAAiB,wCAAjBA,EAAiB,mBAAjBA,EAAiB,yBAAjBA,EAAiB,4CAAjBA,EAAiB,yBAAjBA,EAAiB,2BAAjBA,EAAiB,6BAAjBA,EAAiB,4CAAjBA,EAAiB,gCAAjBA,EAAiB,gCAAjBA,EAAiB,uBAAjBA,EAAiB,mBAAjBA,EAAiB,2BAAjBA,EAAiB,oCAAjBA,EAAiB,qBAAjBA,EAAiB,sCAAjBA,EAAiB,kDAAjBA,EAAiB,sCAAjBA,EAAiB,mEAAjBA,CAAiB,MA4BjBnH,EAAgB,SAAhBA,GAAgB,OAAhBA,EAAgB,kCAAhBA,EAAgB,gCAAhBA,EAAgB,+CAAhBA,EAAgB,8BAAhBA,EAAgB,8BAAhBA,EAAgB,0CAAhBA,EAAgB,yCAAhBA,EAAgB,8BAAhBA,CAAgB,MAWhBT,EAAa,SAAbA,GAAa,OAAbA,EAAa,iCAAbA,EAAa,uBAAbA,EAAa,qBAAbA,EAAa,qBAAbA,EAAa,2BAAbA,EAAa,qBAAbA,EAAa,qBAAbA,EAAa,qBAAbA,EAAa,mBAAbA,EAAa,uBAAbA,EAAa,qBAAbA,EAAa,qBAAbA,EAAa,uBAAbA,EAAa,qBAAbA,EAAa,qBAAbA,EAAa,qBAAbA,EAAa,uBAAbA,EAAa,qBAAbA,EAAa,yBAAbA,EAAa,yBAAbA,EAAa,yBAAbA,EAAa,uBAAbA,EAAa,qBAAbA,EAAa,qBAAbA,EAAa,mBAAbA,CAAa,MA4Bb8xC,EAAW,SAAXA,GAAW,OAAXA,EAAW,2BAAXA,EAAW,qBAAXA,EAAW,iBAAXA,EAAW,mBAAXA,EAAW,mBAAXA,EAAW,qBAAXA,EAAW,qBAAXA,EAAW,uBAAXA,EAAW,iBAAXA,EAAW,mBAAXA,EAAW,mBAAXA,EAAW,6BAAXA,EAAW,iBAAXA,EAAW,mBAAXA,EAAW,mBAAXA,EAAW,qBAAXA,EAAW,mBAAXA,EAAW,iBAAXA,EAAW,qBAAXA,CAAW,MAsBXC,EAAgB,SAAhBA,GAAgB,OAAhBA,EAAgB,iCAAhBA,EAAgB,yBAAhBA,EAAgB,+BAAhBA,CAAgB,MAMhBC,EAAc,SAAdA,GAAc,OAAdA,EAAc,mCAAdA,EAAc,iCAAdA,EAAc,yBAAdA,EAAc,+BAAdA,CAAc,MAOdn/C,EAAmB,SAAnBA,GAAmB,OAAnBA,EAAmB,iCAAnBA,EAAmB,yBAAnBA,EAAmB,uCAAnBA,EAAmB,+CAAnBA,EAAmB,6CAAnBA,EAAmB,2CAAnBA,CAAmB,MASxB,MAAMo/C,EAAwD,CACnE,CAACp/C,EAAoBq/C,WAAY,YACjC,CAACr/C,EAAoBs/C,OAAQ,QAC7B,CAACt/C,EAAoBu/C,kBAAmB,qBACxC,CAACv/C,EAAoBw/C,kBAAmB,qBACxC,CAACx/C,EAAoBy/C,iBAAkB,qBACvC,CAACz/C,EAAoB0/C,gBAAiB,sBAU3B16C,EAA0C,CACrD,OAAQ,CAAE26C,QAAS,EAAGC,KAAM,EAAGjkB,MAAO,GACtC,OAAQ,CAAEgkB,QAAS,EAAGC,KAAM,EAAGjkB,MAAO,GACtC,OAAQ,CAAEgkB,QAAS,EAAGC,KAAM,EAAGjkB,MAAO,GACtC,OAAQ,CAAEgkB,QAAS,EAAGC,KAAM,EAAGjkB,MAAO,GACtC,OAAQ,CAAEgkB,QAAS,EAAGC,KAAM,EAAGjkB,MAAO,GACtC,OAAQ,CAAEgkB,QAAS,EAAGC,KAAM,EAAGjkB,MAAO,GACtC,OAAQ,CAAEgkB,QAAS,EAAGC,KAAM,EAAGjkB,MAAO,GACtC,OAAQ,CACNgkB,QAAS,EACTC,KAAM,EACNjkB,MAAO,EACPkkB,UAAW,CAAC,gBAAiB,gBAAiB,kBAEhD,OAAQ,CACNF,QAAS,EACTC,KAAM,EACNjkB,MAAO,EACPkkB,UAAW,CAAC,gBAAiB,gBAAiB,mBAIrCl7C,EAAiB,CAC5BC,IAAK,MACLk7C,KAAM,QAQD,IAAKvgB,EAAS,SAATA,GAAS,OAATA,EAAS,QAATA,EAAS,QAATA,EAAS,QAATA,EAAS,QAATA,EAAS,UAATA,EAAS,UAATA,EAAS,UAATA,EAAS,MAATA,EAAS,QAATA,EAAS,QAATA,EAAS,MAATA,EAAS,MAATA,EAAS,MAATA,CAAS,MAkBd,MAAM4V,EAA6B,CAAC5V,EAAUC,GAAID,EAAUE,GAAIF,EAAUG,GAAIH,EAAUI,IAElF6L,EAA4B,CACvC,CAACjM,EAAUC,IAAK,EAChB,CAACD,EAAUE,IAAK,EAChB,CAACF,EAAUG,IAAK,EAChB,CAACH,EAAUI,IAAK,EAChB,CAACJ,EAAUK,KAAM,GACjB,CAACL,EAAUM,KAAM,GACjB,CAACN,EAAUO,KAAM,GACjB,CAACP,EAAUpoB,GAAI,GACf,CAACooB,EAAUQ,IAAK,IAChB,CAACR,EAAUS,IAAK,KAGL+f,EAAsB,CACjC,CAACxgB,EAAUC,IAAK,KAChB,CAACD,EAAUE,IAAK,KAChB,CAACF,EAAUG,IAAK,KAChB,CAACH,EAAUI,IAAK,KAChB,CAACJ,EAAUK,KAAM,MACjB,CAACL,EAAUM,KAAM,MACjB,CAACN,EAAUO,KAAM,MACjB,CAACP,EAAUpoB,GAAI,KACf,CAACooB,EAAUQ,IAAK,KAChB,CAACR,EAAUS,IAAK,KAChB,CAACT,EAAUlc,GAAI,IACf,CAACkc,EAAUW,GAAI,IACf,CAACX,EAAUX,GAAI,KAGV,IAAKohB,EAAa,SAAbA,GAAa,OAAbA,EAAa,QAAbA,EAAa,QAAbA,EAAa,QAAbA,EAAa,QAAbA,EAAa,QAAbA,EAAa,UAAbA,EAAa,QAAbA,EAAa,QAAbA,EAAa,QAAbA,EAAa,UAAbA,CAAa,MAalB,MAAMC,EAAoB,CAC/B,CAAC1gB,EAAUC,IAAK,GAChB,CAACD,EAAUE,IAAK,IAChB,CAACF,EAAUG,IAAK,IAChB,CAACH,EAAUI,IAAK,IAChB,CAACJ,EAAUK,KAAM,IACjB,CAACL,EAAUM,KAAM,IACjB,CAACN,EAAUO,KAAM,KACjB,CAACP,EAAUpoB,GAAI,KACf,CAACooB,EAAUQ,IAAK,KAChB,CAACR,EAAUS,IAAK,MAChB,CAACT,EAAUlc,GAAI,MACf,CAACkc,EAAUW,GAAI,OACf,CAACX,EAAUX,GAAI,QAGJshB,EAAU,CACrBC,OAAQ,SACRC,OAAQ,SACRC,OAAQ,SACRC,OAAQ,SACRC,OAAQ,SACRC,OAAQ,SACRC,OAAQ,SACRC,OAAQ,SACRC,OAAQ,SACRC,OAAQ,SACRC,OAAQ,SACRC,OAAQ,SACRC,OAAQ,SACRC,OAAQ,UAGH,IAAK/c,EAA0B,SAA1BA,GAA0B,OAA1BA,EAA0B,kBAA1BA,EAA0B,sBAA1BA,EAA0B,sBAA1BA,EAA0B,sBAA1BA,EAA0B,wBAA1BA,EAA0B,sBAA1BA,EAA0B,sBAA1BA,EAA0B,0BAA1BA,EAA0B,wBAA1BA,CAA0B,MAY1B9V,EAAS,SAATA,GAAS,OAATA,EAAS,YAATA,EAAS,cAATA,EAAS,gBAATA,EAAS,cAATA,EAAS,UAATA,CAAS,MAQTF,EAAY,SAAZA,GAAY,OAAZA,EAAY,UAAZA,EAAY,2BAAZA,EAAY,gBAAZA,EAAY,wBAAZA,EAAY,mCAAZA,EAAY,gBAAZA,CAAY,MASZrf,EAAS,SAATA,GAAS,OAATA,EAAS,gBAATA,EAAS,wBAATA,EAAS,0BAATA,CAAS,MAMTqyC,EAAwB,SAAxBA,GAAwB,OAAxBA,EAAAA,EAAwB,uBAAxBA,EAAAA,EAAwB,kBAAxBA,EAAAA,EAAwB,mBAAxBA,EAAAA,EAAwB,6CAAxBA,CAAwB,MAO7B,MAAMC,EAA8B,GAE9BC,EAAa,CACxB,CAACvyC,EAAUC,QAAS,SACpB,CAACD,EAAUG,YAAa,aACxB,CAACH,EAAUK,aAAc,eAGd3B,EAAsB,CACjCrM,MAAO,IACP4L,UAAW,KAGAu0C,EAAyB,GAEzBC,EAAsB,IAEtBC,EAA+B,IAE/BC,EAAmB,CAAC,KAAM,KAAM,KAAM,MAAO,KAAM,KAAM,KAAM,OAE/D1d,EAAqB73B,IAChC,OAAQA,GACN,KAAKuzB,EAAUC,GACb,MAAO,QACT,KAAKD,EAAUE,GACb,MAAO,QACT,KAAKF,EAAUG,GACb,MAAO,QACT,KAAKH,EAAUI,GACb,MAAO,QACT,KAAKJ,EAAUK,IACb,MAAO,SACT,KAAKL,EAAUM,IACb,MAAO,SACT,KAAKN,EAAUO,IACb,MAAO,SACT,KAAKP,EAAUpoB,EACb,MAAO,OACT,KAAKooB,EAAUQ,GACb,MAAO,OACT,KAAKR,EAAUS,GACb,MAAO,OACT,KAAKT,EAAUlc,EACb,MAAO,QACT,KAAKkc,EAAUW,EACb,MAAO,SACT,KAAKX,EAAUX,EACb,MAAO,UACT,QACE,MAAO,GACX,EAoBK,IAAK4iB,EAAwB,SAAxBA,GAAwB,OAAxBA,EAAwB,MAAxBA,EAAwB,MAAxBA,EAAwB,QAAxBA,EAAwB,QAAxBA,EAAwB,QAAxBA,EAAwB,MAAxBA,EAAwB,MAAxBA,CAAwB,MAYxB90B,EAAc,SAAdA,GAAc,OAAdA,EAAc,kBAAdA,EAAc,cAAdA,EAAc,YAAdA,EAAc,cAAdA,EAAc,gBAAdA,CAAc,MASnB,MAAMP,EAAsB,CACjC,CAACoT,EAAUC,IAAK,CACdvT,MAAO,EACPC,MAAOQ,EAAe+0B,SAExB,CAACliB,EAAUE,IAAK,CACdxT,MAAO,EACPC,MAAOQ,EAAe+0B,SAExB,CAACliB,EAAUG,IAAK,CACdzT,MAAO,EACPC,MAAOQ,EAAe+0B,SAExB,CAACliB,EAAUI,IAAK,CACd1T,MAAO,EACPC,MAAOQ,EAAe+0B,SAExB,CAACliB,EAAUK,KAAM,CACf3T,MAAO,GACPC,MAAOQ,EAAe+0B,SAExB,CAACliB,EAAUM,KAAM,CACf5T,MAAO,GACPC,MAAOQ,EAAe+0B,SAExB,CAACliB,EAAUO,KAAM,CACf7T,MAAO,GACPC,MAAOQ,EAAe+0B,SAExB,CAACliB,EAAUpoB,GAAI,CACb8U,MAAO,EACPC,MAAOQ,EAAeogB,OAExB,CAACvN,EAAUQ,IAAK,CACd9T,MAAO,EACPC,MAAOQ,EAAeogB,OAExB,CAACvN,EAAUS,IAAK,CACd/T,MAAO,EACPC,MAAOQ,EAAeogB,OAExB,CAACvN,EAAUlc,GAAI,CACb4I,MAAO,EACPC,MAAOQ,EAAeg1B,MAExB,CAACniB,EAAUW,GAAI,CACbjU,MAAO,EACPC,MAAOQ,EAAei1B,OAExB,CAACpiB,EAAUX,GAAI,CACb3S,MAAO,EACPC,MAAOQ,EAAe2uB,SAIbuG,EAAuBpnD,OAAOC,KAAK0xB,GAAqC7nB,QACnF,CAACu9C,EAAMC,KAAS,IACXD,EACH,CAAC11B,EAAoB21B,GAAM51B,OAAQ21B,EAAK11B,EAAoB21B,GAAM51B,OAC9D,IAAI21B,EAAK11B,EAAoB21B,GAAM51B,OAAQC,EAAoB21B,GAAM71B,OACrE,CAACE,EAAoB21B,GAAM71B,UAEjC,CAAC,GAYI,IAAKY,EAAe,SAAfA,GAAe,OAAfA,EAAAA,EAAe,qCAAfA,EAAAA,EAAe,qCAAfA,EAAAA,EAAe,6BAAfA,EAAAA,EAAe,aAAfA,CAAe,MAOpB,MAAMk1B,EAAoB,kBAGpBC,EAA8B,IAE9BC,EAAmB,O,uLCzgBzB,SAASC,EAA+Bj4B,GAC7C,MAAMk4B,EAAmBl4B,EAAKhd,SAAS7L,MAAM3H,GAAOA,EAAGyT,KAAKrV,WAAW,iBACvE,GAAIsqD,EACF,OAAOA,EAAiBj1C,KAG1B,OADqB+c,EAAKhd,SAAS7L,MAAM3H,GAAOA,EAAGyT,KAAKrV,WAAW,aAE1D,QAEF,IACT,CAEO,SAASuqD,EAAiBnpD,GAC/B,MAAMopD,EAAcppD,EAAMopD,cACpBC,EAAgBD,GAAarhD,UAAUkM,MAAQ,KACrD,OAAIm1C,GAAavvB,eAAiBwvB,IAAkBn1C,EAAAA,GAAciD,KACzDkyC,EAELD,GAAaE,UACR,QAEF,IACT,CAEO,SAASC,EAAqCtjD,GAUlD,IAVmD,QACpD7F,EAAO,WACPopD,EAAU,qBACVC,EAAoB,oBACpBC,GAMDzjD,EACC,MAAMZ,EAAYjF,EAAQ4wB,OACpBkZ,EAAS7kC,EAAUskD,oBACnBC,EAAgBT,EAAiB9jD,GACvC,GAAI6kC,GAAU7kC,GAAaukD,KAAmBxpD,EAAQypD,WAA4B,YAAfL,GAA2B,CAC5F,MAAMM,EAAe1pD,EAAQ2H,SAASyqB,mBAChCu3B,EAA8B,CAClC1hD,UAAWjI,EAAQiI,UACnB2hD,OAAQ5pD,EAAQ4pD,OAChB9f,SACA+f,WAAYP,EACZF,aACAI,gBACAM,aAAc5kC,KAAKC,UAAUukC,IAGzBK,EAAmB,IAAIV,GACvBW,EAAqBD,EAAiBhqD,WACzCkqD,GAAmBA,EAAehiD,YAAc0hD,EAAW1hD,YAG9D,IAAIiiD,GAAoB,EACxB,GAAIF,GAAsB,EAAG,CAC3B,MAAMG,EAAgBJ,EAAiBC,GACjCI,EAAmBD,EAAcP,SAAWD,EAAWC,OACvDS,EAAiBF,EAAcf,aAAeO,EAAWP,WACzDkB,EAAkBH,EAAcL,eAAiBH,EAAWG,aAC5DS,EAAYF,GAAkBC,GAAmBF,GAEpDpqD,EAAQ2H,SAASwoB,kBAClBg6B,EAAcrgB,SAAWA,GACzBygB,GAC6B,YAA7BJ,EAAcf,aAEdW,EAAiBC,GAAsBL,EACvCO,GAAoB,EAExB,MACEH,EAAiBtqD,KAAKkqD,GACtBO,GAAoB,EAGtB,MAAO,CACLH,mBACAG,oBACAP,aAEJ,CACF,CAEO,SAASa,EAAyCt7C,GACvD,MAAMozC,EAAoB,GACpBmI,EAA8C,CAAC,QAYrD,OAVAv7C,EAAYw7C,cAAcjkD,SAASxB,IACjC,MAAM6kC,EAAS7kC,EAAUskD,oBACnBC,EAAgBT,EAAiB9jD,GACnC6kC,IAAWwY,EAAQhqB,SAASwR,IAC9BwY,EAAQ7iD,KAAKqqC,GAEX0f,IAAkBiB,EAAenyB,SAASkxB,IAC5CiB,EAAehrD,KAAK+pD,EACtB,IAEK,CAAElH,UAASmI,iBACpB,CAEO,SAASE,EAAmCrkD,GAUhD,IAViD,gBAClDskD,EAAe,qBACfvB,EAAoB,oBACpBC,EAAmB,aACnBuB,GAMDvkD,EACKwkD,EAAyBxB,EAC7B,MAAMS,EAAmB,IAAIV,GACvB0B,EAA8B,GA4BpC,OA1BAH,EAAgBnkD,SAASukD,IACvBF,GAAyBG,EAAAA,EAAAA,IAAWH,EAAwBE,EAAQnB,YACpE,MAAMqB,EAAenB,EAAiBhqD,WAAUiM,IAAA,IAAC,UAAE/D,GAAW+D,EAAA,OAAKg/C,EAAQ/iD,YAAcA,CAAS,IAC5FkjD,EAAiBD,GAAgB,EAAInB,EAAiBmB,GAAgB,KAC5E,GAAuB,OAAnBC,EACFpB,EAAiBtqD,KAAKurD,GACtBD,EAAkBtrD,KAAKurD,EAAQ/iD,gBAC1B,GAAqC,SAAjCkjD,EAAe3B,eAA4BqB,EAAc,CAClE,MAAMO,EAAcC,EAAmBF,GACjCG,EAAgBD,EAAmBL,GACrCI,IAAgBE,IAClBvB,EAAiBmB,GAAgB,IAC5BF,EACHnB,YAAY0B,EAAAA,EAAAA,KAAaN,EAAAA,EAAAA,IAAWE,EAAetB,WAAYmB,EAAQnB,YAAa1lD,KAAKC,OACzF0lD,aAAc5kC,KAAKC,UAAU,IACxBD,KAAKsmC,MAAMR,EAAQlB,cACtB/lC,KAAO,GAAEqnC,QAAkBE,QAIjCP,EAAkBtrD,KAAKurD,EAAQ/iD,UACjC,MAAWwjD,EAAAA,EAAAA,IAAW1B,EAAiBmB,GAAcrB,WAAYmB,EAAQnB,YAAc,IACrFE,EAAiBmB,GAAgBF,EACjCD,EAAkBtrD,KAAKurD,EAAQ/iD,WACjC,IAEK,CAAE6iD,yBAAwBf,mBAAkBgB,oBACrD,CAEO,SAASW,IACd,MAAMC,GACJ5nD,OAAO8S,gBAAgB+0C,sBAAwB7nD,OAAO8nD,sBAAsBD,uBAC3EE,SAEH,OAAOH,GAAiB//C,KAAK9L,GAASisD,EAA+BjsD,MAAU,IACjF,CAEO,SAASksD,EAA6Bp+C,GAM1C,IAN2C,iBAC5CrB,EAAgB,cAChB0/C,GAIDr+C,EACCrB,EAAiB2/C,iBAAiBzlD,SAASzG,IACrCA,EAAQmsD,aACVnsD,EAAQisD,IACV,GAEJ,CAEO,SAASG,EAAiBtiB,GAC/B,MAAQ,QAAOA,GACjB,CAEO,SAASuhB,EAAmBgB,GACjC,OAAQA,EAAcnnC,KAAKsmC,MAAMa,EAAYvC,eAAe/lC,KAAO,KAAO,EAC5E,CAEO,SAASuoC,EAAiB/zB,GAAwE,IAAvE,OAAEuR,EAAM,SAAEl2B,GAA2D2kB,EAErG,OAAO8yB,EADaz3C,EAAS7L,MAAKywB,IAAA,IAAC,UAAEvwB,GAAWuwB,EAAA,OAAKvwB,IAAcmkD,EAAiBtiB,EAAO,IAE7F,CAEO,SAASiiB,EAA+BjsD,GAC7C,MAAO,CACLmI,UAAWnI,EAAKmI,UAChB6hC,OAAQhqC,EAAKgqC,OACb8f,OAAQ9pD,EAAK8pD,OACbR,WAAYtpD,EAAKspD,WACjBI,cAAe1pD,EAAK0pD,cACpBM,aAAchqD,EAAKgqD,aACnBD,WAAY,CACV0C,GAAIzsD,EAAK0sD,oBACTlqB,MAAOxiC,EAAK2sD,kBACZC,KAAM5sD,EAAK6sD,oBAGjB,CAEO,SAASC,EAA+B9sD,GAC7C,MAAO,CACLmI,UAAWnI,EAAKmI,UAChB6hC,OAAQhqC,EAAKgqC,OACb8f,OAAQ9pD,EAAK8pD,OACbR,WAAYtpD,EAAKspD,WACjBI,cAAe1pD,EAAK0pD,cACpBM,aAAc5kC,KAAKC,UAAUrlB,EAAKgqD,cAClC0C,oBAAqB1sD,EAAK+pD,WAAW0C,GACrCE,kBAAmB3sD,EAAK+pD,WAAWvnB,MACnCqqB,mBAAoB7sD,EAAK+pD,WAAW6C,KAExC,C,qJCrMA,MAAMG,EAAmE,CACvE,CAACjiB,EAAAA,GAA2BkiB,WAAY,wBACxC,CAACliB,EAAAA,GAA2BmiB,aAAc,0BAC1C,CAACniB,EAAAA,GAA2BoiB,WAAY,wBACxC,CAACpiB,EAAAA,GAA2BqiB,YAAa,0BAQpC,SAASC,EAAYrnD,GAA+C,IAA9C,YAAEsnD,GAA0CtnD,EACvE,MAAOunD,IAAuB5zC,EAAAA,EAAAA,GAAe,IACxC6zC,EAAAA,EACHzzC,gBAAgB,EAChBF,cAAe,SACfD,QAASA,IAAM0zC,OAGX,cAAE/zB,GAAkBg0B,GAAuB,CAAC,EAElD,OAAO7iD,EAAAA,EAAAA,KAAC6uB,EAAa,CAACk0B,QAASH,GACjC,CAEO,MAAMI,EAAiChkD,EAAAA,MAAW,SAAuCjD,GAGxD,IAHyD,MAC/FzB,EAAK,OACL2oD,GACoClnD,EACpC,MAAM,oBAAEmnD,EAAmB,mBAAEC,EAAkB,iBAAEnhD,IAAqBkE,EAAAA,EAAAA,KAChEk9C,GAA0BC,EAAAA,EAAAA,OAC1BT,EAActoD,EAAMgpD,KAEpBC,EAA6BvkD,EAAAA,aAChCzK,IACC,GAAI4uD,IAGF,OAFA5uD,EAAGivD,sBACHJ,EAAwB56C,OAG1Bo6C,GAAa,GAEf,CAACQ,EAAyBD,EAAoBP,IAG1Ca,EAAwBzkD,EAAAA,aAAkB,KAC9CkkD,IAEAlyC,WAAW4xC,EAAY,GACtB,CAACM,EAAqBN,IAEnBc,EAAiB1kD,EAAAA,SAAc,KACnC,MAAM2kD,EAAwBrpD,EAAMspD,WAAWC,mBACzC,IAAE5pC,EAAM,EAAC,OAAE7e,EAAS,IAAOuoD,GAAuBG,yBAA2B,CAAC,EACpF,OAAO7pC,EAAM7e,EAAS5B,OAAOuqD,OAAO,GAGnC,CAACd,IAEEe,EAAchlD,EAAAA,SAAc,KAChC,MAAMilD,EAAe1lD,SAAS2lD,eAAe7F,EAAAA,IAC7C,OAAO4F,GAAcE,cAAgB,CAAC,GAGrC,CAAClB,IAEJ,OACEtgD,EAAAA,EAAAA,MAACyhD,EAAAA,IAAO,CAAC/pD,MAAM,OAAOC,MAAOA,EAAOyoD,QAASQ,EAA4Bz5C,MAAO,CAAEu6C,UAAWL,EAAc,IAAK5jD,SAAA,EAC9GJ,EAAAA,EAAAA,KAAA,OAEE4C,UAAW0hD,IAAW,iDAAkD,CACtE,kBAAmBtiD,GAAkBgD,6BAA+Bq7B,EAAAA,GAA2ByS,YAEjGhpC,MAAO,CAAEmQ,KAAMypC,GAAiBtjD,UAEhCJ,EAAAA,EAAAA,KAAA,OACE4C,UAAW0hD,IACTC,EAAAA,IAAgBC,QAChBC,EAAAA,GAAa/rC,QAEb,kDACAtY,UAEFJ,EAAAA,EAAAA,KAAChB,EAAAA,SAAc,CACb2R,UACE3Q,EAAAA,EAAAA,KAAA,OAAK4C,UAAU,4EAA2ExC,UACxFJ,EAAAA,EAAAA,KAAC0kD,EAAAA,IAAO,CAAAtkD,UACNJ,EAAAA,EAAAA,KAAC2kD,EAAAA,IAAO,CAACxpD,MAAO,SAGrBiF,UAEDJ,EAAAA,EAAAA,KAAC2iD,EAAY,CAACC,YAAatoD,EAAMgpD,cAKvCtjD,EAAAA,EAAAA,KAAC4kD,EAAAA,IAAkB,CACjBtqD,MAAO8oD,EACP,aAAW,kBACXjsD,MAAM,kBACN0tD,SACEliD,EAAAA,EAAAA,MAAAiC,EAAAA,SAAA,CAAAxE,SAAA,EACEJ,EAAAA,EAAAA,KAACC,EAAAA,IAAM,CAAC,cAAY,6BAA6B6kD,GAAIC,EAAAA,GAAc3kD,SAAC,YAGpEJ,EAAAA,EAAAA,KAACC,EAAAA,IAAM,CACL5F,MAAM,MACN,cAAY,6BACZyqD,GAAIC,EAAAA,GACJxlD,QAASkkD,EAAsBrjD,SAChC,uBAIJA,SACF,gDAKP,IAQO,SAAS4kD,EAAmBvjD,GAKmB,IALlB,UAClCoE,EAAS,MACTxQ,EAAK,UACLiN,KACG3L,GAC+C8K,EAClD,MAAMwjD,GAAuB5B,EAAAA,EAAAA,KAAgB,CAAE/gD,UAAWA,GAAa,WACjE2gD,EAASgC,EAAqBC,SAAS,QAEvCC,EAAcnmD,EAAAA,SAAc,IAC5B3J,EAAM2P,6BAA+Bq7B,EAAAA,GAA2BkiB,WAAc18C,EAW3E,CACLi/C,GAAIM,EAAAA,IACJ9qD,MAAO2qD,EACPzhD,OAAQy/C,GAbD,CACL6B,GAAI,IACJO,KAAO,gBAAcC,EAAAA,EAAAA,KAAkB,CACrCC,WAAY,SACZC,WAAY,SACZC,aAAcnD,EAAYjtD,EAAM2P,kCAUrC,CAAC3P,EAAM2P,2BAA4Ba,EAAWo/C,EAAsBhC,IAEvE,OACEtgD,EAAAA,EAAAA,MAAAiC,EAAAA,SAAA,CAAAxE,SAAA,EACEJ,EAAAA,EAAAA,KAACC,EAAAA,IAAM,IACDklD,EACJL,GAAIK,EAAYL,GAChBY,WAAW,EACX,cAAY,0BACZ3iD,WAAYpM,EAAMyJ,cAAWpE,EAAY,SACzC7E,MAAOR,EAAMyJ,cAAWpE,EAAY,iBACpCkE,YAAY,mBACRvJ,KAENqJ,EAAAA,EAAAA,KAACgjD,EAA8B,CAACC,OAAQA,EAAQ3oD,MAAO2qD,MAG7D,C,2JCxLA,MAAMU,EAAsB5nD,GACzB,YAAWA,EAAWwhC,UAAUxhC,EAAWyI,cAAczI,EAAWlJ,KAEhE,SAAS+R,EAAgBtL,GAM7B,IALDyC,WAAY6nD,EAAmB,cAC/B/+C,GAIDvL,EACC,MAAMkD,GAAWkD,EAAAA,EAAAA,MACXC,GAAWC,EAAAA,EAAAA,MACX7D,GAAakE,EAAAA,EAAAA,GAAc2jD,EAAqB,CACpD1jD,gBAAiB,CAAC,SAAU,YAAa,eAErCF,GAAmBC,EAAAA,EAAAA,GAAclE,GAAYwpB,gBAAkB,KAAM,CACzErlB,gBAAiB,CAAC,OAAQ,cAEtB2jD,EC5BD,SAAgDxwD,GACrD,MAAMywD,EAAW9mD,EAAAA,OAAa3J,GAM9B,OAJA2J,EAAAA,WAAgB,KACd8mD,EAAStzD,QAAU6C,CAAK,GACvB,CAACA,IAEGywD,CACT,CDoBwBC,CAAYhoD,IAC3B4I,EAAW6I,GAAgBxQ,EAAAA,UAAe,GAC3CgnD,EAAwBhnD,EAAAA,OAAa,IACrCinD,IAAgBjkD,GAAkBmD,MAAMtQ,GAExCqxD,EAA+BlnD,EAAAA,aAAmB1B,IACtD,MAAMD,EAAQwoD,EAAcrzD,QAC5B,IAAK6K,EACH,OAGF,MAAM2E,EAAmB3E,EAAMkqB,eACzB4+B,EAAe9oD,EAAM2hD,sBAAwB1hD,EAAM8oD,eAEzD/oD,EAAM8iD,cAAcjkD,SAASmqB,IACrBA,EAAKggC,8BACThgC,EAAKgd,gBAAgB,aAAc,KACrC,IAGFhmC,EAAMyG,iBAAiB,CAAE8a,YAAY0nC,EAAAA,EAAAA,IAAc,CAAEhpD,QAAOS,WAAYV,IAAUC,QAAOipD,YAAY,IAGrGlpD,EACGmpD,eACAj7C,QAAQk7C,IAAgBA,EAAW3wD,IAAIwH,KACvCpB,SAASoB,IACRA,EAAMopD,UAAU,CAAEC,UAAWC,EAAAA,EAAeC,WAAY,IAG5D,MAAMC,EAAYzpD,EAAM0pD,eACxB/kD,EAAiBglD,kBAAkB5pD,SAAS6pD,cAAa,GAEzD,MAAM59C,EAAW,IAAIhM,EAAMskD,oBAAsBmF,GAAWI,mBAAkB,IAAU,IACxF,IAAK,MAAMzxD,KAAW4T,EAAU,CAC9B,MAAMu4C,EAAYnsD,EAAQmsD,YACpBuF,EAAe1xD,EAAQ0xD,gBACzBvF,GAAauF,KAEXhB,IAAiBgB,GAAgBnlD,EAAiBolD,0BACpD3xD,EAAQ2H,SAASka,eAEjB7hB,EAAQ4xD,iBAGd,CAEAhqD,EAAMiqD,eAAehqD,EAAMC,aAAa,GAExCupD,GAAWS,2BAA2B,GAIrC,IAEGC,EAAaxoD,EAAAA,aAAkB3D,UACnC,IAAKwL,IAAkB9I,GAAckoD,EACnC,OAEFz2C,GAAa,GAEb,MAAM,OAAE+vB,EAAM,WAAE/4B,EAAU,UAAE4B,EAAS,eAAEq/C,GAAmB1pD,GACpD,UAAE2pD,EAAS,YAAEC,GAAgBxpD,EAAAA,EAAMi4C,QACnCwR,EAAW7pD,EAAW8pD,iBACtBC,EAAe/pD,EAAWT,QAChC,GAAIwqD,EAAa1B,iBAAmB7mB,GAAUuoB,EAAa1/C,YAAcA,EAAW,CAClF49C,EAAsBxzD,QAAUmzD,EAAmB5nD,GACnD,MAAMgqD,GAAkBC,EAAAA,EAAAA,IAA6B,CACnD1mD,IAAK0kD,EAAsBxzD,QAC3By1D,2BAA4B9pD,EAAAA,EAAMo6C,QAC/Bj7C,GACCA,EAAMiiC,SAAWA,GACjBjiC,EAAM8K,YAAcA,GACpB9K,EAAM4J,YACNnJ,EAAWwpB,eAAeixB,SAASl7C,EAAMm7C,YAIzCn7C,QAAca,EAAAA,EAAM0oB,IAAI,CAC5B0Y,SACA/4B,aACA4B,YACA/P,QAAS,CACPqvD,YACAC,cACAO,OAAQT,EACRG,WACAO,eAAiB7qD,QAA2BtB,IAAjBsB,EAAMm7C,OACjC2P,2BAA2B,GAE7BL,oBAGF,GAAIzqD,EAAM+qD,gBAAiB,CAEzB,MAAMC,EAA2BvqD,EAC9BwpB,eACAnhB,eACAmF,QAAQlO,IAAWU,EAAWjI,IAAIuH,KAClCvB,MAAMuB,GAAUC,EAAMxH,IAAIuH,EAAMC,WAOnC,aAJyB,IAArBA,EAAMirD,WAAqBD,GAC7BhrD,EAAMkrD,UAIV,EAEAC,EAAAA,EAAAA,IAAqBzC,EAAsBxzD,SAE3C0zD,EAA6B5oD,EAC/B,CAEAkS,GAAa,EAAM,GAIlB,CACDzR,GAAYlJ,GACZkJ,GAAYwhC,OACZxhC,GAAYqK,UACZrK,GAAYyI,WACZy/C,EACAC,EACAr/C,IAuFF,OApFA7H,EAAAA,WAAgB,KACdwoD,GAAY,GACX,CAACA,IAKJxoD,EAAAA,WAAgB,KACd,GAAIjB,EAAY,CACd,MAAM2qD,GAAqB5mD,EAAAA,EAAAA,KAAgDtD,EAASuD,QAC9E4mD,EAAc5qD,EACjBwpB,eACAnhB,eACA/E,KAAKhE,GAAUA,EAAMwK,YAClB+gD,EAASD,EAAYE,OAAOhzC,IAAOA,SAAK7Z,EAAY2sD,EAAYnxD,KAAK,KAEvEkxD,EAAmB33C,IAAM63C,GAC3BjnD,EAAS,CACPI,OAAS,KAAGujD,EAAAA,EAAAA,KAAkB,IACzBoD,EACH33C,EAAG63C,OAIX,IAEC,CAAC7qD,GAAY8J,YAYhB7I,EAAAA,WAAgB,KACd,MAAM3B,EAAQwoD,EAAcrzD,QACtB8K,EAAQD,GAAOC,QAErB,IAAIwrD,GAA4B,EAChC,GAAI9mD,GAAkBgD,6BAA+Bq7B,EAAAA,GAA2ByS,YAAcmT,EAAa,CACzG,MAAMliD,EAAW/B,GAAkB+B,SAC7BqkC,EAAW,EACX2gB,EAAY,EAClB,GAAIhlD,EAAU,CACZ,MAAMilD,EAAkB,CACtBjlD,EAAS8qB,cAAcrE,OAAO4d,SAC9BrkC,EAASkrB,kBAAkBzE,OAAO4d,UAClCygB,OAAOtnD,GAAUA,IAAU6mC,IACvB6gB,EAAmB,CACvBllD,EAAS8qB,cAAcrE,OAAOu+B,UAC9BhlD,EAASkrB,kBAAkBzE,OAAOu+B,WAClCF,OAAOtnD,GAAUA,IAAUwnD,IAE7BD,GAA6BE,IAAoBC,EAC7CH,IACF/kD,EAAS8qB,cAAcrE,OAAO4d,SAAWA,EACzCrkC,EAASkrB,kBAAkBzE,OAAO4d,SAAWA,EAC7CrkC,EAAS8qB,cAAcrE,OAAOu+B,UAAYA,EAC1ChlD,EAASkrB,kBAAkBzE,OAAOu+B,UAAYA,EAE9C/mD,EAAiB8B,iBAAiB,CAAEC,aAExC,CACF,CAEA,GACE1G,GACAC,IACC0E,GAAkBgD,6BAA+Bq7B,EAAAA,GAA2BkiB,WAC3EuG,KACD7C,EACD,CACA,MAAMrnC,GAAa0nC,EAAAA,EAAAA,IAAc,CAAEhpD,QAAOS,WAAYV,IACtDA,EAAMyG,iBAAiB,CAAE8a,cAC3B,IAIC,CAAC7gB,GAAYT,SAAS8K,UAAWpG,GAAkB+B,SAAUkiD,IAEzD,CAAEt/C,YACX,C,iKErNO,SAASS,EAAkC9L,GAM/C,IANgD,WACjDyC,EAAU,UACV8H,GAIDvK,EACC,MAAMgU,GAAsBC,EAAAA,EAAAA,OACtB/Q,GAAWkD,EAAAA,EAAAA,OACVwF,EAAYgiD,GAAiBlqD,EAAAA,UAAe,GAC7CgD,EAAmBjE,GAAYwpB,gBAAkB,KACjDvf,EAAahG,GAAkBoE,eAAe5Q,WAAW6H,GAAUU,EAAYjI,IAAIuH,OAAY,GAC/F,gBAAE8E,IAAoBC,EAAAA,EAAAA,GAAsB,CAAEJ,mBAAkBgG,eAChEhD,EAA6BhD,GAAkBgD,4BAA8Bq7B,EAAAA,GAA2B3nB,QAExG5R,EAAa9H,EAAAA,SAAc,KAC/B,IAAKjB,EAAY,OAAO,IAAInE,KAC5B,MAAM0D,EAAQS,EAAWT,QACzB,OAAO6rD,EAAAA,EAAAA,IAAsB7rD,EAAM69B,KAAK79B,EAAM69B,KAAKvnC,OAAS,GAAG,GAC9D,CAACmK,IAEEgJ,EAAgC/H,EAAAA,aACpCjD,IAAuE,IAAtE,OAAEwjC,EAAM,UAAEn3B,EAAS,UAAEP,GAA4C9L,EAChE,OAAIiJ,IAA+Bq7B,EAAAA,GAA2ByS,UACrD3wC,EAAgB,CACrBo9B,OAAQA,EACRn3B,UAAWA,EACXP,UAAWA,KAIRuhD,EAAAA,EAAAA,KAAkC,CACvCvjD,YACAgH,SAAUrO,EAASqO,SACnBzE,UAAWA,EACXP,UAAWA,EACXy6C,YAAa+G,EAAAA,IAAarkD,IAC1B,GAEJ,CAAC7C,EAAiB0D,EAAWb,EAA4BxG,EAASqO,WAkEpE,MAAO,CACL/F,aACAC,gCACAC,wBAlE+BnB,IAC/ByjD,EAAAA,EAAAA,IAA2B,CACzBzjD,YACA0jD,aAAeC,GAAcziD,EAA8B,CAAEqB,UAAWohD,EAAUjoD,MAAOsG,UAAW,SAgEtGZ,wBA7D8BxF,IAAA,IAAC,UAC/BoE,EAAS,YACT+B,EAAW,WACXpB,GAKD/E,EAAA,OACCgoD,EAAAA,EAAAA,KAA2B,CACzB5jD,YACA+B,cACApB,aACA+iD,aAAe1hD,GACbd,EAA8B,CAAEqB,UAAWP,EAAUO,UAAYP,UAAWA,EAAUtG,SACxF,EA+CF2F,aACAC,gCA9CsC9L,UACtC,GAA6B,OAAzBquD,EAAenoD,MAAgB,CACjC,MAAM,UAAE6G,EAAS,OAAEm3B,EAAM,WAAE/4B,EAAU,UAAEkhD,EAAS,YAAEC,GAAgB5pD,GAAYT,SAAW,CAAC,EACpFsqD,IAAa7pD,GAAY8pD,iBAC/B,KAAK/gD,GAAeN,GAAe+4B,GAAWn3B,GAAcshD,EAAenoD,OAAO,OAAO,EACzF2nD,GAAc,GACd,MAAM5rD,QAAca,EAAAA,EAAM0oB,IAAI,CAC5B0Y,SACA/4B,aACA4B,UAAWshD,EAAethD,UAC1B/P,QAAS,CACPqvD,YACAC,cACAC,WACAO,eAAiB7qD,QAA2BtB,IAAjBsB,EAAMm7C,OACjC2P,2BAA2B,KAG/Bc,GAAc,GAEd,MAAM,iBAAES,IAAqBC,EAAAA,EAAAA,IAAqB,KAC7CC,EAAAA,EAAAA,IAAsB,CAAEhiD,UAAW6hD,EAAenoD,MAAOjE,UAC5DA,QACAuK,UAAW6hD,EAAenoD,QAE5B,GAAyB,IAArBooD,EASF,OARAr6C,EAAoB9G,MAClBxI,EAAAA,EAAAA,KAACkQ,EAAAA,GAAY,CAAC20C,SAAS7kD,EAAAA,EAAAA,KAAA4E,EAAAA,SAAA,IAAOuL,YAAa,IAAK/P,UAC9CJ,EAAAA,EAAAA,KAACkD,EAAAA,IAAS,CAACN,UAAU,gBAAexC,SAAC,sFAMlC,CAEX,CACA,OAAO,CAAI,EAWf,C,gICtIO,SAASgC,EAAqB9G,GAMlC,IALD0G,iBAAkB8nD,EAAyB,WAC3C9hD,GAAa,GAId1M,EACC,MAAMkD,GAAWkD,EAAAA,EAAAA,MACXM,GAAmBC,EAAAA,EAAAA,GAAc6nD,EAA2B,CAChE5nD,gBAAiB,CAAC,oBAEd6nD,EAAqB/qD,EAAAA,SACzB,MAAQgD,GAAkBuB,qBAAqBymD,EAAAA,GAAkBC,YAEjE,CAACjoD,GAAkBkoD,iBAEfC,EAAkBnrD,EAAAA,SACtB,MAAQgD,GAAkBuB,qBAAqBymD,EAAAA,GAAkB77C,SAEjE,CAACnM,GAAkBkoD,iBAgErB,MAAO,CAAE/nD,gBA7DenD,EAAAA,aACtBjD,IAUM,IAVL,OACCwjC,EAAM,UACNn3B,EAAS,UACTP,EAAS,OACThF,GAMD9G,EACC,IAAKiG,EACH,MAAO,CACL6K,SAAUrO,EAASqO,SACnB9K,OAAQ,IAIZ,MAAMqoD,GAAgBtoD,EAAAA,EAAAA,KAAyCtD,EAASuD,SAClE,MAAEg2B,GAAU32B,EAAAA,GAASyB,GAAUb,EAAiBa,QAChDwnD,EAAaD,EAAc1zB,GAAGhJ,MAAM,MAAQ,GAC5C48B,EAAgBF,EAAchgC,GAAGsD,MAAM,MAAQ,GAC/C68B,EAAgBH,EAAcr5C,GAAG2c,MAAM,KAEvC88B,EAAyBh3D,MAAMk1B,KAAK,CAAE90B,OAAQmkC,IAC9CggB,EAAUyS,EACbnpD,KAAI,CAACgkB,EAAGzvB,KACP,MAAM60D,EAAgBJ,EAAWz0D,IAAUy0D,EAAWA,EAAWz2D,OAAS,GAC1E,OAAQoU,IAAepS,GAASu0D,IAAoB5qB,EAASA,EAASkrB,CAAa,IAEpFjzD,KAAK,KACFkzD,EAAaF,EAChBnpD,KAAI,CAACgkB,EAAGzvB,KACP,MAAM+0D,EAAmBL,EAAc10D,IAAU00D,EAAcA,EAAc12D,OAAS,GACtF,OAAQoU,IAAepS,GAASm0D,IAAuB3hD,EAAYA,EAAYuiD,CAAgB,IAEhGnzD,KAAK,KACFoxD,EAAS4B,EACZnpD,KAAI,CAACgkB,EAAGzvB,KACP,MAAMg1D,EAAmBL,EACrBA,EAAc30D,IAAU20D,EAAcA,EAAc32D,OAAS,QAC7DoI,EACJ,OAAQgM,IAAepS,IAASm0D,QAAqC/tD,IAAd6L,EAAsC+iD,EAAZ/iD,CAA4B,IAE9GrQ,KAAK,KAER,MAAO,CACLqV,SAAUrO,EAASqO,SACnB9K,OAAS,KAAGujD,EAAAA,EAAAA,KAAkB,CAC5B5uB,EAAGqhB,EACH3tB,EAAGsgC,EACH35C,EAAG63C,EAAOl7B,MAAM,KAAK5xB,KAAK+uD,SAAWjC,OAAS5sD,EAC9C0G,EAAGG,GAAUb,EAAiBa,OAC9BioD,SAASC,EAAAA,EAAAA,WAAwB/uD,EAAYouD,EAAcU,YAE9D,GAEH,CAAC9oD,EAAkBgG,EAAYxJ,EAAU2rD,EAAiBJ,IAI9D,C,sHC7EO,SAAST,EAA0BhuD,GAMvC,IANwC,UACzCuK,EAAS,aACT0jD,GAIDjuD,EACC,OAAO0vD,EAAAA,EAAAA,KAAmBnlD,GAAWxE,KAAK4pD,IAA+B,CACvExoD,MAAOwoD,EAAexoD,MACtBioD,WAAYO,EAAeP,WAAWrpD,KAAKmoD,IAAS,IAC/CA,EACHnE,KAAMkE,EAAaC,UAGzB,CAEO,IAAK0B,EAAmB,SAAnBA,GAAmB,OAAnBA,EAAmB,sCAAnBA,EAAmB,0BAAnBA,EAAmB,YAAnBA,EAAmB,YAAnBA,EAAmB,wBAAnBA,EAAmB,sCAAnBA,CAAmB,MASnBC,EAAkB,SAAlBA,GAAkB,OAAlBA,EAAkB,QAAlBA,EAAkB,MAAlBA,EAAkB,MAAlBA,EAAkB,MAAlBA,EAAkB,QAAlBA,EAAkB,QAAlBA,CAAkB,MASvB,MAAMC,EAAuB,CAClC,CAACD,EAAmBE,IAAKH,EAAoBI,kBAC7C,CAACH,EAAmB/qC,GAAI8qC,EAAoBnhD,YAC5C,CAACohD,EAAmBzoD,GAAIwoD,EAAoB5gD,KAC5C,CAAC6gD,EAAmBI,GAAIL,EAAoB1gD,KAC5C,CAAC2gD,EAAmBK,IAAKN,EAAoBhhD,WAC7C,CAACihD,EAAmBM,IAAKP,EAAoB9gD,mBAGlCshD,EAAuB,CAClC,CAACR,EAAoBI,mBAAoBH,EAAmBE,GAC5D,CAACH,EAAoBnhD,aAAcohD,EAAmB/qC,EACtD,CAAC8qC,EAAoB5gD,MAAO6gD,EAAmBzoD,EAC/C,CAACwoD,EAAoB1gD,MAAO2gD,EAAmBI,EAC/C,CAACL,EAAoBhhD,YAAaihD,EAAmBK,GACrD,CAACN,EAAoB9gD,mBAAoB+gD,EAAmBM,IASjDE,EAAkC,CAC7C,CAAEC,KAAM,iBAAkBrqD,MAAO2pD,EAAoBnhD,YAAatH,MAAO,UACzE,CAAEmpD,KAAM,gBAAiBrqD,MAAO2pD,EAAoB5gD,KAAM7H,MAAO,QACjE,CAAEmpD,KAAM,gBAAiBrqD,MAAO2pD,EAAoB1gD,KAAM/H,MAAO,QACjE,CAAEmpD,KAAM,kBAAmBrqD,MAAO2pD,EAAoB9gD,kBAAmB3H,MAAO,iBAChF,CAAEmpD,KAAM,sBAAuBrqD,MAAO2pD,EAAoBhhD,WAAYzH,MAAO,gBAGlEopD,EAAqC,CAChD,CAAED,KAAM,iBAAkBrqD,MAAO2pD,EAAoBI,kBAAmB7oD,MAAO,mBAC/E,CAAEmpD,KAAM,iBAAkBrqD,MAAO2pD,EAAoBnhD,YAAatH,MAAO,wBAEtEkpD,EAAcpgD,QAAQjC,GAASA,EAAK/H,QAAU2pD,EAAoBnhD,eAG1D+hD,EAA0B,CAAC,oBAAqB,cAAe,O,gDC1FrE,MAAMpwD,EAAyB,CACpCC,SAAUA,IAAM,gCAChBZ,SAAU,e,kECFL,MAAM+nD,EAA2B,CACtCnnD,SAAUA,IAAM,gCAChBZ,SAAU,kBAGCgxD,EAAuC,CAClDpwD,SAAUA,IACR,gCACFZ,SAAU,iCAGCixD,EAA0C,CACrDrwD,SAAUA,IACR,gCACFZ,SAAU,kC,qHCLL,SAASkxD,EAAe3wD,GAAkE,IAAjE,MAAEmH,EAAQ,aAAY,MAAElB,EAAK,SAAE2qD,GAAgC5wD,EAC7F,OACE0E,EAAAA,EAAAA,KAACmsD,EAAAA,IAAgB,CACf1pD,MAAOA,EACP2pD,gBAAkB,eAAc3pD,EAAM4pD,iCACtCxgD,OAAO+xB,EAAAA,EAAAA,KAAkBr8B,GACzB2qD,SAAUA,GAGhB,CCFO,SAASI,EAAkBhxD,GASN,IATO,MACjCmH,EAAK,WACL8pD,EAAU,YACVC,EAAW,WACXC,EAAU,YACVC,EAAW,WACXC,EAAU,WACVC,EAAU,SACVV,GACwB5wD,EACxB,MAAMuxD,GAAoBC,EAAAA,EAAAA,cACvBv4D,IACC,MAAMgN,EAAQhN,EAAGw4D,cAAcxrD,MAC/B2qD,EAASK,EAAYhrD,EAAM,GAE7B,CAAC2qD,EAAUK,IAEPS,GAAoBF,EAAAA,EAAAA,cACvBjhD,IACCqgD,EAASrgD,EAAO4gD,EAAW,GAE7B,CAACP,EAAUO,IAEb,OACE9pD,EAAAA,EAAAA,MAAA,OAAKC,UAAU,iBAAgBxC,SAAA,EAC7BJ,EAAAA,EAAAA,KAAA,OAAK4C,UAAU,2BAA0BxC,UACvCJ,EAAAA,EAAAA,KAACmsD,EAAAA,IAAgB,CAAC1pD,MAAOA,EAAOoJ,MAAO0gD,EAAYH,gBAAiBI,EAAaN,SAAUc,OAE7FhtD,EAAAA,EAAAA,KAAA,OAAK4C,UAAU,gCAA+BxC,UAC5CJ,EAAAA,EAAAA,KAACitD,EAAAA,IAAW,IACNL,EACJnqD,MAAOkqD,EACPO,cACEltD,EAAAA,EAAAA,KAACkD,EAAAA,IAAS,CAAC4hD,GAAG,MAAM3hD,KAAK,QAAQP,UAAU,wDAAuDxC,SAC/FqsD,IAGLP,SAAUW,EACVtrD,MAAOkW,OAAOg1C,GACd,cAAaC,QAKvB,CC1CO,SAASS,EAAW7xD,GAAoE,IAAnE,MAAEmH,EAAQ,SAAQ,MAAElB,EAAK,SAAE2qD,EAAQ,IAAE7zC,EAAG,IAAEG,GAAuBld,EAC3F,OACE0E,EAAAA,EAAAA,KAACssD,EAAkB,CACjB7pD,MAAOA,EACP8pD,YAAY3uB,EAAAA,EAAAA,KAAkBr8B,EAAMsK,OACpC2gD,YAAY,2BACZC,WAAYlrD,EAAMpG,MAClByxD,WAAY,CAAEv0C,IAAKA,GAAO,EAAGG,IAAKA,GAAO,EAAGkW,KAAM,GAClDi+B,WAAW,QACXD,YAAY,2BACZR,SAAUA,CAACrgD,EAAe1Q,IAAkB+wD,EAAS,CAAErgD,QAAO1Q,WAGpE,CCtBO,SAASiyD,EAAQ9xD,GAA4C,IAA3C,MAAEmH,EAAK,MAAElB,EAAK,SAAE2qD,GAAyB5wD,EAChE,OACE0E,EAAAA,EAAAA,KAACqtD,EAAAA,IAAQ,CACPC,QAAS/rD,EACT2qD,SAAW33D,GAA4C23D,EAAS33D,EAAGw4D,cAAcO,SACjF,cAAY,uBAAsBltD,SAEjCqC,GAGP,CChBA,MAAM8qD,EAAc,CAClB,CAAEhsD,MAAO,QAASkB,MAAO,SACzB,CAAElB,MAAO,UAAWkB,MAAO,YAetB,SAAS+qD,EAASlyD,GAAsC,IAArC,MAAEiG,EAAK,SAAE2qD,GAA0B5wD,EAC3D,MAAOoe,EAAQ+zC,IAAavI,EAAAA,EAAAA,UAAS3jD,EAAMmY,SACpCvW,EAAMuqD,IAAWxI,EAAAA,EAAAA,UAAS3jD,EAAM4B,OAChC2G,EAAO6jD,IAAYzI,EAAAA,EAAAA,UAAS3jD,EAAMuI,QAClC6P,EAAQi0C,IAAa1I,EAAAA,EAAAA,UAAS3jD,EAAMoY,QAErCk0C,GAAWf,EAAAA,EAAAA,cACf,CAACxrD,EAAKwsD,EAAavsD,KACjBusD,EAAYvsD,GACZ2qD,EAAS,CAAExyC,SAAQvW,OAAM2G,QAAO6P,SAAQ,CAACrY,GAAMC,GAAQ,GAEzD,CAACmY,EAAQvW,EAAM2G,EAAO6P,EAAQuyC,IAGhC,OACElsD,EAAAA,EAAAA,KAAA,OAAAI,UACEuC,EAAAA,EAAAA,MAAA,OAAKC,UAAU,2BAA0BxC,SAAA,EACvCJ,EAAAA,EAAAA,KAAC+tD,EAAAA,IAAK,CAAC52D,MAAM,OAAOyL,UAAU,gBAAexC,UAC3CJ,EAAAA,EAAAA,KAACguD,EAAAA,IAAM,CACLprD,UAAU,SACV,aAAW,OACXqrD,MAAOV,EACPhsD,MAAOA,EAAMmY,OACbwyC,SAAWgC,GAAaL,EAAS,SAAUJ,EAAWS,EAAS3sD,OAC/D,cAAY,+BAGhBvB,EAAAA,EAAAA,KAACmuD,EAAAA,IAAK,CACJ1rD,MAAM,OACN6G,KAAK,SACL+O,IAAI,IACJG,IAAI,KACJ0zC,SAAW33D,GAA4Cs5D,EAAS,OAAQH,EAASn5D,EAAGw4D,cAAcxrD,OAClGA,MAAO4B,EACP,cAAY,2BAGdnD,EAAAA,EAAAA,KAACqtD,EAAAA,IAAQ,CACPC,QAAoB,SAAX3zC,EACTuyC,SAAW33D,GACTs5D,EAAS,SAAUD,EAAWr5D,EAAGw4D,cAAcO,QAAU,OAAS,UAEpE,cAAY,0BAAyBltD,SACtC,UAGDJ,EAAAA,EAAAA,KAACqtD,EAAAA,IAAQ,CACPC,QAAmB,WAAVxjD,EACToiD,SAAW33D,GACTs5D,EAAS,QAASF,EAAUp5D,EAAGw4D,cAAcO,QAAU,SAAW,UAEpE,cAAY,yBAAwBltD,SACrC,eAMT,CC9DO,SAASguD,EAAS9yD,GAAsD,IAArD,MAAEmH,EAAQ,OAAM,MAAElB,EAAK,SAAE2qD,GAA0B5wD,EAC3E,OACE0E,EAAAA,EAAAA,KAACssD,EAAkB,CACjB7pD,MAAOA,EACP8pD,YAAY3uB,EAAAA,EAAAA,KAAkBr8B,EAAMsK,OACpC2gD,YAAY,yBACZC,WAAYlrD,EAAMpG,MAClByxD,WAAY,CAAEv0C,IAAK,EAAGG,IAAK,EAAGkW,KAAM,GACpCi+B,WAAW,QACXD,YAAY,yBACZR,SAAUA,CAACrgD,EAAO1Q,IAAU+wD,EAAS,CAAErgD,QAAO1Q,WAGpD,CCnBO,SAASkzD,EAAoB/yD,GAAkE,IAAjE,MAAEmH,EAAK,MAAElB,EAAK,SAAE+X,EAAQ,SAAE4yC,GAAqC5wD,EAClG,OACE0E,EAAAA,EAAAA,KAACsuD,EAAAA,IAAQ,CACP7rD,MAAOA,EACP6W,SAAUA,EACVi1C,YAAY,mBACZrC,SAAWhzD,GAA8CgzD,EAAShzD,EAAEs1D,OAAOjtD,OAC3EA,MAAOA,EACPktD,WAAS,EACT,cAAY,yCAGlB,CCPO,SAASC,EAAY/3D,GAC1B,MAAM,MAAE8L,EAAK,KAAE1L,EAAI,MAAEwK,EAAK,SAAE+X,EAAQ,IAAEjB,EAAG,IAAEG,EAAG,KAAEkW,EAAI,aAAES,GAAe,GAAUx4B,EAE/E,OACEqJ,EAAAA,EAAAA,KAACmuD,EAAAA,IAAK,CACJ7kD,KAAK,SACL7G,MAAOA,EACP1L,KAAMA,EACNuiB,SAAUA,EACVq1C,QAASx/B,EAAe,qBAAuB,SAC/C5tB,MAAOA,EACP8W,IAAKA,GAAO,EACZG,IAAKA,EACLkW,KAAMA,EACNw9B,SAAWhzD,GACTvC,EAAMu1D,SAAS/8B,EAAezX,WAAWxe,EAAEs1D,OAAOjtD,OAASuvC,SAAS53C,EAAEs1D,OAAOjtD,MAAO,KAEtF,cAAY,4BAGlB,CCxBO,SAASqtD,EAAYj4D,GAC1B,MAAM,MAAE8L,EAAK,KAAE1L,EAAI,MAAEwK,EAAK,SAAE+X,GAAa3iB,EAEzC,OACEqJ,EAAAA,EAAAA,KAACmuD,EAAAA,IAAK,CACJ7kD,KAAK,OACL7G,MAAOA,EACP1L,KAAMA,EACNuiB,SAAUA,EACV/X,MAAOA,EACP2qD,SAAWhzD,GAA2CvC,EAAMu1D,SAAShzD,EAAEs1D,OAAOjtD,OAC9E,cAAY,gCAGlB,CCXO,SAASstD,EAAKvzD,GAAuC,IAAtC,MAAEiG,EAAK,SAAE2qD,GAA2B5wD,EACxD,OACEqH,EAAAA,EAAAA,MAAA,OAAKC,UAAU,2BAA0BxC,SAAA,EACvCJ,EAAAA,EAAAA,KAACqtD,EAAAA,IAAQ,CACPC,QAAS/rD,EAAMiC,OACf0oD,SAAW33D,GAA4C23D,EAAS,IAAK3qD,EAAOiC,OAAQjP,EAAGw4D,cAAcO,UACrG,cAAY,8BAEdttD,EAAAA,EAAAA,KAACmuD,EAAAA,IAAK,CACJ7kD,KAAK,SACLolB,KAAK,MACLw9B,SAAW33D,GACT23D,EAAS,IAAK3qD,EAAOmyB,MAAOn/B,EAAGw4D,cAAc+B,gBAE/CvtD,MAAOA,EAAMmyB,MACb,cAAY,6BAEd1zB,EAAAA,EAAAA,KAACmsD,EAAAA,IAAgB,CACftgD,OAAO+xB,EAAAA,EAAAA,KAAkBr8B,EAAMsK,OAC/BqgD,SAAWrgD,GAAkBqgD,EAAS,IAAK3qD,EAAOsK,MAAOA,IACzDugD,gBAAgB,8BAIxB,C,8CCnBO,SAAS2C,EAAezzD,GAA4D,IAA3D,MAAEiG,EAAK,SAAE2qD,EAAQ,eAAE8C,GAAsC1zD,EACvF,MAAO2zD,EAAOC,GAAYlwD,EAAAA,SAAeuC,EAAM0tD,QACxCvmC,EAAMymC,GAAWnwD,EAAAA,SAAeuC,EAAMmnB,OACtCC,EAAIE,GAAS7pB,EAAAA,SAAeuC,EAAMonB,KACnC,SAAEymC,GAAa7tD,EACf8tD,EAAaD,EAASE,OAAO,GAAGl2B,cAAgBg2B,EAASp7D,MAAM,GAE/D65D,EAAW7uD,EAAAA,aACf,CAACsC,EAAKwsD,EAAavsD,KACjBusD,EAAYvsD,GACZ2qD,EAAS,CAAEkD,WAAUH,QAAOvmC,OAAMC,KAAI,CAACrnB,GAAMC,GAAQ,GAEvD,CAAC6tD,EAAUH,EAAOvmC,EAAMC,EAAIujC,IAE9B,OACElsD,EAAAA,EAAAA,KAAA,OAAoB4C,UAAU,qBAAoBxC,UAChDuC,EAAAA,EAAAA,MAAA,OAAKC,UAAU,8BAA6BxC,SAAA,EAC1CJ,EAAAA,EAAAA,KAACqtD,EAAAA,IAAQ,CACPzqD,UAAU,iBACV0qD,SAAU2B,EACV,cAAc,uBAAsBG,IACpClD,SAAWhzD,GAA2C20D,EAAS,QAASqB,GAAWh2D,EAAEs1D,OAAOlB,SAASltD,SAEpG4uD,GAAkBK,KAEnBL,IACArsD,EAAAA,EAAAA,MAAAiC,EAAAA,SAAA,CAAAxE,SAAA,EACEJ,EAAAA,EAAAA,KAACmuD,EAAAA,IAAK,CACJjpD,SAAU+pD,EACVrsD,UAAU,OACV0G,KAAK,SACLvS,KAAO,GAAEq4D,SACT7tD,MAAOmnB,EACPrQ,IAAKsf,EAASy3B,GAAU1mC,KACxBlQ,IAAKxF,KAAKqF,IAAIsf,EAASy3B,GAAUzmC,GAAIA,GACrCujC,SAAW33D,GACTs5D,EAAS,OAAQsB,EAAS13C,OAAOljB,EAAGw4D,cAAcxrD,QAEpD,cAAc,oBAAmB6tD,YAEnCpvD,EAAAA,EAAAA,KAAA,QAAAI,SAAM,OACNJ,EAAAA,EAAAA,KAACmuD,EAAAA,IAAK,CACJjpD,SAAU+pD,EACVrsD,UAAU,OACV0G,KAAK,SACLvS,KAAO,GAAEq4D,OACT7tD,MAAOonB,EACPtQ,IAAKrF,KAAKwF,IAAImf,EAASy3B,GAAU1mC,KAAMA,GACvClQ,IAAKmf,EAASy3B,GAAUzmC,GACxBujC,SAAW33D,GACTs5D,EAAS,KAAMhlC,EAAOpR,OAAOljB,EAAGw4D,cAAcxrD,QAEhD,cAAc,oBAAmB6tD,UAEnCpvD,EAAAA,EAAAA,KAACkD,EAAAA,IAAS,CAAA9C,SAAEivD,WAvCVD,EA6Cd,CC7DO,MAAMz3B,EAA0B,CAErC,CAAC7O,EAAAA,GAAe+0B,SAAU,CAAEoR,OAAO,EAAOvmC,KAAM,EAAGC,GAAI,IACvD,CAACG,EAAAA,GAAeogB,OAAQ,CAAE+lB,OAAO,EAAOvmC,KAAM,EAAGC,GAAI,IACrD,CAACG,EAAAA,GAAeg1B,MAAO,CAAEmR,OAAO,EAAOvmC,KAAM,EAAGC,GAAI,KACpD,CAACG,EAAAA,GAAei1B,OAAQ,CAAEkR,OAAO,EAAOvmC,KAAM,EAAGC,GAAI,IACrD,CAACG,EAAAA,GAAe2uB,QAAS,CAAEwX,OAAO,EAAOvmC,KAAM,EAAGC,GAAI,KAGlD4mC,EAAmB,CAACzmC,EAAAA,GAAe+0B,QAAS/0B,EAAAA,GAAeogB,OAE3DsmB,EAAmBjuD,IACvB,MAAMkuD,EAAe50C,IAAM,CAAC,EAAG8c,GAC/B,IAAK,MAAMnP,KAAcinC,EAAc,CACrC,MAAMC,EAAiBlnC,EACjBmnC,EAAsBpuD,IAAQmuD,GAC/BC,IAC2C,IAA5C/4D,OAAOC,KAAK84D,GAAqB/7D,OACnC67D,EAAaC,GAAkB,IAAKD,EAAaC,GAAiBT,OAAO,GAEzEQ,EAAaC,GAAkB,IAAKD,EAAaC,MAAoBC,GAEzE,CACA,OAAOF,CAAY,EAGfG,EAA6CruD,GAClC3K,OAAOC,KAAKiyB,EAAAA,IAAgB+/B,OAAOgH,IAChD,MAAMC,EAAavuD,EAAMsuD,GAEzB,OACEC,IACoC,IAAnCl5D,OAAOC,KAAKi5D,GAAYl8D,SACtBoqD,EAAAA,GAAoB6R,GAAkC/zD,MAAMvG,IAC3DkzB,EAAAA,EAAAA,IAAU,CACRlnB,MAAOhM,EACP8iB,IAAKy3C,GAAYpnC,MAAQiP,EAASk4B,GAAkCnnC,KACpElQ,IAAKs3C,GAAYnnC,IAAMgP,EAASk4B,GAAkClnC,OAEpE,IAMH,SAASonC,EAAWp5D,GACzB,MAAMq5D,EAAuBhxD,EAAAA,OAA4BwwD,EAAgB74D,EAAM4K,QAEzE0uD,EAAgB1uD,IACpB,MAAM+0B,EAAsB3/B,EAAM4K,MAAQsZ,IAAM,CAAC,EAAGlkB,EAAM4K,OAAS,CAAC,EACpE+0B,EAAO/0B,EAAM6tD,UAAY,CAAC,EAEtB7tD,EAAM0tD,MACRt4D,EAAMu1D,SAAS51B,GACN/0B,EAAMmnB,OAASiP,EAASp2B,EAAM6tD,UAAU1mC,MAAQnnB,EAAMonB,KAAOgP,EAASp2B,EAAM6tD,UAAUzmC,WACxF2N,EAAO/0B,EAAM6tD,UACpBz4D,EAAMu1D,SAAS51B,KAEX/0B,EAAMmnB,OAASiP,EAASp2B,EAAM6tD,UAAU1mC,OAC1C4N,EAAO/0B,EAAM6tD,UAAW1mC,KAAOnnB,EAAMmnB,MAEnCnnB,EAAMonB,KAAOgP,EAASp2B,EAAM6tD,UAAUzmC,KACxC2N,EAAO/0B,EAAM6tD,UAAWzmC,GAAKpnB,EAAMonB,IAErChyB,EAAMu1D,SAAS51B,IAGjB3/B,EAAMu5D,sBACJN,EAA0Ct5B,IACtC,sFAEL,EAGH,OAAO1/B,OAAOC,KAAKm5D,EAAqBx9D,SAAS6O,KAAK+tD,IACpDpvD,EAAAA,EAAAA,KAAC+uD,EAAe,CAEdxtD,MAAO,IAAKyuD,EAAqBx9D,QAAQ48D,GAA6BA,SAAUA,GAChFJ,gBAAiBO,EAAiBxhC,SAASqhC,GAC3ClD,SAAU+D,GAHJ,cAAab,MAMzB,CC7CA,MAAMe,EAA0B,CAAE7mD,KAAM,SAAmB1G,UAAW,SAAUzC,aAAc,eAmB9F,SAASiwD,EAAuBC,GAC9B,OAAOA,EAAU3vD,QAAO,CAACC,EAAiB2vD,KACxC3vD,EAAI2vD,EAAIv5D,MAAQu5D,EAAI/uD,MACbZ,IACN,CAAC,EACN,CAAC,IAEI4vD,EAAU,SAAVA,GAAU,OAAVA,EAAAA,EAAU,iBAAVA,EAAAA,EAAU,2BAAVA,CAAU,EAAVA,GAAU,IAKR,SAASC,EAAmB75D,GACjC,MAAMgxB,EAAShxB,EAAMlB,QAAQiyB,iBACvB+oC,EAAsBzxD,EAAAA,OAAmC2b,KAAKsmC,MAAMtmC,KAAKC,UAAU+M,EAAO/S,WACzFy7C,EAAWK,GAAgB1xD,EAAAA,SAAqC2oB,EAAO/S,SACvE+7C,EAAaC,GAAkB5xD,EAAAA,SAAeuxD,EAAWM,QACzDC,EAAkBC,GAAuB/xD,EAAAA,UAA+B,GAEzEgyD,EAAmBr6D,EAAMlB,QAAQkxB,eAEvC3nB,EAAAA,WAAgB,KACdrI,EAAMlB,QAAQmwB,kBAAmB,EAC1B,KACLjvB,EAAMlB,QAAQmwB,kBAAmB,EACjCjvB,EAAMlB,QAAQyH,QAAQ,SAAUvG,EAAMlB,QAAQ,IAG/C,IAEH,MAAMw7D,EAAqBjyD,EAAAA,aACzB1D,IAQM,IARL,OACCO,EAAM,aACNq1D,GAAe,EAAK,cACpBC,GAAgB,GAKjB71D,EACC,MAAM81D,EAAwC,mBAAnBz6D,EAAM06D,SAC3BC,EAA0C,mBAApB36D,EAAM46D,UAElC56D,EAAMlB,QAAQqd,IAAIjX,GACdq1D,GAAgBE,EAClBz6D,EAAM06D,SAAUx1D,GACPs1D,GAAiBG,GAC1B36D,EAAM46D,aAGJL,GAAgBC,IAClBx6D,EAAM2D,MAAMgpD,MACd,GAEF,CAAC3sD,IAGG66D,EAAgCxyD,EAAAA,OACpCyyD,KACGC,IACC,MAAM71D,EAASu0D,EAAuBsB,GACtCT,EAAmB,CAAEp1D,UAAS,GAEhC,GACA,CAAE81D,QAAS,OAIf3yD,EAAAA,WACE,IAAM,KACJwyD,EAA8Bh/D,QAAQo/D,QAAQ,GAEhD,IAGF,MAAMP,EAAoDryD,EAAAA,aACvDzK,IAEC,GADAA,EAAGivD,iBACCjvD,EAAGw4D,cAAc8E,gBAAiB,CACpC,MAAMh2D,EAASu0D,EAAuBC,GACtCY,EAAmB,CAAEp1D,SAAQq1D,cAAc,GAC7C,IAEF,CAACb,EAAWY,IAGRa,EAAoB9yD,EAAAA,aAAkB,KAC1C,MAAMnD,EAASu0D,EAAuBK,EAAoBj+D,SAC1Dy+D,EAAmB,CAAEp1D,SAAQs1D,eAAe,GAAO,GAClD,CAACF,IAQJ,OACEtuD,EAAAA,EAAAA,MAACovD,EAAAA,IAAM,CACLC,aAAW,EACXC,OAAO,EACPrvD,UAAU,OACV,cAAY,gBACZtI,MAAO3D,EAAM2D,MACb,aAAYqtB,EAAOxwB,OAAS,aAC5B+6D,UAAUlyD,EAAAA,EAAAA,KAAA,OAAK6lB,YAAaisC,IAC5BK,cAAex7D,EAAMy7D,OAAOhyD,SAAA,EAE5BJ,EAAAA,EAAAA,KAACqyD,EAAAA,IAAY,CAACC,aAAcR,EAAkB1xD,SAAEunB,EAAOxwB,SACvDwL,EAAAA,EAAAA,MAAA,QAAM0uD,SAAUA,EAAUzuD,UAAU,gCAA+BxC,SAAA,EACjEuC,EAAAA,EAAAA,MAAC4vD,EAAAA,IAAU,CAAC3vD,UAAU,YAAWxC,SAAA,CAC9B4wD,IACCruD,EAAAA,EAAAA,MAAC6vD,EAAAA,IAAW,CAACC,YAAY,EAAO7vD,UAAU,SAAQxC,SAAA,EAChDJ,EAAAA,EAAAA,KAACC,EAAAA,IAAM,IACDkwD,EACJ3sD,OAAQmtD,IAAgBJ,EAAWM,MACnCtxD,QAASA,IAAMqxD,EAAeL,EAAWM,OACzC,cAAY,0BAAyBzwD,SACtC,WAGDJ,EAAAA,EAAAA,KAACC,EAAAA,IAAM,IACDkwD,EACJ3sD,OAAQmtD,IAAgBJ,EAAWR,WACnCxwD,QAASA,IAAMqxD,EAAeL,EAAWR,YACzC,cAAY,+BAA8B3vD,SAC3C,kBAMJiwD,EAAUhvD,KAAKumB,IACd,MAAM8qC,EArLlB,SAAyBppD,GACvB,OAAQA,GACN,IAAK,SACH,OAAOolD,EACT,IAAK,SAEL,IAAK,OACH,OAAOE,EACT,IAAK,aACH,OAAO3C,EACT,IAAK,SACH,OAAOkB,EACT,IAAK,OACH,OAAOiB,EACT,IAAK,mBACH,OAAOC,EACT,IAAK,OACH,OAAOb,EACT,IAAK,WACH,OAAOJ,EACT,IAAK,QACH,OAAOyB,EACT,IAAK,aACH,OAAOkB,EACT,QACE,MAAO,KAAM/vD,EAAAA,EAAAA,KAAA,OAAAI,SAAK,8BAExB,CA0JmCuyD,CAAgB/qC,EAAMte,MAI7C,OA9C0BspD,EA+CGhrC,EAAMte,MA9CvCqnD,IAAgBJ,EAAWR,YAA4B,eAAd6C,GACzCjC,IAAgBJ,EAAWR,YAA4B,eAAd6C,KA8CjC5yD,EAAAA,EAAAA,KAAC0yD,EAAc,IAET9qC,EACJskC,SAAW3qD,IACTmvD,GAAch5D,IACZ,MAAMg6D,EAAeh6D,EAAU2J,KAAKwxD,GAC9BA,EAAW97D,OAAS6wB,EAAM7wB,KACrB,IAAK87D,EAAYtxD,SAEnBsxD,IAGT,OADArB,EAA8Bh/D,QAAQk/D,GAC/BA,CAAY,GACnB,EAEJxB,oBAAqBa,GAdhBnpC,EAAM7wB,MAjDS67D,KAiEvB,QAIPjwD,EAAAA,EAAAA,MAACmwD,EAAAA,IAAY,CAAA1yD,SAAA,EACXJ,EAAAA,EAAAA,KAACC,EAAAA,IAAM,CAACqJ,KAAK,SAAS/J,QAASuyD,EAAmB,cAAY,uBAAsB1xD,SAAC,WAGrFJ,EAAAA,EAAAA,KAACC,EAAAA,IAAM,CACL5F,MAAM,OACNiP,KAAK,SACL,cAAY,wBACZpE,WAAY4rD,EACZ35D,MAAO25D,GAAoB,SAAS1wD,SACrC,iBAOX,CAEO,MAAM2yD,EAA4B/zD,EAAAA,eAA4C,SAU9E,SAASg0D,EAA0Br8D,GACxC,MAAOlB,EAASw9D,GAAcj0D,EAAAA,SAAqC,OAC5DqyD,EAAU6B,GAAel0D,EAAAA,SAA6B,OACtDuyD,EAAW4B,GAAgBn0D,EAAAA,SAA8B,MAC1Do0D,GAASC,EAAAA,EAAAA,OAoBf,OACE1wD,EAAAA,EAAAA,MAACowD,EAA0BO,SAAQ,CAAC/xD,MAnBnBgyD,CAAC99D,EAAwB47D,EAAyBE,KAC/DF,GACF6B,GAAY,IAAM7B,IAEhBE,GACF4B,GAAa,IAAM5B,IAGrB0B,EAAWx9D,GACX29D,EAAO5qD,MAAM,EAUyCpI,SAAA,CACnDzJ,EAAMyJ,SACN3K,IACCuK,EAAAA,EAAAA,KAACwwD,EAAkB,CACjBl2D,MAAO84D,EACP39D,QAASA,EACT47D,SAAUA,EACVE,UAAWA,EACXa,OAfOA,KACba,EAAW,MACXC,EAAY,MACZC,EAAa,KAAK,MAiBtB,C,wOCtRO,MACMK,EAA4B,I,4BCTzC,MAAMC,GAAc,EAEb,SAASC,KACd,MAAMC,EAAoB30D,EAAAA,OAAa,GACjC40D,EAAsB50D,EAAAA,OAAa,GACnCsQ,GAAsBC,EAAAA,EAAAA,OAEtBskD,EAAgB70D,EAAAA,aACpB3D,UAQM,IARC,QACL08C,EAAO,eACPmI,EAAc,WACdZ,GAKDhkD,EACC,IAcE,aAbmBw4D,EAAAA,EAAAA,IAEhB,CACDt1D,SAAU,sBACVu1D,gBAAiB,CACfx0B,OAAQwY,EAAQvgD,KAAK,KACrB0oD,eAAgBA,EAAe1oD,KAAK,WAAQwE,EAC5CimD,oBAAqB3C,EAAW0C,GAChCE,kBAAmB5C,EAAWvnB,MAC9BqqB,mBAAoB9C,EAAW6C,MAEjC6R,mBAAoB,CAAC,IAAK,QAEhBzS,SAASlgD,KAAKo/C,IAAYe,EAAAA,EAAAA,IAA+Bf,IACvE,CAAE,MACA,CAGF,MAAO,EAAE,GAEX,IAGIwT,EAAej1D,EAAAA,aACnB3D,UACE,GAAwB,IAApBkmD,EAAS3tD,OAIb,IACE,MAAMsgE,EAAiBv5C,KAAKC,UAAU2mC,EAASlgD,KAAK9L,IAAS8sD,EAAAA,EAAAA,IAA+B9sD,MAC5F,IAAI4+D,GAAY,EAChB,IACEA,EChEH,SAA+Bx9B,GAEpC,IAAI2V,EAAI,EACR,IAAK,IAAIz2B,EAAI,EAAGnT,EAAIi0B,EAAE/iC,OAAQiiB,EAAInT,EAAGmT,IAAK,CACxC,MAAMu+C,EAAKz9B,EAAE09B,WAAWx+C,GACxB,GAAIu+C,EAAK,IACP9nB,GAAK,OACA,GAAI8nB,EAAK,KACd9nB,GAAK,OACA,GAAI8nB,EAAK,MACd9nB,GAAK,OACA,GAAI8nB,EAAK,MAAQ,CACtB,MAAME,EAAK39B,EAAE09B,aAAax+C,GAC1B,KAAIA,EAAInT,GAAK4xD,GAAM,OAAUA,GAAM,OAGjC,MAAM,IAAIv3D,MAAM,0BAFhBuvC,GAAK,CAIT,KAAO,IAAI8nB,EAAK,MACd,MAAM,IAAIr3D,MAAM,0BAEhBuvC,GAAK,CACP,CACF,CACA,OAAOA,CACT,CDuCsBioB,CAAsBL,GAAkB,IACtD,CAAE,MAAOj9D,GACPuC,OAAOwV,QAAQlS,iBAAiB7F,EAClC,OACM68D,EAAAA,EAAAA,IAAS,CACbt1D,SAAU,sBACVg2D,OAAQ,OACRR,mBAAoB,CAAC,IAAK,IAAK,IAAK,IAAK,KACzCS,YAAaC,EAAAA,GAAYC,gBACzBj1D,KAAMw0D,EACNC,cAEF,MAAOS,GAAmB,IAAIrT,GAAUhhD,MAAK,CAACC,EAAGC,KAAMygD,EAAAA,GAAAA,IAAWzgD,EAAE6+C,WAAY9+C,EAAE8+C,cAElF,OADAqU,EAAkBnhE,QAAU,EACrBoiE,EAAgBtV,UACzB,CAAE,MAAOroD,GACP,GAAIA,aAAiB49D,EAAAA,GAAqB,CAExC,GAAIlB,EAAkBnhE,QAAUihE,GAG9B,OAFAE,EAAkBnhE,QAAUmhE,EAAkBnhE,QAAU,QAClD,IAAIse,SAASC,GAAMC,WAAWD,EAAG,OAChCkjD,EAAa1S,GAGpBoS,EAAkBnhE,QAAU,CAEhC,KAAO,IAAIyE,aAAiB69D,EAAAA,GAE1B,OACK,GAAI79D,aAAiB89D,EAAAA,GAAW,CACrC,MAAMC,EAAa/9D,EAAMg+D,SAAwBD,UAC3CE,EAAUF,EACX,WAAUzT,EAAS,GAAGhiB,2BAA2By1B,KACjD,WAAUzT,EAAS,GAAGhiB,4BAM3B,YALAjwB,EAAoB9G,MAClBxI,EAAAA,EAAAA,KAACkQ,EAAAA,GAAY,CAAC20C,SAAS7kD,EAAAA,EAAAA,KAAA4E,EAAAA,SAAA,IAAOuL,YAAa,IAAK/P,UAC9CJ,EAAAA,EAAAA,KAACkD,EAAAA,IAAS,CAACN,UAAU,WAAUxC,SAAE80D,MAIvC,EAaA,YAVA17D,OAAOwV,QAAQlS,iBAAiB7F,EAAO,CACrC+F,OAAQ/F,aAAiBk+D,EAAAA,GACpBl+D,EAAMg+D,SAAwBG,aAC/B7T,GACF7gD,QACA,CAACC,EAAiB2vD,EAAiB16D,KAAkB,IAAM+K,EAAK,CAAE,QAAO/K,KAAU+kB,KAAKC,UAAU01C,MAClG,CAAC,IAKP,IAEF,CAAChhD,IAGG+lD,EAAoBr2D,EAAAA,aACxB3D,UAAoG,IAA7F,QAAE08C,EAAO,gBAAEud,GAA8Dv5D,EAC9E,IACE,MAAMw5D,GAASvU,EAAAA,GAAAA,IAAasU,EAAiB17D,KAAKC,aAC5Ci6D,EAAAA,EAAAA,IAAS,CACbt1D,SAAW,8BAA6Bu5C,EAAQvgD,KAAK,4BACnD+9D,EAAOvT,wBACauT,EAAOx9B,4BAA4Bw9B,EAAOpT,OAChEqS,OAAQ,SACRR,mBAAoB,CAAC,IAAK,IAAK,KAC/BG,WAAW,IAEbP,EAAoBphE,QAAU,CAChC,CAAE,MAAOyE,GACP,GAAIA,aAAiB49D,EAAAA,GAAqB,CAExC,GAAIjB,EAAoBphE,QAAUihE,GAGhC,OAFAG,EAAoBphE,QAAUohE,EAAoBphE,QAAU,QACtD,IAAIse,SAASC,GAAMC,WAAWD,EAAG,OAChCskD,EAAkB,CAAEtd,UAASud,oBAGpC1B,EAAoBphE,QAAU,CAElC,MAAO,GAAIyE,aAAiB69D,EAAAA,GAE1B,OAIFt7D,OAAOwV,QAAQlS,iBAAiB7F,EAClC,IAEF,IAGF,MAAO,CAAE48D,gBAAeI,eAAcoB,oBACxC,CE5IO,SAASG,GAA2B7wD,GACzC,MAAM,cAAEkvD,EAAa,aAAEI,EAAY,kBAAEoB,GAAsB3B,KACrD+B,EClBD,SAA6B9wD,GAClC,MAAM3C,GAAmBC,EAAAA,EAAAA,GAAc0C,EAAa,CAClDzC,gBAAiB,CAAC,SAAU,2BAA4B,WAEpD,KAAEiD,EAAI,OAAEuwD,EAAM,yBAAEtO,GAA6BplD,EACnD,OAAOhD,EAAAA,SACL,KACE22D,EAAAA,EAAAA,IAA0C3zD,IAAqBolD,KAA8BsO,IAAWvwD,GAAMtQ,IAChH,CAACuyD,EAA0BsO,EAAQvwD,GAAMtQ,GAAImN,GAEjD,CDQ2B4zD,CAAoBjxD,GACvCkxD,EAAwB72D,EAAAA,SAAc,IAAM2F,EAAYkxD,yBAAyB,CAAClxD,IAClFmxD,EAAiB92D,EAAAA,SAEvBA,EAAAA,WACE,IAAM,KACA82D,EAAetjE,SACjBujE,aAAaD,EAAetjE,QAC9B,GAEF,IAGF,MAAMwjE,EAAoBh3D,EAAAA,aACxB,WAGK,IAFHi3D,EAAalhE,UAAAnB,OAAA,QAAAoI,IAAAjH,UAAA,GAAAA,UAAA,GAAGy+D,EAChB0C,EAAyEnhE,UAAAnB,OAAA,QAAAoI,IAAAjH,UAAA,GAAAA,UAAA,GAAG,KAExE+gE,EAAetjE,SACjBujE,aAAaD,EAAetjE,SAE9B,MAAM2jE,EAAYN,EAAsBxsD,SAASkC,QAC9ChW,IACC2rD,EAAAA,GAAAA,IAAW3rD,EAAK+pD,WAAYuW,EAAsBO,4BAA8B,GAChF7gE,EAAK+pD,WAAW6C,OAAS0T,EAAsBQ,eACb,OAAjCH,GAAyCA,EAA6B3gE,MAE3E,GAAyB,IAArB4gE,EAAUviE,OACZ,OAGFiiE,EAAsBS,iBAAiBC,EAAAA,GAAcC,SAErD,MAAMlzC,EAAOjoB,UACXw6D,EAAsBS,iBAAiBC,EAAAA,GAAcE,QACrD,MAAMngC,QAAe29B,EAAakC,GAQlC,OAPI7/B,GACFu/B,EAAsB/xD,iBAAiB,CACrCsyD,4BAA4B1V,EAAAA,GAAAA,IAAWmV,EAAsBO,2BAA4B9/B,KAG7Fu/B,EAAsBS,iBAAiBC,EAAAA,GAAcG,OAE9CpgC,CAAM,EAGf,GAAsB,IAAlB2/B,EACF,OAAO3yC,IAGTwyC,EAAetjE,QAAUgH,OAAOwX,WAAWsS,EAAM2yC,EACnD,GACA,CAAChC,EAAc4B,IAGXc,EAA0B33D,EAAAA,aAC7ByhD,IACC,GAA8B,SAA1BA,EAAQxB,cACV,OAEF,MAAM2X,EAAkC,YAAvBnW,EAAQ5B,WAEzBl6C,EAAYw7C,cAAcjkD,SAASxB,IACjC,MAAM6kC,EAAS7kC,EAAUskD,oBACnB6X,GAAoBrY,EAAAA,EAAAA,IAAiB9jD,GAC3C,IAAKm8D,GAAqBpW,EAAQlhB,SAAWA,EAC3C,OAEF,MAAMu3B,EAA4BjB,EAAsBxsD,SAASkC,QAC9DwrD,GAAoBA,EAAgBx3B,SAAWA,GAAUw3B,EAAgB9X,gBAAkB4X,IAG9F,IAAIphE,EADiBiF,EAAUinD,iBAElBzlD,SAAS86D,IACpB,GAAIA,EAAYpV,cAAgBoV,EAAY55D,SAASkoB,UAAW,CAC9D,MAAM2xC,EAAcH,EAA0Bt5D,MAAKlC,IAAA,IAAC,UAAEoC,GAAWpC,EAAA,OAAKoC,IAAcs5D,EAAYt5D,SAAS,IACpGu5D,GAA0C,YAA3BA,EAAYpY,WAErBmY,EAAYt5D,WAAas5D,EAAYt5D,YAAc+iD,EAAQ/iD,YACpEjI,EAAUuhE,GAFVA,EAAY3P,gBAIhB,KAGF,MAAM6P,EAAqBv8C,KAAKsmC,MAAMR,EAAQlB,cAC9C,GAAI9pD,EACEgrD,EAAQlB,eAAiB5kC,KAAKC,UAAUnlB,EAAQ2H,SAASyqB,sBACvDpyB,EAAQ4wB,OAAOC,YAAc7wB,EAAQ2H,UAAa3H,EAAQ0hE,0BAC5D1hE,EAAQ2H,SAAS0V,IAAIokD,GACrBzhE,EAAQ2H,SAASka,iBAGjBmpC,EAAQpB,SAAW5pD,EAAQ4pD,QAC7B5pD,EAAQqO,iBAAiB,CAAEu7C,OAAQoB,EAAQpB,UAEzCuX,GAAYC,IAAsBpW,EAAQxB,gBAC5CxpD,EAAQ4xD,sBAEL,IAAKuP,GAAYC,IAAsBpW,EAAQxB,cAAe,CACnE,MAAM7hD,GAAWg6D,EAAAA,GAAAA,GAAuBF,EAAmB5tD,MAAM4b,WAC/DgyC,EACAx8D,GAEFA,EAAU2O,WAAWguD,OAAO,CAAE35D,UAAW+iD,EAAQ/iD,UAAWN,WAAUiiD,OAAQoB,EAAQpB,SACtFjiD,EAASka,cACX,IACA,GAEJ,CAAC3S,EAAakxD,IAGVyB,EAA2Bt4D,EAAAA,aAC/B,CAACu4D,EAAch4B,KACb,GAAIA,EAAQ,CACV,MAAMi4B,EAAkC,CACtC95D,WAAWmkD,EAAAA,EAAAA,IAAiBtiB,GAC5B8f,OAAQ,EACR9f,OAAQA,EACR+f,YAAY0B,EAAAA,GAAAA,IAAa6U,EAAsBO,2BAA4Bx8D,KAAKC,OAChFglD,WAAY,SACZI,cAAe,OACfM,aAAc5kC,KAAKC,UAAU,CAAEpB,KAAM+9C,KAGvC1B,EAAsB/xD,iBAAiB,CACrCuF,SAAU,IACLwsD,EAAsBxsD,SAASkC,QAAOxP,IAAA,IAAC,UAAE2B,GAAW3B,EAAA,OAAK2B,IAAc85D,EAAe95D,SAAS,IAClG85D,IAGN,IAEF,CAAC3B,IAGG4B,EAAuBz4D,EAAAA,aAC1Bu4D,IACK5yD,EAAYQ,MAAMoyD,OAASA,IAAS5yD,EAAYQ,MAAQoyD,KAC1D5yD,EAAY0+B,gBAAgB,OAAQ,IAAK1+B,EAAYQ,KAAMoyD,SAC3DD,EAAyBC,EAAM5yD,EAAY+yD,aAAa1Y,0BAAuBhjD,GACjF,GAEF,CAAC2I,EAAa2yD,IAGVK,EAAqB34D,EAAAA,aACzB3D,iBAAgC,IAAzBilD,EAAYvrD,UAAAnB,OAAA,QAAAoI,IAAAjH,UAAA,IAAAA,UAAA,GACjB,MAAM,QAAEgjD,EAAO,eAAEmI,IAAmBD,EAAAA,EAAAA,IAAyCt7C,GACzE27C,GACFuV,EAAsB/xD,iBAAiB,CACrC8zD,6BAA6BC,EAAAA,GAAAA,IAAQhC,EAAsBQ,aAAc,KAI7E,MAAMhW,QAAwBwT,EAAc,CAC1C9b,UACAmI,iBACAZ,WAAYuW,EAAsB+B,+BAE9B,uBAAErX,EAAsB,kBAAEC,EAAiB,iBAAEhB,IAAqBY,EAAAA,EAAAA,IAAoC,CAC1GC,kBACAvB,qBAAsB+W,EAAsBxsD,SAC5C01C,oBAAqB8W,EAAsB+B,4BAC3CtX,iBAaF,GAVAuV,EAAsB/xD,iBAAiB,IAEjC08C,EAAkB5sD,OAAS,EAAI,CAAEyV,SAAUm2C,GAAqB,CAAC,EACrEoY,4BAA6BrX,EAC7B6V,2BACE9V,GAAgBd,EAAiB5rD,OAAS,GACtC8sD,EAAAA,GAAAA,IAAWmV,EAAsBO,2BAA4B7V,GAC7DsV,EAAsBO,6BAG1B5V,EAAkB5sD,OAAS,GAAK0sD,EAAc,CAChD0V,EAAkB,GAClB,MAAM8B,EAAcnzD,EAAYg9C,iBAchC,GAbAnB,EAAkBtkD,SAASwB,IACzB,MAAMjI,EAAUqiE,EAAYt6D,MAAM/H,GAAYA,EAAQiI,YAAcA,IAEhEjI,GAAWA,EAAQmsD,cAAgBnsD,EAAQ0hE,yBAC7C1hE,EAAQ4xD,gBACV,IAGFwO,EAAsBxsD,SAASnN,QAAQy6D,GACvChyD,EAAYw7C,cAAcjkD,SAASxB,IACjCA,EAAUq9D,mBAAmB,IAG3BpzD,EAAYK,6BAA+Bq7B,EAAAA,GAA2BkiB,UAAW,CACnF,MAAMyV,EAAerzD,EAAY+yD,aAAa1Y,qBAAuB,GACrEyY,GAAqB1V,EAAAA,EAAAA,IAAkB,CAAExiB,OAAQy4B,EAAc3uD,SAAUm2C,IAC3E,CACF,CACF,GACA,CACE76C,EACAkxD,EACAc,EACA9C,EACA4D,EACAzB,IAIEiC,EAAiCj5D,EAAAA,aACrC,CAACvJ,EAAkBopD,KACjB,MAAMqZ,GAAetZ,EAAAA,EAAAA,IAAsC,CACzDnpD,UACAopD,aACAC,qBAAsB+W,EAAsBxsD,SAC5C01C,qBAAqBiC,EAAAA,GAAAA,KACnBN,EAAAA,GAAAA,IACEmV,EAAsBO,2BACtBP,EAAsB+B,6BAExBh+D,KAAKC,SAIT,GAAIq+D,EAAc,CAChB,MAAM,kBAAEvY,EAAiB,iBAAEH,EAAgB,WAAEJ,GAAe8Y,EACxDvY,IACFkW,EAAsB/xD,iBAAiB,CAAEuF,SAAUm2C,IACnDmX,EAAwBvX,GAE5B,IAEF,CAACuX,EAAyBd,IAGtBsC,EAA6Bn5D,EAAAA,aAAkB3D,UACnD,MAAM,QAAE08C,IAAYkI,EAAAA,EAAAA,IAAyCt7C,SAEvD0wD,EAAkB,CAAEtd,UAASud,gBAAiBO,EAAsBO,mCACpEuB,GAAoB,GACzB,CAAChzD,EAAa0wD,EAAmBQ,EAAuB8B,IAErDS,EAAkBp5D,EAAAA,aACtB,CAACvJ,EAAkB4vB,EAAShtB,KAC1B,MAAMggE,EAAc5iE,EAAQ4wB,OAG5B,IAAK5wB,EAAQmsD,aAAensD,EAAQ2H,SAASkoB,YAAc+yC,EACzD,OAEF,MAAMC,GAAuB9Z,EAAAA,EAAAA,IAAiB6Z,GACxCE,EAAoBF,EAAYrZ,oBAMtC,GALsCr6C,EACnCw7C,cACArkD,MACEzG,IAAUmpD,EAAAA,EAAAA,IAAiBnpD,KAAWijE,GAAwBjjE,EAAM2pD,sBAAwBuZ,IAE9D,CACjC,MAAM3B,EAAWv+D,GAASmgE,YAAcC,EAAAA,GAAyBC,OACjET,EAA+BxiE,EAASmhE,EAAW,UAAY,SACjE,IAEF,CAACqB,EAAgCtzD,IAGnC,MAAO,CACLkxD,wBACAuC,kBACAX,uBACAU,6BACA1C,mBACA6B,2BACAX,0BACAX,oBACA2B,qBAEJ,CE9RA,SAASgB,GAAmBh0D,GAC1B,MAAM,gBACJyzD,EAAe,2BACfD,EAA0B,mBAC1BR,EAAkB,wBAClBhB,EAAuB,kBACvBX,EAAiB,iBACjBP,GACED,GAA2B7wD,GAEzBi0D,EAAiC55D,EAAAA,SAAc,IAAM2F,EAAYkxD,yBAAyB,CAAClxD,IAC3FkxD,GAAwB5zD,EAAAA,EAAAA,GAAc22D,EAAgC,CAAE12D,gBAAiB,CAAC,cAC1F22D,ECvBD,SAAqBt3D,GAC1B,MAAMu3D,EAAM95D,EAAAA,SAIZ,OAHAA,EAAAA,WAAgB,KACd85D,EAAItmE,QAAU+O,CAAK,GAClB,CAACA,IACGu3D,EAAItmE,OACb,CDiB+BumE,CAAYtD,GAEnCuD,EAAiCh6D,EAAAA,aAAkB3D,UACvDsJ,EAAYg9C,iBAAiBzlD,SAASzG,IAE/BogE,EAAsBxsD,SAASvN,MAAM2kD,GAAYA,EAAQ/iD,YAAcjI,EAAQiI,aAClF06D,EAAgB3iE,EAClB,UAKIugE,EAAkB,GAAIzgE,GAAgC,SAAvBA,EAAK0pD,gBAE1C0Y,GAAmB,EAAK,GACvB,CAACA,EAAoBhzD,EAAayzD,EAAiBvC,EAAsBxsD,SAAU2sD,IA+DtF,OA7DAh3D,EAAAA,WAAgB,KACVy2D,GACFO,GACF,GACC,CAACA,EAAmBH,EAAsBxsD,SAAUosD,IAEvDz2D,EAAAA,WAAgB,KACd,IAAKy2D,EAEH,YADA9wD,EAAYkxD,wBAAwBS,iBAAiBC,EAAAA,GAAc0C,KAGrEt0D,EAAYkxD,wBAAwBS,iBAAiBC,EAAAA,GAAcG,QAC9DmC,GAAwBpD,GAC3BuD,IAGF,IAAI,QAAEjhB,EAAO,eAAEmI,IAAmBD,EAAAA,EAAAA,IAAyCt7C,GAE3E,MAAMu0D,EAA2BA,KAC/B,MAAQnhB,QAASohB,EAAYjZ,eAAgBkZ,IAC3CnZ,EAAAA,EAAAA,IAAyCt7C,GAEzCgW,KAAKC,UAAUm9B,KAAap9B,KAAKC,UAAUu+C,IAC3Cx+C,KAAKC,UAAUslC,KAAoBvlC,KAAKC,UAAUw+C,KAElDrhB,EAAUohB,EACVjZ,EAAiBkZ,EACjBzB,GAAmB,GACrB,EAGF0B,EAAAA,EAAW/kE,KAAM,GAAE4pC,EAAAA,GAAkBC,0BAA2B+6B,GAChE56D,EAAAA,EAAQhK,KAAK,SAAU8jE,GAEvBvC,EAAsBxsD,SAASnN,QAAQy6D,GACvC,MAAM2C,EAA6BC,YAAY5B,ELtD4B,MKwDrE6B,EAAsBA,KAC1BC,cAAcH,GACdD,EAAAA,EAAW/jE,OAAQ,GAAE4oC,EAAAA,GAAkBC,0BAA2B+6B,GAClE56D,EAAAA,EAAQhJ,OAAO,SAAU8iE,EAAgB,EAS3C,OANAh6D,EAAAA,EAAY9J,KAAK,UAAWe,IACtBA,EAAMqkE,aACRF,GACF,IAGKA,CAAmB,GACzB,CACD70D,EACAkxD,EACA8B,EACAS,EACAzB,EACAlB,EACAoD,EACAG,IAGK,CAAEb,6BAA4B1C,mBACvC,C,gHE5FO,SAASkE,GAAgBr+D,GAAwC,IAAvC,UAAEuK,EAAS,MAAExQ,KAAUsB,GAAc2E,EACpE,MAAM,WAAEs+D,EAAU,eAAEC,GCIf,SAAsBv+D,GAAmE,IAAlE,UAAEuK,EAAS,MAAExQ,GAAmDiG,EAC5F,MAAMkD,GAAWkD,EAAAA,GAAAA,OACX,EAAEjB,EAAC,EAAEi2B,EAAC,GAAEojC,EAAE,GAAEC,EAAE,EAAE3vC,EAAI,IAAG,EAAErZ,IAAMjP,EAAAA,EAAAA,KAAkBtD,EAASuD,QAC1Di4D,EAAQF,EAAKriD,OAAOq5B,SAASgpB,GAAM,EACnCG,EAAc5kE,EAAM2P,6BAA+Bq7B,EAAAA,GAA2BkiB,UAE9EsX,EAAiB76D,EAAAA,aAAkB,KACvC,MAAMk7D,GACFH,GAAyC3O,GAAAA,GAAqB2O,KAC/DvgE,OAAO2gE,uBAEV,OAAQt0D,GAAaq0D,IAAgBhP,GAAAA,GAAoBnhD,aAAyB,IAAViwD,EAEpEE,EADAhP,GAAAA,GAAoBI,iBACT,GACd,CAACzlD,EAAWm0D,EAAOD,IAEhBK,EAAqBp7D,EAAAA,aACxBsK,GACKzD,GAAaimD,GAAAA,GAAwB/9B,SAASzkB,GACxC,GAAE9K,EAASqO,aAAYy4C,EAAAA,EAAAA,KAAkB,CAC/C7kD,IACAi2B,IACA3lB,IACAgpD,GACEzwD,IAAS4hD,GAAAA,GAAoBI,kBACzBI,GAAAA,GAAqB3hD,YACrB2hD,GAAAA,GAAqBpiD,GAC3BwwD,GAAIxwD,IAAS4hD,GAAAA,GAAoBnhD,YAAc,IAAM,IACrDqgB,QAGI,gBAAck7B,EAAAA,EAAAA,KAAkB,CACtCC,WAAY,SACZC,WAAY,SACZC,aAAc,+BAGlB,CAAC5/C,EAAWrH,EAASqO,SAAUpM,EAAGi2B,EAAG3lB,EAAGqZ,IAa1C,MAAO,CAAEyvC,iBAAgBD,WAVN56D,EAAAA,SAAc,KACf6G,IAAco0D,EAActO,GAAAA,GAAgBE,GAAAA,IAE7CxqD,KAAK9L,IAAI,IACnBA,EACH8vD,KAAM+U,EAAmB7kE,EAAKgM,OAC9B84D,gBAAiBx0D,OAElB,CAACu0D,EAAoBv0D,EAAWo0D,IAGrC,CDvDyCK,CAAc,CAAEz0D,YAAWxQ,UAC5DklE,EAAcV,KACbW,EAAcC,GAAmBz7D,EAAAA,SAAeu7D,GACjD3O,EAAOgO,EAAWp8D,MAAMjI,GAASA,EAAKgM,QAAUi5D,KAAe5O,KAMrE,OAJA5sD,EAAAA,WAAgB,KACdy7D,EAAgBF,EAAY,GAC3B,CAACA,KAGFv6D,EAAAA,EAAAA,KAACguD,EAAAA,IAAM,IACDr3D,EACJ,cAAY,oBACZ,aAAW,aACXiM,UAAU,cACVrB,MAAOi5D,EACPvM,MAAO2L,EACPz5D,aAAa,WACbD,YACkB,SAAhBvJ,EAAM0D,MACJuxD,GAEA5rD,EAAAA,EAAAA,KAACgD,EAAAA,IAAI,CAACjM,KAAM6iE,EAAWp8D,MAAMjI,GAASA,EAAKgM,QAAUi5D,KAAe5O,KAAMhpD,UAAU,kBAGxF83D,aAAa,SACbxO,SAAW32D,GAASklE,EAAgBllE,EAAKgM,QAG/C,CEtBA,MAAMo5D,GAAsB,CAAC,SAAU,UACjCC,GAA4B,IAAID,MAAwB/jE,OAAOiF,OAAO+qD,GAAAA,IAE5E,SAASiU,GAAWv/D,GAAuD,IAAtD,SAAE8E,EAAQ,aAAE06D,EAAY,OAAEC,GAA0Bz/D,EACvE,OACE0E,EAAAA,EAAAA,KAACkD,EAAAA,IAAS,CACRC,KAAM43D,EAAS,OAAS,QACxBn4D,UAAWo4D,IAAW,sCAAuC,CAC3D,iBAAkBF,EAAe,EACjC,eAAgBA,EAAe,IAC9B16D,SAEFA,GAGP,CAuCO,MAAM66D,GAAqBj8D,EAAAA,MAChC2G,EAAAA,EAAAA,MAtCK,SAAoC5J,GAAwB,IAAvB,WAAEiM,GAAmBjM,EAC/D,MAAM,iBAAEiG,IAAqBkE,EAAAA,EAAAA,KACvBnI,GAAakE,EAAAA,EAAAA,GAAcD,GAAkBoE,eAAe4B,IAAe,KAAM,CACrF9F,gBAAiB,CAAC,SAClBg5D,eAAgBP,KAEZQ,GAAal5D,EAAAA,EAAAA,GAAclE,GAAYT,SAAW,KAAM,CAC5D4E,gBAAiB,CAAC,YAAa,YAAa,cAC5Cg5D,eAAgBN,KAGZrtB,EAAe4tB,IAAc1tB,EAAAA,EAAAA,IAAgB,CAAEl1C,KAAM4iE,IACrDJ,IACFxtB,GAAcA,cAChB94B,GAAAA,GAAKka,2BAA2B,CAC9BnoB,WAAY20D,EAAY30D,WACxBjF,MAAO45D,EAAYvsC,aACf,EAER,OACE5uB,EAAAA,EAAAA,KAAA,OAAK4C,UAAU,4EAA2ExC,SACvFmtC,GAAcA,eACb5qC,EAAAA,EAAAA,MAAAiC,EAAAA,SAAA,CAAAxE,SAAA,CACGmtC,EAAaC,oBACZxtC,EAAAA,EAAAA,KAAC66D,GAAW,CAACC,aAAcvtB,EAAaC,kBAAkB53B,OAAQmlD,OAAQA,EAAO36D,SAC9EmtC,EAAaC,kBAAkBO,UAGpC/tC,EAAAA,EAAAA,KAAC66D,GAAW,CAACC,aAAcvtB,EAAaA,aAAa33B,OAAQmlD,OAAQA,EAAO36D,SACzEmtC,EAAaA,aAAaQ,aAMvC,KAIE,CAACvoC,EAAWC,IAAcD,EAAUwC,aAAevC,EAAUuC,aCpEzDs6C,GAAmE,CACvE,CAACjiB,EAAAA,GAA2BkiB,WAAY,oBACxC,CAACliB,EAAAA,GAA2BmiB,aAAc,4BAC1C,CAACniB,EAAAA,GAA2BoiB,WAAY,0BACxC,CAACpiB,EAAAA,GAA2BqiB,YAAa,4BAGrC0Y,GAA8D,CAClE,CAAC/6B,EAAAA,GAA2BkiB,WAAY,wBACxC,CAACliB,EAAAA,GAA2BmiB,aAAc,sBAC1C,CAACniB,EAAAA,GAA2BoiB,WAAY,oBACxC,CAACpiB,EAAAA,GAA2BqiB,YAAa,sBASpC,SAAS2Y,GAAU//D,GAImB,IAJlB,UACzBuK,EAAS,2BACTb,KACGrO,GACsC2E,EACzC,MAAM6pD,EAAcnmD,EAAAA,SAAc,IAC3B6G,EAWE,CACLtG,QAAUhL,IACRA,EAAGivD,iBACH,MAAM8X,GAAWC,EAAAA,EAAAA,MAAwB,MAAQ,MAEjDt3D,EAAAA,EAAAA,KAAiBu3D,EAAAA,GAAqBF,GACnCp3D,OAAM,KAEL,MAAMu3D,EAAU,IAAI7hE,KACpB6hE,EAAQC,SAASD,EAAQngC,WAAa,GACtCoC,EAAAA,GAAMi+B,UAAUH,EAAAA,GAAqBF,EAAUG,EAAQ,IAExDG,SAAQ,KACP,MAAQ/lD,EAAG1Q,KAASnQ,IAAS8M,EAAAA,EAAAA,OACzBqD,EACF5G,SAASC,SAAY,eAAa8mD,EAAAA,EAAAA,KAAkBtwD,KAEpDuJ,SAASC,SAAS4R,QACpB,GACA,GA7BC,CACL00C,GAAI,IACJO,KAAO,gBAAcC,EAAAA,EAAAA,KAAkB,CACrCC,WAAY,SACZC,WAAY,SACZC,aAAcnD,GAAYt9C,SA2B/B,CAACa,EAAWb,IAEf,OACEhF,EAAAA,EAAAA,KAACC,EAAAA,IAAM,IACDklD,KACAxuD,EACJuJ,YAAY,OACZ,cAAak7D,GAAOp2D,GACpBjC,WAAYpM,EAAMyJ,cAAWpE,EAAY,SACzC7E,MAAOR,EAAMyJ,cAAWpE,EAAY,QAG1C,CCjEA,SAAS6/D,GAAcC,GACrB,OAAQA,GACN,KAAK,EACL,KAAK,EACH,MAAO,OACT,KAAK,EACH,MAAO,OACT,KAAK,EACH,MAAO,OACT,KAAK,EACH,MAAO,OAET,QAEE,MAAO,OAEb,CAEA,MAAMxZ,GAAmE,CACvE,CAACjiB,EAAAA,GAA2BkiB,WAAY,0BACxC,CAACliB,EAAAA,GAA2BmiB,aAAc,4BAC1C,CAACniB,EAAAA,GAA2BoiB,WAAY,0BACxC,CAACpiB,EAAAA,GAA2BqiB,YAAa,4BASpC,SAAS7jD,GAAgBvD,GAAiF,IAAhF,MAAEjG,EAAK,UAAEwQ,KAAclP,GAAuD2E,EAC7G,MAAMkD,GAAWkD,EAAAA,GAAAA,OACX,EAAEmU,EAAC,EAAEuU,EAAI,IAAG,EAAErZ,IAAMjP,EAAAA,EAAAA,KAAkBtD,EAASuD,QAC/CsoD,EAAah1D,EAChBwV,SACAlV,MACA0L,KAAKhE,GAAUA,EAAMC,QAAQ8oD,iBAEhC,OACEpmD,EAAAA,EAAAA,KAACC,EAAAA,IAAM,IACDtJ,EACJmuD,GAAG,IACH5kD,YAAY,aACZsuD,OAAQ3oD,EAAY,cAAW7J,EAC/B+G,WAAYpM,EAAMyJ,cAAWpE,EAAY,SACzC7E,MAAOR,EAAMyJ,cAAWpE,EAAY,aACpC,cAAY,0BACZqpD,KACEx/C,EACK,YAAUy/C,EAAAA,EAAAA,KAAkB,CAC3BzvC,IACA6gB,GA1DYqhB,EA0DQsS,EA1DWyR,EA0DCzR,EAAWz2D,OAzDhDJ,MAAMk1B,KAAK,CAAE90B,OAAQof,KAAKqF,IAAIyjD,EAAc,KAChDz6D,KAAI,CAACgkB,EAAGzvB,IAAUmiD,EAAQniD,IAAUmiD,EAAQA,EAAQnkD,OAAS,KAC7D4D,KAAK,MAwDI4yB,EAAGigC,EAAWhpD,KAAI,IAAM+oB,IAAG5yB,KAAK,KAChCkL,EAAGm5D,GAAcxR,EAAWz2D,QAC5Bmd,QAED,gBAAcu0C,EAAAA,EAAAA,KAAkB,CAC/BC,WAAY,SACZC,WAAY,SACZC,aAAcnD,GAAYjtD,EAAM2P,kCAlE9C,IAA0B+yC,EAAmB+jB,CAuE7C,C,gBCtDe,SAASC,GAAMzgE,GAAoE,IAAnE,OAAEikC,EAAM,WAAE/4B,EAAU,iBAAEw1D,EAAgB,WAAEh0D,GAAyB1M,EAC9F,MAAM2gE,GAAgB55D,EAAAA,EAAAA,KAAiB,CAAEC,UAAW,eAC9C45D,GAA6B7I,EAAAA,EAAAA,OAC7B8I,EAA2BD,EAA2BhX,SAAS,QAC/DkX,GAAyB/I,EAAAA,EAAAA,OACzBgJ,EAAuBD,EAAuBlX,SAAS,SACtDoX,GAAyB31D,UAAW41D,KAA8BttD,EAAAA,GAAAA,GAAe,IACnF9C,EAAAA,IACHiD,iBAAkB+sD,EAClBjtD,QAASA,IAAMgtD,EAA2B5Y,UAErCkZ,GAAqB71D,UAAW81D,KAA0BxtD,EAAAA,GAAAA,GAAe,IAC3E/C,EAAAA,IACHkD,iBAAkBitD,EAClBntD,QAASA,IAAMktD,EAAuB9Y,SAElCoZ,EAAkBJ,GAAuBI,gBACzCC,EAAcH,GAAmBG,YAEjCC,EAAa59D,EAAAA,SAAc,KAC/B,MAAM69D,EAAkBt9B,EAAOvyB,QAAQ,IAAK,IAE5C,OAAQxG,GACN,KAAKC,EAAAA,GAAWC,MACd,MAAQ,iBAAgBm2D,IAC1B,KAAKp2D,EAAAA,GAAWq2D,QACd,MAAQ,0BAAyBD,IACnC,KAAKp2D,EAAAA,GAAWs2D,MACd,MAAQ,wBAAuBF,IACjC,KAAKp2D,EAAAA,GAAW47B,OACd,MAAQ,yBAAwBw6B,IACpC,GACC,CAACt9B,EAAQ/4B,IAEZ,OACE7D,EAAAA,EAAAA,MAAA,OAAKC,UAAU,0CAAyCxC,SAAA,EACtDJ,EAAAA,EAAAA,KAACg9D,EAAAA,IAAsB,CACrBh1D,WAAYA,EACZumD,YAAahvB,EACbp8B,KAAK,SACL85D,WAAW,kIACXC,cAAc,EACdC,kBAAkB,EAClBC,kBAAkB,EAClBpB,iBAAkBA,EAClB9O,cACEvqD,EAAAA,EAAAA,MAACH,EAAAA,IAAQ,CACPlI,MAAO2hE,EACP,aAAW,eACXx5D,OACEzC,EAAAA,EAAAA,KAACC,EAAAA,IAAM,CACLqJ,KAAK,SACLnG,KAAK,OACLP,UAAU,+CACVvI,MAAM,cACN0I,WAAW,SACXmqD,cAAcltD,EAAAA,EAAAA,KAACgD,EAAAA,IAAI,CAAC7H,MAAO,GAAIpE,KAAK,WAEvCqJ,SAAA,EAEDJ,EAAAA,EAAAA,KAAC8C,EAAAA,IAAY,CACXgiD,GAAG,IACH0J,OAAO,SACPnJ,KAAMuX,EACNr9D,QAASA,KACP/F,OAAOkK,OAAO,QAAS,QAAS,CAAE25D,eAAgB,qBAAsB,EACxEj9D,SAEDoG,IAAeC,EAAAA,GAAWC,MAAQ,oBAAsB,gBAE1DF,IAAeC,EAAAA,GAAWC,QACzB1G,EAAAA,EAAAA,KAAC8C,EAAAA,IAAY,CACXvD,QAASA,KACP28D,EAA2B1zD,OAC3BhP,OAAOkK,OAAO,QAAS,QAAS,CAAE25D,eAAgB,qBAAsB,EACxEj9D,SACH,sBAIFoG,IAAeC,EAAAA,GAAWC,QACzB1G,EAAAA,EAAAA,KAAC8C,EAAAA,IAAY,CACXvD,QAASA,KACP68D,EAAuB5zD,OACvBhP,OAAOkK,OAAO,QAAS,QAAS,CAAE25D,eAAgB,gBAAiB,EACnEj9D,SACH,uBAOTuC,EAAAA,EAAAA,MAACovD,EAAAA,IAAM,CAACz3D,MAAO4hE,EAA4B,aAAW,oBAAoBt5D,UAAU,QAAOxC,SAAA,CACxFm8D,IACCv8D,EAAAA,EAAAA,KAAA,OAAK4C,UAAU,wCAAuCxC,UACpDJ,EAAAA,EAAAA,KAAC2kD,EAAAA,IAAO,MAGX+X,IAAmB18D,EAAAA,EAAAA,KAAC08D,EAAe,CAACn9B,OAAQA,QAE/C58B,EAAAA,EAAAA,MAACovD,EAAAA,IAAM,CAACz3D,MAAO8hE,EAAwB,aAAW,eAAex5D,UAAU,YAAWxC,SAAA,CACnFq8D,IACCz8D,EAAAA,EAAAA,KAAA,OAAK4C,UAAU,wCAAuCxC,UACpDJ,EAAAA,EAAAA,KAAC2kD,EAAAA,IAAO,MAGXgY,IAAe38D,EAAAA,EAAAA,KAAC28D,EAAW,CAACp9B,OAAQA,SAI7C,C,wCCvGA,MAAM15B,GAAYrM,OAAO8S,eAAeC,eAClC+wD,GAAqB9jE,OAAO8S,eAAegxD,mBAE1C,SAASC,GAAajiE,GAA0E,IAAzE,WAAE0M,EAAYjK,WAAY6nD,GAA6CtqD,EACnG,MAAM2M,EAA2Cq1D,QAAqBthE,EAAY,OAE5E2I,EAAc3F,EAAAA,SAAc,IAAM4mD,EAAoBr+B,gBAAgB,CAACq+B,IACvE7nD,GAAakE,EAAAA,EAAAA,GAAc2jD,EAAqB,CACpD1jD,gBAAiB,CAAC,SAAU,QAAS,gBAEjC,WAAEsE,GAAezI,GAAYT,SAAW,CAAC,EACzC28D,EAAct1D,EAAYK,6BAA+Bq7B,EAAAA,GAA2BkiB,UAEpF5gD,GAAWC,EAAAA,GAAAA,OACX,mBAAEyE,EAAkB,wBAAEC,IAA4BC,EAAAA,EAAAA,QAClD,UAAEI,IAAcC,EAAAA,GAAAA,GAAiB,CACrC7I,aACA8I,eAAe,KAEX,WACJC,EAAU,8BACVC,EAA6B,wBAC7BC,EAAuB,wBACvBC,EAAuB,WACvBC,EAAU,gCACVC,IACEC,EAAAA,GAAAA,GAAmC,CAAErJ,aAAY8H,gBAC/C,eAAEwB,EAAc,2BAAEC,EAA0B,sBAAEC,EAAqB,sBAAEC,IACzEC,EAAAA,EAAAA,IAAyB,CACvBjB,aACAM,aACAY,cAAeX,IAGby2D,EAAqBx+D,EAAAA,aACxBugC,IACC,MAAMk+B,EAAkBl+B,EAAOnG,cAE/Bz3B,EACEoF,EAA8B,CAC5Bw4B,OAAQk+B,EACRr1D,UAAWrK,EAAWqK,UACtBP,UAAW9J,EAAW8J,YAEzB,GAEH,CAAC9J,EAAYgJ,EAA+BpF,IAG9CtG,eAAeqiE,EAAwB7hE,GACrC,MAAMiN,EAAqBtB,EAAsB3L,EAAOgM,WACxD,IAAKiB,EAAoB,aAEH3B,EAAgC2B,IACzCzB,EAAeyB,EAC9B,CAEA,MAAM60D,EAAoB3+D,EAAAA,SACxB,KAAM,CACJmE,KAAM,SACN6E,WAAYA,EACZF,gBAAiBd,EAAwBnB,IACzC8B,gBAAiBV,EAAwB,CAAEpB,aAAW+B,YAAa7J,EAAW8J,UAAWrB,eACzF2B,kBAAmBpK,EAAWqK,UAC9BpC,kBAAmBA,OACnBqC,kBAAmBtK,EAAW8J,UAC9BxB,mBAAoBA,EACpBiC,iBAAkB3B,EAAY5I,EAAWqK,eAAYpM,EACrDiK,kBAAmBsB,EACnBgB,uBAAwBA,KAClB1C,IAAWyB,EAA2BkB,MAAM,EAElDG,mBAAoB9C,GACpB4C,0BAA2B1M,IAAkD,IAAjD,MAAEwF,GAA0CxF,EACtEuK,EAAwB/E,EAAM,KAGlC,CACEyG,EACAjK,EAAW8J,UACX9J,EAAWqK,UACXd,EACAL,EACAZ,EACAkB,EACAf,EACAG,EACAK,EACAV,IAIJ,GAAI3B,EAAYK,6BAA+Bq7B,EAAAA,GAA2ByS,UACxE,OACEnwC,EAAAA,EAAAA,MAAA,OAAKC,UAAU,8DAA6DxC,SAAA,CACzErC,EAAWwpB,eAAeq2C,kBACzB59D,EAAAA,EAAAA,KAAC+7D,GAAM,CACLx8B,OAAQxhC,EAAWwhC,OACnB/4B,WAAYzI,EAAWyI,WACvBw1D,iBAAkBwB,EAClBx1D,WAAYA,KAIhBhI,EAAAA,EAAAA,KAAC+H,EAAAA,IAAY,IAAK41D,KAElB39D,EAAAA,EAAAA,KAACi7D,GAAkB,CAACjzD,WAAYA,KAEhChI,EAAAA,EAAAA,KAAC4I,EAAAA,IAAe,CACdC,YAAavB,EACbO,UAAW9J,EAAW8J,UACtBf,WAAYA,EACZO,eAAgBq2D,EAChBx2D,WAAYA,OAMpB,MAAM22D,EAAel5D,EAAYm5D,QAAQ/vC,SAASotB,EAAAA,GAAgB/yC,WAElE,OACEzF,EAAAA,EAAAA,MAAA,OACEC,UAAWo4D,IAAW,sCAAuC,CAC3D,kBAAmB6C,EACnB,mDAAoDP,KACnDl9D,SAAA,EAEHuC,EAAAA,EAAAA,MAAA,OAAKC,UAAU,gCAA+BxC,SAAA,EAC1C65D,IACAj6D,EAAAA,EAAAA,KAAC+9D,EAAAA,IAAO,CAACznE,MAAO,EAAGsM,UAAU,gEAA+DxC,SACzFrC,EAAWT,QAAQvG,MAAQgH,EAAWwhC,SAG1C56B,EAAYm5D,QAAQ/vC,SAASotB,EAAAA,GAAgB6iB,SAC5Ch+D,EAAAA,EAAAA,KAACq7D,GAAU,CACThhE,MAAM,OACN8I,KAAK,SACLK,OAAQmB,EAAYs5D,SACpBp4D,UAAWA,GACXoC,SAAUA,EACVjD,2BAA4BL,EAAYK,2BAA2B5E,SACpE,SAIFuE,EAAYm5D,QAAQ/vC,SAASotB,EAAAA,GAAgB+iB,SAC5Cl+D,EAAAA,EAAAA,KAAC6E,GAAAA,EAAa,CAACxP,MAAOsP,EAAatK,MAAM,OAAO8I,KAAK,SAAS8E,SAAUA,EAAS7H,SAAC,WAIlFy9D,IACA79D,EAAAA,EAAAA,KAAA,OAAAI,UACEJ,EAAAA,EAAAA,KAAC25D,GAAgB,CACftkE,MAAOsP,EACPkB,UAAWA,GACXxL,MAAM,OACN8I,KAAK,SACL8E,SAAUA,SAMjB41D,IACC79D,EAAAA,EAAAA,KAAA,OAAK4C,UAAU,gCAA+BxC,UAC5CuC,EAAAA,EAAAA,MAAA,OAAKC,UAAU,kEAAiExC,SAAA,EAC9EJ,EAAAA,EAAAA,KAAA,OAAAI,UACEJ,EAAAA,EAAAA,KAAC25D,GAAgB,CAACtkE,MAAOsP,EAAakB,UAAWA,GAAW1C,KAAK,SAAS8E,SAAUA,OAEtFtF,EAAAA,EAAAA,MAAA,OAAKC,UAAU,0CAAyCxC,SAAA,EACtDJ,EAAAA,EAAAA,KAAC+H,EAAAA,IAAY,CACXo2D,2BAA4B,KACxBR,EACJ/6D,UAAU,cACVqF,SAAUA,KAEZjI,EAAAA,EAAAA,KAAC4I,EAAAA,IAAe,CACdC,YAAavB,EACbO,UAAW9J,EAAW8J,UACtBf,WAAYA,EACZO,eAAgBq2D,EAChBx2D,WAAYA,aAOtBvE,EAAAA,EAAAA,MAAA,OAAKC,UAAWo4D,IAAW,4CAA6C,CAAEoD,MAAOP,IAAgBz9D,SAAA,CAC9FuE,EAAYm5D,QAAQ/vC,SAASotB,EAAAA,GAAgBkjB,WAC5Cr+D,EAAAA,EAAAA,KAACiF,GAAAA,EAAO,CACN5P,MAAOsP,EACPtK,MAAM,OACN8I,KAAK,SACL8E,SAAUA,EACV,cAAY,wBAAuB7H,SACpC,UAIF65D,IACCj6D,EAAAA,EAAAA,KAAC8E,GAAAA,EAAU,CAACC,KAAMJ,EAAYK,2BAA4BiD,SAAUA,EAAU5N,MAAM,OAAO8I,KAAK,YAElGnD,EAAAA,EAAAA,KAACnB,GAAgB,CAACxJ,MAAOsP,EAAakB,UAAWA,GAAWoC,SAAUA,EAAU5N,MAAM,OAAO8I,KAAK,SAAQ/C,UACtG65D,GAAe,eAElBt1D,EAAYm5D,QAAQ/vC,SAASotB,EAAAA,GAAgBp3C,YAC5C/D,EAAAA,EAAAA,KAACglD,GAAAA,GAAmB,CAAC3vD,MAAOsP,EAAakB,UAAWA,GAAWoC,SAAUA,EAAU5N,MAAM,OAAO8I,KAAK,SAAQ/C,UACzG65D,GAAe,cAGnBA,IACAj6D,EAAAA,EAAAA,KAAA,OAAK4C,UAAU,iCAAgCxC,UAC7CJ,EAAAA,EAAAA,KAACi7D,GAAkB,CAACjzD,WAAY,WAM5C,C,0HC1PA,MAAMs2D,WAAoBjqE,KAAAA,MACxB,gBAAOoG,GACL9G,KAAKgH,UAAU,cAAe,QAAS,SAAU,MAAO,OAC1D,EAQF2jE,GAAY7jE,YAEZ,MAAM8jE,GAAcD,GAAYjH,SAChCkH,GAAYj7C,OAEZ,YCXMk7C,GAAW,gBAEjB,MAAMF,WAAoBt/D,EAAAA,UACxBy/D,iBAAAA,GACEppE,GAAMf,KAAK,SAAUX,KAAK+qE,OAC5B,CAEAC,oBAAAA,GACEtpE,GAAMC,OAAO,SAAU3B,KAAK+qE,OAC9B,CAEAA,OAASA,KACP/qE,KAAKirE,aAAa,EAGpBpjD,MAAAA,GACE,OAAInmB,GAAMwpE,OACRtgE,SAASugE,cAAcN,KAAW7+D,UAAUE,OAAO,WAOnD8C,EAAAA,EAAAA,MAAAiC,EAAAA,SAAA,CAAAxE,SAAA,EACEJ,EAAAA,EAAAA,KAAA,OACE4C,UAAU,sBACVrD,QAASA,IAAM5L,KAAK2vD,OACpByb,cAAgB7lE,GAAMA,EAAEsqD,iBACxB,cAAY,iCAEdxjD,EAAAA,EAAAA,KAACg/D,EAAAA,IAAoB,CAAC/kD,IAAK5kB,GAAM4kB,IAAKG,KAAM/kB,GAAM+kB,KAAM6zC,MAAO54D,GAAMsyB,OAAQ27B,KAAM3vD,KAAK2vD,YAZ1F/kD,SAASugE,cAAcN,KAAW7+D,UAAUC,IAAI,UACzC,KAcX,CAEA0jD,IAAAA,GACEjuD,GAAMguC,gBAAgB,SAAS,EACjC,GAEF47B,EAAAA,EAAAA,KAAM,KACJ,MAAMppE,EAAK0I,SAASugE,cAAcN,IAC9B3oE,GACFqpE,EAAAA,QAAgBl/D,EAAAA,EAAAA,KAACs+D,GAAW,IAAKzoE,EACnC,IAGF,MAWA,GAX2B,CACzB2S,KAAMA,CAAC22D,EAAsCx3C,KAC3CtyB,GAAMyO,iBAAiB,CACrB+6D,OAAO,EACPl3C,OAAQA,EACR1N,IAAKklD,EAAMC,QAAU5lE,OAAO6lE,YAC5BjlD,KAAM+kD,EAAMG,SACZ,G,oDCvCC,SAASC,GAA0BjkE,GAAkD,IAAjD,WAAEyC,GAA6CzC,EACxF,MAAMkkE,EAAuBxgE,EAAAA,SAAc,IAAMjB,EAAWwpB,gBAAkB,MAAM,CAACxpB,KAC/E,iBAAEipD,EAAgB,MAAE3sD,IAAU4H,EAAAA,EAAAA,GAAcu9D,EAAsB,CAAEt9D,gBAAiB,CAAC,sBACtFu9D,GAAepc,EAAAA,EAAAA,KAAgB,CAAE/gD,UAAW,QAC5Co9D,EAAmBD,EAAava,SAAS,YACxCp7C,EAAO6jD,GAAY3uD,EAAAA,SAAe,CAAEib,IAAK,EAAGG,KAAM,KAClDulD,IAAqB1wD,EAAAA,GAAAA,GAAe,IACtCvT,GAAAA,EACH0T,iBAAkBswD,EAClBvwD,cAAe,SACfD,QAASA,IAAMuwD,EAAanc,SAExBsc,EAA0B5Y,GAAkB3gC,OAAOhpB,QAAQvH,IAAIiI,IAC9DxF,EAAMsnE,GAAW7gE,EAAAA,SAAkC,MACpD8gE,ECjCD,SAAsBtrE,GAAwE,IAApBurE,IAAWhrE,UAAAnB,OAAA,QAAAoI,IAAAjH,UAAA,KAAAA,UAAA,GAC1F,MAAM+jE,EAAM95D,EAAAA,OAAiC,MACvCghE,EAAchhE,EAAAA,OAAaxK,GAyBjC,OAvBAwK,EAAAA,iBAAsB,KACpBghE,EAAYxtE,QAAUgC,CAAQ,IAGhCwK,EAAAA,WAAgB,KACd,IAAK+gE,EACH,OAEF,MAAMtiC,EAAW9+B,EAAAA,GAAM8+B,WACjBwiC,EAAW/mE,IACf,MAAMzD,EAAUqjE,EAAItmE,QAChBiD,GAAWyD,EAAEs1D,SAAW/4D,EAAQyqE,SAAShnE,EAAEs1D,SAC7CwR,EAAYxtE,QAAQ0G,EACtB,EAKF,OAFAqF,SAASuB,iBAAiB29B,EAAW,aAAe,YAAawiC,GAE1D,KACL1hE,SAASwB,oBAAoB09B,EAAW,aAAe,YAAawiC,EAAQ,CAC7E,GACA,CAACzrE,EAAUurE,IAEPjH,CACT,CDKuBqH,EAAa,QACJpiE,EACzBgpD,gBACCG,oBACDprD,MAAMskE,GAAeA,EAAWhjE,SAASuoB,aAElBqhC,GAAoB4Y,GAC5C5Y,EAAiB5pD,SAAS6pD,cAAa,EACzC,KACGD,GAAoB4Y,GAEzBE,EAAattE,QAAUitE,EAAava,SAAS,kBAC7C,MAAMmb,EAAcZ,EAAaj3D,KAC3B83D,EAAcb,EAAanc,KAqCjC,OAnCAtkD,EAAAA,WAAgB,KACd,IAAKgoD,GAAkB5pD,SAAS6lD,SAAW2c,EACzC,OAAKF,EAGEY,IAFET,EAAQ,MAInB,IAAKD,EAAyB,OAC9B,MAAM,IAAE3lD,EAAG,KAAEG,GAAS4sC,EAAiB5pD,SACjCmjE,EAAUvZ,EAAiB7pD,oBAC7BojE,GAAS7iE,YAAcnF,GAAMmF,WAC/BmiE,EAAQ,IACHU,EACHnmE,UAAW4sD,EAAiB5pD,SAASojE,0BAIrC12D,EAAMmQ,MAAQA,GAAOnQ,EAAMsQ,OAASA,GACtCuzC,EAAS,CAAE1zC,MAAKG,SAEbslD,GACHW,GACF,GACC,CACDrZ,EACAzuD,GAAMmF,UACNkiE,EACAF,EACAY,EACAD,EACAZ,EACA31D,EAAMsQ,KACNtQ,EAAMmQ,OAINtX,EAAAA,EAAAA,MAAAiC,EAAAA,SAAA,CAAAxE,SAAA,EACEJ,EAAAA,EAAAA,KAACygE,EAAAA,IAAa,CACZ5rE,GAAG,kBACH6rE,MAAOjB,EACP78D,UAAU,sCACVkH,MAAOA,IAERvR,IACCyH,EAAAA,EAAAA,KAAC2gE,EAAAA,IAAcrN,SAAQ,CAAC/xD,MAAM,WAAUnB,UACtCJ,EAAAA,EAAAA,KAAC4gE,EAAAA,IAAa,CAAAxgE,UACZJ,EAAAA,EAAAA,KAACokD,EAAAA,IAAO,CACNyc,SAAU,EACV,aAAW,QACXvmE,MAAOmlE,EACP,cAAY,sBACZvN,UAAU,EAEVD,OAAO,EACP6O,uBAAuB,EAGvBC,WAAW,EACXC,iBAAiB,EAAM5gE,UAEvBJ,EAAAA,EAAAA,KAACuyD,EAAAA,IAAU,CACT3vD,UAAW0hD,IAAW,kCAAmC,CACvD,gBAAiBqb,IAChBv/D,SAEFu/D,GACC3/D,EAAAA,EAAAA,KAAC2/D,EAAkBsB,yBAAwB,CAAC7mE,UAAW7B,EAAK6B,UAAW7B,KAAMA,EAAM8B,MAAOA,KAE1F2F,EAAAA,EAAAA,KAAA,OAAK4C,UAAU,4CAA2CxC,UACxDJ,EAAAA,EAAAA,KAAC0kD,EAAAA,IAAO,CAACwc,eAAgB,KAAK9gE,UAC5BJ,EAAAA,EAAAA,KAAC2kD,EAAAA,IAAO,CAACxpD,MAAO,mBAWtC,CEzHO,SAASgmE,GAAoB7lE,GAAiE,IAA9DyC,WAAYoI,GAAgD7K,EACjG,MAAMqU,ECVD,WACL,MAAMyxD,EAAepiE,EAAAA,QAAa,GAC5B2Q,EAAe3Q,EAAAA,aAAkB,IAAMoiE,EAAa5uE,SAAS,IASnE,OAPAwM,EAAAA,WAAgB,KACdoiE,EAAa5uE,SAAU,EAChB,KACL4uE,EAAa5uE,SAAU,CAAK,IAE7B,IAEImd,CACT,CDFuBC,GACf7R,GAAakE,EAAAA,EAAAA,GAAckE,EAAqB,CAAEjE,gBAAiB,CAAC,WACpEi5D,GAAal5D,EAAAA,EAAAA,GAAclE,EAAWT,QAAS,CAAE4E,gBAAiB,CAAC,iBAClEm/D,EAAqBC,GAA0BtiE,EAAAA,UAAe,GAErEA,EAAAA,WAAgB,KACTjB,EAAWwjE,sBAEdxjE,EACGT,QACAkkE,kCACAjxD,MAAMkxD,IACD9xD,KACF2xD,EAAuBG,EACzB,GAEN,GAGC,IAcH,OAAKJ,GAKHrhE,EAAAA,EAAAA,KAACwyD,EAAAA,IAAW,CAACvqD,SAAS,OAAOrF,UAAU,sCAAqCxC,UAC1EJ,EAAAA,EAAAA,KAACC,EAAAA,IAAM,CACLC,YACEi7D,GAAYj0D,YACVlH,EAAAA,EAAAA,KAAC0kD,EAAAA,IAAO,CAACwc,gBAAgBlhE,EAAAA,EAAAA,KAACgD,EAAAA,IAAI,CAACjM,KAAK,YAAaqJ,UAC/CJ,EAAAA,EAAAA,KAAC2kD,EAAAA,IAAO,CAACxpD,MAAO,OAGlB,UAGJ+J,SAAUi2D,GAAYj0D,WACtB/P,MAAM,mBACNoI,QA9BuBlE,UAC3B,MAAMqmE,EAAW3jE,EACdyoD,eACAnlD,KAAIhG,SAAiBiC,EAAMopD,UAAU,CAAEC,UAAWC,GAAAA,EAAeC,cACpE9oD,EAAW+F,iBAAiB,CAAE69D,aAAa,UACrC7wD,QAAQnb,IAAI+rE,GACd/xD,MACF2xD,GAAuB,GACvB9nE,OAAOkK,OAAO,QAAS,mBAAoB,CAAE25D,eAAgB,UAC/D,EAsBI,cAAY,0BAAyBj9D,SACtC,uBAnBI,IAwBX,CE5DO,MAAMwhE,GAA6B,YAC7BC,GAAiC,aAExCC,GAAuF,CAC3F3+D,KAAM,OACNP,UAAW,UACXzC,aAAc,uBAGVs9B,GAAW9+B,EAAAA,GAAM8+B,WAWjBskC,GAAwBhkE,IAC5BuoD,EAAAA,GAAAA,IAAc,CACZhpD,MAAOS,EAAWT,QAClBS,aACA4pB,OAAQ,CAAC,IAGN,SAASq6C,GAAY1mE,GAON,IAPO,gBAC3B2mE,EAAe,WACflkE,EAAU,UACVmkE,EAAS,SACTC,EAAQ,UACRC,EAAS,YACTC,GACkB/mE,EAClB,MAAM0G,GAAmBC,EAAAA,EAAAA,GAAclE,EAAWwpB,eAAgB,CAAErlB,gBAAiB,CAAC,WAC/EogE,EAAqBC,GAA0BvjE,EAAAA,UAAe,IAC/D,kBAAEwjE,GAAsBxgE,GACvBygE,EAAoBC,GAAyB1jE,EAAAA,SAAejB,EAAWuqC,aAAek6B,GACvFG,EAAuB3jE,EAAAA,aAAkB,KAC7CjB,EAAW+F,iBAAiB,CAAE8a,WAAYmjD,GAAqBhkE,GAAa8J,UAAW,MAAO,GAC7F,CAAC9J,IAkBJ,OAhBAiB,EAAAA,WAAgB,KACd,MAAM4jE,EAAkCnR,KACtC,KACEiR,EAAsB3kE,EAAWuqC,aAAek6B,GAChDD,EAAuBxkE,EAAW6gB,aAAemjD,GAAqBhkE,GAAY,GAEpF,IACA,CAAE4zD,QAAS,MAGb,OADA5zD,EAAWzJ,KAAK,SAAUsuE,GACnB,KACLA,EAAgChR,SAChC7zD,EAAWzI,OAAO,SAAUstE,EAAgC,CAC7D,GACA,CAACJ,EAAmBzkE,KAGrB4E,EAAAA,EAAAA,MAAA,OACEm2D,IAAKmJ,EACLr/D,UAAWo4D,IACT,gIACA,CAAE6H,QAASX,IACX9hE,SAAA,EAEAq9B,KACA96B,EAAAA,EAAAA,MAAA,OAAKC,UAAU,qIAAoIxC,SAAA,CAChJqiE,IACCziE,EAAAA,EAAAA,KAAA,OAAK4C,UAAU,gGAA+FxC,UAC5GJ,EAAAA,EAAAA,KAACwyD,EAAAA,IAAW,CAACvqD,SAAS,OAAOrF,UAAU,sCAAqCxC,UAC1EJ,EAAAA,EAAAA,KAACC,EAAAA,IAAM,IACD6hE,GACJ,cAAY,iCACZ3qE,MAAM,aACNoI,QAAS8iE,EACTz/D,UAAU,UAASxC,UAEnBJ,EAAAA,EAAAA,KAACgD,EAAAA,IAAI,CAACjM,KAAK,mBAKnB4L,EAAAA,EAAAA,MAAC6vD,EAAAA,IAAW,CAACvqD,SAAS,OAAOrF,UAAU,sCAAqCxC,SAAA,EAC1EJ,EAAAA,EAAAA,KAACC,EAAAA,IAAM,IACD6hE,GACJ,cAAY,+BACZ3qE,MAAM,WACNoI,QAAS6iE,EAAUhiE,UAEnBJ,EAAAA,EAAAA,KAACgD,EAAAA,IAAI,CAACjM,KAAK,cAGbiJ,EAAAA,EAAAA,KAACC,EAAAA,IAAM,IAAK6hE,GAAmB,cAAY,8BAA8B3qE,MAAM,UAAUoI,QAAS4iE,EAAS/hE,UACzGJ,EAAAA,EAAAA,KAACgD,EAAAA,IAAI,CAACjM,KAAK,iBAMnB4L,EAAAA,EAAAA,MAAA,OAAKC,UAAU,qGAAoGxC,SAAA,GAC9G4B,EAAiBmD,MAAMtQ,KAAMmL,EAAAA,EAAAA,KAACmhE,GAAoB,CAACpjE,WAAYA,IAEjEukE,IACCtiE,EAAAA,EAAAA,KAACwyD,EAAAA,IAAW,CAACvqD,SAAS,OAAOrF,UAAU,sCAAqCxC,UAC1EJ,EAAAA,EAAAA,KAACC,EAAAA,IAAM,CACL8C,WAAW,SACX,cAAY,mCACZ5L,MAAM,8BACNoI,QAASojE,EAAqBviE,UAE9BJ,EAAAA,EAAAA,KAACgD,EAAAA,IAAI,CAACjM,KAAK,oBAOzB,CCnDA,MAAMmH,WAAac,EAAAA,UACjB8jE,MAAwB,KACxBC,WAA6B,KAC7B5H,WACA6H,QAAUhkE,EAAAA,YACVikE,UAAYjkE,EAAAA,YACZkkE,UAAYlkE,EAAAA,YACZijE,gBAAkBjjE,EAAAA,YAClBmkE,iBAAmBnkE,EAAAA,YACnBokE,UAAYpkE,EAAAA,YACZqkE,eAAiBrkE,EAAAA,YACjBgD,iBAAmBrO,KAAKgD,MAAMoH,WAAWwpB,eACzC+7C,WACAC,aACAC,aACAC,oBACAv8C,WAAY,EACZw8C,YACAC,YACAC,iBAAwD,KACxDptD,MACAC,MACAotD,eACAC,YAA6B,KAC7BC,kBAAmB,EACnBC,eAAuC,KACvCvmC,SACAwmC,8BAA+B,EAE/BtqC,OAAmC,KACnCuqC,UAA6C,KAC7CC,YAAwC,KACxCC,eAAkD,KAClDC,iBAAkB,EAElB/pE,MAAmB,CACjBgqE,2BAA4B9qE,OAAO+qE,cAAcC,QAAQ,6BAI3D1tE,WAAAA,CAAYH,GACViH,MAAMjH,GAENhD,KAAKwnE,WAAaxnE,KAAKgD,MAAMoH,WAAWT,QACxC3G,EAAMtB,MAAMguC,gBAAgB,WAAY1vC,MACxCgD,EAAMtB,MAAMf,KAAK,SAAUX,KAAK8wE,eAChC9tE,EAAMtB,MACHgU,WACA/U,KAAK,SAAUX,KAAK+wE,iBACpBpwE,KAAK,UAAWX,KAAKgxE,kBACrBrwE,KAAK,UAAWX,KAAKixE,kBACrBtwE,KAAK,SAAUX,KAAKkxE,iBACpBvwE,KAAK,YAAaX,KAAKmxE,gBACvBxwE,KAAK,SAAUX,KAAKoxE,6CACpBzwE,KAAK,SAAUm9D,IAAS99D,KAAKqxE,aAAc,KAC9CruE,EAAMtB,MAAMf,KAAK4pC,EAAAA,GAAkB+mC,aAActxE,KAAKqxE,cAEtDruE,EAAMtB,MAAMkI,cAAcjJ,KAAK,SAAUX,KAAK+wE,iBAAiBpwE,KAAK,SAAUm9D,IAAS99D,KAAKqxE,aAAc,KAE1GrxE,KAAKgD,MAAMoH,WAAWzJ,KAAK,SAAUX,KAAKuxE,eAC1CvxE,KAAKgD,MAAMoH,WAAWzJ,KAAM,UAAS4pC,EAAAA,GAAkBC,mBAAoBxqC,KAAKqxE,cAChFrxE,KAAKwnE,WAAW7mE,KAAK,SAAUX,KAAKqxE,cACpCrxE,KAAK8pC,WAAa9+B,EAAAA,GAAM8+B,WACxB9pC,KAAKkwE,eAAiBltE,EAAMwuE,WACvBC,GAAAA,EAAW/+C,QACd++C,GAAAA,EAAW/hC,gBAAgB,OAAQ1sC,EAAMtB,OAE3C1B,KAAK0wE,gBAAkB1tE,EAAMtB,MAAMgwE,qBACnC1xE,KAAKqxE,cACP,CAEAvG,iBAAAA,GACE,MAAM,MAAEppE,GAAU1B,KAAKgD,MACvBhD,KAAKqO,iBAAiB1N,KAAK,QAASX,KAAK2xE,WACzC3xE,KAAKqO,iBAAiB1N,KAAK,QAASX,KAAK43C,aAEzC,MAAMg6B,GAAuBpkB,EAAAA,EAAAA,OAA6B,GACzC,IAAI9rD,EAAMssD,oBAAqBtsD,EAAM6xD,mBAAkB,IAC/DhrD,SAASzG,IAEhB,GADA9B,KAAK+wE,gBAAgBjvE,GACjBA,EAAQmsD,YAAa,CACU2jB,EAAqBzpE,MAAKC,IAAA,IAAC,UAAE2B,GAAW3B,EAAA,OAAKtG,EAAQiI,YAAcA,CAAS,KAE3GjI,EAAQ2H,UAAUka,eAEpB7hB,EAAQ2H,SAAS+Z,6BACnB,MAAW1hB,EAAQ0xD,gBACjB1xD,EAAQ2H,UAAUka,cACpB,IAGFjiB,GAAOkyD,4BAEP5zD,KAAKgmC,OAAShmC,KAAKyvE,UAAU5wE,QAC7BmB,KAAKuwE,WAAY9uD,EAAAA,GAAAA,GAAoBzhB,KAAKyvE,UAAU5wE,SACpDmB,KAAKwwE,YAAcxwE,KAAK0vE,eAAe7wE,QACvCmB,KAAKywE,gBAAiBhvD,EAAAA,GAAAA,GAAoBzhB,KAAK0vE,eAAe7wE,SAE9DmB,KAAK2vE,WAAa,IAAIkC,KAAAA,SAAe7xE,KAAKqvE,QAAQxwE,QAAU,CAAEizE,YAAa,SAC3E9xE,KAAK2vE,WAAW1jE,IAAI,IAAI4lE,KAAAA,OAAa,CAAEE,UAAW,EAAGtuE,KAAM,OAC3DzD,KAAK2vE,WAAWqC,GAAG,QAAShyE,KAAKiyE,SACjCjyE,KAAK8vE,oBAAsB,IAAI+B,KAAJ,CAAW7xE,KAAKwvE,iBAAiB3wE,QAAU,CAAEizE,YAAa,SACrF9xE,KAAK8vE,oBAAoBkC,GAAG,MAAOhyE,KAAK4L,SACxC5L,KAAKwvE,iBAAiB3wE,SAASsN,iBAAiB,YAAanM,KAAKkyE,YAAa,CAAEC,SAAS,KAEtFnyE,KAAKqO,iBAAiB+jE,YAAepyE,KAAK8pC,WACxC9pC,KAAKsvE,UAAUzwE,UACjBmB,KAAK4vE,aAAe,IAAIiC,KAAJ,CAAW7xE,KAAKsvE,UAAUzwE,QAAS,CAAEizE,YAAa,SACtE9xE,KAAK4vE,aAAaoC,GAAG,YAAahyE,KAAKqyE,gBAErCryE,KAAKuvE,UAAU1wE,UACjBmB,KAAK6vE,aAAe,IAAIgC,KAAJ,CAAW7xE,KAAKuvE,UAAU1wE,QAAS,CAAEizE,YAAa,SACtE9xE,KAAK6vE,aAAamC,GAAG,YAAahyE,KAAKgD,MAAMsvE,gBAE/CtyE,KAAK8vE,oBAAoBkC,GAAG,YAAahyE,KAAKuyE,gBAGhDvyE,KAAKuxE,cAAc,CAAE/pE,MAAOxH,KAAKgD,MAAMoH,WAAW5C,QAClDxH,KAAK8wE,cAAc,CAAErpE,OAAQ/F,EAAM+F,SACnCzH,KAAKirE,cACLjrE,KAAKqO,iBAAiB9E,QAAQipE,GAAAA,EAChC,CAEAxH,oBAAAA,GACEhrE,KAAKwvE,iBAAiB3wE,SAASuN,oBAAoB,YAAapM,KAAKkyE,cACrEtnC,EAAAA,EAAAA,IAAc5qC,KAAKgmC,SACnB4E,EAAAA,EAAAA,IAAc5qC,KAAKwwE,aACnBxwE,KAAKgD,MAAMoH,WAAWzI,OAAO,SAAU3B,KAAKuxE,eAC5CvxE,KAAKgD,MAAMoH,WAAWzI,OAAO,SAAU3B,KAAKqxE,cAC5CrxE,KAAKwnE,WAAW7lE,OAAO,SAAU3B,KAAKqxE,aACxC,CAEAxpD,MAAAA,GACE,MAAM,WAAE2pD,EAAU,oBAAEiB,EAAmB,YAAEC,EAAW,UAAEC,EAAS,WAAEt+D,EAAU,MAAE3S,EAAK,WAAE0I,GAAepK,KAAKgD,MACxG,GAAIyvE,EACFzyE,KAAK2vE,YAAYxwD,IAAI,CAAE2yD,YAAa,SACpC9xE,KAAK4vE,cAAczwD,IAAI,CAAE2yD,YAAa,SACtC9xE,KAAK6vE,cAAc1wD,IAAI,CAAE2yD,YAAa,SACtC9xE,KAAK8vE,qBAAqB3wD,IAAI,CAAE2yD,YAAa,aACxC,CACL,MAAMA,EAAc9xE,KAAK4yE,+BAAiC,OAAS,OACnE5yE,KAAK4vE,cAAczwD,IAAI,CAAE2yD,YAAa,SACtC9xE,KAAK6vE,cAAc1wD,IAAI,CAAE2yD,YAAa,SACtC9xE,KAAK2vE,YAAYxwD,IAAI,CAAE2yD,gBACvB9xE,KAAK8vE,qBAAqB3wD,IAAI,CAAE2yD,eAClC,CAEA,MAAMe,EAAcnxE,EAAMoxE,iBAE1B,OACE9jE,EAAAA,EAAAA,MAAA,OACEC,UAAU,OACVk2D,IAAKnlE,KAAKqvE,QACVl9C,YAAanyB,KAAK+yE,gBAClBC,aAAchzE,KAAKizE,iBACnBrnE,QAASA,IAAM8mE,IAAchxE,GAC7BwxE,aAAcA,IAAMR,IAAchxE,GAClC0pE,cAAeprE,KAAKorE,cACpB,cAAc,SAAQ/2D,UAAmBs+D,IAAYlmE,SAAA,CAEpDomE,IAAexmE,EAAAA,EAAAA,KAACu/D,GAA0B,CAACxhE,WAAYA,IACzC,IAAduoE,IACCtmE,EAAAA,EAAAA,KAAA,OACE4C,UAAU,UACVijB,YAAc3sB,GAAMvF,KAAKgD,MAAMmwE,mBAAmB5tE,EAAG7D,GACrD,cAAc,SAAQ2S,UAAmBs+D,cAG5C3yE,KAAKqO,iBAAiB+kE,oBACrB/mE,EAAAA,EAAAA,KAAA,OACE4C,UAAWo4D,IAAW,6EAA8E,CAClG,qBAAsBrnE,KAAK0wE,gBAC3B,oBAAqB1wE,KAAK0wE,kBAE5BvL,IAAKnlE,KAAKsvE,UACVp9C,YAAalyB,KAAKqzE,kBAClBC,aAActzE,KAAKuzE,mBACnBL,aAAclzE,KAAKwzE,mBACnBjB,cAAevyE,KAAKqyE,cACpB,cAAc,SAAQh+D,UAAmBs+D,aAI5C3yE,KAAKqO,iBAAiB+kE,mBAAqBP,IAC1C7jE,EAAAA,EAAAA,MAAAiC,EAAAA,SAAA,CAAAxE,SAAA,EACEJ,EAAAA,EAAAA,KAAA,OACE4C,UAAU,SACVk2D,IAAKnlE,KAAKuvE,UACVr9C,YAAalyB,KAAKgD,MAAMywE,kBACxBthD,YAAanyB,KAAK0zE,kBAClBR,aAAclzE,KAAKgD,MAAM2wE,mBACzBpB,cAAevyE,KAAKgD,MAAMsvE,cAC1B,cAAc,SAAQj+D,UAAmBs+D,cAE3CtmE,EAAAA,EAAAA,KAACgiE,GAAY,CACXjkE,WAAYpK,KAAKgD,MAAMoH,WACvBkkE,gBAAiBtuE,KAAKsuE,gBACtBC,UAAWiD,IAAeoC,GAAAA,GAAYC,OAA6B,OAApBnyE,EAAMixB,UACrD67C,SAAUA,KACRxuE,KAAKgD,MAAM8wE,kBAAkB,CAAEC,KAAM,GAAKC,2BAA2B,GAAO,EAE9EvF,UAAWA,KACTzuE,KAAKgD,MAAM8wE,kBAAkB,CAAEC,MAAO,GAAKC,2BAA2B,GAAO,EAE/EtF,YAAa1uE,KAAKgD,MAAMsvE,oBAI9BtjE,EAAAA,EAAAA,MAAA,OACEC,UAAU,sBACVk2D,IAAKnlE,KAAKwvE,iBACVtC,SAAU,EACV,cAAc,SAAQ74D,UAAmBs+D,WACzCzgD,YAAclyB,KAAK8pC,cAA2CzhC,EAAhCrI,KAAKi0E,yBACnC9hD,YAAcnyB,KAAK8pC,cAA0CzhC,EAA/BrI,KAAKk0E,wBACnClB,aAAchzE,KAAKgzE,aACnBE,aAAclzE,KAAK8pC,SAAW9pC,KAAKkzE,kBAAe7qE,EAClD8rE,WAAYn0E,KAAKm0E,WACjBC,OAAQp0E,KAAKo0E,OAAO3nE,SAAA,EAEpBJ,EAAAA,EAAAA,KAAA,UAAQ84D,IAAKnlE,KAAKyvE,UAAUhjE,UAAE4nE,EAAAA,GAAAA,IAAYr0E,KAAKwnE,cAC9CxnE,KAAKqO,iBAAiBimE,QAASjoE,EAAAA,EAAAA,KAAA,UAAQ4C,UAAU,SAASk2D,IAAKnlE,KAAK0vE,sBAI7E,CAEAkD,6BAA+BA,IAC7B5yE,KAAKqO,iBAAiBgD,6BAA+Bq7B,EAAAA,GAA2ByS,YAC/En/C,KAAKqO,iBAAiBkmE,qBACtBv0E,KAAKqO,iBAAiB+jE,WAEzBrB,gBAAmB7uE,IACjBA,EAAGuH,SAAS9I,KAAK,SAAUX,KAAK2xE,WAChC3xE,KAAK2xE,WAAW,EAGlBV,iBAAmBA,CAAC/uE,EAAkBsyE,KACpCA,EAAmB7yE,OAAO,SAAU3B,KAAK2xE,WACzCzvE,EAAGuH,SAAS9I,KAAK,SAAUX,KAAK2xE,WAC5B6C,IAAuBx0E,KAAKgD,MAAMtB,MAAMixB,WAAc3yB,KAAKqO,iBAAiBomE,8BAG9Ez0E,KAAK00E,aAAa,MAFlB10E,KAAK00E,aAAaxyE,EAAGuH,UAIvBzJ,KAAK2xE,WAAW,EAGlBX,iBAAoB9uE,IAClB,MAAM,KAAEyT,GAASzT,EAAGuH,SACpBvH,EAAGuH,SAAS9H,OAAO,SAAU3B,KAAK2xE,WAC9BzvE,EAAGuH,WAAazJ,KAAKgD,MAAMtB,MAAMixB,WACnC3yB,KAAK00E,aAAa,OAEhB/+D,EAAKrV,WAAW,YAAcqV,EAAKrV,WAAW,iBAChDN,KAAKgD,MAAM2xE,cAAczyE,EAAY,SAEvClC,KAAK2xE,WAAW,EAGlBT,gBAAmBhvE,IACjBlC,KAAK40E,mBAAmB1yE,EAAGuH,SAAS,EAGtC0nE,eAAiBA,CAACz/C,EAAYmjD,KAC5B70E,KAAK40E,mBAAmBC,EAAsB,EAGhD/D,cAAgBhjE,IAAoC,IAAnC,OAAErG,GAA4BqG,EAC7C9N,KAAK80E,cAAc,CACjBttE,MAAOxH,KAAKgD,MAAMoH,WAAW5C,MAC7BC,UACA,EAGJ8pE,cAAgB7hE,IAAkC,IAAjC,MAAElI,GAA0BkI,EAC3C,MAAM,MAAEhO,EAAK,WAAE0I,GAAepK,KAAKgD,MACnChD,KAAK80E,cAAc,CACjBttE,QACAC,OAAQ/F,EAAM+F,SAEhB,MAAMkC,EAAQS,EAAWT,QACpB3J,KAAKwnE,WAAWrlE,IAAIwH,KACvB3J,KAAKwnE,WAAW7lE,OAAO,SAAU3B,KAAKqxE,cAClC1nE,IACF3J,KAAKwnE,WAAa79D,EAClB3J,KAAKwnE,WAAW7mE,KAAK,SAAUX,KAAKqxE,eAExC,EAGFqC,kBAA8DnuE,IAC5D,IAAKvF,KAAKqO,iBAAiB+jE,YAAepyE,KAAK8pC,WAAa9pC,KAAKqO,iBAAiBkmE,mBAAqB,OACvG,MAAM3zD,EAAO5gB,KAAK+0E,QAAQxvE,GAC1BksE,GAAAA,EAAWthE,iBAAiB,CAC1B0H,SAAU,CAAE2G,EAAGoC,EAAKpC,EAAGC,EAAG,MAC1BiU,KAAM1yB,KAAKgD,MAAMtB,OACjB,EAGJszE,uBAA0BxJ,IACxB,GAAIxrE,KAAKgD,MAAMiyE,uBACb,OAGF,IAAI,QAAEtJ,EAAO,QAAEF,GAAYD,EAC3B,MAAM,MAAE9pE,GAAU1B,KAAKgD,MAOvB,GALsC,oBAAfkyE,YAA8B1J,aAAiB0J,YACvD1J,EAAM2J,eAAel1E,OAAS,IAC3C0rE,EAAUH,EAAM2J,cAAc,GAAGxJ,QACjCF,EAAUD,EAAM2J,cAAc,GAAG1J,UAE9B/pE,EAAMixB,YAAc3yB,KAAKqO,iBAAiBglD,iBAAkB,CAC/D,GAAwB,MAApBrzD,KAAK+vE,YAAqB,CAC5B,MAAMqF,EAAMp1E,KAAK+vE,YAAcpE,EAC/B3rE,KAAKq1E,iBAAiBD,EACxB,CACA,GAAI1zE,EAAM+tC,YAAkC,MAApBzvC,KAAKgwE,YAAqB,CAChD,IACItvD,GADA,IAAEgE,EAAG,IAAEG,GAAQnjB,EAAM+tC,WAEzB,GAAQzvC,KAAKgD,MAAMoH,WAAW+M,QACvBE,EAAAA,GAAUK,YACbgJ,EAAO1gB,KAAKgwE,YAAcvE,EAC1B/mD,EAAMhjB,EAAMyV,MAAMsH,EAAEyN,OAAOxqB,EAAMyV,MAAMsH,EAAEiG,GAAOhE,GAChDmE,EAAMnjB,EAAMyV,MAAMsH,EAAEyN,OAAOxqB,EAAMyV,MAAMsH,EAAEoG,GAAOnE,QAIhDA,GAAQ1gB,KAAKgwE,YAAcvE,IAAY/pE,EAAMyV,MAAMsH,EAAEyN,OAAO,GAAKxqB,EAAMyV,MAAMsH,EAAEyN,OAAO,IACtFxH,GAAOhE,EACPmE,GAAOnE,EAKXhf,EAAMguC,gBAAgB,aAAc,CAAEhrB,MAAKG,QAC3C7kB,KAAKqxE,eACLrxE,KAAKiwE,iBAAmBjwE,KAAKgD,MAAMtB,MAAMgxD,8BAA8BjpD,UAAU6lC,eAAiB,IACpG,CACF,CACAtvC,KAAK+vE,YAAcpE,EACnB3rE,KAAKgwE,YAAcvE,CAAO,EAG5B+H,mBAA+DjuE,IACxDvF,KAAKqO,iBAAiB+jE,aAAcpyE,KAAKgD,MAAMyvE,qBAChDzyE,KAAKqO,iBAAiB+jE,YAAyC,IAA3B7sE,EAAE4vE,cAAcl1E,QACtDD,KAAKqzE,kBAAkB9tE,EAAE4vE,cAAc,GACzC,EAGFG,kBAAqB/vE,IACfvF,KAAKqO,iBAAiB+jE,YAAyC,IAA3B7sE,EAAE4vE,cAAcl1E,QACtDD,KAAKu1E,kBAAkBhwE,EAAE4vE,cAAc,GACzC,EAGFK,iBAAmBA,KACbx1E,KAAKqO,iBAAiB+jE,YACxBpyE,KAAKy1E,iBACP,EAGFlC,mBAAqBA,KACnB9B,GAAAA,EAAWthE,iBAAiB,CAC1B0H,SAAU,KACV6a,KAAM,MACN,EAGJ2gD,kBAAqB7H,IACnB,MAAM,uBAAEyJ,EAAsB,0BAAES,EAAyB,MAAEh0E,GAAU1B,KAAKgD,MAC1E,GAAKwoE,aAAiBmK,YAAcnK,EAAMoK,QAAWX,IAA2Bj1E,KAAKqO,iBAAiB+jE,WACpG,OAEFsD,EAA0B,UAE1B11E,KAAKmwE,YAAc3E,EAAMC,QAEzB,MAAOvoD,EAAkBC,GAAoBzhB,EAAMyV,MAAMsH,EAAE2E,SAC3DpjB,KAAKiwE,iBAAmB,CAAEvrD,IAAKvB,EAAkB0B,IAAK3B,GACtDtY,SAASuB,iBAA8B,YAAanM,KAAKu1E,mBACzD3qE,SAASuB,iBAAiB,UAAWnM,KAAKy1E,iBAC1C7qE,SAASuB,iBAAiB,YAAanM,KAAKs1E,mBAC5C1qE,SAASuB,iBAAiB,WAAYnM,KAAKw1E,iBAAiB,EAG9DD,kBAAqB/J,IACnB,MAAM,MAAE9pE,EAAK,WAAE0I,GAAepK,KAAKgD,MACnC,GAAyB,OAArBtB,EAAM+tC,YAAiD,OAA1BzvC,KAAKiwE,iBACpC,OAEF,IACIvvD,GADA,IAAEgE,EAAG,IAAEG,GAAQnjB,EAAM+tC,YAAczvC,KAAKiwE,iBAE5C,GAAQjwE,KAAKgD,MAAMoH,WAAW+M,QACvBE,EAAAA,GAAUK,YACbgJ,EAAO1gB,KAAKmwE,YAAe3E,EAAMC,QACjC/mD,EAAMhjB,EAAMyV,MAAMsH,EAAEyN,OAAOxqB,EAAMyV,MAAMsH,EAAEiG,GAAOhE,GAChDmE,EAAMnjB,EAAMyV,MAAMsH,EAAEyN,OAAOxqB,EAAMyV,MAAMsH,EAAEoG,GAAOnE,QAIhDA,IAAS1gB,KAAKmwE,YAAe3E,EAAMC,UAAY/pE,EAAMyV,MAAMsH,EAAEyN,OAAO,GAAKxqB,EAAMyV,MAAMsH,EAAEyN,OAAO,IAC9FxH,GAAOhE,EACPmE,GAAOnE,EAIX1gB,KAAKmwE,YAAc3E,EAAMC,QAEzB,MAAMoK,EAAiBn0E,EAAMgxD,8BAA8BjpD,UAAU6lC,cACrE,GAAIumC,EAAgB,CAClB,MAAMC,EAAcz2D,KAAKQ,IAAIgF,EAAMH,GAC7BqxD,EAAe12D,KAAKQ,IAAIg2D,EAAehxD,IAAMgxD,EAAenxD,KAElE,GAAIoxD,EA3cmB,IA2cLC,GAAuCD,EAAcC,EA3chD,IA4crB,MAEJ,CAEAr0E,EAAMguC,gBAAgB,aAAc,CAAEhrB,MAAKG,QAC3Cza,EAAWslC,gBAAgB,YAAa,MACxC1vC,KAAKqxE,cAAc,EAGrBoE,gBAAkBA,KAChBz1E,KAAKmwE,YAAc,KAEnBvlE,SAASwB,oBAAoB,YAAapM,KAAKu1E,mBAC/C3qE,SAASwB,oBAAoB,UAAWpM,KAAKy1E,iBAC7C7qE,SAASwB,oBAAoB,YAAapM,KAAKs1E,mBAC/C1qE,SAASwB,oBAAoB,WAAYpM,KAAKw1E,kBAC9Cx1E,KAAKgD,MAAM0yE,0BAA0B,KAAK,EAG5CrD,cAAgBA,KACd,MAAM,MAAE3wE,EAAK,WAAE0I,GAAepK,KAAKgD,MAC9BhD,KAAKqO,iBAAiB+jE,aAC3BhoE,EAAWslC,gBAAgB,YAAa,MACxChuC,EAAMguC,gBAAgB,aAAc,MACpC1vC,KAAKqxE,eAAc,EAGrBgE,gBAAmB18B,IACjB,MAAMhvC,EAAQ3J,KAAKgD,MAAMoH,WAAWT,QAC9B8qC,GAAWC,EAAAA,EAAAA,IAAsB,CACrC1jC,YAAahR,KAAKqO,iBAClBsmC,WAAY30C,KAAKgD,MAAMoH,WAAWuqC,aAE9B1pB,GAAa+qD,EAAAA,GAAAA,IAAoB,CACrCC,cAAej2E,KAAKgD,MAAMoH,WAAW6gB,WAAa0tB,EAClDvuC,WAAYpK,KAAKgD,MAAMoH,WACvBqqC,WACArY,SAAUzyB,EAAMyyB,SAASzyB,EAAM2jC,KAAKrtC,OAAS,KAG3CgrB,EAAawpB,GACf9qC,EAAMusE,iBAERl2E,KAAKgD,MAAMoH,WAAW+F,iBAAiB,CACrC8a,aACA/W,UAAW,MACX,EAGJq+D,cAAiB/G,IACfA,EAAM3b,iBACN,MAAMjvC,EAAO5gB,KAAK+0E,QAAQvJ,GACpB1pE,EAAU9B,KAAKgD,MAAMtB,MAAMixB,WAAa3yB,KAAKm2E,WAAWv1D,GAC1D9e,GAAWA,EAAQ6T,OAASC,EAAAA,GAAcC,MAAQ/T,EAAQ6vB,YAC5DtU,YAAW,KACTrd,KAAKgD,MAAMozE,uBAAwBt0E,EAAQ,GAC1C,GACHA,EAAQyH,QAAQ,WAAYiiE,GAC9B,EAGFyG,QAAW1sE,IACT,GAAsB,UAAlBA,EAAE8wE,YAAyB,OAE/B9wE,EAAEomE,QAAUpmE,EAAEsxB,OAAOrY,EACrBjZ,EAAEkmE,QAAUlmE,EAAEsxB,OAAOpY,EAErB,MAAMvc,EAAKlC,KAAKgD,MAAMtB,MAAMixB,WAAa3yB,KAAKm2E,WAAWn2E,KAAK+0E,QAAQxvE,IACjEvF,KAAKqO,iBAAiBkmE,qBACpBryE,EAGHlC,KAAKorE,cAAc7lE,EAAuBrD,GAF1ClC,KAAKs2E,cAAc/wE,GAIvB,EAGF6lE,cAAgBA,CAAC7lE,EAAqBzD,KACpCyD,EAAEsqD,iBACF,MAAMjvC,EAAO5gB,KAAK+0E,QAAQxvE,GACpBgxE,EAAgBv2E,KAAKm2E,WAAWv1D,GAChC1e,EAAKJ,GAAWy0E,EACtB,IAAKr0E,GAAMA,EAAG6pB,gBAAgBnL,GAC5B,OAEF,MAAM41D,EAAe3vE,EAAAA,EAAawrB,gBAA8B,WAAYnwB,GAC5E,IAAKs0E,EAAc,OACnBx2E,KAAK40E,mBAAmB1yE,GACxB,MAAMu0E,EACJ,CAAC,YAAa,UAAUtuE,MAAMwN,GAASzT,EAAGyT,KAAKrV,WAAWqV,MAAUzT,EAAGyT,OAASC,EAAAA,GAAcC,IAC1F6gE,EAAmBF,EAAavoB,YAEtC,OAAO0c,GAAY91D,KACjBtP,EACA,CACEkxE,GAAiB,CACfv1E,GAAI,OACJ4N,MAAO,aACPlD,QAASA,IAAM5L,KAAKgD,MAAMozE,uBAAwBl0E,MAGlDs0E,EAAaxrB,WAAawrB,GAAcj7C,gBAAkB,CAC1Dr6B,GAAI,QACJ4N,MAAO,QACPlD,QAASA,IAAM4qE,EAAaG,gBAG1BD,EACA,CACE,CAAE/gE,KAAM,UAAW7G,MAAO,cAE1B,CACE5N,GAAI,+BACJ4N,MAAO,6BACPlD,QAASA,IAAM4qE,EAAa/sE,SAASwrB,gBAAgBK,EAAAA,GAAgBC,kBAGvE,CACEr0B,GAAI,+BACJ4N,MAAO,6BACPlD,QAASA,IAAM4qE,EAAa/sE,SAASwrB,gBAAgBK,EAAAA,GAAgBE,kBAGvE,CACEt0B,GAAI,0BACJ4N,MAAO,wBACPlD,QAASA,IAAM4qE,EAAa/sE,SAASwrB,gBAAgBK,EAAAA,GAAgBG,cAGvE,CACEv0B,GAAI,2BACJ4N,MAAO,gBACPlD,QAASA,IAAM4qE,EAAa/sE,SAASwrB,gBAAgBK,EAAAA,GAAgBtzB,OAGzE,IAEH00E,GAAoBD,IAAkB,CAAE9gE,KAAM,WAE/C,CACEzU,GAAI,iBACJ4N,MAAO,iBACPlD,QAASA,IAAM4qE,EAAaI,gBAE9B,CACE11E,GAAI,eACJ4N,MAAO,eACPlD,QAASA,IAAM4qE,EAAaK,cAE9B,CACE31E,GAAI,gBACJ4N,MAAO,gBACPlD,QAASA,IAAM4qE,EAAaM,gBAE9B,CACE51E,GAAI,gBACJ4N,MAAO,gBACPlD,QAASA,IAAM4qE,EAAaO,gBAG9B,CAAEphE,KAAM,WAER,CACEzU,GAAI,SACJ4N,MAAO,SACPlD,QAASA,KACH4qE,EAAaj7C,eACfy7C,EAAAA,GAAAA,IAA0B,CAAErE,UAAW3yE,KAAKgD,MAAM2vE,UAAWtkE,iBAAkBrO,KAAKqO,oBAEpFmoE,EAAa9iB,eAAe,CAAEmR,UAAWC,EAAAA,GAAyBC,SAClE/kE,KAAKgD,MAAMtB,MAAM0iE,oBACnB,IAIHxsD,OAAOs/C,SACPxpD,KAAK9L,IAAI,IAAWA,EAAMmO,KAAM,CAAEknE,aAAc/0E,EAAGyT,UACvD,EAGHy7D,4CAA+CtvE,KACzCA,GAASkpD,WAAalpD,GAASy5B,gBACjCv7B,KAAKqxE,cACP,EAGFA,aAAeA,CAAC3/C,EAAawlD,KAC3B,MAAM,MAAEx1E,GAAU1B,KAAKgD,MACjBoH,EAAa1I,EAAMgI,QACN,YAAfwtE,GAA6B9sE,GAAeA,EAAWT,WAI3D0nE,EAAAA,GAAAA,IAAa,CAAEjnE,aAAYrD,UAAWrF,IAElC1B,KAAKuwE,WACPvwE,KAAK2xE,YACP,EAGFyC,OAASA,KACHp0E,KAAKgD,MAAMtB,MAAMixB,WAAW3P,iBAC9BhjB,KAAK00E,aAAa,MAElB10E,KAAK40E,mBAAmB,MAEtB50E,KAAKqwE,iBACPrwE,KAAKqwE,eAAe79C,cAAa,GACjCxyB,KAAKqwE,eAAiB,MAExBrwE,KAAKgD,MAAMtB,MAAMssD,iBAAiBzlD,SAASzG,IACrCA,EAAQ2H,SAASuZ,mBAAqBlhB,EAAQ2H,SAAS+qB,4BACzD1yB,EAAQ4xD,gBACV,GACA,EAGJie,UAAah8D,IAGX,GAAa,UAATA,GAAoB3V,KAAKqO,iBAAiBimE,OAC5C,GAAwB,OAApBt0E,KAAKovE,WAAqB,CAC5B,MAAMA,EAAavpE,OAAOsxE,uBAAsB,KAC9Cn3E,KAAK43C,aAC4B,IAI/Bw/B,EAGJp3E,KAAKovE,WAAaA,CACpB,OACK,GAAkB,MAAdpvE,KAAKmvE,OAAiBnvE,KAAKuwE,UAAW,CAC/C,MAAMpB,EAAQtpE,OAAOsxE,uBAAsB,KACzCn3E,KAAKq3E,YAC4B,IAI/BD,EAGJp3E,KAAKmvE,MAAQA,CACf,GAGFkI,WAAaA,KACX,MAAM,MAAE31E,GAAU1B,KAAKgD,MAED,OAAlBtB,EAAMgI,SAA+C,OAA3B1J,KAAKyvE,UAAU5wE,SAAqBmB,KAAKuwE,YAGnEvwE,KAAKs3E,sBACiB,OAApBt3E,KAAKovE,aACPpvE,KAAKovE,WAAavpE,OAAOsxE,sBAAsBn3E,KAAK43C,cAGxD53C,KAAKmvE,WAAQ9mE,GAEbkvE,EAAAA,GAAAA,IAAW,CACTlpE,iBAAkBrO,KAAKqO,iBACvBjE,WAAYpK,KAAKgD,MAAMoH,WACvBrD,UAAWrF,EACX6uE,UAAWvwE,KAAKuwE,YAChB,EAGJ+G,kBAAAA,GACE,MAAM,2BAAEjmE,GAA+BrR,KAAKqO,iBACtCmpE,EAAWnmE,IAA+Bq7B,EAAAA,GAA2ByS,UACrEs4B,GAAiC13B,EAAAA,EAAAA,IAAiB,CAAE1uC,+BAE1D,OAAOmmE,GAAYC,CACrB,CAEA7/B,YAAcA,KACZ,MAAM,MAAEl2C,GAAU1B,KAAKgD,MACjB00E,EAAgBjG,GAAAA,EAAWkG,2BAA2Bj2E,GAE5D,GADA1B,KAAKovE,WAAa,MACbpvE,KAAKywE,eACR,OAEFzwE,KAAKywE,eAAemH,UAAU,EAAG,EAAG53E,KAAKgD,MAAMoH,WAAW5C,MAAO9F,EAAM+F,QACvE,MAAMowE,EACwG,IAA5GC,GAAAA,EAAUlzB,QAAmBnuB,KAAQA,EAAE9D,YAAc8D,EAAE9D,UAAUhd,KAAKrV,WAAW,iBAAgBL,QACjGD,KAAKgD,MAAMoH,WAAW2tE,kBACrBL,EAEH,IAAK,MAAQjuE,SAAUuuE,KAAqBt2E,EAAMssD,mBAE5C6pB,GAAkD,MAA/BG,EAAgBpgC,aACpCigC,GAAsD,MAAnCG,EAAgB5tC,mBAEpCpqC,KAAKywE,eAAe9gD,OAChBkoD,EACFG,EAAgB5tC,gBAAiBpqC,KAAKywE,eAAgB3sD,OAAOwxB,KAE7D0iC,EAAgBpgC,YAAa53C,KAAKywE,gBAEpCzwE,KAAKywE,eAAe5gD,UAExB,EAGFklD,QAAUA,CAAqCxvE,EAAe0yE,KAC5D,MAAM,MAAEv2E,GAAU1B,KAAKgD,MACjB2oE,EAAUpmE,EAAEomE,SAAWsM,GAAgBtM,QACvCF,EAAUlmE,EAAEkmE,SAAWwM,GAAgBxM,QACvCyM,GAAWC,EAAAA,GAAAA,IAAYz2E,GACvB02E,EAAgBp4E,KAAKgmC,OAAQmqB,wBAC7BkoB,EAAuB1M,EAAUyM,EAAc3xD,KAC/C6xD,EAAuB7M,EAAU2M,EAAc9xD,IAC/C9H,EAAI65D,EAAuB32E,EAAMgI,QAAQuhB,WAAaitD,EAASzxD,KAAKjf,MACpEiX,EAAI65D,EAAuBJ,EAAS5xD,IAAI7e,OACxC0P,EAAQzV,EAAMyV,MACdohE,EAAaH,EAAc3xD,KAAOyxD,EAASzxD,KAAKjf,MAChDgxE,EAAcJ,EAAc7xD,MAAQ2xD,EAAS3xD,MAAM/e,MACzD,MAAO,IACDywE,EAEJz5D,EAAGrH,EAAMqH,EAAE0N,OAAO1N,GAClBC,EAAGtH,EAAMsH,EAAEyN,OAAOzN,GAClBE,OAAQ,CACNH,IACAC,KAEFjX,MAAO,EACPC,OAAQ,EACRgxE,QAASJ,EACTK,QAASJ,EACTK,+BAAgChN,EAAU4M,GAAc5M,EAAU6M,EACnE,EAGH1D,cAAgBz6C,IAA0D,IAAzD,MAAE7yB,EAAK,OAAEC,GAA2C4yB,EACnE,MAAM8L,EAAQn7B,EAAAA,GAAM07B,gBACdE,EAAgB5mC,KAAKyvE,UAAU5wE,QAQnCmB,KAAKuwE,WACL3pC,IACCvnB,KAAKQ,IAAIpY,EAAS0+B,EAAQS,EAAcn/B,SAAW,GAAK4X,KAAKQ,IAAIrY,EAAQ2+B,EAAQS,EAAcp/B,QAAU,KAE1GwD,EAAAA,GAAM27B,uBAAuB,CAAEC,gBAAep/B,QAAOC,WACrDzH,KAAKuwE,UAAUp5D,MAAMgvB,EAAOA,GACxBnmC,KAAKqO,iBAAiBimE,OAASt0E,KAAKywE,iBACtCzlE,EAAAA,GAAM27B,uBAAuB,CAC3BC,cAAe5mC,KAAK0vE,eAAe7wE,QACnC2I,QACAC,WAEFzH,KAAKywE,eAAet5D,MAAMgvB,EAAOA,IAEnC9oB,YAAW,KACTrd,KAAKqxE,cAAc,IAEvB,EAGFzlE,QAAW4/D,IACT,MAAM5qD,EAAO5gB,KAAK+0E,QAAQvJ,EAAO,CAC/BG,QAASH,EAAM30C,OAAOrY,EACtBitD,QAASD,EAAM30C,OAAOpY,IAElB3c,EAAU9B,KAAKgD,MAAMtB,MAAMixB,WAAa3yB,KAAKm2E,WAAWv1D,GAG9D,GAFA9e,GAASyH,QAAQ,QAASqX,GAErB5gB,KAAKswE,6BAAV,CAKA,GAAItwE,KAAKqO,iBAAiBkmE,mBACxB9C,GAAAA,EAAWthE,iBAAiB,CAC1B0H,SAAU,KACV6a,KAAM,OAER1yB,KAAKqO,iBAAiB8B,iBAAiB,CACrCiiE,WAAYpyE,KAAKqO,iBAAiB+kE,kBAClCmB,oBAAoB,SAEjB,GACLv0E,KAAK8pC,WACJ9pC,KAAK2G,MAAMgqE,0BACZ3wE,KAAKkwE,iBAAmB0D,GAAAA,GAAYC,OACpC7zE,KAAKqO,iBAAiBgD,6BAA+Bq7B,EAAAA,GAA2BoR,WAChF,CACA,MAAM86B,EAAe54E,KAAKqO,iBAAiBgD,6BAA+Bq7B,EAAAA,GAA2ByS,UAErGn/C,KAAK64E,SAAS,CAAElI,0BAA0B,IAC1C3wE,KAAKgD,MAAM2Y,oBAAoB9G,MAC7BxI,EAAAA,EAAAA,KAACkQ,EAAAA,GAAY,CACX20C,SACE7kD,EAAAA,EAAAA,KAACC,EAAAA,IAAM,CACLV,QAASA,KACP5L,KAAKgD,MAAM2Y,oBAAoBg0C,OAC/B9pD,OAAO+qE,aAAakI,QAAQ,2BAA4B,OAAO,EAEjEpyE,MAAM,OAAM+F,SACb,WAGFA,UAEDJ,EAAAA,EAAAA,KAACkD,EAAAA,IAAS,CAACN,UAAU,WAAUxC,SAAC,kDAElC,CAAEssE,QAASH,GAEf,CAEA54E,KAAKkwE,eAAiBlwE,KAAKgD,MAAMwuE,UAxCjC,MAFExxE,KAAKswE,8BAA+B,CA0CK,EAG7C2C,iBAAmBA,KAEjB51D,YAAW,KACTrd,KAAKsuE,gBAAgBzvE,SAASmN,UAAUE,OAAO+hE,GAA4BC,GAA+B,IAExGluE,KAAKqO,iBAAiBgD,6BAA+Bq7B,EAAAA,GAA2ByS,WAClFn/C,KAAK43C,aACP,EAGFm7B,gBAAkB,MAAH,IAAAiG,EAAG,KAAH,OAAG,SAACzzE,GAAkE,IAA/B0zE,EAAkB73E,UAAAnB,OAAA,QAAAoI,IAAAjH,UAAA,IAAAA,UAAA,GACtE,MAAM,MAAEM,EAAK,WAAE0I,GAAe4uE,EAAKh2E,MAC7Bk2E,EAAeF,EAAK1K,gBAAgBzvE,QACpCs6E,EAAaz3E,EAAM+F,OACzB,GAAIyxE,EAAc,CAChB,MAAMt4D,EAAOo4D,EAAKjE,QAAkExvE,EAAG,CACrFguB,WAAY0lD,GAAsBD,EAAKzlD,UACvCo4C,QAASpmE,EAAEomE,QACXF,QAASlmE,EAAEkmE,UAIbpuD,YAAW,KAGT,MAAMsD,EAAWjf,EAAM+F,OAAS,IAAMmZ,EAAK83D,SAAWS,EAAa,KAGjEx4D,GACCu4D,EAAaltE,UAAUugE,SAAS2B,KAChC9jE,EAAW2tE,iBAGFp3D,GAAYu4D,EAAaltE,UAAUugE,SAAS2B,KACtDgL,EAAaltE,UAAUE,OAAOgiE,IAF9BgL,EAAaltE,UAAUC,IAAIiiE,IAKxBttD,EAAK2S,WAAc7xB,EAAMixB,YAAahS,GAAavW,EAAW2tE,gBAIxDmB,EAAaltE,UAAUugE,SAAS0B,KACzCiL,EAAaltE,UAAUE,OAAO+hE,IAJzBiL,EAAaltE,UAAUugE,SAAS0B,KACnCiL,EAAaltE,UAAUC,IAAIgiE,GAI/B,GAEJ,CACF,CAAC,EApCiB,GAsClB+E,aAAeA,KACbhzE,KAAKuzB,WAAY,CAAK,EAGxB2/C,aAAgB3tE,IACd,IAAKvF,KAAKgD,MAAMyvE,qBAAkD,IAA3BltE,EAAE4vE,cAAcl1E,OAAc,CACnE,MAAMm5E,EAAa7zE,EAAE4vE,cAAc,GACnC,GAAIn1E,KAAKqO,iBAAiB+jE,WACxBpyE,KAAKi0E,yBAAyBmF,QACzB,GAAIp5E,KAAKqO,iBAAiBkmE,oBAG/B,GAFAv0E,KAAK+vE,YAAcqJ,EAAWzN,QAC9B3rE,KAAKgwE,YAAcoJ,EAAW3N,SACzBgG,GAAAA,EAAW/+C,QAAQvwB,IAAInC,KAAKgD,MAAMtB,OAAQ,CAC7C,MAAMkf,EAAO5gB,KAAK+0E,QAAQqE,EAAY,CACpC7lD,UAAWvzB,KAAKuzB,UAChBo4C,QAASyN,EAAWzN,QACpBF,QAAS2N,EAAW3N,UAEtBzrE,KAAKq5E,iBAAiBr5E,KAAKs5E,6BAA6B14D,IACxD5gB,KAAKswE,8BAA+B,CACtC,MACK,CACL,MAAM1vD,EAAO5gB,KAAK+0E,QAAQqE,EAAY,CAAEG,SAAS,IAC3Cz3E,EAAU9B,KAAKm2E,WAAWv1D,GAChC,GAAI9e,GAASswB,qBAAuBpyB,KAAKgD,MAAMwuE,aAAeoC,GAAAA,GAAYC,MAAO,CACrD/xE,EACRwxD,cACpB,CACF,CACAtzD,KAAK+yE,gBAAgBqG,GAAY,EACnC,GAGFlH,YAAe3sE,IACRvF,KAAKgD,MAAMyvE,sBACTzyE,KAAK4yE,gCACRrtE,EAAEsqD,iBAEC7vD,KAAKgD,MAAMyvE,qBAAkD,IAA3BltE,EAAE4vE,cAAcl1E,QACrDD,KAAKk0E,wBAAwB3uE,EAAE4vE,cAAc,IAEjD,EAGFhB,WAAc5uE,KACPvF,KAAKgD,MAAMyvE,qBAAuBzyE,KAAKqO,iBAAiB+jE,YAC3DpyE,KAAKw5E,uBAAuBj0E,EAC9B,EAGF+wE,cAAiB/wE,IACXvF,KAAKqO,iBAAiB+jE,aACxBpyE,KAAKqO,iBAAiBqhC,gBAAgB,cAAc,GACpD9kC,SAASwB,oBAAoB,YAAapM,KAAKg1E,yBAE5Ch1E,KAAKqO,iBAAiBkmE,qBACzBv0E,KAAKqO,iBAAiBqhC,gBAAgB,sBAAsB,GAC5D1vC,KAAKk0E,wBAAwB3uE,GAC/B,EAGF0uE,yBAA4B1uE,IAC1B,MAAM,WAAEisE,EAAU,uBAAEyD,EAAsB,WAAE7qE,EAAU,MAAE1I,GAAU1B,KAAKgD,MACjEu2E,EAA2B,oBAAVE,OAAyBl0E,aAAak0E,MAG7D,GAFAz5E,KAAKkwE,eAAiBsB,GAElBkI,EAAAA,EAAAA,IAAen0E,KAAO0vE,IAA2B7qE,EAAW2tE,gBAAiB,CAC/E,MAAMn3D,EAAO5gB,KAAK+0E,QAAQxvE,EAAG,CAAEg0E,YACzBz3E,EAAU9B,KAAKm2E,WAAWv1D,GAmBhC,GAfIlf,EAAMixB,WAAWhB,YAAc/Q,EAAK+3D,gCAAkC72E,IAAYJ,EAAMixB,WAC1FjxB,EAAMssD,iBAAiBzlD,SAASzG,IAC1BA,EAAQ2H,SAASuZ,mBAAqBlhB,EAAQ2H,SAAS+qB,4BACzD1yB,EAAQ4xD,gBACV,IAGA1zD,KAAKqO,iBAAiB+jE,cACxB/5B,EAAAA,GAAAA,GAAiB,CAAEtuC,UAAW/J,KAAKqO,iBAAiBiqC,mBAAoBtgB,OAAQ,aAC5Et2B,EAAM+tC,aACRzvC,KAAKiwE,iBAAmBvuE,EAAMgxD,8BAA8BjpD,UAAU6lC,eAAiB,MAEzF1kC,SAASuB,iBAAiBotE,EAAU,YAAc,YAAav5E,KAAKg1E,wBACpEpqE,SAASuB,iBAAiBotE,EAAU,WAAa,UAAWv5E,KAAKw5E,yBAE/D13E,GAASswB,qBAAuBo/C,IAAeoC,GAAAA,GAAYC,MAAO,CACpE7zE,KAAK40E,mBAAmB,MACE9yE,EACRwxD,cACpB,MACEke,IAAeoC,GAAAA,GAAYC,OAC3BnyE,EAAMssD,iBAAiB7lD,MAAKmyB,IAAA,IAAC,SAAE7wB,GAAU6wB,EAAA,OAAK7wB,EAASkoB,SAAS,OAEhE7vB,GAASyH,QAAQ,YAAaqX,GAC9B5gB,KAAK40E,mBAAmB9yE,IAE1BJ,EAAM6H,QAAQ,YAAa7H,EAAOkf,EAAM9e,GACxC9B,KAAKuzB,WAAY,EACjBvzB,KAAK6iB,MAAQjC,EAAKpC,EAClBxe,KAAK8iB,MAAQlC,EAAKnC,CACpB,CAEAze,KAAK+vE,YAAcxqE,EAAEomE,QACrB3rE,KAAKgwE,YAAczqE,EAAEkmE,OAAO,EAG9ByI,wBAA2B3uE,IACzB,MAAMqb,EAAO5gB,KAAK+0E,QAAQxvE,EAAG,CAC3BguB,UAAWvzB,KAAKuzB,UAChBo4C,QAASpmE,EAAEomE,QACXF,QAASlmE,EAAEkmE,UAEb,IAAK7qD,EAAK+3D,+BAKR,YAJAlH,GAAAA,EAAWthE,iBAAiB,CAC1B0H,SAAU,KACV6a,KAAM,OAKV,MAAM,MAAEhxB,GAAU1B,KAAKgD,MACjBqtE,EAAiBrwE,KAAKm2E,WAAWv1D,GACjC9e,EAAUJ,EAAMixB,WAAa09C,EAE7BrwE,KAAK8pC,WAAa9pC,KAAKqO,iBAAiBkmE,qBAC5Cv0E,KAAKswE,8BAA+B,EACpCtwE,KAAKq5E,iBACHr5E,KAAK+vE,aAAe/vE,KAAKgwE,aAAehwE,KAAKqO,iBAAiBkmE,oBAAsB9C,GAAAA,EAAW55D,SAC3F7X,KAAKs5E,6BAA6B,CAChC96D,EAAGizD,GAAAA,EAAW55D,SAAS2G,GAAK9c,EAAMyV,MAAMqH,EAAE0N,OAAOtL,EAAK+qD,SAAWjqE,EAAMyV,MAAMqH,EAAE0N,OAAOlsB,KAAK+vE,cAC3FtxD,EAAGgzD,GAAAA,EAAW55D,SAAS4G,GAAK/c,EAAMyV,MAAMsH,EAAEyN,OAAOtL,EAAK6qD,SAAW/pE,EAAMyV,MAAMsH,EAAEyN,OAAOlsB,KAAKgwE,gBAE7F,CAAExxD,EAAGoC,EAAKpC,EAAGC,EAAGmC,EAAKnC,KAIxBze,KAAKqO,iBAAiB+jE,aACzBpyE,KAAK+vE,YAAcnvD,EAAK+qD,QACxB3rE,KAAKgwE,YAAcpvD,EAAK6qD,SAG1B3pE,GAASyH,QAAQ,YAAaqX,GAE5B5gB,KAAKuzB,WACL7xB,EAAMixB,qBAAqBgnD,GAAAA,IAC1Bj4E,EAAMixB,UAAUd,cAChB7xB,KAAKqO,iBAAiBglD,mBAElB3xD,EAAMixB,UAAU3P,kBACnBthB,EAAMixB,UAAUnS,OAAOI,EAAKpC,EAAIxe,KAAK6iB,MAAOjC,EAAKnC,EAAIze,KAAK8iB,OAE5D9iB,KAAK6iB,MAAQjC,EAAKpC,EAClBxe,KAAK8iB,MAAQlC,EAAKnC,EAClBze,KAAK2xE,aAEP,MAAMvB,EACJpwE,KAAKgD,MAAMwuE,aAAeoC,GAAAA,GAAYC,QACpC/xE,GAAWA,IAAYuuE,GAAmBA,aAA0BsJ,GAAAA,GAEpEtJ,IAAmBrwE,KAAKqwE,gBAAkBrwE,KAAKqwE,0BAA0BsJ,GAAAA,IAC3E35E,KAAKqwE,eAAe79C,cAAa,GACjCxyB,KAAKqwE,eAAiB,MAGpBD,GAAoBC,aAA0BsJ,GAAAA,IAC3CtJ,EAAer+C,WAAcq+C,EAAet+C,aAC/Cs+C,EAAe79C,cAAa,GAC5BxyB,KAAKqwE,eAAiBA,IAItBD,IAAqBpwE,KAAKowE,kBAAoBpwE,KAAKgmC,QAAUqqC,GAAgB16D,OAASC,EAAAA,GAAcC,MACtG7V,KAAKgmC,OAAO/2B,UAAYmhE,EAAmB,QAAU,GACjDpwE,KAAKqO,iBAAiBimE,OAASt0E,KAAKwwE,cACtCxwE,KAAKwwE,YAAYvhE,UAAa,UAAQmhE,EAAmB,SAAW,KAEtEpwE,KAAKowE,iBAAmBA,EAC1B,EAGFoJ,uBAA0BhO,IACpBiG,GAAAA,EAAW55D,UACbwgC,EAAAA,GAAAA,GAAiB,CAAEtuC,UAAW/J,KAAKqO,iBAAiBiqC,mBAAoBtgB,OAAQ,eAEhFqgB,EAAAA,GAAAA,GAAiB,CAAEtuC,UAAW/J,KAAKqO,iBAAiBiqC,mBAAoBtgB,OAAQ,YAElF,MAAMuhD,EAAgC,oBAAfrE,YAA8B1J,aAAiB0J,WACtEl1E,KAAKuzB,WAAY,EACjB,MAAM3S,EAAO5gB,KAAK+0E,QAAQvJ,GACpB1pE,EAAU9B,KAAKgD,MAAMtB,MAAMixB,WAAa3yB,KAAKm2E,WAAWv1D,GAC9D9e,GAASyH,QAAQ,UAAWqX,GAC5BhW,SAASwB,oBAAoBmtE,EAAU,YAAc,YAAav5E,KAAKg1E,wBACvEpqE,SAASwB,oBAAoBmtE,EAAU,WAAa,UAAWv5E,KAAKw5E,uBAAuB,EAG7FF,6BAA+B/+C,IAAwC,IAAvC,EAAE/b,EAAC,EAAEC,GAA6B8b,EAChE,MAAM,MAAE74B,GAAU1B,KAAKgD,MACjBk1E,GAAWC,EAAAA,GAAAA,IAAYz2E,GACvBk4E,EAAsB55E,KAAKgmC,OAAQmqB,wBACnC0pB,EAAYn4E,EAAMyV,MAAMqH,EAAE0N,OAAmC,EAA3BxqB,EAAMgI,QAAQuhB,YAChD6uD,EAAap4E,EAAMyV,MAAMqH,EAAE0N,OAC/B0tD,EAAoBpyE,MAAQ0wE,EAAS3xD,MAAM/e,MAAQ0wE,EAASzxD,KAAKjf,MAAQ9F,EAAMgI,QAAQuhB,WAAa,GAEhG8uD,EAAWr4E,EAAMyV,MAAMsH,EAAEyN,OAAO,GAChC8tD,EAAct4E,EAAMyV,MAAMsH,EAAEyN,OAAO0tD,EAAoBnyE,OAASywE,EAAS1xD,OAAO/e,OAASywE,EAAS5xD,IAAI7e,QAE5G,MAAO,CACL+W,GAAGy7D,EAAAA,EAAAA,IAAgB,CACjBrsE,MAAO4Q,EACPkG,IAAKm1D,EACLh1D,IAAKi1D,IAEPr7D,GAAGw7D,EAAAA,EAAAA,IAAgB,CACjBrsE,MAAO6Q,EACPiG,IAAKs1D,EACLn1D,IAAKk1D,IAER,EAGHV,iBAAmBrnC,IAAwC,IAAvC,EAAExzB,EAAC,EAAEC,GAA6BuzB,EACpD,MAAMkoC,IAAqBzI,GAAAA,EAAW/+C,QAAQvwB,IAAInC,KAAKgD,MAAMtB,OAC7D+vE,GAAAA,EAAWthE,iBAAiB,CAC1B0H,SAAU,CAAE2G,IAAGC,QACXy7D,EAAmB,CAAC,EAAI,CAAExnD,KAAM1yB,KAAKgD,MAAMtB,QAC/C,EAGJgzE,aAAgB/hD,IACVA,aAAqBgnD,GAAAA,GACvBhnD,GAAWJ,eAAc,GAG3BvyB,KAAKgD,MAAMtB,MAAMguC,gBAAgB,YAAa/c,EAAU,EAG1DiiD,mBAAsB9yE,IACpB,MAAM,UAAE6wB,GAAc3yB,KAAKgD,MAAMtB,MAC3By4E,EAAoBxnD,aAAqBgnD,GAAAA,GAC3C73E,IAAY6wB,GAAcwnD,GAAqBr4E,IAAY6wB,GAAWZ,cACpEooD,GACFxnD,GAAWJ,eAAc,GAEvB4nD,GAAqBxnD,GAAWhB,UAClC3xB,KAAK00E,aAAa,MAElB10E,KAAK00E,aAAa5yE,GAEtB,EAGFq0E,WAAcv1D,IACZ,MAAMhX,EAAc5J,KAAKgD,MAAMtB,MAAM6xD,mBAAkB,GAEvD,IAAK,IAAIrxC,EAAItY,EAAY3J,OAAS,EAAGiiB,GAAK,EAAGA,IAAK,CAChD,MAAMhgB,EAAK0H,EAAYsY,GAAGzY,SAC1B,GAAIvH,EAAG8oB,iBAAiBhrB,KAAKgD,MAAMoH,aAAelI,EAAGye,SAASC,GAC5D,OAAO1e,CAEX,CAEA,MAAMwT,EAAW1V,KAAKgD,MAAMtB,MAAMssD,iBAElC,IAAK,IAAI9rC,EAAIxM,EAASzV,OAAS,EAAGiiB,GAAK,EAAGA,IAAK,CAC7C,MAAMhgB,EAAKwT,EAASwM,GAAGzY,SACvB,GAAIvH,EAAG8oB,iBAAiBhrB,KAAKgD,MAAMoH,aAAelI,EAAGye,SAASC,GAC5D,OAAO1e,CAEX,CACA,OAAO,IAAI,EAGbk4E,iBAAmBA,IAEjBp6E,KAAKyvE,UAAU5wE,QAGnB,UAAew7E,EAAAA,EAAAA,KtB39BR,SAAwCt9D,GAC7C,OAAO,SAA0B/Z,GAC/B,MAAM0b,EAAUrT,EAAAA,WAAiB+zD,GAEjC,OAAO/yD,EAAAA,EAAAA,KAAC0Q,EAAS,IAAK/Z,EAAOozE,uBAAwB13D,GACvD,CACF,CsBq9BuC47D,ECrtCuBv9D,GDqtCmBxS,GCptCxE,SAA0BvH,GAC/B,MAAMtB,GAAQ4M,EAAAA,EAAAA,GAActL,EAAMtB,MAAO,CAAE6M,gBAAiB,CAAC,eAE7D,OAAOlC,EAAAA,EAAAA,KAAC0Q,GAAS,IAAK/Z,EAAOtB,MAAOA,GACtC,KALK,IAAuDqb,GCDvD,SAASw9D,GAAmB5yE,GAA8E,IAA7E,cAAE6yE,EAAa,UAAEvrE,GAA0DtH,EAC7G,MAAO4mE,EAAWkM,GAAgBpvE,EAAAA,SAAemvE,GAajD,OAZAnvE,EAAAA,WAAgB,KACd,IAAIqvE,EAMJ,OALKF,IACHE,EAAU70E,OAAOwX,YAAW,KAC1Bo9D,GAAa,EAAM,GAClB,MAEE,KACLrY,aAAasY,EAAQ,CACtB,GACA,CAACF,KAGFnuE,EAAAA,EAAAA,KAAA4E,EAAAA,SAAA,CAAAxE,SACG8hE,IACCliE,EAAAA,EAAAA,KAAA,OACE4C,UAAWo4D,IACT,wIACA,CACE,cAAemT,EACf,aAAcA,GAEhBvrE,GAEF,cAAY,wBAAuBxC,UAEnCJ,EAAAA,EAAAA,KAAC2kD,EAAAA,IAAO,OAKlB,CC9BO,MACM2pB,GAA4B,MCmBzC,SAASC,GAAmBpP,GAC1BA,EAAM3b,gBACR,CA4CA,MAAMvlD,WAAce,EAAAA,UAClBwvE,UACAC,kBACAC,yBACAC,WAAa,EACbl4D,MAAuB,KACvBD,MAAuB,KACvBo4D,kBAAoB,EACpBC,kBAAoB,EACpBC,iBAIW,KAGXh4E,WAAAA,CAAYH,GACViH,MAAMjH,GAENhD,KAAK66E,UAAY73E,EAAMoH,WAAW5C,MAClCxH,KAAKgD,MAAMo4E,YAAYz6E,KAAK,SAAUX,KAAKq7E,qBAC3Cr7E,KAAK2G,MAAQ,CAAE20E,oBAAqB,KACtC,CAEAxQ,iBAAAA,GACE,MAAM,WAAE1gE,GAAepK,KAAKgD,MAC5BhD,KAAK66E,UAAY76E,KAAKgD,MAAMo4E,YAAY5zE,MAExC4C,EAAWb,QAAQ,SAAUa,GAC7BA,EAAWzJ,KAAK,aAAcX,KAAKu7E,cAEnCv7E,KAAKw7E,6BACLx7E,KAAKy7E,kBAAkBrxE,EAAWT,SAClC3J,KAAK07E,gBAELtxE,EAAWzJ,KAAK,SAAUX,KAAK07E,eAC/BtxE,EAAWzJ,KAAK,WAAW,KACzB6J,GAAAA,EAAM7I,OAAO,YAAa3B,KAAK27E,mBAC/BnxE,GAAAA,EAAM7I,OAAQ,GAAEsxD,GAAAA,EAAe2oB,WAAW3oB,GAAAA,EAAeC,YAAalzD,KAAK67E,aAAa,IAG1FrxE,GAAAA,EAAM7J,KAAK,YAAaX,KAAK27E,mBAC7BnxE,GAAAA,EAAM7J,KAAa,GAAEsyD,GAAAA,EAAe2oB,WAAW3oB,GAAAA,EAAeC,YAAalzD,KAAK67E,aAClF,CAEAC,kBAAAA,CAAmBjqE,EAAiC9N,GAEhDA,EAAUu3E,sBAAwBt7E,KAAK2G,MAAM20E,qBAC7CzpE,EAAUupE,YAAYW,qBAAuB/7E,KAAKgD,MAAMo4E,YAAYW,qBAEpEh4E,EAAUu3E,qBAAqBlvE,oBAAoB,QAASwuE,IAExD56E,KAAKgD,MAAMo4E,YAAYW,oBAEzB/7E,KAAK2G,MAAM20E,qBAAqBnvE,iBAAiB,QAASyuE,GAAoB,CAAEzI,SAAS,IAG/F,CAEAnH,oBAAAA,GACE,MAAM,WAAE5gE,EAAU,YAAEgxE,GAAgBp7E,KAAKgD,MACrChD,KAAK+6E,0BACP3Y,aAAapiE,KAAK+6E,0BAEpBK,EAAYz5E,OAAO,SAAU3B,KAAKq7E,qBAClCjxE,EAAWzI,OAAO,SAAU3B,KAAK07E,eAEjC17E,KAAK2G,MAAM20E,qBAAqBlvE,oBAAoB,QAASwuE,GAC/D,CAEAoB,yBAA4BV,IAC1Bt7E,KAAK64E,SAAS,CAAEyC,uBAAsB,EAGxCzzD,MAAAA,GACE,MAAM,WAAE2pD,EAAU,WAAEn9D,EAAU,YAAE+mE,EAAW,WAAEhxE,EAAU,mBAAE6xE,GAAuBj8E,KAAKgD,MAC/Ek5E,EAAcd,EAAY/pE,6BAA+Bq7B,EAAAA,GAA2ByS,UACpF9pC,EACJ+lE,EAAY/pE,6BAA+Bq7B,EAAAA,GAA2BmiB,YAClEzkD,EAAW+xE,mBACX/xE,EAAWoiD,cACX4vB,EAAehB,EAAYjR,QAAQ/vC,SAASotB,EAAAA,GAAgBp3C,UAElE,OACEpB,EAAAA,EAAAA,MAAAiC,EAAAA,SAAA,CAAAxE,SAAA,EACEJ,EAAAA,EAAAA,KAAA,OACET,QAASswE,EAAc,IAAMl8E,KAAK4L,aAAQvD,QAAaA,EACvD,cAAc,SAAQgM,aACtBi/D,aAActzE,KAAKq8E,gBAAgB5vE,SAElC2vE,IAAgB/vE,EAAAA,EAAAA,KAACu9D,GAAa,CAA0Bv1D,WAAYA,EAAYjK,WAAYA,GAAxDgxE,EAAYlsE,UAElDksE,EAAY9Q,UAAY8R,GAAgBH,IACvC5vE,EAAAA,EAAAA,KAAA,OACE4C,UAAWo4D,IAAW,WAAY,CAChC,kBAAkB9yD,EAAAA,EAAAA,MAClB,8BAA8BA,EAAAA,EAAAA,QAC7B9H,SAEFwvE,OAGL5vE,EAAAA,EAAAA,KAAA,OACE84D,IAAKnlE,KAAKg8E,yBACV9I,aAAclzE,KAAKs8E,aACnBtJ,aAAejpC,EAAAA,GAAMD,gBAAoCzhC,EAAvBrI,KAAKq8E,gBACvCE,QAASv8E,KAAKw8E,aAAa/vE,SAE1B4I,EAAM3H,KAAI,CAACglB,EAAMzwB,KAChBoK,EAAAA,EAAAA,KAAC9B,GAAI,CAEHooE,UAAW1wE,EACXoS,WAAYA,EACZ3S,MAAOgxB,EACP8+C,WAAYA,EACZpnE,WAAYA,EACZ0pE,kBAAmB9zE,KAAKy8E,gBACxB/J,YAAawJ,EAAcl8E,KAAK4L,aAAUvD,EAC1CssE,cAAe30E,KAAK20E,cACpBxB,mBAAoBnzE,KAAKmzE,mBACzBM,kBAAmBzzE,KAAKyzE,kBACxBnB,cAAetyE,KAAKsyE,cACpBqB,mBAAoB3zE,KAAK2zE,mBACzB+B,0BAA2B11E,KAAKgD,MAAM0yE,0BACtCT,uBAAwBj1E,KAAKgD,MAAMiyE,uBACnCxC,oBAAqBzyE,KAAKgD,MAAMyvE,qBAf3B//C,EAAKxxB,UAqBtB,CAEAs7E,aAAgBj3E,IACd,MAAM,WAAE6E,EAAU,YAAEgxE,GAAgBp7E,KAAKgD,MACnCgQ,EAAY5I,EAAWiL,QAAQ+uB,QAAU,EAC1Cg3C,EAAYW,qBAAsB/oE,IAGlChT,KAAKm7E,kBACRn7E,KAAK08E,uBAEPta,aAAapiE,KAAK86E,mBAClB96E,KAAK86E,kBAAoBj1E,OAAOwX,YAAW,KACzCrd,KAAKm7E,iBAAmB,IAAI,GAC3B,KACHn7E,KAAK0zE,kBAAkBnuE,OAAG8C,GAAW,GAAK,EAG5CuD,QAAW+wE,IAEN38E,KAAKgD,MAAMo4E,YAAYrX,YAAY5hE,IAAInC,KAAKgD,MAAMoH,cACjDpK,KAAKgD,MAAMo4E,YAAYuB,YAAYx6E,IAAIw6E,IAAe38E,KAAKgD,MAAMo4E,YAAYuB,aAAeA,IAE9F38E,KAAKgD,MAAMo4E,YAAYjrE,iBAAiB,CAAE4zD,YAAa/jE,KAAKgD,MAAMoH,WAAYuyE,cAChF,EAGFpB,aAAeA,KACb,MAAM,WAAEnxE,GAAepK,KAAKgD,MAC5BhD,KAAK07E,gBACL17E,KAAKw7E,6BACLpxE,EAAWb,QAAQ,SAAUa,EAAW,EAG1CuqE,cAAiBiI,IACf,MAAM,WAAExyE,GAAepK,KAAKgD,MACtB0vB,EAAOtoB,EAAWiL,QAAQxL,KAAK+yE,GAEjClqD,IACFA,EAAKghC,iBACL1zD,KAAK07E,gBACLtxE,EAAWb,QAAQ,SAAUa,GAC/B,EAGFsxE,cAAiBmB,IACf,MAAM,WAAEzyE,EAAU,OAAE4pB,GAAWh0B,KAAKgD,MAC9BqS,EAAQjL,EAAWoiD,cACnB7iD,EAAQS,EAAWT,QAEzB,GAAqB,IAAjB0L,EAAMpV,SAAiB0J,QAAmCtB,IAA1B+B,EAAW6gB,WAC7C,OAGF,MAAM,MAAEzjB,EAAK,OAAEC,GAAW2C,EAC1B,IAAI0yE,EAAcznE,EAAMtI,QAAO,CAAC81C,EAAKnwB,IAASmwB,GAAOnwB,EAAKjrB,QAAU,IAAI,GACxE,GAAIq1E,IAAgBr1E,EAAQ,CAC1Bq1E,EAAcznE,EAAMtI,QAAO,CAAC81C,EAAKnwB,KAC/B,MAAMqqD,EAAgB19D,KAAK2E,MAAO0O,EAAKjrB,OAASq1E,EAAer1E,GAI/D,OAHKqc,OAAOkS,MAAM+mD,IAChBrqD,EAAKgd,gBAAgB,SAAUqtC,GAE1Bl6B,EAAMk6B,CAAa,GACzB,GACH,MAAM5pB,EAAY/oD,EAAWgpD,eAC7B,GAAID,GAAa2pB,IAAgBr1E,EAAQ,CACvC,MAAMu1E,EAAqB7pB,EAAU1rD,OAASA,EAASq1E,EAClDh5D,OAAOkS,MAAMgnD,IAChB7pB,EAAUzjB,gBAAgB,SAAUstC,EAExC,CACF,CAEA,MAAM/G,GAAgBtjB,EAAAA,GAAAA,IAAc,CAClChpD,QACAS,aACA4pB,OAAQA,IAEJipD,EAAgB7yE,EAAW6gB,aAAegrD,EAC1CrjB,EAAaxoD,EAAWwoD,WACzBA,GAAc5yD,KAAK66E,YAAcrzE,EAG3BorD,IAAeqqB,GACxB7yE,EAAW+F,iBAAiB,CAAEyiD,WAAYqqB,KAH1Cj9E,KAAK66E,UAAYrzE,EACjB4C,EAAWslC,gBAAgB,aAAcumC,IAKvCj2E,KAAKg7E,aAAevzE,IACtBzH,KAAKg7E,WAAavzE,EAClBzH,KAAKw7E,8BAGHqB,GACF78E,KAAKy7E,kBAAkBoB,EAAgBlzE,QACzC,EAGF0xE,oBAAsBjzE,IAAqF,IAApF,YAAE27D,EAAW,WAAE4Y,GAAgEv0E,EACpG,MAAM,WAAEgC,GAAepK,KAAKgD,MAC5B,GAAK+gE,EAGL,IAAK,MAAMrxC,KAAQtoB,EAAWoiD,cACxBmwB,GAAYz7E,KAAOwxB,EAAKxxB,KAAqC,IAA/BwxB,EAAKC,WAAWZ,aAChDW,EAAKC,UAAUJ,eAAc,GAC7BG,EAAKgd,gBAAgB,iBAAarnC,GAEtC,EAGF8qE,mBAAqBA,CAAC5tE,EAAkC7D,KACrC,IAAb6D,EAAEqwE,SAGN51E,KAAK8iB,MAAQvd,EAAEkmE,QACfzrE,KAAKi7E,iBAAmBj7E,KAAKgD,MAAMoH,WAChCiL,QACArT,MACAH,WAAW6wB,GAASA,EAAKvwB,IAAIT,KAChCkJ,SAASuB,iBAAiB,YAAanM,KAAKk9E,oBAC5CtyE,SAASuB,iBAAiB,UAAWnM,KAAKm9E,kBAAiB,EAG7DD,mBAAsB33E,IAChBvF,KAAKi7E,iBAAmB,GAAoB,OAAfj7E,KAAK8iB,OAAkB9iB,KAAKo9E,uBAAuBp9E,KAAK8iB,MAASvd,EAAEkmE,WAClGzrE,KAAK8iB,MAAQvd,EAAEkmE,QACjB,EAGF0R,iBAAoB53E,IAClB,MAAM,WAAE6E,GAAepK,KAAKgD,MACxBhD,KAAKi7E,iBAAmB,GAAoB,OAAfj7E,KAAK8iB,QACpC9iB,KAAKo9E,uBAAuBp9E,KAAK8iB,MAAQvd,EAAEkmE,SAC3CzrE,KAAK8iB,MAAQ,KAEb1Y,EAAWb,QAAQ,SAAUa,IAG/BQ,SAASwB,oBAAoB,YAAapM,KAAKk9E,oBAC/CtyE,SAASwB,oBAAoB,UAAWpM,KAAKm9E,iBAAiB,EAGhE3B,0BAAAA,GACE,MAAM,WAAEpxE,GAAepK,KAAKgD,OACtB,UAAE0tD,EAAS,MAAE2sB,GAAUjzE,EAC1BiL,QACArT,MACA+K,QACC,CAAAe,EAAuB4kB,KAAS,IAA/B,UAAEg+B,EAAS,MAAE2sB,GAAOvvE,EAKnB,OAJI4iD,EAAYh+B,EAAKjrB,SACnBipD,EAAYh+B,EAAKjrB,QAEnB41E,GAAS3qD,EAAKogD,iBAAmB,EAAI,EAC9B,CAAEpiB,YAAW2sB,QAAO,GAE7B,CAAE3sB,UAAWtmD,EAAW3C,OAAQ41E,MAAO,IAErCC,EAAgBj+D,KAAK+E,MAAMha,EAAW3C,OAAS41E,GACrDr9E,KAAKk7E,kBAAoB77D,KAAKqF,IAAIgsC,EAAW4sB,EAC/C,CAEAF,sBAAAA,CAAuB18D,GACrB,MAAM,WAAEtW,GAAepK,KAAKgD,MACtBqS,EAAQjL,EAAWiL,QAAQrT,MACjC,IAAIu7E,EAAWv9E,KAAKi7E,iBACpB,IAAKv6D,EACH,OAAO,EACF,GAAIA,EAAO,EAAG,CACnB,IAAIwB,EAAIq7D,EACJ7qD,EAAOrd,EAAM6M,GAMjB,IALIwQ,EAAKjrB,OAASiZ,GAAQ1gB,KAAKk7E,kBAC7BxoD,EAAKgd,gBAAgB,SAAUhd,EAAKjrB,OAASiZ,GAE7CgS,EAAKgd,gBAAgB,SAAU1vC,KAAKk7E,qBAE/Bh5D,EAAGA,GAAK,EAAGA,IAAK,CAErB,GADAwQ,EAAOrd,EAAM6M,GACTwQ,EAAKjrB,OAASiZ,GAAQ1gB,KAAKk7E,kBAAmB,CAChDxoD,EAAKgd,gBAAgB,SAAUhd,EAAKjrB,OAASiZ,GAC7C,KACF,CACEgS,EAAKgd,gBAAgB,SAAU1vC,KAAKk7E,kBAExC,CACF,MAAO,GAAIx6D,EAAO,EAAG,CACnB68D,EAAWl+D,KAAKwF,IAAI,EAAG04D,EAAW,GAClC,IAAIr7D,EAAIq7D,EACJ7qD,EAAOrd,EAAM6M,GAMjB,IALIwQ,EAAKjrB,OAASiZ,GAAQ1gB,KAAKk7E,kBAC7BxoD,EAAKgd,gBAAgB,SAAUhd,EAAKjrB,OAASiZ,GAE7CgS,EAAKgd,gBAAgB,SAAU1vC,KAAKk7E,qBAE/Bh5D,EAAGA,EAAI7M,EAAMpV,OAAQiiB,IAAK,CAE/B,GADAwQ,EAAOrd,EAAM6M,GACTwQ,EAAKjrB,OAASiZ,GAAQ1gB,KAAKk7E,kBAAmB,CAChDxoD,EAAKgd,gBAAgB,SAAUhd,EAAKjrB,OAASiZ,GAC7C,KACF,CACEgS,EAAKgd,gBAAgB,SAAU1vC,KAAKk7E,kBAExC,CACF,CAEA,MAAM4B,EAAcznE,EAAMtI,QAAO,CAAC81C,EAAKnwB,IAASmwB,EAAMnwB,EAAKjrB,QAAQ,GACnE,GAAIq1E,IAAgB1yE,EAAW3C,OAAQ,CACrCiZ,EAAOtW,EAAW3C,OAASq1E,EAE3B,MAAMpqD,EAAOrd,EAAMkoE,GAInB,OAHA7qD,EAAKgd,gBAAgB,SAAUhd,EAAKjrB,OAASiZ,IAGtC,CACT,CAEA,OAAO,CACT,CAEAizD,mBAAsBpuE,IACfvF,KAAKgD,MAAMo4E,YAAYhJ,YAAmC,IAArB7sE,EAAEi4E,QAAQv9E,SAAgBD,KAAKgD,MAAMyvE,qBAG/EzyE,KAAKyzE,kBAAkBluE,EAAE4vE,cAAc,GAAG,EAG5CsI,kBAAqBl4E,IACdvF,KAAKgD,MAAMo4E,YAAYhJ,YAAmC,IAArB7sE,EAAEi4E,QAAQv9E,QAGpDD,KAAK0zE,kBAAkBnuE,EAAE4vE,cAAc,GAAG,EAG5CuI,iBAAmBA,KACZ19E,KAAKgD,MAAMo4E,YAAYhJ,YAG5BpyE,KAAK29E,iBAAiB,EAGxBC,eAAkBr4E,IAChB,MAAM4f,EAAK,CAAE3G,EAAGjZ,EAAEi4E,QAAQ,GAAG7R,QAASltD,EAAGlZ,EAAEi4E,QAAQ,GAAG/R,SAChDrmD,EAAK,CAAE5G,EAAGjZ,EAAEi4E,QAAQ,GAAG7R,QAASltD,EAAGlZ,EAAEi4E,QAAQ,GAAG/R,SACtD,OAAO3qD,GAAAA,GAAKwE,SAASH,EAAIC,EAAG,EAG9Bk3D,aAAgB/2E,IACd,MAAM,WAAE6E,GAAepK,KAAKgD,OACtB,uBAAEiyE,EAAsB,0BAAES,EAAyB,oBAAEjD,GAAwBzyE,KAAKgD,MAClFgQ,EAAY5I,EAAWiL,QAAQ+uB,QAAU,GAG7CpkC,KAAKgD,MAAMo4E,YAAYhJ,YACF,IAArB7sE,EAAEi4E,QAAQv9E,QACTg1E,GACAjiE,GACAy/D,IAEDiD,EAA0B,SAC1B11E,KAAKyzE,kBAAkB,CAAE9H,QAAS3rE,KAAK49E,eAAer4E,KAEtDqF,SAASuB,iBAAiB,YAAanM,KAAK69E,aAC5CjzE,SAASuB,iBAAiB,WAAYnM,KAAK89E,YAC7C,EAGFD,YAAet4E,IACY,IAArBA,EAAEi4E,QAAQv9E,QACZD,KAAK0zE,kBAAkB,CAAE/H,QAAS3rE,KAAK49E,eAAer4E,IACxD,EAGFu4E,WAAcv4E,IACa,IAArBA,EAAEi4E,QAAQv9E,SACZD,KAAK29E,kBACL/yE,SAASwB,oBAAoB,YAAapM,KAAK69E,aAC/CjzE,SAASwB,oBAAoB,WAAYpM,KAAK89E,YAChD,EAGFpB,qBAAuBA,KACrB,MAAM,WAAEtyE,GAAepK,KAAKgD,OACtB,cAAEk4B,GAAkB9wB,EAAWiU,yBAC/B1U,EAAQS,EAAWT,QACnBwY,EAAK/X,EAAWiL,QAAQotC,QAAQtrC,MAAMqH,EACtCi2B,GAAWC,EAAAA,EAAAA,IAAsB,CAAEC,WAAYvqC,EAAWuqC,WAAY3jC,YAAahR,KAAKgD,MAAMo4E,cAC9F2C,GAAoBprB,EAAAA,GAAAA,IAAc,CAAEhpD,QAAOS,aAAY4pB,OAAQh0B,KAAKgD,MAAMgxB,OAAQygB,aAGxF,GAFAz0C,KAAKm7E,iBAAmB,KAEpBxxE,EAAMq0E,YAAcr0E,EAAMkJ,aAAeC,EAAAA,GAAWC,MAAO,CAC7D,MAAMqpB,EAAWzyB,EAAMwxB,YAAYxxB,EAAMyxB,MAAMn7B,OAAS,GACxD,IAAIg+E,EACF7zE,EAAW6gB,YACX0nC,EAAAA,GAAAA,IAAc,CACZhpD,QACAS,WAAYA,EACZ4pB,OAAQh0B,KAAKgD,MAAMgxB,OACnBygB,WACArY,WACA8hD,8BAA8B,IAElC,MAAMC,KAAgBF,EAAaxpC,GACnCwpC,GAAcE,EAAa1pC,EAC3Bz0C,KAAKm7E,iBAAmB,CACtB/+C,WACAn6B,MAAOm6B,EAAW+hD,EAClBF,aAEJ,MAAO,GAAI7zE,EAAW6gB,YAAc8yD,EAClC/9E,KAAKm7E,iBAAmB,CACtBl5E,MAAO0H,EAAMwxB,YAAYxxB,EAAM2jC,KAAKrtC,OAAS,GAC7Cg+E,WAAY7zE,EAAW6gB,WAAa8yD,OAEjC,CACL,MAAMxnD,EAASnsB,EAAW6gB,WAC1B,IAAK,IAAI/I,EAAI,EAAGA,EAAIvY,EAAM2jC,KAAKrtC,OAAQiiB,GAAK,EAAG,CAC7C,MAAM1D,EAAI2D,EAAGD,GACb,KAAI1D,EAAI+X,EAAS,IAGb/X,EAAI+X,EAASnsB,EAAW5C,MAAQ0zB,EAAczU,KAAKjf,MAAQ0zB,EAAc3U,MAAM/e,MAAO,CACxF,MAAM40B,EAAWzyB,EAAMwxB,YAAYjZ,EAAI,GACvC,IAAI+7D,EACF1nD,GACAo8B,EAAAA,GAAAA,IAAc,CACZhpD,QACAS,aACA4pB,OAAQh0B,KAAKgD,MAAMgxB,OACnBygB,WACArY,aAEJ,MAAM+hD,KAAgBF,EAAaxpC,GACnCwpC,GAAcE,EAAa1pC,EAC3Bz0C,KAAKm7E,iBAAmB,CACtB/+C,WACAn6B,MAAOm6B,EAAW+hD,EAClBF,cAEF,KACF,CACF,CACF,GAGFxK,kBAAqBluE,IACnB,IAAkB,IAAbA,EAAEqwE,UAAgB,WAAYrwE,KAAOvF,KAAKgD,MAAMo4E,YAAYhJ,WAAjE,CAGA,OAAQpyE,KAAKgD,MAAMiyE,wBACjB,IAAK,QACH,MACF,KAAK,KACHj1E,KAAKgD,MAAM0yE,0BAA0B,UACrC,MACF,QACE,OAGJ11E,KAAK6iB,MAAQtd,EAAEomE,SAAW,KAC1B3rE,KAAK08E,uBAEL9xE,SAASuB,iBAAiB,YAAanM,KAAK0zE,mBAC5C9oE,SAASuB,iBAAiB,UAAWnM,KAAK29E,iBAC1C/yE,SAASuB,iBAAiB,YAAanM,KAAKy9E,mBAC5C7yE,SAASuB,iBAAiB,WAAYnM,KAAK09E,iBAjB3C,CAiB4D,EAG9DU,qBAAwB74E,IAEtB,MAAMsa,EAAMR,KAAKQ,IAAIta,EAAE84E,QACvB,OAAY,IAARx+D,EAAkB,EACfR,KAAK7Z,IAAIqa,GAAOR,KAAKoO,KAAKloB,EAAE84E,QAAU,EAAE,EAGjD3K,kBAAoB,MAAH,IAAAsF,EAAG,KAAH,OAAG,SAClBzzE,EACAmsB,GAEG,IADH4sD,EAAYl9E,UAAAnB,OAAA,QAAAoI,IAAAjH,UAAA,IAAAA,UAAA,GAEZ,MAAM,WAAEgJ,EAAU,YAAEgxE,GAAgBpC,EAAKh2E,MACzC,IAAIyd,EACC26D,EAAYhJ,aACZkM,GAA+B,OAAftF,EAAKn2D,MAMxBpC,EAAOu4D,EAAKoF,qBAAqB74E,GAAmB,KALpDkb,GAAQu4D,EAAKn2D,MAAQtd,EAAEomE,SAAWvhE,EAAW5C,MAC7CwxE,EAAKn2D,MAAQtd,EAAEomE,SAOjBqN,EAAKyD,gBAAgB,CAAE1I,MAAOtzD,IAChC,CAAC,EAlBmB,GAoBpBg8D,gBAAkB/sE,IAMZ,IANa,KACjBqkE,EAAI,0BACJC,GAA4B,GAI7BtkE,EACC,MAAM,WAAEtF,EAAU,YAAEgxE,GAAgBp7E,KAAKgD,MACrCgxE,GACFh0E,KAAK08E,uBAGP,MAAM6B,EAAkBn0E,EAAWuqC,YAAc,GAAID,EAAAA,EAAAA,IAAsB,CAAE1jC,YAAahR,KAAKgD,MAAMo4E,eAC/FzmC,EAnkBV,SAAsBhtC,GAYnB,IAZoB,YACrBqJ,EAAW,kBACXwtE,EAAiB,KACjBzK,EAAI,gBACJ0K,EAAkB,EAAC,gBACnBC,EAAkB,IAOnB/2E,EACC,MAAMg3E,GAAgBC,EAAAA,EAAAA,IAA8B,CAClD5tE,cACA6tE,kBAAmBJ,EACnBzoB,iBAAkB,IAEd8oB,GAAgBF,EAAAA,EAAAA,IAA8B,CAClD5tE,cACA6tE,kBAAmBH,EACnB1oB,iBAAkB,IAEd+oB,EAAsBhL,EAAO,EAC7BiL,EAAgBR,EAAoBzK,EACpCkL,EAAuB5/D,KAAKqF,IAAIrF,KAAKwF,IAAI85D,EAAeK,GAAgBF,GAE9E,OAAIE,EAAgBC,GAAwBT,EAAoBS,EACvDF,EAAsBC,EAAgBR,EAG3CQ,EAAgBC,GAAwBT,EAAoBS,EACtDF,EAAsCP,EAAhBQ,EAGzBC,CACT,CA+hBuBC,CAAc,CAC/BluE,YAAaoqE,EACboD,kBAAmBp0E,EAAWuqC,WAC9Bo/B,KAAMA,EAAOwK,IAET9pC,GAAWC,EAAAA,EAAAA,IAAsB,CACrCC,aACA3jC,YAAahR,KAAKgD,MAAMo4E,cAG1B,IAAInwD,EACJ,GAAIjrB,KAAKgD,MAAMgxB,OAAOmrD,QACpBl0D,EAAa,OACR,IAAI0gB,EAAAA,GAAAA,IAAqB3rC,KAAKgD,MAAMo4E,YAAY/pE,4BACrD4Z,EAAawpB,MACR,KAAIz0C,KAAKm7E,iBAgBd,OAfAlwD,GAAa+qD,EAAAA,GAAAA,IAAoB,CAC/BC,eACEtjB,EAAAA,GAAAA,IAAc,CACZhpD,MAAOS,EAAWT,QAClBS,WAAYA,EACZ4pB,OAAQh0B,KAAKgD,MAAMgxB,OACnBygB,WACArY,SAAUp8B,KAAKm7E,iBAAiBl5E,MAChCi8E,8BAA8B,IAC3Bl+E,KAAKm7E,iBAAiB8C,WAC7B7zE,WAAYA,EACZqqC,WACArY,UAAUjB,EAAAA,GAAAA,IAAY/wB,EAAWT,UAIrC,CACAS,EAAW+F,iBAAiB,CAC1BwkC,aACA1pB,aACA/W,UAAW,OAET8/D,IACFh0E,KAAKm7E,iBAAmB,KAC1B,EAGFwC,gBAAkBA,KAChB39E,KAAKm7E,iBAAmB,KACxBvwE,SAASwB,oBAAoB,YAAapM,KAAK0zE,mBAC/C9oE,SAASwB,oBAAoB,UAAWpM,KAAK29E,iBAC7C/yE,SAASwB,oBAAoB,YAAapM,KAAKy9E,mBAC/C7yE,SAASwB,oBAAoB,WAAYpM,KAAK09E,kBAC9C19E,KAAKgD,MAAM0yE,0BAA0B,KAAK,EAG5CpD,cAAgBA,KACd,MAAM,WAAEloE,EAAU,YAAEgxE,GAAgBp7E,KAAKgD,MACnC2xC,EAAavqC,EAAWwpB,eAAei7C,kBACvCp6B,GAAWC,EAAAA,EAAAA,IAAsB,CAAEC,aAAY3jC,YAAaoqE,IAC5DnwD,GAAa0nC,EAAAA,GAAAA,IAAc,CAC/BhpD,MAAOS,EAAWT,QAClBS,aACA4pB,OAAQh0B,KAAKgD,MAAMgxB,OACnBygB,aAGFrqC,EAAW+F,iBAAiB,CAC1BwkC,aACA1pB,aACA/W,UAAW,MACX,EAGJynE,kBAAoBA,KAClB,MAAM,IAAIvyE,MAAM,oCAAoC,EAItDizE,gBAAkBA,KACEr8E,KAAKgD,MAAMoH,WAAWiL,QAAQ+uB,QAAU,GAExDqtC,GAAAA,EAAWthE,iBAAiB,CAC1B0H,SAAU,KACV6a,KAAM,MAEV,EAGF+oD,kBAAqB9xE,IACnB,MAAM,WAAES,GAAepK,KAAKgD,MAG5B,GAAIoH,EAAW8J,UAAW,CACxB,IAAKvK,EAAMxH,IAAIiI,EAAWT,UAAYS,EAAWqK,YAAc9K,EAAM8K,WAAmC,IAAtB9K,EAAM69B,KAAKvnC,OAC3F,QAEFm/E,EAAAA,GAAAA,IAAmC,CAAEh1E,aAAYT,SACnD,GAGFkyE,aAAeA,CAACwD,EAAiBrsB,KAC/B,MAAM,WAAE5oD,GAAepK,KAAKgD,MACtB2G,EAAQS,EAAWT,QACzB,IAAKA,GAAOxH,IAAIk9E,GACd,OAGF,MAAMC,EAA8BtsB,IAAcC,GAAAA,EAAe2oB,QACjE,IAAI3F,EAAgB7rE,EAAW6gB,aAEU,IAAtCjrB,KAAKgD,MAAMo4E,YAAYhJ,aAAyBpyE,KAAKgD,MAAMo4E,YAAY7G,qBACvEnqE,EAAWwoD,YACZ0sB,KAEArJ,GAAgBtjB,EAAAA,GAAAA,IAAc,CAC5BhpD,QACAS,WAAYA,EACZ4pB,OAAQh0B,KAAKgD,MAAMgxB,UAIvB5pB,EAAWupD,eAAehqD,EAAMC,aAAcD,EAAM4qD,QAEhD0hB,IAAkB7rE,EAAW6gB,YAC/B7gB,EAAW4jD,iBAAiBzlD,SAASzG,IAC/BA,EAAQmsD,cAAgBnsD,EAAQgwB,eAClChwB,EAAQ2H,SAASka,cACnB,IAIJvZ,EAAWslC,gBAAgB,aAAcumC,GAEzCj2E,KAAKy7E,kBAAkB9xE,EAAM,EAIjC,SC1tBO,SAAuBoT,GAC5B,OAAO,SAA0B/Z,GAC/B,MAAM,YAAEu8E,EAAc5E,GAAyB,SAAE6E,GAAax8E,EACxDy8E,EAAsBp0E,EAAAA,QAAa,GACnC3J,GAAQ4M,EAAAA,EAAAA,GAActL,EAAMoH,WAAY,CAAEmE,gBAAiB,CAAC,QAAS,WACrE6sE,GAAc9sE,EAAAA,EAAAA,GAActL,EAAMo4E,YAAa,CAAE7sE,gBAAiB,CAAC,iBACnE5E,EAAQjI,EAAMiI,QAEd+1E,EAAer0E,EAAAA,QAAa3D,UAChC,MAAM,WAAE0C,EAAU,OAAE4pB,GAAWhxB,GACzB,UAAE+wD,EAAS,eAAED,EAAc,YAAEE,EAAW,OAAEpoB,EAAM,WAAE/4B,EAAU,UAAE4B,EAAWY,MAAOsqE,GAAgB3rD,EAEhGtvB,EAAU,CACdqvD,YACAC,cACAO,OAAQT,EACRG,SAAU0rB,EAAYx3E,MACnBuqB,GACCA,EAAKhd,UAAUvN,MACZrG,GAAYA,EAAQkW,UAAU7P,MAAM8P,GAAyC,sBAAjBA,EAAQtC,YAKvEhM,QAAca,GAAAA,EAAM0oB,IAAI,CAC5B0Y,SACA/4B,aACA4B,YACA/P,YAEIk7E,EAAyBD,EAAY/nE,QAAOjQ,IAAA,IAAC,SAAE+N,GAAU/N,EAAA,OAC7D+N,EAASvN,MAAKC,IAAA,IAAC,KAAEuN,GAAMvN,EAAA,MAAc,oBAATuN,CAA0B,GAAC,IAWzD,GARIiqE,SACIziE,QAAQ0iE,WACZD,EAAuBlyE,KAAKoyE,IAC1BC,EAAAA,EAAAA,IAA+B,CAAED,wBAAuBrrE,YAAW/P,gBAKrE+6E,EAAoB5gF,QAAxB,CAkBA,GAdAm1B,EAAO3e,MAAM9M,SAASmqB,IACpB,MAAMstD,EAAiB94D,IAAM,CAAC,EAAGwL,GACjCstD,EAAet2E,MAAQU,EACvBA,EAAW61E,kBAAkBD,EAAe,IAG9C51E,EAAW+F,iBAAiB,CAC1BxG,QACAoqD,UAAWrvD,EAAQqvD,UACnBC,YAAatvD,EAAQsvD,cAGvB5pD,EAAWupD,eAAehqD,EAAMC,aAAa,GAEzC5G,EAAMk9E,aAAc,CACtB,MAAMC,GAAmBC,EAAAA,EAAAA,IAAoBp9E,EAAMo4E,YAAY9iC,oBAC/Dt1C,EAAMo4E,YAAYjrE,iBAAiBgwE,EACrC,CAEA,GAA6B,MAAzB/1E,EAAW6gB,WAAoB,CACjC,MAAMA,GAAa0nC,EAAAA,GAAAA,IAAc,CAAEhpD,QAAOS,WAAYA,EAAY4pB,OAAQhxB,EAAMgxB,SAChF5pB,EAAWslC,gBAAgB,aAAczkB,EAC3C,CAxBA,CAwBA,IAGF5f,EAAAA,WAAgB,KACd,MAAMg1E,EAA2BA,KAC/BZ,EAAoB5gF,SAAU,CAAI,EAKpC,OAFA6C,EAAMf,KAAK,gBAAiB0/E,GAC5BX,EAAa7gF,UACN,KACL6C,EAAMC,OAAO,gBAAiB0+E,EAAyB,CACxD,GAGA,IAEH,MAAM/Z,EAActjE,EAAMo4E,YAAY/pE,6BAA+Bq7B,EAAAA,GAA2BkiB,UAC1FstB,EAAcl5E,EAAMo4E,YAAY/pE,6BAA+Bq7B,EAAAA,GAA2ByS,UAC1FmhC,EAA2B,CAC/B5zC,EAAAA,GAA2BmiB,YAC3BniB,EAAAA,GAA2BoiB,UAC3BpiB,EAAAA,GAA2BqiB,YAC3B30B,SAASp3B,EAAMo4E,YAAY/pE,4BACvBkvE,EACJ52E,SAA+BtB,IAApBsB,EAAMirD,WAA2BjrD,EAAMyxB,MAAMn7B,OAAS,GAAM0J,EAAMirD,UAAY,GAAKjrD,GAC1F62E,GACHD,GAAgBja,EAEb,CAAE9+D,MAAO9F,EAAM8F,MAAQ9F,EAAM8F,MAAQ,EAAI,OAAQC,OAAQ/F,EAAM+F,OAAS,QACxEY,EAEN,OACE2G,EAAAA,EAAAA,MAACuwE,EAAW,CACVtwE,UAAW0hD,IF7Gc,wBE6GgB,CACvC9gD,OAAQy2D,EACR,kBAAmBga,IAA4B/rE,EAAAA,EAAAA,MAC/C,qCAAsC6mE,EAAYrX,YAAY5hE,IAAIT,IAAUsB,EAAMy9E,gBAE/ElB,IAAgB5E,GAA4B,CAAE6E,YAAa,CAAC,EACjE,cAAc,SAAQx8E,EAAMqR,uBAC5B8B,MAAOqqE,EAAa/zE,SAAA,CAEnByvE,IACC7vE,EAAAA,EAAAA,KAACkuE,GAAmB,CAClBtrE,UAAW0hD,IAAW,CACpB,WAAY2V,EACZ,8BAA+B4V,IAEjC1B,eAAgB+F,IAGnBA,IAAgBl0E,EAAAA,EAAAA,KAAC0Q,EAAS,IAAK/Z,MAGtC,CACF,CD8lBA,CEnuBO,SAA4E+Z,GACjF,OAAO,SAA0B/Z,GAC/B,MAAMtB,GAAQ4M,EAAAA,EAAAA,GAActL,EAAMoH,WAAY,CAAEmE,gBAAiB,CAAC,WAElE,OAAOlC,EAAAA,EAAAA,KAAC0Q,EAAS,IAAK/Z,EAAOtB,MAAOA,GACtC,CACF,CF6tB6Bg/E,CAA6Bp2E,K,4BGxuBnD,MAAMq2E,GAA6B,CACxC34E,SAAUA,IAAM,8BAChBZ,SAAU,oBCACw5E,GAAgE,CAC3E,CAACC,GAAAA,GAAeC,SAAU,CACxB5/E,GAAI2/E,GAAAA,GAAeC,QACnBt9E,MAAO,WACPy0D,KAAM,QAER,CAAC4oB,GAAAA,GAAeE,gBAAiB,CAC/B7/E,GAAI2/E,GAAAA,GAAeE,eACnBv9E,MAAO,sBACPy0D,KAAM,uBAER,CAAC4oB,GAAAA,GAAeG,yBAA0B,CACxC9/E,GAAI2/E,GAAAA,GAAeG,wBACnBx9E,MAAO,gCACPy0D,KAAM,wBAIGgpB,GAA2Bt5E,IAAA,IAAC,iBACvCm6D,EAAgB,mBAChBof,GAAqB,EAAK,OAC1BC,GAKDx5E,EAAA,MAAuC,IAClCu5E,EACA,CACE,CACEE,YAAaR,GAAeC,GAAAA,GAAeC,SAC3CO,WAAYF,EACZG,gBAAiB,uCAGrB,GACJ,CACEF,YACER,GAAe9e,EAAmB+e,GAAAA,GAAeG,wBAA0BH,GAAAA,GAAeE,iBAE/F,ECxCKQ,GAAkE,CACtE,CAACC,GAAAA,GAAeC,kBAAmB,CACjCvgF,GAAIsgF,GAAAA,GAAeC,iBACnBxpB,KAAM,iCACNypB,WAAY,uCACZl+E,MAAO,yBACPm+E,YAAa,yBAEf,CAACH,GAAAA,GAAeI,uBAAwB,CACtC1gF,GAAIsgF,GAAAA,GAAeI,sBACnB3pB,KAAM,4BACNypB,WAAY,kCACZl+E,MAAO,uBACPm+E,YAAa,4BAEf,CAACH,GAAAA,GAAeK,cAAe,CAC7B3gF,GAAIsgF,GAAAA,GAAeK,aACnB5pB,KAAM,qBACNypB,WAAY,qBACZl+E,MAAO,gBACPm+E,YAAa,iBAEf,CAACH,GAAAA,GAAeM,cAAe,CAC7B5gF,GAAIsgF,GAAAA,GAAeM,aACnB7pB,KAAM,qBACNypB,WAAY,uBACZl+E,MAAO,gBACPm+E,YAAa,oBAIXI,GAA2D,CAC/D7gF,GAAIsgF,GAAAA,GAAeC,iBACnBxpB,KAAM,4BACNypB,WAAY,2BACZM,WAAY,+BACZx+E,MAAO,yBACPm+E,YAAa,wBACbM,YAAa,6BAGFC,GAA4Bv6E,IAQC,IARA,uCACxCw6E,EAAsC,OACtChB,EAAM,qBACNiB,GAKDz6E,EAuBC,MAtBwB,CACtB,CACEy5E,YAAaG,GAAgBC,GAAAA,GAAeI,2BAE1CO,EACA,CACE,CACEf,YAAaW,GACbV,WAAYF,EACZkB,WAAYD,EACZd,gBAAiB,uCAGrB,GACJ,CACEF,YAAaG,GAAgBC,GAAAA,GAAeK,eAE9C,CACET,YAAaG,GAAgBC,GAAAA,GAAeM,eAI1B,ECxEXQ,GAAyD,CACpE,CAAC1O,GAAAA,GAAYC,OAAQ,CACnB3yE,GAAI0yE,GAAAA,GAAYC,MAChBrwE,MAAO,QACPy0D,KAAM,aAER,CAAC2b,GAAAA,GAAY/3C,SAAU,CACrB36B,GAAI0yE,GAAAA,GAAY/3C,QAChBr4B,MAAO,UACPy0D,KAAM,eAER,CAAC2b,GAAAA,GAAYh5C,YAAa,CACxB15B,GAAI0yE,GAAAA,GAAYh5C,WAChBp3B,MAAO,OACPy0D,KAAM,YAER,CAAC2b,GAAAA,GAAYt2D,OAAQ,CACnBpc,GAAI0yE,GAAAA,GAAYt2D,MAChB9Z,MAAO,QACPy0D,KAAM,aAER,CAAC2b,GAAAA,GAAY5uC,cAAe,CAC1B9jC,GAAI0yE,GAAAA,GAAY5uC,aAChBxhC,MAAO,gBACPy0D,KAAM,gBAER,CAAC2b,GAAAA,GAAYj5C,gBAAiB,CAC5Bz5B,GAAI0yE,GAAAA,GAAYj5C,eAChBn3B,MAAO,kBACPy0D,KAAM,gBAER,CAAC2b,GAAAA,GAAY3wC,WAAY,CACvB/hC,GAAI0yE,GAAAA,GAAY3wC,UAChBz/B,MAAO,YACPy0D,KAAM,YAER,CAAC2b,GAAAA,GAAY3lD,kBAAmB,CAC9B/sB,GAAI0yE,GAAAA,GAAY3lD,iBAChBzqB,MAAO,oBACPy0D,KAAM,mBAER,CAAC2b,GAAAA,GAAY7uC,UAAW,CACtB7jC,GAAI0yE,GAAAA,GAAY7uC,SAChBvhC,MAAO,WACPy0D,KAAM,gBAER,CAAC2b,GAAAA,GAAY5nD,SAAU,CACrB9qB,GAAI0yE,GAAAA,GAAY5nD,QAChBxoB,MAAO,UACPy0D,KAAM,eAER,CAAC2b,GAAAA,GAAY1oD,OAAQ,CACnBhqB,GAAI0yE,GAAAA,GAAY1oD,MAChB1nB,MAAO,QACPy0D,KAAM,aAER,CAAC2b,GAAAA,GAAY/yC,WAAY,CACvB3/B,GAAI0yE,GAAAA,GAAY/yC,UAChBr9B,MAAO,YACPy0D,KAAM,iBAER,CAAC2b,GAAAA,GAAYpyC,SAAU,CACrBtgC,GAAI0yE,GAAAA,GAAYpyC,QAChBh+B,MAAO,UACPy0D,KAAM,eAER,CAAC2b,GAAAA,GAAY2O,OAAQ,CACnBrhF,GAAI0yE,GAAAA,GAAY2O,MAChB/+E,MAAO,QACPy0D,KAAM,aAER,CAAC2b,GAAAA,GAAYpwC,YAAa,CACxBtiC,GAAI0yE,GAAAA,GAAYpwC,WAChBhgC,MAAO,OACPy0D,KAAM,YAER,CAAC2b,GAAAA,GAAY1yD,OAAQ,CACnBhgB,GAAI0yE,GAAAA,GAAY1yD,MAChB1d,MAAO,QACPy0D,KAAM,aAER,CAAC2b,GAAAA,GAAYv9C,cAAe,CAC1Bn1B,GAAI0yE,GAAAA,GAAYv9C,aAChB7yB,MAAO,gBACPy0D,KAAM,mBAER,CAAC2b,GAAAA,GAAYj6C,uBAAwB,CACnCz4B,GAAI0yE,GAAAA,GAAYj6C,sBAChBn2B,MAAO,yBACPy0D,KAAM,iBAER,CAAC2b,GAAAA,GAAY97D,UAAW,CACtB5W,GAAI0yE,GAAAA,GAAY97D,SAChBtU,MAAO,WACPy0D,KAAM,gBAER,CAAC2b,GAAAA,GAAYruD,SAAU,CACrBrkB,GAAI0yE,GAAAA,GAAYruD,QAChB/hB,MAAO,UACPy0D,KAAM,gBAIGuqB,GAAsD,CACjE,CACEpB,YAAakB,GAAa1O,GAAAA,GAAYC,QAExC,CACEuN,YAAakB,GAAa1O,GAAAA,GAAY/3C,UAExC,CACEulD,YAAakB,GAAa1O,GAAAA,GAAYh5C,YACtC6nD,UAAW,CACTH,GAAa1O,GAAAA,GAAYh5C,YACzB0nD,GAAa1O,GAAAA,GAAY5uC,cACzBs9C,GAAa1O,GAAAA,GAAYj5C,gBACzB2nD,GAAa1O,GAAAA,GAAY1oD,QAE3Bw3D,eAAgB,cAElB,CACEtB,YAAakB,GAAa1O,GAAAA,GAAYt2D,QAExC,CACE8jE,YAAakB,GAAa1O,GAAAA,GAAY3wC,YAExC,CACEm+C,YAAakB,GAAa1O,GAAAA,GAAY3lD,mBAExC,CACEmzD,YAAakB,GAAa1O,GAAAA,GAAY7uC,WAExC,CACEq8C,YAAakB,GAAa1O,GAAAA,GAAY5nD,UAExC,CACEo1D,YAAakB,GAAa1O,GAAAA,GAAYpyC,UAExC,CACE4/C,YAAakB,GAAa1O,GAAAA,GAAY2O,OACtCE,UAAW,CAACH,GAAa1O,GAAAA,GAAY2O,OAAQD,GAAa1O,GAAAA,GAAY/yC,YACtE6hD,eAAgB,eAElB,CACEtB,YAAakB,GAAa1O,GAAAA,GAAYpwC,YACtCi/C,UAAW,CAACH,GAAa1O,GAAAA,GAAYpwC,YAAa8+C,GAAa1O,GAAAA,GAAYruD,UAC3Em9D,eAAgB,cAElB,CACEtB,YAAakB,GAAa1O,GAAAA,GAAY1yD,QAExC,CACEkgE,YAAakB,GAAa1O,GAAAA,GAAYv9C,eAExC,CACE+qD,YAAakB,GAAa1O,GAAAA,GAAYj6C,wBAExC,CACEynD,YAAakB,GAAa1O,GAAAA,GAAY97D,YC9I7B6qE,GAA8B,2CAE5B,SAASC,GAAOj7E,GAab,IAbc,UAC9Bk7E,EAAS,aACTC,EAAY,gBACZC,EAAe,WACfvR,EAAU,iBACVnjE,EAAgB,mBAChB20E,EAAkB,qBAClBC,EAAoB,sBACpBC,EAAqB,aACrBC,EAAY,gBACZ5B,EAAe,mBACf6B,EAAkB,iBAClBC,GACc17E,EACd,MAAO27E,GAAyBtwE,UAAWuwE,KAAoCjoE,EAAAA,GAAAA,GAAe,IACzFqlE,GACHllE,kBAAkB,KAEd,cAAE+nE,IAAkBl1E,EAAAA,EAAAA,GACxBjD,EAAAA,SAAc,IAAMgD,EAAiB6zD,yBAAyB,CAAC7zD,IAC/D,CAAEE,gBAAiB,CAAC,oBAEf0/C,EAAWw1B,GAAgBp4E,EAAAA,UAAe,GAC3C+qE,EAAyB/qE,EAAAA,WAAiB+zD,GAE1CskB,EAA2BxB,GAA0B,CACzDC,wCAAwCngB,EAAAA,EAAAA,IAA0C3zD,GAClF+zE,qBAAsBoB,IAAkB5gB,EAAAA,GAAcE,OACtDqe,SAAU9yE,EAAiBmD,MAAMtQ,KAG7ByiF,EAA0B1C,GAAyB,CACvDnf,iBAAkB0hB,IAAkB5gB,EAAAA,GAAc0C,IAClD4b,mBAAoB7yE,EAAiBgD,6BAA+Bq7B,EAAAA,GAA2ByS,UAC/FgiC,SAAU9yE,EAAiBmD,MAAMtQ,KAqDnC,OAlDAmK,EAAAA,WAAgB,KACd,IAAKi4E,EACH,OAGF,MAAMpxD,EAAcA,CAACxwB,EAAkBkf,KACrC,MAAMgjE,EAA0BrC,EAAgBC,GAAAA,GAAeI,uBACzDj8B,EAAUjkD,EAAMgI,QAAQC,QAAQyxB,MAAMn7B,OAAS,EAC/C4jF,EAAoBtC,EAAgBC,GAAAA,GAAeK,cACnDiC,EAAOxB,GAAa9Q,GAAYtwE,GAEtC,GAAI4iF,IAASlQ,GAAAA,GAAYC,OAAS5lB,GAAa41B,IAAsBl+B,EACnE,OAGF89B,GAAa,GACb,MAAM,gCAAEM,EAA+B,2BAAEC,GAA+BV,EAClEW,EAAYrjE,EAAK24D,QAAUwK,EAAgCD,GAAQE,EAA2BF,GAC9FhiF,EAAUJ,EAAMgU,WAAWguD,OAAO,CACtCj6D,SAAU,IAAIw6E,EAAUrjE,EAAM,CAAC,EAAGlf,EAAO00E,GAAwB,KAC1DwN,GACHZ,EAAmBpP,GAAAA,GAAYC,OAEjC4P,GAAa,GACbN,KAAgB,MAGpBrhF,EAAQoiF,IAAI,WAAW97E,IAAkB,IAAjB,SAAEqB,GAAUrB,EAC9BqB,EAASuZ,iBACXygE,GAAa,GACbN,MACF,IAGFrhF,EAAQyH,QAAQ,SAAUzH,EAAQ,EAGpC,OADAg2E,GAAAA,EAAUn3E,KAAK,YAAauxB,GACrB,KACL4lD,GAAAA,EAAUn2E,OAAO,YAAauwB,EAAY,CAC3C,GACA,CACDs/C,EACAwR,EACA5M,EACA+M,EACAG,EACA/B,EACAtzB,KAIAj/C,EAAAA,EAAAA,MAACm1E,EAAAA,IAAgB,CACfr6C,SAAUi5C,EACVpxC,WAAWmxC,GAAiBD,GAAcE,EAAiC,WAAf,aAC5Dr8E,MAAO08E,EAAqB,mBAAgB/6E,EAC5C4G,UAAWo4D,IAAW,CAAE,mCAAoC0b,IAAmBt2E,SAAA,CAE9E+1E,GAAoB90E,KAAK9L,IACxB,MAAMwiF,EAAW5S,IAAe5vE,EAAKw/E,YAAYlgF,IAAMU,EAAK6gF,WAAWt6E,MAAM27E,GAASA,EAAK5iF,KAAOswE,IAC5F6S,EAAgBd,GAAkCa,EAExD,OACE/3E,EAAAA,EAAAA,KAACi4E,EAAAA,IAAW,CAEVlD,YAAax/E,EAAKw/E,YAClBgD,WAAYA,EACZpxE,UAAWqxE,EACXE,WAAY3iF,EAAK6gF,UACjB+B,WAAY5iF,EAAK8gF,eACjBnqB,SAAUyqB,EACVzxE,SAAU3P,EAAKw/E,YAAYlgF,KAAO0yE,GAAAA,GAAYC,OAASwP,EACvD/B,gBAAiBqB,GACjB8B,iBAAqC,IAApB1B,QAAmC16E,GAT/CzG,EAAKw/E,YAAYlgF,GAUtB,KAGNmL,EAAAA,EAAAA,KAACq4E,EAAAA,IAAc,CAACz1E,UAAWo4D,IAAW,CAAE,aAAc0b,MACrDW,EAAyBh2E,KAAK9L,IAC7ByK,EAAAA,EAAAA,KAACi4E,EAAAA,IAAW,CAEVlD,YAAax/E,EAAKw/E,YAClBgD,SAAU7C,EAAgB3/E,EAAKw/E,YAAYlgF,IAC3CmhF,WAAYzgF,EAAKygF,WACjBf,gBAAiB1/E,EAAK0/E,gBACtB/vE,SAAU3P,EAAKy/E,WACf9oB,SAAU2qB,GANLthF,EAAKw/E,YAAYlgF,MASzByiF,EAAwBj2E,KAAK9L,IAC5ByK,EAAAA,EAAAA,KAACi4E,EAAAA,IAAW,CAEVlD,YAAax/E,EAAKw/E,YAClBgD,UAAU,EACV7yE,SAAU3P,EAAKy/E,WACfC,gBAAiB1/E,EAAK0/E,gBACtB/oB,SAAU0qB,GALLrhF,EAAKw/E,YAAYlgF,QAUhC,CC3JA,YCcA,SAASyjF,GAAiBh9E,GAAyD,IAAxD,OAAEikC,EAAM,KAAEg4B,EAAI,aAAEghB,GAAsCj9E,EAC/E,OACE0E,EAAAA,EAAAA,KAACsuD,EAAAA,IAAQ,CACP,cAAc,0BAAyB/uB,IACvC98B,MAAO88B,EACP09B,WAAW,SACXjhB,KAAM,EACNz6C,MAAOg2D,EACPrL,SAAWhzD,IACTq/E,EAAar/E,EAAEs1D,OAAOjtD,MAAOg+B,EAAO,GAI5C,CAMO,SAASi5C,GAAkBz8E,GAA8B,IAA7B,iBAAEiG,GAAyBjG,EAC5D,MAAM,yBAAEu7D,GAA6B9B,GAA2BxzD,IACzD+1C,EAAS0gC,GAAcz5E,EAAAA,SAAyB,IACjD05E,EAAyB15E,EAAAA,SAAc,IAAMgD,EAAiB6zD,yBAAyB,CAAC7zD,IACxF6zD,GAAwB5zD,EAAAA,EAAAA,GAAcy2E,EAAwB,CAAEx2E,gBAAiB,CAAC,cAExFlD,EAAAA,WAAgB,KAEd,MAAM25E,EAAoBA,KACxB,MAAM,QAAE5gC,IAAYkI,EAAAA,EAAAA,IAAyCj+C,GAC7Dy2E,EAAW1gC,EAAQ,EAKrB,OAFA95C,EAAAA,EAAM3J,KAAK,SAAUqkF,GACrBA,IACO,KACL16E,EAAAA,EAAM3I,OAAO,SAAUqjF,EAAkB,CAC1C,GACA,CAAC32E,IAEJ,MAAM42E,EAAgB55E,EAAAA,SAAc,KAClC,MAAMqC,EAAkB,CAAC,EAOzB,OANAw0D,EAAsBxsD,SAASnN,SAASzG,IACR,SAA1BA,EAAQwpD,eAA4BlH,EAAQhqB,SAASt4B,EAAQ8pC,UAC/Dl+B,EAAI5L,EAAQ8pC,SAAUuhB,EAAAA,EAAAA,IAAmBrrD,GAC3C,IAGK4L,CAAG,GACT,CAACw0D,EAAsBxsD,SAAU0uC,IAEpC,OACE/3C,EAAAA,EAAAA,KAAA,OAAK4C,UAAU,YAAWxC,SACvB23C,EAAQ12C,KAAKk+B,IACZv/B,EAAAA,EAAAA,KAACs4E,GAAiB,CAEhB/4C,OAAQA,EACRg4B,KAAMqhB,EAAcr5C,IAAW,GAC/Bg5C,aAAcjhB,GAHT/3B,MAQf,CCnEO,SAASs5C,GAAmBv9E,GAA2C,IAA1C,MAAEhB,EAAK,iBAAE0H,GAA+B1G,EAC1E,MAAM2nD,EAAS3oD,EAAM4qD,SAAS,QACxB4zB,EAAcx+E,EAAM4qD,SAAS,aAC7B6zB,GAAiB91B,IAAW61B,EAElC,OACEn2E,EAAAA,EAAAA,MAACovD,EAAAA,IAAM,CACLC,aAAW,EACX,aAAW,cACXpvD,UAAU,OACVtI,MAAOA,EACP43D,UAAU,EACV8mB,WAAW,EACX/mB,OAAO,EAAM7xD,SAAA,EAEbJ,EAAAA,EAAAA,KAACqyD,EAAAA,IAAY,CAAAjyD,SAAC,WACdJ,EAAAA,EAAAA,KAACuyD,EAAAA,IAAU,CAAAnyD,UAAG24E,IAAiB/4E,EAAAA,EAAAA,KAACw4E,GAAkB,CAACx2E,iBAAkBA,QAG3E,CCUO,SAAS4iD,GAAkB7oD,GAMV,IANW,MACjCzB,EAAK,SACL2+E,EAAQ,SACRC,EAAQ,wBACRC,GAA0B,EAAK,QAC/BphC,GACoBh8C,EACpB,MAAMq9E,EAvCiB99E,KAMnB,IANoB,wBACxB69E,EAAuB,QACvBphC,GAIDz8C,EACC,OAAI69E,EACK,CACLhiF,MAAO,iCACP+9D,SACEvyD,EAAAA,EAAAA,MAAAiC,EAAAA,SAAA,CAAAxE,SAAA,CAAE,qCACiCJ,EAAAA,EAAAA,KAAA,KAAAI,SAAG,cAAa,qFAC3BJ,EAAAA,EAAAA,KAAA,KAAAI,SAAI23C,EAAQvgD,KAAK,QAAU,QAKlD,CACLL,MAAO,uBACP+9D,QAAU,oKACX,EAkBqBmkB,CAAiB,CAAEF,0BAAyBphC,YAElE,OACE/3C,EAAAA,EAAAA,KAACs5E,EAAAA,IAA2B,CAC1Bh/E,MAAOA,EACP,aAAY8+E,EAAcjiF,MAC1BA,MAAOiiF,EAAcjiF,MACrB0tD,SACEliD,EAAAA,EAAAA,MAAAiC,EAAAA,SAAA,CAAAxE,SAAA,EACEJ,EAAAA,EAAAA,KAACC,EAAAA,IAAM,CAAC,cAAY,6BAA6B6kD,GAAIC,EAAAA,GAAexlD,QAAS25E,EAAS94E,SAAC,YAGvFJ,EAAAA,EAAAA,KAACC,EAAAA,IAAM,CAAC,cAAY,6BAA6BV,QAAS05E,EAAU5+E,MAAM,MAAK+F,SAAC,cAInFA,SAEAg5E,EAAclkB,SAGrB,C,4BCzDe,SAASqkB,GAAUj+E,GAA2C,IAA1C,WAAE6pE,EAAU,QAAE5lE,GAA0BjE,EACzE,OACE0E,EAAAA,EAAAA,KAACC,EAAAA,IAAM,CAAC8C,WAAW,SAASxD,QAASA,EAASiE,QAAQ,EAAMnJ,MAAM,kBAAkB8I,KAAK,SAAQ/C,UAC/FJ,EAAAA,EAAAA,KAACgD,EAAAA,IAAI,CAACjM,KAAMk/E,GAAa9Q,GAAYvZ,KAAMzwD,MAAO,GAAIyH,UAAU,cAGtE,CCHe,SAAS42E,GAAal+E,GAKd,IALe,WACpC6pE,EAAU,mBACVwR,EAAkB,qBAClBC,KACG5hF,GACgBsG,EACnB,MAAOm+E,EAAkBC,GAAuB16E,EAAAA,UAAe,IACxD26E,EAAiBC,IAAsBC,EAAAA,GAAAA,OACvCC,EAAsBC,GAA2B/6E,EAAAA,SAAmC,MAG3FA,EAAAA,WAAgB,KACd+6E,EAAwBx7E,SAAS2lD,eAAe81B,GAAAA,GAAuB,GACtE,IAEH,MAAMC,EAAyBj7E,EAAAA,aAC7B,CAACk7E,EAA0Bh9E,KAGzB,GAFAy5E,EAAmBuD,EAAah9E,GAEhB,UAAZA,EAAqB,OAAOw8E,GAAoB,EAAM,GAE5D,CAAC/C,IAIGwD,EAAan7E,EAAAA,OAA6B,MAChDA,EAAAA,WAAgB,KACd,GAAKy6E,EAYL,OAHAl7E,SAASuB,iBAAiB,YAAas6E,GACvC77E,SAASuB,iBAAiB,aAAcs6E,GAEjC,KACL77E,SAASwB,oBAAoB,YAAaq6E,GAC1C77E,SAASwB,oBAAoB,aAAcq6E,EAAmB,EAZhE,SAASA,EAAmBjb,GAE1B,MAAMkb,EAAa97E,SAASugE,cAAc,+BACtCqb,EAAW3nF,SAAS0tE,SAASf,EAAM3Q,SAAmB6rB,GAAYna,SAASf,EAAM3Q,SACrFkrB,GAAoB,EACtB,CAQC,GACA,CAACD,IAOJ,OAAKK,EAEE5a,EAAAA,cACLv8D,EAAAA,EAAAA,MAAAiC,EAAAA,SAAA,CAAAxE,SAAA,EACEJ,EAAAA,EAAAA,KAAA,OACE84D,IAAKqhB,EACLv3E,UAAW0hD,IAAW,oBAAqB,CACzC,iCAAkCm1B,IACjCr5E,UAEHJ,EAAAA,EAAAA,KAACu2E,GAAO,CACNG,iBAAe,EACfvR,WAAYA,EACZwR,mBAAoBsD,EACpBrD,qBAnB0B0D,IAChC1D,IAAuB0D,GACvBZ,GAAoB,EAAM,KAkBhB1kF,MAGP2kF,EAAgBY,IAAIC,GAAAA,IAAwBrV,IAAeoC,GAAAA,GAAYC,OACtExnE,EAAAA,EAAAA,KAACC,EAAAA,IAAM,CACLC,YAAY,OACZiD,KAAK,SACL5D,QAASA,KACPm6E,GAAoB,GACpBE,GAAoBa,IAClBA,EAAOC,OAAOF,GAAAA,GACPC,IACP,EACFr6E,SACH,UAIDJ,EAAAA,EAAAA,KAACu5E,GAAU,CACTpU,WAAYA,EACZ5lE,QAASA,KACPm6E,GAAoB,EAAK,OAKjCI,GAzCgC,IA2CpC,CCjGO,SAASa,GAAsBr/E,GAAkD,IAAjD,iBAAE0G,GAA6C1G,EACpF,MAAMs9D,EAAiC55D,EAAAA,SACrC,IAAMgD,EAAiB6zD,yBACvB,CAAC7zD,KAEG,cAAEm1E,IAAkBl1E,EAAAA,EAAAA,GAAc22D,EAAgC,CAAE12D,gBAAiB,CAAC,oBACrFggE,EAAWkM,GAAgBpvE,EAAAA,UAAe,GAqCjD,OAnCAA,EAAAA,WAAgB,KACd,GAAIm4E,IAAkB5gB,EAAAA,GAAc0C,IAClC,OAGF,IAAI2hB,EAAsC,KAC1C,MAAMC,EAAe1D,IAAkB5gB,EAAAA,GAAcG,MAErDkkB,EAAuBphF,OAAOwX,YAC5B,KACEo9D,EAAayM,EAAa,GAE5BA,EAAe,EAAI,KAGrB,MAAMC,EAA+B3b,IACnC,GAAIgY,IAAkB5gB,EAAAA,GAAcG,MAClC,OAGF,MAAMxB,EAAW,4FAEjB,OADAiK,EAAM4b,YAAc7lB,EACbA,CAAO,EAKhB,OAFA17D,OAAOsG,iBAAiB,eAAgBg7E,GAEjC,KACLthF,OAAOuG,oBAAoB,eAAgB+6E,GACvCF,GACF7kB,aAAa6kB,EACf,CACD,GACA,CAACzD,IAOG,IACT,CC9CA,MAAM6D,IAAc9yE,EAAAA,EAAAA,MAEb,SAAS+yE,GAAuB3/E,GAAsE,IAAnE0G,iBAAkBk5E,EAAyB,YAAEC,GAAoB7/E,EACzG,MAAM0G,GAAmBC,EAAAA,EAAAA,GAAci5E,EAA2B,CAChEh5E,gBAAiB,CAAC,WAEd,qBAAEu1D,GAAyBjC,GAA2BxzD,GAE5D,OAAKA,EAAiBi8D,UAKpBt7D,EAAAA,EAAAA,MAAA,OAAKC,UAAU,oCAAmCxC,SAAA,EAC9C46E,KAAeh7E,EAAAA,EAAAA,KAAA,OAAAI,SAAK,WACtBJ,EAAAA,EAAAA,KAAA,OAAK4C,UAAU,0BAAyBxC,UACtCJ,EAAAA,EAAAA,KAACsuD,EAAAA,IAAQ,CACPwK,IAAKqiB,EACLlzE,SAAU+yE,QAAch/E,EAAY,OACpCihE,WAAW,eACX1O,YAAY,mCACZ,cAAY,qBACZhtD,MAAOS,EAAiBmD,MAAMoyD,MAAQ,GACtCrL,SAAWhzD,IACTu+D,EAAqBv+D,EAAEs1D,OAAOjtD,MAAM,SAfrC,IAqBX,C,gBC/BO,SAAS65E,KACd,MAAMC,EAAuB98E,SAAS+8E,uBAAuB,oBAG7D,OAFiC9nF,MAAMk1B,KAAK2yD,EAG9C,CAEA,SAASE,GAAe3lF,GACtB,MAAM4lF,EAAaj9E,SAAS2lD,eAAgB,QAAOtuD,KACnD,OAAO4lF,GAAY9+E,KAAO,IAC5B,CAEO,SAAS++E,GAA6BngF,GAAmE,IAAlE,YAAEykE,EAAW,YAAEgP,GAAiDzzE,EAC5G,MAAM83D,GAASC,EAAAA,EAAAA,OACTpQ,EAASmQ,EAAOlO,SAAS,SACxBw2B,EAAcC,GAAmB38E,EAAAA,SAAe,CACrD48E,UAAU,EACVC,YAAa,KACbzzE,UAAW,GACXm3B,OAAQ,MAEHu8C,IAAsB7sE,EAAAA,GAAAA,GAAe,IACvC8sE,GAAAA,EACH3sE,iBAAkB6zC,IAEd+4B,EAAgBF,GAAoBpjE,QA+B1C,OA7BA1Z,EAAAA,WAAgB,KACd,MAAMi9E,EAA2Bb,KAC3Bc,EAAgB/c,IACpB,MAAM,MAAEvpE,EAAK,OAAE2pC,EAAM,UAAEn3B,GAAe+2D,EAAMpS,cAA8BovB,QAC1E,GAAIvmF,GAAS2pC,GAAUn3B,EAAW,CAChC,MAAMg0E,EAAW3kE,OAAOq5B,SAASl7C,GACjC+lF,EAAgB,CACdp8C,SACAn3B,YACAwzE,SAAuB,IAAbQ,EACVP,YAAaO,EAAW,EAAIb,GAAea,GAAY,OAEzDhpB,EAAO5qD,MACT,GASF,OANIu3D,GACFkc,EAAyB//E,SAASrG,IAChCA,EAAGiK,iBAAiB,QAASo8E,EAAa,IAIvC,KACLD,EAAyB//E,SAASrG,IAChCA,EAAGkK,oBAAoB,QAASm8E,EAAa,GAC7C,CACH,GACA,CAAC9oB,EAAQ2M,IAELic,GAAgBh8E,EAAAA,EAAAA,KAACg8E,EAAa,CAAC1hF,MAAO84D,EAAQzrC,OAAQ+zD,EAAc3M,YAAaA,IAAkB,IAC5G,C,gBCzDO,IAAKsN,GAA+B,SAA/BA,GAA+B,OAA/BA,EAAAA,EAA+B,iBAA/BA,EAAAA,EAA+B,uBAA/BA,EAAAA,EAA+B,qBAA/BA,EAAAA,EAA+B,mBAA/BA,CAA+B,MAYpC,SAASC,GAAehhF,GAA8C,IAA7C,MAAEhB,EAAK,eAAEiiF,GAAkCjhF,EACzE,OACEqH,EAAAA,EAAAA,MAACovD,EAAAA,IAAM,CACLz3D,MAAOA,EACP,aAAW,wGACXsI,UAAU,OACVsvD,UAAUlyD,EAAAA,EAAAA,KAAA,OAAK6lB,YAAaA,IAAM02D,EAAeF,GAAgCG,UAAYp8E,SAAA,EAE7FJ,EAAAA,EAAAA,KAACqyD,EAAAA,IAAY,CAACC,aAAcA,IAAMiqB,EAAeF,GAAgCG,QAAQp8E,SAAC,qCAG1FJ,EAAAA,EAAAA,KAACuyD,EAAAA,IAAU,CAAAnyD,UACTuC,EAAAA,EAAAA,MAAA,OAAKC,UAAU,YAAWxC,SAAA,EACxBJ,EAAAA,EAAAA,KAACkD,EAAAA,IAAS,CAAA9C,SAAC,yEACXuC,EAAAA,EAAAA,MAACO,EAAAA,IAAS,CAAA9C,SAAA,EACRJ,EAAAA,EAAAA,KAAA,UAAAI,SAAQ,sBACRJ,EAAAA,EAAAA,KAAA,SAAM,uHAIR2C,EAAAA,EAAAA,MAACO,EAAAA,IAAS,CAAA9C,SAAA,EACRJ,EAAAA,EAAAA,KAAA,UAAAI,SAAQ,sBACRJ,EAAAA,EAAAA,KAAA,SAAM,+LAIR2C,EAAAA,EAAAA,MAACO,EAAAA,IAAS,CAAA9C,SAAA,EACRJ,EAAAA,EAAAA,KAAA,UAAAI,SAAQ,gBACRJ,EAAAA,EAAAA,KAAA,SAAM,mEAKZ2C,EAAAA,EAAAA,MAACmwD,EAAAA,IAAY,CAAA1yD,SAAA,EACXJ,EAAAA,EAAAA,KAACC,EAAAA,IAAM,CACL,cAAY,+BACZ6kD,GAAIC,EAAAA,GACJxlD,QAASA,IAAMg9E,EAAeF,GAAgCI,UAAUr8E,SACzE,aAGDJ,EAAAA,EAAAA,KAACC,EAAAA,IAAM,CACL,cAAY,4BACZ6kD,GAAIC,EAAAA,GACJxlD,QAASA,IAAMg9E,EAAeF,GAAgCK,OAAOt8E,SACtE,aAGDJ,EAAAA,EAAAA,KAACC,EAAAA,IAAM,CACL,cAAY,8BACZ6kD,GAAIC,EAAAA,GACJxlD,QAASA,IAAMg9E,EAAeF,GAAgCM,SAASv8E,SACxE,oBAMT,CCtDA,MAAMw8E,GAAoCC,IACxC,OAAQA,GACN,KAAKj/B,EAAAA,GAAyBl7C,EAC5B,OAAOsH,EAAAA,GAAiBO,UAC1B,KAAKqzC,EAAAA,GAAyB6N,GAC5B,OAAOzhD,EAAAA,GAAiBK,kBAC1B,KAAKuzC,EAAAA,GAAyB4N,GAC5B,OAAOxhD,EAAAA,GAAiBG,WAC1B,KAAKyzC,EAAAA,GAAyB2N,EAC5B,OAAOvhD,EAAAA,GAAiBS,UAC1B,KAAKmzC,EAAAA,GAAyBxzB,EAC5B,OAAOpgB,EAAAA,GAAiBgvC,UAC1B,KAAK4E,EAAAA,GAAyBx9B,EAC9B,KAAKw9B,EAAAA,GAAyByN,GAC5B,OAAOrhD,EAAAA,GAAiBC,YAC1B,QACE,OACE6yE,EAAAA,GAAAA,IAAoCtjF,OAAO8S,gBAAgBywE,IAAIjzE,OAAS,OAASE,EAAAA,GAAiBC,YAExG,EAGI+yE,GAAuBh7E,KAC3BwL,EAAAA,EAAAA,KAAiB,CAAEC,cAAc,IACjC,MAAMjP,GAAWkD,EAAAA,GAAAA,MACXC,GAAWC,EAAAA,GAAAA,OACX,kBAAEyzD,GAAsB3B,KACxBN,GAASC,EAAAA,EAAAA,OACT4pB,EAAoB7pB,EAAOlO,SAAS,QAEpC+U,EAAcj4D,GAAkBgD,6BAA+Bq7B,EAAAA,GAA2BkiB,UAC1FstB,EAAc7tE,GAAkBgD,6BAA+Bq7B,EAAAA,GAA2ByS,UAC1FmhC,EAA2B,CAC/B5zC,EAAAA,GAA2BmiB,YAC3BniB,EAAAA,GAA2BoiB,UAC3BpiB,EAAAA,GAA2BqiB,YAC3B30B,SAAS/rB,GAAkBgD,4BAE7BhG,EAAAA,WAAgB,KACV6wE,GACFnyC,EAAAA,GAAMi+B,UACJ,YACC,KAAGrW,EAAAA,EAAAA,KAAkB,KAAKxjD,EAAAA,EAAAA,KAAkBtD,EAASuD,QAAS8T,OAAG7Z,EAAW+H,cAAU/H,MACvFkhF,GAAAA,EAAY,IAAItjF,KAAQ,CAAE69C,OAAQ,IAEtC,GACC,CAACo4B,EAAarxE,EAASuD,SAE1B/C,EAAAA,WAAgB,KACd,MAAM0pD,GAAqB5mD,EAAAA,EAAAA,KAAgDtD,EAASuD,QAIhFC,GAAoB0mD,EAAmB7yC,IAAM7T,EAAiBmD,MAAMtQ,IACtE2E,OAAOgF,SAAS4R,QAClB,GAGC,CAAC5R,EAASuD,OAAQC,GAAkBmD,MAAMtQ,KAE7C,MAAMsoF,EAAoBn+E,EAAAA,aAAkB,KAC1C,IAAKgD,EAAkB,OAEvB,MAAMooD,GAAgBtoD,EAAAA,EAAAA,KAAgDtD,EAASuD,QAEzEq7E,EAAWhzB,EAAuC2P,IAAM,MAC9DsjB,EAAAA,EAAAA,IAAiB,CACf/zE,KAAMszE,GAAiCQ,GACvCp7E,qBAGE6tE,GAAe7tE,EAAiBa,SAAYunD,EAAwC1nD,GACtFV,EAAiB8B,iBAAiB,CAAEjB,OAASunD,EAAwC1nD,IAGvFV,EAAiBoE,eAAelK,SAAQ,CAAC6B,EAAYiK,KACnD,MAAMs1E,EAAYlzB,EAAc1zB,EAAEhJ,MAAM,KAAK1lB,IAAe,KACtDu1E,EAAenzB,EAAchgC,GAAGsD,MAAM,KAAK1lB,IAAe,KAC1Dw1E,EAAepzB,EAAcr5C,GAAG2c,MAAM,KAAK1lB,IAAe,KAC1Dy1D,EAAkB6f,GAAWlkD,cAMnC,IAAI5yB,GAAai3E,EAAAA,EAAAA,IAAchgB,GAC3Bz7D,EAAiBgD,6BAA+Bq7B,EAAAA,GAA2ByS,YAC7EtsC,EAAazI,EAAWyI,YAG1B,MAAMk3E,EAAiB,CACrBl3E,aACA+4B,QAAQo+C,EAAAA,GAAAA,IAA0Bn3E,EAAYi3D,GAC9Cr1D,UAAWm1E,EACX11E,UAAW21E,GAGT5mF,OAAOuK,QAAQu8E,GAAgB5hF,MAAKR,IAAA,IAAEgG,EAAKC,GAAMjG,EAAA,OAAKyC,EAAWuD,KAAwBC,CAAK,KAChGxD,EAAW6/E,wBAAwBF,EACrC,GACA,GACD,CAAC17E,EAAkBxD,EAASuD,OAAQ8tE,IAEvC7wE,EAAAA,WAAgB,KACd,MAAMorD,GAAgBtoD,EAAAA,EAAAA,KAAgDtD,EAASuD,QAE/E,GACGC,GACAooD,EAAchgC,GACdggC,EAAc1zB,IACbujC,GAAe4V,GAAeoE,GAJlC,CA0BA,GAJIjyE,EAAiBmD,MAAMtQ,IAAMooF,GAC/B7pB,EAAO9P,QAGJ8G,EAAcv0C,GAAK7T,EAAiBmD,MAAMtQ,GAAI,CACjD,MAAMyoF,EAAYlzB,EAAc1zB,EAAEhJ,MAAM,KAClCy4B,EAAenkD,EAClBoE,eACAyiD,OAAM,CAACxrD,EAAOwY,IAAMxY,EAAM2hD,sBAAwBs+B,EAAUznE,KAE/D,GAAIswC,GAAgB3sD,OAAO8S,eAAeC,gBAAkBvK,EAAiBolD,yBAE3E,YADAgM,EAAO5qD,OAGJxG,EAAiBolD,0BAA6BjB,IACjD1E,EAAAA,EAAAA,IAA8B,CAAEz/C,mBAAkB0/C,cAAe,mBAEnE1/C,EAAiB67E,UACnB,CACAV,GApBA,MAfO/yB,EAAchgC,GAAK6vC,GACtBt4D,EACE,CACEI,OAAS,KAAGujD,EAAAA,EAAAA,KAAkB,IACzB8E,EACHhgC,EAAG5wB,OAAO8S,eAAewxE,eAAiBniD,EAAAA,GAAUlc,EACpD1O,EAAGvX,OAAO8S,eAAeyxE,sBAG7B,CACE/wE,SAAS,GAyBE,GAElB,CACDxO,EAASuD,OACTJ,EACAK,EACAi4D,EACA4V,EACAoE,EACAkJ,IAGF,MAAMa,EAAkBh/E,EAAAA,aACtB3D,UACE,GAAK2G,EACL,GAAIrK,IAAW0kF,GAAgCG,OAA/C,CAIA,OAAQ7kF,GACN,KAAK0kF,GAAgCK,OACnCj7B,EAAAA,EAAAA,IAA8B,CAC5Bz/C,mBACA0/C,cAAe,qBAEjB,MAEF,KAAK26B,GAAgCI,SAAU,CAC7C,MAAM,QAAE1kC,IAAYkI,EAAAA,EAAAA,IAAyCj+C,SACvDqzD,EAAkB,CAAEtd,UAASud,iBAAiBuC,EAAAA,GAAAA,KAAQomB,EAAAA,EAAAA,MAAWrkF,KAAKC,SAC5E,KACF,CACA,KAAKwiF,GAAgCM,SACnCl7B,EAAAA,EAAAA,IAA8B,CAC5Bz/C,mBACA0/C,cAAe,mBAOrB1/C,EAAiB67E,WACjBV,GAzBA,MAFEx7E,GAAU,EA2BO,GAErB,CAACK,EAAkBm7E,EAAmB9nB,EAAmB1zD,IAG3D,MAAO,CACLyxD,SACA4qB,kBACD,E,gCCxJH,MAAME,WAAiCl/E,EAAAA,UAErC3J,MACAooC,SAAWotB,QAAQntB,EAAAA,GAAMD,UAAS,IAClC5yB,OACAszE,yBACAC,+BAAiC,IAAIC,gBAErCvnF,WAAAA,CAAYH,GACViH,MAAMjH,GAENhD,KAAK0B,MAAQsB,EAAMqL,iBACnB,MAAM2lB,EAAShxB,EAAMgxB,OAErBh0B,KAAKkX,OAAS,GACd,IAAK,MAAMF,KAAegd,EAAO9c,OAAQ,CACvC,MAAMyzE,EAA8CzjE,IAAM,CAAC,EAAGlQ,GAE9D2zE,EAAgB/2D,aAAe5zB,KAAK0B,aAC7BipF,EAAgBt1E,MACW,MAA9Bs1E,EAAgBh2C,aAClBg2C,EAAgBh2C,WAAa30C,KAAK0B,MAAMmtE,mBAEP,MAA/B8b,EAAgB3c,cAClB2c,EAAgB3c,aAAc,GAE3B2c,EAAgBz2E,YACnBy2E,EAAgBz2E,UAAY,MAE9By2E,EAAgBC,qBAAuB5qF,KAAK0B,MAAMkpF,qBAClDD,EAAgB/3B,YAAa,EAC7B,MAAMlxD,EAAQ1B,KAAK0B,MAAMwV,SAASwsD,OAAmBinB,GACrD3qF,KAAKkX,OAAO3V,KAAK,CAAEG,QAAOsyB,OAAQhd,GACpC,CACAhX,KAAK0B,MAAMguC,gBAAgB,cAAe1vC,KAAK0B,MAAMwV,SAASurC,SAE9DziD,KAAK2G,MAAQ,CACX2jE,SAAUtqE,KAAK0B,MAAM4oE,SACrBH,QAASnqE,KAAK0B,MAAMyoE,QACpBj7D,OAAQlP,KAAK0B,MAAMwN,OACnB+lE,uBAAwB,KACxBzD,WAAYoC,GAAAA,GAAYC,MACxBpB,qBAAqB,EACrBoY,qBAAqB,EACrBtJ,gBAAiB,CACf,CAACC,GAAAA,GAAeI,wBAAwB,EACxC,CAACJ,GAAAA,GAAeC,kBAAmBzhF,KAAK8qF,qCACxC,CAACtJ,GAAAA,GAAeK,eAAe,EAC/B,CAACL,GAAAA,GAAeM,eAAe,GAGrC,CAEAhX,iBAAAA,GACE,GAAI9qE,KAAK2G,MAAM2jE,SAAU,CACvB,MAAMygB,EAAS,GACfllF,OAAOsG,iBAAiB,SAAU5G,IAChC,MAAMg1D,EAAWv6D,KAAK0B,MAAMspF,uBAC5B,GAAIzlF,EAAE0lF,UAAYF,GAAUxwB,EAAU,CACpC,MAAMz4D,EAAU+E,EAAAA,EAAawrB,gBAA8B,WAAYkoC,EAAS5nC,WAChF,GAAI7wB,EAAS,CACX,MAAM4iE,EAAc5iE,EAAQ4wB,OAC5B5wB,EAAQ4xD,eAAe,CAAEmR,UAAWC,EAAAA,GAAyBC,SAC7DL,EAAYN,mBACd,CACF,IAEJ,CAEIpkE,KAAK8pC,WACP9pC,KAAK0B,MAAM0O,SAASu0B,cAAcn1B,KAAOxP,KAAK0B,MAAM0O,SAASu0B,cAAcumD,WAG7ElrF,KAAK07E,gBAEL17E,KAAK0B,MAAMf,KAAK,SAAUX,KAAK07E,eAC/B17E,KAAK0B,MAAMwV,SAASvW,KAAK,UAAWX,KAAKmrF,gBAEzCnrF,KAAKorF,qBACLvlF,OAAOsG,iBAAiB,SAAUnM,KAAKqrF,gBACvCxlF,OAAOsG,iBAAiB,oBAAqBnM,KAAKsrF,yBAE9CtrF,KAAK8pC,WACP9pC,KAAKurF,2BACL1lF,OAAOsG,iBAAiB,WAAYnM,KAAKurF,0BAE7C,CAEAzP,kBAAAA,CAAmBjqE,GACbA,EAAUL,OAASxR,KAAKgD,MAAMwO,OAC5BxR,KAAK0B,MAAM2P,6BAA+Bq7B,EAAAA,GAA2ByS,WACvEn/C,KAAKqrF,iBAEPzgF,SAASugE,cAAc,0BAA0Bj/D,UAGnDlM,KAAKorF,oBACP,CAEApgB,oBAAAA,GACEhrE,KAAKyqF,+BAA+Be,QACpCxrF,KAAK0B,MAAMC,OAAO,SAAU3B,KAAK07E,eAEjC71E,OAAOuG,oBAAoB,SAAUpM,KAAKqrF,gBAC1CxlF,OAAOuG,oBAAoB,oBAAqBpM,KAAKsrF,yBAEjDtrF,KAAK8pC,UACPjkC,OAAOuG,oBAAoB,WAAYpM,KAAKurF,0BAG9CnpB,aAAapiE,KAAKwqF,0BAClBxqF,KAAKyrF,gBAAgBxtB,SACrBj+D,KAAK0B,MAAMgyD,gBACb,CAEAo3B,mCAAqCA,KACnC,IAAIY,GAAmB,EASvB,OARI1pB,EAAAA,EAAAA,IAA0ChiE,KAAK0B,cAC2B2G,IAAxExC,OAAO8S,eAAegzE,aAAanK,GAAAA,GAAeC,kBACpDiK,EAAmB7lF,OAAO8S,eAAegzE,WAAWnK,GAAAA,GAAeC,kBAEnEzhF,KAAK4rF,kCAGT5rF,KAAK0B,MAAMguC,gBAAgB,2BAA4Bg8C,GAChDA,CAAgB,EAGzBE,+BAAiClkF,UAC/B,MAAMmkF,EAAuBn7C,IAC3B1wC,KAAK0B,MAAMguC,gBAAgB,2BAA4BgB,GACvD1wC,KAAK64E,UAAU90E,IAAS,CACtBw9E,gBAAiB,IACZx9E,EAAUw9E,gBACb,CAACC,GAAAA,GAAeC,kBAAmB/wC,MAEpC,EAGL,IACE1wC,KAAKyqF,+BAA+Be,QACpCxrF,KAAKyqF,+BAAiC,IAAIC,gBAC1C,MAAMppB,QAAiBnB,EAAAA,EAAAA,IAAS,CAC9Bt1D,SAAU,wBACVg2D,YAAkBx4D,IAAVuF,EAAsB,OAAS,MACvC7B,UACY1D,IAAVuF,EACI,IAAIk+E,gBAAgB,CAAEC,YAAa/kE,KAAKC,UAAU,CAAE,CAACu6D,GAAAA,GAAeC,kBAAmB7zE,WACvFvF,EACNg4D,mBAAoB,CAAC,KACrBjM,gBAAiBp0D,KAAKyqF,sCAGVpiF,IAAVuF,QAAuEvF,IAAhDi5D,IAAWkgB,GAAAA,GAAeC,mBACnDoK,EAAoBvqB,EAASkgB,GAAAA,GAAeC,kBAEhD,CAAE,WACcp5E,IAAVuF,GACFi+E,GAAqBj+E,EAEzB,GAGF09E,wBAA0BA,KACxBtrF,KAAKwqF,yBAA2B3kF,OAAOwX,YAAW,KAChDrd,KAAKorF,qBACDprF,KAAKgD,MAAMk9E,cACblgF,KAAKgsF,cACP,GACA,EAGJX,eAAiBA,KACfrrF,KAAKorF,qBAEDprF,KAAKgD,MAAMk9E,cACblgF,KAAKyrF,iBACP,EAGFO,aAAeA,KACb,MAAMC,GAAwC7L,EAAAA,EAAAA,IAAoBpgF,KAAK0B,MAAM42C,oBAC7Et4C,KAAK0B,MAAMyO,iBAAiB87E,EAAW,EAGzCR,gBAAkBS,IAASlsF,KAAKgsF,aAAc,KAE9CZ,kBAAAA,GAGE,MAAMe,EAAyBnsF,KAAK0B,MAAM8F,MAAQ,IAAM3B,OAAOumF,YAAcvmF,OAAOumF,WAAa,IAC7FD,IAA2BnsF,KAAK2G,MAAMkkF,qBACxC7qF,KAAK64E,SAAS,CACZgS,oBAAqBsB,GAG3B,CAEAZ,yBAA2BA,MACpB,aAAac,KAAKxmF,OAAOgF,SAASqO,YAAa5N,EAAAA,EAAAA,OAA2D,IAAlCtL,KAAKssF,yBAChFtsF,KAAK2G,OAAO8rE,qBAAuBzyE,KAAK64E,SAAS,CAAEpG,qBAAqB,KAEvEzyE,KAAK2G,OAAO8rE,qBAAuBzyE,KAAK64E,SAAS,CAAEpG,qBAAqB,GAC3E,EAGF6Z,uBAAyBA,IAInBzmF,OAAO0mF,gBAAkBvsF,KAAK8pC,SACzBjkC,OAAO0mF,eAAep1E,MAEtB,EAIXmvE,uBAA0B9U,IACnBxxE,KAAK0B,MAAMmyB,sBACd7zB,KAAK64E,SAAS,CAAErH,cAClB,EAGFgb,oBAAuB7F,IACrB,OAAQA,GACN,KAAK9F,GAAAA,GAAeC,QAClB9gF,KAAKgD,MAAMypF,gBAAgBC,SAC3B,MACF,KAAK7L,GAAAA,GAAeE,eACpB,KAAKF,GAAAA,GAAeG,wBAClBhhF,KAAKgD,MAAMysD,wBAAwB56C,OACnC,MACF,QACE,OACJ,EAGF83E,kCAAoCA,KAC9B3sF,KAAK0B,MAAMwgE,wBAAwBshB,gBAAkB5gB,EAAAA,GAAc0C,KACrEtlE,KAAKgD,MAAMwhE,6BAEbxkE,KAAK0B,MAAMssD,iBAAiBzlD,SAASzG,IACnC,GAAIA,EAAQmsD,YAAa,CACvBnsD,EAAQ4xD,eAAe,CAAEmR,UAAWC,EAAAA,GAAyBC,SAC7D,MAAM6nB,EAAkB5sF,KAAK0B,MAC1BwgE,wBACAxsD,SAAS7L,MAAKlC,IAAA,IAAC,UAAEoC,GAAWpC,EAAA,OAAKoC,IAAcjI,EAAQZ,EAAE,IACxD0rF,IACFA,EAAgB1hC,WAAa,UAEjC,KAEFlrD,KAAKgD,MAAMysD,wBAAwBE,MAAM,EAG3Ck9B,sBAAyBC,IACvB,MAAMC,EAAS,IAAK/sF,KAAK2G,MAAM46E,gBAAiB,CAACuL,IAAa9sF,KAAK2G,MAAM46E,gBAAgBuL,IAEzF,OAAQA,GACN,KAAKtL,GAAAA,GAAeK,aAClB7hF,KAAKsmF,uBAAuB1S,GAAAA,GAAYC,OACxC7zE,KAAKgtF,mBAAmBD,EAAOvL,GAAAA,GAAeK,eAC9C7hF,KAAKitF,mBAAmBF,GACxB,MACF,KAAKvL,GAAAA,GAAeC,iBAClBzhF,KAAK4rF,+BAA+BmB,EAAOvL,GAAAA,GAAeC,mBAC1DzhF,KAAK0B,MAAMguC,gBAAgB,2BAA4Bq9C,EAAOvL,GAAAA,GAAeC,mBAC7E,MACF,KAAKD,GAAAA,GAAeM,aAClB9hF,KAAKsmF,uBAAuB1S,GAAAA,GAAYC,OACxC7zE,KAAKitF,mBAAmBF,GACxB,MACF,KAAKvL,GAAAA,GAAeI,sBAClB5hF,KAAK0B,MAAMguC,gBAAgB,gCAAiCq9C,EAAOvL,GAAAA,GAAeI,yBACjC,IAAjDmL,EAAOvL,GAAAA,GAAeI,wBAAoC5hF,KAAKsmF,uBAAuB1S,GAAAA,GAAYC,OAMtG7zE,KAAK64E,SAAS,CAAE0I,gBAAiBwL,IACjClnF,OAAOkK,OAAO,QAAS,2BAA4B,CACjD25D,eAAgBqjB,EAAOD,GAAa,SAAW,UAC/C98E,YAAa88E,GACb,EAGJG,mBAAsB1L,IACpBvhF,KAAK0B,MAAMguC,gBACT,0BACG6xC,EAAgBC,GAAAA,GAAeK,gBAAkBN,EAAgBC,GAAAA,GAAeM,eACpF,EAGHkL,kBAAAA,CAAmBp/E,GACjB5N,KAAK0B,MAAMguC,gBAAgB,uBAAwB9hC,GACnD5N,KAAK0B,MAAM+Q,eAAelK,SAASmB,GAAUA,EAAMgmC,gBAAgB,uBAAwB9hC,IAC7F,CAEAs/E,aAAAA,CAAcC,GACZ,MAAM,WAAE3b,EAAU,gBAAE+P,GAAoBvhF,KAAK2G,MAC7C,OAAOwmF,EAAKC,kBACV/gF,EAAAA,EAAAA,KAACw5E,GAAa,CACZx3E,iBAAkBrO,KAAK0B,MACvB8vE,WAAYA,EACZwR,mBAAoBhjF,KAAKsmF,uBACzBrD,qBAAsBjjF,KAAKwsF,oBAC3BtJ,sBAAuBljF,KAAK6sF,sBAC5BtL,gBAAiBA,EACjB8B,iBAAkB9B,EAAgBC,GAAAA,GAAeK,eAAiBN,EAAgBC,GAAAA,GAAeM,iBAGnGz1E,EAAAA,EAAAA,KAACu2E,GAAO,CACNv0E,iBAAkBrO,KAAK0B,MACvB8vE,WAAYA,EACZwR,mBAAoBhjF,KAAKsmF,uBACzBrD,qBAAsBjjF,KAAKwsF,oBAC3BtJ,sBAAuBljF,KAAK6sF,sBAC5BtL,gBAAiBA,EACjB8B,iBAAkB9B,EAAgBC,GAAAA,GAAeK,eAAiBN,EAAgBC,GAAAA,GAAeM,iBAC7FqL,GAGV,CAEAtlE,MAAAA,GACE,MAAM,UAAEwlE,EAAS,QAAEC,GAAYttF,KAAKgD,MAAMgxB,QACpC,WAAEw9C,EAAU,SAAElH,EAAQ,QAAEH,EAAO,oBAAE0gB,GAAwB7qF,KAAK2G,MAC9D+jE,EAAUP,EAAQ/vC,SAASotB,EAAAA,GAAgBkjB,UAAY+c,KAA8BxnF,OAAS,EAC9F+Q,EAAcvD,EAAAA,GAAQzN,KAAK0B,MAAMwN,QACjCq+E,GAAmBn2B,EAAAA,EAAAA,IAAoBp3D,KAAK8pC,WAC5C,QAAEsa,IAAYkI,EAAAA,EAAAA,IAAyCtsD,KAAK0B,OAElE,GAAI2rF,EAAW,CACb,MAAMG,GAAmBC,EAAAA,EAAAA,IAAoB/gD,EAAAA,GAA2ByS,WACxE,OACEnwC,EAAAA,EAAAA,MAAAiC,EAAAA,SAAA,CAAAxE,SAAA,EACEuC,EAAAA,EAAAA,MAAA,OAAKC,UAAU,4BAA2BxC,SAAA,EACtC8gF,GAIAvtF,KAAKktF,cAAc,CACjBrK,WAAW,EACXC,cAAc,KAElBz2E,EAAAA,EAAAA,KAAC4kD,GAAkB,CACjBtqD,MAAO3G,KAAKgD,MAAMysD,wBAClB61B,SAAUtlF,KAAK2sF,kCACfnH,wBAAyBxlF,KAAKgD,MAAM8+D,iBACpC1d,QAASA,KAEX/3C,EAAAA,EAAAA,KAAC64E,GAAmB,CAACv+E,MAAO3G,KAAKgD,MAAMypF,gBAAiBp+E,iBAAkBrO,KAAK0B,SAC/E2K,EAAAA,EAAAA,KAACqhF,EAAAA,IAAS,CACRtvE,QAAM,EACNld,GAAIlB,KAAK0B,MAAM42C,mBACf,cAAY,mBACZ8P,QAASp3C,EAAYo3C,QACrBC,KAAMr3C,EAAYq3C,KAAK57C,SAEtBzM,KAAKkX,OAAOxJ,KAAI,CAAAtF,EAAoBnG,KAAK,IAAxB,MAAEP,EAAK,OAAEsyB,GAAQ5rB,EAAA,OACjCiE,EAAAA,EAAAA,KAAC/B,GAAK,CAEJm2E,YAAU,EACVpsE,WAAYpS,EACZmI,WAAY1I,EACZsyB,OAAQA,EACRonD,YAAap7E,KAAK0B,MAClB69E,YAAaoO,EAAAA,IACbnO,SAAUxuE,EAAYs3C,YAAYrmD,GAClCyzE,0BAA2B11E,KAAK01E,0BAChClE,WAAYA,EACZyD,uBAAwBj1E,KAAK2G,MAAMsuE,uBACnCxC,oBAAqBzyE,KAAK2G,MAAM8rE,oBAChCyN,aAAclgF,KAAKgD,MAAMk9E,cAZpBx+E,EAAMR,GAaX,OAGNmL,EAAAA,EAAAA,KAAC26E,GAAsB,CAAC34E,iBAAkBrO,KAAK0B,WAEhD6rF,GAAoBC,IACnBnhF,EAAAA,EAAAA,KAACuhF,GAAAA,EAAO,CAACC,eAAgB7tF,KAAKyrF,gBAAiB95C,UAAWr5B,GAAAA,EAAiBw1E,aAE5EP,GACCvtF,KAAKktF,cAAc,CACjBrK,WAAW,EACXC,cAAc,EACdsK,iBAAkBI,IAErBxtF,KAAKgD,MAAMwO,MAAMoyD,OAChBv3D,EAAAA,EAAAA,KAAA,OAAK4C,UAAU,6DAA4DxC,UACzEJ,EAAAA,EAAAA,KAAA,OAAK4C,UAAU,uEAAsExC,SAClFzM,KAAKgD,MAAMwO,KAAKoyD,WAM7B,CAEA,MAAMyjB,GAAc9yE,EAAAA,EAAAA,MACdw5E,EAAgBzjB,GAAYH,EAAQ/vC,SAASotB,EAAAA,GAAgB6iB,OAC7D2jB,GAAcjuC,EAAAA,EAAAA,IAAiB//C,KAAK0B,OAASqsF,IAAkBlD,EAAsBkD,EAErFE,EAAqBrjF,SAASugE,cAAc,yBAC5C+iB,EAAYluF,KAAKgD,MAAMwO,MAAMg2B,MACjCxnC,KAAK0B,MAAM2P,6BAA+Bq7B,EAAAA,GAA2BkiB,YACnEviD,EAAAA,EAAAA,KAAA,MAAI4C,UAAU,mBAAkBxC,SAAG,kBAAiBzM,KAAKgD,MAAMwO,KAAKg2B,SAGxE,OACEx4B,EAAAA,EAAAA,MAAAiC,EAAAA,SAAA,CAAAxE,SAAA,CACGwhF,EAAqB1iB,EAAAA,aAAsB2iB,EAAWD,GAAsBC,GAC7E7hF,EAAAA,EAAAA,KAACy7E,GAA6B,CAAC1b,cAAe1B,EAAS0Q,YAAap7E,KAAK0B,QACxEssF,IACC3hF,EAAAA,EAAAA,KAAA,OACEnL,GAAG,uBACH,oBAAmB2pF,EAAsB,EAAI,EAC7C57E,UAAWo4D,IAAW,CACpB,wBAAyBwjB,EACzB,8BAA+BA,IAAwBxD,EACvD,0CAA2CwD,GAAuBxD,IAEpE,cAAY,uBAAsB56E,SAEjCzM,KAAKktF,cAAc,CAClBpK,aAAc+H,EACdzH,oBAAoB,OAI1B/2E,EAAAA,EAAAA,KAAC4kD,GAAkB,CACjBtqD,MAAO3G,KAAKgD,MAAMysD,wBAClB61B,SAAUtlF,KAAK2sF,kCACfnH,wBAAyBxlF,KAAKgD,MAAM8+D,iBACpC1d,QAASA,KAEX/3C,EAAAA,EAAAA,KAACqhF,EAAAA,IAAS,CACRxsF,GAAIlB,KAAK0B,MAAM42C,mBACf,cAAY,mBACZ8P,QAASp3C,EAAYo3C,QACrBC,KAAMr3C,EAAYq3C,KAClBjqC,OAAQkvE,EAAQ7gF,SAEfzM,KAAKkX,OAAOxJ,KAAI,CAAAI,EAAoB7L,KAAK,IAAxB,MAAEP,EAAK,OAAEsyB,GAAQlmB,EAAA,OACjCzB,EAAAA,EAAAA,KAAC/B,GAAK,CAEJ+J,WAAYpS,EACZmI,WAAY1I,EACZsyB,OAAQA,EACRw9C,WAAYA,EACZ4J,YAAap7E,KAAK0B,MAClB++E,WAAY6M,EACZ5X,0BAA2B11E,KAAK01E,0BAChCT,uBAAwBj1E,KAAK2G,MAAMsuE,uBACnCxC,oBAAqBzyE,KAAK2G,MAAM8rE,oBAChCwJ,mBACE4O,EACI,IACE7qF,KAAKktF,cAAc,CACjBpK,cAAc,EACdM,oBAAoB,SAExB/6E,GAjBD3G,EAAMR,GAmBX,OAGNmL,EAAAA,EAAAA,KAAA,OAAK4C,UAAU,WACf5C,EAAAA,EAAAA,KAAA,OAAK4C,UAAU,UACf5C,EAAAA,EAAAA,KAAA,OAAK8J,MAAO,CAAEg4E,MAAO,UACpBnuF,KAAK0B,MAAM2P,6BAA+Bq7B,EAAAA,GAA2BkiB,YACpEviD,EAAAA,EAAAA,KAACi7E,GAAuB,CAACj5E,iBAAkBrO,KAAK0B,SAElD2K,EAAAA,EAAAA,KAAC26E,GAAsB,CAAC34E,iBAAkBrO,KAAK0B,UAGrD,CAEAg0E,0BAA6B9nE,IAC3B5N,KAAK64E,SAAS,CAAE5D,uBAAwBrnE,GAAQ,EAGlDwgF,YAAAA,GACE,MAAMl/E,EAASzB,EAAAA,GAAQzN,KAAK0B,MAAMwN,QAC5BgI,EAASlX,KAAK0B,MAAMwV,SAASlV,MACb,IAAlBkV,EAAOjX,SAIPiX,EAAOjX,OAASiP,EAAOk1B,MACzBpkC,KAAKquF,aAAan/E,EAAOk1B,OAChBltB,EAAOjX,OAASiP,EAAOk1B,OAChCpkC,KAAKsuF,UAAUp/E,EAAOk1B,MAAQltB,EAAOjX,QAGvCD,KAAK0B,MACFwV,SACAlV,MACAuG,SAAQ,CAACmB,EAAOzH,KACf,MAAOssF,EAAUC,EAAaC,EAAQC,GACpCx/E,EAAOo5C,YAAYrmD,GAChBoX,QAAQ,KAAM,IACd0gB,MAAM,KACNrsB,KAAKvJ,GAAQ2f,OAAOq5B,SAASh5C,MAAS,GACrCwqF,EAAmB,CAACF,EAAQF,GAAUr5B,OAAOtnD,QAAoBvF,IAAVuF,IAAuB6gF,EAASF,EAAW,EAClGK,EAAsB,CAACJ,EAAaE,GAAWx5B,OAAOtnD,QAAoBvF,IAAVuF,IAClE8gF,EAAYF,EACZ,EACEK,EAA0BF,EAAmBz/E,EAAOm5C,KACpDymC,EAA6BF,EAAsB1/E,EAAOk5C,QAC1D2mC,KAAc/uF,KAAK0B,MAAM8F,MAAQsnF,GACjC5S,EAAcl8E,KAAK0B,MAAM2P,6BAA+Bq7B,EAAAA,GAA2ByS,UAIzF,IAAI6vC,MAHsB9S,EACtBl8E,KAAK0B,MAAM+F,OACXzH,KAAK0B,MAAMwV,SAASurC,QAAQh7C,QAAUzH,KAAK0B,MAAM+F,QACdonF,GAEnC7uF,KAAK0B,MAAMyoE,QAAQ/vC,SAASotB,EAAAA,GAAgBp3C,WAAa8rE,IAC3D8S,GAAahvF,KAAK0B,MAAM0O,SAAS8qB,cAAc2Q,QAAQojD,iBAEpDvlF,EAAMlC,QAAUunF,GAAYrlF,EAAMjC,SAAWunF,IAAcD,EAAW,GAAKC,EAAY,GAC1FtlF,EAAMyG,iBAAiB,CAAE3I,MAAOunF,EAAUtnF,OAAQunF,GACpD,IAEN,CAEAV,SAAAA,CAAUlqD,GACR,MAAMz6B,EAAQ3J,KAAK0B,MAAMwV,SAASnX,OAAO4J,QACzC,IAAKA,EAAO,OACZ,MAAMqqB,EAAS,IACVh0B,KAAK0B,MAAMwV,SAASnX,OAAOiK,WAC9BihB,WAAY,KACZ2I,aAAc5zB,KAAK0B,MACnBsyD,YAAarqD,EAAMqqD,YACnBD,UAAWpqD,EAAMoqD,WAEnB,IAAK,IAAI7xC,EAAI,EAAGA,EAAIkiB,EAAOliB,IAAK,CAC9B,MAAMxgB,EAAQ1B,KAAK0B,MAAMwV,SAASwsD,OAAmB1vC,GACrDh0B,KAAKkX,OAAO3V,KAAK,CAAEG,QAAOsyB,UAC5B,CACF,CAEAq6D,YAAAA,CAAaa,GACX,KAAOlvF,KAAK0B,MAAMwV,SAASktB,QAAU8qD,GAAa,CAClClvF,KAAK0B,MAAMwV,SAASnX,OAC5B2zD,iBACN1zD,KAAKkX,OAAOi4E,KACd,CACF,CAEAhE,eAAkB/gF,IAChBpK,KAAKouF,eACDpuF,KAAK0B,MAAMqiE,aAAa5hE,IAAIiI,IAC9BpK,KAAK0B,MAAMguC,gBAAgB,cAAe1vC,KAAK0B,MAAMwV,SAASnX,OAChE,EAGF27E,cAAgBA,CAACN,EAA2B5P,KAC5B,YAAVA,IAGJxrE,KAAKouF,eAEDhT,GAAyB,WAAV5P,GACjBxrE,KAAK64E,SAAS,CACZvO,SAAU8Q,EAAY9Q,SACtBH,QAASiR,EAAYjR,QACrBj7D,OAAQksE,EAAYlsE,SAExB,EAIG,MAAMkgF,GAAuBC,KChoBKtyE,GAAoB/Z,IAC3DqI,EAAAA,WAAgB,KACd,MAiBMikF,EAA0BxxB,KAjBNyxB,KACxB,MAAMC,EAAYhlF,GAAAA,EAAMxI,MAElBytF,EADYnlF,EAAAA,EAAMtI,MACSy5C,SAAS/xC,GAAUA,EAAMmpD,iBAE1D28B,EAAUjnF,SAASoB,KAEd8lF,EAAetnF,MAAMunF,GAAcA,EAAUvtF,IAAIwH,OACjDA,EAAM4J,YACP5J,EAAMirD,WAAa,GACnBjrD,EAAMirD,UAAY3uD,KAAKC,MAdE,KAgBzByD,EAAMkrD,SACR,GACA,GAGwD,KAG5D,OADArqD,GAAAA,EAAM7J,KAAK,SAAU2uF,GACd,KACLA,EAAwBrxB,SACxBzzD,GAAAA,EAAM7I,OAAO,SAAU2tF,EAAwB,CAChD,GACA,KAEIjjF,EAAAA,EAAAA,KAAC0Q,EAAS,IAAK/Z,OCjCQ+Z,GAAoB/Z,IAClD,MAAMysD,GAA0BiQ,EAAAA,EAAAA,OAC1B+sB,GAAkB/sB,EAAAA,EAAAA,OAExB,OAAOrzD,EAAAA,EAAAA,KAAC0Q,EAAS,CAAC0yC,wBAAyBA,EAAyBg9B,gBAAiBA,KAAqBzpF,GAAS,GFooBnH2sF,GAAAA,GGrkBK,SACL5yE,GAEA,OAAO,SAA0B/Z,GAC/B,MAAM,kBAAE4sF,GAnEZ,WACE,MAAMC,EAA0BxkF,EAAAA,OAAaT,SAASpH,QAE9C3E,QAAS+wF,GAAsBvkF,EAAAA,QAAcgD,IACnD,MAAM6I,EAAS7I,EACZoE,eACA1F,QACC,CAACC,EAAKnO,IACAmO,EAAI7E,MAAKR,IAAA,IAAC,OAAEikC,GAAQjkC,EAAA,OAAKikC,IAAW/sC,EAAQ+sC,MAAM,IAC7C5+B,EAEF,IAAIA,EAAK,CAAE4+B,OAAQ/sC,EAAQ+sC,OAAQn3B,UAAW5V,EAAQ4V,UAAW5B,WAAYhU,EAAQgU,cAE9F,IAEDnF,KAAKhE,IACJ,MAAM,OAAEkiC,EAAM,UAAEn3B,EAAS,WAAE5B,GAAenJ,EACpCw6C,EAAS15C,GAAAA,EAAMo6C,QAClBj7C,GACCA,EAAMiiC,SAAWA,EAAOvyB,QAAQ,IAAK,KACrC1P,EAAM8K,YAAcA,GACpB9K,EAAMkJ,aAAeA,GACrBxE,EAAiBw2C,SAASl7C,EAAMm7C,UAEpC,GAAIZ,EAAOjkD,OAAS,EAAG,CACrB,MAAM,UAAEg7B,EAAS,WAAEpoB,EAAU,WAAE46B,EAAU,UAAE2L,EAAS,KAAEh2C,GAAS8gD,EAAO,GACtE,IAAI4rC,EACJ,OAAK70D,GAGa,OAAdme,IACF02C,EAAiD,KAA7B70D,EAAYme,EAAY,IAE3B,OAAf3L,GAAuBA,IAAexS,IACxC60D,EAAkD,KAA9BriD,EAAaxS,EAAY,IAEvC,GAAE73B,GAAQwoC,KAAU9qB,GAAAA,GAAKkD,MAAM,CACrCpW,MAAOqtB,EACPA,YACApoB,aACAoR,oBAAgB5b,OACZynF,EAAoB,EAAI,IAAM,MAAMhvE,GAAAA,GAAKkD,MAAM,CACnDpW,MAAOyR,KAAKQ,IAAIiwE,GAChB7rE,eAAgB,QAfT,IAiBX,CACA,OAAO,IAAI,IAEZrM,QAAQlO,GAAoB,OAAVA,IAErB,GAAIwN,GAAUA,EAAOjX,OAAS,EAAG,CAC/B,MAAMuD,EAAQ0T,EAAOrT,KAAK,OACtB+G,SAASpH,QAAUA,IACrBoH,SAASpH,MAAQA,EAErB,MAAWoH,SAASpH,QAAUqsF,EAAwBhxF,UACpD+L,SAASpH,MAAQqsF,EAAwBhxF,QAC3C,IAGF,MAAO,CAAE+wF,oBACX,CAMkCG,GAExBC,EAAqB3kF,EAAAA,aAAkB,KAC3CukF,EAAkB5sF,EAAMqL,iBAAiB,GACxC,CAACrL,EAAMqL,iBAAkBuhF,IAc5B,OAZAvkF,EAAAA,WAAgB,KACd,GAAIrI,EAAMqL,iBAAiBgD,6BAA+Bq7B,EAAAA,GAA2ByS,UAKnF,OAJAn8C,EAAMqL,iBAAiB6I,SAASvW,KAAK,SAAUqvF,GAE/CA,IAEO,KACLhtF,EAAMqL,iBAAiB6I,SAASvV,OAAO,SAAUquF,EAAmB,CAExE,GACC,CAAChtF,EAAMqL,iBAAkB2hF,KAErB3jF,EAAAA,EAAAA,KAAC0Q,EAAS,IAAK/Z,GACxB,CACF,IJqJO,SACL+Z,GAIA,MAAMqyE,EAnBR,SACEryE,GAEA,OAAO,SAA0B/Z,GAC/B,MAAM,OAAEy8D,EAAM,gBAAE4qB,GAAoBhB,GAAoBrmF,EAAMqL,kBAC9D,OACEW,EAAAA,EAAAA,MAAAiC,EAAAA,SAAA,CAAAxE,SAAA,EACEJ,EAAAA,EAAAA,KAACs8E,GAAe,CAAChiF,MAAO84D,EAAQmpB,eAAgByB,KAChDh+E,EAAAA,EAAAA,KAAC0Q,EAAS,IAAK/Z,MAGrB,CACF,CAO+BitF,CAAmClzE,GAChE,OAAO,SAA0B/Z,GAC/B,MAAM,GAAEojE,IAAOj4D,EAAAA,EAAAA,OACT+tE,EAAcl5E,EAAMqL,iBAAiBgD,6BAA+Bq7B,EAAAA,GAA2ByS,UAC/FmnB,EAActjE,EAAMqL,iBAAiBgD,6BAA+Bq7B,EAAAA,GAA2BkiB,UAC/F0xB,EAA2B,CAC/B5zC,EAAAA,GAA2BmiB,YAC3BniB,EAAAA,GAA2BoiB,UAC3BpiB,EAAAA,GAA2BqiB,YAC3B30B,SAASp3B,EAAMqL,iBAAiBgD,4BAClC,OAAI6qE,GAAgB5V,GAAsB,MAAPF,GAAeka,GACzCj0E,EAAAA,EAAAA,KAAC+iF,EAAoB,IAAKpsF,KAG5BqJ,EAAAA,EAAAA,KAAC0Q,EAAS,IAAK/Z,GACxB,CACF,IKnQO,SACL+Z,GAEA,OAAO,SAA0B/Z,GAC/B,MAAMqL,GAAmBC,EAAAA,EAAAA,GAActL,EAAMqL,iBAAkB,CAAEE,gBAAiB,CAAC,UACnF,OAAOlC,EAAAA,EAAAA,KAAC0Q,EAAS,IAAK/Z,EAAOwO,KAAMnD,GAAkBmD,MACvD,CACF,GJmoBE0+E,GAAAA,GvCjiBmCnzE,GAAoB/Z,IACvD,MAAM,2BAAEwhE,EAA0B,iBAAE1C,GAAqBkD,GAAmBhiE,EAAMqL,kBAElF,OACEhC,EAAAA,EAAAA,KAAC0Q,EAAS,IAAK/Z,EAAOwhE,2BAA4BA,EAA4B1C,iBAAkBA,GAAoB,GuCshBpFutB,CASlC9E,IKloBK,SAAS9/E,GAAW9C,GAAyE,IAAxE,OAAEqsB,EAAM,aAAEksD,EAAY,oBAAEiQ,GAAsB,GAAwBxoF,EAChG,MAAMyoF,EAAUD,EAAsBE,EAAAA,IAAsBhlF,EAAAA,SAC5D,OACEgB,EAAAA,EAAAA,KAAC+jF,EAAO,CAAA3jF,UACNJ,EAAAA,EAAAA,KAACgzD,EAAyB,CAAA5yD,UACxBJ,EAAAA,EAAAA,KAAC+iF,GAAoB,CAACp7D,OAAQA,EAAQksD,aAAcA,OAI5D,CAwBO,MAAMoQ,IAA6Bt+E,EAAAA,EAAAA,MAtBnC,SAAsC5J,GAIK,IAJJ,OAC5C4rB,EAAM,aACNksD,EAAY,cACZqQ,GAC8CnoF,EAC9C,MAAM,oBAAEooF,EAAmB,0BAAEC,EAAyB,mBAAEC,IAAuBn+E,EAAAA,EAAAA,KAE/E,OACElG,EAAAA,EAAAA,KAACgzD,EAAyB,CAAA5yD,SACvBunB,IACC3nB,EAAAA,EAAAA,KAAC+iF,GAAoB,CAEnBp7D,OAAQy8D,EAA0B,CAAEzzE,SAAUgX,IAC9CksD,aAAcA,EACdyQ,2BAA4BH,EAC5BD,cAAeA,GAJVG,IASf,G,gDC9CO,MAAMle,EAAkC,wB,4MCyB/C,SAASoe,EAAqB5/E,GAC5B,MAAMo7E,EAAavmF,OAAOumF,WAC1B,OACEA,GAAcriC,EAAAA,IACd/4C,EAAYK,6BAA+Bq7B,EAAAA,GAA2ByS,UAE/D,GAGFy/B,EAAAA,EAAAA,IAA8B,CACnC5tE,cACAglD,iBAAkBlM,EAAAA,GAClB+0B,kBAAmBuN,GAEvB,CAEA,SAASyE,EAAclpF,GAKyD,IALxD,iBACtB0G,EAAgB,OAChB2lB,EAAM,2BACN28D,EAA0B,cAC1BJ,GAC4E5oF,EAC5E,MAAOo6D,EAAQ+uB,GAAazlF,EAAAA,UAAe,GAmD3C,OA1CAA,EAAAA,WAAgB,KACd,GAAIslF,GAA8BtiF,IAAqB0zD,EAAQ,CAC7D,MAAMgvB,EAAwBA,KAC5B,MAAM,OAAE75E,GAAW7I,EAAiBnE,WAElCgN,EAAOjX,SAAW+zB,EAAO9c,OAAOjX,QAChCiX,EAAOg+C,OACL,CAACxrD,EAAO2K,IACN3K,EAAM2L,MAAMpV,SAAW+zB,EAAO9c,OAAO7C,GAAYgB,MAAMpV,QACvDyJ,EAAM2L,MAAM6/C,OACV,CAACxiC,EAAMigD,IACLjgD,EAAKhd,SAASzV,SAAW+zB,EAAO9c,OAAO7C,GAAYgB,MAAMs9D,GAAWj9D,SAASzV,QAC7EyyB,EAAKhd,SAASw/C,OACZ,CAACpzD,EAASkvF,IACRlvF,EAAQkW,UAAU/X,SAClB+zB,EAAO9c,OAAO7C,GAAYgB,MAAMs9D,GAAWj9D,SAASs7E,GAAch5E,UAAU/X,eAMxF6wF,GAAU,GACVziF,EAAiB8B,iBAAiB,CAAE4xD,QAAQ,IAC5C4uB,EAA2BtiF,GACvBkiF,IACFA,EAAcp6E,MAAM86E,QAAU,QAC9BV,EAAcp6E,MAAMu6C,UAAY,QAChC6/B,EAAcp6E,MAAM1F,SAAW,SAEnC,EAOF,OAJApC,EAAiB1N,KAAK6xE,EAAAA,EAAiCue,GAEvDA,IAEO,KACL1iF,EAAiB1M,OAAO6wE,EAAAA,EAAiCue,EAAsB,CAEnF,IACC,CAAC1iF,EAAkB2lB,EAAQ+tC,EAAQ4uB,EAA4BJ,IAE3D,IACT,CAEO,MAAMZ,EAA+B5yE,GAAoB/Z,IAC9D,MAAMgxB,EAAS3oB,EAAAA,SAAc,KAC3B,MAAM6lF,EAAYhqE,IAAM,CAAC,EAAGlkB,EAAMgxB,OAAQ,CACxCs2C,SAAUtnE,EAAMgxB,OAAOs2C,WAAY,EACnCL,gBAAiBjnE,EAAMgxB,OAAOi2C,kBAAmB,EACjDmI,WAAYpvE,EAAMgxB,OAAOo+C,aAAc,EACvCkC,MAAOtxE,EAAMgxB,OAAOsgD,QAAS,EAC7B5tE,MACE1D,EAAMgxB,OAAOttB,OAAS,CAACgC,EAAAA,GAAMg3C,MAAOh3C,EAAAA,GAAMyoF,MAAM/2D,SAASp3B,EAAMgxB,OAAOttB,OAAS1D,EAAMgxB,OAAOttB,MAAQgC,EAAAA,GAAMg3C,MAC5GyqB,QAASnnE,EAAMgxB,OAAOm2C,SAAW,CAAC3iB,EAAAA,GAAgBkjB,QAASljB,EAAAA,GAAgB6iB,MAAO7iB,EAAAA,GAAgB+iB,OAClGA,MAAOvnE,EAAMgxB,OAAOu2C,QAAS,EAC7Bl5D,2BAA4BrO,EAAMgxB,OAAO3iB,4BAA8Bq7B,EAAAA,GAA2B3nB,QAClG6sD,qBAAsB,KAGnBsf,EAAU3mB,QACb2mB,EAAU/mB,QAAU+mB,EAAU/mB,QAAQvyD,QAAQ4G,GAAY,UAANA,MAIlDuhC,EAAAA,EAAAA,IAAiBmxC,EAAW,CAACxkD,EAAAA,GAA2BkiB,cAC1DsiC,EAAU/mB,QAAU+mB,EAAU/mB,QAAQinB,OAAO,CAAC5pC,EAAAA,GAAgBp3C,SAAUo3C,EAAAA,GAAgB/yC,aAG1F,MAAMm9D,GAAuBpkB,EAAAA,EAAAA,OAA2B51C,QAAOxP,IAAA,IAAC,WAAE8iD,GAAY9iD,EAAA,MAAoB,YAAf8iD,CAAwB,KAAK,GAC1Gob,EAAc4qB,EAAU7/E,6BAA+Bq7B,EAAAA,GAA2BkiB,UAClFyiC,EAA6B/qB,GAAkD,OAAnCv8B,EAAAA,GAAMunD,UAAU,eAElE,GAAoC,IAAhC1f,EAAqB3xE,QAAgBoxF,EACvC,OAAOH,EAGT,MAAMK,EAAc3f,EAAqB/nE,MACvCiE,IAAA,IAAC,cAAEw9C,EAAa,OAAE1f,GAAQ99B,EAAA,MACN,SAAlBw9C,GAA4BtoD,EAAMgxB,OAAO9c,OAAO/O,MAAMuB,GAAUA,EAAMkiC,SAAWA,GAAO,IAGtFg4B,EAAO2tB,GAAevqE,KAAKsmC,MAAMikC,EAAY3lC,eAAe/lC,KAC5D2rE,EAAalrB,GAAe1C,EAAO,CAAEA,aAASv7D,EAEpD,MAAO,IACF6oF,EACHtf,uBACApgE,KAAM0/E,EAAU1/E,MAAQggF,EACxBt6E,OAAQg6E,EAAUh6E,OAAOxJ,KAAKhE,IAC5B,MAAM,OAAEkiC,EAAM,MAAEv2B,GAAU3L,EAC1B,MAAO,IACFA,EACH2L,MAAOA,EAAM3H,KAAKglB,IAChB,MAAM44B,GAAgBX,EAAAA,EAAAA,IAA+Bj4B,GAC/C++D,EAAc7f,EACjBh6D,QACEk1C,GACCA,EAAQxB,gBAAkBA,GAC1BwB,EAAQlhB,SAAWA,IAClBlZ,EAAKhd,SAASvN,MAAMk7D,GAAgBA,EAAYt5D,YAAc+iD,EAAQ/iD,cAE1E2D,KAAIgC,IAAA,IAAC,UAAE3F,EAAS,OAAE2hD,EAAM,aAAEE,GAAcl8C,EAAA,MAAM,CAC7C3F,YACA2hD,YACG1kC,KAAKsmC,MAAM1B,GACf,IACH,MAAO,IACFl5B,EACHhd,SAAU,IAAIgd,EAAKhd,YAAa+7E,GACjC,IAEJ,IAEJ,GAGA,IAEGpjF,EAAmBhD,EAAAA,SAAc,KACrC,MAAM+E,GAAW+nE,EAAAA,EAAAA,IAAY,IAAKnkD,EAAQttB,MAAOstB,EAAOttB,QAClDsK,EAAc0gF,EAAAA,EAAiBhuB,OAAyB,CAC5Dx0D,OAAQ8kB,EAAO9kB,OACf1H,MAAOwsB,EAAOxsB,MACdC,OAAQusB,EAAOvsB,OACf6iE,SAAUt2C,EAAOs2C,SACjBL,gBAAiBj2C,EAAOi2C,gBACxBmI,WAAYp+C,EAAOo+C,WACnBgB,kBAAmBp/C,EAAOo+C,WAC1BkC,MAAOtgD,EAAOsgD,MACdnK,QAASn2C,EAAOm2C,QAChBzjE,MAAOstB,EAAOttB,MACd8K,KAAMwiB,EAAOxiB,KACbpB,WACA2rE,mBAAoB/nD,EAAO3iB,6BAA+Bq7B,EAAAA,GAA2ByS,UACrF9tC,2BAA4B2iB,EAAO3iB,2BACnCu5E,sBAAsB,EACtBn3B,6BACEuO,EAAAA,EAAAA,IAA0ChuC,KAC1CnuB,OAAO8S,eAAegzE,aAAanK,EAAAA,GAAeC,mBAEpD5tD,sBAAsB,EACtB26B,KAAMx6B,EAAOw6B,KACb0T,sBAAuBx3D,EAAAA,EAAsBg5D,OAA8B,CACzEhuD,SAAUse,EAAO49C,yBAMrB,OAFA5gE,EAAYb,iBAAiB,CAAE0+D,kBAAmB+hB,EAAqB5/E,KAEhEA,CAAW,GAIjB,IAEH,OAAO3C,GACLW,EAAAA,EAAAA,MAAAiC,EAAAA,SAAA,CAAAxE,SAAA,EACEJ,EAAAA,EAAAA,KAACwkF,EAAc,CACb78D,OAAQA,EACR3lB,iBAAkBA,EAClBsiF,2BAA4B3tF,EAAM2tF,2BAClCJ,cAAevtF,GAAOutF,iBAExBlkF,EAAAA,EAAAA,KAAC0Q,EAAS,CAAC1O,iBAAkBA,KAAsBrL,EAAOgxB,OAAQA,OAElE,IAAI,C,mJC1MH,MAAMk8D,EAAoBnzE,GAAoB/Z,IACnD,MAAO2uF,EAAyBC,GAA8BvmF,EAAAA,SAA4C,CAAC,GACrGwmF,EAA4BxmF,EAAAA,aAAkB,KAElD,MAAMymF,EAA0D,CAAC,EACjE9uF,EAAMqL,iBAAiBoE,eAAelK,SAASmB,IAC7C,MAAMqoF,EAAuBroF,EAAMkkE,qBAE/BmkB,IACFD,EAA2BC,GAAwBD,EAA2BC,IAAyB,GACvGD,EAA2BC,GAAsBxwF,KAAKmI,EAAMxI,IAC9D,IAGE8lB,KAAKC,UAAU6qE,KAAgC9qE,KAAKC,UAAU0qE,IAChEC,EAA2BE,EAC7B,GACC,CAAC9uF,EAAMqL,iBAAkBsjF,IACtBK,EAAiB3mF,EAAAA,OAAuB,IAyD9C,OAvDAA,EAAAA,WAAgB,KACd,MAAM4mF,EAAqCn0B,IAAS+zB,GAC9CK,EAA0BrsF,OAAO+/D,YACrCqsB,EAC8B,IAA9BtoC,EAAAA,IAOF,OAHAr/C,EAAAA,EAAM3J,KAAK,SAAUsxF,GACrB1nF,EAAAA,EAAK5J,KAAK,SAAUsxF,GAEb,KACLA,EAAmCh0B,SACnC3zD,EAAAA,EAAM3I,OAAO,SAAUswF,GACvB1nF,EAAAA,EAAK5I,OAAO,SAAUswF,GACtBpsF,OAAOigE,cAAcosB,EAAwB,CAC9C,GACA,CAACL,IAEJxmF,EAAAA,WAAgB,KACd,MAAM8mF,EAAmBlvF,OAAOC,KAAKyuF,GAAyBjkF,IAAIoW,QAC5DsuE,EAAYpvF,EAAMqL,iBAAiBoE,eACnC4/E,EAAsBhzE,KAAKqF,OAAOytE,GAuBxC,OArBAA,EAAiB5pF,SAAShG,IACxB,MAAM+vF,EAAYzsF,OAAO+/D,aAAY,KACnC,MAAM2sB,EAAWZ,EAAwBpvF,GAEzC6vF,EACGx6E,QAAQlO,GAAU6oF,EAASn4D,SAAS1wB,EAAMxI,MAC1Cu6C,SAAS/xC,GAAUA,EAAMmpD,iBACzBj7C,QACC,CAACjO,EAAO1H,EAAOuwF,KACZ7oF,EAAM4J,YAActR,IAAUuwF,EAAe3wF,WAAW4wF,GAAkB9oF,EAAMxH,IAAIswF,OAExFlqF,SAASoB,IACRA,EAAMopD,UAAU,CAAEC,UAAWC,EAAAA,EAAeC,WAAY,IAExD3wD,IAAa8vF,GACfznF,SAAS8nF,cAAc,IAAIC,MAAMnoC,EAAAA,IACnC,GACCjoD,GACHyvF,EAAenzF,QAAQ0C,KAAK+wF,EAAU,IAGjC,KACDN,EAAenzF,QAAQoB,OAAS,IAClC+xF,EAAenzF,QAAQ0J,SAAS+pF,IAC9BzsF,OAAOigE,cAAcwsB,EAAU,IAEjCN,EAAenzF,QAAU,GAC3B,CACD,GACA,CAACmE,EAAMqL,iBAAkBsjF,KAErBtlF,EAAAA,EAAAA,KAAC0Q,EAAS,IAAK/Z,GAAS,C,qQCpE1B,SAAS4vF,EAAUjrF,GAA6F,IAA5F,OAAEikC,EAAM,WAAE/4B,EAAU,OAAEmD,EAAM,GAAE9U,GAA4DyG,EACnH,MAAMkrF,EAAe,CAAE9vD,EAAG6I,EAAQnV,EAAGzgB,EAAQkM,EAAGhhB,GAC1Cw8C,EAAU7qC,IAAeC,EAAAA,GAAWC,MACpCuzD,EAAc,YAAY+lB,KAAKxmF,OAAOgF,SAASqO,UAC/C45E,EAAgBxsB,GAAe5oB,EAGrC,MAAQ,IAFM4oB,GAAe5oB,EAAU73C,OAAOgF,SAASqO,SAAW,kBAEhD65E,EAAAA,UAAsB,IAAKF,KAAkBC,EAAgB,CAAE3sB,GAAI,KAAQ,CAAEp3D,EAAG,WACpG,C,eCvBe,SAASikF,EAAQrrF,GAA0C,IAAzC,KAAE6J,EAAI,cAAEyhF,GAA+BtrF,EACtE,MAAOurF,EAAYC,GAAiB9nF,EAAAA,UAAe,IAC5C+nF,EAAiBC,GAAsBhoF,EAAAA,UAAe,IACrD6W,EAAGoxE,IAAgBnlF,EAAAA,EAAAA,OAErBolF,EAAoBloF,EAAAA,QAAa3D,UAGrC,IAAI8rF,EAFJL,GAAc,GAGd,IAKEK,EAAiC,aAJVC,MAAO,4BAA2BjiF,EAAKtQ,KAAM,CAClE2/D,OAAQ,YAGY6yB,MACxB,CAAE,MAAO,CAET,GAAKF,EAAL,CAIA,GAAIF,IAAgB9hF,EAAKtQ,GAAGqD,WAAY,CACtC,MAAMovF,EAAS,IAAIC,IAAI/tF,OAAOgF,SAAS6mD,MAGvC,OAFAiiC,EAAOE,aAAa9M,OAAO,UAC3BlhF,OAAOgF,SAAS6mD,KAAOiiC,EAAOjiC,KAEhC,CAEAuhC,EAAczhF,EATd,CASmB,IAGrB,OACExC,EAAAA,EAAAA,MAAA,OAEEC,UAAW0hD,IAAW,mDAAoD,CACxE,oFAAqFyiC,EACrF,iBAAkBA,IAEpBxnF,QAASwnF,OAAkB/qF,EAAY,IAAOuC,SAASC,SAAW+nF,EAAWphF,GAC7E,cAAY,0BAAyB/E,SAAA,EAErCuC,EAAAA,EAAAA,MAAAiC,EAAAA,SAAA,CAAAxE,SAAA,EACEuC,EAAAA,EAAAA,MAAA,OAAKC,UAAU,wEAAuExC,SAAA,EACpFuC,EAAAA,EAAAA,MAAA,MAAIC,UAAU,sCAAqCxC,SAAA,EACjDJ,EAAAA,EAAAA,KAAA,QAAM4C,UAAU,cAAaxC,SAAE+E,EAAKo6B,SACnCp6B,EAAKsiF,UAAWznF,EAAAA,EAAAA,KAAA,QAAM4C,UAAU,eAAcxC,SAAE+E,EAAKsiF,cAExD9kF,EAAAA,EAAAA,MAAA,QAAMC,UAAU,iBAAiB,cAAY,6BAA4BxC,SAAA,EACvEJ,EAAAA,EAAAA,KAAA,QAAAI,SAAO+E,EAAKg2B,QACZn7B,EAAAA,EAAAA,KAAA,QAAM4C,UAAU,eAAcxC,SAAE+E,EAAK/N,QACrCuL,EAAAA,EAAAA,MAAA,QAAMC,UAAU,4BAA2BxC,SAAA,EACzCJ,EAAAA,EAAAA,KAACgD,EAAAA,IAAI,CAACjM,KAAK,WAAWoE,MAAO,GAAIyH,UAAU,WAC1Cu5C,EAAAA,GAAoBh3C,EAAKwE,cAGf,KAAdxE,EAAKoyD,MACJv3D,EAAAA,EAAAA,KAAA,KAAG4C,UAAU,+DAA8DxC,SAAE+E,EAAKoyD,OAChF,SAGNv3D,EAAAA,EAAAA,KAACC,EAAAA,IAAM,CACL,cAAY,gCACZitD,aAAa,WACbnqD,WAAW,SACXH,UAAU,OACVrD,QAAUhL,IACRA,EAAGmzF,kBACHV,GAAmB,EAAK,OAK7BD,IACCpkF,EAAAA,EAAAA,MAAA,OAAKC,UAAU,qFAAoFxC,SAAA,EACjGJ,EAAAA,EAAAA,KAAA,OAAK4C,UAAU,mCAAkCxC,UAC/CuC,EAAAA,EAAAA,MAAA,MAAIC,UAAU,sEAAqExC,SAAA,CAAC,UAC1E+E,EAAKo6B,OAAO,cAAYp6B,EAAKg2B,KAAK,UAI9Cx4B,EAAAA,EAAAA,MAAA,OAAKC,UAAU,wBAAuBxC,SAAA,EACpCJ,EAAAA,EAAAA,KAACC,EAAAA,IAAM,CACLV,QAASA,KACPynF,GAAmB,EAAM,EACzB5mF,SACH,YAGDJ,EAAAA,EAAAA,KAACC,EAAAA,IAAM,CACL,cAAY,wCACZiF,SAAU2hF,EACVxsF,MAAM,MACNkF,QAASA,KACP2nF,EAAkB10F,QAAQ2S,EAAK,EAC/B/E,SACH,mBA9DF+E,EAAKtQ,GAsEhB,CC1Ge,SAAS8yF,IACtB,MAAOC,EAAUC,GAAe7oF,EAAAA,UAAe,IACxC8oF,EAAYC,GAAiB/oF,EAAAA,UAAe,IAC5CgpF,EAAkBC,GAAuBjpF,EAAAA,SAAgC,KACzEy7E,IAAUZ,EAAAA,EAAAA,MACXqO,EAAezN,EAAO5zD,IAAI,KAAM6G,MAAM,KAE5C1uB,EAAAA,WAAgB,MACd3D,iBACE7B,OAAOkK,OAAO,QAAS,OAAQ,CAAE25D,eAAgB,UACjD,IACE,MACMa,SADapK,EAAAA,EAAAA,IAAS,CAAEt1D,SAAU,uBAAwBw1D,mBAAoB,CAAC,QAClEkK,MAAM78D,KAAK8D,IAC5B,MAAMgjF,EAAYhjF,EAAKg2B,KAAKzN,MAAM,KAClC,MAAO,IACFvoB,EACHqB,YAAYi3E,EAAAA,EAAAA,IAAct4E,EAAKo6B,QAC/BpE,KAAMgtD,EAAU,GAAGn7E,QAAQ,IAAK,KAAKA,QAAQ,IAAK,MAClD5V,KAAM+wF,EAAU,GACjB,IAGHF,EFuFD,SAAyB/pB,EAAgBnmB,GAC9C,GAAImmB,EAAMtqE,QAAU,EAAG,MAAO,GAE9B,MAAMo0F,EAAmB9pB,EAAMx9D,QAAO,CAAC0nF,EAAWjjF,KAChD,MAAMkjF,EAAcD,EAAU5qF,MAAMqY,GAAMA,EAAE0pB,SAAWp6B,EAAKo6B,SAW5D,OATI8oD,EACFA,EAAYnqB,MAAMhpE,KAAKiQ,GACd4yC,EAAQhqB,SAAS5oB,EAAKo6B,SAC/B6oD,EAAUlzF,KAAK,CACbqqC,OAAQp6B,EAAKo6B,OACb2+B,MAAO,CAAC/4D,KAILijF,CAAS,GACf,IAMH,OALAJ,EAAiBhkD,QAAQ,CACvBzE,OAAQ,YACR2+B,MAAOA,IAGF8pB,CACT,CE9G4BM,CAAgBpqB,EAAOgqB,IAC3CH,GAAc,EAChB,CAAE,MACAF,GAAY,EACd,CACF,CAEAU,EAAY,GAIX,IAEH,MAAMC,EAAqBrjF,IACzB8iF,GAAqBhqC,IACnB,MAAMwqC,EAAqB,IAAIxqC,GAGzByqC,EAAgBD,EAAmBjzF,WAAW4qB,GAAMA,EAAEmf,SAAWp6B,EAAKo6B,SAC5E,GAAImpD,GAAiB,EAAG,CACtB,MAAMC,EAAkB,IACnBF,EAAmBC,GACtBxqB,MAAOuqB,EAAmBC,GAAexqB,MAAM3yD,QAAQsK,GAAMA,EAAEhhB,KAAOsQ,EAAKtQ,MAE7E4zF,EAAmBC,GAAiBC,CACtC,CAGA,MAAMC,EAAa,IACdH,EAAmB,GACtBvqB,MAAOuqB,EAAmB,GAAGvqB,MAAM3yD,QAAQsK,GAAMA,EAAEhhB,KAAOsQ,EAAKtQ,MAKjE,OAHA4zF,EAAmB,GAAKG,EAGjBH,EAAmBl9E,QAAQ6U,GAAyB,IAAnBA,EAAE89C,MAAMtqE,QAAa,GAC7D,EAGJ,OAAKk0F,GAAcF,GAEf5nF,EAAAA,EAAAA,KAAA,OAAK4C,UAAU,0DAAyDxC,SACrEwnF,EAAW,sDAAwD,aAK1C,IAA5BI,EAAiBp0F,QAEjBoM,EAAAA,EAAAA,KAAA,OACE,cAAY,+BACZ4C,UAAU,0DAAyDxC,SACpE,qBAOHuC,EAAAA,EAAAA,MAACkmF,EAAAA,IAAI,CAAAzoF,SAAA,EACHJ,EAAAA,EAAAA,KAAC8oF,EAAAA,IAAO,CAAC,aAAW,YAAYlmF,UAAU,kBAAiBxC,SACxD4nF,EAAiB3mF,KAAK0nF,IACrB/oF,EAAAA,EAAAA,KAACgpF,EAAAA,IAAG,CAAuB7lF,KAAK,QAAQ+pD,cAAcltD,EAAAA,EAAAA,KAACipF,EAAAA,IAAK,CAAA7oF,SAAE2oF,EAAS7qB,MAAMtqE,SAAgBwM,SAC1F2oF,EAASxpD,QADFwpD,EAASxpD,YAKtByoD,EAAiB3mF,KAAK0nF,IACrB/oF,EAAAA,EAAAA,KAACkpF,EAAAA,IAAQ,CAEP,cAAc,mBAAkBH,EAASxpD,OAAO4pD,cAAcn8E,QAAQ,IAAK,OAAO5M,UAElFJ,EAAAA,EAAAA,KAAA,OAAK4C,UAAU,cAAaxC,SACzB2oF,EAAS7qB,MAAM78D,KAAK8D,IACnBnF,EAAAA,EAAAA,KAAC2mF,EAAQ,CAAexhF,KAAMA,EAAMyhF,cAAe4B,GAApCrjF,EAAKtQ,SALnBk0F,EAASxpD,YAYxB,CCxGe,SAAS6pD,EAAW9tF,GAA8B,IAA7B,MAAEhB,GAAyBgB,EAC7D,OACEqH,EAAAA,EAAAA,MAACovD,EAAAA,IAAM,CAACz3D,MAAOA,EAAO,aAAW,aAAa,cAAY,qBAAoB8F,SAAA,EAC5EJ,EAAAA,EAAAA,KAACqyD,EAAAA,IAAY,CAAAjyD,SAAC,gBACdJ,EAAAA,EAAAA,KAACuyD,EAAAA,IAAU,CAAC3vD,UAAU,mCAAmCymF,YAAY,EAAMjpF,UACzEJ,EAAAA,EAAAA,KAAC2nF,EAAS,QAIlB,C,eCcO,SAAS9iF,EAAavJ,GAKkB,IALjB,MAC5BjG,EAAK,SACL4S,EAAQ,wBACRqhF,KACG3yF,GACwC2E,EAC3C,MAAMiuF,GAAeC,EAAAA,EAAAA,KAAgB,CAAElnF,UAAW,iBAC3CmnF,EAAmBC,GAAwB1qF,EAAAA,UAAe,GAC3D85D,EAAM95D,EAAAA,OAAa,MACnBo0D,GAASC,EAAAA,EAAAA,OACTs2B,GAAWtnF,EAAAA,EAAAA,OACXunF,EAAcL,EAAajmC,KAE3BumC,EAAoBJ,EACrB,CACC3kC,GAAIglC,EAAAA,IACJxvF,MAAOivF,GAER,CAAC,EAoBN,OAlBAvqF,EAAAA,WAAgB,KACd,MAAM+qF,EAA2BA,KAC/B,MAAMC,EAAiB7rF,EAAAA,EAAMo6C,QAAej7C,GAAUA,EAAM4J,aAAmC,IAArB5J,EAAMirD,YAChFmhC,EAAqBM,EAAep2F,OAAS,EAAE,EAIjD,OADAuK,EAAAA,EAAM7J,KAAK,SAAUy1F,GACd,KACL5rF,EAAAA,EAAM7I,OAAO,SAAUy0F,EAAyB,CACjD,GACA,IAEH/qF,EAAAA,WAAgB,KACTyqF,GAAsBE,EAASM,SAClCL,GACF,GACC,CAACH,EAAmBE,EAASM,QAASL,IAEpCpwF,OAAO8S,eAAeC,gBAsBzB5J,EAAAA,EAAAA,MAAAiC,EAAAA,SAAA,CAAAxE,SAAA,EACEuC,EAAAA,EAAAA,MAACH,EAAAA,IAAQ,CACPs2D,IAAKA,EACLx+D,MAAOqvF,EACP,aAAW,OACX1hF,SAAUA,EACVxF,OACEzC,EAAAA,EAAAA,KAACC,EAAAA,IAAM,IACDtJ,EACJuJ,YAAY,OACZ0C,UAAW0mF,EACX,cAAY,sBACZnpF,aAAa,iBACb4C,WAAYpM,EAAMyJ,cAAWpE,EAAY,SACzC7E,MAAOR,EAAMyJ,cAAWpE,EAAY,UAEvCoE,SAAA,EAEDJ,EAAAA,EAAAA,KAAC8C,EAAAA,IAAY,IACP+mF,EACJ/kC,GAAI+kC,EAAkB/kC,GACtB5kD,YAAY,WACZ,cAAY,8BACZgqF,cAAc,EACdtnF,UAAU,iBACVrD,QAASA,KACHkqF,EACFF,EAAa/gF,OJjFpBnN,eAAwB0zE,GAC7B,MAAMrX,EAAcqX,EAAYrX,YAC1ByyB,EAAmBzyB,EAAYp6D,QAAQ8sF,UACvC,OAAE7qD,EAAM,WAAE/4B,EAAU,IAAE1M,GAAQ49D,EAC9B/tD,EAASwgF,EAAiB/hF,WAC1B,cAAEymB,GAAkBkgD,EAAYhrE,SAChClB,EAAqBksE,EAAYpxE,WACvCkF,EAAOA,OAASu4C,EAAAA,GAAW,QAC3Bv4C,EAAOulC,SAAWvZ,EAAcrE,OAAO4d,SACvCvlC,EAAOkmD,UAAYl6B,EAAcrE,OAAOu+B,UACxClmD,EAAOgI,OAAShI,EAAOgI,OACpBU,QAAQ6U,GAAkBA,EAAEiqE,UAAYvwF,IACxCuH,KAAK+e,IAAa,IAAWA,EAAGvY,UAAW,KAAM85D,aAAa,aAE1D9+D,EAAOgI,OAAO,GAAGw/E,QAGxB,MAgBMtyC,EAhBmBuyC,KACvB,IAAIvyC,EAAU,GACVwyC,EAAgB,GACpB,IAAK,MAAMlkE,KAAQikE,EACjB,IAAK,MAAM70F,KAAW4wB,EAAKhd,SACJ,oBAAjB5T,EAAQ6T,OACVihF,EAAgB90F,EAAQsiD,SAQ9B,OAJAA,EAAUwyC,EAAc78D,MAAM,KAAKniB,QAAQhW,GAASA,IAC/CwiD,EAAQhqB,SAASwR,IACpBwY,EAAQ7iD,KAAKqqC,EAAOvyB,QAAQ,IAAK,KAE5B+qC,CAAO,EAEAyyC,CAAgB3nF,EAAOgI,OAAO,GAAG7B,OAC3C6uC,EAAS15C,EAAAA,EAAMo6C,QAClBj7C,GACCy6C,EAAQhqB,SAASzwB,EAAMiiC,SAAWjiC,EAAM8K,YAAcsvD,EAAYtvD,WAAa2mE,EAAYv2B,SAASl7C,EAAMm7C,UAC5GltC,QAAO,CAAC9V,EAASG,EAAOihD,IAAUA,EAAMrhD,WAAWkhC,GAAMA,EAAE6I,SAAW9pC,EAAQ8pC,WAAY3pC,IACtF60F,EAAmB9vE,KAAKC,UAAUi9B,EAAOx2C,KAAKi3C,GAAMxwB,IAAKwwB,EAAE8xC,SAAU,CAAC,SAAU,iBAEhF/sF,EAAQsd,KAAKC,UAAU/X,GACvB00D,EACJwX,EAAY5pE,MAAMoyD,OAClBxV,EAAAA,EAAAA,IAAkB,CAAExiB,SAAQl2B,SAAU0lE,EAAYlZ,wBAAwBxsD,YAC1E,GACF7P,OAAOkK,OAAO,QAAS,OAAQ,CAAE25D,eAAgB,UAE7CtlB,EAAQnkD,SAAWikD,EAAOjkD,SAC5BkJ,EAAAA,EAAAA,IAAiB,IAAIC,MAAM,4CAA6C,CACtEC,MAAO,CACL+6C,UACA2yC,uBAAwB7yC,EAAOx2C,KAAK/D,IAAK,CAAQiiC,OAAQjiC,EAAMiiC,OAAQn3B,UAAW9K,EAAM8K,cACxFzD,YAAaoqE,EAAYlxE,SAAS,CAAC,SAAU,aAKnD,MAAMtF,QAAau7D,EAAAA,EAAAA,IAAyB,CAC1Ct1D,SAAU,sBACVg2D,OAAQ,OACR90D,MAAMirF,EAAAA,EAAAA,IAAsB,CAAEprD,SAAQ51B,SAAQtM,QAAOw6C,OAAQ4yC,EAAkBlzB,WAG3EqzB,EAAUrE,EAAW,CACzBhnD,SACA51B,SACAnD,aACA3R,GAAI0D,EAAK1D,KAQTmc,YAAW,KACTxX,OAAOynC,KAAK2pD,EAAS,kBAAkB,GAG7C,CIKYC,CAASx1F,EAAM,EACf+K,SACH,eAGDJ,EAAAA,EAAAA,KAAC8C,EAAAA,IAAY,CAAC5C,YAAY,WAAW,cAAY,8BAA8BX,QAASA,IAAM6zD,EAAO5qD,OAAOpI,SAAC,kBAI/GJ,EAAAA,EAAAA,KAACopF,EAAW,CAAC9uF,MAAO84D,IACnBq2B,IACC9mF,EAAAA,EAAAA,MAACmoF,EAAAA,IAAO,CAACxwF,MAAOivF,EAAc3mF,UAAU,OAAMxC,SAAA,EAC5CJ,EAAAA,EAAAA,KAAA,OAAK4C,UAAU,OAAMxC,UACnBJ,EAAAA,EAAAA,KAAC2kD,EAAAA,IAAO,CAACxpD,MAAO,QAElB6E,EAAAA,EAAAA,KAAA,QAAM4C,UAAWo4D,IAAW,OAAQ,CAAE,QAAQ+vB,EAAAA,EAAAA,QAA2B3qF,SAAC,oDAjE9EJ,EAAAA,EAAAA,KAACC,EAAAA,IAAM,IACDtJ,EACJmuD,GAAG,IACHO,KAAO,gBAAcC,EAAAA,EAAAA,KAAkB,CACrCC,WAAY,SACZC,WAAY,SACZC,aAAc,yBAEhBvlD,YAAY,OACZ0C,UAAW0mF,EACX,cAAY,sBACZnpF,aAAa,iBACb4C,WAAYpM,EAAMyJ,cAAWpE,EAAY,SACzC7E,MAAOR,EAAMyJ,cAAWpE,EAAY,QACpCiM,SAAUA,GA0DlB,C,8HCnIO,SAAShD,EAAO3J,GAA6D,IAA5D,MAAEjG,KAAUsB,GAA8C2E,EAChF,MAAM83D,GAASC,EAAAA,EAAAA,OACT23B,EAAe53B,EAAOlO,SAAS,SAC9B42B,GAAoB,UAAEn1E,KAAesI,EAAAA,EAAAA,GAAe,IACtD8sE,EAAAA,EACH3sE,iBAAkB47E,EAClB77E,cAAe,SACfD,QAASA,IAAMkkD,EAAO9P,SAElB04B,EAAgBF,GAAoBpjE,QAE1C,OACE/V,EAAAA,EAAAA,MAAAiC,EAAAA,SAAA,CAAAxE,SAAA,EACEJ,EAAAA,EAAAA,KAACC,EAAAA,IAAM,IACDtJ,EACJwJ,aAAa,iBACbqD,OAAQwnF,EACRjoF,WAAYpM,EAAMyJ,cAAWpE,EAAY,SACzC7E,MAAOR,EAAMyJ,cAAWpE,EAAY,cACpCuD,QAASA,IAAM6zD,EAAO5qD,OACtBtI,YACEyG,GACE3G,EAAAA,EAAAA,KAAC0kD,EAAAA,IAAO,CACNwc,gBACElhE,EAAAA,EAAAA,KAACgD,EAAAA,IAAI,CAACjM,KAAK,QAAQ6L,UAAWo4D,IAAW,CAAE,aAA8B,eAAhBrkE,EAAM0D,UAChE+F,UAEDJ,EAAAA,EAAAA,KAAC2kD,EAAAA,IAAO,CAACxpD,MAAO,OAGlB,UAIL6gF,IAAiBh8E,EAAAA,EAAAA,KAACg8E,EAAa,CAAC1hF,MAAO84D,EAAQ2b,YAAa15E,MAGnE,C,8HChCA,MAAMwQ,EAAYrM,OAAO8S,eAAeC,eAwIjC,SAASzH,EAAUxJ,GAAiF,IAAhF,KAAEyJ,EAAI,UAAEnC,EAAS,MAAEvI,KAAU1D,GAAiD2E,EACvG,MAAM2vF,GAAOC,EAAAA,EAAAA,OACPC,EAvIR,SAAiBpmF,GACf,MAAO,CACL,CACElQ,GAAI,aACJu2F,MAAO,CACL,CACEj0F,MAAO,aACPuI,KAAM,2GAEJmG,EACA,CACE,CACE1O,MAAO,qBACPuI,KAAM,2FACN8uD,OAAQ,yCAEV,CACEr3D,MAAO,uBACPuI,KAAM,+KACN8uD,OAAQ,yCAEV,CACEr3D,MAAO,2BACPuI,KAAM,wGACN8uD,OAAQ,YAEV,CACEr3D,MAAO,qBACPuI,KAAM,oKACN8uD,OAAQ,mCAGZ,CACE,CACEr3D,MAAO,sBACPuI,MACEiD,EAAAA,EAAAA,MAAAiC,EAAAA,SAAA,CAAAxE,SAAA,EACEJ,EAAAA,EAAAA,KAAA,KACEqlD,KAAO,gBAAcC,EAAAA,EAAAA,KAAkB,CACrCC,WAAY,SACZC,WAAY,SACZC,aAAc,iBAEhB+I,OAAO,SACP5rD,UAAU,WAAUxC,SACrB,iBAEI,IAAI,8GAEFJ,EAAAA,EAAAA,KAAA,SAAM,yGAIjBwuD,OAAQ,wCACRlsD,UAAW,iBAGnB,CACEnL,MAAO,uBACPuI,KAAMmG,EACF,qGACA,kHACJ2oD,OAAQ,sCACRlsD,UAAW,mBAETyC,IAASs7B,EAAAA,GAA2BkiB,UACpC,GACA,CACE,CACEprD,MAAO,8BACPuI,KAAM,+IACN8uD,OAAQ,4CAGXrvD,EAAAA,EAAAA,IAAqBZ,SAASa,kBAAoB2F,IAASs7B,EAAAA,GAA2ByS,UAEvF,CACE,CACE37C,MAAO,kBACPuI,KACEqF,IAASs7B,EAAAA,GAA2BkiB,UAChC,oFACA,gDACNiM,OAAQ,0CACRlsD,UAAWyC,IAASs7B,EAAAA,GAA2ByS,UAAY,SAAW,eAT1E,GAYJ,CACE37C,MAAO,cACPuI,KAAM,uDACN8uD,OAAQ,wCACR68B,eAAgBtmF,IAASs7B,EAAAA,GAA2BkiB,UAAY,OAAIvmD,EACpEsG,UAAW,cAET4F,EAAAA,EAAAA,OAAuBnD,IAASs7B,EAAAA,GAA2ByS,UAC3D,CACE,CACE37C,MAAO,QACPuI,KAAM,2CACN8uD,OAAQ,uCAGZ,GACJ,CACEr3D,MAAO,iBACPuI,KAAM,+FACN8uD,OAAQ,0CACRlsD,UAAWyC,IAASs7B,EAAAA,GAA2ByS,UAAY,SAAW,gBAI5E/tC,IAASs7B,EAAAA,GAA2ByS,WAAa,CAC/Cj+C,GAAI,oBACJu2F,MAAO,CACL,CACEj0F,MAAO,0BACPuI,KAAM,oKACN8uD,OAAQ,wCACRlsD,UAAW,iBAIjBiJ,OAAOs/C,QACX,CAYoBygC,CAAQvmF,IACnBwmF,EAAUC,GAAkBxsF,EAAAA,SAAeisF,EAAKQ,gBAAgBN,IACjEO,EAA+BH,EAASI,YAAc,OAAStxF,GAAS,aAE9E,OACE2F,EAAAA,EAAAA,KAACC,EAAAA,IAAM,IACDtJ,EACJ0D,MAAOqxF,EACPxrF,YACE+qF,EAAKtkF,WACH3G,EAAAA,EAAAA,KAAC0kD,EAAAA,IAAO,CACNwc,gBACElhE,EAAAA,EAAAA,KAACgD,EAAAA,IAAI,CAACjM,KAAK,kBAAkB6L,UAAWo4D,IAAW,CAAE,aAA8B,eAAhB0wB,MACpEtrF,UAEDJ,EAAAA,EAAAA,KAAC2kD,EAAAA,IAAO,CAACxpD,MAAO,QAGlB6E,EAAAA,EAAAA,KAACgD,EAAAA,IAAI,CAACjM,KAAK,kBAAkB6L,UAAWo4D,IAAW,CAAE,aAA8B,eAAhB0wB,MAGvE9oF,UAAWA,EACXzC,aAAc4E,IAASs7B,EAAAA,GAA2BkiB,UAAY,iBAAmB,GACjFprD,MAAM,uBACNoI,QAASlE,UACP,GAAIkwF,EAAU,CACZ,MAAMK,QAAmBX,EAAKY,UAAUN,EAASN,MACjDW,GAAYE,KAAK,YAAY,KAC3BN,EAAeP,EAAKQ,gBAAgBN,GAAW,GAEnD,IAIR,C,yUCnLO,IAAKY,EAAyB,SAAzBA,GAAyB,OAAzBA,EAAyB,cAAzBA,EAAyB,YAAzBA,CAAyB,MAK9B,MACMC,EAA6B,IAInC,SAASC,EAAmBpkF,GACjC,OAAOA,EAAU6lB,MAAMs+D,EACzB,CCyBO,MAAMpiC,EAAuBtuD,IAA6D,IAA5D,MAAE69B,EAAK,IAAE6e,EAAG,MAAE16C,EAAK,UAAEuK,GAAkCvM,EAC1F,MAAM4wF,EAAa/yD,EAAQA,EAAMgzD,UAAY,IAAO,EAC9CC,EAAWp0C,EAAIm0C,UAAY,IAE3BE,EAAqB/uF,EAAMyyB,SAASzyB,EAAMyyB,SAASn8B,OAAS,GAClE,IAAI04F,EAAsBD,EACtB1iC,EAAmB,EACvB,GACE,CAACvN,EAAAA,GAAcmwC,GAAInwC,EAAAA,GAAcowC,IAAIz+D,SAASlmB,IAC9CvK,EAAMkJ,aAAeC,EAAAA,GAAWC,MAEhCijD,EAAmBrsD,EAAMqrC,sBACpB,CACL,IAAI8jD,GAAwB,EAY5B,GAXAH,GAAuB,EACvBhvF,EAAM69B,KAAKj/B,SAAQ,CAACwwF,EAAW92F,KAZL82F,IAAsBA,GAAaR,GAAcQ,GAAaN,EAalFO,CAAmBD,MACS,IAA1BD,IACFA,EAAuBnvF,EAAMyyB,SAASn6B,IAExC02F,EAAsBhvF,EAAMyyB,SAASn6B,GACvC,IAEF+zD,EAAmB2iC,EAAsBG,EAAuB,GAElC,IAA1BA,IAAwD,IAAzBH,EACjC,MAAO,CAAE3iC,iBAAkB,EAAGijC,gBAAiB,EAEnD,CAEA,MAAO,CAAEjjC,mBAAkBijC,gBAAiBP,EAAqBC,EAAqB,EAG3EO,EAA4B9wF,IAON,IAPO,kBACxCy2E,EAAiB,MACjBr5C,EAAK,IACL6e,EAAG,MACH16C,EAAK,WACLS,EAAU,kBACV+uF,GAC4B/wF,EAC5B,MAAM,iBAAE4tD,EAAgB,gBAAEijC,GAAoBhjC,EAAqB,CACjEzwB,QACA6e,MACA16C,QACAuK,UAAW9J,EAAW8J,YAExB,GAAyB,IAArB8hD,EACF,MAAO,CAAErhB,WAAYvqC,EAAWuqC,WAAY1pB,WAAY7gB,EAAW6gB,YAGrE,MAAMja,EAAc5G,EAAWwpB,eACzB+gB,GAAaiqC,EAAAA,EAAAA,IAA8B,CAC/C5tE,cACA6tE,oBACA7oB,iBAAkBmjC,GAAqBnjC,IAEnCvhB,GAAWC,EAAAA,EAAAA,IAAsB,CAAE1jC,cAAa2jC,eAUtD,MAAO,CAAEA,aAAY1pB,WARnB0nC,EAAc,CACZhpD,QACAS,aACA4pB,OAAQ,CAAC,EACTygB,WACA2kD,mBAAoBD,IAEtBF,EAAkBxkD,EACa,EAGtByhB,EAAwBpoD,IAAmD,IAAlD,UAAEoG,EAAS,MAAEvK,GAAgCmE,EACjF,MAAMurF,EAAc1vF,EAAM2vF,iBACpBpsD,GAAWsoB,EAAAA,EAAAA,IAAsB7rD,EAAM69B,KAAK79B,EAAM69B,KAAKvnC,OAAS,IAEtE,GAAIiU,EAAUkmB,SAASi+D,GAA6B,CAClD,MAAMjsD,EDlGH,SAAqCzkC,GAAqE,IAApE,UAAEuM,EAAS,WAAEf,GAAqDxL,EAC7G,MAAO4xF,EAAiBC,GAAkBlB,EAAmBpkF,GAE7D,GAAIqlF,IAAoBnB,EAA0BqB,MAAO,CACvD,MAAOC,EAAgBC,GAAgBH,EAAengF,QAAQ,KAAM,KAAK0gB,MAXzC,KAY1B6/D,EAAWF,EAAiB,IAAIzzF,KAAKyzF,GAAkB,KACvDG,EAASF,EAAe,IAAI1zF,KAAK0zF,GAAgB,KACvD,MAAO,CACLn0D,MAAOo0D,IAAa91E,OAAOkS,MAAM4jE,EAASpB,WAAaoB,EAAW,KAClEv1C,IAAKw1C,IAAW/1E,OAAOkS,MAAM6jE,EAAOrB,WAAajP,EAAAA,EAAiBsQ,GAAU,KAEhF,CAEA,GAAIN,IAAoBnB,EAA0B0B,KAAM,CACtD,MAAOC,EAAOj2C,EAAQqG,GAAQqvC,EAAez/D,MApBb,KAoBgDrsB,IAAIoW,QAEpF,MAAI,CAACi2E,EAAOj2C,EAAQqG,GAAMhiD,KAAK2b,OAAOkS,OAC7B,CAAEwP,MAAO,KAAM6e,IAAK,MAGtB,CACL7e,MAAO+jD,EAAAA,EAAmBA,EAAAA,EAAYp2E,EAAY,CAAE4mF,QAAOj2C,SAAQqG,KAAMA,EAAO,KAChF9F,IAAKlxC,EAET,CAEA,MAAO,CAAEqyB,MAAO,KAAM6e,IAAKlxC,EAC7B,CCuEkB6mF,CAA6B,CAAE9lF,YAAWf,WAAY+5B,IAC9DmX,GAAM41C,EAAAA,EAAAA,IACV7tD,EAAMiY,KAAOjY,EAAMiY,IAAIm0C,WAAatrD,EAASsrD,UAAYpsD,EAAMiY,IAAMnX,GACrE,GAEF,MAAO,CACL1H,MAAO4G,EAAM5G,QAASy0D,EAAAA,EAAAA,IAAqB7tD,EAAM5G,OAAO,GACxD6e,MAEJ,CAEA,IAAI7e,EAEJ,OAAQtxB,GACN,KAAKu0C,EAAAA,GAAcmwC,GACjB1rD,EAASgtD,SAAS,GAAI,GAAI,GAAI,KAC9B10D,EAA+B,IAAvB6zD,EAAYp5F,OAAeitC,EAAWmsD,EAAYA,EAAYp5F,OAAS,GAC/E,MACF,KAAKwoD,EAAAA,GAAcowC,GACjB3rD,EAASgtD,SAAS,GAAI,GAAI,GAAI,KAC9B,MAAMC,EAAwC,IAAvBd,EAAYp5F,QAAgB,EAAIof,KAAKwF,IAAIw0E,EAAYp5F,OAAS,EAAG,GACxFulC,GAA4B,IAApB20D,EAAwBjtD,EAAWmsD,EAAYc,GACvD,MACF,KAAK1xC,EAAAA,GAAc2xC,GACjB50D,EAAQ+jD,EAAAA,EAAkBr8C,EAAU,GACpC,MACF,KAAKub,EAAAA,GAAc4xC,GACjB70D,EAAQ+jD,EAAAA,EAAkBr8C,EAAU,GACpC,MACF,KAAKub,EAAAA,GAAc6xC,GACjB90D,EAAQ+jD,EAAAA,EAAkBr8C,EAAU,GACpC,MACF,KAAKub,EAAAA,GAAc8xC,IACjB/0D,EAAQ+jD,EAAAA,EAAoBr8C,GAC5B,MACF,KAAKub,EAAAA,GAAc1qC,GACjBynB,EAAQ+jD,EAAAA,EAAiBr8C,EAAU,GACnC,MACF,KAAKub,EAAAA,GAAcxqC,GACjBunB,EAAQ+jD,EAAAA,EAAiBr8C,EAAU,GACnC,MACF,KAAKub,EAAAA,GAAc+xC,GACjBh1D,EAAQ+jD,EAAAA,EAAiBr8C,EAAU,GACnC,MACF,KAAKub,EAAAA,GAAc5jC,IACnB,QACE2gB,EAAQ,KAIZ,MAAO,CAAEA,MAAOA,IAASy0D,EAAAA,EAAAA,IAAqBz0D,GAAO,GAAQ6e,KAAK41C,EAAAA,EAAAA,IAAqB/sD,GAAU,GAAQ,EAa9F8oC,EAAsBtmE,IAU7B,IAV8B,cAClCumE,EAAa,WACb7rE,EAAU,SACVqqC,GAAWC,EAAAA,EAAAA,IAAsB,CAAEC,WAAYvqC,EAAWuqC,WAAY3jC,YAAa5G,EAAWwpB,iBAAiB,SAC/GwI,GAMD1sB,EACC,MAAM,cAAEwrB,GAAkB9wB,EAAWiU,yBAC/B7W,EAAQ4C,EAAW5C,MAAQ0zB,EAAczU,KAAKjf,MAAQ0zB,EAAc3U,MAAM/e,MAC1EizF,EAAkBp7E,KAAK+E,MAAM5c,EAAQitC,GAE3C,QAASzpC,EAAAA,GAAM0Z,IAAI+vB,EAAW,EAAGzpC,EAAAA,GAAM6Z,IAAIoxD,EAAezuE,GAD9CvF,EACyDm6B,EAAWq+D,EADlDx4F,EAAQwyC,KAA1BxyC,KACsF,EAqB7F,SAASy4F,EAAsBpgE,GAcnC,IAdoC,iBACrCqgE,EAAgB,mBAChBC,EAAkB,aAClBC,EAAY,eACZC,EAAc,SACdC,EAAQ,aACRC,GAQD1gE,EACC,MAAM2gE,EAjCD,SAA0B5gE,GAU9B,IAV+B,eAChCygE,EAAc,aACdD,EAAY,iBACZF,EAAgB,mBAChBC,GAMDvgE,EACC,MAEM6gE,EAA8E,IAAvD,KAFAL,EAAepwC,EAAAA,GAA8B,IAC3CqwC,EAAiBrwC,EAAAA,GAA8B,IAG9E,OAAO7N,EAAAA,GAAanQ,EAAImQ,EAAAA,GAAaC,IAAOq+C,EAAsBP,EAAoBC,CACxF,CAiByBO,CAAkB,CAAEN,eAAcC,iBAAgBF,qBAAoBD,qBAGvFS,EADuD,GAA9B3wC,EAAAA,GACckwC,EAAoBC,EAE3DS,EACJL,GAAgBF,GAAkBD,GAAgBE,GAFvBE,EAAiBG,GAE0CL,EAAWE,EAEnG,MAAO,CACLA,iBACAG,WAAYC,EAAkBD,EAAa,EAC3CE,qBAAsBD,EAAkBJ,EAAiBG,EAAaH,EACtEM,iBAXuB,GAa3B,CAEO,MAAM5oC,EAAgBp4B,IAQH,IARI,MAC5B5wB,EAAK,WACLS,EAAU,OACV4pB,EAAM,SACNygB,GAAWC,EAAAA,EAAAA,IAAsB,CAAEC,WAAYvqC,EAAWuqC,WAAY3jC,YAAa5G,EAAWwpB,iBAAiB,SAC/GwI,EAAWjB,EAAYxxB,GAAM,mBAC7ByvF,EAAkB,6BAClBlb,GAA+B,GACZ3jD,EACnB,MAAM,cAAEW,GAAkB9wB,EAAWiU,yBAC/B7W,EAAQ4C,EAAW5C,MAAQ0zB,EAAczU,KAAKjf,MAAQ0zB,EAAc3U,MAAM/e,MAC1E6J,EAA6BjH,EAAWwpB,eAAeviB,2BAC7D,GAAI2iB,GAAQmrD,QACV,OAAO,EAET,GAAIxzC,EAAqBt6B,GACvB,OAAOojC,EAET,MAAMtyB,EAAMlgB,GAAkBA,EAAQwyC,EACtC,IAAIxpB,EAAazjB,EAAQ2a,EAAGia,GAAY/c,KAAK2E,MAAMywB,EAAW,GAE9D,GADAxpB,EAAa5L,KAAK2E,MAAMhZ,EAAAA,GAAM0Z,IAAI+vB,EAAW,EAAGzpC,EAAAA,GAAM6Z,IAAIoG,EAAYzjB,EAAQ2a,EAAGia,EAAW,OAE1F8hD,GACAsd,EAAsB,CACpB7xF,QACAyvF,qBACA/nF,6BACA6C,UAAW9J,EAAW8J,YAExB,CACA,IAAIunF,EAAqB,EACrBrC,EACFqC,EAAqBp8E,KAAKg1B,KAAK+kD,EAAqBzvF,EAAM+rC,gBAC9B,KAAnB/rC,EAAMqqC,UAAmB5pC,EAAW8J,YAAcu0C,EAAAA,GAAcowC,GACzE4C,EAAqB,EACO,KAAnB9xF,EAAMqqC,SACfynD,EAAqB,EACO,KAAnB9xF,EAAMqqC,SACfynD,EAAqB,GACO,KAAnB9xF,EAAMqqC,SACfynD,EAAqB,GACO,MAAnB9xF,EAAMqqC,SACfynD,EAAqB,GACO,MAAnB9xF,EAAMqqC,SACfynD,EAAqB,GACZ9xF,EAAMqqC,SAAW,MAC1BynD,EAAsB9xF,EAAMqqC,SAAW,GAAM,IAE/C,MAAM,WAAEonD,EAAU,iBAAEG,GAAqBb,EAAuB,CAC9DG,aAAclxF,EAAMoqD,UACpB+mC,eAAgBnxF,EAAMqqD,YACtB4mC,mBAAoBnmD,EACpBkmD,iBAAkBhxF,EAAMqqC,SACxB+mD,SAAU3wF,EAAW5C,MACrBwzF,cAAe5wF,EAAW8J,YAK5B,GAHsBunF,EAAqB9xF,EAAM+rC,eAAkBjB,EAAW2mD,GAGzD5zF,EAAQ,EAAG,CAC9B,MAAMk0F,EAAgB/xF,EAAM69B,KAAKznC,OAASgqC,EAAAA,GAAAA,sBAA4BpgC,EAAM69B,KAAKznC,QAAW,KAEtF47F,GAAgB14F,OAAOC,KAAKyG,EAAMkrC,kBAAkB50C,OAASw7F,GAAsB9xF,EAAM+rC,eACzFkmD,GAAmBF,GAAe52F,YAAc,IAAMy2F,EAAmBH,EAAa,EAI5FnwE,EAAa5L,KAAK2E,OAAO7B,EAAGw5E,GAAgBt8E,KAAKwF,IAAI,KAAM4vB,EAAW,KAAOmnD,CAC/E,CACF,CAEA,OAAIvqF,IAA+Bq7B,EAAAA,GAA2BC,UACrD1hB,EAEF+qD,EAAoB,CACzBC,cAAehrD,EACf7gB,aACAqqC,WACArY,YACA,EAGSjB,EAAexxB,GAAiBA,GAAOwxB,YAAYxxB,EAAM2jC,MAAMrtC,OAAS0J,EAAM2jC,KAAKrtC,OAAS,EAAI,IAAM,EAEtG0rC,EAAwBt6B,GACnCA,IAA+Bq7B,EAAAA,GAA2BoR,WAe/C09C,EAAwBxpD,IAKH,IALI,MACpCroC,EAAK,UACLuK,EAAS,mBACTklF,EAAkB,2BAClB/nF,GAC2B2gC,EAC3B,MAAM6pD,EAAkBlyF,EAAMq0E,YAAcr0E,EAAMkJ,aAAeC,EAAAA,GAAWC,MACtE+oF,IAAwB5nF,GAAa,CAACu0C,EAAAA,GAAcmwC,GAAInwC,EAAAA,GAAcowC,IAAIz+D,SAASlmB,GACnF6nF,EAAc1qF,IAA+Bq7B,EAAAA,GAA2BC,UACxEqvD,EAA6BD,IAAgB7nF,EAC7C+nF,EAA+BF,GAAeD,EAC9CI,EAA2BH,GAAe3C,EAE1C9yB,EAAcj1D,IAA+Bq7B,EAAAA,GAA2BkiB,UACxEutC,EAA6B71B,IAAgBpyD,EAC7CkoF,EAA+B91B,GAAew1B,EAC9CO,EAA2B/1B,GAAe8yB,EAE1Cld,EAAc7qE,IAA+Bq7B,EAAAA,GAA2ByS,UAG9E,OACE08C,IACCG,GACCC,GACAC,GACAC,GACAC,GACAC,GAT6BngB,GAAe4f,GACf5f,GAAekd,EAUnB,EAWlBjuD,EAAO+H,IAAuD,IAAtD,UAAEq9B,EAAS,MAAE/oE,EAAK,OAAEC,EAAM,SAAEywE,GAAqBhlC,EACpE,MAAM4E,EAAetwC,EAAQ0wE,EAASzxD,KAAKjf,MAAQ0wE,EAAS3xD,MAAM/e,MAC5DuwC,EAAgBtwC,EAASywE,EAAS5xD,IAAI7e,OAASywE,EAAS1xD,OAAO/e,OACrE8oE,EAAUrxD,YACVqxD,EAAU5sC,KAAKu0C,EAASzxD,KAAKjf,MAAO0wE,EAAS5xD,IAAI7e,OAAQqwC,EAAcC,GACvEw4B,EAAUplC,MAAM,EAGLgtC,EAAepxE,IAC1B,MAAM,cAAEm0B,EAAa,kBAAEI,GAAsBv0B,EAAU2C,QAAQ2U,yBAC/D,IAAK,MAAMvc,KAAWiF,EAAU2O,WAAW1T,MACzC,GAAIF,EAAQy5B,cACV,OAAOD,EAGX,OAAOJ,CAAa,EAUhBohE,EAA8B9lB,IAClC,MAAM7sE,EAAQ6sE,EAAa9jD,OAAOhpB,QAAQC,QAE1C,OAAOA,EAAMC,YAAY3J,OAAS,IAAM,CAAC+nC,EAAAA,GAAUW,EAAGX,EAAAA,GAAUX,GAAGjN,SAASzwB,EAAM8K,UAAU,EAGjF48D,EAAe39B,IAAkD,IAAjD,WAAEtpC,EAAU,UAAErD,GAA8B2sC,EACvE,MAAM,cAAExY,EAAa,kBAAEI,EAAiB,wBAAEsnB,GAA4Bx4C,EAAWiU,yBAC3ErN,EAAc5G,EAAWwpB,eACzBgnE,GAAqBlmD,EAAAA,EAAAA,IAAsB,CAAE1jC,cAAa2jC,WAAYvqC,EAAWuqC,aACvF,IAAK,MAAM6hC,IAAgB,IAAIzvE,EAAUinD,oBAAqBjnD,EAAUwsD,mBAAkB,IAAS,CACjG,MAAMrxD,EAAKs0E,EAAa/sE,SAClBuhD,EAAUwrB,EAAaxrB,UAC7B,GAAIA,GAAWwrB,EAAaj7C,cAAe,CACzC,IAAIpZ,EAAc+1D,EAAwF1wE,EAC1G,MAAM+0F,EAAYvxC,EAAU5gD,EAAW+M,MAAQE,EAAAA,GAAUC,OAEvD4gE,EADEltB,EACS5gD,EAAWyI,aAAeC,EAAAA,GAAWq/B,gBAAkByQ,EAA0B1nB,EAEjFI,EAEb,MAAMyc,EAAgBhxC,EAAUU,OAASywE,EAAS5xD,IAAI7e,OAASywE,EAAS1xD,OAAO/e,OAE3E2C,EAAW+0E,SACb33E,EAAQ4C,EAAW5C,MAAQ0wE,EAASzxD,KAAKjf,MAAQ0wE,EAAS3xD,MAAM/e,MAChE2a,EAAK0tB,EAAAA,MAEFzD,MAAM,CAAC,EAAG5kC,IACV4b,OAAO,CAAC,EAAG/D,KAAKwF,IAAI,EAAGza,EAAWT,QAAQyxB,MAAMn7B,OAAS,OAE5DkiB,EAAOlgB,GAAkBA,EAAQ24F,EACjCz4E,EAAG+J,OAAU1N,GAAcA,EAAIo8E,EAC/Bz4E,EAAG3a,MAAQ,SAAUmhC,GACnB,OAAO3oC,KAAKksB,OAAOyc,GAAK3oC,KAAKksB,OAAO,EACtC,GAEFnlB,EAAU2oC,gBAAgB,QAAS,CAAElxB,EAAG2D,IAExC,MAAM,IAAEuC,EAAG,IAAEG,GAAQ9d,EAAU0oC,YAAcvtC,EAAGotC,YAChD,IAAIltB,EAEJ,MAAMo6E,EAAqBA,CAACC,EAAwBC,KAClD,GAAI1xC,GAAWsxC,EAA2B9lB,GAAe,CACvD,MAAMmmB,EAAoB5kD,EAAgBnvC,EAAAA,GACpCg0F,EAAQH,EAAa/3E,GACrBtB,EAASq5E,EAAar5E,SAC5B,GAAIw5E,EAAQD,EAAmB,CAC7B,MACME,EADYH,IAAetwD,MAAM,CAAC,EAAGuwD,IAAoBv5E,OAAO,CAACyB,EAAKH,IAC9CwH,OAAO6rB,GACrC0kD,EAAar5E,OAAO,CAACA,EAAO,GAAIy5E,GAClC,CACF,GAGF,GAAQN,IACDllF,EAAAA,GAAUK,YACb0K,EAAKytB,EAAAA,MAAiBzD,MAAM,CAAC,EAAG2L,IAAgB30B,OAAO,CAACyB,EAAKH,IAC7D83E,EAAmBp6E,EAAIytB,EAAAA,UAGvBztB,EAAKytB,EAAAA,MAAiBzD,MAAM,CAAC,EAAG2L,IAAgB30B,OAAO,CAACyB,EAAKH,IACxD3d,EAAU0oC,aACbrtB,EAAKA,EAAG0tB,KAAK,IACb0sD,EAAmBp6E,EAAIytB,EAAAA,MAI7BztB,EAAG3a,OAAS,SAAUmY,GACpB,OAAO5f,KAAKksB,OAAOtM,GAAK5f,KAAKksB,OAAO,EACtC,EACAnlB,EAAU2oC,gBAAgB,QAAS,CACjClxB,EAAG2D,EACH1D,EAAG2D,IAGD4oC,GACF9oD,EAAG+7C,UAAW97B,GAEhB,KACF,CACF,GAIWqU,EAA0BxX,GAAuBA,EAAY,GAAM,EAAI,EAAI,GAW3ED,EAAsBo2B,IAAsD,IAArD,UAAEn2B,EAAS,GAAElB,EAAE,GAAEC,EAAE,GAAEC,EAAE,GAAEC,GAAuBk3B,EAElF,OAAIn2B,EAAY,GAAM,EACb,CAAER,EAAG,EAAGC,EAAG,GAEhBV,IAAOE,EACF,CAAEO,EAAG,EAAGC,EAAG,IACTX,IAAOE,EACT,CAAEQ,EAAG,GAAKC,EAAG,GAEb,CAAED,EAAG,GAAKC,EAAG,GACtB,EAGWI,EAA0C2S,IACrD,MAAMsrE,EAAU75F,OAAOuK,QAAgBgkB,GACvC,IAAK,IAAItP,EAAI,EAAGA,EAAI46E,EAAQ78F,OAAQiiB,IAClC46E,EAAQ56E,GAAG,GAAK7C,KAAK2E,MAAM84E,EAAQ56E,GAAG,IAExC,OAAOjf,OAAO85F,YAAYD,EAAQ,EAcvB5tD,EAAesG,IAAA,IAAC,QAAE92B,EAAO,QAAE+Q,EAAO,QAAEC,GAAqB8lB,EAAA,MAAqB,CACzFrG,GAAIA,IAAMzwB,EAAQO,UAAUwQ,EAASC,GACrCuhB,KAAMA,IAAMvyB,EAAQO,WAAqB,EAAXwQ,GAAyB,EAAXC,GAC7C,EAOYmf,EAAyB8G,IAAA,IAAC,OAAEzY,EAAM,KAAE4R,GAA6B6G,EAAA,OAAOzY,EAAS4R,GAAQA,EAAQ,GAAG,EAEpGmB,EAAyB4F,IAAA,IAAC,OAAE3Y,EAAM,KAAE4R,GAA6B+G,EAAA,OAAM3Y,EAAS,IAAO4R,EAAOA,CAAI,EAOxG,SAASswC,EAAkCnpC,GAAiE,IAAhE,WAAE7rC,EAAU,MAAET,GAAgDssC,EAC/G,MAAM,cAAE/a,GAAkB9wB,EAAWiU,yBAC/BwgE,EAAoBz0E,EAAW5C,OAAS0zB,EAAczU,KAAKjf,MAAQ0zB,EAAc3U,MAAM/e,QAEvF,MAAEg+B,EAAK,IAAE6e,EAAG,kBAAE80C,GD/ff,SAAmC/wF,GAA4D,IAA3D,UAAE8L,EAAS,MAAEvK,GAA4CvB,EAClG,MAAM40F,EAAc9mC,EAAsB,CAAEhiD,YAAWvK,WAChD4vF,GAAmBjB,EAAmBpkF,GAE7C,IAAI+oF,EAA8B,KAC9BC,EAA4B,KAC5BC,EAAmC,KAEvC,GAAIH,EAAYx3D,OAAS+zD,IAAoBnB,EAA0B0B,KAAM,CAC3E,MACMsD,EAAsB,IADRzzF,EAAM2vF,kBACmB/lD,UACvC8pD,EAAqBD,EAAoBv7F,WAAW2lC,GAASA,EAAKgxD,WAAawE,EAAYx3D,MAAOgzD,YAClG8E,EAAmBF,EAAoBv7F,WAAW2lC,GAASA,EAAKgxD,WAAawE,EAAY34C,IAAKm0C,YACpGyE,EAAiBG,EAAoBC,IAAuB,KAC5DH,EAAeE,EAAoBE,IAAqB,KACxDH,EAAoBxzF,EAAMqqC,UAAY,EAAIqpD,EAAqBC,EAAmB,EAAI,IACxF,CAEA,MAAO,CACL93D,MAAOw3D,EAAYx3D,MACnB6e,IAAK24C,EAAY34C,IACjB44C,iBACAC,eACAC,oBACAhE,mBAAoBgE,GAAqB,IAAMxzF,EAAM+rC,gBAAkB,SAAMrtC,EAC7Ek1F,gBAAiBP,EAAYx3D,OAAS+jD,EAAAA,EAAmByT,EAAYx3D,OACrEg4D,cAAeR,EAAY34C,KAAOklC,EAAAA,EAAiByT,EAAY34C,KAEnE,CCme4Co5C,CAA2B,CACnEvpF,UAAW9J,EAAW8J,UACtBvK,WAGI,WAAEgrC,EAAU,WAAE1pB,GAAeiuE,EAA0B,CAC3Dra,oBACAr5C,QACA6e,MACA16C,QACAwvF,oBACA/uF,WAAYA,IAGVA,EAAWuqC,aAAeA,GAAcvqC,EAAW6gB,aAAeA,GACpE7gB,EAAW+F,iBAAiB,CAAEwkC,aAAY1pB,cAE9C,CAEO,SAASssD,EAAU79B,GAYvB,IAZwB,iBACzBrrC,EAAgB,WAChBjE,EAAU,UACVrD,EAAS,UACTwpE,EAAS,kBACTmtB,GAAoB,GAOrBhkD,EACK3yC,EAAU2C,QAAQmJ,aAAeC,EAAAA,GAAWq/B,gBAC9Co+B,EAAUqH,UAAU,EAAG,EAAGxtE,EAAW5C,MAAOT,EAAUU,SAEtD8oE,EAAUpxD,IAAI,YAAa/U,EAAWiU,yBAAyB6c,cAAc2Q,QAAQttB,OAAOu8B,YAC5Fy1B,EAAUzzC,SAAS,EAAG,EAAG1yB,EAAW5C,MAAOT,EAAUU,SAEvD,MAAMiO,EAAW3O,EAAUinD,iBAC3B,IAAK,MAAQvkD,SAAUuuE,KAAqBtiE,EACA,mBAA/BsiE,EAAgBxsC,aACzB+kC,EAAU5gD,OACVqoD,EAAgBxsC,WAAW+kC,GAC3BA,EAAU1gD,WAId,MAAMjmB,EAAc7C,EAAUwsD,oBACxB2kB,EAAWC,EAAYpxE,GAC7B,IAAK,MAAQ0C,SAAUuuE,IAAqB,IAAItiE,KAAa9L,GAAc,CACzE,MAAMqkD,EAAY+pB,EAAgBhlD,eAC5BwgC,EAAewkB,EAAgB5lD,oBAEjC67B,IAAc5/C,EAAiBu8E,sBAAyB5S,EAAgBlkD,oBAEhEm6B,IAAauF,GAAkBwkB,EAAgBhtD,iBAAiB5gB,MAI5EmmE,EAAU5gD,OAC2B,MAAjCqoD,EAAgBt6D,eAClB6yD,EAAU5gD,OACVwb,EAAK,CACHolC,YACA/oE,MAAO4C,EAAW5C,MAClBC,OAAQV,EAAUU,OAClBywE,aAEF3H,EAAUtxD,UAAUlY,EAAU2C,QAAQuhB,WAAaitD,EAASzxD,KAAKjf,MAAO0wE,EAAS5xD,IAAI7e,QACrFuwE,EAAgBt6D,cAAc6yD,GAC9BA,EAAU1gD,UACkC,mBAAjCmoD,EAAgB38C,cACzB28C,EAAgB38C,aAAak1C,IAG/ByH,EAAgBnwD,OAAO0oD,GAGvBmtB,IACCrvF,EAAiBgD,6BAA+Bq7B,EAAAA,GAA2ByS,YAC1EY,EAAAA,EAAAA,IAAiB1xC,KACY,MAA/B2pE,EAAgBpgC,aAEhBogC,EAAgBpgC,YAAY24B,GAE9BA,EAAU1gD,WACZ,CACF,C,wDChpBO,MAAM8tE,EAAiB,CAC5Bj5E,IAAK,IACLG,IAAK,KAGA,IAAKvM,EAAgB,SAAhBA,GAAgB,OAAhBA,EAAAA,EAAgB,uBAAhBA,EAAAA,EAAgB,2BAAhBA,CAAgB,K,kFCe5B,MAAMslF,EAAsC,CAC1CC,aAAc,KACdvuC,QAAQ,EACRwuC,gBAAgB,EAChBnsD,UAAWr5B,EAAAA,EAAiBw1E,WAC5BtmF,MAAOm2F,EAAAA,EACPviE,MAAOA,OACP2iE,SAAUA,OACVC,aAAcA,QAGHC,EAAiB5yF,EAAAA,cAAwCuyF,GACzDM,EAAoBA,IAAM7yF,EAAAA,WAAiB4yF,E,qFC5BjD,SAASE,EAAiBn7F,GAC/B,OACEqJ,EAAAA,EAAAA,KAAC+xF,EAAAA,IAAoB,IACfp7F,EACJQ,MAAM,iBACN+9D,QAAQ,2FAGd,C,gDCZO,MAAM88B,EAAgC,CAC3Cr2F,SAAUA,IAAM,gCAChBZ,SAAU,uB,2DCIL,IAAKk3F,EAAa,SAAbA,GAAa,OAAbA,EAAa,sBAAbA,CAAa,MAgBlB,MAAMC,EAA2Dt7F,OAAOitB,OAAO,CACpF,CAACouE,EAAcE,WAAY,CACzB7wF,IAAK2wF,EAAcE,UACnBvmC,KAAM,YACNwmC,YAAa,sBACbC,QCrBG,SAELC,GAA2F,IAA5BC,EAAkBx9F,UAAAnB,OAAA,QAAAoI,IAAAjH,UAAA,IAAAA,UAAA,GACjF,OAAO,WACL,MAAOy9F,EAAkBC,GAAuBzzF,EAAAA,UAAe,IACxD0zF,GAAe,QAAEjjF,KAAaR,EAAAA,EAAAA,GAAe,IAC/CqjF,EACHjjF,gBAAgB,IAGZ4iF,EAAgBS,GAAeh6E,QAErC,OAAIjJ,GACKzP,EAAAA,EAAAA,KAAC8xF,EAAAA,EAAgB,KAIxBnvF,EAAAA,EAAAA,MAAAiC,EAAAA,SAAA,CAAAxE,SAAA,EACIoyF,GAAoBD,IACpBvyF,EAAAA,EAAAA,KAAC0kD,EAAAA,IAAO,CAAAtkD,UACNJ,EAAAA,EAAAA,KAAA,OAAK4C,UAAU,iDAAgDxC,UAC7DJ,EAAAA,EAAAA,KAAC2kD,EAAAA,IAAO,UAIXstC,IAAiBjyF,EAAAA,EAAAA,KAACiyF,EAAa,CAACQ,oBAAqBA,MAG9D,CACF,CDRaE,CAAoBX,GAA+B,GAC5D72F,MAAO,CAAEkd,IAAK,IAAKK,QAAS,CAAEk6E,OAAQ,Q,iJEpBnC,MAAM5Y,EAAwB,iBAMtB,SAAS6Y,EAAWv3F,GAAkC,IAAjC,UAAEsH,GAA6BtH,EACjE,MAAM,OAAE2nD,EAAM,UAAE3d,EAAS,aAAEksD,EAAY,aAAEG,IAAiBE,EAAAA,EAAAA,KACpDtI,GAAeC,EAAAA,EAAAA,KAAgB,CAAElnF,UAAW,OAAQwwF,YAAa,MAEvE,OACEnwF,EAAAA,EAAAA,MAAA,OACEC,UAAWo4D,IACT,iIACA,CACE,WAAY/X,GAAU3d,IAAcr5B,EAAAA,EAAiB8mF,SACrD,sBAAuBztD,IAAcr5B,EAAAA,EAAiB8mF,SACtD,WAAYztD,IAAcr5B,EAAAA,EAAiBw1E,YAE7C7+E,GACAxC,SAAA,CAGDklC,IAAcr5B,EAAAA,EAAiBw1E,aAC9BzhF,EAAAA,EAAAA,KAAA,OACEnL,GAAImlF,EACJ,cAAc,GAAEA,QAChBp3E,UAAU,+BAIbhM,OAAOuK,QAAQ+wF,EAAAA,GAAgB7wF,KAAItF,IAAkB,IAAhBuF,EAAKC,GAAMxF,EAC/C,MAAMg8E,EAAWyZ,GAAclwF,MAAQA,EACvC,OACEqB,EAAAA,EAAAA,MAAC3D,EAAAA,SAAc,CAAAoB,SAAA,EACbJ,EAAAA,EAAAA,KAAC8pF,EAAAA,IAAc,CACb/oB,WAAS,EACTvlD,QACExb,EAAAA,EAAAA,KAACC,EAAAA,IAAM,CACL8C,WAAW,SACXI,KAAK,SACLK,OAAQu0E,EACR19E,MAAM,kBACNkF,QAASA,KACPoyF,EAAa5Z,OAAW/7E,EAAYuF,EAAMD,IAAI,EAEhDsB,UAAWo4D,IAAW,CAAE,OAAQ11B,IAAcr5B,EAAAA,EAAiBw1E,aAC/D,cAAc,WAAUngF,QAAUlB,UAElCJ,EAAAA,EAAAA,KAACgD,EAAAA,IAAI,CAACjM,KAAMwK,EAAMqqD,KAAMzwD,MAAO,GAAIyH,UAAU,eAGjDtI,MAAOivF,EACP,aAAYhoF,EAAM6wF,YAClBY,eAAa,KAGfhzF,EAAAA,EAAAA,KAAC8qF,EAAAA,IAAO,CAACxwF,MAAOivF,EAAanpF,UAC3BJ,EAAAA,EAAAA,KAACkD,EAAAA,IAAS,CAACC,KAAK,QAAO/C,SAAEmB,EAAM6wF,kBAxBd9wF,EA0BJ,MAK3B,C,2NC9De,SAAS2xF,EAAc33F,GAAoC,IAAnC,SAAE8E,GAA+B9E,EACtE,MAAM,UAAEgqC,EAAS,SAAEosD,EAAQ,MAAE3iE,EAAK,MAAE5zB,IAAU02F,EAAAA,EAAAA,KACxCztF,EAAWjJ,GAAOkd,KAAOi5E,EAAAA,EAAej5E,IACxCq2E,EAAWvzF,GAAOqd,KAAO84E,EAAAA,EAAe94E,IACxC06E,EAAgB/3F,GAAOud,SAASk6E,QAAUxuF,EAC1C+uF,EAAiBh4F,GAAOud,SAAS06E,SAAW1E,EAElD,OACE/rF,EAAAA,EAAAA,MAAAiC,EAAAA,SAAA,CAAAxE,SAAA,CACGklC,IAAcr5B,EAAAA,EAAiB8mF,WAC9B/yF,EAAAA,EAAAA,KAACqzF,EAAAA,EAAS,CACRjvF,SAAUA,EACVsqF,SAAUA,EACV4E,OAAQ,CACNl5E,KAAMjf,GAAOkd,MAAQld,GAAOqd,KAAOpU,EAAWsqF,GAEhD6E,cAAe,CACbn5E,KAAM,wDAERxX,UAAU,6BACV8uF,SAAUA,EACV8B,YAAa,CACXr4F,MAAOwD,EAAAA,GAAM8+B,aAAe9+B,EAAAA,GAAMD,SAAWw0F,EAAgBC,EAC7D/3F,OAAQ,QACRgF,SAEDA,IAGJklC,IAAcr5B,EAAAA,EAAiBw1E,aAC9B9+E,EAAAA,EAAAA,MAAAiC,EAAAA,SAAA,CAAAxE,SAAA,EACEJ,EAAAA,EAAAA,KAAA,OAAK4C,UAAU,mCAAmCrD,QAASwvB,KAC3D/uB,EAAAA,EAAAA,KAAA,OAAK4C,UAAU,yHAAwHxC,SACpIA,SAMb,C,eCrCO,MAAMo6E,EAAsB,UAKjCjW,EAAAA,IAAAA,YADkC,iBAYpC,IAAI7O,GAAS,EAEN,SAAS6rB,EAAOjmF,GAA6D,IAA5D,eAAEkmF,EAAc,UAAEl8C,EAAS,cAAEmuD,GAA6Bn4F,EAChF,MAAMqG,GAAWC,EAAAA,EAAAA,OACV+3E,IAAmBE,EAAAA,EAAAA,MACpB6Z,EAAoB/Z,EAAgB9yD,IAAI2zD,IAA+D,MACtGgX,EAAcmC,GAAmB30F,EAAAA,SAAyC,MAE3EikD,IAAWuuC,EACXoC,EAAqB50F,EAAAA,aACxBsC,IACC,MAAMuyF,EAAqB,IAAIpU,gBAAgB9F,GAC3Cr4E,EACFuyF,EAAmB/gF,IAAI0nE,EAAqBl5E,GAE5CuyF,EAAmBnZ,OAAOF,GAE5B74E,EAAS,CAAEI,OAAQ8xF,EAAmB37F,YAAc,CAAE8U,SAAS,GAAO,GAExE,CAAC2sE,EAAiBh4E,IAGdmyF,EAAqB90F,EAAAA,aAAkB,KAC3C40F,OAAmB53F,EAAU,GAC5B,CAAC43F,IAGJ50F,EAAAA,WAAgB,KACdwiF,GAAgB,GACf,CAACgQ,EAAchQ,IAGlBxiF,EAAAA,WAAgB,KACd,IAAI0zF,EAAgBgB,GAAoBxB,EAAAA,EAAewB,IAElDh+B,IAAU3K,EAAAA,EAAAA,QACb2nC,EAAgB,KAChBoB,KAGFH,EAAgBjB,GAChBh9B,GAAS,CAAI,GACZ,CAACg+B,EAAkBI,IAEtB,MAAMC,EAAmC/0F,EAAAA,SACvC,KAAM,CACJsmC,YACA2d,SACAwuC,eAAgBnsD,IAAcr5B,EAAAA,EAAiBw1E,WAC/CtmF,MAAOq2F,GAAcr2F,MACrBq2F,eACAE,SAAUlQ,EACVzyD,MAAO+kE,EACPnC,aAAciC,KAEhB,CAACtuD,EAAW2d,EAAQu+B,EAAgBgQ,EAAcsC,EAAoBF,IAGxE,OACEjxF,EAAAA,EAAAA,MAACivF,EAAAA,EAAet+B,SAAQ,CAAC/xD,MAAOwyF,EAAa3zF,SAAA,CAC1CoxF,IACCxxF,EAAAA,EAAAA,KAACizF,EAAc,CAAA7yF,UACbJ,EAAAA,EAAAA,KAACg0F,EAAAA,GAAa,CAACC,kBAAmBnC,EAAAA,EAAiB1xF,UACjDJ,EAAAA,EAAAA,KAAChB,EAAAA,SAAc,CACb2R,UACE3Q,EAAAA,EAAAA,KAAC0kD,EAAAA,IAAO,CAAAtkD,UACNJ,EAAAA,EAAAA,KAAA,OAAK4C,UAAU,iDAAgDxC,UAC7DJ,EAAAA,EAAAA,KAAC2kD,EAAAA,IAAO,QAGbvkD,UAEDJ,EAAAA,EAAAA,KAACwxF,EAAaa,QAAO,WAK7BryF,EAAAA,EAAAA,KAAC6yF,EAAAA,EAAW,CAACjwF,UAAW6wF,MAG9B,C,mECzGO,IAAKlsB,EAAW,SAAXA,GAAW,OAAXA,EAAW,cAAXA,EAAW,cAAXA,EAAW,kBAAXA,EAAW,cAAXA,EAAW,4BAAXA,EAAW,kBAAXA,EAAW,+CAAXA,EAAW,iCAAXA,EAAW,kBAAXA,EAAW,cAAXA,EAAW,sBAAXA,EAAW,kBAAXA,EAAW,oBAAXA,EAAW,sBAAXA,EAAW,qCAAXA,EAAW,yBAAXA,EAAW,yBAAXA,EAAW,oBAAXA,EAAW,6BAAXA,EAAW,cAAXA,CAAW,MAuBXiN,EAAc,SAAdA,GAAc,OAAdA,EAAc,mBAAdA,EAAc,iCAAdA,EAAc,oDAAdA,CAAc,MAMdW,EAAc,SAAdA,GAAc,OAAdA,EAAc,qCAAdA,EAAc,gDAAdA,EAAc,6BAAdA,EAAc,6BAAdA,CAAc,K,6FCdnB,SAASnN,EAAY7M,GAC1B,MAAQ,GAAEA,EAAWpkE,MAAQokE,EAAW57B,YAhBnC,SAA4B/4B,GACjC,OAAQA,GACN,KAAKC,EAAAA,GAAWC,MACd,MAAO,QACT,KAAKD,EAAAA,GAAWq2D,QACd,MAAO,UACT,KAAKr2D,EAAAA,GAAWs2D,MACd,MAAO,QACT,KAAKt2D,EAAAA,GAAW47B,OACd,MAAO,SACT,KAAK57B,EAAAA,GAAWq/B,gBACd,MAAO,mBAEb,CAGsDouD,CAAmB/4B,EAAW30D,yBACpF,CAEO,MAAM2tF,EAAwBC,IACnC,OAAQA,GACN,KAAKpqF,EAAAA,GAAiBG,WACpB,MAAO,aACT,KAAKH,EAAAA,GAAiBK,kBACpB,MAAO,oBACT,KAAKL,EAAAA,GAAiBO,UACpB,MAAO,OACT,KAAKP,EAAAA,GAAiBS,UACpB,MAAO,OACT,KAAKT,EAAAA,GAAiBC,YACtB,QACE,MAAO,cACX,EAGW6yE,EAAuCuX,GAC5B,OAAtBA,EACI,KACAz9F,OAAOiF,OAAOmO,EAAAA,IAAkBxM,MAC7B42F,GAAgCC,IAAsBF,EAAqBC,I,+DCZpF,QA7BA,MACEzqF,OACA6sC,IACAze,MACAx2B,MAEAzK,WAAAA,CAAY6S,GACVhW,KAAKgW,OAASA,EACdhW,KAAK6iD,IAAM,EACX7iD,KAAKokC,MAAQ,EACbpkC,KAAK4N,MAAQ,CACf,CAEA3B,GAAAA,CAAIkQ,EAAc4sB,EAAaqQ,GAC7B,MAAMunD,EAAK52D,EAAAA,GAAMllB,IAAI,CAAC1I,EAAO4sB,EAAK1pB,KAAKQ,IAAI1D,EAAOi9B,GAAY/5B,KAAKQ,IAAIkpB,EAAMqQ,KAEzEp5C,KAAKokC,MAAQpkC,KAAKgW,QACpBhW,KAAK6iD,KAAO89C,EACZ3gG,KAAK4N,MAAQ5N,KAAK6iD,KAAO7iD,KAAKokC,MAAQ,GAClCpkC,KAAKokC,QAAUpkC,KAAKgW,OAAS,IAC/BhW,KAAK6iD,KAAO7iD,KAAKgW,SAGnBhW,KAAK4N,OAAS5N,KAAK4N,OAAS5N,KAAKgW,OAAS,GAAK2qF,GAAM3gG,KAAKgW,OAE5DhW,KAAKokC,OACP,E,sHCHF,MAAMw8D,UAAoEj2F,EAAAA,EACxE4S,YAAcqqC,EAAAA,GAAeg5C,WAC7BrjF,aAAe,aAUf+xC,QAAS,EAET7oC,KAAO,EACPH,IAAM,EAENnjB,WAAAA,CAAY+E,EAAwBxG,GAClCuI,MAAM/B,EAAQxG,GACd1B,KAAKmX,MAAMnX,KAAKke,uBAClB,CAEAA,qBAAuBA,KAAA,CAASM,EAAG,CAAC,KAAMC,EAAG,KAE7C,QAAI9I,GACF,OAAQ3V,KAAKmD,YAAkCwS,IACjD,CAEA,SAAI7G,GACF,OAAQ9O,KAAKmD,YAAkC2L,KACjD,CAEA+9D,qBAAAA,GACE,OAAQ7sE,KAAK2V,MACX,KAAKiyC,EAAAA,GAAeE,UAClB,OAAOr/C,EAAAA,GAAoBq/C,UAC7B,KAAKF,EAAAA,GAAeG,MAClB,OAAOt/C,EAAAA,GAAoBs/C,MAG/B,OAAOt/C,EAAAA,GAAoBy/C,eAC7B,CAEA24C,kBAAAA,GAKE,OAJK7gG,KAAK8gG,kBACR9gG,KAAK8gG,gBAAkB9gG,KAAK0B,MAAMkI,eAAeyoB,gBAAgB,WAAYryB,OAGxEA,KAAK8gG,eACd,CAEAC,aAAAA,GACE,MAAM,IAAEz6E,EAAG,OAAEE,GAAWxmB,KAAKqe,yBAAyB6c,cAChD4lE,EAAkB9gG,KAAK6gG,sBACvB,EAAEriF,GAAMxe,KAAK2e,OACbC,GAAYC,EAAAA,EAAAA,IAAiB,CAAEL,MAC/BC,EACHze,KAAK0B,MAAoB+F,OAC1B6e,EAAI7e,OACJ+e,EAAO/e,OACPmB,EAAAA,IACCk4F,GAAiB55F,QAAU,GAAK0B,EAAAA,GAEnC,MAAO,CAAE4V,EAAGI,EAAUJ,EAAI5V,EAAAA,GAAyB,EAAG6V,IACxD,CAEAqV,YAAAA,GACE,OAAQ,CAACkU,EAAAA,GAAUW,EAAGX,EAAAA,GAAUX,GAAGjN,SAASp6B,KAAK0B,MAAMgI,QAAQC,SAAS8K,UAC1E,CAEAiJ,aAAAA,CAAcgB,GACZ,IAAK1e,KAAK8zB,iBAAmB9zB,KAAK8gG,gBAAiB,OAEnD9gG,KAAK+C,MAAMyb,EAAIa,KAAK2E,MAAMhkB,KAAK+C,MAAMyb,GACrC,MAAM9U,EAAQ1J,KAAK0B,MAAMgI,QACnBsH,EAActH,EAAMkqB,gBACpB,EAAEpV,EAAC,EAAEC,GAAMze,KAAK+gG,gBAChB/tD,EAAS,GAAKpqC,EAAAA,GACpB,GAAI4V,EAAI9U,EAAMuhB,YAAc+nB,GAAUx0B,EAAI9U,EAAMuhB,WAAavhB,EAAMlC,MAAQwrC,EACzE,OAEF,MAAMpxC,EAAO5B,KAAK8gG,gBAAgB35F,wBAAwB,CACxDT,MAAOsK,EAAYtK,MACnBC,OA7FsB8lE,EA6FIzsE,KA5F1BysE,EAAWnd,OACNhnD,EAAAA,GAAqBiyD,SAE1BkS,EAAWz6C,UACN1pB,EAAAA,GAAqB04F,MAEvB14F,EAAAA,GAAqByc,SAuFxBte,UAAWzG,KAAK6sE,0BA9FtB,IAA4BJ,EAiGxB,IAAK7qE,EAAM,OAEX,MAAM,KAAE6kB,EAAI,IAAEH,GAAQtmB,KAAKqe,yBAAyB6c,cACpDl7B,KAAKymB,KAAOjI,EAAI9U,EAAMuhB,WAAaxE,EAAKjf,MAAQoB,EAAAA,GAAyB,EACzE5I,KAAKsmB,IAAM7H,EAAI6H,EAAI7e,OACnBiX,EAAQ0nB,UAAUxkC,EAAM4c,EAAGC,EAAG7V,EAAAA,GAAwBA,EAAAA,GACxD,CAEA4pB,YAAAA,CAAaR,GACNhyB,KAAK8zB,iBAEV9zB,KAAKgyB,UAAYA,EACjBhyB,KAAK0B,MAAMkyD,4BACX5zD,KAAKuJ,QAAQ,UACf,CAGA+pD,YAAAA,CAAa2tC,GACX,MAAMjwF,EAAchR,KAAK0B,MAAMgI,QAAQkqB,eACjCktE,EAAkB9gG,KAAK6gG,qBAEvBK,EAAuBlwF,EAAYqiD,kBAAkBtpD,YAAc+2F,GAAiB/2F,UACpFulD,EAAS2xC,KAAmBC,IAAwBJ,GAAiBr3F,SAAS6lD,QACpFtvD,KAAKsvD,OAASA,EACVt+C,EAAYqiD,kBAAkB5pD,SAAS6lD,SAAW4xC,GACpDlwF,EAAYqiD,kBAAkB5pD,SAAS6pD,cAAa,IAElDhE,GAAU4xC,IACZlwF,EAAY0+B,gBAAgB,oBAAqB4f,GAAU4xC,OAAuB74F,EAAYy4F,GAGhG9gG,KAAK0B,MAAMkyD,4BACX5zD,KAAKuJ,QAAQ,SACf,CAEAoX,QAAAA,CAASC,GACP,IAAK5gB,KAAK8zB,eAAgB,OAAO,EAEjC,MAAMqtE,EAAavgF,EAAKjC,QAClB,EAAEH,EAAC,EAAEC,GAAMze,KAAK+gG,gBAMtB,OAJEviF,GAAK2iF,EAAW3iF,GAChBA,EAAI5V,EAAAA,IAA0Bu4F,EAAW3iF,GACzCC,GAAK0iF,EAAW1iF,GAChBA,EAAI7V,EAAAA,IAA0Bu4F,EAAW1iF,CAE7C,CAEAuM,gBAAAA,CAAiBthB,GACf,IAAK1J,KAAK8zB,eAAgB,OAAO,EAEjC,MAAM,EAAEtV,GAAMxe,KAAK+gG,gBAEnB,OADiBviF,EAAI5V,EAAAA,KAA2Bc,EAAMuhB,YAAczM,IAAM9U,EAAMuhB,WAAavhB,EAAMlC,KAErG,EAGF,UCtKA,MAAMsgD,UAAkB84C,EACtBrjF,YAAcqqC,EAAAA,GAAeE,UAC7BvqC,aAAesqC,EAAAA,GAAiBD,EAAAA,GAAeE,WAGjD,UCJA,MAAMs5C,UAAiBR,EACrBrjF,YAAcqqC,EAAAA,GAAew5C,SAC7B7jF,aAAesqC,EAAAA,GAAiBD,EAAAA,GAAew5C,UAE/Cv0B,qBAAAA,GACE,MAAMw0B,EAAYrhG,KAAK6gG,sBAAsBr3F,oBAE7C,IAAK63F,EACH,OAAO54F,EAAAA,GAAoBy/C,gBAG7B,QAA4B7/C,IAAxBg5F,EAAUC,gBAAqDj5F,IAA1Bg5F,EAAUE,YAA2B,CAC5E,MAAMr7F,EAAMD,KAAKC,MAAQ,IACzB,OAAOm7F,EAAUG,cAAgBt7F,EAAMuC,EAAAA,GAAoB0/C,eAAiB1/C,EAAAA,GAAoBy/C,eAClG,CACA,OAAOm5C,EAAUC,UAAYD,EAAUE,YAAc,EACjD94F,EAAAA,GAAoBw/C,iBACpBx/C,EAAAA,GAAoBu/C,gBAC1B,EAGF,UCtBA,MAAMD,UAAc64C,EAClBrjF,YAAcqqC,EAAAA,GAAeG,MAC7BxqC,aAAesqC,EAAAA,GAAiBD,EAAAA,GAAeG,OAGjD,UCFa05C,EAAoBx+F,OAAOitB,OAAO,CAC7C,CAAC03B,EAAAA,GAAeg5C,YAAan0B,EAC7B,CAAC7kB,EAAAA,GAAeE,WAAY45C,EAC5B,CAAC95C,EAAAA,GAAeG,OAAQhuB,EACxB,CAAC6tB,EAAAA,GAAew5C,UAAWO,I,0BCH7B,MAAMC,EAAiB,I,SAClBr4D,KACAs4D,EAAAA,KACA5xE,EAAAA,KACA02B,EAAAA,KACA86C,GAGE,SAASh+B,EAAuBq+B,GACrC,OAAOF,EAAeE,EACxB,C,kFCRO,IAAKC,EAAS,SAATA,GAAS,OAATA,EAAAA,EAAS,uBAATA,EAAAA,EAAS,qBAATA,EAAAA,EAAS,qBAATA,EAAAA,EAAS,uBAATA,CAAS,MAOd,MAAMC,EAAoB,CAC/B,CAACD,EAAUE,UAAW,IACtB,CAACF,EAAUG,SAAU,IACrB,CAACH,EAAUI,SAAU,IACrB,CAACJ,EAAUK,UAAW,MAGlBC,EAAoB,CACxB,CAACN,EAAUE,UAAW,EACtB,CAACF,EAAUG,SAAU,EACrB,CAACH,EAAUI,SAAU,EACrB,CAACJ,EAAUK,UAAW,IAGlBE,EAAoB,CACxB,CAACP,EAAUE,UAAW,IACtB,CAACF,EAAUG,SAAU,IACrB,CAACH,EAAUI,SAAU,IACrB,CAACJ,EAAUK,UAAW,KA6VxB,EA1Va,CACXG,WAAUA,CAACp9E,EAAWC,IACbD,EAAG3G,EAAI4G,EAAG5G,EAAI2G,EAAG1G,EAAI2G,EAAG3G,EAGjC+jF,aAAYA,CAACr9E,EAAWC,IACfD,EAAG3G,EAAI4G,EAAG3G,EAAI0G,EAAG1G,EAAI2G,EAAG5G,EAGjC8G,SAAQA,CAACH,EAAWC,IACX/F,KAAKsP,KAAKtP,KAAKojF,IAAIt9E,EAAG3G,EAAI4G,EAAG5G,EAAG,GAAKa,KAAKojF,IAAIt9E,EAAG1G,EAAI2G,EAAG3G,EAAG,IAGpEikF,YAAAA,CAAa/rF,GAEX,GAAIA,EAAKmH,KAAOnH,EAAKqH,GACnB,MAAO,CACLnR,EAAG,EACHC,EAAG,EACH2f,GAAI9V,EAAKmH,IAGb,MAAM6kF,GAAKhsF,EAAKsH,GAAKtH,EAAKoH,KAAOpH,EAAKqH,GAAKrH,EAAKmH,IAChD,MAAO,CACLjR,GAAI81F,EACJ71F,EAAG,EACH2f,EAAGk2E,EAAIhsF,EAAKmH,GAAKnH,EAAKoH,GACtB4kF,IAEJ,EAEA53E,cAAAA,CAAevI,EAAcsI,GAE3B,IAAI83E,EAAI93E,EAAQ7qB,OAAS,EACrB4iG,GAAW,EACf,IAAK,IAAI3gF,EAAI,EAAGA,EAAI4I,EAAQ7qB,OAAQiiB,IAAK,CACvC,MAAMuU,EAAI3L,EAAQ5I,IAEduU,EAAEhY,EAAI+D,EAAM/D,GAAKqM,EAAQ83E,GAAGnkF,GAAK+D,EAAM/D,GAAOqM,EAAQ83E,GAAGnkF,EAAI+D,EAAM/D,GAAKgY,EAAEhY,GAAK+D,EAAM/D,KACtFgY,EAAEjY,GAAKgE,EAAMhE,GAAKsM,EAAQ83E,GAAGpkF,GAAKgE,EAAMhE,IAErCiY,EAAEjY,GAAMgE,EAAM/D,EAAIgY,EAAEhY,IAAMqM,EAAQ83E,GAAGnkF,EAAIgY,EAAEhY,IAAOqM,EAAQ83E,GAAGpkF,EAAIiY,EAAEjY,GAAKgE,EAAMhE,IAChFqkF,GAAYA,GAGhBD,EAAI1gF,CACN,CACA,OAAO2gF,CACT,EAEA5qE,cAAAA,CAAezV,EAAc7L,GAC3B,MAAM,EAAE9J,EAAC,EAAEC,EAAC,EAAE2f,GAAMzsB,KAAK0iG,aAAa/rF,GAEtC,OADa0I,KAAKQ,IAAIhT,EAAI2V,EAAMhE,EAAI1R,EAAI0V,EAAM/D,EAAIgO,GAAKpN,KAAKsP,KAAK9hB,EAAIA,EAAIC,EAAIA,EAE/E,EAEAiU,iBAAAA,CAAkByB,EAAc7L,GAC9B,MAAMmsF,EAAKzjF,KAAKojF,IAAI9rF,EAAKmH,GAAKnH,EAAKqH,GAAI,GAAKqB,KAAKojF,IAAI9rF,EAAKoH,GAAKpH,EAAKsH,GAAI,GACxE,GAAW,IAAP6kF,EACF,OAAOzjF,KAAKsP,KAAKtP,KAAKojF,IAAIjgF,EAAMhE,EAAI7H,EAAKmH,GAAI,GAAKuB,KAAKojF,IAAIjgF,EAAM/D,EAAI9H,EAAKoH,GAAI,IAEhF,MAAMglB,IAAMvgB,EAAMhE,EAAI7H,EAAKmH,KAAOnH,EAAKqH,GAAKrH,EAAKmH,KAAO0E,EAAM/D,EAAI9H,EAAKoH,KAAOpH,EAAKsH,GAAKtH,EAAKoH,KAAO+kF,EACpG,GAAI//D,EAAI,EACN,OAAO1jB,KAAKsP,KAAKtP,KAAKojF,IAAIjgF,EAAMhE,EAAI7H,EAAKmH,GAAI,GAAKuB,KAAKojF,IAAIjgF,EAAM/D,EAAI9H,EAAKoH,GAAI,IAEhF,GAAIglB,EAAI,EACN,OAAO1jB,KAAKsP,KAAKtP,KAAKojF,IAAIjgF,EAAMhE,EAAI7H,EAAKqH,GAAI,GAAKqB,KAAKojF,IAAIjgF,EAAM/D,EAAI9H,EAAKsH,GAAI,IAEhF,MAAMO,EAAI7H,EAAKmH,GAAKilB,GAAKpsB,EAAKqH,GAAKrH,EAAKmH,IAClCW,EAAI9H,EAAKoH,GAAKglB,GAAKpsB,EAAKsH,GAAKtH,EAAKoH,IACxC,OAAOsB,KAAKsP,KAAKtP,KAAKojF,IAAIjgF,EAAMhE,EAAIA,EAAG,GAAKa,KAAKojF,IAAIjgF,EAAM/D,EAAIA,EAAG,GACpE,EAEAuc,0BAAAA,CAA0BrzB,GAAoE,IAAnE,MAAEiG,EAAK,WAAEiF,GAAwDlL,EAC1F,OAAIkL,IAAeC,EAAAA,GAAW47B,QAAU9gC,GAAS,KACxC,EAGJiF,IAAeC,EAAAA,GAAWC,OAASnF,GAAS,GAAOiF,IAAeC,EAAAA,GAAWC,OAASnF,EAAQ,EAC1F,EAGF,CACT,EAEAm1F,eAAAA,CAAgB7lE,EAAgBt5B,EAAkBo/F,GAChD,MAAMC,EAAS5jF,KAAKQ,IAAIqd,GAClBgmE,EAAY96F,IAA8E,IAA7E,IAAEjE,EAAG,OAAEg/F,EAAM,OAAEC,GAAyDh7F,EACzF,MAAM7H,EAAM4D,EAAII,WAChB,GAAIhE,EAAI65B,SAAS,KAAM,CACrB,MAAMipE,EAAc9iG,EAAIw5B,MAAM,KACxBupE,EAAYx/E,OAAOu/E,EAAY,IAAMD,EAC3C,OAAO/jF,KAAK2E,MAAMF,OAAOu/E,EAAY,KAAK9+F,WAAWg/F,OAAOlkF,KAAKwF,IAAI,EAAGy+E,GAAY,KAAOH,CAC7F,CACA,MAAM11E,EAAOpO,KAAKoO,KAAKtpB,GACjBq/F,EAAsBnkF,KAAKojF,IAAI,GAAIW,GACnCzgE,EAAUsgE,EAASO,EAAuB/1E,EAChD,OAAQ3J,OAAO2/E,UAAU9gE,GAAUA,EAASA,EAAO/+B,aAAoByE,IAAZzE,EAAwBA,EAAU,IAAMu/F,CAAM,EAG3G,OAAIF,GAAUjB,EAAkBD,EAAUK,WAAaY,IAAcjB,EAAUK,SACtEc,EAAU,CACf/+F,IAAK+4B,EACLimE,OAAQb,EAAkBP,EAAUK,UACpCgB,OAAQf,EAAkBN,EAAUK,YAE7Ba,GAAUjB,EAAkBD,EAAUI,UAAYa,IAAcjB,EAAUI,QAC5Ee,EAAU,CACf/+F,IAAK+4B,EACLimE,OAAQb,EAAkBP,EAAUI,SACpCiB,OAAQf,EAAkBN,EAAUI,WAE7Bc,GAAUjB,EAAkBD,EAAUG,UAAYc,IAAcjB,EAAUG,QAC5EgB,EAAU,CACf/+F,IAAK+4B,EACLimE,OAAQb,EAAkBP,EAAUG,SACpCkB,OAAQf,EAAkBN,EAAUG,WAE7Be,GAAUjB,EAAkBD,EAAUE,WAAae,IAAcjB,EAAUE,SAC7EiB,EAAU,CACf/+F,IAAK+4B,EACLimE,OAAQb,EAAkBP,EAAUE,UACpCmB,OAAQf,EAAkBN,EAAUE,iBAGnB55F,IAAZzE,EAAwBs5B,EAAOt5B,QAAQA,GAAWs5B,EAAO34B,UAEpE,EAEAyf,KAAAA,CAAKlW,GAUF,IAVG,MACJF,EAAK,UACLqtB,EAAY,EAAC,WACbpoB,EAAU,eACVoR,GAMDnW,EACC,GAAIuR,KAAKQ,IAAIjS,IAAUo0F,EAAkBD,EAAUG,SACjD,OAAOliG,KAAK+iG,gBAAgBn1F,EAAOqW,GAGrC,MAAMJ,EACsB,iBAAnBI,EACHA,EACAjkB,KAAKg7B,2BAA2B,CAAEptB,MAAOqtB,EAAWpoB,eAE1D,OAAIjF,EAAQ,KAEHA,EAAMhK,QAAQigB,GAEhBC,OAAQ,GAAEzE,KAAK2E,MAAMF,OAAQ,GAAElW,MAAUiW,UAAeA,KAAUjgB,QAAQigB,EACnF,EAEA6G,wBAAAA,CAAwBhb,GAA6D,IAK/Eg0F,EACAC,GANmB,KAAEhtF,EAAI,SAAE2O,GAAkD5V,EACjF,GAAiB,IAAb4V,EACF,MAAO,CAAE9G,EAAG7H,EAAKqH,GAAIS,EAAG9H,EAAKsH,IAM3BtH,EAAKmH,IAAMnH,EAAKqH,IAAMrH,EAAKoH,IAAMpH,EAAKsH,IACxC0lF,GAAmB,EACnBD,GAAmB,GACV/sF,EAAKmH,IAAMnH,EAAKqH,IAAMrH,EAAKoH,IAAMpH,EAAKsH,IAC/C0lF,EAAkB,EAClBD,GAAmB,GACV/sF,EAAKmH,IAAMnH,EAAKqH,IAAMrH,EAAKoH,IAAMpH,EAAKsH,IAC/C0lF,GAAmB,EACnBD,EAAkB,IAGlBC,EAAkB,EAClBD,EAAkB,GAGpB,MAAME,EAAWvkF,KAAKM,MAAMN,KAAKQ,IAAIlJ,EAAKqH,GAAKrH,EAAKmH,IAAKuB,KAAKQ,IAAIlJ,EAAKsH,GAAKtH,EAAKoH,KAGjF,MAAO,CAAES,EAFC7H,EAAKqH,GAAK2lF,GAAmBr+E,EAAWjG,KAAKS,IAAI8jF,IAE/CnlF,EADF9H,EAAKsH,GAAKylF,GAAmBp+E,EAAWjG,KAAKa,IAAI0jF,IAE7D,EAEAtqE,uBAAAA,CAAuBe,GAQpB,IARqB,kBACtBtB,EAAiB,MACjB3Z,EAAK,cACL4Z,GAKDqB,EAGC,MAAMna,EAAMb,KAAKa,IAAId,GACfU,EAAMT,KAAKS,IAAIV,GASrB,MAAO,CAAEZ,EAPPsB,GAAOkZ,EAAcxa,EAAIua,EAAkBva,GAC3C0B,GAAO8Y,EAAcva,EAAIsa,EAAkBta,GAC3Csa,EAAkBva,EAKEC,EAHpBqB,GAAOkZ,EAAcva,EAAIsa,EAAkBta,GAC3CyB,GAAO8Y,EAAcxa,EAAIua,EAAkBva,GAC3Cua,EAAkBta,EAEtB,EACA0a,qBAAAA,CAAqBmB,GAQlB,IARmB,YACpBlB,EAAW,aACXH,EAAY,aACZC,GAKDoB,EAGC,MAOM6L,GANJlN,EAAaxa,GAAK2a,EAAY5a,EAAI0a,EAAa1a,GAC/C4a,EAAY3a,GAAKya,EAAa1a,EAAIya,EAAaza,GAC/C0a,EAAaza,GAAKwa,EAAaza,EAAI4a,EAAY5a,MAE9Cya,EAAaza,EAAI4a,EAAY5a,IAAM4a,EAAY5a,EAAI0a,EAAa1a,IAChEya,EAAaxa,EAAI2a,EAAY3a,IAAM2a,EAAY3a,EAAIya,EAAaza,IAGnE,OAAOY,KAAKmO,KAAK2Y,EACnB,EAEA/c,2BAAAA,CAA4BjE,EAAWC,EAAWy+E,EAAWC,GAM3D,GAAK3+E,EAAG3G,IAAM4G,EAAG5G,GAAK2G,EAAG1G,IAAM2G,EAAG3G,GAAOolF,EAAGrlF,IAAMslF,EAAGtlF,GAAKqlF,EAAGplF,IAAMqlF,EAAGrlF,EACpE,OAAO,EAGT,MAAMslF,GAAeD,EAAGrlF,EAAIolF,EAAGplF,IAAM2G,EAAG5G,EAAI2G,EAAG3G,IAAMslF,EAAGtlF,EAAIqlF,EAAGrlF,IAAM4G,EAAG3G,EAAI0G,EAAG1G,GAG/E,GAAoB,IAAhBslF,EACF,OAAO,EAGT,MAAMC,IAAOF,EAAGtlF,EAAIqlF,EAAGrlF,IAAM2G,EAAG1G,EAAIolF,EAAGplF,IAAMqlF,EAAGrlF,EAAIolF,EAAGplF,IAAM0G,EAAG3G,EAAIqlF,EAAGrlF,IAAMulF,EACvEE,IAAO7+E,EAAG5G,EAAI2G,EAAG3G,IAAM2G,EAAG1G,EAAIolF,EAAGplF,IAAM2G,EAAG3G,EAAI0G,EAAG1G,IAAM0G,EAAG3G,EAAIqlF,EAAGrlF,IAAMulF,EAG7E,GAAIC,EAAK,GAAKA,EAAK,GAAKC,EAAK,GAAKA,EAAK,EACrC,OAAO,EAOT,MAAO,CAAEzlF,EAHC2G,EAAG3G,EAAIwlF,GAAM5+E,EAAG5G,EAAI2G,EAAG3G,GAGrBC,EAFF0G,EAAG1G,EAAIulF,GAAM5+E,EAAG3G,EAAI0G,EAAG1G,GAGnC,EAGAylF,qBAAAA,CAAsBC,EAAiBC,EAAiBC,EAAiBC,GAEvE,IAAIz3F,EAAGC,EACP,MAAM61B,EAAuE,CAC3EnkB,EAAG,EACHC,EAAG,EACH8lF,SAAS,EACTC,SAAS,GAELT,GACHO,EAAS7lF,EAAI4lF,EAAS5lF,IAAM2lF,EAAS5lF,EAAI2lF,EAAS3lF,IAAM8lF,EAAS9lF,EAAI6lF,EAAS7lF,IAAM4lF,EAAS3lF,EAAI0lF,EAAS1lF,GAC7G,GAAoB,IAAhBslF,EACF,OAAO,EAGTl3F,EAAIs3F,EAAS1lF,EAAI4lF,EAAS5lF,EAC1B3R,EAAIq3F,EAAS3lF,EAAI6lF,EAAS7lF,EAC1B,MAAMimF,GAAcH,EAAS9lF,EAAI6lF,EAAS7lF,GAAK3R,GAAKy3F,EAAS7lF,EAAI4lF,EAAS5lF,GAAK3R,EACzE43F,GAAcN,EAAS5lF,EAAI2lF,EAAS3lF,GAAK3R,GAAKu3F,EAAS3lF,EAAI0lF,EAAS1lF,GAAK3R,EAiB/E,OAhBAD,EAAI43F,EAAaV,EACjBj3F,EAAI43F,EAAaX,EAGjBphE,EAAOnkB,EAAI2lF,EAAS3lF,EAAI3R,GAAKu3F,EAAS5lF,EAAI2lF,EAAS3lF,GACnDmkB,EAAOlkB,EAAI0lF,EAAS1lF,EAAI5R,GAAKu3F,EAAS3lF,EAAI0lF,EAAS1lF,GAG/C5R,EAAI,GAAKA,EAAI,IACf81B,EAAO4hE,SAAU,GAGfz3F,EAAI,GAAKA,EAAI,IACf61B,EAAO6hE,SAAU,GAGZ7hE,CACT,EAGAxE,+BAAAA,CAAgCL,EAAkB6mE,EAAeC,EAAqBC,GACpF,MAAMC,EAAmB9kG,KAAKkkG,sBAAsBpmE,EAAW6mE,EAAQC,EAAcC,GAErF,SACGC,GACDA,EAAiBP,SACjBvkG,KAAKuiG,WACHviG,KAAK0gC,eAAe5C,EAAWgnE,GAC/B9kG,KAAK0gC,eAAe5C,EAAW6mE,KAC5B,IAGA,IAAKG,EAAkBtmF,EAAGa,KAAK2E,MAAM8gF,EAAiBtmF,GAAIC,EAAGY,KAAK2E,MAAM8gF,EAAiBrmF,GAClG,EAEA8gB,4BAA2BA,CAACjI,EAAWJ,KAG9B,CAAE1Y,GAFE8Y,EAAG9Y,EAAI0Y,EAAG1Y,GAAK,EAAI0Y,EAAG1Y,EAErBC,GADD6Y,EAAG7Y,EAAIyY,EAAGzY,GAAK,EAAIyY,EAAGzY,IAInCkhB,eAAAA,CAAgBolE,GACd,MAAM9kG,EAASof,KAAKsP,KAAKo2E,EAAEvmF,EAAIumF,EAAEvmF,EAAIumF,EAAEtmF,EAAIsmF,EAAEtmF,GAC7C,MAAO,CAAED,EAAGumF,EAAEvmF,EAAIve,EAAQwe,EAAGsmF,EAAEtmF,EAAIxe,EACrC,EAEAugC,uBAAsBA,CAACukE,EAAUC,KACxB,CAAExmF,EAAGumF,EAAEvmF,EAAIwmF,EAAQvmF,EAAGsmF,EAAEtmF,EAAIumF,IAGrCzkE,UAASA,CAACjJ,EAAWJ,KACZ,CAAE1Y,EAAG8Y,EAAG9Y,EAAI0Y,EAAG1Y,EAAGC,EAAG6Y,EAAG7Y,EAAIyY,EAAGzY,IAGxCiiB,eAAcA,CAACpJ,EAAWJ,KACjB,CAAE1Y,EAAG8Y,EAAG9Y,EAAI0Y,EAAG1Y,EAAGC,EAAG6Y,EAAG7Y,EAAIyY,EAAGzY,IAGxCwmF,WAAAA,CAAY3tE,EAAWJ,GAAoC,IAAzB4U,EAAM1qC,UAAAnB,OAAA,QAAAoI,IAAAjH,UAAA,GAAAA,UAAA,GAAG,CAAEod,EAAG,EAAGC,EAAG,GACpD,OAAO6Y,EAAG9Y,EAAIstB,EAAOttB,GAAK0Y,EAAG1Y,GAAK0Y,EAAG1Y,GAAK8Y,EAAG9Y,EAAIstB,EAAOttB,GAAK8Y,EAAG7Y,EAAIqtB,EAAOrtB,GAAKyY,EAAGzY,GAAKyY,EAAGzY,GAAK6Y,EAAG7Y,EAAIqtB,EAAOrtB,CAChH,E,kFCrXK,MAAMymF,EACXlvF,OACAmvF,WACAtiD,IACAze,MACAx2B,MAEAzK,WAAAA,CAAY6S,GACVhW,KAAKgW,OAASA,EACdhW,KAAKmlG,WAAa,GAAKnlG,KAAKgW,OAAS,GACrChW,KAAK6iD,IAAM,EACX7iD,KAAKokC,MAAQ,EACbpkC,KAAK4N,MAAQ,CACf,CAEA3B,GAAAA,CAAI6f,GACE9rB,KAAKokC,MAAQpkC,KAAKgW,QACpBhW,KAAK6iD,KAAO/2B,EACZ9rB,KAAKokC,QACLpkC,KAAK4N,MAAQ5N,KAAK6iD,IAAM7iD,KAAKokC,OAE7BpkC,KAAK4N,MAAQke,EAAI9rB,KAAKmlG,WAAanlG,KAAK4N,OAAS,EAAI5N,KAAKmlG,WAE9D,EAOK,MAAMC,UAAuBC,EAAAA,EAClC9nF,YAAcmqC,EAAAA,GAAY49C,IAE1BC,0BAAAA,GACE,MAAO,CAAEC,IAAK,GAChB,CAEAC,SAAAA,CAAUC,GACR,MAAM,OAAE1vF,GAAWhW,KAAK0E,SAClB,MAAE02B,GAAUp7B,KAAK2J,MACjBo5C,EAAY3nB,EAAMn7B,OAAS,EAC3BulG,EAAM,IAAIN,EAAyBlvF,GACzChW,KAAK2lG,kBAAoB3lG,KAAKulG,6BAE9B,IAAK,IAAItjG,EAAQ,EAAGA,GAAS8gD,IAC3ByiD,EAAIv5F,IAAImvB,EAAMn5B,IACdjC,KAAK4lG,iBAAiBJ,IAAIvjG,GAASujG,EAAI53F,OAEmB,IAAtD83F,IAAoB1lG,KAAK4lG,iBAAkB3jG,IAJTA,KAQ1C,E,0EC7CK,MAAMojG,EAIX9nF,YAA2C3H,EAAAA,GAAczL,UAEzDR,MACAjF,QAEUihG,kBAEVxiG,WAAAA,CAAWwE,GAA+C,IAA9C,MAAEgC,EAAK,QAAEjF,GAAmCiD,EACtD3H,KAAK2J,MAAQA,GAAS,IAAIa,EAAAA,EAC1BxK,KAAK0E,QAAUA,EACf1E,KAAK2lG,kBAAoB3lG,KAAKulG,4BAChC,CAEA,oBAAIK,GACF,OAAO5lG,KAAK2lG,iBACd,CAEAJ,0BAAAA,GACE,MAAMn8F,MAAM,uCACd,CAEAq8F,SAAAA,CAAU/zE,GACR,MAAMtoB,MAAM,sBACd,CAEAy8F,sBAAAA,CAAuBC,GACrB,MAAMF,EAAmB,CAAC,EAI1B,OAHA3iG,OAAOC,KAAKlD,KAAK4lG,kBAAkBr9F,SAASoF,IAC1Ci4F,EAAiBj4F,GAAkC3N,KAAK+lG,oBAAoBp4F,EAAKm4F,EAAW,IAEvFF,CACT,CAEAG,mBAAAA,CAAoBp4F,EAA8Bm4F,GAChD,OAAQ9lG,KAAK4lG,iBAAiBj4F,GAAkBtN,OAAOylG,EACzD,CAQAE,eAAAA,GACE,MAAM,KAAErwF,GAAS3V,KAAKmD,YAKtB,MAAO,CAJWwS,EAAKokB,MAAM,KAAK,MACf92B,OAAOC,KAAKlD,KAAK0E,SAAW,CAAC,GAAGkI,MAAK,CAACq5F,EAAMC,IAASD,EAAKE,cAAcD,KAEzDx4F,KAAKC,GAAS,GAAEA,EAAItN,MAAM,EAAG,KAAKL,KAAK0E,QAASiJ,QAC5C9J,KAAK,IAC7C,E,yPCxBF,MAAMuiG,EAA6BtiF,OAAO86B,UACpCynD,GAA8BviF,OAAO86B,UAsC3C,MAAMz0C,UAAyDzJ,IAAAA,OAC7D6c,YAAc3H,EAAAA,GAAczL,UAC5BoT,aAAe,YAEf,gBAAOzW,GACL7D,OAAOkwB,eAAenzB,KAAKF,UAAW,SAAU,CAC9CozB,GAAAA,GACE,OAAOlzB,KAAK0B,MAAM+F,MACpB,IAEFxE,OAAOkwB,eAAenzB,KAAKF,UAAW,gBAAiB,CACrDozB,GAAAA,GACE,MAAM,kBAAEoI,GAAsBt7B,KAAKqe,yBACnC,OAAOre,KAAKyH,OAAS6zB,EAAkBhV,IAAI7e,OAAS6zB,EAAkB9U,OAAO/e,MAC/E,GAEJ,CAEA,iBAAO8pB,CAAWrpB,EAAoBxG,GACpC,MAAM4T,EAAY,IAAItV,KAAKkI,EAAQxG,GAEnC,OADA4T,EAAU6J,IAAIjX,GACPoN,CACT,CAEA,yBAAOmc,CAAkB9pB,GAAkE,IAAjE,OAAEqO,GAA6DrO,EACvF,MAAO2+F,EAAY,IAAKC,EAAAA,EAAAA,IAAkCvwF,GAC1D,OAAOswF,CACT,CAQAvjG,MACArB,MACA8kG,WAAa,EACb5xC,WAAa,EACb3pC,WAAa,EACbzjB,MAAQ,EACRswC,aAAe,EACf2uD,UAA2B,KAC3BC,cAAe,EACftiD,QAAyB,KACzBpuC,OAEA7S,WAAAA,CAAYJ,EAAcrB,GACxBuI,MAAMlH,EAAOrB,GACb1B,KAAK+C,MAAQA,EACb/C,KAAK0B,MAAQA,EACb1B,KAAK4E,KAAO5E,KAAK0B,MAAMgI,QAAQC,QAE/B3J,KAAKmqC,YAAcnqC,KAAKmqC,YAAYxpC,KAAKX,MACzCA,KAAKoqC,gBAAkBpqC,KAAKoqC,gBAAgBzpC,KAAKX,MAEjDA,KAAK0B,MAAMgI,QAAQ/I,KAAK,SAAUX,KAAKuJ,QAAQ5I,KAAKX,KAAM,WAC1DA,KAAK0B,MAAMf,KAAK,gBAAiBX,KAAKuJ,QAAQ5I,KAAKX,KAAM,WACzD,MAAM0qC,EAA0B1qC,KAAKuJ,QAAQ5I,KAAKX,KAAM,SAAU,SAClEA,KAAK0B,MAAMf,KAAK,WAAW,KACzBgqC,EAAAA,EAAWhpC,OAAO,SAAU+oC,EAAwB,IAEtDC,EAAAA,EAAWhqC,KAAK,SAAU+pC,GAE1B1qC,KAAK0B,MAAMgI,QAAQkqB,eAAejzB,KAAK,QAASX,KAAKqqC,WAAW1pC,KAAKX,MACvE,CAEA,QAAI2V,GACF,OAAQ3V,KAAKmD,YAAiCwS,IAChD,CAEA,SAAI7G,GACF,OAAQ9O,KAAKmD,YAAiC2L,KAChD,CAEA+Y,MAAAA,CAAOnJ,GACL,MAAM,kBAAE4c,GAAsBt7B,KAAKqe,yBACnCre,KAAK4E,KAAO5E,KAAK0B,MAAMgI,QAAQC,QAC/B3J,KAAKirB,WAAajrB,KAAK0B,MAAMgI,QAAQuhB,WACrCjrB,KAAKwH,MAAQxH,KAAK0B,MAAMgI,QAAQlC,MAChCxH,KAAK83C,aAAe93C,KAAKwH,MAAQ8zB,EAAkB7U,KAAKjf,MAAQ8zB,EAAkB/U,MAAM/e,MAExFxH,KAAK2mG,UAEL3mG,KAAKqqC,aAELrqC,KAAKmqC,YAAYzrB,GAEjBA,EAAQiR,OACR3vB,KAAKmrC,KAAKzsB,GACV1e,KAAKyrC,YAAY/sB,GACjB,MAAMO,GAAYiwB,EAAAA,EAAAA,IAAa,CAC7BxwB,UACA+Q,QAASzvB,KAAKirB,WAAaqQ,EAAkB7U,KAAKjf,MAClDkoB,QAAS4L,EAAkBhV,IAAI7e,SAEjCwX,EAAUkwB,KACVnvC,KAAK4mG,gBAAgBloF,GACrBO,EAAUgyB,OACVvyB,EAAQmR,UAEH7vB,KAAK6mG,uCACR7mG,KAAK8mG,YAAYpoF,EAErB,CAEAqoF,kBAAAA,GAKE,QAAI/mG,KAAK40D,YAAc50D,KAAK4E,KAAKgwD,YAAa50D,KAAK0mG,gBACjD1mG,KAAK40D,UAAY50D,KAAK4E,KAAKgwD,UAC3B50D,KAAK0mG,cAAe,GACb,EAGX,CAEAv8D,WAAAA,CAAYzrB,GACV,MAAM,kBAAE4c,EAAiB,cAAEJ,GAAkBl7B,KAAKqe,0BAC5C,OAAEE,GAAW2c,EAAc2Q,QACjC,IAAIptB,EACJ,MAAMQ,GAAYiwB,EAAAA,EAAAA,IAAa,CAC7BxwB,UACA+Q,QAAS6L,EAAkB7U,KAAKjf,MAChCkoB,QAAS4L,EAAkBhV,IAAI7e,SAEjCwX,EAAUkwB,KACV,MAAMY,EAAQ/vC,KAAK0B,MAAMyV,MAAMsH,EAAEsxB,MAAM,IACjCi3D,EAAe3nF,KAAKQ,IAAIkwB,EAAM,GAAKA,EAAM,IACzC2T,EAAQ,IAAIjoB,EAAAA,EAChB,CACE3d,GAAI,EACJE,GAAIhe,KAAK83C,aACTpc,YAAand,EAAOo4B,KACpBhb,WAAY,GAEd37B,KAAK0B,OAEDmkB,EAAO,IAAIL,EAAAA,EACf,CACEhH,EAAGxe,KAAK83C,aAAe9L,EAAAA,GAAOa,EAAIvR,EAAkB/U,MAAMqqB,KAAK9E,OAAOrlB,KACtEX,KAAMN,EAAAA,EAAK0e,2BAA2B,OAAQ5I,EAAkB/U,MAAMqqB,KAAK9qB,MAC3EG,UAAW1H,EAAOsH,KAClBO,aAAcsQ,EAAAA,GAAaC,QAE7B32B,KAAK0B,OAEP,IAAK,IAAIO,EAAQ,EAAGA,EAAQ8tC,EAAM9vC,OAAQgC,IAAS,CACjD,MAAM+tC,EAAOD,EAAM9tC,GACnBwc,EAAIY,KAAK2E,MAAMhkB,KAAKoiB,GAAG4tB,IACvB0T,EAAMvkC,IAAI,CAAEpB,GAAIU,EAAGR,GAAIQ,IAAKoJ,OAAOnJ,GAC/Bzc,EAAQ,GAAM,GAChB4jB,EAAK1G,IAAI,CAAE0G,KAAM7lB,KAAKinG,WAAWj3D,EAAMg3D,GAAevoF,MAAKoJ,OAAOnJ,EAEtE,CAEA,MACMoG,EAAO9kB,KAAK+3C,cACZmvD,EAA4B,OAAnBlnG,KAAKymG,UAAqB,EAAIpnF,KAAK2E,MAAMhkB,KAAKoiB,GAAGpiB,KAAKymG,YAC/C,MAAlBzmG,KAAKymG,WAAqBS,GAHjB,GAGmCA,GAAUpiF,GACxD,IAAIU,EAAAA,EACF,CACEK,KAAM/E,EAAAA,GAAKiiF,gBAAgB/iG,KAAKymG,UAAW,GAC3CjoF,EAAGxe,KAAK83C,aAAe9L,EAAAA,GAAOa,EAAIllB,EAAAA,GAAQ+b,IAAMpI,EAAkB/U,MAAMqqB,KAAK9E,OAAOrlB,KACpFhI,EAAGyoF,EACHphF,KAAMN,EAAAA,EAAK0e,2BAA2B,OAAQ5I,EAAkB/U,MAAMqqB,KAAK9qB,MAC3EI,WAAYoV,EAAkB/U,MAAMqqB,KAAK9qB,KAAKI,WAC9CG,QAAS,CACPC,IAAKgV,EAAkB/U,MAAMqqB,KAAK9qB,MAAMO,SAASC,KAAOqB,EAAAA,GAAQ+b,IAChEnd,MAAO+U,EAAkB/U,MAAMqqB,KAAK9qB,MAAMO,SAASE,OAASoB,EAAAA,GAAQ+b,IACpEld,OAAQ8U,EAAkB/U,MAAMqqB,KAAK9qB,MAAMO,SAASG,QAAUmB,EAAAA,GAAQ+b,IACtEjd,KAAM6U,EAAkB/U,MAAMqqB,KAAK9qB,MAAMO,SAASI,MAAQkB,EAAAA,GAAQ+b,KAEpEtd,aAAcsQ,EAAAA,GAAaC,OAC3B1Q,UAAW1H,EAAO4oF,qBAClBzgF,WAAYnI,EAAO6oF,4BAErBpnG,KAAK0B,OACLmmB,OAAOnJ,GAGXO,EAAUgyB,MACZ,CAEAxF,WAAAA,CAAY/sB,GACV,MAAM,kBAAE4c,EAAiB,cAAEJ,GAAkBl7B,KAAKqe,0BAC5C,OAAEE,GAAW2c,EAAc2Q,QAC3B0I,EAAQ,IAAI9Y,EAAAA,EAChB,CACE3d,GAAI,EACJE,GAAI,EACJD,GAAI,EACJE,GAAIje,KAAK+3C,cACTrc,YAAand,EAAOo4B,KACpBhb,WAAY,GAEd37B,KAAK0B,OAEDud,GAAYiwB,EAAAA,EAAAA,IAAa,CAC7BxwB,UACA+Q,QAAS6L,EAAkB7U,KAAKjf,MAChCkoB,QAAS4L,EAAkBhV,IAAI7e,SAEjCwX,EAAUkwB,KACV,IAAK,IAAIa,EAAO,EAAGqU,EAAMrkD,KAAK4E,KAAK4iC,KAAKvnC,OAAQ+vC,EAAOqU,EAAKrU,GAAQ,GAAI,CACtE,MAAMxxB,EAAIa,KAAK2E,MAAMhkB,KAAKmiB,GAAG6tB,GAAQhwC,KAAKirB,YACtCzM,GAAK,IAAMA,EAAIxe,KAAKwH,MAAQ,IAIhC+sC,EAAMp1B,IAAI,CAAErB,GAAIU,EAAGR,GAAIQ,IAAKqJ,OAAOnJ,EACrC,CACAO,EAAUgyB,MACZ,CAEA61D,WAAAA,CAAYpoF,GACN1e,KAAK6mG,sCACP7mG,KAAKqnG,sBAAsB3oF,GAE3B1e,KAAKsnG,qBAAqB5oF,EAE9B,CAEA4oF,oBAAAA,CAAqB5oF,GACnB,MAAM,kBAAE4c,EAAiB,cAAEJ,GAAkBl7B,KAAKqe,0BAC5C,OAAEE,GAAW2c,EAAc2Q,QAC3B/8B,EAAQ,IAAI0W,EAAAA,EAChB,CACEK,KAAM7lB,KAAKuE,WACXia,EAAG8c,EAAkB7U,KAAK8gF,eAAez7D,OAAOrlB,KAChDhI,EAAG6c,EAAkB7U,KAAK8gF,eAAez7D,OAAOxlB,IAChDR,KAAMN,EAAAA,EAAK0e,2BAA2B,OAAQ5I,EAAkB7U,KAAK8gF,eAAezhF,MACpFG,UAAW1H,EAAOsH,KAClBM,UAAWyQ,EAAAA,GAAUnQ,KACrBL,aAAcsQ,EAAAA,GAAapQ,KAE7BtmB,KAAK0B,OAGP,OADA1B,KAAKwmG,WAAa13F,EAAM6hB,QAAQjS,GACzB5P,EAAM+Y,OAAOnJ,EACtB,CAEA2oF,qBAAAA,CAAsB3oF,GACpB,MAAM,kBAAE4c,GAAsBt7B,KAAKqe,0BAC7B,MAAE3X,EAAK,2BAAE2K,GAA+BrR,KAAK0B,MAAMgI,QAAQkqB,eAC3D1jB,EAAaxJ,IAAUgC,EAAAA,GAAMyoF,KAC7B3yE,EACJnN,IAA+Bq7B,EAAAA,GAA2BkiB,UACtD5iB,EAAAA,GAAOpkB,EACP0T,EAAkB7U,KAAK8gF,eAAez7D,OAAOrlB,KAC7ChI,EAAI6c,EAAkB7U,KAAK8gF,eAAez7D,OAAOxlB,IACjDxX,EAAQ,IAAI0W,EAAAA,EAChB,CACEK,KAAM7lB,KAAKuE,WACXia,EAAO,EAAJA,EACHsH,KAAMN,EAAAA,EAAK0e,2BAA2B,OAAQ5I,EAAkB7U,KAAK8gF,eAAezhF,MACpFG,UAAWojB,IAAAA,KAAoBn5B,EAAa,GAAK,KACjDiW,UAAWyQ,EAAAA,GAAUnQ,KACrBL,aAAcsQ,EAAAA,GAAaC,QAE7B32B,KAAK0B,OAeP,OAbA1B,KAAKwmG,WAAa13F,EAAM6hB,QAAQjS,GAAgE,EAArD4c,EAAkB7U,KAAK8gF,eAAez7D,OAAOrlB,KACxF3X,EAAMqQ,IAAI,CAAEV,EAAGA,GAAKorC,EAAAA,GAAyB/6C,EAAM/L,MAAMmjB,WAAa,KC5VnE,SAAoBve,GAgBxB,IAhByB,IAC1Bmf,EAAG,EACHtI,EAAC,EACDC,EAAC,MACDjX,EAAK,OACLC,EAAM,OACN2gB,EAAM,MACNlQ,GASDvQ,EACCmf,EAAI7H,UAAU,GAAK,IACnB6H,EAAI3H,IAAI,cAAejH,GACvB4O,EAAI3H,IAAI,YAAajH,GACrB4O,EAAI5H,YACJ4H,EAAIvH,OAAOf,EAAGC,EAAI2J,GAClBtB,EAAItH,OAAOhB,EAAGC,EAAIhX,EAAS2gB,GAC3BtB,EAAImD,MAAMzL,EAAGC,EAAIhX,EAAQ+W,EAAI4J,EAAQ3J,EAAIhX,EAAQ2gB,GACjDtB,EAAItH,OAAOhB,EAAIhX,EAAQ4gB,EAAQ3J,EAAIhX,GACnCqf,EAAImD,MAAMzL,EAAIhX,EAAOiX,EAAIhX,EAAQ+W,EAAIhX,EAAOiX,EAAIhX,EAAS2gB,EAAQA,GACjEtB,EAAItH,OAAOhB,EAAIhX,EAAOiX,EAAI2J,GAC1BtB,EAAImD,MAAMzL,EAAIhX,EAAOiX,EAAGD,EAAIhX,EAAQ4gB,EAAQ3J,EAAG2J,GAC/CtB,EAAItH,OAAOhB,EAAI4J,EAAQ3J,GACvBqI,EAAImD,MAAMzL,EAAGC,EAAGD,EAAGC,EAAI2J,EAAQA,GAC/BtB,EAAIrH,SACJqH,EAAIlF,OACJkF,EAAI7H,WAAW,IAAM,GACvB,CD4TIuoF,CAAY,CACV1gF,IAAKpI,EACLF,IACAC,IACAhX,OAAQoiD,EAAAA,GACRriD,MAAOxH,KAAKwmG,WACZp+E,OAAQ,EACRlQ,MAAQ,GAAEmxB,IAAAA,KAAoBn5B,EAAa,IAAM,UAEnDpB,EAAM+Y,OAAOnJ,GAEN,CAAEF,IAAGC,IAAG+nF,WAAYxmG,KAAKwmG,WAClC,CAEA5uD,WAAAA,CAAYl5B,IACVk5B,EAAAA,EAAAA,IAAY,CACVl5B,UACAisB,WAAU,IACV5jC,UAAW/G,KAAK0B,MAChBiI,MAAO3J,KAAK4E,KACZkzC,aAAc93C,KAAK83C,aACnBC,cAAe/3C,KAAK+3C,cACpBxc,aAAa,EACbksE,gBAAiBznG,KAAK2V,OAASC,EAAAA,GAAc8xF,KAC7CvvD,kBAAoBn4C,KAAK6mG,2CAA+Dx+F,EAAvBrI,KAAKoqC,kBAGpEpqC,KAAK6mG,uCACP7mG,KAAKoqC,gBAAgB1rB,EAASisB,EAAAA,EAAWyN,qBAAqBp4C,KAAK0B,OAEvE,CAEA0oC,eAAAA,CAAgB1rB,EAAmC+5B,GACjDz4C,KAAK4E,KAAO5E,KAAK0B,MAAMgI,QAAQC,QAC/B,MAAM1H,EAAQ6hB,OAAOkS,MAAMyiB,GAAcz4C,KAAK4E,KAAKw2B,MAAMn7B,OAAS,EAAIw4C,EAClEz4C,KAAK6mG,uCACP7mG,KAAKqnG,sBAAsB3oF,GAE3B1e,KAAK2nG,0BAA0BjpF,EAASzc,IAExCjC,KAAK4nG,yBAAyBlpF,EAASzc,EAE3C,CAEA0lG,yBAAAA,CAA0Bj2E,EAA6BY,GAAa,CAEpEs1E,wBAAAA,CAAyBl2E,EAA6BY,GAAa,CAEnEu1E,wBAAAA,CACEnpF,EACAwkC,EACAnuB,EACAouB,EACA2kD,EACA1kD,EACA2kD,GAEA,MAAM,kBAAEzsE,GAAsBt7B,KAAKqe,yBACnC,GAA+B,IAA3Bre,KAAK4E,KAAKw2B,MAAMn7B,OAAc,OAClC,MAAM+nG,EAAyB,CAC7BC,gBAAiBlzE,EACjB9J,WAAYjrB,KAAKirB,WACjBlkB,UAAW/G,KAAK0B,MAChBiI,MAAO3J,KAAK4E,KACZ4C,MAAOxH,KAAKwH,OAGR22C,GAAwB+pD,EAAAA,EAAAA,IAAoCF,GAEjD,MAAbD,IACFA,GAAY,GAGdrpF,EAAQiR,OAER,IAAIw4E,EAAa9oF,KAAK2E,MAAMhkB,KAAKoiB,GAAG+gC,GAAYnjD,KAAKoiB,GAAGpiB,KAAK0B,MAAMyV,MAAMsH,EAAE2E,SAAS,MAChF+kF,GAAc,IAAK3mD,EAAAA,EAAAA,SACrB9iC,EAAQQ,YACRR,EAAQilB,MACL3jC,KAAKirB,WACNjrB,KAAKoiB,GAAGpiB,KAAK0B,MAAMyV,MAAMsH,EAAE2E,SAAS,IAAM,EAC1CpjB,KAAK83C,aACLqwD,EAAa,EAAIA,EAAa,GAAK,IAGvCzpF,EAAQysB,OACRzsB,EAAQS,IAAI,YAAa,WAEzBT,EAAQQ,YACRR,EAAQa,OAAOvf,KAAKmiB,GAAGg8B,GAAwB9+B,KAAK2E,MAAMhkB,KAAKoiB,GAAGpiB,KAAK0B,MAAMyV,MAAMsH,EAAE2E,SAAS,OAC9Fo0B,EAAAA,EAAAA,IAAkB,IACbwwD,EACHvwD,gBAAiBA,CAACv1B,EAAG1D,KACnBE,EAAQc,OAAOhB,EAAGa,KAAK2E,MAAMhkB,KAAKoiB,GAAG8gC,EAAMhhC,KAAK,IAGpDxD,EAAQc,OAAOxf,KAAKmiB,GAAGniB,KAAK4E,KAAKw2B,MAAMn7B,OAAS,GAAIof,KAAK2E,MAAMhkB,KAAKoiB,GAAGpiB,KAAK0B,MAAMyV,MAAMsH,EAAE2E,SAAS,MACnG1E,EAAQkD,OACRlD,EAAQmR,UACJk4E,GACF,IAAItsE,EAAAA,EACF,CACE3d,IAAK9d,KAAKirB,WACVjN,IAAKhe,KAAKirB,WAAajrB,KAAK83C,aAC5B/5B,GAAIsB,KAAK2E,MAAMhkB,KAAKoiB,GAAG+gC,IACvBllC,GAAIoB,KAAK2E,MAAMhkB,KAAKoiB,GAAG+gC,IACvBznB,YAAa,WAEf17B,KAAK0B,OACLmmB,OAAOnJ,GAGPqpF,GACF/nG,KAAKooG,eAAe1pF,EAASopF,GAG/BppF,EAAQiR,OACRw4E,EAAa9oF,KAAK2E,MAAMhkB,KAAKoiB,GAAGghC,KAC5B+kD,GAAc,IAAK3mD,EAAAA,EAAAA,SACrB9iC,EAAQQ,YACRR,EAAQilB,MACL3jC,KAAKirB,WACNjrB,KAAKoiB,GAAGpiB,KAAK0B,MAAMyV,MAAMsH,EAAE2E,SAAS,IACpCpjB,KAAK83C,aACLqwD,EAAa,EAAIA,EAAa,IAIlCzpF,EAAQysB,OACRzsB,EAAQS,IAAI,YAAa,WACzBT,EAAQQ,YACRR,EAAQa,OAAOvf,KAAKmiB,GAAGg8B,GAAwB9+B,KAAK2E,MAAMhkB,KAAKoiB,GAAGpiB,KAAK0B,MAAMyV,MAAMsH,EAAE2E,SAAS,OAC9Fo0B,EAAAA,EAAAA,IAAkB,IACbwwD,EACHvwD,gBAAiBA,CAACv1B,EAAG1D,KACnBE,EAAQc,OAAOhB,EAAGa,KAAK2E,MAAMhkB,KAAKoiB,GAAG8gC,EAAMhhC,KAAK,IAGpDxD,EAAQc,OAAOxf,KAAKmiB,GAAGniB,KAAK4E,KAAKw2B,MAAMn7B,OAAS,GAAIof,KAAK2E,MAAMhkB,KAAKoiB,GAAGpiB,KAAK0B,MAAMyV,MAAMsH,EAAE2E,SAAS,IAAM,IACzG1E,EAAQkD,OACRlD,EAAQmR,UACJk4E,GACF,IAAItsE,EAAAA,EACF,CACE3d,IAAK9d,KAAKirB,WACVjN,IAAKhe,KAAKirB,WAAajrB,KAAK83C,aAC5B/5B,GAAIsB,KAAK2E,MAAMhkB,KAAKoiB,GAAGghC,IACvBnlC,GAAIoB,KAAK2E,MAAMhkB,KAAKoiB,GAAGghC,IACvB1nB,YAAa,WAEf17B,KAAK0B,OACLmmB,OAAOnJ,GAGXA,EAAQS,IAAI,cAAemc,EAAkBuQ,QAAQttB,OAAO5H,MAC5D+H,EAAQS,IAAI,YAAa,WAEzBT,EAAQO,UAAU,GAAK,IACvBP,EAAQQ,aACRs4B,EAAAA,EAAAA,IAAkB,IACbwwD,EACHvwD,gBAAiBA,CAACv1B,EAAG1D,KACnBE,EAAQc,OAAOH,KAAK2E,MAAMxF,GAAIa,KAAK2E,MAAMhkB,KAAKoiB,GAAG8gC,EAAMhhC,KAAK,IAGhExD,EAAQe,SACRf,EAAQO,WAAW,IAAM,GAC3B,CAEAmpF,cAAAA,CAAe1pF,EAAmCopF,GAChD,IAAIrsE,EAAAA,EACF,CACE3d,IAAK9d,KAAKirB,WACVjN,IAAKhe,KAAKirB,WAAajrB,KAAK83C,aAC5B/5B,GAAIsB,KAAK2E,MAAMhkB,KAAKoiB,GAAG0lF,IACvB7pF,GAAIoB,KAAK2E,MAAMhkB,KAAKoiB,GAAG0lF,IACvBpsE,YAAa,UACbC,WAAY,GAEd37B,KAAK0B,OACLmmB,OAAOnJ,EACX,CAEA2rB,UAAAA,GAAc,CAEdc,IAAAA,CAAKzsB,GACH,MAAM,kBAAE4c,GAAsBt7B,KAAKqe,yBAGnC,OAFAK,EAAQQ,YACRR,EAAQilB,KAAKrI,EAAkB7U,KAAKjf,MAAO8zB,EAAkBhV,IAAI7e,OAAQzH,KAAK83C,aAAc93C,KAAK+3C,cAAgB,GAC1Gr5B,EAAQysB,MACjB,CAEA87D,UAAAA,CAAWr5F,EAAey6F,GACxB,YAAiBhgG,IAAbggG,GAA0B,GAAKA,EAC1Bz6F,EAAMhK,QAAQ,GAEhBgK,EAAMrJ,UACf,CAEA4d,GAAM3D,GAAcxe,KAAK0B,MAAMyV,MAAMqH,EAAExe,KAAK4E,KAAKw3B,SAAS5d,IAE1D4D,GAAM3D,GAAcze,KAAK0B,MAAMyV,MAAMsH,EAAEA,GAEvCU,GAAAA,CAAIjX,GACF,MAAM,kBAAEozB,GAAsBt7B,KAAKqe,yBACnCre,KAAK0mG,cAAe,EACpB,IAAK,MAAM/4F,KAAOzF,EACJ,SAARyF,IAEF3N,KAAK2N,GAAOzF,EAAOyF,IAGvB3N,KAAKwH,MAAQxH,KAAK0B,MAAMgI,QAAQlC,MAChCxH,KAAK83C,aAAe93C,KAAKwH,MAAQ8zB,EAAkB7U,KAAKjf,MAAQ8zB,EAAkB/U,MAAM/e,MAExF,MAAM8gG,EAAWtoG,KAAK+zB,iBACnB9S,OAAOvT,KAAItF,IAAA,IAAC,MAAEwF,GAAOxF,EAAA,OAAKwF,EAAMrJ,UAAU,IAC1CV,KAAK,KACJykG,IAAUtoG,KAAK+C,MAAQ,IAAK/C,KAAK+C,MAAOiT,OAAQsyF,IAEpDtoG,KAAK0B,MAAM6H,QAAQghC,EAAAA,GAAkB+mC,aACvC,CAEAi3B,cAAAA,CAAergG,GACgB,iBAAlBA,EAAO8N,SAChBhW,KAAKgW,OAAS8N,OAAOq5B,SAASj1C,EAAO8N,OAAQ,IAC7ChW,KAAK0B,MAAM6H,QAAQghC,EAAAA,GAAkB+mC,cAEzC,CAEAk3B,QAAAA,CAAS9mG,GACP,OAAQ1B,KAAK0B,MAAQA,CACvB,CAEAif,QAAAA,CAASC,GACP,MAAM,kBAAE0a,GAAsBt7B,KAAKqe,yBAC7BG,EAAI8c,EAAkB7U,KAAK8gF,eAAez7D,OAAOrlB,KACjDhI,EAAI6c,EAAkB7U,KAAK8gF,eAAez7D,OAAOxlB,IACvD,IAAI9e,EAAmB,EAAXwkC,EAAAA,GAAOa,EAAQ7sC,KAAKwmG,WAC5B/+F,EAAoB,EAAXukC,EAAAA,GAAOpkB,EAAQmkB,EAAAA,GAAUc,EAOtC,OALI7sC,KAAK6mG,wCACPr/F,EAAQxH,KAAKwmG,WACb/+F,EAASoiD,EAAAA,IAGPrrC,EAAIoC,EAAK63D,SAAW73D,EAAK63D,QAAUjxE,EAAQgX,GAAKC,EAAImC,EAAK83D,SAAW93D,EAAK83D,QAAUjxE,EAASgX,CAIlG,CAEAuM,gBAAAA,CAAiB0G,GACf,OAAO,CACT,CAEAlR,MAAAA,GAAU,CAEVuL,eAAAA,GACE,OAAO,CACT,CAEA03B,oBAAAA,GACE,IAAI/+B,EAAM0hF,EACNvhF,EAAMwhF,EAEV,MAAM,WAAEp7E,GAAejrB,KAAK0B,MAAMgI,QAE5By0C,GAAwB7L,EAAAA,EAAAA,IAA2B,CACvD3oC,MAAO3J,KAAK4E,KACZmC,UAAW/G,KAAK0B,MAChBupB,eAEImzB,GAAuB9L,EAAAA,EAAAA,IAA2B,CACtD3oC,MAAO3J,KAAK4E,KACZmC,UAAW/G,KAAK0B,MAChBupB,aACAunB,WAAYxyC,KAAK83C,eAEb2wD,GAAmBnqD,EAAAA,EAAAA,IAAoBH,EAAuBC,GAAqB,QAAAj9C,EAAAC,UAAAnB,OAjBnEykD,EAAM,IAAA7kD,MAAAsB,GAAAG,EAAA,EAAAA,EAAAH,EAAAG,IAANojD,EAAMpjD,GAAAF,UAAAE,GAmB5B,IAAK,MAAMqL,KAAO+3C,EAChB,IAAK,IAAIxiC,EAAIi8B,EAAsBl8C,MAAOigB,GAAKk8B,EAAqBn8C,MAAOigB,IACpE8T,MAAMrpB,EAAIuV,MACbwC,EAAMrF,KAAKqF,IAAIA,EAAK/X,EAAIuV,IACxB2C,EAAMxF,KAAKwF,IAAIA,EAAKlY,EAAIuV,KAK9B,OAAQumF,GAAoB/jF,IAAQG,GAAOH,IAAQ0hF,GAA8BvhF,IAAQwhF,EAErFrmG,KAAK0oG,kBAAkB1oG,KAAK2V,MAD5B,CAAE+O,MAAKG,MAEb,CAEAkP,cAAAA,GACE,MAAO,CACLvwB,MAAO,GACPyd,OAAQ,GACR0nF,oBAAqB,CAAC,EAE1B,CAEAD,kBAAqB39C,GA7lBWz1C,KAChC,OAAQA,GACN,KAAKM,EAAAA,GAAcgzF,KACjB,MAAO,CAAElkF,IAAK,EAAGG,IAAK,GACxB,KAAKjP,EAAAA,GAAcizF,IACjB,MAAO,CAAEnkF,IAAK,EAAGG,IAAK,IACxB,KAAKjP,EAAAA,GAAckzF,IACnB,KAAKlzF,EAAAA,GAAcmzF,IACnB,KAAKnzF,EAAAA,GAAcozF,IACnB,KAAKpzF,EAAAA,GAAc8xF,KACnB,KAAK9xF,EAAAA,GAAcqzF,IACnB,KAAKrzF,EAAAA,GAAcszF,IACnB,KAAKtzF,EAAAA,GAAcuzF,MACnB,KAAKvzF,EAAAA,GAAcwzF,IACjB,MAAO,CAAE1kF,IAAK,EAAGG,IAAK,KACxB,KAAKjP,EAAAA,GAAcyzF,KACnB,KAAKzzF,EAAAA,GAAc0zF,IACnB,KAAK1zF,EAAAA,GAAc2zF,KACjB,MAAO,CAAE7kF,KAAM,EAAGG,IAAK,GACzB,KAAKjP,EAAAA,GAAc4zF,GACjB,MAAO,CAAE9kF,KAAM,IAAKG,IAAK,GAC3B,KAAKjP,EAAAA,GAAc6zF,OACnB,KAAK7zF,EAAAA,GAAc8zF,IACjB,MAAO,CAAEhlF,KAAM,IAAKG,IAAK,KAC3B,KAAKjP,EAAAA,GAAc+zF,IACnB,KAAK/zF,EAAAA,GAAcg0F,GACjB,MAAO,CAAEllF,KAAM,IAAKG,IAAK,KAC3B,QACE,MAAO,CAAEH,IAAK,EAAGG,IAAK,KAC1B,EAgkBsDglF,CAAyB9+C,GAE/Ezb,SAAAA,GAGE,OAFAtvC,KAAK4E,KAAO5E,KAAK0B,MAAMgI,QAAQC,QAC/B3J,KAAK2mG,UACE,CAAEjiF,IAAK1kB,KAAK0kB,IAAKG,IAAK7kB,KAAK6kB,IACpC,CAEA7a,QAAAA,GACE,OAAOkd,IAAM,CAAC,EAAGlnB,KAAK+C,MAAO,CAAE4S,KAAM3V,KAAK2V,KAAMyuC,QAASpkD,KAAKokD,SAChE,CAEAl6C,QAAAA,GACE,MAAO,CACLyL,KAAM3V,KAAK2V,KACXK,OAAQhW,KAAK+zB,iBACV9S,OAAOvT,KAAKumB,GAA6BA,EAAMrmB,MAAMrJ,aACrDV,KAAK,KAEZ,CAEAwa,sBAAAA,GACE,OAAOA,EAAAA,EAAAA,IAAuBre,KAAK0B,MAAMgI,QAAQkqB,eACnD,CAEAgzE,eAAAA,CAAgBl1E,GACd,MAAMtoB,MAAM,mCACd,CAEA0gG,UAAAA,CAAWp4E,GACT,MAAMtoB,MAAM,YACd,CAEA2gG,qBAAAA,CAAqBj8F,GAA+E,IAA9E,IAAEH,EAAG,YAAEq8F,GAAc,GAA8Cl8F,EACvF,MAAMmmB,EAAQj0B,KAAK+zB,iBAAiB9S,OAAOpX,MAAK6F,IAAA,IAAC,KAAEtM,GAAwBsM,EAAA,OAAK/B,IAAQvK,CAAI,IAC5F,QAAS6wB,IAASa,EAAAA,EAAAA,IAAUb,MAAY+1E,IAAeC,EAAAA,EAAAA,IAAkBh2E,EAAMrmB,OACjF,CAEAi5F,mCAAAA,GACE,MAAM,2BAAEx1F,GAA+BrR,KAAK0B,MAAMgI,QAAQkqB,eACpD4jD,EAAWnmE,IAA+Bq7B,EAAAA,GAA2ByS,UACrEs4B,GACJljE,EAAAA,EAAAA,OACA,CACEm4B,EAAAA,GAA2BmiB,YAC3BniB,EAAAA,GAA2BoiB,UAC3BpiB,EAAAA,GAA2BqiB,WAC3BriB,EAAAA,GAA2BkiB,WAC3Bx0B,SAAS/oB,GAEb,OAAOmmE,GAAYC,CACrB,CAEAzkD,YAAAA,GACE,OAAO,CACT,CAEAZ,eAAAA,GACE,OAAO,CACT,CAEAu0E,OAAAA,GACE,MAAMv9F,MAAM,2BACd,EAGFe,EAAUrD,YAEV,UEvsBA,MAAMojG,UAAY//F,EAChBoT,YAAc3H,EAAAA,GAAckzF,IAC5BvrF,aAAe,MAGf4sF,IAAgB,GAChBC,IAAgB,GAChBC,IAAgB,GAEhBlrF,GAAAA,CAAIjX,GACF+B,MAAMkV,IAAIjX,GACVlI,KAAKuoG,eAAergG,EACtB,CAEAy+F,OAAAA,GACE,GAAI3mG,KAAK+mG,qBAAsB,CAC7B,IAAIsD,EAAKC,EAAMC,EAAMH,EAAKD,EAC1BnqG,KAAKmqG,IAAM,GACXnqG,KAAKoqG,IAAM,GACXpqG,KAAKqqG,IAAM,GACX,IAAIG,EAAOD,EAAOD,EAAOD,EAAM,EAC/B,IAAK,IAAInoF,EAAIliB,KAAKgW,OAAQkM,EAAIliB,KAAK4E,KAAKw2B,MAAMn7B,OAAQiiB,IAAK,CACzD,MAAMuoF,EAAYzqG,KAAK4E,KAAKuX,KAAK+F,GAAKliB,KAAK4E,KAAKuX,KAAK+F,EAAI,GACnDwoF,EAAW1qG,KAAK4E,KAAKmkC,IAAI7mB,EAAI,GAAKliB,KAAK4E,KAAKmkC,IAAI7mB,GAEtD,IAAIyoF,EAAM,EACNF,EAAY,GAAKA,EAAYC,IAC/BC,EAAMF,GAGR,IAAIG,EAAM,EACNF,EAAW,GAAKA,EAAWD,IAC7BG,EAAMF,GAGR,MAAM/J,EAAK52D,EAAAA,GAAMllB,IAAI,CACnB7kB,KAAK4E,KAAKuX,KAAK+F,GAAKliB,KAAK4E,KAAKmkC,IAAI7mB,GAClC7C,KAAKQ,IAAI7f,KAAK4E,KAAKuX,KAAK+F,GAAKliB,KAAK4E,KAAKw2B,MAAMlZ,EAAI,IACjD7C,KAAKQ,IAAI7f,KAAK4E,KAAKmkC,IAAI7mB,GAAKliB,KAAK4E,KAAKw2B,MAAMlZ,EAAI,MAGlDsoF,GAAOA,GAAOxqG,KAAKgW,OAAS,GAAK2qF,GAAM3gG,KAAKgW,OAC5Cu0F,GAAQA,GAAQvqG,KAAKgW,OAAS,GAAK20F,GAAO3qG,KAAKgW,OAC/Cs0F,GAAQA,GAAQtqG,KAAKgW,OAAS,GAAK40F,GAAO5qG,KAAKgW,OAE/Cm0F,EAAMK,EAAM,EAAY,IAAPD,EAAcC,EAAM,EACrCJ,EAAMI,EAAM,EAAY,IAAPF,EAAcE,EAAM,EACrC,MAAMK,EAAKxrF,KAAKQ,IAAIsqF,EAAMC,GACpB17E,EAAKy7E,EAAMC,EAAM,EAAU,IAALS,GAAaV,EAAMC,GAAO,EACtDC,GAAOA,GAAOrqG,KAAKgW,OAAS,GAAK0Y,GAAM1uB,KAAKgW,OAE5ChW,KAAKmqG,IAAIjoF,GAAKioF,EACdnqG,KAAKoqG,IAAIloF,GAAKkoF,EACdpqG,KAAKqqG,IAAInoF,GAAKmoF,CAChB,CACArqG,KAAKymG,UAAYzmG,KAAKqqG,IAAItqG,QAAU,IACtC,CACA,MAAM,IAAE2kB,EAAG,IAAEG,GACX7kB,KAAKmqG,IAAIlqG,OAAS,GAAKD,KAAKoqG,IAAInqG,OAAS,GAAKD,KAAKqqG,IAAIpqG,OAAS,EAC5DD,KAAKyjD,qBAAqBzjD,KAAKmqG,IAAKnqG,KAAKoqG,IAAKpqG,KAAKqqG,KACnDrqG,KAAK0oG,kBAAkB1oG,KAAK2V,MAClC3V,KAAK0kB,IAAMA,EACX1kB,KAAK6kB,IAAMA,CACb,CAEA+hF,eAAAA,CAAgBloF,GACd,GAA+B,IAA3B1e,KAAK4E,KAAKw2B,MAAMn7B,OAAc,OAElCye,EAAQO,UAAU,GAAK,IACvBP,EAAQS,IAAI,cAAe,WAC3BT,EAAQQ,YAER,MAAM8oF,EAAyB,CAC7Br+F,MAAO3J,KAAK4E,KACZmC,UAAW/G,KAAK0B,MAChBupB,WAAYjrB,KAAKirB,WACjBzjB,MAAOxH,KAAKwH,MACZygG,gBAAiBjoG,KAAKgW,SAExBwhC,EAAAA,EAAAA,IAAkB,IACbwwD,EACHvwD,gBAAiBA,CAACv1B,EAAG1D,KACnBE,EAAQc,OAAOhB,EAAGa,KAAK2E,MAAMhkB,KAAKoiB,GAAGpiB,KAAKmqG,IAAIjoF,KAAK,IAIvDxD,EAAQe,SAERf,EAAQS,IAAI,cAAe,WAC3BT,EAAQQ,aACRs4B,EAAAA,EAAAA,IAAkB,IACbwwD,EACHvwD,gBAAiBA,CAACv1B,EAAG1D,KACnBE,EAAQc,OAAOhB,EAAGa,KAAK2E,MAAMhkB,KAAKoiB,GAAGpiB,KAAKoqG,IAAIloF,KAAK,IAGvDxD,EAAQe,SACRf,EAAQS,IAAI,cAAenf,KAAKqe,yBAAyBid,kBAAkBuQ,QAAQttB,OAAO5H,MAC1F+H,EAAQQ,aAERs4B,EAAAA,EAAAA,IAAkB,IACbwwD,EACHvwD,gBAAiBA,CAACv1B,EAAG1D,KACnBE,EAAQc,OAAOhB,EAAGa,KAAK2E,MAAMhkB,KAAKoiB,GAAGpiB,KAAKqqG,IAAInoF,KAAK,IAGvDxD,EAAQe,SACRf,EAAQO,WAAW,IAAM,GAC3B,CAEA8U,cAAAA,GACE,MAAM/d,EAAS,CACbL,KAAM,SACN7G,MAAO,SACP1L,KAAM,SACNwK,MAAO5N,KAAKgW,QAAU,GACtB2P,UAAU,EACVjB,IAAK,EACLG,IAAK,QAGP,MAAO,CACLrhB,MAAOxD,KAAK8O,MACZmS,OAAQ,CAACjL,GACT2yF,oBAAqB,CACnB3yF,OAAS,GAAEA,EAAOlH,wCAAwCkH,EAAO0O,WAAW1O,EAAO6O,OAGzF,CAEAilF,UAAAA,CAAWn8F,GACT,MACO,WADCA,GAEG3N,KAAK+pG,sBAAsB,CAAEp8F,OAI1C,CAEApJ,QAAAA,GACE,MAAQ,OAAMvE,KAAKgW,QACrB,EAGF,U,wBC5IO,MAAM80F,UAAyBzF,EAAAA,EACpC9nF,YAAc3H,EAAAA,GAAcmzF,IAE5BxD,0BAAAA,GACE,MAAO,CACLwF,QAAS,GACTC,UAAW,GACXC,WAAY,GAEhB,CAEAxF,SAAAA,CAAUC,GACR,MAAM,OAAE1vF,GAAWhW,KAAK0E,SAClB,IAAEqkC,EAAG,KAAE5sB,GAASnc,KAAK2J,MAC3B3J,KAAK2lG,kBAAoB3lG,KAAKulG,6BAE9B,IAAK,IAAIrjF,EAAIlM,EAAQkM,EAAI/F,EAAKlc,OAAQiiB,IAAK,CACzC,MAAMgpF,EAAa/uF,EAAK9b,MAAM6hB,EAAIlM,EAAQkM,EAAI,GACxCipF,EAAkB9rF,KAAKwF,OAAOqmF,GAC9BE,EAAkBp1F,EAASk1F,EAAWG,YAAYF,GACxDnrG,KAAK2lG,kBAAkBoF,QAAQ7oF,IAAalM,EAASo1F,GAAmBp1F,EAApC,IAEpC,MAAMs1F,EAAYviE,EAAI1oC,MAAM6hB,EAAIlM,EAAQkM,EAAI,GACtCqpF,EAAiBlsF,KAAKqF,OAAO4mF,GAC7BE,EAAiBx1F,EAASs1F,EAAUD,YAAYE,GAKtD,GAJAvrG,KAAK2lG,kBAAkBqF,UAAU9oF,IAAalM,EAASw1F,GAAkBx1F,EAAnC,IAEtChW,KAAK2lG,kBAAkBsF,WAAW/oF,GAAKliB,KAAK2lG,kBAAkBoF,QAAQ7oF,GAAKliB,KAAK2lG,kBAAkBqF,UAAU9oF,IAEtD,IAAlDwjF,IAAoB1lG,KAAK4lG,iBAAkB1jF,GAC7C,KAEJ,CACF,EClCF,MAAMupF,EACK,UADLA,EAEO,UAGb,MAAMC,UAAcvhG,EAClBoT,YAAc3H,EAAAA,GAAcmzF,IAC5BxrF,aAAe,QAEfouF,iBAA4C,KAG5CxoG,WAAAA,CAAYJ,EAAcrB,GACxBuI,MAAMlH,EAAOrB,GACb1B,KAAKmqC,YAAcnqC,KAAKmqC,YAAYxpC,KAAKX,KAC3C,CAEAmf,GAAAA,CAAIjX,GACF+B,MAAMkV,IAAIjX,GACVlI,KAAKuoG,eAAergG,EACtB,CAEAy+F,OAAAA,GACE,IAAK3mG,KAAK+mG,sBAAkD,OAA1B/mG,KAAK2rG,iBAA2B,OAElE3rG,KAAK2rG,iBAAmB,IAAIb,EAAiB,CAC3CnhG,MAAO3J,KAAK4E,KACZF,QAAS,CAAEsR,OAAQhW,KAAKgW,UAG1BhW,KAAK2rG,iBAAiBlG,YAEtB,MAAM,IAAE/gF,EAAG,IAAEG,GAAQ7kB,KAAK0oG,kBAAkB1oG,KAAK2V,MACjD3V,KAAK0kB,IAAMA,EACX1kB,KAAK6kB,IAAMA,CACb,CAEA+hF,eAAAA,CAAgBloF,GACd,GAA+B,IAA3B1e,KAAK4E,KAAKw2B,MAAMn7B,SAAiBD,KAAK2rG,iBAAkB,OAE5DjtF,EAAQO,UAAU,GAAK,IACvBP,EAAQS,IAAI,cAAessF,GAC3B/sF,EAAQQ,YACR,MAAM8oF,EAAyB,CAC7Br+F,MAAO3J,KAAK4E,KACZmC,UAAW/G,KAAK0B,MAChBupB,WAAYjrB,KAAKirB,WACjBzjB,MAAOxH,KAAKwH,MACZygG,gBAAiBjoG,KAAKgW,SAElB,QAAE+0F,EAAO,UAAEC,GAAchrG,KAAK2rG,iBAAiB/F,kBACrDpuD,EAAAA,EAAAA,IAAkB,IACbwwD,EACHvwD,gBAAiBA,CAACv1B,EAAG1D,KACnBE,EAAQc,OAAOhB,EAAGa,KAAK2E,MAAMhkB,KAAKoiB,GAAG2oF,EAAQ7oF,KAAK,IAGtDxD,EAAQe,SAERf,EAAQS,IAAI,cAAessF,GAC3B/sF,EAAQQ,aACRs4B,EAAAA,EAAAA,IAAkB,IACbwwD,EACHvwD,gBAAiBA,CAACv1B,EAAG1D,KACnBE,EAAQc,OAAOhB,EAAGa,KAAK2E,MAAMhkB,KAAKoiB,GAAG4oF,EAAU9oF,KAAK,IAGxDxD,EAAQe,SACRf,EAAQO,WAAW,IAAM,GAC3B,CAEAkrB,WAAAA,CAAYzrB,GAEV,GADAzU,MAAMkgC,YAAYzrB,IACb1e,KAAK2rG,iBAAkB,OAC5B,MAAM,kBAAErwE,EAAiB,cAAEJ,GAAkBl7B,KAAKqe,0BAC5C,OAAEE,GAAW2c,EAAc2Q,SAC3B,QAAEk/D,EAAO,UAAEC,GAAchrG,KAAK2rG,iBAAiB/F,iBAE/C3mF,GAAYiwB,EAAAA,EAAAA,IAAa,CAC7BxwB,UACA+Q,QAAS6L,EAAkB7U,KAAKjf,MAChCkoB,QAAS4L,EAAkBhV,IAAI7e,SAEjCwX,EAAUkwB,KACV,MAAMtpB,EAAO,IAAIL,EAAAA,EACf,CACEhH,EAAGxe,KAAK83C,aAAe9L,EAAAA,GAAOa,EAAIllB,EAAAA,GAAQ+b,IAAMpI,EAAkB/U,MAAMqqB,KAAK9E,OAAOrlB,KACpFX,KAAMN,EAAAA,EAAK0e,2BAA2B,OAAQ5I,EAAkB/U,MAAMqqB,KAAK9qB,MAC3EI,WAAYoV,EAAkB/U,MAAMqqB,KAAK9qB,KAAKI,WAC9CG,QAAS,CACPC,IAAKgV,EAAkB/U,MAAMqqB,KAAK9qB,MAAMO,SAASC,KAAOqB,EAAAA,GAAQ+b,IAChEnd,MAAO+U,EAAkB/U,MAAMqqB,KAAK9qB,MAAMO,SAASE,OAASoB,EAAAA,GAAQ+b,IACpEld,OAAQ8U,EAAkB/U,MAAMqqB,KAAK9qB,MAAMO,SAASG,QAAUmB,EAAAA,GAAQ+b,IACtEjd,KAAM6U,EAAkB/U,MAAMqqB,KAAK9qB,MAAMO,SAASI,MAAQkB,EAAAA,GAAQ+b,KAEpEtd,aAAcsQ,EAAAA,GAAaC,OAC3B1Q,UAAW1H,EAAO4oF,sBAEpBnnG,KAAK0B,OAEDkqG,EAAa,GACfZ,EAAU/qG,OAAS,GACrB2rG,EAAWrqG,KAAK,CACdskB,KAAMmlF,EAAUjrG,OAAQ6D,QAAQ,GAChC6a,EAAGY,KAAK2E,MAAMhkB,KAAKoiB,GAAG4oF,EAAUjrG,SAChC2mB,WAAY+kF,IAGZV,EAAQ9qG,OAAS,GACnB2rG,EAAWrqG,KAAK,CACdskB,KAAMklF,EAAQhrG,OAAQ6D,QAAQ,GAC9B6a,EAAGY,KAAK2E,MAAMhkB,KAAKoiB,GAAG2oF,EAAQhrG,SAC9B2mB,WAAY+kF,IAIhB,MACM3mF,EAAO9kB,KAAKyH,OAAS6zB,EAAkB9U,OAAO/e,OAAS6zB,EAAkBhV,IAAI7e,OACnFmkG,EAAWrjG,SAASsjG,IACdA,EAAaptF,GAHN,GAGmBotF,EAAaptF,GAAKqG,GAC9Ce,EAAK1G,IAAI0sF,GAAchkF,OAAOnJ,EAChC,IAGFO,EAAUgyB,MACZ,CAEAld,cAAAA,GACE,MAAM/d,EAAS,CACbL,KAAM,SACN7G,MAAO,SACP1L,KAAM,SACNwK,MAAO5N,KAAKgW,QAAU,GACtB2P,UAAU,EACVjB,IAAK,EACLG,IAAK,QAGP,MAAO,CACLrhB,MAAOxD,KAAK8O,MACZmS,OAAQ,CAACjL,GACT2yF,oBAAqB,CACnB3yF,OAAS,GAAEA,EAAOlH,wCAAwCkH,EAAO0O,WAAW1O,EAAO6O,OAGzF,CAEAilF,UAAAA,CAAWn8F,GACT,MACO,WADCA,GAEG3N,KAAK+pG,sBAAsB,CAAEp8F,OAI1C,CAEApJ,QAAAA,GACE,MAAQ,SAAQvE,KAAKgW,QACvB,EAGF,UCrKA,MAAM81F,UAAwB3hG,EAC5BoT,YAAc3H,EAAAA,GAAc6zF,OAC5BlsF,aAAe,mBAEfouF,iBAA4C,KAG5CxsF,GAAAA,CAAIjX,GACF+B,MAAMkV,IAAIjX,GACVlI,KAAKuoG,eAAergG,EACtB,CAEAy+F,OAAAA,GACE,IAAK3mG,KAAK+mG,sBAAkD,OAA1B/mG,KAAK2rG,iBAA2B,OAElE3rG,KAAK2rG,iBAAmB,IAAIb,EAAiB,CAC3CnhG,MAAO3J,KAAK4E,KACZF,QAAS,CAAEsR,OAAQhW,KAAKgW,UAG1BhW,KAAK2rG,iBAAiBlG,YAEtBzlG,KAAKymG,UAAYzmG,KAAK2rG,iBAAiB/F,iBAAiBqF,WAAWlrG,QAAU,KAC7E,MAAM,IAAE2kB,EAAG,IAAEG,GAAQ7kB,KAAK0oG,kBAAkB1oG,KAAK2V,MACjD3V,KAAK0kB,IAAMA,EACX1kB,KAAK6kB,IAAMA,CACb,CAEA+hF,eAAAA,CAAgBloF,GACd1e,KAAK6nG,yBACHnpF,EACA1e,KAAK2rG,kBAAkB/F,iBAAiBqF,YAAc,GACtDjrG,KAAKgW,OACL,EACA,EACA,GACA,EAEJ,CAEA+d,cAAAA,GACE,MAAM/d,EAAS,CACbL,KAAM,SACN7G,MAAO,SACP1L,KAAM,SACNwK,MAAO5N,KAAKgW,QAAU,GACtB2P,UAAU,EACVjB,IAAK,EACLG,IAAK,QAGP,MAAO,CACLrhB,MAAOxD,KAAK8O,MACZmS,OAAQ,CAACjL,GACT2yF,oBAAqB,CACnB3yF,OAAS,GAAEA,EAAOlH,wCAAwCkH,EAAO0O,WAAW1O,EAAO6O,OAGzF,CAEAilF,UAAAA,CAAWn8F,GACT,MACO,WADCA,GAEG3N,KAAK+pG,sBAAsB,CAAEp8F,OAI1C,CAEApJ,QAAAA,GACE,MAAQ,oBAAmBvE,KAAKgW,QAClC,EAGF,U,eCzEA,MAAM+1F,UAAY5hG,EAChBoT,YAAc3H,EAAAA,GAAcizF,IAC5BtrF,aAAe,qBAEfitF,IAAgB,GAGhBrrF,GAAAA,CAAIjX,GACF+B,MAAMkV,IAAIjX,GACVlI,KAAKuoG,eAAergG,EACtB,CAEAy+F,OAAAA,GACE,GAAI3mG,KAAK+mG,qBAAsB,CAC7B/mG,KAAKwqG,IAAM,GACX,MAAMA,EAAM,IAAIwB,EAAAA,EAAiBhsG,KAAKgW,QACtC,IAAK,IAAIkM,EAAI,EAAGA,EAAIliB,KAAK4E,KAAKw2B,MAAMn7B,OAAQiiB,IAC1CsoF,EAAIv+F,IAAIjM,KAAK4E,KAAKuX,KAAK+F,GAAIliB,KAAK4E,KAAKmkC,IAAI7mB,GAAIliB,KAAK4E,KAAKw2B,MAAMlZ,EAAI,IACjEliB,KAAKwqG,IAAItoF,GAAKsoF,EAAI58F,MAGpB5N,KAAKymG,UAAYzmG,KAAKwqG,IAAIzqG,QAAU,IACtC,CACA,MAAM,IAAE2kB,EAAG,IAAEG,GAAQ7kB,KAAKwqG,IAAIvqG,OAAS,EAAID,KAAKyjD,qBAAqBzjD,KAAKwqG,KAAOxqG,KAAK0oG,kBAAkB1oG,KAAK2V,MAC7G3V,KAAK0kB,IAAMA,EACX1kB,KAAK6kB,IAAMA,CACb,CAEA+hF,eAAAA,CAAgBloF,GACdA,EAAQS,IAAI,cAAenf,KAAKqe,yBAAyBid,kBAAkBuQ,QAAQttB,OAAO5H,MAC1F+H,EAAQO,UAAU,GAAK,IACvBP,EAAQQ,aACRs4B,EAAAA,EAAAA,IAAkB,CAChB7tC,MAAO3J,KAAK4E,KACZmC,UAAW/G,KAAK0B,MAChBupB,WAAYjrB,KAAKirB,WACjBzjB,MAAOxH,KAAKwH,MACZiwC,gBAAiBA,CAACv1B,EAAW1D,KAC3BE,EAAQc,OAAOhB,EAAGa,KAAK2E,MAAMhkB,KAAKoiB,GAAGpiB,KAAKwqG,IAAItoF,KAAK,IAGvDxD,EAAQe,SACRf,EAAQO,WAAW,IAAM,GAC3B,CAEA8U,cAAAA,GACE,MAAM/d,EAAS,CACbL,KAAM,SACN7G,MAAO,SACP1L,KAAM,SACNwK,MAAO5N,KAAKgW,QAAU,GACtB2P,UAAU,EACVjB,IAAK,EACLG,IAAK,QAGP,MAAO,CACLrhB,MAAOxD,KAAK8O,MACZmS,OAAQ,CAACjL,GACT2yF,oBAAqB,CACnB3yF,OAAS,GAAEA,EAAOlH,wCAAwCkH,EAAO0O,WAAW1O,EAAO6O,OAGzF,CAEAilF,UAAAA,CAAWn8F,GACT,MACO,WADCA,GAEG3N,KAAK+pG,sBAAsB,CAAEp8F,OAI1C,CAEApJ,QAAAA,GACE,MAAQ,OAAMvE,KAAKgW,QACrB,EAGF,UChFA,MAAMi2F,UAA8B9hG,EAClCoT,YAAc3H,EAAAA,GAAc+zF,IAC5BpsF,aAAe,0BAEf2uF,IAAgB,GAGhB/sF,GAAAA,CAAIjX,GACF+B,MAAMkV,IAAIjX,GACVlI,KAAKuoG,eAAergG,EACtB,CAEAy+F,OAAAA,GACE,GAAI3mG,KAAK+mG,qBAAsB,CAC7B,IAAIoF,EACJ,MAAMC,EAAK,GACXpsG,KAAKksG,IAAM,GACX,IAAIG,EAAUF,EAAW,EACzB,IAAK,IAAIjqF,EAAI,EAAGA,EAAIliB,KAAK4E,KAAKw2B,MAAMn7B,OAAQiiB,IAAK,CAC/C,IAAIoqF,EACJ,MAAMC,GAAgBvsG,KAAK4E,KAAKw2B,MAAMlZ,GAAKliB,KAAK4E,KAAKmkC,IAAI7mB,GAAKliB,KAAK4E,KAAKuX,KAAK+F,IAAM,EACnFkqF,EAAGlqF,GAAKqqF,EAERF,GAAUE,EACVJ,IACIA,EAAWnsG,KAAKgW,SAClBq2F,GAAUD,EAAGlqF,EAAIliB,KAAKgW,QACtBm2F,KAEF,MAAMK,EAAMH,EAASF,EAErB,GAAIjqF,EAAIliB,KAAKgW,OAAS,EACpB,SAGF,IAAIy2F,EAAUH,EAAW,EACzB,IAAK,IAAI1J,EAAI1gF,EAAIliB,KAAKgW,OAAS,EAAG4sF,GAAK1gF,EAAG0gF,IACxC6J,GAAUptF,KAAKQ,IAAIusF,EAAGxJ,GAAK4J,GAC3BF,IAGF,MAAMI,EAAMD,EAASH,EACrBtsG,KAAKksG,IAAIhqF,GAAK,EACVwqF,EAAM,IACR1sG,KAAKksG,IAAIhqF,IAAMqqF,EAAeC,IA7CvB,KA6C0CE,GAErD,CAEA1sG,KAAKymG,UAAYzmG,KAAKksG,IAAInsG,QAAU,IACtC,CAEA,MAAM,IAAE2kB,EAAG,IAAEG,GAAQ7kB,KAAKksG,IAAIjsG,OAAS,EAAID,KAAKyjD,qBAAqBzjD,KAAKksG,KAAOlsG,KAAK0oG,kBAAkB1oG,KAAK2V,MAC7G3V,KAAK0kB,IAAMA,EACX1kB,KAAK6kB,IAAMA,CACb,CAEA+hF,eAAAA,CAAgBloF,GACd1e,KAAK6nG,yBAAyBnpF,EAAS1e,KAAKksG,IAAKlsG,KAAKgW,QAAS,IAAK,EAAG,IACzE,CAEA+d,cAAAA,GACE,MAAM/d,EAAS,CACbL,KAAM,SACN7G,MAAO,SACP1L,KAAM,SACNwK,MAAO5N,KAAKgW,QAAU,GACtB2P,UAAU,EACVjB,IAAK,EACLG,IAAK,QAGP,MAAO,CACLrhB,MAAOxD,KAAK8O,MACZmS,OAAQ,CAACjL,GACT2yF,oBAAqB,CACnB3yF,OAAS,GAAEA,EAAOlH,wCAAwCkH,EAAO0O,WAAW1O,EAAO6O,OAGzF,CAEAilF,UAAAA,CAAWn8F,GACT,MACO,WADCA,GAEG3N,KAAK+pG,sBAAsB,CAAEp8F,OAI1C,CAEApJ,QAAAA,GACE,MAAQ,OAAMvE,KAAKgW,QACrB,EAGF,UC5EA,MAAM22F,UAAYxiG,EAChBoT,YAAc3H,EAAAA,GAAcC,IAC5B0H,aAAe,MAEf,yBAAOkU,GACL,OAAO,CACT,CAIAk1E,OAAAA,GACE,IAAK3mG,KAAK+mG,uBAAyB/mG,KAAK4E,KAAK4Q,KAAM,OACnD,MAAMo3F,EAAe3pG,OAAOC,KAAKlD,KAAK4E,KAAK4Q,MAAM,IAC5CxV,KAAK+C,MAAM0S,MAAQm3F,IACtB5sG,KAAK+C,MAAM0S,KAAOm3F,GAEpB,MAAMC,EAAM7sG,KAAK4E,KAAK4Q,KAAKxV,KAAK+C,MAAM0S,OAC/BiP,EAAKG,GAAOklB,EAAAA,GAAMsF,OAAOw9D,EAAIC,kBAAmBD,EAAIE,aAAcF,EAAIG,cAC7EhtG,KAAK6kB,IAAMxF,KAAKwF,IAAIxF,KAAKQ,IAAIgF,GAAMxF,KAAKQ,IAAI6E,IAC5C1kB,KAAK0kB,KAAO1kB,KAAK6kB,GACnB,CAEA+hF,eAAAA,CAAgBloF,GACd,GAAK1e,KAAK4E,KAAK4Q,KAAf,CACAkJ,EAAQO,UAAU,GAAK,IACvB,IAAK,MAAMtR,KAAO3N,KAAK8D,OAAQ,CAC7B4a,EAAQS,IAAI,cAAenf,KAAK8D,OAAO6J,IACvC+Q,EAAQQ,YACR,MAAMta,EAAO5E,KAAK4E,KAAK4Q,KAAKxV,KAAK+C,MAAM0S,MAAM9H,IAC7C6pC,EAAAA,EAAAA,IAAkB,CAChB7tC,MAAO3J,KAAK4E,KACZmC,UAAW/G,KAAK0B,MAChBupB,WAAYjrB,KAAKirB,WACjBzjB,MAAOxH,KAAKwH,MACZiwC,gBAAiBA,CAACv1B,EAAW1D,KAC3BE,EAAQc,OAAOhB,EAAGa,KAAK2E,MAAMhkB,KAAKoiB,GAAGxd,EAAKsd,KAAK,IAGnDxD,EAAQe,QACV,CACAf,EAAQO,WAAW,IAAM,GAjBE,CAkB7B,CAEA6nF,WAAAA,CAAYpoF,GACV,IAAK1e,KAAK4E,KAAK4Q,KAAM,OACrB,MAAM,cAAE0lB,GAAkBl7B,KAAKqe,0BACzB,OAAEE,GAAW2c,EAAc2Q,QAC3BzoC,EAAO,IAAIoiB,EAAAA,EACf,CACEK,KAAM7lB,KAAKuE,WACXia,EAAG,EACHC,EAAG,GACHqH,KAAM,CAAEtW,KAAM,GAAI2G,MAAO,QACzB8P,UAAW1H,EAAOsH,KAClBM,UAAWyQ,EAAAA,GAAUnQ,KACrBL,aAAcsQ,EAAAA,GAAalQ,QAE7BxmB,KAAK0B,OAEP0B,EAAKykB,OAAOnJ,GAEZ,IAAI8G,EAAAA,EACF,CACEK,KAAM7lB,KAAK4E,KAAK4Q,KAAKxV,KAAK+C,MAAM0S,MAAMw3F,MACtCzuF,EAAG,GAAKpb,EAAKutB,UACblS,EAAG,GACHqH,KAAM,CAAEtW,KAAM,GACdyW,UAAW1H,EAAOsH,KAClBM,UAAWyQ,EAAAA,GAAUnQ,KACrBL,aAAcsQ,EAAAA,GAAalQ,QAE7BxmB,KAAK0B,OACLmmB,OAAOnJ,GAET1e,KAAKktG,uBAAuBxuF,EAC9B,CAEA2oF,qBAAAA,CAAsB3oF,GACpB,MAAM,EAAEF,EAAC,EAAEC,EAAC,WAAE+nF,GAAev8F,MAAMo9F,sBAAsB3oF,IAEnD,kBAAE4c,GAAsBt7B,KAAKqe,yBAC7BnO,EAAalQ,KAAK0B,MAAMgI,QAAQkqB,eAAeltB,QAAUgC,EAAAA,GAAMyoF,KAC/Dgc,EAAkB3G,EAAiB,EAAJhoF,EAC/B4uF,EAAe9xE,EAAkB7U,KAAK8gF,eAAezhF,KAGrDunF,EAAiB,IAAI7nF,EAAAA,EACzB,CACEK,KAAM7lB,KAAK4E,KAAK4Q,KAAKxV,KAAK+C,MAAM0S,MAAMw3F,MACtCzuF,EAAG2uF,EAAkB3uF,EACrBsH,KAAMN,EAAAA,EAAK0e,2BAA2B,OAAQ,IACzCkpE,EACH59F,KAAM49F,EAAa59F,KARA,GAQO49F,EAAa59F,UAA0BnH,EACjE8N,MAAO,WAET8P,UAAWojB,IAAAA,KAAoBn5B,EAAa,GAAK,KACjDiW,UAAWyQ,EAAAA,GAAUnQ,KACrBL,aAAcsQ,EAAAA,GAAaC,QAE7B32B,KAAK0B,OAEP2rG,EAAeluF,IAAI,CACjBV,EAAGA,GAlBoB,GAkBforC,EAAAA,GAlBe,GAkB8BwjD,EAAetqG,MAAMmjB,WAAiC,KAE7GmnF,EAAexlF,OAAOnJ,GAEtB1e,KAAKktG,uBAAuBxuF,EAC9B,CAEAwuF,sBAAAA,CAAuBxuF,GACrB,MAAM,cAAEwc,EAAa,kBAAEI,GAAsBt7B,KAAKqe,0BAC5C,OAAEE,GAAW2c,EAAc2Q,QAEjC,IAAIrmB,EAAAA,EACF,CACEK,KAAM,MACNrH,EAAG,GACHC,EAAG6c,EAAkBhV,IAAI7e,QAAU6zB,EAAkB9U,OAAO/e,OAASzH,KAAK+3C,eAAiB,EAC3F34B,OAAQ,GACR0G,KAAM,CAAEtW,KAAM,GAAIwW,OAAQ,MAAOD,OAAQ,oBACzCE,UAAW1H,EAAOguB,cAClBpmB,UAAWyQ,EAAAA,GAAUC,OACrBzQ,aAAcsQ,EAAAA,GAAauN,YAE7BjkC,KAAK0B,OACLmmB,OAAOnJ,GAET,MAAMmH,EAAO,IAAIL,EAAAA,EACf,CACEK,KAAM,qBACNrH,EAAG8c,EAAkB7U,KAAKjf,MAC1BiX,EAAG6c,EAAkBhV,IAAI7e,OAASzH,KAAK+3C,cAAgBzc,EAAkB9U,OAAO/e,OAAS,EACzFqe,KAAM,CAAEtW,KAAM,EAAG2G,MAAO,QACxB8P,UAAWjmB,KAAK8D,OAAOgpG,kBACvB3mF,UAAWyQ,EAAAA,GAAUnQ,KACrBL,aAAcsQ,EAAAA,GAAalQ,QAE7BxmB,KAAK0B,OAEPmkB,EAAKgC,OAAOnJ,GAEZ,IAAIF,EAAIqH,EAAKqN,IAAI,KAAQ,EAAIrN,EAAK8K,UAClC9K,EAAK1G,IAAI,CAAE0G,KAAM,gBAAiBrH,IAAGyH,UAAWjmB,KAAK8D,OAAOipG,eAC5DlnF,EAAKgC,OAAOnJ,GAEZF,GAAK,EAAIqH,EAAK8K,UACd9K,EAAK1G,IAAI,CAAE0G,KAAM,gBAAiBrH,IAAGyH,UAAWjmB,KAAK8D,OAAOkpG,eAC5DnnF,EAAKgC,OAAOnJ,EACd,CAEAuoF,UAAAA,CAAWr5F,GAGT,OADe5N,KAAK0B,MAAMyV,MAAMsH,EAClBu4B,WAAW,EAAG,IAArB1nB,CAA0B1hB,GAAOyL,QAAQ,IAAK,IACvD,CAEA0a,cAAAA,GACE,MAAO,CACLvwB,MAAO,MACPyd,OAAQ,GACR0nF,oBAAqB,CAAC,EAE1B,CAEApkG,QAAAA,GACE,OAAOvE,KAAK4E,MAAM4Q,KAAQxV,KAAK4E,KAAK4Q,KAAKxV,KAAK+C,MAAM0S,MAAMrS,UAAkBiF,CAC9E,CAEA6B,QAAAA,GACE,MAAO,CACLyL,KAAM3V,KAAK2V,KACXF,KAAMzV,KAAK+C,MAAM0S,KAErB,EAGFk3F,EAAI7sG,UAAUgE,OAAS,CACrBgpG,kBAAmB,UACnBC,aAAc,UACdC,aAAc,WAGhB,U,eCpMO,MAAMM,UAAsBjI,EAAAA,EACjC9nF,YAAc3H,EAAAA,GAAcg0F,GAE5BrE,0BAAAA,GACE,MAAO,CAAEgI,GAAI,GACf,CAEA9H,SAAAA,CAAUC,GACR,MAAM,OAAE1vF,GAAWhW,KAAK0E,SAClB,MAAE02B,EAAK,OAAEe,GAAWn8B,KAAK2J,MACzB67F,EAAM,IAAIN,EAAAA,EAAyBlvF,GACzChW,KAAK2lG,kBAAoB3lG,KAAKulG,6BAE9B,IAAK,IAAItjG,EAAQ,EAAGA,EAAQm5B,EAAMn7B,OAAQgC,IAAS,CACjD,MAAM2L,GAAUwtB,EAAMn5B,GAASm5B,EAAMn5B,EAAQ,IAAMk6B,EAAOl6B,GAAU,IAIpE,GAHAujG,EAAIv5F,IAAI2B,GACR5N,KAAK4lG,iBAAiB2H,GAAGtrG,GAASujG,EAAI53F,OAEoB,IAAtD83F,IAAoB1lG,KAAK4lG,iBAAkB3jG,GAC7C,KAEJ,CACF,EC1BF,MAAMurG,UAAmBrjG,EACvBoT,YAAc3H,EAAAA,GAAcg0F,GAC5BrsF,aAAe,cAEfkwF,cAAsC,KAGtCtuF,GAAAA,CAAIjX,GACF+B,MAAMkV,IAAIjX,GACVlI,KAAKuoG,eAAergG,EACtB,CAEAy+F,OAAAA,GACM3mG,KAAK+mG,uBACP/mG,KAAKytG,cAAgB,IAAIH,EAAc,CACrC3jG,MAAO3J,KAAK4E,KACZF,QAAS,CACPsR,OAAQhW,KAAKgW,UAGjBhW,KAAKytG,cAAchI,YACnBzlG,KAAKymG,UAAYzmG,KAAKytG,cAAc7H,iBAAiB2H,GAAGxtG,QAAU,MAEpE,MAAMwtG,EAAKvtG,KAAKytG,eAAe7H,iBAAiB2H,IAAM,IAChD,IAAE7oF,EAAG,IAAEG,GAAQ0oF,EAAGttG,OAAS,EAAID,KAAKyjD,qBAAqB8pD,GAAMvtG,KAAK0oG,kBAAkB1oG,KAAK2V,MACjG3V,KAAK0kB,IAAMA,EACX1kB,KAAK6kB,IAAMA,CACb,CAEA+hF,eAAAA,CAAgBloF,GACd1e,KAAK6nG,yBAAyBnpF,EAAS1e,KAAKytG,eAAe7H,iBAAiB2H,IAAM,GAAI,EAAG,EAAG,EAAG,GAAG,EACpG,CAEAx5E,cAAAA,GACE,MAAM/d,EAAS,CACbL,KAAM,SACN7G,MAAO,SACP1L,KAAM,SACNwK,MAAO5N,KAAKgW,QAAU,GACtB2P,UAAU,EACVjB,IAAK,EACLG,IAAK,QAGP,MAAO,CACLrhB,MAAOxD,KAAK8O,MACZmS,OAAQ,CAACjL,GACT2yF,oBAAqB,CACnB3yF,OAAS,GAAEA,EAAOlH,wCAAwCkH,EAAO0O,WAAW1O,EAAO6O,OAGzF,CAEAilF,UAAAA,CAAWn8F,GACT,MACO,WADCA,GAEG3N,KAAK+pG,sBAAsB,CAAEp8F,OAI1C,CAEApJ,QAAAA,GACE,MAAQ,SAAQvE,KAAKgW,QACvB,EAGF,UC3DO,MAAM03F,UAAwBrI,EAAAA,EACnC9nF,YAAc3H,EAAAA,GAAcyzF,KAE5B9D,0BAAAA,GACE,MAAO,CACLoI,KAAM,GACNC,OAAQ,GACRC,UAAW,GAEf,CAEApI,SAAAA,CAAUC,GACR,MAAM,MAAEtqE,GAAUp7B,KAAK2J,OACjB,WAAEmkG,EAAU,WAAEC,EAAU,aAAEC,GAAiBhuG,KAAK0E,QAChDupG,EAAU,IAAI/I,EAAAA,EAAyB4I,GACvCI,EAAU,IAAIhJ,EAAAA,EAAyB6I,GACvCI,EAAY,IAAIjJ,EAAAA,EAAyB8I,GAC/ChuG,KAAK2lG,kBAAoB3lG,KAAKulG,6BAE9B,IAAK,IAAIrjF,EAAI,EAAGA,EAAIkZ,EAAMn7B,OAAQiiB,IAAK,CACrC,MAAM4J,EAAIsP,EAAMlZ,GAEhB+rF,EAAQhiG,IAAI6f,GACZoiF,EAAQjiG,IAAI6f,GACZ,MAAM6hF,EAAOM,EAAQrgG,MAAQsgG,EAAQtgG,MAOrC,GANAugG,EAAUliG,IAAI0hG,GAEd3tG,KAAK4lG,iBAAiB+H,KAAKzrF,GAAKyrF,EAChC3tG,KAAK4lG,iBAAiBgI,OAAO1rF,GAAKisF,EAAUvgG,MAC5C5N,KAAK4lG,iBAAiBiI,UAAU3rF,GAAKyrF,EAAOQ,EAAUvgG,OAEA,IAAlD83F,IAAoB1lG,KAAK4lG,iBAAkB1jF,GAC7C,KAEJ,CACF,ECpCF,MAAMksF,UAAajkG,EACjBoT,YAAc3H,EAAAA,GAAcyzF,KAC5B9rF,aAAe,OAEf,yBAAOkU,CAAkB9pB,GAAkE,IAAjE,OAAEqO,GAA6DrO,EACvF,MAAOmmG,EAAa,EAAGC,EAAa,EAAGC,EAAe,IAAKzH,EAAAA,EAAAA,IAAkCvwF,GAC7F,OAAOqJ,KAAKwF,IAAIipF,EAAYC,EAAYC,EAC1C,CAEAK,gBAA0C,KAM1ClvF,GAAAA,CAAIjX,GACF,GAA6B,iBAAlBA,EAAO8N,OAAqB,CACrC,MAAO83F,EAAa,EAAGC,EAAa,EAAGC,EAAe,IAAKzH,EAAAA,EAAAA,IAAkCvmG,KAAK+C,MAAMiT,QACxG/L,MAAMkV,IAAI,IAAKjX,EAAQ4lG,aAAYC,aAAYC,gBACjD,MACE/jG,MAAMkV,IAAIjX,EAEd,CAEAy+F,OAAAA,IACM3mG,KAAK+mG,sBAAiD,OAAzB/mG,KAAKquG,mBACpCruG,KAAKquG,gBAAkB,IAAIX,EAAgB,CACzC/jG,MAAO3J,KAAK4E,KACZF,QAAS,CACPspG,aAAchuG,KAAKguG,aACnBF,WAAY9tG,KAAK8tG,WACjBC,WAAY/tG,KAAK+tG,cAGrB/tG,KAAKquG,gBAAgB5I,YAErBzlG,KAAKymG,UAAYzmG,KAAKquG,gBAAgBzI,iBAAiB+H,KAAK5tG,QAAU,MAGxE,MAAM,KAAE4tG,EAAI,UAAEE,EAAS,OAAED,GAAW5tG,KAAKquG,gBAAgBzI,kBAEnD,IAAElhF,EAAG,IAAEG,GACX8oF,EAAK1tG,OAAS,GAAK2tG,EAAO3tG,OAAS,GAAK4tG,EAAU5tG,OAAS,EACvDD,KAAKyjD,qBAAqBkqD,EAAMC,EAAQC,GACxC7tG,KAAK0oG,kBAAkB1oG,KAAK2V,MAClC3V,KAAK0kB,IAAMA,EACX1kB,KAAK6kB,IAAMA,CACb,CAEA+hF,eAAAA,CAAgBloF,GACd,MAAM,kBAAE4c,GAAsBt7B,KAAKqe,yBACnC,GAA6B,OAAzBre,KAAKquG,iBAAuD,IAA3BruG,KAAK4E,KAAKw2B,MAAMn7B,OAAc,OACnE,MAAMwe,EAAIY,KAAK2E,MAAMhkB,KAAKoiB,GAAG,IACvBhY,EAAapK,KAAK0B,MAAMgI,SACxB,WAAEirC,GAAevqC,GACjB,aAAEu2C,EAAY,eAAEC,IAAmBC,EAAAA,EAAAA,IAA6B,CACpElM,aACA3jC,YAAa5G,EAAWwpB,iBAEpB0jB,EAAwBqJ,EAAgC,EAAjBC,EACvCxJ,IAAiB/3B,KAAKwF,IAAI,EAAGyyB,EAAwB,IACrD,KAAEq2D,EAAI,UAAEE,EAAS,OAAED,GAAW5tG,KAAKquG,gBAAgBzI,iBACnDoC,EAAyB,CAC7Br+F,MAAO3J,KAAK4E,KACZmC,UAAW/G,KAAK0B,MAChBupB,WAAYjrB,KAAKirB,WACjBzjB,MAAOxH,KAAKwH,OAGdkX,EAAQS,IAAI,YAAa,WACzBT,EAAQQ,aACRs4B,EAAAA,EAAAA,IAAkB,IACbwwD,EACHvwD,gBAAiBA,CAACv1B,EAAG1D,KACnBE,EAAQilB,KAAKnlB,EAAI44B,EAAc34B,EAAG64B,EAAuBj4B,KAAK2E,MAAMhkB,KAAKoiB,GAAGyrF,EAAU3rF,IAAMzD,GAAG,IAGnGC,EAAQkD,OAERlD,EAAQO,UAAU,GAAK,IACvBP,EAAQS,IAAI,cAAemc,EAAkBuQ,QAAQttB,OAAO5H,MAC5D+H,EAAQQ,aAERs4B,EAAAA,EAAAA,IAAkB,IACbwwD,EACHvwD,gBAAiBA,CAACv1B,EAAG1D,KACnBE,EAAQc,OAAOhB,EAAGa,KAAK2E,MAAMhkB,KAAKoiB,GAAGurF,EAAKzrF,KAAK,IAGnDxD,EAAQe,SAERf,EAAQS,IAAI,cAAemc,EAAkBuQ,QAAQttB,OAAO+vF,YAC5D5vF,EAAQQ,aACRs4B,EAAAA,EAAAA,IAAkB,IACbwwD,EACHvwD,gBAAiBA,CAACv1B,EAAG1D,KACnBE,EAAQc,OAAOhB,EAAGa,KAAK2E,MAAMhkB,KAAKoiB,GAAGwrF,EAAO1rF,KAAK,IAGrDxD,EAAQe,SACRf,EAAQO,WAAW,IAAM,GAC3B,CAEA8U,cAAAA,GACE,MAAM+5E,EAAa,CACjBn4F,KAAM,SACN7G,MAAO,SACP1L,KAAM,aACNwK,MAAO5N,KAAK8tG,YAAc,GAC1BnoF,UAAU,EACVjB,IAAK,EACLG,IAAK,QAEDkpF,EAAa,CACjBp4F,KAAM,SACN7G,MAAO,OACP1L,KAAM,aACNwK,MAAO5N,KAAK+tG,YAAc,GAC1BpoF,UAAU,EACVjB,IAAK,EACLG,IAAK,QAEDmpF,EAAe,CACnBr4F,KAAM,SACN7G,MAAO,SACP1L,KAAM,eACNwK,MAAO5N,KAAKguG,cAAgB,EAC5BroF,UAAU,EACVjB,IAAK,EACLG,IAAK,QAGP,MAAO,CACLrhB,MAAOxD,KAAK8O,MACZmS,OAAQ,CAAC6sF,EAAYC,EAAYC,GACjCrF,oBAAqB,CACnBmF,WAAa,GAAEA,EAAWh/F,wCAAwCg/F,EAAWppF,WAAWopF,EAAWjpF,MACnGkpF,WAAa,GAAEA,EAAWj/F,wCAAwCi/F,EAAWrpF,WAAWqpF,EAAWlpF,MACnGmpF,aAAe,GAAEA,EAAal/F,wCAAwCk/F,EAAatpF,WAAWspF,EAAanpF,OAGjH,CAEAilF,UAAAA,CAAWn8F,GACT,OAAQA,GACN,IAAK,aACL,IAAK,aACL,IAAK,eACH,OAAO3N,KAAK+pG,sBAAsB,CAAEp8F,QACtC,QACE,OAAO,EAEb,CAEApJ,QAAAA,GACE,MAAQ,QAAOvE,KAAK8tG,cAAc9tG,KAAK+tG,cAAc/tG,KAAKguG,cAC5D,EAGF,UCvKA,MAAMO,UAAYpkG,EAChBoT,YAAc3H,EAAAA,GAAcozF,IAC5BzrF,aAAe,mBAEfixF,IAAgB,GAGhBrvF,GAAAA,CAAIjX,GACF+B,MAAMkV,IAAIjX,GACVlI,KAAKuoG,eAAergG,EACtB,CAEAy+F,OAAAA,GACE,IAAK3mG,KAAK+mG,qBAAsB,OAEhC,IAAI0H,EACJ,MAAMC,EAAK,GACX1uG,KAAKwuG,IAAM,GACX,IAAIG,GAAoB3uG,KAAK4E,KAAKw2B,MAAM,GAAKp7B,KAAK4E,KAAKmkC,IAAI,GAAK/oC,KAAK4E,KAAKuX,KAAK,IAAM,EACjFyyF,EAAqBH,EAAoB,EAC7C,IAAK,IAAIvsF,EAAI,EAAGA,EAAIliB,KAAK4E,KAAKw2B,MAAMn7B,OAAQiiB,IAAK,CAC/C,MAAMqqF,GAAgBvsG,KAAK4E,KAAKw2B,MAAMlZ,GAAKliB,KAAK4E,KAAKmkC,IAAI7mB,GAAKliB,KAAK4E,KAAKuX,KAAK+F,IAAM,EAC7E2sF,EAAYtC,EAAevsG,KAAK4E,KAAKu3B,OAAOja,GAUlD,GARIqqF,EAAeoC,GACjBC,GAAqBC,EACrBH,EAAGxsF,GAAK2sF,GACCtC,EAAeoC,IACxBF,GAAqBI,EACrBH,EAAGxsF,IAAM2sF,GAGP3sF,EAAIliB,KAAKgW,OAAQ,CACnB,MAAM84F,EAAQJ,EAAGxsF,EAAIliB,KAAKgW,QACtB84F,EAAQ,EACVF,GAAqBE,EACZA,EAAQ,IACjBL,GAAqBK,GAIrB9uG,KAAKwuG,IAAItsF,GADP0sF,EAAoBH,EAAoB,EACP,IAApBG,GAA4BA,EAAoBH,GAEjD,EAElB,CAEAE,EAAmBpC,CACrB,CAEAvsG,KAAKymG,UAAYzmG,KAAKwuG,IAAIzuG,QAAU,KACpC,MAAM,IAAE2kB,EAAG,IAAEG,GAAQ7kB,KAAK0oG,kBAAkB1oG,KAAK2V,MACjD3V,KAAK0kB,IAAMA,EACX1kB,KAAK6kB,IAAMA,CACb,CAEA+hF,eAAAA,CAAgBloF,GACd1e,KAAK6nG,yBAAyBnpF,EAAS1e,KAAKwuG,IAAKxuG,KAAKgW,OAAQ,GAAI,GAAI,GACxE,CAEA+d,cAAAA,GACE,MAAM/d,EAAS,CACbL,KAAM,SACN7G,MAAO,SACP1L,KAAM,SACNwK,MAAO5N,KAAKgW,QAAU,GACtB2P,UAAU,EACVjB,IAAK,EACLG,IAAK,QAGP,MAAO,CACLrhB,MAAOxD,KAAK8O,MACZmS,OAAQ,CAACjL,GACT2yF,oBAAqB,CACnB3yF,OAAS,GAAEA,EAAOlH,wCAAwCkH,EAAO0O,WAAW1O,EAAO6O,OAGzF,CAEAilF,UAAAA,CAAWn8F,GACT,MACO,WADCA,GAEG3N,KAAK+pG,sBAAsB,CAAEp8F,OAI1C,CAEApJ,QAAAA,GACE,MAAQ,OAAMvE,KAAKgW,QACrB,EAGF,UClGA,MAAM6C,UAAa1O,EACjBoT,YAAc3H,EAAAA,GAAciD,KAC5B0E,aAAe,OAEfopF,OAAAA,GAAW,CAEXC,eAAAA,GAAmB,CAEnBriG,QAAAA,GACE,MAAO,EACT,EAGF,UCXA,MAAMwqG,UAAY5kG,EAChBoT,YAAc3H,EAAAA,GAAco5F,IAC5BzxF,aAAe,oBAEf0xF,IAAgB,GAEhBtI,OAAAA,GACE,GAAI3mG,KAAK+mG,qBAAsB,CAC7B/mG,KAAKivG,IAAM,CAAC,GAEZ,IAAK,IAAI/sF,EAAI,EAAGA,EAAIliB,KAAK4E,KAAKu3B,OAAOl8B,OAAQiiB,IAAK,CAChD,IAAIgtF,EAAalvG,KAAKivG,IAAI/sF,EAAI,GAC1BliB,KAAK4E,KAAKw2B,MAAMlZ,GAAKliB,KAAK4E,KAAKw2B,MAAMlZ,EAAI,GAC3CgtF,GAAclvG,KAAK4E,KAAKu3B,OAAOja,GACtBliB,KAAK4E,KAAKw2B,MAAMlZ,GAAKliB,KAAK4E,KAAKw2B,MAAMlZ,EAAI,KAClDgtF,GAAclvG,KAAK4E,KAAKu3B,OAAOja,IAGjCliB,KAAKivG,IAAI/sF,GAAKgtF,CAChB,CAEAlvG,KAAKymG,UAAYzmG,KAAKivG,IAAIlvG,QAAU,IACtC,CACA,MAAM,IAAE2kB,EAAG,IAAEG,GAAQ7kB,KAAKivG,IAAIhvG,OAAS,EAAID,KAAKyjD,qBAAqBzjD,KAAKivG,KAAOjvG,KAAK0oG,kBAAkB1oG,KAAK2V,MAC7G3V,KAAK0kB,IAAMA,EACX1kB,KAAK6kB,IAAMA,CACb,CAEA+hF,eAAAA,CAAgBloF,GACdA,EAAQS,IAAI,cAAenf,KAAKqe,yBAAyBid,kBAAkBuQ,QAAQttB,OAAO5H,MAC1F+H,EAAQO,UAAU,GAAK,IACvBP,EAAQQ,aACRs4B,EAAAA,EAAAA,IAAkB,CAChB7tC,MAAO3J,KAAK4E,KACZmC,UAAW/G,KAAK0B,MAChBupB,WAAYjrB,KAAKirB,WACjBzjB,MAAOxH,KAAKwH,MACZiwC,gBAAiBA,CAACv1B,EAAW1D,KAC3BE,EAAQc,OAAOhB,EAAGa,KAAK2E,MAAMhkB,KAAKoiB,GAAGpiB,KAAKivG,IAAI/sF,KAAK,IAGvDxD,EAAQe,SACRf,EAAQO,WAAW,IAAM,GAC3B,CAEAgoF,UAAAA,CAAWr5F,GACT,OAAOkT,EAAAA,GAAKiiF,gBAAgBn1F,EAAO,EACrC,CAEAmmB,cAAAA,GACE,MAAO,CACLvwB,MAAOxD,KAAK8O,MACZmS,OAAQ,GACR0nF,oBAAqB,CAAC,EAE1B,CAEApkG,QAAAA,GACE,MAAO,KACT,EAGF,W,oDCtCA,MAAM4qG,WAAyBhlG,EAC7BoT,YAAc3H,EAAAA,GAAc8xF,KAC5BnqF,aAAe,sBAEf,yBAAOkU,GACL,OAAO,CACT,CAEAhd,UACA2vC,QAAU,GACVknB,OAAQ,EACR8jC,kBAAmB,EACnB3sD,MAAoB,CAAC,EACrB8C,KAAmB,CAAC,EACpBrB,OAA4B,CAAC,EAC7BmrD,oBAAkC,CAAC,EAEnClsG,WAAAA,CAAYJ,EAAcrB,GACxBuI,MAAMlH,EAAOrB,GACb1B,KAAKmqC,YAAcnqC,KAAKmqC,YAAYxpC,KAAKX,MAEzCA,KAAKyU,UAAYzU,KAAK0B,MAAMgI,QAAQ+K,UACpCzU,KAAKoiB,GAAKytB,GAAAA,MAAiBzD,MAAM,CAAC,EAAGpsC,KAAK+3C,gBACtC/3C,KAAK+C,MAAMiT,SAAWhW,KAAKokD,UAC7BpkD,KAAKokD,QAAUpkD,KAAK+C,MAAMiT,OAE9B,CAEA,aAAM2wF,GACJ,MAAMviD,EAAUpkD,KAAKsvG,aACfjhG,EAAmBrO,KAAK0B,MAAMgI,QAAQkqB,eACtC27E,EAAYlhG,EAAiBmgD,KAC7BghD,EAAgBxvG,KAAKyvG,yBAAyBv6C,OAClDvtD,IAAA,IAAC,OAAEikC,EAAM,WAAE/4B,EAAU,UAAE4B,GAAW9M,EAAA,OAChC6C,GAAAA,EAAMo6C,QACHD,GACCA,EAAE/Y,SAAWA,GACb+Y,EAAE9xC,aAAeA,GACjB8xC,EAAElwC,YAAcA,GAChBpG,EAAiBw2C,SAASF,EAAEG,SAC5ByqD,IAAc5qD,EAAE4qD,YACf5qD,EAAEpxC,aACLtT,OAAS,CAAC,IAGhB,GAAID,KAAKyU,YAAczU,KAAK0B,MAAMgI,QAAQC,QAAQ8K,YAAezU,KAAKsrE,QAAUtrE,KAAKovG,iBAInF,GAHApvG,KAAKyU,UAAYzU,KAAK0B,MAAMgI,QAAQC,QAAQ8K,UAC5CzU,KAAKovG,kBAAmB,EAEnBI,EAOHxvG,KAAKsrE,OAAQ,EACbtrE,KAAK2mG,cARa,CAClB,MAAM/hG,QAAa4F,GAAAA,EAAMklG,OAAO1vG,KAAKyvG,0BACjC7qG,IACF5E,KAAKwjD,SAASY,EAASx/C,GACvB5E,KAAKuJ,QAAQ,UAEjB,MAIK,GAAIvJ,KAAKsrE,MAAO,CACrB,MAAM1mE,EAA0B,CAAC,EACjC,IAAK,MAAMgnC,KAAUwY,EACnBx/C,EAAKgnC,GAAUphC,GAAAA,EAAMo6C,QAClBD,GACCA,EAAE/Y,SAAWA,GACb+Y,EAAElwC,YAAczU,KAAKyU,WACrB86F,IAAc5qD,EAAE4qD,WAChBlhG,EAAiBw2C,SAASF,EAAEG,UAC9B,GAEJ9kD,KAAKwjD,SAASY,EAASx/C,EACzB,CACF,CAEA4+C,QAAAA,CAASY,EAAmBx/C,GAC1B,MAAM,WAAEqmB,GAAejrB,KAAK0B,MAAMgI,QAClC,IAAIimG,EAAe,KACfC,EAAc,KAClB,IAAK,IAAI1tF,EAAI,EAAGA,EAAIliB,KAAK4E,KAAKw2B,MAAMn7B,OAAQiiB,IAAK,CAC/C,MAAM2U,EAAS72B,KAAKmiB,GAAGD,GACnB2U,EAAS5L,EAAa,GAAK4L,EAAS5L,EAAajrB,KAAK83C,eAMrC,OAAjB63D,IACFA,EAAe3vG,KAAK4E,KAAK4iC,KAAKtlB,IAGhC0tF,EAAc5vG,KAAK4E,KAAK4iC,KAAKtlB,GAC/B,CAEAtd,EAAK5E,KAAK4E,KAAKgnC,QAAU5rC,KAAK4E,KAC9B5E,KAAKkkD,OAASt/C,EACd5E,KAAKulD,KAAO,CAAC,EACb,MAAMsqD,EAAc7vG,KAAK4E,KAAKkrG,iBAC9B,IAAK,MAAMlkE,IAAU,CAAC5rC,KAAK4E,KAAKgnC,UAAWwY,GAAU,CACnDpkD,KAAKulD,KAAK3Z,GAAU,GACpB,MAAM9f,EAAIlnB,EAAKgnC,GACf,IAAK9f,EACH,SAEF,IAAI22B,EAAQ,KACRxgD,GAAS,EACb,IAAK,IAAIigB,EAAI,EAAGA,EAAI4J,EAAEsP,MAAMn7B,OAAQiiB,IAAK,CACvC,MAAMslB,EAAO1b,EAAE0b,KAAKtlB,GAChBslB,EAAOmoE,GAAiBnoE,EAAOooE,IAInC3tG,EAAQ4tG,EAAYroE,GAChBvlC,UAIU,OAAVwgD,IACFA,EAAQ32B,EAAEsP,MAAMlZ,GAChBliB,KAAKyiD,MAAM7W,GAAU6W,EACjBxgD,EAAQ,IACVjC,KAAKulD,KAAK3Z,GAAQ3pC,EAAQ,GAAmB,IAAb6pB,EAAEsP,MAAMlZ,GAAYugC,EAAQ,MAIhEziD,KAAKulD,KAAK3Z,GAAQ3pC,GAAuB,IAAb6pB,EAAEsP,MAAMlZ,GAAYugC,EAAQ,KAC1D,CAEIxgD,EAAQjC,KAAK4E,KAAK4iC,KAAKvnC,OAAS,GAAe,OAAVwiD,IACvCziD,KAAKulD,KAAK3Z,GAAQ3pC,EAAQ,GAAKjC,KAAKulD,KAAK3Z,GAAQ3pC,GAErD,CAEA,MAAM8tG,EAAa9sG,OAAOC,KAAKlD,KAAKulD,MAAM73C,KAAK8Q,GAAMxe,KAAKulD,KAAK/mC,MACzD,IAAEkG,EAAG,IAAEG,GAAQkrF,EAAW5nG,MAAM+6C,GAAUA,EAAMjjD,OAAS,IAC3DD,KAAKyjD,wBAAwBssD,GAC7B/vG,KAAK0oG,kBAAkB1oG,KAAK2V,MAEhC3V,KAAK0kB,IAAMA,EACX1kB,KAAK6kB,IAAMA,EAEX,MAAMzC,EAAKytB,GAAAA,MAERzD,MAAM,CAAC,EAAGpsC,KAAK+3C,gBACf30B,OAAO,CAACpjB,KAAK0B,MAAM+tC,YAAY5qB,KAAO7kB,KAAK6kB,IAAK7kB,KAAK0B,MAAM+tC,YAAY/qB,KAAO1kB,KAAK0kB,MACjF1kB,KAAK0B,MAAM+tC,YACdrtB,EAAG0tB,KAAK,IAGV9vC,KAAK0B,MAAMyV,MAAMsH,EAAIze,KAAKoiB,GAAKA,EAC/BpiB,KAAKsrE,OAAQ,CACf,CAEAs7B,eAAAA,CAAgBloF,GACd,IAAK1e,KAAKsrE,MACR,OAEF,MAAM,eAAErnB,EAAc,kBAAE3oB,GAAsBt7B,KAAKqe,yBACnD,IAAIod,EAAAA,EACF,CACE3d,IAAK9d,KAAKirB,WACVjN,IAAKhe,KAAKirB,WAAajrB,KAAK83C,aAC5B/5B,GAAIsB,KAAK2E,MAAMhkB,KAAKoiB,GAAG,IACvBnE,GAAIoB,KAAK2E,MAAMhkB,KAAKoiB,GAAG,IACvBsZ,YAAa,UACbC,WAAY,GAEd37B,KAAK0B,OACLmmB,OAAOnJ,GAETA,EAAQO,UAAU,GAAK,IACvB,MAAMld,EAAW/B,KAAKsvG,aACtB,IAAK,IAAIrtG,EAAQ,EAAGA,EAAQF,EAAS9B,OAAQgC,IAAS,CACpD,MAAM2pC,EAAS7pC,EAASE,GACxB,GAAIjC,KAAKulD,KAAK3Z,GAAQ3rC,OAAS,EAAG,CAChCye,EAAQS,IAAI,cAAe8kC,EAAehiD,EAAQgiD,EAAehkD,SACjEye,EAAQQ,YACR,IAAK,IAAIgD,EAAI,EAAGA,EAAIliB,KAAKulD,KAAK3Z,GAAQ3rC,OAAQiiB,IAAK,CACjD,MAAMzD,EAAIY,KAAK2E,MAAMhkB,KAAKoiB,GAAGpiB,KAAKulD,KAAK3Z,GAAQ1pB,KAC/CxD,EAAQc,OAAOxf,KAAKmiB,GAAGD,GAAIzD,EAC7B,CACAC,EAAQe,QACV,CACF,CAEAf,EAAQS,IAAI,cAAemc,EAAkBuQ,QAAQttB,OAAO5H,MAC5D+H,EAAQQ,YACR,IAAK,IAAIgD,EAAI,EAAGA,EAAIliB,KAAKulD,KAAKvlD,KAAK4E,KAAKgnC,QAAQ3rC,OAAQiiB,IAAK,CAC3D,MAAMzD,EAAIY,KAAK2E,MAAMhkB,KAAKoiB,GAAGpiB,KAAKulD,KAAKvlD,KAAK4E,KAAKgnC,QAAQ1pB,KACpD8T,MAAMvX,IACTC,EAAQc,OAAOxf,KAAKmiB,GAAGD,GAAIzD,EAE/B,CACAC,EAAQe,SACRf,EAAQO,WAAW,IAAM,GAC3B,CAEA2oF,wBAAAA,CAAyBlpF,EAAmC+5B,GAC1D,IAAK/5B,IAAY+5B,EACf,OAEF,MAAM,eAAEwL,EAAc,cAAE/oB,EAAa,kBAAEI,GAAsBt7B,KAAKqe,0BAC5D,OAAEE,GAAW2c,EAAc2Q,QACjB,CAAC7rC,KAAK4E,KAAKgnC,UAAW5rC,KAAKsvG,cACnC/mG,SAAQ,CAACoF,EAAK1L,KACpB,MAAM+tG,EAA4BhwG,KAAKkkD,SAASlkD,KAAK4E,KAAKgnC,SAASgN,kBAAkB,OAAQH,GACvFw3D,EAAoBD,EACtBhwG,KAAKkkD,SAASv2C,IAAMmiG,mBAAmBE,GACvC,KACEE,EAAoBD,EAC4B,IAAjDjwG,KAAKkkD,SAASv2C,IAAMytB,QAAQ60E,GAA4BjwG,KAAKyiD,MAAM90C,GAAO,IAC3E,KACsB,OAAtBuiG,GAA+Bl6E,MAAMk6E,KACvCxxF,EAAQuH,UAAY1H,EAAOu8B,WAC3Bp8B,EAAQoe,SACNxB,EAAkB7U,KAAK8gF,eAAez7D,OAAOrlB,KAAQkB,EAAAA,GAAQ8b,MAC5DnI,EAAkB7U,KAAK8gF,eAAezhF,KAAKI,WAC1CoV,EAAkB7U,KAAK8gF,eAAeh5D,eACrCtsC,EAAQ,GACTq5B,EAAkB7U,KAAK8gF,eAAez7D,OAAOxlB,IAC7CqB,EAAAA,GAAQ8b,KACV9b,EAAAA,GAAQ8b,KAAOzjC,KAAKqvG,oBAAoB1hG,GAAOga,EAAAA,GAAQ8b,KACvD9b,EAAAA,GAAQ8b,KAAOnI,EAAkB7U,KAAK8gF,eAAezhF,KAAKtW,KAAQmY,EAAAA,GAAQ8b,MAE5E,IAAIje,EAAAA,EACF,CACEK,KAAO,GAAElY,KAAOuiG,EAAkBtsG,QAAQ,MAC1C4a,EAAG8c,EAAkB7U,KAAK8gF,eAAez7D,OAAOrlB,KAChDhI,GACG6c,EAAkB7U,KAAK8gF,eAAezhF,KAAKI,WAC1CoV,EAAkB7U,KAAK8gF,eAAeh5D,eACrCtsC,EAAQ,GACXq5B,EAAkB7U,KAAK8gF,eAAez7D,OAAOxlB,IAC/CR,KAAMN,EAAAA,EAAK0e,2BAA2B,OAAQ5I,EAAkB7U,KAAK8gF,eAAezhF,MACpFG,UACY,IAAVhkB,EAAcsc,EAAO4xF,0BAA4BlsD,EAAehiD,EAAS,EAAIgiD,EAAehkD,QAC9FkmB,UAAWyQ,EAAAA,GAAUnQ,KACrBL,aAAcsQ,EAAAA,GAAapQ,KAE7BtmB,KAAK0B,OACLmmB,OAAOnJ,GACX,GAEJ,CAEAipF,yBAAAA,CAA0BjpF,EAAmC+5B,GAC3D,IAAK/5B,IAAY+5B,EACf,OAGF,MAAM,eAAEwL,EAAc,cAAE/oB,EAAa,kBAAEI,GAAsBt7B,KAAKqe,0BAC5D,OAAEE,GAAW2c,EAAc2Q,QACjC,IAAIukE,GAAa,EACjB,MAAMC,EAAc/0E,EAAkB7U,KAAK8gF,eAAez7D,OAAOxlB,IAAOujC,EAAAA,GAClEzF,EAAU,CAACpkD,KAAK4E,KAAKgnC,UAAW5rC,KAAKsvG,cACrC5jE,EAAa,IAAIlmB,EAAAA,EACrB,CACEM,KAAMN,EAAAA,EAAK0e,2BAA2B,OAAQ,IACzC5I,EAAkB7U,KAAK8gF,eAAezhF,KACzC3P,MAAO,WAETgQ,UAAWyQ,EAAAA,GAAUnQ,KACrBL,aAAcsQ,EAAAA,GAAaC,OAC3BjQ,YAAY2a,EAAAA,GAAAA,IAAwB9iB,EAAOu8B,WAAY,IACvDz0B,QAAS,CAAEC,IAAK,EAAGE,OAAQ,EAAGC,KAAM,EAAGF,MAAO,IAEhDvmB,KAAK0B,OAEP,IAAI8c,EAAI8c,EAAkB7U,KAAK8gF,eAAez7D,OAAOrlB,KACjDhI,EACF6c,EAAkB7U,KAAK8gF,eAAez7D,OAAOxlB,KAAQ,EAAIujC,EAAAA,GAAyBne,EAAW3oC,MAAMmjB,YAAc,EAEnH,MAEMoqF,EAFY5kE,EAAW3oC,MAAMmjB,WAAak+B,EAAQnkD,OAEdowG,GAAerwG,KAAKyH,OAC1DzH,KAAKwH,OAASuiD,EAAAA,KAAiCumD,GACjDF,GAAa,EACb5xF,GAAKA,EAAIxe,KAAKwmG,YAEd/nF,GAAK6c,EAAkB7U,KAAK8gF,eAAez7D,OAAOxlB,IAAOujC,EAAAA,GAG3D,MAAM0mD,EAAcvwG,KAAKkkD,SAASlkD,KAAK4E,KAAKgnC,QACtC4kE,EAAgBnxF,KAAKqF,IAAI+zB,GAAa83D,GAAan1E,MAAMn7B,QAAUyQ,KAAY,GACrF0zC,EAAQ77C,SAAQ,CAACoF,EAAK1L,KACpB,MAAM+tG,EAA4BO,GAAa33D,kBAAkB,OAAQ43D,GACnEP,EAAoBD,EACtBhwG,KAAKkkD,SAASv2C,IAAMmiG,mBAAmBE,GACvC,KACEE,EAAoBD,EAC4B,IAAjDjwG,KAAKkkD,SAASv2C,IAAMytB,QAAQ60E,GAA4BjwG,KAAKyiD,MAAM90C,GAAO,IAC3E,KACJ,GAA0B,OAAtBuiG,IAA+Bl6E,MAAMk6E,GAAoB,CAC3DxkE,EAAWvsB,IAAI,CACbX,IACAC,IACAwH,UACY,IAAVhkB,EAAcsc,EAAO4xF,0BAA4BlsD,EAAehiD,EAAS,EAAIgiD,EAAehkD,QAC9F4lB,KAAO,GAAElY,KAAOuiG,EAAkBtsG,QAAQ,QAE5C,MAAM6sG,EACJ/kE,EAAW/a,QAAQjS,GAAWgtB,EAAW3oC,MAAMsjB,QAAQI,KAAOilB,EAAW3oC,MAAMsjB,QAAQE,OAEtF6pF,GACDpwG,KAAKwH,MAAQ8zB,EAAkB7U,KAAK8gF,eAAez7D,OAAOrlB,KAAQ6U,EAAkB/U,MAAM/e,OACxFgX,EAAIiyF,IAENjyF,EAAI,EAAI8c,EAAkB7U,KAAK8gF,eAAez7D,OAAOrlB,KAAQzmB,KAAKwmG,WAClE/nF,GAAKitB,EAAW3oC,MAAMmjB,WACtBwlB,EAAWvsB,IAAI,CAAEX,IAAGC,OAEtBitB,EAAW7jB,OAAOnJ,GAEd0xF,EACF3xF,GAAKitB,EAAW3oC,MAAMmjB,WAEtB1H,GAAKiyF,CAET,IAEJ,CAEAhlE,WAAAA,CAAY/sB,GACV,GAAK1e,KAAKsrE,MAGV,OAAOrhE,MAAMwhC,YAAY/sB,EAC3B,CAEAyrB,WAAAA,CAAYzrB,GACV,IAAIktB,EACJ3hC,MAAMkgC,YAAYzrB,GAClB,MAAM,kBAAE4c,EAAiB,cAAEJ,EAAa,eAAE+oB,GAAmBjkD,KAAKqe,0BAC5D,OAAEE,GAAW2c,EAAc2Q,QACjC,IAAK7rC,KAAKsrE,MACR,OAEF,GAA2C,IAAvCtrE,KAAKulD,KAAKvlD,KAAK4E,KAAKgnC,QAAQ3rC,OAC9B,OAEF,MAAMgf,GAAYiwB,EAAAA,EAAAA,IAAa,CAC7BxwB,UACA+Q,QAAS6L,EAAkB7U,KAAKjf,MAChCkoB,QAAS4L,EAAkBhV,IAAI7e,SAEjCwX,EAAUkwB,KACV,MAAM,WAAEjpB,EAAU,QAAEG,EAAO,KAAE7W,GAAS8rB,EAAkB/U,MAAMqqB,KAAK9qB,KAC7DD,EAAO,IAAIL,EAAAA,EACf,CACEhH,EAAGxe,KAAK83C,aAAe9L,EAAAA,GAAOa,EAAIxmB,EAASI,KAAQ6U,EAAkB/U,MAAMqqB,KAAK9E,OAAOrlB,KACvFX,KAAMN,EAAAA,EAAK0e,2BAA2B,OAAQ,CAAE10B,SAChD0W,aACAG,QAAS,CACPI,KAAMJ,EAASI,KACfF,MAAOF,EAASE,MAChBD,IAAKD,EAASC,IACdE,OAAQH,EAASG,QAEnBJ,aAAcsQ,EAAAA,GAAaC,OAC3B1Q,UAAW1H,EAAOmyF,WAEpB1wG,KAAK0B,OAEDK,EAAW/B,KAAKsvG,aAChB1D,EAAa,GACnB,IAAK,IAAI3pG,EAAQ,EAAGA,EAAQF,EAAS9B,OAAQgC,IAC3C2pC,EAAS7pC,EAASE,GACdjC,KAAKulD,KAAK3Z,GAAQ3rC,OAAS,GAC7B2rG,EAAWrqG,KAAK,CACdskB,KAAM7lB,KAAKulD,KAAK3Z,GAAQ7rC,OAAO6D,QAAQ,GAAK,IAC5C6a,EAAGY,KAAK2E,MAAMhkB,KAAKoiB,GAAGpiB,KAAKulD,KAAK3Z,GAAQ7rC,SACxC2mB,WAAYu9B,EAAehiD,EAAQgiD,EAAehkD,UAIxD2rG,EAAWrqG,KAAK,CACdskB,KAAM7lB,KAAKulD,KAAKvlD,KAAK4E,KAAKgnC,QAAQ7rC,OAAO6D,QAAQ,GAAK,IACtD6a,EAAGY,KAAK2E,MAAMhkB,KAAKoiB,GAAGpiB,KAAKulD,KAAKvlD,KAAK4E,KAAKgnC,QAAQ7rC,SAClD2mB,WAAYnI,EAAO4xF,4BAGrB,MACMrrF,EAAO9kB,KAAK+3C,cAClB6zD,EAAWrjG,SAASsjG,IACdA,EAAaptF,GAHN,GAGmBotF,EAAaptF,GAAKqG,GAC9Ce,EAAK1G,IAAI0sF,GAAchkF,OAAOnJ,EAChC,IAGFO,EAAUgyB,MACZ,CAEAq2D,oBAAAA,CAAqB5oF,GACnBzU,MAAMq9F,qBAAqB5oF,GAC3B,MAAM,eAAEulC,EAAc,cAAE/oB,EAAa,kBAAEI,GAAsBt7B,KAAKqe,0BAC5D,OAAEE,GAAW2c,EAAc2Q,QACjC,GAAI7rC,KAAKsrE,MAAO,CACd,MAAMlnB,EAAUpkD,KAAKsvG,aACfY,EAAoB,CACxB,CAAE,CAAClwG,KAAK4E,KAAKgnC,QAAS5rC,KAAKulD,KAAKvlD,KAAK4E,KAAKgnC,QAAQ5rC,KAAKulD,KAAKvlD,KAAK4E,KAAKgnC,QAAQ3rC,OAAS,OACpFmkD,EAAQ12C,KAAKk+B,IAAM,CAAQ,CAACA,GAAS5rC,KAAKulD,KAAK3Z,GAAQ5rC,KAAKulD,KAAK3Z,GAAQ3rC,OAAS,QACrF8M,QAAO,CAACu9C,EAAMzrD,KAAY,IAAMyrD,KAASzrD,KAAY,CAAC,GACxDoE,OAAOC,KAAKgtG,GAAmB3nG,SAAQ,CAACoF,EAAK1L,KAC3C,GAAIiuG,EAAkBviG,GAAM,CAC1B,MAAMkY,EAAO,IAAIL,EAAAA,EACf,CACEK,KAAO,GAAElY,KAAOuiG,EAAkBviG,GAAK/J,QAAQ,MAC/C4a,EAAG8c,EAAkB7U,KAAK8gF,eAAez7D,OAAOrlB,KAChDhI,GACG6c,EAAkB7U,KAAK8gF,eAAezhF,KAAKI,WAC1CoV,EAAkB7U,KAAK8gF,eAAeh5D,eACrCtsC,EAAQ,GACXq5B,EAAkB7U,KAAK8gF,eAAez7D,OAAOxlB,IAC/CR,KAAMN,EAAAA,EAAK0e,2BAA2B,OAAQ5I,EAAkB7U,KAAK8gF,eAAezhF,MACpFG,UACY,IAAVhkB,EAAcsc,EAAO4xF,0BAA4BlsD,EAAehiD,EAAS,EAAIgiD,EAAehkD,QAC9FkmB,UAAWyQ,EAAAA,GAAUnQ,KACrBL,aAAcsQ,EAAAA,GAAapQ,KAE7BtmB,KAAK0B,OAEP1B,KAAKqvG,oBAAsB,IAAKrvG,KAAKqvG,oBAAqB,CAAC1hG,GAAMkY,EAAK8K,QAAQjS,IAC9EmH,EAAKgC,OAAOnJ,EACd,IAEJ,CACF,CAEA4wF,UAAAA,GACE,OAAOtvG,KAAKokD,QACTrqB,MAAM,KACNrsB,KAAKk+B,GAAWA,IAChBh0B,QAAQ4G,GAAMA,GACnB,CAEAixF,sBAAAA,GACE,MAAM,UAAEh7F,GAAczU,KAAK0B,MAAMgI,QAAQC,QACzC,OAAO3J,KAAKsvG,aAAa5hG,KAAKk+B,IAAM,CAClCA,SACA/4B,YAAYi3E,EAAAA,EAAAA,IAAcl+C,GAC1Bn3B,eAEJ,CAEA0K,GAAAA,CAAIjX,GACFlI,KAAKsrE,OAAQ,EACbtrE,KAAKovG,kBAAmB,EACxBnlG,MAAMkV,IAAI,IAAKjX,EAAQk8C,QAASl8C,EAAO8N,SAAW9N,EAAOk8C,SAAUusD,EAAAA,GAAAA,GAAmBzoG,EAAOk8C,SAAS,GAAQ,MAC9GpkD,KAAKokD,SAAWpkD,KAAKokD,SAAW,IAAI3e,aACtC,CAEA1R,cAAAA,GACE,MAAO,CACLvwB,MAAOxD,KAAK8O,MACZmS,OAAQ,CACN,CACEtL,KAAM,OACN7G,MAAO,UACP1L,KAAM,UACNwK,MAAS5N,KAAKokD,QAAUpkD,KAAKokD,QA5cf,UA6cdz+B,UAAU,IAGdgjF,oBAAqB,CACnBvkD,QAAS,0CAGf,CAEA0lD,UAAAA,CAAWn8F,GACT,MACO,YADCA,GAEG3N,KAAK2N,GAAK1N,OAAS,CAIhC,CAEAsE,QAAAA,GACE,OAAOvE,KAAK6mG,sCAAwC,SAAY,SAAQ7mG,KAAKokD,SAC/E,EAGF,YCtfA,MAAMwsD,WAAYzmG,EAChBoT,YAAc3H,EAAAA,GAAcqzF,IAC5B1rF,aAAe,0BAEfszF,IAAgB,GAIhB1xF,GAAAA,CAAIjX,GACF,GAA6B,iBAAlBA,EAAO8N,OAAqB,CACrC,MAAOA,EAAS,EAAG86F,EAAW,IAAKvK,EAAAA,EAAAA,IAAkCr+F,EAAO8N,QAC5E/L,MAAMkV,IAAI,IAAKjX,EAAQ8N,SAAQ86F,YACjC,MACE7mG,MAAMkV,IAAIjX,EAEd,CAEAy+F,OAAAA,GACE,IAAK3mG,KAAK+mG,qBAAsB,OAEhC/mG,KAAK6wG,IAAM,GACX,IAGIE,EAAWjlF,EAAWklF,EAAYC,EAHlC7sE,EAAQ,EACR8sE,EAAO,EACPC,EAAO,EAEX,IAAK,IAAIjvF,EAAIliB,KAAK8wG,SAAU5uF,EAAIliB,KAAK4E,KAAKw2B,MAAMn7B,OAAQiiB,IAAK,CAC3D6uF,EAAIjlF,EAAI,EACJ9rB,KAAK4E,KAAKw2B,MAAMlZ,GAAKliB,KAAK4E,KAAKw2B,MAAMlZ,EAAIliB,KAAK8wG,YAChDC,EAAI/wG,KAAK4E,KAAKw2B,MAAMlZ,GAAKliB,KAAK4E,KAAKw2B,MAAMlZ,EAAIliB,KAAK8wG,WAEhD9wG,KAAK4E,KAAKw2B,MAAMlZ,GAAKliB,KAAK4E,KAAKw2B,MAAMlZ,EAAIliB,KAAK8wG,YAChDhlF,EAAI9rB,KAAK4E,KAAKw2B,MAAMlZ,EAAIliB,KAAK8wG,UAAY9wG,KAAK4E,KAAKw2B,MAAMlZ,IAGvDkiB,EAAQpkC,KAAKgW,QACfk7F,GAAQH,EACRI,GAAQrlF,EACRsY,IACA6sE,EAAKC,EAAO9sE,EACZ4sE,EAAKG,EAAO/sE,IAEZ6sE,GAAMA,GAAOjxG,KAAKgW,OAAS,GAAK+6F,GAAK/wG,KAAKgW,OAC1Cg7F,GAAMA,GAAOhxG,KAAKgW,OAAS,GAAK8V,GAAK9rB,KAAKgW,QAG5C,MAAMo7F,EAAKJ,EAAK,EAAIC,EAAKD,EAAK,EAC9BhxG,KAAK6wG,IAAI3uF,GAAK,IAAa,GAAK,EAAIkvF,GAAhB,GACtB,CAEApxG,KAAKymG,UAAYzmG,KAAK6wG,IAAI9wG,QAAU,KACpC,MAAM,IAAE2kB,EAAG,IAAEG,GAAQ7kB,KAAK0oG,kBAAkB1oG,KAAK2V,MACjD3V,KAAK0kB,IAAMA,EACX1kB,KAAK6kB,IAAMA,CACb,CAEA+hF,eAAAA,CAAgBloF,GACd1e,KAAK6nG,yBAAyBnpF,EAAS1e,KAAK6wG,IAAK7wG,KAAK8wG,SAAU,GAAI,GAAI,GAC1E,CAEA/8E,cAAAA,GACE,MAAM/d,EAAS,CACbL,KAAM,SACN7G,MAAO,SACP1L,KAAM,SACNwK,MAAO5N,KAAKgW,QAAU,GACtB2P,UAAU,EACVjB,IAAK,EACLG,IAAK,QAEDisF,EAAW,CACfn7F,KAAM,SACN7G,MAAO,WACP1L,KAAM,WACNwK,MAAO5N,KAAK8wG,UAAY,EACxBnrF,UAAU,EACVjB,IAAK,EACLG,IAAK,QAGP,MAAO,CACLrhB,MAAOxD,KAAK8O,MACZmS,OAAQ,CAACjL,EAAQ86F,GACjBnI,oBAAqB,CACnB3yF,OAAS,GAAEA,EAAOlH,wCAAwCkH,EAAO0O,WAAW1O,EAAO6O,MACnFisF,SAAW,GAAEA,EAAShiG,wCAAwCgiG,EAASpsF,WAAWosF,EAASjsF,OAGjG,CAEAilF,UAAAA,CAAWn8F,GACT,OAAQA,GACN,IAAK,SACL,IAAK,WACH,OAAO3N,KAAK+pG,sBAAsB,CAAEp8F,QACtC,QACE,OAAO,EAEb,CAEApJ,QAAAA,GACE,MAAQ,OAAMvE,KAAKgW,UAAUhW,KAAK8wG,UACpC,EAGF,YCxGA,MAAMO,WAAYlnG,EAChBoT,YAAc3H,EAAAA,GAAc8zF,IAC5BnsF,aAAe,mBAEf+zF,IAAgB,GAGhBnyF,GAAAA,CAAIjX,GACF+B,MAAMkV,IAAIjX,GACVlI,KAAKuoG,eAAergG,EACtB,CAEAy+F,OAAAA,GACE,GAAI3mG,KAAK+mG,qBAAsB,CAC7B/mG,KAAKsxG,IAAM,GACX,IAAK,IAAIpvF,EAAIliB,KAAKgW,OAAQkM,EAAIliB,KAAK4E,KAAKw2B,MAAMn7B,OAAQiiB,IACpDliB,KAAKsxG,IAAIpvF,IAAOliB,KAAK4E,KAAKw2B,MAAMlZ,GAAKliB,KAAK4E,KAAKw2B,MAAMlZ,EAAIliB,KAAKgW,SAAWhW,KAAK4E,KAAKw2B,MAAMlZ,EAAIliB,KAAKgW,QAAW,IAG/GhW,KAAKymG,UAAYzmG,KAAKsxG,IAAIvxG,QAAU,IACtC,CACA,MAAM,IAAE2kB,EAAG,IAAEG,GAAQ7kB,KAAKsxG,IAAIrxG,OAAS,EAAID,KAAKyjD,qBAAqBzjD,KAAKsxG,KAAOtxG,KAAK0oG,kBAAkB1oG,KAAK2V,MAC7G3V,KAAK0kB,IAAMA,EACX1kB,KAAK6kB,IAAMA,CACb,CAEA+hF,eAAAA,CAAgBloF,GACd,IAAI+c,EAAAA,EACF,CACE3d,IAAK9d,KAAKirB,WACVjN,IAAKhe,KAAKirB,WAAajrB,KAAK83C,aAC5B/5B,GAAIsB,KAAK2E,MAAMhkB,KAAKoiB,GAAG,IACvBnE,GAAIoB,KAAK2E,MAAMhkB,KAAKoiB,GAAG,IACvBsZ,YAAa,UACbC,WAAY,GAEd37B,KAAK0B,OACLmmB,OAAOnJ,GACTA,EAAQS,IAAI,cAAenf,KAAKqe,yBAAyBid,kBAAkBuQ,QAAQttB,OAAO5H,MAC1F+H,EAAQO,UAAU,GAAK,IACvBP,EAAQQ,aACRs4B,EAAAA,EAAAA,IAAkB,CAChB7tC,MAAO3J,KAAK4E,KACZmC,UAAW/G,KAAK0B,MAChBupB,WAAYjrB,KAAKirB,WACjBzjB,MAAOxH,KAAKwH,MACZiwC,gBAAiBA,CAACv1B,EAAW1D,KAC3BE,EAAQc,OAAOhB,EAAGa,KAAK2E,MAAMhkB,KAAKoiB,GAAGpiB,KAAKsxG,IAAIpvF,KAAK,IAGvDxD,EAAQe,SACRf,EAAQO,WAAW,IAAM,GAC3B,CAEA8U,cAAAA,GACE,MAAM/d,EAAS,CACbL,KAAM,SACN7G,MAAO,SACP1L,KAAM,SACNwK,MAAO5N,KAAKgW,QAAU,GACtB2P,UAAU,EACVjB,IAAK,EACLG,IAAK,QAGP,MAAO,CACLrhB,MAAOxD,KAAK8O,MACZmS,OAAQ,CAACjL,GACT2yF,oBAAqB,CACnB3yF,OAAS,GAAEA,EAAOlH,wCAAwCkH,EAAO0O,WAAW1O,EAAO6O,OAGzF,CAEAilF,UAAAA,CAAWn8F,GACT,MACO,WADCA,GAEG3N,KAAK+pG,sBAAsB,CAAEp8F,OAI1C,CAEApJ,QAAAA,GACE,MAAQ,OAAMvE,KAAKgW,QACrB,EAGF,YCtFO,MAAMu7F,WAAuBlM,EAAAA,EAClC9nF,YAAc3H,EAAAA,GAAcszF,IAE5B3D,0BAAAA,GACE,MAAO,CAAEiM,IAAK,GAChB,CAEA/L,SAAAA,CAAUC,GACR,MAAM,OAAE1vF,GAAWhW,KAAK0E,SAClB,MAAE02B,GAAUp7B,KAAK2J,MACvB3J,KAAK2lG,kBAAoB3lG,KAAKulG,6BAE9B,IAEIwL,EAAWjlF,EAAWklF,EAAYC,EAFlCC,EAAO,EACPC,EAAO,EAEX,IAAK,IAAIjvF,EAAI,EAAGA,EAAIkZ,EAAMn7B,OAAQiiB,IAAK,CACrC6uF,EAAIjlF,EAAI,EACJsP,EAAMlZ,GAAKkZ,EAAMlZ,EAAI,KACvB6uF,EAAI31E,EAAMlZ,GAAKkZ,EAAMlZ,EAAI,IAEvBkZ,EAAMlZ,GAAKkZ,EAAMlZ,EAAI,KACvB4J,EAAIsP,EAAMlZ,EAAI,GAAKkZ,EAAMlZ,IAGvBA,GAAKlM,GACPk7F,GAAQH,EACRI,GAAQrlF,EACRmlF,EAAKC,EAAOhvF,EACZ8uF,EAAKG,EAAOjvF,IAEZ+uF,GAAMA,GAAOj7F,EAAS,GAAK+6F,GAAK/6F,EAChCg7F,GAAMA,GAAOh7F,EAAS,GAAK8V,GAAK9V,GAGlC,MAAMo7F,EAAKJ,EAAK,EAAIC,EAAKD,EAAK,EAG9B,GAFAhxG,KAAK4lG,iBAAiB4L,IAAItvF,GAAK,IAAa,GAAK,EAAIkvF,GAAhB,KAEiB,IAAlD1L,IAAoB1lG,KAAK4lG,iBAAkB1jF,GAC7C,KAEJ,CACF,EC5CF,MAAMuvF,WAAYtnG,EAChBoT,YAAc3H,EAAAA,GAAcszF,IAC5B3rF,aAAe,0BAEfm0F,eAAwC,KAGxCvyF,GAAAA,CAAIjX,GACF+B,MAAMkV,IAAIjX,GACVlI,KAAKuoG,eAAergG,EACtB,CAEAy+F,OAAAA,GACE,IAAK3mG,KAAK+mG,sBAAgD,OAAxB/mG,KAAK0xG,eAAyB,OAEhE1xG,KAAK0xG,eAAiB,IAAIH,GAAe,CACvC5nG,MAAO3J,KAAK4E,KACZF,QAAS,CAAEsR,OAAQhW,KAAKgW,UAG1BhW,KAAK0xG,eAAejM,YAEpBzlG,KAAKymG,UAAYzmG,KAAK0xG,eAAe9L,iBAAiB4L,IAAIzxG,QAAU,KACpE,MAAM,IAAE2kB,EAAG,IAAEG,GAAQ7kB,KAAK0oG,kBAAkB1oG,KAAK2V,MACjD3V,KAAK0kB,IAAMA,EACX1kB,KAAK6kB,IAAMA,CACb,CAEA+hF,eAAAA,CAAgBloF,GACd1e,KAAK6nG,yBAAyBnpF,EAAS1e,KAAK0xG,gBAAgB9L,iBAAiB4L,KAAO,GAAIxxG,KAAKgW,OAAQ,GAAI,GAAI,GAC/G,CAEA+d,cAAAA,GACE,MAAM/d,EAAS,CACbL,KAAM,SACN7G,MAAO,SACP1L,KAAM,SACNwK,MAAO5N,KAAKgW,QAAU,GACtB2P,UAAU,EACVjB,IAAK,EACLG,IAAK,QAGP,MAAO,CACLrhB,MAAOxD,KAAK8O,MACZmS,OAAQ,CAACjL,GACT2yF,oBAAqB,CACnB3yF,OAAS,GAAEA,EAAOlH,wCAAwCkH,EAAO0O,WAAW1O,EAAO6O,OAGzF,CAEAilF,UAAAA,CAAWn8F,GACT,MACO,WADCA,GAEG3N,KAAK+pG,sBAAsB,CAAEp8F,OAI1C,CAEApJ,QAAAA,GACE,MAAQ,OAAMvE,KAAKgW,QACrB,EAGF,YC9DM27F,GACI,GADJA,GAEM,EAWZ,MAAMC,WAAuBznG,EAC3BoT,YAAc3H,EAAAA,GAAcgzF,KAC5BrrF,aAAe,kBAEfs0F,KAAiB,GAIjB1yF,GAAAA,CAAIjX,GACF,GAA6B,iBAAlBA,EAAO8N,OAAqB,CACrC,MAAOA,EAAS,EAAG87F,EAAW,GAlBpC,SAAqBC,GACnB,MAAM7pG,EAAS6pG,EAAUh4E,MAAM,KAI/B,MAAO,CAHQojB,SAASj1C,EAAO,KAAOypG,GACrB5tF,WAAW7b,EAAO,KAAOypG,GAG5C,CAYyCK,CAAY9pG,EAAO8N,QACtD/L,MAAMkV,IAAI,IAAKjX,EAAQ8N,SAAQ87F,YACjC,MACE7nG,MAAMkV,IAAIjX,EAEd,CAEAy+F,OAAAA,GACE,GAAI3mG,KAAK+mG,qBAAsB,CAC7B/mG,KAAK6xG,KAAO,GAEZ,IAAIhvD,EAAM,EACV,IAAK,IAAI3gC,EAAI,EAAGA,EAAIliB,KAAKgW,OAAQkM,IAC/B2gC,GAAO7iD,KAAK4E,KAAKu3B,OAAOja,GAE1B,IAAK,IAAIA,EAAIliB,KAAKgW,OAAQkM,EAAIliB,KAAK4E,KAAKu3B,OAAOl8B,OAAQiiB,IACrD2gC,EAAMA,EAAM7iD,KAAK4E,KAAKu3B,OAAOja,EAAIliB,KAAKgW,QAAUhW,KAAK4E,KAAKu3B,OAAOja,GACjEliB,KAAK6xG,KAAK3vF,GAAKliB,KAAK4E,KAAKu3B,OAAOja,IAAM2gC,EAAM7iD,KAAKgW,QAGnDhW,KAAKymG,UAAYzmG,KAAK6xG,KAAK9xG,QAAU,IACvC,CAEA,MAAM,IAAE2kB,EAAG,IAAEG,GACX7kB,KAAK6xG,KAAK5xG,OAAS,EACfD,KAAKyjD,qBAAqB,IAAIzjD,KAAK6xG,KAAM7xG,KAAK8xG,WAC9C9xG,KAAK0oG,kBAAkB1oG,KAAK2V,MAClC3V,KAAK0kB,IAAMA,EACX1kB,KAAK6kB,IAAMA,CACb,CAEA+hF,eAAAA,CAAgBloF,GACd,MAAM,cAAEwc,GAAkBl7B,KAAKqe,0BACzB,OAAEE,GAAW2c,EAAc2Q,QAC3BzhC,EAAapK,KAAK0B,MAAMgI,SACxB,WAAEirC,GAAevqC,GACjB,aAAEu2C,EAAY,eAAEC,IAAmBC,EAAAA,EAAAA,IAA6B,CACpElM,aACA3jC,YAAa5G,EAAWwpB,iBAEpB0jB,EAAwBqJ,EAAgC,EAAjBC,EACvCxJ,IAAiB/3B,KAAKwF,IAAI,EAAGyyB,EAAwB,IAE3DE,EAAAA,EAAAA,IAAkB,CAChB7tC,MAAO3J,KAAK4E,KACZmC,UAAW/G,KAAK0B,MAChBupB,WAAYjrB,KAAKirB,WACjBzjB,MAAOxH,KAAKwH,MACZygG,gBAAiBjoG,KAAKgW,OAAS,EAC/ByhC,gBAAiBA,CAACv1B,EAAG1D,KACnB,QAAqBnW,IAAjBrI,KAAK6xG,KAAK3vF,GAAkB,OAEhC,MAAM4vF,EAAWzyF,KAAK2E,MAAMhkB,KAAKoiB,GAAGpiB,KAAK8xG,WACnCrzF,EAAIY,KAAK2E,MAAMhkB,KAAKoiB,GAAGpiB,KAAK6xG,KAAK3vF,KAEvCxD,EAAQuH,UAAYjmB,KAAK6xG,KAAK3vF,GAAKliB,KAAK8xG,SAAWvzF,EAAOm5B,gBAAkBn5B,EAAOo5B,cACnFj5B,EAAQoe,SAASte,EAAI44B,EAAc06D,EAAUx6D,EAAuB74B,EAAIqzF,EAAS,IAIrF,MAAMG,EAAYjyG,KAAKoiB,GAAGpiB,KAAK8xG,UAC/B,IAAIr2E,EAAAA,EACF,CACE3d,IAAK9d,KAAKirB,WACVjN,IAAKhe,KAAKirB,WAAajrB,KAAK83C,aAC5B/5B,GAAIsB,KAAK2E,MAAMiuF,GACfh0F,GAAIoB,KAAK2E,MAAMiuF,GACfv2E,aAAa2F,EAAAA,GAAAA,IAAwB9iB,EAAO2jC,WAAY,KAE1DliD,KAAK0B,OACLmmB,OAAOnJ,EACX,CAEAqV,cAAAA,GACE,MAAM/d,EAAS,CACbL,KAAM,SACN7G,MAAO,SACP1L,KAAM,SACNwK,MAAO5N,KAAKgW,QAAU27F,GACtBhsF,UAAU,EACVjB,IAAK,EACLG,IAAK,QAGDitF,EAAW,CACfn8F,KAAM,SACN7G,MAAO,WACP1L,KAAM,WACNwK,MAAO5N,KAAK8xG,UAAYH,GACxBhsF,UAAU,EACVoV,KAAM,GACNS,cAAc,EACd9W,IAAK,EACLG,IAAK,QAGP,MAAO,CACLrhB,MAAOxD,KAAK8O,MACZmS,OAAQ,CAACjL,EAAQ87F,GACjBnJ,oBAAqB,CACnB3yF,OAAS,GAAEA,EAAOlH,wCAAwCkH,EAAO0O,WAAW1O,EAAO6O,MACnFitF,SAAW,GAAEA,EAAShjG,kCAAkCgjG,EAASptF,WAAWotF,EAASjtF,OAG3F,CAEAilF,UAAAA,CAAWn8F,GACT,OAAQA,GACN,IAAK,SACH,OAAO3N,KAAK+pG,sBAAsB,CAAEp8F,QACtC,IAAK,WACH,OAAO3N,KAAK+pG,sBAAsB,CAAEp8F,MAAKq8F,aAAa,IACxD,QACE,OAAO,EAEb,CAEAzlG,QAAAA,GACE,MAAQ,QAAOvE,KAAKgW,WAAWhW,KAAK8xG,eACtC,EAGF,YCjJA,MAAMI,WAAY/nG,EAChBoT,YAAc3H,EAAAA,GAAc0zF,IAC5B/rF,aAAe,oBAEfojF,GAAe,GACf6J,IAAgB,GAChB2H,MAAkB,GAClBC,MAAkB,GAGlBjvG,WAAAA,CAAYJ,EAAcrB,GACxBuI,MAAMlH,EAAOrB,GACb1B,KAAKmqC,YAAcnqC,KAAKmqC,YAAYxpC,KAAKX,KAC3C,CAEAmf,GAAAA,CAAIjX,GACF+B,MAAMkV,IAAIjX,GACVlI,KAAKuoG,eAAergG,EACtB,CAEAy+F,OAAAA,GACE,GAAI3mG,KAAK+mG,qBAAsB,CAC7B/mG,KAAK2gG,GAAK,GACV3gG,KAAKwqG,IAAM,GACXxqG,KAAKmyG,MAAQ,GACbnyG,KAAKoyG,MAAQ,GACb,IAAI5H,EAAM,EAEV,IAAK,IAAItoF,EAAI,EAAGA,EAAIliB,KAAK4E,KAAKw2B,MAAMn7B,OAAQiiB,IAAK,CAC/C,MAAMy+E,EAAK52D,EAAAA,GAAMllB,IAAI,CACnB7kB,KAAK4E,KAAKuX,KAAK+F,GAAKliB,KAAK4E,KAAKmkC,IAAI7mB,GAClC7C,KAAKQ,IAAI7f,KAAK4E,KAAKuX,KAAK+F,GAAKliB,KAAK4E,KAAKw2B,MAAMlZ,EAAI,IACjD7C,KAAKQ,IAAI7f,KAAK4E,KAAKmkC,IAAI7mB,GAAKliB,KAAK4E,KAAKw2B,MAAMlZ,EAAI,MAElDliB,KAAK2gG,GAAGz+E,GAAKy+E,EAETz+E,EAAIliB,KAAKgW,QACXw0F,GAAO7J,EACP3gG,KAAKwqG,IAAItoF,GAAKsoF,GAAOtoF,EAAI,GACrBA,IAAMliB,KAAKgW,OAAS,IACtBw0F,GAAOxqG,KAAKgW,SAGdhW,KAAKwqG,IAAItoF,IAAMliB,KAAKwqG,IAAItoF,EAAI,IAAMliB,KAAKgW,OAAS,GAAK2qF,GAAM3gG,KAAKgW,MAEpE,CAEA,IAAK,IAAIkM,EAAIliB,KAAKgW,OAAS,EAAGkM,EAAIliB,KAAK4E,KAAKw2B,MAAMn7B,OAAQiiB,IAAK,CAC7D,MAAMtC,EAAI5f,KAAK4E,KAAKuX,KAAK+F,GACnBnT,EAAI/O,KAAK4E,KAAKmkC,IAAI7mB,GACxB,IAAImwF,EAAQryG,KAAK2gG,GAAGz+E,EAAI,GAAKliB,KAAK2gG,GAAGz+E,EAAI,GACrCkiB,EAAQ,EACRkuE,EAAaD,EAAQjuE,EAAS/kB,KAAKsP,KAAKyV,GACxCmuE,EAAQD,EAAY,GAAK1yF,EAAI5f,KAAK4E,KAAKmkC,IAAI7mB,EAAI,IAAMowF,GAAa,EAClEE,EAAQF,EAAY,GAAKtyG,KAAK4E,KAAKuX,KAAK+F,EAAI,GAAKnT,GAAKujG,GAAa,EACvE,IAAK,IAAI1P,EAAI1gF,EAAI,EAAG0gF,EAAI1gF,EAAIliB,KAAKgW,OAAS,EAAG4sF,IAAK,CAIhD,GAHAyP,GAASryG,KAAK2gG,GAAGiC,EAAI,GACrBx+D,IACAkuE,EAAaD,EAAQjuE,EAAS/kB,KAAKsP,KAAKyV,GACtB,IAAdkuE,EACF,SAGF,MAAM7xC,GAAM7gD,EAAI5f,KAAK4E,KAAKmkC,IAAI65D,EAAI,IAAM0P,EACpC7xC,EAAK8xC,IACPA,EAAQ9xC,GAGV,MAAME,GAAM3gE,KAAK4E,KAAKuX,KAAKymF,EAAI,GAAK7zF,GAAKujG,EACrC3xC,EAAK6xC,IACPA,EAAQ7xC,EAEZ,CACA3gE,KAAKmyG,MAAMjwF,GAAKqwF,EAChBvyG,KAAKoyG,MAAMlwF,GAAKswF,CAClB,CACF,CACA,MAAM,IAAE9tF,EAAG,IAAEG,GACX7kB,KAAKmyG,MAAMlyG,OAAS,GAAKD,KAAKoyG,MAAMnyG,OAAS,EACzCD,KAAKyjD,qBAAqBzjD,KAAKmyG,MAAOnyG,KAAKoyG,OAC3CpyG,KAAK0oG,kBAAkB1oG,KAAK2V,MAClC3V,KAAK0kB,IAAMA,EACX1kB,KAAK6kB,IAAMA,CACb,CAEA+hF,eAAAA,CAAgBloF,GACd,GAA+B,IAA3B1e,KAAK4E,KAAKw2B,MAAMn7B,OAAc,OAElC,MAAM+nG,EAAyB,CAC7Br+F,MAAO3J,KAAK4E,KACZmC,UAAW/G,KAAK0B,MAChBupB,WAAYjrB,KAAKirB,WACjBzjB,MAAOxH,KAAKwH,MACZygG,gBAAiBjoG,KAAKgW,QAGxB0I,EAAQO,UAAU,GAAK,IACvBP,EAAQS,IAAI,cAAe,WAC3BT,EAAQQ,aACRs4B,EAAAA,EAAAA,IAAkB,IACbwwD,EACHvwD,gBAAiBA,CAACv1B,EAAW1D,KAC3BE,EAAQc,OAAOhB,EAAGa,KAAK2E,MAAMhkB,KAAKoiB,GAAGpiB,KAAKoyG,MAAMlwF,KAAK,IAGzDxD,EAAQe,SAERf,EAAQS,IAAI,cAAe,WAC3BT,EAAQQ,aACRs4B,EAAAA,EAAAA,IAAkB,IACbwwD,EACHvwD,gBAAiBA,CAACv1B,EAAW1D,KAC3BE,EAAQc,OAAOhB,EAAGa,KAAK2E,MAAMhkB,KAAKoiB,GAAGpiB,KAAKmyG,MAAMjwF,KAAK,IAGzDxD,EAAQe,SACRf,EAAQO,WAAW,IAAM,GAC3B,CAEAkrB,WAAAA,CAAYzrB,GACVzU,MAAMkgC,YAAYzrB,GAClB,MAAM,kBAAE4c,EAAiB,cAAEJ,GAAkBl7B,KAAKqe,0BAC5C,OAAEE,GAAW2c,EAAc2Q,QAC3B5sB,GAAYiwB,EAAAA,EAAAA,IAAa,CAC7BxwB,UACA+Q,QAAS6L,EAAkB7U,KAAKjf,MAChCkoB,QAAS4L,EAAkBhV,IAAI7e,SAEjCwX,EAAUkwB,KACV,MAAMtpB,EAAO,IAAIL,EAAAA,EACf,CACEhH,EAAGxe,KAAK83C,aAAe9L,EAAAA,GAAOa,EAAIllB,EAAAA,GAAQ+b,IAAMpI,EAAkB/U,MAAMqqB,KAAK9E,OAAOrlB,KACpFX,KAAMN,EAAAA,EAAK0e,2BAA2B,OAAQ5I,EAAkB/U,MAAMqqB,KAAK9qB,MAC3EI,WAAYoV,EAAkB/U,MAAMqqB,KAAK9qB,KAAKI,WAC9CG,QAAS,CACPC,IAAKgV,EAAkB/U,MAAMqqB,KAAK9qB,MAAMO,SAASC,KAAOqB,EAAAA,GAAQ+b,IAChEnd,MAAO+U,EAAkB/U,MAAMqqB,KAAK9qB,MAAMO,SAASE,OAASoB,EAAAA,GAAQ+b,IACpEld,OAAQ8U,EAAkB/U,MAAMqqB,KAAK9qB,MAAMO,SAASG,QAAUmB,EAAAA,GAAQ+b,IACtEjd,KAAM6U,EAAkB/U,MAAMqqB,KAAK9qB,MAAMO,SAASI,MAAQkB,EAAAA,GAAQ+b,KAEpEtd,aAAcsQ,EAAAA,GAAaC,OAC3B1Q,UAAW1H,EAAO4oF,sBAEpBnnG,KAAK0B,OAEDkqG,EAAa,GACf5rG,KAAKoyG,MAAMnyG,OAAS,GACtB2rG,EAAWrqG,KAAK,CACdskB,KAAM7lB,KAAKoyG,MAAMryG,OAAQ6D,QAAQ,GACjC6a,EAAGY,KAAK2E,MAAMhkB,KAAKoiB,GAAGpiB,KAAKoyG,MAAMryG,SACjC2mB,WAAY,YAGZ1mB,KAAKmyG,MAAMlyG,OAAS,GACtB2rG,EAAWrqG,KAAK,CACdskB,KAAM7lB,KAAKmyG,MAAMpyG,OAAQ6D,QAAQ,GACjC6a,EAAGY,KAAK2E,MAAMhkB,KAAKoiB,GAAGpiB,KAAKmyG,MAAMpyG,SACjC2mB,WAAY,YAIhB,MACM5B,EAAO9kB,KAAKyH,OAAS6zB,EAAkB9U,OAAO/e,OAAS6zB,EAAkBhV,IAAI7e,OACnFmkG,EAAWrjG,SAASsjG,IACdA,EAAaptF,GAHN,GAGmBotF,EAAaptF,GAAKqG,GAC9Ce,EAAK1G,IAAI0sF,GAAchkF,OAAOnJ,EAChC,IAGFO,EAAUgyB,MACZ,CAEAld,cAAAA,GACE,MAAM/d,EAAS,CACbL,KAAM,SACN7G,MAAO,SACP1L,KAAM,SACNwK,MAAO5N,KAAKgW,QAAU,EACtB2P,UAAU,EACVjB,IAAK,EACLG,IAAK,QAGP,MAAO,CACLrhB,MAAOxD,KAAK8O,MACZmS,OAAQ,CAACjL,GACT2yF,oBAAqB,CACnB3yF,OAAS,GAAEA,EAAOlH,wCAAwCkH,EAAO0O,WAAW1O,EAAO6O,OAGzF,CAEAilF,UAAAA,CAAWn8F,GACT,MACO,WADCA,GAEG3N,KAAK+pG,sBAAsB,CAAEp8F,OAI1C,CAEApJ,QAAAA,GACE,MAAQ,OAAMvE,KAAKgW,QACrB,EAGF,YC9MA,MAAMy8F,WAA6CtoG,EACjDoT,YAAc3H,EAAAA,GAAcuzF,MAC5B5rF,aAAe,mBAEfolF,EAAc,GACd+P,GAAe,GACf5mF,EAAc,GAKd3M,GAAAA,CAAIjX,GACF,GAA6B,iBAAlBA,EAAO8N,OAAqB,CACrC,MAAOA,EAAS,EAAG28F,EAAU,EAAGC,EAAU,IAAKrM,EAAAA,EAAAA,IAAkCr+F,EAAO8N,QACxF/L,MAAMkV,IAAI,IAAKjX,EAAQ8N,SAAQ48F,UAASD,WAC1C,MACE1oG,MAAMkV,IAAIjX,EAEd,CAEAy+F,OAAAA,GACE,IAAK3mG,KAAK+mG,qBAAsB,OAEhC,MAAM/wF,EAASqJ,KAAKqF,IAAI1kB,KAAKgW,OAAQhW,KAAK4E,KAAKw2B,MAAMn7B,OAAS,GAC9D,IAAI4yG,EAAQC,EAAMnQ,EAClB3iG,KAAK0yG,GAAK,GACV1yG,KAAK2iG,EAAI,GACT3iG,KAAK8rB,EAAI,GACT,IAAIinF,EAAQD,EAAO,EACfE,EAAUH,EAAS,EACvB,IAAK,IAAI3wF,EAAI,EAAGA,EAAIliB,KAAK4E,KAAKw2B,MAAMn7B,OAAQiiB,IAAK,CAC/C,IAAI+wF,EAAcjzG,KAAK4E,KAAKuX,KAAK+F,GAC7BgxF,EAAYlzG,KAAK4E,KAAKmkC,IAAI7mB,GAE9B,IAAK,IAAI0gF,EAAI1gF,EAAIlM,EAAS,EAAG4sF,GAAK1gF,EAAG0gF,IAC/B5iG,KAAK4E,KAAKuX,KAAKymF,GAAKqQ,IACtBA,EAAcjzG,KAAK4E,KAAKuX,KAAKymF,IAE3B5iG,KAAK4E,KAAKmkC,IAAI65D,GAAKsQ,IACrBA,EAAYlzG,KAAK4E,KAAKmkC,IAAI65D,IAI9BD,GAAM3iG,KAAK4E,KAAKw2B,MAAMlZ,GAAKgxF,IAAcD,EAAcC,GAAc,IACjED,IAAgBC,IAClBvQ,EAAI,KAEN3iG,KAAK0yG,GAAGxwF,GAAKygF,EACT3iG,KAAK2yG,QAAU,IACjBI,GAAQpQ,EACRqQ,IACIA,EAAShzG,KAAK2yG,UAChBI,GAAQ/yG,KAAK0yG,GAAGxwF,EAAIliB,KAAK2yG,SACzBK,KAEFrQ,EAAIoQ,EAAOC,GAGbF,GAAQnQ,EACRkQ,IACIA,EAAS7yG,KAAK4yG,UAChBE,GAAQ9yG,KAAK2iG,EAAEzgF,EAAIliB,KAAK4yG,SACxBC,KAGF,MAAM/mF,EAAIgnF,EAAOD,EACjB7yG,KAAK2iG,EAAEzgF,GAAKygF,EACZ3iG,KAAK8rB,EAAE5J,GAAK4J,CACd,CAEA9rB,KAAKymG,UAAYzmG,KAAK2iG,EAAE5iG,QAAU,KAClC,MAAM,IAAE2kB,EAAG,IAAEG,GAAQ7kB,KAAK0oG,kBAAkB1oG,KAAK2V,MACjD3V,KAAK0kB,IAAMA,EACX1kB,KAAK6kB,IAAMA,CACb,CAEA+hF,eAAAA,CAAgBloF,GACd,GAA+B,IAA3B1e,KAAK4E,KAAKw2B,MAAMn7B,OAAc,OAElC,IAAIw7B,EAAAA,EACF,CACE3d,IAAK9d,KAAKirB,WACVjN,IAAKhe,KAAKirB,WAAajrB,KAAK83C,aAC5B/5B,GAAIsB,KAAK2E,MAAMhkB,KAAKoiB,GAAG,KACvBnE,GAAIoB,KAAK2E,MAAMhkB,KAAKoiB,GAAG,KACvBsZ,YAAa,UACbC,WAAY,GAEd37B,KAAK0B,OACLmmB,OAAOnJ,GACT,IAAI+c,EAAAA,EACF,CACE3d,IAAK9d,KAAKirB,WACVjN,IAAKhe,KAAKirB,WAAajrB,KAAK83C,aAC5B/5B,GAAIsB,KAAK2E,MAAMhkB,KAAKoiB,GAAG,KACvBnE,GAAIoB,KAAK2E,MAAMhkB,KAAKoiB,GAAG,KACvBsZ,YAAa,WAEf17B,KAAK0B,OACLmmB,OAAOnJ,GACT,IAAI+c,EAAAA,EACF,CACE3d,IAAK9d,KAAKirB,WACVjN,IAAKhe,KAAKirB,WAAajrB,KAAK83C,aAC5B/5B,GAAIsB,KAAK2E,MAAMhkB,KAAKoiB,GAAG,KACvBnE,GAAIoB,KAAK2E,MAAMhkB,KAAKoiB,GAAG,KACvBsZ,YAAa,WAEf17B,KAAK0B,OACLmmB,OAAOnJ,GAETA,EAAQS,IAAI,cAAenf,KAAKqe,yBAAyBid,kBAAkBuQ,QAAQttB,OAAO5H,MAC1F+H,EAAQO,UAAU,GAAK,IACvBP,EAAQQ,YACR,MAAM8oF,EAAyB,CAC7Br+F,MAAO3J,KAAK4E,KACZmC,UAAW/G,KAAK0B,MAChBupB,WAAYjrB,KAAKirB,WACjBzjB,MAAOxH,KAAKwH,MACZygG,gBAAiBjoG,KAAKgW,SAExBwhC,EAAAA,EAAAA,IAAkB,IACbwwD,EACHvwD,gBAAiBA,CAACv1B,EAAG1D,KACnBE,EAAQc,OAAOhB,EAAGa,KAAK2E,MAAMhkB,KAAKoiB,GAAGpiB,KAAK2iG,EAAEzgF,KAAK,IAGrDxD,EAAQe,SAERf,EAAQS,IAAI,cAAe,WAC3BT,EAAQQ,aACRs4B,EAAAA,EAAAA,IAAkB,IACbwwD,EACHvwD,gBAAiBA,CAACv1B,EAAG1D,KACnBE,EAAQc,OAAOhB,EAAGa,KAAK2E,MAAMhkB,KAAKoiB,GAAGpiB,KAAK8rB,EAAE5J,KAAK,IAGrDxD,EAAQe,SACRf,EAAQO,WAAW,IAAM,GAC3B,CAEA8U,cAAAA,GACE,MAAM/d,EAAS,CACbL,KAAM,SACN7G,MAAO,SACP1L,KAAM,SACNwK,MAAO5N,KAAKgW,QAAU,GACtB2P,UAAU,EACVjB,IAAK,EACLG,IAAK,QAED8tF,EAAU,CACdh9F,KAAM,SACN7G,MAAO,WACP1L,KAAM,UACNwK,MAAO5N,KAAK2yG,SAAW,EACvBhtF,UAAU,EACVjB,IAAK,EACLG,IAAK,QAED+tF,EAAU,CACdj9F,KAAM,SACN7G,MAAO,WACP1L,KAAM,UACNwK,MAAO5N,KAAK4yG,SAAW,EACvBjtF,UAAU,EACVjB,IAAK,EACLG,IAAK,QAGP,MAAO,CACLrhB,MAAOxD,KAAK8O,MACZmS,OAAQ,CAACjL,EAAQ28F,EAASC,GAC1BjK,oBAAqB,CACnB3yF,OAAS,GAAEA,EAAOlH,wCAAwCkH,EAAO0O,WAAW1O,EAAO6O,MACnF+tF,QAAU,GAAEA,EAAQ9jG,wCAAwC8jG,EAAQluF,WAAWkuF,EAAQ/tF,MACvF8tF,QAAU,GAAEA,EAAQ7jG,wCAAwC6jG,EAAQjuF,WAAWiuF,EAAQ9tF,OAO7F,CAEAilF,UAAAA,CAAWn8F,GACT,OAAQA,GACN,IAAK,SACL,IAAK,UACL,IAAK,UACH,OAAO3N,KAAK+pG,sBAAsB,CAAEp8F,QACtC,QACE,OAAO,EAEb,CAEApJ,QAAAA,GACE,MAAQ,oBAAmBvE,KAAKgW,UAAUhW,KAAK2yG,WAAW3yG,KAAK4yG,SACjE,EAGF,YC1MA,MAAMO,WAAwBV,GAC5Bl1F,YAAc3H,EAAAA,GAAcw9F,MAC5B71F,aAAe,mBAMfpa,WAAAA,CAAYJ,EAAcrB,GACxBuI,MAAMlH,EAAOrB,GACb1B,KAAK2yG,QAAU,CACjB,CAEAxzF,GAAAA,CAAIjX,GACF,GAA6B,iBAAlBA,EAAO8N,OAAqB,CACrC,MAAOA,EAAS,EAAG48F,EAAU,IAAKrM,EAAAA,EAAAA,IAAkCr+F,EAAO8N,QAC3E/L,MAAMkV,IAAI,IAAKjX,EAAQ8N,SAAQ48F,UAASD,QAAS,GACnD,MACE1oG,MAAMkV,IAAIjX,EAEd,CAEA6rB,cAAAA,GACE,MAAM/d,EAAS,CACbL,KAAM,SACN7G,MAAO,SACP1L,KAAM,SACNwK,MAAO5N,KAAKgW,QAAU,GACtB2P,UAAU,EACVjB,IAAK,EACLG,IAAK,QAED+tF,EAAU,CACdj9F,KAAM,SACN7G,MAAO,WACP1L,KAAM,UACNwK,MAAO5N,KAAK4yG,SAAW,EACvBjtF,UAAU,EACVjB,IAAK,EACLG,IAAK,QAGP,MAAO,CACLrhB,MAAOxD,KAAK8O,MACZmS,OAAQ,CAACjL,EAAQ48F,GACjBjK,oBAAqB,CACnB3yF,OAAS,GAAEA,EAAOlH,wCAAwCkH,EAAO0O,WAAW1O,EAAO6O,MACnF+tF,QAAU,GAAEA,EAAQ9jG,wCAAwC8jG,EAAQluF,WAAWkuF,EAAQ/tF,OAG7F,CAEAilF,UAAAA,CAAWn8F,GACT,OAAQA,GACN,IAAK,SACL,IAAK,UACH,OAAO3N,KAAK+pG,sBAAsB,CAAEp8F,QACtC,QACE,OAAO,EAEb,CAEApJ,QAAAA,GACE,MAAQ,oBAAmBvE,KAAKgW,UAAUhW,KAAK4yG,SACjD,EAGF,YCpEA,MAAMS,WAAwBZ,GAC5Bl1F,YAAc3H,EAAAA,GAAc09F,MAC5B/1F,aAAe,mBAEfo1F,QAAU,EAEVxzF,GAAAA,CAAIjX,GACF,GAA6B,iBAAlBA,EAAO8N,OAAqB,CACrC,MAAOA,EAAS,EAAG48F,EAAU,IAAKrM,EAAAA,EAAAA,IAAkCr+F,EAAO8N,QAC3E/L,MAAMkV,IAAI,IAAKjX,EAAQ8N,SAAQ48F,UAASD,QAAS,GACnD,MACE1oG,MAAMkV,IAAIjX,EAEd,CAEA6rB,cAAAA,GACE,MAAM/d,EAAS,CACbL,KAAM,SACN7G,MAAO,SACP1L,KAAM,SACNwK,MAAO5N,KAAKgW,QAAU,GACtB2P,UAAU,EACVjB,IAAK,EACLG,IAAK,QAED+tF,EAAU,CACdj9F,KAAM,SACN7G,MAAO,WACP1L,KAAM,UACNwK,MAAO5N,KAAK4yG,SAAW,EACvBjtF,UAAU,EACVjB,IAAK,EACLG,IAAK,QAGP,MAAO,CACLrhB,MAAOxD,KAAK8O,MACZmS,OAAQ,CAACjL,EAAQ48F,GACjBjK,oBAAqB,CACnB3yF,OAAS,GAAEA,EAAOlH,wCAAwCkH,EAAO0O,WAAW1O,EAAO6O,MACnF+tF,QAAU,GAAEA,EAAQ9jG,wCAAwC8jG,EAAQluF,WAAWkuF,EAAQ/tF,OAG7F,CAEAilF,UAAAA,CAAWn8F,GACT,OAAQA,GACN,IAAK,SACL,IAAK,UACH,OAAO3N,KAAK+pG,sBAAsB,CAAEp8F,QACtC,QACE,OAAO,EAEb,CAEApJ,QAAAA,GACE,MAAQ,oBAAmBvE,KAAKgW,UAAUhW,KAAK4yG,SACjD,EAGF,YC1DO,MAAMW,WAAwBlO,EAAAA,EACnC9nF,YAAc3H,EAAAA,GAAc2zF,KAE5BhE,0BAAAA,GACE,MAAO,CAAEiO,KAAM,GACjB,CAEA/N,SAAAA,CAAUC,GACR,MAAM,OAAE1vF,GAAWhW,KAAK0E,SAClB,MAAE02B,GAAUp7B,KAAK2J,MACjBo5C,EAAY3nB,EAAMn7B,OAAS,EAC3BwzG,EAAO,IAAIvO,EAAAA,EAAyBlvF,GACpC09F,EAAO,IAAIxO,EAAAA,EAAyBlvF,GACpC29F,EAAO,IAAIzO,EAAAA,EAAyBlvF,GAC1ChW,KAAK2lG,kBAAoB3lG,KAAKulG,6BAE9B,IAAIj7C,EAAO,EACX,IAAK,IAAIroD,EAAQ,EAAGA,GAAS8gD,IAC3B0wD,EAAKxnG,IAAImvB,EAAMn5B,IACfyxG,EAAKznG,IAAIwnG,EAAK7lG,OACd+lG,EAAK1nG,IAAIynG,EAAK9lG,OACV08C,EAAO,IACTtqD,KAAK4lG,iBAAiB4N,KAAKvxG,GAAuB,IAAb0xG,EAAK/lG,MAAe08C,EAAO,KAElEA,EAAOqpD,EAAK/lG,OAE8C,IAAtD83F,IAAoB1lG,KAAK4lG,iBAAkB3jG,IATTA,KAa1C,EChCF,MAAMsnG,WAAap/F,EACjBoT,YAAc3H,EAAAA,GAAc2zF,KAC5BhsF,aAAe,OAEfq2F,gBAA0C,KAG1Cz0F,GAAAA,CAAIjX,GACF+B,MAAMkV,IAAIjX,GACVlI,KAAKuoG,eAAergG,EACtB,CAEAy+F,OAAAA,GACM3mG,KAAK+mG,uBACP/mG,KAAK4zG,gBAAkB,IAAIL,GAAgB,CACzC5pG,MAAO3J,KAAK4E,KACZF,QAAS,CACPsR,OAAQhW,KAAKgW,UAGjBhW,KAAK4zG,gBAAgBnO,YACrBzlG,KAAKymG,UAAYzmG,KAAK4zG,gBAAgBhO,iBAAiB4N,KAAKzzG,QAAU,MAExE,MAAMyzG,EAAOxzG,KAAK4zG,iBAAiBhO,iBAAiB4N,MAAQ,IACtD,IAAE9uF,EAAG,IAAEG,GAAQ2uF,EAAKvzG,OAAS,EAAID,KAAKyjD,qBAAqB+vD,GAAQxzG,KAAK0oG,kBAAkB1oG,KAAK2V,MACrG3V,KAAK0kB,IAAMA,EACX1kB,KAAK6kB,IAAMA,CACb,CAEA+hF,eAAAA,CAAgBloF,GACd,IAAI+c,EAAAA,EACF,CACE3d,IAAK9d,KAAKirB,WACVjN,IAAKhe,KAAKirB,WAAajrB,KAAK83C,aAC5B/5B,GAAIsB,KAAK2E,MAAMhkB,KAAKoiB,GAAG,IACvBnE,GAAIoB,KAAK2E,MAAMhkB,KAAKoiB,GAAG,IACvBsZ,YAAa,UACbC,WAAY,GAEd37B,KAAK0B,OACLmmB,OAAOnJ,GACTA,EAAQS,IAAI,cAAenf,KAAKqe,yBAAyBid,kBAAkBuQ,QAAQttB,OAAO5H,MAC1F+H,EAAQO,UAAU,GAAK,IACvBP,EAAQQ,aACRs4B,EAAAA,EAAAA,IAAkB,CAChB7tC,MAAO3J,KAAK4E,KACZmC,UAAW/G,KAAK0B,MAChBupB,WAAYjrB,KAAKirB,WACjBzjB,MAAOxH,KAAKwH,MACZiwC,gBAAiBA,CAACv1B,EAAW1D,KAC3B,MAAM5Q,EAAQ5N,KAAK4zG,iBAAiBhO,iBAAiB4N,KAAKtxF,GACtDtU,GAAO8Q,EAAQc,OAAOhB,IAAKxe,KAAKoiB,GAAGxU,GAAO,IAGlD8Q,EAAQe,SACRf,EAAQO,WAAW,IAAM,GAC3B,CAEA8U,cAAAA,GACE,MAAM/d,EAAS,CACbL,KAAM,SACN7G,MAAO,SACP1L,KAAM,SACNwK,MAAO5N,KAAKgW,QAAU,EACtB2P,UAAU,EACVjB,IAAK,EACLG,IAAK,QAGP,MAAO,CACLrhB,MAAOxD,KAAK8O,MACZmS,OAAQ,CAACjL,GACT2yF,oBAAqB,CACnB3yF,OAAS,GAAEA,EAAOlH,wCAAwCkH,EAAO0O,WAAW1O,EAAO6O,OAGzF,CAEAilF,UAAAA,CAAWn8F,GACT,MACO,WADCA,GAEG3N,KAAK+pG,sBAAsB,CAAEp8F,OAI1C,CAEApJ,QAAAA,GACE,MAAQ,QAAOvE,KAAKgW,QACtB,EAGF,YC1FA,MAAM69F,WAA2B1pG,EAC/BoT,YAAc3H,EAAAA,GAAcwzF,IAC5B7rF,aAAe,sBAEf,yBAAOkU,CAAkB9pB,GAAkE,IAAjE,OAAEqO,GAA6DrO,EACvF,MAAOmsG,EAAU,EAAGC,EAAU,EAAGC,EAAU,IAAKzN,EAAAA,EAAAA,IAAkCvwF,GAClF,OAAOqJ,KAAKwF,IAAIivF,EAASC,EAASC,EACpC,CAKAC,IAAgB,GAChBtT,GAAe,GACfuT,GAAe,GAEf/0F,GAAAA,CAAIjX,GACF,GAA6B,iBAAlBA,EAAO8N,OAAqB,CACrC,MAAO89F,EAAU,EAAGC,EAAU,EAAGC,EAAU,IAAKzN,EAAAA,EAAAA,IAAkCr+F,EAAO8N,QACzF/L,MAAMkV,IAAI,IAAKjX,EAAQ4rG,UAASC,UAASC,WAC3C,MACE/pG,MAAMkV,IAAIjX,EAEd,CAEAy+F,OAAAA,GACE,IAAK3mG,KAAK+mG,qBAAsB,OAGhC,IAAIoN,EAAQC,EAAQC,EAAQC,EAAQC,EAAQC,EAD5Cx0G,KAAKi0G,IAAM,GAEX,MAAMtT,EAAK,GACLuT,EAAK,GACX,IAGIO,EAAMC,EAHNC,EAAUR,EAASC,EAAS,EAC5BQ,EAAUL,EAASC,EAAS,EAC5BK,EAAUR,EAASC,EAAS,EAEhC,IAAK,IAAIpyF,EAAI,EAAGA,EAAIliB,KAAK4E,KAAKw2B,MAAMn7B,OAAQiiB,IAAK,CAC/CgyF,EAAGhyF,GAAKliB,KAAK4E,KAAKw2B,MAAMlZ,GAAK7C,KAAKqF,IAAI1kB,KAAK4E,KAAKmkC,IAAI7mB,GAAIliB,KAAK4E,KAAKw2B,MAAMlZ,EAAI,IAC5Ey+E,EAAGz+E,GAAK7C,KAAKwF,IAAI7kB,KAAK4E,KAAKuX,KAAK+F,GAAIliB,KAAK4E,KAAKw2B,MAAMlZ,EAAI,IAAM7C,KAAKqF,IAAI1kB,KAAK4E,KAAKmkC,IAAI7mB,GAAIliB,KAAK4E,KAAKw2B,MAAMlZ,EAAI,IAE7GyyF,GAAUT,EAAGhyF,GACb0yF,GAAUjU,EAAGz+E,GACb2yF,IACIA,EAAS70G,KAAK8zG,UAChBa,GAAUT,EAAGhyF,EAAIliB,KAAK8zG,SACtBc,GAAUjU,EAAGz+E,EAAIliB,KAAK8zG,UAGxBK,GAAUD,EAAGhyF,GACbqyF,GAAU5T,EAAGz+E,GACbmyF,IACIA,EAASr0G,KAAK+zG,UAChBI,GAAUD,EAAGhyF,EAAIliB,KAAK+zG,SACtBQ,GAAU5T,EAAGz+E,EAAIliB,KAAK+zG,UAGxBK,GAAUF,EAAGhyF,GACbsyF,GAAU7T,EAAGz+E,GACboyF,IACIA,EAASt0G,KAAKg0G,UAChBI,GAAUF,EAAGhyF,EAAIliB,KAAKg0G,SACtBQ,GAAU7T,EAAGz+E,EAAIliB,KAAKg0G,UAGxB,IAAIc,EAAQL,EAAOC,EAAO,EACtBE,EAAS,IACXE,EAAOH,EAASC,GAEdL,EAAS,IACXE,EAAON,EAASI,GAEdC,EAAS,IACXE,EAAON,EAASI,GAGlBx0G,KAAKi0G,IAAI/xF,GAAM,KAAO,EAAI4yF,EAAO,EAAIL,EAAOC,GAAS,CACvD,CAEA10G,KAAKymG,UAAYzmG,KAAKi0G,IAAIl0G,QAAU,KACpC,MAAM,IAAE2kB,EAAG,IAAEG,GAAQ7kB,KAAK0oG,kBAAkB1oG,KAAK2V,MACjD3V,KAAK0kB,IAAMA,EACX1kB,KAAK6kB,IAAMA,CACb,CAEA+hF,eAAAA,CAAgBloF,GACd1e,KAAK6nG,yBAAyBnpF,EAAS1e,KAAKi0G,IAAK,EAAG,GAAI,GAAI,GAC9D,CAEAlgF,cAAAA,GACE,MAAM+/E,EAAU,CACdn+F,KAAM,SACN7G,MAAO,WACP1L,KAAM,UACNwK,MAAO5N,KAAK8zG,SAAW,EACvBnuF,UAAU,EACVjB,IAAK,EACLG,IAAK,QAEDkvF,EAAU,CACdp+F,KAAM,SACN7G,MAAO,WACP1L,KAAM,UACNwK,MAAO5N,KAAK+zG,SAAW,GACvBpuF,UAAU,EACVjB,IAAK,EACLG,IAAK,QAEDmvF,EAAU,CACdr+F,KAAM,SACN7G,MAAO,WACP1L,KAAM,UACNwK,MAAO5N,KAAKg0G,SAAW,GACvBruF,UAAU,EACVjB,IAAK,EACLG,IAAK,QAGP,MAAO,CACLrhB,MAAOxD,KAAK8O,MACZmS,OAAQ,CAAC6yF,EAASC,EAASC,GAC3BrL,oBAAqB,CACnBmL,QAAU,GAAEA,EAAQhlG,wCAAwCglG,EAAQpvF,WAAWovF,EAAQjvF,MACvFkvF,QAAU,GAAEA,EAAQjlG,wCAAwCilG,EAAQrvF,WAAWqvF,EAAQlvF,MACvFmvF,QAAU,GAAEA,EAAQllG,wCAAwCklG,EAAQtvF,WAAWsvF,EAAQnvF,OAG7F,CAEAilF,UAAAA,CAAWn8F,GACT,OAAQA,GACN,IAAK,UACL,IAAK,UACL,IAAK,UACH,OAAO3N,KAAK+pG,sBAAsB,CAAEp8F,QACtC,QACE,OAAO,EAEb,CAEApJ,QAAAA,GACE,MAAQ,OAAMvE,KAAK8zG,WAAW9zG,KAAK+zG,WAAW/zG,KAAKg0G,SACrD,EAGF,YCtJA,MAAMe,WAAe5qG,EACnBoT,YAAc3H,EAAAA,GAAcygC,IAC5B94B,aAAe,SAEfopF,OAAAA,GACE,MAAM,IAAEjiF,EAAG,IAAEG,GACX7kB,KAAK4E,KAAKu3B,OAAOl8B,OAAS,EAAID,KAAKyjD,qBAAqBzjD,KAAK4E,KAAKu3B,QAAUn8B,KAAK0oG,kBAAkB1oG,KAAK2V,MAC1G3V,KAAK0kB,IAAMA,EACX1kB,KAAK6kB,IAAMA,EACX7kB,KAAKymG,UAAYzmG,KAAK4E,KAAKu3B,OAAOp8B,QAAU,IAC9C,CAEA6mG,eAAAA,CAAgBloF,GACd,MAAM,cAAEwc,GAAkBl7B,KAAKqe,0BACzB,OAAEE,GAAW2c,EAAc2Q,QAC3BzhC,EAAapK,KAAK0B,MAAMgI,SACxB,WAAEirC,GAAevqC,GACjB,aAAEu2C,EAAY,eAAEC,IAAmBC,EAAAA,EAAAA,IAA6B,CACpElM,aACA3jC,YAAa5G,EAAWwpB,iBAEpB0jB,EAAwBqJ,EAAgC,EAAjBC,EACvCxJ,IAAiB/3B,KAAKwF,IAAI,EAAGyyB,EAAwB,IAE3DE,EAAAA,EAAAA,IAAkB,CAChB7tC,MAAO3J,KAAK4E,KACZmC,UAAW/G,KAAK0B,MAChBupB,WAAYjrB,KAAKirB,WACjBzjB,MAAOxH,KAAKwH,MACZiwC,gBAAiBA,CAACv1B,EAAG1D,KACnBE,EAAQuH,UAAYjmB,KAAK4E,KAAKw2B,MAAMlZ,GAAKliB,KAAK4E,KAAK0oC,KAAKprB,GAAK3D,EAAOm5B,gBAAkBn5B,EAAOo5B,cAC7F,MAAMl5B,EAAIY,KAAK2E,MAAMhkB,KAAKoiB,GAAGpiB,KAAK4E,KAAKu3B,OAAOja,KAC9CxD,EAAQoe,SAASte,EAAI44B,EAAc34B,EAAG64B,EAAuB54B,EAAQsnB,OAAOv+B,OAASgX,EAAE,GAG7F,CAEAwoF,UAAAA,CAAWr5F,GACT,OAAOkT,EAAAA,GAAKiiF,gBAAgBn1F,EAAO,EACrC,CAEAmmB,cAAAA,GACE,MAAO,CACLvwB,MAAOxD,KAAK8O,MACZmS,OAAQ,GACR0nF,oBAAqB,CAAC,EAE1B,CAEApkG,QAAAA,GACE,MAAQ,QACV,EAGF,YCrDA,MAAMywG,WAAkB7qG,EACtBoT,YAAc3H,EAAAA,GAAc4zF,GAC5BjsF,aAAe,cAGfH,EAAc,GAEd+B,GAAAA,CAAIjX,GACF+B,MAAMkV,IAAIjX,GACVlI,KAAKuoG,eAAergG,EACtB,CAEAy+F,OAAAA,GACE,GAAI3mG,KAAK+mG,qBAAsB,CAC7B/mG,KAAKod,EAAI,GACT,IAAK,IAAI8E,EAAIliB,KAAKgW,OAAQkM,EAAIliB,KAAK4E,KAAKw2B,MAAMn7B,OAAQiiB,IAAK,CACzD,IAAI+wF,EAAcjzG,KAAK4E,KAAKuX,KAAK+F,GAC7BgxF,EAAYlzG,KAAK4E,KAAKmkC,IAAI7mB,GAC9B,IAAK,IAAI0gF,EAAI1gF,EAAIliB,KAAKgW,OAAS,EAAG4sF,GAAK1gF,EAAG0gF,IACpC5iG,KAAK4E,KAAKuX,KAAKymF,GAAKqQ,IACtBA,EAAcjzG,KAAK4E,KAAKuX,KAAKymF,IAE3B5iG,KAAK4E,KAAKmkC,IAAI65D,GAAKsQ,IACrBA,EAAYlzG,KAAK4E,KAAKmkC,IAAI65D,IAI9B5iG,KAAKod,EAAE8E,GAAK,EACR+wF,EAAcC,EAAY,IAC5BlzG,KAAKod,EAAE8E,IAAO+wF,EAAcjzG,KAAK4E,KAAKw2B,MAAMlZ,KAAO+wF,EAAcC,IAAe,IAEpF,CAEAlzG,KAAKymG,UAAYzmG,KAAKod,EAAErd,QAAU,IACpC,CACA,MAAM,IAAE2kB,EAAG,IAAEG,GAAQ7kB,KAAKod,EAAEnd,OAAS,EAAID,KAAKyjD,qBAAqBzjD,KAAKod,GAAKpd,KAAK0oG,kBAAkB1oG,KAAK2V,MACzG3V,KAAK0kB,IAAMA,EACX1kB,KAAK6kB,IAAMA,CACb,CAEA+hF,eAAAA,CAAgBloF,GACd1e,KAAK6nG,yBAAyBnpF,EAAS1e,KAAKod,EAAGpd,KAAKgW,QAAS,IAAK,IAAK,GACzE,CAEA+d,cAAAA,GACE,MAAM/d,EAAS,CACbL,KAAM,SACN7G,MAAO,SACP1L,KAAM,SACNwK,MAAO5N,KAAKgW,QAAU,GACtB2P,UAAU,EACVjB,IAAK,EACLG,IAAK,QAGP,MAAO,CACLrhB,MAAOxD,KAAK8O,MACZmS,OAAQ,CAACjL,GACT2yF,oBAAqB,CACnB3yF,OAAS,GAAEA,EAAOlH,wCAAwCkH,EAAO0O,WAAW1O,EAAO6O,OAGzF,CAEAilF,UAAAA,CAAWn8F,GACT,MACO,WADCA,GAEG3N,KAAK+pG,sBAAsB,CAAEp8F,OAI1C,CAEApJ,QAAAA,GACE,MAAQ,OAAMvE,KAAKgW,QACrB,EAGF,YCzDa6rF,GAAmB5+F,OAAOitB,OAAO,CAC5C,CAACta,EAAAA,GAAczL,WAAYmL,EAC3B,CAACM,EAAAA,GAAciD,MAAOo8F,EACtB,CAACr/F,EAAAA,GAAckzF,KAAMuB,EACrB,CAACz0F,EAAAA,GAAcmzF,KAAMmM,EACrB,CAACt/F,EAAAA,GAAc6zF,QAAS0L,EACxB,CAACv/F,EAAAA,GAAcizF,KAAM2B,EACrB,CAAC50F,EAAAA,GAAc+zF,KAAMuC,EACrB,CAACt2F,EAAAA,GAAcC,KAAMg3F,EACrB,CAACj3F,EAAAA,GAAcg0F,IAAK2D,EACpB,CAAC33F,EAAAA,GAAcyzF,MAAOsE,EACtB,CAAC/3F,EAAAA,GAAcozF,KAAMwF,EACrB,CAAC54F,EAAAA,GAAco5F,KAAMC,GACrB,CAACr5F,EAAAA,GAAc8xF,MAAOniD,GACtB,CAAC3vC,EAAAA,GAAcqzF,KAAM4H,GACrB,CAACj7F,EAAAA,GAAc8zF,KAAM4H,GACrB,CAAC17F,EAAAA,GAAcszF,KAAMsI,GACrB,CAAC57F,EAAAA,GAAcgzF,MAAOiJ,GACtB,CAACj8F,EAAAA,GAAc0zF,KAAM8L,GACrB,CAACx/F,EAAAA,GAAcw9F,OAAQiC,GACvB,CAACz/F,EAAAA,GAAcuzF,OAAQmM,GACvB,CAAC1/F,EAAAA,GAAc09F,OAAQiC,GACvB,CAAC3/F,EAAAA,GAAc2zF,MAAOiK,GACtB,CAAC59F,EAAAA,GAAcwzF,KAAM6K,GACrB,CAACr+F,EAAAA,GAAcygC,KAAMm/D,GACrB,CAAC5/F,EAAAA,GAAc4zF,IAAKiM,KAGiBxyG,OAAOitB,OAAO,CAACta,EAAAA,GAAco5F,IAAKp5F,EAAAA,GAAcygC,K,gDCxDhF,MAAM+xC,EAA0B,CACrCpgF,SAAUA,IAAM,+BAChBZ,SAAU,iB,oHCYZ,MAGMsuG,EAAsBA,CAC1BC,EACAj0G,KAEA,GAA2B,mBAAhBi0G,EAA4B,CACrC,MAAM/nG,EAAQ+nG,EAAY9pG,KAAKnK,GAE/B,GAAIkM,IAVkBA,IACxB,CAAClN,IAAAA,MAAaA,IAAAA,OAAcA,IAAAA,YAAkByH,MAAMytG,GAAgBhoG,aAAiBgoG,IASrEC,CAAiBjoG,GAC7B,MAAMxE,MAAM,gEAGd,MAA0B,mBAAfwE,GAAO5L,IACT4L,EAAM5L,MAGR4L,CACT,CAEA,GAA2B,iBAAhB+nG,EAA0B,CACnC,MAAMG,IAAgBH,GAAe,aAAcA,EACnD,OAAO3uF,KAAKC,UAAU6uF,EAAcH,EAAY3rG,WAAa2rG,GAAaI,EAAAA,EAAAA,MAC5E,CAEA,OAAOJ,CAAW,EAGdK,EAAkBA,CAA4Bt0G,EAAqBsB,IACvEA,GAAO+J,QACL,CAACC,EAAKm3B,KAAY,IACbn3B,EACH,CAACm3B,GAAUuxE,EAAoBh0G,IAAQyiC,GAAUziC,MAEnD,CAAC,GAGCu0G,EAA0BA,CAC9BC,EACAC,IAEID,aAAwBx1G,IAAAA,MACnBw1G,EAAa/zG,IAAIg0G,GAGnBD,IAAiBC,EAGpBC,EAAuBnzG,OAAOiF,OAAOmuG,EAAAA,IAEpC,SAAS/nG,EACd5M,GAEA,IADAgD,EAAoCtD,UAAAnB,OAAA,QAAAoI,IAAAjH,UAAA,GAAAA,UAAA,GAAG,CAAC,EAExC,MAAM,gBAAEmN,EAAkB,GAAE,eAAEg5D,EAAiB6uC,GAAyB1xG,EAClE4xG,EAAqBtvF,KAAKC,UAAUviB,IACpC,YAAEumE,IAAgBsrC,EAAAA,EAAAA,KAClBC,EAAuBnrG,EAAAA,OAAa2qG,EAAgBt0G,EAAO6M,IAqCjE,OAnCAlD,EAAAA,WAAgB,KACd,MAAMorG,EAAoBA,KACNloG,EAAgBpG,MAAMg8B,IACtC,MAAM+xE,EAAeR,EAAoBh0G,IAAQyiC,GAAUziC,GACrDy0G,EAAgBK,EAAqB33G,UAAUslC,GAErD,OAAItkC,MAAM62G,QAAQR,IAEbr2G,MAAM62G,QAAQP,IACfD,EAAaj2G,SAAWk2G,EAAcl2G,QACtCi2G,EAAa/tG,MAAK,CAACnH,EAAQiB,KAAWg0G,EAAwBj1G,EAAQm1G,EAAcl0G,OAIhFg0G,EAAwBC,EAAcC,EAAc,MAI5DK,EAAqB33G,QAAUm3G,EAAgBt0G,EAAO6M,GACtD08D,IACF,EAGI0rC,EAAcpvC,EAAe1jE,KAAK,KAMxC,OAJAnC,GAAOf,KAAKg2G,EAAaF,GAEzBxrC,IAEO,KACLvpE,GAAOC,OAAOg1G,EAAaF,EAAkB,CAC9C,GAEA,CAAC/0G,GAAOyE,IAAKmwG,EAAoBrrC,IAE7BvpE,CACT,C,yKC9EA,MAAM4I,UAAc5J,IAAAA,MAClB,gBAAOoG,CAAUC,EAAwBygE,EAA0Bn5D,GACjErO,KAAKgH,UACH,QACA,QACA,SACA,YACA,YACA,QACA,aACA,SACA,aACA,KACA,KACA,aACA,cACA,UACA,uBACA,aACA,gBACA,YACA,cACA,kBAEFhH,KAAK42G,QAAQ,QAAS7vG,GACtB/G,KAAKiH,UAAU,QAASugE,GACxBxnE,KAAKiH,UAAU,eAAgBoH,EACjC,CA2BA+kD,YAAAA,GACE,OAAOpzD,KAAKqV,QACTrT,MACA6H,MAAM6oB,GACLA,EACGhd,WACA1T,MACAmG,MAAMjG,GAAOA,EAAG8oD,aAEzB,CAEA6rD,eAAAA,GACE,IAAK,MAAMnkF,KAAQ1yB,KAAKqV,QAAQrT,MAC9B,IAAK,MAAME,KAAMwwB,EAAKhd,WAAW1T,MAC/B,GAAIE,EAAG8oD,UACL,OAAO9oD,CAIf,CAEA40G,YAAAA,GACE,OAAO92G,KAAK62G,mBAAmBptG,SAASkM,IAC1C,CAEAi4D,kBAAAA,GACE,IAAImpC,EAAwC,KACZ,iBAArB/2G,KAAKguE,YACd+oC,EAAyB/2G,KAAKguE,aACA,IAArBhuE,KAAKguE,cACd+oC,EAAyBrtD,EAAAA,GAAyBstD,SAGpD,MAAMt5D,EAAU19C,KAAK6S,aAAeC,EAAAA,GAAWC,MACzCb,EAAYrM,OAAO8S,eAAeC,eACxC,IAAIq+F,EAAwBvtD,EAAAA,GAAyBwtD,MAOrD,OANKhlG,EAEMwrC,IAAY1yC,EAAAA,GAAMmsG,gCAC3BF,EAAwBvtD,EAAAA,GAAyB0tD,oBAFjDH,EAAwBvtD,EAAAA,GAAyB2tD,KAK5CN,GAA0B13F,KAAKwF,IAAIkyF,EAAwBE,EACpE,CAEAjtG,QAAAA,GACE,MAAMqL,EAAQrV,KAAKqV,QAChBrT,MACA0L,KAAKglB,GAASA,EAAK1oB,aACtB,MAAO,CACLxC,MAAOxH,KAAKwH,MACZ0M,UAAWlU,KAAKkU,UAChBzM,OAAQzH,KAAKyH,OACbgN,UAAWzU,KAAKyU,UAChB0C,MAAOnX,KAAKmX,MACZ8T,WAAYjrB,KAAKirB,WACjB2gB,OAAQ5rC,KAAK4rC,OACb/4B,WAAY7S,KAAK6S,WACjB8hC,WAAY30C,KAAK20C,WACjBq5B,YAAahuE,KAAKguE,YAClBmR,QAASn/E,KAAKm/E,QACduX,QAAS12F,KAAKmG,IACdkP,QACAu1E,qBAAsB5qF,KAAK4qF,qBAC3Bh4B,WAAY5yD,KAAK4yD,WACjBmB,UAAW/zD,KAAK+zD,UAChBC,YAAah0D,KAAKg0D,YAClBF,eAAgB9zD,KAAK8zD,eAEzB,CAEA5pD,QAAAA,GAAoC,IAA3BotG,EAAQl2G,UAAAnB,OAAA,QAAAoI,IAAAjH,UAAA,GAAAA,UAAA,GAAG,GAClB,MAAMiU,EAAQrV,KAAKqV,QAChBrT,MACA0L,KAAKglB,GAASA,EAAKxoB,SAASotG,KAC/B,OAAOnjF,IACL,CACE3sB,MAAOxH,KAAKwH,MACZC,OAAQzH,KAAKyH,OACbgN,UAAWzU,KAAKyU,UAChB0C,MAAOnX,KAAKmX,MACZ8T,WAAYjrB,KAAKirB,WACjB2gB,OAAQ5rC,KAAK4rC,OACb/4B,WAAY7S,KAAK6S,WACjB8hC,WAAY30C,KAAK20C,WACjBq5B,YAAahuE,KAAKguE,YAClBmR,QAASn/E,KAAKm/E,QACduX,QAAS12F,KAAKmG,IACdkP,QACAu1E,qBAAsB5qF,KAAK4qF,qBAC3Bh4B,WAAY5yD,KAAK4yD,WACjBmB,UAAW/zD,KAAK+zD,UAChBC,YAAah0D,KAAKg0D,YAClBF,eAAgB9zD,KAAK8zD,gBAEvBwjD,EAEJ,CAEA5jD,cAAAA,CAAehvD,GAMb,OALA1E,KAAKqV,QACFrT,MACAuG,SAASmqB,IACRA,EAAKghC,gBAAgB,IAElB1zD,KAAK60D,QAAQnwD,EACtB,CAEA2Z,sBAAAA,GACE,OAAOA,EAAAA,EAAAA,IAAuBre,KAAK4zB,eACrC,CAEAmkD,aAAAA,GACE,OAAsC,IAA/B/3E,KAAK2J,SAASyxB,MAAMn7B,MAC7B,CAEAs3G,eAAAA,GACE,OAAOv3G,KAAK4zB,eAAew+C,UAC7B,CAEA5lB,WAAAA,GACE,OAAOxsD,KAAKqV,QAAQrT,KACtB,CAEAm6E,gBAAAA,GACE,MAAM5mE,EAAUtS,OAAOC,KAAKlD,KAAK2J,QAAQ6L,MAAQ,CAAC,GAClD,OAAOxV,KAAKwsD,cAAc50C,QAAQ8a,IAChC,MAAMo4B,EAAcp4B,EAAKo4B,cACzB,OAAIA,GAAarhD,SAASkM,OAASC,EAAAA,GAAcC,KAExCN,EAAQ6kB,SAAU0wB,EAAYrhD,SAA4B1G,MAAM0S,KAE9D,GAEf,CAEAu4C,cAAAA,GACE,OAAOhuD,KAAKwsD,cAAc/Q,SAAS/oB,GAASA,EAAKs7B,kBACnD,CAEA6E,YAAAA,GACE,MAAM2kD,EAAax3G,KAAKguD,iBACrBp2C,QAAOjQ,IAAA,IAAC,SAAE8B,GAAU9B,EAAA,OAAK8B,EAASkM,OAASC,EAAAA,GAAc8xF,IAAI,IAC7DjsD,SAAQrzC,IAAA,IAAC,SAAEqB,GAAUrB,EAAA,OAAKnF,OAAOiF,OAAQuB,EAAyCy6C,OAAO,IAE5F,IAAIuzD,EAA4B,GAChC,GAAIz3G,KAAK4zB,eAAeviB,6BAA+Bq7B,EAAAA,GAA2BgrE,UAAW,CAC3F,MAAMvwD,EAAYnnD,KAAK62G,mBAAmBptG,SACtC09C,IACFswD,EAAmBjtG,EAAAA,EAAMo6C,QACtBD,GAAawC,EAAUpkD,MAAMqhD,QAAQhqB,SAASuqB,EAAE/Y,SAAW,CAAC5D,EAAAA,GAAUlc,EAAGkc,EAAAA,GAAUX,GAAGjN,SAASuqB,EAAElwC,aAGxG,CAEA,MAAO,IAAI+iG,KAAeC,EAAkBz3G,KAAK2J,SAASiO,QACxD,CAACjO,EAAO1H,EAAOiiD,IAAWv6C,GAASu6C,EAAOriD,WAAW8iD,GAAMA,GAAGzjD,KAAOyI,EAAMzI,OAAQe,GAEvF,CAEAg+E,iBAAAA,CAAkBD,GAChB,MAAMj5E,EAAY/G,KAAKqV,QAAQquD,OAAasc,GAE5CA,EAAetqE,UAAUnN,SAAQuF,IAAuC,IAAtC,OAAE49C,EAAM,UAAE3hD,KAAcjI,GAASgM,EACjE,MAAMrE,GAAWg6D,EAAAA,EAAAA,GAAuB3hE,EAAQ6T,MAAM4b,WAAWzvB,EAASiF,GAC1EA,EAAU2O,WAAWguD,OAAO,CAAEj6D,WAAUiiD,SAAQ3hD,cAChDhD,EAAU2C,QAAQH,QAAQghC,EAAAA,GAAkBC,iBAAiB,IAG/D,MAAMmtE,EAAmB5wG,EAAU2rD,6BAKnC,OAJI3rD,EAAU+jD,eAAe/gD,YAAc4tG,GAAkB5tG,WAC3DhD,EAAUoJ,iBAAiB,CAAE26C,YAAa6sD,IAGrC5wG,CACT,CAEAkjF,uBAAAA,CAA2Dr8E,GACzD,MAAMgqG,EAAc30G,OAAOuK,QAAQqqG,EAAAA,IAChCjgG,QAAOlI,IAAA,IAAE/B,GAAI+B,EAAA,OAAK1P,KAAK4P,qBAAqBjC,EAAoC,IAChF8tC,SAAQphB,IAAA,IAAE3I,EAAGomF,GAAUz9E,EAAA,OAAKy9E,CAAS,IACxC93G,KAAKmQ,iBAAiBvC,GAElBgqG,EAAY33G,OAAS,GACvBD,KAAK4zB,eACFnhB,eACAlK,SAAS6B,IACR,GAAIpK,KAAKmC,IAAIiI,GACX,OAEF,MAAMk+F,EAAuB,CAAC,EAC9BsP,EAAYrvG,SAASuvG,IACflqG,EAAMmqG,eAAeD,KACvBxP,EAASwP,GAAalqG,EAAMkqG,GAC9B,IAEF1tG,EAAW+F,iBAAiBm4F,EAAS,GAG7C,CAEAx4F,iBAAAA,CAAkBkoG,EAAqDC,GACrEj4G,KAAK4zB,eAAe9jB,kBAAkBkoG,EAAYC,EACpD,CAEAroG,oBAAAA,CAAqBsoG,GACnB,OAAOl4G,KAAK4zB,eAAehkB,qBAAqBsoG,EAClD,CAEAhkD,cAAAA,GACE,OAAOl0D,KAAKguD,iBAAiB7lD,MAAMrG,GAC7B,eAAgBA,EAAQ2H,UAClB3H,EAAQ2H,SAAuBy1C,aAAa,aAK1D,CAEAmM,iBAAAA,GACE,OAAOrrD,KAAK2J,SAAS8oD,gBAAkB,IACzC,CAEAkB,cAAAA,CAAe/pD,GAA2E,IAArBuuG,EAAW/2G,UAAAnB,OAAA,QAAAoI,IAAAjH,UAAA,IAAAA,UAAA,GAC9E,MAAM+xD,EAAYnzD,KAAKozD,eACvB,IAAKD,EACH,OAEF,MAAMilD,EAAiBjlD,EAAUvpD,cAAc5H,MAC3Cm2G,GACFC,EAAe7vG,SAASkkE,GAAeA,EAAW/Y,mBAGpD,MAAMa,EAAS4jD,EACXvuG,EACAA,GAAagO,QAAQ60D,IAAgB2rC,EAAejwG,MAAKmyB,IAAA,IAAC,UAAEvwB,GAAWuwB,EAAA,OAAKmyC,EAAW1iE,YAAcA,CAAS,MAElHwqD,GAAQhsD,SAAQgyB,IAA6C,IAA5C,UAAExwB,EAAS,UAAE86D,EAAS,cAAE28B,GAAejnE,EAChC44B,EAAUvpD,cAAc85D,OAA0B,CACtEj6D,UAAUg6D,EAAAA,EAAAA,GAAuBoB,GAAWtzC,WAAW,CAAEkC,mBAAoB,CAAEjV,EAAGgjF,IAAmBruC,GACrGppD,cAEYN,SAASka,cAAc,IAGvCwvC,EAAUS,2BACZ,EAGF,S,mEC3UO,IAAKyC,EAAiB,SAAjBA,GAAiB,OAAjBA,EAAiB,sBAAjBA,EAAiB,gBAAjBA,EAAiB,sBAAjBA,CAAiB,MAMtB,MAAMwhD,EAA0B,CACrC,CAACxhD,EAAkB77C,QAAS,CAAC,UAC7B,CAAC67C,EAAkBC,WAAY,CAAC,YAAa,cAGlC7mD,EAAqB,CAChC,CAAE7B,MAAOyoD,EAAkB77C,OAAQ1L,MAAO,UAC1C,CAAElB,MAAOyoD,EAAkBC,UAAWxnD,MAAO,aAC7C,CAAElB,MAAOyoD,EAAkBgiD,UAAWvpG,MAAO,a,sICF/C,MAAMrE,UAAoB/J,IAAAA,MACxB,gBAAOoG,CAAUsD,EAA0BkuG,GACzCt4G,KAAKgH,UACH,cACA,SACA,cACA,aACA,mBACA,QACA,SACA,WACA,kBACA,aACA,oBACA,QACA,UACA,QACA,WACA,qBACA,6BACA,eACA,uBACA,2BACA,uBACA,gCACA,OACA,qBACA,oBACA,iBACA,SACA,cACA,QAEFhH,KAAK42G,QAAQ,SAAUxsG,GACvBpK,KAAKiH,UAAU,wBAAyBqxG,EAC1C,CAiCAn1G,WAAAA,GACE8G,SAAM7I,YAEDogD,EAAAA,EAAAA,OACHxhD,KAAKW,KAAK,UAAWe,IACdmE,OAAO8S,eAAegzE,aACzB9lF,OAAO8S,eAAegzE,WAAa,CAAC,GAEtC9lF,OAAO8S,eAAegzE,WAAWnK,EAAAA,GAAeC,kBAAoB//E,EAAM+xD,wBAAwB,GAGxG,CAEAu3B,oBAAAA,GACE,IAAK,MAAMt4D,KAAQ1yB,KAAKwsD,cACtB,GAAI95B,EAAKC,UACP,OAAOD,CAGb,CAEA1oB,QAAAA,GACE,MAAMkN,EAASlX,KAAKyS,eAAe/E,KAAKhE,GAAUA,EAAMM,aACxD,MAAO,CACLkF,OAAQlP,KAAKkP,OACb1H,MAAOxH,KAAKwH,MACZC,OAAQzH,KAAKyH,OACbyP,SACA0zE,qBAAsB5qF,KAAK4qF,qBAC3Bn3B,yBAA0BzzD,KAAKyzD,yBAEnC,CAEAvpD,QAAAA,GAAyG,IAA9BotG,EAAQl2G,UAAAnB,OAAA,QAAAoI,IAAAjH,UAAA,GAAAA,UAAA,GAAG,GACpF,MAAM8V,EAASlX,KAAKyS,eAAe/E,KAAKhE,GAAUA,EAAMQ,SAASotG,KACjE,OAAOtwF,KAAKsmC,MACVtmC,KAAKC,UACHkN,IACE,IACKn0B,KAAKoQ,SAAS8qB,cAAcrE,OAC/B3nB,OAAQlP,KAAKkP,OACb1H,MAAOxH,KAAKwH,MACZC,OAAQzH,KAAKyH,OACbyP,SACA0zE,qBAAsB5qF,KAAK4qF,qBAC3Bn3B,yBAA0BzzD,KAAKyzD,yBAC/B3vD,OAAQ9D,KAAKoQ,SAAS8qB,cAAc2Q,QAAQttB,OAC5ClN,2BAA4BrR,KAAKqR,2BACjC84D,QAASnqE,KAAKmqE,QACdG,SAAUtqE,KAAKsqE,SACf8H,WAAYpyE,KAAKoyE,WACjB1rE,MAAO1G,KAAK0G,MACZ2mF,UAAW,aAAahB,KAAKxmF,OAAOgF,SAASqO,WAE/Co+F,IAIR,CAEAziD,OAAAA,CAAQnwD,GAEN,OADA1E,KAAK0vC,gBAAgB,eAAe,GAC7BzlC,MAAM4qD,QAAQnwD,EACvB,CAEAgvD,cAAAA,CAAehvD,GAKb,OAJA1E,KAAK0vC,gBAAgB,eAAe,GACpC1vC,KAAKyS,eAAelK,SAASmB,IAC3BA,EAAMgqD,gBAAgB,IAEjB1zD,KAAK60D,QAAQnwD,EACtB,CAEA+N,YAAAA,GACE,OAAOzS,KAAKkX,SAASlV,KACvB,CAEAwqD,WAAAA,GACE,OAAOxsD,KAAKyS,eAAegpC,SAAS/xC,GAAUA,EAAM8iD,eACtD,CAEAwB,cAAAA,GACE,OAAOhuD,KAAKyS,eAAegpC,SAAS/xC,GAAUA,EAAMskD,kBACtD,CAEAl+C,iBAAAA,CAAkBkoG,EAAqDC,GACrE,MAAMM,EAAmB14G,MAAM62G,QAAQsB,GAAcA,EAAa,CAACA,GAE7DQ,EAAsBx4G,KAAKu2D,gBAAgB3+C,QAAQsgG,IAAeK,EAAiBn+E,SAAS89E,MAAe,GAE7GD,GACFO,EAAoBj3G,QAAQg3G,GAG9Bv4G,KAAKmQ,iBAAiB,CAAEomD,eAAgBiiD,GAC1C,CAEA5oG,oBAAAA,CAAqBsoG,GACnB,QAASl4G,KAAKu2D,gBAAgBn8B,SAAS89E,EACzC,CAEA9hE,qBAAAA,CAAsBzgC,GACpB,QAAS3V,KAAKkX,SACXurC,SACCuL,iBACD7lD,MAAMrG,GAAYA,EAAQy5B,eAAkBz5B,EAAQ2H,SAAkCkM,OAASA,GACpG,CAEA2iC,gBAAAA,GACE,MAAQ,gBAAet4C,KAAKkB,IAC9B,CAEAgpF,QAAAA,GACElqF,KAAK0vC,gBAAgB,YAAQrnC,GAC7BrI,KAAKyS,eAAelK,SAASmB,IAE3BA,EAAMmpD,eAAetqD,SAASoB,IACxBA,EAAMm7C,SACRn7C,EAAMwG,iBAAiB,CAAE20C,YAAQz8C,IACjCsB,EAAMopD,UAAU,CAAEC,UAAWC,EAAAA,EAAe2oB,UAC9C,IAGFlyE,EAAMyG,iBAAiB,CAAE69D,aAAa,GAAO,GAEjD,CAEAnpB,QAAAA,GAAmC,IAA1B3jD,EAAiBE,UAAAnB,OAAA,QAAAoI,IAAAjH,UAAA,GAAAA,UAAA,GAAG,KAC3B,OAAQpB,KAAKwR,MAAMtQ,IAAM,QAAUA,CACrC,EAGF,S,0ECrNA,SAASu3G,IAAkC,IAAhBC,EAASt3G,UAAAnB,OAAA,QAAAoI,IAAAjH,UAAA,GAAAA,UAAA,GAAG,GAErC,OAAwB,IADPs3G,EAAUr/F,QAAQ,IAAK,IAC3BpZ,OACH,GAAEy4G,MAELA,CACT,CAEO,MAAMp5D,EAAqB33C,IAM5B,IAN6B,MACjCjB,EAAK,OACL5C,GAID6D,EACC,MAAMgxG,EAAe70G,EAAO4C,GACtBkyG,EAAkB31G,OAAOC,KAAKy1G,GAC9BE,EAAgBnyG,IAAUgC,EAAAA,GAAMg3C,MAAQo5D,EAAAA,GAAkBC,EAAAA,GAEhE,OAAOH,EAAgB7rG,QAAO,CAACC,EAAKyyC,IAEhCg5D,EAAkBE,EAAal5D,IAAW+1C,gBAC1CijB,EAAkBI,EAAcp5D,IAAW+1C,cAGzC,IACKxoF,EACH,CAACyyC,GAAWk5D,EAAal5D,IAE3BzyC,GACH,CAAC,EAAE,C,8KC0BD,MAAM8rG,EAAqC,CAChDt7D,gBAAiB,YACjB92B,WAAY,YACZ25B,WAAY,YACZC,SAAU,YACVxF,WAAY,YACZw5B,MAAO,YACPo8B,UAAW,OACXsI,oBAAqB,OACrBznE,kBAAmBlI,IAAAA,aAA4B,KAC/C4I,YAAa5I,IAAAA,KAAoB,KACjCsN,KAAM,YACNb,cAAe,UACfsxD,2BAA4B/9D,IAAAA,KAAoB,KAChD89D,qBAAsB,OACtBxwF,KAAM,YACN2sC,WAAYja,IAAAA,IAAmB,KAC/Bka,SAAUla,IAAAA,MAAqB,KAC/B4vE,eAAgB,YAChBh3D,cAAe,YACfD,YAAa,YACbk3D,8BAA8B73E,EAAAA,EAAAA,IAAwB,UAAW,KACjE2P,uBAAwB,OACxBm/D,0BAA2B,UAC3BgJ,eAAgB,YAChB57D,cAAe,YACfnE,UAAW,YACXvzB,KAAM,UACN0mB,cAAe,UACf4T,UAAW,YACXC,QAAS,YACT1I,gBAAiB,UACjBC,cAAe,UACf4I,SAAU,YACVC,OAAQ,YACR0B,WAAY,QAGD62D,EAAoC,CAC/Cv7D,gBAAiB,YACjB92B,WAAY,YACZ25B,WAAY,YACZC,SAAU,YACVxF,WAAYzR,IAAAA,KAAoB,KAChCirC,MAAO,UACPo8B,UAAW,OACXsI,oBAAqB,OACrBznE,kBAAmBlI,IAAAA,OAAsB,KACzC4I,YAAa5I,IAAAA,KAAoB,KACjCsN,KAAM,YACNb,cAAe,UACfsxD,2BAA4B/9D,IAAAA,KAAoB,KAChD89D,qBAAsB,OACtBxwF,KAAM,YACN2sC,WAAYja,IAAAA,IAAmB,KAC/Bka,SAAUla,IAAAA,MAAqB,KAC/B4vE,eAAgB5vE,IAAAA,IAAmB,KACnC4Y,cAAe,YACfD,YAAa,YACbk3D,8BAA8B73E,EAAAA,EAAAA,IAAwB,UAAW,KACjE2P,uBAAwB,OACxBm/D,0BAA2B,UAC3BgJ,eAAgB9vE,IAAAA,MAAqB,KACrCkU,cAAe,YACfnE,UAAW,YACXvzB,KAAM,UACN0mB,cAAe,YACf4T,UAAW,YACXC,QAAS,YACT1I,gBAAiB,YACjBC,cAAe,YACf4I,SAAU,YACVC,OAAQ,YACR0B,WAAY,WAGDrC,EAAsC,CACjDS,SAAU,YACVE,OAAQ,UACRH,WAAY,YACZE,SAAU,aAGC64D,EAA6C,CACxDziG,KAAM,UACN23F,WAAYjlE,IAAAA,IAAmB,MAGpBgwE,EAA4C,CACvD1iG,KAAM,UACN23F,WAAYjlE,IAAAA,IAAmB,MAGpBiwE,EAAyC,CACpD3iG,KAAM,UACNyH,OAAQ,UACRwH,sBAAuB,WAGZ2zF,EAAwC,CACnD5iG,KAAM,UACNyH,OAAQ,UACRwH,sBAAuB,WAEZ4zF,EAA+B,CAC1C,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,WAIW15D,EAAwB,CACnCM,QAAS,UACTD,UAAW,WAGN,IAAKyiB,EAAa,SAAbA,GAAa,OAAbA,EAAAA,EAAa,aAAbA,EAAAA,EAAa,iBAAbA,EAAAA,EAAa,qBAAbA,EAAAA,EAAa,mBAAbA,CAAa,MAOlB,MAAMh6D,EAAyB,E,yGC9KtC,MAAM8B,UAA8BhK,IAAAA,MAClC,gBAAOoG,GACL9G,KAAKgH,UACH,wBACA,WACA,8BACA,6BACA,gBACA,eAEJ,CAEA0O,SACAuuD,4BACAxB,2BACAC,aACA8gB,cAEArgF,WAAAA,GAA6D,IAAjDJ,EAA0C3B,UAAAnB,OAAA,QAAAoI,IAAAjH,UAAA,GAAAA,UAAA,GAAG,CAAC,EACxD6I,MAAMlH,GAEN/C,KAAK0V,SAAW3S,EAAM2S,UAAY,GAClC1V,KAAK0iE,aAAe3/D,EAAM2/D,eAAgB4nB,EAAAA,EAAAA,MAC1CtqF,KAAKyiE,2BAA6B1/D,EAAM0/D,6BAA8ByB,EAAAA,EAAAA,IAAQlkE,KAAK0iE,aAAc,GACjG1iE,KAAKikE,4BAA8BlhE,EAAMkhE,8BAA+BC,EAAAA,EAAAA,IAAQlkE,KAAK0iE,aAAc,GACnG1iE,KAAKwjF,cAAgBzgF,EAAMygF,eAAiB5gB,EAAAA,GAAc0C,GAC5D,CAEA3C,iBAAoB82C,IACdz5G,KAAKwjF,gBAAkBi2B,GACzBz5G,KAAKmQ,iBAAiB,CAAEqzE,cAAei2B,GACzC,EAIJ,S,6HCvCA,MAAM9uG,UAAgBjK,IAAAA,MACpB,gBAAOoG,CAAUC,GACf/G,KAAKgH,UAAU,UAAW,WAAY,aAAc,SAAU,aAC9DhH,KAAKiH,UAAU,OAAQF,EACzB,CAMA4kD,WAA4B,KAC5B5hD,UAA2B,KAC3B2hD,QAAU,EAEVguD,cAAel4D,EAAAA,EAAAA,WAAan5C,EAAYiiF,EAAAA,GAExCnnF,WAAAA,GACE8G,SAAM7I,WACN,MAAMwqD,EAAYxqD,UAAAnB,QAAA,OAAAoI,EAAAjH,UAAA,GAClBpB,KAAK+J,UAAY6hD,GAAc7hD,WAAa/J,KAAK05G,iBACjD15G,KAAKkkF,IAAI,UAAU,KACjBlkF,KAAKmQ,iBAAiB,CACpBu7C,OAAQE,GAAcF,QAAU1rD,KAAK0yB,OAAOinF,wBAAwB90F,IAAM,GAC1E,GAEN,CAEAxL,OAAAA,CAAQ5P,GACN,MAAMmwG,EAAc55G,KAAKyJ,SACzBzJ,KAAK0vC,gBAAgB,WAAYjmC,GACjCzJ,KAAKuJ,QAAQ,UAAWvJ,KAAM45G,EAChC,CAEAjjC,SAAAA,GACE,MAAM,SAAEltE,EAAQ,QAAEowG,GAAY75G,MACxB,MAAE+C,GAAU0G,GACZ,MAAE0N,GAAU1N,EAAS/H,MACrBo4G,EAAY5yF,IAAM,CAAE2yF,WAAW92G,GAC/Bg3G,EAAS9pF,EAAAA,EAAmBxmB,EAASkM,MAA2B4b,WAAWuoF,EAAWrwG,EAAS/H,QAC/F,cAAEijC,GAAkB3kC,KAAK0yB,OAAOrU,yBAChCkY,EAASoO,EAAcn1B,KAAmC,EAA5Bm1B,EAAcD,YAClDq1E,EAAOv5F,OAAOrJ,EAAMqH,EAAE0N,OAAOqK,GAASpf,EAAMsH,EAAEyN,OAAOqK,GAAUpf,EAAMsH,EAAEyN,OAAO,IAC9E6tF,EAAOv2F,8BACP7Y,EAAQ+4D,OAAO,CAAEj6D,SAAUswG,EAAQF,YACnC75G,KAAKuJ,QAAQ,YAAavJ,KAAM+5G,EAClC,CAEAC,YAAAA,CAAatuD,GACX,MAAMuuD,EAAgBj6G,KAAK0rD,OACrBwuD,EAAgBxuD,EAASuuD,EAAgB,GAAK,EAEpD,GAAIj6G,KAAKgrD,WAAahrD,KAAKu7B,cAYzB,OAXoB,IAAhBv7B,KAAK0rD,QACP1rD,KAAKmQ,iBAAiB,CAAEu7C,OAAQ,SAElC1rD,KAAK0yB,OACFs7B,iBACAp2C,QAAQ9V,IAC8B,IAAlBo4G,EAAsBp4G,EAAQ4pD,QAAUA,EAAS5pD,EAAQ4pD,QAAUA,IACjE5pD,EAAQmsD,cAE9B1lD,SAASzG,GAAYA,EAAQk4G,cAA8B,EAAjBE,KAK/C,MAAMC,EAAuB,IAAXzuD,EAAewuD,EAAgBxuD,GAC3C,IAAEhnC,EAAG,IAAEG,GAAQ7kB,KAAK0yB,OAAOinF,wBACjC,GACEM,IAAkBE,GACjBF,IAAkBv1F,IAA0B,IAAnBw1F,GACzBD,IAAkBp1F,GAAyB,IAAlBq1F,EAE1B,OAEF,MAAM,kBAAEE,EAAiB,kBAAEC,GAAsBr6G,KAAK0yB,OAAO4nF,6BAE7DC,EAAAA,EAAAA,IAAsB,CACpBC,cAAeJ,EACfK,WAAYN,EAAY,EAAIn6G,UAAOqI,EACnCqyG,UAAWT,EACXE,YACAQ,aAAa,KAGfJ,EAAAA,EAAAA,IAAsB,CACpBC,cAAeH,EACfI,WAAYN,EAAY,EAAIn6G,UAAOqI,EACnCqyG,UAAWT,EACXE,aAEJ,CAEAvjC,YAAAA,GACE52E,KAAKg6G,aAAah6G,KAAK0yB,OAAOinF,wBAAwB90F,IAAM,EAC9D,CAEAgyD,UAAAA,GACE72E,KAAKg6G,aAAah6G,KAAK0yB,OAAOinF,wBAAwBj1F,IAAM,EAC9D,CAEAoyD,YAAAA,GACE92E,KAAKg6G,aAAah6G,KAAK0rD,OAAS,EAClC,CAEAqrB,YAAAA,GACE/2E,KAAKg6G,aAAah6G,KAAK0rD,OAAS,EAClC,CAEAV,OAAAA,GACE,QAAShrD,KAAKyJ,UAAUkM,KAAKrV,WAAW,UAC1C,CAEAi7B,WAAAA,GACE,QAASv7B,KAAKyJ,UAAUkM,KAAKrV,WAAW,cAC1C,CAEAs6G,SAAAA,GACE,QAAS56G,KAAKyJ,UAAUkM,KAAKrV,WAAW,YAC1C,CAEA2tD,SAAAA,GACE,QAASjuD,KAAKyJ,UAAUkM,KAAKrV,WAAW,UAC1C,CAEAkzD,YAAAA,GACE,QAASxzD,KAAKyJ,UAAUkM,KAAKrV,WAAW,cAC1C,CAEAwxB,WAAAA,GACE,QAAS9xB,KAAKyJ,UAAUqoB,WAC1B,CAEA0xC,qBAAAA,GACE,OAAOxjE,KAAK8xB,eAAiB9xB,KAAKyJ,SAASwoB,gBAC7C,CAEAjoB,QAAAA,GACE,MAAO,IACFhK,KAAKyJ,SAASO,WACjBD,UAAW/J,KAAK+J,UAChB2hD,OAAQ1rD,KAAK0rD,OAEjB,CAEAxhD,QAAAA,GACE,MAAO,IACFlK,KAAKyJ,SAASS,WACjBH,UAAW/J,KAAK+J,UAChB2hD,OAAQ1rD,KAAK0rD,OAEjB,CAEAgI,cAAAA,CAAehvD,GACb,OAAO1E,KAAK60D,QAAQnwD,EACtB,CAEAm2G,gBAAAA,GACE76G,KAAK0vC,gBAAgB,YAAa1vC,KAAK05G,iBACzC,EAGF,S,gKCpKA,MAAMoB,EAAe,CAAEvlE,MAAO,EAAG2U,QAAS,IACpC6wD,EAAa,CAAExlE,MAAO,GAAI2U,QAAS,IAQlC,SAAS8wD,EAAsBrzG,GAQnC,IARoC,YACrCszG,EAAW,YACXC,EAAW,UACX14G,GAKDmF,EACKwzG,GAAe3lD,EAAAA,EAAAA,IAAsBhzD,GACzC,MAAM44G,EACJH,EAAYtxG,QAAQoqD,WAAanW,EAAAA,GAA2BxjB,SAAS6gF,EAAYxmG,WAC7E4mG,EACJH,EAAYvxG,QAAQoqD,WAAanW,EAAAA,GAA2BxjB,SAAS8gF,EAAYzmG,WAkBnF,MAhBI,CAACuzB,EAAAA,GAAUlc,EAAGkc,EAAAA,GAAUW,EAAGX,EAAAA,GAAUX,GAAGjN,SAAS6gF,EAAYxmG,aAC/D0mG,GAAeG,EAAAA,EAAAA,GAAQH,EAAcL,IAGnCI,EAAYzmG,YAAcuzB,EAAAA,GAAUX,EACtC8zE,GAAeG,EAAAA,EAAAA,IAAQC,EAAAA,EAAAA,GAAeJ,GAAeJ,GAC5CG,EAAYzmG,YAAcuzB,EAAAA,GAAUW,EAC7CwyE,GAAeG,EAAAA,EAAAA,IAAQE,EAAAA,EAAAA,GAAcL,EAAc,CAAEM,aAAc,IAAMV,GAChEG,EAAYzmG,YAAcuzB,EAAAA,GAAUlc,GAAwC,UAAnCovF,EAAYvxG,QAAQkJ,aACtEsoG,GAAeO,EAAAA,EAAAA,GAASP,IAGtBC,IAA4BC,GAA8D,UAAnCH,EAAYvxG,QAAQkJ,aAC7EsoG,EAlCJ,SAAoC3zE,GAClC,MAAM+N,EAAQ/N,EAAK1iC,WACbolD,EAAU1iB,EAAKziC,aACrB,OAAOwwC,EAAQulE,EAAavlE,OAAUA,IAAUulE,EAAavlE,OAAS2U,EAAU4wD,EAAa5wD,OAC/F,CA8BmByxD,CAA2BR,IAAgBG,EAAAA,EAAAA,GAAQH,EAAcL,GAAgBK,OAGxFlhB,EAAAA,EAAAA,IAAqBkhB,GAAc,GAAO3iB,UAAY,IAClE,CC5CO,MAAM3kB,UAAcnzE,IAAAA,MACzB,gBAAOoG,GACL9G,KAAKgH,UAAU,QAAS,YACxBhH,KAAKiH,UAAU,OAAQsD,EAAAA,EACzB,CAKAqxG,iBAAmBA,MAAQ57G,KAAK0yB,QAAQhpB,QAAQkG,qBAAqBymD,EAAAA,GAAkBgiD,WAEvFwD,wBAA2BnpF,KAAiB1yB,KAAK0yB,QAAQhpB,QAAQvH,IAAIuwB,EAAKhpB,SAE1EiuE,2BAA8BjlD,GAAe1yB,KAAK47G,oBAAsB57G,KAAK67G,wBAAwBnpF,GAErG0lB,qBAAwB1lB,IACtB,GAAI1yB,KAAK6X,SAAU,CACjB,GAAI7X,KAAK67G,wBAAwBnpF,GAC/B,OAAOrT,KAAK2E,MAAMhkB,KAAK6X,SAAS2G,GAElC,MAAMs9F,EAAc97G,KAAK0yB,OACzB,GAAI1yB,KAAK47G,oBAAsBE,EAAa,CAC1C,MAAMC,EAAeD,EAAYpyG,QAC3BsyG,EAAmBtpF,EAAKhpB,QACxBuyG,EAAyBF,EAAapyG,QAAQ+Z,yBAAyBrE,KAAK2E,MAAMhkB,KAAK6X,SAAS2G,IAChG09F,EAAuBF,EAAiBryG,QAAQia,0BACpDo3F,EAAuB,CACrBC,YAAac,EACbb,YAAac,EACbx5G,UAAWy5G,KAGf,OAAO58F,KAAK+E,MAAM83F,EACpB,CACF,CAEA,OAAOp4F,OAAOwxB,GAAG,EAGnB6mE,gBAAmBzpF,IACjB,MAAMmD,EAAY71B,KAAK6X,UAAU4G,GAAK,KAEtC,GAAIze,KAAK0yB,QAAQvwB,IAAIuwB,GACnB,OAAOmD,EAGT,GAAI71B,KAAK47G,oBAAsB57G,KAAK0yB,OAAQ,CAC1C,MAAM0pF,EAAiBp8G,KAAK0yB,QAAQ2pF,kBAEpC,OAAOD,IADkB1pF,EAAK2pF,kBACexmF,EAAY,IAC3D,CAEA,OAAO,IAAI,EAQfg+C,EAAM/sE,YAEN,MAAMw1G,EAAQzoC,EAAMnQ,SACpB44C,EAAM3sF,OAEN,S,iJClDA,MAAM4sF,EAA+B,CACnC9zG,EAAAA,GAAoBs/C,MACpBt/C,EAAAA,GAAoBq/C,UACpBr/C,EAAAA,GAAoBu/C,iBACpBv/C,EAAAA,GAAoBw/C,iBACpBx/C,EAAAA,GAAoBy/C,gBACpBz/C,EAAAA,GAAoB0/C,gBAGtB,MAAM59C,UAAa7J,IAAAA,MACjB,gBAAOoG,CACL0vE,EACAgmC,EACApyG,GAEApK,KAAKgH,UAAU,OAAQ,SAAU,QAAS,aAAc,WAAY,aACpEhH,KAAK42G,QAAQ,WAAYpgC,GACzBx2E,KAAK42G,QAAQ,cAAe4F,GAC5Bx8G,KAAKiH,UAAU,cAAeuvE,GAC9Bx2E,KAAKiH,UAAU,QAASmD,EAC1B,CAeAuoB,UAAkC,KAClC8c,WAAkD,KAElDikB,cAAAA,CAAehvD,GAMb,OALA1E,KAAK0V,WACF1T,MACAuG,SAASzG,IACRA,EAAQ4xD,gBAAgB,IAErB1zD,KAAK60D,QAAQnwD,EACtB,CAEAsF,QAAAA,GACE,MAAM0L,EAAW1V,KAAK0V,WACnB1T,MACA0L,KAAKxL,GAAOA,EAAG8H,aAClB,MAAO,CACLvC,OAAQzH,KAAKyH,OACb0P,MAAOnX,KAAKmX,MACZs4B,WAAYzvC,KAAKyvC,WACjB/5B,WAEJ,CAEAxL,QAAAA,GAAoC,IAA3BotG,EAAQl2G,UAAAnB,OAAA,QAAAoI,IAAAjH,UAAA,GAAAA,UAAA,GAAG,GAClB,MAAMsU,EAAW1V,KAAK0V,WACnB1T,MACA0L,KAAKxL,GAAOA,EAAGgI,aAClB,OAAOiqB,IACL,CACE1sB,OAAQzH,KAAKyH,OACbgoC,WAAYzvC,KAAKyvC,WACjB/5B,YAEF4hG,EAEJ,CAEAmF,IAAAA,CAAK9qE,GACH,MAAM+qE,EAAa18G,KAAK0J,QAAQ8iD,cAC1B2G,EAAYupD,EAAW7yG,MAAM6oB,IAAUA,EAAKg/C,uBAC5CirC,EAAaD,EAAW7yG,MAAM6oB,GAAS1yB,KAAKmC,IAAIuwB,KAEtD,IAAKygC,IAAcwpD,EAAY,OAE/B,MAAMC,EAA0BryG,EAAKsyG,QAAQjlG,QAAQ8a,GAASA,EAAKoqF,WAAaH,EAAWG,WACrFC,EAAwBxyG,EAAKsyG,QAAQjlG,QAAQ8a,GAASA,EAAKoqF,WAAaH,EAAWG,WAEnFE,EAAoBJ,EAAwB/6G,WAAWb,GAAWA,EAAOE,KAAOy7G,EAAWz7G,KAC3F+7G,EAA2BL,EAAwBhlG,QAAO,CAAC8Z,EAAGzvB,IAAUA,IAAU+6G,IAClFE,EAAmBD,EAAyBp7G,WAAWb,GAAWA,EAAOE,KAAOiyD,EAAUjyD,KAE1Fi8G,EAAaF,EAAyB58G,MAAM,EAAG68G,GAC/CE,EAAaH,EAAyB58G,MAAM68G,EAAmB,GACjEvrE,IAAc75B,EAAAA,GAASC,QACzBolG,EAAW57G,KAAKq7G,EAAwBI,IACxCG,EAAWvwG,MAAK,CAACC,EAAGC,IAAMD,EAAEwwG,eAAiBvwG,EAAEuwG,kBAE7C1rE,IAAc75B,EAAAA,GAASK,QACzBilG,EAAW77G,KAAKq7G,EAAwBI,IACxCI,EAAWxwG,MAAK,CAACC,EAAGC,IAAMD,EAAEwwG,eAAiBvwG,EAAEuwG,kBAGjD9yG,EAAKsyG,QAAUE,EAAsB3rB,OAAO,IACvC+rB,EACHF,EAAyBC,MACtBE,IAELp9G,KAAK0J,QAAQH,QAAQ,SAAUvJ,KAAK0J,QACtC,CAEA2U,sBAAAA,GACE,OAAOA,EAAAA,EAAAA,IAAuBre,KAAK0J,QAAQkqB,eAC7C,CAEAo6B,cAAAA,GACE,OAAOhuD,KAAK0V,WACT1T,MACA4K,MAAK,CAACC,EAAGC,IAAMD,EAAE6+C,OAAS5+C,EAAE4+C,QACjC,CAEA6H,iBAAAA,GAAmC,IAAjB+pD,IAAQl8G,UAAAnB,OAAA,QAAAoI,IAAAjH,UAAA,KAAAA,UAAA,GACxB,MAAMwI,EAAc,IAAI5J,KAAK4J,cAAc5H,OAC3C,OAAOs7G,EAAW1zG,EAAYgD,MAAK,CAACC,EAAGC,IAAMD,EAAE6+C,OAAS5+C,EAAE4+C,SAAU9hD,CACtE,CAEA8oD,0BAAAA,GACE,OAAO1yD,KAAKguD,iBAAiBnkD,MAAM3H,GAAOA,EAAG8oD,WAAa9oD,EAAGq5B,iBAAkB,IACjF,CAEAm2C,kBAAAA,GACE,QAAS1xE,KAAK8qD,eAAevvB,aAC/B,CAEAu3C,cAAAA,GACE,QAAS9yE,KAAK8qD,eAAeE,SAC/B,CAEAuyD,WAAAA,GACMv9G,KAAK0xE,sBACP1xE,KAAK0vC,gBAAgB,SAAU35B,EAAAA,GAAoBT,WAEjDtV,KAAK8yE,kBACP9yE,KAAK0vC,gBAAgB,SAAU35B,EAAAA,GAAoBrM,MAEvD,CAEA2yG,eAAAA,GACE,OAAOr8G,KAAK0J,QACT8iD,cACA3qD,WAAWsxD,GAAcA,EAAUhxD,IAAInC,OAC5C,CAEA25G,qBAAAA,GACE,IAAI90F,GAAO,EACPH,EAAM,EASV,OARA1kB,KAAKguD,iBAAiBzlD,SAASrG,IACzBA,EAAGwpD,OAAS7mC,IACdA,EAAM3iB,EAAGwpD,QAEPxpD,EAAGwpD,OAAShnC,IACdA,EAAMxiB,EAAGwpD,OACX,IAEK,CAAEhnC,MAAKG,MAChB,CAEAy1F,yBAAAA,GACE,MAAMkD,EAAkBx9G,KAAKguD,iBACvBosD,EAA+B,GAC/BC,EAA+B,GAUrC,OATAmD,EAAgBj1G,SAASrG,IACnBA,EAAGwpD,OAAS,GACd0uD,EAAkB74G,KAAKW,GAErBA,EAAGwpD,OAAS,GACd2uD,EAAkB94G,KAAKW,EACzB,IAGK,CAAEk4G,oBAAmBC,oBAC9B,CAEAj2C,iBAAAA,GACE,MAAM,kBAAEg2C,EAAiB,kBAAEC,GAAsBr6G,KAAKs6G,6BACtDmD,EAAAA,EAAAA,IAAuB,CAAEjD,cAAeJ,EAAmBO,aAAa,KACxE8C,EAAAA,EAAAA,IAAuB,CAAEjD,cAAeH,EAAmBM,aAAa,GAC1E,CAEAtvD,iBAAAA,GACE,OAAOrrD,KAAK0J,QAAQ2hD,mBACtB,CAEAgyD,YAAAA,GACE,OAAOv5F,OAAO9jB,KAAKkB,GAAGmY,QAAQ,KAAM,IACtC,CAEAu6C,yBAAAA,GACE,IAAK5zD,KAAKmX,QAAUnX,KAAKmX,MAAM4gG,eAAe,KAC5C,OAGF,MAAMnuG,EAAc5J,KAAKuzD,mBAAkB,GAAO3mD,MAChD,CAACC,EAAGC,IAAMD,EAAEpD,SAAS1G,MAAM0wB,mBAAoBjV,EAAI1R,EAAErD,SAAS1G,MAAM0wB,mBAAoBjV,IAEpFk/F,EAAoB9zG,EAAYC,MAAM4iE,GAAeA,EAAWhjE,SAASuoB,YACzE2rF,EAAmB/zG,EAAYC,MAAM4iE,GAAeA,EAAWhjE,SAAS6lD,SAExEsuD,EAAqD,GACrDC,EAAoD,GACpDC,EAAmD,GAEzDl0G,EAAYrB,SAAQ,CAACkkE,EAAYxqE,KAC/B,MAAM87G,EAA0Bn0G,EAAYgO,QAC1C,CAAComG,EAAc97F,IACbA,EAAIjgB,GAASod,KAAK2E,MAAMyoD,EAAWhjE,SAAS1G,MAAMyb,KAAOa,KAAK2E,MAAMg6F,EAAcv0G,SAAS1G,MAAMyb,KAErGiuD,EAAWt8D,iBAAiB,CAAEjJ,OAAQ62G,EAAwB99G,SAC9D,MAAM+xB,EAAYy6C,EAAWhjE,WAAai0G,GAAmBj0G,SACvDw0G,EAAWxxC,EAAWhjE,WAAak0G,GAAkBl0G,SACrDy0G,EAAgBzxC,EAAWhjE,SAASkM,OAAS+nG,GAAmBj0G,SAASkM,KACzEwoG,EAAa1xC,EAAWhjE,SAASkM,OAASgoG,GAAkBl0G,SAASkM,KACtEqc,GAAcisF,IACbC,EACFN,EAA8Br8G,KAAKkrE,GAC1B0xC,EACTN,EAA6Bt8G,KAAKkrE,GAElCqxC,EAA4Bv8G,KAAKkrE,GAErC,IAGFqxC,EAA4BlxG,MAC1B,CAACC,EAAGC,IACFyvG,EAA6B/7G,QAAQqM,EAAEpD,SAASojE,yBAChD0vC,EAA6B/7G,QAAQsM,EAAErD,SAASojE,2BAGzB,IACtBixC,KACAD,EACHF,KACGC,EACHF,GACA9lG,OAAOs/C,SACU3uD,SAAQ,CAACkkE,EAAYxqE,KACtCwqE,EAAYt8D,iBAAiB,CAAEu7C,OAAQzpD,GAAQ,GAEnD,EAGF,S,iMCtPA,MAAMm8G,EAAa,CAAC,EAEb,SAASC,EAAc12G,GAI+D,IAJ9D,IAC7BxB,EAAG,IACHwH,EAAG,UACHinD,GACyFjtD,EACzF,MAAMgC,EAAQy0G,EAAWj4G,GACzB,OAAIwD,GAAO20G,WAAa1pD,GAAajnD,EAC5BhE,EAAMgE,GACHA,EAGL,KAFEhE,CAGX,CAEO,SAAS40G,EAAcn2G,GAK2C,IAL1C,IAC7BjC,EAAG,IACHwH,EAAG,MACHC,EAAK,UACLgnD,GACqExsD,EACrEg2G,EAAWj4G,GAAO,IACZi4G,EAAWj4G,IAAMm4G,WAAa1pD,EAAYwpD,EAAWj4G,GAAO,CAAC,EACjE,CAACwH,GAAMC,EACP0wG,SAAU1pD,EAEd,C,eChCA,MA4EM4pD,EAAa,CACjBlxE,KAAM,GACNnxB,KAAM,GACN4sB,IAAK,GACL3N,MAAO,GACPe,OAAQ,GACRqL,KAAM,GACNotB,WAAY,EACZ6pD,sBAAuB,EACvBlrG,YAAY,EACZmrG,OAAO,EACPlpG,UAAMnN,EACNjF,UAAMiF,EACN2sC,uBAAmB3sC,EACnB8rC,wBAAoB9rC,EACpB6sC,4BAAwB7sC,EACxBisC,8BAA0BjsC,EAC1B4rD,SAAU,GACV0qD,sBAAkBt2G,EAClBu2G,sBAAkBv2G,EAClBquC,oBAAgBruC,EAChB2lC,cAAU3lC,EACV4lC,cAAU5lC,EACV6lC,aAAS7lC,EACT4yB,eAAW5yB,EACXslC,gBAAYtlC,EACZw2G,YAAQx2G,EACR6kC,cAAU7kC,EACV+wC,eAAW/wC,EACXolC,gBAAYplC,EACZwhC,iBAAaxhC,EACbuB,YAAa,IAqEf,MAAMY,UAAc9J,IAAAA,MAClB,gBAAOoG,GACL9G,KAAKgH,UACH,QACA,SACA,OACA,aACA,YACA,OACA,OACA,MACA,QACA,OACA,SACA,WACA,WACA,UACA,YACA,WACA,aACA,WACA,SACA,YACA,OACA,cACA,aACA,cACA,YACA,oBACA,qBACA,yBACA,2BACA,cACA,YACA,SACA,cACA,WACA,mBACA,mBACA,iBACA,YACA,aACA,WACA,WACA,WACA,iBACA,kBACA,aACA,kBACA,YACA,wBACA,UACA,SACA,QAEJ,CAEA,gBAAaksB,CAAGoH,GAQmB,IAPjCsR,OAAQkzE,EAAS,WACjBjsG,EAAU,UACV4B,EAAS,QACT/P,EAAO,gBACP0vD,EAAe,eACf2qD,GAAiB,EAAI,UACrBxP,GACej1E,EACf,MAAMsR,EAASkzE,EAAUzlG,QAAQ,IAAK,KAC/B1P,GAASo1G,EACZv0G,EAAMo6C,QACHD,GA3H0Bv8C,KAAA,IAAC,MACpCuB,EAAK,OACLiiC,EAAM,WACN/4B,EAAU,UACV4B,GAMDrM,EAAA,OAAKuB,EAAMiiC,SAAWA,GAAUjiC,EAAMkJ,aAAeA,GAAclJ,EAAM8K,YAAcA,CAAS,EAkHrFuqG,CAA6B,CAAEr1G,MAAOg7C,EAAG/Y,SAAQ/4B,aAAY4B,eA/G7C3G,KAAA,IAAC,MAAEnE,EAAK,KAAE6kD,GAAuC1gD,EAAA,OAAM0gD,GAAQ7kD,EAAM4lG,YAAc/gD,CAAI,EAgHvGywD,CAAoB,CAAEt1G,MAAOg7C,EAAG6J,KAAM+gD,KA3GzB5lG,KAAsC,IAArBA,EAAMirD,WAAoBjrD,EAAM4J,WA4G9D2rG,CAAgBv6D,IA/GLj1C,KAAA,IAAC,MAAE/F,EAAK,QAAEjF,GAAoDgL,EAAA,OAClFhL,GAAS8vD,gBAAkB9vD,EAAQ8vD,eAAe7qD,EAAM,EA+G/Cw1G,CAAe,CAAEx1G,MAAOg7C,EAAGjgD,cAC1BigD,EAAE9xC,aAAeC,EAAAA,GAAWC,OAC3B+Q,OAAO2/E,UAAU9+C,EAAEG,SAxIAn9C,KAAA,IAAC,MAAEgC,EAAK,QAAEjF,GAAoDiD,EAAA,SAC5FgC,EAAMoqD,YAAervD,GAASqvD,YAC9BpqD,EAAMqqD,cAAiBtvD,GAASsvD,cAChCrqD,EAAMy1G,cAAiB16G,GAASuvD,UAE/BvvD,GAAS6vD,SAAY5qD,EAAM4qD,OAAO,EAoIxB8qD,CAAyB,CAAE11G,MAAOg7C,EAAGjgD,eAE3C,GAEJ,GAAIiF,EAMF,OALIA,EAAM4J,iBACF5J,EAAM21G,6BACH56G,GAAS+vD,iCACZ9qD,EAAMopD,UAAU,CAAEC,UAAWC,EAAAA,EAAeC,UAAWkB,oBAExDzqD,EAGT,MAAM01E,EAAW70E,EAAMk5D,OAAc,IAChC86C,EACH5yE,SACAn3B,YACA5B,aACA08F,YACAgQ,QAAS76G,GAAS66G,QAClBxrD,YAAarvD,GAASqvD,UACtBC,cAAetvD,GAASsvD,YACxBorD,cAAe16G,GAASuvD,SACxBM,SAAU7vD,GAAS6vD,SAKrB,aAFM8qB,EAAStsB,UAAU,CAAEC,UAAWC,EAAAA,EAAe2oB,QAASxnB,oBAEvDirB,CACT,CAEA,mBAAaqwB,CAAO8P,GAElB,GAAoC,IAAhCA,EAAqBv/G,OACvB,MAAO,CAAC,EAGV,UACQkd,QAAQnb,IACZw9G,EAAqB9xG,KAAI6sB,IAAA,IAAC,OAAEqR,EAAM,WAAE/4B,EAAU,UAAE4B,GAAW8lB,EAAA,OACzDv6B,KAAKkzB,IAAI,CAAE0Y,OAAQA,EAAQ/4B,aAAY4B,aAAY,KAevD,OAZa+qG,EAAqBzyG,QAChC,CAAC0yG,EAAavJ,KAAiB,IAC1BuJ,EACH,CAACvJ,EAAatqE,QAASphC,EAAMo6C,QAC1BD,GACCA,EAAE/Y,SAAWsqE,EAAatqE,QAC1B+Y,EAAE9xC,aAAeqjG,EAAarjG,YAC9B8xC,EAAElwC,YAAcyhG,EAAazhG,YAC/B,MAEJ,CAAC,EAGL,CAAE,MAAOqI,GACP,CAEJ,CA2DA,kBAAM4iG,CAAY1tE,GAMf,IANgB,gBACjBoiB,EAAe,QACf1vD,EAAU,CAAEiR,KAAMgqG,EAAAA,EAAwBC,MAI3C5tE,EACKptC,EAA4B,KAC5B85G,GAAQ,EACRhqD,GAAkB,EAEtB,MAAMmrD,GAAkB1/C,EAAAA,EAAAA,IAAuB,CAC7Ct1D,SAAU7K,KAAK8/G,OAAOp7G,GACtB27D,mBAAoB,CAAC,KACrBjM,oBAGFp0D,KAAKmQ,iBAAiB,CACpBoD,YAAY,EACZssG,oBAGF,IACEj7G,QAAai7G,CACf,CAAE,MAAO/iG,IACHijG,EAAAA,EAAAA,IAAgBjjG,KAClB43C,GAAkB,GAIpBgqD,EAAQ5hG,aAAekjG,EAAAA,EAEzB,CAEA,MAAMC,GAAuBr7G,IAAS8vD,GAAmBhwD,EAAQiR,OAASgqG,EAAAA,EAAwBC,IAalG,OAPA5/G,KAAKmQ,iBAAiB,IAChB8vG,EAAsBzB,EAAa,CAAC,EACxCE,QACAhqD,kBACAnhD,YAAY,IAGP3O,CACT,CAEA,qCAAMipE,GAIE,IAJ8B,gBACpCzZ,GAGDhzD,UAAAnB,OAAA,QAAAoI,IAAAjH,UAAA,GAAAA,UAAA,GAAG,CAAC,EACH,MAAMwD,QAAa5E,KAAK0/G,aAAa,CAAEtrD,oBACvC,SAAIxvD,GAAQA,EAAK4iC,KAAKvnC,OAAS,GAAKD,KAAKwnC,KAAKvnC,OAAS,IAC9CD,KAAKwnC,KAAKxnC,KAAKwnC,KAAKvnC,OAAS,IAAM2E,EAAK4iC,KAAK,EAGxD,CAEA,eAAMurB,CAAS7f,GAMZ,IACGxuC,GAPU,UACdsuD,EAAS,gBACToB,GAIDlhB,EAEC,GAAI8f,IAAcC,EAAAA,EAAe2oB,QAC/Bl3E,EAAU,CAAEiR,KAAMgqG,EAAAA,EAAwBC,SACrC,IAAI5sD,IAAcC,EAAAA,EAAeC,UAMtC,OALAxuD,EAAU,CAAEiR,KAAMgqG,EAAAA,EAAwBO,QACrClgH,KAAKy+G,uBAAyB,GA5bG,KA6bpC/5G,EAAQm6G,OAAS7+G,KAAK6+G,OAI1B,CACI7+G,KAAK6S,aAAeC,EAAAA,GAAWC,QACjCrO,EAAQ6vD,OAAwB,MAAfv0D,KAAKu0D,QAAwBv0D,KAAKu0D,QAGrD,MAAM3vD,QAAa5E,KAAK0/G,aAAa,CAAEtrD,kBAAiB1vD,YAExD,IAAKE,IAA2B,IAAnBA,EAAKu7G,UAIhB,YAHAngH,KAAKmQ,iBAAiB,CACpBsuG,uBAAwBz+G,KAAKy+G,uBAAyB,GAAK,IAI/D,GAAIz+G,KAAKyU,YAAc7P,EAAK6P,WAAazU,KAAK4rC,OAAO4pD,gBAAkB5wF,EAAKgnC,QAAQ4pD,cAClF,OAGF,MAAM4qB,EAAe,CACnB5qG,KAAM5Q,EAAK4Q,KACXpS,KAAMwB,EAAKxB,KACXkqC,KAAM1oC,EAAK0oC,KACXnxB,KAAMvX,EAAKuX,KACX4sB,IAAKnkC,EAAKmkC,IACV3N,MAAOx2B,EAAKw2B,MACZe,OAAQv3B,EAAKu3B,OACbqL,KAAM5iC,EAAK4iC,KACXwN,kBAAmBpwC,EAAKowC,kBACxBb,mBAAoBvvC,EAAKuvC,mBACzBe,uBAAwBtwC,EAAKswC,uBAC7BZ,yBAA0B1vC,EAAK0vC,yBAC/B2f,SAAUrvD,EAAKqvD,UAAY,GAC3B0qD,iBAAkB/5G,EAAK+5G,iBACvBC,iBAAkBh6G,EAAKg6G,iBACvBloE,eAAgB9xC,EAAK8xC,eACrB1I,SAAUppC,EAAKopC,SACfC,SAAUrpC,EAAKqpC,SACfC,QAAStpC,EAAKspC,QACdjT,UAAWr2B,EAAKq2B,UAChB0S,WAAY/oC,EAAK+oC,WACjBkxE,OAAQj6G,EAAKi6G,OACb3xE,SAAUtoC,EAAKsoC,SACfmzE,SAAUz7G,EAAKy7G,SACfjnE,UAAWx0C,EAAKw0C,UAChB3L,WAAY7oC,EAAK6oC,WACjB5D,YAAajlC,EAAKilC,YAClBy2E,UAAW17G,EAAK07G,UAChB7B,sBAAuB,EACvB70G,YAAahF,EAAKgF,aAAe,GACjCgrD,UAAW3uD,KAAKC,OAGlB,GAEI8sD,IAAcC,EAAAA,EAAe2oB,UAC7B,CAAC9oE,EAAAA,GAAWq2D,QAASr2D,EAAAA,GAAWs2D,MAAOt2D,EAAAA,GAAW47B,QAAQtU,SAASp6B,KAAK6S,YAE1E,CAIA,IAAI0tG,EAAS,EACTC,EAAS,EACTC,GAAc,EAClB,KAAOF,EAASvgH,KAAKwnC,KAAKvnC,QAAUugH,EAAS57G,EAAK4iC,KAAKvnC,QAAQ,CAC7D,MAAMygH,EAAQ1gH,KAAKwnC,KAAK+4E,GAClBI,EAAQ/7G,EAAK4iC,KAAKg5E,GACxB,QAAcn4G,IAAVs4G,EACF,MACK,GAAID,IAAUC,EAEnB3gH,KAAKstC,KAAKizE,GAAU37G,EAAK0oC,KAAKkzE,GAC9BxgH,KAAKmc,KAAKokG,GAAU37G,EAAKuX,KAAKqkG,GAC9BxgH,KAAK+oC,IAAIw3E,GAAU37G,EAAKmkC,IAAIy3E,GAC5BxgH,KAAKo7B,MAAMmlF,GAAU37G,EAAKw2B,MAAMolF,GAChCxgH,KAAKm8B,OAAOokF,GAAU37G,EAAKu3B,OAAOqkF,GAClCD,IACAC,SACK,GAAIE,EAAQC,QAAmBt4G,IAAVq4G,EAAqB,CAG/C,IAAoB,IAAhBD,GAAqB,CAACz4E,EAAAA,GAAUW,EAAGX,EAAAA,GAAUX,GAAGjN,SAASp6B,KAAKyU,WAAY,CAC5E,MAAMmsG,EAAaL,EAAS,EACtBM,GAAWrrD,EAAAA,EAAAA,IAAsBx1D,KAAKwnC,KAAKo5E,IAC3CE,GAAUtrD,EAAAA,EAAAA,IAAsB5wD,EAAK4iC,KAAKg5E,IAEhD,GACGx4E,EAAAA,GAAUW,IAAM3oC,KAAKyU,YAAassG,EAAAA,EAAAA,GAAWF,EAAUC,EAAS,CAAErF,aAAc,KAChFzzE,EAAAA,GAAUX,IAAMrnC,KAAKyU,YAAausG,EAAAA,EAAAA,GAAYH,EAAUC,GACzD,CACA9gH,KAAKwnC,KAAKo5E,GAAch8G,EAAK4iC,KAAKg5E,GAClCxgH,KAAKstC,KAAKszE,GAAch8G,EAAK0oC,KAAKkzE,GAClCxgH,KAAKmc,KAAKykG,GAAch8G,EAAKuX,KAAKqkG,GAClCxgH,KAAK+oC,IAAI63E,GAAch8G,EAAKmkC,IAAIy3E,GAChCxgH,KAAKo7B,MAAMwlF,GAAch8G,EAAKw2B,MAAMolF,GACpCxgH,KAAKm8B,OAAOykF,GAAch8G,EAAKu3B,OAAOqkF,GACtCC,EAAaG,EAEbJ,IACA,QACF,CACF,CACAxgH,KAAKwnC,KAAKmX,OAAO4hE,EAAQ,EAAG37G,EAAK4iC,KAAKg5E,IACtCxgH,KAAKstC,KAAKqR,OAAO4hE,EAAQ,EAAG37G,EAAK0oC,KAAKkzE,IACtCxgH,KAAKmc,KAAKwiC,OAAO4hE,EAAQ,EAAG37G,EAAKuX,KAAKqkG,IACtCxgH,KAAK+oC,IAAI4V,OAAO4hE,EAAQ,EAAG37G,EAAKmkC,IAAIy3E,IACpCxgH,KAAKo7B,MAAMujB,OAAO4hE,EAAQ,EAAG37G,EAAKw2B,MAAMolF,IACxCxgH,KAAKm8B,OAAOwiB,OAAO4hE,EAAQ,EAAG37G,EAAKu3B,OAAOqkF,IAE1CD,IACAC,GACF,MAAWE,EAAQC,EACjBJ,KAEA19G,QAAQo+G,KAAK,gCACbp7G,OAAOwV,QAAQgZ,eAAe,wCAAyC,CACrEhrB,MAAO,CACL63G,eAAgBlhH,KAAKwnC,KAAKvnC,OAC1BkhH,eAAgBv8G,EAAK4iC,KAAKvnC,OAC1BsgH,SACAC,SACAE,QACAC,WAIR,CAEAP,EAAa54E,KAAOxnC,KAAKwnC,KACzB44E,EAAa9yE,KAAOttC,KAAKstC,KACzB8yE,EAAajkG,KAAOnc,KAAKmc,KACzBikG,EAAar3E,IAAM/oC,KAAK+oC,IACxBq3E,EAAahlF,MAAQp7B,KAAKo7B,MAC1BglF,EAAajkF,OAASn8B,KAAKm8B,MAC7B,CAE+Bn8B,KAAKmQ,iBAAiBiwG,IAInDv6G,OAAOwV,QAAQgZ,eAAe,mDAAoD,CAAEhrB,MAAOrJ,OAExFA,MAEH6F,OAAOwV,QAAQgZ,eAAe,wCAAyC,CAAEhrB,MAAOrJ,OAElFA,KAAKuJ,QAAQypD,EAAWhzD,KAAMgzD,EAChC,CAEA,gCAAMssD,GACJ,IACE,aAAat/G,KAAK6/G,eACpB,CAAE,MACA,CAEJ,CAEA3pC,cAAAA,GAGA,CAEAnwE,IAAAA,CAAKq7G,GACHn3G,MAAMlE,KAAKq7G,GACX,MAAM,UAAExsD,EAAY,GAAMwsD,GACpB,SAAE9C,GAAcD,EAAe,CAAEl4G,IAAKnG,KAAKmG,OAA0C,CAAC,EAgC5F,OA/BInG,KAAKyU,WAAa6pG,IAAa1pD,IACjC2pD,EAAe,CAAEp4G,IAAKnG,KAAKmG,IAAKwH,IAAK,WAAYC,MAAOgnD,EAAWA,cACnE50D,KAAKg+E,WAAa,CAChBh2C,EAAAA,GAAUC,GACVD,EAAAA,GAAUE,GACVF,EAAAA,GAAUG,GACVH,EAAAA,GAAUI,GACVJ,EAAAA,GAAUK,IACVL,EAAAA,GAAUM,IACVN,EAAAA,GAAUO,IACVP,EAAAA,GAAUpoB,EACVooB,EAAAA,GAAUQ,GACVR,EAAAA,GAAUS,IACVrO,SAASp6B,KAAKyU,WAChBzU,KAAKg0C,SAAWh0C,KAAKg+E,WACjB/pC,EAAAA,GAA0Bj0C,KAAKyU,WAC/B,EACJzU,KAAKqhH,SAAWrhH,KAAKkyC,cACrBlyC,KAAKo8B,SAAWp8B,KAAKshH,gBACrBthH,KAAKi0D,SAAWj0D,KAAKi0D,UAAY,GACjCj0D,KAAKuhH,eAAiBvhH,KAAKo8B,SAASqf,SAAQ,CAACrf,EAAUn6B,KACrD,MAAM8gD,EAAY/iD,KAAKo8B,SAASn6B,EAAQ,KAAO,EAC/C,MAAO,IAAIpC,MAAMk1B,KAAK,CAAE90B,OAAQm8B,EAAW2mB,EAAY,IAAKnhC,KAAKvC,KAAKwF,IAAI,EAAG5iB,EAAQ,IAAKA,EAAM,KAGhGjC,KAAKyU,WAAazU,KAAK4rC,SACzB5rC,KAAK4J,YAxeX,SAA6BywB,GAAiF,IAAhF,OAAEuR,EAAM,YAAEhiC,GAAoEywB,EAC1G,OACEzwB,GAAa8D,KAAK9L,IAChB,IAAIijE,EACJ,OAAQjjE,EAAKijE,WACX,KAAKld,EAAAA,GAAiBG,UACpB+c,EAAYjd,EAAAA,GAAeE,UAC3B,MACF,KAAKH,EAAAA,GAAiBI,MACpB8c,EAAYjd,EAAAA,GAAeG,MAC3B,MACF,KAAKJ,EAAAA,GAAiBy5C,SACpBv8B,EAAYjd,EAAAA,GAAew5C,SAG/B,MAAO,IACFx/F,EACHmI,UAAY,GAAE6hC,EAAO4pD,iBAAiB5zF,EAAKijE,aAAajjE,EAAK4/F,gBAC7D38B,YACD,KACG,EAEV,CAkdyB28C,CAAqB,CACtC51E,OAAQ5rC,KAAK4rC,OACbhiC,YAAa5J,KAAK4J,eAGf5J,IACT,CAEA60D,OAAAA,CAAQnwD,GAGN,OAFAuF,MAAM4qD,QAAQnwD,GDvmBX,SAA0BoJ,GAAgD,IAA/C,IAAE3H,GAA2C2H,SACtEswG,EAAWj4G,EACpB,CCsmBIs7G,CAAkB,CAAEt7G,IAAKnG,KAAKmG,MACvBnG,IACT,CAEAkyC,WAAAA,GACE,GAAIlyC,KAAK6S,aAAeC,EAAAA,GAAWC,MACjC,OAAOrC,IAET,OAAQ1Q,KAAKyU,WACX,KAAKuzB,EAAAA,GAAUC,GACf,KAAKD,EAAAA,GAAUE,GACf,KAAKF,EAAAA,GAAUG,GACf,KAAKH,EAAAA,GAAUI,GACf,KAAKJ,EAAAA,GAAUK,IACb,OAAO,GACT,KAAKL,EAAAA,GAAUM,IACf,KAAKN,EAAAA,GAAUO,IACf,KAAKP,EAAAA,GAAUpoB,EACf,KAAKooB,EAAAA,GAAUQ,GACf,KAAKR,EAAAA,GAAUS,GACb,OAAO,GAIb,CAEA2Z,iBAAAA,GACE,MAAMs/D,EAAuBrD,EAAe,CAAEl4G,IAAKnG,KAAKmG,IAAKwH,IAAK,iBAAkBinD,UAAW50D,KAAK40D,YACpG,GAAI8sD,EACF,OAAOA,EAGT,MAAMC,EAAU3hH,KAAKstC,KAAK5/B,KAAI,CAACgkB,EAAGxP,KAAOliB,KAAKstC,KAAKprB,GAAKliB,KAAKmc,KAAK+F,GAAKliB,KAAKo7B,MAAMlZ,GAAKliB,KAAK+oC,IAAI7mB,IAAM,IAMhG0/F,EAAe,CAAEt0E,KALRttC,KAAKstC,KAAKvgC,QACvB,CAACC,EAAKsgC,EAAMprB,IAAM,IAAIlV,GAAY,IAANkV,EAAUorB,EAAOq0E,EAAQ,GAAK30G,EAAIkV,EAAI,GAAKy/F,EAAQz/F,EAAI,IAAM,IACzF,IAGmCkZ,MAAOumF,GAI5C,OAFApD,EAAe,CAAEp4G,IAAKnG,KAAKmG,IAAKwH,IAAK,iBAAkBC,MAAOg0G,EAAchtD,UAAW50D,KAAK40D,YAErFgtD,CACT,CAEA/sE,cAAAA,GACE,MAAMgtE,EAAoBxD,EAAe,CAAEl4G,IAAKnG,KAAKmG,IAAKwH,IAAK,cAAeinD,UAAW50D,KAAK40D,YAC9F,GAAIitD,EACF,OAAOA,EAET,MAAMjtE,EAA0B,CAAC,EACjC,IACIQ,EADAtN,EAAM,EAEV,IAAK,IAAI5lB,EAAI,EAAGmiC,EAAMrkD,KAAKwnC,KAAKvnC,OAAQqkD,EAAMD,GAAO,EAAGC,EAAMpiC,EAAImiC,EAAMniC,EAAImiC,EAAKC,EAAMpiC,IAAMA,IAAK,CAChG,MAAMslB,GAAOguB,EAAAA,EAAAA,IAAsBx1D,KAAKwnC,KAAKtlB,IACvCulB,GAAaq6E,EAAAA,EAAAA,IAAmBt6E,GAClCC,IAAe2N,IACjBR,EAAYnN,GAAcK,EAC1BA,IACAsN,EAAU3N,EAEd,CAGA,IAAI+Z,EAAAA,EAAAA,OAAcxhD,KAAKktC,SAAU,CAE/B,MAAO60E,EAAMC,EAAIC,GAAM,IAAIjiH,KAAKktC,SAAW,QAAWltC,KAAKktC,SAAW,KAAO,IAAKltC,KAAKktC,SAAW,KAC5FA,EAAY,GAAE60E,KAAQ7hH,OAAO8hH,GAAIE,SAAS,EAAG,QAAQhiH,OAAO+hH,GAAIC,SAAS,EAAG,OAE9E9sE,IAAYlI,IACd0H,EAAY1H,GAAYpF,EAE5B,CAGA,OADAy2E,EAAe,CAAEp4G,IAAKnG,KAAKmG,IAAKwH,IAAK,cAAeC,MAAOgnC,EAAaggB,UAAW50D,KAAK40D,YACjFhgB,CACT,CAEA0kD,cAAAA,GACE,MAAMuoB,EAAoBxD,EAAe,CAAEl4G,IAAKnG,KAAKmG,IAAKwH,IAAK,cAAeinD,UAAW50D,KAAK40D,YAC9F,GAAIitD,EACF,OAAOA,EAET,MAAMjtE,EAAc50C,KAAK60C,iBACnBwkD,EAAcp2F,OAAOC,KAAK0xC,GAC7BlnC,KAAK+5B,IACJ,MAAOG,EAAMF,EAAOI,GAAOL,EAAW1N,MAAM,KAC5C,OAAO,IAAI9zB,KAAK6d,OAAOq5B,SAASvV,GAAO9jB,OAAOq5B,SAASzV,GAAS,EAAG5jB,OAAOq5B,SAASrV,GAAK,IAEzFl7B,MAAK,CAACC,EAAGC,IAAMD,EAAE2rF,UAAY1rF,EAAE0rF,YAGlC,OADA+lB,EAAe,CAAEp4G,IAAKnG,KAAKmG,IAAKwH,IAAK,cAAeC,MAAOyrF,EAAazkC,UAAW50D,KAAK40D,YACjFykC,CACT,CAEAioB,aAAAA,GACE,IAAKthH,KAAKg+E,YAAch+E,KAAK6S,aAAeC,EAAAA,GAAWC,MACrD,OAAOlT,MAAMk1B,KAAK,CAAE90B,OAAQD,KAAKwnC,KAAKvnC,SAAUyN,KAAI,CAACgkB,EAAGzvB,IAAUA,IAGpE,MAAMm6B,EAAW,GACXwY,EAAc50C,KAAK60C,iBAEzB,IAAK,IAAI3yB,EAAI,EAAGA,EAAIliB,KAAKwnC,KAAKvnC,OAAQiiB,GAAK,EAAG,CAC5C,MAAMslB,GAAOguB,EAAAA,EAAAA,IAAsBx1D,KAAKwnC,KAAKtlB,IAC7C,IAAI1D,EAAIa,KAAKg1B,MAAwB,GAAlB7M,EAAK1iC,WAAkB0iC,EAAKziC,aAAe/E,KAAKm0C,oBAAsBn0C,KAAKg0C,UAC9Fx1B,GAAKo2B,GAAYktE,EAAAA,EAAAA,IAAmBt6E,IAASxnC,KAAK01C,eAClDtZ,EAASla,GAAK1D,CAChB,CAEA,OAAO4d,CACT,CAEAjB,WAAAA,CAAYjZ,GACV,OAAKliB,KAAKg+E,YAAch+E,KAAK6S,aAAeC,EAAAA,GAAWC,MAGhD/S,KAAKo8B,SAASla,GAFZA,CAGX,CAEAwzB,YAAAA,GACE,GAAK11C,KAAKg+E,YAAch+E,KAAK6S,aAAeC,EAAAA,GAAWC,MAGvD,OAAOsM,KAAKg1B,KAAKr0C,KAAKg1C,kBAAoBh1C,KAAKg0C,SACjD,CAEA+E,sBAAAA,CAAuB92C,GACrB,GAAIjC,KAAKo8B,SACP,IAAK,IAAIla,EAAI,EAAGA,EAAIliB,KAAKo8B,SAASn8B,OAAQiiB,IACxC,GAAIliB,KAAKo8B,SAASla,KAAOjgB,EACvB,OAAOigB,EAIb,OAAQ,CACV,CAEA02B,iBAAAA,CAAkBjrC,EAAkB1L,GAClC,MAAMkgH,EAAYniH,KAAK+4C,uBAAuB92C,GAC9C,GAAIkgH,GAAa,EAAG,CAElB,OADkBniH,KAAK2N,GACNw0G,IAAc,IACjC,CACA,OAAO,IACT,CAEArS,cAAAA,GACE,MAAMsS,EAAoB/D,EAAe,CAAEl4G,IAAKnG,KAAKmG,IAAKwH,IAAK,cAAeinD,UAAW50D,KAAK40D,YAC9F,GAAIwtD,EACF,OAAOA,EAET,MAAMvS,EAAkC,CAAC,EACzC,IAAK,IAAI3tF,EAAI,EAAGA,EAAIliB,KAAKwnC,KAAKvnC,OAAQiiB,IACpC2tF,EAAY7vG,KAAKwnC,KAAKtlB,IAAMA,EAG9B,OADAq8F,EAAe,CAAEp4G,IAAKnG,KAAKmG,IAAKwH,IAAK,cAAeC,MAAOiiG,EAAaj7C,UAAW50D,KAAK40D,YACjFi7C,CACT,CAEAnsF,wBAAAA,CAAyBgQ,GACvB,OAAyB,IAArB1zB,KAAKwnC,KAAKvnC,OACL,GAEFoiH,EAAAA,EAAAA,IAA0B,CAC/B3uF,YACA/pB,MAAO3J,MAEX,CAEA4jB,yBAAAA,CAA0BphB,GACxB,OAAyB,IAArBxC,KAAKwnC,KAAKvnC,OACL,GAEF2jB,EAAAA,EAAAA,IAA0B,CAC/BphB,YACAmH,MAAO3J,MAEX,CAEA8/G,MAAAA,CAAOp7G,GACL,MAAMsvB,EAAqB,CACzB4X,OAAQ5rC,KAAK4rC,OACb/4B,WAAY7S,KAAK6S,WACjB4B,UAAWzU,KAAKyU,WAAa,KAC7Bu/C,YAAah0D,KAAKg0D,YAClBD,UAAW/zD,KAAK+zD,UAChBE,SAAUj0D,KAAKo/G,YACfG,QAASv/G,KAAKu/G,WACX76G,GAGCg5C,EAAU1pB,EAAOnhB,aAAeC,EAAAA,GAAWC,MAEjD,IAAIqQ,IADoBo+B,EAAAA,EAAAA,OAAyC,qBAA3B52C,SAASC,SAASy3G,MACzB5kE,EAAU,yBAA2B,GAMpE,OAJI8D,EAAAA,EAAAA,QACFp+B,EAASg0D,QAAQmrC,IAAIC,YAGf,GAAEp/F,oBAAyB2vE,EAAAA,UAAsB,CAAE0vB,IAAKx8G,KAAKC,SAAU8tB,KACjF,CAEAy+B,YAAAA,GACE,OAAOu3B,EAAAA,EAAAA,IAA0BhqF,KAAK6S,WAAY7S,KAAK4rC,OACzD,CAEA82E,SAAAA,GACE1iH,KAAKmQ,iBAAiBquG,EACxB,EAGFh0G,EAAM1D,YAEN,S,wDCj3BO,IAAKmsD,EAAc,SAAdA,GAAc,OAAdA,EAAc,kBAAdA,EAAc,sBAAdA,CAAc,MAKd0sD,EAAuB,SAAvBA,GAAuB,OAAvBA,EAAuB,UAAvBA,EAAuB,cAAvBA,CAAuB,K,uICL5B,MAAMgD,EAAqB,CAChC/6F,EAAG,EACHilB,EAAG,GACHgQ,IAAK,GACLuK,KAAM,I,eCkBD,MAAMw7D,EAA8Bl8G,IAAY,CACrDw0B,cAAe,CACb2Q,QAAS,CACPttB,OAAQ,IACF7X,IAAUgC,EAAAA,GAAMg3C,MAAQo5D,EAAAA,GAAkBC,EAAAA,GAC9C,CAACrwG,EAAAA,GAAMg3C,OAAQo5D,EAAAA,GACf,CAACpwG,EAAAA,GAAMyoF,MAAO4nB,EAAAA,IAEhB9pB,eAAgB3nC,EAAAA,GAChBu7D,4BAA6Bt7D,EAAAA,IAE/B1wB,OAAQ,CACN4d,SAAU,EACV2gB,UAAW,EACXh3C,OAAQ,GAEVkI,IAAK,CACH7e,OAAQm1C,EAAAA,GAAayK,GACrBpb,SAAUvV,EAAAA,GAAauN,WACvB2H,OAAQ,CACNE,OAAQ,CACNxlB,IAAK,GACLG,KAAM,GAERX,KAAM,CACJtW,KAAMu8B,EAAAA,GAAUqb,KAChBjxC,MAAO,SAGXU,KAAM,CACJi1B,OAAQ,CACNxlB,IAAK,GACLG,KAAM,GACNF,MAAO,IAETT,KAAM,CACJtW,KAAMu8B,EAAAA,GAAUnkB,IAGpB+xB,OAAQ,CACN7N,OAAQ,CACNxlB,IAAK,GACLC,MAAO,GAETT,KAAM,CACJtW,KAAMu8B,EAAAA,GAAUc,EAChB12B,MAAO,UAIboQ,MAAO,CACL/e,MAAOo1C,EAAAA,GAAaC,IACpBjM,KAAM,CACJ9E,OAAQ,CACNrlB,KAAM,GAERX,KAAM,CACJtW,KAAMu8B,EAAAA,GAAUnkB,EAChB1B,WAAY0rB,EAAAA,GAAYhqB,EACxBvB,QAAS,CACPC,IAAKqB,EAAAA,GAAQ+b,IACbld,OAAQmB,EAAAA,GAAQ+b,IAChBjd,KAAMkB,EAAAA,GAAQ+b,IACdnd,MAAOoB,EAAAA,GAAQ+b,QAKvBld,OAAQ,CACN/e,OAAQm1C,EAAAA,GAAa/P,EACrBZ,SAAUvV,EAAAA,GAAapQ,IACvBsqB,KAAM,CACJ9E,OAAQ,CACNxlB,IAAK,GAEPR,KAAM,CACJtW,KAAMu8B,EAAAA,GAAUnkB,KAItBnB,KAAM,CACJjf,MAAOo1C,EAAAA,GAAanQ,EACpB4B,aAAc,CACZE,aAAc,GACdzC,OAAQ,CACNxlB,KAAM,EACNG,KAAM,GAERX,KAAM,CACJtW,KAAMu8B,EAAAA,GAAUnkB,EAChB5B,OAAQ,SAGZvR,UAAW,CACTq3B,OAAQ,CACNxlB,IAAK,EACLG,KAAM,IAERX,KAAM,CACJtW,KAAMu8B,EAAAA,GAAUc,EAChB7mB,OAAQ,MACRD,OAAQ,qBAGZ+wB,WAAY,CACVhL,OAAQ,CACNrlB,KAAM,IAERX,KAAM,CACJtW,KAAMu8B,EAAAA,GAAUnkB,MAKxB0T,kBAAmB,CACjBuQ,QAAS,CACPpkC,OAAQ,IACR8W,OAAQ7X,IAAUgC,EAAAA,GAAMg3C,MAAQ05D,EAAAA,GAAsBC,EAAAA,IAExDxiF,OAAQ,CACN4d,SAAU,EACV2gB,UAAW,EACXh3C,OAAQ,GAEVkI,IAAK,CACH7e,OAAQm1C,EAAAA,GAAah1B,GAEvBrB,MAAO,CACL/e,MAAOo1C,EAAAA,GAAaC,IACpBjM,KAAM,CACJ9E,OAAQ,CACNrlB,KAAM,GAERX,KAAM,CACJtW,KAAMu8B,EAAAA,GAAUnkB,EAChB1B,WAAY0rB,EAAAA,GAAYhqB,EACxBvB,QAAS,CACPC,IAAKqB,EAAAA,GAAQ+b,IACbld,OAAQmB,EAAAA,GAAQ+b,IAChBjd,KAAMkB,EAAAA,GAAQ+b,IACdnd,MAAOoB,EAAAA,GAAQ+b,QAKvBld,OAAQ,CACN/e,OAAQm1C,EAAAA,GAAah1B,GAEvBnB,KAAM,CACJjf,MAAOo1C,EAAAA,GAAanQ,EACpB86D,eAAgB,CACdh5D,aAAc,EACdzC,OAAQ,CACNxlB,IAAK0lB,EAAAA,GAAOpkB,EACZnB,KAAMulB,EAAAA,GAAOa,GAEf/mB,KAAM,CACJtW,KAAMu8B,EAAAA,GAAUc,EAChB12B,MAAO,OACP+P,WAAY0rB,EAAAA,GAAY/E,MAKhC+V,wBAAyB,CACvB/W,QAAS,CACPttB,OAAQ7X,IAAUgC,EAAAA,GAAMg3C,MAAQo5D,EAAAA,GAAkBC,EAAAA,IAEpDliF,OAAQ,CACN4d,SAAU,EACV2gB,UAAW,EACXh3C,OAAQ,GAEVkI,IAAK,CACH7e,OAAQ,GAEV+e,OAAQ,CACN/e,OAAQ,IAEVgf,KAAM,CACJjf,MAAO,GAET+e,MAAO,CACL/e,MAAO,KAGXy8C,eAAgBu1D,EAAAA,GAChB70E,cAAe,CACbn1B,KAAM,EACN07E,UAAW,GACXhzE,MAAO,OACPwsB,YAAa,EACbE,YAAa,QAEftmB,gBAAiB,CACfC,OAAQ7X,IAAUgC,EAAAA,GAAMg3C,MAAQ45D,EAAAA,GAAoBC,EAAAA,GACpD5yF,YAAa,YACb9E,uBAAwB,eCzLrB,SAASs2D,EAAYnkD,EAAgB8uF,GAC1C,MAAM1yG,EAAW8W,IAAM,CAAC,EAAG47F,GAAiBF,EAA2B5uF,EAAOttB,QAoB9E,GAlBuB,MAAnBstB,EAAOygB,WACTrkC,EAAS8qB,cAAcrE,OAAO4d,SAAWzgB,EAAOygB,SAChDrkC,EAASkrB,kBAAkBzE,OAAO4d,SAAWzgB,EAAOygB,UAE9B,MAApBzgB,EAAOohC,YACThlD,EAAS8qB,cAAcrE,OAAOu+B,UAAYphC,EAAOohC,UACjDhlD,EAASkrB,kBAAkBzE,OAAOu+B,UAAYphC,EAAOohC,WAElC,MAAjBphC,EAAO5V,SACThO,EAAS8qB,cAAcrE,OAAOzY,OAAS4V,EAAO5V,OAC9ChO,EAASkrB,kBAAkBzE,OAAOzY,OAAS4V,EAAO5V,QAEhD4V,EAAO+uF,iBACT3yG,EAAS6zC,eAAiBjwB,EAAO+uF,gBAE/B/uF,EAAOkqB,eACT9tC,EAAS8qB,cAAcrE,OAAOqnB,aAAelqB,EAAOkqB,cAElDlqB,EAAOlwB,OAAQ,CACjB,MAAMk/G,EAAgB5yG,EAAS8qB,cAAc2Q,QAAQttB,OACrDnO,EAAS8qB,cAAc2Q,QAAQttB,OAAS,IACnCykG,EACH,CAACt6G,EAAAA,GAAMg3C,OAAQ,IACVsjE,EAAct6G,EAAAA,GAAMg3C,WACpBJ,EAAAA,EAAAA,GAAmB,CAAE54C,MAAOgC,EAAAA,GAAMg3C,MAAO57C,OAAQkwB,EAAOlwB,UAE7D,CAAC4E,EAAAA,GAAMyoF,MAAO,IACT6xB,EAAct6G,EAAAA,GAAMyoF,UACpB7xC,EAAAA,EAAAA,GAAmB,CAAE54C,MAAOgC,EAAAA,GAAMyoF,KAAMrtF,OAAQkwB,EAAOlwB,UAGhE,CAUA,GATIkwB,EAAO3iB,6BAA+Bq7B,EAAAA,GAA2ByS,WAAan0C,EAAAA,GAAM8+B,aACtF15B,EAAS8qB,cAAczU,KAAKjf,MAAQ,EACpC4I,EAAS8qB,cAAc5U,IAAIslB,OAAOE,OAAOrlB,KAAOrW,EAAS8qB,cAAczU,KAAK4nB,aAAavC,OAAOrlB,KAChGrW,EAASkrB,kBAAkB7U,KAAKjf,MAAQ,IAEtCklC,EAAAA,GAA2ByS,YAAcnrB,EAAO3iB,6BAA8B0uC,EAAAA,EAAAA,IAAiB/rB,MACjG5jB,EAAS8qB,cAAc5U,IAAI7e,OAAS,IAGlCusB,EAAO3iB,6BAA+Bq7B,EAAAA,GAA2BC,UAAW,CAC9E,MAAMqN,EAAoBhmB,EAAO9c,QAAQ/O,MAAKR,IAAA,IAAC,WAAEkL,GAAYlL,EAAA,OAAKkL,IAAeC,EAAAA,GAAWu5B,KAAK,IAC7F2N,IACF5pC,EAAS8qB,cAAc5U,IAAIzP,KAAKi1B,OAAOxlB,IAAM,EAC7ClW,EAAS8qB,cAAc5U,IAAIslB,OAAOE,OAAOxlB,IAAM,EAC/ClW,EAAS8qB,cAAc5U,IAAIslB,OAAO9lB,KAAO,CACvCtW,KAAMmzG,EAAmB9lE,IACzB1mC,MAAO,QAET/F,EAAS8qB,cAAczU,KAAKhS,UAAUq3B,OAAOxlB,IAAM,GACnDlW,EAAS8qB,cAAczU,KAAKhS,UAAUqR,KAAO,CAC3CtW,KAAMmzG,EAAmB/6F,EACzBzR,MAAO,QAGb,CAMA,YAJgC9N,IAA5B2rB,EAAOwY,mBACTp8B,EAASo8B,iBAAmBxY,EAAOwY,kBAG9Bp8B,CACT,CAEO,SAASC,EAAeujB,EAA2BltB,GACxD,MAAM0J,EAAW8W,IAAM,CAAC,EAAG0M,EAAaxjB,UAClC6yG,EAAUv8G,IAAUgC,EAAAA,GAAMg3C,MAKhC,OAJAtvC,EAASwyC,wBAAwB/W,QAAQttB,OAAS0kG,EAAU,IAAKnK,EAAAA,IAAoB,IAAKC,EAAAA,IAC1F3oG,EAASkrB,kBAAkBuQ,QAAQttB,OAAS0kG,EAAU,IAAK7J,EAAAA,IAAwB,IAAKC,EAAAA,IACxFjpG,EAASkO,gBAAgBC,OAAS0kG,EAAU,IAAK3J,EAAAA,IAAsB,IAAKC,EAAAA,IAErEnpG,CACT,CAEO,SAASiO,EAAuBuV,GACrC,MAAMxjB,EAAWwjB,EAAaxjB,SAE9B,MAAO,IACFA,EACH8qB,cAAe,IACV9qB,EAAS8qB,cACZ2Q,QAAS,IACJz7B,EAAS8qB,cAAc2Q,QAC1BttB,OAAQ,IACHnO,EAAS8qB,cAAc2Q,QAAQttB,UAC/BnO,EAAS8qB,cAAc2Q,QAAQttB,OAAOqV,EAAaltB,UAKhE,C,oGC5HO,MAAMswE,EAA4BrvE,IAMnC,IANoC,UACxCgrE,EAAS,iBACTtkE,GAID1G,EACgB0G,EAAiBoE,eACzBlK,SAASmB,GAAUA,EAAM8iD,cAAcmmB,GAAWjf,kBAAiB,EAGrE,SAASwvD,EAAmB96G,GAAkE,IAAjE,MAAEnG,EAAK,YAAE04G,GAAsDvyG,EACjG,OAAQnG,EAAQ,IAAM04G,GAAe,EAAI,EAC3C,CAEO,SAAS8C,EAAsB3vG,GAMnC,IANoC,cACrC0sG,EAAa,YACbG,GAID7sG,GACkB6sG,EAAc,IAAIH,GAAejnE,UAAYinE,GACrDjyG,SAAQ,CAACzG,EAASG,KACzB,MAAMk4G,EAAY+I,EAAoB,CAAEjhH,QAAO04G,gBAC3CR,IAAcr4G,EAAQ4pD,QACxB5pD,EAAQqO,iBAAiB,CAAEu7C,OAAQyuD,GACrC,GAEJ,CAEO,SAASI,EAAqB7qG,GAYlC,IAZmC,cACpC8qG,EAAa,WACbC,EAAU,UACVC,EAAS,UACTP,EAAS,YACTQ,GAAc,GAOfjrG,EACC,MAAMwzC,EAAQy3D,EAAc,IAAIH,GAAejnE,UAAYinE,EACrD9kG,EACqB,IAAzB8kG,EAAcv6G,QAAgBw6G,EAC1B,IAAIv3D,EAAOu3D,GACXv3D,EACGtrC,QAAO,CAAC8Z,EAAGzvB,IAAUihH,EAAoB,CAAEjhH,QAAO04G,kBAAmBD,IACrEj/D,SAAQ,CAACv5C,EAAID,IACZihH,EAAoB,CAAEjhH,QAAO04G,kBAAmBR,GAAaM,EAAa,CAACA,EAAYv4G,GAAMA,IAInGwT,EAASzV,OAASof,KAAKQ,IAAIs6F,IAAcM,GAC3C/kG,EAASnU,KAAKk5G,GAGhBgD,EAAuB,CAAEjD,cAAeG,EAAc,IAAIjlG,GAAU69B,UAAY79B,EAAUilG,eAC5F,CAEO,SAAS3wB,EAA0Bn3E,EAAwB+4B,GAChE,MAAQ,GACN,CAAC94B,EAAAA,GAAW47B,OAAQ57B,EAAAA,GAAWs2D,MAAOt2D,EAAAA,GAAWq2D,SAAS/uC,SAASvnB,KAAgB+4B,EAAOxR,SAAS,KAAO,IAAM,KAC/GwR,GACL,C,sFCvDO,MAAMu3E,UAAsB9d,EAAAA,EACjC9nF,YAAcmqC,EAAAA,GAAY07D,GAE1B7d,0BAAAA,GACE,MAAO,CACLiH,IAAK,GACL6W,OAAQ,GACRC,UAAW,GACXC,UAAW,GAEf,CAEA9d,SAAAA,CAAUC,GACR,MAAM,OAAE1vF,EAAM,WAAEwtG,GAAexjH,KAAK0E,SAC9B,MAAE02B,GAAUp7B,KAAK2J,MACvB3J,KAAK2lG,kBAAoB3lG,KAAKulG,6BAE9B,IAAI1iD,EAAM,EACV,IAAK,IAAI3gC,EAAI,EAAGA,EAAIlM,EAAQkM,IAC1B2gC,GAAOznB,EAAMlZ,GAEf,IAAK,IAAIA,EAAIlM,EAAQkM,EAAIkZ,EAAMn7B,OAAQiiB,IAAK,CAC1C2gC,EAAMA,EAAMznB,EAAMlZ,EAAIlM,GAAUolB,EAAMlZ,GACtCliB,KAAK4lG,iBAAiB4G,IAAItqF,GAAK2gC,EAAM7sC,EAErC,IAAIytG,EAAY,EAChB,IAAK,IAAI7gB,EAAI1gF,EAAIlM,EAAS,EAAG4sF,GAAK1gF,EAAG0gF,IACnC6gB,GAAapkG,KAAKojF,IAAIrnE,EAAMwnE,GAAK5iG,KAAK4lG,iBAAiB4G,IAAItqF,GAAI,GAOjE,GALAliB,KAAK4lG,iBAAiByd,OAAOnhG,GAAK7C,KAAKsP,KAAK80F,EAAYztG,GAExDhW,KAAK4lG,iBAAiB0d,UAAUphG,GAAKliB,KAAK4lG,iBAAiB4G,IAAItqF,GAAKliB,KAAK4lG,iBAAiByd,OAAOnhG,GAAKshG,EACtGxjH,KAAK4lG,iBAAiB2d,UAAUrhG,GAAKliB,KAAK4lG,iBAAiB4G,IAAItqF,GAAKliB,KAAK4lG,iBAAiByd,OAAOnhG,GAAKshG,GAEhD,IAAlD9d,IAAoB1lG,KAAK4lG,iBAAkB1jF,GAC7C,KAEJ,CACF,E,gDCjCF,MAAM7X,UAAuDM,EAAAA,EAC3D4S,YAAcmqC,EAAAA,GAAYr9C,QAC1BkT,aAAe,UAEf,yBAAOkU,CAAkB9pB,GAAkE,IAAjE,OAAEqO,GAA6DrO,EACvF,MAAO2+F,IAAaC,EAAAA,EAAAA,IAAkCvwF,GACtD,OAAOswF,CACT,CAKA,QAAI3wF,GACF,OAAQ3V,KAAKmD,YAA+BwS,IAC9C,CAEA,SAAI7G,GACF,OAAQ9O,KAAKmD,YAA+B2L,KAC9C,CAEA0/B,aAAAA,GACE,OAAOxuC,KAAK+C,MAAMmV,OAAQ+xB,EAAAA,EAAAA,IAAkBjqC,KAAK+C,MAAMmV,OAvB/B,SAwB1B,CAEAwrG,YAAAA,GACE,OAAO1jH,KAAKqe,yBAAyB4lC,eAAe,EAkBtD,CAEAvmC,aAAAA,CAAcgU,GACZ1xB,KAAK4E,KAAO5E,KAAK0B,MAAMgI,QAAQC,OACjC,CAEAwY,GAAM3D,GAAcxe,KAAK0B,MAAMyV,MAAMqH,EAAExe,KAAK4E,KAAKw3B,SAAS5d,IAE1DsrF,UAAAA,CAAWp4E,GACT,MAAMtoB,MAAM,YACd,CAEA2gG,qBAAAA,CAAqB3hG,GAA+E,IAA9E,IAAEuF,EAAG,YAAEq8F,GAAc,GAA8C5hG,EACvF,MAAM6rB,EAAQj0B,KAAK+zB,iBAAiB9S,OAAOpX,MAAKiE,IAAA,IAAC,KAAE1K,GAAwB0K,EAAA,OAAKH,IAAQvK,CAAI,IAC5F,QAAS6wB,IAASa,EAAAA,EAAAA,IAAUb,MAAY+1E,IAAeC,EAAAA,EAAAA,IAAkBh2E,EAAMrmB,OACjF,CAEAiqC,UAAAA,GACE,OAAO,CACT,CAEAvJ,uBAAAA,GACE,OAAOtuC,KAAK63C,YACd,CAEA9jB,cAAAA,GACE,MAAO,CACLvwB,MAAO,GACPyd,OAAQ,GACR0nF,oBAAqB,CAAC,EAE1B,CAEAz+F,QAAAA,GACE,MAAMpG,EAAmB,GACnB6/G,EAAoB,GAU1B,OARA3jH,KAAK+zB,iBAAiB9S,OAAO1Y,SAAS0rB,IACjB,UAAfA,EAAMte,KACR7R,EAAOvC,MAAKqiH,EAAAA,EAAAA,IAAiC3vF,EAAMrmB,MAAMrJ,aAEzDo/G,EAAQpiH,KAAK0yB,EAAMrmB,MAAMrJ,WAC3B,IAGK,CAAEoR,KAAM3V,KAAK2V,KAAMK,OAAQ2tG,EAAQ9/G,KAAK,KAAMqU,MAAOpU,EAAOD,KAAK,KAC1E,EAGF,UC1GMggH,EAAY,CAChB,CAACn7G,EAAAA,GAAMg3C,OAAQ,CACbokE,IAAK,UACLC,OAAQ,UACRC,OAAQ,WAEV,CAACt7G,EAAAA,GAAMyoF,MAAO,CACZ2yB,IAAK,UACLC,OAAQ,UACRC,OAAQ,YAINrS,EACI,GADJA,EAEQ,EAkBd,MAAMsS,UAAuB55G,EAC3BkT,YAAcmqC,EAAAA,GAAY07D,GAC1B7lG,aAAe,kBAEf,yBAAOkU,CAAkB9pB,GAAkE,IAAjE,OAAEqO,GAA6DrO,EACvF,MAAO2+F,EAAY,IAAKC,EAAAA,EAAAA,IAAkCvwF,GAC1D,OAAOswF,EAAY,CACrB,CAEAnnF,GAAAA,CAAIqS,GACFvnB,MAAMkV,IAAIqS,GACV,MAAM,OAAExb,GAAWwb,EACnB,GAAsB,iBAAXxb,EAAqB,CAC9B,MAAOswF,EAAWkd,GArBxB,SAAqBzR,GACnB,MAAM7pG,EAAS6pG,EAAUh4E,MAAM,KAI/B,MAAO,CAHQojB,SAASj1C,EAAO,KAAOypG,EACnB5tF,WAAW7b,EAAO,KAAOypG,EAG9C,CAesCK,CAAYh8F,GAC5ChW,KAAK+C,MAAMiT,OAASswF,EACpBtmG,KAAK+C,MAAMygH,WAAaA,EACxBxjH,KAAKuJ,QAAQ,SACf,CACA,OAAOvJ,IACT,CAEA0d,aAAAA,CAAcgB,GACZ,GAAiC,iBAAtB1e,KAAK+C,MAAMiT,OACpB,OAEF/L,MAAMyT,gBACN,MAAM,OAAEa,GAAWve,KAAKqe,yBAAyB6c,cAAc2Q,QACzDnlC,EAAQ1G,KAAK0B,MAAMgI,QAAQkqB,eAAeltB,OAC1C,WAAEukB,EAAU,MAAEzjB,GAAUxH,KAAK0B,MAAMgI,SAClC4c,EAAKE,GAAUxmB,KAAK0B,MAAMyV,MAAMsH,EAAE2E,SACnC8gG,EAAYlkH,KAAKoiB,GAAGkE,GACpB69F,EAAenkH,KAAKoiB,GAAGoE,IACvB,MAAE4U,GAAUp7B,KAAK4E,KACjBoR,EAASqJ,KAAKqF,IAAI1kB,KAAK+C,MAAMiT,OAAQolB,EAAMn7B,OAAS,GAE1D,IAAImkH,EACAC,EAAkB,EAGtB3lG,EAAQO,UAAU,GAAK,IACvBP,EAAQQ,YACRR,EAAQS,IAAI,YAAa,GACzBT,EAAQS,IAAI,cAAe0kG,EAAUn9G,GAAOs9G,QAE5C,MAAMM,EAAgB,IAAInB,EAAc,CACtCx5G,MAAO3J,KAAK4E,KACZF,QAAS,CACPsR,SACAwtG,WAAYxjH,KAAK+C,MAAMygH,cAkB3B,GAdAc,EAAc7e,WAAU,CAAAr9F,EAAU+5G,KAAc,IAAvB,IAAE3V,GAAKpkG,EAC9B,KAAIpI,KAAKmiB,GAAGggG,EAAY,GAAKl3F,EAAa,GAA1C,CAOA,QAJyB5iB,IAArB+7G,IAAgCA,EAAmBjC,GAEvDzjG,EAAQc,OAAOxf,KAAKmiB,GAAGggG,GAAY9iG,KAAK2E,MAAMhkB,KAAKoiB,GAAGoqF,EAAI2V,MAEtDniH,KAAKmiB,GAAGggG,EAAY,GAAKl3F,EAAazjB,EACxC,OAAO,EAET68G,EAAkBlC,CARlB,CAQ2B,SAGJ95G,IAArB+7G,EAAJ,CACA1lG,EAAQe,SACRf,EAAQS,IAAI,YAAaZ,EAAO26F,8BAGhCx6F,EAAQQ,YACRR,EAAQa,OAAOvf,KAAKmiB,GAAGiiG,GAAmBF,GAC1CxlG,EAAQS,IAAI,cAAe0kG,EAAUn9G,GAAOo9G,KAC5C,IAAK,IAAI5hG,EAAIkiG,EAAkBliG,GAAKmiG,EAAiBniG,IACnDxD,EAAQc,OAAOxf,KAAKmiB,GAAGD,GAAI7C,KAAK2E,MAAMhkB,KAAKoiB,GAAGkiG,EAAc1e,iBAAiB0d,UAAUphG,MAEzFxD,EAAQe,SACRf,EAAQc,OAAOxf,KAAKmiB,GAAGkiG,GAAkBH,GACzCxlG,EAAQkD,OAGRlD,EAAQQ,YACRR,EAAQa,OAAOvf,KAAKmiB,GAAGiiG,GAAmBD,GAC1CzlG,EAAQS,IAAI,cAAe0kG,EAAUn9G,GAAOq9G,QAC5C,IAAK,IAAI7hG,EAAIkiG,EAAkBliG,GAAKmiG,EAAiBniG,IACnDxD,EAAQc,OAAOxf,KAAKmiB,GAAGD,GAAI7C,KAAK2E,MAAMhkB,KAAKoiB,GAAGkiG,EAAc1e,iBAAiB2d,UAAUrhG,MAEzFxD,EAAQe,SACRf,EAAQc,OAAOxf,KAAKmiB,GAAGkiG,GAAkBF,GACzCzlG,EAAQkD,OACRlD,EAAQO,WAAW,IAAM,GAzBiB,CA0B5C,CAEA8U,cAAAA,GACE,MAAM/d,EAAS,CACbL,KAAM,SACN7G,MAAO,SACP1L,KAAM,SACNwK,MAAO5N,KAAK+C,MAAMiT,QAAU27F,EAC5BhsF,UAAU,EACVjB,IAAK,EACLG,IAAK,QAED2+F,EAAa,CACjB7tG,KAAM,SACN7G,MAAO,aACP1L,KAAM,aACNwK,MAAO5N,KAAK+C,MAAMygH,YAAc7R,EAChChsF,UAAU,EACVjB,IAAK,GACLG,IAAK,IACLkW,KAAM,IAEFwpF,EAAW,CACf5uG,KAAM,QACN7G,MAAO,YACP1L,KAAM,WACNwK,MAAO5N,KAAK+C,MAAMwhH,UAAYvkH,KAAK0jH,gBAE/Bc,EAAc,CAClB7uG,KAAM,QACN7G,MAAO,eACP1L,KAAM,cACNwK,MAAO5N,KAAK+C,MAAMyhH,aAAexkH,KAAK0jH,gBAGxC,MAAO,CACLlgH,MAAOxD,KAAK8O,MACZmS,OAAQ,CAACjL,EAAQwtG,EAAYe,EAAUC,GACvC7b,oBAAqB,CACnB3yF,OAAS,GAAEA,EAAOlH,wCAAwCkH,EAAO0O,WAAW1O,EAAO6O,MACnF2+F,WAAa,GAAEA,EAAW10G,kCAAkC00G,EAAW9+F,WAAW8+F,EAAW3+F,OAGnG,CAEAilF,UAAAA,CAAWn8F,GACT,OAAQA,GACN,IAAK,SACH,OAAO3N,KAAK+pG,sBAAsB,CAAEp8F,QACtC,IAAK,aACH,OAAO3N,KAAK+pG,sBAAsB,CAAEp8F,MAAKq8F,aAAa,IACxD,IAAK,WACL,IAAK,cAEH,OAAO,EACT,QACE,OAAO,EAEb,CAEAx7D,aAAAA,GACE,MAAM9nC,EAAQ1G,KAAK0B,MAAMgI,QAAQkqB,eAAeltB,MAChD,OAAO1G,KAAK+C,MAAMwhH,UAAYV,EAAUn9G,GAAOo9G,GACjD,CAEAv/G,QAAAA,GACE,MAAQ,MAAKvE,KAAK+C,MAAMiT,UAAUhW,KAAK+C,MAAMygH,YAC/C,EAGFS,EAAenkH,UAAUsC,SAAW,CAAEmiH,SAAU,UAAWC,YAAa,WAExE,U,0BC/LA,MAEM/Y,EACW,UADXA,EAES,YAFTA,EAGc,UAGpB,MAAMgZ,UAAyBp6G,EAC7BkT,YAAcmqC,EAAAA,GAAYg9D,IAC1BnnG,aAAe,oBAEf4B,GAAAA,CAAIqS,GACFvnB,MAAMkV,IAAIqS,GACV,MAAM,OAAExb,GAAWwb,EAKnB,MAJsB,iBAAXxb,IACThW,KAAK+C,MAAMiT,OAASmnC,SAASnnC,EAAQ,IACrChW,KAAKuJ,QAAQ,WAERvJ,IACT,CAEA0d,aAAAA,CAAcgB,GACZzU,MAAMyT,gBACN,MAAM,WAAEuN,EAAU,MAAEzjB,GAAUxH,KAAK0B,MAAMgI,SACnC,OAAEsM,GAAWhW,KAAK+C,MAClBugH,EAAsB,GACtBC,EAAsB,GACtBoB,EAAuB,GAC7B,IAAIP,GAAoB,EACpBC,EAAkB,EACtB,QAA+Bh8G,IAA3BrI,KAAK4E,KAAKw2B,MAAMn7B,OAApB,CAIAye,EAAQiR,OACRjR,EAAQO,UAAU,GAAK,IACvBP,EAAQS,IAAI,YAAa,GACzBT,EAAQS,IAAI,cAAessF,GAC3B/sF,EAAQS,IAAI,YAAassF,GAGzB/sF,EAAQQ,aACRs4B,EAAAA,EAAAA,IAAkB,CAChB7tC,MAAO3J,KAAK4E,KACZmC,UAAW/G,KAAK0B,MAChBupB,aACAzjB,QACAiwC,gBAAiBA,CAACv1B,EAAG1D,KACnB4lG,GAAyC,IAAtBA,EAA0BliG,EAAIkiG,EACjDd,EAAUphG,GAAK6nB,EAAAA,GAAMllB,IAAI7kB,KAAK4E,KAAKuX,KAAK9b,MAAMgf,KAAKwF,IAAI,EAAG3C,EAAIlM,GAASkM,EAAI,IAC3EqhG,EAAUrhG,GAAK6nB,EAAAA,GAAMrlB,IAAI1kB,KAAK4E,KAAKmkC,IAAI1oC,MAAMgf,KAAKwF,IAAI,EAAG3C,EAAIlM,GAASkM,EAAI,IAC1EyiG,EAAWziG,IAAMohG,EAAUphG,GAAKqhG,EAAUrhG,IAAM,EAEhDxD,EAAQc,OAAOhB,EAAGa,KAAK2E,MAAMhkB,KAAKoiB,GAAGkhG,EAAUphG,MAC/CmiG,EAAkBniG,CAAC,IAGvBxD,EAAQe,SACRf,EAAQc,OAAOxf,KAAKmiB,GAAGkiG,GAAkB3lG,EAAQsnB,OAAOv+B,QACxDiX,EAAQc,OAAOxf,KAAKmiB,GAAGiiG,GAAmB1lG,EAAQsnB,OAAOv+B,QACzDiX,EAAQysB,OAGRzsB,EAAQQ,YACR,IAAK,IAAIgD,EAAIkiG,EAAkBliG,GAAKmiG,EAAiBniG,IAAK,CACxD,MAAM1D,EAAIxe,KAAKmiB,GAAGD,GAClBxD,EAAQc,OAAOhB,EAAGa,KAAK2E,MAAMhkB,KAAKoiB,GAAGmhG,EAAUrhG,KACjD,CACAxD,EAAQe,SACRf,EAAQc,OAAOxf,KAAKmiB,GAAGkiG,GAAkB,GACzC3lG,EAAQc,OAAO,EAAG,GAClBd,EAAQkD,OAGRlD,EAAQS,IAAI,cAAessF,GAC3B/sF,EAAQQ,YACR,IAAK,IAAIgD,EAAIkiG,EAAkBliG,GAAKmiG,EAAiBniG,IAAK,CACxD,MAAM1D,EAAIxe,KAAKmiB,GAAGD,GAClBxD,EAAQc,OAAOhB,EAAGa,KAAK2E,MAAMhkB,KAAKoiB,GAAGuiG,EAAWziG,KAClD,CACAxD,EAAQe,SACRf,EAAQmR,SAjDR,CAkDF,CAEAkE,cAAAA,GACE,MAAM/d,EAAS,CACbL,KAAM,SACN7G,MAAO,SACP1L,KAAM,SACNwK,MAAO5N,KAAK+C,MAAMiT,QA1FD,GA2FjB2P,UAAU,EACVjB,IAAK,EACLG,IAAK,QAGD+/F,EAAc,CAClBjvG,KAAM,QACN7G,MAAO,wBACP1L,KAAM,cACNwK,MAAO5N,KAAK+C,MAAM8hH,oBAAsB7kH,KAAK0jH,gBAEzCoB,EAAY,CAChBnvG,KAAM,QACN7G,MAAO,sBACP1L,KAAM,YACNwK,MAAO5N,KAAK+C,MAAMgiH,kBAAoB/kH,KAAK0jH,gBAEvCsB,EAAkB,CACtBrvG,KAAM,QACN7G,MAAO,oBACP1L,KAAM,kBACNwK,MAAO5N,KAAK+C,MAAMiiH,iBAAmBhlH,KAAK0jH,gBAG5C,MAAO,CACLlgH,MAAOxD,KAAK8O,MACZmS,OAAQ,CAACjL,EAAQgvG,EAAiBJ,EAAaE,GAC/Cnc,oBAAqB,CACnB3yF,OAAS,GAAEA,EAAOlH,wCAAwCkH,EAAO0O,WAAW1O,EAAO6O,OAGzF,CAEAilF,UAAAA,CAAWn8F,GACT,OAAQA,GACN,IAAK,SACH,OAAO3N,KAAK+pG,sBAAsB,CAAEp8F,QACtC,IAAK,kBACL,IAAK,cACL,IAAK,YACH,OAAO,EACT,QACE,OAAO,EAEb,CAEA6gC,aAAAA,GACE,OAAOxuC,KAAK+C,MAAMiiH,eACpB,CAEAzgH,QAAAA,GACE,MAAQ,YAAWvE,KAAK+C,MAAMiT,QAChC,EAGFyuG,EAAiB3kH,UAAUsC,SAAW,CACpC4iH,gBAAiBvZ,EACjBoZ,mBAAoBpZ,EACpBsZ,iBAAkBtZ,GAGpB,U,eC1JA,MAAMwZ,UAAY56G,EAChBkT,YAAcmqC,EAAAA,GAAY49C,IAC1B/nF,aAAe,6BAEf4B,GAAAA,CAAIqS,GACFvnB,MAAMkV,IAAIqS,GACV,MAAM,OAAExb,GAAWwb,EAKnB,MAJsB,iBAAXxb,IACThW,KAAK+C,MAAMiT,OAASmnC,SAASnnC,EAAQ,IACrChW,KAAKuJ,QAAQ,WAERvJ,IACT,CAEA0d,aAAAA,CAAcgB,GACZzU,MAAMyT,gBACN,MAAM,WAAEuN,EAAU,MAAEzjB,GAAUxH,KAAK0B,MAAMgI,QAEzCgV,EAAQO,UAAU,GAAK,IACvBP,EAAQQ,YACRR,EAAQS,IAAI,YAAa,GACzBT,EAAQS,IAAI,cAAenf,KAAK+C,MAAMmV,OACf,IAAIktF,EAAAA,EAAe,CACxCz7F,MAAO3J,KAAK4E,KACZF,QAAS,CACPsR,OAAQhW,KAAK+C,MAAMiT,UAGRyvF,WAAU,CAAA99F,EAAUw6G,KAAc,IAAvB,IAAE3c,GAAK79F,EAC/B,MAAM6W,EAAIxe,KAAKmiB,GAAGggG,GAClB,KAAIniH,KAAKmiB,GAAGggG,EAAY,GAAKl3F,EAAa,GAG1C,QAAIjrB,KAAKmiB,GAAGggG,EAAY,GAAKl3F,EAAazjB,SAG1CkX,EAAQc,OAAOhB,EAAGa,KAAK2E,MAAMhkB,KAAKoiB,GAAGojF,EAAI2c,KAAa,IAExDzjG,EAAQe,SACRf,EAAQO,WAAW,IAAM,GAC3B,CAEA8U,cAAAA,GACE,MAAM/d,EAAS,CACbL,KAAM,SACN7G,MAAO,SACP1L,KAAM,SACNwK,MAAO5N,KAAK+C,MAAMiT,QAAU,EAC5B2P,UAAU,EACVjB,IAAK,EACLG,IAAK,QAED3M,EAAQ,CACZvC,KAAM,QACN7G,MAAO,QACP1L,KAAM,QACNwK,MAAO5N,KAAK+C,MAAMmV,OAASlY,KAAK0jH,gBAGlC,MAAO,CACLlgH,MAAOxD,KAAK8O,MACZmS,OAAQ,CAACjL,EAAQkC,GACjBywF,oBAAqB,CACnB3yF,OAAS,GAAEA,EAAOlH,wCAAwCkH,EAAO0O,WAAW1O,EAAO6O,OAGzF,CAEAilF,UAAAA,CAAWn8F,GACT,OAAQA,GACN,IAAK,SACH,OAAO3N,KAAK+pG,sBAAsB,CAAEp8F,QACtC,IAAK,QACH,QAAS3N,KAAK+C,MAAM4K,GACtB,QACE,OAAO,EAEb,CAEApJ,QAAAA,GACE,MAAQ,OAAMvE,KAAK+C,MAAMiT,QAC3B,EAGFivG,EAAInlH,UAAUsC,SAAW,CAAE8V,MAAO,WAElC,UC7FA,MAAMgtG,UAAaD,EACjB1nG,YAAcmqC,EAAAA,GAAYy9D,KAG5BD,EAAKplH,UAAUsC,SAAW,CAAE8V,MAAO,WAEnC,U,eCEA,MAAMktG,UAAgB/6G,EACpBkT,YAAcmqC,EAAAA,GAAY29D,KAC1B9nG,aAAe,WAEfpa,WAAAA,CAAY+E,EAAwBxG,GAClCuI,MAAM/B,EAAQxG,GACd1B,KAAK0d,cAAgB1d,KAAK0d,cAAc/c,KAAKX,KAC/C,CAEAmf,GAAAA,CAAIqS,GACFvnB,MAAMkV,IAAIqS,GACV,MAAM,OAAExb,GAAWwb,EAKnB,MAJsB,iBAAXxb,IACThW,KAAK+C,MAAMiT,OAASmnC,SAASnnC,EAAQ,IACrChW,KAAKuJ,QAAQ,WAERvJ,IACT,CAEA0d,aAAAA,CAAcgB,GACZzU,MAAMyT,gBACN,MAAMtT,EAAapK,KAAK0B,MAAMgI,SACxB,cAAEwxB,GAAkBl7B,KAAKqe,0BACzB,OAAEE,GAAW2c,EAAc2Q,SAC3B,WAAE5gB,EAAU,MAAEzjB,EAAK,WAAEmtC,GAAevqC,EAKpC8a,GAJWwvB,EAAAA,EAAAA,IAAsB,CACrCC,aACA3jC,YAAa5G,EAAWwpB,iBAEG,EACvB5d,EAASqJ,KAAKqF,IAAI1kB,KAAK+C,MAAMiT,OAAQhW,KAAK4E,KAAKw2B,MAAMn7B,OAAS,GACpE,IAAImkH,EACAC,EAAkB,EACtB3lG,EAAQO,UAAU,GAAK,IACvBP,EAAQS,IAAI,YAAaZ,EAAO26F,8BAChCx6F,EAAQQ,YACRR,EAAQS,IAAI,cAAenf,KAAK+C,MAAMuiH,WACtC,IAAIC,GAAY,EAChB,IAAK,IAAIrjG,EAAI,EAAGA,EAAIliB,KAAK4E,KAAKw2B,MAAMn7B,OAAQiiB,IAAK,CAC/C,IAAI+wF,EAAcjzG,KAAK4E,KAAKuX,KAAK+F,GACjC,IAAK,IAAI0gF,EAAI1gF,EAAIlM,EAAS,EAAG4sF,GAAK1gF,EAAG0gF,IAC/B5iG,KAAK4E,KAAKuX,KAAKymF,GAAKqQ,IACtBA,EAAcjzG,KAAK4E,KAAKuX,KAAKymF,IAIjC,MAAMpkF,EAAIxe,KAAKmiB,GAAGD,GAClB,GAAIliB,KAAKmiB,GAAGD,EAAI,GAAK+I,GAAc,GAAI,CACrCs6F,EAAWtS,EACX,QACF,CAEA,QADyB5qG,IAArB+7G,IAAgCA,EAAmBliG,GACnDliB,KAAKmiB,GAAGD,EAAI,GAAK+I,EAAazjB,EAChC,MAGWxH,KAAK4E,KAAKw3B,SAASla,GAAKliB,KAAK4E,KAAKw3B,SAASioF,GAC7C,GAAKkB,IAAatS,GAAesS,EAAW,GACrD7mG,EAAQc,OAAOH,KAAK2E,MAAMxF,EAAI0G,GAAY7F,KAAK2E,MAAMhkB,KAAKoiB,GAAGmjG,KAE/D7mG,EAAQc,OAAOH,KAAK2E,MAAMxF,EAAI0G,GAAY7F,KAAK2E,MAAMhkB,KAAKoiB,GAAG6wF,KAC7Dv0F,EAAQc,OAAOH,KAAK2E,MAAMxF,EAAI0G,GAAY7F,KAAK2E,MAAMhkB,KAAKoiB,GAAG6wF,KAE7DsS,EAAWtS,EACXoR,EAAkBniG,CACpB,CAEA,GADAxD,EAAQe,cACiBpX,IAArB+7G,EAAgC,OAGpC1lG,EAAQc,OAAOxf,KAAKmiB,GAAGkiG,GAAmBn/F,EAAW,GACrDxG,EAAQc,OAAOxf,KAAKmiB,GAAGiiG,GAAoBl/F,EAAW,GACtDxG,EAAQkD,OAERlD,EAAQQ,YACRR,EAAQS,IAAI,cAAenf,KAAK+C,MAAMyiH,UACtC,IAAIC,GAAW,EACXC,EAAUtB,EACd,IAAK,IAAIliG,EAAIkiG,EAAkBliG,GAAKmiG,EAAiBniG,IAAK,CACxD,IAAIgxF,EAAYlzG,KAAK4E,KAAKmkC,IAAI7mB,GAC9B,IAAK,IAAI0gF,EAAI1gF,EAAIlM,EAAS,EAAG4sF,GAAK1gF,EAAG0gF,IAC/B5iG,KAAK4E,KAAKmkC,IAAI65D,GAAKsQ,IACrBA,EAAYlzG,KAAK4E,KAAKmkC,IAAI65D,IAI9B,MAAMpkF,EAAIxe,KAAKmiB,GAAGD,GACLliB,KAAK4E,KAAKw3B,SAASla,GAAKliB,KAAK4E,KAAKw3B,SAASspF,GAC7C,GAAKD,IAAYvS,GAAauS,EAAU,GACjD/mG,EAAQc,OAAOH,KAAK2E,MAAMxF,EAAI0G,GAAY7F,KAAK2E,MAAMhkB,KAAKoiB,GAAGqjG,KAE/D/mG,EAAQc,OAAOH,KAAK2E,MAAMxF,EAAI0G,GAAY7F,KAAK2E,MAAMhkB,KAAKoiB,GAAG8wF,KAC7Dx0F,EAAQc,OAAOH,KAAK2E,MAAMxF,EAAI0G,GAAY7F,KAAK2E,MAAMhkB,KAAKoiB,GAAG8wF,KAE7DuS,EAAUvS,EACVwS,EAAUxjG,CACZ,CACAxD,EAAQe,SACRf,EAAQO,WAAW,IAAM,IAGzBP,EAAQc,OAAOxf,KAAKmiB,GAAGkiG,GAAkB3lG,EAAQsnB,OAAOv+B,QACxDiX,EAAQc,OAAOxf,KAAKmiB,GAAGiiG,GAAoBl/F,EAAWxG,EAAQsnB,OAAOv+B,QACrEiX,EAAQkD,MACV,CAEAmS,cAAAA,GACE,MAAM/d,EAAS,CACbL,KAAM,SACN7G,MAAO,SACP1L,KAAM,SACNwK,MAAO5N,KAAK+C,MAAMiT,QAAU,GAC5B2P,UAAU,EACVjB,IAAK,EACLG,IAAK,QAEDygG,EAAY,CAChB3vG,KAAM,QACN7G,MAAO,aACP1L,KAAM,YACNwK,MAAO5N,KAAK+C,MAAMuiH,WAAatlH,KAAK0jH,gBAEhC8B,EAAW,CACf7vG,KAAM,QACN7G,MAAO,YACP1L,KAAM,WACNwK,MAAO5N,KAAK+C,MAAMyiH,UAAYxlH,KAAK0jH,gBAGrC,MAAO,CACLlgH,MAAOxD,KAAK8O,MACZmS,OAAQ,CAACjL,EAAQsvG,EAAWE,GAC5B7c,oBAAqB,CACnB3yF,OAAS,GAAEA,EAAOlH,wCAAwCkH,EAAO0O,WAAW1O,EAAO6O,OAGzF,CAEAilF,UAAAA,CAAWn8F,GACT,OAAQA,GACN,IAAK,SACH,OAAO3N,KAAK+pG,sBAAsB,CAAEp8F,QACtC,IAAK,YACL,IAAK,WAEH,OAAO,EACT,QACE,OAAO,EAEb,CAEA6gC,aAAAA,GACE,OAAOxuC,KAAK+C,MAAMuiH,SACpB,CAEA/gH,QAAAA,GACE,MAAQ,QAAOvE,KAAK+C,MAAMiT,QAC5B,EAGFovG,EAAQtlH,UAAUsC,SAAW,CAC3BojH,SAAU,UACVF,UAAW,WAGb,UCtKA,MAAM3qF,UAAuBtwB,EAC3BkT,YAAcmqC,EAAAA,GAAYi+D,MAC1BpoG,aAAe,kBAEf,yBAAOkU,GACL,OAAO,CACT,CAEAtS,GAAAA,CAAIqS,GAMF,OALAvnB,MAAMkV,IAAIqS,GACuB,iBAAtBxxB,KAAK+C,MAAMiT,aAA4C3N,IAArBrI,KAAK+C,MAAMk1C,QACtDj4C,KAAK+C,MAAMk1C,MAAQl0B,WAAW/jB,KAAK+C,MAAMiT,QACzChW,KAAKuJ,QAAQ,WAERvJ,IACT,CAEA0d,aAAAA,CAAcgB,GACZzU,MAAMyT,gBACN,MAAMe,EAAIY,KAAK2E,MAAMhkB,KAAKoiB,GAAGpiB,KAAK+C,MAAMk1C,QACxCv5B,EAAQS,IAAI,cAAenf,KAAK+C,MAAMmV,OACtCwG,EAAQO,UAAU,EAAG,IACrBP,EAAQQ,YACRR,EAAQa,QAAQvf,KAAK0B,MAAMgI,QAAQuhB,WAAYxM,GAC/CC,EAAQc,QAAQxf,KAAK0B,MAAMgI,QAAQuhB,WAAajrB,KAAK0B,MAAMgI,QAAQlC,MAAOiX,GAC1EC,EAAQe,SACRf,EAAQO,UAAU,GAAI,GACxB,CAEA8U,cAAAA,GACE,MAAMkkB,EAAQ,CACZtiC,KAAM,SACN7G,MAAO,QACP1L,KAAM,QACNwK,MAAO5N,KAAK+C,MAAMk1C,OAASj4C,KAAK0B,OAAOyV,OAAOsH,GAAG2E,SAASrW,QAAO,CAACF,EAAWC,IAAcD,EAAIC,GAAG,GAAK,EACvG6Y,UAAU,EACVoV,KAAM,IAEF7iB,EAAQ,CACZvC,KAAM,QACN7G,MAAO,QACP1L,KAAM,QACNwK,MAAO5N,KAAK+C,MAAMmV,OAASlY,KAAK0jH,gBAGlC,MAAO,CACLlgH,MAAOxD,KAAK8O,MACZmS,OAAQ,CAACg3B,EAAO//B,GAChBywF,oBAAqB,CACnB1wD,MAAQ,GAAEA,EAAMnpC,wBAGtB,CAEAg7F,UAAAA,CAAWn8F,GACT,OAAQA,GACN,IAAK,QACH,OAAOi4G,EAAAA,EAAAA,IAAgB5lH,KAAK+C,MAAM4K,IACpC,IAAK,QACH,QAAS3N,KAAK+C,MAAM4K,GACtB,QACE,OAAO,EAEb,CAEApJ,QAAAA,GACE,MAAQ,MAAKvE,KAAK+C,MAAMk1C,OAC1B,EAGFtd,EAAe76B,UAAUsC,SAAW,CAAE8V,MAAO,WAE7C,UC9DMuzF,EACG,CACLoa,OAAQ,UACRC,KAAM,aAHJra,EAKG,CACLoa,OAAQ,UACRC,KAAM,aAPJra,EASY,UATZA,EAUM,UAVNA,EAWS,UAGTkG,EAAqB,CACzBoU,WAAY,EACZC,KAAM,GACNC,MAAO,IAGT,SAASjU,EAAYh8F,GACnB,MAAOkwG,EAAavU,EAAmBoU,WAAYj3E,EAAO6iE,EAAmBqU,KAAMG,EAAQxU,EAAmBsU,QAC5G1f,EAAAA,EAAAA,IAAkCvwF,GACpC,MAAO,CAACkwG,EAAYp3E,EAAMq3E,EAC5B,CAEA,MAAMC,UAAsB/7G,EAC1BkT,YAAcmqC,EAAAA,GAAY2+D,GAC1B9oG,aAAe,iBACfA,mBAAoB,EAEpB,yBAAOkU,CAAkB9pB,GAAkE,IAAjE,OAAEqO,GAA6DrO,EACvF,OAAO0X,KAAKwF,OAAOmtF,EAAYh8F,GACjC,CAEA,cAAIswG,GACF,OAAQtmH,KAAKmD,YAAqCmjH,UACpD,CAEAnnG,GAAAA,CAAIqS,GAEF,GADAvnB,MAAMkV,IAAIqS,GAEqB,iBAAtBxxB,KAAK+C,MAAMiT,cACS3N,IAA1BrI,KAAK+C,MAAMmjH,iBAAgD79G,IAApBrI,KAAK+C,MAAM+rC,WAA2CzmC,IAArBrI,KAAK+C,MAAMojH,OACpF,CACA,MAAOD,EAAYp3E,EAAMq3E,GAASnU,EAAYhyG,KAAK+C,MAAMiT,QACzDhW,KAAK+C,MAAMmjH,WAAaA,EACxBlmH,KAAK+C,MAAM+rC,KAAOA,EAClB9uC,KAAK+C,MAAMojH,MAAQA,CACrB,CAEA,OADAnmH,KAAKuJ,QAAQ,UACNvJ,IACT,CAEAmiB,GAAM3D,IACJ,MAAMukC,EAAY/iD,KAAK4E,KAAKw2B,MAAMn7B,OAAS,EACrCsmH,EAAavmH,KAAK4E,KAAKw3B,SAAS2mB,GAAavkC,EAAIukC,EAEvD,OAAO/iD,KAAK0B,MAAMyV,MAAMqH,EAAExe,KAAK4E,KAAKw3B,SAAS5d,IAAM+nG,EAAW,EAGhE7oG,aAAAA,CAAcgB,GACZzU,MAAMyT,gBACN,MAAM,WAAEuN,EAAU,MAAEzjB,GAAUxH,KAAK0B,MAAMgI,SACnC,KAAEyS,EAAI,IAAE4sB,EAAG,MAAE3N,GAAUp7B,KAAK4E,MAE5B,WACJshH,EAAU,KACVp3E,EAAI,MACJq3E,EAAK,eACLK,EAAc,iBACdC,EAAgB,eAChBC,EAAc,iBACdC,EAAgB,cAChBC,EAAa,oBACbC,EAAmB,iBACnBC,GACE9mH,KAAK+C,MAEHgkH,EAA2B,GAC3BjV,EAAqB,GACrBkV,EAAwB,GACxBC,EAAwB,GACxBC,EAAuBhB,EAAa,EACpCiB,EAAiBr4E,EAAO,EACxBs4E,EAAajB,EAAQ,EACrB3gF,EAAQnmB,KAAKqF,IAAIyiG,EAAgBD,GACjC7iE,EAAMjpB,EAAMn7B,OAASknH,EAE3B,GAA+B,IAA3BnnH,KAAK4E,KAAKw2B,MAAMn7B,OAAc,OAGlC,IAAK,IAAIiiB,EAAIsjB,EAAOtjB,EAAImiC,EAAKniC,IAAK,CAChC,GAAIA,GAAKglG,GAAwBhlG,EAAIkZ,EAAMn7B,OAAQ,CACjD,MAAMonH,EAAYhoG,KAAKwF,OAAO1I,EAAK9b,MAAM6hB,EAAIglG,EAAsBhlG,EAAI,IACjEolG,EAAWjoG,KAAKqF,OAAOqkB,EAAI1oC,MAAM6hB,EAAIglG,EAAsBhlG,EAAI,IACrE6kG,EAAe7kG,IAAMmlG,EAAYC,GAAY,CAC/C,CAEA,GAAIplG,GAAKilG,GAAkBjlG,EAAIkZ,EAAMn7B,OAAQ,CAC3C,MAAMonH,EAAYhoG,KAAKwF,OAAO1I,EAAK9b,MAAM6hB,EAAIilG,EAAgBjlG,EAAI,IAC3DolG,EAAWjoG,KAAKqF,OAAOqkB,EAAI1oC,MAAM6hB,EAAIilG,EAAgBjlG,EAAI,IAC/D4vF,EAAS5vF,IAAMmlG,EAAYC,GAAY,EAEvCN,EAAY9kG,EAAIilG,IAAmBrV,EAAS5vF,GAAK6kG,EAAe7kG,IAAM,CACxE,CAEA,GAAIA,GAAKklG,EAAY,CACnB,MAAMC,EAAYhoG,KAAKwF,OAAO1I,EAAK9b,MAAM6hB,EAAIklG,EAAYllG,EAAI,IACvDolG,EAAWjoG,KAAKqF,OAAOqkB,EAAI1oC,MAAM6hB,EAAIklG,EAAYllG,EAAI,IAC3D+kG,EAAY/kG,EAAIilG,IAAmBE,EAAYC,GAAY,CAC7D,CACF,CAEA,IAAIC,EAAa,EACbC,EAAa,EACjB,MAAMC,EAAiBznH,KAAKmiB,GAAGilG,EAAaD,GAEtCnf,EAAyB,CAC7B0f,cAAeP,EACfl8F,aACAlkB,UAAW/G,KAAK0B,MAChBiI,MAAO3J,KAAK4E,KACZ4C,QACAmgH,WAAY3nH,KAAKmiB,IAGnBzD,EAAQS,IAAI,YAAa,GACzBT,EAAQO,UAAU,GAAK,IACvBP,EAAQiR,OAGRjR,EAAQS,IAAI,cAAesnG,GAC3B/nG,EAAQS,IAAI,YAAaqnG,GACzB9nG,EAAQQ,aACRs4B,EAAAA,EAAAA,IAAkB,IACbwwD,EACHvwD,gBAAiBA,CAACv1B,EAAG1D,KACnBE,EAAQc,OAAOhB,EAAGa,KAAK2E,MAAMhkB,KAAKoiB,GAAG4kG,EAAY9kG,MACjDqlG,EAAa/oG,CAAC,IAGlBE,EAAQe,SAERf,EAAQc,OAAO+nG,EAAY7oG,EAAQsnB,OAAOv+B,QAC1CiX,EAAQc,OAAOioG,EAAgB/oG,EAAQsnB,OAAOv+B,QAC9CiX,EAAQysB,OAERzsB,EAAQQ,aACRs4B,EAAAA,EAAAA,IAAkB,IACbwwD,EACHvwD,gBAAiBA,CAACv1B,EAAG1D,KACf0D,GAAK8kG,EAAY/mH,SACrBye,EAAQc,OAAOhB,EAAGa,KAAK2E,MAAMhkB,KAAKoiB,GAAG6kG,EAAY/kG,MACjDslG,EAAahpG,EAAC,IAGlBE,EAAQc,OAAOgoG,EAAY,GAC3B9oG,EAAQc,OAAOioG,EAAgB,GAC/B/oG,EAAQkD,OACRlD,EAAQmR,UAIRnR,EAAQiR,OACRjR,EAAQS,IAAI,cAAewnG,GAC3BjoG,EAAQS,IAAI,YAAaunG,GACzBhoG,EAAQQ,aACRs4B,EAAAA,EAAAA,IAAkB,IACbwwD,EACHvwD,gBAAiBA,CAACv1B,EAAG1D,KACf0D,GAAK8kG,EAAY/mH,QACrBye,EAAQc,OAAOhB,EAAGa,KAAK2E,MAAMhkB,KAAKoiB,GAAG6kG,EAAY/kG,KAAK,IAG1DxD,EAAQe,SAERf,EAAQc,OAAOgoG,EAAY9oG,EAAQsnB,OAAOv+B,QAC1CiX,EAAQc,OAAOioG,EAAgB/oG,EAAQsnB,OAAOv+B,QAC9CiX,EAAQysB,OAERzsB,EAAQQ,aACRs4B,EAAAA,EAAAA,IAAkB,IACbwwD,EACHvwD,gBAAiBA,CAACv1B,EAAG1D,KACnBE,EAAQc,OAAOhB,EAAGa,KAAK2E,MAAMhkB,KAAKoiB,GAAG4kG,EAAY9kG,KAAK,IAG1DxD,EAAQc,OAAOgoG,EAAY,GAC3B9oG,EAAQc,OAAOioG,EAAgB,GAC/B/oG,EAAQkD,OACRlD,EAAQmR,UACRnR,EAAQO,WAAW,IAAM,IAErBjf,KAAKsmH,aAEP5nG,EAAQS,IAAI,cAAe0nG,GAC3BnoG,EAAQO,UAAU,GAAK,IACvBP,EAAQQ,aACRs4B,EAAAA,EAAAA,IAAkB,IACbwwD,EACHvwD,gBAAiBA,CAACv1B,EAAG1D,KACnBE,EAAQc,OAAOhB,EAAGa,KAAK2E,MAAMhkB,KAAKoiB,GAAG2kG,EAAe7kG,KAAK,IAG7DxD,EAAQe,SAGRf,EAAQS,IAAI,cAAeynG,GAC3BloG,EAAQQ,aACRs4B,EAAAA,EAAAA,IAAkB,IACbwwD,EACHvwD,gBAAiBA,CAACv1B,EAAG1D,KACnBE,EAAQc,OAAOhB,EAAGa,KAAK2E,MAAMhkB,KAAKoiB,GAAG0vF,EAAS5vF,KAAK,IAGvDxD,EAAQe,SAGRf,EAAQS,IAAI,cAAe2nG,GAC3BpoG,EAAQQ,aACRs4B,EAAAA,EAAAA,IAAkB,IACbwwD,EACH2f,WAAanpG,GAAcxe,KAAKmiB,GAAG3D,EAAIswB,GACvC2I,gBAAiBA,CAACv1B,EAAG1D,KACnBE,EAAQc,OAAOhB,EAAGa,KAAK2E,MAAMhkB,KAAKoiB,GAAGpiB,KAAK4E,KAAKw2B,MAAMlZ,KAAK,IAG9DxD,EAAQe,SACRf,EAAQO,WAAW,IAAM,IAE7B,CAEA8U,cAAAA,GACE,MAAMmyF,EAAa,CACjBvwG,KAAM,SACN7G,MAAO,kBACP1L,KAAM,aACNwK,MAAO5N,KAAK+C,MAAMmjH,YAAcvU,EAAmBoU,WACnDpgG,UAAU,EACVjB,IAAK,EACLG,IAAK,QAEDiqB,EAAO,CACXn5B,KAAM,SACN7G,MAAO,mBACP1L,KAAM,OACNwK,MAAO5N,KAAK+C,MAAM+rC,MAAQ6iE,EAAmBqU,KAC7CrgG,UAAU,EACVjB,IAAK,EACLG,IAAK,QAEDshG,EAAQ,CACZxwG,KAAM,SACN7G,MAAO,wBACP1L,KAAM,QACNwK,MAAO5N,KAAK+C,MAAMojH,OAASxU,EAAmBsU,MAC9CtgG,UAAU,EACVjB,IAAK,EACLG,IAAK,QAGD4hG,EAAmB,CACvB9wG,KAAM,QACN7G,MAAO,sBACP1L,KAAM,mBACNwK,MAAO5N,KAAK+C,MAAM0jH,kBAAoBzmH,KAAK0jH,gBAEvC8C,EAAiB,CACrB7wG,KAAM,QACN7G,MAAO,oBACP1L,KAAM,iBACNwK,MAAO5N,KAAK+C,MAAMyjH,gBAAkBxmH,KAAK0jH,gBAErCiD,EAAmB,CACvBhxG,KAAM,QACN7G,MAAO,sBACP1L,KAAM,mBACNwK,MAAO5N,KAAK+C,MAAM4jH,kBAAoB3mH,KAAK0jH,gBAEvCgD,EAAiB,CACrB/wG,KAAM,QACN7G,MAAO,oBACP1L,KAAM,iBACNwK,MAAO5N,KAAK+C,MAAM2jH,gBAAkB1mH,KAAK0jH,gBAErCmD,EAAsB,CAC1BlxG,KAAM,QACN7G,MAAO,wBACP1L,KAAM,sBACNwK,MAAO5N,KAAK+C,MAAM8jH,qBAAuB7mH,KAAK0jH,gBAE1CkD,EAAgB,CACpBjxG,KAAM,QACN7G,MAAO,kBACP1L,KAAM,gBACNwK,MAAO5N,KAAK+C,MAAM6jH,eAAiB5mH,KAAK0jH,gBAEpCoD,EAAmB,CACvBnxG,KAAM,QACN7G,MAAO,qBACP1L,KAAM,mBACNwK,MAAO5N,KAAK+C,MAAM+jH,kBAAoB9mH,KAAK0jH,gBAG7C,MAAO,CACLlgH,MAAOxD,KAAK8O,MACZmS,OAAQ,CACNilG,EACAp3E,EACAq3E,EACAM,EACAD,EACAG,EACAD,EACAG,EACAD,EACAE,GAEFne,oBAAqB,CACnBud,WAAa,GAAEA,EAAWp3G,wCAAwCo3G,EAAWxhG,WAAWwhG,EAAWrhG,MACnGiqB,KAAO,GAAEA,EAAKhgC,wCAAwCggC,EAAKpqB,WAAWoqB,EAAKjqB,MAC3EshG,MAAQ,GAAEA,EAAMr3G,wCAAwCq3G,EAAMzhG,WAAWyhG,EAAMthG,OAGrF,CAEAilF,UAAAA,CAAWn8F,GACT,OAAQA,GACN,IAAK,aACL,IAAK,OACL,IAAK,QACL,IAAK,UACH,OAAO3N,KAAK+pG,sBAAsB,CAAEp8F,QACtC,IAAK,mBACL,IAAK,iBACL,IAAK,mBACL,IAAK,iBACL,IAAK,sBACL,IAAK,gBACL,IAAK,mBACH,OAAO,EACT,QACE,OAAO,EAEb,CAEA6gC,aAAAA,GACE,OAAOxuC,KAAK+C,MAAM0jH,gBACpB,CAEAliH,QAAAA,GACE,MAAQ,YAAWvE,KAAK+C,MAAMmjH,cAAclmH,KAAK+C,MAAM+rC,QAAQ9uC,KAAK+C,MAAMojH,OAC5E,EAGFC,EAActmH,UAAUsC,SAAW,CACjCqkH,iBAAkBhb,EAAaoa,OAC/BW,eAAgB/a,EAAaqa,KAC7Ba,iBAAkBlb,EAAaoa,OAC/Ba,eAAgBjb,EAAaqa,KAC7Be,oBAAqBpb,EACrBmb,cAAenb,EACfqb,iBAAkBrb,GAGpB,UC/XA,MAAMmc,UAA0BxB,EAC9B7oG,YAAcmqC,EAAAA,GAAYmgE,IAC1BtqG,aAAe,wBACfA,mBAAoB,EAGtB,U,eCMA,MAAMo0F,EACO,GADPA,EAEQ,EAFRA,EAGO,GAGPlG,EACI,UADJA,EAEE,YAGR,SAASuG,EAAYh8F,GACnB,MAAM9N,EAAS8N,EAAO+jB,MAAM,KAK5B,MAAO,CAJWojB,SAASj1C,EAAO,IACf6b,WAAW7b,EAAO,IACnBi1C,SAASj1C,EAAO,IAGpC,CAEA,MAAM4/G,UAAuBz9G,EAC3BkT,YAAcmqC,EAAAA,GAAYqgE,IAC1BxqG,aAAe,kBAEf,yBAAOkU,CAAkB9pB,GAAkE,IAAjE,OAAEqO,GAA6DrO,EACvF,OAA0C,EAAnC0X,KAAKwF,OAAOmtF,EAAYh8F,GACjC,CAEAmJ,GAAAA,CAAIqS,GAEF,GADAvnB,MAAMkV,IAAIqS,GAEqB,iBAAtBxxB,KAAK+C,MAAMiT,cACQ3N,IAAzBrI,KAAK+C,MAAMilH,gBAAqD3/G,IAA1BrI,KAAK+C,MAAMoiG,iBAAqD98F,IAAzBrI,KAAK+C,MAAMklH,WACzF,CACA,MAAOD,EAAW7iB,EAAY8iB,GAAajW,EAAYhyG,KAAK+C,MAAMiT,QAClEhW,KAAK+C,MAAMilH,UAAYA,EACvBhoH,KAAK+C,MAAMoiG,WAAaA,EACxBnlG,KAAK+C,MAAMklH,UAAYA,EACvBjoH,KAAKuJ,QAAQ,SACf,CACA,OAAOvJ,IACT,CAEA0d,aAAAA,CAAcgB,GACZzU,MAAMyT,gBACN,MAAM,WAAEuN,EAAU,MAAEzjB,GAAUxH,KAAK0B,MAAMgI,SACnC,UAAEs+G,EAAS,WAAE7iB,EAAU,UAAE8iB,EAAS,YAAErD,EAAW,UAAEE,GAAc9kH,KAAK+C,MACpEyiG,EAAM,IAAIN,EAAAA,EAAyB8iB,GACnCxd,EAAM,IAAIwB,EAAAA,EAAiBic,GAC3BC,EAAuB,GACvB5E,EAAsB,GACtBC,EAAsB,GACtB/9E,EAAQnmB,KAAKwF,IAAImjG,EAAWC,GAClC,IAAI7D,EACAC,EAAkB,EAEtB3lG,EAAQiR,OACRjR,EAAQO,UAAU,GAAK,IACvBP,EAAQS,IAAI,YAAa,GACzBT,EAAQS,IAAI,cAAeylG,GAC3BlmG,EAAQS,IAAI,YAAa2lG,GAGzBpmG,EAAQQ,YACR,IAAK,IAAIgD,EAAI,EAAGA,EAAIliB,KAAK4E,KAAKw2B,MAAMn7B,OAAQiiB,IAAK,CAG/C,GAFAsjF,EAAIv5F,IAAIjM,KAAK4E,KAAKw2B,MAAMlZ,IACxBsoF,EAAIv+F,IAAIjM,KAAK4E,KAAKuX,KAAK+F,GAAIliB,KAAK4E,KAAKmkC,IAAI7mB,GAAIliB,KAAK4E,KAAKw2B,MAAMlZ,EAAI,IAC7DA,EAAIsjB,EACN,SAGF,MAAMhnB,EAAIxe,KAAKmiB,GAAGD,GAClB,KAAIliB,KAAKmiB,GAAGD,EAAI,GAAK+I,EAAa,GAAlC,CAGA,GAAIjrB,KAAKmiB,GAAGD,EAAI,GAAK+I,EAAazjB,EAChC,WAEuBa,IAArB+7G,IAAgCA,EAAmBliG,GAEvDgmG,EAAWhmG,GAAKsjF,EAAI53F,MACpB01G,EAAUphG,GAAKsjF,EAAI53F,MAAQu3F,EAAaqF,EAAI58F,MAC5C21G,EAAUrhG,GAAKsjF,EAAI53F,MAAQu3F,EAAaqF,EAAI58F,MAE5C8Q,EAAQc,OAAOhB,EAAGa,KAAK2E,MAAMhkB,KAAKoiB,GAAGkhG,EAAUphG,MAC/CmiG,EAAkBniG,CAXlB,CAYF,CACA,QAAyB7Z,IAArB+7G,EAAJ,CAIA1lG,EAAQe,SACRf,EAAQc,OAAOxf,KAAKmiB,GAAGkiG,GAAkB3lG,EAAQsnB,OAAOv+B,QACxDiX,EAAQc,OAAOxf,KAAKmiB,GAAGiiG,GAAmB1lG,EAAQsnB,OAAOv+B,QACzDiX,EAAQysB,OAGRzsB,EAAQQ,YACR,IAAK,IAAIgD,EAAIkiG,EAAkBliG,GAAKmiG,EAAiBniG,IAAK,CACxD,MAAM1D,EAAIxe,KAAKmiB,GAAGD,GAClBxD,EAAQc,OAAOhB,EAAGa,KAAK2E,MAAMhkB,KAAKoiB,GAAGmhG,EAAUrhG,KACjD,CACAxD,EAAQe,SACRf,EAAQc,OAAOxf,KAAKmiB,GAAGkiG,GAAkB,GACzC3lG,EAAQc,OAAO,EAAG,GAClBd,EAAQkD,OAGRlD,EAAQQ,YACR,IAAK,IAAIgD,EAAIkiG,EAAkBliG,GAAKmiG,EAAiBniG,IAAK,CACxD,MAAM1D,EAAIxe,KAAKmiB,GAAGD,GAClBxD,EAAQc,OAAOhB,EAAGa,KAAK2E,MAAMhkB,KAAKoiB,GAAG8lG,EAAWhmG,KAClD,CACAxD,EAAQe,SACRf,EAAQmR,SAxBR,MAFEnR,EAAQmR,SA2BZ,CAEAkE,cAAAA,GACE,MAAMi0F,EAAY,CAChBryG,KAAM,SACN7G,MAAO,aACP1L,KAAM,YACNwK,MAAO5N,KAAK+C,MAAMilH,WAAarW,EAC/BhsF,UAAU,EACVjB,IAAK,EACLG,IAAK,QAGDsgF,EAAa,CACjBxvF,KAAM,SACN7G,MAAO,aACP1L,KAAM,aACNwK,MAAO5N,KAAK+C,MAAMoiG,YAAcwM,EAChChsF,UAAU,EACVoV,KAAM,GACNrW,IAAK,EACLG,IAAK,KAGDojG,EAAY,CAChBtyG,KAAM,SACN7G,MAAO,aACP1L,KAAM,YACNwK,MAAO5N,KAAK+C,MAAMklH,WAAatW,EAC/BhsF,UAAU,EACVjB,IAAK,EACLG,IAAK,QAGD+/F,EAAc,CAClBjvG,KAAM,QACN7G,MAAO,eACP1L,KAAM,cACNwK,MAAO5N,KAAK+C,MAAM6hH,aAAe5kH,KAAK0jH,gBAElCoB,EAAY,CAChBnvG,KAAM,QACN7G,MAAO,aACP1L,KAAM,YACNwK,MAAO5N,KAAK+C,MAAM+hH,WAAa9kH,KAAK0jH,gBAGtC,MAAO,CACLlgH,MAAOxD,KAAK8O,MACZmS,OAAQ,CAAC+mG,EAAW7iB,EAAY8iB,EAAWrD,EAAaE,GACxDnc,oBAAqB,CACnBqf,UAAY,GAAEA,EAAUl5G,wCAAwCk5G,EAAUtjG,WAAWsjG,EAAUnjG,MAC/FsgF,WAAa,GAAEA,EAAWr2F,kCAAkCq2F,EAAWzgF,WAAWygF,EAAWtgF,MAC7FojG,UAAY,GAAEA,EAAUn5G,wCAAwCm5G,EAAUvjG,WAAWujG,EAAUpjG,OAGrG,CAEAilF,UAAAA,CAAWn8F,GACT,OAAQA,GACN,IAAK,YAIL,IAAK,YACH,OAAO3N,KAAK+pG,sBAAsB,CAAEp8F,QAHtC,IAAK,aACH,OAAO3N,KAAK+pG,sBAAsB,CAAEp8F,MAAKq8F,aAAa,IAGxD,IAAK,cACL,IAAK,YACH,OAAO,EACT,QACE,OAAO,EAEb,CAEAx7D,aAAAA,GACE,OAAOxuC,KAAK+C,MAAM6hH,WACpB,CAEArgH,QAAAA,GACE,MAAQ,mBAAkBvE,KAAK+C,MAAMilH,aAAahoH,KAAK+C,MAAMoiG,cAAcnlG,KAAK+C,MAAMklH,WACxF,EAGFH,EAAehoH,UAAUsC,SAAW,CAAEwiH,YAAanZ,EAAeqZ,UAAWrZ,GAE7E,UCnNA,MAAM5yF,WAAaxO,EACjBkT,YAAcmqC,EAAAA,GAAY7uC,KAC1B0E,aAAe,OAEf,yBAAOkU,GACL,OAAO,CACT,CAEAomB,UAAAA,GACE,OAAO,CACT,CAEAiyD,UAAAA,GACE,OAAO,CACT,EAGF,Y,4BCdA,MAAMqe,WAAiB99G,EACrBkT,YAAcmqC,EAAAA,GAAYygE,SAC1B5qG,aAAe,0BAEf,yBAAOkU,GACL,OAAO,CACT,CAEA/T,aAAAA,CAAcgB,GACZzU,MAAMyT,gBACN,MAAM,cAAEwd,GAAkBl7B,KAAKqe,yBACzBzZ,EAAO5E,KAAK4E,KAClB,GAA6B,IAAzBA,EAAKqvD,SAASh0D,OAChB,OAGF,MAAMmoH,EAAgB,CACpB5gH,MAAO,IACPC,OAAQ,IACR4gH,UAAWhpG,KAAKqF,IAAI9f,EAAKw2B,MAAMn7B,OAAQ,KACvCkc,KAAMvX,EAAKg6G,iBACX71E,IAAKnkC,EAAK+5G,iBACVlqE,SAAU,GAEZ2zE,EAAc3zE,SAAW2zE,EAAc5gH,MAAQ,IAE/C,MAAM8nB,GAAU84F,EAAcjsG,KAAOisG,EAAcr/E,KAAOq/E,EAAc3gH,OAClE0a,EAAM3D,GACA,IAANA,EACKxe,KAAKmiB,GAAG,GAEVniB,KAAKmiB,GAAGvd,EAAKw2B,MAAMn7B,OAAS,KAAOmoH,EAAcC,UAAY7pG,EAAI4pG,EAAc3zE,WAElFryB,EAAM3D,GAAcze,KAAKoiB,GAAGgmG,EAAcjsG,KAAOsC,EAAI6Q,GACrD3Y,EAAOA,CAACuB,EAAe4F,EAAYC,EAAYC,EAAYC,KAC/D,MAAMW,GAAYC,EAAAA,GAAAA,IAAiB,CACjCf,GAAIqE,EAAGrE,GACPC,GAAIqE,EAAGrE,GACPC,GAAImE,EAAGnE,GACPC,GAAImE,EAAGnE,KAEHa,GAAcC,EAAAA,GAAAA,IAAoB,CAAEC,UAAW,KAAMJ,IAC3DF,EAAQO,UAAUH,EAAYN,EAAGM,EAAYL,GAE7CC,EAAQQ,YACRR,EAAQS,IAAI,YAAa,GACzBT,EAAQS,IAAI,cAAejH,GAC3BwG,EAAQc,OAAOZ,EAAUd,GAAIc,EAAUb,IACvCW,EAAQc,OAAOZ,EAAUZ,GAAIY,EAAUX,IACvCS,EAAQe,SAERf,EAAQO,WAA2B,EAAjBH,EAAYN,GAAyB,EAAjBM,EAAYL,EAAO,EAErDoH,EAAOA,CAACA,EAAcyiG,EAA4BpwG,EAAe4F,EAAYE,EAAYD,KAC7F,IAAIyH,GAAAA,EACF,CACEhH,EAAG2D,GAAIrE,EAAKE,GAAM,GAClBS,EAAG2D,EAAGrE,IAAsB,UAAfuqG,GAA0B,EAAI,GAC3CxiG,KAAM,CAAEtW,KAAM,EAAG2G,MAAO,QACxBiQ,aAA6B,UAAfkiG,EAAyB5xF,EAAAA,GAAalQ,OAASkQ,EAAAA,GAAapQ,IAC1EL,UAAW/N,EACXiO,UAAWyQ,EAAAA,GAAUC,OACrBhR,QAEF7lB,KAAK0B,OACLmmB,OAAOnJ,EAAQ,EAEb6pG,EAASA,CAAC1iG,EAAcyiG,EAA4BpwG,EAAe4F,EAAYC,KACnF,IAAIyH,GAAAA,EACF,CACEhH,EAAG2D,EAAGrE,GAAM,EACZW,EAAG2D,EAAGrE,IAAsB,UAAfuqG,GAA0B,EAAI,GAC3CxiG,KAAM,CAAEtW,KAAM,EAAG2G,MAAO,QACxBiQ,aAA6B,UAAfkiG,EAAyB5xF,EAAAA,GAAalQ,OAASkQ,EAAAA,GAAapQ,IAC1EL,UAAW/N,EACXiO,UAAWyQ,EAAAA,GAAUC,OACrBhR,QAEF7lB,KAAK0B,OACLmmB,OAAOnJ,EAAQ,EAEb8pG,EAAS/pG,GACb2D,EAAG3D,GAAK,IAAMze,KAAK0B,MAAM+F,OAASyzB,EAAc5U,IAAI7e,OAASyzB,EAAc1U,OAAO/e,OAAS,QAAU,QACjGghH,EAAShqG,GAAe2D,EAAG3D,IAAM,GAAK,QAAU,QAEhDiqG,EAAe,mBACfC,EAAc,oBAEpB,IAAK,MAAM3tD,KAAWp2D,EAAKqvD,SAAU,CACnC,MAAM,GAAEn2C,EAAE,GAAEE,EAAE,GAAEoN,EAAE,GAAEC,GAAO2vC,EAC3B,IAAI,GAAEj9C,EAAE,GAAEE,GAAO+8C,EACjB,OAAQA,EAAQ4tD,MACd,KAAK,EACHjyG,EAAK,2BAA4BmH,EAAIC,EAAIC,EAAIC,GAC7C,MAEF,KAAK,EACHtH,EAAKgyG,EAAa7qG,EAAIC,EAAIC,EAAIC,GAC9B,MAEF,KAAK,EACCF,IAAOqqG,EAAc3gH,QAAUwW,IAAOmqG,EAAc3gH,SACtDsW,EAAKE,EAAKmqG,EAAc3gH,OAAS,GAGnCkP,EAAK+xG,EAAc5qG,EAAIC,EAAIC,EAAIC,GAC/B,MAEF,KAAK,GACH4H,EAAK,aAAc4iG,EAAM1qG,GAAK4qG,EAAa7qG,EAAIE,EAAID,GACnD,MAEF,KAAK,GACH8H,EAAK,gBAAiB2iG,EAAMzqG,GAAK2qG,EAAc5qG,EAAIE,EAAID,GACvD,MAEF,KAAK,GACH8H,EAAK,eAAgB4iG,EAAM1qG,GAAK4qG,EAAa7qG,EAAIE,EAAID,GACrD,MAEF,KAAK,GACH8H,EAAK,kBAAmB2iG,EAAMzqG,GAAK2qG,EAAc5qG,EAAIE,EAAID,GACzD,MAEF,KAAK,GACHwqG,EAAO,IAAKE,EAAM1qG,GAAK4qG,EAAa7qG,EAAIC,GACxCwqG,EAAO,IAAKE,EAAMxqG,GAAK0qG,EAAa3qG,EAAIC,GACxCsqG,EAAO,IAAKE,EAAMp9F,GAAKs9F,EAAav9F,EAAIC,GACxC,MAEF,KAAK,GACHk9F,EAAO,IAAKC,EAAMzqG,GAAK2qG,EAAc5qG,EAAIC,GACzCwqG,EAAO,IAAKC,EAAMvqG,GAAKyqG,EAAc1qG,EAAIC,GACzCsqG,EAAO,IAAKC,EAAMn9F,GAAKq9F,EAAct9F,EAAIC,GAK/C,CACF,CAEA0I,cAAAA,GACE,MAAM20F,EAAe,CACnB/yG,KAAM,QACN7G,MAAO,gBACP1L,KAAM,eACNwK,MAAO5N,KAAK+C,MAAM2lH,cAAgB1oH,KAAK0jH,gBAEnCiF,EAAc,CAClBhzG,KAAM,QACN7G,MAAO,eACP1L,KAAM,cACNwK,MAAO5N,KAAK+C,MAAM4lH,aAAe3oH,KAAK0jH,gBAGxC,MAAO,CACLlgH,MAAOxD,KAAK8O,MACZmS,OAAQ,CAACynG,EAAcC,GACvBhgB,oBAAqB,CAAC,EAE1B,CAEAmB,UAAAA,GACE,OAAO,CACT,CAEAx7D,uBAAAA,GACE,OAAO,CACT,CAEA/pC,QAAAA,GACE,MAAO,EACT,EAGF4jH,GAASroH,UAAUsC,SAAW,CAAEsmH,aAAc,UAAWC,YAAa,WAEtE,Y,+DC7KKE,GAAW,SAAXA,GAAW,OAAXA,EAAW,oBAAXA,EAAW,sBAAXA,CAAW,EAAXA,IAAW,IAMXC,GAAW,SAAXA,GAAW,OAAXA,EAAAA,EAAW,aAAXA,EAAAA,EAAW,eAAXA,EAAAA,EAAW,iBAAXA,EAAAA,EAAW,eAAXA,CAAW,EAAXA,IAAW,IAuBhB,MAAMnX,GACa,WADbA,GAEG,UAOT,MAAMoX,WAAoB1+G,EACxBkT,YAAcmqC,EAAAA,GAAYshE,GAC1BzrG,aAAe,eAEf4B,GAAAA,CAAIqS,GACFvnB,MAAMkV,IAAIqS,GACV,MAAM,OAAExb,GAAWwb,EAKnB,OAJIxb,IACFhW,KAAK+C,MAAMkmH,gBAAkBjzG,EAC7BhW,KAAKuJ,QAAQ,WAERvJ,IACT,CAEAkpH,aAAAA,GACE,OAAQlpH,KAAK4E,KAAK6P,WAChB,KAAKuzB,EAAAA,GAAUO,IACf,KAAKP,EAAAA,GAAUpoB,EACf,KAAKooB,EAAAA,GAAUQ,GACb,OAAOsgF,GAAYK,KACrB,KAAKnhF,EAAAA,GAAUS,GACf,KAAKT,EAAAA,GAAUlc,EACb,OAAOg9F,GAAYphF,MACrB,KAAKM,EAAAA,GAAUW,EACf,KAAKX,EAAAA,GAAUX,EACb,OAAOyhF,GAAYlhF,KACrB,QACE,OAAOkhF,GAAYhhF,IAEzB,CAEAshF,eAAAA,CAAgBC,EAAoBC,EAAkBC,GACpD,IAAIC,EAAS,EAIb,GAHID,IAAeT,GAAYphF,QAAO8hF,EAAS,IAC3CD,IAAeT,GAAYlhF,OAAM4hF,EAAS,KAE1CH,IAAeC,EAAU,CAC3B,GAAmB,IAAfD,EAAkB,CAKpB,OAJkBrpH,KAAK4E,KAAK4iC,KAAK8hF,GAAYtpH,KAAK4E,KAAK4iC,KAAK6hF,IAzChD,OA6COG,CACrB,CAAO,CACL,MAAMC,EAAWz+G,EAAAA,GAAAA,sBAA4BhL,KAAK4E,KAAK4iC,KAAK6hF,IACtDK,EAAY1+G,EAAAA,GAAAA,sBAA4BhL,KAAK4E,KAAK4iC,KAAK6hF,EAAa,IAC1E,OAAIE,IAAeT,GAAYK,KACtBO,EAAU3hF,YAAc0hF,EAAS1hF,UAEjC2hF,EAAU/hF,aAAe8hF,EAAS9hF,UAE7C,CACF,CACA,OAAO,CACT,CAEAxlB,GAAM3D,IACJ,MAAMukC,EAAY/iD,KAAK4E,KAAKw2B,MAAMn7B,OAAS,EACrCsmH,EAAavmH,KAAK4E,KAAKw3B,SAAS2mB,GAAavkC,EAAIukC,EAEvD,OAAO/iD,KAAK0B,MAAMyV,MAAMqH,EAAExe,KAAK4E,KAAKw3B,SAAS5d,IAAM+nG,EAAW,EAGhE7oG,aAAAA,CAAcgB,GAEZ,GADAzU,MAAMyT,gBACyB,IAA3B1d,KAAK4E,KAAKw2B,MAAMn7B,OAAc,OAElC,MAAMmK,EAAapK,KAAK0B,MAAMgI,SACxB,WAAEuhB,EAAU,MAAEzjB,EAAK,WAAEmtC,GAAevqC,GACpC,KAAEqc,EAAI,MAAEF,GAAUnc,EAAWiU,yBAAyB6c,cACtDsX,EAAahrC,EAAQif,EAAKjf,MAAQ+e,EAAM/e,MACxCitC,GAAWC,EAAAA,EAAAA,IAAsB,CACrCC,aACA3jC,YAAa5G,EAAWwpB,iBAGpBwwF,GAAmB9xE,EAAAA,EAAAA,IAA2B,CAClD3oC,MAAO3J,KAAK4E,KACZmC,UAAW/G,KAAK0B,MAChBupB,eAEIo5F,GAAkB/xE,EAAAA,EAAAA,IAA2B,CACjD3oC,MAAO3J,KAAK4E,KACZmC,UAAW/G,KAAK0B,MAChBupB,aACAunB,eAIF,IADyB8L,EAAAA,EAAAA,IAAoB8lE,EAAkBC,GACzC,OAEtB,MAAMx+F,EAAOA,CAAC/W,EAAempC,EAAe0xE,KAC1C,IAAInkG,GAAAA,EACF,CACEhH,EAAGmrG,EACHlrG,EAAGze,KAAKoiB,GAAG61B,GAAS,GACpBnyB,KAAM,CAAEtW,KAAM,EAAGwW,OAAQ,OACzBI,aAAcsQ,EAAAA,GAAapQ,IAC3BL,UAAWjmB,KAAK+C,MAAMmV,MACtB2N,KAAO,GAAE/W,OAAUkV,EAAAA,EAAAA,IAAM,CAAEpf,KAAM5E,KAAK4E,KAAMT,IAAK8zC,QAEnDj4C,KAAK0B,OACLmmB,OAAOnJ,EAAQ,EAGb/H,EAAOA,CAACizG,EAAeC,EAAaprG,KACxCC,EAAQa,OAAOqqG,EAAO5pH,KAAKoiB,GAAG3D,IAC9BC,EAAQc,OAAOqqG,EAAK7pH,KAAKoiB,GAAG3D,GAAG,EAGjC,IAAI4qG,GAAc,EACdC,GAAY,EAChB,MAAM5rE,EAAU19C,KAAK4E,KAAKiO,aAAeC,EAAAA,GAAWC,MAC9Cw2G,EAAavpH,KAAKkpH,gBACxB,IACIh8E,EADA48E,EAAc,IAAI7jH,KAGtByY,EAAQO,UAAU,GAAK,IACvBP,EAAQS,IAAI,cAAenf,KAAK+C,MAAMmV,OAEtC,IAAK,IAAIjW,EAAQmiH,EAAiBniH,MAAOA,GAASoiH,EAAgBpiH,MAAOA,IAAS,CAIhF,OAHA6nH,EAAc9+G,EAAAA,GAAAA,sBAA4BhL,KAAK4E,KAAK4iC,KAAKvlC,IAGjDsnH,GACN,KAAKT,GAAYhhF,IACf,GAAIgiF,EAAY/hF,YAAcmF,GAAUnF,UACtC,SAEF,MACF,KAAK+gF,GAAYK,KACf,GAAIj8E,GAAYq8C,GAAAA,EAAmBr8C,EAAU48E,EAAa,CAAErO,aAAc,IACxE,SAEF,MACF,KAAKqN,GAAYphF,MACf,GAAIoiF,EAAYniF,aAAeuF,GAAUvF,WACvC,SAEF,MACF,KAAKmhF,GAAYlhF,KACf,GAAIkiF,EAAYjiF,gBAAkBqF,GAAUrF,cAC1C,SAON,OAHAqF,EAAW48E,EAGHP,GACN,KAAKT,GAAYhhF,IACf,GAAI7lC,EAAQ,EAAG,CACb,IAAI8nH,EAAqB,IAAI9jH,KAC7B,IAAK,IAAIic,EAAIjgB,EAAQ,EAAGigB,GAAK,IAC3B6nG,EAAqB/+G,EAAAA,GAAAA,sBAA4BhL,KAAK4E,KAAK4iC,KAAKtlB,IAC5D6nG,EAAmBhiF,YAAc+hF,EAAY/hF,WAFnB7lB,KAIhC6nG,EAAmB7vB,SAAS,EAAG,EAAG,EAAG,GACrC,MAAM8vB,EAA8Bh/G,EAAAA,GAAAA,qBAA2B++G,GAAoB,GAAOvxB,UAAY,IAChGyxB,EAAkB,IAAIhkH,KAAK6jH,GACjCG,EAAgB/vB,SAAS,EAAG,EAAG,EAAG,GAClC,MAAMgwB,EAA6Bl/G,EAAAA,GAAAA,qBAA2Bi/G,GAAiB,GAAOzxB,UAAY,IAMlG,GAJA6wB,EAAarpH,KAAK4E,KAAK4iC,KAAK3lC,WAAWwsD,GAAOA,GAAM27D,IACpDV,EAAWtpH,KAAK4E,KAAK4iC,KAAK3lC,WAAWwsD,GAAOA,EAAK67D,IAG7Cb,IAAeC,EAAU,CAC3B,MAAMv1C,EAAO/zE,KAAK4E,KAAK4iC,KAAK8hF,GAAYtpH,KAAK4E,KAAK4iC,KAAK6hF,GACjDc,GAAqBzsE,GAAWq2B,GA5KhC,MA6KAq2C,EAAiB1sE,GAAWqsE,EAAmBhiF,YAAc+hF,EAAY/hF,UAC1EoiF,GAAsBC,IACzBf,EAAaC,EAAWxlG,OAAOwgB,iBAEnC,CACF,CACA,MACF,KAAKwkF,GAAYK,KACf,MAAMkB,EAAsB9gC,GAAAA,EAAoBugC,EAAa,CAAErO,aAAc,IACvE6O,EAA+Bt/G,EAAAA,GAAAA,qBAA2Bq/G,GAAqB,GAAO7xB,UAAY,IAClG+xB,EAAuBhhC,GAAAA,EAAY8gC,EAAqB,CAAEjgE,MAAO,IACjEogE,EAAgCx/G,EAAAA,GAAAA,qBAA2Bu/G,GAAsB,GAAO/xB,UAAY,IAE1G6wB,EAAarpH,KAAK4E,KAAK4iC,KAAK3lC,WAAWwsD,GAAOA,GAAMm8D,IACpDlB,EAAWtpH,KAAK4E,KAAK4iC,KAAK3lC,WAAWwsD,GAAOA,EAAKi8D,IAE5CtqH,KAAKopH,gBAAgBC,EAAYC,EAAUC,KAC9CF,EAAaC,EAAWxlG,OAAOwgB,kBAEjC,MACF,KAAKwkF,GAAYphF,MACf,MAAM+iF,EAAuBlhC,GAAAA,EAAqBugC,GAC5CY,EAAgC1/G,EAAAA,GAAAA,qBAA2By/G,GAAsB,GAAOjyB,UAAY,IACpGmyB,EAAwBphC,GAAAA,EAAYkhC,EAAsB,CAAE3mE,OAAQ,IACpE8mE,EACJ5/G,EAAAA,GAAAA,qBAA2B2/G,GAAuB,GAAOnyB,UAAY,IAEvE6wB,EAAarpH,KAAK4E,KAAK4iC,KAAK3lC,WAAWwsD,GAAOA,GAAMu8D,IACpDtB,EAAWtpH,KAAK4E,KAAK4iC,KAAK3lC,WAAWwsD,GAAOA,EAAKq8D,IAE5C1qH,KAAKopH,gBAAgBC,EAAYC,EAAUC,KAC9CF,EAAaC,EAAWxlG,OAAOwgB,kBAEjC,MACF,KAAKwkF,GAAYlhF,KACf,MAAMijF,EAAsBthC,GAAAA,EAAoBugC,GAC1CgB,EAA+B9/G,EAAAA,GAAAA,qBAA2B6/G,GAAqB,GAAOryB,UAAY,IAClGuyB,EAAuBxhC,GAAAA,EAAYshC,EAAqB,CAAE9wB,MAAO,IACjEixB,EAAgChgH,EAAAA,GAAAA,qBAA2B+/G,GAAsB,GAAOvyB,UAAY,IAE1G6wB,EAAarpH,KAAK4E,KAAK4iC,KAAK3lC,WAAWwsD,GAAOA,GAAM28D,IACpD1B,EAAWtpH,KAAK4E,KAAK4iC,KAAK3lC,WAAWwsD,GAAOA,EAAKy8D,IAE5C9qH,KAAKopH,gBAAgBC,EAAYC,EAAUC,KAC9CF,EAAaC,EAAWxlG,OAAOwgB,kBAMrC,MAAsB,IAAhB+kF,IAAmC,IAAdC,GAAmBD,EAAaC,GAAW,SAEtE,IAAI2B,EAAOC,EAAMC,EAAMC,EAAMC,EAAMC,EAAMC,EACzC,MAAMC,EAAensG,KAAKwF,OAAO7kB,KAAK4E,KAAKuX,KAAK9b,MAAMgpH,EAAYC,IAC5DmC,EAAcpsG,KAAKqF,OAAO1kB,KAAK4E,KAAKmkC,IAAI1oC,MAAMgpH,EAAYC,IAC1DrwE,EAAgBj5C,KAAK4E,KAAKw2B,MAAMkuF,EAAW,GAEd,aAA/BtpH,KAAK+C,MAAMkmH,iBACbgC,GAASO,EAAeC,EAAcxyE,GAAiB,EACvDiyE,EAAO,EAAID,EAAQO,EACnBL,EAAOF,GAASO,EAAeC,GAC/BL,EAAOK,EAAc,GAAKD,EAAeP,GACzCI,EAAO,EAAIJ,EAAQQ,EACnBH,EAAOL,GAASO,EAAeC,GAC/BF,EAAOC,EAAe,GAAKP,EAAQQ,KAEnCR,GAASO,EAAeC,EAAcxyE,GAAiB,EACvDiyE,EAAOD,EAlPG,MAkPMO,EAAeC,GAC/BN,EAAOF,EAlPG,MAkPMO,EAAeC,GAC/BL,EAAOH,GAASO,EAAeC,GAC/BJ,EAAOJ,EArPG,MAqPMO,EAAeC,GAC/BH,EAAOL,EArPG,MAqPMO,EAAeC,GAC/BF,EAAON,GAASO,EAAeC,IAGjC,MAAMC,EAA6B,CAAET,QAAOC,OAAMC,OAAMC,OAAMC,OAAMC,OAAMC,QAG1E,IAAI3B,EAAQ5pH,KAAKmiB,GAAGlgB,GAChB4nH,EAAM7pH,KAAKmiB,GAAGlgB,GAClB,OAAQsnH,GACN,KAAKT,GAAYhhF,IACf,MAAMkM,EAAWh0C,KAAK4E,KAAKovC,SACrB23E,EAAW/B,EAEX7jE,EAAS,IAAI9/C,KAAK6jH,GACxB/jE,EAAOm0C,SAAS,GAAI,EAAG,EAAG,GACtBl6F,KAAK4E,KAAKovD,aAAehgB,GAAY,GAAG+R,EAAOm0C,SAAS,GAAI,GAAI,EAAG,GACnElmD,GAAY,KAAO0J,GAASqI,EAAOm0C,SAAS,GAAI,GAAI,GAAI,IAC5D,MAEM0xB,GAFc7lE,EAAOyyC,UAAY,IACFsxB,EAAYtxB,UAAY,KAAQ,GACtCxkD,EAC/B61E,EAAMxqG,KAAKqF,IAAIinG,EAAWC,EAASn3E,GAAWxpB,EAAazjB,GAE3D,MAAMs+C,EAAW,IAAI7/C,KAAK6jH,GAC1BhkE,EAASo0C,SAAS,EAAG,GAAI,EAAG,GACxBl6F,KAAK4E,KAAKmvD,WAAa/f,GAAY,GAAG8R,EAASo0C,SAAS,EAAG,EAAG,EAAG,GACjElmD,GAAY,KAAO0J,GAASoI,EAASo0C,SAAS,EAAG,EAAG,EAAG,GAI3D0vB,EAAQ+B,GAHc7lE,EAAS0yC,UAAY,IACFsxB,EAAYtxB,UAAY,KAAQ,GACtCxkD,EACLS,EAC9B,MAEF,KAAKq0E,GAAYK,KACf,IAAK,IAAIjnG,EAAIjgB,EAAQ,EAAGigB,GAAKmiG,EAAgBpiH,MAAOigB,IAAK,CACvD,MAAM2pG,EAAW7gH,EAAAA,GAAAA,sBAA4BhL,KAAK4E,KAAK4iC,KAAKtlB,IAC5D,IAAKqnE,GAAAA,EAAmBugC,EAAa+B,EAAU,CAAEpQ,aAAc,IAAM,CACnEoO,EAAM7pH,KAAKmiB,GAAGD,GACd,KACF,CACF,CACA,IAAK,IAAIA,EAAIjgB,EAAQ,EAAGigB,GAAKkiG,EAAiBniH,MAAOigB,IAAK,CACxD,MAAM2pG,EAAW7gH,EAAAA,GAAAA,sBAA4BhL,KAAK4E,KAAK4iC,KAAKtlB,IAC5D,IAAKqnE,GAAAA,EAAmBugC,EAAa+B,EAAU,CAAEpQ,aAAc,IAAM,CACnEmO,EAAQ5pH,KAAKmiB,GAAGD,EAAI,GACpB,KACF,CACF,CAEA,GAAI0nG,IAAUC,EAAK,CAGjBA,IAAQnsE,EAAU,EAAI,GADHr+B,KAAKg1B,MAAMr0C,KAAK4E,KAAKowC,mBAtS5B,MAsSoEh1C,KAAK4E,KAAKovC,UAClDS,CAC1C,CACA,MAEF,KAAKq0E,GAAYphF,MACf,IAAK,IAAIxlB,EAAIjgB,EAAQ,EAAGigB,GAAKmiG,EAAgBpiH,MAAOigB,IAAK,CAEvD,GADiBlX,EAAAA,GAAAA,sBAA4BhL,KAAK4E,KAAK4iC,KAAKtlB,IAC/CylB,aAAemiF,EAAYniF,WAAY,CAClDkiF,EAAM7pH,KAAKmiB,GAAGD,GACd,KACF,CACF,CACA,IAAK,IAAIA,EAAIjgB,EAAQ,EAAGigB,GAAKkiG,EAAiBniH,MAAOigB,IAAK,CAExD,GADiBlX,EAAAA,GAAAA,sBAA4BhL,KAAK4E,KAAK4iC,KAAKtlB,IAC/CylB,aAAemiF,EAAYniF,WAAY,CAClDiiF,EAAQ5pH,KAAKmiB,GAAGD,EAAI,GACpB,KACF,CACF,CAEA,GAAI0nG,IAAUC,EAAK,CAKjBA,IAAQnsE,EAAU,GAAK,KAHJ19C,KAAK4E,KAAKo5E,WACzB3+D,KAAKg1B,MAAMr0C,KAAK4E,KAAKowC,mBA9Tb,MA8TqDh1C,KAAK4E,KAAKovC,UACvE,GACsCS,CAC5C,CACA,MACF,QACE,IAAK,IAAIvyB,EAAIjgB,EAAQ,EAAGigB,GAAKmiG,EAAgBpiH,MAAOigB,IAAK,CAEvD,GADiBlX,EAAAA,GAAAA,sBAA4BhL,KAAK4E,KAAK4iC,KAAKtlB,IAC/C2lB,gBAAkBiiF,EAAYjiF,cAAe,CACxDgiF,EAAM7pH,KAAKmiB,GAAGD,GACd,KACF,CACF,CACA,IAAK,IAAIA,EAAIjgB,EAAQ,EAAGigB,GAAKkiG,EAAiBniH,MAAOigB,IAAK,CAExD,GADiBlX,EAAAA,GAAAA,sBAA4BhL,KAAK4E,KAAK4iC,KAAKtlB,IAC/C2lB,gBAAkBiiF,EAAYjiF,cAAe,CACxD+hF,EAAQ5pH,KAAKmiB,GAAGD,EAAI,GACpB,KACF,CACF,CAEI0nG,IAAUC,IAEZA,IAAQ7pH,KAAK4E,KAAK6P,YAAcuzB,EAAAA,GAAUW,EAAI,GAAK,IAAM8L,GAI/Dm1E,EAAQvqG,KAAKwF,IAAI+kG,GAAQ3+F,GAGzBvM,EAAQQ,YACRvI,EAAKizG,EAAOC,EAAK6B,EAAWT,OAC5BvsG,EAAQe,SAGRf,EAAQiR,OACRjR,EAAQkd,YAAY,CAAC,EAAG,IACxBld,EAAQQ,YACRvI,EAAKizG,EAAOC,EAAK6B,EAAWL,MAC5B10G,EAAKizG,EAAOC,EAAK6B,EAAWJ,MAC5B30G,EAAKizG,EAAOC,EAAK6B,EAAWH,MAC5B50G,EAAKizG,EAAOC,EAAK6B,EAAWR,MAC5Bv0G,EAAKizG,EAAOC,EAAK6B,EAAWP,MAC5Bx0G,EAAKizG,EAAOC,EAAK6B,EAAWN,MAC5B1sG,EAAQe,SACRf,EAAQmR,UAGJg6F,EAAMD,GAAS,KACjB/jG,EAAK,IAAK6lG,EAAWT,MAAOrB,GAC5B/jG,EAAK,KAAM6lG,EAAWL,KAAMzB,GAC5B/jG,EAAK,KAAM6lG,EAAWJ,KAAM1B,GAC5B/jG,EAAK,KAAM6lG,EAAWH,KAAM3B,GAC5B/jG,EAAK,KAAM6lG,EAAWR,KAAMtB,GAC5B/jG,EAAK,KAAM6lG,EAAWP,KAAMvB,GAC5B/jG,EAAK,KAAM6lG,EAAWN,KAAMxB,GAEhC,CAEAlrG,EAAQO,WAAW,IAAM,GAC3B,CAEA8U,cAAAA,GACE,MAAMk1F,EAAkB,CACtBtzG,KAAM,SACN7G,MAAO,mBACP1L,KAAM,kBACNwK,MAAO5N,KAAK+C,MAAMkmH,iBAAmBtX,GACrChsF,UAAU,EACV20C,MAAO,CACL,CACE1sD,MAAO,WACPkB,MAAO,YAET,CACElB,MAAO,YACPkB,MAAO,eAIPoJ,EAAQ,CACZvC,KAAM,QACN7G,MAAO,QACP1L,KAAM,QACNwK,MAAO5N,KAAK+C,MAAMmV,OAASlY,KAAK0jH,gBAGlC,MAAO,CACLlgH,MAAOxD,KAAK8O,MACZmS,OAAQ,CAACgoG,EAAiB/wG,GAC1BywF,oBAAqB,CAAC,EAE1B,CAEAmB,UAAAA,CAAWn8F,GACT,OAAQA,GACN,IAAK,kBACL,IAAK,QACH,QAAS3N,KAAK+C,MAAM4K,GACtB,QACE,OAAO,EAEb,CAEApJ,QAAAA,GACE,MAAQ,iBAAgBskH,GAAY7oH,KAAK+C,MAAMkmH,mBACjD,EAGFF,GAAYjpH,UAAUsC,SAAW,CAC/B6mH,gBAAiBtX,GACjBz5F,MAAOy5F,IAGT,YCpdA,MAAMma,WAAYzhH,EAChBkT,YAAcmqC,EAAAA,GAAYqkE,IAC1BxuG,aAAe,gBAEf,yBAAOkU,GACL,OAAO,CACT,CAEAtS,GAAAA,CAAIqS,GAEF,GADAvnB,MAAMkV,IAAIqS,GACuB,iBAAtBxxB,KAAK+C,MAAMiT,cAA4C3N,IAApBrI,KAAK+C,MAAMg4B,WAA6C1yB,IAAvBrI,KAAK+C,MAAMipH,SAAwB,CAChH,MAAOjxF,EAAO,EAAGixF,EAAU,GAAKhsH,KAAK+C,MAAMiT,OAAO+jB,MAAM,KAAKrsB,KAAK8Q,GAAMuF,WAAWvF,KACnFxe,KAAK+C,MAAMg4B,KAAOA,EAClB/6B,KAAK+C,MAAMipH,QAAUA,CACvB,CAEA,OADAhsH,KAAKuJ,QAAQ,UACNvJ,IACT,CAEA0d,aAAAA,CAAcgB,GACZzU,MAAMyT,gBACN,MAAM9Y,EAAO5E,KAAK4E,KACZ6lG,EAAY7lG,EAAKuX,KAAK,GAAKvX,EAAKuX,KAAK,GACrCuuF,EAAW9lG,EAAKmkC,IAAI,GAAKnkC,EAAKmkC,IAAI,GAGxC,IAAIkjF,GAFQxhB,EAAY,GAAKA,EAAYC,EAAWD,EAAY,KACpDC,EAAW,GAAKA,EAAWD,EAAYC,EAAW,GAG1DwhB,EAAMD,EAASrnH,EAAKmkC,IAAI,GAAKnkC,EAAKuX,KAAK,GACvCgwG,EAAKF,EAASrnH,EAAKuX,KAAK,GAAKvX,EAAKmkC,IAAI,GACtCqjF,EAAUxnH,EAAKuX,KAAK,GACpBkwG,EAASznH,EAAKmkC,IAAI,GAClBujF,EAAKtsH,KAAK+C,MAAMg4B,KAEpB,IAAK,IAAI7Y,EAAI,EAAGmiC,EAAMz/C,EAAKw2B,MAAMn7B,OAAQqkD,EAAMD,GAAO,EAAGC,EAAMpiC,EAAImiC,EAAMniC,EAAImiC,EAAKC,EAAMpiC,IAAMA,IAAK,CACjG,IAAIqqG,EACJ,MAAMhH,EAAW6G,EACX3G,EAAU4G,EAChBD,EAAUxnH,EAAKuX,KAAK+F,GACpBmqG,EAASznH,EAAKmkC,IAAI7mB,GAEd+pG,EACEI,GAAUH,GACZD,GAAS,EACTC,EAAMC,EAEFD,EAAM3G,IACR2G,EAAM3G,GAEJ2G,EAAME,IACRF,EAAME,GAGRG,EAAYL,EAEZI,EAAKtsH,KAAK+C,MAAMg4B,KAChBoxF,EAAKE,EAELH,GAAYI,GAAMH,EAAKD,GAEnBA,EAAM3G,IACR2G,EAAM3G,GAEJ2G,EAAME,IACRF,EAAME,KAGRG,EAAYL,EAERE,EAAUD,IACZA,EAAKC,EACLE,GAAMtsH,KAAK+C,MAAMg4B,KACbuxF,EAAKtsH,KAAK+C,MAAMipH,UAClBM,EAAKtsH,KAAK+C,MAAMipH,UAIpBE,GAAYI,GAAMH,EAAKD,GAEnBA,EAAMzG,IACRyG,EAAMzG,GAEJyG,EAAMG,IACRH,EAAMG,IAIND,GAAWF,GACbD,GAAS,EACTC,EAAMC,EAEFD,EAAMzG,IACRyG,EAAMzG,GAEJyG,EAAMG,IACRH,EAAMG,GAGRE,EAAYL,EAEZI,EAAKtsH,KAAK+C,MAAMg4B,KAChBoxF,EAAKC,EAELF,GAAYI,GAAMH,EAAKD,GAEnBA,EAAMzG,IACRyG,EAAMzG,GAEJyG,EAAMG,IACRH,EAAMG,KAGRE,EAAYL,EAERG,EAASF,IACXA,EAAKE,EACLC,GAAMtsH,KAAK+C,MAAMg4B,KACbuxF,EAAKtsH,KAAK+C,MAAMipH,UAClBM,EAAKtsH,KAAK+C,MAAMipH,UAIpBE,GAAYI,GAAMH,EAAKD,GAEnBA,EAAM3G,IACR2G,EAAM3G,GAEJ2G,EAAME,IACRF,EAAME,IAKZ,MAAM5tG,EAAIa,KAAK2E,MAAMhkB,KAAKmiB,GAAGD,GAAK,KAC5BzD,EAAIY,KAAK2E,MAAMhkB,KAAKoiB,GAAGmqG,GAAa,KAC1C7tG,EAAQS,IAAI,YAAa8sG,EAASjsH,KAAK+C,MAAMypH,YAAcxsH,KAAK+C,MAAM0pH,cACtE/tG,EAAQoe,SAASte,EAAGC,EAAG,EAAG,EAC5B,CACF,CAEAsV,cAAAA,GACE,MAAMgH,EAAO,CACXplB,KAAM,SACNolB,KAAM,IACNrW,IAAK,IACLG,IAAK,IACL/V,MAAO,OACP1L,KAAM,OACNwK,MAAO5N,KAAK+C,MAAMg4B,MAAQ,IAC1BpV,UAAU,GAENqmG,EAAU,CACdr2G,KAAM,SACNolB,KAAM,IACNrW,IAAK,IACLG,IAAK,IACL/V,MAAO,eACP1L,KAAM,UACNwK,MAAO5N,KAAK+C,MAAMipH,SAAW,GAC7BrmG,UAAU,GAEN6mG,EAAc,CAClB72G,KAAM,QACN7G,MAAO,eACP1L,KAAM,cACNwK,MAAO5N,KAAK+C,MAAMypH,aAAexsH,KAAK0jH,eACtCgJ,cAAc,GAEVD,EAAe,CACnB92G,KAAM,QACN7G,MAAO,gBACP1L,KAAM,eACNwK,MAAO5N,KAAK+C,MAAM0pH,cAAgBzsH,KAAK0jH,eACvCgJ,cAAc,GAGhB,MAAO,CACLlpH,MAAOxD,KAAK8O,MACZmS,OAAQ,CAAC8Z,EAAMixF,EAASQ,EAAaC,GACrC9jB,oBAAqB,CACnB5tE,KAAO,GAAEA,EAAKjsB,kCAAkCisB,EAAKrW,WAAWqW,EAAKlW,MACrEmnG,QAAU,GAAEA,EAAQl9G,kCAAkCk9G,EAAQtnG,WAAWsnG,EAAQnnG,OAGvF,CAEAilF,UAAAA,CAAWn8F,GACT,OAAQA,GACN,IAAK,OACL,IAAK,UACH,OAAO3N,KAAK+pG,sBAAsB,CAAEp8F,MAAKq8F,aAAa,IAExD,IAAK,cACL,IAAK,eAEH,OAAO,EACT,QACE,OAAO,EAEb,CAEAx7D,aAAAA,GACE,OAAOxuC,KAAK+C,MAAMypH,WACpB,CAEAjoH,QAAAA,GACE,MAAQ,OAAMvE,KAAK+C,MAAMg4B,QAAQ/6B,KAAK+C,MAAMipH,SAC9C,EAGFF,GAAIhsH,UAAUsC,SAAW,CACvBoqH,YAAa,UACbC,aAAc,WAGhB,YCvNO,MAAME,WAAuBtnB,EAAAA,EAClC9nF,YAAcmqC,EAAAA,GAAYklE,IAG1BrnB,0BAAAA,GACE,MAAO,CAAEiH,IAAK,GAChB,CAEA/G,SAAAA,CAAUC,GACR,MAAM,MAAEtqE,GAAUp7B,KAAK2J,MACjBo5C,EAAY3nB,EAAMn7B,OAAS,EACjCD,KAAK2lG,kBAAoB3lG,KAAKulG,6BAE9B,IAAI1iD,EAAM,EACV,IAAK,IAAI3gC,EAAI,EAAGA,EAAIliB,KAAK0E,QAAQsR,OAAQkM,IACvC2gC,GAAOznB,EAAMlZ,GAEf,IAAK,IAAIA,EAAIliB,KAAK0E,QAAQsR,OAAQkM,GAAK6gC,IACrCF,EAAMA,EAAMznB,EAAMlZ,EAAIliB,KAAK0E,QAAQsR,QAAUolB,EAAMlZ,GACnDliB,KAAK4lG,iBAAiB4G,IAAItqF,GAAK2gC,EAAM7iD,KAAK0E,QAAQsR,QAEI,IAAlD0vF,IAAoB1lG,KAAK4lG,iBAAkB1jF,IAJCA,KAQpD,ECvBF,MAAM2qG,WAAYxiH,EAChBkT,YAAcmqC,EAAAA,GAAYklE,IAC1BrvG,aAAe,wBAEf,yBAAOkU,CAAmBza,GAExB,OADwB3M,EAAQonB,mBAAmBza,GAC1B,CAC3B,CAEAmI,GAAAA,CAAIqS,GACFvnB,MAAMkV,IAAIqS,GACV,MAAM,OAAExb,GAAWwb,EAKnB,MAJsB,iBAAXxb,IACThW,KAAK+C,MAAMiT,OAASmnC,SAASnnC,EAAQ,IACrChW,KAAKuJ,QAAQ,WAERvJ,IACT,CAEA0d,aAAAA,CAAcgB,GACZzU,MAAMyT,gBACN,MAAM,WAAEuN,EAAU,MAAEzjB,GAAUxH,KAAK0B,MAAMgI,QACnCsM,EAASqJ,KAAKqF,IAAI1kB,KAAK+C,MAAMiT,OAAQhW,KAAK4E,KAAKw2B,MAAMn7B,OAAS,GACpEye,EAAQQ,YACRR,EAAQO,UAAU,GAAK,IACvBP,EAAQS,IAAI,YAAa,GACzBT,EAAQS,IAAI,cAAenf,KAAK+C,MAAMmV,OAEf,IAAIy0G,GAAe,CACxChjH,MAAO3J,KAAK4E,KACZF,QAAS,CAAEsR,YAGEyvF,WAAU,CAAA99F,EAAUw6G,KAAc,IAAvB,IAAE3V,GAAK7kG,EAC/B,MAAM6W,EAAIxe,KAAKmiB,GAAGggG,GAClB,KAAIniH,KAAKmiB,GAAGggG,EAAY,GAAKl3F,EAAa,GAG1C,QAAIjrB,KAAKmiB,GAAGggG,EAAY,GAAKl3F,EAAazjB,SAG1CkX,EAAQc,OAAOhB,EAAGa,KAAK2E,MAAMhkB,KAAKoiB,GAAGoqF,EAAI2V,KAAa,IAGxDzjG,EAAQO,WAAW,IAAM,IACzBP,EAAQe,QACV,CAEAsU,cAAAA,GACE,MAAM/d,EAAS,CACbL,KAAM,SACN7G,MAAO,SACP1L,KAAM,SACNwK,MAAO5N,KAAK+C,MAAMiT,QAAU,EAC5B2P,UAAU,EACVjB,IAAK,EACLG,IAAK,QAED3M,EAAQ,CACZvC,KAAM,QACN7G,MAAO,QACP1L,KAAM,QACNwK,MAAO5N,KAAK+C,MAAMmV,OAASlY,KAAK0jH,gBAGlC,MAAO,CACLlgH,MAAOxD,KAAK8O,MACZmS,OAAQ,CAACjL,EAAQkC,GACjBywF,oBAAqB,CACnB3yF,OAAS,GAAEA,EAAOlH,wCAAwCkH,EAAO0O,WAAW1O,EAAO6O,OAGzF,CAEAilF,UAAAA,CAAWn8F,GACT,OAAQA,GACN,IAAK,SACH,OAAO3N,KAAK+pG,sBAAsB,CAAEp8F,QACtC,IAAK,QACH,QAAS3N,KAAK+C,MAAM4K,GACtB,QACE,OAAO,EAEb,CAEApJ,QAAAA,GACE,MAAQ,OAAMvE,KAAK+C,MAAMiT,QAC3B,EAGF62G,GAAI/sH,UAAUsC,SAAW,CAAE8V,MAAO,WAElC,YCtGA,MAAM40G,WAAaD,GACjBtvG,YAAcmqC,EAAAA,GAAYqlE,KAG5BD,GAAKhtH,UAAUsC,SAAW,CAAE8V,MAAO,WAEnC,YCGMy5F,GACI,EADJA,GAEQ,EAGRlG,GACK,UADLA,GAEO,UAGb,SAASuG,GAAYD,GACnB,MAAM7pG,EAAS6pG,EAAUh4E,MAAM,KAI/B,MAAO,CAHQojB,SAASj1C,EAAO,KAAOypG,GACnB5tF,WAAW7b,EAAO,KAAOypG,GAG9C,CAEA,MAAMqb,WAAmB3iH,EACvBkT,YAAcmqC,EAAAA,GAAYulE,IAC1B1vG,aAAe,aAEf,yBAAOkU,CAAkB9pB,GAAkE,IAAjE,OAAEqO,GAA6DrO,EACvF,MAAO2+F,GAAa0L,GAAYh8F,GAChC,OAAOswF,EAAY,CACrB,CAEAnnF,GAAAA,CAAIqS,GACFvnB,MAAMkV,IAAIqS,GACV,MAAM,OAAExb,GAAWwb,EACnB,GAAsB,iBAAXxb,EAAqB,CAC9B,MAAOswF,EAAWnB,GAAc6M,GAAYh8F,GAC5ChW,KAAK+C,MAAMiT,OAASswF,EACpBtmG,KAAK+C,MAAMoiG,WAAaA,EACxBnlG,KAAKuJ,QAAQ,SACf,CACA,OAAOvJ,IACT,CAEA0d,aAAAA,CAAcgB,GACZzU,MAAMyT,gBACN,MAAM,WAAEuN,EAAU,MAAEzjB,GAAUxH,KAAK0B,MAAMgI,SACnC,OAAEsM,EAAM,WAAEmvF,GAAenlG,KAAK+C,OAC9B,KAAEoZ,EAAI,IAAE4sB,EAAG,MAAE3N,GAAUp7B,KAAK4E,KAC5B4lG,EAAM,IAAIwB,EAAAA,EAAiBh2F,GAC3Bk3G,EAA2B,GAC3BC,EAA2B,GAC3BC,EAAwB,GAC9B,IAAIhJ,EACAC,EAAkB,EAEtB3lG,EAAQO,UAAU,GAAK,IACvBP,EAAQQ,YACRR,EAAQS,IAAI,YAAa,GACzBT,EAAQS,IAAI,cAAenf,KAAK+C,MAAMsqH,cACtC,IAAK,IAAInrG,EAAI,EAAGA,EAAIkZ,EAAMn7B,OAAQiiB,IAAK,CACrCsoF,EAAIv+F,IAAIkQ,EAAK+F,GAAI6mB,EAAI7mB,GAAIkZ,EAAMlZ,EAAI,IAGnC,MAAMorG,GAAOnxG,EAAK+F,GAAK6mB,EAAI7mB,IAAM,EAC3BohG,EAAYgK,EAAMnoB,EAAaqF,EAAI58F,MACnC21G,EAAY+J,EAAMnoB,EAAaqF,EAAI58F,MAEzCs/G,EAAehrG,GAAKohG,EACpB6J,EAAejrG,GAAKqhG,EAGhBnoF,EAAMlZ,GAAKgrG,EAAehrG,EAAI,GAChCkrG,EAAWlrG,IAAK,EACPkZ,EAAMlZ,GAAKirG,EAAejrG,EAAI,GACvCkrG,EAAWlrG,IAAK,EAEhBkrG,EAAWlrG,GAAKkrG,EAAWlrG,EAAI,GAI7BkrG,EAAWlrG,IAAMirG,EAAejrG,GAAKirG,EAAejrG,EAAI,KAC1DirG,EAAejrG,GAAKirG,EAAejrG,EAAI,KAEpCkrG,EAAWlrG,IAAMgrG,EAAehrG,GAAKgrG,EAAehrG,EAAI,KAC3DgrG,EAAehrG,GAAKgrG,EAAehrG,EAAI,IAGzC,MAAM1D,EAAIxe,KAAKmiB,GAAGD,GAClB,KAAIA,EAAIlM,GAAUwI,EAAIyM,EAAa,GAAnC,CAGA,GAAIjrB,KAAKmiB,GAAGD,EAAI,GAAK+I,EAAazjB,EAChC,WAEuBa,IAArB+7G,IAAgCA,EAAmBliG,GAEnDkrG,EAAWlrG,KAAOkrG,EAAWlrG,EAAI,IAEnCxD,EAAQa,OAAOvf,KAAKmiB,GAAGD,EAAI,GAAI7C,KAAK2E,MAAMhkB,KAAKoiB,GAAG8qG,EAAehrG,EAAI,MACrExD,EAAQc,OAAOhB,EAAGa,KAAK2E,MAAMhkB,KAAKoiB,GAAG+qG,EAAejrG,OAC3CkrG,EAAWlrG,GAEpBxD,EAAQc,OAAOhB,EAAGa,KAAK2E,MAAMhkB,KAAKoiB,GAAG+qG,EAAejrG,MAGpDxD,EAAQa,OAAOf,EAAGa,KAAK2E,MAAMhkB,KAAKoiB,GAAG+qG,EAAejrG,MAEtDmiG,EAAkBniG,CAjBlB,CAkBF,CAGA,GAFAxD,EAAQe,cAEiBpX,IAArB+7G,EAAJ,CAKA1lG,EAAQQ,YACRR,EAAQS,IAAI,cAAenf,KAAK+C,MAAMwqH,gBACtC,IAAK,IAAIrrG,EAAIkiG,EAAkBliG,GAAKmiG,EAAiBniG,IAAK,CACxD,MAAM1D,EAAIxe,KAAKmiB,GAAGD,IACbkrG,EAAWlrG,IAAMkrG,EAAWlrG,EAAI,IAEnCxD,EAAQa,OAAOvf,KAAKmiB,GAAGD,EAAI,GAAI7C,KAAK2E,MAAMhkB,KAAKoiB,GAAG+qG,EAAejrG,EAAI,MACrExD,EAAQc,OAAOhB,EAAGa,KAAK2E,MAAMhkB,KAAKoiB,GAAG8qG,EAAehrG,OAC1CkrG,EAAWlrG,GAKrBxD,EAAQa,OAAOf,EAAGa,KAAK2E,MAAMhkB,KAAKoiB,GAAG8qG,EAAehrG,MAHpDxD,EAAQc,OAAOhB,EAAGa,KAAK2E,MAAMhkB,KAAKoiB,GAAG8qG,EAAehrG,KAKxD,CACAxD,EAAQe,SAERf,EAAQO,WAAW,IAAM,GApBzB,MAFEP,EAAQO,WAAW,IAAM,GAuB7B,CAEA8U,cAAAA,GACE,MAAM/d,EAAS,CACbL,KAAM,SACN7G,MAAO,SACP1L,KAAM,SACNwK,MAAO5N,KAAK+C,MAAMiT,QAAU27F,GAC5BhsF,UAAU,EACVjB,IAAK,EACLG,IAAK,QAEDsgF,EAAa,CACjBxvF,KAAM,SACN7G,MAAO,SACP1L,KAAM,aACNwK,MAAO5N,KAAK+C,MAAMoiG,YAAcwM,GAChChsF,UAAU,EACVoV,KAAM,GACNrW,IAAK,EACLG,IAAK,KAGDwoG,EAAe,CACnB13G,KAAM,QACN7G,MAAO,gBACP1L,KAAM,eACNwK,MAAO5N,KAAK+C,MAAMsqH,cAAgBrtH,KAAK0jH,gBAEnC6J,EAAiB,CACrB53G,KAAM,QACN7G,MAAO,kBACP1L,KAAM,iBACNwK,MAAO5N,KAAK+C,MAAMwqH,gBAAkBvtH,KAAK0jH,gBAG3C,MAAO,CACLlgH,MAAOxD,KAAK8O,MACZmS,OAAQ,CAACjL,EAAQmvF,EAAYkoB,EAAcE,GAC3C5kB,oBAAqB,CACnB3yF,OAAS,GAAEA,EAAOlH,wCAAwCkH,EAAO0O,WAAW1O,EAAO6O,MACnFsgF,WAAa,GAAEA,EAAWr2F,kCAAkCq2F,EAAWzgF,WAAWygF,EAAWtgF,OAGnG,CAEAilF,UAAAA,CAAWn8F,GACT,OAAQA,GACN,IAAK,SACH,OAAO3N,KAAK+pG,sBAAsB,CAAEp8F,QACtC,IAAK,aACH,OAAO3N,KAAK+pG,sBAAsB,CAAEp8F,MAAKq8F,aAAa,IACxD,IAAK,eACL,IAAK,iBACH,OAAO,EACT,QACE,OAAO,EAEb,CAEAx7D,aAAAA,GACE,OAAOxuC,KAAK+C,MAAMsqH,YACpB,CAEA9oH,QAAAA,GACE,MAAQ,cAAavE,KAAK+C,MAAMiT,UAAUhW,KAAK+C,MAAMoiG,YACvD,EAGF6nB,GAAWltH,UAAUsC,SAAW,CAC9BirH,aAAc5hB,GACd8hB,eAAgB9hB,IAGlB,Y,gBC9MA,MAAM+hB,GACA,UADAA,GAEE,UAGF7b,GACI,GADJA,GAEK,GAUX,SAAS8b,GAAoBv1G,EAAe+4E,GAC1C,OAAO5vD,EAAAA,EAAAA,KAAwB4I,EAAAA,EAAAA,IAAkB/xB,GAAQ+4E,EAC3D,CAuBA,MAAMy8B,WAAsBrjH,EAC1BkT,YAAcmqC,EAAAA,GAAYimE,GAC1BpwG,aAAe,iBAEf,yBAAOkU,CAAkB9pB,GAAkE,IAAjE,OAAEqO,GAA6DrO,EACvF,MAAO2+F,EAAY,IAAKC,EAAAA,EAAAA,IAAkCvwF,GAC1D,OAAOswF,EAAY,CACrB,CAEAnnF,GAAAA,CAAIqS,GACFvnB,MAAMkV,IAAIqS,GACV,MAAM,OAAExb,GAAWwb,EACnB,GAAsB,iBAAXxb,EAAqB,CAC9B,MAAOswF,EAAWrV,GArBxB,SAAqB8gB,GACnB,MAAM7pG,EAAS6pG,EAAUh4E,MAAM,KAI/B,MAAO,CAHQojB,SAASj1C,EAAO,KAAOypG,GACtB5tF,WAAW7b,EAAO,KAAOypG,GAG3C,CAemCK,CAAYh8F,GACzChW,KAAK+C,MAAMiT,OAASswF,EACpBtmG,KAAK+C,MAAMkuF,QAAUA,EACrBjxF,KAAKuJ,QAAQ,SACf,CACA,OAAOvJ,IACT,CAEA0d,aAAAA,CAAcgB,GACZ,GAAiC,iBAAtB1e,KAAK+C,MAAMiT,OACpB,OAEF/L,MAAMyT,gBAEN,MAAMtT,EAAapK,KAAK0B,MAAMgI,SACxB,WAAEuhB,EAAU,MAAEzjB,GAAU4C,GACxB,KAAEqc,EAAI,MAAEF,GAAUnc,EAAWiU,yBAAyB6c,cACtDsX,EAAahrC,EAAQif,EAAKjf,MAAQ+e,EAAM/e,MAE9C,GAA+B,IAA3BxH,KAAK4E,KAAKw2B,MAAMn7B,OAAc,OAElC,MAAMmkH,GAAmB9xE,EAAAA,EAAAA,IAA2B,CAClD3oC,MAAO3J,KAAK4E,KACZmC,UAAW/G,KAAK0B,MAChBupB,eAGIo5F,GAAkB/xE,EAAAA,EAAAA,IAA2B,CACjD3oC,MAAO3J,KAAK4E,KACZmC,UAAW/G,KAAK0B,MAChBupB,aACAunB,eAIF,IADyB8L,EAAAA,EAAAA,IAAoB8lE,EAAkBC,GACzC,OAEtB,MAAOuJ,EAASC,GAtEX,CACLJ,IAFiC1qH,EAuEwB/C,KAAK+C,OArEpC6qH,SAAWJ,GAAczqH,EAAMkuF,SACzDw8B,GAAoB1qH,EAAM8qH,WAAaL,GAAgBzqH,EAAMkuF,UAHjE,IAAqCluF,EAwEjC,MAAO+qH,EAAUC,GAAYhkF,EAAAA,GAAMsF,OAAOrvC,KAAK4E,KAAKw2B,MAAM/6B,MAAM+jH,EAAiBniH,MAAOoiH,EAAgBpiH,MAAQ,IAE1G+rH,EAAU3uG,KAAKQ,IAAIkuG,EAAWD,GAAY9tH,KAAK+C,MAAMiT,OACrDi4G,EAAW,GAEjB,IAAK,IAAI/rG,EAAI,EAAGA,EAAIliB,KAAK+C,MAAMiT,OAAQkM,IAAK,CAC1C,MAAM0iF,EAAekpB,EAAWE,EAAU9rG,EACpC2iF,EAAaD,EAAeopB,EAClCC,EAAS1sH,KAAK,CAAEikC,MAAOo/D,EAAcvgD,IAAKwgD,EAAYqpB,GAAI,EAAGC,KAAM,GACrE,CAGA,IAAK,IAAIjsG,EAAIkiG,EAAiBniH,MAAOigB,GAAKmiG,EAAgBpiH,MAAOigB,IAAK,CACpE,MAAMksG,EAAuBH,EAASpsH,WAAU,CAACD,EAAMwsH,KACrDC,OA7Ea39E,EA6ED1wC,KAAK4E,KAAKw2B,MAAMlZ,GA7EFsjB,EA6EM5jC,EAAK4jC,MA7EI6e,EA6EGziD,EAAKyiD,OAAO+pE,EA5EtC19E,EAAMlL,EAAQkL,GAAOlL,IAAUkL,GAAO2T,EADhE,IAAqB3T,EAAalL,EAAe6e,CA8E3C,IACA,IAAsB,IAAlB+pE,EAAqB,SACzB,MAAME,EAActuH,KAAK4E,KAAKw2B,MAAMlZ,GAAKliB,KAAK4E,KAAK0oC,KAAKprB,GAAK,OAAS,KACtE+rG,EAASG,GAAcE,IAAgBtuH,KAAK4E,KAAKu3B,OAAOja,EAC1D,CAEA,MAAM2C,EAAMklB,EAAAA,GAAMllB,IAAIopG,EAASvgH,KAAK9L,GAASA,EAAKssH,GAAKtsH,EAAKusH,QACtDv3E,EAAwB,GAAbpE,EACX+7E,EAAW1+E,GAAAA,MAAiBzD,MAAM,CAAC,EAAGwK,IAAWxzB,OAAO,CAAC,EAAGyB,IAElEopG,EAAS1lH,SAAS3G,IAChB,MAAM6c,EAAIY,KAAK2E,MAAMhkB,KAAKoiB,GAAGxgB,EAAK4jC,QAC5BgpF,EAAmBnvG,KAAK2E,MAAMhkB,KAAKoiB,GAAGxgB,EAAKyiD,MAAQ5lC,EACnDgwG,EAAgBD,GAAoBnvG,KAAKQ,IAAI2uG,GAAoB,EAAI,EAAI,GACzEhwG,EAAIa,KAAKQ,IAAIoL,GACbyjG,EAAiBrvG,KAAK2E,MAAMuqG,EAAS3sH,EAAKssH,KAC1CS,EAAmBtvG,KAAK2E,MAAMuqG,EAAS3sH,EAAKusH,OAElDzvG,EAAQuH,UAAY2nG,EACpBlvG,EAAQoe,SAASte,EAAGC,EAAGiwG,EAAgBD,GACvC/vG,EAAQuH,UAAY4nG,EACpBnvG,EAAQoe,SAASte,EAAIkwG,EAAgBjwG,EAAGkwG,EAAkBF,EAAc,GAE5E,CAEA16F,cAAAA,GACE,MAAM/d,EAAS,CACbL,KAAM,SACN7G,MAAO,QACP1L,KAAM,SACNwK,MAAO5N,KAAK+C,MAAMiT,QAAU27F,GAC5BhsF,UAAU,EACVjB,IAAK,EACLG,IAAK,QAEDosE,EAAU,CACdt7E,KAAM,SACN7G,MAAO,UACP1L,KAAM,UACNwK,MAAO5N,KAAK+C,MAAMkuF,SAAW0gB,GAC7BhsF,UAAU,EACVjB,IAAK,EACLG,IAAK,EACLkW,KAAM,IAEF6yF,EAAU,CACdj4G,KAAM,QACN7G,MAAO,WACP1L,KAAM,UACNwK,MAAO5N,KAAK+C,MAAM6qH,SAAWJ,IAEzBK,EAAY,CAChBl4G,KAAM,QACN7G,MAAO,aACP1L,KAAM,YACNwK,MAAO5N,KAAK+C,MAAM8qH,WAAaL,IAGjC,MAAO,CACLhqH,MAAOxD,KAAK8O,MACZmS,OAAQ,CAACjL,EAAQi7E,EAAS28B,EAASC,GACnCllB,oBAAqB,CACnB3yF,OAAS,GAAEA,EAAOlH,wCAAwCkH,EAAO0O,WAAW1O,EAAO6O,MACnFosE,QAAU,GAAEA,EAAQniF,kCAAkCmiF,EAAQvsE,WAAWusE,EAAQpsE,OAGvF,CAEAilF,UAAAA,CAAWn8F,GACT,OAAQA,GACN,IAAK,SACH,OAAO3N,KAAK+pG,sBAAsB,CAAEp8F,QACtC,IAAK,UACH,OAAO3N,KAAK+pG,sBAAsB,CAAEp8F,MAAKq8F,aAAa,IACxD,IAAK,UACL,IAAK,YAEH,OAAO,EACT,QACE,OAAO,EAEb,CAEAx7D,aAAAA,GACE,OAAOxuC,KAAK+C,MAAM6qH,SAAWJ,EAC/B,CAEAjpH,QAAAA,GACE,MAAQ,MAAKvE,KAAK+C,MAAMiT,QAC1B,EAGF03G,GAAc5tH,UAAUsC,SAAW,CAAEwrH,QAASJ,GAAcK,UAAWL,IAEvE,YCpMO,MAAMoB,WAAwBvpB,EAAAA,EACnC9nF,YAAcmqC,EAAAA,GAAYmnE,KAE1BtpB,0BAAAA,GACE,MAAO,CAAEupB,KAAM,GACjB,CAEArpB,SAAAA,CAAUC,GACR,MAAM,KAAEl+D,EAAI,MAAEpM,EAAK,IAAE2N,EAAG,KAAE5sB,EAAI,OAAEggB,GAAWn8B,KAAK2J,MAC1Co5C,EAAYvb,EAAKvnC,OAAS,EAChCD,KAAK2lG,kBAAoB3lG,KAAKulG,6BAE9B,IAAIwpB,EAAe,EACfC,EAAmB,EAEvB,IAAK,IAAI9sG,EAAI,EAAGA,GAAK6gC,EAAW7gC,IAAK,CACnC,GAAIA,EAAI,EAAG,CACT,MAAM2+F,GAAWrrD,EAAAA,EAAAA,IAAsBhuB,EAAKtlB,EAAI,IA1B7BugC,EA2BIo+D,EA3BSoO,GA2BCz5D,EAAAA,EAAAA,IAAsBhuB,EAAKtlB,KA1BlEugC,EAAM5a,gBAAkBonF,EAAOpnF,eAC/B4a,EAAM9a,aAAesnF,EAAOtnF,YAC5B8a,EAAM1a,YAAcknF,EAAOlnF,aAyBnBgnF,EAAe,EACfC,EAAmB,EAEvB,CAUA,GALAD,IAHsB3zF,EAAMlZ,GAAK6mB,EAAI7mB,GAAK/F,EAAK+F,IAAM,EAC3Bia,EAAOja,GAGjC8sG,GAAoB7yF,EAAOja,GAE3BliB,KAAK4lG,iBAAiBkpB,KAAK5sG,GAAK6sG,EAAeC,GAEO,IAAlDtpB,IAAoB1lG,KAAK4lG,iBAAkB1jF,GAC7C,KAEJ,CA5CsBgtG,IAACzsE,EAAawsE,CA6CtC,EC3CF,MAAME,WAAa9kH,EACjBkT,YAAcmqC,EAAAA,GAAYmnE,KAC1BtxG,aAAe,yBAEf,yBAAOkU,GACL,OAAO,CACT,CAEAtuB,WAAAA,CAAY+E,EAAwBxG,GAClCuI,MAAM/B,EAAQxG,GACd1B,KAAK+C,MAAMiT,OAAS,CACtB,CAEA0H,aAAAA,CAAcgB,GAEZ,GADAzU,MAAMyT,iBACD1d,KAAK63C,aACR,OAGF,MAAM,WAAE5sB,EAAU,MAAEzjB,GAAUxH,KAAK0B,MAAMgI,QACzCgV,EAAQO,UAAU,GAAK,IACvBP,EAAQQ,YACRR,EAAQS,IAAI,YAAa,GACzBT,EAAQS,IAAI,cAAenf,KAAK+C,MAAMmV,OAEd,IAAI02G,GAAgB,CAC1CjlH,MAAO3J,KAAK4E,KACZF,QAAS,CAAEsR,OAAQhW,KAAK+C,MAAMiT,UAGhByvF,WAAU,CAAA99F,EAAWw6G,KAAc,IAAxB,KAAE2M,GAAMnnH,EACjC,MAAM6W,EAAIxe,KAAKmiB,GAAGggG,GAClB,GAAIniH,KAAKmiB,GAAGggG,EAAY,GAAKl3F,EAAa,EACxC,OAEF,GAAIjrB,KAAKmiB,GAAGggG,EAAY,GAAKl3F,EAAazjB,EACxC,OAAO,EAET,MAAMiX,EAAIY,KAAK2E,MAAMhkB,KAAKoiB,GAAG0sG,EAAK3M,KAClCzjG,EAAQc,OAAOhB,EAAGC,EAAE,IAGtBC,EAAQe,SACRf,EAAQO,WAAW,IAAM,GAC3B,CAEA8U,cAAAA,GACE,MAAM7b,EAAQ,CACZvC,KAAM,QACN7G,MAAO,QACP1L,KAAM,QACNwK,MAAO5N,KAAK+C,MAAMmV,OAASlY,KAAK0jH,gBAGlC,MAAO,CACLlgH,MAAOxD,KAAK8O,MACZmS,OAAQ,CAAC/I,GACTywF,oBAAqB,CAAC,EAE1B,CAEAmB,UAAAA,CAAWn8F,GACT,MACO,UADCA,CAOV,CAEAkqC,UAAAA,GACE,OAAO73C,KAAK0B,MAAMgI,QAAQC,QAAQq0E,UACpC,CAEA1vC,uBAAAA,GACE,OAAOtuC,KAAK63C,YACd,CAEAtzC,QAAAA,GACE,MAAQ,MACV,EAGF4qH,GAAKrvH,UAAUsC,SAAW,CAAE8V,MAAO,WAEnC,YC3EaqxB,GAAiBtmC,OAAOitB,OAAO,CAC1C,CAACw3B,EAAAA,GAAYr9C,SAAU4N,EACvB,CAACyvC,EAAAA,GAAY7uC,MAAOo8F,GACpB,CAACvtD,EAAAA,GAAY07D,IAAKgM,EAClB,CAAC1nE,EAAAA,GAAYg9D,KAAM2K,EACnB,CAAC3nE,EAAAA,GAAY49C,KAAME,EACnB,CAAC99C,EAAAA,GAAYy9D,MAAOzR,EACpB,CAAChsD,EAAAA,GAAY29D,MAAOiK,EACpB,CAAC5nE,EAAAA,GAAYi+D,OAAQ4J,EACrB,CAAC7nE,EAAAA,GAAY2+D,IAAKmJ,EAClB,CAAC9nE,EAAAA,GAAYmgE,KAAM4H,EACnB,CAAC/nE,EAAAA,GAAYqgE,KAAM2H,EACnB,CAAChoE,EAAAA,GAAYygE,UAAWl0D,GACxB,CAACvM,EAAAA,GAAYshE,IAAK2G,GAClB,CAACjoE,EAAAA,GAAYqkE,KAAMG,GACnB,CAACxkE,EAAAA,GAAYklE,KAAMpgB,GACnB,CAAC9kD,EAAAA,GAAYqlE,MAAO6C,GACpB,CAACloE,EAAAA,GAAYulE,KAAM1sH,GACnB,CAACmnD,EAAAA,GAAYimE,IAAKkC,GAClB,CAACnoE,EAAAA,GAAYmnE,MAAOC,I,yMCjBtB,MAAM9jH,EACJ,UAAO0Z,GAAkE,QAAAvjB,EAAAC,UAAAnB,OAAnBktF,EAAI,IAAAttF,MAAAsB,GAAAG,EAAA,EAAAA,EAAAH,EAAAG,IAAJ6rF,EAAI7rF,GAAAF,UAAAE,GACxD,GAAuB,iBAAZ6rF,EAAK,GACd,OAAOA,EAAK,IAAMA,EAAK,GAAKA,EAAK,GAAMA,EAAK,GAE9C,IAAIzoE,EAAMyoE,EAAK,GAAG,GAClB,IAAK,MAAM2iC,KAAO3iC,EAChB,IAAK,MAAMjrF,KAAM4tH,EACX5tH,EAAKwiB,IACPA,EAAMxiB,GAIZ,OAAOwiB,CACT,CAEA,UAAOG,GAAkE,QAAAkrG,EAAA3uH,UAAAnB,OAAnBktF,EAAI,IAAAttF,MAAAkwH,GAAAC,EAAA,EAAAA,EAAAD,EAAAC,IAAJ7iC,EAAI6iC,GAAA5uH,UAAA4uH,GACxD,GAAuB,iBAAZ7iC,EAAK,GACd,OAAOA,EAAK,IAAMA,EAAK,GAAKA,EAAK,GAAMA,EAAK,GAE9C,IAAItoE,EAAMsoE,EAAK,GAAG,GAClB,IAAK,MAAM2iC,KAAO3iC,EAChB,IAAK,MAAMjrF,KAAM4tH,EACX5tH,EAAK2iB,IACPA,EAAM3iB,GAIZ,OAAO2iB,CACT,CAEA,aAAOwqB,GACL,IAAIxqB,EAAG,QAAAorG,EAAA7uH,UAAAnB,OADQktF,EAAI,IAAAttF,MAAAowH,GAAAC,EAAA,EAAAA,EAAAD,EAAAC,IAAJ/iC,EAAI+iC,GAAA9uH,UAAA8uH,GAEnB,IAAIxrG,EAAOG,EAAMsoE,EAAK,GAAG,GACzB,IAAK,MAAM2iC,KAAO3iC,EAChB,IAAK,MAAMjrF,KAAM4tH,EACX5tH,EAAKwiB,IACPA,EAAMxiB,GAEJA,EAAK2iB,IACPA,EAAM3iB,GAIZ,MAAO,CAACwiB,EAAKG,EACf,CAEA,oBAAO6hB,GACL,MAA0B,oBAAX7gC,QAA0BA,OAAOsqH,kBAAqB,CACvE,CAEA,6BAAOxpF,CAAsBh/B,GAU1B,IAV2B,cAC5Bi/B,EAAa,MACbp/B,EAAK,OACLC,EAAM,MACN0+B,EAAQn7B,EAAM07B,iBAMf/+B,EACKi/B,IACFA,EAAcp/B,MAAQA,EAAQ2+B,EAC9BS,EAAcn/B,OAASA,EAAS0+B,EAChCS,EAAczwB,MAAM3O,MAAQA,EAAQ,KACpCo/B,EAAczwB,MAAM1O,OAASA,EAAS,KAE1C,CAEA,2CAAO2oH,CAAqCC,GAC1C,MAAM7oF,EAAO6oF,GAAiB,IAAIpqH,KAUlC,OAAyB,IA/F7B,SAAsBuhC,GACpB,MAAM8oF,EAAY9oF,EAAKO,UACjBwoF,EAAa/oF,EAAKG,WAElB6oF,EAAiBF,EADL9oF,EAAKipF,SAEvB,QAAIF,EAAa,GAAKA,EAAa,MAG/BA,EAAa,GAAKA,EAAa,KAGb,IAAfA,EAAmBC,GAAkB,EAAIA,GAAkB,GACpE,CAkFkBE,CARG,IAAIzqH,KACnBuhC,EAAKmpF,iBACLnpF,EAAKopF,cACLppF,EAAKqpF,aACLrpF,EAAKspF,cAAgB,EACrBtpF,EAAKupF,gBACLvpF,EAAKwpF,kBAGS,EAAI,GAAU,EAChC,CAEA,2BAAO/2B,CAAqBo2B,EAAqBY,GAC/C,MAAMzpF,EAAO,IAAIvhC,KAAKoqH,GAChBa,EAA6E,IAAnDlmH,EAAMolH,qCAAqC5oF,GACrE2pF,EAAiD,GAA3B3pF,EAAK4pF,oBAA2B,IACtDC,EAA6BJ,EAAY,GAAK,EAEpD,OADAzpF,EAAK8pF,QAAQ9pF,EAAKgxD,WAAa24B,EAAsBD,GAA2BG,GACzE7pF,CACT,CAGA,kCAAO2vE,GAA4F,IAAhEtc,IAAYz5F,UAAAnB,OAAA,QAAAoI,IAAAjH,UAAA,KAAAA,UAAA,GAAS05F,IAAc15F,UAAAnB,OAAA,QAAAoI,IAAAjH,UAAA,KAAAA,UAAA,GAASmwH,EAAanwH,UAAAnB,OAAA,QAAAoI,IAAAjH,UAAA,GAAAA,UAAA,GAAG,GAC7F,MAEM2D,EAAaqD,IAAA,IAAC,MAAEmtC,EAAK,QAAE2U,GAA6C9hD,EAAA,OAAa,GAARmtC,EAAa2U,CAAO,EAE7F1iB,EAAOyyD,EAAqB,IAAIh0F,MAAQ,GACxCurH,EAAYhqF,EAAKipF,SACjBgB,EAAsC,GAAlBjqF,EAAK1iC,WAAkB0iC,EAAKziC,aAEhD2sH,EAAmB72B,EAA6C,GAA9BpwC,EAAAA,GAAmC,EACrEknE,EAAqB72B,EAA+C,GAA9BrwC,EAAAA,GAAmC,EAEzEmnE,EAA0B,IAAdJ,GAAiC,IAAdA,EAC/BliE,EAASvqD,EAZM,CAAEwwC,MAAO,EAAG2U,QAAS,KAYAwnE,EAAmBH,GAAiBE,EACxEI,EAAW9sH,EAZE,CAAEwwC,MAAO,GAAI2U,QAAS,IAYCynE,EAAqBJ,GAAiBE,EAChF,OAAQG,GAAatiE,IAAWuiE,CAClC,CAEA,4BAAOr8D,CAAsBhzD,GAM3B,MAAMglC,EAAO,IAAIvhC,KAAK,GAEtB,OADAuhC,EAAKsqF,cAActvH,GACZwI,EAAMivF,qBAAqBzyD,GAAM,EAC1C,CAEA,yBAAOs6E,CAAmBt6E,GACxB,MAAQ,GAAEA,EAAKK,iBAAiB3nC,OAAOsnC,EAAKG,WAAa,GAAGu6E,SAAS,EAAG,QAAQhiH,OAAOsnC,EAAKO,WAAWm6E,SACrG,EACA,MAEJ,CAEA,yBAAOntE,CAAmBtN,GACxB,MAAOs6E,EAAMC,EAAIC,GAAMx6E,EAAW1N,MAAM,KAElCyN,EAAO,IAAIvhC,KAAK6d,OAAOq5B,SAAS4kE,GAAOj+F,OAAOq5B,SAAS6kE,GAAM,EAAGl+F,OAAOq5B,SAAS8kE,IAKtF,OAJIn+F,OAAOkS,MAAMwR,EAAKgxD,aACpBrvF,EAAAA,EAAAA,IAAiB,IAAIC,MAAM,gBAAiB,CAAEC,MAAO,CAAEm+B,OAAMC,gBAGxDD,CACT,CAEA,eAAOsC,CAASioF,GACd,IAAIvwE,EAAAA,EAAAA,MAAY,OAAO,EACvB,IAAIwwE,GAAa,EAGjB,GAAIC,UAAUC,UAAU1xH,QAAQ,cAAgB,EAC9C,IACEoK,SAASunH,YAAY,cACrBH,GAAa,CACf,CAAE,MAAOzsH,GAAI,MAEbysH,IAAeC,UAAUC,UAAUE,MACjC,+EAIJ,GAAIL,EACF,IACE,OACEC,IACCnsH,OAAOosH,UAAUI,kBAChBxsH,OAAOosH,UAAUK,gBACjB,iBAAkB1nH,SAAS8W,cAAc,OAE/C,CAAE,MAAOnc,GAAI,CAGf,OAAOysH,CACT,CAEA,aAAOjnH,GACL,MAAMwnH,EAAcN,UAAUC,UAAUE,MAAM,SACxCI,EAAgBP,UAAUC,UAAUE,MAAM,WAC1CK,EAAcR,UAAUC,UAAUE,MAAM,SAG9C,OAFuBH,UAAUC,UAAUE,MAAM,QAAUH,UAAUK,eAAiB,IAE3DE,IAAkBC,GAAgBF,CAC/D,CAEA,gBAAOjhC,CAAUluF,GACf,MAAMsvH,EAAK,IAAIC,OAAO,mBAAqBvvH,EAAO,+BAClD,OAAOwH,SAASgoH,OAAOv5G,QAAQq5G,EAAI,KACrC,CAEA,gBAAO1qD,CAAU5kE,EAAcwK,EAAek6D,GAC5C,IAAI8qD,EAASxvH,EAAO,IAAMwK,EAAQ,aAAek6D,EAAQ+qD,cACtB,cAA/BjoH,SAASC,SAASC,WACpB8nH,GAAU,wBAEZhoH,SAASgoH,OAASA,CACpB,EAGF,UACa34B,EAAuBjvF,EAAMivF,qBAC7BzkC,EAAwBxqD,EAAMwqD,sBAC9BssD,EAAqB92G,EAAM82G,mBAC3B/sE,EAAqB/pC,EAAM+pC,mBAEjC,SAASzpC,IACd,OACEV,SAASkoH,mBACTloH,SAASmoH,yBACTnoH,SAASooH,sBACTpoH,SAASqoH,sBACT,CAEJ,CAEO,SAASznH,EAAqB1J,GACnC,OACEA,EAAQyJ,mBACRzJ,EAAQoxH,yBACRpxH,EAAQqxH,sBACRrxH,EAAQsxH,mBAEZ,CAEO,SAASznH,IACd,OACEf,SAASc,gBAAkBd,SAASyoH,sBAAwBzoH,SAAS0oH,mBAAqB1oH,SAAS2oH,gBAEvG,CAEO,SAASjoD,EAAMkoD,GACQ,YAAxB5oH,SAAS6oH,WAKb7oH,SAASuB,iBAAiB,mBAAoBqnH,GAJ5CA,GAKJ,CAEO,SAASpzC,EAAoBszC,GAClC,MACM3+G,EAAmBnK,SAAS2lD,eAAemjE,GAE3CC,EAAM5+G,GAAkBo7C,wBAE9B,MAAO,CACL3oD,MAAO6X,KAAKwF,KAAK8uG,GAAKnsH,OAAS,GANjB,EAM+B,GAC7CC,OAAQ4X,KAAKwF,KAAK8uG,GAAKlsH,QAAU,GAPnB,EAOiC,GAEnD,CAEO,SAAS2vF,IACd,OAAOvxF,OAAOumF,WAAariC,EAAAA,EAC7B,CAEO,SAASqN,EAAoBttB,GAClC,SAAIA,GAAY9+B,EAAM8+B,aACbjkC,OAAO+I,YAAc,KAAQ,CAGxC,CAEO,SAASiuB,EAA8BjvB,GAC5C,IAAIu1F,EAAS,GAYb,OAXIv1F,GAAS,KACXA,GAAS,IACTu1F,EAAS,KACAv1F,GAAS,KAClBA,GAAS,IACTu1F,EAAS,KACAv1F,GAAS,MAClBA,GAAS,IACTu1F,EAAS,KAGJv1F,EAAMhK,QAAQ,GAAKu/F,CAC5B,CAEO,SAAS5uF,IACd,MAAyB,oBAAX1O,QAA0BA,OAAO8S,gBAAgBgxD,kBACjE,CAEO,SAAS5pB,EACdvuB,GAMA,IALAoiG,EAAaxyH,UAAAnB,OAAA,QAAAoI,IAAAjH,UAAA,GAAAA,UAAA,GAAG,CACdsrC,EAAAA,GAA2BoiB,UAC3BpiB,EAAAA,GAA2BmiB,YAC3BniB,EAAAA,GAA2BqiB,YAG7B,OACGx6C,KAAuBq/G,EAAcx5F,SAAS5I,EAAIngB,6BAEnDmgB,EAAIngB,6BAA+Bq7B,EAAAA,GAA2BkiB,SAElE,C,mECvTA,MAAMilE,EAA6D,CAAC,EAE7D,SAAS/+D,EAAqBnnD,UAC5BkmH,EAA8BlmH,EACvC,CAOO,SAASoyG,EAAgBz8G,GAC9B,MAAsB,eAAfA,EAAMF,IACf,CAEO,SAASixD,EAA4B1sD,GAMzC,IAN0C,IAC3CgG,EAAG,0BACH2mD,GAA4B,GAI7B3sD,EACK2sD,GAhBC,SAAsB3mD,GAC3BkmH,EAA8BlmH,IAAM69E,QACpC12B,EAAqBnnD,EACvB,CAcImmH,CAAanmH,GAEf,MAAMomH,EAAa,oBAAqBluH,OAAS,IAAI6kF,qBAAoBriF,EAIzE,OAHI0rH,IACFF,EAA8BlmH,GAAOomH,GAEhCA,CACT,C,0ECvBO,MAAMz4G,EACXtY,GAQAgxH,EAAAA,IAA6B,CAAE7qH,iBAAgB,QAAKnG,G,gDCYtD,MAAMixH,IAAmBzyE,E,SAAAA,OA3BzB,WACE,MAAM0yE,EAAiBjC,UAAUC,UAAUE,MAAM,YAC3C+B,EAAelC,UAAUC,UAAUE,MAAM,UACzCI,EAAgBP,UAAUC,UAAUE,MAAM,WAC1CgC,EAAcnC,UAAUC,UAAUE,MAAM,SACxCK,EAAcR,UAAUC,UAAUE,MAAM,SACxCiC,EAAoBpC,UAAUC,UAAUE,MAAM,eAC9CkC,EAAsBrC,UAAUC,UAAUE,MAAM,kBAChDmC,EAAiBtC,UAAUC,UAAUE,MAAM,QAAUH,UAAUK,eAAiB,EAEhFkC,EACJN,GACAC,GACA3B,GACA4B,GACA3B,GACA4B,GACAC,GACAC,EAIF,QAFyBtC,UAAUC,UAAUE,MAAM,cAEzBoC,CAC5B,CAI8CC,GAEvC,SAAShzG,EAAoBukB,GAClC,IAAKA,EACH,OAAO,KAGT,MAAMtnB,EAAUsnB,EAAO0uF,WAAW,KAAMT,EAAmB,CAAEU,oBAAoB,QAAStsH,GAC1F,IAAKqW,EAEH,OADA7Y,OAAOwV,QAAQgZ,eAAe,uBACvB,KAGT3V,EAAQk2G,OAAS,CAAC,EAElB,MAAMC,EAAWC,yBAAyBh1H,UAAU+vB,QAapD,OAZAnR,EAAQmR,QAAU,WAEhB,OADA7vB,KAAK40H,OAAS,CAAC,EACRC,EAASvuH,MAAMtG,KACxB,EAEA0e,EAAQS,IAAM,SAAUxR,EAAKC,GACvB5N,KAAK40H,OAAOjnH,KAASC,IACvB5N,KAAK2N,GAAOC,EACZ5N,KAAK40H,OAAOjnH,GAAOC,EAEvB,EAEO8Q,CACT,C,8ICzBO,IAAKpW,EAAoB,SAApBA,GAAoB,OAApBA,EAAoB,kBAApBA,EAAoB,cAApBA,EAAoB,oBAApBA,CAAoB,MAoCzB,SAASysH,EAAwBptH,GAAsD,IAArD,MAAEjB,EAAK,MAAEC,EAAK,OAAE7C,GAAmC6D,EAC1F,MAAO,CACLqtH,YAAalxH,EAAO4C,GAAOsuH,YAC3BC,YAAanxH,EAAO4C,GAAOuuH,YAC3BC,UAAWpxH,EAAO4C,GAAOwuH,UAAUvuH,GACnCwuH,SAAUrxH,EAAO4C,GAAOyuH,SAASxuH,GAErC,CAEO,SAASyuH,EACdC,GAKA,IAJAC,EAAqBl0H,UAAAnB,OAAA,QAAAoI,IAAAjH,UAAA,IAAAA,UAAA,GACrBsD,EAAmBtD,UAAAnB,OAAA,QAAAoI,IAAAjH,UAAA,GAAAA,UAAA,GAAG,CACpBsmC,MAAO,SAGT,MAAM6tF,EAAaxrF,EAAAA,GAAAA,sBAA4BsrF,GAEzC9/E,EAAQggF,EAAWzwH,WACnB0wH,GAAgBC,EAAAA,EAAAA,IAAqBF,EAAY7wH,GAEvD,GAAI4wH,EAAuB,CACzB,IAAInyB,EAAS,GAQb,OANI5tD,GAAS,EACX4tD,EAAS,MACA5tD,GAAS,KAClB4tD,EAAS,OAGH,GAAEqyB,KAAiBryB,GAC7B,CAEA,OAAOqyB,CACT,CAEO,SAASE,EAAiBttH,GAQ9B,IAR+B,MAChCwF,EAAK,cACL+nH,EAAa,iBACbC,EAAmB,GAKpBxtH,EACKytH,EAAe,GACf1yB,EAAS,GAEb,QAAsB96F,IAAlBstH,EACFE,EAAe/0G,EAAAA,GAAKkD,MAAM,CAAEpW,QAAOqW,eAAgB,QAC9C,CACL,MAAM6xG,EAAYh1G,EAAAA,GAAKiiF,gBAAgBn1F,EAAQo0F,EAAAA,GAAkB2zB,GAAgB,EAAG5zB,EAAAA,GAAUG,SAC9F2zB,EAAe9xG,WAAW+xG,EAAU9/E,UAAU,EAAG8/E,EAAU71H,OAAS,IAAIsE,WACxE4+F,EAAS2yB,EAAU9/E,UAAU8/E,EAAU71H,OAAS,EAClD,CAEA,MAAO81H,EAAaC,GAAiBH,EAAa97F,MAAM,KAExD,QAAsB1xB,IAAlB2tH,EAA6B,MAAQ,GAAED,IAAc5yB,IAEzD,IAAI8yB,EAAyBD,EAK7B,OAJyB,IAArBJ,GAAsE,MAA5CI,EAAcA,EAAc/1H,OAAS,KACjEg2H,EAAyBD,EAAc31H,MAAM,GAAI,IAG3C,GAAE,CAAC01H,EAAaE,GAAwBpyH,KAAK,OAAOs/F,GAC9D,CAEO,SAAS+yB,EAAwBz2E,GACtC,MAAO,CACLC,MAAO,CACLs1E,YAAamB,IAAAA,MACblB,YAAakB,IAAS12E,GAAU,KAChCy1E,UAAW,CACTnwG,QAASoxG,IAAS12E,GAAU,IAC5BuhD,MAAOm1B,IAAS12E,GAAU,KAC1B8a,SAAU47D,IAAS12E,GAAU,MAE/B01E,SAAU,CACRpwG,QAASoxG,IAAS12E,GAAU,KAC5BuhD,MAAOm1B,IAAS12E,GAAU,KAC1B8a,SAAU47D,IAAAA,QAGdhlC,KAAM,CACJ6jC,YAAamB,IAAAA,KAAc,KAC3BlB,YAAakB,IAAS12E,GAAU,KAChCy1E,UAAW,CACTnwG,QAASoxG,IAAS12E,GAAU,KAC5BuhD,MAAOm1B,IAAS12E,GAAU,KAC1B8a,SAAU47D,IAAS12E,GAAU,MAE/B01E,SAAU,CACRpwG,QAASoxG,IAAAA,MACTn1B,MAAOm1B,IAAAA,MACP57D,SAAU47D,IAAAA,QAIlB,C,kcC3IA,MAAMC,EAAiB,MACjBC,EAAgB,KAChBC,EAKD,CAAC,EAGN,SAASC,EAAwB5uH,GAA6C,IAA5C,IAAE6uH,EAAG,IAAEC,GAAmC9uH,EAC1E,MAAM+uH,EAASF,EACTG,EAASF,EACf,OAAOp3G,KAAK+E,MAAMsyG,EAASN,KAAoB/2G,KAAK+E,MAAMuyG,EAASP,EACrE,CAEA,SAASQ,EAAsBxuH,GAQ5B,IAR6B,WAC9ByuH,EAAU,OACVjrF,EAAM,UACNn3B,GAKDrM,EACC,MAAQ,GAAEwjC,KAAUn3B,KAAaoiH,GACnC,CAsCA,SAASC,EAAqBpnH,GAc3B,IAd4B,WAC7BmnH,EAAU,OACVjrF,EAAM,UACNn3B,EAAS,YACTsiH,EAAW,UACXC,EAAS,aACTC,GAQDvnH,EACC,MAAMxO,EAAK01H,EAAuB,CAAEC,aAAYjrF,SAAQn3B,eAxB1D,WACE,MAAMvO,EAAMD,KAAKC,MACjBjD,OAAOC,KAAKozH,GAAmB/tH,SAAS2uH,IAClCZ,EAAkBY,GAAqBC,SAAWjxH,EAAMmwH,UACnDC,EAAkBY,EAC3B,GAEJ,CAkBEE,GACAd,EAAkBp1H,GAAM,CACtB61H,cACAC,YACAC,eACAE,SAAUlxH,KAAKC,MAEnB,CAEA,MAAMmxH,EAAuB,EACvBC,EAAuB,EACvBC,EAAuB,GAEtB,SAAS12E,EAA4BxmB,GAMzC,IAN0C,WAC3Csa,EAAa,EAAC,YACd3jC,GAIDqpB,EACC,MAAM,cAAEa,GAAkBlqB,EAAYZ,SAChConH,EAAiBt8F,EAAcrE,OAC/Bu+B,EACJzgB,EAAa,GAAkC,IAA7B6iF,EAAepiE,UAC7B/1C,KAAKqF,IAAI8yG,EAAe/iF,SAAU,EAAI,EAAIE,GAC1C6iF,EAAepiE,UAMrB,MAAO,CACLzU,aALmB62E,EAAe/iF,SAAWE,EAM7CiM,eALqBvhC,KAAKqF,IAAI8yG,EAAep5G,OAASu2B,EAAY0iF,GAMlEI,eALqBp4G,KAAKwF,IAAIyyG,EAAsBj4G,KAAKqF,IAAI0wC,EAAYzgB,EAAY4iF,IAOzF,CAEO,SAAS7iF,EAAqBpa,GAQlC,IARmC,WACpCqa,EAAa,EAAC,YACd3jC,EAAW,YACX0mH,GAAc,GAKfp9F,EACC,MAAM,aAAEqmB,EAAY,eAAEC,EAAc,eAAE62E,GAAmB52E,EAA6B,CAAElM,aAAY3jC,gBAE9FyjC,EAAWkM,EAAgC,EAAjBC,EAAqB62E,EACrD,IAAKC,EACH,OAAOjjF,EAET,MAAMkjF,EAAqBljF,EAAW,IAAM,GAAK,IACjD,OAAOp1B,KAAK2E,MAAMywB,EAAWkjF,GAAsBA,CACrD,CAEO,SAASpgF,EAAyBntC,GACvC,MAAM,aAAEu2C,EAAY,eAAEC,GAAmBC,EAA6B,CACpE7vC,YAAa5G,EAAWwpB,eACxB+gB,WAAYvqC,EAAWuqC,aAEzB,OAAOgM,EAAgC,EAAjBC,CACxB,CAEO,SAASvJ,EAAgBjtC,GAAiC,IAAdga,IAAKhjB,UAAAnB,OAAA,QAAAoI,IAAAjH,UAAA,KAAAA,UAAA,GAQtD,MAAMw2H,EAAkBv4G,KAAKwF,IAAI,EAAG0yB,EAAyBntC,GAAc,GAC3E,OAAOga,IAAUwzG,EAAkBA,CACrC,CAEA,MAAMC,EAA+B,KAE/BC,EAA8C,CAAC,EAC/CC,EAAgD,GAEhDC,EAA0BrqH,GAAgBmqH,EAAgCnqH,IAAQ,KAClFsqH,EAAuBA,CAACtqH,EAAaC,KACzC,IAAKmqH,EAAoC39F,SAASzsB,KAChDoqH,EAAoC1nF,QAAQ1iC,GACxCoqH,EAAoC93H,OALN,IAK8C,CAC9E,MAAMi4H,EAAYH,EAAoC5oC,MAClD+oC,UACKJ,EAAgCI,EAE3C,CAGFJ,EAAgCnqH,GAAOC,CAAK,EAGvC,SAASgxE,EAA6BrkD,GAQ1C,IAR2C,kBAC5CskD,EAAiB,iBACjB7oB,EAAgB,YAChBhlD,GAKDupB,EACC,MAAM49F,EAA4BzjF,EAAsB,CAAE1jC,gBACpD4pF,EAAqB/b,EAAoB7oB,EACzC5uD,EAAY,GAAE+wH,KAA6Bv9B,IACjD,IAAIw9B,EAAgB,EAChB55C,EAAoB,EACpB65C,EAAkBL,EAAuB5wH,GACzCkxH,EAAY,EAIhB,IAHI19B,GAAsBu9B,IACxBE,EAAkBz9B,EAAqBu9B,GAEd,OAApBE,GAA0B,CAC/BC,GAAa,EACb,MAAMvmD,EAAY,IAClByM,GAAqB45C,EACrB,MAAM3jF,EAAWC,EAAsB,CAAEC,WAAY6pC,EAAmBxtE,cAAa0mH,aAAa,IAC5Fa,EAAe39B,EAAqBnmD,EAS1C,GARI8jF,EAAexmD,EACjBqmD,EAAgBA,EAAgB,EAAoB,EAAhBA,EAAoBP,EAC/CU,GAAgBxmD,EACzBqmD,EAAgBA,EAAgB,EAAoB,EAAhBA,GAAqBP,EAEzDQ,EAAkB75C,EAGF,MAAd85C,EAYF,OAXAnvH,EAAAA,EAAAA,IAAiB,IAAIC,MAAM,0DAA2D,CACpFC,MAAO,CACLivH,YACAF,gBACAx9B,qBACAnmD,WACA8jF,eACA/5C,oBACAxtE,YAAaA,EAAY9G,SAAS,CAAC,SAAU,aAG1Cs0E,CAEX,CAIA,OAFAy5C,EAAqB7wH,EAAUixH,GAExBA,CACT,CAEO,SAASG,EAAmBxmF,GAQhC,IARiC,WAClCymF,EAAU,MACVC,EAAK,UACLjkH,GAKDu9B,EACC,MAAM2mF,EAAaF,EAAa,EAEhC,OAD0B,CAACC,EAAMC,GAAaD,EAAMD,IAAatwH,MAAMlG,QAAoBoG,IAAVpG,IACvDy2H,EAAMC,GAAcD,EAAMD,GAAc/vE,EAAAA,GAAkBj0C,EACtF,CAyCO,SAAS8kC,EAA8B7F,GAQ3C,IAR4C,UAC7C8F,EAAS,QACTC,EAAO,MACP9vC,GAKD+pC,EACC,MAAQlM,KAAMkxF,EAAK,OAAE9sF,EAAM,UAAEn3B,EAAS,WAAE5B,EAAU,WAAEmrE,EAAU,mBAAE7pC,GAAuBxqC,EACjF0+G,EAAY1+G,EAAM+rC,gBAAkB,EAIpCkjF,EAA2Bp/E,IAAck/E,EAAM,IAAMj/E,IAAYi/E,EAAMA,EAAMz4H,OAAS,GAEtF44H,EAA0B,CAC9BhC,WAAY6B,EAAMz4H,OAClB2rC,SACAn3B,YACAsiH,YAAav9E,EACbw9E,UAAWv9E,GAEPq/E,EAvRR,SAA8BhrH,GAY3B,IAZ4B,WAC7B+oH,EAAU,OACVjrF,EAAM,UACNn3B,EAAS,YACTsiH,EAAW,UACXC,GAODlpH,EACC,MAAM5M,EAAK01H,EAAuB,CAAEC,aAAYjrF,SAAQn3B,cAClDsG,EAAQu7G,EAAkBp1H,GAChC,OAAI6Z,GAAOg8G,aAAeA,GAAeh8G,GAAOi8G,WAAaA,GAC3Dj8G,EAAMo8G,SAAWlxH,KAAKC,MAClB6U,EAAMg8G,cAAgBA,GAAeh8G,EAAMi8G,YAAcA,EACpDj8G,EAAMk8G,aAERl8G,EAAMk8G,aAAar/G,QACvBmhH,GAAuBA,GAAsBhC,GAAegC,GAAsB/B,KAGhF,IACT,CA8PsBgC,CAAsBH,GAC1C,GAAIC,EACF,OAAOA,EAET,IAAK96C,GAAcnrE,IAAeC,EAAAA,GAAWC,MAAO,CAClD,GAAI6lH,EACF,OAAOF,EAET,MAAMO,EAAmBvwE,EAAAA,GAAkBj0C,GACrCykH,EAAYR,EAAM,GAClBxrF,EAAWwrF,EAAMA,EAAMz4H,OAAS,GAChCk5H,EAAmB95G,KAAKg1B,MAAM6kF,EAAY1/E,GAAay/E,GACvDG,EAAkB/5G,KAAKg1B,MAAMoF,EAAUvM,GAAY+rF,GACzD,MAAO,IACFp5H,MAAMk1B,KAAK,CAAE90B,OAAQk5H,IACrBzrH,KAAI,CAACgkB,EAAGzvB,IAAUi3H,GAAaj3H,EAAQ,GAAKg3H,IAC5C1lF,aACAmlF,KACA74H,MAAMk1B,KAAK,CAAE90B,OAAQm5H,IAAmB1rH,KAAI,CAACgkB,EAAGzvB,IAAUirC,GAAYjrC,EAAQ,GAAKg3H,IAE1F,CAEA,MAAMI,EAAoBT,EACtBjvH,EAAM2vF,iBArFZ,SAA6BpmD,GAU1B,IAV2B,iBAC5BomF,EAAgB,eAChBC,EAAc,aACdC,EAAY,mBACZrlF,GAMDjB,EACC,MAAMsG,GAAYgc,EAAAA,EAAAA,IAAsB8jE,GAClC7/E,GAAU+b,EAAAA,EAAAA,IAAsB+jE,GAChCE,EAAqBH,EAAmBE,EAAa,GACrDE,EAAkBF,EAAav5H,OAAS,GAAKu5H,EAAaA,EAAav5H,OAAS,GAAKs5H,EACrFL,GAAY1jE,EAAAA,EAAAA,IAAsBgkE,EAAa,IAC/CtsF,GAAWsoB,EAAAA,EAAAA,IAAsBgkE,EAAaA,EAAav5H,OAAS,IAC1E,OAAOspF,EAAAA,EACc,CACjB/jD,MACEi0F,IAAuBlwC,EAAAA,EAAkB/vC,IAAcA,EAAUz0C,aAAeovC,GAC5Eo1C,EAAAA,EAAwB/vC,GAAY,GACpCA,EACN6K,IAAKq1E,EAAkBnwC,EAAAA,EAAwB9vC,EAAS,GAAKA,IAE9D7hC,QAAQ4vB,IACP,MAAMivF,EAAMjvF,EAAKgxD,UAAY,IAAkC,GAA3BhxD,EAAK4pF,oBACzC,OACG7nC,EAAAA,EAAyB/hD,EAAM,CAAEhC,MAAO+jD,EAAAA,EAAmB2vC,GAAY70E,IAAKklC,EAAAA,EAAiBr8C,MAC9FssF,EAAarxH,MAAMwxH,GACjBpD,EAAyB,CACvBC,IAAKmD,EAAW3uH,EAAAA,GAAMolH,qCAAqC,IAAInqH,KAAgB,IAAX0zH,IACpElD,SAEH,GAGT,CAiDMmD,CAAqB,CACnBN,iBAAkB9/E,EAClB+/E,eAAgB9/E,EAChB+/E,aAAcd,EACdvkF,uBAGA0lF,EAA0C,GAArB1lF,EACrB2lF,EAAsBj6H,MAAMk1B,KAAK,CAAE90B,OAAQooH,IAAa36G,KAAI,CAACgkB,EAAGxP,IAAMA,EAAIwmC,EAAAA,GAAkBj0C,KAC5FslH,EAA4B/uH,EAAAA,GAAMolH,qCAAqC,IAAInqH,KAAiB,IAAZuzC,IAChFy9E,EAAeoC,EAAkB59E,SAASjU,IAC9C,MAEMwyF,EADJxyF,EAAKgxD,UAAY,IAAOxtF,EAAAA,GAAMolH,qCAAqC5oF,GAAmC,GAA3BA,EAAK4pF,oBAC7CyI,EACrC,OAAOC,EAAoBpsH,KAEzB,CAACusH,EAAYh4H,KACV,CAAC+lC,EAAAA,GAAUpoB,EAAGooB,EAAAA,GAAUQ,GAAIR,EAAAA,GAAUS,IAAIrO,SAAS3lB,IAAcxS,EAAQ,GAAK,KAAO,GACtF+3H,EACAC,GACH,IAqBH,OAlBKrB,GACH3B,EAAar/G,QAAO,CAAC4vB,EAAMvlC,EAAOi4H,KAChC,MAAMC,EACJ3yF,GAAQgS,GACR+8E,EAAyB,CACvBC,IAAKhvF,EAAOx8B,EAAAA,GAAMolH,qCAAqC,IAAInqH,KAAY,IAAPuhC,IAChEivF,IAAKj9E,EAAYugF,IAEfK,EAA8B5gF,EAAYhS,GAAQgS,EAAY0gF,EAA4Bj4H,EAAQ,GACxG,OAAOk4H,GAAkBC,CAA2B,IAIxDtD,EAAsB,IACjB+B,EACH5B,iBAGKA,CACT,CAMO,SAAS5U,EAAyBltE,GAA8E,IAA7E,UAAEzhB,EAAS,MAAE/pB,GAA8DwrC,EACnH,MAAM,KAAE3N,EAAI,UAAE/yB,GAAc9K,EACtB+uH,EAAQn/E,EAA+B,CAC3CC,UAAWhS,EAAK,GAChBiS,QAASjS,EAAKA,EAAKvnC,OAAS,GAC5B0J,UAEI6vC,EAAYk/E,EAAM,GAClBj/E,EAAUi/E,EAAMA,EAAMz4H,OAAS,GAC/Bo6H,EAAgB3B,EAAMz4H,OAAS,EACrC,GAAIyzB,GAAa,GAAKA,GAAa2mG,EAAe,CAChD,MAAM5B,EAAap5G,KAAK+E,MAAMsP,GACxBulG,EAAmBT,EAAoB,CAAEC,aAAYC,QAAOjkH,cAClE,OAAOikH,EAAMD,IAAe/kG,EAAY+kG,GAAcQ,CACxD,CACA,MAAMqB,EAAgB5mG,EAAY,EAC5B6mG,GAAkB9gF,EAAUD,GAAak/E,EAAMz4H,OAC/Cu6H,EAA0BF,EAC5Bj7G,KAAKQ,IAAI6T,GAAa6mG,GACrB7mG,EAAY2mG,GAAiBE,EAClC,OAAOl7G,KAAK2E,MAAMs2G,EAAgB9gF,EAAYghF,EAA0B/gF,EAAU+gF,EACpF,CAEO,SAAS52G,EAAyB4xB,GAA8E,IAA7E,UAAEhzC,EAAS,MAAEmH,GAA8D6rC,EACnH,MAAM,KAAEhO,EAAI,UAAE/yB,GAAc9K,EACtB+uH,EAAQn/E,EAA+B,CAC3CC,UAAWhS,EAAK,GAChBiS,QAASjS,EAAKA,EAAKvnC,OAAS,GAC5B0J,UAEI6vC,EAAYk/E,EAAM,GAClBj/E,EAAUi/E,EAAMA,EAAMz4H,OAAS,GAC/Bo6H,EAAgB3B,EAAMz4H,OAAS,EACrC,GAAIuC,GAAak2H,EAAM,IAAMl2H,GAAak2H,EAAMA,EAAMz4H,OAAS,GAAI,CACjE,MAAM04H,EAAan2H,IAAci3C,EAAU4gF,EAAgB3B,EAAM72H,WAAW2lC,GAASA,EAAOhlC,IACtFy2H,EAAmBT,EAAoB,CAAEC,WAAYE,EAAa,EAAGD,QAAOjkH,cAElF,OAAOkkH,GAD6BD,EAAMC,GAAcn2H,GAAay2H,CAEvE,CACA,MAAMqB,EAAgB93H,EAAYg3C,EAC5B+gF,GAAkB9gF,EAAUD,GAAak/E,EAAMz4H,OACrD,OAAOq6H,IACA9gF,EAAYh3C,GAAa+3H,EAC5BF,GAAiB73H,EAAYi3C,GAAW8gF,CAC9C,CAGO,SAASzwC,EAAcg1B,GAC5B,GAA+B,IAA3BA,EAAUt+G,QAAQ,KAAY,CAChC,MAAMorC,EAASkzE,EAAU9oE,UAAU,GAEnC,OAAI2S,EAAAA,GAAQ/c,GACH94B,EAAAA,GAAW47B,OACS,IAAlB9C,EAAO3rC,OACT6S,EAAAA,GAAWs2D,MAEXt2D,EAAAA,GAAWq2D,OAEtB,CACA,OAAOr2D,EAAAA,GAAWC,KACpB,CAwBOrL,eAAeq4E,EAA8B9pC,GAKZ,IALa,sBACnD6pC,EAAqB,UACrBrrE,EAAS,QACT/P,EAAO,UACP6qG,GACoCt5D,EACpC,MAAMupE,EA5BD,SAA4C7pE,GAMhD,IANiD,sBAClDmqC,EAAqB,UACrBrrE,GAIDkhC,EACC,MAAM,SAAEjgC,GAAaoqE,EACf26C,EAAuB/kH,EAAS7L,MAAKgsC,IAAA,IAAC,KAAElgC,GAAMkgC,EAAA,MAAc,oBAATlgC,CAA0B,IAEnF,OADgB8kH,GAAsBzkH,QAAQ+jB,MAAM,MAAQ,IAC7CrsB,KAAKk+B,IAAM,CACxBA,SACA/4B,WAAYi3E,EAAcl+C,GAC1Bn3B,eAEJ,CAa+BimH,CAAoC,CAAE56C,wBAAuBrrE,cAE1F,GAAI+qG,EAAqBv/G,OAAS,EAAG,CACnC,MAAM8tE,EAAWyxC,EAAqB9xG,KAAIgsC,IAAA,IAAC,OAAE9N,EAAM,WAAE/4B,EAAU,UAAE4B,GAAWilC,EAAA,OAC1ElvC,EAAAA,EAAM0oB,IAAI,CACR0Y,SACA/4B,aACA4B,YACA/P,UACA6qG,aACA,IAEJ,OAAOpyF,QAAQnb,IAAI+rE,EACrB,CACA,OAAO5wD,QAAQw9G,QAAQ,GACzB,CAeO,SAAS/iF,EAAW+C,GAWN,IAXO,QAC1Bj8B,EAAO,WACPisB,EAAU,UACV5jC,EAAS,MACT4C,EAAK,aACLmuC,EAAY,cACZC,EAAa,kBACbI,EAAiB,sBACjBH,EAAqB,YACrBzc,GAAc,EAAK,gBACnBksE,GAAkB,GACD9sD,EACjB,MAAMlC,EAAa9N,EAAWyN,qBAAqBrxC,GAC7CqD,EAAarD,EAAU2C,SACvB,cAAEwxB,EAAa,kBAAEI,IAAsBjd,EAAAA,EAAAA,IAAuBjU,EAAWwpB,gBACzExjB,EAAWmrB,EAAcD,EAAoBJ,GAC7C,OAAE3c,GAAW2c,EAAc2Q,QAEjC,IAAKlB,EAAWgtC,2BAA2B5wE,GACzC,OAAO,EAGT,MAAMkxC,EAAQtN,EAAWwxE,gBAAgBp1G,GACnC4vB,EAAS5vB,EAAUoQ,MAAMqH,EAAEi6B,GAAcruC,EAAW6gB,WACpD2vG,EAAgBjkG,EAAS,GAAKA,GAAUmhB,EAC9C,GAAI8iF,EAAe,CACjB,MAAMp8G,EAAImY,EAASvmB,EAASqW,KAAKjf,MACjC,IAAIi0B,EAAAA,EACF,CACE3d,GAAIU,EACJR,GAAIQ,EACJT,GAAI3N,EAASkW,IAAI7e,OACjBwW,GAAI7N,EAASkW,IAAI7e,OAASswC,EAC1Brc,YAAand,EAAO+1D,OAEtBvtE,GACA8gB,OAAOnJ,GAETy5B,IAAoBz5B,EAAS+5B,EAC/B,CAEA,MAAMoiF,EAAc9zH,EAAUoQ,MAAMsH,EACjC2E,SACA/iB,QACAuM,MAAK,CAACC,EAAGC,IAAMD,EAAIC,IAEtB,GAAc,OAAVmrC,KAAoB4iF,EAAY,IAAM5iF,GAASA,GAAS4iF,EAAY,IACtE,OAAOD,EAGT,MAAME,EAAU/zH,EAAUoQ,MAAMsH,EAAEw5B,GAC5Bx5B,EAAIY,KAAK2E,MAAM82G,EAAU1qH,EAASkW,IAAI7e,QAC5C,IAAIg0B,EAAAA,EACF,CACE3d,GAAI1N,EAASqW,KAAKjf,MAClBwW,GAAI5N,EAASqW,KAAKjf,MAAQswC,EAC1B/5B,GAAIU,EACJR,GAAIQ,EACJid,YAAand,EAAO+1D,OAEtBvtE,GACA8gB,OAAOnJ,GACT,MAAMq8G,EAAkBpxH,EAAMkJ,aAAeC,EAAAA,GAAW47B,QAAU/kC,EAAMsxB,WAAa,KAAQ,EAAI,EA+CjG,OA5BA,IAAIzV,EAAAA,EACF,CACEK,KAlBEzb,EAAW+M,QAAUE,EAAAA,GAAUG,YAAe+jB,EAQ1C,GAAEza,EAAAA,GAAKkD,MAAM,CACnBpW,MAAOqqC,EACPhd,UAAWtxB,EAAMsxB,UACjBpoB,WAAYlJ,EAAMkJ,WAClBoR,eAAgB+zB,IAAwBC,KAAWlxC,EAAU+rE,sBAAmBzqE,EAAY,OACzFo/F,EAAkB,IAAM,KAZnB,GAAE3mF,EAAAA,GAAKkD,MAAM,CACnBpW,OAAOihC,EAAAA,EAAAA,IAAuB,CAAE3R,OAAQ+a,EAAOnJ,KAAM1kC,EAAW4wH,gBAChE//F,UAAWtxB,EAAMsxB,UACjBpoB,WAAYlJ,EAAMkJ,WAClBoR,eAAgB,OAclBzF,EACEpO,EAASqW,KAAKjf,MACd4I,EAASmW,MAAMqqB,KAAK9E,OAAOrlB,KAC3BqxB,GACCvc,EAAcyQ,EAAAA,GAAOpkB,EAAImzG,EAAkBpzG,EAAAA,GAAQ+b,KACtDrd,QAASkV,EACL/V,EAAAA,EAAK0e,2BAA2B,UAAW5I,EAAkB/U,MAAMqqB,KAAK9qB,KAAKO,SAC7E,CACEC,IAAKqB,EAAAA,GAAQ+b,IACbnd,MAAOoB,EAAAA,GAAQ+b,IACfld,OAAQmB,EAAAA,GAAQ+b,IAChBjd,KAAMkB,EAAAA,GAAQ+b,KAGlBjlB,IACA2H,aAAcsQ,EAAAA,GAAaC,OAC3B1Q,UAAW1H,EAAOmyF,UAClBhqF,WAAYnI,EAAOy6F,oBACnBlzF,KAAMN,EAAAA,EAAK0e,2BAA2B,OAAQ,IAAK9zB,EAASmW,MAAMqqB,KAAK9qB,KAAM3P,MAAO,SACpF+P,WAAY9V,EAASmW,MAAMqqB,KAAK9qB,KAAKI,YAGzCnf,GACA8gB,OAAOnJ,IAEF,CACT,CAOO,SAASksB,EAAc5E,GACvBA,IAELA,EAAOx+B,MAAQ,EACfw+B,EAAOv+B,OAAS,EAChBu+B,EAAO7vB,MAAM3O,MAAQ,MACrBw+B,EAAO7vB,MAAM1O,OAAS,MACxB,CAEO,SAAS4yC,EAAcyB,GAA+E,IAA9E,OAAEnC,EAAM,cAAEze,GAAkE4gB,EACzG,MAAM,OAAEv9B,GAAW2c,EAAc2Q,QACjC,OAAe,IAAX8N,EACKp7B,EAAO2jC,WAETvI,EAAS,EAAIp7B,EAAO46F,eAAiB56F,EAAO06F,cACrD,CAEO,SAASj1F,EAAKg5B,GAAuF,IAAtF,KAAEp4C,EAAI,IAAET,EAAG,eAAE8f,GAAuE+4B,EACxG,OAAOl8B,EAAAA,GAAKkD,MAAM,CAChBpW,MAAOzJ,EACP82B,UAAWr2B,EAAKq2B,UAChBpoB,WAAYjO,EAAKiO,WACjBoR,eAAgBA,GAEpB,CAYO,SAASi1B,EAA8B+hF,GAQ5B,IAR6B,YAC7C9hF,EAAW,UACXC,EAAS,KACTx0C,GAKDq2H,EACC,MAAM9zD,EAAehuB,EAAcC,EAC7B8hF,EAAgD,KAA/B/hF,EAAcC,EAAY,GAC3C3rB,EAAO05C,EAAe,EAAI,IAAMA,EAAe,EAAI,IAAM,GACzDg0D,EAAuB,GAAEn3G,EAAM,CACnCpf,OACAT,IAAKkb,KAAKQ,IAAIq7G,GACdj3G,eAAgB,OAOlB,MAAO,CACLhC,OAAQklD,EACR/sB,OAP0B,GAAE3sB,IAAOzJ,EAAM,CACzCpf,OACAT,IAAKkb,KAAKQ,IAAIsnD,SACTg0D,KAKLhhF,cAAgB,GAAE1sB,IAAO0tG,IAE7B,CACO,SAASrhF,EAAeshF,GAA4B,IAA3B,KAAEx2H,GAAuBw2H,EACvD,MAAMz4F,EAA8B,CAAEiX,aAAc,KAAMC,kBAAmB,MAC5D/1B,OAAO0pB,SAAS5oC,EAAKw0C,aAEpCzW,EAAOiX,aAAeV,EAA+B,CACnDt0C,OACAu0C,YAAav0C,EAAKq2B,UAClBme,UAAWx0C,EAAKw0C,aAKpB,GADsBt1B,OAAO0pB,SAAS5oC,EAAK6oC,aAAe7oC,EAAK6oC,aAAe7oC,EAAKq2B,UAChE,CACjB,MAAM4e,EAAoBX,EAA+B,CACvDt0C,OACAu0C,YAAav0C,EAAK6oC,WAClB2L,UAAWx0C,EAAKq2B,YAElB0H,EAAOkX,kBAAoB,IACtBA,EACHO,OAAS,OAAMP,EAAkBO,SAErC,CAEA,OAAOzX,CACT,CAEO,SAAS04F,EAAyBhqH,GACvC,MAAO,CACLq7B,EAAAA,GAA2BoiB,UAC3BpiB,EAAAA,GAA2BqiB,WAC3BriB,EAAAA,GAA2BmiB,aAC3Bz0B,SAAS/oB,EACb,CAEO,SAASsuC,EAA4B27E,GAOzC,IAP0C,2BAC3CjqH,EAA0B,cAC1BuuC,GAKD07E,EACC,MAAMC,EAAuBF,EAAyBhqH,GAChDmqH,EACJnqH,IAA+Bq7B,EAAAA,GAA2BC,WAAaiT,EAAgB,EACnF67E,EACJpqH,IAA+Bq7B,EAAAA,GAA2BkiB,WAAahP,EAAgB,EAEzF,OAAO27E,GAAwBC,GAAkCC,CACnE,CAEO,MAAM5zD,EAAsB,cAC5B,SAASD,KACd,MAAgD,OAAzC58D,EAAAA,GAAMsmF,UAAUzpB,EACzB,CAQO,SAAS4lB,GAAoBp8E,GAClC,OAAOA,IAA+Bq7B,EAAAA,GAA2ByS,SACnE,CAEO,MAAMuqC,GAAmBgyC,IAM1B,IAN2B,KAC/B/lH,EAAI,iBACJtH,GAIDqtH,EACkBrtH,EAAiB2/C,iBACzBzlD,SAASzG,IAChB,GAAIA,EAAQkpD,WAAalpD,EAAQ2H,SAAS1G,MAAM4S,OAASA,EAAM,CAC7D,MAAM+c,EAAO5wB,EAAQ4wB,OACfjpB,EAAWk9C,EAAAA,EAAahxC,GAAM4b,WAClC,IACKzvB,EAAQ2H,SAAS1G,MACpB4S,QAEF+c,GAEF5wB,EAAQuX,QAAQ5P,EAClB,IACA,EAGSu4D,GAA6CmrB,IAKxD,MAAM,2BAAE97E,EAA0B,SAAEi5D,EAAQ,QAAEH,GAAYgjB,EAE1D,OACE7iB,GACAH,GAAS/vC,SAASotB,EAAAA,GAAgB6iB,QAClCh5D,GACA,CACEq7B,EAAAA,GAA2ByS,UAC3BzS,EAAAA,GAA2BkiB,UAC3BliB,EAAAA,GAA2BoiB,UAC3BpiB,EAAAA,GAA2BmiB,YAC3BniB,EAAAA,GAA2BqiB,YAC3B30B,SAAS/oB,EAA2B,C,8FChxBnC,SAASsqH,EAAgBjjB,GAC9B,MAAMkjB,EAAWC,EAAiBnjB,GAClC,IAAIt7F,EAAqB,EACrB0+G,EAAqB,EACrBhvH,EAAqB,EACrBD,EAAqB,IAmBzB,OAhBwB,IAApB+uH,EAAS37H,QAAoC,IAApB27H,EAAS37H,QACpCmd,EAAI,KAAOw+G,EAAS,GAAKA,EAAS,GAClCE,EAAI,KAAOF,EAAS,GAAKA,EAAS,GAClC9uH,EAAI,KAAO8uH,EAAS,GAAKA,EAAS,GAElC/uH,EAAwB,IAApB+uH,EAAS37H,OAAe,KAAO27H,EAAS,GAAKA,EAAS,GAAK/uH,GAGlC,IAApB+uH,EAAS37H,QAAoC,IAApB27H,EAAS37H,SAC3Cmd,EAAI,KAAOw+G,EAAS,GAAKA,EAAS,GAClCE,EAAI,KAAOF,EAAS,GAAKA,EAAS,GAClC9uH,EAAI,KAAO8uH,EAAS,GAAKA,EAAS,GAElC/uH,EAAwB,IAApB+uH,EAAS37H,OAAe,KAAO27H,EAAS,GAAKA,EAAS,GAAK/uH,GAG1D,CAAEuQ,EAAG0G,OAAO1G,GAAI0+G,EAAGh4G,OAAOg4G,GAAIhvH,EAAGgX,OAAOhX,GAAID,EAAGwS,KAAKqF,IAAIrF,KAAK2E,MAAOF,OAAOjX,GAAK,IAAO,KAAO,IAAK,GAC5G,CA4CO,SAASkvH,EAAgB7jH,GAA4B,IAAf8jH,EAAK56H,UAAAnB,OAAA,QAAAoI,IAAAjH,UAAA,IAAAA,UAAA,GAChD,MAAMgc,EAAIlF,EAAMkF,EAAE7Y,SAAS,IACrBu3H,EAAI5jH,EAAM4jH,EAAEv3H,SAAS,IACrBuI,EAAIoL,EAAMpL,EAAEvI,SAAS,IACrBm0G,EAAY,IAAMt7F,EAAE8kG,SAAS,EAAG,KAAO4Z,EAAE5Z,SAAS,EAAG,KAAOp1G,EAAEo1G,SAAS,EAAG,KAEhF,OAAK8Z,GAAqB,IAAZ9jH,EAAMrL,EAIZ,GAAE6rG,IAvBL,SAAoBsjB,GACzB,OAAO38G,KAAKwF,IAAIxF,KAAKqF,IAAIrF,KAAK2E,MAAc,IAARg4G,GAAc,KAAM,GACrDz3H,SAAS,IACT29G,SAAS,EAAG,IACjB,CAmBwB+Z,CAAW/jH,EAAMrL,KAH9B6rG,CAIX,CAwCO,SAASwjB,EAAWhkH,GACzB,MAAMkF,EAAIlF,EAAMkF,EAAI,IACd0+G,EAAI5jH,EAAM4jH,EAAI,IACdhvH,EAAIoL,EAAMpL,EAAI,IAEdi4F,EAAI1lF,KAAKwF,IAAIzH,EAAG0+G,EAAGhvH,GACnB2f,EAAIs4E,EAAI1lF,KAAKqF,IAAItH,EAAG0+G,EAAGhvH,GACvB8S,EAAI6M,IAAMs4E,IAAM3nF,GAAK0+G,EAAIhvH,GAAK2f,EAAIs4E,IAAM+2B,EAAI,GAAKhvH,EAAIsQ,GAAKqP,EAAI,GAAKrP,EAAI0+G,GAAKrvG,GAElF,MAAO,CACL7M,EAAG,IAAMA,EAAI,EAAIA,EAAI,EAAIA,GACzBojB,EAAG+hE,EAAIt4E,EAAIs4E,EAAI,EACfA,EAAGA,EACHl4F,EAAGqL,EAAMrL,EAEb,CAoCO,SAASsvH,EAAWjkH,GACzB,MAAMmsB,EAAI,SAACsU,GAAS,IAAEgqD,EAACvhG,UAAAnB,OAAA,QAAAoI,IAAAjH,UAAA,GAAAA,UAAA,IAAIu3C,EAAIzgC,EAAM0H,EAAI,IAAM,EAAC,OAAK1H,EAAM6sF,EAAI7sF,EAAM6sF,EAAI7sF,EAAM8qB,EAAI3jB,KAAKwF,IAAIxF,KAAKqF,IAAIi+E,EAAG,EAAIA,EAAG,GAAI,EAAE,EAErH,MAAO,CACLvlF,EAAGiC,KAAK2E,MAAa,IAAPqgB,EAAE,IAChBy3F,EAAGz8G,KAAK2E,MAAa,IAAPqgB,EAAE,IAChBv3B,EAAGuS,KAAK2E,MAAa,IAAPqgB,EAAE,IAChBx3B,EAAGwS,KAAK2E,MAAgB,IAAV9L,EAAMrL,GAAW,IAEnC,CA6BO,SAASuvH,EAAiBlkH,GAC/B,MAAQ,QAAOA,EAAMkF,MAAMlF,EAAM4jH,MAAM5jH,EAAMpL,MAAMoL,EAAMrL,IAC3D,CASO,SAASwvH,EAAmBnkH,GACjC,MAAMokH,EAAa,gFAAgFC,KAAKrkH,IACjGjZ,EAAKM,EAAOR,EAAMi9H,EAAQ,KAAOM,GAAYj8H,MAAM,IAAM,CAAC,EAAG,EAAG,EAAG,GAAGqN,IAAIxN,QACjF,MAAO,CACLkd,EAAG0G,OAAOq5B,SAASl+C,GACnB68H,EAAGh4G,OAAOq5B,SAAS59C,GACnBuN,EAAGgX,OAAOq5B,SAASp+C,GACnB8N,EAAGiX,OAAOC,WAAWi4G,GAEzB,CAeO,SAASH,EAAiBW,GAC/B,OAAOA,EAASnjH,QAAQ,KAAM,GAChC,CAiBO,SAAS4wB,EAAkBuyF,GAAqC,IAAnBC,IAAUr7H,UAAAnB,OAAA,QAAAoI,IAAAjH,UAAA,KAAAA,UAAA,GAC5D,MACMw6H,EADQc,EAASF,GACET,EAAgBM,EAAmBG,GAAWC,GAAcD,EAErF,OAAIC,EACKb,EAEFA,EAASv7H,MAAM,EAAG,EAC3B,CAKO,SAASq8H,EAASF,GACvB,MAAMG,EAAU,CAAC,OAIjB,SALuDv7H,UAAAnB,OAAA,QAAAoI,IAAAjH,UAAA,KAAAA,UAAA,KAGrDu7H,EAAQp7H,KAAK,QAERo7H,EAAQx0H,MAAM7H,GAAek8H,EAASl8H,WAAWA,IAC1D,CAKO,SAASgxC,EAAiBkrF,GAC/B,OAAIE,EAASF,GACJN,EAAWG,EAAmBG,IA9PhCN,EAAWP,EAiQKa,GACzB,CAKO,SAASnrF,EAAmBn5B,EAAa0kH,EAAwBC,GACtE,MACO,SADCD,EAEGR,EAAiBD,EAAWjkH,IAlNlC,SAAyBA,GAA4B,IAAf8jH,EAAK56H,UAAAnB,OAAA,QAAAoI,IAAAjH,UAAA,IAAAA,UAAA,GAGhD,OAAO26H,EAFWI,EAAWjkH,GAEK8jH,EACpC,CAgNac,CAAgB5kH,EAAO2kH,EAEpC,CAsBO,SAASx7F,EAAwBnpB,GAA0B,IAAX8jH,EAAK56H,UAAAnB,OAAA,QAAAoI,IAAAjH,UAAA,GAAAA,UAAA,GAAG,EAE7D,OAAO26H,EAAgB,IADLJ,EAAgBzjH,GACKrL,EAAGmvH,IAAS,EACrD,CAKO,SAASpY,EAAiCh2G,GAC/C,OAAI8uH,EAAS9uH,GAAewuH,EAAiBC,EAAmBzuH,IACzDwuH,EAAiBT,EAAgB/tH,GAC1C,C,gDCjXO,MAAMyqC,EAAmB1wC,IAQ1B,IAR2B,UAC/BoC,EAAS,OACTiuB,EAAM,kBACNugB,GAKD5wC,EACC,MAAM7F,EAAU8I,SAAS2lD,eAAexmD,IACpCjI,GAAYy2C,GAAoBz2C,EAAQqU,MAAM6hB,SAAWugB,IAC3Dz2C,EAAQqU,MAAM6hB,OAASA,EACzB,C,2FCGK,MAAMwf,EAAoB7vC,IAkB3B,IAlB4B,gBAChC8vC,EAAe,gBACfwwD,EAAkB,EAAC,WACnB0f,EAAU,WACV18F,EAAU,UACVlkB,EAAS,MACT4C,EAAK,cACL+9G,EAAgB,EAAC,MACjBlgH,GAUDG,EACC,MAAMwa,EAAKwlG,GAAc,CAAE1lH,GAAkB8E,EAAUoQ,MAAMqH,EAAE7U,EAAMyyB,SAASn6B,KAW9E,IAAIoiH,GAAmB,EACvB,IAAK,IAAIniG,EAHqBgmF,EAAoC,CAAEv+F,QAAO5C,YAAWkkB,aAAYg9E,oBAG9D/lF,EAAIvY,EAAMyxB,MAAMn7B,OAASynH,EAAexlG,IAAK,CAC/E,MAAM1D,EAAI2D,EAAGD,GACb,GAAI1D,EAAIyM,EAAazjB,EAAO,CAC1B68G,EAAkBniG,EAClB,KACF,CACAu1B,EAAgBv1B,EAAG1D,EACrB,CAEA,GAAI6lG,GAAmB,EAAG,CAExB5sE,EAAgB4sE,EADNliG,EAAGkiG,GAEf,GAOK,SAAS/xE,EAA0BlqC,GAUvC,IAVwC,WACzCoqC,EAAU,WACVvnB,EAAU,UACVlkB,EAAS,MACT4C,GAMDvB,EACC,MAAMgC,EAAarD,EAAU2C,QAMvB0yB,EAAW/c,KAAK2E,MAAMjd,EAAUoQ,MAAMqH,EAAE0N,QAAQjB,QAA6B5iB,IAAfmqC,EAA2BA,EAAa,KACtGuqF,EAAepzH,EAAM43G,eAAeliG,KAAKqF,IAAIrF,KAAKwF,IAAIuX,EAAU,GAAIzyB,EAAM43G,eAAethH,OAAS,IAClGm3C,GAAeC,EAAAA,EAAAA,IAAgBjtC,GAAY,GAE3C4yH,EAAe39G,KAAK2E,MAAMjd,EAAUoQ,MAAMqH,EAAE7U,EAAMyyB,SAAS2gG,IAAiB3lF,GAAgBnsB,EAAa,EAE/G,MAAO,CACLhpB,WACiBoG,IAAfmqC,EACIwqF,EACED,EACA19G,KAAKwF,IAAIxF,KAAKqF,IAAIq4G,EAAe,EAAGpzH,EAAMyyB,SAASn8B,OAAS,GAAI,GAClE88H,EACNC,eAEJ,CAGO,SAAS90B,EAAmCp6F,GAUhD,IAViD,gBAClDm6F,EAAkB,EAAC,WACnBh9E,EAAU,UACVlkB,EAAS,MACT4C,GAMDmE,EACC,OAAOuR,KAAKwF,IAAI,EAAGytB,EAA2B,CAAE3oC,QAAOshB,aAAYlkB,cAAa9E,MAAQ,EAAGgmG,EAC7F,CAUO,SAAS3pD,EAAoBH,EAAqCC,GACvE,OAAQD,EAAsB6+E,eAAiB5+E,EAAqB4+E,YACtE,C,+HC9GO,MAAMhmC,EAAyBimC,GACpCh6H,OAAOC,KAAK+5H,GAAQlwH,QAAO,CAACmwH,EAAUvvH,KACpCuvH,EAASC,OAAOxvH,EAAKsvH,EAAOtvH,IACrBuvH,IACN,IAAIE,UAIF,IAAKr8D,EAAW,SAAXA,GAAW,OAAXA,EAAW,mCAAXA,EAAW,qDAAXA,EAAW,mDAAXA,EAAW,gCAAXA,CAAW,MAsEhB,MAAMS,UAA+Bp4D,MAC1Ck4D,SACA+7D,WAEAl6H,WAAAA,CAAYo+D,EAAiBD,EAA+B+7D,GAC1DpzH,MAAMs3D,GACNvhE,KAAKshE,SAAWA,EAChBthE,KAAKq9H,WAAaA,CACpB,EAEK,MAAMl8D,UAAuBK,GAC7B,MAAMw+C,UAAsBx+C,GAC5B,MAAMN,UAA4BM,GAClC,MAAMJ,UAAkBI,GAE/B,QAlEiB95D,UAUI,IAV+C,SAClEmD,EAAQ,gBACRu1D,EAAe,OACfS,EAAM,KACN90D,EAAI,YACJ+0D,EAAW,gBACX1M,EAAe,mBACfiM,EAAkB,iBAClBi9D,EAAgB,UAChB98D,GAAY,GACE74D,EACd,MAAM41H,EAAO,GAAE1yH,IAAWu1D,EAAmB,IAAG2yB,EAAAA,UAAsB3yB,KAAqB,KACrFnqD,EAA0B,CAC9B4qD,OAAQA,GAAU,MAClB28D,YAAa,UACbC,QAAS38D,GAAe,CACtB,eAAgBA,GAElB8sC,OAAQx5C,GAAiBw5C,OACzB7hG,KAAMA,EACNy0D,aAEF,IACE,MAAMc,QAAiBmyB,MAAM8pC,EAAKtnH,GAC5BynH,EAAoCp8D,EAASm8D,QAAQvqG,IAAI,iBAA2B6tC,EAAY48D,KAChGC,EArCV,SAAqCt8D,EAAkBR,GACrD,OAAQA,GACN,KAAKC,EAAYC,gBACjB,KAAKD,EAAY88D,mBACjB,KAAK98D,EAAY+8D,eACf,OAAO92G,KAAKsmC,MAAMgU,GACpB,QACE,OAAOA,EAEb,CA4ByBy8D,OAAkCz8D,EAASz7C,OAAQ63G,GACxE,GAAIr9D,GAAoBjmC,SAASknC,EAASoyB,SAAW4pC,IAAmBh8D,GAAW,CAEjF,MAAM,IAQZ,SAA4B+7D,GAC1B,OAAQA,GACN,KAAK,IACH,OAAOl8D,EACT,KAAK,IACH,OAAO6+C,EACT,KAAK,IACH,OAAO5+C,EACT,KAAK,IACH,OAAOF,EACT,QACE,OAAOM,EAEb,CAtB8Bw8D,CAAmB18D,EAASoyB,QAC9C,CAAqB,GAAE6pC,cAAgBj8D,EAASoyB,SAAUkqC,EAAmBt8D,EAASoyB,OAC9F,CACA,OAAOkqC,CACT,CAAE,MAAO9gH,GACP,MAAMA,CACR,E,+DC1EK,SAASy5F,IACd,MAAO0nB,EAAgBC,GAAa7yH,EAAAA,SAAe,GAInD,MAAO,CAAE4/D,YAHW5/D,EAAAA,aAAkB,KACpC6yH,GAAW5zE,GAASA,EAAO,GAAE,GAC5B,IACmB2zE,iBACxB,C,gMCNO,SAAShhG,EAAgBt1B,GAAiF,IAAhF,OAAEu1B,EAAM,mBAAEC,GAAoEx1B,EAC7G,MAAMw2H,EAAY9+G,KAAKojF,IAAI,GAAItlE,GAC/B,OAAOj9B,OAAOmf,KAAK2E,MAAMkZ,EAASihG,GAAaA,EACjD,CAEO,SAAS38E,IACd,MAA0B,oBAAZ41B,UAA2B,CAC3C,CAOO,SAASmvB,EAAkC63B,GAEhD,OADoBA,EAAarkG,MAAM,KACpBrsB,KAAK2wH,GAASv6G,OAAOq5B,SAASkhF,EAAM,KACzD,CAEO,SAASl1H,EAAiBgS,EAAkBC,GAQ/CvV,OAAOwV,OAAOlS,iBAAiBgS,EAAWC,EAE9C,CAEO,SAASwqG,EAAgBh4G,GAC9B,MAAM0wH,EAAex6G,OAAOC,WAAY,GAAEnW,KAC1C,OAAQkW,OAAOkS,MAAMsoG,IAAiB9wF,SAAS8wF,IAAiBA,EAAe,CACjF,CAEO,SAASr0B,EAAkBr8F,GAChC,MAAMwsC,EAAU,GAAExsC,IAClB,OAAOg4G,EAAgBh4G,IAAUkW,OAAOq5B,SAAS/C,EAAQ,MAAQt2B,OAAOC,WAAWq2B,EACrF,CAEO,SAAStlB,EAAS1sB,GAQtB,IARuB,MACxBwF,EAAK,IACL8W,EAAMZ,OAAOwgB,iBAAgB,IAC7Bzf,EAAMf,OAAOy6G,kBAKdn2H,EACC,MAAMk2H,EAAex6G,OAAOC,WAAY,GAAEnW,KAC1C,OAAQkW,OAAOkS,MAAMsoG,IAAiBA,GAAgB55G,GAAO45G,GAAgBz5G,CAC/E,CAUO,SAASo1D,EAAensE,GAAmE,IAAlE,MAAEF,EAAK,IAAE8W,EAAG,IAAEG,GAAkD/W,EAC9F,OAAOuR,KAAKqF,IAAIrF,KAAKwF,IAAIjX,EAAO8W,GAAMG,EACxC,CAEO,SAAS60D,EAAen0E,GAG7B,OAAIA,EAAEwyG,eAAe,gBAAqD1vG,IAAvC9C,EAA4BqwE,QACd,IAAvCrwE,EAA4BqwE,MAIxC,CAGO,SAASmgC,IACd,MAAMyoB,EAAU,IAAIC,QACpB,MAAO,CAAC9wH,EAAaC,KACnB,GAAqB,iBAAVA,GAAgC,OAAVA,EAAgB,CAC/C,GAAI4wH,EAAQ53C,IAAIh5E,GACd,OAEF4wH,EAAQvyH,IAAI2B,EACd,CACA,OAAOA,CAAK,CAEhB,CAGO,MAAM6nH,EAAuBA,CAACjuF,EAAY9iC,IAC/C8iC,EAAKk3F,mBAAmB,QAAS,CAC/B52F,IAAK,UACLJ,MAAO,UACPE,KAAM,aACHljC,IAWA,SAAS4lF,IACd,OAAOzkF,OAAO84H,QAAQC,gBAPd,uCAAqCvlH,QAAQ,UAAW28B,IAC9D,MAAMvpB,EAAI3I,OAAOkyB,GACjB,OAAQvpB,EAAKkyG,OAAOE,gBAAgB,IAAIC,WAAW,IAAI,GAAM,IAAOryG,EAAI,GAAMloB,SAAS,GAAG,GAM9F,C,4ECzGO,MAYM2/D,EAAUA,CAAC1V,EAActoD,KAAW,CAC/CmoD,GAAInoD,EACJk+B,MAAO,EACPoqB,SAGWjB,EAAaA,CAAC22B,EAAU66C,IAC/B76C,EAAI71B,KAAO0wE,EAAI1wE,GACb61B,EAAI9/C,QAAU26F,EAAI36F,MAChB8/C,EAAI11B,OAASuwE,EAAIvwE,KACZ,EAEF01B,EAAI11B,KAAOuwE,EAAIvwE,MAAQ,EAAI,EAE7B01B,EAAI9/C,MAAQ26F,EAAI36F,MAElB8/C,EAAI71B,GAAK0wE,EAAI1wE,GAGThB,EAAeA,CAAC2xE,EAAY94H,IACnCA,EAAM84H,EAAM3wE,GACP,CAAEA,GAAInoD,EAAKk+B,MAAO,EAAGoqB,KAAMwwE,EAAMxwE,MAGnC,IAAKwwE,EAAO56F,MAAO46F,EAAM56F,MAAQ,GAG7B2oB,EAAaA,CAACiyE,EAAYC,IACjC1xE,EAAWyxE,EAAOC,IAAW,EACxBD,EAEF,IAAKA,EAAO3wE,GAAI4wE,EAAO5wE,GAAIjqB,MAAO66F,EAAO76F,M,0EC9C3C,SAAS7xB,IACd,MAAO2sH,IAAmC5jH,EAAAA,EAAAA,GAAe,IACpD88C,EAAAA,GACH18C,gBAAgB,IAElB,OAAOwjH,EAAgCC,2BACzC,C,8FCqPO,IAAKrsH,EAAU,SAAVA,GAAU,OAAVA,EAAU,cAAVA,EAAU,gBAAVA,EAAU,mCAAVA,EAAU,kBAAVA,EAAU,cAAVA,EAAU,cAAVA,CAAU,MASVpK,EAAK,SAALA,GAAK,OAALA,EAAK,cAALA,EAAK,YAALA,CAAK,MA2BLoP,EAAQ,SAARA,GAAQ,OAARA,EAAQ,cAARA,EAAQ,cAARA,CAAQ,MAKRu+F,EAAkB,SAAlBA,GAAkB,OAAlBA,EAAkB,gBAAlBA,EAAkB,kBAAlBA,EAAkB,kBAAlBA,EAAkB,gBAAlBA,CAAkB,MAOlB9rE,EAAiB,SAAjBA,GAAiB,OAAjBA,EAAiB,oCAAjBA,EAAiB,4BAAjBA,CAAiB,MAKjBu6B,EAAwB,SAAxBA,GAAwB,OAAxBA,EAAwB,gBAAxBA,CAAwB,K","sources":["webpack://@finviz/website/../config/colors.js","webpack://@finviz/website/../charts/app/lib/shims.ts","webpack://@finviz/website/../charts/app/logger.js","webpack://@finviz/website/../charts/app/models/chart-event-element.ts","webpack://@finviz/website/../charts/app/models/indicator.ts","webpack://@finviz/website/../charts/app/models/overlay.ts","webpack://@finviz/website/../charts/app/models/relationships.ts","webpack://@finviz/website/../charts/app/index.ts","webpack://@finviz/website/../charts/app/controllers/header/fullscreen_button.tsx","webpack://@finviz/website/../charts/app/controllers/header/layout_dropdown.tsx","webpack://@finviz/website/../charts/app/helpers/sorter.ts","webpack://@finviz/website/../charts/app/controllers/header/theme_toggle_button.tsx","webpack://@finviz/website/../charts/app/controllers/header/index.tsx","webpack://@finviz/website/../charts/app/controllers/chart-controls/stock-detail-timeframe-bar.tsx","webpack://@finviz/website/../charts/app/utils/convert_ta.ts","webpack://@finviz/website/./js/app/charts-lib.ts","webpack://@finviz/website/./js/app/quote/create-alert/async-modules.ts","webpack://@finviz/website/./js/app/quote/save-to-portfolio/async-modules.ts","webpack://@finviz/website/./js/app/shared/tracking.ts","webpack://@finviz/website/./js/main/components/portfolio/async-modules.ts","webpack://@finviz/website/./js/charts_lib_entry_do_not_directly_use_in_website.ts","webpack://@finviz/website/./js/main/hooks/use-track-pageview.ts","webpack://@finviz/website/./js/main/modules/portfolio/types.tsx","webpack://@finviz/website/./js/main/services/async-modules-utils.tsx","webpack://@finviz/website/./js/main/services/import-with-retry.ts","webpack://@finviz/website/../charts/app/canvas/arrow.ts","webpack://@finviz/website/../charts/app/canvas/brush/brush_v1.ts","webpack://@finviz/website/../charts/app/canvas/callout/callout_utils.ts","webpack://@finviz/website/../charts/app/canvas/callout/callout_v1.ts","webpack://@finviz/website/../charts/app/canvas/curve.ts","webpack://@finviz/website/../charts/app/canvas/ellipse.ts","webpack://@finviz/website/../charts/app/canvas/rotated_rectangle.ts","webpack://@finviz/website/../charts/app/canvas/symbol.ts","webpack://@finviz/website/../charts/app/canvas/drawingTools.ts","webpack://@finviz/website/../charts/app/canvas/element.ts","webpack://@finviz/website/../charts/app/canvas/elliott_waves/elliott_waves.ts","webpack://@finviz/website/../charts/app/canvas/ellipse/ellipse_v1.ts","webpack://@finviz/website/../charts/app/canvas/fibonacci_retracements.ts","webpack://@finviz/website/../charts/app/canvas/horizontal_line.ts","webpack://@finviz/website/../charts/app/canvas/line.ts","webpack://@finviz/website/../charts/app/canvas/measure.ts","webpack://@finviz/website/../charts/app/canvas/pitchfork/pitchfork_utils.ts","webpack://@finviz/website/../charts/app/canvas/pitchfork/pitchfork_v1.ts","webpack://@finviz/website/../charts/app/canvas/polygon.ts","webpack://@finviz/website/../charts/app/canvas/position.ts","webpack://@finviz/website/../charts/app/canvas/rectangle.ts","webpack://@finviz/website/../charts/app/canvas/rotated_rectangle/rotated_rectangle_v1.ts","webpack://@finviz/website/../charts/app/canvas/scaled_line.ts","webpack://@finviz/website/../charts/app/canvas/scaled_text.ts","webpack://@finviz/website/../charts/app/canvas/text.ts","webpack://@finviz/website/../charts/app/canvas/thumb.ts","webpack://@finviz/website/../charts/app/canvas/triangle.ts","webpack://@finviz/website/../charts/app/canvas/vertical_line.ts","webpack://@finviz/website/../charts/app/canvas/xabcd.ts","webpack://@finviz/website/../charts/app/canvas/cache.js","webpack://@finviz/website/../charts/app/models/chart_settings/interfaces.ts","webpack://@finviz/website/../charts/app/charts/utils.ts","webpack://@finviz/website/../charts/app/charts/base_chart.ts","webpack://@finviz/website/../charts/app/charts/candle_stick.ts","webpack://@finviz/website/../charts/app/charts/candle_stick_hollow.ts","webpack://@finviz/website/../charts/app/charts/heikin_ashi.ts","webpack://@finviz/website/../charts/app/charts/line_chart.ts","webpack://@finviz/website/../charts/app/charts/market_sentiment.ts","webpack://@finviz/website/../charts/app/charts/multi_line_chart.ts","webpack://@finviz/website/../charts/app/charts/ohlc_chart.ts","webpack://@finviz/website/../charts/app/charts/perf_chart.ts","webpack://@finviz/website/../charts/app/charts/charts.ts","webpack://@finviz/website/../charts/app/constants/common.ts","webpack://@finviz/website/../charts/app/controllers/autosave/utils.ts","webpack://@finviz/website/../charts/app/controllers/chart-controls/settings-button.tsx","webpack://@finviz/website/../charts/app/controllers/chart-controls/use-chart-controls.ts","webpack://@finviz/website/../charts/app/model-hooks/useModelRef.ts","webpack://@finviz/website/../charts/app/controllers/chart-controls/use-chart-model-custom-date-range-values.tsx","webpack://@finviz/website/../charts/app/controllers/chart-controls/use-charts-path-location.ts","webpack://@finviz/website/../charts/app/controllers/chart-controls/utils.ts","webpack://@finviz/website/../charts/app/controllers/chart-events/async-modules.ts","webpack://@finviz/website/../charts/app/controllers/chart-settings/async-modules.ts","webpack://@finviz/website/../charts/app/modals/background.tsx","webpack://@finviz/website/../charts/app/modals/color_range_row.tsx","webpack://@finviz/website/../charts/app/modals/border.tsx","webpack://@finviz/website/../charts/app/modals/checkbox.tsx","webpack://@finviz/website/../charts/app/modals/font.tsx","webpack://@finviz/website/../charts/app/modals/line.tsx","webpack://@finviz/website/../charts/app/modals/multiline_string.tsx","webpack://@finviz/website/../charts/app/modals/number.tsx","webpack://@finviz/website/../charts/app/modals/string.tsx","webpack://@finviz/website/../charts/app/modals/trend.tsx","webpack://@finviz/website/../charts/app/modals/visibility/visibility-input.tsx","webpack://@finviz/website/../charts/app/modals/visibility/index.tsx","webpack://@finviz/website/../charts/app/modals/element_style.tsx","webpack://@finviz/website/../charts/app/controllers/autosave/constants.ts","webpack://@finviz/website/../charts/app/controllers/autosave/use-drawing-autosave-api.tsx","webpack://@finviz/website/../charts/app/utils/string-byte-length.ts","webpack://@finviz/website/../charts/app/controllers/autosave/use-drawing-auto-save-controls.ts","webpack://@finviz/website/../charts/app/controllers/autosave/use-is-auto-save-active.ts","webpack://@finviz/website/../charts/app/controllers/autosave/with-auto-save.tsx","webpack://@finviz/website/../charts/app/utils/use-prev-state.ts","webpack://@finviz/website/../charts/app/controllers/chart-controls/chart-type-select.tsx","webpack://@finviz/website/../charts/app/controllers/chart-controls/use-chart-types.ts","webpack://@finviz/website/../charts/app/controllers/chart-controls/daily-change-display.tsx","webpack://@finviz/website/../charts/app/controllers/chart-controls/draw-button.tsx","webpack://@finviz/website/../charts/app/controllers/chart-controls/fullscreen-button.tsx","webpack://@finviz/website/../charts/app/controllers/chart-controls/search.tsx","webpack://@finviz/website/../charts/app/controllers/chart-controls/chart-controls.tsx","webpack://@finviz/website/../charts/app/models/context_menu.ts","webpack://@finviz/website/../charts/app/controllers/context_menu.tsx","webpack://@finviz/website/../charts/app/controllers/pane/chart-event-popover-with-state.tsx","webpack://@finviz/website/../charts/app/utils/use-click-away.ts","webpack://@finviz/website/../charts/app/controllers/pane/load-latest-data-button.tsx","webpack://@finviz/website/../charts/app/utils/use-is-mounted.ts","webpack://@finviz/website/../charts/app/controllers/pane/zoom_controls.tsx","webpack://@finviz/website/../charts/app/controllers/pane/pane.tsx","webpack://@finviz/website/../charts/app/controllers/pane/with-pane-model.tsx","webpack://@finviz/website/../charts/app/controllers/chart/chart-spinner-overlay.tsx","webpack://@finviz/website/../charts/app/controllers/chart/constants.ts","webpack://@finviz/website/../charts/app/controllers/chart/chart.tsx","webpack://@finviz/website/../charts/app/controllers/chart/with-chart-init.tsx","webpack://@finviz/website/../charts/app/controllers/chart/with-watched-panes-on-chart-model.tsx","webpack://@finviz/website/../charts/app/creators/async-modules.ts","webpack://@finviz/website/../charts/app/controllers/toolbar/drawingActions.tsx","webpack://@finviz/website/../charts/app/controllers/toolbar/drawingSettings.tsx","webpack://@finviz/website/../charts/app/controllers/toolbar/drawingTools.ts","webpack://@finviz/website/../charts/app/controllers/toolbar/toolbar.tsx","webpack://@finviz/website/../charts/app/controllers/toolbar/index.ts","webpack://@finviz/website/../charts/app/controllers/toolbar/auto-save-notes/auto-save-notes.tsx","webpack://@finviz/website/../charts/app/controllers/toolbar/auto-save-notes/auto-save-notes-dialog.tsx","webpack://@finviz/website/../charts/app/controllers/toolbar/confirmation_dialog.tsx","webpack://@finviz/website/../charts/app/controllers/toolbar/mobile/tool-button.tsx","webpack://@finviz/website/../charts/app/controllers/toolbar/mobile/toolbar-mobile.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/auto-save-state-indicator.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/chart-layout-auto-save-note.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/publish_old_button_click_listener.tsx","webpack://@finviz/website/../charts/app/controllers/autosave/idea-leave-dialog.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/with-chart-route-change.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/chart_layout_component.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/with-quote-cache-management.tsx","webpack://@finviz/website/../charts/app/controllers/with_dialog_state_hook.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/with-chart-page-title.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/with-idea-model-state.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/chart_layout.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/constants.ts","webpack://@finviz/website/../charts/app/controllers/chart_layout/with-complete-layout-model-init.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/with-quote-polling.tsx","webpack://@finviz/website/../charts/app/modals/ideas/utils.ts","webpack://@finviz/website/../charts/app/modals/ideas/IdeaItem.tsx","webpack://@finviz/website/../charts/app/modals/ideas/IdeasTabs.tsx","webpack://@finviz/website/../charts/app/modals/ideas/Ideas.tsx","webpack://@finviz/website/../charts/app/controllers/header/ideas_dropdown.tsx","webpack://@finviz/website/../charts/app/controllers/header/publish.tsx","webpack://@finviz/website/../charts/app/controllers/header/tour_button.tsx","webpack://@finviz/website/../charts/app/utils/chart-date-range-utils.ts","webpack://@finviz/website/../charts/app/controllers/renderUtils.ts","webpack://@finviz/website/../charts/app/controllers/sidebar/constants.ts","webpack://@finviz/website/../charts/app/controllers/sidebar/hooks/sidebar-context.tsx","webpack://@finviz/website/../charts/app/controllers/sidebar/modules/module-load-failed.tsx","webpack://@finviz/website/../charts/app/controllers/sidebar/modules/portfolio-watchlist/async-modules.ts","webpack://@finviz/website/../charts/app/controllers/sidebar/modules/modules.ts","webpack://@finviz/website/../charts/app/controllers/sidebar/modules/with-module-async-load.tsx","webpack://@finviz/website/../charts/app/controllers/sidebar/sidebar-tabs.tsx","webpack://@finviz/website/../charts/app/controllers/sidebar/sidebar-content.tsx","webpack://@finviz/website/../charts/app/controllers/sidebar/sidebar.tsx","webpack://@finviz/website/../charts/app/controllers/toolbar/interfaces.ts","webpack://@finviz/website/../charts/app/controllers/utils.ts","webpack://@finviz/website/../charts/app/helpers/atr.ts","webpack://@finviz/website/../charts/app/chart-events/chart-event.ts","webpack://@finviz/website/../charts/app/chart-events/dividends.ts","webpack://@finviz/website/../charts/app/chart-events/earnings.ts","webpack://@finviz/website/../charts/app/chart-events/split.ts","webpack://@finviz/website/../charts/app/chart-events/index.ts","webpack://@finviz/website/../charts/app/helpers/get-canvas-element-by-type.ts","webpack://@finviz/website/../charts/app/helpers/math.ts","webpack://@finviz/website/../charts/app/indicator-calculation/ema.ts","webpack://@finviz/website/../charts/app/indicator-calculation/main.ts","webpack://@finviz/website/../charts/app/indicators/indicator.ts","webpack://@finviz/website/../charts/app/utils/canvas-render.ts","webpack://@finviz/website/../charts/app/indicators/adx.ts","webpack://@finviz/website/../charts/app/indicator-calculation/aroon.ts","webpack://@finviz/website/../charts/app/indicators/aro.ts","webpack://@finviz/website/../charts/app/indicators/aroosc.ts","webpack://@finviz/website/../charts/app/indicators/atr.ts","webpack://@finviz/website/../charts/app/indicators/cci.ts","webpack://@finviz/website/../charts/app/indicators/cot.ts","webpack://@finviz/website/../charts/app/indicator-calculation/fi.ts","webpack://@finviz/website/../charts/app/indicators/fi.ts","webpack://@finviz/website/../charts/app/indicator-calculation/macd.ts","webpack://@finviz/website/../charts/app/indicators/macd.ts","webpack://@finviz/website/../charts/app/indicators/mfi.ts","webpack://@finviz/website/../charts/app/indicators/none.ts","webpack://@finviz/website/../charts/app/indicators/obv.ts","webpack://@finviz/website/../charts/app/indicators/perf.ts","webpack://@finviz/website/../charts/app/indicators/rmi.ts","webpack://@finviz/website/../charts/app/indicators/roc.ts","webpack://@finviz/website/../charts/app/indicator-calculation/rsi.ts","webpack://@finviz/website/../charts/app/indicators/rsi.ts","webpack://@finviz/website/../charts/app/indicators/rvol.ts","webpack://@finviz/website/../charts/app/indicators/rwi.ts","webpack://@finviz/website/../charts/app/indicators/stofu.ts","webpack://@finviz/website/../charts/app/indicators/stofa.ts","webpack://@finviz/website/../charts/app/indicators/stosl.ts","webpack://@finviz/website/../charts/app/indicator-calculation/trix.ts","webpack://@finviz/website/../charts/app/indicators/trix.ts","webpack://@finviz/website/../charts/app/indicators/ult.ts","webpack://@finviz/website/../charts/app/indicators/vol.ts","webpack://@finviz/website/../charts/app/indicators/wr.ts","webpack://@finviz/website/../charts/app/indicators/indicators.ts","webpack://@finviz/website/../charts/app/modals/publish/async-modules.ts","webpack://@finviz/website/../charts/app/model-hooks/use-model-state.ts","webpack://@finviz/website/../charts/app/models/chart.ts","webpack://@finviz/website/../charts/app/models/chart/contstants.ts","webpack://@finviz/website/../charts/app/models/chart_layout.ts","webpack://@finviz/website/../charts/app/models/chart_settings/index.ts","webpack://@finviz/website/../charts/app/models/constants.ts","webpack://@finviz/website/../charts/app/models/drawings-internal-store.ts","webpack://@finviz/website/../charts/app/models/element.ts","webpack://@finviz/website/../charts/app/models/mouse/mouse-utils.ts","webpack://@finviz/website/../charts/app/models/mouse/mouse.ts","webpack://@finviz/website/../charts/app/models/pane.ts","webpack://@finviz/website/../charts/app/models/quoteCache.ts","webpack://@finviz/website/../charts/app/models/quote.ts","webpack://@finviz/website/../charts/app/models/quote/constants.ts","webpack://@finviz/website/../charts/app/models/chart_settings/constants.ts","webpack://@finviz/website/../charts/app/models/chart_settings/interactive_chart_settings.ts","webpack://@finviz/website/../charts/app/models/settings.ts","webpack://@finviz/website/../charts/app/models/utils.ts","webpack://@finviz/website/../charts/app/indicator-calculation/bb.ts","webpack://@finviz/website/../charts/app/overlays/overlay.ts","webpack://@finviz/website/../charts/app/overlays/bb.ts","webpack://@finviz/website/../charts/app/overlays/dch.ts","webpack://@finviz/website/../charts/app/overlays/ema.ts","webpack://@finviz/website/../charts/app/overlays/ema2.ts","webpack://@finviz/website/../charts/app/overlays/hilo.ts","webpack://@finviz/website/../charts/app/overlays/hline.ts","webpack://@finviz/website/../charts/app/overlays/ic.ts","webpack://@finviz/website/../charts/app/overlays/icf.ts","webpack://@finviz/website/../charts/app/overlays/kch.ts","webpack://@finviz/website/../charts/app/overlays/none.ts","webpack://@finviz/website/../charts/app/overlays/patterns.ts","webpack://@finviz/website/../charts/app/overlays/pp.ts","webpack://@finviz/website/../charts/app/overlays/sar.ts","webpack://@finviz/website/../charts/app/indicator-calculation/sma.ts","webpack://@finviz/website/../charts/app/overlays/sma.ts","webpack://@finviz/website/../charts/app/overlays/sma2.ts","webpack://@finviz/website/../charts/app/overlays/str.ts","webpack://@finviz/website/../charts/app/overlays/vp.ts","webpack://@finviz/website/../charts/app/indicator-calculation/vwap.ts","webpack://@finviz/website/../charts/app/overlays/vwap.ts","webpack://@finviz/website/../charts/app/overlays/overlays.ts","webpack://@finviz/website/../charts/app/utils.ts","webpack://@finviz/website/../charts/app/utils/abort_controller.ts","webpack://@finviz/website/../charts/app/utils/async-modules-utils.ts","webpack://@finviz/website/../charts/app/utils/canvas.ts","webpack://@finviz/website/../charts/app/utils/chart-events-utils.ts","webpack://@finviz/website/../charts/app/utils/chart.ts","webpack://@finviz/website/../charts/app/utils/colors.ts","webpack://@finviz/website/../charts/app/utils/cursor.ts","webpack://@finviz/website/../charts/app/utils/draw_in_visible_area.ts","webpack://@finviz/website/../charts/app/utils/fetch_api.ts","webpack://@finviz/website/../charts/app/utils/force-update.ts","webpack://@finviz/website/../charts/app/utils/helpers.ts","webpack://@finviz/website/../charts/app/utils/hlc.ts","webpack://@finviz/website/../charts/app/utils/useChartLayoutGlobalModelAsync.ts","webpack://@finviz/website/../charts/types/shared.ts"],"sourcesContent":["// Keep in sync with charts repository colors.js file in: app/constants/colors.js\r\n\r\nmodule.exports = {\r\n white: '#fff',\r\n black: '#000',\r\n inherit: 'inherit',\r\n transparent: 'transparent',\r\n current: 'currentColor',\r\n finviz: {\r\n 'blue-gray': '#262931',\r\n blue: '#4fa4f4',\r\n },\r\n gray: {\r\n 50: '#f3f3f5',\r\n 100: '#dedfe5',\r\n 200: '#c3c6d0',\r\n 300: '#a3a8b9',\r\n 400: '#868ea5',\r\n 500: '#676f85',\r\n 600: '#4c5263',\r\n 700: '#353945',\r\n 750: '#2c303b',\r\n 800: '#22262f',\r\n 900: '#14161d',\r\n },\r\n red: {\r\n 50: '#fef0f0',\r\n 100: '#fcd6d6',\r\n 200: '#fbb4b4',\r\n 300: '#fd8487',\r\n 400: '#fb5057',\r\n 500: '#d91e2b',\r\n 600: '#9f1f2a',\r\n 700: '#691f24',\r\n 800: '#45171a',\r\n 900: '#280e0f',\r\n },\r\n orange: {\r\n 50: '#fef2eb',\r\n 100: '#fdd9c5',\r\n 200: '#fab889',\r\n 300: '#ef9323',\r\n 400: '#ca7b14',\r\n 500: '#a0600e',\r\n 600: '#79460a',\r\n 700: '#583006',\r\n 800: '#3d1e03',\r\n 900: '#261101',\r\n },\r\n amber: {\r\n 50: '#fef2e7',\r\n 100: '#fedab5',\r\n 200: '#fbba56',\r\n 300: '#de9c1a',\r\n 400: '#bb830f',\r\n 500: '#956600',\r\n 600: '#704b00',\r\n 700: '#4f3400',\r\n 800: '#372200',\r\n 900: '#211300',\r\n },\r\n yellow: {\r\n 50: '#fdf2df',\r\n 100: '#fcdc86',\r\n 200: '#f3c736',\r\n 300: '#cda30b',\r\n 400: '#b08900',\r\n 500: '#8b6a00',\r\n 600: '#664e21',\r\n 700: '#46371e',\r\n 800: '#2f2516',\r\n 900: '#1b150d',\r\n },\r\n brightYellow: {\r\n 50: '#fff699',\r\n 100: '#fff200',\r\n },\r\n lime: {\r\n 50: '#ebfad6',\r\n 100: '#caec90',\r\n 200: '#aad547',\r\n 300: '#8db61e',\r\n 400: '#769913',\r\n 500: '#5b7800',\r\n 600: '#435900',\r\n 700: '#2e3e00',\r\n 800: '#1e2a00',\r\n 900: '#111900',\r\n },\r\n green: {\r\n 50: '#e7f7e8',\r\n 100: '#beeac1',\r\n 200: '#86d895',\r\n 300: '#34c062',\r\n 400: '#00a449',\r\n 500: '#19803d',\r\n 600: '#265d35',\r\n 700: '#1e4027',\r\n 800: '#162b1b',\r\n 900: '#0d1810',\r\n },\r\n emerald: {\r\n 50: '#ddfaee',\r\n 100: '#a2f0d2',\r\n 200: '#4dddaf',\r\n 300: '#25be93',\r\n 400: '#1d9f7b',\r\n 500: '#157e60',\r\n 600: '#035d47',\r\n 700: '#004139',\r\n 800: '#002c22',\r\n 900: '#001a13',\r\n },\r\n teal: {\r\n 50: '#e0f8fc',\r\n 100: '#9beef7',\r\n 200: '#4fd8e5',\r\n 300: '#27b9c4',\r\n 400: '#109ba5',\r\n 500: '#007c83',\r\n 600: '#005b62',\r\n 700: '#004045',\r\n 800: '#002b2e',\r\n 900: '#00191b',\r\n },\r\n blue: {\r\n 50: '#ebf4fe',\r\n 100: '#cae2fc',\r\n 200: '#9bcbfa',\r\n 300: '#57aefb',\r\n 400: '#2f91ef',\r\n 500: '#306dca',\r\n 600: '#2f5091',\r\n 700: '#263766',\r\n 800: '#1b2542',\r\n 900: '#101527',\r\n },\r\n violet: {\r\n 50: '#f4f2fe',\r\n 100: '#e1dbfd',\r\n 200: '#c9befc',\r\n 300: '#ad9bfb',\r\n 400: '#9978f9',\r\n 500: '#7c51e7',\r\n 600: '#5e36b8',\r\n 700: '#402979',\r\n 800: '#2a1e4e',\r\n 900: '#18122c',\r\n },\r\n purple: {\r\n 50: '#f9f1fe',\r\n 100: '#eed8fd',\r\n 200: '#e1b6fc',\r\n 300: '#d38bfb',\r\n 400: '#c85bf9',\r\n 500: '#ae27e0',\r\n 600: '#8514ac',\r\n 700: '#60077e',\r\n 800: '#44005a',\r\n 900: '#2a003a',\r\n },\r\n pink: {\r\n 50: '#fef1f4',\r\n 100: '#fdd6e1',\r\n 200: '#fcb2c7',\r\n 300: '#f984aa',\r\n 400: '#f25090',\r\n 500: '#cd2a74',\r\n 600: '#9d1658',\r\n 700: '#700c42',\r\n 800: '#4e052b',\r\n 900: '#32011a',\r\n },\r\n}\r\n","import Spine from '@finviz/spine'\r\n\r\n// eslint-disable-next-line no-extend-native\r\nArray.prototype.last = function () {\r\n return this[this.length - 1]\r\n}\r\n\r\n// eslint-disable-next-line no-extend-native\r\nString.prototype.padLeft = function (paddingValue) {\r\n return String(paddingValue + this).slice(-paddingValue.length)\r\n}\r\n\r\n// eslint-disable-next-line no-extend-native\r\nString.prototype.startsWith = function (str) {\r\n return this.indexOf(str) === 0\r\n}\r\n\r\ninterface CallbackCacheItem {\r\n newCb: (...args: any[]) => any\r\n origCb: (...args: any[]) => any\r\n}\r\n\r\nconst _callbackCache: CallbackCacheItem[] = []\r\nSpine.Collection.prototype.bind = function (ev, callback) {\r\n // eslint-disable-next-line @typescript-eslint/no-this-alias\r\n const that = this\r\n const cb = (record: Spine.Model, ...rest: any[]) => {\r\n if (record[that.fkey as keyof Spine.Model] === that.record.id) {\r\n return callback(record, ...rest)\r\n }\r\n }\r\n _callbackCache.push({ newCb: cb, origCb: callback })\r\n this.model.bind(ev, cb)\r\n return this\r\n}\r\n\r\nSpine.Collection.prototype.unbind = function (ev, callback) {\r\n let cb\r\n for (const item of _callbackCache) {\r\n if (item.origCb === callback) {\r\n cb = item.newCb\r\n break\r\n }\r\n }\r\n return this.model.unbind(ev, cb)\r\n}\r\n\r\nSpine.Model.findIndex = function (element) {\r\n const iterable = this.all()\r\n for (let index = 0; index < iterable.length; index++) {\r\n const el = iterable[index]\r\n if (element.eql(el)) {\r\n return index\r\n }\r\n }\r\n}\r\n","import Spine from '@finviz/spine'\r\n\r\nexport const defaults = {\r\n enabled: false,\r\n collapsed: true,\r\n duration: false,\r\n timestamp: true,\r\n logErrors: true,\r\n withStackTrace: false,\r\n level: 'log',\r\n logger: console,\r\n filterChanges: (model, attrs) => {\r\n const props = Object.keys(attrs)\r\n return (\r\n model.constructor.name === 'Mouse' ||\r\n model.constructor.name === 'Quote' ||\r\n (props.length === 1 && (props[0] === 'scale' || props[0] === 'leftOffset'))\r\n )\r\n },\r\n errorTransformer: (error) => error,\r\n titleFormatter: ({ timestamp, duration }, title, time, took) => {\r\n const parts = ['model']\r\n parts.push(`%c${String(title)}`)\r\n if (timestamp) {\r\n parts.push(`%c@ ${time}`)\r\n }\r\n if (duration) {\r\n parts.push(`%c(in ${took.toFixed(2)} ms)`)\r\n }\r\n return parts.join(' ')\r\n },\r\n colors: {\r\n title: () => 'inherit',\r\n prevState: () => '#9E9E9E',\r\n action: () => '#03A9F4',\r\n nextState: () => '#4CAF50',\r\n error: () => '#F20404',\r\n },\r\n}\r\n\r\nconst repeat = (str, times) => new Array(times + 1).join(str)\r\nconst pad = (num, maxLength = 2) => repeat('0', maxLength - num.toString().length) + num\r\nconst formatTime = (time) =>\r\n `${pad(time.getHours())}:${pad(time.getMinutes())}:${pad(time.getSeconds())}.${pad(time.getMilliseconds(), 3)}`\r\n\r\nexport const printLogEntry = (logEntry, options = {}) => {\r\n const { logger, logErrors, titleFormatter, collapsed, timestamp, duration, withStackTrace, colors, level } = {\r\n ...defaults,\r\n ...options,\r\n }\r\n const { startedTime, title, prevState, data, error, nextState, took } = logEntry\r\n\r\n const formattedTime = formatTime(startedTime)\r\n const titleCSS = colors.title ? `color: ${colors.title(title)};` : ''\r\n const headerCSS = ['color: gray; font-weight: lighter;']\r\n headerCSS.push(titleCSS)\r\n if (timestamp) {\r\n headerCSS.push('color: gray; font-weight: lighter;')\r\n }\r\n if (duration) {\r\n headerCSS.push('color: gray; font-weight: lighter;')\r\n }\r\n const formattedTitle = titleFormatter(defaults, title, formattedTime, took)\r\n\r\n try {\r\n if (collapsed) {\r\n if (colors.title) {\r\n logger.groupCollapsed(`%c ${formattedTitle}`, ...headerCSS)\r\n } else {\r\n logger.groupCollapsed(formattedTitle)\r\n }\r\n } else if (colors.title) {\r\n logger.group(`%c ${formattedTitle}`, ...headerCSS)\r\n } else {\r\n logger.group(formattedTitle)\r\n }\r\n } catch (e) {\r\n logger.log(formattedTitle)\r\n }\r\n\r\n if (colors.prevState) {\r\n const styles = `color: ${colors.prevState(prevState)}; font-weight: bold`\r\n logger[level]('%c prev state', styles, prevState)\r\n } else {\r\n logger[level]('prev state', prevState)\r\n }\r\n\r\n if (colors.action) {\r\n const styles = `color: ${colors.action(data)}; font-weight: bold`\r\n logger[level]('%c arguments ', styles, data)\r\n } else {\r\n logger[level]('arguments ', data)\r\n }\r\n\r\n if (error && logErrors) {\r\n if (colors.error) {\r\n const styles = `color: ${colors.error(error, prevState)}; font-weight: bold;`\r\n logger['error']('%c error ', styles, error)\r\n } else {\r\n logger['error']('error ', error)\r\n }\r\n }\r\n\r\n if (colors.nextState) {\r\n const styles = `color: ${colors.nextState(nextState)}; font-weight: bold`\r\n logger[level]('%c next state', styles, nextState)\r\n } else {\r\n logger[level]('next state', nextState)\r\n }\r\n\r\n if (withStackTrace) {\r\n logger.groupCollapsed('TRACE')\r\n logger.trace()\r\n logger.groupEnd()\r\n }\r\n\r\n try {\r\n logger.groupEnd()\r\n } catch (e) {\r\n logger.log('—— log end ——')\r\n }\r\n}\r\n\r\nexport const initialize = () => {\r\n window['logger'] = defaults\r\n\r\n const protoModelLoad = Spine.Model.prototype.load\r\n Spine.Model.prototype.load = function (attrs) {\r\n if (defaults.enabled && !defaults.filterChanges(this, attrs)) {\r\n const started = Date.now()\r\n const logEntry = {\r\n title: `${this.constructor.name}[#${this.id || this.cid}]`,\r\n started: started,\r\n startedTime: new Date(started),\r\n prevState: this.attributes(),\r\n data: attrs,\r\n }\r\n\r\n let returnedValue\r\n try {\r\n returnedValue = protoModelLoad.apply(this, arguments)\r\n } catch (e) {\r\n logEntry.error = e\r\n }\r\n\r\n logEntry.nextState = this.attributes()\r\n logEntry.took = Date.now() - logEntry.started\r\n\r\n printLogEntry(logEntry)\r\n return returnedValue\r\n } else {\r\n return protoModelLoad.apply(this, arguments)\r\n }\r\n }\r\n}\r\n","import { ObjectHash } from '../../types/shared'\r\nimport { Theme } from '../../types/shared'\r\nimport ChartEvent from '../chart-events/chart-event'\r\nimport { ChartEventBadgeType } from '../constants/common'\r\nimport { chartEventsAsyncModule } from '../controllers/chart-events/async-modules'\r\nimport ElementModel from '../models/element'\r\nimport { ChartEventBadgeState, IChartEventBadgeProps } from '../utils/chart-events-utils'\r\nimport { captureException } from '../utils/helpers'\r\nimport { CHART_EVENT_BADGE_SIZE } from './constants'\r\nimport Pane from './pane'\r\n\r\nconst badgeImages = {} as ObjectHash<{ image: HTMLImageElement; isLoaded?: boolean }, string>\r\n\r\ntype ChartEventBadgeCommonType = Omit & { badgeType: ChartEventBadgeType }\r\n\r\nfunction getSvgImageCacheKey(props: Pick) {\r\n return `${props.badgeType}-${props.theme}-${props.state}`\r\n}\r\n\r\nasync function fetchAndCacheChartEventBadges({ onBadgeInitLoad }: { onBadgeInitLoad: () => void }) {\r\n // Currently node charts don't render badges and if the code below is executed on server it will crash because of missing file which is not transpiled\r\n if (typeof window === 'undefined') {\r\n return\r\n }\r\n\r\n // Temp workaround to prevent node charts from crashing\r\n const { importWithRetry } = await import('@finviz/website')\r\n const { chartBadgeSvgByType } = await importWithRetry(chartEventsAsyncModule.importFn)\r\n\r\n const handleImageResolve = () => {\r\n const hasSomeUnresolvedImages = Object.values(badgeImages).some(({ isLoaded }) => isLoaded === undefined)\r\n if (!hasSomeUnresolvedImages) {\r\n onBadgeInitLoad()\r\n }\r\n }\r\n\r\n Object.values(ChartEventBadgeState).forEach((badgeState) => {\r\n Object.values(ChartEventBadgeType).forEach((badgeType) => {\r\n Object.values(Theme).forEach((theme) => {\r\n const cacheKey = getSvgImageCacheKey({\r\n badgeType,\r\n state: badgeState,\r\n theme,\r\n })\r\n const svgHTML = chartBadgeSvgByType[badgeType]({\r\n state: badgeState,\r\n theme,\r\n width: CHART_EVENT_BADGE_SIZE,\r\n })\r\n const img = new Image()\r\n img.src = `data:image/svg+xml,${encodeURIComponent(svgHTML)}`\r\n img.onload = () => {\r\n badgeImages[cacheKey].isLoaded = true\r\n handleImageResolve()\r\n }\r\n img.onerror = () => {\r\n badgeImages[cacheKey].isLoaded = false\r\n handleImageResolve()\r\n captureException(new Error(`Image with cache key ${cacheKey} is invalid`), { extra: { src: img.src } })\r\n }\r\n badgeImages[cacheKey] = {\r\n image: img,\r\n }\r\n })\r\n })\r\n })\r\n}\r\n\r\nclass ChartEventElement extends ElementModel {\r\n static initClass(paneModel: typeof Pane) {\r\n this.configure('ChartEventElement', 'instance', 'lastChange', 'zIndex', 'yIndex', 'elementId')\r\n this.belongsTo('pane', paneModel)\r\n }\r\n\r\n declare instance: ChartEvent\r\n yIndex = 0\r\n\r\n getChartEventBadgeImage(props: ChartEventBadgeCommonType) {\r\n const cacheKey = getSvgImageCacheKey(props)\r\n const badgeImage = badgeImages[cacheKey]\r\n if (badgeImage) {\r\n // Possible fix for https://finvizcom.sentry.io/issues/4737062163\r\n if (badgeImage.isLoaded && badgeImage.image.width > 0 && badgeImage.image.height > 0) {\r\n return badgeImage.image\r\n }\r\n return undefined\r\n }\r\n\r\n void fetchAndCacheChartEventBadges({\r\n onBadgeInitLoad: () => this.trigger('change', this),\r\n })\r\n }\r\n\r\n getChartEventData() {\r\n return this.instance.model\r\n .chart()\r\n .quote()\r\n ?.chartEvents?.find((stockEvent) => stockEvent.elementId === this?.elementId)\r\n }\r\n\r\n toObject() {\r\n return {\r\n ...super.toObject(),\r\n yIndex: this.yIndex,\r\n }\r\n }\r\n\r\n toConfig() {\r\n return {\r\n ...super.toConfig(),\r\n yIndex: this.yIndex,\r\n }\r\n }\r\n}\r\n\r\nexport default ChartEventElement\r\n","import Spine from '@finviz/spine'\r\n\r\nimport Chart from './chart'\r\n\r\nclass Indicator extends Spine.Model {\r\n static initClass(chartModel: typeof Chart) {\r\n this.configure('Indicator', 'instance')\r\n this.belongsTo('chart', chartModel)\r\n }\r\n\r\n declare chart: () => Chart\r\n\r\n // instance - todo - not sure what instance type to put here\r\n}\r\n\r\nexport default Indicator\r\n","import Spine from '@finviz/spine'\r\n\r\nimport Chart from './chart'\r\n\r\nclass Overlay extends Spine.Model {\r\n static initClass(chartModel: typeof Chart) {\r\n this.configure('Overlay', 'overlay')\r\n this.belongsTo('chart', chartModel)\r\n }\r\n\r\n declare overlay: any\r\n declare chart: () => Chart\r\n}\r\n\r\nexport default Overlay\r\n","/**\r\n * This file sets up the relationships between models and solves circular dependencies\r\n * This file needs to be imported in the index file so that the relationships are\r\n * called in time for instantiation.\r\n */\r\nimport Chart from './chart'\r\nimport ChartEventElement from './chart-event-element'\r\nimport ChartLayout from './chart_layout'\r\nimport DrawingsInternalStore from './drawings-internal-store'\r\nimport Element from './element'\r\nimport Indicator from './indicator'\r\nimport Overlay from './overlay'\r\nimport Pane from './pane'\r\nimport Quote from './quote'\r\n\r\nChart.initClass(Pane, Quote, ChartLayout)\r\nChartLayout.initClass(Chart, DrawingsInternalStore)\r\nDrawingsInternalStore.initClass()\r\nElement.initClass(Pane)\r\nChartEventElement.initClass(Pane)\r\nIndicator.initClass(Chart)\r\nOverlay.initClass(Chart)\r\nPane.initClass(Element, ChartEventElement, Chart)\r\n","import './lib/shims'\r\nimport { initialize } from './logger'\r\nimport './models/relationships'\r\n\r\nif (document.location.hostname === 'localhost') {\r\n initialize()\r\n}\r\n","import { Button } from '@finviz/website'\r\nimport * as React from 'react'\r\n\r\nimport Utils, { getExitFullscreen, getFullscreenStatus, getRequestFullscreen } from '../../utils'\r\n\r\nconst isIPad = Utils.isIPad()\r\nconst IPAD_FULLSCREEN_CLASS = 'is-ipad-fullscreen'\r\n\r\nexport function FullscreenButton() {\r\n const [isFullscreen, setIsFullscreen] = React.useState(getFullscreenStatus())\r\n const requestFullscreen = getRequestFullscreen(document.documentElement)\r\n const exitFullscreen = getExitFullscreen()\r\n\r\n const onClick = React.useRef(() => {\r\n if (getFullscreenStatus()) {\r\n exitFullscreen.call(document)\r\n } else {\r\n requestFullscreen.call(document.documentElement)\r\n }\r\n })\r\n\r\n React.useEffect(() => {\r\n const checkFullscreen = () => {\r\n if (isIPad) {\r\n if (getFullscreenStatus()) {\r\n document.body.classList.add(IPAD_FULLSCREEN_CLASS)\r\n } else {\r\n document.body.classList.remove(IPAD_FULLSCREEN_CLASS)\r\n }\r\n }\r\n setIsFullscreen(getFullscreenStatus())\r\n }\r\n\r\n document.addEventListener('webkitfullscreenchange', checkFullscreen)\r\n document.addEventListener('fullscreenchange', checkFullscreen)\r\n return () => {\r\n document.removeEventListener('webkitfullscreenchange', checkFullscreen)\r\n document.removeEventListener('fullscreenchange', checkFullscreen)\r\n }\r\n }, [])\r\n\r\n if (!requestFullscreen) return null\r\n\r\n return (\r\n \r\n {isFullscreen ? 'Exit Full screen' : 'Full screen'}\r\n \r\n )\r\n}\r\n","import {\r\n Button,\r\n Dropdown,\r\n DropdownItem,\r\n DropdownSeparator,\r\n Icon,\r\n IconNameType,\r\n Paragraph,\r\n useDropdownState,\r\n} from '@finviz/website'\r\nimport * as React from 'react'\r\nimport { useLocation, useNavigate } from 'react-router-dom'\r\n\r\nimport { LAYOUTS } from '../../constants/common'\r\nimport { sortObjects } from '../../helpers/sorter'\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport { ChartSyncableParts } from '../../models/chart/contstants'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { decodeQueryString } from '../../utils/query_string'\r\nimport { useChartsPathLocation } from '../chart-controls/use-charts-path-location'\r\n\r\nconst SORTED_LAYOUT_KEYS = sortObjects(\r\n Object.entries(LAYOUTS).map(([key, value]) => ({ ...value, key })),\r\n [{ sortBy: 'columns' }, { sortBy: 'count' }]\r\n).map(({ key }) => key)\r\n\r\nexport function ChartLayoutDropdown({ model }: { model: ChartLayout }) {\r\n const location = useLocation()\r\n const navigate = useNavigate()\r\n const parsedQuery = decodeQueryString(location.search)\r\n const chartLayoutModel = useModelState(model, { watchProperties: ['layout', 'syncChartParts'] })\r\n const { getChartsToPath } = useChartsPathLocation({ chartLayoutModel })\r\n const state = useDropdownState({ placement: 'bottom', orientation: 'horizontal' })\r\n\r\n return (\r\n \r\n Layout\r\n \r\n }\r\n >\r\n
\r\n
\r\n {SORTED_LAYOUT_KEYS.map((layout) => (\r\n {\r\n navigate(getChartsToPath({ layout }))\r\n }}\r\n >\r\n \r\n \r\n ))}\r\n
\r\n \r\n
\r\n
\r\n Sync:\r\n
\r\n {ChartSyncableParts.map(({ value, label }) => {\r\n const isChartPartInSync = chartLayoutModel.getIsChartPartInSync(value)\r\n return (\r\n {\r\n chartLayoutModel.setSyncChartParts(value, !isChartPartInSync)\r\n if (!isChartPartInSync) window.gtag?.('event', 'sync', { event_label: value })\r\n }}\r\n >\r\n {label}\r\n \r\n )\r\n })}\r\n
\r\n
\r\n \r\n )\r\n}\r\n","import { ObjectHash } from '../../types/shared'\r\nimport { SORT_DIRECTION } from '../constants/common'\r\n\r\nexport function sortObjects(\r\n arr: ObjectHash[],\r\n options: Array<{ sortBy: string; sortDirection?: keyof typeof SORT_DIRECTION }> = []\r\n) {\r\n return arr.sort((a, b) =>\r\n options.reduce((acc, option) => {\r\n const { sortBy, sortDirection = SORT_DIRECTION.ASC } = option\r\n const directionMultiplier = sortDirection === SORT_DIRECTION.ASC ? 1 : -1\r\n return acc === 0 ? (a[sortBy] - b[sortBy]) * directionMultiplier : acc\r\n }, 0)\r\n )\r\n}\r\n","import { Button, setCookieRequest } from '@finviz/website'\r\nimport * as React from 'react'\r\n\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { updateSettings } from '../../models/settings'\r\n\r\nexport function ThemeToggleButton({ model }: { model: ChartLayout }) {\r\n const chartLayoutModel = useModelState(model, { watchProperties: ['theme'] })\r\n const isDarkMode = model.theme === 'dark'\r\n\r\n const onClick = () => {\r\n const theme = isDarkMode ? 'light' : 'dark'\r\n chartLayoutModel.updateAttributes({ theme, settings: updateSettings(chartLayoutModel, theme) })\r\n chartLayoutModel.trigger('theme', chartLayoutModel)\r\n setCookieRequest('chartsTheme', theme).catch(() => {})\r\n\r\n if (isDarkMode) {\r\n document.documentElement.classList.remove('dark')\r\n } else {\r\n document.documentElement.classList.add('dark')\r\n }\r\n }\r\n\r\n if (!chartLayoutModel) {\r\n return null\r\n }\r\n\r\n return (\r\n \r\n )\r\n}\r\n","import { Button, Time, TimeBreakpoint } from '@finviz/website'\r\nimport * as React from 'react'\r\n\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { FullscreenButton } from './fullscreen_button'\r\nimport { IdeasDropdown } from './ideas_dropdown'\r\nimport { ChartLayoutDropdown } from './layout_dropdown'\r\nimport { Publish } from './publish'\r\nimport { ThemeToggleButton } from './theme_toggle_button'\r\nimport { TourButton } from './tour_button'\r\n\r\nconst BREAKPOINTS: TimeBreakpoint[] = [\r\n { minWidth: -Infinity, marketBadgeText: false, timeFormat: 'timeOnly' },\r\n { minWidth: 550, marketBadgeText: false, timeFormat: 'short' },\r\n { minWidth: 700, marketBadgeText: false, timeFormat: 'long' },\r\n { minWidth: 768, marketBadgeText: true, timeFormat: 'long' },\r\n]\r\n\r\ninterface ChartLayoutHeaderProps {\r\n model: ChartLayout\r\n onSettingsOpen: () => void\r\n hasPublish: boolean\r\n}\r\n\r\nexport function ChartLayoutHeaderComponent({ model, onSettingsOpen = () => {}, hasPublish }: ChartLayoutHeaderProps) {\r\n const chartLayout = useModelState(model, { watchProperties: ['idea'] })!\r\n\r\n return (\r\n <>\r\n
\r\n \r\n Ideas\r\n \r\n
\r\n
\r\n \r\n Chart tour\r\n \r\n \r\n \r\n {hasPublish && (\r\n \r\n Share\r\n \r\n )}\r\n \r\n \r\n \r\n
\r\n \r\n )\r\n}\r\n\r\nexport const ChartLayoutHeader = React.memo(\r\n ChartLayoutHeaderComponent,\r\n (prevProps, nextProps) =>\r\n prevProps.model === nextProps.model &&\r\n prevProps.onSettingsOpen === nextProps.onSettingsOpen &&\r\n prevProps.hasPublish === nextProps.hasPublish\r\n)\r\n","import {\r\n ButtonSizeType,\r\n CustomDateRange,\r\n TimeframeBar,\r\n useCustomDateRangeDialog,\r\n useFavoriteTimeframes,\r\n withSuspense,\r\n} from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport { Instrument } from '../../../types/shared'\r\nimport { TIMEFRAME } from '../../constants/common'\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport { isRedesignEnabled } from '../../utils'\r\nimport { useChartLayoutGlobalModelAsync } from '../../utils/useChartLayoutGlobalModelAsync'\r\nimport { useChartControls } from './use-chart-controls'\r\nimport { IDateRange, useChartModelCustomDateRangeValues } from './use-chart-model-custom-date-range-values'\r\n\r\nfunction StockDetailTimeframeBarRaw({\r\n size = 'regular',\r\n className = '!m-0 space-x-2',\r\n isDateRangeAvailable,\r\n isPremium,\r\n isLoadingOverride,\r\n isScrollIntoViewEnabled = false,\r\n onTimeframeSelect = () => {},\r\n onDateRangeSelect = () => {},\r\n}: {\r\n size?: ButtonSizeType\r\n className?: string\r\n isDateRangeAvailable: boolean\r\n isPremium: boolean\r\n isLoadingOverride?: boolean\r\n isScrollIntoViewEnabled?: boolean\r\n onTimeframeSelect?: (timeframe: any) => void\r\n onDateRangeSelect?: (timeframe: any) => void\r\n}) {\r\n const { chartLayoutModel } = useChartLayoutGlobalModelAsync()\r\n const chartModelUnwatched = React.useMemo(() => chartLayoutModel?.getAllCharts()[0] ?? null, [chartLayoutModel])\r\n const { favoriteTimeframes, toggleFavoriteTimeframe } = useFavoriteTimeframes(isPremium)\r\n const chartModel = useModelState(chartModelUnwatched, {\r\n watchProperties: ['timeframe', 'dateRange'],\r\n })\r\n const { instrument = Instrument.Stock } = chartModel?.quote() || {}\r\n const { isLoading } = useChartControls({\r\n chartModel,\r\n isInteractive: isDateRangeAvailable,\r\n })\r\n\r\n const {\r\n anchorDate,\r\n generateChartLayoutRouterPath,\r\n timeframeGroupsWithHref,\r\n dateRangeGroupsWithHref,\r\n isFetching,\r\n handleCustomDateRangeValidation,\r\n } = useChartModelCustomDateRangeValues({ chartModel, isPremium })\r\n const { onDialogSubmit, customDateRangeDialogState, handleDateRangeSelect, getDateRangeTimeframe } =\r\n useCustomDateRangeDialog({\r\n instrument,\r\n anchorDate,\r\n pathGenerator: generateChartLayoutRouterPath,\r\n })\r\n\r\n const dateRangeGroups = dateRangeGroupsWithHref({ isPremium, customRange: chartModel?.dateRange, instrument })\r\n const timeFrameGroups = timeframeGroupsWithHref(isPremium)\r\n\r\n async function handleCustomRangeSubmit(values: { dateRange: string | null }) {\r\n const dateRangeTimeframe = getDateRangeTimeframe(values.dateRange) as IDateRange | null\r\n if (!dateRangeTimeframe) return\r\n\r\n const isValid = await handleCustomDateRangeValidation(dateRangeTimeframe)\r\n if (isValid) onDialogSubmit(dateRangeTimeframe, onDateRangeSelect)\r\n }\r\n\r\n return (\r\n <>\r\n {\r\n handleDateRangeSelect(value)\r\n onDateRangeSelect?.(value)\r\n }}\r\n onCustomDateRangeClick={() => {\r\n if (isPremium) customDateRangeDialogState.show()\r\n }}\r\n onTimeframeSelect={onTimeframeSelect}\r\n onFavoriteTimeframeToggle={({ value }: { value: string }) => {\r\n toggleFavoriteTimeframe(value as TIMEFRAME)\r\n }}\r\n isDateRangeAvailable={isDateRangeAvailable}\r\n containerElement={document.body}\r\n className={className}\r\n isFavoritesEnabled={isPremium}\r\n isScrollIntoViewEnabled={isScrollIntoViewEnabled}\r\n />\r\n\r\n {chartModel && (\r\n \r\n )}\r\n \r\n )\r\n}\r\n\r\nexport const StockDetailTimeframeBar = withSuspense(StockDetailTimeframeBarRaw)\r\n","import { ChartConfigChartPane, Position, RootChartConfigObject } from '../../types/shared'\r\nimport { ChartElementType, IndicatorType, OverlayType, PANE_HEIGHT_DEFAULT, ScaleType } from '../constants/common'\r\n\r\nfunction hasPaneWithCOTCode(panes: ChartConfigChartPane[], code: string) {\r\n return panes.some(({ elements }) =>\r\n elements.some((element) => element.type === IndicatorType.Cot && element.code === code)\r\n )\r\n}\r\nfunction pushIndicators(\r\n panes: ChartConfigChartPane[],\r\n indicator: { name: string; parameters: string },\r\n options?: { COTs?: string[] }\r\n) {\r\n if (indicator.name === 'cot') {\r\n const cotKeys = options?.COTs ?? []\r\n if (cotKeys.length === 0) {\r\n cotKeys.push('')\r\n }\r\n cotKeys.forEach(function (code: string) {\r\n if (!hasPaneWithCOTCode(panes, code)) {\r\n panes.push({\r\n height: PANE_HEIGHT_DEFAULT.indicator,\r\n elements: [\r\n {\r\n type: IndicatorType.Cot,\r\n code,\r\n },\r\n ],\r\n })\r\n }\r\n })\r\n } else {\r\n panes.push({\r\n height: PANE_HEIGHT_DEFAULT.indicator,\r\n elements: [\r\n {\r\n type: ('indicators/' + indicator.name) as IndicatorType,\r\n period: indicator.parameters,\r\n },\r\n ],\r\n })\r\n }\r\n}\r\n\r\nfunction getChartTypeByTaConfigStyle(style: string) {\r\n const chartTypeMap = {\r\n candlestick: ChartElementType.CandleStick,\r\n heikinashi: ChartElementType.HeikinAshi,\r\n hollowcandlestick: ChartElementType.HollowCandleStick,\r\n line: ChartElementType.LineChart,\r\n ohlc: ChartElementType.OhlcChart,\r\n }\r\n return chartTypeMap[style as keyof typeof chartTypeMap]\r\n}\r\n\r\nfunction getChartScaleByTaConfigScale(scale: string | undefined) {\r\n const chartScaleMap = {\r\n linear: ScaleType.Linear,\r\n percentage: ScaleType.Percentage,\r\n logarithmic: ScaleType.Logarithmic,\r\n }\r\n return chartScaleMap[scale as keyof typeof chartScaleMap] ?? ScaleType.Linear\r\n}\r\n\r\n/*\r\n * Merges chartConfig (in \"chart\" format) with taConfig (in format that TA is preserved in DB)\r\n */\r\nexport const mergeChartAndTAConfig = function convertTA(\r\n chartConfig: RootChartConfigObject,\r\n taConfig: TaConfigObject,\r\n options?: { COTs: string[] }\r\n) {\r\n const panes = chartConfig.charts[0].panes\r\n const chart = chartConfig.charts[0]\r\n\r\n chart.scale = getChartScaleByTaConfigScale(taConfig.scale)\r\n\r\n taConfig.indicators\r\n .filter((indicator) => indicator.position === Position.Above)\r\n .forEach((indicator) => {\r\n pushIndicators(panes, indicator, options)\r\n })\r\n\r\n const overlays = taConfig.overlays.map(function (overlay) {\r\n return {\r\n type: ('overlays/' + overlay.name) as OverlayType,\r\n period: overlay.parameters ?? '',\r\n color: overlay.color ?? '',\r\n }\r\n })\r\n panes.push({\r\n height: PANE_HEIGHT_DEFAULT.chart,\r\n elements: [\r\n {\r\n type: getChartTypeByTaConfigStyle(taConfig.style),\r\n overlays: overlays,\r\n },\r\n ],\r\n })\r\n\r\n taConfig.indicators\r\n .filter((indicator) => indicator.position === Position.Below)\r\n .forEach((indicator) => {\r\n pushIndicators(panes, indicator, options)\r\n })\r\n\r\n chartConfig.height = chart.height = PANE_HEIGHT_DEFAULT.chart + (panes.length - 1) * PANE_HEIGHT_DEFAULT.indicator\r\n}\r\n\r\nexport const getPanes = function getPanes(taConfig: TaConfigObject) {\r\n const options = {}\r\n const panes: ChartConfigChartPane[] = []\r\n\r\n taConfig.indicators\r\n .filter((indicator) => indicator.position === Position.Above)\r\n .forEach((indicator) => {\r\n pushIndicators(panes, indicator, options)\r\n })\r\n\r\n const overlays = taConfig.overlays.map(function (overlay) {\r\n return {\r\n type: ('overlays/' + overlay.name) as OverlayType,\r\n period: overlay.parameters ?? '',\r\n color: overlay.color ?? '',\r\n }\r\n })\r\n panes.push({\r\n height: PANE_HEIGHT_DEFAULT.chart,\r\n elements: [\r\n {\r\n type: getChartTypeByTaConfigStyle(taConfig.style),\r\n overlays: overlays,\r\n },\r\n ],\r\n })\r\n\r\n taConfig.indicators\r\n .filter((indicator) => indicator.position === Position.Below)\r\n .forEach((indicator) => {\r\n pushIndicators(panes, indicator, options)\r\n })\r\n\r\n return panes\r\n}\r\n","export * from 'finviz-charts/app/lib-export'\r\n\r\nexport enum SettingsTab {\r\n Chart = 'chart',\r\n Colors = 'colors',\r\n}\r\n\r\nexport enum SidebarDirection {\r\n vertical,\r\n horizontal,\r\n}\r\n","export const createAlertAsyncModule = {\r\n importFn: () => import(/* webpackChunkName: \"create-alert\" */ './module-entry'),\r\n cacheKey: 'create-alert',\r\n}\r\n","export const saveToPortfolioAsyncModule = {\r\n importFn: () => import(/* webpackChunkName: \"save-to-portfolio\" */ './module-entry'),\r\n cacheKey: 'save-to-portfolio',\r\n}\r\n","export enum AdsProvider {\r\n None,\r\n InvestingChannel,\r\n Freestar,\r\n}\r\n\r\nexport function getAdsProvider() {\r\n if (FinvizSettings.hasUserPremium) return AdsProvider.None\r\n\r\n if (FinvizSettings.adsProvider === 2) {\r\n return AdsProvider.Freestar\r\n }\r\n\r\n return AdsProvider.InvestingChannel\r\n}\r\n\r\n/**\r\n * Tracks virtual page views to google analytics and freestar\r\n */\r\nexport function trackPageView(props: { pathname?: string; query?: string; freestarPageView?: boolean }) {\r\n const { pathname = window.location.pathname, query = window.location.search, freestarPageView = true } = props\r\n\r\n window.gtag?.('set', 'page_path', `${pathname}${query.length ? '?' : ''}${query.replace(/^\\?/, '')}`)\r\n window.gtag?.('event', 'page_view')\r\n\r\n if (freestarPageView && getAdsProvider() === AdsProvider.Freestar) {\r\n window.freestar?.queue.push(() => freestar.trackPageview())\r\n }\r\n}\r\n","export const portfolioWatchlistTableAsyncModule = {\r\n importFn: () => import(/* webpackChunkName: \"portfolio-watchlist-table\" */ './PortfolioWatchlistTable'),\r\n cacheKey: 'portfolio-watchlist-table',\r\n}\r\n","import logo from './app/shared/assets/logo.png'\r\nimport logo_light from './app/shared/assets/logo_light.png'\r\n\r\nexport * from './main/components'\r\n\r\nexport { getSanitizedTicker } from './app/shared/ticker-sanitizer'\r\nexport * from './app/queryString'\r\nexport * from './main/modules/portfolio/types'\r\n\r\nexport { getFormattedDateString } from './app/header/utils'\r\nexport { decodeQueryString, encodeQueryString } from './app/queryString'\r\nexport { createAlertAsyncModule } from './app/quote/create-alert/async-modules'\r\nexport { saveToPortfolioAsyncModule } from './app/quote/save-to-portfolio/async-modules'\r\nexport { formatDateToStringUS } from './app/shared/utils'\r\nexport { portfolioWatchlistTableAsyncModule } from './main/components/portfolio/async-modules'\r\nexport { useTrackPageView } from './main/hooks/use-track-pageview'\r\nexport {\r\n useAsyncModule,\r\n withSuspense,\r\n type ControlledModuleConfig,\r\n type SuspenseModuleConfig,\r\n} from './main/services/async-modules-utils'\r\nexport { importWithRetry } from './main/services/import-with-retry'\r\nexport * as localStorage from './main/services/local-storage'\r\nexport { waitForPreviousPromise } from './main/services/wait-for-previous-promise'\r\nexport { setCookieRequest } from './main/services/api'\r\n\r\nexport const assets = { logo, logo_light }\r\n\r\n// Re-export Portal so we can use it when we can’t use `modal` components (see chart event popover)\r\nexport { Portal as AriakitPortal } from '@ariakit/react'\r\n","import * as React from 'react'\r\nimport { useLocation } from 'react-router-dom'\r\n\r\nimport * as tracking from '../../app/shared/tracking'\r\n\r\nexport function useTrackPageView(props?: { trackInitial?: boolean; trackAutomatically?: boolean }) {\r\n const { trackInitial = false, trackAutomatically = true } = props ?? {}\r\n const initialRender = React.useRef(trackInitial)\r\n const location = useLocation()\r\n\r\n const handleTrackView = React.useCallback(() => {\r\n tracking.trackPageView({ pathname: location.pathname, query: location.search })\r\n }, [location.pathname, location.search])\r\n\r\n React.useEffect(() => {\r\n if (!trackAutomatically) return\r\n if (initialRender.current) handleTrackView()\r\n initialRender.current = true\r\n }, [trackAutomatically, handleTrackView, trackInitial])\r\n\r\n return handleTrackView\r\n}\r\n","import { TableAlign } from '../../components/Table'\r\nimport { SortByShape } from '../../hooks/use-sort-data'\r\nimport { NullableNumbers } from '../../types'\r\n\r\nexport enum PortfolioQuery {\r\n View = 'v',\r\n TableView = 'tv',\r\n PortfolioId = 'pid',\r\n Order = 'o',\r\n Tickers = 't',\r\n Map = 'map',\r\n Size = 'mapSize',\r\n Subtype = 'subtype',\r\n Group = 'group',\r\n}\r\n\r\nexport enum PortfolioMapSizeKey {\r\n MarketValue = 'market',\r\n Gain = 'gain',\r\n}\r\n\r\nexport enum PortfolioView {\r\n View = '1',\r\n Edit = '2',\r\n}\r\n\r\nexport enum PortfolioTableView {\r\n Ticker = '1',\r\n Trade = '2',\r\n}\r\n\r\nexport const PortfolioTableViewLabels = {\r\n [PortfolioTableView.Ticker]: 'Tickers',\r\n [PortfolioTableView.Trade]: 'Trades',\r\n}\r\n\r\nexport enum PortfolioSymbolType {\r\n Stock = 'stock',\r\n Cash = 'cash',\r\n}\r\n\r\nexport enum PortfolioTransaction {\r\n Watch = 0,\r\n\r\n // Stock transactions\r\n Buy = 1,\r\n Short = 2,\r\n\r\n // Cash transactions\r\n CashDeposit = 200,\r\n CashWithdraw = 201,\r\n CashIncome = 202,\r\n CashFee = 203,\r\n}\r\n\r\nexport enum NumberOfShares {\r\n None = 0,\r\n /**\r\n * The usage of this is technically incorrect. The value for `PositiveNumber` is 1.\r\n * But we don’t care in this context, because we only want to differentiate betwen zero/non-zero values,\r\n * which helps us get correct types.\r\n *\r\n * # Don’t compare `entry.shares === NumberOfShares.PositiveNumber`\r\n */\r\n PositiveNumber = 1,\r\n}\r\n\r\nexport interface PortfolioEntryBase {\r\n id: number\r\n ticker: string\r\n date: string\r\n transaction: PortfolioTransaction\r\n shares: number\r\n price: number\r\n type: PortfolioSymbolType\r\n}\r\n\r\n/**\r\n * Base type which lists all common properties\r\n */\r\nexport interface PortfolioEntryComputed {\r\n valuePaid: number\r\n valueMarket: number\r\n valueMarketPrev: number\r\n gainMarket: number\r\n gainMarketPct: number\r\n gainMarketUsd: number\r\n gainTodayUsd: number\r\n lastChangePct: number\r\n}\r\n\r\n/**\r\n * Transaction with > 0 shares\r\n */\r\nexport interface PortfolioTransactionStake extends PortfolioEntryBase, PortfolioEntryComputed {\r\n shares: NumberOfShares.PositiveNumber\r\n}\r\n\r\n/**\r\n * Transaction with 0 shares\r\n */\r\nexport interface PortfolioTransactionWatch\r\n extends Omit,\r\n NullableNumbers {\r\n shares: NumberOfShares.None\r\n transaction: PortfolioTransaction\r\n}\r\n\r\nexport type PortfolioEntryTransaction = PortfolioTransactionStake | PortfolioTransactionWatch\r\n\r\nexport type PortfolioActionType = PortfolioEntryTransaction & { isNotification?: boolean; message?: string }\r\n\r\n/**\r\n * Top level portfolio entry\r\n */\r\nexport interface PortfolioGroup extends PortfolioEntryComputed {\r\n ticker: string\r\n shares: number\r\n industry: string\r\n country: string\r\n company: string\r\n marketCap: number\r\n prevClose: number\r\n lastClose: number\r\n lastVolume: number\r\n perfWeek: number\r\n costAvg: number\r\n transactions: PortfolioEntryTransaction[]\r\n order: number\r\n id: number\r\n date: string\r\n type: PortfolioSymbolType\r\n isDelisted?: true\r\n}\r\n\r\nexport type PortfolioTrade = Omit & PortfolioEntryTransaction\r\n\r\nexport type PortfolioMapEntry = Omit & PortfolioTransactionStake\r\n\r\n/**\r\n * Summary row for the whole portfolio\r\n */\r\nexport interface PortfolioSummary {\r\n tickers: number\r\n transactions: number\r\n shares: number\r\n lastChangePct: number\r\n valuePaid: number\r\n valueMarket: number\r\n valueMarketStocks: number\r\n valueMarketStocksPrev: number\r\n gainMarketUsd: number\r\n gainMarketPct: number\r\n gainTodayUsd: number\r\n}\r\n\r\nexport interface PortfolioDefinition {\r\n id: number\r\n name: string\r\n order: number\r\n}\r\n\r\nexport interface PortfolioInitData {\r\n limit: number\r\n limitTransactions: number\r\n selectedPortfolio: number\r\n portfolios: PortfolioDefinition[]\r\n portfolio: PortfolioGroup[]\r\n news: string[]\r\n version?: number\r\n}\r\n\r\nexport interface PortfolioFormEntry\r\n extends Pick,\r\n Partial> {\r\n uuid: string\r\n}\r\n\r\nexport interface PortfolioFormGroup extends Pick {\r\n id: string\r\n transactions: PortfolioFormEntry[]\r\n}\r\n\r\nexport enum ColumnId {\r\n Spacer = 'spacer',\r\n Ticker = 'ticker',\r\n Company = 'company',\r\n LastClose = 'lastClose',\r\n CostAvg = 'costAvg',\r\n LastChange = 'lastChange',\r\n LastChangePct = 'lastChangePct',\r\n LastVolume = 'lastVolume',\r\n Transaction = 'transaction',\r\n Date = 'date',\r\n Shares = 'shares',\r\n Price = 'price',\r\n ValuePaid = 'valuePaid',\r\n Amount = 'amount',\r\n ValueMarket = 'valueMarket',\r\n GainMarketUsd = 'gainMarketUsd',\r\n GainMarketPct = 'gainMarketPct',\r\n GainMarketCombined = 'gainMarketCombined',\r\n GainTodayUsd = 'gainTodayUsd',\r\n GainTodayCombined = 'gainTodayCombined',\r\n Order = 'order',\r\n}\r\n\r\nexport enum RowKind {\r\n Group, // A group of transactions\r\n Transaction, // A transaction made inside ticker\r\n Summary, // Portfolio summary\r\n Watchlist, // Charts portfolio watchlist table\r\n Trade,\r\n}\r\n\r\ninterface GroupProps {\r\n kind: RowKind.Group\r\n row: PortfolioGroup\r\n}\r\ninterface TradeProps {\r\n kind: RowKind.Trade\r\n row: PortfolioTrade\r\n}\r\n\r\ninterface TransactionProps {\r\n kind: RowKind.Transaction\r\n row: PortfolioEntryTransaction\r\n}\r\n\r\ninterface SummaryProps {\r\n kind: RowKind.Summary\r\n row: PortfolioSummary\r\n}\r\n\r\ninterface WatchlistProps {\r\n index: number\r\n kind: RowKind.Watchlist\r\n row: PortfolioGroup\r\n}\r\n\r\nexport interface TableColumnDefinition<\r\n PropsType = GroupProps | TradeProps | TransactionProps | SummaryProps | WatchlistProps,\r\n> extends SortByShape {\r\n urlSort: string\r\n name: string\r\n align?: TableAlign\r\n\r\n /**\r\n * Get the value of the column and render it\r\n */\r\n renderColumn: (props: PropsType) => React.ReactNode\r\n}\r\n\r\nexport enum ActionKind {\r\n AddTickers,\r\n RemoveTicker,\r\n AddTransaction,\r\n EditTransaction,\r\n RemoveTransaction,\r\n ReorderTickers,\r\n PortfoliosReorder,\r\n}\r\n\r\nexport interface Action {\r\n kind: ActionKind\r\n payload: PayloadType\r\n}\r\n\r\nexport type AddTickersError = {\r\n tickers?: string\r\n}\r\n\r\nexport interface CreatePortfolioErrors extends AddTickersError {\r\n portfolioName?: string\r\n}\r\n\r\nexport interface CreatePortfolioData {\r\n tickers: string\r\n portfolioName: string\r\n}\r\n\r\nexport type FormErrors = Partial>\r\n\r\nexport interface PortfolioBulkEditErrors {\r\n portfolioName: boolean\r\n rows: Record\r\n}\r\n","import * as React from 'react'\r\n\r\nimport { Notification, useNotification } from '../components/notification'\r\nimport { Paragraph } from '../components/typography'\r\nimport { useIsMounted } from '../hooks/use-is-mounted'\r\nimport { importWithRetry } from './import-with-retry'\r\n\r\nconst cache: any = {}\r\nconst errorsCache: any = {}\r\n\r\nenum ErrorSeverity {\r\n medium,\r\n high,\r\n}\r\n\r\nfunction defaultCaptureException(exception: Error, captureContext?: { extra: Record }) {\r\n if (process.env.NODE_ENV === 'development') {\r\n console.error(exception)\r\n } else {\r\n window.Sentry.captureException(exception, captureContext)\r\n }\r\n}\r\n\r\nexport interface ControlledModuleConfig {\r\n /**\r\n * Suspense mode shouldn’t be used together with controlled loading as it could lead to bugs.\r\n * If you know what you’re doing, add an ignore comment explaining the decision\r\n */\r\n isSuspenseMode?: never\r\n shouldLoadModule?: boolean\r\n}\r\nexport interface SuspenseModuleConfig {\r\n /**\r\n * Controlled loading shouldn’t be used together with suspense mode as it could lead to bugs.\r\n * If you know what you’re doing, add an ignore comment explaining the decision\r\n */\r\n shouldLoadModule?: never\r\n isSuspenseMode?: SuspenseMode\r\n}\r\n\r\n/**\r\n * Hook used to asynchronously load a module\r\n *\r\n * Usage: [wiki](https://github.com/finvizhq/Finviz-Website/wiki/Loading-modules-asynchronously#useasyncmodule)\r\n */\r\nexport function useAsyncModule({\r\n importFn,\r\n onError,\r\n errorSeverity,\r\n cacheKey,\r\n captureException = defaultCaptureException,\r\n shouldLoadModule = false,\r\n isSuspenseMode = false as SuspenseMode,\r\n}: {\r\n importFn: () => Promise\r\n onError?: () => void\r\n cacheKey: string\r\n errorSeverity?: keyof typeof ErrorSeverity\r\n captureException?: typeof defaultCaptureException\r\n} & (ControlledModuleConfig | SuspenseModuleConfig)) {\r\n const notificationContext = useNotification()\r\n const [isLoading, setIsLoading] = React.useState(false)\r\n const [isError, setIsError] = React.useState(false)\r\n const getIsMounted = useIsMounted()\r\n\r\n const handleError = () => {\r\n onError?.()\r\n setIsError(true)\r\n\r\n if (errorSeverity === undefined) {\r\n return\r\n }\r\n\r\n if (ErrorSeverity[errorSeverity] === ErrorSeverity.high) {\r\n window.handleScriptNotLoaded()\r\n window.renderScriptNotLoaded()\r\n }\r\n\r\n if (ErrorSeverity[errorSeverity] === ErrorSeverity.medium) {\r\n notificationContext.show(\r\n \r\n \r\n One or more of the required application components couldn’t be loaded.
Please try to repeat the\r\n action or{' '}\r\n window.location.reload()}>\r\n refresh the page\r\n {' '}\r\n if the problem persists.\r\n
\r\n
\r\n )\r\n }\r\n }\r\n\r\n const loadModule = async () => {\r\n if (cache[cacheKey]) {\r\n return cache[cacheKey]\r\n }\r\n\r\n setIsLoading(true)\r\n\r\n try {\r\n cache[cacheKey] = await importWithRetry(importFn)\r\n } catch (error) {\r\n captureException(error as Error)\r\n handleError()\r\n } finally {\r\n if (getIsMounted()) {\r\n setIsLoading(false)\r\n }\r\n }\r\n\r\n return cache[cacheKey]\r\n }\r\n\r\n React.useEffect(() => {\r\n if (shouldLoadModule) {\r\n loadModule()\r\n }\r\n // We want to run it only on shouldLoadModule change\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [shouldLoadModule])\r\n\r\n const cachedModule = cache[cacheKey]\r\n if (isSuspenseMode) {\r\n if (errorsCache[cacheKey]) throw errorsCache[cacheKey]\r\n if (!cachedModule) {\r\n throw importFn()\r\n .then((mod) => (cache[cacheKey] = mod))\r\n .catch((err) => {\r\n handleError()\r\n errorsCache[cacheKey] = err\r\n })\r\n }\r\n }\r\n\r\n return [cachedModule ?? null, { isLoading, loadModule, isError }] as [\r\n SuspenseMode extends true ? T : T | null,\r\n { isLoading: boolean; loadModule: () => Promise; isError: boolean },\r\n ]\r\n}\r\n\r\n/**\r\n * HOC which wraps component in React.Suspense\r\n *\r\n * Usage: [wiki](https://github.com/finvizhq/Finviz-Website/wiki/Loading-modules-asynchronously#withsuspense)\r\n */\r\nexport function withSuspense

>(\r\n Component: React.ComponentType

,\r\n fallback: React.ReactNode = null\r\n) {\r\n return function WrappedComponent(props: P) {\r\n return (\r\n \r\n \r\n \r\n )\r\n }\r\n}\r\n","const NUM_OF_RETRIES = 3\r\n\r\nexport function importWithRetry(importFn: () => Promise, retries = 0) {\r\n const result = importFn().catch(async (err) => {\r\n if (retries > NUM_OF_RETRIES) {\r\n throw err\r\n }\r\n\r\n await new Promise((r) => setTimeout(r, 1000 * retries))\r\n\r\n return importWithRetry(importFn, retries + 1)\r\n }) as Promise\r\n\r\n return result\r\n}\r\n","import { DrawingBorder, PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport { getRoundedObject, getXYOffsetFromLine } from '../controllers/renderUtils'\r\nimport math from '../helpers/math'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Thumb from './thumb'\r\n\r\nexport interface IArrowAttrs {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n border: DrawingBorder\r\n}\r\n\r\nclass Arrow extends Element {\r\n static type = CanvasElementType.arrow\r\n\r\n declare scaled: Pick\r\n name = 'Arrow'\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.renderContent = this.renderContent.bind(this)\r\n this.resize = this.resize.bind(this)\r\n this._thumbs = [\r\n new Thumb(\r\n 'l',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'r',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getDefaults() {\r\n return {\r\n border: {\r\n width: 3,\r\n color: this.getChartLayoutSettings().ElementSettings.Colors.line,\r\n },\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { x1, x2, y1, y2 } = this.scaled\r\n const roundedXY = getRoundedObject({ x1, x2, y1, y2 })\r\n const translateXY = getXYOffsetFromLine({ lineWidth: this.attrs.border.width, ...roundedXY })\r\n\r\n context.translate(translateXY.x, translateXY.y)\r\n context.beginPath()\r\n context.set('lineCap', 'round')\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n\r\n const angle = Math.PI / 8\r\n const d = 20\r\n\r\n context.beginPath()\r\n context.moveTo(roundedXY.x1, roundedXY.y1)\r\n context.lineTo(roundedXY.x2, roundedXY.y2)\r\n context.stroke()\r\n\r\n const lineAngle = Math.atan2(roundedXY.y2 - roundedXY.y1, roundedXY.x2 - roundedXY.x1)\r\n const h = Math.abs(d / Math.cos(angle))\r\n\r\n const angle1 = lineAngle + angle\r\n const topx = roundedXY.x1 + Math.cos(angle1) * h\r\n const topy = roundedXY.y1 + Math.sin(angle1) * h\r\n const angle2 = lineAngle - angle\r\n const botx = roundedXY.x1 + Math.cos(angle2) * h\r\n const boty = roundedXY.y1 + Math.sin(angle2) * h\r\n\r\n context.beginPath()\r\n context.moveTo(topx, topy)\r\n context.lineTo(roundedXY.x1, roundedXY.y1)\r\n context.lineTo(botx, boty)\r\n context.stroke()\r\n context.translate(translateXY.x * -1, translateXY.y * -1)\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.x2 += x\r\n this.attrs.y1 += y\r\n this.attrs.y2 += y\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n if (type === 'l') {\r\n this.attrs.x1 += difX\r\n this.attrs.y1 += difY\r\n } else {\r\n this.attrs.x2 += difX\r\n this.attrs.y2 += difY\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n if (math.distanceToSegment(area.scaled, this.scaled) <= 10) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n}\r\n\r\nArrow.prototype.modalConfig = {\r\n inputs: [{ type: 'line', name: 'border' }],\r\n}\r\n\r\nexport default Arrow\r\n","import { DrawingBorder, PaneArea, RequireByKey, ResizeByThumbFuncProps } from '../../../types/shared'\r\nimport { CanvasElementType } from '../../constants/common'\r\nimport math from '../../helpers/math'\r\nimport PaneModel from '../../models/pane'\r\nimport { getContextWithCache } from '../../utils/canvas'\r\nimport Element, { EdgeValues } from '../element'\r\nimport Thumb from '../thumb'\r\n\r\nexport type BrushPoints = Array<[x: number, y: number]>\r\n\r\nexport interface IBrushAttrs {\r\n points: BrushPoints\r\n fill: string\r\n border: DrawingBorder\r\n isPolyLineClosed: boolean\r\n positionPointsTimestamps: BrushPoints\r\n}\r\n\r\nclass Brush extends Element {\r\n static type = CanvasElementType.brushV1\r\n\r\n untranslatedContext: CanvasRenderingContext2D | null = null\r\n\r\n name = 'Brush'\r\n\r\n brushPath: Path2D | null = null\r\n\r\n cachedFill = {\r\n previousFill: '',\r\n shouldRenderFill: false,\r\n }\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.untranslatedContext = getContextWithCache(document.createElement('canvas'))\r\n this.setFillCache()\r\n }\r\n\r\n getDefaults() {\r\n const { ElementSettings } = this.getChartLayoutSettings()\r\n return {\r\n fill: ElementSettings.defaultTransparentFill,\r\n border: {\r\n width: 3,\r\n color: ElementSettings.Colors.border,\r\n },\r\n isPolyLineClosed: false,\r\n } as Partial\r\n }\r\n\r\n setFillCache() {\r\n this.cachedFill.previousFill = this.attrs.fill\r\n if (this.attrs.fill.length === 9) {\r\n this.cachedFill.shouldRenderFill = this.attrs.fill.slice(7) !== '00'\r\n } else {\r\n this.cachedFill.shouldRenderFill = true\r\n }\r\n }\r\n\r\n getShouldRenderFill() {\r\n if (this.attrs.fill !== this.cachedFill.previousFill) {\r\n this.setFillCache()\r\n }\r\n return this.cachedFill.shouldRenderFill\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n if (this.attrs.border != null) {\r\n context.set('strokeStyle', this.attrs.border.color)\r\n }\r\n context.set('lineCap', 'round')\r\n context.set('lineJoin', 'round')\r\n\r\n const brushPath = new Path2D()\r\n const { points } = this.attrs\r\n context.beginPath()\r\n brushPath.moveTo(this.fx(points[0][0]), this.fy(points[0][1]))\r\n let i\r\n if (points.length > 3) {\r\n for (i = 0; i < points.length - 2; i++) {\r\n const xc = (this.fx(points[i][0]) + this.fx(points[i + 1][0])) / 2\r\n const yc = (this.fy(points[i][1]) + this.fy(points[i + 1][1])) / 2\r\n brushPath.quadraticCurveTo(this.fx(points[i][0]), this.fy(points[i][1]), xc, yc)\r\n }\r\n brushPath.quadraticCurveTo(\r\n this.fx(points[i][0]),\r\n this.fy(points[i][1]),\r\n this.fx(points[i + 1][0]),\r\n this.fy(points[i + 1][1])\r\n )\r\n } else {\r\n for (const point of points) {\r\n brushPath.lineTo(this.fx(point[0]), this.fy(point[1]))\r\n }\r\n }\r\n\r\n if (this.attrs.isPolyLineClosed) {\r\n brushPath.closePath()\r\n }\r\n this.brushPath = brushPath\r\n if (this.attrs.fill && this.getShouldRenderFill()) {\r\n context.set('fillStyle', this.attrs.fill)\r\n context.fill(brushPath)\r\n }\r\n if (this.attrs?.border?.width) {\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.stroke(brushPath)\r\n }\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n getThumbs() {\r\n const [firstX, firstY] = this.attrs.points[0]\r\n const [lastX, lastY] = this.attrs.points[this.attrs.points.length - 1]\r\n\r\n return [\r\n new Thumb(\r\n 'first',\r\n () => firstX,\r\n () => firstY,\r\n this.moveByThumb,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'last',\r\n () => lastX,\r\n () => lastY,\r\n this.moveByThumb,\r\n this.model\r\n ),\r\n ]\r\n }\r\n\r\n moveByThumb = ({ difX, difY }: RequireByKey) => {\r\n this.moveBy(difX, difY)\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n if (this.getIsCreator()) return\r\n for (const point of this.attrs.points) {\r\n point[0] += x\r\n point[1] += y\r\n }\r\n }\r\n\r\n onMouseUp() {\r\n const [currentDomainMax, currentDomainMin] = this.model.scale.y.domain()\r\n for (const point of this.attrs.points) {\r\n point[0] = this.roundToFixed(point[0], 2)\r\n point[1] = this.roundY(point[1], currentDomainMax - currentDomainMin)\r\n }\r\n super.onMouseUp()\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const { points } = this.attrs\r\n if (\r\n (this.getShouldRenderFill() || this.attrs.isPolyLineClosed) &&\r\n this.brushPath &&\r\n this.untranslatedContext?.isPointInPath(this.brushPath, area.scaled.x, area.scaled.y)\r\n ) {\r\n return true\r\n } else if (points.length > 1) {\r\n for (let i = 0; i < points.length - 1; i++) {\r\n if (\r\n math.distanceToSegment(area.scaled, {\r\n x1: this.fx(points[i][0]),\r\n y1: this.fy(points[i][1]),\r\n x2: this.fx(points[i + 1][0]),\r\n y2: this.fy(points[i + 1][1]),\r\n }) <= 10\r\n ) {\r\n return true\r\n }\r\n }\r\n }\r\n return super.isInArea(area)\r\n }\r\n\r\n cachePointPositionTimestamp = () => {\r\n const quote = this.model?.chart()?.quote()\r\n if (quote) {\r\n const positionPointsTimestamps = this.attrs.points.map(([x, y]) => [quote.getTimestampFomPositionX(x), y])\r\n this.set({ positionPointsTimestamps } as Partial)\r\n }\r\n }\r\n\r\n updateScales() {\r\n const quote = this.model.chart().quote()\r\n const { positionPointsTimestamps } = this.attrs\r\n if (!quote || !positionPointsTimestamps) {\r\n // positionPointsTimestamps check is temporary to prevent app from crashing\r\n // caused by corrupted drawings - https://github.com/finvizhq/charts/pull/1386/files\r\n return\r\n }\r\n const points = positionPointsTimestamps.map(([x, y]) => [quote.getPositionXFromTimestamp(x), y])\r\n this.set({ points } as Partial)\r\n }\r\n\r\n roundToFixed = (value: number, places: number) => Number.parseFloat(math.round({ value, overridePlaces: places }))\r\n\r\n roundY = (y: number, domainDiff: number) => {\r\n if (domainDiff < 1) {\r\n const numberOfLeadingZeros = Math.abs(Math.floor(Math.log10(Math.abs(domainDiff)) + 1))\r\n if (numberOfLeadingZeros > 0) {\r\n return this.roundToFixed(y, numberOfLeadingZeros + 4)\r\n } else {\r\n return this.roundToFixed(y, numberOfLeadingZeros + 3)\r\n }\r\n } else if (domainDiff < 10) {\r\n return this.roundToFixed(y, 3)\r\n }\r\n return this.roundToFixed(y, 2)\r\n }\r\n\r\n getAutosaveOmittedProperties() {\r\n return ['points']\r\n }\r\n\r\n getEdgeXYValues() {\r\n if (this.edgeXYValues === null) {\r\n const edgeXYValues = {} as EdgeValues\r\n this.attrs.points.forEach(([x, y]) => {\r\n edgeXYValues.minX = Math.min(x, edgeXYValues.minX ?? x)\r\n edgeXYValues.minY = Math.min(y, edgeXYValues.minY ?? y)\r\n edgeXYValues.maxX = Math.max(x, edgeXYValues.maxX ?? x)\r\n edgeXYValues.maxY = Math.max(y, edgeXYValues.maxY ?? y)\r\n })\r\n\r\n this.edgeXYValues = edgeXYValues\r\n }\r\n\r\n return this.edgeXYValues\r\n }\r\n}\r\n\r\nBrush.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'background', name: 'fill' },\r\n { type: 'border', name: 'border', min: 1, max: 20, default: {} },\r\n { type: 'checkbox', name: 'isPolyLineClosed', label: 'Close line' },\r\n ],\r\n}\r\n\r\nexport default Brush\r\n","import math from '../../helpers/math'\r\n\r\ninterface ICoordinates {\r\n x: number\r\n y: number\r\n}\r\nexport interface IRectangleSidesCoordinates {\r\n topLeft: ICoordinates\r\n topRight: ICoordinates\r\n rightTop: ICoordinates\r\n rightBottom: ICoordinates\r\n bottomRight: ICoordinates\r\n bottomLeft: ICoordinates\r\n leftBottom: ICoordinates\r\n leftTop: ICoordinates\r\n}\r\n\r\nexport interface ITailCoordinates {\r\n tailRoot: ICoordinates\r\n tailTip: ICoordinates\r\n}\r\n\r\nexport enum TailDirection {\r\n noTail,\r\n topLeftCorner,\r\n topRightCorner,\r\n bottomLeftCorner,\r\n bottomRightCorner,\r\n topSide,\r\n rightSide,\r\n bottomSide,\r\n leftSide,\r\n}\r\n\r\nexport const getRectangleSidesCoordinates = ({\r\n padding,\r\n radius,\r\n x2,\r\n y2,\r\n textWidth,\r\n measuredHeight,\r\n}: {\r\n padding: number\r\n radius: number\r\n x2: number\r\n y2: number\r\n textWidth: number\r\n measuredHeight: number\r\n}): IRectangleSidesCoordinates => ({\r\n topLeft: {\r\n x: x2 - padding + radius,\r\n y: y2 - padding,\r\n },\r\n topRight: {\r\n x: x2 + textWidth + padding - radius,\r\n y: y2 - padding,\r\n },\r\n rightTop: {\r\n x: x2 + textWidth + padding,\r\n y: y2 - padding + radius,\r\n },\r\n rightBottom: {\r\n x: x2 + textWidth + padding,\r\n y: y2 + padding + measuredHeight - radius,\r\n },\r\n bottomRight: {\r\n x: x2 + textWidth + padding - radius,\r\n y: y2 + padding + measuredHeight,\r\n },\r\n bottomLeft: {\r\n x: x2 - padding + radius,\r\n y: y2 + padding + measuredHeight,\r\n },\r\n leftBottom: {\r\n x: x2 - padding,\r\n y: y2 + padding + measuredHeight - radius,\r\n },\r\n leftTop: {\r\n x: x2 - padding,\r\n y: y2 - padding + radius,\r\n },\r\n})\r\n\r\nexport const getTailCoordinates = ({\r\n rectangleSides,\r\n x1,\r\n y1,\r\n}: {\r\n rectangleSides: IRectangleSidesCoordinates\r\n x1: number\r\n y1: number\r\n}): ITailCoordinates => ({\r\n tailRoot: {\r\n x: rectangleSides.topLeft.x + (rectangleSides.topRight.x - rectangleSides.topLeft.x) / 2,\r\n y: rectangleSides.leftTop.y + (rectangleSides.leftBottom.y - rectangleSides.leftTop.y) / 2,\r\n },\r\n tailTip: {\r\n x: x1,\r\n y: y1,\r\n },\r\n})\r\n\r\nconst getTailHalfWidth = (halfWidth: number, p1: ICoordinates, p2: ICoordinates): number => {\r\n const dist = math.distance(p1, p2)\r\n if (dist < halfWidth * 2) {\r\n return dist / 2\r\n } else {\r\n return halfWidth\r\n }\r\n}\r\n\r\nexport const getTailToSideIntersection = ({\r\n tail,\r\n rectangleSides,\r\n}: {\r\n tail: ITailCoordinates\r\n rectangleSides: IRectangleSidesCoordinates\r\n}): TailDirection => {\r\n const { topLeft, topRight, rightTop, rightBottom, bottomRight, bottomLeft, leftBottom, leftTop } = rectangleSides\r\n const { tailTip, tailRoot } = tail\r\n if (math.twoSegmentLinesIntersection(tailTip, tailRoot, topLeft, leftTop)) {\r\n return TailDirection.topLeftCorner\r\n } else if (math.twoSegmentLinesIntersection(tailTip, tailRoot, topRight, rightTop)) {\r\n return TailDirection.topRightCorner\r\n } else if (math.twoSegmentLinesIntersection(tailTip, tailRoot, bottomLeft, leftBottom)) {\r\n return TailDirection.bottomLeftCorner\r\n } else if (math.twoSegmentLinesIntersection(tailTip, tailRoot, bottomRight, rightBottom)) {\r\n return TailDirection.bottomRightCorner\r\n } else if (math.twoSegmentLinesIntersection(tailTip, tailRoot, topLeft, topRight)) {\r\n return TailDirection.topSide\r\n } else if (math.twoSegmentLinesIntersection(tailTip, tailRoot, rightTop, rightBottom)) {\r\n return TailDirection.rightSide\r\n } else if (math.twoSegmentLinesIntersection(tailTip, tailRoot, bottomLeft, bottomRight)) {\r\n return TailDirection.bottomSide\r\n } else if (math.twoSegmentLinesIntersection(tailTip, tailRoot, leftTop, leftBottom)) {\r\n return TailDirection.leftSide\r\n } else {\r\n return TailDirection.noTail\r\n }\r\n}\r\n\r\ninterface IRenderCallout {\r\n context: any\r\n radius: number\r\n requiredTailHalfWidth: number\r\n tail: ITailCoordinates\r\n rectangleSides: IRectangleSidesCoordinates\r\n tailDirection: TailDirection\r\n}\r\n\r\nexport const renderCallout = ({\r\n context,\r\n radius,\r\n requiredTailHalfWidth,\r\n tail,\r\n rectangleSides,\r\n tailDirection,\r\n}: IRenderCallout): void => {\r\n const { topLeft, topRight, rightTop, rightBottom, bottomRight, bottomLeft, leftBottom, leftTop } = rectangleSides\r\n const { tailTip, tailRoot } = tail\r\n\r\n // draw rounded rectangle from top left corner clockwise\r\n // !!! ORDER OF RENDER MATTERS !!!\r\n\r\n // renderTopLeftCorner\r\n if (tailDirection === TailDirection.topLeftCorner) {\r\n context.moveTo(leftTop.x, leftTop.y)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(topLeft.x, topLeft.y)\r\n } else {\r\n context.moveTo(leftTop.x, leftTop.y)\r\n context.arcTo(leftTop.x, topLeft.y, topLeft.x, topLeft.y, radius)\r\n }\r\n\r\n // renderTopLine\r\n if (tailDirection === TailDirection.topSide) {\r\n const tailLineToTopLineIntersection = math.twoSegmentLinesIntersection(tailTip, tailRoot, topLeft, topRight)\r\n if (!tailLineToTopLineIntersection) {\r\n context.lineTo(topRight.x, topRight.y)\r\n return\r\n }\r\n const tailHalfWidth = getTailHalfWidth(requiredTailHalfWidth, topLeft, topRight)\r\n if (tailLineToTopLineIntersection.x - tailHalfWidth < topLeft.x) {\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(topLeft.x + tailHalfWidth * 2, tailLineToTopLineIntersection.y)\r\n } else if (tailLineToTopLineIntersection.x + tailHalfWidth > topRight.x) {\r\n context.lineTo(topRight.x - tailHalfWidth * 2, tailLineToTopLineIntersection.y)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(topRight.x, tailLineToTopLineIntersection.y)\r\n } else {\r\n context.lineTo(tailLineToTopLineIntersection.x - tailHalfWidth, tailLineToTopLineIntersection.y)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(tailLineToTopLineIntersection.x + tailHalfWidth, tailLineToTopLineIntersection.y)\r\n context.lineTo(topRight.x, topRight.y)\r\n }\r\n } else {\r\n context.lineTo(topRight.x, topRight.y)\r\n }\r\n\r\n // renderTopRightCorner\r\n if (tailDirection === TailDirection.topRightCorner) {\r\n context.lineTo(topRight.x, topRight.y)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(rightTop.x, rightTop.y)\r\n } else {\r\n context.arcTo(rightTop.x, topRight.y, rightTop.x, rightTop.y, radius)\r\n }\r\n\r\n // renderRightLine\r\n if (tailDirection === TailDirection.rightSide) {\r\n const tailLineToRightLineIntersection = math.twoSegmentLinesIntersection(tailTip, tailRoot, rightTop, rightBottom)\r\n if (!tailLineToRightLineIntersection) {\r\n context.lineTo(rightBottom.x, rightBottom.y)\r\n return\r\n }\r\n const tailHalfWidth = getTailHalfWidth(requiredTailHalfWidth, rightTop, rightBottom)\r\n if (tailLineToRightLineIntersection.y - tailHalfWidth < rightTop.y) {\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(rightTop.x, rightTop.y + tailHalfWidth * 2)\r\n } else if (tailLineToRightLineIntersection.y + tailHalfWidth > rightBottom.y) {\r\n context.lineTo(rightBottom.x, rightBottom.y - tailHalfWidth * 2)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(rightBottom.x, rightBottom.y)\r\n } else {\r\n context.lineTo(tailLineToRightLineIntersection.x, tailLineToRightLineIntersection.y - tailHalfWidth)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(tailLineToRightLineIntersection.x, tailLineToRightLineIntersection.y + tailHalfWidth)\r\n context.lineTo(rightBottom.x, rightBottom.y)\r\n }\r\n } else {\r\n context.lineTo(rightBottom.x, rightBottom.y)\r\n }\r\n\r\n // renderBottomRightCorner\r\n if (tailDirection === TailDirection.bottomRightCorner) {\r\n context.lineTo(rightBottom.x, rightBottom.y)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(bottomRight.x, bottomRight.y)\r\n } else {\r\n context.arcTo(rightBottom.x, bottomRight.y, bottomRight.x, bottomRight.y, radius)\r\n }\r\n\r\n // renderBottomLine\r\n if (tailDirection === TailDirection.bottomSide) {\r\n const tailLineToBottomLineIntersection = math.twoSegmentLinesIntersection(\r\n tailTip,\r\n tailRoot,\r\n bottomLeft,\r\n bottomRight\r\n )\r\n if (!tailLineToBottomLineIntersection) {\r\n context.lineTo(bottomLeft.x, bottomLeft.y)\r\n return\r\n }\r\n const tailHalfWidth = getTailHalfWidth(requiredTailHalfWidth, bottomLeft, bottomRight)\r\n if (tailLineToBottomLineIntersection.x + tailHalfWidth > bottomRight.x) {\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(bottomRight.x - tailHalfWidth * 2, tailLineToBottomLineIntersection.y)\r\n } else if (tailLineToBottomLineIntersection.x - tailHalfWidth < bottomLeft.x) {\r\n context.lineTo(bottomLeft.x + tailHalfWidth * 2, tailLineToBottomLineIntersection.y)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(bottomLeft.x, tailLineToBottomLineIntersection.y)\r\n } else {\r\n context.lineTo(tailLineToBottomLineIntersection.x + tailHalfWidth, tailLineToBottomLineIntersection.y)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(tailLineToBottomLineIntersection.x - tailHalfWidth, tailLineToBottomLineIntersection.y)\r\n context.lineTo(bottomLeft.x, bottomLeft.y)\r\n }\r\n } else {\r\n context.lineTo(bottomLeft.x, bottomLeft.y)\r\n }\r\n\r\n // renderBottomLeftCorner\r\n if (tailDirection === TailDirection.bottomLeftCorner) {\r\n context.lineTo(bottomLeft.x, bottomLeft.y)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(leftBottom.x, leftBottom.y)\r\n } else {\r\n context.arcTo(leftBottom.x, bottomLeft.y, leftBottom.x, leftBottom.y, radius)\r\n }\r\n\r\n // renderLeftLine\r\n if (tailDirection === TailDirection.leftSide) {\r\n const tailLineToLeftLineIntersection = math.twoSegmentLinesIntersection(tailTip, tailRoot, leftTop, leftBottom)\r\n if (!tailLineToLeftLineIntersection) {\r\n context.lineTo(leftTop.x, leftTop.y)\r\n return\r\n }\r\n const tailHalfWidth = getTailHalfWidth(requiredTailHalfWidth, leftTop, leftBottom)\r\n if (tailLineToLeftLineIntersection.y + tailHalfWidth > leftBottom.y) {\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(leftBottom.x, leftBottom.y - tailHalfWidth * 2)\r\n } else if (tailLineToLeftLineIntersection.y - tailHalfWidth < leftTop.y) {\r\n context.lineTo(leftTop.x, leftTop.y + tailHalfWidth * 2)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(leftTop.x, leftTop.y)\r\n } else {\r\n context.lineTo(tailLineToLeftLineIntersection.x, tailLineToLeftLineIntersection.y + tailHalfWidth)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(tailLineToLeftLineIntersection.x, tailLineToLeftLineIntersection.y - tailHalfWidth)\r\n context.lineTo(leftTop.x, leftTop.y)\r\n }\r\n } else {\r\n context.lineTo(leftTop.x, leftTop.y)\r\n }\r\n}\r\n","import merge from 'lodash.merge'\r\n\r\nimport { PaneArea, RequireByKey, ResizeByThumbWithTypeAndDifs, TextAttrs } from '../../../types/shared'\r\nimport { PADDING } from '../../constants/common'\r\nimport { CanvasElementType } from '../../constants/common'\r\nimport math from '../../helpers/math'\r\nimport Chart from '../../models/chart'\r\nimport PaneModel from '../../models/pane'\r\nimport Text from '../text'\r\nimport Thumb from '../thumb'\r\nimport {\r\n getRectangleSidesCoordinates,\r\n getTailCoordinates,\r\n getTailToSideIntersection,\r\n renderCallout,\r\n} from './callout_utils'\r\n\r\nexport interface ICalloutAttrs {\r\n x1: number\r\n y1: number\r\n x2: number\r\n y2: number\r\n}\r\n\r\ninterface FontFamilyHeightCoefficient {\r\n Arial: {\r\n firstLine: number\r\n otherLines: number\r\n }\r\n Verdana: {\r\n firstLine: number\r\n otherLines: number\r\n }\r\n}\r\n\r\ntype CalloutTextAttrs = ICalloutAttrs & RequireByKey\r\n\r\nclass Callout extends Text {\r\n static type = CanvasElementType.calloutV1\r\n\r\n name = 'Callout'\r\n\r\n declare fontFamilyHeightCoeficient: FontFamilyHeightCoefficient\r\n declare isActualBoundingBoxAvailable: boolean\r\n declare lastAttrs: Attrs\r\n declare scaled: Pick\r\n declare measuredHeight: number\r\n declare font: string\r\n declare context?: CanvasRenderingContext2D\r\n declare lines: {\r\n text: string\r\n metrics: TextMetrics\r\n }[]\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n this._thumbs = [\r\n new Thumb(\r\n 'tail',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n getModalConfigBase() {\r\n return {\r\n inputs: [\r\n { type: 'multiline_string', name: 'text', required: true },\r\n { type: 'font', name: 'font' },\r\n {\r\n type: 'background',\r\n name: 'fillStyle',\r\n label: 'Color',\r\n default: this.getChartLayoutSettings().ElementSettings.Colors.textWithoutBackground,\r\n },\r\n {\r\n type: 'background',\r\n name: 'background',\r\n label: 'Background',\r\n default: 'rgba(0,0,0,0)',\r\n },\r\n {\r\n type: 'border',\r\n name: 'border',\r\n min: 0,\r\n },\r\n ],\r\n }\r\n }\r\n\r\n getDefaults() {\r\n const { ElementSettings } = this.getChartLayoutSettings()\r\n return {\r\n text: '',\r\n font: {\r\n size: 15,\r\n family: 'Arial',\r\n style: 'normal',\r\n weight: 'normal',\r\n },\r\n fillStyle: ElementSettings.Colors.textWithoutBackground,\r\n lineHeight: 15,\r\n // left | right | center | start | end\r\n textAlign: 'left',\r\n // top | middle | alphabetic | bottom\r\n textBaseline: 'alphabetic',\r\n padding: {\r\n top: 0,\r\n right: 0,\r\n bottom: 0,\r\n left: 0,\r\n },\r\n background: ElementSettings.defaultFill,\r\n border: { color: ElementSettings.Colors.line, width: 1 },\r\n } as Partial\r\n }\r\n\r\n setupContext(context: CanvasRenderingContext2D) {\r\n this.context = context\r\n context.set('font', this.font)\r\n context.set('fillStyle', this.attrs.fillStyle)\r\n context.set('textAlign', this.attrs.textAlign)\r\n context.set('textBaseline', this.attrs.textBaseline)\r\n this.setupTextMetricsCache()\r\n }\r\n\r\n setupTextMetricsCache() {\r\n const ctx = this.context\r\n\r\n if (\r\n (this.attrs.text !== this.lastAttrs?.text ||\r\n JSON.stringify(this.attrs.font) !== JSON.stringify(this.lastAttrs?.font)) &&\r\n ctx\r\n ) {\r\n this.lastAttrs = merge({}, this.attrs)\r\n this.lines = this.getLines().map((line) => ({\r\n text: line,\r\n metrics: ctx.measureText(line),\r\n }))\r\n this.measuredHeight = this.lines.reduce((acc, current, currentIndex) => {\r\n const lineHeight =\r\n current.metrics.actualBoundingBoxAscent +\r\n current.metrics.actualBoundingBoxDescent +\r\n (currentIndex !== this.lines.length - 1 ? PADDING.S : 0)\r\n return acc + lineHeight\r\n }, 0)\r\n }\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n this.render(context)\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n renderText() {\r\n if (!this.context) return\r\n let y = this.scaled.y2 + this.attrs.padding.top\r\n let previousDescent = 0\r\n for (let i = 0; i < this.lines.length; i++) {\r\n y += i === 0 ? 0 : this.lines[i].metrics.actualBoundingBoxAscent + previousDescent + PADDING.S\r\n this.context.fillText(this.lines[i].text, this.scaled.x2 + this.attrs.padding.left, y)\r\n previousDescent = this.lines[i].metrics.actualBoundingBoxDescent\r\n }\r\n }\r\n\r\n getCalloutProperties() {\r\n const textWidth = this.attrs.text === '' ? this.attrs.font.size * 2 : this.width\r\n const requiredTailHalfWidth = this.attrs.font.size * 0.5\r\n const padding = this.attrs.border.width / 2 + this.attrs.font.size * 0.5\r\n const radius = textWidth < requiredTailHalfWidth ? textWidth / 2 : requiredTailHalfWidth\r\n\r\n const measuredHeight = this.measuredHeight < requiredTailHalfWidth ? radius * 2 : this.measuredHeight\r\n const y2 = this.scaled.y2 - (this.lines?.[0]?.metrics.actualBoundingBoxAscent || measuredHeight)\r\n\r\n // Points diagram\r\n //.......X-----------------X.......\r\n //.................................\r\n //...X.........................X...\r\n //...|.........................|...\r\n //...|.........................|...\r\n //...X.........................X...\r\n //.................................\r\n //.......X-----------------X.......\r\n\r\n const rectangleSides = getRectangleSidesCoordinates({\r\n padding,\r\n radius,\r\n x2: this.scaled.x2,\r\n y2,\r\n textWidth,\r\n measuredHeight,\r\n })\r\n const tail = getTailCoordinates({ rectangleSides, x1: this.scaled.x1, y1: this.scaled.y1 })\r\n const tailDirection = getTailToSideIntersection({ tail, rectangleSides })\r\n\r\n return {\r\n radius,\r\n requiredTailHalfWidth,\r\n rectangleSides,\r\n tail,\r\n tailDirection,\r\n }\r\n }\r\n\r\n renderBackground() {\r\n if (!this.attrs.background || !this.context) {\r\n return\r\n }\r\n\r\n const { radius, requiredTailHalfWidth, tail, tailDirection, rectangleSides } = this.getCalloutProperties()\r\n\r\n this.context.beginPath()\r\n this.context.set('fillStyle', this.attrs.background)\r\n this.context.lineJoin = 'round'\r\n renderCallout({\r\n context: this.context,\r\n radius,\r\n requiredTailHalfWidth,\r\n tail,\r\n rectangleSides,\r\n tailDirection,\r\n })\r\n this.context.closePath()\r\n this.context.fill()\r\n this.context.set('fillStyle', this.attrs.fillStyle)\r\n this.renderBorder()\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n // is in rectangle\r\n const { tail, rectangleSides, requiredTailHalfWidth } = this.getCalloutProperties()\r\n if (\r\n this.lines &&\r\n rectangleSides &&\r\n rectangleSides.leftTop.x < area.scaled.x &&\r\n rectangleSides.topLeft.y < area.scaled.y &&\r\n rectangleSides.rightBottom.x > area.scaled.x &&\r\n rectangleSides.bottomRight.y > area.scaled.y\r\n ) {\r\n return true\r\n }\r\n // is in tail\r\n if (tail) {\r\n const tailP1 = math.perpendicularPointToLine({\r\n distance: requiredTailHalfWidth,\r\n line: { x1: tail.tailTip.x, y1: tail.tailTip.y, x2: tail.tailRoot.x, y2: tail.tailRoot.y },\r\n })\r\n const pointOffsetX = tailP1.x - tail.tailRoot.x\r\n const pointOffsetY = tailP1.y - tail.tailRoot.y\r\n const tailP2 = { x: tail.tailRoot.x + -1 * pointOffsetX, y: tail.tailRoot.y + -1 * pointOffsetY }\r\n const polygon = [tail.tailTip, tailP1, tailP2]\r\n if (math.pointInPolygon(area.scaled, polygon)) {\r\n return true\r\n }\r\n }\r\n return super.isInArea(area)\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x2 += x\r\n this.attrs.y2 += y\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n if (type === 'tail') {\r\n this.attrs.x1 += difX\r\n this.attrs.y1 += difY\r\n }\r\n }\r\n\r\n getIsInChartView(chart: Chart) {\r\n if (this.getIsCreator() || !this.lines) {\r\n return true\r\n }\r\n\r\n const { tail, rectangleSides } = this.getCalloutProperties()\r\n\r\n return [...Object.values(rectangleSides), tail.tailRoot, tail.tailTip].some(\r\n ({ x, y }) => x <= -chart.leftOffset + chart.width && x >= -chart.leftOffset && y >= 0 && y <= this.model.height\r\n )\r\n }\r\n}\r\n\r\nexport default Callout\r\n","import { Bezier } from 'bezier-js'\r\n\r\nimport { DrawingBorder, PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport Chart from '../models/chart'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Thumb from './thumb'\r\n\r\nexport interface ICurveAttrs {\r\n x1: number\r\n x2: number\r\n x3: number\r\n cp1x: number\r\n cp2x: number\r\n y1: number\r\n y2: number\r\n y3: number\r\n cp1y: number\r\n cp2y: number\r\n border: DrawingBorder\r\n}\r\n\r\nclass Curve extends Element {\r\n static type = CanvasElementType.curve\r\n\r\n name = 'Curve'\r\n declare scaled: Pick\r\n declare curve: Bezier\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.render = this.render.bind(this)\r\n this.resize = this.resize.bind(this)\r\n this._thumbs = [\r\n new Thumb(\r\n 'a',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'b',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'c',\r\n () => this.attrs.x3 || this.attrs.x2,\r\n () => this.attrs.y3 || this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getDefaults() {\r\n return {\r\n border: {\r\n width: 1,\r\n color: this.getChartLayoutSettings().ElementSettings.Colors.line,\r\n },\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2', 'x3'], y: ['y1', 'y2', 'y3'] })\r\n\r\n drawQuadraticCurve(context: CanvasRenderingContext2D, curve: Bezier) {\r\n const { points } = curve\r\n context.beginPath()\r\n context.moveTo(points[0].x, points[0].y)\r\n context.quadraticCurveTo(points[1].x, points[1].y, points[2].x, points[2].y)\r\n context.stroke()\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { x1, x2, x3, y1, y2, y3 } = this.scaled\r\n context.translate(0.5, 0.5)\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n if (!x3 || !y3) {\r\n context.beginPath()\r\n context.moveTo(x1, y1)\r\n context.lineTo(x2, y2)\r\n context.lineTo(x3, y3)\r\n context.stroke()\r\n } else {\r\n this.curve = Bezier.quadraticFromPoints({ x: x1, y: y1 }, { x: x2, y: y2 }, { x: x3, y: y3 }, 0.5)\r\n this.drawQuadraticCurve(context, this.curve)\r\n }\r\n\r\n context.translate(-0.5, -0.5)\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.x2 += x\r\n this.attrs.x3 += x\r\n this.attrs.cp1x += x\r\n this.attrs.cp2x += x\r\n\r\n this.attrs.y1 += y\r\n this.attrs.y2 += y\r\n this.attrs.y3 += y\r\n this.attrs.cp1y += y\r\n this.attrs.cp2y += y\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n switch (type) {\r\n case 'a':\r\n this.attrs.x1 += difX\r\n this.attrs.y1 += difY\r\n break\r\n case 'b':\r\n this.attrs.x2 += difX\r\n this.attrs.y2 += difY\r\n break\r\n case 'c':\r\n this.attrs.x3 += difX\r\n this.attrs.y3 += difY\r\n break\r\n default:\r\n break\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n if (this.curve && this.curve.project(area.scaled).d! <= 10) {\r\n return true\r\n }\r\n return this.thumbsAreInArea(area)\r\n }\r\n\r\n getIsInChartView(chart: Chart) {\r\n if (this.getIsCreator()) {\r\n return true\r\n }\r\n\r\n const { x1, x2, x3, y1, y2, y3 } = this.scaled\r\n if (!x3 || !y3) {\r\n return true\r\n }\r\n const isInView =\r\n Bezier.quadraticFromPoints({ x: x1, y: y1 }, { x: x2, y: y2 }, { x: x3, y: y3 }, 0.5).points.some(\r\n ({ x, y }) => x <= -chart.leftOffset + chart.width && x >= -chart.leftOffset && y >= 0 && y <= this.model.height\r\n ) ?? true\r\n\r\n return isInView\r\n }\r\n}\r\n\r\nCurve.prototype.modalConfig = {\r\n inputs: [{ type: 'line', name: 'border' }],\r\n}\r\n\r\nexport default Curve\r\n","import { DrawingBorder, PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Thumb from './thumb'\r\n\r\nexport interface IEllipseAttrs {\r\n x1: number\r\n x2: number\r\n x3: number\r\n cp1x: number\r\n cp2x: number\r\n y1: number\r\n y2: number\r\n y3: number\r\n cp1y: number\r\n cp2y: number\r\n width: number\r\n fill: string\r\n border: DrawingBorder\r\n}\r\n\r\ninterface ICoordinates {\r\n topCenterX: number\r\n topCenterY: number\r\n topRightX: number\r\n topRightY: number\r\n topLeftX: number\r\n topLeftY: number\r\n centerLeftX: number\r\n centerLeftY: number\r\n centerRightX: number\r\n centerRightY: number\r\n bottomCenterX: number\r\n bottomCenterY: number\r\n bottomLeftX: number\r\n bottomLeftY: number\r\n bottomRightX: number\r\n bottomRightY: number\r\n}\r\n\r\n// OLD Ellipse \"v0\" kept for backward-compatibiluty for old saved ideas\r\n// current Ellipse tool located in ellipse folder\r\nclass Ellipse extends Element {\r\n static type = CanvasElementType.ellipse\r\n\r\n name = 'Ellipse'\r\n\r\n declare scaled: Pick\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n this._thumbs = [\r\n new Thumb(\r\n 'x1',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'x2',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'lw',\r\n () => this.model.scale.x.invert(this.getCoordinates().centerLeftX),\r\n () => this.model.scale.y.invert(this.getCoordinates().centerLeftY),\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'rw',\r\n () => this.model.scale.x.invert(this.getCoordinates().centerRightX),\r\n () => this.model.scale.y.invert(this.getCoordinates().centerRightY),\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n const boundingPointKeys = this.getBoundingPointKeys()\r\n this.scale({ x: [...boundingPointKeys.x, 'width'], y: boundingPointKeys.y })\r\n }\r\n\r\n getDefaults() {\r\n const { ElementSettings } = this.getChartLayoutSettings()\r\n return {\r\n fill: ElementSettings.defaultFill,\r\n border: {\r\n width: 1,\r\n color: ElementSettings.Colors.line,\r\n },\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const c = this.getCoordinates()\r\n\r\n context.set('fillStyle', this.attrs.fill)\r\n\r\n context.beginPath()\r\n context.moveTo(c.bottomCenterX, c.bottomCenterY)\r\n context.bezierCurveTo(c.bottomRightX, c.bottomRightY, c.topRightX, c.topRightY, c.topCenterX, c.topCenterY)\r\n context.bezierCurveTo(c.topLeftX, c.topLeftY, c.bottomLeftX, c.bottomLeftY, c.bottomCenterX, c.bottomCenterY)\r\n context.closePath()\r\n context.fill()\r\n\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n if ((this.attrs.border != null ? this.attrs.border.width : undefined) !== 0) {\r\n context.stroke()\r\n }\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.y1 += y\r\n this.attrs.x2 += x\r\n this.attrs.y2 += y\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n switch (type) {\r\n case 'x1':\r\n this.attrs.x1 += difX\r\n this.attrs.y1 += difY\r\n break\r\n case 'x2':\r\n this.attrs.x2 += difX\r\n this.attrs.y2 += difY\r\n break\r\n case 'lw':\r\n this.attrs.width += difX\r\n break\r\n case 'rw':\r\n this.attrs.width -= difX\r\n break\r\n default:\r\n break\r\n }\r\n }\r\n\r\n getCoordinates(): ICoordinates {\r\n // TODO cache?\r\n // http://stackoverflow.com/questions/14169234/the-relation-of-the-bezier-curve-and-ellipse\r\n const rotationAngle =\r\n Math.PI + Math.atan(-1 / ((this.scaled.y2 - this.scaled.y1) / (this.scaled.x2 - this.scaled.x1)))\r\n\r\n const sign = this.scaled.y1 > this.scaled.y2 ? 1 : -1\r\n const radiusX = this.scaled.width / 2\r\n let radiusY = (sign * Math.abs(this.scaled.y1 - this.scaled.y2)) / Math.cos(rotationAngle) / 2\r\n if (this.scaled.y1 === this.scaled.y2) {\r\n radiusY = Math.abs(this.scaled.x1 - this.scaled.x2) / 2\r\n }\r\n\r\n const width_two_thirds = (radiusX * 4) / 3\r\n\r\n const dx1 = Math.sin(rotationAngle) * radiusY\r\n const dy1 = Math.cos(rotationAngle) * radiusY\r\n const dx2 = Math.cos(rotationAngle) * width_two_thirds\r\n const dy2 = Math.sin(rotationAngle) * width_two_thirds\r\n\r\n const x = this.scaled.x1 + dx1\r\n const y = this.scaled.y1 - dy1\r\n\r\n const topCenterX = x - dx1\r\n const topCenterY = y + dy1\r\n const topRightX = topCenterX + dx2\r\n const topRightY = topCenterY + dy2\r\n const topLeftX = topCenterX - dx2\r\n const topLeftY = topCenterY - dy2\r\n\r\n const bottomCenterX = x + dx1\r\n const bottomCenterY = y - dy1\r\n const bottomRightX = bottomCenterX + dx2\r\n const bottomRightY = bottomCenterY + dy2\r\n const bottomLeftX = bottomCenterX - dx2\r\n const bottomLeftY = bottomCenterY - dy2\r\n\r\n const centerRightX = x + dx2\r\n const centerRightY = y + dy2\r\n const centerLeftX = x - dx2\r\n const centerLeftY = y - dy2\r\n\r\n return {\r\n topCenterX,\r\n topCenterY,\r\n topRightX,\r\n topRightY,\r\n topLeftX,\r\n topLeftY,\r\n centerLeftX,\r\n centerLeftY,\r\n centerRightX,\r\n centerRightY,\r\n bottomCenterX,\r\n bottomCenterY,\r\n bottomLeftX,\r\n bottomLeftY,\r\n bottomRightX,\r\n bottomRightY,\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const c = this.getCoordinates()\r\n const left = Math.min(this.scaled.x1, this.scaled.x2, c.centerRightX)\r\n const right = Math.max(this.scaled.x1, this.scaled.x2, c.centerLeftX)\r\n const top = Math.min(this.scaled.y1, this.scaled.y2, c.centerRightY)\r\n const bottom = Math.max(this.scaled.y1, this.scaled.y2, c.centerLeftY)\r\n if (left < area.scaled.x && area.scaled.x < right && top < area.scaled.y && area.scaled.y < bottom) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n\r\n getIsInChartView() {\r\n return true\r\n }\r\n}\r\n\r\nEllipse.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'background', name: 'fill' },\r\n { type: 'border', name: 'border', min: 1, default: {} },\r\n ],\r\n}\r\n\r\nexport default Ellipse\r\n","import { DrawingBorder, PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport math from '../helpers/math'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Thumb from './thumb'\r\n\r\ntype RotatedRectangleCoordiantes = [[number, number], [number, number], [number, number], [number, number]]\r\n\r\nexport interface IRotatedRectangleAttrs {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n height: number\r\n fill: string\r\n border: DrawingBorder\r\n}\r\n\r\n// OLD RotatedRectangle \"v0\" kept for backward-compatibiluty for old saved ideas\r\n// current RotatedRectangle tool located in rotated_rectangle folder\r\nclass RotatedRectangle extends Element {\r\n static type = CanvasElementType.rotatedRectangle\r\n\r\n name = 'Rotated rectangle'\r\n\r\n declare scaled: Pick\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n const x = this.model.scale.x.invert\r\n const y = this.model.scale.y.invert\r\n this._thumbs = [\r\n new Thumb(\r\n 'ml',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'mr',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'tl',\r\n () => x(this.getRectCoordinates()[0][0]),\r\n () => y(this.getRectCoordinates()[0][1]),\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'tr',\r\n () => x(this.getRectCoordinates()[1][0]),\r\n () => y(this.getRectCoordinates()[1][1]),\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'bl',\r\n () => x(this.getRectCoordinates()[2][0]),\r\n () => y(this.getRectCoordinates()[2][1]),\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'br',\r\n () => x(this.getRectCoordinates()[3][0]),\r\n () => y(this.getRectCoordinates()[3][1]),\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n const boundingPointKeys = this.getBoundingPointKeys()\r\n this.scale({ x: [...boundingPointKeys.x, 'height'], y: boundingPointKeys.y })\r\n }\r\n\r\n getDefaults() {\r\n const { ElementSettings } = this.getChartLayoutSettings()\r\n return {\r\n fill: ElementSettings.defaultFill,\r\n border: {\r\n width: 1,\r\n color: ElementSettings.Colors.border,\r\n },\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n context.set('fillStyle', this.attrs.fill)\r\n\r\n context.beginPath()\r\n const coords = this.getRectCoordinates()\r\n for (const point of coords) {\r\n context.lineTo(point[0], point[1])\r\n }\r\n context.lineTo(coords[0][0], coords[0][1])\r\n context.fill()\r\n\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n if ((this.attrs.border != null ? this.attrs.border.width : undefined) !== 0) {\r\n context.stroke()\r\n }\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n getRectCoordinates(): RotatedRectangleCoordiantes {\r\n const mx1 = this.scaled.x1\r\n const mx2 = this.scaled.x2\r\n const my1 = this.scaled.y1\r\n const my2 = this.scaled.y2\r\n const { height } = this.scaled\r\n\r\n const k = (my2 - my1) / (mx2 - mx1)\r\n const nk = -1 / k\r\n\r\n const sign = my1 > my2 ? 1 : -1\r\n const dx = (sign * Math.sqrt((height * height) / (1 + nk * nk))) / 2\r\n const dy = nk * dx\r\n\r\n let x1 = mx1 - dx\r\n let y1 = my1 - dy\r\n let x2 = mx2 - dx\r\n let y2 = my2 - dy\r\n\r\n let x3 = mx2 + dx\r\n let y3 = my2 + dy\r\n let x4 = mx1 + dx\r\n let y4 = my1 + dy\r\n\r\n if (my1 === my2) {\r\n x1 = mx1\r\n y1 = my1 - height / 2\r\n x2 = mx2\r\n y2 = my2 - height / 2\r\n\r\n x3 = mx2\r\n y3 = my2 + height / 2\r\n x4 = mx1\r\n y4 = my1 + height / 2\r\n }\r\n\r\n return [\r\n [x1, y1],\r\n [x2, y2],\r\n [x3, y3],\r\n [x4, y4],\r\n ]\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.y1 += y\r\n this.attrs.x2 += x\r\n this.attrs.y2 += y\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n switch (type) {\r\n case 'ml':\r\n this.attrs.x1 += difX\r\n this.attrs.y1 += difY\r\n break\r\n case 'mr':\r\n this.attrs.x2 += difX\r\n this.attrs.y2 += difY\r\n break\r\n case 'tl':\r\n case 'tr':\r\n this.attrs.height += difY\r\n break\r\n case 'bl':\r\n case 'br':\r\n this.attrs.height -= difY\r\n break\r\n default:\r\n return\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const coords = this.getRectCoordinates()\r\n const polygon = coords.map((c) => ({ x: c[0], y: c[1] }))\r\n if (math.pointInPolygon(area.scaled, polygon)) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n\r\n getIsInChartView() {\r\n return true\r\n }\r\n}\r\n\r\nRotatedRectangle.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'background', name: 'fill' },\r\n { type: 'border', name: 'border', min: 1, default: {} },\r\n ],\r\n}\r\n\r\nexport default RotatedRectangle\r\n","// TODO FontAwesome font or similar needs to be loaded before using Symbol\r\nimport { DrawingBorder, PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Thumb from './thumb'\r\n\r\nexport interface ISymbolAttrs {\r\n x1: number\r\n scaleX: number\r\n y1: number\r\n scaleY: number\r\n angle: number\r\n fill: string\r\n symbol: string\r\n border: DrawingBorder\r\n}\r\n\r\nclass SymbolElement extends Element {\r\n static type = CanvasElementType.symbol\r\n\r\n name = 'Symbol'\r\n\r\n declare textWidth: number\r\n declare textHeight: number\r\n declare scaled: Pick\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n\r\n this.resize = this.resize.bind(this)\r\n\r\n const sx = (sign: number) =>\r\n this.getRotatedCoordinates(this.scaled.x1 + sign * (this.textWidth / 2) * this.attrs.scaleX, this.scaled.y1)\r\n const sy = (sign: number) =>\r\n this.getRotatedCoordinates(this.scaled.x1, this.scaled.y1 + sign * (this.textHeight / 2) * this.attrs.scaleY)\r\n this._thumbs = [\r\n new Thumb(\r\n 'xr',\r\n () => this.model.scale.x.invert(sx(+1).x),\r\n () => this.model.scale.y.invert(sx(+1).y),\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'xl',\r\n () => this.model.scale.x.invert(sx(-1).x),\r\n () => this.model.scale.y.invert(sx(-1).y),\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'yt',\r\n () => this.model.scale.x.invert(sy(+1).x),\r\n () => this.model.scale.y.invert(sy(+1).y),\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'yb',\r\n () => this.model.scale.x.invert(sy(-1).x),\r\n () => this.model.scale.y.invert(sy(-1).y),\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'c',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n this.attrs.angle = this.attrs.angle || 0\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1'], y: ['y1'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n context.set('font', '36px FontAwesome')\r\n context.set('fillStyle', this.attrs.fill)\r\n context.set('textAlign', 'left')\r\n context.set('textBaseline', 'top')\r\n\r\n this.textWidth = context.measureText(this.attrs.symbol).width\r\n this.textHeight = 36\r\n const xScale = this.attrs.scaleX\r\n const yScale = this.attrs.scaleY\r\n\r\n const xOffset = this.textWidth / -2\r\n const yOffset = this.textHeight / -2\r\n\r\n context.save()\r\n context.translate(this.scaled.x1, this.scaled.y1)\r\n context.rotate(this.attrs.angle)\r\n context.scale(xScale, yScale)\r\n context.fillText(this.attrs.symbol, xOffset, yOffset)\r\n context.restore()\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n getRotatedCoordinates(x: number, y: number) {\r\n const cx = this.scaled.x1\r\n const cy = this.scaled.y1\r\n const dx = x - cx\r\n const dy = y - cy\r\n const rx = dx * Math.cos(this.attrs.angle) - dy * Math.sin(this.attrs.angle)\r\n const ry = dy * Math.cos(this.attrs.angle) + dx * Math.sin(this.attrs.angle)\r\n return { x: cx + rx, y: cy + ry }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n return (this.attrs.y1 += y)\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n switch (type) {\r\n case 'xl':\r\n this.attrs.scaleX -= difX\r\n break\r\n case 'xr':\r\n this.attrs.scaleX += difX\r\n break\r\n case 'yt':\r\n this.attrs.scaleY -= difY\r\n break\r\n case 'yb':\r\n this.attrs.scaleY += difY\r\n break\r\n case 'c':\r\n this.attrs.angle += difX / 5\r\n break\r\n default:\r\n break\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const halfWidth = (this.textWidth / 2) * this.attrs.scaleX\r\n const halfHeight = (this.textHeight / 2) * this.attrs.scaleY\r\n const left = Math.min(this.scaled.x1 - halfWidth, this.scaled.x1 + halfWidth)\r\n const right = Math.max(this.scaled.x1 - halfWidth, this.scaled.x1 + halfWidth)\r\n const top = Math.min(this.scaled.y1 - halfHeight, this.scaled.y1 + halfHeight)\r\n const bottom = Math.max(this.scaled.y1 - halfHeight, this.scaled.y1 + halfHeight)\r\n if (left < area.scaled.x && area.scaled.x < right && top < area.scaled.y && area.scaled.y < bottom) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n}\r\n\r\nSymbolElement.prototype.defaults = { fill: 'rgba(0,0,0,1)' }\r\n\r\nSymbolElement.prototype.modalConfig = {\r\n inputs: [{ type: 'background', name: 'fill', label: 'Fill' }],\r\n}\r\n\r\nexport default SymbolElement\r\n","import { CanvasElementType } from '../constants/common'\r\nimport arrow from './arrow'\r\nimport brush_v1 from './brush/brush_v1'\r\nimport callout_v1 from './callout/callout_v1'\r\nimport curve from './curve'\r\nimport element from './element'\r\nimport elliottWaves from './elliott_waves/elliott_waves'\r\nimport ellipse from './ellipse'\r\nimport ellipse_v1 from './ellipse/ellipse_v1'\r\nimport fibonacci from './fibonacci_retracements'\r\nimport horizontalLine from './horizontal_line'\r\nimport line from './line'\r\nimport measure from './measure'\r\nimport pitchfork_v1 from './pitchfork/pitchfork_v1'\r\nimport polygon from './polygon'\r\nimport position from './position'\r\nimport rectangle from './rectangle'\r\nimport rotatedRectangle from './rotated_rectangle'\r\nimport rotatedRectangle_v1 from './rotated_rectangle/rotated_rectangle_v1'\r\nimport scaledLine from './scaled_line'\r\nimport scaledText from './scaled_text'\r\nimport symbolElement from './symbol'\r\nimport text from './text'\r\nimport triangle from './triangle'\r\nimport verticalLine from './vertical_line'\r\nimport xabcd from './xabcd'\r\n\r\nexport const drawingToolsByType = Object.freeze({\r\n [CanvasElementType.element]: element,\r\n [CanvasElementType.arrow]: arrow,\r\n [CanvasElementType.brushV1]: brush_v1,\r\n [CanvasElementType.calloutV1]: callout_v1,\r\n [CanvasElementType.curve]: curve,\r\n [CanvasElementType.elliottWaves]: elliottWaves,\r\n [CanvasElementType.ellipse]: ellipse,\r\n [CanvasElementType.ellipseV1]: ellipse_v1,\r\n [CanvasElementType.fibonacciRetracements]: fibonacci,\r\n [CanvasElementType.horizontalLine]: horizontalLine,\r\n [CanvasElementType.line]: line,\r\n [CanvasElementType.measure]: measure,\r\n [CanvasElementType.pitchforkV1]: pitchfork_v1,\r\n [CanvasElementType.polygon]: polygon,\r\n [CanvasElementType.position]: position,\r\n [CanvasElementType.rectangle]: rectangle,\r\n [CanvasElementType.rotatedRectangle]: rotatedRectangle,\r\n [CanvasElementType.rotatedRectangleV1]: rotatedRectangle_v1,\r\n [CanvasElementType.scaledLine]: scaledLine,\r\n [CanvasElementType.scaledText]: scaledText,\r\n [CanvasElementType.symbol]: symbolElement,\r\n [CanvasElementType.text]: text,\r\n [CanvasElementType.triangle]: triangle,\r\n [CanvasElementType.verticalLine]: verticalLine,\r\n [CanvasElementType.xabcd]: xabcd,\r\n})\r\n","import Spine from '@finviz/spine'\r\nimport merge from 'lodash.merge'\r\nimport mergewith from 'lodash.mergewith'\r\nimport omit from 'lodash.omit'\r\n\r\nimport {\r\n ChartConfigChartPaneElement,\r\n ObjectHash,\r\n PaneArea,\r\n RequireByKey,\r\n TodoObjectHashAnyType,\r\n} from '../../types/shared'\r\nimport Thumb from '../canvas/thumb'\r\nimport {\r\n CanvasElementType,\r\n ChartElementType,\r\n ChartEventType,\r\n IVisibility,\r\n IndicatorType,\r\n MacroTimeframe,\r\n MicroMacroTimeframe,\r\n OverlayType,\r\n SetVisibilityTo,\r\n TIMEFRAME,\r\n} from '../constants/common'\r\nimport Chart from '../models/chart'\r\nimport PaneModel, { ScaleAxis } from '../models/pane'\r\nimport Quote from '../models/quote'\r\nimport { getChartLayoutSettings } from '../models/settings'\r\nimport { isInRange } from '../utils/helpers'\r\n\r\nexport type TodoModalConfig = TodoObjectHashAnyType\r\ntype TodoPositionTimestamps = TodoObjectHashAnyType\r\n\r\nexport interface DefaultAttrs extends ObjectHash {\r\n positionTimestamps?: TodoPositionTimestamps\r\n visibility?: IVisibility\r\n}\r\n\r\nexport type EdgeValues = { minX?: number; maxX?: number; minY?: number; maxY?: number }\r\n\r\nclass Element extends Spine.Module {\r\n static type: CanvasElementType | OverlayType | ChartElementType | IndicatorType | ChartEventType =\r\n CanvasElementType.element\r\n\r\n static fromObject(obj: T['attrs'], model: T['model']) {\r\n return new this(obj, model) as T\r\n }\r\n\r\n static getNumOfBarsBuffer(\r\n _?: RequireByKey | RequireByKey\r\n ) {\r\n return 0\r\n }\r\n\r\n isCreator = false\r\n isCreatorDialogOpen = false\r\n attrs: Attrs = {} as Attrs\r\n\r\n model: any\r\n _thumbs: Thumb[]\r\n\r\n getDefaults?(): Partial\r\n renderCross?(ctx: RenderingContext2DType): void\r\n renderCrossText?(\r\n ctx: RenderingContext2DType,\r\n crossIndex: number,\r\n getDataByCrossIndex?: (key: keyof Quote, shouldReturnRoundedString?: boolean) => string | undefined\r\n ): void\r\n\r\n renderContent?(ctx: RenderingContext2DType): void\r\n renderGrid?(ctx: RenderingContext2DType): void\r\n renderLabels?(ctx: RenderingContext2DType): void\r\n declare defaults?: Partial\r\n getModalConfigBase?(): TodoModalConfig\r\n declare modalConfig?: TodoModalConfig\r\n getMinMax?(): { min: number; max: number }\r\n setupAxis?(fx: ScaleAxis): void | { min: number; max: number }\r\n\r\n activeThumb: Thumb | null = null\r\n isMouseDown = false\r\n isSelected = false\r\n isHovered = false\r\n isEditInProgress = false\r\n edgeXYValues: EdgeValues | null = null\r\n declare scaled?: ObjectHash | Partial\r\n\r\n declare toolsCallback: () => void\r\n\r\n constructor(values: Partial, model: Model) {\r\n super(values, model)\r\n this.model = model\r\n if (this.getDefaults) {\r\n this.set(this.getDefaults() || {})\r\n } else {\r\n this.set(this.defaults || {})\r\n }\r\n this.set(values)\r\n this._thumbs = []\r\n\r\n this.onMouseDown = this.onMouseDown.bind(this)\r\n this.onMouseMove = this.onMouseMove.bind(this)\r\n this.onMouseUp = this.onMouseUp.bind(this)\r\n this.bind('mousedown', this.onMouseDown)\r\n this.bind('mousemove', this.onMouseMove)\r\n this.bind('mouseup', this.onMouseUp)\r\n this.bind('change', () => {\r\n // elements is optional because this.model is not Pane in all usecases, e.g. base_chart extends this element and sets Chart as model\r\n const element = this.getIsChartEvent()\r\n ? this.model.chartEvents?.()?.findByAttribute('instance', this)\r\n : this.model.elements?.()?.findByAttribute('instance', this)\r\n\r\n element?.trigger('change', element)\r\n })\r\n }\r\n\r\n get type() {\r\n return (this.constructor as typeof Element).type\r\n }\r\n\r\n getThumbs() {\r\n return this._thumbs\r\n }\r\n\r\n moveBy(_: number, __: number) {}\r\n\r\n setIsSelected(isSelected: boolean) {\r\n this.isSelected = isSelected\r\n this.trigger('change')\r\n }\r\n\r\n setIsHovered(isHovered: boolean) {\r\n this.isHovered = isHovered\r\n this.trigger('change')\r\n }\r\n\r\n getShouldRenderThumbs() {\r\n return this.isSelected || this.isHovered\r\n }\r\n\r\n getIsPaneSelection(): boolean {\r\n const paneModel = this.model.elements().findByAttribute('instance', this)?.pane() as PaneModel | undefined\r\n return paneModel?.selection === this\r\n }\r\n\r\n set(obj: Partial) {\r\n const attrsSubset = Object.keys(obj).reduce(\r\n (acc, key) => ({ ...acc, [key]: this.attrs[key] }),\r\n {} as Partial\r\n )\r\n if (JSON.stringify(obj) !== JSON.stringify(attrsSubset)) {\r\n const customizer = (objValue: Partial, srcValue: Partial, key: keyof Attrs) => {\r\n if (this.getIsDrawing() && key === 'visibility') {\r\n return srcValue ?? {}\r\n }\r\n }\r\n mergewith(this.attrs, obj, customizer)\r\n if (this.getIsPaneSelection() && !this.getIsCreator()) {\r\n this.cachePointPositionTimestamp()\r\n }\r\n this.trigger('change', this)\r\n }\r\n this.edgeXYValues = null\r\n return this\r\n }\r\n\r\n get(key: T) {\r\n return this.attrs[key]\r\n }\r\n\r\n getBoundingPointKeys = (): { x: string[]; y: string[] } | void => {}\r\n\r\n fx = (x: number) => this.model.scale.x(x)\r\n\r\n fy = (y: number) => this.model.scale.y(y)\r\n\r\n scale({ x, y }: { x: string[]; y: string[] }) {\r\n this.scaled = {}\r\n x.forEach((el) => {\r\n Object.defineProperty(this.scaled, el, {\r\n get: () => this.fx(this.attrs[el]),\r\n })\r\n })\r\n\r\n y.forEach((el) => {\r\n Object.defineProperty(this.scaled, el, {\r\n get: () => this.fy(this.attrs[el]),\r\n })\r\n })\r\n }\r\n\r\n render(_: RenderingContext2DType) {}\r\n\r\n renderThumbs(context: CanvasRenderingContext2D) {\r\n const isHoveredThumbStyle = this.isHovered && !this.isSelected\r\n if (isHoveredThumbStyle) {\r\n context.globalAlpha = 0.5\r\n }\r\n this.getThumbs().map((thumb) => thumb.render(context))\r\n context.globalAlpha = 1\r\n }\r\n\r\n onMouseDown(area: PaneArea) {\r\n this.isMouseDown = true\r\n this.isEditInProgress = true\r\n for (const thumb of this.getThumbs()) {\r\n if (thumb.isInArea(area)) {\r\n this.activeThumb = thumb\r\n this.activeThumb.startEditing(area)\r\n return\r\n }\r\n }\r\n }\r\n\r\n onMouseMove(area: PaneArea) {\r\n if (!area.mouseDown) {\r\n return\r\n }\r\n if (this.activeThumb != null) {\r\n this.activeThumb.moveTo(area)\r\n this.trigger('change')\r\n }\r\n }\r\n\r\n onMouseUp(_?: PaneArea) {\r\n this.isMouseDown = false\r\n this.isEditInProgress = false\r\n this.activeThumb = null\r\n if (!this.getIsCreator() && !this.getIsChartEvent()) {\r\n this.cachePointPositionTimestamp()\r\n }\r\n this.trigger('change', this)\r\n }\r\n\r\n cachePointPositionTimestamp = () => {\r\n const quote = this.model?.chart().quote()\r\n if (quote) {\r\n const { x: xPointKeys } = this.getBoundingPointKeys()!\r\n const positionTimestamps = xPointKeys.reduce((acc, key) => {\r\n const positionX = this.attrs[key]\r\n const timeStamp = positionX && quote.getTimestampFomPositionX(positionX)\r\n return {\r\n ...acc,\r\n [key]: timeStamp,\r\n }\r\n }, {}) as TodoPositionTimestamps\r\n this.set({ positionTimestamps } as Partial)\r\n }\r\n }\r\n\r\n updateScales() {\r\n const quote = this.model.chart().quote()\r\n const { positionTimestamps } = this.attrs\r\n if (!quote || !positionTimestamps) {\r\n // positionTimestamps check is temporary to prevent app from crashing\r\n // caused by corrupted drawings - https://github.com/finvizhq/charts/pull/1386/files\r\n return\r\n }\r\n const pointPoitionsFromTimestamp = Object.entries(positionTimestamps).reduce(\r\n (acc, [key, timestamp]) => ({\r\n ...acc,\r\n [key]: timestamp && quote.getPositionXFromTimestamp(timestamp),\r\n }),\r\n {}\r\n )\r\n this.set(pointPoitionsFromTimestamp)\r\n }\r\n\r\n thumbsAreInArea(area: PaneArea) {\r\n for (const thumb of this.getThumbs()) {\r\n if (thumb.isInArea(area)) {\r\n return true\r\n }\r\n }\r\n return false\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n return this.thumbsAreInArea(area)\r\n }\r\n\r\n isDrawingElementLockedOrInvisible() {\r\n return this.model.chart().chart_layout().isLockDrawingsActive || !this.getIsVisible()\r\n }\r\n\r\n getModalConfig() {\r\n let config\r\n if (this.getModalConfigBase) {\r\n config = merge({}, this.getModalConfigBase())\r\n } else {\r\n config = merge({}, this.modalConfig)\r\n }\r\n if (this.getIsDrawing()) {\r\n config.inputs.push({ type: 'visibility', name: 'visibility', label: 'Visibility' })\r\n }\r\n if (config.title == null) {\r\n config.title = this.name\r\n }\r\n for (const input of config.inputs) {\r\n if (input.default != null) {\r\n input.value = input.default\r\n }\r\n if (this.attrs[input.name] != null) {\r\n input.value = this.attrs[input.name]\r\n }\r\n }\r\n return config\r\n }\r\n\r\n toObject() {\r\n return merge({}, this.attrs, { type: this.type })\r\n }\r\n\r\n toConfig(): T['attrs'] & { type: T['type'] } {\r\n return this.toObject()\r\n }\r\n\r\n getAutosaveOmittedProperties() {\r\n return this.attrs.positionTimestamps ? Object.keys(this.attrs.positionTimestamps) : []\r\n }\r\n\r\n toAutosaveConfig() {\r\n // We don't want to save attrs which are stored in \"position timestamps\" because they are relative to timeframe for example\r\n // so in order to keep drawings in sync across different timeframes we can't rely on its position but we have to rely on \"position timestamps\" and then call updateScales to calculate correct positions for given timeframe\r\n return omit(this.toConfig(), this.getAutosaveOmittedProperties()) as Partial\r\n }\r\n\r\n replaceMyself(element: Element) {\r\n setTimeout(() => {\r\n element.cachePointPositionTimestamp()\r\n const el = this.model.elements().findByAttribute('instance', this)\r\n if (!el) {\r\n // Temporary code below\r\n // additional info gaining for https://finvizcom.sentry.io/issues/3990343438/events/e87ce8b4108341cf81f15ec78707c65e/?project=33153&query=is%3Aunresolved+Cannot+read+properties+of+undefined&referrer=previous-event&statsPeriod=14d&stream_index=0\r\n window.Sentry?.captureMessage('element.ts replaceMyself', {\r\n extra: {\r\n oldElement: {\r\n type: this?.type,\r\n isCreator: this?.isCreator,\r\n isMouseDown: this?.isMouseDown,\r\n isSelected: this?.isSelected,\r\n isHovered: this?.isHovered,\r\n isEditInProgress: this?.isEditInProgress,\r\n },\r\n newElement: {\r\n type: element?.type,\r\n isCreator: element?.isCreator,\r\n isMouseDown: element?.isMouseDown,\r\n isSelected: element?.isSelected,\r\n isHovered: element?.isHovered,\r\n isEditInProgress: element?.isEditInProgress,\r\n },\r\n },\r\n })\r\n } else {\r\n el.replace(element)\r\n }\r\n })\r\n }\r\n\r\n toString() {\r\n return this.name\r\n }\r\n\r\n getIsCreator() {\r\n return this.isCreator\r\n }\r\n\r\n getIsCreatorDialogOpen() {\r\n return this.isCreatorDialogOpen\r\n }\r\n\r\n release() {\r\n this.cachePointPositionTimestamp()\r\n this.unbind()\r\n }\r\n\r\n getChartLayoutSettings() {\r\n return getChartLayoutSettings(this.model.chart().chart_layout())\r\n }\r\n\r\n getIsDrawing() {\r\n return !!this.type.startsWith('canvas/')\r\n }\r\n\r\n getIsChartEvent() {\r\n return !!this?.type.startsWith('chartEvent/')\r\n }\r\n\r\n getIsVisible() {\r\n const { micro, macro } = MicroMacroTimeframe[this.model.chart().quote().timeframe as TIMEFRAME]\r\n const visibility = this.attrs.visibility?.[macro]\r\n\r\n // this.attrs.visibility.minutes === undefined: drawing visible on any minutes timeframe\r\n if (visibility === undefined) return true\r\n // this.attrs.visibility.minutes === {}: drawing invisible on any minutes timeframe\r\n if (Object.keys(visibility).length === 0) return false\r\n // this.attrs.visibility.minutes === {from: 5, to: 15}: drawing visible on minutes TF between 5 & 15 interval\r\n return isInRange({ value: micro, min: visibility.from, max: visibility.to })\r\n }\r\n\r\n setVisibilityTo(setTo: SetVisibilityTo) {\r\n const { macro, micro } = MicroMacroTimeframe[this.model.chart().quote().timeframe as TIMEFRAME]\r\n const currentIndex = Object.keys(MacroTimeframe).indexOf(macro)\r\n\r\n let timeframesToSet: string[] = []\r\n let attrsToSet: { from?: number; to?: number } = {}\r\n\r\n switch (setTo) {\r\n case SetVisibilityTo.currentAndAbove: {\r\n timeframesToSet = Object.keys(MacroTimeframe).filter((key, index) => index < currentIndex)\r\n attrsToSet = { from: micro }\r\n break\r\n }\r\n case SetVisibilityTo.currentAndBelow: {\r\n timeframesToSet = Object.keys(MacroTimeframe).filter((key, index) => index > currentIndex)\r\n attrsToSet = { to: micro }\r\n break\r\n }\r\n case SetVisibilityTo.currentOnly: {\r\n timeframesToSet = Object.keys(MacroTimeframe).filter((key, index) => index !== currentIndex)\r\n attrsToSet = { from: micro, to: micro }\r\n break\r\n }\r\n case SetVisibilityTo.all:\r\n default: {\r\n this.set({ visibility: {} } as Partial)\r\n return\r\n }\r\n }\r\n\r\n this.set({\r\n visibility: Object.assign({}, ...timeframesToSet.map((item) => ({ [item]: {} })), { [macro]: attrsToSet }),\r\n } as Partial)\r\n }\r\n\r\n getEdgeXYValues() {\r\n const { x: xPoints, y: yPoints } = this.getBoundingPointKeys() ?? {}\r\n if (this.edgeXYValues === null) {\r\n const edgeXYValues = {} as EdgeValues\r\n xPoints?.forEach((key) => {\r\n const positionX = this.attrs[key]\r\n if (positionX !== undefined) {\r\n edgeXYValues.minX = Math.min(positionX, edgeXYValues.minX ?? positionX)\r\n edgeXYValues.maxX = Math.max(positionX, edgeXYValues.maxX ?? positionX)\r\n }\r\n })\r\n yPoints?.forEach((key) => {\r\n const positionY = this.attrs[key]\r\n if (positionY !== undefined) {\r\n edgeXYValues.minY = Math.min(positionY, edgeXYValues.minY ?? positionY)\r\n edgeXYValues.maxY = Math.max(positionY, edgeXYValues.maxY ?? positionY)\r\n }\r\n })\r\n\r\n this.edgeXYValues = edgeXYValues\r\n }\r\n\r\n return this.edgeXYValues\r\n }\r\n\r\n getIsInChartView(chart: Chart, options?: { omitX?: boolean; omitY?: boolean }) {\r\n const { minX, maxX, minY, maxY } = this.getEdgeXYValues()\r\n\r\n if (this.getIsCreator()) {\r\n return true\r\n }\r\n\r\n if (!options?.omitX) {\r\n const isMaxXInvalid = maxX === undefined || isNaN(maxX)\r\n const isMinXInvalid = minX === undefined || isNaN(minX)\r\n if (\r\n !isMaxXInvalid &&\r\n !isMinXInvalid &&\r\n !(this.fx(maxX) >= -chart.leftOffset && this.fx(minX) <= -chart.leftOffset + chart.width)\r\n ) {\r\n return false\r\n }\r\n }\r\n\r\n if (!options?.omitY) {\r\n if (minY === undefined || maxY === undefined) {\r\n return true\r\n }\r\n\r\n const topBound = this.model.scale.y.invert(0)\r\n const bottomBound = this.model.scale.y.invert(this.model.height)\r\n return topBound >= minY && bottomBound <= maxY\r\n }\r\n\r\n // If all checks fall through, render element\r\n return true\r\n }\r\n}\r\n\r\nexport default Element\r\n","import { DrawingBorder, PaneArea, ResizeByThumbWithTypeAndDifs } from '../../../types/shared'\r\nimport { CanvasElementType, TextAlign, TextBaseline } from '../../constants/common'\r\nimport { getOffsetFromLineWidth } from '../../controllers/renderUtils'\r\nimport math from '../../helpers/math'\r\nimport PaneModel from '../../models/pane'\r\nimport Element from '../element'\r\nimport Text from '../text'\r\nimport Thumb from '../thumb'\r\n\r\nexport interface IElliottWavesAttrs {\r\n waves: Array<{ x: number; y: number }>\r\n positionWavesTimestamps?: Array<{ x: number; y: number }>\r\n border: DrawingBorder\r\n}\r\n\r\nclass ElliottWaves extends Element {\r\n static type = CanvasElementType.elliottWaves\r\n\r\n name = 'Elliott Wave'\r\n waves = ['', 'I', 'II', 'III', 'IV', 'V']\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n }\r\n\r\n getDefaults() {\r\n return {\r\n border: {\r\n width: 2,\r\n color: this.getChartLayoutSettings().ElementSettings.Colors.line,\r\n },\r\n } as Partial\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const offset = getOffsetFromLineWidth(this.attrs.border.width)\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n\r\n context.translate(offset, offset)\r\n context.beginPath()\r\n context.moveTo(Math.round(this.fx(this.attrs.waves[0].x)), Math.round(this.fy(this.attrs.waves[0].y)))\r\n for (const p of this.attrs.waves.slice(1)) {\r\n context.lineTo(Math.round(this.fx(p.x)), Math.round(this.fy(p.y)))\r\n }\r\n context.stroke()\r\n context.translate(offset * -1, offset * -1)\r\n\r\n const text = new Text(\r\n {\r\n font: { size: 8, style: 'bold' },\r\n textBaseline: TextBaseline.middle,\r\n textAlign: TextAlign.center,\r\n fillStyle: this.getChartLayoutSettings().ElementSettings.Colors.textWithoutBackground,\r\n },\r\n this.model\r\n )\r\n for (let i = 0; i < this.attrs.waves.length; i++) {\r\n let y\r\n const p = this.attrs.waves[i]\r\n if (i > 0 && this.attrs.waves[i - 1].y > p.y) {\r\n y = this.fy(p.y) + 8\r\n } else {\r\n y = this.fy(p.y) - 8\r\n }\r\n text.set({ text: this.waves[i], x: this.fx(p.x), y })\r\n text.render(context)\r\n }\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n getThumbs() {\r\n return this.attrs.waves.map(\r\n (wave, index) =>\r\n new Thumb(\r\n `${index}`,\r\n () => wave.x,\r\n () => wave.y,\r\n this.resize,\r\n this.model\r\n )\r\n )\r\n }\r\n\r\n cachePointPositionTimestamp = () => {\r\n const quote = this.model?.chart().quote()\r\n if (quote) {\r\n const positionWavesTimestamps = this.attrs.waves.map((wave) => ({\r\n ...wave,\r\n x: quote.getTimestampFomPositionX(wave.x),\r\n }))\r\n\r\n this.set({ positionWavesTimestamps } as Partial)\r\n }\r\n }\r\n\r\n updateScales() {\r\n const quote = this.model.chart().quote()\r\n const { positionWavesTimestamps } = this.attrs\r\n if (!quote || !positionWavesTimestamps) {\r\n // positionWavesTimestamps check is temporary to prevent app from crashing\r\n // caused by corrupted drawings - https://github.com/finvizhq/charts/pull/1386/files\r\n return\r\n }\r\n const waves = positionWavesTimestamps.map((wave) => ({\r\n ...wave,\r\n x: quote.getPositionXFromTimestamp(wave.x),\r\n }))\r\n this.set({ waves } as Partial)\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n for (const point of this.attrs.waves) {\r\n point.x += x\r\n point.y += y\r\n }\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n this.attrs.waves[+type].x += difX\r\n this.attrs.waves[+type].y += difY\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const waves = this.attrs.waves\r\n for (let i = 0; i < waves.length - 1; i++) {\r\n if (\r\n math.distanceToSegment(area.scaled, {\r\n x1: this.fx(waves[i].x),\r\n y1: this.fy(waves[i].y),\r\n x2: this.fx(waves[i + 1].x),\r\n y2: this.fy(waves[i + 1].y),\r\n }) <= 10\r\n ) {\r\n return true\r\n }\r\n }\r\n return super.isInArea(area)\r\n }\r\n\r\n getAutosaveOmittedProperties() {\r\n return ['waves']\r\n }\r\n}\r\n\r\nElliottWaves.prototype.modalConfig = {\r\n inputs: [{ type: 'line', name: 'border' }],\r\n}\r\n\r\nexport default ElliottWaves\r\n","import { DrawingBorder, PaneArea, Point, ResizeByThumbWithTypeAndDifs } from '../../../types/shared'\r\nimport { CanvasElementType } from '../../constants/common'\r\nimport math from '../../helpers/math'\r\nimport PaneModel from '../../models/pane'\r\nimport { getContextWithCache } from '../../utils/canvas'\r\nimport Element from '../element'\r\nimport Thumb from '../thumb'\r\n\r\nexport interface IEllipseAttrs {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n cursorTargetX: number\r\n cursorTargetY: number\r\n\r\n fill: string\r\n border: DrawingBorder\r\n}\r\n\r\ninterface Coordinates {\r\n P1: Point\r\n P2: Point\r\n P3: Point\r\n P4: Point\r\n CP1: Point\r\n CP2: Point\r\n CP3: Point\r\n CP4: Point\r\n}\r\n\r\nclass EllipseV1 extends Element {\r\n static type = CanvasElementType.ellipseV1\r\n\r\n name = 'Ellipse'\r\n\r\n untranslatedContext: CanvasRenderingContext2D | null = null\r\n declare ellipsePath: Path2D\r\n declare scaled: Pick\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n this.untranslatedContext = getContextWithCache(document.createElement('canvas'))\r\n this._thumbs = [\r\n new Thumb(\r\n 'left',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'right',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'top',\r\n () => this.getEllipsePoints(true).P2.x || this.attrs.x1,\r\n () => this.getEllipsePoints(true).P2.y || this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'bottom',\r\n () => this.getEllipsePoints(true).P4.x || this.attrs.x2,\r\n () => this.getEllipsePoints(true).P4.y || this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getDefaults() {\r\n const { ElementSettings } = this.getChartLayoutSettings()\r\n return {\r\n fill: ElementSettings.defaultFill,\r\n border: {\r\n width: 1,\r\n color: ElementSettings.Colors.border,\r\n },\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2', 'cursorTargetX'], y: ['y1', 'y2', 'cursorTargetY'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const coordinates = this.getEllipsePoints() as Coordinates\r\n const ellipse = new Path2D()\r\n context.set('fillStyle', this.attrs.fill)\r\n context.beginPath()\r\n if (coordinates.P2.x === coordinates.P3.x || coordinates.P2.y === coordinates.P3.y) {\r\n ellipse.lineTo(coordinates.P1.x, coordinates.P1.y)\r\n ellipse.lineTo(coordinates.P2.x, coordinates.P2.y)\r\n } else {\r\n ellipse.moveTo(coordinates.P4.x, coordinates.P4.y)\r\n ellipse.bezierCurveTo(\r\n coordinates.CP4.x,\r\n coordinates.CP4.y,\r\n coordinates.CP1.x,\r\n coordinates.CP1.y,\r\n coordinates.P2.x,\r\n coordinates.P2.y\r\n )\r\n ellipse.bezierCurveTo(\r\n coordinates.CP2.x,\r\n coordinates.CP2.y,\r\n coordinates.CP3.x,\r\n coordinates.CP3.y,\r\n coordinates.P4.x,\r\n coordinates.P4.y\r\n )\r\n ellipse.closePath()\r\n this.ellipsePath = ellipse\r\n context.fill(ellipse)\r\n }\r\n\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n context.stroke(ellipse)\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n getEllipsePoints(inverted = false) {\r\n const { x1, x2, y1, y2, cursorTargetX, cursorTargetY } = this.scaled\r\n\r\n const P1 = { x: x2, y: y2 }\r\n const P3 = { x: x1, y: y1 }\r\n\r\n let perpendicularPoint\r\n if (!isNaN(cursorTargetX) && !isNaN(cursorTargetY)) {\r\n const cursor = { x: cursorTargetX, y: cursorTargetY }\r\n const line = { x1, y1, x2, y2 }\r\n const distance = math.distanceToLine(cursor, line)\r\n perpendicularPoint = math.perpendicularPointToLine({\r\n distance,\r\n line,\r\n })\r\n } else {\r\n return {\r\n P1: P3,\r\n P2: P1,\r\n P3: P1,\r\n P4: P3,\r\n }\r\n }\r\n\r\n const lineCenterX = (P1.x + P3.x) / 2\r\n const lineCenterY = (P1.y + P3.y) / 2\r\n const pointOffsetX = perpendicularPoint.x - P1.x\r\n const pointOffsetY = perpendicularPoint.y - P1.y\r\n\r\n const P2 = { x: lineCenterX + pointOffsetX, y: lineCenterY + pointOffsetY }\r\n const P4 = { x: lineCenterX + -1 * pointOffsetX, y: lineCenterY + -1 * pointOffsetY }\r\n const invertX = this.model.scale.x.invert\r\n const invertY = this.model.scale.y.invert\r\n if (inverted) {\r\n return {\r\n P2: { x: invertX(P2.x), y: invertY(P2.y) },\r\n P4: { x: invertX(P4.x), y: invertY(P4.y) },\r\n }\r\n }\r\n\r\n const perpendicularPointEllipseOffsetX = (perpendicularPoint.x - P2.x) / 0.75 - (perpendicularPoint.x - P2.x)\r\n const perpendicularPointEllipseOffsetY = (perpendicularPoint.y - P2.y) / 0.75 - (perpendicularPoint.y - P2.y)\r\n\r\n const P1WithOffsetX = P1.x + perpendicularPointEllipseOffsetX\r\n const P1WithOffsetY = P1.y + perpendicularPointEllipseOffsetY\r\n\r\n const P3WithOffsetX = P3.x - perpendicularPointEllipseOffsetX\r\n const P3WithOffsetY = P3.y - perpendicularPointEllipseOffsetY\r\n\r\n const CP1 = {\r\n x: perpendicularPoint.x + perpendicularPointEllipseOffsetX,\r\n y: perpendicularPoint.y + perpendicularPointEllipseOffsetY,\r\n }\r\n const controlPointOffsetX = CP1.x - P1WithOffsetX\r\n const controlPointOffsetY = CP1.y - P1WithOffsetY\r\n\r\n const CP2 = { x: P3WithOffsetX + controlPointOffsetX, y: P3WithOffsetY + controlPointOffsetY }\r\n const CP3 = { x: P3WithOffsetX + -1 * controlPointOffsetX, y: P3WithOffsetY + -1 * controlPointOffsetY }\r\n const CP4 = { x: P1WithOffsetX + -1 * controlPointOffsetX, y: P1WithOffsetY + -1 * controlPointOffsetY }\r\n\r\n return {\r\n P1,\r\n P2,\r\n P3,\r\n P4,\r\n CP1,\r\n CP2,\r\n CP3,\r\n CP4,\r\n }\r\n }\r\n\r\n getRotatedPointCoordinates = ({\r\n rotationAxisPoint,\r\n pointToRotate,\r\n oldLinePoint,\r\n newLinePoint,\r\n }: {\r\n rotationAxisPoint: { x: number; y: number }\r\n pointToRotate: { x: number; y: number }\r\n oldLinePoint: { x: number; y: number }\r\n newLinePoint: { x: number; y: number }\r\n }) => {\r\n const angle = math.sharedPointLinesAngle({\r\n sharedPoint: rotationAxisPoint,\r\n oldLinePoint,\r\n newLinePoint,\r\n })\r\n const rotatedPoinCoordinates = math.rotatedPointCoordinates({\r\n rotationAxisPoint,\r\n angle,\r\n pointToRotate,\r\n })\r\n return {\r\n x: this.model.scale.x.invert(rotatedPoinCoordinates.x),\r\n y: this.model.scale.y.invert(rotatedPoinCoordinates.y),\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.y1 += y\r\n this.attrs.x2 += x\r\n this.attrs.y2 += y\r\n this.attrs.cursorTargetX += x\r\n this.attrs.cursorTargetY += y\r\n }\r\n\r\n resize({ type, difX, difY, area }: ResizeByThumbWithTypeAndDifs) {\r\n switch (type) {\r\n case 'left':\r\n const newLeftPoint = {\r\n x: this.attrs.x1 + difX,\r\n y: this.attrs.y1 + difY,\r\n }\r\n const leftRotatedCursorPoint = this.getRotatedPointCoordinates({\r\n rotationAxisPoint: { x: this.scaled.x2, y: this.scaled.y2 },\r\n pointToRotate: {\r\n x: this.scaled.cursorTargetX,\r\n y: this.scaled.cursorTargetY,\r\n },\r\n oldLinePoint: { x: this.scaled.x1, y: this.scaled.y1 },\r\n newLinePoint: { x: this.model.scale.x(newLeftPoint.x), y: this.model.scale.y(newLeftPoint.y) },\r\n })\r\n this.attrs = {\r\n ...this.attrs,\r\n x1: newLeftPoint.x,\r\n y1: newLeftPoint.y,\r\n cursorTargetX: leftRotatedCursorPoint.x,\r\n cursorTargetY: leftRotatedCursorPoint.y,\r\n }\r\n break\r\n case 'right':\r\n const newRightPoint = {\r\n x: this.attrs.x2 + difX,\r\n y: this.attrs.y2 + difY,\r\n }\r\n const rightRotatedCursorPoint = this.getRotatedPointCoordinates({\r\n rotationAxisPoint: { x: this.scaled.x1, y: this.scaled.y1 },\r\n pointToRotate: {\r\n x: this.scaled.cursorTargetX,\r\n y: this.scaled.cursorTargetY,\r\n },\r\n oldLinePoint: { x: this.scaled.x2, y: this.scaled.y2 },\r\n newLinePoint: { x: this.model.scale.x(newRightPoint.x), y: this.model.scale.y(newRightPoint.y) },\r\n })\r\n this.attrs = {\r\n ...this.attrs,\r\n x2: newRightPoint.x,\r\n y2: newRightPoint.y,\r\n cursorTargetX: rightRotatedCursorPoint.x,\r\n cursorTargetY: rightRotatedCursorPoint.y,\r\n }\r\n break\r\n case 'top':\r\n case 'bottom':\r\n this.attrs = {\r\n ...this.attrs,\r\n cursorTargetX: area.x,\r\n cursorTargetY: area.y,\r\n }\r\n break\r\n default:\r\n break\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n if (this.ellipsePath && this.untranslatedContext?.isPointInPath(this.ellipsePath, area.scaled.x, area.scaled.y)) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n\r\n getIsInChartView() {\r\n return true\r\n }\r\n}\r\n\r\nEllipseV1.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'background', name: 'fill' },\r\n { type: 'border', name: 'border', min: 1, default: {} },\r\n ],\r\n}\r\n\r\nexport default EllipseV1\r\n","import { DrawingBorder, PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType, TextAlign, TextBaseline } from '../constants/common'\r\nimport { getRoundedObject, getXYOffsetFromLine } from '../controllers/renderUtils'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Text, { ITextAttrs } from './text'\r\nimport Thumb from './thumb'\r\n\r\ntype Coefficients = string\r\n\r\nexport interface IFibonacciRetracementsAttrs {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n coefficients: Coefficients\r\n border: DrawingBorder\r\n}\r\n\r\nclass FibonacciRetracements<\r\n Attrs extends IFibonacciRetracementsAttrs = IFibonacciRetracementsAttrs,\r\n> extends Element {\r\n static type = CanvasElementType.fibonacciRetracements\r\n\r\n name = 'Fibonacci Retracements'\r\n declare coefficients: { default: string; parsed: number[]; max: number; min: number }\r\n declare scaled: Pick\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n this._thumbs = [\r\n new Thumb(\r\n 'oneCoefficient_1',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'oneCoefficient_2',\r\n () => this.attrs.x2,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'zeroCoefficient_1',\r\n () => this.attrs.x1,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'zeroCoefficient_2',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.parseCoefficients(this.attrs.coefficients)\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getDefaults() {\r\n return {\r\n border: {\r\n width: 1,\r\n color: this.getChartLayoutSettings().ElementSettings.Colors.line,\r\n },\r\n coefficients: [0, 0.236, 0.382, 0.5, 0.618, 1].toString(),\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n parseCoefficients(coefficients: Coefficients) {\r\n if (!this.coefficients || coefficients !== this.coefficients.default) {\r\n const parsed = coefficients.split(',').map((x) => parseFloat(x.trim()))\r\n this.coefficients = { default: coefficients, parsed, max: Math.max(...parsed), min: Math.min(...parsed) }\r\n }\r\n }\r\n\r\n getMaxCoefficientUnscaledY() {\r\n return this.model.scale.y.invert(this.scaled.y2 - this.coefficients.max * (this.scaled.y2 - this.scaled.y1))\r\n }\r\n\r\n getMinCoefficientUnscaledY() {\r\n return this.model.scale.y.invert(this.scaled.y2 - this.coefficients.min * (this.scaled.y2 - this.scaled.y1))\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { x1, x2, y1, y2 } = this.scaled\r\n const roundedXY = getRoundedObject({ x1, x2, y1, y2 })\r\n const translateXY = getXYOffsetFromLine({ lineWidth: this.attrs.border.width, ...roundedXY, y2: roundedXY.y1 })\r\n\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n this.parseCoefficients(this.attrs.coefficients)\r\n\r\n const height = this.attrs.y2 - this.attrs.y1\r\n const heightScaled = roundedXY.y2 - roundedXY.y1\r\n\r\n context.translate(translateXY.x, translateXY.y)\r\n context.beginPath()\r\n for (const p of this.coefficients.parsed) {\r\n context.moveTo(roundedXY.x1, Math.round(y2 - p * heightScaled))\r\n context.lineTo(roundedXY.x2, Math.round(y2 - p * heightScaled))\r\n }\r\n context.stroke()\r\n context.translate(translateXY.x * -1, translateXY.y * -1)\r\n\r\n const text = new Text(\r\n {\r\n x: roundedXY.x1,\r\n font: { size: 8, style: 'bold' },\r\n textBaseline: TextBaseline.bottom,\r\n fillStyle: this.attrs.border.color,\r\n textAlign: TextAlign.left,\r\n },\r\n this.model\r\n )\r\n if (roundedXY.x1 > roundedXY.x2) {\r\n text.set({ textAlign: TextAlign.right })\r\n }\r\n\r\n for (const p of this.coefficients.parsed) {\r\n const y = this.attrs.y2 - p * height\r\n text.set({\r\n text: (p * 100).toFixed(1) + '%: ' + y.toFixed(2),\r\n y: Math.round(this.fy(y) - this.attrs.border.width / 2),\r\n } as Partial)\r\n text.render(context)\r\n }\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n getThumbs() {\r\n if (this.coefficients.max > 1 && !this._thumbs.some(({ type }) => type.includes('maxCoefficient'))) {\r\n this._thumbs = [\r\n ...this._thumbs,\r\n new Thumb(\r\n 'maxCoefficient_1',\r\n () => this.attrs.x1,\r\n () => this.getMaxCoefficientUnscaledY(),\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'maxCoefficient_2',\r\n () => this.attrs.x2,\r\n () => this.getMaxCoefficientUnscaledY(),\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n }\r\n if (this.coefficients.max <= 1 && this._thumbs.some(({ type }) => type.includes('maxCoefficient'))) {\r\n this._thumbs = this._thumbs.filter(({ type }) => !type.includes('maxCoefficient'))\r\n }\r\n\r\n if (this.coefficients.min < 0 && !this._thumbs.some(({ type }) => type.includes('minCoefficient'))) {\r\n this._thumbs = [\r\n ...this._thumbs,\r\n new Thumb(\r\n 'minCoefficient_1',\r\n () => this.attrs.x1,\r\n () => this.getMinCoefficientUnscaledY(),\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'minCoefficient_2',\r\n () => this.attrs.x2,\r\n () => this.getMinCoefficientUnscaledY(),\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n }\r\n if (this.coefficients.min >= 0 && this._thumbs.some(({ type }) => type.includes('minCoefficient'))) {\r\n this._thumbs = this._thumbs.filter(({ type }) => !type.includes('minCoefficient'))\r\n }\r\n\r\n return this._thumbs\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.x2 += x\r\n this.attrs.y1 += y\r\n this.attrs.y2 += y\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n switch (type) {\r\n case 'oneCoefficient_1':\r\n this.attrs.x1 += difX\r\n this.attrs.y1 += difY\r\n break\r\n case 'oneCoefficient_2':\r\n this.attrs.x2 += difX\r\n this.attrs.y1 += difY\r\n break\r\n case 'zeroCoefficient_1':\r\n this.attrs.x1 += difX\r\n this.attrs.y2 += difY\r\n break\r\n case 'zeroCoefficient_2':\r\n this.attrs.x2 += difX\r\n this.attrs.y2 += difY\r\n break\r\n case 'maxCoefficient_1':\r\n this.attrs.x1 += difX\r\n this.attrs.y1 += difY / this.coefficients.max\r\n break\r\n case 'maxCoefficient_2':\r\n this.attrs.x2 += difX\r\n this.attrs.y1 += difY / this.coefficients.max\r\n break\r\n case 'minCoefficient_1':\r\n this.attrs.x1 += difX\r\n this.attrs.y2 += difY / (Math.abs(this.coefficients.min) + 1)\r\n break\r\n case 'minCoefficient_2':\r\n this.attrs.x2 += difX\r\n this.attrs.y2 += difY / (Math.abs(this.coefficients.min) + 1)\r\n break\r\n default:\r\n break\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const maxCoefficientY = this.coefficients.max > 1 && this.getMaxCoefficientUnscaledY()\r\n const minCoefficientY = this.coefficients.min < 0 && this.getMinCoefficientUnscaledY()\r\n const left = Math.min(this.attrs.x1, this.attrs.x2)\r\n const right = Math.max(this.attrs.x1, this.attrs.x2)\r\n const allYValues = [this.attrs.y1, this.attrs.y2, maxCoefficientY, minCoefficientY].filter((item) => item !== false)\r\n const top = Math.min(...allYValues)\r\n const bottom = Math.max(...allYValues)\r\n\r\n if (left < area.x && area.x < right && top < area.y && area.y < bottom) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n\r\n getEdgeXYValues() {\r\n this.edgeXYValues = super.getEdgeXYValues()\r\n\r\n // Because minY, maxY can go outside of control points boundaries [0,1] we need to compensate\r\n // for that in getEdgeXYValues(), otherwise getIsInChartView() hide drawings sooner than it should\r\n const min = this.getMinCoefficientUnscaledY()\r\n const max = this.getMaxCoefficientUnscaledY()\r\n\r\n if (!isNaN(min) && !isNaN(max)) {\r\n this.edgeXYValues.minY = Math.min(min, max)\r\n this.edgeXYValues.maxY = Math.max(min, max)\r\n }\r\n\r\n return this.edgeXYValues\r\n }\r\n}\r\n\r\nFibonacciRetracements.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'line', name: 'border' },\r\n { type: 'string', name: 'coefficients', label: 'Coefficients' },\r\n ],\r\n}\r\n\r\nexport default FibonacciRetracements\r\n","import { Maybe, RequireByKey, ResizeByThumbFuncProps } from '../../types/shared'\r\nimport { CanvasElementType, TextBaseline } from '../constants/common'\r\nimport math from '../helpers/math'\r\nimport Chart from '../models/chart'\r\nimport PaneModel from '../models/pane'\r\nimport ScaledLine, { IScaledLineAttrs } from './scaled_line'\r\nimport Text from './text'\r\n\r\nconst DEFAULT_DECIMAL_PLACES = 2\r\n\r\nclass HorizontalLine extends ScaledLine {\r\n static type = CanvasElementType.horizontalLine\r\n\r\n name = 'Horizontal line'\r\n decimalPlaces = DEFAULT_DECIMAL_PLACES\r\n declare scaled: Pick\r\n declare model: PaneModel\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n\r\n this.updateDecimalPlaces()\r\n\r\n if (this.attrs.y1) {\r\n this.attrs.y1 = Number(math.round({ value: this.attrs.y1, overridePlaces: this.decimalPlaces }))\r\n }\r\n if (this.modalConfig) {\r\n const step = `0.${'0'.repeat(this.decimalPlaces - 1)}1`\r\n this.modalConfig.inputs[1] = {\r\n ...this.modalConfig.inputs[1],\r\n step,\r\n min: Number(step),\r\n }\r\n }\r\n this.renderContent = this.renderContent.bind(this)\r\n this._thumbs = []\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n updateDecimalPlaces() {\r\n const quote = this.model.chart().quote()\r\n this.decimalPlaces = quote\r\n ? math.getInstrumentDecimalPlaces({\r\n instrument: quote.instrument,\r\n value: quote.lastClose,\r\n })\r\n : DEFAULT_DECIMAL_PLACES\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n this.attrs.y2 = this.attrs.y1\r\n // mixing scaled and unscaled values, do not copy paste as solution\r\n this.attrs.x1 = ChartSettings.left.width * -1\r\n this.attrs.x2 =\r\n this.model\r\n .chart()\r\n .quote()\r\n .getBarIndex(this.model.chart().quote().close.length - 1) + this.model.chart().width\r\n super.renderContent(context)\r\n }\r\n\r\n renderLabels(context: CanvasRenderingContext2D) {\r\n if (this.attrs.y1) {\r\n this.updateDecimalPlaces()\r\n const { ChartSettings, IndicatorSettings } = this.getChartLayoutSettings()\r\n const isIndicatorPane = this.model\r\n .elements()\r\n .all()\r\n .some((element) => element.isIndicator())\r\n const settings = isIndicatorPane ? IndicatorSettings : ChartSettings\r\n context.translate(this.model.chart().width - settings.right.width, settings.top.height)\r\n new Text(\r\n {\r\n x: 6,\r\n y: this.scaled.y1,\r\n font: { size: 8, style: 'bold' },\r\n lineHeight: 8,\r\n padding: {\r\n top: 2,\r\n right: 2,\r\n bottom: 2,\r\n left: 2,\r\n },\r\n fillStyle: '#fff',\r\n background: '#000',\r\n textBaseline: TextBaseline.middle,\r\n text: this.attrs.y1.toFixed(this.decimalPlaces).toString(),\r\n },\r\n this.model\r\n ).render(context)\r\n }\r\n }\r\n\r\n moveBy(x: Maybe, y: number) {\r\n this.attrs.y1 += y\r\n }\r\n\r\n resize({ difY }: RequireByKey) {\r\n this.moveBy(0, difY)\r\n }\r\n\r\n getIsInChartView(chart: Chart) {\r\n return super.getIsInChartView(chart, { omitX: true })\r\n }\r\n}\r\n\r\nHorizontalLine.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'line', name: 'border' },\r\n { type: 'number', name: 'y1', label: 'Price', allowDecimal: true },\r\n ],\r\n}\r\n\r\nexport default HorizontalLine\r\n","import { PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport { getRoundedObject, getXYOffsetFromLine } from '../controllers/renderUtils'\r\nimport math from '../helpers/math'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Thumb from './thumb'\r\n\r\ninterface ILineAttrs {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n dashLength: number\r\n lineWidth: number\r\n strokeStyle: string\r\n}\r\n\r\nclass Line extends Element {\r\n static type = CanvasElementType.line\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.render = this.render.bind(this)\r\n this.resize = this.resize.bind(this)\r\n this._thumbs = [\r\n new Thumb(\r\n 'l',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'r',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n }\r\n\r\n getDefaults() {\r\n return {\r\n lineWidth: 1,\r\n strokeStyle: this.getChartLayoutSettings().ElementSettings.Colors.line,\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n render(context: CanvasRenderingContext2D) {\r\n const { x1, y1, x2, y2, lineWidth } = this.attrs\r\n const roundedXY = getRoundedObject({ x1, y1, x2, y2 })\r\n const translateXY = getXYOffsetFromLine({ lineWidth, ...roundedXY })\r\n\r\n context.translate(translateXY.x, translateXY.y)\r\n context.beginPath()\r\n context.set('lineWidth', this.attrs.lineWidth)\r\n context.set('strokeStyle', this.attrs.strokeStyle)\r\n\r\n context.moveTo(roundedXY.x1, roundedXY.y1)\r\n if (this.attrs.dashLength) {\r\n context.setLineDash([this.attrs.dashLength])\r\n }\r\n context.lineTo(roundedXY.x2, roundedXY.y2)\r\n context.stroke()\r\n if (this.attrs.dashLength) {\r\n context.setLineDash([])\r\n }\r\n context.translate(translateXY.x * -1, translateXY.y * -1)\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.x2 += x\r\n this.attrs.y1 += y\r\n this.attrs.y2 += y\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n if (type === 'l') {\r\n this.attrs.x1 += difX\r\n this.attrs.y1 += difY\r\n } else {\r\n this.attrs.x2 += difX\r\n this.attrs.y2 += difY\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n if (math.distanceToSegment(area, this.attrs) <= 10) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n}\r\n\r\nexport default Line\r\n","import { PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType, TextBaseline } from '../constants/common'\r\nimport { getRoundedObject } from '../controllers/renderUtils'\r\nimport PaneModel from '../models/pane'\r\nimport { numberToStringWithUnitsSuffix } from '../utils'\r\nimport { getRoundedString } from '../utils/helpers'\r\nimport Element from './element'\r\nimport Text, { ITextAttrs } from './text'\r\nimport Thumb from './thumb'\r\n\r\ninterface Coordinates {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n}\r\n\r\nexport interface IMeasureAttrs extends Coordinates {\r\n fill: string\r\n}\r\n\r\nclass Measure extends Element {\r\n static type = CanvasElementType.measure\r\n\r\n name = 'Measure'\r\n declare scaled: Pick\r\n\r\n x1Dif: number\r\n x2Dif: number\r\n startingX1: number\r\n startingX2: number\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n this._thumbs = [\r\n new Thumb(\r\n 'tl',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'br',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n this.x1Dif = this.x2Dif = 0\r\n\r\n this.startingX1 = this.attrs.x1\r\n this.startingX2 = this.attrs.x2\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n getVolumeSumString = () => {\r\n const { volume, barIndex }: { volume: number[]; barIndex: number[] } = this.model.chart().quote()\r\n const roundedX1 = Math.round(this.attrs.x1)\r\n const roundedX2 = Math.round(this.attrs.x2)\r\n // min/max values are offset by 1 so there's no value on such index\r\n // and at the same time it won't iterate over unlimited number of nonexisting indexes\r\n const minIndexLimit = barIndex[0] - 1\r\n const maxIndexLimit = barIndex[barIndex.length - 1] + 1\r\n const volMinIndex = Math.min(Math.max(Math.min(roundedX1, roundedX2), minIndexLimit), maxIndexLimit)\r\n const volMaxIndex = Math.min(Math.max(Math.max(roundedX1, roundedX2), minIndexLimit), maxIndexLimit)\r\n\r\n let volumeSum = 0\r\n for (let i = volMinIndex; i <= volMaxIndex; i++) {\r\n const volumeIndex = barIndex.indexOf(i)\r\n if (volumeIndex >= 0) {\r\n volumeSum += volume[volumeIndex]\r\n }\r\n }\r\n\r\n return `Vol ${numberToStringWithUnitsSuffix(volumeSum)}`\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n context.set('fillStyle', this.attrs.fill)\r\n const { x1, x2, y1, y2 } = this.scaled\r\n const roundedXY = getRoundedObject({ x1, x2, y1, y2 })\r\n\r\n const width = roundedXY.x2 - roundedXY.x1\r\n const height = roundedXY.y2 - roundedXY.y1\r\n context.fillRect(x1, roundedXY.y1, width, height)\r\n\r\n const priceDif = this.attrs.y2 - this.attrs.y1\r\n const percentage = (100 / this.attrs.y1) * priceDif\r\n const heightStr = `${priceDif.toFixed(2)} (${percentage.toFixed(2)}%)`\r\n\r\n const text = new Text(\r\n {\r\n text: `${getRoundedString({ number: Math.abs(this.attrs.x2 - this.attrs.x1), numOfDecimalPlaces: 2 })} bars`,\r\n fillStyle: '#333',\r\n font: { size: 10, family: 'Arial', weight: 'bold' },\r\n textBaseline: TextBaseline.middle,\r\n },\r\n this.model\r\n )\r\n const baseX = x1 + width / 2\r\n const baseY = roundedXY.y1 + height / 2\r\n let textWidth = text.measure(context)\r\n text.set({\r\n x: baseX - textWidth / 2,\r\n y: baseY - text.getHeight(),\r\n } as Partial)\r\n text.render(context)\r\n\r\n text.set({ text: heightStr })\r\n textWidth = text.measure(context)\r\n text.set({\r\n x: baseX - textWidth / 2,\r\n y: baseY,\r\n } as Partial)\r\n text.render(context)\r\n\r\n text.set({ text: this.getVolumeSumString() })\r\n textWidth = text.measure(context)\r\n text.set({\r\n x: baseX - textWidth / 2,\r\n y: baseY + text.getHeight(),\r\n } as Partial)\r\n text.render(context)\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n addToCoordinates(difs: Partial) {\r\n this.attrs.y1 += difs.y1 || 0\r\n this.attrs.y2 += difs.y2 || 0\r\n\r\n this.x1Dif += difs.x1 || 0\r\n this.x2Dif += difs.x2 || 0\r\n\r\n // The reason for adding +1 is to \"ceil\" the number when moving to the left (decreasing bar index)\r\n const newX1 = ~~(this.startingX1 + this.x1Dif) + (this.x1Dif < 0 ? 1 : 0)\r\n if (~~this.attrs.x1 - newX1 !== 0) {\r\n this.attrs.x1 = newX1\r\n }\r\n const newX2 = ~~(this.startingX2 + this.x2Dif) + (this.x2Dif < 0 ? 1 : 0)\r\n if (~~this.attrs.x2 - newX2 !== 0) {\r\n this.attrs.x2 = newX2\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n return this.addToCoordinates({\r\n x1: x,\r\n y1: y,\r\n x2: x,\r\n y2: y,\r\n })\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n if (type === 'tl') {\r\n this.addToCoordinates({ x1: difX, y1: difY })\r\n } else {\r\n this.addToCoordinates({ x2: difX, y2: difY })\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const x1 = Math.round(this.attrs.x1)\r\n const x2 = Math.round(this.attrs.x2)\r\n\r\n const left = Math.min(x1, x2)\r\n const right = Math.max(x1, x2)\r\n const top = Math.min(this.attrs.y1, this.attrs.y2)\r\n const bottom = Math.max(this.attrs.y1, this.attrs.y2)\r\n if (left < area.x && area.x < right && top < area.y && area.y < bottom) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n\r\n onMouseDown(paneArea: PaneArea) {\r\n super.onMouseDown(paneArea)\r\n this.startingX1 = this.attrs.x1\r\n this.startingX2 = this.attrs.x2\r\n }\r\n\r\n onMouseUp(paneArea?: PaneArea) {\r\n super.onMouseUp(paneArea)\r\n this.x1Dif = this.x2Dif = 0\r\n }\r\n}\r\n\r\nMeasure.prototype.defaults = { fill: 'rgba(180,220,255,0.8)' }\r\n\r\nMeasure.prototype.modalConfig = {\r\n inputs: [{ type: 'background', name: 'fill' }],\r\n}\r\n\r\nexport default Measure\r\n","import { Point } from '../../../types/shared'\r\nimport { getRoundedObject } from '../../controllers/renderUtils'\r\nimport math from '../../helpers/math'\r\nimport PaneModel from '../../models/pane'\r\nimport { isInRange } from '../../utils/helpers'\r\nimport { ITrendAttrs } from './pitchfork_v1'\r\n\r\ninterface IGetEdgeIntersectionPointArguments {\r\n sides: { x: number; y: number }[][]\r\n rayOrigin: Point\r\n rayDirection: Point\r\n}\r\n\r\nexport const getEdgeIntersectionPoint = ({ sides, rayOrigin, rayDirection }: IGetEdgeIntersectionPointArguments) => {\r\n if (rayOrigin.x === rayDirection.x && rayOrigin.y === rayDirection.y) return rayDirection\r\n\r\n let intersection = rayDirection\r\n let intersectionDistance = 0\r\n for (let index = 0; index < sides.length; index++) {\r\n const rayToLineIntersection = math.getRayToLineSegmentIntersection(\r\n rayOrigin,\r\n rayDirection,\r\n sides[index][0],\r\n sides[index][1]\r\n )\r\n if (rayToLineIntersection) {\r\n const distance = math.distance(rayToLineIntersection, rayOrigin)\r\n if (distance > intersectionDistance && isInRange({ value: distance })) {\r\n intersectionDistance = distance\r\n intersection = { x: rayToLineIntersection.x, y: rayToLineIntersection.y }\r\n }\r\n }\r\n }\r\n\r\n return intersection\r\n}\r\n\r\nexport const getChartVisibleAreaBoundaries = (paneModel: PaneModel) => {\r\n const { left, right, top, bottom } = paneModel.getChartLayoutSettings().ChartSettings\r\n const { leftOffset, width } = paneModel.chart()\r\n\r\n const chartVisibleAreaLeftX = Math.abs(leftOffset)\r\n const chartVisibleAreaRightX = chartVisibleAreaLeftX + width - left.width - right.width\r\n const chartVisibleAreaTopY = 0\r\n const chartVisibleAreaBottomY = paneModel.height - top.height - bottom.height\r\n\r\n const chartVisibleAreaTopLeftPoint = {\r\n x: chartVisibleAreaLeftX,\r\n y: chartVisibleAreaTopY,\r\n }\r\n const chartVisibleAreaTopRightPoint = {\r\n x: chartVisibleAreaRightX,\r\n y: chartVisibleAreaTopY,\r\n }\r\n const chartVisibleAreaBottomLeftPoint = {\r\n x: chartVisibleAreaLeftX,\r\n y: chartVisibleAreaBottomY,\r\n }\r\n const chartVisibleAreaBottomRightPoint = {\r\n x: chartVisibleAreaRightX,\r\n y: chartVisibleAreaBottomY,\r\n }\r\n const topSide = [chartVisibleAreaTopLeftPoint, chartVisibleAreaTopRightPoint]\r\n const rightSide = [chartVisibleAreaTopRightPoint, chartVisibleAreaBottomRightPoint]\r\n const bottomSide = [chartVisibleAreaBottomLeftPoint, chartVisibleAreaBottomRightPoint]\r\n const leftSide = [chartVisibleAreaTopLeftPoint, chartVisibleAreaBottomLeftPoint]\r\n\r\n const sides = [topSide, rightSide, bottomSide, leftSide]\r\n\r\n return sides\r\n}\r\n\r\ninterface IGetPitchforkCoordinates {\r\n paneModel: PaneModel\r\n rayOrigin: Point\r\n rayDirectionControlPoint1: Point\r\n rayDirectionControlPoint2?: Point\r\n trend1: ITrendAttrs\r\n trend2: ITrendAttrs\r\n}\r\n\r\ninterface ILineSegment {\r\n P1: Point\r\n P2: Point\r\n}\r\n\r\ninterface ICoordinates {\r\n medianRay: ILineSegment\r\n trend1Ray1: ILineSegment | undefined\r\n trend1Ray2: ILineSegment | undefined\r\n trend2Ray1: ILineSegment | undefined\r\n trend2Ray2: ILineSegment | undefined\r\n}\r\n\r\nexport const getPitchforkCoordinates = ({\r\n paneModel,\r\n rayOrigin,\r\n rayDirectionControlPoint1,\r\n rayDirectionControlPoint2,\r\n trend1,\r\n trend2,\r\n}: IGetPitchforkCoordinates) => {\r\n const sides = getChartVisibleAreaBoundaries(paneModel)\r\n\r\n const coordinates: ICoordinates = {\r\n medianRay: { P1: rayOrigin, P2: rayDirectionControlPoint1 },\r\n trend1Ray1: undefined,\r\n trend2Ray1: undefined,\r\n trend1Ray2: undefined,\r\n trend2Ray2: undefined,\r\n }\r\n\r\n // If rayDirectionControlPoint2 doesn't exist return only medianRay with rayDirectionControlPoint1 as rayDirection\r\n if (!rayDirectionControlPoint2) {\r\n coordinates.medianRay = {\r\n P1: getRoundedObject(rayOrigin),\r\n P2: getRoundedObject(\r\n getEdgeIntersectionPoint({\r\n sides,\r\n rayOrigin,\r\n rayDirection: rayDirectionControlPoint1,\r\n })\r\n ),\r\n }\r\n return coordinates\r\n }\r\n\r\n const medianRayDirectionPoint = math.getMiddlePointOnLineSegment(rayDirectionControlPoint1, rayDirectionControlPoint2)\r\n const rayOriginToRayDirectionVector = {\r\n x: medianRayDirectionPoint.x - rayOrigin.x,\r\n y: medianRayDirectionPoint.y - rayOrigin.y,\r\n }\r\n\r\n const rayDirectionControlPoint1ToPoint2Vector = {\r\n x: rayDirectionControlPoint1.x - rayDirectionControlPoint2.x,\r\n y: rayDirectionControlPoint1.y - rayDirectionControlPoint2.y,\r\n }\r\n\r\n const normalizedRayDirectionControlPoint1ToPoint2Vector = math.normalizeVector(\r\n rayDirectionControlPoint1ToPoint2Vector\r\n )\r\n\r\n const medianRayDirectionPointToRayDirectionControlPoint1Distance = math.distance(\r\n medianRayDirectionPoint,\r\n rayDirectionControlPoint1\r\n )\r\n\r\n coordinates.medianRay = {\r\n P1: getRoundedObject(rayOrigin),\r\n P2: getRoundedObject(\r\n getEdgeIntersectionPoint({\r\n sides,\r\n rayOrigin,\r\n rayDirection: medianRayDirectionPoint,\r\n })\r\n ),\r\n }\r\n if (trend1.active) {\r\n const trend1Ray = getTrendRayCoordinates({\r\n trend: trend1.trend,\r\n medianToControlPointDistance: medianRayDirectionPointToRayDirectionControlPoint1Distance,\r\n normalizedControlToControlPointVector: normalizedRayDirectionControlPoint1ToPoint2Vector,\r\n rayOriginToRayDirectionVector,\r\n medianRayDirectionPoint,\r\n sides,\r\n })\r\n\r\n coordinates.trend1Ray1 = trend1Ray.trendRay1\r\n coordinates.trend1Ray2 = trend1Ray.trendRay2\r\n }\r\n if (trend2.active) {\r\n const trend2Ray = getTrendRayCoordinates({\r\n trend: trend2.trend,\r\n medianToControlPointDistance: medianRayDirectionPointToRayDirectionControlPoint1Distance,\r\n normalizedControlToControlPointVector: normalizedRayDirectionControlPoint1ToPoint2Vector,\r\n rayOriginToRayDirectionVector,\r\n medianRayDirectionPoint,\r\n sides,\r\n })\r\n\r\n coordinates.trend2Ray1 = trend2Ray.trendRay1\r\n coordinates.trend2Ray2 = trend2Ray.trendRay2\r\n }\r\n\r\n return coordinates\r\n}\r\n\r\ninterface IGetTrendRayCoordinates {\r\n trend: number\r\n medianToControlPointDistance: number\r\n normalizedControlToControlPointVector: Point\r\n rayOriginToRayDirectionVector: Point\r\n medianRayDirectionPoint: Point\r\n sides: Point[][]\r\n}\r\n\r\nconst getTrendRayCoordinates = ({\r\n trend,\r\n medianToControlPointDistance,\r\n normalizedControlToControlPointVector,\r\n rayOriginToRayDirectionVector,\r\n medianRayDirectionPoint,\r\n sides,\r\n}: IGetTrendRayCoordinates) => {\r\n const medianToTrendLineDistance = medianToControlPointDistance * trend\r\n\r\n const trendRayPoint1Origin = math.addPoints(\r\n medianRayDirectionPoint,\r\n math.multiplyVectorByScalar(normalizedControlToControlPointVector, medianToTrendLineDistance)\r\n )\r\n const trendPoint2RayOriginPoint2 = math.subtractPoints(\r\n medianRayDirectionPoint,\r\n math.multiplyVectorByScalar(normalizedControlToControlPointVector, medianToTrendLineDistance)\r\n )\r\n\r\n const trendRayPoint1DirectionPoint = {\r\n x: trendRayPoint1Origin.x + rayOriginToRayDirectionVector.x,\r\n y: trendRayPoint1Origin.y + rayOriginToRayDirectionVector.y,\r\n }\r\n const trendPoint2RayDirectionPoint = {\r\n x: trendPoint2RayOriginPoint2.x + rayOriginToRayDirectionVector.x,\r\n y: trendPoint2RayOriginPoint2.y + rayOriginToRayDirectionVector.y,\r\n }\r\n\r\n return {\r\n trendRay1: {\r\n P1: getRoundedObject(trendRayPoint1Origin),\r\n P2: getRoundedObject(\r\n getEdgeIntersectionPoint({\r\n sides,\r\n rayOrigin: trendRayPoint1Origin,\r\n rayDirection: trendRayPoint1DirectionPoint,\r\n })\r\n ),\r\n },\r\n trendRay2: {\r\n P1: getRoundedObject(trendPoint2RayOriginPoint2),\r\n P2: getRoundedObject(\r\n getEdgeIntersectionPoint({\r\n sides,\r\n rayOrigin: trendPoint2RayOriginPoint2,\r\n rayDirection: trendPoint2RayDirectionPoint,\r\n })\r\n ),\r\n },\r\n }\r\n}\r\n","import { PaneArea, ResizeByThumbWithTypeAndDifs } from '../../../types/shared'\r\nimport { CanvasElementType } from '../../constants/common'\r\nimport { getOffsetFromLineWidth } from '../../controllers/renderUtils'\r\nimport math from '../../helpers/math'\r\nimport Chart from '../../models/chart'\r\nimport PaneModel from '../../models/pane'\r\nimport { getHEXWithSpecificAplha } from '../../utils/colors'\r\nimport Element from '../element'\r\nimport Thumb from '../thumb'\r\nimport { getPitchforkCoordinates } from './pitchfork_utils'\r\n\r\nexport interface ITrendAttrs {\r\n active: boolean\r\n trend: number\r\n color: string\r\n}\r\n\r\nexport interface IPitchforkAttrs {\r\n x1: number\r\n y1: number\r\n x2: number\r\n y2: number\r\n x3: number\r\n y3: number\r\n median: { color: string; width: number }\r\n trend1: ITrendAttrs\r\n trend2: ITrendAttrs\r\n}\r\n\r\nclass Pitchfork extends Element {\r\n static type = CanvasElementType.pitchforkV1\r\n\r\n declare scaled: Pick\r\n name = 'Pitchfork'\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n\r\n this.resize = this.resize.bind(this)\r\n\r\n this._thumbs = [\r\n new Thumb(\r\n 'medianRayOrigin',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'rayDirectionControlPoint1',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'rayDirectionControlPoint2',\r\n () => this.attrs.x3,\r\n () => this.attrs.y3,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getDefaults() {\r\n return {\r\n median: { color: '#e72f2f', width: 1 },\r\n trend1: {\r\n color: '#004ad31c',\r\n active: true,\r\n trend: 1,\r\n },\r\n trend2: {\r\n color: '#00ca4e1f',\r\n active: true,\r\n trend: 0.5,\r\n },\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2', 'x3'], y: ['y1', 'y2', 'y3'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { x1, x2, x3, y1, y2, y3 } = this.scaled\r\n\r\n const offset = getOffsetFromLineWidth(this.attrs.median.width)\r\n context.translate(offset, offset)\r\n\r\n const { medianRay, trend1Ray1, trend1Ray2, trend2Ray1, trend2Ray2 } = getPitchforkCoordinates({\r\n paneModel: this.model,\r\n rayOrigin: { x: x1, y: y1 },\r\n rayDirectionControlPoint1: { x: x2, y: y2 },\r\n rayDirectionControlPoint2: Number.isNaN(x3) || Number.isNaN(y3) ? undefined : { x: x3, y: y3 },\r\n trend1: this.attrs.trend1,\r\n trend2: this.attrs.trend2,\r\n })\r\n\r\n context.set('lineWidth', this.attrs.median.width)\r\n\r\n const trendLines = [\r\n { trend: this.attrs.trend1, line1: trend1Ray1, line2: trend1Ray2 },\r\n { trend: this.attrs.trend2, line1: trend2Ray1, line2: trend2Ray2 },\r\n ].sort((a, b) => {\r\n if (Math.abs(a.trend.trend) > Math.abs(b.trend.trend)) {\r\n return -1\r\n }\r\n if (Math.abs(a.trend.trend) < Math.abs(b.trend.trend)) {\r\n return 1\r\n }\r\n return 0\r\n })\r\n\r\n // Draw trend lines and fill\r\n trendLines.forEach((trendLine, trendLineIndex) => {\r\n if (trendLine.line1 && trendLine.line2) {\r\n const { line1, line2 } = trendLine\r\n const solidTrendColor = getHEXWithSpecificAplha(trendLine.trend.color)\r\n const nextTrendLine = trendLines[trendLineIndex + 1]\r\n\r\n context.beginPath()\r\n context.moveTo(line1.P1.x, line1.P1.y)\r\n context.lineTo(line1.P2.x, line1.P2.y)\r\n if (trendLineIndex !== trendLines.length - 1 && nextTrendLine.line1 && nextTrendLine.line2) {\r\n context.lineTo(nextTrendLine.line1.P2.x, nextTrendLine.line1.P2.y)\r\n context.lineTo(nextTrendLine.line1.P1.x, nextTrendLine.line1.P1.y)\r\n context.moveTo(nextTrendLine.line2.P1.x, nextTrendLine.line2.P1.y)\r\n context.lineTo(nextTrendLine.line2.P2.x, nextTrendLine.line2.P2.y)\r\n }\r\n context.lineTo(line2.P2.x, line2.P2.y)\r\n context.lineTo(line2.P1.x, line2.P1.y)\r\n context.closePath()\r\n context.set('fillStyle', trendLine.trend.color)\r\n context.fill()\r\n\r\n context.beginPath()\r\n context.moveTo(line1.P1.x, line1.P1.y)\r\n context.lineTo(line1.P2.x, line1.P2.y)\r\n context.moveTo(line2.P1.x, line2.P1.y)\r\n context.lineTo(line2.P2.x, line2.P2.y)\r\n context.set('strokeStyle', solidTrendColor)\r\n context.stroke()\r\n }\r\n })\r\n\r\n // Draw median ray line\r\n context.beginPath()\r\n context.moveTo(medianRay.P1.x, medianRay.P1.y)\r\n context.lineTo(medianRay.P2.x, medianRay.P2.y)\r\n\r\n // Draw line between outer trend lines origin points or if smaller than 1 between direction control points\r\n const outerTrendLines =\r\n trendLines.filter(\r\n (item) => item.line1 && item.line2 && item.trend.active && Math.abs(item.trend.trend) >= 1\r\n )[0] ?? {}\r\n\r\n if (outerTrendLines.line1 && outerTrendLines.line2) {\r\n context.moveTo(outerTrendLines.line1.P1.x, outerTrendLines.line1.P1.y)\r\n context.lineTo(outerTrendLines.line2.P1.x, outerTrendLines.line2.P1.y)\r\n } else if (!Number.isNaN(x3) && !Number.isNaN(y3)) {\r\n context.moveTo(x2, y2)\r\n context.lineTo(x3, y3)\r\n }\r\n\r\n context.set('strokeStyle', this.attrs.median.color)\r\n context.stroke()\r\n\r\n context.translate(offset * -1, offset * -1)\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.y1 += y\r\n this.attrs.x2 += x\r\n this.attrs.y2 += y\r\n this.attrs.x3 += x\r\n this.attrs.y3 += y\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n switch (type) {\r\n case 'medianRayOrigin':\r\n this.attrs.x1 += difX\r\n this.attrs.y1 += difY\r\n break\r\n case 'rayDirectionControlPoint1':\r\n this.attrs.x2 += difX\r\n this.attrs.y2 += difY\r\n break\r\n case 'rayDirectionControlPoint2':\r\n this.attrs.x3 += difX\r\n this.attrs.y3 += difY\r\n break\r\n default:\r\n break\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const { x1, x2, x3, y1, y2, y3 } = this.scaled\r\n const { medianRay, trend1Ray1, trend1Ray2, trend2Ray1, trend2Ray2 } = getPitchforkCoordinates({\r\n paneModel: this.model,\r\n rayOrigin: { x: x1, y: y1 },\r\n rayDirectionControlPoint1: { x: x2, y: y2 },\r\n rayDirectionControlPoint2: Number.isNaN(x3) || Number.isNaN(y3) ? undefined : { x: x3, y: y3 },\r\n trend1: this.attrs.trend1,\r\n trend2: this.attrs.trend2,\r\n })\r\n const outerTrendLines =\r\n Math.abs(this.attrs.trend1.trend) > Math.abs(this.attrs.trend2.trend)\r\n ? { line1: trend1Ray1, line2: trend1Ray2 }\r\n : { line1: trend2Ray1, line2: trend2Ray2 }\r\n\r\n if (\r\n math.distanceToSegment(area.scaled, {\r\n x1: medianRay.P1.x,\r\n y1: medianRay.P1.y,\r\n x2: medianRay.P2.x,\r\n y2: medianRay.P2.y,\r\n }) <= 10\r\n ) {\r\n // cursor is near median ray\r\n return true\r\n } else if (\r\n !Number.isNaN(x3) &&\r\n !Number.isNaN(y3) &&\r\n math.distanceToSegment(area.scaled, {\r\n x1: x2,\r\n y1: y2,\r\n x2: x3,\r\n y2: y3,\r\n }) <= 10\r\n ) {\r\n // cursor is near line connecting direction control points\r\n return true\r\n } else if (\r\n outerTrendLines.line1 &&\r\n outerTrendLines.line2 &&\r\n math.pointInPolygon(area.scaled, [\r\n outerTrendLines.line1.P1,\r\n outerTrendLines.line1.P2,\r\n outerTrendLines.line2.P2,\r\n outerTrendLines.line2.P1,\r\n ])\r\n ) {\r\n // cursor is on polygon created by outer trend lines\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n\r\n getIsInChartView(_: Chart) {\r\n return true\r\n }\r\n}\r\n\r\nPitchfork.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'line', name: 'median' },\r\n { type: 'trend', name: 'trend1' },\r\n { type: 'trend', name: 'trend2' },\r\n ],\r\n}\r\n\r\nexport default Pitchfork\r\n","import { DrawingBorder, PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport { getOffsetFromLineWidth } from '../controllers/renderUtils'\r\nimport math from '../helpers/math'\r\nimport PaneModel from '../models/pane'\r\nimport Element, { EdgeValues } from './element'\r\nimport Thumb from './thumb'\r\n\r\ntype Points = Array<{ x: number; y: number }>\r\n\r\nexport interface IPolygonAttrs {\r\n points: Points\r\n fill: string\r\n border: DrawingBorder\r\n positionPointsTimestamps?: Points\r\n}\r\n\r\nclass Polygon extends Element {\r\n static type = CanvasElementType.polygon\r\n\r\n name = 'Polygon'\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n this.attrs.fill = this.attrs.fill || 'rgba(50, 60, 70, 0.8)'\r\n }\r\n\r\n getDefaults() {\r\n const { ElementSettings } = this.getChartLayoutSettings()\r\n return {\r\n fill: ElementSettings.defaultFill,\r\n border: {\r\n width: 1,\r\n color: ElementSettings.Colors.border,\r\n },\r\n } as Partial\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n context.set('fillStyle', this.attrs.fill)\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n\r\n const offset = getOffsetFromLineWidth(this.attrs.border.width)\r\n context.translate(offset, offset)\r\n\r\n const { points } = this.attrs\r\n context.beginPath()\r\n context.moveTo(this.fx(points[0].x), this.fy(points[0].y))\r\n for (const p of points.slice(1)) {\r\n context.lineTo(this.fx(p.x), this.fy(p.y))\r\n }\r\n\r\n if (this.isPolygon()) {\r\n context.closePath()\r\n context.fill()\r\n }\r\n context.translate(offset * -1, offset * -1)\r\n if ((this.attrs.border != null ? this.attrs.border.width : undefined) !== 0) {\r\n context.stroke()\r\n }\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n getThumbs() {\r\n return this.attrs.points.map(\r\n (point, index) =>\r\n new Thumb(\r\n `${index}`,\r\n () => point.x,\r\n () => point.y,\r\n this.resize,\r\n this.model\r\n )\r\n )\r\n }\r\n\r\n cachePointPositionTimestamp = () => {\r\n const quote = this.model?.chart()?.quote()\r\n if (quote) {\r\n const positionPointsTimestamps = this.attrs.points.map((point) => ({\r\n ...point,\r\n x: quote.getTimestampFomPositionX(point.x),\r\n }))\r\n\r\n this.set({ positionPointsTimestamps } as Partial)\r\n }\r\n }\r\n\r\n updateScales() {\r\n const quote = this.model.chart().quote()\r\n const { positionPointsTimestamps } = this.attrs\r\n if (!quote || !positionPointsTimestamps) {\r\n // positionWavesTimestamps check is temporary to prevent app from crashing\r\n // caused by corrupted drawings - https://github.com/finvizhq/charts/pull/1386/files\r\n return\r\n }\r\n const points = positionPointsTimestamps.map((point) => ({\r\n ...point,\r\n x: quote.getPositionXFromTimestamp(point.x),\r\n }))\r\n this.set({ points } as Partial)\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n for (const point of this.attrs.points) {\r\n point.x += x\r\n point.y += y\r\n }\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n const last = this.attrs.points.length - 1\r\n if (this.isPolygon() && (+type === 0 || +type === last)) {\r\n this.attrs.points[0].x += difX\r\n this.attrs.points[0].y += difY\r\n this.attrs.points[last].x += difX\r\n this.attrs.points[last].y += difY\r\n } else {\r\n this.attrs.points[+type].x += difX\r\n this.attrs.points[+type].y += difY\r\n }\r\n }\r\n\r\n isPolygon() {\r\n return (\r\n this.attrs.points[0].x === this.attrs.points.last()?.x && this.attrs.points[0].y === this.attrs.points.last()?.y\r\n )\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const scaledPoints = this.attrs.points.map((p) => ({\r\n x: this.fx(p.x),\r\n y: this.fy(p.y),\r\n }))\r\n if (this.isPolygon()) {\r\n if (math.pointInPolygon(area.scaled, scaledPoints)) {\r\n return true\r\n }\r\n } else {\r\n for (let i = 0; i < scaledPoints.length - 1; i++) {\r\n if (\r\n math.distanceToSegment(area.scaled, {\r\n x1: scaledPoints[i].x,\r\n y1: scaledPoints[i].y,\r\n x2: scaledPoints[i + 1].x,\r\n y2: scaledPoints[i + 1].y,\r\n }) <= 10\r\n ) {\r\n return true\r\n }\r\n }\r\n }\r\n\r\n return super.isInArea(area)\r\n }\r\n\r\n getAutosaveOmittedProperties() {\r\n return ['points']\r\n }\r\n\r\n getEdgeXYValues() {\r\n if (this.edgeXYValues === null) {\r\n const edgeXYValues = {} as EdgeValues\r\n this.attrs.points.forEach(({ x, y }) => {\r\n const xPoint = x\r\n const yPoint = y\r\n edgeXYValues.minX = Math.min(xPoint, edgeXYValues.minX ?? xPoint)\r\n edgeXYValues.minY = Math.min(yPoint, edgeXYValues.minY ?? yPoint)\r\n edgeXYValues.maxX = Math.max(xPoint, edgeXYValues.maxX ?? xPoint)\r\n edgeXYValues.maxY = Math.max(yPoint, edgeXYValues.maxY ?? yPoint)\r\n })\r\n\r\n this.edgeXYValues = edgeXYValues\r\n }\r\n\r\n return this.edgeXYValues\r\n }\r\n}\r\n\r\nPolygon.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'background', name: 'fill' },\r\n { type: 'border', name: 'border', min: 1, default: {} },\r\n ],\r\n}\r\n\r\nexport default Polygon\r\n","import { PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType, TextBaseline } from '../constants/common'\r\nimport { getRoundedObject } from '../controllers/renderUtils'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Text, { ITextAttrs } from './text'\r\nimport Thumb from './thumb'\r\n\r\ninterface Coordinates {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n}\r\n\r\nexport interface IPositionAttrs extends Coordinates {\r\n targetColor: string\r\n stopColor: string\r\n targetY: number\r\n centerY: number\r\n stopY: number\r\n}\r\n\r\nclass Position extends Element {\r\n static type = CanvasElementType.position\r\n\r\n name = 'Position'\r\n\r\n declare scaled: Pick\r\n\r\n x1Dif: number\r\n x2Dif: number\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n this._thumbs = [\r\n new Thumb(\r\n 't1',\r\n () => this.attrs.x1,\r\n () => this.attrs.targetY,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 't2',\r\n () => this.attrs.x2,\r\n () => this.attrs.targetY,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 's1',\r\n () => this.attrs.x1,\r\n () => this.attrs.stopY,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 's2',\r\n () => this.attrs.x2,\r\n () => this.attrs.stopY,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'c1',\r\n () => this.attrs.x1,\r\n () => this.attrs.centerY,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'c2',\r\n () => this.attrs.x2,\r\n () => this.attrs.centerY,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n this.x1Dif = this.x2Dif = 0\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['targetY', 'centerY', 'stopY'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { x1, x2, targetY, centerY, stopY } = this.scaled\r\n const roundedXY = getRoundedObject({ x1, x2, targetY, centerY, stopY })\r\n let sign, stopBaseline, targetBaseline\r\n const width = roundedXY.x2 - roundedXY.x1\r\n\r\n context.set('fillStyle', this.attrs.targetColor)\r\n context.fillRect(roundedXY.x1, roundedXY.targetY, width, roundedXY.centerY - roundedXY.targetY)\r\n\r\n context.set('fillStyle', this.attrs.stopColor)\r\n context.fillRect(roundedXY.x1, roundedXY.centerY, width, roundedXY.stopY - roundedXY.centerY)\r\n\r\n const targetDif = Math.abs(this.attrs.targetY - this.attrs.centerY)\r\n const targetPerc = (100 / this.attrs.centerY) * targetDif\r\n const targetStr = `Target: ${targetDif.toFixed(2)} (${targetPerc.toFixed(2)}%)`\r\n\r\n const stopDif = Math.abs(this.attrs.stopY - this.attrs.centerY)\r\n const stopPerc = (100 / this.attrs.centerY) * stopDif\r\n const stopStr = `Stop: ${stopDif.toFixed(2)} (${stopPerc.toFixed(2)}%)`\r\n\r\n if (this.attrs.targetY > this.attrs.centerY) {\r\n sign = 1\r\n targetBaseline = TextBaseline.bottom\r\n stopBaseline = TextBaseline.top\r\n } else {\r\n sign = -1\r\n targetBaseline = TextBaseline.top\r\n stopBaseline = TextBaseline.bottom\r\n }\r\n\r\n const text = new Text(\r\n {\r\n text: targetStr,\r\n fillStyle: this.getChartLayoutSettings().ElementSettings.Colors.textWithoutBackground,\r\n font: { size: 10, family: 'Arial', weight: 'bold' },\r\n y: roundedXY.targetY - sign * 4,\r\n textBaseline: targetBaseline,\r\n },\r\n this.model\r\n )\r\n let textWidth = text.measure(context)\r\n text.set({ x: roundedXY.x1 + width / 2 - textWidth / 2 } as Partial)\r\n text.render(context)\r\n\r\n text.set({\r\n text: stopStr,\r\n y: roundedXY.stopY + sign * 4,\r\n textBaseline: stopBaseline,\r\n })\r\n textWidth = text.measure(context)\r\n text.set({ x: roundedXY.x1 + width / 2 - textWidth / 2 } as Partial)\r\n text.render(context)\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n addToCoordinates(difs: Partial) {\r\n let middle, middle1, result\r\n if (difs.targetY) {\r\n result = this.attrs.targetY + difs.targetY\r\n if (\r\n (this.attrs.targetY > this.attrs.centerY && result < this.attrs.centerY) ||\r\n (this.attrs.targetY < this.attrs.centerY && result > this.attrs.centerY)\r\n ) {\r\n this.attrs.stopY = this.attrs.centerY - (this.attrs.stopY - this.attrs.centerY) // swap target&stop\r\n }\r\n this.attrs.targetY = result\r\n }\r\n\r\n if (difs.stopY) {\r\n result = this.attrs.stopY + difs.stopY\r\n if (\r\n (this.attrs.stopY > this.attrs.centerY && result < this.attrs.centerY) ||\r\n (this.attrs.stopY < this.attrs.centerY && result > this.attrs.centerY)\r\n ) {\r\n this.attrs.targetY = this.attrs.centerY - (this.attrs.targetY - this.attrs.centerY) // swap target&stop\r\n }\r\n this.attrs.stopY = result\r\n }\r\n\r\n if (\r\n difs.centerY &&\r\n ((this.attrs.stopY < (middle = this.attrs.centerY + difs.centerY) && middle < this.attrs.targetY) ||\r\n (this.attrs.stopY > (middle1 = this.attrs.centerY + difs.centerY) && middle1 > this.attrs.targetY))\r\n ) {\r\n this.attrs.centerY += difs.centerY\r\n }\r\n\r\n this.x1Dif += difs.x1 || 0\r\n this.x2Dif += difs.x2 || 0\r\n const roundDif = ~~this.x1Dif || ~~this.x2Dif\r\n if (roundDif !== 0) {\r\n if (difs.x1 != null) {\r\n this.attrs.x1 += roundDif\r\n }\r\n if (difs.x2 != null) {\r\n this.attrs.x2 += roundDif\r\n }\r\n this.x1Dif = this.x2Dif = 0\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n return this.addToCoordinates({\r\n x1: x,\r\n x2: x,\r\n targetY: y,\r\n centerY: y,\r\n stopY: y,\r\n })\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n const [coordType, coordIndex] = (type as string).split('')\r\n const yPoints: Record = { t: 'targetY', c: 'centerY', s: 'stopY' }\r\n const obj: Partial = {\r\n [`x${coordIndex}`]: difX,\r\n [yPoints[coordType]]: difY,\r\n }\r\n return this.addToCoordinates(obj)\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const x1 = Math.round(this.attrs.x1)\r\n const x2 = Math.round(this.attrs.x2)\r\n const left = Math.min(x1, x2)\r\n const right = Math.max(x1, x2)\r\n const top = Math.min(this.attrs.targetY, this.attrs.stopY)\r\n const bottom = Math.max(this.attrs.targetY, this.attrs.stopY)\r\n if (left < area.x && area.x < right && top < area.y && area.y < bottom) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n}\r\n\r\nPosition.prototype.defaults = {\r\n targetColor: 'rgba(0,200,0,0.3)',\r\n stopColor: 'rgba(200,0,0,0.3)',\r\n}\r\n\r\nPosition.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'background', name: 'targetColor' },\r\n { type: 'background', name: 'stopColor' },\r\n ],\r\n}\r\n\r\nexport default Position\r\n","import { DrawingBorder, PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport { getOffsetFromLineWidth, getRoundedObject } from '../controllers/renderUtils'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Thumb from './thumb'\r\n\r\nexport interface IRectangleAttrs {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n fill: string\r\n border: DrawingBorder\r\n}\r\n\r\nclass Rectangle extends Element {\r\n static type = CanvasElementType.rectangle\r\n\r\n name = 'Rectangle'\r\n\r\n declare scaled: Pick\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n this._thumbs = [\r\n new Thumb(\r\n 'br',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'tl',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getDefaults() {\r\n const { ElementSettings } = this.getChartLayoutSettings()\r\n return {\r\n fill: ElementSettings.defaultFill,\r\n border: {\r\n width: 1,\r\n color: ElementSettings.Colors.border,\r\n },\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { x1, x2, y1, y2 } = this.scaled\r\n const roundedXY = getRoundedObject({ x1, x2, y1, y2 })\r\n const width = roundedXY.x2 - roundedXY.x1\r\n const height = roundedXY.y2 - roundedXY.y1\r\n\r\n context.set('fillStyle', this.attrs.fill)\r\n\r\n context.fillRect(roundedXY.x1, roundedXY.y1, width, height)\r\n\r\n if ((this.attrs.border != null ? this.attrs.border.width : undefined) !== 0) {\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n const offset = getOffsetFromLineWidth(this.attrs.border.width)\r\n context.strokeRect(roundedXY.x1 + offset, roundedXY.y1 + offset, width, height)\r\n }\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.x2 += x\r\n this.attrs.y1 += y\r\n this.attrs.y2 += y\r\n\r\n // @todo - Live sync of elements while they are being moved around\r\n // In order to have live sync across charts we need to trigger change so listeners can update other charts with new values\r\n // this.set(this.attrs)\r\n // this.trigger('change', this)\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n if (type === 'tl') {\r\n this.attrs.x1 += difX\r\n return (this.attrs.y1 += difY)\r\n } else {\r\n this.attrs.x2 += difX\r\n this.attrs.y2 += difY\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const left = Math.min(this.attrs.x1, this.attrs.x2)\r\n const right = Math.max(this.attrs.x1, this.attrs.x2)\r\n const top = Math.min(this.attrs.y1, this.attrs.y2)\r\n const bottom = Math.max(this.attrs.y1, this.attrs.y2)\r\n if (left < area.x && area.x < right && top < area.y && area.y < bottom) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n}\r\n\r\nRectangle.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'background', name: 'fill' },\r\n { type: 'border', name: 'border', min: 1, default: {} },\r\n ],\r\n}\r\n\r\nexport default Rectangle\r\n","import { DrawingBorder, PaneArea, Point, ResizeByThumbWithTypeAndDifs } from '../../../types/shared'\r\nimport { CanvasElementType } from '../../constants/common'\r\nimport { getOffsetFromLineWidth, getRoundedObject } from '../../controllers/renderUtils'\r\nimport math from '../../helpers/math'\r\nimport PaneModel from '../../models/pane'\r\nimport Element from '../element'\r\nimport Thumb from '../thumb'\r\n\r\nexport interface IRotatedRectangleV1Attrs {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n cursorTargetX: number\r\n cursorTargetY: number\r\n fill: string\r\n border: DrawingBorder\r\n}\r\n\r\nclass RotatedRectangleV1 extends Element {\r\n static type = CanvasElementType.rotatedRectangleV1\r\n\r\n name = 'New Rotated Rectangle'\r\n\r\n declare scaled: Pick\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n this._thumbs = [\r\n new Thumb(\r\n 'middleLeft',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'middleRight',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'topRight',\r\n () => this.getRectCoordinates(true).P1.x || this.attrs.x2,\r\n () => this.getRectCoordinates(true).P1.y || this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'topLeft',\r\n () => this.getRectCoordinates(true).P2.x || this.attrs.x2,\r\n () => this.getRectCoordinates(true).P2.y || this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'bottomLeft',\r\n () => this.getRectCoordinates(true).P3.x || this.attrs.x1,\r\n () => this.getRectCoordinates(true).P3.y || this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'bottomRight',\r\n () => this.getRectCoordinates(true).P4.x || this.attrs.x1,\r\n () => this.getRectCoordinates(true).P4.y || this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getDefaults() {\r\n const { ElementSettings } = this.getChartLayoutSettings()\r\n return {\r\n fill: ElementSettings.defaultFill,\r\n border: {\r\n width: 1,\r\n color: ElementSettings.Colors.border,\r\n },\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2', 'cursorTargetX'], y: ['y1', 'y2', 'cursorTargetY'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { P1, P2, P3, P4 } = this.getRectCoordinates()\r\n const roundedXY = {\r\n P1: getRoundedObject(P1),\r\n P2: getRoundedObject(P2),\r\n P3: getRoundedObject(P3),\r\n P4: getRoundedObject(P4),\r\n }\r\n const offset = getOffsetFromLineWidth(this.attrs.border.width)\r\n context.set('fillStyle', this.attrs.fill)\r\n\r\n context.translate(offset, offset)\r\n context.beginPath()\r\n if (roundedXY.P1.x === roundedXY.P4.x && roundedXY.P1.y === roundedXY.P4.y) {\r\n context.lineTo(roundedXY.P1.x, roundedXY.P1.y)\r\n context.lineTo(roundedXY.P2.x, roundedXY.P2.y)\r\n } else {\r\n context.lineTo(roundedXY.P1.x, roundedXY.P1.y)\r\n context.lineTo(roundedXY.P2.x, roundedXY.P2.y)\r\n context.lineTo(roundedXY.P3.x, roundedXY.P3.y)\r\n context.lineTo(roundedXY.P4.x, roundedXY.P4.y)\r\n context.closePath()\r\n context.fill()\r\n }\r\n context.translate(offset * -1, offset * -1)\r\n\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n context.stroke()\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n getRectCoordinates(inverted = false) {\r\n const { x1, x2, y1, y2, cursorTargetX, cursorTargetY } = this.scaled\r\n let perpendicularPoint\r\n if (!isNaN(cursorTargetX) && !isNaN(cursorTargetY)) {\r\n const cursor = { x: cursorTargetX, y: cursorTargetY }\r\n const line = { x1, y1, x2, y2 }\r\n const distance = math.distanceToLine(cursor, line)\r\n perpendicularPoint = math.perpendicularPointToLine({\r\n distance,\r\n line,\r\n })\r\n } else {\r\n return {\r\n P1: { x: x2, y: y2 },\r\n P2: { x: x1, y: y1 },\r\n P3: { x: x1, y: y1 },\r\n P4: { x: x2, y: y2 },\r\n }\r\n }\r\n\r\n const pointOffsetX = perpendicularPoint.x - x2\r\n const pointOffsetY = perpendicularPoint.y - y2\r\n\r\n const P1 = { x: x2 + pointOffsetX, y: y2 + pointOffsetY }\r\n const P2 = { x: x1 + pointOffsetX, y: y1 + pointOffsetY }\r\n const P3 = { x: x1 + -1 * pointOffsetX, y: y1 + -1 * pointOffsetY }\r\n const P4 = { x: x2 + -1 * pointOffsetX, y: y2 + -1 * pointOffsetY }\r\n\r\n const invertX = this.model.scale.x.invert\r\n const invertY = this.model.scale.y.invert\r\n if (inverted) {\r\n return {\r\n P1: { x: invertX(P1.x), y: invertY(P1.y) },\r\n P2: { x: invertX(P2.x), y: invertY(P2.y) },\r\n P3: { x: invertX(P3.x), y: invertY(P3.y) },\r\n P4: { x: invertX(P4.x), y: invertY(P4.y) },\r\n }\r\n }\r\n return { P1, P2, P3, P4 }\r\n }\r\n\r\n getRotatedPointCoordinates = ({\r\n rotationAxisPoint,\r\n pointToRotate,\r\n oldLinePoint,\r\n newLinePoint,\r\n }: {\r\n rotationAxisPoint: Point\r\n pointToRotate: Point\r\n oldLinePoint: Point\r\n newLinePoint: Point\r\n }) => {\r\n const angle = math.sharedPointLinesAngle({\r\n sharedPoint: rotationAxisPoint,\r\n oldLinePoint,\r\n newLinePoint,\r\n })\r\n const rotatedPoinCoordinates = math.rotatedPointCoordinates({\r\n rotationAxisPoint,\r\n angle,\r\n pointToRotate,\r\n })\r\n return {\r\n x: this.model.scale.x.invert(rotatedPoinCoordinates.x),\r\n y: this.model.scale.y.invert(rotatedPoinCoordinates.y),\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.y1 += y\r\n this.attrs.x2 += x\r\n this.attrs.y2 += y\r\n this.attrs.cursorTargetX += x\r\n this.attrs.cursorTargetY += y\r\n }\r\n\r\n resize({ type, difX, difY, area }: ResizeByThumbWithTypeAndDifs) {\r\n switch (type) {\r\n case 'middleLeft':\r\n const newMiddleLeftPoint = {\r\n x: this.attrs.x1 + difX,\r\n y: this.attrs.y1 + difY,\r\n }\r\n const middleLeftRotatedCursorPoint = this.getRotatedPointCoordinates({\r\n rotationAxisPoint: { x: this.scaled.x2, y: this.scaled.y2 },\r\n pointToRotate: {\r\n x: this.scaled.cursorTargetX,\r\n y: this.scaled.cursorTargetY,\r\n },\r\n oldLinePoint: { x: this.scaled.x1, y: this.scaled.y1 },\r\n newLinePoint: { x: this.model.scale.x(newMiddleLeftPoint.x), y: this.model.scale.y(newMiddleLeftPoint.y) },\r\n })\r\n this.attrs = {\r\n ...this.attrs,\r\n x1: newMiddleLeftPoint.x,\r\n y1: newMiddleLeftPoint.y,\r\n cursorTargetX: middleLeftRotatedCursorPoint.x,\r\n cursorTargetY: middleLeftRotatedCursorPoint.y,\r\n }\r\n break\r\n case 'middleRight':\r\n const newMiddleRightPoint = {\r\n x: this.attrs.x2 + difX,\r\n y: this.attrs.y2 + difY,\r\n }\r\n const middleRightRotatedCursorPoint = this.getRotatedPointCoordinates({\r\n rotationAxisPoint: { x: this.scaled.x1, y: this.scaled.y1 },\r\n pointToRotate: {\r\n x: this.scaled.cursorTargetX,\r\n y: this.scaled.cursorTargetY,\r\n },\r\n oldLinePoint: { x: this.scaled.x2, y: this.scaled.y2 },\r\n newLinePoint: { x: this.model.scale.x(newMiddleRightPoint.x), y: this.model.scale.y(newMiddleRightPoint.y) },\r\n })\r\n this.attrs = {\r\n ...this.attrs,\r\n x2: newMiddleRightPoint.x,\r\n y2: newMiddleRightPoint.y,\r\n cursorTargetX: middleRightRotatedCursorPoint.x,\r\n cursorTargetY: middleRightRotatedCursorPoint.y,\r\n }\r\n break\r\n case 'topRight':\r\n case 'topLeft':\r\n case 'bottomLeft':\r\n case 'bottomRight':\r\n this.attrs = {\r\n ...this.attrs,\r\n cursorTargetX: area.x,\r\n cursorTargetY: area.y,\r\n }\r\n break\r\n default:\r\n break\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const coordinates = this.getRectCoordinates()\r\n const polygon = Object.keys(coordinates).map((point) => ({\r\n x: coordinates[point as 'P1' | 'P2' | 'P3' | 'P4'].x,\r\n y: coordinates[point as 'P1' | 'P2' | 'P3' | 'P4'].y,\r\n }))\r\n if (math.pointInPolygon(area.scaled, polygon)) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n\r\n getIsInChartView() {\r\n return true\r\n }\r\n}\r\n\r\nRotatedRectangleV1.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'background', name: 'fill' },\r\n { type: 'border', name: 'border', min: 1, default: {} },\r\n ],\r\n}\r\n\r\nexport default RotatedRectangleV1\r\n","import { DrawingBorder, PaneArea } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport { getRoundedObject, getXYOffsetFromLine } from '../controllers/renderUtils'\r\nimport math from '../helpers/math'\r\nimport PaneModel from '../models/pane'\r\nimport Line from './line'\r\n\r\nexport interface IScaledLineAttrs {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n dashLength: number\r\n lineWidth: number\r\n strokeStyle: string\r\n border: DrawingBorder\r\n}\r\n\r\nclass ScaledLine extends Line {\r\n static type = CanvasElementType.scaledLine\r\n\r\n name = 'Line'\r\n\r\n declare scaled: Pick\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.renderContent = this.renderContent.bind(this)\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getDefaults() {\r\n return {\r\n border: {\r\n width: 1,\r\n color: this.getChartLayoutSettings().ElementSettings.Colors.border,\r\n },\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { x1, x2, y1, y2 } = this.scaled\r\n const roundedXY = getRoundedObject({ x1, x2, y1, y2 })\r\n const translateXY = getXYOffsetFromLine({ lineWidth: this.attrs.border.width, ...roundedXY })\r\n\r\n context.translate(translateXY.x, translateXY.y)\r\n context.beginPath()\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n\r\n context.moveTo(roundedXY.x1, roundedXY.y1)\r\n if (this.attrs.dashLength) {\r\n context.setLineDash([this.attrs.dashLength])\r\n }\r\n context.lineTo(roundedXY.x2, roundedXY.y2)\r\n context.stroke()\r\n context.translate(translateXY.x * -1, translateXY.y * -1)\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n if (math.distanceToSegment(area.scaled, this.scaled) <= 10) {\r\n return true\r\n }\r\n return this.thumbsAreInArea(area)\r\n }\r\n}\r\n\r\nScaledLine.prototype.modalConfig = {\r\n inputs: [{ type: 'line', name: 'border' }],\r\n}\r\n\r\nexport default ScaledLine\r\n","import merge from 'lodash.merge'\r\n\r\nimport { PaneArea } from '../../types/shared'\r\nimport { PADDING } from '../constants/common'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport Chart from '../models/chart'\r\nimport PaneModel from '../models/pane'\r\nimport Text, { ITextAttrs } from './text'\r\n\r\ninterface FontFamilyHeightCoefficient {\r\n Arial: {\r\n firstLine: number\r\n otherLines: number\r\n }\r\n Verdana: {\r\n firstLine: number\r\n otherLines: number\r\n }\r\n}\r\n\r\nclass ScaledText extends Text {\r\n static type = CanvasElementType.scaledText\r\n\r\n name = 'Text'\r\n declare fontFamilyHeightCoeficient: FontFamilyHeightCoefficient\r\n declare lastAttrs: Attrs\r\n declare scaled: Partial\r\n declare measuredHeight: number\r\n\r\n declare font: string\r\n declare context?: CanvasRenderingContext2D\r\n declare lines: {\r\n text: string\r\n metrics: TextMetrics\r\n }[]\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.scale({ x: ['x'], y: ['y'] })\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x'], y: ['y'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n this.render(context)\r\n }\r\n\r\n setupTextMetricsCache() {\r\n const ctx = this.context\r\n\r\n if (\r\n (this.attrs.text !== this.lastAttrs?.text ||\r\n JSON.stringify(this.attrs.font) !== JSON.stringify(this.lastAttrs?.font)) &&\r\n ctx\r\n ) {\r\n this.lastAttrs = merge({}, this.attrs)\r\n this.lines = this.getLines().map((line) => ({\r\n text: line,\r\n metrics: ctx.measureText(line),\r\n }))\r\n this.measuredHeight = this.lines.reduce((acc, current, currentIndex) => {\r\n const lineHeight =\r\n current.metrics.actualBoundingBoxAscent +\r\n current.metrics.actualBoundingBoxDescent +\r\n (currentIndex !== this.lines.length - 1 ? PADDING.XXXS : 0)\r\n return acc + lineHeight\r\n }, 0)\r\n }\r\n }\r\n\r\n // private\r\n setupContext(context: CanvasRenderingContext2D) {\r\n this.context = context\r\n context.set('font', this.font)\r\n context.set('fillStyle', this.attrs.fillStyle!)\r\n context.set('textAlign', this.attrs.textAlign!)\r\n context.set('textBaseline', this.attrs.textBaseline)\r\n this.setupTextMetricsCache()\r\n }\r\n\r\n // private\r\n renderText() {\r\n if (!this.context) return\r\n let y = this.scaled.y! + this.attrs.padding.top\r\n let previousDescent = 0\r\n for (let i = 0; i < this.lines.length; i++) {\r\n y += i === 0 ? 0 : this.lines[i].metrics.actualBoundingBoxAscent + previousDescent + PADDING.XXXS\r\n this.context.fillText(this.lines[i].text, this.scaled.x! + this.attrs.padding.left, y)\r\n previousDescent = this.lines[i].metrics.actualBoundingBoxDescent\r\n }\r\n }\r\n\r\n // private\r\n renderBackground() {\r\n if (!this.attrs.background || !this.context) {\r\n return\r\n }\r\n const padding = this.attrs.border!.width / 2 + PADDING.XXS\r\n\r\n this.context.beginPath()\r\n this.context.rect(\r\n this.scaled.x! - padding,\r\n this.scaled.y! - this.lines[0].metrics.actualBoundingBoxAscent - padding,\r\n this.width + padding * 2,\r\n this.measuredHeight + padding * 2\r\n )\r\n this.context.set('fillStyle', this.attrs.background)\r\n this.context.fill()\r\n this.context.set('fillStyle', this.attrs.fillStyle!)\r\n this.renderBorder()\r\n this.context.closePath()\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n // TODO\r\n // if @attrs.textBaseline == 'middle'\r\n // rect.y = @attrs.y - rect.height/2\r\n if (\r\n this.lines &&\r\n this.scaled.x! < area.scaled.x &&\r\n area.scaled.x < this.scaled.x! + this.width &&\r\n this.scaled.y! - this.lines[0].metrics.actualBoundingBoxAscent < area.scaled.y &&\r\n area.scaled.y < this.scaled.y! - this.lines[0].metrics.actualBoundingBoxAscent + this.measuredHeight\r\n ) {\r\n return true\r\n }\r\n return this.thumbsAreInArea(area)\r\n }\r\n\r\n getIsInChartView(chart: Chart) {\r\n if (this.getIsCreator()) {\r\n return true\r\n }\r\n\r\n if (!this.lines) {\r\n return true\r\n }\r\n\r\n const padding = this.attrs.border!.width / 2 + PADDING.XXS\r\n const textBoxX = this.scaled.x! - padding\r\n const textBoxY = this.scaled.y! - this.lines[0].metrics.actualBoundingBoxAscent - padding\r\n const textBoxWidth = this.width + padding * 2\r\n const textBoxHeight = this.measuredHeight + padding * 2\r\n\r\n if (\r\n textBoxX <= -chart.leftOffset + chart.width &&\r\n textBoxX + textBoxWidth >= -chart.leftOffset &&\r\n textBoxY <= this.model.height &&\r\n textBoxY + textBoxHeight >= 0\r\n ) {\r\n return true\r\n }\r\n\r\n return false\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x! += x\r\n this.attrs.y! += y\r\n }\r\n}\r\n\r\nexport default ScaledText\r\n","import { PaneArea, RequireByKey, TextAttrs } from '../../types/shared'\r\nimport { CanvasElementType, TextAlign, TextBaseline } from '../constants/common'\r\nimport Element, { TodoModalConfig } from './element'\r\n\r\nexport interface Area {\r\n x: number\r\n y: number\r\n}\r\n\r\nexport type ITextAttrs = RequireByKey & Partial\r\n\r\nconst DEFAULTS: Partial = {\r\n text: '',\r\n font: {\r\n size: 20,\r\n family: 'Arial',\r\n style: 'normal',\r\n weight: 'normal',\r\n },\r\n lineHeight: 20,\r\n // left | right | center | start | end\r\n textAlign: TextAlign.left,\r\n // top | hanging | middle | alphabetic | ideographic | bottom\r\n textBaseline: TextBaseline.alphabetic,\r\n padding: {\r\n top: 0,\r\n right: 0,\r\n bottom: 0,\r\n left: 0,\r\n },\r\n}\r\n\r\nclass Text extends Element {\r\n static type = CanvasElementType.text\r\n\r\n static getMergedPropsWithDefaults>(\r\n propKey: T,\r\n props: Partial = {}\r\n ) {\r\n return {\r\n ...DEFAULTS[propKey],\r\n ...Object.entries(props).reduce((acc, [key, value]) => (value ? { ...acc, [key]: value } : acc), {}),\r\n }\r\n }\r\n\r\n name = 'Anchored text'\r\n declare context?: CanvasRenderingContext2D\r\n declare width: number\r\n declare height: number\r\n declare font: string\r\n\r\n static initClass() {\r\n Object.defineProperty(this.prototype, 'width', {\r\n get() {\r\n // TODO: revisit this getter, when you call `this.width` you don't expect/want context change\r\n if (this.context) {\r\n this.setupContext(this.context)\r\n }\r\n return this.measure() + this.attrs.padding.left + this.attrs.padding.right\r\n },\r\n })\r\n\r\n Object.defineProperty(this.prototype, 'height', {\r\n get() {\r\n const count = this.getLines().length\r\n return this.attrs.lineHeight * count + this.attrs.padding.top + this.attrs.padding.bottom\r\n },\r\n })\r\n\r\n Object.defineProperty(this.prototype, 'font', {\r\n get() {\r\n const f = this.attrs.font\r\n return `${f.style} ${f.weight} ${f.size}pt ${f.family}`\r\n },\r\n })\r\n }\r\n\r\n getModalConfigBase() {\r\n return {\r\n inputs: [\r\n { type: 'multiline_string', name: 'text', required: true },\r\n { type: 'font', name: 'font' },\r\n {\r\n type: 'background',\r\n name: 'fillStyle',\r\n label: 'Color',\r\n default: this.getChartLayoutSettings().ElementSettings.Colors.textWithoutBackground,\r\n },\r\n {\r\n type: 'background',\r\n name: 'background',\r\n label: 'Background',\r\n default: 'rgba(0,0,0,0)',\r\n },\r\n {\r\n type: 'border',\r\n name: 'border',\r\n min: 0,\r\n default: { color: 'rgba(0,0,0)', width: 0 },\r\n },\r\n ],\r\n } as unknown as TodoModalConfig\r\n }\r\n\r\n getDefaults() {\r\n return {\r\n ...DEFAULTS,\r\n fillStyle: this.getChartLayoutSettings().ElementSettings.Colors.textWithoutBackground,\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x'], y: ['y'] })\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n if (obj.font?.size && !obj.lineHeight) {\r\n this.attrs.lineHeight = Math.max(obj.font.size, this.attrs.lineHeight)\r\n }\r\n return this\r\n }\r\n\r\n render(context: CanvasRenderingContext2D) {\r\n this.setupContext(context)\r\n if (this.attrs.angle && this.context) {\r\n // TODO background & multiline text\r\n this.context.save()\r\n this.context.translate(this.attrs.x!, this.attrs.y!)\r\n this.context.rotate((this.attrs.angle * Math.PI) / 180)\r\n this.context.fillText(this.attrs.text, 0, 0)\r\n this.context.restore()\r\n } else {\r\n this.renderBackground()\r\n this.renderText()\r\n }\r\n }\r\n\r\n measure(context?: CanvasRenderingContext2D) {\r\n if (context) {\r\n this.setupContext(context)\r\n }\r\n const lines = this.getLines()\r\n let max = 0\r\n for (const line of lines) {\r\n max = Math.max(this.context?.measureText(line).width ?? Number.MIN_SAFE_INTEGER, max)\r\n }\r\n return ~~max\r\n }\r\n\r\n isInArea(testArea: PaneArea) {\r\n const area = this.convertArea(testArea)\r\n // TODO iny align\r\n if (\r\n this.attrs.x! < area.x &&\r\n area.x < this.attrs.x! + this.width &&\r\n this.attrs.y! - this.attrs.font.size < area.y &&\r\n area.y < this.attrs.y! - this.attrs.font.size + this.height\r\n ) {\r\n return true\r\n }\r\n return super.isInArea(testArea)\r\n }\r\n\r\n setupContext(context: CanvasRenderingContext2D) {\r\n this.context = context\r\n context.set('font', this.font)\r\n context.set('fillStyle', this.attrs.fillStyle)\r\n context.set('textAlign', this.attrs.textAlign)\r\n context.set('textBaseline', this.attrs.textBaseline)\r\n }\r\n\r\n getLines() {\r\n return this.attrs.text.toString().split('\\n')\r\n }\r\n\r\n renderText() {\r\n if (!this.context) return\r\n let { y } = this.attrs // + @attrs.padding.top\r\n for (const line of this.getLines()) {\r\n this.context.fillText(line, this.attrs.x! + this.attrs.padding.left, y!)\r\n y! += this.attrs.lineHeight\r\n }\r\n }\r\n\r\n renderBackground() {\r\n if (!this.attrs.background || !this.context) {\r\n return\r\n }\r\n\r\n const { width } = this\r\n const { height } = this\r\n const rawHight = height - this.attrs.padding.top - this.attrs.padding.bottom\r\n const { x } = this.attrs\r\n let y = this.attrs.y! - height\r\n\r\n if (this.attrs.textBaseline === 'middle') {\r\n y = this.attrs.y! - rawHight / 2 - this.attrs.padding.top - 1\r\n } else if (this.attrs.textBaseline === 'alphabetic') {\r\n y = this.attrs.y! - this.attrs.lineHeight\r\n }\r\n\r\n this.context.beginPath()\r\n this.context.set('fillStyle', this.attrs.background)\r\n this.context.rect(x!, y, width, height)\r\n this.context.fill()\r\n this.context.set('fillStyle', this.attrs.fillStyle)\r\n this.renderBorder()\r\n this.context.closePath()\r\n }\r\n\r\n renderBorder() {\r\n const { lineWidth = 0, strokeStyle, border } = this.attrs\r\n const borderWidth = border?.width ?? 0\r\n\r\n if ((lineWidth || this.attrs.strokeStyle || borderWidth > 0) && this.context) {\r\n this.context.set('strokeStyle', strokeStyle ?? border?.color ?? '')\r\n this.context.set('lineWidth', Math.max(lineWidth, borderWidth))\r\n this.context.stroke()\r\n }\r\n }\r\n\r\n private convertArea(area: PaneArea) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n return {\r\n x: this.model.scale.x(area.x) + this.model.chart().leftOffset + ChartSettings.left.width,\r\n y: this.model.scale.y(area.y) + ChartSettings.top.height,\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x! += this.model.scale.x(x) + 1\r\n this.attrs.y! += this.model.scale.y(y) - this.model.scale.y(0)\r\n }\r\n\r\n getHeight() {\r\n return this.height\r\n }\r\n}\r\n\r\nText.initClass()\r\n\r\nexport default Text\r\n","import { PaneArea, ResizeByThumbFuncProps, ThumbType } from '../../types/shared'\r\nimport { getOffsetFromLineWidth } from '../controllers/renderUtils'\r\nimport PaneModel from '../models/pane'\r\n\r\ntype Area = PaneArea\r\ntype ResizeFunc = (props: ResizeByThumbFuncProps) => void\r\ntype ScaleFunc = () => number\r\n\r\nclass Thumb {\r\n type: ThumbType\r\n lastX = 0\r\n lastY = 0\r\n fx: ScaleFunc\r\n fy: ScaleFunc\r\n resize: ResizeFunc\r\n model: PaneModel\r\n\r\n constructor(type: ThumbType, fx: ScaleFunc, fy: ScaleFunc, resize: ResizeFunc, model: PaneModel) {\r\n this.type = type\r\n this.fx = fx\r\n this.fy = fy\r\n this.resize = resize\r\n this.model = model\r\n }\r\n\r\n render(context: CanvasRenderingContext2D) {\r\n const { ThumbSettings } = this.model.getChartLayoutSettings()\r\n context.set('fillStyle', ThumbSettings.color)\r\n context.set('strokeStyle', ThumbSettings.borderColor)\r\n context.set('lineWidth', ThumbSettings.borderWidth)\r\n const x = ~~this.x()\r\n const y = ~~this.y()\r\n const thumbWidth = this.getThumbWidth()\r\n const offset = getOffsetFromLineWidth(ThumbSettings.borderWidth)\r\n context.beginPath()\r\n context.rect(x + offset, y + offset, thumbWidth, thumbWidth)\r\n context.fill()\r\n context.stroke()\r\n }\r\n\r\n startEditing(area: Area) {\r\n this.lastX = area.x\r\n return (this.lastY = area.y)\r\n }\r\n\r\n moveTo(area: Area) {\r\n const difX = area.x - this.lastX\r\n const difY = area.y - this.lastY\r\n this.resize({ type: this.type, difX, difY, area })\r\n this.lastX = area.x\r\n this.lastY = area.y\r\n }\r\n\r\n isInArea(area: Area) {\r\n const width = this.model.scale.x.invert(this.getThumbWidth())\r\n const height = this.model.scale.y.invert(0) - this.model.scale.y.invert(this.getThumbWidth())\r\n // +- width/2 because we have coordinates of a center\r\n if (\r\n this.fx() + width / 2 >= area.x &&\r\n this.fx() - width / 2 <= area.x &&\r\n this.fy() + height / 2 > area.y &&\r\n this.fy() - height / 2 < area.y\r\n ) {\r\n return true\r\n }\r\n return false\r\n }\r\n\r\n getThumbWidth() {\r\n const { ThumbSettings } = this.model.getChartLayoutSettings()\r\n return ThumbSettings.size + ThumbSettings.borderWidth * 2\r\n }\r\n\r\n x() {\r\n const { ThumbSettings } = this.model.getChartLayoutSettings()\r\n return this.model.scale.x(this.fx()) - ThumbSettings.size / 2\r\n }\r\n\r\n y() {\r\n const { ThumbSettings } = this.model.getChartLayoutSettings()\r\n return this.model.scale.y(this.fy()) - ThumbSettings.size / 2\r\n }\r\n}\r\n\r\nexport default Thumb\r\n","import { PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport { getOffsetFromLineWidth, getRoundedObject } from '../controllers/renderUtils'\r\nimport math from '../helpers/math'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Thumb from './thumb'\r\n\r\nexport interface ITriangleAttrs {\r\n x1: number\r\n x2: number\r\n x3: number\r\n y1: number\r\n y2: number\r\n y3: number\r\n fill: string\r\n border: string\r\n}\r\n\r\nclass Triangle extends Element {\r\n static type = CanvasElementType.triangle\r\n\r\n declare scaled: Pick\r\n name = 'Triangle'\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n\r\n this.resize = this.resize.bind(this)\r\n\r\n this._thumbs = [\r\n new Thumb(\r\n 'a',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'b',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'c',\r\n () => this.attrs.x3,\r\n () => this.attrs.y3,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getDefaults() {\r\n const { ElementSettings } = this.getChartLayoutSettings()\r\n return { fill: ElementSettings.defaultFill, border: ElementSettings.Colors.border } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2', 'x3'], y: ['y1', 'y2', 'y3'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { x1, x2, x3, y1, y2, y3 } = this.scaled\r\n const roundedXY = getRoundedObject({ x1, x2, x3, y1, y2, y3 })\r\n\r\n context.set('fillStyle', this.attrs.fill)\r\n\r\n const offset = this.getShouldRenderThumbs() ? getOffsetFromLineWidth(1) : 0\r\n\r\n context.translate(offset, offset)\r\n context.beginPath()\r\n context.moveTo(roundedXY.x1, roundedXY.y1)\r\n context.lineTo(roundedXY.x2, roundedXY.y2)\r\n context.lineTo(roundedXY.x3, roundedXY.y3)\r\n context.lineTo(roundedXY.x1, roundedXY.y1)\r\n context.fill()\r\n context.translate(offset * -1, offset * -1)\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n context.set('strokeStyle', this.attrs.border)\r\n context.stroke()\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.y1 += y\r\n this.attrs.x2 += x\r\n this.attrs.y2 += y\r\n this.attrs.x3 += x\r\n this.attrs.y3 += y\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n switch (type) {\r\n case 'a':\r\n this.attrs.x1 += difX\r\n this.attrs.y1 += difY\r\n break\r\n case 'b':\r\n this.attrs.x2 += difX\r\n this.attrs.y2 += difY\r\n break\r\n case 'c':\r\n this.attrs.x3 += difX\r\n this.attrs.y3 += difY\r\n break\r\n default:\r\n break\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const polygon = [1, 2, 3].map((i) => ({\r\n x: this.scaled[`x${i}` as 'x1' | 'x2' | 'x3'],\r\n y: this.scaled[`y${i}` as 'y1' | 'y2' | 'y3'],\r\n }))\r\n if (math.pointInPolygon(area.scaled, polygon)) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n}\r\n\r\nTriangle.prototype.modalConfig = {\r\n inputs: [{ type: 'background', name: 'fill' }],\r\n}\r\n\r\nexport default Triangle\r\n","import { RequireByKey, ResizeByThumbFuncProps } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport Chart from '../models/chart'\r\nimport PaneModel from '../models/pane'\r\nimport ScaledLine, { IScaledLineAttrs } from './scaled_line'\r\n\r\nclass VerticalLine extends ScaledLine {\r\n static type = CanvasElementType.verticalLine\r\n\r\n name = 'Vertical line'\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n\r\n this.renderContent = this.renderContent.bind(this)\r\n\r\n this.attrs.x2 = this.attrs.x1\r\n this._thumbs = [this._thumbs[0]]\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const domain = this.model.scale.y.domain()\r\n this.attrs.y1 = domain[0]\r\n this.attrs.y2 = domain[1]\r\n this._thumbs[0].fy = () => (this.attrs.y1 + this.attrs.y2) / 2\r\n super.renderContent(context)\r\n }\r\n\r\n moveBy(x: number) {\r\n return (this.attrs.x1 = this.attrs.x2 += x)\r\n }\r\n\r\n resize({ difX }: RequireByKey) {\r\n return this.moveBy(difX)\r\n }\r\n\r\n getIsInChartView(chart: Chart) {\r\n return super.getIsInChartView(chart, { omitY: true })\r\n }\r\n}\r\n\r\nexport default VerticalLine\r\n","import { DrawingBorder, PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType, TextAlign, TextBaseline } from '../constants/common'\r\nimport { getOffsetFromLineWidth, getRoundedObject } from '../controllers/renderUtils'\r\nimport math from '../helpers/math'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Text, { ITextAttrs } from './text'\r\nimport Thumb from './thumb'\r\n\r\nexport interface IXABCDPositionAttrs {\r\n xx: number\r\n xy: number\r\n ax: number\r\n ay: number\r\n bx: number\r\n by: number\r\n cx: number\r\n cy: number\r\n dx: number\r\n dy: number\r\n}\r\n\r\ntype xPoints = 'xx' | 'ax' | 'bx' | 'cx' | 'dx'\r\ntype yPoints = 'xy' | 'ay' | 'by' | 'cy' | 'dy'\r\n\r\nexport interface IXABCDAttrs extends IXABCDPositionAttrs {\r\n fill: string\r\n border: DrawingBorder\r\n lineWidth: number\r\n}\r\n\r\nclass XABCD extends Element {\r\n static type = CanvasElementType.xabcd\r\n\r\n name = 'XABCD pattern'\r\n\r\n declare scaled: Pick\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n\r\n this.resize = this.resize.bind(this)\r\n\r\n this._thumbs = [\r\n new Thumb(\r\n 'x',\r\n () => this.attrs.xx,\r\n () => this.attrs.xy,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'a',\r\n () => this.attrs.ax,\r\n () => this.attrs.ay,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'b',\r\n () => this.attrs.bx,\r\n () => this.attrs.by,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'c',\r\n () => this.attrs.cx,\r\n () => this.attrs.cy,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'd',\r\n () => this.attrs.dx,\r\n () => this.attrs.dy,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n if (this.attrs.lineWidth == null) {\r\n this.attrs.lineWidth = 1\r\n }\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getDefaults() {\r\n const { ElementSettings } = this.getChartLayoutSettings()\r\n return {\r\n fill: ElementSettings.defaultFill,\r\n border: {\r\n width: 1,\r\n color: ElementSettings.Colors.border,\r\n },\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({\r\n x: ['xx', 'ax', 'bx', 'cx', 'dx'],\r\n y: ['xy', 'ay', 'by', 'cy', 'dy'],\r\n })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { xx, xy, ax, ay, bx, by, cx, cy, dx, dy } = this.scaled\r\n const roundedXY = getRoundedObject({ xx, xy, ax, ay, bx, by, cx, cy, dx, dy })\r\n\r\n context.set('fillStyle', this.attrs.fill)\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n\r\n const offset = getOffsetFromLineWidth(this.attrs.border.width)\r\n context.translate(offset, offset)\r\n\r\n context.beginPath()\r\n context.moveTo(roundedXY.xx, roundedXY.xy)\r\n context.lineTo(roundedXY.ax, roundedXY.ay)\r\n context.lineTo(roundedXY.bx, roundedXY.by)\r\n context.lineTo(roundedXY.xx, roundedXY.xy)\r\n context.fill()\r\n if ((this.attrs.border != null ? this.attrs.border.width : undefined) !== 0) {\r\n context.stroke()\r\n }\r\n\r\n context.beginPath()\r\n context.moveTo(roundedXY.bx, roundedXY.by)\r\n context.lineTo(roundedXY.cx, roundedXY.cy)\r\n context.lineTo(roundedXY.dx, roundedXY.dy)\r\n context.lineTo(roundedXY.bx, roundedXY.by)\r\n context.fill()\r\n if ((this.attrs.border != null ? this.attrs.border.width : undefined) !== 0) {\r\n context.stroke()\r\n }\r\n\r\n context.beginPath()\r\n context.moveTo(roundedXY.ax, roundedXY.ay)\r\n context.lineTo(roundedXY.cx, roundedXY.cy)\r\n context.moveTo(roundedXY.xx, roundedXY.xy)\r\n context.lineTo(roundedXY.dx, roundedXY.dy)\r\n context.stroke()\r\n\r\n const text = new Text(\r\n {\r\n font: { size: 8, style: 'bold' },\r\n lineHeight: 8,\r\n padding: {\r\n top: 2,\r\n right: 2,\r\n bottom: 2,\r\n left: 2,\r\n },\r\n textBaseline: TextBaseline.middle,\r\n textAlign: TextAlign.start,\r\n fillStyle: '#ffffff',\r\n background: this.attrs.fill || '#000000',\r\n },\r\n this.model\r\n )\r\n\r\n for (const t of Array.from('xabcd')) {\r\n text\r\n .set({\r\n text: t.toUpperCase(),\r\n x: roundedXY[(t + 'x') as xPoints] - 6,\r\n y: roundedXY[(t + 'y') as yPoints] + 12,\r\n } as Partial)\r\n .render(context)\r\n }\r\n\r\n const retLabel = (y1: string, y2: string, y3: string) => {\r\n const len = Math.abs(this.attrs[(y1 + 'y') as yPoints] - this.attrs[(y2 + 'y') as yPoints])\r\n const ret = Math.abs(this.attrs[(y3 + 'y') as yPoints] - this.attrs[(y2 + 'y') as yPoints]) / len\r\n const x = (roundedXY[(y1 + 'x') as xPoints] + roundedXY[(y3 + 'x') as xPoints]) / 2\r\n const y = (roundedXY[(y1 + 'y') as yPoints] + roundedXY[(y3 + 'y') as yPoints]) / 2\r\n return text\r\n .set({\r\n text: ret.toFixed(3),\r\n x,\r\n y,\r\n })\r\n .render(context)\r\n }\r\n\r\n retLabel('x', 'a', 'b')\r\n retLabel('a', 'b', 'c')\r\n retLabel('b', 'c', 'd')\r\n retLabel('x', 'a', 'd')\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n context.translate(offset * -1, offset * -1)\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n for (const t of Array.from('xabcd')) {\r\n this.attrs[(t + 'x') as xPoints] += x\r\n this.attrs[(t + 'y') as yPoints] += y\r\n }\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n this.attrs[(type + 'x') as xPoints] += difX\r\n return (this.attrs[(type + 'y') as yPoints] += difY)\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n let t\r\n const xab = (() => {\r\n const result = []\r\n for (t of Array.from('xab')) {\r\n result.push({ x: this.scaled[(t + 'x') as xPoints], y: this.scaled[(t + 'y') as yPoints] })\r\n }\r\n return result\r\n })()\r\n const bcd = (() => {\r\n const result1 = []\r\n for (t of Array.from('bcd')) {\r\n result1.push({ x: this.scaled[(t + 'x') as xPoints], y: this.scaled[(t + 'y') as yPoints] })\r\n }\r\n return result1\r\n })()\r\n if (math.pointInPolygon(area.scaled, xab) || math.pointInPolygon(area.scaled, bcd)) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n}\r\n\r\nXABCD.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'background', name: 'fill' },\r\n { type: 'border', name: 'border', min: 1 },\r\n ],\r\n}\r\n\r\nexport default XABCD\r\n","import Utils from '../utils'\r\nimport { getContextWithCache } from '../utils/canvas'\r\nimport { captureException, getIsSSr } from '../utils/helpers'\r\n\r\nclass Cache {\r\n constructor() {\r\n this.canvas = getIsSSr() ? null : document.createElement('canvas')\r\n }\r\n\r\n set(callback, width, height) {\r\n this.callback = callback\r\n this.width = width\r\n this.height = height\r\n this.rendered = false\r\n }\r\n\r\n render(context, x, y) {\r\n if (x == null) {\r\n x = 0\r\n }\r\n if (y == null) {\r\n y = 0\r\n }\r\n if (!this.rendered) {\r\n this.refresh()\r\n }\r\n if (this.width < 1 || this.height < 1) {\r\n return\r\n }\r\n\r\n try {\r\n if (this.ratio >= 1 && this.canvas) {\r\n context.drawImage(\r\n this.canvas,\r\n 0,\r\n 0,\r\n ~~(this.width * this.ratio),\r\n ~~(this.height * this.ratio),\r\n x,\r\n y,\r\n this.width,\r\n this.height\r\n )\r\n } else {\r\n context.save()\r\n context.translate(x, y)\r\n this.callback(context)\r\n context.restore()\r\n }\r\n } catch (e) {\r\n captureException(\r\n e,\r\n this.canvas\r\n ? {\r\n extra: {\r\n width: this.width,\r\n height: this.height,\r\n ratio: this.ratio,\r\n cWidth: this.canvas.width,\r\n cHeight: this.canvas.height,\r\n sWidth: window.screen.width,\r\n sHeight: window.screen.height,\r\n },\r\n }\r\n : {}\r\n )\r\n }\r\n }\r\n\r\n refresh() {\r\n if (getIsSSr()) {\r\n return\r\n }\r\n this.canvas.width = this.width\r\n this.canvas.height = this.height\r\n this.context = getContextWithCache(this.canvas)\r\n this.ratio = Utils.getScaleRatio()\r\n Utils.setSizeOnCanvasElement({ canvasElement: this.canvas, width: this.width, height: this.height })\r\n this.context.scale(this.ratio, this.ratio)\r\n\r\n this.callback(this.context)\r\n this.rendered = true\r\n }\r\n}\r\n\r\nexport default Cache\r\n","import { ObjectHash, Theme } from '../../../types/shared'\r\nimport { TextAlign, TextBaseline } from '../../constants/common'\r\nimport { IChartThemeColors, IElementThemeColors, IIndicatorThemeColors } from '../constants'\r\n\r\nexport enum OHLCType {\r\n singleLine = 'singleLine',\r\n dateOnly = 'dateOnly',\r\n timeOnly = 'timeOnly',\r\n}\r\n\r\nexport interface IMargin {\r\n top?: number\r\n right?: number\r\n bottom?: number\r\n left?: number\r\n}\r\n\r\ninterface IPadding {\r\n top?: number\r\n right?: number\r\n bottom?: number\r\n left?: number\r\n}\r\n\r\ninterface IGenericText {\r\n margin: IMargin\r\n font: IFont\r\n}\r\n\r\ninterface IFont {\r\n size?: number\r\n style?: string\r\n weight?: string\r\n family?: string\r\n lineHeight?: number\r\n padding?: IPadding\r\n baseline?: TextBaseline\r\n textAlign?: TextAlign\r\n}\r\n\r\ninterface ISettingsGeneralBase {\r\n Colors: IChartThemeColors\r\n}\r\n\r\nexport interface ISettingsCenterBase {\r\n barWidth: number\r\n barMargin: number\r\n border: number\r\n volumeHeight?: number\r\n}\r\n\r\ninterface ISettingsTopBase {\r\n height: number\r\n}\r\n\r\ninterface ISettingsBottomBase {\r\n height: number\r\n}\r\n\r\ninterface ISettingsLeftBase {\r\n width: number\r\n}\r\n\r\ninterface ISettingsRightBase {\r\n width: number\r\n}\r\n\r\nexport interface ISettings {\r\n ChartSettings: IChartSettings\r\n IndicatorSettings: IIndicatorSettings\r\n MarketSentimentSettings: IMarketSentimentChartSettings\r\n ColorsSettings: Array\r\n ThumbSettings: IThumbSettings\r\n ElementSettings: IElementSettings\r\n isOurSiteRequest?: boolean\r\n}\r\n\r\nexport interface IChartSettings {\r\n general: IChartGeneral\r\n center: ISettingsCenterBase\r\n top: IChartTop\r\n bottom: IChartBottom\r\n left: IChartLeft\r\n right: IChartRight\r\n}\r\n\r\ninterface IChartGeneral {\r\n settingsHeight: number\r\n tickerTimeframeChangeHeight: number\r\n Colors: IChartThemeColors & ObjectHash\r\n}\r\n\r\ninterface IChartTop extends ISettingsTopBase {\r\n baseline: TextBaseline\r\n ticker: IGenericText\r\n ohlc: IOHLC\r\n change: IGenericText\r\n}\r\n\r\ninterface IOHLC extends IGenericText {\r\n type?: OHLCType\r\n}\r\n\r\ninterface IChartBottom extends ISettingsBottomBase {\r\n baseline: TextBaseline\r\n axis: IGenericText\r\n}\r\n\r\ninterface IChartLeft extends ISettingsLeftBase {\r\n overlayLabel: IOverlayLabel\r\n timeframe: IGenericText\r\n volumeAxis: IGenericText\r\n}\r\n\r\ninterface IOverlayLabel extends IGenericText {\r\n labelSpacing: number\r\n}\r\n\r\ninterface IChartRight extends ISettingsRightBase {\r\n axis: IGenericText\r\n}\r\n\r\nexport interface IIndicatorSettings {\r\n general: IIndicatorGeneral\r\n center: ISettingsCenterBase\r\n top: ISettingsTopBase\r\n bottom: ISettingsBottomBase\r\n left: IIndicatorLeft\r\n right: IIndicatorRight\r\n}\r\n\r\ninterface IIndicatorRight extends ISettingsRightBase {\r\n axis: IGenericText\r\n}\r\n\r\ninterface IIndicatorLeft extends ISettingsLeftBase {\r\n indicatorLabel: IIndicatorLabel\r\n}\r\n\r\ninterface IIndicatorLabel extends IGenericText {\r\n labelSpacing: number\r\n}\r\n\r\ninterface IIndicatorGeneral {\r\n Colors: IIndicatorThemeColors\r\n height: number\r\n}\r\n\r\ninterface IMarketSentimentChartSettings {\r\n general: ISettingsGeneralBase\r\n center: ISettingsCenterBase\r\n top: ISettingsTopBase\r\n bottom: ISettingsBottomBase\r\n left: ISettingsLeftBase\r\n right: ISettingsRightBase\r\n}\r\n\r\ninterface IThumbSettings {\r\n size: number\r\n touchSize: number\r\n color: string\r\n borderWidth: number\r\n borderColor: string\r\n}\r\n\r\ninterface IElementSettings {\r\n Colors: IElementThemeColors\r\n defaultFill: string\r\n defaultTransparentFill: string\r\n}\r\n","export enum ChartMinWidthBreakpoints {\r\n xs = 0,\r\n s = 480,\r\n m = 768,\r\n l = 1024,\r\n}\r\n\r\nexport function getChartBreakpoints(chartWidthInPx: number) {\r\n return {\r\n isXs: chartWidthInPx >= ChartMinWidthBreakpoints.xs,\r\n isS: chartWidthInPx >= ChartMinWidthBreakpoints.s,\r\n isM: chartWidthInPx >= ChartMinWidthBreakpoints.m,\r\n isL: chartWidthInPx >= ChartMinWidthBreakpoints.l,\r\n }\r\n}\r\n","import * as d3 from 'd3'\r\nimport merge from 'lodash.merge'\r\n\r\nimport {\r\n ChartConfigChartPaneElement,\r\n CustomSpineEvents,\r\n Instrument,\r\n Maybe,\r\n RequireByKey,\r\n Theme,\r\n} from '../../types/shared'\r\nimport Cache from '../canvas/cache'\r\nimport Element from '../canvas/element'\r\nimport Line from '../canvas/line'\r\nimport Text from '../canvas/text'\r\nimport tailwindColors from '../constants/colors'\r\nimport {\r\n CHART_MARGIN,\r\n ChartElementType,\r\n FONT_SIZE,\r\n IndicatorType,\r\n IntradayTimeframeInterval,\r\n LINE_HEIGHT,\r\n MONTHS,\r\n OFFSET,\r\n PADDING,\r\n ScaleType,\r\n SpecificChartFunctionality,\r\n TIMEFRAME,\r\n TIMEFRAMES_WITH_PRE_MARKET,\r\n TextAlign,\r\n TextBaseline,\r\n getTimeframeLabel,\r\n} from '../constants/common'\r\nimport {\r\n getIsSmallIndexChart,\r\n getPercentageFromValue,\r\n getTranslate,\r\n getValueFromPercentage,\r\n} from '../controllers/renderUtils'\r\nimport Chart from '../models/chart'\r\nimport { getColorOverwrites } from '../models/chart_settings'\r\nimport { ISettings, OHLCType } from '../models/chart_settings/interfaces'\r\nimport { darkerWickColors, thinBarColorsOverride } from '../models/constants'\r\nimport mouseModel from '../models/mouse'\r\nimport PaneModel, { ScaleAxis } from '../models/pane'\r\nimport Quote from '../models/quote'\r\nimport { getChartLayoutSettings } from '../models/settings'\r\nimport Overlay from '../overlays/overlay'\r\nimport { overlaysByType } from '../overlays/overlays'\r\nimport utils, { dateFromDateString, isRedesignedPage, numberToStringWithUnitsSuffix } from '../utils'\r\nimport {\r\n ITickerChange,\r\n getBarWidthWithMargin,\r\n getBarWithoutMarginWidth,\r\n getChangeColor,\r\n getHalfBarWidth,\r\n getShouldUseDarkerWickColors,\r\n getTickerChange,\r\n getTickerChangeFromCloseValues,\r\n getVirtualTimeframeTradedDates,\r\n renderCross,\r\n round,\r\n unmountCanvas,\r\n} from '../utils/chart'\r\nimport { convertColorToHEX, getHEXWithSpecificAplha, getHSVAFromColor, stringifyHSVAColor } from '../utils/colors'\r\nimport { setElementCursor } from '../utils/cursor'\r\nimport { drawInVisibleArea, getAreNoBarsVisible, getVisibleBarToRenderIndex } from '../utils/draw_in_visible_area'\r\nimport { getChartBreakpoints } from './utils'\r\n\r\nexport interface BaseChartAttrs {\r\n overlays: Required['overlays']\r\n}\r\n\r\ntype OhlcLineElements = Array<{ text: string; color: string } | 'space'>\r\n\r\ninterface LastOHLCAttrs {\r\n text: string\r\n x: number\r\n y: number\r\n width: number\r\n textBaseline: TextBaseline\r\n textAlign: TextAlign\r\n}\r\n\r\ninterface IRenderOHLCParameters {\r\n context: CanvasRenderingContext2D\r\n date: Maybe\r\n open?: Maybe\r\n high?: Maybe\r\n low?: Maybe\r\n close?: Maybe\r\n volume?: Maybe\r\n afterHour?: string\r\n isSmallIndexChart?: boolean\r\n isNewestOHLC?: boolean\r\n directRender?: boolean\r\n time?: string\r\n changePercentage?: Maybe\r\n}\r\n\r\ninterface XAxisLabel {\r\n x: number\r\n text: string\r\n textWidth: number\r\n hasPriority?: boolean\r\n allowedOverflow?: number\r\n}\r\n\r\ninterface IRenderXAxisProps {\r\n textRenderer: Text\r\n startBarIndex: number\r\n endBarIndex: number\r\n}\r\n\r\nconst getDateString = ({ date, timeframe }: { date: Date; timeframe: TIMEFRAME }) => {\r\n let dateString = ''\r\n const month = date.getMonth() // 20141126\r\n const year = date.getFullYear()\r\n const day = date.getDate()\r\n switch (timeframe) {\r\n case TIMEFRAME.i1:\r\n case TIMEFRAME.i2:\r\n case TIMEFRAME.i3:\r\n case TIMEFRAME.i5:\r\n case TIMEFRAME.i10:\r\n case TIMEFRAME.i15:\r\n case TIMEFRAME.i30:\r\n case TIMEFRAME.h:\r\n case TIMEFRAME.h2:\r\n case TIMEFRAME.h4:\r\n const t =\r\n (((date.getHours() + 11) % 12) + 1).toString().padLeft('00') +\r\n ':' +\r\n date.getMinutes().toString().padLeft('00') +\r\n (date.getHours() < 12 ? 'AM' : 'PM')\r\n dateString = `${MONTHS[month]} ${day} ${t}`\r\n break\r\n case TIMEFRAME.d:\r\n case TIMEFRAME.w:\r\n dateString = `${MONTHS[month]} ${day}`\r\n break\r\n case TIMEFRAME.m:\r\n dateString = `${MONTHS[month]} ${year}`\r\n break\r\n default:\r\n break\r\n }\r\n\r\n return dateString\r\n}\r\n\r\nconst getIsOverlapping = ({\r\n x,\r\n textWidth,\r\n renderedLabelRanges,\r\n}: {\r\n x: number\r\n textWidth: number\r\n renderedLabelRanges: Array<{ from: number; to: number }>\r\n}) =>\r\n renderedLabelRanges.some(({ from, to }) => {\r\n const minX = x - textWidth / 2\r\n const maxX = x + textWidth / 2\r\n return (from < maxX && maxX < to) || (from < minX && minX < to)\r\n })\r\n\r\nfunction getClosestDifferentMinMaxValueIndices(\r\n currentMinIndex: number,\r\n currentMaxIndex: number,\r\n high: number[],\r\n low: number[]\r\n): { minIndex: number; maxIndex: number } {\r\n const hasPreviousIndex = currentMinIndex > 0\r\n const hasNextIndex = currentMaxIndex < high.length - 1\r\n let minIndex = currentMinIndex\r\n let maxIndex = currentMaxIndex\r\n if (hasPreviousIndex) {\r\n minIndex -= 1\r\n }\r\n if (hasNextIndex) {\r\n maxIndex += 1\r\n }\r\n\r\n if (low[minIndex] === high[maxIndex] && (hasPreviousIndex || hasNextIndex)) {\r\n return getClosestDifferentMinMaxValueIndices(minIndex, maxIndex, high, low)\r\n }\r\n\r\n return low[minIndex] < high[maxIndex] ? { minIndex, maxIndex } : { minIndex: maxIndex, maxIndex: minIndex }\r\n}\r\n\r\nconst SMALL_INDEX_CHART_LABEL_BUFFER = 15\r\n\r\nconst gray300 = tailwindColors.gray[300]\r\n\r\nclass BaseChart extends Element {\r\n static initClass() {\r\n Object.defineProperty(this.prototype, 'width', {\r\n get() {\r\n const { ChartSettings } = this.getChartLayoutSettings() as ISettings\r\n return this.model.width - ChartSettings.left.width - ChartSettings.right.width\r\n },\r\n })\r\n\r\n Object.defineProperty(this.prototype, 'height', {\r\n get() {\r\n const { ChartSettings } = this.getChartLayoutSettings() as ISettings\r\n return this.paneModel.height - ChartSettings.top.height - ChartSettings.bottom.height\r\n },\r\n })\r\n }\r\n\r\n static getNumOfBarsBuffer({ overlays }: RequireByKey) {\r\n return Math.max(0, ...overlays.map((overlay) => overlaysByType[overlay.type].getNumOfBarsBuffer(overlay)))\r\n }\r\n\r\n static label = 'Chart'\r\n static iconName = ''\r\n\r\n paneModel: PaneModel\r\n model: Chart\r\n data: Quote\r\n specificChartFunctionality: SpecificChartFunctionality\r\n tickerWidth = 0\r\n changeWidth = 0\r\n lastOhlc: Array> = []\r\n overlays: Overlay[] = []\r\n isLargeChart?: boolean\r\n shouldRenderVolume = true\r\n afterChange: {\r\n x: number\r\n y: number\r\n width: number\r\n } | null = null\r\n\r\n declare setupAxisTimeFrame: string\r\n declare volumeFY: d3.ScaleLinear\r\n declare tickerText: Text\r\n declare baseCache: Cache\r\n declare leftOffset: number\r\n declare context: CanvasRenderingContext2D\r\n declare width: number\r\n declare height: number\r\n declare isMobile: boolean\r\n\r\n constructor(values: Partial, paneModel: PaneModel) {\r\n super(values, paneModel)\r\n\r\n this.paneModel = paneModel\r\n this.model = this.paneModel.chart()\r\n this.data = this.model.quote()\r\n const chartLayoutModel = this.model.chart_layout()\r\n this.specificChartFunctionality = chartLayoutModel.specificChartFunctionality\r\n this.isLargeChart = chartLayoutModel.isLargeChart\r\n this.isMobile = utils.isMobile(true)\r\n\r\n this.overlays = []\r\n if (values.overlays) {\r\n for (const overlayDefinition of values.overlays) {\r\n // overlayDefinition.color coming from DB is always string however overlays\r\n // internaly didn't use format as in db (type, color, period) but rather\r\n // more overlay specific parameters eg. (BB: topColor, bottomColor, etc.)\r\n // thus overlayDefinition.color might be undefined\r\n // approach could be reworked in https://github.com/finvizhq/charts/issues/770\r\n // but for now (!overlayDefinition.color) check solve issue as well\r\n const overlay = overlaysByType[overlayDefinition.type].fromObject(\r\n {\r\n ...overlayDefinition,\r\n color:\r\n !overlayDefinition.color || overlayDefinition.color.includes('|')\r\n ? ''\r\n : convertColorToHEX(overlayDefinition.color),\r\n },\r\n this.paneModel\r\n )\r\n this.addOverlay(overlay)\r\n }\r\n delete values.overlays\r\n }\r\n\r\n this.renderYAxis = this.renderYAxis.bind(this)\r\n this.renderText = this.renderText.bind(this)\r\n this.renderCrossText = this.renderCrossText.bind(this)\r\n this.setupCache = this.setupCache.bind(this)\r\n this.renderOverlaysLabels = this.renderOverlaysLabels.bind(this)\r\n\r\n // this.paneModel.bind('update', this.setupAxis.bind(this))\r\n this.paneModel.bind('update', this.setupCache)\r\n this.paneModel.bind('change', this.trigger.bind(this, 'change'))\r\n this.model = this.paneModel.chart()\r\n // this.model.bind('change', this.setupAxis.bind(this))\r\n this.model.bind('change', this.setupCache)\r\n this.model.bind('change', this.trigger.bind(this, 'change'))\r\n this.model.bind(CustomSpineEvents.IndicatorsChange, this.handleIndicatorsChange.bind(this))\r\n const mouseModelChangeHandler = this.trigger.bind(this, 'change', 'cross')\r\n this.model.bind('destroy', () => {\r\n this.model.unbind('change', this.setupCache)\r\n this.model.unbind(CustomSpineEvents.IndicatorsChange, this.handleIndicatorsChange.bind(this))\r\n mouseModel.unbind('change', mouseModelChangeHandler)\r\n unmountCanvas(this.baseCache.canvas)\r\n })\r\n mouseModel.bind('change', mouseModelChangeHandler)\r\n\r\n this.model.chart_layout().bind('theme', this.setupCache)\r\n this.model.chart_layout().bind('update', this.updateShouldRenderVolume.bind(this))\r\n\r\n this.setupCache()\r\n }\r\n\r\n renderChart() {\r\n throw Error('Implement renderChart')\r\n }\r\n\r\n render(context: CanvasRenderingContext2D) {\r\n this.data = this.model.quote()\r\n this.leftOffset = this.model.leftOffset\r\n this.context = context\r\n\r\n if (this.data.close.length === 0) {\r\n this.renderChartNotAvailable()\r\n if (!this.getIsRedesignedChart()) this.renderTicker(context)\r\n return\r\n }\r\n\r\n this.context.save()\r\n this.clip()\r\n this.renderVolume()\r\n this.renderChart()\r\n this.renderOverlays()\r\n this.renderPrevClose()\r\n this.renderFadeExtendedHours()\r\n this.context.restore()\r\n if (!this.getIsRedesignedChart()) this.renderTicker(context)\r\n }\r\n\r\n renderGrid(context: CanvasRenderingContext2D) {\r\n this.data = this.model.quote()\r\n this.leftOffset = this.model.leftOffset\r\n this.context = context\r\n // text, xAxis, volumeAxis\r\n this.renderXAxis()\r\n this.baseCache.render(context)\r\n }\r\n\r\n renderTicker(context: CanvasRenderingContext2D) {\r\n if (this.tickerText) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n context.translate(ChartSettings.left.width, 0)\r\n this.tickerText.render(context)\r\n\r\n if (getIsSmallIndexChart(this.specificChartFunctionality) && this.data.ticker === 'RUSSELL 2000') {\r\n const { Colors } = ChartSettings.general\r\n new Text(\r\n {\r\n text: 'ETF',\r\n x: ChartSettings.top.ticker.margin.left,\r\n y: ChartSettings.top.ticker.margin.top! + FONT_SIZE.XXS + OFFSET.XXS,\r\n font: { size: FONT_SIZE.XXS },\r\n fillStyle: Colors.text,\r\n textBaseline: ChartSettings.top.baseline,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n }\r\n\r\n context.translate(-ChartSettings.left.width, 0)\r\n }\r\n }\r\n\r\n renderTimeframe(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const quote = this.model.quote()\r\n const y = (this.height - this.volumeFY.range()[1] - 4) / 2\r\n\r\n return new Text(\r\n {\r\n text: quote.instrument === Instrument.Group ? 'YEAR PERFORMANCE %' : getTimeframeLabel(quote.timeframe),\r\n x: ChartSettings.left.timeframe.margin.left,\r\n y: ChartSettings.top.height + y + (ChartSettings.left.timeframe.margin.top ?? 0),\r\n angle: -90,\r\n font: Text.getMergedPropsWithDefaults('font', ChartSettings.left.timeframe.font),\r\n fillStyle: Colors.textSecondary,\r\n textAlign: TextAlign.center,\r\n textBaseline: TextBaseline.alphabetic,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n }\r\n\r\n renderText(context: CanvasRenderingContext2D) {\r\n const { ChartSettings, isOurSiteRequest } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n context.save()\r\n context.translate(ChartSettings.left.width, 0)\r\n\r\n if (!getIsSmallIndexChart(this.specificChartFunctionality)) {\r\n this.tickerText = new Text(\r\n {\r\n text: this.data.name || this.data.ticker,\r\n x: ChartSettings.top.ticker.margin.left,\r\n y: ChartSettings.top.ticker.margin.top,\r\n font: Text.getMergedPropsWithDefaults('font', ChartSettings.top.ticker.font),\r\n textBaseline: ChartSettings.top.baseline,\r\n fillStyle: Colors.text,\r\n },\r\n this.paneModel\r\n )\r\n } else {\r\n this.tickerText = new Text(\r\n {\r\n text: this.data.name || this.data.ticker,\r\n x: ChartSettings.top.ticker.margin.left,\r\n y: ChartSettings.top.ticker.margin.top,\r\n font: { size: FONT_SIZE.L, style: 'bold' },\r\n fillStyle: Colors.text,\r\n },\r\n this.paneModel\r\n )\r\n }\r\n this.tickerWidth = this.tickerText.measure(context)\r\n\r\n // render watermark on backend chart\r\n if (this.specificChartFunctionality === SpecificChartFunctionality.offScreen) {\r\n let yOffset = 0\r\n if (!isOurSiteRequest) {\r\n yOffset = this.isLargeChart ? -2 : -3\r\n }\r\n new Text(\r\n {\r\n text: '© finviz.com',\r\n x: this.width + ChartSettings.right.width - 2,\r\n y: 1 + yOffset,\r\n font: { size: isOurSiteRequest ? FONT_SIZE.XS : FONT_SIZE.M },\r\n textAlign: TextAlign.right,\r\n textBaseline: TextBaseline.top,\r\n fillStyle: isOurSiteRequest ? 'rgb(136, 193, 233)' : tailwindColors.finviz.blue,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n }\r\n\r\n if (!this.getIsRedesignedChart()) {\r\n this.renderChange({ context })\r\n if (!this.lastOhlc[0]) {\r\n this.getOHLC({ context, directRender: false })\r\n }\r\n this.getOHLC({ context })\r\n }\r\n\r\n context.restore()\r\n if (!this.getIsRedesignedChart() && !getIsSmallIndexChart(this.specificChartFunctionality)) {\r\n this.renderTimeframe(context)\r\n }\r\n }\r\n\r\n getOHLC({\r\n context,\r\n directRender = true,\r\n data,\r\n date,\r\n dateString = null,\r\n changePercentage = null,\r\n }: {\r\n context: CanvasRenderingContext2D\r\n directRender?: boolean\r\n data?: {\r\n open?: string\r\n high?: string\r\n low?: string\r\n close?: string\r\n volume?: string\r\n }\r\n date?: Date\r\n dateString?: string | null\r\n changePercentage?: ITickerChange | null\r\n }) {\r\n if (!this.data.lastDate) return\r\n\r\n // modulo \"parsing\" is 100% faster than with str.slice()\r\n const lastDate = `${MONTHS[(~~(this.data.lastDate / 100) % 100) - 1]} ${this.data.lastDate % 100}` // YYYYMMDD / 20211118 => Nov 18\r\n if (getIsSmallIndexChart(this.specificChartFunctionality)) {\r\n this.renderOHLC({\r\n context,\r\n date: lastDate,\r\n isSmallIndexChart: true,\r\n isNewestOHLC: true,\r\n directRender,\r\n })\r\n } else if (data && date) {\r\n this.renderOHLC({\r\n context,\r\n date: getDateString({ date, timeframe: this.data.timeframe }),\r\n open: data.open,\r\n high: data.high,\r\n low: data.low,\r\n close: data.close,\r\n volume: numberToStringWithUnitsSuffix(Number(data.volume)),\r\n directRender,\r\n changePercentage,\r\n })\r\n } else if (dateString !== null) {\r\n this.renderOHLC({\r\n context,\r\n date: dateString,\r\n open: null,\r\n high: null,\r\n low: null,\r\n close: null,\r\n volume: null,\r\n directRender,\r\n })\r\n } else {\r\n this.renderOHLC({\r\n context,\r\n date: lastDate,\r\n afterHour:\r\n Number.isFinite(this.data.afterClose) && this.data.afterClose !== this.data.lastClose\r\n ? this.roundOhlc(this.data.afterClose)\r\n : undefined,\r\n volume: numberToStringWithUnitsSuffix(this.data.lastVolume),\r\n isNewestOHLC: true,\r\n time: utils.dateFromUnixTimestamp(this.data.date.last()!).toLocaleTimeString('en-US', {\r\n hour: '2-digit',\r\n minute: '2-digit',\r\n }),\r\n directRender,\r\n ...this.getRoundedLastData(),\r\n })\r\n }\r\n }\r\n\r\n getRoundedLastData() {\r\n return {\r\n open: this.roundOhlc(this.data.lastOpen),\r\n high: this.roundOhlc(this.data.lastHigh),\r\n low: this.roundOhlc(this.data.lastLow),\r\n close: this.roundOhlc(this.data.lastClose),\r\n }\r\n }\r\n\r\n renderOverlaysLabels(context: CanvasRenderingContext2D) {\r\n if (!this.getIsRedesignedChart()) {\r\n this.renderOverlaysLabelsQuotePage(context)\r\n } else if (this.data.close.length !== 0) {\r\n this.renderOverlaysLabelsChartsPage(context)\r\n }\r\n }\r\n\r\n renderOverlaysLabelsQuotePage(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const text = new Text(\r\n {\r\n x: ChartSettings.left.overlayLabel.margin.left,\r\n y: ChartSettings.top.height + ChartSettings.left.overlayLabel.margin.top!,\r\n font: Text.getMergedPropsWithDefaults('font', ChartSettings.left.overlayLabel.font),\r\n textBaseline: TextBaseline.top,\r\n },\r\n this.paneModel\r\n )\r\n for (const overlay of this.overlays) {\r\n if (!overlay.isRenderedOverlaysLabel()) {\r\n continue\r\n }\r\n text\r\n .set({\r\n text: overlay.toString(),\r\n y: text.get('y')! + ChartSettings.left.overlayLabel.labelSpacing,\r\n fillStyle: overlay.getLabelColor(),\r\n })\r\n .render(context)\r\n }\r\n }\r\n\r\n getYAxisLeftMargin() {\r\n if (this.data.instrument === Instrument.Crypto && this.data.lastClose <= 0.001) {\r\n return 3\r\n }\r\n return 8\r\n }\r\n\r\n getYAxisLastCloseLabel({ lastClose, firstVisibleClose }: { lastClose: number; firstVisibleClose?: number | null }) {\r\n if (typeof firstVisibleClose === 'number' && this.model.scale === ScaleType.Percentage) {\r\n return `${this.round(getPercentageFromValue({ number: lastClose, base: firstVisibleClose }), 2)}%`\r\n }\r\n return this.round(lastClose)\r\n }\r\n\r\n renderYAxis(\r\n context: CanvasRenderingContext2D,\r\n { lastClose }: RequireByKey, 'lastClose'> = this.data,\r\n renderLabels = true\r\n ) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n let y, lineTicks, textTicks, lastCloseLabel\r\n const translate = getTranslate({ context, xOffset: ChartSettings.left.width, yOffset: ChartSettings.top.height })\r\n translate.do()\r\n const tickCount = Math.floor(this.paneModel.height / 35)\r\n const minMax = this.getMinMax()\r\n const { firstVisibleClose } = minMax\r\n const height = this.height\r\n let stepPrice = 0\r\n let placesAxis\r\n\r\n switch (this.model.scale) {\r\n case ScaleType.Percentage: {\r\n if (!firstVisibleClose) return\r\n\r\n const scaleRange = this.paneModel.scaleRange\r\n const { min, max } = scaleRange || minMax\r\n\r\n this.model.updateAttribute('firstBarClose', firstVisibleClose)\r\n\r\n const minPerc = getPercentageFromValue({ number: min, base: firstVisibleClose })\r\n const maxPerc = getPercentageFromValue({ number: max, base: firstVisibleClose })\r\n\r\n const percScale = d3.scaleLinear().range([0, this.height]).domain([maxPerc, minPerc]).nice(10)\r\n textTicks = percScale.ticks(Math.min(tickCount, 9))\r\n lineTicks = textTicks.map((tick) => getValueFromPercentage({ number: tick, base: firstVisibleClose }))\r\n lastCloseLabel = this.getYAxisLastCloseLabel({ lastClose, firstVisibleClose })\r\n break\r\n }\r\n case ScaleType.Logarithmic: {\r\n if (!firstVisibleClose) return\r\n\r\n const scaleRange = this.paneModel.scaleRange\r\n const { min, max } = scaleRange || minMax\r\n lineTicks = [Math.floor(min)]\r\n const pixelGap = 30\r\n\r\n const negativeScale = []\r\n if (min < 0) {\r\n let previousNegativeTick = Math.min(0, max)\r\n while (this.paneModel.scale.y(previousNegativeTick) + pixelGap < this.paneModel.scale.y(min)) {\r\n const tick = this.paneModel.scale.y.invert(this.paneModel.scale.y(previousNegativeTick) + pixelGap)\r\n if (previousNegativeTick === tick) {\r\n break\r\n }\r\n const range = d3.nice(-previousNegativeTick, -tick, 2)\r\n previousNegativeTick = -range[range.length - 1]\r\n negativeScale.unshift(previousNegativeTick)\r\n }\r\n }\r\n\r\n const positiveScale = []\r\n if (max > 0) {\r\n positiveScale.push(Math.max(this.paneModel.scale.y.invert(this.paneModel.scale.y(min) + pixelGap), 0))\r\n }\r\n while (this.paneModel.scale.y(positiveScale[positiveScale.length - 1]) - pixelGap > 0) {\r\n const previousTick = positiveScale[positiveScale.length - 1]\r\n const positiveScaleY = this.paneModel.scale.y(positiveScale[positiveScale.length - 1])\r\n const tick = this.paneModel.scale.y.invert(positiveScaleY - pixelGap)\r\n if (previousTick === tick) {\r\n break\r\n }\r\n\r\n const range = d3.nice(previousTick, tick, 2)\r\n positiveScale.push(range[range.length - 1])\r\n }\r\n lineTicks = [...negativeScale, ...positiveScale]\r\n textTicks = lineTicks\r\n lastCloseLabel = this.getYAxisLastCloseLabel({ lastClose })\r\n break\r\n }\r\n default:\r\n // default to linear scale type\r\n lineTicks = this.paneModel.scale.y.ticks(Math.min(tickCount, 9))\r\n textTicks = lineTicks\r\n lastCloseLabel = this.getYAxisLastCloseLabel({ lastClose })\r\n }\r\n\r\n if (textTicks.length >= 2) {\r\n stepPrice = Math.abs(textTicks[1] - textTicks[0])\r\n }\r\n if (\r\n stepPrice > 10 ||\r\n (getIsSmallIndexChart(this.specificChartFunctionality) && Math.round(textTicks[0]).toString().length > 3) // if small index chart max tick is less than 999 (3 digits) allow for decimals in axis labels\r\n ) {\r\n placesAxis = 0\r\n }\r\n\r\n const getYLineText = (val: number, places?: number) => {\r\n switch (this.model.scale) {\r\n case ScaleType.Percentage:\r\n return `${val}%`\r\n default:\r\n return this.round(val, places)\r\n }\r\n }\r\n\r\n const yTickText = new Text(\r\n {\r\n x: this.width + this.getYAxisLeftMargin() + ChartSettings.right.axis.margin.left!,\r\n font: Text.getMergedPropsWithDefaults('font', ChartSettings.right.axis.font),\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.middle,\r\n },\r\n this.paneModel\r\n )\r\n\r\n let yTickLine = this.getYLine()\r\n const resetYTicksStyles = () => {\r\n yTickText.set({\r\n font: Text.getMergedPropsWithDefaults('font', ChartSettings.right.axis.font),\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.middle,\r\n })\r\n yTickLine = this.getYLine()\r\n }\r\n for (let i = 0; i < lineTicks.length; i++) {\r\n y = Math.round(this.fy(lineTicks[i]))\r\n if (y < 0 || y > height) continue\r\n yTickLine.set({ y1: y, y2: y })\r\n yTickText.set({\r\n text: getYLineText(textTicks[i], placesAxis),\r\n y,\r\n })\r\n if (this.model.scale === ScaleType.Percentage && textTicks[i] === 0) {\r\n yTickLine.set({ strokeStyle: Colors.text })\r\n yTickText.set({\r\n font: { weight: 'bold', size: yTickText.attrs.font.size },\r\n fillStyle: Colors.percentageZeroLineText,\r\n })\r\n yTickLine.render(context)\r\n yTickText.render(context)\r\n resetYTicksStyles()\r\n } else {\r\n yTickLine.render(context)\r\n yTickText.render(context)\r\n }\r\n }\r\n translate.undo()\r\n\r\n if (renderLabels) {\r\n this.renderYAxisLabel({ context, yCoordinate: Math.round(this.fy(lastClose)), label: lastCloseLabel })\r\n // if (typeof this.data.afterClose === 'number') {\r\n // this.renderYAxisLabel({\r\n // context,\r\n // yCoordinate: this.getYAxisSecondaryLabelYCoordinate({\r\n // mainLabelValue: lastClose,\r\n // secondaryLabelValue: this.data.afterClose,\r\n // }),\r\n // label: this.getYAxisLastCloseLabel({ lastClose: this.data.afterClose, firstVisibleClose }),\r\n // background: this.getSecondaryLabelBackgroundColor(),\r\n // })\r\n // }\r\n }\r\n }\r\n\r\n getSecondaryLabelBackgroundColor() {\r\n return stringifyHSVAColor(\r\n {\r\n ...getHSVAFromColor(this.getChartLayoutSettings().ChartSettings.general.Colors.currentBackground),\r\n s: 0.3,\r\n },\r\n 'hex'\r\n )\r\n }\r\n\r\n getYAxisSecondaryLabelYCoordinate({\r\n mainLabelValue,\r\n secondaryLabelValue,\r\n }: {\r\n mainLabelValue: number\r\n secondaryLabelValue: number\r\n }) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { lineHeight } = ChartSettings.right.axis.font\r\n const padding = Text.getMergedPropsWithDefaults('padding', ChartSettings.right.axis.font.padding)\r\n\r\n const direction = Math.sign(mainLabelValue - secondaryLabelValue) || 1\r\n const offset = (lineHeight ?? LINE_HEIGHT.S) + (padding.top ?? PADDING.XXS) + (padding.bottom ?? PADDING.XXS)\r\n const mainLabelValuePosition = Math.round(this.fy(mainLabelValue))\r\n const secondaryLabelValuePosition = Math.round(this.fy(secondaryLabelValue))\r\n const offsetedY = mainLabelValuePosition + offset * direction\r\n\r\n return Math.abs(secondaryLabelValuePosition - mainLabelValuePosition) > offset\r\n ? secondaryLabelValuePosition\r\n : offsetedY\r\n }\r\n\r\n renderYAxisLabel({\r\n context,\r\n yCoordinate,\r\n label,\r\n background,\r\n }: {\r\n context: CanvasRenderingContext2D\r\n yCoordinate: number\r\n label: string\r\n background?: string\r\n }) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const translate = getTranslate({ context, xOffset: ChartSettings.left.width, yOffset: ChartSettings.top.height })\r\n const { Colors } = ChartSettings.general\r\n const { size, lineHeight } = ChartSettings.right.axis.font\r\n const padding = Text.getMergedPropsWithDefaults('padding', ChartSettings.right.axis.font.padding)\r\n\r\n translate.do()\r\n new Text(\r\n {\r\n text: label,\r\n x: this.width + this.getYAxisLeftMargin() - padding.left + ChartSettings.right.axis.margin.left!,\r\n y: yCoordinate,\r\n font: Text.getMergedPropsWithDefaults('font', { size, style: 'bold' }),\r\n lineHeight,\r\n padding,\r\n textBaseline: TextBaseline.middle,\r\n fillStyle:\r\n this.specificChartFunctionality === SpecificChartFunctionality.offScreen ? 'black' : Colors.currentText,\r\n background: background || Colors.currentBackground,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n translate.undo()\r\n }\r\n\r\n renderXAxis() {\r\n const { leftOffset, width } = this\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n\r\n this.context.save()\r\n if (\r\n this.data.getDrawDays() !== 1 &&\r\n !getIsSmallIndexChart(this.specificChartFunctionality) &&\r\n this.data.instrument !== Instrument.MarketSentiment\r\n ) {\r\n this.clip(true)\r\n }\r\n this.context.translate(ChartSettings.left.width, ChartSettings.top.height)\r\n const textRenderer = new Text(\r\n {\r\n y: this.height + ChartSettings.bottom.axis.margin.top!,\r\n font: Text.getMergedPropsWithDefaults('font', { size: ChartSettings.bottom.axis.font.size }),\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.top,\r\n textAlign: TextAlign.center,\r\n },\r\n this.paneModel\r\n )\r\n\r\n // Ticks are placed at the start of each timeframe period (hour/day/month/year).\r\n // The \"-1\" in the code ensures we start searching from one bar outside the visible area,\r\n // avoiding a tick on the first visible index unless it marks the start of a new timeframe period.\r\n // For example, if the start of December is on December 3rd and the first visible bar is on December 14th,\r\n // we won't display a tick.\r\n const startBarIndex = Math.max(\r\n getVisibleBarToRenderIndex({\r\n quote: this.data,\r\n paneModel: this.paneModel,\r\n leftOffset,\r\n }).index - 1,\r\n 0\r\n )\r\n\r\n const endBarIndex = Math.min(\r\n getVisibleBarToRenderIndex({\r\n quote: this.data,\r\n paneModel: this.paneModel,\r\n leftOffset,\r\n chartWidth: width,\r\n }).index + 1,\r\n this.data.close.length - 1\r\n )\r\n\r\n switch (this.data.timeframe) {\r\n case TIMEFRAME.i1:\r\n case TIMEFRAME.i2:\r\n case TIMEFRAME.i3:\r\n case TIMEFRAME.i5:\r\n if (this.data.instrument === Instrument.Stock) {\r\n if (\r\n this.type === ChartElementType.LineChart &&\r\n this.specificChartFunctionality === SpecificChartFunctionality.offScreen &&\r\n this.data.timeframe === 'i5'\r\n ) {\r\n this.render15MinXAxis({ textRenderer, startBarIndex, endBarIndex })\r\n } else {\r\n this.renderIntradayXAxis(textRenderer)\r\n }\r\n } else {\r\n this.renderIntradayXAxisFutures({ textRenderer, startBarIndex, endBarIndex })\r\n }\r\n break\r\n case TIMEFRAME.i10:\r\n if (getIsSmallIndexChart(this.specificChartFunctionality)) {\r\n this.renderIntradayXAxis(textRenderer)\r\n } else {\r\n this.render15MinXAxis({ textRenderer, startBarIndex, endBarIndex })\r\n }\r\n break\r\n case TIMEFRAME.i15:\r\n case TIMEFRAME.i30:\r\n case TIMEFRAME.h:\r\n case TIMEFRAME.h2:\r\n case TIMEFRAME.h4:\r\n this.render15MinXAxis({ textRenderer, startBarIndex, endBarIndex })\r\n break\r\n case TIMEFRAME.d:\r\n this.renderDailyXAxis({ textRenderer, startBarIndex, endBarIndex })\r\n break\r\n case TIMEFRAME.w:\r\n this.renderWeeklyXAxis({ textRenderer, startBarIndex, endBarIndex })\r\n break\r\n case TIMEFRAME.m:\r\n this.renderMonthlyXAxis({ textRenderer, startBarIndex, endBarIndex })\r\n break\r\n default:\r\n break\r\n }\r\n this.context.restore()\r\n }\r\n\r\n isXPointVisible(x: number, buffer = 0) {\r\n return x >= 0 - buffer && x <= this.width + buffer\r\n }\r\n\r\n renderXAxisLabels({\r\n labels,\r\n textRenderer,\r\n allowedOverflow = 0,\r\n }: {\r\n labels: Omit[]\r\n textRenderer: Text\r\n allowedOverflow?: number\r\n }) {\r\n const sortedLabels: XAxisLabel[] = []\r\n const renderedLabelRanges: Array<{ from: number; to: number }> = []\r\n labels.reverse().forEach((label) => {\r\n textRenderer.set({ text: label.text })\r\n const textWidth = Math.floor(textRenderer.measure(this.context))\r\n const newLabel = { ...label, textWidth }\r\n if (label.hasPriority) {\r\n sortedLabels.unshift(newLabel)\r\n } else {\r\n sortedLabels.push(newLabel)\r\n }\r\n })\r\n\r\n sortedLabels.forEach(({ x, text, textWidth }) => {\r\n if (!this.isXPointVisible(x, allowedOverflow)) {\r\n return\r\n }\r\n const halfOfTextWidth = textWidth / 2\r\n const overflowLeft = x - halfOfTextWidth + allowedOverflow\r\n const overflowRight = this.width - (x + halfOfTextWidth) + allowedOverflow\r\n let labelX = x\r\n if (overflowLeft < 0) {\r\n labelX = Math.round(x - overflowLeft)\r\n } else if (overflowRight < 0) {\r\n labelX = Math.round(x + overflowRight)\r\n }\r\n if (getIsOverlapping({ x: labelX, textWidth, renderedLabelRanges })) {\r\n return\r\n }\r\n renderedLabelRanges.push({\r\n from: labelX - halfOfTextWidth - OFFSET.M,\r\n to: labelX + halfOfTextWidth + OFFSET.M,\r\n })\r\n textRenderer.set({ text, x: labelX })\r\n textRenderer.render(this.context)\r\n })\r\n }\r\n\r\n renderIntradayXAxis(textRenderer: Text) {\r\n const interval = IntradayTimeframeInterval[this.data.timeframe as keyof typeof IntradayTimeframeInterval]\r\n const marketStartHour = ~~(this.data.marketStartMinutes / 60)\r\n let marketEndHour = 15 + Math.ceil(this.data.aftermarketLengthMinutes / 60)\r\n const labels = []\r\n if (getIsSmallIndexChart(this.specificChartFunctionality)) {\r\n marketEndHour = 16\r\n }\r\n\r\n const xLine = this.getXLine()\r\n const barWidth = getBarWidthWithMargin({\r\n zoomFactor: this.model.zoomFactor,\r\n chartLayout: this.model.chart_layout(),\r\n })\r\n\r\n const dayToOffset = this.data.getDayToOffset()\r\n const isSmallIndexChart = getIsSmallIndexChart(this.specificChartFunctionality)\r\n const allowedOverflow = isSmallIndexChart ? SMALL_INDEX_CHART_LABEL_BUFFER : 0\r\n for (const day in dayToOffset) {\r\n const dayIndex = dayToOffset[day]\r\n const date = dateFromDateString(day)\r\n\r\n for (let i = marketStartHour; i <= marketEndHour; i++) {\r\n let x =\r\n ((i * 60 - this.data.marketStartMinutes) / interval) * barWidth +\r\n dayIndex * (this.data.drawMinutesPerDay / interval) * barWidth +\r\n this.leftOffset\r\n if (!this.isXPointVisible(x, allowedOverflow)) {\r\n continue\r\n }\r\n let roundedX = Math.round(x)\r\n\r\n if (i === marketStartHour) {\r\n if (isSmallIndexChart) {\r\n roundedX = Math.round(x - 3 + (30 / interval) * barWidth)\r\n // ~9:30AM\r\n xLine\r\n .set({\r\n x1: roundedX,\r\n x2: roundedX,\r\n })\r\n .render(this.context)\r\n continue\r\n }\r\n if (this.data.premarketLengthMinutes === 0) {\r\n // If there is no premarket, day starts at 9:30 AM\r\n x += (30 / interval) * barWidth\r\n }\r\n roundedX = Math.round(x)\r\n xLine.set({ x1: roundedX, x2: roundedX }).render(this.context)\r\n labels.push({\r\n hasPriority: true,\r\n text: MONTHS[date.getMonth()] + ' ' + date.getDate().toString().padLeft('00'),\r\n x: roundedX,\r\n })\r\n } else {\r\n xLine.set({ x1: roundedX, x2: roundedX }).render(this.context)\r\n labels.push({\r\n text: ((i + 11) % 12) + 1 + (i < 12 ? 'AM' : 'PM'),\r\n x: roundedX,\r\n })\r\n }\r\n }\r\n }\r\n this.renderXAxisLabels({ labels, textRenderer, allowedOverflow })\r\n }\r\n\r\n renderIntradayXAxisFutures({ textRenderer, startBarIndex, endBarIndex }: IRenderXAxisProps) {\r\n let lastDay = ''\r\n let lastHours = NaN\r\n\r\n const labels = []\r\n const xLine = this.getXLine()\r\n for (let i = startBarIndex; i <= endBarIndex; i++) {\r\n const date = utils.dateFromUnixTimestamp(this.data.date[i])\r\n const day = date.getDate() + '-' + date.getMonth()\r\n const hours = date.getHours()\r\n const x = Math.round(this.fx(i) + this.leftOffset)\r\n\r\n if (day !== lastDay) {\r\n lastDay = day\r\n lastHours = hours\r\n if (!this.isXPointVisible(x)) {\r\n continue\r\n }\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n labels.push({\r\n x,\r\n text: MONTHS[date.getMonth()] + ' ' + date.getDate().toString().padLeft('00'),\r\n })\r\n } else if (hours % 2 === 0 && hours !== lastHours) {\r\n lastHours = hours\r\n if (!this.isXPointVisible(x)) {\r\n continue\r\n }\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n labels.push({ x, text: ((hours + 11) % 12) + 1 + (hours < 12 ? 'AM' : 'PM') })\r\n }\r\n }\r\n this.renderXAxisLabels({ labels, textRenderer })\r\n }\r\n\r\n render15MinXAxis({ textRenderer, startBarIndex, endBarIndex }: IRenderXAxisProps) {\r\n let lastDay = ''\r\n let x = 0\r\n\r\n const labels = []\r\n const xLine = this.getXLine()\r\n for (let i = startBarIndex; i <= endBarIndex; i++) {\r\n const date = utils.dateFromUnixTimestamp(this.data.date[i])\r\n const day = date.getDate() + '-' + date.getMonth()\r\n if (day !== lastDay) {\r\n lastDay = day\r\n if (this.data.instrument === Instrument.Stock) {\r\n const barAtMinute = date.getMinutes() + date.getHours() * 60\r\n const indexOffset = (barAtMinute - this.data.marketStartMinutes) / this.data.interval\r\n x = Math.round(this.paneModel.scale.x(this.data.barIndex[i] - indexOffset) + this.leftOffset)\r\n } else {\r\n x = Math.round(this.fx(i) + this.leftOffset)\r\n }\r\n if (!this.isXPointVisible(x)) {\r\n continue\r\n }\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n labels.push({\r\n text: MONTHS[date.getMonth()] + ' ' + date.getDate().toString().padLeft('00'),\r\n x,\r\n })\r\n }\r\n }\r\n\r\n // Offscreen only - if lastDate !== lastBarDate add tick\r\n if (this.specificChartFunctionality === SpecificChartFunctionality.offScreen) {\r\n const lastDate = `${MONTHS[(~~(this.data.lastDate / 100) % 100) - 1]} ${(this.data.lastDate % 100)\r\n .toString()\r\n .padLeft('00')}` // YYYYMMDD / 20211118 => Nov 18\r\n\r\n if (labels.length > 0 && labels[labels.length - 1].text !== lastDate) {\r\n const barsInDay = this.data.getBarsInDay()!\r\n const barWidth = getBarWidthWithMargin({\r\n zoomFactor: this.model.zoomFactor,\r\n chartLayout: this.model.chart_layout(),\r\n })\r\n const dayWidth = barsInDay * barWidth\r\n x += dayWidth\r\n labels.push({\r\n text: lastDate,\r\n x,\r\n })\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n }\r\n }\r\n\r\n this.renderXAxisLabels({ labels, textRenderer })\r\n }\r\n\r\n renderDailyXAxis({ textRenderer, startBarIndex, endBarIndex }: IRenderXAxisProps) {\r\n let lastMonth = ''\r\n\r\n const labels = []\r\n const xLine = this.getXLine()\r\n for (let i = startBarIndex; i <= endBarIndex; i++) {\r\n const date = utils.dateFromUnixTimestamp(this.data.date[i])\r\n const month = date.getMonth() + '-' + date.getFullYear()\r\n if (month !== lastMonth) {\r\n lastMonth = month\r\n const x = Math.round(this.fx(i) + this.leftOffset)\r\n if (!this.isXPointVisible(x)) {\r\n continue\r\n }\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n labels.push({\r\n hasPriority: date.getMonth() === 0,\r\n text: date.getMonth() === 0 ? date.getFullYear().toString() : MONTHS[date.getMonth()],\r\n x,\r\n })\r\n }\r\n }\r\n this.renderXAxisLabels({ labels, textRenderer })\r\n }\r\n\r\n renderWeeklyXAxis({ textRenderer, startBarIndex, endBarIndex }: IRenderXAxisProps) {\r\n let lastMonth = ''\r\n\r\n const labels = []\r\n const xLine = this.getXLine()\r\n const { Colors } = this.getChartLayoutSettings().ChartSettings.general\r\n for (let i = startBarIndex; i <= endBarIndex; i++) {\r\n const date = utils.dateFromUnixTimestamp(this.data.date[i])\r\n const month = date.getMonth() + '-' + date.getFullYear()\r\n if (month !== lastMonth) {\r\n lastMonth = month\r\n const x = Math.round(this.fx(i) + this.leftOffset)\r\n if (!this.isXPointVisible(x)) {\r\n continue\r\n }\r\n if (date.getMonth() % 3 === 0) {\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n } else {\r\n new Line(\r\n {\r\n x1: x,\r\n x2: x,\r\n y1: 0,\r\n y2: this.height,\r\n strokeStyle: Colors.gridSecondary,\r\n dashLength: 3,\r\n },\r\n this.paneModel\r\n ).render(this.context)\r\n }\r\n const isYearLabel = date.getMonth() === 0\r\n labels.push({\r\n text: isYearLabel ? date.getFullYear().toString().substring(2) : MONTHS[date.getMonth()][0],\r\n hasPriority: isYearLabel,\r\n x,\r\n })\r\n }\r\n }\r\n this.renderXAxisLabels({ labels, textRenderer })\r\n }\r\n\r\n renderMonthlyXAxis({ textRenderer, startBarIndex, endBarIndex }: IRenderXAxisProps) {\r\n let lastYear = null\r\n\r\n const labels = []\r\n const xLine = this.getXLine()\r\n for (let i = startBarIndex; i <= endBarIndex; i++) {\r\n const date = utils.dateFromUnixTimestamp(this.data.date[i])\r\n const year = date.getFullYear()\r\n const isJanuary = date.getMonth() === 0\r\n if (year !== lastYear && (labels.length !== 0 || isJanuary)) {\r\n lastYear = year\r\n const x = Math.round(this.fx(i) + this.leftOffset)\r\n if (!this.isXPointVisible(x)) {\r\n continue\r\n }\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n labels.push({\r\n text: date.getFullYear().toString(),\r\n x,\r\n })\r\n }\r\n }\r\n this.renderXAxisLabels({ labels, textRenderer })\r\n }\r\n\r\n handleIndicatorsChange() {\r\n this.updateShouldRenderVolume()\r\n this.setupCache()\r\n this.trigger('change')\r\n }\r\n\r\n updateShouldRenderVolume() {\r\n this.shouldRenderVolume = !this.model.chart_layout().getIsIndicatorPresent(IndicatorType.Vol)\r\n }\r\n\r\n getVolumeTicks(count: number, maxHeight: number, fontHeight: number): number[] {\r\n const maxCount = 5\r\n const minCount = 1\r\n if (count > maxCount) {\r\n count = maxCount\r\n }\r\n const ticks = this.volumeFY.ticks(count).filter((tick) => tick !== 0)\r\n if (count <= minCount) {\r\n return [ticks[ticks.length - 1]]\r\n }\r\n // ticks are rendered on middle line so we have +- 1/2 of font size above and below range[min,max]\r\n // so we already have +-1 fontsize space, but in some cases that wouldn't be enough so we need to scale\r\n // dynamically, we add 3px of space per tick gap\r\n if (ticks.length * fontHeight + (ticks.length - 1) * 3 > maxHeight) {\r\n return this.getVolumeTicks(count - 1, maxHeight, fontHeight)\r\n }\r\n return ticks\r\n }\r\n\r\n renderVolumeAxis(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n if (getIsSmallIndexChart(this.specificChartFunctionality)) {\r\n context.save()\r\n const relativeVolume = Math.max(0, Math.min(2, this.data.relativeVolume))\r\n\r\n const x = 20\r\n const fy = (y: number) => ChartSettings.top.height + this.height - this.height * (0.5 * y)\r\n const height = this.height * (0.5 * relativeVolume)\r\n\r\n const label = new Text(\r\n {\r\n x: 15,\r\n font: { size: 8 },\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.middle,\r\n textAlign: TextAlign.right,\r\n },\r\n this.paneModel\r\n )\r\n for (let i = 0.5; i <= 2; i += 0.5) {\r\n const y = Math.round(fy(i))\r\n label\r\n .set({\r\n text: i.toFixed(1),\r\n y: y,\r\n })\r\n .render(context)\r\n\r\n context.set('strokeStyle', 'rgb(130, 130, 130)')\r\n context.beginPath()\r\n context.setLineDash([2, 3])\r\n context.translate(0, 0.5)\r\n context.moveTo(x, y)\r\n context.lineTo(x + 7, y)\r\n context.translate(0, -0.5)\r\n context.stroke()\r\n }\r\n\r\n context.set('fillStyle', 'rgba(0, 135, 255, 0.58)')\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', Colors.grid)\r\n context.setLineDash([])\r\n\r\n context.fillRect(x, Math.round(ChartSettings.top.height + this.height - height), 7, Math.round(height))\r\n context.translate(0.5, 0.5)\r\n context.strokeRect(x, ChartSettings.top.height, 7, this.height)\r\n context.translate(-0.5, -0.5)\r\n\r\n new Text(\r\n {\r\n text: 'RELATIVE\\nVOLUME',\r\n x: 33,\r\n y: ChartSettings.top.height + this.height + 6,\r\n font: { size: FONT_SIZE.XXS },\r\n lineHeight: LINE_HEIGHT.XS,\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.top,\r\n textAlign: TextAlign.right,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n context.restore()\r\n return\r\n }\r\n const rangeMax = this.volumeFY.range()[1]\r\n const volumeAxisFontSize = ChartSettings.left.volumeAxis.font.size!\r\n const tickCount = Math.floor(rangeMax / volumeAxisFontSize)\r\n const ticks = this.getVolumeTicks(tickCount, rangeMax, volumeAxisFontSize)\r\n const format = this.volumeFY.tickFormat(4, 's')\r\n const text = new Text(\r\n {\r\n x: ChartSettings.left.volumeAxis.margin.left,\r\n font: Text.getMergedPropsWithDefaults('font', { size: ChartSettings.left.volumeAxis.font.size }),\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.middle,\r\n textAlign: TextAlign.right,\r\n },\r\n this.paneModel\r\n )\r\n ticks.forEach((tick) =>\r\n text\r\n .set({\r\n text: format(tick).replace(/G/, 'B'), // https://github.com/d3/d3-format/blob/master/README.md#locale_formatPrefix\r\n y: ChartSettings.top.height + this.height - this.volumeFY(tick),\r\n })\r\n .render(context)\r\n )\r\n }\r\n\r\n renderVolume() {\r\n if (!this.shouldRenderVolume) return\r\n\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n // Return if the domain bounds are equal, this would put any value in the middle\r\n const [domainFrom, domainTo] = this.volumeFY.domain()\r\n if (this.setupAxisTimeFrame !== this.data.timeframe || domainFrom === domainTo) {\r\n return\r\n }\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width,\r\n yOffset: ChartSettings.top.height + this.height - 59,\r\n })\r\n translate.do()\r\n const halfBarWidth = getHalfBarWidth(this.model)\r\n const barWidthWithoutMargin = getBarWithoutMarginWidth(this.model)\r\n drawInVisibleArea({\r\n quote: this.data,\r\n paneModel: this.paneModel,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i, x) => {\r\n // Skip render if the value is <= 0\r\n if (this.data.volume[i] <= 0) {\r\n return\r\n }\r\n\r\n this.context.fillStyle = this.data.close[i] < this.data.open[i] ? Colors.volumeTrendDown : Colors.volumeTrendUp\r\n const y = Math.round(this.volumeFY(this.data.volume[i]))\r\n this.context.fillRect(x - halfBarWidth, 60, barWidthWithoutMargin, -y)\r\n },\r\n })\r\n translate.undo()\r\n }\r\n\r\n renderOverlays() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width,\r\n yOffset: ChartSettings.top.height,\r\n })\r\n translate.do()\r\n for (const overlay of this.overlays) {\r\n overlay.renderContent(this.context)\r\n }\r\n translate.undo()\r\n }\r\n\r\n renderCross(context: CanvasRenderingContext2D) {\r\n const isRendered = renderCross({\r\n context,\r\n mouseModel,\r\n paneModel: this.paneModel,\r\n contentWidth: this.width,\r\n contentHeight: this.height,\r\n quote: this.data,\r\n getRoundDecimalPlaces: (price) => this.getPlacesLastClose(price),\r\n onRenderCrossText: !this.getIsRedesignedChart() ? this.renderCrossText : undefined,\r\n })\r\n if (this.getIsRedesignedChart()) {\r\n this.renderCrossText(context, mouseModel.getCrossIndexForPane(this.paneModel))\r\n }\r\n\r\n if (isRendered !== undefined) {\r\n setElementCursor({\r\n elementId: this.model.chart_layout().getHTMLElementId(),\r\n cursor: isRendered ? 'crosshair' : 'default',\r\n conditionalCursor: 'grabbing',\r\n })\r\n }\r\n }\r\n\r\n getDataByCrossIndex(crossIndex: number, key: keyof Quote, shouldReturnRoundedString = true) {\r\n const n = this.data.getDataByBarIndex(key, crossIndex)\r\n if (n !== null) {\r\n return shouldReturnRoundedString ? this.roundOhlc(n) : `${n}`\r\n }\r\n }\r\n\r\n getCrossIndexChange(crossIndex: number) {\r\n const crossDataIndex = this.data.getDataIndexByBarIndex(crossIndex)\r\n const crossClose = this.data.close[crossDataIndex] ?? null\r\n const previousClose = this.data.close[crossDataIndex - 1] ?? null\r\n if (crossClose !== null && previousClose !== null) {\r\n return getTickerChangeFromCloseValues({ data: this.data, anchorClose: crossClose, prevClose: previousClose })\r\n }\r\n\r\n return null\r\n }\r\n\r\n renderCrossText(context: CanvasRenderingContext2D, crossIndex: number) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n context.save()\r\n context.translate(ChartSettings.left.width, 0)\r\n\r\n if (this.getIsRedesignedChart()) {\r\n this.renderOverlaysLabels(context)\r\n if (Number.isNaN(crossIndex)) {\r\n this.getOHLC({ context })\r\n context.restore()\r\n return\r\n }\r\n }\r\n\r\n const dateByBarIndex = this.data.getDataByBarIndex('date', crossIndex)\r\n const date = dateByBarIndex ? utils.dateFromUnixTimestamp(dateByBarIndex) : null\r\n\r\n if (date === null) {\r\n const virtualTradedDates =\r\n this.data.date.length > 0\r\n ? getVirtualTimeframeTradedDates({\r\n dateStart: this.data.date[0],\r\n dateEnd: this.data.date[this.data.date.length - 1],\r\n quote: this.data,\r\n })\r\n : []\r\n this.getOHLC({\r\n context,\r\n dateString: virtualTradedDates[crossIndex]\r\n ? getDateString({\r\n date: utils.dateFromUnixTimestamp(virtualTradedDates[crossIndex]),\r\n timeframe: this.data.timeframe,\r\n })\r\n : null,\r\n })\r\n context.restore()\r\n return\r\n }\r\n\r\n this.getOHLC({\r\n context,\r\n date,\r\n data: {\r\n open: this.getDataByCrossIndex(crossIndex, 'open'),\r\n high: this.getDataByCrossIndex(crossIndex, 'high'),\r\n low: this.getDataByCrossIndex(crossIndex, 'low'),\r\n close: this.getDataByCrossIndex(crossIndex, 'close'),\r\n volume: this.getDataByCrossIndex(crossIndex, 'volume', false),\r\n },\r\n changePercentage: this.getCrossIndexChange(crossIndex),\r\n })\r\n\r\n context.restore()\r\n }\r\n\r\n renderChange({ context }: { context: CanvasRenderingContext2D }) {\r\n const CHANGE_SPACER = 10\r\n const { ChartSettings, isOurSiteRequest } = this.getChartLayoutSettings()\r\n const { ticker, change, ohlc } = ChartSettings.top\r\n const { tickerChange, tickerAfterChange } = getTickerChange({ data: this.data })\r\n\r\n if (!tickerChange) {\r\n return\r\n }\r\n\r\n const isOffscreen = this.specificChartFunctionality === SpecificChartFunctionality.offScreen\r\n const isGroupInstrument = this.data.instrument === Instrument.Group\r\n const finvizWatermarkOffset = !isOffscreen || isOurSiteRequest || this.isLargeChart ? 0 : 15\r\n const changeText = new Text(\r\n {\r\n text: isOffscreen && isGroupInstrument ? tickerChange.percentString : tickerChange.string,\r\n x: !getIsSmallIndexChart(this.specificChartFunctionality)\r\n ? this.width - ChartSettings.top.change.margin.right! - finvizWatermarkOffset\r\n : this.width,\r\n y: ChartSettings.top.change.margin.top,\r\n font: Text.getMergedPropsWithDefaults('font', ChartSettings.top.change.font),\r\n textAlign: TextAlign.right,\r\n textBaseline: ChartSettings.top.baseline,\r\n fillStyle: getChangeColor({ change: tickerChange.points, ChartSettings }),\r\n },\r\n this.paneModel\r\n )\r\n this.changeWidth = changeText.measure(context)\r\n changeText.render(context)\r\n\r\n if (isOffscreen && (!this.isLargeChart || isGroupInstrument)) {\r\n return\r\n }\r\n if (tickerAfterChange) {\r\n const afterChangeText = new Text(\r\n {\r\n text: tickerAfterChange?.string,\r\n font: Text.getMergedPropsWithDefaults('font', ChartSettings.top.change.font),\r\n textAlign: TextAlign.right,\r\n textBaseline: ChartSettings.top.baseline,\r\n fillStyle: getChangeColor({ change: tickerAfterChange.points, ChartSettings }),\r\n },\r\n this.paneModel\r\n )\r\n const afterChangeTextWidth = afterChangeText.measure(context)\r\n const oneLineAHChangeWidth = this.changeWidth + CHANGE_SPACER + afterChangeTextWidth\r\n\r\n if (\r\n ChartSettings.left.width + this.tickerWidth + ticker.margin.left! + OFFSET.S <\r\n ChartSettings.left.width + this.width - oneLineAHChangeWidth - change.margin.right!\r\n ) {\r\n afterChangeText\r\n .set({\r\n x: this.width - ChartSettings.top.change.margin.right! - this.changeWidth - CHANGE_SPACER,\r\n y: ChartSettings.top.change.margin.top,\r\n })\r\n .render(context)\r\n this.afterChange = null\r\n this.changeWidth = oneLineAHChangeWidth\r\n } else if (\r\n this.lastOhlc[0] &&\r\n ChartSettings.left.width +\r\n this.tickerWidth +\r\n ticker.margin.left! +\r\n this.lastOhlc[0].width! +\r\n ohlc.margin.left! +\r\n ohlc.margin.right! <\r\n ChartSettings.left.width + this.width - afterChangeTextWidth - change.margin.right!\r\n ) {\r\n afterChangeText\r\n .set({\r\n x: this.width - ChartSettings.top.change.margin.right!,\r\n y: ChartSettings.top.change.margin.top! - ChartSettings.top.change.font.size! - OFFSET.S,\r\n })\r\n .render(context)\r\n this.changeWidth = Math.max(this.changeWidth, afterChangeTextWidth)\r\n this.afterChange = {\r\n x: this.width - ChartSettings.top.change.margin.right!,\r\n y: ChartSettings.top.change.margin.top! - ChartSettings.top.change.font.size! - OFFSET.S,\r\n width: afterChangeTextWidth,\r\n }\r\n }\r\n }\r\n }\r\n\r\n renderOHLC(parameters: IRenderOHLCParameters) {\r\n if (!this.getIsRedesignedChart()) {\r\n this.renderOHLCQuotePage(parameters)\r\n } else {\r\n this.renderOHLCChartsPage(parameters)\r\n }\r\n }\r\n\r\n renderOHLCChartsPage({ context, date, open, high, low, close, volume, changePercentage }: IRenderOHLCParameters) {\r\n const chartBreakpoints = getChartBreakpoints(this.width)\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n\r\n const OhlcText = new Text(\r\n {\r\n font: { size: FONT_SIZE.S },\r\n lineHeight: 18,\r\n fillStyle: Colors.text,\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.middle,\r\n background: getHEXWithSpecificAplha(Colors.canvasFill, 0.8),\r\n },\r\n this.paneModel\r\n )\r\n\r\n const dateElements = date ? [{ text: date, color: gray300 }] : []\r\n const trendColor = (open ?? 0) > (close ?? 0) ? tailwindColors.red[400] : tailwindColors.green[400]\r\n const oElements = open\r\n ? [\r\n { text: 'O', color: gray300 },\r\n { text: open, color: trendColor },\r\n ]\r\n : []\r\n const hElements = high\r\n ? [\r\n { text: 'H', color: gray300 },\r\n { text: high, color: trendColor },\r\n ]\r\n : []\r\n const lElements = low\r\n ? [\r\n { text: 'L', color: gray300 },\r\n { text: low, color: trendColor },\r\n ]\r\n : []\r\n const cElements = close\r\n ? [\r\n { text: 'C', color: gray300 },\r\n { text: close, color: trendColor },\r\n ]\r\n : []\r\n const volElements = volume\r\n ? [\r\n { text: 'Vol', color: gray300 },\r\n { text: volume, color: trendColor },\r\n ]\r\n : []\r\n const changeElements = changePercentage != null ? [{ text: changePercentage.string, color: trendColor }] : []\r\n\r\n const lines: OhlcLineElements[] = []\r\n\r\n const getFlatLineArrayWithSpaces = (lineElements: OhlcLineElements[]) =>\r\n lineElements.flatMap((elements, index) =>\r\n index > 0 ? ([...(elements.length > 0 ? ['space'] : []), ...elements] as OhlcLineElements) : elements\r\n )\r\n if (chartBreakpoints.isM) {\r\n lines.push(\r\n getFlatLineArrayWithSpaces([\r\n dateElements,\r\n oElements,\r\n hElements,\r\n lElements,\r\n cElements,\r\n volElements,\r\n changeElements,\r\n ])\r\n )\r\n } else if (chartBreakpoints.isS) {\r\n lines.push(getFlatLineArrayWithSpaces([dateElements, changeElements]))\r\n lines.push(getFlatLineArrayWithSpaces([oElements, hElements, lElements, cElements, volElements]))\r\n } else {\r\n lines.push(getFlatLineArrayWithSpaces([dateElements, volElements, changeElements]))\r\n lines.push(getFlatLineArrayWithSpaces([oElements, hElements, lElements, cElements]))\r\n }\r\n\r\n const startX = OFFSET.M - ChartSettings.left.width\r\n let x = startX\r\n let y = OFFSET.M + OhlcText.attrs.lineHeight / 2\r\n\r\n lines.forEach((line) => {\r\n x = startX\r\n line.forEach((lineElement, index, lineElements) => {\r\n const padding = { left: 1, right: 1, top: 0, bottom: 0 }\r\n const { text = '', color = undefined } = lineElement === 'space' ? {} : lineElement\r\n if (index === 0) {\r\n padding.left = 5\r\n } else if (index === lineElements.length - 1) {\r\n padding.right = 5\r\n } else if (lineElement === 'space') {\r\n padding.left = 7\r\n padding.right = 7\r\n if (!chartBreakpoints.isS) {\r\n padding.left = 5\r\n padding.right = 5\r\n }\r\n }\r\n OhlcText.set({ text, fillStyle: color, x, y, padding })\r\n OhlcText.render(context)\r\n x += OhlcText.width\r\n })\r\n y += OhlcText.attrs.lineHeight\r\n })\r\n }\r\n\r\n renderOverlaysLabelsChartsPage(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const chartBreakpoints = getChartBreakpoints(this.width)\r\n const LabelsText = new Text(\r\n {\r\n font: { size: FONT_SIZE.S },\r\n lineHeight: 18,\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.middle,\r\n background: getHEXWithSpecificAplha(ChartSettings.general.Colors.canvasFill, 0.8),\r\n // this function gets (indirectly) called from renderCrossText which is already \"translateX\" by ChartSettings.left.width\r\n x: OFFSET.M - ChartSettings.left.width,\r\n padding: { left: PADDING.S, right: PADDING.S, top: 0, bottom: 0 },\r\n },\r\n this.paneModel\r\n )\r\n\r\n let numberOfNewOhlcLines = 2\r\n if (chartBreakpoints.isM) {\r\n numberOfNewOhlcLines = 1\r\n } else if (chartBreakpoints.isS) {\r\n numberOfNewOhlcLines = 2\r\n }\r\n\r\n // We assume lineheight is the same as OHLC text\r\n const { lineHeight } = LabelsText.attrs\r\n let y = lineHeight * numberOfNewOhlcLines + lineHeight / 2 + OFFSET.M\r\n\r\n for (const overlay of this.overlays) {\r\n if (!overlay.isRenderedOverlaysLabel()) {\r\n continue\r\n }\r\n LabelsText.set({\r\n text: overlay.toString(),\r\n y,\r\n fillStyle: overlay.getLabelColor(),\r\n }).render(context)\r\n y += lineHeight\r\n }\r\n }\r\n\r\n renderOHLCQuotePage({\r\n context,\r\n date,\r\n open,\r\n high,\r\n low,\r\n close,\r\n volume,\r\n afterHour,\r\n isSmallIndexChart = false,\r\n isNewestOHLC = false,\r\n time,\r\n directRender = false,\r\n changePercentage,\r\n }: IRenderOHLCParameters) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const { ohlc } = ChartSettings.top\r\n const isOffscreen = this.specificChartFunctionality === SpecificChartFunctionality.offScreen\r\n const isGroupInstrument = this.data.instrument === Instrument.Group\r\n if (isOffscreen && isGroupInstrument) {\r\n ohlc.type = OHLCType.dateOnly\r\n } else if (isOffscreen && this.data.instrument !== Instrument.Stock && time) {\r\n ohlc.type = OHLCType.timeOnly\r\n }\r\n\r\n const lineTopY = ohlc.type ? ohlc.margin.top : ohlc.margin.top! - ChartSettings.top.ticker.font.size!\r\n const OHLCFontSize = ohlc.font.size!\r\n const centerXOffset =\r\n this.tickerWidth +\r\n ChartSettings.top.ticker.margin.left! +\r\n (this.width -\r\n (this.tickerWidth +\r\n ChartSettings.top.ticker.margin.left! +\r\n this.changeWidth +\r\n (isSmallIndexChart ? 0 : ChartSettings.top.change.margin.right!))) / // smallIndexChart don't have change.margin.right\r\n 2\r\n const leftXOffset = this.tickerWidth + ChartSettings.top.ticker.margin.left! + ohlc.margin.left!\r\n const hasOhlc = ![open, high, low, close, volume].some((ohlcString) => !ohlcString)\r\n const OHLC = hasOhlc\r\n ? {\r\n date: [date ?? ''],\r\n singleLine: [\r\n `${date} O:${open} H:${high} L:${low} C:${close}${\r\n afterHour ? ` AH:${afterHour}` : ''\r\n } Vol:${volume} `,\r\n /*\r\n * this is needed because of the way we render ohlc text down below in renderOHLCToCanvas\r\n * undefined is used instead of null because TS had some issues with `null` even if it is filtered out\r\n * */\r\n changePercentage ? changePercentage.string : undefined,\r\n ].filter((value) => value !== undefined),\r\n }\r\n : {\r\n date: [date ?? ''],\r\n singleLine: [`${date ?? ''}`],\r\n }\r\n\r\n const OHLC_TEXT = new Text(\r\n {\r\n font: { size: OHLCFontSize },\r\n },\r\n this.paneModel\r\n )\r\n\r\n const getOHLCType = () => {\r\n if (!isSmallIndexChart) {\r\n return OHLCType.singleLine\r\n }\r\n return OHLCType.dateOnly\r\n }\r\n\r\n const getOHLCSettings = () => {\r\n switch (ohlc.type || getOHLCType()) {\r\n case OHLCType.singleLine:\r\n return {\r\n text: OHLC.singleLine,\r\n x: [leftXOffset, leftXOffset],\r\n y: [ohlc.margin.top],\r\n textAlign: TextAlign.left,\r\n textBaseline: [TextBaseline.alphabetic],\r\n }\r\n case OHLCType.dateOnly:\r\n if (isOffscreen && isGroupInstrument) {\r\n const text = `${OHLC.date} Volume: ${volume}`\r\n const textWidth = OHLC_TEXT.set({ text }).measure(context)\r\n return {\r\n text: [text],\r\n x: [\r\n this.width - ChartSettings.top.change.margin.right! - this.changeWidth - textWidth - CHART_MARGIN.XXL,\r\n ],\r\n y: [ohlc.margin.top],\r\n textAlign: TextAlign.center,\r\n textBaseline: [TextBaseline.alphabetic],\r\n }\r\n } else if (isSmallIndexChart) {\r\n return {\r\n text: OHLC.date,\r\n x: [centerXOffset],\r\n y: [ohlc.margin.top],\r\n textAlign: TextAlign.center,\r\n textBaseline: [TextBaseline.alphabetic],\r\n }\r\n } else {\r\n const isEnoughSpace =\r\n this.width -\r\n (this.tickerWidth +\r\n ChartSettings.top.ticker.margin.left! +\r\n ohlc.margin.left! +\r\n ohlc.margin.right! +\r\n this.changeWidth +\r\n ChartSettings.top.change.margin.right!) >\r\n OHLC_TEXT.set({ text: OHLC.date[0] }).measure(context)\r\n const alignTop = !isEnoughSpace || ohlc.font.baseline === TextBaseline.top\r\n return {\r\n text: OHLC.date,\r\n x: [leftXOffset],\r\n y: alignTop ? [lineTopY] : [ohlc.margin.top],\r\n textAlign: TextAlign.left,\r\n textBaseline: alignTop ? [TextBaseline.top] : [TextBaseline.alphabetic],\r\n }\r\n }\r\n case OHLCType.timeOnly:\r\n return {\r\n text: [time],\r\n x: [centerXOffset - OHLC_TEXT.set({ text: time }).measure(context) / 2],\r\n y: [lineTopY],\r\n textAlign: TextAlign.center,\r\n textBaseline: [ohlc.font.baseline],\r\n }\r\n default:\r\n return\r\n }\r\n }\r\n\r\n if (!isNewestOHLC) {\r\n context.fillStyle = Colors.canvasFill\r\n this.lastOhlc.forEach((line) => {\r\n const x = (line.textAlign === TextAlign.left ? line.x : line.x! - line.width! / 2)!\r\n const y = (line.textBaseline === TextBaseline.top ? line.y : line.y! - OHLCFontSize)!\r\n context.fillRect(\r\n x - PADDING.XXS,\r\n y - PADDING.XXS,\r\n PADDING.XXS + line.width! + PADDING.XXS,\r\n PADDING.XXS + OHLCFontSize + PADDING.XXS\r\n )\r\n })\r\n\r\n if (this.afterChange) {\r\n context.fillRect(\r\n this.afterChange.x - this.afterChange.width - PADDING.XXS,\r\n this.afterChange.y - ChartSettings.top.change.font.size! - PADDING.XXS,\r\n PADDING.XXS + this.afterChange.width + PADDING.XXS,\r\n PADDING.XXS + ChartSettings.top.change.font.size! + PADDING.XS\r\n )\r\n }\r\n } else {\r\n this.lastOhlc = []\r\n }\r\n\r\n const ohlcSettings = getOHLCSettings()\r\n\r\n const renderOHLCToCanvas = ({\r\n ohlcSet,\r\n render = true,\r\n }: {\r\n ohlcSet?: {\r\n text: (string | undefined)[]\r\n x: number[]\r\n y: (number | undefined)[]\r\n textAlign: TextAlign\r\n textBaseline: (TextBaseline | undefined)[]\r\n }\r\n render?: boolean\r\n }) => {\r\n const isSingleLineWithChange = (ohlc.type || getOHLCType()) === OHLCType.singleLine && changePercentage\r\n ohlcSet?.text.forEach((line: string | undefined, index: number) => {\r\n let i = index\r\n let leftOffset = 0\r\n let fillStyle = Colors.text\r\n let text = line\r\n if (index > 0 && isSingleLineWithChange) {\r\n i -= 1\r\n leftOffset = OHLC_TEXT.measure(context)\r\n text = line\r\n\r\n fillStyle = getChangeColor({ change: changePercentage.points, ChartSettings })\r\n }\r\n const options = {\r\n text,\r\n x: ohlcSet.x[i] + leftOffset,\r\n y: ohlcSet.y[i],\r\n textBaseline: ohlc.font.baseline ? ohlc.font.baseline : ohlcSet.textBaseline[i],\r\n textAlign: ohlc.font.textAlign ? ohlc.font.textAlign : ohlcSet.textAlign,\r\n fillStyle,\r\n }\r\n OHLC_TEXT.set(options)\r\n if (isNewestOHLC) {\r\n this.lastOhlc[i] = { width: OHLC_TEXT.measure(context), ...options }\r\n }\r\n if (render) {\r\n OHLC_TEXT.render(context)\r\n }\r\n })\r\n }\r\n renderOHLCToCanvas({ ohlcSet: ohlcSettings, render: directRender })\r\n\r\n return {\r\n ohlcSettings,\r\n renderOHLCToCanvas,\r\n }\r\n }\r\n\r\n // only for stocks on i1/i3/i5 and one day view\r\n renderFadeExtendedHours() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const period = this.model.quote().timeframe\r\n if (this.data.instrument !== Instrument.Stock) {\r\n return\r\n }\r\n if (![TIMEFRAME.i1, TIMEFRAME.i2, TIMEFRAME.i3, TIMEFRAME.i5].includes(period)) {\r\n return\r\n }\r\n\r\n const interval = parseInt(period.substring(1), 10)\r\n const dayToOffset = this.data.getDayToOffset()\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width,\r\n yOffset: ChartSettings.top.height,\r\n })\r\n translate.do()\r\n const halfBarWidth = getHalfBarWidth(this.model)\r\n for (const day in dayToOffset) {\r\n // todo aftermarket\r\n const dayIndex = dayToOffset[day]\r\n let n0 = (this.data.drawMinutesPerDay / interval) * dayIndex\r\n let n1 = this.data.premarketLengthMinutes / interval + n0 // bars in 90mins from 8am to 9:30am\r\n let x0 = this.paneModel.scale.x(n0) - halfBarWidth\r\n let width = this.paneModel.scale.x(n1) - this.paneModel.scale.x(n0)\r\n this.context.set('fillStyle', Colors.premarketFade)\r\n this.context.fillRect(x0, 0, width, this.height + 1)\r\n\r\n if (this.data.aftermarketLengthMinutes > 0) {\r\n n0 =\r\n (this.data.drawMinutesPerDay / interval) * dayIndex +\r\n (this.data.drawMinutesPerDay - this.data.aftermarketLengthMinutes) / interval\r\n n1 = this.data.aftermarketLengthMinutes / interval + n0 // bars in 90mins from 4pm to 5:30pm\r\n x0 = this.paneModel.scale.x(n0) - halfBarWidth\r\n width = this.paneModel.scale.x(n1) - this.paneModel.scale.x(n0)\r\n\r\n this.context.set('fillStyle', Colors.aftermarketFade)\r\n this.context.fillRect(x0, 0, width, this.height + 1)\r\n }\r\n }\r\n translate.undo()\r\n }\r\n\r\n shouldShowPrevClose() {\r\n const quote = this.model.quote()\r\n const isStock = quote.instrument === Instrument.Stock\r\n const isIntradayWithPreMarket = TIMEFRAMES_WITH_PRE_MARKET.includes(quote.timeframe)\r\n const isIndexChart = this.specificChartFunctionality === SpecificChartFunctionality.smallIndex\r\n\r\n return isStock && (isIntradayWithPreMarket || isIndexChart)\r\n }\r\n\r\n renderPrevClose() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n if (!this.shouldShowPrevClose()) {\r\n return\r\n }\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: ChartSettings.left.width,\r\n yOffset: ChartSettings.top.height,\r\n })\r\n translate.do()\r\n\r\n let y = Math.round(this.fy(this.model.quote().prevClose))\r\n if (y === this.height) y -= 1 // due pixel perfect rendering of lines, line on bottom edge is moved outside of \"chart area\" because of 0.5px translate, to compensate for this we subtract 1px\r\n\r\n new Line(\r\n {\r\n x1: 0,\r\n x2: this.width,\r\n y1: y,\r\n y2: y,\r\n strokeStyle: Colors.prevClose,\r\n dashLength: 3,\r\n },\r\n this.paneModel\r\n ).render(this.context)\r\n translate.undo()\r\n }\r\n\r\n renderChartNotAvailable() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const x = ~~((ChartSettings.left.width + ChartSettings.right.width + this.width) / 2)\r\n const y = ~~((ChartSettings.top.height + ChartSettings.bottom.height + this.height) / 2)\r\n new Text(\r\n {\r\n text: 'Chart not available',\r\n x,\r\n y,\r\n font: { size: FONT_SIZE.M, style: 'bold' },\r\n fillStyle: Colors.text,\r\n textAlign: TextAlign.center,\r\n textBaseline: TextBaseline.middle,\r\n },\r\n this.paneModel\r\n ).render(this.context)\r\n }\r\n\r\n // private\r\n setupCache() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n /*\r\n * Don't create new Cache instances, because Safari takes too long to free up memory\r\n * leading to canvas.getContext returning null. https://stackoverflow.com/questions/52532614/total-canvas-memory-use-exceeds-the-maximum-limit-safari-12\r\n *\r\n * To further improve performance, cache.set shouldn't be called when unnecessary,\r\n * because setupCache is called for many model updates. The same applies for indicators/indicator.js.\r\n */\r\n this.baseCache = this.baseCache || new Cache()\r\n\r\n this.baseCache.set(\r\n (context: CanvasRenderingContext2D) => {\r\n if (this.data.close.length === 0) {\r\n this.renderText(context)\r\n return\r\n }\r\n this.renderYAxis(context)\r\n this.renderText(context)\r\n if (!this.getIsMobileChartPage() && this.shouldRenderVolume) {\r\n this.renderVolumeAxis(context)\r\n }\r\n if (!this.getIsRedesignedChart()) {\r\n this.renderOverlaysLabels(context)\r\n }\r\n },\r\n this.width + ChartSettings.left.width + ChartSettings.right.width,\r\n this.height + ChartSettings.top.height + ChartSettings.bottom.height\r\n )\r\n }\r\n\r\n // called by controllers/pane on recountScale\r\n setupAxis(fx: ScaleAxis) {\r\n this.data = this.model.quote()\r\n const { volumeHeight } = this.getChartLayoutSettings().ChartSettings.center\r\n\r\n if (typeof fx !== 'function') {\r\n return\r\n }\r\n\r\n const firstBarToRenderIndex = getVisibleBarToRenderIndex({\r\n leftOffset: this.model.leftOffset,\r\n paneModel: this.paneModel,\r\n quote: this.data,\r\n })\r\n\r\n const lastBarToRenderIndex = getVisibleBarToRenderIndex({\r\n leftOffset: this.model.leftOffset,\r\n paneModel: this.paneModel,\r\n quote: this.data,\r\n chartWidth: this.width,\r\n })\r\n\r\n const areNoBarsVisible = getAreNoBarsVisible(firstBarToRenderIndex, lastBarToRenderIndex)\r\n\r\n const volumes = []\r\n if (areNoBarsVisible) {\r\n volumes.push(\r\n this.data.volume[firstBarToRenderIndex.index],\r\n Math.min(lastBarToRenderIndex.index, this.data.barIndex.length - 1)\r\n )\r\n } else {\r\n for (let i = firstBarToRenderIndex.index; i <= lastBarToRenderIndex.index; i++) {\r\n volumes.push(this.data.volume[i])\r\n }\r\n }\r\n\r\n const max = utils.max(volumes) ?? 0\r\n const rangeMax = volumeHeight || 60\r\n this.volumeFY = d3.scaleLinear().range([0, rangeMax]).domain([0, max]).nice(4)\r\n this.setupAxisTimeFrame = this.data.timeframe\r\n }\r\n\r\n // private\r\n clip(addMarginBottom?: boolean) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n if (addMarginBottom == null) {\r\n addMarginBottom = false\r\n }\r\n this.context.beginPath()\r\n let marginBottom = 0\r\n if (addMarginBottom) {\r\n marginBottom = ChartSettings.bottom.height\r\n }\r\n // due pixel perfect rendering of lines, line on bottom edge is moved outside of \"chart area\" because of 0.5px translate,\r\n // to compensate for this we clip canvas 1px taller than chart height\r\n this.context.rect(ChartSettings.left.width, ChartSettings.top.height, this.width, this.height + marginBottom + 1)\r\n this.context.clip()\r\n }\r\n\r\n addOverlay(overlay: Overlay) {\r\n overlay.chart = this\r\n this.overlays.push(overlay)\r\n return this.trigger('change')\r\n }\r\n\r\n setOverlays(overlays: Overlay[]) {\r\n this.overlays = overlays\r\n return this.trigger('change')\r\n }\r\n\r\n removeOverlay(overlay: Overlay) {\r\n for (let index = 0; index < this.overlays.length; index++) {\r\n const el = this.overlays[index]\r\n if (el === overlay) {\r\n this.attrs.overlays.splice(index, 1)\r\n this.overlays.splice(index, 1)\r\n this.trigger('change')\r\n break\r\n }\r\n }\r\n }\r\n\r\n getMinMax(): { min: number; max: number; firstVisibleClose?: number | null } {\r\n this.data = this.model.quote()\r\n let min = Number.MAX_VALUE\r\n let max = Number.MIN_VALUE\r\n let minIndex = -1\r\n let maxIndex = -1\r\n let firstVisibleClose = null\r\n\r\n const firstBarToRenderIndex = getVisibleBarToRenderIndex({\r\n leftOffset: this.model.leftOffset,\r\n paneModel: this.paneModel,\r\n quote: this.data,\r\n })\r\n const lastBarToRenderIndex = getVisibleBarToRenderIndex({\r\n leftOffset: this.model.leftOffset,\r\n paneModel: this.paneModel,\r\n quote: this.data,\r\n chartWidth: this.width,\r\n })\r\n\r\n const areNoBarsVisible = getAreNoBarsVisible(firstBarToRenderIndex, lastBarToRenderIndex)\r\n\r\n // If no bars are visible min/max are first available bar before visible and first after\r\n if (areNoBarsVisible) {\r\n min = this.data.low[firstBarToRenderIndex.index]\r\n max = this.data.high[Math.min(lastBarToRenderIndex.index, this.data.barIndex.length - 1)]\r\n if (min > max) {\r\n const prevMin = min\r\n min = max\r\n max = prevMin\r\n }\r\n firstVisibleClose = this.data.close[firstBarToRenderIndex.index]\r\n } else {\r\n for (let i = firstBarToRenderIndex.index; i <= lastBarToRenderIndex.index; i++) {\r\n if (minIndex === -1 || this.data.low[minIndex] > this.data.low[i]) {\r\n minIndex = i\r\n }\r\n if (maxIndex === -1 || this.data.high[maxIndex] < this.data.high[i]) {\r\n maxIndex = i\r\n }\r\n }\r\n\r\n // If only a single bar is visible get min/max index range from closes values outside of visible area\r\n if (this.data.low[minIndex] === this.data.high[maxIndex]) {\r\n const closestMinMaxIndices = getClosestDifferentMinMaxValueIndices(\r\n minIndex,\r\n maxIndex,\r\n this.data.high,\r\n this.data.low\r\n )\r\n minIndex = closestMinMaxIndices.minIndex\r\n maxIndex = closestMinMaxIndices.maxIndex\r\n }\r\n\r\n min = this.data.low[minIndex]\r\n max = this.data.high[maxIndex]\r\n\r\n firstVisibleClose = this.data.close[firstBarToRenderIndex.index]\r\n }\r\n\r\n // Apply scale min & max buffer if min/max is the same\r\n if (min === max) {\r\n min *= 0.99\r\n max *= 1.01\r\n }\r\n\r\n // Update min/max so prevClose is in range and can be rendered if it should\r\n if (this.shouldShowPrevClose() && this.data.prevClose !== null) {\r\n min = Math.min(min, this.data.prevClose)\r\n max = Math.max(max, this.data.prevClose)\r\n }\r\n\r\n // Update min/max so lastClose is in range and can be rendered if it should\r\n if (this.specificChartFunctionality === SpecificChartFunctionality.offScreen && !this.model.dateRange) {\r\n min = Math.min(min, this.data.lastClose)\r\n max = Math.max(max, this.data.lastClose)\r\n }\r\n\r\n return { min, max, firstVisibleClose }\r\n }\r\n\r\n moveBy() {}\r\n\r\n isInArea() {\r\n return false\r\n }\r\n\r\n fx = (x: number) => this.paneModel.scale.x(this.data.barIndex[x])\r\n\r\n fy = (y: number) => this.paneModel.scale.y(y)\r\n\r\n round(n: number, overridePlaces?: number) {\r\n return round({ data: this.data, num: n, overridePlaces: overridePlaces ?? this.getPlacesLastClose() })\r\n }\r\n\r\n roundOhlc(n: number) {\r\n const placesLastClose = this.getPlacesLastClose()\r\n return round({\r\n data: this.data,\r\n num: n,\r\n overridePlaces: placesLastClose ? Math.max(placesLastClose, 2) : undefined,\r\n })\r\n }\r\n\r\n toObject() {\r\n const overlays = this.overlays.map((overlay) => overlay.toObject())\r\n return merge({}, this.attrs, { type: this.type, overlays })\r\n }\r\n\r\n toConfig() {\r\n const overlays = this.overlays.map((overlay) => overlay.toConfig())\r\n return merge({}, this.attrs, { type: this.type, overlays })\r\n }\r\n\r\n getPlacesLastClose(price?: number) {\r\n const { lastClose, instrument } = this.data\r\n const priceAbs = price && Math.abs(price)\r\n if (lastClose >= 100000) {\r\n return 0\r\n } else if (lastClose >= 10000) {\r\n return 1\r\n } else if (instrument === Instrument.Stock && (priceAbs ?? lastClose) < 1) {\r\n return 4\r\n } else if (lastClose === undefined) {\r\n // if lastClose is not defined we'll always display 2 decimpal places, e.g. backtests, screener stats\r\n return 2\r\n }\r\n\r\n return undefined\r\n }\r\n\r\n hasOverlay(type: string) {\r\n return this.overlays.some((x) => x.type === 'overlays/' + type)\r\n }\r\n\r\n getXLine(): Line {\r\n return new Line(\r\n {\r\n y1: 0,\r\n y2: this.height,\r\n strokeStyle: this.getChartLayoutSettings().ChartSettings.general.Colors.grid,\r\n dashLength: 3,\r\n },\r\n this.paneModel\r\n )\r\n }\r\n\r\n getYLine(): Line {\r\n return new Line(\r\n {\r\n x1: 0,\r\n x2: this.width,\r\n strokeStyle: this.getChartLayoutSettings().ChartSettings.general.Colors.grid,\r\n dashLength: 3,\r\n },\r\n this.paneModel\r\n )\r\n }\r\n\r\n getChartLayoutSettings() {\r\n return getChartLayoutSettings(this.model.chart_layout())\r\n }\r\n\r\n getIsMobileChartPage() {\r\n return (\r\n this.isMobile && this.model.chart_layout().specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n )\r\n }\r\n\r\n getCandleLikeChartsRenderingColors() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const { theme, specificChartFunctionality } = this.model.chart_layout()\r\n let colors = Colors\r\n const overwrittenColors = getColorOverwrites({\r\n colors,\r\n theme,\r\n })\r\n const overwrittenColorKeys = Object.keys(overwrittenColors)\r\n const hasOverwrittenCandleColor = ['borderUp', 'wickUp', 'borderDown', 'wickDown', 'trendUp', 'trendDown'].some(\r\n (colorKey) => overwrittenColorKeys.includes(colorKey)\r\n )\r\n\r\n const shouldUseDarkerColors =\r\n theme === Theme.light &&\r\n getShouldUseDarkerWickColors({\r\n specificChartFunctionality: specificChartFunctionality,\r\n totalBarWidth: ChartSettings.center.barWidth + ChartSettings.center.border * 2,\r\n })\r\n\r\n if (shouldUseDarkerColors && !hasOverwrittenCandleColor) {\r\n colors = { ...colors, ...darkerWickColors }\r\n }\r\n const isNodeChartWithThinBars =\r\n specificChartFunctionality === SpecificChartFunctionality.offScreen && ChartSettings.center.border === 0\r\n if (isNodeChartWithThinBars && !hasOverwrittenCandleColor) {\r\n colors = { ...colors, ...thinBarColorsOverride, ...overwrittenColors }\r\n }\r\n\r\n return colors\r\n }\r\n\r\n getIsRedesignedChart() {\r\n return this.specificChartFunctionality === SpecificChartFunctionality.chartPage || isRedesignedPage(this)\r\n }\r\n}\r\n\r\nBaseChart.initClass()\r\n\r\nexport default BaseChart\r\n","import { RendererChartBarProps } from '../../types/shared'\r\nimport { ChartElementType } from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport utils from '../utils'\r\nimport { getBarWidthWithMarginByParts } from '../utils/chart'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { getIsSSr } from '../utils/helpers'\r\nimport Chart from './base_chart'\r\n\r\nconst WICK_WIDTH = 1\r\n\r\nclass CandleStick extends Chart {\r\n static type = ChartElementType.CandleStick\r\n static label = 'Candle'\r\n static iconName = 'candleBarBasic'\r\n\r\n getRenderChartBarProps({ index, chartSettingsColors, hasFillAndBorder }: RendererChartBarProps) {\r\n const { trendDown, trendUp, borderDown, borderUp, wickDown, wickUp } = chartSettingsColors\r\n const open = this.data.open[index]\r\n const close = this.data.close[index]\r\n const trendColor = close < open ? trendDown : trendUp\r\n const wickColor = close < open ? wickDown : wickUp\r\n return {\r\n open,\r\n close,\r\n high: this.data.high[index],\r\n low: this.data.low[index],\r\n barFillColor: trendColor,\r\n borderColor: close < open ? borderDown : borderUp,\r\n wickColor: hasFillAndBorder ? wickColor : trendColor,\r\n }\r\n }\r\n\r\n renderChart() {\r\n if (this.setupAxisTimeFrame !== this.data.timeframe) {\r\n return\r\n }\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const Colors = this.getCandleLikeChartsRenderingColors()\r\n const { barFillWidth, barBorderWidth } = getBarWidthWithMarginByParts({\r\n chartLayout: this.model.chart_layout(),\r\n zoomFactor: this.model.zoomFactor,\r\n })\r\n const shouldRenderFillAndBorder =\r\n barFillWidth + barBorderWidth * 2 >= 2 &&\r\n !(this.type === ChartElementType.HollowCandleStick && barBorderWidth === 0)\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width,\r\n yOffset: ChartSettings.top.height,\r\n })\r\n const translateForWick = getTranslate({\r\n context: this.context,\r\n xOffset: WICK_WIDTH / 2,\r\n yOffset: 0,\r\n })\r\n\r\n translate.do()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n paneModel: this.paneModel,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i: number, center: number) => {\r\n const { open, close, high, low, wickColor, borderColor, barFillColor } = this.getRenderChartBarProps({\r\n index: i,\r\n chartSettingsColors: Colors,\r\n hasFillAndBorder: shouldRenderFillAndBorder,\r\n })\r\n\r\n const candleBodyHigh = Math.round(this.fy(utils.max(open, close)))\r\n const candleBodyLow = Math.round(this.fy(utils.min(open, close)))\r\n const candleWickHigh = Math.round(this.fy(high))\r\n const candleWickLow = Math.round(this.fy(low))\r\n\r\n const candleBodyHeight = candleBodyLow - candleBodyHigh\r\n const candleBodyLeftX = center - Math.floor(barBorderWidth + barFillWidth / 2)\r\n const halfBorderWidth = barBorderWidth / 2\r\n\r\n // TODO: revisit for better approach, this solve issue with candlesticks\r\n // with even width are shifted 1px to the left and thus first candle is vertically sliced\r\n if (getIsSSr() && candleBodyLeftX + this.leftOffset < 0) {\r\n return\r\n }\r\n\r\n const isBodyHeightGreaterOrEqualBorders = candleBodyHeight >= barBorderWidth * 2\r\n const isWickLineCandleLessThanOnePixel = !shouldRenderFillAndBorder && candleWickLow - candleWickHigh < 1\r\n\r\n translateForWick.do()\r\n this.context.set('strokeStyle', wickColor)\r\n this.context.beginPath()\r\n this.context.moveTo(center, candleWickHigh)\r\n if (shouldRenderFillAndBorder) {\r\n this.context.lineTo(center, candleBodyHigh)\r\n this.context.moveTo(\r\n center,\r\n candleBodyHigh + (isBodyHeightGreaterOrEqualBorders ? candleBodyHeight : WICK_WIDTH)\r\n )\r\n }\r\n this.context.lineTo(center, isWickLineCandleLessThanOnePixel ? candleWickHigh + 1 : candleWickLow)\r\n this.context.stroke()\r\n translateForWick.undo()\r\n\r\n if (shouldRenderFillAndBorder) {\r\n const hasBorder = barBorderWidth > 0\r\n if (hasBorder) {\r\n this.context.set('strokeStyle', borderColor)\r\n if (isBodyHeightGreaterOrEqualBorders) {\r\n this.context.set('lineWidth', barBorderWidth)\r\n this.context.strokeRect(\r\n candleBodyLeftX + halfBorderWidth,\r\n candleBodyHigh + halfBorderWidth,\r\n barFillWidth + 2 * halfBorderWidth,\r\n candleBodyHeight - 2 * halfBorderWidth\r\n )\r\n this.context.set('lineWidth', WICK_WIDTH)\r\n } else {\r\n this.context.beginPath()\r\n this.context.moveTo(candleBodyLeftX, candleBodyHigh + WICK_WIDTH / 2)\r\n this.context.lineTo(candleBodyLeftX + barFillWidth + 2 * barBorderWidth, candleBodyHigh + WICK_WIDTH / 2)\r\n this.context.stroke()\r\n }\r\n }\r\n\r\n const fillHeight = candleBodyHeight - 2 * barBorderWidth\r\n const hasFill = fillHeight > 0\r\n if (hasFill || !hasBorder) {\r\n this.context.set('fillStyle', hasFill ? barFillColor : borderColor)\r\n this.context.fillRect(\r\n candleBodyLeftX + barBorderWidth,\r\n candleBodyHigh + barBorderWidth,\r\n barFillWidth,\r\n hasFill ? fillHeight : WICK_WIDTH\r\n )\r\n }\r\n }\r\n },\r\n })\r\n translate.undo()\r\n }\r\n\r\n toString() {\r\n return `Candle stick ${this.data.ticker}`\r\n }\r\n}\r\n\r\nexport default CandleStick\r\n","import { ChartConfigChartPaneElement, RendererChartBarProps, RequireByKey } from '../../types/shared'\r\nimport { ChartElementType } from '../constants/common'\r\nimport CandleStick from './candle_stick'\r\n\r\nclass HollowCandleStick extends CandleStick {\r\n static type = ChartElementType.HollowCandleStick\r\n static label = 'Hollow Candle'\r\n static iconName = 'candleBarHollow'\r\n\r\n static getNumOfBarsBuffer(element: RequireByKey) {\r\n return Math.max(1, super.getNumOfBarsBuffer(element))\r\n }\r\n\r\n getRenderChartBarProps({ index, chartSettingsColors }: RendererChartBarProps) {\r\n const open = this.data.open[index]\r\n const close = this.data.close[index]\r\n const isHollow = close > open\r\n const generalTrendColor =\r\n close > this.data.close[index - 1] ? chartSettingsColors.ohlcTrendUp : chartSettingsColors.ohlcTrendDown\r\n const trendColor = index === 0 ? chartSettingsColors.zeroChange : generalTrendColor\r\n return {\r\n open,\r\n close,\r\n high: this.data.high[index],\r\n low: this.data.low[index],\r\n // hollow candles have transparend bodies that's why rgba is here\r\n barFillColor: isHollow ? 'rgba(0, 0, 0, 0)' : trendColor,\r\n borderColor: trendColor,\r\n wickColor: trendColor,\r\n }\r\n }\r\n\r\n toString() {\r\n return `Hollow Candle stick ${this.data.ticker}`\r\n }\r\n}\r\n\r\nexport default HollowCandleStick\r\n","import { ChartConfigChartPaneElement, RendererChartBarProps, RequireByKey } from '../../types/shared'\r\nimport { ChartElementType, ScaleType } from '../constants/common'\r\nimport Quote from '../models/quote'\r\nimport { getTickerChangeFromCloseValues } from '../utils/chart'\r\nimport CandleStick from './candle_stick'\r\n\r\ntype OhlcKeys = 'high' | 'low' | 'open' | 'close'\r\n\r\nclass HeikinAshi extends CandleStick {\r\n static type = ChartElementType.HeikinAshi\r\n static label = 'Heikin Ashi'\r\n static iconName = 'candleBarHeikinAshi'\r\n\r\n static getNumOfBarsBuffer(element: RequireByKey) {\r\n return Math.max(1, super.getNumOfBarsBuffer(element))\r\n }\r\n\r\n getRenderChartBarProps = ({ index, chartSettingsColors, hasFillAndBorder }: RendererChartBarProps) => {\r\n const haData = this.data.getHeikinAshiData()\r\n\r\n const open = haData.open[index]\r\n const close = haData.close[index]\r\n const trendColor = close < open ? chartSettingsColors.trendDown : chartSettingsColors.trendUp\r\n const wickColor = close < open ? chartSettingsColors.wickDown : chartSettingsColors.wickUp\r\n return {\r\n open,\r\n close,\r\n high: Math.max(this.data.high[index], open, close),\r\n low: Math.min(open, close, this.data.low[index]),\r\n barFillColor: trendColor,\r\n borderColor: close < open ? chartSettingsColors.borderDown : chartSettingsColors.borderUp,\r\n wickColor: hasFillAndBorder ? wickColor : trendColor,\r\n }\r\n }\r\n\r\n getLastValues = () => {\r\n const Colors = this.getCandleLikeChartsRenderingColors()\r\n const {\r\n open: lastOpen,\r\n close: lastClose,\r\n high: lastHigh,\r\n low: lastLow,\r\n } = this.getRenderChartBarProps({\r\n index: this.data.date.length - 1,\r\n chartSettingsColors: Colors,\r\n })\r\n\r\n return { lastOpen, lastClose, lastHigh, lastLow }\r\n }\r\n\r\n getRoundedLastData() {\r\n const lastOhlc = this.getLastValues()\r\n return {\r\n open: this.roundOhlc(lastOhlc.lastOpen),\r\n high: this.roundOhlc(lastOhlc.lastHigh),\r\n low: this.roundOhlc(lastOhlc.lastLow),\r\n close: this.roundOhlc(lastOhlc.lastClose),\r\n }\r\n }\r\n\r\n renderYAxis = (context: CanvasRenderingContext2D) => {\r\n const { lastClose } = this.getLastValues()\r\n super.renderYAxis(context, { lastClose }, false)\r\n\r\n const { firstVisibleClose } = this.getMinMax()\r\n if (this.model.scale === ScaleType.Percentage && !firstVisibleClose) return\r\n\r\n const originalLatestClose = this.data.close[this.data.close.length - 1]\r\n const heikinLatestCloseLabel = this.getYAxisLastCloseLabel({ lastClose, firstVisibleClose })\r\n const originalLatestCloseLabel = this.getYAxisLastCloseLabel({ lastClose: originalLatestClose, firstVisibleClose })\r\n\r\n this.renderYAxisLabel({ context, yCoordinate: Math.round(this.fy(lastClose)), label: heikinLatestCloseLabel })\r\n\r\n if (heikinLatestCloseLabel === originalLatestCloseLabel) return\r\n\r\n this.renderYAxisLabel({\r\n context,\r\n yCoordinate: this.getYAxisSecondaryLabelYCoordinate({\r\n mainLabelValue: lastClose,\r\n secondaryLabelValue: originalLatestClose,\r\n }),\r\n label: originalLatestCloseLabel,\r\n background: this.getSecondaryLabelBackgroundColor(),\r\n })\r\n }\r\n\r\n getDataByCrossIndex(crossIndex: number, key: keyof Quote, shouldReturnRoundedString = true) {\r\n const Colors = this.getCandleLikeChartsRenderingColors()\r\n const barIndex = this.data.getDataIndexByBarIndex(crossIndex)\r\n if (barIndex > -1) {\r\n let value = null\r\n if (['high', 'low', 'open', 'close'].includes(key)) {\r\n const data = this.getRenderChartBarProps({ index: barIndex, chartSettingsColors: Colors })\r\n value = data[key as OhlcKeys]\r\n }\r\n value = value === null ? this.data.getDataByBarIndex(key, crossIndex) : value\r\n if (value !== null) {\r\n return shouldReturnRoundedString ? this.roundOhlc(value) : `${value}`\r\n }\r\n }\r\n }\r\n\r\n getCrossIndexChange(crossIndex: number) {\r\n const barIndex = this.data.getDataIndexByBarIndex(crossIndex)\r\n const haData = this.data.getHeikinAshiData()\r\n const crossClose = haData.close[barIndex] ?? null\r\n const previousClose = haData.close[barIndex - 1] ?? null\r\n if (crossClose !== null && previousClose !== null) {\r\n return getTickerChangeFromCloseValues({ data: this.data, anchorClose: crossClose, prevClose: previousClose })\r\n }\r\n\r\n return null\r\n }\r\n\r\n toString() {\r\n return `HA Candle stick ${this.data.ticker}`\r\n }\r\n}\r\n\r\nexport default HeikinAshi\r\n","import { ChartElementType } from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Chart from './base_chart'\r\n\r\nclass LineChart extends Chart {\r\n static type = ChartElementType.LineChart\r\n static label = 'Line'\r\n static iconName = 'lineChartType'\r\n\r\n renderChart() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n let first: number | undefined, last: number | undefined\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width + 0.5,\r\n yOffset: ChartSettings.top.height + 0.5,\r\n })\r\n translate.do()\r\n this.context.beginPath()\r\n this.context.set('lineWidth', 1)\r\n this.context.set('strokeStyle', Colors.line)\r\n drawInVisibleArea({\r\n quote: this.data,\r\n paneModel: this.paneModel,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i: number, x: number) => {\r\n const y = Math.round(this.fy(this.data.close[i]))\r\n this.context.lineTo(x, y)\r\n last = x\r\n if (first === undefined) {\r\n first = x\r\n }\r\n },\r\n })\r\n if (first !== undefined && last !== undefined) {\r\n this.context.stroke()\r\n this.context.set('fillStyle', Colors.background)\r\n this.context.lineTo(last!, this.height)\r\n this.context.lineTo(first!, this.height)\r\n this.context.fill()\r\n }\r\n\r\n translate.undo()\r\n }\r\n\r\n toString() {\r\n return `Line chart ${this.data.ticker}`\r\n }\r\n}\r\n\r\nexport default LineChart\r\n","import Text from '../canvas/text'\r\nimport { ChartElementType, TextAlign, TextBaseline } from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport Pane from '../models/pane'\r\nimport { isRedesignEnabled } from '../utils'\r\nimport Chart, { BaseChartAttrs } from './base_chart'\r\n\r\nconst interval = 3\r\nconst domainMin = -1\r\nconst domainMax = 1\r\nconst red = 'rgba(200, 0, 0, 0.392)'\r\nconst redLine = 'rgb(120, 0, 0)'\r\nconst green = 'rgba(0, 180, 0, 0.392)'\r\nconst greenLine = 'rgb(0, 100, 0)'\r\n\r\nclass MarketSentiment extends Chart {\r\n static type = ChartElementType.MarketSentiment\r\n\r\n static initClass() {\r\n Object.defineProperty(this.prototype, 'width', {\r\n get() {\r\n const { MarketSentimentSettings } = this.getChartLayoutSettings()\r\n return this.model.width - MarketSentimentSettings.left.width - MarketSentimentSettings.right.width\r\n },\r\n })\r\n\r\n Object.defineProperty(this.prototype, 'height', {\r\n get() {\r\n const { MarketSentimentSettings } = this.getChartLayoutSettings()\r\n return this.paneModel.height - MarketSentimentSettings.top.height - MarketSentimentSettings.bottom.height\r\n },\r\n })\r\n }\r\n\r\n declare _data: number[]\r\n declare _dataLastIndex: number | null\r\n\r\n constructor(values: Partial, model: Pane) {\r\n super(values, model)\r\n this.renderText = this.renderText.bind(this)\r\n this.renderOverlaysLabels = this.renderOverlaysLabels.bind(this)\r\n this.renderYAxis = this.renderYAxis.bind(this)\r\n this.setupCache = this.setupCache.bind(this)\r\n }\r\n\r\n setupCache() {\r\n super.setupCache()\r\n if (!this.data) {\r\n return\r\n }\r\n const arr: number[] = []\r\n this.data.close.forEach((sum, i) => {\r\n arr[i] = sum / this.data.volume[i]\r\n })\r\n this._data = arr\r\n\r\n let lastIndex = null\r\n for (let i = this.data.volume.length - 1; i >= 0; i--) {\r\n if (this.data.volume[i] !== 0) {\r\n lastIndex = i\r\n break\r\n }\r\n }\r\n this._dataLastIndex =\r\n lastIndex === null\r\n ? null\r\n : Math.min(lastIndex, Math.round((this.data.drawMinutesPerDay - this.data.marketStartMinutes) / interval))\r\n }\r\n\r\n renderChart() {\r\n const { MarketSentimentSettings } = this.getChartLayoutSettings()\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + MarketSentimentSettings.left.width + 0.5,\r\n yOffset: MarketSentimentSettings.top.height + 0.5,\r\n })\r\n translate.do()\r\n this.renderLineBullBear(this.context, this._data, 0, 0, 0)\r\n translate.undo()\r\n }\r\n\r\n renderLineBullBear(\r\n context: CanvasRenderingContext2D,\r\n array: number[],\r\n from: number,\r\n oversold: number,\r\n overbought: number\r\n ) {\r\n if (this._dataLastIndex === null) {\r\n return\r\n }\r\n const isRedesign = isRedesignEnabled()\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n\r\n const domain = [domainMax, domainMin]\r\n\r\n context.save()\r\n context.beginPath()\r\n context.rect(\r\n -this.leftOffset,\r\n this.fy(domain[1]),\r\n this.fx(this._dataLastIndex),\r\n Math.round(this.fy(oversold) - this.fy(domain[1])) - 0.5\r\n )\r\n context.clip()\r\n context.set('fillStyle', red)\r\n context.set('strokeStyle', isRedesign ? Colors.marketDown : redLine)\r\n context.beginPath()\r\n context.moveTo(this.fx(0), Math.round(this.fy(domain[0])))\r\n for (let i = from; i < this.data.close.length; i++) {\r\n context.lineTo(this.fx(i), Math.round(this.fy(array[i])))\r\n }\r\n context.lineTo(this.fx(this.data.close.length - 1), Math.round(this.fy(domain[0])))\r\n context.fill()\r\n context.stroke()\r\n context.restore()\r\n\r\n context.save()\r\n context.beginPath()\r\n context.rect(\r\n -this.leftOffset,\r\n this.fy(domain[0]),\r\n this.fx(this._dataLastIndex),\r\n Math.round(this.fy(overbought)) - 0.5\r\n )\r\n context.clip()\r\n context.set('fillStyle', green)\r\n context.set('strokeStyle', isRedesign ? Colors.marketUp : greenLine)\r\n context.beginPath()\r\n context.moveTo(this.fx(0), Math.round(this.fy(domain[1])))\r\n for (let i = from; i < this.data.close.length; i++) {\r\n context.lineTo(this.fx(i), Math.round(this.fy(array[i])))\r\n }\r\n context.lineTo(this.fx(this.data.close.length - 1), Math.round(this.fy(domain[1])))\r\n context.fill()\r\n context.stroke()\r\n context.restore()\r\n }\r\n\r\n renderXAxis() {\r\n const { MarketSentimentSettings } = this.getChartLayoutSettings()\r\n const { Colors } = MarketSentimentSettings.general\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + MarketSentimentSettings.left.width,\r\n yOffset: MarketSentimentSettings.top.height,\r\n })\r\n translate.do()\r\n\r\n const xLine = this.getXLine()\r\n const text = new Text(\r\n {\r\n y: this.height + 12,\r\n font: { size: 7 },\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.bottom,\r\n textAlign: TextAlign.center,\r\n },\r\n this.paneModel\r\n )\r\n let x\r\n\r\n x = this.fx(0)\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n x = this.fx(10) + 2 /* remove overflow */\r\n text.set({ text: '10AM', x }).render(this.context)\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n x = this.fx(10 + 20)\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n x = this.fx(10 + 40)\r\n text.set({ text: '12PM', x }).render(this.context)\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n x = this.fx(10 + 60)\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n x = this.fx(10 + 80)\r\n text.set({ text: '2PM', x }).render(this.context)\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n x = this.fx(10 + 100)\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n x = this.fx(10 + 120 - 1)\r\n text.set({ text: '4PM', x }).render(this.context)\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n translate.undo()\r\n }\r\n\r\n renderText() {}\r\n\r\n renderCrossText() {}\r\n\r\n renderOverlaysLabels() {}\r\n\r\n _compute() {\r\n return { min: domainMin, max: domainMax }\r\n }\r\n\r\n computeVisibleMinMax() {\r\n return this._compute()\r\n }\r\n\r\n renderYAxis(context: CanvasRenderingContext2D) {\r\n const { MarketSentimentSettings, ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const isRedesign = isRedesignEnabled()\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: MarketSentimentSettings.left.width,\r\n yOffset: MarketSentimentSettings.top.height,\r\n })\r\n translate.do()\r\n\r\n const yLine = this.getYLine()\r\n for (const tick of [domainMin, 0, domainMax]) {\r\n const y = Math.round(this.fy(tick))\r\n yLine.set({ y1: y, y2: y }).render(context)\r\n }\r\n\r\n const text = new Text(\r\n {\r\n x: this.width + 27,\r\n font: { size: 8 },\r\n textBaseline: TextBaseline.middle,\r\n textAlign: TextAlign.right,\r\n },\r\n this.paneModel\r\n )\r\n\r\n const fillUp = isRedesign ? Colors.marketUp : greenLine\r\n const fillDown = isRedesign ? Colors.marketDown : redLine\r\n const last = this._data[this._dataLastIndex!]\r\n const percent = this._dataLastIndex !== null ? Math.floor(last * 50 + 50) : 50\r\n text.set({ y: this.fy(0) - 5, fillStyle: fillUp, text: `${percent}%` }).render(context)\r\n text.set({ y: this.fy(0) + 7, fillStyle: fillDown, text: `${100 - percent}%` }).render(context)\r\n\r\n translate.undo()\r\n }\r\n\r\n clip() {\r\n const { MarketSentimentSettings } = this.getChartLayoutSettings()\r\n this.context.beginPath()\r\n this.context.rect(MarketSentimentSettings.left.width, MarketSentimentSettings.top.height, this.width, this.height)\r\n this.context.clip()\r\n }\r\n\r\n getMinMax() {\r\n return this._compute()\r\n }\r\n\r\n renderVolumeAxis() {}\r\n\r\n renderVolume() {}\r\n\r\n toString() {\r\n return `Market sentiment chart`\r\n }\r\n}\r\nMarketSentiment.initClass()\r\n\r\nexport default MarketSentiment\r\n","import { ObjectHash } from '../../types/shared'\r\nimport Text from '../canvas/text'\r\nimport { ChartElementType, FONT_SIZE, LINE_HEIGHT, PADDING, TextAlign, TextBaseline } from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport Pane from '../models/pane'\r\nimport Quote from '../models/quote'\r\nimport utils from '../utils'\r\nimport Chart, { BaseChartAttrs } from './base_chart'\r\n\r\ninterface MultiLineChartAttrs extends BaseChartAttrs {\r\n tickers: string[]\r\n label?: string\r\n min?: number\r\n max?: number\r\n}\r\n\r\nconst months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']\r\n\r\nclass MultiLineChart extends Chart {\r\n static type = ChartElementType.MultiLineChart\r\n tickersDimensions: number[] = []\r\n\r\n constructor(values: Partial, model: Pane) {\r\n super(values, model)\r\n this.renderText = this.renderText.bind(this)\r\n }\r\n\r\n renderChart() {\r\n const { ChartSettings, ColorsSettings } = this.getChartLayoutSettings()\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width + 0.5,\r\n yOffset: ChartSettings.top.height + 0.5,\r\n })\r\n translate.do()\r\n\r\n this.context.set('lineWidth', 1)\r\n\r\n const quotes: ObjectHash = {}\r\n for (const quote of this.getQuotes()) {\r\n quotes[quote.ticker] = quote\r\n }\r\n\r\n for (let index = this.attrs.tickers.length - 1; index >= 0; index--) {\r\n const ticker = this.attrs.tickers[index]\r\n const quote = quotes[ticker]\r\n this.context.set('strokeStyle', ColorsSettings[index % ColorsSettings.length])\r\n this.context.beginPath()\r\n for (let i = 0, end = quote.close.length, asc = end >= 0; asc ? i < end : i > end; asc ? i++ : i--) {\r\n const x = this.fx(i)\r\n if (x + this.leftOffset < -10 || x + this.leftOffset > this.model.width + 10) {\r\n // margin?\r\n continue\r\n }\r\n const y = Math.round(this.fy(quote.close[i]))\r\n this.context.lineTo(x, y)\r\n }\r\n this.context.stroke()\r\n }\r\n\r\n translate.undo()\r\n }\r\n\r\n renderText(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const text = this.attrs.label || ''\r\n const y = (this.height - 4) / 2\r\n new Text(\r\n {\r\n text,\r\n x: 28,\r\n y: ChartSettings.top.height + y,\r\n angle: -90,\r\n font: { size: 10, weight: '900', family: 'Lato, sans-serif' },\r\n fillStyle: Colors.textSecondary,\r\n textAlign: TextAlign.center,\r\n textBaseline: TextBaseline.alphabetic,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n return this.renderCrossText(context, this.data.close.length - 1)\r\n }\r\n\r\n renderCrossText(context: CanvasRenderingContext2D, crossIndex: number) {\r\n const { ChartSettings, ColorsSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const maxTickerLength = utils.max(this.attrs.tickers.map((t) => t.length))\r\n\r\n const date = utils.dateFromUnixTimestamp(this.data.getDataByBarIndex('date', crossIndex) ?? 0)\r\n const month = date.getMonth() // 20141126\r\n const year = date.getFullYear()\r\n const day = date.getDate()\r\n const isLastDate = crossIndex === this.data.close.length - 1\r\n\r\n new Text(\r\n {\r\n text: `${months[month]} ${day} ${year} `,\r\n x: ChartSettings.left.width + (maxTickerLength > 15 ? 200 : 132),\r\n y: 30,\r\n font: { size: 8 },\r\n fillStyle: Colors.text,\r\n background: Colors.canvasFill,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n\r\n const quotes: ObjectHash = {}\r\n for (const quote of this.getQuotes()) {\r\n quotes[quote.ticker] = quote\r\n }\r\n for (let index = 0; index < this.attrs.tickers.length; index++) {\r\n const y = PADDING.S + (PADDING.S + LINE_HEIGHT.M) * index\r\n if (this.tickersDimensions[index]) {\r\n context.fillStyle = Colors.canvasFill\r\n context.fillRect(\r\n ChartSettings.left.width - PADDING.XXXS,\r\n y - PADDING.XXXS,\r\n PADDING.XXXS + this.tickersDimensions[index] + PADDING.XXXS,\r\n PADDING.XXXS + FONT_SIZE.M + PADDING.XXXS\r\n )\r\n }\r\n const ticker = this.attrs.tickers[index]\r\n const closeValue = quotes[ticker].close[crossIndex]\r\n const text = new Text(\r\n {\r\n text: `${ticker} ${typeof closeValue === 'number' ? closeValue.toFixed(2) : NaN} `,\r\n x: ChartSettings.left.width,\r\n y,\r\n font: { size: FONT_SIZE.M, style: 'bold' },\r\n lineHeight: LINE_HEIGHT.M,\r\n fillStyle: ColorsSettings[index % ColorsSettings.length],\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.top,\r\n },\r\n this.paneModel\r\n )\r\n if (isLastDate) {\r\n this.tickersDimensions[index] = text.measure(context)\r\n }\r\n text.render(context)\r\n }\r\n }\r\n\r\n computeVisibleMinMax(...arrays: Array) {\r\n let min = Number.MAX_VALUE\r\n let max = Number.MIN_VALUE\r\n\r\n const { leftOffset } = this.model\r\n for (const arr of arrays) {\r\n for (let i = 0, end = arr.length, asc = end >= 0; asc ? i < end : i > end; asc ? i++ : i--) {\r\n const center = this.fx(i)\r\n if (center + leftOffset < 0 || center + leftOffset > this.width) {\r\n // margin?\r\n continue\r\n }\r\n\r\n if (min > arr[i]) {\r\n min = arr[i]\r\n }\r\n if (max < arr[i]) {\r\n max = arr[i]\r\n }\r\n }\r\n }\r\n\r\n return { min, max }\r\n }\r\n\r\n getMinMax() {\r\n const quotes = this.getQuotes()\r\n let { min, max } = this.computeVisibleMinMax(...quotes.map((q) => q.close))\r\n if (typeof this.attrs.min !== 'undefined') {\r\n min = this.attrs.min\r\n }\r\n if (typeof this.attrs.max !== 'undefined') {\r\n max = this.attrs.max\r\n }\r\n return { min, max }\r\n }\r\n\r\n renderVolumeAxis() {}\r\n\r\n renderVolume() {}\r\n\r\n getQuotes() {\r\n return Quote.select(\r\n (q: Quote) =>\r\n this.attrs.tickers.includes(q.ticker) &&\r\n q.timeframe === this.data?.timeframe &&\r\n this.model.chart_layout().isIdeaId(q.ideaID)\r\n )\r\n }\r\n\r\n toString() {\r\n return `Line chart ${this.data.ticker}`\r\n }\r\n}\r\n\r\nexport default MultiLineChart\r\n","import { ChartElementType } from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport { getBarWithoutMarginWidth } from '../utils/chart'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Chart from './base_chart'\r\n\r\nclass OHLCChart extends Chart {\r\n static type = ChartElementType.OhlcChart\r\n static label = 'OHLC'\r\n static iconName = 'ohlcChartType'\r\n\r\n renderChart() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width,\r\n yOffset: ChartSettings.top.height,\r\n })\r\n translate.do()\r\n\r\n const barWithoutMarginWidth = getBarWithoutMarginWidth(this.model)\r\n\r\n let lineWidth = 1\r\n if (barWithoutMarginWidth >= 40) {\r\n lineWidth = 4\r\n } else if (barWithoutMarginWidth >= 30) {\r\n lineWidth = 3\r\n } else if (barWithoutMarginWidth >= 15) {\r\n lineWidth = 2\r\n }\r\n const lineThickness = lineWidth / 2\r\n const handleLengthFromWick = Math.round(barWithoutMarginWidth / 2 - lineThickness)\r\n const lineOffset = lineWidth % 2 === 0 ? 0 : 0.5\r\n this.context.set('lineWidth', lineWidth)\r\n\r\n drawInVisibleArea({\r\n quote: this.data,\r\n paneModel: this.paneModel,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i: number, x: number) => {\r\n const barX = ~~(x - 1) + lineOffset // move 1px to left so cursor don't cover bar of ohlc-chart & round for pixel perfect render on zoom\r\n\r\n this.context.beginPath()\r\n this.context.set(\r\n 'strokeStyle',\r\n this.data.close[i] < this.data.open[i] ? Colors.ohlcTrendDown : Colors.ohlcTrendUp\r\n )\r\n\r\n this.context.moveTo(barX, Math.round(this.fy(this.data.high[i])))\r\n this.context.lineTo(barX, Math.round(this.fy(this.data.low[i])))\r\n\r\n if (handleLengthFromWick >= 1) {\r\n const open = Math.round(this.fy(this.data.open[i]))\r\n this.context.moveTo(barX + lineThickness, open + lineOffset) // move to right edge of wick\r\n this.context.lineTo(barX - lineThickness - handleLengthFromWick, open + lineOffset) // draw line to the left\r\n\r\n const close = Math.round(this.fy(this.data.close[i]))\r\n this.context.moveTo(barX - lineThickness, close + lineOffset) // move to left edge of wick\r\n this.context.lineTo(barX + lineThickness + handleLengthFromWick, close + lineOffset) // draw line to the right\r\n }\r\n\r\n this.context.stroke()\r\n },\r\n })\r\n\r\n translate.undo()\r\n }\r\n\r\n toString() {\r\n return `OHLC ${this.data.ticker}`\r\n }\r\n}\r\n\r\nexport default OHLCChart\r\n","import * as d3 from 'd3'\r\n\r\nimport { ObjectHash } from '../../types/shared'\r\nimport Text from '../canvas/text'\r\nimport { ChartElementType, FONT_SIZE, MARGIN, OFFSET, PADDING, TextAlign, TextBaseline } from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport Pane from '../models/pane'\r\nimport Quote from '../models/quote'\r\nimport utils from '../utils'\r\nimport Chart, { BaseChartAttrs } from './base_chart'\r\n\r\nconst months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']\r\n\r\ninterface PerfChartAttrs extends BaseChartAttrs {\r\n tickers: string[]\r\n label?: string\r\n fromDate: string\r\n toDate: string\r\n min?: number\r\n max?: number\r\n}\r\n\r\nclass PerfChart extends Chart {\r\n static type = ChartElementType.PerfChart\r\n\r\n overlayLabelWidth: ObjectHash\r\n perf: ObjectHash = {}\r\n\r\n constructor(values: Partial, model: Pane) {\r\n super(values, model)\r\n this.renderText = this.renderText.bind(this)\r\n this.renderOverlaysLabels = this.renderOverlaysLabels.bind(this)\r\n this.renderYAxis = this.renderYAxis.bind(this)\r\n this.overlayLabelWidth = {}\r\n }\r\n\r\n renderChart() {\r\n const { ChartSettings, ColorsSettings } = this.getChartLayoutSettings()\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width + 0.5,\r\n yOffset: ChartSettings.top.height + 0.5,\r\n })\r\n translate.do()\r\n\r\n this.context.beginPath()\r\n this.context.set('lineWidth', 1)\r\n for (let index = 0; index < this.attrs.tickers.length; index++) {\r\n const ticker = this.attrs.tickers[index]\r\n if ((this.perf[ticker] != null ? this.perf[ticker].length : 0) > 0) {\r\n this.context.set('strokeStyle', ColorsSettings[index % ColorsSettings.length])\r\n this.context.beginPath()\r\n for (let i = 0, end = this.data.close.length, asc = end >= 0; asc ? i < end : i > end; asc ? i++ : i--) {\r\n this.context.lineTo(this.fx(i), Math.round(this.fy(this.perf[ticker][i])))\r\n }\r\n this.context.stroke()\r\n }\r\n }\r\n\r\n translate.undo()\r\n }\r\n\r\n renderText(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const period = (() => {\r\n switch (this.model.quote().timeframe) {\r\n case 'd':\r\n return 'DAILY'\r\n case 'w':\r\n return 'WEEKLY'\r\n case 'm':\r\n return 'MONTHLY'\r\n default:\r\n return\r\n }\r\n })()\r\n const y = (this.height - 4) / 2\r\n new Text(\r\n {\r\n text: period,\r\n x: 28,\r\n y: ChartSettings.top.height + y,\r\n angle: -90,\r\n font: { size: 10, weight: '900', family: 'Lato, sans-serif' },\r\n fillStyle: Colors.textSecondary,\r\n textAlign: TextAlign.center,\r\n textBaseline: TextBaseline.alphabetic,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n }\r\n\r\n renderCrossText(context: CanvasRenderingContext2D, crossIndex: number) {\r\n const { ChartSettings, ColorsSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const date = utils.dateFromUnixTimestamp(this.data.getDataByBarIndex('date', crossIndex) ?? 0)\r\n let dateString = ''\r\n const month = date.getMonth() // 20141126\r\n const year = date.getFullYear()\r\n const day = date.getDate()\r\n switch (this.data.timeframe) {\r\n case 'd':\r\n case 'w':\r\n dateString = `${months[month]} ${day}`\r\n break\r\n case 'm':\r\n dateString = `${months[month]} ${year}`\r\n break\r\n default:\r\n return\r\n }\r\n\r\n let shouldRenderDate = false\r\n for (let index = 0; index < this.attrs.tickers.length; index++) {\r\n const ticker = this.attrs.tickers[index]\r\n const tickerData = this.perf[ticker]\r\n if (tickerData?.length) {\r\n context.fillStyle = Colors.canvasFill\r\n context.fillRect(\r\n ChartSettings.left.width - PADDING.XXXS,\r\n OFFSET.M + (FONT_SIZE.M + MARGIN.XS) * index - PADDING.XXXS,\r\n PADDING.XXXS + this.overlayLabelWidth[ticker] + PADDING.XXXS,\r\n PADDING.XXXS + FONT_SIZE.M + PADDING.XXXS\r\n )\r\n const hasData = Number.isFinite(tickerData[crossIndex])\r\n const percentageText = hasData ? `${tickerData[crossIndex].toFixed(2)}%` : ''\r\n shouldRenderDate = shouldRenderDate || hasData\r\n new Text(\r\n {\r\n text: `${ticker} ${percentageText}`,\r\n x: ChartSettings.left.width,\r\n y: OFFSET.M + (FONT_SIZE.M + MARGIN.XS) * index,\r\n font: { size: FONT_SIZE.M, style: 'bold' },\r\n fillStyle: ColorsSettings[index % ColorsSettings.length],\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.top,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n }\r\n }\r\n\r\n if (shouldRenderDate) {\r\n new Text(\r\n {\r\n text: `${dateString} `,\r\n x: ChartSettings.left.width + 132,\r\n y: 30,\r\n font: { size: 8 },\r\n fillStyle: Colors.text,\r\n background: Colors.canvasFill,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n }\r\n }\r\n\r\n renderOverlaysLabels(context: CanvasRenderingContext2D) {\r\n super.renderOverlaysLabels(context)\r\n const { ChartSettings, ColorsSettings } = this.getChartLayoutSettings()\r\n\r\n for (let index = 0; index < this.attrs.tickers.length; index++) {\r\n const ticker = this.attrs.tickers[index]\r\n const tickerData = this.perf[ticker]\r\n if (tickerData?.length) {\r\n const lastCrossIndex = this.perf[ticker].length - 1\r\n const hasData = Number.isFinite(tickerData[lastCrossIndex])\r\n const percentageText = hasData ? `${tickerData[lastCrossIndex].toFixed(2)}%` : ''\r\n const text = new Text(\r\n {\r\n text: `${ticker} ${percentageText}`,\r\n x: ChartSettings.left.width,\r\n y: OFFSET.M + (FONT_SIZE.M + MARGIN.XS) * index,\r\n font: { size: FONT_SIZE.M, style: 'bold' },\r\n fillStyle: ColorsSettings[index % ColorsSettings.length],\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.top,\r\n },\r\n this.paneModel\r\n )\r\n this.overlayLabelWidth = { ...this.overlayLabelWidth, [ticker]: text.measure(context) }\r\n text.render(context)\r\n }\r\n }\r\n }\r\n\r\n _compute() {\r\n this.perf = {}\r\n const quotes = this.getQuotes()\r\n\r\n const fromDate = new Date(this.attrs.fromDate + ' 00:00')\r\n const toDate = new Date(this.attrs.toDate + ' 23:59')\r\n const filteredQuotes = []\r\n for (const quote of quotes) {\r\n const closes = []\r\n for (let i = 0, end = quote.close.length, asc = end >= 0; asc ? i < end : i > end; asc ? i++ : i--) {\r\n const date = utils.dateFromUnixTimestamp(quote.date[i])\r\n if (fromDate <= date && date <= toDate) {\r\n closes.push(quote.close[i])\r\n }\r\n }\r\n filteredQuotes.push({ ticker: quote.ticker, close: closes })\r\n }\r\n\r\n const daysCount = d3.max(filteredQuotes, (q) => q.close.length) ?? 0\r\n for (const quote of filteredQuotes) {\r\n this.perf[quote.ticker] = []\r\n const first = quote.close[0]\r\n let offset = 0\r\n if (daysCount > quote.close.length) {\r\n offset = daysCount - quote.close.length\r\n for (let i = 0, end1 = offset, asc1 = end1 >= 0; asc1 ? i < end1 : i > end1; asc1 ? i++ : i--) {\r\n this.perf[quote.ticker][i] = NaN\r\n }\r\n }\r\n for (let i = 0, end2 = quote.close.length, asc2 = end2 >= 0; asc2 ? i < end2 : i > end2; asc2 ? i++ : i--) {\r\n this.perf[quote.ticker][offset + i] = (quote.close[i] * 100) / first - 100\r\n }\r\n }\r\n const { min, max } = this.computeVisibleMinMax(...Object.keys(this.perf).map((x) => this.perf[x]))\r\n return { min, max }\r\n }\r\n\r\n // TODO refactor into ?utils\r\n computeVisibleMinMax(...arrays: Array) {\r\n let min = Number.MAX_VALUE\r\n let max = Number.MIN_VALUE\r\n\r\n const { leftOffset } = this.model\r\n for (const arr of arrays) {\r\n for (let i = 0, end = arr.length, asc = end >= 0; asc ? i < end : i > end; asc ? i++ : i--) {\r\n const center = this.fx(i)\r\n if (center + leftOffset < 0 || center + leftOffset > this.width) {\r\n // margin?\r\n continue\r\n }\r\n\r\n if (min > arr[i]) {\r\n min = arr[i]\r\n }\r\n if (max < arr[i]) {\r\n max = arr[i]\r\n }\r\n }\r\n }\r\n\r\n return { min, max }\r\n }\r\n\r\n renderYAxis(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const translate = getTranslate({\r\n context,\r\n xOffset: ChartSettings.left.width,\r\n yOffset: ChartSettings.top.height,\r\n })\r\n translate.do()\r\n const ticks = this.paneModel.scale.y.ticks(10)\r\n const yLine = this.getYLine()\r\n const text = new Text(\r\n {\r\n x: this.width + 8,\r\n font: { size: 8 },\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.middle,\r\n },\r\n this.paneModel\r\n )\r\n for (const tick of ticks) {\r\n const y = Math.round(this.fy(tick))\r\n yLine.set({ y1: y, y2: y }).render(context)\r\n text.set({ text: tick.toFixed(2), y }).render(context)\r\n }\r\n translate.undo()\r\n }\r\n\r\n renderXAxis() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width,\r\n yOffset: ChartSettings.top.height,\r\n })\r\n translate.do()\r\n const text = new Text(\r\n {\r\n y: this.height + 18,\r\n font: { size: 8 },\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.bottom,\r\n textAlign: TextAlign.center,\r\n },\r\n this.paneModel\r\n )\r\n const textWidth = text.set({ text: '2020' }).measure(this.context)\r\n\r\n let date = new Date(this.data.date[0] * 1000)\r\n let lastMonth = date.getMonth() + '-' + date.getFullYear()\r\n\r\n let monthsInData = 0\r\n this.data.date.forEach((d, index) => {\r\n if (index < 1) {\r\n return\r\n }\r\n\r\n const date = new Date(d * 1000)\r\n const month = date.getMonth() + '-' + date.getFullYear()\r\n if (month !== lastMonth) {\r\n monthsInData++\r\n }\r\n lastMonth = month\r\n })\r\n\r\n const availableTickSpots = ~~(this.width / textWidth)\r\n const monthsToAvail = monthsInData / availableTickSpots\r\n let renderMonth\r\n if (monthsToAvail <= 1) {\r\n renderMonth = () => true\r\n } else if (monthsToAvail <= 2) {\r\n renderMonth = (x: number) => x % 2 === 0\r\n } else if (monthsToAvail <= 3) {\r\n renderMonth = (x: number) => x % 3 === 0\r\n } else if (monthsToAvail <= 4) {\r\n renderMonth = (x: number) => x % 4 === 0\r\n } else if (monthsToAvail <= 6) {\r\n renderMonth = (x: number) => x % 6 === 0\r\n } else {\r\n renderMonth = (x: number) => x === 0\r\n }\r\n\r\n date = new Date(this.data.date[0] * 1000)\r\n lastMonth = date.getMonth() + '-' + date.getFullYear()\r\n\r\n const xLine = this.getXLine()\r\n\r\n for (let i = 0; i < this.data.date.length; i++) {\r\n date = new Date(this.data.date[i] * 1000)\r\n const month = date.getMonth() + '-' + date.getFullYear()\r\n if (month !== lastMonth) {\r\n lastMonth = month\r\n const x = this.fx(i)\r\n if (x + this.leftOffset < -15 || x + this.leftOffset > this.width + 15) {\r\n // margin?\r\n continue\r\n }\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n if (!renderMonth(date.getMonth())) {\r\n continue\r\n }\r\n\r\n text\r\n .set({\r\n text: date.getMonth() === 0 ? date.getFullYear().toString() : months[date.getMonth()],\r\n x: x,\r\n })\r\n .render(this.context)\r\n }\r\n }\r\n\r\n translate.undo()\r\n }\r\n\r\n getMinMax() {\r\n return this._compute()\r\n }\r\n\r\n renderVolumeAxis() {}\r\n\r\n renderVolume() {}\r\n\r\n getQuotes() {\r\n return Quote.select(\r\n (q: Quote) =>\r\n this.attrs.tickers.includes(q.ticker) &&\r\n q.timeframe === this.data?.timeframe &&\r\n this.model.chart_layout().isIdeaId(q.ideaID)\r\n )\r\n }\r\n\r\n toString() {\r\n return `Perf chart ${this.data.ticker}`\r\n }\r\n}\r\n\r\nexport default PerfChart\r\n","import { ChartElementType } from '../constants/common'\r\nimport candleStick from './candle_stick'\r\nimport hollowCandleStick from './candle_stick_hollow'\r\nimport heikinAshi from './heikin_ashi'\r\nimport lineChart from './line_chart'\r\nimport marketSentiment from './market_sentiment'\r\nimport multiLineCharts from './multi_line_chart'\r\nimport ohlcChart from './ohlc_chart'\r\nimport perfChart from './perf_chart'\r\n\r\nexport const chartsByType = Object.freeze({\r\n [ChartElementType.CandleStick]: candleStick,\r\n [ChartElementType.HeikinAshi]: heikinAshi,\r\n [ChartElementType.HollowCandleStick]: hollowCandleStick,\r\n [ChartElementType.LineChart]: lineChart,\r\n [ChartElementType.MarketSentiment]: marketSentiment,\r\n [ChartElementType.MultiLineChart]: multiLineCharts,\r\n [ChartElementType.OhlcChart]: ohlcChart,\r\n [ChartElementType.PerfChart]: perfChart,\r\n})\r\n","export const FONT_SIZE = {\r\n XXS: 5,\r\n XS: 7,\r\n S: 8,\r\n M: 10,\r\n L: 11,\r\n XXL: 18,\r\n XXXL: 23,\r\n}\r\nexport const LINE_HEIGHT = {\r\n XS: 7,\r\n S: 8,\r\n M: 10,\r\n}\r\nexport const PADDING = {\r\n XXXS: 1,\r\n XXS: 2,\r\n XS: 3,\r\n S: 5,\r\n}\r\nexport const MARGIN = {\r\n XS: 4,\r\n}\r\nexport const CHART_MARGIN = {\r\n S: 15,\r\n M: 30,\r\n L: 35,\r\n XL: 38,\r\n XXL: 48,\r\n}\r\nexport const SETTINGS_HEIGHT = 44\r\nexport const TICKER_TIMEFRAME_CHANGE_HEIGHT = 20\r\nexport const OFFSET = {\r\n XXS: 2,\r\n XS: 4,\r\n S: 6,\r\n M: 8,\r\n XXL: 20,\r\n}\r\nexport const MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']\r\n\r\nexport enum ChartEditorEnum {\r\n publish = 'publish',\r\n tools = 'tools',\r\n ideas = 'ideas',\r\n settings = 'settings',\r\n timeframe = 'timeframe',\r\n}\r\n\r\nexport enum LayoutType {\r\n '1h1v' = '1h1v',\r\n '1h2v' = '1h2v',\r\n '1h3v' = '1h3v',\r\n '2h1v' = '2h1v',\r\n '2h2v' = '2h2v',\r\n '3h1v' = '3h1v',\r\n '3h2v' = '3h2v',\r\n '1l2r' = '1l2r',\r\n '1t2b' = '1t2b',\r\n}\r\n\r\nexport enum CanvasElementType {\r\n element = 'canvas/element',\r\n arrow = 'canvas/arrow',\r\n brushV1 = 'canvas/brush/brush_v1',\r\n curve = 'canvas/curve',\r\n ellipse = 'canvas/ellipse',\r\n fibonacciRetracements = 'canvas/fibonacci_retracements',\r\n horizontalLine = 'canvas/horizontal_line',\r\n line = 'canvas/line',\r\n measure = 'canvas/measure',\r\n pitchforkV1 = 'canvas/pitchfork/pitchfork_v1',\r\n polygon = 'canvas/polygon',\r\n position = 'canvas/position',\r\n rectangle = 'canvas/rectangle',\r\n rotatedRectangle = 'canvas/rotated_rectangle',\r\n scaledLine = 'canvas/scaled_line',\r\n scaledText = 'canvas/scaled_text',\r\n symbol = 'canvas/symbol',\r\n text = 'canvas/text',\r\n triangle = 'canvas/triangle',\r\n verticalLine = 'canvas/vertical_line',\r\n xabcd = 'canvas/xabcd',\r\n calloutV1 = 'canvas/callout/callout_v1',\r\n elliottWaves = 'canvas/elliott_waves/elliott_waves',\r\n ellipseV1 = 'canvas/ellipse/ellipse_v1',\r\n rotatedRectangleV1 = 'canvas/rotated_rectangle/rotated_rectangle_v1',\r\n}\r\n\r\nexport enum ChartElementType {\r\n CandleStick = 'charts/candle_stick',\r\n HeikinAshi = 'charts/heikin_ashi',\r\n HollowCandleStick = 'charts/candle_stick_hollow',\r\n LineChart = 'charts/line_chart',\r\n OhlcChart = 'charts/ohlc_chart',\r\n MarketSentiment = 'charts/market_sentiment',\r\n MultiLineChart = 'charts/multi_line_chart',\r\n PerfChart = 'charts/perf_chart',\r\n}\r\n\r\nexport enum IndicatorType {\r\n Indicator = 'indicators/indicator',\r\n None = 'indicators/none',\r\n Adx = 'indicators/adx',\r\n Aro = 'indicators/aro',\r\n Aroosc = 'indicators/aroosc',\r\n Atr = 'indicators/atr',\r\n Cci = 'indicators/cci',\r\n Cot = 'indicators/cot',\r\n Fi = 'indicators/fi',\r\n Macd = 'indicators/macd',\r\n Mfi = 'indicators/mfi',\r\n Obv = 'indicators/obv',\r\n Perf = 'indicators/perf',\r\n Rmi = 'indicators/rmi',\r\n Roc = 'indicators/roc',\r\n Rsi = 'indicators/rsi',\r\n Rvol = 'indicators/rvol',\r\n Rwi = 'indicators/rwi',\r\n Stofa = 'indicators/stofa',\r\n Stofu = 'indicators/stofu',\r\n Stosl = 'indicators/stosl',\r\n Trix = 'indicators/trix',\r\n Ult = 'indicators/ult',\r\n Vol = 'indicators/vol',\r\n Wr = 'indicators/wr',\r\n}\r\n\r\nexport enum OverlayType {\r\n Overlay = 'overlays/overlay',\r\n None = 'overlays/none',\r\n Bb = 'overlays/bb',\r\n Dch = 'overlays/dch',\r\n Ema = 'overlays/ema',\r\n Ema2 = 'overlays/ema2',\r\n Hilo = 'overlays/hilo',\r\n Hline = 'overlays/hline',\r\n Ic = 'overlays/ic',\r\n Icf = 'overlays/icf',\r\n Kch = 'overlays/kch',\r\n Patterns = 'overlays/patterns',\r\n Pp = 'overlays/pp',\r\n Sar = 'overlays/sar',\r\n Sma = 'overlays/sma',\r\n Sma2 = 'overlays/sma2',\r\n Str = 'overlays/str',\r\n Vp = 'overlays/vp',\r\n Vwap = 'overlays/vwap',\r\n}\r\n\r\nexport enum ChartEventDbType {\r\n Dividends = 'chartEvent/dividends',\r\n Split = 'chartEvent/split',\r\n Earnings = 'chartEvent/earnings',\r\n}\r\n\r\nexport enum ChartEventType {\r\n ChartEvent = 'chartEvent/chartEvent',\r\n Dividends = 'chartEvent/dividends',\r\n Split = 'chartEvent/split',\r\n Earnings = 'chartEvent/earnings',\r\n}\r\n\r\nexport enum ChartEventBadgeType {\r\n Dividends = 'chartEvent/dividends',\r\n Split = 'chartEvent/split',\r\n EarningsPositive = 'chartEvent/earnings',\r\n EarningsNegative = 'chartEvent/earningsNegative',\r\n EarningsNeutral = 'chartEvent/earningsNeutral',\r\n EarningsFuture = 'chartEvent/earningsFuture',\r\n}\r\n\r\nexport const ChartEventLabels: Record = {\r\n [ChartEventBadgeType.Dividends]: 'Dividends',\r\n [ChartEventBadgeType.Split]: 'Split',\r\n [ChartEventBadgeType.EarningsPositive]: 'Earnings & Revenue',\r\n [ChartEventBadgeType.EarningsNegative]: 'Earnings & Revenue',\r\n [ChartEventBadgeType.EarningsNeutral]: 'Earnings & Revenue',\r\n [ChartEventBadgeType.EarningsFuture]: 'Earnings & Revenue',\r\n}\r\n\r\ninterface LayoutRule {\r\n columns: number\r\n rows: number\r\n count: number\r\n gridAreas?: string[]\r\n}\r\n\r\nexport const LAYOUTS: Record = {\r\n '1h1v': { columns: 1, rows: 1, count: 1 },\r\n '1h2v': { columns: 1, rows: 2, count: 2 },\r\n '1h3v': { columns: 1, rows: 3, count: 3 },\r\n '2h1v': { columns: 2, rows: 1, count: 2 },\r\n '2h2v': { columns: 2, rows: 2, count: 4 },\r\n '3h1v': { columns: 3, rows: 1, count: 3 },\r\n '3h2v': { columns: 3, rows: 2, count: 6 },\r\n '1l2r': {\r\n columns: 2,\r\n rows: 2,\r\n count: 3,\r\n gridAreas: ['1 / 1 / 3 / 2', '1 / 2 / 2 / 3', '2 / 2 / 3 / 3'],\r\n },\r\n '1t2b': {\r\n columns: 2,\r\n rows: 2,\r\n count: 3,\r\n gridAreas: ['1 / 1 / 2 / 3', '2 / 1 / 3 / 2', '2 / 2 / 3 / 3'],\r\n },\r\n}\r\n\r\nexport const SORT_DIRECTION = {\r\n ASC: 'ASC',\r\n DESC: 'DESC',\r\n}\r\n\r\nexport const ICON_SIZE = {\r\n L: 32,\r\n}\r\n\r\n// Keep in sync with the copy in Website repo - Website/js/main/constants.ts\r\nexport enum TIMEFRAME {\r\n i1 = 'i1',\r\n i2 = 'i2',\r\n i3 = 'i3',\r\n i5 = 'i5',\r\n i10 = 'i10',\r\n i15 = 'i15',\r\n i30 = 'i30',\r\n h = 'h',\r\n h2 = 'h2',\r\n h4 = 'h4',\r\n d = 'd',\r\n w = 'w',\r\n m = 'm',\r\n}\r\n\r\nexport type TimeframeAndIntradayType = TIMEFRAME | 'intraday'\r\n\r\nexport const TIMEFRAMES_WITH_PRE_MARKET = [TIMEFRAME.i1, TIMEFRAME.i2, TIMEFRAME.i3, TIMEFRAME.i5]\r\n\r\nexport const IntradayTimeframeInterval = {\r\n [TIMEFRAME.i1]: 1,\r\n [TIMEFRAME.i2]: 2,\r\n [TIMEFRAME.i3]: 3,\r\n [TIMEFRAME.i5]: 5,\r\n [TIMEFRAME.i10]: 10,\r\n [TIMEFRAME.i15]: 15,\r\n [TIMEFRAME.i30]: 30,\r\n [TIMEFRAME.h]: 60,\r\n [TIMEFRAME.h2]: 120,\r\n [TIMEFRAME.h4]: 240,\r\n}\r\n\r\nexport const TimeframeLabelShort = {\r\n [TIMEFRAME.i1]: '1M',\r\n [TIMEFRAME.i2]: '2M',\r\n [TIMEFRAME.i3]: '3M',\r\n [TIMEFRAME.i5]: '5M',\r\n [TIMEFRAME.i10]: '10M',\r\n [TIMEFRAME.i15]: '15M',\r\n [TIMEFRAME.i30]: '30M',\r\n [TIMEFRAME.h]: '1H',\r\n [TIMEFRAME.h2]: '2H',\r\n [TIMEFRAME.h4]: '4H',\r\n [TIMEFRAME.d]: 'D',\r\n [TIMEFRAME.w]: 'W',\r\n [TIMEFRAME.m]: 'M',\r\n}\r\n\r\nexport enum DateRangeType {\r\n d1 = 'd1',\r\n d5 = 'd5',\r\n m1 = 'm1',\r\n m3 = 'm3',\r\n m6 = 'm6',\r\n ytd = 'ytd',\r\n y1 = 'y1',\r\n y2 = 'y2',\r\n y5 = 'y5',\r\n max = 'max',\r\n}\r\n\r\nexport const TIMEFRAME_SECONDS = {\r\n [TIMEFRAME.i1]: 60,\r\n [TIMEFRAME.i2]: 120,\r\n [TIMEFRAME.i3]: 180,\r\n [TIMEFRAME.i5]: 300,\r\n [TIMEFRAME.i10]: 600,\r\n [TIMEFRAME.i15]: 900,\r\n [TIMEFRAME.i30]: 1800,\r\n [TIMEFRAME.h]: 3600,\r\n [TIMEFRAME.h2]: 7200,\r\n [TIMEFRAME.h4]: 14400,\r\n [TIMEFRAME.d]: 86400,\r\n [TIMEFRAME.w]: 604800,\r\n [TIMEFRAME.m]: 2592000,\r\n}\r\n\r\nexport const CRYPTOS = {\r\n BTCUSD: 'BTCUSD',\r\n LTCUSD: 'LTCUSD',\r\n ETHUSD: 'ETHUSD',\r\n XRPUSD: 'XRPUSD',\r\n BCHUSD: 'BCHUSD',\r\n BTCEUR: 'BTCEUR',\r\n LTCEUR: 'LTCEUR',\r\n ETHEUR: 'ETHEUR',\r\n XRPEUR: 'XRPEUR',\r\n BCHEUR: 'BCHEUR',\r\n LTCBTC: 'LTCBTC',\r\n ETHBTC: 'ETHBTC',\r\n XRPBTC: 'XRPBTC',\r\n BCHBTC: 'BCHBTC',\r\n}\r\n\r\nexport enum SpecificChartFunctionality {\r\n default = 'default',\r\n quotePage = 'quotePage',\r\n quotePerf = 'quotePerf',\r\n chartPage = 'chartPage',\r\n smallIndex = 'smallIndex',\r\n offScreen = 'offScreen',\r\n forexPage = 'forexPage',\r\n futuresPage = 'futuresPage',\r\n cryptoPage = 'cryptoPage',\r\n}\r\n\r\nexport enum TextAlign {\r\n left = 'left',\r\n right = 'right',\r\n center = 'center',\r\n start = 'start',\r\n end = 'end',\r\n}\r\n\r\nexport enum TextBaseline {\r\n top = 'top',\r\n hanging_dont_use = 'hanging', // not supported - https://github.com/Automattic/node-canvas/wiki/Compatibility-Status#text-styles\r\n middle = 'middle',\r\n alphabetic = 'alphabetic',\r\n ideographic_dont_use = 'ideographic', // not supported - https://github.com/Automattic/node-canvas/wiki/Compatibility-Status#text-styles\r\n bottom = 'bottom',\r\n}\r\n\r\nexport enum ScaleType {\r\n Linear = 'linear',\r\n Percentage = 'percentage',\r\n Logarithmic = 'logarithmic',\r\n}\r\n\r\nexport enum QuotePollingIntervalInMs {\r\n Default = 2000,\r\n Free = 180000,\r\n Elite = Default,\r\n EliteStocksReduced = 60000,\r\n}\r\n\r\nexport const EXTRA_MARKET_BUFFER_MINUTES = 30\r\n\r\nexport const ScaleLabel = {\r\n [ScaleType.Linear]: 'Linear',\r\n [ScaleType.Percentage]: 'Percentage',\r\n [ScaleType.Logarithmic]: 'Logarithmic',\r\n}\r\n\r\nexport const PANE_HEIGHT_DEFAULT = {\r\n chart: 400,\r\n indicator: 120,\r\n}\r\n\r\nexport const INDICATOR_LABEL_HEIGHT = 24\r\n\r\nexport const MOBILE_BARS_TO_VIEW = 150 // 5 months of daily bars\r\n\r\nexport const MOBILE_VIEW_BREAKPOINT_WIDTH = 768\r\n\r\nexport const FREE_DATE_RANGES = ['m1', 'm3', 'm6', 'ytd', 'y1', 'y2', 'y5', 'max']\r\n\r\nexport const getTimeframeLabel = (timeframe: string) => {\r\n switch (timeframe) {\r\n case TIMEFRAME.i1:\r\n return '1 MIN'\r\n case TIMEFRAME.i2:\r\n return '2 MIN'\r\n case TIMEFRAME.i3:\r\n return '3 MIN'\r\n case TIMEFRAME.i5:\r\n return '5 MIN'\r\n case TIMEFRAME.i10:\r\n return '10 MIN'\r\n case TIMEFRAME.i15:\r\n return '15 MIN'\r\n case TIMEFRAME.i30:\r\n return '30 MIN'\r\n case TIMEFRAME.h:\r\n return '1 HR'\r\n case TIMEFRAME.h2:\r\n return '2 HR'\r\n case TIMEFRAME.h4:\r\n return '4 HR'\r\n case TIMEFRAME.d:\r\n return 'DAILY'\r\n case TIMEFRAME.w:\r\n return 'WEEKLY'\r\n case TIMEFRAME.m:\r\n return 'MONTHLY'\r\n default:\r\n return ''\r\n }\r\n}\r\n\r\nexport type ChartsPageQueryParams = {\r\n p: string\r\n t: string\r\n l: string\r\n r?: string\r\n i?: string\r\n sidebar?: string\r\n}\r\n\r\nexport type QuotePageQueryParams = {\r\n p?: string\r\n t: string\r\n r?: string\r\n i?: string\r\n ty?: QuotePageQueryChartTypes\r\n}\r\n\r\nexport enum QuotePageQueryChartTypes {\r\n l = 'l',\r\n c = 'c',\r\n cs = 'cs',\r\n hc = 'hc',\r\n ha = 'ha',\r\n o = 'o',\r\n p = 'p',\r\n}\r\n\r\nexport type ChartsOrQuotePageQueryParams = ChartsPageQueryParams | QuotePageQueryParams\r\n\r\nexport enum MacroTimeframe {\r\n // seconds = 'seconds',\r\n minutes = 'minutes',\r\n hours = 'hours',\r\n days = 'days',\r\n weeks = 'weeks',\r\n months = 'months',\r\n}\r\n\r\nexport const MicroMacroTimeframe = {\r\n [TIMEFRAME.i1]: {\r\n micro: 1,\r\n macro: MacroTimeframe.minutes,\r\n },\r\n [TIMEFRAME.i2]: {\r\n micro: 2,\r\n macro: MacroTimeframe.minutes,\r\n },\r\n [TIMEFRAME.i3]: {\r\n micro: 3,\r\n macro: MacroTimeframe.minutes,\r\n },\r\n [TIMEFRAME.i5]: {\r\n micro: 5,\r\n macro: MacroTimeframe.minutes,\r\n },\r\n [TIMEFRAME.i10]: {\r\n micro: 10,\r\n macro: MacroTimeframe.minutes,\r\n },\r\n [TIMEFRAME.i15]: {\r\n micro: 15,\r\n macro: MacroTimeframe.minutes,\r\n },\r\n [TIMEFRAME.i30]: {\r\n micro: 30,\r\n macro: MacroTimeframe.minutes,\r\n },\r\n [TIMEFRAME.h]: {\r\n micro: 1,\r\n macro: MacroTimeframe.hours,\r\n },\r\n [TIMEFRAME.h2]: {\r\n micro: 2,\r\n macro: MacroTimeframe.hours,\r\n },\r\n [TIMEFRAME.h4]: {\r\n micro: 4,\r\n macro: MacroTimeframe.hours,\r\n },\r\n [TIMEFRAME.d]: {\r\n micro: 1,\r\n macro: MacroTimeframe.days,\r\n },\r\n [TIMEFRAME.w]: {\r\n micro: 1,\r\n macro: MacroTimeframe.weeks,\r\n },\r\n [TIMEFRAME.m]: {\r\n micro: 1,\r\n macro: MacroTimeframe.months,\r\n },\r\n}\r\n\r\nexport const MicroTimeframeRange = (Object.keys(MicroMacroTimeframe) as TIMEFRAME[]).reduce(\r\n (prev, curr) => ({\r\n ...prev,\r\n [MicroMacroTimeframe[curr].macro]: prev[MicroMacroTimeframe[curr].macro]\r\n ? [...prev[MicroMacroTimeframe[curr].macro], MicroMacroTimeframe[curr].micro]\r\n : [MicroMacroTimeframe[curr].micro],\r\n }),\r\n {} as { [key in MacroTimeframe]: number[] }\r\n)\r\n\r\ntype IRange = {\r\n from?: number\r\n to?: number\r\n}\r\n\r\nexport type IVisibility = {\r\n [key in MacroTimeframe]?: IRange\r\n}\r\n\r\nexport enum SetVisibilityTo {\r\n currentAndAbove,\r\n currentAndBelow,\r\n currentOnly,\r\n all,\r\n}\r\n\r\nexport const QUOTE_FETCH_EVENT = 'quoteFetchEvent'\r\n\r\n// Keep in sync with the clone in Website repo in shared/is-stock-fast-refresh-available.ts\r\nexport const PREMARKET_AFTERMARKET_HOURS = 2.5\r\n\r\nexport const CHART_ELEMENT_ID = 'chart'\r\n","import { ChartConfigChartPane } from '../../../types/shared'\r\nimport { IndicatorType } from '../../constants/common'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport Element from '../../models/element'\r\nimport PaneModel from '../../models/pane'\r\nimport { HLC, compareHlc, incrementHlc, receiveHlc } from '../../utils/hlc'\r\nimport {\r\n AutoSaveChangeType,\r\n AutoSaveElement,\r\n AutoSaveElementDBRecord,\r\n DrawingChangeTimestamp,\r\n DrawingContainerType,\r\n} from './constants'\r\n\r\nexport function getContainerTypeFromPaneConfig(pane: ChartConfigChartPane) {\r\n const indicatorElement = pane.elements.find((el) => el.type.startsWith('indicators/'))\r\n if (indicatorElement) {\r\n return indicatorElement.type as DrawingContainerType\r\n }\r\n const chartElement = pane.elements.find((el) => el.type.startsWith('charts/'))\r\n if (chartElement) {\r\n return 'chart'\r\n }\r\n return null\r\n}\r\n\r\nexport function getContainerType(model: PaneModel) {\r\n const mainElement = model.mainElement()\r\n const indicatorType = mainElement?.instance?.type ?? null\r\n if (mainElement?.isIndicator() && indicatorType !== IndicatorType.None) {\r\n return indicatorType as DrawingContainerType\r\n }\r\n if (mainElement?.isChart()) {\r\n return 'chart'\r\n }\r\n return null\r\n}\r\n\r\nexport function updateInternalStoreWithChangedElement({\r\n element,\r\n changeType,\r\n currentInternalStore,\r\n lastUpdateTimestamp,\r\n}: {\r\n element: Element\r\n changeType: AutoSaveChangeType\r\n currentInternalStore: AutoSaveElement[]\r\n lastUpdateTimestamp: HLC\r\n}) {\r\n const paneModel = element.pane()\r\n const ticker = paneModel.getQuoteRawTicker()\r\n const containerType = getContainerType(paneModel)\r\n if (ticker && paneModel && containerType && (!element.destroyed || changeType === 'destroy')) {\r\n const instanceJson = element.instance.toAutosaveConfig()\r\n const newDrawing: AutoSaveElement = {\r\n elementId: element.elementId!,\r\n zIndex: element.zIndex,\r\n ticker,\r\n lastChange: lastUpdateTimestamp,\r\n changeType,\r\n containerType,\r\n elementAttrs: JSON.stringify(instanceJson),\r\n }\r\n\r\n const newInternalStore = [...currentInternalStore]\r\n const updateDrawingIndex = newInternalStore.findIndex(\r\n (drawingElement) => drawingElement.elementId === newDrawing.elementId\r\n )\r\n\r\n let shouldSyncAndSave = false\r\n if (updateDrawingIndex > -1) {\r\n const updatedRecord = newInternalStore[updateDrawingIndex]\r\n const hasChangedZIndex = updatedRecord.zIndex !== newDrawing.zIndex\r\n const hasChangedType = updatedRecord.changeType !== newDrawing.changeType\r\n const hasChangedAttrs = updatedRecord.elementAttrs !== newDrawing.elementAttrs\r\n const hasChange = hasChangedType || hasChangedAttrs || hasChangedZIndex\r\n if (\r\n !element.instance.isEditInProgress &&\r\n updatedRecord.ticker === ticker &&\r\n hasChange &&\r\n updatedRecord.changeType !== 'destroy'\r\n ) {\r\n newInternalStore[updateDrawingIndex] = newDrawing\r\n shouldSyncAndSave = true\r\n }\r\n } else {\r\n newInternalStore.push(newDrawing)\r\n shouldSyncAndSave = true\r\n }\r\n\r\n return {\r\n newInternalStore,\r\n shouldSyncAndSave,\r\n newDrawing,\r\n }\r\n }\r\n}\r\n\r\nexport function getTickersAndContainerTypesInLayoutModel(chartLayout: ChartLayout) {\r\n const tickers: string[] = []\r\n const containerTypes: Array = ['note']\r\n\r\n chartLayout.getAllPanes().forEach((paneModel) => {\r\n const ticker = paneModel.getQuoteRawTicker()\r\n const containerType = getContainerType(paneModel)\r\n if (ticker && !tickers.includes(ticker)) {\r\n tickers.push(ticker)\r\n }\r\n if (containerType && !containerTypes.includes(containerType)) {\r\n containerTypes.push(containerType)\r\n }\r\n })\r\n return { tickers, containerTypes }\r\n}\r\n\r\nexport function mergeUpdatedDrawingsToInternalStore({\r\n updatedDrawings,\r\n currentInternalStore,\r\n lastUpdateTimestamp,\r\n isRefetchAll,\r\n}: {\r\n updatedDrawings: AutoSaveElement[]\r\n currentInternalStore: AutoSaveElement[]\r\n lastUpdateTimestamp: DrawingChangeTimestamp\r\n isRefetchAll: boolean\r\n}) {\r\n let newLastUpdateTimestamp = lastUpdateTimestamp\r\n const newInternalStore = [...currentInternalStore]\r\n const updatedElementIds: string[] = []\r\n\r\n updatedDrawings.forEach((drawing) => {\r\n newLastUpdateTimestamp = receiveHlc(newLastUpdateTimestamp, drawing.lastChange)\r\n const drawingIndex = newInternalStore.findIndex(({ elementId }) => drawing.elementId === elementId)\r\n const currentDrawing = drawingIndex > -1 ? newInternalStore[drawingIndex] : null\r\n if (currentDrawing === null) {\r\n newInternalStore.push(drawing)\r\n updatedElementIds.push(drawing.elementId)\r\n } else if (currentDrawing.containerType === 'note' && isRefetchAll) {\r\n const currentNote = getElementNoteText(currentDrawing)\r\n const autoSavedNote = getElementNoteText(drawing)\r\n if (currentNote !== autoSavedNote) {\r\n newInternalStore[drawingIndex] = {\r\n ...drawing,\r\n lastChange: incrementHlc(receiveHlc(currentDrawing.lastChange, drawing.lastChange), Date.now()),\r\n elementAttrs: JSON.stringify({\r\n ...JSON.parse(drawing.elementAttrs),\r\n text: `${currentNote}\\r\\n${autoSavedNote}`,\r\n }),\r\n }\r\n }\r\n updatedElementIds.push(drawing.elementId)\r\n } else if (compareHlc(newInternalStore[drawingIndex].lastChange, drawing.lastChange) < 0) {\r\n newInternalStore[drawingIndex] = drawing\r\n updatedElementIds.push(drawing.elementId)\r\n }\r\n })\r\n return { newLastUpdateTimestamp, newInternalStore, updatedElementIds }\r\n}\r\n\r\nexport function getInitialStoreDrawings(): null | AutoSaveElement[] {\r\n const initialDrawings = (\r\n window.FinvizSettings?.initialDrawingsStore ?? window.FinvizChartsSettings?.initialDrawingsStore\r\n )?.drawings as null | AutoSaveElementDBRecord[]\r\n\r\n return initialDrawings?.map((item) => getAutosaveElementFromDBRecord(item)) ?? null\r\n}\r\n\r\nexport function handleCallMethodOnAllDrawings({\r\n chartLayoutModel,\r\n elementMethod,\r\n}: {\r\n chartLayoutModel: ChartLayout\r\n elementMethod: keyof Pick\r\n}) {\r\n chartLayoutModel.getAllElements().forEach((element) => {\r\n if (element.isDrawing()) {\r\n element[elementMethod]()\r\n }\r\n })\r\n}\r\n\r\nexport function getNoteElementId(ticker: string) {\r\n return `note-${ticker}`\r\n}\r\n\r\nexport function getElementNoteText(noteElement?: AutoSaveElement) {\r\n return (noteElement ? JSON.parse(noteElement.elementAttrs)?.text : '') ?? ''\r\n}\r\n\r\nexport function getTickerNoteText({ ticker, elements }: { ticker: string; elements: AutoSaveElement[] }) {\r\n const noteElement = elements.find(({ elementId }) => elementId === getNoteElementId(ticker))\r\n return getElementNoteText(noteElement)\r\n}\r\n\r\nexport function getAutosaveElementFromDBRecord(item: AutoSaveElementDBRecord): AutoSaveElement {\r\n return {\r\n elementId: item.elementId,\r\n ticker: item.ticker,\r\n zIndex: item.zIndex,\r\n changeType: item.changeType,\r\n containerType: item.containerType,\r\n elementAttrs: item.elementAttrs,\r\n lastChange: {\r\n ts: item.lastChangeTimestamp,\r\n count: item.lastChangeCounter,\r\n uuid: item.lastChangeNodeUUID,\r\n },\r\n }\r\n}\r\n\r\nexport function getDBRecordFromAutosaveElement(item: AutoSaveElement): Omit {\r\n return {\r\n elementId: item.elementId,\r\n ticker: item.ticker,\r\n zIndex: item.zIndex,\r\n changeType: item.changeType,\r\n containerType: item.containerType,\r\n elementAttrs: JSON.stringify(item.elementAttrs),\r\n lastChangeTimestamp: item.lastChange.ts,\r\n lastChangeCounter: item.lastChange.count,\r\n lastChangeNodeUUID: item.lastChange.uuid,\r\n }\r\n}\r\n","import {\r\n Button,\r\n ButtonComponentProps,\r\n ConfirmationDialog,\r\n Delayed,\r\n DialogDismiss,\r\n Popover,\r\n PopoverPlacement,\r\n PopoverRounding,\r\n PopoverStateReturn,\r\n PopoverTheme,\r\n PopoverTrigger,\r\n Spinner,\r\n usePopoverState,\r\n} from '@finviz/website'\r\nimport classNames from 'classnames'\r\nimport React from 'react'\r\n\r\nimport { CHART_ELEMENT_ID, SpecificChartFunctionality } from '../../constants/common'\r\nimport { chartSettingsAsyncModule } from '../../controllers/chart-settings/async-modules'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { useAsyncModule } from '../../utils/async-modules-utils'\r\nimport { encodeQueryString } from '../../utils/query_string'\r\nimport { useChartLayoutGlobalModelAsync } from '../../utils/useChartLayoutGlobalModelAsync'\r\n\r\nconst utmCampaign: Partial> = {\r\n [SpecificChartFunctionality.quotePage]: 'quote-settings-button',\r\n [SpecificChartFunctionality.futuresPage]: 'futures-settings-button',\r\n [SpecificChartFunctionality.forexPage]: 'forex-settings-button',\r\n [SpecificChartFunctionality.cryptoPage]: 'crypto-settings-button',\r\n}\r\n\r\ninterface ScrollableChartSettingsPopoverProps {\r\n isOpen: boolean\r\n state: PopoverStateReturn\r\n}\r\n\r\nexport function PopoverInner({ hidePopover }: { hidePopover: () => void }) {\r\n const [chartSettingsModule] = useAsyncModule({\r\n ...chartSettingsAsyncModule,\r\n isSuspenseMode: true,\r\n errorSeverity: 'medium',\r\n onError: () => hidePopover(),\r\n })\r\n\r\n const { ChartSettings } = chartSettingsModule ?? {}\r\n\r\n return \r\n}\r\n\r\nexport const ScrollableChartSettingsPopover = React.memo(function ScrollableChartSettingsPopover({\r\n state,\r\n isOpen,\r\n}: ScrollableChartSettingsPopoverProps) {\r\n const { forceGlobalRerender, getIsConfigChanged, chartLayoutModel } = useChartLayoutGlobalModelAsync()\r\n const confirmationDialogState = usePopoverState()\r\n const hidePopover = state.hide\r\n\r\n const checkChangesAndOpenDiscard = React.useCallback(\r\n (ev: Event | React.MouseEvent) => {\r\n if (getIsConfigChanged()) {\r\n ev.preventDefault()\r\n confirmationDialogState.show()\r\n return\r\n }\r\n hidePopover()\r\n },\r\n [confirmationDialogState, getIsConfigChanged, hidePopover]\r\n )\r\n\r\n const discardChangesAndHide = React.useCallback(() => {\r\n forceGlobalRerender()\r\n // We need to defer the hide so that the rerender finishes first\r\n setTimeout(hidePopover)\r\n }, [forceGlobalRerender, hidePopover])\r\n\r\n const buttonPosition = React.useMemo(() => {\r\n const popoverContentElement = state.getState().disclosureElement\r\n const { top = 0, height = 32 } = popoverContentElement?.getBoundingClientRect() ?? {}\r\n return top + height + window.scrollY\r\n // Only recount on open\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [isOpen])\r\n\r\n const chartHeight = React.useMemo(() => {\r\n const chartElement = document.getElementById(CHART_ELEMENT_ID)\r\n return chartElement?.clientHeight ?? 0\r\n // Only recount on open\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [isOpen])\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n }\r\n >\r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n \r\n Discard changes\r\n \r\n \r\n }\r\n >\r\n Are you sure you want to discard changes?\r\n \r\n \r\n )\r\n})\r\n\r\ninterface ChartSettingsButtonProps extends ButtonComponentProps {\r\n isPremium: boolean\r\n placement?: PopoverPlacement\r\n model: ChartLayout\r\n}\r\n\r\nexport function ChartSettingsButton({\r\n isPremium,\r\n model,\r\n placement,\r\n ...props\r\n}: React.PropsWithChildren) {\r\n const settingsPopoverState = usePopoverState({ placement: placement ?? 'bottom' })\r\n const isOpen = settingsPopoverState.useState('open')\r\n\r\n const buttonProps = React.useMemo(() => {\r\n if (model.specificChartFunctionality !== SpecificChartFunctionality.quotePage && !isPremium) {\r\n return {\r\n as: 'a',\r\n href: `/elite.ashx?${encodeQueryString({\r\n utm_source: 'finviz',\r\n utm_medium: 'banner',\r\n utm_campaign: utmCampaign[model.specificChartFunctionality],\r\n })}`,\r\n } as ButtonComponentProps<'a'>\r\n }\r\n\r\n return {\r\n as: PopoverTrigger,\r\n state: settingsPopoverState,\r\n active: isOpen,\r\n } as ButtonComponentProps\r\n }, [model.specificChartFunctionality, isPremium, settingsPopoverState, isOpen])\r\n\r\n return (\r\n <>\r\n \r\n \r\n \r\n )\r\n}\r\n","import * as React from 'react'\r\nimport { useLocation, useNavigate } from 'react-router-dom'\r\n\r\nimport { ChartsOrQuotePageQueryParams, SpecificChartFunctionality } from '../../constants/common'\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport { useModelRef } from '../../model-hooks/useModelRef'\r\nimport Chart from '../../models/chart'\r\nimport Quote from '../../models/quote'\r\nimport { QuoteFetchType } from '../../models/quote/constants'\r\nimport { createRequestAbortController, removeFromAbortCache } from '../../utils/abort_controller'\r\nimport { decodeQueryString, encodeQueryString } from '../../utils/query_string'\r\nimport { getLeftOffset } from '../renderUtils'\r\n\r\nconst getQuoteRequestKey = (chartModel: Chart) =>\r\n `quoteReq-${chartModel.ticker}-${chartModel.instrument}-${chartModel.id}`\r\n\r\nexport function useChartControls({\r\n chartModel: unwatchedChartModel,\r\n isInteractive,\r\n}: {\r\n chartModel: Chart | null\r\n isInteractive: boolean\r\n}) {\r\n const location = useLocation()\r\n const navigate = useNavigate()\r\n const chartModel = useModelState(unwatchedChartModel, {\r\n watchProperties: ['ticker', 'timeframe', 'dateRange'],\r\n })\r\n const chartLayoutModel = useModelState(chartModel?.chart_layout() ?? null, {\r\n watchProperties: ['idea', 'settings'],\r\n })\r\n const chartModelRef = useModelRef(chartModel)\r\n const [isLoading, setIsLoading] = React.useState(false)\r\n const abortControllerKeyRef = React.useRef('')\r\n const isIdeaChart = !!chartLayoutModel?.idea?.id\r\n\r\n const updateChartModelWithNewQuote = React.useCallback((quote: Quote) => {\r\n const chart = chartModelRef.current\r\n if (!chart) {\r\n return\r\n }\r\n\r\n const chartLayoutModel = chart.chart_layout()\r\n const isSameTicker = chart.getQuoteRawTicker() === quote.getRawTicker()\r\n\r\n chart.getAllPanes().forEach((pane) => {\r\n if (!!pane.getChartOrIndicatorElement()) {\r\n pane.updateAttribute('scaleRange', null)\r\n }\r\n })\r\n\r\n chart.updateAttributes({ leftOffset: getLeftOffset({ quote, chartModel: chart }), quote, isScrolled: true })\r\n\r\n // Refetch all other chart quotes as the main one is already refetched so we can filter it out but other quotes (from perf for example) should be refetched as well\r\n chart\r\n .getAllQuotes()\r\n .filter((chartQuote) => !chartQuote.eql(quote))\r\n .forEach((quote) => {\r\n quote.fetchData({ fetchType: QuoteFetchType.NewerData })\r\n })\r\n\r\n const chartPane = chart.getChartPane()\r\n chartLayoutModel.activeChartEvent?.instance.toggleIsOpen(false)\r\n\r\n const elements = [...chart.getAllElements(), ...(chartPane?.getAllChartEvents(false) ?? [])]\r\n for (const element of elements) {\r\n const isDrawing = element.isDrawing()\r\n const isChartEvent = element.isChartEvent()\r\n if (isDrawing || isChartEvent) {\r\n // We want to remove all drawings on ticker change but if autosave is enabled we let the autosave hook take care of that\r\n if (isSameTicker && (isChartEvent || chartLayoutModel.isPreserveDrawingsActive)) {\r\n element.instance.updateScales()\r\n } else {\r\n element.destroyCascade()\r\n }\r\n }\r\n }\r\n\r\n chart.setChartEvents(quote.chartEvents, true)\r\n\r\n chartPane?.updateChartEventsZIndexes()\r\n\r\n // The only dependency here is a ref , so no need to add it to dependencies\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [])\r\n\r\n const fetchQuote = React.useCallback(async () => {\r\n if (!isInteractive || !chartModel || isIdeaChart) {\r\n return\r\n }\r\n setIsLoading(true)\r\n\r\n const { ticker, instrument, timeframe, hasChartEvents } = chartModel\r\n const { premarket, aftermarket } = Quote.first()\r\n const patterns = chartModel.getHasPatterns()\r\n const currentQuote = chartModel.quote()\r\n if (currentQuote.getRawTicker() !== ticker || currentQuote.timeframe !== timeframe) {\r\n abortControllerKeyRef.current = getQuoteRequestKey(chartModel)\r\n const abortController = createRequestAbortController({\r\n key: abortControllerKeyRef.current,\r\n shouldAbortRunningRequest: !Quote.select(\r\n (quote) =>\r\n quote.ticker === ticker &&\r\n quote.timeframe === timeframe &&\r\n quote.isFetching &&\r\n chartModel.chart_layout().isIdeaId(quote.ideaID)\r\n ),\r\n })\r\n\r\n const quote = await Quote.get({\r\n ticker,\r\n instrument,\r\n timeframe,\r\n options: {\r\n premarket,\r\n aftermarket,\r\n events: hasChartEvents,\r\n patterns,\r\n cachePredicate: (quote) => quote.ideaID === undefined,\r\n fetchNewDataOnCachedQuote: true,\r\n },\r\n abortController,\r\n })\r\n\r\n if (quote.wasFetchAborted) {\r\n // Check if the quote is also used in other chars, as the quote may be reused if we already have a quote with the same options\r\n const isQuoteUsedInOtherCharts = chartModel\r\n .chart_layout()\r\n .getAllCharts()\r\n .filter((chart) => !chartModel.eql(chart))\r\n .some((chart) => quote.eql(chart.quote()))\r\n\r\n // If the quote hasn't been fetched yet and is not anywhere else we can destroy the model\r\n if (quote.fetchedAt === -1 && !isQuoteUsedInOtherCharts) {\r\n quote.destroy()\r\n }\r\n\r\n return\r\n }\r\n\r\n removeFromAbortCache(abortControllerKeyRef.current)\r\n\r\n updateChartModelWithNewQuote(quote)\r\n }\r\n\r\n setIsLoading(false)\r\n\r\n // We don't want to create new function on any chartModel change as it may be the same chart with different object instance\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [\r\n chartModel?.id,\r\n chartModel?.ticker,\r\n chartModel?.timeframe,\r\n chartModel?.instrument,\r\n isIdeaChart,\r\n updateChartModelWithNewQuote,\r\n isInteractive,\r\n ])\r\n\r\n React.useEffect(() => {\r\n fetchQuote()\r\n }, [fetchQuote])\r\n\r\n // There are several ways how to turn off dateRange, e.g. moving the charts\r\n // This effect listens to dateRange changes on chartmodel and updates the url if there's a change\r\n // Consider refactoring this part so we only update chart models on route changes not the other way around\r\n React.useEffect(() => {\r\n if (chartModel) {\r\n const decodedQueryString = decodeQueryString(location.search)\r\n const rangesArray = chartModel\r\n .chart_layout()\r\n .getAllCharts()\r\n .map((chart) => chart.dateRange)\r\n const ranges = rangesArray.every((i) => !i) ? undefined : rangesArray.join(',')\r\n\r\n if (decodedQueryString.r !== ranges) {\r\n navigate({\r\n search: `?${encodeQueryString({\r\n ...decodedQueryString,\r\n r: ranges,\r\n })}`,\r\n })\r\n }\r\n }\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [chartModel?.dateRange])\r\n\r\n // https://github.com/finvizhq/charts/pull/1253/files#r1052266805\r\n // React.useEffect(\r\n // () => () => {\r\n // if (isInteractive && abortControllerKeyRef.current !== '') {\r\n // abortRequest(abortControllerKeyRef.current)\r\n // }\r\n // },\r\n // [isInteractive]\r\n // )\r\n\r\n React.useEffect(() => {\r\n const chart = chartModelRef.current\r\n const quote = chart?.quote()\r\n\r\n let shouldRecalculateOnCharts = false\r\n if (chartLayoutModel?.specificChartFunctionality === SpecificChartFunctionality.chartPage && !isIdeaChart) {\r\n const settings = chartLayoutModel?.settings\r\n const barWidth = 3\r\n const barMargin = 1\r\n if (settings) {\r\n const hasSameBarWidth = [\r\n settings.ChartSettings.center.barWidth,\r\n settings.IndicatorSettings.center.barWidth,\r\n ].every((value) => value === barWidth)\r\n const hasSameBarMargin = [\r\n settings.ChartSettings.center.barMargin,\r\n settings.IndicatorSettings.center.barMargin,\r\n ].every((value) => value === barMargin)\r\n\r\n shouldRecalculateOnCharts = !hasSameBarWidth || !hasSameBarMargin\r\n if (shouldRecalculateOnCharts) {\r\n settings.ChartSettings.center.barWidth = barWidth\r\n settings.IndicatorSettings.center.barWidth = barWidth\r\n settings.ChartSettings.center.barMargin = barMargin\r\n settings.IndicatorSettings.center.barMargin = barMargin\r\n\r\n chartLayoutModel.updateAttributes({ settings })\r\n }\r\n }\r\n }\r\n\r\n if (\r\n chart &&\r\n quote &&\r\n (chartLayoutModel?.specificChartFunctionality === SpecificChartFunctionality.quotePage ||\r\n shouldRecalculateOnCharts) &&\r\n !isIdeaChart\r\n ) {\r\n const leftOffset = getLeftOffset({ quote, chartModel: chart })\r\n chart.updateAttributes({ leftOffset })\r\n }\r\n // This effect should run only on timeframe change & idea change\r\n // The reason we need to recalculate the left offset is that quote timeframe change changes chart and chart bars sizes\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [chartModel?.quote()?.timeframe, chartLayoutModel?.settings, isIdeaChart])\r\n\r\n return { isLoading }\r\n}\r\n","import Spine from '@finviz/spine'\r\nimport * as React from 'react'\r\n\r\nexport function useModelRef(model: Model | null) {\r\n const modelRef = React.useRef(model)\r\n\r\n React.useEffect(() => {\r\n modelRef.current = model\r\n }, [model])\r\n\r\n return modelRef\r\n}\r\n","import {\r\n Notification,\r\n Paragraph,\r\n generatePathForTimeframeDateRange,\r\n getDateRangeGroupsWithHref,\r\n timeframeUtm,\r\n useNotification,\r\n} from '@finviz/website'\r\nimport React from 'react'\r\nimport { useLocation } from 'react-router-dom'\r\n\r\nimport { Instrument } from '../../../types/shared'\r\nimport { SpecificChartFunctionality, TIMEFRAME, TimeframeAndIntradayType } from '../../constants/common'\r\nimport Chart from '../../models/chart'\r\nimport Quote from '../../models/quote'\r\nimport { dateFromUnixTimestamp } from '../../utils'\r\nimport { getChartStartEndDates, getVisibleBarsNumber } from '../renderUtils'\r\nimport { useChartsPathLocation } from './use-charts-path-location'\r\nimport { getTimeframeGroupsWithHref } from './utils'\r\n\r\ninterface IPathForTimeframeDateRangeProps {\r\n timeframe: TimeframeAndIntradayType\r\n dateRange?: string | null\r\n ticker?: string\r\n}\r\n\r\nexport interface IDateRange {\r\n value: string\r\n timeframe: TIMEFRAME\r\n}\r\n\r\nexport function useChartModelCustomDateRangeValues({\r\n chartModel,\r\n isPremium,\r\n}: {\r\n chartModel: Chart | null\r\n isPremium: boolean\r\n}) {\r\n const notificationContext = useNotification()\r\n const location = useLocation()\r\n const [isFetching, setIsFetching] = React.useState(false)\r\n const chartLayoutModel = chartModel?.chart_layout() || null\r\n const chartIndex = chartLayoutModel?.getAllCharts().findIndex((chart) => chartModel!.eql(chart)) ?? -1\r\n const { getChartsToPath } = useChartsPathLocation({ chartLayoutModel, chartIndex })\r\n const specificChartFunctionality = chartLayoutModel?.specificChartFunctionality ?? SpecificChartFunctionality.default\r\n\r\n const anchorDate = React.useMemo(() => {\r\n if (!chartModel) return new Date()\r\n const quote = chartModel.quote()\r\n return dateFromUnixTimestamp(quote.date[quote.date.length - 1])\r\n }, [chartModel])\r\n\r\n const generateChartLayoutRouterPath = React.useCallback(\r\n ({ ticker, timeframe, dateRange }: IPathForTimeframeDateRangeProps) => {\r\n if (specificChartFunctionality === SpecificChartFunctionality.chartPage) {\r\n return getChartsToPath({\r\n ticker: ticker,\r\n timeframe: timeframe as TIMEFRAME,\r\n dateRange: dateRange,\r\n })\r\n }\r\n\r\n return generatePathForTimeframeDateRange({\r\n isPremium,\r\n pathname: location.pathname,\r\n timeframe: timeframe,\r\n dateRange: dateRange,\r\n utmCampaign: timeframeUtm[specificChartFunctionality],\r\n })\r\n },\r\n [getChartsToPath, isPremium, specificChartFunctionality, location.pathname]\r\n )\r\n\r\n const timeframeGroupsWithHref = (isPremium: boolean) =>\r\n getTimeframeGroupsWithHref({\r\n isPremium,\r\n generatePath: (timeFrame) => generateChartLayoutRouterPath({ timeframe: timeFrame.value, dateRange: null }),\r\n })\r\n\r\n const dateRangeGroupsWithHref = ({\r\n isPremium,\r\n customRange,\r\n instrument,\r\n }: {\r\n isPremium: boolean\r\n customRange?: string\r\n instrument: Instrument\r\n }) =>\r\n getDateRangeGroupsWithHref({\r\n isPremium,\r\n customRange,\r\n instrument,\r\n generatePath: (dateRange: { timeframe?: TIMEFRAME; value: string }) =>\r\n generateChartLayoutRouterPath({ timeframe: dateRange.timeframe!, dateRange: dateRange.value }),\r\n })\r\n\r\n const handleCustomDateRangeValidation = async (dateRangeState: { value: string | null; timeframe: TIMEFRAME }) => {\r\n if (dateRangeState.value !== null) {\r\n const { timeframe, ticker, instrument, premarket, aftermarket } = chartModel?.quote() || {}\r\n const patterns = !!chartModel?.getHasPatterns()\r\n if (!anchorDate || !instrument || !ticker || !timeframe || !dateRangeState.value) return false\r\n setIsFetching(true)\r\n const quote = await Quote.get({\r\n ticker,\r\n instrument,\r\n timeframe: dateRangeState.timeframe,\r\n options: {\r\n premarket,\r\n aftermarket,\r\n patterns,\r\n cachePredicate: (quote) => quote.ideaID === undefined,\r\n fetchNewDataOnCachedQuote: true,\r\n },\r\n })\r\n setIsFetching(false)\r\n\r\n const { numOfVisibleBars } = getVisibleBarsNumber({\r\n ...getChartStartEndDates({ dateRange: dateRangeState.value, quote }),\r\n quote,\r\n dateRange: dateRangeState.value,\r\n })\r\n if (numOfVisibleBars === 0) {\r\n notificationContext.show(\r\n } timeoutInMs={6000}>\r\n \r\n There are no data for the selected date range. Try selecting different dates.\r\n \r\n \r\n )\r\n\r\n return false\r\n }\r\n }\r\n return true\r\n }\r\n\r\n return {\r\n anchorDate,\r\n generateChartLayoutRouterPath,\r\n timeframeGroupsWithHref,\r\n dateRangeGroupsWithHref,\r\n isFetching,\r\n handleCustomDateRangeValidation,\r\n }\r\n}\r\n","import * as React from 'react'\r\nimport { useLocation } from 'react-router-dom'\r\n\r\nimport { ChartsPageQueryParams, LAYOUTS, LayoutType, TIMEFRAME } from '../../constants/common'\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport { ChartSyncablePart } from '../../models/chart/contstants'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { getIsMobilePortrait } from '../../utils'\r\nimport { decodeQueryString, encodeQueryString } from '../../utils/query_string'\r\n\r\nexport function useChartsPathLocation({\r\n chartLayoutModel: unwatchedChartLayoutModel,\r\n chartIndex = -1,\r\n}: {\r\n chartLayoutModel: ChartLayout | null\r\n chartIndex?: number\r\n}) {\r\n const location = useLocation()\r\n const chartLayoutModel = useModelState(unwatchedChartLayoutModel, {\r\n watchProperties: ['syncChartParts'],\r\n })\r\n const hasSyncedTimeframe = React.useMemo(\r\n () => !!chartLayoutModel?.getIsChartPartInSync(ChartSyncablePart.Timeframe),\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n [chartLayoutModel?.syncChartParts]\r\n )\r\n const hasSyncedTicker = React.useMemo(\r\n () => !!chartLayoutModel?.getIsChartPartInSync(ChartSyncablePart.Ticker),\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n [chartLayoutModel?.syncChartParts]\r\n )\r\n\r\n const getChartsToPath = React.useCallback(\r\n ({\r\n ticker,\r\n timeframe,\r\n dateRange,\r\n layout,\r\n }: {\r\n timeframe?: TIMEFRAME\r\n dateRange?: string | null\r\n ticker?: string\r\n layout?: LayoutType\r\n }) => {\r\n if (!chartLayoutModel) {\r\n return {\r\n pathname: location.pathname,\r\n search: '',\r\n }\r\n }\r\n\r\n const decodedSearch = decodeQueryString(location.search)\r\n const { count } = LAYOUTS[(layout ?? chartLayoutModel.layout) as LayoutType]\r\n const urlTickers = decodedSearch.t?.split(',') ?? []\r\n const urlTimeframes = decodedSearch.p?.split(',') ?? []\r\n const urlDateRanges = decodedSearch.r?.split(',')\r\n\r\n const chartsArrayPlaceholder = Array.from({ length: count })\r\n const tickers = chartsArrayPlaceholder\r\n .map((_, index) => {\r\n const currentTicker = urlTickers[index] ?? urlTickers[urlTickers.length - 1]\r\n return (chartIndex === index || hasSyncedTicker) && ticker ? ticker : currentTicker\r\n })\r\n .join(',')\r\n const timeframes = chartsArrayPlaceholder\r\n .map((_, index) => {\r\n const currentTimeframe = urlTimeframes[index] ?? urlTimeframes[urlTimeframes.length - 1]\r\n return (chartIndex === index || hasSyncedTimeframe) && timeframe ? timeframe : currentTimeframe\r\n })\r\n .join(',')\r\n const ranges = chartsArrayPlaceholder\r\n .map((_, index) => {\r\n const currentDaterange = urlDateRanges\r\n ? urlDateRanges[index] ?? urlDateRanges[urlDateRanges.length - 1]\r\n : undefined\r\n return (chartIndex === index || hasSyncedTimeframe) && dateRange !== undefined ? dateRange : currentDaterange\r\n })\r\n .join(',')\r\n\r\n return {\r\n pathname: location.pathname,\r\n search: `?${encodeQueryString({\r\n t: tickers,\r\n p: timeframes,\r\n r: ranges.split(',').some(Boolean) ? ranges : undefined,\r\n l: layout ?? chartLayoutModel.layout,\r\n sidebar: getIsMobilePortrait() ? undefined : decodedSearch.sidebar,\r\n })}`,\r\n }\r\n },\r\n [chartLayoutModel, chartIndex, location, hasSyncedTicker, hasSyncedTimeframe]\r\n )\r\n\r\n return { getChartsToPath }\r\n}\r\n","import { IconNameType, getTimeframeGroups } from '@finviz/website'\r\nimport { type To } from 'react-router-dom'\r\n\r\nimport { TimeframeAndIntradayType } from '../../constants/common'\r\n\r\ninterface ITimeFrame {\r\n value: TimeframeAndIntradayType\r\n label: string\r\n labelShort: string\r\n labelPageTitle?: string\r\n}\r\n\r\ninterface ITimeframeGroup {\r\n label: string\r\n timeframes: ITimeFrame[]\r\n}\r\n\r\nexport function getTimeframeGroupsWithHref({\r\n isPremium,\r\n generatePath,\r\n}: {\r\n isPremium: boolean\r\n generatePath: (timeframe: ITimeFrame) => To\r\n}) {\r\n return getTimeframeGroups(isPremium).map((timeFrameGroup: ITimeframeGroup) => ({\r\n label: timeFrameGroup.label,\r\n timeframes: timeFrameGroup.timeframes.map((timeFrame) => ({\r\n ...timeFrame,\r\n href: generatePath(timeFrame),\r\n })),\r\n }))\r\n}\r\n\r\nexport enum QuoteNodeChartTypes {\r\n candlesticksimple = 'candlesticksimple',\r\n candlestick = 'candlestick',\r\n line = 'line',\r\n ohlc = 'ohlc',\r\n heikinashi = 'heikinashi',\r\n hollowcandlestick = 'hollowcandlestick',\r\n}\r\n\r\nexport enum QuoteUrlChartTypes {\r\n cs = 'cs',\r\n c = 'c',\r\n l = 'l',\r\n o = 'o',\r\n ha = 'ha',\r\n hc = 'hc',\r\n}\r\n\r\nexport const QuoteShortToLongType = {\r\n [QuoteUrlChartTypes.cs]: QuoteNodeChartTypes.candlesticksimple,\r\n [QuoteUrlChartTypes.c]: QuoteNodeChartTypes.candlestick,\r\n [QuoteUrlChartTypes.l]: QuoteNodeChartTypes.line,\r\n [QuoteUrlChartTypes.o]: QuoteNodeChartTypes.ohlc,\r\n [QuoteUrlChartTypes.ha]: QuoteNodeChartTypes.heikinashi,\r\n [QuoteUrlChartTypes.hc]: QuoteNodeChartTypes.hollowcandlestick,\r\n} as const\r\n\r\nexport const QuoteLongToShortType = {\r\n [QuoteNodeChartTypes.candlesticksimple]: QuoteUrlChartTypes.cs,\r\n [QuoteNodeChartTypes.candlestick]: QuoteUrlChartTypes.c,\r\n [QuoteNodeChartTypes.line]: QuoteUrlChartTypes.l,\r\n [QuoteNodeChartTypes.ohlc]: QuoteUrlChartTypes.o,\r\n [QuoteNodeChartTypes.heikinashi]: QuoteUrlChartTypes.ha,\r\n [QuoteNodeChartTypes.hollowcandlestick]: QuoteUrlChartTypes.hc,\r\n} as const\r\n\r\nexport type TypeBaseOption = {\r\n label: string\r\n value: QuoteNodeChartTypes\r\n icon: IconNameType\r\n href?: string\r\n}\r\nexport const DEFAULT_TYPES: TypeBaseOption[] = [\r\n { icon: 'candleBarBasic', value: QuoteNodeChartTypes.candlestick, label: 'Candle' },\r\n { icon: 'lineChartType', value: QuoteNodeChartTypes.line, label: 'Line' },\r\n { icon: 'ohlcChartType', value: QuoteNodeChartTypes.ohlc, label: 'OHLC' },\r\n { icon: 'candleBarHollow', value: QuoteNodeChartTypes.hollowcandlestick, label: 'Hollow Candle' },\r\n { icon: 'candleBarHeikinAshi', value: QuoteNodeChartTypes.heikinashi, label: 'Heikin Ashi' },\r\n]\r\n\r\nexport const FREE_TYPES_QUOTE: TypeBaseOption[] = [\r\n { icon: 'candleBarBasic', value: QuoteNodeChartTypes.candlesticksimple, label: 'Candle - simple' },\r\n { icon: 'candleBarBasic', value: QuoteNodeChartTypes.candlestick, label: 'Candle - advanced' },\r\n // Filter out the candle from DEFAULT_TYPES, we’re naming it differently\r\n ...DEFAULT_TYPES.filter((type) => type.value !== QuoteNodeChartTypes.candlestick),\r\n]\r\n\r\nexport const FREE_TYPES_QUOTE_VALUES = ['candlesticksimple', 'candlestick', 'line']\r\n","export const chartEventsAsyncModule = {\r\n importFn: () => import(/* webpackChunkName: \"chart-events\" */ './module-entry'),\r\n cacheKey: 'chart-events',\r\n}\r\n","export const chartSettingsAsyncModule = {\r\n importFn: () => import(/* webpackChunkName: \"chart-settings\" */ './module-entry'),\r\n cacheKey: 'chart-settings',\r\n}\r\n\r\nexport const useChartLayoutGlobalModelAsyncModule = {\r\n importFn: () =>\r\n import(/* webpackChunkName: \"use-chart-layout-global-model\" */ './useChartLayoutGlobalModel/module-entry'),\r\n cacheKey: 'use-chart-layout-global-model',\r\n}\r\n\r\nexport const preventClosingUnsavedChangesAsyncModule = {\r\n importFn: () =>\r\n import(/* webpackChunkName: \"prevent-closing-unsaved-changes\" */ './PreventClosingUnsavedChanges/module-entry'),\r\n cacheKey: 'prevent-closing-unsaved-changes',\r\n}\r\n","import { InputColorPicker, convertColorToHEX } from '@finviz/website'\r\nimport * as React from 'react'\r\n\r\ninterface BackgroundInputProps {\r\n label: string\r\n value: string\r\n onChange: (color: string) => void\r\n}\r\n\r\nexport function BackgroundInput({ label = 'Background', value, onChange }: BackgroundInputProps) {\r\n return (\r\n \r\n )\r\n}\r\n","import { InputColorPicker, Paragraph, RangeSlider } from '@finviz/website'\r\nimport React, { useCallback } from 'react'\r\n\r\nimport { ObjectHash } from '../../types/shared'\r\n\r\ninterface ColorRangeRowInputProps {\r\n label: string\r\n colorValue: string\r\n colorTestId: string\r\n rangeValue: string\r\n rangeTestId: string\r\n rangeLabel: string\r\n rangeProps: ObjectHash\r\n onChange: (colorValue: string, value: string) => void\r\n}\r\n\r\nexport function ColorRangeRowInput({\r\n label,\r\n colorValue,\r\n colorTestId,\r\n rangeValue,\r\n rangeTestId,\r\n rangeLabel,\r\n rangeProps,\r\n onChange,\r\n}: ColorRangeRowInputProps) {\r\n const handleRangeChange = useCallback(\r\n (ev) => {\r\n const value = ev.currentTarget.value\r\n onChange(colorValue, value)\r\n },\r\n [onChange, colorValue]\r\n )\r\n const handleColorChange = useCallback(\r\n (color) => {\r\n onChange(color, rangeValue)\r\n },\r\n [onChange, rangeValue]\r\n )\r\n return (\r\n

\r\n
\r\n \r\n
\r\n
\r\n \r\n {rangeValue}\r\n \r\n }\r\n onChange={handleRangeChange}\r\n value={Number(rangeValue)}\r\n data-testid={rangeTestId}\r\n />\r\n
\r\n
\r\n )\r\n}\r\n","import { convertColorToHEX } from '@finviz/website'\r\nimport * as React from 'react'\r\n\r\nimport { ColorRangeRowInput } from './color_range_row'\r\n\r\ninterface Value {\r\n color: string\r\n width: string\r\n}\r\n\r\ninterface BorderInputProps {\r\n label: string\r\n value: Value\r\n min: number\r\n max: number\r\n onChange: (value: Value) => void\r\n}\r\n\r\nexport function BorderInput({ label = 'Border', value, onChange, min, max }: BorderInputProps) {\r\n return (\r\n onChange({ color, width })}\r\n />\r\n )\r\n}\r\n","import { Checkbox } from '@finviz/website'\r\nimport React from 'react'\r\n\r\ninterface CheckBoxProps {\r\n label: string\r\n value: boolean\r\n onChange: (isChecked: boolean) => void\r\n}\r\n\r\nexport function CheckBox({ label, value, onChange }: CheckBoxProps) {\r\n return (\r\n ) => onChange(ev.currentTarget.checked)}\r\n data-testid=\"chart-modal-checkbox\"\r\n >\r\n {label}\r\n \r\n )\r\n}\r\n","import { Checkbox, Input, Label, Select } from '@finviz/website'\r\nimport React, { useCallback, useState } from 'react'\r\n\r\nconst FONT_VALUES = [\r\n { value: 'Arial', label: 'Arial' },\r\n { value: 'Verdana', label: 'Verdana' },\r\n]\r\n\r\ninterface InputProps {\r\n family: string\r\n size: string\r\n style: string\r\n weight: string\r\n}\r\n\r\ninterface FontInputProps {\r\n value: InputProps\r\n onChange: (values: InputProps) => void\r\n}\r\n\r\nexport function FontInput({ value, onChange }: FontInputProps) {\r\n const [family, setFamily] = useState(value.family)\r\n const [size, setSize] = useState(value.size)\r\n const [style, setStyle] = useState(value.style)\r\n const [weight, setWeight] = useState(value.weight)\r\n\r\n const setValue = useCallback(\r\n (key, valueSetter, value) => {\r\n valueSetter(value)\r\n onChange({ family, size, style, weight, [key]: value })\r\n },\r\n [family, size, style, weight, onChange]\r\n )\r\n\r\n return (\r\n
\r\n
\r\n \r\n ) => setValue('size', setSize, ev.currentTarget.value)}\r\n value={size}\r\n data-testid=\"chart-modal-font-size\"\r\n />\r\n\r\n ) =>\r\n setValue('weight', setWeight, ev.currentTarget.checked ? 'bold' : 'normal')\r\n }\r\n data-testid=\"chart-modal-font-weight\"\r\n >\r\n Bold\r\n \r\n ) =>\r\n setValue('style', setStyle, ev.currentTarget.checked ? 'italic' : 'normal')\r\n }\r\n data-testid=\"chart-modal-font-style\"\r\n >\r\n Italic\r\n \r\n
\r\n
\r\n )\r\n}\r\n","import { convertColorToHEX } from '@finviz/website'\r\nimport * as React from 'react'\r\n\r\nimport { ColorRangeRowInput } from './color_range_row'\r\n\r\ninterface LineInputValue {\r\n color: string\r\n width: string\r\n}\r\n\r\ninterface LineInputProps {\r\n label: string\r\n value: LineInputValue\r\n onChange: (value: LineInputValue) => void\r\n}\r\n\r\nexport function LineInput({ label = 'Line', value, onChange }: LineInputProps) {\r\n return (\r\n onChange({ color, width })}\r\n />\r\n )\r\n}\r\n","import { Textarea } from '@finviz/website'\r\nimport React from 'react'\r\n\r\ninterface MultilineStringInputProps {\r\n label: string\r\n value: string\r\n required: boolean\r\n onChange: (value: string) => void\r\n}\r\n\r\nexport function MultilineStringInput({ label, value, required, onChange }: MultilineStringInputProps) {\r\n return (\r\n ) => onChange(e.target.value)}\r\n value={value}\r\n autoFocus\r\n data-testid=\"chart-modal-multiline-string-textarea\"\r\n />\r\n )\r\n}\r\n","import { Input } from '@finviz/website'\r\nimport React from 'react'\r\n\r\ninterface NumberInputProps {\r\n label: string\r\n name: string\r\n value: number\r\n required: boolean\r\n min?: number\r\n max?: number\r\n allowDecimal?: boolean\r\n step?: number\r\n onChange: (value: number) => void\r\n}\r\n\r\nexport function NumberInput(props: NumberInputProps) {\r\n const { label, name, value, required, min, max, step, allowDecimal = false } = props\r\n\r\n return (\r\n ) =>\r\n props.onChange(allowDecimal ? parseFloat(e.target.value) : parseInt(e.target.value, 10))\r\n }\r\n data-testid=\"chart-modal-number-input\"\r\n />\r\n )\r\n}\r\n","import { Input } from '@finviz/website'\r\nimport React from 'react'\r\n\r\ninterface StringInputProps {\r\n label: string\r\n name: string\r\n value: string\r\n required: boolean\r\n onChange: (value: string) => void\r\n}\r\n\r\nexport function StringInput(props: StringInputProps) {\r\n const { label, name, value, required } = props\r\n\r\n return (\r\n ) => props.onChange(e.target.value)}\r\n data-testid=\"chart-modal-string-textinput\"\r\n />\r\n )\r\n}\r\n","import { Checkbox, Input, InputColorPicker, convertColorToHEX } from '@finviz/website'\r\nimport React from 'react'\r\n\r\ninterface InputProps {\r\n active: boolean\r\n trend: number\r\n color: string\r\n}\r\n\r\ninterface trendInputProps {\r\n value: InputProps\r\n onChange: (values: InputProps) => void\r\n}\r\n\r\nexport function Trend({ value, onChange }: trendInputProps) {\r\n return (\r\n
\r\n ) => onChange({ ...value, active: ev.currentTarget.checked })}\r\n data-testid=\"chart-modal-trend-active\"\r\n />\r\n ) =>\r\n onChange({ ...value, trend: ev.currentTarget.valueAsNumber })\r\n }\r\n value={value.trend}\r\n data-testid=\"chart-modal-trend-value\"\r\n />\r\n onChange({ ...value, color: color })}\r\n inputDataTestId=\"chart-modal-trend-color\"\r\n />\r\n
\r\n )\r\n}\r\n","import { Checkbox, Input, Paragraph } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport { MacroTimeframe } from '../../constants/common'\r\nimport { DEFAULTS } from './index'\r\n\r\nexport interface InputProps {\r\n macroKey: MacroTimeframe\r\n isOff: boolean\r\n from: number\r\n to: number\r\n}\r\n\r\ninterface VisibilityInputProps {\r\n value: InputProps\r\n onChange: (value: InputProps) => void\r\n isCheckboxOnly: boolean\r\n}\r\n\r\nexport function VisibilityInput({ value, onChange, isCheckboxOnly }: VisibilityInputProps) {\r\n const [isOff, setIsOff] = React.useState(value.isOff)\r\n const [from, setFrom] = React.useState(value.from)\r\n const [to, setTo] = React.useState(value.to)\r\n const { macroKey } = value\r\n const macroLabel = macroKey.charAt(0).toUpperCase() + macroKey.slice(1)\r\n\r\n const setValue = React.useCallback(\r\n (key, valueSetter, value) => {\r\n valueSetter(value)\r\n onChange({ macroKey, isOff, from, to, [key]: value })\r\n },\r\n [macroKey, isOff, from, to, onChange]\r\n )\r\n return (\r\n
\r\n
\r\n ) => setValue('isOff', setIsOff, !e.target.checked)}\r\n >\r\n {isCheckboxOnly && macroLabel}\r\n \r\n {!isCheckboxOnly && (\r\n <>\r\n ) =>\r\n setValue('from', setFrom, Number(ev.currentTarget.value))\r\n }\r\n data-testid={`visibility-input-${macroKey}-from`}\r\n />\r\n -\r\n ) =>\r\n setValue('to', setTo, Number(ev.currentTarget.value))\r\n }\r\n data-testid={`visibility-input-${macroKey}-to`}\r\n />\r\n {macroLabel}\r\n \r\n )}\r\n
\r\n
\r\n )\r\n}\r\n","import merge from 'lodash.merge'\r\nimport React from 'react'\r\n\r\nimport { IVisibility, MacroTimeframe, MicroTimeframeRange } from '../../constants/common'\r\nimport { isInRange } from '../../utils/helpers'\r\nimport { InputProps, VisibilityInput } from './visibility-input'\r\n\r\ninterface VisibilityProps {\r\n label: string\r\n name: string\r\n value: IVisibility\r\n onChange: (value: IVisibility) => void\r\n handleDisableSubmit: (value: string | false) => void\r\n}\r\n\r\ntype Micro = { isOff: boolean; from: number; to: number }\r\nexport type DEFAULTS_TYPE = { [key in MacroTimeframe]: Micro }\r\n\r\nexport const DEFAULTS: DEFAULTS_TYPE = {\r\n // [MacroTimeframe.seconds]: { isOff: false, from: 1, to: 59 },\r\n [MacroTimeframe.minutes]: { isOff: false, from: 1, to: 59 },\r\n [MacroTimeframe.hours]: { isOff: false, from: 1, to: 24 },\r\n [MacroTimeframe.days]: { isOff: false, from: 1, to: 366 },\r\n [MacroTimeframe.weeks]: { isOff: false, from: 1, to: 52 },\r\n [MacroTimeframe.months]: { isOff: false, from: 1, to: 12 },\r\n}\r\n\r\nconst INPUTS_AVAILABLE = [MacroTimeframe.minutes, MacroTimeframe.hours]\r\n\r\nconst getInitialState = (value: IVisibility) => {\r\n const visibilities = merge({}, DEFAULTS)\r\n for (const visibility in visibilities) {\r\n const macroTimeframe = visibility as MacroTimeframe\r\n const valueMacroTimeframe = value?.[macroTimeframe]\r\n if (!valueMacroTimeframe) continue\r\n if (Object.keys(valueMacroTimeframe).length === 0) {\r\n visibilities[macroTimeframe] = { ...visibilities[macroTimeframe], isOff: true }\r\n } else {\r\n visibilities[macroTimeframe] = { ...visibilities[macroTimeframe], ...valueMacroTimeframe }\r\n }\r\n }\r\n return visibilities\r\n}\r\n\r\nconst getIsVisibilityOutsideAvailableTimeframes = (value: IVisibility) => {\r\n const result = Object.keys(MacroTimeframe).every((macrotimeframe) => {\r\n const macroRange = value[macrotimeframe as MacroTimeframe]\r\n\r\n return (\r\n macroRange &&\r\n (Object.keys(macroRange).length === 0 ||\r\n !MicroTimeframeRange[macrotimeframe as MacroTimeframe].some((item) =>\r\n isInRange({\r\n value: item,\r\n min: macroRange?.from ?? DEFAULTS[macrotimeframe as MacroTimeframe].from,\r\n max: macroRange?.to ?? DEFAULTS[macrotimeframe as MacroTimeframe].to,\r\n })\r\n ))\r\n )\r\n })\r\n return result\r\n}\r\n\r\nexport function Visibility(props: VisibilityProps) {\r\n const initialVisibilityRef = React.useRef(getInitialState(props.value))\r\n\r\n const handleChange = (value: InputProps) => {\r\n const result: IVisibility = props.value ? merge({}, props.value) : {}\r\n result[value.macroKey] = {}\r\n\r\n if (value.isOff) {\r\n props.onChange(result)\r\n } else if (value.from === DEFAULTS[value.macroKey].from && value.to === DEFAULTS[value.macroKey].to) {\r\n delete result[value.macroKey]\r\n props.onChange(result)\r\n } else {\r\n if (value.from !== DEFAULTS[value.macroKey].from) {\r\n result[value.macroKey]!.from = value.from\r\n }\r\n if (value.to !== DEFAULTS[value.macroKey].to) {\r\n result[value.macroKey]!.to = value.to\r\n }\r\n props.onChange(result)\r\n }\r\n\r\n props.handleDisableSubmit(\r\n getIsVisibilityOutsideAvailableTimeframes(result)\r\n ? 'The chosen timeframes would make the drawing invisible on all supported timeframes.'\r\n : false\r\n )\r\n }\r\n\r\n return Object.keys(initialVisibilityRef.current).map((macroKey) => (\r\n \r\n ))\r\n}\r\n","import {\r\n Button,\r\n ButtonGroup,\r\n Dialog,\r\n DialogBody,\r\n DialogFooter,\r\n DialogHeader,\r\n DialogStateReturn,\r\n useDialogState,\r\n} from '@finviz/website'\r\nimport debounce from 'lodash.debounce'\r\nimport * as React from 'react'\r\n\r\nimport { ObjectHash } from '../../types/shared'\r\nimport CanvasElement from '../canvas/element'\r\nimport { BackgroundInput } from './background'\r\nimport { BorderInput } from './border'\r\nimport { CheckBox } from './checkbox'\r\nimport { FontInput } from './font'\r\nimport { LineInput } from './line'\r\nimport { MultilineStringInput } from './multiline_string'\r\nimport { NumberInput } from './number'\r\nimport { StringInput } from './string'\r\nimport { Trend } from './trend'\r\nimport { Visibility } from './visibility'\r\n\r\nfunction getInputForType(type: string) {\r\n switch (type) {\r\n case 'number':\r\n return NumberInput\r\n case 'string':\r\n return StringInput\r\n case 'text':\r\n return StringInput\r\n case 'background':\r\n return BackgroundInput\r\n case 'border':\r\n return BorderInput\r\n case 'line':\r\n return LineInput\r\n case 'multiline_string':\r\n return MultilineStringInput\r\n case 'font':\r\n return FontInput\r\n case 'checkbox':\r\n return CheckBox\r\n case 'trend':\r\n return Trend\r\n case 'visibility':\r\n return Visibility\r\n default:\r\n return () =>
ERROR: Unknown input type
\r\n }\r\n}\r\n\r\nconst TAB_BUTTON_COMMON_PROPS = { type: 'button' as const, className: 'flex-1', contentClass: 'text-center' }\r\n\r\ntype OnSubmitType = ((value: ObjectHash) => void) | null\r\ntype OnDismissType = (() => void) | null\r\n\r\nexport interface ElementStyleDialogProps {\r\n state: DialogStateReturn\r\n element: ElementType\r\n onSubmit: ((values: ElementType['attrs']) => void) | null\r\n onDismiss: (() => void) | null\r\n onHide: () => void\r\n}\r\n\r\nexport type StyleDialogOpener = (\r\n element: ElementType,\r\n onSubmit: ElementStyleDialogProps['onSubmit'],\r\n onDismiss: ElementStyleDialogProps['onDismiss']\r\n) => void\r\n\r\nfunction getValuesFromFormState(formState: ObjectHash) {\r\n return formState.reduce((acc: ObjectHash, cur: ObjectHash) => {\r\n acc[cur.name] = cur.value\r\n return acc\r\n }, {} as ObjectHash)\r\n}\r\n\r\nenum DialogTabs {\r\n Style,\r\n Visibility,\r\n}\r\n\r\nexport function ElementStyleDialog(props: ElementStyleDialogProps) {\r\n const config = props.element.getModalConfig()\r\n const initialFormStateRef = React.useRef[]>(JSON.parse(JSON.stringify(config.inputs)))\r\n const [formState, setFormState] = React.useState[]>(config.inputs)\r\n const [selectedTab, setSelectedTab] = React.useState(DialogTabs.Style)\r\n const [isSubmitDisabled, setIsSubmitDisabled] = React.useState(false) // If string, the value is used as title for disabled button.\r\n\r\n const isDrawingElement = props.element.getIsDrawing()\r\n\r\n React.useEffect(() => {\r\n props.element.isEditInProgress = true\r\n return () => {\r\n props.element.isEditInProgress = false\r\n props.element.trigger('change', props.element)\r\n }\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [])\r\n\r\n const handleValuesChange = React.useCallback(\r\n ({\r\n values,\r\n shouldSubmit = false,\r\n shouldDismiss = false,\r\n }: {\r\n values: ObjectHash\r\n shouldSubmit?: boolean\r\n shouldDismiss?: boolean\r\n }) => {\r\n const hasOnSubmit = typeof props.onSubmit === 'function'\r\n const hasOnDismiss = typeof props.onDismiss === 'function'\r\n\r\n props.element.set(values)\r\n if (shouldSubmit && hasOnSubmit) {\r\n props.onSubmit!(values)\r\n } else if (shouldDismiss && hasOnDismiss) {\r\n props.onDismiss!()\r\n }\r\n\r\n if (shouldSubmit || shouldDismiss) {\r\n props.state.hide()\r\n }\r\n },\r\n [props]\r\n )\r\n\r\n const handleValuesChangeDebounceRef = React.useRef(\r\n debounce(\r\n (newFormState) => {\r\n const values = getValuesFromFormState(newFormState)\r\n handleValuesChange({ values })\r\n },\r\n 50,\r\n { maxWait: 100 }\r\n )\r\n )\r\n\r\n React.useEffect(\r\n () => () => {\r\n handleValuesChangeDebounceRef.current.cancel()\r\n },\r\n []\r\n )\r\n\r\n const onSubmit: React.FormEventHandler = React.useCallback(\r\n (ev: React.FormEvent) => {\r\n ev.preventDefault()\r\n if (ev.currentTarget.checkValidity()) {\r\n const values = getValuesFromFormState(formState)\r\n handleValuesChange({ values, shouldSubmit: true })\r\n }\r\n },\r\n [formState, handleValuesChange]\r\n )\r\n\r\n const handleCloseDialog = React.useCallback(() => {\r\n const values = getValuesFromFormState(initialFormStateRef.current)\r\n handleValuesChange({ values, shouldDismiss: true })\r\n }, [handleValuesChange])\r\n\r\n const getShouldRenderInputForTab = (inputType: string) => {\r\n if (selectedTab === DialogTabs.Visibility && inputType === 'visibility') return true\r\n if (selectedTab !== DialogTabs.Visibility && inputType !== 'visibility') return true\r\n return false\r\n }\r\n\r\n return (\r\n }\r\n onFullyClosed={props.onHide}\r\n >\r\n {config.title}\r\n
\r\n \r\n {isDrawingElement && (\r\n \r\n setSelectedTab(DialogTabs.Style)}\r\n data-testid=\"dialog-tab-button-style\"\r\n >\r\n Style\r\n \r\n setSelectedTab(DialogTabs.Visibility)}\r\n data-testid=\"dialog-tab-button-visibility\"\r\n >\r\n Visibility\r\n \r\n \r\n )}\r\n\r\n {formState.map((input) => {\r\n const InputComponent = getInputForType(input.type) as React.FC<{\r\n onChange: (value: string) => void\r\n handleDisableSubmit?: typeof setIsSubmitDisabled\r\n }>\r\n return (\r\n getShouldRenderInputForTab(input.type) && (\r\n {\r\n setFormState((prevState) => {\r\n const newFormState = prevState.map((stateInput) => {\r\n if (stateInput.name === input.name) {\r\n return { ...stateInput, value }\r\n }\r\n return stateInput\r\n })\r\n handleValuesChangeDebounceRef.current(newFormState)\r\n return newFormState\r\n })\r\n }}\r\n handleDisableSubmit={setIsSubmitDisabled}\r\n />\r\n )\r\n )\r\n })}\r\n \r\n \r\n \r\n \r\n Save\r\n \r\n \r\n
\r\n \r\n )\r\n}\r\n\r\nexport const ElementStyleDialogContext = React.createContext>(() => {})\r\n\r\nexport function withElementStyleDialogState

(Component: React.ComponentType

) {\r\n return function WrappedComponent(props: P) {\r\n const context = React.useContext(ElementStyleDialogContext)\r\n\r\n return \r\n }\r\n}\r\n\r\nexport function ElementStyleDialogWrapper(props: { children: React.ReactNode }) {\r\n const [element, setElement] = React.useState(null)\r\n const [onSubmit, setOnSubmit] = React.useState(null)\r\n const [onDismiss, setOnDismiss] = React.useState(null)\r\n const dialog = useDialogState()\r\n\r\n const openDialog = (element: CanvasElement, onSubmit?: OnSubmitType, onDismiss?: OnDismissType) => {\r\n if (onSubmit) {\r\n setOnSubmit(() => onSubmit)\r\n }\r\n if (onDismiss) {\r\n setOnDismiss(() => onDismiss)\r\n }\r\n\r\n setElement(element)\r\n dialog.show()\r\n }\r\n\r\n const onHide = () => {\r\n setElement(null)\r\n setOnSubmit(null)\r\n setOnDismiss(null)\r\n }\r\n\r\n return (\r\n \r\n {props.children}\r\n {element && (\r\n \r\n )}\r\n \r\n )\r\n}\r\n","import { IndicatorType } from '../../constants/common'\r\nimport { HLC } from '../../utils/hlc'\r\n\r\nexport type DrawingChangeTimestamp = HLC\r\nexport type DrawingContainerType = IndicatorType | 'chart' | 'note' | null\r\nexport type AutoSaveChangeType = 'update' | 'destroy'\r\n\r\nexport interface AutoSaveElement {\r\n elementId: string\r\n ticker: string\r\n zIndex: number\r\n lastChange: DrawingChangeTimestamp\r\n changeType: AutoSaveChangeType\r\n containerType: DrawingContainerType\r\n elementAttrs: string\r\n}\r\n\r\nexport type AutoSaveElementDBRecord = Omit & { lastChange: string } & {\r\n lastChangeTimestamp: number\r\n lastChangeCounter: number\r\n lastChangeNodeUUID: string\r\n}\r\n\r\nexport const DRAWINGS_UPDATE_INTERVAL_MS = process.env.IS_E2E_TESTING ? 3000 : 15000\r\nexport const DRAWINGS_SAVE_INTERVAL_MS = 250\r\n","import { Notification, Paragraph, useNotification } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport fetchApi, {\r\n ContentType,\r\n ForbiddenError,\r\n GenericStatusCodeError,\r\n GoneError,\r\n InternalServerError,\r\n} from '../../utils/fetch_api'\r\nimport { HLC, compareHlc, incrementHlc } from '../../utils/hlc'\r\nimport { getByteLengthOfString } from '../../utils/string-byte-length'\r\nimport { AutoSaveElement, AutoSaveElementDBRecord, DrawingContainerType } from './constants'\r\nimport { getAutosaveElementFromDBRecord, getDBRecordFromAutosaveElement } from './utils'\r\n\r\nconst RETRY_LIMIT = 5\r\n\r\nexport function useDrawingAutoSaveApi() {\r\n const postRetryCountRef = React.useRef(0)\r\n const deleteRetryCountRef = React.useRef(0)\r\n const notificationContext = useNotification()\r\n\r\n const fetchDrawings = React.useCallback(\r\n async ({\r\n tickers,\r\n containerTypes,\r\n lastChange,\r\n }: {\r\n tickers: string[]\r\n containerTypes: DrawingContainerType[]\r\n lastChange: HLC\r\n }) => {\r\n try {\r\n const data = await fetchApi<{\r\n drawings: AutoSaveElementDBRecord[]\r\n }>({\r\n location: '/api/auto_save.ashx',\r\n queryParameters: {\r\n ticker: tickers.join(','),\r\n containerTypes: containerTypes.join(',') || undefined,\r\n lastChangeTimestamp: lastChange.ts,\r\n lastChangeCounter: lastChange.count,\r\n lastChangeNodeUUID: lastChange.uuid,\r\n },\r\n throwOnStatusCodes: [403, 404],\r\n })\r\n return data.drawings.map((drawing) => getAutosaveElementFromDBRecord(drawing))\r\n } catch {\r\n // ignore error\r\n }\r\n\r\n return []\r\n },\r\n []\r\n )\r\n\r\n const saveDrawings = React.useCallback(\r\n async (drawings: AutoSaveElement[]): Promise => {\r\n if (drawings.length === 0) {\r\n return undefined\r\n }\r\n\r\n try {\r\n const bodyJsonString = JSON.stringify(drawings.map((item) => getDBRecordFromAutosaveElement(item)))\r\n let keepalive = false\r\n try {\r\n keepalive = getByteLengthOfString(bodyJsonString) < 64000\r\n } catch (error: any) {\r\n window.Sentry?.captureException(error)\r\n }\r\n await fetchApi({\r\n location: '/api/auto_save.ashx',\r\n method: 'POST',\r\n throwOnStatusCodes: [400, 403, 404, 410, 500],\r\n contentType: ContentType.ApplicationJson,\r\n body: bodyJsonString,\r\n keepalive,\r\n })\r\n const [latestChangeHlc] = [...drawings].sort((a, b) => compareHlc(b.lastChange, a.lastChange))\r\n postRetryCountRef.current = 0\r\n return latestChangeHlc.lastChange\r\n } catch (error) {\r\n if (error instanceof InternalServerError) {\r\n // try again\r\n if (postRetryCountRef.current < RETRY_LIMIT) {\r\n postRetryCountRef.current = postRetryCountRef.current + 1\r\n await new Promise((r) => setTimeout(r, 1000))\r\n return saveDrawings(drawings)\r\n } else {\r\n // continue to report to Sentry\r\n postRetryCountRef.current = 0\r\n }\r\n } else if (error instanceof ForbiddenError) {\r\n // ignore error\r\n return undefined\r\n } else if (error instanceof GoneError) {\r\n const newTicker = (error.response as ObjectHash).newTicker\r\n const message = newTicker\r\n ? `Ticker \"${drawings[0].ticker}\" was renamed to \"${newTicker}\"`\r\n : `Ticker \"${drawings[0].ticker}\" no longer exists.`\r\n notificationContext.show(\r\n } timeoutInMs={6000}>\r\n {message}\r\n \r\n )\r\n return undefined\r\n }\r\n\r\n // report error to Sentry\r\n window.Sentry?.captureException(error, {\r\n extra: (error instanceof GenericStatusCodeError\r\n ? (error.response as ObjectHash).invalidItems\r\n : drawings\r\n ).reduce(\r\n (acc: ObjectHash, cur: ObjectHash, index: number) => ({ ...acc, [`item-${index}`]: JSON.stringify(cur) }),\r\n {} as ObjectHash\r\n ),\r\n })\r\n\r\n return undefined\r\n }\r\n },\r\n [notificationContext]\r\n )\r\n\r\n const deleteAllDrawings = React.useCallback(\r\n async ({ tickers, lastLocalChange }: { tickers: string[]; lastLocalChange: HLC }): Promise => {\r\n try {\r\n const newHlc = incrementHlc(lastLocalChange, Date.now())\r\n await fetchApi({\r\n location: `/api/auto_save.ashx?ticker=${tickers.join(',')}&lastChangeTimestamp=${\r\n newHlc.ts\r\n }&lastChangeCounter=${newHlc.count}&lastChangeNodeUUID=${newHlc.uuid}`,\r\n method: 'DELETE',\r\n throwOnStatusCodes: [403, 404, 500],\r\n keepalive: true,\r\n })\r\n deleteRetryCountRef.current = 0\r\n } catch (error) {\r\n if (error instanceof InternalServerError) {\r\n // try again\r\n if (deleteRetryCountRef.current < RETRY_LIMIT) {\r\n deleteRetryCountRef.current = deleteRetryCountRef.current + 1\r\n await new Promise((r) => setTimeout(r, 1000))\r\n return deleteAllDrawings({ tickers, lastLocalChange })\r\n } else {\r\n // continue to report to Sentry\r\n deleteRetryCountRef.current = 0\r\n }\r\n } else if (error instanceof ForbiddenError) {\r\n // ignore error\r\n return\r\n }\r\n\r\n // report error to Sentry\r\n window.Sentry?.captureException(error)\r\n }\r\n },\r\n []\r\n )\r\n\r\n return { fetchDrawings, saveDrawings, deleteAllDrawings }\r\n}\r\n","// byteLengthCharCode2 from https://stackoverflow.com/a/63893237\r\n\r\nexport function getByteLengthOfString(s: string) {\r\n //assuming the String is UCS-2(aka UTF-16) encoded\r\n let n = 0\r\n for (let i = 0, l = s.length; i < l; i++) {\r\n const hi = s.charCodeAt(i)\r\n if (hi < 0x0080) {\r\n n += 1\r\n } else if (hi < 0x0800) {\r\n n += 2\r\n } else if (hi < 0xd800) {\r\n n += 3\r\n } else if (hi < 0xdc00) {\r\n const lo = s.charCodeAt(++i)\r\n if (i < l && lo >= 0xdc00 && lo <= 0xdfff) {\r\n n += 4\r\n } else {\r\n throw new Error('UCS-2 String malformed')\r\n }\r\n } else if (hi < 0xe000) {\r\n throw new Error('UCS-2 String malformed')\r\n } else {\r\n n += 3\r\n }\r\n }\r\n return n\r\n}\r\n","import React from 'react'\r\n\r\nimport { DrawingSpineOptions, DrawingSpineOptionsEvent } from '../../../types/shared'\r\nimport ElementCanvas from '../../canvas/element'\r\nimport { SpecificChartFunctionality } from '../../constants/common'\r\nimport { getCanvasElementByType } from '../../helpers/get-canvas-element-by-type'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { AutoSaveState } from '../../models/constants'\r\nimport Element from '../../models/element'\r\nimport { compareHlc, incrementHlc, initHlc, receiveHlc } from '../../utils/hlc'\r\nimport { AutoSaveChangeType, AutoSaveElement, DRAWINGS_SAVE_INTERVAL_MS } from './constants'\r\nimport { useDrawingAutoSaveApi } from './use-drawing-autosave-api'\r\nimport { useIsAutoSaveActive } from './use-is-auto-save-active'\r\nimport {\r\n getContainerType,\r\n getNoteElementId,\r\n getTickerNoteText,\r\n getTickersAndContainerTypesInLayoutModel,\r\n mergeUpdatedDrawingsToInternalStore,\r\n updateInternalStoreWithChangedElement,\r\n} from './utils'\r\n\r\nexport function useDrawingAutoSaveControls(chartLayout: ChartLayout) {\r\n const { fetchDrawings, saveDrawings, deleteAllDrawings } = useDrawingAutoSaveApi()\r\n const isAutoSaveActive = useIsAutoSaveActive(chartLayout)\r\n const drawingsInternalStore = React.useMemo(() => chartLayout.drawingsInternalStore(), [chartLayout])\r\n const saveTimeoutRef = React.useRef()\r\n\r\n React.useEffect(\r\n () => () => {\r\n if (saveTimeoutRef.current) {\r\n clearTimeout(saveTimeoutRef.current)\r\n }\r\n },\r\n []\r\n )\r\n\r\n const saveLatestChanges = React.useCallback(\r\n (\r\n withDelayInMs = DRAWINGS_SAVE_INTERVAL_MS,\r\n saveQueueExtraFilterCallback: ((item: AutoSaveElement) => boolean) | null = null\r\n ) => {\r\n if (saveTimeoutRef.current) {\r\n clearTimeout(saveTimeoutRef.current)\r\n }\r\n const saveQueue = drawingsInternalStore.elements.filter(\r\n (item) =>\r\n compareHlc(item.lastChange, drawingsInternalStore.latestLocalUpdateTimestamp) > 0 &&\r\n item.lastChange.uuid === drawingsInternalStore.instanceUUID &&\r\n (saveQueueExtraFilterCallback === null || saveQueueExtraFilterCallback(item))\r\n )\r\n if (saveQueue.length === 0) {\r\n return\r\n }\r\n\r\n drawingsInternalStore.setAutoSaveState(AutoSaveState.Unsaved)\r\n\r\n const save = async () => {\r\n drawingsInternalStore.setAutoSaveState(AutoSaveState.Saving)\r\n const result = await saveDrawings(saveQueue)\r\n if (result) {\r\n drawingsInternalStore.updateAttributes({\r\n latestLocalUpdateTimestamp: receiveHlc(drawingsInternalStore.latestLocalUpdateTimestamp, result),\r\n })\r\n }\r\n drawingsInternalStore.setAutoSaveState(AutoSaveState.Saved)\r\n\r\n return result\r\n }\r\n\r\n if (withDelayInMs === 0) {\r\n return save()\r\n }\r\n\r\n saveTimeoutRef.current = window.setTimeout(save, withDelayInMs)\r\n },\r\n [saveDrawings, drawingsInternalStore]\r\n )\r\n\r\n const syncChartLayoutDrawings = React.useCallback(\r\n (drawing: AutoSaveElement) => {\r\n if (drawing.containerType === 'note') {\r\n return\r\n }\r\n const isRemove = drawing.changeType === 'destroy'\r\n\r\n chartLayout.getAllPanes().forEach((paneModel) => {\r\n const ticker = paneModel.getQuoteRawTicker()\r\n const paneContainerType = getContainerType(paneModel)\r\n if (!paneContainerType || drawing.ticker !== ticker) {\r\n return\r\n }\r\n const paneInternalStoreElements = drawingsInternalStore.elements.filter(\r\n (autoSaveElement) => autoSaveElement.ticker === ticker && autoSaveElement.containerType === paneContainerType\r\n )\r\n const paneElements = paneModel.getAllElements()\r\n let element: Element | undefined\r\n paneElements.forEach((paneElement) => {\r\n if (paneElement.isDrawing() && !paneElement.instance.isCreator) {\r\n const paneDrawing = paneInternalStoreElements.find(({ elementId }) => elementId === paneElement.elementId)\r\n if (!paneDrawing || paneDrawing.changeType === 'destroy') {\r\n paneElement.destroyCascade()\r\n } else if (paneElement.elementId && paneElement.elementId === drawing.elementId) {\r\n element = paneElement\r\n }\r\n }\r\n })\r\n\r\n const parsedElementAttrs = JSON.parse(drawing.elementAttrs)\r\n if (element) {\r\n if (drawing.elementAttrs !== JSON.stringify(element.instance.toAutosaveConfig())) {\r\n if (element.pane().selection !== element.instance && !element.hasOngoingInteraction()) {\r\n element.instance.set(parsedElementAttrs)\r\n element.instance.updateScales()\r\n }\r\n }\r\n if (drawing.zIndex !== element.zIndex) {\r\n element.updateAttributes({ zIndex: drawing.zIndex })\r\n }\r\n if (isRemove || paneContainerType !== drawing.containerType) {\r\n element.destroyCascade()\r\n }\r\n } else if (!isRemove && paneContainerType === drawing.containerType) {\r\n const instance = getCanvasElementByType(parsedElementAttrs.type).fromObject(\r\n parsedElementAttrs,\r\n paneModel\r\n ) as ElementCanvas\r\n paneModel.elements().create({ elementId: drawing.elementId, instance, zIndex: drawing.zIndex })\r\n instance.updateScales()\r\n }\r\n })\r\n },\r\n [chartLayout, drawingsInternalStore]\r\n )\r\n\r\n const handleAutoSaveNoteChange = React.useCallback(\r\n (note: string, ticker?: string) => {\r\n if (ticker) {\r\n const newNoteElement: AutoSaveElement = {\r\n elementId: getNoteElementId(ticker),\r\n zIndex: 0,\r\n ticker: ticker,\r\n lastChange: incrementHlc(drawingsInternalStore.latestLocalUpdateTimestamp, Date.now()),\r\n changeType: 'update',\r\n containerType: 'note',\r\n elementAttrs: JSON.stringify({ text: note }),\r\n }\r\n\r\n drawingsInternalStore.updateAttributes({\r\n elements: [\r\n ...drawingsInternalStore.elements.filter(({ elementId }) => elementId !== newNoteElement.elementId),\r\n newNoteElement,\r\n ],\r\n })\r\n }\r\n },\r\n [drawingsInternalStore]\r\n )\r\n\r\n const handleIdeaNoteChange = React.useCallback(\r\n (note: string) => {\r\n if (chartLayout.idea?.note !== note && (chartLayout.idea || note)) {\r\n chartLayout.updateAttribute('idea', { ...chartLayout.idea, note })\r\n handleAutoSaveNoteChange(note, chartLayout.activeChart?.getQuoteRawTicker() ?? undefined)\r\n }\r\n },\r\n [chartLayout, handleAutoSaveNoteChange]\r\n )\r\n\r\n const checkDrawingUpdate = React.useCallback(\r\n async (isRefetchAll = false) => {\r\n const { tickers, containerTypes } = getTickersAndContainerTypesInLayoutModel(chartLayout)\r\n if (isRefetchAll) {\r\n drawingsInternalStore.updateAttributes({\r\n latestRemoteUpdateTimestamp: initHlc(drawingsInternalStore.instanceUUID, 0),\r\n })\r\n }\r\n\r\n const updatedDrawings = await fetchDrawings({\r\n tickers,\r\n containerTypes,\r\n lastChange: drawingsInternalStore.latestRemoteUpdateTimestamp,\r\n })\r\n const { newLastUpdateTimestamp, updatedElementIds, newInternalStore } = mergeUpdatedDrawingsToInternalStore({\r\n updatedDrawings,\r\n currentInternalStore: drawingsInternalStore.elements,\r\n lastUpdateTimestamp: drawingsInternalStore.latestRemoteUpdateTimestamp,\r\n isRefetchAll,\r\n })\r\n\r\n drawingsInternalStore.updateAttributes({\r\n // Even if there are no changes in elements, newInternalStore is new array with the same content which may cause unnecessary rerenders\r\n ...(updatedElementIds.length > 0 ? { elements: newInternalStore } : {}),\r\n latestRemoteUpdateTimestamp: newLastUpdateTimestamp,\r\n latestLocalUpdateTimestamp:\r\n isRefetchAll && newInternalStore.length > 0\r\n ? receiveHlc(drawingsInternalStore.latestLocalUpdateTimestamp, newLastUpdateTimestamp)\r\n : drawingsInternalStore.latestLocalUpdateTimestamp,\r\n })\r\n\r\n if (updatedElementIds.length > 0 || isRefetchAll) {\r\n saveLatestChanges(0)\r\n const allElements = chartLayout.getAllElements()\r\n updatedElementIds.forEach((elementId) => {\r\n const element = allElements.find((element) => element.elementId === elementId)\r\n\r\n if (element && element.isDrawing() && !element.hasOngoingInteraction()) {\r\n element.destroyCascade()\r\n }\r\n })\r\n\r\n drawingsInternalStore.elements.forEach(syncChartLayoutDrawings)\r\n chartLayout.getAllPanes().forEach((paneModel) => {\r\n paneModel.normalizeZIndexes()\r\n })\r\n\r\n if (chartLayout.specificChartFunctionality === SpecificChartFunctionality.quotePage) {\r\n const activeTicker = chartLayout.activeChart?.getQuoteRawTicker() ?? ''\r\n handleIdeaNoteChange(getTickerNoteText({ ticker: activeTicker, elements: newInternalStore }))\r\n }\r\n }\r\n },\r\n [\r\n chartLayout,\r\n drawingsInternalStore,\r\n syncChartLayoutDrawings,\r\n fetchDrawings,\r\n handleIdeaNoteChange,\r\n saveLatestChanges,\r\n ]\r\n )\r\n\r\n const updateInternalStoreWithElement = React.useCallback(\r\n (element: Element, changeType: AutoSaveChangeType) => {\r\n const updateResult = updateInternalStoreWithChangedElement({\r\n element,\r\n changeType,\r\n currentInternalStore: drawingsInternalStore.elements,\r\n lastUpdateTimestamp: incrementHlc(\r\n receiveHlc(\r\n drawingsInternalStore.latestLocalUpdateTimestamp,\r\n drawingsInternalStore.latestRemoteUpdateTimestamp\r\n ),\r\n Date.now()\r\n ),\r\n })\r\n\r\n if (updateResult) {\r\n const { shouldSyncAndSave, newInternalStore, newDrawing } = updateResult\r\n if (shouldSyncAndSave) {\r\n drawingsInternalStore.updateAttributes({ elements: newInternalStore })\r\n syncChartLayoutDrawings(newDrawing)\r\n }\r\n }\r\n },\r\n [syncChartLayoutDrawings, drawingsInternalStore]\r\n )\r\n\r\n const deleteAllAutoSavedElements = React.useCallback(async () => {\r\n const { tickers } = getTickersAndContainerTypesInLayoutModel(chartLayout)\r\n\r\n await deleteAllDrawings({ tickers, lastLocalChange: drawingsInternalStore.latestLocalUpdateTimestamp })\r\n await checkDrawingUpdate()\r\n }, [chartLayout, deleteAllDrawings, drawingsInternalStore, checkDrawingUpdate])\r\n\r\n const onElementChange = React.useCallback(\r\n (element: Element, _?: any, options?: DrawingSpineOptions) => {\r\n const elementPane = element.pane()\r\n // This may happen if pane had been removed already, in most cases \"element.destroyed\" should be true,\r\n // but we would need to check if it was destroyed by delete drawing action or not, and checking if pane exists covers all cases\r\n if (!element.isDrawing() || element.instance.isCreator || !elementPane) {\r\n return\r\n }\r\n const elementContainerType = getContainerType(elementPane)\r\n const elementPaneTicker = elementPane.getQuoteRawTicker()\r\n const isElementInCurrentChartLayout = chartLayout\r\n .getAllPanes()\r\n .some(\r\n (model) => getContainerType(model) === elementContainerType && model.getQuoteRawTicker() === elementPaneTicker\r\n )\r\n if (isElementInCurrentChartLayout) {\r\n const isRemove = options?.eventType === DrawingSpineOptionsEvent.Remove\r\n updateInternalStoreWithElement(element, isRemove ? 'destroy' : 'update')\r\n }\r\n },\r\n [updateInternalStoreWithElement, chartLayout]\r\n )\r\n\r\n return {\r\n drawingsInternalStore,\r\n onElementChange,\r\n handleIdeaNoteChange,\r\n deleteAllAutoSavedElements,\r\n isAutoSaveActive,\r\n handleAutoSaveNoteChange,\r\n syncChartLayoutDrawings,\r\n saveLatestChanges,\r\n checkDrawingUpdate,\r\n }\r\n}\r\n","import React from 'react'\r\n\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { getIsPreserveDrawingsAndAutosaveAvailable } from '../../utils/chart'\r\n\r\nexport function useIsAutoSaveActive(chartLayout: ChartLayout) {\r\n const chartLayoutModel = useModelState(chartLayout, {\r\n watchProperties: ['isInit', 'isPreserveDrawingsActive', 'idea'],\r\n })\r\n const { idea, isInit, isPreserveDrawingsActive } = chartLayoutModel\r\n return React.useMemo(\r\n () =>\r\n getIsPreserveDrawingsAndAutosaveAvailable(chartLayoutModel) && isPreserveDrawingsActive && !!isInit && !idea?.id,\r\n [isPreserveDrawingsActive, isInit, idea?.id, chartLayoutModel]\r\n )\r\n}\r\n","import React from 'react'\r\n\r\nimport { CustomSpineEvents } from '../../../types/shared'\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport ChartModel from '../../models/chart'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { AutoSaveState } from '../../models/constants'\r\nimport Element from '../../models/element'\r\nimport { usePrevious } from '../../utils/use-prev-state'\r\nimport { DRAWINGS_UPDATE_INTERVAL_MS } from './constants'\r\nimport { useDrawingAutoSaveControls } from './use-drawing-auto-save-controls'\r\nimport { getTickersAndContainerTypesInLayoutModel } from './utils'\r\n\r\nfunction useDrawingAutoSave(chartLayout: ChartLayout) {\r\n const {\r\n onElementChange,\r\n deleteAllAutoSavedElements,\r\n checkDrawingUpdate,\r\n syncChartLayoutDrawings,\r\n saveLatestChanges,\r\n isAutoSaveActive,\r\n } = useDrawingAutoSaveControls(chartLayout)\r\n\r\n const drawingsInternalStoreUnwatched = React.useMemo(() => chartLayout.drawingsInternalStore(), [chartLayout])\r\n const drawingsInternalStore = useModelState(drawingsInternalStoreUnwatched, { watchProperties: ['elements'] })\r\n const prevIsAutoSaveActive = usePrevious(isAutoSaveActive)\r\n\r\n const runInitialSaveAndRefetchUpdate = React.useCallback(async () => {\r\n chartLayout.getAllElements().forEach((element) => {\r\n // Adds drawings to internal store if isAutoSaveActive and they are not in the store yet\r\n if (!drawingsInternalStore.elements.some((drawing) => drawing.elementId === element.elementId)) {\r\n onElementChange(element)\r\n }\r\n })\r\n\r\n // We want to save everything except notes because saving notes can overwrite those already saved in db. Each drawing has different id but there is only one note per ticker\r\n // Notes are merged in checkDrawingUpdate fn\r\n await saveLatestChanges(0, (item) => item.containerType !== 'note')\r\n\r\n checkDrawingUpdate(true)\r\n }, [checkDrawingUpdate, chartLayout, onElementChange, drawingsInternalStore.elements, saveLatestChanges])\r\n\r\n React.useEffect(() => {\r\n if (isAutoSaveActive) {\r\n saveLatestChanges()\r\n }\r\n }, [saveLatestChanges, drawingsInternalStore.elements, isAutoSaveActive])\r\n\r\n React.useEffect(() => {\r\n if (!isAutoSaveActive) {\r\n chartLayout.drawingsInternalStore().setAutoSaveState(AutoSaveState.Off)\r\n return\r\n }\r\n chartLayout.drawingsInternalStore().setAutoSaveState(AutoSaveState.Saved)\r\n if (!prevIsAutoSaveActive && isAutoSaveActive) {\r\n runInitialSaveAndRefetchUpdate()\r\n }\r\n\r\n let { tickers, containerTypes } = getTickersAndContainerTypesInLayoutModel(chartLayout)\r\n\r\n const onChartOrIndicatorChange = () => {\r\n const { tickers: newTickers, containerTypes: newContainerTypes } =\r\n getTickersAndContainerTypesInLayoutModel(chartLayout)\r\n if (\r\n JSON.stringify(tickers) !== JSON.stringify(newTickers) ||\r\n JSON.stringify(containerTypes) !== JSON.stringify(newContainerTypes)\r\n ) {\r\n tickers = newTickers\r\n containerTypes = newContainerTypes\r\n checkDrawingUpdate(true)\r\n }\r\n }\r\n\r\n ChartModel.bind(`${CustomSpineEvents.IndicatorsChange} change`, onChartOrIndicatorChange)\r\n Element.bind('change', onElementChange)\r\n\r\n drawingsInternalStore.elements.forEach(syncChartLayoutDrawings)\r\n const checkDrawingUpdateInterval = setInterval(checkDrawingUpdate, DRAWINGS_UPDATE_INTERVAL_MS)\r\n\r\n const unregisterListeners = () => {\r\n clearInterval(checkDrawingUpdateInterval)\r\n ChartModel.unbind(`${CustomSpineEvents.IndicatorsChange} change`, onChartOrIndicatorChange)\r\n Element.unbind('change', onElementChange)\r\n }\r\n\r\n ChartLayout.bind('change', (model: ChartLayout) => {\r\n if (model.willDestroy) {\r\n unregisterListeners()\r\n }\r\n })\r\n\r\n return unregisterListeners\r\n }, [\r\n chartLayout,\r\n drawingsInternalStore,\r\n checkDrawingUpdate,\r\n onElementChange,\r\n syncChartLayoutDrawings,\r\n isAutoSaveActive,\r\n prevIsAutoSaveActive,\r\n runInitialSaveAndRefetchUpdate,\r\n ])\r\n\r\n return { deleteAllAutoSavedElements, isAutoSaveActive }\r\n}\r\n\r\ninterface Props {\r\n chartLayoutModel: ChartLayout\r\n}\r\n\r\nexport const withDrawingsAutoSave = (Component: any) => (props: Props) => {\r\n const { deleteAllAutoSavedElements, isAutoSaveActive } = useDrawingAutoSave(props.chartLayoutModel)\r\n\r\n return (\r\n \r\n )\r\n}\r\n","import React from 'react'\r\n\r\nexport function usePrevious(value: any) {\r\n const ref = React.useRef()\r\n React.useEffect(() => {\r\n ref.current = value\r\n }, [value])\r\n return ref.current\r\n}\r\n","import { ButtonComponentProps, Icon, Select, SelectListProps } from '@finviz/website'\r\nimport * as React from 'react'\r\n\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { useChartTypes } from './use-chart-types'\r\n\r\ninterface Props extends Pick {\r\n isPremium: boolean\r\n model: ChartLayout\r\n rounding: SelectListProps['rounding']\r\n}\r\n\r\nexport function ChartTypesSelect({ isPremium, model, ...props }: Props) {\r\n const { chartTypes, getCurrentType } = useChartTypes({ isPremium, model })\r\n const currentType = getCurrentType()\r\n const [selectedType, setSelectedType] = React.useState(currentType)\r\n const icon = chartTypes.find((item) => item.value === selectedType)?.icon\r\n\r\n React.useEffect(() => {\r\n setSelectedType(currentType)\r\n }, [currentType])\r\n\r\n return (\r\n item.value === selectedType)?.icon} className=\"text-gray-300\" />\r\n )\r\n }\r\n nativeSelect=\"mobile\"\r\n onChange={(item) => setSelectedType(item.value)}\r\n />\r\n )\r\n}\r\n","import * as React from 'react'\r\nimport { useLocation } from 'react-router-dom'\r\n\r\nimport { SpecificChartFunctionality } from '../../constants/common'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { decodeQueryString, encodeQueryString } from '../../utils/query_string'\r\nimport {\r\n DEFAULT_TYPES,\r\n FREE_TYPES_QUOTE,\r\n FREE_TYPES_QUOTE_VALUES,\r\n QuoteLongToShortType,\r\n QuoteNodeChartTypes,\r\n QuoteShortToLongType,\r\n QuoteUrlChartTypes,\r\n TypeBaseOption,\r\n} from './utils'\r\n\r\nexport function useChartTypes({ isPremium, model }: { isPremium: boolean; model: ChartLayout }) {\r\n const location = useLocation()\r\n const { b, t, ta, ty, p = 'd', r } = decodeQueryString(location.search)\r\n const taInt = ta ? Number.parseInt(ta) : 1\r\n const isQuotePage = model.specificChartFunctionality === SpecificChartFunctionality.quotePage\r\n\r\n const getCurrentType = React.useCallback(() => {\r\n const defaultType =\r\n ((ty as QuoteUrlChartTypes | undefined) && QuoteShortToLongType[ty as QuoteUrlChartTypes]) ??\r\n (window.FinvizQuoteTypeCurrent as QuoteNodeChartTypes)\r\n\r\n return !isPremium && defaultType === QuoteNodeChartTypes.candlestick && taInt === 0\r\n ? QuoteNodeChartTypes.candlesticksimple\r\n : defaultType\r\n }, [isPremium, taInt, ty])\r\n\r\n const generateRouterPath = React.useCallback(\r\n (type: QuoteNodeChartTypes) => {\r\n if (isPremium || FREE_TYPES_QUOTE_VALUES.includes(type)) {\r\n return `${location.pathname}?${encodeQueryString({\r\n b,\r\n t,\r\n r,\r\n ty:\r\n type === QuoteNodeChartTypes.candlesticksimple\r\n ? QuoteLongToShortType.candlestick\r\n : QuoteLongToShortType[type],\r\n ta: type === QuoteNodeChartTypes.candlestick ? '1' : '0',\r\n p,\r\n })}`\r\n }\r\n return `/elite.ashx?${encodeQueryString({\r\n utm_source: 'finviz',\r\n utm_medium: 'banner',\r\n utm_campaign: 'quote-chart-type-select',\r\n })}`\r\n },\r\n [isPremium, location.pathname, b, t, r, p]\r\n )\r\n\r\n const chartTypes = React.useMemo(() => {\r\n const options = isPremium || !isQuotePage ? DEFAULT_TYPES : FREE_TYPES_QUOTE\r\n\r\n return options.map((item) => ({\r\n ...item,\r\n href: generateRouterPath(item.value as QuoteNodeChartTypes),\r\n reloadDocument: !isPremium,\r\n })) as TypeBaseOption[]\r\n }, [generateRouterPath, isPremium, isQuotePage])\r\n\r\n return { getCurrentType, chartTypes }\r\n}\r\n","import { Paragraph, withSuspense } from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport * as React from 'react'\r\n\r\nimport math from '../../helpers/math'\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport { QuoteFetchType } from '../../models/quote/constants'\r\nimport { getTickerChange } from '../../utils/chart'\r\nimport { useChartLayoutGlobalModelAsync } from '../../utils/useChartLayoutGlobalModelAsync'\r\n\r\ninterface Props {\r\n chartIndex: number\r\n}\r\n\r\ninterface ChangeLabelProps {\r\n children: React.ReactNode\r\n changePoints: number\r\n isTiny: boolean\r\n}\r\n\r\nconst CHANGE_UPATE_EVENTS = ['change', 'update']\r\nconst QUOTE_MODEL_CHANGE_EVENTS = [...CHANGE_UPATE_EVENTS, ...Object.values(QuoteFetchType)]\r\n\r\nfunction ChangeLabel({ children, changePoints, isTiny }: ChangeLabelProps) {\r\n return (\r\n 0,\r\n 'text-red-400': changePoints < 0,\r\n })}\r\n >\r\n {children}\r\n \r\n )\r\n}\r\n\r\nexport function DailyChangeDisplayComponent({ chartIndex }: Props) {\r\n const { chartLayoutModel } = useChartLayoutGlobalModelAsync()\r\n const chartModel = useModelState(chartLayoutModel?.getAllCharts()[chartIndex] ?? null, {\r\n watchProperties: ['quote'],\r\n listenOnEvents: CHANGE_UPATE_EVENTS,\r\n })\r\n const quoteModel = useModelState(chartModel?.quote() ?? null, {\r\n watchProperties: ['lastClose', 'prevClose', 'afterClose'],\r\n listenOnEvents: QUOTE_MODEL_CHANGE_EVENTS,\r\n })\r\n\r\n const tickerChange = quoteModel && getTickerChange({ data: quoteModel })\r\n const isTiny =\r\n !!tickerChange?.tickerChange &&\r\n math.getInstrumentDecimalPlaces({\r\n instrument: quoteModel!.instrument,\r\n value: quoteModel!.lastClose,\r\n }) >= 6\r\n\r\n return (\r\n

\r\n {tickerChange?.tickerChange && (\r\n <>\r\n {tickerChange.tickerAfterChange && (\r\n \r\n {tickerChange.tickerAfterChange.string}\r\n \r\n )}\r\n \r\n {tickerChange.tickerChange.string}\r\n \r\n \r\n )}\r\n
\r\n )\r\n}\r\n\r\nexport const DailyChangeDisplay = React.memo(\r\n withSuspense(DailyChangeDisplayComponent),\r\n (prevProps, nextProps) => prevProps.chartIndex === nextProps.chartIndex\r\n)\r\n","import { Button, ButtonComponentProps, setCookieRequest } from '@finviz/website'\r\nimport * as React from 'react'\r\n\r\nimport { SpecificChartFunctionality } from '../../constants/common'\r\nimport utils from '../../utils'\r\nimport { DRAWING_COOKIE_NAME, getIsDrawingEnabled } from '../../utils/chart'\r\nimport { decodeQueryString, encodeQueryString } from '../../utils/query_string'\r\n\r\nconst utmCampaign: Partial> = {\r\n [SpecificChartFunctionality.quotePage]: 'quote-draw-button',\r\n [SpecificChartFunctionality.futuresPage]: 'futures-interactive-chart',\r\n [SpecificChartFunctionality.forexPage]: 'forex-interactive-chart',\r\n [SpecificChartFunctionality.cryptoPage]: 'crypto-interactive-chart',\r\n}\r\n\r\nconst testId: Partial> = {\r\n [SpecificChartFunctionality.quotePage]: 'quote-toggle-draw-btn',\r\n [SpecificChartFunctionality.futuresPage]: 'futures-interactive',\r\n [SpecificChartFunctionality.forexPage]: 'forex-interactive',\r\n [SpecificChartFunctionality.cryptoPage]: 'crypto-interactive',\r\n}\r\n\r\ninterface DrawButtonProps extends Pick {\r\n isPremium: boolean\r\n specificChartFunctionality: SpecificChartFunctionality\r\n active?: boolean\r\n}\r\n\r\nexport function DrawButton({\r\n isPremium,\r\n specificChartFunctionality,\r\n ...props\r\n}: React.PropsWithChildren) {\r\n const buttonProps = React.useMemo(() => {\r\n if (!isPremium) {\r\n return {\r\n as: 'a' as const,\r\n href: `/elite.ashx?${encodeQueryString({\r\n utm_source: 'finviz',\r\n utm_medium: 'banner',\r\n utm_campaign: utmCampaign[specificChartFunctionality],\r\n })}`,\r\n }\r\n }\r\n\r\n return {\r\n onClick: (ev: React.MouseEvent) => {\r\n ev.preventDefault()\r\n const newValue = getIsDrawingEnabled() ? 'off' : 'on'\r\n\r\n setCookieRequest(DRAWING_COOKIE_NAME, newValue)\r\n .catch(() => {\r\n // fallback to JS otherwise draw toggle won't work if API don't work\r\n const expires = new Date()\r\n expires.setMonth(expires.getMonth() + 1)\r\n utils.setCookie(DRAWING_COOKIE_NAME, newValue, expires)\r\n })\r\n .finally(() => {\r\n const { i: idea, ...rest } = decodeQueryString()\r\n if (idea) {\r\n document.location = `quote.ashx?${encodeQueryString(rest)}`\r\n } else {\r\n document.location.reload()\r\n }\r\n })\r\n },\r\n }\r\n }, [isPremium, specificChartFunctionality])\r\n\r\n return (\r\n \r\n )\r\n}\r\n","import { Button, ButtonComponentProps } from '@finviz/website'\r\nimport * as React from 'react'\r\nimport { useLocation } from 'react-router-dom'\r\n\r\nimport { SpecificChartFunctionality } from '../../constants/common'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { decodeQueryString, encodeQueryString } from '../../utils/query_string'\r\n\r\nfunction getTickersString(tickers: string[], tickersCount: number) {\r\n return Array.from({ length: Math.min(tickersCount, 6) })\r\n .map((_, index) => tickers[index] ?? tickers[tickers.length - 1])\r\n .join(',')\r\n}\r\n\r\nfunction getLayoutType(tickersCount: number) {\r\n switch (tickersCount) {\r\n case 0: // shouldn't happen\r\n case 1:\r\n return '1h1v'\r\n case 2:\r\n return '2h1v'\r\n case 3:\r\n return '3h1v'\r\n case 4:\r\n return '2h2v'\r\n case 5:\r\n default:\r\n // 6 and more\r\n return '3h2v'\r\n }\r\n}\r\n\r\nconst utmCampaign: Partial> = {\r\n [SpecificChartFunctionality.quotePage]: 'quote-fullscreen-button',\r\n [SpecificChartFunctionality.futuresPage]: 'futures-fullscreen-button',\r\n [SpecificChartFunctionality.forexPage]: 'forex-fullscreen-button',\r\n [SpecificChartFunctionality.cryptoPage]: 'crypto-fullscreen-button',\r\n}\r\n\r\ninterface FullscreenButtonProps extends Pick {\r\n model: ChartLayout\r\n isPremium: boolean\r\n title?: string\r\n}\r\n\r\nexport function FullscreenButton({ model, isPremium, ...props }: React.PropsWithChildren) {\r\n const location = useLocation()\r\n const { i, p = 'd', r } = decodeQueryString(location.search)\r\n const urlTickers = model\r\n .charts()\r\n .all()\r\n .map((chart) => chart.quote().getRawTicker())\r\n\r\n return (\r\n p).join(','),\r\n l: getLayoutType(urlTickers.length),\r\n r,\r\n })}`\r\n : `/elite.ashx?${encodeQueryString({\r\n utm_source: 'finviz',\r\n utm_medium: 'banner',\r\n utm_campaign: utmCampaign[model.specificChartFunctionality],\r\n })}`\r\n }\r\n />\r\n )\r\n}\r\n","import {\r\n Button,\r\n Dialog,\r\n Dropdown,\r\n DropdownItem,\r\n Icon,\r\n Spinner,\r\n Search as WebsiteSearchComponent,\r\n createAlertAsyncModule,\r\n saveToPortfolioAsyncModule,\r\n useDialogState,\r\n useDropdownState,\r\n} from '@finviz/website'\r\nimport * as React from 'react'\r\n\r\nimport { Instrument } from '../../../types/shared'\r\nimport { useAsyncModule } from '../../utils/async-modules-utils'\r\n\r\ninterface SearchProps {\r\n ticker: string\r\n instrument: Instrument\r\n onTickerSelected: (ticker: string) => void\r\n chartIndex: number\r\n}\r\n\r\nexport default function Search({ ticker, instrument, onTickerSelected, chartIndex }: SearchProps) {\r\n const dropdownState = useDropdownState({ placement: 'bottom-end' })\r\n const saveToPortfolioDialogState = useDialogState()\r\n const isSaveToPortfolioVisible = saveToPortfolioDialogState.useState('open')\r\n const createAlertDialogState = useDialogState()\r\n const isCreateAlertVisible = createAlertDialogState.useState('open')\r\n const [saveToPortfolioModule, { isLoading: isLoadingSaveToPortfolio }] = useAsyncModule({\r\n ...saveToPortfolioAsyncModule,\r\n shouldLoadModule: isSaveToPortfolioVisible,\r\n onError: () => saveToPortfolioDialogState.hide(),\r\n })\r\n const [createAlertModule, { isLoading: isLoadingCreateAlert }] = useAsyncModule({\r\n ...createAlertAsyncModule,\r\n shouldLoadModule: isCreateAlertVisible,\r\n onError: () => createAlertDialogState.hide(),\r\n })\r\n const SaveToPortfolio = saveToPortfolioModule?.SaveToPortfolio\r\n const CreateAlert = createAlertModule?.CreateAlert\r\n\r\n const detailLink = React.useMemo(() => {\r\n const formattedTicker = ticker.replace('@', '')\r\n\r\n switch (instrument) {\r\n case Instrument.Stock:\r\n return `/quote.ashx?t=${formattedTicker}`\r\n case Instrument.Futures:\r\n return `/futures_charts.ashx?t=${formattedTicker}`\r\n case Instrument.Forex:\r\n return `/forex_charts.ashx?t=${formattedTicker}`\r\n case Instrument.Crypto:\r\n return `/crypto_charts.ashx?t=${formattedTicker}`\r\n }\r\n }, [ticker, instrument])\r\n\r\n return (\r\n
\r\n }\r\n />\r\n }\r\n >\r\n {\r\n window.gtag?.('event', 'click', { event_category: 'open-stock-detail' })\r\n }}\r\n >\r\n {instrument === Instrument.Stock ? 'Open Stock Detail' : 'Open Detail'}\r\n \r\n {instrument === Instrument.Stock && (\r\n {\r\n saveToPortfolioDialogState.show()\r\n window.gtag?.('event', 'click', { event_category: 'save-to-portfolio' })\r\n }}\r\n >\r\n Save to Portfolio\r\n \r\n )}\r\n {instrument === Instrument.Stock && (\r\n {\r\n createAlertDialogState.show()\r\n window.gtag?.('event', 'click', { event_category: 'create-alert' })\r\n }}\r\n >\r\n Create Alert\r\n \r\n )}\r\n \r\n }\r\n />\r\n \r\n {isLoadingSaveToPortfolio && (\r\n
\r\n \r\n
\r\n )}\r\n {SaveToPortfolio && }\r\n
\r\n \r\n {isLoadingCreateAlert && (\r\n
\r\n \r\n
\r\n )}\r\n {CreateAlert && }\r\n
\r\n
\r\n )\r\n}\r\n","import {\r\n ButtonRoundingType,\r\n ButtonSizeType,\r\n CustomDateRange,\r\n Heading,\r\n TimeframeBar,\r\n useCustomDateRangeDialog,\r\n useFavoriteTimeframes,\r\n} from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport React from 'react'\r\nimport { useNavigate } from 'react-router-dom'\r\n\r\nimport { ChartEditorEnum, SpecificChartFunctionality, TIMEFRAME } from '../../constants/common'\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport Chart from '../../models/chart'\r\nimport { IdeasDropdown } from '../header/ideas_dropdown'\r\nimport { Publish } from '../header/publish'\r\nimport { TourButton } from '../header/tour_button'\r\nimport { ChartTypesSelect } from './chart-type-select'\r\nimport { DailyChangeDisplay } from './daily-change-display'\r\nimport { DrawButton } from './draw-button'\r\nimport { FullscreenButton } from './fullscreen-button'\r\nimport Search from './search'\r\nimport { ChartSettingsButton } from './settings-button'\r\nimport { useChartControls } from './use-chart-controls'\r\nimport { IDateRange, useChartModelCustomDateRangeValues } from './use-chart-model-custom-date-range-values'\r\n\r\ninterface SettingsComponentProps {\r\n chartModel: Chart\r\n chartIndex: number\r\n}\r\n\r\nconst isPremium = window.FinvizSettings.hasUserPremium\r\nconst hasRedesignEnabled = window.FinvizSettings.hasRedesignEnabled\r\n\r\nexport function ChartControls({ chartIndex, chartModel: unwatchedChartModel }: SettingsComponentProps) {\r\n const rounding: ButtonRoundingType | undefined = hasRedesignEnabled ? undefined : 'none'\r\n // This memo is required for publish, otherwise it ends up in a loop\r\n const chartLayout = React.useMemo(() => unwatchedChartModel.chart_layout(), [unwatchedChartModel])\r\n const chartModel = useModelState(unwatchedChartModel, {\r\n watchProperties: ['ticker', 'quote', 'dateRange'],\r\n })\r\n const { instrument } = chartModel?.quote() || {}\r\n const isQuotePage = chartLayout.specificChartFunctionality === SpecificChartFunctionality.quotePage\r\n\r\n const navigate = useNavigate()\r\n const { favoriteTimeframes, toggleFavoriteTimeframe } = useFavoriteTimeframes()\r\n const { isLoading } = useChartControls({\r\n chartModel,\r\n isInteractive: true,\r\n })\r\n const {\r\n anchorDate,\r\n generateChartLayoutRouterPath,\r\n timeframeGroupsWithHref,\r\n dateRangeGroupsWithHref,\r\n isFetching,\r\n handleCustomDateRangeValidation,\r\n } = useChartModelCustomDateRangeValues({ chartModel, isPremium })\r\n const { onDialogSubmit, customDateRangeDialogState, handleDateRangeSelect, getDateRangeTimeframe } =\r\n useCustomDateRangeDialog({\r\n instrument,\r\n anchorDate,\r\n pathGenerator: generateChartLayoutRouterPath,\r\n })\r\n\r\n const handleTickerSelect = React.useCallback(\r\n (ticker: string) => {\r\n const upperCaseTicker = ticker.toUpperCase()\r\n\r\n navigate(\r\n generateChartLayoutRouterPath({\r\n ticker: upperCaseTicker,\r\n timeframe: chartModel.timeframe,\r\n dateRange: chartModel.dateRange,\r\n })\r\n )\r\n },\r\n [chartModel, generateChartLayoutRouterPath, navigate]\r\n )\r\n\r\n async function handleCustomRangeSubmit(values: { dateRange: string | null }) {\r\n const dateRangeTimeframe = getDateRangeTimeframe(values.dateRange) as IDateRange | null\r\n if (!dateRangeTimeframe) return\r\n\r\n const isValid = await handleCustomDateRangeValidation(dateRangeTimeframe)\r\n if (isValid) onDialogSubmit(dateRangeTimeframe)\r\n }\r\n\r\n const timeframeBarProps = React.useMemo(\r\n () => ({\r\n size: 'medium' as ButtonSizeType,\r\n chartIndex: chartIndex,\r\n timeFrameGroups: timeframeGroupsWithHref(isPremium),\r\n dateRangeGroups: dateRangeGroupsWithHref({ isPremium, customRange: chartModel.dateRange, instrument }),\r\n selectedTimeframe: chartModel.timeframe,\r\n onTimeframeSelect: () => {},\r\n selectedDateRange: chartModel.dateRange,\r\n favoriteTimeframes: favoriteTimeframes,\r\n loadingTimeframe: isLoading ? chartModel.timeframe : undefined,\r\n onDateRangeSelect: handleDateRangeSelect,\r\n onCustomDateRangeClick: () => {\r\n if (isPremium) customDateRangeDialogState.show()\r\n },\r\n isFavoritesEnabled: isPremium,\r\n onFavoriteTimeframeToggle: ({ value }: { value: TIMEFRAME | 'intraday' }) => {\r\n toggleFavoriteTimeframe(value)\r\n },\r\n }),\r\n [\r\n chartIndex,\r\n chartModel.dateRange,\r\n chartModel.timeframe,\r\n customDateRangeDialogState,\r\n dateRangeGroupsWithHref,\r\n favoriteTimeframes,\r\n handleDateRangeSelect,\r\n instrument,\r\n isLoading,\r\n timeframeGroupsWithHref,\r\n toggleFavoriteTimeframe,\r\n ]\r\n )\r\n\r\n if (chartLayout.specificChartFunctionality === SpecificChartFunctionality.chartPage) {\r\n return (\r\n
\r\n {chartModel.chart_layout().canChangeTicker && (\r\n \r\n )}\r\n\r\n \r\n\r\n \r\n\r\n \r\n
\r\n )\r\n }\r\n\r\n const hasTimeframe = chartLayout.editors.includes(ChartEditorEnum.timeframe)\r\n\r\n return (\r\n \r\n
\r\n {!isQuotePage && (\r\n \r\n {chartModel.quote().name ?? chartModel.ticker}\r\n \r\n )}\r\n {chartLayout.editors.includes(ChartEditorEnum.tools) && (\r\n \r\n Draw\r\n \r\n )}\r\n {chartLayout.editors.includes(ChartEditorEnum.ideas) && (\r\n \r\n Ideas\r\n \r\n )}\r\n {!hasTimeframe && (\r\n
\r\n \r\n
\r\n )}\r\n
\r\n\r\n {hasTimeframe && (\r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n \r\n \r\n
\r\n
\r\n
\r\n )}\r\n\r\n
\r\n {chartLayout.editors.includes(ChartEditorEnum.publish) && (\r\n \r\n Share\r\n \r\n )}\r\n {isQuotePage && (\r\n \r\n )}\r\n \r\n {!isQuotePage && 'Fullscreen'}\r\n \r\n {chartLayout.editors.includes(ChartEditorEnum.settings) && (\r\n \r\n {!isQuotePage && 'Settings'}\r\n \r\n )}\r\n {!isQuotePage && (\r\n
\r\n \r\n
\r\n )}\r\n
\r\n \r\n )\r\n}\r\n","import Spine from '@finviz/spine'\r\nimport { ContextMenuItem } from '@finviz/website'\r\n\r\nclass ContextMenu extends Spine.Model {\r\n static initClass() {\r\n this.configure('ContextMenu', 'shown', 'config', 'top', 'left')\r\n }\r\n\r\n declare shown: boolean\r\n declare config: ContextMenuItem[]\r\n declare top: number\r\n declare left: number\r\n}\r\n\r\nContextMenu.initClass()\r\n\r\nconst contextMenu = ContextMenu.create() as ContextMenu\r\ncontextMenu.save()\r\n\r\nexport default contextMenu\r\n","import { ContextMenu as ContextMenuComponent } from '@finviz/website'\r\nimport React from 'react'\r\nimport * as ReactDOM from 'react-dom'\r\n\r\nimport { ObjectHash } from '../../types/shared'\r\nimport model from '../models/context_menu'\r\nimport { ready } from '../utils'\r\n\r\nconst selector = '.context-menu'\r\n\r\nclass ContextMenu extends React.Component {\r\n componentDidMount() {\r\n model.bind('update', this.update)\r\n }\r\n\r\n componentWillUnmount() {\r\n model.unbind('update', this.update)\r\n }\r\n\r\n update = () => {\r\n this.forceUpdate()\r\n }\r\n\r\n render() {\r\n if (model.shown) {\r\n document.querySelector(selector)?.classList.remove('hidden')\r\n } else {\r\n document.querySelector(selector)?.classList.add('hidden')\r\n return null\r\n }\r\n\r\n return (\r\n <>\r\n this.hide()}\r\n onContextMenu={(e) => e.preventDefault()}\r\n data-testid=\"charts-context-menu-overlay\"\r\n >\r\n \r\n \r\n )\r\n }\r\n\r\n hide() {\r\n model.updateAttribute('shown', false)\r\n }\r\n}\r\nready(() => {\r\n const el = document.querySelector(selector)\r\n if (el) {\r\n ReactDOM.render(, el)\r\n }\r\n})\r\n\r\nconst contextMenuControl = {\r\n show: (event: MouseEvent | React.MouseEvent, config: ObjectHash) => {\r\n model.updateAttributes({\r\n shown: true,\r\n config: config,\r\n top: event.clientY + window.pageYOffset,\r\n left: event.clientX,\r\n })\r\n },\r\n}\r\n\r\nexport default contextMenuControl\r\n","import {\r\n AriakitPortal,\r\n Delayed,\r\n DialogBody,\r\n Popover,\r\n PopoverAnchor,\r\n Spinner,\r\n ZIndexContext,\r\n usePopoverState,\r\n} from '@finviz/website'\r\nimport classNames from 'classnames'\r\nimport React from 'react'\r\n\r\nimport { chartEventsAsyncModule } from '../../controllers/chart-events/async-modules'\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport ChartModel from '../../models/chart'\r\nimport { useAsyncModule } from '../../utils/async-modules-utils'\r\nimport { useClickAway } from '../../utils/use-click-away'\r\n\r\ninterface ChartEventPopoverWithStateProps {\r\n chartModel: ChartModel\r\n}\r\n\r\nexport function ChartEventPopoverWithState({ chartModel }: ChartEventPopoverWithStateProps) {\r\n const unwatchedChartLayout = React.useMemo(() => chartModel.chart_layout() ?? null, [chartModel])\r\n const { activeChartEvent, theme } = useModelState(unwatchedChartLayout, { watchProperties: ['activeChartEvent'] })\r\n const popoverState = usePopoverState({ placement: 'top' })\r\n const isPopoverMounted = popoverState.useState('mounted')\r\n const [style, setStyle] = React.useState({ top: 0, left: 0 })\r\n const [chartEventsModule] = useAsyncModule({\r\n ...chartEventsAsyncModule,\r\n shouldLoadModule: isPopoverMounted,\r\n errorSeverity: 'medium',\r\n onError: () => popoverState.hide(),\r\n })\r\n const isChartEventOfThisChart = activeChartEvent?.pane().chart().eql(chartModel)\r\n const [data, setData] = React.useState(null)\r\n const clickAwayRef = useClickAway(() => {\r\n const isAnyBadgeHovered = !!chartModel\r\n .getChartPane()\r\n ?.getAllChartEvents()\r\n .some((chartEvent) => chartEvent.instance.isHovered)\r\n\r\n if (!isAnyBadgeHovered && activeChartEvent && isChartEventOfThisChart) {\r\n activeChartEvent.instance.toggleIsOpen(false)\r\n }\r\n }, !!activeChartEvent && isChartEventOfThisChart)\r\n // This is intentional, it doesn't need to be in useEffect, it would just call effect function which is redundant\r\n clickAwayRef.current = popoverState.useState('popoverElement')\r\n const popoverShow = popoverState.show\r\n const popoverHide = popoverState.hide\r\n\r\n React.useEffect(() => {\r\n if (!activeChartEvent?.instance.isOpen || !isChartEventOfThisChart) {\r\n if (!isPopoverMounted) {\r\n return setData(null)\r\n }\r\n return popoverHide()\r\n }\r\n if (!isChartEventOfThisChart) return\r\n const { top, left } = activeChartEvent.instance\r\n const newData = activeChartEvent.getChartEventData()\r\n if (newData?.elementId !== data?.elementId) {\r\n setData({\r\n ...newData,\r\n badgeType: activeChartEvent.instance.getChartEvenBadgeType(),\r\n })\r\n }\r\n\r\n if (style.top !== top || style.left !== left) {\r\n setStyle({ top, left })\r\n }\r\n if (!isPopoverMounted) {\r\n popoverShow()\r\n }\r\n }, [\r\n activeChartEvent,\r\n data?.elementId,\r\n isChartEventOfThisChart,\r\n isPopoverMounted,\r\n popoverHide,\r\n popoverShow,\r\n popoverState,\r\n style.left,\r\n style.top,\r\n ])\r\n\r\n return (\r\n <>\r\n \r\n {data && (\r\n \r\n \r\n \r\n \r\n {chartEventsModule ? (\r\n \r\n ) : (\r\n
\r\n \r\n \r\n \r\n
\r\n )}\r\n \r\n \r\n
\r\n
\r\n )}\r\n \r\n )\r\n}\r\n","import React from 'react'\r\n\r\nimport Utils from '../utils'\r\n\r\nexport function useClickAway(callback: (event: MouseEvent | TouchEvent) => void, isListening = true) {\r\n const ref = React.useRef(null)\r\n const refCallback = React.useRef(callback)\r\n\r\n React.useLayoutEffect(() => {\r\n refCallback.current = callback\r\n })\r\n\r\n React.useEffect(() => {\r\n if (!isListening) {\r\n return\r\n }\r\n const isMobile = Utils.isMobile()\r\n const handler = (e: MouseEvent | TouchEvent) => {\r\n const element = ref.current\r\n if (element && e.target && !element.contains(e.target as HTMLElement)) {\r\n refCallback.current(e)\r\n }\r\n }\r\n\r\n document.addEventListener(isMobile ? 'touchstart' : 'mousedown', handler)\r\n\r\n return () => {\r\n document.removeEventListener(isMobile ? 'touchstart' : 'mousedown', handler)\r\n }\r\n }, [callback, isListening])\r\n\r\n return ref\r\n}\r\n","import { Button, ButtonGroup, Delayed, Icon, Spinner } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport Chart from '../../models/chart'\r\nimport { QuoteFetchType } from '../../models/quote/constants'\r\nimport { useIsMounted } from '../../utils/use-is-mounted'\r\n\r\ninterface LoadLatestDataButtonProps {\r\n chartModel: Chart\r\n}\r\n\r\nexport function LoadLatestDataButton({ chartModel: chartModelUnwatched }: LoadLatestDataButtonProps) {\r\n const getIsMounted = useIsMounted()\r\n const chartModel = useModelState(chartModelUnwatched, { watchProperties: ['quote'] })\r\n const quoteModel = useModelState(chartModel.quote(), { watchProperties: ['isFetching'] })\r\n const [hasNewDataAvailable, setHasNewDataAvailable] = React.useState(false)\r\n\r\n React.useEffect(() => {\r\n if (!chartModel.getRefreshInterval()) {\r\n // We will do a check here if we have correct new data\r\n chartModel\r\n .quote()\r\n .isPossibleToFetchSequentialData()\r\n .then((hasNewData) => {\r\n if (getIsMounted()) {\r\n setHasNewDataAvailable(hasNewData)\r\n }\r\n })\r\n }\r\n // We need to run it only on mount\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [])\r\n\r\n const handleLoadLatestData = async () => {\r\n const promises = chartModel\r\n .getAllQuotes()\r\n .map(async (quote) => quote.fetchData({ fetchType: QuoteFetchType.NewerData }))\r\n chartModel.updateAttributes({ refreshData: true })\r\n await Promise.all(promises)\r\n if (getIsMounted()) {\r\n setHasNewDataAvailable(false)\r\n window.gtag?.('event', 'load-latest-data', { event_category: 'ideas' })\r\n }\r\n }\r\n\r\n if (!hasNewDataAvailable) {\r\n return null\r\n }\r\n\r\n return (\r\n \r\n }>\r\n \r\n \r\n ) : (\r\n 'refresh'\r\n )\r\n }\r\n disabled={quoteModel?.isFetching}\r\n title=\"Load latest data\"\r\n onClick={handleLoadLatestData}\r\n data-testid=\"load-latest-data-button\"\r\n >\r\n Load latest data\r\n \r\n \r\n )\r\n}\r\n","// Copy if this file is in Website repo in Website/js/main/hooks/ folder\r\nimport * as React from 'react'\r\n\r\nexport function useIsMounted() {\r\n const isMountedRef = React.useRef(false)\r\n const getIsMounted = React.useCallback(() => isMountedRef.current, [])\r\n\r\n React.useEffect(() => {\r\n isMountedRef.current = true\r\n return () => {\r\n isMountedRef.current = false\r\n }\r\n }, [])\r\n\r\n return getIsMounted\r\n}\r\n","import { Button, ButtonGroup, ButtonSizeType, Icon } from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport debounce from 'lodash.debounce'\r\nimport React from 'react'\r\n\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport Chart from '../../models/chart'\r\nimport Utils from '../../utils'\r\nimport { getLeftOffset } from '../renderUtils'\r\nimport { LoadLatestDataButton } from './load-latest-data-button'\r\n\r\nexport const ZOOM_CONTROLS_ACTIVE_CLASS = 'is-active'\r\nexport const ZOOM_CONTROLS_IS_IN_AREA_CLASS = 'is-in-area'\r\n\r\nconst buttonCommonProps: { size: ButtonSizeType; className: string; contentClass: string } = {\r\n size: 'none',\r\n className: 'w-7 h-6',\r\n contentClass: 'flex justify-center',\r\n}\r\n\r\nconst isMobile = Utils.isMobile()\r\n\r\ninterface ZoomControlsProps {\r\n zoomControlsRef: React.RefObject\r\n isVisible: boolean\r\n chartModel: Chart\r\n onZoomIn: () => void\r\n onZoomOut: () => void\r\n onZoomReset: () => void\r\n}\r\n\r\nconst getDefaultLeftOffset = (chartModel: Chart) =>\r\n getLeftOffset({\r\n quote: chartModel.quote(),\r\n chartModel,\r\n config: {},\r\n })\r\n\r\nexport function ZoomControls({\r\n zoomControlsRef,\r\n chartModel,\r\n isVisible,\r\n onZoomIn,\r\n onZoomOut,\r\n onZoomReset,\r\n}: ZoomControlsProps) {\r\n const chartLayoutModel = useModelState(chartModel.chart_layout(), { watchProperties: ['idea'] })\r\n const [isGoToRecentVisible, setIsGoToRecentVisible] = React.useState(false)\r\n const { defaultZoomFactor } = chartLayoutModel\r\n const [isZoomResetVisible, setIsZoomResetVisible] = React.useState(chartModel.zoomFactor !== defaultZoomFactor)\r\n const handleGoToMostRecent = React.useCallback(() => {\r\n chartModel.updateAttributes({ leftOffset: getDefaultLeftOffset(chartModel), dateRange: null })\r\n }, [chartModel])\r\n\r\n React.useEffect(() => {\r\n const handleChartModelChangeDebounced = debounce(\r\n () => {\r\n setIsZoomResetVisible(chartModel.zoomFactor !== defaultZoomFactor)\r\n setIsGoToRecentVisible(chartModel.leftOffset !== getDefaultLeftOffset(chartModel))\r\n },\r\n 100,\r\n { maxWait: 333 }\r\n )\r\n chartModel.bind('change', handleChartModelChangeDebounced)\r\n return () => {\r\n handleChartModelChangeDebounced.cancel()\r\n chartModel.unbind('change', handleChartModelChangeDebounced)\r\n }\r\n }, [defaultZoomFactor, chartModel])\r\n\r\n return (\r\n \r\n {!isMobile && (\r\n
\r\n {isZoomResetVisible && (\r\n
\r\n \r\n \r\n \r\n \r\n \r\n
\r\n )}\r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n
\r\n )}\r\n\r\n
\r\n {!!chartLayoutModel.idea?.id && }\r\n\r\n {isGoToRecentVisible && (\r\n \r\n \r\n \r\n \r\n \r\n )}\r\n
\r\n \r\n )\r\n}\r\n","import Spine from '@finviz/spine'\r\nimport { Button, Notification, NotificationContextType, Paragraph, withNotificationContext } from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport Hammer from 'hammerjs'\r\nimport debounce from 'lodash.debounce'\r\nimport React from 'react'\r\n\r\nimport { CustomSpineEvents, DrawingSpineOptionsEvent, EmptyObject, ObjectHash, PaneArea } from '../../../types/shared'\r\nimport CanvasElement from '../../canvas/element'\r\nimport ChartEvent from '../../chart-events/chart-event'\r\nimport { IndicatorType, ScaleType, SetVisibilityTo, SpecificChartFunctionality } from '../../constants/common'\r\nimport IndicatorElement from '../../indicators/indicator'\r\nimport { withElementStyleDialogState } from '../../modals/element_style'\r\nimport ChartModel from '../../models/chart'\r\nimport ChartEventElement from '../../models/chart-event-element'\r\nimport ElementModel from '../../models/element'\r\nimport MouseModel from '../../models/mouse'\r\nimport PaneModel from '../../models/pane'\r\nimport Quote from '../../models/quote'\r\nimport { handleRemoveIndicatorPane } from '../../models/utils'\r\nimport Utils, { isRedesignedPage } from '../../utils'\r\nimport { getContextWithCache } from '../../utils/canvas'\r\nimport { getBarWidthWithMargin, unmountCanvas } from '../../utils/chart'\r\nimport { setElementCursor } from '../../utils/cursor'\r\nimport { getValueInRange, isPrimaryClick } from '../../utils/helpers'\r\nimport { getInitialStoreDrawings } from '../autosave/utils'\r\nimport { CHART_LAYOUT_CHILD_CHANGE_EVENT } from '../chart_layout/constants'\r\nimport ContextMenu from '../context_menu'\r\nimport { getMinMaxLeftOffset, getSettings, recountScale, renderPane } from '../renderUtils'\r\nimport { DrawingTool } from '../toolbar/interfaces'\r\nimport { getChartAlt } from '../utils'\r\nimport { ChartEventPopoverWithState } from './chart-event-popover-with-state'\r\nimport { withPaneModel } from './with-pane-model'\r\nimport { ZOOM_CONTROLS_ACTIVE_CLASS, ZOOM_CONTROLS_IS_IN_AREA_CLASS, ZoomControls } from './zoom_controls'\r\n\r\n// Indicates how many time lower/higher can new scale be compared to original one\r\nconst ALLOWED_MIN_MAX_ZOOM = 10000\r\n\r\ninterface PaneProps {\r\n model: PaneModel\r\n chartModel: ChartModel\r\n activeTool: DrawingTool\r\n activeChartInteraction: string | null\r\n chartIndex: number\r\n paneIndex: number\r\n touchEventsDisabled: boolean\r\n onPaneClick?: (model: PaneModel) => void\r\n onZoomerReset: () => void\r\n onZoomerMouseDown: React.MouseEventHandler\r\n onZoomerTouchStart: React.TouchEventHandler\r\n onAddToZoomFactor: (data: { diff: number; shouldCalculateRightAlign: boolean }) => void\r\n onResizerMouseDown: (e: React.MouseEvent, model: PaneModel) => void\r\n onPaneDestroy: (paneId: string) => void\r\n setActiveChartInteraction: (value: string | null) => void\r\n openElementStyleDialog?: (element: CanvasElement | IndicatorElement) => void\r\n notificationContext: NotificationContextType\r\n}\r\n\r\ninterface PaneState {\r\n hasSeenCrossNotification: boolean\r\n}\r\n\r\nfunction toggleE2eRenderInProgress({ id, isInProgress }: { id: number; isInProgress: boolean }) {\r\n if (process.env.IS_E2E_TESTING) {\r\n window.rendersInProgress = window.rendersInProgress ?? []\r\n\r\n if (isInProgress) {\r\n window.isRenderInProgress = true\r\n window.rendersInProgress.push(id)\r\n } else {\r\n window.rendersInProgress = window.rendersInProgress.filter((progressId) => id !== progressId)\r\n\r\n if (window.rendersInProgress.length === 0) {\r\n window.isRenderInProgress = Date.now()\r\n }\r\n }\r\n }\r\n}\r\n\r\nclass Pane extends React.Component {\r\n rafId?: number | null = null\r\n crossRafId?: number | null = null\r\n quoteModel: Quote\r\n paneRef = React.createRef()\r\n scalerRef = React.createRef()\r\n zoomerRef = React.createRef()\r\n zoomControlsRef = React.createRef()\r\n canvasWrapperRef = React.createRef()\r\n canvasRef = React.createRef()\r\n crossCanvasRef = React.createRef()\r\n chartLayoutModel = this.props.chartModel.chart_layout()\r\n paneHammer!: HammerManager\r\n scalerHammer!: HammerManager\r\n zoomerHammer!: HammerManager\r\n canvasWrapperHammer!: HammerManager\r\n mouseDown = false\r\n lastClientX?: number\r\n lastClientY?: number\r\n currentViewRange: { min: number; max: number } | null = null\r\n lastX!: number\r\n lastY!: number\r\n lastActiveTool: DrawingTool\r\n scalerLastY: number | null = null\r\n isElementHovered = false\r\n hoveredElement: CanvasElement | null = null\r\n isMobile: boolean\r\n isDisableTouchCrossAvailable = true\r\n\r\n canvas: HTMLCanvasElement | null = null\r\n canvasCtx: CanvasRenderingContext2D | null = null\r\n crossCanvas: HTMLCanvasElement | null = null\r\n crossCanvasCtx: CanvasRenderingContext2D | null = null\r\n isIndicatorPane = false\r\n\r\n state: PaneState = {\r\n hasSeenCrossNotification: !!window.localStorage?.getItem('hasSeenCrossNotification'),\r\n }\r\n\r\n // expects chartModel, model, onResizerMouseDown, onPaneDestroy\r\n constructor(props: PaneProps) {\r\n super(props)\r\n\r\n this.quoteModel = this.props.chartModel.quote()\r\n props.model.updateAttribute('instance', this)\r\n props.model.bind('update', this.onModelUpdate)\r\n props.model\r\n .elements()\r\n .bind('create', this.onElementCreate)\r\n .bind('destroy', this.onElementDestroy)\r\n .bind('replace', this.onElementReplace)\r\n .bind('select', this.onElementSelect)\r\n .bind('makeClone', this.onElementClone)\r\n .bind('change', this.immediateRecountScaleOnChartIndicatorChange)\r\n .bind('change', debounce(this.recountScale, 50))\r\n props.model.bind(CustomSpineEvents.ManualChange, this.recountScale)\r\n\r\n props.model.chartEvents().bind('create', this.onElementCreate).bind('change', debounce(this.recountScale, 50))\r\n\r\n this.props.chartModel.bind('update', this.onChartUpdate)\r\n this.props.chartModel.bind(`change ${CustomSpineEvents.IndicatorsChange}`, this.recountScale)\r\n this.quoteModel.bind('change', this.recountScale)\r\n this.isMobile = !!Utils.isMobile()\r\n this.lastActiveTool = props.activeTool\r\n if (!MouseModel.pane()) {\r\n MouseModel.updateAttribute('pane', props.model)\r\n }\r\n this.isIndicatorPane = props.model.getIsIndicatorPane()\r\n this.recountScale()\r\n }\r\n\r\n componentDidMount() {\r\n const { model } = this.props\r\n this.chartLayoutModel.bind('theme', this.renderAll)\r\n this.chartLayoutModel.bind('theme', this.renderCross)\r\n\r\n const initialStoreDrawings = getInitialStoreDrawings() ?? []\r\n const elements = [...model.getAllElements(), ...model.getAllChartEvents(false)]\r\n elements.forEach((element) => {\r\n this.onElementCreate(element)\r\n if (element.isDrawing()) {\r\n const hasDrawingInInitialCache = initialStoreDrawings.some(({ elementId }) => element.elementId === elementId)\r\n if (hasDrawingInInitialCache) {\r\n element.instance?.updateScales()\r\n }\r\n element.instance.cachePointPositionTimestamp()\r\n } else if (element.isChartEvent()) {\r\n element.instance?.updateScales()\r\n }\r\n })\r\n\r\n model?.updateChartEventsZIndexes()\r\n\r\n this.canvas = this.canvasRef.current\r\n this.canvasCtx = getContextWithCache(this.canvasRef.current)\r\n this.crossCanvas = this.crossCanvasRef.current\r\n this.crossCanvasCtx = getContextWithCache(this.crossCanvasRef.current)\r\n\r\n this.paneHammer = new Hammer.Manager(this.paneRef.current!, { touchAction: 'none' })\r\n this.paneHammer.add(new Hammer.Press({ threshold: 5, time: 500 })) // chrome simulator \"long touch\" -> \"oncontextmenu\" is 680ms +- 2ms\r\n this.paneHammer.on('press', this.onPress)\r\n this.canvasWrapperHammer = new Hammer(this.canvasWrapperRef.current!, { touchAction: 'none' })\r\n this.canvasWrapperHammer.on('tap', this.onClick)\r\n this.canvasWrapperRef.current?.addEventListener('touchmove', this.onTouchMove, { passive: false })\r\n\r\n if (this.chartLayoutModel.scrollable || !this.isMobile) {\r\n if (this.scalerRef.current) {\r\n this.scalerHammer = new Hammer(this.scalerRef.current, { touchAction: 'none' })\r\n this.scalerHammer.on('doubletap', this.onScalerReset)\r\n }\r\n if (this.zoomerRef.current) {\r\n this.zoomerHammer = new Hammer(this.zoomerRef.current, { touchAction: 'none' })\r\n this.zoomerHammer.on('doubletap', this.props.onZoomerReset)\r\n }\r\n this.canvasWrapperHammer.on('doubletap', this.onDoubleClick)\r\n }\r\n\r\n this.onChartUpdate({ width: this.props.chartModel.width })\r\n this.onModelUpdate({ height: model.height })\r\n this.forceUpdate()\r\n this.chartLayoutModel.trigger(CHART_LAYOUT_CHILD_CHANGE_EVENT)\r\n }\r\n\r\n componentWillUnmount() {\r\n this.canvasWrapperRef.current?.removeEventListener('touchmove', this.onTouchMove)\r\n unmountCanvas(this.canvas)\r\n unmountCanvas(this.crossCanvas)\r\n this.props.chartModel.unbind('update', this.onChartUpdate)\r\n this.props.chartModel.unbind('change', this.recountScale)\r\n this.quoteModel.unbind('change', this.recountScale)\r\n }\r\n\r\n render() {\r\n const { activeTool, touchEventsDisabled, onPaneClick, paneIndex, chartIndex, model, chartModel } = this.props\r\n if (touchEventsDisabled) {\r\n this.paneHammer?.set({ touchAction: 'auto' })\r\n this.scalerHammer?.set({ touchAction: 'auto' })\r\n this.zoomerHammer?.set({ touchAction: 'auto' })\r\n this.canvasWrapperHammer?.set({ touchAction: 'auto' })\r\n } else {\r\n const touchAction = this.getIsHammerAllowScrollActive() ? 'auto' : 'none'\r\n this.scalerHammer?.set({ touchAction: 'none' })\r\n this.zoomerHammer?.set({ touchAction: 'none' })\r\n this.paneHammer?.set({ touchAction })\r\n this.canvasWrapperHammer?.set({ touchAction })\r\n }\r\n\r\n const isChartPane = model.getIsChartPane()\r\n\r\n return (\r\n onPaneClick?.(model)}\r\n onTouchStart={() => onPaneClick?.(model)}\r\n onContextMenu={this.onContextMenu}\r\n data-testid={`chart-${chartIndex}-pane-${paneIndex}`}\r\n >\r\n {isChartPane && }\r\n {paneIndex !== 0 && (\r\n this.props.onResizerMouseDown(e, model)}\r\n data-testid={`chart-${chartIndex}-pane-${paneIndex}-resizer`}\r\n />\r\n )}\r\n {this.chartLayoutModel.initialScrollable && (\r\n \r\n )}\r\n\r\n {this.chartLayoutModel.initialScrollable && isChartPane && (\r\n <>\r\n \r\n {\r\n this.props.onAddToZoomFactor({ diff: 0.1, shouldCalculateRightAlign: true })\r\n }}\r\n onZoomOut={() => {\r\n this.props.onAddToZoomFactor({ diff: -0.1, shouldCalculateRightAlign: true })\r\n }}\r\n onZoomReset={this.props.onZoomerReset}\r\n />\r\n \r\n )}\r\n \r\n {getChartAlt(this.quoteModel)}\r\n {this.chartLayoutModel.cross && }\r\n \r\n \r\n )\r\n }\r\n\r\n getIsHammerAllowScrollActive = () =>\r\n this.chartLayoutModel.specificChartFunctionality !== SpecificChartFunctionality.chartPage &&\r\n !this.chartLayoutModel.isTouchCrossActive &&\r\n !this.chartLayoutModel.scrollable\r\n\r\n onElementCreate = (el: ElementModel | ChartEventElement) => {\r\n el.instance.bind('change', this.renderAll)\r\n this.renderAll()\r\n }\r\n\r\n onElementReplace = (el: ElementModel, oldElementInstance: CanvasElement) => {\r\n oldElementInstance.unbind('change', this.renderAll)\r\n el.instance.bind('change', this.renderAll)\r\n if (oldElementInstance === this.props.model.selection && !this.chartLayoutModel.isDrawingModeContinuousActive) {\r\n this.setSelection(el.instance)\r\n } else {\r\n this.setSelection(null)\r\n }\r\n this.renderAll()\r\n }\r\n\r\n onElementDestroy = (el: ElementModel) => {\r\n const { type } = el.instance\r\n el.instance.unbind('change', this.renderAll)\r\n if (el.instance === this.props.model.selection) {\r\n this.setSelection(null)\r\n }\r\n if (type.startsWith('charts/') || type.startsWith('indicators/')) {\r\n this.props.onPaneDestroy(el['pane_id'])\r\n }\r\n this.renderAll()\r\n }\r\n\r\n onElementSelect = (el: ElementModel) => {\r\n this.setSelectedElement(el.instance)\r\n }\r\n\r\n onElementClone = (_: unknown, clonedElementInstance: CanvasElement) => {\r\n this.setSelectedElement(clonedElementInstance)\r\n }\r\n\r\n onModelUpdate = ({ height }: { height: number }) => {\r\n this.setCanvasSize({\r\n width: this.props.chartModel.width,\r\n height,\r\n })\r\n }\r\n\r\n onChartUpdate = ({ width }: { width: number }) => {\r\n const { model, chartModel } = this.props\r\n this.setCanvasSize({\r\n width,\r\n height: model.height,\r\n })\r\n const quote = chartModel.quote()\r\n if (!this.quoteModel.eql(quote)) {\r\n this.quoteModel.unbind('change', this.recountScale)\r\n if (quote) {\r\n this.quoteModel = quote\r\n this.quoteModel.bind('change', this.recountScale)\r\n }\r\n }\r\n }\r\n\r\n onZoomerMouseMove: React.MouseEventHandler = (e) => {\r\n if (!this.chartLayoutModel.scrollable || (this.isMobile && !this.chartLayoutModel.isTouchCrossActive)) return\r\n const area = this.getArea(e)\r\n MouseModel.updateAttributes({\r\n position: { x: area.x, y: null },\r\n pane: this.props.model,\r\n })\r\n }\r\n\r\n onMouseMoveOnScrolling = (event: TouchEvent | MouseEvent) => {\r\n if (this.props.activeChartInteraction) {\r\n return\r\n }\r\n\r\n let { clientX, clientY } = event as MouseEvent\r\n const { model } = this.props\r\n\r\n const isTouch = typeof TouchEvent !== 'undefined' && event instanceof TouchEvent\r\n if (isTouch && event.targetTouches?.length > 0) {\r\n clientX = event.targetTouches[0].clientX\r\n clientY = event.targetTouches[0].clientY\r\n }\r\n if (!model.selection && !this.chartLayoutModel.activeChartEvent) {\r\n if (this.lastClientX != null) {\r\n const dif = this.lastClientX - clientX\r\n this.addToLeftOffset(-dif)\r\n }\r\n if (model.scaleRange && this.lastClientY != null) {\r\n let { min, max } = model.scaleRange\r\n let difY\r\n switch (this.props.chartModel.scale) {\r\n case ScaleType.Logarithmic: {\r\n difY = this.lastClientY - clientY\r\n min = model.scale.y.invert(model.scale.y(min) + difY)\r\n max = model.scale.y.invert(model.scale.y(max) + difY)\r\n break\r\n }\r\n default: {\r\n difY = (this.lastClientY - clientY) * (model.scale.y.invert(0) - model.scale.y.invert(1))\r\n min -= difY\r\n max -= difY\r\n break\r\n }\r\n }\r\n\r\n model.updateAttribute('scaleRange', { min, max })\r\n this.recountScale()\r\n this.currentViewRange = this.props.model.getChartOrIndicatorElement()?.instance?.getMinMax?.() ?? null\r\n }\r\n }\r\n this.lastClientX = clientX\r\n this.lastClientY = clientY\r\n }\r\n\r\n onScalerTouchStart: React.TouchEventHandler = (e) => {\r\n if (!this.chartLayoutModel.scrollable || this.props.touchEventsDisabled) return\r\n if (this.chartLayoutModel.scrollable && e.targetTouches.length === 1) {\r\n this.onScalerMouseDown(e.targetTouches[0])\r\n }\r\n }\r\n\r\n onScalerTouchMove = (e: TouchEvent) => {\r\n if (this.chartLayoutModel.scrollable && e.targetTouches.length === 1) {\r\n this.onScalerMouseMove(e.targetTouches[0])\r\n }\r\n }\r\n\r\n onScalerTouchEnd = () => {\r\n if (this.chartLayoutModel.scrollable) {\r\n this.onScalerMouseUp()\r\n }\r\n }\r\n\r\n onScalerMouseEnter = () => {\r\n MouseModel.updateAttributes({\r\n position: null,\r\n pane: null,\r\n })\r\n }\r\n\r\n onScalerMouseDown = (event: React.MouseEvent | React.Touch) => {\r\n const { activeChartInteraction, setActiveChartInteraction, model } = this.props\r\n if ((event instanceof MouseEvent && event.button) || activeChartInteraction || !this.chartLayoutModel.scrollable) {\r\n return\r\n }\r\n setActiveChartInteraction('scaler')\r\n\r\n this.scalerLastY = event.clientY\r\n // here we need current domain scale or former \"nice\" value\r\n const [currentDomainMax, currentDomainMin] = model.scale.y.domain()\r\n this.currentViewRange = { min: currentDomainMin, max: currentDomainMax }\r\n document.addEventListener<'mousemove'>('mousemove', this.onScalerMouseMove)\r\n document.addEventListener('mouseup', this.onScalerMouseUp)\r\n document.addEventListener('touchmove', this.onScalerTouchMove)\r\n document.addEventListener('touchend', this.onScalerTouchEnd)\r\n }\r\n\r\n onScalerMouseMove = (event: MouseEvent | Touch) => {\r\n const { model, chartModel } = this.props\r\n if (model.scaleRange === null && this.currentViewRange === null) {\r\n return\r\n }\r\n let { min, max } = model.scaleRange || this.currentViewRange!\r\n let difY\r\n switch (this.props.chartModel.scale) {\r\n case ScaleType.Logarithmic: {\r\n difY = this.scalerLastY! - event.clientY\r\n min = model.scale.y.invert(model.scale.y(min) - difY)\r\n max = model.scale.y.invert(model.scale.y(max) + difY)\r\n break\r\n }\r\n default: {\r\n difY = -(this.scalerLastY! - event.clientY) * (model.scale.y.invert(0) - model.scale.y.invert(1))\r\n min -= difY\r\n max += difY\r\n break\r\n }\r\n }\r\n this.scalerLastY = event.clientY\r\n\r\n const originalMinMax = model.getChartOrIndicatorElement()?.instance?.getMinMax?.()\r\n if (originalMinMax) {\r\n const currentDiff = Math.abs(max - min)\r\n const originalDiff = Math.abs(originalMinMax.max - originalMinMax.min)\r\n\r\n if (currentDiff > originalDiff * ALLOWED_MIN_MAX_ZOOM || currentDiff < originalDiff / ALLOWED_MIN_MAX_ZOOM) {\r\n return\r\n }\r\n }\r\n\r\n model.updateAttribute('scaleRange', { min, max })\r\n chartModel.updateAttribute('dateRange', null)\r\n this.recountScale()\r\n }\r\n\r\n onScalerMouseUp = () => {\r\n this.scalerLastY = null\r\n\r\n document.removeEventListener('mousemove', this.onScalerMouseMove)\r\n document.removeEventListener('mouseup', this.onScalerMouseUp)\r\n document.removeEventListener('touchmove', this.onScalerTouchMove)\r\n document.removeEventListener('touchend', this.onScalerTouchEnd)\r\n this.props.setActiveChartInteraction(null)\r\n }\r\n\r\n onScalerReset = () => {\r\n const { model, chartModel } = this.props\r\n if (!this.chartLayoutModel.scrollable) return\r\n chartModel.updateAttribute('dateRange', null)\r\n model.updateAttribute('scaleRange', null)\r\n this.recountScale()\r\n }\r\n\r\n addToLeftOffset = (n: number) => {\r\n const quote = this.props.chartModel.quote()\r\n const barWidth = getBarWidthWithMargin({\r\n chartLayout: this.chartLayoutModel,\r\n zoomFactor: this.props.chartModel.zoomFactor,\r\n })\r\n const leftOffset = getMinMaxLeftOffset({\r\n newLeftOffset: this.props.chartModel.leftOffset + n,\r\n chartModel: this.props.chartModel,\r\n barWidth,\r\n barIndex: quote.barIndex[quote.open.length - 1],\r\n })\r\n\r\n if (leftOffset > barWidth) {\r\n quote.fetchOlderData()\r\n }\r\n this.props.chartModel.updateAttributes({\r\n leftOffset,\r\n dateRange: null,\r\n })\r\n }\r\n\r\n onDoubleClick = (event: HammerInput) => {\r\n event.preventDefault()\r\n const area = this.getArea(event)\r\n const element = this.props.model.selection || this.getElement(area)\r\n if (element && element.type !== IndicatorType.Cot && !element.isCreator) {\r\n setTimeout(() => {\r\n this.props.openElementStyleDialog!(element)\r\n }, 0)\r\n element.trigger('dblclick', event)\r\n }\r\n }\r\n\r\n onPress = (e: ObjectHash) => {\r\n if (e.pointerType !== 'touch') return\r\n\r\n e.clientX = e.center.x\r\n e.clientY = e.center.y\r\n\r\n const el = this.props.model.selection || this.getElement(this.getArea(e))\r\n if (!this.chartLayoutModel.isTouchCrossActive) {\r\n if (!el) {\r\n this.onCanvasPress(e as React.MouseEvent)\r\n } else {\r\n this.onContextMenu(e as React.MouseEvent, el)\r\n }\r\n }\r\n }\r\n\r\n onContextMenu = (e: React.MouseEvent, element?: IndicatorElement | CanvasElement) => {\r\n e.preventDefault()\r\n const area = this.getArea(e)\r\n const elementInArea = this.getElement(area)\r\n const el = element ?? elementInArea\r\n if (!el || el.thumbsAreInArea(area)) {\r\n return\r\n }\r\n const elementModel = ElementModel.findByAttribute('instance', el)\r\n if (!elementModel) return\r\n this.setSelectedElement(el)\r\n const hasProperties =\r\n ['indicator', 'canvas'].some((type) => el.type.startsWith(type)) && el.type !== IndicatorType.Cot\r\n const isElementDrawing = elementModel.isDrawing()\r\n\r\n return ContextMenu.show(\r\n e,\r\n [\r\n hasProperties && {\r\n id: 'edit',\r\n label: 'Edit style',\r\n onClick: () => this.props.openElementStyleDialog!(el),\r\n },\r\n\r\n !(elementModel.isChart() || elementModel?.isIndicator()) && {\r\n id: 'clone',\r\n label: 'Clone',\r\n onClick: () => elementModel.makeClone(),\r\n },\r\n\r\n ...(isElementDrawing\r\n ? [\r\n { type: 'divider', label: 'Visibility' },\r\n\r\n {\r\n id: 'visibility-current-and-above',\r\n label: 'Current interval and above',\r\n onClick: () => elementModel.instance.setVisibilityTo(SetVisibilityTo.currentAndAbove),\r\n },\r\n\r\n {\r\n id: 'visibility-current-and-below',\r\n label: 'Current interval and below',\r\n onClick: () => elementModel.instance.setVisibilityTo(SetVisibilityTo.currentAndBelow),\r\n },\r\n\r\n {\r\n id: 'visibility-current-only',\r\n label: 'Current interval only',\r\n onClick: () => elementModel.instance.setVisibilityTo(SetVisibilityTo.currentOnly),\r\n },\r\n\r\n {\r\n id: 'visibility-all-intervals',\r\n label: 'All intervals',\r\n onClick: () => elementModel.instance.setVisibilityTo(SetVisibilityTo.all),\r\n },\r\n ]\r\n : []),\r\n\r\n (isElementDrawing || hasProperties) && { type: 'divider' },\r\n\r\n {\r\n id: 'bring-to-front',\r\n label: 'Bring to Front',\r\n onClick: () => elementModel.bringToFront(),\r\n },\r\n {\r\n id: 'send-to-back',\r\n label: 'Send to Back',\r\n onClick: () => elementModel.sendToBack(),\r\n },\r\n {\r\n id: 'bring-forward',\r\n label: 'Bring Forward',\r\n onClick: () => elementModel.bringForward(),\r\n },\r\n {\r\n id: 'send-backward',\r\n label: 'Send Backward',\r\n onClick: () => elementModel.sendBackward(),\r\n },\r\n\r\n { type: 'divider' },\r\n\r\n {\r\n id: 'remove',\r\n label: 'Remove',\r\n onClick: () => {\r\n if (elementModel.isIndicator()) {\r\n handleRemoveIndicatorPane({ paneIndex: this.props.paneIndex, chartLayoutModel: this.chartLayoutModel })\r\n } else {\r\n elementModel.destroyCascade({ eventType: DrawingSpineOptionsEvent.Remove })\r\n this.props.model.normalizeZIndexes()\r\n }\r\n },\r\n },\r\n ]\r\n .filter(Boolean)\r\n .map((item) => ({ ...item, gtag: { element_type: el.type } }))\r\n )\r\n }\r\n\r\n immediateRecountScaleOnChartIndicatorChange = (element?: ElementModel) => {\r\n if (element?.isChart() || element?.isIndicator()) {\r\n this.recountScale()\r\n }\r\n }\r\n\r\n recountScale = (_?: unknown, updateType?: Spine.Event) => {\r\n const { model } = this.props\r\n const chartModel = model.chart()\r\n if (updateType === 'destroy' || !chartModel || !chartModel.quote()) {\r\n return\r\n }\r\n\r\n recountScale({ chartModel, paneModel: model })\r\n\r\n if (this.canvasCtx) {\r\n this.renderAll()\r\n }\r\n }\r\n\r\n onBlur = () => {\r\n if (this.props.model.selection?.getIsCreator?.()) {\r\n this.setSelection(null)\r\n } else {\r\n this.setSelectedElement(null)\r\n }\r\n if (this.hoveredElement) {\r\n this.hoveredElement.setIsHovered(false)\r\n this.hoveredElement = null\r\n }\r\n this.props.model.getAllElements().forEach((element) => {\r\n if (element.instance.getIsCreator?.() && !element.instance.getIsCreatorDialogOpen?.()) {\r\n element.destroyCascade()\r\n }\r\n })\r\n }\r\n\r\n renderAll = (type?: string) => {\r\n if (process.env.IS_E2E_TESTING) window.isRenderInProgress = true\r\n\r\n if (type === 'cross' && this.chartLayoutModel.cross) {\r\n if (this.crossRafId === null) {\r\n const crossRafId = window.requestAnimationFrame(() => {\r\n this.renderCross()\r\n if (process.env.IS_E2E_TESTING) {\r\n toggleE2eRenderInProgress({ id: crossRafId, isInProgress: false })\r\n }\r\n })\r\n if (process.env.IS_E2E_TESTING) {\r\n toggleE2eRenderInProgress({ id: crossRafId, isInProgress: true })\r\n }\r\n this.crossRafId = crossRafId\r\n }\r\n } else if (this.rafId == null && this.canvasCtx) {\r\n const rafId = window.requestAnimationFrame(() => {\r\n this._renderAll()\r\n if (process.env.IS_E2E_TESTING) {\r\n toggleE2eRenderInProgress({ id: rafId, isInProgress: false })\r\n }\r\n })\r\n if (process.env.IS_E2E_TESTING) {\r\n toggleE2eRenderInProgress({ id: rafId, isInProgress: true })\r\n }\r\n this.rafId = rafId\r\n }\r\n }\r\n\r\n _renderAll = () => {\r\n const { model } = this.props\r\n // _renderAll may be called after Chart was deleted because of requestAnimationFrame\r\n if (model.chart() === null || this.canvasRef.current === null || !this.canvasCtx) {\r\n return\r\n }\r\n if (this.getIsUpdatedDesign()) {\r\n if (this.crossRafId === null) {\r\n this.crossRafId = window.requestAnimationFrame(this.renderCross)\r\n }\r\n }\r\n this.rafId = undefined\r\n\r\n renderPane({\r\n chartLayoutModel: this.chartLayoutModel,\r\n chartModel: this.props.chartModel,\r\n paneModel: model,\r\n canvasCtx: this.canvasCtx,\r\n })\r\n }\r\n\r\n getIsUpdatedDesign() {\r\n const { specificChartFunctionality } = this.chartLayoutModel\r\n const isCharts = specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n const isRedesignedFuturesForexCrypto = isRedesignedPage({ specificChartFunctionality })\r\n\r\n return isCharts || isRedesignedFuturesForexCrypto\r\n }\r\n\r\n renderCross = () => {\r\n const { model } = this.props\r\n const isMouseInPane = MouseModel.getShouldRenderCrossInPane(model)\r\n this.crossRafId = null\r\n if (!this.crossCanvasCtx) {\r\n return\r\n }\r\n this.crossCanvasCtx.clearRect(0, 0, this.props.chartModel.width, model.height)\r\n const isCrossDisabled =\r\n PaneModel.select((p) => !!p.selection && !p.selection.type.startsWith('indicators/')).length !== 0 ||\r\n this.props.chartModel.getIsDisabled() ||\r\n !isMouseInPane\r\n\r\n for (const { instance: elementInstance } of model.getAllElements()) {\r\n if (\r\n (!isCrossDisabled && elementInstance.renderCross != null) ||\r\n (isCrossDisabled && elementInstance.renderCrossText != null)\r\n ) {\r\n this.crossCanvasCtx.save()\r\n if (isCrossDisabled) {\r\n elementInstance.renderCrossText!(this.crossCanvasCtx, Number.NaN)\r\n } else {\r\n elementInstance.renderCross!(this.crossCanvasCtx)\r\n }\r\n this.crossCanvasCtx.restore()\r\n }\r\n }\r\n }\r\n\r\n getArea = (e: ObjectHash, additionalData?: T): PaneArea => {\r\n const { model } = this.props\r\n const clientX = e.clientX || additionalData?.clientX\r\n const clientY = e.clientY || additionalData?.clientY\r\n const Settings = getSettings(model)\r\n const areaRectangle = this.canvas!.getBoundingClientRect()\r\n const areaRectangleCursorX = clientX - areaRectangle.left\r\n const areaRectangleCursorY = clientY - areaRectangle.top\r\n const x = areaRectangleCursorX - model.chart().leftOffset - Settings.left.width\r\n const y = areaRectangleCursorY - Settings.top.height\r\n const scale = model.scale\r\n const chartLeftX = areaRectangle.left + Settings.left.width\r\n const chartRightX = areaRectangle.right - Settings.right.width\r\n return {\r\n ...(additionalData as T),\r\n // TODO: rewrite if canvas uses padding/border\r\n x: scale.x.invert(x),\r\n y: scale.y.invert(y),\r\n scaled: {\r\n x,\r\n y,\r\n },\r\n width: 1,\r\n height: 1,\r\n cursorX: areaRectangleCursorX,\r\n cursorY: areaRectangleCursorY,\r\n isCursorInChartWidthBoundaries: clientX > chartLeftX && clientX < chartRightX,\r\n }\r\n }\r\n\r\n setCanvasSize = ({ width, height }: { width: number; height: number }) => {\r\n const ratio = Utils.getScaleRatio()\r\n const canvasElement = this.canvasRef.current\r\n\r\n /**\r\n * It seems that value passed into element attr (e.g. height) is ceiled down,\r\n * so if you provide canvas element with height 100.5 we'll get integer 100 from canvasElement.height\r\n * If the difference in values between \"new height\" and canvasElement.height is less than 1, I treat it as the same value\r\n */\r\n if (\r\n this.canvasCtx &&\r\n canvasElement &&\r\n (Math.abs(height * ratio - canvasElement.height) >= 1 || Math.abs(width * ratio - canvasElement.width) >= 1)\r\n ) {\r\n Utils.setSizeOnCanvasElement({ canvasElement, width, height })\r\n this.canvasCtx.scale(ratio, ratio)\r\n if (this.chartLayoutModel.cross && this.crossCanvasCtx) {\r\n Utils.setSizeOnCanvasElement({\r\n canvasElement: this.crossCanvasRef.current,\r\n width,\r\n height,\r\n })\r\n this.crossCanvasCtx.scale(ratio, ratio)\r\n }\r\n setTimeout(() => {\r\n this.recountScale()\r\n })\r\n }\r\n }\r\n\r\n onClick = (event: HammerInput) => {\r\n const area = this.getArea(event, {\r\n clientX: event.center.x,\r\n clientY: event.center.y,\r\n })\r\n const element = this.props.model.selection || this.getElement(area)\r\n element?.trigger('click', area)\r\n\r\n if (!this.isDisableTouchCrossAvailable) {\r\n this.isDisableTouchCrossAvailable = true\r\n return\r\n }\r\n\r\n if (this.chartLayoutModel.isTouchCrossActive) {\r\n MouseModel.updateAttributes({\r\n position: null,\r\n pane: null,\r\n })\r\n this.chartLayoutModel.updateAttributes({\r\n scrollable: this.chartLayoutModel.initialScrollable,\r\n isTouchCrossActive: false,\r\n })\r\n } else if (\r\n this.isMobile &&\r\n !this.state.hasSeenCrossNotification &&\r\n this.lastActiveTool === DrawingTool.Mouse &&\r\n this.chartLayoutModel.specificChartFunctionality !== SpecificChartFunctionality.smallIndex\r\n ) {\r\n const isChartsPage = this.chartLayoutModel.specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n\r\n this.setState({ hasSeenCrossNotification: true })\r\n this.props.notificationContext.show(\r\n {\r\n this.props.notificationContext.hide()\r\n window.localStorage.setItem('hasSeenCrossNotification', 'true')\r\n }}\r\n theme=\"dark\"\r\n >\r\n Got it\r\n \r\n }\r\n >\r\n Long press the chart to show the crosshair.\r\n ,\r\n { inline: !isChartsPage }\r\n )\r\n }\r\n\r\n this.lastActiveTool = this.props.activeTool\r\n }\r\n\r\n onPaneMouseLeave = () => {\r\n // timout in onPaneMouseMove may cause racecondition where active class is added right after it's been removed\r\n setTimeout(() => {\r\n this.zoomControlsRef.current?.classList.remove(ZOOM_CONTROLS_ACTIVE_CLASS, ZOOM_CONTROLS_IS_IN_AREA_CLASS)\r\n })\r\n if (this.chartLayoutModel.specificChartFunctionality === SpecificChartFunctionality.chartPage) {\r\n this.renderCross()\r\n }\r\n }\r\n\r\n onPaneMouseMove = (e: React.MouseEvent | React.Touch, isMouseDownIgnored = false) => {\r\n const { model, chartModel } = this.props\r\n const zoomControls = this.zoomControlsRef.current\r\n const paneHeight = model.height\r\n if (zoomControls) {\r\n const area = this.getArea<{ mouseDown: boolean; clientX: number; clientY: number }>(e, {\r\n mouseDown: !isMouseDownIgnored && this.mouseDown,\r\n clientX: e.clientX,\r\n clientY: e.clientY,\r\n })\r\n\r\n // timeout is needed here as adding a classname on parent element of a button where we are listening on a click is not working properly if done synchrnousely\r\n setTimeout(() => {\r\n // 103 is the destance between pane bottom and zoom-controls top\r\n // zoomer bottom (8 px) + zoomer height (20px) - 13px + zoom controls height (75px) = 90px\r\n const isInArea = model.height - 90 <= area.cursorY && paneHeight > 210\r\n\r\n if (\r\n isInArea &&\r\n !zoomControls.classList.contains(ZOOM_CONTROLS_IS_IN_AREA_CLASS) &&\r\n !chartModel.getIsDisabled()\r\n ) {\r\n zoomControls.classList.add(ZOOM_CONTROLS_IS_IN_AREA_CLASS)\r\n } else if (!isInArea && zoomControls.classList.contains(ZOOM_CONTROLS_IS_IN_AREA_CLASS)) {\r\n zoomControls.classList.remove(ZOOM_CONTROLS_IS_IN_AREA_CLASS)\r\n }\r\n\r\n if (!area.mouseDown && !model.selection && isInArea && !chartModel.getIsDisabled()) {\r\n if (!zoomControls.classList.contains(ZOOM_CONTROLS_ACTIVE_CLASS)) {\r\n zoomControls.classList.add(ZOOM_CONTROLS_ACTIVE_CLASS)\r\n }\r\n } else if (zoomControls.classList.contains(ZOOM_CONTROLS_ACTIVE_CLASS)) {\r\n zoomControls.classList.remove(ZOOM_CONTROLS_ACTIVE_CLASS)\r\n }\r\n })\r\n }\r\n }\r\n\r\n onMouseLeave = () => {\r\n this.mouseDown = false\r\n }\r\n\r\n onTouchStart = (e: React.TouchEvent) => {\r\n if (!this.props.touchEventsDisabled && e.targetTouches.length === 1) {\r\n const touchEvent = e.targetTouches[0]\r\n if (this.chartLayoutModel.scrollable) {\r\n this.onCanvasInteractionStart(touchEvent)\r\n } else if (this.chartLayoutModel.isTouchCrossActive) {\r\n this.lastClientX = touchEvent.clientX\r\n this.lastClientY = touchEvent.clientY\r\n if (!MouseModel.pane()?.eql(this.props.model)) {\r\n const area = this.getArea(touchEvent, {\r\n mouseDown: this.mouseDown,\r\n clientX: touchEvent.clientX,\r\n clientY: touchEvent.clientY,\r\n })\r\n this.setMousePosition(this.getMousePositionInBoundaries(area))\r\n this.isDisableTouchCrossAvailable = false\r\n }\r\n } else {\r\n const area = this.getArea(touchEvent, { isTouch: true }) // passing isTouch is pretty confusing, it's used in Tools.jsx -> onMouseDown method\r\n const element = this.getElement(area)\r\n if (element?.getIsChartEvent?.() && this.props.activeTool === DrawingTool.Mouse) {\r\n const chartEventElement = element as ChartEvent\r\n chartEventElement.toggleIsOpen()\r\n }\r\n }\r\n this.onPaneMouseMove(touchEvent, true)\r\n }\r\n }\r\n\r\n onTouchMove = (e: TouchEvent) => {\r\n if (!this.props.touchEventsDisabled) {\r\n if (!this.getIsHammerAllowScrollActive()) {\r\n e.preventDefault()\r\n }\r\n if (!this.props.touchEventsDisabled && e.targetTouches.length === 1) {\r\n this.onCanvasInteractionMove(e.targetTouches[0])\r\n }\r\n }\r\n }\r\n\r\n onTouchEnd = (e: React.TouchEvent) => {\r\n if (!this.props.touchEventsDisabled && this.chartLayoutModel.scrollable) {\r\n this.onCanvasInteractionEnd(e)\r\n }\r\n }\r\n\r\n onCanvasPress = (e: React.MouseEvent) => {\r\n if (this.chartLayoutModel.scrollable) {\r\n this.chartLayoutModel.updateAttribute('scrollable', false)\r\n document.removeEventListener('touchmove', this.onMouseMoveOnScrolling)\r\n }\r\n if (!this.chartLayoutModel.isTouchCrossActive) {\r\n this.chartLayoutModel.updateAttribute('isTouchCrossActive', true)\r\n this.onCanvasInteractionMove(e)\r\n }\r\n }\r\n\r\n onCanvasInteractionStart = (e: React.Touch | React.MouseEvent) => {\r\n const { activeTool, activeChartInteraction, chartModel, model } = this.props\r\n const isTouch = typeof Touch !== 'undefined' && e instanceof Touch\r\n this.lastActiveTool = activeTool\r\n\r\n if (isPrimaryClick(e) && !activeChartInteraction && !chartModel.getIsDisabled()) {\r\n const area = this.getArea(e, { isTouch }) // passing isTouch is pretty confusing, it's used in Tools.jsx -> onMouseDown method\r\n const element = this.getElement(area)\r\n\r\n // if user click outside of drawable area but still inside canvas creator would hang unfinised,\r\n // it that case we want to cancel element creation, same as we do on click outside of canvas / onBlur\r\n if (model.selection?.isCreator && !area.isCursorInChartWidthBoundaries && element !== model.selection) {\r\n model.getAllElements().forEach((element) => {\r\n if (element.instance.getIsCreator?.() && !element.instance.getIsCreatorDialogOpen?.()) {\r\n element.destroyCascade()\r\n }\r\n })\r\n }\r\n if (this.chartLayoutModel.scrollable) {\r\n setElementCursor({ elementId: this.chartLayoutModel.getHTMLElementId(), cursor: 'grabbing' })\r\n if (model.scaleRange) {\r\n this.currentViewRange = model.getChartOrIndicatorElement()?.instance?.getMinMax?.() ?? null\r\n }\r\n document.addEventListener(isTouch ? 'touchmove' : 'mousemove', this.onMouseMoveOnScrolling)\r\n document.addEventListener(isTouch ? 'touchend' : 'mouseup', this.onCanvasInteractionEnd)\r\n }\r\n if (element?.getIsChartEvent?.() && activeTool === DrawingTool.Mouse) {\r\n this.setSelectedElement(null)\r\n const chartEventElement = element as ChartEvent\r\n chartEventElement.toggleIsOpen()\r\n } else if (\r\n activeTool === DrawingTool.Mouse ||\r\n model.getAllElements().some(({ instance }) => instance.isCreator)\r\n ) {\r\n element?.trigger('mousedown', area)\r\n this.setSelectedElement(element)\r\n }\r\n model.trigger('mousedown', model, area, element)\r\n this.mouseDown = true\r\n this.lastX = area.x\r\n this.lastY = area.y\r\n }\r\n\r\n this.lastClientX = e.clientX\r\n this.lastClientY = e.clientY\r\n }\r\n\r\n onCanvasInteractionMove = (e: React.MouseEvent | React.Touch) => {\r\n const area = this.getArea(e, {\r\n mouseDown: this.mouseDown,\r\n clientX: e.clientX,\r\n clientY: e.clientY,\r\n })\r\n if (!area.isCursorInChartWidthBoundaries) {\r\n MouseModel.updateAttributes({\r\n position: null,\r\n pane: null,\r\n })\r\n return\r\n }\r\n\r\n const { model } = this.props\r\n const hoveredElement = this.getElement(area)\r\n const element = model.selection || hoveredElement\r\n\r\n if (!(this.isMobile && !this.chartLayoutModel.isTouchCrossActive)) {\r\n this.isDisableTouchCrossAvailable = true\r\n this.setMousePosition(\r\n this.lastClientX && this.lastClientY && this.chartLayoutModel.isTouchCrossActive && MouseModel.position\r\n ? this.getMousePositionInBoundaries({\r\n x: MouseModel.position.x + (model.scale.x.invert(area.clientX) - model.scale.x.invert(this.lastClientX)),\r\n y: MouseModel.position.y + (model.scale.y.invert(area.clientY) - model.scale.y.invert(this.lastClientY)),\r\n })\r\n : { x: area.x, y: area.y }\r\n )\r\n }\r\n\r\n if (!this.chartLayoutModel.scrollable) {\r\n this.lastClientX = area.clientX\r\n this.lastClientY = area.clientY\r\n }\r\n\r\n element?.trigger('mousemove', area)\r\n if (\r\n this.mouseDown &&\r\n model.selection instanceof CanvasElement &&\r\n !model.selection.activeThumb &&\r\n !this.chartLayoutModel.activeChartEvent\r\n ) {\r\n if (!model.selection.getIsCreator?.()) {\r\n model.selection.moveBy(area.x - this.lastX, area.y - this.lastY)\r\n }\r\n this.lastX = area.x\r\n this.lastY = area.y\r\n this.renderAll()\r\n }\r\n const isElementHovered =\r\n this.props.activeTool === DrawingTool.Mouse &&\r\n ((element && element === hoveredElement) || hoveredElement instanceof CanvasElement)\r\n\r\n if (hoveredElement !== this.hoveredElement && this.hoveredElement instanceof CanvasElement) {\r\n this.hoveredElement.setIsHovered(false)\r\n this.hoveredElement = null\r\n }\r\n\r\n if (isElementHovered && hoveredElement instanceof CanvasElement) {\r\n if (!hoveredElement.isHovered && !hoveredElement.isSelected) {\r\n hoveredElement.setIsHovered(true)\r\n this.hoveredElement = hoveredElement\r\n }\r\n }\r\n\r\n if (isElementHovered !== this.isElementHovered && this.canvas && hoveredElement?.type !== IndicatorType.Cot) {\r\n this.canvas.className = isElementHovered ? 'hover' : ''\r\n if (this.chartLayoutModel.cross && this.crossCanvas) {\r\n this.crossCanvas.className = `second${isElementHovered ? ' hover' : ''}`\r\n }\r\n this.isElementHovered = isElementHovered\r\n }\r\n }\r\n\r\n onCanvasInteractionEnd = (event: TouchEvent | MouseEvent | React.TouchEvent) => {\r\n if (MouseModel.position) {\r\n setElementCursor({ elementId: this.chartLayoutModel.getHTMLElementId(), cursor: 'crosshair' })\r\n } else {\r\n setElementCursor({ elementId: this.chartLayoutModel.getHTMLElementId(), cursor: 'default' })\r\n }\r\n const isTouch = typeof TouchEvent !== 'undefined' && event instanceof TouchEvent\r\n this.mouseDown = false\r\n const area = this.getArea(event)\r\n const element = this.props.model.selection || this.getElement(area)\r\n element?.trigger('mouseup', area)\r\n document.removeEventListener(isTouch ? 'touchmove' : 'mousemove', this.onMouseMoveOnScrolling)\r\n document.removeEventListener(isTouch ? 'touchend' : 'mouseup', this.onCanvasInteractionEnd)\r\n }\r\n\r\n getMousePositionInBoundaries = ({ x, y }: { x: number; y: number }) => {\r\n const { model } = this.props\r\n const Settings = getSettings(model)\r\n const canvasAreaRectangle = this.canvas!.getBoundingClientRect()\r\n const chartLeft = model.scale.x.invert(-model.chart().leftOffset + 1)\r\n const chartRight = model.scale.x.invert(\r\n canvasAreaRectangle.width - Settings.right.width - Settings.left.width - model.chart().leftOffset - 1\r\n )\r\n const chartTop = model.scale.y.invert(0)\r\n const chartBottom = model.scale.y.invert(canvasAreaRectangle.height - Settings.bottom.height - Settings.top.height)\r\n\r\n return {\r\n x: getValueInRange({\r\n value: x,\r\n min: chartLeft,\r\n max: chartRight,\r\n }),\r\n y: getValueInRange({\r\n value: y,\r\n min: chartBottom,\r\n max: chartTop,\r\n }),\r\n }\r\n }\r\n\r\n setMousePosition = ({ x, y }: { x: number; y: number }) => {\r\n const isSameMouseModel = !!MouseModel.pane()?.eql(this.props.model)\r\n MouseModel.updateAttributes({\r\n position: { x, y },\r\n ...(isSameMouseModel ? {} : { pane: this.props.model }),\r\n })\r\n }\r\n\r\n setSelection = (selection: IndicatorElement | CanvasElement | null) => {\r\n if (selection instanceof CanvasElement) {\r\n selection?.setIsSelected(true)\r\n }\r\n\r\n this.props.model.updateAttribute('selection', selection)\r\n }\r\n\r\n setSelectedElement = (element: IndicatorElement | CanvasElement | null) => {\r\n const { selection } = this.props.model\r\n const isSelectionCanvas = selection instanceof CanvasElement\r\n if (element !== selection || (isSelectionCanvas && element && !selection?.isSelected)) {\r\n if (isSelectionCanvas) {\r\n selection?.setIsSelected(false)\r\n }\r\n if (isSelectionCanvas && selection?.isCreator) {\r\n this.setSelection(null)\r\n } else {\r\n this.setSelection(element)\r\n }\r\n }\r\n }\r\n\r\n getElement = (area: PaneArea) => {\r\n const chartEvents = this.props.model.getAllChartEvents(false)\r\n\r\n for (let i = chartEvents.length - 1; i >= 0; i--) {\r\n const el = chartEvents[i].instance\r\n if (el.getIsInChartView(this.props.chartModel) && el.isInArea(area)) {\r\n return el\r\n }\r\n }\r\n\r\n const elements = this.props.model.getAllElements()\r\n\r\n for (let i = elements.length - 1; i >= 0; i--) {\r\n const el = elements[i].instance\r\n if (el.getIsInChartView(this.props.chartModel) && el.isInArea(area)) {\r\n return el\r\n }\r\n }\r\n return null\r\n }\r\n\r\n getCanvasDOMNode = () =>\r\n // This is used in app/modals/publish/publish.jsx\r\n this.canvasRef.current\r\n}\r\n\r\nexport default withNotificationContext(withElementStyleDialogState(withPaneModel(Pane)))\r\n","import React from 'react'\r\n\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport PaneModel from '../../models/pane'\r\n\r\nexport function withPaneModel

(Component: React.ComponentType

) {\r\n return function WrappedComponent(props: P) {\r\n const model = useModelState(props.model, { watchProperties: ['selection'] })\r\n\r\n return \r\n }\r\n}\r\n","import { Spinner } from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport React from 'react'\r\n\r\nexport function ChartSpinnerOverlay({ shouldDisplay, className }: { shouldDisplay: boolean; className: string }) {\r\n const [isVisible, setIsVisible] = React.useState(shouldDisplay)\r\n React.useEffect(() => {\r\n let timeout: number\r\n if (!shouldDisplay) {\r\n timeout = window.setTimeout(() => {\r\n setIsVisible(false)\r\n }, 400)\r\n }\r\n return () => {\r\n clearTimeout(timeout)\r\n }\r\n }, [shouldDisplay])\r\n\r\n return (\r\n <>\r\n {isVisible && (\r\n \r\n \r\n \r\n )}\r\n \r\n )\r\n}\r\n","import React from 'react'\r\n\r\nimport { RootChartConfigObjectChart } from '../../../types/shared'\r\nimport ChartModel from '../../models/chart'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { DrawingTool } from '../toolbar/interfaces'\r\n\r\nexport const CHART_CLASS_NAMES = 'chart flex-1 relative'\r\nexport const DEFAULT_WRAPPER_COMPONENT = 'div'\r\n\r\nexport interface ChartProps {\r\n chartIndex: number\r\n gridArea?: string\r\n WrapperComp?: React.RefForwardingComponent\r\n config: RootChartConfigObjectChart\r\n chartModel: ChartModel\r\n layoutModel: ChartLayout\r\n setActiveChartInteraction: (interaction: string | null) => void\r\n activeChartInteraction: string | null\r\n activeTool: DrawingTool\r\n touchEventsDisabled: boolean\r\n hasOutline?: boolean\r\n shouldResize?: boolean\r\n renderChartToolbar?: () => React.ReactNode\r\n}\r\n","import classnames from 'classnames'\r\nimport React from 'react'\r\n\r\nimport { Instrument } from '../../../types/shared'\r\nimport { ChartEditorEnum, SpecificChartFunctionality } from '../../constants/common'\r\nimport math from '../../helpers/math'\r\nimport ChartModel from '../../models/chart'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport MouseModel from '../../models/mouse'\r\nimport PaneModel from '../../models/pane'\r\nimport Quote from '../../models/quote'\r\nimport { QuoteFetchType } from '../../models/quote/constants'\r\nimport utils, { isRedesignEnabled } from '../../utils'\r\nimport { getBarWidthWithMargin, getZoomFactorForBarsToDisplay } from '../../utils/chart'\r\nimport { ChartControls } from '../chart-controls'\r\nimport Pane from '../pane'\r\nimport {\r\n getBarIndex,\r\n getIsSmallIndexChart,\r\n getLeftOffset,\r\n getMinMaxLeftOffset,\r\n updateZoomAndLeftOffsetByDateRange,\r\n} from '../renderUtils'\r\nimport { ChartProps } from './constants'\r\nimport { withChartInit } from './with-chart-init'\r\nimport { withWatchedPanesOnChartModel } from './with-watched-panes-on-chart-model'\r\n\r\nfunction preventDefaultFunc(event: Event) {\r\n event.preventDefault()\r\n}\r\n\r\nfunction getZoomFactor({\r\n chartLayout,\r\n currentZoomFactor,\r\n diff,\r\n minBarWidthInPx = 1,\r\n maxBarWidthInPx = 66,\r\n}: {\r\n chartLayout: ChartLayout\r\n currentZoomFactor: number\r\n diff: number\r\n minBarWidthInPx?: number\r\n maxBarWidthInPx?: number\r\n}) {\r\n const minZoomFactor = getZoomFactorForBarsToDisplay({\r\n chartLayout,\r\n chartVisibleWidth: minBarWidthInPx,\r\n numOfVisibleBars: 1,\r\n })\r\n const maxZoomFactor = getZoomFactorForBarsToDisplay({\r\n chartLayout,\r\n chartVisibleWidth: maxBarWidthInPx,\r\n numOfVisibleBars: 1,\r\n })\r\n const isNegativeDirection = diff < 0\r\n const newZoomFactor = currentZoomFactor + diff\r\n const newZoomFactorInRange = Math.min(Math.max(minZoomFactor, newZoomFactor), maxZoomFactor)\r\n\r\n if (newZoomFactor > newZoomFactorInRange && currentZoomFactor > newZoomFactorInRange) {\r\n return isNegativeDirection ? newZoomFactor : currentZoomFactor\r\n }\r\n\r\n if (newZoomFactor < newZoomFactorInRange && currentZoomFactor < newZoomFactorInRange) {\r\n return !isNegativeDirection ? newZoomFactor : currentZoomFactor\r\n }\r\n\r\n return newZoomFactorInRange\r\n}\r\n\r\ninterface ChartState {\r\n panesWrapperElement: HTMLDivElement | null\r\n}\r\n\r\nclass Chart extends React.Component {\r\n lastWidth: number\r\n mouseWheelTimeout?: number\r\n setStateWithPanesTimeout?: number\r\n lastHeight = 0\r\n lastY: number | null = null\r\n lastX: number | null = null\r\n resizerPaneIndex = -1\r\n minimalPaneHeight = 0\r\n zoomerRightAlign: {\r\n barIndex?: number\r\n index: number\r\n offsetDiff: number\r\n } | null = null\r\n\r\n // expects model, config, layoutModel\r\n constructor(props: ChartProps) {\r\n super(props)\r\n\r\n this.lastWidth = props.chartModel.width\r\n this.props.layoutModel.bind('change', this.onLayoutModelChange)\r\n this.state = { panesWrapperElement: null }\r\n }\r\n\r\n componentDidMount() {\r\n const { chartModel } = this.props\r\n this.lastWidth = this.props.layoutModel.width\r\n\r\n chartModel.trigger('change', chartModel)\r\n chartModel.bind('createPane', this.onPaneCreate)\r\n\r\n this.calculateMinimalPaneHeight()\r\n this.handleQuoteChange(chartModel.quote()!)\r\n this.onModelChange()\r\n\r\n chartModel.bind('update', this.onModelChange)\r\n chartModel.bind('destroy', () => {\r\n Quote.unbind('olderData', this.onOlderDataLoaded)\r\n Quote.unbind(`${QuoteFetchType.Refetch} ${QuoteFetchType.NewerData}`, this.onDataLoaded)\r\n })\r\n\r\n Quote.bind('olderData', this.onOlderDataLoaded)\r\n Quote.bind(`${QuoteFetchType.Refetch} ${QuoteFetchType.NewerData}`, this.onDataLoaded)\r\n }\r\n\r\n componentDidUpdate(prevProps: Readonly, prevState: Readonly) {\r\n if (\r\n prevState.panesWrapperElement !== this.state.panesWrapperElement ||\r\n prevProps.layoutModel.isWheelZoomEnabled !== this.props.layoutModel.isWheelZoomEnabled\r\n ) {\r\n prevState.panesWrapperElement?.removeEventListener('wheel', preventDefaultFunc)\r\n\r\n if (this.props.layoutModel.isWheelZoomEnabled) {\r\n // can't use onWheel as it has passive: true\r\n this.state.panesWrapperElement?.addEventListener('wheel', preventDefaultFunc, { passive: false })\r\n }\r\n }\r\n }\r\n\r\n componentWillUnmount() {\r\n const { chartModel, layoutModel } = this.props\r\n if (this.setStateWithPanesTimeout) {\r\n clearTimeout(this.setStateWithPanesTimeout)\r\n }\r\n layoutModel.unbind('change', this.onLayoutModelChange)\r\n chartModel.unbind('update', this.onModelChange)\r\n\r\n this.state.panesWrapperElement?.removeEventListener('wheel', preventDefaultFunc)\r\n }\r\n\r\n handleSetPanesWrapperRef = (panesWrapperElement: HTMLDivElement | null) => {\r\n this.setState({ panesWrapperElement })\r\n }\r\n\r\n render() {\r\n const { activeTool, chartIndex, layoutModel, chartModel, renderChartToolbar } = this.props\r\n const isChartPage = layoutModel.specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n const panes =\r\n layoutModel.specificChartFunctionality === SpecificChartFunctionality.futuresPage\r\n ? chartModel.getAllValidPanes()\r\n : chartModel.getAllPanes()\r\n const showSettings = layoutModel.editors.includes(ChartEditorEnum.settings)\r\n\r\n return (\r\n <>\r\n this.onClick(undefined) : undefined}\r\n data-testid={`chart-${chartIndex}-settings`}\r\n onMouseEnter={this.resetMouseModel}\r\n >\r\n {showSettings && }\r\n \r\n {layoutModel.editable && showSettings && renderChartToolbar && (\r\n \r\n {renderChartToolbar()}\r\n \r\n )}\r\n \r\n {panes.map((pane, index) => (\r\n \r\n ))}\r\n \r\n \r\n )\r\n }\r\n\r\n onMouseWheel = (e: React.WheelEvent) => {\r\n const { chartModel, layoutModel } = this.props\r\n const isLoading = chartModel.panes().count() < 1\r\n if (!layoutModel.isWheelZoomEnabled || isLoading) {\r\n return\r\n }\r\n if (!this.zoomerRightAlign) {\r\n this.calcZoomerRightAlign()\r\n }\r\n clearTimeout(this.mouseWheelTimeout)\r\n this.mouseWheelTimeout = window.setTimeout(() => {\r\n this.zoomerRightAlign = null\r\n }, 250)\r\n this.onZoomerMouseMove(e, undefined, true)\r\n }\r\n\r\n onClick = (activePane: PaneModel | undefined) => {\r\n if (\r\n !this.props.layoutModel.activeChart.eql(this.props.chartModel) ||\r\n !(this.props.layoutModel.activePane?.eql(activePane) || this.props.layoutModel.activePane === activePane)\r\n ) {\r\n this.props.layoutModel.updateAttributes({ activeChart: this.props.chartModel, activePane })\r\n }\r\n }\r\n\r\n onPaneCreate = () => {\r\n const { chartModel } = this.props\r\n this.onModelChange()\r\n this.calculateMinimalPaneHeight()\r\n chartModel.trigger('change', chartModel)\r\n }\r\n\r\n onPaneDestroy = (paneId: string) => {\r\n const { chartModel } = this.props\r\n const pane = chartModel.panes().find(paneId)\r\n\r\n if (pane) {\r\n pane.destroyCascade()\r\n this.onModelChange()\r\n chartModel.trigger('change', chartModel)\r\n }\r\n }\r\n\r\n onModelChange = (chartModelParam?: ChartModel) => {\r\n const { chartModel, config } = this.props\r\n const panes = chartModel.getAllPanes()\r\n const quote = chartModel.quote()\r\n\r\n if (panes.length === 0 || !quote || chartModel.leftOffset === undefined) {\r\n return\r\n }\r\n\r\n const { width, height } = chartModel\r\n let panesHeight = panes.reduce((sum, pane) => sum + (pane.height ?? 0), 0)\r\n if (panesHeight !== height) {\r\n panesHeight = panes.reduce((sum, pane) => {\r\n const newPaneHeight = Math.round((pane.height / panesHeight) * height)\r\n if (!Number.isNaN(newPaneHeight)) {\r\n pane.updateAttribute('height', newPaneHeight)\r\n }\r\n return sum + newPaneHeight\r\n }, 0)\r\n const chartPane = chartModel.getChartPane()\r\n if (chartPane && panesHeight !== height) {\r\n const newChartPaneHeight = chartPane.height + height - panesHeight\r\n if (!Number.isNaN(newChartPaneHeight)) {\r\n chartPane.updateAttribute('height', newChartPaneHeight)\r\n }\r\n }\r\n }\r\n\r\n const newLeftOffset = getLeftOffset({\r\n quote,\r\n chartModel,\r\n config: config,\r\n })\r\n const newIsScrolled = chartModel.leftOffset !== newLeftOffset\r\n const isScrolled = chartModel.isScrolled\r\n if (!isScrolled && this.lastWidth !== width) {\r\n this.lastWidth = width\r\n chartModel.updateAttribute('leftOffset', newLeftOffset)\r\n } else if (isScrolled !== newIsScrolled) {\r\n chartModel.updateAttributes({ isScrolled: newIsScrolled })\r\n }\r\n\r\n if (this.lastHeight !== height) {\r\n this.lastHeight = height\r\n this.calculateMinimalPaneHeight()\r\n }\r\n\r\n if (chartModelParam) {\r\n this.handleQuoteChange(chartModelParam.quote())\r\n }\r\n }\r\n\r\n onLayoutModelChange = ({ activeChart, activePane }: { activeChart: ChartModel; activePane: PaneModel }) => {\r\n const { chartModel } = this.props\r\n if (!activeChart) {\r\n return\r\n }\r\n for (const pane of chartModel.getAllPanes()) {\r\n if (activePane?.id !== pane.id && pane.selection?.isSelected === true) {\r\n pane.selection.setIsSelected(false)\r\n pane.updateAttribute('selection', undefined)\r\n }\r\n }\r\n }\r\n\r\n onResizerMouseDown = (e: React.MouseEvent | MouseEvent, model: PaneModel) => {\r\n if (e.button !== 0) {\r\n return\r\n }\r\n this.lastY = e.clientY\r\n this.resizerPaneIndex = this.props.chartModel\r\n .panes()\r\n .all()\r\n .findIndex((pane) => pane.eql(model))\r\n document.addEventListener('mousemove', this.onResizerMouseMove)\r\n document.addEventListener('mouseup', this.onResizerMouseUp)\r\n }\r\n\r\n onResizerMouseMove = (e: MouseEvent) => {\r\n if (this.resizerPaneIndex > 0 && this.lastY !== null && this.resizePanesAccordingly(this.lastY! - e.clientY)) {\r\n this.lastY = e.clientY\r\n }\r\n }\r\n\r\n onResizerMouseUp = (e: MouseEvent) => {\r\n const { chartModel } = this.props\r\n if (this.resizerPaneIndex > 0 && this.lastY !== null) {\r\n this.resizePanesAccordingly(this.lastY - e.clientY)\r\n this.lastY = null\r\n\r\n chartModel.trigger('change', chartModel)\r\n }\r\n\r\n document.removeEventListener('mousemove', this.onResizerMouseMove)\r\n document.removeEventListener('mouseup', this.onResizerMouseUp)\r\n }\r\n\r\n calculateMinimalPaneHeight() {\r\n const { chartModel } = this.props\r\n const { minHeight, total } = chartModel\r\n .panes()\r\n .all()\r\n .reduce(\r\n ({ minHeight, total }, pane) => {\r\n if (minHeight > pane.height) {\r\n minHeight = pane.height\r\n }\r\n total += pane.getIsChartPane() ? 3 : 1\r\n return { minHeight, total }\r\n },\r\n { minHeight: chartModel.height, total: 0 }\r\n )\r\n const optiMinHeight = Math.floor(chartModel.height / total)\r\n this.minimalPaneHeight = Math.min(minHeight, optiMinHeight)\r\n }\r\n\r\n resizePanesAccordingly(difY: number) {\r\n const { chartModel } = this.props\r\n const panes = chartModel.panes().all()\r\n let basePane = this.resizerPaneIndex\r\n if (!difY) {\r\n return true\r\n } else if (difY > 0) {\r\n let i = basePane\r\n let pane = panes[i]\r\n if (pane.height + difY >= this.minimalPaneHeight) {\r\n pane.updateAttribute('height', pane.height + difY)\r\n } else {\r\n pane.updateAttribute('height', this.minimalPaneHeight)\r\n }\r\n for (--i; i >= 0; i--) {\r\n pane = panes[i]\r\n if (pane.height - difY >= this.minimalPaneHeight) {\r\n pane.updateAttribute('height', pane.height - difY)\r\n break\r\n } else {\r\n pane.updateAttribute('height', this.minimalPaneHeight)\r\n }\r\n }\r\n } else if (difY < 0) {\r\n basePane = Math.max(0, basePane - 1)\r\n let i = basePane\r\n let pane = panes[i]\r\n if (pane.height - difY >= this.minimalPaneHeight) {\r\n pane.updateAttribute('height', pane.height - difY)\r\n } else {\r\n pane.updateAttribute('height', this.minimalPaneHeight)\r\n }\r\n for (++i; i < panes.length; i++) {\r\n pane = panes[i]\r\n if (pane.height + difY >= this.minimalPaneHeight) {\r\n pane.updateAttribute('height', pane.height + difY)\r\n break\r\n } else {\r\n pane.updateAttribute('height', this.minimalPaneHeight)\r\n }\r\n }\r\n }\r\n\r\n const panesHeight = panes.reduce((sum, pane) => sum + pane.height, 0)\r\n if (panesHeight !== chartModel.height) {\r\n difY = chartModel.height - panesHeight\r\n\r\n const pane = panes[basePane]\r\n pane.updateAttribute('height', pane.height + difY)\r\n\r\n // if we exceeded total height we need to stop updating lastY - return false\r\n return false\r\n }\r\n\r\n return true\r\n }\r\n\r\n onZoomerTouchStart = (e: React.TouchEvent | TouchEvent) => {\r\n if (!this.props.layoutModel.scrollable || e.touches.length !== 1 || this.props.touchEventsDisabled) {\r\n return\r\n }\r\n this.onZoomerMouseDown(e.targetTouches[0])\r\n }\r\n\r\n onZoomerTouchMove = (e: TouchEvent) => {\r\n if (!this.props.layoutModel.scrollable || e.touches.length !== 1) {\r\n return\r\n }\r\n this.onZoomerMouseMove(e.targetTouches[0])\r\n }\r\n\r\n onZoomerTouchEnd = () => {\r\n if (!this.props.layoutModel.scrollable) {\r\n return\r\n }\r\n this.onZoomerMouseUp()\r\n }\r\n\r\n getRawDistance = (e: Pick) => {\r\n const p1 = { x: e.touches[0].clientX, y: e.touches[0].clientY }\r\n const p2 = { x: e.touches[1].clientX, y: e.touches[1].clientY }\r\n return math.distance(p1, p2)\r\n }\r\n\r\n onPinchStart = (e: React.TouchEvent) => {\r\n const { chartModel } = this.props\r\n const { activeChartInteraction, setActiveChartInteraction, touchEventsDisabled } = this.props\r\n const isLoading = chartModel.panes().count() < 1\r\n\r\n if (\r\n this.props.layoutModel.scrollable &&\r\n e.touches.length === 2 &&\r\n !activeChartInteraction &&\r\n !isLoading &&\r\n !touchEventsDisabled\r\n ) {\r\n setActiveChartInteraction('pinch')\r\n this.onZoomerMouseDown({ clientX: this.getRawDistance(e as unknown as TouchEvent) })\r\n\r\n document.addEventListener('touchmove', this.onPinchMove)\r\n document.addEventListener('touchend', this.onPinchEnd)\r\n }\r\n }\r\n\r\n onPinchMove = (e: TouchEvent) => {\r\n if (e.touches.length === 2) {\r\n this.onZoomerMouseMove({ clientX: this.getRawDistance(e) })\r\n }\r\n }\r\n\r\n onPinchEnd = (e: TouchEvent) => {\r\n if (e.touches.length === 1) {\r\n this.onZoomerMouseUp()\r\n document.removeEventListener('touchmove', this.onPinchMove)\r\n document.removeEventListener('touchend', this.onPinchEnd)\r\n }\r\n }\r\n\r\n calcZoomerRightAlign = () => {\r\n const { chartModel } = this.props\r\n const { ChartSettings } = chartModel.getChartLayoutSettings()\r\n const quote = chartModel.quote()\r\n const fx = chartModel.panes().first().scale.x\r\n const barWidth = getBarWidthWithMargin({ zoomFactor: chartModel.zoomFactor, chartLayout: this.props.layoutModel })\r\n const currentLeftOffset = getLeftOffset({ quote, chartModel, config: this.props.config, barWidth })\r\n this.zoomerRightAlign = null\r\n\r\n if (quote.isIntraday && quote.instrument === Instrument.Stock) {\r\n const barIndex = quote.getBarIndex(quote.close.length - 1)\r\n let offsetDiff =\r\n chartModel.leftOffset -\r\n getLeftOffset({\r\n quote,\r\n chartModel: chartModel,\r\n config: this.props.config,\r\n barWidth,\r\n barIndex,\r\n shouldAlignDaysToLeftApplied: false,\r\n })\r\n const offsetBars = ~~(offsetDiff / barWidth)\r\n offsetDiff -= offsetBars * barWidth\r\n this.zoomerRightAlign = {\r\n barIndex,\r\n index: barIndex - offsetBars,\r\n offsetDiff,\r\n }\r\n } else if (chartModel.leftOffset <= currentLeftOffset) {\r\n this.zoomerRightAlign = {\r\n index: quote.getBarIndex(quote.open.length - 1),\r\n offsetDiff: chartModel.leftOffset - currentLeftOffset,\r\n }\r\n } else {\r\n const offset = chartModel.leftOffset\r\n for (let i = 0; i < quote.open.length; i += 1) {\r\n const x = fx(i)\r\n if (x + offset < 0) {\r\n continue\r\n }\r\n if (x + offset > chartModel.width - ChartSettings.left.width - ChartSettings.right.width) {\r\n const barIndex = quote.getBarIndex(i - 1)\r\n let offsetDiff =\r\n offset -\r\n getLeftOffset({\r\n quote,\r\n chartModel,\r\n config: this.props.config,\r\n barWidth,\r\n barIndex,\r\n })\r\n const offsetBars = ~~(offsetDiff / barWidth)\r\n offsetDiff -= offsetBars * barWidth\r\n this.zoomerRightAlign = {\r\n barIndex,\r\n index: barIndex - offsetBars,\r\n offsetDiff,\r\n }\r\n break\r\n }\r\n }\r\n }\r\n }\r\n\r\n onZoomerMouseDown = (e: Partial) => {\r\n if ((e.button !== 0 && 'button' in e) || !this.props.layoutModel.scrollable) {\r\n return\r\n }\r\n switch (this.props.activeChartInteraction) {\r\n case 'pinch':\r\n break\r\n case null:\r\n this.props.setActiveChartInteraction('zoomer')\r\n break\r\n default:\r\n return\r\n }\r\n\r\n this.lastX = e.clientX ?? null\r\n this.calcZoomerRightAlign()\r\n\r\n document.addEventListener('mousemove', this.onZoomerMouseMove)\r\n document.addEventListener('mouseup', this.onZoomerMouseUp)\r\n document.addEventListener('touchmove', this.onZoomerTouchMove)\r\n document.addEventListener('touchend', this.onZoomerTouchEnd)\r\n }\r\n\r\n normalizeWheelDeltaY = (e: WheelEvent) => {\r\n // because wheel deltaY on mouse and touchpad is quite different we need to normalize it\r\n const abs = Math.abs(e.deltaY)\r\n if (abs === 0) return 0\r\n return Math.log(abs) * Math.sign(e.deltaY) * 10\r\n }\r\n\r\n onZoomerMouseMove = (\r\n e: React.WheelEvent | MouseEvent | Touch | { clientX: number },\r\n _?: unknown,\r\n isMouseWheel = false\r\n ) => {\r\n const { chartModel, layoutModel } = this.props\r\n let difX\r\n if (!layoutModel.scrollable) return\r\n if (!isMouseWheel && this.lastX !== null) {\r\n difX = (this.lastX - e.clientX) / chartModel.width\r\n this.lastX = e.clientX\r\n } else {\r\n // standard difX calculation result is around 0.00x, wheel deltaY is whole px\r\n // because of that we divide px with 1000\r\n difX = this.normalizeWheelDeltaY(e as WheelEvent) / 1000\r\n }\r\n\r\n this.addToZoomFactor({ diff: -difX })\r\n }\r\n\r\n addToZoomFactor = ({\r\n diff,\r\n shouldCalculateRightAlign = false,\r\n }: {\r\n diff: number\r\n shouldCalculateRightAlign?: boolean\r\n }) => {\r\n const { chartModel, layoutModel } = this.props\r\n if (shouldCalculateRightAlign) {\r\n this.calcZoomerRightAlign()\r\n }\r\n // 6 is default bar width with margin on charts page, so to get the similar feeling when zooming we're multiplying the zoom factor by the coefficient\r\n const diffCoefficient = chartModel.zoomFactor * (6 / getBarWidthWithMargin({ chartLayout: this.props.layoutModel }))\r\n const zoomFactor = getZoomFactor({\r\n chartLayout: layoutModel,\r\n currentZoomFactor: chartModel.zoomFactor,\r\n diff: diff * diffCoefficient,\r\n })\r\n const barWidth = getBarWidthWithMargin({\r\n zoomFactor,\r\n chartLayout: this.props.layoutModel,\r\n })\r\n\r\n let leftOffset\r\n if (this.props.config.stretch) {\r\n leftOffset = 0\r\n } else if (getIsSmallIndexChart(this.props.layoutModel.specificChartFunctionality)) {\r\n leftOffset = barWidth\r\n } else if (this.zoomerRightAlign) {\r\n leftOffset = getMinMaxLeftOffset({\r\n newLeftOffset:\r\n getLeftOffset({\r\n quote: chartModel.quote(),\r\n chartModel: chartModel,\r\n config: this.props.config,\r\n barWidth,\r\n barIndex: this.zoomerRightAlign.index,\r\n shouldAlignDaysToLeftApplied: false,\r\n }) + this.zoomerRightAlign.offsetDiff,\r\n chartModel: chartModel,\r\n barWidth,\r\n barIndex: getBarIndex(chartModel.quote()),\r\n })\r\n } else {\r\n return\r\n }\r\n chartModel.updateAttributes({\r\n zoomFactor,\r\n leftOffset,\r\n dateRange: null,\r\n })\r\n if (shouldCalculateRightAlign) {\r\n this.zoomerRightAlign = null\r\n }\r\n }\r\n\r\n onZoomerMouseUp = () => {\r\n this.zoomerRightAlign = null\r\n document.removeEventListener('mousemove', this.onZoomerMouseMove)\r\n document.removeEventListener('mouseup', this.onZoomerMouseUp)\r\n document.removeEventListener('touchmove', this.onZoomerTouchMove)\r\n document.removeEventListener('touchend', this.onZoomerTouchEnd)\r\n this.props.setActiveChartInteraction(null)\r\n }\r\n\r\n onZoomerReset = () => {\r\n const { chartModel, layoutModel } = this.props\r\n const zoomFactor = chartModel.chart_layout().defaultZoomFactor\r\n const barWidth = getBarWidthWithMargin({ zoomFactor, chartLayout: layoutModel })\r\n const leftOffset = getLeftOffset({\r\n quote: chartModel.quote(),\r\n chartModel,\r\n config: this.props.config,\r\n barWidth,\r\n })\r\n\r\n chartModel.updateAttributes({\r\n zoomFactor,\r\n leftOffset,\r\n dateRange: null,\r\n })\r\n }\r\n\r\n onOlderDataLoaded = () => {\r\n throw new Error('onOlderDataLoaded not implemented')\r\n // TODO implement similarly to onDataLoaded\r\n }\r\n\r\n resetMouseModel = () => {\r\n const isLoading = this.props.chartModel.panes().count() < 1\r\n if (!isLoading) {\r\n MouseModel.updateAttributes({\r\n position: null,\r\n pane: null,\r\n })\r\n }\r\n }\r\n\r\n handleQuoteChange = (quote: Quote) => {\r\n const { chartModel } = this.props\r\n\r\n // Update only date range chart\r\n if (chartModel.dateRange) {\r\n if (!quote.eql(chartModel.quote()) || chartModel.timeframe !== quote.timeframe || quote.date.length === 0) {\r\n return\r\n }\r\n updateZoomAndLeftOffsetByDateRange({ chartModel, quote })\r\n }\r\n }\r\n\r\n onDataLoaded = (newQuote: Quote, fetchType: QuoteFetchType) => {\r\n const { chartModel } = this.props\r\n const quote = chartModel.quote()\r\n if (!quote?.eql(newQuote)) {\r\n return\r\n }\r\n\r\n const shouldForceLeftOffsetUpdate = fetchType === QuoteFetchType.Refetch\r\n let newLeftOffset = chartModel.leftOffset // TODO find proper fix. If this line is removed (if we don't trigger leftOffset update), the chart stops being updated for the user until they move chart around.\r\n if (\r\n (this.props.layoutModel.scrollable === false && !this.props.layoutModel.isTouchCrossActive) ||\r\n !chartModel.isScrolled ||\r\n shouldForceLeftOffsetUpdate\r\n ) {\r\n newLeftOffset = getLeftOffset({\r\n quote,\r\n chartModel: chartModel,\r\n config: this.props.config,\r\n })\r\n }\r\n\r\n chartModel.setChartEvents(quote.chartEvents, !quote.events)\r\n\r\n if (newLeftOffset !== chartModel.leftOffset) {\r\n chartModel.getAllElements().forEach((element) => {\r\n if (element.isDrawing() && !element.isMouseDown()) {\r\n element.instance.updateScales()\r\n }\r\n })\r\n }\r\n\r\n chartModel.updateAttribute('leftOffset', newLeftOffset)\r\n\r\n this.handleQuoteChange(quote)\r\n }\r\n}\r\n\r\nexport default withChartInit(withWatchedPanesOnChartModel(Chart))\r\n","import classNames from 'classnames'\r\nimport merge from 'lodash.merge'\r\nimport React from 'react'\r\n\r\nimport { ObjectHash } from '../../../types/shared'\r\nimport { SpecificChartFunctionality } from '../../constants/common'\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport Quote from '../../models/quote'\r\nimport { getChartsDimensions, isRedesignEnabled } from '../../utils'\r\nimport { prefetchPerfIndicatorAllQuotes } from '../../utils/chart'\r\nimport { getLeftOffset } from '../renderUtils'\r\nimport { ChartSpinnerOverlay } from './chart-spinner-overlay'\r\nimport { CHART_CLASS_NAMES, ChartProps, DEFAULT_WRAPPER_COMPONENT } from './constants'\r\n\r\nexport function withChartInit(Component: React.ComponentType) {\r\n return function WrappedComponent(props: ChartProps) {\r\n const { WrapperComp = DEFAULT_WRAPPER_COMPONENT, gridArea } = props\r\n const isModelDestroyedRef = React.useRef(false)\r\n const model = useModelState(props.chartModel, { watchProperties: ['panes', 'quote'] })\r\n const layoutModel = useModelState(props.layoutModel, { watchProperties: ['activeChart'] })\r\n const quote = model.quote()\r\n\r\n const initChartRef = React.useRef(async () => {\r\n const { chartModel, config } = props\r\n const { premarket, hasChartEvents, aftermarket, ticker, instrument, timeframe, panes: panesConfig } = config\r\n\r\n const options = {\r\n premarket,\r\n aftermarket,\r\n events: hasChartEvents,\r\n patterns: panesConfig.some(\r\n (pane) =>\r\n pane.elements?.some(\r\n (element) => element.overlays?.some((overlay: ObjectHash) => overlay.type === 'overlays/patterns')\r\n )\r\n ),\r\n }\r\n\r\n const quote = await Quote.get({\r\n ticker,\r\n instrument,\r\n timeframe,\r\n options,\r\n })\r\n const panesWithPerfIndicator = panesConfig.filter(({ elements }) =>\r\n elements.some(({ type }) => type === 'indicators/perf')\r\n )\r\n\r\n if (panesWithPerfIndicator) {\r\n await Promise.allSettled(\r\n panesWithPerfIndicator.map((paneWithPerfIndicator) =>\r\n prefetchPerfIndicatorAllQuotes({ paneWithPerfIndicator, timeframe, options })\r\n )\r\n )\r\n }\r\n\r\n if (isModelDestroyedRef.current) {\r\n return\r\n }\r\n\r\n config.panes.forEach((pane) => {\r\n const paneProperties = merge({}, pane)\r\n paneProperties.chart = chartModel\r\n chartModel.createPaneCascade(paneProperties)\r\n })\r\n\r\n chartModel.updateAttributes({\r\n quote,\r\n premarket: options.premarket,\r\n aftermarket: options.aftermarket,\r\n })\r\n\r\n chartModel.setChartEvents(quote.chartEvents, true)\r\n\r\n if (props.shouldResize) {\r\n const chartsDimensions = getChartsDimensions(props.layoutModel.getHTMLElementId())\r\n props.layoutModel.updateAttributes(chartsDimensions)\r\n }\r\n\r\n if (chartModel.leftOffset == null) {\r\n const leftOffset = getLeftOffset({ quote, chartModel: chartModel, config: props.config })\r\n chartModel.updateAttribute('leftOffset', leftOffset)\r\n }\r\n })\r\n\r\n React.useEffect(() => {\r\n const handleModelBeforeDestroy = () => {\r\n isModelDestroyedRef.current = true\r\n }\r\n\r\n model.bind('beforeDestroy', handleModelBeforeDestroy)\r\n initChartRef.current()\r\n return () => {\r\n model.unbind('beforeDestroy', handleModelBeforeDestroy)\r\n }\r\n // We want to run it only on mount\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [])\r\n\r\n const isQuotePage = props.layoutModel.specificChartFunctionality === SpecificChartFunctionality.quotePage\r\n const isChartPage = props.layoutModel.specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n const isFuturesForexCryptoPage = [\r\n SpecificChartFunctionality.futuresPage,\r\n SpecificChartFunctionality.forexPage,\r\n SpecificChartFunctionality.cryptoPage,\r\n ].includes(props.layoutModel.specificChartFunctionality)\r\n const isModelReady =\r\n quote && ((quote.fetchedAt === undefined && quote.close.length > 0) || quote.fetchedAt > 0 || quote)\r\n const loadingStyle =\r\n !isModelReady && isQuotePage\r\n ? // 2px is border\r\n { width: model.width ? model.width + 2 : '100%', height: model.height + 2 }\r\n : undefined\r\n\r\n return (\r\n \r\n {isChartPage && (\r\n \r\n )}\r\n {isModelReady && }\r\n \r\n )\r\n }\r\n}\r\n","import React from 'react'\r\n\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport ChartModel from '../../models/chart'\r\n\r\nexport function withWatchedPanesOnChartModel

(Component: React.ComponentType

) {\r\n return function WrappedComponent(props: P) {\r\n const model = useModelState(props.chartModel, { watchProperties: ['panes'] })\r\n\r\n return \r\n }\r\n}\r\n","export const drawingCreatorsAsyncModule = {\r\n importFn: () => import(/* webpackChunkName: \"drawing-creators\" */ './module-entry'),\r\n cacheKey: 'drawing-creators',\r\n}\r\n","import { DrawingActions, IToolbarDrawingAction, IToolbarDrawingActionItem } from './interfaces'\r\n\r\nexport const drawingActions: Record = {\r\n [DrawingActions.AddNote]: {\r\n id: DrawingActions.AddNote,\r\n title: 'Add note',\r\n icon: 'note',\r\n },\r\n [DrawingActions.DeleteDrawings]: {\r\n id: DrawingActions.DeleteDrawings,\r\n title: 'Remove all drawings',\r\n icon: 'drawingActionDelete',\r\n },\r\n [DrawingActions.DeleteAutoSavedDrawings]: {\r\n id: DrawingActions.DeleteAutoSavedDrawings,\r\n title: 'Remove all autosaved drawings',\r\n icon: 'drawingActionDelete',\r\n },\r\n}\r\n\r\nexport const getToolbarDrawingActions = ({\r\n isAutoSaveActive,\r\n isAddNoteAvailable = false,\r\n isIdea,\r\n}: {\r\n isAutoSaveActive: boolean\r\n isAddNoteAvailable?: boolean\r\n isIdea?: boolean\r\n}): Array => [\r\n ...(isAddNoteAvailable\r\n ? [\r\n {\r\n defaultItem: drawingActions[DrawingActions.AddNote],\r\n isDisabled: isIdea,\r\n disabledTooltip: 'Add note is not available in ideas',\r\n },\r\n ]\r\n : []),\r\n {\r\n defaultItem:\r\n drawingActions[isAutoSaveActive ? DrawingActions.DeleteAutoSavedDrawings : DrawingActions.DeleteDrawings],\r\n },\r\n]\r\n","import { DrawingSetting, IToolbarDrawingSetting, IToolbarDrawingsSettingItem } from './interfaces'\r\n\r\nconst drawingSettings: Record = {\r\n [DrawingSetting.PreserveDrawings]: {\r\n id: DrawingSetting.PreserveDrawings,\r\n icon: 'drawingSettingPreserveDrawings',\r\n iconActive: 'drawingSettingPreserveDrawingsActive',\r\n title: 'Preserve drawings: Off',\r\n titleActive: 'Preserve drawings: On',\r\n },\r\n [DrawingSetting.DrawingModeContinuous]: {\r\n id: DrawingSetting.DrawingModeContinuous,\r\n icon: 'drawingSettingDrawingMode',\r\n iconActive: 'drawingSettingDrawingModeActive',\r\n title: 'Drawing mode: Single',\r\n titleActive: 'Drawing mode: Continuous',\r\n },\r\n [DrawingSetting.HideDrawings]: {\r\n id: DrawingSetting.HideDrawings,\r\n icon: 'drawingSettingHide',\r\n iconActive: 'drawingSettingShow',\r\n title: 'Hide drawings',\r\n titleActive: 'Show drawings',\r\n },\r\n [DrawingSetting.LockDrawings]: {\r\n id: DrawingSetting.LockDrawings,\r\n icon: 'drawingSettingLock',\r\n iconActive: 'drawingSettingUnlock',\r\n title: 'Lock drawings',\r\n titleActive: 'Unlock drawings',\r\n },\r\n}\r\n\r\nconst preserveDrawingsAutosaveOverride: IToolbarDrawingSetting = {\r\n id: DrawingSetting.PreserveDrawings, // DrawingSetting.PreserveDrawings so it works with current settings sync to DB\r\n icon: 'drawingSettingAutosaveOff',\r\n iconActive: 'drawingSettingAutosaveOn',\r\n iconAction: 'drawingSettingAutosaveSaving',\r\n title: 'Drawings autosave: Off',\r\n titleActive: 'Drawings Autosave: On',\r\n titleAction: 'Drawings Autosave: Saving',\r\n}\r\n\r\nexport const getToolbarDrawingSettings = ({\r\n isPreserveDrawingsAndAutosaveAvailable,\r\n isIdea,\r\n isAutoSaveInProgress,\r\n}: {\r\n isPreserveDrawingsAndAutosaveAvailable?: boolean\r\n isIdea?: boolean\r\n isAutoSaveInProgress?: boolean\r\n}): Array => {\r\n const toolbarSettings = [\r\n {\r\n defaultItem: drawingSettings[DrawingSetting.DrawingModeContinuous],\r\n },\r\n ...(isPreserveDrawingsAndAutosaveAvailable\r\n ? [\r\n {\r\n defaultItem: preserveDrawingsAutosaveOverride,\r\n isDisabled: isIdea,\r\n isInAction: isAutoSaveInProgress,\r\n disabledTooltip: 'Autosave is not available in ideas',\r\n },\r\n ]\r\n : []),\r\n {\r\n defaultItem: drawingSettings[DrawingSetting.HideDrawings],\r\n },\r\n {\r\n defaultItem: drawingSettings[DrawingSetting.LockDrawings],\r\n },\r\n ]\r\n\r\n return toolbarSettings\r\n}\r\n","import { DrawingTool, IToolbarDrawingTool, IToolbarDrawingToolItem } from './interfaces'\r\n\r\nexport const drawingTools: Record = {\r\n [DrawingTool.Mouse]: {\r\n id: DrawingTool.Mouse,\r\n title: 'Mouse',\r\n icon: 'toolMouse',\r\n },\r\n [DrawingTool.Measure]: {\r\n id: DrawingTool.Measure,\r\n title: 'Measure',\r\n icon: 'toolMeasure',\r\n },\r\n [DrawingTool.ScaledLine]: {\r\n id: DrawingTool.ScaledLine,\r\n title: 'Line',\r\n icon: 'toolLine',\r\n },\r\n [DrawingTool.Arrow]: {\r\n id: DrawingTool.Arrow,\r\n title: 'Arrow',\r\n icon: 'toolArrow',\r\n },\r\n [DrawingTool.VerticalLine]: {\r\n id: DrawingTool.VerticalLine,\r\n title: 'Vertical line',\r\n icon: 'toolMidLineV',\r\n },\r\n [DrawingTool.HorizontalLine]: {\r\n id: DrawingTool.HorizontalLine,\r\n title: 'Horizontal line',\r\n icon: 'toolMidLineH',\r\n },\r\n [DrawingTool.Rectangle]: {\r\n id: DrawingTool.Rectangle,\r\n title: 'Rectangle',\r\n icon: 'toolRect',\r\n },\r\n [DrawingTool.RotatedRectangle]: {\r\n id: DrawingTool.RotatedRectangle,\r\n title: 'Rotated rectangle',\r\n icon: 'toolRectRotated',\r\n },\r\n [DrawingTool.Triangle]: {\r\n id: DrawingTool.Triangle,\r\n title: 'Triangle',\r\n icon: 'toolTriangle',\r\n },\r\n [DrawingTool.Ellipse]: {\r\n id: DrawingTool.Ellipse,\r\n title: 'Ellipse',\r\n icon: 'toolEllipse',\r\n },\r\n [DrawingTool.Curve]: {\r\n id: DrawingTool.Curve,\r\n title: 'Curve',\r\n icon: 'toolCurve',\r\n },\r\n [DrawingTool.Pitchfork]: {\r\n id: DrawingTool.Pitchfork,\r\n title: 'Pitchfork',\r\n icon: 'toolPitchfork',\r\n },\r\n [DrawingTool.Polygon]: {\r\n id: DrawingTool.Polygon,\r\n title: 'Polygon',\r\n icon: 'toolPolygon',\r\n },\r\n [DrawingTool.Xabcd]: {\r\n id: DrawingTool.Xabcd,\r\n title: 'XABCD',\r\n icon: 'toolXABCD',\r\n },\r\n [DrawingTool.ScaledText]: {\r\n id: DrawingTool.ScaledText,\r\n title: 'Text',\r\n icon: 'toolText',\r\n },\r\n [DrawingTool.Brush]: {\r\n id: DrawingTool.Brush,\r\n title: 'Brush',\r\n icon: 'toolBrush',\r\n },\r\n [DrawingTool.ElliottWaves]: {\r\n id: DrawingTool.ElliottWaves,\r\n title: 'Elliott waves',\r\n icon: 'toolElliottWave',\r\n },\r\n [DrawingTool.FibonacciRetracements]: {\r\n id: DrawingTool.FibonacciRetracements,\r\n title: 'Fibonacci retracements',\r\n icon: 'toolFibonacci',\r\n },\r\n [DrawingTool.Position]: {\r\n id: DrawingTool.Position,\r\n title: 'Position',\r\n icon: 'toolPosition',\r\n },\r\n [DrawingTool.Callout]: {\r\n id: DrawingTool.Callout,\r\n title: 'Callout',\r\n icon: 'toolCallout',\r\n },\r\n}\r\n\r\nexport const toolbarDrawingTools: Array = [\r\n {\r\n defaultItem: drawingTools[DrawingTool.Mouse],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.Measure],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.ScaledLine],\r\n toolGroup: [\r\n drawingTools[DrawingTool.ScaledLine],\r\n drawingTools[DrawingTool.VerticalLine],\r\n drawingTools[DrawingTool.HorizontalLine],\r\n drawingTools[DrawingTool.Curve],\r\n ],\r\n toolGroupTitle: 'Line tools',\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.Arrow],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.Rectangle],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.RotatedRectangle],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.Triangle],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.Ellipse],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.Polygon],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.Xabcd],\r\n toolGroup: [drawingTools[DrawingTool.Xabcd], drawingTools[DrawingTool.Pitchfork]],\r\n toolGroupTitle: 'XABCD tools',\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.ScaledText],\r\n toolGroup: [drawingTools[DrawingTool.ScaledText], drawingTools[DrawingTool.Callout]],\r\n toolGroupTitle: 'Text tools',\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.Brush],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.ElliottWaves],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.FibonacciRetracements],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.Position],\r\n },\r\n]\r\n","import { Toolbar as ToolbarComponent, ToolbarDivider, ToolbarGroupProps, ToolbarItem } from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport React from 'react'\r\n\r\nimport { PaneArea } from '../../../types/shared'\r\nimport { SpecificChartFunctionality } from '../../constants/common'\r\nimport { drawingCreatorsAsyncModule } from '../../creators/async-modules'\r\nimport { ElementStyleDialogContext } from '../../modals/element_style'\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport { AutoSaveState } from '../../models/constants'\r\nimport PaneModel from '../../models/pane'\r\nimport { useAsyncModule } from '../../utils/async-modules-utils'\r\nimport { getIsPreserveDrawingsAndAutosaveAvailable } from '../../utils/chart'\r\nimport { getToolbarDrawingActions } from './drawingActions'\r\nimport { getToolbarDrawingSettings } from './drawingSettings'\r\nimport { drawingTools, toolbarDrawingTools } from './drawingTools'\r\nimport { DrawingSetting, DrawingTool, IToolBarProps } from './interfaces'\r\n\r\nexport const DISABLED_ITEM_TOOLTIP_LABEL = \"Disabled due 'lock/hide' drawings active\"\r\n\r\nexport default function Toolbar({\r\n isSidebar,\r\n isHorizontal,\r\n isMobileOverlay,\r\n activeTool,\r\n chartLayoutModel,\r\n onActiveToolChange,\r\n onDrawingActionClick,\r\n onDrawingSettingClick,\r\n onDrawingEnd,\r\n drawingSettings,\r\n isAlternativeTheme,\r\n areToolsDisabled,\r\n}: IToolBarProps) {\r\n const [drawingCreatorsModule, { isLoading: isDrawingCreatorsModuleLoading }] = useAsyncModule({\r\n ...drawingCreatorsAsyncModule,\r\n shouldLoadModule: true,\r\n })\r\n const { autoSaveState } = useModelState(\r\n React.useMemo(() => chartLayoutModel.drawingsInternalStore(), [chartLayoutModel]),\r\n { watchProperties: ['autoSaveState'] }\r\n )\r\n const [isDrawing, setIsDrawing] = React.useState(false)\r\n const openElementStyleDialog = React.useContext(ElementStyleDialogContext)\r\n\r\n const availableDrawingSettings = getToolbarDrawingSettings({\r\n isPreserveDrawingsAndAutosaveAvailable: getIsPreserveDrawingsAndAutosaveAvailable(chartLayoutModel),\r\n isAutoSaveInProgress: autoSaveState === AutoSaveState.Saving,\r\n isIdea: !!chartLayoutModel.idea?.id,\r\n })\r\n\r\n const availableDrawingActions = getToolbarDrawingActions({\r\n isAutoSaveActive: autoSaveState !== AutoSaveState.Off,\r\n isAddNoteAvailable: chartLayoutModel.specificChartFunctionality === SpecificChartFunctionality.chartPage,\r\n isIdea: !!chartLayoutModel.idea?.id,\r\n })\r\n\r\n React.useEffect(() => {\r\n if (!drawingCreatorsModule) {\r\n return\r\n }\r\n\r\n const onMouseDown = (model: PaneModel, area: PaneArea & { isTouch: boolean }) => {\r\n const isDrawingModeContinuous = drawingSettings[DrawingSetting.DrawingModeContinuous]\r\n const hasData = model.chart().quote().close.length > 0\r\n const hasHiddenDrawings = drawingSettings[DrawingSetting.HideDrawings]\r\n const tool = drawingTools[activeTool].id\r\n\r\n if (tool === DrawingTool.Mouse || isDrawing || hasHiddenDrawings || !hasData) {\r\n return\r\n }\r\n\r\n setIsDrawing(true)\r\n const { drawingToolsTouchCreatorsByType, drawingToolsCreatorsByType } = drawingCreatorsModule\r\n const ToolClass = area.isTouch ? drawingToolsTouchCreatorsByType[tool] : drawingToolsCreatorsByType[tool]\r\n const element = model.elements().create({\r\n instance: new ToolClass(area, {}, model, openElementStyleDialog, () => {\r\n if (!isDrawingModeContinuous) {\r\n onActiveToolChange(DrawingTool.Mouse)\r\n }\r\n setIsDrawing(false)\r\n onDrawingEnd?.()\r\n }),\r\n })\r\n element.one('destroy', ({ instance }) => {\r\n if (instance.getIsCreator()) {\r\n setIsDrawing(false)\r\n onDrawingEnd?.()\r\n }\r\n })\r\n\r\n element.trigger('select', element)\r\n }\r\n PaneModel.bind('mousedown', onMouseDown)\r\n return () => {\r\n PaneModel.unbind('mousedown', onMouseDown)\r\n }\r\n }, [\r\n activeTool,\r\n onActiveToolChange,\r\n openElementStyleDialog,\r\n onDrawingEnd,\r\n drawingCreatorsModule,\r\n drawingSettings,\r\n isDrawing,\r\n ])\r\n\r\n return (\r\n \r\n {toolbarDrawingTools.map((item) => {\r\n const isActive = activeTool === item.defaultItem.id || item.toolGroup?.some((tool) => tool.id === activeTool)\r\n const isToolLoading = isDrawingCreatorsModuleLoading && isActive\r\n\r\n return (\r\n \r\n )\r\n })}\r\n \r\n {availableDrawingSettings.map((item) => (\r\n \r\n ))}\r\n {availableDrawingActions.map((item) => (\r\n \r\n ))}\r\n \r\n )\r\n}\r\n","import Toolbar from './toolbar'\r\n\r\nexport default Toolbar\r\n","import { Textarea } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport { ObjectHash } from '../../../../types/shared'\r\nimport { useModelState } from '../../../model-hooks/use-model-state'\r\nimport Chart from '../../../models/chart'\r\nimport ChartLayout from '../../../models/chart_layout'\r\nimport { useDrawingAutoSaveControls } from '../../autosave/use-drawing-auto-save-controls'\r\nimport { getElementNoteText, getTickersAndContainerTypesInLayoutModel } from '../../autosave/utils'\r\n\r\ninterface ChartAutoSaveNoteProps {\r\n ticker: string\r\n note: string\r\n onNoteChange: (note: string, ticker: string) => void\r\n}\r\n\r\nfunction ChartAutoSaveNote({ ticker, note, onNoteChange }: ChartAutoSaveNoteProps) {\r\n return (\r\n ) => {\r\n onNoteChange(e.target.value, ticker)\r\n }}\r\n />\r\n )\r\n}\r\n\r\ninterface Props {\r\n chartLayoutModel: ChartLayout\r\n}\r\n\r\nexport function ChartAutoSaveNotes({ chartLayoutModel }: Props) {\r\n const { handleAutoSaveNoteChange } = useDrawingAutoSaveControls(chartLayoutModel)\r\n const [tickers, setTickers] = React.useState([])\r\n const unwatchedInternalStore = React.useMemo(() => chartLayoutModel.drawingsInternalStore(), [chartLayoutModel])\r\n const drawingsInternalStore = useModelState(unwatchedInternalStore, { watchProperties: ['elements'] })\r\n\r\n React.useEffect(() => {\r\n // There was no better way how to listen on ticker changes which is necessary for displaying correct text areas\r\n const handleChartChange = () => {\r\n const { tickers } = getTickersAndContainerTypesInLayoutModel(chartLayoutModel)\r\n setTickers(tickers)\r\n }\r\n\r\n Chart.bind('change', handleChartChange)\r\n handleChartChange()\r\n return () => {\r\n Chart.unbind('change', handleChartChange)\r\n }\r\n }, [chartLayoutModel])\r\n\r\n const tickerNoteMap = React.useMemo(() => {\r\n const map: ObjectHash = {}\r\n drawingsInternalStore.elements.forEach((element) => {\r\n if (element.containerType === 'note' && tickers.includes(element.ticker)) {\r\n map[element.ticker] = getElementNoteText(element)\r\n }\r\n })\r\n\r\n return map\r\n }, [drawingsInternalStore.elements, tickers])\r\n\r\n return (\r\n

\r\n {tickers.map((ticker) => (\r\n \r\n ))}\r\n
\r\n )\r\n}\r\n","import { Dialog, DialogBody, DialogHeader, DialogStateReturn } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport ChartLayout from '../../../models/chart_layout'\r\nimport { ChartAutoSaveNotes } from './auto-save-notes'\r\n\r\ninterface INoteDialog {\r\n state: DialogStateReturn\r\n chartLayoutModel: ChartLayout\r\n}\r\n\r\nexport function AutoSaveNotesDialog({ state, chartLayoutModel }: INoteDialog) {\r\n const isOpen = state.useState('open')\r\n const isAnimating = state.useState('animating')\r\n const isFullyClosed = !isOpen && !isAnimating\r\n\r\n return (\r\n \r\n Notes\r\n {!isFullyClosed && }\r\n \r\n )\r\n}\r\n","import {\r\n Button,\r\n ConfirmationDialog as ConfirmationDialogComponent,\r\n DialogDismiss,\r\n DialogStateReturn,\r\n} from '@finviz/website'\r\nimport React from 'react'\r\n\r\nconst getDialogContent = ({\r\n isAutosaveDialogContent,\r\n tickers,\r\n}: {\r\n isAutosaveDialogContent: boolean\r\n tickers: string[]\r\n}) => {\r\n if (isAutosaveDialogContent) {\r\n return {\r\n title: 'Remove all autosaved drawings?',\r\n message: (\r\n <>\r\n Do you really want to remove all autosaved drawings? This action is irreversible and will remove all\r\n non-idea drawings for {tickers.join(', ')}.\r\n \r\n ),\r\n }\r\n }\r\n return {\r\n title: 'Remove all drawings?',\r\n message: `Do you really want to remove all drawings? This action only affects the current page and visible tickers. This action doesn't remove autosaved drawings or ideas.`,\r\n }\r\n}\r\n\r\nexport interface IConfirmationDialog {\r\n state: DialogStateReturn\r\n onAction: () => void\r\n onCancel?: () => void\r\n isAutosaveDialogContent: boolean\r\n tickers: string[]\r\n}\r\n\r\nexport function ConfirmationDialog({\r\n state,\r\n onAction,\r\n onCancel,\r\n isAutosaveDialogContent = false,\r\n tickers,\r\n}: IConfirmationDialog) {\r\n const dialogContent = getDialogContent({ isAutosaveDialogContent, tickers })\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n }\r\n >\r\n {dialogContent.message}\r\n \r\n )\r\n}\r\n","import { Button, Icon } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport { drawingTools } from '../drawingTools'\r\nimport { DrawingTool } from '../interfaces'\r\n\r\ntype ToolButtonProps = {\r\n onClick: () => void\r\n activeTool: DrawingTool\r\n}\r\n\r\nexport default function ToolButton({ activeTool, onClick }: ToolButtonProps) {\r\n return (\r\n \r\n )\r\n}\r\n","import { Button } from '@finviz/website'\r\nimport classNames from 'classnames'\r\nimport React from 'react'\r\nimport ReactDOM from 'react-dom'\r\nimport { useSearchParams } from 'react-router-dom'\r\n\r\nimport { SIDEBAR_QUERY_PARAM } from '../../sidebar/sidebar'\r\nimport { MOBILE_TOOLBAR_DIV_ID } from '../../sidebar/sidebar-tabs'\r\nimport { DrawingActions, DrawingTool, IToolBarProps } from '../interfaces'\r\nimport Toolbar from '../toolbar'\r\nimport ToolButton from './tool-button'\r\n\r\ntype ToolbarMobileProps = Omit\r\n\r\nexport default function ToolbarMobile({\r\n activeTool,\r\n onActiveToolChange,\r\n onDrawingActionClick,\r\n ...rest\r\n}: ToolbarMobileProps) {\r\n const [isToolbarVisible, setIsToolbarVisible] = React.useState(false)\r\n const [urlSearchParams, setUrlSearchParams] = useSearchParams()\r\n const [toolbarMobileElement, setToolbarMobileElement] = React.useState(null)\r\n\r\n // get toolbar mobile element on first render\r\n React.useEffect(() => {\r\n setToolbarMobileElement(document.getElementById(MOBILE_TOOLBAR_DIV_ID))\r\n }, [])\r\n\r\n const handleActiveToolChange = React.useCallback(\r\n (drawingTool: DrawingTool, trigger?: 'button' | 'select' | 'group') => {\r\n onActiveToolChange(drawingTool, trigger)\r\n\r\n if (trigger !== 'group') return setIsToolbarVisible(false)\r\n },\r\n [onActiveToolChange]\r\n )\r\n\r\n // Hide toolbar on click outside\r\n const wrapperRef = React.useRef(null)\r\n React.useEffect(() => {\r\n if (!isToolbarVisible) return\r\n\r\n function handleClickOutside(event: TouchEvent | MouseEvent) {\r\n // Get the currently open select\r\n const openSelect = document.querySelector('.finviz-popover[data-enter]')\r\n if (wrapperRef.current?.contains(event.target as Node) || openSelect?.contains(event.target as Node)) return\r\n setIsToolbarVisible(false)\r\n }\r\n\r\n document.addEventListener('mousedown', handleClickOutside)\r\n document.addEventListener('touchstart', handleClickOutside)\r\n\r\n return () => {\r\n document.removeEventListener('mousedown', handleClickOutside)\r\n document.removeEventListener('touchstart', handleClickOutside)\r\n }\r\n }, [isToolbarVisible])\r\n\r\n const handleDrawingActionClick = (actionId: DrawingActions) => {\r\n onDrawingActionClick?.(actionId)\r\n setIsToolbarVisible(false)\r\n }\r\n\r\n if (!toolbarMobileElement) return null\r\n\r\n return ReactDOM.createPortal(\r\n <>\r\n \r\n \r\n \r\n {urlSearchParams.has(SIDEBAR_QUERY_PARAM) || activeTool === DrawingTool.Mouse ? (\r\n {\r\n setIsToolbarVisible(true)\r\n setUrlSearchParams((params) => {\r\n params.delete(SIDEBAR_QUERY_PARAM)\r\n return params\r\n })\r\n }}\r\n >\r\n Draw\r\n \r\n ) : (\r\n {\r\n setIsToolbarVisible(true)\r\n }}\r\n />\r\n )}\r\n ,\r\n toolbarMobileElement\r\n )\r\n}\r\n","import React from 'react'\r\n\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { AutoSaveState } from '../../models/constants'\r\n\r\ninterface LoadLatestDataButtonProps {\r\n chartLayoutModel: ChartLayout\r\n}\r\n\r\nexport function AutoSaveStateIndicator({ chartLayoutModel }: LoadLatestDataButtonProps) {\r\n const drawingsInternalStoreUnwatched = React.useMemo(\r\n () => chartLayoutModel.drawingsInternalStore(),\r\n [chartLayoutModel]\r\n )\r\n const { autoSaveState } = useModelState(drawingsInternalStoreUnwatched, { watchProperties: ['autoSaveState'] })!\r\n const [isVisible, setIsVisible] = React.useState(false)\r\n\r\n React.useEffect(() => {\r\n if (autoSaveState === AutoSaveState.Off) {\r\n return\r\n }\r\n\r\n let setVisibilityTimeout: number | null = null\r\n const newIsVisible = autoSaveState !== AutoSaveState.Saved\r\n\r\n setVisibilityTimeout = window.setTimeout(\r\n () => {\r\n setIsVisible(newIsVisible)\r\n },\r\n newIsVisible ? 0 : 3000\r\n )\r\n\r\n const checkIfNeededPreventLeaving = (event: BeforeUnloadEvent) => {\r\n if (autoSaveState === AutoSaveState.Saved) {\r\n return undefined\r\n }\r\n\r\n const message = `Your latest changes haven't been saved yet. If you leave now, your changes might be lost.`\r\n event.returnValue = message\r\n return message\r\n }\r\n\r\n window.addEventListener('beforeunload', checkIfNeededPreventLeaving)\r\n\r\n return () => {\r\n window.removeEventListener('beforeunload', checkIfNeededPreventLeaving)\r\n if (setVisibilityTimeout) {\r\n clearTimeout(setVisibilityTimeout)\r\n }\r\n }\r\n }, [autoSaveState])\r\n\r\n if (!isVisible) {\r\n return null\r\n }\r\n\r\n // @todo - add proper indicator component here\r\n return null\r\n}\r\n","import { Textarea } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { isRedesignEnabled } from '../../utils'\r\nimport { useDrawingAutoSaveControls } from '../autosave/use-drawing-auto-save-controls'\r\n\r\ninterface Props {\r\n chartLayoutModel: ChartLayout\r\n ideaNoteRef?: React.RefObject\r\n}\r\n\r\nconst hasRedesign = isRedesignEnabled()\r\n\r\nexport function ChartLayoutAutoSaveNote({ chartLayoutModel: chartLayoutModelUnwatched, ideaNoteRef }: Props) {\r\n const chartLayoutModel = useModelState(chartLayoutModelUnwatched, {\r\n watchProperties: ['idea'],\r\n })!\r\n const { handleIdeaNoteChange } = useDrawingAutoSaveControls(chartLayoutModel)\r\n\r\n if (!chartLayoutModel.editable) {\r\n return null\r\n }\r\n\r\n return (\r\n
\r\n {!hasRedesign &&
Note:
}\r\n
\r\n ) => {\r\n handleIdeaNoteChange(e.target.value)\r\n }}\r\n />\r\n
\r\n
\r\n )\r\n}\r\n","import { useDialogState } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport { publishModalAsyncModule } from '../../modals/publish/async-modules'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { useAsyncModule } from '../../utils/async-modules-utils'\r\n\r\ninterface PublishOldButtonClickListenerProps {\r\n isListening: boolean\r\n layoutModel: ChartLayout\r\n}\r\n\r\nexport function getPublishChartHtmlElements() {\r\n const publishChartElements = document.getElementsByClassName('js-publish-chart')\r\n const publishChartHtmlElements = Array.from(publishChartElements) as HTMLElement[]\r\n\r\n return publishChartHtmlElements\r\n}\r\n\r\nfunction getChartImgUrl(index: number) {\r\n const imgElement = document.getElementById(`chart${index}`) as HTMLImageElement | null\r\n return imgElement?.src ?? null\r\n}\r\n\r\nexport function PublishOldButtonClickListener({ isListening, layoutModel }: PublishOldButtonClickListenerProps) {\r\n const dialog = useDialogState()\r\n const isOpen = dialog.useState('open')\r\n const [dialogConfig, setDialogConfig] = React.useState({\r\n isCanvas: true,\r\n chartImgUrl: null as null | string,\r\n timeframe: '',\r\n ticker: '',\r\n })\r\n const [publishModalModule] = useAsyncModule({\r\n ...publishModalAsyncModule,\r\n shouldLoadModule: isOpen,\r\n })\r\n const PublishDialog = publishModalModule?.default\r\n\r\n React.useEffect(() => {\r\n const publishChartHtmlElements = getPublishChartHtmlElements()\r\n const clickHandler = (event: MouseEvent) => {\r\n const { index, ticker, timeframe } = (event.currentTarget as HTMLElement).dataset\r\n if (index && ticker && timeframe) {\r\n const indexInt = Number.parseInt(index)\r\n setDialogConfig({\r\n ticker,\r\n timeframe,\r\n isCanvas: indexInt === 0,\r\n chartImgUrl: indexInt > 0 ? getChartImgUrl(indexInt) : null,\r\n })\r\n dialog.show()\r\n }\r\n }\r\n\r\n if (isListening) {\r\n publishChartHtmlElements.forEach((el) => {\r\n el.addEventListener('click', clickHandler)\r\n })\r\n }\r\n\r\n return () => {\r\n publishChartHtmlElements.forEach((el) => {\r\n el.removeEventListener('click', clickHandler)\r\n })\r\n }\r\n }, [dialog, isListening])\r\n\r\n return PublishDialog ? : null\r\n}\r\n","import {\r\n Button,\r\n Dialog,\r\n DialogBody,\r\n DialogDismiss,\r\n DialogFooter,\r\n DialogHeader,\r\n DialogStateReturn,\r\n Paragraph,\r\n} from '@finviz/website'\r\nimport React from 'react'\r\n\r\nexport enum IdeaDrawingsConfirmationOptions {\r\n Merge,\r\n Override,\r\n Nothing,\r\n Cancel,\r\n}\r\n\r\ninterface IIdeaLeaveDialog {\r\n state: DialogStateReturn\r\n actionCallback: (action: IdeaDrawingsConfirmationOptions) => void\r\n}\r\n\r\nexport function IdeaLeaveDialog({ state, actionCallback }: IIdeaLeaveDialog) {\r\n return (\r\n actionCallback(IdeaDrawingsConfirmationOptions.Cancel)} />}\r\n >\r\n actionCallback(IdeaDrawingsConfirmationOptions.Cancel)}>\r\n You’re About to Leave your Idea\r\n \r\n \r\n
\r\n What would you like to do with the drawings from your current Idea?\r\n \r\n Replace Drawings\r\n
\r\n Your Autosaved Drawings for this ticker will be deleted, and the Idea Drawings will be copied to the live\r\n chart.\r\n
\r\n \r\n Combine Drawings\r\n
\r\n The Idea Drawings will be copied to the live chart without changing the positions or settings of any\r\n Autosaved Drawings. This may cause duplicates if some drawings were also autosaved.\r\n
\r\n \r\n Do Nothing\r\n
\r\n Close the idea without changing any Autosaved Drawings.\r\n
\r\n
\r\n
\r\n \r\n actionCallback(IdeaDrawingsConfirmationOptions.Override)}\r\n >\r\n Replace\r\n \r\n actionCallback(IdeaDrawingsConfirmationOptions.Merge)}\r\n >\r\n Combine\r\n \r\n actionCallback(IdeaDrawingsConfirmationOptions.Nothing)}\r\n >\r\n Do Nothing\r\n \r\n \r\n \r\n )\r\n}\r\n","import { useDialogState, useTrackPageView } from '@finviz/website'\r\nimport * as dateFns from 'date-fns'\r\nimport React from 'react'\r\nimport { useLocation, useNavigate } from 'react-router-dom'\r\n\r\nimport {\r\n ChartElementType,\r\n ChartsOrQuotePageQueryParams,\r\n ChartsPageQueryParams,\r\n QuotePageQueryChartTypes,\r\n QuotePageQueryParams,\r\n SpecificChartFunctionality,\r\n TIMEFRAME,\r\n} from '../../constants/common'\r\nimport Chart from '../../models/chart'\r\nimport ChartLayoutModel from '../../models/chart_layout'\r\nimport { getRawTickerForInstrument } from '../../models/utils'\r\nimport utils from '../../utils'\r\nimport { getInstrument, handleTypeChange } from '../../utils/chart'\r\nimport { getUuid } from '../../utils/helpers'\r\nimport { initHlc } from '../../utils/hlc'\r\nimport { decodeQueryString, encodeQueryString } from '../../utils/query_string'\r\nimport { IdeaLeaveDialog } from '../autosave/idea-leave-dialog'\r\nimport { IdeaDrawingsConfirmationOptions } from '../autosave/idea-leave-dialog'\r\nimport { useDrawingAutoSaveApi } from '../autosave/use-drawing-autosave-api'\r\nimport { getTickersAndContainerTypesInLayoutModel, handleCallMethodOnAllDrawings } from '../autosave/utils'\r\nimport { getChartElementTypeFromResponseType } from '../utils'\r\n\r\nconst getChartElementTypeFromQueryType = (queryType: QuotePageQueryChartTypes | null) => {\r\n switch (queryType) {\r\n case QuotePageQueryChartTypes.l:\r\n return ChartElementType.LineChart\r\n case QuotePageQueryChartTypes.hc:\r\n return ChartElementType.HollowCandleStick\r\n case QuotePageQueryChartTypes.ha:\r\n return ChartElementType.HeikinAshi\r\n case QuotePageQueryChartTypes.o:\r\n return ChartElementType.OhlcChart\r\n case QuotePageQueryChartTypes.p:\r\n return ChartElementType.PerfChart\r\n case QuotePageQueryChartTypes.c:\r\n case QuotePageQueryChartTypes.cs:\r\n return ChartElementType.CandleStick\r\n default:\r\n return (\r\n getChartElementTypeFromResponseType(window.FinvizSettings?.TA?.style ?? null) ?? ChartElementType.CandleStick\r\n )\r\n }\r\n}\r\n\r\nconst useChartRouteChange = (chartLayoutModel: ChartLayoutModel | null) => {\r\n useTrackPageView({ trackInitial: false })\r\n const location = useLocation()\r\n const navigate = useNavigate()\r\n const { deleteAllDrawings } = useDrawingAutoSaveApi()\r\n const dialog = useDialogState()\r\n const isIdeasDialogOpen = dialog.useState('open')\r\n\r\n const isQuotePage = chartLayoutModel?.specificChartFunctionality === SpecificChartFunctionality.quotePage\r\n const isChartPage = chartLayoutModel?.specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n const isFuturesForexCryptoPage = [\r\n SpecificChartFunctionality.futuresPage,\r\n SpecificChartFunctionality.forexPage,\r\n SpecificChartFunctionality.cryptoPage,\r\n ].includes(chartLayoutModel?.specificChartFunctionality as SpecificChartFunctionality)\r\n\r\n React.useEffect(() => {\r\n if (isChartPage) {\r\n utils.setCookie(\r\n 'chartsUrl',\r\n `?${encodeQueryString({ ...decodeQueryString(location.search), i: undefined, settings: undefined })}`,\r\n dateFns.add(new Date(), { months: 1 })\r\n )\r\n }\r\n }, [isChartPage, location.search])\r\n\r\n React.useEffect(() => {\r\n const decodedQueryString = decodeQueryString(location.search)\r\n // We can navigate to idea chart without a refresh e.g. using browser back button\r\n // It breaks charts because we don't have idea data & idea quote anymore\r\n // So if we end up on a page with idea in the url and we don't have any idea data in chartLayout model we'll refresh the page\r\n if (chartLayoutModel && decodedQueryString.i && !chartLayoutModel.idea?.id) {\r\n window.location.reload()\r\n }\r\n // No need to have chartLayoutModel as dependecny here , I'm only interested in idea on the model\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [location.search, chartLayoutModel?.idea?.id])\r\n\r\n const updateChartConfig = React.useCallback(() => {\r\n if (!chartLayoutModel) return\r\n\r\n const decodedSearch = decodeQueryString(location.search)\r\n\r\n const urlType = (decodedSearch as QuotePageQueryParams).ty ?? null\r\n handleTypeChange({\r\n type: getChartElementTypeFromQueryType(urlType),\r\n chartLayoutModel,\r\n })\r\n\r\n if (isChartPage && chartLayoutModel.layout !== (decodedSearch as ChartsPageQueryParams).l) {\r\n chartLayoutModel.updateAttributes({ layout: (decodedSearch as ChartsPageQueryParams).l })\r\n }\r\n\r\n chartLayoutModel.getAllCharts().forEach((chartModel, chartIndex) => {\r\n const urlTicker = decodedSearch.t.split(',')[chartIndex] ?? null\r\n const urlTimeframe = decodedSearch.p?.split(',')[chartIndex] ?? null\r\n const urlDateRange = decodedSearch.r?.split(',')[chartIndex] ?? null\r\n const upperCaseTicker = urlTicker?.toUpperCase()\r\n\r\n /**\r\n * Only Charts page charts can change instruments. Other pages need forced\r\n * instrument because we might not be able to guess it from urlTicker\r\n */\r\n let instrument = getInstrument(upperCaseTicker)\r\n if (chartLayoutModel.specificChartFunctionality !== SpecificChartFunctionality.chartPage) {\r\n instrument = chartModel.instrument\r\n }\r\n\r\n const newChartConfig = {\r\n instrument,\r\n ticker: getRawTickerForInstrument(instrument, upperCaseTicker),\r\n timeframe: urlTimeframe,\r\n dateRange: urlDateRange,\r\n }\r\n\r\n if (Object.entries(newChartConfig).some(([key, value]) => chartModel[key as keyof Chart] !== value)) {\r\n chartModel.updateAttributesAndSync(newChartConfig)\r\n }\r\n })\r\n }, [chartLayoutModel, location.search, isChartPage])\r\n\r\n React.useEffect(() => {\r\n const decodedSearch = decodeQueryString(location.search)\r\n\r\n if (\r\n !chartLayoutModel ||\r\n !decodedSearch.p ||\r\n !decodedSearch.t ||\r\n !(isQuotePage || isChartPage || isFuturesForexCryptoPage)\r\n ) {\r\n if (!decodedSearch.p && isQuotePage) {\r\n navigate(\r\n {\r\n search: `?${encodeQueryString({\r\n ...decodedSearch,\r\n p: window.FinvizSettings.defaultPeriod ?? TIMEFRAME.d,\r\n r: window.FinvizSettings.defaultDateRange,\r\n })}`,\r\n },\r\n {\r\n replace: true,\r\n }\r\n )\r\n }\r\n return\r\n }\r\n if (chartLayoutModel.idea?.id && isIdeasDialogOpen) {\r\n dialog.hide()\r\n }\r\n\r\n if (!decodedSearch.i && chartLayoutModel.idea?.id) {\r\n const urlTicker = decodedSearch.t.split(',')\r\n const isSameTicker = chartLayoutModel\r\n .getAllCharts()\r\n .every((chart, i) => chart.getQuoteRawTicker() === urlTicker[i])\r\n\r\n if (isSameTicker && window.FinvizSettings.hasUserPremium && chartLayoutModel.isPreserveDrawingsActive) {\r\n dialog.show()\r\n return\r\n }\r\n if (!chartLayoutModel.isPreserveDrawingsActive || !isSameTicker) {\r\n handleCallMethodOnAllDrawings({ chartLayoutModel, elementMethod: 'destroyCascade' })\r\n }\r\n chartLayoutModel.exitIdea()\r\n }\r\n updateChartConfig()\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [\r\n location.search,\r\n navigate,\r\n chartLayoutModel,\r\n isQuotePage,\r\n isChartPage,\r\n isFuturesForexCryptoPage,\r\n updateChartConfig,\r\n ])\r\n\r\n const handleIdeaLeave = React.useCallback(\r\n async (action: IdeaDrawingsConfirmationOptions) => {\r\n if (!chartLayoutModel) return\r\n if (action === IdeaDrawingsConfirmationOptions.Cancel) {\r\n navigate(-1)\r\n return\r\n }\r\n switch (action) {\r\n case IdeaDrawingsConfirmationOptions.Merge: {\r\n handleCallMethodOnAllDrawings({\r\n chartLayoutModel,\r\n elementMethod: 'refreshElementId',\r\n })\r\n break\r\n }\r\n case IdeaDrawingsConfirmationOptions.Override: {\r\n const { tickers } = getTickersAndContainerTypesInLayoutModel(chartLayoutModel)\r\n await deleteAllDrawings({ tickers, lastLocalChange: initHlc(getUuid(), Date.now()) })\r\n break\r\n }\r\n case IdeaDrawingsConfirmationOptions.Nothing: {\r\n handleCallMethodOnAllDrawings({\r\n chartLayoutModel,\r\n elementMethod: 'destroyCascade',\r\n })\r\n break\r\n }\r\n default:\r\n break\r\n }\r\n chartLayoutModel.exitIdea()\r\n updateChartConfig()\r\n },\r\n [chartLayoutModel, updateChartConfig, deleteAllDrawings, navigate]\r\n )\r\n\r\n return {\r\n dialog,\r\n handleIdeaLeave,\r\n }\r\n}\r\n\r\nfunction getChartLayoutWithChartRouteChange

(\r\n Component: React.ComponentType

\r\n) {\r\n return function WrappedComponent(props: P) {\r\n const { dialog, handleIdeaLeave } = useChartRouteChange(props.chartLayoutModel)\r\n return (\r\n <>\r\n \r\n \r\n \r\n )\r\n }\r\n}\r\n\r\nexport function withChartRouteChange

(\r\n Component: React.ComponentType

\r\n) {\r\n // Chart layout is used in ReactRouter context and also outside of RR context\r\n // if we use RR hooks outside the context it will crash so this function will return different component for quote & chart pages than for other usecases\r\n const ChartLayoutComponent = getChartLayoutWithChartRouteChange(Component)\r\n return function WrappedComponent(props: P) {\r\n const { ty } = decodeQueryString()\r\n const isChartPage = props.chartLayoutModel.specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n const isQuotePage = props.chartLayoutModel.specificChartFunctionality === SpecificChartFunctionality.quotePage\r\n const isFuturesForexCryptoPage = [\r\n SpecificChartFunctionality.futuresPage,\r\n SpecificChartFunctionality.forexPage,\r\n SpecificChartFunctionality.cryptoPage,\r\n ].includes(props.chartLayoutModel.specificChartFunctionality)\r\n if (isChartPage || (isQuotePage && ty !== 'p') || isFuturesForexCryptoPage) {\r\n return \r\n }\r\n\r\n return \r\n }\r\n}\r\n","import Spine from '@finviz/spine'\r\nimport { ChartGrid, ChartGridCell, DialogStateReturn } from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport flowRight from 'lodash.flowright'\r\nimport merge from 'lodash.merge'\r\nimport throttle from 'lodash.throttle'\r\nimport React from 'react'\r\nimport * as ReactDOM from 'react-dom'\r\n\r\nimport {\r\n ChartConfigObject,\r\n DrawingSpineOptionsEvent,\r\n IIdea,\r\n RootChartConfigObject,\r\n RootChartConfigObjectChart,\r\n} from '../../../types/shared'\r\nimport { ChartEditorEnum, LAYOUTS, LayoutType, SpecificChartFunctionality } from '../../constants/common'\r\nimport ChartModel from '../../models/chart'\r\nimport ChartLayoutModel from '../../models/chart_layout'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { AutoSaveState } from '../../models/constants'\r\nimport ElementModel from '../../models/element'\r\nimport utils, {\r\n getChartsDimensions,\r\n getFullscreenStatus,\r\n getIsMobilePortrait,\r\n isRedesignEnabled,\r\n isRedesignedPage,\r\n} from '../../utils'\r\nimport { getIsPreserveDrawingsAndAutosaveAvailable, getIsSidebarEnabled } from '../../utils/chart'\r\nimport fetchApi from '../../utils/fetch_api'\r\nimport { getTickersAndContainerTypesInLayoutModel } from '../autosave/utils'\r\nimport { withDrawingsAutoSave } from '../autosave/with-auto-save'\r\nimport Chart from '../chart'\r\nimport { SidebarDirection } from '../sidebar/constants'\r\nimport { Sidebar } from '../sidebar/sidebar'\r\nimport Toolbar from '../toolbar'\r\nimport { AutoSaveNotesDialog } from '../toolbar/auto-save-notes'\r\nimport { ConfirmationDialog } from '../toolbar/confirmation_dialog'\r\nimport { DrawingActions, DrawingSetting, DrawingTool } from '../toolbar/interfaces'\r\nimport ToolbarMobile from '../toolbar/mobile/toolbar-mobile'\r\nimport { withDialogState } from '../with_dialog_state_hook'\r\nimport { AutoSaveStateIndicator } from './auto-save-state-indicator'\r\nimport { ChartLayoutAutoSaveNote } from './chart-layout-auto-save-note'\r\nimport { PublishOldButtonClickListener, getPublishChartHtmlElements } from './publish_old_button_click_listener'\r\nimport { withChartPageTitle } from './with-chart-page-title'\r\nimport { withChartRouteChange } from './with-chart-route-change'\r\nimport { withCompleteLayoutModelInit } from './with-complete-layout-model-init'\r\nimport { withIdeaModelState } from './with-idea-model-state'\r\nimport { withQuoteCacheManagement } from './with-quote-cache-management'\r\nimport { withQuotePolling } from './with-quote-polling'\r\n\r\ninterface ChartLayoutComponentProps {\r\n config: RootChartConfigObject\r\n confirmationDialogState: DialogStateReturn\r\n noteDialogState: DialogStateReturn\r\n shouldResize?: boolean\r\n chartLayoutModel: ChartLayoutModel\r\n idea?: IIdea\r\n deleteAllAutoSavedElements: () => void\r\n isAutoSaveActive: boolean\r\n}\r\n\r\ninterface ChartLayoutComponentState {\r\n editable: boolean\r\n editors: ChartEditorEnum[]\r\n layout: LayoutType\r\n activeChartInteraction: string | null\r\n touchEventsDisabled: boolean\r\n isToolbarHorizontal: boolean\r\n activeTool: DrawingTool\r\n drawingSettings: Record\r\n}\r\n\r\nclass ChartLayoutComponentBase extends React.Component {\r\n // expects config, bindPublic\r\n model: ChartLayoutModel\r\n isMobile = Boolean(utils.isMobile(true))\r\n charts: Array<{ model: ChartModel; config: RootChartConfigObjectChart }>\r\n orientationChangeTimeout: number | undefined\r\n preserveDrawingAbortController = new AbortController()\r\n\r\n constructor(props: ChartLayoutComponentProps) {\r\n super(props)\r\n\r\n this.model = props.chartLayoutModel\r\n const config = props.config\r\n\r\n this.charts = []\r\n for (const chartConfig of config.charts) {\r\n const modelProperties: Partial = merge({}, chartConfig)\r\n\r\n modelProperties.chart_layout = this.model\r\n delete modelProperties.panes\r\n if (modelProperties.zoomFactor == null) {\r\n modelProperties.zoomFactor = this.model.defaultZoomFactor\r\n }\r\n if (modelProperties.refreshData == null) {\r\n modelProperties.refreshData = true\r\n }\r\n if (!modelProperties.dateRange) {\r\n modelProperties.dateRange = null\r\n }\r\n modelProperties.isHideDrawingsActive = this.model.isHideDrawingsActive\r\n modelProperties.isScrolled = false\r\n const model = this.model.charts().create(modelProperties)\r\n this.charts.push({ model, config: chartConfig })\r\n }\r\n this.model.updateAttribute('activeChart', this.model.charts().first())\r\n\r\n this.state = {\r\n editable: this.model.editable,\r\n editors: this.model.editors,\r\n layout: this.model.layout,\r\n activeChartInteraction: null,\r\n activeTool: DrawingTool.Mouse,\r\n touchEventsDisabled: false,\r\n isToolbarHorizontal: true,\r\n drawingSettings: {\r\n [DrawingSetting.DrawingModeContinuous]: false,\r\n [DrawingSetting.PreserveDrawings]: this.handleInitialPreserveDrawingsState(),\r\n [DrawingSetting.HideDrawings]: false,\r\n [DrawingSetting.LockDrawings]: false,\r\n },\r\n }\r\n }\r\n\r\n componentDidMount() {\r\n if (this.state.editable) {\r\n const DELETE = 46\r\n window.addEventListener('keyup', (e) => {\r\n const selected = this.model.getPaneWithSelection()\r\n if (e.keyCode === DELETE && selected) {\r\n const element = ElementModel.findByAttribute('instance', selected.selection)\r\n if (element) {\r\n const elementPane = element.pane()\r\n element.destroyCascade({ eventType: DrawingSpineOptionsEvent.Remove })\r\n elementPane.normalizeZIndexes()\r\n }\r\n }\r\n })\r\n }\r\n\r\n if (this.isMobile) {\r\n this.model.settings.ThumbSettings.size = this.model.settings.ThumbSettings.touchSize\r\n }\r\n\r\n this.onModelChange()\r\n\r\n this.model.bind('change', this.onModelChange)\r\n this.model.charts().bind('destroy', this.onChartDestroy)\r\n\r\n this.setToolbarPosition()\r\n window.addEventListener('resize', this.onWindowResize)\r\n window.addEventListener('orientationchange', this.handleOrientationChange)\r\n\r\n if (this.isMobile) {\r\n this.checkTouchEventsDisabled()\r\n window.addEventListener('touchend', this.checkTouchEventsDisabled)\r\n }\r\n }\r\n\r\n componentDidUpdate(prevProps: Readonly): void {\r\n if (prevProps.idea && !this.props.idea) {\r\n if (this.model.specificChartFunctionality === SpecificChartFunctionality.chartPage) {\r\n this.onWindowResize()\r\n }\r\n document.querySelector('#idea-title-container')?.remove()\r\n }\r\n\r\n this.setToolbarPosition()\r\n }\r\n\r\n componentWillUnmount() {\r\n this.preserveDrawingAbortController.abort()\r\n this.model.unbind('change', this.onModelChange)\r\n\r\n window.removeEventListener('resize', this.onWindowResize)\r\n window.removeEventListener('orientationchange', this.handleOrientationChange)\r\n\r\n if (this.isMobile) {\r\n window.removeEventListener('touchend', this.checkTouchEventsDisabled)\r\n }\r\n\r\n clearTimeout(this.orientationChangeTimeout)\r\n this.throttledResize.cancel()\r\n this.model.destroyCascade()\r\n }\r\n\r\n handleInitialPreserveDrawingsState = () => {\r\n let preserveDrawings = false\r\n if (getIsPreserveDrawingsAndAutosaveAvailable(this.model)) {\r\n if (window.FinvizSettings.toolsState?.[DrawingSetting.PreserveDrawings] !== undefined) {\r\n preserveDrawings = window.FinvizSettings.toolsState[DrawingSetting.PreserveDrawings]\r\n } else {\r\n this.handlePreserveDrawingsSettings()\r\n }\r\n }\r\n this.model.updateAttribute('isPreserveDrawingsActive', preserveDrawings)\r\n return preserveDrawings\r\n }\r\n\r\n handlePreserveDrawingsSettings = async (value?: boolean) => {\r\n const setPreserveDrawings = (val: boolean) => {\r\n this.model.updateAttribute('isPreserveDrawingsActive', val)\r\n this.setState((prevState) => ({\r\n drawingSettings: {\r\n ...prevState.drawingSettings,\r\n [DrawingSetting.PreserveDrawings]: val,\r\n },\r\n }))\r\n }\r\n\r\n try {\r\n this.preserveDrawingAbortController.abort()\r\n this.preserveDrawingAbortController = new AbortController()\r\n const response = await fetchApi({\r\n location: '/api/tools_state.ashx',\r\n method: value !== undefined ? 'POST' : 'GET',\r\n body:\r\n value !== undefined\r\n ? new URLSearchParams({ tools_state: JSON.stringify({ [DrawingSetting.PreserveDrawings]: value }) })\r\n : undefined,\r\n throwOnStatusCodes: [404],\r\n abortController: this.preserveDrawingAbortController,\r\n })\r\n\r\n if (value === undefined && response?.[DrawingSetting.PreserveDrawings] !== undefined) {\r\n setPreserveDrawings(response[DrawingSetting.PreserveDrawings])\r\n }\r\n } catch {\r\n if (value !== undefined) {\r\n setPreserveDrawings(!value)\r\n }\r\n }\r\n }\r\n\r\n handleOrientationChange = () => {\r\n this.orientationChangeTimeout = window.setTimeout(() => {\r\n this.setToolbarPosition()\r\n if (this.props.shouldResize) {\r\n this.handleResize()\r\n }\r\n })\r\n }\r\n\r\n onWindowResize = () => {\r\n this.setToolbarPosition()\r\n\r\n if (this.props.shouldResize) {\r\n this.throttledResize()\r\n }\r\n }\r\n\r\n handleResize = () => {\r\n const modelAttrs: Partial = getChartsDimensions(this.model.getHTMLElementId())\r\n this.model.updateAttributes(modelAttrs)\r\n }\r\n\r\n throttledResize = throttle(this.handleResize, 200)\r\n\r\n setToolbarPosition() {\r\n // quote page toolbar\r\n // 210px represents: (20px (toolbar left margin) + 80px (toolbar width) + 5px (toolbar rigth margin)) * 2 (both sides of chart)\r\n const newIsToolbarHorizontal = this.model.width + 210 > window.innerWidth || window.innerWidth < 1000\r\n if (newIsToolbarHorizontal !== this.state.isToolbarHorizontal) {\r\n this.setState({\r\n isToolbarHorizontal: newIsToolbarHorizontal,\r\n })\r\n }\r\n }\r\n\r\n checkTouchEventsDisabled = () => {\r\n if (!/\\bcharts\\b/.test(window.location.pathname) || getFullscreenStatus() || this.getVisualViewportScale() === 1) {\r\n this.state?.touchEventsDisabled && this.setState({ touchEventsDisabled: false })\r\n } else {\r\n !this.state?.touchEventsDisabled && this.setState({ touchEventsDisabled: true })\r\n }\r\n }\r\n\r\n getVisualViewportScale = () => {\r\n if (process.env.IS_E2E_TESTING) {\r\n return 1\r\n }\r\n if (window.visualViewport && this.isMobile) {\r\n return window.visualViewport.scale\r\n } else {\r\n return 1\r\n }\r\n }\r\n\r\n handleActiveToolChange = (activeTool: DrawingTool) => {\r\n if (!this.model.isLockDrawingsActive) {\r\n this.setState({ activeTool })\r\n }\r\n }\r\n\r\n handleDrawingAction = (actionId: DrawingActions) => {\r\n switch (actionId) {\r\n case DrawingActions.AddNote:\r\n this.props.noteDialogState.toggle()\r\n break\r\n case DrawingActions.DeleteDrawings:\r\n case DrawingActions.DeleteAutoSavedDrawings:\r\n this.props.confirmationDialogState.show()\r\n break\r\n default:\r\n return\r\n }\r\n }\r\n\r\n handleConfirmationDialogDeleteBtn = () => {\r\n if (this.model.drawingsInternalStore().autoSaveState !== AutoSaveState.Off) {\r\n this.props.deleteAllAutoSavedElements()\r\n }\r\n this.model.getAllElements().forEach((element) => {\r\n if (element.isDrawing()) {\r\n element.destroyCascade({ eventType: DrawingSpineOptionsEvent.Remove })\r\n const drawingToRemove = this.model\r\n .drawingsInternalStore()\r\n .elements.find(({ elementId }) => elementId === element.id)\r\n if (drawingToRemove) {\r\n drawingToRemove.changeType = 'destroy'\r\n }\r\n }\r\n })\r\n this.props.confirmationDialogState.hide()\r\n }\r\n\r\n handleDrawingsSetting = (settingId: DrawingSetting) => {\r\n const newObj = { ...this.state.drawingSettings, [settingId]: !this.state.drawingSettings[settingId] }\r\n\r\n switch (settingId) {\r\n case DrawingSetting.HideDrawings:\r\n this.handleActiveToolChange(DrawingTool.Mouse)\r\n this.toggleHideDrawings(newObj[DrawingSetting.HideDrawings])\r\n this.handleLockDrawings(newObj)\r\n break\r\n case DrawingSetting.PreserveDrawings:\r\n this.handlePreserveDrawingsSettings(newObj[DrawingSetting.PreserveDrawings])\r\n this.model.updateAttribute('isPreserveDrawingsActive', newObj[DrawingSetting.PreserveDrawings])\r\n break\r\n case DrawingSetting.LockDrawings:\r\n this.handleActiveToolChange(DrawingTool.Mouse)\r\n this.handleLockDrawings(newObj)\r\n break\r\n case DrawingSetting.DrawingModeContinuous:\r\n this.model.updateAttribute('isDrawingModeContinuousActive', newObj[DrawingSetting.DrawingModeContinuous])\r\n newObj[DrawingSetting.DrawingModeContinuous] === false && this.handleActiveToolChange(DrawingTool.Mouse)\r\n break\r\n default:\r\n break\r\n }\r\n\r\n this.setState({ drawingSettings: newObj })\r\n window.gtag?.('event', 'drawings_settings_toggle', {\r\n event_category: newObj[settingId] ? 'enable' : 'disable',\r\n event_label: settingId,\r\n })\r\n }\r\n\r\n handleLockDrawings = (drawingSettings: Record) => {\r\n this.model.updateAttribute(\r\n 'isLockDrawingsActive',\r\n !(!drawingSettings[DrawingSetting.HideDrawings] && !drawingSettings[DrawingSetting.LockDrawings])\r\n )\r\n }\r\n\r\n toggleHideDrawings(value: boolean) {\r\n this.model.updateAttribute('isHideDrawingsActive', value)\r\n this.model.getAllCharts().forEach((chart) => chart.updateAttribute('isHideDrawingsActive', value))\r\n }\r\n\r\n renderToolbar(args: any) {\r\n const { activeTool, drawingSettings } = this.state\r\n return args.isOverlayToolbar ? (\r\n \r\n ) : (\r\n \r\n )\r\n }\r\n\r\n render() {\r\n const { newCharts, useGrid } = this.props.config\r\n const { activeTool, editable, editors, isToolbarHorizontal } = this.state\r\n const publish = editors.includes(ChartEditorEnum.publish) && getPublishChartHtmlElements().length > 0\r\n const chartLayout = LAYOUTS[this.model.layout]\r\n const isMobilePortrait = getIsMobilePortrait(this.isMobile)\r\n const { tickers } = getTickersAndContainerTypesInLayoutModel(this.model)\r\n\r\n if (newCharts) {\r\n const isSidebarEnabled = getIsSidebarEnabled(SpecificChartFunctionality.chartPage)\r\n return (\r\n <>\r\n

\r\n {!isMobilePortrait &&\r\n // Due safari iOS flex-column bug not resizing height properly we need to render toolbar\r\n // outside of flex for portrait and inside for landscape\r\n // https://github.com/finvizhq/charts/pull/784\r\n this.renderToolbar({\r\n isSidebar: true,\r\n isHorizontal: false,\r\n })}\r\n \r\n \r\n \r\n {this.charts.map(({ model, config }, index) => (\r\n }\r\n gridArea={chartLayout.gridAreas?.[index]}\r\n setActiveChartInteraction={this.setActiveChartInteraction}\r\n activeTool={activeTool}\r\n activeChartInteraction={this.state.activeChartInteraction}\r\n touchEventsDisabled={this.state.touchEventsDisabled}\r\n shouldResize={this.props.shouldResize}\r\n />\r\n ))}\r\n \r\n \r\n
\r\n {isMobilePortrait && isSidebarEnabled && (\r\n \r\n )}\r\n {isMobilePortrait &&\r\n this.renderToolbar({\r\n isSidebar: false,\r\n isHorizontal: true,\r\n isOverlayToolbar: isSidebarEnabled,\r\n })}\r\n {this.props.idea?.note && (\r\n
\r\n
\r\n {this.props.idea.note}\r\n
\r\n
\r\n )}\r\n \r\n )\r\n }\r\n\r\n const hasRedesign = isRedesignEnabled()\r\n const hasChartTools = editable && editors.includes(ChartEditorEnum.tools)\r\n const renderTools = isRedesignedPage(this.model) ? hasChartTools && !isToolbarHorizontal : hasChartTools\r\n\r\n const ideaTitleContainer = document.querySelector('#idea-title-container')\r\n const ideaTitle = this.props.idea?.date &&\r\n this.model.specificChartFunctionality === SpecificChartFunctionality.quotePage && (\r\n

{`Your idea from ${this.props.idea.date}`}

\r\n )\r\n\r\n return (\r\n <>\r\n {ideaTitleContainer ? ReactDOM.createPortal(ideaTitle, ideaTitleContainer) : ideaTitle}\r\n \r\n {renderTools && (\r\n \r\n {this.renderToolbar({\r\n isHorizontal: isToolbarHorizontal,\r\n isAlternativeTheme: true,\r\n })}\r\n \r\n )}\r\n \r\n \r\n {this.charts.map(({ model, config }, index) => (\r\n \r\n this.renderToolbar({\r\n isHorizontal: true,\r\n isAlternativeTheme: true,\r\n })\r\n : undefined\r\n }\r\n />\r\n ))}\r\n \r\n
\r\n
\r\n
\r\n {this.model.specificChartFunctionality === SpecificChartFunctionality.quotePage && (\r\n \r\n )}\r\n \r\n \r\n )\r\n }\r\n\r\n setActiveChartInteraction = (value: string | null) => {\r\n this.setState({ activeChartInteraction: value })\r\n }\r\n\r\n updateLayout() {\r\n const layout = LAYOUTS[this.model.layout]\r\n const charts = this.model.charts().all()\r\n if (charts.length === 0) {\r\n return\r\n }\r\n\r\n if (charts.length > layout.count) {\r\n this.removeCharts(layout.count)\r\n } else if (charts.length < layout.count) {\r\n this.addCharts(layout.count - charts.length)\r\n }\r\n\r\n this.model\r\n .charts()\r\n .all()\r\n .forEach((chart, index) => {\r\n const [rowStart, columnStart, rowEnd, columnEnd] =\r\n layout.gridAreas?.[index]\r\n .replace(/ /g, '')\r\n .split('/')\r\n .map((num) => Number.parseInt(num)) || []\r\n const numOfRowsCovered = [rowEnd, rowStart].every((value) => value !== undefined) ? rowEnd - rowStart : 1\r\n const numOfColumnsCovered = [columnStart, columnEnd].every((value) => value !== undefined)\r\n ? columnEnd - columnStart\r\n : 1\r\n const percentageOfRowsCovered = numOfRowsCovered / layout.rows\r\n const percentageOfColumnsCovered = numOfColumnsCovered / layout.columns\r\n const newWidth = ~~(this.model.width * percentageOfColumnsCovered)\r\n const isChartPage = this.model.specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n const chartLayoutHeight = isChartPage\r\n ? this.model.height\r\n : this.model.charts().first().height || this.model.height\r\n let newHeight = ~~(chartLayoutHeight * percentageOfRowsCovered)\r\n\r\n if (this.model.editors.includes(ChartEditorEnum.settings) && isChartPage) {\r\n newHeight -= this.model.settings.ChartSettings.general.settingsHeight\r\n }\r\n if ((chart.width !== newWidth || chart.height !== newHeight) && newWidth > 0 && newHeight > 0) {\r\n chart.updateAttributes({ width: newWidth, height: newHeight })\r\n }\r\n })\r\n }\r\n\r\n addCharts(count: number) {\r\n const quote = this.model.charts().last().quote()\r\n if (!quote) return\r\n const config = {\r\n ...this.model.charts().last().toObject(),\r\n leftOffset: null,\r\n chart_layout: this.model,\r\n aftermarket: quote.aftermarket,\r\n premarket: quote.premarket,\r\n }\r\n for (let i = 0; i < count; i++) {\r\n const model = this.model.charts().create(config)\r\n this.charts.push({ model, config })\r\n }\r\n }\r\n\r\n removeCharts(wantedCount: number) {\r\n while (this.model.charts().count() > wantedCount) {\r\n const chart = this.model.charts().last()\r\n chart.destroyCascade()\r\n this.charts.pop()\r\n }\r\n }\r\n\r\n onChartDestroy = (chartModel: ChartModel) => {\r\n this.updateLayout()\r\n if (this.model.activeChart?.eql(chartModel)) {\r\n this.model.updateAttribute('activeChart', this.model.charts().last())\r\n }\r\n }\r\n\r\n onModelChange = (layoutModel?: ChartLayout, event?: Spine.Event) => {\r\n if (event === 'refresh') {\r\n return\r\n }\r\n this.updateLayout()\r\n\r\n if (layoutModel && event === 'update') {\r\n this.setState({\r\n editable: layoutModel.editable,\r\n editors: layoutModel.editors,\r\n layout: layoutModel.layout,\r\n })\r\n }\r\n }\r\n}\r\n\r\nexport const ChartLayoutComponent = flowRight(\r\n withQuoteCacheManagement,\r\n withDialogState,\r\n withCompleteLayoutModelInit,\r\n withChartPageTitle,\r\n withChartRouteChange,\r\n withIdeaModelState,\r\n withQuotePolling,\r\n withDrawingsAutoSave\r\n)(ChartLayoutComponentBase)\r\n","import debounce from 'lodash.debounce'\r\nimport React from 'react'\r\n\r\nimport Chart from '../../models/chart'\r\nimport Quote from '../../models/quote'\r\n\r\nconst MAX_QUOTE_CACHE_TIME_IN_MS = 300000 // 5 min\r\n\r\nexport const withQuoteCacheManagement = (Component: any) => (props: any) => {\r\n React.useEffect(() => {\r\n const cleanupQuoteCache = () => {\r\n const allQuotes = Quote.all()\r\n const allCharts = Chart.all()\r\n const allChartQuotes = allCharts.flatMap((chart) => chart.getAllQuotes())\r\n\r\n allQuotes.forEach((quote) => {\r\n if (\r\n !allChartQuotes.some((usedQuote) => usedQuote.eql(quote)) &&\r\n !quote.isFetching &&\r\n quote.fetchedAt > -1 &&\r\n quote.fetchedAt < Date.now() - MAX_QUOTE_CACHE_TIME_IN_MS\r\n ) {\r\n quote.destroy()\r\n }\r\n })\r\n }\r\n\r\n const checkQuoteCacheDebounce = debounce(cleanupQuoteCache, 500)\r\n\r\n Quote.bind('change', checkQuoteCacheDebounce)\r\n return () => {\r\n checkQuoteCacheDebounce.cancel()\r\n Quote.unbind('change', checkQuoteCacheDebounce)\r\n }\r\n }, [])\r\n\r\n return \r\n}\r\n","import { useDialogState } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nexport const withDialogState = (Component: any) => (props: any) => {\r\n const confirmationDialogState = useDialogState()\r\n const noteDialogState = useDialogState()\r\n\r\n return \r\n}\r\n","import * as React from 'react'\r\n\r\nimport { SpecificChartFunctionality, TIMEFRAME } from '../../constants/common'\r\nimport math from '../../helpers/math'\r\nimport ChartLayoutModel from '../../models/chart_layout'\r\nimport Quote from '../../models/quote'\r\n\r\nfunction useChartPageTitle() {\r\n const defaultDocumentTitleRef = React.useRef(document.title)\r\n\r\n const { current: updateChartsTitle } = React.useRef((chartLayoutModel: ChartLayoutModel) => {\r\n const charts = chartLayoutModel\r\n .getAllCharts()\r\n .reduce(\r\n (acc, current) => {\r\n if (acc.some(({ ticker }) => ticker === current.ticker)) {\r\n return acc\r\n }\r\n return [...acc, { ticker: current.ticker, timeframe: current.timeframe, instrument: current.instrument }]\r\n },\r\n [] as Array<{ ticker: string; timeframe: TIMEFRAME; instrument: string }>\r\n )\r\n .map((chart) => {\r\n const { ticker, timeframe, instrument } = chart\r\n const quotes = Quote.select(\r\n (quote: Quote) =>\r\n quote.ticker === ticker.replace('@', '') &&\r\n quote.timeframe === timeframe &&\r\n quote.instrument === instrument &&\r\n chartLayoutModel.isIdeaId(quote.ideaID)\r\n )\r\n if (quotes.length > 0) {\r\n const { lastClose, instrument, afterClose, prevClose, name } = quotes[0]\r\n let percentageChange: number\r\n if (!lastClose) {\r\n return null\r\n }\r\n if (prevClose !== null) {\r\n percentageChange = (lastClose / prevClose - 1) * 100\r\n }\r\n if (afterClose !== null && afterClose !== lastClose) {\r\n percentageChange = (afterClose / lastClose - 1) * 100\r\n }\r\n return `${name || ticker} ${math.round({\r\n value: lastClose,\r\n lastClose,\r\n instrument,\r\n overridePlaces: undefined,\r\n })} ${percentageChange! > 0 ? '+' : '-'}${math.round({\r\n value: Math.abs(percentageChange!),\r\n overridePlaces: 2,\r\n })}%`\r\n }\r\n return null\r\n })\r\n .filter((chart) => chart !== null)\r\n\r\n if (charts && charts.length > 0) {\r\n const title = charts.join(' | ')\r\n if (document.title !== title) {\r\n document.title = title\r\n }\r\n } else if (document.title !== defaultDocumentTitleRef.current) {\r\n document.title = defaultDocumentTitleRef.current\r\n }\r\n })\r\n\r\n return { updateChartsTitle }\r\n}\r\n\r\nexport function withChartPageTitle

(\r\n Component: React.ComponentType

\r\n) {\r\n return function WrappedComponent(props: P) {\r\n const { updateChartsTitle } = useChartPageTitle()\r\n\r\n const handleChartsUpdate = React.useCallback(() => {\r\n updateChartsTitle(props.chartLayoutModel)\r\n }, [props.chartLayoutModel, updateChartsTitle])\r\n\r\n React.useEffect(() => {\r\n if (props.chartLayoutModel.specificChartFunctionality === SpecificChartFunctionality.chartPage) {\r\n props.chartLayoutModel.charts().bind('change', handleChartsUpdate)\r\n\r\n handleChartsUpdate()\r\n\r\n return () => {\r\n props.chartLayoutModel.charts().unbind('change', handleChartsUpdate)\r\n }\r\n }\r\n }, [props.chartLayoutModel, handleChartsUpdate])\r\n\r\n return \r\n }\r\n}\r\n","import React from 'react'\r\n\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport ChartLayoutModel from '../../models/chart_layout'\r\n\r\nexport function withIdeaModelState

(\r\n Component: React.ComponentType

\r\n) {\r\n return function WrappedComponent(props: P) {\r\n const chartLayoutModel = useModelState(props.chartLayoutModel, { watchProperties: ['idea'] })\r\n return \r\n }\r\n}\r\n","import { NotificationWrapper, withSuspense } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport { RootChartConfigObject } from '../../../types/shared'\r\nimport { ElementStyleDialogWrapper } from '../../modals/element_style'\r\nimport { useChartLayoutGlobalModelAsync } from '../../utils/useChartLayoutGlobalModelAsync'\r\nimport { ChartLayoutComponent } from './chart_layout_component'\r\n\r\ninterface ChartLayoutProps {\r\n config: RootChartConfigObject\r\n shouldResize?: boolean\r\n parentElement?: HTMLElement\r\n isWithNotifications?: boolean\r\n}\r\n\r\nexport function ChartLayout({ config, shouldResize, isWithNotifications = true }: ChartLayoutProps) {\r\n const Wrapper = isWithNotifications ? NotificationWrapper : React.Fragment\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n )\r\n}\r\n\r\nexport function ChartLayoutWithGlobalStateRaw({\r\n config,\r\n shouldResize,\r\n parentElement,\r\n}: Omit) {\r\n const { setChartLayoutModel, getChartLayoutModelConfig, lastGlobalRerender } = useChartLayoutGlobalModelAsync()\r\n\r\n return (\r\n \r\n {config && (\r\n \r\n )}\r\n \r\n )\r\n}\r\n\r\nexport const ChartLayoutWithGlobalState = withSuspense(ChartLayoutWithGlobalStateRaw)\r\n","export const CHART_LAYOUT_CHILD_CHANGE_EVENT = 'chartLayoutChildChange'\r\n","import merge from 'lodash.merge'\r\nimport React from 'react'\r\n\r\nimport { RootChartConfigObject, Theme } from '../../../types/shared'\r\nimport {\r\n ChartEditorEnum,\r\n MOBILE_BARS_TO_VIEW,\r\n MOBILE_VIEW_BREAKPOINT_WIDTH,\r\n SpecificChartFunctionality,\r\n} from '../../constants/common'\r\nimport ChartLayoutModel from '../../models/chart_layout'\r\nimport DrawingsInternalStore from '../../models/drawings-internal-store'\r\nimport { getSettings } from '../../models/settings'\r\nimport utils, { isRedesignedPage } from '../../utils'\r\nimport { getIsPreserveDrawingsAndAutosaveAvailable, getZoomFactorForBarsToDisplay } from '../../utils/chart'\r\nimport { getContainerTypeFromPaneConfig, getInitialStoreDrawings } from '../autosave/utils'\r\nimport { DrawingSetting } from '../toolbar/interfaces'\r\nimport { CHART_LAYOUT_CHILD_CHANGE_EVENT } from './constants'\r\n\r\ninterface Props {\r\n config: RootChartConfigObject\r\n onRegisterChartLayoutModel?: (chartLayoutModel: ChartLayoutModel) => void\r\n parentElement?: HTMLElement\r\n}\r\n\r\nfunction getDefaultZoomFactor(chartLayout: ChartLayoutModel) {\r\n const innerWidth = window.innerWidth\r\n if (\r\n innerWidth >= MOBILE_VIEW_BREAKPOINT_WIDTH ||\r\n chartLayout.specificChartFunctionality !== SpecificChartFunctionality.chartPage\r\n ) {\r\n return 1\r\n }\r\n\r\n return getZoomFactorForBarsToDisplay({\r\n chartLayout,\r\n numOfVisibleBars: MOBILE_BARS_TO_VIEW,\r\n chartVisibleWidth: innerWidth,\r\n })\r\n}\r\n\r\nfunction OnInitListener({\r\n chartLayoutModel,\r\n config,\r\n onRegisterChartLayoutModel,\r\n parentElement,\r\n}: Props & { chartLayoutModel: ChartLayoutModel; parentElement?: HTMLElement }) {\r\n const [isInit, setIsInit] = React.useState(false)\r\n\r\n /*\r\n * This entire effect is used to check for updates in entire chart layout obj tree.\r\n * Once config object matches object generated from chart layout, the layout model is completely initialised.\r\n *\r\n * We couldn't just add a callback to `componentDidMount` (or equivalent) because its children are rendered asynchronously.\r\n *\r\n * */\r\n React.useEffect(() => {\r\n if (onRegisterChartLayoutModel && chartLayoutModel && !isInit) {\r\n const checkIfInitIsComplete = () => {\r\n const { charts } = chartLayoutModel.toConfig()\r\n const isReady =\r\n charts.length === config.charts.length &&\r\n charts.every(\r\n (chart, chartIndex) =>\r\n chart.panes.length === config.charts[chartIndex].panes.length &&\r\n chart.panes.every(\r\n (pane, paneIndex) =>\r\n pane.elements.length === config.charts[chartIndex].panes[paneIndex].elements.length &&\r\n pane.elements.every(\r\n (element, elementIndex) =>\r\n element.overlays?.length ===\r\n config.charts[chartIndex].panes[paneIndex].elements[elementIndex].overlays?.length\r\n )\r\n )\r\n )\r\n\r\n if (isReady) {\r\n setIsInit(true)\r\n chartLayoutModel.updateAttributes({ isInit: true })\r\n onRegisterChartLayoutModel(chartLayoutModel)\r\n if (parentElement) {\r\n parentElement.style.opacity = 'unset'\r\n parentElement.style.minHeight = 'unset'\r\n parentElement.style.minWidth = 'unset'\r\n }\r\n }\r\n }\r\n\r\n chartLayoutModel.bind(CHART_LAYOUT_CHILD_CHANGE_EVENT, checkIfInitIsComplete)\r\n\r\n checkIfInitIsComplete()\r\n\r\n return () => {\r\n chartLayoutModel.unbind(CHART_LAYOUT_CHILD_CHANGE_EVENT, checkIfInitIsComplete)\r\n }\r\n }\r\n }, [chartLayoutModel, config, isInit, onRegisterChartLayoutModel, parentElement])\r\n\r\n return null\r\n}\r\n\r\nexport const withCompleteLayoutModelInit = (Component: any) => (props: Props) => {\r\n const config = React.useMemo(() => {\r\n const newConfig = merge({}, props.config, {\r\n editable: props.config.editable ?? true,\r\n canChangeTicker: props.config.canChangeTicker ?? true,\r\n scrollable: props.config.scrollable ?? true,\r\n cross: props.config.cross ?? true,\r\n theme:\r\n props.config.theme && [Theme.light, Theme.dark].includes(props.config.theme) ? props.config.theme : Theme.light,\r\n editors: props.config.editors ?? [ChartEditorEnum.publish, ChartEditorEnum.tools, ChartEditorEnum.ideas],\r\n ideas: props.config.ideas ?? true,\r\n specificChartFunctionality: props.config.specificChartFunctionality ?? SpecificChartFunctionality.default,\r\n initialStoreDrawings: [],\r\n })\r\n\r\n if (!newConfig.ideas) {\r\n newConfig.editors = newConfig.editors.filter((x) => x !== 'ideas')\r\n }\r\n\r\n // We need to add these because ideas might not have them and chart controls wouldn’t render properly\r\n if (isRedesignedPage(newConfig, [SpecificChartFunctionality.quotePage])) {\r\n newConfig.editors = newConfig.editors.concat([ChartEditorEnum.settings, ChartEditorEnum.timeframe])\r\n }\r\n\r\n const initialStoreDrawings = getInitialStoreDrawings()?.filter(({ changeType }) => changeType !== 'destroy') ?? []\r\n const isQuotePage = newConfig.specificChartFunctionality === SpecificChartFunctionality.quotePage\r\n const isQuotePageWithDrawingsOff = isQuotePage && utils.getCookie('charts-draw') !== 'on'\r\n\r\n if (initialStoreDrawings.length === 0 || isQuotePageWithDrawingsOff) {\r\n return newConfig\r\n }\r\n\r\n const noteDrawing = initialStoreDrawings.find(\r\n ({ containerType, ticker }) =>\r\n containerType === 'note' && props.config.charts.some((chart) => chart.ticker === ticker)\r\n )\r\n\r\n const note = noteDrawing && JSON.parse(noteDrawing.elementAttrs)?.text\r\n const ideaObject = isQuotePage && note ? { note } : undefined\r\n\r\n return {\r\n ...newConfig,\r\n initialStoreDrawings,\r\n idea: newConfig.idea ?? ideaObject,\r\n charts: newConfig.charts.map((chart) => {\r\n const { ticker, panes } = chart\r\n return {\r\n ...chart,\r\n panes: panes.map((pane) => {\r\n const containerType = getContainerTypeFromPaneConfig(pane)\r\n const newElements = initialStoreDrawings\r\n .filter(\r\n (drawing) =>\r\n drawing.containerType === containerType &&\r\n drawing.ticker === ticker &&\r\n !pane.elements.some((paneElement) => paneElement.elementId === drawing.elementId)\r\n )\r\n .map(({ elementId, zIndex, elementAttrs }) => ({\r\n elementId,\r\n zIndex,\r\n ...JSON.parse(elementAttrs),\r\n }))\r\n return {\r\n ...pane,\r\n elements: [...pane.elements, ...newElements],\r\n }\r\n }),\r\n }\r\n }),\r\n }\r\n // We need to disable the eslint check because the hook is supposed to run only once on mount\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [])\r\n\r\n const chartLayoutModel = React.useMemo(() => {\r\n const settings = getSettings({ ...config, theme: config.theme! })\r\n const chartLayout = ChartLayoutModel.create({\r\n layout: config.layout,\r\n width: config.width,\r\n height: config.height,\r\n editable: config.editable,\r\n canChangeTicker: config.canChangeTicker,\r\n scrollable: config.scrollable,\r\n initialScrollable: config.scrollable,\r\n cross: config.cross,\r\n editors: config.editors,\r\n theme: config.theme,\r\n idea: config.idea,\r\n settings,\r\n isWheelZoomEnabled: config.specificChartFunctionality === SpecificChartFunctionality.chartPage,\r\n specificChartFunctionality: config.specificChartFunctionality,\r\n isHideDrawingsActive: false,\r\n isPreserveDrawingsActive: !!(\r\n getIsPreserveDrawingsAndAutosaveAvailable(config) &&\r\n window.FinvizSettings.toolsState?.[DrawingSetting.PreserveDrawings]\r\n ),\r\n isLockDrawingsActive: false,\r\n uuid: config.uuid,\r\n drawingsInternalStore: DrawingsInternalStore.create({\r\n elements: config.initialStoreDrawings,\r\n }),\r\n })\r\n\r\n chartLayout.updateAttributes({ defaultZoomFactor: getDefaultZoomFactor(chartLayout) })\r\n\r\n return chartLayout\r\n\r\n // We need to disable the eslint check because the hook is supposed to run only once on mount\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [])\r\n\r\n return chartLayoutModel ? (\r\n <>\r\n \r\n \r\n \r\n ) : null\r\n}\r\n","import debounce from 'lodash.debounce'\r\nimport React from 'react'\r\n\r\nimport { ObjectHash } from '../../../types/shared'\r\nimport { EXTRA_MARKET_BUFFER_MINUTES, QUOTE_FETCH_EVENT } from '../../constants/common'\r\nimport Chart from '../../models/chart'\r\nimport ChartLayoutModel from '../../models/chart_layout'\r\nimport Pane from '../../models/pane'\r\nimport { QuoteFetchType } from '../../models/quote/constants'\r\n\r\ninterface Props {\r\n chartLayoutModel: ChartLayoutModel\r\n}\r\n\r\ntype PollingIntervalToChartsType = ObjectHash\r\n\r\n/*\r\n * This HOC loops through all charts and checks if they are supposed to be refetch in some interval\r\n * It creates groups of charts to be refreshed grouped by the refresh interval\r\n * */\r\nexport const withQuotePolling = (Component: any) => (props: Props) => {\r\n const [pollingIntervalToCharts, setPollingIntervalToCharts] = React.useState({})\r\n const checkForChartsWithPolling = React.useCallback(() => {\r\n // check for charts which have some refresh interval and group chart ids by the interval value e.g. { interval_in_ms: [id1, id2] }\r\n const newPollingIntervalToCharts: PollingIntervalToChartsType = {} // example { 60000: ['c-0', 'c-1'], 9000: ['c-4'] }\r\n props.chartLayoutModel.getAllCharts().forEach((chart) => {\r\n const chartRefreshInterval = chart.getRefreshInterval()\r\n\r\n if (chartRefreshInterval) {\r\n newPollingIntervalToCharts[chartRefreshInterval] = newPollingIntervalToCharts[chartRefreshInterval] ?? []\r\n newPollingIntervalToCharts[chartRefreshInterval].push(chart.id)\r\n }\r\n })\r\n\r\n if (JSON.stringify(newPollingIntervalToCharts) !== JSON.stringify(pollingIntervalToCharts)) {\r\n setPollingIntervalToCharts(newPollingIntervalToCharts)\r\n }\r\n }, [props.chartLayoutModel, pollingIntervalToCharts])\r\n const intervalIdsRef = React.useRef([])\r\n\r\n React.useEffect(() => {\r\n const checkForChartsWithPollingDebounced = debounce(checkForChartsWithPolling)\r\n const chartsCheckerIntervalId = window.setInterval(\r\n checkForChartsWithPollingDebounced,\r\n EXTRA_MARKET_BUFFER_MINUTES * 1000\r\n )\r\n\r\n // listen on any changes in all charts & panes and call debounced check for charts/indicators with quotes that needs to be refetched periodically\r\n Chart.bind('change', checkForChartsWithPollingDebounced)\r\n Pane.bind('change', checkForChartsWithPollingDebounced)\r\n\r\n return () => {\r\n checkForChartsWithPollingDebounced.cancel()\r\n Chart.unbind('change', checkForChartsWithPollingDebounced)\r\n Pane.unbind('change', checkForChartsWithPollingDebounced)\r\n window.clearInterval(chartsCheckerIntervalId)\r\n }\r\n }, [checkForChartsWithPolling])\r\n\r\n React.useEffect(() => {\r\n const timeoutDurations = Object.keys(pollingIntervalToCharts).map(Number)\r\n const allCharts = props.chartLayoutModel.getAllCharts()\r\n const timeoutDurationsMin = Math.min(...timeoutDurations)\r\n\r\n timeoutDurations.forEach((duration) => {\r\n const timeoutId = window.setInterval(() => {\r\n const chartIds = pollingIntervalToCharts[duration]\r\n // get all UNIQUE quotes used in charts and refetch them\r\n allCharts\r\n .filter((chart) => chartIds.includes(chart.id))\r\n .flatMap((chart) => chart.getAllQuotes())\r\n .filter(\r\n (quote, index, quotesToUpdate) =>\r\n !quote.isFetching && index === quotesToUpdate.findIndex((quoteToUpdate) => quote.eql(quoteToUpdate))\r\n )\r\n .forEach((quote) => {\r\n quote.fetchData({ fetchType: QuoteFetchType.NewerData })\r\n })\r\n if (duration === timeoutDurationsMin) {\r\n document.dispatchEvent(new Event(QUOTE_FETCH_EVENT))\r\n }\r\n }, duration)\r\n intervalIdsRef.current.push(timeoutId)\r\n })\r\n\r\n return () => {\r\n if (intervalIdsRef.current.length > 0) {\r\n intervalIdsRef.current.forEach((timeoutId) => {\r\n window.clearInterval(timeoutId)\r\n })\r\n intervalIdsRef.current = []\r\n }\r\n }\r\n }, [props.chartLayoutModel, pollingIntervalToCharts])\r\n\r\n return \r\n}\r\n","import omit from 'lodash.omit'\r\nimport queryString from 'query-string'\r\n\r\nimport { Instrument, ObjectHash } from '../../../types/shared'\r\nimport { LayoutType } from '../../constants/common'\r\nimport { getTickerNoteText } from '../../controllers/autosave/utils'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport Quote from '../../models/quote'\r\nimport fetchApi, { getFormDataFromObject } from '../../utils/fetch_api'\r\nimport { captureException } from '../../utils/helpers'\r\n\r\nexport interface IIdea {\r\n ticker: string\r\n instrument: string\r\n period: string\r\n company?: string\r\n date: string\r\n time: string\r\n note: string\r\n id: string\r\n}\r\n\r\nexport interface IIdeaCategory {\r\n ticker: string\r\n ideas: IIdea[]\r\n}\r\n\r\nexport function getIdeaUrl({ ticker, instrument, period, id }: Pick) {\r\n const searchObject = { t: ticker, p: period, i: id }\r\n const isStock = instrument === Instrument.Stock\r\n const isQuotePage = /\\/quote\\b/.test(window.location.pathname)\r\n const isStockOnQute = isQuotePage && isStock\r\n const path = !isQuotePage || isStock ? window.location.pathname : '/charts.ashx'\r\n\r\n return `${path}?${queryString.stringify({ ...searchObject, ...(isStockOnQute ? { ta: '2' } : { l: '1h1v' }) })}`\r\n}\r\n\r\nexport async function saveIdea(layoutModel: ChartLayout) {\r\n const activeChart = layoutModel.activeChart\r\n const activeChartQuote = activeChart.quote().toJSON()\r\n const { ticker, instrument, cid } = activeChart\r\n const period = activeChartQuote.timeframe\r\n const { ChartSettings } = layoutModel.settings\r\n const layout: ObjectHash = layoutModel.toObject()\r\n layout.layout = LayoutType['1h1v']\r\n layout.barWidth = ChartSettings.center.barWidth\r\n layout.barMargin = ChartSettings.center.barMargin\r\n layout.charts = layout.charts\r\n .filter((c: ObjectHash) => c.chartId === cid)\r\n .map((c: ObjectHash) => ({ ...c, dateRange: null, refreshData: false }))\r\n\r\n delete layout.charts[0].chartId\r\n\r\n // TODO: replace with better solution after indicators overhaul\r\n const getChartTickers = (layoutModelObjectPanes: { elements: { type: string; tickers: string }[] }[]) => {\r\n let tickers = []\r\n let tickersString = ''\r\n for (const pane of layoutModelObjectPanes) {\r\n for (const element of pane.elements) {\r\n if (element.type === 'indicators/perf') {\r\n tickersString = element.tickers\r\n }\r\n }\r\n }\r\n tickers = tickersString.split(',').filter((item) => item)\r\n if (!tickers.includes(ticker)) {\r\n tickers.push(ticker.replace('@', ''))\r\n }\r\n return tickers\r\n }\r\n const tickers = getChartTickers(layout.charts[0].panes)\r\n const quotes = Quote.select(\r\n (quote: Quote) =>\r\n tickers.includes(quote.ticker) && quote.timeframe === activeChart.timeframe && layoutModel.isIdeaId(quote.ideaID)\r\n ).filter((element, index, array) => array.findIndex((t) => t.ticker === element.ticker) === index)\r\n const quotesJsonString = JSON.stringify(quotes.map((q) => omit(q.toJSON(), ['ideaID', 'chartUuid'])))\r\n\r\n const chart = JSON.stringify(layout)\r\n const note =\r\n layoutModel.idea?.note ||\r\n getTickerNoteText({ ticker, elements: layoutModel.drawingsInternalStore().elements }) ||\r\n ''\r\n window.gtag?.('event', 'save', { event_category: 'ideas' })\r\n\r\n if (tickers.length !== quotes.length) {\r\n captureException(new Error('Idea saved with inconsistent quotes data'), {\r\n extra: {\r\n tickers,\r\n quoteTickersTimeframes: quotes.map((quote) => ({ ticker: quote.ticker, timeframe: quote.timeframe })),\r\n chartLayout: layoutModel.toConfig(['colors', 'panes']),\r\n },\r\n })\r\n }\r\n\r\n const data = await fetchApi<{ id: string }>({\r\n location: '/api/idea_save.ashx',\r\n method: 'POST',\r\n body: getFormDataFromObject({ ticker, period, chart, quotes: quotesJsonString, note }),\r\n })\r\n\r\n const ideaUrl = getIdeaUrl({\r\n ticker,\r\n period,\r\n instrument,\r\n id: data.id,\r\n })\r\n\r\n if (process.env.IS_E2E_TESTING) {\r\n window.location.href = ideaUrl\r\n } else {\r\n // need to be in setTimeout because Safari block any call to window.open made in async,\r\n // this is hack to force run window.open in main thread\r\n setTimeout(() => {\r\n window.open(ideaUrl, 'FinvizSavedIdea')\r\n })\r\n }\r\n}\r\n\r\nexport function categorizeIdeas(ideas: IIdea[], tickers: string[]) {\r\n if (ideas.length <= 0) return []\r\n\r\n const categorizedIdeas = ideas.reduce((processed, idea) => {\r\n const tickerIdeas = processed.find((i) => i.ticker === idea.ticker)\r\n\r\n if (tickerIdeas) {\r\n tickerIdeas.ideas.push(idea)\r\n } else if (tickers.includes(idea.ticker)) {\r\n processed.push({\r\n ticker: idea.ticker,\r\n ideas: [idea],\r\n })\r\n }\r\n\r\n return processed\r\n }, [] as IIdeaCategory[])\r\n categorizedIdeas.unshift({\r\n ticker: 'All Ideas',\r\n ideas: ideas,\r\n })\r\n\r\n return categorizedIdeas\r\n}\r\n","import { Button, Icon, decodeQueryString } from '@finviz/website'\r\nimport classNames from 'classnames'\r\nimport React from 'react'\r\n\r\nimport { ChartsOrQuotePageQueryParams, TIMEFRAME, TimeframeLabelShort } from '../../constants/common'\r\nimport { IIdea, getIdeaUrl } from './utils'\r\n\r\ntype IdeasListProps = {\r\n idea: IIdea\r\n onIdeaDeleted: (idea: IIdea) => void\r\n}\r\n\r\nexport default function IdeaItem({ idea, onIdeaDeleted }: IdeasListProps) {\r\n const [isDeleting, setIsDeleting] = React.useState(false)\r\n const [isConfirmDelete, setIsConfirmDelete] = React.useState(false)\r\n const { i: currentIdea } = decodeQueryString()\r\n\r\n const onDeleteIdeaClick = React.useRef(async (idea: IIdea) => {\r\n setIsDeleting(true)\r\n\r\n let wasDeleted\r\n try {\r\n const response = await fetch(`/api/idea_delete.ashx?id=${idea.id}`, {\r\n method: 'DELETE',\r\n })\r\n\r\n wasDeleted = response.status === 200\r\n } catch {}\r\n\r\n if (!wasDeleted) {\r\n return\r\n }\r\n\r\n if (currentIdea === idea.id.toString()) {\r\n const newUrl = new URL(window.location.href)\r\n newUrl.searchParams.delete('i')\r\n window.location.href = newUrl.href\r\n return\r\n }\r\n\r\n onIdeaDeleted(idea)\r\n })\r\n\r\n return (\r\n (document.location = getIdeaUrl(idea))}\r\n data-testid=\"charts-notice-idea-item\"\r\n >\r\n <>\r\n

\r\n

\r\n {idea.ticker}\r\n {idea.company && {idea.company}}\r\n

\r\n \r\n {idea.date}\r\n {idea.time}\r\n \r\n \r\n {TimeframeLabelShort[idea.period as TIMEFRAME]}\r\n \r\n \r\n {idea.note !== '' ? (\r\n

{idea.note}

\r\n ) : null}\r\n
\r\n\r\n ) => {\r\n ev.stopPropagation()\r\n setIsConfirmDelete(true)\r\n }}\r\n />\r\n \r\n\r\n {isConfirmDelete && (\r\n
\r\n
\r\n

\r\n Delete {idea.ticker} Idea from {idea.date}?\r\n

\r\n
\r\n\r\n
\r\n {\r\n setIsConfirmDelete(false)\r\n }}\r\n >\r\n Cancel\r\n \r\n {\r\n onDeleteIdeaClick.current(idea)\r\n }}\r\n >\r\n Delete\r\n \r\n
\r\n
\r\n )}\r\n \r\n )\r\n}\r\n","import { Badge, Tab, TabList, TabPanel, Tabs } from '@finviz/website'\r\nimport React from 'react'\r\nimport { useSearchParams } from 'react-router-dom'\r\n\r\nimport { getInstrument } from '../../utils/chart'\r\nimport fetchApi from '../../utils/fetch_api'\r\nimport IdeaItem from './IdeaItem'\r\nimport { IIdea, IIdeaCategory, categorizeIdeas } from './utils'\r\n\r\nexport default function IdeasTabs() {\r\n const [hasError, setHasError] = React.useState(false)\r\n const [hasFetched, setHasFetched] = React.useState(false)\r\n const [categorizedIdeas, setCategorizedIdeas] = React.useState([])\r\n const [params] = useSearchParams()\r\n const queryTickers = params.get('t')!.split(',') // there always be some t param defined\r\n\r\n React.useEffect(() => {\r\n async function fetchIdeas() {\r\n window.gtag?.('event', 'load', { event_category: 'ideas' })\r\n try {\r\n const data = await fetchApi({ location: '/api/ideas_load.ashx', throwOnStatusCodes: [404] })\r\n const ideas = data.ideas.map((idea: IIdea) => {\r\n const dateParts = idea.date.split(' ')\r\n return {\r\n ...idea,\r\n instrument: getInstrument(idea.ticker),\r\n date: dateParts[0].replace('-', ' ').replace('-', ', '),\r\n time: dateParts[1],\r\n }\r\n })\r\n\r\n setCategorizedIdeas(categorizeIdeas(ideas, queryTickers))\r\n setHasFetched(true)\r\n } catch {\r\n setHasError(true)\r\n }\r\n }\r\n\r\n fetchIdeas()\r\n\r\n // run only on mount\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [])\r\n\r\n const handleIdeaDeleted = (idea: IIdea) => {\r\n setCategorizedIdeas((prev) => {\r\n const modifiedCategories = [...prev]\r\n\r\n // remove from specific ticker category\r\n const categoryIndex = modifiedCategories.findIndex((c) => c.ticker === idea.ticker)\r\n if (categoryIndex >= 0) {\r\n const updatedCategory = {\r\n ...modifiedCategories[categoryIndex],\r\n ideas: modifiedCategories[categoryIndex].ideas.filter((i) => i.id !== idea.id),\r\n }\r\n modifiedCategories[categoryIndex] = updatedCategory\r\n }\r\n\r\n // remove from all\r\n const updatedAll = {\r\n ...modifiedCategories[0],\r\n ideas: modifiedCategories[0].ideas.filter((i) => i.id !== idea.id),\r\n }\r\n modifiedCategories[0] = updatedAll\r\n\r\n // remove empty categories\r\n return modifiedCategories.filter((c) => c.ideas.length !== 0)\r\n })\r\n }\r\n\r\n if (!hasFetched || hasError) {\r\n return (\r\n
\r\n {hasError ? 'Unexpected error occurred, please refresh the page.' : 'Loading…'}\r\n
\r\n )\r\n }\r\n\r\n if (categorizedIdeas.length === 0) {\r\n return (\r\n \r\n No saved ideas.\r\n \r\n )\r\n }\r\n\r\n return (\r\n \r\n \r\n {categorizedIdeas.map((category) => (\r\n {category.ideas.length}}>\r\n {category.ticker}\r\n \r\n ))}\r\n \r\n {categorizedIdeas.map((category) => (\r\n \r\n
\r\n {category.ideas.map((idea) => (\r\n \r\n ))}\r\n
\r\n \r\n ))}\r\n
\r\n )\r\n}\r\n","import { Dialog, DialogBody, DialogHeader, DialogStateReturn } from '@finviz/website'\r\n\r\nimport IdeasTabs from './IdeasTabs'\r\n\r\ntype IdeasDialogProps = {\r\n state: DialogStateReturn\r\n}\r\n\r\nexport default function IdeasDialog({ state }: IdeasDialogProps) {\r\n return (\r\n \r\n Your Ideas\r\n \r\n \r\n \r\n \r\n )\r\n}\r\n","import {\r\n Button,\r\n ButtonComponentProps,\r\n ButtonProps,\r\n Dropdown,\r\n DropdownItem,\r\n Spinner,\r\n Tooltip,\r\n TooltipTrigger,\r\n useDialogState,\r\n useDropdownState,\r\n useTooltipState,\r\n} from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport * as React from 'react'\r\n\r\nimport IdeasDialog from '../../modals/ideas/Ideas'\r\nimport { saveIdea } from '../../modals/ideas/utils'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport Quote from '../../models/quote'\r\nimport { getIsMobileScreenSize } from '../../utils'\r\nimport { encodeQueryString } from '../../utils/query_string'\r\n\r\ninterface IdeaDropdownProps {\r\n model: ChartLayout\r\n rounding?: 'none' | 'regular'\r\n theme?: ButtonProps['theme']\r\n size?: ButtonProps['size']\r\n dropdownButtonClassName?: string\r\n}\r\n\r\nexport function IdeasDropdown({\r\n model,\r\n rounding,\r\n dropdownButtonClassName,\r\n ...props\r\n}: React.PropsWithChildren) {\r\n const tooltipState = useTooltipState({ placement: 'right-start' })\r\n const [isAnyQuoteLoading, setIsAnyQuoteLoading] = React.useState(false)\r\n const ref = React.useRef(null)\r\n const dialog = useDialogState()\r\n const dropdown = useDropdownState()\r\n const hideTooltip = tooltipState.hide\r\n\r\n const dropdownItemProps = isAnyQuoteLoading\r\n ? ({\r\n as: TooltipTrigger,\r\n state: tooltipState,\r\n } as ButtonComponentProps)\r\n : ({} as ButtonComponentProps)\r\n\r\n React.useEffect(() => {\r\n const checkIfAnyQuoteIsLoading = () => {\r\n const fetchingQuotes = Quote.select((quote) => quote.isFetching && quote.fetchedAt === -1)\r\n setIsAnyQuoteLoading(fetchingQuotes.length > 0)\r\n }\r\n\r\n Quote.bind('change', checkIfAnyQuoteIsLoading)\r\n return () => {\r\n Quote.unbind('change', checkIfAnyQuoteIsLoading)\r\n }\r\n }, [])\r\n\r\n React.useEffect(() => {\r\n if (!isAnyQuoteLoading || !dropdown.visible) {\r\n hideTooltip()\r\n }\r\n }, [isAnyQuoteLoading, dropdown.visible, hideTooltip])\r\n\r\n if (!window.FinvizSettings.hasUserPremium) {\r\n return (\r\n \r\n )\r\n }\r\n\r\n return (\r\n <>\r\n \r\n }\r\n >\r\n {\r\n if (isAnyQuoteLoading) {\r\n tooltipState.show()\r\n return\r\n }\r\n saveIdea(model)\r\n }}\r\n >\r\n Save idea\r\n \r\n dialog.show()}>\r\n Load idea\r\n \r\n \r\n \r\n {isAnyQuoteLoading && (\r\n \r\n
\r\n \r\n
\r\n \r\n Some data is still loading. Please wait.\r\n \r\n
\r\n )}\r\n \r\n )\r\n}\r\n","import { Button, ButtonComponentProps, Delayed, Icon, Spinner, useDialogState } from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport * as React from 'react'\r\n\r\nimport { publishModalAsyncModule } from '../../modals/publish/async-modules'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { useAsyncModule } from '../../utils/async-modules-utils'\r\n\r\ninterface PublishProps extends Pick {\r\n model: ChartLayout\r\n}\r\n\r\nexport function Publish({ model, ...props }: React.PropsWithChildren) {\r\n const dialog = useDialogState()\r\n const isDialogOpen = dialog.useState('open')\r\n const [publishModalModule, { isLoading }] = useAsyncModule({\r\n ...publishModalAsyncModule,\r\n shouldLoadModule: isDialogOpen,\r\n errorSeverity: 'medium',\r\n onError: () => dialog.hide(),\r\n })\r\n const PublishDialog = publishModalModule?.default\r\n\r\n return (\r\n <>\r\n dialog.show()}\r\n leftContent={\r\n isLoading ? (\r\n \r\n }\r\n >\r\n \r\n \r\n ) : (\r\n 'share'\r\n )\r\n }\r\n />\r\n {PublishDialog && }\r\n \r\n )\r\n}\r\n","import {\r\n Button,\r\n ButtonSizeType,\r\n ButtonThemeType,\r\n Delayed,\r\n Icon,\r\n Spinner,\r\n TourDefinition,\r\n useTour,\r\n} from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport * as React from 'react'\r\n\r\nimport { SpecificChartFunctionality } from '../../constants/common'\r\nimport { getRequestFullscreen, isRedesignEnabled } from '../../utils'\r\nimport { encodeQueryString } from '../../utils/query_string'\r\n\r\nconst isPremium = window.FinvizSettings.hasUserPremium\r\n\r\n// If we need to update / discontinue some tour we can use skip flag on legacy version to ensure that it won't reset users tour but won't include it in new tours\r\nfunction getTour(page: SpecificChartFunctionality): TourDefinition[] {\r\n return [\r\n {\r\n id: 'chart-tour',\r\n steps: [\r\n {\r\n title: 'Chart Tour',\r\n body: 'Discover powerful Chart features in the 2-min tour to master your analysis of trading opportunities.',\r\n },\r\n ...(isPremium\r\n ? [\r\n {\r\n title: 'Scale the Timeline',\r\n body: 'Grab the timeline to zoom it in and out. Double-click the timeline to reset the scaling.',\r\n target: '[data-testid=\"chart-0-pane-0-zoomer\"]',\r\n },\r\n {\r\n title: 'Scale the Price Axis',\r\n body: 'Grab the Price Axis to zoom it in and out. Move the chart around freely in any direction when Price Axis has custom scale. Double-click the Price Axis to reset the scaling.',\r\n target: '[data-testid=\"chart-0-pane-0-scaler\"]',\r\n },\r\n {\r\n title: 'Drawing tools & settings',\r\n body: 'Pick any Drawing Tool to analyze the market. Tailor your drawing experience with additional settings.',\r\n target: '#toolbar',\r\n },\r\n {\r\n title: 'Fine-tune Drawings',\r\n body: 'Double-click on a chart drawing to tweak its color and style. Right-click on a drawing to access other options, such as changing its visibility, order, and more.',\r\n target: '[data-testid=\"chart-0-pane-0\"]',\r\n },\r\n ]\r\n : [\r\n {\r\n title: 'Enable Drawing mode',\r\n body: (\r\n <>\r\n \r\n Finviz*Elite\r\n {' '}\r\n subscribers get access a whole suite of drawing tools which allow them to draw on and annotate the\r\n chart.
\r\n While in drawing mode, you can also pan the chart, scale the timeline and price axis and much more.\r\n \r\n ),\r\n target: '[data-testid=\"quote-toggle-draw-btn\"]',\r\n placement: 'bottom-start',\r\n },\r\n ]),\r\n {\r\n title: 'Save your best Ideas',\r\n body: isPremium\r\n ? 'Besides your drawings being autosaved, you can manually save ideas that you wish to revisit later.'\r\n : 'Your drawings will be saved automatically, but you can also manually save ideas that you wish to revisit later.',\r\n target: '[data-testid=\"chart-toolbar-ideas\"]',\r\n placement: 'bottom-start',\r\n },\r\n ...(page === SpecificChartFunctionality.quotePage\r\n ? []\r\n : [\r\n {\r\n title: 'Chart Layouts & Charts Sync',\r\n body: 'Switch between Chart Layouts to view multiple charts on your screen. Synchronize Ticker, Timeframe or Crosshair position across your charts.',\r\n target: '[data-testid=\"chart-layout-layout\"]',\r\n },\r\n ]),\r\n ...(!getRequestFullscreen(document.documentElement) && page === SpecificChartFunctionality.chartPage\r\n ? []\r\n : [\r\n {\r\n title: 'Fullscreen mode',\r\n body:\r\n page === SpecificChartFunctionality.quotePage\r\n ? 'Open the chart in an expanded view for full-page display and split-screen charts.'\r\n : 'Toggle the window to fill your entire screen.',\r\n target: '[data-testid=\"chart-layout-fullscreen\"]',\r\n placement: page === SpecificChartFunctionality.chartPage ? 'bottom' : 'bottom-end',\r\n },\r\n ]),\r\n {\r\n title: 'Share chart',\r\n body: 'Share a chart together with your analysis and ideas.',\r\n target: '[data-testid=\"chart-toolbar-publish\"]',\r\n overlayPadding: page === SpecificChartFunctionality.quotePage ? 3 : undefined,\r\n placement: 'bottom',\r\n },\r\n ...(isRedesignEnabled() || page === SpecificChartFunctionality.chartPage\r\n ? [\r\n {\r\n title: 'Theme',\r\n body: 'Switch between the Light and Dark theme.',\r\n target: '[data-testid=\"chart-layout-theme\"]',\r\n },\r\n ]\r\n : []),\r\n {\r\n title: 'Study Settings',\r\n body: 'Customize the Chart Type and appearance. Add Overlays, Indicators and toggle Extended Hours.',\r\n target: '[data-testid=\"chart-settings-open-btn\"]',\r\n placement: page === SpecificChartFunctionality.chartPage ? 'bottom' : 'bottom-end',\r\n },\r\n ],\r\n },\r\n page === SpecificChartFunctionality.chartPage && {\r\n id: 'sidebar-watchlist',\r\n steps: [\r\n {\r\n title: 'Explore Your Portfolios',\r\n body: 'Effortlessly navigate through your portfolio holdings. With just a click, visualize individual stock charts, gain insights, and stay updated on your investments.',\r\n target: '[data-testid=\"sidebar-portfolio-btn\"]',\r\n placement: 'left-start',\r\n },\r\n ],\r\n },\r\n ].filter(Boolean) as TourDefinition[]\r\n}\r\n\r\ninterface TourButtonProps {\r\n page: SpecificChartFunctionality\r\n rounding?: 'none' | 'regular'\r\n size?: ButtonSizeType\r\n theme?: ButtonThemeType\r\n className?: string\r\n}\r\n\r\nexport function TourButton({ page, className, theme, ...props }: React.PropsWithChildren) {\r\n const tour = useTour()\r\n const pageTours = getTour(page)\r\n const [userTour, setCurrentTour] = React.useState(tour.getStepsForUser(pageTours))\r\n const buttonTheme: ButtonThemeType = userTour.hasNewTours ? 'blue' : theme ?? 'headerItem'\r\n\r\n return (\r\n \r\n }\r\n >\r\n \r\n \r\n ) : (\r\n \r\n )\r\n }\r\n className={className}\r\n contentClass={page !== SpecificChartFunctionality.quotePage ? 'hidden lg:flex' : ''}\r\n title=\"Explore new features\"\r\n onClick={async () => {\r\n if (userTour) {\r\n const activeTour = await tour.startTour(userTour.tour)\r\n activeTour?.once('inactive', () => {\r\n setCurrentTour(tour.getStepsForUser(pageTours))\r\n })\r\n }\r\n }}\r\n />\r\n )\r\n}\r\n","import * as dateFns from 'date-fns'\r\n\r\nimport { getChartStartEndDates } from '../controllers/renderUtils'\r\nimport Quote from '../models/quote'\r\n\r\n// **************START**************\r\n// Functions from here until END have to be in sync with\r\n// Finviz-Website: components/timeframe-bar/custom-date-range-utils.ts\r\n// *********************************\r\n\r\nexport enum CustomDateRangePrefixEnum {\r\n Range = 'range',\r\n Prev = 'prev',\r\n}\r\n\r\nexport const CUSTOM_DATE_RANGE = 'custom'\r\nexport const DATE_RANGE_PREFIX_DELMITER = '_'\r\nconst CUSTOM_DATE_RANGE_DELIMITER = 'x'\r\nconst CUSTOM_PREV_RANGE_DELIMITER = '-'\r\n\r\nexport function getParsedDateRange(dateRange: string) {\r\n return dateRange.split(DATE_RANGE_PREFIX_DELMITER)\r\n}\r\n\r\nexport function parseCustomDateRangeUrlParam({ dateRange, anchorDate }: { dateRange: string; anchorDate: Date }) {\r\n const [dateRangePrefix, dateRangeValue] = getParsedDateRange(dateRange)\r\n\r\n if (dateRangePrefix === CustomDateRangePrefixEnum.Range) {\r\n const [dateFromString, dateToString] = dateRangeValue.replace(/-/g, '/').split(CUSTOM_DATE_RANGE_DELIMITER)\r\n const dateFrom = dateFromString ? new Date(dateFromString) : null\r\n const dateTo = dateToString ? new Date(dateToString) : null\r\n return {\r\n start: dateFrom && !Number.isNaN(dateFrom.getTime()) ? dateFrom : null,\r\n end: dateTo && !Number.isNaN(dateTo.getTime()) ? dateFns.endOfDay(dateTo) : null,\r\n }\r\n }\r\n\r\n if (dateRangePrefix === CustomDateRangePrefixEnum.Prev) {\r\n const [years, months, days] = dateRangeValue.split(CUSTOM_PREV_RANGE_DELIMITER).map(Number)\r\n\r\n if ([years, months, days].some(Number.isNaN)) {\r\n return { start: null, end: null }\r\n }\r\n\r\n return {\r\n start: dateFns.startOfDay(dateFns.sub(anchorDate, { years, months, days: days - 1 })),\r\n end: anchorDate,\r\n }\r\n }\r\n\r\n return { start: null, end: anchorDate }\r\n}\r\n\r\n// **************END**************\r\n// Functions below don't need to be\r\n// in sync with Website repository\r\n// *******************************\r\n\r\nexport function getParsedDateRangeMetaData({ dateRange, quote }: { dateRange: string; quote: Quote }) {\r\n const parsedRange = getChartStartEndDates({ dateRange, quote })\r\n const [dateRangePrefix] = getParsedDateRange(dateRange)\r\n\r\n let startQuoteDate: Date | null = null\r\n let endQuoteDate: Date | null = null\r\n let numOfDaysToRender: number | null = null\r\n\r\n if (parsedRange.start && dateRangePrefix === CustomDateRangePrefixEnum.Prev) {\r\n const daysInQuote = quote.getDaysInQuote()\r\n const reversedDaysInQuote = [...daysInQuote].reverse()\r\n const startQuoteDayIndex = reversedDaysInQuote.findIndex((date) => date.getTime() <= parsedRange.start!.getTime())\r\n const endQuoteDayIndex = reversedDaysInQuote.findIndex((date) => date.getTime() <= parsedRange.end!.getTime())\r\n startQuoteDate = reversedDaysInQuote[startQuoteDayIndex] ?? null\r\n endQuoteDate = reversedDaysInQuote[endQuoteDayIndex] ?? null\r\n numOfDaysToRender = quote.interval <= 5 ? startQuoteDayIndex - endQuoteDayIndex + 1 : null\r\n }\r\n\r\n return {\r\n start: parsedRange.start,\r\n end: parsedRange.end,\r\n startQuoteDate,\r\n endQuoteDate,\r\n numOfDaysToRender,\r\n numOfBarsToRender: (numOfDaysToRender ?? 0) * (quote.getBarsInDay() ?? 0) || undefined,\r\n renderDateStart: parsedRange.start && dateFns.startOfDay(parsedRange.start),\r\n renderDateEnd: parsedRange.end && dateFns.endOfDay(parsedRange.end),\r\n }\r\n}\r\n","import * as d3 from 'd3'\r\nimport * as dateFns from 'date-fns'\r\n\r\nimport { Instrument, ObjectHash } from '../../types/shared'\r\nimport {\r\n CHART_MARGIN,\r\n DateRangeType,\r\n PREMARKET_AFTERMARKET_HOURS,\r\n ScaleType,\r\n SpecificChartFunctionality,\r\n TIMEFRAME,\r\n} from '../constants/common'\r\nimport Chart from '../models/chart'\r\nimport ChartEventElement from '../models/chart-event-element'\r\nimport ChartLayout from '../models/chart_layout'\r\nimport { IChartSettings, IIndicatorSettings, ISettings } from '../models/chart_settings/interfaces'\r\nimport { CHART_EVENT_BADGE_SIZE } from '../models/constants'\r\nimport Element from '../models/element'\r\nimport Pane, { ScaleAxis } from '../models/pane'\r\nimport Quote from '../models/quote'\r\nimport Utils from '../utils'\r\nimport utils, { convertLocalToNyTime, dateFromUnixTimestamp, isRedesignedPage } from '../utils'\r\nimport { getBarWidthWithMargin, getZoomFactorForBarsToDisplay } from '../utils/chart'\r\nimport {\r\n DATE_RANGE_PREFIX_DELMITER,\r\n getParsedDateRangeMetaData,\r\n parseCustomDateRangeUrlParam,\r\n} from '../utils/chart-date-range-utils'\r\n\r\ninterface VisibleBarNumberProps {\r\n start: Date | null\r\n end: Date\r\n quote: Quote\r\n dateRange: string\r\n}\r\n\r\ninterface ChartZoomAndLeftOffsetProps extends Omit {\r\n chartVisibleWidth: number\r\n numOfBarsToRender?: number\r\n chartModel: Chart\r\n}\r\n\r\ninterface ChartStartEndDatesProps {\r\n dateRange: string\r\n quote: Quote\r\n}\r\n\r\nexport const getVisibleBarsNumber = ({ start, end, quote, dateRange }: VisibleBarNumberProps) => {\r\n const startInSec = start ? start.getTime() / 1000 : 0\r\n const endInSec = end.getTime() / 1000\r\n const isQuoteDateInRange = (quoteDate: number) => quoteDate >= startInSec && quoteDate <= endInSec\r\n const lastQuoteDateIndex = quote.barIndex[quote.barIndex.length - 1]\r\n let lastVisibleBarIndex = lastQuoteDateIndex\r\n let numOfVisibleBars = 0\r\n if (\r\n [DateRangeType.d1, DateRangeType.d5].includes(dateRange as DateRangeType) &&\r\n quote.instrument === Instrument.Stock\r\n ) {\r\n numOfVisibleBars = quote.drawMinutesPerDay\r\n } else {\r\n let firstVisibleBarIndex = -1\r\n lastVisibleBarIndex = -1\r\n quote.date.forEach((quoteDate, index) => {\r\n if (isQuoteDateInRange(quoteDate)) {\r\n if (firstVisibleBarIndex === -1) {\r\n firstVisibleBarIndex = quote.barIndex[index]\r\n }\r\n lastVisibleBarIndex = quote.barIndex[index]\r\n }\r\n })\r\n numOfVisibleBars = lastVisibleBarIndex - firstVisibleBarIndex + 1\r\n\r\n if (firstVisibleBarIndex === -1 && lastVisibleBarIndex === -1) {\r\n return { numOfVisibleBars: 0, numOfBarsOffset: 0 }\r\n }\r\n }\r\n\r\n return { numOfVisibleBars, numOfBarsOffset: lastQuoteDateIndex - lastVisibleBarIndex }\r\n}\r\n\r\nexport const getChartZoomAndLeftOffset = ({\r\n chartVisibleWidth,\r\n start,\r\n end,\r\n quote,\r\n chartModel,\r\n numOfBarsToRender,\r\n}: ChartZoomAndLeftOffsetProps) => {\r\n const { numOfVisibleBars, numOfBarsOffset } = getVisibleBarsNumber({\r\n start,\r\n end,\r\n quote,\r\n dateRange: chartModel.dateRange,\r\n })\r\n if (numOfVisibleBars === 0) {\r\n return { zoomFactor: chartModel.zoomFactor, leftOffset: chartModel.leftOffset }\r\n }\r\n\r\n const chartLayout = chartModel.chart_layout()\r\n const zoomFactor = getZoomFactorForBarsToDisplay({\r\n chartLayout,\r\n chartVisibleWidth,\r\n numOfVisibleBars: numOfBarsToRender ?? numOfVisibleBars,\r\n })\r\n const barWidth = getBarWidthWithMargin({ chartLayout, zoomFactor })\r\n const leftOffset =\r\n getLeftOffset({\r\n quote,\r\n chartModel,\r\n config: {},\r\n barWidth,\r\n numberOfBarsToDraw: numOfBarsToRender,\r\n }) +\r\n numOfBarsOffset * barWidth\r\n return { zoomFactor, leftOffset }\r\n}\r\n\r\nexport const getChartStartEndDates = ({ dateRange, quote }: ChartStartEndDatesProps) => {\r\n const daysInQuote = quote.getDaysInQuote()\r\n const lastDate = dateFromUnixTimestamp(quote.date[quote.date.length - 1])\r\n\r\n if (dateRange.includes(DATE_RANGE_PREFIX_DELMITER)) {\r\n const range = parseCustomDateRangeUrlParam({ dateRange, anchorDate: lastDate })\r\n const end = convertLocalToNyTime(\r\n range.end && range.end.getTime() <= lastDate.getTime() ? range.end : lastDate,\r\n false\r\n )\r\n return {\r\n start: range.start && convertLocalToNyTime(range.start, false),\r\n end,\r\n }\r\n }\r\n\r\n let start\r\n // No condition is needed here, but this would be dateRangePrefix === DateRangePrefixEnum.Enum\r\n switch (dateRange) {\r\n case DateRangeType.d1:\r\n lastDate.setHours(23, 59, 59, 999)\r\n start = daysInQuote.length === 0 ? lastDate : daysInQuote[daysInQuote.length - 1]\r\n break\r\n case DateRangeType.d5:\r\n lastDate.setHours(23, 59, 59, 999)\r\n const startDateIndex = daysInQuote.length === 0 ? -1 : Math.max(daysInQuote.length - 5, 0)\r\n start = startDateIndex === -1 ? lastDate : daysInQuote[startDateIndex]\r\n break\r\n case DateRangeType.m1:\r\n start = dateFns.subMonths(lastDate, 1)\r\n break\r\n case DateRangeType.m3:\r\n start = dateFns.subMonths(lastDate, 3)\r\n break\r\n case DateRangeType.m6:\r\n start = dateFns.subMonths(lastDate, 6)\r\n break\r\n case DateRangeType.ytd:\r\n start = dateFns.startOfYear(lastDate)\r\n break\r\n case DateRangeType.y1:\r\n start = dateFns.subYears(lastDate, 1)\r\n break\r\n case DateRangeType.y2:\r\n start = dateFns.subYears(lastDate, 2)\r\n break\r\n case DateRangeType.y5:\r\n start = dateFns.subYears(lastDate, 5)\r\n break\r\n case DateRangeType.max:\r\n default:\r\n start = null\r\n break\r\n }\r\n\r\n return { start: start && convertLocalToNyTime(start, false), end: convertLocalToNyTime(lastDate, false) }\r\n}\r\n\r\ninterface GetLeftOffsetProps {\r\n quote: Quote\r\n chartModel: Chart\r\n config?: { stretch?: boolean }\r\n barWidth?: number\r\n barIndex?: number\r\n numberOfBarsToDraw?: number\r\n shouldAlignDaysToLeftApplied?: boolean\r\n}\r\n\r\nexport const getMinMaxLeftOffset = ({\r\n newLeftOffset,\r\n chartModel,\r\n barWidth = getBarWidthWithMargin({ zoomFactor: chartModel.zoomFactor, chartLayout: chartModel.chart_layout() }),\r\n barIndex,\r\n}: {\r\n newLeftOffset: number\r\n chartModel: Chart\r\n barWidth?: number\r\n barIndex: number\r\n}) => {\r\n const { ChartSettings } = chartModel.getChartLayoutSettings()\r\n const width = chartModel.width - ChartSettings.left.width - ChartSettings.right.width\r\n const numOfBarsInView = Math.floor(width / barWidth)\r\n const fx = (index: number) => index * barWidth\r\n return ~~Utils.min(barWidth / 2, Utils.max(newLeftOffset, width - fx(barIndex + numOfBarsInView)))\r\n}\r\n\r\nexport function getFullChartWidth({\r\n hasAftermarket,\r\n hasPremarket,\r\n timeframeMinutes,\r\n barWidthWithMargin,\r\n}: {\r\n hasPremarket: boolean\r\n hasAftermarket: boolean\r\n timeframeMinutes: number\r\n barWidthWithMargin: number\r\n}) {\r\n const premarketHoursLength = hasPremarket ? PREMARKET_AFTERMARKET_HOURS : 0\r\n const aftermarketHoursLength = hasAftermarket ? PREMARKET_AFTERMARKET_HOURS : 0\r\n const marketMinutesLength = (6.5 + premarketHoursLength + aftermarketHoursLength) * 60\r\n // CHART_MARGIN.L as left offset + CHART_MARGIN.XXL as right offset\r\n return CHART_MARGIN.L + CHART_MARGIN.XXL + (marketMinutesLength / timeframeMinutes) * barWidthWithMargin\r\n}\r\n\r\nexport function getIntradayChartConfig({\r\n timeframeMinutes,\r\n barWidthWithMargin,\r\n hasPremarket,\r\n hasAftermarket,\r\n maxWidth,\r\n canCropChart,\r\n}: {\r\n hasPremarket: boolean\r\n hasAftermarket: boolean\r\n timeframeMinutes: number\r\n barWidthWithMargin: number\r\n maxWidth: number\r\n canCropChart: boolean\r\n}) {\r\n const fullChartWidth = getFullChartWidth({ hasPremarket, hasAftermarket, barWidthWithMargin, timeframeMinutes })\r\n const offsetChartAfter = 16 // Int from 0-23 , if last quote date is >= this constant `offsetInPx` is applied (chart is moved to the left)\r\n const cropChartMinutesLength = PREMARKET_AFTERMARKET_HOURS * 60\r\n const offsetInPx = (cropChartMinutesLength / timeframeMinutes) * barWidthWithMargin\r\n const chartWidthWithOffset = fullChartWidth - offsetInPx\r\n const shouldCropChart =\r\n canCropChart && hasAftermarket && hasPremarket && maxWidth >= chartWidthWithOffset && maxWidth < fullChartWidth\r\n\r\n return {\r\n fullChartWidth,\r\n offsetInPx: shouldCropChart ? offsetInPx : 0,\r\n chartWidthWithOffset: shouldCropChart ? fullChartWidth - offsetInPx : fullChartWidth,\r\n offsetChartAfter,\r\n }\r\n}\r\n\r\nexport const getLeftOffset = ({\r\n quote,\r\n chartModel,\r\n config,\r\n barWidth = getBarWidthWithMargin({ zoomFactor: chartModel.zoomFactor, chartLayout: chartModel.chart_layout() }),\r\n barIndex = getBarIndex(quote),\r\n numberOfBarsToDraw,\r\n shouldAlignDaysToLeftApplied = true,\r\n}: GetLeftOffsetProps) => {\r\n const { ChartSettings } = chartModel.getChartLayoutSettings()\r\n const width = chartModel.width - ChartSettings.left.width - ChartSettings.right.width\r\n const specificChartFunctionality = chartModel.chart_layout().specificChartFunctionality\r\n if (config?.stretch) {\r\n return 0\r\n }\r\n if (getIsSmallIndexChart(specificChartFunctionality)) {\r\n return barWidth\r\n }\r\n const fx = (index: number) => index * barWidth\r\n let leftOffset = width - fx(barIndex) - Math.round(barWidth / 2)\r\n leftOffset = Math.round(Utils.min(barWidth / 2, Utils.max(leftOffset, width - fx(barIndex + 45))))\r\n if (\r\n shouldAlignDaysToLeftApplied &&\r\n shouldAlignDaysToLeft({\r\n quote,\r\n numberOfBarsToDraw,\r\n specificChartFunctionality,\r\n dateRange: chartModel.dateRange,\r\n })\r\n ) {\r\n let drawDaysInOneChart = 1\r\n if (numberOfBarsToDraw) {\r\n drawDaysInOneChart = Math.ceil(numberOfBarsToDraw / quote.getBarsInDay()!)\r\n } else if (quote.interval === 10 || chartModel.dateRange === DateRangeType.d5) {\r\n drawDaysInOneChart = 5\r\n } else if (quote.interval === 15) {\r\n drawDaysInOneChart = 6\r\n } else if (quote.interval === 30) {\r\n drawDaysInOneChart = 12\r\n } else if (quote.interval === 60) {\r\n drawDaysInOneChart = 22\r\n } else if (quote.interval === 120) {\r\n drawDaysInOneChart = 39\r\n } else if (quote.interval === 240) {\r\n drawDaysInOneChart = 78\r\n } else if (quote.interval > 240) {\r\n drawDaysInOneChart = (quote.interval / 30) * 10\r\n }\r\n const { offsetInPx, offsetChartAfter } = getIntradayChartConfig({\r\n hasPremarket: quote.premarket,\r\n hasAftermarket: quote.aftermarket,\r\n barWidthWithMargin: barWidth,\r\n timeframeMinutes: quote.interval,\r\n maxWidth: chartModel.width,\r\n canCropChart: !chartModel.dateRange,\r\n })\r\n const drawDaysWidth = drawDaysInOneChart * quote.getBarsInDay()! * barWidth - offsetInPx\r\n\r\n // +1 is a buffer as it often happens drawDaysWidth is wider than width by tiny amount (< 1/10000 of px)\r\n if (drawDaysWidth <= width + 1) {\r\n const lastQuoteDate = quote.date.last() ? utils.dateFromUnixTimestamp(quote.date.last()!) : null\r\n // Align start of day to left if we have enough space to show all bars in day\r\n const barsToOffset = (Object.keys(quote.getDayToOffset()).length - drawDaysInOneChart) * quote.getBarsInDay()!\r\n const offsetChartInPx = (lastQuoteDate?.getHours() ?? 0) >= offsetChartAfter ? offsetInPx : 0\r\n // Math.max(1, ~~num) is to mimic imlementation from getHalfBarWidth(),\r\n // we never render bar with width < 1 but at the same time when we have and odd\r\n // width like 5, wa want to floor because of pixel perfect rendering\r\n leftOffset = Math.round(-fx(barsToOffset) + Math.max(1, ~~(barWidth / 2))) - offsetChartInPx\r\n }\r\n }\r\n // getMinMaxLeftOffset move left offset to keep at least one bar in view what isn't desired for offscreen charts\r\n if (specificChartFunctionality === SpecificChartFunctionality.offScreen) {\r\n return leftOffset\r\n }\r\n return getMinMaxLeftOffset({\r\n newLeftOffset: leftOffset,\r\n chartModel,\r\n barWidth,\r\n barIndex,\r\n })\r\n}\r\n\r\nexport const getBarIndex = (quote: Quote) => quote?.getBarIndex(quote.open?.length ? quote.open.length - 1 : 0) || 0\r\n\r\nexport const getIsSmallIndexChart = (specificChartFunctionality: SpecificChartFunctionality) =>\r\n specificChartFunctionality === SpecificChartFunctionality.smallIndex\r\n\r\ninterface ShouldAlignDaysToLeftProps {\r\n quote: Quote\r\n numberOfBarsToDraw?: number\r\n specificChartFunctionality: SpecificChartFunctionality\r\n dateRange: DateRangeType | null\r\n}\r\n\r\n/**\r\n * Evaluate if days should be aligned to the left\r\n * @param {object} object.quote - Quote model\r\n * @param {string} object.specificChartFunctionality - SpecificChartFunctionality enum\r\n * @returns {boolean} boolean\r\n * */\r\nexport const shouldAlignDaysToLeft = ({\r\n quote,\r\n dateRange,\r\n numberOfBarsToDraw,\r\n specificChartFunctionality,\r\n}: ShouldAlignDaysToLeftProps) => {\r\n const isStockIntraday = quote.isIntraday && quote.instrument === Instrument.Stock\r\n const isIntradayDateRange = !!dateRange && [DateRangeType.d1, DateRangeType.d5].includes(dateRange)\r\n const isOffScreen = specificChartFunctionality === SpecificChartFunctionality.offScreen\r\n const isOffScreenWithNoDateRange = isOffScreen && !dateRange\r\n const isOffScreenIntradayDateRange = isOffScreen && isIntradayDateRange\r\n const isOffScreenWithFixedBars = isOffScreen && numberOfBarsToDraw\r\n\r\n const isQuotePage = specificChartFunctionality === SpecificChartFunctionality.quotePage\r\n const isQuotePageWithNoDateRange = isQuotePage && !dateRange\r\n const isQuotePageIntradayDateRange = isQuotePage && isIntradayDateRange\r\n const isQuotePageWithFixedBars = isQuotePage && numberOfBarsToDraw\r\n\r\n const isChartPage = specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n const isChartsInradayDateRange = isChartPage && isIntradayDateRange\r\n const isChartPageWithFixedBars = isChartPage && numberOfBarsToDraw\r\n return (\r\n isStockIntraday &&\r\n (isOffScreenWithNoDateRange ||\r\n isOffScreenIntradayDateRange ||\r\n isOffScreenWithFixedBars ||\r\n isQuotePageWithNoDateRange ||\r\n isQuotePageIntradayDateRange ||\r\n isQuotePageWithFixedBars ||\r\n isChartsInradayDateRange ||\r\n isChartPageWithFixedBars)\r\n )\r\n}\r\n\r\ninterface ClipProps {\r\n canvasCtx: RenderingContext2DType\r\n width: number\r\n height: number\r\n Settings: ISettings['ChartSettings'] | ISettings['IndicatorSettings']\r\n}\r\n// pane canvasCtx clip\r\nexport const clip = ({ canvasCtx, width, height, Settings }: ClipProps) => {\r\n const contentWidth = width - Settings.left.width - Settings.right.width\r\n const contentHeight = height - Settings.top.height - Settings.bottom.height\r\n canvasCtx.beginPath()\r\n canvasCtx.rect(Settings.left.width, Settings.top.height, contentWidth, contentHeight)\r\n canvasCtx.clip()\r\n}\r\n\r\nexport const getSettings = (paneModel: Pane): IIndicatorSettings | IChartSettings => {\r\n const { ChartSettings, IndicatorSettings } = paneModel.chart().getChartLayoutSettings()\r\n for (const element of paneModel.elements().all()) {\r\n if (element.isIndicator()) {\r\n return IndicatorSettings\r\n }\r\n }\r\n return ChartSettings\r\n}\r\n\r\ninterface RecountScaleProps {\r\n chartModel: Chart\r\n paneModel: Pane\r\n}\r\n\r\ntype ScaledFn = Partial & (d3.ScaleLinear | d3.ScaleSymLog)\r\n\r\nconst getShouldOffsetChartDomain = (elementModel: Element | ChartEventElement) => {\r\n const quote = elementModel.pane().chart().quote()\r\n\r\n return quote.chartEvents.length > 0 && ![TIMEFRAME.w, TIMEFRAME.m].includes(quote.timeframe)\r\n}\r\n\r\nexport const recountScale = ({ chartModel, paneModel }: RecountScaleProps) => {\r\n const { ChartSettings, IndicatorSettings, MarketSentimentSettings } = chartModel.getChartLayoutSettings()\r\n const chartLayout = chartModel.chart_layout()\r\n const barWidthWithMargin = getBarWidthWithMargin({ chartLayout, zoomFactor: chartModel.zoomFactor })\r\n for (const elementModel of [...paneModel.getAllElements(), ...paneModel.getAllChartEvents(false)]) {\r\n const el = elementModel.instance\r\n const isChart = elementModel.isChart()\r\n if (isChart || elementModel.isIndicator()) {\r\n let fx: ScaledFn, Settings: ISettings['MarketSentimentSettings' | 'ChartSettings' | 'IndicatorSettings'], width\r\n const scaleType = isChart ? chartModel.scale : ScaleType.Linear\r\n if (isChart) {\r\n Settings = chartModel.instrument === Instrument.MarketSentiment ? MarketSentimentSettings : ChartSettings\r\n } else {\r\n Settings = IndicatorSettings as ISettings['IndicatorSettings']\r\n }\r\n const contentHeight = paneModel.height - Settings.top.height - Settings.bottom.height\r\n\r\n if (chartModel.stretch) {\r\n width = chartModel.width - Settings.left.width - Settings.right.width\r\n fx = d3\r\n .scaleLinear()\r\n .range([0, width])\r\n .domain([0, Math.max(0, chartModel.quote().close.length - 1)]) as ScaledFn\r\n } else {\r\n fx = ((index: number) => index * barWidthWithMargin) as ScaledFn\r\n fx.invert = (x: number) => x / barWidthWithMargin\r\n fx.width = function (w) {\r\n return this.invert(w) - this.invert(0)\r\n }\r\n }\r\n paneModel.updateAttribute('scale', { x: fx }) // some elements need fx to count getMinMax\r\n\r\n const { min, max } = paneModel.scaleRange || el.getMinMax!()\r\n let fy\r\n\r\n const handleDomainOffset = (currentScale: ScaledFn, scaleCreator: any) => {\r\n if (isChart && getShouldOffsetChartDomain(elementModel)) {\r\n const protectedHeightPx = contentHeight - CHART_EVENT_BADGE_SIZE\r\n const minPx = currentScale(min)\r\n const domain = currentScale.domain()\r\n if (minPx > protectedHeightPx) {\r\n const tempScale = scaleCreator().range([0, protectedHeightPx]).domain([max, min])\r\n const extendedMin = tempScale.invert(contentHeight)\r\n currentScale.domain([domain[0], extendedMin])\r\n }\r\n }\r\n }\r\n\r\n switch (scaleType) {\r\n case ScaleType.Logarithmic:\r\n fy = d3.scaleSymlog().range([0, contentHeight]).domain([max, min]) as ScaledFn\r\n handleDomainOffset(fy, d3.scaleSymlog)\r\n break\r\n default:\r\n fy = d3.scaleLinear().range([0, contentHeight]).domain([max, min]) as ScaledFn\r\n if (!paneModel.scaleRange) {\r\n fy = fy.nice(10)\r\n handleDomainOffset(fy, d3.scaleLinear)\r\n }\r\n break\r\n }\r\n fy.height = function (h: number) {\r\n return this.invert(h) - this.invert(0)\r\n }\r\n paneModel.updateAttribute('scale', {\r\n x: fx,\r\n y: fy,\r\n })\r\n\r\n if (isChart) {\r\n el.setupAxis!(fx as ScaleAxis)\r\n }\r\n break\r\n }\r\n }\r\n}\r\n\r\n// general, only when blurry ends won't be visible or didn't matter\r\nexport const getOffsetFromLineWidth = (lineWidth: number) => (lineWidth % 2 === 0 ? 0 : 0.5)\r\n\r\ninterface IXYOffsetFromLine {\r\n lineWidth: number\r\n x1: number\r\n y1: number\r\n x2: number\r\n y2: number\r\n}\r\n\r\n// return x,y offsets for pixel perfect line rendering\r\nexport const getXYOffsetFromLine = ({ lineWidth, x1, y1, x2, y2 }: IXYOffsetFromLine) => {\r\n // don't add offset is lineWidth is even\r\n if (lineWidth % 2 === 0) {\r\n return { x: 0, y: 0 }\r\n }\r\n if (y1 === y2) {\r\n return { x: 0, y: 0.5 } // horizontal line\r\n } else if (x1 === x2) {\r\n return { x: 0.5, y: 0 } // vertical line\r\n } else {\r\n return { x: 0.5, y: 0.5 } // diagonal line\r\n }\r\n}\r\n\r\nexport const getRoundedObject = (obj: T): T => {\r\n const rounded = Object.entries(obj)\r\n for (let i = 0; i < rounded.length; i++) {\r\n rounded[i][1] = Math.round(rounded[i][1])\r\n }\r\n return Object.fromEntries(rounded) as T\r\n}\r\n\r\ninterface ITranslate {\r\n context: CanvasRenderingContext2D\r\n xOffset: number\r\n yOffset: number\r\n}\r\n\r\ninterface ITranslateObj {\r\n do: () => void\r\n undo: () => void\r\n}\r\n\r\nexport const getTranslate = ({ context, xOffset, yOffset }: ITranslate): ITranslateObj => ({\r\n do: () => context.translate(xOffset, yOffset),\r\n undo: () => context.translate(xOffset * -1, yOffset * -1),\r\n})\r\n\r\ninterface IPercentageScaleValue {\r\n number: number\r\n base: number\r\n}\r\n\r\nexport const getPercentageFromValue = ({ number, base }: IPercentageScaleValue) => ((number - base) / base) * 100\r\n\r\nexport const getValueFromPercentage = ({ number, base }: IPercentageScaleValue) => (number / 100) * base + base\r\n\r\ninterface UpdateZoomAndLeftOffsetByDateRangeProps {\r\n chartModel: Chart\r\n quote: Quote\r\n}\r\n\r\nexport function updateZoomAndLeftOffsetByDateRange({ chartModel, quote }: UpdateZoomAndLeftOffsetByDateRangeProps) {\r\n const { ChartSettings } = chartModel.getChartLayoutSettings()\r\n const chartVisibleWidth = chartModel.width - (ChartSettings.left.width + ChartSettings.right.width)\r\n\r\n const { start, end, numOfBarsToRender } = getParsedDateRangeMetaData({\r\n dateRange: chartModel.dateRange,\r\n quote,\r\n })\r\n\r\n const { zoomFactor, leftOffset } = getChartZoomAndLeftOffset({\r\n chartVisibleWidth,\r\n start,\r\n end,\r\n quote,\r\n numOfBarsToRender,\r\n chartModel: chartModel,\r\n })\r\n\r\n if (chartModel.zoomFactor !== zoomFactor || chartModel.leftOffset !== leftOffset) {\r\n chartModel.updateAttributes({ zoomFactor, leftOffset })\r\n }\r\n}\r\n\r\nexport function renderPane({\r\n chartLayoutModel,\r\n chartModel,\r\n paneModel,\r\n canvasCtx,\r\n shouldRenderCross = false,\r\n}: {\r\n chartLayoutModel: ChartLayout\r\n chartModel: Chart\r\n paneModel: Pane\r\n canvasCtx: CanvasRenderingContext2D\r\n shouldRenderCross?: boolean\r\n}) {\r\n if (paneModel.chart().instrument === Instrument.MarketSentiment) {\r\n canvasCtx.clearRect(0, 0, chartModel.width, paneModel.height)\r\n } else {\r\n canvasCtx.set('fillStyle', chartModel.getChartLayoutSettings().ChartSettings.general.Colors.canvasFill)\r\n canvasCtx.fillRect(0, 0, chartModel.width, paneModel.height)\r\n }\r\n const elements = paneModel.getAllElements()\r\n for (const { instance: elementInstance } of elements) {\r\n if (typeof elementInstance.renderGrid === 'function') {\r\n canvasCtx.save()\r\n elementInstance.renderGrid(canvasCtx)\r\n canvasCtx.restore()\r\n }\r\n }\r\n\r\n const chartEvents = paneModel.getAllChartEvents()\r\n const Settings = getSettings(paneModel)\r\n for (const { instance: elementInstance } of [...elements, ...chartEvents]) {\r\n const isDrawing = elementInstance.getIsDrawing()\r\n const isChartEvent = elementInstance.getIsChartEvent()\r\n\r\n if (isDrawing && (chartLayoutModel.isHideDrawingsActive || !elementInstance.getIsVisible())) {\r\n continue\r\n } else if ((isDrawing || isChartEvent) && !elementInstance.getIsInChartView(chartModel)) {\r\n continue\r\n }\r\n\r\n canvasCtx.save()\r\n if (elementInstance.renderContent != null) {\r\n canvasCtx.save()\r\n clip({\r\n canvasCtx,\r\n width: chartModel.width,\r\n height: paneModel.height,\r\n Settings,\r\n })\r\n canvasCtx.translate(paneModel.chart().leftOffset + Settings.left.width, Settings.top.height)\r\n elementInstance.renderContent(canvasCtx)\r\n canvasCtx.restore()\r\n if (typeof elementInstance.renderLabels === 'function') {\r\n elementInstance.renderLabels(canvasCtx)\r\n }\r\n } else {\r\n elementInstance.render(canvasCtx)\r\n }\r\n if (\r\n shouldRenderCross &&\r\n (chartLayoutModel.specificChartFunctionality === SpecificChartFunctionality.chartPage ||\r\n isRedesignedPage(chartLayoutModel)) &&\r\n elementInstance.renderCross != null\r\n ) {\r\n elementInstance.renderCross(canvasCtx)\r\n }\r\n canvasCtx.restore()\r\n }\r\n}\r\n","export const DEFAULT_WIDTHS = {\r\n min: 200,\r\n max: 400,\r\n}\r\n\r\nexport enum SidebarDirection {\r\n vertical,\r\n horizontal,\r\n}\r\n","import React from 'react'\r\n\r\nimport { DEFAULT_WIDTHS, SidebarDirection } from '../constants'\r\nimport { SidebarModule, SidebarModuleType } from '../modules/modules'\r\n\r\nexport type SidebarContextType = {\r\n isOpen: boolean\r\n isCloseVisible: boolean\r\n direction: SidebarDirection\r\n width?: {\r\n min?: number | string\r\n max?: number | string\r\n default?: { desktop?: number; mobile?: number }\r\n }\r\n activeModule: SidebarModuleType | null\r\n close: () => void\r\n onResize: () => void\r\n selectModule: (module?: SidebarModule) => void\r\n}\r\n\r\nconst DEFAULT_CONTEXT: SidebarContextType = {\r\n activeModule: null,\r\n isOpen: false,\r\n isCloseVisible: false,\r\n direction: SidebarDirection.horizontal,\r\n width: DEFAULT_WIDTHS,\r\n close: () => {},\r\n onResize: () => {},\r\n selectModule: () => {},\r\n}\r\n\r\nexport const SidebarContext = React.createContext(DEFAULT_CONTEXT)\r\nexport const useSidebarContext = () => React.useContext(SidebarContext)\r\n","import { DefaultErrorBoundary } from '@finviz/website'\r\nimport * as React from 'react'\r\nimport { FallbackProps } from 'react-error-boundary'\r\n\r\nexport function ModuleLoadFailed(props: Partial) {\r\n return (\r\n \r\n )\r\n}\r\n","export const portfolioWatchlistAsyncModule = {\r\n importFn: () => import(/* webpackChunkName: \"portfolio-watchlist\" */ './portfolio-watchlist'),\r\n cacheKey: 'portfolio-watchlist',\r\n}\r\n","import { IconNameType } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport { portfolioWatchlistAsyncModule } from './portfolio-watchlist/async-modules'\r\nimport { withModuleAsyncLoad } from './with-module-async-load'\r\n\r\nexport enum SidebarModule {\r\n portfolio = 'portfolio',\r\n}\r\n\r\nexport type SidebarModuleType = {\r\n key: SidebarModule\r\n icon: IconNameType\r\n description: string\r\n content: React.ComponentType\r\n width?: {\r\n min?: number | string\r\n max?: number | string\r\n default?: { desktop?: number; mobile?: number }\r\n }\r\n}\r\n\r\nexport const sidebarModules: Record = Object.freeze({\r\n [SidebarModule.portfolio]: {\r\n key: SidebarModule.portfolio,\r\n icon: 'briefcase',\r\n description: 'Portfolio watchlist',\r\n content: withModuleAsyncLoad(portfolioWatchlistAsyncModule, true),\r\n width: { min: 200, default: { mobile: 275 } },\r\n },\r\n})\r\n","import { Delayed, Spinner } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport { useAsyncModule } from '../../../utils/async-modules-utils'\r\nimport { ModuleLoadFailed } from './module-load-failed'\r\n\r\nexport function withModuleAsyncLoad<\r\n T extends { default: React.ComponentType<{ setIsComponentReady: React.Dispatch> }> },\r\n>(asyncModule: { importFn: () => Promise; cacheKey: string }, withInitialLoading = false) {\r\n return function InnerFunction() {\r\n const [isComponentReady, setIsComponentReady] = React.useState(false)\r\n const [sidebarModule, { isError }] = useAsyncModule({\r\n ...asyncModule,\r\n isSuspenseMode: true,\r\n })\r\n\r\n const SidebarModule = sidebarModule?.default\r\n\r\n if (isError) {\r\n return \r\n }\r\n\r\n return (\r\n <>\r\n {!isComponentReady && withInitialLoading && (\r\n \r\n
\r\n \r\n
\r\n
\r\n )}\r\n {!!SidebarModule && }\r\n \r\n )\r\n }\r\n}\r\n","import { Button, Icon, Paragraph, Tooltip, TooltipTrigger, useTooltipState } from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport React from 'react'\r\n\r\nimport { SidebarDirection } from './constants'\r\nimport { useSidebarContext } from './hooks/sidebar-context'\r\nimport { sidebarModules } from './modules/modules'\r\n\r\nexport const MOBILE_TOOLBAR_DIV_ID = 'toolbar-mobile'\r\n\r\ntype SidebarTabsProps = {\r\n className?: string\r\n}\r\n\r\nexport default function SidebarTabs({ className }: SidebarTabsProps) {\r\n const { isOpen, direction, activeModule, selectModule } = useSidebarContext()\r\n const tooltipState = useTooltipState({ placement: 'left', showTimeout: 300 })\r\n\r\n return (\r\n \r\n {/* reserved space for drawing button on mobile devices */}\r\n {direction === SidebarDirection.horizontal && (\r\n \r\n )}\r\n\r\n {Object.entries(sidebarModules).map(([key, value]) => {\r\n const isActive = activeModule?.key === key\r\n return (\r\n \r\n {\r\n selectModule(isActive ? undefined : value.key)\r\n }}\r\n className={classnames({ 'ml-2': direction === SidebarDirection.horizontal })}\r\n data-testid={`sidebar-${key}-btn`}\r\n >\r\n \r\n \r\n }\r\n state={tooltipState}\r\n aria-label={value.description}\r\n isHideOnClick\r\n />\r\n\r\n \r\n {value.description}\r\n \r\n \r\n )\r\n })}\r\n \r\n )\r\n}\r\n","import { Resizable } from 're-resizable'\r\nimport React from 'react'\r\n\r\nimport Utils from '../../utils'\r\nimport { DEFAULT_WIDTHS, SidebarDirection } from './constants'\r\nimport { useSidebarContext } from './hooks/sidebar-context'\r\n\r\ntype SidebarContentProps = {\r\n children: React.ReactNode\r\n}\r\n\r\nexport default function SidebarContent({ children }: SidebarContentProps) {\r\n const { direction, onResize, close, width } = useSidebarContext()\r\n const minWidth = width?.min ?? DEFAULT_WIDTHS.min\r\n const maxWidth = width?.max ?? DEFAULT_WIDTHS.max\r\n const defaultMobile = width?.default?.mobile ?? minWidth\r\n const defaultDesktop = width?.default?.desktop ?? maxWidth\r\n\r\n return (\r\n <>\r\n {direction === SidebarDirection.vertical && (\r\n \r\n {children}\r\n \r\n )}\r\n {direction === SidebarDirection.horizontal && (\r\n <>\r\n
\r\n
\r\n {children}\r\n
\r\n \r\n )}\r\n \r\n )\r\n}\r\n","import { Delayed, Spinner, localStorage } from '@finviz/website'\r\nimport * as React from 'react'\r\nimport { ErrorBoundary } from 'react-error-boundary'\r\nimport { useNavigate, useSearchParams } from 'react-router-dom'\r\n\r\nimport { getIsMobilePortrait } from '../../utils'\r\nimport { SidebarDirection } from './constants'\r\nimport { SidebarContext, SidebarContextType } from './hooks/sidebar-context'\r\nimport { ModuleLoadFailed } from './modules/module-load-failed'\r\nimport { SidebarModule, SidebarModuleType, sidebarModules } from './modules/modules'\r\nimport SidebarContent from './sidebar-content'\r\nimport SidebarTabs from './sidebar-tabs'\r\n\r\nexport const SIDEBAR_QUERY_PARAM = 'sidebar'\r\n\r\n// This is a temp function, to remove unused property from localstorage\r\nfunction removeSidebarFromLocalstorage() {\r\n const SIDEBAR_LOCAL_STORAGE_KEY = 'sidebarModule'\r\n localStorage.removeValue(SIDEBAR_LOCAL_STORAGE_KEY)\r\n}\r\nremoveSidebarFromLocalstorage()\r\n\r\ntype SidebarProps = {\r\n onShouldResize: () => void\r\n direction: SidebarDirection\r\n tabsClassName?: string\r\n}\r\n\r\n// Todo - this is not correct approach but this component can unmount/mount on mobile orientation change so we can't keep it inside the component\r\nlet isInit = false\r\n\r\nexport function Sidebar({ onShouldResize, direction, tabsClassName }: SidebarProps) {\r\n const navigate = useNavigate()\r\n const [urlSearchParams] = useSearchParams()\r\n const sidebarModuleKey = (urlSearchParams.get(SIDEBAR_QUERY_PARAM) as keyof typeof sidebarModules | null) || null\r\n const [activeModule, setActiveModule] = React.useState(null)\r\n\r\n const isOpen = !!activeModule\r\n const handleSelectModule = React.useCallback(\r\n (key?: SidebarModule) => {\r\n const newUrlSearchParams = new URLSearchParams(urlSearchParams)\r\n if (key) {\r\n newUrlSearchParams.set(SIDEBAR_QUERY_PARAM, key)\r\n } else {\r\n newUrlSearchParams.delete(SIDEBAR_QUERY_PARAM)\r\n }\r\n navigate({ search: newUrlSearchParams.toString() }, { replace: true })\r\n },\r\n [urlSearchParams, navigate]\r\n )\r\n\r\n const handleCloseSidebar = React.useCallback(() => {\r\n handleSelectModule(undefined)\r\n }, [handleSelectModule])\r\n\r\n // Resize charts every time the sidebar is opened/closed or active module is changed\r\n React.useEffect(() => {\r\n onShouldResize()\r\n }, [activeModule, onShouldResize])\r\n\r\n // Set active module based on sidebarModuleKey\r\n React.useEffect(() => {\r\n let sidebarModule = sidebarModuleKey && sidebarModules[sidebarModuleKey]\r\n\r\n if (!isInit && getIsMobilePortrait()) {\r\n sidebarModule = null\r\n handleCloseSidebar()\r\n }\r\n\r\n setActiveModule(sidebarModule)\r\n isInit = true\r\n }, [sidebarModuleKey, handleCloseSidebar])\r\n\r\n const contextValue: SidebarContextType = React.useMemo(\r\n () => ({\r\n direction,\r\n isOpen,\r\n isCloseVisible: direction === SidebarDirection.horizontal,\r\n width: activeModule?.width,\r\n activeModule,\r\n onResize: onShouldResize,\r\n close: handleCloseSidebar,\r\n selectModule: handleSelectModule,\r\n }),\r\n [direction, isOpen, onShouldResize, activeModule, handleCloseSidebar, handleSelectModule]\r\n )\r\n\r\n return (\r\n \r\n {activeModule && (\r\n \r\n \r\n \r\n
\r\n \r\n
\r\n \r\n }\r\n >\r\n \r\n \r\n
\r\n
\r\n )}\r\n \r\n
\r\n )\r\n}\r\n","import { IconNameType } from '@finviz/website'\r\n\r\nimport ChartLayout from '../../models/chart_layout'\r\n\r\nexport enum DrawingTool {\r\n Arrow = 'arrow',\r\n Brush = 'brush',\r\n Callout = 'callout',\r\n Curve = 'curve',\r\n ElliottWaves = 'elliott-wave',\r\n Ellipse = 'ellipse',\r\n FibonacciRetracements = 'fibonacci-retracements',\r\n HorizontalLine = 'horizontal-line',\r\n Measure = 'measure',\r\n Mouse = 'mouse',\r\n Pitchfork = 'pitchfork',\r\n Polygon = 'polygon',\r\n Position = 'position',\r\n Rectangle = 'rectangle',\r\n RotatedRectangle = 'rotated-rectangle',\r\n ScaledLine = 'scaled-line',\r\n ScaledText = 'scaled-text',\r\n Triangle = 'triangle',\r\n VerticalLine = 'vertical-line',\r\n Xabcd = 'xabcd',\r\n}\r\n\r\nexport enum DrawingActions {\r\n AddNote = 'add-note',\r\n DeleteDrawings = 'delete-drawings',\r\n DeleteAutoSavedDrawings = 'delete-autosaved-drawings',\r\n}\r\n\r\nexport enum DrawingSetting {\r\n PreserveDrawings = 'preserve-drawings',\r\n DrawingModeContinuous = 'drawing-mode-continuous',\r\n HideDrawings = 'hide-drawings',\r\n LockDrawings = 'lock-drawings',\r\n}\r\n\r\nexport interface IToolBarProps {\r\n chartLayoutModel: ChartLayout\r\n isSidebar?: boolean\r\n isHorizontal?: boolean\r\n isMobileOverlay?: boolean\r\n /**\r\n * Current selected tool id\r\n */\r\n activeTool: DrawingTool\r\n /**\r\n * On tool item select callback\r\n */\r\n onActiveToolChange: (activeTool: DrawingTool, trigger?: 'button' | 'select' | 'group') => void\r\n /**\r\n * On drawing actions item select callback\r\n */\r\n onDrawingActionClick?: (actionId: DrawingActions) => void\r\n /**\r\n * On drawing settings item select callback\r\n */\r\n onDrawingSettingClick?: (settingId: DrawingSetting) => void\r\n /**\r\n * On drawing end callback\r\n */\r\n onDrawingEnd?: () => void\r\n /**\r\n * Current state of drawing settings\r\n */\r\n drawingSettings: Record\r\n isAlternativeTheme?: boolean\r\n /**\r\n * Are tools disabled\r\n */\r\n areToolsDisabled?: boolean\r\n}\r\n\r\nexport interface IToolbarItemProperties {\r\n icon: IconNameType\r\n iconActive?: IconNameType\r\n iconAction?: IconNameType\r\n title: string\r\n titleActive?: string\r\n titleAction?: string\r\n}\r\n\r\nexport interface IToolbarDrawingTool extends IToolbarItemProperties {\r\n id: DrawingTool\r\n}\r\n\r\nexport interface IToolbarDrawingAction extends IToolbarItemProperties {\r\n id: DrawingActions\r\n}\r\n\r\nexport interface IToolbarDrawingSetting extends IToolbarItemProperties {\r\n id: DrawingSetting\r\n}\r\n\r\nexport interface IToolbarDrawingToolItem {\r\n defaultItem: IToolbarDrawingTool\r\n toolGroup?: Array\r\n toolGroupTitle?: string\r\n}\r\n\r\nexport interface IToolbarDrawingActionItem {\r\n defaultItem: IToolbarDrawingAction\r\n isDisabled?: boolean\r\n disabledTooltip?: string\r\n}\r\n\r\nexport interface IToolbarDrawingsSettingItem {\r\n defaultItem: IToolbarDrawingSetting\r\n isDisabled?: boolean\r\n isInAction?: boolean\r\n disabledTooltip?: string\r\n}\r\n","import { Instrument } from '../../types/shared'\r\nimport { ChartElementType } from '../constants/common'\r\nimport QuoteModel from '../models/quote'\r\n\r\nexport function getInstrumentLabel(instrument: Instrument) {\r\n switch (instrument) {\r\n case Instrument.Stock:\r\n return 'Stock'\r\n case Instrument.Futures:\r\n return 'Futures'\r\n case Instrument.Forex:\r\n return 'Forex'\r\n case Instrument.Crypto:\r\n return 'Crypto'\r\n case Instrument.MarketSentiment:\r\n return 'Market Sentiment'\r\n }\r\n}\r\n\r\nexport function getChartAlt(quoteModel: QuoteModel) {\r\n return `${quoteModel.name || quoteModel.ticker} - ${getInstrumentLabel(quoteModel.instrument)} Price Chart`\r\n}\r\n\r\nexport const getResponseChartType = (chartType: ChartElementType) => {\r\n switch (chartType) {\r\n case ChartElementType.HeikinAshi:\r\n return 'heikinashi'\r\n case ChartElementType.HollowCandleStick:\r\n return 'hollowcandlestick'\r\n case ChartElementType.LineChart:\r\n return 'line'\r\n case ChartElementType.OhlcChart:\r\n return 'ohlc'\r\n case ChartElementType.CandleStick:\r\n default:\r\n return 'candlestick'\r\n }\r\n}\r\n\r\nexport const getChartElementTypeFromResponseType = (chartResponseType: string | null) =>\r\n chartResponseType === null\r\n ? null\r\n : Object.values(ChartElementType).find(\r\n (chartType: ChartElementType) => chartResponseType === getResponseChartType(chartType)\r\n )\r\n","import utils from '../utils'\r\n\r\nclass AverageTrueRange {\r\n period: number\r\n sum: number\r\n count: number\r\n value: number\r\n\r\n constructor(period: number) {\r\n this.period = period\r\n this.sum = 0\r\n this.count = 0\r\n this.value = 0\r\n }\r\n\r\n add(high: number, low: number, prevClose: number) {\r\n const tr = utils.max([high - low, Math.abs(high - prevClose), Math.abs(low - prevClose)])\r\n\r\n if (this.count < this.period) {\r\n this.sum += tr\r\n this.value = this.sum / (this.count + 1)\r\n if (this.count === this.period - 1) {\r\n this.sum /= this.period\r\n }\r\n } else {\r\n this.value = (this.value * (this.period - 1) + tr) / this.period\r\n }\r\n this.count++\r\n }\r\n}\r\n\r\nexport default AverageTrueRange\r\n","import { PaneArea } from '../../types/shared'\r\nimport Element, { DefaultAttrs } from '../canvas/element'\r\nimport BaseChart from '../charts/base_chart'\r\nimport { ChartEventBadgeType, ChartEventType, TIMEFRAME } from '../constants/common'\r\nimport { getRoundedObject } from '../controllers/renderUtils'\r\nimport Chart from '../models/chart'\r\nimport ChartEventElement from '../models/chart-event-element'\r\nimport { CHART_EVENT_BADGE_SIZE } from '../models/constants'\r\nimport type PaneModel from '../models/pane'\r\nimport { ChartEventBadgeState } from '../utils/chart-events-utils'\r\n\r\ninterface ChartEventAttrs extends DefaultAttrs {\r\n x: number\r\n}\r\n\r\nfunction getChartEventState(chartEvent: ChartEvent): ChartEventBadgeState {\r\n if (chartEvent.isOpen) {\r\n return ChartEventBadgeState.selected\r\n }\r\n if (chartEvent.isHovered) {\r\n return ChartEventBadgeState.hover\r\n }\r\n return ChartEventBadgeState.default\r\n}\r\n\r\nclass ChartEvent extends Element {\r\n static type = ChartEventType.ChartEvent\r\n static label = 'ChartEvent'\r\n\r\n declare scaled: Pick\r\n\r\n declare chart: BaseChart\r\n\r\n declare model: PaneModel\r\n\r\n declare chartEventModel: ChartEventElement | undefined\r\n\r\n isOpen = false\r\n\r\n left = 0\r\n top = 0\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x'], y: [] })\r\n\r\n get type() {\r\n return (this.constructor as typeof ChartEvent).type\r\n }\r\n\r\n get label() {\r\n return (this.constructor as typeof ChartEvent).label\r\n }\r\n\r\n getChartEvenBadgeType(): ChartEventBadgeType {\r\n switch (this.type) {\r\n case ChartEventType.Dividends:\r\n return ChartEventBadgeType.Dividends\r\n case ChartEventType.Split:\r\n return ChartEventBadgeType.Split\r\n }\r\n\r\n return ChartEventBadgeType.EarningsNeutral\r\n }\r\n\r\n getChartEventModel(): ChartEventElement | undefined {\r\n if (!this.chartEventModel) {\r\n this.chartEventModel = this.model.chartEvents()?.findByAttribute('instance', this)\r\n }\r\n\r\n return this.chartEventModel\r\n }\r\n\r\n getXYPosition() {\r\n const { top, bottom } = this.getChartLayoutSettings().ChartSettings\r\n const chartEventModel = this.getChartEventModel()\r\n const { x } = this.scaled\r\n const roundedXY = getRoundedObject({ x })\r\n const y =\r\n (this.model as PaneModel).height -\r\n top.height -\r\n bottom.height -\r\n CHART_EVENT_BADGE_SIZE -\r\n (chartEventModel?.yIndex ?? 0) * CHART_EVENT_BADGE_SIZE\r\n\r\n return { x: roundedXY.x - CHART_EVENT_BADGE_SIZE / 2, y }\r\n }\r\n\r\n getIsVisible() {\r\n return ![TIMEFRAME.w, TIMEFRAME.m].includes(this.model.chart().quote()?.timeframe)\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n if (!this.getIsVisible() || !this.chartEventModel) return\r\n\r\n this.attrs.x = Math.round(this.attrs.x)\r\n const chart = this.model.chart()\r\n const chartLayout = chart.chart_layout()\r\n const { x, y } = this.getXYPosition()\r\n const buffer = 10 + CHART_EVENT_BADGE_SIZE\r\n if (x + chart.leftOffset < -buffer || x + chart.leftOffset > chart.width + buffer) {\r\n return\r\n }\r\n const item = this.chartEventModel.getChartEventBadgeImage({\r\n theme: chartLayout.theme,\r\n state: getChartEventState(this),\r\n badgeType: this.getChartEvenBadgeType(),\r\n })\r\n\r\n if (!item) return\r\n\r\n const { left, top } = this.getChartLayoutSettings().ChartSettings\r\n this.left = x + chart.leftOffset + left.width + CHART_EVENT_BADGE_SIZE / 2\r\n this.top = y + top.height\r\n context.drawImage(item, x, y, CHART_EVENT_BADGE_SIZE, CHART_EVENT_BADGE_SIZE)\r\n }\r\n\r\n setIsHovered(isHovered: boolean) {\r\n if (!this.getIsVisible()) return\r\n\r\n this.isHovered = isHovered\r\n this.model.updateChartEventsZIndexes()\r\n this.trigger('change')\r\n }\r\n\r\n // If isOpenOverride is undefined, the function works as toggle\r\n toggleIsOpen(isOpenOverride?: boolean) {\r\n const chartLayout = this.model.chart().chart_layout()\r\n const chartEventModel = this.getChartEventModel()\r\n\r\n const isCurrentEventActive = chartLayout.activeChartEvent?.elementId === chartEventModel?.elementId\r\n const isOpen = isOpenOverride ?? (isCurrentEventActive ? !chartEventModel?.instance.isOpen : true)\r\n this.isOpen = isOpen\r\n if (chartLayout.activeChartEvent?.instance.isOpen && !isCurrentEventActive) {\r\n chartLayout.activeChartEvent?.instance.toggleIsOpen(false)\r\n }\r\n if (isOpen || isCurrentEventActive) {\r\n chartLayout.updateAttribute('activeChartEvent', !isOpen && isCurrentEventActive ? undefined : chartEventModel)\r\n }\r\n\r\n this.model.updateChartEventsZIndexes()\r\n this.trigger('change')\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (!this.getIsVisible()) return false\r\n\r\n const scaledArea = area.scaled\r\n const { x, y } = this.getXYPosition()\r\n const isInArea =\r\n x <= scaledArea.x &&\r\n x + CHART_EVENT_BADGE_SIZE >= scaledArea.x &&\r\n y <= scaledArea.y &&\r\n y + CHART_EVENT_BADGE_SIZE >= scaledArea.y\r\n return isInArea\r\n }\r\n\r\n getIsInChartView(chart: Chart) {\r\n if (!this.getIsVisible()) return false\r\n\r\n const { x } = this.getXYPosition()\r\n const isInView = x + CHART_EVENT_BADGE_SIZE >= -chart.leftOffset && x <= -chart.leftOffset + chart.width\r\n return isInView\r\n }\r\n}\r\n\r\nexport default ChartEvent\r\n","import { ChartEventLabels, ChartEventType } from '../constants/common'\r\nimport ChartEvent from './chart-event'\r\n\r\nclass Dividends extends ChartEvent {\r\n static type = ChartEventType.Dividends\r\n static label = ChartEventLabels[ChartEventType.Dividends]\r\n}\r\n\r\nexport default Dividends\r\n","import { ChartEventBadgeType, ChartEventLabels, ChartEventType } from '../constants/common'\r\nimport { IEarnings } from '../utils/chart-events-utils'\r\nimport ChartEvent from './chart-event'\r\n\r\nclass Earnings extends ChartEvent {\r\n static type = ChartEventType.Earnings\r\n static label = ChartEventLabels[ChartEventType.Earnings]\r\n\r\n getChartEvenBadgeType(): ChartEventBadgeType {\r\n const eventItem = this.getChartEventModel()?.getChartEventData() as IEarnings | undefined\r\n\r\n if (!eventItem) {\r\n return ChartEventBadgeType.EarningsNeutral\r\n }\r\n\r\n if (eventItem.epsActual === undefined || eventItem.epsEstimate === undefined) {\r\n const now = Date.now() / 1000\r\n return eventItem.dateTimestamp > now ? ChartEventBadgeType.EarningsFuture : ChartEventBadgeType.EarningsNeutral\r\n }\r\n return eventItem.epsActual - eventItem.epsEstimate < 0\r\n ? ChartEventBadgeType.EarningsNegative\r\n : ChartEventBadgeType.EarningsPositive\r\n }\r\n}\r\n\r\nexport default Earnings\r\n","import { ChartEventLabels, ChartEventType } from '../constants/common'\r\nimport ChartEvent from './chart-event'\r\n\r\nclass Split extends ChartEvent {\r\n static type = ChartEventType.Split\r\n static label = ChartEventLabels[ChartEventType.Split]\r\n}\r\n\r\nexport default Split\r\n","import { ChartEventType } from '../constants/common'\r\nimport chartEvent from './chart-event'\r\nimport dividends from './dividends'\r\nimport earnings from './earnings'\r\nimport split from './split'\r\n\r\nexport const chartEventsByType = Object.freeze({\r\n [ChartEventType.ChartEvent]: chartEvent,\r\n [ChartEventType.Dividends]: dividends,\r\n [ChartEventType.Split]: split,\r\n [ChartEventType.Earnings]: earnings,\r\n})\r\n","import { ChartConfigChartPaneElement } from '../../types/shared'\r\nimport { drawingToolsByType } from '../canvas/drawingTools'\r\nimport { chartEventsByType } from '../chart-events'\r\nimport { chartsByType } from '../charts/charts'\r\nimport { indicatorsByType } from '../indicators/indicators'\r\nimport { overlaysByType } from '../overlays/overlays'\r\n\r\nconst canvasElements = {\r\n ...overlaysByType,\r\n ...indicatorsByType,\r\n ...drawingToolsByType,\r\n ...chartsByType,\r\n ...chartEventsByType,\r\n}\r\n\r\nexport function getCanvasElementByType(elementType: ChartConfigChartPaneElement['type']) {\r\n return canvasElements[elementType]\r\n}\r\n","import { Instrument, Point } from '../../types/shared'\r\n\r\ninterface LinePoints {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n}\r\n\r\nexport enum BigNumber {\r\n Thousand,\r\n Million,\r\n Billion,\r\n Trillion,\r\n}\r\n\r\nexport const BIG_NUMBER_VALUES = {\r\n [BigNumber.Thousand]: 1e3,\r\n [BigNumber.Million]: 1e6,\r\n [BigNumber.Billion]: 1e9,\r\n [BigNumber.Trillion]: 1e12,\r\n}\r\n\r\nconst BIG_NUMBER_ZEROES = {\r\n [BigNumber.Thousand]: 3,\r\n [BigNumber.Million]: 6,\r\n [BigNumber.Billion]: 9,\r\n [BigNumber.Trillion]: 12,\r\n}\r\n\r\nconst BIG_NUMBER_SUFFIX = {\r\n [BigNumber.Thousand]: 'K',\r\n [BigNumber.Million]: 'M',\r\n [BigNumber.Billion]: 'B',\r\n [BigNumber.Trillion]: 'T',\r\n}\r\n\r\nconst math = {\r\n dotProduct(p1: Point, p2: Point) {\r\n return p1.x * p2.x + p1.y * p2.y\r\n },\r\n\r\n crossProduct(p1: Point, p2: Point) {\r\n return p1.x * p2.y - p1.y * p2.x\r\n },\r\n\r\n distance(p1: Point, p2: Point) {\r\n return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2))\r\n },\r\n\r\n lineEquation(line: LinePoints) {\r\n // ax + by + c = 0\r\n if (line.x1 === line.x2) {\r\n return {\r\n a: 1,\r\n b: 0,\r\n c: -line.x1,\r\n }\r\n }\r\n const k = (line.y2 - line.y1) / (line.x2 - line.x1)\r\n return {\r\n a: -k,\r\n b: 1,\r\n c: k * line.x1 - line.y1,\r\n k,\r\n }\r\n },\r\n\r\n pointInPolygon(point: Point, polygon: Point[]) {\r\n // http://alienryderflex.com/polygon/\r\n let j = polygon.length - 1\r\n let oddNodes = false\r\n for (let i = 0; i < polygon.length; i++) {\r\n const p = polygon[i]\r\n if (\r\n ((p.y < point.y && polygon[j].y >= point.y) || (polygon[j].y < point.y && p.y >= point.y)) &&\r\n (p.x <= point.x || polygon[j].x <= point.x)\r\n ) {\r\n if (p.x + ((point.y - p.y) / (polygon[j].y - p.y)) * (polygon[j].x - p.x) < point.x) {\r\n oddNodes = !oddNodes\r\n }\r\n }\r\n j = i\r\n }\r\n return oddNodes\r\n },\r\n\r\n distanceToLine(point: Point, line: LinePoints) {\r\n const { a, b, c } = this.lineEquation(line)\r\n const dist = Math.abs(a * point.x + b * point.y + c) / Math.sqrt(a * a + b * b)\r\n return dist\r\n },\r\n\r\n distanceToSegment(point: Point, line: LinePoints) {\r\n const l2 = Math.pow(line.x1 - line.x2, 2) + Math.pow(line.y1 - line.y2, 2)\r\n if (l2 === 0) {\r\n return Math.sqrt(Math.pow(point.x - line.x1, 2) + Math.pow(point.y - line.y1, 2))\r\n }\r\n const t = ((point.x - line.x1) * (line.x2 - line.x1) + (point.y - line.y1) * (line.y2 - line.y1)) / l2\r\n if (t < 0) {\r\n return Math.sqrt(Math.pow(point.x - line.x1, 2) + Math.pow(point.y - line.y1, 2))\r\n }\r\n if (t > 1) {\r\n return Math.sqrt(Math.pow(point.x - line.x2, 2) + Math.pow(point.y - line.y2, 2))\r\n }\r\n const x = line.x1 + t * (line.x2 - line.x1)\r\n const y = line.y1 + t * (line.y2 - line.y1)\r\n return Math.sqrt(Math.pow(point.x - x, 2) + Math.pow(point.y - y, 2))\r\n },\r\n\r\n getInstrumentDecimalPlaces({ value, instrument }: { value: number; instrument?: Instrument }) {\r\n if (instrument === Instrument.Crypto && value <= 0.001) {\r\n return 8\r\n }\r\n\r\n if ((instrument !== Instrument.Stock && value <= 6) || (instrument === Instrument.Stock && value < 1)) {\r\n return 4\r\n }\r\n\r\n return 2\r\n },\r\n\r\n formatBigNumber(number: number, toFixed?: number, minNumber?: BigNumber) {\r\n const absNum = Math.abs(number)\r\n const getString = ({ num, suffix, zeroes }: { num: number; suffix: string; zeroes: number }) => {\r\n const str = num.toString()\r\n if (str.includes('e')) {\r\n const splitString = str.split('e')\r\n const addZeroes = Number(splitString[1]) - zeroes\r\n return Math.round(Number(splitString[0])).toString().padEnd(Math.max(0, addZeroes), '0') + suffix\r\n }\r\n const sign = Math.sign(num)\r\n const numberByZeroesCount = Math.pow(10, zeroes)\r\n const result = (absNum / numberByZeroesCount) * sign\r\n return (Number.isInteger(result) ? result : result.toFixed(toFixed !== undefined ? toFixed : 1)) + suffix\r\n }\r\n\r\n if (absNum >= BIG_NUMBER_VALUES[BigNumber.Trillion] || minNumber === BigNumber.Trillion) {\r\n return getString({\r\n num: number,\r\n suffix: BIG_NUMBER_SUFFIX[BigNumber.Trillion],\r\n zeroes: BIG_NUMBER_ZEROES[BigNumber.Trillion],\r\n })\r\n } else if (absNum >= BIG_NUMBER_VALUES[BigNumber.Billion] || minNumber === BigNumber.Billion) {\r\n return getString({\r\n num: number,\r\n suffix: BIG_NUMBER_SUFFIX[BigNumber.Billion],\r\n zeroes: BIG_NUMBER_ZEROES[BigNumber.Billion],\r\n })\r\n } else if (absNum >= BIG_NUMBER_VALUES[BigNumber.Million] || minNumber === BigNumber.Million) {\r\n return getString({\r\n num: number,\r\n suffix: BIG_NUMBER_SUFFIX[BigNumber.Million],\r\n zeroes: BIG_NUMBER_ZEROES[BigNumber.Million],\r\n })\r\n } else if (absNum >= BIG_NUMBER_VALUES[BigNumber.Thousand] || minNumber === BigNumber.Thousand) {\r\n return getString({\r\n num: number,\r\n suffix: BIG_NUMBER_SUFFIX[BigNumber.Thousand],\r\n zeroes: BIG_NUMBER_ZEROES[BigNumber.Thousand],\r\n })\r\n } else {\r\n return toFixed !== undefined ? number.toFixed(toFixed) : number.toString()\r\n }\r\n },\r\n\r\n round({\r\n value,\r\n lastClose = 0,\r\n instrument,\r\n overridePlaces,\r\n }: {\r\n value: number\r\n lastClose?: number\r\n instrument?: Instrument\r\n overridePlaces?: number\r\n }) {\r\n if (Math.abs(value) >= BIG_NUMBER_VALUES[BigNumber.Million]) {\r\n return this.formatBigNumber(value, overridePlaces)\r\n }\r\n\r\n const places =\r\n typeof overridePlaces === 'number'\r\n ? overridePlaces\r\n : this.getInstrumentDecimalPlaces({ value: lastClose, instrument })\r\n\r\n if (value < 0.000001) {\r\n // There was an issue with getting NaN when rounding small numbers with latter method\r\n return value.toFixed(places)\r\n }\r\n return Number(`${Math.round(Number(`${value}e+${places}`))}e-${places}`).toFixed(places)\r\n },\r\n\r\n perpendicularPointToLine({ line, distance }: { line: LinePoints; distance: number }) {\r\n if (distance === 0) {\r\n return { x: line.x2, y: line.y2 }\r\n }\r\n\r\n let yAxisCoeficient\r\n let xAxisCoeficient\r\n\r\n if (line.x1 <= line.x2 && line.y1 >= line.y2) {\r\n xAxisCoeficient = -1\r\n yAxisCoeficient = -1\r\n } else if (line.x1 <= line.x2 && line.y1 <= line.y2) {\r\n xAxisCoeficient = 1\r\n yAxisCoeficient = -1\r\n } else if (line.x1 >= line.x2 && line.y1 >= line.y2) {\r\n xAxisCoeficient = -1\r\n yAxisCoeficient = 1\r\n } else {\r\n // conditions falling to else: (line.x1 >= line.x2 && line.y1 <= line.y2)\r\n xAxisCoeficient = 1\r\n yAxisCoeficient = 1\r\n }\r\n\r\n const radAngle = Math.atan2(Math.abs(line.x2 - line.x1), Math.abs(line.y2 - line.y1))\r\n const x = line.x2 + xAxisCoeficient * (distance * Math.cos(radAngle))\r\n const y = line.y2 + yAxisCoeficient * (distance * Math.sin(radAngle))\r\n return { x, y }\r\n },\r\n\r\n rotatedPointCoordinates({\r\n rotationAxisPoint,\r\n angle,\r\n pointToRotate,\r\n }: {\r\n rotationAxisPoint: Point\r\n angle: number\r\n pointToRotate: Point\r\n }) {\r\n // return newCoordinates for pointToRotate after rotation defined by\r\n // angle around rotationAxisPoint\r\n const sin = Math.sin(angle)\r\n const cos = Math.cos(angle)\r\n const rotatedX =\r\n cos * (pointToRotate.x - rotationAxisPoint.x) +\r\n sin * (pointToRotate.y - rotationAxisPoint.y) +\r\n rotationAxisPoint.x\r\n const rotatedY =\r\n cos * (pointToRotate.y - rotationAxisPoint.y) -\r\n sin * (pointToRotate.x - rotationAxisPoint.x) +\r\n rotationAxisPoint.y\r\n return { x: rotatedX, y: rotatedY }\r\n },\r\n sharedPointLinesAngle({\r\n sharedPoint,\r\n oldLinePoint,\r\n newLinePoint,\r\n }: {\r\n sharedPoint: Point\r\n oldLinePoint: Point\r\n newLinePoint: Point\r\n }) {\r\n // return angle between line from sharedPoint to oldLinePoint and\r\n // line from sharedPoint to newLinePoint\r\n const numerator =\r\n oldLinePoint.y * (sharedPoint.x - newLinePoint.x) +\r\n sharedPoint.y * (newLinePoint.x - oldLinePoint.x) +\r\n newLinePoint.y * (oldLinePoint.x - sharedPoint.x)\r\n const denominator =\r\n (oldLinePoint.x - sharedPoint.x) * (sharedPoint.x - newLinePoint.x) +\r\n (oldLinePoint.y - sharedPoint.y) * (sharedPoint.y - newLinePoint.y)\r\n const ratio = numerator / denominator\r\n\r\n return Math.atan(ratio)\r\n },\r\n\r\n twoSegmentLinesIntersection(p1: Point, p2: Point, p3: Point, p4: Point) {\r\n // line intercept math by Paul Bourke http://paulbourke.net/geometry/pointlineplane/\r\n // Determine the intersection point of two line segments\r\n // Return FALSE if the lines don't intersect\r\n\r\n // Check if none of the lines are of length 0\r\n if ((p1.x === p2.x && p1.y === p2.y) || (p3.x === p4.x && p3.y === p4.y)) {\r\n return false\r\n }\r\n\r\n const denominator = (p4.y - p3.y) * (p2.x - p1.x) - (p4.x - p3.x) * (p2.y - p1.y)\r\n\r\n // Lines are parallel\r\n if (denominator === 0) {\r\n return false\r\n }\r\n\r\n const ua = ((p4.x - p3.x) * (p1.y - p3.y) - (p4.y - p3.y) * (p1.x - p3.x)) / denominator\r\n const ub = ((p2.x - p1.x) * (p1.y - p3.y) - (p2.y - p1.y) * (p1.x - p3.x)) / denominator\r\n\r\n // is the intersection along the segments\r\n if (ua < 0 || ua > 1 || ub < 0 || ub > 1) {\r\n return false\r\n }\r\n\r\n // Return a object with the x and y coordinates of the intersection\r\n const x = p1.x + ua * (p2.x - p1.x)\r\n const y = p1.y + ua * (p2.y - p1.y)\r\n\r\n return { x, y }\r\n },\r\n\r\n // https://stackoverflow.com/a/60368757\r\n checkLineIntersection(line1_p1: Point, line1_p2: Point, line2_p1: Point, line2_p2: Point) {\r\n // if the lines intersect, the result contains the x and y of the intersection (treating the lines as infinite) and booleans for whether line segment 1 or line segment 2 contain the point\r\n let a, b\r\n const result: { x: number; y: number; onLine1: boolean; onLine2: boolean } = {\r\n x: 0,\r\n y: 0,\r\n onLine1: false,\r\n onLine2: false,\r\n }\r\n const denominator =\r\n (line2_p2.y - line2_p1.y) * (line1_p2.x - line1_p1.x) - (line2_p2.x - line2_p1.x) * (line1_p2.y - line1_p1.y)\r\n if (denominator === 0) {\r\n return false\r\n }\r\n\r\n a = line1_p1.y - line2_p1.y\r\n b = line1_p1.x - line2_p1.x\r\n const numerator1 = (line2_p2.x - line2_p1.x) * a - (line2_p2.y - line2_p1.y) * b\r\n const numerator2 = (line1_p2.x - line1_p1.x) * a - (line1_p2.y - line1_p1.y) * b\r\n a = numerator1 / denominator\r\n b = numerator2 / denominator\r\n\r\n // if we cast these lines infinitely in both directions, they intersect here:\r\n result.x = line1_p1.x + a * (line1_p2.x - line1_p1.x)\r\n result.y = line1_p1.y + a * (line1_p2.y - line1_p1.y)\r\n\r\n // if line1 is a segment and line2 is infinite, they intersect if:\r\n if (a > 0 && a < 1) {\r\n result.onLine1 = true\r\n }\r\n // if line2 is a segment and line1 is infinite, they intersect if:\r\n if (b > 0 && b < 1) {\r\n result.onLine2 = true\r\n }\r\n // if line1 and line2 are segments, they intersect if both of the above are true\r\n return result\r\n },\r\n\r\n // ray is considered line1, segment is considered line2\r\n getRayToLineSegmentIntersection(rayOrigin: Point, rayEnd: Point, segmentStart: Point, segmentEnd: Point) {\r\n const lineIntersection = this.checkLineIntersection(rayOrigin, rayEnd, segmentStart, segmentEnd)\r\n\r\n if (\r\n !lineIntersection ||\r\n lineIntersection.onLine1 ||\r\n this.dotProduct(\r\n this.subtractPoints(rayOrigin, lineIntersection as Point),\r\n this.subtractPoints(rayOrigin, rayEnd)\r\n ) <= 0\r\n )\r\n return false\r\n return { ...lineIntersection, x: Math.round(lineIntersection.x), y: Math.round(lineIntersection.y) } // sometimes edge value can have crazy precision instead of `0` something like `5.684341886080802e-14` which is basically 0.00000000000005684341886080802 we should round it\r\n },\r\n\r\n getMiddlePointOnLineSegment(P1: Point, P2: Point) {\r\n const x = (P1.x - P2.x) / 2 + P2.x\r\n const y = (P1.y - P2.y) / 2 + P2.y\r\n return { x, y }\r\n },\r\n\r\n normalizeVector(v: Point) {\r\n const length = Math.sqrt(v.x * v.x + v.y * v.y)\r\n return { x: v.x / length, y: v.y / length }\r\n },\r\n\r\n multiplyVectorByScalar(v: Point, scalar: number) {\r\n return { x: v.x * scalar, y: v.y * scalar }\r\n },\r\n\r\n addPoints(P1: Point, P2: Point) {\r\n return { x: P1.x + P2.x, y: P1.y + P2.y }\r\n },\r\n\r\n subtractPoints(P1: Point, P2: Point): Point {\r\n return { x: P1.x - P2.x, y: P1.y - P2.y }\r\n },\r\n\r\n isSamePoint(P1: Point, P2: Point, margin = { x: 0, y: 0 }) {\r\n return P1.x - margin.x <= P2.x && P2.x <= P1.x + margin.x && P1.y - margin.y <= P2.y && P2.y <= P1.y + margin.y\r\n },\r\n}\r\n\r\nexport default math\r\n","import { OverlayType } from '../constants/common'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype Options = {\r\n period: number\r\n}\r\n\r\nexport class ExponentialMovingAverage {\r\n period: number\r\n multiplier: number\r\n sum: number\r\n count: number\r\n value: number\r\n\r\n constructor(period: number) {\r\n this.period = period\r\n this.multiplier = 2 / (this.period + 1)\r\n this.sum = 0\r\n this.count = 0\r\n this.value = 0\r\n }\r\n\r\n add(d: number) {\r\n if (this.count < this.period) {\r\n this.sum += d\r\n this.count++\r\n this.value = this.sum / this.count\r\n } else {\r\n this.value = d * this.multiplier + this.value * (1 - this.multiplier)\r\n }\r\n }\r\n}\r\n\r\ntype DefaultCalculatedValuesType = {\r\n ema: number[]\r\n}\r\n\r\nexport class EMACalculation extends MainCalculation {\r\n static type = OverlayType.Ema\r\n\r\n getDefaultCalculatedValues() {\r\n return { ema: [] }\r\n }\r\n\r\n calculate(onValueCalculated?: OnValueCalculated) {\r\n const { period } = this.options\r\n const { close } = this.quote\r\n const lastIndex = close.length - 1\r\n const ema = new ExponentialMovingAverage(period)\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n for (let index = 0; index <= lastIndex; index++) {\r\n ema.add(close[index])\r\n this.calculatedValues.ema[index] = ema.value\r\n\r\n if (onValueCalculated?.(this.calculatedValues, index) === false) {\r\n break\r\n }\r\n }\r\n }\r\n}\r\n","import { ObjectHash } from '../../types/shared'\r\nimport { IndicatorType, OverlayType } from '../constants/common'\r\nimport Quote from '../models/quote'\r\n\r\ntype OptionValuesType = ObjectHash\r\ntype CalculatedValuesType = ObjectHash\r\ninterface MainProps {\r\n quote?: Quote\r\n options: T\r\n}\r\n\r\nexport type OnValueCalculatedReturnValue = boolean | undefined\r\nexport type OnValueCalculated = ((value: T, dataIndex: number) => OnValueCalculatedReturnValue) | undefined\r\n\r\nexport class MainCalculation<\r\n TOptionValues extends OptionValuesType | undefined = undefined,\r\n TCalculatedValues extends CalculatedValuesType = CalculatedValuesType,\r\n> {\r\n static type: IndicatorType | OverlayType = IndicatorType.Indicator\r\n\r\n quote: NonNullable['quote']>\r\n options: MainProps['options']\r\n\r\n protected _calculatedValues: TCalculatedValues\r\n\r\n constructor({ quote, options }: MainProps) {\r\n this.quote = quote ?? new Quote()\r\n this.options = options\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n }\r\n\r\n get calculatedValues() {\r\n return this._calculatedValues\r\n }\r\n\r\n getDefaultCalculatedValues(): TCalculatedValues {\r\n throw Error('Implement getDefaultCalculatedValues')\r\n }\r\n\r\n calculate(_: OnValueCalculated) {\r\n throw Error('Implement calculate')\r\n }\r\n\r\n getAllCalculatedValues(lastNItems: number) {\r\n const calculatedValues = {} as TCalculatedValues\r\n Object.keys(this.calculatedValues).forEach((key) => {\r\n calculatedValues[key as keyof TCalculatedValues] = this.getCalculatedValues(key, lastNItems)\r\n })\r\n return calculatedValues\r\n }\r\n\r\n getCalculatedValues(key: keyof TCalculatedValues, lastNItems: number) {\r\n return (this.calculatedValues[key] as number[]).slice(-lastNItems) as TCalculatedValues[keyof TCalculatedValues]\r\n }\r\n\r\n /**\r\n * This function is used to construct sql script for db table creation\r\n * and also to build precalculated data object used on node server.\r\n *\r\n * Precalculated data object uses database column names as property keys to simplify data mapping on BE\r\n */\r\n getDbColumnName() {\r\n const { type } = this.constructor as typeof MainCalculation\r\n const typeLabel = type.split('/')[1]\r\n const optionKeys = Object.keys(this.options ?? {}).sort((key1, key2) => key1.localeCompare(key2))\r\n\r\n const optionsStrings = optionKeys.map((key) => `${key.slice(0, 1)}${this.options![key]}`)\r\n return [typeLabel, ...optionsStrings].join('_')\r\n }\r\n}\r\n","import Spine from '@finviz/spine'\r\nimport merge from 'lodash.merge'\r\n\r\nimport {\r\n ChartConfigChartPaneElement,\r\n CustomSpineEvents,\r\n IModalConfig,\r\n IModalConfigInput,\r\n ObjectHash,\r\n PaneArea,\r\n RequireByKey,\r\n Theme,\r\n} from '../../types/shared'\r\nimport Line from '../canvas/line'\r\nimport Text from '../canvas/text'\r\nimport tailwindColors from '../constants/colors'\r\nimport {\r\n FONT_SIZE,\r\n INDICATOR_LABEL_HEIGHT,\r\n IndicatorType,\r\n OFFSET,\r\n PADDING,\r\n SpecificChartFunctionality,\r\n TextAlign,\r\n TextBaseline,\r\n} from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport math from '../helpers/math'\r\nimport Chart from '../models/chart'\r\nimport mouseModel from '../models/mouse'\r\nimport Pane from '../models/pane'\r\nimport Quote from '../models/quote'\r\nimport { getChartLayoutSettings } from '../models/settings'\r\nimport { isRedesignEnabled } from '../utils'\r\nimport { roundedRect } from '../utils/canvas-render'\r\nimport { renderCross } from '../utils/chart'\r\nimport {\r\n drawInVisibleArea,\r\n getAreNoBarsVisible,\r\n getCompensatedFirstBarToRenderIndex,\r\n getVisibleBarToRenderIndex,\r\n} from '../utils/draw_in_visible_area'\r\nimport { getIsSSr, getParsedIntegersFromPeriodString, isInRange, isPositiveInteger } from '../utils/helpers'\r\n\r\nconst MAX_POSITIVE_DEFAULT_VALUE = Number.MAX_VALUE\r\nconst MAX_NEGATIVE_DEFAULT_VALUE = -Number.MAX_VALUE\r\n\r\nconst INDICATOR_DEFAULT_DOMAIN = (indicator: IndicatorType) => {\r\n switch (indicator) {\r\n case IndicatorType.Rvol:\r\n return { min: 0, max: 2 }\r\n case IndicatorType.Atr:\r\n return { min: 0, max: 10 }\r\n case IndicatorType.Adx:\r\n case IndicatorType.Aro:\r\n case IndicatorType.Mfi:\r\n case IndicatorType.Perf:\r\n case IndicatorType.Rmi:\r\n case IndicatorType.Rsi:\r\n case IndicatorType.Stofu:\r\n case IndicatorType.Ult:\r\n return { min: 0, max: 100 }\r\n case IndicatorType.Macd:\r\n case IndicatorType.Rwi:\r\n case IndicatorType.Trix:\r\n return { min: -1, max: 1 }\r\n case IndicatorType.Wr:\r\n return { min: -100, max: 0 }\r\n case IndicatorType.Aroosc:\r\n case IndicatorType.Roc:\r\n return { min: -100, max: 100 }\r\n case IndicatorType.Cci:\r\n case IndicatorType.Fi:\r\n return { min: -200, max: 200 }\r\n default:\r\n return { min: 0, max: 100 }\r\n }\r\n}\r\n\r\nexport interface IIndicatorIsValid {\r\n getIsValid(key: string): boolean | void\r\n}\r\n\r\nclass Indicator extends Spine.Module implements IIndicatorIsValid {\r\n static type = IndicatorType.Indicator\r\n static label = 'Indicator'\r\n\r\n static initClass() {\r\n Object.defineProperty(this.prototype, 'height', {\r\n get() {\r\n return this.model.height\r\n },\r\n })\r\n Object.defineProperty(this.prototype, 'contentHeight', {\r\n get() {\r\n const { IndicatorSettings } = this.getChartLayoutSettings()\r\n return this.height - IndicatorSettings.top.height - IndicatorSettings.bottom.height\r\n },\r\n })\r\n }\r\n\r\n static fromObject(values: ObjectHash, model: Pane) {\r\n const indicator = new this(values, model)\r\n indicator.set(values)\r\n return indicator\r\n }\r\n\r\n static getNumOfBarsBuffer({ period }: RequireByKey) {\r\n const [periodInt = 0] = getParsedIntegersFromPeriodString(period)\r\n return periodInt\r\n }\r\n\r\n declare data: Quote\r\n declare min: number\r\n declare max: number\r\n declare contentHeight: number\r\n declare height: number\r\n\r\n attrs: Attrs\r\n model: Pane\r\n labelWidth = 0\r\n fetchedAt = -1\r\n leftOffset = 0\r\n width = 0\r\n contentWidth = 0\r\n lastValue: number | null = null\r\n shouldUpdate = true\r\n tickers: string | null = null\r\n period?: string | number\r\n\r\n constructor(attrs: Attrs, model: Pane) {\r\n super(attrs, model)\r\n this.attrs = attrs\r\n this.model = model\r\n this.data = this.model.chart().quote()\r\n\r\n this.renderYAxis = this.renderYAxis.bind(this)\r\n this.renderCrossText = this.renderCrossText.bind(this)\r\n\r\n this.model.chart().bind('update', this.trigger.bind(this, 'change'))\r\n this.model.bind('update change', this.trigger.bind(this, 'change'))\r\n const mouseModelChangeHandler = this.trigger.bind(this, 'change', 'cross')\r\n this.model.bind('destroy', () => {\r\n mouseModel.unbind('change', mouseModelChangeHandler)\r\n })\r\n mouseModel.bind('change', mouseModelChangeHandler)\r\n\r\n this.model.chart().chart_layout().bind('theme', this.setupCache.bind(this))\r\n }\r\n\r\n get type() {\r\n return (this.constructor as typeof Indicator).type\r\n }\r\n\r\n get label() {\r\n return (this.constructor as typeof Indicator).label\r\n }\r\n\r\n render(context: CanvasRenderingContext2D) {\r\n const { IndicatorSettings } = this.getChartLayoutSettings()\r\n this.data = this.model.chart().quote()\r\n this.leftOffset = this.model.chart().leftOffset\r\n this.width = this.model.chart().width\r\n this.contentWidth = this.width - IndicatorSettings.left.width - IndicatorSettings.right.width\r\n\r\n this.compute()\r\n\r\n this.setupCache()\r\n\r\n this.renderYAxis(context)\r\n\r\n context.save()\r\n this.clip(context)\r\n this.renderXAxis(context)\r\n const translate = getTranslate({\r\n context,\r\n xOffset: this.leftOffset + IndicatorSettings.left.width,\r\n yOffset: IndicatorSettings.top.height,\r\n })\r\n translate.do()\r\n this.renderIndicator(context)\r\n translate.undo()\r\n context.restore()\r\n\r\n if (!this.getIsChartPageSpecificFunctionality()) {\r\n this.renderLabel(context)\r\n }\r\n }\r\n\r\n isComputeNecessary() {\r\n // if quote was updated (this.fetchedAt !== this.data.fetchedAt)\r\n // or indicator setting was changed via modal (this.shouldUpdate)\r\n // allow compute and update variables to prevent another unless\r\n // those variables change again\r\n if (this.fetchedAt !== this.data.fetchedAt || this.shouldUpdate) {\r\n this.fetchedAt = this.data.fetchedAt\r\n this.shouldUpdate = false\r\n return true\r\n }\r\n return false\r\n }\r\n\r\n renderYAxis(context: CanvasRenderingContext2D) {\r\n const { IndicatorSettings, ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n let y\r\n const translate = getTranslate({\r\n context,\r\n xOffset: IndicatorSettings.left.width,\r\n yOffset: IndicatorSettings.top.height,\r\n })\r\n translate.do()\r\n const ticks = this.model.scale.y.ticks(10)\r\n const tickTextStep = Math.abs(ticks[2] - ticks[0])\r\n const yLine = new Line(\r\n {\r\n x1: 0,\r\n x2: this.contentWidth,\r\n strokeStyle: Colors.grid,\r\n dashLength: 3,\r\n },\r\n this.model\r\n )\r\n const text = new Text(\r\n {\r\n x: this.contentWidth + OFFSET.M + IndicatorSettings.right.axis.margin.left!,\r\n font: Text.getMergedPropsWithDefaults('font', IndicatorSettings.right.axis.font),\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.middle,\r\n },\r\n this.model\r\n )\r\n for (let index = 0; index < ticks.length; index++) {\r\n const tick = ticks[index]\r\n y = Math.round(this.fy(tick))\r\n yLine.set({ y1: y, y2: y }).render(context)\r\n if (index % 2 === 0) {\r\n text.set({ text: this.formatAxis(tick, tickTextStep), y }).render(context)\r\n }\r\n }\r\n\r\n const minY = 0\r\n const maxY = this.contentHeight\r\n const valueY = this.lastValue === null ? 0 : Math.round(this.fy(this.lastValue))\r\n if (this.lastValue != null && valueY >= minY && valueY <= maxY) {\r\n new Text(\r\n {\r\n text: math.formatBigNumber(this.lastValue, 2),\r\n x: this.contentWidth + OFFSET.M - PADDING.XXS + IndicatorSettings.right.axis.margin.left!,\r\n y: valueY,\r\n font: Text.getMergedPropsWithDefaults('font', IndicatorSettings.right.axis.font),\r\n lineHeight: IndicatorSettings.right.axis.font.lineHeight,\r\n padding: {\r\n top: IndicatorSettings.right.axis.font?.padding?.top ?? PADDING.XXS,\r\n right: IndicatorSettings.right.axis.font?.padding?.right ?? PADDING.XXS,\r\n bottom: IndicatorSettings.right.axis.font?.padding?.bottom ?? PADDING.XXS,\r\n left: IndicatorSettings.right.axis.font?.padding?.left ?? PADDING.XXS,\r\n },\r\n textBaseline: TextBaseline.middle,\r\n fillStyle: Colors.indicatorCurrentText,\r\n background: Colors.indicatorCurrentBackground,\r\n },\r\n this.model\r\n ).render(context)\r\n }\r\n\r\n translate.undo()\r\n }\r\n\r\n renderXAxis(context: CanvasRenderingContext2D) {\r\n const { IndicatorSettings, ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const xLine = new Line(\r\n {\r\n x1: 0,\r\n x2: 0,\r\n y1: 0,\r\n y2: this.contentHeight,\r\n strokeStyle: Colors.grid,\r\n dashLength: 3,\r\n },\r\n this.model\r\n )\r\n const translate = getTranslate({\r\n context,\r\n xOffset: IndicatorSettings.left.width,\r\n yOffset: IndicatorSettings.top.height,\r\n })\r\n translate.do()\r\n for (let tick = 0, end = this.data.date.length; tick < end; tick += 10) {\r\n const x = Math.round(this.fx(tick) + this.leftOffset)\r\n if (x < -15 || x > this.width + 15) {\r\n // margin?\r\n continue\r\n }\r\n xLine.set({ x1: x, x2: x }).render(context)\r\n }\r\n translate.undo()\r\n }\r\n\r\n renderLabel(context: CanvasRenderingContext2D) {\r\n if (this.getIsChartPageSpecificFunctionality()) {\r\n this.renderLabelChartsPage(context)\r\n } else {\r\n this.renderLabelQuotePage(context)\r\n }\r\n }\r\n\r\n renderLabelQuotePage(context: CanvasRenderingContext2D) {\r\n const { IndicatorSettings, ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const label = new Text(\r\n {\r\n text: this.toString(),\r\n x: IndicatorSettings.left.indicatorLabel.margin.left,\r\n y: IndicatorSettings.left.indicatorLabel.margin.top,\r\n font: Text.getMergedPropsWithDefaults('font', IndicatorSettings.left.indicatorLabel.font),\r\n fillStyle: Colors.text,\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.top,\r\n },\r\n this.model\r\n )\r\n this.labelWidth = label.measure(context)\r\n return label.render(context)\r\n }\r\n\r\n renderLabelChartsPage(context: CanvasRenderingContext2D): { x: number; y: number; labelWidth: number } | void {\r\n const { IndicatorSettings } = this.getChartLayoutSettings()\r\n const { theme, specificChartFunctionality } = this.model.chart().chart_layout()\r\n const isDarkMode = theme === Theme.dark\r\n const x =\r\n specificChartFunctionality === SpecificChartFunctionality.quotePage\r\n ? OFFSET.S\r\n : IndicatorSettings.left.indicatorLabel.margin.left!\r\n const y = IndicatorSettings.left.indicatorLabel.margin.top!\r\n const label = new Text(\r\n {\r\n text: this.toString(),\r\n x: x * 2,\r\n font: Text.getMergedPropsWithDefaults('font', IndicatorSettings.left.indicatorLabel.font),\r\n fillStyle: tailwindColors.gray[isDarkMode ? 50 : 900],\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.middle,\r\n },\r\n this.model\r\n )\r\n this.labelWidth = label.measure(context) + IndicatorSettings.left.indicatorLabel.margin.left! * 2\r\n label.set({ y: y + (INDICATOR_LABEL_HEIGHT - label.attrs.lineHeight / 2) })\r\n roundedRect({\r\n ctx: context,\r\n x,\r\n y,\r\n height: INDICATOR_LABEL_HEIGHT,\r\n width: this.labelWidth,\r\n radius: 6,\r\n color: `${tailwindColors.gray[isDarkMode ? 700 : 50]}cc`,\r\n })\r\n label.render(context)\r\n\r\n return { x, y, labelWidth: this.labelWidth }\r\n }\r\n\r\n renderCross(context: CanvasRenderingContext2D) {\r\n renderCross({\r\n context,\r\n mouseModel,\r\n paneModel: this.model,\r\n quote: this.data,\r\n contentWidth: this.contentWidth,\r\n contentHeight: this.contentHeight,\r\n isIndicator: true,\r\n isPerfIndicator: this.type === IndicatorType.Perf,\r\n onRenderCrossText: !this.getIsChartPageSpecificFunctionality() ? this.renderCrossText : undefined,\r\n })\r\n\r\n if (this.getIsChartPageSpecificFunctionality()) {\r\n this.renderCrossText(context, mouseModel.getCrossIndexForPane(this.model))\r\n }\r\n }\r\n\r\n renderCrossText(context: CanvasRenderingContext2D, crossIndex: number) {\r\n this.data = this.model.chart().quote()\r\n const index = Number.isNaN(crossIndex) ? this.data.close.length - 1 : crossIndex\r\n if (this.getIsChartPageSpecificFunctionality()) {\r\n this.renderLabelChartsPage(context)\r\n\r\n this.renderCrossTextChartsPage(context, index)\r\n } else {\r\n this.renderCrossTextQuotePage(context, index)\r\n }\r\n }\r\n\r\n renderCrossTextChartsPage(_: CanvasRenderingContext2D, __: number) {}\r\n\r\n renderCrossTextQuotePage(_: CanvasRenderingContext2D, __: number) {}\r\n\r\n renderOversoldOverbought(\r\n context: CanvasRenderingContext2D,\r\n array: number[],\r\n from: number,\r\n oversold: number,\r\n zero: number,\r\n overbought: number,\r\n drawLines?: boolean\r\n ) {\r\n const { IndicatorSettings } = this.getChartLayoutSettings()\r\n if (this.data.close.length === 0) return\r\n const drawInVisibleAreaProps = {\r\n fromIndexOffset: from,\r\n leftOffset: this.leftOffset,\r\n paneModel: this.model,\r\n quote: this.data,\r\n width: this.width,\r\n }\r\n\r\n const firstBarToRenderIndex = getCompensatedFirstBarToRenderIndex(drawInVisibleAreaProps)\r\n\r\n if (drawLines == null) {\r\n drawLines = true\r\n }\r\n\r\n context.save()\r\n\r\n let clipHeight = Math.round(this.fy(oversold) - this.fy(this.model.scale.y.domain()[1]))\r\n if (clipHeight <= 0 || getIsSSr()) {\r\n context.beginPath()\r\n context.rect(\r\n -this.leftOffset,\r\n this.fy(this.model.scale.y.domain()[1]) + 1, // compensation to addition of 1 in clip function\r\n this.contentWidth,\r\n clipHeight < 0 ? clipHeight - 1 : -1 // clipHeight - 1 is a compensation to addition of 1 in clip function ; fix bug in skia-canvas when clip is incorrect if height is 0 or clip is outside of previous clip https://github.com/samizdatco/skia-canvas/issues/87\r\n )\r\n }\r\n context.clip()\r\n context.set('fillStyle', '#87ceef')\r\n\r\n context.beginPath()\r\n context.moveTo(this.fx(firstBarToRenderIndex), Math.round(this.fy(this.model.scale.y.domain()[0])))\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(array[i])))\r\n },\r\n })\r\n context.lineTo(this.fx(this.data.close.length - 1), Math.round(this.fy(this.model.scale.y.domain()[0])))\r\n context.fill()\r\n context.restore()\r\n if (drawLines) {\r\n new Line(\r\n {\r\n x1: -this.leftOffset,\r\n x2: -this.leftOffset + this.contentWidth,\r\n y1: Math.round(this.fy(oversold)),\r\n y2: Math.round(this.fy(oversold)),\r\n strokeStyle: '#69c1ea',\r\n },\r\n this.model\r\n ).render(context)\r\n }\r\n\r\n if (drawLines) {\r\n this.renderZeroLine(context, zero)\r\n }\r\n\r\n context.save()\r\n clipHeight = Math.round(this.fy(overbought))\r\n if (clipHeight >= 0 || getIsSSr()) {\r\n context.beginPath()\r\n context.rect(\r\n -this.leftOffset,\r\n this.fy(this.model.scale.y.domain()[0]),\r\n this.contentWidth,\r\n clipHeight > 0 ? clipHeight : 1 // // fix bug in skia-canvas when clip is incorrect if height is 0 or clip is outside of previous clip https://github.com/samizdatco/skia-canvas/issues/87\r\n )\r\n }\r\n\r\n context.clip()\r\n context.set('fillStyle', '#dc9fe5')\r\n context.beginPath()\r\n context.moveTo(this.fx(firstBarToRenderIndex), Math.round(this.fy(this.model.scale.y.domain()[1])))\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(array[i])))\r\n },\r\n })\r\n context.lineTo(this.fx(this.data.close.length - 1), Math.round(this.fy(this.model.scale.y.domain()[1]) + 1))\r\n context.fill()\r\n context.restore()\r\n if (drawLines) {\r\n new Line(\r\n {\r\n x1: -this.leftOffset,\r\n x2: -this.leftOffset + this.contentWidth,\r\n y1: Math.round(this.fy(overbought)),\r\n y2: Math.round(this.fy(overbought)),\r\n strokeStyle: '#d386df',\r\n },\r\n this.model\r\n ).render(context)\r\n }\r\n\r\n context.set('strokeStyle', IndicatorSettings.general.Colors.line)\r\n context.set('fillStyle', '#dc9fe5')\r\n\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(Math.round(x), Math.round(this.fy(array[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n renderZeroLine(context: CanvasRenderingContext2D, zero: number) {\r\n new Line(\r\n {\r\n x1: -this.leftOffset,\r\n x2: -this.leftOffset + this.contentWidth,\r\n y1: Math.round(this.fy(zero)),\r\n y2: Math.round(this.fy(zero)),\r\n strokeStyle: '#ff8787',\r\n dashLength: 3,\r\n },\r\n this.model\r\n ).render(context)\r\n }\r\n\r\n setupCache() {}\r\n\r\n clip(context: CanvasRenderingContext2D) {\r\n const { IndicatorSettings } = this.getChartLayoutSettings()\r\n context.beginPath()\r\n context.rect(IndicatorSettings.left.width, IndicatorSettings.top.height, this.contentWidth, this.contentHeight + 1) // +1 shows one more pixel which is needed to be able to see a line at very bottom of an indicaor\r\n return context.clip()\r\n }\r\n\r\n formatAxis(value: number, tickStep?: number) {\r\n if (tickStep !== undefined && 10 > tickStep) {\r\n return value.toFixed(2)\r\n }\r\n return value.toString()\r\n }\r\n\r\n fx = (x: number) => this.model.scale.x(this.data.barIndex[x])\r\n\r\n fy = (y: number) => this.model.scale.y(y)\r\n\r\n set(values: Partial) {\r\n const { IndicatorSettings } = this.getChartLayoutSettings()\r\n this.shouldUpdate = true\r\n for (const key in values) {\r\n if (key !== 'type') {\r\n // @ts-expect-error - values keys don't have to always match variables on the instance\r\n this[key] = values[key]\r\n }\r\n }\r\n this.width = this.model.chart().width\r\n this.contentWidth = this.width - IndicatorSettings.left.width - IndicatorSettings.right.width\r\n\r\n const newAttrs = this.getModalConfig()\r\n .inputs.map(({ value }) => value.toString())\r\n .join(',')\r\n if (newAttrs) this.attrs = { ...this.attrs, period: newAttrs }\r\n\r\n this.model.trigger(CustomSpineEvents.ManualChange)\r\n }\r\n\r\n parsePeriodInt(values: Partial) {\r\n if (typeof values.period === 'string') {\r\n this.period = Number.parseInt(values.period, 10)\r\n this.model.trigger(CustomSpineEvents.ManualChange)\r\n }\r\n }\r\n\r\n setModel(model: Pane) {\r\n return (this.model = model)\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n const { IndicatorSettings } = this.getChartLayoutSettings()\r\n const x = IndicatorSettings.left.indicatorLabel.margin.left!\r\n const y = IndicatorSettings.left.indicatorLabel.margin.top!\r\n let width = OFFSET.M * 2 + this.labelWidth\r\n let height = OFFSET.S * 2 + FONT_SIZE.M\r\n\r\n if (this.getIsChartPageSpecificFunctionality()) {\r\n width = this.labelWidth\r\n height = INDICATOR_LABEL_HEIGHT\r\n }\r\n\r\n if (x < area.cursorX && area.cursorX < width + x && y < area.cursorY && area.cursorY < height + y) {\r\n return true\r\n }\r\n return false\r\n }\r\n\r\n getIsInChartView(_: Chart) {\r\n return true\r\n }\r\n\r\n moveBy() {}\r\n\r\n thumbsAreInArea() {\r\n return false\r\n }\r\n\r\n computeVisibleMinMax(...arrays: number[][]) {\r\n let min = MAX_POSITIVE_DEFAULT_VALUE\r\n let max = MAX_NEGATIVE_DEFAULT_VALUE\r\n\r\n const { leftOffset } = this.model.chart()\r\n\r\n const firstBarToRenderIndex = getVisibleBarToRenderIndex({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset,\r\n })\r\n const lastBarToRenderIndex = getVisibleBarToRenderIndex({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset,\r\n chartWidth: this.contentWidth,\r\n })\r\n const areNoBarsVisible = getAreNoBarsVisible(firstBarToRenderIndex, lastBarToRenderIndex)\r\n\r\n for (const arr of arrays) {\r\n for (let i = firstBarToRenderIndex.index; i <= lastBarToRenderIndex.index; i++) {\r\n if (!isNaN(arr[i])) {\r\n min = Math.min(min, arr[i])\r\n max = Math.max(max, arr[i])\r\n }\r\n }\r\n }\r\n\r\n return !areNoBarsVisible && min !== max && min !== MAX_POSITIVE_DEFAULT_VALUE && max !== MAX_NEGATIVE_DEFAULT_VALUE\r\n ? { min, max }\r\n : this.getDomainDefaults(this.type)\r\n }\r\n\r\n getModalConfig(): IModalConfig {\r\n return {\r\n title: '',\r\n inputs: [],\r\n inputsErrorMessages: {},\r\n }\r\n }\r\n\r\n getDomainDefaults = (indicatorType: IndicatorType) => INDICATOR_DEFAULT_DOMAIN(indicatorType)\r\n\r\n getMinMax() {\r\n this.data = this.model.chart().quote()\r\n this.compute()\r\n return { min: this.min, max: this.max }\r\n }\r\n\r\n toObject() {\r\n return merge({}, this.attrs, { type: this.type, tickers: this.tickers })\r\n }\r\n\r\n toConfig(): T['attrs'] & { type: T['type'] } {\r\n return {\r\n type: this.type,\r\n period: this.getModalConfig()\r\n .inputs.map((input: IModalConfigInput) => input.value.toString())\r\n .join(','),\r\n }\r\n }\r\n\r\n getChartLayoutSettings() {\r\n return getChartLayoutSettings(this.model.chart().chart_layout())\r\n }\r\n\r\n renderIndicator(_: CanvasRenderingContext2D) {\r\n throw Error('Implement renderIndicator method')\r\n }\r\n\r\n getIsValid(_: string): boolean | undefined {\r\n throw Error('Implement')\r\n }\r\n\r\n getIsNumberInputValid({ key, integerOnly = true }: { key: string; integerOnly?: boolean }): boolean {\r\n const input = this.getModalConfig().inputs.find(({ name }: { name: string }) => key === name)\r\n return !!input && isInRange(input) && (!integerOnly || isPositiveInteger(input.value))\r\n }\r\n\r\n getIsChartPageSpecificFunctionality() {\r\n const { specificChartFunctionality } = this.model.chart().chart_layout()\r\n const isCharts = specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n const isRedesignedFuturesForexCrypto =\r\n isRedesignEnabled() &&\r\n [\r\n SpecificChartFunctionality.futuresPage,\r\n SpecificChartFunctionality.forexPage,\r\n SpecificChartFunctionality.cryptoPage,\r\n SpecificChartFunctionality.quotePage,\r\n ].includes(specificChartFunctionality)\r\n\r\n return isCharts || isRedesignedFuturesForexCrypto\r\n }\r\n\r\n getIsDrawing() {\r\n return false\r\n }\r\n\r\n getIsChartEvent() {\r\n return false\r\n }\r\n\r\n compute() {\r\n throw Error('Implement compute method')\r\n }\r\n}\r\n\r\nIndicator.initClass()\r\n\r\nexport default Indicator\r\n","export function roundedRect({\r\n ctx,\r\n x,\r\n y,\r\n width,\r\n height,\r\n radius,\r\n color,\r\n}: {\r\n ctx: CanvasRenderingContext2D\r\n x: number\r\n y: number\r\n width: number\r\n height: number\r\n radius: number\r\n color: string\r\n}) {\r\n ctx.translate(0.5, 0.5)\r\n ctx.set('strokeStyle', color)\r\n ctx.set('fillStyle', color)\r\n ctx.beginPath()\r\n ctx.moveTo(x, y + radius)\r\n ctx.lineTo(x, y + height - radius)\r\n ctx.arcTo(x, y + height, x + radius, y + height, radius)\r\n ctx.lineTo(x + width - radius, y + height)\r\n ctx.arcTo(x + width, y + height, x + width, y + height - radius, radius)\r\n ctx.lineTo(x + width, y + radius)\r\n ctx.arcTo(x + width, y, x + width - radius, y, radius)\r\n ctx.lineTo(x + radius, y)\r\n ctx.arcTo(x, y, x, y + radius, radius)\r\n ctx.stroke()\r\n ctx.fill()\r\n ctx.translate(-0.5, -0.5)\r\n}\r\n","import { IndicatorType } from '../constants/common'\r\nimport utils from '../utils'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n}\r\n\r\nclass ADX extends Indicator {\r\n static type = IndicatorType.Adx\r\n static label = 'ADX'\r\n\r\n declare period: number\r\n pdi: number[] = []\r\n mdi: number[] = []\r\n adx: number[] = []\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (this.isComputeNecessary()) {\r\n let adx, amdm, apdm, mdi, pdi\r\n this.pdi = []\r\n this.mdi = []\r\n this.adx = []\r\n let atr = (apdm = amdm = adx = 0)\r\n for (let i = this.period; i < this.data.close.length; i++) {\r\n const deltaHigh = this.data.high[i] - this.data.high[i - 1]\r\n const deltaLow = this.data.low[i - 1] - this.data.low[i]\r\n\r\n let pdm = 0\r\n if (deltaHigh > 0 && deltaHigh > deltaLow) {\r\n pdm = deltaHigh\r\n }\r\n\r\n let mdm = 0\r\n if (deltaLow > 0 && deltaLow > deltaHigh) {\r\n mdm = deltaLow\r\n }\r\n\r\n const tr = utils.max([\r\n this.data.high[i] - this.data.low[i],\r\n Math.abs(this.data.high[i] - this.data.close[i - 1]),\r\n Math.abs(this.data.low[i] - this.data.close[i - 1]),\r\n ])\r\n\r\n atr = (atr * (this.period - 1) + tr) / this.period\r\n apdm = (apdm * (this.period - 1) + pdm) / this.period\r\n amdm = (amdm * (this.period - 1) + mdm) / this.period\r\n\r\n pdi = atr > 0 ? (apdm * 100) / atr : 0\r\n mdi = atr > 0 ? (amdm * 100) / atr : 0\r\n const di = Math.abs(pdi - mdi)\r\n const dx = pdi + mdi > 0 ? (di * 100) / (pdi + mdi) : 0\r\n adx = (adx * (this.period - 1) + dx) / this.period\r\n\r\n this.pdi[i] = pdi\r\n this.mdi[i] = mdi\r\n this.adx[i] = adx\r\n }\r\n this.lastValue = this.adx.last() ?? null\r\n }\r\n const { min, max } =\r\n this.pdi.length > 0 || this.mdi.length > 0 || this.adx.length > 0\r\n ? this.computeVisibleMinMax(this.pdi, this.mdi, this.adx)\r\n : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n if (this.data.close.length === 0) return\r\n\r\n context.translate(0.5, 0.5)\r\n context.set('strokeStyle', '#2eb12e')\r\n context.beginPath()\r\n\r\n const drawInVisibleAreaProps = {\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n fromIndexOffset: this.period,\r\n }\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(this.pdi[i])))\r\n },\r\n })\r\n\r\n context.stroke()\r\n\r\n context.set('strokeStyle', '#d43737')\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(this.mdi[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.set('strokeStyle', this.getChartLayoutSettings().IndicatorSettings.general.Colors.line)\r\n context.beginPath()\r\n\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(this.adx[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 14,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `ADX ${this.period}`\r\n }\r\n}\r\n\r\nexport default ADX\r\n","import { IndicatorType } from '../constants/common'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype Options = {\r\n period: number\r\n}\r\n\r\ntype DefaultCalculatedValuesType = {\r\n aroonUp: number[]\r\n aroonDown: number[]\r\n oscillator: number[]\r\n}\r\n\r\nexport class AroonCalculation extends MainCalculation {\r\n static type = IndicatorType.Aro\r\n\r\n getDefaultCalculatedValues() {\r\n return {\r\n aroonUp: [],\r\n aroonDown: [],\r\n oscillator: [],\r\n }\r\n }\r\n\r\n calculate(onValueCalculated?: OnValueCalculated) {\r\n const { period } = this.options\r\n const { low, high } = this.quote\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n for (let i = period; i < high.length; i++) {\r\n const highPeriod = high.slice(i - period, i + 1)\r\n const highestInPeriod = Math.max(...highPeriod)\r\n const periodSinceHigh = period - highPeriod.lastIndexOf(highestInPeriod)\r\n this._calculatedValues.aroonUp[i] = 100 * ((period - periodSinceHigh) / period)\r\n\r\n const lowPeriod = low.slice(i - period, i + 1)\r\n const lowestInPeriod = Math.min(...lowPeriod)\r\n const periodSinceLow = period - lowPeriod.lastIndexOf(lowestInPeriod)\r\n this._calculatedValues.aroonDown[i] = 100 * ((period - periodSinceLow) / period)\r\n\r\n this._calculatedValues.oscillator[i] = this._calculatedValues.aroonUp[i] - this._calculatedValues.aroonDown[i]\r\n\r\n if (onValueCalculated?.(this.calculatedValues, i) === false) {\r\n break\r\n }\r\n }\r\n }\r\n}\r\n","import Text from '../canvas/text'\r\nimport { IndicatorType, OFFSET, PADDING, TextBaseline } from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport { AroonCalculation } from '../indicator-calculation/aroon'\r\nimport Pane from '../models/pane'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n}\r\n\r\nconst COLORS = {\r\n aroonUp: '#00a000',\r\n aroonDown: '#c80000',\r\n}\r\n\r\nclass Aroon extends Indicator {\r\n static type = IndicatorType.Aro\r\n static label = 'Aroon'\r\n\r\n aroonCalculation: AroonCalculation | null = null\r\n declare period: number\r\n\r\n constructor(attrs: Attrs, model: Pane) {\r\n super(attrs, model)\r\n this.renderYAxis = this.renderYAxis.bind(this)\r\n }\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (!this.isComputeNecessary() && this.aroonCalculation !== null) return\r\n\r\n this.aroonCalculation = new AroonCalculation({\r\n quote: this.data,\r\n options: { period: this.period },\r\n })\r\n\r\n this.aroonCalculation.calculate()\r\n\r\n const { min, max } = this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n if (this.data.close.length === 0 || !this.aroonCalculation) return\r\n\r\n context.translate(0.5, 0.5)\r\n context.set('strokeStyle', COLORS.aroonUp)\r\n context.beginPath()\r\n const drawInVisibleAreaProps = {\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n fromIndexOffset: this.period,\r\n }\r\n const { aroonUp, aroonDown } = this.aroonCalculation.calculatedValues\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(aroonUp[i])))\r\n },\r\n })\r\n context.stroke()\r\n\r\n context.set('strokeStyle', COLORS.aroonDown)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(aroonDown[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n renderYAxis(context: CanvasRenderingContext2D) {\r\n super.renderYAxis(context)\r\n if (!this.aroonCalculation) return\r\n const { IndicatorSettings, ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const { aroonUp, aroonDown } = this.aroonCalculation.calculatedValues\r\n\r\n const translate = getTranslate({\r\n context,\r\n xOffset: IndicatorSettings.left.width,\r\n yOffset: IndicatorSettings.top.height,\r\n })\r\n translate.do()\r\n const text = new Text(\r\n {\r\n x: this.contentWidth + OFFSET.M - PADDING.XXS + IndicatorSettings.right.axis.margin.left!,\r\n font: Text.getMergedPropsWithDefaults('font', IndicatorSettings.right.axis.font),\r\n lineHeight: IndicatorSettings.right.axis.font.lineHeight,\r\n padding: {\r\n top: IndicatorSettings.right.axis.font?.padding?.top ?? PADDING.XXS,\r\n right: IndicatorSettings.right.axis.font?.padding?.right ?? PADDING.XXS,\r\n bottom: IndicatorSettings.right.axis.font?.padding?.bottom ?? PADDING.XXS,\r\n left: IndicatorSettings.right.axis.font?.padding?.left ?? PADDING.XXS,\r\n },\r\n textBaseline: TextBaseline.middle,\r\n fillStyle: Colors.indicatorCurrentText,\r\n },\r\n this.model\r\n )\r\n const textLabels = []\r\n if (aroonDown.length > 0) {\r\n textLabels.push({\r\n text: aroonDown.last()!.toFixed(2),\r\n y: Math.round(this.fy(aroonDown.last()!)),\r\n background: COLORS.aroonDown,\r\n })\r\n }\r\n if (aroonUp.length > 0) {\r\n textLabels.push({\r\n text: aroonUp.last()!.toFixed(2),\r\n y: Math.round(this.fy(aroonUp.last()!)),\r\n background: COLORS.aroonUp,\r\n })\r\n }\r\n\r\n const minY = 0\r\n const maxY = this.height - IndicatorSettings.bottom.height - IndicatorSettings.top.height\r\n textLabels.forEach((labelSetting) => {\r\n if (labelSetting.y >= minY && labelSetting.y <= maxY) {\r\n text.set(labelSetting).render(context)\r\n }\r\n })\r\n\r\n translate.undo()\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 25,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `Aroon ${this.period}`\r\n }\r\n}\r\n\r\nexport default Aroon\r\n","import { IndicatorType } from '../constants/common'\r\nimport { AroonCalculation } from '../indicator-calculation/aroon'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n}\r\n\r\nclass AroonOscillator extends Indicator {\r\n static type = IndicatorType.Aroosc\r\n static label = 'Aroon Oscillator'\r\n\r\n aroonCalculation: AroonCalculation | null = null\r\n declare period: number\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (!this.isComputeNecessary() && this.aroonCalculation !== null) return\r\n\r\n this.aroonCalculation = new AroonCalculation({\r\n quote: this.data,\r\n options: { period: this.period },\r\n })\r\n\r\n this.aroonCalculation.calculate()\r\n\r\n this.lastValue = this.aroonCalculation.calculatedValues.oscillator.last() ?? null\r\n const { min, max } = this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n this.renderOversoldOverbought(\r\n context,\r\n this.aroonCalculation?.calculatedValues.oscillator ?? [],\r\n this.period,\r\n 0,\r\n 0,\r\n 0,\r\n false\r\n )\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 25,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `Aroon Oscillator ${this.period}`\r\n }\r\n}\r\n\r\nexport default AroonOscillator\r\n","import { IndicatorType } from '../constants/common'\r\nimport AverageTrueRange from '../helpers/atr'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n}\r\n\r\nclass ATR extends Indicator {\r\n static type = IndicatorType.Atr\r\n static label = 'Average True Range'\r\n\r\n atr: number[] = []\r\n declare period: number\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (this.isComputeNecessary()) {\r\n this.atr = []\r\n const atr = new AverageTrueRange(this.period)\r\n for (let i = 0; i < this.data.close.length; i++) {\r\n atr.add(this.data.high[i], this.data.low[i], this.data.close[i - 1])\r\n this.atr[i] = atr.value\r\n }\r\n\r\n this.lastValue = this.atr.last() ?? null\r\n }\r\n const { min, max } = this.atr.length > 0 ? this.computeVisibleMinMax(this.atr) : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n context.set('strokeStyle', this.getChartLayoutSettings().IndicatorSettings.general.Colors.line)\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i: number, x: number) => {\r\n context.lineTo(x, Math.round(this.fy(this.atr[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 14,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `ATR ${this.period}`\r\n }\r\n}\r\n\r\nexport default ATR\r\n","import { IndicatorType } from '../constants/common'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n}\r\n\r\nconst constant = 0.015\r\nclass CommodityChannelIndex extends Indicator {\r\n static type = IndicatorType.Cci\r\n static label = 'Commodity Channel Index'\r\n\r\n cci: number[] = []\r\n declare period: number\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (this.isComputeNecessary()) {\r\n let smaCount\r\n const tp = []\r\n this.cci = []\r\n let smaSum = (smaCount = 0)\r\n for (let i = 0; i < this.data.close.length; i++) {\r\n let devCount\r\n const typicalPrice = (this.data.close[i] + this.data.low[i] + this.data.high[i]) / 3\r\n tp[i] = typicalPrice\r\n\r\n smaSum += typicalPrice\r\n smaCount++\r\n if (smaCount > this.period) {\r\n smaSum -= tp[i - this.period]\r\n smaCount--\r\n }\r\n const sma = smaSum / smaCount\r\n\r\n if (i < this.period - 1) {\r\n continue\r\n }\r\n\r\n let devSum = (devCount = 0)\r\n for (let j = i - this.period + 1; j <= i; j++) {\r\n devSum += Math.abs(tp[j] - sma)\r\n devCount++\r\n }\r\n\r\n const dev = devSum / devCount\r\n this.cci[i] = 0\r\n if (dev > 0) {\r\n this.cci[i] = (typicalPrice - sma) / (constant * dev)\r\n }\r\n }\r\n\r\n this.lastValue = this.cci.last() ?? null\r\n }\r\n\r\n const { min, max } = this.cci.length > 0 ? this.computeVisibleMinMax(this.cci) : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n this.renderOversoldOverbought(context, this.cci, this.period, -100, 0, 100)\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 20,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `CCI ${this.period}`\r\n }\r\n}\r\n\r\nexport default CommodityChannelIndex\r\n","import * as d3 from 'd3'\r\n\r\nimport { ObjectHash, Theme } from '../../types/shared'\r\nimport Text from '../canvas/text'\r\nimport tailwindColors from '../constants/colors'\r\nimport { INDICATOR_LABEL_HEIGHT, IndicatorType, TextAlign, TextBaseline } from '../constants/common'\r\nimport utils from '../utils'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Indicator from './indicator'\r\n\r\nexport interface ICOT {\r\n code: string\r\n name: string\r\n units: string\r\n commercialHedgers: number[]\r\n largeTraders: number[]\r\n smallTraders: number[]\r\n}\r\n\r\ninterface Attrs {\r\n period: string\r\n code: string\r\n}\r\n\r\ntype ColorsKeys = keyof Pick\r\n\r\nclass COT extends Indicator {\r\n static type = IndicatorType.Cot\r\n static label = 'COT'\r\n\r\n static getNumOfBarsBuffer() {\r\n return 0\r\n }\r\n\r\n declare colors: ObjectHash\r\n\r\n compute() {\r\n if (!this.isComputeNecessary() || !this.data.COTs) return\r\n const cotQuoteCode = Object.keys(this.data.COTs)[0]\r\n if (!this.attrs.code && cotQuoteCode) {\r\n this.attrs.code = cotQuoteCode\r\n }\r\n const cot = this.data.COTs[this.attrs.code]\r\n const [min, max] = utils.minMax(cot.commercialHedgers, cot.largeTraders, cot.smallTraders)\r\n this.max = Math.max(Math.abs(max), Math.abs(min))\r\n this.min = -this.max\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n if (!this.data.COTs) return\r\n context.translate(0.5, 0.5)\r\n for (const key in this.colors) {\r\n context.set('strokeStyle', this.colors[key as ColorsKeys])\r\n context.beginPath()\r\n const data = this.data.COTs[this.attrs.code][key as ColorsKeys]\r\n drawInVisibleArea({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i: number, x: number) => {\r\n context.lineTo(x, Math.round(this.fy(data[i])))\r\n },\r\n })\r\n context.stroke()\r\n }\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n renderLabel(context: CanvasRenderingContext2D) {\r\n if (!this.data.COTs) return\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const name = new Text(\r\n {\r\n text: this.toString(),\r\n x: 8,\r\n y: 16,\r\n font: { size: 10, style: 'bold' },\r\n fillStyle: Colors.text,\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.bottom,\r\n },\r\n this.model\r\n )\r\n name.render(context)\r\n\r\n new Text(\r\n {\r\n text: this.data.COTs[this.attrs.code].units as string,\r\n x: 38 + name.measure(),\r\n y: 16,\r\n font: { size: 8 },\r\n fillStyle: Colors.text,\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.bottom,\r\n },\r\n this.model\r\n ).render(context)\r\n\r\n this.renderAdditionalLabels(context)\r\n }\r\n\r\n renderLabelChartsPage(context: CanvasRenderingContext2D) {\r\n const { x, y, labelWidth } = super.renderLabelChartsPage(context) as { x: number; y: number; labelWidth: number }\r\n\r\n const { IndicatorSettings } = this.getChartLayoutSettings()\r\n const isDarkMode = this.model.chart().chart_layout().theme === Theme.dark\r\n const secondarylabelX = labelWidth + x * 2\r\n const fontSettings = IndicatorSettings.left.indicatorLabel.font\r\n const scaleCoefficient = 0.7\r\n\r\n const secondarylabel = new Text(\r\n {\r\n text: this.data.COTs[this.attrs.code].units as string,\r\n x: secondarylabelX + x,\r\n font: Text.getMergedPropsWithDefaults('font', {\r\n ...fontSettings,\r\n size: fontSettings.size ? fontSettings.size * scaleCoefficient : undefined,\r\n style: 'normal',\r\n }),\r\n fillStyle: tailwindColors.gray[isDarkMode ? 50 : 900],\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.middle,\r\n },\r\n this.model\r\n )\r\n secondarylabel.set({\r\n y: y + (INDICATOR_LABEL_HEIGHT * scaleCoefficient - (secondarylabel.attrs.lineHeight * scaleCoefficient) / 2),\r\n })\r\n secondarylabel.render(context)\r\n\r\n this.renderAdditionalLabels(context)\r\n }\r\n\r\n renderAdditionalLabels(context: CanvasRenderingContext2D) {\r\n const { ChartSettings, IndicatorSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n\r\n new Text(\r\n {\r\n text: 'COT',\r\n x: 23,\r\n y: IndicatorSettings.top.height + (IndicatorSettings.bottom.height + this.contentHeight) / 2,\r\n angle: -90,\r\n font: { size: 10, weight: '900', family: 'Lato, sans-serif' },\r\n fillStyle: Colors.textSecondary,\r\n textAlign: TextAlign.center,\r\n textBaseline: TextBaseline.alphabetic,\r\n },\r\n this.model\r\n ).render(context)\r\n\r\n const text = new Text(\r\n {\r\n text: 'Commercial Hedgers',\r\n x: IndicatorSettings.left.width,\r\n y: IndicatorSettings.top.height + this.contentHeight + IndicatorSettings.bottom.height - 1, // allign to very bottom of indicator with 1 pixel bottom padding\r\n font: { size: 8, style: 'bold' },\r\n fillStyle: this.colors.commercialHedgers,\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.bottom,\r\n },\r\n this.model\r\n )\r\n text.render(context)\r\n\r\n let x = text.get('x')! + 8 + text.measure()\r\n text.set({ text: 'Large Traders', x, fillStyle: this.colors.largeTraders })\r\n text.render(context)\r\n\r\n x += 8 + text.measure()\r\n text.set({ text: 'Small Traders', x, fillStyle: this.colors.smallTraders })\r\n text.render(context)\r\n }\r\n\r\n formatAxis(value: number) {\r\n // https://github.com/d3/d3-format/blob/master/README.md#locale_formatPrefix\r\n const scaleY = this.model.scale.y as unknown as d3.ScaleLinear\r\n return scaleY.tickFormat(4, 's')(value).replace(/G/, 'B')\r\n }\r\n\r\n getModalConfig() {\r\n return {\r\n title: 'COT',\r\n inputs: [],\r\n inputsErrorMessages: {},\r\n }\r\n }\r\n\r\n toString() {\r\n return this.data?.COTs ? (this.data.COTs[this.attrs.code].name as string) : undefined\r\n }\r\n\r\n toConfig(): T['attrs'] & { type: T['type'] } {\r\n return {\r\n type: this.type,\r\n code: this.attrs.code,\r\n }\r\n }\r\n}\r\n\r\nCOT.prototype.colors = {\r\n commercialHedgers: '#10cc10',\r\n largeTraders: '#cc1010',\r\n smallTraders: '#1010cc',\r\n}\r\n\r\nexport default COT\r\n","import { IndicatorType } from '../constants/common'\r\nimport { ExponentialMovingAverage } from './ema'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype Options = {\r\n period: number\r\n}\r\n\r\ntype DefaultCalculatedValuesType = {\r\n fi: number[]\r\n}\r\n\r\nexport class FICalculation extends MainCalculation {\r\n static type = IndicatorType.Fi\r\n\r\n getDefaultCalculatedValues() {\r\n return { fi: [] }\r\n }\r\n\r\n calculate(onValueCalculated?: OnValueCalculated) {\r\n const { period } = this.options\r\n const { close, volume } = this.quote\r\n const ema = new ExponentialMovingAverage(period)\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n for (let index = 1; index < close.length; index++) {\r\n const value = ((close[index] - close[index - 1]) * volume[index]) / 1000000\r\n ema.add(value)\r\n this.calculatedValues.fi[index] = ema.value\r\n\r\n if (onValueCalculated?.(this.calculatedValues, index) === false) {\r\n break\r\n }\r\n }\r\n }\r\n}\r\n","import { IndicatorType } from '../constants/common'\r\nimport { FICalculation } from '../indicator-calculation/fi'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n}\r\n\r\nclass ForceIndex extends Indicator {\r\n static type = IndicatorType.Fi\r\n static label = 'Force Index'\r\n\r\n fiCalculation: FICalculation | null = null\r\n declare period: number\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (this.isComputeNecessary()) {\r\n this.fiCalculation = new FICalculation({\r\n quote: this.data,\r\n options: {\r\n period: this.period,\r\n },\r\n })\r\n this.fiCalculation.calculate()\r\n this.lastValue = this.fiCalculation.calculatedValues.fi.last() ?? null\r\n }\r\n const fi = this.fiCalculation?.calculatedValues.fi ?? []\r\n const { min, max } = fi.length > 0 ? this.computeVisibleMinMax(fi) : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n this.renderOversoldOverbought(context, this.fiCalculation?.calculatedValues.fi ?? [], 1, 0, 0, 0, false)\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 13,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `FORCE ${this.period}`\r\n }\r\n}\r\n\r\nexport default ForceIndex\r\n","import { IndicatorType } from '../constants/common'\r\nimport { ExponentialMovingAverage } from './ema'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype Options = {\r\n fastPeriod: number\r\n slowPeriod: number\r\n signalPeriod: number\r\n}\r\n\r\ntype DefaultCalculatedValuesType = {\r\n macd: number[]\r\n signal: number[]\r\n histogram: number[]\r\n}\r\n\r\nexport class MACDCalculation extends MainCalculation {\r\n static type = IndicatorType.Macd\r\n\r\n getDefaultCalculatedValues() {\r\n return {\r\n macd: [],\r\n signal: [],\r\n histogram: [],\r\n }\r\n }\r\n\r\n calculate(onValueCalculated?: OnValueCalculated) {\r\n const { close } = this.quote\r\n const { fastPeriod, slowPeriod, signalPeriod } = this.options\r\n const emaFast = new ExponentialMovingAverage(fastPeriod)\r\n const emaSlow = new ExponentialMovingAverage(slowPeriod)\r\n const emaSignal = new ExponentialMovingAverage(signalPeriod)\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n for (let i = 0; i < close.length; i++) {\r\n const d = close[i]\r\n\r\n emaFast.add(d)\r\n emaSlow.add(d)\r\n const macd = emaFast.value - emaSlow.value\r\n emaSignal.add(macd)\r\n\r\n this.calculatedValues.macd[i] = macd\r\n this.calculatedValues.signal[i] = emaSignal.value\r\n this.calculatedValues.histogram[i] = macd - emaSignal.value\r\n\r\n if (onValueCalculated?.(this.calculatedValues, i) === false) {\r\n break\r\n }\r\n }\r\n }\r\n}\r\n","import { ChartConfigChartPaneElement, RequireByKey } from '../../types/shared'\r\nimport { IndicatorType } from '../constants/common'\r\nimport { MACDCalculation } from '../indicator-calculation/macd'\r\nimport { getBarWidthWithMarginByParts } from '../utils/chart'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n fastPeriod: number\r\n slowPeriod: number\r\n signalPeriod: number\r\n}\r\n\r\nclass MACD extends Indicator {\r\n static type = IndicatorType.Macd\r\n static label = 'MACD'\r\n\r\n static getNumOfBarsBuffer({ period }: RequireByKey) {\r\n const [fastPeriod = 0, slowPeriod = 0, signalPeriod = 0] = getParsedIntegersFromPeriodString(period)\r\n return Math.max(fastPeriod, slowPeriod, signalPeriod)\r\n }\r\n\r\n macdCalculation: MACDCalculation | null = null\r\n\r\n declare fastPeriod: number\r\n declare slowPeriod: number\r\n declare signalPeriod: number\r\n\r\n set(values: Partial) {\r\n if (typeof values.period === 'string') {\r\n const [fastPeriod = 0, slowPeriod = 0, signalPeriod = 0] = getParsedIntegersFromPeriodString(this.attrs.period)\r\n super.set({ ...values, fastPeriod, slowPeriod, signalPeriod })\r\n } else {\r\n super.set(values)\r\n }\r\n }\r\n\r\n compute() {\r\n if (this.isComputeNecessary() || this.macdCalculation === null) {\r\n this.macdCalculation = new MACDCalculation({\r\n quote: this.data,\r\n options: {\r\n signalPeriod: this.signalPeriod,\r\n fastPeriod: this.fastPeriod,\r\n slowPeriod: this.slowPeriod,\r\n },\r\n })\r\n this.macdCalculation.calculate()\r\n\r\n this.lastValue = this.macdCalculation.calculatedValues.macd.last() ?? null\r\n }\r\n\r\n const { macd, histogram, signal } = this.macdCalculation.calculatedValues\r\n\r\n const { min, max } =\r\n macd.length > 0 || signal.length > 0 || histogram.length > 0\r\n ? this.computeVisibleMinMax(macd, signal, histogram)\r\n : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n const { IndicatorSettings } = this.getChartLayoutSettings()\r\n if (this.macdCalculation === null || this.data.close.length === 0) return\r\n const y = Math.round(this.fy(0))\r\n const chartModel = this.model.chart()\r\n const { zoomFactor } = chartModel\r\n const { barFillWidth, barBorderWidth } = getBarWidthWithMarginByParts({\r\n zoomFactor,\r\n chartLayout: chartModel.chart_layout(),\r\n })\r\n const barWidthWithoutMargin = barFillWidth + barBorderWidth * 2\r\n const halfBarWidth = ~~Math.max(1, barWidthWithoutMargin / 2)\r\n const { macd, histogram, signal } = this.macdCalculation.calculatedValues\r\n const drawInVisibleAreaProps = {\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n }\r\n\r\n context.set('fillStyle', '#79c3e8')\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.rect(x - halfBarWidth, y, barWidthWithoutMargin, Math.round(this.fy(histogram[i]) - y))\r\n },\r\n })\r\n context.fill()\r\n\r\n context.translate(0.5, 0.5)\r\n context.set('strokeStyle', IndicatorSettings.general.Colors.line)\r\n context.beginPath()\r\n\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(macd[i])))\r\n },\r\n })\r\n context.stroke()\r\n\r\n context.set('strokeStyle', IndicatorSettings.general.Colors.signalLine)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(signal[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const fastPeriod = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'fastPeriod',\r\n value: this.fastPeriod ?? 12,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n const slowPeriod = {\r\n type: 'number',\r\n label: 'Slow',\r\n name: 'slowPeriod',\r\n value: this.slowPeriod ?? 26,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n const signalPeriod = {\r\n type: 'number',\r\n label: 'Signal',\r\n name: 'signalPeriod',\r\n value: this.signalPeriod ?? 9,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [fastPeriod, slowPeriod, signalPeriod],\r\n inputsErrorMessages: {\r\n fastPeriod: `${fastPeriod.label} must be a whole number between ${fastPeriod.min} and ${fastPeriod.max}`,\r\n slowPeriod: `${slowPeriod.label} must be a whole number between ${slowPeriod.min} and ${slowPeriod.max}`,\r\n signalPeriod: `${signalPeriod.label} must be a whole number between ${signalPeriod.min} and ${signalPeriod.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'fastPeriod':\r\n case 'slowPeriod':\r\n case 'signalPeriod':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `MACD ${this.fastPeriod},${this.slowPeriod},${this.signalPeriod}`\r\n }\r\n}\r\n\r\nexport default MACD\r\n","import { IndicatorType } from '../constants/common'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n}\r\n\r\nclass MFI extends Indicator {\r\n static type = IndicatorType.Mfi\r\n static label = 'Money Flow Index'\r\n\r\n mfi: number[] = []\r\n declare period: number\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (!this.isComputeNecessary()) return\r\n\r\n let negativeMoneyFlow\r\n const mf = []\r\n this.mfi = []\r\n let prevTypicalPrice = (this.data.close[0] + this.data.low[0] + this.data.high[0]) / 3\r\n let positiveMoneyFlow = (negativeMoneyFlow = 0)\r\n for (let i = 1; i < this.data.close.length; i++) {\r\n const typicalPrice = (this.data.close[i] + this.data.low[i] + this.data.high[i]) / 3\r\n const moneyFlow = typicalPrice * this.data.volume[i]\r\n\r\n if (typicalPrice > prevTypicalPrice) {\r\n positiveMoneyFlow += moneyFlow\r\n mf[i] = moneyFlow\r\n } else if (typicalPrice < prevTypicalPrice) {\r\n negativeMoneyFlow += moneyFlow\r\n mf[i] = -moneyFlow\r\n }\r\n\r\n if (i > this.period) {\r\n const oldMF = mf[i - this.period]\r\n if (oldMF > 0) {\r\n positiveMoneyFlow -= oldMF\r\n } else if (oldMF < 0) {\r\n negativeMoneyFlow += oldMF\r\n }\r\n\r\n if (positiveMoneyFlow + negativeMoneyFlow > 0) {\r\n this.mfi[i] = (positiveMoneyFlow * 100) / (positiveMoneyFlow + negativeMoneyFlow)\r\n } else {\r\n this.mfi[i] = 50\r\n }\r\n }\r\n\r\n prevTypicalPrice = typicalPrice\r\n }\r\n\r\n this.lastValue = this.mfi.last() ?? null\r\n const { min, max } = this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n this.renderOversoldOverbought(context, this.mfi, this.period, 20, 50, 80)\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 14,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `MFI ${this.period}`\r\n }\r\n}\r\n\r\nexport default MFI\r\n","import { IndicatorType } from '../constants/common'\r\nimport Indicator from './indicator'\r\n\r\nclass None extends Indicator {\r\n static type = IndicatorType.None\r\n static label = 'None'\r\n\r\n compute() {}\r\n\r\n renderIndicator() {}\r\n\r\n toString() {\r\n return ''\r\n }\r\n}\r\n\r\nexport default None\r\n","import { IndicatorType } from '../constants/common'\r\nimport math from '../helpers/math'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Indicator from './indicator'\r\n\r\nclass OBV extends Indicator {\r\n static type = IndicatorType.Obv\r\n static label = 'On-Balance Volume'\r\n\r\n obv: number[] = []\r\n\r\n compute() {\r\n if (this.isComputeNecessary()) {\r\n this.obv = [0]\r\n\r\n for (let i = 1; i < this.data.volume.length; i++) {\r\n let currentObv = this.obv[i - 1]\r\n if (this.data.close[i] > this.data.close[i - 1]) {\r\n currentObv += this.data.volume[i]\r\n } else if (this.data.close[i] < this.data.close[i - 1]) {\r\n currentObv -= this.data.volume[i]\r\n }\r\n\r\n this.obv[i] = currentObv\r\n }\r\n\r\n this.lastValue = this.obv.last() ?? null\r\n }\r\n const { min, max } = this.obv.length > 0 ? this.computeVisibleMinMax(this.obv) : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n context.set('strokeStyle', this.getChartLayoutSettings().IndicatorSettings.general.Colors.line)\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i: number, x: number) => {\r\n context.lineTo(x, Math.round(this.fy(this.obv[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n formatAxis(value: number) {\r\n return math.formatBigNumber(value, 2)\r\n }\r\n\r\n getModalConfig() {\r\n return {\r\n title: this.label,\r\n inputs: [],\r\n inputsErrorMessages: {},\r\n }\r\n }\r\n\r\n toString() {\r\n return 'OBV'\r\n }\r\n}\r\n\r\nexport default OBV\r\n","import * as d3 from 'd3'\r\n\r\nimport { ObjectHash } from '../../types/shared'\r\nimport Line from '../canvas/line'\r\nimport Text from '../canvas/text'\r\nimport {\r\n INDICATOR_LABEL_HEIGHT,\r\n IndicatorType,\r\n MOBILE_VIEW_BREAKPOINT_WIDTH,\r\n OFFSET,\r\n PADDING,\r\n TextAlign,\r\n TextBaseline,\r\n} from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport Pane from '../models/pane'\r\nimport Quote from '../models/quote'\r\nimport { getSanitizedTicker } from '../utils'\r\nimport { getInstrument } from '../utils/chart'\r\nimport { getHEXWithSpecificAplha } from '../utils/colors'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n tickers?: string\r\n}\r\n\r\nconst DEFAULT_TICKERS = 'SPY,QQQ'\r\n\r\nclass PricePerformance extends Indicator {\r\n static type = IndicatorType.Perf\r\n static label = 'Price Performance %'\r\n\r\n static getNumOfBarsBuffer() {\r\n return 0\r\n }\r\n\r\n timeframe: string\r\n tickers = ''\r\n ready = false\r\n firstFetchCalled = false\r\n first: ObjectHash = {}\r\n perf: ObjectHash = {}\r\n quotes: ObjectHash = {}\r\n indicatorLabelWidth: ObjectHash = {}\r\n\r\n constructor(attrs: Attrs, model: Pane) {\r\n super(attrs, model)\r\n this.renderYAxis = this.renderYAxis.bind(this)\r\n\r\n this.timeframe = this.model.chart().timeframe\r\n this.fy = d3.scaleLinear().range([0, this.contentHeight])\r\n if (this.attrs.period && !this.tickers) {\r\n this.tickers = this.attrs.period\r\n }\r\n }\r\n\r\n async compute() {\r\n const tickers = this.getTickers()\r\n const chartLayoutModel = this.model.chart().chart_layout()\r\n const chartUuid = chartLayoutModel.uuid\r\n const hasCachedData = this.getTickersAndTimeframe().every(\r\n ({ ticker, instrument, timeframe }) =>\r\n Quote.select(\r\n (q: Quote) =>\r\n q.ticker === ticker &&\r\n q.instrument === instrument &&\r\n q.timeframe === timeframe &&\r\n chartLayoutModel.isIdeaId(q.ideaID) &&\r\n chartUuid === q.chartUuid &&\r\n !q.isFetching\r\n ).length > 0\r\n )\r\n\r\n if (this.timeframe !== this.model.chart().quote().timeframe || (!this.ready && !this.firstFetchCalled)) {\r\n this.timeframe = this.model.chart().quote().timeframe\r\n this.firstFetchCalled = true\r\n\r\n if (!hasCachedData) {\r\n const data = await Quote.getAll(this.getTickersAndTimeframe())\r\n if (data) {\r\n this._compute(tickers, data)\r\n this.trigger('change')\r\n }\r\n } else {\r\n this.ready = true\r\n this.compute()\r\n }\r\n } else if (this.ready) {\r\n const data: ObjectHash = {}\r\n for (const ticker of tickers) {\r\n data[ticker] = Quote.select(\r\n (q: Quote) =>\r\n q.ticker === ticker &&\r\n q.timeframe === this.timeframe &&\r\n chartUuid === q.chartUuid &&\r\n chartLayoutModel.isIdeaId(q.ideaID)\r\n )[0]\r\n }\r\n this._compute(tickers, data)\r\n }\r\n }\r\n\r\n _compute(tickers: string[], data: ObjectHash) {\r\n const { leftOffset } = this.model.chart()\r\n let firstBarTime = null\r\n let lastBarTime = null\r\n for (let i = 0; i < this.data.close.length; i++) {\r\n const center = this.fx(i)\r\n if (center + leftOffset < 0 || center + leftOffset > this.contentWidth) {\r\n // margin?\r\n continue\r\n }\r\n\r\n // Rendering one extra bar out of viewport ensures continuity of line, if there are missing data on intraday the indicator may have gaps\r\n if (firstBarTime === null) {\r\n firstBarTime = this.data.date[i]\r\n }\r\n\r\n lastBarTime = this.data.date[i]\r\n }\r\n\r\n data[this.data.ticker] = this.data\r\n this.quotes = data\r\n this.perf = {}\r\n const dateToIndex = this.data.getDateToIndex()\r\n for (const ticker of [this.data.ticker, ...tickers]) {\r\n this.perf[ticker] = []\r\n const d = data[ticker]\r\n if (!d) {\r\n continue\r\n }\r\n let first = null\r\n let index = -1\r\n for (let i = 0; i < d.close.length; i++) {\r\n const date = d.date[i]\r\n if (date < firstBarTime! || date > lastBarTime!) {\r\n continue\r\n }\r\n\r\n index = dateToIndex[date]\r\n if (index === undefined || index === null) {\r\n continue\r\n }\r\n\r\n if (first === null) {\r\n first = d.close[i]\r\n this.first[ticker] = first\r\n if (index > 0) {\r\n this.perf[ticker][index - 1] = (d.close[i] * 100) / first - 100\r\n }\r\n }\r\n\r\n this.perf[ticker][index] = (d.close[i] * 100) / first - 100\r\n }\r\n\r\n if (index < this.data.date.length - 1 && first !== null) {\r\n this.perf[ticker][index + 1] = this.perf[ticker][index]\r\n }\r\n }\r\n\r\n const perfArrays = Object.keys(this.perf).map((x) => this.perf[x])\r\n const { min, max } = perfArrays.some((array) => array.length > 0)\r\n ? this.computeVisibleMinMax(...perfArrays)\r\n : this.getDomainDefaults(this.type)\r\n\r\n this.min = min\r\n this.max = max\r\n\r\n const fy = d3\r\n .scaleLinear()\r\n .range([0, this.contentHeight])\r\n .domain([this.model.scaleRange?.max ?? this.max, this.model.scaleRange?.min ?? this.min])\r\n if (!this.model.scaleRange) {\r\n fy.nice(10)\r\n }\r\n // @ts-expect-error - TODO scale.y types dont match\r\n this.model.scale.y = this.fy = fy\r\n this.ready = true\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n if (!this.ready) {\r\n return\r\n }\r\n const { ColorsSettings, IndicatorSettings } = this.getChartLayoutSettings()\r\n new Line(\r\n {\r\n x1: -this.leftOffset,\r\n x2: -this.leftOffset + this.contentWidth,\r\n y1: Math.round(this.fy(0)),\r\n y2: Math.round(this.fy(0)),\r\n strokeStyle: '#ff8787',\r\n dashLength: 3,\r\n },\r\n this.model\r\n ).render(context)\r\n\r\n context.translate(0.5, 0.5)\r\n const iterable = this.getTickers()\r\n for (let index = 0; index < iterable.length; index++) {\r\n const ticker = iterable[index]\r\n if (this.perf[ticker].length > 0) {\r\n context.set('strokeStyle', ColorsSettings[index % ColorsSettings.length])\r\n context.beginPath()\r\n for (let i = 0; i < this.perf[ticker].length; i++) {\r\n const y = Math.round(this.fy(this.perf[ticker][i]))\r\n context.lineTo(this.fx(i), y)\r\n }\r\n context.stroke()\r\n }\r\n }\r\n\r\n context.set('strokeStyle', IndicatorSettings.general.Colors.line)\r\n context.beginPath()\r\n for (let i = 0; i < this.perf[this.data.ticker].length; i++) {\r\n const y = Math.round(this.fy(this.perf[this.data.ticker][i]))\r\n if (!isNaN(y)) {\r\n context.lineTo(this.fx(i), y)\r\n }\r\n }\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n renderCrossTextQuotePage(context: CanvasRenderingContext2D, crossIndex: number) {\r\n if (!context || !crossIndex) {\r\n return\r\n }\r\n const { ColorsSettings, ChartSettings, IndicatorSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const tickers = [this.data.ticker, ...this.getTickers()]\r\n tickers.forEach((key, index) => {\r\n const crossIndexTickerTimeStamp = this.quotes?.[this.data.ticker]?.getDataByBarIndex('date', crossIndex)\r\n const tickerDateToIndex = crossIndexTickerTimeStamp\r\n ? this.quotes?.[key]?.getDateToIndex()?.[crossIndexTickerTimeStamp]\r\n : null\r\n const tickerPerformance = tickerDateToIndex\r\n ? (this.quotes?.[key]?.close?.[tickerDateToIndex] * 100) / this.first[key] - 100\r\n : null\r\n if (tickerPerformance !== null && !isNaN(tickerPerformance)) {\r\n context.fillStyle = Colors.canvasFill\r\n context.fillRect(\r\n IndicatorSettings.left.indicatorLabel.margin.left! - PADDING.XXXS,\r\n (IndicatorSettings.left.indicatorLabel.font.lineHeight! +\r\n IndicatorSettings.left.indicatorLabel.labelSpacing) *\r\n (index + 1) +\r\n IndicatorSettings.left.indicatorLabel.margin.top! -\r\n PADDING.XXXS,\r\n PADDING.XXXS + this.indicatorLabelWidth[key] + PADDING.XXXS,\r\n PADDING.XXXS + IndicatorSettings.left.indicatorLabel.font.size! + PADDING.XXXS\r\n )\r\n new Text(\r\n {\r\n text: `${key} ${tickerPerformance.toFixed(2)}%`,\r\n x: IndicatorSettings.left.indicatorLabel.margin.left,\r\n y:\r\n (IndicatorSettings.left.indicatorLabel.font.lineHeight! +\r\n IndicatorSettings.left.indicatorLabel.labelSpacing) *\r\n (index + 1) +\r\n IndicatorSettings.left.indicatorLabel.margin.top!,\r\n font: Text.getMergedPropsWithDefaults('font', IndicatorSettings.left.indicatorLabel.font),\r\n fillStyle:\r\n index === 0 ? Colors.performanceIndicatorLabel : ColorsSettings[index - (1 % ColorsSettings.length)],\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.top,\r\n },\r\n this.model\r\n ).render(context)\r\n }\r\n })\r\n }\r\n\r\n renderCrossTextChartsPage(context: CanvasRenderingContext2D, crossIndex: number) {\r\n if (!context || !crossIndex) {\r\n return\r\n }\r\n\r\n const { ColorsSettings, ChartSettings, IndicatorSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n let isVertical = true\r\n const labelBottom = IndicatorSettings.left.indicatorLabel.margin.top! + INDICATOR_LABEL_HEIGHT\r\n const tickers = [this.data.ticker, ...this.getTickers()]\r\n const tickerText = new Text(\r\n {\r\n font: Text.getMergedPropsWithDefaults('font', {\r\n ...IndicatorSettings.left.indicatorLabel.font,\r\n style: 'normal',\r\n }),\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.middle,\r\n background: getHEXWithSpecificAplha(Colors.canvasFill, 0.8),\r\n padding: { top: 0, bottom: 0, left: 5, right: 5 },\r\n },\r\n this.model\r\n )\r\n let x = IndicatorSettings.left.indicatorLabel.margin.left!\r\n let y =\r\n IndicatorSettings.left.indicatorLabel.margin.top! + (2 * INDICATOR_LABEL_HEIGHT - tickerText.attrs.lineHeight) / 2\r\n\r\n const maxHeight = tickerText.attrs.lineHeight * tickers.length\r\n\r\n const canFitItemsVertically = maxHeight + labelBottom <= this.height\r\n if (this.width <= MOBILE_VIEW_BREAKPOINT_WIDTH || !canFitItemsVertically) {\r\n isVertical = false\r\n x += x + this.labelWidth\r\n } else {\r\n y += IndicatorSettings.left.indicatorLabel.margin.top! + INDICATOR_LABEL_HEIGHT\r\n }\r\n\r\n const tickerQuote = this.quotes?.[this.data.ticker]\r\n const maxCrossIndex = Math.min(crossIndex, (tickerQuote?.close.length ?? Infinity) - 1)\r\n tickers.forEach((key, index) => {\r\n const crossIndexTickerTimeStamp = tickerQuote?.getDataByBarIndex('date', maxCrossIndex)\r\n const tickerDateToIndex = crossIndexTickerTimeStamp\r\n ? this.quotes?.[key]?.getDateToIndex()?.[crossIndexTickerTimeStamp]\r\n : null\r\n const tickerPerformance = tickerDateToIndex\r\n ? (this.quotes?.[key]?.close?.[tickerDateToIndex] * 100) / this.first[key] - 100\r\n : null\r\n if (tickerPerformance !== null && !isNaN(tickerPerformance)) {\r\n tickerText.set({\r\n x,\r\n y,\r\n fillStyle:\r\n index === 0 ? Colors.performanceIndicatorLabel : ColorsSettings[index - (1 % ColorsSettings.length)],\r\n text: `${key} ${tickerPerformance.toFixed(2)}%`,\r\n })\r\n const tickerTextWidth =\r\n tickerText.measure(context) + tickerText.attrs.padding.left + tickerText.attrs.padding.right\r\n if (\r\n !isVertical &&\r\n this.width - IndicatorSettings.left.indicatorLabel.margin.left! - IndicatorSettings.right.width! <=\r\n x + tickerTextWidth\r\n ) {\r\n x = 2 * IndicatorSettings.left.indicatorLabel.margin.left! + this.labelWidth\r\n y += tickerText.attrs.lineHeight\r\n tickerText.set({ x, y })\r\n }\r\n tickerText.render(context)\r\n\r\n if (isVertical) {\r\n y += tickerText.attrs.lineHeight\r\n } else {\r\n x += tickerTextWidth\r\n }\r\n }\r\n })\r\n }\r\n\r\n renderXAxis(context: CanvasRenderingContext2D) {\r\n if (!this.ready) {\r\n return\r\n }\r\n return super.renderXAxis(context)\r\n }\r\n\r\n renderYAxis(context: CanvasRenderingContext2D) {\r\n let ticker\r\n super.renderYAxis(context)\r\n const { IndicatorSettings, ChartSettings, ColorsSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n if (!this.ready) {\r\n return\r\n }\r\n if (this.perf[this.data.ticker].length === 0) {\r\n return\r\n }\r\n const translate = getTranslate({\r\n context,\r\n xOffset: IndicatorSettings.left.width,\r\n yOffset: IndicatorSettings.top.height,\r\n })\r\n translate.do()\r\n const { lineHeight, padding, size } = IndicatorSettings.right.axis.font\r\n const text = new Text(\r\n {\r\n x: this.contentWidth + OFFSET.M - padding!.left! + IndicatorSettings.right.axis.margin.left!,\r\n font: Text.getMergedPropsWithDefaults('font', { size }),\r\n lineHeight,\r\n padding: {\r\n left: padding!.left!,\r\n right: padding!.right!,\r\n top: padding!.top!,\r\n bottom: padding!.bottom!,\r\n },\r\n textBaseline: TextBaseline.middle,\r\n fillStyle: Colors.crossText,\r\n },\r\n this.model\r\n )\r\n const iterable = this.getTickers()\r\n const textLabels = []\r\n for (let index = 0; index < iterable.length; index++) {\r\n ticker = iterable[index]\r\n if (this.perf[ticker].length > 0) {\r\n textLabels.push({\r\n text: this.perf[ticker].last().toFixed(2) + '%',\r\n y: Math.round(this.fy(this.perf[ticker].last())),\r\n background: ColorsSettings[index % ColorsSettings.length],\r\n })\r\n }\r\n }\r\n textLabels.push({\r\n text: this.perf[this.data.ticker].last().toFixed(2) + '%',\r\n y: Math.round(this.fy(this.perf[this.data.ticker].last())),\r\n background: Colors.performanceIndicatorLabel,\r\n })\r\n\r\n const minY = 0\r\n const maxY = this.contentHeight\r\n textLabels.forEach((labelSetting) => {\r\n if (labelSetting.y >= minY && labelSetting.y <= maxY) {\r\n text.set(labelSetting).render(context)\r\n }\r\n })\r\n\r\n translate.undo()\r\n }\r\n\r\n renderLabelQuotePage(context: CanvasRenderingContext2D) {\r\n super.renderLabelQuotePage(context)\r\n const { ColorsSettings, ChartSettings, IndicatorSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n if (this.ready) {\r\n const tickers = this.getTickers()\r\n const tickerPerformance = [\r\n { [this.data.ticker]: this.perf[this.data.ticker][this.perf[this.data.ticker].length - 1] },\r\n ...tickers.map((ticker) => ({ [ticker]: this.perf[ticker][this.perf[ticker].length - 1] })),\r\n ].reduce((prev, current) => ({ ...prev, ...current }), {})\r\n Object.keys(tickerPerformance).forEach((key, index) => {\r\n if (tickerPerformance[key]) {\r\n const text = new Text(\r\n {\r\n text: `${key} ${tickerPerformance[key].toFixed(2)}%`,\r\n x: IndicatorSettings.left.indicatorLabel.margin.left,\r\n y:\r\n (IndicatorSettings.left.indicatorLabel.font.lineHeight! +\r\n IndicatorSettings.left.indicatorLabel.labelSpacing) *\r\n (index + 1) +\r\n IndicatorSettings.left.indicatorLabel.margin.top!,\r\n font: Text.getMergedPropsWithDefaults('font', IndicatorSettings.left.indicatorLabel.font),\r\n fillStyle:\r\n index === 0 ? Colors.performanceIndicatorLabel : ColorsSettings[index - (1 % ColorsSettings.length)],\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.top,\r\n },\r\n this.model\r\n )\r\n this.indicatorLabelWidth = { ...this.indicatorLabelWidth, [key]: text.measure(context) }\r\n text.render(context)\r\n }\r\n })\r\n }\r\n }\r\n\r\n getTickers() {\r\n return this.tickers\r\n .split(',')\r\n .map((ticker) => ticker)\r\n .filter((x) => x)\r\n }\r\n\r\n getTickersAndTimeframe() {\r\n const { timeframe } = this.model.chart().quote()\r\n return this.getTickers().map((ticker) => ({\r\n ticker,\r\n instrument: getInstrument(ticker),\r\n timeframe,\r\n }))\r\n }\r\n\r\n set(values: Partial) {\r\n this.ready = false\r\n this.firstFetchCalled = false\r\n super.set({ ...values, tickers: values.period || (values.tickers ? getSanitizedTicker(values.tickers, true) : '') })\r\n this.tickers = (this.tickers || '').toUpperCase()\r\n }\r\n\r\n getModalConfig() {\r\n return {\r\n title: this.label,\r\n inputs: [\r\n {\r\n type: 'text',\r\n label: 'Tickers',\r\n name: 'tickers',\r\n value: !!this.tickers ? this.tickers : DEFAULT_TICKERS,\r\n required: true,\r\n },\r\n ],\r\n inputsErrorMessages: {\r\n tickers: 'At least one ticker has to be provided',\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'tickers':\r\n return this[key].length > 0\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return this.getIsChartPageSpecificFunctionality() ? 'PERF %' : `PERF% ${this.tickers}`\r\n }\r\n}\r\n\r\nexport default PricePerformance\r\n","import { IndicatorType } from '../constants/common'\r\nimport { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: number | string\r\n momentum: number\r\n}\r\n\r\nclass RMI extends Indicator {\r\n static type = IndicatorType.Rmi\r\n static label = 'Relative Momentum Index'\r\n\r\n rmi: number[] = []\r\n declare momentum: number\r\n declare period: number\r\n\r\n set(values: Partial) {\r\n if (typeof values.period === 'string') {\r\n const [period = 0, momentum = 0] = getParsedIntegersFromPeriodString(values.period)\r\n super.set({ ...values, period, momentum })\r\n } else {\r\n super.set(values)\r\n }\r\n }\r\n\r\n compute() {\r\n if (!this.isComputeNecessary()) return\r\n\r\n this.rmi = []\r\n let count = 0\r\n let sumu = 0\r\n let sumd = 0\r\n let u: number, d: number, ad: number, au: number\r\n for (let i = this.momentum; i < this.data.close.length; i++) {\r\n u = d = 0\r\n if (this.data.close[i] > this.data.close[i - this.momentum]) {\r\n u = this.data.close[i] - this.data.close[i - this.momentum]\r\n }\r\n if (this.data.close[i] < this.data.close[i - this.momentum]) {\r\n d = this.data.close[i - this.momentum] - this.data.close[i]\r\n }\r\n\r\n if (count < this.period) {\r\n sumu += u\r\n sumd += d\r\n count++\r\n au = sumu / count\r\n ad = sumd / count\r\n } else {\r\n au = (au! * (this.period - 1) + u) / this.period\r\n ad = (ad! * (this.period - 1) + d) / this.period\r\n }\r\n\r\n const rs = ad > 0 ? au / ad : 1\r\n this.rmi[i] = 100 - 100 * (1 / (1 + rs))\r\n }\r\n\r\n this.lastValue = this.rmi.last() ?? null\r\n const { min, max } = this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n this.renderOversoldOverbought(context, this.rmi, this.momentum, 30, 50, 70)\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 20,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n const momentum = {\r\n type: 'number',\r\n label: 'Momentum',\r\n name: 'momentum',\r\n value: this.momentum ?? 5,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period, momentum],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n momentum: `${momentum.label} must be a whole number between ${momentum.min} and ${momentum.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n case 'momentum':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `RMI ${this.period},${this.momentum}`\r\n }\r\n}\r\n\r\nexport default RMI\r\n","import Line from '../canvas/line'\r\nimport { IndicatorType } from '../constants/common'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n}\r\n\r\nclass ROC extends Indicator {\r\n static type = IndicatorType.Roc\r\n static label = 'Rate of Change %'\r\n\r\n roc: number[] = []\r\n declare period: number\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (this.isComputeNecessary()) {\r\n this.roc = []\r\n for (let i = this.period; i < this.data.close.length; i++) {\r\n this.roc[i] = ((this.data.close[i] - this.data.close[i - this.period]) / this.data.close[i - this.period]) * 100\r\n }\r\n\r\n this.lastValue = this.roc.last() ?? null\r\n }\r\n const { min, max } = this.roc.length > 0 ? this.computeVisibleMinMax(this.roc) : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n new Line(\r\n {\r\n x1: -this.leftOffset,\r\n x2: -this.leftOffset + this.contentWidth,\r\n y1: Math.round(this.fy(0)),\r\n y2: Math.round(this.fy(0)),\r\n strokeStyle: '#ff8787',\r\n dashLength: 3,\r\n },\r\n this.model\r\n ).render(context)\r\n context.set('strokeStyle', this.getChartLayoutSettings().IndicatorSettings.general.Colors.line)\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i: number, x: number) => {\r\n context.lineTo(x, Math.round(this.fy(this.roc[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 12,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `ROC ${this.period}`\r\n }\r\n}\r\n\r\nexport default ROC\r\n","import { IndicatorType } from '../constants/common'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype Options = {\r\n period: number\r\n}\r\n\r\ntype DefaultCalculatedValuesType = {\r\n rsi: number[]\r\n}\r\n\r\nexport class RsiCalculation extends MainCalculation {\r\n static type = IndicatorType.Rsi\r\n\r\n getDefaultCalculatedValues() {\r\n return { rsi: [] }\r\n }\r\n\r\n calculate(onValueCalculated?: OnValueCalculated) {\r\n const { period } = this.options\r\n const { close } = this.quote\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n let sumu = 0\r\n let sumd = 0\r\n let u: number, d: number, ad: number, au: number\r\n for (let i = 1; i < close.length; i++) {\r\n u = d = 0\r\n if (close[i] > close[i - 1]) {\r\n u = close[i] - close[i - 1]\r\n }\r\n if (close[i] < close[i - 1]) {\r\n d = close[i - 1] - close[i]\r\n }\r\n\r\n if (i <= period) {\r\n sumu += u\r\n sumd += d\r\n au = sumu / i\r\n ad = sumd / i\r\n } else {\r\n au = (au! * (period - 1) + u) / period\r\n ad = (ad! * (period - 1) + d) / period\r\n }\r\n\r\n const rs = ad > 0 ? au / ad : 1\r\n this.calculatedValues.rsi[i] = 100 - 100 * (1 / (1 + rs))\r\n\r\n if (onValueCalculated?.(this.calculatedValues, i) === false) {\r\n break\r\n }\r\n }\r\n }\r\n}\r\n","import { IndicatorType } from '../constants/common'\r\nimport { RsiCalculation } from '../indicator-calculation/rsi'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n}\r\n\r\nclass RSI extends Indicator {\r\n static type = IndicatorType.Rsi\r\n static label = 'Relative Strength Index'\r\n\r\n rsiCalculation: RsiCalculation | null = null\r\n declare period: number\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (!this.isComputeNecessary() && this.rsiCalculation !== null) return\r\n\r\n this.rsiCalculation = new RsiCalculation({\r\n quote: this.data,\r\n options: { period: this.period },\r\n })\r\n\r\n this.rsiCalculation.calculate()\r\n\r\n this.lastValue = this.rsiCalculation.calculatedValues.rsi.last() ?? null\r\n const { min, max } = this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n this.renderOversoldOverbought(context, this.rsiCalculation?.calculatedValues.rsi ?? [], this.period, 30, 50, 70)\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 14,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `RSI ${this.period}`\r\n }\r\n}\r\n\r\nexport default RSI\r\n","import Line from '../canvas/line'\r\nimport { IndicatorType } from '../constants/common'\r\nimport { getBarWidthWithMarginByParts } from '../utils/chart'\r\nimport { getHEXWithSpecificAplha } from '../utils/colors'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: number | string\r\n baseLine: number\r\n}\r\n\r\nconst DEFAULT_PARAMETERS = {\r\n Period: 50,\r\n BaseLine: 1.0,\r\n}\r\n\r\nfunction parsePeriod(periodStr: string) {\r\n const values = periodStr.split(',')\r\n const period = parseInt(values[0]) || DEFAULT_PARAMETERS.Period\r\n const baseLine = parseFloat(values[1]) || DEFAULT_PARAMETERS.BaseLine\r\n\r\n return [period, baseLine]\r\n}\r\n\r\nclass RelativeVolume extends Indicator {\r\n static type = IndicatorType.Rvol\r\n static label = 'Relative Volume'\r\n\r\n rvol: number[] = []\r\n declare period: number\r\n declare baseLine: number\r\n\r\n set(values: Partial) {\r\n if (typeof values.period === 'string') {\r\n const [period = 0, baseLine = 0] = parsePeriod(values.period)\r\n super.set({ ...values, period, baseLine })\r\n } else {\r\n super.set(values)\r\n }\r\n }\r\n\r\n compute() {\r\n if (this.isComputeNecessary()) {\r\n this.rvol = []\r\n\r\n let sum = 0\r\n for (let i = 0; i < this.period; i++) {\r\n sum += this.data.volume[i]\r\n }\r\n for (let i = this.period; i < this.data.volume.length; i++) {\r\n sum = sum - this.data.volume[i - this.period] + this.data.volume[i]\r\n this.rvol[i] = this.data.volume[i] / (sum / this.period)\r\n }\r\n\r\n this.lastValue = this.rvol.last() ?? null\r\n }\r\n\r\n const { min, max } =\r\n this.rvol.length > 0\r\n ? this.computeVisibleMinMax([...this.rvol, this.baseLine])\r\n : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const chartModel = this.model.chart()\r\n const { zoomFactor } = chartModel\r\n const { barFillWidth, barBorderWidth } = getBarWidthWithMarginByParts({\r\n zoomFactor,\r\n chartLayout: chartModel.chart_layout(),\r\n })\r\n const barWidthWithoutMargin = barFillWidth + barBorderWidth * 2\r\n const halfBarWidth = ~~Math.max(1, barWidthWithoutMargin / 2)\r\n\r\n drawInVisibleArea({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n fromIndexOffset: this.period + 1,\r\n drawBarCallback: (i, x) => {\r\n if (this.rvol[i] === undefined) return\r\n\r\n const baseLine = Math.round(this.fy(this.baseLine))\r\n const y = Math.round(this.fy(this.rvol[i]))\r\n\r\n context.fillStyle = this.rvol[i] < this.baseLine ? Colors.volumeTrendDown : Colors.volumeTrendUp\r\n context.fillRect(x - halfBarWidth, baseLine, barWidthWithoutMargin, y - baseLine)\r\n },\r\n })\r\n\r\n const baseLineY = this.fy(this.baseLine)\r\n new Line(\r\n {\r\n x1: -this.leftOffset,\r\n x2: -this.leftOffset + this.contentWidth,\r\n y1: Math.round(baseLineY),\r\n y2: Math.round(baseLineY),\r\n strokeStyle: getHEXWithSpecificAplha(Colors.zeroChange, 0.5),\r\n },\r\n this.model\r\n ).render(context)\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? DEFAULT_PARAMETERS.Period,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n const baseLine = {\r\n type: 'number',\r\n label: 'Baseline',\r\n name: 'baseLine',\r\n value: this.baseLine ?? DEFAULT_PARAMETERS.BaseLine,\r\n required: true,\r\n step: 0.1,\r\n allowDecimal: true,\r\n min: 0,\r\n max: 999999,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period, baseLine],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n baseLine: `${baseLine.label} must be a number between ${baseLine.min} and ${baseLine.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n case 'baseLine':\r\n return this.getIsNumberInputValid({ key, integerOnly: false })\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `RVOL ${this.period}, ${this.baseLine}, SMA`\r\n }\r\n}\r\n\r\nexport default RelativeVolume\r\n","import Text from '../canvas/text'\r\nimport { IndicatorType, OFFSET, PADDING, TextBaseline } from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport Pane from '../models/pane'\r\nimport utils from '../utils'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n}\r\n\r\nclass RWI extends Indicator {\r\n static type = IndicatorType.Rwi\r\n static label = 'Random Walk Index'\r\n\r\n tr: number[] = []\r\n atr: number[] = []\r\n rwiHi: number[] = []\r\n rwiLo: number[] = []\r\n declare period: number\r\n\r\n constructor(attrs: Attrs, model: Pane) {\r\n super(attrs, model)\r\n this.renderYAxis = this.renderYAxis.bind(this)\r\n }\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (this.isComputeNecessary()) {\r\n this.tr = []\r\n this.atr = []\r\n this.rwiHi = []\r\n this.rwiLo = []\r\n let atr = 0\r\n\r\n for (let i = 0; i < this.data.close.length; i++) {\r\n const tr = utils.max([\r\n this.data.high[i] - this.data.low[i],\r\n Math.abs(this.data.high[i] - this.data.close[i - 1]),\r\n Math.abs(this.data.low[i] - this.data.close[i - 1]),\r\n ])\r\n this.tr[i] = tr\r\n\r\n if (i < this.period) {\r\n atr += tr\r\n this.atr[i] = atr / (i + 1)\r\n if (i === this.period - 1) {\r\n atr /= this.period\r\n }\r\n } else {\r\n this.atr[i] = (this.atr[i - 1] * (this.period - 1) + tr) / this.period\r\n }\r\n }\r\n\r\n for (let i = this.period + 2; i < this.data.close.length; i++) {\r\n const h = this.data.high[i]\r\n const l = this.data.low[i]\r\n let trSum = this.tr[i - 1] + this.tr[i - 2]\r\n let count = 2\r\n let atrWeight = (trSum / count) * Math.sqrt(count)\r\n let maxHi = atrWeight > 0 ? (h - this.data.low[i - 1]) / atrWeight : -1\r\n let maxLo = atrWeight > 0 ? (this.data.high[i - 1] - l) / atrWeight : -1\r\n for (let j = i - 1; j > i - this.period + 1; j--) {\r\n trSum += this.tr[j - 2]\r\n count++\r\n atrWeight = (trSum / count) * Math.sqrt(count)\r\n if (atrWeight === 0) {\r\n continue\r\n }\r\n\r\n const hi = (h - this.data.low[j - 1]) / atrWeight\r\n if (hi > maxHi) {\r\n maxHi = hi\r\n }\r\n\r\n const lo = (this.data.high[j - 1] - l) / atrWeight\r\n if (lo > maxLo) {\r\n maxLo = lo\r\n }\r\n }\r\n this.rwiHi[i] = maxHi\r\n this.rwiLo[i] = maxLo\r\n }\r\n }\r\n const { min, max } =\r\n this.rwiHi.length > 0 || this.rwiLo.length > 0\r\n ? this.computeVisibleMinMax(this.rwiHi, this.rwiLo)\r\n : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n if (this.data.close.length === 0) return\r\n\r\n const drawInVisibleAreaProps = {\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n fromIndexOffset: this.period,\r\n }\r\n\r\n context.translate(0.5, 0.5)\r\n context.set('strokeStyle', '#c80000')\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i: number, x: number) => {\r\n context.lineTo(x, Math.round(this.fy(this.rwiLo[i])))\r\n },\r\n })\r\n context.stroke()\r\n\r\n context.set('strokeStyle', '#00a000')\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i: number, x: number) => {\r\n context.lineTo(x, Math.round(this.fy(this.rwiHi[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n renderYAxis(context: CanvasRenderingContext2D) {\r\n super.renderYAxis(context)\r\n const { IndicatorSettings, ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const translate = getTranslate({\r\n context,\r\n xOffset: IndicatorSettings.left.width,\r\n yOffset: IndicatorSettings.top.height,\r\n })\r\n translate.do()\r\n const text = new Text(\r\n {\r\n x: this.contentWidth + OFFSET.M - PADDING.XXS + IndicatorSettings.right.axis.margin.left!,\r\n font: Text.getMergedPropsWithDefaults('font', IndicatorSettings.right.axis.font),\r\n lineHeight: IndicatorSettings.right.axis.font.lineHeight,\r\n padding: {\r\n top: IndicatorSettings.right.axis.font?.padding?.top ?? PADDING.XXS,\r\n right: IndicatorSettings.right.axis.font?.padding?.right ?? PADDING.XXS,\r\n bottom: IndicatorSettings.right.axis.font?.padding?.bottom ?? PADDING.XXS,\r\n left: IndicatorSettings.right.axis.font?.padding?.left ?? PADDING.XXS,\r\n },\r\n textBaseline: TextBaseline.middle,\r\n fillStyle: Colors.indicatorCurrentText,\r\n },\r\n this.model\r\n )\r\n const textLabels = []\r\n if (this.rwiLo.length > 0) {\r\n textLabels.push({\r\n text: this.rwiLo.last()!.toFixed(2),\r\n y: Math.round(this.fy(this.rwiLo.last()!)),\r\n background: '#c80000',\r\n })\r\n }\r\n if (this.rwiHi.length > 0) {\r\n textLabels.push({\r\n text: this.rwiHi.last()!.toFixed(2),\r\n y: Math.round(this.fy(this.rwiHi.last()!)),\r\n background: '#00a000',\r\n })\r\n }\r\n\r\n const minY = 0\r\n const maxY = this.height - IndicatorSettings.bottom.height - IndicatorSettings.top.height\r\n textLabels.forEach((labelSetting) => {\r\n if (labelSetting.y >= minY && labelSetting.y <= maxY) {\r\n text.set(labelSetting).render(context)\r\n }\r\n })\r\n\r\n translate.undo()\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 9,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `RWI ${this.period}`\r\n }\r\n}\r\n\r\nexport default RWI\r\n","import Line from '../canvas/line'\r\nimport { IndicatorType } from '../constants/common'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string | number\r\n dPeriod: number\r\n kPeriod: number\r\n}\r\n\r\nclass Stochastics extends Indicator {\r\n static type = IndicatorType.Stofu\r\n static label = 'Stochastics FULL'\r\n\r\n k: number[] = []\r\n k1: number[] = []\r\n d: number[] = []\r\n declare kPeriod: number\r\n declare period: number\r\n declare dPeriod: number\r\n\r\n set(values: Partial) {\r\n if (typeof values.period === 'string') {\r\n const [period = 0, kPeriod = 0, dPeriod = 0] = getParsedIntegersFromPeriodString(values.period)\r\n super.set({ ...values, period, dPeriod, kPeriod })\r\n } else {\r\n super.set(values)\r\n }\r\n }\r\n\r\n compute() {\r\n if (!this.isComputeNecessary()) return\r\n\r\n const period = Math.min(this.period, this.data.close.length - 1)\r\n let dCount, dSum, k\r\n this.k1 = []\r\n this.k = []\r\n this.d = []\r\n let kSum = (dSum = 0)\r\n let kCount = (dCount = 0)\r\n for (let i = 0; i < this.data.close.length; i++) {\r\n let highestHigh = this.data.high[i]\r\n let lowestLow = this.data.low[i]\r\n\r\n for (let j = i - period + 1; j <= i; j++) {\r\n if (this.data.high[j] > highestHigh) {\r\n highestHigh = this.data.high[j]\r\n }\r\n if (this.data.low[j] < lowestLow) {\r\n lowestLow = this.data.low[j]\r\n }\r\n }\r\n\r\n k = ((this.data.close[i] - lowestLow) / (highestHigh - lowestLow)) * 100\r\n if (highestHigh === lowestLow) {\r\n k = 100\r\n }\r\n this.k1[i] = k\r\n if (this.kPeriod > 1) {\r\n kSum += k\r\n kCount++\r\n if (kCount > this.kPeriod) {\r\n kSum -= this.k1[i - this.kPeriod]\r\n kCount--\r\n }\r\n k = kSum / kCount\r\n }\r\n\r\n dSum += k\r\n dCount++\r\n if (dCount > this.dPeriod) {\r\n dSum -= this.k[i - this.dPeriod]\r\n dCount--\r\n }\r\n\r\n const d = dSum / dCount\r\n this.k[i] = k\r\n this.d[i] = d\r\n }\r\n\r\n this.lastValue = this.k.last() ?? null\r\n const { min, max } = this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n if (this.data.close.length === 0) return\r\n\r\n new Line(\r\n {\r\n x1: -this.leftOffset,\r\n x2: -this.leftOffset + this.contentWidth,\r\n y1: Math.round(this.fy(50)),\r\n y2: Math.round(this.fy(50)),\r\n strokeStyle: '#ff8787',\r\n dashLength: 3,\r\n },\r\n this.model\r\n ).render(context)\r\n new Line(\r\n {\r\n x1: -this.leftOffset,\r\n x2: -this.leftOffset + this.contentWidth,\r\n y1: Math.round(this.fy(20)),\r\n y2: Math.round(this.fy(20)),\r\n strokeStyle: '#69c1ea',\r\n },\r\n this.model\r\n ).render(context)\r\n new Line(\r\n {\r\n x1: -this.leftOffset,\r\n x2: -this.leftOffset + this.contentWidth,\r\n y1: Math.round(this.fy(80)),\r\n y2: Math.round(this.fy(80)),\r\n strokeStyle: '#d386df',\r\n },\r\n this.model\r\n ).render(context)\r\n\r\n context.set('strokeStyle', this.getChartLayoutSettings().IndicatorSettings.general.Colors.line)\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n const drawInVisibleAreaProps = {\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n fromIndexOffset: this.period,\r\n }\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(this.k[i])))\r\n },\r\n })\r\n context.stroke()\r\n\r\n context.set('strokeStyle', '#c80000')\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(this.d[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 14,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n const kPeriod = {\r\n type: 'number',\r\n label: 'K Period',\r\n name: 'kPeriod',\r\n value: this.kPeriod ?? 3,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n const dPeriod = {\r\n type: 'number',\r\n label: 'D Period',\r\n name: 'dPeriod',\r\n value: this.dPeriod ?? 3,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period, kPeriod, dPeriod],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n dPeriod: `${dPeriod.label} must be a whole number between ${dPeriod.min} and ${dPeriod.max}`,\r\n kPeriod: `${kPeriod.label} must be a whole number between ${kPeriod.min} and ${kPeriod.max}`,\r\n } as {\r\n period: string\r\n dPeriod: string\r\n kPeriod?: string\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n case 'dPeriod':\r\n case 'kPeriod':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `Stochastics FULL ${this.period},${this.kPeriod},${this.dPeriod}`\r\n }\r\n}\r\n\r\nexport default Stochastics\r\n","import { IndicatorType } from '../constants/common'\r\nimport Pane from '../models/pane'\r\nimport { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport Stochastics from './stofu'\r\n\r\ninterface Attrs {\r\n period: string | number\r\n dPeriod: number\r\n kPeriod: number\r\n}\r\n\r\nclass StochasticsFast extends Stochastics {\r\n static type = IndicatorType.Stofa\r\n static label = 'Stochastics FAST'\r\n\r\n declare kPeriod: number\r\n declare period: number\r\n declare dPeriod: number\r\n\r\n constructor(attrs: Attrs, model: Pane) {\r\n super(attrs, model)\r\n this.kPeriod = 1\r\n }\r\n\r\n set(values: Partial) {\r\n if (typeof values.period === 'string') {\r\n const [period = 0, dPeriod = 0] = getParsedIntegersFromPeriodString(values.period)\r\n super.set({ ...values, period, dPeriod, kPeriod: 1 })\r\n } else {\r\n super.set(values)\r\n }\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 14,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n const dPeriod = {\r\n type: 'number',\r\n label: 'D Period',\r\n name: 'dPeriod',\r\n value: this.dPeriod ?? 3,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period, dPeriod],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n dPeriod: `${dPeriod.label} must be a whole number between ${dPeriod.min} and ${dPeriod.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n case 'dPeriod':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `Stochastics FAST ${this.period},${this.dPeriod}`\r\n }\r\n}\r\n\r\nexport default StochasticsFast\r\n","import { IndicatorType } from '../constants/common'\r\nimport { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport Stochastics from './stofu'\r\n\r\ninterface Attrs {\r\n period: string | number\r\n dPeriod: number\r\n kPeriod: number\r\n}\r\n\r\nclass StochasticsSlow extends Stochastics {\r\n static type = IndicatorType.Stosl\r\n static label = 'Stochastics SLOW'\r\n\r\n kPeriod = 3\r\n\r\n set(values: Partial) {\r\n if (typeof values.period === 'string') {\r\n const [period = 0, dPeriod = 0] = getParsedIntegersFromPeriodString(values.period)\r\n super.set({ ...values, period, dPeriod, kPeriod: 3 })\r\n } else {\r\n super.set(values)\r\n }\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 14,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n const dPeriod = {\r\n type: 'number',\r\n label: 'D Period',\r\n name: 'dPeriod',\r\n value: this.dPeriod ?? 3,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period, dPeriod],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n dPeriod: `${dPeriod.label} must be a whole number between ${dPeriod.min} and ${dPeriod.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n case 'dPeriod':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `Stochastics SLOW ${this.period},${this.dPeriod}`\r\n }\r\n}\r\n\r\nexport default StochasticsSlow\r\n","import { IndicatorType } from '../constants/common'\r\nimport { ExponentialMovingAverage } from './ema'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype Options = {\r\n period: number\r\n}\r\n\r\ntype DefaultCalculatedValuesType = {\r\n trix: number[]\r\n}\r\n\r\nexport class TrixCalculation extends MainCalculation {\r\n static type = IndicatorType.Trix\r\n\r\n getDefaultCalculatedValues() {\r\n return { trix: [] }\r\n }\r\n\r\n calculate(onValueCalculated?: OnValueCalculated) {\r\n const { period } = this.options\r\n const { close } = this.quote\r\n const lastIndex = close.length - 1\r\n const ema1 = new ExponentialMovingAverage(period)\r\n const ema2 = new ExponentialMovingAverage(period)\r\n const ema3 = new ExponentialMovingAverage(period)\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n let prev = 0\r\n for (let index = 0; index <= lastIndex; index++) {\r\n ema1.add(close[index])\r\n ema2.add(ema1.value)\r\n ema3.add(ema2.value)\r\n if (prev > 0) {\r\n this.calculatedValues.trix[index] = (ema3.value * 100) / prev - 100\r\n }\r\n prev = ema3.value\r\n\r\n if (onValueCalculated?.(this.calculatedValues, index) === false) {\r\n break\r\n }\r\n }\r\n }\r\n}\r\n","import Line from '../canvas/line'\r\nimport { IndicatorType } from '../constants/common'\r\nimport { TrixCalculation } from '../indicator-calculation/trix'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n}\r\n\r\nclass Trix extends Indicator {\r\n static type = IndicatorType.Trix\r\n static label = 'TRIX'\r\n\r\n trixCalculation: TrixCalculation | null = null\r\n declare period: number\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (this.isComputeNecessary()) {\r\n this.trixCalculation = new TrixCalculation({\r\n quote: this.data,\r\n options: {\r\n period: this.period,\r\n },\r\n })\r\n this.trixCalculation.calculate()\r\n this.lastValue = this.trixCalculation.calculatedValues.trix.last() ?? null\r\n }\r\n const trix = this.trixCalculation?.calculatedValues.trix ?? []\r\n const { min, max } = trix.length > 0 ? this.computeVisibleMinMax(trix) : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n new Line(\r\n {\r\n x1: -this.leftOffset,\r\n x2: -this.leftOffset + this.contentWidth,\r\n y1: Math.round(this.fy(0)),\r\n y2: Math.round(this.fy(0)),\r\n strokeStyle: '#ff8787',\r\n dashLength: 3,\r\n },\r\n this.model\r\n ).render(context)\r\n context.set('strokeStyle', this.getChartLayoutSettings().IndicatorSettings.general.Colors.line)\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i: number, x: number) => {\r\n const value = this.trixCalculation?.calculatedValues.trix[i]\r\n if (value) context.lineTo(x, ~~this.fy(value))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 9,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `TRIX ${this.period}`\r\n }\r\n}\r\n\r\nexport default Trix\r\n","import { ChartConfigChartPaneElement, RequireByKey } from '../../types/shared'\r\nimport { IndicatorType } from '../constants/common'\r\nimport { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n period1: number\r\n period2: number\r\n period3: number\r\n}\r\n\r\nclass UltimateOscillator extends Indicator {\r\n static type = IndicatorType.Ult\r\n static label = 'Ultimate Oscillator'\r\n\r\n static getNumOfBarsBuffer({ period }: RequireByKey) {\r\n const [period1 = 0, period2 = 0, period3 = 0] = getParsedIntegersFromPeriodString(period)\r\n return Math.max(period1, period2, period3)\r\n }\r\n\r\n declare period1: number\r\n declare period2: number\r\n declare period3: number\r\n ult: number[] = []\r\n tr: number[] = []\r\n bp: number[] = []\r\n\r\n set(values: Partial) {\r\n if (typeof values.period === 'string') {\r\n const [period1 = 0, period2 = 0, period3 = 0] = getParsedIntegersFromPeriodString(values.period)\r\n super.set({ ...values, period1, period2, period3 })\r\n } else {\r\n super.set(values)\r\n }\r\n }\r\n\r\n compute() {\r\n if (!this.isComputeNecessary()) return\r\n\r\n this.ult = []\r\n let bpSum2, bpSum3, count2, count3, trSum2, trSum3\r\n const tr = []\r\n const bp = []\r\n let bpSum1 = (bpSum2 = bpSum3 = 0)\r\n let trSum1 = (trSum2 = trSum3 = 0)\r\n let count1 = (count2 = count3 = 0)\r\n let avg2, avg3\r\n for (let i = 1; i < this.data.close.length; i++) {\r\n bp[i] = this.data.close[i] - Math.min(this.data.low[i], this.data.close[i - 1])\r\n tr[i] = Math.max(this.data.high[i], this.data.close[i - 1]) - Math.min(this.data.low[i], this.data.close[i - 1])\r\n\r\n bpSum1 += bp[i]\r\n trSum1 += tr[i]\r\n count1++\r\n if (count1 > this.period1) {\r\n bpSum1 -= bp[i - this.period1]\r\n trSum1 -= tr[i - this.period1]\r\n }\r\n\r\n bpSum2 += bp[i]\r\n trSum2 += tr[i]\r\n count2++\r\n if (count2 > this.period2) {\r\n bpSum2 -= bp[i - this.period2]\r\n trSum2 -= tr[i - this.period2]\r\n }\r\n\r\n bpSum3 += bp[i]\r\n trSum3 += tr[i]\r\n count3++\r\n if (count3 > this.period3) {\r\n bpSum3 -= bp[i - this.period3]\r\n trSum3 -= tr[i - this.period3]\r\n }\r\n\r\n let avg1 = (avg2 = avg3 = 0)\r\n if (trSum1 > 0) {\r\n avg1 = bpSum1 / trSum1\r\n }\r\n if (trSum2 > 0) {\r\n avg2 = bpSum2 / trSum2\r\n }\r\n if (trSum3 > 0) {\r\n avg3 = bpSum3 / trSum3\r\n }\r\n\r\n this.ult[i] = (100 * (4 * avg1 + 2 * avg2 + avg3)) / 7\r\n }\r\n\r\n this.lastValue = this.ult.last() ?? null\r\n const { min, max } = this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n this.renderOversoldOverbought(context, this.ult, 1, 30, 50, 70)\r\n }\r\n\r\n getModalConfig() {\r\n const period1 = {\r\n type: 'number',\r\n label: 'Period 1',\r\n name: 'period1',\r\n value: this.period1 ?? 7,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n const period2 = {\r\n type: 'number',\r\n label: 'Period 2',\r\n name: 'period2',\r\n value: this.period2 ?? 14,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n const period3 = {\r\n type: 'number',\r\n label: 'Period 3',\r\n name: 'period3',\r\n value: this.period3 ?? 28,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period1, period2, period3],\r\n inputsErrorMessages: {\r\n period1: `${period1.label} must be a whole number between ${period1.min} and ${period1.max}`,\r\n period2: `${period2.label} must be a whole number between ${period2.min} and ${period2.max}`,\r\n period3: `${period3.label} must be a whole number between ${period3.min} and ${period3.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period1':\r\n case 'period2':\r\n case 'period3':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `ULT ${this.period1},${this.period2},${this.period3}`\r\n }\r\n}\r\n\r\nexport default UltimateOscillator\r\n","import { IndicatorType } from '../constants/common'\r\nimport math from '../helpers/math'\r\nimport { getBarWidthWithMarginByParts } from '../utils/chart'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Indicator from './indicator'\r\n\r\nclass Volume extends Indicator {\r\n static type = IndicatorType.Vol\r\n static label = 'Volume'\r\n\r\n compute() {\r\n const { min, max } =\r\n this.data.volume.length > 0 ? this.computeVisibleMinMax(this.data.volume) : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n this.lastValue = this.data.volume.last() ?? null\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const chartModel = this.model.chart()\r\n const { zoomFactor } = chartModel\r\n const { barFillWidth, barBorderWidth } = getBarWidthWithMarginByParts({\r\n zoomFactor,\r\n chartLayout: chartModel.chart_layout(),\r\n })\r\n const barWidthWithoutMargin = barFillWidth + barBorderWidth * 2\r\n const halfBarWidth = ~~Math.max(1, barWidthWithoutMargin / 2)\r\n\r\n drawInVisibleArea({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i, x) => {\r\n context.fillStyle = this.data.close[i] < this.data.open[i] ? Colors.volumeTrendDown : Colors.volumeTrendUp\r\n const y = Math.round(this.fy(this.data.volume[i]))\r\n context.fillRect(x - halfBarWidth, y, barWidthWithoutMargin, context.canvas.height - y)\r\n },\r\n })\r\n }\r\n\r\n formatAxis(value: number) {\r\n return math.formatBigNumber(value, 2)\r\n }\r\n\r\n getModalConfig() {\r\n return {\r\n title: this.label,\r\n inputs: [],\r\n inputsErrorMessages: {},\r\n }\r\n }\r\n\r\n toString() {\r\n return `Volume`\r\n }\r\n}\r\n\r\nexport default Volume\r\n","import { IndicatorType } from '../constants/common'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n}\r\n\r\nclass WilliamsR extends Indicator {\r\n static type = IndicatorType.Wr\r\n static label = 'Williams %R'\r\n\r\n declare period: number\r\n r: number[] = []\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (this.isComputeNecessary()) {\r\n this.r = []\r\n for (let i = this.period; i < this.data.close.length; i++) {\r\n let highestHigh = this.data.high[i]\r\n let lowestLow = this.data.low[i]\r\n for (let j = i - this.period + 1; j <= i; j++) {\r\n if (this.data.high[j] > highestHigh) {\r\n highestHigh = this.data.high[j]\r\n }\r\n if (this.data.low[j] < lowestLow) {\r\n lowestLow = this.data.low[j]\r\n }\r\n }\r\n\r\n this.r[i] = 0\r\n if (highestHigh - lowestLow > 0) {\r\n this.r[i] = ((highestHigh - this.data.close[i]) / (highestHigh - lowestLow)) * -100\r\n }\r\n }\r\n\r\n this.lastValue = this.r.last() ?? null\r\n }\r\n const { min, max } = this.r.length > 0 ? this.computeVisibleMinMax(this.r) : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n this.renderOversoldOverbought(context, this.r, this.period, -80, -50, -20)\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 14,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `W%R ${this.period}`\r\n }\r\n}\r\n\r\nexport default WilliamsR\r\n","import { IndicatorType } from '../constants/common'\r\nimport adx from './adx'\r\nimport aro from './aro'\r\nimport aroosc from './aroosc'\r\nimport atr from './atr'\r\nimport cci from './cci'\r\nimport cot from './cot'\r\nimport fi from './fi'\r\nimport indicator from './indicator'\r\nimport macd from './macd'\r\nimport mfi from './mfi'\r\nimport none from './none'\r\nimport obv from './obv'\r\nimport perf from './perf'\r\nimport rmi from './rmi'\r\nimport roc from './roc'\r\nimport rsi from './rsi'\r\nimport rvol from './rvol'\r\nimport rwi from './rwi'\r\nimport stofa from './stofa'\r\nimport stofu from './stofu'\r\nimport stosl from './stosl'\r\nimport trix from './trix'\r\nimport ult from './ult'\r\nimport vol from './vol'\r\nimport wr from './wr'\r\n\r\n// TODO check if this doesn't break saved charts\r\nexport const indicatorsByType = Object.freeze({\r\n [IndicatorType.Indicator]: indicator,\r\n [IndicatorType.None]: none,\r\n [IndicatorType.Adx]: adx,\r\n [IndicatorType.Aro]: aro,\r\n [IndicatorType.Aroosc]: aroosc,\r\n [IndicatorType.Atr]: atr,\r\n [IndicatorType.Cci]: cci,\r\n [IndicatorType.Cot]: cot,\r\n [IndicatorType.Fi]: fi,\r\n [IndicatorType.Macd]: macd,\r\n [IndicatorType.Mfi]: mfi,\r\n [IndicatorType.Obv]: obv,\r\n [IndicatorType.Perf]: perf,\r\n [IndicatorType.Rmi]: rmi,\r\n [IndicatorType.Roc]: roc,\r\n [IndicatorType.Rsi]: rsi,\r\n [IndicatorType.Rvol]: rvol,\r\n [IndicatorType.Rwi]: rwi,\r\n [IndicatorType.Stofa]: stofa,\r\n [IndicatorType.Stofu]: stofu,\r\n [IndicatorType.Stosl]: stosl,\r\n [IndicatorType.Trix]: trix,\r\n [IndicatorType.Ult]: ult,\r\n [IndicatorType.Vol]: vol,\r\n [IndicatorType.Wr]: wr,\r\n})\r\n\r\nexport const indicatorsWithoutPeriod = Object.freeze([IndicatorType.Obv, IndicatorType.Vol])\r\n","export const publishModalAsyncModule = {\r\n importFn: () => import(/* webpackChunkName: \"modals-publish\" */ './module-entry'),\r\n cacheKey: 'modals-publish',\r\n}\r\n","import Spine from '@finviz/spine'\r\nimport * as React from 'react'\r\n\r\nimport { DefaultSpineEvents } from '../../types/shared'\r\nimport ElementModule from '../canvas/element'\r\nimport IndicatorModule from '../indicators/indicator'\r\nimport { useForceUpdate } from '../utils/force-update'\r\nimport { getJSONReplacerFunc } from '../utils/helpers'\r\n\r\ninterface UseModelStateOptions {\r\n watchProperties?: T extends null ? never[] : Array\r\n listenOnEvents?: string[]\r\n}\r\n\r\nconst getIsSpineObject = (value: any) =>\r\n [Spine.Model, Spine.Module, Spine.Collection].some((spineObject) => value instanceof spineObject)\r\n\r\nconst getWatchedPropValue = (\r\n watchedProp: Model[keyof Model] | ElementModule | IndicatorModule | undefined,\r\n model: Model | null\r\n) => {\r\n if (typeof watchedProp === 'function') {\r\n const value = watchedProp.call(model)\r\n\r\n if (value && !getIsSpineObject(value)) {\r\n throw Error('Watched prop should have a primitive value or a spine object')\r\n }\r\n\r\n if (typeof value?.all === 'function') {\r\n return value.all()\r\n }\r\n\r\n return value\r\n }\r\n\r\n if (typeof watchedProp === 'object') {\r\n const hasToObject = !!watchedProp && 'toObject' in watchedProp\r\n return JSON.stringify(hasToObject ? watchedProp.toObject() : watchedProp, getJSONReplacerFunc())\r\n }\r\n\r\n return watchedProp\r\n}\r\n\r\nconst getWatchedProps = (model: Model | null, props?: Array) =>\r\n props?.reduce(\r\n (acc, propKey) => ({\r\n ...acc,\r\n [propKey]: getWatchedPropValue(model?.[propKey], model),\r\n }),\r\n {} as Partial\r\n )\r\n\r\nconst getAreWatchedPropsEqual = (\r\n currentValue: Value,\r\n previousValue: Value\r\n) => {\r\n if (currentValue instanceof Spine.Model) {\r\n return currentValue.eql(previousValue)\r\n }\r\n\r\n return currentValue === previousValue\r\n}\r\n\r\nconst DEFAULT_SPINE_EVENTS = Object.values(DefaultSpineEvents)\r\n\r\nexport function useModelState(\r\n model: Model,\r\n options: UseModelStateOptions = {}\r\n) {\r\n const { watchProperties = [], listenOnEvents = DEFAULT_SPINE_EVENTS } = options\r\n const stringifiedOptions = JSON.stringify(options)\r\n const { forceUpdate } = useForceUpdate()\r\n const watchedPropertiesRef = React.useRef(getWatchedProps(model, watchProperties))\r\n\r\n React.useEffect(() => {\r\n const handleModelChange = () => {\r\n const hasChange = watchProperties.some((propKey) => {\r\n const currentValue = getWatchedPropValue(model?.[propKey], model)\r\n const previousValue = watchedPropertiesRef.current?.[propKey]\r\n\r\n if (Array.isArray(currentValue)) {\r\n return (\r\n !Array.isArray(previousValue) ||\r\n currentValue.length !== previousValue.length ||\r\n currentValue.some((record, index) => !getAreWatchedPropsEqual(record, previousValue[index]))\r\n )\r\n }\r\n\r\n return !getAreWatchedPropsEqual(currentValue, previousValue)\r\n })\r\n\r\n if (hasChange) {\r\n watchedPropertiesRef.current = getWatchedProps(model, watchProperties)\r\n forceUpdate()\r\n }\r\n }\r\n\r\n const spineEvents = listenOnEvents.join(' ')\r\n\r\n model?.bind(spineEvents, handleModelChange)\r\n\r\n forceUpdate()\r\n\r\n return () => {\r\n model?.unbind(spineEvents, handleModelChange)\r\n }\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [model?.cid, stringifiedOptions, forceUpdate])\r\n\r\n return model\r\n}\r\n","import Spine, { Collection } from '@finviz/spine'\r\nimport omit from 'lodash.omit'\r\n\r\nimport {\r\n ChartConfigChartPane,\r\n CustomSpineEvents,\r\n Instrument,\r\n ObjectHash,\r\n TodoObjectHashAnyType,\r\n} from '../../types/shared'\r\nimport BaseChart from '../charts/base_chart'\r\nimport PerfChart from '../charts/perf_chart'\r\nimport {\r\n DateRangeType,\r\n IndicatorType,\r\n QuotePollingIntervalInMs,\r\n ScaleType,\r\n SpecificChartFunctionality,\r\n TIMEFRAME,\r\n} from '../constants/common'\r\nimport { getCanvasElementByType } from '../helpers/get-canvas-element-by-type'\r\nimport COT from '../indicators/cot'\r\nimport PricePerformance from '../indicators/perf'\r\nimport { getChartLayoutSettings } from '../models/settings'\r\nimport Utils from '../utils'\r\nimport { IDividends, IEarnings, ISplit } from '../utils/chart-events-utils'\r\nimport ChartEventElement from './chart-event-element'\r\nimport { ChartPartToAttrsSyncMap, ChartSyncablePart } from './chart/contstants'\r\nimport ChartLayout from './chart_layout'\r\nimport Pane from './pane'\r\nimport Quote from './quote'\r\n\r\nclass Chart extends Spine.Model {\r\n static initClass(paneModel: typeof Pane, quoteModel: typeof Quote, chartLayoutModel: typeof ChartLayout) {\r\n this.configure(\r\n 'Chart',\r\n 'width',\r\n 'height',\r\n 'timeframe',\r\n 'dateRange',\r\n 'scale',\r\n 'leftOffset',\r\n 'ticker',\r\n 'instrument',\r\n 'fx',\r\n 'fy',\r\n 'zoomFactor',\r\n 'refreshData',\r\n 'stretch',\r\n 'isHideDrawingsActive',\r\n 'isScrolled',\r\n 'firstBarClose',\r\n 'premarket',\r\n 'aftermarket',\r\n 'hasChartEvents'\r\n )\r\n this.hasMany('panes', paneModel)\r\n this.belongsTo('quote', quoteModel)\r\n this.belongsTo('chart_layout', chartLayoutModel)\r\n }\r\n\r\n declare stretch: boolean\r\n declare chart_layout_id: string\r\n declare chart_layout: () => ChartLayout\r\n declare quote_id: string\r\n declare quote: () => Quote\r\n declare panes: () => Collection\r\n declare refreshData: boolean | number\r\n declare dateRange: DateRangeType\r\n declare width: number\r\n declare height: number\r\n declare timeframe: TIMEFRAME\r\n declare leftOffset: number\r\n declare ticker: string\r\n declare instrument: Instrument\r\n declare fx: (x: number) => number\r\n declare fy: (x: number) => number\r\n declare zoomFactor: number\r\n declare isHideDrawingsActive: boolean\r\n declare isScrolled: boolean\r\n declare scale: ScaleType\r\n declare firstBarClose: number\r\n declare premarket: boolean\r\n declare aftermarket: boolean\r\n declare hasChartEvents: boolean\r\n\r\n getChartPane() {\r\n return this.panes()\r\n .all()\r\n .find((pane: Pane) =>\r\n pane\r\n .elements()\r\n .all()\r\n .some((el) => el.isChart())\r\n )\r\n }\r\n\r\n getChartElement() {\r\n for (const pane of this.panes().all()) {\r\n for (const el of pane.elements().all()) {\r\n if (el.isChart()) {\r\n return el\r\n }\r\n }\r\n }\r\n }\r\n\r\n getChartType() {\r\n return this.getChartElement()?.instance.type\r\n }\r\n\r\n getRefreshInterval() {\r\n let defaultRefreshInterval: number | null = null\r\n if (typeof this.refreshData === 'number') {\r\n defaultRefreshInterval = this.refreshData\r\n } else if (this.refreshData === true) {\r\n defaultRefreshInterval = QuotePollingIntervalInMs.Default\r\n }\r\n\r\n const isStock = this.instrument === Instrument.Stock\r\n const isPremium = window.FinvizSettings.hasUserPremium\r\n let customRefreshInterval = QuotePollingIntervalInMs.Elite\r\n if (!isPremium) {\r\n customRefreshInterval = QuotePollingIntervalInMs.Free\r\n } else if (isStock && !Utils.isStockFastRefreshAvailable()) {\r\n customRefreshInterval = QuotePollingIntervalInMs.EliteStocksReduced\r\n }\r\n\r\n return defaultRefreshInterval && Math.max(defaultRefreshInterval, customRefreshInterval)\r\n }\r\n\r\n toObject() {\r\n const panes = this.panes()\r\n .all()\r\n .map((pane) => pane.toObject())\r\n return {\r\n width: this.width,\r\n dateRange: this.dateRange,\r\n height: this.height,\r\n timeframe: this.timeframe,\r\n scale: this.scale,\r\n leftOffset: this.leftOffset,\r\n ticker: this.ticker,\r\n instrument: this.instrument,\r\n zoomFactor: this.zoomFactor,\r\n refreshData: this.refreshData,\r\n stretch: this.stretch,\r\n chartId: this.cid,\r\n panes,\r\n isHideDrawingsActive: this.isHideDrawingsActive,\r\n isScrolled: this.isScrolled,\r\n premarket: this.premarket,\r\n aftermarket: this.aftermarket,\r\n hasChartEvents: this.hasChartEvents,\r\n }\r\n }\r\n\r\n toConfig(omitKeys = [] as string[]) {\r\n const panes = this.panes()\r\n .all()\r\n .map((pane) => pane.toConfig(omitKeys))\r\n return omit(\r\n {\r\n width: this.width,\r\n height: this.height,\r\n timeframe: this.timeframe,\r\n scale: this.scale,\r\n leftOffset: this.leftOffset,\r\n ticker: this.ticker,\r\n instrument: this.instrument,\r\n zoomFactor: this.zoomFactor,\r\n refreshData: this.refreshData,\r\n stretch: this.stretch,\r\n chartId: this.cid,\r\n panes,\r\n isHideDrawingsActive: this.isHideDrawingsActive,\r\n isScrolled: this.isScrolled,\r\n premarket: this.premarket,\r\n aftermarket: this.aftermarket,\r\n hasChartEvents: this.hasChartEvents,\r\n },\r\n omitKeys\r\n )\r\n }\r\n\r\n destroyCascade(options?: TodoObjectHashAnyType) {\r\n this.panes()\r\n .all()\r\n .forEach((pane) => {\r\n pane.destroyCascade()\r\n })\r\n return this.destroy(options)\r\n }\r\n\r\n getChartLayoutSettings() {\r\n return getChartLayoutSettings(this.chart_layout())\r\n }\r\n\r\n getIsDisabled() {\r\n return this.quote()?.close.length === 0\r\n }\r\n\r\n getIsScrollable() {\r\n return this.chart_layout().scrollable\r\n }\r\n\r\n getAllPanes() {\r\n return this.panes().all()\r\n }\r\n\r\n getAllValidPanes() {\r\n const cotKeys = Object.keys(this.quote().COTs ?? {})\r\n return this.getAllPanes().filter((pane) => {\r\n const mainElement = pane.mainElement()\r\n if (mainElement?.instance.type === IndicatorType.Cot) {\r\n // Type of mainElement is `Element` but it can be an indicator too\r\n return cotKeys.includes((mainElement.instance as unknown as COT).attrs.code)\r\n }\r\n return true\r\n })\r\n }\r\n\r\n getAllElements() {\r\n return this.getAllPanes().flatMap((pane) => pane.getAllElements())\r\n }\r\n\r\n getAllQuotes(): Quote[] {\r\n const perfQuotes = this.getAllElements()\r\n .filter(({ instance }) => instance.type === IndicatorType.Perf)\r\n .flatMap(({ instance }) => Object.values((instance as unknown as PricePerformance).quotes))\r\n\r\n let quotePerfTickers: Quote[] = []\r\n if (this.chart_layout().specificChartFunctionality === SpecificChartFunctionality.quotePerf) {\r\n const perfChart = this.getChartElement()?.instance as PerfChart | undefined\r\n if (perfChart) {\r\n quotePerfTickers = Quote.select(\r\n (q: Quote) => perfChart.attrs.tickers.includes(q.ticker) && [TIMEFRAME.d, TIMEFRAME.m].includes(q.timeframe)\r\n )\r\n }\r\n }\r\n\r\n return [...perfQuotes, ...quotePerfTickers, this.quote()].filter(\r\n (quote, index, quotes) => quote && quotes.findIndex((q) => q?.id === quote.id) === index\r\n )\r\n }\r\n\r\n createPaneCascade(paneProperties: ChartConfigChartPane) {\r\n const paneModel = this.panes().create(paneProperties)\r\n\r\n paneProperties.elements?.forEach(({ zIndex, elementId, ...element }) => {\r\n const instance = getCanvasElementByType(element.type).fromObject(element, paneModel)\r\n paneModel.elements().create({ instance, zIndex, elementId })\r\n paneModel.chart().trigger(CustomSpineEvents.IndicatorsChange)\r\n })\r\n\r\n const chartOrIndicator = paneModel.getChartOrIndicatorElement()\r\n if (paneModel.mainElement()?.elementId !== chartOrIndicator?.elementId) {\r\n paneModel.updateAttributes({ mainElement: chartOrIndicator })\r\n }\r\n\r\n return paneModel\r\n }\r\n\r\n updateAttributesAndSync(value: T) {\r\n const attrsInSync = Object.entries(ChartPartToAttrsSyncMap)\r\n .filter(([key]) => this.getIsChartPartInSync(key as unknown as ChartSyncablePart))\r\n .flatMap(([_, modelAttr]) => modelAttr)\r\n this.updateAttributes(value)\r\n\r\n if (attrsInSync.length > 0) {\r\n this.chart_layout()\r\n .getAllCharts()\r\n .forEach((chartModel) => {\r\n if (this.eql(chartModel)) {\r\n return\r\n }\r\n const newAttrs: ObjectHash = {}\r\n attrsInSync.forEach((modelAttr) => {\r\n if (value.hasOwnProperty(modelAttr)) {\r\n newAttrs[modelAttr] = value[modelAttr]\r\n }\r\n })\r\n chartModel.updateAttributes(newAttrs)\r\n })\r\n }\r\n }\r\n\r\n setSyncChartParts(chartParts: ChartSyncablePart | ChartSyncablePart[], isInSync: boolean) {\r\n this.chart_layout().setSyncChartParts(chartParts, isInSync)\r\n }\r\n\r\n getIsChartPartInSync(chartPart: ChartSyncablePart) {\r\n return this.chart_layout().getIsChartPartInSync(chartPart)\r\n }\r\n\r\n getHasPatterns() {\r\n return this.getAllElements().some((element) => {\r\n if ('hasOverlay' in element.instance) {\r\n return (element.instance as BaseChart).hasOverlay?.('patterns')\r\n }\r\n\r\n return false\r\n })\r\n }\r\n\r\n getQuoteRawTicker(): string | null {\r\n return this.quote()?.getRawTicker() ?? null\r\n }\r\n\r\n setChartEvents(chartEvents?: Array, shouldClear = false) {\r\n const chartPane = this.getChartPane()\r\n if (!chartPane) {\r\n return\r\n }\r\n const allChartEvents = chartPane.chartEvents().all()\r\n if (shouldClear) {\r\n allChartEvents.forEach((chartEvent) => chartEvent.destroyCascade())\r\n }\r\n\r\n const events = shouldClear\r\n ? chartEvents\r\n : chartEvents?.filter((chartEvent) => !allChartEvents.some(({ elementId }) => chartEvent.elementId === elementId))\r\n\r\n events?.forEach(({ elementId, eventType, dateTimestamp }) => {\r\n const newChartEvent = chartPane.chartEvents().create({\r\n instance: getCanvasElementByType(eventType).fromObject({ positionTimestamps: { x: dateTimestamp } }, chartPane),\r\n elementId,\r\n })\r\n newChartEvent.instance.updateScales()\r\n })\r\n\r\n chartPane.updateChartEventsZIndexes()\r\n }\r\n}\r\n\r\nexport default Chart\r\n","/*\r\n * it converts it to numbered index and it causes problems later on\r\n * the reason it's not just numbered enum is that it when used in const below\r\n * */\r\nexport enum ChartSyncablePart {\r\n Crosshair = 'crosshair',\r\n Ticker = 'ticker',\r\n Timeframe = 'timeframe',\r\n}\r\n\r\nexport const ChartPartToAttrsSyncMap = {\r\n [ChartSyncablePart.Ticker]: ['ticker'],\r\n [ChartSyncablePart.Timeframe]: ['timeframe', 'dateRange'],\r\n}\r\n\r\nexport const ChartSyncableParts = [\r\n { value: ChartSyncablePart.Ticker, label: 'Ticker' },\r\n { value: ChartSyncablePart.Timeframe, label: 'Timeframe' },\r\n { value: ChartSyncablePart.Crosshair, label: 'Crosshair' },\r\n]\r\n","import Spine, { Collection } from '@finviz/spine'\r\nimport omit from 'lodash.omit'\r\n\r\nimport { IIdea, RootChartConfigObject, Theme, TodoObjectHashAnyType } from '../../types/shared'\r\nimport { ChartEditorEnum, IndicatorType, LayoutType, SpecificChartFunctionality } from '../constants/common'\r\nimport { DrawingSetting } from '../controllers/toolbar/interfaces'\r\nimport Indicator from '../indicators/indicator'\r\nimport { getIsSSr } from '../utils/helpers'\r\nimport Chart from './chart'\r\nimport ChartEventElement from './chart-event-element'\r\nimport { ChartSyncablePart } from './chart/contstants'\r\nimport { ISettings } from './chart_settings/interfaces'\r\nimport DrawingsInternalStore from './drawings-internal-store'\r\nimport Pane from './pane'\r\nimport { QuoteFetchType } from './quote/constants'\r\n\r\nclass ChartLayout extends Spine.Model {\r\n static initClass(chartModel: typeof Chart, drawingsInternalStoreModel: typeof DrawingsInternalStore) {\r\n this.configure(\r\n 'ChartLayout',\r\n 'layout',\r\n 'activeChart',\r\n 'activePane',\r\n 'activeChartEvent',\r\n 'width',\r\n 'height',\r\n 'editable',\r\n 'canChangeTicker',\r\n 'scrollable',\r\n 'initialScrollable',\r\n 'cross',\r\n 'editors',\r\n 'theme',\r\n 'settings',\r\n 'isWheelZoomEnabled',\r\n 'specificChartFunctionality',\r\n 'isLargeChart',\r\n 'isHideDrawingsActive',\r\n 'isPreserveDrawingsActive',\r\n 'isLockDrawingsActive',\r\n 'isDrawingModeContinuousActive',\r\n 'uuid',\r\n 'isTouchCrossActive',\r\n 'defaultZoomFactor',\r\n 'syncChartParts',\r\n 'isInit',\r\n 'willDestroy',\r\n 'idea'\r\n )\r\n this.hasMany('charts', chartModel)\r\n this.belongsTo('drawingsInternalStore', drawingsInternalStoreModel)\r\n }\r\n\r\n declare layout: LayoutType\r\n declare activeChart: Chart\r\n declare activePane?: Pane\r\n declare activeChartEvent?: ChartEventElement\r\n declare width: number\r\n declare height: number\r\n declare editable: boolean\r\n declare canChangeTicker: boolean\r\n declare scrollable: boolean\r\n declare readonly initialScrollable: boolean\r\n declare cross: boolean\r\n declare editors: ChartEditorEnum[]\r\n declare theme: Theme\r\n declare settings: ISettings\r\n declare isWheelZoomEnabled: boolean\r\n declare specificChartFunctionality: SpecificChartFunctionality\r\n declare isLargeChart?: boolean\r\n declare charts: () => Collection\r\n declare isHideDrawingsActive: boolean\r\n declare isPreserveDrawingsActive: boolean\r\n declare isLockDrawingsActive: boolean\r\n declare isDrawingModeContinuousActive: boolean\r\n declare uuid: string\r\n declare isTouchCrossActive?: boolean\r\n declare defaultZoomFactor: number\r\n declare syncChartParts: ChartSyncablePart[]\r\n declare idea?: IIdea\r\n declare isInit?: boolean\r\n declare willDestroy?: boolean\r\n declare drawingsInternalStore: () => DrawingsInternalStore\r\n\r\n constructor(...args: any[]) {\r\n super(...args)\r\n\r\n if (!getIsSSr()) {\r\n this.bind('update', (model: ChartLayout) => {\r\n if (!window.FinvizSettings.toolsState) {\r\n window.FinvizSettings.toolsState = {}\r\n }\r\n window.FinvizSettings.toolsState[DrawingSetting.PreserveDrawings] = model.isPreserveDrawingsActive\r\n })\r\n }\r\n }\r\n\r\n getPaneWithSelection() {\r\n for (const pane of this.getAllPanes()) {\r\n if (pane.selection) {\r\n return pane\r\n }\r\n }\r\n }\r\n\r\n toObject() {\r\n const charts = this.getAllCharts().map((chart) => chart.toObject())\r\n return {\r\n layout: this.layout,\r\n width: this.width,\r\n height: this.height,\r\n charts,\r\n isHideDrawingsActive: this.isHideDrawingsActive,\r\n isPreserveDrawingsActive: this.isPreserveDrawingsActive,\r\n }\r\n }\r\n\r\n toConfig = RootChartConfigObject>(omitKeys = [] as string[]): T {\r\n const charts = this.getAllCharts().map((chart) => chart.toConfig(omitKeys))\r\n return JSON.parse(\r\n JSON.stringify(\r\n omit(\r\n {\r\n ...this.settings.ChartSettings.center,\r\n layout: this.layout,\r\n width: this.width,\r\n height: this.height,\r\n charts,\r\n isHideDrawingsActive: this.isHideDrawingsActive,\r\n isPreserveDrawingsActive: this.isPreserveDrawingsActive,\r\n colors: this.settings.ChartSettings.general.Colors,\r\n specificChartFunctionality: this.specificChartFunctionality,\r\n editors: this.editors,\r\n editable: this.editable,\r\n scrollable: this.scrollable,\r\n theme: this.theme,\r\n newCharts: /\\bcharts\\b/.test(window.location.pathname),\r\n },\r\n omitKeys\r\n )\r\n )\r\n )\r\n }\r\n\r\n destroy(options?: TodoObjectHashAnyType) {\r\n this.updateAttribute('willDestroy', true)\r\n return super.destroy(options)\r\n }\r\n\r\n destroyCascade(options?: TodoObjectHashAnyType) {\r\n this.updateAttribute('willDestroy', true)\r\n this.getAllCharts().forEach((chart) => {\r\n chart.destroyCascade()\r\n })\r\n return this.destroy(options)\r\n }\r\n\r\n getAllCharts() {\r\n return this.charts().all()\r\n }\r\n\r\n getAllPanes() {\r\n return this.getAllCharts().flatMap((chart) => chart.getAllPanes())\r\n }\r\n\r\n getAllElements() {\r\n return this.getAllCharts().flatMap((chart) => chart.getAllElements())\r\n }\r\n\r\n setSyncChartParts(chartParts: ChartSyncablePart | ChartSyncablePart[], isInSync: boolean) {\r\n const chartPartsToSync = Array.isArray(chartParts) ? chartParts : [chartParts]\r\n\r\n const newSyncedChartParts = this.syncChartParts?.filter((chartPart) => !chartPartsToSync.includes(chartPart)) ?? []\r\n\r\n if (isInSync) {\r\n newSyncedChartParts.push(...chartPartsToSync)\r\n }\r\n\r\n this.updateAttributes({ syncChartParts: newSyncedChartParts })\r\n }\r\n\r\n getIsChartPartInSync(chartPart: ChartSyncablePart) {\r\n return !!this.syncChartParts?.includes(chartPart)\r\n }\r\n\r\n getIsIndicatorPresent(type: IndicatorType) {\r\n return !!this.charts()\r\n .first()\r\n ?.getAllElements()\r\n .some((element) => element.isIndicator() && (element.instance as unknown as Indicator).type === type)\r\n }\r\n\r\n getHTMLElementId() {\r\n return `chart-layout-${this.id}`\r\n }\r\n\r\n exitIdea() {\r\n this.updateAttribute('idea', undefined)\r\n this.getAllCharts().forEach((chart) => {\r\n // Change all idea quotes to non idea quotes and refetch because we don't need them anymore, but they may cause inconsistencies if they are in cache\r\n chart.getAllQuotes().forEach((quote) => {\r\n if (quote.ideaID) {\r\n quote.updateAttributes({ ideaID: undefined })\r\n quote.fetchData({ fetchType: QuoteFetchType.Refetch })\r\n }\r\n })\r\n\r\n chart.updateAttributes({ refreshData: true })\r\n })\r\n }\r\n\r\n isIdeaId(id: number | null = null) {\r\n return (this.idea?.id ?? null) === id\r\n }\r\n}\r\n\r\nexport default ChartLayout\r\n","import { ObjectHash, Theme } from '../../../types/shared'\r\nimport { IChartThemeColors, chartDarkTheme, chartLightTheme } from '../constants'\r\n\r\nfunction normalizeHexAlpha(hexString = '') {\r\n const hexValue = hexString.replace('#', '')\r\n if (hexValue.length === 6) {\r\n return `${hexString}FF`\r\n }\r\n return hexString\r\n}\r\n\r\nexport const getColorOverwrites = ({\r\n theme,\r\n colors,\r\n}: {\r\n theme: Theme\r\n colors: ObjectHash, Theme>\r\n}) => {\r\n const customColors = colors[theme]\r\n const customColorKeys = Object.keys(customColors) as Array>\r\n const defaultColors = theme === Theme.light ? chartLightTheme : chartDarkTheme\r\n\r\n return customColorKeys.reduce((acc, colorKey) => {\r\n const isDefaultOverWritten =\r\n normalizeHexAlpha(customColors[colorKey]).toLowerCase() !==\r\n normalizeHexAlpha(defaultColors[colorKey]).toLowerCase()\r\n\r\n return isDefaultOverWritten\r\n ? {\r\n ...acc,\r\n [colorKey]: customColors[colorKey],\r\n }\r\n : acc\r\n }, {})\r\n}\r\n","import tailwindColors from '../constants/colors'\r\nimport { getHEXWithSpecificAplha } from '../utils/colors'\r\n\r\nexport interface IChartThemeColors {\r\n aftermarketFade: string\r\n background: string\r\n borderDown: string\r\n borderUp: string\r\n canvasFill: string\r\n cross: string\r\n crossText: string\r\n crossTextBackground: string\r\n currentBackground: string\r\n currentText: string\r\n grid: string\r\n gridSecondary: string\r\n indicatorCurrentBackground: string\r\n indicatorCurrentText: string\r\n line: string\r\n marketDown: string\r\n marketUp: string\r\n negativeChange: string\r\n ohlcTrendDown: string\r\n ohlcTrendUp: string\r\n overlayTransparentBackground: string\r\n percentageZeroLineText: string\r\n performanceIndicatorLabel: string\r\n positiveChange: string\r\n premarketFade: string\r\n prevClose: string\r\n text: string\r\n textSecondary: string\r\n trendDown: string\r\n trendUp: string\r\n volumeTrendDown: string\r\n volumeTrendUp: string\r\n wickDown: string\r\n wickUp: string\r\n zeroChange: string\r\n}\r\n\r\nexport interface IIndicatorThemeColors {\r\n line: string\r\n signalLine: string\r\n}\r\n\r\nexport interface IElementThemeColors {\r\n line: string\r\n border: string\r\n textWithoutBackground: string\r\n}\r\n\r\ninterface IDarkerWickColors {\r\n borderUp: string\r\n wickUp: string\r\n borderDown: string\r\n wickDown: string\r\n}\r\n\r\nexport const chartLightTheme: IChartThemeColors = {\r\n aftermarketFade: '#FFFFFF99',\r\n background: '#008CFF0E',\r\n borderDown: '#000000FF',\r\n borderUp: '#000000FF',\r\n canvasFill: '#FFFFFFFF',\r\n cross: '#0000004C',\r\n crossText: '#fff',\r\n crossTextBackground: '#111',\r\n currentBackground: tailwindColors.brightYellow[100],\r\n currentText: tailwindColors.gray[800],\r\n grid: '#D2D2D2FF',\r\n gridSecondary: '#ECECEC',\r\n indicatorCurrentBackground: tailwindColors.gray[600],\r\n indicatorCurrentText: '#fff',\r\n line: '#1E6DC0FF',\r\n marketDown: tailwindColors.red[500],\r\n marketUp: tailwindColors.green[500],\r\n negativeChange: '#C80000FF',\r\n ohlcTrendDown: '#E54040FF',\r\n ohlcTrendUp: '#40A140FF',\r\n overlayTransparentBackground: getHEXWithSpecificAplha('#C9CCD6', 0.25),\r\n percentageZeroLineText: '#111',\r\n performanceIndicatorLabel: '#646464',\r\n positiveChange: '#009600FF',\r\n premarketFade: '#FFFFFF99',\r\n prevClose: '#C80000FF',\r\n text: '#828282',\r\n textSecondary: '#dedede',\r\n trendDown: '#FF0000FF',\r\n trendUp: '#00FF00FF',\r\n volumeTrendDown: '#ffc0c0',\r\n volumeTrendUp: '#a8e0a8',\r\n wickDown: '#000000FF',\r\n wickUp: '#000000FF',\r\n zeroChange: '#000',\r\n}\r\n\r\nexport const chartDarkTheme: IChartThemeColors = {\r\n aftermarketFade: '#4C526133',\r\n background: '#1E6DC019',\r\n borderDown: '#F63538FF',\r\n borderUp: '#30CC5AFF',\r\n canvasFill: tailwindColors.gray[800],\r\n cross: '#404553',\r\n crossText: '#fff',\r\n crossTextBackground: '#111',\r\n currentBackground: tailwindColors.yellow[200],\r\n currentText: tailwindColors.gray[700],\r\n grid: '#363A46FF',\r\n gridSecondary: '#2C303A',\r\n indicatorCurrentBackground: tailwindColors.gray[500],\r\n indicatorCurrentText: '#fff',\r\n line: '#1E6DC0FF',\r\n marketDown: tailwindColors.red[300],\r\n marketUp: tailwindColors.green[300],\r\n negativeChange: tailwindColors.red[400],\r\n ohlcTrendDown: '#E54040FF',\r\n ohlcTrendUp: '#40A140FF',\r\n overlayTransparentBackground: getHEXWithSpecificAplha('#0C0E13', 0.35),\r\n percentageZeroLineText: '#fff',\r\n performanceIndicatorLabel: '#646464',\r\n positiveChange: tailwindColors.green[400],\r\n premarketFade: '#4C526133',\r\n prevClose: '#C80000FF',\r\n text: '#929cb3',\r\n textSecondary: '#929CB399',\r\n trendDown: '#F63538FF',\r\n trendUp: '#30CC5AFF',\r\n volumeTrendDown: '#F635387F',\r\n volumeTrendUp: '#30CC5A7F',\r\n wickDown: '#F63538FF',\r\n wickUp: '#30CC5AFF',\r\n zeroChange: '#929cb3',\r\n}\r\n\r\nexport const darkerWickColors: IDarkerWickColors = {\r\n borderUp: '#006400FF',\r\n wickUp: '#006400',\r\n borderDown: '#6E0000FF',\r\n wickDown: '#6E0000FF',\r\n}\r\n\r\nexport const indicatorLightTheme: IIndicatorThemeColors = {\r\n line: '#000000',\r\n signalLine: tailwindColors.red[400],\r\n}\r\n\r\nexport const indicatorDarkTheme: IIndicatorThemeColors = {\r\n line: '#D07933',\r\n signalLine: tailwindColors.red[400],\r\n}\r\n\r\nexport const elementLightTheme: IElementThemeColors = {\r\n line: '#000000',\r\n border: '#000000',\r\n textWithoutBackground: '#000000',\r\n}\r\n\r\nexport const elementDarkTheme: IElementThemeColors = {\r\n line: '#5faaf4',\r\n border: '#5192D1',\r\n textWithoutBackground: '#929cb3',\r\n}\r\nexport const generalColors: Array = [\r\n '#1f77b4',\r\n '#ff7f0e',\r\n '#2ca02c',\r\n '#d62728',\r\n '#9467bd',\r\n '#8c564b',\r\n '#e377c2',\r\n '#7f7f7f',\r\n '#bcbd22',\r\n '#17becf',\r\n]\r\n\r\n// node chart with thin bars color override\r\nexport const thinBarColorsOverride = {\r\n trendUp: '#00b400',\r\n trendDown: '#b40000',\r\n}\r\n\r\nexport enum AutoSaveState {\r\n Off,\r\n Saved,\r\n Unsaved,\r\n Saving,\r\n}\r\n\r\nexport const CHART_EVENT_BADGE_SIZE = 24\r\n","import Spine from '@finviz/spine'\r\n\r\nimport { AutoSaveElement } from '../controllers/autosave/constants'\r\nimport { getUuid } from '../utils/helpers'\r\nimport { HLC, initHlc } from '../utils/hlc'\r\nimport { AutoSaveState } from './constants'\r\n\r\ninterface DrawingsInternalStateAttrs {\r\n elements: AutoSaveElement[]\r\n latestRemoteUpdateTimestamp: HLC\r\n latestLocalUpdateTimestamp: HLC\r\n instanceUUID: string\r\n autoSaveState: AutoSaveState\r\n}\r\n\r\nclass DrawingsInternalStore extends Spine.Model {\r\n static initClass() {\r\n this.configure(\r\n 'DrawingsInternalState',\r\n 'elements',\r\n 'latestRemoteUpdateTimestamp',\r\n 'latestLocalUpdateTimestamp',\r\n 'autoSaveState',\r\n 'instanceUUID'\r\n )\r\n }\r\n\r\n elements: AutoSaveElement[]\r\n latestRemoteUpdateTimestamp: HLC\r\n latestLocalUpdateTimestamp: HLC\r\n instanceUUID: string\r\n autoSaveState: AutoSaveState\r\n\r\n constructor(attrs: Partial = {}) {\r\n super(attrs)\r\n\r\n this.elements = attrs.elements ?? []\r\n this.instanceUUID = attrs.instanceUUID ?? getUuid()\r\n this.latestLocalUpdateTimestamp = attrs.latestLocalUpdateTimestamp ?? initHlc(this.instanceUUID, 0)\r\n this.latestRemoteUpdateTimestamp = attrs.latestRemoteUpdateTimestamp ?? initHlc(this.instanceUUID, 0)\r\n this.autoSaveState = attrs.autoSaveState ?? AutoSaveState.Off\r\n }\r\n\r\n setAutoSaveState = (newAutoSaveState: AutoSaveState) => {\r\n if (this.autoSaveState !== newAutoSaveState) {\r\n this.updateAttributes({ autoSaveState: newAutoSaveState })\r\n }\r\n }\r\n}\r\n\r\nexport default DrawingsInternalStore\r\n","import Spine from '@finviz/spine'\r\nimport merge from 'lodash.merge'\r\n\r\nimport { TodoObjectHashAnyType } from '../../types/shared'\r\nimport { drawingToolsByType } from '../canvas/drawingTools'\r\nimport CanvasElement from '../canvas/element'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport { getIsSSr, getUuid } from '../utils/helpers'\r\nimport Pane from './pane'\r\nimport { changeElementZIndexes } from './utils'\r\n\r\nclass Element extends Spine.Model {\r\n static initClass(paneModel: typeof Pane) {\r\n this.configure('Element', 'instance', 'lastChange', 'zIndex', 'elementId')\r\n this.belongsTo('pane', paneModel)\r\n }\r\n\r\n declare instance: CanvasElement\r\n declare pane_id: string\r\n declare destroyed: true | undefined\r\n declare pane: () => Pane\r\n lastChange: number | null = null\r\n elementId: string | null = null\r\n zIndex = -1\r\n\r\n generateUuid = getIsSSr() ? undefined : getUuid\r\n\r\n constructor(...args: any[]) {\r\n super(...args)\r\n const elementAttrs = args[0]\r\n this.elementId = elementAttrs?.elementId ?? this.generateUuid?.()\r\n this.one('create', () => {\r\n this.updateAttributes({\r\n zIndex: elementAttrs?.zIndex ?? this.pane().getElementZIndexRange().max + 1,\r\n })\r\n })\r\n }\r\n\r\n replace(instance: CanvasElement) {\r\n const oldInstance = this.instance\r\n this.updateAttribute('instance', instance)\r\n this.trigger('replace', this, oldInstance)\r\n }\r\n\r\n makeClone() {\r\n const { instance, pane_id } = this\r\n const { attrs } = instance\r\n const { scale } = instance.model\r\n const clonedObj = merge({ pane_id }, attrs)\r\n const cloned = drawingToolsByType[instance.type as CanvasElementType].fromObject(clonedObj, instance.model)\r\n const { ThumbSettings } = this.pane().getChartLayoutSettings()\r\n const offset = ThumbSettings.size + ThumbSettings.borderWidth * 2\r\n cloned.moveBy(scale.x.invert(offset), scale.y.invert(offset) - scale.y.invert(0))\r\n cloned.cachePointPositionTimestamp()\r\n Element.create({ instance: cloned, pane_id })\r\n this.trigger('makeClone', this, cloned)\r\n }\r\n\r\n moveToZIndex(zIndex: number) {\r\n const currentZIndex = this.zIndex\r\n const directionCoef = zIndex > currentZIndex ? 1 : -1\r\n\r\n if (this.isChart() || this.isIndicator()) {\r\n if (this.zIndex !== 0) {\r\n this.updateAttributes({ zIndex: 0 })\r\n }\r\n this.pane()\r\n .getAllElements()\r\n .filter((element) => {\r\n const shouldMove = directionCoef === 1 ? element.zIndex <= zIndex : element.zIndex >= zIndex\r\n return shouldMove && element.isDrawing()\r\n })\r\n .forEach((element) => element.moveToZIndex(directionCoef * -1))\r\n\r\n return\r\n }\r\n\r\n const newZIndex = zIndex === 0 ? directionCoef : zIndex // 0 is protected value for chart/indicator element\r\n const { min, max } = this.pane().getElementZIndexRange()\r\n if (\r\n currentZIndex === newZIndex ||\r\n (currentZIndex === min && directionCoef === -1) ||\r\n (currentZIndex === max && directionCoef === 1)\r\n ) {\r\n return\r\n }\r\n const { elementsBelowZero, elementsAboveZero } = this.pane().getBelowAboveZeroElements()\r\n\r\n changeElementZIndexes({\r\n elementsArray: elementsBelowZero,\r\n addElement: newZIndex < 0 ? this : undefined,\r\n oldZIndex: currentZIndex,\r\n newZIndex,\r\n isBelowZero: true,\r\n })\r\n\r\n changeElementZIndexes({\r\n elementsArray: elementsAboveZero,\r\n addElement: newZIndex > 0 ? this : undefined,\r\n oldZIndex: currentZIndex,\r\n newZIndex,\r\n })\r\n }\r\n\r\n bringToFront() {\r\n this.moveToZIndex(this.pane().getElementZIndexRange().max + 1)\r\n }\r\n\r\n sendToBack() {\r\n this.moveToZIndex(this.pane().getElementZIndexRange().min - 1)\r\n }\r\n\r\n bringForward() {\r\n this.moveToZIndex(this.zIndex + 1)\r\n }\r\n\r\n sendBackward() {\r\n this.moveToZIndex(this.zIndex - 1)\r\n }\r\n\r\n isChart() {\r\n return !!this.instance?.type.startsWith('charts/')\r\n }\r\n\r\n isIndicator() {\r\n return !!this.instance?.type.startsWith('indicators/')\r\n }\r\n\r\n isOverlay() {\r\n return !!this.instance?.type.startsWith('overlays/')\r\n }\r\n\r\n isDrawing() {\r\n return !!this.instance?.type.startsWith('canvas/')\r\n }\r\n\r\n isChartEvent() {\r\n return !!this.instance?.type.startsWith('chartEvent/')\r\n }\r\n\r\n isMouseDown() {\r\n return !!this.instance?.isMouseDown\r\n }\r\n\r\n hasOngoingInteraction() {\r\n return this.isMouseDown() || this.instance.isEditInProgress\r\n }\r\n\r\n toObject() {\r\n return {\r\n ...this.instance.toObject(),\r\n elementId: this.elementId,\r\n zIndex: this.zIndex,\r\n }\r\n }\r\n\r\n toConfig() {\r\n return {\r\n ...this.instance.toConfig(),\r\n elementId: this.elementId,\r\n zIndex: this.zIndex,\r\n }\r\n }\r\n\r\n destroyCascade(options?: TodoObjectHashAnyType) {\r\n return this.destroy(options)\r\n }\r\n\r\n refreshElementId() {\r\n this.updateAttribute('elementId', this.generateUuid?.())\r\n }\r\n}\r\n\r\nexport default Element\r\n","import endOfDay from 'date-fns/endOfDay'\r\nimport lastDayOfMonth from 'date-fns/lastDayOfMonth'\r\nimport lastDayOfWeek from 'date-fns/lastDayOfWeek'\r\nimport setDate from 'date-fns/set'\r\n\r\nimport { TIMEFRAME, TIMEFRAMES_WITH_PRE_MARKET } from '../../constants/common'\r\nimport { convertLocalToNyTime, dateFromUnixTimestamp } from '../../utils'\r\nimport Chart from '../chart'\r\n\r\nconst MARKET_START = { hours: 9, minutes: 30 }\r\nconst END_OF_DAY = { hours: 23, minutes: 59 }\r\n\r\nfunction getIsDateBeforeMarketStart(date: Date) {\r\n const hours = date.getHours()\r\n const minutes = date.getMinutes()\r\n return hours < MARKET_START.hours || (hours === MARKET_START.hours && minutes < MARKET_START.minutes)\r\n}\r\n\r\nexport function roundTimeForSyncedPane({\r\n sourceChart,\r\n targetChart,\r\n timestamp,\r\n}: {\r\n sourceChart: Chart\r\n targetChart: Chart\r\n timestamp: number\r\n}) {\r\n let dateToReturn = dateFromUnixTimestamp(timestamp)\r\n const sourceChartHasPremarket =\r\n sourceChart.quote().premarket && TIMEFRAMES_WITH_PRE_MARKET.includes(sourceChart.timeframe)\r\n const targetChartHasPremarket =\r\n targetChart.quote().premarket && TIMEFRAMES_WITH_PRE_MARKET.includes(targetChart.timeframe)\r\n\r\n if ([TIMEFRAME.d, TIMEFRAME.w, TIMEFRAME.m].includes(sourceChart.timeframe)) {\r\n dateToReturn = setDate(dateToReturn, MARKET_START)\r\n }\r\n\r\n if (targetChart.timeframe === TIMEFRAME.m) {\r\n dateToReturn = setDate(lastDayOfMonth(dateToReturn), END_OF_DAY)\r\n } else if (targetChart.timeframe === TIMEFRAME.w) {\r\n dateToReturn = setDate(lastDayOfWeek(dateToReturn, { weekStartsOn: 1 }), END_OF_DAY)\r\n } else if (targetChart.timeframe === TIMEFRAME.d && targetChart.quote().instrument !== 'stock') {\r\n dateToReturn = endOfDay(dateToReturn)\r\n }\r\n\r\n if (sourceChartHasPremarket && !targetChartHasPremarket && targetChart.quote().instrument === 'stock') {\r\n dateToReturn = getIsDateBeforeMarketStart(dateToReturn) ? setDate(dateToReturn, MARKET_START) : dateToReturn\r\n }\r\n\r\n return ~~(convertLocalToNyTime(dateToReturn, false).getTime() / 1000)\r\n}\r\n","import Spine from '@finviz/spine'\r\n\r\nimport { ChartSyncablePart } from '../chart/contstants'\r\nimport Pane from '../pane'\r\nimport { roundTimeForSyncedPane } from './mouse-utils'\r\n\r\nexport class Mouse extends Spine.Model {\r\n static initClass() {\r\n this.configure('Mouse', 'position')\r\n this.belongsTo('pane', Pane)\r\n }\r\n\r\n declare position: { x: number; y: number } | undefined\r\n declare pane: () => Pane | null\r\n\r\n getIsCrossSyncOn = () => !!this.pane()?.chart().getIsChartPartInSync(ChartSyncablePart.Crosshair)\r\n\r\n getIsMouseInChartOfPane = (pane: Pane) => !!this.pane()?.chart().eql(pane.chart())\r\n\r\n getShouldRenderCrossInPane = (pane: Pane) => this.getIsCrossSyncOn() || this.getIsMouseInChartOfPane(pane)\r\n\r\n getCrossIndexForPane = (pane: Pane) => {\r\n if (this.position) {\r\n if (this.getIsMouseInChartOfPane(pane)) {\r\n return Math.round(this.position.x)\r\n }\r\n const paneOfMouse = this.pane()\r\n if (this.getIsCrossSyncOn() && paneOfMouse) {\r\n const mouseInChart = paneOfMouse.chart()\r\n const currentPaneChart = pane.chart()\r\n const mousePositionTimestamp = mouseInChart.quote().getTimestampFomPositionX(Math.round(this.position.x))\r\n const currentPanePositionX = currentPaneChart.quote().getPositionXFromTimestamp(\r\n roundTimeForSyncedPane({\r\n sourceChart: mouseInChart,\r\n targetChart: currentPaneChart,\r\n timestamp: mousePositionTimestamp,\r\n })\r\n )\r\n return Math.floor(currentPanePositionX)\r\n }\r\n }\r\n\r\n return Number.NaN\r\n }\r\n\r\n getPriceForPane = (pane: Pane) => {\r\n const positionY = this.position?.y ?? null\r\n\r\n if (this.pane()?.eql(pane)) {\r\n return positionY\r\n }\r\n\r\n if (this.getIsCrossSyncOn() && this.pane()) {\r\n const mousePaneIndex = this.pane()?.getIndexInChart()\r\n const currentPaneIndex = pane.getIndexInChart()\r\n return mousePaneIndex === currentPaneIndex ? positionY : null\r\n }\r\n\r\n return null\r\n }\r\n}\r\n\r\n/**\r\n * Mouse is a singleton, so `initClass` must be called before we create the instance\r\n * otherwise it wouldn’t work\r\n */\r\nMouse.initClass()\r\n\r\nconst mouse = Mouse.create()\r\nmouse.save()\r\n\r\nexport default mouse as Mouse\r\n","import Spine, { Collection } from '@finviz/spine'\r\nimport omit from 'lodash.omit'\r\n\r\nimport { Position, TodoObjectHashAnyType } from '../../types/shared'\r\nimport CanvasElement from '../canvas/element'\r\nimport { ChartEventBadgeType, PANE_HEIGHT_DEFAULT } from '../constants/common'\r\nimport { getChartLayoutSettings } from '../models/settings'\r\nimport Chart from './chart'\r\nimport ChartEventElement from './chart-event-element'\r\nimport Element from './element'\r\nimport { rebuildElementZIndexes } from './utils'\r\n\r\nexport interface ScaleAxis {\r\n (index: number): number\r\n invert: (x: number) => number\r\n domain: () => [currentDomainMax: number, currentDomainMin: number]\r\n width: (x: number) => number\r\n height: (y: number) => number\r\n ticks: (y: number) => number[]\r\n}\r\n\r\nconst CHART_EVENT_BADGE_TYPE_ORDER = [\r\n ChartEventBadgeType.Split,\r\n ChartEventBadgeType.Dividends,\r\n ChartEventBadgeType.EarningsPositive,\r\n ChartEventBadgeType.EarningsNegative,\r\n ChartEventBadgeType.EarningsNeutral,\r\n ChartEventBadgeType.EarningsFuture,\r\n]\r\n\r\nclass Pane extends Spine.Model {\r\n static initClass(\r\n elementModel: typeof Element,\r\n chartEventElementModel: typeof ChartEventElement,\r\n chartModel: typeof Chart\r\n ) {\r\n this.configure('Pane', 'height', 'scale', 'scaleRange', 'instance', 'selection')\r\n this.hasMany('elements', elementModel)\r\n this.hasMany('chartEvents', chartEventElementModel)\r\n this.belongsTo('mainElement', elementModel)\r\n this.belongsTo('chart', chartModel)\r\n }\r\n\r\n declare id: string\r\n declare chart_id: string\r\n declare height: number\r\n declare scale: {\r\n x: ScaleAxis\r\n y: ScaleAxis\r\n }\r\n\r\n declare instance: any\r\n declare chart: () => Chart\r\n declare mainElement: () => T | null\r\n declare elements: () => Collection\r\n declare chartEvents: () => Collection\r\n selection: CanvasElement | null = null\r\n scaleRange: { min: number; max: number } | null = null\r\n\r\n destroyCascade(options?: TodoObjectHashAnyType) {\r\n this.elements()\r\n .all()\r\n .forEach((element) => {\r\n element.destroyCascade()\r\n })\r\n return this.destroy(options)\r\n }\r\n\r\n toObject() {\r\n const elements = this.elements()\r\n .all()\r\n .map((el) => el.toObject())\r\n return {\r\n height: this.height,\r\n scale: this.scale,\r\n scaleRange: this.scaleRange,\r\n elements,\r\n }\r\n }\r\n\r\n toConfig(omitKeys = [] as string[]) {\r\n const elements = this.elements()\r\n .all()\r\n .map((el) => el.toConfig())\r\n return omit(\r\n {\r\n height: this.height,\r\n scaleRange: this.scaleRange,\r\n elements,\r\n },\r\n omitKeys\r\n )\r\n }\r\n\r\n move(direction: Position) {\r\n const chartPanes = this.chart().getAllPanes()\r\n const chartPane = chartPanes.find((pane) => !pane.getIsIndicatorPane())\r\n const targetPane = chartPanes.find((pane) => this.eql(pane))\r\n\r\n if (!chartPane || !targetPane) return\r\n\r\n const currentChartPaneRecords = Pane.records.filter((pane) => pane.chart_id === targetPane.chart_id)\r\n const ohterChartPaneRecords = Pane.records.filter((pane) => pane.chart_id !== targetPane.chart_id)\r\n\r\n const targetRecordIndex = currentChartPaneRecords.findIndex((record) => record.id === targetPane.id)\r\n const arrayWithoutTargetRecord = currentChartPaneRecords.filter((_, index) => index !== targetRecordIndex)\r\n const chartRecordIndex = arrayWithoutTargetRecord.findIndex((record) => record.id === chartPane.id)\r\n\r\n const panesAbove = arrayWithoutTargetRecord.slice(0, chartRecordIndex)\r\n const panesBelow = arrayWithoutTargetRecord.slice(chartRecordIndex + 1)\r\n if (direction === Position.Above) {\r\n panesAbove.push(currentChartPaneRecords[targetRecordIndex])\r\n panesAbove.sort((a, b) => a.getNumericId() - b.getNumericId())\r\n }\r\n if (direction === Position.Below) {\r\n panesBelow.push(currentChartPaneRecords[targetRecordIndex])\r\n panesBelow.sort((a, b) => a.getNumericId() - b.getNumericId())\r\n }\r\n\r\n Pane.records = ohterChartPaneRecords.concat([\r\n ...panesAbove,\r\n arrayWithoutTargetRecord[chartRecordIndex],\r\n ...panesBelow,\r\n ])\r\n this.chart().trigger('change', this.chart())\r\n }\r\n\r\n getChartLayoutSettings() {\r\n return getChartLayoutSettings(this.chart().chart_layout())\r\n }\r\n\r\n getAllElements() {\r\n return this.elements()\r\n .all()\r\n .sort((a, b) => a.zIndex - b.zIndex)\r\n }\r\n\r\n getAllChartEvents(isSorted = true) {\r\n const chartEvents = [...this.chartEvents().all()]\r\n return isSorted ? chartEvents.sort((a, b) => a.zIndex - b.zIndex) : chartEvents\r\n }\r\n\r\n getChartOrIndicatorElement() {\r\n return this.getAllElements().find((el) => el.isChart() || el.isIndicator()) ?? null\r\n }\r\n\r\n getIsIndicatorPane() {\r\n return !!this.mainElement()?.isIndicator()\r\n }\r\n\r\n getIsChartPane() {\r\n return !!this.mainElement()?.isChart()\r\n }\r\n\r\n resetHeight() {\r\n if (this.getIsIndicatorPane()) {\r\n this.updateAttribute('height', PANE_HEIGHT_DEFAULT.indicator)\r\n }\r\n if (this.getIsChartPane()) {\r\n this.updateAttribute('height', PANE_HEIGHT_DEFAULT.chart)\r\n }\r\n }\r\n\r\n getIndexInChart() {\r\n return this.chart()\r\n .getAllPanes()\r\n .findIndex((chartPane) => chartPane.eql(this))\r\n }\r\n\r\n getElementZIndexRange() {\r\n let max = -1\r\n let min = 1\r\n this.getAllElements().forEach((el) => {\r\n if (el.zIndex > max) {\r\n max = el.zIndex\r\n }\r\n if (el.zIndex < min) {\r\n min = el.zIndex\r\n }\r\n })\r\n return { min, max }\r\n }\r\n\r\n getBelowAboveZeroElements() {\r\n const allPaneElements = this.getAllElements()\r\n const elementsBelowZero: Element[] = []\r\n const elementsAboveZero: Element[] = []\r\n allPaneElements.forEach((el) => {\r\n if (el.zIndex < 0) {\r\n elementsBelowZero.push(el)\r\n }\r\n if (el.zIndex > 0) {\r\n elementsAboveZero.push(el)\r\n }\r\n })\r\n\r\n return { elementsBelowZero, elementsAboveZero }\r\n }\r\n\r\n normalizeZIndexes() {\r\n const { elementsBelowZero, elementsAboveZero } = this.getBelowAboveZeroElements()\r\n rebuildElementZIndexes({ elementsArray: elementsBelowZero, isBelowZero: true })\r\n rebuildElementZIndexes({ elementsArray: elementsAboveZero, isBelowZero: false })\r\n }\r\n\r\n getQuoteRawTicker() {\r\n return this.chart().getQuoteRawTicker()\r\n }\r\n\r\n getNumericId() {\r\n return Number(this.id.replace('c-', ''))\r\n }\r\n\r\n updateChartEventsZIndexes() {\r\n if (!this.scale || !this.scale.hasOwnProperty('x')) {\r\n return\r\n }\r\n\r\n const chartEvents = this.getAllChartEvents(false).sort(\r\n (a, b) => a.instance.attrs.positionTimestamps!.x - b.instance.attrs.positionTimestamps!.x\r\n )\r\n const hoveredChartEvent = chartEvents.find((chartEvent) => chartEvent.instance.isHovered)\r\n const openedChartEvent = chartEvents.find((chartEvent) => chartEvent.instance.isOpen)\r\n\r\n const hoveredTypeChartEventElements: ChartEventElement[] = []\r\n const openedTypeChartEventElements: ChartEventElement[] = []\r\n const nonActiveChartEventElements: ChartEventElement[] = []\r\n\r\n chartEvents.forEach((chartEvent, index) => {\r\n const chartEventsOnSameXPoint = chartEvents.filter(\r\n (chartEvent_B, i) =>\r\n i < index && Math.round(chartEvent.instance.attrs.x) === Math.round(chartEvent_B!.instance.attrs.x)\r\n )\r\n chartEvent.updateAttributes({ yIndex: chartEventsOnSameXPoint.length })\r\n const isHovered = chartEvent.instance === hoveredChartEvent?.instance\r\n const isOpened = chartEvent.instance === openedChartEvent?.instance\r\n const isHoveredType = chartEvent.instance.type === hoveredChartEvent?.instance.type\r\n const isOpenType = chartEvent.instance.type === openedChartEvent?.instance.type\r\n if (!isHovered || !isOpened) {\r\n if (isHoveredType) {\r\n hoveredTypeChartEventElements.push(chartEvent)\r\n } else if (isOpenType) {\r\n openedTypeChartEventElements.push(chartEvent)\r\n } else {\r\n nonActiveChartEventElements.push(chartEvent)\r\n }\r\n }\r\n })\r\n\r\n nonActiveChartEventElements.sort(\r\n (a, b) =>\r\n CHART_EVENT_BADGE_TYPE_ORDER.indexOf(a.instance.getChartEvenBadgeType()) -\r\n CHART_EVENT_BADGE_TYPE_ORDER.indexOf(b.instance.getChartEvenBadgeType())\r\n )\r\n\r\n const chartEventElements = [\r\n ...nonActiveChartEventElements,\r\n ...openedTypeChartEventElements,\r\n openedChartEvent,\r\n ...hoveredTypeChartEventElements,\r\n hoveredChartEvent,\r\n ].filter(Boolean)\r\n chartEventElements.forEach((chartEvent, index) => {\r\n chartEvent!.updateAttributes({ zIndex: index })\r\n })\r\n }\r\n}\r\n\r\nexport default Pane\r\n","import { ObjectHash, RequireByKey } from '../../types/shared'\r\n\r\ninterface HeikinAshiData {\r\n HAOpen: number[]\r\n HAClose: number[]\r\n}\r\n\r\ninterface QuoteValues {\r\n cachedAt: null | number\r\n dayToOffset: ObjectHash[]\r\n dateToIndex: ObjectHash[]\r\n heikinAshiData?: HeikinAshiData\r\n daysInQuote: Date[]\r\n}\r\n\r\ninterface QuoteCacheFunctionProps {\r\n cid: string\r\n key: keyof QuoteValues\r\n fetchedAt: number\r\n value: any\r\n}\r\n\r\nconst quoteCache = {} as ObjectHash\r\n\r\nexport function getCachedQuote({\r\n cid,\r\n key,\r\n fetchedAt,\r\n}: RequireByKey>, 'cid'>) {\r\n const quote = quoteCache[cid]\r\n if (quote?.cachedAt === fetchedAt && key) {\r\n return quote[key]\r\n } else if (!key) {\r\n return quote\r\n }\r\n return null\r\n}\r\n\r\nexport function setCachedQuote({\r\n cid,\r\n key,\r\n value,\r\n fetchedAt,\r\n}: Pick) {\r\n quoteCache[cid] = {\r\n ...(quoteCache[cid]?.cachedAt === fetchedAt ? quoteCache[cid] : {}),\r\n [key]: value,\r\n cachedAt: fetchedAt,\r\n } as QuoteValues\r\n}\r\n\r\nexport function deleteCachedQuote({ cid }: Pick) {\r\n delete quoteCache[cid]\r\n}\r\n","import Spine from '@finviz/spine'\r\nimport { isSameMonth, isSameWeek } from 'date-fns'\r\nimport queryString from 'query-string'\r\n\r\nimport { Instrument, ObjectHash, TodoObjectHashAnyType } from '../../types/shared'\r\nimport { ChartEventDbType, ChartEventType, IntradayTimeframeInterval, TIMEFRAME } from '../constants/common'\r\nimport type { ICOT } from '../indicators/cot'\r\nimport { dateFromUnixTimestamp, dateStringFromDate } from '../utils'\r\nimport { getIsAbortError } from '../utils/abort_controller'\r\nimport { getPositionXFromTimestamp, getTimestampFromPositionX } from '../utils/chart'\r\nimport { IDividends, IEarnings, ISplit } from '../utils/chart-events-utils'\r\nimport fetchApi, { NotFoundError } from '../utils/fetch_api'\r\nimport { getIsSSr } from '../utils/helpers'\r\nimport { QuoteFetchType, QuoteFetchTypeUrlOption, QuoteUrlOptions } from './quote/constants'\r\nimport { deleteCachedQuote, getCachedQuote, setCachedQuote } from './quoteCache'\r\nimport { getRawTickerForInstrument } from './utils'\r\n\r\nconst quoteRefreshChecksBeforeFullRefresh = 15\r\n\r\ntype TodoPattern = TodoObjectHashAnyType\r\n\r\nexport interface TickerTimeframesProps {\r\n ticker: string\r\n instrument: string\r\n timeframe: string\r\n}\r\n\r\ninterface QuoteFetchOptions {\r\n aftermarket?: boolean\r\n premarket?: boolean\r\n patterns?: boolean\r\n events?: boolean\r\n maxBars?: number\r\n}\r\n\r\ninterface QuoteInternalOptions {\r\n cachePredicate?: (quote: Quote) => boolean\r\n fetchNewDataOnCachedQuote?: boolean\r\n}\r\n\r\ninterface UrlOptions extends QuoteFetchOptions {\r\n ticker: string\r\n instrument: string\r\n timeframe: string\r\n}\r\n\r\ntype ChartEventDataRaw = Omit & { eventType: ChartEventDbType }\r\n\r\nexport interface DataResponse {\r\n COTs: COTData\r\n name: string\r\n ticker: string\r\n instrument: string\r\n interval: number\r\n timeframe: string\r\n open: number[]\r\n high: number[]\r\n low: number[]\r\n close: number[]\r\n date: number[]\r\n volume: number[]\r\n lastOpen: number\r\n lastHigh: number\r\n lastLow: number\r\n lastClose: number\r\n lastDate: number\r\n lastTime: string | null\r\n lastVolume: number\r\n dataId: string\r\n prevClose: number\r\n afterClose: number\r\n afterChange: number\r\n afterTime: string | null\r\n drawMinutesPerDay: number\r\n marketStartMinutes: number\r\n premarketLengthMinutes: number\r\n aftermarketLengthMinutes: number\r\n aftermarket: boolean\r\n premarket: boolean\r\n hasPatterns: boolean\r\n patterns: Array\r\n patternsMinRange: number\r\n patternsMaxRange: number\r\n relativeVolume: number\r\n isIntraday: boolean\r\n noNewData?: boolean\r\n chartEvents?: ChartEventDataRaw[]\r\n}\r\n\r\ninterface COTData {\r\n [code: string]: ICOT\r\n}\r\n\r\nconst emptyQuote = {\r\n open: [],\r\n high: [],\r\n low: [],\r\n close: [],\r\n volume: [],\r\n date: [],\r\n fetchedAt: -1,\r\n numberOfRefreshChecks: 0,\r\n isFetching: false,\r\n is404: false,\r\n COTs: undefined,\r\n name: undefined,\r\n drawMinutesPerDay: undefined,\r\n marketStartMinutes: undefined,\r\n premarketLengthMinutes: undefined,\r\n aftermarketLengthMinutes: undefined,\r\n patterns: [],\r\n patternsMinRange: undefined,\r\n patternsMaxRange: undefined,\r\n relativeVolume: undefined,\r\n lastOpen: undefined,\r\n lastHigh: undefined,\r\n lastLow: undefined,\r\n lastClose: undefined,\r\n lastVolume: undefined,\r\n dataId: undefined,\r\n lastDate: undefined,\r\n prevClose: undefined,\r\n afterClose: undefined,\r\n afterChange: undefined,\r\n chartEvents: [],\r\n}\r\n\r\ninterface ICacheAvailabilityCheckFunctionsArguments {\r\n quote: Quote\r\n options?: QuoteFetchOptions & QuoteInternalOptions\r\n}\r\n\r\nconst doesQuoteAndOptionsMatch = ({ quote, options }: ICacheAvailabilityCheckFunctionsArguments) =>\r\n !quote.premarket === !options?.premarket &&\r\n !quote.aftermarket === !options?.aftermarket &&\r\n !quote.hasPatterns === !options?.patterns &&\r\n // if options.events is false we can reuse quote with events\r\n (!options?.events || !!quote.events)\r\n\r\nconst doesQuoteAndFetchParamsMatch = ({\r\n quote,\r\n ticker,\r\n instrument,\r\n timeframe,\r\n}: {\r\n quote: Quote\r\n ticker: string\r\n instrument: Instrument\r\n timeframe: TIMEFRAME\r\n}) => quote.ticker === ticker && quote.instrument === instrument && quote.timeframe === timeframe\r\n\r\n// either we don't care about matching uuid at all, or they have to match\r\nconst isSameOrNoChartUuid = ({ quote, uuid }: { quote: Quote; uuid?: string }) => !uuid || quote.chartUuid === uuid\r\n\r\nconst isCacheAllowed = ({ quote, options }: ICacheAvailabilityCheckFunctionsArguments) =>\r\n !options?.cachePredicate || options.cachePredicate(quote)\r\n\r\nconst isNotEmptyQuote = (quote: Quote) => quote.fetchedAt !== -1 || quote.isFetching\r\n\r\nexport type QuoteGetParams = {\r\n ticker: string\r\n instrument: Instrument\r\n timeframe: TIMEFRAME\r\n options?: QuoteFetchOptions & QuoteInternalOptions\r\n abortController?: null | AbortController\r\n shouldUseCache?: boolean\r\n chartUuid?: string\r\n}\r\n\r\nfunction getChartEventsWithId({ ticker, chartEvents }: { ticker: string; chartEvents?: ChartEventDataRaw[] }) {\r\n return (\r\n chartEvents?.map((item) => {\r\n let eventType: ChartEventType\r\n switch (item.eventType) {\r\n case ChartEventDbType.Dividends:\r\n eventType = ChartEventType.Dividends\r\n break\r\n case ChartEventDbType.Split:\r\n eventType = ChartEventType.Split\r\n break\r\n case ChartEventDbType.Earnings:\r\n eventType = ChartEventType.Earnings\r\n break\r\n }\r\n return {\r\n ...item,\r\n elementId: `${ticker.toLowerCase()}-${item.eventType}-${item.dateTimestamp}`,\r\n eventType,\r\n }\r\n }) ?? []\r\n )\r\n}\r\n\r\nclass Quote extends Spine.Model {\r\n static initClass() {\r\n this.configure(\r\n 'Quote',\r\n 'ticker',\r\n 'name',\r\n 'instrument',\r\n 'timeframe',\r\n 'open',\r\n 'high',\r\n 'low',\r\n 'close',\r\n 'date',\r\n 'volume',\r\n 'lastOpen',\r\n 'lastHigh',\r\n 'lastLow',\r\n 'lastClose',\r\n 'lastDate',\r\n 'lastVolume',\r\n 'lastTime',\r\n 'dataId',\r\n 'prevClose',\r\n 'COTs',\r\n 'chartEvents',\r\n 'afterClose',\r\n 'afterChange',\r\n 'afterTime',\r\n 'drawMinutesPerDay',\r\n 'marketStartMinutes',\r\n 'premarketLengthMinutes',\r\n 'aftermarketLengthMinutes',\r\n 'aftermarket',\r\n 'premarket',\r\n 'events',\r\n 'hasPatterns',\r\n 'patterns',\r\n 'patternsMinRange',\r\n 'patternsMaxRange',\r\n 'relativeVolume',\r\n 'fetchedAt',\r\n 'isIntraday',\r\n 'interval',\r\n 'drawDays',\r\n 'barIndex',\r\n 'barToDataIndex',\r\n 'fetchingPromise',\r\n 'isFetching',\r\n 'wasFetchAborted',\r\n 'chartUuid',\r\n 'numberOfRefreshChecks',\r\n 'maxBars',\r\n 'ideaID',\r\n 'is404'\r\n )\r\n }\r\n\r\n static async get({\r\n ticker: tickerRaw,\r\n instrument,\r\n timeframe,\r\n options,\r\n abortController,\r\n shouldUseCache = true,\r\n chartUuid,\r\n }: QuoteGetParams): Promise {\r\n const ticker = tickerRaw.replace('@', '')\r\n const [quote] = shouldUseCache\r\n ? Quote.select(\r\n (q) =>\r\n doesQuoteAndFetchParamsMatch({ quote: q, ticker, instrument, timeframe }) &&\r\n isSameOrNoChartUuid({ quote: q, uuid: chartUuid }) &&\r\n isNotEmptyQuote(q) &&\r\n isCacheAllowed({ quote: q, options }) &&\r\n (q.instrument !== Instrument.Stock ||\r\n Number.isInteger(q.ideaID) ||\r\n doesQuoteAndOptionsMatch({ quote: q, options }))\r\n )\r\n : []\r\n\r\n if (quote) {\r\n if (quote.isFetching) {\r\n await quote.getResolvedFetchingPromise()\r\n } else if (options?.fetchNewDataOnCachedQuote) {\r\n await quote.fetchData({ fetchType: QuoteFetchType.NewerData, abortController })\r\n }\r\n return quote\r\n }\r\n\r\n const newQuote = Quote.create({\r\n ...emptyQuote,\r\n ticker,\r\n timeframe,\r\n instrument,\r\n chartUuid,\r\n maxBars: options?.maxBars,\r\n premarket: !!options?.premarket,\r\n aftermarket: !!options?.aftermarket,\r\n hasPatterns: !!options?.patterns,\r\n events: !!options?.events,\r\n })\r\n\r\n await newQuote.fetchData({ fetchType: QuoteFetchType.Refetch, abortController })\r\n\r\n return newQuote\r\n }\r\n\r\n static async getAll(tickersAndTimeframes: Array<{ ticker: string; instrument: Instrument; timeframe: TIMEFRAME }>) {\r\n // TODO: fetch in 1 request\r\n if (tickersAndTimeframes.length === 0) {\r\n return {}\r\n }\r\n\r\n try {\r\n await Promise.all(\r\n tickersAndTimeframes.map(({ ticker, instrument, timeframe }) =>\r\n this.get({ ticker: ticker, instrument, timeframe })\r\n )\r\n )\r\n const data = tickersAndTimeframes.reduce(\r\n (accumulator, currentValue) => ({\r\n ...accumulator,\r\n [currentValue.ticker]: Quote.select(\r\n (q: Quote) =>\r\n q.ticker === currentValue.ticker &&\r\n q.instrument === currentValue.instrument &&\r\n q.timeframe === currentValue.timeframe\r\n )[0],\r\n }),\r\n {}\r\n )\r\n return data\r\n } catch (err) {\r\n // TODO: handle somehow\r\n }\r\n }\r\n\r\n declare ticker: string\r\n declare name: string\r\n declare instrument: Instrument\r\n declare interval: number\r\n declare timeframe: TIMEFRAME\r\n declare open: number[]\r\n declare high: number[]\r\n declare low: number[]\r\n declare close: number[]\r\n declare date: number[]\r\n declare volume: number[]\r\n declare lastOpen: number\r\n declare lastHigh: number\r\n declare lastLow: number\r\n declare lastClose: number\r\n declare lastDate: number\r\n declare lastVolume: number\r\n declare dataId: string\r\n declare prevClose: number\r\n declare COTs: COTData\r\n declare afterClose: number\r\n declare afterChange: number\r\n declare drawMinutesPerDay: number\r\n declare marketStartMinutes: number\r\n declare premarketLengthMinutes: number\r\n declare aftermarketLengthMinutes: number\r\n declare hasPatterns: boolean\r\n declare patterns: Array\r\n declare patternsMinRange: number\r\n declare patternsMaxRange: number\r\n declare relativeVolume: number\r\n declare isIntraday: boolean\r\n declare drawDays?: number\r\n declare barIndex: number[]\r\n /**\r\n * Array of length the same as number of bars\r\n *\r\n * If there's a gap and a bar index has no corresponding data index,\r\n * the last data index is used (or 0 if there's no last data index)\r\n *\r\n * @type {number[]}\r\n */\r\n declare barToDataIndex: number[]\r\n declare chartUuid?: string\r\n declare aftermarket: boolean\r\n declare premarket: boolean\r\n declare fetchedAt: number\r\n declare numberOfRefreshChecks: number\r\n declare isFetching: boolean\r\n declare fetchingPromise?: Promise\r\n declare wasFetchAborted: boolean\r\n declare maxBars?: number\r\n declare ideaID?: number\r\n declare is404?: boolean\r\n declare chartEvents: Array\r\n declare events?: boolean\r\n\r\n async fetchRequest({\r\n abortController,\r\n options = { type: QuoteFetchTypeUrlOption.New },\r\n }: {\r\n abortController?: null | AbortController\r\n options?: QuoteUrlOptions\r\n }) {\r\n let data: DataResponse | null = null\r\n let is404 = false\r\n let wasFetchAborted = false\r\n\r\n const fetchingPromise = fetchApi({\r\n location: this.getUrl(options),\r\n throwOnStatusCodes: [404],\r\n abortController,\r\n })\r\n\r\n this.updateAttributes({\r\n isFetching: true,\r\n fetchingPromise,\r\n })\r\n\r\n try {\r\n data = await fetchingPromise\r\n } catch (err) {\r\n if (getIsAbortError(err as Error)) {\r\n wasFetchAborted = true\r\n } else if (process.env.IS_E2E_TESTING) {\r\n throw new Error('Quote fetch error', { cause: err })\r\n }\r\n is404 = err instanceof NotFoundError\r\n // Ignore network/notfound errors\r\n }\r\n\r\n const shouldUseEmptyQuote = !data && !wasFetchAborted && options.type === QuoteFetchTypeUrlOption.New\r\n\r\n if (process.env.IS_E2E_TESTING && shouldUseEmptyQuote) {\r\n throw new Error('Quote fetch new fail', { cause: { options, is404, wasFetchAborted, data } })\r\n }\r\n\r\n this.updateAttributes({\r\n ...(shouldUseEmptyQuote ? emptyQuote : {}),\r\n is404,\r\n wasFetchAborted,\r\n isFetching: false,\r\n })\r\n\r\n return data\r\n }\r\n\r\n async isPossibleToFetchSequentialData({\r\n abortController,\r\n }: {\r\n abortController?: null | AbortController\r\n } = {}) {\r\n const data = await this.fetchRequest({ abortController })\r\n if (data && data.date.length > 0 && this.date.length > 0) {\r\n return this.date[this.date.length - 1] >= data.date[0]\r\n }\r\n return false\r\n }\r\n\r\n async fetchData({\r\n fetchType,\r\n abortController,\r\n }: {\r\n fetchType: QuoteFetchType\r\n abortController?: null | AbortController\r\n }) {\r\n let options: QuoteUrlOptions\r\n if (fetchType === QuoteFetchType.Refetch) {\r\n options = { type: QuoteFetchTypeUrlOption.New }\r\n } else if (fetchType === QuoteFetchType.NewerData) {\r\n options = { type: QuoteFetchTypeUrlOption.Newer }\r\n if ((this.numberOfRefreshChecks ?? 0) < quoteRefreshChecksBeforeFullRefresh) {\r\n options.dataId = this.dataId\r\n }\r\n } else {\r\n return\r\n }\r\n if (this.instrument === Instrument.Stock) {\r\n options.events = this.events == null ? true : this.events\r\n }\r\n\r\n const data = await this.fetchRequest({ abortController, options })\r\n\r\n if (!data || data.noNewData === true) {\r\n this.updateAttributes({\r\n numberOfRefreshChecks: (this.numberOfRefreshChecks ?? 0) + 1,\r\n })\r\n return\r\n }\r\n if (this.timeframe !== data.timeframe || this.ticker.toLowerCase() !== data.ticker?.toLowerCase()) {\r\n return\r\n }\r\n\r\n const newQuoteData = {\r\n COTs: data.COTs,\r\n name: data.name,\r\n open: data.open,\r\n high: data.high,\r\n low: data.low,\r\n close: data.close,\r\n volume: data.volume,\r\n date: data.date,\r\n drawMinutesPerDay: data.drawMinutesPerDay,\r\n marketStartMinutes: data.marketStartMinutes,\r\n premarketLengthMinutes: data.premarketLengthMinutes,\r\n aftermarketLengthMinutes: data.aftermarketLengthMinutes,\r\n patterns: data.patterns ?? [],\r\n patternsMinRange: data.patternsMinRange,\r\n patternsMaxRange: data.patternsMaxRange,\r\n relativeVolume: data.relativeVolume,\r\n lastOpen: data.lastOpen,\r\n lastHigh: data.lastHigh,\r\n lastLow: data.lastLow,\r\n lastClose: data.lastClose,\r\n lastVolume: data.lastVolume,\r\n dataId: data.dataId,\r\n lastDate: data.lastDate,\r\n lastTime: data.lastTime,\r\n prevClose: data.prevClose,\r\n afterClose: data.afterClose,\r\n afterChange: data.afterChange,\r\n afterTime: data.afterTime,\r\n numberOfRefreshChecks: 0,\r\n chartEvents: data.chartEvents ?? [],\r\n fetchedAt: Date.now(),\r\n }\r\n\r\n if (\r\n !(\r\n fetchType === QuoteFetchType.Refetch ||\r\n [Instrument.Futures, Instrument.Forex, Instrument.Crypto].includes(this.instrument)\r\n )\r\n ) {\r\n /*\r\n * Merges current and new data taking date as index\r\n */\r\n let AIndex = 0\r\n let BIndex = 0\r\n let mergeIndex = -1\r\n while (AIndex < this.date.length || BIndex < data.date.length) {\r\n const ADate = this.date[AIndex]\r\n const BDate = data.date[BIndex]\r\n if (BDate === undefined) {\r\n break\r\n } else if (ADate === BDate) {\r\n // Same date, update OHLCV\r\n this.open[AIndex] = data.open[BIndex]\r\n this.high[AIndex] = data.high[BIndex]\r\n this.low[AIndex] = data.low[BIndex]\r\n this.close[AIndex] = data.close[BIndex]\r\n this.volume[AIndex] = data.volume[BIndex]\r\n AIndex++\r\n BIndex++\r\n } else if (ADate > BDate || ADate === undefined) {\r\n // New bar for a date not yet in our dataset\r\n // If weekly or monthly timeframe & wasn't merged on AIndex\r\n if (mergeIndex === -1 && [TIMEFRAME.w, TIMEFRAME.m].includes(this.timeframe)) {\r\n const prevAIndex = AIndex - 1\r\n const prevDate = dateFromUnixTimestamp(this.date[prevAIndex])\r\n const newDate = dateFromUnixTimestamp(data.date[BIndex])\r\n // If merge bar for weekly is sameWeek or for monthly is sameMonth perform merge on AIndex\r\n if (\r\n (TIMEFRAME.w === this.timeframe && isSameWeek(prevDate, newDate, { weekStartsOn: 1 })) ||\r\n (TIMEFRAME.m === this.timeframe && isSameMonth(prevDate, newDate))\r\n ) {\r\n this.date[prevAIndex] = data.date[BIndex]\r\n this.open[prevAIndex] = data.open[BIndex]\r\n this.high[prevAIndex] = data.high[BIndex]\r\n this.low[prevAIndex] = data.low[BIndex]\r\n this.close[prevAIndex] = data.close[BIndex]\r\n this.volume[prevAIndex] = data.volume[BIndex]\r\n mergeIndex = prevAIndex\r\n // Incrementing BIndex only because we're mergin arrays on AIndex\r\n BIndex++\r\n continue\r\n }\r\n }\r\n this.date.splice(AIndex, 0, data.date[BIndex])\r\n this.open.splice(AIndex, 0, data.open[BIndex])\r\n this.high.splice(AIndex, 0, data.high[BIndex])\r\n this.low.splice(AIndex, 0, data.low[BIndex])\r\n this.close.splice(AIndex, 0, data.close[BIndex])\r\n this.volume.splice(AIndex, 0, data.volume[BIndex])\r\n // Incrementing AIndex because we're changing the array in-place\r\n AIndex++\r\n BIndex++\r\n } else if (ADate < BDate) {\r\n AIndex++\r\n } else {\r\n console.warn('fetchNewerData merge warning')\r\n window.Sentry?.captureMessage('quote.ts fetchNewerData merge warning', {\r\n extra: {\r\n thisDateLength: this.date.length,\r\n dataDateLength: data.date.length,\r\n AIndex,\r\n BIndex,\r\n ADate,\r\n BDate,\r\n },\r\n })\r\n }\r\n }\r\n\r\n newQuoteData.date = this.date\r\n newQuoteData.open = this.open\r\n newQuoteData.high = this.high\r\n newQuoteData.low = this.low\r\n newQuoteData.close = this.close\r\n newQuoteData.volume = this.volume\r\n }\r\n\r\n const hasUpdatedSuccessfully = this.updateAttributes(newQuoteData)\r\n // https://github.com/finvizhq/charts/issues/510\r\n if (!hasUpdatedSuccessfully) {\r\n // attempt to find if this.model.quote() => null is comming from this.save() validation fail\r\n window.Sentry?.captureMessage('quote.ts fetchNewerData save() validation failed', { extra: this })\r\n }\r\n if (!this) {\r\n // or this somehow became null / falsy\r\n window.Sentry?.captureMessage('quote.ts fetchNewerData this is falsy', { extra: this })\r\n }\r\n this.trigger(fetchType, this, fetchType)\r\n }\r\n\r\n async getResolvedFetchingPromise() {\r\n try {\r\n return await this.fetchingPromise\r\n } catch {\r\n // do nothing\r\n }\r\n }\r\n\r\n fetchOlderData() {\r\n return // not yet implemented\r\n // TODO cancel previous request\r\n }\r\n\r\n load(atts: ObjectHash) {\r\n super.load(atts)\r\n const { fetchedAt = 0 } = atts\r\n const { cachedAt } = (getCachedQuote({ cid: this.cid }) as { cachedAt: number } | null) || {}\r\n if (this.timeframe && cachedAt !== fetchedAt) {\r\n setCachedQuote({ cid: this.cid, key: 'cachedAt', value: fetchedAt, fetchedAt })\r\n this.isIntraday = [\r\n TIMEFRAME.i1,\r\n TIMEFRAME.i2,\r\n TIMEFRAME.i3,\r\n TIMEFRAME.i5,\r\n TIMEFRAME.i10,\r\n TIMEFRAME.i15,\r\n TIMEFRAME.i30,\r\n TIMEFRAME.h,\r\n TIMEFRAME.h2,\r\n TIMEFRAME.h4,\r\n ].includes(this.timeframe)\r\n this.interval = this.isIntraday\r\n ? IntradayTimeframeInterval[this.timeframe as keyof typeof IntradayTimeframeInterval]\r\n : 0\r\n this.drawDays = this.getDrawDays()\r\n this.barIndex = this.getBarIndexes()\r\n this.patterns = this.patterns ?? []\r\n this.barToDataIndex = this.barIndex.flatMap((barIndex, index) => {\r\n const lastIndex = this.barIndex[index - 1] ?? -1\r\n return [...Array.from({ length: barIndex - lastIndex - 1 }).fill(Math.max(0, index - 1)), index] as number[]\r\n })\r\n }\r\n if (this.timeframe && this.ticker) {\r\n this.chartEvents = getChartEventsWithId({\r\n ticker: this.ticker,\r\n chartEvents: this.chartEvents as unknown as ChartEventDataRaw[],\r\n })\r\n }\r\n return this\r\n }\r\n\r\n destroy(options?: ObjectHash) {\r\n super.destroy(options)\r\n deleteCachedQuote({ cid: this.cid })\r\n return this\r\n }\r\n\r\n getDrawDays() {\r\n if (this.instrument !== Instrument.Stock) {\r\n return Infinity\r\n }\r\n switch (this.timeframe) {\r\n case TIMEFRAME.i1:\r\n case TIMEFRAME.i2:\r\n case TIMEFRAME.i3:\r\n case TIMEFRAME.i5:\r\n case TIMEFRAME.i10:\r\n return 10\r\n case TIMEFRAME.i15:\r\n case TIMEFRAME.i30:\r\n case TIMEFRAME.h:\r\n case TIMEFRAME.h2:\r\n case TIMEFRAME.h4:\r\n return 15\r\n default:\r\n break\r\n }\r\n }\r\n\r\n getHeikinAshiData() {\r\n const cachedHeikinAshiData = getCachedQuote({ cid: this.cid, key: 'heikinAshiData', fetchedAt: this.fetchedAt })\r\n if (cachedHeikinAshiData) {\r\n return cachedHeikinAshiData as unknown as { open: number[]; close: number[] }\r\n }\r\n\r\n const HAClose = this.open.map((_, i) => (this.open[i] + this.high[i] + this.close[i] + this.low[i]) / 4)\r\n const HAOpen = this.open.reduce(\r\n (acc, open, i) => [...acc, (i === 0 ? open + HAClose[0] : acc[i - 1] + HAClose[i - 1]) / 2],\r\n [] as number[]\r\n )\r\n\r\n const heikAshiData = { open: HAOpen, close: HAClose }\r\n\r\n setCachedQuote({ cid: this.cid, key: 'heikinAshiData', value: heikAshiData, fetchedAt: this.fetchedAt })\r\n\r\n return heikAshiData\r\n }\r\n\r\n getDayToOffset(): ObjectHash {\r\n const cachedDayToOffset = getCachedQuote({ cid: this.cid, key: 'dayToOffset', fetchedAt: this.fetchedAt })\r\n if (cachedDayToOffset) {\r\n return cachedDayToOffset as unknown as ObjectHash\r\n }\r\n const dayToOffset: ObjectHash = {}\r\n let day = 0\r\n let lastDay\r\n for (let i = 0, end = this.date.length, asc = end >= 0; asc ? i < end : i > end; asc ? i++ : i--) {\r\n const date = dateFromUnixTimestamp(this.date[i])\r\n const dateString = dateStringFromDate(date)\r\n if (dateString !== lastDay) {\r\n dayToOffset[dateString] = day\r\n day++\r\n lastDay = dateString\r\n }\r\n }\r\n // for ofscreen renderer we need to add lastDate to have correct dayToOffset because if\r\n // premarket=false in fetch query there isn't other way to distinguish that\r\n if (getIsSSr() && this.lastDate) {\r\n // YYYYMMDD / 20211118 => YYYY-MM-DD\r\n const [yyyy, mm, dd] = [~~(this.lastDate / 10000), ~~(this.lastDate / 100) % 100, this.lastDate % 100]\r\n const lastDate = `${yyyy}-${String(mm).padStart(2, '0')}-${String(dd).padStart(2, '0')}`\r\n\r\n if (lastDay !== lastDate) {\r\n dayToOffset[lastDate] = day\r\n }\r\n }\r\n\r\n setCachedQuote({ cid: this.cid, key: 'dayToOffset', value: dayToOffset, fetchedAt: this.fetchedAt })\r\n return dayToOffset\r\n }\r\n\r\n getDaysInQuote() {\r\n const cachedDayToOffset = getCachedQuote({ cid: this.cid, key: 'daysInQuote', fetchedAt: this.fetchedAt })\r\n if (cachedDayToOffset) {\r\n return cachedDayToOffset as unknown as Date[]\r\n }\r\n const dayToOffset = this.getDayToOffset()\r\n const daysInQuote = Object.keys(dayToOffset)\r\n .map((dateString) => {\r\n const [year, month, day] = dateString.split('-')\r\n return new Date(Number.parseInt(year), Number.parseInt(month) - 1, Number.parseInt(day))\r\n })\r\n .sort((a, b) => a.getTime() - b.getTime())\r\n\r\n setCachedQuote({ cid: this.cid, key: 'daysInQuote', value: daysInQuote, fetchedAt: this.fetchedAt })\r\n return daysInQuote\r\n }\r\n\r\n getBarIndexes() {\r\n if (!this.isIntraday || this.instrument !== Instrument.Stock) {\r\n return Array.from({ length: this.date.length }).map((_, index) => index)\r\n }\r\n\r\n const barIndex = []\r\n const dayToOffset = this.getDayToOffset()\r\n\r\n for (let i = 0; i < this.date.length; i += 1) {\r\n const date = dateFromUnixTimestamp(this.date[i])\r\n let x = Math.ceil((date.getHours() * 60 + date.getMinutes() - this.marketStartMinutes) / this.interval)\r\n x += dayToOffset[dateStringFromDate(date)] * this.getBarsInDay()! // add days\r\n barIndex[i] = x\r\n }\r\n\r\n return barIndex\r\n }\r\n\r\n getBarIndex(i: number) {\r\n if (!this.isIntraday || this.instrument !== Instrument.Stock) {\r\n return i\r\n }\r\n return this.barIndex[i]\r\n }\r\n\r\n getBarsInDay() {\r\n if (!this.isIntraday || this.instrument !== Instrument.Stock) {\r\n return\r\n }\r\n return Math.ceil(this.drawMinutesPerDay / this.interval)\r\n }\r\n\r\n getDataIndexByBarIndex(index: number) {\r\n if (this.barIndex) {\r\n for (let i = 0; i < this.barIndex.length; i++) {\r\n if (this.barIndex[i] === index) {\r\n return i\r\n }\r\n }\r\n }\r\n return -1\r\n }\r\n\r\n getDataByBarIndex(key: keyof Quote, index: number) {\r\n const dataIndex = this.getDataIndexByBarIndex(index)\r\n if (dataIndex > -1) {\r\n const quoteData = this[key as keyof Quote]! as number[]\r\n return quoteData[dataIndex] ?? null\r\n }\r\n return null\r\n }\r\n\r\n getDateToIndex() {\r\n const cachedDateToIndex = getCachedQuote({ cid: this.cid, key: 'dateToIndex', fetchedAt: this.fetchedAt })\r\n if (cachedDateToIndex) {\r\n return cachedDateToIndex as unknown as ObjectHash\r\n }\r\n const dateToIndex: ObjectHash = {}\r\n for (let i = 0; i < this.date.length; i++) {\r\n dateToIndex[this.date[i]] = i\r\n }\r\n setCachedQuote({ cid: this.cid, key: 'dateToIndex', value: dateToIndex, fetchedAt: this.fetchedAt })\r\n return dateToIndex\r\n }\r\n\r\n getTimestampFomPositionX(positionX: number) {\r\n if (this.date.length === 0) {\r\n return 0\r\n }\r\n return getTimestampFromPositionX({\r\n positionX,\r\n quote: this,\r\n })\r\n }\r\n\r\n getPositionXFromTimestamp(timestamp: number) {\r\n if (this.date.length === 0) {\r\n return 0\r\n }\r\n return getPositionXFromTimestamp({\r\n timestamp,\r\n quote: this,\r\n })\r\n }\r\n\r\n getUrl(options: QuoteUrlOptions) {\r\n const config: UrlOptions = {\r\n ticker: this.ticker,\r\n instrument: this.instrument,\r\n timeframe: this.timeframe || 'd1',\r\n aftermarket: this.aftermarket,\r\n premarket: this.premarket,\r\n patterns: this.hasPatterns,\r\n maxBars: this.maxBars,\r\n ...options,\r\n }\r\n\r\n const isStock = config.instrument === Instrument.Stock\r\n const isBrowserElite = !getIsSSr() && document.location.host === 'elite.finviz.com'\r\n let domain = isBrowserElite && isStock ? 'https://api.finviz.com' : ''\r\n\r\n if (getIsSSr()) {\r\n domain = process.env.BE_API_URL!\r\n }\r\n\r\n return `${domain}/api/quote.ashx?${queryString.stringify({ rev: Date.now(), ...config })}`\r\n }\r\n\r\n getRawTicker() {\r\n return getRawTickerForInstrument(this.instrument, this.ticker)\r\n }\r\n\r\n clearData() {\r\n this.updateAttributes(emptyQuote)\r\n }\r\n}\r\n\r\nQuote.initClass()\r\n\r\nexport default Quote\r\n","export enum QuoteFetchType {\r\n Refetch = 'refetch',\r\n NewerData = 'newerData',\r\n}\r\n\r\nexport enum QuoteFetchTypeUrlOption {\r\n New = 'new',\r\n Newer = 'newer',\r\n}\r\n\r\nexport interface QuoteUrlOptions {\r\n type: QuoteFetchTypeUrlOption\r\n dataId?: string\r\n events?: boolean\r\n}\r\n","export const largeChartFontSize = {\r\n S: 8,\r\n M: 10,\r\n XXL: 16,\r\n XXXL: 24,\r\n}\r\n","import { Theme } from '../../../types/shared'\r\nimport {\r\n CHART_MARGIN,\r\n FONT_SIZE,\r\n LINE_HEIGHT,\r\n OFFSET,\r\n PADDING,\r\n SETTINGS_HEIGHT,\r\n TICKER_TIMEFRAME_CHANGE_HEIGHT,\r\n TextBaseline,\r\n} from '../../constants/common'\r\nimport {\r\n chartDarkTheme,\r\n chartLightTheme,\r\n elementDarkTheme,\r\n elementLightTheme,\r\n generalColors,\r\n indicatorDarkTheme,\r\n indicatorLightTheme,\r\n} from '../constants'\r\nimport { ISettings } from './interfaces'\r\n\r\nexport const INTERACTIVE_CHART_SETTINGS = (theme: Theme): ISettings => ({\r\n ChartSettings: {\r\n general: {\r\n Colors: {\r\n ...(theme === Theme.light ? chartLightTheme : chartDarkTheme),\r\n [Theme.light]: chartLightTheme,\r\n [Theme.dark]: chartDarkTheme,\r\n },\r\n settingsHeight: SETTINGS_HEIGHT,\r\n tickerTimeframeChangeHeight: TICKER_TIMEFRAME_CHANGE_HEIGHT,\r\n },\r\n center: {\r\n barWidth: 3,\r\n barMargin: 1,\r\n border: 1,\r\n },\r\n top: {\r\n height: CHART_MARGIN.XL,\r\n baseline: TextBaseline.alphabetic,\r\n ticker: {\r\n margin: {\r\n top: 30,\r\n left: 0,\r\n },\r\n font: {\r\n size: FONT_SIZE.XXXL,\r\n style: 'bold',\r\n },\r\n },\r\n ohlc: {\r\n margin: {\r\n top: 30,\r\n left: 30,\r\n right: 30,\r\n },\r\n font: {\r\n size: FONT_SIZE.S,\r\n },\r\n },\r\n change: {\r\n margin: {\r\n top: 30,\r\n right: 0,\r\n },\r\n font: {\r\n size: FONT_SIZE.M,\r\n style: 'bold',\r\n },\r\n },\r\n },\r\n right: {\r\n width: CHART_MARGIN.XXL,\r\n axis: {\r\n margin: {\r\n left: 0,\r\n },\r\n font: {\r\n size: FONT_SIZE.S,\r\n lineHeight: LINE_HEIGHT.S,\r\n padding: {\r\n top: PADDING.XXS,\r\n bottom: PADDING.XXS,\r\n left: PADDING.XXS,\r\n right: PADDING.XXS,\r\n },\r\n },\r\n },\r\n },\r\n bottom: {\r\n height: CHART_MARGIN.M,\r\n baseline: TextBaseline.top,\r\n axis: {\r\n margin: {\r\n top: 8,\r\n },\r\n font: {\r\n size: FONT_SIZE.S,\r\n },\r\n },\r\n },\r\n left: {\r\n width: CHART_MARGIN.L,\r\n overlayLabel: {\r\n labelSpacing: 12,\r\n margin: {\r\n top: -8,\r\n left: 6,\r\n },\r\n font: {\r\n size: FONT_SIZE.S,\r\n weight: 'bold',\r\n },\r\n },\r\n timeframe: {\r\n margin: {\r\n top: 0,\r\n left: 28,\r\n },\r\n font: {\r\n size: FONT_SIZE.M,\r\n weight: '900',\r\n family: 'Lato, sans-serif',\r\n },\r\n },\r\n volumeAxis: {\r\n margin: {\r\n left: 33,\r\n },\r\n font: {\r\n size: FONT_SIZE.S,\r\n },\r\n },\r\n },\r\n },\r\n IndicatorSettings: {\r\n general: {\r\n height: 140,\r\n Colors: theme === Theme.light ? indicatorLightTheme : indicatorDarkTheme,\r\n },\r\n center: {\r\n barWidth: 3,\r\n barMargin: 2,\r\n border: 1,\r\n },\r\n top: {\r\n height: CHART_MARGIN.S,\r\n },\r\n right: {\r\n width: CHART_MARGIN.XXL,\r\n axis: {\r\n margin: {\r\n left: 0,\r\n },\r\n font: {\r\n size: FONT_SIZE.S,\r\n lineHeight: LINE_HEIGHT.S,\r\n padding: {\r\n top: PADDING.XXS,\r\n bottom: PADDING.XXS,\r\n left: PADDING.XXS,\r\n right: PADDING.XXS,\r\n },\r\n },\r\n },\r\n },\r\n bottom: {\r\n height: CHART_MARGIN.S,\r\n },\r\n left: {\r\n width: CHART_MARGIN.L,\r\n indicatorLabel: {\r\n labelSpacing: 4,\r\n margin: {\r\n top: OFFSET.S,\r\n left: OFFSET.M,\r\n },\r\n font: {\r\n size: FONT_SIZE.M,\r\n style: 'bold',\r\n lineHeight: LINE_HEIGHT.M,\r\n },\r\n },\r\n },\r\n },\r\n MarketSentimentSettings: {\r\n general: {\r\n Colors: theme === Theme.light ? chartLightTheme : chartDarkTheme,\r\n },\r\n center: {\r\n barWidth: 3,\r\n barMargin: 1,\r\n border: 1,\r\n },\r\n top: {\r\n height: 0,\r\n },\r\n bottom: {\r\n height: 12,\r\n },\r\n left: {\r\n width: 0,\r\n },\r\n right: {\r\n width: 30,\r\n },\r\n },\r\n ColorsSettings: generalColors,\r\n ThumbSettings: {\r\n size: 8,\r\n touchSize: 16,\r\n color: '#ddd',\r\n borderWidth: 1,\r\n borderColor: '#999',\r\n },\r\n ElementSettings: {\r\n Colors: theme === Theme.light ? elementLightTheme : elementDarkTheme,\r\n defaultFill: '#1e6dc066',\r\n defaultTransparentFill: '#1e6dc000',\r\n },\r\n})\r\n","import merge from 'lodash.merge'\r\n\r\nimport { ChartConfigChart } from '../../server/chartConfig'\r\nimport { Instrument, ObjectHash, Theme } from '../../types/shared'\r\nimport { SpecificChartFunctionality } from '../constants/common'\r\nimport Utils, { isRedesignedPage } from '../utils'\r\nimport LayoutModel from './chart_layout'\r\nimport { getColorOverwrites } from './chart_settings'\r\nimport { largeChartFontSize } from './chart_settings/constants'\r\nimport { INTERACTIVE_CHART_SETTINGS } from './chart_settings/interactive_chart_settings'\r\nimport { ISettings } from './chart_settings/interfaces'\r\nimport {\r\n IChartThemeColors,\r\n chartDarkTheme,\r\n chartLightTheme,\r\n elementDarkTheme,\r\n elementLightTheme,\r\n indicatorDarkTheme,\r\n indicatorLightTheme,\r\n} from './constants'\r\n\r\ninterface Config {\r\n theme: Theme\r\n barMargin?: number\r\n barWidth?: number\r\n border?: number\r\n charts?: ChartConfigChart[]\r\n colorsOverride?: Array\r\n volumeHeight?: number\r\n colors?: ObjectHash, Theme>\r\n specificChartFunctionality?: SpecificChartFunctionality\r\n isOurSiteRequest?: boolean\r\n}\r\n\r\nexport function getSettings(config: Config, chartSettings?: ISettings): ISettings {\r\n const settings = merge({}, chartSettings ?? INTERACTIVE_CHART_SETTINGS(config.theme))\r\n\r\n if (config.barWidth != null) {\r\n settings.ChartSettings.center.barWidth = config.barWidth\r\n settings.IndicatorSettings.center.barWidth = config.barWidth\r\n }\r\n if (config.barMargin != null) {\r\n settings.ChartSettings.center.barMargin = config.barMargin\r\n settings.IndicatorSettings.center.barMargin = config.barMargin\r\n }\r\n if (config.border != null) {\r\n settings.ChartSettings.center.border = config.border\r\n settings.IndicatorSettings.center.border = config.border\r\n }\r\n if (config.colorsOverride) {\r\n settings.ColorsSettings = config.colorsOverride\r\n }\r\n if (config.volumeHeight) {\r\n settings.ChartSettings.center.volumeHeight = config.volumeHeight\r\n }\r\n if (config.colors) {\r\n const settingColors = settings.ChartSettings.general.Colors\r\n settings.ChartSettings.general.Colors = {\r\n ...settingColors,\r\n [Theme.light]: {\r\n ...settingColors[Theme.light],\r\n ...getColorOverwrites({ theme: Theme.light, colors: config.colors }),\r\n },\r\n [Theme.dark]: {\r\n ...settingColors[Theme.dark],\r\n ...getColorOverwrites({ theme: Theme.dark, colors: config.colors }),\r\n },\r\n }\r\n }\r\n if (config.specificChartFunctionality === SpecificChartFunctionality.chartPage && Utils.isMobile()) {\r\n settings.ChartSettings.left.width = 0\r\n settings.ChartSettings.top.ticker.margin.left = settings.ChartSettings.left.overlayLabel.margin.left\r\n settings.IndicatorSettings.left.width = 0\r\n }\r\n if (SpecificChartFunctionality.chartPage === config.specificChartFunctionality || isRedesignedPage(config)) {\r\n settings.ChartSettings.top.height = 10\r\n }\r\n\r\n if (config.specificChartFunctionality === SpecificChartFunctionality.offScreen) {\r\n const isGroupInstrument = config.charts?.some(({ instrument }) => instrument === Instrument.Group)\r\n if (isGroupInstrument) {\r\n settings.ChartSettings.top.ohlc.margin.top = 4\r\n settings.ChartSettings.top.ticker.margin.top = 0\r\n settings.ChartSettings.top.ticker.font = {\r\n size: largeChartFontSize.XXL,\r\n style: 'bold',\r\n }\r\n settings.ChartSettings.left.timeframe.margin.top = 12\r\n settings.ChartSettings.left.timeframe.font = {\r\n size: largeChartFontSize.S,\r\n style: 'bold',\r\n }\r\n }\r\n }\r\n\r\n if (config.isOurSiteRequest !== undefined) {\r\n settings.isOurSiteRequest = config.isOurSiteRequest\r\n }\r\n\r\n return settings\r\n}\r\n\r\nexport function updateSettings(chart_layout: LayoutModel, theme: string): ISettings {\r\n const settings = merge({}, chart_layout.settings)\r\n const isLight = theme === Theme.light\r\n settings.MarketSentimentSettings.general.Colors = isLight ? { ...chartLightTheme } : { ...chartDarkTheme }\r\n settings.IndicatorSettings.general.Colors = isLight ? { ...indicatorLightTheme } : { ...indicatorDarkTheme }\r\n settings.ElementSettings.Colors = isLight ? { ...elementLightTheme } : { ...elementDarkTheme }\r\n\r\n return settings\r\n}\r\n\r\nexport function getChartLayoutSettings(chart_layout: LayoutModel): ISettings {\r\n const settings = chart_layout.settings\r\n\r\n return {\r\n ...settings,\r\n ChartSettings: {\r\n ...settings.ChartSettings,\r\n general: {\r\n ...settings.ChartSettings.general,\r\n Colors: {\r\n ...settings.ChartSettings.general.Colors,\r\n ...settings.ChartSettings.general.Colors[chart_layout.theme],\r\n },\r\n },\r\n },\r\n }\r\n}\r\n","import { Instrument } from '../../types/shared'\r\nimport ChartLayoutModel from './chart_layout'\r\nimport Element from './element'\r\n\r\nexport const handleRemoveIndicatorPane = ({\r\n paneIndex,\r\n chartLayoutModel,\r\n}: {\r\n paneIndex: number\r\n chartLayoutModel: ChartLayoutModel\r\n}) => {\r\n const charts = chartLayoutModel.getAllCharts()\r\n charts.forEach((chart) => chart.getAllPanes()[paneIndex].destroyCascade())\r\n}\r\n\r\nexport function getNormalizedZIndex({ index, isBelowZero }: { index: number; isBelowZero: boolean }) {\r\n return (index + 1) * (isBelowZero ? -1 : 1)\r\n}\r\n\r\nexport function rebuildElementZIndexes({\r\n elementsArray,\r\n isBelowZero,\r\n}: {\r\n elementsArray: Element[]\r\n isBelowZero: boolean\r\n}) {\r\n const elements = isBelowZero ? [...elementsArray].reverse() : elementsArray\r\n elements.forEach((element, index) => {\r\n const newZIndex = getNormalizedZIndex({ index, isBelowZero })\r\n if (newZIndex !== element.zIndex) {\r\n element.updateAttributes({ zIndex: newZIndex })\r\n }\r\n })\r\n}\r\n\r\nexport function changeElementZIndexes({\r\n elementsArray,\r\n addElement,\r\n oldZIndex,\r\n newZIndex,\r\n isBelowZero = false,\r\n}: {\r\n elementsArray: Element[]\r\n addElement: Element | undefined\r\n oldZIndex: number\r\n newZIndex: number\r\n isBelowZero?: boolean\r\n}) {\r\n const array = isBelowZero ? [...elementsArray].reverse() : elementsArray\r\n const elements =\r\n elementsArray.length === 0 && addElement\r\n ? [...array, addElement]\r\n : array\r\n .filter((_, index) => getNormalizedZIndex({ index, isBelowZero }) !== oldZIndex)\r\n .flatMap((el, index) =>\r\n getNormalizedZIndex({ index, isBelowZero }) === newZIndex && addElement ? [addElement, el] : el\r\n )\r\n\r\n // If there are only 2 drawings and we move a drawing from index 1 to index 2 to have to push it to the array because it's the last element and it didn't get into the array in the flatMap above\r\n if (elements.length < Math.abs(newZIndex) && addElement) {\r\n elements.push(addElement)\r\n }\r\n\r\n rebuildElementZIndexes({ elementsArray: isBelowZero ? [...elements].reverse() : elements, isBelowZero })\r\n}\r\n\r\nexport function getRawTickerForInstrument(instrument: Instrument, ticker: string) {\r\n return `${\r\n [Instrument.Crypto, Instrument.Forex, Instrument.Futures].includes(instrument) && !ticker.includes('@') ? '@' : ''\r\n }${ticker}`\r\n}\r\n","import { OverlayType } from '../constants/common'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype Options = {\r\n period: number\r\n deviations: number\r\n}\r\n\r\ntype DefaultCalculatedValuesType = {\r\n sma: number[]\r\n stdDev: number[]\r\n upperBand: number[]\r\n lowerBand: number[]\r\n}\r\n\r\nexport class BbCalculation extends MainCalculation {\r\n static type = OverlayType.Bb\r\n\r\n getDefaultCalculatedValues() {\r\n return {\r\n sma: [],\r\n stdDev: [],\r\n upperBand: [],\r\n lowerBand: [],\r\n }\r\n }\r\n\r\n calculate(onValueCalculated?: OnValueCalculated) {\r\n const { period, deviations } = this.options\r\n const { close } = this.quote\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n let sum = 0\r\n for (let i = 0; i < period; i++) {\r\n sum += close[i]\r\n }\r\n for (let i = period; i < close.length; i++) {\r\n sum = sum - close[i - period] + close[i]\r\n this.calculatedValues.sma[i] = sum / period\r\n\r\n let stdDevSum = 0\r\n for (let j = i - period + 1; j <= i; j++) {\r\n stdDevSum += Math.pow(close[j] - this.calculatedValues.sma[i], 2)\r\n }\r\n this.calculatedValues.stdDev[i] = Math.sqrt(stdDevSum / period)\r\n\r\n this.calculatedValues.upperBand[i] = this.calculatedValues.sma[i] + this.calculatedValues.stdDev[i] * deviations\r\n this.calculatedValues.lowerBand[i] = this.calculatedValues.sma[i] - this.calculatedValues.stdDev[i] * deviations\r\n\r\n if (onValueCalculated?.(this.calculatedValues, i) === false) {\r\n break\r\n }\r\n }\r\n }\r\n}\r\n","import {\r\n ChartConfigChartPaneElement,\r\n IModalConfig,\r\n IModalConfigInput,\r\n ObjectHash,\r\n RequireByKey,\r\n} from '../../types/shared'\r\nimport Element from '../canvas/element'\r\nimport BaseChart from '../charts/base_chart'\r\nimport { OverlayType } from '../constants/common'\r\nimport Quote from '../models/quote'\r\nimport { convertColorToHEX, getRGBAValueFromValidColorString } from '../utils/colors'\r\nimport { getParsedIntegersFromPeriodString, isInRange, isPositiveInteger } from '../utils/helpers'\r\n\r\nexport interface IOverlayIsValid {\r\n getIsValid(key: string): boolean | void\r\n}\r\n\r\nconst DEFAULT_LABEL_COLOR = '#0587cd'\r\n\r\nclass Overlay extends Element implements IOverlayIsValid {\r\n static type = OverlayType.Overlay\r\n static label = 'Overlay'\r\n\r\n static getNumOfBarsBuffer({ period }: RequireByKey) {\r\n const [periodInt] = getParsedIntegersFromPeriodString(period)\r\n return periodInt\r\n }\r\n\r\n declare data: Quote\r\n declare chart: BaseChart\r\n\r\n get type() {\r\n return (this.constructor as typeof Overlay).type\r\n }\r\n\r\n get label() {\r\n return (this.constructor as typeof Overlay).label\r\n }\r\n\r\n getLabelColor() {\r\n return this.attrs.color ? convertColorToHEX(this.attrs.color) : DEFAULT_LABEL_COLOR\r\n }\r\n\r\n getFreeColor() {\r\n return this.getChartLayoutSettings().ColorsSettings[0]\r\n // TODO proper implementation - example how this could be done:\r\n // let colorsUsed = []\r\n // for (let overlay of this.chart.overlays) {\r\n // let object = overlay.getModalConfig().inputs\r\n // for (let _ in object) {\r\n // let input = object[_]\r\n // if (input.type === 'color') {\r\n // colorsUsed.push(input.value)\r\n // }\r\n // }\r\n // }\r\n // for (let color of colors) {\r\n // if (!colorsUsed.includes(color)) {\r\n // return color\r\n // }\r\n // }\r\n // return colors[0]\r\n }\r\n\r\n renderContent(_?: RenderingContext2DType) {\r\n this.data = this.model.chart().quote()\r\n }\r\n\r\n fx = (x: number) => this.model.scale.x(this.data.barIndex[x])\r\n\r\n getIsValid(_: string): boolean | undefined {\r\n throw Error('Implement')\r\n }\r\n\r\n getIsNumberInputValid({ key, integerOnly = true }: { key: string; integerOnly?: boolean }): boolean {\r\n const input = this.getModalConfig().inputs.find(({ name }: { name: string }) => key === name)\r\n return !!input && isInRange(input) && (!integerOnly || isPositiveInteger(input.value))\r\n }\r\n\r\n isRendered() {\r\n return true\r\n }\r\n\r\n isRenderedOverlaysLabel() {\r\n return this.isRendered()\r\n }\r\n\r\n getModalConfig(): IModalConfig {\r\n return {\r\n title: '',\r\n inputs: [],\r\n inputsErrorMessages: {},\r\n }\r\n }\r\n\r\n toConfig() {\r\n const colors: string[] = []\r\n const periods: string[] = []\r\n\r\n this.getModalConfig().inputs.forEach((input: IModalConfigInput) => {\r\n if (input.type === 'color') {\r\n colors.push(getRGBAValueFromValidColorString(input.value.toString()))\r\n } else {\r\n periods.push(input.value.toString())\r\n }\r\n })\r\n\r\n return { type: this.type, period: periods.join(','), color: colors.join('|') }\r\n }\r\n}\r\n\r\nexport default Overlay\r\n","import { ChartConfigChartPaneElement, RequireByKey, Theme } from '../../types/shared'\r\nimport { OverlayType } from '../constants/common'\r\nimport { BbCalculation } from '../indicator-calculation/bb'\r\nimport { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport Overlay from './overlay'\r\n\r\nconst BB_COLORS = {\r\n [Theme.light]: {\r\n TOP: '#D386DF',\r\n BOTTOM: '#69C1EA',\r\n MIDDLE: '#CFD2F2',\r\n },\r\n [Theme.dark]: {\r\n TOP: '#D38BFB',\r\n BOTTOM: '#57AEFB',\r\n MIDDLE: '#E1B6FC',\r\n },\r\n}\r\n\r\nconst DEFAULT_PARAMETERS = {\r\n Period: 20,\r\n Deviations: 2.0,\r\n}\r\n\r\ninterface Attrs {\r\n period: number | string\r\n deviations: number\r\n topColor?: string\r\n bottomColor?: string\r\n}\r\n\r\nfunction parsePeriod(periodStr: string) {\r\n const values = periodStr.split(',')\r\n const period = parseInt(values[0]) || DEFAULT_PARAMETERS.Period\r\n const deviations = parseFloat(values[1]) || DEFAULT_PARAMETERS.Deviations\r\n\r\n return [period, deviations]\r\n}\r\n\r\nclass BollingerBands extends Overlay {\r\n static type = OverlayType.Bb\r\n static label = 'Bollinger Bands'\r\n\r\n static getNumOfBarsBuffer({ period }: RequireByKey) {\r\n const [periodInt = 0] = getParsedIntegersFromPeriodString(period)\r\n return periodInt + 1 // +1 offsets rendering so it doesn't start on first bar which doesn't look OK in SSR rendered charts\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n const { period } = obj\r\n if (typeof period === 'string') {\r\n const [periodInt, deviations] = parsePeriod(period)\r\n this.attrs.period = periodInt\r\n this.attrs.deviations = deviations\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n if (typeof this.attrs.period !== 'number') {\r\n return\r\n }\r\n super.renderContent()\r\n const { Colors } = this.getChartLayoutSettings().ChartSettings.general\r\n const theme = this.model.chart().chart_layout().theme as Theme\r\n const { leftOffset, width } = this.model.chart()\r\n const [top, bottom] = this.model.scale.y.domain()\r\n const scaledTop = this.fy(top)\r\n const scaledBottom = this.fy(bottom)\r\n const { close } = this.data\r\n const period = Math.min(this.attrs.period, close.length - 1)\r\n\r\n let firstBarToRender: number | undefined\r\n let lastBarToRender = 0\r\n\r\n // middle line && find first & last bar to render\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', BB_COLORS[theme].MIDDLE)\r\n\r\n const bbCalculation = new BbCalculation({\r\n quote: this.data,\r\n options: {\r\n period,\r\n deviations: this.attrs.deviations,\r\n },\r\n })\r\n\r\n bbCalculation.calculate(({ sma }, dataIndex) => {\r\n if (this.fx(dataIndex + 1) + leftOffset < 0) {\r\n return\r\n }\r\n if (firstBarToRender === undefined) firstBarToRender = dataIndex\r\n\r\n context.lineTo(this.fx(dataIndex), Math.round(this.fy(sma[dataIndex])))\r\n\r\n if (this.fx(dataIndex - 1) + leftOffset > width) {\r\n return false\r\n }\r\n lastBarToRender = dataIndex\r\n })\r\n\r\n if (firstBarToRender === undefined) return\r\n context.stroke()\r\n context.set('fillStyle', Colors.overlayTransparentBackground)\r\n\r\n // top line\r\n context.beginPath()\r\n context.moveTo(this.fx(firstBarToRender), scaledTop)\r\n context.set('strokeStyle', BB_COLORS[theme].TOP)\r\n for (let i = firstBarToRender; i <= lastBarToRender; i++) {\r\n context.lineTo(this.fx(i), Math.round(this.fy(bbCalculation.calculatedValues.upperBand[i])))\r\n }\r\n context.stroke()\r\n context.lineTo(this.fx(lastBarToRender), scaledTop)\r\n context.fill()\r\n\r\n // bottom line\r\n context.beginPath()\r\n context.moveTo(this.fx(firstBarToRender), scaledBottom)\r\n context.set('strokeStyle', BB_COLORS[theme].BOTTOM)\r\n for (let i = firstBarToRender; i <= lastBarToRender; i++) {\r\n context.lineTo(this.fx(i), Math.round(this.fy(bbCalculation.calculatedValues.lowerBand[i])))\r\n }\r\n context.stroke()\r\n context.lineTo(this.fx(lastBarToRender), scaledBottom)\r\n context.fill()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.attrs.period ?? DEFAULT_PARAMETERS.Period,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n const deviations = {\r\n type: 'number',\r\n label: 'Deviations',\r\n name: 'deviations',\r\n value: this.attrs.deviations ?? DEFAULT_PARAMETERS.Deviations,\r\n required: true,\r\n min: 0.1,\r\n max: 999,\r\n step: 0.1,\r\n }\r\n const topColor = {\r\n type: 'color',\r\n label: 'Top Color',\r\n name: 'topColor',\r\n value: this.attrs.topColor ?? this.getFreeColor(),\r\n }\r\n const bottomColor = {\r\n type: 'color',\r\n label: 'Bottom Color',\r\n name: 'bottomColor',\r\n value: this.attrs.bottomColor ?? this.getFreeColor(),\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period, deviations, topColor, bottomColor],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n deviations: `${deviations.label} must be a number between ${deviations.min} and ${deviations.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n case 'deviations':\r\n return this.getIsNumberInputValid({ key, integerOnly: false })\r\n case 'topColor':\r\n case 'bottomColor':\r\n // Some users have wrong colors which break the form validation\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n getLabelColor() {\r\n const theme = this.model.chart().chart_layout().theme as Theme\r\n return this.attrs.topColor || BB_COLORS[theme].TOP\r\n }\r\n\r\n toString() {\r\n return `BB ${this.attrs.period},${this.attrs.deviations}`\r\n }\r\n}\r\n\r\nBollingerBands.prototype.defaults = { topColor: '#69c1ea', bottomColor: '#d386df' }\r\n\r\nexport default BollingerBands\r\n","import { OverlayType } from '../constants/common'\r\nimport utils from '../utils'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Overlay from './overlay'\r\n\r\ninterface Attrs {\r\n period: number\r\n channelStrokeColor: string\r\n channelFillColor: string\r\n medianBandColor: string\r\n}\r\n\r\nconst DEFAULT_PERIOD = 20\r\n\r\nconst COLORS = {\r\n ChannelStroke: '#69c1ea',\r\n ChannelFill: '#69C1EA12',\r\n MedianBandStroke: '#ffa75f',\r\n}\r\n\r\nclass DonchianChannels extends Overlay {\r\n static type = OverlayType.Dch\r\n static label = 'Donchian Channels'\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n const { period } = obj\r\n if (typeof period === 'string') {\r\n this.attrs.period = parseInt(period, 10)\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const { leftOffset, width } = this.model.chart()\r\n const { period } = this.attrs\r\n const upperBand: number[] = []\r\n const lowerBand: number[] = []\r\n const medianBand: number[] = []\r\n let firstBarToRender = -1\r\n let lastBarToRender = 0\r\n if (this.data.close.length === undefined) {\r\n return\r\n }\r\n\r\n context.save()\r\n context.translate(0.5, 0.5)\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', COLORS.ChannelStroke)\r\n context.set('fillStyle', COLORS.ChannelFill)\r\n\r\n //upper band + clip\r\n context.beginPath()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset,\r\n width,\r\n drawBarCallback: (i, x) => {\r\n firstBarToRender = firstBarToRender === -1 ? i : firstBarToRender\r\n upperBand[i] = utils.max(this.data.high.slice(Math.max(0, i - period), i + 1))\r\n lowerBand[i] = utils.min(this.data.low.slice(Math.max(0, i - period), i + 1))\r\n medianBand[i] = (upperBand[i] + lowerBand[i]) / 2\r\n\r\n context.lineTo(x, Math.round(this.fy(upperBand[i])))\r\n lastBarToRender = i\r\n },\r\n })\r\n context.stroke()\r\n context.lineTo(this.fx(lastBarToRender), context.canvas.height)\r\n context.lineTo(this.fx(firstBarToRender), context.canvas.height)\r\n context.clip()\r\n\r\n // lower band + fill\r\n context.beginPath()\r\n for (let i = firstBarToRender; i <= lastBarToRender; i++) {\r\n const x = this.fx(i)\r\n context.lineTo(x, Math.round(this.fy(lowerBand[i])))\r\n }\r\n context.stroke()\r\n context.lineTo(this.fx(lastBarToRender), 0)\r\n context.lineTo(0, 0)\r\n context.fill()\r\n\r\n // median band\r\n context.set('strokeStyle', COLORS.MedianBandStroke)\r\n context.beginPath()\r\n for (let i = firstBarToRender; i <= lastBarToRender; i++) {\r\n const x = this.fx(i)\r\n context.lineTo(x, Math.round(this.fy(medianBand[i])))\r\n }\r\n context.stroke()\r\n context.restore()\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.attrs.period ?? DEFAULT_PERIOD,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n const strokeColor = {\r\n type: 'color',\r\n label: 'Channels Stroke Color',\r\n name: 'strokeColor',\r\n value: this.attrs.channelStrokeColor ?? this.getFreeColor(),\r\n }\r\n const fillColor = {\r\n type: 'color',\r\n label: 'Channels Fill Color',\r\n name: 'fillColor',\r\n value: this.attrs.channelFillColor ?? this.getFreeColor(),\r\n }\r\n const medianBandColor = {\r\n type: 'color',\r\n label: 'Median Band Color',\r\n name: 'medianBandColor',\r\n value: this.attrs.medianBandColor ?? this.getFreeColor(),\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period, medianBandColor, strokeColor, fillColor],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n case 'medianBandColor':\r\n case 'strokeColor':\r\n case 'fillColor':\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n getLabelColor() {\r\n return this.attrs.medianBandColor\r\n }\r\n\r\n toString() {\r\n return `Donchian ${this.attrs.period}`\r\n }\r\n}\r\n\r\nDonchianChannels.prototype.defaults = {\r\n medianBandColor: COLORS.MedianBandStroke,\r\n channelStrokeColor: COLORS.ChannelStroke,\r\n channelFillColor: COLORS.ChannelFill,\r\n}\r\n\r\nexport default DonchianChannels\r\n","import { OverlayType } from '../constants/common'\r\nimport { EMACalculation } from '../indicator-calculation/ema'\r\nimport Overlay from './overlay'\r\n\r\ninterface Attrs {\r\n period: number\r\n deviations: number\r\n color: string\r\n}\r\n\r\nclass EMA extends Overlay {\r\n static type = OverlayType.Ema\r\n static label = 'Exponential Moving Average'\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n const { period } = obj\r\n if (typeof period === 'string') {\r\n this.attrs.period = parseInt(period, 10)\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const { leftOffset, width } = this.model.chart()\r\n\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', this.attrs.color)\r\n const emaCalculation = new EMACalculation({\r\n quote: this.data,\r\n options: {\r\n period: this.attrs.period,\r\n },\r\n })\r\n emaCalculation.calculate(({ ema }, dataIndex) => {\r\n const x = this.fx(dataIndex)\r\n if (this.fx(dataIndex + 1) + leftOffset < 0) {\r\n return\r\n }\r\n if (this.fx(dataIndex - 1) + leftOffset > width) {\r\n return false\r\n }\r\n context.lineTo(x, Math.round(this.fy(ema[dataIndex])))\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.attrs.period ?? 5,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n const color = {\r\n type: 'color',\r\n label: 'Color',\r\n name: 'color',\r\n value: this.attrs.color ?? this.getFreeColor(),\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period, color],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n case 'color':\r\n return !!this.attrs[key] // use real color validation, we got isValidHexColor but it might be also RGBA\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `EMA ${this.attrs.period}`\r\n }\r\n}\r\n\r\nEMA.prototype.defaults = { color: '#ffa75f' }\r\n\r\nexport default EMA\r\n","import { OverlayType } from '../constants/common'\r\nimport EMA from './ema'\r\n\r\nclass EMA2 extends EMA {\r\n static type = OverlayType.Ema2\r\n}\r\n\r\nEMA2.prototype.defaults = { color: '#ff6400' }\r\n\r\nexport default EMA2\r\n","import { OverlayType } from '../constants/common'\r\nimport PaneModel from '../models/pane'\r\nimport { getBarWidthWithMargin } from '../utils/chart'\r\nimport Overlay from './overlay'\r\n\r\ninterface Attrs {\r\n period: number\r\n lowColor: string\r\n highColor: string\r\n}\r\n\r\nclass HighLow extends Overlay {\r\n static type = OverlayType.Hilo\r\n static label = 'High/Low'\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.renderContent = this.renderContent.bind(this)\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n const { period } = obj\r\n if (typeof period === 'string') {\r\n this.attrs.period = parseInt(period, 10)\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const chartModel = this.model.chart()\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const { leftOffset, width, zoomFactor } = chartModel\r\n const barWidth = getBarWidthWithMargin({\r\n zoomFactor,\r\n chartLayout: chartModel.chart_layout(),\r\n })\r\n const halfWidth = barWidth / 2\r\n const period = Math.min(this.attrs.period, this.data.close.length - 1)\r\n let firstBarToRender\r\n let lastBarToRender = 0\r\n context.translate(0.5, 0.5)\r\n context.set('fillStyle', Colors.overlayTransparentBackground)\r\n context.beginPath()\r\n context.set('strokeStyle', this.attrs.highColor)\r\n let prevHigh = -1\r\n for (let i = 0; i < this.data.close.length; i++) {\r\n let highestHigh = this.data.high[i]\r\n for (let j = i - period + 1; j <= i; j++) {\r\n if (this.data.high[j] > highestHigh) {\r\n highestHigh = this.data.high[j]\r\n }\r\n }\r\n\r\n const x = this.fx(i)\r\n if (this.fx(i + 1) + leftOffset < -10) {\r\n prevHigh = highestHigh\r\n continue\r\n }\r\n if (firstBarToRender === undefined) firstBarToRender = i\r\n if (this.fx(i - 1) + leftOffset > width) {\r\n break\r\n }\r\n\r\n const diff = this.data.barIndex[i] - this.data.barIndex[lastBarToRender]\r\n if (diff > 1 && prevHigh !== highestHigh && prevHigh > 0) {\r\n context.lineTo(Math.round(x - halfWidth), Math.round(this.fy(prevHigh)))\r\n }\r\n context.lineTo(Math.round(x - halfWidth), Math.round(this.fy(highestHigh)))\r\n context.lineTo(Math.round(x + halfWidth), Math.round(this.fy(highestHigh)))\r\n\r\n prevHigh = highestHigh\r\n lastBarToRender = i\r\n }\r\n context.stroke()\r\n if (firstBarToRender === undefined) return\r\n\r\n // return to start and fill with background color\r\n context.lineTo(this.fx(lastBarToRender) + halfWidth, 0)\r\n context.lineTo(this.fx(firstBarToRender) - halfWidth, 0)\r\n context.fill()\r\n\r\n context.beginPath()\r\n context.set('strokeStyle', this.attrs.lowColor)\r\n let prevLow = -1\r\n let prevBar = firstBarToRender\r\n for (let i = firstBarToRender; i <= lastBarToRender; i++) {\r\n let lowestLow = this.data.low[i]\r\n for (let j = i - period + 1; j <= i; j++) {\r\n if (this.data.low[j] < lowestLow) {\r\n lowestLow = this.data.low[j]\r\n }\r\n }\r\n\r\n const x = this.fx(i)\r\n const diff = this.data.barIndex[i] - this.data.barIndex[prevBar]\r\n if (diff > 1 && prevLow !== lowestLow && prevLow > 0) {\r\n context.lineTo(Math.round(x - halfWidth), Math.round(this.fy(prevLow)))\r\n }\r\n context.lineTo(Math.round(x - halfWidth), Math.round(this.fy(lowestLow)))\r\n context.lineTo(Math.round(x + halfWidth), Math.round(this.fy(lowestLow)))\r\n\r\n prevLow = lowestLow\r\n prevBar = i\r\n }\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n\r\n // return to start and fill with background color\r\n context.lineTo(this.fx(lastBarToRender), context.canvas.height)\r\n context.lineTo(this.fx(firstBarToRender) - halfWidth, context.canvas.height)\r\n context.fill()\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.attrs.period ?? 50,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n const highColor = {\r\n type: 'color',\r\n label: 'High Color',\r\n name: 'highColor',\r\n value: this.attrs.highColor ?? this.getFreeColor(),\r\n }\r\n const lowColor = {\r\n type: 'color',\r\n label: 'Low Color',\r\n name: 'lowColor',\r\n value: this.attrs.lowColor ?? this.getFreeColor(),\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period, highColor, lowColor],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n case 'highColor':\r\n case 'lowColor':\r\n // Some users have wrong colors which break the form validation\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n getLabelColor() {\r\n return this.attrs.highColor\r\n }\r\n\r\n toString() {\r\n return `HILO ${this.attrs.period}`\r\n }\r\n}\r\n\r\nHighLow.prototype.defaults = {\r\n lowColor: '#69c1ea',\r\n highColor: '#d386df',\r\n}\r\n\r\nexport default HighLow\r\n","import { OverlayType } from '../constants/common'\r\nimport { isPositiveFloat } from '../utils/helpers'\r\nimport Overlay from './overlay'\r\n\r\ninterface Attrs {\r\n period: number\r\n price: number\r\n color: string\r\n}\r\n\r\nclass HorizontalLine extends Overlay {\r\n static type = OverlayType.Hline\r\n static label = 'Horizontal Line'\r\n\r\n static getNumOfBarsBuffer() {\r\n return 0\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n if (typeof this.attrs.period === 'string' && this.attrs.price === undefined) {\r\n this.attrs.price = parseFloat(this.attrs.period)\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const y = Math.round(this.fy(this.attrs.price))\r\n context.set('strokeStyle', this.attrs.color)\r\n context.translate(0, 0.5)\r\n context.beginPath()\r\n context.moveTo(-this.model.chart().leftOffset, y)\r\n context.lineTo(-this.model.chart().leftOffset + this.model.chart().width, y)\r\n context.stroke()\r\n context.translate(0, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const price = {\r\n type: 'number',\r\n label: 'Price',\r\n name: 'price',\r\n value: this.attrs.price || this.model?.scale?.y?.domain().reduce((a: number, b: number) => a + b, 0) / 2,\r\n required: true,\r\n step: 0.1,\r\n }\r\n const color = {\r\n type: 'color',\r\n label: 'Color',\r\n name: 'color',\r\n value: this.attrs.color ?? this.getFreeColor(),\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [price, color],\r\n inputsErrorMessages: {\r\n price: `${price.label} must be number`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'price':\r\n return isPositiveFloat(this.attrs[key])\r\n case 'color':\r\n return !!this.attrs[key] // use real color validation, we got isValidHexColor but it might be also RGBA\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `HL ${this.attrs.price}`\r\n }\r\n}\r\n\r\nHorizontalLine.prototype.defaults = { color: '#0587cd' }\r\n\r\nexport default HorizontalLine\r\n","import { ChartConfigChartPaneElement, RequireByKey } from '../../types/shared'\r\nimport { OverlayType } from '../constants/common'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport Overlay from './overlay'\r\n\r\ninterface Attrs {\r\n period?: string\r\n conversion: number\r\n base: number\r\n spanB: number\r\n spanAStrokeColor: string\r\n spanAFillColor: string\r\n spanBStrokeColor: string\r\n spanBFillColor: string\r\n conversionLineColor: string\r\n baseLineColor: string\r\n laggingSpanColor: string\r\n}\r\n\r\nconst COLORS = {\r\n SpanA: {\r\n Stroke: '#009600',\r\n Fill: '#00960022',\r\n },\r\n SpanB: {\r\n Stroke: '#C80000',\r\n Fill: '#C8000022',\r\n },\r\n ConversionLine: '#69C1EA',\r\n BaseLine: '#E54040',\r\n LaggingSpan: '#FFA75F',\r\n}\r\n\r\nconst DEFAULT_PARAMETERS = {\r\n Conversion: 9,\r\n Base: 26,\r\n SpanB: 52,\r\n}\r\n\r\nfunction parsePeriod(period: string) {\r\n const [conversion = DEFAULT_PARAMETERS.Conversion, base = DEFAULT_PARAMETERS.Base, spanB = DEFAULT_PARAMETERS.SpanB] =\r\n getParsedIntegersFromPeriodString(period)\r\n return [conversion, base, spanB]\r\n}\r\n\r\nclass IchimokuCloud extends Overlay {\r\n static type = OverlayType.Ic\r\n static label = 'Ichimoku Cloud'\r\n static renderFull = false\r\n\r\n static getNumOfBarsBuffer({ period }: RequireByKey) {\r\n return Math.max(...parsePeriod(period))\r\n }\r\n\r\n get renderFull() {\r\n return (this.constructor as typeof IchimokuCloud).renderFull\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n if (\r\n typeof this.attrs.period === 'string' &&\r\n (this.attrs.conversion === undefined || this.attrs.base === undefined || this.attrs.spanB === undefined)\r\n ) {\r\n const [conversion, base, spanB] = parsePeriod(this.attrs.period)\r\n this.attrs.conversion = conversion\r\n this.attrs.base = base\r\n this.attrs.spanB = spanB\r\n }\r\n this.trigger('change')\r\n return this\r\n }\r\n\r\n fx = (x: number) => {\r\n const lastIndex = this.data.close.length - 1\r\n const outsideBar = this.data.barIndex[lastIndex] + x - lastIndex\r\n\r\n return this.model.scale.x(this.data.barIndex[x] ?? outsideBar)\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const { leftOffset, width } = this.model.chart()\r\n const { high, low, close } = this.data\r\n\r\n const {\r\n conversion,\r\n base,\r\n spanB,\r\n spanAFillColor,\r\n spanAStrokeColor,\r\n spanBFillColor,\r\n spanBStrokeColor,\r\n baseLineColor,\r\n conversionLineColor,\r\n laggingSpanColor,\r\n } = this.attrs\r\n\r\n const conversionLine: number[] = []\r\n const baseLine: number[] = []\r\n const senkouSpanA: number[] = []\r\n const senkouSpanB: number[] = []\r\n const conversionStartIndex = conversion - 1\r\n const baseStartIndex = base - 1\r\n const spanBIndex = spanB - 1\r\n const start = Math.min(baseStartIndex, conversionStartIndex)\r\n const end = close.length + baseStartIndex\r\n\r\n if (this.data.close.length === 0) return\r\n\r\n // Calculation\r\n for (let i = start; i < end; i++) {\r\n if (i >= conversionStartIndex && i < close.length) {\r\n const highestHi = Math.max(...high.slice(i - conversionStartIndex, i + 1))\r\n const lowestLo = Math.min(...low.slice(i - conversionStartIndex, i + 1))\r\n conversionLine[i] = (highestHi + lowestLo) / 2\r\n }\r\n\r\n if (i >= baseStartIndex && i < close.length) {\r\n const highestHi = Math.max(...high.slice(i - baseStartIndex, i + 1))\r\n const lowestLo = Math.min(...low.slice(i - baseStartIndex, i + 1))\r\n baseLine[i] = (highestHi + lowestLo) / 2\r\n\r\n senkouSpanA[i + baseStartIndex] = (baseLine[i] + conversionLine[i]) / 2 // + baseStart because it needs to be shifted to the future\r\n }\r\n\r\n if (i >= spanBIndex) {\r\n const highestHi = Math.max(...high.slice(i - spanBIndex, i + 1))\r\n const lowestLo = Math.min(...low.slice(i - spanBIndex, i + 1))\r\n senkouSpanB[i + baseStartIndex] = (highestHi + lowestLo) / 2 // + baseStart because it needs to be shifted to the future\r\n }\r\n }\r\n\r\n let lastSpanAX = 0\r\n let lastSpanBX = 0\r\n const cloudStartingX = this.fx(spanBIndex + baseStartIndex)\r\n\r\n const drawInVisibleAreaProps = {\r\n toIndexOffset: baseStartIndex,\r\n leftOffset,\r\n paneModel: this.model,\r\n quote: this.data,\r\n width,\r\n fxOverride: this.fx,\r\n }\r\n\r\n context.set('lineWidth', 1)\r\n context.translate(0.5, 0.5)\r\n context.save()\r\n // 1. Senkou Span A\r\n // 1.1 Stroke\r\n context.set('strokeStyle', spanAStrokeColor)\r\n context.set('fillStyle', spanAFillColor)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(senkouSpanA[i])))\r\n lastSpanAX = x\r\n },\r\n })\r\n context.stroke()\r\n // 1.2 Clipping area\r\n context.lineTo(lastSpanAX, context.canvas.height)\r\n context.lineTo(cloudStartingX, context.canvas.height)\r\n context.clip()\r\n // 1.3 Fill\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n if (i >= senkouSpanA.length) return\r\n context.lineTo(x, Math.round(this.fy(senkouSpanB[i])))\r\n lastSpanBX = x\r\n },\r\n })\r\n context.lineTo(lastSpanBX, 0)\r\n context.lineTo(cloudStartingX, 0)\r\n context.fill()\r\n context.restore()\r\n\r\n // 2. Senkou Span B\r\n // 2.1 Stroke\r\n context.save()\r\n context.set('strokeStyle', spanBStrokeColor)\r\n context.set('fillStyle', spanBFillColor)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n if (i >= senkouSpanA.length) return\r\n context.lineTo(x, Math.round(this.fy(senkouSpanB[i])))\r\n },\r\n })\r\n context.stroke()\r\n // 2.2 Clipping area\r\n context.lineTo(lastSpanBX, context.canvas.height)\r\n context.lineTo(cloudStartingX, context.canvas.height)\r\n context.clip()\r\n // 2.3 Fill\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(senkouSpanA[i])))\r\n },\r\n })\r\n context.lineTo(lastSpanBX, 0)\r\n context.lineTo(cloudStartingX, 0)\r\n context.fill()\r\n context.restore()\r\n context.translate(-0.5, -0.5)\r\n\r\n if (this.renderFull) {\r\n // conversion line\r\n context.set('strokeStyle', conversionLineColor)\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(conversionLine[i])))\r\n },\r\n })\r\n context.stroke()\r\n\r\n // base line\r\n context.set('strokeStyle', baseLineColor)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(baseLine[i])))\r\n },\r\n })\r\n context.stroke()\r\n\r\n // lagging span\r\n context.set('strokeStyle', laggingSpanColor)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n fxOverride: (x: number) => this.fx(x - base),\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(this.data.close[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n }\r\n\r\n getModalConfig() {\r\n const conversion = {\r\n type: 'number',\r\n label: 'Conversion Line',\r\n name: 'conversion',\r\n value: this.attrs.conversion ?? DEFAULT_PARAMETERS.Conversion,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n const base = {\r\n type: 'number',\r\n label: 'Base Line Length',\r\n name: 'base',\r\n value: this.attrs.base ?? DEFAULT_PARAMETERS.Base,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n const spanB = {\r\n type: 'number',\r\n label: 'Leading Span B Length',\r\n name: 'spanB',\r\n value: this.attrs.spanB ?? DEFAULT_PARAMETERS.SpanB,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n const spanAStrokeColor = {\r\n type: 'color',\r\n label: 'Span A Stroke Color',\r\n name: 'spanAStrokeColor',\r\n value: this.attrs.spanAStrokeColor ?? this.getFreeColor(),\r\n }\r\n const spanAFillColor = {\r\n type: 'color',\r\n label: 'Span A Fill Color',\r\n name: 'spanAFillColor',\r\n value: this.attrs.spanAFillColor ?? this.getFreeColor(),\r\n }\r\n const spanBStrokeColor = {\r\n type: 'color',\r\n label: 'Span B Stroke Color',\r\n name: 'spanBStrokeColor',\r\n value: this.attrs.spanBStrokeColor ?? this.getFreeColor(),\r\n }\r\n const spanBFillColor = {\r\n type: 'color',\r\n label: 'Span B Fill Color',\r\n name: 'spanBFillColor',\r\n value: this.attrs.spanBFillColor ?? this.getFreeColor(),\r\n }\r\n const conversionLineColor = {\r\n type: 'color',\r\n label: 'Conversion Line Color',\r\n name: 'conversionLineColor',\r\n value: this.attrs.conversionLineColor ?? this.getFreeColor(),\r\n }\r\n const baseLineColor = {\r\n type: 'color',\r\n label: 'Base Line Color',\r\n name: 'baseLineColor',\r\n value: this.attrs.baseLineColor ?? this.getFreeColor(),\r\n }\r\n const laggingSpanColor = {\r\n type: 'color',\r\n label: 'Lagging Span Color',\r\n name: 'laggingSpanColor',\r\n value: this.attrs.laggingSpanColor ?? this.getFreeColor(),\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [\r\n conversion,\r\n base,\r\n spanB,\r\n spanAStrokeColor,\r\n spanAFillColor,\r\n spanBStrokeColor,\r\n spanBFillColor,\r\n conversionLineColor,\r\n baseLineColor,\r\n laggingSpanColor,\r\n ],\r\n inputsErrorMessages: {\r\n conversion: `${conversion.label} must be a whole number between ${conversion.min} and ${conversion.max}`,\r\n base: `${base.label} must be a whole number between ${base.min} and ${base.max}`,\r\n spanB: `${spanB.label} must be a whole number between ${spanB.min} and ${spanB.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'conversion':\r\n case 'base':\r\n case 'spanB':\r\n case 'lagging':\r\n return this.getIsNumberInputValid({ key })\r\n case 'spanAStrokeColor':\r\n case 'spanAFillColor':\r\n case 'spanBStrokeColor':\r\n case 'spanBFillColor':\r\n case 'conversionLineColor':\r\n case 'baseLineColor':\r\n case 'laggingSpanColor':\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n getLabelColor() {\r\n return this.attrs.spanAStrokeColor\r\n }\r\n\r\n toString() {\r\n return `Ichimoku ${this.attrs.conversion},${this.attrs.base},${this.attrs.spanB}`\r\n }\r\n}\r\n\r\nIchimokuCloud.prototype.defaults = {\r\n spanAStrokeColor: COLORS.SpanA.Stroke,\r\n spanAFillColor: COLORS.SpanA.Fill,\r\n spanBStrokeColor: COLORS.SpanB.Stroke,\r\n spanBFillColor: COLORS.SpanB.Fill,\r\n conversionLineColor: COLORS.ConversionLine,\r\n baseLineColor: COLORS.BaseLine,\r\n laggingSpanColor: COLORS.LaggingSpan,\r\n}\r\n\r\nexport default IchimokuCloud\r\n","import { OverlayType } from '../constants/common'\r\nimport IchimokuCloud from './ic'\r\n\r\nclass IchimokuCloudFull extends IchimokuCloud {\r\n static type = OverlayType.Icf\r\n static label = 'Ichimoku Cloud (Full)'\r\n static renderFull = true\r\n}\r\n\r\nexport default IchimokuCloudFull\r\n","import { ChartConfigChartPaneElement, RequireByKey } from '../../types/shared'\r\nimport { OverlayType } from '../constants/common'\r\nimport AverageTrueRange from '../helpers/atr'\r\nimport { ExponentialMovingAverage } from '../indicator-calculation/ema'\r\nimport Overlay from './overlay'\r\n\r\ninterface Attrs {\r\n period?: string\r\n emaPeriod: number\r\n multiplier: number\r\n atrPeriod: number\r\n strokeColor: string\r\n fillColor: string\r\n}\r\n\r\nconst DEFAULT_PARAMETERS = {\r\n emaPeriod: 20,\r\n multiplier: 2.0,\r\n atrPeriod: 10,\r\n}\r\n\r\nconst COLORS = {\r\n Stroke: '#69C1EA',\r\n Fill: '#69C1EA33',\r\n}\r\n\r\nfunction parsePeriod(period: string) {\r\n const values = period.split(',')\r\n const emaPeriod = parseInt(values[0])\r\n const multiplier = parseFloat(values[1])\r\n const atrPeriod = parseInt(values[2])\r\n\r\n return [emaPeriod, multiplier, atrPeriod]\r\n}\r\n\r\nclass KeltnerChannel extends Overlay {\r\n static type = OverlayType.Kch\r\n static label = 'Keltner Channel'\r\n\r\n static getNumOfBarsBuffer({ period }: RequireByKey) {\r\n return Math.max(...parsePeriod(period)) * 2\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n if (\r\n typeof this.attrs.period === 'string' &&\r\n (this.attrs.emaPeriod === undefined || this.attrs.multiplier === undefined || this.attrs.atrPeriod === undefined)\r\n ) {\r\n const [emaPeriod, multiplier, atrPeriod] = parsePeriod(this.attrs.period)\r\n this.attrs.emaPeriod = emaPeriod\r\n this.attrs.multiplier = multiplier\r\n this.attrs.atrPeriod = atrPeriod\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const { leftOffset, width } = this.model.chart()\r\n const { emaPeriod, multiplier, atrPeriod, strokeColor, fillColor } = this.attrs\r\n const ema = new ExponentialMovingAverage(emaPeriod)\r\n const atr = new AverageTrueRange(atrPeriod)\r\n const middleLine: number[] = []\r\n const upperBand: number[] = []\r\n const lowerBand: number[] = []\r\n const start = Math.max(emaPeriod, atrPeriod)\r\n let firstBarToRender\r\n let lastBarToRender = 0\r\n\r\n context.save()\r\n context.translate(0.5, 0.5)\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', strokeColor)\r\n context.set('fillStyle', fillColor)\r\n\r\n //top line + clip\r\n context.beginPath()\r\n for (let i = 1; i < this.data.close.length; i++) {\r\n ema.add(this.data.close[i])\r\n atr.add(this.data.high[i], this.data.low[i], this.data.close[i - 1])\r\n if (i < start) {\r\n continue\r\n }\r\n\r\n const x = this.fx(i)\r\n if (this.fx(i + 1) + leftOffset < 0) {\r\n continue\r\n }\r\n if (this.fx(i - 1) + leftOffset > width) {\r\n break\r\n }\r\n if (firstBarToRender === undefined) firstBarToRender = i\r\n\r\n middleLine[i] = ema.value\r\n upperBand[i] = ema.value + multiplier * atr.value\r\n lowerBand[i] = ema.value - multiplier * atr.value\r\n\r\n context.lineTo(x, Math.round(this.fy(upperBand[i])))\r\n lastBarToRender = i\r\n }\r\n if (firstBarToRender === undefined) {\r\n context.restore()\r\n return\r\n }\r\n context.stroke()\r\n context.lineTo(this.fx(lastBarToRender), context.canvas.height)\r\n context.lineTo(this.fx(firstBarToRender), context.canvas.height)\r\n context.clip()\r\n\r\n // bottom line + fill\r\n context.beginPath()\r\n for (let i = firstBarToRender; i <= lastBarToRender; i++) {\r\n const x = this.fx(i)\r\n context.lineTo(x, Math.round(this.fy(lowerBand[i])))\r\n }\r\n context.stroke()\r\n context.lineTo(this.fx(lastBarToRender), 0)\r\n context.lineTo(0, 0)\r\n context.fill()\r\n\r\n // middle line\r\n context.beginPath()\r\n for (let i = firstBarToRender; i <= lastBarToRender; i++) {\r\n const x = this.fx(i)\r\n context.lineTo(x, Math.round(this.fy(middleLine[i])))\r\n }\r\n context.stroke()\r\n context.restore()\r\n }\r\n\r\n getModalConfig() {\r\n const emaPeriod = {\r\n type: 'number',\r\n label: 'EMA Period',\r\n name: 'emaPeriod',\r\n value: this.attrs.emaPeriod ?? DEFAULT_PARAMETERS.emaPeriod,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n const multiplier = {\r\n type: 'number',\r\n label: 'Multiplier',\r\n name: 'multiplier',\r\n value: this.attrs.multiplier ?? DEFAULT_PARAMETERS.multiplier,\r\n required: true,\r\n step: 0.1,\r\n min: 0.0,\r\n max: 999,\r\n }\r\n\r\n const atrPeriod = {\r\n type: 'number',\r\n label: 'ATR Period',\r\n name: 'atrPeriod',\r\n value: this.attrs.atrPeriod ?? DEFAULT_PARAMETERS.atrPeriod,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n const strokeColor = {\r\n type: 'color',\r\n label: 'Stroke Color',\r\n name: 'strokeColor',\r\n value: this.attrs.strokeColor ?? this.getFreeColor(),\r\n }\r\n const fillColor = {\r\n type: 'color',\r\n label: 'Fill Color',\r\n name: 'fillColor',\r\n value: this.attrs.fillColor ?? this.getFreeColor(),\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [emaPeriod, multiplier, atrPeriod, strokeColor, fillColor],\r\n inputsErrorMessages: {\r\n emaPeriod: `${emaPeriod.label} must be a whole number between ${emaPeriod.min} and ${emaPeriod.max}`,\r\n multiplier: `${multiplier.label} must be a number between ${multiplier.min} and ${multiplier.max}`,\r\n atrPeriod: `${atrPeriod.label} must be a whole number between ${atrPeriod.min} and ${atrPeriod.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'emaPeriod':\r\n return this.getIsNumberInputValid({ key })\r\n case 'multiplier':\r\n return this.getIsNumberInputValid({ key, integerOnly: false })\r\n case 'atrPeriod':\r\n return this.getIsNumberInputValid({ key })\r\n case 'strokeColor':\r\n case 'fillColor':\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n getLabelColor() {\r\n return this.attrs.strokeColor\r\n }\r\n\r\n toString() {\r\n return `Keltner Channel ${this.attrs.emaPeriod},${this.attrs.multiplier},${this.attrs.atrPeriod}`\r\n }\r\n}\r\n\r\nKeltnerChannel.prototype.defaults = { strokeColor: COLORS.Stroke, fillColor: COLORS.Fill }\r\n\r\nexport default KeltnerChannel\r\n","import { OverlayType } from '../constants/common'\r\nimport Overlay from './overlay'\r\n\r\n// This indicator is used as a placeholder when we need to render TA like chart but don't need any overlay or indicator in the chart\r\nclass None extends Overlay {\r\n static type = OverlayType.None\r\n static label = 'None'\r\n\r\n static getNumOfBarsBuffer() {\r\n return 0\r\n }\r\n\r\n isRendered() {\r\n return false\r\n }\r\n\r\n getIsValid() {\r\n return true\r\n }\r\n}\r\n\r\nexport default None\r\n","import Text from '../canvas/text'\r\nimport { OverlayType, TextAlign, TextBaseline } from '../constants/common'\r\nimport { getRoundedObject, getXYOffsetFromLine } from '../controllers/renderUtils'\r\nimport Overlay from './overlay'\r\n\r\ntype aboveBelowType = 'above' | 'below'\r\n\r\nclass Patterns extends Overlay {\r\n static type = OverlayType.Patterns\r\n static label = 'Patterns (daily charts)'\r\n\r\n static getNumOfBarsBuffer() {\r\n return 0\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const data = this.data\r\n if (data.patterns.length === 0) {\r\n return\r\n }\r\n\r\n const originalScale = {\r\n width: 600,\r\n height: 300,\r\n barsInDay: Math.min(data.close.length, 200),\r\n high: data.patternsMaxRange,\r\n low: data.patternsMinRange,\r\n barWidth: 0,\r\n }\r\n originalScale.barWidth = originalScale.width / 200\r\n\r\n const scaleY = (originalScale.high - originalScale.low) / originalScale.height\r\n const fx = (x: number) => {\r\n if (x === 0) {\r\n return this.fx(0)\r\n }\r\n return this.fx(data.close.length - 1 - ~~(originalScale.barsInDay - x / originalScale.barWidth))\r\n }\r\n const fy = (y: number) => this.fy(originalScale.high - y * scaleY)\r\n const line = (color: string, x1: number, y1: number, x2: number, y2: number) => {\r\n const roundedXY = getRoundedObject({\r\n x1: fx(x1),\r\n y1: fy(y1),\r\n x2: fx(x2),\r\n y2: fy(y2),\r\n })\r\n const translateXY = getXYOffsetFromLine({ lineWidth: 1, ...roundedXY })\r\n context.translate(translateXY.x, translateXY.y)\r\n\r\n context.beginPath()\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', color)\r\n context.lineTo(roundedXY.x1, roundedXY.y1)\r\n context.lineTo(roundedXY.x2, roundedXY.y2)\r\n context.stroke()\r\n\r\n context.translate(translateXY.x * -1, translateXY.y * -1)\r\n }\r\n const text = (text: string, aboveBelow: aboveBelowType, color: string, x1: number, x2: number, y1: number) => {\r\n new Text(\r\n {\r\n x: fx((x1 + x2) / 2),\r\n y: fy(y1) + (aboveBelow === 'above' ? -1 : 2),\r\n font: { size: 8, style: 'bold' },\r\n textBaseline: aboveBelow === 'above' ? TextBaseline.bottom : TextBaseline.top,\r\n fillStyle: color,\r\n textAlign: TextAlign.center,\r\n text,\r\n },\r\n this.model\r\n ).render(context)\r\n }\r\n const textHS = (text: string, aboveBelow: aboveBelowType, color: string, x1: number, y1: number) => {\r\n new Text(\r\n {\r\n x: fx(x1) + 5,\r\n y: fy(y1) + (aboveBelow === 'above' ? -1 : 2),\r\n font: { size: 9, style: 'bold' },\r\n textBaseline: aboveBelow === 'above' ? TextBaseline.bottom : TextBaseline.top,\r\n fillStyle: color,\r\n textAlign: TextAlign.center,\r\n text,\r\n },\r\n this.model\r\n ).render(context)\r\n }\r\n const above = (y: number) =>\r\n fy(y) + 10 >= this.model.height - ChartSettings.top.height - ChartSettings.bottom.height ? 'above' : 'below'\r\n const below = (y: number) => (fy(y) <= 15 ? 'below' : 'above')\r\n\r\n const supportColor = 'rgb(0, 150, 220)'\r\n const resistColor = 'rgb(180, 50, 200)'\r\n\r\n for (const pattern of data.patterns) {\r\n const { x1, x2, x3, y3 } = pattern\r\n let { y1, y2 } = pattern\r\n switch (pattern.kind) {\r\n case 1: // Horiz S/R\r\n line('rgba(50, 50, 180, 0.588)', x1, y1, x2, y2)\r\n break\r\n\r\n case 2: // tl resist\r\n line(resistColor, x1, y1, x2, y2)\r\n break\r\n\r\n case 3: // tl support\r\n if (y1 === originalScale.height && y2 === originalScale.height) {\r\n y1 = y2 = originalScale.height - 1\r\n // Maybe just need to check on the new scale?\r\n } // support \"pod grafom\"\r\n line(supportColor, x1, y1, x2, y2)\r\n break\r\n\r\n case 12: // double top\r\n text('Double Top', below(y1), resistColor, x1, x2, y1)\r\n break\r\n\r\n case 13: // double bottom\r\n text('Double Bottom', above(y1), supportColor, x1, x2, y1)\r\n break\r\n\r\n case 14: // multi top\r\n text('Multiple Top', below(y1), resistColor, x1, x2, y1)\r\n break\r\n\r\n case 15: // multi bottom\r\n text('Multiple Bottom', above(y1), supportColor, x1, x2, y1)\r\n break\r\n\r\n case 16: // h&s top\r\n textHS('L', below(y1), resistColor, x1, y1)\r\n textHS('H', below(y2), resistColor, x2, y2)\r\n textHS('R', below(y3), resistColor, x3, y3)\r\n break\r\n\r\n case 17: // h&s bot\r\n textHS('L', above(y1), supportColor, x1, y1)\r\n textHS('H', above(y2), supportColor, x2, y2)\r\n textHS('R', above(y3), supportColor, x3, y3)\r\n break\r\n default:\r\n break\r\n }\r\n }\r\n }\r\n\r\n getModalConfig() {\r\n const supportColor = {\r\n type: 'color',\r\n label: 'Support Color',\r\n name: 'supportColor',\r\n value: this.attrs.supportColor ?? this.getFreeColor(),\r\n }\r\n const resistColor = {\r\n type: 'color',\r\n label: 'Resist Color',\r\n name: 'resistColor',\r\n value: this.attrs.resistColor ?? this.getFreeColor(),\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [supportColor, resistColor],\r\n inputsErrorMessages: {},\r\n }\r\n }\r\n\r\n getIsValid() {\r\n return true\r\n }\r\n\r\n isRenderedOverlaysLabel() {\r\n return false\r\n }\r\n\r\n toString() {\r\n return ''\r\n }\r\n}\r\n\r\nPatterns.prototype.defaults = { supportColor: '#69c1ea', resistColor: '#d386df' }\r\n\r\nexport default Patterns\r\n","import * as dateFns from 'date-fns'\r\n\r\nimport { Instrument } from '../../types/shared'\r\nimport Text from '../canvas/text'\r\nimport { OverlayType, TIMEFRAME, TextBaseline } from '../constants/common'\r\nimport Chart from '../models/chart'\r\nimport Utils from '../utils'\r\nimport { getBarWidthWithMargin, round } from '../utils/chart'\r\nimport { getAreNoBarsVisible, getVisibleBarToRenderIndex } from '../utils/draw_in_visible_area'\r\nimport Overlay from './overlay'\r\n\r\nenum Calculation {\r\n standard = 'Standard',\r\n fibonacci = 'Fibonacci',\r\n}\r\ntype CalculationType = keyof typeof Calculation\r\n\r\nenum PivotPeriod {\r\n day,\r\n week,\r\n month,\r\n year,\r\n}\r\n\r\ntype PivotPointType = {\r\n pivot: number\r\n res1: number\r\n res2: number\r\n res3: number\r\n sup1: number\r\n sup2: number\r\n sup3: number\r\n}\r\n\r\ninterface Attrs {\r\n period?: string\r\n calculationType: CalculationType\r\n color: string\r\n}\r\n\r\nconst DEFAULT_PARAMETERS = {\r\n CalculationType: 'standard' as CalculationType,\r\n Color: '#FFA75F',\r\n}\r\nconst FIB_LVL_1 = 0.382\r\nconst FIB_LVL_2 = 0.618\r\nconst DAY_SECONDS = 86400\r\nconst MINUTES_PER_DAY = 1440\r\n\r\nclass PivotPoints extends Overlay {\r\n static type = OverlayType.Pp\r\n static label = 'Pivot Points'\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n const { period } = obj\r\n if (period) {\r\n this.attrs.calculationType = period as CalculationType\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n getPeriodType() {\r\n switch (this.data.timeframe) {\r\n case TIMEFRAME.i30:\r\n case TIMEFRAME.h:\r\n case TIMEFRAME.h2:\r\n return PivotPeriod.week\r\n case TIMEFRAME.h4:\r\n case TIMEFRAME.d:\r\n return PivotPeriod.month\r\n case TIMEFRAME.w:\r\n case TIMEFRAME.m:\r\n return PivotPeriod.year\r\n default:\r\n return PivotPeriod.day\r\n }\r\n }\r\n\r\n getIsEnoughData(startIndex: number, endIndex: number, periodType: PivotPeriod) {\r\n let dayGap = 7 // one week for week period\r\n if (periodType === PivotPeriod.month) dayGap = 28 // shortest month\r\n if (periodType === PivotPeriod.year) dayGap = 365\r\n\r\n if (startIndex !== endIndex) {\r\n if (startIndex === 0) {\r\n const daysDiff = (this.data.date[endIndex] - this.data.date[startIndex]) / DAY_SECONDS\r\n // we need to somehow determine if we have data if it starts from index 0\r\n // and we can't easily check if day before is different (different month/week/year)\r\n // so we are at least checking if it is [dayGap] days between start and end date\r\n return daysDiff >= dayGap\r\n } else {\r\n const startDay = Utils.dateFromUnixTimestamp(this.data.date[startIndex])\r\n const beforeDay = Utils.dateFromUnixTimestamp(this.data.date[startIndex - 1])\r\n if (periodType === PivotPeriod.week) {\r\n return beforeDay.getDate() !== startDay.getDate()\r\n } else {\r\n return beforeDay.getMonth() !== startDay.getMonth()\r\n }\r\n }\r\n }\r\n return false\r\n }\r\n\r\n fx = (x: number) => {\r\n const lastIndex = this.data.close.length - 1\r\n const outsideBar = this.data.barIndex[lastIndex] + x - lastIndex\r\n\r\n return this.model.scale.x(this.data.barIndex[x] ?? outsideBar)\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n if (this.data.close.length === 0) return\r\n\r\n const chartModel = this.model.chart() as Chart\r\n const { leftOffset, width, zoomFactor } = chartModel\r\n const { left, right } = chartModel.getChartLayoutSettings().ChartSettings\r\n const chartWidth = width - left.width - right.width\r\n const barWidth = getBarWidthWithMargin({\r\n zoomFactor,\r\n chartLayout: chartModel.chart_layout(),\r\n })\r\n\r\n const firstBarToRender = getVisibleBarToRenderIndex({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset,\r\n })\r\n const lastBarToRender = getVisibleBarToRenderIndex({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset,\r\n chartWidth,\r\n })\r\n\r\n const areNoBarsVisible = getAreNoBarsVisible(firstBarToRender, lastBarToRender)\r\n if (areNoBarsVisible) return\r\n\r\n const text = (label: string, price: number, calculatedX: number) => {\r\n new Text(\r\n {\r\n x: calculatedX,\r\n y: this.fy(price) - 13,\r\n font: { size: 8, weight: '900' },\r\n textBaseline: TextBaseline.top,\r\n fillStyle: this.attrs.color,\r\n text: `${label} (${round({ data: this.data, num: price })})`,\r\n },\r\n this.model\r\n ).render(context)\r\n }\r\n\r\n const line = (fromX: number, toX: number, y: number) => {\r\n context.moveTo(fromX, this.fy(y))\r\n context.lineTo(toX, this.fy(y))\r\n }\r\n\r\n let startIndex = -1\r\n let endIndex = -1\r\n const isStock = this.data.instrument === Instrument.Stock\r\n const periodType = this.getPeriodType()\r\n let currentDate = new Date()\r\n let lastDate: Date | undefined\r\n\r\n context.translate(0.5, 0.5)\r\n context.set('strokeStyle', this.attrs.color)\r\n\r\n for (let index = firstBarToRender.index; index <= lastBarToRender.index; index++) {\r\n currentDate = Utils.dateFromUnixTimestamp(this.data.date[index])\r\n\r\n // check if new calculation/render is necessary\r\n switch (periodType) {\r\n case PivotPeriod.day: // only if it is a new day\r\n if (currentDate.getDate() === lastDate?.getDate()) {\r\n continue\r\n }\r\n break\r\n case PivotPeriod.week: // only if it is a new week\r\n if (lastDate && dateFns.isSameWeek(lastDate, currentDate, { weekStartsOn: 1 })) {\r\n continue\r\n }\r\n break\r\n case PivotPeriod.month: // only if it is a new month\r\n if (currentDate.getMonth() === lastDate?.getMonth()) {\r\n continue\r\n }\r\n break\r\n case PivotPeriod.year: // only if it is a new year\r\n if (currentDate.getFullYear() === lastDate?.getFullYear()) {\r\n continue\r\n }\r\n break\r\n }\r\n lastDate = currentDate\r\n\r\n // Find start/end indexes for the entire previous period\r\n switch (periodType) {\r\n case PivotPeriod.day:\r\n if (index > 0) {\r\n let previousTradingDay = new Date()\r\n for (let i = index - 1; i >= 0; i--) {\r\n previousTradingDay = Utils.dateFromUnixTimestamp(this.data.date[i])\r\n if (previousTradingDay.getDate() !== currentDate.getDate()) break\r\n }\r\n previousTradingDay.setHours(0, 0, 0, 0)\r\n const previousNYMidnightTimestamp = Utils.convertLocalToNyTime(previousTradingDay, false).getTime() / 1000\r\n const currentMidnight = new Date(currentDate)\r\n currentMidnight.setHours(0, 0, 0, 0)\r\n const currentNYMidnightTimestamp = Utils.convertLocalToNyTime(currentMidnight, false).getTime() / 1000\r\n\r\n startIndex = this.data.date.findIndex((ts) => ts >= previousNYMidnightTimestamp)\r\n endIndex = this.data.date.findIndex((ts) => ts > currentNYMidnightTimestamp)\r\n\r\n // check if we have data for entire day\r\n if (startIndex !== endIndex) {\r\n const diff = this.data.date[endIndex] - this.data.date[startIndex]\r\n const isNonStockFullDay = !isStock && diff >= DAY_SECONDS\r\n const isStockFullDay = isStock && previousTradingDay.getDate() !== currentDate.getDate()\r\n if (!isNonStockFullDay && !isStockFullDay) {\r\n startIndex = endIndex = Number.MIN_SAFE_INTEGER\r\n }\r\n }\r\n }\r\n break\r\n case PivotPeriod.week:\r\n const firstDayCurrentWeek = dateFns.startOfWeek(currentDate, { weekStartsOn: 1 })\r\n const firstDayCurrentWeekTimestamp = Utils.convertLocalToNyTime(firstDayCurrentWeek, false).getTime() / 1000\r\n const firstDayPreviousWeek = dateFns.sub(firstDayCurrentWeek, { weeks: 1 })\r\n const firstDayPreviousWeekTimestamp = Utils.convertLocalToNyTime(firstDayPreviousWeek, false).getTime() / 1000\r\n\r\n startIndex = this.data.date.findIndex((ts) => ts >= firstDayPreviousWeekTimestamp)\r\n endIndex = this.data.date.findIndex((ts) => ts > firstDayCurrentWeekTimestamp)\r\n\r\n if (!this.getIsEnoughData(startIndex, endIndex, periodType)) {\r\n startIndex = endIndex = Number.MIN_SAFE_INTEGER\r\n }\r\n break\r\n case PivotPeriod.month:\r\n const firstDayCurrentMonth = dateFns.startOfMonth(currentDate)\r\n const firstDayCurrentMonthTimestamp = Utils.convertLocalToNyTime(firstDayCurrentMonth, false).getTime() / 1000\r\n const firstDayPreviousMonth = dateFns.sub(firstDayCurrentMonth, { months: 1 })\r\n const firstDayPreviousMonthTimestamp =\r\n Utils.convertLocalToNyTime(firstDayPreviousMonth, false).getTime() / 1000\r\n\r\n startIndex = this.data.date.findIndex((ts) => ts >= firstDayPreviousMonthTimestamp)\r\n endIndex = this.data.date.findIndex((ts) => ts > firstDayCurrentMonthTimestamp)\r\n\r\n if (!this.getIsEnoughData(startIndex, endIndex, periodType)) {\r\n startIndex = endIndex = Number.MIN_SAFE_INTEGER\r\n }\r\n break\r\n case PivotPeriod.year:\r\n const firstDayCurrentYear = dateFns.startOfYear(currentDate)\r\n const firstDayCurrentYearTimestamp = Utils.convertLocalToNyTime(firstDayCurrentYear, false).getTime() / 1000\r\n const firstDayPreviousYear = dateFns.sub(firstDayCurrentYear, { years: 1 })\r\n const firstDayPreviousYearTimestamp = Utils.convertLocalToNyTime(firstDayPreviousYear, false).getTime() / 1000\r\n\r\n startIndex = this.data.date.findIndex((ts) => ts >= firstDayPreviousYearTimestamp)\r\n endIndex = this.data.date.findIndex((ts) => ts > firstDayCurrentYearTimestamp)\r\n\r\n if (!this.getIsEnoughData(startIndex, endIndex, periodType)) {\r\n startIndex = endIndex = Number.MIN_SAFE_INTEGER\r\n }\r\n break\r\n }\r\n\r\n // calculate pivot point if it was found\r\n if (!(startIndex !== -1 && endIndex !== -1 && startIndex < endIndex)) continue\r\n\r\n let pivot, sup1, sup2, sup3, res1, res2, res3\r\n const previousHigh = Math.max(...this.data.high.slice(startIndex, endIndex))\r\n const previousLow = Math.min(...this.data.low.slice(startIndex, endIndex))\r\n const previousClose = this.data.close[endIndex - 1] // endIndex is the beginning of the next period\r\n\r\n if (this.attrs.calculationType === 'standard') {\r\n pivot = (previousHigh + previousLow + previousClose) / 3\r\n sup1 = 2 * pivot - previousHigh\r\n sup2 = pivot - (previousHigh - previousLow)\r\n sup3 = previousLow - 2 * (previousHigh - pivot)\r\n res1 = 2 * pivot - previousLow\r\n res2 = pivot + (previousHigh - previousLow)\r\n res3 = previousHigh + 2 * (pivot - previousLow)\r\n } else {\r\n pivot = (previousHigh + previousLow + previousClose) / 3\r\n sup1 = pivot - (previousHigh - previousLow) * FIB_LVL_1\r\n sup2 = pivot - (previousHigh - previousLow) * FIB_LVL_2\r\n sup3 = pivot - (previousHigh - previousLow)\r\n res1 = pivot + (previousHigh - previousLow) * FIB_LVL_1\r\n res2 = pivot + (previousHigh - previousLow) * FIB_LVL_2\r\n res3 = pivot + (previousHigh - previousLow)\r\n }\r\n\r\n const pivotPoint: PivotPointType = { pivot, sup1, sup2, sup3, res1, res2, res3 }\r\n\r\n // prepare x coordinates for lines rendering\r\n let fromX = this.fx(index)\r\n let toX = this.fx(index)\r\n switch (periodType) {\r\n case PivotPeriod.day:\r\n const interval = this.data.interval\r\n const currentX = fromX\r\n\r\n const toDate = new Date(currentDate)\r\n toDate.setHours(16, 0, 0, 0)\r\n if (this.data.aftermarket && interval <= 5) toDate.setHours(18, 30, 0, 0)\r\n if (interval <= 15 && !isStock) toDate.setHours(23, 59, 59, 99)\r\n const toTimestamp = toDate.getTime() / 1000\r\n const toDiffMinutes = (toTimestamp - currentDate.getTime() / 1000) / 60\r\n const toBars = toDiffMinutes / interval\r\n toX = Math.min(currentX + toBars * barWidth, -leftOffset + width)\r\n\r\n const fromDate = new Date(currentDate)\r\n fromDate.setHours(9, 30, 0, 0)\r\n if (this.data.premarket && interval <= 5) fromDate.setHours(7, 0, 0, 0)\r\n if (interval <= 15 && !isStock) fromDate.setHours(0, 0, 0, 0)\r\n const fromTimestamp = fromDate.getTime() / 1000\r\n const fromDiffMinutes = (fromTimestamp - currentDate.getTime() / 1000) / 60\r\n const fromBars = fromDiffMinutes / interval\r\n fromX = currentX + fromBars * barWidth\r\n break\r\n\r\n case PivotPeriod.week:\r\n for (let i = index + 1; i <= lastBarToRender.index; i++) {\r\n const nextDate = Utils.dateFromUnixTimestamp(this.data.date[i])\r\n if (!dateFns.isSameWeek(currentDate, nextDate, { weekStartsOn: 1 })) {\r\n toX = this.fx(i)\r\n break\r\n }\r\n }\r\n for (let i = index - 1; i >= firstBarToRender.index; i--) {\r\n const nextDate = Utils.dateFromUnixTimestamp(this.data.date[i])\r\n if (!dateFns.isSameWeek(currentDate, nextDate, { weekStartsOn: 1 })) {\r\n fromX = this.fx(i + 1) // because we need start from current week\r\n break\r\n }\r\n }\r\n\r\n if (fromX === toX) {\r\n // we need line to imaginary end of the week\r\n const barsPerDay = Math.ceil((this.data.drawMinutesPerDay ?? MINUTES_PER_DAY) / this.data.interval)\r\n toX += (isStock ? 5 : 7) * barsPerDay * barWidth\r\n }\r\n break\r\n\r\n case PivotPeriod.month:\r\n for (let i = index + 1; i <= lastBarToRender.index; i++) {\r\n const nextDate = Utils.dateFromUnixTimestamp(this.data.date[i])\r\n if (nextDate.getMonth() !== currentDate.getMonth()) {\r\n toX = this.fx(i)\r\n break\r\n }\r\n }\r\n for (let i = index - 1; i >= firstBarToRender.index; i--) {\r\n const nextDate = Utils.dateFromUnixTimestamp(this.data.date[i])\r\n if (nextDate.getMonth() !== currentDate.getMonth()) {\r\n fromX = this.fx(i + 1) // because we need start from current month\r\n break\r\n }\r\n }\r\n\r\n if (fromX === toX) {\r\n // we need line to imaginary end of the month\r\n const barsPerDay = this.data.isIntraday\r\n ? Math.ceil((this.data.drawMinutesPerDay ?? MINUTES_PER_DAY) / this.data.interval)\r\n : 1\r\n toX += (isStock ? 20 : 30) * barsPerDay * barWidth\r\n }\r\n break\r\n default:\r\n for (let i = index + 1; i <= lastBarToRender.index; i++) {\r\n const nextDate = Utils.dateFromUnixTimestamp(this.data.date[i])\r\n if (nextDate.getFullYear() !== currentDate.getFullYear()) {\r\n toX = this.fx(i)\r\n break\r\n }\r\n }\r\n for (let i = index - 1; i >= firstBarToRender.index; i--) {\r\n const nextDate = Utils.dateFromUnixTimestamp(this.data.date[i])\r\n if (nextDate.getFullYear() !== currentDate.getFullYear()) {\r\n fromX = this.fx(i + 1) // because we need start from current year\r\n break\r\n }\r\n }\r\n\r\n if (fromX === toX) {\r\n // we need line to imaginary end of the year\r\n toX += (this.data.timeframe === TIMEFRAME.w ? 49 : 12) * barWidth\r\n }\r\n break\r\n }\r\n fromX = Math.max(fromX, -leftOffset)\r\n\r\n // render pivot line\r\n context.beginPath()\r\n line(fromX, toX, pivotPoint.pivot)\r\n context.stroke()\r\n\r\n // render resistance and support lines\r\n context.save()\r\n context.setLineDash([3, 3])\r\n context.beginPath()\r\n line(fromX, toX, pivotPoint.res1)\r\n line(fromX, toX, pivotPoint.res2)\r\n line(fromX, toX, pivotPoint.res3)\r\n line(fromX, toX, pivotPoint.sup1)\r\n line(fromX, toX, pivotPoint.sup2)\r\n line(fromX, toX, pivotPoint.sup3)\r\n context.stroke()\r\n context.restore()\r\n\r\n // render labels if there is enough space\r\n if (toX - fromX >= 48) {\r\n text('P', pivotPoint.pivot, fromX)\r\n text('R1', pivotPoint.res1, fromX)\r\n text('R2', pivotPoint.res2, fromX)\r\n text('R3', pivotPoint.res3, fromX)\r\n text('S1', pivotPoint.sup1, fromX)\r\n text('S2', pivotPoint.sup2, fromX)\r\n text('S3', pivotPoint.sup3, fromX)\r\n }\r\n }\r\n\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const calculationType = {\r\n type: 'select',\r\n label: 'Calculation Type',\r\n name: 'calculationType',\r\n value: this.attrs.calculationType ?? DEFAULT_PARAMETERS.CalculationType,\r\n required: true,\r\n items: [\r\n {\r\n value: 'standard',\r\n label: 'Standard',\r\n },\r\n {\r\n value: 'fibonacci',\r\n label: 'Fibonacci',\r\n },\r\n ],\r\n }\r\n const color = {\r\n type: 'color',\r\n label: 'Color',\r\n name: 'color',\r\n value: this.attrs.color ?? this.getFreeColor(),\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [calculationType, color],\r\n inputsErrorMessages: {},\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'calculationType':\r\n case 'color':\r\n return !!this.attrs[key]\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `Pivot Points (${Calculation[this.attrs.calculationType]})`\r\n }\r\n}\r\n\r\nPivotPoints.prototype.defaults = {\r\n calculationType: DEFAULT_PARAMETERS.CalculationType,\r\n color: DEFAULT_PARAMETERS.Color,\r\n}\r\n\r\nexport default PivotPoints\r\n","import { OverlayType } from '../constants/common'\r\nimport Overlay from './overlay'\r\n\r\ninterface Attrs {\r\n step: number\r\n period: string\r\n maxStep: number\r\n risingColor: string\r\n fallingColor: string\r\n}\r\n\r\nclass SAR extends Overlay {\r\n static type = OverlayType.Sar\r\n static label = 'Parabolic SAR'\r\n\r\n static getNumOfBarsBuffer() {\r\n return 0\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n if (typeof this.attrs.period === 'string' && (this.attrs.step === undefined || this.attrs.maxStep === undefined)) {\r\n const [step = 0, maxStep = 0] = this.attrs.period.split(',').map((x) => parseFloat(x))\r\n this.attrs.step = step\r\n this.attrs.maxStep = maxStep\r\n }\r\n this.trigger('change')\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const data = this.data\r\n const deltaHigh = data.high[1] - data.high[0]\r\n const deltaLow = data.low[0] - data.low[1]\r\n const pdm = deltaHigh > 0 && deltaHigh > deltaLow ? deltaHigh : 0\r\n const mdm = deltaLow > 0 && deltaLow > deltaHigh ? deltaLow : 0\r\n let isLong = pdm >= mdm\r\n\r\n let sar = isLong ? data.low[0] : data.high[0]\r\n let ep = isLong ? data.high[1] : data.low[1]\r\n let newHigh = data.high[0]\r\n let newLow = data.low[0]\r\n let af = this.attrs.step\r\n\r\n for (let i = 1, end = data.close.length, asc = end >= 1; asc ? i < end : i > end; asc ? i++ : i--) {\r\n let sarToDraw\r\n const prevHigh = newHigh\r\n const prevLow = newLow\r\n newHigh = data.high[i]\r\n newLow = data.low[i]\r\n\r\n if (isLong) {\r\n if (newLow <= sar) {\r\n isLong = false\r\n sar = ep\r\n\r\n if (sar < prevHigh) {\r\n sar = prevHigh\r\n }\r\n if (sar < newHigh) {\r\n sar = newHigh\r\n }\r\n\r\n sarToDraw = sar\r\n\r\n af = this.attrs.step\r\n ep = newLow\r\n\r\n sar = sar + af * (ep - sar)\r\n\r\n if (sar < prevHigh) {\r\n sar = prevHigh\r\n }\r\n if (sar < newHigh) {\r\n sar = newHigh\r\n }\r\n } else {\r\n sarToDraw = sar\r\n\r\n if (newHigh > ep) {\r\n ep = newHigh\r\n af += this.attrs.step\r\n if (af > this.attrs.maxStep) {\r\n af = this.attrs.maxStep\r\n }\r\n }\r\n\r\n sar = sar + af * (ep - sar)\r\n\r\n if (sar > prevLow) {\r\n sar = prevLow\r\n }\r\n if (sar > newLow) {\r\n sar = newLow\r\n }\r\n }\r\n } else {\r\n if (newHigh >= sar) {\r\n isLong = true\r\n sar = ep\r\n\r\n if (sar > prevLow) {\r\n sar = prevLow\r\n }\r\n if (sar > newLow) {\r\n sar = newLow\r\n }\r\n\r\n sarToDraw = sar\r\n\r\n af = this.attrs.step\r\n ep = newHigh\r\n\r\n sar = sar + af * (ep - sar)\r\n\r\n if (sar > prevLow) {\r\n sar = prevLow\r\n }\r\n if (sar > newLow) {\r\n sar = newLow\r\n }\r\n } else {\r\n sarToDraw = sar\r\n\r\n if (newLow < ep) {\r\n ep = newLow\r\n af += this.attrs.step\r\n if (af > this.attrs.maxStep) {\r\n af = this.attrs.maxStep\r\n }\r\n }\r\n\r\n sar = sar + af * (ep - sar)\r\n\r\n if (sar < prevHigh) {\r\n sar = prevHigh\r\n }\r\n if (sar < newHigh) {\r\n sar = newHigh\r\n }\r\n }\r\n }\r\n\r\n const x = Math.round(this.fx(i) - 1.5)\r\n const y = Math.round(this.fy(sarToDraw) - 1.5)\r\n context.set('fillStyle', isLong ? this.attrs.risingColor : this.attrs.fallingColor)\r\n context.fillRect(x, y, 3, 3)\r\n }\r\n }\r\n\r\n getModalConfig() {\r\n const step = {\r\n type: 'number',\r\n step: 0.01,\r\n min: 0.01,\r\n max: 999,\r\n label: 'Step',\r\n name: 'step',\r\n value: this.attrs.step ?? 0.02,\r\n required: true,\r\n }\r\n const maxStep = {\r\n type: 'number',\r\n step: 0.01,\r\n min: 0.01,\r\n max: 999,\r\n label: 'Maximum Step',\r\n name: 'maxStep',\r\n value: this.attrs.maxStep ?? 0.2,\r\n required: true,\r\n }\r\n const risingColor = {\r\n type: 'color',\r\n label: 'Rising Color',\r\n name: 'risingColor',\r\n value: this.attrs.risingColor ?? this.getFreeColor(),\r\n customizable: false,\r\n }\r\n const fallingColor = {\r\n type: 'color',\r\n label: 'Falling Color',\r\n name: 'fallingColor',\r\n value: this.attrs.fallingColor ?? this.getFreeColor(),\r\n customizable: false,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [step, maxStep, risingColor, fallingColor],\r\n inputsErrorMessages: {\r\n step: `${step.label} must be a number between ${step.min} and ${step.max}`,\r\n maxStep: `${maxStep.label} must be a number between ${maxStep.min} and ${maxStep.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'step':\r\n case 'maxStep': {\r\n return this.getIsNumberInputValid({ key, integerOnly: false })\r\n }\r\n case 'risingColor':\r\n case 'fallingColor':\r\n // Some users have wrong colors which break the form validation\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n getLabelColor() {\r\n return this.attrs.risingColor\r\n }\r\n\r\n toString() {\r\n return `SAR ${this.attrs.step},${this.attrs.maxStep}`\r\n }\r\n}\r\n\r\nSAR.prototype.defaults = {\r\n risingColor: '#69c1ea',\r\n fallingColor: '#d386df',\r\n}\r\n\r\nexport default SAR\r\n","import { OverlayType } from '../constants/common'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype Options = {\r\n period: number\r\n}\r\n\r\ntype DefaultCalculatedValuesType = {\r\n sma: number[]\r\n}\r\n\r\nexport class SMACalculation extends MainCalculation {\r\n static type = OverlayType.Sma\r\n declare options: Options\r\n\r\n getDefaultCalculatedValues() {\r\n return { sma: [] }\r\n }\r\n\r\n calculate(onValueCalculated?: OnValueCalculated) {\r\n const { close } = this.quote\r\n const lastIndex = close.length - 1\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n let sum = 0\r\n for (let i = 0; i < this.options.period; i++) {\r\n sum += close[i]\r\n }\r\n for (let i = this.options.period; i <= lastIndex; i++) {\r\n sum = sum - close[i - this.options.period] + close[i]\r\n this.calculatedValues.sma[i] = sum / this.options.period\r\n\r\n if (onValueCalculated?.(this.calculatedValues, i) === false) {\r\n break\r\n }\r\n }\r\n }\r\n}\r\n","import { ChartConfigChartPaneElement, RequireByKey } from '../../types/shared'\r\nimport { OverlayType } from '../constants/common'\r\nimport { SMACalculation } from '../indicator-calculation/sma'\r\nimport Overlay from './overlay'\r\n\r\ninterface Attrs {\r\n step: number\r\n period: string\r\n maxStep: number\r\n risingColor: string\r\n color: string\r\n}\r\n\r\nclass SMA extends Overlay {\r\n static type = OverlayType.Sma\r\n static label = 'Simple Moving Average'\r\n\r\n static getNumOfBarsBuffer(chartConfig: RequireByKey) {\r\n const numOfBarsBuffer = Overlay.getNumOfBarsBuffer(chartConfig)\r\n return numOfBarsBuffer + 1 // +1 offsets rendering so it doesn't start on first bar which doesn't look OK in SSR rendered charts\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n const { period } = obj\r\n if (typeof period === 'string') {\r\n this.attrs.period = parseInt(period, 10)\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const { leftOffset, width } = this.model.chart()\r\n const period = Math.min(this.attrs.period, this.data.close.length - 1)\r\n context.beginPath()\r\n context.translate(0.5, 0.5)\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', this.attrs.color)\r\n\r\n const smaCalculation = new SMACalculation({\r\n quote: this.data,\r\n options: { period },\r\n })\r\n\r\n smaCalculation.calculate(({ sma }, dataIndex) => {\r\n const x = this.fx(dataIndex)\r\n if (this.fx(dataIndex + 1) + leftOffset < 0) {\r\n return\r\n }\r\n if (this.fx(dataIndex - 1) + leftOffset > width) {\r\n return false\r\n }\r\n context.lineTo(x, Math.round(this.fy(sma[dataIndex])))\r\n })\r\n\r\n context.translate(-0.5, -0.5)\r\n context.stroke()\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.attrs.period ?? 5,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n const color = {\r\n type: 'color',\r\n label: 'Color',\r\n name: 'color',\r\n value: this.attrs.color ?? this.getFreeColor(),\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period, color],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n case 'color':\r\n return !!this.attrs[key] // use real color validation, we got isValidHexColor but it might be also RGBA\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `SMA ${this.attrs.period}`\r\n }\r\n}\r\n\r\nSMA.prototype.defaults = { color: '#ffa75f' }\r\n\r\nexport default SMA\r\n","import { OverlayType } from '../constants/common'\r\nimport SMA from './sma'\r\n\r\nclass SMA2 extends SMA {\r\n static type = OverlayType.Sma2\r\n}\r\n\r\nSMA2.prototype.defaults = { color: '#ff6400' }\r\n\r\nexport default SMA2\r\n","import { ChartConfigChartPaneElement, RequireByKey } from '../../types/shared'\r\nimport { OverlayType } from '../constants/common'\r\nimport AverageTrueRange from '../helpers/atr'\r\nimport Overlay from './overlay'\r\n\r\ninterface Attrs {\r\n period: number\r\n multiplier: number\r\n uptrendColor: string\r\n downtrendColor: string\r\n}\r\n\r\nconst DEFAULT_PARAMETERS = {\r\n Period: 7,\r\n Multiplier: 3.0,\r\n}\r\n\r\nconst COLORS = {\r\n Uptrend: '#00a000',\r\n Downtrend: '#c80000',\r\n}\r\n\r\nfunction parsePeriod(periodStr: string) {\r\n const values = periodStr.split(',')\r\n const period = parseInt(values[0]) || DEFAULT_PARAMETERS.Period\r\n const multiplier = parseFloat(values[1]) || DEFAULT_PARAMETERS.Multiplier\r\n\r\n return [period, multiplier]\r\n}\r\n\r\nclass Supertrend extends Overlay {\r\n static type = OverlayType.Str\r\n static label = 'Supertrend'\r\n\r\n static getNumOfBarsBuffer({ period }: RequireByKey) {\r\n const [periodInt] = parsePeriod(period)\r\n return periodInt + 1\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n const { period } = obj\r\n if (typeof period === 'string') {\r\n const [periodInt, multiplier] = parsePeriod(period)\r\n this.attrs.period = periodInt\r\n this.attrs.multiplier = multiplier\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const { leftOffset, width } = this.model.chart()\r\n const { period, multiplier } = this.attrs\r\n const { high, low, close } = this.data\r\n const atr = new AverageTrueRange(period)\r\n const finalUpperBand: number[] = []\r\n const finalLowerBand: number[] = []\r\n const supertrend: boolean[] = []\r\n let firstBarToRender\r\n let lastBarToRender = 0\r\n\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', this.attrs.uptrendColor)\r\n for (let i = 1; i < close.length; i++) {\r\n atr.add(high[i], low[i], close[i - 1])\r\n\r\n // compute bands\r\n const avg = (high[i] + low[i]) / 2\r\n const upperBand = avg + multiplier * atr.value\r\n const lowerBand = avg - multiplier * atr.value\r\n\r\n finalUpperBand[i] = upperBand\r\n finalLowerBand[i] = lowerBand\r\n\r\n // identify supertrend\r\n if (close[i] > finalUpperBand[i - 1]) {\r\n supertrend[i] = true\r\n } else if (close[i] < finalLowerBand[i - 1]) {\r\n supertrend[i] = false\r\n } else {\r\n supertrend[i] = supertrend[i - 1]\r\n }\r\n\r\n // adjust bands\r\n if (supertrend[i] && finalLowerBand[i] < finalLowerBand[i - 1]) {\r\n finalLowerBand[i] = finalLowerBand[i - 1]\r\n }\r\n if (!supertrend[i] && finalUpperBand[i] > finalUpperBand[i - 1]) {\r\n finalUpperBand[i] = finalUpperBand[i - 1]\r\n }\r\n\r\n const x = this.fx(i)\r\n if (i < period || x + leftOffset < 0) {\r\n continue\r\n }\r\n if (this.fx(i - 1) + leftOffset > width) {\r\n break\r\n }\r\n if (firstBarToRender === undefined) firstBarToRender = i\r\n\r\n if (supertrend[i] && !supertrend[i - 1]) {\r\n // buy\r\n context.moveTo(this.fx(i - 1), Math.round(this.fy(finalUpperBand[i - 1])))\r\n context.lineTo(x, Math.round(this.fy(finalLowerBand[i])))\r\n } else if (supertrend[i]) {\r\n // keep buying\r\n context.lineTo(x, Math.round(this.fy(finalLowerBand[i])))\r\n } else {\r\n // keep selling\r\n context.moveTo(x, Math.round(this.fy(finalLowerBand[i])))\r\n }\r\n lastBarToRender = i\r\n }\r\n context.stroke()\r\n\r\n if (firstBarToRender === undefined) {\r\n context.translate(-0.5, -0.5)\r\n return\r\n }\r\n\r\n context.beginPath()\r\n context.set('strokeStyle', this.attrs.downtrendColor)\r\n for (let i = firstBarToRender; i <= lastBarToRender; i++) {\r\n const x = this.fx(i)\r\n if (!supertrend[i] && supertrend[i - 1]) {\r\n // sell\r\n context.moveTo(this.fx(i - 1), Math.round(this.fy(finalLowerBand[i - 1])))\r\n context.lineTo(x, Math.round(this.fy(finalUpperBand[i])))\r\n } else if (!supertrend[i]) {\r\n // keep selling\r\n context.lineTo(x, Math.round(this.fy(finalUpperBand[i])))\r\n } else {\r\n // keep buying\r\n context.moveTo(x, Math.round(this.fy(finalUpperBand[i])))\r\n }\r\n }\r\n context.stroke()\r\n\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.attrs.period ?? DEFAULT_PARAMETERS.Period,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n const multiplier = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'multiplier',\r\n value: this.attrs.multiplier ?? DEFAULT_PARAMETERS.Multiplier,\r\n required: true,\r\n step: 0.1,\r\n min: 0.0,\r\n max: 999,\r\n }\r\n\r\n const uptrendColor = {\r\n type: 'color',\r\n label: 'Uptrend Color',\r\n name: 'uptrendColor',\r\n value: this.attrs.uptrendColor ?? this.getFreeColor(),\r\n }\r\n const downtrendColor = {\r\n type: 'color',\r\n label: 'Downtrend Color',\r\n name: 'downtrendColor',\r\n value: this.attrs.downtrendColor ?? this.getFreeColor(),\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period, multiplier, uptrendColor, downtrendColor],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n multiplier: `${multiplier.label} must be a number between ${multiplier.min} and ${multiplier.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n case 'multiplier':\r\n return this.getIsNumberInputValid({ key, integerOnly: false })\r\n case 'uptrendColor':\r\n case 'downtrendColor':\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n getLabelColor(): string {\r\n return this.attrs.uptrendColor\r\n }\r\n\r\n toString() {\r\n return `Supertrend ${this.attrs.period},${this.attrs.multiplier}`\r\n }\r\n}\r\n\r\nSupertrend.prototype.defaults = {\r\n uptrendColor: COLORS.Uptrend,\r\n downtrendColor: COLORS.Downtrend,\r\n}\r\n\r\nexport default Supertrend\r\n","import * as d3 from 'd3'\r\n\r\nimport { ChartConfigChartPaneElement, RequireByKey } from '../../types/shared'\r\nimport { OverlayType } from '../constants/common'\r\nimport Chart from '../models/chart'\r\nimport utils from '../utils'\r\nimport { convertColorToHEX, getHEXWithSpecificAplha } from '../utils/colors'\r\nimport { getAreNoBarsVisible, getVisibleBarToRenderIndex } from '../utils/draw_in_visible_area'\r\nimport { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport Overlay from './overlay'\r\n\r\nconst VP_COLORS = {\r\n UP: '#00FF00',\r\n DOWN: '#FF0000',\r\n}\r\n\r\nconst DEFAULT_PARAMETERS = {\r\n Period: 20,\r\n Opacity: 0.3,\r\n}\r\n\r\ninterface Attrs {\r\n period: number | string\r\n opacity: number\r\n upColor?: string\r\n downColor?: string\r\n}\r\n\r\nfunction applyOpacityToColor(color: string, opacity: number) {\r\n return getHEXWithSpecificAplha(convertColorToHEX(color), opacity)\r\n}\r\n\r\nfunction getColorsWithAppliedOpacity(attrs: Attrs) {\r\n return [\r\n applyOpacityToColor(attrs.upColor ?? VP_COLORS.UP, attrs.opacity),\r\n applyOpacityToColor(attrs.downColor ?? VP_COLORS.DOWN, attrs.opacity),\r\n ]\r\n}\r\n\r\n// Only time when we want value to be able to equal start of segment is first segment,\r\n// because start of next segment is equal to end of previous and value would match two segments\r\nfunction isInSegment(val: number, start: number, end: number, notEqualStart: boolean) {\r\n return (notEqualStart ? val > start : val >= start) && val <= end\r\n}\r\n\r\nfunction parsePeriod(periodStr: string) {\r\n const values = periodStr.split(',')\r\n const period = parseInt(values[0]) || DEFAULT_PARAMETERS.Period\r\n const opacity = parseFloat(values[1]) || DEFAULT_PARAMETERS.Opacity\r\n\r\n return [period, opacity]\r\n}\r\n\r\nclass VolumeProfile extends Overlay {\r\n static type = OverlayType.Vp\r\n static label = 'Volume Profile'\r\n\r\n static getNumOfBarsBuffer({ period }: RequireByKey) {\r\n const [periodInt = 0] = getParsedIntegersFromPeriodString(period)\r\n return periodInt + 1 // +1 offsets rendering so it doesn't start on first bar which doesn't look OK in SSR rendered charts\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n const { period } = obj\r\n if (typeof period === 'string') {\r\n const [periodInt, opacity] = parsePeriod(period)\r\n this.attrs.period = periodInt\r\n this.attrs.opacity = opacity\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n if (typeof this.attrs.period !== 'number') {\r\n return\r\n }\r\n super.renderContent()\r\n\r\n const chartModel = this.model.chart() as Chart\r\n const { leftOffset, width } = chartModel\r\n const { left, right } = chartModel.getChartLayoutSettings().ChartSettings\r\n const chartWidth = width - left.width - right.width\r\n\r\n if (this.data.close.length === 0) return\r\n\r\n const firstBarToRender = getVisibleBarToRenderIndex({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset,\r\n })\r\n\r\n const lastBarToRender = getVisibleBarToRenderIndex({\r\n quote: this.data,\r\n paneModel: this.model,\r\n leftOffset,\r\n chartWidth,\r\n })\r\n\r\n const areNoBarsVisible = getAreNoBarsVisible(firstBarToRender, lastBarToRender)\r\n if (areNoBarsVisible) return\r\n\r\n const [upColor, downColor] = getColorsWithAppliedOpacity(this.attrs)\r\n const [minClose, maxClose] = utils.minMax(this.data.close.slice(firstBarToRender.index, lastBarToRender.index + 1))\r\n\r\n const segment = Math.abs(maxClose - minClose) / this.attrs.period\r\n const segments = [] // create an empty array to hold the segments\r\n\r\n for (let i = 0; i < this.attrs.period; i++) {\r\n const segmentStart = minClose + segment * i // calculate start of current segment\r\n const segmentEnd = segmentStart + segment // calculate end of current segment\r\n segments.push({ start: segmentStart, end: segmentEnd, up: 0, down: 0 }) // add segment to array\r\n }\r\n\r\n // loop through visible bars and assign volumes to segments\r\n for (let i = firstBarToRender.index; i <= lastBarToRender.index; i++) {\r\n const segmentIndex: number = segments.findIndex((item, segmentIndex) =>\r\n isInSegment(this.data.close[i], item.start, item.end, !!segmentIndex)\r\n )\r\n if (segmentIndex === -1) continue\r\n const volumeTrend = this.data.close[i] < this.data.open[i] ? 'down' : 'up'\r\n segments[segmentIndex][volumeTrend] += this.data.volume[i]\r\n }\r\n\r\n const max = utils.max(segments.map((item) => item.up + item.down))\r\n const rangeMax = chartWidth * 0.4 // maximum range in pixels where longest bar would reach (now it's 40% of chart width)\r\n const volumeFX = d3.scaleLinear().range([0, rangeMax]).domain([0, max])\r\n\r\n segments.forEach((item) => {\r\n const y = Math.round(this.fy(item.start))\r\n const segmentHeightRaw = Math.round(this.fy(item.end)) - y // raw segment height without gap between segments\r\n const segmentHeight = segmentHeightRaw + (Math.abs(segmentHeightRaw) > 5 ? 2 : 1) // apply gap to segment based on how high segment is\r\n const x = Math.abs(leftOffset) // segments are alligned to left side of chart which equal to absoulute value of leftOffset\r\n const upSegmentWidth = Math.round(volumeFX(item.up))\r\n const downSegmentWidth = Math.round(volumeFX(item.down))\r\n\r\n context.fillStyle = upColor\r\n context.fillRect(x, y, upSegmentWidth, segmentHeight)\r\n context.fillStyle = downColor\r\n context.fillRect(x + upSegmentWidth, y, downSegmentWidth, segmentHeight)\r\n })\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Zones',\r\n name: 'period',\r\n value: this.attrs.period ?? DEFAULT_PARAMETERS.Period,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n const opacity = {\r\n type: 'number',\r\n label: 'Opacity',\r\n name: 'opacity',\r\n value: this.attrs.opacity ?? DEFAULT_PARAMETERS.Opacity,\r\n required: true,\r\n min: 0,\r\n max: 1,\r\n step: 0.1,\r\n }\r\n const upColor = {\r\n type: 'color',\r\n label: 'Up Color',\r\n name: 'upColor',\r\n value: this.attrs.upColor ?? VP_COLORS.UP,\r\n }\r\n const downColor = {\r\n type: 'color',\r\n label: 'Down Color',\r\n name: 'downColor',\r\n value: this.attrs.downColor ?? VP_COLORS.DOWN,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period, opacity, upColor, downColor],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n opacity: `${opacity.label} must be a number between ${opacity.min} and ${opacity.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n case 'opacity':\r\n return this.getIsNumberInputValid({ key, integerOnly: false })\r\n case 'upColor':\r\n case 'downColor':\r\n // Some users have wrong colors which break the form validation\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n getLabelColor() {\r\n return this.attrs.upColor || VP_COLORS.UP\r\n }\r\n\r\n toString() {\r\n return `VP ${this.attrs.period}`\r\n }\r\n}\r\n\r\nVolumeProfile.prototype.defaults = { upColor: VP_COLORS.UP, downColor: VP_COLORS.DOWN }\r\n\r\nexport default VolumeProfile\r\n","import { OverlayType } from '../constants/common'\r\nimport { dateFromUnixTimestamp } from '../utils'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype Options = {\r\n period: number\r\n}\r\n\r\nconst datesAreOnSameDay = (first: Date, second: Date) =>\r\n first.getFullYear() === second.getFullYear() &&\r\n first.getMonth() === second.getMonth() &&\r\n first.getDate() === second.getDate()\r\n\r\ntype DefaultCalculatedValuesType = {\r\n vwap: number[]\r\n}\r\n\r\nexport class VWapCalculation extends MainCalculation {\r\n static type = OverlayType.Vwap\r\n\r\n getDefaultCalculatedValues() {\r\n return { vwap: [] }\r\n }\r\n\r\n calculate(onValueCalculated?: OnValueCalculated) {\r\n const { date, close, low, high, volume } = this.quote\r\n const lastIndex = date.length - 1\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n let cumulativePV = 0\r\n let cumulativeVolume = 0\r\n\r\n for (let i = 0; i <= lastIndex; i++) {\r\n if (i > 0) {\r\n const prevDate = dateFromUnixTimestamp(date[i - 1])\r\n if (!datesAreOnSameDay(prevDate, dateFromUnixTimestamp(date[i]))) {\r\n cumulativePV = 0\r\n cumulativeVolume = 0\r\n }\r\n }\r\n\r\n const typicalPrice = (close[i] + low[i] + high[i]) / 3\r\n const pv = typicalPrice * volume[i]\r\n\r\n cumulativePV += pv\r\n cumulativeVolume += volume[i]\r\n\r\n this.calculatedValues.vwap[i] = cumulativePV / cumulativeVolume\r\n\r\n if (onValueCalculated?.(this.calculatedValues, i) === false) {\r\n break\r\n }\r\n }\r\n }\r\n}\r\n","import { OverlayType } from '../constants/common'\r\nimport { VWapCalculation } from '../indicator-calculation/vwap'\r\nimport PaneModel from '../models/pane'\r\nimport Overlay from './overlay'\r\n\r\ninterface Attrs {\r\n period: number\r\n color: string\r\n}\r\n\r\nclass VWAP extends Overlay {\r\n static type = OverlayType.Vwap\r\n static label = 'VWAP (intraday charts)'\r\n\r\n static getNumOfBarsBuffer() {\r\n return 1\r\n }\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.attrs.period = 5\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n if (!this.isRendered()) {\r\n return\r\n }\r\n\r\n const { leftOffset, width } = this.model.chart()\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', this.attrs.color)\r\n\r\n const vwapCalculation = new VWapCalculation({\r\n quote: this.data,\r\n options: { period: this.attrs.period },\r\n })\r\n\r\n vwapCalculation.calculate(({ vwap }, dataIndex) => {\r\n const x = this.fx(dataIndex)\r\n if (this.fx(dataIndex + 1) + leftOffset < 0) {\r\n return // continue\r\n }\r\n if (this.fx(dataIndex - 1) + leftOffset > width) {\r\n return false // break\r\n }\r\n const y = Math.round(this.fy(vwap[dataIndex]))\r\n context.lineTo(x, y)\r\n })\r\n\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const color = {\r\n type: 'color',\r\n label: 'Color',\r\n name: 'color',\r\n value: this.attrs.color ?? this.getFreeColor(),\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [color],\r\n inputsErrorMessages: {},\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'color':\r\n // Some users have wrong colors which break the form validation\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n isRendered() {\r\n return this.model.chart().quote().isIntraday\r\n }\r\n\r\n isRenderedOverlaysLabel() {\r\n return this.isRendered()\r\n }\r\n\r\n toString() {\r\n return `VWAP`\r\n }\r\n}\r\n\r\nVWAP.prototype.defaults = { color: '#9467bd' }\r\n\r\nexport default VWAP\r\n","import { OverlayType } from '../constants/common'\r\nimport bb from './bb'\r\nimport dch from './dch'\r\nimport ema from './ema'\r\nimport ema2 from './ema2'\r\nimport hilo from './hilo'\r\nimport hline from './hline'\r\nimport ic from './ic'\r\nimport icf from './icf'\r\nimport kch from './kch'\r\nimport none from './none'\r\nimport overlay from './overlay'\r\nimport patterns from './patterns'\r\nimport pp from './pp'\r\nimport sar from './sar'\r\nimport sma from './sma'\r\nimport sma2 from './sma2'\r\nimport str from './str'\r\nimport vp from './vp'\r\nimport vwap from './vwap'\r\n\r\nexport const overlaysByType = Object.freeze({\r\n [OverlayType.Overlay]: overlay,\r\n [OverlayType.None]: none,\r\n [OverlayType.Bb]: bb,\r\n [OverlayType.Dch]: dch,\r\n [OverlayType.Ema]: ema,\r\n [OverlayType.Ema2]: ema2,\r\n [OverlayType.Hilo]: hilo,\r\n [OverlayType.Hline]: hline,\r\n [OverlayType.Ic]: ic,\r\n [OverlayType.Icf]: icf,\r\n [OverlayType.Kch]: kch,\r\n [OverlayType.Patterns]: patterns,\r\n [OverlayType.Pp]: pp,\r\n [OverlayType.Sar]: sar,\r\n [OverlayType.Sma]: sma,\r\n [OverlayType.Sma2]: sma2,\r\n [OverlayType.Str]: str,\r\n [OverlayType.Vp]: vp,\r\n [OverlayType.Vwap]: vwap,\r\n})\r\n","import {\r\n MOBILE_VIEW_BREAKPOINT_WIDTH,\r\n PREMARKET_AFTERMARKET_HOURS,\r\n SpecificChartFunctionality,\r\n} from './constants/common'\r\nimport { captureException, getIsSSr } from './utils/helpers'\r\n\r\nexport { getSanitizedTicker } from './utils/ticker-sanitizer'\r\n\r\nfunction getIsDstInNy(date: Date) {\r\n const dayNumber = date.getDate()\r\n const monthIndex = date.getMonth()\r\n const dayOfWeek = date.getDay()\r\n const previousSunday = dayNumber - dayOfWeek\r\n if (monthIndex < 2 || monthIndex > 10) {\r\n return false\r\n }\r\n if (monthIndex > 2 && monthIndex < 10) {\r\n return true\r\n }\r\n return monthIndex === 2 ? previousSunday >= 8 : previousSunday <= 0\r\n}\r\n\r\nclass Utils {\r\n static min(...args: T[]): number {\r\n if (typeof args[0] === 'number') {\r\n return args[0] < +args[1] ? args[0] : (args[1] as number)\r\n }\r\n let min = args[0][0]\r\n for (const arg of args) {\r\n for (const el of arg as number[]) {\r\n if (el < min) {\r\n min = el\r\n }\r\n }\r\n }\r\n return min\r\n }\r\n\r\n static max(...args: T[]): number {\r\n if (typeof args[0] === 'number') {\r\n return args[0] > +args[1] ? args[0] : (args[1] as number)\r\n }\r\n let max = args[0][0]\r\n for (const arg of args) {\r\n for (const el of arg as number[]) {\r\n if (el > max) {\r\n max = el\r\n }\r\n }\r\n }\r\n return max\r\n }\r\n\r\n static minMax(...args: number[][]) {\r\n let max\r\n let min = (max = args[0][0] as number)\r\n for (const arg of args) {\r\n for (const el of arg) {\r\n if (el < min) {\r\n min = el\r\n }\r\n if (el > max) {\r\n max = el\r\n }\r\n }\r\n }\r\n return [min, max]\r\n }\r\n\r\n static getScaleRatio() {\r\n return (typeof window !== 'undefined' && window.devicePixelRatio) || 1\r\n }\r\n\r\n static setSizeOnCanvasElement({\r\n canvasElement,\r\n width,\r\n height,\r\n ratio = Utils.getScaleRatio(),\r\n }: {\r\n canvasElement: HTMLCanvasElement | null\r\n width: number\r\n height: number\r\n ratio?: number\r\n }) {\r\n if (canvasElement) {\r\n canvasElement.width = width * ratio\r\n canvasElement.height = height * ratio\r\n canvasElement.style.width = width + 'px'\r\n canvasElement.style.height = height + 'px'\r\n }\r\n }\r\n\r\n static getQuoteDateTimestampOffsetInSeconds(referenceDate?: Date) {\r\n const date = referenceDate || new Date()\r\n const dateAsNY = new Date(\r\n date.getUTCFullYear(),\r\n date.getUTCMonth(),\r\n date.getUTCDate(),\r\n date.getUTCHours() - 5,\r\n date.getUTCMinutes(),\r\n date.getUTCSeconds()\r\n )\r\n const isDst = getIsDstInNy(dateAsNY)\r\n return (isDst ? 4 : 5) * 60 * 60\r\n }\r\n\r\n static convertLocalToNyTime(referenceDate: Date, addOffset: boolean) {\r\n const date = new Date(referenceDate)\r\n const quoteDateTimeOffsetInMs = Utils.getQuoteDateTimestampOffsetInSeconds(date) * 1000\r\n const localTimeOffsetInMs = date.getTimezoneOffset() * 60 * 1000\r\n const offsetDirectionCoefficient = addOffset ? 1 : -1\r\n date.setTime(date.getTime() + (localTimeOffsetInMs - quoteDateTimeOffsetInMs) * offsetDirectionCoefficient)\r\n return date\r\n }\r\n\r\n // Keep in sync with the clone in Website repo in shared/isStockFastRefreshAvailable.ts\r\n static isStockFastRefreshAvailable(hasPremarket = true, hasAftermarket = true, bufferMinutes = 30) {\r\n const MARKET_START = { hours: 9, minutes: 30 }\r\n const MARKET_END = { hours: 16, minutes: 0 }\r\n const getMinutes = ({ hours, minutes }: { hours: number; minutes: number }) => hours * 60 + minutes\r\n\r\n const date = convertLocalToNyTime(new Date(), true)\r\n const dayOfWeek = date.getDay()\r\n const currentDayMinutes = date.getHours() * 60 + date.getMinutes()\r\n\r\n const premarketMinutes = hasPremarket ? PREMARKET_AFTERMARKET_HOURS * 60 : 0\r\n const aftermarketMinutes = hasAftermarket ? PREMARKET_AFTERMARKET_HOURS * 60 : 0\r\n\r\n const isWeekend = dayOfWeek === 0 || dayOfWeek === 6\r\n const isOpen = getMinutes(MARKET_START) - premarketMinutes - bufferMinutes <= currentDayMinutes\r\n const isClosed = getMinutes(MARKET_END) + aftermarketMinutes + bufferMinutes <= currentDayMinutes\r\n return !isWeekend && isOpen && !isClosed\r\n }\r\n\r\n static dateFromUnixTimestamp(timestamp: number) {\r\n /*\r\n * Passing 0 as a param is needed in order to setUTCSeconds work properly.\r\n * The function adds seconds to the date instance if it exceeds 60.\r\n * For more info see the docs https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setUTCSeconds\r\n * */\r\n const date = new Date(0)\r\n date.setUTCSeconds(timestamp)\r\n return Utils.convertLocalToNyTime(date, true)\r\n }\r\n\r\n static dateStringFromDate(date: Date) {\r\n return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(\r\n 2,\r\n '0'\r\n )}`\r\n }\r\n\r\n static dateFromDateString(dateString: string) {\r\n const [yyyy, mm, dd] = dateString.split('-')\r\n\r\n const date = new Date(Number.parseInt(yyyy), Number.parseInt(mm) - 1, Number.parseInt(dd))\r\n if (Number.isNaN(date.getTime())) {\r\n captureException(new Error('Invalid Date'), { extra: { date, dateString } })\r\n }\r\n\r\n return date\r\n }\r\n\r\n static isMobile(testTouchPoints?: boolean) {\r\n if (getIsSSr()) return false\r\n let isMobileOs = false\r\n\r\n // New iOS versions no longer report iPad in user agent\r\n if (navigator.userAgent.indexOf('Macintosh') > -1) {\r\n try {\r\n document.createEvent('TouchEvent')\r\n isMobileOs = true\r\n } catch (e) {}\r\n } else {\r\n isMobileOs = !!navigator.userAgent.match(\r\n /\\b(Android|webOS|i(?:Phone|Pad|Pod)|BlackBerry|Windows (?:Phone|Mobile))\\b/i\r\n )\r\n }\r\n\r\n if (testTouchPoints) {\r\n try {\r\n return (\r\n isMobileOs &&\r\n (window.navigator.msMaxTouchPoints ||\r\n window.navigator.maxTouchPoints ||\r\n 'ontouchstart' in document.createElement('div'))\r\n )\r\n } catch (e) {}\r\n }\r\n\r\n return isMobileOs\r\n }\r\n\r\n static isIPad() {\r\n const matchesIPad = navigator.userAgent.match(/iPad/i)\r\n const matchesIPhone = navigator.userAgent.match(/iPhone/i)\r\n const matchesIPod = navigator.userAgent.match(/iPod/i)\r\n const matchesIOSLike = navigator.userAgent.match(/Mac/) && navigator.maxTouchPoints > 0\r\n\r\n return (matchesIOSLike && !matchesIPhone && !matchesIPod) || matchesIPad\r\n }\r\n\r\n static getCookie(name: string) {\r\n const re = new RegExp('(?:(?:^|.*;\\\\s*)' + name + '\\\\s*\\\\=\\\\s*([^;]*).*$)|^.*$')\r\n return document.cookie.replace(re, '$1')\r\n }\r\n\r\n static setCookie(name: string, value: string, expires: Date) {\r\n let cookie = name + '=' + value + '; expires=' + expires.toUTCString()\r\n if (document.location.hostname !== 'localhost') {\r\n cookie += '; domain=.finviz.com'\r\n }\r\n document.cookie = cookie\r\n }\r\n}\r\n\r\nexport default Utils\r\nexport const convertLocalToNyTime = Utils.convertLocalToNyTime\r\nexport const dateFromUnixTimestamp = Utils.dateFromUnixTimestamp\r\nexport const dateStringFromDate = Utils.dateStringFromDate\r\nexport const dateFromDateString = Utils.dateFromDateString\r\n\r\nexport function getFullscreenStatus(): boolean {\r\n return (\r\n document.fullscreenElement ??\r\n document.webkitFullscreenElement ??\r\n document.mozFullScreenElement ??\r\n document.msFullscreenElement ??\r\n false\r\n )\r\n}\r\n\r\nexport function getRequestFullscreen(element: HTMLElement) {\r\n return (\r\n element.requestFullscreen ??\r\n element.webkitRequestFullScreen ??\r\n element.mozRequestFullScreen ??\r\n element.msRequestFullscreen\r\n )\r\n}\r\n\r\nexport function getExitFullscreen() {\r\n return (\r\n document.exitFullscreen ?? document.webkitExitFullscreen ?? document.mozExitFullScreen ?? document.msExitFullscreen\r\n )\r\n}\r\n\r\nexport function ready(fn: () => void) {\r\n if (document.readyState !== 'loading') {\r\n fn()\r\n return\r\n }\r\n\r\n document.addEventListener('DOMContentLoaded', fn)\r\n}\r\n\r\nexport function getChartsDimensions(chartElementId: string) {\r\n const PADDING = 2 // Border widths\r\n const containerElement = document.getElementById(chartElementId)\r\n\r\n const box = containerElement?.getBoundingClientRect()\r\n\r\n return {\r\n width: Math.max((box?.width ?? 0) - PADDING, 0),\r\n height: Math.max((box?.height ?? 0) - PADDING, 0),\r\n }\r\n}\r\n\r\nexport function getIsMobileScreenSize() {\r\n return window.innerWidth < MOBILE_VIEW_BREAKPOINT_WIDTH\r\n}\r\n\r\nexport function getIsMobilePortrait(isMobile?: boolean) {\r\n if (isMobile ?? Utils.isMobile()) {\r\n return window.orientation % 180 === 0\r\n }\r\n return false\r\n}\r\n\r\nexport function numberToStringWithUnitsSuffix(value: number) {\r\n let suffix = ''\r\n if (value >= 1000000000) {\r\n value /= 1000000000\r\n suffix = 'B'\r\n } else if (value >= 1000000) {\r\n value /= 1000000\r\n suffix = 'M'\r\n } else if (value >= 1000) {\r\n value /= 1000\r\n suffix = 'K'\r\n }\r\n\r\n return value.toFixed(2) + suffix\r\n}\r\n\r\nexport function isRedesignEnabled() {\r\n return typeof window !== 'undefined' && window.FinvizSettings?.hasRedesignEnabled\r\n}\r\n\r\nexport function isRedesignedPage(\r\n obj: { specificChartFunctionality?: SpecificChartFunctionality | null },\r\n matchingPages = [\r\n SpecificChartFunctionality.forexPage,\r\n SpecificChartFunctionality.futuresPage,\r\n SpecificChartFunctionality.cryptoPage,\r\n ]\r\n) {\r\n return (\r\n (isRedesignEnabled() && matchingPages.includes(obj.specificChartFunctionality!)) ||\r\n // Legacy design on quote uses redesigned elements (page header + chart controls)\r\n obj.specificChartFunctionality === SpecificChartFunctionality.quotePage\r\n )\r\n}\r\n","import { ObjectHash } from '../../types/shared'\r\n\r\nconst requestsAbortControllersCache: ObjectHash = {}\r\n\r\nexport function removeFromAbortCache(key: string) {\r\n delete requestsAbortControllersCache[key]\r\n}\r\n\r\nexport function abortRequest(key: string) {\r\n requestsAbortControllersCache[key]?.abort()\r\n removeFromAbortCache(key)\r\n}\r\n\r\nexport function getIsAbortError(error: Error) {\r\n return error.name === 'AbortError'\r\n}\r\n\r\nexport function createRequestAbortController({\r\n key,\r\n shouldAbortRunningRequest = false,\r\n}: {\r\n key: string\r\n shouldAbortRunningRequest?: boolean\r\n}) {\r\n if (shouldAbortRunningRequest) {\r\n abortRequest(key)\r\n }\r\n const controller = 'AbortController' in window ? new AbortController() : undefined\r\n if (controller) {\r\n requestsAbortControllersCache[key] = controller\r\n }\r\n return controller\r\n}\r\n","import * as websiteShared from '@finviz/website'\r\n\r\nimport { captureException } from './helpers'\r\n\r\n/**\r\n * Hook used to asynchronously load a module\r\n *\r\n * Usage: [wiki](https://github.com/finvizhq/Finviz-Website/wiki/Loading-modules-asynchronously#useasyncmodule)\r\n */\r\nexport const useAsyncModule = (\r\n props: {\r\n importFn: () => Promise\r\n onError?: () => void\r\n cacheKey: string\r\n captureException?: (exception: Error, captureContext?: { extra: Record }) => void\r\n errorSeverity?: 'medium' | 'high'\r\n } & (websiteShared.ControlledModuleConfig | websiteShared.SuspenseModuleConfig)\r\n) =>\r\n websiteShared.useAsyncModule({ captureException, ...props }) as [\r\n SuspenseMode extends true ? T : T | null,\r\n { isLoading: boolean; loadModule: () => Promise; isError: boolean },\r\n ]\r\n","import { getIsSSr } from './helpers'\r\n\r\n// Extracted from isMobile, and modified to fit usage\r\nfunction isFirefoxDesktop() {\r\n const matchesAndroid = navigator.userAgent.match(/Android/i)\r\n const matchesWebOS = navigator.userAgent.match(/webOS/i)\r\n const matchesIPhone = navigator.userAgent.match(/iPhone/i)\r\n const matchesiPad = navigator.userAgent.match(/iPad/i)\r\n const matchesIPod = navigator.userAgent.match(/iPod/i)\r\n const matchesBlackBerry = navigator.userAgent.match(/BlackBerry/i)\r\n const matchesWindowsPhone = navigator.userAgent.match(/Windows Phone/i)\r\n const matchesIOSLike = navigator.userAgent.match(/Mac/) && navigator.maxTouchPoints > 0\r\n\r\n const isMobileDevice =\r\n matchesAndroid ||\r\n matchesWebOS ||\r\n matchesIPhone ||\r\n matchesiPad ||\r\n matchesIPod ||\r\n matchesBlackBerry ||\r\n matchesWindowsPhone ||\r\n matchesIOSLike\r\n\r\n const matchesFirefox = !!navigator.userAgent.match(/firefox/i)\r\n\r\n return matchesFirefox && !isMobileDevice\r\n}\r\n\r\n// Due bug in FireFox, when if HW acceleration is used canvas is blurry\r\n// we need to set canvas as CPU only\r\nconst shouldUseCPUOnly = getIsSSr() ? false : isFirefoxDesktop()\r\n\r\nexport function getContextWithCache(canvas: HTMLCanvasElement | null): CanvasRenderingContext2D | null {\r\n if (!canvas) {\r\n return null\r\n }\r\n\r\n const context = canvas.getContext('2d', shouldUseCPUOnly ? { willReadFrequently: true } : undefined)\r\n if (!context) {\r\n window.Sentry?.captureMessage('Context unavailable')\r\n return null\r\n }\r\n\r\n context._cache = {}\r\n\r\n const _restore = CanvasRenderingContext2D.prototype.restore\r\n context.restore = function () {\r\n this._cache = {}\r\n return _restore.apply(this)\r\n }\r\n\r\n context.set = function (key, value) {\r\n if (this._cache[key] !== value) {\r\n this[key] = value\r\n this._cache[key] = value\r\n }\r\n }\r\n\r\n return context\r\n}\r\n","import { Theme } from '../../types/shared'\r\nimport twColors from '../constants/colors'\r\nimport { ChartEventType } from '../constants/common'\r\nimport math, { BIG_NUMBER_VALUES, BigNumber } from '../helpers/math'\r\nimport utils from '../utils'\r\nimport { formatDateToStringUS } from '../utils/helpers'\r\n\r\ninterface IChartEventBase {\r\n elementId: string\r\n eventType: ChartEventType\r\n dateTimestamp: number // represent 'earningsDate' column of earnings and 'exdate' column for dividends & split\r\n}\r\n\r\nexport interface IEarnings extends IChartEventBase {\r\n epsActual?: number\r\n epsEstimate?: number\r\n epsReportedActual?: number\r\n epsReportedEstimate?: number\r\n fiscalEndDate: number\r\n fiscalPeriod: string\r\n salesActual?: number\r\n salesEstimate?: number\r\n}\r\n\r\nexport interface IDividends extends IChartEventBase {\r\n ordinary: number\r\n special: number\r\n}\r\n\r\nexport interface ISplit extends IChartEventBase {\r\n factorFrom: number\r\n factorTo: number\r\n}\r\n\r\nexport enum ChartEventBadgeState {\r\n default = 'default',\r\n hover = 'hover',\r\n selected = 'selected',\r\n}\r\n\r\nexport interface IChartEventBadgeProps {\r\n theme: Theme\r\n state: ChartEventBadgeState\r\n width: number\r\n}\r\n\r\ninterface IGetChartEventBadgeColors {\r\n theme: Theme\r\n state: ChartEventBadgeState\r\n colors: IBadgeColors\r\n}\r\n\r\ninterface IBadgeStateColors {\r\n default: string\r\n hover: string\r\n selected: string\r\n}\r\n\r\ninterface IBadgeThemeColors {\r\n outerStroke: string\r\n innerStroke: string\r\n innerFill: IBadgeStateColors\r\n textFill: IBadgeStateColors\r\n}\r\n\r\ninterface IBadgeColors {\r\n light: IBadgeThemeColors\r\n dark: IBadgeThemeColors\r\n}\r\n\r\nexport function getChartEventBadgeColors({ theme, state, colors }: IGetChartEventBadgeColors) {\r\n return {\r\n outerStroke: colors[theme].outerStroke,\r\n innerStroke: colors[theme].innerStroke,\r\n innerFill: colors[theme].innerFill[state],\r\n textFill: colors[theme].textFill[state],\r\n }\r\n}\r\n\r\nexport function getFormattedEventDate(\r\n exdate: number,\r\n hasEarningsDateSuffix = false,\r\n options: ObjectHash = {\r\n month: 'short',\r\n }\r\n) {\r\n const parsedDate = utils.dateFromUnixTimestamp(exdate)\r\n\r\n const hours = parsedDate.getHours()\r\n const formattedDate = formatDateToStringUS(parsedDate, options)\r\n\r\n if (hasEarningsDateSuffix) {\r\n let suffix = ''\r\n\r\n if (hours <= 9) {\r\n suffix = 'BMO'\r\n } else if (hours >= 16) {\r\n suffix = 'AMC'\r\n }\r\n\r\n return `${formattedDate} ${suffix}`\r\n }\r\n\r\n return formattedDate\r\n}\r\n\r\nexport function getFormattedValue({\r\n value,\r\n bigNumberUnit,\r\n maxDecimalPlaces = 3,\r\n}: {\r\n value: number\r\n bigNumberUnit?: BigNumber\r\n maxDecimalPlaces?: number\r\n}) {\r\n let numberString = ''\r\n let suffix = ''\r\n\r\n if (bigNumberUnit === undefined) {\r\n numberString = math.round({ value, overridePlaces: 3 })\r\n } else {\r\n const bigNumber = math.formatBigNumber(value * BIG_NUMBER_VALUES[bigNumberUnit], 3, BigNumber.Million)\r\n numberString = parseFloat(bigNumber.substring(0, bigNumber.length - 1)).toString() // parseFloat with toString are removing trailing zeroes\r\n suffix = bigNumber.substring(bigNumber.length - 1)\r\n }\r\n\r\n const [wholeNumber, decimalNumber] = numberString.split('.')\r\n\r\n if (decimalNumber === undefined) return `${wholeNumber}${suffix}`\r\n\r\n let formattedDecimalNumber = decimalNumber\r\n if (maxDecimalPlaces === 2 || decimalNumber[decimalNumber.length - 1] === '0') {\r\n formattedDecimalNumber = decimalNumber.slice(0, -1)\r\n }\r\n\r\n return `${[wholeNumber, formattedDecimalNumber].join('.')}${suffix}`\r\n}\r\n\r\nexport function getChartEventBageColors(colorKey: 'violet' | 'blue' | 'red' | 'gray' | 'purple' | 'green') {\r\n return {\r\n light: {\r\n outerStroke: twColors.white,\r\n innerStroke: twColors[colorKey][400],\r\n innerFill: {\r\n default: twColors[colorKey][50],\r\n hover: twColors[colorKey][100],\r\n selected: twColors[colorKey][400],\r\n },\r\n textFill: {\r\n default: twColors[colorKey][500],\r\n hover: twColors[colorKey][600],\r\n selected: twColors.white,\r\n },\r\n },\r\n dark: {\r\n outerStroke: twColors.gray[900],\r\n innerStroke: twColors[colorKey][400],\r\n innerFill: {\r\n default: twColors[colorKey][800],\r\n hover: twColors[colorKey][600],\r\n selected: twColors[colorKey][400],\r\n },\r\n textFill: {\r\n default: twColors.white,\r\n hover: twColors.white,\r\n selected: twColors.white,\r\n },\r\n },\r\n } as IBadgeColors\r\n}\r\n","import * as dateFns from 'date-fns'\r\n\r\nimport { ChartConfigChartPane, Instrument, ObjectHash } from '../../types/shared'\r\nimport Line from '../canvas/line'\r\nimport Text from '../canvas/text'\r\nimport { chartsByType } from '../charts/charts'\r\nimport {\r\n CRYPTOS,\r\n ChartEditorEnum,\r\n ChartElementType,\r\n OFFSET,\r\n PADDING,\r\n ScaleType,\r\n SpecificChartFunctionality,\r\n TIMEFRAME,\r\n TIMEFRAME_SECONDS,\r\n TextBaseline,\r\n} from '../constants/common'\r\nimport { getPercentageFromValue } from '../controllers/renderUtils'\r\nimport math from '../helpers/math'\r\nimport Chart from '../models/chart'\r\nimport ChartLayoutModel from '../models/chart_layout'\r\nimport { IChartSettings } from '../models/chart_settings/interfaces'\r\nimport { Mouse } from '../models/mouse'\r\nimport Pane from '../models/pane'\r\nimport Quote, { QuoteGetParams } from '../models/quote'\r\nimport { getChartLayoutSettings } from '../models/settings'\r\nimport Utils, { dateFromUnixTimestamp } from '../utils'\r\nimport { captureException } from './helpers'\r\n\r\nconst DAY_IN_SECONDS = 86400\r\nconst TWO_MIN_IN_MS = 2 * 60 * 1000\r\nconst virtualDatesCache: ObjectHash<{\r\n fromSeconds: number\r\n toSeconds: number\r\n lastUsed: number\r\n virtualDates: number[]\r\n}> = {}\r\n\r\n// The reason to use this func instead of dateFns.isSameDay is performance as this is way faster\r\nfunction areTimestampsFromSameDay({ ts1, ts2 }: { ts1: number; ts2: number }) {\r\n const ts1Utc = ts1\r\n const ts2Utc = ts2\r\n return Math.floor(ts1Utc / DAY_IN_SECONDS) === Math.floor(ts2Utc / DAY_IN_SECONDS)\r\n}\r\n\r\nfunction getVirtualDatesCacheId({\r\n idRevision,\r\n ticker,\r\n timeframe,\r\n}: {\r\n idRevision: number\r\n ticker: string\r\n timeframe: string\r\n}) {\r\n return `${ticker}-${timeframe}-${idRevision}`\r\n}\r\n\r\nfunction getCachedVirtualDates({\r\n idRevision,\r\n ticker,\r\n timeframe,\r\n fromSeconds,\r\n toSeconds,\r\n}: {\r\n idRevision: number\r\n ticker: string\r\n timeframe: string\r\n fromSeconds: number\r\n toSeconds: number\r\n}) {\r\n const id = getVirtualDatesCacheId({ idRevision, ticker, timeframe })\r\n const cache = virtualDatesCache[id]\r\n if (cache?.fromSeconds <= fromSeconds && cache?.toSeconds >= toSeconds) {\r\n cache.lastUsed = Date.now()\r\n if (cache.fromSeconds === fromSeconds && cache.toSeconds === toSeconds) {\r\n return cache.virtualDates\r\n }\r\n return cache.virtualDates.filter(\r\n (virtualDateSeconds) => virtualDateSeconds >= fromSeconds && virtualDateSeconds <= toSeconds\r\n )\r\n }\r\n return null\r\n}\r\n\r\nfunction checkVirtualCacheSize() {\r\n const now = Date.now()\r\n Object.keys(virtualDatesCache).forEach((virtualDatesCacheId) => {\r\n if (virtualDatesCache[virtualDatesCacheId].lastUsed < now - TWO_MIN_IN_MS) {\r\n delete virtualDatesCache[virtualDatesCacheId]\r\n }\r\n })\r\n}\r\n\r\nfunction setCachedVirtualDates({\r\n idRevision,\r\n ticker,\r\n timeframe,\r\n fromSeconds,\r\n toSeconds,\r\n virtualDates,\r\n}: {\r\n idRevision: number\r\n ticker: string\r\n timeframe: string\r\n fromSeconds: number\r\n toSeconds: number\r\n virtualDates: number[]\r\n}) {\r\n const id = getVirtualDatesCacheId({ idRevision, ticker, timeframe })\r\n checkVirtualCacheSize()\r\n virtualDatesCache[id] = {\r\n fromSeconds,\r\n toSeconds,\r\n virtualDates,\r\n lastUsed: Date.now(),\r\n }\r\n}\r\n\r\nconst MAX_BAR_BORDER_WIDTH = 1\r\nconst MIN_BAR_MARGIN_WIDTH = 0\r\nconst MAX_BAR_MARGIN_WIDTH = 16\r\n\r\nexport function getBarWidthWithMarginByParts({\r\n zoomFactor = 1,\r\n chartLayout,\r\n}: {\r\n zoomFactor?: number\r\n chartLayout: ChartLayoutModel\r\n}) {\r\n const { ChartSettings } = chartLayout.settings\r\n const settingsCenter = ChartSettings.center\r\n const barMargin =\r\n zoomFactor > 1 && settingsCenter.barMargin === 0\r\n ? Math.min(settingsCenter.barWidth, 1 - 1 / zoomFactor)\r\n : settingsCenter.barMargin\r\n\r\n const barFillWidth = settingsCenter.barWidth * zoomFactor\r\n const barBorderWidth = Math.min(settingsCenter.border * zoomFactor, MAX_BAR_BORDER_WIDTH)\r\n const barMarginWidth = Math.max(MIN_BAR_MARGIN_WIDTH, Math.min(barMargin * zoomFactor, MAX_BAR_MARGIN_WIDTH))\r\n\r\n return {\r\n barFillWidth,\r\n barBorderWidth,\r\n barMarginWidth,\r\n }\r\n}\r\n\r\nexport function getBarWidthWithMargin({\r\n zoomFactor = 1,\r\n chartLayout,\r\n shouldRound = true,\r\n}: {\r\n zoomFactor?: number\r\n chartLayout: ChartLayoutModel\r\n shouldRound?: boolean\r\n}) {\r\n const { barFillWidth, barBorderWidth, barMarginWidth } = getBarWidthWithMarginByParts({ zoomFactor, chartLayout })\r\n\r\n const barWidth = barFillWidth + barBorderWidth * 2 + barMarginWidth\r\n if (!shouldRound) {\r\n return barWidth\r\n }\r\n const roundDecimalPlaces = barWidth > 100 ? 10 : 10000\r\n return Math.round(barWidth * roundDecimalPlaces) / roundDecimalPlaces\r\n}\r\n\r\nexport function getBarWithoutMarginWidth(chartModel: Chart) {\r\n const { barFillWidth, barBorderWidth } = getBarWidthWithMarginByParts({\r\n chartLayout: chartModel.chart_layout(),\r\n zoomFactor: chartModel.zoomFactor,\r\n })\r\n return barFillWidth + barBorderWidth * 2\r\n}\r\n\r\nexport function getHalfBarWidth(chartModel: Chart, floor = true) {\r\n // Math.max(1, num) is kept from previous implementation, it is highly likely\r\n // that some function which use getHalfBarWidth expect return to be >= 1,\r\n // because we never render bar with width < 1 but at the same time when we have and odd\r\n // width like 5, wa want to floor because of pixel perfect rendering\r\n // but some function require raw not floored number to be able to do it's calculations\r\n // TODO: it would be good to possibly revisit this and check usage if we do need\r\n // to perform floor as well as limit result to be >= 1 but it is most likely necessary\r\n const halfBarWidthRaw = Math.max(1, getBarWithoutMarginWidth(chartModel) / 2)\r\n return floor ? ~~halfBarWidthRaw : halfBarWidthRaw\r\n}\r\n\r\nconst DEFAULT_ZOOM_GUESS_INCREMENT = 0.001\r\n\r\nconst zoomFactorForBarsToDisplayCache: ObjectHash = {}\r\nconst zoomFactorForBarsToDisplayCacheKeys: string[] = []\r\nconst NUMBER_OF_CACHED_ZOOM_FACTORS = 10\r\nconst getZoomFactorFromCache = (key: string) => zoomFactorForBarsToDisplayCache[key] ?? null\r\nconst setZoomFactorToCache = (key: string, value: number) => {\r\n if (!zoomFactorForBarsToDisplayCacheKeys.includes(key)) {\r\n zoomFactorForBarsToDisplayCacheKeys.unshift(key)\r\n if (zoomFactorForBarsToDisplayCacheKeys.length > NUMBER_OF_CACHED_ZOOM_FACTORS) {\r\n const poppedKey = zoomFactorForBarsToDisplayCacheKeys.pop()\r\n if (poppedKey) {\r\n delete zoomFactorForBarsToDisplayCache[poppedKey]\r\n }\r\n }\r\n }\r\n\r\n zoomFactorForBarsToDisplayCache[key] = value\r\n}\r\n\r\nexport function getZoomFactorForBarsToDisplay({\r\n chartVisibleWidth,\r\n numOfVisibleBars,\r\n chartLayout,\r\n}: {\r\n chartVisibleWidth: number\r\n numOfVisibleBars: number\r\n chartLayout: ChartLayoutModel\r\n}) {\r\n const defaultBarWidthWithMargin = getBarWidthWithMargin({ chartLayout })\r\n const barWidthWithMargin = chartVisibleWidth / numOfVisibleBars\r\n const cacheKey = `${defaultBarWidthWithMargin}-${barWidthWithMargin}`\r\n let zoomIncrement = 0\r\n let currentZoomFactor = 1\r\n let finalZoomFactor = getZoomFactorFromCache(cacheKey)\r\n let iteration = 0\r\n if (barWidthWithMargin <= defaultBarWidthWithMargin) {\r\n finalZoomFactor = barWidthWithMargin / defaultBarWidthWithMargin\r\n }\r\n while (finalZoomFactor === null) {\r\n iteration += 1\r\n const threshold = 0.01\r\n currentZoomFactor += zoomIncrement\r\n const barWidth = getBarWidthWithMargin({ zoomFactor: currentZoomFactor, chartLayout, shouldRound: false })\r\n const barWidthDiff = barWidthWithMargin - barWidth\r\n if (barWidthDiff > threshold) {\r\n zoomIncrement = zoomIncrement > 0 ? zoomIncrement * 2 : DEFAULT_ZOOM_GUESS_INCREMENT\r\n } else if (barWidthDiff < -threshold) {\r\n zoomIncrement = zoomIncrement < 0 ? zoomIncrement * 2 : -DEFAULT_ZOOM_GUESS_INCREMENT\r\n } else {\r\n finalZoomFactor = currentZoomFactor\r\n }\r\n\r\n if (iteration === 1000) {\r\n captureException(new Error('Invalid zoom factor from getZoomFactorForBarsToDisplay'), {\r\n extra: {\r\n iteration,\r\n zoomIncrement,\r\n barWidthWithMargin,\r\n barWidth,\r\n barWidthDiff,\r\n currentZoomFactor,\r\n chartLayout: chartLayout.toConfig(['colors', 'panes']),\r\n },\r\n })\r\n return currentZoomFactor\r\n }\r\n }\r\n\r\n setZoomFactorToCache(cacheKey, finalZoomFactor)\r\n\r\n return finalZoomFactor\r\n}\r\n\r\nexport function getTimeframeSeconds({\r\n lowerIndex,\r\n dates,\r\n timeframe,\r\n}: {\r\n lowerIndex: number\r\n dates: number[]\r\n timeframe: TIMEFRAME\r\n}) {\r\n const upperIndex = lowerIndex + 1\r\n const areBoundsDefined = ![dates[upperIndex], dates[lowerIndex]].some((index) => index === undefined)\r\n return areBoundsDefined ? dates[upperIndex] - dates[lowerIndex] : TIMEFRAME_SECONDS[timeframe]\r\n}\r\n\r\nfunction getVirtualTradedDays({\r\n dateStartSeconds,\r\n dateEndSeconds,\r\n datesSeconds,\r\n marketStartMinutes,\r\n}: {\r\n dateStartSeconds: number\r\n dateEndSeconds: number\r\n datesSeconds: number[]\r\n marketStartMinutes: number\r\n}) {\r\n const dateStart = dateFromUnixTimestamp(dateStartSeconds)\r\n const dateEnd = dateFromUnixTimestamp(dateEndSeconds)\r\n const isStartBeforeDates = dateStartSeconds < datesSeconds[0]\r\n const isEndAfterDates = datesSeconds.length > 0 && datesSeconds[datesSeconds.length - 1] < dateEndSeconds\r\n const firstDate = dateFromUnixTimestamp(datesSeconds[0])\r\n const lastDate = dateFromUnixTimestamp(datesSeconds[datesSeconds.length - 1])\r\n return dateFns\r\n .eachDayOfInterval({\r\n start:\r\n isStartBeforeDates && (dateFns.isWeekend(dateStart) || dateStart.getMinutes() < marketStartMinutes)\r\n ? dateFns.addBusinessDays(dateStart, -1)\r\n : dateStart,\r\n end: isEndAfterDates ? dateFns.addBusinessDays(dateEnd, 1) : dateEnd,\r\n })\r\n .filter((date) => {\r\n const ts2 = date.getTime() / 1000 - date.getTimezoneOffset() * 60\r\n return (\r\n !dateFns.isWithinInterval(date, { start: dateFns.startOfDay(firstDate), end: dateFns.endOfDay(lastDate) }) ||\r\n datesSeconds.some((dateTime) =>\r\n areTimestampsFromSameDay({\r\n ts1: dateTime - Utils.getQuoteDateTimestampOffsetInSeconds(new Date(dateTime * 1000)),\r\n ts2,\r\n })\r\n )\r\n )\r\n })\r\n}\r\n\r\nexport function getVirtualTimeframeTradedDates({\r\n dateStart,\r\n dateEnd,\r\n quote,\r\n}: {\r\n dateStart: number\r\n dateEnd: number\r\n quote: Quote\r\n}) {\r\n const { date: dates, ticker, timeframe, instrument, isIntraday, marketStartMinutes } = quote\r\n const barsInDay = quote.getBarsInDay() ?? 0\r\n\r\n // Currently we're passing first and last quote dates to dateStart / dateEnd so this is always true\r\n // but this function can be used on other places in the future where it will work with dates out of quote dates range\r\n const isWithinRangeOfQuoteDate = dateStart === dates[0] && dateEnd === dates[dates.length - 1]\r\n\r\n const commonVirtualCacheProps = {\r\n idRevision: dates.length,\r\n ticker,\r\n timeframe,\r\n fromSeconds: dateStart,\r\n toSeconds: dateEnd,\r\n }\r\n const cachedDates = getCachedVirtualDates(commonVirtualCacheProps)\r\n if (cachedDates) {\r\n return cachedDates\r\n }\r\n if (!isIntraday || instrument !== Instrument.Stock) {\r\n if (isWithinRangeOfQuoteDate) {\r\n return dates\r\n }\r\n const timeframeSeconds = TIMEFRAME_SECONDS[timeframe]\r\n const firstDate = dates[0]\r\n const lastDate = dates[dates.length - 1]\r\n const numOfDatesBefore = Math.ceil((firstDate - dateStart) / timeframeSeconds)\r\n const numOfDatesAfter = Math.ceil((dateEnd - lastDate) / timeframeSeconds)\r\n return [\r\n ...Array.from({ length: numOfDatesBefore })\r\n .map((_, index) => firstDate - (index + 1) * timeframeSeconds)\r\n .reverse(),\r\n ...dates,\r\n ...Array.from({ length: numOfDatesAfter }).map((_, index) => lastDate + (index + 1) * timeframeSeconds),\r\n ]\r\n }\r\n\r\n const virtualTradedDays = isWithinRangeOfQuoteDate\r\n ? quote.getDaysInQuote()\r\n : getVirtualTradedDays({\r\n dateStartSeconds: dateStart,\r\n dateEndSeconds: dateEnd,\r\n datesSeconds: dates,\r\n marketStartMinutes,\r\n })\r\n\r\n const marketStartSeconds = marketStartMinutes * 60\r\n const barTimeframeSeconds = Array.from({ length: barsInDay }).map((_, i) => i * TIMEFRAME_SECONDS[timeframe])\r\n const quoteDatesTimestampOffset = Utils.getQuoteDateTimestampOffsetInSeconds(new Date(dateStart * 1000))\r\n const virtualDates = virtualTradedDays.flatMap((date) => {\r\n const daySeconds =\r\n date.getTime() / 1000 + Utils.getQuoteDateTimestampOffsetInSeconds(date) - date.getTimezoneOffset() * 60\r\n const dayStartSeconds = daySeconds + marketStartSeconds\r\n return barTimeframeSeconds.map(\r\n // Hourly market starts at 9:30 but all other time ticks should be rounded down to :00 of the current hour\r\n (barSeconds, index) =>\r\n ([TIMEFRAME.h, TIMEFRAME.h2, TIMEFRAME.h4].includes(timeframe) && index > 0 ? -1800 : 0) +\r\n dayStartSeconds +\r\n barSeconds\r\n )\r\n })\r\n\r\n if (!isWithinRangeOfQuoteDate) {\r\n virtualDates.filter((date, index, virtualTimeframeTradedDates) => {\r\n const isLowerBounded =\r\n date >= dateStart ||\r\n areTimestampsFromSameDay({\r\n ts1: date - Utils.getQuoteDateTimestampOffsetInSeconds(new Date(date * 1000)),\r\n ts2: dateStart - quoteDatesTimestampOffset,\r\n })\r\n const isOneBeforeLowerBoundStarts = dateStart > date && dateStart < virtualTimeframeTradedDates[index + 1]\r\n return isLowerBounded || isOneBeforeLowerBoundStarts\r\n })\r\n }\r\n\r\n setCachedVirtualDates({\r\n ...commonVirtualCacheProps,\r\n virtualDates,\r\n })\r\n\r\n return virtualDates\r\n}\r\n\r\ninterface TimestampPositionGettersProps {\r\n quote: Quote\r\n}\r\n\r\nexport function getTimestampFromPositionX({ positionX, quote }: TimestampPositionGettersProps & { positionX: number }) {\r\n const { date, timeframe } = quote\r\n const dates = getVirtualTimeframeTradedDates({\r\n dateStart: date[0],\r\n dateEnd: date[date.length - 1],\r\n quote,\r\n })\r\n const dateStart = dates[0]\r\n const dateEnd = dates[dates.length - 1]\r\n const lastDateIndex = dates.length - 1\r\n if (positionX >= 0 && positionX <= lastDateIndex) {\r\n const lowerIndex = Math.floor(positionX)\r\n const timeframeSeconds = getTimeframeSeconds({ lowerIndex, dates, timeframe })\r\n return dates[lowerIndex] + (positionX - lowerIndex) * timeframeSeconds\r\n }\r\n const isLookingBack = positionX < 0\r\n const averageBarDate = (dateEnd - dateStart) / dates.length\r\n const numOfSecondsOutOfBounds = isLookingBack\r\n ? Math.abs(positionX) * averageBarDate\r\n : (positionX - lastDateIndex) * averageBarDate\r\n return Math.round(isLookingBack ? dateStart - numOfSecondsOutOfBounds : dateEnd + numOfSecondsOutOfBounds)\r\n}\r\n\r\nexport function getPositionXFromTimestamp({ timestamp, quote }: TimestampPositionGettersProps & { timestamp: number }) {\r\n const { date, timeframe } = quote\r\n const dates = getVirtualTimeframeTradedDates({\r\n dateStart: date[0],\r\n dateEnd: date[date.length - 1],\r\n quote,\r\n })\r\n const dateStart = dates[0]\r\n const dateEnd = dates[dates.length - 1]\r\n const lastDateIndex = dates.length - 1\r\n if (timestamp >= dates[0] && timestamp <= dates[dates.length - 1]) {\r\n const upperIndex = timestamp === dateEnd ? lastDateIndex : dates.findIndex((date) => date > timestamp)\r\n const timeframeSeconds = getTimeframeSeconds({ lowerIndex: upperIndex - 1, dates, timeframe })\r\n const positionDiffUpperTimestamp = (dates[upperIndex] - timestamp) / timeframeSeconds\r\n return upperIndex - positionDiffUpperTimestamp\r\n }\r\n const isLookingBack = timestamp < dateStart\r\n const averageBarDate = (dateEnd - dateStart) / dates.length\r\n return isLookingBack\r\n ? -((dateStart - timestamp) / averageBarDate)\r\n : lastDateIndex + (timestamp - dateEnd) / averageBarDate\r\n}\r\n\r\n// counterpart in Finviz-Website 'Finviz-Website/js/main/util.ts'\r\nexport function getInstrument(tickerRaw: string) {\r\n if (tickerRaw.indexOf('@') === 0) {\r\n const ticker = tickerRaw.substring(1) as keyof typeof CRYPTOS\r\n\r\n if (CRYPTOS[ticker]) {\r\n return Instrument.Crypto\r\n } else if (ticker.length === 6) {\r\n return Instrument.Forex\r\n } else {\r\n return Instrument.Futures\r\n }\r\n }\r\n return Instrument.Stock\r\n}\r\n\r\nexport function getPerfIndicatorTickerAndTimeframes({\r\n paneWithPerfIndicator,\r\n timeframe,\r\n}: {\r\n paneWithPerfIndicator: ChartConfigChartPane\r\n timeframe: TIMEFRAME\r\n}) {\r\n const { elements } = paneWithPerfIndicator\r\n const perfIndicatorElement = elements.find(({ type }) => type === 'indicators/perf')\r\n const tickers = perfIndicatorElement?.period?.split(',') ?? []\r\n return tickers.map((ticker) => ({\r\n ticker,\r\n instrument: getInstrument(ticker),\r\n timeframe,\r\n }))\r\n}\r\n\r\ninterface PrefetchPerfIndicatorAllQuotesProps extends Pick {\r\n paneWithPerfIndicator: ChartConfigChartPane\r\n chartUuid?: string\r\n}\r\n\r\nexport async function prefetchPerfIndicatorAllQuotes({\r\n paneWithPerfIndicator,\r\n timeframe,\r\n options,\r\n chartUuid,\r\n}: PrefetchPerfIndicatorAllQuotesProps) {\r\n const tickersAndTimeframes = getPerfIndicatorTickerAndTimeframes({ paneWithPerfIndicator, timeframe })\r\n\r\n if (tickersAndTimeframes.length > 0) {\r\n const promises = tickersAndTimeframes.map(({ ticker, instrument, timeframe }) =>\r\n Quote.get({\r\n ticker,\r\n instrument,\r\n timeframe,\r\n options,\r\n chartUuid,\r\n })\r\n )\r\n return Promise.all(promises)\r\n }\r\n return Promise.resolve([])\r\n}\r\n\r\ninterface RenderCrossProps {\r\n context: CanvasRenderingContext2D\r\n mouseModel: Mouse\r\n paneModel: Pane\r\n quote: Quote\r\n contentWidth: number\r\n contentHeight: number\r\n onRenderCrossText?: (context: CanvasRenderingContext2D, crossIndex: number) => void\r\n getRoundDecimalPlaces?: (price?: number) => number | undefined\r\n isIndicator?: boolean\r\n isPerfIndicator?: boolean\r\n}\r\n\r\nexport function renderCross({\r\n context,\r\n mouseModel,\r\n paneModel,\r\n quote,\r\n contentWidth,\r\n contentHeight,\r\n onRenderCrossText,\r\n getRoundDecimalPlaces,\r\n isIndicator = false,\r\n isPerfIndicator = false,\r\n}: RenderCrossProps) {\r\n const crossIndex = mouseModel.getCrossIndexForPane(paneModel)\r\n const chartModel = paneModel.chart()\r\n const { ChartSettings, IndicatorSettings } = getChartLayoutSettings(chartModel.chart_layout())\r\n const settings = isIndicator ? IndicatorSettings : ChartSettings\r\n const { Colors } = ChartSettings.general\r\n\r\n if (!mouseModel.getShouldRenderCrossInPane(paneModel)) {\r\n return false\r\n }\r\n\r\n const price = mouseModel.getPriceForPane(paneModel)\r\n const middle = paneModel.scale.x(crossIndex) + chartModel.leftOffset\r\n const isXAxisInView = middle > 0 && middle <= contentWidth\r\n if (isXAxisInView) {\r\n const x = middle + settings.left.width\r\n new Line(\r\n {\r\n x1: x,\r\n x2: x,\r\n y1: settings.top.height,\r\n y2: settings.top.height + contentHeight,\r\n strokeStyle: Colors.cross,\r\n },\r\n paneModel\r\n ).render(context)\r\n\r\n onRenderCrossText?.(context, crossIndex)\r\n }\r\n\r\n const domainRange = paneModel.scale.y\r\n .domain()\r\n .slice()\r\n .sort((a, b) => a - b)\r\n\r\n if (price === null || !(domainRange[0] <= price && price <= domainRange[1])) {\r\n return isXAxisInView\r\n }\r\n\r\n const priceFy = paneModel.scale.y(price)\r\n const y = Math.round(priceFy + settings.top.height)\r\n new Line(\r\n {\r\n x1: settings.left.width,\r\n x2: settings.left.width + contentWidth,\r\n y1: y,\r\n y2: y,\r\n strokeStyle: Colors.cross,\r\n },\r\n paneModel\r\n ).render(context)\r\n const YAxisLeftMargin = quote.instrument === Instrument.Crypto && quote.lastClose <= 0.001 ? 3 : 8\r\n\r\n const getCrossText = () => {\r\n if (chartModel.scale === ScaleType.Percentage && !isIndicator) {\r\n return `${math.round({\r\n value: getPercentageFromValue({ number: price, base: chartModel.firstBarClose }),\r\n lastClose: quote.lastClose,\r\n instrument: quote.instrument,\r\n overridePlaces: 2,\r\n })}%`\r\n }\r\n return `${math.round({\r\n value: price,\r\n lastClose: quote.lastClose,\r\n instrument: quote.instrument,\r\n overridePlaces: getRoundDecimalPlaces?.(price) ?? (paneModel.getIsChartPane() ? undefined : 2),\r\n })}${isPerfIndicator ? '%' : ''}`\r\n }\r\n\r\n new Text(\r\n {\r\n text: getCrossText(),\r\n x:\r\n settings.left.width +\r\n settings.right.axis.margin.left! +\r\n contentWidth +\r\n (isIndicator ? OFFSET.S : YAxisLeftMargin - PADDING.XXS),\r\n padding: isIndicator\r\n ? Text.getMergedPropsWithDefaults('padding', IndicatorSettings.right.axis.font.padding)\r\n : {\r\n top: PADDING.XXS,\r\n right: PADDING.XXS,\r\n bottom: PADDING.XXS,\r\n left: PADDING.XXS,\r\n },\r\n ...{\r\n y,\r\n textBaseline: TextBaseline.middle,\r\n fillStyle: Colors.crossText,\r\n background: Colors.crossTextBackground,\r\n font: Text.getMergedPropsWithDefaults('font', { ...settings.right.axis.font, style: 'bold' }),\r\n lineHeight: settings.right.axis.font.lineHeight,\r\n },\r\n },\r\n paneModel\r\n ).render(context)\r\n\r\n return true\r\n}\r\n\r\n/**\r\n * Set canvas width and height to 0 which fixes Safari memory problems\r\n *\r\n * @see https://stackoverflow.com/questions/52532614/total-canvas-memory-use-exceeds-the-maximum-limit-safari-12\r\n */\r\nexport function unmountCanvas(canvas?: HTMLCanvasElement | null) {\r\n if (!canvas) return\r\n\r\n canvas.width = 0\r\n canvas.height = 0\r\n canvas.style.width = '0px'\r\n canvas.style.height = '0px'\r\n}\r\n\r\nexport function getChangeColor({ change, ChartSettings }: { change: number; ChartSettings: IChartSettings }) {\r\n const { Colors } = ChartSettings.general\r\n if (change === 0) {\r\n return Colors.zeroChange\r\n }\r\n return change > 0 ? Colors.positiveChange : Colors.negativeChange\r\n}\r\n\r\nexport function round({ data, num, overridePlaces }: { data: Quote; num: number; overridePlaces?: number }) {\r\n return math.round({\r\n value: num,\r\n lastClose: data.lastClose,\r\n instrument: data.instrument,\r\n overridePlaces: overridePlaces,\r\n })\r\n}\r\n\r\nexport interface ITickerChange {\r\n points: number\r\n string: string\r\n percentString: string\r\n}\r\ninterface ITickerChangeResult {\r\n tickerChange: ITickerChange | null\r\n tickerAfterChange: ITickerChange | null\r\n}\r\n\r\nexport function getTickerChangeFromCloseValues({\r\n anchorClose,\r\n prevClose,\r\n data,\r\n}: {\r\n anchorClose: number\r\n prevClose: number\r\n data: Quote\r\n}): ITickerChange {\r\n const changePoints = anchorClose - prevClose\r\n const changePercent = (anchorClose / prevClose - 1) * 100\r\n const sign = changePoints < 0 ? '-' : changePoints > 0 ? '+' : ''\r\n const changePercentString = `${round({\r\n data,\r\n num: Math.abs(changePercent),\r\n overridePlaces: 2,\r\n })}%`\r\n const changePointsString = `${sign}${round({\r\n data,\r\n num: Math.abs(changePoints),\r\n })} (${changePercentString})`\r\n\r\n return {\r\n points: changePoints,\r\n string: changePointsString,\r\n percentString: `${sign}${changePercentString}`,\r\n }\r\n}\r\nexport function getTickerChange({ data }: { data: Quote }) {\r\n const result: ITickerChangeResult = { tickerChange: null, tickerAfterChange: null }\r\n const isChange = Number.isFinite(data.prevClose) // if not new stock always present\r\n if (isChange) {\r\n result.tickerChange = getTickerChangeFromCloseValues({\r\n data,\r\n anchorClose: data.lastClose,\r\n prevClose: data.prevClose,\r\n })\r\n }\r\n\r\n const isAfterChange = Number.isFinite(data.afterClose) && data.afterClose !== data.lastClose\r\n if (isAfterChange) {\r\n const tickerAfterChange = getTickerChangeFromCloseValues({\r\n data,\r\n anchorClose: data.afterClose,\r\n prevClose: data.lastClose,\r\n })\r\n result.tickerAfterChange = {\r\n ...tickerAfterChange,\r\n string: `AH: ${tickerAfterChange.string}`,\r\n }\r\n }\r\n\r\n return result\r\n}\r\n\r\nexport function isForexFuturesCryptoPage(specificChartFunctionality: SpecificChartFunctionality) {\r\n return [\r\n SpecificChartFunctionality.forexPage,\r\n SpecificChartFunctionality.cryptoPage,\r\n SpecificChartFunctionality.futuresPage,\r\n ].includes(specificChartFunctionality)\r\n}\r\n\r\nexport function getShouldUseDarkerWickColors({\r\n specificChartFunctionality,\r\n totalBarWidth,\r\n}: {\r\n specificChartFunctionality: SpecificChartFunctionality\r\n timeFrame?: TIMEFRAME\r\n totalBarWidth: number\r\n}) {\r\n const isForexFuturesCrypto = isForexFuturesCryptoPage(specificChartFunctionality)\r\n const isOffscreenChartWithNarrowBars =\r\n specificChartFunctionality === SpecificChartFunctionality.offScreen && totalBarWidth < 5\r\n const isQuoteChartWithNarrowBars =\r\n specificChartFunctionality === SpecificChartFunctionality.quotePage && totalBarWidth < 5\r\n\r\n return isForexFuturesCrypto || isOffscreenChartWithNarrowBars || isQuoteChartWithNarrowBars\r\n}\r\n\r\nexport const DRAWING_COOKIE_NAME = 'charts-draw'\r\nexport function getIsDrawingEnabled() {\r\n return Utils.getCookie(DRAWING_COOKIE_NAME) === 'on'\r\n}\r\n\r\nexport function setIsDrawingEnabled(value: boolean) {\r\n const expires = new Date()\r\n expires.setMonth(expires.getMonth() + 1)\r\n Utils.setCookie(DRAWING_COOKIE_NAME, value ? 'on' : 'off', expires)\r\n}\r\n\r\nexport function getIsSidebarEnabled(specificChartFunctionality?: SpecificChartFunctionality) {\r\n return specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n}\r\n\r\nexport const handleTypeChange = ({\r\n type,\r\n chartLayoutModel,\r\n}: {\r\n type: ChartElementType\r\n chartLayoutModel: ChartLayoutModel\r\n}) => {\r\n const elements = chartLayoutModel.getAllElements()\r\n elements.forEach((element) => {\r\n if (element.isChart() && element.instance.attrs.type !== type) {\r\n const pane = element.pane()\r\n const instance = chartsByType[type].fromObject(\r\n {\r\n ...element.instance.attrs,\r\n type,\r\n },\r\n pane\r\n )\r\n element.replace(instance)\r\n }\r\n })\r\n}\r\n\r\nexport const getIsPreserveDrawingsAndAutosaveAvailable = (args: {\r\n specificChartFunctionality: SpecificChartFunctionality\r\n editable: boolean\r\n editors: ChartEditorEnum[]\r\n}) => {\r\n const { specificChartFunctionality, editable, editors } = args\r\n\r\n return (\r\n editable &&\r\n editors?.includes(ChartEditorEnum.tools) &&\r\n specificChartFunctionality &&\r\n [\r\n SpecificChartFunctionality.chartPage,\r\n SpecificChartFunctionality.quotePage,\r\n SpecificChartFunctionality.forexPage,\r\n SpecificChartFunctionality.futuresPage,\r\n SpecificChartFunctionality.cryptoPage,\r\n ].includes(specificChartFunctionality)\r\n )\r\n}\r\n","/**\r\n * Keep this file in sync with `Website/js/main/components/color-picker/util.ts` in website repo\r\n * */\r\n\r\nexport interface RGBA {\r\n r: number\r\n g: number\r\n b: number\r\n a: number\r\n}\r\n\r\nexport interface HSVA {\r\n h: number\r\n s: number\r\n v: number\r\n a: number\r\n}\r\n\r\nexport interface HSLA {\r\n h: number\r\n s: number\r\n l: number\r\n a: number\r\n}\r\n\r\n/**\r\n * Convert Hex string to RGBA object.\r\n * @see https://css-tricks.com/converting-color-spaces-in-javascript/\r\n *\r\n * Input: color in hex3, hex4, hex6 or hex8 format (#fff)\r\n *\r\n * Output: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n */\r\nexport function hexStringToRGBA(hexString: string): RGBA {\r\n const hexColor = removeHashSymbol(hexString)\r\n let r: string | number = 0\r\n let g: string | number = 0\r\n let b: string | number = 0\r\n let a: string | number = 255\r\n\r\n // 3 digits\r\n if (hexColor.length === 3 || hexColor.length === 4) {\r\n r = '0x' + hexColor[0] + hexColor[0]\r\n g = '0x' + hexColor[1] + hexColor[1]\r\n b = '0x' + hexColor[2] + hexColor[2]\r\n // Get channel if defined\r\n a = hexColor.length === 4 ? '0x' + hexColor[3] + hexColor[3] : a\r\n\r\n // 6 digits\r\n } else if (hexColor.length === 6 || hexColor.length === 8) {\r\n r = '0x' + hexColor[0] + hexColor[1]\r\n g = '0x' + hexColor[2] + hexColor[3]\r\n b = '0x' + hexColor[4] + hexColor[5]\r\n // Get channel if defined\r\n a = hexColor.length === 8 ? '0x' + hexColor[6] + hexColor[7] : a\r\n }\r\n\r\n return { r: Number(r), g: Number(g), b: Number(b), a: Math.min(Math.round((Number(a) / 255) * 100) / 100, 1) }\r\n}\r\n\r\n/**\r\n * Convert HEX string to HSVA color representation.\r\n *\r\n * Input: color in hex3, hex4, hex6 or hex8 format (#fff)\r\n *\r\n * Output: { h: [0,360], s: [0,1], v: [0,1], a: [0,1]}\r\n */\r\nexport function hexStringToHSVA(hexString: string) {\r\n return rgbaToHSVA(hexStringToRGBA(hexString))\r\n}\r\n\r\n/**\r\n * Convert HEX string to HSLA color representation.\r\n *\r\n * Input: color in hex3, hex4, hex6 or hex8 format (#fff)\r\n *\r\n * Output: { h: [0,360], s: [0,1], l: [0,1], a: [0,1]}\r\n */\r\nexport function hexStringToHSLA(hexString: string) {\r\n return rgbaToHSLA(hexStringToRGBA(hexString))\r\n}\r\n\r\n/**\r\n * Convert alpha value to hex value\r\n *\r\n * Input: [0,1]\r\n *\r\n * Output: alpha in HEX format\r\n */\r\nexport function alphaToHex(alpha: number) {\r\n return Math.max(Math.min(Math.round(alpha * 255), 255), 0)\r\n .toString(16)\r\n .padStart(2, '0')\r\n}\r\n\r\n/**\r\n * Convert RGBA color to HEX string.\r\n *\r\n * Input: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n *\r\n * Output: color in hex6 or hex8 depending on whether or not alpha is enabled\r\n */\r\nexport function rgbaToHexString(color: RGBA, alpha = false) {\r\n const r = color.r.toString(16)\r\n const g = color.g.toString(16)\r\n const b = color.b.toString(16)\r\n const hexString = '#' + r.padStart(2, '0') + g.padStart(2, '0') + b.padStart(2, '0')\r\n\r\n if (!alpha || color.a === 1) {\r\n return hexString\r\n }\r\n\r\n return `${hexString}${alphaToHex(color.a)}`\r\n}\r\n\r\n/**\r\n * Convert HSVA object to HEX string\r\n *\r\n * @see https://css-tricks.com/converting-color-spaces-in-javascript/\r\n *\r\n * Input: { h: [0,360], s: [0,1], v: [0,1], a: [0,1]}\r\n *\r\n * Output: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n */\r\nexport function hsvaToHEXString(color: HSVA, alpha = false) {\r\n const rgbaColor = hsvaToRGBA(color)\r\n\r\n return rgbaToHexString(rgbaColor, alpha)\r\n}\r\n\r\n/**\r\n * Convert HSLA object to HEX string\r\n *\r\n * @see https://css-tricks.com/converting-color-spaces-in-javascript/\r\n *\r\n * Input: { h: [0,360], s: [0,1], l: [0,1], a: [0,1]}\r\n *\r\n * Output: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n */\r\nexport function hslaToHexString(color: HSLA, alpha = false) {\r\n const rgbaColor = hslaToRGBA(color)\r\n\r\n return rgbaToHexString(rgbaColor, alpha)\r\n}\r\n\r\n/**\r\n * Convert RGBA color to HSVA\r\n * @see https://stackoverflow.com/a/54070620/6662683\r\n *\r\n * Input: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n *\r\n * Output: { h: [0,360], s: [0,1], v: [0,1], a: [0,1]}\r\n */\r\nexport function rgbaToHSVA(color: RGBA): HSVA {\r\n const r = color.r / 255\r\n const g = color.g / 255\r\n const b = color.b / 255\r\n\r\n const v = Math.max(r, g, b)\r\n const c = v - Math.min(r, g, b)\r\n const h = c && (v === r ? (g - b) / c : v === g ? 2 + (b - r) / c : 4 + (r - g) / c)\r\n\r\n return {\r\n h: 60 * (h < 0 ? h + 6 : h),\r\n s: v ? c / v : 0,\r\n v: v,\r\n a: color.a,\r\n }\r\n}\r\n\r\n/**\r\n * Convert RGBA to HSLA\r\n * @see https://stackoverflow.com/a/54071699/6662683\r\n *\r\n * Input: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n *\r\n * Output: { h: [0,360], s: [0,1], l: [0,1], a: [0,1]}\r\n */\r\nexport function rgbaToHSLA(color: RGBA): HSLA {\r\n const r = color.r / 255\r\n const g = color.g / 255\r\n const b = color.b / 255\r\n\r\n const v = Math.max(r, g, b)\r\n const c = v - Math.min(r, g, b)\r\n const f = 1 - Math.abs(v + v - c - 1)\r\n const h = c && (v === r ? (g - b) / c : v === g ? 2 + (b - r) / c : 4 + (r - g) / c)\r\n\r\n return {\r\n h: 60 * (h < 0 ? h + 6 : h),\r\n s: f ? c / f : 0,\r\n l: (v + v - c) / 2,\r\n a: color.a,\r\n }\r\n}\r\n\r\n/**\r\n * Convert HSVA color to RGBA\r\n * @see https://stackoverflow.com/a/54024653/6662683\r\n *\r\n * Input: { h: [0,360], s: [0,1], v: [0,1], a: [0,1]}\r\n *\r\n * Output: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n */\r\nexport function hsvaToRGBA(color: HSVA): RGBA {\r\n const f = (n: number, k = (n + color.h / 60) % 6) => color.v - color.v * color.s * Math.max(Math.min(k, 4 - k, 1), 0)\r\n\r\n return {\r\n r: Math.round(f(5) * 255),\r\n g: Math.round(f(3) * 255),\r\n b: Math.round(f(1) * 255),\r\n a: Math.round(color.a * 100) / 100,\r\n }\r\n}\r\n\r\n/**\r\n * Convert HSLA color to RGBA\r\n * @see https://stackoverflow.com/a/54014428/6662683\r\n *\r\n * Input: { h: [0,360], s: [0,1], l: [0,1], a: [0,1]}\r\n *\r\n * Output: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n */\r\nexport function hslaToRGBA(color: HSLA): RGBA {\r\n const a = color.s * Math.min(color.l, 1 - color.l)\r\n const f = (n: number, k = (n + color.h / 30) % 12) => color.l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1)\r\n\r\n return {\r\n r: Math.round(f(0) * 255),\r\n g: Math.round(f(8) * 255),\r\n b: Math.round(f(4) * 255),\r\n a: color.a,\r\n }\r\n}\r\n\r\n/**\r\n * Convert RGBA color to rgba() string\r\n *\r\n * Input: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n *\r\n * Output: rgba(r, g, b, a)\r\n */\r\nexport function rgbaToRGBAString(color: RGBA) {\r\n return `rgba(${color.r}, ${color.g}, ${color.b}, ${color.a})`\r\n}\r\n\r\n/**\r\n * Convert rgba() string to RGBA color\r\n *\r\n * Input: rgba(r, g, b, a)\r\n *\r\n * Output: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n */\r\nexport function rgbaStringToObject(color: string) {\r\n const colorParts = /^rgba?\\(([0-9]{1,3})[ ,]+([0-9]{1,3})[ ,]+([0-9]{1,3})[ ,]*([01].?[0-9]*)?\\)$/.exec(color)\r\n const [red, green, blue, alpha = '1'] = colorParts?.slice(1) || [0, 0, 0, 1].map(String)\r\n return {\r\n r: Number.parseInt(red),\r\n g: Number.parseInt(green),\r\n b: Number.parseInt(blue),\r\n a: Number.parseFloat(alpha),\r\n }\r\n}\r\n\r\n/**\r\n * Convert HSLA color to hsla() string\r\n *\r\n * Input: { h: [0,360], s: [0,1], l: [0,1], a: [0,1]}\r\n *\r\n * Output: hsla(h, s, l, a)\r\n */\r\nexport function hslaToHSLAString(color: HSLA) {\r\n return `hsla(${Math.round(color.h)}, ${Math.round(color.s * 10000) / 100}%, ${Math.round(color.l * 10000) / 100}%, ${\r\n color.a\r\n })`\r\n}\r\n\r\nexport function removeHashSymbol(strColor: string) {\r\n return strColor.replace(/#/g, '')\r\n}\r\n\r\n/**\r\n * Check if the param is a valid color by setting it as style\r\n */\r\nexport function isValidColor(strColor: string) {\r\n const isRgb = strColor.startsWith('rgba')\r\n const s = new Option().style\r\n\r\n s.color = isRgb ? strColor : `#${removeHashSymbol(strColor)}`\r\n\r\n return s.color !== ''\r\n}\r\n\r\n/**\r\n * Normalize color to be a hex value\r\n */\r\nexport function convertColorToHEX(strColor: string, allowAlpha = true) {\r\n const isRgb = getIsRgb(strColor)\r\n const hexColor = isRgb ? rgbaToHexString(rgbaStringToObject(strColor), allowAlpha) : strColor\r\n\r\n if (allowAlpha) {\r\n return hexColor\r\n }\r\n return hexColor.slice(0, 7)\r\n}\r\n\r\n/**\r\n * Returns true if color is rgb or rgba\r\n */\r\nexport function getIsRgb(strColor: string, isAlphaAllowed = true) {\r\n const rgbKeys = ['rgb']\r\n if (isAlphaAllowed) {\r\n rgbKeys.push('rgba')\r\n }\r\n return rgbKeys.some((startsWith) => strColor.startsWith(startsWith))\r\n}\r\n\r\n/**\r\n * Convert any color format to HSVA (internal color picker representation)\r\n */\r\nexport function getHSVAFromColor(strColor: string) {\r\n if (getIsRgb(strColor)) {\r\n return rgbaToHSVA(rgbaStringToObject(strColor))\r\n }\r\n\r\n return hexStringToHSVA(strColor)\r\n}\r\n\r\n/**\r\n * Stringify HSVA color representation into a output format\r\n */\r\nexport function stringifyHSVAColor(color: HSVA, output: 'rgba' | 'hex', canSelectAlpha?: boolean) {\r\n switch (output) {\r\n case 'rgba':\r\n return rgbaToRGBAString(hsvaToRGBA(color))\r\n default:\r\n return hsvaToHEXString(color, canSelectAlpha)\r\n }\r\n}\r\n\r\n/**\r\n * Get luma value from RGBA color using the Rec. 709 coefficients\r\n * @see https://en.wikipedia.org/wiki/Luma_%28video%29\r\n *\r\n * If luma is >= 165 the foreground color should be dark\r\n */\r\nexport function getLumaFromRGBA(color: RGBA) {\r\n return 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b\r\n}\r\n\r\n/**\r\n * Checks if luma is >= 165 or alpha < 0.3\r\n */\r\nexport function getIsColorTooLightOrTransparent(color: RGBA) {\r\n return getLumaFromRGBA(color) >= 165 || color.a < 0.5\r\n}\r\n\r\n/**\r\n * Set specific alpha for a hex color\r\n */\r\nexport function getHEXWithSpecificAplha(color: string, alpha = 1) {\r\n const rgbaColor = hexStringToRGBA(color)\r\n return rgbaToHexString({ ...rgbaColor, a: alpha }, true)\r\n}\r\n\r\n/**\r\n * Get rgba from valid color string\r\n */\r\nexport function getRGBAValueFromValidColorString(value: string) {\r\n if (getIsRgb(value)) return rgbaToRGBAString(rgbaStringToObject(value))\r\n return rgbaToRGBAString(hexStringToRGBA(value))\r\n}\r\n","// if conditionalCursor provided, cursor is set only if current cursor !== conditionalCursor\r\n// otherwise cursor is set if element exists\r\nexport const setElementCursor = ({\r\n elementId,\r\n cursor,\r\n conditionalCursor,\r\n}: {\r\n elementId: string\r\n cursor: string\r\n conditionalCursor?: string\r\n}) => {\r\n const element = document.getElementById(elementId)\r\n if (element && (conditionalCursor ? element.style.cursor !== conditionalCursor : true)) {\r\n element.style.cursor = cursor\r\n }\r\n}\r\n","/*\r\n * We want to be able to render only bars/parts of line that are visible to users,\r\n * but without introducing visual artifacts like bars missing in front of users while scrolling\r\n * or lines that start in middle of chart for sparse intraday stock data.\r\n *\r\n * In general we want to start rendering lines one bar sooner than what is visible to user and stop rendering\r\n * one bar outside of visible area to create a continuous line.\r\n */\r\nimport type Pane from '../models/pane'\r\nimport type Quote from '../models/quote'\r\nimport { getHalfBarWidth } from './chart'\r\n\r\ninterface IBarToRender {\r\n index: number\r\n isBarVisible: boolean\r\n}\r\n\r\nexport const drawInVisibleArea = ({\r\n drawBarCallback,\r\n fromIndexOffset = 0,\r\n fxOverride,\r\n leftOffset,\r\n paneModel,\r\n quote,\r\n toIndexOffset = 0,\r\n width,\r\n}: {\r\n drawBarCallback: (i: number, x: number) => void\r\n fromIndexOffset?: number\r\n fxOverride?: (index: number) => number\r\n leftOffset: number\r\n paneModel: Pane\r\n quote: Quote\r\n toIndexOffset?: number\r\n width: number\r\n}) => {\r\n const fx = fxOverride ?? ((index: number) => paneModel.scale.x(quote.barIndex[index]))\r\n\r\n // We want to start rendering one bar outside of the visible area for two reasons:\r\n // 1. To create a seamless transition for bars entering/leaving the view, avoiding them from\r\n // abruptly dis/appearing when half the bar is outside.\r\n // 2. To prevent disconnected lines in case there's a bar gap.\r\n // However, if a `fromIndex` is provided and it's higher than the first visible bar,\r\n // we need to start rendering from that specific index. This ensures correct starting\r\n // points for elements like indicators that rely on this value.\r\n const firstBarToRenderIndex = getCompensatedFirstBarToRenderIndex({ quote, paneModel, leftOffset, fromIndexOffset })\r\n\r\n let lastBarToRender = -1\r\n for (let i = firstBarToRenderIndex; i < quote.close.length + toIndexOffset; i++) {\r\n const x = fx(i)\r\n if (x + leftOffset > width) {\r\n lastBarToRender = i\r\n break\r\n }\r\n drawBarCallback(i, x)\r\n }\r\n\r\n if (lastBarToRender > -1) {\r\n const x = fx(lastBarToRender)\r\n drawBarCallback(lastBarToRender, x)\r\n }\r\n}\r\n\r\n/**\r\n * Get first or last visible bar index.\r\n * IMPORTANT: If chartWidth provided return is lastVisibleBarIndex\r\n */\r\nexport function getVisibleBarToRenderIndex({\r\n chartWidth,\r\n leftOffset,\r\n paneModel,\r\n quote,\r\n}: {\r\n chartWidth?: number\r\n leftOffset: number\r\n paneModel: Pane\r\n quote: Quote\r\n}) {\r\n const chartModel = paneModel.chart()\r\n\r\n // not all the time there is bar present on barIndex calculated via inverted leftOffset\r\n // there might be a gap between bars, if there is, barToDataIndex on that gap spot will have value of\r\n // previous bar which isn't visible\r\n\r\n const barIndex = Math.round(paneModel.scale.x.invert(-leftOffset + (chartWidth !== undefined ? chartWidth : 0)))\r\n const dataBarIndex = quote.barToDataIndex[Math.min(Math.max(barIndex, 0), quote.barToDataIndex.length - 1)]\r\n const halfBarWidth = getHalfBarWidth(chartModel, false)\r\n\r\n const isBarVisible = Math.round(paneModel.scale.x(quote.barIndex[dataBarIndex]) + halfBarWidth) + leftOffset > 0\r\n\r\n return {\r\n index:\r\n chartWidth === undefined\r\n ? isBarVisible\r\n ? dataBarIndex\r\n : Math.max(Math.min(dataBarIndex + 1, quote.barIndex.length - 1), 0)\r\n : dataBarIndex,\r\n isBarVisible,\r\n }\r\n}\r\n\r\n// Get first bar to render compensated for fromIndexOffset\r\nexport function getCompensatedFirstBarToRenderIndex({\r\n fromIndexOffset = 0,\r\n leftOffset,\r\n paneModel,\r\n quote,\r\n}: {\r\n fromIndexOffset?: number\r\n leftOffset: number\r\n paneModel: Pane\r\n quote: Quote\r\n}) {\r\n return Math.max(0, getVisibleBarToRenderIndex({ quote, leftOffset, paneModel }).index - 1, fromIndexOffset)\r\n}\r\n\r\n/**\r\n * Checks if there are no visible bars between the specified first and last bars to render.\r\n * IMPORTANT: Provided indexes should be without bar gap compensation.\r\n *\r\n * @param {IBarToRender} firstBarToRenderIndex The index of the first bar to render.\r\n * @param {IBarToRender} lastBarToRenderIndex The index of the last bar to render.\r\n * @returns {boolean} True if there are no visible bars between the first and last bars, false otherwise.\r\n */\r\nexport function getAreNoBarsVisible(firstBarToRenderIndex: IBarToRender, lastBarToRenderIndex: IBarToRender): boolean {\r\n return !firstBarToRenderIndex.isBarVisible && !lastBarToRenderIndex.isBarVisible\r\n}\r\n","import queryString from 'query-string'\r\n\r\nimport { ObjectHash } from '../../types/shared'\r\n\r\ninterface FetchApiProps {\r\n location: string\r\n queryParameters?: ObjectHash\r\n method?: string\r\n body?: RequestInit['body']\r\n contentType?: ContentType\r\n abortController?: null | AbortController\r\n throwOnStatusCodes?: number[]\r\n throwOnPredicate?: (response: Response) => boolean\r\n keepalive?: boolean\r\n}\r\n\r\nexport const getFormDataFromObject = (object: ObjectHash) =>\r\n Object.keys(object).reduce((formData, key) => {\r\n formData.append(key, object[key])\r\n return formData\r\n }, new FormData())\r\n\r\n// Keep in sync with ContentType in https://github.com/finvizhq/Finviz-Website/blob/master/Website/js/main/services/api.ts\r\n// START\r\nexport enum ContentType {\r\n ApplicationJson = 'application/json',\r\n ApplicationJsonUTF = 'application/json; charset=utf-8', // WriteAsJsonAsync\r\n FormUrlEncoded = 'application/x-www-form-urlencoded',\r\n Html = 'text/html; charset=utf-8',\r\n}\r\n\r\nfunction parseResponseForContentType(response: string, contentType: ContentType) {\r\n switch (contentType) {\r\n case ContentType.ApplicationJson:\r\n case ContentType.ApplicationJsonUTF:\r\n case ContentType.FormUrlEncoded:\r\n return JSON.parse(response)\r\n default:\r\n return response\r\n }\r\n}\r\n// END\r\n\r\nconst fetchApi = async ({\r\n location,\r\n queryParameters,\r\n method,\r\n body,\r\n contentType,\r\n abortController,\r\n throwOnStatusCodes,\r\n throwOnPredicate,\r\n keepalive = false,\r\n}: FetchApiProps) => {\r\n const url = `${location}${queryParameters ? `?${queryString.stringify(queryParameters)}` : ''}`\r\n const parameters: RequestInit = {\r\n method: method || 'GET',\r\n credentials: 'include',\r\n headers: contentType && {\r\n 'Content-Type': contentType,\r\n },\r\n signal: abortController?.signal,\r\n body: body,\r\n keepalive,\r\n }\r\n try {\r\n const response = await fetch(url, parameters)\r\n const responseContentType: ContentType = (response.headers.get('Content-Type') as any) ?? ContentType.Html\r\n const responseData = parseResponseForContentType(await response.text(), responseContentType)\r\n if (throwOnStatusCodes?.includes(response.status) || throwOnPredicate?.(response)) {\r\n const StatusCodeError = getStatusCodeError(response.status)\r\n throw new StatusCodeError(`${url} returned ${response.status}`, responseData as T, response.status)\r\n }\r\n return responseData as T\r\n } catch (err) {\r\n throw err\r\n }\r\n}\r\n\r\nfunction getStatusCodeError(statusCode: number): typeof GenericStatusCodeError {\r\n switch (statusCode) {\r\n case 403:\r\n return ForbiddenError\r\n case 404:\r\n return NotFoundError\r\n case 410:\r\n return GoneError\r\n case 500:\r\n return InternalServerError\r\n default:\r\n return GenericStatusCodeError\r\n }\r\n}\r\n\r\nexport class GenericStatusCodeError extends Error {\r\n response: ObjectHash | string\r\n statusCode: number\r\n\r\n constructor(message: string, response: ObjectHash | string, statusCode: number) {\r\n super(message)\r\n this.response = response\r\n this.statusCode = statusCode\r\n }\r\n}\r\nexport class ForbiddenError extends GenericStatusCodeError {}\r\nexport class NotFoundError extends GenericStatusCodeError {}\r\nexport class InternalServerError extends GenericStatusCodeError {}\r\nexport class GoneError extends GenericStatusCodeError {}\r\n\r\nexport default fetchApi\r\n","import React from 'react'\r\n\r\nexport function useForceUpdate() {\r\n const [forceUpdateKey, increment] = React.useState(0)\r\n const forceUpdate = React.useCallback(() => {\r\n increment((prev) => prev + 1)\r\n }, [])\r\n return { forceUpdate, forceUpdateKey }\r\n}\r\n","import { EmptyObject, ObjectHash } from '../../types/shared'\r\n\r\nexport function getRoundedString({ number, numOfDecimalPlaces }: { number: number; numOfDecimalPlaces: number }) {\r\n const precision = Math.pow(10, numOfDecimalPlaces)\r\n return String(Math.round(number * precision) / precision)\r\n}\r\n\r\nexport function getIsSSr() {\r\n return typeof process !== 'undefined' && !!process?.env.IS_OFFSCREEN_RENDERER\r\n}\r\n\r\nexport function isValidHexColor(color: string) {\r\n const regex = /^#([\\da-f]{3}){1,2}$|^#([\\da-f]{4}){1,2}$/i\r\n return !!color && regex.test(color)\r\n}\r\n\r\nexport function getParsedIntegersFromPeriodString(periodString: string) {\r\n const periodParts = periodString.split(',')\r\n return periodParts.map((part) => Number.parseInt(part, 10))\r\n}\r\n\r\nexport function captureException(exception: Error, captureContext?: { extra: ObjectHash }) {\r\n if (process.env.NODE_ENV === 'development' || process.env.IS_E2E_TESTING) {\r\n console.error(exception)\r\n } else if (process.env.IS_OFFSCREEN_RENDERER) {\r\n import('@sentry/node').then((client) => {\r\n client.captureException(exception, captureContext)\r\n })\r\n } else {\r\n window.Sentry.captureException(exception, captureContext)\r\n }\r\n}\r\n\r\nexport function isPositiveFloat(value: string | number) {\r\n const parsedNumber = Number.parseFloat(`${value}`)\r\n return !Number.isNaN(parsedNumber) && isFinite(parsedNumber) && parsedNumber > 0\r\n}\r\n\r\nexport function isPositiveInteger(value: string | number) {\r\n const string = `${value}`\r\n return isPositiveFloat(value) && Number.parseInt(string, 10) === Number.parseFloat(string)\r\n}\r\n\r\nexport function isInRange({\r\n value,\r\n min = Number.MIN_SAFE_INTEGER,\r\n max = Number.MAX_SAFE_INTEGER,\r\n}: {\r\n value: string | number\r\n min?: number\r\n max?: number\r\n}) {\r\n const parsedNumber = Number.parseFloat(`${value}`)\r\n return !Number.isNaN(parsedNumber) && parsedNumber >= min && parsedNumber <= max\r\n}\r\n\r\nexport function tryJsonParse(json: string | null = '') {\r\n try {\r\n return JSON.parse(json ?? '') as Result\r\n } catch {\r\n return null\r\n }\r\n}\r\n\r\nexport function getValueInRange({ value, min, max }: { value: number; min: number; max: number }) {\r\n return Math.min(Math.max(value, min), max)\r\n}\r\n\r\nexport function isPrimaryClick(e: React.Touch | React.TouchEvent | React.MouseEvent) {\r\n // cypress trigger mouseevent has button: undefined if button option isn't explicitly specified\r\n // as cy.get('.target').trigger('mousedown', { button: 0 })\r\n if (e.hasOwnProperty('button') && (e as unknown as MouseEvent).button !== undefined) {\r\n return (e as unknown as MouseEvent).button === 0\r\n } else {\r\n return true\r\n }\r\n}\r\n\r\n// this function is used to fix the issue with circular reference when stringifying an object using JSON.stringify\r\nexport function getJSONReplacerFunc() {\r\n const visited = new WeakSet()\r\n return (key: string, value: any) => {\r\n if (typeof value === 'object' && value !== null) {\r\n if (visited.has(value)) {\r\n return\r\n }\r\n visited.add(value)\r\n }\r\n return value\r\n }\r\n}\r\n\r\n// This is a duplicate from Website repo which is accessible on window.FLibs but this doesn't work on SSR charts\r\nexport const formatDateToStringUS = (date: Date, options?: Intl.DateTimeFormatOptions | undefined) =>\r\n date.toLocaleDateString('en-US', {\r\n day: '2-digit',\r\n month: '2-digit',\r\n year: 'numeric',\r\n ...options,\r\n })\r\n\r\n// randomUUID source: https://stackoverflow.com/questions/105034/how-do-i-create-a-guid-uuid/2117523#2117523\r\nexport function randomUUID() {\r\n return `${1e7}-${1e3}-${4e3}-${8e3}-${1e11}`.replace(/[018]/g, (substring) => {\r\n const c = Number(substring)\r\n return (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16)\r\n })\r\n}\r\n\r\nexport function getUuid() {\r\n return window.crypto?.randomUUID?.() ?? randomUUID()\r\n}\r\n","export type HLC = {\r\n ts: number\r\n count: number\r\n uuid: string\r\n}\r\n\r\nexport const serializeHlc = ({ ts, count, uuid }: HLC) =>\r\n ts.toString().padStart(15, '0') + ':' + count.toString(36).padStart(5, '0') + ':' + uuid\r\n\r\nexport const parseHlc = (serialized: string) => {\r\n const [ts, count, uuid] = serialized.split(':')\r\n return {\r\n ts: Number.parseInt(ts),\r\n count: Number.parseInt(count, 36),\r\n uuid,\r\n }\r\n}\r\n\r\nexport const initHlc = (uuid: string, now: number): HLC => ({\r\n ts: now,\r\n count: 0,\r\n uuid,\r\n})\r\n\r\nexport const compareHlc = (one: HLC, two: HLC) => {\r\n if (one.ts === two.ts) {\r\n if (one.count === two.count) {\r\n if (one.uuid === two.uuid) {\r\n return 0\r\n }\r\n return one.uuid < two.uuid ? -1 : 1\r\n }\r\n return one.count - two.count\r\n }\r\n return one.ts - two.ts\r\n}\r\n\r\nexport const incrementHlc = (local: HLC, now: number): HLC => {\r\n if (now > local.ts) {\r\n return { ts: now, count: 0, uuid: local.uuid }\r\n }\r\n\r\n return { ...local, count: local.count + 1 }\r\n}\r\n\r\nexport const receiveHlc = (local: HLC, remote: HLC): HLC => {\r\n if (compareHlc(local, remote) >= 0) {\r\n return local\r\n }\r\n return { ...local, ts: remote.ts, count: remote.count }\r\n}\r\n","import { useChartLayoutGlobalModelAsyncModule } from '../controllers/chart-settings/async-modules'\r\nimport { useAsyncModule } from './async-modules-utils'\r\n\r\nexport function useChartLayoutGlobalModelAsync() {\r\n const [useChartLayoutGlobalModelModule] = useAsyncModule({\r\n ...useChartLayoutGlobalModelAsyncModule,\r\n isSuspenseMode: true,\r\n })\r\n return useChartLayoutGlobalModelModule.useChartLayoutGlobalModel()\r\n}\r\n","import { CanvasRenderingContext2D as NodeCanvasRenderingContext2D } from 'skia-canvas'\r\n\r\nimport {\r\n CanvasElementType,\r\n ChartEditorEnum,\r\n ChartElementType,\r\n ChartEventType,\r\n IndicatorType,\r\n LayoutType,\r\n OverlayType,\r\n ScaleType,\r\n SpecificChartFunctionality,\r\n TIMEFRAME,\r\n TextAlign,\r\n TextBaseline,\r\n} from '../app/constants/common'\r\nimport ChartModel from '../app/models/chart'\r\nimport ChartLayout from '../app/models/chart_layout'\r\nimport { IChartThemeColors } from '../app/models/constants'\r\n\r\ninterface ISentry {\r\n captureException: (exception: any, captureContext?: { extra: ObjectHash }) => any\r\n captureMessage: (message: string, captureContext?: { extra: ObjectHash }) => any\r\n}\r\n\r\ndeclare global {\r\n interface Window {\r\n Sentry: ISentry\r\n FinvizSettings: ObjectHash\r\n FinvizChartsSettings: ObjectHash\r\n globalChartConfig: RootChartConfigObject\r\n isRenderInProgress: boolean | number\r\n rendersInProgress: number[]\r\n FinvizQuoteTypeCurrent: string\r\n handleScriptNotLoaded: () => void\r\n renderScriptNotLoaded: () => void\r\n gtag?: any\r\n }\r\n\r\n interface Document {\r\n fullscreenElement: any\r\n webkitFullscreenElement?: () => void\r\n mozFullScreenElement?: () => void\r\n msFullscreenElement?: () => void\r\n\r\n webkitExitFullscreen?: () => void\r\n mozExitFullScreen?: () => void\r\n msExitFullscreen?: () => void\r\n }\r\n\r\n interface HTMLElement {\r\n webkitRequestFullScreen?: () => void\r\n mozRequestFullScreen?: () => void\r\n msRequestFullscreen?: () => void\r\n }\r\n\r\n interface Navigator {\r\n msMaxTouchPoints: any\r\n }\r\n\r\n interface Array {\r\n last(): T | undefined\r\n }\r\n\r\n interface String {\r\n padLeft(paddingValue: string): string\r\n startsWith(str: string): boolean\r\n }\r\n\r\n type CanvasCache = Partial>\r\n\r\n interface CanvasRenderingContext2D {\r\n _cache: CanvasCache\r\n // We need to omit `canvas` because it is read only\r\n set>(\r\n key: Key,\r\n value: CanvasRenderingContext2D[Key]\r\n ): void\r\n }\r\n\r\n interface HTMLCanvasElement {\r\n _cache: CanvasCache\r\n }\r\n\r\n interface ImageBitmapRenderingContext {\r\n _cache: CanvasCache\r\n }\r\n\r\n type RenderingContext2DType = CanvasRenderingContext2D | NodeCanvasRenderingContext2D\r\n}\r\n\r\ndeclare module 'skia-canvas' {\r\n interface CanvasRenderingContext2D {\r\n _cache: CanvasCache\r\n\r\n set>(\r\n key: Key,\r\n value: CanvasRenderingContext2D[Key]\r\n ): void\r\n }\r\n}\r\n\r\nexport type TodoObjectHashAnyType = Record\r\nexport type TodoAreaObject = Record\r\nexport type ObjectHash = Record\r\nexport type EmptyObject = Record\r\n\r\nexport type TodoAnyType = any\r\n\r\nexport type ThumbType = string\r\n\r\nexport type PaneArea = {\r\n mouseDown?: boolean\r\n x: number\r\n y: number\r\n scaled: {\r\n x: number\r\n y: number\r\n }\r\n width: number\r\n height: number\r\n cursorX: number\r\n cursorY: number\r\n isCursorInChartWidthBoundaries: boolean\r\n} & T\r\n\r\nexport type Maybe = T | null | undefined\r\n\r\nexport interface DrawingBorder {\r\n color: string\r\n width: number\r\n}\r\n\r\nexport interface TextAttrs {\r\n text?: string\r\n background: string\r\n border?: { width: number; color: string }\r\n lineWidth?: number\r\n font: {\r\n size: number\r\n family?: string\r\n style?: string\r\n weight?: string\r\n }\r\n fillStyle?: string\r\n strokeStyle?: string\r\n angle?: number\r\n lineHeight: number\r\n textAlign?: TextAlign\r\n textBaseline: TextBaseline\r\n padding: {\r\n top: number\r\n right: number\r\n bottom: number\r\n left: number\r\n }\r\n}\r\n\r\nexport interface Point {\r\n x: number\r\n y: number\r\n}\r\n\r\nexport type RequireByKey = Omit & Required>\r\n\r\nexport interface ResizeByThumbFuncProps {\r\n type: ThumbType\r\n difX: number\r\n difY: number\r\n area: PaneArea\r\n}\r\n\r\nexport type ResizeByThumbWithTypeAndDifs = RequireByKey\r\n\r\nexport interface ChartConfigChartPaneElement {\r\n type: ChartElementType | CanvasElementType | IndicatorType | OverlayType | ChartEventType\r\n overlays?: OverlayConfigObject[]\r\n period?: string\r\n code?: string\r\n elementId?: string | null\r\n zIndex?: number\r\n}\r\n\r\nexport interface RendererChartBarProps {\r\n index: number\r\n chartSettingsColors: IChartThemeColors\r\n hasFillAndBorder?: boolean\r\n}\r\n\r\nexport interface ChartConfigChartPane {\r\n elements: ChartConfigChartPaneElement[]\r\n height: number\r\n chart?: ChartConfigObject | ChartModel\r\n}\r\n\r\nexport interface IIdea {\r\n id?: number\r\n date?: string\r\n note: string\r\n}\r\n\r\nexport interface ChartConfigObjectExtended {\r\n editable: boolean\r\n canChangeTicker: boolean\r\n scrollable: boolean\r\n cross: boolean\r\n ideas: boolean\r\n editors: ChartEditorEnum[]\r\n specificChartFunctionality: SpecificChartFunctionality\r\n theme: Theme\r\n layout: LayoutType\r\n uuid?: string\r\n idea?: IIdea\r\n}\r\n\r\nexport interface ChartConfigObject {\r\n width: number\r\n height: number\r\n panes: ChartConfigChartPane[]\r\n premarket: boolean\r\n aftermarket: boolean\r\n dateRange: string | null\r\n hasChartEvents?: boolean\r\n stretch?: boolean\r\n ticker: string\r\n instrument: Instrument\r\n timeframe: TIMEFRAME\r\n chart_layout: ChartLayout\r\n zoomFactor: number\r\n leftOffset: number | null\r\n refreshData: boolean | number\r\n isHideDrawingsActive: boolean\r\n isScrolled?: boolean\r\n scale: ScaleType\r\n}\r\n\r\nexport type RootChartConfigObjectChart = Omit<\r\n ChartConfigObject,\r\n 'chart_layout' | 'leftOffset' | 'zoomFactor' | 'isHideDrawingsActive'\r\n>\r\nexport interface RootChartConfigObject extends Partial {\r\n charts: Array\r\n width: number\r\n height: number\r\n newCharts?: boolean\r\n useGrid?: boolean\r\n}\r\n\r\nexport interface OverlayConfigObject {\r\n color: string\r\n period: string\r\n type: OverlayType\r\n}\r\n\r\nexport enum Instrument {\r\n Stock = 'stock',\r\n Crypto = 'crypto',\r\n MarketSentiment = 'market_sentiment',\r\n Futures = 'futures',\r\n Forex = 'forex',\r\n Group = 'group',\r\n}\r\n\r\nexport enum Theme {\r\n light = 'light',\r\n dark = 'dark',\r\n}\r\n\r\nexport interface IModalConfig {\r\n title: string\r\n inputs: IModalConfigInput[]\r\n inputsErrorMessages: ObjectHash\r\n}\r\nexport interface IOptionType {\r\n value: string | number\r\n label: string\r\n}\r\nexport interface IModalConfigInput {\r\n type: React.HTMLInputTypeAttribute\r\n label: string\r\n name: string\r\n value: number | string\r\n required?: boolean\r\n min?: number\r\n color?: string\r\n step?: number\r\n items?: IOptionType[]\r\n}\r\n\r\n// Keep in sync with config/types/globals.d.ts\r\nexport enum Position {\r\n Above = 'above',\r\n Below = 'below',\r\n}\r\n\r\nexport enum DefaultSpineEvents {\r\n Change = 'change',\r\n Destroy = 'destroy',\r\n Refresh = 'refresh',\r\n Update = 'update',\r\n}\r\n\r\nexport enum CustomSpineEvents {\r\n IndicatorsChange = 'indicatorsChange',\r\n ManualChange = 'manualChange',\r\n}\r\n\r\nexport enum DrawingSpineOptionsEvent {\r\n Remove = 'remove',\r\n}\r\n\r\nexport interface DrawingSpineOptions {\r\n eventType: DrawingSpineOptionsEvent\r\n}\r\n\r\nexport type TodoButtonProps = ObjectHash\r\nexport type TodoButtonTheme = string\r\n"],"names":["module","exports","white","black","inherit","transparent","current","finviz","blue","gray","red","orange","amber","yellow","brightYellow","lime","green","emerald","teal","violet","purple","pink","Array","prototype","last","this","length","String","padLeft","paddingValue","slice","startsWith","str","indexOf","_callbackCache","Spine","bind","ev","callback","that","cb","record","fkey","id","_len","arguments","rest","_key","push","newCb","origCb","model","unbind","item","findIndex","element","iterable","all","index","el","eql","defaults","enabled","collapsed","duration","timestamp","logErrors","withStackTrace","level","logger","console","filterChanges","attrs","props","Object","keys","constructor","name","errorTransformer","error","titleFormatter","title","time","took","parts","toFixed","join","colors","prevState","action","nextState","pad","num","maxLength","repeat","times","toString","printLogEntry","logEntry","options","startedTime","data","formattedTime","getHours","getMinutes","getSeconds","getMilliseconds","titleCSS","headerCSS","formattedTitle","groupCollapsed","group","e","log","styles","trace","groupEnd","initialize","window","protoModelLoad","load","started","Date","now","cid","attributes","returnedValue","apply","badgeImages","getSvgImageCacheKey","badgeType","theme","state","ChartEventElement","ElementModel","initClass","paneModel","configure","belongsTo","yIndex","getChartEventBadgeImage","cacheKey","badgeImage","isLoaded","image","width","height","async","_ref","onBadgeInitLoad","importWithRetry","chartBadgeSvgByType","chartEventsAsyncModule","importFn","handleImageResolve","values","some","_ref2","undefined","ChartEventBadgeState","forEach","badgeState","ChartEventBadgeType","Theme","svgHTML","CHART_EVENT_BADGE_SIZE","img","Image","src","encodeURIComponent","onload","onerror","captureException","Error","extra","fetchAndCacheChartEventBadges","trigger","getChartEventData","instance","chart","quote","chartEvents","find","stockEvent","elementId","toObject","super","toConfig","Indicator","chartModel","Overlay","Chart","Pane","Quote","ChartLayout","DrawingsInternalStore","Element","document","location","hostname","isIPad","Utils","IPAD_FULLSCREEN_CLASS","FullscreenButton","isFullscreen","setIsFullscreen","React","getFullscreenStatus","requestFullscreen","getRequestFullscreen","documentElement","exitFullscreen","getExitFullscreen","onClick","call","checkFullscreen","body","classList","add","remove","addEventListener","removeEventListener","_jsx","Button","leftContent","contentClass","children","SORTED_LAYOUT_KEYS","arr","sort","a","b","reduce","acc","option","sortBy","sortDirection","SORT_DIRECTION","ASC","directionMultiplier","sortObjects","entries","LAYOUTS","map","key","value","ChartLayoutDropdown","_ref3","useLocation","navigate","useNavigate","parsedQuery","decodeQueryString","search","chartLayoutModel","useModelState","watchProperties","getChartsToPath","useChartsPathLocation","useDropdownState","placement","orientation","Dropdown","label","l","_jsxs","className","layout","DropdownItem","appearance","Icon","DropdownSeparator","Paragraph","size","ChartSyncableParts","_ref4","isChartPartInSync","getIsChartPartInSync","active","setSyncChartParts","gtag","event_label","ThemeToggleButton","isDarkMode","updateAttributes","settings","updateSettings","setCookieRequest","catch","BREAKPOINTS","minWidth","Infinity","marketBadgeText","timeFormat","ChartLayoutHeaderComponent","onSettingsOpen","hasPublish","chartLayout","_Fragment","IdeasDropdown","TourButton","page","specificChartFunctionality","Publish","disabled","idea","Time","breakpointMode","breakpoints","ChartLayoutHeader","prevProps","nextProps","StockDetailTimeframeBar","withSuspense","isDateRangeAvailable","isPremium","isLoadingOverride","isScrollIntoViewEnabled","onTimeframeSelect","onDateRangeSelect","useChartLayoutGlobalModelAsync","chartModelUnwatched","getAllCharts","favoriteTimeframes","toggleFavoriteTimeframe","useFavoriteTimeframes","instrument","Instrument","Stock","isLoading","useChartControls","isInteractive","anchorDate","generateChartLayoutRouterPath","timeframeGroupsWithHref","dateRangeGroupsWithHref","isFetching","handleCustomDateRangeValidation","useChartModelCustomDateRangeValues","onDialogSubmit","customDateRangeDialogState","handleDateRangeSelect","getDateRangeTimeframe","useCustomDateRangeDialog","pathGenerator","dateRangeGroups","customRange","dateRange","timeFrameGroups","TimeframeBar","chartIndex","rounding","isRedesignEnabled","selectedTimeframe","timeframe","selectedDateRange","loadingTimeframe","onCustomDateRangeClick","show","onFavoriteTimeframeToggle","containerElement","isFavoritesEnabled","CustomDateRange","dialogState","dateRangeTimeframe","pushIndicators","panes","indicator","cotKeys","COTs","code","elements","type","IndicatorType","Cot","hasPaneWithCOTCode","PANE_HEIGHT_DEFAULT","period","parameters","getChartTypeByTaConfigStyle","style","candlestick","ChartElementType","CandleStick","heikinashi","HeikinAshi","hollowcandlestick","HollowCandleStick","line","LineChart","ohlc","OhlcChart","mergeChartAndTAConfig","chartConfig","taConfig","charts","scale","linear","ScaleType","Linear","percentage","Percentage","logarithmic","Logarithmic","indicators","filter","position","Position","Above","overlays","overlay","color","Below","getPanes","SettingsTab","SidebarDirection","createAlertAsyncModule","saveToPortfolioAsyncModule","AdsProvider","getAdsProvider","FinvizSettings","hasUserPremium","None","adsProvider","Freestar","InvestingChannel","trackPageView","pathname","query","freestarPageView","replace","freestar","queue","trackPageview","portfolioWatchlistTableAsyncModule","assets","logo","logo_light","useTrackPageView","trackInitial","trackAutomatically","initialRender","handleTrackView","tracking","PortfolioQuery","PortfolioMapSizeKey","PortfolioView","PortfolioTableView","PortfolioTableViewLabels","Ticker","Trade","PortfolioSymbolType","PortfolioTransaction","ColumnId","RowKind","ActionKind","cache","errorsCache","ErrorSeverity","defaultCaptureException","exception","captureContext","Sentry","useAsyncModule","onError","errorSeverity","shouldLoadModule","isSuspenseMode","notificationContext","useNotification","setIsLoading","isError","setIsError","getIsMounted","useIsMounted","handleError","high","handleScriptNotLoaded","renderScriptNotLoaded","medium","Notification","timeoutInMs","reload","loadModule","cachedModule","then","mod","err","Component","fallback","NUM_OF_RETRIES","retries","Promise","r","setTimeout","Arrow","static","CanvasElementType","arrow","renderContent","resize","_thumbs","Thumb","x1","y1","x2","y2","getBoundingPointKeys","getDefaults","border","getChartLayoutSettings","ElementSettings","Colors","x","y","context","scaled","roundedXY","getRoundedObject","translateXY","getXYOffsetFromLine","lineWidth","translate","beginPath","set","angle","Math","PI","moveTo","lineTo","stroke","lineAngle","atan2","h","abs","cos","angle1","topx","topy","sin","angle2","botx","boty","getShouldRenderThumbs","renderThumbs","moveBy","difX","difY","isInArea","area","isDrawingElementLockedOrInvisible","math","distanceToSegment","modalConfig","inputs","Brush","brushV1","untranslatedContext","brushPath","cachedFill","previousFill","shouldRenderFill","getContextWithCache","createElement","setFillCache","fill","defaultTransparentFill","isPolyLineClosed","getShouldRenderFill","Path2D","points","i","fx","fy","xc","yc","quadraticCurveTo","point","closePath","getThumbs","firstX","firstY","lastX","lastY","moveByThumb","getIsCreator","onMouseUp","currentDomainMax","currentDomainMin","domain","roundToFixed","roundY","isPointInPath","cachePointPositionTimestamp","positionPointsTimestamps","getTimestampFomPositionX","updateScales","getPositionXFromTimestamp","places","Number","parseFloat","round","overridePlaces","domainDiff","numberOfLeadingZeros","floor","log10","getAutosaveOmittedProperties","getEdgeXYValues","edgeXYValues","minX","min","minY","maxX","max","maxY","default","TailDirection","getTailHalfWidth","halfWidth","p1","p2","dist","distance","Callout","Text","calloutV1","getModalConfigBase","required","textWithoutBackground","text","font","family","weight","fillStyle","lineHeight","textAlign","textBaseline","padding","top","right","bottom","left","background","defaultFill","setupContext","setupTextMetricsCache","ctx","lastAttrs","JSON","stringify","merge","lines","getLines","metrics","measureText","measuredHeight","currentIndex","actualBoundingBoxAscent","actualBoundingBoxDescent","PADDING","S","render","renderText","previousDescent","fillText","getCalloutProperties","textWidth","requiredTailHalfWidth","radius","rectangleSides","topLeft","topRight","rightTop","rightBottom","bottomRight","bottomLeft","leftBottom","leftTop","getRectangleSidesCoordinates","tail","tailRoot","tailTip","getTailCoordinates","tailDirection","twoSegmentLinesIntersection","topLeftCorner","topRightCorner","bottomLeftCorner","bottomRightCorner","topSide","rightSide","bottomSide","leftSide","noTail","getTailToSideIntersection","renderBackground","lineJoin","arcTo","tailLineToTopLineIntersection","tailHalfWidth","tailLineToRightLineIntersection","tailLineToBottomLineIntersection","tailLineToLeftLineIntersection","renderCallout","renderBorder","tailP1","perpendicularPointToLine","pointOffsetX","pointOffsetY","tailP2","polygon","pointInPolygon","getIsInChartView","leftOffset","Curve","curve","x3","y3","drawQuadraticCurve","Bezier","quadraticFromPoints","cp1x","cp2x","cp1y","cp2y","project","d","thumbsAreInArea","Ellipse","ellipse","invert","getCoordinates","centerLeftX","centerLeftY","centerRightX","centerRightY","boundingPointKeys","c","bottomCenterX","bottomCenterY","bezierCurveTo","bottomRightX","bottomRightY","topRightX","topRightY","topCenterX","topCenterY","topLeftX","topLeftY","bottomLeftX","bottomLeftY","rotationAngle","atan","sign","radiusX","radiusY","width_two_thirds","dx1","dy1","dx2","dy2","RotatedRectangle","rotatedRectangle","getRectCoordinates","coords","mx1","mx2","my1","my2","nk","dx","sqrt","dy","x4","y4","SymbolElement","symbol","sx","getRotatedCoordinates","scaleX","sy","textHeight","scaleY","xScale","yScale","xOffset","yOffset","save","rotate","restore","cx","cy","halfHeight","drawingToolsByType","freeze","brush_v1","callout_v1","elliottWaves","ellipseV1","ellipse_v1","fibonacciRetracements","fibonacci","horizontalLine","measure","pitchforkV1","pitchfork_v1","rectangle","rotatedRectangleV1","rotatedRectangle_v1","scaledLine","scaledText","symbolElement","triangle","verticalLine","xabcd","fromObject","obj","getNumOfBarsBuffer","_","isCreator","isCreatorDialogOpen","activeThumb","isMouseDown","isSelected","isHovered","isEditInProgress","onMouseDown","onMouseMove","getIsChartEvent","findByAttribute","__","setIsSelected","setIsHovered","getIsPaneSelection","pane","selection","attrsSubset","customizer","objValue","srcValue","getIsDrawing","mergewith","get","defineProperty","globalAlpha","thumb","startEditing","mouseDown","xPointKeys","positionTimestamps","positionX","pointPoitionsFromTimestamp","chart_layout","isLockDrawingsActive","getIsVisible","getModalConfig","config","input","toAutosaveConfig","omit","replaceMyself","captureMessage","oldElement","newElement","getIsCreatorDialogOpen","release","micro","macro","MicroMacroTimeframe","visibility","isInRange","from","to","setVisibilityTo","setTo","MacroTimeframe","timeframesToSet","attrsToSet","SetVisibilityTo","currentAndAbove","currentAndBelow","currentOnly","assign","xPoints","yPoints","positionY","omitX","isMaxXInvalid","isNaN","isMinXInvalid","omitY","topBound","bottomBound","ElliottWaves","waves","offset","getOffsetFromLineWidth","p","TextBaseline","middle","TextAlign","center","wave","positionWavesTimestamps","EllipseV1","getEllipsePoints","P2","P4","coordinates","P3","P1","CP4","CP1","CP2","CP3","ellipsePath","inverted","cursorTargetX","cursorTargetY","perpendicularPoint","cursor","distanceToLine","lineCenterX","lineCenterY","invertX","invertY","perpendicularPointEllipseOffsetX","perpendicularPointEllipseOffsetY","P1WithOffsetX","P1WithOffsetY","P3WithOffsetX","P3WithOffsetY","controlPointOffsetX","controlPointOffsetY","getRotatedPointCoordinates","rotationAxisPoint","pointToRotate","oldLinePoint","newLinePoint","sharedPointLinesAngle","sharedPoint","rotatedPoinCoordinates","rotatedPointCoordinates","newLeftPoint","leftRotatedCursorPoint","newRightPoint","rightRotatedCursorPoint","FibonacciRetracements","parseCoefficients","coefficients","parsed","split","trim","getMaxCoefficientUnscaledY","getMinCoefficientUnscaledY","heightScaled","includes","_ref5","_ref6","_ref7","maxCoefficientY","minCoefficientY","allYValues","HorizontalLine","ScaledLine","decimalPlaces","updateDecimalPlaces","step","getInstrumentDecimalPlaces","lastClose","ChartSettings","getBarIndex","close","renderLabels","IndicatorSettings","isIndicator","allowDecimal","Line","strokeStyle","dashLength","setLineDash","Measure","x1Dif","x2Dif","startingX1","startingX2","getVolumeSumString","volume","barIndex","roundedX1","roundedX2","minIndexLimit","maxIndexLimit","volMinIndex","volMaxIndex","volumeSum","volumeIndex","numberToStringWithUnitsSuffix","fillRect","priceDif","heightStr","getRoundedString","number","numOfDecimalPlaces","baseX","baseY","getHeight","addToCoordinates","difs","newX1","newX2","paneArea","getEdgeIntersectionPoint","sides","rayOrigin","rayDirection","intersection","intersectionDistance","rayToLineIntersection","getRayToLineSegmentIntersection","getPitchforkCoordinates","rayDirectionControlPoint1","rayDirectionControlPoint2","trend1","trend2","chartVisibleAreaLeftX","chartVisibleAreaRightX","chartVisibleAreaBottomY","chartVisibleAreaTopLeftPoint","chartVisibleAreaTopRightPoint","chartVisibleAreaBottomLeftPoint","chartVisibleAreaBottomRightPoint","getChartVisibleAreaBoundaries","medianRay","trend1Ray1","trend2Ray1","trend1Ray2","trend2Ray2","medianRayDirectionPoint","getMiddlePointOnLineSegment","rayOriginToRayDirectionVector","rayDirectionControlPoint1ToPoint2Vector","normalizedRayDirectionControlPoint1ToPoint2Vector","normalizeVector","medianRayDirectionPointToRayDirectionControlPoint1Distance","trend1Ray","getTrendRayCoordinates","trend","medianToControlPointDistance","normalizedControlToControlPointVector","trendRay1","trendRay2","trend2Ray","medianToTrendLineDistance","trendRayPoint1Origin","addPoints","multiplyVectorByScalar","trendPoint2RayOriginPoint2","subtractPoints","trendRayPoint1DirectionPoint","trendPoint2RayDirectionPoint","Pitchfork","median","trendLines","line1","line2","trendLine","trendLineIndex","solidTrendColor","getHEXWithSpecificAplha","nextTrendLine","outerTrendLines","Polygon","isPolygon","scaledPoints","xPoint","yPoint","targetY","stopY","centerY","stopBaseline","targetBaseline","targetColor","stopColor","targetDif","targetPerc","targetStr","stopDif","stopPerc","stopStr","middle1","result","roundDif","coordType","coordIndex","t","s","Rectangle","strokeRect","RotatedRectangleV1","newMiddleLeftPoint","middleLeftRotatedCursorPoint","newMiddleRightPoint","middleRightRotatedCursorPoint","ScaledText","XXXS","XXS","rect","textBoxX","textBoxY","textBoxWidth","textBoxHeight","DEFAULTS","alphabetic","getMergedPropsWithDefaults","propKey","count","f","MIN_SAFE_INTEGER","testArea","convertArea","rawHight","borderWidth","ThumbSettings","borderColor","thumbWidth","getThumbWidth","Triangle","VerticalLine","XABCD","xx","xy","ax","ay","bx","by","start","toUpperCase","retLabel","len","ret","xab","bcd","result1","canvas","rendered","refresh","ratio","drawImage","cWidth","cHeight","sWidth","screen","sHeight","getScaleRatio","setSizeOnCanvasElement","canvasElement","OHLCType","ChartMinWidthBreakpoints","getChartBreakpoints","chartWidthInPx","isXs","xs","isS","isM","m","isL","getDateString","date","dateString","month","getMonth","year","getFullYear","day","getDate","TIMEFRAME","i1","i2","i3","i5","i10","i15","i30","h2","h4","MONTHS","w","getClosestDifferentMinMaxValueIndices","currentMinIndex","currentMaxIndex","low","hasPreviousIndex","hasNextIndex","minIndex","maxIndex","gray300","tailwindColors","BaseChart","overlaysByType","tickerWidth","changeWidth","lastOhlc","isLargeChart","shouldRenderVolume","afterChange","isMobile","utils","overlayDefinition","convertColorToHEX","addOverlay","renderYAxis","renderCrossText","setupCache","renderOverlaysLabels","CustomSpineEvents","IndicatorsChange","handleIndicatorsChange","mouseModelChangeHandler","mouseModel","unmountCanvas","baseCache","updateShouldRenderVolume","renderChart","renderChartNotAvailable","getIsRedesignedChart","renderTicker","clip","renderVolume","renderOverlays","renderPrevClose","renderFadeExtendedHours","renderGrid","renderXAxis","tickerText","getIsSmallIndexChart","ticker","general","margin","FONT_SIZE","OFFSET","baseline","renderTimeframe","volumeFY","range","Group","getTimeframeLabel","textSecondary","isOurSiteRequest","L","SpecificChartFunctionality","offScreen","XS","M","renderChange","getOHLC","directRender","changePercentage","lastDate","renderOHLC","isSmallIndexChart","isNewestOHLC","open","afterHour","isFinite","afterClose","roundOhlc","lastVolume","toLocaleTimeString","hour","minute","getRoundedLastData","lastOpen","lastHigh","lastLow","renderOverlaysLabelsChartsPage","renderOverlaysLabelsQuotePage","overlayLabel","isRenderedOverlaysLabel","labelSpacing","getLabelColor","getYAxisLeftMargin","Crypto","getYAxisLastCloseLabel","firstVisibleClose","getPercentageFromValue","base","lineTicks","textTicks","lastCloseLabel","getTranslate","do","tickCount","minMax","getMinMax","placesAxis","stepPrice","scaleRange","updateAttribute","minPerc","maxPerc","d3","nice","ticks","tick","getValueFromPercentage","pixelGap","negativeScale","previousNegativeTick","unshift","positiveScale","previousTick","positiveScaleY","getYLineText","val","yTickText","axis","yTickLine","getYLine","resetYTicksStyles","percentageZeroLineText","undo","renderYAxisLabel","yCoordinate","getSecondaryLabelBackgroundColor","stringifyHSVAColor","getHSVAFromColor","currentBackground","getYAxisSecondaryLabelYCoordinate","mainLabelValue","secondaryLabelValue","direction","LINE_HEIGHT","mainLabelValuePosition","secondaryLabelValuePosition","offsetedY","_ref8","currentText","getDrawDays","MarketSentiment","textRenderer","startBarIndex","getVisibleBarToRenderIndex","endBarIndex","chartWidth","render15MinXAxis","renderIntradayXAxis","renderIntradayXAxisFutures","renderDailyXAxis","renderWeeklyXAxis","renderMonthlyXAxis","isXPointVisible","buffer","renderXAxisLabels","_ref9","labels","allowedOverflow","sortedLabels","renderedLabelRanges","reverse","newLabel","hasPriority","_ref10","halfOfTextWidth","overflowLeft","overflowRight","labelX","getIsOverlapping","interval","IntradayTimeframeInterval","marketStartHour","marketStartMinutes","marketEndHour","ceil","aftermarketLengthMinutes","xLine","getXLine","barWidth","getBarWidthWithMargin","zoomFactor","dayToOffset","getDayToOffset","dayIndex","dateFromDateString","drawMinutesPerDay","roundedX","premarketLengthMinutes","_ref11","lastDay","lastHours","NaN","hours","_ref12","indexOffset","getBarsInDay","_ref13","lastMonth","_ref14","gridSecondary","isYearLabel","substring","_ref15","lastYear","isJanuary","getIsIndicatorPresent","Vol","getVolumeTicks","maxHeight","fontHeight","renderVolumeAxis","relativeVolume","grid","rangeMax","volumeAxisFontSize","volumeAxis","format","tickFormat","domainFrom","domainTo","setupAxisTimeFrame","halfBarWidth","getHalfBarWidth","barWidthWithoutMargin","getBarWithoutMarginWidth","drawInVisibleArea","drawBarCallback","volumeTrendDown","volumeTrendUp","renderCross","isRendered","contentWidth","contentHeight","getRoundDecimalPlaces","price","getPlacesLastClose","onRenderCrossText","getCrossIndexForPane","setElementCursor","getHTMLElementId","conditionalCursor","getDataByCrossIndex","crossIndex","shouldReturnRoundedString","n","getDataByBarIndex","getCrossIndexChange","crossDataIndex","getDataIndexByBarIndex","crossClose","previousClose","getTickerChangeFromCloseValues","anchorClose","prevClose","dateByBarIndex","virtualTradedDates","getVirtualTimeframeTradedDates","dateStart","dateEnd","_ref16","change","tickerChange","tickerAfterChange","getTickerChange","isOffscreen","isGroupInstrument","finvizWatermarkOffset","changeText","percentString","string","getChangeColor","afterChangeText","afterChangeTextWidth","oneLineAHChangeWidth","renderOHLCChartsPage","renderOHLCQuotePage","_ref17","chartBreakpoints","OhlcText","canvasFill","dateElements","trendColor","oElements","hElements","lElements","cElements","volElements","changeElements","getFlatLineArrayWithSpaces","lineElements","flatMap","startX","lineElement","LabelsText","numberOfNewOhlcLines","_ref18","dateOnly","timeOnly","lineTopY","OHLCFontSize","centerXOffset","leftXOffset","OHLC","ohlcString","singleLine","OHLC_TEXT","getOHLCType","ohlcSettings","getOHLCSettings","CHART_MARGIN","XXL","alignTop","renderOHLCToCanvas","_ref19","ohlcSet","isSingleLineWithChange","parseInt","n0","n1","x0","premarketFade","aftermarketFade","shouldShowPrevClose","isStock","isIntradayWithPreMarket","TIMEFRAMES_WITH_PRE_MARKET","isIndexChart","smallIndex","Cache","getIsMobileChartPage","setupAxis","volumeHeight","firstBarToRenderIndex","lastBarToRenderIndex","volumes","getAreNoBarsVisible","addMarginBottom","marginBottom","setOverlays","removeOverlay","splice","MAX_VALUE","MIN_VALUE","prevMin","closestMinMaxIndices","placesLastClose","priceAbs","hasOverlay","chartPage","getCandleLikeChartsRenderingColors","overwrittenColors","getColorOverwrites","overwrittenColorKeys","hasOverwrittenCandleColor","colorKey","light","getShouldUseDarkerWickColors","totalBarWidth","darkerWickColors","thinBarColorsOverride","isRedesignedPage","getRenderChartBarProps","chartSettingsColors","hasFillAndBorder","trendDown","trendUp","borderDown","borderUp","wickDown","wickUp","wickColor","barFillColor","barFillWidth","barBorderWidth","getBarWidthWithMarginByParts","shouldRenderFillAndBorder","translateForWick","WICK_WIDTH","candleBodyHigh","candleBodyLow","candleWickHigh","candleWickLow","candleBodyHeight","candleBodyLeftX","halfBorderWidth","getIsSSr","isBodyHeightGreaterOrEqualBorders","isWickLineCandleLessThanOnePixel","hasBorder","fillHeight","hasFill","isHollow","generalTrendColor","ohlcTrendUp","ohlcTrendDown","zeroChange","haData","getHeikinAshiData","getLastValues","originalLatestClose","heikinLatestCloseLabel","originalLatestCloseLabel","first","redLine","greenLine","MarketSentimentSettings","sum","_data","lastIndex","_dataLastIndex","renderLineBullBear","array","oversold","overbought","isRedesign","marketDown","marketUp","_compute","computeVisibleMinMax","yLine","fillUp","fillDown","percent","months","MultiLineChart","tickersDimensions","ColorsSettings","quotes","getQuotes","tickers","end","asc","maxTickerLength","isLastDate","closeValue","arrays","q","select","isIdeaId","ideaID","OHLCChart","barWithoutMarginWidth","lineThickness","handleLengthFromWick","lineOffset","barX","PerfChart","overlayLabelWidth","perf","shouldRenderDate","tickerData","MARGIN","hasData","percentageText","lastCrossIndex","fromDate","toDate","filteredQuotes","closes","daysCount","end1","asc1","end2","asc2","monthsInData","availableTickSpots","monthsToAvail","renderMonth","chartsByType","candleStick","heikinAshi","hollowCandleStick","lineChart","marketSentiment","multiLineCharts","ohlcChart","perfChart","XXXL","XL","SETTINGS_HEIGHT","TICKER_TIMEFRAME_CHANGE_HEIGHT","ChartEditorEnum","LayoutType","OverlayType","ChartEventDbType","ChartEventType","ChartEventLabels","Dividends","Split","EarningsPositive","EarningsNegative","EarningsNeutral","EarningsFuture","columns","rows","gridAreas","DESC","TimeframeLabelShort","DateRangeType","TIMEFRAME_SECONDS","CRYPTOS","BTCUSD","LTCUSD","ETHUSD","XRPUSD","BCHUSD","BTCEUR","LTCEUR","ETHEUR","XRPEUR","BCHEUR","LTCBTC","ETHBTC","XRPBTC","BCHBTC","QuotePollingIntervalInMs","EXTRA_MARKET_BUFFER_MINUTES","ScaleLabel","INDICATOR_LABEL_HEIGHT","MOBILE_BARS_TO_VIEW","MOBILE_VIEW_BREAKPOINT_WIDTH","FREE_DATE_RANGES","QuotePageQueryChartTypes","minutes","days","weeks","MicroTimeframeRange","prev","curr","QUOTE_FETCH_EVENT","PREMARKET_AFTERMARKET_HOURS","CHART_ELEMENT_ID","getContainerTypeFromPaneConfig","indicatorElement","getContainerType","mainElement","indicatorType","isChart","updateInternalStoreWithChangedElement","changeType","currentInternalStore","lastUpdateTimestamp","getQuoteRawTicker","containerType","destroyed","instanceJson","newDrawing","zIndex","lastChange","elementAttrs","newInternalStore","updateDrawingIndex","drawingElement","shouldSyncAndSave","updatedRecord","hasChangedZIndex","hasChangedType","hasChangedAttrs","hasChange","getTickersAndContainerTypesInLayoutModel","containerTypes","getAllPanes","mergeUpdatedDrawingsToInternalStore","updatedDrawings","isRefetchAll","newLastUpdateTimestamp","updatedElementIds","drawing","receiveHlc","drawingIndex","currentDrawing","currentNote","getElementNoteText","autoSavedNote","incrementHlc","parse","compareHlc","getInitialStoreDrawings","initialDrawings","initialDrawingsStore","FinvizChartsSettings","drawings","getAutosaveElementFromDBRecord","handleCallMethodOnAllDrawings","elementMethod","getAllElements","isDrawing","getNoteElementId","noteElement","getTickerNoteText","ts","lastChangeTimestamp","lastChangeCounter","uuid","lastChangeNodeUUID","getDBRecordFromAutosaveElement","utmCampaign","quotePage","futuresPage","forexPage","cryptoPage","PopoverInner","hidePopover","chartSettingsModule","chartSettingsAsyncModule","onClose","ScrollableChartSettingsPopover","isOpen","forceGlobalRerender","getIsConfigChanged","confirmationDialogState","usePopoverState","hide","checkChangesAndOpenDiscard","preventDefault","discardChangesAndHide","buttonPosition","popoverContentElement","getState","disclosureElement","getBoundingClientRect","scrollY","chartHeight","chartElement","getElementById","clientHeight","Popover","minHeight","classNames","PopoverRounding","regular","PopoverTheme","Delayed","Spinner","ConfirmationDialog","actions","as","DialogDismiss","ChartSettingsButton","settingsPopoverState","useState","buttonProps","PopoverTrigger","href","encodeQueryString","utm_source","utm_medium","utm_campaign","focusRing","getQuoteRequestKey","unwatchedChartModel","chartModelRef","modelRef","useModelRef","abortControllerKeyRef","isIdeaChart","updateChartModelWithNewQuote","isSameTicker","getRawTicker","getChartOrIndicatorElement","getLeftOffset","isScrolled","getAllQuotes","chartQuote","fetchData","fetchType","QuoteFetchType","NewerData","chartPane","getChartPane","activeChartEvent","toggleIsOpen","getAllChartEvents","isChartEvent","isPreserveDrawingsActive","destroyCascade","setChartEvents","updateChartEventsZIndexes","fetchQuote","hasChartEvents","premarket","aftermarket","patterns","getHasPatterns","currentQuote","abortController","createRequestAbortController","shouldAbortRunningRequest","events","cachePredicate","fetchNewDataOnCachedQuote","wasFetchAborted","isQuoteUsedInOtherCharts","fetchedAt","destroy","removeFromAbortCache","decodedQueryString","rangesArray","ranges","every","shouldRecalculateOnCharts","barMargin","hasSameBarWidth","hasSameBarMargin","setIsFetching","dateFromUnixTimestamp","generatePathForTimeframeDateRange","timeframeUtm","getTimeframeGroupsWithHref","generatePath","timeFrame","getDateRangeGroupsWithHref","dateRangeState","numOfVisibleBars","getVisibleBarsNumber","getChartStartEndDates","unwatchedChartLayoutModel","hasSyncedTimeframe","ChartSyncablePart","Timeframe","syncChartParts","hasSyncedTicker","decodedSearch","urlTickers","urlTimeframes","urlDateRanges","chartsArrayPlaceholder","currentTicker","timeframes","currentTimeframe","currentDaterange","Boolean","sidebar","getIsMobilePortrait","getTimeframeGroups","timeFrameGroup","QuoteNodeChartTypes","QuoteUrlChartTypes","QuoteShortToLongType","cs","candlesticksimple","o","ha","hc","QuoteLongToShortType","DEFAULT_TYPES","icon","FREE_TYPES_QUOTE","FREE_TYPES_QUOTE_VALUES","useChartLayoutGlobalModelAsyncModule","preventClosingUnsavedChangesAsyncModule","BackgroundInput","onChange","InputColorPicker","inputDataTestId","toLocaleLowerCase","ColorRangeRowInput","colorValue","colorTestId","rangeValue","rangeTestId","rangeLabel","rangeProps","handleRangeChange","useCallback","currentTarget","handleColorChange","RangeSlider","rightContent","BorderInput","CheckBox","Checkbox","checked","FONT_VALUES","FontInput","setFamily","setSize","setStyle","setWeight","setValue","valueSetter","Label","Select","items","selected","Input","LineInput","MultilineStringInput","Textarea","placeholder","target","autoFocus","NumberInput","pattern","StringInput","Trend","valueAsNumber","VisibilityInput","isCheckboxOnly","isOff","setIsOff","setFrom","macroKey","macroLabel","charAt","INPUTS_AVAILABLE","getInitialState","visibilities","macroTimeframe","valueMacroTimeframe","getIsVisibilityOutsideAvailableTimeframes","macrotimeframe","macroRange","Visibility","initialVisibilityRef","handleChange","handleDisableSubmit","TAB_BUTTON_COMMON_PROPS","getValuesFromFormState","formState","cur","DialogTabs","ElementStyleDialog","initialFormStateRef","setFormState","selectedTab","setSelectedTab","Style","isSubmitDisabled","setIsSubmitDisabled","isDrawingElement","handleValuesChange","shouldSubmit","shouldDismiss","hasOnSubmit","onSubmit","hasOnDismiss","onDismiss","handleValuesChangeDebounceRef","debounce","newFormState","maxWait","cancel","checkValidity","handleCloseDialog","Dialog","isDraggable","modal","backdrop","onFullyClosed","onHide","DialogHeader","onCloseClick","DialogBody","ButtonGroup","hasDivider","InputComponent","getInputForType","inputType","stateInput","DialogFooter","ElementStyleDialogContext","ElementStyleDialogWrapper","setElement","setOnSubmit","setOnDismiss","dialog","useDialogState","Provider","openDialog","DRAWINGS_SAVE_INTERVAL_MS","RETRY_LIMIT","useDrawingAutoSaveApi","postRetryCountRef","deleteRetryCountRef","fetchDrawings","fetchApi","queryParameters","throwOnStatusCodes","saveDrawings","bodyJsonString","keepalive","hi","charCodeAt","lo","getByteLengthOfString","method","contentType","ContentType","ApplicationJson","latestChangeHlc","InternalServerError","ForbiddenError","GoneError","newTicker","response","message","GenericStatusCodeError","invalidItems","deleteAllDrawings","lastLocalChange","newHlc","useDrawingAutoSaveControls","isAutoSaveActive","isInit","getIsPreserveDrawingsAndAutosaveAvailable","useIsAutoSaveActive","drawingsInternalStore","saveTimeoutRef","clearTimeout","saveLatestChanges","withDelayInMs","saveQueueExtraFilterCallback","saveQueue","latestLocalUpdateTimestamp","instanceUUID","setAutoSaveState","AutoSaveState","Unsaved","Saving","Saved","syncChartLayoutDrawings","isRemove","paneContainerType","paneInternalStoreElements","autoSaveElement","paneElement","paneDrawing","parsedElementAttrs","hasOngoingInteraction","getCanvasElementByType","create","handleAutoSaveNoteChange","note","newNoteElement","handleIdeaNoteChange","activeChart","checkDrawingUpdate","latestRemoteUpdateTimestamp","initHlc","allElements","normalizeZIndexes","activeTicker","updateInternalStoreWithElement","updateResult","deleteAllAutoSavedElements","onElementChange","elementPane","elementContainerType","elementPaneTicker","eventType","DrawingSpineOptionsEvent","Remove","useDrawingAutoSave","drawingsInternalStoreUnwatched","prevIsAutoSaveActive","ref","usePrevious","runInitialSaveAndRefetchUpdate","Off","onChartOrIndicatorChange","newTickers","newContainerTypes","ChartModel","checkDrawingUpdateInterval","setInterval","unregisterListeners","clearInterval","willDestroy","ChartTypesSelect","chartTypes","getCurrentType","ta","ty","taInt","isQuotePage","defaultType","FinvizQuoteTypeCurrent","generateRouterPath","reloadDocument","useChartTypes","currentType","selectedType","setSelectedType","nativeSelect","CHANGE_UPATE_EVENTS","QUOTE_MODEL_CHANGE_EVENTS","ChangeLabel","changePoints","isTiny","classnames","DailyChangeDisplay","listenOnEvents","quoteModel","testId","DrawButton","newValue","getIsDrawingEnabled","DRAWING_COOKIE_NAME","expires","setMonth","setCookie","finally","getLayoutType","tickersCount","Search","onTickerSelected","dropdownState","saveToPortfolioDialogState","isSaveToPortfolioVisible","createAlertDialogState","isCreateAlertVisible","saveToPortfolioModule","isLoadingSaveToPortfolio","createAlertModule","isLoadingCreateAlert","SaveToPortfolio","CreateAlert","detailLink","formattedTicker","Futures","Forex","WebsiteSearchComponent","inputClass","isSearchIcon","isSearchItemLink","isShowAllVisible","event_category","hasRedesignEnabled","ChartControls","handleTickerSelect","upperCaseTicker","handleCustomRangeSubmit","timeframeBarProps","canChangeTicker","hasTimeframe","editors","Heading","tools","editable","ideas","compactViewMaxBreakpointPx","grow","publish","ContextMenu","contextMenu","selector","componentDidMount","update","componentWillUnmount","forceUpdate","shown","querySelector","onContextMenu","ContextMenuComponent","ready","ReactDOM","event","clientY","pageYOffset","clientX","ChartEventPopoverWithState","unwatchedChartLayout","popoverState","isPopoverMounted","chartEventsModule","isChartEventOfThisChart","setData","clickAwayRef","isListening","refCallback","handler","contains","useClickAway","chartEvent","popoverShow","popoverHide","newData","getChartEvenBadgeType","PopoverAnchor","store","ZIndexContext","AriakitPortal","tabIndex","hideOnInteractOutside","focusable","autoFocusOnShow","ChartEventPopoverContent","delayComponent","LoadLatestDataButton","isMountedRef","hasNewDataAvailable","setHasNewDataAvailable","getRefreshInterval","isPossibleToFetchSequentialData","hasNewData","promises","refreshData","ZOOM_CONTROLS_ACTIVE_CLASS","ZOOM_CONTROLS_IS_IN_AREA_CLASS","buttonCommonProps","getDefaultLeftOffset","ZoomControls","zoomControlsRef","isVisible","onZoomIn","onZoomOut","onZoomReset","isGoToRecentVisible","setIsGoToRecentVisible","defaultZoomFactor","isZoomResetVisible","setIsZoomResetVisible","handleGoToMostRecent","handleChartModelChangeDebounced","hidden","rafId","crossRafId","paneRef","scalerRef","zoomerRef","canvasWrapperRef","canvasRef","crossCanvasRef","paneHammer","scalerHammer","zoomerHammer","canvasWrapperHammer","lastClientX","lastClientY","currentViewRange","lastActiveTool","scalerLastY","isElementHovered","hoveredElement","isDisableTouchCrossAvailable","canvasCtx","crossCanvas","crossCanvasCtx","isIndicatorPane","hasSeenCrossNotification","localStorage","getItem","onModelUpdate","onElementCreate","onElementDestroy","onElementReplace","onElementSelect","onElementClone","immediateRecountScaleOnChartIndicatorChange","recountScale","ManualChange","onChartUpdate","activeTool","MouseModel","getIsIndicatorPane","renderAll","initialStoreDrawings","Hammer","touchAction","threshold","on","onPress","onTouchMove","passive","scrollable","onScalerReset","onZoomerReset","onDoubleClick","CHART_LAYOUT_CHILD_CHANGE_EVENT","touchEventsDisabled","onPaneClick","paneIndex","getIsHammerAllowScrollActive","isChartPane","getIsChartPane","onPaneMouseMove","onMouseLeave","onPaneMouseLeave","onTouchStart","onResizerMouseDown","initialScrollable","onScalerMouseDown","onMouseEnter","onScalerMouseEnter","onScalerTouchStart","onZoomerMouseDown","onZoomerMouseMove","onZoomerTouchStart","DrawingTool","Mouse","onAddToZoomFactor","diff","shouldCalculateRightAlign","onCanvasInteractionStart","onCanvasInteractionMove","onTouchEnd","onBlur","getChartAlt","cross","isTouchCrossActive","oldElementInstance","isDrawingModeContinuousActive","setSelection","onPaneDestroy","setSelectedElement","clonedElementInstance","setCanvasSize","getArea","onMouseMoveOnScrolling","activeChartInteraction","TouchEvent","targetTouches","dif","addToLeftOffset","onScalerTouchMove","onScalerMouseMove","onScalerTouchEnd","onScalerMouseUp","setActiveChartInteraction","MouseEvent","button","originalMinMax","currentDiff","originalDiff","getMinMaxLeftOffset","newLeftOffset","fetchOlderData","getElement","openElementStyleDialog","pointerType","onCanvasPress","elementInArea","elementModel","hasProperties","isElementDrawing","makeClone","bringToFront","sendToBack","bringForward","sendBackward","handleRemoveIndicatorPane","element_type","updateType","requestAnimationFrame","process","_renderAll","getIsUpdatedDesign","renderPane","isCharts","isRedesignedFuturesForexCrypto","isMouseInPane","getShouldRenderCrossInPane","clearRect","isCrossDisabled","PaneModel","getIsDisabled","elementInstance","additionalData","Settings","getSettings","areaRectangle","areaRectangleCursorX","areaRectangleCursorY","chartLeftX","chartRightX","cursorX","cursorY","isCursorInChartWidthBoundaries","isChartsPage","setState","setItem","inline","_this","isMouseDownIgnored","zoomControls","paneHeight","touchEvent","setMousePosition","getMousePositionInBoundaries","isTouch","onCanvasInteractionEnd","Touch","isPrimaryClick","CanvasElement","canvasAreaRectangle","chartLeft","chartRight","chartTop","chartBottom","getValueInRange","isSameMouseModel","isSelectionCanvas","getCanvasDOMNode","withNotificationContext","withElementStyleDialogState","ChartSpinnerOverlay","shouldDisplay","setIsVisible","timeout","DEFAULT_WRAPPER_COMPONENT","preventDefaultFunc","lastWidth","mouseWheelTimeout","setStateWithPanesTimeout","lastHeight","resizerPaneIndex","minimalPaneHeight","zoomerRightAlign","layoutModel","onLayoutModelChange","panesWrapperElement","onPaneCreate","calculateMinimalPaneHeight","handleQuoteChange","onModelChange","onOlderDataLoaded","Refetch","onDataLoaded","componentDidUpdate","isWheelZoomEnabled","handleSetPanesWrapperRef","renderChartToolbar","isChartPage","getAllValidPanes","showSettings","resetMouseModel","onPinchStart","onWheel","onMouseWheel","addToZoomFactor","calcZoomerRightAlign","activePane","paneId","chartModelParam","panesHeight","newPaneHeight","newChartPaneHeight","newIsScrolled","onResizerMouseMove","onResizerMouseUp","resizePanesAccordingly","total","optiMinHeight","basePane","touches","onZoomerTouchMove","onZoomerTouchEnd","onZoomerMouseUp","getRawDistance","onPinchMove","onPinchEnd","currentLeftOffset","isIntraday","offsetDiff","shouldAlignDaysToLeftApplied","offsetBars","normalizeWheelDeltaY","deltaY","isMouseWheel","diffCoefficient","currentZoomFactor","minBarWidthInPx","maxBarWidthInPx","minZoomFactor","getZoomFactorForBarsToDisplay","chartVisibleWidth","maxZoomFactor","isNegativeDirection","newZoomFactor","newZoomFactorInRange","getZoomFactor","stretch","updateZoomAndLeftOffsetByDateRange","newQuote","shouldForceLeftOffsetUpdate","WrapperComp","gridArea","isModelDestroyedRef","initChartRef","panesConfig","panesWithPerfIndicator","allSettled","paneWithPerfIndicator","prefetchPerfIndicatorAllQuotes","paneProperties","createPaneCascade","shouldResize","chartsDimensions","getChartsDimensions","handleModelBeforeDestroy","isFuturesForexCryptoPage","isModelReady","loadingStyle","hasOutline","withWatchedPanesOnChartModel","drawingCreatorsAsyncModule","drawingActions","DrawingActions","AddNote","DeleteDrawings","DeleteAutoSavedDrawings","getToolbarDrawingActions","isAddNoteAvailable","isIdea","defaultItem","isDisabled","disabledTooltip","drawingSettings","DrawingSetting","PreserveDrawings","iconActive","titleActive","DrawingModeContinuous","HideDrawings","LockDrawings","preserveDrawingsAutosaveOverride","iconAction","titleAction","getToolbarDrawingSettings","isPreserveDrawingsAndAutosaveAvailable","isAutoSaveInProgress","isInAction","drawingTools","Xabcd","toolbarDrawingTools","toolGroup","toolGroupTitle","DISABLED_ITEM_TOOLTIP_LABEL","Toolbar","isSidebar","isHorizontal","isMobileOverlay","onActiveToolChange","onDrawingActionClick","onDrawingSettingClick","onDrawingEnd","isAlternativeTheme","areToolsDisabled","drawingCreatorsModule","isDrawingCreatorsModuleLoading","autoSaveState","setIsDrawing","availableDrawingSettings","availableDrawingActions","isDrawingModeContinuous","hasHiddenDrawings","tool","drawingToolsTouchCreatorsByType","drawingToolsCreatorsByType","ToolClass","one","ToolbarComponent","isActive","isToolLoading","ToolbarItem","groupItems","groupTitle","useNativeSelect","ToolbarDivider","ChartAutoSaveNote","onNoteChange","ChartAutoSaveNotes","setTickers","unwatchedInternalStore","handleChartChange","tickerNoteMap","AutoSaveNotesDialog","isAnimating","isFullyClosed","hideOnEsc","onAction","onCancel","isAutosaveDialogContent","dialogContent","getDialogContent","ConfirmationDialogComponent","ToolButton","ToolbarMobile","isToolbarVisible","setIsToolbarVisible","urlSearchParams","setUrlSearchParams","useSearchParams","toolbarMobileElement","setToolbarMobileElement","MOBILE_TOOLBAR_DIV_ID","handleActiveToolChange","drawingTool","wrapperRef","handleClickOutside","openSelect","actionId","has","SIDEBAR_QUERY_PARAM","params","delete","AutoSaveStateIndicator","setVisibilityTimeout","newIsVisible","checkIfNeededPreventLeaving","returnValue","hasRedesign","ChartLayoutAutoSaveNote","chartLayoutModelUnwatched","ideaNoteRef","getPublishChartHtmlElements","publishChartElements","getElementsByClassName","getChartImgUrl","imgElement","PublishOldButtonClickListener","dialogConfig","setDialogConfig","isCanvas","chartImgUrl","publishModalModule","publishModalAsyncModule","PublishDialog","publishChartHtmlElements","clickHandler","dataset","indexInt","IdeaDrawingsConfirmationOptions","IdeaLeaveDialog","actionCallback","Cancel","Override","Merge","Nothing","getChartElementTypeFromQueryType","queryType","getChartElementTypeFromResponseType","TA","useChartRouteChange","isIdeasDialogOpen","dateFns","updateChartConfig","urlType","handleTypeChange","urlTicker","urlTimeframe","urlDateRange","getInstrument","newChartConfig","getRawTickerForInstrument","updateAttributesAndSync","exitIdea","defaultPeriod","defaultDateRange","handleIdeaLeave","getUuid","ChartLayoutComponentBase","orientationChangeTimeout","preserveDrawingAbortController","AbortController","modelProperties","isHideDrawingsActive","isToolbarHorizontal","handleInitialPreserveDrawingsState","DELETE","getPaneWithSelection","keyCode","touchSize","onChartDestroy","setToolbarPosition","onWindowResize","handleOrientationChange","checkTouchEventsDisabled","abort","throttledResize","preserveDrawings","toolsState","handlePreserveDrawingsSettings","setPreserveDrawings","URLSearchParams","tools_state","handleResize","modelAttrs","throttle","newIsToolbarHorizontal","innerWidth","test","getVisualViewportScale","visualViewport","handleDrawingAction","noteDialogState","toggle","handleConfirmationDialogDeleteBtn","drawingToRemove","handleDrawingsSetting","settingId","newObj","toggleHideDrawings","handleLockDrawings","renderToolbar","args","isOverlayToolbar","newCharts","useGrid","isMobilePortrait","isSidebarEnabled","getIsSidebarEnabled","ChartGrid","ChartGridCell","Sidebar","onShouldResize","horizontal","hasChartTools","renderTools","ideaTitleContainer","ideaTitle","clear","updateLayout","removeCharts","addCharts","rowStart","columnStart","rowEnd","columnEnd","numOfRowsCovered","numOfColumnsCovered","percentageOfRowsCovered","percentageOfColumnsCovered","newWidth","newHeight","settingsHeight","wantedCount","pop","ChartLayoutComponent","flowRight","checkQuoteCacheDebounce","cleanupQuoteCache","allQuotes","allChartQuotes","usedQuote","withCompleteLayoutModelInit","updateChartsTitle","defaultDocumentTitleRef","percentageChange","useChartPageTitle","handleChartsUpdate","getChartLayoutWithChartRouteChange","withQuotePolling","isWithNotifications","Wrapper","NotificationWrapper","ChartLayoutWithGlobalState","parentElement","setChartLayoutModel","getChartLayoutModelConfig","lastGlobalRerender","onRegisterChartLayoutModel","getDefaultZoomFactor","OnInitListener","setIsInit","checkIfInitIsComplete","elementIndex","opacity","newConfig","dark","concat","isQuotePageWithDrawingsOff","getCookie","noteDrawing","ideaObject","newElements","ChartLayoutModel","pollingIntervalToCharts","setPollingIntervalToCharts","checkForChartsWithPolling","newPollingIntervalToCharts","chartRefreshInterval","intervalIdsRef","checkForChartsWithPollingDebounced","chartsCheckerIntervalId","timeoutDurations","allCharts","timeoutDurationsMin","timeoutId","chartIds","quotesToUpdate","quoteToUpdate","dispatchEvent","Event","getIdeaUrl","searchObject","isStockOnQute","queryString","IdeaItem","onIdeaDeleted","isDeleting","setIsDeleting","isConfirmDelete","setIsConfirmDelete","currentIdea","onDeleteIdeaClick","wasDeleted","fetch","status","newUrl","URL","searchParams","company","stopPropagation","IdeasTabs","hasError","setHasError","hasFetched","setHasFetched","categorizedIdeas","setCategorizedIdeas","queryTickers","dateParts","processed","tickerIdeas","categorizeIdeas","fetchIdeas","handleIdeaDeleted","modifiedCategories","categoryIndex","updatedCategory","updatedAll","Tabs","TabList","category","Tab","Badge","TabPanel","toLowerCase","IdeasDialog","hasPadding","dropdownButtonClassName","tooltipState","useTooltipState","isAnyQuoteLoading","setIsAnyQuoteLoading","dropdown","hideTooltip","dropdownItemProps","TooltipTrigger","checkIfAnyQuoteIsLoading","fetchingQuotes","visible","closeOnClick","activeChartQuote","toJSON","chartId","layoutModelObjectPanes","tickersString","getChartTickers","quotesJsonString","quoteTickersTimeframes","getFormDataFromObject","ideaUrl","saveIdea","Tooltip","getIsMobileScreenSize","isDialogOpen","tour","useTour","pageTours","steps","overlayPadding","getTour","userTour","setCurrentTour","getStepsForUser","buttonTheme","hasNewTours","activeTour","startTour","once","CustomDateRangePrefixEnum","DATE_RANGE_PREFIX_DELMITER","getParsedDateRange","startInSec","getTime","endInSec","lastQuoteDateIndex","lastVisibleBarIndex","d1","d5","firstVisibleBarIndex","quoteDate","isQuoteDateInRange","numOfBarsOffset","getChartZoomAndLeftOffset","numOfBarsToRender","numberOfBarsToDraw","daysInQuote","getDaysInQuote","dateRangePrefix","dateRangeValue","Range","dateFromString","dateToString","dateFrom","dateTo","Prev","years","parseCustomDateRangeUrlParam","convertLocalToNyTime","setHours","startDateIndex","m1","m3","m6","ytd","y5","numOfBarsInView","getIntradayChartConfig","timeframeMinutes","barWidthWithMargin","hasPremarket","hasAftermarket","maxWidth","canCropChart","fullChartWidth","marketMinutesLength","getFullChartWidth","offsetInPx","shouldCropChart","chartWidthWithOffset","offsetChartAfter","shouldAlignDaysToLeft","drawDaysInOneChart","lastQuoteDate","barsToOffset","offsetChartInPx","isStockIntraday","isIntradayDateRange","isOffScreen","isOffScreenWithNoDateRange","isOffScreenIntradayDateRange","isOffScreenWithFixedBars","isQuotePageWithNoDateRange","isQuotePageIntradayDateRange","isQuotePageWithFixedBars","getShouldOffsetChartDomain","scaleType","handleDomainOffset","currentScale","scaleCreator","protectedHeightPx","minPx","extendedMin","rounded","fromEntries","parsedRange","startQuoteDate","endQuoteDate","numOfDaysToRender","reversedDaysInQuote","startQuoteDayIndex","endQuoteDayIndex","renderDateStart","renderDateEnd","getParsedDateRangeMetaData","shouldRenderCross","DEFAULT_WIDTHS","DEFAULT_CONTEXT","activeModule","isCloseVisible","onResize","selectModule","SidebarContext","useSidebarContext","ModuleLoadFailed","DefaultErrorBoundary","portfolioWatchlistAsyncModule","SidebarModule","sidebarModules","portfolio","description","content","asyncModule","withInitialLoading","isComponentReady","setIsComponentReady","sidebarModule","withModuleAsyncLoad","mobile","SidebarTabs","showTimeout","vertical","isHideOnClick","SidebarContent","defaultMobile","defaultDesktop","desktop","Resizable","enable","handleClasses","defaultSize","tabsClassName","sidebarModuleKey","setActiveModule","handleSelectModule","newUrlSearchParams","handleCloseSidebar","contextValue","ErrorBoundary","FallbackComponent","getInstrumentLabel","getResponseChartType","chartType","chartResponseType","tr","ChartEvent","getChartEventModel","chartEventModel","getXYPosition","hover","isOpenOverride","isCurrentEventActive","scaledArea","Earnings","eventItem","epsActual","epsEstimate","dateTimestamp","chartEventsByType","dividends","earnings","canvasElements","indicatorsByType","elementType","BigNumber","BIG_NUMBER_VALUES","Thousand","Million","Billion","Trillion","BIG_NUMBER_ZEROES","BIG_NUMBER_SUFFIX","dotProduct","crossProduct","pow","lineEquation","k","j","oddNodes","l2","formatBigNumber","minNumber","absNum","getString","suffix","zeroes","splitString","addZeroes","padEnd","numberByZeroesCount","isInteger","yAxisCoeficient","xAxisCoeficient","radAngle","p3","p4","denominator","ua","ub","checkLineIntersection","line1_p1","line1_p2","line2_p1","line2_p2","onLine1","onLine2","numerator1","numerator2","rayEnd","segmentStart","segmentEnd","lineIntersection","v","scalar","isSamePoint","ExponentialMovingAverage","multiplier","EMACalculation","MainCalculation","Ema","getDefaultCalculatedValues","ema","calculate","onValueCalculated","_calculatedValues","calculatedValues","getAllCalculatedValues","lastNItems","getCalculatedValues","getDbColumnName","key1","key2","localeCompare","MAX_POSITIVE_DEFAULT_VALUE","MAX_NEGATIVE_DEFAULT_VALUE","periodInt","getParsedIntegersFromPeriodString","labelWidth","lastValue","shouldUpdate","compute","renderIndicator","getIsChartPageSpecificFunctionality","renderLabel","isComputeNecessary","tickTextStep","formatAxis","valueY","indicatorCurrentText","indicatorCurrentBackground","renderLabelChartsPage","renderLabelQuotePage","indicatorLabel","roundedRect","isPerfIndicator","Perf","renderCrossTextChartsPage","renderCrossTextQuotePage","renderOversoldOverbought","zero","drawLines","drawInVisibleAreaProps","fromIndexOffset","getCompensatedFirstBarToRenderIndex","clipHeight","renderZeroLine","tickStep","newAttrs","parsePeriodInt","setModel","areNoBarsVisible","getDomainDefaults","inputsErrorMessages","Rvol","Atr","Adx","Aro","Mfi","Rmi","Rsi","Stofu","Ult","Macd","Rwi","Trix","Wr","Aroosc","Roc","Cci","Fi","INDICATOR_DEFAULT_DOMAIN","getIsValid","getIsNumberInputValid","integerOnly","isPositiveInteger","ADX","pdi","mdi","adx","amdm","apdm","atr","deltaHigh","deltaLow","pdm","mdm","di","AroonCalculation","aroonUp","aroonDown","oscillator","highPeriod","highestInPeriod","periodSinceHigh","lastIndexOf","lowPeriod","lowestInPeriod","periodSinceLow","COLORS","Aroon","aroonCalculation","textLabels","labelSetting","AroonOscillator","ATR","AverageTrueRange","CommodityChannelIndex","cci","smaCount","tp","smaSum","devCount","typicalPrice","sma","devSum","dev","COT","cotQuoteCode","cot","commercialHedgers","largeTraders","smallTraders","units","renderAdditionalLabels","secondarylabelX","fontSettings","secondarylabel","FICalculation","fi","ForceIndex","fiCalculation","MACDCalculation","macd","signal","histogram","fastPeriod","slowPeriod","signalPeriod","emaFast","emaSlow","emaSignal","MACD","macdCalculation","signalLine","MFI","mfi","negativeMoneyFlow","mf","prevTypicalPrice","positiveMoneyFlow","moneyFlow","oldMF","OBV","Obv","obv","currentObv","PricePerformance","firstFetchCalled","indicatorLabelWidth","getTickers","chartUuid","hasCachedData","getTickersAndTimeframe","getAll","firstBarTime","lastBarTime","dateToIndex","getDateToIndex","perfArrays","crossIndexTickerTimeStamp","tickerDateToIndex","tickerPerformance","performanceIndicatorLabel","isVertical","labelBottom","canFitItemsVertically","tickerQuote","maxCrossIndex","tickerTextWidth","crossText","getSanitizedTicker","RMI","rmi","momentum","u","ad","au","sumu","sumd","rs","ROC","roc","RsiCalculation","rsi","RSI","rsiCalculation","DEFAULT_PARAMETERS","RelativeVolume","rvol","baseLine","periodStr","parsePeriod","baseLineY","RWI","rwiHi","rwiLo","trSum","atrWeight","maxHi","maxLo","Stochastics","k1","kPeriod","dPeriod","dCount","dSum","kSum","kCount","highestHigh","lowestLow","StochasticsFast","Stofa","StochasticsSlow","Stosl","TrixCalculation","trix","ema1","ema2","ema3","trixCalculation","UltimateOscillator","period1","period2","period3","ult","bp","bpSum2","bpSum3","count2","count3","trSum2","trSum3","avg2","avg3","bpSum1","trSum1","count1","avg1","Volume","WilliamsR","none","aro","aroosc","rwi","stofa","stofu","stosl","vol","wr","getWatchedPropValue","watchedProp","spineObject","getIsSpineObject","hasToObject","getJSONReplacerFunc","getWatchedProps","getAreWatchedPropsEqual","currentValue","previousValue","DEFAULT_SPINE_EVENTS","DefaultSpineEvents","stringifiedOptions","useForceUpdate","watchedPropertiesRef","handleModelChange","isArray","spineEvents","hasMany","getChartElement","getChartType","defaultRefreshInterval","Default","customRefreshInterval","Elite","isStockFastRefreshAvailable","EliteStocksReduced","Free","omitKeys","getIsScrollable","perfQuotes","quotePerfTickers","quotePerf","chartOrIndicator","attrsInSync","ChartPartToAttrsSyncMap","modelAttr","hasOwnProperty","chartParts","isInSync","chartPart","shouldClear","allChartEvents","Crosshair","drawingsInternalStoreModel","chartPartsToSync","newSyncedChartParts","normalizeHexAlpha","hexString","customColors","customColorKeys","defaultColors","chartLightTheme","chartDarkTheme","crossTextBackground","negativeChange","overlayTransparentBackground","positiveChange","indicatorLightTheme","indicatorDarkTheme","elementLightTheme","elementDarkTheme","generalColors","newAutoSaveState","generateUuid","getElementZIndexRange","oldInstance","pane_id","clonedObj","cloned","moveToZIndex","currentZIndex","directionCoef","newZIndex","elementsBelowZero","elementsAboveZero","getBelowAboveZeroElements","changeElementZIndexes","elementsArray","addElement","oldZIndex","isBelowZero","isOverlay","refreshElementId","MARKET_START","END_OF_DAY","roundTimeForSyncedPane","sourceChart","targetChart","dateToReturn","sourceChartHasPremarket","targetChartHasPremarket","setDate","lastDayOfMonth","lastDayOfWeek","weekStartsOn","endOfDay","getIsDateBeforeMarketStart","getIsCrossSyncOn","getIsMouseInChartOfPane","paneOfMouse","mouseInChart","currentPaneChart","mousePositionTimestamp","currentPanePositionX","getPriceForPane","mousePaneIndex","getIndexInChart","mouse","CHART_EVENT_BADGE_TYPE_ORDER","chartEventElementModel","move","chartPanes","targetPane","currentChartPaneRecords","records","chart_id","ohterChartPaneRecords","targetRecordIndex","arrayWithoutTargetRecord","chartRecordIndex","panesAbove","panesBelow","getNumericId","isSorted","resetHeight","allPaneElements","rebuildElementZIndexes","hoveredChartEvent","openedChartEvent","hoveredTypeChartEventElements","openedTypeChartEventElements","nonActiveChartEventElements","chartEventsOnSameXPoint","chartEvent_B","isOpened","isHoveredType","isOpenType","quoteCache","getCachedQuote","cachedAt","setCachedQuote","emptyQuote","numberOfRefreshChecks","is404","patternsMinRange","patternsMaxRange","dataId","tickerRaw","shouldUseCache","doesQuoteAndFetchParamsMatch","isSameOrNoChartUuid","isNotEmptyQuote","isCacheAllowed","hasPatterns","doesQuoteAndOptionsMatch","getResolvedFetchingPromise","maxBars","tickersAndTimeframes","accumulator","fetchRequest","QuoteFetchTypeUrlOption","New","fetchingPromise","getUrl","getIsAbortError","NotFoundError","shouldUseEmptyQuote","Newer","noNewData","newQuoteData","lastTime","afterTime","AIndex","BIndex","mergeIndex","ADate","BDate","prevAIndex","prevDate","newDate","isSameWeek","isSameMonth","warn","thisDateLength","dataDateLength","atts","drawDays","getBarIndexes","barToDataIndex","getChartEventsWithId","deleteCachedQuote","cachedHeikinAshiData","HAClose","heikAshiData","cachedDayToOffset","dateStringFromDate","yyyy","mm","dd","padStart","dataIndex","cachedDateToIndex","getTimestampFromPositionX","host","env","BE_API_URL","rev","clearData","largeChartFontSize","INTERACTIVE_CHART_SETTINGS","tickerTimeframeChangeHeight","chartSettings","colorsOverride","settingColors","isLight","getNormalizedZIndex","BbCalculation","Bb","stdDev","upperBand","lowerBand","deviations","stdDevSum","getFreeColor","periods","getRGBAValueFromValidColorString","BB_COLORS","TOP","BOTTOM","MIDDLE","BollingerBands","scaledTop","scaledBottom","firstBarToRender","lastBarToRender","bbCalculation","topColor","bottomColor","DonchianChannels","Dch","medianBand","strokeColor","channelStrokeColor","fillColor","channelFillColor","medianBandColor","EMA","EMA2","Ema2","HighLow","Hilo","highColor","prevHigh","lowColor","prevLow","prevBar","Hline","isPositiveFloat","Stroke","Fill","Conversion","Base","SpanB","conversion","spanB","IchimokuCloud","Ic","renderFull","outsideBar","spanAFillColor","spanAStrokeColor","spanBFillColor","spanBStrokeColor","baseLineColor","conversionLineColor","laggingSpanColor","conversionLine","senkouSpanA","senkouSpanB","conversionStartIndex","baseStartIndex","spanBIndex","highestHi","lowestLo","lastSpanAX","lastSpanBX","cloudStartingX","toIndexOffset","fxOverride","IchimokuCloudFull","Icf","KeltnerChannel","Kch","emaPeriod","atrPeriod","middleLine","Patterns","originalScale","barsInDay","aboveBelow","textHS","above","below","supportColor","resistColor","kind","Calculation","PivotPeriod","PivotPoints","Pp","calculationType","getPeriodType","week","getIsEnoughData","startIndex","endIndex","periodType","dayGap","startDay","beforeDay","calculatedX","fromX","toX","currentDate","previousTradingDay","previousNYMidnightTimestamp","currentMidnight","currentNYMidnightTimestamp","isNonStockFullDay","isStockFullDay","firstDayCurrentWeek","firstDayCurrentWeekTimestamp","firstDayPreviousWeek","firstDayPreviousWeekTimestamp","firstDayCurrentMonth","firstDayCurrentMonthTimestamp","firstDayPreviousMonth","firstDayPreviousMonthTimestamp","firstDayCurrentYear","firstDayCurrentYearTimestamp","firstDayPreviousYear","firstDayPreviousYearTimestamp","pivot","sup1","sup2","sup3","res1","res2","res3","previousHigh","previousLow","pivotPoint","currentX","toBars","nextDate","SAR","Sar","maxStep","isLong","sar","ep","newHigh","newLow","af","sarToDraw","risingColor","fallingColor","customizable","SMACalculation","Sma","SMA","SMA2","Sma2","Supertrend","Str","finalUpperBand","finalLowerBand","supertrend","uptrendColor","avg","downtrendColor","VP_COLORS","applyOpacityToColor","VolumeProfile","Vp","upColor","downColor","minClose","maxClose","segment","segments","up","down","segmentIndex","isInSegment","volumeTrend","volumeFX","segmentHeightRaw","segmentHeight","upSegmentWidth","downSegmentWidth","VWapCalculation","Vwap","vwap","cumulativePV","cumulativeVolume","second","datesAreOnSameDay","VWAP","bb","dch","hilo","hline","ic","icf","kch","pp","sma2","vp","arg","_len2","_key2","_len3","_key3","devicePixelRatio","getQuoteDateTimestampOffsetInSeconds","referenceDate","dayNumber","monthIndex","previousSunday","getDay","getIsDstInNy","getUTCFullYear","getUTCMonth","getUTCDate","getUTCHours","getUTCMinutes","getUTCSeconds","addOffset","quoteDateTimeOffsetInMs","localTimeOffsetInMs","getTimezoneOffset","offsetDirectionCoefficient","setTime","bufferMinutes","dayOfWeek","currentDayMinutes","premarketMinutes","aftermarketMinutes","isWeekend","isClosed","setUTCSeconds","testTouchPoints","isMobileOs","navigator","userAgent","createEvent","match","msMaxTouchPoints","maxTouchPoints","matchesIPad","matchesIPhone","matchesIPod","re","RegExp","cookie","toUTCString","fullscreenElement","webkitFullscreenElement","mozFullScreenElement","msFullscreenElement","webkitRequestFullScreen","mozRequestFullScreen","msRequestFullscreen","webkitExitFullscreen","mozExitFullScreen","msExitFullscreen","fn","readyState","chartElementId","box","matchingPages","requestsAbortControllersCache","abortRequest","controller","websiteShared","shouldUseCPUOnly","matchesAndroid","matchesWebOS","matchesiPad","matchesBlackBerry","matchesWindowsPhone","matchesIOSLike","isMobileDevice","isFirefoxDesktop","getContext","willReadFrequently","_cache","_restore","CanvasRenderingContext2D","getChartEventBadgeColors","outerStroke","innerStroke","innerFill","textFill","getFormattedEventDate","exdate","hasEarningsDateSuffix","parsedDate","formattedDate","formatDateToStringUS","getFormattedValue","bigNumberUnit","maxDecimalPlaces","numberString","bigNumber","wholeNumber","decimalNumber","formattedDecimalNumber","getChartEventBageColors","twColors","DAY_IN_SECONDS","TWO_MIN_IN_MS","virtualDatesCache","areTimestampsFromSameDay","ts1","ts2","ts1Utc","ts2Utc","getVirtualDatesCacheId","idRevision","setCachedVirtualDates","fromSeconds","toSeconds","virtualDates","virtualDatesCacheId","lastUsed","checkVirtualCacheSize","MAX_BAR_BORDER_WIDTH","MIN_BAR_MARGIN_WIDTH","MAX_BAR_MARGIN_WIDTH","settingsCenter","barMarginWidth","shouldRound","roundDecimalPlaces","halfBarWidthRaw","DEFAULT_ZOOM_GUESS_INCREMENT","zoomFactorForBarsToDisplayCache","zoomFactorForBarsToDisplayCacheKeys","getZoomFactorFromCache","setZoomFactorToCache","poppedKey","defaultBarWidthWithMargin","zoomIncrement","finalZoomFactor","iteration","barWidthDiff","getTimeframeSeconds","lowerIndex","dates","upperIndex","isWithinRangeOfQuoteDate","commonVirtualCacheProps","cachedDates","virtualDateSeconds","getCachedVirtualDates","timeframeSeconds","firstDate","numOfDatesBefore","numOfDatesAfter","virtualTradedDays","dateStartSeconds","dateEndSeconds","datesSeconds","isStartBeforeDates","isEndAfterDates","dateTime","getVirtualTradedDays","marketStartSeconds","barTimeframeSeconds","quoteDatesTimestampOffset","dayStartSeconds","barSeconds","virtualTimeframeTradedDates","isLowerBounded","isOneBeforeLowerBoundStarts","lastDateIndex","isLookingBack","averageBarDate","numOfSecondsOutOfBounds","perfIndicatorElement","getPerfIndicatorTickerAndTimeframes","resolve","isXAxisInView","domainRange","priceFy","YAxisLeftMargin","firstBarClose","_ref20","changePercent","changePercentString","_ref21","isForexFuturesCryptoPage","_ref22","isForexFuturesCrypto","isOffscreenChartWithNarrowBars","isQuoteChartWithNarrowBars","_ref23","hexStringToRGBA","hexColor","removeHashSymbol","g","rgbaToHexString","alpha","alphaToHex","rgbaToHSVA","hsvaToRGBA","rgbaToRGBAString","rgbaStringToObject","colorParts","exec","strColor","allowAlpha","getIsRgb","rgbKeys","output","canSelectAlpha","hsvaToHEXString","dataBarIndex","isBarVisible","object","formData","append","FormData","statusCode","throwOnPredicate","url","credentials","headers","responseContentType","Html","responseData","ApplicationJsonUTF","FormUrlEncoded","parseResponseForContentType","getStatusCodeError","forceUpdateKey","increment","precision","periodString","part","parsedNumber","MAX_SAFE_INTEGER","visited","WeakSet","toLocaleDateString","crypto","randomUUID","getRandomValues","Uint8Array","two","local","remote","useChartLayoutGlobalModelModule","useChartLayoutGlobalModel"],"sourceRoot":""}