{"version":3,"file":"static/js/e90b90cb72c38893b506.bundle.js","mappings":";mSAIM,MAAOA,EAITC,YAAYC,EAAmCC,GAMxC,KAAAC,sBAAwB,IACpBC,KAAKC,MAAMC,qCACd,2BACA,EACAC,EAAAA,cACA,QACA,CACIC,YAAa,MACbC,aAAc,0BAElB,IAID,KAAAC,kBAAoB,KAAe,EAEnC,KAAAC,YAAc,IAAM,wBAAwBP,KAAKF,OACjD,KAAAU,mBAAqB,IAAM,uBAC3B,KAAAC,cAAgB,IAAiB,UAvBpCT,KAAKF,KAAOA,EAEZE,KAAKC,MAAQ,IAAIS,EAAAA,kBAwBzB,MAKaC,EAAgCC,MAAOC,EAAqCC,IAChFA,EAAIC,eAAejB,KAAKkB,sBAGRC,EAAAA,EAAAA,qBAA8BJ,EAAMd,wBAAyBe,GAF7D,GAMZI,GAA0BC,EAAAA,EAAAA,IAA2B,CAC9DC,GAAI,wCACJC,OAA2BV,EAC3BE,MAhBiBS,IAAiF,IAAAC,EAClG,MAAM,KAAEzB,GAASwB,EAAUP,eAC3B,OAAO,IAAIpB,EAA6B2B,EAAUP,eAAelB,YAAuC,QAA5B0B,EAAEzB,EAAK0B,6BAAqB,IAAAD,EAAAA,EAAI,OAiBhH,4JC7CM,SAAUE,EACZC,EAA2CC,GAG3C,MAAM1B,GARC,IAAIS,EAAAA,kBAQyCkB,eAAeF,GAEnE,OADAzB,EAAM4B,IAAI,KACH5B,EAAMC,qCACT,kCACA,EAAMC,EAAAA,6BACN,OACA,CAAEC,YAAa,OAAQC,aAAc,oCACrC,CACIsB,WAAYA,IAKjBf,eAAekB,EAAoCC,EAAmBJ,GACzE,MAAMK,EAAUP,EACZM,EAAQL,qBAAuB,GAAIC,GAEvC,aAD0BV,EAAAA,EAAAA,qBAAqDe,EAASD,EAAQE,ksBCoB9F,MAAOC,EAyBTtC,YACIuC,EACAtC,EACA6B,EACAU,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,GAgBG,KAAArC,YAAc,KACjB,MAAMmB,EAAmBmB,EAAAA,EAAA,GAClB7C,KAAK0B,oBAAoBoB,SACzBC,EAAAA,EAAAA,IAAK/C,KAAK0B,oBAAoBsB,UAoBrC,OAjBiBC,EAAAA,EAAAA,kBACbjD,KAAKH,YACL,CAAEqD,IAAK,WAAYC,MAAOnD,KAAKmC,UAC/B,CAAEe,IAAK,WAAYC,MAAOnD,KAAKqC,UAC/B,CAAEa,IAAK,aAAcC,MAAOnD,KAAKsC,YACjC,CAAEY,IAAK,YAAaC,MAAOnD,KAAK0C,WAChC,CACIQ,IAAK,WACLC,MAAOnD,KAAKoC,SAASgB,KACjBC,GACI,mBAAmBA,EAAQC,wCAAwCD,EAAQE,sBACvE,4BAA4BF,EAAQG,uBAAyB,QAG7E,CAAEN,IAAK,sBAAuBC,OAAOM,EAAAA,EAAAA,iBAAgB/B,IACrD,CAAEwB,IAAK,SAAUC,MAAOnD,KAAKyC,UAK9B,KAAAjC,mBAAqB,IAAM,yBAE3B,KAAAC,cAAgB,IAAiB,UA1CpCT,KAAKmC,SAAWA,EAChBnC,KAAKH,YAAcA,EACnBG,KAAKqC,SAAWA,EAChBrC,KAAKsC,WAAaA,EAClBtC,KAAK0B,oBAAsBA,EAC3B1B,KAAKoC,SAAWA,EAChBpC,KAAKuC,kBAAoBA,EACzBvC,KAAKwC,qBAAuBA,EAC5BxC,KAAKyC,OAASA,EACdzC,KAAK0C,UAAYA,MAAAA,EAAAA,EAAa,EAC9B1C,KAAK2C,8BAAgCA,EACrC3C,KAAK4C,iBAAmBA,GA2DzB,MAAMc,EAA4BA,CACrCC,EACAC,KAEA,MAAMzB,EACyC,aAA3CwB,EAAK5C,eAAe8C,UAAU1B,UAA4BwB,EAAK5C,eAAed,OAAS0D,EAAK5C,eAAed,MAAM6D,WAC3G,WACA,SAEJpC,EAAsBqC,EAAAA,yBAAyBC,cAAcL,GAAMM,oBACnEC,GAAgBC,EAAAA,EAAAA,IAAuBR,EAAK5C,gBAC5CwB,MA3IoBjB,EA2IqBqC,KA1I9BrC,EAAU8C,aAAiDC,IAAvC/C,EAAU8C,OAAO7B,oBAA0E,IAAvCjB,EAAU8C,OAAO7B,mBAD9G,IAA8BjB,EA4I1B,MAAMkB,EAhIV,SAA+BlB,GAA+D,IAAAgD,EAC1F,QAAyB,QAAjBA,EAAChD,EAAU8C,cAAM,IAAAE,IAAhBA,EAAkBC,oBA+HEC,CAAsBb,GAC7CjB,GAAY+B,EAAAA,EAAAA,IAAad,EAAK5C,gBAMP,IAAA2D,EAA7B,GAJIf,EAAK5C,eAAed,OAAS0D,EAAK5C,eAAed,MAAM0E,UACvDjD,EAAoBsB,QAAU,CAAE4B,QAAuBC,KAAKC,MAAMC,mBAAmBpB,EAAK5C,eAAed,MAAM0E,YAGlG,aAAbxC,EACA,OAAO,IAAIyB,EACPzB,EACAwB,EAAK5C,eAAelB,YACpB6B,EACAwC,IACEP,EAAK5C,eAAe8C,UAAUmB,QAAWrB,EAAK5C,eAAed,OAAS0D,EAAK5C,eAAed,MAAM6D,YAAe,GACxF,QAD0FY,EACnHf,EAAK5C,eAAed,aAAK,IAAAyE,OAAA,EAAzBA,EAA2BO,EAC3B1C,EACAC,EACAmB,EAAK5C,eAAe0B,OACpBC,GAED,GAAiB,WAAbP,GAAyBwB,EAAK5C,eAAed,OAAS0D,EAAK5C,eAAed,MAAMgF,IAAMtB,EAAK5C,eAAed,MAAMiF,eACvH,OAAO,IAAItB,EACPzB,EACAwB,EAAK5C,eAAelB,YACpB6B,EACAwC,OACAG,EACAV,EAAK5C,eAAed,MAAMgF,EAC1B1C,EACAC,EACAmB,EAAK5C,eAAe0B,OACpBC,GAED,GAAiB,WAAbP,GAAyBwB,EAAK5C,eAAed,OAAS0D,EAAK5C,eAAed,MAAMiF,eAAgB,CACvG,IAAI5C,EAAa,GAUjB,OARIA,EADAqB,EAAK5C,eAAed,MAAMkF,UACbN,KAAKO,UAAU,CACxBC,UAAW1B,EAAK5C,eAAed,MAAMkF,UACrCG,eAAgB3B,EAAK5C,eAAed,MAAMiF,eAC1CK,WAAY5B,EAAK5C,eAAed,MAAMgF,IAG7BJ,KAAKO,UAAU,CAAEE,eAAgB3B,EAAK5C,eAAed,MAAMiF,eAAgBK,WAAY5B,EAAK5C,eAAed,MAAMgF,IAE3H,IAAIrB,EACPzB,EACAwB,EAAK5C,eAAelB,YACpB6B,EACAwC,OACAG,EACA/B,EACAC,EACAC,EACAmB,EAAK5C,eAAe0B,OACpBC,GAED,GAAiB,WAAbP,GAAyBwB,EAAK5C,eAAed,OAAS0D,EAAK5C,eAAed,MAAMuF,YAAa,CACpG,MAAMlD,EAAauC,KAAKO,UAAU,CAAEK,YAAa9B,EAAK5C,eAAed,MAAMuF,cAC3E,OAAO,IAAI5B,EACPzB,EACAwB,EAAK5C,eAAelB,YACpB6B,EACAwC,OACAG,EACA/B,EACAC,EACAC,EACAmB,EAAK5C,eAAe0B,OACpBC,GAIR,MAAM,IAAIgD,MAAM,0VCnOd,MAAOC,EAGT/F,YAAmBgG,GAQZ,KAAArF,YAAc,IAAc,qCAAqCsE,KAAKO,UAAUpF,KAAK4F,YAMrF,KAAApF,mBAAqB,IAAc,sBAMnC,KAAAC,cAAgB,IAAiB,OAnBpCT,KAAK4F,SAAWA,GA6FjB,MAOP,GAP8DzE,EAAAA,EAAAA,IAA2B,CACrFC,GAAI,uFAEJC,OA1DGT,eACHC,EACAkB,GAEA,IAAI8D,EACJ,IAAIC,EAAAA,gBAAgBC,YAAYlF,EAAM+E,UAGlC,OAAOI,QAAQC,QAAQ,IAFvBJ,EAAgBhF,EAAM+E,SAASxC,KAAI8C,GAAWA,EAAQC,WAK1D,MAAMzD,GAAY+B,EAAAA,EAAAA,IAAa1C,EAAQhB,gBAEjCqF,EAAkC,CAAEC,WAAYtE,EAAQhB,eAAelB,YAAYyG,UAAWC,UAAW7D,GAG/G,IACI,MAAM8D,QAAsBC,EAAAA,EAAAA,sBAAqB,CAAExE,cAAeF,EAASL,oBAAqBqC,EAAAA,yBAAyB2C,qCAAqC3E,IAC1JqE,EACAP,EACA,IAAIc,KACJ,KACA,MACA,GACA,GACA,GAEEC,EAAiB/F,EAAM+E,SAASxC,KAAI8C,IACtC,MAAMW,EAAcL,EAAcM,MAAKC,GAASA,EAAM1B,YAAca,EAAQC,WAC3D,IAAAa,EAAAC,EAAAC,EAAAC,EAAbN,IACAX,EAAQkB,OAAQC,EAAAA,EAAAA,GAAiBR,GACjCX,EAAQoB,MAA2C,QAAtCN,EAAGH,EAAYU,+BAAuB,IAAAP,EAAAA,EAAId,EAAQoB,MAC/DpB,EAAQsB,UAAYC,KAAKC,IACA,QADGT,EACxBJ,EAAYW,iBAAS,IAAAP,EAAAA,EAnBnB,EAoB6B,QADGC,EAClCL,EAAYc,2BAAmB,IAAAT,EAAAA,EApB7B,EAqBuB,QADmBC,EAC5CN,EAAYe,qBAAa,IAAAT,EAAAA,EArBvB,GAuBNjB,EAAQ2B,aAAehB,EACvBX,EAAQ4B,iBAAkB,GAE9B,OAAO5B,KAGX,OAAOF,QAAQC,QAAQW,GACzB,MAAOmB,GAIL,MAFAhG,EAAQiG,UAAUC,UAAUF,GAC5BhG,EAAQiG,UAAUE,MAAM,sEAClB,IAAIxC,MAAM,wEAWpB7E,MAtE+D+E,GACxD,IAAID,EAAuCC,KCbhD,MAAOuC,UAAyCjG,EAAAA,EAAtDtC,kCAKW,KAAAY,mBAAqB,IAAc,0BAMnC,KAAAC,cAAgB,IACZ,QAkBR,IAAK2H,GAAZ,SAAYA,GAIRA,EAAA,kBAKAA,EAAA,kBAKAA,EAAA,kBAdJ,CAAYA,IAAAA,EAAoC,KA0DzCxH,eAAeyH,EAClBC,EACAvG,EACAwG,EACA5F,GAEA,MAEM6F,EAAiCF,EAAqBlF,KAAIqF,IAC5D,MAAMC,GAAcC,EAAAA,EAAAA,yBAAwBF,EAAqB1G,EAAQhB,eAAelB,aAMxF,OAJI6I,IACAD,EAAoBG,gBAAkBF,GAGnCD,KAKX,GACI1G,EAAQhB,eAAe8H,IAAIzE,OAAO0E,iBAAmBC,EAAAA,gBAAgBC,YACd,IAAvDjH,EAAQhB,eAAe8H,IAAIzE,OAAO6E,iBAElC,MAAO,CACHrD,SAAU4C,EACVU,MAAOX,MAAAA,EAAAA,EApBqB,GA+CpC,MAAO,CACH3C,SAxBmB4C,EAA+BpF,KAAIqF,IACtD,GAAI3C,EAAAA,gBAAgBC,YAAY0C,EAAoBU,iBAChD,IAAK,MAAMC,KAAWX,EAAoBU,gBAElCxG,QACqB0B,IAArB+E,EAAQjD,UACRiD,EAAQjD,WAAaxD,EAA8B0G,mCAEG,QAAtDtH,EAAQhB,eAAe8H,IAAIzE,OAAOkF,iBAClCF,EAAQG,YAAc5G,EAA8B6G,wCAMpDJ,EAAQG,UAAY,IAKhC,OAAOd,KAKPS,MAAOX,MAAAA,EAAAA,EAjDyB,EAmDhCkB,gCAAiC9G,EAC3BA,EAA8B0G,uCAC9BhF,EACNqF,kCAAmC/G,EAC7BA,EAA8BgH,kDAC9BtF,GAuOP,MAAMuF,GAAmBzI,EAAAA,EAAAA,IAA2B,CACvDC,GAAI,qFACJC,OA9NJT,eAAsBC,EAAyCkB,GAAuB,IAAA8H,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAClF,IAAIC,EACAC,EACAC,EACJ,MAAMC,EAA6C,GACnDA,EAAoBC,QAAU,CAAElE,UAAWtE,EAAQhB,eAAelB,YAAYyG,UAAWC,UAAW1F,EAAM6B,WAE1G4H,EAAoBE,WAAa3F,KAAKC,MAAMD,KAAKO,UAAUvE,EAAMuB,SAASqI,UAC1EH,EAAoBI,kBAAoB7J,EAAM0B,kBAC9C+H,EAAoBK,sBAAuB,EAC3CL,EAAoBM,gBAAkB/J,EAAMyB,WAI5C,IAAK,IAAIuI,EAAQ,EAAGA,EAAQP,EAAoBE,WAAYM,OAAQD,IAAS,CACzE,MAAMzB,EAAUkB,EAAoBE,WAAYK,GAEoC,IAAAE,EAApF,GAAI3B,EAAQ4B,qBAA8D,iBAAhC5B,EAAQ4B,oBAC9C5B,EAAQ4B,oBAAsBnG,KAAKC,MAAMD,KAAKO,UAAmD,QAA1C2F,EAAClK,EAAMuB,SAASyI,GAAOG,2BAAmB,IAAAD,OAAA,EAAzCA,EAA2CN,UAI3GH,EAAoBE,YAAaS,EAAAA,EAAAA,IAA4BlJ,EAASuI,EAAoBE,aAEtFU,EAAAA,EAAAA,IAAoBnJ,UACdoJ,EAAAA,EAAAA,IAAuBpJ,EAASuI,SAGpCc,EAAAA,EAAAA,IAAwBrJ,EAASuI,GAGnCF,EADAvJ,EAAM8B,8BACiC0I,EAAAA,YAAYpF,QAAQpF,EAAM8B,gCAE1B2I,EAAAA,EAAAA,gCAA+B,CAAErJ,cAAeF,IAE3F,MAAMY,QAAsCyH,EAKtCxH,EAAmB0H,EAAoBE,WAAW1D,MACpDzD,GAAWA,EAAQC,mBAAoBX,MAAAA,OAA6B,EAA7BA,EAA+B0G,qCAE1E,GAAIzG,EAAkB,CAClB0H,EAAoBE,WAAaF,EAAoBE,WAAWe,QAC5DlI,GAAWA,EAAQC,mBAAoBX,MAAAA,OAA6B,EAA7BA,EAA+B0G,qCAG1E,MAAMmC,EACF5I,EAAiBW,wBAAyBZ,MAAAA,OAA6B,EAA7BA,EAA+B6G,wCACzE5G,EAAiBY,yBAA0Bb,MAAAA,OAA6B,EAA7BA,EAA+B6G,uCACxEiC,GAAwBC,EAAAA,EAAAA,IAAiC/I,EAA+B6I,IAEzDlB,EAAoBE,WAAWmB,MAChEtI,GAAWA,EAAQC,mBAAoBmI,MAAAA,OAAqB,EAArBA,EAAuBnI,oBAE7BmI,GACjCnB,EAAoBE,WAAWoB,KAAKH,GAI5C,IAAqC,QAAjC5B,EAAA9H,EAAQhB,eAAe8H,IAAIzE,cAAM,IAAAyF,OAAA,EAAjCA,EAAmCgC,+BAAgCzD,EAAqC0D,QAAS,CACjH,MAAMC,GAAY,EACZC,GAA+BN,EAAAA,EAAAA,IAAiC/I,EAA+BoJ,IAEzDzB,EAAoBE,WAAWmB,MACvEtI,GAAWA,EAAQC,mBAAoB0I,MAAAA,OAA4B,EAA5BA,EAA8B1I,oBAE7B0I,GACxC1B,EAAoBE,WAAWoB,KAAKI,GAK5C,IAAK1B,EAAoBM,iBAAoD,QAArCd,EAAI/H,EAAQhB,eAAe8H,IAAIzE,cAAM,IAAA0F,GAAjCA,EAAmCmC,yBAA0B,CACrG,MAAMA,EAA2BlK,EAAQhB,eAAe8H,IAAIzE,OAAO6H,yBAGnE,GAAIA,EAAyBC,MAAM,SAAU,KAAAC,EAAAC,EACzCvL,EAAMa,oBAAoBsB,QAA2C,QAApCmJ,EAAGtL,EAAMa,oBAAoBsB,eAAO,IAAAmJ,EAAAA,EAAI,GACzEtL,EAAMa,oBAAoBsB,QAAQ4B,QAAmD,QAA5CwH,EAAGvL,EAAMa,oBAAoBsB,QAAQ4B,eAAO,IAAAwH,EAAAA,EAAI,GACzF,MAAMC,EAAqB,QAAQJ,IACFpL,EAAMa,oBAAoBsB,QAAQ4B,QAAQ+G,MAAKW,GAAUA,EAAOC,aAAeF,KAE5GxL,EAAMa,oBAAoBsB,QAAQ4B,QAAQgH,KAAK,CAC3CW,WAAYF,EACZG,cAAc,KAO9B,IACqC,QAAjCzC,EAAAhI,EAAQhB,eAAe8H,IAAIzE,cAAM,IAAA2F,OAAA,EAAjCA,EAAmC8B,+BAAgCzD,EAAqCqE,SACxG9J,EAA8BgH,6CAChC,KAAA+C,EAAAC,EACE9L,EAAMa,oBAAoBsB,QAA2C,QAApC0J,EAAG7L,EAAMa,oBAAoBsB,eAAO,IAAA0J,EAAAA,EAAI,GACzE7L,EAAMa,oBAAoBsB,QAAQ4B,QAAmD,QAA5C+H,EAAG9L,EAAMa,oBAAoBsB,QAAQ4B,eAAO,IAAA+H,EAAAA,EAAI,GACzF,MAAMC,EAAiB,QAAQjK,EAA8BgH,+CAChC9I,EAAMa,oBAAoBsB,QAAQ4B,QAAQ+G,MAAKW,GAAUA,EAAOC,aAAeK,KAExG/L,EAAMa,oBAAoBsB,QAAQ4B,QAAQgH,KAAK,CAC3CW,WAAYK,EACZJ,cAAc,IAK1B,GAAuB,aAAnB3L,EAAMsB,UAAuD,QAAhC6H,EAAIjI,EAAQhB,eAAed,aAAK,IAAA+J,GAA5BA,EAA8BlG,WAAY,CAC3E,IAAIjD,EAAMwB,SAUN,MAAM,IAAIqD,MAAM,wFAThB4E,EAAoBuC,YAAc,CAAChM,EAAMwB,UApGnB,GAqGtB8H,GAAU2C,EAAAA,EAAAA,uBACN,CACI7K,cAAeF,EACfL,oBAAqBb,EAAMa,qBAE/B4I,QAKL,GAAIzJ,EAAMyB,YAA0C,QAAhC2H,EAAIlI,EAAQhB,eAAed,aAAK,IAAAgK,GAA5BA,EAA8BhF,IAAMlD,EAAQhB,eAAed,MAAMiF,eAC5FoF,EAAoBM,gBAAkB/J,EAAMyB,WAC5C6H,GAAU2C,EAAAA,EAAAA,uBACN,CACI7K,cAAeF,EACfL,oBAAqBb,EAAMa,qBAE/B4I,QAED,GAAIzJ,EAAMyB,YAAcP,EAAQhB,eAAed,OAAS8B,EAAQhB,eAAed,MAAMiF,eAAgB,CACxG,MAAM6H,EAAelI,KAAKC,MAAMjE,EAAMyB,YAItC,GAHIP,EAAQhB,eAAed,MAAMkF,YAC7BkF,EAAkB2C,OAAOD,EAAa1H,YAEtC2H,OAAOC,MAAM5C,GACb,MAAM,IAAI3E,MAAM,mDACb,IAEFqH,EAAazH,eAEd,MAAM,IAAII,MAAM,0CAEhB4E,EAAoBM,gBAAkBmC,EAAaxH,WACnD+E,EAAoB4C,qBAAuBH,EAAazH,eACpD+E,IACAC,EAAoB6C,IAAM,CAAC9C,GAxIT,IA0ItBF,GAAU2C,EAAAA,EAAAA,uBACN,CACI7K,cAAeF,EACfL,oBAAqBb,EAAMa,qBAE/B4I,OAGL,KAAIzJ,EAAMyB,YAA0C,QAAhC4H,EAAInI,EAAQhB,eAAed,aAAK,IAAAiK,IAA5BA,EAA8B1E,YAoCzD,MAAM,IAAIE,MAAM,qGApCsD,KAAA0H,EACtE,MAAMC,QAA2BC,EAAAA,EAAAA,aAAY,IAAIC,EAAAA,GAAiBxL,EAAQhB,eAAelB,aAAckC,GACjGyD,EAA0C,QAA/B4H,EAAGrL,EAAQhB,eAAed,aAAK,IAAAmN,OAAA,EAA5BA,EAA8B5H,YAAYgI,MAAM,KAsB9D7L,SApB0B8L,EAAAA,EAAAA,2BAC5B,CACIxL,cAAeF,EACfL,oBAAqBb,EAAMa,qBAE/B8D,MAAAA,EAAAA,EAAe,GACf,CACIkI,cAAe,CACXrH,UAAWtE,EAAQhB,eAAelB,YAAYyG,UAC9CqH,sBAAuBN,MAAAA,OAAkB,EAAlBA,EAAoBO,eAE/CC,aAAc,CACV,CACItH,UAAW1F,EAAM6B,aAI7B,IAAIiE,OAG6BvD,KAAI0K,IAAC,IAAAC,EAAA,OAAe,QAAfA,EAAID,EAAEzI,iBAAS,IAAA0I,EAAAA,EAAI,KAC7DzD,EAAoB6C,IAAMxL,EAC1B2I,EAAoBqD,sBAAwBN,EAAmBO,cAE/DzD,GAAU2C,EAAAA,EAAAA,uBACN,CACI7K,cAAeF,EACfL,oBAAqBb,EAAMa,qBAE/B4I,IAMR,IAAIhC,QAA6B6B,EAWjC,GARA7B,EAAqB0F,SAAQC,IACzBA,EAAE3G,MAAQ,EACV2G,EAAEzG,UAAY,EACdyG,EAAEC,gBAAkB,EACpBD,EAAEE,gBAAkB,EACpBF,EAAEnG,iBAAkB,KAGpB/F,EAAQhB,eAAejB,KAAKkB,gBAC5B,IACI,MAAMH,EAAQ,IAAI8E,EAAuC2C,GAEzDA,QADqB8F,EAA+CvN,EAAOkB,GAE7E,MAAOgG,IAKb,OAAOM,EAAeC,EAAsBvG,EAASoI,EAAQkE,SAASnF,MAAOvG,IAM7E9B,MAlUiB8C,IACjB,MAAM9C,GAAQ6C,EAAAA,EAAAA,GAA0BC,EAAMwE,GAc9C,OAXItH,EAAMa,oBAAoBoB,QAAUa,EAAKS,SACzCvD,EAAMa,oBAAoBoB,OAAOwL,IAAM3K,EAAKS,OAAOmK,cAAgB,GAInE1N,EAAMa,oBAAoBoB,QAAUa,EAAK5C,eAAed,OAAS0D,EAAK5C,eAAed,MAAMuO,OAC3F3N,EAAMa,oBAAoBoB,OAAO2L,MAAQ9K,EAAK5C,eAAed,MAAMuO,MAGvE3N,EAAMa,oBAAoBwH,OAAQ,EAE3BrI,KAsTX,0OCpYO,MAAM6N,EAAc,CACvBC,0BAA2B,eAC3BC,sBAAuB,oBACvBC,uBAAwB,qBACxBC,oBAAqB,WACrBC,qBAAsB,YACtBC,qBAAsB,YACtBC,sBAAuB,aACvBC,wBAAyB,cACzBC,qBAAsB,WACtBC,0BAA2B,iBAMzB,MAAOC,EAGTzP,YAAYC,GAIL,KAAAU,YAAc,KAAM+O,EAAAA,EAAAA,eAAc,oBAAqBtP,KAAKH,aAE5D,KAAAW,mBAAqB,IAAM,oBAE3B,KAAAC,cAAgB,IAAiB,UAPpCT,KAAKH,YAAcA,GAepBe,eAAe2O,EAA6B1O,EAA0BC,GACzE,OAAO0O,EAAAA,EAAAA,6BAA4B,CAAEvN,cAAenB,IAAO2O,MAAMC,IACxBA,EAAoBC,oBAAsB,IAC1EvM,KAA4CwM,IACzC,IAAI1M,EAAM,GACV,GAAI0M,EAAWrD,WACX,OAAQqD,EAAWrD,WAAWsD,eAC1B,IAAK,OACD3M,EAAM0M,EAAWpD,aAAekC,EAAYK,qBAAuBL,EAAYI,oBAC/E,MACJ,IAAK,QACD5L,EAAM0M,EAAWpD,aAAekC,EAAYO,sBAAwBP,EAAYM,qBAChF,MACJ,IAAK,gBACD9L,EAAM0M,EAAWpD,aAAekC,EAAYG,uBAAyBH,EAAYE,sBACjF,MACJ,IAAK,UACD1L,EAAMwL,EAAYC,0BAClB,MACJ,IAAK,mBACDzL,EAAMwL,EAAYQ,wBAClB,MACJ,IAAK,WACDhM,EAAMwL,EAAYS,qBAClB,MACJ,IAAK,gBACDjM,EAAMwL,EAAYU,+BAK1BtO,EAAIkH,UAAU8H,QAAQ,2DAE1B,GAAI5M,EACA,MAAO,CACHA,IAAAA,EACA0M,WAAAA,MAKXrE,OAAOwE,WAIb,MAAMC,EAAe1O,GACjB,IAAI+N,EAAkB/N,EAAUP,eAAelB,aAG7CoQ,GAAyC9O,EAAAA,EAAAA,IAA2B,CAC7EC,GAAI,qFACJC,OAA8CkO,EAC9C1O,MAAOmP,IAGX,kECzGOpP,eAAesP,EAClBC,EACAzO,EACAZ,GAEA,MAAMsP,QAAwBC,EAAAA,EAAAA,+BAA8B,CAAEpO,cAAenB,EAAKY,oBAAAA,GAAuByO,GAEzG,IAAKC,EAED,OADAtP,EAAIwP,MAAM,sDACyB,GAGvC,MAAMC,GAAUH,GAAmB,IAAIhN,KAAKoN,GAA6DA,IAEzG,OAAsB,IAAlBD,EAAOzF,QACPhK,EAAIwP,MAAM,8EACyB,IAGhCC,4KClBNE,8DAAL,SAAKA,GACDA,EAAAA,EAAA,mDACAA,EAAAA,EAAA,iDAFJ,CAAKA,IAAAA,EAAa,KAQZ,MAAOC,UAAkCxO,EAAAA,EAA/CtC,kCACW,KAAAY,mBAAqB,IAAM,iBAE3B,KAAAC,cAAgB,IACZ,QA6BRG,eAAe+P,EAAmC9P,EAAkCkB,GAAuB,IAAA8H,EAC9G,IAAIQ,EAIAD,EAFAhI,EAAkC,IAAIvB,EAAMuB,WAAa,GAIzDgI,EADAvJ,EAAM8B,8BACiC0I,EAAAA,YAAYpF,QAAQpF,EAAM8B,gCAE1B2I,EAAAA,EAAAA,gCAA+B,CAAErJ,cAAeF,IAE3F,MAAMY,QAAsCyH,EAKtCxH,EAAmBR,EAAS0E,MAC9BzD,GAAWA,EAAQC,mBAAoBX,MAAAA,OAA6B,EAA7BA,EAA+B0G,qCAE1E,GAAIzG,EAAkB,CAClBR,EAAWA,EAASmJ,QAAOlI,GAAWA,EAAQC,mBAAoBX,MAAAA,OAA6B,EAA7BA,EAA+B0G,qCAEjG,MAAMmC,EACF5I,EAAiBW,wBAAyBZ,MAAAA,OAA6B,EAA7BA,EAA+B6G,wCACzE5G,EAAiBY,yBAA0Bb,MAAAA,OAA6B,EAA7BA,EAA+B6G,uCACxEiC,GAAwBC,EAAAA,EAAAA,IAAiC/I,EAA+B6I,IAEzDpJ,EAASuJ,MAAKtI,GAAWA,EAAQC,mBAAoBmI,MAAAA,OAAqB,EAArBA,EAAuBnI,oBAC5EmI,GACjCrJ,EAASwJ,KAAKH,GAItB,IAAqC,QAAjC5B,EAAA9H,EAAQhB,eAAe8H,IAAIzE,cAAM,IAAAyF,OAAA,EAAjCA,EAAmCgC,+BAAgCzD,EAAAA,GAAqC0D,QAAS,CACjH,MAAMC,GAAY,EACZC,GAA+BN,EAAAA,EAAAA,IAAiC/I,EAA+BoJ,IAEzD3J,EAASuJ,MACjDtI,GAAWA,EAAQC,mBAAoB0I,MAAAA,OAA4B,EAA5BA,EAA8B1I,oBAE7B0I,GACxC5J,EAASwJ,KAAKI,GAItB,MAAM4E,GAAgB1F,EAAAA,EAAAA,IAAoBnJ,GACpC8O,QAA0BC,EAAAA,EAAAA,IAAwB/O,GAIxDK,GAAW6I,EAAAA,EAAAA,IAA4BlJ,EAASK,GAC3C2O,OAAOH,QAAsBI,EAAAA,EAAAA,IAAmBjP,GAAW,IAC3DgP,OAAOF,GACZ,MAAMI,GAAkBhG,EAAAA,EAAAA,IAA4BlJ,GAC/CgP,OAAOH,QAAsBI,EAAAA,EAAAA,IAAmBjP,GAAW,IAC3DgP,OAAOF,GAEZ,GAAuB,aAAnBhQ,EAAMsB,SAAyB,CAC/B,GAAItB,EAAMwB,SAEN,OADAxB,EAAMuB,SAAWvB,EAAM2B,qBAAuBJ,EAAW6O,GAClDf,EAAAA,EAAAA,GACH,CACIrD,YAAa,CAAChM,EAAMwB,UAAYoO,EAAcS,wBAC9C3G,QAAS,CACLlE,UAAWxF,EAAMhB,YAAYyG,UAC7BC,UAAW1F,EAAM6B,WAErB8H,WAAY3J,EAAM2B,qBAAuBJ,EAAW6O,EACpDrG,gBAAiB/J,EAAMyB,YAE3BzB,EAAMa,oBACNK,GAGR,MAAM,IAAI2D,MAAM,oFAEhB,GAAI7E,EAAMyB,YAAcP,EAAQhB,eAAed,OAAS8B,EAAQhB,eAAed,MAAMgF,IAAMlD,EAAQhB,eAAed,MAAMiF,eAEpH,OADArE,EAAMuB,SAAWvB,EAAM2B,qBAAuBJ,EAAW6O,GAClDf,EAAAA,EAAAA,GACH,CACItF,gBAAiB/J,EAAMyB,WACvBiI,QAAS,CACLlE,UAAWxF,EAAMhB,YAAYyG,UAC7BC,UAAW1F,EAAM6B,WAErB8H,WAAY3J,EAAM2B,qBAAuBJ,EAAW6O,GAExDpQ,EAAMa,oBACNK,GAGR,GAAIlB,EAAMyB,YAAcP,EAAQhB,eAAed,OAAS8B,EAAQhB,eAAed,MAAMiF,eAAgB,CACjG,MAAM6H,EAAelI,KAAKC,MAAMjE,EAAMyB,YAItC,GAHIP,EAAQhB,eAAed,MAAMkF,YAC7BkF,EAAkB2C,OAAOD,EAAa1H,YAEtC2H,OAAOC,MAAM5C,GACb,MAAM,IAAI3E,MAAM,mDACb,GAAKqH,EAAazH,eAElB,CACH,MAAMgF,EAA6C,GAYnD,OAXAzJ,EAAMuB,SAAWvB,EAAM2B,qBAAuBJ,EAAW6O,EACzD3G,EAAoBC,QAAU,CAC1BlE,UAAWxF,EAAMhB,YAAYyG,UAC7BC,UAAW1F,EAAM6B,WAErB4H,EAAoBM,gBAAkBmC,EAAaxH,WACnD+E,EAAoBE,WAAa3J,EAAM2B,qBAAuBJ,EAAW6O,EACzE3G,EAAoB4C,qBAAuBH,EAAazH,eACpD+E,IACAC,EAAoB6C,IAAM,CAAC9C,GAAmBoG,EAAcU,yBAEzDjB,EAAAA,EAAAA,GAA2B5F,EAAqBzJ,EAAMa,oBAAqBK,GAdlF,MAAM,IAAI2D,MAAM,0CAiBpB,MAAM,IAAIA,MAAM,qGAKrB,MAAMkE,GAAmBzI,EAAAA,EAAAA,IAA2B,CACvDC,GAAI,iFACJC,OAA6CsP,EAC7C9P,MArIiB8C,IACVD,EAAAA,EAAAA,GAA0BC,EAAM+M,KAuI3C,yWClKO,MAAMhF,EAAmCA,CAC5C/I,EACAoJ,KAEA,GAAIpJ,GAAiCA,EAA8BgH,6CAC/D,MAAO,CACHrG,gBAAiBX,EAA8BgH,6CAC/CyH,cAAeC,EAAAA,kBAAkBC,UACjC/N,qBAAsBwI,EAAY,OAAS,QAC3CvI,sBAAuBuI,EAAY,OAAS,QAC5CwF,SAAU,GACVC,UAAW,EACXC,MAAO,EACPzG,oBAAqB,GACrB0G,mBAAoBC,EAAAA,qBAAqBC,YAUE1P,EAAAA,GA8FvBf,EAAAA,EAAAA,IAA2B,CACvDC,GAAI,4EACJC,OAjCJT,eAAsBC,EAA0CkB,GAAuB,IAAA8P,EACnF,MAAMzP,QAAiB8N,EAAAA,EAAAA,GACnB,CACI3F,QAAS,CACLlE,UAAWxF,EAAMhB,YAAYyG,UAC7BC,UAAW1F,EAAM6B,YAGzB7B,EAAMa,oBACNK,GAKJ,OACgF,KAAxC,QAAnC8P,EAAAhR,EAAM8B,qCAA6B,IAAAkP,OAAA,EAAnCA,EAAqCxI,oCAClCjH,EAAS0E,MAAKzD,IAAO,IAAAyO,EAAA,OAAIzO,EAAQ8C,YAAgD,QAAxC2L,EAAKjR,EAAM8B,qCAA6B,IAAAmP,OAAA,EAAnCA,EAAqCzI,uCAE1C,IAA5CxI,EAAMkR,mCACH3P,EAAS0E,MAAKzD,GAAWA,EAAQ8C,WAAatF,EAAMkR,qCACxD,kvBC7HR,MAAMC,EAA0B,WAEhC,SAASC,EAAiBlQ,GAAuB,IAAA8H,EAC7C,MAAMqI,EAA2E,QAApErI,EAAG9H,EAAQhB,eAAeoR,IAAIC,WAAWC,aAAaC,IAAI,kBAAU,IAAAzI,OAAA,EAAjEA,EAAmE0I,cAEnF,MAAmB,MAAZL,GAA+B,SAAZA,EAGxB,SAAUhH,EAAoBnJ,GAAuB,IAAA+H,EAAAC,EACvD,MAAMyI,EAA0G,WAApB,QAAjE1I,EAAA/H,EAAQhB,eAAeoR,IAAIC,WAAWC,aAAaC,IAAI,kBAAU,IAAAxI,OAAA,EAAjEA,EAAmEyI,eACxFE,EAAyBzF,OAAwC,QAAlCjD,EAAChI,EAAQhB,eAAe8H,IAAIzE,cAAM,IAAA2F,OAAA,EAAjCA,EAAmC0I,wBAEzE,OAAOD,IAAuBvF,MAAMwF,IAA2BA,EAAyB,EAGrF7R,eAAeoQ,EAAmBjP,GAAuB,IAAAiI,EAC5D,IAAI0I,EAA0B1F,OAAwC,QAAlChD,EAACjI,EAAQhB,eAAe8H,IAAIzE,cAAM,IAAA4F,OAAA,EAAjCA,EAAmCyI,yBAEpExF,MAAMyF,IAAwD,IAA5BA,KAClCA,EAA0BV,GAG9B,MAAMzB,EAAgC,GAChCoC,EAAsC,CACxCvB,cAAe,EACf7N,qBAAsB,IACtBD,gBAAiBoP,EACjBhB,mBAAoB,EACpBlO,sBAAuB,IACvB+N,SAAU,IAGdhB,EAAO3E,KAAK+G,GAEZ,IACI,IAAIC,EAAsB,EAE1B,GAAI7Q,EAAQhB,eAAejB,KAAKkB,gBAAiB,KAAA6R,EAG7C,MAAMC,QAAiB5R,EAAAA,EAAAA,SAAwB,IAAIvB,EAAAA,6BAA6BoC,EAAQhB,eAAelB,YAAakC,EAAQhB,eAAejB,KAAK0B,uBAAyBO,GACnKgR,EAAiB/F,OAA0B,QAApB6F,EAACC,EAASE,kBAAU,IAAAH,GAAmD,QAAnDA,EAAnBA,EAAqB/L,MAAKmH,GAAKA,EAAE9H,WAAauM,WAAwB,IAAAG,GAAgB,QAAhBA,EAAtEA,EAAwEI,sBAAc,IAAAJ,OAAA,EAAtFA,EAAwFK,aAElHjG,MAAM8F,GAENI,QAAQC,KAAK,qDAEbR,EAAsBG,OAI1BH,EAAsB,EAQ1BS,MAAMT,GAAqBU,KAAK,GAAGtF,SAAQ,CAACuF,EAAG1I,KAC3C0F,EAAO3E,KAAI/I,EAAAA,EAAC,GACL8P,GAAc,IACjBpP,sBAAuBsH,EAAQ,GAAG2I,WAClChQ,uBAAwBqH,EAAQ,GAAG2I,iBAG7C,MAAOzL,GACLoL,QAAQC,KAAK,2HAA4HrL,GAG7I,OAAOwI,EAGJ3P,eAAe6S,EAAkB1R,EAAyBuI,GAA0C,IAAAL,EACvG,IAAIyI,EAA0B1F,OAAwC,QAAlC/C,EAAClI,EAAQhB,eAAe8H,IAAIzE,cAAM,IAAA6F,OAAA,EAAjCA,EAAmCwI,yBAEpExF,MAAMyF,IAAwD,IAA5BA,KAClCA,EAA0BV,GAG1B1H,EAAoBE,WAAYmB,MAAKsC,GAAKA,EAAE3K,kBAAoBoP,MAEhEpI,EAAoBE,WAAaF,EAAoBE,WAAYe,QAAO0C,GAAKA,EAAE3K,kBAAoBoP,KAGvG,MAAMtQ,QAAiB4O,EAAmBjP,GAI1C,OAFAuI,EAAoBE,WAAaF,EAAoBE,WAAYuG,OAAO3O,GAEjE4D,QAAQC,UAGb,SAAUgF,EAA4BlJ,EAAyBK,GAKjE,IAF+B6P,EAAiBlQ,GAEnB,CACzB,MAAMwO,EAASnO,EAAW,IAAIA,GAAY,GAGpCsR,EAAenD,EAAOzJ,MAAKmH,GAA2B,IAAtBA,EAAE3K,kBAOjC,IAAA4G,EALP,GAAIwJ,IAEKA,EAAanQ,sBAAwByJ,OAAO0G,EAAanQ,sBAAwB,OAClFmQ,EAAanQ,qBAAuB,aAIxCgN,EAAO3E,KAAK,CACR,cAAe,qEACf6F,MAAO,EACPL,cAAe,EACf7N,qBAAsB,OACtByH,oBAAqB,GACrB1H,gBAAiB,EACjBoO,mBAAoB,EACpBlO,sBAAuB,aACvBgO,UAAW,EACXD,SAAwC,QAAhCrH,EAAEnI,EAAQhB,eAAe4S,eAAO,IAAAzJ,OAAA,EAA9BA,EAAgC0J,WAIlD,OAAOrD,EAGX,OAAOnO,GAAY,GAGhBxB,eAAeiT,EAAqB9R,EAAyB+R,EAAqDC,EAA2BC,GAChJ,MAAMzD,EAAgC,GAChClN,EAA+B,CACjC+N,cAAe,EACf7N,qBAAsB,IACtBD,gBAAiByQ,EACjBrC,mBAAoB,EACpBlO,sBAAuB,IACvB+N,SAAU,IAGdhB,EAAO3E,KAAKvI,GAEZ,IACI,IAAI4Q,EAAiB,EAErB,GAAIlS,EAAQhB,eAAejB,KAAKkB,gBAAiB,KAAAkT,EAC7C,MAAMC,EAAYnH,OAAO8G,MAAAA,GAA+D,QAA7CI,EAAlBJ,EAAoBhN,MAAKmH,GAAKA,EAAE9H,WAAa4N,WAAkB,IAAAG,GAAgB,QAAhBA,EAA/DA,EAAiEjB,sBAAc,IAAAiB,OAAA,EAA/EA,EAAiFhB,aAEtGjG,MAAMkH,GAEFH,EACAb,QAAQC,KAAK,GAAGY,iDAEhBb,QAAQC,KAAK,4BAA4BW,yCAG7CE,EAAiBE,OAIrBF,EAAiB,EAGE,IAAnBA,GACA1D,EAAO3E,KAAI/I,EAAAA,EAAC,GACLQ,GAAO,IACVE,qBAAsB0Q,EAAeT,WACrChQ,sBAAuByQ,EAAeT,cAGhD,MAAOzL,GACDiM,EACAb,QAAQC,KAAK,iBAAiBY,iFAA6FjM,GAE3HoL,QAAQC,KAAK,gDAAgDW,+DAAgFhM,GAIrJ,OAAOwI,EAGJ3P,eAAewT,EAAoBrS,EAAyB+R,GAAmD,IAAA1G,EAClH,MAAMiH,EAAwD,QAApCjH,EAAGrL,EAAQhB,eAAe8H,IAAIzE,cAAM,IAAAgJ,OAAA,EAAjCA,EAAmCkH,2BAEhE,GAAKD,GAAyBtS,EAAQhB,eAAejB,KAAKkB,gBAI1D,IAAI,IAAAuT,EACA,MAAMJ,EAAYL,MAAAA,GAA0E,QAAxDS,EAAlBT,EAAoBhN,MAAKmH,GAAKA,EAAE9H,WAAa6G,OAAOqH,YAAsB,IAAAE,GAAgB,QAAhBA,EAA1EA,EAA4EtB,sBAAc,IAAAsB,OAAA,EAA1FA,EAA4FC,aAE9G,IAAKL,GAAalH,MAAMkH,IAA4B,IAAdA,EAClC,OAGJ,MAAO,CACH/C,cAAeC,EAAAA,kBAAkBoD,QACjClR,qBAAsB4Q,EAAUX,WAChClQ,gBAAiB0J,OAAOqH,GACxB3C,mBAAoBC,EAAAA,qBAAqBC,UACzCpO,sBAAuB2Q,EAAUX,WACjCjC,SAAU,IAEhB,MAAOxJ,GAEL,YADAoL,QAAQpL,MAAM,oCAAqCA,IAKpDnH,eAAe8T,EAAmB3S,EAAyB+R,GAAmD,IAAAa,EAAAC,EACjH,IAAK7S,EAAQhB,eAAejB,KAAKkB,gBAC7B,OAGJ,MAAM6T,EAAuD,QAApCF,EAAG5S,EAAQhB,eAAe8H,IAAIzE,cAAM,IAAAuQ,OAAA,EAAjCA,EAAmCG,0BACzDC,EAA8D,QAApCH,EAAG7S,EAAQhB,eAAe8H,IAAIzE,cAAM,IAAAwQ,OAAA,EAAjCA,EAAmCI,iCAGtE,GAAKH,GAAwBE,IAKzB9H,MAAM4H,KAAwB5H,MAAM8H,GAIxC,IAAI,IAAAE,EACA,MAAMd,EAAYL,MAAAA,GAAyE,QAAvDmB,EAAlBnB,EAAoBhN,MAAKmH,GAAKA,EAAE9H,WAAa6G,OAAO6H,YAAqB,IAAAI,GAAgB,QAAhBA,EAAzEA,EAA2EhC,sBAAc,IAAAgC,OAAA,EAAzFA,EAA2FT,aAG7G,IAAKL,GAAalH,MAAMkH,IAAcA,GAAa,EAC/C,OAIJ,MAAO,CACH/C,cAAeC,EAAAA,kBAAkBoD,QACjClR,qBAAsB,IACtBD,gBAAiB0J,OAAO+H,GACxBrD,mBAAoBC,EAAAA,qBAAqBC,UACzCpO,sBAAuB,IACvB+N,SAAU,IAEhB,MAAOxJ,GAEL,YADAoL,QAAQpL,MAAM,sCAAuCA,IAKtDnH,eAAesU,EAAoBnT,EAAyB+R,EAAqDxJ,EAA4CyJ,GAC5JzJ,EAAoBE,WAAYmB,MAAKsC,GAAKA,EAAE3K,kBAAoByQ,MAEhEzJ,EAAoBE,WAAaF,EAAoBE,WAAYe,QAAO0C,GAAKA,EAAE3K,kBAAoByQ,KAGvG,MAAM3R,QAAiByR,EAAqB9R,EAAS+R,EAAoBC,GAEzEzJ,EAAoBE,WAAaF,EAAoBE,WAAYuG,OAAO3O,GAarExB,eAAewK,EAAwBrJ,EAAyBuI,GAA0C,IAAA6K,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAG7G,GAFgBvD,EAAiBlQ,GAG7B,OAGJ,IAAI+R,EAAsD,GAE1D,GAAI/R,EAAQhB,eAAejB,KAAKkB,gBAAiB,CAC7C,MAAM,YAAEnB,EAAaC,MAAM,sBAAE0B,IAA4BO,EAAQhB,eAEjE+S,SADuB5S,EAAAA,EAAAA,SAAwB,IAAIvB,EAAAA,6BAA6BE,EAAa2B,GAAyBO,IACxFiR,WAGlC,MAAMyC,EAA+B,CACA,QADAN,EACjCpT,EAAQhB,eAAe8H,IAAIzE,cAAM,IAAA+Q,OAAA,EAAjCA,EAAmCO,uBACF,QADwBN,EACzDrT,EAAQhB,eAAe8H,IAAIzE,cAAM,IAAAgR,OAAA,EAAjCA,EAAmCO,wBACF,QADyBN,EAC1DtT,EAAQhB,eAAe8H,IAAIzE,cAAM,IAAAiR,OAAA,EAAjCA,EAAmCO,oBACF,QADqBN,EACtDvT,EAAQhB,eAAe8H,IAAIzE,cAAM,IAAAkR,OAAA,EAAjCA,EAAmCO,6BACF,QAD8BN,EAC/DxT,EAAQhB,eAAe8H,IAAIzE,cAAM,IAAAmR,OAAA,EAAjCA,EAAmCO,wBAGvC,IAAK,MAAM/B,KAAqB0B,EAAoB,CAChD,MAAMrU,EAAK4L,OAAO+G,IAGb9G,MAAM7L,IAAOA,EAAK,SACb8T,EAAoBnT,EAAS+R,EAAoBxJ,EAAqBlJ,GAIpF,MAAM2U,EAAiB/I,OAAwC,QAAlCwI,EAACzT,EAAQhB,eAAe8H,IAAIzE,cAAM,IAAAoR,OAAA,EAAjCA,EAAmCQ,yBAE5D/I,MAAM8I,IAAmBA,EAAiB,SA5C5CnV,eAA+CmB,EAAyB+R,EAAqDxJ,EAA4CyJ,GAC5K,GAAIzJ,EAAoBE,WAAYmB,MAAKsC,GAAKA,EAAE3K,kBAAoByQ,IAChE,OAGJ,MAAM3R,QAAiByR,EAAqB9R,EAAS+R,EAAoBC,GAEzEzJ,EAAoBE,WAAaF,EAAoBE,WAAYuG,OAAO3O,GAsC9D6T,CAAgClU,EAAS+R,EAAoBxJ,EAAqByL,GAG5F,MAAMG,QAAyB9B,EAAoBrS,EAAS+R,GAExDoC,GACA5L,EAAoBE,WAAYoB,KAAKsK,GAGzC,MAAMC,QAAwBzB,EAAmB3S,EAAS+R,GAEtDqC,GACA7L,EAAoBE,WAAYoB,KAAKuK,GAItCvV,eAAekQ,EAAwB/O,GAAuB,IAAAqU,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAGjE,GAFgBxE,EAAiBlQ,GAG7B,MAAO,GAGX,IAAI+R,EAAsD,GAE1D,GAAI/R,EAAQhB,eAAejB,KAAKkB,gBAAiB,CAC7C,MAAM,YAAEnB,EAAaC,MAAM,sBAAE0B,IAA4BO,EAAQhB,eAEjE+S,SADuB5S,EAAAA,EAAAA,SAAwB,IAAIvB,EAAAA,6BAA6BE,EAAa2B,GAAyBO,IACxFiR,WAGlC,MAAMyC,EAA+B,CACA,QADAW,EACjCrU,EAAQhB,eAAe8H,IAAIzE,cAAM,IAAAgS,OAAA,EAAjCA,EAAmCJ,uBACF,QADwBK,EACzDtU,EAAQhB,eAAe8H,IAAIzE,cAAM,IAAAiS,OAAA,EAAjCA,EAAmCX,uBACF,QADwBY,EACzDvU,EAAQhB,eAAe8H,IAAIzE,cAAM,IAAAkS,OAAA,EAAjCA,EAAmCX,wBACF,QADyBY,EAC1DxU,EAAQhB,eAAe8H,IAAIzE,cAAM,IAAAmS,OAAA,EAAjCA,EAAmCX,oBACF,QADqBY,EACtDzU,EAAQhB,eAAe8H,IAAIzE,cAAM,IAAAoS,OAAA,EAAjCA,EAAmCX,6BACF,QAD8BY,EAC/D1U,EAAQhB,eAAe8H,IAAIzE,cAAM,IAAAqS,OAAA,EAAjCA,EAAmCX,wBAGjCvF,EAAgC,GAEtC,IAAK,MAAMwD,KAAqB0B,EAAoB,CAChD,MAAMrU,EAAK4L,OAAO+G,GAGlB,IAAK9G,MAAM7L,IAAOA,EAAK,EAAG,CACtB,MAAMgB,QAAiByR,EAAqB9R,EAAS+R,EAAoB1S,GACzEmP,EAAO3E,QAAQxJ,IAIvB,MAAM8T,QAAyB9B,EAAoBrS,EAAS+R,GAExDoC,GACA3F,EAAO3E,KAAKsK,GAGhB,MAAMC,QAAwBzB,EAAmB3S,EAAS+R,GAM1D,OAJIqC,GACA5F,EAAO3E,KAAKuK,GAGT5F,gICzWX,MAAMmG,EAAwB,CAC1B,gBACA,uBACA,kBACA,qBACA,wBACA,WAEA,aAQSvS,EAA0BpD,IACnC,MAAM4V,EAAyBC,EAAuC,WAAY7V,GAClF,OAAK4V,GAA4D,IAAlCA,EAAuB7L,OAIxB6L,EACzBvT,KAAIyT,IACD,IACI,MAAMC,EAAqC,GAI3C,OAHAJ,EAAsB1I,SAAQ,CAAC+I,EAAYlM,KACvCiM,EAAcC,GAAcF,EAAkBhM,MAE3CiM,EACT,MAAAE,GACE,WAGPzL,OAAOwE,SAfD,IA2CFkH,EAAmBA,CAACC,EAAc9U,EAAkC+U,EAA+BC,KAE5G,QAAiB/S,IAAbjC,EAAwB,CACxB,GAAwB,IAApBA,EAAS0I,OACToM,EAAQ7E,aAAagF,OAAO,gBACzB,CACH,MAAMC,EAAiBlV,EAASmV,MAAK,CAACC,EAAOC,IACzCD,EAAMlU,iBAAmBmU,EAAOnU,iBAAmBkU,EAAMlU,gBAAkBmU,EAAOnU,gBAAkB,GAAK,IAE7G4T,EAAQ7E,aAAaqF,IAAI,WAAY7S,KAAKO,UA9BrBhD,CAAAA,IAC7B,MAAMuV,EAA4C,GAUlD,OARAvV,EAAS4L,SAAQ3K,IACb,MAAMwT,EAAyC,GAC/CH,EAAsB1I,SAAQ+I,IAC1BF,EAAkBjL,KAAKvI,EAAQ0T,OAEnCY,EAAmB/L,KAAKiL,MAGrBc,GAmBqDC,CAAiBN,KAKzE,OADAJ,EAAQ7E,aAAagF,OAAO,QACrBH,EAAQW,KAGnB,YAAuBxT,IAAnB8S,GAC8B,IAA1BA,EAAerM,OACfoM,EAAQ7E,aAAagF,OAAO,WAE5BH,EAAQ7E,aAAaqF,IAAI,UAAW7S,KAAKO,UAAU+R,IAIvDD,EAAQ7E,aAAagF,OAAO,QACrBH,EAAQW,OAGfT,GACAF,EAAQ7E,aAAaqF,IAAI,OAAQN,EAAU5D,YAGxC0D,EAAQW,OAQNjB,EAAkBA,CAAI1T,EAAanC,IACxCA,EAAed,OAASc,EAAed,MAAMiD,GAInC2B,KAAKC,MAAM/D,EAAed,MAAMiD,IAEvC,KAOE4U,EAAiB/W,GACtBgX,EAAAA,GAASC,UACF,IAAIC,IAAIC,OAAOC,SAASN,MAI/B9W,EAAeoR,IAAIC,WAAWyF,KACvB,IAAII,IAAIlX,EAAeoR,IAAIC,WAAWyF,MAE1C,IAAII,IAAsBlX,EAAeoR,IAAIC,8LC9GxD,IAAqBgG,EAArB,cAA2CC,EAAAA,cA4BvCzY,YAAY0Y,GACRC,MAAMD,GA5BO,KAAAE,iBAA2B,gBAmK3B,KAAAC,SAAYC,IACzBA,EAAEC,iBACFD,EAAEE,kBAEF,MAAMC,EAASH,EAAEI,cACXC,EAAWF,EAAOG,aAAa,SAAUC,SAAS,6BAClDC,EAAkBH,OAAW1U,EAAYrE,KAAKmZ,0BAA0BN,GAE1E7Y,KAAKsY,MAAMc,iBACXpZ,KAAKsY,MAAMc,gBAAgB,CACvBL,SAAAA,EACAM,YAAaR,EACbS,cAAeJ,EACfK,gBAAiBV,EAAOW,eAnJhCxZ,KAAKyZ,SAAUC,EAAAA,EAAAA,kBAAiB,QAAS1Z,KAAKsY,MAAMqB,iBAAmB,IAzBjE,0BAAuB,IAAAC,EAC7B,IAAI,gBAAEC,GAAoB7Z,KAAKsY,MAC/B,MAAM,gCAAE7O,EAA+B,iBAAEqQ,GAAqB9Z,KAAKsY,MAWnE,OATsB,QAAlBsB,EAAA5Z,KAAKsY,MAAMvW,eAAO,IAAA6X,OAAA,EAAlBA,EAAoB/Q,IAAIzE,OAAOyH,+BAAgCzD,EAAAA,GAAqC0D,UACpG+N,EAAkBA,EAAgBtO,QAAOwO,IACrC,MAAMC,EAASF,MAAAA,OAAgB,EAAhBA,EAAkBhT,MAC5BmT,KACKA,EAAUC,OAAOpT,MAAM3D,IAA+BgX,EAAAA,EAAAA,IAA8BhX,EAAO4W,OAErG,OAAOC,GAAUA,EAAO7T,WAAasD,MAGtCoQ,EAAgBzW,KAAI,CAAC8V,EAAsCrO,KAC9D,MAAMuP,EAAapa,KAAKqa,uBAAuBnB,EAAiBrO,EAAM2I,YACtE,MAAO,CACHtQ,IAAKkX,EAAalX,IAClB8W,OAAOI,EAAaJ,OACpB7W,MAAO+V,MAUZoB,SACH,MAAM,aAAEC,EAAY,MAAEC,EAAK,WAAEC,EAAU,gBAAEC,EAAe,eAAEC,EAAc,SAACC,EAAQ,QAACC,GAAY7a,KAAKsY,MAC7FwC,EAAQ9a,KAAK+a,oBACnB/a,KAAKyZ,QAAQuB,cAAcC,MAAQV,EACnC,MAAMW,GAAqBC,EAAAA,EAAAA,wBAAuBnb,KAAKsY,MAAMqB,iBAAmB3Z,KAAKyZ,SACrF,OACIpB,EAAAA,cAAA,OAAK+C,UAAU,sBACVN,EAAMhQ,OAAS,GAAK0P,GAASnC,EAAAA,cAAA,QAAM+C,UAAU,6BAA6BZ,GAC3EnC,EAAAA,cAAA,MAAI+C,UAAWC,GAAAA,CAAWZ,EAAY,2BAA4B,kBAC7DK,EAAM1X,KAAKkY,IAAqB,IAAAC,EAC7Bvb,KAAKyZ,QAAQuB,cAAcC,MAAQK,EAAKpY,IACxC,MAAMiR,GAAYgH,EAAAA,EAAAA,wBAAuBnb,KAAKsY,MAAMqB,iBAAmB3Z,KAAKyZ,SAC5E,IAAIlW,EAAuB+X,EAAKnY,MAAMI,sBAClC+X,EAAKnY,QAASqY,EAAAA,EAAAA,IAAUF,EAAKnY,MAAMiO,gBAE5BpE,OAAOhN,KAAKsY,MAAMtC,0BAA4BsF,EAAKnY,MAAMG,iBAEzC,yBAAhBgY,EAAKtB,UAHZzW,EAAgD,MAAzBA,EAA+BqX,EAAWC,GAOrE,IAAIY,EAAYH,EAAKtB,OACjB0B,EAAYnY,GAAqE,KAA7C+X,EAAKnY,MAAMwY,gCAE5CL,EAAKnY,MAAMwY,oCACmCtX,IAA7CiX,EAAKnY,MAAMwY,+BACgB,IAA/BL,EAAKnY,MAAMG,gBAHTC,EAIA+X,EAAKpY,IAQX,OALa,QAATqY,EAAAE,SAAS,IAAAF,GAATA,EAAWK,WAAW,cAAgBF,IACtCD,EAAYA,EAAUI,QAAQ,YAAa,IAC3CH,GAAYI,EAAAA,EAAAA,IAAmBJ,IAI/BrD,EAAAA,cAAA,MAAI+C,UAAU,gCAAgClY,IAAKoY,EAAKpY,KACpDmV,EAAAA,cAAA,IAAA0D,OAAAC,OAAA,CACIZ,UAAU,2BACVvD,KAAM7X,KAAKsY,MAAM2D,WAAWX,EAAKnY,OAAO,GAAM,aAClC,GAAGI,KAAwBmX,IACvCwB,QAASlc,KAAKyY,SACd0D,KAAK,SACL/a,GAAIka,EAAKpY,KACLiR,IAEHmH,MAAAA,OAAI,EAAJA,EAAMtB,SAAU3B,EAAAA,cAAA,QAAM+D,MAAO,CAAEC,WAAY,SAAWZ,EAAS,KAC/DC,EACDrD,EAAAA,cAAA,QACI+C,UAAW,GAAGpb,KAAKwY,6CACnB2D,KAAK,SAAQ,aACDxB,UAOnCG,EAAMhQ,OAAS,GAAKyP,GACjBlC,EAAAA,cAAA,IAAA0D,OAAAC,OAAA,CACInE,KAAM7X,KAAKsY,MAAM2D,WAAW,IAAI,GAChCb,UAAU,iCACNF,EAAkB,CACtBgB,QAASlc,KAAKyY,WAEb8B,IAObF,uBAAuBiC,EAA0CzR,GACrE,MAAM,aAAE0R,EAAY,uBAAEC,EAAsB,iBAAE1C,EAAgB,UAAE9R,EAAS,cAAEyU,GAAkBzc,KAAKsY,MAC5FoE,EAAgBH,GAAgB,MAChCI,EAAcH,EACpB,IAaII,EAbAC,EAAc,GAClB,GAAI/C,GAAoBA,EAAiBhT,KAAM,CAC3C,MAAMkT,EAASF,EAAiBhT,MAC3BmT,KACKA,EAAUC,OAAOpT,MAAM3D,IAA+BgX,EAAAA,EAAAA,IAA8BhX,EAAOmZ,OAGhGtC,EAGD6C,EAAc7C,EAAO8C,SAAW,GAFhC9U,EAAU8H,QAAQ,oEAM1B,IAAIiN,EAAAA,EAAAA,IAAYT,EAAoBlL,eAChCwL,EAAmBD,EACdd,QAAQ,MAAO7b,KAAKgd,aAAaV,EAAoB/Y,qBAAsB+Y,EAAoB/K,WAC/FsK,QAAQ,MAAO7b,KAAKgd,aAAaV,EAAoB9Y,sBAAuB8Y,EAAoB/K,gBAClG,GAA4C,IAAxC+K,EAAoBhZ,gBAAuB,CAClD,MAAM2Z,EAAcR,MAAAA,OAAa,EAAbA,EAAevC,OAAOpT,MACtCzD,GAAWA,EAAQE,uBAAyB+Y,EAAoB/Y,uBAEpEqZ,GAAoBK,EAAcA,EAAYtB,8BAAgCW,EAAoB/Y,uBAAyB,QAE3HqZ,EAAmBN,EAAoBX,+BAAiCW,EAAoB/Y,sBAAwB,GAExH,MAAoB,WAAhBsZ,GAA4C,UAAhBA,GAA2C,SAAhBA,EAChD,CACH3Z,IAAKwZ,EAAcb,QAAQ,MAAOgB,GAAahB,QAAQ,MAAO,GAAGe,KACjE5C,OAAO6C,GAIR,CACJ3Z,IAAKwZ,EAAcb,QAAQ,MAAOgB,GAAahB,QAAQ,MAAO,GAAGe,KAAoBC,KAAehS,KACnGmP,OAAO6C,GAIPG,aAAaE,EAA4BC,GAC7C,IAAKD,IAAWC,EAEZ,OADAnd,KAAKsY,MAAMtQ,UAAUsI,MAAM,2CACpB4M,GAAU,GAErB,IAAI3M,EAAS2M,EAEb,IACI3M,EAASvQ,KAAKsY,MAAMvW,QAASqb,iBAAiBC,eAAerQ,OAAOkQ,GAASC,GAC/E,MAAOpV,GACL/H,KAAKsY,MAAMtQ,UAAU8H,QAAQ,8BAA8BS,MAAWxI,KAG1E,OAAOwI,EAqBH4I,0BAA0BE,GAC9B,MAAM9I,EAASvQ,KAAK+a,oBAAoBjU,MAAKwW,GAAYjE,EAAYjY,KAAOkc,EAASpa,MACrF,OAAQqN,GAAUA,EAAOpN,YAAUkB,KAnL7BkZ,EAAAA,EAAAA,IAAA,CAATC,EAAAA,IAAQ,wCALQpF,GAAamF,EAAAA,EAAAA,IAAA,CADjCE,EAAAA,IACoBrF,oUCrBd,MAAMsF,EAAwCC,IAAa,IAAZ,KAAEC,GAAMD,EAC1D,OACItF,EAAAA,cAAA,QAAM+C,UAAU,kDACZ/C,EAAAA,cAAA,MAAI+C,UAAU,cACT,IACAwC,EACA,2CCSV,MAAMC,EAA8DF,IAOtE,IAAAG,EAAA,IAPuE,QACxE5X,EAAO,QACPnE,EAAO,cACPgc,EAAa,UACbC,EAAS,iBACTrE,EAAgB,eAChBzU,GACHyY,EACG,GAAgB,OAAZzX,EACA,OAAO,KAGX,MAAM+X,EAAc/X,EAAQgY,KACtBC,EAAkBjY,GAAWA,EAAQC,SAAWD,EAAQC,SAAW,EACnEiY,GAAaC,EAAAA,EAAAA,uBAAsBnY,EAAQgY,MAAQ,GAAIC,EAAiBpc,GAAWA,EAAQuc,mBAAeja,GAC1Gka,GAAgBC,EAAAA,EAAAA,qBAClBtY,EAAQuY,OACR1c,EAAQuc,cAAcvd,eAAelB,YAClB,QAD6Bie,EAChD/b,EAAQC,QAAQ6G,WAAG,IAAAiV,GAAQ,QAARA,EAAnBA,EAAqB1Z,cAAM,IAAA0Z,OAAA,EAA3BA,EAA6BY,kBAE3BC,EACFzZ,GAAqC,iBAAnBA,EAAoC8Y,EAAUY,+BAAiCZ,EAAUa,yBAGzGpF,GAAUC,EAAAA,EAAAA,kBAAiB,QAASC,EAAmBsE,EAAcE,EAAgB3K,YAErFW,GAAYgH,EAAAA,EAAAA,wBAAuBxB,EAAmBF,GAC5D,OACIpB,EAAAA,cAAA,OAAK+C,UAAU,kCACX/C,EAAAA,cAAA,IAAA0D,OAAAC,OAAA,CACInE,KAAMuG,EACNlC,SAAS4C,EAAAA,EAAAA,kBAAiBnF,EAAmBF,EAASvT,EAAQgY,OAC1D/J,EAAS,cACDjO,EAAQgY,OAEpB7F,EAAAA,cAAA,OAAK+C,UAAU,0CAmB/B,SACI2C,EACAgB,EACAC,EACAC,EACAV,EACAxc,GAEA,IAAKid,IAAaD,IAAiBhB,EAC/B,OAAO,KAEX,MAAMmB,EAAkB,CACpBC,IAAKH,EACLC,QAASA,GAAoB,IAE3BG,EAAa,CACfL,aAAAA,EACAhB,cAAAA,EACAsB,YAAad,GAEjB,OAAOlG,EAAAA,cAACiH,EAAAA,GAAKvD,OAAAC,OAAA,GAAKkD,EAASE,EAAU,CAAEG,oBAAoB,QAAQxe,eAAgBgB,KAtClEyd,CACGzB,EACAhc,EAAQC,QAAQ+c,aAChB7Y,EAAQ0C,gBACR1C,EAAQgY,KACRK,EACAxc,EAAQuc,cAAcvd,kBAIlCsX,EAAAA,cAAA,OAAK+C,UAAU,2CACX/C,EAAAA,cAAA,KAAG+C,UAAU,4CAA4CuD,IA8B7Cc,EA7BQvZ,MAAAA,OAAO,EAAPA,EAASgY,KA8BlC7F,EAAAA,cAAA,MAAI+C,UAAU,kDAAkDqE,MAD3E,IAA4BA,GCzFrB,MAAMC,EAAwB/B,IAAA,IAAC,KAAEC,EAAI,UAAExC,EAAS,KAAEvD,EAAI,UAAE8H,GAAWhC,EAAA,OACtEtF,EAAAA,cAAA,KAAG+C,UAAWA,EAAWvD,KAAMA,EAAI,aAAc8H,GAC5C,IACA/B,EAAM,MCkBFgC,EAA4CtH,IACrD,MAAM,KAAEsF,EAAI,QAAE1B,EAAO,UAAEyD,EAAS,SAAEE,EAAQ,GAAEze,GAAOkX,EACnD,OACID,IAAAA,cAAA,UAAQjX,GAAIA,EAAIga,UAAU,aAAY,aAAauE,EAAWzD,QAASA,EAAS4D,IAAKD,GAChFjC,IAKAmC,EAAqBzH,IACvB,CACH0H,MAAOC,EAAU3H,GACjB4H,YAAaC,EAAgB7H,GAC7B8H,YAAaC,EAAgB/H,GAC7BgI,UAAWjI,IAAAA,cAACkI,EAAAA,UAAS,CAACnF,UAAU,4BAIlC6E,EAAa3H,GAEXD,IAAAA,cAACmI,EAAAA,MAAK,CACFC,WAAS,EACTC,gBAAgB,aAChBC,eAAgBrI,EAAMsI,UACtBC,OAAQvI,EAAMuI,OACdC,OAAQxI,EAAMyI,cACd3F,UAAU,0BACV4F,OAAQ,OAKdb,EAAmB7H,GACdD,IAAAA,cAAC4I,EAAAA,YAAW,CAACH,OAAQxI,EAAMyI,eAAgBzI,EAAM0F,UAAUkD,YAGhEb,EAAmB/H,GAEjBD,IAAAA,cAAC8I,EAAAA,YAAW,KACR9I,IAAAA,cAAC+I,EAAAA,OAAM,CAAClF,QAAS5D,EAAMyI,cAAe3F,UAAU,kCAC3C9C,EAAM0F,UAAUqD,qGCQ3B,SAAUC,EAAkB7X,EAAqDvD,EAA8Bqb,GACjH,GAAIA,EAAwB,CACxB,MAAMC,EAAoBD,EAAuBza,MAAK2a,GAAYA,EAASC,yBAAyBrc,YAAca,EAAQC,WAC1H,GAAIqb,GAAqBA,EAAkBG,gBACvC,OAAOH,EAAkBG,gBAGjC,IAAKlY,IAAoC3D,EAAAA,gBAAgBC,YAAYG,EAAQiD,iBACzE,OAEJ,MAAMyY,EAAqB1b,EAAQiD,gBAAgBrC,MAAKqN,GAAaA,EAAUhO,WAAasD,IAC5F,OAAImY,EACOA,EAAmBrY,eAD9B,EAMJ3I,eAAeihB,EAAoB9f,EAAuBoD,EAAmB2c,EAAoBC,GAC7F,IACI,MAAMjP,QAAiBkP,EAAmBjgB,GAC1C,GAAI+Q,GAAYA,EAASlF,cAAe,CACpC,MAAMqU,QAA4BC,EAAAA,EAAAA,eAAc,CAAEjgB,cAAeF,EAAQuc,eACrEwD,EACA,EACIK,EAAAA,EAAAA,mBAAkBhd,EAAW2N,EAASlF,cAAekU,KAE7D/f,EAAQuc,cAAc8D,QAAOC,EAAAA,EAAAA,0BAAyB,GAAI,MAAO,CAACJ,KAExE,MAAOK,GAAK,IAAAC,EAAAC,EACV,MAAMza,EAAQua,EACRG,EAAS1a,MAAAA,GAAW,QAANwa,EAALxa,EAAO2a,YAAI,IAAAH,GAAXA,EAAaI,cAAgB,mBAAmB5a,MAAAA,GAAW,QAANya,EAALza,EAAO2a,YAAI,IAAAF,OAAA,EAAXA,EAAaG,qBAAkBte,EAC9Fue,EAAAA,EAAO7a,MAAMga,EAAkBha,EAAO,CAAE0a,OAAQA,KAIxD7hB,eAAeohB,EAAmBjgB,GAC9B,MAAM8gB,EAAgB,IAAItV,EAAAA,iBAAiBxL,EAAQuc,cAAcvd,eAAelB,aAChF,OAAOyN,EAAAA,EAAAA,aAAYuV,EAAe9gB,EAAQuc,eAgG9C,SAASwE,EAAkB/gB,EAAuBic,EAAiD9X,EAA8B6c,EAAuCC,GAA2B,IAAAC,EAC/L,MAAMC,KAAeH,GAAaA,EAAUjY,OAAS,GAAmC,QAAlCmY,EAAIF,EAAU,GAAGI,yBAAiB,IAAAF,GAA9BA,EAAgCnc,MAAKmH,GAAKA,EAAE5I,YAAca,EAAQC,YAC5H,IAAIiV,EAAY,sBAMhB,OAJI8H,IACA9H,GAAa,kBAIb/C,EAAAA,cAAA,WACIA,EAAAA,cAAA,UACI+C,UAAWA,EACXqE,MAAQyD,EAAmDlF,EAAUoF,6BAA9CpF,EAAUqF,wBAAgE,aACpFH,EAAmDlF,EAAUoF,6BAA9CpF,EAAUqF,wBACtCnH,QAAStb,UACAsiB,EAjCzB,SAAgCnhB,EAAuBghB,EAAuC7c,EAA8B6b,GACxH,MAAMuB,EA5EV,SAAwCP,EAAuC5d,GAC3E,IAAK4d,IACA5d,GACoB,IAArB4d,EAAUjY,SACTiY,EAAU,GAAGI,mBAC4B,IAA1CJ,EAAU,GAAGI,kBAAkBrY,OAC/B,OAAO,KAGX,MAAMyY,EAAoBR,EAAU,GAAGI,kBAAkB5X,QAAOiY,GACrDA,EAAiBne,YAAcF,IAG1C,OAAIoe,GAAqBA,EAAkB,GAAGE,OACnCF,EAAkB,GAAGE,OAEzB,KA4DgBC,CAA+BX,EAAW7c,EAAQC,UACrE4c,GAAaA,EAAU,IAAMO,IAC7BK,EAAAA,EAAAA,kBAAiB,CAAE1hB,cAAeF,EAAQuc,eAAiByE,EAAU,GAAGa,GAAI,CAAC,CAAEH,OAAQH,KAClF7T,MAAKoU,IACF,MAAMC,EAAe,IACdf,GAEPe,EAAa,GAAKD,EAClB9hB,EAAQuc,cAAc8D,QAAOC,EAAAA,EAAAA,0BAAyB,GAAI,MAAOyB,MAEpEC,OAAMhc,IAAQ,IAAAic,EAAAC,EACX,MAAMxB,EAAS1a,MAAAA,GAAW,QAANic,EAALjc,EAAO2a,YAAI,IAAAsB,GAAXA,EAAarB,cAAgB,mBAAmB5a,MAAAA,GAAW,QAANkc,EAALlc,EAAO2a,YAAI,IAAAuB,OAAA,EAAXA,EAAatB,qBAAkBte,EAC9Fue,EAAAA,EAAO7a,MAAMga,EAAkBha,EAAO,CAAE0a,OAAAA,OAuBhCyB,CAAuBniB,EAASghB,EAAW7c,EAAS8X,EAAU+D,wBA5FtFnhB,eAAkCmB,EAAuBic,EAAiD9X,EAA8B8c,GACpI,IAAKjhB,IAAYmE,IAAYnE,EAAQC,QAAQlC,KAAK4C,UAC9C,OAAOsD,QAAQC,UAGnB,MAAMke,EAAgC,GAChCC,EAAe,IAAIC,EAAAA,aACrBne,EAAQC,SACRpE,EAAQC,QAAQnC,iBAChBwE,OAAWA,EACXtC,EAAQC,SACPD,EAAQC,QAAQlC,KAAK4C,WAE1ByhB,EAAcvY,KAAKwY,GAEnB,MAAME,QAAsBC,EAAAA,EAAAA,mBAAkBJ,EAAepiB,EAAQuc,eAErE,GAAIvc,EAAQC,QAAQlC,KAAKkB,iBAAmBsjB,GAAiBA,EAAcxZ,QAAU,EAAG,CACpF,MAAMgI,QAAiBkP,EAAmBjgB,GACpCghB,QAAkByB,EAAAA,EAAAA,0BAAwBnC,EAAAA,EAAAA,0BAAyB,GAAI,MAAOtgB,EAAQuc,eAC5F,GAAKyE,GAAkC,IAArBA,EAAUjY,aAsBlB+W,EAAoB9f,EAASuiB,EAAc,GAAGne,SAAU4c,EAAU,GAAGa,GAAI5F,EAAU+D,mBAEzF0C,EAAAA,EAAAA,GAAM,CACF7G,KAAMI,EAAU0G,2BAA2B7I,QAAQ,gBAAiByI,EAAc,GAAGpG,MAAQ,IAC7FyG,KAAM,UACNC,UAAW,IACXC,SAAU,eACVC,UAAU,EACVC,cAAc,QA9BoB,CACtC,MAAMC,EAAehC,EACrB,GAAIlQ,GAAYA,EAASlF,cAAe,CACpC,MAAMqX,EAAyB,CAC3BC,WAAYpS,EAASlF,cACrBsQ,KAAM8G,EACNG,sBAAuB,EACvBvB,GAAI,GAER,IACI,MAAMC,QAAqBuB,EAAAA,EAAAA,yBAAwB,CAC3CnjB,cAAeF,EAAQuc,eAE3B2G,SACEpD,EAAoB9f,EAASuiB,EAAc,GAAGne,SAAU0d,EAAaD,GAAI5F,EAAU+D,kBAC3F,MAAOO,GAAK,IAAA+C,EAAAC,EACV,MAAMvd,EAAQua,EACRG,EAAS1a,MAAAA,GAAW,QAANsd,EAALtd,EAAO2a,YAAI,IAAA2C,GAAXA,EAAa1C,cAAgB,mBAAmB5a,MAAAA,GAAW,QAANud,EAALvd,EAAO2a,YAAI,IAAA4C,OAAA,EAAXA,EAAa3C,qBAAkBte,EAC9Fue,EAAAA,EAAO7a,MAAMiW,EAAU+D,iBAAkBha,EAAO,CAAE0a,OAAAA,QAoDxC8C,CAAmBxjB,EAASic,EAAW9X,EAAS8c,KAM5DE,EAAmDlF,EAAUoF,6BAA9CpF,EAAUqF,0BAMpC,MAAMmC,EAAgE7H,IA2BxE,IA3ByE,KAC1E8H,EAAI,SACJ7f,EAAQ,eACR8f,EAAc,oBACdC,EAAmB,eACnBC,EAAc,eACdC,EAAc,gBACdC,EAAe,UACf/C,EAAS,QACThhB,EAAO,OACPqC,EAAM,cACN2Z,EAAa,UACbC,EAAS,WACT+H,EAAU,SACVC,EAAQ,oBACRC,EAAmB,iBACnBtM,EAAgB,cAChBuM,EAAa,wBACbC,EAAuB,gCACvB1c,EAA+B,qBAC/B2c,EAAoB,gCACpBC,EAA+B,uBAC/B9E,EAAsB,uBACtB+E,EAAsB,kBACtBC,EAAiB,WACjBC,EAAU,4BACVC,GACH9I,EACG,MAAO+I,EAAqBC,GAA0BtO,EAAAA,cAA4ChU,GAC5FuiB,EAAYvO,EAAAA,SAAc,IAAM,IAAIwO,EAAAA,EAAO,CAAEC,YAAa,KAAM,IAEhEC,EAA4BnmB,MAAAA,IAC9B,IAAIomB,EAEJ,GAAIC,EACAD,EAAoB,IAAKN,IAA4Cb,GAAkC,KAGnGmB,EAAkBE,OAAMjZ,GAAKA,EAAEkZ,YAAYvD,KAAOqD,EAAiBrD,MACnEoD,EAAkBI,OAAO,EAAG,EAAG,IAAIC,EAAAA,cAAcJ,EAAkB,GAAI,QAExE,CAEH,MAAMvlB,EAAsBqC,EAAAA,yBAAyBC,cAAc,CAC/DjD,eAAgBgB,EAAQC,QACxBoC,OAAQA,IACTH,oBACGpD,EAAQ,IAAIymB,EAAAA,uBAAuB,GAAI5lB,GAC7CslB,SAA2BO,EAAAA,EAAAA,mBAAkB1mB,EAAOkB,EAAQuc,gBAAgBlb,KAAI6K,GAAK,IAAIoZ,EAAAA,cAAcpZ,EAAG,GAAI,KAIlH,OADA0Y,EAAuBK,GAChBA,GAGLQ,EAAyB5mB,SACpBilB,IAAkCa,GAA4CK,KAGnFU,EAA2C,CAC7CC,oBAAqB1J,EAAU0J,qBAEnC,OACIrP,EAAAA,cAAA,MAAI+C,UAAU,iBACTxV,EAASxC,KAAI,CAAC8C,EAAiC2E,KAAa,IAAA8c,EAAA,OACzDtP,EAAAA,cAAA,MAAI+C,UAAU,iCAAiClY,IAAK2H,GAChDwN,EAAAA,cAACuP,EAAAA,iBAAgB,CACb7lB,QAASA,EACT4X,iBAAkBA,EAClBoE,cAAeA,EACf8J,cAAe7J,EAAU8J,UACzBC,kBAAmB/J,EAAU+J,kBAC7BC,iBAAkBhK,EAAUgK,iBAC5BC,gBAAiBjK,EAAUiK,gBAC3BC,UAAWjC,EACX7kB,GAAI4kB,EACJ9iB,IAAKgD,EAAQC,SACbgiB,SAAUpC,EACVrD,KAAM,CACF+C,KAAAA,EACAvf,QAAAA,EACAoe,cAAeoB,EAAe5e,MAAKmH,GAAKA,EAAE9H,WAAaD,EAAQC,WAC/Dwf,oBAAAA,EACAG,gBAAiBA,MAAAA,OAAe,EAAfA,EAAiBva,QAAO0C,GAAKA,EAAEma,kBAAoBliB,EAAQC,YAEhFygB,UAAWA,EACXyB,cAAY,EACZC,sBAAsBC,EAAAA,EAAAA,IAAqBxmB,EAAS6jB,GACpD4B,uBAAwBA,EACxBgB,uBAAwBzB,EACxB0B,gBAAiBvC,EACjBC,wBAAyBA,EACzBuC,eAAgB5F,EAAkB/gB,EAASic,EAAW9X,EAAS6c,EAAW/E,EAAUgF,qBACpF2F,eAAgBrH,EAAkB7X,EAAiCvD,EAAQqb,GAC3EqH,gBAAiBnC,MAAAA,OAA2B,EAA3BA,EAA6B3f,MAAKmH,GAAKA,EAAEyT,yBAAyBrc,YAAca,EAAQC,WACzGigB,qBAAsBA,EACtByC,iBAAkBtC,EAClBuC,UAAWtC,EACXuC,cAAezC,MAAAA,GAAkE,QAA5CqB,EAAtBrB,EAAwBxf,MAAKmH,GAAKA,EAAE9H,WAAaD,EAAQC,kBAAS,IAAAwhB,OAAA,EAAlEA,EAAoEqB,UACnFvB,eAAgBA,EAChBwB,oBAAqBjL,EAAUiL,oBAC/BC,cAAelL,EAAUkL,cACzBC,eAAgBnL,EAAUmL,eAC1BC,mBAAoBpL,EAAUoL,mBAC9BC,eAAgBrL,EAAUqL,eAC1BC,eAAgBtL,EAAUsL,eAC1BC,aAAc,CACVC,YAAaxL,EAAU+D,iBACvB0H,oBAAqBzL,EAAUyL,oBAC/BC,wBAAyB1L,EAAU0L,wBACnCC,sBAAuB3L,EAAU2L,sBACjCC,SAAU5L,EAAU6L,cACpBC,kBAAmB9L,EAAU+L,wBAEjCC,kBAAmBhM,EAAUgM,kBAC7BC,eAAgBjM,EAAUiM,eAC1BC,wBAAyBlM,EAAUkM,wBACnCC,wBAAyB9D,MAAAA,OAA+B,EAA/BA,EAAiCvf,MACtDsjB,GACItkB,EAAAA,gBAAgBC,YAAYqkB,IAC5BA,EAAsB,GAAGC,kBAAoBnkB,EAAQokB,kBAE7DC,4BAA6B,CACzBC,yBAA0BxM,EAAUwM,yBACpCC,wBAAyBzM,EAAUyM,wBACnCC,4BAA6B1M,EAAU0M,4BACvCC,gCAAiC3M,EAAU2M,gCAC3CC,iCAAkC5M,EAAU4M,iCAC5CC,sCAAuC7M,EAAU6M,sCACjDC,oBAAqB9M,EAAU8M,oBAC/BC,wBAAyB/M,EAAU+M,wBACnCC,cAAehN,EAAUgN,cACzBC,0BAA2BjN,EAAUiN,0BACrCC,mBAAoBlN,EAAUkN,mBAC9BC,2BAA4BnN,EAAUmN,2BACtCC,+BAAgCpN,EAAUoN,+BAC1CC,yBAA0BrN,EAAUqN,yBACpCC,8BAA+BtN,EAAUsN,8BACzCC,yCAA0CvN,EAAUuN,yCACpDC,4BAA6BxN,EAAUwN,4BACvCC,2BAA4BzN,EAAUyN,2BACtCC,0CAA2C1N,EAAU0N,0CACrDC,6CAA8C3N,EAAU2N,6CACxDC,0CAA2C5N,EAAU4N,0CACrD9D,UAAW9J,EAAU8J,UACrBC,kBAAmB/J,EAAU+J,kBAC7BC,iBAAkBhK,EAAUgK,iBAC5B6D,yBAA0B7N,EAAU6N,yBACpCC,8BAA+B9N,EAAU8N,8BACzCC,yBAA0B/N,EAAU+N,yBACpCC,+BAAgChO,EAAUgO,+BAC1CC,6BAA8BjO,EAAUiO,6BACxCC,gCAAiClO,EAAUkO,iCAE/CC,cAAgBjmB,IAAYkmB,EAAAA,EAAAA,GACxBrqB,EACA4jB,EACAzf,EACA8X,EAAU+L,wECvY/B,MAAMsC,EAAkC1O,IAAA,IAAC,UAAE2O,GAAW3O,EAAA,OACzDtF,EAAAA,cAAA,YACK,IACAiU,EACA,MCHIC,EAA0B5O,IAAA,IAAC,KAAEC,EAAI,UAAExC,GAAWuC,EAAA,OACvDtF,EAAAA,cAAA,QAAM+C,UAAWA,GACZ,IACAwC,EACA,qDCiCT,IAAqB4O,EAArB,cAAkDnU,EAAAA,UAO9CzY,YAAmB0Y,GACfC,MAAMD,GAPO,KAAAmU,6BAAoD,IAAIC,IAQrE1sB,KAAK2sB,qBAAuB3sB,KAAK2sB,qBAAqBC,KAAK5sB,MAC3DA,KAAK6sB,qBAAuB7sB,KAAK6sB,qBAAqBD,KAAK5sB,MAC3DA,KAAK8sB,aAAe9sB,KAAK8sB,aAAaF,KAAK5sB,MAE3CA,KAAK+sB,SAAW1U,EAAAA,YAChBrY,KAAKgtB,SAAW3U,EAAAA,YAChB,IAAI4U,EAAa,GACbC,EAAa,GACjB,MAAM,4BAAEC,EAA2B,8BAAEC,GAAkCptB,KAAKsY,MACxE6U,IACAF,GAAaI,EAAAA,EAAAA,IAAiCF,EAA6BC,GACrE,IACAD,MAAAA,OAA2B,EAA3BA,EAA6B5pB,uBAAwB,GAC3D2pB,GAAaG,EAAAA,EAAAA,IAAiCF,EAA6BC,GACrE,IACAD,MAAAA,OAA2B,EAA3BA,EAA6B3pB,wBAAyB,IAGhExD,KAAKstB,MAAQ,CACTC,wBAAoBlpB,EACpBmpB,wBAAoBnpB,EACpBopB,YAAaR,EACbS,YAAaR,EACbS,cAAeV,GAAcC,GAC7BU,WAAW,GAIZC,sBAAsBC,EAAuCC,GAChE,OAAI/tB,KAAKstB,QAAUS,GAAa/tB,KAAKsY,QAAUwV,KAG/CC,EAAUJ,cAAgBI,EAAUN,aAAeM,EAAUL,cACtD,GAGJM,mBAAmBC,GAClBA,IAAkBjuB,KAAKsY,OACvBtY,KAAKkuB,yBAIN5T,SACH,GAA6B,UAAzBta,KAAKsY,MAAM6V,UACX,OAAOnuB,KAAKouB,qBAQZF,yBAAsB,IAAAG,EAAAC,EAAAC,EAAAC,EAC1B,MAAMf,EAAegB,GAAAA,CAAkD,QAAlDJ,EAAYruB,KAAKsY,MAAM6U,mCAA2B,IAAAkB,OAAA,EAAtCA,EAAwC7c,WAE7B,QADpC8c,EACFtuB,KAAKsY,MAAM6U,mCAA2B,IAAAmB,OAAA,EAAtCA,EAAwC/qB,qBADxC,GAEAmqB,EAAee,GAAAA,CAAkD,QAAlDF,EAAYvuB,KAAKsY,MAAM6U,mCAA2B,IAAAoB,OAAA,EAAtCA,EAAwC/c,WAE7B,QADpCgd,EACFxuB,KAAKsY,MAAM6U,mCAA2B,IAAAqB,OAAA,EAAtCA,EAAwChrB,sBADxC,GAENxD,KAAK0uB,SAAS,CAAEjB,YAAAA,EAAaC,YAAAA,IAGzBU,qBACJ,MAAM,WAAEO,EAAU,8BAAEvB,EAA6B,sBAAEwB,GAA0B5uB,KAAKsY,OAC5E,mBAAEiV,EAAkB,mBAAEC,GAAuBxtB,KAAKstB,MAGlDuB,EAAY,CACd,cAFoBD,EAAsBE,iBAAmB,OAAOjT,QAAQ,MAAOuR,EAA8BtQ,SAAW,IAG5H,gBAAiB6R,GAGfI,EAAoB,mEACtBxB,EAAqB,qCAAuC,IAE1DyB,EAAoB,mEACtBxB,EAAqB,qCAAuC,IAEhE,OACInV,EAAAA,cAAA,MAAI+C,UAAU,8EACV/C,EAAAA,cAAA,OAAA0D,OAAAC,OAAA,CAAMZ,UAAW,0CAA8CyT,GAC3DxW,EAAAA,cAAA,WACIA,EAAAA,cAAA,SACI+C,UAAW2T,EACXE,YAAa,MACbC,SAAUlvB,KAAK2sB,qBACfxpB,MAAOnD,KAAKstB,MAAMG,YAClB3N,IAAK9f,KAAK+sB,WAEd1U,EAAAA,cAAA,YAAO,OACPA,EAAAA,cAAA,SACI+C,UAAW4T,EACXC,YAAa,MACbC,SAAUlvB,KAAK6sB,qBACf1pB,MAAOnD,KAAKstB,MAAMI,YAClB5N,IAAK9f,KAAKgtB,WAEbO,GACGlV,EAAAA,cAAA,QAAM+C,UAAU,wFACXmS,GAGRC,GAAsBD,IAAuBC,GAC1CnV,EAAAA,cAAA,QAAM+C,UAAU,wFACXoS,IAIbnV,EAAAA,cAAA,WACIA,EAAAA,cAAC+I,EAAAA,OAAM,CAAC3B,MAAO,QAASrE,UAAU,WAAWc,QAASlc,KAAK8sB,aAAcqC,SAAUnvB,KAAKstB,MAAMK,aACzF,YAQjBb,aAAasC,GACjB,MAAMC,EAAmBrvB,KAAKsvB,2BAA2BtvB,KAAKstB,MAAMG,aAAe,IACnFztB,KAAK0uB,SAAS,CACVjB,YAAa4B,EACbE,YAAY,IAEhB,MAAMxC,EAAW/f,OAAOqiB,IAClB,SAAEG,EAAQ,8BAAEpC,GAAkCptB,KAAKsY,MACnD5Q,EAAM1H,KAAKstB,MAAMI,YAEjB+B,EAAS/nB,EAAMsF,OAAOtF,QAAOrD,EAC7BiY,EAA2C,CAC7ChZ,gBAAiB8pB,EAA8BlT,OAAO,GAAG5W,gBACzDC,qBAAsBvD,KAAKstB,MAAMG,YACjCjqB,sBAAuBxD,KAAKstB,MAAMI,YAClCtc,cAAegc,EAA8Bhc,cAC7CM,mBAAoB0b,EAA8BlT,OAAO,GAAGxI,oBAG5D1R,KAAK0vB,eAAe3C,EAAU0C,IAC9BD,EAAS,CACLpC,8BAAAA,EACA9Q,oBAAAA,EACAqT,aAAa,IAKjBhD,qBAAqByC,GACzBpvB,KAAK0uB,SAAS,CACVjB,YAAa2B,EAAMvW,OAAO1V,MAAMysB,SAIhC/C,qBAAqBuC,GACzBpvB,KAAK0uB,SAAS,CACVhB,YAAa0B,EAAMvW,OAAO1V,MAAMysB,SAIhCF,eAAeG,EAAanoB,GAChC,MAAM,sBAAEknB,GAA0B5uB,KAAKsY,MACvC,YAAYjU,IAARqD,MAIAmoB,EAAMnoB,KACN1H,KAAK0uB,SAAS,CACVnB,mBAAoBqB,EAAsBkB,qBAC1CtC,mBAAoBoB,EAAsBkB,wBAEvC,IAMPR,2BAA2BzuB,GAE/B,MAAMkvB,EAAa/iB,OAAOnM,GAC1B,IAAKoM,MAAM8iB,GACP,OAAOlvB,EAKX,OAD4Bb,KAAKysB,6BAA6Bna,IAAIzR,IACpCA,IAjMjB2rB,GAAoBjP,EAAAA,EAAAA,IAAA,CADxCE,EAAAA,IACoB+O,kICDrB,IAAqBwD,EAArB,cAA6C3X,EAAAA,UAWzCzY,YAAmB0Y,GAA4B,IAAA2X,EAAAtS,EAAA0Q,EAAAC,EAAA4B,EAAA3B,EAAAC,EAC3CjW,MAAMD,GAXO,KAAAmU,6BAAoD,IAAIC,IA0IxD,KAAAyD,UAAY,CAACC,EAAkBC,EAAkBC,IACvD,CACH,CACIC,QAAS,GAAGH,UACZI,YAAa,GAAGH,IAChBI,iBAAkB,SAEtB,CACIF,QAAS,GAAGH,QACZI,YAAa,GAAGF,IAChBG,iBAAkB,QAgBb,KAAAC,gBAAkB,CAC/BN,EACAO,EACAlD,EACAmD,EACAlD,EACAmD,EACAP,KACqB,IAAAQ,EAAAC,EAErB,MAAO,CACH,CACI3vB,GAAI,GAAGgvB,IAAWO,uBAClBxtB,MAAQsqB,GAAezgB,OAAOygB,IAJN,EAKxB9N,UAAW,GAA0C,QAA1CmR,EAAG9wB,KAAKsY,MAAM0Y,oCAA4B,IAAAF,EAAAA,EAAI,MAAM9wB,KAAKixB,eACpEC,cAAe,GAAGN,KAEtB,CACIxvB,GAAI,GAAGgvB,IAAWO,qBAClBxtB,MAAO6J,OAAO0gB,IAAgB1gB,OAAOsjB,GACrC3Q,UAAW,GAA0C,QAA1CoR,EAAG/wB,KAAKsY,MAAM6Y,oCAA4B,IAAAJ,EAAAA,EAAI,MAAM/wB,KAAKixB,eACpEC,cAAe,GAAGL,OA7K1B7wB,KAAKoxB,eAAiBpxB,KAAKoxB,eAAexE,KAAK5sB,MAC/CA,KAAKqxB,kBAAoBrxB,KAAKqxB,kBAAkBzE,KAAK5sB,MACrDA,KAAKsxB,wBAA0BtxB,KAAKsxB,wBAAwB1E,KAAK5sB,MACjEA,KAAKuxB,WAAavxB,KAAKuxB,WAAW3E,KAAK5sB,MACvCA,KAAKwxB,WAAaxxB,KAAKwxB,WAAW5E,KAAK5sB,MACvCA,KAAKyxB,iBAAmBzxB,KAAKyxB,iBAAiB7E,KAAK5sB,MACnDA,KAAK0xB,iBAAmB1xB,KAAK0xB,iBAAiB9E,KAAK5sB,MAEnDA,KAAK+sB,SAAW1U,EAAAA,YAChBrY,KAAKgtB,SAAW3U,EAAAA,YAEhB,MAAM,4BAAE8U,GAAgCntB,KAAKsY,MACvC2U,EAA8D,QAApDgD,EAAG9C,MAAAA,OAA2B,EAA3BA,EAA6B5pB,4BAAoB,IAAA0sB,EAAAA,EAAI,IAClE/C,EAAaC,MAAAA,OAA2B,EAA3BA,EAA6B3pB,sBAC1C4sB,EAAW,UAAUuB,OAAO3xB,KAAKsY,MAAM8U,8BAA8BjnB,aAAawrB,OACpF3xB,KAAKsY,MAAMgE,oBAAoBhZ,mBAE7BsuB,EAAW5xB,KAAKsY,MAAMgE,oBAAoB/Y,qBAC1CsuB,EAAW7xB,KAAKsY,MAAMgE,oBAAoB9Y,sBAC1C6sB,EAAWrwB,KAAKgd,aAAa4U,GAC7BtB,EAAWtwB,KAAKgd,aAAa6U,GAC7BC,EAAyB9xB,KAAKmwB,UAAUC,EAAUC,EAAUC,GAC5D7C,EACiH,QADtG9P,EAC+C,QAD/C0Q,EACyB,QADzBC,EACbtuB,KAAKsY,MAAM6U,mCAA2B,IAAAmB,OAAA,EAAtCA,EAAwC/qB,4BAAoB,IAAA8qB,EAAAA,EAAIruB,KAAKsY,MAAMgE,oBAAoB/Y,4BAAoB,IAAAoa,EAAAA,EAAI,IACrH+P,EAEkD,QAFvCwC,EACgD,QADhD3B,EACyB,QADzBC,EACbxuB,KAAKsY,MAAM6U,mCAA2B,IAAAqB,OAAA,EAAtCA,EAAwChrB,6BAAqB,IAAA+qB,EAAAA,EAC7DvuB,KAAKsY,MAAMgE,oBAAoB9Y,6BAAqB,IAAA0sB,EAAAA,EACpD2B,EACEjB,EAAmB5wB,KAAKgd,aAAayQ,GACrCoD,EAAmB7wB,KAAKgd,aAAa0Q,GACrCqE,EAAkB/xB,KAAKsY,MAAMqY,UAAY,IAAIgB,OAAO3xB,KAAKsY,MAAMqY,aAAe,GAC9EqB,EAAoChyB,KAAK0wB,gBAC3CN,EACA2B,EACAtE,EACAmD,EACAlD,EACAmD,EACAP,GAEJtwB,KAAKstB,MAAQ,CACTM,WAAW,EACXL,wBAAoBlpB,EACpBmpB,wBAAoBnpB,EACpBopB,YAAaR,EACbS,YAAaR,EACb+E,YAAY,EACZC,YAAY,EACZ9B,SAAAA,EACAwB,SAAAA,EACAC,SAAAA,EACAC,OAAAA,EACAE,aAAAA,GA1DE,mBACN,OAAOhyB,KAAKsY,MAAMgE,oBAAoB/K,UAAY,GA6D/Csc,sBAAsBC,EAAkCC,GAC3D,OAAI/tB,KAAKstB,QAAUS,GAAa/tB,KAAKsY,QAAUwV,EAM5CE,mBAAmBC,GAClBA,IAAkBjuB,KAAKsY,OACvBtY,KAAKmyB,oBAIN7X,SACH,MAAM,oBAAEgC,EAAmB,8BAAE8Q,EAA6B,sBAAEwB,GAA0B5uB,KAAKsY,MAE3F,GAAKgE,GAAwB8Q,EAO7B,MAA6B,UAAzBptB,KAAKsY,MAAM6V,UACJnuB,KAAKouB,qBAGTpuB,KAAKoyB,gBAVRxD,EAAsB5mB,UAAUD,MAC5B,kGAeJoqB,oBAAiB,IAAAE,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EACrB,MAAMtC,EAAW,UAAUuB,OAAO3xB,KAAKsY,MAAM8U,8BAA8BjnB,aAAawrB,OACpF3xB,KAAKsY,MAAMgE,oBAAoBhZ,mBAE7BsuB,EAAW5xB,KAAKsY,MAAMgE,oBAAoB/Y,qBAC1CsuB,EAAW7xB,KAAKsY,MAAMgE,oBAAoB9Y,sBAC1C6sB,EAAWrwB,KAAKgd,aAAa4U,GAC7BtB,EAAWtwB,KAAKgd,aAAa6U,GAC7BC,EAAyB9xB,KAAKmwB,UAAUC,EAAUC,EAAUC,GAC5D7C,EACiH,QADtG4E,EAC+C,QAD/CC,EACyB,QADzBC,EACbvyB,KAAKsY,MAAM6U,mCAA2B,IAAAoF,OAAA,EAAtCA,EAAwChvB,4BAAoB,IAAA+uB,EAAAA,EAAItyB,KAAKsY,MAAMgE,oBAAoB/Y,4BAAoB,IAAA8uB,EAAAA,EAAI,IACrH3E,EAEkD,QAFvC8E,EACgD,QADhDC,EACyB,QADzBC,EACb1yB,KAAKsY,MAAM6U,mCAA2B,IAAAuF,OAAA,EAAtCA,EAAwClvB,6BAAqB,IAAAivB,EAAAA,EAC7DzyB,KAAKsY,MAAMgE,oBAAoB9Y,6BAAqB,IAAAgvB,EAAAA,EACpDX,EACEjB,EAAmB5wB,KAAKgd,aAAayQ,GACrCoD,EAAmB7wB,KAAKgd,aAAa0Q,GACrCqE,EAAkB/xB,KAAKsY,MAAMqY,UAAY,IAAIgB,OAAO3xB,KAAKsY,MAAMqY,aAAe,GAC9EqB,EAAoChyB,KAAK0wB,gBAC3CN,EACA2B,EACAtE,EACAmD,EACAlD,EACAmD,EACAP,GAEJtwB,KAAK0uB,SAAS,CAAE0B,SAAAA,EAAUwB,SAAAA,EAAUC,SAAAA,EAAUC,OAAAA,EAAQE,aAAAA,IA8DlD5D,qBACJ,MAAM,WAAEO,EAAU,8BAAEvB,EAA6B,sBAAEwB,GAA0B5uB,KAAKsY,OAC5E,YAAEmV,EAAW,YAAEC,EAAW,WAAEuE,EAAU,WAAEC,EAAU,mBAAE3E,EAAkB,mBAAEC,GAAuBxtB,KAAKstB,MAGpGuB,EAAY,CACd,cAFoBD,EAAsBE,iBAAmB,OAAOjT,QAAQ,MAAOuR,EAA8BtQ,SAAW,IAG5H,gBAAiB6R,GAOfI,EAAoB,mEACtBxB,EAAqB,qCAAuC,IAE1DyB,EAAoB,mEACtBxB,EAAqB,qCAAuC,IAI1DmF,EAAuB3yB,KAAK4yB,2BAA2BnF,EAAawE,EAAY1E,GAChFsF,EAAuB7yB,KAAK4yB,2BAA2BlF,EAAawE,EAAY1E,GACtF,OACInV,EAAAA,cAAA,OAAA0D,OAAAC,OAAA,CAAMZ,UAAU,0CAA6CyT,GACzDxW,EAAAA,cAAA,SAAO+C,UANW,8EAObwT,EAAsBkE,SACvBza,EAAAA,cAAA,SACI+C,UAAW2T,EACXG,SAAUlvB,KAAKuxB,WACfwB,QAAS/yB,KAAKuxB,WACdyB,OAAQhzB,KAAKyxB,iBACbtuB,MAAOwvB,EACP7S,IAAK9f,KAAK+sB,YAGlB1U,EAAAA,cAAA,SAAO+C,UAhBW,8EAiBbwT,EAAsBqE,SACvB5a,EAAAA,cAAA,SACI+C,UAAW4T,EACXC,YAAa4D,OAAuBxuB,EAAYuqB,EAAsBsE,mBACtEhE,SAAUlvB,KAAKwxB,WACfuB,QAAS/yB,KAAKwxB,WACdwB,OAAQhzB,KAAK0xB,iBACbvuB,MAAO0vB,EACP/S,IAAK9f,KAAKgtB,YAGjBO,GACGlV,EAAAA,cAAA,QAAM+C,UAAU,wFACXmS,GAGRC,GAAsBD,IAAuBC,GAC1CnV,EAAAA,cAAA,QAAM+C,UAAU,wFACXoS,IAOb4E,gBACJ,MAAM,WAAEzD,EAAU,UAAEgC,GAAc3wB,KAAKsY,MACjC6a,EAAiB,CACnB,gBAAiBxE,GAGrB,OACItW,EAAAA,cAAC+a,EAAAA,OAAMrX,OAAAC,OAAA,CACHZ,UAAU,mCACVlY,IAAKlD,KAAKstB,MAAM8C,SAChBO,UAAWA,EACXvvB,GAAIpB,KAAKstB,MAAM8C,SACfiD,QAAQ,EACRxD,IAAM7vB,KAAKstB,MAAMsE,UAAY5kB,OAAOhN,KAAKstB,MAAMsE,gBAAcvtB,EAC7DqD,IAAM1H,KAAKstB,MAAMuE,UAAY7kB,OAAOhN,KAAKstB,MAAMuE,gBAAcxtB,EAC7DivB,KAAM,EACNC,YAAY,aACZzB,OAAQ9xB,KAAKstB,MAAMwE,OACnB0B,YAAU,EACVC,aAAW,EACXzB,aAAchyB,KAAKstB,MAAM0E,aACzB0B,YAAa1zB,KAAKqxB,kBAClBnC,SAAUyE,GAAAA,CAAS3zB,KAAKoxB,eAAgB,KACxCwC,kBAAmB5zB,KAAKsxB,yBACpB6B,IAKR5B,WAAWnC,GACfpvB,KAAK6zB,aAAazE,EAAO,OAGrBoC,WAAWpC,GACfpvB,KAAK6zB,aAAazE,EAAO,OAGrByE,aAAazE,EAA2C0E,GAC5D,MAAMC,EAAc,WAAWD,IACzBE,EAAa,UAAUF,IAC7B9zB,KAAK0uB,SAAS,CACV,CAACqF,GAAc/zB,KAAKsvB,2BAA2BF,EAAMtW,cAAc3V,OACnE,CAAC6wB,IAAa,IAIdvC,iBAAiBrC,GACrB,MAAMC,EAAmBrvB,KAAKsvB,2BAA2BF,EAAMtW,cAAc3V,OAC7EnD,KAAK0uB,SAAS,CACVjB,YAAa4B,EACbE,YAAY,IAEhB,MAAMxC,EAAW/f,OAAOqiB,IAClB,SACFG,EAAQ,8BACRpC,EAA6B,oBAC7B9Q,EAAmB,sBACnBsS,EAAqB,4BACrBzB,GACAntB,KAAKsY,MACH5Q,EAAOylB,GAA+BA,EAA4B3pB,4BAA0Ba,EAE5ForB,EAAS/nB,EAAMsF,OAAOtF,QAAOrD,EAEnC,OAAI4I,MAAM8f,IACN/sB,KAAK0uB,SAAS,CAAEnB,mBAAoBqB,EAAsBqF,qBAC1Dj0B,KAAKk0B,OAAO,QACL,GAGPl0B,KAAK0vB,eAAe3C,EAAU0C,IAC9BD,EAAS,CACLpC,8BAAAA,EACA9Q,oBAAAA,EACAqT,aAAa,EACbwE,WAAYpH,EACZqH,SAAU3E,KAEP,IAEXzvB,KAAKk0B,OAAO,QAEL,GAGHxC,iBAAiBtC,GACrB,MAAMiF,EAAmBr0B,KAAKsvB,2BAA2BF,EAAMtW,cAAc3V,OAC7EnD,KAAK0uB,SAAS,CACVhB,YAAa2G,EACbC,YAAY,IAEhB,MAAMtH,EAAWhgB,OAAOqnB,IAClB,SACF7E,EAAQ,8BACRpC,EAA6B,oBAC7B9Q,EAAmB,sBACnBsS,EAAqB,4BACrBzB,GACAntB,KAAKsY,MACHuX,EAAO1C,GAA+BA,EAA4B5pB,sBAAyB,IAE3FgxB,EAASvnB,OAAO6iB,GAEtB,OAAI5iB,MAAM+f,IACNhtB,KAAK0uB,SAAS,CAAElB,mBAAoBoB,EAAsBqF,qBAC1Dj0B,KAAKk0B,OAAO,QACL,KAGPl0B,KAAK0vB,eAAe6E,EAAQvH,KACxB1Q,EACAkT,EAAS,CACLpC,8BAAAA,EACA9Q,oBAAAA,EACAqT,aAAa,EACbwE,WAAYI,EACZH,SAAUpH,IAGdhtB,KAAKk0B,OAAO,QAET,GAMPA,OAAOJ,GACX,MAAMhU,EAAoB,QAAdgU,EAAsB9zB,KAAKgtB,SAAWhtB,KAAK+sB,SAEvDyH,YAAW,KACH1U,GAAOA,EAAI2U,SACX3U,EAAI2U,QAAQC,UAEjB,IAGC9B,2BACJtV,EACAqX,EACAC,GAEA,OAAID,GAAWC,QAAgCvwB,IAAbiZ,EACvBA,EAEJtd,KAAKgd,aAAaM,GAGrBoS,eAAeG,EAAanoB,GAChC,MAAM,sBAAEknB,GAA0B5uB,KAAKsY,MACvC,YAAYjU,IAARqD,MAIAmoB,EAAMnoB,KACN1H,KAAK0uB,SAAS,CACVnB,mBAAoBqB,EAAsBkB,qBAC1CtC,mBAAoBoB,EAAsBkB,wBAEvC,IAMP9S,aAAaE,GACjB,GAAuD,IAAnDld,KAAKsY,MAAMgE,oBAAoBhZ,gBAAuB,CAEtD,OADetD,KAAKsY,MAAMvW,QAAQqb,iBAAiBC,eAAerQ,OAAOkQ,GAASld,KAAKixB,cAG3F,OAAO/T,GAAU,GAGboS,2BAA2BzuB,GAE/B,MAAMkvB,EAAa/iB,OAAOnM,GAC1B,IAAKoM,MAAM8iB,GACP,OAAOlvB,EAKX,OAD4Bb,KAAKysB,6BAA6Bna,IAAIzR,IACpCA,EAK1BuwB,eAAeyD,GAEnB,GAA2C,cAAvCA,EAAyBC,UAA2B,CACpD,MAAM,SAAEtF,EAAQ,8BAAEpC,EAA6B,oBAAE9Q,GAAwBtc,KAAKsY,MAC1EgE,GAAuBuY,IACvBrF,EAAS,CACLpC,8BAAAA,EACA9Q,oBAAAA,EACAqT,aAAa,EACbwE,WAAYU,EAAyBE,gBACrCX,SAAUS,EAAyBG,mBAGvCh1B,KAAKi1B,oBAAoBJ,KAM7BxD,kBAAkBwD,GACtB,MAAM,SAAErF,EAAQ,8BAAEpC,EAA6B,oBAAE9Q,GAAwBtc,KAAKsY,MAC1EgE,GAAuBuY,IACvBrF,EAAS,CACLpC,8BAAAA,EACA9Q,oBAAAA,EACAqT,aAAa,EACbwE,WAAYU,EAAyBE,gBACrCX,SAAUS,EAAyBG,mBAGvCh1B,KAAKi1B,oBAAoBJ,IAKzBI,oBAAoBJ,GACxB,GAAIA,EAAyBzzB,GAAI,CAC7B,MAAMgI,EAAU8rB,SAASC,eAAe,GAAGN,EAAyBzzB,WAChEgI,GACAorB,YAAW,KACPprB,EAAQsrB,UACT,IAKPpD,wBAAwB8D,GAC5B,OAAOp1B,KAAKgd,aAAa,GAAGoY,QAjetB7X,EAAAA,EAAAA,IAAA,CAATC,EAAAA,IAAQ,iCAPQwS,GAAezS,EAAAA,EAAAA,IAAA,CADnCE,EAAAA,IACoBuS,ufCYP,MAAOqF,UAAmBhd,EAAAA,UAKpCzY,YAAmB0Y,GACfC,MAAMD,GAkMO,KAAAG,SAAYC,IACzBA,EAAEC,iBAEF,MAAM,8BAAEyU,EAA6B,oBAAE9Q,EAAmB,4BAAE6Q,GAAgCntB,KAAKsY,MAC7FgE,IACAtc,KAAKsY,MAAMkX,SAAS,CAChBpC,8BAAAA,EACA9Q,oBAAAA,EACAqT,aAAcxC,IAGlBqH,YAAW,KACPx0B,KAAKs1B,WAAWb,SAAWz0B,KAAKs1B,WAAWb,QAAQC,UACpD,KA9MP10B,KAAKyY,SAAWzY,KAAKyY,SAASmU,KAAK5sB,MACnCA,KAAKstB,MAAQ,CACTM,YAAa5tB,KAAKsY,MAAM6U,6BAE5BntB,KAAKs1B,WAAajd,EAAAA,YAClBrY,KAAKyZ,SAAUC,EAAAA,EAAAA,kBAAiB,QAAS1Z,KAAKsY,MAAMqB,iBAAmB,IAGpEkU,sBAAsBC,EAA6BC,GACtD,OAAI/tB,KAAKstB,QAAUS,GAAa/tB,KAAKsY,QAAUwV,EAM5CxT,SAAM,IAAAib,EAAAC,EACT,MAAAC,EAmBIz1B,KAAKsY,OAnBH,WACFqW,EAAU,sBACVC,EAAqB,8BACrBxB,EAA6B,oBAC7B9Q,EAAmB,4BACnB6Q,EAA2B,sBAC3BuI,EAAqB,4BACrBC,EAA2B,MAC3B9qB,EAAK,SACL+qB,EAAQ,SACRpG,EAAQ,QACRztB,EAAO,iBACP4X,EAAgB,oBAChBkc,EAAmB,qBACnBC,EAAoB,QACpBC,EAAO,OACPC,EAAM,uBACNhgB,GAEHyf,EADMQ,GAAKC,EAAAA,EAAAA,GAAAT,EAAAU,GAEZ,IAAK7Z,EAED,YADAsS,EAAsB5mB,UAAUD,MAAM,sEAGrCuU,EAAoB/Y,sBACrBqrB,EAAsB5mB,UAAU8H,QAC5B,2DAA2DjL,KAAKO,UAAUkX,MAGlF,MAAM8Z,EAAiBhJ,EAA8BiJ,mBAAqBC,EAAAA,YAAYC,aACtF,IAAIC,EAAoBJ,EAAiB,gBAAkB,eAC3DI,EAAoB,0BAA0BA,IAC9C,MAAM1C,EAAYsC,EAAiB,QAAU,WACvCxI,IAAcT,EAEpB,GADAqJ,EAAoB5I,EAAY,GAAG4I,YAA8BA,EAC7DpJ,EAA8BqJ,cAAgB9kB,EAAAA,qBAAqB+kB,OACnE,OAAO12B,KAAK22B,cACRra,EACA8Q,EACAQ,EACA7rB,EACA8I,EACA8O,EACA+b,EACAC,GAGR,IAAIla,EAAYa,EAAoBX,+BAAiCW,EAAoB/Y,qBAErFyS,GAA0BsG,EAAoBhZ,kBAAoB0J,OAAOgJ,KACvD,MAAdyF,EACAA,EAAYua,MAAAA,EAAAA,EAAU,KACD,MAAdva,IACPA,EAAYsa,MAAAA,EAAAA,EAAW,QAIe,yBAA1C3I,EAA8BtQ,UACZ,MAAdrB,EACAA,EAAYua,MAAAA,EAAAA,EAAU,KACD,MAAdva,IACPA,EAAYsa,MAAAA,EAAAA,EAAW,QAI/B/1B,KAAKyZ,QAAQuB,cAAcC,MAAQQ,EACnC,MAAMtH,GAAYgH,EAAAA,EAAAA,wBAAuBxB,EAAmB3Z,KAAKyZ,SAE3Dmd,EAAcnb,GAAa,GAE3Bob,EAAeva,EAAoB7K,OAAS,EAClD,IAAIqlB,EAEAA,EADiB,IAAjBD,EAC0BhB,GACpBkB,EAAAA,EAAAA,QAAOlB,EAAqBzI,EAA8BtQ,QAAS8Z,GACnE,GAEoBd,GACpBiB,EAAAA,EAAAA,QAAOjB,EAAsB1I,EAA8BtQ,QAAS8Z,EAAaC,GACjF,GAGV,MAAMG,EAAsF,QAAzEzB,EAAoD,QAApDC,EAAIx1B,KAAKsY,MAAM8U,8BAA8BtQ,eAAO,IAAA0Y,OAAA,EAAhDA,EAAkDyB,2BAAmB,IAAA1B,EAAAA,EAAI,GAC1F2B,EAAwBl3B,KAAKm3B,0BAA0BH,GAE7D,IAAI5b,EAAY,yBACZ8b,IACA9b,EAAYC,GAAAA,CAAWD,EAAW,sCAAsC4b,MAK5E,MAAMI,GAAYC,EAAAA,iBAAiBC,mBAAmBhb,EAAoBib,oBACpEC,GAAYH,EAAAA,iBAAiBC,mBAAmBhb,EAAoBmb,gBACpEC,EAAmBN,GAAYI,EAC/BpC,EAAU,GAAG3Z,SAA0CpX,IAA9BiY,EAAoB7K,MAAsB,KAAK6K,EAAoB7K,SAAW,KAM7G,OAJIkmB,EAAAA,EAAAA,IAAuBvK,IAAkC3R,IACzDA,EAAYA,EAAUjO,MAAM,KAAKpK,IAAI0Y,EAAAA,IAAoB8b,KAAK,MAI9Dvf,EAAAA,cAAA,MAAI+C,UAAWA,EAAWha,GAAI,GAAGgsB,EAA8BtQ,WAAYjS,KACvEwN,EAAAA,cAAA,IAAA0D,OAAAC,OAAA,CACI9Y,IAAKiqB,EAA8B,OAAS,QAC5CrN,IAAK9f,KAAKs1B,WACVzd,KAAM7X,KAAK63B,iBACXC,SAAUV,GAAY,EAAI,EAC1Blb,QAASlc,KAAKyY,SACd2C,UAAWob,EACXra,KAAM2X,EAAS,aACHgD,EAAuB,iBACnB3J,EAChB1N,MAAO2V,GACHjhB,EACA8hB,GAEHyB,GAAoBR,GAAyBl3B,KAAK+3B,cAAcf,GACjE3e,EAAAA,cAAA,QAAM+C,UAAU,gCAA+B,cAAa,QAExD/C,EAAAA,cAAA,QAAM+C,UAAU,uCACXK,QAE0BpX,IAA9BiY,EAAoB7K,OACjB4G,EAAAA,cAAA,QAAM+C,UAAU,wCAAwCkB,EAAoB7K,UAQ5F0lB,0BAA0BH,GAE9B,OAD8BgB,EAAAA,EAAAA,8BAA6BhB,EAAeh3B,KAAKsY,MAAMvW,SAIjFg2B,cAAcf,GAA6B,IAAAiB,EAC/C,MAAM3b,EAAsBtc,KAAKsY,MAAMgE,oBAGjCsB,EAAOtB,EAAoBX,+BAAiCW,EAAoB/Y,sBAAwB,GACxG20B,EAAc,CAChB,CACIlzB,OAAQ,GAAsC,QAAtCizB,EAAG3b,EAAoBhZ,uBAAe,IAAA20B,EAAAA,EAAI,MAAMjB,KAAiBpZ,IACzEza,MAAOya,EACPoZ,cAAAA,EACAmB,aAAc7b,EAAoBib,mBAClCvY,SAAU1C,EAAoBmb,iBAItC,OACIpf,EAAAA,cAAC+f,EAAAA,gBAAe,CACZhd,UAAU,iCACVvb,YAAaG,KAAKsY,MAAMvW,QAAQC,QAAQnC,YACxCw4B,KAAMH,EACNI,oBAAoB,EACpBC,cAAY,IAKhBV,iBACJ,MAAM,WAAE5b,EAAU,8BAAEmR,EAA6B,oBAAE9Q,EAAmB,4BAAE6Q,GAAgCntB,KAAKsY,MAE7G,OAAIgE,EACOL,EAAW,CACdmR,8BAAAA,EACA9Q,oBAAAA,EACAqT,aAAcxC,IAIf,GAoBHwJ,cACJra,EACA8Q,EACAQ,EACA7rB,EACA8I,EACA8O,EACA6e,EACAC,GAEA,GAAInc,EAAoB/Y,qBAAsB,KAAA8qB,EAAAqK,EAC1C14B,KAAKyZ,QAAQuB,cAAcC,MAAQqB,EAAoBX,8BACvD,MAAMxH,GAAYgH,EAAAA,EAAAA,wBAAuBxB,EAAmB3Z,KAAKyZ,SAC3Dkf,EAAgB3rB,OAAO4rB,SAAStc,EAAoB/Y,qBAAsB,IAC1Es1B,EAAgD,QAAnCxK,EAAGruB,KAAKsY,MAAMwgB,6BAAqB,IAAAzK,OAAA,EAAhCA,EAAkCvnB,MACpD3D,GAASA,EAAMiO,gBAAkBkL,EAAoBlL,gBAGnD2nB,EAAiB/rB,OAAO4rB,UAASC,MAAAA,OAAa,EAAbA,EAAet1B,uBAAwB,IAAK,IAC7Ey1B,EAAyB,EAC/B,IAAIC,EAA+B,sBAE/BA,EADAN,EAAgBI,EACO,GAAGE,QACnBN,EAAgBI,EACA,GAAGE,UAEH,GAAGA,aAE9B,MAAMC,OAC4B70B,IAA9BiY,EAAoB7K,OAAuB6K,EAAoB7K,QAAUunB,EACnEP,IAAkC1B,EAAAA,EAAAA,QAAO0B,EAAgCnc,EAAoB7K,OAC7F+mB,IAA4BzB,EAAAA,EAAAA,QAAOyB,EAA0Blc,EAAoB7K,OAC3F,OACI4G,EAAAA,cAAA,MACI+C,UAAU,wDACVe,KAAOnc,KAAKsY,MAAM6gB,kBAAgC90B,EAAjB,eACjCjD,GAAI,GAAGgsB,EAA8BtQ,WAAYjS,KAEjDwN,EAAAA,cAAA,IAAA0D,OAAAC,OAAA,CACInE,KAAM7X,KAAK63B,iBACX1b,KAAK,SAAQ,gBACEyR,EAAS,aACZ,GAAGR,EAA8BtQ,WAAYR,EAAoBX,0DAC3Eud,IACFhd,QAASlc,KAAKyY,UACVtE,GAEJkE,EAAAA,cAAC+gB,EAAAA,gBAAe,CACZhe,UAAW6d,EACXI,UAAWV,EACXW,YAA8D,QAAnDZ,EAAEpc,EAAoBX,qCAA6B,IAAA+c,EAAAA,EAAIpc,EAAoB/Y,qBACtFg2B,WAAW,EACXC,UAAQ,EACR7Z,UAAU,GACV5d,QAASA,EACTX,GAAIpB,KAAKsY,MAAM0N,SACfmC,SAAUnoB,KAAKsY,MAAMmhB,eACrB/W,KAAM,KAEVrK,EAAAA,cAAA,QAAM+C,UAAU,8BAA6B,cAAcpb,KAAKsY,MAAM6gB,aAAe,YAAS90B,QAC3DA,IAA9BiY,EAAoB7K,OAAuB,IAAI6K,EAAoB7K,oKCjRhG,MAAMioB,UAAsBrhB,EAAAA,UAGxBzY,YAAY0Y,GACRC,MAAMD,GAHO,KAAAqhB,SAAW,GAKxB35B,KAAK45B,cAAgB55B,KAAK45B,cAAchN,KAAK5sB,MAC7CA,KAAK65B,iBAAmB75B,KAAK65B,iBAAiBjN,KAAK5sB,MAEnD,MAAM85B,EAAa95B,KAAKsY,MAAMyhB,wBAM9B/5B,KAAKstB,MAAQ,CACT0M,SAAUF,EACVG,eAAgB3hB,EAAM4hB,wBAAwBhgB,OAAOpP,QAAU9K,KAAK25B,UAIrE9L,sBAAsBC,EAAgCC,GACzD,OAAI/tB,KAAKstB,QAAUS,GAAa/tB,KAAKsY,QAAUwV,EAM5CxT,SACH,MAAM,wBAAE4f,EAAuB,sBAAEtL,GAA0B5uB,KAAKsY,MAMhE,GAJK4hB,GACDtL,EAAsB5mB,UAAUD,MAAM,wDAGtCmyB,EAAwBzD,cAAgB9kB,EAAAA,qBAAqB+kB,QAAU12B,KAAKsY,MAAMvW,QAAQ8G,IAAIzE,OAAO+1B,WACrG,OAAO,KAGX,IAAIC,EAAUF,EAAwBpd,QAEe,IAAAud,GAAjD1C,EAAAA,EAAAA,IAAuBuC,KACvBE,EAAiB,QAAVC,EAAGD,SAAO,IAAAC,OAAA,EAAPA,EAASxe,QAAQ,YAAa,KAG5C,MAAMT,EAAYC,GAAAA,CACd,oBACA,aACA+e,GAGJ,OACI/hB,EAAAA,cAAA,OAAK+C,UAAWA,GACZ/C,EAAAA,cAAC+I,EAAAA,OAAM,CACHhG,UAAWpb,KAAKstB,MAAM0M,SAAW,iCAAmC,kCAAiC,aACzFI,EACZle,QAASlc,KAAK65B,iBAAgB,gBACf75B,KAAKstB,MAAM0M,UAEzBI,GAEL/hB,EAAAA,cAACiiB,EAAAA,SAAQ,CAACzZ,OAAQ7gB,KAAKstB,MAAM0M,SAAUO,QAAS,EAAGC,UAAWA,KAG1DtiB,OAAOuiB,cAAc,IAAIC,MAAM,aAE9B16B,KAAK26B,kBAAkBT,KAMhCS,kBAAkBT,GACtB,OAAInd,EAAAA,EAAAA,IAAYmd,EAAwB9oB,eAC7BpR,KAAK46B,aAAaV,GAEtBl6B,KAAK66B,yBAAyBX,GAGjCW,yBAAyBX,GAAiD,IAAAY,EAC9E,MAAM,WACFnM,EAAU,sBACVC,EAAqB,sBACrBkK,EAAqB,QACrB/2B,EAAO,sBACP2zB,EAAqB,4BACrBC,EAA2B,oBAC3BE,EAAmB,qBACnBC,EAAoB,SACpBiF,GACA/6B,KAAKsY,MAIH6D,EAFF+d,EAAwB7D,mBAAqBC,EAAAA,YAAYC,cACzD2D,EAAwBzD,cAAgB9kB,EAAAA,qBAAqB+kB,OACnC,CAAEva,KAAM,gBAAc9X,EAC9C22B,EAAoBd,EAAwBhgB,QAAU,GAC5D8gB,EAAkBzjB,MACd,CAAC0jB,EAAGC,KAAOD,EAAEtf,+BAAiCsf,EAAE13B,sBAAwB,IAAI43B,cAAcD,EAAEvf,+BAAiCuf,EAAE33B,sBAAwB,GAAIxB,EAAQC,QAAQS,UAE/K,MAAM24B,EAAYJ,EAAkB53B,KAAI,CAACi4B,EAA4BxwB,KACjE,IAAKwwB,EAID,OAHAzM,EAAsB5mB,UAAUD,MAC5B,6DAA6DmyB,EAAwB/zB,aAAa+zB,EAAwBpd,YAEvH,KAEX,GAAIjS,EAAS7K,KAAK25B,SAAW,IAAO35B,KAAKstB,MAAM2M,eAC3C,OAAO,KAEX,MAAM9M,GAA8BmO,EAAAA,EAAAA,IAAgCD,EAAOvC,GAE3E,OACIzgB,EAAAA,cAACgd,EAAAA,EAAU,CACPjI,8BAA+B8M,EAC/B5d,oBAAqB+e,EACrBlO,4BAA6BA,EAC7B2L,sBAAuBA,EAAsBvtB,QAAOgwB,GAChDP,EAAkBl0B,MAAK3D,GAASA,EAAMG,kBAAoBi4B,EAAcj4B,oBAE5EsrB,sBAAuBA,EACvBY,SAAUxvB,KAAK45B,cACf3d,WAAYjc,KAAKsY,MAAM2D,WACvB0S,WAAYA,EACZzrB,IAAK2H,EACLA,MAAOA,EACP9I,QAASA,EACTikB,SAAUhmB,KAAKsY,MAAM0N,SACrByT,eAAgBz5B,KAAKsY,MAAMmhB,eAC3B9f,iBAAkB3Z,KAAKsY,MAAMqB,iBAC7B+b,sBAAuBA,EACvBG,oBAAqBA,EACrBC,qBAAsBA,EACtBH,4BAA6BA,EAC7BwD,aAAc4B,EACdhF,QAAS/1B,KAAKsY,MAAMyd,QACpBC,OAAQh2B,KAAKsY,MAAM0d,OACnBhgB,uBAAwBhW,KAAKsY,MAAMtC,4BAKzCokB,GAAUzC,EAAAA,EAAAA,IAAuBuC,GACF,QAD0BY,EACzDZ,EAAwBpd,eAAO,IAAAge,OAAA,EAA/BA,EAAiCjf,QAAQ,YAAa,IACtDqe,EAAwBpd,QAE9B,OACIzE,EAAAA,cAAA,KAAA0D,OAAAC,OAAA,CACIZ,UAAW,2BAA2Bgf,KAClCje,EAAI,cACIie,IAEXgB,EACAJ,EAAkBlwB,OAAS9K,KAAK25B,UAAYthB,EAAAA,cAAA,UAAQ+C,UAAW,sBAAqBpb,KAAKstB,MAAM2M,eAAiB,OAAO,QAAU/d,QAASA,IAAKlc,KAAK0uB,SAAS,CAACuL,gBAAgBj6B,KAAKstB,MAAM2M,kBAAmBj6B,KAAKstB,MAAM2M,eAAiB,YAAc,YAAYe,EAAkBlwB,OAAS9K,KAAK25B,cAKvS6B,cAActB,GAClB,OACIA,EAAwBuB,uBAAyBC,EAAAA,gBAAgBC,OACjEzB,EAAwBuB,uBAAyBC,EAAAA,gBAAgBtI,QACjE8G,EAAwBuB,uBAAyBC,EAAAA,gBAAgBE,eAE1D,SAEJ,QAGHhB,aAAaV,GAAiD,IAAA2B,EAClE,MAAM,WACFlN,EAAU,sBACVC,EAAqB,sBACrBkK,EAAqB,QACrB/2B,EAAO,6BACPivB,EAA4B,6BAC5BG,GACAnxB,KAAKsY,MAGH8iB,GADoBlB,EAAwBhgB,QAAU,IACxB9W,KAAI,CAACi4B,EAA4BxwB,KACjE,IAAKwwB,EAID,OAHAzM,EAAsB5mB,UAAUD,MAC5B,4CAA4CmyB,EAAwB/zB,aAAa+zB,EAAwBpd,YAEtG,KAGX,MAAMqQ,GAA8BmO,EAAAA,EAAAA,IAAgCD,EAAOvC,GAErE3K,EAAYnuB,KAAKw7B,cAActB,GAC/Bh3B,EAAMiqB,EACN,GAAGA,EAA4B5pB,wBAAwB4pB,EAA4B3pB,wBACnF,gBAAgBqH,IACtB,OACIwN,EAAAA,cAAA,MAAI+C,UAAW,sEAAoClY,IAAK2H,GACpDwN,EAAAA,cAAC2X,EAAAA,EAAe,CACZ5C,8BAA+B8M,EAC/B5d,oBAAqB+e,EACrBlO,4BAA6BA,EAC7ByB,sBAAuBA,EACvBY,SAAUxvB,KAAK45B,cACf3d,WAAYjc,KAAKsY,MAAM2D,WACvB0S,WAAYA,EACZR,UAAWA,EACXjrB,IAAKA,EACLytB,UAAWztB,EACXnB,QAASA,EACTivB,6BAA8BA,EAC9BG,6BAA8BA,EAC9BnL,SAAUhmB,KAAKsY,MAAM0N,SACrByT,eAAgBz5B,KAAKsY,MAAMmhB,qBAMrCW,GAAUzC,EAAAA,EAAAA,IAAuBuC,GACF,QAD0B2B,EACzD3B,EAAwBpd,eAAO,IAAA+e,OAAA,EAA/BA,EAAiChgB,QAAQ,YAAa,IACtDqe,EAAwBpd,QAE9B,OAAOzE,EAAAA,cAAA,MAAI+C,UAAW,yCAAyCgf,KAAYgB,GAGvExB,cAAckC,GAClB97B,KAAKsY,MAAMyjB,iBAAiBD,GAGxBjC,mBACJ75B,KAAK0uB,UAASsN,IAAa,CACvBhC,UAAWgC,EAAUhC,cAKjC,yGCtRYiC,EAmDAC,EA8BAvqB,6lBA2EN,SAAUoL,EAAYof,GACxB,OAAOA,IAAkB9qB,EAAAA,kBAAkBuC,UAAYuoB,IAAkB9qB,EAAAA,kBAAkB+qB,QAmBzF,SAAU5gB,EAAU2gB,GACtB,OACIA,IAAkB9qB,EAAAA,kBAAkBC,UAOtC,SAAU+b,EACZF,EACAC,GAEA,YAC+C/oB,KAA3C8oB,MAAAA,OAA2B,EAA3BA,EAA6B3b,YACc,QAA3C2b,MAAAA,OAA2B,EAA3BA,EAA6B3b,aAC7B2b,MAAAA,OAA2B,EAA3BA,EAA6B/b,iBAAkBC,EAAAA,kBAAkBoD,SACjE2Y,EAA8BqO,uBAAyBC,EAAAA,gBAAgBC,MA2BzE,SAAUL,EACZhf,EACA+f,GAGA,OAAOA,EAAmBv1B,MAAMw1B,GAC5BniB,EAA8BmC,EAAqBggB,KAUrD,SAAUniB,EACZmC,EACAggB,EACAtiB,GAIA,OACIsiB,EAAoBh5B,kBAAoBgZ,EAAoBhZ,iBAC5Dg5B,EAAoB5qB,qBAAuB4K,EAAoB5K,oBAC/D4qB,EAAoBlrB,gBAAkBkL,EAAoBlL,kBACxD4I,MAAAA,OAAM,EAANA,EAAQyhB,wBAAyBC,EAAAA,gBAAgBC,MAC7C5e,EAAYuf,EAAoBlrB,gBApFR+qB,EAqFFG,EAAoBlrB,iBAnF9BC,EAAAA,kBAAkBuC,UACpCuoB,IAAkB9qB,EAAAA,kBAAkB+qB,SACpCD,IAAkB9qB,EAAAA,kBAAkBoD,UAkFhC6nB,EAAoB/4B,uBAAyB+Y,EAAoB/Y,sBAtFvE,IAAgC44B,EA2HhC,SAAUI,EACZT,EACAU,GAEA,MAAMC,EAAmD,GACzD,IAAIC,GAAmB,EAuCvB,GAnCIZ,EAAuB1O,8BAA8Bhc,gBAAkBC,EAAAA,kBAAkBoD,SACzFqnB,EAAuB1O,8BAA8BqO,uBAAyBC,EAAAA,gBAAgBC,QAE9Fa,EAA4BA,EAA0BjxB,QAAOoxB,GAClDA,EAAEr5B,kBAAoBw4B,EAAuBxf,oBAAoBhZ,mBAIhFk5B,EAA0BxuB,SAAS4uB,IAC/B,GACIziB,EACI2hB,EAAuBxf,oBACvBsgB,EACAd,EAAuB1O,gCAI3B,GADAsP,GAAmB,EACfZ,EAAuBnM,YAAa,CACpC,MAAMkN,EAAIh6B,EAAAA,EAAA,GACH+5B,GAAiB,IACpBr5B,0BAC2Cc,IAAtCy3B,EAAuB3H,YAA4B,GAAG2H,EAAuB3H,cAC9EyI,EAAkBr5B,qBACtBC,2BACyCa,IAApCy3B,EAAuB1H,UAA0B,GAAG0H,EAAuB1H,YAC5EwI,EAAkBp5B,wBAE1Bi5B,EAA0B7wB,KAAKixB,SAInCJ,EAA0B7wB,KAAKgxB,OAIlCF,EAAkB,CACnB,MAAMG,EAAIh6B,EAAAA,EAAA,GACHi5B,EAAuBxf,qBAAmB,IAC7C/Y,0BAC2Cc,IAAtCy3B,EAAuB3H,YAA4B,GAAG2H,EAAuB3H,cAC9E2H,EAAuBxf,oBAAoB/Y,qBAC/CC,2BACyCa,IAApCy3B,EAAuB1H,UAA0B,GAAG0H,EAAuB1H,YAC5E0H,EAAuBxf,oBAAoB9Y,wBAEnDi5B,EAA0B7wB,KAAKixB,GAI1Bf,EAAuBxf,oBAAoBlL,gBAAkBC,EAAAA,kBAAkByrB,MAC5EhB,EAAuBxf,oBAAoBlL,gBAAkBC,EAAAA,kBAAkBC,WACnFwqB,EAAuB1O,8BAA8BiJ,mBAAqBC,EAAAA,YAAYC,cAEtFuF,EAAuB1O,8BAA8BlT,OAAOlM,SAASqtB,IACjE,GAAIA,EAAM/3B,kBAAoBu5B,EAAKv5B,iBAAmB+3B,EAAM93B,uBAAyBs5B,EAAKt5B,0BAEnF,CACH,MAAMw5B,EAAgBN,EAA0BO,WAAWC,GACvD9iB,EAA8BkhB,EAAO4B,EAAWnB,EAAuB1O,iCAEvE2P,GAAiB,GACjBN,EAA0BrV,OAAO2V,EAAe,OAOpE,OAAON,GA5WX,SAAYR,GASRA,EAAAA,EAAA,iBAWAA,EAAAA,EAAA,2BAUAA,EAAAA,EAAA,eAUAA,EAAAA,EAAA,qBAxCJ,CAAYA,IAAAA,EAAgC,KAmD5C,SAAYC,GASRA,EAAAA,EAAA,mBAUAA,EAAAA,EAAA,iBAnBJ,CAAYA,IAAAA,EAAuB,KA8BnC,SAAYvqB,GASRA,EAAAA,EAAA,eAUAA,EAAAA,EAAA,yBAUAA,EAAAA,EAAA,uBAUAA,EAAAA,EAAA,iBAUAA,EAAAA,EAAA,mBAjDJ,CAAYA,IAAAA,EAAoB,mEC5FzB/Q,eAAewrB,EAClBrqB,EACA+Q,EACA5M,EACAg3B,GAEA,IAAKh3B,IAAYA,EAAQiD,gBACrB,MAAO,CAAEg0B,SAAS,GAGtB,MAAMC,GAAYC,EAAAA,EAAAA,IAAet7B,EAAS+Q,EAAU5M,EAAQiD,iBAE5D,MAAO,CACHg0B,QAASC,EACTE,QAASF,OAAY/4B,EAAY64B,yDCjBlC,MAAMK,EAAYA,CAACC,EAAyBC,KAC/C,MAAMC,EAAeF,EAAQlrB,IAAImrB,GAEjC,OAAIC,GAAgBA,EAAav6B,OAASu6B,EAAav6B,MAAM2H,OAAS,EAC3D4yB,EAAav6B,WAEpB,GAIKw6B,EAAYA,CAACH,EAAyBr6B,EAAes6B,EAAoBG,KAC9Ez6B,GACAq6B,EAAQ9lB,IAAI+lB,EAAYt6B,EAAO,CAAE06B,KAAM,IAAKC,OAAQF","sources":["webpack://Msdyn365.Commerce.Online/./src/actions/get-organization-customer.ts?79c2","webpack://Msdyn365.Commerce.Online/./src/actions/get-product-unit-of-measure-options.action.ts?bc1e","webpack://Msdyn365.Commerce.Online/./src/modules/dlvry-search-result-container/actions/base-collection-action.ts?11e2","webpack://Msdyn365.Commerce.Online/./src/modules/dlvry-search-result-container/actions/get-cached-price-for-product-search-results.ts?029f","webpack://Msdyn365.Commerce.Online/./src/modules/dlvry-search-result-container/actions/get-full-products-by-collection.ts?8637","webpack://Msdyn365.Commerce.Online/./src/modules/dlvry-search-result-container/actions/get-mapped-search-configuration.ts?6b32","webpack://Msdyn365.Commerce.Online/./src/modules/dlvry-search-result-container/actions/get-product-refiner-hierarchy.ts?67ba","webpack://Msdyn365.Commerce.Online/./src/modules/dlvry-search-result-container/actions/get-refiners-for-collection.ts?5d9b","webpack://Msdyn365.Commerce.Online/./src/modules/dlvry-search-result-container/actions/get-inventory-refiners.ts?275a","webpack://Msdyn365.Commerce.Online/./src/modules/dlvry-search-result-container/actions/refiner-utils.ts?04ba","webpack://Msdyn365.Commerce.Online/./src/modules/dlvry-search-result-container/actions/url-utils.ts?6503","webpack://Msdyn365.Commerce.Online/./src/modules/dlvry-search-result-container/components/choice-summary.tsx?f410","webpack://Msdyn365.Commerce.Online/./src/modules/dlvry-search-result-container/components/error-message.tsx?3c52","webpack://Msdyn365.Commerce.Online/./src/modules/dlvry-search-result-container/components/feature-search-result-item.tsx?eefa","webpack://Msdyn365.Commerce.Online/./src/modules/dlvry-search-result-container/components/link.tsx?b255","webpack://Msdyn365.Commerce.Online/./src/modules/dlvry-search-result-container/components/modal.tsx?c4c9","webpack://Msdyn365.Commerce.Online/./src/modules/dlvry-search-result-container/components/product-search-result-items.tsx?573e","webpack://Msdyn365.Commerce.Online/./src/modules/dlvry-search-result-container/components/separator.tsx?f88a","webpack://Msdyn365.Commerce.Online/./src/modules/dlvry-search-result-container/components/title.tsx?e5ce","webpack://Msdyn365.Commerce.Online/./src/modules/dlvry-search-result-container/components/range-refine-item-input.tsx?6940","webpack://Msdyn365.Commerce.Online/./src/modules/dlvry-search-result-container/components/range-refine-item.tsx?1286","webpack://Msdyn365.Commerce.Online/./src/modules/dlvry-search-result-container/components/refine-item.tsx?7edb","webpack://Msdyn365.Commerce.Online/./src/modules/dlvry-search-result-container/components/refine-submenu.tsx?776f","webpack://Msdyn365.Commerce.Online/./src/modules/dlvry-search-result-container/components/utilities.ts?c7b3","webpack://Msdyn365.Commerce.Online/./src/shared-utils/attributes/on-buy-access-validator.ts?4b31","webpack://Msdyn365.Commerce.Online/./src/shared-utils/cookie-utilities.ts?6237"],"sourcesContent":["import { createObservableDataAction, IActionContext, IAction, ICreateActionContext, IGeneric, IAny, ICommerceApiSettings } from '@msdyn365-commerce/core';\r\nimport { CacheType, callActionOrExecute, Customer, DataServiceQuery, IActionInput, IDataServiceRequest } from \"@msdyn365-commerce/retail-proxy\";\r\nimport * as Entities from '@msdyn365-commerce/retail-proxy/dist/Entities/CommerceModels.g';\r\n\r\nexport class GetOrganizationCustomerInput implements IActionInput {\r\n private readonly user: string | undefined;\r\n private readonly query: DataServiceQuery;\r\n\r\n constructor(apiSettings: ICommerceApiSettings, user: string) {\r\n this.user = user;\r\n\r\n this.query = new DataServiceQuery();\r\n }\r\n\r\n public getDataServiceRequest = (): IDataServiceRequest => {\r\n return this.query.createDataServiceRequestForOperation(\r\n 'GetOrganizationCustomer',\r\n false,\r\n Entities.CustomerClass,\r\n 'false',\r\n {\r\n bypassCache: 'get',\r\n returnEntity: 'Entities.CustomerClass'\r\n },\r\n {}\r\n );\r\n };\r\n\r\n public shouldCacheOutput = (): boolean => false;\r\n\r\n public getCacheKey = () => `OrganizationCustomer-${this.user}`;\r\n public getCacheObjectType = () => 'OrganizationCustomer';\r\n public dataCacheType = (): CacheType => 'request';\r\n}\r\n\r\nconst createInput = (inputData: ICreateActionContext>): GetOrganizationCustomerInput => {\r\n const { user } = inputData.requestContext;\r\n return new GetOrganizationCustomerInput(inputData.requestContext.apiSettings, user.customerAccountNumber ?? \"\");\r\n};\r\n\r\nexport const getOrganizationCustomerAction = async (input: GetOrganizationCustomerInput, ctx: IActionContext): Promise => {\r\n if (!ctx.requestContext.user.isAuthenticated) {\r\n return {};\r\n }\r\n var customer = await callActionOrExecute(input.getDataServiceRequest(), ctx);\r\n return customer;\r\n};\r\n\r\nexport const getOrganizationCustomer = createObservableDataAction({\r\n id: 'src/actions/get-organization-customer',\r\n action: >getOrganizationCustomerAction,\r\n input: createInput\r\n});\r\n\r\nexport default getOrganizationCustomer;\r\n","import { callActionOrExecute, DataServiceQuery, IContext, IDataServiceRequest, IQueryResultSettings } from \"@msdyn365-commerce/retail-proxy\";\r\nimport * as Entities from '@msdyn365-commerce/retail-proxy/dist/Entities/CommerceModels.g';\r\nimport * as Types from '@msdyn365-commerce/retail-proxy/dist/Entities/CommerceTypes.g';\r\n\r\nfunction getProductUnitOfMeasureOptionsQuery(): DataServiceQuery {\r\n return new DataServiceQuery();\r\n}\r\n\r\n\r\nexport function getProductUnitOfMeasureOptionsInput(\r\n queryResultSettings: IQueryResultSettings, productIds:\r\n number[]\r\n): IDataServiceRequest {\r\n const query = getProductUnitOfMeasureOptionsQuery().resultSettings(queryResultSettings);\r\n query.top(10000);\r\n return query.createDataServiceRequestForOperation(\r\n 'GetProductUnitOfMeasureOptions',\r\n true, Entities.UnitOfMeasureConversionClass,\r\n 'true',\r\n { bypassCache: 'none', returnEntity: 'Entities.UnitOfMeasureConversion' },\r\n {\r\n productIds: productIds\r\n }\r\n );\r\n}\r\n\r\nexport async function getProductUnitOfMeasureOptionsAsync(context: IContext, productIds: number[]): Promise {\r\n const request = getProductUnitOfMeasureOptionsInput(\r\n context.queryResultSettings || {}, productIds);\r\n const conversions = await callActionOrExecute(request, context.callerContext);\r\n return conversions;\r\n}","/*!\r\n * Copyright (c) Microsoft Corporation.\r\n * All rights reserved. See LICENSE in the project root for license information.\r\n */\r\n\r\n/* eslint-disable no-duplicate-imports */\r\nimport { CacheType, getCatalogId, IActionInput, IAny, ICommerceApiSettings, ICreateActionContext, IGeneric } from '@msdyn365-commerce/core';\r\nimport { IProductRefinerHierarchy } from '@msdyn365-commerce/commerce-entities';\r\nimport {\r\n convertToString,\r\n ChannelInventoryConfiguration,\r\n IQueryResultSettings,\r\n ProductRefinerValue,\r\n SortColumn\r\n} from '@msdyn365-commerce/retail-proxy';\r\nimport { generateCacheKey, QueryResultSettingsProxy } from '@msdyn365-commerce-modules/retail-actions';\r\nimport { toJS } from 'mobx';\r\n\r\nimport { hydrateRefinersFromUrl } from './url-utils';\r\n\r\n/**\r\n * Export listPageType.\r\n */\r\nexport type listPageType = 'Category' | 'Search' | 'Unknown';\r\n\r\n/**\r\n * Get include attributes from config.\r\n * @param inputData - ICreateActionContext.\r\n * @returns Boolean.\r\n */\r\nfunction getIncludeAttributes(inputData: ICreateActionContext, IGeneric>): boolean {\r\n if (inputData && inputData.config && inputData.config.includeAttributes !== undefined && inputData.config.includeAttributes === true) {\r\n return true;\r\n }\r\n return false;\r\n}\r\n\r\n/**\r\n * Get updateRefinerPanel from config.\r\n * @param inputData - ICreateActionContext.\r\n * @returns Boolean.\r\n */\r\nfunction getUpdateRefinerPanel(inputData: ICreateActionContext, IGeneric>): boolean {\r\n return !!inputData.config?.updateRefinerPanel;\r\n}\r\n\r\n/**\r\n * BaseCollection Action Input.\r\n */\r\nexport class BaseCollectionInput implements IActionInput {\r\n public pageType: listPageType;\r\n\r\n public category: number | undefined;\r\n\r\n public searchText: string | undefined;\r\n\r\n public refiners: ProductRefinerValue[];\r\n\r\n public queryResultSettings: IQueryResultSettings;\r\n\r\n public apiSettings: ICommerceApiSettings;\r\n\r\n public includeAttributes: boolean | undefined;\r\n\r\n public locale?: string;\r\n\r\n public isUpdateRefinerPanel?: boolean;\r\n\r\n public catalogId?: number;\r\n\r\n public channelInventoryConfiguration?: ChannelInventoryConfiguration;\r\n\r\n public inventoryRefiner?: IProductRefinerHierarchy;\r\n\r\n public constructor(\r\n pageType: listPageType,\r\n apiSettings: ICommerceApiSettings,\r\n queryResultSettings: IQueryResultSettings,\r\n refiners: ProductRefinerValue[],\r\n category: number | undefined,\r\n searchText: string | undefined,\r\n includeAttributes: boolean | undefined,\r\n isUpdateRefinerPanel?: boolean | undefined,\r\n locale?: string,\r\n catalogId?: number,\r\n channelInventoryConfiguration?: ChannelInventoryConfiguration,\r\n inventoryRefiner?: IProductRefinerHierarchy\r\n ) {\r\n this.pageType = pageType;\r\n this.apiSettings = apiSettings;\r\n this.category = category;\r\n this.searchText = searchText;\r\n this.queryResultSettings = queryResultSettings;\r\n this.refiners = refiners;\r\n this.includeAttributes = includeAttributes;\r\n this.isUpdateRefinerPanel = isUpdateRefinerPanel;\r\n this.locale = locale;\r\n this.catalogId = catalogId ?? 0;\r\n this.channelInventoryConfiguration = channelInventoryConfiguration;\r\n this.inventoryRefiner = inventoryRefiner;\r\n }\r\n\r\n public getCacheKey = () => {\r\n const queryResultSettings = {\r\n ...this.queryResultSettings.Paging,\r\n ...toJS(this.queryResultSettings.Sorting)\r\n };\r\n\r\n const cacheKey = generateCacheKey(\r\n this.apiSettings,\r\n { key: 'PageType', value: this.pageType },\r\n { key: 'Category', value: this.category },\r\n { key: 'SearchText', value: this.searchText },\r\n { key: 'CatalogId', value: this.catalogId },\r\n {\r\n key: 'Refiners',\r\n value: this.refiners.map(\r\n refiner =>\r\n `RefinerRecordId:${refiner.RefinerRecordId}-LeftValueBoundString:${refiner.LeftValueBoundString ||\r\n ''}-RightValueBoundString:${refiner.RightValueBoundString || ''}`\r\n )\r\n },\r\n { key: 'QueryResultSettings', value: convertToString(queryResultSettings) },\r\n { key: 'Locale', value: this.locale }\r\n );\r\n return cacheKey;\r\n };\r\n\r\n public getCacheObjectType = () => 'CollectionActionResult';\r\n\r\n public dataCacheType = (): CacheType => 'request';\r\n}\r\n\r\n// TODO: Create a data model here or import one to capture the response of the action\r\nexport interface IGetFullProductsByCollectionData {\r\n text: string;\r\n}\r\n\r\nexport type CollectionClassConstructor = new (\r\n pageType: listPageType,\r\n apiSettings: ICommerceApiSettings,\r\n queryResultSettings: IQueryResultSettings,\r\n refiners: ProductRefinerValue[],\r\n category: number | undefined,\r\n searchText: string | undefined,\r\n includeAttributes: boolean | undefined,\r\n isUpdateRefinerPanel?: boolean | undefined,\r\n locale?: string,\r\n catalogId?: number,\r\n channelInventoryConfiguration?: ChannelInventoryConfiguration,\r\n inventoryRefiner?: IProductRefinerHierarchy\r\n) => BaseCollectionInput;\r\n\r\n/**\r\n * TODO: Use this function to create the input required to make the action call.\r\n * @param args\r\n * @param inputClassConstuctor\r\n */\r\nexport const createBaseCollectionInput = (\r\n args: ICreateActionContext,\r\n inputClassConstuctor: CollectionClassConstructor\r\n): BaseCollectionInput => {\r\n const pageType =\r\n args.requestContext.urlTokens.pageType === 'Category' || (args.requestContext.query && args.requestContext.query.categoryId)\r\n ? 'Category'\r\n : 'Search';\r\n\r\n const queryResultSettings = QueryResultSettingsProxy.fromInputData(args).QueryResultSettings;\r\n const queryRefiners = hydrateRefinersFromUrl(args.requestContext);\r\n const includeAttributes = getIncludeAttributes(args);\r\n const isUpdateRefinerPanel = getUpdateRefinerPanel(args);\r\n const catalogId = getCatalogId(args.requestContext);\r\n\r\n if (args.requestContext.query && args.requestContext.query.sorting) {\r\n queryResultSettings.Sorting = { Columns: JSON.parse(decodeURIComponent(args.requestContext.query.sorting)) };\r\n }\r\n\r\n if (pageType === 'Category') {\r\n return new inputClassConstuctor(\r\n pageType,\r\n args.requestContext.apiSettings,\r\n queryResultSettings,\r\n queryRefiners,\r\n +(args.requestContext.urlTokens.itemId || (args.requestContext.query && args.requestContext.query.categoryId) || 0),\r\n args.requestContext.query?.q,\r\n includeAttributes,\r\n isUpdateRefinerPanel,\r\n args.requestContext.locale,\r\n catalogId\r\n );\r\n } else if (pageType === 'Search' && args.requestContext.query && args.requestContext.query.q && !args.requestContext.query.recommendation) {\r\n return new inputClassConstuctor(\r\n pageType,\r\n args.requestContext.apiSettings,\r\n queryResultSettings,\r\n queryRefiners,\r\n undefined,\r\n args.requestContext.query.q,\r\n includeAttributes,\r\n isUpdateRefinerPanel,\r\n args.requestContext.locale,\r\n catalogId\r\n );\r\n } else if (pageType === 'Search' && args.requestContext.query && args.requestContext.query.recommendation) {\r\n let searchText = '';\r\n if (args.requestContext.query.productId) {\r\n searchText = JSON.stringify({\r\n ProductId: args.requestContext.query.productId,\r\n Recommendation: args.requestContext.query.recommendation,\r\n SearchText: args.requestContext.query.q\r\n });\r\n } else {\r\n searchText = JSON.stringify({ Recommendation: args.requestContext.query.recommendation, SearchText: args.requestContext.query.q });\r\n }\r\n return new inputClassConstuctor(\r\n pageType,\r\n args.requestContext.apiSettings,\r\n queryResultSettings,\r\n queryRefiners,\r\n undefined,\r\n searchText,\r\n includeAttributes,\r\n isUpdateRefinerPanel,\r\n args.requestContext.locale,\r\n catalogId\r\n );\r\n } else if (pageType === 'Search' && args.requestContext.query && args.requestContext.query.discountIds) {\r\n const searchText = JSON.stringify({ DiscountIds: args.requestContext.query.discountIds });\r\n return new inputClassConstuctor(\r\n pageType,\r\n args.requestContext.apiSettings,\r\n queryResultSettings,\r\n queryRefiners,\r\n undefined,\r\n searchText,\r\n includeAttributes,\r\n isUpdateRefinerPanel,\r\n args.requestContext.locale,\r\n catalogId\r\n );\r\n }\r\n\r\n throw new Error('[getFullProductsForCollection]Unable to create input');\r\n};\r\n","/*!\r\n * Copyright (c) Microsoft Corporation.\r\n * All rights reserved. See LICENSE in the project root for license information.\r\n */\r\n\r\nimport { CacheType, createObservableDataAction, getCatalogId, IAction, IActionContext, IActionInput } from '@msdyn365-commerce/core';\r\nimport { ProductSearchResult, ProjectionDomain } from '@msdyn365-commerce/retail-proxy';\r\nimport { ArrayExtensions, QueryResultSettingsProxy } from '@msdyn365-commerce-modules/retail-actions';\r\nimport { ProductSearchResultExt } from '../components';\r\nimport { getActivePricesAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/ProductsDataActions.g';\r\nimport { getDiscountBadge } from '../../../shared-utils/badge-utils';\r\n\r\n/**\r\n * Input class for the GetCachedPriceForProductSearchResult Data Action.\r\n */\r\nexport class CachedPriceForProductSearchResultInput implements IActionInput {\r\n public products: ProductSearchResultExt[];\r\n\r\n public constructor(products: ProductSearchResult[] | ProductSearchResultExt[]) {\r\n this.products = products;\r\n }\r\n\r\n /**\r\n * Get the cache key.\r\n * @returns The cache key.\r\n */\r\n public getCacheKey = (): string => `CachedPriceForProductSearchResult-${JSON.stringify(this.products)}`;\r\n\r\n /**\r\n * Get the cache object type.\r\n * @returns The cache object type.\r\n */\r\n public getCacheObjectType = (): string => 'ProductSearchResult';\r\n\r\n /**\r\n * Define the data cache type.\r\n * @returns The cache type.\r\n */\r\n public dataCacheType = (): CacheType => 'none';\r\n}\r\n\r\n/**\r\n * The createInput method for the GetCachedPriceForProductSearchResultDataAction.\r\n * @param products -- The product search result.\r\n * @returns The input.\r\n */\r\nexport const createCachedActivePriceForProductSearchResultInput = (products: ProductSearchResult[] | ProductSearchResultExt[]): CachedPriceForProductSearchResultInput => {\r\n return new CachedPriceForProductSearchResultInput(products);\r\n};\r\n\r\n/**\r\n * The Action Method for the GetCachedPriceForProductSearchResult Data Action\r\n * Gets the active price for product search result via the getActivePrice RetailServer API.\r\n * @param input -- The data input.\r\n * @param context -- The action context.\r\n * @returns The product search result updated with price.\r\n */\r\nexport async function getCachedPriceForProductSearchResultAction(\r\n input: CachedPriceForProductSearchResultInput,\r\n context: IActionContext\r\n): Promise {\r\n let productRecIds: number[];\r\n if (ArrayExtensions.hasElements(input.products)) {\r\n productRecIds = input.products.map(product => product.RecordId);\r\n } else {\r\n return Promise.resolve([]);\r\n }\r\n\r\n const catalogId = getCatalogId(context.requestContext);\r\n\r\n const projectDomain: ProjectionDomain = { ChannelId: +context.requestContext.apiSettings.channelId, CatalogId: catalogId };\r\n const priceZero = 0;\r\n\r\n try {\r\n const productPrices = await getActivePricesAsync({ callerContext: context, queryResultSettings: QueryResultSettingsProxy.getPagingFromInputDataOrDefaultValue(context) },\r\n projectDomain,\r\n productRecIds,\r\n new Date(),\r\n null,\r\n null,\r\n true,\r\n false,\r\n false);\r\n\r\n const productResults = input.products.map(product => {\r\n const activePrice = productPrices.find(price => price.ProductId === product.RecordId);\r\n if (activePrice) {\r\n product.Badge = getDiscountBadge(activePrice);\r\n product.Price = activePrice.CustomerContextualPrice ?? product.Price;\r\n product.BasePrice = Math.max(\r\n activePrice.BasePrice ?? priceZero,\r\n activePrice.TradeAgreementPrice ?? priceZero,\r\n activePrice.AdjustedPrice ?? priceZero\r\n );\r\n product.ProductPrice = activePrice;\r\n product.PrefetchedPrice = true;\r\n }\r\n return product;\r\n });\r\n\r\n return Promise.resolve(productResults);\r\n } catch (error) {\r\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument -- existing error type.\r\n context.telemetry.exception(error);\r\n context.telemetry.debug('[getCachedPriceForProductSearchResultAction]Error executing action');\r\n throw new Error('[getCachedPriceForProductSearchResultAction]Error executing action');\r\n }\r\n}\r\n\r\n/**\r\n * The getPriceForProductSearchResult data action.\r\n */\r\nexport const getCachedPriceForProductSearchResultDataAction = createObservableDataAction({\r\n id: '@msdyn365-commerce-modules/retail-actions/get-cached-price-for-product-search-result',\r\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- existing pattern.\r\n action: >getCachedPriceForProductSearchResultAction,\r\n input: createCachedActivePriceForProductSearchResultInput\r\n});\r\n\r\nexport default getCachedPriceForProductSearchResultDataAction;\r\n","/*!\r\n * Copyright (c) Microsoft Corporation.\r\n * All rights reserved. See LICENSE in the project root for license information.\r\n */\r\n\r\n/* eslint-disable no-duplicate-imports */\r\nimport {\r\n CacheType,\r\n createObservableDataAction,\r\n GetCustomerInput,\r\n IAction,\r\n IActionContext,\r\n IActionInput,\r\n ICreateActionContext\r\n} from '@msdyn365-commerce/core';\r\nimport { AsyncResult, ChannelInventoryConfiguration, ProductSearchCriteria, ProductSearchResult } from '@msdyn365-commerce/retail-proxy';\r\nimport { getProductPromotionsAsync, searchByCriteriaAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/ProductsDataActions.g';\r\nimport { getInventoryConfigurationAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/StoreOperationsDataActions.g';\r\nimport {\r\n ArrayExtensions,\r\n generateProductImageUrl,\r\n getCustomer,\r\n InventoryLevels\r\n} from '@msdyn365-commerce-modules/retail-actions';\r\n\r\nimport { BaseCollectionInput, createBaseCollectionInput } from './base-collection-action';\r\nimport { getInventorySortableRefinerValue } from '.';\r\nimport { addAlcoholRefiner as addAlcoholRefinerAsync, addAllAttributeRefiners, addOrUpdateZeroPriceRefiner, shouldFilterAlcohol } from './refiner-utils';\r\nimport getCachedPriceForProductSearchResultDataAction, { CachedPriceForProductSearchResultInput } from './get-cached-price-for-product-search-results';\r\nimport { ProductSearchResultExt } from '../components';\r\n\r\n/**\r\n * GetFullProductsByCollection Action Input.\r\n */\r\nexport class GetFullProductsByCollectionInput extends BaseCollectionInput implements IActionInput {\r\n /**\r\n * The cache object type.\r\n * @returns The cache object type.\r\n */\r\n public getCacheObjectType = (): string => 'FullProductSearchResult';\r\n\r\n /**\r\n * The data cache type.\r\n * @returns The data cache type.\r\n */\r\n public dataCacheType = (): CacheType => {\r\n return 'none';\r\n /* if (\r\n this.pageType !== 'Category' ||\r\n (this.refiners && this.refiners.length > 0) ||\r\n (this.queryResultSettings &&\r\n this.queryResultSettings.Sorting &&\r\n this.queryResultSettings.Sorting.Columns &&\r\n this.queryResultSettings.Sorting.Columns.length > 0)\r\n ) {\r\n return 'request';\r\n }\r\n return 'application'; */\r\n };\r\n}\r\n\r\n/**\r\n * This setting defines inventory filtering options.\r\n */\r\nexport enum ProductListInventoryFilteringOptions {\r\n /**\r\n * Filter out all products out of stock.\r\n */\r\n HideOOS = 'hideOOS',\r\n\r\n /**\r\n * Sort products by availability, OOS goes last.\r\n */\r\n SortOOS = 'sortOOS',\r\n\r\n /**\r\n * No filtering selected.\r\n */\r\n Default = 'default'\r\n}\r\n\r\n/**\r\n * The full product search result with count interface.\r\n */\r\nexport interface IFullProductsSearchResultsWithCount {\r\n products: ProductSearchResultExt[];\r\n count: number;\r\n channelInventoryConfigurationId?: number;\r\n inventoryAwareSortableAttributeId?: number;\r\n}\r\n\r\n/**\r\n * CreateInput function which creates and actionInput used to fetch products for a list page.\r\n * @param args - The API arguments.\r\n * @returns IActionInput - The action input.\r\n */\r\nconst createInput = (args: ICreateActionContext<{ itemsPerPage: number; includedAttributes: boolean | undefined }>): IActionInput => {\r\n const input = createBaseCollectionInput(args, GetFullProductsByCollectionInput);\r\n\r\n // Set Top\r\n if (input.queryResultSettings.Paging && args.config) {\r\n input.queryResultSettings.Paging.Top = args.config.itemsPerPage || 1;\r\n }\r\n\r\n // Set Skip\r\n if (input.queryResultSettings.Paging && args.requestContext.query && args.requestContext.query.skip) {\r\n input.queryResultSettings.Paging.Skip = +args.requestContext.query.skip;\r\n }\r\n\r\n input.queryResultSettings.count = true;\r\n\r\n return input;\r\n};\r\n\r\n/**\r\n * Returns list of products based on inventory information.\r\n * @param productSearchResults - The products.\r\n * @param context - The context.\r\n * @param metadataCount - The metadata count.\r\n * @param channelInventoryConfiguration - The channel inventory configuration.\r\n * @returns List of product based on the inventory information.\r\n */\r\nexport async function returnProducts(\r\n productSearchResults: ProductSearchResult[],\r\n context: IActionContext,\r\n metadataCount: number | undefined,\r\n channelInventoryConfiguration?: ChannelInventoryConfiguration\r\n): Promise {\r\n const defaultProductCount: number = 0;\r\n\r\n const productSearchResultsWithImages = productSearchResults.map(productSearchResult => {\r\n const newImageUrl = generateProductImageUrl(productSearchResult, context.requestContext.apiSettings);\r\n\r\n if (newImageUrl) {\r\n productSearchResult.PrimaryImageUrl = newImageUrl;\r\n }\r\n\r\n return productSearchResult;\r\n });\r\n\r\n // If inventory level is threshold or inventory check is disabled then return the list of products without the inventory configuration\r\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- read config file.\r\n if (\r\n context.requestContext.app.config.inventoryLevel === InventoryLevels.threshold ||\r\n context.requestContext.app.config.enableStockCheck === false\r\n ) {\r\n return {\r\n products: productSearchResultsWithImages,\r\n count: metadataCount ?? defaultProductCount\r\n };\r\n }\r\n\r\n const mappedProducts = productSearchResultsWithImages.map(productSearchResult => {\r\n if (ArrayExtensions.hasElements(productSearchResult.AttributeValues)) {\r\n for (const element of productSearchResult.AttributeValues) {\r\n if (\r\n channelInventoryConfiguration &&\r\n element.RecordId !== undefined &&\r\n element.RecordId === channelInventoryConfiguration.InventoryProductAttributeRecordId &&\r\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- read config file.\r\n context.requestContext.app.config.inventoryRanges !== 'all' &&\r\n element.TextValue !== channelInventoryConfiguration.InventoryOutOfStockAttributeValueText\r\n ) {\r\n // If same RecordId then it means that is the Inventory attribute\r\n // Based on the inventory range (and filtering options), the inventory label will be displayed\r\n // If Inventory range is 'All' then in stock and out of stock labels are shown, else only OOS\r\n // if the text value is different that the channelInventoryConfiguration.InventoryOutOfStockAttributeValueText then is in stock\r\n element.TextValue = '';\r\n }\r\n }\r\n }\r\n\r\n return productSearchResult;\r\n });\r\n\r\n return {\r\n products: mappedProducts,\r\n count: metadataCount ?? defaultProductCount,\r\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- check config.\r\n channelInventoryConfigurationId: channelInventoryConfiguration\r\n ? channelInventoryConfiguration.InventoryProductAttributeRecordId\r\n : undefined,\r\n inventoryAwareSortableAttributeId: channelInventoryConfiguration\r\n ? channelInventoryConfiguration.ProductAvailabilitySortableAttributeRecordId\r\n : undefined\r\n };\r\n}\r\n\r\n/**\r\n * Action function to fetch products for a list page.\r\n * @param input - The input.\r\n * @param context - The context.\r\n * @returns IFullProductsSearchResultsWithCount - The full product search result with count.\r\n */\r\n// eslint-disable-next-line complexity -- ignore the complexity.\r\nasync function action(input: GetFullProductsByCollectionInput, context: IActionContext): Promise {\r\n let promise: AsyncResult;\r\n let channelInventoryConfigurationPromise: AsyncResult;\r\n let searchProductId;\r\n const searchCriteriaInput: ProductSearchCriteria = {};\r\n searchCriteriaInput.Context = { ChannelId: context.requestContext.apiSettings.channelId, CatalogId: input.catalogId };\r\n // Decouple searchCriteriaInput.Refinement from input.refiners to avoid input.refiners being modified below\r\n searchCriteriaInput.Refinement = JSON.parse(JSON.stringify(input.refiners.slice()));\r\n searchCriteriaInput.IncludeAttributes = input.includeAttributes;\r\n searchCriteriaInput.SkipVariantExpansion = true;\r\n searchCriteriaInput.SearchCondition = input.searchText;\r\n const defaultNumber: number = 0;\r\n\r\n // Fix mobx arrays that got turned to objects\r\n for (let index = 0; index < searchCriteriaInput.Refinement!.length; index++) {\r\n const element = searchCriteriaInput.Refinement![index];\r\n\r\n if (element.ExtensionProperties && typeof element.ExtensionProperties === 'object') {\r\n element.ExtensionProperties = JSON.parse(JSON.stringify(input.refiners[index].ExtensionProperties?.slice()));\r\n }\r\n }\r\n\r\n searchCriteriaInput.Refinement = addOrUpdateZeroPriceRefiner(context, searchCriteriaInput.Refinement);\r\n\r\n if (shouldFilterAlcohol(context)) {\r\n await addAlcoholRefinerAsync(context, searchCriteriaInput);\r\n }\r\n\r\n await addAllAttributeRefiners(context, searchCriteriaInput);\r\n\r\n if (input.channelInventoryConfiguration) {\r\n channelInventoryConfigurationPromise = AsyncResult.resolve(input.channelInventoryConfiguration);\r\n } else {\r\n channelInventoryConfigurationPromise = getInventoryConfigurationAsync({ callerContext: context });\r\n }\r\n const channelInventoryConfiguration = await channelInventoryConfigurationPromise;\r\n\r\n // Replace InventoryProductAttribute with boolean refiner.\r\n // Because the value of InventoryProductAttribute is different from language to language since it's string type.\r\n // The cached old inventory refiner value may be hit when customer switch language which will lead to \"no products found\" issue.\r\n const inventoryRefiner = searchCriteriaInput.Refinement.find(\r\n refiner => refiner.RefinerRecordId === channelInventoryConfiguration?.InventoryProductAttributeRecordId\r\n );\r\n if (inventoryRefiner) {\r\n searchCriteriaInput.Refinement = searchCriteriaInput.Refinement.filter(\r\n refiner => refiner.RefinerRecordId !== channelInventoryConfiguration?.InventoryProductAttributeRecordId\r\n );\r\n\r\n const isInStockRefiner =\r\n inventoryRefiner.LeftValueBoundString !== channelInventoryConfiguration?.InventoryOutOfStockAttributeValueText &&\r\n inventoryRefiner.RightValueBoundString !== channelInventoryConfiguration?.InventoryOutOfStockAttributeValueText;\r\n const inventoryRefinerValue = getInventorySortableRefinerValue(channelInventoryConfiguration, isInStockRefiner);\r\n\r\n const isInventoryRefinerValueExist = searchCriteriaInput.Refinement.some(\r\n refiner => refiner.RefinerRecordId === inventoryRefinerValue?.RefinerRecordId\r\n );\r\n if (!isInventoryRefinerValueExist && inventoryRefinerValue) {\r\n searchCriteriaInput.Refinement.push(inventoryRefinerValue);\r\n }\r\n }\r\n\r\n if (context.requestContext.app.config?.productListInventoryDisplay === ProductListInventoryFilteringOptions.HideOOS) {\r\n const isInStock = true;\r\n const inventoryInStockRefinerValue = getInventorySortableRefinerValue(channelInventoryConfiguration, isInStock);\r\n\r\n const isInventoryInStockRefinerValueExist = searchCriteriaInput.Refinement.some(\r\n refiner => refiner.RefinerRecordId === inventoryInStockRefinerValue?.RefinerRecordId\r\n );\r\n if (!isInventoryInStockRefinerValueExist && inventoryInStockRefinerValue) {\r\n searchCriteriaInput.Refinement.push(inventoryInStockRefinerValue);\r\n }\r\n }\r\n\r\n // Only sort by priority if there is no search condition\r\n if (!searchCriteriaInput.SearchCondition && context.requestContext.app.config?.prioritySortingAttribute) {\r\n const prioritySortingAttribute = context.requestContext.app.config.prioritySortingAttribute as string;\r\n\r\n // Check if the priority sorting attribute only has digits. If not skip this\r\n if (prioritySortingAttribute.match(/^\\d+$/)) {\r\n input.queryResultSettings.Sorting = input.queryResultSettings.Sorting ?? {};\r\n input.queryResultSettings.Sorting.Columns = input.queryResultSettings.Sorting.Columns ?? [];\r\n const priorityColumnName = `Attr_${prioritySortingAttribute}`;\r\n const isPriorityAttributeExist = input.queryResultSettings.Sorting.Columns.some(column => column.ColumnName === priorityColumnName);\r\n if (!isPriorityAttributeExist) {\r\n input.queryResultSettings.Sorting.Columns.push({\r\n ColumnName: priorityColumnName,\r\n IsDescending: true\r\n });\r\n }\r\n }\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- app configs are of generic type\r\n if (\r\n context.requestContext.app.config?.productListInventoryDisplay === ProductListInventoryFilteringOptions.SortOOS &&\r\n channelInventoryConfiguration.ProductAvailabilitySortableAttributeRecordId\r\n ) {\r\n input.queryResultSettings.Sorting = input.queryResultSettings.Sorting ?? {};\r\n input.queryResultSettings.Sorting.Columns = input.queryResultSettings.Sorting.Columns ?? [];\r\n const sortColumnName = `Attr_${channelInventoryConfiguration.ProductAvailabilitySortableAttributeRecordId}`;\r\n const isSortAttributeExist = input.queryResultSettings.Sorting.Columns.some(column => column.ColumnName === sortColumnName);\r\n if (!isSortAttributeExist) {\r\n input.queryResultSettings.Sorting.Columns.push({\r\n ColumnName: sortColumnName,\r\n IsDescending: true\r\n });\r\n }\r\n }\r\n\r\n if (input.pageType === 'Category' || context.requestContext.query?.categoryId) {\r\n if (input.category) {\r\n searchCriteriaInput.CategoryIds = [input.category || defaultNumber];\r\n promise = searchByCriteriaAsync(\r\n {\r\n callerContext: context,\r\n queryResultSettings: input.queryResultSettings\r\n },\r\n searchCriteriaInput\r\n );\r\n } else {\r\n throw new Error('[GetFullProductsForCollection]Category Page Detected, but no global categoryId found');\r\n }\r\n } else if (input.searchText && context.requestContext.query?.q && !context.requestContext.query.recommendation) {\r\n searchCriteriaInput.SearchCondition = input.searchText;\r\n promise = searchByCriteriaAsync(\r\n {\r\n callerContext: context,\r\n queryResultSettings: input.queryResultSettings\r\n },\r\n searchCriteriaInput\r\n );\r\n } else if (input.searchText && context.requestContext.query && context.requestContext.query.recommendation) {\r\n const searchObject = JSON.parse(input.searchText);\r\n if (context.requestContext.query.productId) {\r\n searchProductId = Number(searchObject.ProductId);\r\n }\r\n if (Number.isNaN(searchProductId)) {\r\n throw new Error('Failed to cast search product id into a number.');\r\n } else if (\r\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- Existing code\r\n !searchObject.Recommendation\r\n ) {\r\n throw new Error('Failed to retrieve the Recommendation.');\r\n } else {\r\n searchCriteriaInput.SearchCondition = searchObject.SearchText;\r\n searchCriteriaInput.RecommendationListId = searchObject.Recommendation;\r\n if (searchProductId) {\r\n searchCriteriaInput.Ids = [searchProductId || defaultNumber];\r\n }\r\n promise = searchByCriteriaAsync(\r\n {\r\n callerContext: context,\r\n queryResultSettings: input.queryResultSettings\r\n },\r\n searchCriteriaInput\r\n );\r\n }\r\n } else if (input.searchText && context.requestContext.query?.discountIds) {\r\n const accountInformation = await getCustomer(new GetCustomerInput(context.requestContext.apiSettings), context);\r\n const discountIds = context.requestContext.query?.discountIds.split(',');\r\n\r\n const productPromotions = await getProductPromotionsAsync(\r\n {\r\n callerContext: context,\r\n queryResultSettings: input.queryResultSettings\r\n },\r\n discountIds ?? [],\r\n {\r\n HeaderContext: {\r\n ChannelId: context.requestContext.apiSettings.channelId,\r\n CustomerAccountNumber: accountInformation?.AccountNumber\r\n },\r\n LineContexts: [\r\n {\r\n CatalogId: input.catalogId\r\n }\r\n ]\r\n },\r\n new Date()\r\n );\r\n\r\n const productIds = productPromotions.map(p => p.ProductId ?? 0);\r\n searchCriteriaInput.Ids = productIds;\r\n searchCriteriaInput.CustomerAccountNumber = accountInformation.AccountNumber;\r\n\r\n promise = searchByCriteriaAsync(\r\n {\r\n callerContext: context,\r\n queryResultSettings: input.queryResultSettings\r\n },\r\n searchCriteriaInput\r\n );\r\n } else {\r\n throw new Error('[GetFullProductsForCollection]Search Page Detected, but no q= or productId= query parameter found');\r\n }\r\n\r\n let productSearchResults = await promise as ProductSearchResultExt[];\r\n\r\n // Reset non-active prices\r\n productSearchResults.forEach(x => {\r\n x.Price = 0;\r\n x.BasePrice = 0;\r\n x.MaxVariantPrice = 0;\r\n x.MinVariantPrice = 0;\r\n x.PrefetchedPrice = false;\r\n });\r\n\r\n if (context.requestContext.user.isAuthenticated) {\r\n try {\r\n const input = new CachedPriceForProductSearchResultInput(productSearchResults);\r\n const cached = await getCachedPriceForProductSearchResultDataAction(input, context);\r\n productSearchResults = cached;\r\n } catch (error) {\r\n // Do nothing, error is already logged in above function\r\n }\r\n }\r\n\r\n return returnProducts(productSearchResults, context, promise.metadata.count, channelInventoryConfiguration);\r\n}\r\n\r\nexport const actionDataAction = createObservableDataAction({\r\n id: '@msdyn365-commerce-modules/search-result-container/get-full-products-by-collection',\r\n action: action as IAction,\r\n input: createInput\r\n});\r\n\r\nexport default actionDataAction;\r\n","/*!\r\n * Copyright (c) Microsoft Corporation.\r\n * All rights reserved. See LICENSE in the project root for license information.\r\n */\r\n\r\n/* eslint-disable no-duplicate-imports */\r\nimport {\r\n CacheType,\r\n createObservableDataAction,\r\n IAction,\r\n IActionContext,\r\n IActionInput,\r\n IAny,\r\n ICommerceApiSettings,\r\n ICreateActionContext,\r\n IGeneric\r\n} from '@msdyn365-commerce/core';\r\nimport { SortColumn } from '@msdyn365-commerce/retail-proxy';\r\nimport { getSearchConfigurationAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/StoreOperationsDataActions.g';\r\nimport { buildCacheKey } from '@msdyn365-commerce-modules/retail-actions';\r\n\r\n// TODO: import from commerce entities when available\r\n// eslint-disable-next-line @typescript-eslint/naming-convention -- Name change will require many modifications\r\ninterface SearchConfiguration {\r\n ProductSortColumns?: SortColumn[];\r\n}\r\n\r\n// eslint-disable-next-line @typescript-eslint/naming-convention -- Name change will require many modifications\r\nexport interface MappedSearchConfiguration {\r\n key: string;\r\n sortColumn: SortColumn;\r\n}\r\n\r\nexport const sortOptions = {\r\n sortByOptionRelevanceDesc: 'Ranking-Desc',\r\n sortByOptionRatingAsc: 'AverageRating-Asc',\r\n sortByOptionRatingDesc: 'AverageRating-Desc',\r\n sortByOptionNameAsc: 'Name-Asc',\r\n sortByOptionNameDesc: 'Name-Desc',\r\n sortByOptionPriceAsc: 'Price-Asc',\r\n sortByOptionPriceDesc: 'Price-Desc',\r\n sortByOptionBestSelling: 'BestSelling',\r\n sortByOptionNewScore: 'NewScore',\r\n sortByOptionTrendingScore: 'TrendingScore'\r\n};\r\n\r\n/**\r\n * ActionInput class for the get-mapped-search-configuration Data Action.\r\n */\r\nexport class MappedSearchInput implements IActionInput {\r\n private readonly apiSettings: ICommerceApiSettings;\r\n\r\n constructor(apiSettings: ICommerceApiSettings) {\r\n this.apiSettings = apiSettings;\r\n }\r\n\r\n public getCacheKey = () => buildCacheKey('MappedSearchInput', this.apiSettings);\r\n\r\n public getCacheObjectType = () => 'MappedSearchInput';\r\n\r\n public dataCacheType = (): CacheType => 'request';\r\n}\r\n\r\n/**\r\n * Get a mapped search configuration that is easy to use for sorting.\r\n * @param input\r\n * @param ctx\r\n */\r\nexport async function getMappedSearchConfiguration(input: MappedSearchInput, ctx: IActionContext): Promise {\r\n return getSearchConfigurationAsync({ callerContext: ctx }).then((searchConfiguration: SearchConfiguration) => {\r\n return (searchConfiguration.ProductSortColumns || [])\r\n .map((sortColumn: SortColumn) => {\r\n let key = '';\r\n if (sortColumn.ColumnName) {\r\n switch (sortColumn.ColumnName.toUpperCase()) {\r\n case 'NAME':\r\n key = sortColumn.IsDescending ? sortOptions.sortByOptionNameDesc : sortOptions.sortByOptionNameAsc;\r\n break;\r\n case 'PRICE':\r\n key = sortColumn.IsDescending ? sortOptions.sortByOptionPriceDesc : sortOptions.sortByOptionPriceAsc;\r\n break;\r\n case 'AVERAGERATING':\r\n key = sortColumn.IsDescending ? sortOptions.sortByOptionRatingDesc : sortOptions.sortByOptionRatingAsc;\r\n break;\r\n case 'RANKING':\r\n key = sortOptions.sortByOptionRelevanceDesc;\r\n break;\r\n case 'BESTSELLINGSCORE':\r\n key = sortOptions.sortByOptionBestSelling;\r\n break;\r\n case 'NEWSCORE':\r\n key = sortOptions.sortByOptionNewScore;\r\n break;\r\n case 'TRENDINGSCORE':\r\n key = sortOptions.sortByOptionTrendingScore;\r\n break;\r\n default:\r\n }\r\n } else {\r\n ctx.telemetry.warning('[get-mapped-search-configuration] unknown search option');\r\n }\r\n if (key) {\r\n return {\r\n key,\r\n sortColumn\r\n };\r\n }\r\n return undefined;\r\n })\r\n .filter(Boolean);\r\n });\r\n}\r\n\r\nexport const createInput = (inputData: ICreateActionContext>): IActionInput => {\r\n return new MappedSearchInput(inputData.requestContext.apiSettings);\r\n};\r\n\r\nexport const getMappedSearchConfigurationDataAction = createObservableDataAction({\r\n id: '@msdyn365-commerce-modules/search-result-container/get-mapped-search-configuration',\r\n action: >getMappedSearchConfiguration,\r\n input: createInput\r\n});\r\n\r\nexport default getMappedSearchConfigurationDataAction;\r\n","/*!\r\n * Copyright (c) Microsoft Corporation.\r\n * All rights reserved. See LICENSE in the project root for license information.\r\n */\r\n\r\n/* eslint-disable no-duplicate-imports */\r\nimport { IProductRefinerHierarchy } from '@msdyn365-commerce/commerce-entities';\r\nimport { IActionContext } from '@msdyn365-commerce/core';\r\nimport { IQueryResultSettings, ProductRefiner, ProductSearchCriteria } from '@msdyn365-commerce/retail-proxy';\r\nimport { getProductSearchRefinersAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/ProductsDataActions.g';\r\n\r\n/**\r\n * Uses Bulk refiner API to get refiners and child refiner values.\r\n * @param searchCriteria Product search criteria.\r\n * @param maxItems Max items.\r\n * @param queryResultSettings\r\n * @param ctx Action context.\r\n */\r\nexport async function getProductRefinerHierarchy(\r\n searchCriteria: ProductSearchCriteria,\r\n queryResultSettings: IQueryResultSettings | undefined,\r\n ctx: IActionContext\r\n): Promise {\r\n const productRefiners = await getProductSearchRefinersAsync({ callerContext: ctx, queryResultSettings }, searchCriteria);\r\n\r\n if (!productRefiners) {\r\n ctx.trace('[getRefinersByCriteriaAction] returned no refiners');\r\n return [];\r\n }\r\n\r\n const result = (productRefiners || []).map((productRefiner: ProductRefiner) => productRefiner);\r\n\r\n if (result.length === 0) {\r\n ctx.trace('[getRefinersByCriteriaAction] returned no IProductRefinerHierarchy objects');\r\n return [];\r\n }\r\n\r\n return result;\r\n}\r\n","/*!\r\n * Copyright (c) Microsoft Corporation.\r\n * All rights reserved. See LICENSE in the project root for license information.\r\n */\r\n\r\n/* eslint-disable no-duplicate-imports */\r\nimport { IProductRefinerHierarchy } from '@msdyn365-commerce/commerce-entities';\r\nimport { createObservableDataAction, IAction, IActionContext, IActionInput, ICreateActionContext } from '@msdyn365-commerce/core';\r\nimport { AsyncResult, ChannelInventoryConfiguration, ProductRefinerValue, ProductSearchCriteria } from '@msdyn365-commerce/retail-proxy';\r\nimport { getInventoryConfigurationAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/StoreOperationsDataActions.g';\r\n\r\nimport { BaseCollectionInput, createBaseCollectionInput } from './base-collection-action';\r\nimport { getProductRefinerHierarchy } from './get-product-refiner-hierarchy';\r\nimport { getInventorySortableRefinerValue, ProductListInventoryFilteringOptions } from '.';\r\nimport { addOrUpdateZeroPriceRefiner, getAlcoholRefiners, getAllAttributeRefiners, shouldFilterAlcohol } from './refiner-utils';\r\n\r\n/**\r\n * Default Category/Product Id Values.\r\n */\r\nenum DefaultValues {\r\n defaultCategoryIdValue = 0,\r\n defaultProductIdValue = 0\r\n}\r\n\r\n/**\r\n * Refiners-by-Collection Input action.\r\n */\r\nexport class RefinersByCollectionInput extends BaseCollectionInput implements IActionInput {\r\n public getCacheObjectType = () => 'ProductRefiner';\r\n\r\n public dataCacheType = () => {\r\n return 'none';\r\n // @ts-ignore\r\n if (\r\n this.pageType !== 'Category' ||\r\n (this.refiners && this.refiners.length > 0) ||\r\n (this.queryResultSettings &&\r\n this.queryResultSettings.Sorting &&\r\n this.queryResultSettings.Sorting!.Columns &&\r\n this.queryResultSettings.Sorting!.Columns!.length > 0)\r\n ) {\r\n return 'request';\r\n }\r\n return 'application';\r\n };\r\n}\r\n\r\n/**\r\n * Create input method which creates an ActionInput for fetching list page refiners.\r\n * @param args\r\n */\r\nconst createInput = (args: ICreateActionContext): IActionInput => {\r\n return createBaseCollectionInput(args, RefinersByCollectionInput);\r\n};\r\n\r\n/**\r\n * Action method which fetches refiners for the given list page.\r\n * @param input\r\n * @param context\r\n */\r\nexport async function getRefinersForCollectionDataAction(input: RefinersByCollectionInput, context: IActionContext): Promise {\r\n let searchProductId;\r\n // Decouple refiners from input.refiners to avoid input.refiners being modified below\r\n let refiners: ProductRefinerValue[] = [...input.refiners] || [];\r\n\r\n let channelInventoryConfigurationPromise: AsyncResult;\r\n if (input.channelInventoryConfiguration) {\r\n channelInventoryConfigurationPromise = AsyncResult.resolve(input.channelInventoryConfiguration);\r\n } else {\r\n channelInventoryConfigurationPromise = getInventoryConfigurationAsync({ callerContext: context });\r\n }\r\n const channelInventoryConfiguration = await channelInventoryConfigurationPromise;\r\n\r\n // Replace InventoryProductAttribute with boolean refiner.\r\n // Because the value of InventoryProductAttribute is different from language to language since it's string type.\r\n // The cached old inventory refiner value may be hit when customer switch language which will lead to \"no products found\" issue.\r\n const inventoryRefiner = refiners.find(\r\n refiner => refiner.RefinerRecordId === channelInventoryConfiguration?.InventoryProductAttributeRecordId\r\n );\r\n if (inventoryRefiner) {\r\n refiners = refiners.filter(refiner => refiner.RefinerRecordId !== channelInventoryConfiguration?.InventoryProductAttributeRecordId);\r\n\r\n const isInStockRefiner =\r\n inventoryRefiner.LeftValueBoundString !== channelInventoryConfiguration?.InventoryOutOfStockAttributeValueText &&\r\n inventoryRefiner.RightValueBoundString !== channelInventoryConfiguration?.InventoryOutOfStockAttributeValueText;\r\n const inventoryRefinerValue = getInventorySortableRefinerValue(channelInventoryConfiguration, isInStockRefiner);\r\n\r\n const isInventoryRefinerValueExist = refiners.some(refiner => refiner.RefinerRecordId === inventoryRefinerValue?.RefinerRecordId);\r\n if (!isInventoryRefinerValueExist && inventoryRefinerValue) {\r\n refiners.push(inventoryRefinerValue);\r\n }\r\n }\r\n\r\n if (context.requestContext.app.config?.productListInventoryDisplay === ProductListInventoryFilteringOptions.HideOOS) {\r\n const isInStock = true;\r\n const inventoryInStockRefinerValue = getInventorySortableRefinerValue(channelInventoryConfiguration, isInStock);\r\n\r\n const isInventoryInStockRefinerValueExist = refiners.some(\r\n refiner => refiner.RefinerRecordId === inventoryInStockRefinerValue?.RefinerRecordId\r\n );\r\n if (!isInventoryInStockRefinerValueExist && inventoryInStockRefinerValue) {\r\n refiners.push(inventoryInStockRefinerValue);\r\n }\r\n }\r\n\r\n const alcoholFilter = shouldFilterAlcohol(context);\r\n const attributeRefiners = await getAllAttributeRefiners(context);\r\n\r\n // Either 'refiners' or 'defaultRefiners' will be used on 'isUpdateRefinerPanel'. But either way it should always\r\n // contain the zero price filter and alcohol refiner.\r\n refiners = addOrUpdateZeroPriceRefiner(context, refiners)\r\n .concat(alcoholFilter ? await getAlcoholRefiners(context) : [])\r\n .concat(attributeRefiners);\r\n const defaultRefiners = addOrUpdateZeroPriceRefiner(context)\r\n .concat(alcoholFilter ? await getAlcoholRefiners(context) : [])\r\n .concat(attributeRefiners);\r\n\r\n if (input.pageType === 'Category') {\r\n if (input.category) {\r\n input.refiners = input.isUpdateRefinerPanel ? refiners : defaultRefiners;\r\n return getProductRefinerHierarchy(\r\n {\r\n CategoryIds: [input.category || DefaultValues.defaultCategoryIdValue],\r\n Context: {\r\n ChannelId: input.apiSettings.channelId,\r\n CatalogId: input.catalogId\r\n },\r\n Refinement: input.isUpdateRefinerPanel ? refiners : defaultRefiners,\r\n SearchCondition: input.searchText\r\n },\r\n input.queryResultSettings,\r\n context\r\n );\r\n }\r\n throw new Error('[GetRefinersForCollection]Category Page Detected, but no global categoryId found');\r\n } else {\r\n if (input.searchText && context.requestContext.query && context.requestContext.query.q && !context.requestContext.query.recommendation) {\r\n input.refiners = input.isUpdateRefinerPanel ? refiners : defaultRefiners;\r\n return getProductRefinerHierarchy(\r\n {\r\n SearchCondition: input.searchText,\r\n Context: {\r\n ChannelId: input.apiSettings.channelId,\r\n CatalogId: input.catalogId\r\n },\r\n Refinement: input.isUpdateRefinerPanel ? refiners : defaultRefiners\r\n },\r\n input.queryResultSettings,\r\n context\r\n );\r\n }\r\n if (input.searchText && context.requestContext.query && context.requestContext.query.recommendation) {\r\n const searchObject = JSON.parse(input.searchText);\r\n if (context.requestContext.query.productId) {\r\n searchProductId = Number(searchObject.ProductId);\r\n }\r\n if (Number.isNaN(searchProductId)) {\r\n throw new Error('Failed to cast search product id into a number.');\r\n } else if (!searchObject.Recommendation) {\r\n throw new Error('Failed to retrieve the Recommendation.');\r\n } else {\r\n const searchCriteriaInput: ProductSearchCriteria = {};\r\n input.refiners = input.isUpdateRefinerPanel ? refiners : defaultRefiners;\r\n searchCriteriaInput.Context = {\r\n ChannelId: input.apiSettings.channelId,\r\n CatalogId: input.catalogId\r\n };\r\n searchCriteriaInput.SearchCondition = searchObject.SearchText;\r\n searchCriteriaInput.Refinement = input.isUpdateRefinerPanel ? refiners : defaultRefiners;\r\n searchCriteriaInput.RecommendationListId = searchObject.Recommendation;\r\n if (searchProductId) {\r\n searchCriteriaInput.Ids = [searchProductId || DefaultValues.defaultProductIdValue];\r\n }\r\n return getProductRefinerHierarchy(searchCriteriaInput, input.queryResultSettings, context);\r\n }\r\n } else {\r\n throw new Error('[GetFullProductsForCollection]Search Page Detected, but no q= or productId= query parameter found');\r\n }\r\n }\r\n}\r\n\r\nexport const actionDataAction = createObservableDataAction({\r\n id: '@msdyn365-commerce-modules/search-result-container/get-refiners-for-collection',\r\n action: >getRefinersForCollectionDataAction,\r\n input: createInput\r\n});\r\n\r\nexport default actionDataAction;\r\n","/*!\r\n * Copyright (c) Microsoft Corporation.\r\n * All rights reserved. See LICENSE in the project root for license information.\r\n */\r\n\r\n/* eslint-disable no-duplicate-imports */\r\nimport { IProductRefinerHierarchy } from '@msdyn365-commerce/commerce-entities';\r\nimport { CacheType, createObservableDataAction, IAction, IActionContext, IActionInput } from '@msdyn365-commerce/core';\r\nimport { buildCacheKey } from '@msdyn365-commerce-modules/retail-actions';\r\n\r\nimport {\r\n AttributeDataType,\r\n ChannelInventoryConfiguration,\r\n ProductRefinerSource,\r\n ProductRefinerValue\r\n} from '@msdyn365-commerce/retail-proxy';\r\nimport { BaseCollectionInput } from './base-collection-action';\r\nimport { getProductRefinerHierarchy } from './get-product-refiner-hierarchy';\r\n\r\n/**\r\n * Returns inventory in stock sortable refiner value.\r\n * @param channelInventoryConfiguration - The channelInventoryConfiguration.\r\n * @param isInStock - The flag indicating whether is getting in-stock refiner or out-of-stock refiner.\r\n * @returns Refiners.\r\n */\r\nexport const getInventorySortableRefinerValue = (\r\n channelInventoryConfiguration: ChannelInventoryConfiguration,\r\n isInStock: boolean\r\n): ProductRefinerValue | undefined => {\r\n if (channelInventoryConfiguration && channelInventoryConfiguration.ProductAvailabilitySortableAttributeRecordId) {\r\n return {\r\n RefinerRecordId: channelInventoryConfiguration.ProductAvailabilitySortableAttributeRecordId,\r\n DataTypeValue: AttributeDataType.TrueFalse,\r\n LeftValueBoundString: isInStock ? 'true' : 'false',\r\n RightValueBoundString: isInStock ? 'true' : 'false',\r\n UnitText: '',\r\n RowNumber: 0,\r\n Count: 0,\r\n ExtensionProperties: [],\r\n RefinerSourceValue: ProductRefinerSource.Attribute\r\n };\r\n }\r\n return undefined;\r\n};\r\n\r\n/**\r\n * InventoryInStockRefinerValue Input action.\r\n * @remark The get-inventory-refiners data action is obsoleted. Please use getInventorySortableRefinerValue instead.\r\n */\r\nexport class InventoryInStockRefinerValueInput extends BaseCollectionInput implements IActionInput {\r\n public inventoryProductAttributeRecordId: number;\r\n\r\n public constructor(input: BaseCollectionInput, inventoryProductAttributeRecordId: number = 0) {\r\n super(\r\n input.pageType,\r\n input.apiSettings,\r\n {\r\n count: true\r\n },\r\n\r\n // Parameter - refiners\r\n [],\r\n\r\n // Parameter - category\r\n undefined,\r\n\r\n // Parameter - searchText\r\n '',\r\n\r\n // Parameter - includeAttributes\r\n false,\r\n\r\n // Parameter - isUpdateRefinerPanel\r\n false,\r\n\r\n // Parameter - locale\r\n undefined,\r\n input.catalogId,\r\n input.channelInventoryConfiguration,\r\n input.inventoryRefiner\r\n );\r\n\r\n this.inventoryProductAttributeRecordId =\r\n inventoryProductAttributeRecordId || input.channelInventoryConfiguration?.InventoryProductAttributeRecordId || 0;\r\n }\r\n\r\n /**\r\n * GetCacheKey.\r\n * @returns - Returns string.\r\n */\r\n public getCacheKey = (): string => buildCacheKey('RefinerList', this.apiSettings);\r\n\r\n /**\r\n * GetCacheObjectType.\r\n * @returns - Returns string.\r\n */\r\n public getCacheObjectType = (): string => 'RefinerList';\r\n\r\n /**\r\n * DataCacheType.\r\n * @returns - CacheType string.\r\n */\r\n public dataCacheType = (): CacheType => 'application';\r\n}\r\n\r\n/**\r\n * Action method returns inventory in stock refiners.\r\n * @param input - InventoryInStockRefinerValueInput.\r\n * @param context - IActionContext.\r\n * @returns - Promise.\r\n * @remark The get-inventory-refiners data action is obsoleted. Please use getInventorySortableRefinerValue instead.\r\n */\r\nasync function action(input: InventoryInStockRefinerValueInput, context: IActionContext): Promise {\r\n const refiners = await getProductRefinerHierarchy(\r\n {\r\n Context: {\r\n ChannelId: input.apiSettings.channelId,\r\n CatalogId: input.catalogId\r\n }\r\n },\r\n input.queryResultSettings,\r\n context\r\n );\r\n\r\n // InventoryProductAttributeRecordId may be 0, and recId of default refiner Category/Price/Rating is always 0 by design. In this case, we should not return refiner\r\n // Why recId of default refiner Category/Price/Rating is 0: see GetChannelProductRefiners.sql\r\n return (\r\n (input.channelInventoryConfiguration?.InventoryProductAttributeRecordId !== 0 &&\r\n refiners.find(refiner => refiner.RecordId === input.channelInventoryConfiguration?.InventoryProductAttributeRecordId)) ||\r\n // keep legacy logic to avoid break existing customers usage from this file\r\n (input.inventoryProductAttributeRecordId !== 0 &&\r\n refiners.find(refiner => refiner.RecordId === input.inventoryProductAttributeRecordId)) ||\r\n null\r\n );\r\n}\r\n\r\n/**\r\n * Action.\r\n * @param id - Id.\r\n * @param action - Action.\r\n * @returns - Results.\r\n * @remark The get-inventory-refiners data action is obsoleted. Please use getInventorySortableRefinerValue instead.\r\n */\r\nexport const actionDataAction = createObservableDataAction({\r\n id: '@msdyn365-commerce-modules/search-result-container/get-inventory-refiners',\r\n action: action as IAction\r\n});\r\n\r\nexport default actionDataAction;\r\n","import { IActionContext } from '@msdyn365-commerce/core';\r\nimport { AttributeDataType, CustomerAttribute, ProductRefinerSource, ProductRefinerValue, ProductSearchCriteria } from '@msdyn365-commerce/retail-proxy';\r\n// @ts-ignore\r\nimport { getCustomer, GetCustomerInput } from '@msdyn365-commerce-modules/retail-actions';\r\nimport getOrganizationCustomer, { GetOrganizationCustomerInput } from '../../../actions/get-organization-customer';\r\n\r\n// Pre populated with ids from STAGE for local development\r\nconst AlcoholGroupAttributeId = 5637155076;\r\n\r\nfunction isGodmodeEnabled(context: IActionContext): boolean {\r\n const godmode = context.requestContext.url.requestUrl.searchParams.get('godmode')?.toLowerCase();\r\n\r\n return godmode === '1' || godmode === 'true';\r\n}\r\n\r\nexport function shouldFilterAlcohol(context: IActionContext): boolean {\r\n const doAlcoholFiltering = context.requestContext.url.requestUrl.searchParams.get('alcohol')?.toLowerCase() !== 'false';\r\n const alcoholRefinerRecordId = Number(context.requestContext.app.config?.alcoholRefinerRecordId);\r\n\r\n return doAlcoholFiltering && !isNaN(alcoholRefinerRecordId) && alcoholRefinerRecordId > 0;\r\n}\r\n\r\nexport async function getAlcoholRefiners(context: IActionContext): Promise {\r\n let alcoholGroupAttributeId = Number(context.requestContext.app.config?.alcoholRefinerRecordId);\r\n\r\n if (isNaN(alcoholGroupAttributeId) || alcoholGroupAttributeId === 0) {\r\n alcoholGroupAttributeId = AlcoholGroupAttributeId;\r\n }\r\n\r\n const result: ProductRefinerValue[] = [];\r\n const alcoholRefiner: ProductRefinerValue = {\r\n DataTypeValue: 5,\r\n LeftValueBoundString: '0',\r\n RefinerRecordId: alcoholGroupAttributeId,\r\n RefinerSourceValue: 1,\r\n RightValueBoundString: '0',\r\n UnitText: ''\r\n };\r\n\r\n result.push(alcoholRefiner);\r\n\r\n try {\r\n let alcoholLicenseValue = 0;\r\n\r\n if (context.requestContext.user.isAuthenticated) {\r\n // Get Customer attributes\r\n // const customer = await getCustomer(new GetCustomerInput(context.requestContext.apiSettings, context.requestContext.user.customerAccountNumber), context);\r\n const customer = await getOrganizationCustomer(new GetOrganizationCustomerInput(context.requestContext.apiSettings, context.requestContext.user.customerAccountNumber!), context);\r\n const alcoholLicense = Number(customer.Attributes?.find(x => x.RecordId === alcoholGroupAttributeId)?.AttributeValue?.StringValue);\r\n\r\n if (isNaN(alcoholLicense)) {\r\n // Throw NaN error\r\n console.warn('Alcohol license value is missing or not a number.');\r\n } else {\r\n alcoholLicenseValue = alcoholLicense;\r\n }\r\n } else {\r\n // If user is not logged in show all products\r\n alcoholLicenseValue = 3;\r\n }\r\n\r\n // TODO: Verify we can do ranges like this on text attributes\r\n // If we can do range on text attributes use this:\r\n //alcoholRefiner.RightValueBoundString = alcoholLicense?.AttributeValue?.StringValue ?? '0';\r\n\r\n // Add a refiner for each alcohol group\r\n Array(alcoholLicenseValue).fill(0).forEach((_, index) => {\r\n result.push({\r\n ...alcoholRefiner,\r\n LeftValueBoundString: (index + 1).toString(),\r\n RightValueBoundString: (index + 1).toString()\r\n });\r\n });\r\n } catch (error) {\r\n console.warn('Failed to get customer attributes for alcohol license or parse value of attribute. No alcohol license applied to search.', error);\r\n }\r\n\r\n return result;\r\n}\r\n\r\nexport async function addAlcoholRefiner(context: IActionContext, searchCriteriaInput: ProductSearchCriteria): Promise {\r\n let alcoholGroupAttributeId = Number(context.requestContext.app.config?.alcoholRefinerRecordId);\r\n\r\n if (isNaN(alcoholGroupAttributeId) || alcoholGroupAttributeId === 0) {\r\n alcoholGroupAttributeId = AlcoholGroupAttributeId;\r\n }\r\n\r\n if (searchCriteriaInput.Refinement!.some(x => x.RefinerRecordId === alcoholGroupAttributeId)) {\r\n // Remove existing, shouldn't be here\r\n searchCriteriaInput.Refinement = searchCriteriaInput.Refinement!.filter(x => x.RefinerRecordId !== alcoholGroupAttributeId);\r\n }\r\n\r\n const refiners = await getAlcoholRefiners(context);\r\n\r\n searchCriteriaInput.Refinement = searchCriteriaInput.Refinement!.concat(refiners);\r\n\r\n return Promise.resolve();\r\n}\r\n\r\nexport function addOrUpdateZeroPriceRefiner(context: IActionContext, refiners?: ProductRefinerValue[]): ProductRefinerValue[] {\r\n // Check criteria for allowing user to see zero price products. Example:\r\n // - Has ?godmode=true in url\r\n const allowZeroPriceProducts = isGodmodeEnabled(context);\r\n\r\n if (!allowZeroPriceProducts) {\r\n const result = refiners ? [...refiners] : [];\r\n\r\n // Make sure we don't show zero price products\r\n const priceRefiner = result.find(x => x.RefinerRecordId === 0);\r\n\r\n if (priceRefiner) {\r\n // There is a price refiner, make sure it has a min value of 0.01 or more\r\n if (!priceRefiner.LeftValueBoundString || Number(priceRefiner.LeftValueBoundString) < 0.01) {\r\n priceRefiner.LeftValueBoundString = '0.01';\r\n }\r\n } else {\r\n // No price refiner, add one\r\n result.push({\r\n '@odata.type': '#Microsoft.Dynamics.Commerce.Runtime.DataModel.ProductRefinerValue',\r\n Count: 0,\r\n DataTypeValue: 1,\r\n LeftValueBoundString: '0.01',\r\n ExtensionProperties: [],\r\n RefinerRecordId: 0,\r\n RefinerSourceValue: 3,\r\n RightValueBoundString: '1000000000',\r\n RowNumber: 0,\r\n UnitText: context.requestContext.channel?.Currency\r\n } as any);\r\n }\r\n\r\n return result;\r\n }\r\n\r\n return refiners || [];\r\n}\r\n\r\nexport async function getAttributeRefiners(context: IActionContext, customerAttributes: CustomerAttribute[] | undefined, attributeRecordId: number, friendlyName?: string): Promise {\r\n const result: ProductRefinerValue[] = [];\r\n const refiner: ProductRefinerValue = {\r\n DataTypeValue: 5,\r\n LeftValueBoundString: '0',\r\n RefinerRecordId: attributeRecordId,\r\n RefinerSourceValue: 1,\r\n RightValueBoundString: '0',\r\n UnitText: ''\r\n };\r\n\r\n result.push(refiner);\r\n\r\n try {\r\n let attributeValue = 0;\r\n\r\n if (context.requestContext.user.isAuthenticated) {\r\n const attribute = Number(customerAttributes?.find(x => x.RecordId === attributeRecordId)?.AttributeValue?.StringValue);\r\n\r\n if (isNaN(attribute)) {\r\n // Throw NaN error\r\n if (friendlyName) {\r\n console.warn(`${friendlyName} attribute value is missing or not a number.`);\r\n } else {\r\n console.warn(`Attribute with record id ${attributeRecordId} is missing a value or not a number.`);\r\n }\r\n } else {\r\n attributeValue = attribute;\r\n }\r\n } else {\r\n // If user is not logged in show all products\r\n attributeValue = 1;\r\n }\r\n\r\n if (attributeValue !== 0) {\r\n result.push({\r\n ...refiner,\r\n LeftValueBoundString: attributeValue.toString(),\r\n RightValueBoundString: attributeValue.toString()\r\n });\r\n }\r\n } catch (error) {\r\n if (friendlyName) {\r\n console.warn(`Failed to get ${friendlyName} customer attribute or parse value of attribute. No filter applied to search.`, error);\r\n } else {\r\n console.warn(`Failed to get customer attribute (record id: ${attributeRecordId}) or parse value of attribute. No filter applied to search.`, error);\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n\r\nexport async function getForsvaretRefiner(context: IActionContext, customerAttributes: CustomerAttribute[] | undefined): Promise {\r\n const forsvaretAttributeId = context.requestContext.app.config?.forsvaretAttributeRecordId;\r\n\r\n if (!forsvaretAttributeId || !context.requestContext.user.isAuthenticated) {\r\n return;\r\n }\r\n\r\n try {\r\n const attribute = customerAttributes?.find(x => x.RecordId === Number(forsvaretAttributeId))?.AttributeValue?.IntegerValue;\r\n\r\n if (!attribute || isNaN(attribute) || attribute === 0) {\r\n return;\r\n }\r\n\r\n return {\r\n DataTypeValue: AttributeDataType.Integer,\r\n LeftValueBoundString: attribute.toString(),\r\n RefinerRecordId: Number(forsvaretAttributeId),\r\n RefinerSourceValue: ProductRefinerSource.Attribute,\r\n RightValueBoundString: attribute.toString(),\r\n UnitText: ''\r\n };\r\n } catch (error) {\r\n console.error('Failed to get forsvaret attribute', error);\r\n return;\r\n }\r\n}\r\n\r\nexport async function getSvalbardRefiner(context: IActionContext, customerAttributes: CustomerAttribute[] | undefined): Promise {\r\n if (!context.requestContext.user.isAuthenticated) {\r\n return;\r\n }\r\n\r\n const svalbardAttributeId = context.requestContext.app.config?.svalbardAttributeRecordId;\r\n const blockedSvalbardAttributeId = context.requestContext.app.config?.blockedSvalbardAttributeRecordId;\r\n\r\n // Both config needs to be set to something\r\n if (!svalbardAttributeId || !blockedSvalbardAttributeId) {\r\n return;\r\n }\r\n\r\n // Both config needs to be numbers. This allows users to prepend values with a character to temporarily disable the refiner\r\n if (isNaN(svalbardAttributeId) || isNaN(blockedSvalbardAttributeId)) {\r\n return;\r\n }\r\n\r\n try {\r\n const attribute = customerAttributes?.find(x => x.RecordId === Number(svalbardAttributeId))?.AttributeValue?.IntegerValue;\r\n\r\n // Check if attribute is set, is a number and above 0\r\n if (!attribute || isNaN(attribute) || attribute <= 0) {\r\n return;\r\n }\r\n\r\n // Add refiner so that only products that isn't blocked for svalbard is shown since customer attribute is set to 1 or more\r\n return {\r\n DataTypeValue: AttributeDataType.Integer,\r\n LeftValueBoundString: '0',\r\n RefinerRecordId: Number(blockedSvalbardAttributeId),\r\n RefinerSourceValue: ProductRefinerSource.Attribute,\r\n RightValueBoundString: '0',\r\n UnitText: ''\r\n };\r\n } catch (error) {\r\n console.error('Failed to get svalbard attribute(s)', error);\r\n return;\r\n }\r\n}\r\n\r\nexport async function addAttributeRefiner(context: IActionContext, customerAttributes: CustomerAttribute[] | undefined, searchCriteriaInput: ProductSearchCriteria, attributeRecordId: number): Promise {\r\n if (searchCriteriaInput.Refinement!.some(x => x.RefinerRecordId === attributeRecordId)) {\r\n // Remove existing, shouldn't be here\r\n searchCriteriaInput.Refinement = searchCriteriaInput.Refinement!.filter(x => x.RefinerRecordId !== attributeRecordId);\r\n }\r\n\r\n const refiners = await getAttributeRefiners(context, customerAttributes, attributeRecordId);\r\n\r\n searchCriteriaInput.Refinement = searchCriteriaInput.Refinement!.concat(refiners);\r\n}\r\n\r\nexport async function addAttributeRefinerKeepExisting(context: IActionContext, customerAttributes: CustomerAttribute[] | undefined, searchCriteriaInput: ProductSearchCriteria, attributeRecordId: number): Promise {\r\n if (searchCriteriaInput.Refinement!.some(x => x.RefinerRecordId === attributeRecordId)) {\r\n return;\r\n }\r\n\r\n const refiners = await getAttributeRefiners(context, customerAttributes, attributeRecordId);\r\n\r\n searchCriteriaInput.Refinement = searchCriteriaInput.Refinement!.concat(refiners);\r\n}\r\n\r\nexport async function addAllAttributeRefiners(context: IActionContext, searchCriteriaInput: ProductSearchCriteria): Promise {\r\n const godmode = isGodmodeEnabled(context);\r\n\r\n if (godmode) {\r\n return;\r\n }\r\n\r\n let customerAttributes: CustomerAttribute[] | undefined = [];\r\n\r\n if (context.requestContext.user.isAuthenticated) {\r\n const { apiSettings, user: { customerAccountNumber } } = context.requestContext;\r\n const customer = await getOrganizationCustomer(new GetOrganizationCustomerInput(apiSettings, customerAccountNumber!), context);\r\n customerAttributes = customer.Attributes;\r\n }\r\n\r\n const attributeRecordIds: string[] = [\r\n context.requestContext.app.config?.tobaccoRefinerRecordId,\r\n context.requestContext.app.config?.cocacolaRefinerRecordId,\r\n context.requestContext.app.config?.bamaRefinerRecordId,\r\n context.requestContext.app.config?.dutyFreeSugarRefinerRecordId,\r\n context.requestContext.app.config?.norturaRefinerRecordId\r\n ];\r\n\r\n for (const attributeRecordId of attributeRecordIds) {\r\n const id = Number(attributeRecordId);\r\n\r\n // Make sure it's a number and above 0\r\n if (!isNaN(id) && id > 0) {\r\n await addAttributeRefiner(context, customerAttributes, searchCriteriaInput, id);\r\n }\r\n }\r\n\r\n const transitRefiner = Number(context.requestContext.app.config?.transitRefinerRecordId);\r\n\r\n if (!isNaN(transitRefiner) && transitRefiner > 0) {\r\n await addAttributeRefinerKeepExisting(context, customerAttributes, searchCriteriaInput, transitRefiner);\r\n }\r\n\r\n const forsvaretRefiner = await getForsvaretRefiner(context, customerAttributes);\r\n\r\n if (forsvaretRefiner) {\r\n searchCriteriaInput.Refinement!.push(forsvaretRefiner);\r\n }\r\n\r\n const svalbardRefiner = await getSvalbardRefiner(context, customerAttributes);\r\n\r\n if (svalbardRefiner) {\r\n searchCriteriaInput.Refinement!.push(svalbardRefiner);\r\n }\r\n}\r\n\r\nexport async function getAllAttributeRefiners(context: IActionContext) {\r\n const godmode = isGodmodeEnabled(context);\r\n\r\n if (godmode) {\r\n return [];\r\n }\r\n\r\n let customerAttributes: CustomerAttribute[] | undefined = [];\r\n\r\n if (context.requestContext.user.isAuthenticated) {\r\n const { apiSettings, user: { customerAccountNumber } } = context.requestContext;\r\n const customer = await getOrganizationCustomer(new GetOrganizationCustomerInput(apiSettings, customerAccountNumber!), context);\r\n customerAttributes = customer.Attributes;\r\n }\r\n\r\n const attributeRecordIds: string[] = [\r\n context.requestContext.app.config?.transitRefinerRecordId,\r\n context.requestContext.app.config?.tobaccoRefinerRecordId,\r\n context.requestContext.app.config?.cocacolaRefinerRecordId,\r\n context.requestContext.app.config?.bamaRefinerRecordId,\r\n context.requestContext.app.config?.dutyFreeSugarRefinerRecordId,\r\n context.requestContext.app.config?.norturaRefinerRecordId\r\n ];\r\n\r\n const result: ProductRefinerValue[] = [];\r\n\r\n for (const attributeRecordId of attributeRecordIds) {\r\n const id = Number(attributeRecordId);\r\n\r\n // Make sure it's a number and above 0\r\n if (!isNaN(id) && id > 0) {\r\n const refiners = await getAttributeRefiners(context, customerAttributes, id);\r\n result.push(...refiners);\r\n }\r\n }\r\n\r\n const forsvaretRefiner = await getForsvaretRefiner(context, customerAttributes);\r\n\r\n if (forsvaretRefiner) {\r\n result.push(forsvaretRefiner);\r\n }\r\n\r\n const svalbardRefiner = await getSvalbardRefiner(context, customerAttributes);\r\n\r\n if (svalbardRefiner) {\r\n result.push(svalbardRefiner);\r\n }\r\n\r\n return result;\r\n}","/*!\r\n * Copyright (c) Microsoft Corporation.\r\n * All rights reserved. See LICENSE in the project root for license information.\r\n */\r\n\r\n/* eslint-disable no-duplicate-imports */\r\nimport MsDyn365, { IRequestContext } from '@msdyn365-commerce/core';\r\nimport { ProductRefinerValue, SortColumn } from '@msdyn365-commerce/retail-proxy';\r\n\r\n/**\r\n * Refiner Compression:\r\n * Refiners contains a non-trivial amount of data that is required to successfully make\r\n * a refiner-based API call. To allow for deep-linking of refiners in the URL, refiner data\r\n * must be compressed so that URL max length is not exceeded. Refiners will be compressed into\r\n * the following array style index-based format:\r\n * [DataTypeValue, LeftValueBoundString, RefinerRecordId, RefinerSourceValue, RightValueBoundString, UnitText].\r\n */\r\nconst compressedRefinerKeys = [\r\n 'DataTypeValue',\r\n 'LeftValueBoundString',\r\n 'RefinerRecordId',\r\n 'RefinerSourceValue',\r\n 'RightValueBoundString',\r\n 'UnitText',\r\n // Added RowNumber to identify if custom range integer or API values option is selected\r\n 'RowNumber'\r\n];\r\n\r\n/**\r\n * Hydrates compressed refiner data from URL.\r\n * @param fullUrl The full URL of the page.\r\n * @param requestContext\r\n */\r\nexport const hydrateRefinersFromUrl = (requestContext: IRequestContext): ProductRefinerValue[] => {\r\n const compressedRefinerArray = parseQueryParam<(string | number)[][]>('refiners', requestContext);\r\n if (!compressedRefinerArray || compressedRefinerArray.length === 0) {\r\n return [];\r\n }\r\n\r\n return compressedRefinerArray\r\n .map(compressedRefiner => {\r\n try {\r\n const parsedRefiner: ProductRefinerValue = {};\r\n compressedRefinerKeys.forEach((refinerKey, index) => {\r\n parsedRefiner[refinerKey] = compressedRefiner[index];\r\n });\r\n return parsedRefiner;\r\n } catch {\r\n return undefined;\r\n }\r\n })\r\n .filter(Boolean);\r\n};\r\n\r\n/**\r\n * Compressed a list of refiners for use in URLs.\r\n * @param refiners The uncompressed refiners.\r\n */\r\nexport const compressRefiners = (refiners: ProductRefinerValue[]) => {\r\n const compressedRefiners: (string | number)[][] = [];\r\n\r\n refiners.forEach(refiner => {\r\n const compressedRefiner: (string | number)[] = [];\r\n compressedRefinerKeys.forEach(refinerKey => {\r\n compressedRefiner.push(refiner[refinerKey]);\r\n });\r\n compressedRefiners.push(compressedRefiner);\r\n });\r\n\r\n return compressedRefiners;\r\n};\r\n\r\n/**\r\n * Method which creates a URL contiaining serialized active refiners.\r\n * @param fullUrl The Current URL of the page.\r\n * @param refiners The refiners which should be added to the URL.\r\n * @param sortingColumns\r\n * @param skipCount\r\n */\r\nexport const buildListPageUrl = (fullUrl: URL, refiners?: ProductRefinerValue[], sortingColumns?: SortColumn[], skipCount?: number) => {\r\n // Refiner Change flow\r\n if (refiners !== undefined) {\r\n if (refiners.length === 0) {\r\n fullUrl.searchParams.delete('refiners');\r\n } else {\r\n const sortedRefiners = refiners.sort((first, second) =>\r\n first.RefinerRecordId && second.RefinerRecordId && first.RefinerRecordId > second.RefinerRecordId ? 1 : -1\r\n );\r\n fullUrl.searchParams.set('refiners', JSON.stringify(compressRefiners(sortedRefiners)));\r\n }\r\n\r\n // Adding or removing a refiner means we want to always load page 1\r\n fullUrl.searchParams.delete('skip');\r\n return fullUrl.href;\r\n }\r\n\r\n if (sortingColumns !== undefined) {\r\n if (sortingColumns.length === 0) {\r\n fullUrl.searchParams.delete('sorting');\r\n } else {\r\n fullUrl.searchParams.set('sorting', JSON.stringify(sortingColumns));\r\n }\r\n\r\n // Changing the sort means always load page 1\r\n fullUrl.searchParams.delete('skip');\r\n return fullUrl.href;\r\n }\r\n\r\n if (skipCount) {\r\n fullUrl.searchParams.set('skip', skipCount.toString());\r\n }\r\n\r\n return fullUrl.href;\r\n};\r\n\r\n/**\r\n * Parses a query param from the query object of the request context.\r\n * @param key The query parameter key.\r\n * @param requestContext The request context.\r\n */\r\nexport const parseQueryParam = (key: string, requestContext: IRequestContext): T | null => {\r\n if (requestContext.query && requestContext.query[key]) {\r\n // NOTE: Query seems to already be decoded\r\n //return JSON.parse(decodeURIComponent(requestContext.query[key]));\r\n\r\n return JSON.parse(requestContext.query[key]);\r\n }\r\n return null;\r\n};\r\n\r\n/**\r\n * Gets the current URL of the page from the request context.\r\n * @param requestContext The request context.\r\n */\r\nexport const getCurrentUrl = (requestContext: IRequestContext): URL => {\r\n if (MsDyn365.isBrowser) {\r\n return new URL(window.location.href);\r\n }\r\n\r\n // NOTE: Typing on requestURL is incorrect\r\n if (requestContext.url.requestUrl.href) {\r\n return new URL(requestContext.url.requestUrl.href);\r\n }\r\n return new URL((requestContext.url.requestUrl));\r\n};\r\n","/*!\r\n * Copyright (c) Microsoft Corporation.\r\n * All rights reserved. See LICENSE in the project root for license information.\r\n */\r\n\r\n/* eslint-disable no-duplicate-imports */\r\nimport { IProductRefinerHierarchy } from '@msdyn365-commerce/commerce-entities';\r\nimport { ProductRefinerValue } from '@msdyn365-commerce/retail-proxy';\r\nimport { getPayloadObject, getTelemetryAttributes, IPayLoad } from '@msdyn365-commerce-modules/utilities';\r\nimport classnames from 'classnames';\r\nimport { computed } from 'mobx';\r\nimport { observer } from 'mobx-react';\r\nimport * as React from 'react';\r\n\r\nimport { ProductListInventoryFilteringOptions } from '../actions';\r\nimport { IChoiceSummaryProps } from './choice-summary.props';\r\nimport { isBoolean, isMatchingRefinementCriterion, isRangeType } from './utilities';\r\nimport { decodeBase64String } from '../../../shared-utils/base64';\r\n\r\ninterface IRefinerMap {\r\n key: string,\r\n parent?:string\r\n value: ProductRefinerValue;\r\n}\r\ninterface IRefinerKey {\r\n key: string;\r\n parent?:string\r\n}\r\n\r\n/**\r\n * ChoiceSummary component.\r\n */\r\n@observer\r\nexport default class ChoiceSummary extends React.PureComponent {\r\n private readonly closeButtonGlyph: string = 'msi-close-btn';\r\n\r\n private readonly payLoad: IPayLoad;\r\n\r\n @computed get selectedRefinersMap(): IRefinerMap[] {\r\n let { selectedChoices } = this.props;\r\n const { channelInventoryConfigurationId, refinerHierarchy } = this.props;\r\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- app configs are of generic type\r\n if (this.props.context?.app.config.productListInventoryDisplay === ProductListInventoryFilteringOptions.HideOOS) {\r\n selectedChoices = selectedChoices.filter(choice => {\r\n const parent = refinerHierarchy?.find(\r\n (hierarchy: IProductRefinerHierarchy) =>\r\n !!hierarchy.Values.find((value: ProductRefinerValue) => isMatchingRefinementCriterion(value, choice))\r\n );\r\n return parent && parent.RecordId !== channelInventoryConfigurationId;\r\n });\r\n }\r\n return selectedChoices.map((selectedRefiner: ProductRefinerValue, index) => {\r\n const RefinerValue=this._getKeyForRefinerValue(selectedRefiner, index.toString());\r\n return {\r\n key: RefinerValue.key,\r\n parent:RefinerValue.parent,\r\n value: selectedRefiner\r\n } as IRefinerMap;\r\n });\r\n }\r\n\r\n constructor(props: Readonly) {\r\n super(props);\r\n this.payLoad = getPayloadObject('click', this.props.telemetryContent!, '');\r\n }\r\n\r\n public render(): JSX.Element {\r\n const { clearAllText, label, classNames, choiceAriaLabel, closeAriaLabel,yesLabel,noLabel } = this.props;\r\n const items = this.selectedRefinersMap;\r\n this.payLoad.contentAction.etext = clearAllText;\r\n const clearAllAttributes = getTelemetryAttributes(this.props.telemetryContent!, this.payLoad);\r\n return (\r\n
\r\n {items.length > 0 && label && {label}}\r\n
    \r\n {items.map((item: IRefinerMap) => {\r\n this.payLoad.contentAction.etext = item.key;\r\n const attribute = getTelemetryAttributes(this.props.telemetryContent!, this.payLoad);\r\n let LeftValueBoundString = item.value.LeftValueBoundString;\r\n if (item.value && isBoolean(item.value.DataTypeValue)) {\r\n LeftValueBoundString = LeftValueBoundString === '1' ? yesLabel : noLabel;\r\n } else if (Number(this.props.transitRefinerRecordId) === item.value.RefinerRecordId) {\r\n LeftValueBoundString = LeftValueBoundString === '1' ? yesLabel : noLabel;\r\n } else if (item.parent === 'Sperret for Svalbard') {\r\n LeftValueBoundString = LeftValueBoundString === '1' ? yesLabel : noLabel;\r\n }\r\n\r\n let labelText = item.parent;\r\n let valueText = LeftValueBoundString && item.value.LeftValueBoundLocalizedString === ''\r\n ? LeftValueBoundString\r\n : (item.value.LeftValueBoundLocalizedString ||\r\n item.value.LeftValueBoundLocalizedString === undefined) &&\r\n item.value.RefinerRecordId === 0\r\n ? item.key\r\n : LeftValueBoundString;\r\n\r\n if (labelText?.startsWith('{base64}:') && valueText) {\r\n labelText = labelText.replace('{base64}:', '');\r\n valueText = decodeBase64String(valueText);\r\n }\r\n\r\n return (\r\n
  • \r\n \r\n {item?.parent && {labelText}:}\r\n {valueText}\r\n \r\n \r\n
  • \r\n );\r\n })}\r\n
\r\n {items.length > 0 && clearAllText && (\r\n \r\n {clearAllText}\r\n \r\n )}\r\n
\r\n );\r\n }\r\n\r\n private _getKeyForRefinerValue(productRefinerValue: ProductRefinerValue, index: string): IRefinerKey {\r\n const { choiceFormat, choiceRangeValueFormat, refinerHierarchy, telemetry, refinerValues } = this.props;\r\n const overallFormat = choiceFormat || '{1}';\r\n const rangeFormat = choiceRangeValueFormat;\r\n let refinerName = '';\r\n if (refinerHierarchy && refinerHierarchy.find) {\r\n const parent = refinerHierarchy.find(\r\n (hierarchy: IProductRefinerHierarchy) =>\r\n !!hierarchy.Values.find((value: ProductRefinerValue) => isMatchingRefinementCriterion(value, productRefinerValue))\r\n );\r\n\r\n if (!parent) {\r\n telemetry.warning('[choice-summary] could not find parent of selected refiner value');\r\n } else {\r\n refinerName = parent.KeyName || '';\r\n }\r\n }\r\n let refinerValueName: string;\r\n if (isRangeType(productRefinerValue.DataTypeValue)) {\r\n refinerValueName = rangeFormat\r\n .replace('{0}', this._formatPrice(productRefinerValue.LeftValueBoundString, productRefinerValue.UnitText))\r\n .replace('{1}', this._formatPrice(productRefinerValue.RightValueBoundString, productRefinerValue.UnitText));\r\n } else if (productRefinerValue.RefinerRecordId === 0) {\r\n const filterValue = refinerValues?.Values.find(\r\n refiner => refiner.LeftValueBoundString === productRefinerValue.LeftValueBoundString\r\n );\r\n refinerValueName = (filterValue ? filterValue.LeftValueBoundLocalizedString : productRefinerValue.LeftValueBoundString) || '';\r\n } else {\r\n refinerValueName = productRefinerValue.LeftValueBoundLocalizedString || productRefinerValue.LeftValueBoundString || '';\r\n }\r\n if (refinerName === 'Rating' || refinerName === 'Price' || refinerName === 'Pris') {\r\n return {\r\n key: overallFormat.replace('{0}', refinerName).replace('{1}', `${refinerValueName}`),\r\n parent:refinerName\r\n };\r\n }\r\n\r\n return {\r\n key: overallFormat.replace('{0}', refinerName).replace('{1}', `${refinerValueName}_${refinerName}_${index}`),\r\n parent:refinerName\r\n };\r\n }\r\n\r\n private _formatPrice(amount: string | undefined, currency: string | undefined): string {\r\n if (!amount || !currency) {\r\n this.props.telemetry.trace('[choice-summary] could not format price');\r\n return amount || '';\r\n }\r\n let result = amount;\r\n\r\n try {\r\n result = this.props.context!.cultureFormatter.formatCurrency(Number(amount), currency);\r\n } catch (error) {\r\n this.props.telemetry.warning(`Failed to format price for ${result}: ${error}`);\r\n }\r\n\r\n return result;\r\n }\r\n\r\n private readonly _onClick = (e: React.MouseEvent): void => {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n\r\n const target = e.currentTarget as HTMLElement;\r\n const clearAll = target.getAttribute('class')!.includes('choice-summary__clear-all');\r\n const selectedRefiner = clearAll ? undefined : this._getSelectedRefinerChoice(target);\r\n\r\n if (this.props.onChoiceClicked) {\r\n this.props.onChoiceClicked({\r\n clearAll,\r\n itemClicked: target,\r\n choiceClicked: selectedRefiner,\r\n nextItemToFocus: target.nextSibling as HTMLElement\r\n });\r\n }\r\n };\r\n\r\n private _getSelectedRefinerChoice(itemClicked: HTMLElement): ProductRefinerValue | undefined {\r\n const result = this.selectedRefinersMap.find(selected => itemClicked.id === selected.key);\r\n return (result && result.value) || undefined;\r\n }\r\n}\r\n","/*!\r\n * Copyright (c) Microsoft Corporation.\r\n * All rights reserved. See LICENSE in the project root for license information.\r\n */\r\n\r\n/* eslint-disable no-duplicate-imports */\r\nimport * as React from 'react';\r\n\r\ninterface IErrorMessage {\r\n text?: string;\r\n}\r\n\r\nexport const ErrorMessage: React.FC = ({ text }) => {\r\n return (\r\n \r\n
\r\n {` `}\r\n {text}\r\n {` `}\r\n
\r\n
\r\n );\r\n};\r\n","/*!\r\n * Copyright (c) Microsoft Corporation.\r\n * All rights reserved. See LICENSE in the project root for license information.\r\n */\r\n\r\n/* eslint-disable no-duplicate-imports */\r\nimport { ICoreContext, IGridSettings, IImageData, IImageSettings, Image, IRequestContext } from '@msdyn365-commerce/core';\r\nimport { SimpleProduct } from '@msdyn365-commerce/retail-proxy';\r\nimport { getFallbackImageUrl, getProductPageUrlSync } from '@msdyn365-commerce-modules/retail-actions';\r\nimport { getPayloadObject, getTelemetryAttributes, ITelemetryContent, onTelemetryClick } from '@msdyn365-commerce-modules/utilities';\r\nimport * as React from 'react';\r\n\r\nimport { IDlvrySearchResultContainerResources } from '../dlvry-search-result-container.props.autogenerated';\r\n\r\n// Import { IComponent, IComponentProps, ICoreContext, IGridSettings, IImageData, IImageSettings, Image, msdyn365Commerce } from '@msdyn365-commerce/core';\r\n\r\ninterface IFeatureSearchResultItem {\r\n product: SimpleProduct | null;\r\n context: ICoreContext;\r\n resources: IDlvrySearchResultContainerResources;\r\n imageSettings?: IImageSettings;\r\n moduleType: string;\r\n moduleId: string;\r\n telemetryContent?: ITelemetryContent;\r\n recommendation?: string;\r\n}\r\n\r\nexport const FeatureSearchResultItem: React.FC = ({\r\n product,\r\n context,\r\n imageSettings,\r\n resources,\r\n telemetryContent,\r\n recommendation\r\n}) => {\r\n if (product === null) {\r\n return null;\r\n }\r\n\r\n const productName = product.Name;\r\n const productRecordId = product && product.RecordId ? product.RecordId : 0;\r\n const productUrl = getProductPageUrlSync(product.Name || '', productRecordId, context && context.actionContext, undefined);\r\n const fallbackImage = getFallbackImageUrl(\r\n product.ItemId,\r\n context.actionContext.requestContext.apiSettings,\r\n context.request.app?.config?.OmniChannelMedia\r\n );\r\n const heading =\r\n recommendation && recommendation === 'descriptions' ? resources.featureSimilarDescriptionTitle : resources.featureSimilarLooksTitle;\r\n\r\n // Construct telemetry attribute to render\r\n const payLoad = getPayloadObject('click', telemetryContent!, productName!, productRecordId.toString());\r\n\r\n const attribute = getTelemetryAttributes(telemetryContent!, payLoad);\r\n return (\r\n
\r\n \r\n
\r\n {renderProductPlacementImage(\r\n imageSettings,\r\n context.request.gridSettings,\r\n product.PrimaryImageUrl,\r\n product.Name,\r\n fallbackImage,\r\n context.actionContext.requestContext\r\n )}\r\n
\r\n \r\n
\r\n

{heading}

\r\n {renderProductTitle(product?.Name)}\r\n
\r\n
\r\n );\r\n};\r\n\r\nfunction renderProductPlacementImage(\r\n imageSettings?: IImageSettings,\r\n gridSettings?: IGridSettings,\r\n imageUrl?: string,\r\n altText?: string,\r\n fallbackImage?: string,\r\n context?: IRequestContext\r\n): JSX.Element | null {\r\n if (!imageUrl || !gridSettings || !imageSettings) {\r\n return null;\r\n }\r\n const img: IImageData = {\r\n src: imageUrl,\r\n altText: altText ? altText : ''\r\n };\r\n const imageProps = {\r\n gridSettings,\r\n imageSettings,\r\n fallBackSrc: fallbackImage\r\n };\r\n return ;\r\n}\r\n\r\nfunction renderProductTitle(title?: string): JSX.Element | null {\r\n return

{title}

;\r\n}\r\n","/*!\r\n * Copyright (c) Microsoft Corporation.\r\n * All rights reserved. See LICENSE in the project root for license information.\r\n */\r\n\r\n/* eslint-disable no-duplicate-imports */\r\nimport * as React from 'react';\r\n\r\ninterface ILink {\r\n className?: string;\r\n text?: string;\r\n href?: string;\r\n ariaLabel?: string;\r\n}\r\n\r\nexport const Link: React.FC = ({ text, className, href, ariaLabel }) => (\r\n \r\n {' '}\r\n {text}{' '}\r\n \r\n);\r\n","/*!\r\n * Copyright (c) Microsoft Corporation.\r\n * All rights reserved. See LICENSE in the project root for license information.\r\n */\r\n\r\n/* eslint-disable no-duplicate-imports */\r\nimport { Button, Modal, ModalBody, ModalFooter, ModalHeader } from '@msdyn365-commerce-modules/utilities';\r\nimport React from 'react';\r\n\r\nexport interface ISearchResultModalViewProps {\r\n modal: React.ReactElement;\r\n modalHeader: React.ReactElement;\r\n modalFooter: React.ReactElement;\r\n modalBody: React.ReactElement;\r\n}\r\n\r\ninterface IModalToggleProps {\r\n innerRef: React.RefObject | undefined;\r\n id: string;\r\n text: string;\r\n ariaLabel: string;\r\n onClick(): void;\r\n}\r\n\r\nexport interface ISearchResultModalResources {\r\n modalTitle: string;\r\n modalCloseButtonText: string;\r\n}\r\n\r\nexport interface ISearchResultModalProps {\r\n resources: ISearchResultModalResources;\r\n isOpen: boolean;\r\n returnRef: React.RefObject | undefined;\r\n onModalToggle(): void;\r\n}\r\n\r\nexport const ModalToggle: React.FC = (props: IModalToggleProps) => {\r\n const { text, onClick, ariaLabel, innerRef, id } = props;\r\n return (\r\n \r\n );\r\n};\r\n\r\nexport const SearchResultModal = (props: ISearchResultModalProps): ISearchResultModalViewProps => {\r\n return {\r\n modal: modalNode(props),\r\n modalHeader: modalHeaderNode(props),\r\n modalFooter: modalFooterNode(props),\r\n modalBody: \r\n };\r\n};\r\n\r\nconst modalNode = (props: ISearchResultModalProps) => {\r\n return (\r\n \r\n );\r\n};\r\n\r\nconst modalHeaderNode = (props: ISearchResultModalProps) => {\r\n return {props.resources.modalTitle};\r\n};\r\n\r\nconst modalFooterNode = (props: ISearchResultModalProps) => {\r\n return (\r\n \r\n \r\n \r\n );\r\n};\r\n","/*!\r\n * Copyright (c) Microsoft Corporation.\r\n * All rights reserved. See LICENSE in the project root for license information.\r\n */\r\n\r\nimport { IProductsDimensionsAvailabilities } from '@msdyn365-commerce/commerce-entities';\r\nimport { IPriceComponentResources } from '@msdyn365-commerce/components';\r\nimport { ICoreContext, IImageSettings } from '@msdyn365-commerce/core';\r\nimport { CommerceList, Customer, ProductList, ProductPrice, ProductSearchResult, SimpleProduct, UnitOfMeasureConversion } from '@msdyn365-commerce/retail-proxy';\r\nimport {\r\n ArrayExtensions,\r\n ProductInput,\r\n getSimpleProducts,\r\n GetCustomerInput,\r\n getCustomer,\r\n getWishlistByCustomerId,\r\n buildWishlistLine,\r\n OrderTemplate,\r\n QueryResultSettingsProxy,\r\n GetOrderTemplatesInput,\r\n getOrderTemplates\r\n} from '@msdyn365-commerce-modules/retail-actions';\r\nimport { ICartState } from '@msdyn365-commerce/global-state';\r\nimport { ITelemetryContent } from '@msdyn365-commerce-modules/utilities';\r\nimport { addLinesAsync, createCommerceListAsync, createGetByCustomerInput, removeLinesAsync } from '@msdyn365-commerce/retail-proxy/dist/DataActions/CommerceListsDataActions.g';\r\nimport * as React from 'react';\r\nimport { ProductComponent } from '../../../themes/dlvry-adventureworks/views/components/product.component';\r\n\r\nimport { IDlvrySearchResultContainerResources } from '../dlvry-search-result-container.props.autogenerated';\r\nimport { toast, toasts } from '../../../components/toast/toast';\r\nimport PQueue from 'p-queue';\r\nimport { ValidateProductAccessResult } from '../../../shared-utils/validate-product-access';\r\nimport { IProductInventoryInformation } from '../../../components/common/product-inventory-utils';\r\nimport { onBuyHasAccessValidator } from '../../../shared-utils/attributes/on-buy-access-validator';\r\nimport { hasAgreementProducts } from '../../../shared-utils/agreement-product-utils';\r\n\r\nexport interface ProductSearchResultExt extends ProductSearchResult {\r\n Badge?: string;\r\n Brand?: string;\r\n Manufacturer?: string;\r\n PrefetchedPrice?: boolean;\r\n PriceFailed?: boolean;\r\n ProductPrice?: ProductPrice;\r\n Transit?: boolean;\r\n IsAgreementProduct?: boolean;\r\n TemperatureZone?: string;\r\n}\r\n\r\ninterface IProductSearchResultItems {\r\n cart: ICartState | undefined;\r\n products: ProductSearchResultExt[];\r\n simpleProducts: SimpleProduct[];\r\n customerInformation?: Customer;\r\n orgInformation?: Customer;\r\n orderTemplates?: OrderTemplate[];\r\n unitConversions?: UnitOfMeasureConversion[];\r\n wishlists: CommerceList[] | undefined;\r\n context: ICoreContext;\r\n config: { [key: string]: any };\r\n resources: IDlvrySearchResultContainerResources;\r\n imageSettings?: IImageSettings;\r\n moduleType: string;\r\n moduleId: string;\r\n allowBackNavigation?: boolean;\r\n telemetryContent: ITelemetryContent;\r\n quickviewSlot?: {} | null | undefined;\r\n productComparisonButton?: {} | null | undefined;\r\n channelInventoryConfigurationId?: number;\r\n isPriceMinMaxEnabled?: boolean;\r\n productsDimensionAvailabilities?: IProductsDimensionsAvailabilities[][];\r\n productInventoryStatus?: IProductInventoryInformation[];\r\n disableBuyButtons?: boolean;\r\n showPrices?: boolean;\r\n validatedProductAccess?: ValidateProductAccessResult[];\r\n productInventoryInformation?: IProductInventoryInformation[];\r\n}\r\n\r\n/**\r\n * Returns the product inventory label.\r\n * @param channelInventoryConfigurationId - The channel configuration Id.\r\n * @param product - The product.\r\n * @param productInventoryStatus\r\n * @returns The inventory label.\r\n */\r\nexport function getInventoryLabel(channelInventoryConfigurationId: number | undefined, product: ProductSearchResult, productInventoryStatus: IProductInventoryInformation[] | undefined): string | undefined {\r\n if (productInventoryStatus) {\r\n const shippingInventory = productInventoryStatus.find(shipping => shipping.ProductAvailableQuantity.ProductId === product.RecordId);\r\n if (shippingInventory && shippingInventory.StockLevelLabel) {\r\n return shippingInventory.StockLevelLabel;\r\n }\r\n }\r\n if (!channelInventoryConfigurationId || !ArrayExtensions.hasElements(product.AttributeValues)) {\r\n return undefined;\r\n }\r\n const inventoryAttribute = product.AttributeValues.find(attribute => attribute.RecordId === channelInventoryConfigurationId);\r\n if (inventoryAttribute) {\r\n return inventoryAttribute.TextValue;\r\n }\r\n return undefined;\r\n}\r\n\r\nasync function callAddWishlistLine(context: ICoreContext, productId: number, wishlistId: number, toastErrorHeader?: string): Promise {\r\n try {\r\n const customer = await getCustomerAccount(context);\r\n if (customer && customer.AccountNumber) {\r\n const createdCommerceList = await addLinesAsync({ callerContext: context.actionContext },\r\n wishlistId,\r\n [\r\n buildWishlistLine(productId, customer.AccountNumber, wishlistId)\r\n ]);\r\n context.actionContext.update(createGetByCustomerInput({}, null), [createdCommerceList]);\r\n }\r\n } catch (err) {\r\n const error = err as unknown as any;\r\n const footer = error?.data?.CorrelationId ? `Correlation Id: ${error?.data?.CorrelationId}` : undefined;\r\n toasts.error(toastErrorHeader, error, { footer: footer });\r\n }\r\n}\r\n\r\nasync function getCustomerAccount(context: ICoreContext) {\r\n const customerInput = new GetCustomerInput(context.actionContext.requestContext.apiSettings);\r\n return getCustomer(customerInput, context.actionContext);\r\n}\r\n\r\nfunction getWishlistLineIdFromProductId(wishlists: CommerceList[] | undefined, productId: number | undefined): number | null {\r\n if (!wishlists ||\r\n !productId ||\r\n wishlists.length === 0 ||\r\n !wishlists[0].CommerceListLines ||\r\n wishlists[0].CommerceListLines.length === 0) {\r\n return null;\r\n }\r\n\r\n const foundWishlistItem = wishlists[0].CommerceListLines.filter(commerceListLine => {\r\n return commerceListLine.ProductId === productId;\r\n });\r\n\r\n if (foundWishlistItem && foundWishlistItem[0].LineId) {\r\n return foundWishlistItem[0].LineId;\r\n }\r\n return null;\r\n}\r\n\r\nasync function moveItemToWishlist(context: ICoreContext, resources: IDlvrySearchResultContainerResources, product: ProductSearchResult, defaultWishlistName: string): Promise {\r\n if (!context || !product || !context.request.user.catalogId) {\r\n return Promise.resolve();\r\n }\r\n\r\n const productInputs: ProductInput[] = [];\r\n const productInput = new ProductInput(\r\n product.RecordId,\r\n context.request.apiSettings,\r\n undefined, undefined,\r\n context.request,\r\n +context.request.user.catalogId\r\n );\r\n productInputs.push(productInput);\r\n\r\n const simpleProduct = await getSimpleProducts(productInputs, context.actionContext);\r\n\r\n if (context.request.user.isAuthenticated && simpleProduct && simpleProduct.length >= 0) {\r\n const customer = await getCustomerAccount(context);\r\n const wishlists = await getWishlistByCustomerId(createGetByCustomerInput({}, null), context.actionContext);\r\n if (!wishlists || wishlists.length === 0) {\r\n const wishlistName = defaultWishlistName;\r\n if (customer && customer.AccountNumber) {\r\n const listData: CommerceList = {\r\n CustomerId: customer.AccountNumber,\r\n Name: wishlistName,\r\n CommerceListTypeValue: 1,\r\n Id: 0\r\n };\r\n try {\r\n const commerceList = await createCommerceListAsync({\r\n callerContext: context.actionContext\r\n },\r\n listData);\r\n await callAddWishlistLine(context, simpleProduct[0].RecordId, commerceList.Id, resources.toastErrorHeader);\r\n } catch (err) {\r\n const error = err as unknown as any;\r\n const footer = error?.data?.CorrelationId ? `Correlation Id: ${error?.data?.CorrelationId}` : undefined;\r\n toasts.error(resources.toastErrorHeader, error, { footer });\r\n }\r\n }\r\n } else {\r\n await callAddWishlistLine(context, simpleProduct[0].RecordId, wishlists[0].Id, resources.toastErrorHeader);\r\n\r\n toast({\r\n text: resources.addedProductToWishlistText.replace('{productName}', simpleProduct[0].Name || ''),\r\n type: 'success',\r\n autoClose: 3000,\r\n position: 'bottom-right',\r\n canClose: true,\r\n showProgress: false\r\n });\r\n }\r\n }\r\n}\r\n\r\nfunction removeItemFromWishlist(context: ICoreContext, wishlists: CommerceList[] | undefined, product: ProductSearchResult, toastErrorHeader?: string): void {\r\n const wishlistLineId = getWishlistLineIdFromProductId(wishlists, product.RecordId);\r\n if (wishlists && wishlists[0] && wishlistLineId) {\r\n removeLinesAsync({ callerContext: context.actionContext }, wishlists[0].Id, [{ LineId: wishlistLineId }])\r\n .then(commerceList => {\r\n const newWishlists = [\r\n ...wishlists\r\n ];\r\n newWishlists[0] = commerceList;\r\n context.actionContext.update(createGetByCustomerInput({}, null), newWishlists);\r\n })\r\n .catch(error => {\r\n const footer = error?.data?.CorrelationId ? `Correlation Id: ${error?.data?.CorrelationId}` : undefined;\r\n toasts.error(toastErrorHeader, error, { footer });\r\n });\r\n }\r\n}\r\n\r\nfunction getWishlistButton(context: ICoreContext, resources: IDlvrySearchResultContainerResources, product: ProductSearchResult, wishlists: CommerceList[] | undefined, defaultWishlistName: string) {\r\n const isWishlisted = wishlists && wishlists.length > 0 && wishlists[0].CommerceListLines?.find(x => x.ProductId === product.RecordId) ? true : false;\r\n let className = 'btn-add-to-wishlist';\r\n\r\n if (isWishlisted) {\r\n className += ' is-wishlisted';\r\n }\r\n\r\n return (\r\n
\r\n {\r\n if (!isWishlisted) {\r\n await moveItemToWishlist(context, resources, product, defaultWishlistName);\r\n } else {\r\n removeItemFromWishlist(context, wishlists, product, resources.toastErrorHeader);\r\n }\r\n }\r\n }>\r\n {!isWishlisted ? resources.addToWishlistButtonText : resources.removeFromWishlistButtonText}\r\n \r\n
\r\n );\r\n}\r\n\r\nexport const ProductSearchResultItems: React.FC = ({\r\n cart,\r\n products,\r\n simpleProducts,\r\n customerInformation,\r\n orgInformation,\r\n orderTemplates,\r\n unitConversions,\r\n wishlists,\r\n context,\r\n config,\r\n imageSettings,\r\n resources,\r\n moduleType,\r\n moduleId,\r\n allowBackNavigation,\r\n telemetryContent,\r\n quickviewSlot,\r\n productComparisonButton,\r\n channelInventoryConfigurationId,\r\n isPriceMinMaxEnabled,\r\n productsDimensionAvailabilities,\r\n productInventoryStatus,\r\n validatedProductAccess,\r\n disableBuyButtons,\r\n showPrices,\r\n productInventoryInformation\r\n}) => {\r\n const [orderTemplatesState, setOrderTemplatesState] = React.useState(undefined);\r\n const cartQueue = React.useMemo(() => new PQueue({ concurrency: 1 }), []);\r\n\r\n const updateOrderTemplatesAsync = async (newOrderTemplate?: ProductList) => {\r\n let newOrderTemplates;\r\n\r\n if (newOrderTemplate) {\r\n newOrderTemplates = [...(orderTemplatesState ? orderTemplatesState : orderTemplates ? orderTemplates : [])];\r\n\r\n // Add new order template if it doesn't exist\r\n if (newOrderTemplates.every(x => x.productList.Id !== newOrderTemplate.Id)) {\r\n newOrderTemplates.splice(0, 0, new OrderTemplate(newOrderTemplate, [], 0));\r\n }\r\n } else {\r\n // Refresh order templates incase new order template was created\r\n const queryResultSettings = QueryResultSettingsProxy.fromInputData({\r\n requestContext: context.request,\r\n config: config\r\n }).QueryResultSettings;\r\n const input = new GetOrderTemplatesInput('', queryResultSettings);\r\n newOrderTemplates = (await getOrderTemplates(input, context.actionContext)).map(x => new OrderTemplate(x, [], 0));\r\n }\r\n\r\n setOrderTemplatesState(newOrderTemplates);\r\n return newOrderTemplates;\r\n };\r\n\r\n const retrieveOrderTemplates = async () => {\r\n return orderTemplates ? orderTemplates : orderTemplatesState ? orderTemplatesState : updateOrderTemplatesAsync();\r\n };\r\n\r\n const priceResources: IPriceComponentResources = {\r\n priceRangeSeparator: resources.priceRangeSeparator\r\n };\r\n return (\r\n
    \r\n {products.map((product: ProductSearchResultExt, index: number) => (\r\n
  • \r\n x.RecordId === product.RecordId),\r\n customerInformation,\r\n unitConversions: unitConversions?.filter(x => x.ProductRecordId === product.RecordId)\r\n }}\r\n cartQueue={cartQueue}\r\n buyAlwaysAdd\r\n showAgreementProduct={hasAgreementProducts(context, orgInformation)}\r\n retrieveOrderTemplates={retrieveOrderTemplates}\r\n onUpdateOrderTemplates={updateOrderTemplatesAsync}\r\n quickViewButton={quickviewSlot}\r\n productComparisonButton={productComparisonButton}\r\n wishlistButton={getWishlistButton(context, resources, product, wishlists, resources.defaultWishlistName)}\r\n inventoryLabel={getInventoryLabel(channelInventoryConfigurationId, product,productInventoryStatus)}\r\n inventoryStatus={productInventoryInformation?.find(x => x.ProductAvailableQuantity.ProductId === product.RecordId)}\r\n isPriceMinMaxEnabled={isPriceMinMaxEnabled}\r\n disableBuyButton={disableBuyButtons}\r\n showPrice={showPrices}\r\n userHasAccess={validatedProductAccess?.find(x => x.RecordId === product.RecordId)?.HasAccess}\r\n priceResources={priceResources}\r\n swatchItemAriaLabel={resources.swatchItemAriaLabel}\r\n addToCartText={resources.addToCartText}\r\n updateCartText={resources.updateCartText}\r\n removeFromCartText={resources.removeFromCartText}\r\n outOfStockText={resources.outOfStockText}\r\n priceErrorText={resources.priceErrorText}\r\n toastStrings={{\r\n errorHeader: resources.toastErrorHeader,\r\n productsAddedToCart: resources.productsAddedToCart,\r\n productsRemovedFromCart: resources.productsRemovedFromCart,\r\n productsUpdatedInCart: resources.productsUpdatedInCart,\r\n goToCart: resources.toastGoToCart,\r\n noAccessToProduct: resources.toastNoAccessToProduct\r\n }}\r\n inCartTooltipText={resources.inCartTooltipText}\r\n transitTooltip={resources.transitTooltip}\r\n agreementProductTooltip={resources.agreementProductTooltip}\r\n dimensionAvailabilities={productsDimensionAvailabilities?.find(\r\n dimensionAvailability =>\r\n ArrayExtensions.hasElements(dimensionAvailability) &&\r\n dimensionAvailability[0].masterProductId === product.MasterProductId\r\n )}\r\n addToOrderTemplateResources={{\r\n addToOrderTemplateHeader: resources.addToOrderTemplateHeader,\r\n noOrderTemplatesMessage: resources.noOrderTemplatesMessage,\r\n noOrderTemplatesDescription: resources.noOrderTemplatesDescription,\r\n createAnOrderTemplateButtonText: resources.createAnOrderTemplateButtonText,\r\n createNewOrderTemplateButtonText: resources.createNewOrderTemplateButtonText,\r\n cancelOrderTemplateCreationButtonText: resources.cancelOrderTemplateCreationButtonText,\r\n selectTemplatesText: resources.selectTemplatesText,\r\n addToTemplateButtonText: resources.addToTemplateButtonText,\r\n lineItemsText: resources.lineItemsText,\r\n createOrderTemplateHeader: resources.createOrderTemplateHeader,\r\n orderTemplateTitle: resources.orderTemplateTitle,\r\n orderTemplateNameAriaLabel: resources.orderTemplateNameAriaLabel,\r\n createOrderTemplateDescription: resources.createOrderTemplateDescription,\r\n defaultOrderTemplateName: resources.defaultOrderTemplateName,\r\n createOrderTemplateButtonText: resources.createOrderTemplateButtonText,\r\n cancelNewOrderTemplateCreationButtonText: resources.cancelNewOrderTemplateCreationButtonText,\r\n viewOrderTemplateButtonText: resources.viewOrderTemplateButtonText,\r\n continueShoppingButtonText: resources.continueShoppingButtonText,\r\n itemAddedToOrderTemplateHeaderItemOneText: resources.itemAddedToOrderTemplateHeaderItemOneText,\r\n itemAddedToOrderTemplateHeaderItemFormatText: resources.itemAddedToOrderTemplateHeaderItemFormatText,\r\n itemAddedToOrderTemplateHeaderMessageText: resources.itemAddedToOrderTemplateHeaderMessageText,\r\n priceFree: resources.priceFree,\r\n originalPriceText: resources.originalPriceText,\r\n currentPriceText: resources.currentPriceText,\r\n duplicatedProductsHeader: resources.duplicatedProductsHeader,\r\n duplicatedProductsDescription: resources.duplicatedProductsDescription,\r\n updateQuantityButtonText: resources.updateQuantityButtonText,\r\n cancelDuplicateItemsButtonText: resources.cancelDuplicateItemsButtonText,\r\n addToOrderTemplateButtonText: resources.addToOrderTemplateButtonText,\r\n addToOrderTemplateButtonTooltip: resources.addToOrderTemplateButtonTooltip\r\n }}\r\n onBuyValidate={(product) => onBuyHasAccessValidator(\r\n context,\r\n customerInformation,\r\n product,\r\n resources.toastNoAccessToProduct\r\n )}\r\n />\r\n
  • \r\n ))}\r\n
\r\n );\r\n};\r\n","/*!\r\n * Copyright (c) Microsoft Corporation.\r\n * All rights reserved. See LICENSE in the project root for license information.\r\n */\r\n\r\n/* eslint-disable no-duplicate-imports */\r\nimport * as React from 'react';\r\n\r\ninterface ISeparator {\r\n separator: string;\r\n}\r\n\r\nexport const Separator: React.FC = ({ separator }) => (\r\n \r\n {` `}\r\n {separator}\r\n {` `}\r\n \r\n);\r\n","/*!\r\n * Copyright (c) Microsoft Corporation.\r\n * All rights reserved. See LICENSE in the project root for license information.\r\n */\r\n\r\n/* eslint-disable no-duplicate-imports */\r\nimport * as React from 'react';\r\n\r\ninterface ITitle {\r\n className: string;\r\n text: string;\r\n}\r\n\r\nexport const Title: React.FC = ({ text, className }) => (\r\n \r\n {` `}\r\n {text}\r\n {` `}\r\n \r\n);\r\n","/*!\r\n * Copyright (c) Microsoft Corporation.\r\n * All rights reserved. See LICENSE in the project root for license information.\r\n */\r\n\r\nimport { observer } from 'mobx-react';\r\nimport * as React from 'react';\r\n\r\nimport { isUndefined } from 'lodash';\r\nimport { ProductRefinerValue } from '@msdyn365-commerce/retail-proxy';\r\nimport { Button } from '@msdyn365-commerce-modules/utilities';\r\nimport { IRefineItemState } from './refine-item';\r\nimport { isCustomRangeTypeIntegerSelected } from './utilities';\r\nimport { IProductRefinerHierarchy } from '@msdyn365-commerce/commerce-entities';\r\nimport { IRefineItemCommonProps } from './refine-item.props.common';\r\nimport { IRefineItemToggleNotification } from './refine-item-toggle-notification';\r\n\r\nexport type RangeRefineItemInputType = 'slider' | 'input';\r\n\r\n/**\r\n * Range refine item properties.\r\n */\r\nexport interface IRangeRefineItemInputProps {\r\n parentProductRefinerHierarchy: IProductRefinerHierarchy;\r\n selectedRefinementCriterion: ProductRefinerValue | undefined;\r\n refineItemCommonProps: IRefineItemCommonProps;\r\n isDisabled: boolean;\r\n rangeType: RangeRefineItemInputType;\r\n\r\n /**\r\n * The telemetry content\r\n */\r\n onToggle(notfication: Readonly): void;\r\n}\r\n\r\n/**\r\n * Range refine item state.\r\n */\r\nexport interface IRangeRefineItemInputState extends IRefineItemState {\r\n validationErrorMin: string | undefined;\r\n validationErrorMax: string | undefined;\r\n selectedMin: string | undefined;\r\n selectedMax: string | undefined;\r\n invalidData: boolean | undefined;\r\n}\r\n\r\n/**\r\n * RangeRefineItem component (controlled by RefineSubmenu).\r\n */\r\n@observer\r\nexport default class RangeRefineItemInput extends React.Component {\r\n private readonly _formattedPriceReverseLookup: Map = new Map();\r\n\r\n private readonly minInput: React.RefObject;\r\n\r\n private readonly maxInput: React.RefObject;\r\n\r\n public constructor(props: IRangeRefineItemInputProps) {\r\n super(props);\r\n this._changeMinInputRange = this._changeMinInputRange.bind(this);\r\n this._changeMaxInputRange = this._changeMaxInputRange.bind(this);\r\n this._applyCustom = this._applyCustom.bind(this);\r\n\r\n this.minInput = React.createRef();\r\n this.maxInput = React.createRef();\r\n let initialMin = '';\r\n let initialMax = '';\r\n const { selectedRefinementCriterion, parentProductRefinerHierarchy } = this.props;\r\n if (selectedRefinementCriterion) {\r\n initialMin = isCustomRangeTypeIntegerSelected(selectedRefinementCriterion, parentProductRefinerHierarchy)\r\n ? ''\r\n : selectedRefinementCriterion?.LeftValueBoundString || '';\r\n initialMax = isCustomRangeTypeIntegerSelected(selectedRefinementCriterion, parentProductRefinerHierarchy)\r\n ? ''\r\n : selectedRefinementCriterion?.RightValueBoundString || '';\r\n }\r\n\r\n this.state = {\r\n validationErrorMin: undefined,\r\n validationErrorMax: undefined,\r\n selectedMin: initialMin,\r\n selectedMax: initialMax,\r\n invalidData: !(initialMin && initialMax),\r\n isChecked: false\r\n };\r\n }\r\n\r\n public shouldComponentUpdate(nextProps: IRangeRefineItemInputProps, nextState: IRangeRefineItemInputState): boolean {\r\n if (this.state === nextState && this.props === nextProps) {\r\n return false;\r\n }\r\n nextState.invalidData = !(nextState.selectedMin && nextState.selectedMax);\r\n return true;\r\n }\r\n\r\n public componentDidUpdate(previousProps: IRangeRefineItemInputProps): void {\r\n if (previousProps !== this.props) {\r\n this.updateInputRangerProps();\r\n }\r\n }\r\n\r\n public render(): JSX.Element | undefined {\r\n if (this.props.rangeType === 'input') {\r\n return this._renderInputFields();\r\n }\r\n return undefined;\r\n }\r\n\r\n // /**\r\n // * Function to update slider props.\r\n // */\r\n private updateInputRangerProps(): void {\r\n const selectedMin = !isUndefined(this.props.selectedRefinementCriterion?.RowNumber)\r\n ? ''\r\n : this.props.selectedRefinementCriterion?.LeftValueBoundString;\r\n const selectedMax = !isUndefined(this.props.selectedRefinementCriterion?.RowNumber)\r\n ? ''\r\n : this.props.selectedRefinementCriterion?.RightValueBoundString;\r\n this.setState({ selectedMin, selectedMax });\r\n }\r\n\r\n private _renderInputFields(): JSX.Element | undefined {\r\n const { isDisabled, parentProductRefinerHierarchy, refineItemCommonProps } = this.props;\r\n const { validationErrorMin, validationErrorMax } = this.state;\r\n\r\n const rangeAriaLabel = (refineItemCommonProps.rangeNameFormat || '{0}').replace('{0}', parentProductRefinerHierarchy.KeyName || '');\r\n const formAttrs = {\r\n 'aria-label': rangeAriaLabel,\r\n 'aria-disabled': isDisabled\r\n };\r\n\r\n const minInputClassName = `ms-refine-submenu__input-range refine-submenu__input-range-min ${\r\n validationErrorMin ? 'refine-submenu__input-range--error' : ''\r\n }`;\r\n const maxInputClassName = `ms-refine-submenu__input-range refine-submenu__input-range-max ${\r\n validationErrorMax ? 'refine-submenu__input-range--error' : ''\r\n }`;\r\n return (\r\n
  • \r\n
    \r\n
    \r\n \r\n {' - '}\r\n \r\n {validationErrorMin && (\r\n \r\n {validationErrorMin}\r\n \r\n )}\r\n {validationErrorMax && validationErrorMin !== validationErrorMax && (\r\n \r\n {validationErrorMax}\r\n \r\n )}\r\n
    \r\n
    \r\n \r\n
    \r\n
    \r\n
  • \r\n );\r\n }\r\n\r\n private _applyCustom(event: React.MouseEvent): void {\r\n const selectedMinValue = this._getInputWithoutFormatting(this.state.selectedMin || '');\r\n this.setState({\r\n selectedMin: selectedMinValue,\r\n minTouched: false\r\n });\r\n const minInput = Number(selectedMinValue);\r\n const { onToggle, parentProductRefinerHierarchy } = this.props;\r\n const max = this.state.selectedMax;\r\n\r\n const maxNum = max ? Number(max) : undefined;\r\n const productRefinerValue: ProductRefinerValue = {\r\n RefinerRecordId: parentProductRefinerHierarchy.Values[0].RefinerRecordId,\r\n LeftValueBoundString: this.state.selectedMin,\r\n RightValueBoundString: this.state.selectedMax,\r\n DataTypeValue: parentProductRefinerHierarchy.DataTypeValue,\r\n RefinerSourceValue: parentProductRefinerHierarchy.Values[0].RefinerSourceValue\r\n };\r\n\r\n if (this._validateRange(minInput, maxNum)) {\r\n onToggle({\r\n parentProductRefinerHierarchy,\r\n productRefinerValue,\r\n isSelecting: true\r\n });\r\n }\r\n }\r\n\r\n private _changeMinInputRange(event: React.ChangeEvent): void {\r\n this.setState({\r\n selectedMin: event.target.value.trim()\r\n });\r\n }\r\n\r\n private _changeMaxInputRange(event: React.ChangeEvent): void {\r\n this.setState({\r\n selectedMax: event.target.value.trim()\r\n });\r\n }\r\n\r\n private _validateRange(min: number, max: number | undefined): boolean {\r\n const { refineItemCommonProps } = this.props;\r\n if (max === undefined) {\r\n return true;\r\n }\r\n\r\n if (min > max) {\r\n this.setState({\r\n validationErrorMin: refineItemCommonProps.validationErrorRange,\r\n validationErrorMax: refineItemCommonProps.validationErrorRange\r\n });\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n private _getInputWithoutFormatting(input: string): string {\r\n // First try to cast raw input to a number\r\n const inputAsNum = Number(input);\r\n if (!isNaN(inputAsNum)) {\r\n return input;\r\n }\r\n\r\n // Otherwise try a reverse lookup and fall back to the raw input if all else fails\r\n const reverseLookupResult = this._formattedPriceReverseLookup.get(input);\r\n return reverseLookupResult || input;\r\n }\r\n}\r\n","/*!\r\n * Copyright (c) Microsoft Corporation.\r\n * All rights reserved. See LICENSE in the project root for license information.\r\n */\r\n\r\n/* eslint-disable no-duplicate-imports */\r\nimport { ISliderLabel, ISliderThumbProps, Slider } from '@msdyn365-commerce-modules/utilities';\r\nimport debounce from 'lodash/debounce';\r\nimport { computed } from 'mobx';\r\nimport { observer } from 'mobx-react';\r\nimport * as React from 'react';\r\n\r\nimport { IRefineItemProps, IRefineItemState } from './refine-item';\r\n\r\ntype InputType = 'Min' | 'Max';\r\n\r\nexport type RangeRefineItemType = 'slider' | 'input';\r\n\r\n/**\r\n * Range refine item properties.\r\n */\r\nexport interface IRangeRefineItemProps extends IRefineItemProps {\r\n rangeType: RangeRefineItemType;\r\n minValueSliderThumbAriaLabel?: string;\r\n maxValueSliderThumbAriaLabel?: string;\r\n sliderKey?: string;\r\n}\r\n\r\n/**\r\n * Range refine item state.\r\n */\r\nexport interface IRangeRefineItemState extends IRefineItemState {\r\n validationErrorMin: string | undefined;\r\n validationErrorMax: string | undefined;\r\n selectedMin: string | undefined;\r\n selectedMax: string | undefined;\r\n touchedMin: boolean;\r\n touchedMax: boolean;\r\n sliderId: string;\r\n minValue: string | undefined;\r\n maxValue: string | undefined;\r\n labels: ISliderLabel[];\r\n sliderThumbs: ISliderThumbProps[];\r\n}\r\n\r\n/**\r\n * RangeRefineItem component (controlled by RefineSubmenu).\r\n */\r\n@observer\r\nexport default class RangeRefineItem extends React.Component {\r\n private readonly _formattedPriceReverseLookup: Map = new Map();\r\n\r\n private readonly minInput: React.RefObject;\r\n\r\n private readonly maxInput: React.RefObject;\r\n\r\n @computed get currencyCode(): string {\r\n return this.props.productRefinerValue.UnitText || '';\r\n }\r\n\r\n public constructor(props: IRangeRefineItemProps) {\r\n super(props);\r\n this._onRangeUpdate = this._onRangeUpdate.bind(this);\r\n this._onRangeUpdateEnd = this._onRangeUpdateEnd.bind(this);\r\n this._handleRangeTooltipText = this._handleRangeTooltipText.bind(this);\r\n this._changeMin = this._changeMin.bind(this);\r\n this._changeMax = this._changeMax.bind(this);\r\n this._finishChangeMin = this._finishChangeMin.bind(this);\r\n this._finishChangeMax = this._finishChangeMax.bind(this);\r\n\r\n this.minInput = React.createRef();\r\n this.maxInput = React.createRef();\r\n\r\n const { selectedRefinementCriterion } = this.props;\r\n const initialMin = selectedRefinementCriterion?.LeftValueBoundString ?? '0';\r\n const initialMax = selectedRefinementCriterion?.RightValueBoundString;\r\n const sliderId = `slider_${String(this.props.parentProductRefinerHierarchy.RecordId)}_${String(\r\n this.props.productRefinerValue.RefinerRecordId\r\n )}`;\r\n const minValue = this.props.productRefinerValue.LeftValueBoundString;\r\n const maxValue = this.props.productRefinerValue.RightValueBoundString;\r\n const minPrice = this._formatPrice(minValue);\r\n const maxPrice = this._formatPrice(maxValue);\r\n const labels: ISliderLabel[] = this.getLabels(sliderId, minPrice, maxPrice);\r\n const selectedMin =\r\n this.props.selectedRefinementCriterion?.LeftValueBoundString ?? this.props.productRefinerValue.LeftValueBoundString ?? '0';\r\n const selectedMax =\r\n this.props.selectedRefinementCriterion?.RightValueBoundString ??\r\n this.props.productRefinerValue.RightValueBoundString ??\r\n maxValue;\r\n const selectedMinPrice = this._formatPrice(selectedMin);\r\n const selectedMaxPrice = this._formatPrice(selectedMax);\r\n const sliderKeyString = this.props.sliderKey ? `_${String(this.props.sliderKey)}` : '';\r\n const sliderThumbs: ISliderThumbProps[] = this.getSliderThumbs(\r\n sliderId,\r\n sliderKeyString,\r\n selectedMin,\r\n selectedMinPrice,\r\n selectedMax,\r\n selectedMaxPrice,\r\n maxPrice\r\n );\r\n this.state = {\r\n isChecked: false,\r\n validationErrorMin: undefined,\r\n validationErrorMax: undefined,\r\n selectedMin: initialMin,\r\n selectedMax: initialMax,\r\n touchedMin: false,\r\n touchedMax: false,\r\n sliderId,\r\n minValue,\r\n maxValue,\r\n labels,\r\n sliderThumbs\r\n };\r\n }\r\n\r\n public shouldComponentUpdate(nextProps: IRangeRefineItemProps, nextState: IRangeRefineItemState): boolean {\r\n if (this.state === nextState && this.props === nextProps) {\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n public componentDidUpdate(previousProps: IRangeRefineItemProps): void {\r\n if (previousProps !== this.props) {\r\n this.updateSliderProps();\r\n }\r\n }\r\n\r\n public render(): JSX.Element | undefined {\r\n const { productRefinerValue, parentProductRefinerHierarchy, refineItemCommonProps } = this.props;\r\n\r\n if (!productRefinerValue || !parentProductRefinerHierarchy) {\r\n refineItemCommonProps.telemetry.error(\r\n 'Cannot render refine value range without productRefinerValue and parentProductRefinerHierarchy'\r\n );\r\n return undefined;\r\n }\r\n\r\n if (this.props.rangeType === 'input') {\r\n return this._renderInputFields();\r\n }\r\n\r\n return this._renderSlider();\r\n }\r\n\r\n /**\r\n * Function to update slider props.\r\n */\r\n private updateSliderProps(): void {\r\n const sliderId = `slider_${String(this.props.parentProductRefinerHierarchy.RecordId)}_${String(\r\n this.props.productRefinerValue.RefinerRecordId\r\n )}`;\r\n const minValue = this.props.productRefinerValue.LeftValueBoundString;\r\n const maxValue = this.props.productRefinerValue.RightValueBoundString;\r\n const minPrice = this._formatPrice(minValue);\r\n const maxPrice = this._formatPrice(maxValue);\r\n const labels: ISliderLabel[] = this.getLabels(sliderId, minPrice, maxPrice);\r\n const selectedMin =\r\n this.props.selectedRefinementCriterion?.LeftValueBoundString ?? this.props.productRefinerValue.LeftValueBoundString ?? '0';\r\n const selectedMax =\r\n this.props.selectedRefinementCriterion?.RightValueBoundString ??\r\n this.props.productRefinerValue.RightValueBoundString ??\r\n maxValue;\r\n const selectedMinPrice = this._formatPrice(selectedMin);\r\n const selectedMaxPrice = this._formatPrice(selectedMax);\r\n const sliderKeyString = this.props.sliderKey ? `_${String(this.props.sliderKey)}` : '';\r\n const sliderThumbs: ISliderThumbProps[] = this.getSliderThumbs(\r\n sliderId,\r\n sliderKeyString,\r\n selectedMin,\r\n selectedMinPrice,\r\n selectedMax,\r\n selectedMaxPrice,\r\n maxPrice\r\n );\r\n this.setState({ sliderId, minValue, maxValue, labels, sliderThumbs });\r\n }\r\n\r\n /**\r\n * Function to create the labels for slider.\r\n * @param sliderId - Slider element id for the DOM.\r\n * @param minPrice - Slider min value.\r\n * @param maxPrice - Slider max value.\r\n * @returns Array labels.\r\n */\r\n private readonly getLabels = (sliderId: string, minPrice: string, maxPrice: string): ISliderLabel[] => {\r\n return [\r\n {\r\n labelId: `${sliderId}_start`,\r\n labelString: `${minPrice}`,\r\n labelPositioning: 'start'\r\n },\r\n {\r\n labelId: `${sliderId}_end`,\r\n labelString: `${maxPrice}`,\r\n labelPositioning: 'end'\r\n }\r\n ];\r\n };\r\n\r\n /**\r\n * Function to create the slider thumbs for slider.\r\n * @param sliderId - Slider element id for the DOM.\r\n * @param sliderKey - Unique key for slider.\r\n * @param selectedMin - Slider selected min value.\r\n * @param selectedMinPrice - Slider selected min price.\r\n * @param selectedMax - Slider selected max value.\r\n * @param selectedMaxPrice - Slider selected max price..\r\n * @param maxPrice - Slider max price..\r\n * @returns Slider Thumb Props.\r\n */\r\n private readonly getSliderThumbs = (\r\n sliderId: string,\r\n sliderKey: string,\r\n selectedMin: string,\r\n selectedMinPrice: string,\r\n selectedMax: string | undefined,\r\n selectedMaxPrice: string,\r\n maxPrice: string\r\n ): ISliderThumbProps[] => {\r\n const sliderThumbDefaultValue = 0;\r\n return [\r\n {\r\n id: `${sliderId}${sliderKey}_slider_thumb_start`,\r\n value: (selectedMin && Number(selectedMin)) || sliderThumbDefaultValue,\r\n ariaLabel: `${this.props.minValueSliderThumbAriaLabel ?? ''} ${this.currencyCode}`,\r\n ariaValueText: `${selectedMinPrice}`\r\n },\r\n {\r\n id: `${sliderId}${sliderKey}_slider_thumb_end`,\r\n value: Number(selectedMax) || Number(maxPrice),\r\n ariaLabel: `${this.props.maxValueSliderThumbAriaLabel ?? ''} ${this.currencyCode}`,\r\n ariaValueText: `${selectedMaxPrice}`\r\n }\r\n ];\r\n };\r\n\r\n private _renderInputFields(): JSX.Element | undefined {\r\n const { isDisabled, parentProductRefinerHierarchy, refineItemCommonProps } = this.props;\r\n const { selectedMin, selectedMax, touchedMin, touchedMax, validationErrorMin, validationErrorMax } = this.state;\r\n\r\n const rangeAriaLabel = (refineItemCommonProps.rangeNameFormat || '{0}').replace('{0}', parentProductRefinerHierarchy.KeyName || '');\r\n const formAttrs = {\r\n 'aria-label': rangeAriaLabel,\r\n 'aria-disabled': isDisabled\r\n };\r\n\r\n // To enable price formatting of selected fields, this is the approach:\r\n // initial value: min=0 formatted as price, max=undefined\r\n // onFocus/onChange: convert to number (unformat) and mark as touched to indicate value is being edited\r\n // onBlur: validate and format entered value as price\r\n const minInputClassName = `ms-refine-submenu__input-range refine-submenu__input-range-min ${\r\n validationErrorMin ? 'refine-submenu__input-range--error' : ''\r\n }`;\r\n const maxInputClassName = `ms-refine-submenu__input-range refine-submenu__input-range-max ${\r\n validationErrorMax ? 'refine-submenu__input-range--error' : ''\r\n }`;\r\n const minLabelClassName = 'ms-refine-submenu__input-range-label refine-submenu__input-range-label-min';\r\n const maxLabelClassName = 'ms-refine-submenu__input-range-label refine-submenu__input-range-label-max';\r\n const formattedSelectedMin = this._getFormattedSelectedValue(selectedMin, touchedMin, validationErrorMin);\r\n const formattedSelectedMax = this._getFormattedSelectedValue(selectedMax, touchedMax, validationErrorMax);\r\n return (\r\n
    \r\n \r\n \r\n {validationErrorMin && (\r\n \r\n {validationErrorMin}\r\n \r\n )}\r\n {validationErrorMax && validationErrorMin !== validationErrorMax && (\r\n \r\n {validationErrorMax}\r\n \r\n )}\r\n
    \r\n );\r\n }\r\n\r\n private _renderSlider(): JSX.Element | undefined {\r\n const { isDisabled, sliderKey } = this.props;\r\n const ariaAttributes = {\r\n 'aria-disabled': isDisabled\r\n };\r\n\r\n return (\r\n \r\n );\r\n }\r\n\r\n private _changeMin(event: React.FocusEvent): void {\r\n this._changeValue(event, 'Min');\r\n }\r\n\r\n private _changeMax(event: React.FocusEvent): void {\r\n this._changeValue(event, 'Max');\r\n }\r\n\r\n private _changeValue(event: React.FocusEvent, inputType: InputType): void {\r\n const selectedKey = `selected${inputType}`;\r\n const touchedKey = `touched${inputType}`;\r\n this.setState({\r\n [selectedKey]: this._getInputWithoutFormatting(event.currentTarget.value),\r\n [touchedKey]: true\r\n });\r\n }\r\n\r\n private _finishChangeMin(event: React.FocusEvent): boolean {\r\n const selectedMinValue = this._getInputWithoutFormatting(event.currentTarget.value);\r\n this.setState({\r\n selectedMin: selectedMinValue,\r\n minTouched: false\r\n });\r\n const minInput = Number(selectedMinValue);\r\n const {\r\n onToggle,\r\n parentProductRefinerHierarchy,\r\n productRefinerValue,\r\n refineItemCommonProps,\r\n selectedRefinementCriterion\r\n } = this.props;\r\n const max = (selectedRefinementCriterion && selectedRefinementCriterion.RightValueBoundString) || undefined;\r\n\r\n const maxNum = max ? Number(max) : undefined;\r\n\r\n if (isNaN(minInput)) {\r\n this.setState({ validationErrorMin: refineItemCommonProps.validationErrorNaN });\r\n this._focus('Min');\r\n return false;\r\n }\r\n\r\n if (this._validateRange(minInput, maxNum)) {\r\n onToggle({\r\n parentProductRefinerHierarchy,\r\n productRefinerValue,\r\n isSelecting: true,\r\n rangeStart: minInput,\r\n rangeEnd: maxNum\r\n });\r\n return true;\r\n }\r\n this._focus('Min');\r\n\r\n return false;\r\n }\r\n\r\n private _finishChangeMax(event: React.FocusEvent): boolean {\r\n const selectedMaxValue = this._getInputWithoutFormatting(event.currentTarget.value);\r\n this.setState({\r\n selectedMax: selectedMaxValue,\r\n maxTouched: false\r\n });\r\n const maxInput = Number(selectedMaxValue);\r\n const {\r\n onToggle,\r\n parentProductRefinerHierarchy,\r\n productRefinerValue,\r\n refineItemCommonProps,\r\n selectedRefinementCriterion\r\n } = this.props;\r\n const min = (selectedRefinementCriterion && selectedRefinementCriterion.LeftValueBoundString) || '0';\r\n\r\n const minNum = Number(min);\r\n\r\n if (isNaN(maxInput)) {\r\n this.setState({ validationErrorMax: refineItemCommonProps.validationErrorNaN });\r\n this._focus('Max');\r\n return false;\r\n }\r\n\r\n if (this._validateRange(minNum, maxInput)) {\r\n if (productRefinerValue) {\r\n onToggle({\r\n parentProductRefinerHierarchy,\r\n productRefinerValue,\r\n isSelecting: true,\r\n rangeStart: minNum,\r\n rangeEnd: maxInput\r\n });\r\n } else {\r\n this._focus('Max');\r\n }\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n private _focus(inputType: InputType): void {\r\n const ref = inputType === 'Max' ? this.maxInput : this.minInput;\r\n\r\n setTimeout(() => {\r\n if (ref && ref.current) {\r\n ref.current.focus();\r\n }\r\n }, 50);\r\n }\r\n\r\n private _getFormattedSelectedValue(\r\n selected: string | undefined,\r\n touched: boolean,\r\n validationError: string | undefined\r\n ): string | undefined {\r\n if (touched || validationError || selected === undefined) {\r\n return selected;\r\n }\r\n return this._formatPrice(selected);\r\n }\r\n\r\n private _validateRange(min: number, max: number | undefined): boolean {\r\n const { refineItemCommonProps } = this.props;\r\n if (max === undefined) {\r\n return true;\r\n }\r\n\r\n if (min > max) {\r\n this.setState({\r\n validationErrorMin: refineItemCommonProps.validationErrorRange,\r\n validationErrorMax: refineItemCommonProps.validationErrorRange\r\n });\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n private _formatPrice(amount: string | undefined): string {\r\n if (this.props.productRefinerValue.RefinerRecordId === 0) {\r\n const result = this.props.context.cultureFormatter.formatCurrency(Number(amount), this.currencyCode);\r\n return result;\r\n }\r\n return amount || '';\r\n }\r\n\r\n private _getInputWithoutFormatting(input: string): string {\r\n // First try to cast raw input to a number\r\n const inputAsNum = Number(input);\r\n if (!isNaN(inputAsNum)) {\r\n return input;\r\n }\r\n\r\n // Otherwise try a reverse lookup and fall back to the raw input if all else fails\r\n const reverseLookupResult = this._formattedPriceReverseLookup.get(input);\r\n return reverseLookupResult || input;\r\n }\r\n\r\n // NOTE: Fix types once Shared Components build pipeline bug fixed\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n private _onRangeUpdate(sliderChangeNotification: any): void {\r\n // Need to filter out mousemove events as these cause errors after the menu updates and slider re-renders\r\n if (sliderChangeNotification.eventType !== 'mousemove') {\r\n const { onToggle, parentProductRefinerHierarchy, productRefinerValue } = this.props;\r\n if (productRefinerValue && sliderChangeNotification) {\r\n onToggle({\r\n parentProductRefinerHierarchy,\r\n productRefinerValue,\r\n isSelecting: true,\r\n rangeStart: sliderChangeNotification.firstThumbValue,\r\n rangeEnd: sliderChangeNotification.secondThumbValue\r\n });\r\n\r\n this._focusOnSliderThumb(sliderChangeNotification);\r\n }\r\n }\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n private _onRangeUpdateEnd(sliderChangeNotification: any): void {\r\n const { onToggle, parentProductRefinerHierarchy, productRefinerValue } = this.props;\r\n if (productRefinerValue && sliderChangeNotification) {\r\n onToggle({\r\n parentProductRefinerHierarchy,\r\n productRefinerValue,\r\n isSelecting: true,\r\n rangeStart: sliderChangeNotification.firstThumbValue,\r\n rangeEnd: sliderChangeNotification.secondThumbValue\r\n });\r\n\r\n this._focusOnSliderThumb(sliderChangeNotification);\r\n }\r\n }\r\n\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n private _focusOnSliderThumb(sliderChangeNotification: any): void {\r\n if (sliderChangeNotification.id) {\r\n const element = document.getElementById(`${sliderChangeNotification.id}range`);\r\n if (element) {\r\n setTimeout(() => {\r\n element.focus();\r\n }, 0);\r\n }\r\n }\r\n }\r\n\r\n private _handleRangeTooltipText(tooltip: number): string {\r\n return this._formatPrice(`${tooltip}`);\r\n }\r\n}\r\n","/*!\r\n * Copyright (c) Microsoft Corporation.\r\n * All rights reserved. See LICENSE in the project root for license information.\r\n */\r\n\r\n/* eslint-disable no-duplicate-imports */\r\nimport { IProductRefinerHierarchy } from '@msdyn365-commerce/commerce-entities';\r\nimport { RatingComponent, SwatchComponent } from '@msdyn365-commerce/components';\r\nimport { IAny, ICoreContext, IGeneric } from '@msdyn365-commerce/core';\r\nimport { ProductRefinerSource, ProductRefinerValue, RefinerType } from '@msdyn365-commerce/retail-proxy';\r\nimport { checkIfShouldDisplayAsSwatch, DimensionTypes, IDimensionsApp, StringExtensions } from '@msdyn365-commerce-modules/retail-actions';\r\nimport { format, getPayloadObject, getTelemetryAttributes, IPayLoad, ITelemetryContent } from '@msdyn365-commerce-modules/utilities';\r\nimport classnames from 'classnames';\r\nimport * as React from 'react';\r\n\r\nimport { IRefineItemCommonProps } from './refine-item.props.common';\r\nimport { IRefineItemToggleNotification } from './refine-item-toggle-notification';\r\nimport { decodeBase64String, isBase64EncodePrefixed } from '../../../shared-utils/base64';\r\n\r\n/**\r\n * RefineItem properties.\r\n */\r\nexport interface IRefineItemProps {\r\n parentProductRefinerHierarchy: IProductRefinerHierarchy;\r\n productRefinerValue: ProductRefinerValue;\r\n selectedRefinementCriterion: ProductRefinerValue | undefined;\r\n selectedRefinerValues?: ProductRefinerValue[];\r\n refineItemCommonProps: IRefineItemCommonProps;\r\n isDisabled: boolean;\r\n context: ICoreContext>;\r\n moduleId: string;\r\n moduleTypeName: string;\r\n index?: number;\r\n productCountAriaLabel?: string;\r\n singleProductCountAriaLabel?: string;\r\n refineItemAriaLabel?: string;\r\n refineItemsAriaLabel?: string;\r\n isMobileView?: boolean;\r\n yesText?: string;\r\n noText?: string;\r\n transitRefinerRecordId?: string;\r\n\r\n /**\r\n * The telemetry content\r\n */\r\n telemetryContent?: ITelemetryContent;\r\n onToggle(notfication: Readonly): void;\r\n urlBuilder(refiner: IRefineItemToggleNotification): string;\r\n}\r\n\r\n/**\r\n * Refine item state.\r\n */\r\nexport interface IRefineItemState extends React.ComponentState {\r\n isChecked: boolean;\r\n renderingError?: object;\r\n}\r\n\r\n/**\r\n * Single-select and multi-select refine item component (controlled by RefineSubmenu).\r\n */\r\nexport default class RefineItem extends React.Component {\r\n private readonly anchorType: React.RefObject;\r\n\r\n private readonly payLoad: IPayLoad;\r\n\r\n public constructor(props: IRefineItemProps) {\r\n super(props);\r\n this._onClick = this._onClick.bind(this);\r\n this.state = {\r\n isChecked: !!this.props.selectedRefinementCriterion\r\n };\r\n this.anchorType = React.createRef();\r\n this.payLoad = getPayloadObject('click', this.props.telemetryContent!, '');\r\n }\r\n\r\n public shouldComponentUpdate(nextProps: IRefineItemProps, nextState: IRefineItemState): boolean {\r\n if (this.state === nextState && this.props === nextProps) {\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n public render(): JSX.Element | undefined {\r\n const {\r\n isDisabled,\r\n refineItemCommonProps,\r\n parentProductRefinerHierarchy,\r\n productRefinerValue,\r\n selectedRefinementCriterion,\r\n productCountAriaLabel,\r\n singleProductCountAriaLabel,\r\n index,\r\n children,\r\n onToggle,\r\n context,\r\n telemetryContent,\r\n refineItemAriaLabel,\r\n refineItemsAriaLabel,\r\n yesText,\r\n noText,\r\n transitRefinerRecordId,\r\n ...attrs\r\n } = this.props;\r\n if (!productRefinerValue) {\r\n refineItemCommonProps.telemetry.error('[refine-item] Cannot render refineItem without productRefinerValue');\r\n return undefined;\r\n }\r\n if (!productRefinerValue.LeftValueBoundString) {\r\n refineItemCommonProps.telemetry.warning(\r\n `[refine-item] RefineItem without LeftValueBoundString: ${JSON.stringify(productRefinerValue)}`\r\n );\r\n }\r\n const isSingleSelect = parentProductRefinerHierarchy.RefinerTypeValue === RefinerType.SingleSelect;\r\n let itemTypeClassName = isSingleSelect ? 'single-select' : 'multi-select';\r\n itemTypeClassName = `ms-refine-submenu-item ${itemTypeClassName}`;\r\n const inputType = isSingleSelect ? 'radio' : 'checkbox';\r\n const isChecked = !!selectedRefinementCriterion;\r\n itemTypeClassName = isChecked ? `${itemTypeClassName}-checked` : itemTypeClassName;\r\n if (parentProductRefinerHierarchy.SourceValue === ProductRefinerSource.Rating) {\r\n return this._renderRating(\r\n productRefinerValue,\r\n parentProductRefinerHierarchy,\r\n isChecked,\r\n context,\r\n index,\r\n telemetryContent,\r\n productCountAriaLabel,\r\n singleProductCountAriaLabel\r\n );\r\n }\r\n let labelText = productRefinerValue.LeftValueBoundLocalizedString || productRefinerValue.LeftValueBoundString;\r\n\r\n if (transitRefinerRecordId && productRefinerValue.RefinerRecordId === Number(transitRefinerRecordId)) {\r\n if (labelText === '0') {\r\n labelText = noText ?? 'No';\r\n } else if (labelText === '1') {\r\n labelText = yesText ?? 'Yes';\r\n }\r\n }\r\n\r\n if (parentProductRefinerHierarchy.KeyName === 'Sperret for Svalbard') {\r\n if (labelText === '0') {\r\n labelText = noText ?? 'No';\r\n } else if (labelText === '1') {\r\n labelText = yesText ?? 'Yes';\r\n }\r\n }\r\n\r\n this.payLoad.contentAction.etext = labelText;\r\n const attribute = getTelemetryAttributes(telemetryContent!, this.payLoad);\r\n // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- Replace with actual value for empty string.\r\n const productText = labelText || '';\r\n // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- Replace with actual value for empty string.\r\n const productCount = productRefinerValue.Count || 0;\r\n let refineMenuItemAriaLabel;\r\n if (productCount === 1) {\r\n refineMenuItemAriaLabel = refineItemAriaLabel\r\n ? format(refineItemAriaLabel, parentProductRefinerHierarchy.KeyName, productText)\r\n : '';\r\n } else {\r\n refineMenuItemAriaLabel = refineItemsAriaLabel\r\n ? format(refineItemsAriaLabel, parentProductRefinerHierarchy.KeyName, productText, productCount)\r\n : '';\r\n }\r\n\r\n const dimensionType = (this.props.parentProductRefinerHierarchy.KeyName?.toLocaleLowerCase() ?? '') as DimensionTypes;\r\n const shouldDisplayAsSwatch = this._getShouldDisplayAsSwatch(dimensionType);\r\n\r\n let className = 'ms-refine-submenu-item';\r\n if (shouldDisplayAsSwatch) {\r\n className = classnames(className, `ms-refine-submenu-item__dimension__${dimensionType}`);\r\n }\r\n\r\n // If the swatch has no color or image specified, it should be displayed as text.\r\n // We don't use swatch logic to display the number of the results found together with the text.\r\n const hasColor = !StringExtensions.isNullOrWhitespace(productRefinerValue.SwatchColorHexCode);\r\n const hasImage = !StringExtensions.isNullOrWhitespace(productRefinerValue.SwatchImageUrl);\r\n const hasContentSwatch = hasColor || hasImage;\r\n const tooltip = `${labelText}${productRefinerValue.Count !== undefined ? ` (${productRefinerValue.Count})` : ''}`;\r\n\r\n if (isBase64EncodePrefixed(parentProductRefinerHierarchy) && labelText) {\r\n labelText = labelText.split('|').map(decodeBase64String).join('|');\r\n }\r\n\r\n return (\r\n
  • \r\n \r\n {hasContentSwatch && shouldDisplayAsSwatch && this._renderSwatch(dimensionType)}\r\n \r\n \r\n
  • \r\n );\r\n }\r\n\r\n private _getShouldDisplayAsSwatch(dimensionType: DimensionTypes) {\r\n const shouldDisplayAsSwatch = checkIfShouldDisplayAsSwatch(dimensionType, this.props.context as ICoreContext);\r\n return shouldDisplayAsSwatch;\r\n }\r\n\r\n private _renderSwatch(dimensionType: DimensionTypes): JSX.Element | null {\r\n const productRefinerValue = this.props.productRefinerValue;\r\n\r\n // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- Replace with actual value for empty string.\r\n const text = productRefinerValue.LeftValueBoundLocalizedString || productRefinerValue.LeftValueBoundString || '';\r\n const swatchItems = [\r\n {\r\n itemId: `${productRefinerValue.RefinerRecordId ?? ''}-${dimensionType}-${text}`,\r\n value: text,\r\n dimensionType,\r\n colorHexCode: productRefinerValue.SwatchColorHexCode,\r\n imageUrl: productRefinerValue.SwatchImageUrl\r\n }\r\n ];\r\n\r\n return (\r\n \r\n );\r\n }\r\n\r\n private _getRefinerUrl(): string {\r\n const { urlBuilder, parentProductRefinerHierarchy, productRefinerValue, selectedRefinementCriterion } = this.props;\r\n\r\n if (productRefinerValue) {\r\n return urlBuilder({\r\n parentProductRefinerHierarchy,\r\n productRefinerValue,\r\n isSelecting: !selectedRefinementCriterion\r\n });\r\n }\r\n\r\n return '';\r\n }\r\n\r\n private readonly _onClick = (e: React.MouseEvent): void => {\r\n e.preventDefault();\r\n\r\n const { parentProductRefinerHierarchy, productRefinerValue, selectedRefinementCriterion } = this.props;\r\n if (productRefinerValue) {\r\n this.props.onToggle({\r\n parentProductRefinerHierarchy,\r\n productRefinerValue,\r\n isSelecting: !selectedRefinementCriterion\r\n });\r\n\r\n setTimeout(() => {\r\n this.anchorType.current && this.anchorType.current.focus();\r\n }, 0);\r\n }\r\n };\r\n\r\n private _renderRating(\r\n productRefinerValue: ProductRefinerValue,\r\n parentProductRefinerHierarchy: IProductRefinerHierarchy,\r\n isChecked: boolean,\r\n context: ICoreContext,\r\n index?: number,\r\n telemetryContent?: ITelemetryContent,\r\n ratingUserCountAriaLabel?: string,\r\n ratingSingleUserCountAriaLabel?: string\r\n ): JSX.Element | undefined {\r\n if (productRefinerValue.LeftValueBoundString) {\r\n this.payLoad.contentAction.etext = productRefinerValue.LeftValueBoundLocalizedString;\r\n const attribute = getTelemetryAttributes(telemetryContent!, this.payLoad);\r\n const refinerRating = Number.parseInt(productRefinerValue.LeftValueBoundString, 10);\r\n const ratingRefiner = this.props.selectedRefinerValues?.find(\r\n value => value.DataTypeValue === productRefinerValue.DataTypeValue\r\n );\r\n // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- Replace with actual value for empty string.\r\n const selectedRating = Number.parseInt(ratingRefiner?.LeftValueBoundString || '0', 10);\r\n const defaultChkProductCount = 1;\r\n let ratingComponentClass: string = 'ms-rating-component';\r\n if (refinerRating > selectedRating) {\r\n ratingComponentClass = `${ratingComponentClass}__up`;\r\n } else if (refinerRating < selectedRating) {\r\n ratingComponentClass = `${ratingComponentClass}__down`;\r\n } else {\r\n ratingComponentClass = `${ratingComponentClass}__current`;\r\n }\r\n const productCountAriaLabelValue =\r\n productRefinerValue.Count !== undefined && productRefinerValue.Count === defaultChkProductCount\r\n ? ratingSingleUserCountAriaLabel && format(ratingSingleUserCountAriaLabel, productRefinerValue.Count)\r\n : ratingUserCountAriaLabel && format(ratingUserCountAriaLabel, productRefinerValue.Count);\r\n return (\r\n \r\n \r\n \r\n \r\n {productRefinerValue.Count !== undefined && `(${productRefinerValue.Count})`}\r\n \r\n \r\n \r\n );\r\n }\r\n return undefined;\r\n }\r\n}\r\n","/*!\r\n * Copyright (c) Microsoft Corporation.\r\n * All rights reserved. See LICENSE in the project root for license information.\r\n */\r\n\r\n/* eslint-disable no-duplicate-imports */\r\nimport { IProductRefinerHierarchy } from '@msdyn365-commerce/commerce-entities';\r\nimport { IAny, ICoreContext, IGeneric } from '@msdyn365-commerce/core';\r\nimport { DisplayTemplate, ProductRefinerSource, ProductRefinerValue, RefinerType } from '@msdyn365-commerce/retail-proxy';\r\nimport { Button, Collapse, ITelemetryContent } from '@msdyn365-commerce-modules/utilities';\r\nimport classnames from 'classnames';\r\nimport * as React from 'react';\r\n\r\nimport RangeRefineItem, { RangeRefineItemType } from './range-refine-item';\r\nimport RefineItem from './refine-item';\r\nimport { IRefineItemCommonProps } from './refine-item.props.common';\r\nimport { IRefineItemToggleNotification } from './refine-item-toggle-notification';\r\nimport { findMatchingRefinementCriterion, isRangeType } from './utilities';\r\nimport { isBase64EncodePrefixed } from '../../../shared-utils/base64';\r\n\r\n/**\r\n * Properties associated with the RefineSubmenu component.\r\n */\r\nexport interface IRefineSubmenuProps {\r\n tempRangeTypeTODO: RangeRefineItemType;\r\n minValueSliderThumbAriaLabel?: string;\r\n maxValueSliderThumbAriaLabel?: string;\r\n productRefinerHierarchy: IProductRefinerHierarchy;\r\n selectedRefinerValues: ProductRefinerValue[];\r\n refineItemCommonProps: IRefineItemCommonProps;\r\n isDisabled: boolean;\r\n isExpandedOnInitialLoad: boolean;\r\n context: ICoreContext>;\r\n moduleId: string;\r\n moduleTypeName: string;\r\n productCountAriaLabel?: string;\r\n singleProductCountAriaLabel?: string;\r\n refineItemAriaLabel?: string;\r\n refineItemsAriaLabel?: string;\r\n isMobile?: boolean;\r\n yesText?: string;\r\n noText?: string;\r\n transitRefinerRecordId?: string;\r\n\r\n /**\r\n * The telemetry content\r\n */\r\n telemetryContent?: ITelemetryContent;\r\n onUpdateRefiners(notfication: Readonly): void;\r\n urlBuilder(refiner: IRefineItemToggleNotification): string;\r\n}\r\n\r\n/**\r\n * Refine submenu state.\r\n */\r\nexport interface IRefineSubmenuState extends React.ComponentState {\r\n expanded: boolean;\r\n}\r\n\r\n/**\r\n *\r\n * The RefineSubmenu component renders the submenu category and child items.\r\n * This computed observes the stateful category hierarchy object.\r\n * @extends {React.PureComponent}\r\n */\r\nclass RefineSubmenu extends React.Component {\r\n private readonly MaxItems = 16;\r\n\r\n constructor(props: IRefineSubmenuProps) {\r\n super(props);\r\n\r\n this._onToggleItem = this._onToggleItem.bind(this);\r\n this._onToggleSubmenu = this._onToggleSubmenu.bind(this);\r\n\r\n const isExpanded = this.props.isExpandedOnInitialLoad;\r\n\r\n // If (this.props.productRefinerHierarchy.DataTypeValue === ProductRefinerValueDataTypeValue.Range) {\r\n // isExpanded = true;\r\n // }\r\n\r\n this.state = {\r\n expanded: isExpanded,\r\n isShowFullList: props.productRefinerHierarchy.Values.length <= this.MaxItems\r\n };\r\n }\r\n\r\n public shouldComponentUpdate(nextProps: IRefineSubmenuProps, nextState: IRefineSubmenuState): boolean {\r\n if (this.state === nextState && this.props === nextProps) {\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n public render(): JSX.Element | null {\r\n const { productRefinerHierarchy, refineItemCommonProps } = this.props;\r\n\r\n if (!productRefinerHierarchy) {\r\n refineItemCommonProps.telemetry.error('Cannot render submenu without refiner hierarchy data');\r\n }\r\n\r\n if (productRefinerHierarchy.SourceValue === ProductRefinerSource.Rating && this.props.context.app.config.hideRating) {\r\n return null;\r\n }\r\n\r\n let keyName = productRefinerHierarchy.KeyName;\r\n\r\n if (isBase64EncodePrefixed(productRefinerHierarchy)) {\r\n keyName = keyName?.replace('{base64}:', '');\r\n }\r\n\r\n const className = classnames(\r\n 'ms-refine-submenu',\r\n 'list-group',\r\n keyName // Deprecated because of the localization issues. Leaving for backward compatibility reasons.\r\n );\r\n\r\n return (\r\n
    \r\n \r\n {keyName}\r\n \r\n {\r\n // Simulate the 'resize' event so that sliders gets rendered correctly.\r\n // If not end Slider will always start a position 0 since hidden elements have no width.\r\n window.dispatchEvent(new Event('resize'));\r\n }}>\r\n {this._renderChildItems(productRefinerHierarchy)}\r\n \r\n
    \r\n );\r\n }\r\n\r\n private _renderChildItems(productRefinerHierarchy: IProductRefinerHierarchy): JSX.Element | null {\r\n if (isRangeType(productRefinerHierarchy.DataTypeValue)) {\r\n return this._renderRange(productRefinerHierarchy);\r\n }\r\n return this._renderSingleMultiSelect(productRefinerHierarchy);\r\n }\r\n\r\n private _renderSingleMultiSelect(productRefinerHierarchy: IProductRefinerHierarchy): JSX.Element | null {\r\n const {\r\n isDisabled,\r\n refineItemCommonProps,\r\n selectedRefinerValues,\r\n context,\r\n productCountAriaLabel,\r\n singleProductCountAriaLabel,\r\n refineItemAriaLabel,\r\n refineItemsAriaLabel,\r\n isMobile\r\n } = this.props;\r\n const isSingleSelect =\r\n productRefinerHierarchy.RefinerTypeValue === RefinerType.SingleSelect &&\r\n productRefinerHierarchy.SourceValue === ProductRefinerSource.Rating;\r\n const role = isSingleSelect ? { role: 'listbox' } : undefined;\r\n const refinerValuesList = productRefinerHierarchy.Values || [];\r\n refinerValuesList.sort(\r\n (a, b) => (a.LeftValueBoundLocalizedString || a.LeftValueBoundString || '').localeCompare(b.LeftValueBoundLocalizedString || b.LeftValueBoundString || '', context.request.locale)\r\n );\r\n const listItems = refinerValuesList.map((child: ProductRefinerValue, index: number) => {\r\n if (!child) {\r\n refineItemCommonProps.telemetry.error(\r\n `[refine-submenu] Could not render refine item for refiner ${productRefinerHierarchy.RecordId} (${productRefinerHierarchy.KeyName})`\r\n );\r\n return null;\r\n }\r\n if (index > (this.MaxItems - 1) && !this.state.isShowFullList) {\r\n return null;\r\n }\r\n const selectedRefinementCriterion = findMatchingRefinementCriterion(child, selectedRefinerValues);\r\n\r\n return (\r\n \r\n refinerValuesList.find(value => value.RefinerRecordId === selectedValue.RefinerRecordId)\r\n )}\r\n refineItemCommonProps={refineItemCommonProps}\r\n onToggle={this._onToggleItem}\r\n urlBuilder={this.props.urlBuilder}\r\n isDisabled={isDisabled}\r\n key={index}\r\n index={index}\r\n context={context}\r\n moduleId={this.props.moduleId}\r\n moduleTypeName={this.props.moduleTypeName}\r\n telemetryContent={this.props.telemetryContent}\r\n productCountAriaLabel={productCountAriaLabel}\r\n refineItemAriaLabel={refineItemAriaLabel}\r\n refineItemsAriaLabel={refineItemsAriaLabel}\r\n singleProductCountAriaLabel={singleProductCountAriaLabel}\r\n isMobileView={isMobile}\r\n yesText={this.props.yesText}\r\n noText={this.props.noText}\r\n transitRefinerRecordId={this.props.transitRefinerRecordId}\r\n />\r\n );\r\n });\r\n\r\n const keyName = isBase64EncodePrefixed(productRefinerHierarchy)\r\n ? productRefinerHierarchy.KeyName?.replace('{base64}:', '')\r\n : productRefinerHierarchy.KeyName;\r\n\r\n return (\r\n \r\n {listItems}\r\n {refinerValuesList.length > this.MaxItems && }\r\n \r\n );\r\n }\r\n\r\n private _getRangeType(productRefinerHierarchy: IProductRefinerHierarchy): 'input' | 'slider' {\r\n if (\r\n productRefinerHierarchy.DisplayTemplateValue === DisplayTemplate.Range ||\r\n productRefinerHierarchy.DisplayTemplateValue === DisplayTemplate.Slider ||\r\n productRefinerHierarchy.DisplayTemplateValue === DisplayTemplate.SliderWithBars\r\n ) {\r\n return 'slider';\r\n }\r\n return 'input';\r\n }\r\n\r\n private _renderRange(productRefinerHierarchy: IProductRefinerHierarchy): JSX.Element | null {\r\n const {\r\n isDisabled,\r\n refineItemCommonProps,\r\n selectedRefinerValues,\r\n context,\r\n minValueSliderThumbAriaLabel,\r\n maxValueSliderThumbAriaLabel\r\n } = this.props;\r\n const submenuClassNamePrefix = 'ms-refine-submenu__item list-group-item refine-submenu__item';\r\n const refinerValuesList = productRefinerHierarchy.Values || [];\r\n const listItems = refinerValuesList.map((child: ProductRefinerValue, index: number) => {\r\n if (!child) {\r\n refineItemCommonProps.telemetry.error(\r\n `Could not render refine item for refiner ${productRefinerHierarchy.RecordId} (${productRefinerHierarchy.KeyName})`\r\n );\r\n return null;\r\n }\r\n\r\n const selectedRefinementCriterion = findMatchingRefinementCriterion(child, selectedRefinerValues);\r\n\r\n const rangeType = this._getRangeType(productRefinerHierarchy);\r\n const key = selectedRefinementCriterion\r\n ? `${selectedRefinementCriterion.LeftValueBoundString}-${selectedRefinementCriterion.RightValueBoundString}`\r\n : `not-selected-${index}`;\r\n return (\r\n
  • \r\n \r\n
  • \r\n );\r\n });\r\n\r\n const keyName = isBase64EncodePrefixed(productRefinerHierarchy)\r\n ? productRefinerHierarchy.KeyName?.replace('{base64}:', '')\r\n : productRefinerHierarchy.KeyName;\r\n\r\n return
      {listItems}
    ;\r\n }\r\n\r\n private _onToggleItem(itemToggleNotification: IRefineItemToggleNotification): void {\r\n this.props.onUpdateRefiners(itemToggleNotification);\r\n }\r\n\r\n private _onToggleSubmenu(): void {\r\n this.setState(prevState => ({\r\n expanded: !prevState.expanded\r\n }));\r\n }\r\n}\r\n\r\nexport default RefineSubmenu;\r\n","/*!\r\n * Copyright (c) Microsoft Corporation.\r\n * All rights reserved. See LICENSE in the project root for license information.\r\n */\r\n\r\n/* eslint-disable no-duplicate-imports */\r\nimport { ITelemetry } from '@msdyn365-commerce/core';\r\nimport { AttributeDataType, DisplayTemplate, ProductRefinerValue, RefinerType } from '@msdyn365-commerce/retail-proxy';\r\n\r\nimport { IProductRefinerHierarchy } from '@msdyn365-commerce/commerce-entities';\r\nimport { DimensionTypes } from '@msdyn365-commerce-modules/retail-actions';\r\nimport { IRefineItemToggleNotification } from './refine-item-toggle-notification';\r\n\r\n/**\r\n * Types of product refiner values.\r\n * @deprecated This will be removed soon. Please, use `AttributeDataType` from `@msdyn365-commerce/retail-proxy` instead.\r\n * @example\r\n * ```\r\n * import { AttributeDataType } from `@msdyn365-commerce/retail-proxy`;\r\n * ```\r\n */\r\nexport enum ProductRefinerValueDataTypeValue {\r\n /**\r\n * Range slider is used for selections like price.\r\n * @deprecated This will be removed soon. Please, use `AttributeDataType` from `@msdyn365-commerce/retail-proxy` instead.\r\n * @example\r\n * ```\r\n * import { AttributeDataType } from `@msdyn365-commerce/retail-proxy`;\r\n * ```\r\n */\r\n Range = 1,\r\n\r\n /**\r\n * Range input is a different way to specify ranges and can be expressed with input boxes\r\n * as well as a set of discrete single-select type values.\r\n * @deprecated This will be removed soon. Please, use `AttributeDataType` from `@msdyn365-commerce/retail-proxy` instead.\r\n * @example\r\n * ```\r\n * import { AttributeDataType } from `@msdyn365-commerce/retail-proxy`;\r\n * ```\r\n */\r\n RangeInput = 4,\r\n\r\n /**\r\n * This is a discrete list item, either multi-select or single-select.\r\n * @deprecated This will be removed soon. Please, use `AttributeDataType` from `@msdyn365-commerce/retail-proxy` instead.\r\n * @example\r\n * ```\r\n * import { AttributeDataType } from `@msdyn365-commerce/retail-proxy`;\r\n * ```\r\n */\r\n List = 5,\r\n\r\n /**\r\n * Boolean types allows only single-select.\r\n * @deprecated This will be removed soon. Please, use `AttributeDataType` from `@msdyn365-commerce/retail-proxy` instead.\r\n * @example\r\n * ```\r\n * import { AttributeDataType } from `@msdyn365-commerce/retail-proxy`;\r\n * ```\r\n */\r\n Boolean = 6\r\n}\r\n\r\n/**\r\n * Types of product refiners.\r\n * @deprecated This will be removed soon. Please, use `RefinerType` from `@msdyn365-commerce/retail-proxy` instead.\r\n * @example\r\n * ```\r\n * import { RefinerType } from `@msdyn365-commerce/retail-proxy`;\r\n * ```\r\n */\r\nexport enum ProductRefinerTypeValue {\r\n /**\r\n * Refiner values are single-select.\r\n * @deprecated This will be removed soon. Please, use `RefinerType` from `@msdyn365-commerce/retail-proxy` instead.\r\n * @example\r\n * ```\r\n * import { RefinerType } from `@msdyn365-commerce/retail-proxy`;\r\n * ```\r\n */\r\n Single = 0,\r\n\r\n /**\r\n * Refiner values are multi-select.\r\n * @deprecated This will be removed soon. Please, use `RefinerType` from `@msdyn365-commerce/retail-proxy` instead.\r\n * @example\r\n * ```\r\n * import { RefinerType } from `@msdyn365-commerce/retail-proxy`;\r\n * ```\r\n */\r\n Multi = 1\r\n}\r\n\r\n/**\r\n * ProductRefinerSource enum type.\r\n * @deprecated This will be removed soon. Please, use `ProductRefinerSource` from `@msdyn365-commerce/retail-proxy` instead.\r\n * @example\r\n * ```\r\n * import { ProductRefinerSource } from `@msdyn365-commerce/retail-proxy`;\r\n * ```\r\n */\r\nexport enum ProductRefinerSource {\r\n /**\r\n * The None member.\r\n * @deprecated This will be removed soon. Please, use `ProductRefinerSource` from `@msdyn365-commerce/retail-proxy` instead.\r\n * @example\r\n * ```\r\n * import { ProductRefinerSource } from `@msdyn365-commerce/retail-proxy`;\r\n * ```\r\n */\r\n None = 0,\r\n\r\n /**\r\n * The Attribute member.\r\n * @deprecated This will be removed soon. Please, use `ProductRefinerSource` from `@msdyn365-commerce/retail-proxy` instead.\r\n * @example\r\n * ```\r\n * import { ProductRefinerSource } from `@msdyn365-commerce/retail-proxy`;\r\n * ```\r\n */\r\n Attribute = 1,\r\n\r\n /**\r\n * The Category member.\r\n * @deprecated This will be removed soon. Please, use `ProductRefinerSource` from `@msdyn365-commerce/retail-proxy` instead.\r\n * @example\r\n * ```\r\n * import { ProductRefinerSource } from `@msdyn365-commerce/retail-proxy`;\r\n * ```\r\n */\r\n Category = 2,\r\n\r\n /**\r\n * The Price member.\r\n * @deprecated This will be removed soon. Please, use `ProductRefinerSource` from `@msdyn365-commerce/retail-proxy` instead.\r\n * @example\r\n * ```\r\n * import { ProductRefinerSource } from `@msdyn365-commerce/retail-proxy`;\r\n * ```\r\n */\r\n Price = 3,\r\n\r\n /**\r\n * The Rating member.\r\n * @deprecated This will be removed soon. Please, use `ProductRefinerSource` from `@msdyn365-commerce/retail-proxy` instead.\r\n * @example\r\n * ```\r\n * import { ProductRefinerSource } from `@msdyn365-commerce/retail-proxy`;\r\n * ```\r\n */\r\n Rating = 4\r\n}\r\n\r\nexport interface IRefineItemData {\r\n sourceValue?: number;\r\n swatchImageUrl?: string;\r\n swatchColorHexCode?: string;\r\n refinerItemId: number;\r\n dataTypeValue?: number;\r\n name: string;\r\n label: string;\r\n count?: number;\r\n isChecked: boolean;\r\n refineItemUrl?: string;\r\n minValue?: string;\r\n maxValue?: string;\r\n dimensionType?: DimensionTypes;\r\n rowNumber?: number;\r\n unitText?: string;\r\n updatedSliderMaxValue?: string;\r\n updatedSliderMinValue?: string;\r\n}\r\n/**\r\n * Checks if the data type value corresponds to a slider.\r\n * @param dataTypeValue\r\n */\r\nexport function isRangeType(dataTypeValue: number | undefined): boolean {\r\n return dataTypeValue === AttributeDataType.Currency || dataTypeValue === AttributeDataType.Decimal;\r\n}\r\n\r\n/**\r\n * Checks if the data type value corresponds to a range type integer.\r\n * @param dataTypeValue\r\n */\r\nexport function isRangeTypeForInteger(dataTypeValue: number | undefined): boolean {\r\n return (\r\n dataTypeValue === AttributeDataType.Currency ||\r\n dataTypeValue === AttributeDataType.Decimal ||\r\n dataTypeValue === AttributeDataType.Integer\r\n );\r\n}\r\n\r\n/**\r\n * Checks if the data type value corresponds to a boolean.\r\n * @param dataTypeValue\r\n */\r\nexport function isBoolean(dataTypeValue: number | undefined): boolean {\r\n return (\r\n dataTypeValue === AttributeDataType.TrueFalse);\r\n}\r\n\r\n/**\r\n * Checks if the data type value corresponds to a custom input box Range.\r\n * @param dataTypeValue\r\n */\r\nexport function isCustomRangeTypeIntegerSelected(\r\n selectedRefinementCriterion: ProductRefinerValue,\r\n parentProductRefinerHierarchy: IProductRefinerHierarchy\r\n): boolean {\r\n return (\r\n selectedRefinementCriterion?.RowNumber !== undefined &&\r\n selectedRefinementCriterion?.RowNumber !== null &&\r\n selectedRefinementCriterion?.DataTypeValue === AttributeDataType.Integer &&\r\n parentProductRefinerHierarchy.DisplayTemplateValue === DisplayTemplate.Range\r\n );\r\n}\r\n\r\n/**\r\n * Checks if the selectedRefinementCriterion is siingle type with API va;ues or custom type.\r\n * If custom type then RowNumber is null\r\n * @param dataTypeValue\r\n */\r\nexport function isSingleSelectRangeTypeIntegerSelected(\r\n selectedRefinementCriterion: ProductRefinerValue,\r\n productRefinerValue: ProductRefinerValue\r\n): boolean {\r\n return (\r\n productRefinerValue.LeftValueBoundString === selectedRefinementCriterion?.LeftValueBoundString &&\r\n productRefinerValue.RightValueBoundString === selectedRefinementCriterion?.RightValueBoundString &&\r\n selectedRefinementCriterion?.RowNumber !== undefined &&\r\n selectedRefinementCriterion?.RowNumber !== null &&\r\n selectedRefinementCriterion !== undefined\r\n );\r\n}\r\n\r\n/**\r\n * Find the refinement criterion associated with this product refiner value.\r\n * @param productRefinerValue Product refiner value to match.\r\n * @param refinementCriteria Selected refinement criteria.\r\n */\r\nexport function findMatchingRefinementCriterion(\r\n productRefinerValue: ProductRefinerValue,\r\n refinementCriteria: ProductRefinerValue[]\r\n): ProductRefinerValue | undefined {\r\n // If the value is a range, then match only on data type value; otherwise match on item string\r\n return refinementCriteria.find((refinementCriterion: ProductRefinerValue) =>\r\n isMatchingRefinementCriterion(productRefinerValue, refinementCriterion)\r\n );\r\n}\r\n\r\n/**\r\n * Find the refinement criterion associated with this product refiner value.\r\n * @param productRefinerValue Product refiner value to match.\r\n * @param refinementCriteria Selected refinement criteria.\r\n * @param refinementCriterion\r\n */\r\nexport function isMatchingRefinementCriterion(\r\n productRefinerValue: ProductRefinerValue,\r\n refinementCriterion: ProductRefinerValue,\r\n parent?: IProductRefinerHierarchy\r\n): boolean {\r\n // If the value is a range, then match only on data type value; otherwise match on item string\r\n // Distinguish by displaytype also\r\n return (\r\n refinementCriterion.RefinerRecordId === productRefinerValue.RefinerRecordId &&\r\n refinementCriterion.RefinerSourceValue === productRefinerValue.RefinerSourceValue &&\r\n refinementCriterion.DataTypeValue === productRefinerValue.DataTypeValue &&\r\n ((parent?.DisplayTemplateValue === DisplayTemplate.Range\r\n ? isRangeType(refinementCriterion.DataTypeValue)\r\n : isRangeTypeForInteger(refinementCriterion.DataTypeValue)) ||\r\n refinementCriterion.LeftValueBoundString === productRefinerValue.LeftValueBoundString)\r\n );\r\n}\r\n\r\nexport function getIntegerRangeName(productRefinerValue: ProductRefinerValue): string {\r\n let rangeValue = '';\r\n\r\n if (productRefinerValue.LeftValueBoundString === '' && productRefinerValue.RightValueBoundString !== '') {\r\n rangeValue = `< ${productRefinerValue.RightValueBoundLocalizedString || productRefinerValue.RightValueBoundString}`;\r\n } else if (productRefinerValue.RightValueBoundString === '' && productRefinerValue.LeftValueBoundString !== '') {\r\n rangeValue = `> ${productRefinerValue.LeftValueBoundLocalizedString || productRefinerValue.LeftValueBoundString}`;\r\n } else if (productRefinerValue.RightValueBoundString !== '' && productRefinerValue.LeftValueBoundString !== '') {\r\n rangeValue = `${productRefinerValue.LeftValueBoundLocalizedString ||\r\n productRefinerValue.LeftValueBoundString} - ${productRefinerValue.RightValueBoundString ||\r\n productRefinerValue.RightValueBoundString}`;\r\n }\r\n return rangeValue;\r\n}\r\n\r\n/**\r\n * Get input without formatting.\r\n * @param input - Input string.\r\n * @returns - Returns number.\r\n */\r\nexport function getInputWithoutFormatting(input: string): string {\r\n // First try to cast raw input to a number\r\n const inputAsNumber = Number(input);\r\n if (!Number.isNaN(inputAsNumber)) {\r\n return input;\r\n }\r\n\r\n // Otherwise try a reverse lookup and fall back to the raw input if all else fails\r\n // const reverseLookupResult = formattedPriceReverseLookup.get(input);\r\n // return reverseLookupResult || input;\r\n return input;\r\n}\r\n\r\nexport function getUpdatedRefinementCriteria(\r\n itemToggleNotification: IRefineItemToggleNotification,\r\n currentRefinementCriteria: ProductRefinerValue[]\r\n): ProductRefinerValue[] {\r\n const updatedRefinementCriteria: ProductRefinerValue[] = [];\r\n let toggledItemFound = false;\r\n\r\n // Keeping only itemToggled value for integer-range type in currentRefinementCriteria\r\n if (\r\n itemToggleNotification.parentProductRefinerHierarchy.DataTypeValue === AttributeDataType.Integer &&\r\n itemToggleNotification.parentProductRefinerHierarchy.DisplayTemplateValue === DisplayTemplate.Range\r\n ) {\r\n currentRefinementCriteria = currentRefinementCriteria.filter(r => {\r\n return r.RefinerRecordId !== itemToggleNotification.productRefinerValue.RefinerRecordId;\r\n });\r\n }\r\n\r\n currentRefinementCriteria.forEach((selectedCriterion: ProductRefinerValue) => {\r\n if (\r\n isMatchingRefinementCriterion(\r\n itemToggleNotification.productRefinerValue,\r\n selectedCriterion,\r\n itemToggleNotification.parentProductRefinerHierarchy\r\n )\r\n ) {\r\n toggledItemFound = true;\r\n if (itemToggleNotification.isSelecting) {\r\n const next = {\r\n ...selectedCriterion,\r\n LeftValueBoundString:\r\n (itemToggleNotification.rangeStart !== undefined && `${itemToggleNotification.rangeStart}`) ||\r\n selectedCriterion.LeftValueBoundString,\r\n RightValueBoundString:\r\n (itemToggleNotification.rangeEnd !== undefined && `${itemToggleNotification.rangeEnd}`) ||\r\n selectedCriterion.RightValueBoundString\r\n };\r\n updatedRefinementCriteria.push(next);\r\n } // Else the item is being de-selected, so omit it from the refinement criteria\r\n } else {\r\n // Keep existing criterion because it is not in the item toggle notification\r\n updatedRefinementCriteria.push(selectedCriterion);\r\n }\r\n });\r\n\r\n if (!toggledItemFound) {\r\n const next = {\r\n ...itemToggleNotification.productRefinerValue,\r\n LeftValueBoundString:\r\n (itemToggleNotification.rangeStart !== undefined && `${itemToggleNotification.rangeStart}`) ||\r\n itemToggleNotification.productRefinerValue.LeftValueBoundString,\r\n RightValueBoundString:\r\n (itemToggleNotification.rangeEnd !== undefined && `${itemToggleNotification.rangeEnd}`) ||\r\n itemToggleNotification.productRefinerValue.RightValueBoundString\r\n };\r\n updatedRefinementCriteria.push(next);\r\n\r\n // If single select, then deselect any others in the parent refiner group\r\n if (\r\n (itemToggleNotification.productRefinerValue.DataTypeValue === AttributeDataType.Text ||\r\n itemToggleNotification.productRefinerValue.DataTypeValue === AttributeDataType.TrueFalse) &&\r\n itemToggleNotification.parentProductRefinerHierarchy.RefinerTypeValue === RefinerType.SingleSelect\r\n ) {\r\n itemToggleNotification.parentProductRefinerHierarchy.Values.forEach((child: ProductRefinerValue) => {\r\n if (child.RefinerRecordId === next.RefinerRecordId && child.LeftValueBoundString === next.LeftValueBoundString) {\r\n // Do nothing\r\n } else {\r\n const matchingIndex = updatedRefinementCriteria.findIndex((criterion: ProductRefinerValue) =>\r\n isMatchingRefinementCriterion(child, criterion, itemToggleNotification.parentProductRefinerHierarchy)\r\n );\r\n if (matchingIndex > -1) {\r\n updatedRefinementCriteria.splice(matchingIndex, 1);\r\n }\r\n }\r\n });\r\n }\r\n }\r\n\r\n return updatedRefinementCriteria;\r\n}\r\n\r\nexport function formatPrice(\r\n amount: string | undefined,\r\n currency: string | undefined,\r\n locale: string | undefined,\r\n telemetry: ITelemetry\r\n): string {\r\n if (!amount || !currency) {\r\n telemetry.trace(`[refine-menu.utilities.formatPrice] could not format price for ${amount} ${currency}`);\r\n return amount || '';\r\n }\r\n const priceAmount = (amount && Number(amount)) || 0;\r\n let result: string;\r\n\r\n try {\r\n result = new Intl.NumberFormat(locale, {\r\n style: 'currency',\r\n currencyDisplay: 'symbol',\r\n currency,\r\n minimumFractionDigits: 0\r\n }).format(priceAmount);\r\n } catch (error) {\r\n result = `${priceAmount} ${currency}`;\r\n telemetry.warning(`[refine-menu.utilities.formatPrice] Failed to format price for ${result}: ${error}`);\r\n }\r\n\r\n return result;\r\n}\r\n","import { ICoreContext } from '@msdyn365-commerce/core';\r\nimport { ProductSearchResultExt } from \"../../modules/dlvry-search-result-container/components\";\r\nimport { Customer } from '@msdyn365-commerce/retail-proxy';\r\nimport { hasAccessToBuy } from '.';\r\n\r\nexport interface OnBuyHasAccessValidatorResult {\r\n isValid: boolean;\r\n message?: string;\r\n}\r\n\r\nexport async function onBuyHasAccessValidator(\r\n context: ICoreContext,\r\n customer: Customer | undefined,\r\n product: ProductSearchResultExt,\r\n validationMessage: string | undefined\r\n): Promise {\r\n if (!product || !product.AttributeValues) {\r\n return { isValid: true };\r\n }\r\n\r\n const hasAccess = hasAccessToBuy(context, customer, product.AttributeValues);\r\n\r\n return {\r\n isValid: hasAccess,\r\n message: hasAccess ? undefined : validationMessage\r\n };\r\n}\r\n","/*!\r\n * Copyright (c) Microsoft Corporation.\r\n * All rights reserved. See LICENSE in the project root for license information.\r\n */\r\n\r\nimport { ICookieValue, ICookieContext } from '@msdyn365-commerce/core';\r\n\r\nexport const GetCookie = (cookies: ICookieContext, cookieName: string): string | undefined => {\r\n const marketCookie = cookies.get(cookieName) as ICookieValue | undefined;\r\n\r\n if (marketCookie && marketCookie.value && marketCookie.value.length > 0) {\r\n return marketCookie.value;\r\n } else {\r\n return undefined;\r\n }\r\n};\r\n\r\nexport const SetCookie = (cookies: ICookieContext, value: string, cookieName: string, exp: number): void => {\r\n if (value) {\r\n cookies.set(cookieName, value, { path: '/', maxAge: exp });\r\n }\r\n};\r\n"],"names":["GetOrganizationCustomerInput","constructor","apiSettings","user","getDataServiceRequest","this","query","createDataServiceRequestForOperation","Entities","bypassCache","returnEntity","shouldCacheOutput","getCacheKey","getCacheObjectType","dataCacheType","DataServiceQuery","getOrganizationCustomerAction","async","input","ctx","requestContext","isAuthenticated","callActionOrExecute","getOrganizationCustomer","createObservableDataAction","id","action","inputData","_user$customerAccount","customerAccountNumber","getProductUnitOfMeasureOptionsInput","queryResultSettings","productIds","resultSettings","top","getProductUnitOfMeasureOptionsAsync","context","request","callerContext","BaseCollectionInput","pageType","refiners","category","searchText","includeAttributes","isUpdateRefinerPanel","locale","catalogId","channelInventoryConfiguration","inventoryRefiner","_objectSpread","Paging","toJS","Sorting","generateCacheKey","key","value","map","refiner","RefinerRecordId","LeftValueBoundString","RightValueBoundString","convertToString","createBaseCollectionInput","args","inputClassConstuctor","urlTokens","categoryId","QueryResultSettingsProxy","fromInputData","QueryResultSettings","queryRefiners","hydrateRefinersFromUrl","config","undefined","_inputData$config","updateRefinerPanel","getUpdateRefinerPanel","getCatalogId","_args$requestContext$","sorting","Columns","JSON","parse","decodeURIComponent","itemId","q","recommendation","productId","stringify","ProductId","Recommendation","SearchText","discountIds","DiscountIds","Error","CachedPriceForProductSearchResultInput","products","productRecIds","ArrayExtensions","hasElements","Promise","resolve","product","RecordId","projectDomain","ChannelId","channelId","CatalogId","productPrices","getActivePricesAsync","getPagingFromInputDataOrDefaultValue","Date","productResults","activePrice","find","price","_activePrice$Customer","_activePrice$BasePric","_activePrice$TradeAgr","_activePrice$Adjusted","Badge","getDiscountBadge","Price","CustomerContextualPrice","BasePrice","Math","max","TradeAgreementPrice","AdjustedPrice","ProductPrice","PrefetchedPrice","error","telemetry","exception","debug","GetFullProductsByCollectionInput","ProductListInventoryFilteringOptions","returnProducts","productSearchResults","metadataCount","productSearchResultsWithImages","productSearchResult","newImageUrl","generateProductImageUrl","PrimaryImageUrl","app","inventoryLevel","InventoryLevels","threshold","enableStockCheck","count","AttributeValues","element","InventoryProductAttributeRecordId","inventoryRanges","TextValue","InventoryOutOfStockAttributeValueText","channelInventoryConfigurationId","inventoryAwareSortableAttributeId","ProductAvailabilitySortableAttributeRecordId","actionDataAction","_context$requestConte","_context$requestConte2","_context$requestConte3","_context$requestConte4","_context$requestConte5","_context$requestConte6","promise","channelInventoryConfigurationPromise","searchProductId","searchCriteriaInput","Context","Refinement","slice","IncludeAttributes","SkipVariantExpansion","SearchCondition","index","length","_input$refiners$index","ExtensionProperties","addOrUpdateZeroPriceRefiner","shouldFilterAlcohol","addAlcoholRefinerAsync","addAllAttributeRefiners","AsyncResult","getInventoryConfigurationAsync","filter","isInStockRefiner","inventoryRefinerValue","getInventorySortableRefinerValue","some","push","productListInventoryDisplay","HideOOS","isInStock","inventoryInStockRefinerValue","prioritySortingAttribute","match","_input$queryResultSet","_input$queryResultSet2","priorityColumnName","column","ColumnName","IsDescending","SortOOS","_input$queryResultSet3","_input$queryResultSet4","sortColumnName","CategoryIds","searchByCriteriaAsync","searchObject","Number","isNaN","RecommendationListId","Ids","_context$requestConte7","accountInformation","getCustomer","GetCustomerInput","split","getProductPromotionsAsync","HeaderContext","CustomerAccountNumber","AccountNumber","LineContexts","p","_p$ProductId","forEach","x","MaxVariantPrice","MinVariantPrice","getCachedPriceForProductSearchResultDataAction","metadata","Top","itemsPerPage","skip","Skip","sortOptions","sortByOptionRelevanceDesc","sortByOptionRatingAsc","sortByOptionRatingDesc","sortByOptionNameAsc","sortByOptionNameDesc","sortByOptionPriceAsc","sortByOptionPriceDesc","sortByOptionBestSelling","sortByOptionNewScore","sortByOptionTrendingScore","MappedSearchInput","buildCacheKey","getMappedSearchConfiguration","getSearchConfigurationAsync","then","searchConfiguration","ProductSortColumns","sortColumn","toUpperCase","warning","Boolean","createInput","getMappedSearchConfigurationDataAction","getProductRefinerHierarchy","searchCriteria","productRefiners","getProductSearchRefinersAsync","trace","result","productRefiner","DefaultValues","RefinersByCollectionInput","getRefinersForCollectionDataAction","alcoholFilter","attributeRefiners","getAllAttributeRefiners","concat","getAlcoholRefiners","defaultRefiners","defaultCategoryIdValue","defaultProductIdValue","DataTypeValue","AttributeDataType","TrueFalse","UnitText","RowNumber","Count","RefinerSourceValue","ProductRefinerSource","Attribute","_input$channelInvento2","_input$channelInvento3","inventoryProductAttributeRecordId","AlcoholGroupAttributeId","isGodmodeEnabled","godmode","url","requestUrl","searchParams","get","toLowerCase","doAlcoholFiltering","alcoholRefinerRecordId","alcoholGroupAttributeId","alcoholRefiner","alcoholLicenseValue","_customer$Attributes","customer","alcoholLicense","Attributes","AttributeValue","StringValue","console","warn","Array","fill","_","toString","addAlcoholRefiner","priceRefiner","channel","Currency","getAttributeRefiners","customerAttributes","attributeRecordId","friendlyName","attributeValue","_customerAttributes$f","attribute","getForsvaretRefiner","forsvaretAttributeId","forsvaretAttributeRecordId","_customerAttributes$f2","IntegerValue","Integer","getSvalbardRefiner","_context$requestConte8","_context$requestConte9","svalbardAttributeId","svalbardAttributeRecordId","blockedSvalbardAttributeId","blockedSvalbardAttributeRecordId","_customerAttributes$f3","addAttributeRefiner","_context$requestConte10","_context$requestConte11","_context$requestConte12","_context$requestConte13","_context$requestConte14","_context$requestConte15","attributeRecordIds","tobaccoRefinerRecordId","cocacolaRefinerRecordId","bamaRefinerRecordId","dutyFreeSugarRefinerRecordId","norturaRefinerRecordId","transitRefiner","transitRefinerRecordId","addAttributeRefinerKeepExisting","forsvaretRefiner","svalbardRefiner","_context$requestConte16","_context$requestConte17","_context$requestConte18","_context$requestConte19","_context$requestConte20","_context$requestConte21","compressedRefinerKeys","compressedRefinerArray","parseQueryParam","compressedRefiner","parsedRefiner","refinerKey","_unused","buildListPageUrl","fullUrl","sortingColumns","skipCount","delete","sortedRefiners","sort","first","second","set","compressedRefiners","compressRefiners","href","getCurrentUrl","MsDyn365","isBrowser","URL","window","location","ChoiceSummary","React","props","super","closeButtonGlyph","_onClick","e","preventDefault","stopPropagation","target","currentTarget","clearAll","getAttribute","includes","selectedRefiner","_getSelectedRefinerChoice","onChoiceClicked","itemClicked","choiceClicked","nextItemToFocus","nextSibling","payLoad","getPayloadObject","telemetryContent","_this$props$context","selectedChoices","refinerHierarchy","choice","parent","hierarchy","Values","isMatchingRefinementCriterion","RefinerValue","_getKeyForRefinerValue","render","clearAllText","label","classNames","choiceAriaLabel","closeAriaLabel","yesLabel","noLabel","items","selectedRefinersMap","contentAction","etext","clearAllAttributes","getTelemetryAttributes","className","classnames","item","_labelText","isBoolean","labelText","valueText","LeftValueBoundLocalizedString","startsWith","replace","decodeBase64String","Object","assign","urlBuilder","onClick","role","style","fontWeight","productRefinerValue","choiceFormat","choiceRangeValueFormat","refinerValues","overallFormat","rangeFormat","refinerValueName","refinerName","KeyName","isRangeType","_formatPrice","filterValue","amount","currency","cultureFormatter","formatCurrency","selected","__decorate","computed","observer","ErrorMessage","_ref","text","FeatureSearchResultItem","_context$request$app","imageSettings","resources","productName","Name","productRecordId","productUrl","getProductPageUrlSync","actionContext","fallbackImage","getFallbackImageUrl","ItemId","OmniChannelMedia","heading","featureSimilarDescriptionTitle","featureSimilarLooksTitle","onTelemetryClick","gridSettings","imageUrl","altText","img","src","imageProps","fallBackSrc","Image","loadFailureBehavior","renderProductPlacementImage","title","Link","ariaLabel","ModalToggle","innerRef","ref","SearchResultModal","modal","modalNode","modalHeader","modalHeaderNode","modalFooter","modalFooterNode","modalBody","ModalBody","Modal","autoFocus","applicationNode","returnFocusRef","returnRef","isOpen","toggle","onModalToggle","zIndex","ModalHeader","modalTitle","ModalFooter","Button","modalCloseButtonText","getInventoryLabel","productInventoryStatus","shippingInventory","shipping","ProductAvailableQuantity","StockLevelLabel","inventoryAttribute","callAddWishlistLine","wishlistId","toastErrorHeader","getCustomerAccount","createdCommerceList","addLinesAsync","buildWishlistLine","update","createGetByCustomerInput","err","_error$data","_error$data2","footer","data","CorrelationId","toasts","customerInput","getWishlistButton","wishlists","defaultWishlistName","_wishlists$0$Commerce","isWishlisted","CommerceListLines","removeFromWishlistButtonText","addToWishlistButtonText","wishlistLineId","foundWishlistItem","commerceListLine","LineId","getWishlistLineIdFromProductId","removeLinesAsync","Id","commerceList","newWishlists","catch","_error$data5","_error$data6","removeItemFromWishlist","productInputs","productInput","ProductInput","simpleProduct","getSimpleProducts","getWishlistByCustomerId","toast","addedProductToWishlistText","type","autoClose","position","canClose","showProgress","wishlistName","listData","CustomerId","CommerceListTypeValue","createCommerceListAsync","_error$data3","_error$data4","moveItemToWishlist","ProductSearchResultItems","cart","simpleProducts","customerInformation","orgInformation","orderTemplates","unitConversions","moduleType","moduleId","allowBackNavigation","quickviewSlot","productComparisonButton","isPriceMinMaxEnabled","productsDimensionAvailabilities","validatedProductAccess","disableBuyButtons","showPrices","productInventoryInformation","orderTemplatesState","setOrderTemplatesState","cartQueue","PQueue","concurrency","updateOrderTemplatesAsync","newOrderTemplates","newOrderTemplate","every","productList","splice","OrderTemplate","GetOrderTemplatesInput","getOrderTemplates","retrieveOrderTemplates","priceResources","priceRangeSeparator","_validatedProductAcce","ProductComponent","freePriceText","priceFree","originalPriceText","currentPriceText","ratingAriaLabel","allowBack","typeName","ProductRecordId","buyAlwaysAdd","showAgreementProduct","hasAgreementProducts","onUpdateOrderTemplates","quickViewButton","wishlistButton","inventoryLabel","inventoryStatus","disableBuyButton","showPrice","userHasAccess","HasAccess","swatchItemAriaLabel","addToCartText","updateCartText","removeFromCartText","outOfStockText","priceErrorText","toastStrings","errorHeader","productsAddedToCart","productsRemovedFromCart","productsUpdatedInCart","goToCart","toastGoToCart","noAccessToProduct","toastNoAccessToProduct","inCartTooltipText","transitTooltip","agreementProductTooltip","dimensionAvailabilities","dimensionAvailability","masterProductId","MasterProductId","addToOrderTemplateResources","addToOrderTemplateHeader","noOrderTemplatesMessage","noOrderTemplatesDescription","createAnOrderTemplateButtonText","createNewOrderTemplateButtonText","cancelOrderTemplateCreationButtonText","selectTemplatesText","addToTemplateButtonText","lineItemsText","createOrderTemplateHeader","orderTemplateTitle","orderTemplateNameAriaLabel","createOrderTemplateDescription","defaultOrderTemplateName","createOrderTemplateButtonText","cancelNewOrderTemplateCreationButtonText","viewOrderTemplateButtonText","continueShoppingButtonText","itemAddedToOrderTemplateHeaderItemOneText","itemAddedToOrderTemplateHeaderItemFormatText","itemAddedToOrderTemplateHeaderMessageText","duplicatedProductsHeader","duplicatedProductsDescription","updateQuantityButtonText","cancelDuplicateItemsButtonText","addToOrderTemplateButtonText","addToOrderTemplateButtonTooltip","onBuyValidate","onBuyHasAccessValidator","Separator","separator","Title","RangeRefineItemInput","_formattedPriceReverseLookup","Map","_changeMinInputRange","bind","_changeMaxInputRange","_applyCustom","minInput","maxInput","initialMin","initialMax","selectedRefinementCriterion","parentProductRefinerHierarchy","isCustomRangeTypeIntegerSelected","state","validationErrorMin","validationErrorMax","selectedMin","selectedMax","invalidData","isChecked","shouldComponentUpdate","nextProps","nextState","componentDidUpdate","previousProps","updateInputRangerProps","rangeType","_renderInputFields","_this$props$selectedR","_this$props$selectedR2","_this$props$selectedR3","_this$props$selectedR4","_isUndefined","setState","isDisabled","refineItemCommonProps","formAttrs","rangeNameFormat","minInputClassName","maxInputClassName","placeholder","onChange","disabled","event","selectedMinValue","_getInputWithoutFormatting","minTouched","onToggle","maxNum","_validateRange","isSelecting","trim","min","validationErrorRange","inputAsNum","RangeRefineItem","_selectedRefinementCr","_ref2","getLabels","sliderId","minPrice","maxPrice","labelId","labelString","labelPositioning","getSliderThumbs","sliderKey","selectedMinPrice","selectedMaxPrice","_this$props$minValueS","_this$props$maxValueS","minValueSliderThumbAriaLabel","currencyCode","ariaValueText","maxValueSliderThumbAriaLabel","_onRangeUpdate","_onRangeUpdateEnd","_handleRangeTooltipText","_changeMin","_changeMax","_finishChangeMin","_finishChangeMax","String","minValue","maxValue","labels","sliderKeyString","sliderThumbs","touchedMin","touchedMax","updateSliderProps","_renderSlider","_ref3","_this$props$selectedR5","_this$props$selectedR6","_ref4","_this$props$selectedR7","_this$props$selectedR8","formattedSelectedMin","_getFormattedSelectedValue","formattedSelectedMax","minLabel","onFocus","onBlur","maxLabel","placeholderTextMax","ariaAttributes","Slider","inForm","step","orientation","showLabels","showTooltip","onChangeEnd","debounce","handleTooltipText","_changeValue","inputType","selectedKey","touchedKey","validationErrorNaN","_focus","rangeStart","rangeEnd","selectedMaxValue","maxTouched","minNum","setTimeout","current","focus","touched","validationError","sliderChangeNotification","eventType","firstThumbValue","secondThumbValue","_focusOnSliderThumb","document","getElementById","tooltip","RefineItem","anchorType","_this$props$parentPro","_this$props$parentPro2","_this$props","productCountAriaLabel","singleProductCountAriaLabel","children","refineItemAriaLabel","refineItemsAriaLabel","yesText","noText","attrs","_objectWithoutProperties","_excluded","isSingleSelect","RefinerTypeValue","RefinerType","SingleSelect","itemTypeClassName","SourceValue","Rating","_renderRating","productText","productCount","refineMenuItemAriaLabel","format","dimensionType","toLocaleLowerCase","shouldDisplayAsSwatch","_getShouldDisplayAsSwatch","hasColor","StringExtensions","isNullOrWhitespace","SwatchColorHexCode","hasImage","SwatchImageUrl","hasContentSwatch","isBase64EncodePrefixed","join","_getRefinerUrl","tabIndex","_renderSwatch","checkIfShouldDisplayAsSwatch","_productRefinerValue$","swatchItems","colorHexCode","SwatchComponent","list","isSelectionEnabled","isRefineItem","ratingUserCountAriaLabel","ratingSingleUserCountAriaLabel","_productRefinerValue$2","refinerRating","parseInt","ratingRefiner","selectedRefinerValues","selectedRating","defaultChkProductCount","ratingComponentClass","productCountAriaLabelValue","isMobileView","RatingComponent","avgRating","ratingCount","hideCount","readOnly","moduleTypeName","RefineSubmenu","MaxItems","_onToggleItem","_onToggleSubmenu","isExpanded","isExpandedOnInitialLoad","expanded","isShowFullList","productRefinerHierarchy","hideRating","keyName","_keyName","Collapse","timeout","onEntered","dispatchEvent","Event","_renderChildItems","_renderRange","_renderSingleMultiSelect","_productRefinerHierar","isMobile","refinerValuesList","a","b","localeCompare","listItems","child","findMatchingRefinementCriterion","selectedValue","_getRangeType","DisplayTemplateValue","DisplayTemplate","Range","SliderWithBars","_productRefinerHierar2","itemToggleNotification","onUpdateRefiners","prevState","ProductRefinerValueDataTypeValue","ProductRefinerTypeValue","dataTypeValue","Decimal","refinementCriteria","refinementCriterion","getUpdatedRefinementCriteria","currentRefinementCriteria","updatedRefinementCriteria","toggledItemFound","r","selectedCriterion","next","Text","matchingIndex","findIndex","criterion","validationMessage","isValid","hasAccess","hasAccessToBuy","message","GetCookie","cookies","cookieName","marketCookie","SetCookie","exp","path","maxAge"],"sourceRoot":""}