{"version":3,"file":"static/js/96499da3c89c66ce13f1.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,GAIR,MAAM,IAAI8C,MAAM,0VCrNd,MAAOC,EAGT7F,YAAmB8F,GAQZ,KAAAnF,YAAc,IAAc,qCAAqCsE,KAAKO,UAAUpF,KAAK0F,YAMrF,KAAAlF,mBAAqB,IAAc,sBAMnC,KAAAC,cAAgB,IAAiB,OAnBpCT,KAAK0F,SAAWA,GA6FjB,MAOP,GAP8DvE,EAAAA,EAAAA,IAA2B,CACrFC,GAAI,uFAEJC,OA1DGT,eACHC,EACAkB,GAEA,IAAI4D,EACJ,IAAIC,EAAAA,gBAAgBC,YAAYhF,EAAM6E,UAGlC,OAAOI,QAAQC,QAAQ,IAFvBJ,EAAgB9E,EAAM6E,SAAStC,KAAI4C,GAAWA,EAAQC,WAK1D,MAAMvD,GAAY+B,EAAAA,EAAAA,IAAa1C,EAAQhB,gBAEjCmF,EAAkC,CAAEC,WAAYpE,EAAQhB,eAAelB,YAAYuG,UAAWC,UAAW3D,GAG/G,IACI,MAAM4D,QAAsBC,EAAAA,EAAAA,sBAAqB,CAAEtE,cAAeF,EAASL,oBAAqBqC,EAAAA,yBAAyByC,qCAAqCzE,IAC1JmE,EACAP,EACA,IAAIc,KACJ,KACA,MACA,GACA,GACA,GAEEC,EAAiB7F,EAAM6E,SAAStC,KAAI4C,IACtC,MAAMW,EAAcL,EAAcM,MAAKC,GAASA,EAAMxB,YAAcW,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,MAFA9F,EAAQ+F,UAAUC,UAAUF,GAC5B9F,EAAQ+F,UAAUE,MAAM,sEAClB,IAAIxC,MAAM,wEAWpB3E,MAtE+D6E,GACxD,IAAID,EAAuCC,KCfhD,MAAOuC,UAAyC/F,EAAAA,EAAtDtC,kCAKW,KAAAY,mBAAqB,IAAc,0BAMnC,KAAAC,cAAgB,IAGG,aAAlBT,KAAKmC,UACJnC,KAAKoC,UAAYpC,KAAKoC,SAAS8F,OAAS,GACxClI,KAAK0B,qBACF1B,KAAK0B,oBAAoBsB,SACzBhD,KAAK0B,oBAAoBsB,QAAQ4B,SACjC5E,KAAK0B,oBAAoBsB,QAAQ4B,QAAQsD,OAAS,EAE/C,UAEJ,eAOR,IAAKC,GAAZ,SAAYA,GAIRA,EAAA,kBAKAA,EAAA,kBAKAA,EAAA,kBAdJ,CAAYA,IAAAA,EAAoC,KA0DzCvH,eAAewH,EAClBC,EACAtG,EACAuG,EACA3F,GAEA,MAEM4F,EAAiCF,EAAqBjF,KAAIoF,IAC5D,MAAMC,GAAcC,EAAAA,EAAAA,yBAAwBF,EAAqBzG,EAAQhB,eAAelB,aAMxF,OAJI4I,IACAD,EAAoBG,gBAAkBF,GAGnCD,KAKX,GACIzG,EAAQhB,eAAe6H,IAAIxE,OAAOyE,iBAAmBC,EAAAA,gBAAgBC,YACd,IAAvDhH,EAAQhB,eAAe6H,IAAIxE,OAAO4E,iBAElC,MAAO,CACHtD,SAAU6C,EACVU,MAAOX,MAAAA,EAAAA,EApBqB,GA+CpC,MAAO,CACH5C,SAxBmB6C,EAA+BnF,KAAIoF,IACtD,GAAI5C,EAAAA,gBAAgBC,YAAY2C,EAAoBU,iBAChD,IAAK,MAAMC,KAAWX,EAAoBU,gBAElCvG,QACqB0B,IAArB8E,EAAQlD,UACRkD,EAAQlD,WAAatD,EAA8ByG,mCAEG,QAAtDrH,EAAQhB,eAAe6H,IAAIxE,OAAOiF,iBAClCF,EAAQG,YAAc3G,EAA8B4G,wCAMpDJ,EAAQG,UAAY,IAKhC,OAAOd,KAKPS,MAAOX,MAAAA,EAAAA,EAjDyB,EAmDhCkB,gCAAiC7G,EAC3BA,EAA8ByG,uCAC9B/E,EACNoF,kCAAmC9G,EAC7BA,EAA8B+G,kDAC9BrF,GAmMP,MAAMsF,GAAmBxI,EAAAA,EAAAA,IAA2B,CACvDC,GAAI,qFACJC,OA1LJT,eAAsBC,EAAyCkB,GAAuB,IAAA6H,EAAAC,EAAAC,EAAAC,EAAAC,EAClF,IAAIC,EACAC,EACAC,EACJ,MAAMC,EAA6C,GACnDA,EAAoBC,QAAU,CAAElE,UAAWpE,EAAQhB,eAAelB,YAAYuG,UAAWC,UAAWxF,EAAM6B,WAE1G0H,EAAoBE,WAAazF,KAAKC,MAAMD,KAAKO,UAAUvE,EAAMuB,SAASmI,UAC1EH,EAAoBI,kBAAoB3J,EAAM0B,kBAC9C6H,EAAoBK,sBAAuB,EAC3CL,EAAoBM,gBAAkB7J,EAAMyB,WAI5C,IAAK,IAAIqI,EAAQ,EAAGA,EAAQP,EAAoBE,WAAYpC,OAAQyC,IAAS,CACzE,MAAMxB,EAAUiB,EAAoBE,WAAYK,GAEoC,IAAAC,EAApF,GAAIzB,EAAQ0B,qBAA8D,iBAAhC1B,EAAQ0B,oBAC9C1B,EAAQ0B,oBAAsBhG,KAAKC,MAAMD,KAAKO,UAAmD,QAA1CwF,EAAC/J,EAAMuB,SAASuI,GAAOE,2BAAmB,IAAAD,OAAA,EAAzCA,EAA2CL,UAI3GH,EAAoBE,YAAaQ,EAAAA,EAAAA,IAA4B/I,EAASqI,EAAoBE,aAEtFS,EAAAA,EAAAA,IAAoBhJ,UACdiJ,EAAAA,EAAAA,IAAuBjJ,EAASqI,SAGpCa,EAAAA,EAAAA,IAAwBlJ,EAASqI,GAGnCF,EADArJ,EAAM8B,8BACiCuI,EAAAA,YAAYnF,QAAQlF,EAAM8B,gCAE1BwI,EAAAA,EAAAA,gCAA+B,CAAElJ,cAAeF,IAE3F,MAAMY,QAAsCuH,EAKtCtH,EAAmBwH,EAAoBE,WAAW1D,MACpDvD,GAAWA,EAAQC,mBAAoBX,MAAAA,OAA6B,EAA7BA,EAA+ByG,qCAE1E,GAAIxG,EAAkB,CAClBwH,EAAoBE,WAAaF,EAAoBE,WAAWc,QAC5D/H,GAAWA,EAAQC,mBAAoBX,MAAAA,OAA6B,EAA7BA,EAA+ByG,qCAG1E,MAAMiC,EACFzI,EAAiBW,wBAAyBZ,MAAAA,OAA6B,EAA7BA,EAA+B4G,wCACzE3G,EAAiBY,yBAA0Bb,MAAAA,OAA6B,EAA7BA,EAA+B4G,uCACxE+B,GAAwBC,EAAAA,EAAAA,IAAiC5I,EAA+B0I,IAEzDjB,EAAoBE,WAAWkB,MAChEnI,GAAWA,EAAQC,mBAAoBgI,MAAAA,OAAqB,EAArBA,EAAuBhI,oBAE7BgI,GACjClB,EAAoBE,WAAWmB,KAAKH,GAI5C,IAAqC,QAAjC1B,EAAA7H,EAAQhB,eAAe6H,IAAIxE,cAAM,IAAAwF,OAAA,EAAjCA,EAAmC8B,+BAAgCvD,EAAqCwD,QAAS,CACjH,MAAMC,GAAY,EACZC,GAA+BN,EAAAA,EAAAA,IAAiC5I,EAA+BiJ,IAEzDxB,EAAoBE,WAAWkB,MACvEnI,GAAWA,EAAQC,mBAAoBuI,MAAAA,OAA4B,EAA5BA,EAA8BvI,oBAE7BuI,GACxCzB,EAAoBE,WAAWmB,KAAKI,GAI5C,GAAqC,QAArChC,EAAI9H,EAAQhB,eAAe6H,IAAIxE,cAAM,IAAAyF,GAAjCA,EAAmCiC,yBAA0B,CAC7D,MAAMA,EAA2B/J,EAAQhB,eAAe6H,IAAIxE,OAAO0H,yBAGnE,GAAIA,EAAyBC,MAAM,SAAU,KAAAC,EAAAC,EACzCpL,EAAMa,oBAAoBsB,QAA2C,QAApCgJ,EAAGnL,EAAMa,oBAAoBsB,eAAO,IAAAgJ,EAAAA,EAAI,GACzEnL,EAAMa,oBAAoBsB,QAAQ4B,QAAmD,QAA5CqH,EAAGpL,EAAMa,oBAAoBsB,QAAQ4B,eAAO,IAAAqH,EAAAA,EAAI,GACzF,MAAMC,EAAqB,QAAQJ,IACFjL,EAAMa,oBAAoBsB,QAAQ4B,QAAQ4G,MAAKW,GAAUA,EAAOC,aAAeF,KAE5GrL,EAAMa,oBAAoBsB,QAAQ4B,QAAQ6G,KAAK,CAC3CW,WAAYF,EACZG,cAAc,KAO9B,IACqC,QAAjCvC,EAAA/H,EAAQhB,eAAe6H,IAAIxE,cAAM,IAAA0F,OAAA,EAAjCA,EAAmC4B,+BAAgCvD,EAAqCmE,SACxG3J,EAA8B+G,6CAChC,KAAA6C,EAAAC,EACE3L,EAAMa,oBAAoBsB,QAA2C,QAApCuJ,EAAG1L,EAAMa,oBAAoBsB,eAAO,IAAAuJ,EAAAA,EAAI,GACzE1L,EAAMa,oBAAoBsB,QAAQ4B,QAAmD,QAA5C4H,EAAG3L,EAAMa,oBAAoBsB,QAAQ4B,eAAO,IAAA4H,EAAAA,EAAI,GACzF,MAAMC,EAAiB,QAAQ9J,EAA8B+G,+CAChC7I,EAAMa,oBAAoBsB,QAAQ4B,QAAQ4G,MAAKW,GAAUA,EAAOC,aAAeK,KAExG5L,EAAMa,oBAAoBsB,QAAQ4B,QAAQ6G,KAAK,CAC3CW,WAAYK,EACZJ,cAAc,IAK1B,GAAuB,aAAnBxL,EAAMsB,UAAuD,QAAhC4H,EAAIhI,EAAQhB,eAAed,aAAK,IAAA8J,GAA5BA,EAA8BjG,WAAY,CAC3E,IAAIjD,EAAMwB,SAUN,MAAM,IAAImD,MAAM,wFAThB4E,EAAoBsC,YAAc,CAAC7L,EAAMwB,UAnGnB,GAoGtB4H,GAAU0C,EAAAA,EAAAA,uBACN,CACI1K,cAAeF,EACfL,oBAAqBb,EAAMa,qBAE/B0I,QAKL,GAAIvJ,EAAMyB,YAA0C,QAAhC0H,EAAIjI,EAAQhB,eAAed,aAAK,IAAA+J,GAA5BA,EAA8B/E,IAAMlD,EAAQhB,eAAed,MAAMiF,eAC5FkF,EAAoBM,gBAAkB7J,EAAMyB,WAC5C2H,GAAU0C,EAAAA,EAAAA,uBACN,CACI1K,cAAeF,EACfL,oBAAqBb,EAAMa,qBAE/B0I,OAED,MAAIvJ,EAAMyB,YAAcP,EAAQhB,eAAed,OAAS8B,EAAQhB,eAAed,MAAMiF,gBA2BxF,MAAM,IAAIM,MAAM,qGA3BwF,CACxG,MAAMoH,EAAe/H,KAAKC,MAAMjE,EAAMyB,YAItC,GAHIP,EAAQhB,eAAed,MAAMkF,YAC7BgF,EAAkB0C,OAAOD,EAAavH,YAEtCwH,OAAOC,MAAM3C,GACb,MAAM,IAAI3E,MAAM,mDACb,IAEFoH,EAAatH,eAEd,MAAM,IAAIE,MAAM,0CAEhB4E,EAAoBM,gBAAkBkC,EAAarH,WACnD6E,EAAoB2C,qBAAuBH,EAAatH,eACpD6E,IACAC,EAAoB4C,IAAM,CAAC7C,GAvIT,IAyItBF,GAAU0C,EAAAA,EAAAA,uBACN,CACI1K,cAAeF,EACfL,oBAAqBb,EAAMa,qBAE/B0I,IAOZ,IAAI/B,QAA6B4B,EAWjC,GARA5B,EAAqB4E,SAAQC,IACzBA,EAAE9F,MAAQ,EACV8F,EAAE5F,UAAY,EACd4F,EAAEC,gBAAkB,EACpBD,EAAEE,gBAAkB,EACpBF,EAAEtF,iBAAkB,KAGpB7F,EAAQhB,eAAejB,KAAKkB,gBAC5B,IACI,MAAMH,EAAQ,IAAI4E,EAAuC4C,GAEzDA,QADqBgF,EAA+CxM,EAAOkB,GAE7E,MAAO8F,IAKb,OAAOO,EAAeC,EAAsBtG,EAASkI,EAAQqD,SAASrE,MAAOtG,IAM7E9B,MA9RiB8C,IACjB,MAAM9C,GAAQ6C,EAAAA,EAAAA,GAA0BC,EAAMsE,GAc9C,OAXIpH,EAAMa,oBAAoBoB,QAAUa,EAAKS,SACzCvD,EAAMa,oBAAoBoB,OAAOyK,IAAM5J,EAAKS,OAAOoJ,cAAgB,GAInE3M,EAAMa,oBAAoBoB,QAAUa,EAAK5C,eAAed,OAAS0D,EAAK5C,eAAed,MAAMwN,OAC3F5M,EAAMa,oBAAoBoB,OAAO4K,MAAQ/J,EAAK5C,eAAed,MAAMwN,MAGvE5M,EAAMa,oBAAoBuH,OAAQ,EAE3BpI,KAkRX,0OC9VO,MAAM8M,EAAc,CACvBC,0BAA2B,eAC3BC,sBAAuB,oBACvBC,uBAAwB,qBACxBC,oBAAqB,WACrBC,qBAAsB,YACtBC,qBAAsB,YACtBC,sBAAuB,aACvBC,wBAAyB,cACzBC,qBAAsB,WACtBC,0BAA2B,iBAMzB,MAAOC,EAGT1O,YAAYC,GAIL,KAAAU,YAAc,KAAMgO,EAAAA,EAAAA,eAAc,oBAAqBvO,KAAKH,aAE5D,KAAAW,mBAAqB,IAAM,oBAE3B,KAAAC,cAAgB,IAAiB,UAPpCT,KAAKH,YAAcA,GAepBe,eAAe4N,EAA6B3N,EAA0BC,GACzE,OAAO2N,EAAAA,EAAAA,6BAA4B,CAAExM,cAAenB,IAAO4N,MAAMC,IACxBA,EAAoBC,oBAAsB,IAC1ExL,KAA4CyL,IACzC,IAAI3L,EAAM,GACV,GAAI2L,EAAWzC,WACX,OAAQyC,EAAWzC,WAAW0C,eAC1B,IAAK,OACD5L,EAAM2L,EAAWxC,aAAesB,EAAYK,qBAAuBL,EAAYI,oBAC/E,MACJ,IAAK,QACD7K,EAAM2L,EAAWxC,aAAesB,EAAYO,sBAAwBP,EAAYM,qBAChF,MACJ,IAAK,gBACD/K,EAAM2L,EAAWxC,aAAesB,EAAYG,uBAAyBH,EAAYE,sBACjF,MACJ,IAAK,UACD3K,EAAMyK,EAAYC,0BAClB,MACJ,IAAK,mBACD1K,EAAMyK,EAAYQ,wBAClB,MACJ,IAAK,WACDjL,EAAMyK,EAAYS,qBAClB,MACJ,IAAK,gBACDlL,EAAMyK,EAAYU,+BAK1BvN,EAAIgH,UAAUiH,QAAQ,2DAE1B,GAAI7L,EACA,MAAO,CACHA,IAAAA,EACA2L,WAAAA,MAKXzD,OAAO4D,WAIb,MAAMC,EAAe3N,GACjB,IAAIgN,EAAkBhN,EAAUP,eAAelB,aAG7CqP,GAAyC/N,EAAAA,EAAAA,IAA2B,CAC7EC,GAAI,qFACJC,OAA8CmN,EAC9C3N,MAAOoO,IAGX,6KCxGKE,8DAAL,SAAKA,GACDA,EAAAA,EAAA,mDACAA,EAAAA,EAAA,iDAFJ,CAAKA,IAAAA,EAAa,KAQZ,MAAOC,UAAkClN,EAAAA,EAA/CtC,kCACW,KAAAY,mBAAqB,IAAM,iBAE3B,KAAAC,cAAgB,IACZ,QA6BRG,eAAeyO,EAAmCxO,EAAkCkB,GAAuB,IAAA6H,EAC9G,IAAIO,EAIAD,EAFA9H,EAAkC,IAAIvB,EAAMuB,WAAa,GAIzD8H,EADArJ,EAAM8B,8BACiCuI,EAAAA,YAAYnF,QAAQlF,EAAM8B,gCAE1BwI,EAAAA,EAAAA,gCAA+B,CAAElJ,cAAeF,IAE3F,MAAMY,QAAsCuH,EAKtCtH,EAAmBR,EAASwE,MAC9BvD,GAAWA,EAAQC,mBAAoBX,MAAAA,OAA6B,EAA7BA,EAA+ByG,qCAE1E,GAAIxG,EAAkB,CAClBR,EAAWA,EAASgJ,QAAO/H,GAAWA,EAAQC,mBAAoBX,MAAAA,OAA6B,EAA7BA,EAA+ByG,qCAEjG,MAAMiC,EACFzI,EAAiBW,wBAAyBZ,MAAAA,OAA6B,EAA7BA,EAA+B4G,wCACzE3G,EAAiBY,yBAA0Bb,MAAAA,OAA6B,EAA7BA,EAA+B4G,uCACxE+B,GAAwBC,EAAAA,EAAAA,IAAiC5I,EAA+B0I,IAEzDjJ,EAASoJ,MAAKnI,GAAWA,EAAQC,mBAAoBgI,MAAAA,OAAqB,EAArBA,EAAuBhI,oBAC5EgI,GACjClJ,EAASqJ,KAAKH,GAItB,IAAqC,QAAjC1B,EAAA7H,EAAQhB,eAAe6H,IAAIxE,cAAM,IAAAwF,OAAA,EAAjCA,EAAmC8B,+BAAgCvD,EAAAA,GAAqCwD,QAAS,CACjH,MAAMC,GAAY,EACZC,GAA+BN,EAAAA,EAAAA,IAAiC5I,EAA+BiJ,IAEzDxJ,EAASoJ,MACjDnI,GAAWA,EAAQC,mBAAoBuI,MAAAA,OAA4B,EAA5BA,EAA8BvI,oBAE7BuI,GACxCzJ,EAASqJ,KAAKI,GAItB,MAAMyD,GAAgBvE,EAAAA,EAAAA,IAAoBhJ,GACpCwN,QAA0BC,EAAAA,EAAAA,IAAwBzN,GAIxDK,GAAW0I,EAAAA,EAAAA,IAA4B/I,EAASK,GAC3CqN,OAAOH,QAAsBI,EAAAA,EAAAA,IAAmB3N,GAAW,IAC3D0N,OAAOF,GACZ,MAAMI,GAAkB7E,EAAAA,EAAAA,IAA4B/I,GAC/C0N,OAAOH,QAAsBI,EAAAA,EAAAA,IAAmB3N,GAAW,IAC3D0N,OAAOF,GAEZ,GAAuB,aAAnB1O,EAAMsB,SAAyB,CAC/B,GAAItB,EAAMwB,SAEN,OADAxB,EAAMuB,SAAWvB,EAAM2B,qBAAuBJ,EAAWuN,GAClDC,EAAAA,EAAAA,GACH,CACIlD,YAAa,CAAC7L,EAAMwB,UAAY8M,EAAcU,wBAC9CxF,QAAS,CACLlE,UAAWtF,EAAMhB,YAAYuG,UAC7BC,UAAWxF,EAAM6B,WAErB4H,WAAYzJ,EAAM2B,qBAAuBJ,EAAWuN,EACpDjF,gBAAiB7J,EAAMyB,YAE3BzB,EAAMa,oBACNK,GAGR,MAAM,IAAIyD,MAAM,oFAEhB,GAAI3E,EAAMyB,YAAcP,EAAQhB,eAAed,OAAS8B,EAAQhB,eAAed,MAAMgF,IAAMlD,EAAQhB,eAAed,MAAMiF,eAEpH,OADArE,EAAMuB,SAAWvB,EAAM2B,qBAAuBJ,EAAWuN,GAClDC,EAAAA,EAAAA,GACH,CACIlF,gBAAiB7J,EAAMyB,WACvB+H,QAAS,CACLlE,UAAWtF,EAAMhB,YAAYuG,UAC7BC,UAAWxF,EAAM6B,WAErB4H,WAAYzJ,EAAM2B,qBAAuBJ,EAAWuN,GAExD9O,EAAMa,oBACNK,GAGR,GAAIlB,EAAMyB,YAAcP,EAAQhB,eAAed,OAAS8B,EAAQhB,eAAed,MAAMiF,eAAgB,CACjG,MAAM0H,EAAe/H,KAAKC,MAAMjE,EAAMyB,YAItC,GAHIP,EAAQhB,eAAed,MAAMkF,YAC7BgF,EAAkB0C,OAAOD,EAAavH,YAEtCwH,OAAOC,MAAM3C,GACb,MAAM,IAAI3E,MAAM,mDACb,GAAKoH,EAAatH,eAElB,CACH,MAAM8E,EAA6C,GAYnD,OAXAvJ,EAAMuB,SAAWvB,EAAM2B,qBAAuBJ,EAAWuN,EACzDvF,EAAoBC,QAAU,CAC1BlE,UAAWtF,EAAMhB,YAAYuG,UAC7BC,UAAWxF,EAAM6B,WAErB0H,EAAoBM,gBAAkBkC,EAAarH,WACnD6E,EAAoBE,WAAazJ,EAAM2B,qBAAuBJ,EAAWuN,EACzEvF,EAAoB2C,qBAAuBH,EAAatH,eACpD6E,IACAC,EAAoB4C,IAAM,CAAC7C,GAAmBgF,EAAcW,yBAEzDF,EAAAA,EAAAA,GAA2BxF,EAAqBvJ,EAAMa,oBAAqBK,GAdlF,MAAM,IAAIyD,MAAM,0CAiBpB,MAAM,IAAIA,MAAM,qGAKrB,MAAMmE,GAAmBxI,EAAAA,EAAAA,IAA2B,CACvDC,GAAI,iFACJC,OAA6CgO,EAC7CxO,MArIiB8C,IACVD,EAAAA,EAAAA,GAA0BC,EAAMyL,KAuI3C,yWClKO,MAAM7D,EAAmCA,CAC5C5I,EACAiJ,KAEA,GAAIjJ,GAAiCA,EAA8B+G,6CAC/D,MAAO,CACHpG,gBAAiBX,EAA8B+G,6CAC/CqG,cAAeC,EAAAA,kBAAkBC,UACjC1M,qBAAsBqI,EAAY,OAAS,QAC3CpI,sBAAuBoI,EAAY,OAAS,QAC5CsE,SAAU,GACVC,UAAW,EACXC,MAAO,EACPvF,oBAAqB,GACrBwF,mBAAoBC,EAAAA,qBAAqBC,aAwGrBpP,EAAAA,EAAAA,IAA2B,CACvDC,GAAI,4EACJC,OAjCJT,eAAsBC,EAA0CkB,GAAuB,IAAAyO,EACnF,MAAMpO,QAAiBwN,EAAAA,EAAAA,GACnB,CACIvF,QAAS,CACLlE,UAAWtF,EAAMhB,YAAYuG,UAC7BC,UAAWxF,EAAM6B,YAGzB7B,EAAMa,oBACNK,GAKJ,OACgF,KAAxC,QAAnCyO,EAAA3P,EAAM8B,qCAA6B,IAAA6N,OAAA,EAAnCA,EAAqCpH,oCAClChH,EAASwE,MAAKvD,IAAO,IAAAoN,EAAA,OAAIpN,EAAQ4C,YAAgD,QAAxCwK,EAAK5P,EAAM8B,qCAA6B,IAAA8N,OAAA,EAAnCA,EAAqCrH,uCAE1C,IAA5CvI,EAAM6P,mCACHtO,EAASwE,MAAKvD,GAAWA,EAAQ4C,WAAapF,EAAM6P,qCACxD,kvBC7HR,MAAMC,EAA0B,WAEhC,SAASC,EAAiB7O,GAAuB,IAAA6H,EAC7C,MAAMiH,EAA2E,QAApEjH,EAAG7H,EAAQhB,eAAe+P,IAAIC,WAAWC,aAAaC,IAAI,kBAAU,IAAArH,OAAA,EAAjEA,EAAmEsH,cAEnF,MAAmB,MAAZL,GAA+B,SAAZA,EAGxB,SAAU9F,EAAoBhJ,GAAuB,IAAA8H,EAAAC,EACvD,MAAMqH,EAA0G,WAApB,QAAjEtH,EAAA9H,EAAQhB,eAAe+P,IAAIC,WAAWC,aAAaC,IAAI,kBAAU,IAAApH,OAAA,EAAjEA,EAAmEqH,eACxFE,EAAyBvE,OAAwC,QAAlC/C,EAAC/H,EAAQhB,eAAe6H,IAAIxE,cAAM,IAAA0F,OAAA,EAAjCA,EAAmCsH,wBAEzE,OAAOD,IAAuBrE,MAAMsE,IAA2BA,EAAyB,EAGrFxQ,eAAe8O,EAAmB3N,GAAuB,IAAAgI,EAC5D,IAAIsH,EAA0BxE,OAAwC,QAAlC9C,EAAChI,EAAQhB,eAAe6H,IAAIxE,cAAM,IAAA2F,OAAA,EAAjCA,EAAmCqH,yBAEpEtE,MAAMuE,IAAwD,IAA5BA,KAClCA,EAA0BV,GAG9B,MAAMW,EAAgC,GAChCC,EAAsC,CACxCxB,cAAe,EACfxM,qBAAsB,IACtBD,gBAAiB+N,EACjBhB,mBAAoB,EACpB7M,sBAAuB,IACvB0M,SAAU,IAGdoB,EAAO7F,KAAK8F,GAEZ,IACI,IAAIC,EAAsB,EAE1B,GAAIzP,EAAQhB,eAAejB,KAAKkB,gBAAiB,KAAAyQ,EAG7C,MAAMC,QAAiBxQ,EAAAA,EAAAA,SAAwB,IAAIvB,EAAAA,6BAA6BoC,EAAQhB,eAAelB,YAAakC,EAAQhB,eAAejB,KAAK0B,uBAAyBO,GACnK4P,EAAiB9E,OAA0B,QAApB4E,EAACC,EAASE,kBAAU,IAAAH,GAAmD,QAAnDA,EAAnBA,EAAqB7K,MAAKsG,GAAKA,EAAEjH,WAAaoL,WAAwB,IAAAI,GAAgB,QAAhBA,EAAtEA,EAAwEI,sBAAc,IAAAJ,OAAA,EAAtFA,EAAwFK,aAElHhF,MAAM6E,GAENI,QAAQC,KAAK,qDAEbR,EAAsBG,OAI1BH,EAAsB,EAQ1BS,MAAMT,GAAqBU,KAAK,GAAGjF,SAAQ,CAACkF,EAAGxH,KAC3C2G,EAAO7F,KAAI5I,EAAAA,EAAC,GACL0O,GAAc,IACjBhO,sBAAuBoH,EAAQ,GAAGyH,WAClC5O,uBAAwBmH,EAAQ,GAAGyH,iBAG7C,MAAOvK,GACLkK,QAAQC,KAAK,2HAA4HnK,GAG7I,OAAOyJ,EAGJ1Q,eAAeyR,EAAkBtQ,EAAyBqI,GAA0C,IAAAJ,EACvG,IAAIqH,EAA0BxE,OAAwC,QAAlC7C,EAACjI,EAAQhB,eAAe6H,IAAIxE,cAAM,IAAA4F,OAAA,EAAjCA,EAAmCoH,yBAEpEtE,MAAMuE,IAAwD,IAA5BA,KAClCA,EAA0BV,GAG1BvG,EAAoBE,WAAYkB,MAAK0B,GAAKA,EAAE5J,kBAAoB+N,MAEhEjH,EAAoBE,WAAaF,EAAoBE,WAAYc,QAAO8B,GAAKA,EAAE5J,kBAAoB+N,KAGvG,MAAMjP,QAAiBsN,EAAmB3N,GAI1C,OAFAqI,EAAoBE,WAAaF,EAAoBE,WAAYmF,OAAOrN,GAEjE0D,QAAQC,UAGb,SAAU+E,EAA4B/I,EAAyBK,GAKjE,IAF+BwO,EAAiB7O,GAEnB,CACzB,MAAMuP,EAASlP,EAAW,IAAIA,GAAY,GAGpCkQ,EAAehB,EAAO1K,MAAKsG,GAA2B,IAAtBA,EAAE5J,kBAOjC,IAAAiP,EALP,GAAID,IAEKA,EAAa/O,sBAAwBsJ,OAAOyF,EAAa/O,sBAAwB,OAClF+O,EAAa/O,qBAAuB,aAIxC+N,EAAO7F,KAAK,CACR,cAAe,qEACf2E,MAAO,EACPL,cAAe,EACfxM,qBAAsB,OACtBsH,oBAAqB,GACrBvH,gBAAiB,EACjB+M,mBAAoB,EACpB7M,sBAAuB,aACvB2M,UAAW,EACXD,SAAwC,QAAhCqC,EAAExQ,EAAQhB,eAAeyR,eAAO,IAAAD,OAAA,EAA9BA,EAAgCE,WAIlD,OAAOnB,EAGX,OAAOlP,GAAY,GAGhBxB,eAAe8R,EAAqB3Q,EAAyB4Q,EAAqDC,EAA2BC,GAChJ,MAAMvB,EAAgC,GAChCjO,EAA+B,CACjC0M,cAAe,EACfxM,qBAAsB,IACtBD,gBAAiBsP,EACjBvC,mBAAoB,EACpB7M,sBAAuB,IACvB0M,SAAU,IAGdoB,EAAO7F,KAAKpI,GAEZ,IACI,IAAIyP,EAAiB,EAErB,GAAI/Q,EAAQhB,eAAejB,KAAKkB,gBAAiB,KAAA+R,EAC7C,MAAMC,EAAYnG,OAAO8F,MAAAA,GAA+D,QAA7CI,EAAlBJ,EAAoB/L,MAAKsG,GAAKA,EAAEjH,WAAa2M,WAAkB,IAAAG,GAAgB,QAAhBA,EAA/DA,EAAiElB,sBAAc,IAAAkB,OAAA,EAA/EA,EAAiFjB,aAEtGhF,MAAMkG,GAEFH,EACAd,QAAQC,KAAK,GAAGa,iDAEhBd,QAAQC,KAAK,4BAA4BY,yCAG7CE,EAAiBE,OAIrBF,EAAiB,EAGE,IAAnBA,GACAxB,EAAO7F,KAAI5I,EAAAA,EAAC,GACLQ,GAAO,IACVE,qBAAsBuP,EAAeV,WACrC5O,sBAAuBsP,EAAeV,cAGhD,MAAOvK,GACDgL,EACAd,QAAQC,KAAK,iBAAiBa,iFAA6FhL,GAE3HkK,QAAQC,KAAK,gDAAgDY,+DAAgF/K,GAIrJ,OAAOyJ,EAGJ1Q,eAAeqS,EAAoBlR,EAAyB4Q,GAAmD,IAAAO,EAClH,MAAMC,EAAwD,QAApCD,EAAGnR,EAAQhB,eAAe6H,IAAIxE,cAAM,IAAA8O,OAAA,EAAjCA,EAAmCE,2BAEhE,GAAKD,GAAyBpR,EAAQhB,eAAejB,KAAKkB,gBAI1D,IAAI,IAAAqS,EACA,MAAML,EAAYL,MAAAA,GAA0E,QAAxDU,EAAlBV,EAAoB/L,MAAKsG,GAAKA,EAAEjH,WAAa4G,OAAOsG,YAAsB,IAAAE,GAAgB,QAAhBA,EAA1EA,EAA4ExB,sBAAc,IAAAwB,OAAA,EAA1FA,EAA4FC,aAE9G,IAAKN,GAAalG,MAAMkG,IAA4B,IAAdA,EAClC,OAGJ,MAAO,CACHjD,cAAeC,EAAAA,kBAAkBuD,QACjChQ,qBAAsByP,EAAUZ,WAChC9O,gBAAiBuJ,OAAOsG,GACxB9C,mBAAoBC,EAAAA,qBAAqBC,UACzC/M,sBAAuBwP,EAAUZ,WACjClC,SAAU,IAEhB,MAAOrI,GAEL,YADAkK,QAAQlK,MAAM,oCAAqCA,IAKpDjH,eAAe4S,EAAoBzR,EAAyB4Q,EAAqDvI,EAA4CwI,GAC5JxI,EAAoBE,WAAYkB,MAAK0B,GAAKA,EAAE5J,kBAAoBsP,MAEhExI,EAAoBE,WAAaF,EAAoBE,WAAYc,QAAO8B,GAAKA,EAAE5J,kBAAoBsP,KAGvG,MAAMxQ,QAAiBsQ,EAAqB3Q,EAAS4Q,EAAoBC,GAEzExI,EAAoBE,WAAaF,EAAoBE,WAAYmF,OAAOrN,GAGrExB,eAAeqK,EAAwBlJ,EAAyBqI,GAA0C,IAAAqJ,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAG7G,GAFgBlD,EAAiB7O,GAG7B,OAGJ,IAAI4Q,EAAsD,GAE1D,GAAI5Q,EAAQhB,eAAejB,KAAKkB,gBAAiB,CAC7C,MAAM,YAAEnB,EAAaC,MAAM,sBAAE0B,IAA4BO,EAAQhB,eAEjE4R,SADuBzR,EAAAA,EAAAA,SAAwB,IAAIvB,EAAAA,6BAA6BE,EAAa2B,GAAyBO,IACxF6P,WAGlC,MAAMmC,EAA+B,CACA,QADAN,EACjC1R,EAAQhB,eAAe6H,IAAIxE,cAAM,IAAAqP,OAAA,EAAjCA,EAAmCO,uBACF,QADwBN,EACzD3R,EAAQhB,eAAe6H,IAAIxE,cAAM,IAAAsP,OAAA,EAAjCA,EAAmCO,uBACF,QADwBN,EACzD5R,EAAQhB,eAAe6H,IAAIxE,cAAM,IAAAuP,OAAA,EAAjCA,EAAmCO,wBACF,QADyBN,EAC1D7R,EAAQhB,eAAe6H,IAAIxE,cAAM,IAAAwP,OAAA,EAAjCA,EAAmCO,oBACF,QADqBN,EACtD9R,EAAQhB,eAAe6H,IAAIxE,cAAM,IAAAyP,OAAA,EAAjCA,EAAmCO,6BACF,QAD8BN,EAC/D/R,EAAQhB,eAAe6H,IAAIxE,cAAM,IAAA0P,OAAA,EAAjCA,EAAmCO,wBAGvC,IAAK,MAAMzB,KAAqBmB,EAAoB,CAChD,MAAM3S,EAAKyL,OAAO+F,IAGb9F,MAAM1L,IAAOA,EAAK,SACboS,EAAoBzR,EAAS4Q,EAAoBvI,EAAqBhJ,GAIpF,MAAMkT,QAAyBrB,EAAoBlR,EAAS4Q,GAExD2B,GACAlK,EAAoBE,WAAYmB,KAAK6I,GAItC1T,eAAe4O,EAAwBzN,GAAuB,IAAAwS,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAGjE,GAFgBhE,EAAiB7O,GAG7B,MAAO,GAGX,IAAI4Q,EAAsD,GAE1D,GAAI5Q,EAAQhB,eAAejB,KAAKkB,gBAAiB,CAC7C,MAAM,YAAEnB,EAAaC,MAAM,sBAAE0B,IAA4BO,EAAQhB,eAEjE4R,SADuBzR,EAAAA,EAAAA,SAAwB,IAAIvB,EAAAA,6BAA6BE,EAAa2B,GAAyBO,IACxF6P,WAGlC,MAAMmC,EAA+B,CACA,QADAQ,EACjCxS,EAAQhB,eAAe6H,IAAIxE,cAAM,IAAAmQ,OAAA,EAAjCA,EAAmCP,uBACF,QADwBQ,EACzDzS,EAAQhB,eAAe6H,IAAIxE,cAAM,IAAAoQ,OAAA,EAAjCA,EAAmCP,uBACF,QADwBQ,EACzD1S,EAAQhB,eAAe6H,IAAIxE,cAAM,IAAAqQ,OAAA,EAAjCA,EAAmCP,wBACF,QADyBQ,EAC1D3S,EAAQhB,eAAe6H,IAAIxE,cAAM,IAAAsQ,OAAA,EAAjCA,EAAmCP,oBACF,QADqBQ,EACtD5S,EAAQhB,eAAe6H,IAAIxE,cAAM,IAAAuQ,OAAA,EAAjCA,EAAmCP,6BACF,QAD8BQ,EAC/D7S,EAAQhB,eAAe6H,IAAIxE,cAAM,IAAAwQ,OAAA,EAAjCA,EAAmCP,wBAGjC/C,EAAgC,GAEtC,IAAK,MAAMsB,KAAqBmB,EAAoB,CAChD,MAAM3S,EAAKyL,OAAO+F,GAGlB,IAAK9F,MAAM1L,IAAOA,EAAK,EAAG,CACtB,MAAMgB,QAAiBsQ,EAAqB3Q,EAAS4Q,EAAoBvR,GACzEkQ,EAAO7F,QAAQrJ,IAIvB,MAAMkS,QAAyBrB,EAAoBlR,EAAS4Q,GAM5D,OAJI2B,GACAhD,EAAO7F,KAAK6I,GAGThD,0HCrSX,MAAMuD,EAAwB,CAC1B,gBACA,uBACA,kBACA,qBACA,wBACA,YAQS1Q,EAA0BpD,IACnC,MAAM+T,EAAyBC,EAAuC,WAAYhU,GAClF,OAAK+T,GAA4D,IAAlCA,EAAuB5M,OAIxB4M,EACzB1R,KAAI4R,IACD,IACI,MAAMC,EAAqC,GAI3C,OAHAJ,EAAsB5H,SAAQ,CAACiI,EAAYvK,KACvCsK,EAAcC,GAAcF,EAAkBrK,MAE3CsK,EACT,MAAAE,GACE,WAGP/J,OAAO4D,SAfD,IA2CFoG,EAAmBA,CAACC,EAAcjT,EAAkCkT,EAA+BC,KAE5G,QAAiBlR,IAAbjC,EAAwB,CACxB,GAAwB,IAApBA,EAAS8F,OACTmN,EAAQrE,aAAawE,OAAO,gBACzB,CACH,MAAMC,EAAiBrT,EAASsT,MAAK,CAACC,EAAOC,IACzCD,EAAMrS,iBAAmBsS,EAAOtS,iBAAmBqS,EAAMrS,gBAAkBsS,EAAOtS,gBAAkB,GAAK,IAE7G+R,EAAQrE,aAAa6E,IAAI,WAAYhR,KAAKO,UA9BrBhD,CAAAA,IAC7B,MAAM0T,EAA4C,GAUlD,OARA1T,EAAS6K,SAAQ5J,IACb,MAAM2R,EAAyC,GAC/CH,EAAsB5H,SAAQiI,IAC1BF,EAAkBvJ,KAAKpI,EAAQ6R,OAEnCY,EAAmBrK,KAAKuJ,MAGrBc,GAmBqDC,CAAiBN,KAKzE,OADAJ,EAAQrE,aAAawE,OAAO,QACrBH,EAAQW,KAGnB,YAAuB3R,IAAnBiR,GAC8B,IAA1BA,EAAepN,OACfmN,EAAQrE,aAAawE,OAAO,WAE5BH,EAAQrE,aAAa6E,IAAI,UAAWhR,KAAKO,UAAUkQ,IAIvDD,EAAQrE,aAAawE,OAAO,QACrBH,EAAQW,OAGfT,GACAF,EAAQrE,aAAa6E,IAAI,OAAQN,EAAUnD,YAGxCiD,EAAQW,OAQNjB,EAAkBA,CAAI7R,EAAanC,IACxCA,EAAed,OAASc,EAAed,MAAMiD,GAInC2B,KAAKC,MAAM/D,EAAed,MAAMiD,IAEvC,KAOE+S,EAAiBlV,GACtBmV,EAAAA,GAASC,UACF,IAAIC,IAAIC,OAAOC,SAASN,MAI/BjV,EAAe+P,IAAIC,WAAWiF,KACvB,IAAII,IAAIrV,EAAe+P,IAAIC,WAAWiF,MAE1C,IAAII,IAAsBrV,EAAe+P,IAAIC,gLC7GxD,IAAqBwF,EAArB,cAA2CC,EAAAA,cA4BvC5W,YAAY6W,GACRC,MAAMD,GA5BO,KAAAE,iBAA2B,gBAsJ3B,KAAAC,SAAYC,IACzBA,EAAEC,iBACFD,EAAEE,kBAEF,MAAMC,EAASH,EAAEI,cACXC,EAAWF,EAAOG,aAAa,SAAUC,SAAS,6BAClDC,EAAkBH,OAAW7S,EAAYrE,KAAKsX,0BAA0BN,GAE1EhX,KAAKyW,MAAMc,iBACXvX,KAAKyW,MAAMc,gBAAgB,CACvBL,SAAAA,EACAM,YAAaR,EACbS,cAAeJ,EACfK,gBAAiBV,EAAOW,eAtIhC3X,KAAK4X,SAAUC,EAAAA,EAAAA,kBAAiB,QAAS7X,KAAKyW,MAAMqB,iBAAmB,IAzBjE,0BAAuB,IAAAC,EAC7B,IAAI,gBAAEC,GAAoBhY,KAAKyW,MAC/B,MAAM,gCAAEjN,EAA+B,iBAAEyO,GAAqBjY,KAAKyW,MAWnE,OATsB,QAAlBsB,EAAA/X,KAAKyW,MAAM1U,eAAO,IAAAgW,OAAA,EAAlBA,EAAoBnP,IAAIxE,OAAOsH,+BAAgCvD,EAAAA,GAAqCwD,UACpGqM,EAAkBA,EAAgB5M,QAAO8M,IACrC,MAAMC,EAASF,MAAAA,OAAgB,EAAhBA,EAAkBrR,MAC5BwR,KACKA,EAAUC,OAAOzR,MAAMzD,IAA+BmV,EAAAA,EAAAA,IAA8BnV,EAAO+U,OAErG,OAAOC,GAAUA,EAAOlS,WAAauD,MAGtCwO,EAAgB5U,KAAI,CAACiU,EAAsC1M,KAC9D,MAAM4N,EAAavY,KAAKwY,uBAAuBnB,EAAiB1M,EAAMyH,YACtE,MAAO,CACHlP,IAAKqV,EAAarV,IAClBiV,OAAOI,EAAaJ,OACpBhV,MAAOkU,MAUZoB,SACH,MAAM,aAAEC,EAAY,MAAEC,EAAK,WAAEC,EAAU,gBAAEC,EAAe,eAAEC,EAAc,SAACC,EAAQ,QAACC,GAAYhZ,KAAKyW,MAC7FwC,EAAQjZ,KAAKkZ,oBACnBlZ,KAAK4X,QAAQuB,cAAcC,MAAQV,EACnC,MAAMW,GAAqBC,EAAAA,EAAAA,wBAAuBtZ,KAAKyW,MAAMqB,iBAAmB9X,KAAK4X,SACrF,OACIpB,EAAAA,cAAA,OAAK+C,UAAU,sBACVN,EAAM/Q,OAAS,GAAKyQ,GAASnC,EAAAA,cAAA,QAAM+C,UAAU,6BAA6BZ,GAC3EnC,EAAAA,cAAA,MAAI+C,UAAWC,GAAAA,CAAWZ,EAAY,2BAA4B,kBAC7DK,EAAM7V,KAAKqW,IACRzZ,KAAK4X,QAAQuB,cAAcC,MAAQK,EAAKvW,IACxC,MAAM8P,GAAYsG,EAAAA,EAAAA,wBAAuBtZ,KAAKyW,MAAMqB,iBAAmB9X,KAAK4X,SAC5E,IAAIrU,EAAuBkW,EAAKtW,MAAMI,qBAItC,OAHIkW,EAAKtW,QAASuW,EAAAA,EAAAA,IAAUD,EAAKtW,MAAM4M,iBACnCxM,EAAgD,MAAzBA,EAA+BwV,EAAWC,GAGjExC,EAAAA,cAAA,MAAI+C,UAAU,gCAAgCrW,IAAKuW,EAAKvW,KACpDsT,EAAAA,cAAA,IAAAmD,OAAAC,OAAA,CACIL,UAAU,2BACVvD,KAAMhW,KAAKyW,MAAMoD,WAAWJ,EAAKtW,OAAO,GAAM,aAClC,GAAGI,KAAwBsV,IACvCiB,QAAS9Z,KAAK4W,SACdmD,KAAK,SACL3Y,GAAIqY,EAAKvW,KACL8P,IAEHyG,MAAAA,OAAI,EAAJA,EAAMtB,SAAU3B,EAAAA,cAAA,QAAMwD,MAAO,CAAEC,WAAY,SAAWR,EAAKtB,OAAM,KACjE5U,GAAqE,KAA7CkW,EAAKtW,MAAM+W,gCAE7BT,EAAKtW,MAAM+W,oCACqC7V,IAA7CoV,EAAKtW,MAAM+W,+BACgB,IAA/BT,EAAKtW,MAAMG,gBAHXC,EAIAkW,EAAKvW,IAEXsT,EAAAA,cAAA,QACI+C,UAAW,GAAGvZ,KAAK2W,6CACnBoD,KAAK,SAAQ,aACDjB,UAOnCG,EAAM/Q,OAAS,GAAKwQ,GACjBlC,EAAAA,cAAA,IAAAmD,OAAAC,OAAA,CACI5D,KAAMhW,KAAKyW,MAAMoD,WAAW,IAAI,GAChCN,UAAU,iCACNF,EAAkB,CACtBS,QAAS9Z,KAAK4W,WAEb8B,IAObF,uBAAuB2B,EAA0CxP,GACrE,MAAM,aAAEyP,EAAY,uBAAEC,EAAsB,iBAAEpC,EAAgB,UAAEnQ,EAAS,cAAEwS,GAAkBta,KAAKyW,MAC5F8D,EAAgBH,GAAgB,MAChCI,EAAcH,EACpB,IAaII,EAbAC,EAAc,GAClB,GAAIzC,GAAoBA,EAAiBrR,KAAM,CAC3C,MAAMuR,EAASF,EAAiBrR,MAC3BwR,KACKA,EAAUC,OAAOzR,MAAMzD,IAA+BmV,EAAAA,EAAAA,IAA8BnV,EAAOgX,OAGhGhC,EAGDuC,EAAcvC,EAAOwC,SAAW,GAFhC7S,EAAUiH,QAAQ,oEAM1B,IAAI6L,EAAAA,EAAAA,IAAYT,EAAoBpK,eAChC0K,EAAmBD,EACdK,QAAQ,MAAO7a,KAAK8a,aAAaX,EAAoB5W,qBAAsB4W,EAAoBjK,WAC/F2K,QAAQ,MAAO7a,KAAK8a,aAAaX,EAAoB3W,sBAAuB2W,EAAoBjK,gBAClG,GAA4C,IAAxCiK,EAAoB7W,gBAAuB,CAClD,MAAMyX,EAAcT,MAAAA,OAAa,EAAbA,EAAejC,OAAOzR,MACtCvD,GAAWA,EAAQE,uBAAyB4W,EAAoB5W,uBAEpEkX,GAAoBM,EAAcA,EAAYb,8BAAgCC,EAAoB5W,uBAAyB,QAE3HkX,EAAmBN,EAAoBD,+BAAiCC,EAAoB5W,sBAAwB,GAExH,MAAoB,WAAhBmX,GAA4C,UAAhBA,GAA2C,SAAhBA,EAChD,CACHxX,IAAKqX,EAAcM,QAAQ,MAAOH,GAAaG,QAAQ,MAAO,GAAGJ,KACjEtC,OAAOuC,GAIR,CACJxX,IAAKqX,EAAcM,QAAQ,MAAOH,GAAaG,QAAQ,MAAO,GAAGJ,KAAoBC,KAAe/P,KACnGwN,OAAOuC,GAIPI,aAAaE,EAA4BC,GAC7C,IAAKD,IAAWC,EAEZ,OADAjb,KAAKyW,MAAM3O,UAAUoT,MAAM,2CACpBF,GAAU,GAErB,IAAI1J,EAAS0J,EAEb,IACI1J,EAAStR,KAAKyW,MAAM1U,QAASoZ,iBAAiBC,eAAevO,OAAOmO,GAASC,GAC/E,MAAOpT,GACL7H,KAAKyW,MAAM3O,UAAUiH,QAAQ,8BAA8BuC,MAAWzJ,KAG1E,OAAOyJ,EAqBHgG,0BAA0BE,GAC9B,MAAMlG,EAAStR,KAAKkZ,oBAAoBtS,MAAKyU,GAAY7D,EAAYpW,KAAOia,EAASnY,MACrF,OAAQoO,GAAUA,EAAOnO,YAAUkB,KAtK7BiX,EAAAA,EAAAA,IAAA,CAATC,EAAAA,IAAQ,wCALQhF,GAAa+E,EAAAA,EAAAA,IAAA,CADjCE,EAAAA,IACoBjF,oUCpBd,MAAMkF,EAAwCC,IAAa,IAAZ,KAAEC,GAAMD,EAC1D,OACIlF,EAAAA,cAAA,QAAM+C,UAAU,kDACZ/C,EAAAA,cAAA,MAAI+C,UAAU,cACT,IACAoC,EACA,2CCSV,MAAMC,EAA8DF,IAOtE,IAAAG,EAAA,IAPuE,QACxE7V,EAAO,QACPjE,EAAO,cACP+Z,EAAa,UACbC,EAAS,iBACTjE,EAAgB,eAChB5S,GACHwW,EACG,GAAgB,OAAZ1V,EACA,OAAO,KAGX,MAAMgW,EAAchW,EAAQiW,KACtBC,EAAkBlW,GAAWA,EAAQC,SAAWD,EAAQC,SAAW,EACnEkW,GAAaC,EAAAA,EAAAA,uBAAsBpW,EAAQiW,MAAQ,GAAIC,EAAiBna,GAAWA,EAAQsa,mBAAehY,GAC1GiY,GAAgBC,EAAAA,EAAAA,qBAClBvW,EAAQwW,OACRza,EAAQsa,cAActb,eAAelB,YAClB,QAD6Bgc,EAChD9Z,EAAQC,QAAQ4G,WAAG,IAAAiT,GAAQ,QAARA,EAAnBA,EAAqBzX,cAAM,IAAAyX,OAAA,EAA3BA,EAA6BY,kBAE3BC,EACFxX,GAAqC,iBAAnBA,EAAoC6W,EAAUY,+BAAiCZ,EAAUa,yBAGzGhF,GAAUC,EAAAA,EAAAA,kBAAiB,QAASC,EAAmBkE,EAAcE,EAAgB9J,YAErFY,GAAYsG,EAAAA,EAAAA,wBAAuBxB,EAAmBF,GAC5D,OACIpB,EAAAA,cAAA,OAAK+C,UAAU,kCACX/C,EAAAA,cAAA,IAAAmD,OAAAC,OAAA,CACI5D,KAAMmG,EACNrC,SAAS+C,EAAAA,EAAAA,kBAAiB/E,EAAmBF,EAAS5R,EAAQiW,OAC1DjJ,EAAS,cACDhN,EAAQiW,OAEpBzF,EAAAA,cAAA,OAAK+C,UAAU,0CAmB/B,SACIuC,EACAgB,EACAC,EACAC,EACAV,EACAva,GAEA,IAAKgb,IAAaD,IAAiBhB,EAC/B,OAAO,KAEX,MAAMmB,EAAkB,CACpBC,IAAKH,EACLC,QAASA,GAAoB,IAE3BG,EAAa,CACfL,aAAAA,EACAhB,cAAAA,EACAsB,YAAad,GAEjB,OAAO9F,EAAAA,cAAC6G,EAAAA,GAAK1D,OAAAC,OAAA,GAAKqD,EAASE,EAAU,CAAEG,oBAAoB,QAAQvc,eAAgBgB,KAtClEwb,CACGzB,EACA/Z,EAAQC,QAAQ8a,aAChB9W,EAAQ2C,gBACR3C,EAAQiW,KACRK,EACAva,EAAQsa,cAActb,kBAIlCyV,EAAAA,cAAA,OAAK+C,UAAU,2CACX/C,EAAAA,cAAA,KAAG+C,UAAU,4CAA4CmD,IA8B7Cc,EA7BQxX,MAAAA,OAAO,EAAPA,EAASiW,KA8BlCzF,EAAAA,cAAA,MAAI+C,UAAU,kDAAkDiE,MAD3E,IAA4BA,GCzFrB,MAAMC,EAAwB/B,IAAA,IAAC,KAAEC,EAAI,UAAEpC,EAAS,KAAEvD,EAAI,UAAE0H,GAAWhC,EAAA,OACtElF,EAAAA,cAAA,KAAG+C,UAAWA,EAAWvD,KAAMA,EAAI,aAAc0H,GAC5C,IACA/B,EAAM,MCkBFgC,EAA4ClH,IACrD,MAAM,KAAEkF,EAAI,QAAE7B,EAAO,UAAE4D,EAAS,SAAEE,EAAQ,GAAExc,GAAOqV,EACnD,OACID,IAAAA,cAAA,UAAQpV,GAAIA,EAAImY,UAAU,aAAY,aAAamE,EAAW5D,QAASA,EAAS+D,IAAKD,GAChFjC,IAKAmC,EAAqBrH,IACvB,CACHsH,MAAOC,EAAUvH,GACjBwH,YAAaC,EAAgBzH,GAC7B0H,YAAaC,EAAgB3H,GAC7B4H,UAAW7H,IAAAA,cAAC8H,EAAAA,UAAS,CAAC/E,UAAU,4BAIlCyE,EAAavH,GAEXD,IAAAA,cAAC+H,EAAAA,MAAK,CACFC,WAAS,EACTC,gBAAgB,aAChBC,eAAgBjI,EAAMkI,UACtBC,OAAQnI,EAAMmI,OACdC,OAAQpI,EAAMqI,cACdvF,UAAU,0BACVwF,OAAQ,OAKdb,EAAmBzH,GACdD,IAAAA,cAACwI,EAAAA,YAAW,CAACH,OAAQpI,EAAMqI,eAAgBrI,EAAMsF,UAAUkD,YAGhEb,EAAmB3H,GAEjBD,IAAAA,cAAC0I,EAAAA,YAAW,KACR1I,IAAAA,cAAC2I,EAAAA,OAAM,CAACrF,QAASrD,EAAMqI,cAAevF,UAAU,kCAC3C9C,EAAMsF,UAAUqD,8FCG3B,SAAUC,EAAkB7V,EAAqDxD,EAA8BsZ,GACjH,GAAIA,EAAwB,CACxB,MAAMC,EAAoBD,EAAuB1Y,MAAK4Y,GAAYA,EAASC,yBAAyBpa,YAAcW,EAAQC,WAC1H,GAAIsZ,GAAqBA,EAAkBG,gBACvC,OAAOH,EAAkBG,gBAGjC,IAAKlW,IAAoC5D,EAAAA,gBAAgBC,YAAYG,EAAQkD,iBACzE,OAEJ,MAAMyW,EAAqB3Z,EAAQkD,gBAAgBtC,MAAKoM,GAAaA,EAAU/M,WAAauD,IAC5F,OAAImW,EACOA,EAAmBrW,eAD9B,EAMJ1I,eAAegf,EAAoB7d,EAAuBoD,EAAmB0a,EAAoBC,GAC7F,IACI,MAAMpO,QAAiBqO,EAAmBhe,GAC1C,GAAI2P,GAAYA,EAASsO,cAAe,CACpC,MAAMC,QAA4BC,EAAAA,EAAAA,IAAc,CAAEje,cAAeF,EAAQsa,eACrEwD,EACA,EACIM,EAAAA,EAAAA,mBAAkBhb,EAAWuM,EAASsO,cAAeH,KAE7D9d,EAAQsa,cAAc+D,QAAOC,EAAAA,EAAAA,IAAyB,GAAI,MAAO,CAACJ,KAExE,MAAOpY,GAAO,IAAAyY,EAAAC,GACZC,EAAAA,EAAAA,GAAM,CACFC,OAAQX,EAERnE,KAAM9T,EAEN6Y,OAAQ7Y,MAAAA,GAAW,QAANyY,EAALzY,EAAO8Y,YAAI,IAAAL,GAAXA,EAAaM,cAAgB,mBAAmB/Y,MAAAA,GAAW,QAAN0Y,EAAL1Y,EAAO8Y,YAAI,IAAAJ,OAAA,EAAXA,EAAaK,qBAAkBvc,EACvFwc,KAAM,QACNC,UAAW,EACXC,SAAU,eACVC,UAAU,EACVC,cAAc,EACdC,QAASA,UAKrBtgB,eAAemf,EAAmBhe,GAC9B,MAAMof,EAAgB,IAAIC,EAAAA,iBAAiBrf,EAAQsa,cAActb,eAAelB,aAChF,OAAOwhB,EAAAA,EAAAA,aAAYF,EAAepf,EAAQsa,eAmH9C,SAASiF,EAAkBvf,EAAuBga,EAAiD/V,EAA8Bub,EAAuCC,GAA2B,IAAAC,EAC/L,MAAMC,KAAeH,GAAaA,EAAUrZ,OAAS,GAAmC,QAAlCuZ,EAAIF,EAAU,GAAGI,yBAAiB,IAAAF,GAA9BA,EAAgC7a,MAAKsG,GAAKA,EAAE7H,YAAcW,EAAQC,YAC5H,IAAIsT,EAAY,sBAMhB,OAJImI,IACAnI,GAAa,kBAIb/C,EAAAA,cAAA,WACIA,EAAAA,cAAA,UACI+C,UAAWA,EACXiE,MAAQkE,EAAmD3F,EAAU6F,6BAA9C7F,EAAU8F,wBAAgE,aACpFH,EAAmD3F,EAAU6F,6BAA9C7F,EAAU8F,wBACtC/H,QAASlZ,UACA8gB,EA1CzB,SAAgC3f,EAAuBwf,EAAuCvb,EAA8B8Z,GACxH,MAAMgC,EAtFV,SAAwCP,EAAuCpc,GAC3E,IAAKoc,IACApc,GACoB,IAArBoc,EAAUrZ,SACTqZ,EAAU,GAAGI,mBAC4B,IAA1CJ,EAAU,GAAGI,kBAAkBzZ,OAC/B,OAAO,KAGX,MAAM6Z,EAAoBR,EAAU,GAAGI,kBAAkBvW,QAAO4W,GACrDA,EAAiB3c,YAAcF,IAG1C,OAAI4c,GAAqBA,EAAkB,GAAGE,OACnCF,EAAkB,GAAGE,OAEzB,KAsEgBC,CAA+BX,EAAWvb,EAAQC,UACrEsb,GAAaA,EAAU,IAAMO,IAC7BK,EAAAA,EAAAA,IAAiB,CAAElgB,cAAeF,EAAQsa,eAAiBkF,EAAU,GAAGa,GAAI,CAAC,CAAEH,OAAQH,KAClFpT,MAAK2T,IACF,MAAMC,EAAe,IACdf,GAEPe,EAAa,GAAKD,EAClBtgB,EAAQsa,cAAc+D,QAAOC,EAAAA,EAAAA,IAAyB,GAAI,MAAOiC,MAEpEC,OAAM1a,IAAQ,IAAA2a,EAAAC,GACXjC,EAAAA,EAAAA,GAAM,CACFC,OAAQX,EACRnE,KAAM9T,EACN6Y,OAAQ7Y,MAAAA,GAAW,QAAN2a,EAAL3a,EAAO8Y,YAAI,IAAA6B,GAAXA,EAAa5B,cAAgB,mBAAmB/Y,MAAAA,GAAW,QAAN4a,EAAL5a,EAAO8Y,YAAI,IAAA8B,OAAA,EAAXA,EAAa7B,qBAAkBvc,EACvFwc,KAAM,QACNC,UAAW,EACXC,SAAU,eACVC,UAAU,EACVC,cAAc,EACdC,QAASA,YAwBLwB,CAAuB3gB,EAASwf,EAAWvb,EAAS+V,EAAU+D,wBA/GtFlf,eAAkCmB,EAAuBga,EAAiD/V,EAA8Bwb,GACpI,IAAKzf,IAAYiE,IAAYjE,EAAQC,QAAQlC,KAAK4C,UAC9C,OAAOoD,QAAQC,UAGnB,MAAM4c,EAAgC,GAChCC,EAAe,IAAIC,EAAAA,aACrB7c,EAAQC,SACRlE,EAAQC,QAAQnC,iBAChBwE,OAAWA,EACXtC,EAAQC,SACPD,EAAQC,QAAQlC,KAAK4C,WAE1BigB,EAAclX,KAAKmX,GAEnB,MAAME,QAAsBC,EAAAA,EAAAA,mBAAkBJ,EAAe5gB,EAAQsa,eAErE,GAAIta,EAAQC,QAAQlC,KAAKkB,iBAAmB8hB,GAAiBA,EAAc5a,QAAU,EAAG,CACpF,MAAMwJ,QAAiBqO,EAAmBhe,GACpCwf,QAAkByB,EAAAA,EAAAA,0BAAwB3C,EAAAA,EAAAA,IAAyB,GAAI,MAAOte,EAAQsa,eAC5F,GAAKkF,GAAkC,IAArBA,EAAUrZ,aAgClB0X,EAAoB7d,EAAS+gB,EAAc,GAAG7c,SAAUsb,EAAU,GAAGa,GAAIrG,EAAU+D,mBAEzFU,EAAAA,EAAAA,GAAM,CACF7E,KAAMI,EAAUkH,2BAA2BpI,QAAQ,gBAAiBiI,EAAc,GAAG7G,MAAQ,IAC7F6E,UAAW,IACXC,SAAU,eACVC,UAAU,EACVC,cAAc,EACdC,QAASA,aAxCyB,CACtC,MAAMgC,EAAe1B,EACrB,GAAI9P,GAAYA,EAASsO,cAAe,CACpC,MAAMmD,EAAyB,CAC3BC,WAAY1R,EAASsO,cACrB/D,KAAMiH,EACNG,sBAAuB,EACvBjB,GAAI,GAER,IACI,MAAMC,QAAqBiB,EAAAA,EAAAA,IAAwB,CAC3CrhB,cAAeF,EAAQsa,eAE3B8G,SACEvD,EAAoB7d,EAAS+gB,EAAc,GAAG7c,SAAUoc,EAAaD,GAAIrG,EAAU+D,kBAC3F,MAAOjY,GAAO,IAAA0b,EAAAC,GACZhD,EAAAA,EAAAA,GAAM,CACFC,OAAQ1E,EAAU+D,iBAElBnE,KAAM9T,EAEN6Y,OAAQ7Y,MAAAA,GAAW,QAAN0b,EAAL1b,EAAO8Y,YAAI,IAAA4C,GAAXA,EAAa3C,cAAgB,mBAAmB/Y,MAAAA,GAAW,QAAN2b,EAAL3b,EAAO8Y,YAAI,IAAA6C,OAAA,EAAXA,EAAa5C,qBAAkBvc,EACvFwc,KAAM,QACNC,UAAW,EACXC,SAAU,eACVC,UAAU,EACVC,cAAc,EACdC,QAASA,aA8DHuC,CAAmB1hB,EAASga,EAAW/V,EAASwb,KAM5DE,EAAmD3F,EAAU6F,6BAA9C7F,EAAU8F,0BAMpC,MAAM6B,EAAgEhI,IA0BxE,IA1ByE,KAC1EiI,EAAI,SACJje,EAAQ,eACRke,EAAc,oBACdC,EAAmB,eACnBC,EAAc,gBACdC,EAAe,UACfxC,EAAS,QACTxf,EAAO,OACPqC,EAAM,cACN0X,EAAa,UACbC,EAAS,WACTiI,EAAU,SACVC,EAAQ,oBACRC,EAAmB,iBACnBpM,EAAgB,cAChBqM,EAAa,wBACbC,EAAuB,gCACvB5a,EAA+B,qBAC/B6a,EAAoB,gCACpBC,EAA+B,uBAC/BhF,EAAsB,uBACtBiF,EAAsB,kBACtBC,EAAiB,WACjBC,EAAU,4BACVC,GACHhJ,EACG,MAAOiJ,EAAqBC,GAA0BpO,EAAAA,cAA4CnS,GAC5FwgB,EAAYrO,EAAAA,SAAc,IAAM,IAAIsO,EAAAA,EAAO,CAAEC,YAAa,KAAM,IAEhEC,EAA4BpkB,MAAAA,IAC9B,IAAIqkB,EAEJ,GAAIC,EACAD,EAAoB,IAAKN,IAA4Cb,GAAkC,KAGnGmB,EAAkBE,OAAMjY,GAAKA,EAAEkY,YAAYhD,KAAO8C,EAAiB9C,MACnE6C,EAAkBI,OAAO,EAAG,EAAG,IAAIC,EAAAA,cAAcJ,EAAkB,GAAI,QAExE,CAEH,MAAMxjB,EAAsBqC,EAAAA,yBAAyBC,cAAc,CAC/DjD,eAAgBgB,EAAQC,QACxBoC,OAAQA,IACTH,oBACGpD,EAAQ,IAAI0kB,EAAAA,uBAAuB,GAAI7jB,GAC7CujB,SAA2BO,EAAAA,EAAAA,mBAAkB3kB,EAAOkB,EAAQsa,gBAAgBjZ,KAAI8J,GAAK,IAAIoY,EAAAA,cAAcpY,EAAG,GAAI,KAIlH,OADA0X,EAAuBK,GAChBA,GAGLQ,EAAyB7kB,SACpBkjB,IAAkCa,GAA4CK,KAGnFU,EAA2C,CAC7CC,oBAAqB5J,EAAU4J,qBAEnC,OACInP,EAAAA,cAAA,MAAI+C,UAAU,iBACT7T,EAAStC,KAAI,CAAC4C,EAAiC2E,KAAa,IAAAib,EAAA,OACzDpP,EAAAA,cAAA,MAAI+C,UAAU,iCAAiCrW,IAAKyH,GAChD6L,EAAAA,cAACqP,EAAAA,iBAAgB,CACb9jB,QAASA,EACT+V,iBAAkBA,EAClBgE,cAAeA,EACfgK,cAAe/J,EAAUgK,UACzBC,kBAAmBjK,EAAUiK,kBAC7BC,iBAAkBlK,EAAUkK,iBAC5BC,gBAAiBnK,EAAUmK,gBAC3BC,UAAWjC,EACX9iB,GAAI6iB,EACJ/gB,IAAK8C,EAAQC,SACbmgB,SAAUpC,EACVrD,KAAM,CACFgD,KAAAA,EACA3d,QAAAA,EACA8c,cAAec,EAAehd,MAAKsG,GAAKA,EAAEjH,WAAaD,EAAQC,WAC/D4d,oBAAAA,EACAE,gBAAiBA,MAAAA,OAAe,EAAfA,EAAiB3Y,QAAO8B,GAAKA,EAAEmZ,kBAAoBrgB,EAAQC,YAEhF4e,UAAWA,EACXyB,cAAY,EACZb,uBAAwBA,EACxBc,uBAAwBvB,EACxBwB,gBAAiBrC,EACjBC,wBAAyBA,EACzBqC,eAAgBnF,EAAkBvf,EAASga,EAAW/V,EAASub,EAAWxF,EAAUyF,qBACpFkF,eAAgBrH,EAAkB7V,EAAiCxD,EAAQsZ,GAC3EqH,gBAAiBjC,MAAAA,OAA2B,EAA3BA,EAA6B9d,MAAKsG,GAAKA,EAAEuS,yBAAyBpa,YAAcW,EAAQC,WACzGoe,qBAAsBA,EACtBuC,iBAAkBpC,EAClBqC,UAAWpC,EACXqC,cAAevC,MAAAA,GAAkE,QAA5CqB,EAAtBrB,EAAwB3d,MAAKsG,GAAKA,EAAEjH,WAAaD,EAAQC,kBAAS,IAAA2f,OAAA,EAAlEA,EAAoEmB,UACnFrB,eAAgBA,EAChBsB,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,wBAAyBzD,MAAAA,OAA+B,EAA/BA,EAAiC1d,MACtDohB,GACIpiB,EAAAA,gBAAgBC,YAAYmiB,IAC5BA,EAAsB,GAAGC,kBAAoBjiB,EAAQkiB,kBAE7DC,4BAA6B,CACzBC,yBAA0BrM,EAAUqM,yBACpCC,wBAAyBtM,EAAUsM,wBACnCC,4BAA6BvM,EAAUuM,4BACvCC,gCAAiCxM,EAAUwM,gCAC3CC,iCAAkCzM,EAAUyM,iCAC5CC,sCAAuC1M,EAAU0M,sCACjDC,oBAAqB3M,EAAU2M,oBAC/BC,wBAAyB5M,EAAU4M,wBACnCC,cAAe7M,EAAU6M,cACzBC,0BAA2B9M,EAAU8M,0BACrCC,mBAAoB/M,EAAU+M,mBAC9BC,2BAA4BhN,EAAUgN,2BACtCC,+BAAgCjN,EAAUiN,+BAC1CC,yBAA0BlN,EAAUkN,yBACpCC,8BAA+BnN,EAAUmN,8BACzCC,yCAA0CpN,EAAUoN,yCACpDC,4BAA6BrN,EAAUqN,4BACvCC,2BAA4BtN,EAAUsN,2BACtCC,0CAA2CvN,EAAUuN,0CACrDC,6CAA8CxN,EAAUwN,6CACxDC,0CAA2CzN,EAAUyN,0CACrDzD,UAAWhK,EAAUgK,UACrBC,kBAAmBjK,EAAUiK,kBAC7BC,iBAAkBlK,EAAUkK,iBAC5BwD,yBAA0B1N,EAAU0N,yBACpCC,8BAA+B3N,EAAU2N,8BACzCC,yBAA0B5N,EAAU4N,yBACpCC,+BAAgC7N,EAAU6N,+BAC1CC,6BAA8B9N,EAAU8N,6BACxCC,gCAAiC/N,EAAU+N,iCAE/CC,cAAgB/jB,IAAYgkB,EAAAA,EAAAA,GACxBjoB,EACA8hB,EACA7d,EACA+V,EAAU+L,wEC1Z/B,MAAMmC,EAAkCvO,IAAA,IAAC,UAAEwO,GAAWxO,EAAA,OACzDlF,EAAAA,cAAA,YACK,IACA0T,EACA,MCHIC,EAA0BzO,IAAA,IAAC,KAAEC,EAAI,UAAEpC,GAAWmC,EAAA,OACvDlF,EAAAA,cAAA,QAAM+C,UAAWA,GACZ,IACAoC,EACA,mJCgCT,IAAqByO,EAArB,cAA6C5T,EAAAA,UAWzC5W,YAAmB6W,GAA4B,IAAA4T,EAAA3O,EAAA4O,EAAAC,EAAAC,EAAAC,EAAAC,EAC3ChU,MAAMD,GAXO,KAAAkU,6BAAoD,IAAIC,IA0IxD,KAAAC,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,EACAC,EACAC,EACAC,EACAC,EACAT,KACqB,IAAAU,EAAAC,EAErB,MAAO,CACH,CACIvqB,GAAI,GAAG0pB,IAAWO,uBAClBloB,MAAQmoB,GAAeze,OAAOye,IAJN,EAKxB5N,UAAW,GAA0C,QAA1CgO,EAAG1rB,KAAKyW,MAAMmV,oCAA4B,IAAAF,EAAAA,EAAI,MAAM1rB,KAAK6rB,eACpEC,cAAe,GAAGP,KAEtB,CACInqB,GAAI,GAAG0pB,IAAWO,qBAClBloB,MAAO0J,OAAO2e,IAAgB3e,OAAOme,GACrCtN,UAAW,GAA0C,QAA1CiO,EAAG3rB,KAAKyW,MAAMsV,oCAA4B,IAAAJ,EAAAA,EAAI,MAAM3rB,KAAK6rB,eACpEC,cAAe,GAAGL,OA7K1BzrB,KAAKgsB,eAAiBhsB,KAAKgsB,eAAeC,KAAKjsB,MAC/CA,KAAKksB,kBAAoBlsB,KAAKksB,kBAAkBD,KAAKjsB,MACrDA,KAAKmsB,wBAA0BnsB,KAAKmsB,wBAAwBF,KAAKjsB,MACjEA,KAAKosB,WAAapsB,KAAKosB,WAAWH,KAAKjsB,MACvCA,KAAKqsB,WAAarsB,KAAKqsB,WAAWJ,KAAKjsB,MACvCA,KAAKssB,iBAAmBtsB,KAAKssB,iBAAiBL,KAAKjsB,MACnDA,KAAKusB,iBAAmBvsB,KAAKusB,iBAAiBN,KAAKjsB,MAEnDA,KAAKwsB,SAAWhW,EAAAA,YAChBxW,KAAKysB,SAAWjW,EAAAA,YAEhB,MAAM,4BAAEkW,GAAgC1sB,KAAKyW,MACvCkW,EAA8D,QAApDtC,EAAGqC,MAAAA,OAA2B,EAA3BA,EAA6BnpB,4BAAoB,IAAA8mB,EAAAA,EAAI,IAClEuC,EAAaF,MAAAA,OAA2B,EAA3BA,EAA6BlpB,sBAC1CsnB,EAAW,UAAU+B,OAAO7sB,KAAKyW,MAAMqW,8BAA8B7mB,aAAa4mB,OACpF7sB,KAAKyW,MAAM0D,oBAAoB7W,mBAE7BypB,EAAW/sB,KAAKyW,MAAM0D,oBAAoB5W,qBAC1CypB,EAAWhtB,KAAKyW,MAAM0D,oBAAoB3W,sBAC1CunB,EAAW/qB,KAAK8a,aAAaiS,GAC7B/B,EAAWhrB,KAAK8a,aAAakS,GAC7BC,EAAyBjtB,KAAK6qB,UAAUC,EAAUC,EAAUC,GAC5DM,EACiH,QADtG5P,EAC+C,QAD/C4O,EACyB,QADzBC,EACbvqB,KAAKyW,MAAMiW,mCAA2B,IAAAnC,OAAA,EAAtCA,EAAwChnB,4BAAoB,IAAA+mB,EAAAA,EAAItqB,KAAKyW,MAAM0D,oBAAoB5W,4BAAoB,IAAAmY,EAAAA,EAAI,IACrH8P,EAEkD,QAFvChB,EACgD,QADhDC,EACyB,QADzBC,EACb1qB,KAAKyW,MAAMiW,mCAA2B,IAAAhC,OAAA,EAAtCA,EAAwClnB,6BAAqB,IAAAinB,EAAAA,EAC7DzqB,KAAKyW,MAAM0D,oBAAoB3W,6BAAqB,IAAAgnB,EAAAA,EACpDwC,EACEzB,EAAmBvrB,KAAK8a,aAAawQ,GACrCG,EAAmBzrB,KAAK8a,aAAa0Q,GACrC0B,EAAkBltB,KAAKyW,MAAM4U,UAAY,IAAIwB,OAAO7sB,KAAKyW,MAAM4U,aAAe,GAC9E8B,EAAoCntB,KAAKorB,gBAC3CN,EACAoC,EACA5B,EACAC,EACAC,EACAC,EACAT,GAEJhrB,KAAKotB,MAAQ,CACTC,WAAW,EACXC,wBAAoBjpB,EACpBkpB,wBAAoBlpB,EACpBinB,YAAaqB,EACbnB,YAAaoB,EACbY,YAAY,EACZC,YAAY,EACZ3C,SAAAA,EACAiC,SAAAA,EACAC,SAAAA,EACAC,OAAAA,EACAE,aAAAA,GA1DE,mBACN,OAAOntB,KAAKyW,MAAM0D,oBAAoBjK,UAAY,GA6D/Cwd,sBAAsBC,EAAkCC,GAC3D,OAAI5tB,KAAKotB,QAAUQ,GAAa5tB,KAAKyW,QAAUkX,EAM5CE,mBAAmBC,GAClBA,IAAkB9tB,KAAKyW,OACvBzW,KAAK+tB,oBAINtV,SACH,MAAM,oBAAE0B,EAAmB,8BAAE2S,EAA6B,sBAAEkB,GAA0BhuB,KAAKyW,MAE3F,GAAK0D,GAAwB2S,EAO7B,MAA6B,UAAzB9sB,KAAKyW,MAAMwX,UACJjuB,KAAKkuB,qBAGTluB,KAAKmuB,gBAVRH,EAAsBlmB,UAAUD,MAC5B,kGAeJkmB,oBAAiB,IAAAK,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EACrB,MAAM3D,EAAW,UAAU+B,OAAO7sB,KAAKyW,MAAMqW,8BAA8B7mB,aAAa4mB,OACpF7sB,KAAKyW,MAAM0D,oBAAoB7W,mBAE7BypB,EAAW/sB,KAAKyW,MAAM0D,oBAAoB5W,qBAC1CypB,EAAWhtB,KAAKyW,MAAM0D,oBAAoB3W,sBAC1CunB,EAAW/qB,KAAK8a,aAAaiS,GAC7B/B,EAAWhrB,KAAK8a,aAAakS,GAC7BC,EAAyBjtB,KAAK6qB,UAAUC,EAAUC,EAAUC,GAC5DM,EACiH,QADtG8C,EAC+C,QAD/CC,EACyB,QADzBC,EACbtuB,KAAKyW,MAAMiW,mCAA2B,IAAA4B,OAAA,EAAtCA,EAAwC/qB,4BAAoB,IAAA8qB,EAAAA,EAAIruB,KAAKyW,MAAM0D,oBAAoB5W,4BAAoB,IAAA6qB,EAAAA,EAAI,IACrH5C,EAEkD,QAFvC+C,EACgD,QADhDC,EACyB,QADzBC,EACbzuB,KAAKyW,MAAMiW,mCAA2B,IAAA+B,OAAA,EAAtCA,EAAwCjrB,6BAAqB,IAAAgrB,EAAAA,EAC7DxuB,KAAKyW,MAAM0D,oBAAoB3W,6BAAqB,IAAA+qB,EAAAA,EACpDvB,EACEzB,EAAmBvrB,KAAK8a,aAAawQ,GACrCG,EAAmBzrB,KAAK8a,aAAa0Q,GACrC0B,EAAkBltB,KAAKyW,MAAM4U,UAAY,IAAIwB,OAAO7sB,KAAKyW,MAAM4U,aAAe,GAC9E8B,EAAoCntB,KAAKorB,gBAC3CN,EACAoC,EACA5B,EACAC,EACAC,EACAC,EACAT,GAEJhrB,KAAK0uB,SAAS,CAAE5D,SAAAA,EAAUiC,SAAAA,EAAUC,SAAAA,EAAUC,OAAAA,EAAQE,aAAAA,IA8DlDe,qBACJ,MAAM,WAAES,EAAU,8BAAE7B,EAA6B,sBAAEkB,GAA0BhuB,KAAKyW,OAC5E,YAAE6U,EAAW,YAAEE,EAAW,WAAEgC,EAAU,WAAEC,EAAU,mBAAEH,EAAkB,mBAAEC,GAAuBvtB,KAAKotB,MAGpGwB,EAAY,CACd,cAFoBZ,EAAsBa,iBAAmB,OAAOhU,QAAQ,MAAOiS,EAA8BnS,SAAW,IAG5H,gBAAiBgU,GAOfG,EAAoB,mEACtBxB,EAAqB,qCAAuC,IAE1DyB,EAAoB,mEACtBxB,EAAqB,qCAAuC,IAI1DyB,EAAuBhvB,KAAKivB,2BAA2B3D,EAAakC,EAAYF,GAChF4B,EAAuBlvB,KAAKivB,2BAA2BzD,EAAaiC,EAAYF,GACtF,OACI/W,EAAAA,cAAA,OAAAmD,OAAAC,OAAA,CAAML,UAAU,0CAA6CqV,GACzDpY,EAAAA,cAAA,SAAO+C,UANW,8EAObyU,EAAsBmB,SACvB3Y,EAAAA,cAAA,SACI+C,UAAWuV,EACXM,SAAUpvB,KAAKosB,WACfiD,QAASrvB,KAAKosB,WACdkD,OAAQtvB,KAAKssB,iBACbnpB,MAAO6rB,EACPnR,IAAK7d,KAAKwsB,YAGlBhW,EAAAA,cAAA,SAAO+C,UAhBW,8EAiBbyU,EAAsBuB,SACvB/Y,EAAAA,cAAA,SACI+C,UAAWwV,EACXS,YAAaN,OAAuB7qB,EAAY2pB,EAAsByB,mBACtEL,SAAUpvB,KAAKqsB,WACfgD,QAASrvB,KAAKqsB,WACdiD,OAAQtvB,KAAKusB,iBACbppB,MAAO+rB,EACPrR,IAAK7d,KAAKysB,YAGjBa,GACG9W,EAAAA,cAAA,QAAM+C,UAAU,wFACX+T,GAGRC,GAAsBD,IAAuBC,GAC1C/W,EAAAA,cAAA,QAAM+C,UAAU,wFACXgU,IAObY,gBACJ,MAAM,WAAEQ,EAAU,UAAEtD,GAAcrrB,KAAKyW,MACjCiZ,EAAiB,CACnB,gBAAiBf,GAGrB,OACInY,EAAAA,cAACmZ,EAAAA,OAAMhW,OAAAC,OAAA,CACHL,UAAU,mCACVrW,IAAKlD,KAAKotB,MAAMtC,SAChBO,UAAWA,EACXjqB,GAAIpB,KAAKotB,MAAMtC,SACf8E,QAAQ,EACRC,IAAM7vB,KAAKotB,MAAML,UAAYlgB,OAAO7M,KAAKotB,MAAML,gBAAc1oB,EAC7DmD,IAAMxH,KAAKotB,MAAMJ,UAAYngB,OAAO7M,KAAKotB,MAAMJ,gBAAc3oB,EAC7DyrB,KAAM,EACNC,YAAY,aACZ9C,OAAQjtB,KAAKotB,MAAMH,OACnB+C,YAAU,EACVC,aAAW,EACX9C,aAAcntB,KAAKotB,MAAMD,aACzB+C,YAAalwB,KAAKksB,kBAClBkD,SAAUe,GAAAA,CAASnwB,KAAKgsB,eAAgB,KACxCoE,kBAAmBpwB,KAAKmsB,yBACpBuD,IAKRtD,WAAWiE,GACfrwB,KAAKswB,aAAaD,EAAO,OAGrBhE,WAAWgE,GACfrwB,KAAKswB,aAAaD,EAAO,OAGrBC,aAAaD,EAA2CE,GAC5D,MAAMC,EAAc,WAAWD,IACzBE,EAAa,UAAUF,IAC7BvwB,KAAK0uB,SAAS,CACV,CAAC8B,GAAcxwB,KAAK0wB,2BAA2BL,EAAMpZ,cAAc9T,OACnE,CAACstB,IAAa,IAIdnE,iBAAiB+D,GACrB,MAAMM,EAAmB3wB,KAAK0wB,2BAA2BL,EAAMpZ,cAAc9T,OAC7EnD,KAAK0uB,SAAS,CACVpD,YAAaqF,EACbC,YAAY,IAEhB,MAAMpE,EAAW3f,OAAO8jB,IAClB,SACFE,EAAQ,8BACR/D,EAA6B,oBAC7B3S,EAAmB,sBACnB6T,EAAqB,4BACrBtB,GACA1sB,KAAKyW,MACHjP,EAAOklB,GAA+BA,EAA4BlpB,4BAA0Ba,EAE5FysB,EAAStpB,EAAMqF,OAAOrF,QAAOnD,EAEnC,OAAIyI,MAAM0f,IACNxsB,KAAK0uB,SAAS,CAAEpB,mBAAoBU,EAAsB+C,qBAC1D/wB,KAAKgxB,OAAO,QACL,GAGPhxB,KAAKixB,eAAezE,EAAUsE,IAC9BD,EAAS,CACL/D,8BAAAA,EACA3S,oBAAAA,EACA+W,aAAa,EACbC,WAAY3E,EACZ4E,SAAUN,KAEP,IAEX9wB,KAAKgxB,OAAO,QAEL,GAGHzE,iBAAiB8D,GACrB,MAAMgB,EAAmBrxB,KAAK0wB,2BAA2BL,EAAMpZ,cAAc9T,OAC7EnD,KAAK0uB,SAAS,CACVlD,YAAa6F,EACbC,YAAY,IAEhB,MAAM7E,EAAW5f,OAAOwkB,IAClB,SACFR,EAAQ,8BACR/D,EAA6B,oBAC7B3S,EAAmB,sBACnB6T,EAAqB,4BACrBtB,GACA1sB,KAAKyW,MACHoZ,EAAOnD,GAA+BA,EAA4BnpB,sBAAyB,IAE3FguB,EAAS1kB,OAAOgjB,GAEtB,OAAI/iB,MAAM2f,IACNzsB,KAAK0uB,SAAS,CAAEnB,mBAAoBS,EAAsB+C,qBAC1D/wB,KAAKgxB,OAAO,QACL,KAGPhxB,KAAKixB,eAAeM,EAAQ9E,KACxBtS,EACA0W,EAAS,CACL/D,8BAAAA,EACA3S,oBAAAA,EACA+W,aAAa,EACbC,WAAYI,EACZH,SAAU3E,IAGdzsB,KAAKgxB,OAAO,QAET,GAMPA,OAAOT,GACX,MAAM1S,EAAoB,QAAd0S,EAAsBvwB,KAAKysB,SAAWzsB,KAAKwsB,SAEvDgF,YAAW,KACH3T,GAAOA,EAAI4T,SACX5T,EAAI4T,QAAQC,UAEjB,IAGCzC,2BACJ5T,EACAsW,EACAC,GAEA,OAAID,GAAWC,QAAgCvtB,IAAbgX,EACvBA,EAEJrb,KAAK8a,aAAaO,GAGrB4V,eAAepB,EAAaroB,GAChC,MAAM,sBAAEwmB,GAA0BhuB,KAAKyW,MACvC,YAAYpS,IAARmD,MAIAqoB,EAAMroB,KACNxH,KAAK0uB,SAAS,CACVpB,mBAAoBU,EAAsB6D,qBAC1CtE,mBAAoBS,EAAsB6D,wBAEvC,IAMP/W,aAAaE,GACjB,GAAuD,IAAnDhb,KAAKyW,MAAM0D,oBAAoB7W,gBAAuB,CAEtD,OADetD,KAAKyW,MAAM1U,QAAQoZ,iBAAiBC,eAAevO,OAAOmO,GAAShb,KAAK6rB,cAG3F,OAAO7Q,GAAU,GAGb0V,2BAA2B7vB,GAE/B,MAAMixB,EAAajlB,OAAOhM,GAC1B,IAAKiM,MAAMglB,GACP,OAAOjxB,EAKX,OAD4Bb,KAAK2qB,6BAA6B1Z,IAAIpQ,IACpCA,EAK1BmrB,eAAe+F,GAEnB,GAA2C,cAAvCA,EAAyBC,UAA2B,CACpD,MAAM,SAAEnB,EAAQ,8BAAE/D,EAA6B,oBAAE3S,GAAwBna,KAAKyW,MAC1E0D,GAAuB4X,IACvBlB,EAAS,CACL/D,8BAAAA,EACA3S,oBAAAA,EACA+W,aAAa,EACbC,WAAYY,EAAyBE,gBACrCb,SAAUW,EAAyBG,mBAGvClyB,KAAKmyB,oBAAoBJ,KAM7B7F,kBAAkB6F,GACtB,MAAM,SAAElB,EAAQ,8BAAE/D,EAA6B,oBAAE3S,GAAwBna,KAAKyW,MAC1E0D,GAAuB4X,IACvBlB,EAAS,CACL/D,8BAAAA,EACA3S,oBAAAA,EACA+W,aAAa,EACbC,WAAYY,EAAyBE,gBACrCb,SAAUW,EAAyBG,mBAGvClyB,KAAKmyB,oBAAoBJ,IAKzBI,oBAAoBJ,GACxB,GAAIA,EAAyB3wB,GAAI,CAC7B,MAAM+H,EAAUipB,SAASC,eAAe,GAAGN,EAAyB3wB,WAChE+H,GACAqoB,YAAW,KACProB,EAAQuoB,UACT,IAKPvF,wBAAwBmG,GAC5B,OAAOtyB,KAAK8a,aAAa,GAAGwX,QAjetBhX,EAAAA,EAAAA,IAAA,CAATC,EAAAA,IAAQ,iCAPQ6O,GAAe9O,EAAAA,EAAAA,IAAA,CADnCE,EAAAA,IACoB4O,kcCQP,MAAOmI,UAAmB/b,EAAAA,UAKpC5W,YAAmB6W,GACfC,MAAMD,GAyKO,KAAAG,SAAYC,IACzBA,EAAEC,iBAEF,MAAM,8BAAEgW,EAA6B,oBAAE3S,EAAmB,4BAAEuS,GAAgC1sB,KAAKyW,MAC7F0D,IACAna,KAAKyW,MAAMoa,SAAS,CAChB/D,8BAAAA,EACA3S,oBAAAA,EACA+W,aAAcxE,IAGlB8E,YAAW,KACPxxB,KAAKwyB,WAAWf,SAAWzxB,KAAKwyB,WAAWf,QAAQC,UACpD,KArLP1xB,KAAK4W,SAAW5W,KAAK4W,SAASqV,KAAKjsB,MACnCA,KAAKotB,MAAQ,CACTC,YAAartB,KAAKyW,MAAMiW,6BAE5B1sB,KAAKwyB,WAAahc,EAAAA,YAClBxW,KAAK4X,SAAUC,EAAAA,EAAAA,kBAAiB,QAAS7X,KAAKyW,MAAMqB,iBAAmB,IAGpE4V,sBAAsBC,EAA6BC,GACtD,OAAI5tB,KAAKotB,QAAUQ,GAAa5tB,KAAKyW,QAAUkX,EAM5ClV,SAAM,IAAAga,EAAAC,EAAAC,EACT,MAAAC,EAgBI5yB,KAAKyW,OAhBH,WACFkY,EAAU,sBACVX,EAAqB,8BACrBlB,EAA6B,oBAC7B3S,EAAmB,4BACnBuS,EAA2B,sBAC3BmG,EAAqB,4BACrBC,EAA2B,MAC3BnoB,EAAK,SACLooB,EAAQ,SACRlC,EAAQ,QACR9uB,EAAO,iBACP+V,EAAgB,oBAChBkb,EAAmB,qBACnBC,GAEHL,EADMM,GAAKC,EAAAA,EAAAA,GAAAP,EAAAQ,GAEZ,IAAKjZ,EAED,YADA6T,EAAsBlmB,UAAUD,MAAM,sEAGrCsS,EAAoB5W,sBACrByqB,EAAsBlmB,UAAUiH,QAC5B,2DAA2DlK,KAAKO,UAAU+U,MAGlF,MAAMkZ,EAAiBvG,EAA8BwG,mBAAqBC,EAAAA,YAAYC,aACtF,IAAIC,EAAoBJ,EAAiB,gBAAkB,eAC3DI,EAAoB,0BAA0BA,IAC9C,MAAMlD,EAAY8C,EAAiB,QAAU,WACvChG,IAAcX,EAEpB,GADA+G,EAAoBpG,EAAY,GAAGoG,YAA8BA,EAC7D3G,EAA8B4G,cAAgBpjB,EAAAA,qBAAqBqjB,OACnE,OAAO3zB,KAAK4zB,cACRzZ,EACA2S,EACAO,EACAtrB,EACA4I,EACAmN,EACA+a,EACAC,GAGR9yB,KAAK4X,QAAQuB,cAAcC,MAAyD,QAApDqZ,EAAGtY,EAAoBD,qCAA6B,IAAAuY,EAAAA,EAAItY,EAAoB5W,qBAC5G,MAAMyP,GAAYsG,EAAAA,EAAAA,wBAAuBxB,EAAmB9X,KAAK4X,SAE3Dic,EAAc1Z,EAAoBD,+BAAiCC,EAAoB5W,sBAAwB,GAE/GuwB,EAAe3Z,EAAoB/J,OAAS,EAClD,IAAI2jB,EAEAA,EADiB,IAAjBD,EAC0Bd,GACpBgB,EAAAA,EAAAA,QAAOhB,EAAqBlG,EAA8BnS,QAASkZ,GACnE,GAEoBZ,GACpBe,EAAAA,EAAAA,QAAOf,EAAsBnG,EAA8BnS,QAASkZ,EAAaC,GACjF,GAGV,MAAMG,EAAsF,QAAzEvB,EAAoD,QAApDC,EAAI3yB,KAAKyW,MAAMqW,8BAA8BnS,eAAO,IAAAgY,OAAA,EAAhDA,EAAkDuB,2BAAmB,IAAAxB,EAAAA,EAAI,GAC1FyB,EAAwBn0B,KAAKo0B,0BAA0BH,GAE7D,IAAI1a,EAAY,yBACZ4a,IACA5a,EAAYC,GAAAA,CAAWD,EAAW,sCAAsC0a,MAK5E,MAAMI,GAAYC,EAAAA,iBAAiBC,mBAAmBpa,EAAoBqa,oBACpEC,GAAYH,EAAAA,iBAAiBC,mBAAmBpa,EAAoBua,gBACpEC,EAAmBN,GAAYI,EAC/BnC,EAAU,GAAGnY,EAAoBD,+BAAiCC,EAAoB5W,4BAAqDc,IAA9B8V,EAAoB/J,MAAsB,KAAK+J,EAAoB/J,SAAW,KAEjM,OACIoG,EAAAA,cAAA,MAAI+C,UAAWA,EAAWnY,GAAI,GAAG0rB,EAA8BnS,WAAYhQ,KACvE6L,EAAAA,cAAA,IAAAmD,OAAAC,OAAA,CACI1W,IAAKwpB,EAA8B,OAAS,QAC5C7O,IAAK7d,KAAKwyB,WACVxc,KAAMhW,KAAK40B,iBACXC,SAAUR,GAAY,EAAI,EAC1Bva,QAAS9Z,KAAK4W,SACd2C,UAAWka,EACX1Z,KAAMwW,EAAS,aACHwD,EAAuB,iBACnBrH,EAChBlP,MAAO8U,GACHtf,EACAkgB,GAEHyB,GAAoBR,GAAyBn0B,KAAK80B,cAAcb,GACjEzd,EAAAA,cAAA,QAAM+C,UAAU,gCAA+B,cAAa,QAExD/C,EAAAA,cAAA,QAAM+C,UAAU,uCACXY,EAAoBD,+BAAiCC,EAAoB5W,2BAE/Cc,IAA9B8V,EAAoB/J,OACjBoG,EAAAA,cAAA,QAAM+C,UAAU,wCAAwCY,EAAoB/J,UAQ5FgkB,0BAA0BH,GAE9B,OAD8Bc,EAAAA,EAAAA,8BAA6Bd,EAAej0B,KAAKyW,MAAM1U,SAIjF+yB,cAAcb,GAA6B,IAAAe,EAC/C,MAAM7a,EAAsBna,KAAKyW,MAAM0D,oBAGjCwB,EAAOxB,EAAoBD,+BAAiCC,EAAoB5W,sBAAwB,GACxG0xB,EAAc,CAChB,CACIjwB,OAAQ,GAAsC,QAAtCgwB,EAAG7a,EAAoB7W,uBAAe,IAAA0xB,EAAAA,EAAI,MAAMf,KAAiBtY,IACzExY,MAAOwY,EACPsY,cAAAA,EACAiB,aAAc/a,EAAoBqa,mBAClCzX,SAAU5C,EAAoBua,iBAItC,OACIle,EAAAA,cAAC2e,EAAAA,gBAAe,CACZ5b,UAAU,iCACV1Z,YAAaG,KAAKyW,MAAM1U,QAAQC,QAAQnC,YACxCu1B,KAAMH,EACNI,oBAAoB,EACpBC,cAAY,IAKhBV,iBACJ,MAAM,WAAE/a,EAAU,8BAAEiT,EAA6B,oBAAE3S,EAAmB,4BAAEuS,GAAgC1sB,KAAKyW,MAE7G,OAAI0D,EACON,EAAW,CACdiT,8BAAAA,EACA3S,oBAAAA,EACA+W,aAAcxE,IAIf,GAoBHkH,cACJzZ,EACA2S,EACAO,EACAtrB,EACA4I,EACAmN,EACAyd,EACAC,GAEA,GAAIrb,EAAoB5W,qBAAsB,KAAA+mB,EAAAmL,EAC1Cz1B,KAAK4X,QAAQuB,cAAcC,MAAQe,EAAoBD,8BACvD,MAAMlH,GAAYsG,EAAAA,EAAAA,wBAAuBxB,EAAmB9X,KAAK4X,SAC3D8d,EAAgB7oB,OAAO8oB,SAASxb,EAAoB5W,qBAAsB,IAC1EqyB,EAAgD,QAAnCtL,EAAGtqB,KAAKyW,MAAMof,6BAAqB,IAAAvL,OAAA,EAAhCA,EAAkC1jB,MACpDzD,GAASA,EAAM4M,gBAAkBoK,EAAoBpK,gBAGnD+lB,EAAiBjpB,OAAO8oB,UAASC,MAAAA,OAAa,EAAbA,EAAeryB,uBAAwB,IAAK,IAC7EwyB,EAAyB,EAC/B,IAAIC,EAA+B,sBAE/BA,EADAN,EAAgBI,EACO,GAAGE,QACnBN,EAAgBI,EACA,GAAGE,UAEH,GAAGA,aAE9B,MAAMC,OAC4B5xB,IAA9B8V,EAAoB/J,OAAuB+J,EAAoB/J,QAAU2lB,EACnEP,IAAkCxB,EAAAA,EAAAA,QAAOwB,EAAgCrb,EAAoB/J,OAC7FmlB,IAA4BvB,EAAAA,EAAAA,QAAOuB,EAA0Bpb,EAAoB/J,OAC3F,OACIoG,EAAAA,cAAA,MACI+C,UAAU,wDACVQ,KAAO/Z,KAAKyW,MAAMyf,kBAAgC7xB,EAAjB,eACjCjD,GAAI,GAAG0rB,EAA8BnS,WAAYhQ,KAEjD6L,EAAAA,cAAA,IAAAmD,OAAAC,OAAA,CACI5D,KAAMhW,KAAK40B,iBACX7a,KAAK,SAAQ,gBACEsT,EAAS,aACZ,GAAGP,EAA8BnS,WAAYR,EAAoBD,0DAC3E+b,IACFnc,QAAS9Z,KAAK4W,UACV5D,GAEJwD,EAAAA,cAAC2f,EAAAA,gBAAe,CACZ5c,UAAWyc,EACXI,UAAWV,EACXW,YAA8D,QAAnDZ,EAAEtb,EAAoBD,qCAA6B,IAAAub,EAAAA,EAAItb,EAAoB5W,qBACtF+yB,WAAW,EACXC,UAAQ,EACR7Y,UAAU,GACV3b,QAASA,EACTX,GAAIpB,KAAKyW,MAAMwN,SACfmC,SAAUpmB,KAAKyW,MAAM+f,eACrB7V,KAAM,KAEVnK,EAAAA,cAAA,QAAM+C,UAAU,8BAA6B,cAAcvZ,KAAKyW,MAAMyf,aAAe,YAAS7xB,QAC3DA,IAA9B8V,EAAoB/J,OAAuB,IAAI+J,EAAoB/J,gJCxPhG,MAAMqmB,UAAsBjgB,EAAAA,UAGxB5W,YAAY6W,GACRC,MAAMD,GAHO,KAAAigB,SAAW,GAKxB12B,KAAK22B,cAAgB32B,KAAK22B,cAAc1K,KAAKjsB,MAC7CA,KAAK42B,iBAAmB52B,KAAK42B,iBAAiB3K,KAAKjsB,MAEnD,MAAM62B,EAAa72B,KAAKyW,MAAMqgB,wBAM9B92B,KAAKotB,MAAQ,CACT2J,SAAUF,EACVG,eAAgBvgB,EAAMwgB,wBAAwB5e,OAAOnQ,QAAUlI,KAAK02B,UAIrEhJ,sBAAsBC,EAAgCC,GACzD,OAAI5tB,KAAKotB,QAAUQ,GAAa5tB,KAAKyW,QAAUkX,EAM5ClV,SACH,MAAM,wBAAEwe,EAAuB,sBAAEjJ,GAA0BhuB,KAAKyW,MAMhE,GAJKwgB,GACDjJ,EAAsBlmB,UAAUD,MAAM,wDAGtCovB,EAAwBvD,cAAgBpjB,EAAAA,qBAAqBqjB,QAAU3zB,KAAKyW,MAAM1U,QAAQ6G,IAAIxE,OAAO8yB,WACrG,OAAO,KAGX,MAAM3d,EAAYC,GAAAA,CACd,oBACA,aACAyd,EAAwBtc,SAG5B,OACInE,EAAAA,cAAA,OAAK+C,UAAWA,GACZ/C,EAAAA,cAAC2I,EAAAA,OAAM,CACH5F,UAAWvZ,KAAKotB,MAAM2J,SAAW,iCAAmC,kCAAiC,aACzFE,EAAwBtc,QACpCb,QAAS9Z,KAAK42B,iBAAgB,gBACf52B,KAAKotB,MAAM2J,UAEzBE,EAAwBtc,SAE7BnE,EAAAA,cAAC2gB,EAAAA,SAAQ,CAACvY,OAAQ5e,KAAKotB,MAAM2J,SAAUK,QAAS,EAAGC,UAAWA,KAG1DhhB,OAAOihB,cAAc,IAAIC,MAAM,aAE9Bv3B,KAAKw3B,kBAAkBP,KAMhCO,kBAAkBP,GACtB,OAAIrc,EAAAA,EAAAA,IAAYqc,EAAwBlnB,eAC7B/P,KAAKy3B,aAAaR,GAEtBj3B,KAAK03B,yBAAyBT,GAGjCS,yBAAyBT,GAC7B,MAAM,WACFtI,EAAU,sBACVX,EAAqB,sBACrB6H,EAAqB,QACrB9zB,EAAO,sBACP8wB,EAAqB,4BACrBC,EAA2B,oBAC3BE,EAAmB,qBACnBC,EAAoB,SACpB0E,GACA33B,KAAKyW,MAIHsD,EAFFkd,EAAwB3D,mBAAqBC,EAAAA,YAAYC,cACzDyD,EAAwBvD,cAAgBpjB,EAAAA,qBAAqBqjB,OACnC,CAAE5Z,KAAM,gBAAc1V,EAC9CuzB,EAAoBX,EAAwB5e,QAAU,GAC5Duf,EAAkBliB,MACd,CAACmiB,EAAGC,KAAOD,EAAE3d,+BAAiC2d,EAAEt0B,sBAAwB,IAAIw0B,cAAcD,EAAE5d,+BAAiC4d,EAAEv0B,sBAAwB,GAAIxB,EAAQC,QAAQS,UAE/K,MAAMu1B,EAAYJ,EAAkBx0B,KAAI,CAAC60B,EAA4BttB,KACjE,IAAKstB,EAID,OAHAjK,EAAsBlmB,UAAUD,MAC5B,6DAA6DovB,EAAwBhxB,aAAagxB,EAAwBtc,YAEvH,KAEX,GAAIhQ,EAAS3K,KAAK02B,SAAW,IAAO12B,KAAKotB,MAAM4J,eAC3C,OAAO,KAEX,MAAMtK,GAA8BwL,EAAAA,EAAAA,IAAgCD,EAAOpC,GAE3E,OACIrf,EAAAA,cAAC+b,EAAAA,EAAU,CACPzF,8BAA+BmK,EAC/B9c,oBAAqB8d,EACrBvL,4BAA6BA,EAC7BmJ,sBAAuBA,EAAsBzqB,QAAO+sB,GAChDP,EAAkBhxB,MAAKzD,GAASA,EAAMG,kBAAoB60B,EAAc70B,oBAE5E0qB,sBAAuBA,EACvB6C,SAAU7wB,KAAK22B,cACf9c,WAAY7Z,KAAKyW,MAAMoD,WACvB8U,WAAYA,EACZzrB,IAAKyH,EACLA,MAAOA,EACP5I,QAASA,EACTkiB,SAAUjkB,KAAKyW,MAAMwN,SACrBuS,eAAgBx2B,KAAKyW,MAAM+f,eAC3B1e,iBAAkB9X,KAAKyW,MAAMqB,iBAC7B+a,sBAAuBA,EACvBG,oBAAqBA,EACrBC,qBAAsBA,EACtBH,4BAA6BA,EAC7BoD,aAAcyB,OAI1B,OACInhB,EAAAA,cAAA,KAAAmD,OAAAC,OAAA,CACIL,UAAW,2BAA2B0d,EAAwBtc,WAC1DZ,EAAI,cACIkd,EAAwBtc,UAEnCqd,EACAJ,EAAkB1vB,OAASlI,KAAK02B,UAAYlgB,EAAAA,cAAA,UAAQ+C,UAAW,sBAAqBvZ,KAAKotB,MAAM4J,eAAiB,OAAO,QAAUld,QAASA,IAAK9Z,KAAK0uB,SAAS,CAACsI,gBAAgBh3B,KAAKotB,MAAM4J,kBAAmBh3B,KAAKotB,MAAM4J,eAAiB,YAAc,YAAYY,EAAkB1vB,OAASlI,KAAK02B,cAKvS0B,cAAcnB,GAClB,OACIA,EAAwBoB,uBAAyBC,EAAAA,gBAAgBC,OACjEtB,EAAwBoB,uBAAyBC,EAAAA,gBAAgB3I,QACjEsH,EAAwBoB,uBAAyBC,EAAAA,gBAAgBE,eAE1D,SAEJ,QAGHf,aAAaR,GACjB,MAAM,WACFtI,EAAU,sBACVX,EAAqB,sBACrB6H,EAAqB,QACrB9zB,EAAO,6BACP6pB,EAA4B,6BAC5BG,GACA/rB,KAAKyW,MAGHuhB,GADoBf,EAAwB5e,QAAU,IACxBjV,KAAI,CAAC60B,EAA4BttB,KACjE,IAAKstB,EAID,OAHAjK,EAAsBlmB,UAAUD,MAC5B,4CAA4CovB,EAAwBhxB,aAAagxB,EAAwBtc,YAEtG,KAGX,MAAM+R,GAA8BwL,EAAAA,EAAAA,IAAgCD,EAAOpC,GAErE5H,EAAYjuB,KAAKo4B,cAAcnB,GAC/B/zB,EAAMwpB,EACN,GAAGA,EAA4BnpB,wBAAwBmpB,EAA4BlpB,wBACnF,gBAAgBmH,IACtB,OACI6L,EAAAA,cAAA,MAAI+C,UAAW,sEAAoCrW,IAAKyH,GACpD6L,EAAAA,cAAC4T,EAAAA,EAAe,CACZ0C,8BAA+BmK,EAC/B9c,oBAAqB8d,EACrBvL,4BAA6BA,EAC7BsB,sBAAuBA,EACvB6C,SAAU7wB,KAAK22B,cACf9c,WAAY7Z,KAAKyW,MAAMoD,WACvB8U,WAAYA,EACZV,UAAWA,EACX/qB,IAAKA,EACLmoB,UAAWnoB,EACXnB,QAASA,EACT6pB,6BAA8BA,EAC9BG,6BAA8BA,EAC9B9H,SAAUjkB,KAAKyW,MAAMwN,SACrBuS,eAAgBx2B,KAAKyW,MAAM+f,qBAK3C,OAAOhgB,EAAAA,cAAA,MAAI+C,UAAW,yCAAyC0d,EAAwBtc,WAAYqd,GAG/FrB,cAAc8B,GAClBz4B,KAAKyW,MAAMiiB,iBAAiBD,GAGxB7B,mBACJ52B,KAAK0uB,UAASiK,IAAa,CACvB5B,UAAW4B,EAAU5B,cAKjC,iGCjQY6B,EAmDAC,EA8BAvoB,6lBAwDN,SAAUsK,EAAYke,GACxB,OACIA,IAAkB9oB,EAAAA,kBAAkByC,UACpCqmB,IAAkB9oB,EAAAA,kBAAkB+oB,SACpCD,IAAkB9oB,EAAAA,kBAAkBuD,QAItC,SAAUmG,EAAUof,GACtB,OACIA,IAAkB9oB,EAAAA,kBAAkBC,UAQtC,SAAUioB,EACZ/d,EACA6e,GAGA,OAAOA,EAAmBpyB,MAAMqyB,GAC5B3gB,EAA8B6B,EAAqB8e,KAUrD,SAAU3gB,EAA8B6B,EAA0C8e,GAEpF,OACIA,EAAoB31B,kBAAoB6W,EAAoB7W,iBAC5D21B,EAAoB5oB,qBAAuB8J,EAAoB9J,oBAC/D4oB,EAAoBlpB,gBAAkBoK,EAAoBpK,gBACzD6K,EAAYqe,EAAoBlpB,gBAC7BkpB,EAAoB11B,uBAAyB4W,EAAoB5W,sBAIvE,SAAU21B,EACZT,EACAU,GAEA,MAAMC,EAAmD,GACzD,IAAIC,GAAmB,EAsBvB,GArBAF,EAA0BlsB,SAASqsB,IAC/B,GAAIhhB,EAA8BmgB,EAAuBte,oBAAqBmf,IAE1E,GADAD,GAAmB,EACfZ,EAAuBvH,YAAa,CACpC,MAAMqI,EAAI12B,EAAAA,EAAA,GACHy2B,GAAiB,IACpB/1B,0BAC2Cc,IAAtCo0B,EAAuBtH,YAA4B,GAAGsH,EAAuBtH,cAC9EmI,EAAkB/1B,qBACtBC,2BACyCa,IAApCo0B,EAAuBrH,UAA0B,GAAGqH,EAAuBrH,YAC5EkI,EAAkB91B,wBAE1B41B,EAA0B3tB,KAAK8tB,SAInCH,EAA0B3tB,KAAK6tB,OAIlCD,EAAkB,CACnB,MAAME,EAAI12B,EAAAA,EAAA,GACH41B,EAAuBte,qBAAmB,IAC7C5W,0BAC2Cc,IAAtCo0B,EAAuBtH,YAA4B,GAAGsH,EAAuBtH,cAC9EsH,EAAuBte,oBAAoB5W,qBAC/CC,2BACyCa,IAApCo0B,EAAuBrH,UAA0B,GAAGqH,EAAuBrH,YAC5EqH,EAAuBte,oBAAoB3W,wBAEnD41B,EAA0B3tB,KAAK8tB,GAI1Bd,EAAuBte,oBAAoBpK,gBAAkBC,EAAAA,kBAAkBwpB,MAC5Ef,EAAuBte,oBAAoBpK,gBAAkBC,EAAAA,kBAAkBC,WACnFwoB,EAAuB3L,8BAA8BwG,mBAAqBC,EAAAA,YAAYC,cAEtFiF,EAAuB3L,8BAA8BzU,OAAOpL,SAASgrB,IACjE,GAAIA,EAAM30B,kBAAoBi2B,EAAKj2B,iBAAmB20B,EAAM10B,uBAAyBg2B,EAAKh2B,0BAEnF,CACH,MAAMk2B,EAAgBL,EAA0BM,WAAWC,GACvDrhB,EAA8B2f,EAAO0B,KAErCF,GAAiB,GACjBL,EAA0B/T,OAAOoU,EAAe,OAOpE,OAAOL,GAlPX,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,SAAYvoB,GASRA,EAAAA,EAAA,eAUAA,EAAAA,EAAA,yBAUAA,EAAAA,EAAA,uBAUAA,EAAAA,EAAA,iBAUAA,EAAAA,EAAA,mBAjDJ,CAAYA,IAAAA,EAAoB,mEC1FzB1P,eAAeopB,EAClBjoB,EACA2P,EACA1L,EACA4zB,GAEA,IAAK5zB,IAAYA,EAAQkD,gBACrB,MAAO,CAAE2wB,SAAS,GAGtB,MAAMC,GAAYC,EAAAA,EAAAA,GAAeh4B,EAAS2P,EAAU1L,EAAQkD,iBAE5D,MAAO,CACH2wB,QAASC,EACTE,QAASF,OAAYz1B,EAAYu1B,yDCjBlC,MAAMK,EAAYA,CAACC,EAAyBC,KAC/C,MAAMC,EAAeF,EAAQjpB,IAAIkpB,GAEjC,OAAIC,GAAgBA,EAAaj3B,OAASi3B,EAAaj3B,MAAM+E,OAAS,EAC3DkyB,EAAaj3B,WAEpB,GAIKk3B,EAAYA,CAACH,EAAyB/2B,EAAeg3B,EAAoBG,KAC9En3B,GACA+2B,EAAQrkB,IAAIskB,EAAYh3B,EAAO,CAAEo3B,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-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.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 }\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 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 { 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 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 if (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 {\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 { 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 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 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?.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 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 forsvaretRefiner = await getForsvaretRefiner(context, customerAttributes);\r\n\r\n if (forsvaretRefiner) {\r\n searchCriteriaInput.Refinement!.push(forsvaretRefiner);\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 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];\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\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 }\r\n return (\r\n
  • \r\n \r\n {item?.parent && {item.parent}:}\r\n {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 \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 } 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\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}\r\n\r\ninterface IProductSearchResultItems {\r\n cart: ICartState | undefined;\r\n products: ProductSearchResultExt[];\r\n simpleProducts: SimpleProduct[];\r\n customerInformation?: 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 (error) {\r\n toast({\r\n header: toastErrorHeader,\r\n // @ts-ignore\r\n text: error,\r\n // @ts-ignore\r\n footer: error?.data?.CorrelationId ? `Correlation Id: ${error?.data?.CorrelationId}` : undefined,\r\n type: \"error\",\r\n autoClose: 0,\r\n position: \"bottom-right\",\r\n canClose: true,\r\n showProgress: false,\r\n onClose: () => { }\r\n });\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 (error) {\r\n toast({\r\n header: resources.toastErrorHeader,\r\n // @ts-ignore\r\n text: error,\r\n // @ts-ignore\r\n footer: error?.data?.CorrelationId ? `Correlation Id: ${error?.data?.CorrelationId}` : undefined,\r\n type: \"error\",\r\n autoClose: 0,\r\n position: \"bottom-right\",\r\n canClose: true,\r\n showProgress: false,\r\n onClose: () => {}\r\n });\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 autoClose: 3000,\r\n position: \"bottom-right\",\r\n canClose: true,\r\n showProgress: false,\r\n onClose: () => { }\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 toast({\r\n header: toastErrorHeader,\r\n text: error,\r\n footer: error?.data?.CorrelationId ? `Correlation Id: ${error?.data?.CorrelationId}` : undefined,\r\n type: \"error\",\r\n autoClose: 0,\r\n position: \"bottom-right\",\r\n canClose: true,\r\n showProgress: false,\r\n onClose: () => {}\r\n });\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 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 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 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\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\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\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 ...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 this.payLoad.contentAction.etext = productRefinerValue.LeftValueBoundLocalizedString ?? productRefinerValue.LeftValueBoundString;\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 = productRefinerValue.LeftValueBoundLocalizedString || productRefinerValue.LeftValueBoundString || '';\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 = `${productRefinerValue.LeftValueBoundLocalizedString || productRefinerValue.LeftValueBoundString}${productRefinerValue.Count !== undefined ? ` (${productRefinerValue.Count})` : ''}`;\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\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\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 const className = classnames(\r\n 'ms-refine-submenu',\r\n 'list-group',\r\n productRefinerHierarchy.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 {productRefinerHierarchy.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 />\r\n );\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 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, ProductRefinerValue, RefinerType } from '@msdyn365-commerce/retail-proxy';\r\n\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\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 (\r\n dataTypeValue === AttributeDataType.Currency ||\r\n dataTypeValue === AttributeDataType.Decimal ||\r\n dataTypeValue === AttributeDataType.Integer\r\n );\r\n}\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 * 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(productRefinerValue: ProductRefinerValue, refinementCriterion: ProductRefinerValue): boolean {\r\n // If the value is a range, then match only on data type value; otherwise match on item string\r\n return (\r\n refinementCriterion.RefinerRecordId === productRefinerValue.RefinerRecordId &&\r\n refinementCriterion.RefinerSourceValue === productRefinerValue.RefinerSourceValue &&\r\n refinementCriterion.DataTypeValue === productRefinerValue.DataTypeValue &&\r\n (isRangeType(refinementCriterion.DataTypeValue) ||\r\n refinementCriterion.LeftValueBoundString === productRefinerValue.LeftValueBoundString)\r\n );\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 currentRefinementCriteria.forEach((selectedCriterion: ProductRefinerValue) => {\r\n if (isMatchingRefinementCriterion(itemToggleNotification.productRefinerValue, selectedCriterion)) {\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)\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","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","length","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","promise","channelInventoryConfigurationPromise","searchProductId","searchCriteriaInput","Context","Refinement","slice","IncludeAttributes","SkipVariantExpansion","SearchCondition","index","_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","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","DefaultValues","RefinersByCollectionInput","getRefinersForCollectionDataAction","alcoholFilter","attributeRefiners","getAllAttributeRefiners","concat","getAlcoholRefiners","defaultRefiners","getProductRefinerHierarchy","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","result","alcoholRefiner","alcoholLicenseValue","_customer$Attributes","customer","alcoholLicense","Attributes","AttributeValue","StringValue","console","warn","Array","fill","_","toString","addAlcoholRefiner","priceRefiner","_context$requestConte6","channel","Currency","getAttributeRefiners","customerAttributes","attributeRecordId","friendlyName","attributeValue","_customerAttributes$f","attribute","getForsvaretRefiner","_context$requestConte7","forsvaretAttributeId","forsvaretAttributeRecordId","_customerAttributes$f2","IntegerValue","Integer","addAttributeRefiner","_context$requestConte8","_context$requestConte9","_context$requestConte10","_context$requestConte11","_context$requestConte12","_context$requestConte13","attributeRecordIds","transitRefinerRecordId","tobaccoRefinerRecordId","cocacolaRefinerRecordId","bamaRefinerRecordId","dutyFreeSugarRefinerRecordId","norturaRefinerRecordId","forsvaretRefiner","_context$requestConte14","_context$requestConte15","_context$requestConte16","_context$requestConte17","_context$requestConte18","_context$requestConte19","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","isBoolean","Object","assign","urlBuilder","onClick","role","style","fontWeight","LeftValueBoundLocalizedString","productRefinerValue","choiceFormat","choiceRangeValueFormat","refinerValues","overallFormat","rangeFormat","refinerValueName","refinerName","KeyName","isRangeType","replace","_formatPrice","filterValue","amount","currency","trace","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","AccountNumber","createdCommerceList","addLinesAsync","buildWishlistLine","update","createGetByCustomerInput","_error$data","_error$data2","toast","header","footer","data","CorrelationId","type","autoClose","position","canClose","showProgress","onClose","customerInput","GetCustomerInput","getCustomer","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","addedProductToWishlistText","wishlistName","listData","CustomerId","CommerceListTypeValue","createCommerceListAsync","_error$data3","_error$data4","moveItemToWishlist","ProductSearchResultItems","cart","simpleProducts","customerInformation","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","onUpdateOrderTemplates","quickViewButton","wishlistButton","inventoryLabel","inventoryStatus","disableBuyButton","showPrice","userHasAccess","HasAccess","swatchItemAriaLabel","addToCartText","updateCartText","removeFromCartText","outOfStockText","priceErrorText","toastStrings","errorHeader","productsAddedToCart","productsRemovedFromCart","productsUpdatedInCart","goToCart","toastGoToCart","noAccessToProduct","toastNoAccessToProduct","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","RangeRefineItem","_selectedRefinementCr","_this$props$selectedR","_this$props$selectedR2","_ref2","_this$props$selectedR3","_this$props$selectedR4","_formattedPriceReverseLookup","Map","getLabels","sliderId","minPrice","maxPrice","labelId","labelString","labelPositioning","getSliderThumbs","sliderKey","selectedMin","selectedMinPrice","selectedMax","selectedMaxPrice","_this$props$minValueS","_this$props$maxValueS","minValueSliderThumbAriaLabel","currencyCode","ariaValueText","maxValueSliderThumbAriaLabel","_onRangeUpdate","bind","_onRangeUpdateEnd","_handleRangeTooltipText","_changeMin","_changeMax","_finishChangeMin","_finishChangeMax","minInput","maxInput","selectedRefinementCriterion","initialMin","initialMax","String","parentProductRefinerHierarchy","minValue","maxValue","labels","sliderKeyString","sliderThumbs","state","isChecked","validationErrorMin","validationErrorMax","touchedMin","touchedMax","shouldComponentUpdate","nextProps","nextState","componentDidUpdate","previousProps","updateSliderProps","refineItemCommonProps","rangeType","_renderInputFields","_renderSlider","_ref3","_this$props$selectedR5","_this$props$selectedR6","_ref4","_this$props$selectedR7","_this$props$selectedR8","setState","isDisabled","formAttrs","rangeNameFormat","minInputClassName","maxInputClassName","formattedSelectedMin","_getFormattedSelectedValue","formattedSelectedMax","minLabel","onChange","onFocus","onBlur","maxLabel","placeholder","placeholderTextMax","ariaAttributes","Slider","inForm","min","step","orientation","showLabels","showTooltip","onChangeEnd","debounce","handleTooltipText","event","_changeValue","inputType","selectedKey","touchedKey","_getInputWithoutFormatting","selectedMinValue","minTouched","onToggle","maxNum","validationErrorNaN","_focus","_validateRange","isSelecting","rangeStart","rangeEnd","selectedMaxValue","maxTouched","minNum","setTimeout","current","focus","touched","validationError","validationErrorRange","inputAsNum","sliderChangeNotification","eventType","firstThumbValue","secondThumbValue","_focusOnSliderThumb","document","getElementById","tooltip","RefineItem","anchorType","_productRefinerValue$","_this$props$parentPro","_this$props$parentPro2","_this$props","productCountAriaLabel","singleProductCountAriaLabel","children","refineItemAriaLabel","refineItemsAriaLabel","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","_getRefinerUrl","tabIndex","_renderSwatch","checkIfShouldDisplayAsSwatch","_productRefinerValue$2","swatchItems","colorHexCode","SwatchComponent","list","isSelectionEnabled","isRefineItem","ratingUserCountAriaLabel","ratingSingleUserCountAriaLabel","_productRefinerValue$3","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","Collapse","timeout","onEntered","dispatchEvent","Event","_renderChildItems","_renderRange","_renderSingleMultiSelect","isMobile","refinerValuesList","a","b","localeCompare","listItems","child","findMatchingRefinementCriterion","selectedValue","_getRangeType","DisplayTemplateValue","DisplayTemplate","Range","SliderWithBars","itemToggleNotification","onUpdateRefiners","prevState","ProductRefinerValueDataTypeValue","ProductRefinerTypeValue","dataTypeValue","Decimal","refinementCriteria","refinementCriterion","getUpdatedRefinementCriteria","currentRefinementCriteria","updatedRefinementCriteria","toggledItemFound","selectedCriterion","next","Text","matchingIndex","findIndex","criterion","validationMessage","isValid","hasAccess","hasAccessToBuy","message","GetCookie","cookies","cookieName","marketCookie","SetCookie","exp","path","maxAge"],"sourceRoot":""}