{"version":3,"file":"coopse.script.5039.3d09d3cb.chunk.js","mappings":"wHAiB4BA,EAAQ,QAAoC,EACxE,IAAIC,EAAY,EAAQ,MAExBC,OAAOC,eAAeH,EAAS,KAA/B,CAA2CI,YAAY,EAAMC,IAAK,WAAc,OAAOJ,EAAUK,MAAQ,G,uBCJzGJ,OAAOC,eAAeH,EAAS,aAAc,CAAEO,OAAO,IACtDP,EAAQQ,iBAAmBR,EAAQS,kBAAoBT,EAAQM,YAAS,EACxE,MAAMI,EAAQ,EAAQ,OAKtB,SAASD,EAAkBE,EAAMC,EAAU,CAAC,GACxC,MAAO,CACHC,KAAM,sBACNC,wBAAyB,CACrBC,OAAQC,KAAKC,UAAUN,EAAMO,EAAoBN,EAAQO,QAGrE,CARAnB,EAAQM,OAHR,SAAgBc,GACZ,OAAOV,EAAMW,cAAc,SAAUnB,OAAOoB,OAAO,CAAC,EAAGb,EAAkBW,EAAMT,KAAMS,IACzF,EAUApB,EAAQS,kBAAoBA,EAO5BT,EAAQQ,iBANR,SAA0BG,EAAMC,EAAU,CAAC,GACvC,MAAO,CACHC,KAAM,sBACNU,UAAWP,KAAKC,UAAUN,EAAMO,EAAoBN,EAAQO,OAEpE,EAEA,MAAMK,EAAkBtB,OAAOuB,OAAO,CAClC,IAAK,QACL,IAAK,OACL,IAAK,OACL,IAAK,SACL,IAAK,WAEHC,EAAe,IAAIC,OAAO,IAAIzB,OAAO0B,KAAKJ,GAAiBK,KAAK,OAAQ,KACxEC,EAAmBC,GAAMP,EAAgBO,GAKzCb,EAGK,CAACc,EAAGzB,KACP,cAAeA,GACX,IAAK,SAED,GAAc,OAAVA,EACA,OAEJ,OAAOA,EACX,IAAK,SACL,IAAK,UACL,IAAK,SACD,OAAOA,EACX,IAAK,SACD,OAAOA,EAAM0B,QAAQP,EAAcI,GACvC,QAII,OAER,C,mHCoBR,EAlF8DV,I,MAC1D,MAAMc,EAAO,OAAH,UAAQd,EAAMe,KAAKD,MACvBE,EAAO,OAAH,UAAQhB,EAAMe,KAAKC,MAEzBF,GAAQA,EAAKG,YACbH,EAAKG,WAAY,QAAa,CAC1BC,KAAMJ,EAAKG,UACXE,KAAsB,QAAhB,EAAAnB,EAAMoB,kBAAU,eAAEC,eAIhC,IAAIC,GAAc,EACdC,GAAc,EAEdvB,EAAMoB,aACNE,EAA+C,IAAjCtB,EAAMoB,WAAWC,YAC3BrB,EAAMoB,WAAWI,aACjBD,EACIvB,EAAMoB,WAAWK,SAAWzB,EAAMoB,WAAWC,aAC7CrB,EAAMoB,WAAWI,aAIzBF,GAAeR,GAAQd,EAAMoB,aAC7BN,EAAKY,UAAW,QAAY1B,EAAMoB,WAAWC,cAG7CE,GAAeT,GAAQd,EAAMoB,aAC7BN,EAAKa,UAAW,QAAY3B,EAAMoB,WAAWC,cAGjD,MAAMO,EACFd,GACAhC,OAAO+C,QAAQf,GAAMgB,QAChBvC,GAAqB,KAAZA,EAAK,SAAyBwC,IAAZxC,EAAK,IAAgC,OAAZA,EAAK,KAG5DyC,EACFhB,GACAlC,OAAO+C,QAAQb,GAAMc,QAChBvC,GAAqB,KAAZA,EAAK,SAAyBwC,IAAZxC,EAAK,IAAgC,OAAZA,EAAK,KAGlE,IAAIC,EAAyE,CACzEsB,KAAMc,aAAQ,EAARA,EAAUK,KAAI,EAAEC,MAAS,CAAGC,SAAU,MAAOhD,MAAO+C,OAG1DF,IACAxC,EAAU,OAAH,wBACAA,GAAO,CACVwB,KAAMgB,EAASC,KAAI,EAAEC,MAAS,CAAGC,SAAU,OAAQhD,MAAO+C,SAIlE,MAAME,GAAoC,EAAAC,EAAA,GAAwC7C,GAElF,OAEI,8BACK4C,IACG,UAACE,EAAA,EAAM,WACFtC,EAAMe,KAAKwB,QACR,2BACKvC,EAAMe,KAAKwB,OACN,KAAwD,GAA9B,+BAGvCP,aAAQ,EAARA,EAAUC,KAAI,EAAEE,EAAUhD,MACvB,iBAAqBqD,KAAML,EAAUM,QAAStD,GAAnCgD,KAGdP,aAAQ,EAARA,EAAUK,KAAI,EAAEE,EAAUhD,MACvB,iBAAqBuD,IAAKP,EAAUQ,KAAMxD,GAA/BgD,KAGdnC,EAAM4C,aAItB,C,mHC5FL,MAAMC,EAAmB,CAAC,QCmBbC,EAAwBtD,IACjC,MAAM,OAAEuD,IAAW,UACbC,GAAW,SAEXC,EACFzD,GACAA,EAAQyD,cACR,IAAIC,IAAI1D,EAAQyD,aAAcE,OAAOC,SAASC,QAAQC,WAGpDC,EDtB8C,EACpDC,EACAhD,EAAiB,MAEjB,MAAMiD,EAAc,IAAIZ,KAAqBrC,GAEvCkD,EAAe,IAAIC,gBAAgBH,GASzC,OAP6BI,MAAMC,KAAKH,EAAa7B,WAChDC,QAAO,EAAEI,KAASuB,EAAYK,SAAS5B,KACvC6B,QAAO,CAACC,GAAM9B,EAAK/C,MAChB6E,EAAIC,IAAI/B,EAAK/C,EAAMmE,YACZU,IACR,IAAIL,iBAEiBL,UAAU,ECOhBY,CAClBnB,EACCvD,GAAWA,EAAQ2E,qBAAwB,IAG1CC,IAAW5E,EAEX6E,GAAY,EAAAC,EAAA,IAAc,KACxBrB,GACAD,EACI,EAAAuB,EAAmBC,cAAc,CAC7BvB,eACAwB,eAAgBjF,GAAWA,EAAQkF,aACnCnC,MAAO/C,GAAWA,EAAQmF,UAC1BnB,YAAaL,OAAOC,SAASL,SAGzC,IASJ,OANA,IAAA6B,YAAU,KACFR,GAAUnB,GACVoB,EAAUQ,SACd,GACD,CAAC7B,EAAUoB,EAAQnB,EAAcM,EAAec,IAE5C,CACHA,YACH,C,8FCxBL,IAhB0ErE,I,OACtE,OAAqB,CACjBiD,aAAiC,QAAnB,EAAAjD,EAAM8E,SAAShE,YAAI,eAAEG,UACnC0D,UAAW3E,EAAM8E,SAASvC,MAC1BmC,aAAc1E,EAAM+E,yBACpBZ,oBAAqBnE,EAAMgF,qCAG/B,MAAMhC,GAAW,SAKjB,OAJA,IAAA4B,YAAU,KACN5B,EAAS,EAAAuB,EAAmBU,SAASjF,EAAM8E,SAASvC,OAAO,GAC5D,CAACS,EAAUhD,EAAM8E,SAASvC,SAEtB,SAAC,IAAQ,CAACxB,KAAMf,EAAM8E,SAAU1D,WAAYpB,EAAMkF,gBAAkB,C,gJCJ/E,IAnBqC,KACjC,MAAM,YAAEC,EAAW,WAAEC,IAAe,OAChC,KAAsBC,uBAGpB,kBAAEC,EAAiB,aAAEC,IAAiB,SAW5C,MAAO,CAAEC,cATa,WAClB,KACI,CACID,eACAJ,iBAER,CAACA,EAAaI,IAGMD,oBAAmBF,aAAY,C,uCCa3D,IA3BiDK,IAC7C,MAAOC,EAAqBC,IAA0B,IAAAC,WAAS,GAEzDC,EAAsBjG,KAAKC,UAAU4F,GAqB3C,OAnBA,IAAAb,YAAU,KACN,MAAMkB,EAA8BlG,KAAKmG,MAAMF,GAC3CC,IACuBlC,MAAMC,KAAKmC,SAASC,qBAAqB,QAAQ,GAAGrD,UAE5DsD,SAASC,I,QACpB,MAAMC,EAAwB,QAAd,EAAAD,aAAK,EAALA,EAAOC,eAAO,eAAEC,cAEI,QAApC,EAAAP,EAA4BM,UAAQ,SAAEF,SAASI,IACvCH,EAAMI,aAAaD,EAAMnE,YAAcmE,EAAMnH,OAC7CgH,EAAMK,aAAa,oBAAqB,OAC5C,GACF,IAGNb,GAAuB,GAC3B,GACD,CAACE,IAEGH,CAAmB,C,uEC/BvB,MAAMpB,EAAoBnF,IAC7B,MAAMsH,GAAM,IAAAC,QAAUvH,GAMtB,OAJA,IAAAwH,kBAAgB,KACZF,EAAI5B,QAAU1F,CAAK,IAGhBsH,CAAG,C,wDCLd,MAAMG,EAAaC,GAAqBA,EAAMC,aAGjCC,EAAwB,CACjCH,YACAI,qBAJwB,E,SAAA,IAAeJ,GAAYC,GAAUA,EAAMI,gB,iFC2CvE,GACIC,gBAAgB,EAAAC,EAAA,IA9CG,CAACC,EAAyCC,KAC7D,MAAMC,EAA6B,CAC/BA,MAAO,SACPC,kBAAmBH,EACnBI,kBAAmBH,EAAQpF,KAAK1C,GAASA,EAAK8G,gBAAe5F,KAAK,KAClEgH,UAAW,oBAGf,OAAaH,EAAM,IAuCnBI,cAAc,EAAAP,EAAA,IApCG,CACjBC,EACAO,EAAkC,QAElC,MAAML,EAA2B,CAC7BA,MAAO,SACPC,kBAAmBH,EACnBI,kBAAmBG,GAAoB,YACvCF,UAAW,kBAGf,OAAaH,EAAM,IA0BnBM,MAAM,EAAAT,EAAA,IAvBYU,IAClB,MAAMP,EAA2B,CAC7BA,MAAO,SACPC,kBAAmB,eACnBC,kBAAmBK,EAAaxB,cAChCoB,UAAW,oBAGf,OAAaH,EAAM,IAgBnBQ,WAAW,EAAAX,EAAA,IAbWY,IACtB,MAAMT,EAA+B,CACjCA,MAAO,eACPU,aAAcD,EAAO,YAAc,eAGvC,OAAaT,EAAM,I,8IC3ChB,MAAMW,EAAmB,CAACC,EAAmBC,IAC5CD,GAAWC,EACJ,mBAGPD,EACO,UAGPC,EACO,gBADX,EAOSC,EAAe,EAAGlH,OAAMC,WACjC,MAAMkH,EAAM,IAAInF,IAAIhC,EAAMiC,OAAOC,SAASC,QAAQC,WAElD,OAAOgF,OAAOC,UAAUpH,IAAkB,IAATA,GAC3B,QAAoBkH,EAAK,CAAElH,KAAMqH,OAAOrH,KACxCkH,CAAG,EAGAI,EAAepH,IACxB,MAAMqC,EAAe,IAAIC,gBAOzB,OANAD,EAAaO,IAAI,QAAS5C,EAAc,GAAGiC,YAE5B,GACXH,OAAOC,SAASC,OAASF,OAAOC,SAASsF,YACzChF,EAAaJ,YAEJ,EAGJqF,EAAetH,IACxB,MAAMqC,EAAe,IAAIC,gBACnBjC,EAAWL,EAAc,EAC3BK,EAAW,EACXgC,EAAaO,IAAI,OAAQvC,EAAS4B,YAElCI,EAAakF,OAAO,QAExB,MAAMC,EAAoBnF,EAAaJ,WAOvC,OAJIH,OAAOC,SAASC,OAChBF,OAAOC,SAASsF,UACfG,EAAoB,IAAInF,EAAaJ,aAAe,GAE5C,C,yTCnCjB,MAAMwF,EAAc,gCA6EpB,MA3EkC9I,I,QAC9B,MAAM,QAAE+I,GAAY/I,EACdgJ,EAAgC,QAAlB,EAAAD,aAAO,EAAPA,EAASE,iBAAS,eAAEC,YAElC,QAAEC,EAAO,OAAEC,EAAM,UAAEC,IAAc,EAAAC,EAAA,GAAmBC,EAAA,EAAYC,wBAAyB,CAC3FC,qBAAqB,IAGnBC,GAAwB,OAAeC,EAAA,EAAeD,uBAEtDF,GAA0B,IAAAI,cAAY,KACpCZ,GACAG,EAAQH,EAAa,GAAIU,EAC7B,GACD,CAACP,EAASH,EAAaU,IAEpBG,EAA2C,QAAhB,EAAAT,aAAM,EAANA,EAAQU,gBAAQ,eAAEhI,QAC9CvC,GAASA,EAAK2J,cAAeH,aAAO,EAAPA,EAASG,eAGrC,iBAAEa,GAAqB/J,GAE7B,IAAA4E,YAAU,KACFiF,GACAE,EAAiBF,EAAyBG,OAC9C,GACD,CAACD,EAAkBF,IAEtB,MAAM,cAAErE,EAAa,WAAEJ,EAAU,sBAAE6E,EAAqB,gBAAEC,IACtD,OAAkC,SAEtC,IAAAtF,YAAU,KACN4E,GAAyB,GAC1B,CAACA,IAEJ,MAAMW,GAAW,IAAAC,SAEjB,OAAKpB,IAEAK,IAAcQ,aAAwB,EAAxBA,EAA0BG,UAKzC,SAACK,EAAA,EAAS,CACNC,GAAG,QAAO,kBACOH,EACjBI,YAAY,SAAC,IAAW,CAACC,GAAIL,EAAQ,SAAGrB,IACxCO,UAAWA,EACXoB,MAAOZ,EACPa,WAAS,EACTC,oBAAqBT,EACrB1E,cAAeA,EACfJ,WAAYA,EACZwF,kBAAmB9B,EACnB+B,kBAAkB,EAClBC,YAAab,EACbc,cAAe,CAACxL,EAAMyL,IAAU,GAAGzL,EAAK2J,cAAc8B,IACtDC,WAAY,CAACC,EAAUF,EAAOG,KAC1B,SAACC,EAAA,EAAoB,CACjBrC,QAASmC,EACTG,SAAO,EACPC,iBAAkB,CACdC,KAAMzC,EACN0C,SAAUR,EACVG,gBAEJM,aAAW,IAGnBC,eAAgB,IAAM,OAjCL,IAmCxB,E,8MCvDL,EAvBuB3C,IACnB,MAAM4C,GAAiB,IAAAjF,SAAO,IACxB,SAAEkF,GAAazI,OAAOC,SAC5B,IACI,MAAM7D,GAAO,QAAsBwJ,EAASA,EAAQ8C,UAAWD,GAC/D,OAAO,SAAC,KAAM,CAAUrM,KAAMA,GAClC,CAAE,MAAOuM,GAaL,OAXAC,QAAQC,IAAIF,GACRA,aAAiBG,QAAUN,EAAe9G,UAC1CqH,EAAA,EAAYC,eAAe,CACvBC,UAAW,OAAF,wBACFN,GAAK,CACRO,QAAS,0DAA0DtD,EAAQvG,SAE/E8J,cAAeC,EAAA,EAAcN,QAEjCN,EAAe9G,SAAU,GAEtB,IACX,G,4ECpBJ,IACI2H,MAAM,EAAArF,EAAA,IAXG,MAOT,OANuC,CACnCG,MAAO,iBACP7H,KAAM,OACNgI,UAAW,sBAGI,K,YCVvB,MAAMgF,GACF,CACI,CAAEC,MAAO,CAAC,EAAG,GAAIrE,IAAK,kCAAmCsE,KAAM,OAC/D,CAAED,MAAO,CAAC,EAAG,GAAIrE,IAAK,kCAAmCsE,KAAM,OAC/D,CAAED,MAAO,CAAC,EAAG,GAAIrE,IAAK,mCAAoCsE,KAAM,UAChE,CAAED,MAAO,CAAC,EAAG,GAAIrE,IAAK,gCAAiCsE,KAAM,QAC7D,CAAED,MAAO,CAAC,EAAG,GAAIrE,IAAK,gCAAiCsE,KAAM,SCkDrE,OA1C8B3M,IAC1B,MAAM4M,EAAmB5M,EAAM6M,cDM1B5K,KAAK6K,IACF,GAAIA,EAAGC,MAAO,CACV,MAAMC,GAdDD,EAcwBD,EAAGC,MAbrCN,GAAeQ,MAAMC,GAAOH,EAAQG,EAAGR,MAAM,IAAMK,GAASG,EAAGR,MAAM,MAchE,GAAIM,EACA,MAAO,CACHxC,GAAIsC,EAAGK,QACP3K,KAAMsK,EAAGM,MACTL,MAAOD,EAAGC,MACV1E,IAAK2E,EAAS3E,IACdsE,KAAMK,EAASL,KAG3B,CAxBQ,IAACI,CA0BO,IAEnBjL,OAAOuL,SACPzF,MAAK,CAAC0F,EAAGC,IAAMD,EAAEP,MAAQQ,EAAER,QCrB1BS,EAAQZ,EAAO7I,QACjB,CAAC0J,EAAMC,KACH,OAAQA,EAAKf,MACT,IAAK,MACD,OAAO,OAAP,wBAAYc,GAAI,CAAEE,QAASF,EAAKE,QAAU,IAC9C,IAAK,SACD,OAAO,OAAP,wBAAYF,GAAI,CAAEG,WAAYH,EAAKG,WAAa,IACpD,IAAK,OACD,OAAO,OAAP,wBAAYH,GAAI,CAAEI,SAAUJ,EAAKI,SAAW,IAChD,QACI,OAAOJ,EACf,GAEJ,CAAEE,QAAS,EAAGC,WAAY,EAAGC,SAAU,IAG3C,IAAIC,EAAa,GAcjB,OAZIN,EAAMG,QAAU,IAChBG,GAAc,2BAA2BN,EAAMG,oBAG/CH,EAAMI,WAAa,IACnBE,GAAc,6BAA6BN,EAAMI,uBAGjDJ,EAAMK,SAAW,IACjBC,GAAc,2BAA2BN,EAAMK,sBAI/C,gBAAKE,UAAW,IC/C8B,YD+CL,aAAcD,EAAWE,OAAM,SACnEpB,EAAO3K,KAAK1C,IACT,gBAAmB0O,IAAI,GAAGC,IAAK3O,EAAK8I,KAA1B9I,EAAKiL,OAG1B,EEpDL,GAAyB,W,wEC8DzB,GA5CI,EAAG2D,MAAKC,kBACR,MAAM,OAAEC,EAAM,MAAEC,IAAU,EAAAC,EAAA,GAAS,KAAUC,2BAEvCnG,EAAM,IAAInF,IAAI,WAVhB,MAAgC,MAE7B,0CAgBP,OAPAmF,EAAI3E,aAAaO,IAAI,UAAWkK,GAChC9F,EAAI3E,aAAaO,IAAI,OAAQ,WAEzBmK,GACA/F,EAAI3E,aAAaO,IAAI,eAAgB,SAIrC,UAAC,MAAK,CACFoK,OAAQA,EACRC,MAAOA,EACPG,OAAQ,IACRC,kBAAkB,2BAA0B,WAE5C,SAACC,GAAA,EAAc,WACX,SAACC,GAAA,EAAW,wCAEhB,SAACC,GAAA,EAAU,CACPC,KAAM,KACNC,MAAM,UACNC,KAAM,GACNC,MAAM,QACNC,QAASZ,EACTP,UC7CY,cD+ChB,gBAAKA,UAAU,2BAA0B,UACrC,mBACIG,IAAK7F,EAAI/E,WACTyK,UAAW,IClDiB,WAAgB,YDmD5CoB,YAAY,IAGZC,SAAU,EACV7M,MAAM,+BAIrB,EEwBL,GA/DyCvC,IACrC,MAAM,KAAE+H,EAAI,OAAEsG,IAAW,EAAAE,EAAA,GAAS,KAAUC,2BAEtCa,EAAc,KAChBC,GAAwB9C,OACxBzE,GAAM,EAeV,OAZA,IAAAnD,YAAU,KACN,GAAIyJ,EAAQ,CACR,MAAM,aAAEkB,EAAY,KAAE/M,EAAI,UAAEgN,GAAcxP,EAAM+I,QAChD,KAAW0G,UAAUC,eAAe3H,KAAK,CACrCoG,IAAKnO,EAAM+I,QAAQG,WACnBqG,eACA/M,OACAmN,MAAOH,GAAa,IAAQI,SAASJ,EAAW,IAAUK,aAElE,IACD,CAACxB,EAAQrO,EAAM+I,UAEb/I,EAAM+I,QAAQ+G,8BAKf,gCACK9P,EAAM+I,QAAQgH,oBACX,oBACItQ,KAAK,SACLsO,UAAW,IAAW,GAAe/N,EAAM+N,WAC3CmB,QAASG,EAAW,gBACN,SAAQ,gBACR,SAAQ,gBACPhB,EAAM,WAErB,iBAAMN,UHvDiB,WGuDK,oCAC5B,iBAAKA,UHxDqE,WGwDpC,WAClC,SAAC,GAAoB,CAAClB,cAAe7M,EAAM+I,QAAQgH,sBACnD,SAACC,EAAA,EAAI,CAAClB,KAAM,IAAkBmB,MAAO,GAAIC,OAAQ,GAAE,0BAI3D,oBACIzQ,KAAK,SACLsO,UAAW,IAAW,GAAe/N,EAAM+N,UHhEE,YGiE7CmB,QAASG,EAAW,gBACN,SAAQ,gBACR,SAAQ,gBACPhB,EAAM,aACV,6EAA4E,2CAGvF,SAAC2B,EAAA,EAAI,CAAClB,KAAM,IAAkBmB,MAAO,GAAIC,OAAQ,GAAE,uBAG3D,SAAC,GAAwB,CACrB/B,IAAKnO,EAAM+I,QAAQG,WACnBkF,aAAcpO,EAAM+I,QAAQgH,wBApC7B,IAuCV,E,oCChFL,IAAgB,KAAO,WAAW,QAAU,WAAW,eAAiB,WAAW,wBAA0B,WAAW,iCAAmC,WAAW,gBAAkB,WAAW,iBAAmB,WAAW,gBAAkB,WAAW,KAAO,WAAW,WAAa,WAAW,YAAc,Y,gDCctT,GAX8B/P,IAC1B,SAACmQ,GAAA,EAAO,CACJC,eAAe,KACfC,QAAQ,KACRtC,UAAU,gDACVuC,UAAU,QAAO,SAEhBtQ,EAAM4C,WCMf,GAfmB,KAEX,iBAAKmL,UAAU,cAAa,WACxB,SAAC,GAAoB,iCACrB,cAAGA,UAAU,aAAY,mXCUrC,MA8KMwC,GAAmBvQ,IAKrB,KAFsB,OAAe+G,GAAA,EAAsBC,uBAEpChH,EAAMwQ,gBAAiB,OAAO,KAErD,MAAMC,EAAOzQ,EAAMwQ,gBAAgB1O,QAC9B4O,IAA8B,QAC3B,SAAkB,QAAhB,EAAAA,EAAIC,oBAAY,eAAEC,iBAAkC,QAAjB,EAAAF,EAAIG,qBAAa,eAAED,YAAW,IAG3E,OAAoB,IAAhBH,EAAKzG,OAAqB,MAG1B,0BACI,iBAAK+D,UAAW,GAAOwC,gBAAe,WAClC,gBAAKxC,UAAW,IAAW,GAAO+C,WAAY,GAAOC,MAAK,2BAC1D,gBAAKhD,UAAW,IAAW,GAAO+C,WAAY,GAAOC,MAAK,8BACzDN,EAAKxO,KAAKyO,IACP,iCACI,gBAAK3C,UAAW,IAAW,GAAOiD,YAAa,GAAOD,MAAK,SACtDL,EAAIC,aAAaC,YAAYvK,iBAElC,gBAAK0H,UAAW,IAAW,GAAOiD,YAAa,GAAOD,MAAK,SACtDL,EAAIG,cAAcD,YAAYvK,yBAMtD,EAGC4K,GAAkBjR,I,gBAGpB,OAFsB,OAAe+G,GAAA,EAAsBC,sBAEpChH,EAAMkR,gBAGzB,iCACyB,QAApB,EAAAlR,EAAMkR,sBAAc,eAAEC,yBACnB,iBAAKpD,UAAU,cAAa,WACxB,SAAC,GAAoB,0BACrB,cAAGA,UAAU,aAAY,SAAE/N,EAAMkR,eAAeC,sBAAsBhS,YAGzD,QAApB,EAAAa,EAAMkR,sBAAc,eAAEE,YACnB,iBAAKrD,UAAU,cAAa,WACxB,SAAC,GAAoB,wBACrB,cAAGA,UAAU,aAAY,SAAE/N,EAAMkR,eAAeE,eAGnC,QAApB,EAAApR,EAAMkR,sBAAc,eAAEG,4BACnB,iBAAKtD,UAAU,cAAa,WACxB,SAAC,GAAoB,8BACrB,cAAGA,UAAU,aAAY,SAAE/N,EAAMkR,eAAeG,+BAGnC,QAApB,EAAArR,EAAMkR,sBAAc,eAAEI,uCACnB,iBAAKvD,UAAU,cAAa,WACxB,SAAC,GAAoB,wCACrB,cAAGA,UAAU,aAAY,SACpB/N,EAAMkR,eAAeI,0CAIb,QAApB,EAAAtR,EAAMkR,sBAAc,eAAEK,yBACnB,iBAAKxD,UAAU,cAAa,WACxB,SAAC,GAAoB,0BACrB,cAAGA,UAAU,aAAY,SAAE/N,EAAMkR,eAAeK,4BAGnC,QAApB,EAAAvR,EAAMkR,sBAAc,eAAEM,uBACnB,iBAAKzD,UAAU,cAAa,WACxB,SAAC,GAAoB,uCACrB,cAAGA,UAAU,aAAY,SAAE/N,EAAMkR,eAAeM,4BAvCZ,IA2CnD,EAGL,OAxPsExR,I,sCAElE,MAAMyR,EAAoBzR,EAAMyR,mBAAqBzR,EAAM0R,yBAErDC,GAAyB,EAAApD,EAAA,GAAS,mBAElCqD,EAA+D,QAAjC,EAAA5R,EAAM4R,mCAA2B,eAAG,GAExE,OACI,oCACmC,QAA3B,EAAA5R,EAAM6R,6BAAqB,eAAE7H,WAAY4H,KACzC,iBAAK7D,UAAU,cAAa,WACxB,iBAAKA,UAAU,+DAA8D,aAC3C,QAA3B,EAAA/N,EAAM6R,6BAAqB,eAAE7H,UAC5B,4BACe,gBACX+D,UAAU,4FAA2F,SAEpG/N,EAAM6R,sBAAsB5P,KAAKgN,I,UAAU,OACxC,yBAGI,SAAC6C,GAAA,GAAe,CACZzJ,KAAgB,QAAX,EAAA4G,EAAM8C,aAAK,eAAE1J,MAAO,GACzB7F,KAAMyM,EAAMzM,KACZwP,UAAU,qBACVC,gBAAgB,qBAChBhC,MAAO,GACPC,OAAQ,MARP,GAAGjB,EAAM/F,cAAqC,QAAvB,EAAW,QAAX,EAAA+F,EAAM8C,aAAK,eAAE7I,kBAAU,QAAI,KAW9D,MAGR0I,IACG,cAAG7D,UAAU,mBAAkB,SAAE6D,OAIH,QAArC,EAAA5R,EAAMkS,uCAA+B,eAAEjQ,KAAKkQ,IACzC,cAAGpE,UAAU,gBAAe,SACvBoE,GAD6BA,WAMC,QAA5C,EAAAnS,EAAMoS,8CAAsC,eAAEpI,UAC7C,iBAAK+D,UAAU,cAAa,WACxB,SAAC,GAAoB,8BACpB/N,EAAMoS,uCAAuCnQ,KAAKoQ,IAC/C,cAAGtE,UAAU,gBAAe,SACvBsE,GAD6BA,SAM5CZ,GAAkD,uBAAX,QAAlB,EAAAzR,EAAMsS,oBAAY,eAAEC,SACvC,iBAAKxE,UAAU,cAAa,UACvB/N,EAAMwS,8BACH,gBAAKzE,UAAU,gBAAe,SAAE/N,EAAMwS,+BAE1C,SAAC,GAAoB,uBACpBf,IAAqB,SAACgB,GAAA,EAAO,CAACC,KAAMjB,IACP,uBAAX,QAAlB,EAAAzR,EAAMsS,oBAAY,eAAEC,QACjB,gBAAKxE,UAAW,IAAW0D,GAAqB,gBAAe,SACxC,QAAlB,EAAAzR,EAAMsS,oBAAY,eAAEnT,YAKrC,SAAC8R,GAAc,CAACC,eAAgBlR,EAAMkR,mBACV,QAA1B,EAAAlR,EAAM2S,4BAAoB,eAAEC,oBAAqB5S,EAAM6S,2BACrD,iBAAK9E,UAAU,cAAa,WACxB,SAAC,GAAoB,qCACM,QAA1B,EAAA/N,EAAM2S,4BAAoB,eAAEC,qBACzB,cAAG7E,UAAU,aAAY,SAAE/N,EAAM2S,qBAAqBC,oBAEzD5S,EAAM6S,0BACH,cAAG9E,UAAU,aAAY,SAAE/N,EAAM6S,8BAI7C,SAACtC,GAAe,CAACC,gBAAqC,QAApB,EAAAxQ,EAAMkR,sBAAc,eAAE4B,uBACrD9S,EAAM+S,4BAA4B/I,SACjC,iBAAK+D,UAAU,cAAa,WACxB,SAAC,GAAoB,yBACrB,gBAAKA,UAAW,GAAOiF,wBAAuB,SACzChT,EAAM+S,4BAA4B9Q,KAAKgR,IACpC,cAAGlF,UAAW,GAAOmF,iCAAgC,SAAGD,YAKtEjT,EAAMmT,wBAAmD,QAA1B,EAAAnT,EAAM2S,4BAAoB,eAAES,wBACzD,iBAAKrF,UAAU,cAAa,WACxB,SAAC,GAAoB,yBACrB,cAAGA,UAAU,aAAY,UAzGbqF,EA2GsB,QAA1B,EAAApT,EAAM2S,4BAAoB,eAAES,oBA3GMD,EA4GlCnT,EAAMmT,sBA3G1BC,GAKG,sBAAsBD,YA2GpBnT,EAAMqT,sBACH,iBAAKtF,UAAU,cAAa,WACxB,SAAC,GAAoB,wBACrB,cAAGA,UAAU,aAAY,SAAE/N,EAAMqT,4BAGZ,QAA1B,EAAArT,EAAMsT,4BAAoB,eAAEtJ,UAC3B,iBAAK+D,UAAU,cAAa,WACxB,SAAC,GAAoB,yCACrB,cAAGA,UAAU,aAAY,SACpB/N,EAAMsT,qBAAqBrR,KAAKsR,GAAYA,EAAQpU,QAAOsB,KAAK,YAI7D,QAAf,EAAAT,EAAMwT,iBAAS,eAAEC,aACd,iBAAK1F,UAAU,cAAa,WACxB,SAAC,GAAoB,4BACrB,cAAGA,UAAU,aAAY,SAAE/N,EAAMwT,UAAUC,gBAGnC,QAAf,EAAAzT,EAAMwT,iBAAS,eAAEE,eACd,iBAAK3F,UAAU,cAAa,WACxB,SAAC,GAAoB,2BACrB,cAAGA,UAAU,aAAY,SAAE/N,EAAMwT,UAAUE,oBAGzB,QAAvB,EAAA1T,EAAM2T,yBAAiB,eAAE3J,UACxB,iBAAK+D,UAAU,cAAa,WACxB,SAAC6F,GAAA,EAAW,CACRC,KAAMlC,EAAuBtD,OAC7BC,MAAOqD,EAAuBrD,MAC9BwF,QAAQ,oBACRzH,QAAQ,iJAER0H,cAAgBtN,IACZ,SAAC,GAAoB,WACjB,mBACIsH,UAAU,sCACVtH,IAAKA,EACLhH,KAAK,SACLyP,QAASyC,EAAuB5J,KAAI,oCAOpD,cAAGgG,UAAU,aAAY,SAAE/N,EAAM2T,kBAAkBlT,KAAK,WAG/DT,EAAMgU,UACH,iBAAKjG,UAAU,cAAa,WACxB,SAAC,GAAoB,sBACrB,eAAGA,UAAU,aAAY,sBAAW/N,EAAMgU,eAGlD,SAAC,GAAU,OAzKQ,IAACZ,EAA8BD,CA2KzD,E,YCxJL,GA7BkFnT,IAE1E,gCACKA,EAAMiU,mBACH,cAAGlG,UAAU,0BAAyB,UAClC,wFAGP/N,EAAMkU,cACH,gBAAKC,SAAS,cAAa,SACtB,WAAUC,SAASpU,EAAMkU,YAAa,CACnCG,aAAc,CAAE3B,MAAM,OAIjC1S,EAAMsU,aACH,4BACI,eAAIvG,UAAU,cAAa,kCAC3B,cAAGA,UAAU,aAAY,+KCvB7C,GAAyE,WAAzE,GAAoG,WAApG,GAAgI,WAAhI,GAAkK,WAAlK,GAAwL,WCCxL,MAAMwG,GAAW,IAAIC,IAA6C,CAC9D,CAAC,MAAO,CAAEC,KAAM,0BAA2BC,MAAO,UAClD,CAAC,MAAO,CAAED,KAAM,OAAQC,MAAO,OAC/B,CAAC,MAAO,CAAED,KAAM,iBAAkBC,MAAO,OACzC,CAAC,MAAO,CAAED,KAAM,aAAcC,MAAO,OACrC,CAAC,MAAO,CAAED,KAAM,aAAcC,MAAO,SACrC,CAAC,KAAM,CAAED,KAAM,iBAAkBC,MAAO,QACxC,CAAC,MAAO,CAAED,KAAM,OAAQC,MAAO,MAC/B,CAAC,MAAO,CAAED,KAAM,QAASC,MAAO,OAChC,CAAC,MAAO,CAAED,KAAM,OAAQC,MAAO,QAC/B,CAAC,MAAO,CAAED,KAAM,SAAUC,MAAO,QACjC,CAAC,MAAO,CAAED,KAAM,WAAYC,MAAO,OACnC,CAAC,MAAO,CAAED,KAAM,YAAaC,MAAO,OACpC,CAAC,MAAO,CAAED,KAAM,MAAOC,MAAO,QAC9B,CAAC,KAAM,CAAED,KAAM,YAAaC,MAAO,OACnC,CAAC,MAAO,CAAED,KAAM,YAAaC,MAAO,OACpC,CAAC,MAAO,CAAED,KAAM,aAAcC,MAAO,OACrC,CAAC,MAAO,CAAED,KAAM,aAAcC,MAAO,OACrC,CAAC,MAAO,CAAED,KAAM,QAASC,MAAO,UAChC,CAAC,MAAO,CAAED,KAAM,eAAgBC,MAAO,OACvC,CAAC,MAAO,CAAED,KAAM,cAAeC,MAAO,OACtC,CAAC,KAAM,CAAED,KAAM,UAAWC,MAAO,QAWxBC,GAA6BC,IACtC,IAAKA,EAAW,MAAO,GAEvB,MAAMC,EAAYjR,MAAMC,KAAK0Q,GAASO,UAAU7H,MAC3C8H,GAASA,EAAKN,KAAKpO,gBAAkBuO,EAAUvO,gBAGpD,OAAOwO,aAAS,EAATA,EAAWH,QAASE,CAAS,EAYlCI,GAAwC,CAC1CC,OAAQ,WACRC,KAAM,aACN,oBAAqB,sBACrB,yBAA0B,wBAC1BC,UAAW,sBACXC,QAAS,iBACTC,KAAM,gBACNC,MAAO,eACP,oBAAqB,gBC8BzB,OArEwFtV,I,UACpF,MAAMuV,EAAqBvV,EAAMwV,eAAeC,MAAMC,KAAWA,EAAKC,0BAChEH,EAAiBxV,EAAMwV,eACxB1T,QAAQ8T,KAAQA,GAAKA,EAAEpT,MAAQoT,EAAEzW,QACjC8C,KAAK2T,GAAO,OAAD,wBAAMA,GAAC,CAAEzW,MAAOyW,EAAEzW,MAAM0B,QAAQ,IAAK,SAC/CgV,EAA+C,QAAzB,EAAA7V,EAAM6V,2BAAmB,eAAG,GAAGC,OACrDC,EDesB,CAACF,I,MAC7B,OACIA,GACA,GAAGA,EAAoBG,yBArBE,CAACzD,IAC9B,IAAKA,EAAM,MAAO,GAElB,MAAMsC,EAAYN,GAAStV,IAAIsT,GAC/B,OAAOsC,aAAS,EAATA,EAAWH,QAASnC,CAAI,EAiBqB0D,CACC,QAA7C,EAAAJ,EAAoBK,iCAAyB,eAAE3D,OAEtD,ECrBqB4D,CAAiBN,GAEjCO,GAAoB,IAAAhM,SAE1B,OACI,iBAAK2D,UFjCe,WEiCY,WAC5B,UAAC,GAAoB,+BACCgI,EAC+B,cAAX,QAArC,EAAAF,aAAmB,EAAnBA,EAAqBQ,wBAAgB,eAAE9D,OACpC,KAA0C,QAArC,EAAAsD,aAAmB,EAAnBA,EAAqBQ,wBAAgB,eAAElX,aAEpD,iBAAK4O,UFvCsC,WEuCP,WAChC,gBAAKA,UAAW,IAAW,mBAAoB,GAAsB,IAAY,uBAGjF,gBAAKA,UAAW,IAAW,mBAAoB,GAAuB,IAAY,SAC7EgI,IAEJR,IACG,gBACIxH,UAAW,IACP,mBACA,GACA,IACH,kBACgBqI,EAAiB,kBAK1C,gBAAKrI,UAAW,KACfyH,EAAevT,KAAI,CAAC2T,EAAG5K,KAAU,OAC9B,UAAC,WAAc,YACX,gBACImJ,UDEM3R,ECFsBoT,EAAEpT,MDGjDA,EAEYwS,GAAcxS,EAAK6D,cAAc2H,QAFhC,YCH6CjM,GACvCgM,UAAW,IAAW,GAAsB,IAAY,SAEvD6H,EAAEpT,QAEP,gBAAKuL,UAAW,IAAW,GAAuB,IAAY,SAAG,GAC7D6H,EAAEzW,SACFwV,GAA0BiB,EAAEb,UAC/BQ,IACG,gBAAKxH,UAAW,IAAW,GAA6B,IAAY,SAC/D6H,EAAED,yBAA2B,GAAGC,EAAED,8BAG3C,gBAAK5H,UAAW,OAfC,GAAG6H,EAAEpT,QAAQoT,EAAEzW,SAASyW,EAAEb,QAAQ/J,EAAM1H,cDIhD,IAACd,CCajB,OAEJ+S,IACG,kBAAMxH,UAAU,eAAevD,GAAI4L,EAAiB,WAChD,iDAA0B,oBAGlC,gBAAKrI,UAAU,cAAa,UACxB,SAAC,GAAU,QAGtB,EC7DL,GAjBoF/N,IAE5E,iCACI,UAAC,GAAoB,mCACK,IACrB,IAAQsW,6BACL,IAAQ1G,SAAS5P,EAAMuW,aAAcvW,EAAM6L,gBAGnD,oKCLZ,MA2EM2K,GACFxW,IAKA,MAAMyW,EAAoBtT,OAAOuT,yBAAsB3U,EAEvD,OACI,UAAC4U,GAAAC,EAAUC,KAAI,CACX1X,MAAOa,EAAMb,MACb4O,UAAW,GAAOyI,4BAA2B,2BACnBxW,EAAM8T,QAAO,WAEvC,SAAC6C,GAAAC,EAAUE,OAAM,CAACC,SAAO,EAAChJ,UAAW,GAAOiJ,gBAAe,UACvD,SAACL,GAAAC,EAAUK,QAAO,WACd,SAAC9G,GAAA,EAAO,CAACE,QAAQ,KAAKD,eAAe,KAAKE,UAAU,QAAO,SACtDtQ,EAAM8T,eAInB,SAAC6C,GAAAC,EAAUM,QAAO,CAACnJ,UAAW,GAAOoJ,iBAAkBC,WAAYX,EAAiB,SAC/EzW,EAAM4C,aAGlB,EAGL,OAtGI5C,I,YAEA,OACI,UAAC2W,GAAAC,EAAUS,KAAI,CACX5X,KAAK,SACL6X,aAAW,EACXvJ,UAAW,IAAW,GAAOsJ,KAAMrX,EAAM+N,WACzCgB,MAAM,OACNwI,SAAO,EACPC,aAAcxX,EAAMwX,aAAY,WAE9BxX,EAAMkU,aAAelU,EAAMsU,cACzB,SAACkC,GAA2B,CAACrX,MAAM,cAAc2U,QAAQ,cAAa,UAClE,SAAC,GAAkB,CACfI,YAAalU,EAAMkU,YACnBI,WAAYtU,EAAMsU,WAClBL,iBAAkBjU,EAAMiU,sBAKpC,SAACuC,GAA2B,CAACrX,MAAM,eAAe2U,QAAQ,eAAc,UACpE,SAAC,GAAY,CACTE,QAAShU,EAAMgU,QACfvC,kBAAmBzR,EAAMyR,kBACzBC,yBAA0B1R,EAAM0R,yBAChCyB,sBAAuBnT,EAAMmT,sBAC7BE,oBAAqBrT,EAAMqT,oBAC3BG,UAAWxT,EAAMwT,UACjBG,kBAAmB3T,EAAM2T,kBACzBd,wBAAyB7S,EAAM6S,wBAC/BF,qBAAsB3S,EAAM2S,qBAC5BW,qBAAsBtT,EAAMsT,qBAC5BP,4BAA6B/S,EAAM+S,4BACnClB,sBAAuB7R,EAAM6R,sBAC7BO,uCACIpS,EAAMoS,uCAEVF,gCAAiClS,EAAMkS,gCACvCN,4BAA6B5R,EAAM4R,4BACnCU,aAActS,EAAMsS,aACpBE,4BAA6BxS,EAAMwS,4BACnCtB,eAAgBlR,EAAMkR,qBAI3BlR,EAAM6V,sBACgC,QAArC,EAAyB,QAAzB,EAAA7V,EAAM6V,2BAAmB,eAAG,GAAGC,cAAM,eAAEE,yBACF,QAArC,EAAyB,QAAzB,EAAAhW,EAAM6V,2BAAmB,eAAG,GAAGC,cAAM,eAAEI,8BACrClW,EAAMwV,kBACNxV,EAAMwV,eAAexL,SACnB,SAACwM,GAA2B,CACxBrX,MAAM,qBACN2U,QAAQ,kBAAiB,UAEzB,SAAC,GAAqB,CAClB0B,eAAgBxV,EAAMwV,eACtBK,oBAAqB7V,EAAM6V,0BAKxC7V,EAAMuW,eACL,SAACC,GAA2B,CAAC1C,QAAQ,eAAe3U,MAAM,eAAc,UACpE,SAAC,GAAmB,CAChBoX,aAAcvW,EAAMuW,aACpB1K,UAAW7L,EAAM6L,gBAKpC,E,4DCnDL,GAzBI,EAAGrJ,OAAMiV,iBACT,MAAM,YAAEC,IAAgB,WAClB,aAAEC,IAAiB,EAAAC,GAAA,GAAwBF,GAE3CG,EAAgC,CAClC,CACIrV,KAAM,SACN6F,KAAK,SAAiByP,GAAA,EAAUC,aAAatI,UAAUpH,KACvD2P,yBAAyB,MAEzBL,EAAa1V,KAAI,CAACsL,EAAGvC,EAAOiN,KAAU,CACtCzV,KAAM+K,EAAE/K,KACR6F,KAAK,SAAmB4P,EAAOjN,GAC/BgN,yBAAyB,OACtB,GACP,CACIxV,OACA6F,IAAKoP,EACLO,yBAAyB,IAIjC,OAAO,SAACE,GAAA,EAAW,CAACzN,MAAOoN,EAAaM,eAAe,cAAcC,OAAK,GAAG,E,YCFjF,GArBsFpY,I,MAClF,MAAM,QAAE+I,GAAY/I,EAEpB,OACI,gBAAK+N,UAAU,oBAAmB,SACL,QAAxB,EAAAhF,aAAO,EAAPA,EAASsP,uBAAe,eAAEpW,KAAKqW,I,UAC5B,OAAU,QAAV,EAAAA,EAAKvG,aAAK,eAAE1J,MACR,SAACkQ,GAAA,EAAY,CAETC,WAAY,CAAEvI,MAAO,GAAIC,OAAQ,QACjCuI,UAAQ,EACRC,eAAgB,CAAEzI,MAAO,GAAIC,OAAQ,QACrC7H,IAAKiQ,EAAKvG,MAAM1J,IAChB4F,IAAKqK,EAAK9V,MALL,GAAG8V,EAAKpP,cAAoC,QAAtB,EAAU,QAAV,EAAAoP,EAAKvG,aAAK,eAAE7I,kBAAU,QAAI,MAOzD,IAAI,KAGnB,E,uECkDL,GA1DsElJ,IAClE,MAAM,OAAEqO,EAAM,MAAEC,EAAK,KAAEvG,IAAS,EAAAwG,EAAA,GAAS,KAAqBoK,kBACxDC,GAAY,WAEZC,EAAa,KACfvK,IACA,KAAoBxG,WAAU,EAAM,EAElCgR,EAAiB,KACnB/Q,IACA,KAAoBD,WAAU,EAAK,EAGvC,OACI,iBAAKiG,UCjC8M,WDiCvK,WACxC,SAAC+D,GAAA,GAAe,CACZ5C,QAAS4J,EACTzQ,IAAKrI,EAAM+Y,SACXvW,KAAMxC,EAAMwC,KACZwW,YAAa,KACbhH,UAAU,2EACVC,gBAAgB,2EAChBgH,SCzCwK,aD2C3KL,IACG,gBAAK7K,UC5CyI,WD4CzG,UACjC,SAACc,GAAA,EAAU,CACPC,KAAM,KACNG,MAAM,aACNF,MAAM,QACNC,KAAM,GACNE,QAAS4J,OAIrB,UAACI,GAAA,GAAK,CAAC7K,OAAQA,EAAQC,MAAOuK,EAAYnK,kBCtD4E,WDsDzC,WACzE,gBAAKX,UAAW,ICvDC,WDuDiC,iBAAgB,UAC9D,SAACc,GAAA,EAAU,CACPC,KAAM,KACNG,MAAM,QACNF,MAAM,QACNC,KAAM,GACNE,QAAS2J,OAGjB,oBAAS9K,UAAW,IChEoD,WDgElB,YAAa,gBAAe,UAC9E,SAAC+D,GAAA,GAAe,CACZzJ,IAAKrI,EAAM+Y,SACXE,SCnEmF,WDoEnFzW,KAAMxC,EAAMwC,KACZwP,UAAU,oFAK7B,E,8FEtDL,MAmDMmH,GAAuE,EAAGC,aAC5E,MAAMC,EAAiB,CAACC,EAA0BC,IAAuB,KACrE,KAAmBC,yBAAyBC,eAAeH,EAAkBC,EAAW,EAGtFG,EAAkB,CAACJ,EAA0BC,IAAuB,KACtE,KAAmBC,yBAAyBG,kBAAkBL,EAAkBC,EAAW,EAG/F,OACI,SAACK,GAAA,EAAyB,CACtBC,UAAWT,EAAOU,UAClBC,YACI,SAACC,GAAA,EAAmB,CAChBxP,GAAI4O,EAAOa,WAAW3W,WACtBd,KAAM4W,EAAO5W,KACb6F,IAAK+Q,EAAOc,YACZC,OAAQf,EAAOgB,UACfC,YAAajB,EAAOkB,gBACpBvB,SAAUK,EAAOL,SACjBwB,MAAOnB,EAAOoB,cACdC,gBAAiBrB,EAAOsB,WACxB9P,kBAAkB,oBAClB+P,WAAYtB,EAAeD,EAAOa,WAAYb,EAAO5W,MACrDoY,YAAalB,EAAgBN,EAAOa,WAAYb,EAAO5W,QAG/DqY,aACI,SAACC,GAAA,EAAoB,CACjBtQ,GAAI4O,EAAOa,WAAW3W,WACtBd,KAAM4W,EAAO5W,KACb6F,IAAK+Q,EAAOc,YACZnB,SAAUK,EAAOL,SACjB0B,gBAAiBrB,EAAOsB,WACxB9P,kBAAkB,oBAClB+P,WAAYtB,EAAeD,EAAOa,WAAYb,EAAO5W,MACrDoY,YAAalB,EAAgBN,EAAOa,WAAYb,EAAO5W,SAItE,EAGL,OA9FwCxC,IACpC,MAAM,QAAEmJ,EAAO,OAAEC,EAAM,UAAEC,IAAc,EAAAC,EAAA,GAAmByR,GAAA,EAAWC,oBAAqB,CACtFvR,qBAAqB,IAGnBC,GAAwB,OAAeC,EAAA,EAAeD,uBAEtDuR,GAAa,IAAArR,cAAY,KACvB5J,EAAMkb,mBACN/R,EAAQ,CAACnJ,EAAMkb,mBAAoBxR,EAAuB,GAC9D,GACD,CAACP,EAASO,EAAuB1J,EAAMkb,qBAEpC,cAAE1V,EAAa,kBAAEF,EAAiB,WAAEF,IAAe,EAAA+V,GAAA,MAElDC,EAAWC,IAAU,YAE5B,IAAAzW,YAAU,KACFyW,GACAJ,GACJ,GACD,CAACI,EAAQJ,IAEZ,MAAM9Q,GAAW,IAAAC,SAEjB,OAAKf,IAAcD,aAAM,EAANA,EAAQY,SAKvB,SAACK,EAAA,EAAS,mBACWF,EACjBG,GAAG,QACH7D,IAAK2U,EACL7Q,YAAalB,IAAa,SAAC,IAAW,CAACmB,GAAIL,EAAQ,6BACnDd,UAAWA,EACXoB,MAAOrB,EACPsB,WAAS,EACTlF,cAAeA,EACfmF,oBAAqBrF,EACrBF,WAAYA,EACZ0F,YAAY,mBACZF,kBAAkB,kBAClBC,kBAAkB,EAClBE,cAAgBxL,GAASA,EAAK0a,WAAW3W,WACzC2H,WAAamO,IAAW,SAACD,GAAU,CAACC,OAAQA,IAC5C1N,eAAgB,KAAM,SAAC,KAAoB,MApBxC,IAsBV,ECdL,MAqDM4P,GAA6B,KAE3B,iBAAKvN,UC7GyB,WD6GY,WACtC,gBAAKA,UC9G+C,WD8GjB,UAC/B,SAACiC,EAAA,EAAI,CAAClB,KAAM,IAAcmB,MAAO,GAAIC,OAAQ,GAAIqL,MAAM,WAE3D,4HAYNC,GAAoExb,I,cACtE,MAAM+I,GAAU,IAAA0S,UAAQ,KAAM,QAAkBzb,EAAM+I,UAAU,CAAC/I,EAAM+I,UACjEW,GAAwB,OAAeC,EAAA,EAAeD,wBAEtD,iBAAEgS,IAAqB,EAAAC,EAAA,KAEvBpZ,EACFwG,EAAQwG,cAAgBxG,EAAQvG,KAAKwH,OAASjB,EAAQwG,aAAavF,OAAS,GACtE,GAAGjB,EAAQvG,UAAUuG,EAAQwG,sBAC7B,GAAGxG,EAAQvG,cAEf0R,EAAcnL,EAAQwG,aACtB,OAAOxG,EAAQvG,aAAauG,EAAQwG,iGACpC,OAAOxG,EAAQvG,0FAEf,eAAEoZ,EAAc,SAAEC,EAAQ,oBAAEC,EAAmB,iBAAEC,IAAqB,QACxE/b,EAAM+I,QACN,CACIiT,UAAU,EACV1Q,iBAAkB,QAIlBvK,KAAMkb,IAAsB,EAAAC,EAAA,KAE9BC,KAAgC,QAAhB,EAAApT,EAAQqT,gBAAQ,eAAEpS,SAExC,IAAApF,YAAU,K,QACF5E,EAAM+I,SACN,KAAiBsT,SACbrc,EAAM+I,QAAQG,WACa,QAA3B,EAAsB,QAAtB,EAAAlJ,EAAM+I,QAAQqT,gBAAQ,eAAG,UAAE,eAAE5R,GAC7Bd,EAER,GACD,CAACA,EAAuB1J,EAAM+I,UAEjC,MAAMuT,EACFvT,EAAQwT,gBAAkB,IAAQ3M,SAAS7G,EAAQwT,eAAgBb,IAEhEc,EAAsBC,IAA2B,IAAA7W,YACjC,QAAlB,EAAAmD,aAAO,EAAPA,EAASE,iBAAS,eAAEC,aAEnBwT,GAAwB,IAAA9S,cAAa+S,IACZ,IAAvBA,GACAF,GAAwB,EAC5B,GACD,IAEGjN,GAAYoM,aAAc,EAAdA,EAAgBpM,YAAazG,EAAQyG,UACjDoN,GAAqBhB,aAAc,EAAdA,EAAgBgB,qBAAsB7T,EAAQ6T,mBAEnEC,GAAa,WACb,QAAEC,EAAO,aAAE7Z,GE5KwB,EAAC8F,EAAuB8T,KACjE,IAAI5Z,GAAe,SAAiB8F,EAAQV,KAK5C,OAJIwU,IACA5Z,EAAeA,EAAapC,SAAQ,SAAmB,MAAc,KAGlE,CACHoC,eACA6Z,QAAS/T,EAAQgQ,UACX,SACIhQ,EAAQgQ,SACR,2EACAjB,GAAA,EAAUC,aAAatI,UAAUqN,cAErC/a,EACT,EF6JiCgb,CAA8BhU,EAAS8T,GAEzE,OACI,iCACI,SAACG,EAAA,EAAc,CACXlY,SAAU,CACNvC,QACAzB,KAAM,CACFG,UAAWgC,GAEfjC,KAAM,CACFkT,cACA,WAAY4I,IAGpB/X,yBAAyB,iBAE7B,SAAC,EAAa,iBAAK/E,EAAM+I,QAAO,CAAE8C,UAAW6P,MAC7C,SAAC,GAAyB,CAAClZ,KAAMuG,EAAQvG,KAAMiV,WAAY1O,EAAQV,OACnE,iBAAK0F,UAAU,OAAM,WACjB,gBAAKA,UAAU,yBAAwB,UACnC,oBAASA,UAAU,WAAU,UACzB,iBAAKA,UAAU,mBAAkB,WAC7B,iBAAKA,UAAU,iBAAgB,WAC3B,gBAAKA,UAAU,iBAAgB,UAC3B,SAAC,GAAY,CAACvL,KAAMuG,EAAQvG,KAAMuW,SAAUhQ,EAAQgQ,cAExD,SAAC,GAAoB,CAAChQ,QAASA,KAC/B,gBAAKgF,UAAU,wBAAuB,SACjChF,EAAQE,YACL,gBAAK8E,UAAU,wBAAuB,UAClC,SAACkP,EAAA,EAAe,CACZxd,KAAK,QACLwJ,UAAWF,EAAQE,UACnB4C,UAAW6P,YAM/B,iBAAK3N,UAAU,mBAAkB,WAC7B,gBAAKA,UAAU,gBAAe,UAC1B,iBAAKA,UAAU,aAAY,WACvB,eAAIA,UAAU,mBAAkB,SAAEhF,EAAQvG,QAC1C,iBAAKuL,UAAU,uBAAsB,UAChChF,EAAQmU,aACL,gBACInP,UAAU,kBACVG,IAAI,gCACJD,IAAI,gBACJgC,MAAM,KACNC,OAAO,QAGf,kBAAMnC,UAAU,iBAAgB,UAC3BhF,EAAQwG,aACRxG,EAAQwG,cAAgB,QAE7B,0BACKxG,EAAQoU,wBACL,IAAIpU,EAAQoU,4BAGnBpU,EAAQqU,uBACL,yBACKrU,EAAQqU,uBACL,QACI,IAAQxN,SACJ7G,EAAQqU,qBACR1B,GAEJ3S,EAAQsU,sBAKU,QAA/B,EAAAtU,EAAQuU,+BAAuB,eAAEtT,UAChC,yBACKjB,EAAQuU,wBAAwB7c,KAAK,UAI3CsI,EAAQkL,mBAAoB,yCAE5BqI,GAAuBA,EAAsB,IAC5C,+BAEK,IAAQhG,6BACLgG,EACA,YACD,IAAG,WAKI,QAAjB,EAAAvT,EAAQE,iBAAS,eAAEsU,cAChB,gBAAKxP,UAAU,gBAAe,UAC1B,SAACyP,EAAA,EAAiB,CACdC,KAAuB,QAAjB,EAAA1U,EAAQE,iBAAS,eAAEsU,WACzBG,kBAAgB,UAKhC,iBAAK3P,UAAU,eAAc,UACxBoO,IACG,gBAAKpO,UAAU,kBAAiB,UAC5B,SAAC4P,EAAA,EAAe,CACZC,kBAAmBhC,aAAc,EAAdA,EAAgBpR,GACnC4R,SAAUrT,EAAQqT,SAClBN,oBAAqBA,OAKjC,SAAC+B,EAAA,EAAY,CACTC,WAAYtO,EACZuO,cAAenB,EACf/Q,UAAW6P,EACXsC,OAAO,QACHjV,EAAQE,UACR2S,QAAkB7Z,GAEtBgM,UAAW,IC7S6E,YD8SxFkQ,YAAY,MACZC,MAAM,OACNC,sBAAoB,EACpBtC,SAAUA,QAGlB,iBAAK9N,UAAU,kBAAiB,WAC5B,SAACqQ,EAAA,EAAe,CACZvC,SAAUA,EACVwC,YAAatC,EACbuC,YAAavV,EAAQvG,OAGxBuG,EAAQE,YACL,gBAAK8E,UAAU,0BAAyB,UACpC,SAACkP,EAAA,EAAe,CACZxd,KAAK,UACLwJ,UAAWF,EAAQE,UACnB4C,UAAW6P,cAOlC1b,EAAM+I,QAAQwV,QAAQC,oBACnB,gBAAKzQ,UAAU,mDAAkD,UAC7D,SAACuN,GAA0B,OAGnC,gBACIvN,UAAU,uCACV0Q,MAAO,CAAEC,cAAe,IAAI,UAE5B,SAAC,GAA+B,CAC5B3Q,UCjVkL,WDkVlLhF,QAASA,OAGjB,gBAAKgF,UAAU,uCAAsC,UACjD,SAAC,GAAuB,CACpBA,UCvVqI,WDwVrIyJ,aAAa,eACb3B,oBAAqB9M,aAAO,EAAPA,EAAS8M,oBAC9BL,eAAgBzM,aAAO,EAAPA,EAASyM,eACzB/D,kBAAmB1I,aAAO,EAAPA,EAAS0I,kBAC5BC,yBAA0B3I,aAAO,EAAPA,EAAS2I,yBACnCyB,sBAAuBpK,aAAO,EAAPA,EAASoK,sBAChCE,oBAAqBtK,aAAO,EAAPA,EAASsK,oBAC9BG,UAAWzK,aAAO,EAAPA,EAASyK,UACpBlB,aAAcvJ,aAAO,EAAPA,EAASuJ,aACvBqB,kBAAmB5K,aAAO,EAAPA,EAAS4K,kBAC5BK,QAASjL,aAAO,EAAPA,EAASiL,QAClBE,YAAanL,aAAO,EAAPA,EAASmL,YACtBI,WAAYvL,aAAO,EAAPA,EAASuL,WAErBiC,aAAcxN,aAAO,EAAPA,EAAS4V,oBACvB9L,wBAAyB9J,aAAO,EAAPA,EAAS8J,wBAClCF,qBAAsB5J,aAAO,EAAPA,EAAS4J,qBAC/BW,qBAAsBvK,aAAO,EAAPA,EAASuK,qBAC/BP,6BACIhK,aAAO,EAAPA,EAASgK,8BAA+B,GAE5ClB,sBAAuB9I,aAAO,EAAPA,EAAS8I,sBAChCO,uCACIrJ,aAAO,EAAPA,EAASqJ,uCAEbF,gCACInJ,aAAO,EAAPA,EAASmJ,gCAEbN,4BACI7I,aAAO,EAAPA,EAAS6I,4BAEb/F,UAAW6P,EACXzH,iBAAkBlL,aAAO,EAAPA,EAASkL,iBAC3BzB,6BACIzJ,aAAO,EAAPA,EAASyJ,+BACTzJ,aAAO,EAAPA,EAAS6V,sBAEb1N,eAAgBnI,aAAO,EAAPA,EAASmI,8BAOjD,gBAAKnD,UAAU,YAAW,UACtB,iBAAKA,UAAU,uBAAsB,WACjC,gBAAKA,UAAU,YAAW,SACrByO,GAAwBP,GACrB,SAAC4C,EAAA,EAAiB,CACdvU,GAAG,QACHwU,iBACI7C,EAAkB8C,iCAEtBC,gBAAgB,EAChBpU,kBACIqR,EAAkBgD,qCAEtBvU,WAAS,EACTwU,UAAQ,EACRrU,kBAAkB,EAClBsU,aAAa,EACbC,kBAAkB,KAGtB,SAAC,EAAwB,CACrBrW,QAASA,EACTgB,iBAAkB2S,MAK7BT,IACG,SAACoD,EAAA,EAAc,CACX5U,MAAOwR,EAAkBqD,kBACzBrU,WAAY,CACRsU,EACAC,EACAC,KAEA,IAAI,IAAAC,qBAAoBH,GAAiB,CACrC,MAAMI,GACF,IAAAC,gCAA+BL,GAEnC,OACI,gBAAKxR,UAAW0R,EAAsB,UAClC,SAACZ,EAAA,EAAiB,eAACvU,GAAG,SAAYqV,KAG9C,MAIZ,gBAAK5R,UAAU,YAAW,UACtB,SAAC,GAA8B,CAC3BmN,kBAAmBnS,EAAQG,yBAOtD,EAGL,OA1Y+B,KAC3B,MACI2W,WAAW,UAAEC,KACb,EAAAC,EAAA,MAEE,QACF5W,EACAC,OAAQL,EAAO,MACf+C,EAAK,OACLkU,IACA,EAAA1W,EAAA,GAAmBC,EAAA,EAAY0W,gBAE7BvW,GAAwB,OAAeC,EAAA,EAAeD,wBAE5D,IAAA9E,YAAU,KACFkb,GACA3W,EAAQ2W,EAAWpW,EACvB,GACD,CAACP,EAAS2W,EAAWpW,IAExB,MAAM,mBAAEwW,IAAuB,EAAAC,EAAA,MAE/B,IAAAvb,YAAU,KACNsb,EAAmB,OAAO,GAC3B,CAACA,IAEJ,MAAOE,EAAgBC,IAAqB,IAAAza,WAAS,GAcrD,OAZA,IAAAhB,YAAU,KACN,GAAIkb,EAAW,CACX,MAAMQ,GAAU,QAAyBnd,OAAOC,SAAST,KAAMmd,IAC/D,QAAWQ,EAASnd,OAAOC,SAAST,MACpC4d,EAAA,EAAaC,MAAM,CAAEV,eACrB,QAAsBQ,GACtBD,GAAkB,EACtB,IACD,CAACP,KAEJ,EAAAW,EAAA,IAAc,IAAWC,OAAQ5U,GAE5BgU,EAGU,YAAXE,GAAyBjX,GAMzB,8BAAGA,GAAWqX,IAAkB,SAAC5E,GAAc,CAACzS,QAASA,OALlD,SAAC4X,GAAA,EAAY,CAAClhB,KAAK,YAHnB,IASV,C,iFGzCL,IA1CuB,EAAGgL,QAAOmW,SAAQC,eAAc5V,iBACnD,MAAM6V,GAAYrW,aAAK,EAALA,EAAO3I,QAAQ8T,KAAQA,KAAOA,EAAEmL,YAAYC,aAAa,GAE3E,OACI,8BACKF,EAAU7e,KAAI,CAACgf,EAAiBjW,KAC7B,SAAC,IAAkB,CACfkW,cAAeD,EAAgBF,YAAYC,SAC3CxhB,QAAS,CACL2hB,mBAAmB,GACtB,SAGA,CAACC,EAAeC,KACb,MAAM5B,EAAyB,KAC3B,QACIwB,EAAgBK,eAAiBV,GAErCC,GAGJ,OACI,8BACM5V,GACEA,EACIoW,EACAJ,EACAxB,KAEJ,gBAAK1R,UAAW0R,EAAsB,UAClC,SAAC2B,EAAa,iBAAKC,OAIlC,GAvBA,IAAIJ,EAAgBF,YAAYQ,aAAavW,SA4BjE,C,iFC3DE,MAAM0U,EAAuBjd,IAA0D,MAC1F,OAA4D,KAAxC,QAApB,EAAAA,aAAO,EAAPA,EAAS+e,mBAAW,eAAE1d,SAAS,yBAAiC,C","sources":["webpack:///../../node_modules/react-schemaorg/dist/src/index.js","webpack:///../../node_modules/react-schemaorg/dist/src/json-ld.js","webpack:///./src/microApps/common/components/atoms/PageHead/PageHead.tsx","webpack:///./src/microApps/common/components/molecules/PageProperties/PageProperties.utils.ts","webpack:///./src/microApps/common/components/molecules/PageProperties/PageProperties.hooks.ts","webpack:///./src/microApps/common/components/molecules/PageProperties/PageProperties.tsx","webpack:///./src/microApps/common/hooks/useBuyableRecipesBreakpoints.ts","webpack:///./src/microApps/common/hooks/useDocumentHeadIsPreparedForReactHelmet.ts","webpack:///./src/microApps/common/hooks/useSavedInRef.ts","webpack:///./src/microApps/common/selectors/featureFlagsSelectors.ts","webpack:///./src/microApps/common/tracking/ga4/products/ga4ProductsEvents.ts","webpack:///./src/microApps/common/utils/metaUtils.ts","webpack:///./src/microApps/common/components/organisms/SamePromotionProductList.tsx","webpack:///./src/microApps/ecommerce/components/JsonLd/ProductJsonLd.tsx","webpack:///./src/microApps/common/tracking/ga4/sustainability/ga4SustainabilityEvents.ts","webpack:///./src/microApps/ecommerce/components/SustainabilityLights/SustainabilityLights.utils.ts","webpack:///./src/microApps/ecommerce/components/SustainabilityLights/SustainabilityLights.tsx","webpack:///./src/microApps/ecommerce/components/SustainabilityLights/SustainabilityLights.module.less","webpack:///./src/microApps/ecommerce/components/SustainabilityDeclarationButton/SustainabilityDeclarationButton.module.scss","webpack:///./src/microApps/ecommerce/components/SustainabilityDeclarationButton/SustainabilityFlyinModal.tsx","webpack:///./src/microApps/ecommerce/components/SustainabilityDeclarationButton/SustainabilityFlyinModal.module.less","webpack:///./src/microApps/ecommerce/components/SustainabilityDeclarationButton/SustainabilityDeclarationButton.tsx","webpack:///./src/microApps/ecommerce/components/pages/productDetailsPage/ProductDetailsAccordion/ProductDetailsAccordion.module.scss","webpack:///./src/microApps/ecommerce/components/pages/productDetailsPage/ProductDetailsAccordion/ProductDetailHeading.tsx","webpack:///./src/microApps/ecommerce/components/pages/productDetailsPage/ProductDetailsAccordion/Disclaimer.tsx","webpack:///./src/microApps/ecommerce/components/pages/productDetailsPage/ProductDetailsAccordion/ProductFacts.tsx","webpack:///./src/microApps/ecommerce/components/pages/productDetailsPage/ProductDetailsAccordion/ProductInformation.tsx","webpack:///./src/microApps/ecommerce/components/pages/productDetailsPage/ProductDetailsAccordion/ProductNutritionTable/ProductNutritionTable.module.scss","webpack:///./src/microApps/ecommerce/components/pages/productDetailsPage/ProductDetailsAccordion/ProductNutritionTable/ProductNutritionTable.utils.ts","webpack:///./src/microApps/ecommerce/components/pages/productDetailsPage/ProductDetailsAccordion/ProductNutritionTable/ProductNutritionTable.tsx","webpack:///./src/microApps/ecommerce/components/pages/productDetailsPage/ProductDetailsAccordion/ProductPriceHistory.tsx","webpack:///./src/microApps/ecommerce/components/pages/productDetailsPage/ProductDetailsAccordion/ProductDetailsAccordion.tsx","webpack:///./src/microApps/ecommerce/components/pages/productDetailsPage/ProductDetailsBreadcrumbs.tsx","webpack:///./src/microApps/ecommerce/components/pages/productDetailsPage/ProductDetailsLabels.tsx","webpack:///./src/microApps/ecommerce/components/pages/productDetailsPage/ProductImage/ProductImage.tsx","webpack:///./src/microApps/ecommerce/components/pages/productDetailsPage/ProductImage/ProductImage.module.less","webpack:///./src/microApps/ecommerce/components/pages/productDetailsPage/RecipeRecommendationsByProduct/RecipeRecommendationsByProduct.tsx","webpack:///./src/microApps/ecommerce/components/pages/productDetailsPage/ProductDetailsPage.tsx","webpack:///./src/microApps/ecommerce/components/pages/productDetailsPage/ProductDetailsPage.module.less","webpack:///./src/microApps/ecommerce/components/pages/productDetailsPage/ProductDetailsPage.utils.ts","webpack:///./src/microApps/episerver/components/base/EpiContentArea.tsx","webpack:///./src/microApps/episerver/components/blocks/EpiDynamicYieldBlock/EpiDynamicYieldBlock.utils.ts"],"sourcesContent":["\"use strict\";\n/**\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.jsonLdScriptProps = exports.JsonLd = exports.helmetJsonLdProp = void 0;\nvar json_ld_1 = require(\"./json-ld\");\nObject.defineProperty(exports, \"helmetJsonLdProp\", { enumerable: true, get: function () { return json_ld_1.helmetJsonLdProp; } });\nObject.defineProperty(exports, \"JsonLd\", { enumerable: true, get: function () { return json_ld_1.JsonLd; } });\nObject.defineProperty(exports, \"jsonLdScriptProps\", { enumerable: true, get: function () { return json_ld_1.jsonLdScriptProps; } });\n","\"use strict\";\n/**\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.helmetJsonLdProp = exports.jsonLdScriptProps = exports.JsonLd = void 0;\nconst React = require(\"react\");\nfunction JsonLd(props) {\n return React.createElement(\"script\", Object.assign({}, jsonLdScriptProps(props.item, props)));\n}\nexports.JsonLd = JsonLd;\nfunction jsonLdScriptProps(item, options = {}) {\n return {\n type: \"application/ld+json\",\n dangerouslySetInnerHTML: {\n __html: JSON.stringify(item, safeJsonLdReplacer, options.space),\n },\n };\n}\nexports.jsonLdScriptProps = jsonLdScriptProps;\nfunction helmetJsonLdProp(item, options = {}) {\n return {\n type: \"application/ld+json\",\n innerHTML: JSON.stringify(item, safeJsonLdReplacer, options.space),\n };\n}\nexports.helmetJsonLdProp = helmetJsonLdProp;\nconst ESCAPE_ENTITIES = Object.freeze({\n \"&\": \"&\",\n \"<\": \"<\",\n \">\": \">\",\n '\"': \""\",\n \"'\": \"'\",\n});\nconst ESCAPE_REGEX = new RegExp(`[${Object.keys(ESCAPE_ENTITIES).join(\"\")}]`, \"g\");\nconst ESCAPE_REPLACER = (t) => ESCAPE_ENTITIES[t];\n/**\n * A replacer for JSON.stringify to strip JSON-LD of illegal HTML entities\n * per https://www.w3.org/TR/json-ld11/#restrictions-for-contents-of-json-ld-script-elements\n */\nconst safeJsonLdReplacer = (() => {\n // Replace per https://www.w3.org/TR/json-ld11/#restrictions-for-contents-of-json-ld-script-elements\n // Solution from https://stackoverflow.com/a/5499821/864313\n return (_, value) => {\n switch (typeof value) {\n case \"object\":\n // Omit null values.\n if (value === null) {\n return undefined;\n }\n return value; // JSON.stringify will recursively call replacer.\n case \"number\":\n case \"boolean\":\n case \"bigint\":\n return value; // These values are not risky.\n case \"string\":\n return value.replace(ESCAPE_REGEX, ESCAPE_REPLACER);\n default: {\n // We shouldn't expect other types.\n isNever(value);\n // JSON.stringify will remove this element.\n return undefined;\n }\n }\n };\n})();\n// Utility: Assert never\nfunction isNever(_) { }\n","import type { FC } from 'react';\nimport Helmet from 'react-helmet';\n\nimport { isProductionEnvironment } from '../../../../../utility/environments';\nimport useDocumentHeadIsPreparedForReactHelmet from '../../../hooks/useDocumentHeadIsPreparedForReactHelmet';\nimport { getCanonical, getNextPage, getPrevPage } from '../../../utils/metaUtils';\nimport type { PageHeadData, PageHeadPagination } from './PageHead.types';\n\ninterface PageHeadProps {\n data: PageHeadData;\n pagination?: PageHeadPagination;\n}\n\nconst PageHead: FC<React.PropsWithChildren<PageHeadProps>> = (props) => {\n const link = { ...props.data.link };\n const meta = { ...props.data.meta };\n\n if (link && link.canonical) {\n link.canonical = getCanonical({\n path: link.canonical,\n page: props.pagination?.currentPage,\n });\n }\n\n let hasPrevPage = false;\n let hasNextPage = false;\n\n if (props.pagination) {\n hasPrevPage = props.pagination.currentPage !== 1;\n if (props.pagination.totalItems) {\n hasNextPage =\n props.pagination.pageSize * props.pagination.currentPage <=\n props.pagination.totalItems;\n }\n }\n\n if (hasPrevPage && link && props.pagination) {\n link.prevPage = getPrevPage(props.pagination.currentPage);\n }\n\n if (hasNextPage && link && props.pagination) {\n link.nextPage = getNextPage(props.pagination.currentPage);\n }\n\n const linkData =\n link &&\n Object.entries(link).filter(\n (item) => item[1] !== '' && item[1] !== undefined && item[1] !== null,\n );\n\n const metaData =\n meta &&\n Object.entries(meta).filter(\n (item) => item[1] !== '' && item[1] !== undefined && item[1] !== null,\n );\n\n let options: Parameters<typeof useDocumentHeadIsPreparedForReactHelmet>[0] = {\n link: linkData?.map(([key]) => ({ property: 'rel', value: key })),\n };\n\n if (metaData) {\n options = {\n ...options,\n meta: metaData.map(([key]) => ({ property: 'name', value: key })),\n };\n }\n\n const isDocumentHeadReadyForReactHelmet = useDocumentHeadIsPreparedForReactHelmet(options);\n\n return (\n // eslint-disable-next-line react/jsx-no-useless-fragment\n <>\n {isDocumentHeadReadyForReactHelmet && (\n <Helmet>\n {props.data.title && (\n <title>\n {props.data.title +\n (!isProductionEnvironment ? ' - NOT FOR COMMERCIAL USE' : '')}\n </title>\n )}\n {metaData?.map(([property, value]) => (\n <meta key={property} name={property} content={value} />\n ))}\n\n {linkData?.map(([property, value]) => (\n <link key={property} rel={property} href={value} />\n ))}\n\n {props.children}\n </Helmet>\n )}\n </>\n );\n};\n\nexport default PageHead;\n","const defaultQueryKeys = ['page'];\n\n/**\n * Filter current query string to only contain certain keys that are relevant for GA's virtual page view\n * @param queryString The complete query string of a location\n * @param keys List of allowed query string keys\n */\nexport const getFilteredQueryStringForVirtualPageView = (\n queryString: string,\n keys: string[] = [],\n) => {\n const triggerKeys = [...defaultQueryKeys, ...keys];\n\n const searchParams = new URLSearchParams(queryString);\n\n const filteredSearchParams = Array.from(searchParams.entries())\n .filter(([key]) => triggerKeys.includes(key))\n .reduce((acc, [key, value]) => {\n acc.set(key, value.toString());\n return acc;\n }, new URLSearchParams());\n\n return filteredSearchParams.toString();\n};\n","import { useEffect } from 'react';\nimport { useLocation } from 'react-router-dom';\n\nimport { useSavedInRef } from '../../../hooks/useSavedInRef';\nimport { useAppDispatch } from '../../../hooks/useThunkDispatch';\nimport { currentPageActions } from '../../../store/slices/currentPage/currentPageSlice';\nimport { getFilteredQueryStringForVirtualPageView } from './PageProperties.utils';\n\ninterface GaVirtualPageParams {\n pageTitle: string;\n canonicalUrl?: string;\n pageTypeName?: string;\n /**\n * Used to specify what key must have been changed in URL's query string to trigger Virtual Page View\n * By defualt, pagination's \"page\" is always a trigger, rest of the triggers are set on page-to-page basis\n */\n queryStringTriggers?: string[];\n}\n\nexport const useGaVirtualPageView = (options?: GaVirtualPageParams) => {\n const { search } = useLocation();\n const dispatch = useAppDispatch();\n\n const canonicalUrl =\n options &&\n options.canonicalUrl &&\n new URL(options.canonicalUrl, window.location.origin).toString();\n\n // used only in dependency array to trigger effect\n const triggerString = getFilteredQueryStringForVirtualPageView(\n search,\n (options && options.queryStringTriggers) || [],\n );\n\n const enable = !!options;\n\n const sendEvent = useSavedInRef(() => {\n if (canonicalUrl) {\n dispatch(\n currentPageActions.setPageGaData({\n canonicalUrl,\n gaPageTypeName: options && options.pageTypeName,\n title: options && options.pageTitle,\n queryString: window.location.search,\n }),\n );\n }\n });\n\n useEffect(() => {\n if (enable && canonicalUrl) {\n sendEvent.current();\n }\n }, [dispatch, enable, canonicalUrl, triggerString, sendEvent]);\n\n return {\n sendEvent,\n };\n};\n","import { type FC, useEffect } from 'react';\n\nimport { useAppDispatch } from '../../../hooks/useThunkDispatch';\nimport { currentPageActions } from '../../../store/slices/currentPage/currentPageSlice';\nimport type { PageHeadData, PageHeadPagination } from '../../atoms/PageHead';\nimport PageHead from '../../atoms/PageHead';\nimport { useGaVirtualPageView } from './PageProperties.hooks';\n\ninterface PagePropertiesProps {\n headData: PageHeadData;\n headPagination?: PageHeadPagination;\n pageTypeNameForAnalytics?: string;\n\n /** @see useGaVirtualPageView comments */\n virtualPageViewQueryStringTriggers?: string[];\n}\n\nconst PageProperties: FC<React.PropsWithChildren<PagePropertiesProps>> = (props) => {\n useGaVirtualPageView({\n canonicalUrl: props.headData.link?.canonical,\n pageTitle: props.headData.title,\n pageTypeName: props.pageTypeNameForAnalytics,\n queryStringTriggers: props.virtualPageViewQueryStringTriggers,\n });\n\n const dispatch = useAppDispatch();\n useEffect(() => {\n dispatch(currentPageActions.setTitle(props.headData.title));\n }, [dispatch, props.headData.title]);\n\n return <PageHead data={props.headData} pagination={props.headPagination} />;\n};\n\nexport default PageProperties;\n","import React from 'react';\nimport type { SwiperOptions } from 'swiper/types';\n\nimport { CoopSwiperBreakpoints } from '../../../utility/coopSwiperBreakpoints';\nimport { useBreakpointsSidebar } from '../../ecommerce/hooks/useBreakpoints';\nimport { useSwiperOverflowClasses } from './useSwiperOverflowClasses';\n\nconst useBuyableRecipesBreakpoints = () => {\n const { breakpoints, cellsInRow } = useBreakpointsSidebar(\n CoopSwiperBreakpoints.AREA_NEW_RECIPE_LIST,\n );\n\n const { mainSwiperClasses, spaceBetween } = useSwiperOverflowClasses();\n\n const swiperOptions = React.useMemo(\n () =>\n ({\n spaceBetween,\n breakpoints,\n }) as SwiperOptions,\n [breakpoints, spaceBetween],\n );\n\n return { swiperOptions, mainSwiperClasses, cellsInRow };\n};\n\nexport default useBuyableRecipesBreakpoints;\n","import { useEffect, useState } from 'react';\n\ninterface ElementsToUpdate {\n [tag: string]: { property: string; value: string }[];\n}\n\n/**\n * React helmet only handles elements inside the head tag that contain data-react-helmet=\"true\"\n */\nconst useDocumentHeadIsPreparedForReactHelmet = (elementsToUpdateByTag: ElementsToUpdate) => {\n const [readyForReactHelmet, setReadyForReactHelmet] = useState(false);\n\n const stringifiedElements = JSON.stringify(elementsToUpdateByTag);\n\n useEffect(() => {\n const parsedElementsToUpdateByTag = JSON.parse(stringifiedElements) as ElementsToUpdate;\n if (parsedElementsToUpdateByTag) {\n const childrenOfHead = Array.from(document.getElementsByTagName('head')[0].children);\n\n childrenOfHead.forEach((child) => {\n const tagName = child?.tagName?.toLowerCase();\n\n parsedElementsToUpdateByTag[tagName]?.forEach((tagEl) => {\n if (child.getAttribute(tagEl.property) === tagEl.value) {\n child.setAttribute('data-react-helmet', 'true');\n }\n });\n });\n\n setReadyForReactHelmet(true);\n }\n }, [stringifiedElements]);\n\n return readyForReactHelmet;\n};\n\nexport default useDocumentHeadIsPreparedForReactHelmet;\n","import { useLayoutEffect, useRef } from 'react';\n\nexport const useSavedInRef = <T>(value: T) => {\n const ref = useRef<T>(value);\n\n useLayoutEffect(() => {\n ref.current = value;\n });\n\n return ref;\n};\n","import { createSelector } from '@reduxjs/toolkit';\n\nimport type { RootState } from '../store';\n\nconst selectAll = (state: RootState) => state.featureFlags;\nconst selectEnablePetFood = createSelector(selectAll, (state) => state.enablePetFood);\n\nexport const featureFlagsSelectors = {\n selectAll,\n selectEnablePetFood,\n};\n","import { failSilently } from '../../utils/failSilently';\nimport { sendGA4Event } from '../shared/sendGa4Event';\n\nconst filterProducts = (categoryType: ProductFilterCategoryType, filters: string[]) => {\n const event: FilterProductsEvent = {\n event: 'filter',\n filter_category_1: categoryType,\n filter_category_2: filters.map((item) => item.toLowerCase()).join(','),\n event_key: 'filter_products',\n };\n\n sendGA4Event(event);\n};\n\nconst filterOffers = (\n categoryType: OfferFilterCategoryType,\n selectedCategory: string | null = null,\n) => {\n const event: FilterOffersEvent = {\n event: 'filter',\n filter_category_1: categoryType,\n filter_category_2: selectedCategory || 'no filter',\n event_key: 'filter_offers',\n };\n\n sendGA4Event(event);\n};\n\nconst sortProducts = (sortingLabel: string) => {\n const event: SortProductsEvent = {\n event: 'filter',\n filter_category_1: 'sortering på',\n filter_category_2: sortingLabel.toLowerCase(),\n event_key: 'filter_products',\n };\n\n sendGA4Event(event);\n};\n\nconst zoomProductImage = (open: boolean) => {\n const event: ZoomProductImageEvent = {\n event: 'zoom_product',\n event_action: open ? 'zoom open' : 'zoom close',\n };\n\n sendGA4Event(event);\n};\n\nexport default {\n filterProducts: failSilently(filterProducts),\n filterOffers: failSilently(filterOffers),\n sort: failSilently(sortProducts),\n zoomImage: failSilently(zoomProductImage),\n};\n","import { addQueryParamsToUrl } from './urlUtils';\n\nexport const getRobotsContent = (noIndex?: boolean, noFollow?: boolean) => {\n if (noIndex && noFollow) {\n return 'NOINDEX,NOFOLLOW';\n }\n\n if (noIndex) {\n return 'NOINDEX';\n }\n\n if (noFollow) {\n return 'NOFOLLOW';\n }\n\n return undefined;\n};\n\nexport const getCanonical = ({ path, page }: { path: string; page?: number }) => {\n const url = new URL(path, window.location.origin).toString();\n\n return Number.isInteger(page) && page !== 1\n ? addQueryParamsToUrl(url, { page: String(page) })\n : url;\n};\n\nexport const getNextPage = (currentPage: number) => {\n const searchParams = new URLSearchParams();\n searchParams.set('page', (currentPage + 1).toString());\n\n const newUrl = `${\n window.location.origin + window.location.pathname\n }?${searchParams.toString()}`;\n\n return newUrl;\n};\n\nexport const getPrevPage = (currentPage: number) => {\n const searchParams = new URLSearchParams();\n const prevPage = currentPage - 1;\n if (prevPage > 1) {\n searchParams.set('page', prevPage.toString());\n } else {\n searchParams.delete('page');\n }\n const stringifiedParams = searchParams.toString();\n\n const newUrl =\n window.location.origin +\n window.location.pathname +\n (stringifiedParams ? `?${searchParams.toString()}` : '');\n\n return newUrl;\n};\n","import { useCallback, useEffect, useId } from 'react';\n\nimport { useVerticalProductTeaserContainer } from '../../../ecommerce/hooks/useProductTeaserContainer';\nimport { productFlow } from '../../flow/product/productFlow';\nimport { useAsyncDispatcher } from '../../hooks/useAsyncDispatcher';\nimport { useAppSelector } from '../../hooks/useThunkDispatch';\nimport type { ProductProps } from '../../models/props/itemTeaserProps';\nimport { storeSelectors } from '../../selectors/storeSelectors';\nimport ListBlock from '../ListBlock/ListBlock';\nimport { BlockHeader } from '../ListBlock/ListBlockHeader';\nimport BuyableProductTeaser from '../molecules/BuyableProductTeaser';\n\ninterface SamePromotionProductListProps {\n product: ProductProps;\n onProductsLoaded: (promoProductsCount: number) => void;\n}\n\nconst listHeading = 'Varor som ingår i erbjudandet';\n\nconst SamePromotionProductList = (props: SamePromotionProductListProps) => {\n const { product } = props;\n const promotionId = product?.promotion?.identifier;\n\n const { execute, result, isLoading } = useAsyncDispatcher(productFlow.getProductsForPromotion, {\n initialLoadingState: true,\n });\n\n const currentProductionUnit = useAppSelector(storeSelectors.currentProductionUnit);\n\n const getProductsForPromotion = useCallback(() => {\n if (promotionId) {\n execute(promotionId, 50, currentProductionUnit);\n }\n }, [execute, promotionId, currentProductionUnit]);\n\n const otherProductsOnPromotion = result?.products?.filter(\n (item) => item.identifier !== product?.identifier,\n );\n\n const { onProductsLoaded } = props;\n\n useEffect(() => {\n if (otherProductsOnPromotion) {\n onProductsLoaded(otherProductsOnPromotion.length);\n }\n }, [onProductsLoaded, otherProductsOnPromotion]);\n\n const { swiperOptions, cellsInRow, gridAdditionalClasses, swiperMainClass } =\n useVerticalProductTeaserContainer('list');\n\n useEffect(() => {\n getProductsForPromotion();\n }, [getProductsForPromotion]);\n\n const headerId = useId();\n\n if (!promotionId) return null;\n\n if (!isLoading && !otherProductsOnPromotion?.length) {\n return null;\n }\n\n return (\n <ListBlock\n as=\"aside\"\n aria-labelledby={headerId}\n headerSlot={<BlockHeader id={headerId}>{listHeading}</BlockHeader>}\n isLoading={isLoading}\n items={otherProductsOnPromotion}\n useSwiper\n swiperMainClassName={swiperMainClass}\n swiperOptions={swiperOptions}\n cellsInRow={cellsInRow}\n analyticsListName={listHeading}\n horizontalHidden={false}\n gridClasses={gridAdditionalClasses}\n itemUniqueKey={(item, index) => `${item.identifier}_${index}`}\n renderItem={(_product, index, listPosition) => (\n <BuyableProductTeaser\n product={_product}\n isALink\n analyticsOptions={{\n list: listHeading,\n position: index,\n listPosition,\n }}\n isAsyncLink\n />\n )}\n renderSkeleton={() => null}\n />\n );\n};\n\nexport default SamePromotionProductList;\n","import { SeverityLevel } from '@microsoft/applicationinsights-web';\nimport { useRef } from 'react';\nimport { JsonLd } from 'react-schemaorg';\nimport type { Product } from 'schema-dts';\n\nimport { appInsights } from '../../../../appInsights';\nimport type { PriceType } from '../../../common/models/priceData/priceData';\nimport { generateProductJsonLd } from './ProductJsonSchema.utils';\n\ninterface ProductJsonLdSchemaProps extends ApiProduct {\n priceType: PriceType;\n}\n\nconst ProductJsonLd = (product: ProductJsonLdSchemaProps) => {\n const errorLoggedRef = useRef(false); // Ref to keep track if error is logged\n const { hostname } = window.location;\n try {\n const item = generateProductJsonLd(product, product.priceType, hostname);\n return <JsonLd<Product> item={item} />;\n } catch (error) {\n // eslint-disable-next-line no-console\n console.log(error);\n if (error instanceof Error && !errorLoggedRef.current) {\n appInsights.trackException({\n exception: {\n ...error,\n message: `Frontend - Unable to create product JSON-LD schema for ${product.name}`,\n },\n severityLevel: SeverityLevel.Error,\n });\n errorLoggedRef.current = true; // Mark the error as logged\n }\n return null;\n }\n};\n\nexport default ProductJsonLd;\n","import { failSilently } from '../../utils/failSilently';\nimport { sendGA4Event } from '../shared/sendGa4Event';\n\nconst view = () => {\n const event: SustainabilityViewEvent = {\n event: 'sustainability',\n type: 'view',\n event_key: 'hd_product_details',\n };\n\n sendGA4Event(event);\n};\n\nexport default {\n view: failSilently(view),\n};\n","const scoresTemplate: { range: [number, number]; url: string; risk: 'low' | 'medium' | 'high' }[] =\n [\n { range: [0, 1], url: '/Assets/Images/Lights/green.svg', risk: 'low' },\n { range: [1, 2], url: '/Assets/Images/Lights/green.svg', risk: 'low' },\n { range: [2, 3], url: '/Assets/Images/Lights/yellow.svg', risk: 'medium' },\n { range: [3, 4], url: '/Assets/Images/Lights/red.svg', risk: 'high' },\n { range: [4, 5], url: '/Assets/Images/Lights/red.svg', risk: 'high' },\n ];\n\nconst getTemplate = (score: number) => {\n return scoresTemplate.find((st) => score > st.range[0] && score <= st.range[1]);\n};\n\nexport const getLights = (\n productScores: {\n score?: number | null;\n param: string;\n paramId: string;\n }[],\n) => {\n const lights = productScores\n .map((ps) => {\n if (ps.score) {\n const template = getTemplate(ps.score);\n if (template) {\n return {\n id: ps.paramId,\n name: ps.param,\n score: ps.score,\n url: template.url,\n risk: template.risk,\n };\n }\n }\n\n return undefined;\n })\n .filter(Boolean)\n .sort((a, b) => a.score - b.score);\n\n return lights;\n};\n","/* eslint-disable react/no-array-index-key */\nimport classnames from 'classnames';\n\nimport styles from './SustainabilityLights.module.less';\nimport { getLights } from './SustainabilityLights.utils';\n\ninterface LightsProps {\n productScores: {\n score?: number | null;\n param: string;\n paramId: string;\n }[];\n}\n\nconst SustainabilityLights = (props: LightsProps) => {\n const lights = getLights(props.productScores);\n\n const risks = lights.reduce(\n (curr, next) => {\n switch (next.risk) {\n case 'low':\n return { ...curr, lowRisk: curr.lowRisk + 1 };\n case 'medium':\n return { ...curr, mediumRisk: curr.mediumRisk + 1 };\n case 'high':\n return { ...curr, highRisk: curr.highRisk + 1 };\n default:\n return curr;\n }\n },\n { lowRisk: 0, mediumRisk: 0, highRisk: 0 },\n );\n\n let risksLabel = '';\n\n if (risks.lowRisk > 0) {\n risksLabel += ` Låg risk för påverkan: ${risks.lowRisk} områden.`;\n }\n\n if (risks.mediumRisk > 0) {\n risksLabel += ` Medel risk för påverkan: ${risks.mediumRisk} områden.`;\n }\n\n if (risks.highRisk > 0) {\n risksLabel += ` Hög risk för påverkan: ${risks.highRisk} områden.`;\n }\n\n return (\n <div className={classnames(styles.Lights)} aria-label={risksLabel.trim()}>\n {lights.map((item) => (\n <img key={item.id} alt=\"\" src={item.url} />\n ))}\n </div>\n );\n};\n\nexport default SustainabilityLights;\n","// extracted by mini-css-extract-plugin\nexport default {\"LightsContainer\":\"cgvrKmJy\",\"Lights\":\"c9KbU6qZ\"};","// extracted by mini-css-extract-plugin\nexport default {\"Button\":\"qNDHRxep\",\"Text\":\"UgDKRoGg\",\"Disabled\":\"BMGVMSob\",\"LightsContainer\":\"JieRJenh\"};","import { IconButton, ModalHeader, VisuallyHidden } from '@coop/components';\nimport { CloseIcon } from '@coop/icons';\nimport classnames from 'classnames';\nimport type { FC } from 'react';\n\nimport { isProductionEnvironment } from '../../../../utility/environments';\nimport { FlyIn } from '../../../common/components/atoms/Modal';\nimport useModal from '../../../common/hooks/useModal';\nimport { FlyInType } from '../../../common/store/structureDefinitions/modalState';\nimport styles from './SustainabilityFlyinModal.module.less';\n\nconst getEnv = () => {\n if (isProductionEnvironment) return 'www';\n\n return 'www-qa';\n};\n\nconst SustainabilityFlyinModal: FC<\n React.PropsWithChildren<{ ean: string; missingData: boolean }>\n> = ({ ean, missingData }) => {\n const { isOpen, close } = useModal(FlyInType.SustainabilityDeclaration);\n\n const url = new URL(`https://${getEnv()}.coop-cdn.se/sustainabilityv2/`);\n url.searchParams.set('barcode', ean);\n url.searchParams.set('mode', 'desktop');\n\n if (missingData) {\n url.searchParams.set('missing_data', 'true');\n }\n\n return (\n <FlyIn\n isOpen={isOpen}\n close={close}\n sizePx={460}\n additionalClasses=\"u-textCenter u-paddingHz\"\n >\n <VisuallyHidden>\n <ModalHeader>Hållbarhetsdeklaration</ModalHeader>\n </VisuallyHidden>\n <IconButton\n icon={CloseIcon}\n theme=\"primary\"\n size={40}\n label=\"Stäng\"\n onClick={close}\n className={styles.CloseIcon}\n />\n <div className=\"u-flexGrow u-posRelative\">\n <iframe\n src={url.toString()}\n className={classnames(styles.Iframe, styles.V2)}\n frameBorder=\"0\"\n // according to axe rule interactive iframes should have tabIndex=\"0\"\n // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex\n tabIndex={0}\n title=\"Hållbarhetsdeklaration\"\n />\n </div>\n </FlyIn>\n );\n};\n\nexport default SustainabilityFlyinModal;\n","// extracted by mini-css-extract-plugin\nexport default {\"CloseIcon\":\"R6GUvD8X\",\"Iframe\":\"TEYqMemS\",\"V2\":\"uKXAGsd9\"};","import { Icon } from '@coop/components';\nimport { ChevronRightIcon } from '@coop/icons';\nimport classNames from 'classnames';\nimport { useEffect } from 'react';\n\nimport { Helpers } from '../../../../utility/helpers';\nimport useModal from '../../../common/hooks/useModal';\nimport { PriceType } from '../../../common/models/priceData/priceData';\nimport type { ProductProps } from '../../../common/models/props/itemTeaserProps';\nimport { FlyInType } from '../../../common/store/structureDefinitions/modalState';\nimport ga4SustainabilityEvents from '../../../common/tracking/ga4/sustainability/ga4SustainabilityEvents';\nimport gaTracking from '../../../common/tracking/tracking';\nimport { SustainabilityLights } from '../SustainabilityLights';\nimport styles from './SustainabilityDeclarationButton.module.scss';\nimport SustainabilityFlyinModal from './SustainabilityFlyinModal';\n\nexport interface SustainabilityDeclarationButtonProps {\n product: ProductProps;\n className?: string;\n}\n\nconst SustainabilityDeclarationButton = (props: SustainabilityDeclarationButtonProps) => {\n const { open, isOpen } = useModal(FlyInType.SustainabilityDeclaration);\n\n const handleClick = () => {\n ga4SustainabilityEvents.view();\n open();\n };\n\n useEffect(() => {\n if (isOpen) {\n const { manufacturer, name, priceData } = props.product;\n gaTracking.ecommerce.sustainability.open({\n ean: props.product.identifier,\n manufacturer,\n name,\n price: priceData && Helpers.getPrice(priceData, PriceType.IncludeTax),\n });\n }\n }, [isOpen, props.product]);\n\n if (!props.product.sustainabilityInfoApplicable) {\n return null;\n }\n\n return (\n <>\n {props.product.sustainabilityInfo ? (\n <button\n type=\"button\"\n className={classNames(styles.Button, props.className)}\n onClick={handleClick}\n aria-controls=\"portal\"\n aria-haspopup=\"dialog\"\n aria-expanded={isOpen}\n >\n <span className={styles.Text}>Hur hållbar är varan?</span>\n <div className={styles.LightsContainer}>\n <SustainabilityLights productScores={props.product.sustainabilityInfo} />\n <Icon icon={ChevronRightIcon} width={24} height={24} aria-hidden />\n </div>\n </button>\n ) : (\n <button\n type=\"button\"\n className={classNames(styles.Button, props.className, styles.Disabled)}\n onClick={handleClick}\n aria-controls=\"portal\"\n aria-haspopup=\"dialog\"\n aria-expanded={isOpen}\n aria-label=\"Hållbarhetsdeklaration saknas för denna produkt. Klicka för att se varför.\"\n >\n Hållbarhetsdeklaration saknas\n <Icon icon={ChevronRightIcon} width={24} height={24} aria-hidden />\n </button>\n )}\n <SustainabilityFlyinModal\n ean={props.product.identifier}\n missingData={!props.product.sustainabilityInfo}\n />\n </>\n );\n};\n\nexport default SustainabilityDeclarationButton;\n","// extracted by mini-css-extract-plugin\nexport default {\"Root\":\"N575FdTl\",\"Content\":\"qhuWtYz4\",\"NutritionTable\":\"L076FrmW\",\"PreparationInstructions\":\"BqigPKyO\",\"PreparationInstructionsParagraph\":\"IwPXUiD5\",\"AccordionHeader\":\"mhEozpqb\",\"AccordionContent\":\"tvkoaCAn\",\"AnimalFoodTable\":\"F7JVvAXx\",\"Cell\":\"i7D9U5yB\",\"HeaderCell\":\"IjQf0_Nq\",\"ContentCell\":\"yrNu1yuB\"};","import type { ReactNode } from 'react';\n\nimport Heading from '../../../../../common/components/Heading';\n\nconst ProductDetailHeading = (props: { children: ReactNode }) => (\n <Heading\n stylingElement=\"h5\"\n element=\"h3\"\n className=\"u-marginBxxsm u-textWeightBold u-wordBreakAll\"\n alignment=\"start\"\n >\n {props.children}\n </Heading>\n);\n\nexport default ProductDetailHeading;\n","import ProductDetailHeading from './ProductDetailHeading';\n\nconst Disclaimer = () => {\n return (\n <div className=\"u-marginBmd\">\n <ProductDetailHeading>Övrig information</ProductDetailHeading>\n <p className=\"u-marginTz\">\n Vi på Coop gör vårt bästa för att alltid ge Dig rätt produktinformation. Över tid\n kan det ske mindre förändringar av innehållet. Vi vill därför vänligen påminna Dig\n om att före användning kontrollera produktinformationen på produktens förpackning.\n Det här är så klart särskilt viktigt om Du av någon anledning vill undvika vissa\n ingredienser eller ämnen.\n </p>\n </div>\n );\n};\n\nexport default Disclaimer;\n","/* eslint-disable react/jsx-props-no-spreading */\nimport { ConfirmInfo } from '@coop/components';\nimport classNames from 'classnames';\nimport type { FC } from 'react';\n\nimport CloudinaryImage from '../../../../../common/components/atoms/CloudinaryImage';\nimport RawHtml from '../../../../../common/components/atoms/RawHtml';\nimport useModal from '../../../../../common/hooks/useModal';\nimport { useAppSelector } from '../../../../../common/hooks/useThunkDispatch';\nimport type { ProductAnimalFoodData } from '../../../../../common/models/props/itemTeaserProps';\nimport { featureFlagsSelectors } from '../../../../../common/selectors/featureFlagsSelectors';\nimport Disclaimer from './Disclaimer';\nimport ProductDetailHeading from './ProductDetailHeading';\nimport styles from './ProductDetailsAccordion.module.scss';\nimport type { AnimalTableRow, ProductFactsProps } from './ProductDetailsAccordion.types';\n\nconst getStorageInstructions = (storageInstructions?: string, maxStorageTemperature?: string) => {\n if (storageInstructions) {\n // storage instructions has priority\n return storageInstructions;\n }\n\n return `Förvaras vid högst ${maxStorageTemperature}${'\\xB0'}C`;\n};\n\nconst ProductFacts: FC<React.PropsWithChildren<ProductFactsProps>> = (props) => {\n // list of non food ingredients should only be shown if the default list is empty\n const listOfIngredients = props.listOfIngredients || props.listOfNonFoodIngredients;\n\n const countryOfOriginConfirm = useModal('CountryOfOrigin');\n\n const healthSafetySignalWordsCode = props.healthSafetySignalWordsCode?.[0];\n\n return (\n <>\n {(!!props.healthattributeLabels?.length || !!healthSafetySignalWordsCode) && (\n <div className=\"u-marginBmd\">\n <div className=\"u-flex u-flexAlignCenter u-flexGap8 u-flexWrap u-marginBxxsm\">\n {!!props.healthattributeLabels?.length && (\n <ul\n aria-label=\"Faropiktogram\"\n className=\"u-flex u-flexAlignCenter u-flexGap8 u-flexWrap u-listStyleTypeNone u-paddingAz u-marginAz\"\n >\n {props.healthattributeLabels.map((label) => (\n <li\n key={`${label.identifier}-${label.image?.identifier ?? ''}`}\n >\n <CloudinaryImage\n url={label.image?.url || ''}\n name={label.name}\n transform=\"q_auto,f_auto,w_48\"\n retinaTransform=\"q_auto,f_auto,w_96\"\n width={48}\n height={48}\n />\n </li>\n ))}\n </ul>\n )}\n {healthSafetySignalWordsCode && (\n <p className=\"u-textWeightBold\">{healthSafetySignalWordsCode}</p>\n )}\n </div>\n\n {props.healthSafetySignalStatementText?.map((signalStatement) => (\n <p className=\"u-marginVxxsm\" key={signalStatement}>\n {signalStatement}\n </p>\n ))}\n </div>\n )}\n {!!props.healthSafetyPrecautionaryStatementText?.length && (\n <div className=\"u-marginBmd\">\n <ProductDetailHeading>Skyddsangivelse</ProductDetailHeading>\n {props.healthSafetyPrecautionaryStatementText.map((precautionaryStatement) => (\n <p className=\"u-marginVxxsm\" key={precautionaryStatement}>\n {precautionaryStatement}\n </p>\n ))}\n </div>\n )}\n {(listOfIngredients || props.storageState?.code === 'PREVIOUSLY_FROZEN') && (\n <div className=\"u-marginBmd\">\n {props.regulatedArticleDescription && (\n <div className=\"u-marginBxxsm\">{props.regulatedArticleDescription}</div>\n )}\n <ProductDetailHeading>Innehåll</ProductDetailHeading>\n {listOfIngredients && <RawHtml html={listOfIngredients} />}\n {props.storageState?.code === 'PREVIOUSLY_FROZEN' && (\n <div className={classNames(listOfIngredients && 'u-marginTxsm')}>\n {props.storageState?.value}\n </div>\n )}\n </div>\n )}\n <AnimalFoodInfo animalFoodData={props.animalFoodData} />\n {(props.consumerInstructions?.usageInstructions || props.compulsoryAdditiveLabel) && (\n <div className=\"u-marginBmd\">\n <ProductDetailHeading>Dosering & användning</ProductDetailHeading>\n {props.consumerInstructions?.usageInstructions && (\n <p className=\"u-marginTz\">{props.consumerInstructions.usageInstructions}</p>\n )}\n {props.compulsoryAdditiveLabel && (\n <p className=\"u-marginTz\">{props.compulsoryAdditiveLabel}</p>\n )}\n </div>\n )}\n <AnimalFoodTable animalFoodTable={props.animalFoodData?.animalFeedingTable} />\n {!!props.preparationInstructionsList.length && (\n <div className=\"u-marginBmd\">\n <ProductDetailHeading>Beredning</ProductDetailHeading>\n <div className={styles.PreparationInstructions}>\n {props.preparationInstructionsList.map((pi) => (\n <p className={styles.PreparationInstructionsParagraph}>{pi}</p>\n ))}\n </div>\n </div>\n )}\n {(props.maxStorageTemperature || props.consumerInstructions?.storageInstructions) && (\n <div className=\"u-marginBmd\">\n <ProductDetailHeading>Förvaring</ProductDetailHeading>\n <p className=\"u-marginTz\">\n {getStorageInstructions(\n props.consumerInstructions?.storageInstructions,\n props.maxStorageTemperature,\n )}\n </p>\n </div>\n )}\n {props.declarationOfOrigin && (\n <div className=\"u-marginBmd\">\n <ProductDetailHeading>Ursprung</ProductDetailHeading>\n <p className=\"u-marginTz\">{props.declarationOfOrigin}</p>\n </div>\n )}\n {!!props.replacementCountries?.length && (\n <div className=\"u-marginBmd\">\n <ProductDetailHeading>Möjliga ersättningsländer</ProductDetailHeading>\n <p className=\"u-marginTz\">\n {props.replacementCountries.map((country) => country.value).join(', ')}\n </p>\n </div>\n )}\n {props.catchData?.catchArea && (\n <div className=\"u-marginBmd\">\n <ProductDetailHeading>Fångstområde</ProductDetailHeading>\n <p className=\"u-marginTz\">{props.catchData.catchArea}</p>\n </div>\n )}\n {props.catchData?.catchMethod && (\n <div className=\"u-marginBmd\">\n <ProductDetailHeading>Fångstmetod</ProductDetailHeading>\n <p className=\"u-marginTz\">{props.catchData.catchMethod}</p>\n </div>\n )}\n {!!props.countriesOfOrigin?.length && (\n <div className=\"u-marginBmd\">\n <ConfirmInfo\n show={countryOfOriginConfirm.isOpen}\n close={countryOfOriginConfirm.close}\n heading=\"Tillverkningsland\"\n message=\"Artikelns tillverkningsland är det land där den genomgick sin sista\n väsentliga bearbetning och/eller förpackades.\"\n renderTrigger={(ref) => (\n <ProductDetailHeading>\n <button\n className=\"u-textUnderline u-outlineSolidBase2\"\n ref={ref}\n type=\"button\"\n onClick={countryOfOriginConfirm.open}\n >\n Tillverkningsland\n </button>\n </ProductDetailHeading>\n )}\n />\n <p className=\"u-marginTz\">{props.countriesOfOrigin.join(', ')}</p>\n </div>\n )}\n {props.eanCode && (\n <div className=\"u-marginBmd\">\n <ProductDetailHeading>Övrigt</ProductDetailHeading>\n <p className=\"u-marginTz\">EAN kod: {props.eanCode}</p>\n </div>\n )}\n <Disclaimer />\n </>\n );\n};\n\nconst AnimalFoodTable = (props: {\n animalFoodTable?: ProductAnimalFoodData['animalFeedingTable'];\n}) => {\n const enablePetFood = useAppSelector(featureFlagsSelectors.selectEnablePetFood);\n\n if (!enablePetFood || !props.animalFoodTable) return null;\n\n const rows = props.animalFoodTable.filter(\n (row): row is AnimalTableRow =>\n !!row.animalWeight?.displayName && !!row.guidingAmount?.displayName,\n );\n\n if (rows.length === 0) return null;\n\n return (\n <div>\n <div className={styles.AnimalFoodTable}>\n <div className={classNames(styles.HeaderCell, styles.Cell)}>Djurets vikt</div>\n <div className={classNames(styles.HeaderCell, styles.Cell)}>Vägledande mängd</div>\n {rows.map((row) => (\n <>\n <div className={classNames(styles.ContentCell, styles.Cell)}>\n {row.animalWeight.displayName.toLowerCase()}\n </div>\n <div className={classNames(styles.ContentCell, styles.Cell)}>\n {row.guidingAmount.displayName.toLowerCase()}\n </div>\n </>\n ))}\n </div>\n </div>\n );\n};\n\nconst AnimalFoodInfo = (props: { animalFoodData?: ProductAnimalFoodData }) => {\n const enablePetFood = useAppSelector(featureFlagsSelectors.selectEnablePetFood);\n\n if (!enablePetFood || !props.animalFoodData) return null;\n\n return (\n <>\n {props.animalFoodData?.targetedConsumptionBy && (\n <div className=\"u-marginBmd\">\n <ProductDetailHeading>Avsedd för</ProductDetailHeading>\n <p className=\"u-marginTz\">{props.animalFoodData.targetedConsumptionBy.value}</p>\n </div>\n )}\n {props.animalFoodData?.feedType && (\n <div className=\"u-marginBmd\">\n <ProductDetailHeading>Fodertyp</ProductDetailHeading>\n <p className=\"u-marginTz\">{props.animalFoodData.feedType}</p>\n </div>\n )}\n {props.animalFoodData?.feedCompositionStatement && (\n <div className=\"u-marginBmd\">\n <ProductDetailHeading>Sammansättning</ProductDetailHeading>\n <p className=\"u-marginTz\">{props.animalFoodData.feedCompositionStatement}</p>\n </div>\n )}\n {props.animalFoodData?.feedAnalyticalConstituentsStatement && (\n <div className=\"u-marginBmd\">\n <ProductDetailHeading>Analytiska beståndsdelar</ProductDetailHeading>\n <p className=\"u-marginTz\">\n {props.animalFoodData.feedAnalyticalConstituentsStatement}\n </p>\n </div>\n )}\n {props.animalFoodData?.feedAdditiveStatement && (\n <div className=\"u-marginBmd\">\n <ProductDetailHeading>Tillsatser</ProductDetailHeading>\n <p className=\"u-marginTz\">{props.animalFoodData.feedAdditiveStatement}</p>\n </div>\n )}\n {props.animalFoodData?.feedingInstructions && (\n <div className=\"u-marginBmd\">\n <ProductDetailHeading>Utfodringsinstruktioner</ProductDetailHeading>\n <p className=\"u-marginTz\">{props.animalFoodData.feedingInstructions}</p>\n </div>\n )}\n </>\n );\n};\n\nexport default ProductFacts;\n","/* eslint-disable react/jsx-props-no-spreading */\nimport DOMPurify from 'dompurify';\nimport type { FC } from 'react';\n\nimport type { ProductInformationProps } from './ProductDetailsAccordion.types';\n\nconst ProductInformation: FC<React.PropsWithChildren<ProductInformationProps>> = (props) => {\n return (\n <>\n {props.isPharmaceutical && (\n <p className=\"u-marginTz u-marginBxsm\">\n <strong>För farmaceutisk rådgivning: Vänd dig till sjukvården</strong>\n </p>\n )}\n {props.description && (\n <div itemProp=\"description\">\n {DOMPurify.sanitize(props.description, {\n USE_PROFILES: { html: false },\n })}\n </div>\n )}\n {props.isMagazine && (\n <div>\n <h5 className=\"u-marginTmd\">Dagsaktuell tidning</h5>\n <p className=\"u-marginTz\">\n När vi plockar din order väljer vi den dagsaktuella utgåvan. Notera att det\n kan innebära en senare utgåva än den som är aktuell vid\n beställningstillfället.\n </p>\n </div>\n )}\n </>\n );\n};\n\nexport default ProductInformation;\n","// extracted by mini-css-extract-plugin\nexport default {\"Container\":\"jrvFBPGu\",\"NutritionGrid\":\"LfLEvtbH\",\"Cell\":\"AE1efsoY\",\"NutritionName\":\"rTAoO43e\",\"NutritionValue\":\"pjP0dWJX\",\"NutritionDailyIntake\":\"ecq2R2UP\",\"GridLine\":\"uyKDhI8r\"};","import type { ProductNutrientInformation } from '../../../../../../common/models/props/itemTeaserProps';\n\nconst unitsMap = new Map<string, { long: string; short: string }>([\n ['B60', { long: 'Lumens per Square Meter', short: 'lm/m²' }],\n ['ANN', { long: 'Year', short: 'år' }],\n ['CEL', { long: 'Degree Celsius', short: '°C' }],\n ['CMT', { long: 'Centimetre', short: 'cm' }],\n ['E14', { long: 'Kilokalori', short: 'kcal' }],\n ['GL', { long: 'Gram Per Litre', short: 'g/l' }],\n ['GRM', { long: 'Gram', short: 'g' }],\n ['H87', { long: 'Piece', short: 'st' }],\n ['HUR', { long: 'Hour', short: 'tim' }],\n ['INH', { long: 'Inches', short: 'tum' }],\n ['KGM', { long: 'Kilogram', short: 'kg' }],\n ['KJO', { long: 'Kilojoule', short: 'kJ' }],\n ['LUX', { long: 'Lux', short: 'lux' }],\n ['MC', { long: 'Mikrogram', short: 'μg' }],\n ['MGM', { long: 'Milligram', short: 'mg' }],\n ['MLT', { long: 'Millilitre', short: 'ml' }],\n ['MMT', { long: 'Millimetre', short: 'mm' }],\n ['MON', { long: 'Month', short: 'månad' }],\n ['MTK', { long: 'Square metre', short: 'm²' }],\n ['MTQ', { long: 'Cubic metre', short: 'm³' }],\n ['P1', { long: 'Percent', short: '%' }],\n]);\n\nexport const getUnitShortValue = (code?: string) => {\n if (!code) return '';\n\n const shortUnit = unitsMap.get(code);\n return shortUnit?.short || code;\n};\n\n// helper function, remove when AS give us unit codes\nexport const getUnitShortFromLongValue = (longValue?: string) => {\n if (!longValue) return '';\n\n const shortUnit = Array.from(unitsMap.values()).find(\n (unit) => unit.long.toLowerCase() === longValue.toLowerCase(),\n );\n\n return shortUnit?.short || longValue;\n};\n\nexport const getNutrientBasis = (nutrientInformation?: ProductNutrientInformation['header']) => {\n return (\n nutrientInformation &&\n `${nutrientInformation.nutrientBasisQuantity} ${getUnitShortValue(\n nutrientInformation.nutrientBasisQuantityUnit?.code,\n )}`\n );\n};\n\nconst schemaPropMap: Record<string, string> = {\n energi: 'calories',\n fett: 'fatContent',\n 'varav mättat fett': 'saturatedFatContent',\n 'varav fleromättat fett': 'unsaturatedFatContent',\n kolhydrat: 'carbohydrateContent',\n protein: 'proteinContent',\n nacl: 'sodiumContent',\n fiber: 'fiberContent',\n 'varav sockerarter': 'sugarContent',\n};\n\nexport const getSchemaPropName = (name: string) => {\n if (!name) return null;\n\n const propName = schemaPropMap[name.toLowerCase().trim()];\n return propName;\n};\n","/* eslint-disable react/jsx-props-no-spreading */\nimport classnames from 'classnames';\nimport { type FC, useId } from 'react';\nimport * as React from 'react';\n\nimport type {\n ProductNutrientInformation,\n ProductNutritionFact,\n} from '../../../../../../common/models/props/itemTeaserProps';\nimport Disclaimer from '../Disclaimer';\nimport ProductDetailHeading from '../ProductDetailHeading';\nimport styles from './ProductNutritionTable.module.scss';\nimport {\n getNutrientBasis,\n getSchemaPropName,\n getUnitShortFromLongValue,\n} from './ProductNutritionTable.utils';\n\ninterface ProductNutritionTableProps {\n nutrientInformation?: ProductNutrientInformation[];\n nutritionFacts: ProductNutritionFact[];\n}\n\nconst ProductNutritionTable: FC<React.PropsWithChildren<ProductNutritionTableProps>> = (props) => {\n const hasDailyIntakeInfo = props.nutritionFacts.some((fact) => !!fact.percentageOfDailyIntake);\n const nutritionFacts = props.nutritionFacts\n .filter((x) => !!x && x.name && x.value)\n .map((x) => ({ ...x, value: x.value.replace('.', ',') })); // later on nutritionFacts will be inside nutrientInformation as details so this field should be removed\n const nutrientInformation = props.nutrientInformation?.[0].header; // this should be a map on array but they dont have all the info yet in AS\n const nutrientBasis = getNutrientBasis(nutrientInformation);\n\n const dailyIntakeHtmlId = useId();\n\n return (\n <div className={styles.Container}>\n <ProductDetailHeading>\n Näringsvärde per {nutrientBasis}\n {nutrientInformation?.preparationState?.code === 'PREPARED' &&\n ` (${nutrientInformation?.preparationState?.value})`}\n </ProductDetailHeading>\n <div className={styles.NutritionGrid}>\n <div className={classnames('u-textWeightBold', styles.NutritionName, styles.Cell)}>\n Innehåll\n </div>\n <div className={classnames('u-textWeightBold', styles.NutritionValue, styles.Cell)}>\n {nutrientBasis}\n </div>\n {hasDailyIntakeInfo && (\n <div\n className={classnames(\n 'u-textWeightBold',\n styles.NutritionDailyIntake,\n styles.Cell,\n )}\n aria-labelledby={dailyIntakeHtmlId}\n >\n RI*\n </div>\n )}\n <div className={styles.GridLine} />\n {nutritionFacts.map((x, index) => (\n <React.Fragment key={`${x.name}_${x.value}_${x.unit}_${index.toString()}`}>\n <div\n itemProp={getSchemaPropName(x.name) || undefined}\n className={classnames(styles.NutritionName, styles.Cell)}\n >\n {x.name}\n </div>\n <div className={classnames(styles.NutritionValue, styles.Cell)}>{`${\n x.value\n } ${getUnitShortFromLongValue(x.unit)}`}</div>\n {hasDailyIntakeInfo && (\n <div className={classnames(styles.NutritionDailyIntake, styles.Cell)}>\n {x.percentageOfDailyIntake && `${x.percentageOfDailyIntake}%`}\n </div>\n )}\n <div className={styles.GridLine} />\n </React.Fragment>\n ))}\n </div>\n {hasDailyIntakeInfo && (\n <span className=\"u-textXSmall\" id={dailyIntakeHtmlId}>\n <span aria-hidden>*</span>Referensintag\n </span>\n )}\n <div className=\"u-marginTmd\">\n <Disclaimer />\n </div>\n </div>\n );\n};\n\nexport default ProductNutritionTable;\n","import type { FC } from 'react';\n\nimport { Helpers } from '../../../../../../utility/helpers';\nimport type { PriceData, PriceType } from '../../../../../common/models/priceData/priceData';\nimport ProductDetailHeading from './ProductDetailHeading';\n\ninterface ProductPriceHistoryProps {\n priceHistory: PriceData;\n priceType: PriceType;\n}\n\nconst ProductPriceHistory: FC<React.PropsWithChildren<ProductPriceHistoryProps>> = (props) => {\n return (\n <>\n <ProductDetailHeading>\n Tidigare lägsta pris:{' '}\n {Helpers.toEcommercePriceWithCurrency(\n Helpers.getPrice(props.priceHistory, props.priceType),\n )}\n </ProductDetailHeading>\n <div>\n Tidigare lägsta pris är det lägsta pris som tillämpats för varan under de senaste 30\n dagarna innan den nuvarande kampanjen började.\n </div>\n </>\n );\n};\n\nexport default ProductPriceHistory;\n","import { Accordion } from '@coop/components';\nimport classNames from 'classnames';\nimport type { PropsWithChildren } from 'react';\n\nimport Heading from '../../../../../common/components/Heading';\nimport styles from './ProductDetailsAccordion.module.scss';\nimport type {\n ProductDetailsAccordionItemType,\n ProductDetailsAccordionProps,\n} from './ProductDetailsAccordion.types';\nimport ProductFacts from './ProductFacts';\nimport ProductInformation from './ProductInformation';\nimport ProductNutritionTable from './ProductNutritionTable';\nimport ProductPriceHistory from './ProductPriceHistory';\n\nconst ProductDetailsAccordion: React.FC<React.PropsWithChildren<ProductDetailsAccordionProps>> = (\n props,\n) => {\n return (\n <Accordion.Root\n type=\"single\"\n collapsible\n className={classNames(styles.Root, props.className)}\n theme=\"gray\"\n rounded\n defaultValue={props.defaultValue}\n >\n {(props.description || props.isMagazine) && (\n <ProductDetailsAccordionItem value=\"description\" heading=\"Beskrivning\">\n <ProductInformation\n description={props.description}\n isMagazine={props.isMagazine}\n isPharmaceutical={props.isPharmaceutical}\n />\n </ProductDetailsAccordionItem>\n )}\n\n <ProductDetailsAccordionItem value=\"productFacts\" heading=\"Produktfakta\">\n <ProductFacts\n eanCode={props.eanCode}\n listOfIngredients={props.listOfIngredients}\n listOfNonFoodIngredients={props.listOfNonFoodIngredients}\n maxStorageTemperature={props.maxStorageTemperature}\n declarationOfOrigin={props.declarationOfOrigin}\n catchData={props.catchData}\n countriesOfOrigin={props.countriesOfOrigin}\n compulsoryAdditiveLabel={props.compulsoryAdditiveLabel}\n consumerInstructions={props.consumerInstructions}\n replacementCountries={props.replacementCountries}\n preparationInstructionsList={props.preparationInstructionsList}\n healthattributeLabels={props.healthattributeLabels}\n healthSafetyPrecautionaryStatementText={\n props.healthSafetyPrecautionaryStatementText\n }\n healthSafetySignalStatementText={props.healthSafetySignalStatementText}\n healthSafetySignalWordsCode={props.healthSafetySignalWordsCode}\n storageState={props.storageState}\n regulatedArticleDescription={props.regulatedArticleDescription}\n animalFoodData={props.animalFoodData}\n />\n </ProductDetailsAccordionItem>\n\n {!!props.nutrientInformation &&\n props.nutrientInformation?.[0].header?.nutrientBasisQuantity &&\n props.nutrientInformation?.[0].header?.nutrientBasisQuantityUnit &&\n !!props.nutritionFacts &&\n !!props.nutritionFacts.length && (\n <ProductDetailsAccordionItem\n value=\"nutritionalContent\"\n heading=\"Näringsinnehåll\"\n >\n <ProductNutritionTable\n nutritionFacts={props.nutritionFacts}\n nutrientInformation={props.nutrientInformation}\n />\n </ProductDetailsAccordionItem>\n )}\n\n {!!props.priceHistory && (\n <ProductDetailsAccordionItem heading=\"Prishistorik\" value=\"priceHistory\">\n <ProductPriceHistory\n priceHistory={props.priceHistory}\n priceType={props.priceType}\n />\n </ProductDetailsAccordionItem>\n )}\n </Accordion.Root>\n );\n};\n\nconst ProductDetailsAccordionItem = (\n props: PropsWithChildren<{\n value: ProductDetailsAccordionItemType;\n heading: string;\n }>,\n) => {\n const openAllAccordions = window.isPrerenderCrawler || undefined; // The accordions needs to be opened for google to be able to index the content.\n\n return (\n <Accordion.Item\n value={props.value}\n className={styles.ProductDetailsAccordionItem}\n data-product-information={props.heading}\n >\n <Accordion.Header asChild className={styles.AccordionHeader}>\n <Accordion.Trigger>\n <Heading element=\"h2\" stylingElement=\"h5\" alignment=\"start\">\n {props.heading}\n </Heading>\n </Accordion.Trigger>\n </Accordion.Header>\n <Accordion.Content className={styles.AccordionContent} forceMount={openAllAccordions}>\n {props.children}\n </Accordion.Content>\n </Accordion.Item>\n );\n};\n\nexport default ProductDetailsAccordion;\n","import type { FC } from 'react';\n\nimport { appConfig } from '../../../../../appConfig';\nimport type { BreadcrumbItem } from '../../../../common/components/molecules/Breadcrumbs';\nimport Breadcrumbs from '../../../../common/components/molecules/Breadcrumbs/Breadcrumbs';\nimport { useProductSectionsContext } from '../../../contexts/productSectionsContext';\nimport { useCurrentSectionParams } from '../../../hooks/useCurrentSectionParams';\nimport { buildAbsoluteUrl, buildSubSectionUrl } from '../../../utils/urlEcommerceUtils';\n\nconst ProductDetailsBreadcrumbs: FC<\n React.PropsWithChildren<{ name: string; productUrl: string }>\n> = ({ name, productUrl }) => {\n const { sectionTree } = useProductSectionsContext();\n const { sectionTrail } = useCurrentSectionParams(sectionTree);\n\n const breadcrumbs: BreadcrumbItem[] = [\n {\n name: 'Handla',\n url: buildAbsoluteUrl(appConfig.coopSettings.ecommerce.url),\n isLayoutRouterAsyncLink: true,\n },\n ...(sectionTrail.map((b, index, array) => ({\n name: b.name,\n url: buildSubSectionUrl(array, index),\n isLayoutRouterAsyncLink: false,\n })) || []),\n {\n name,\n url: productUrl,\n isLayoutRouterAsyncLink: false,\n },\n ];\n\n return <Breadcrumbs items={breadcrumbs} wrapperClasses=\"u-marginBsm\" small />;\n};\n\nexport default ProductDetailsBreadcrumbs;\n","/* eslint-disable react/jsx-props-no-spreading */\nimport type { FC } from 'react';\n\nimport ProductBadge from '../../../../common/components/atoms/ProductBadge';\nimport type { ProductProps } from '../../../../common/models/props/itemTeaserProps';\n\ninterface ProductDetailsLabelsProps {\n product: ProductProps;\n}\n\nconst ProductDetailsLabels: FC<React.PropsWithChildren<ProductDetailsLabelsProps>> = (props) => {\n const { product } = props;\n\n return (\n <div className=\"ItemInfo-labeling\">\n {product?.attributeLabels?.map((attr) =>\n attr.image?.url ? (\n <ProductBadge\n key={`${attr.identifier}-${attr.image?.identifier ?? ''}`}\n dimensions={{ width: 45, height: 'auto' }}\n zoomable\n zoomDimensions={{ width: 80, height: 'auto' }}\n url={attr.image.url}\n alt={attr.name}\n />\n ) : null,\n )}\n </div>\n );\n};\n\nexport default ProductDetailsLabels;\n","import { IconButton } from '@coop/components';\nimport { CloseIcon, SearchIcon } from '@coop/icons';\nimport classnames from 'classnames';\nimport type { FC } from 'react';\nimport type React from 'react';\n\nimport CloudinaryImage from '../../../../../common/components/atoms/CloudinaryImage';\nimport { Modal } from '../../../../../common/components/atoms/Modal';\nimport { useIsDesktop } from '../../../../../common/components/atoms/ResponsiveBreakpoints';\nimport { missingProductImageUrl } from '../../../../../common/components/molecules/ProductTeaser/ProductTeaser.consts';\nimport useModal from '../../../../../common/hooks/useModal';\nimport { ZoomProductImageType } from '../../../../../common/store/structureDefinitions/modalState';\nimport { ga4ProductsTracking } from '../../../../../common/tracking/ga4/products';\nimport styles from './ProductImage.module.less';\n\ninterface ProductImageProps {\n imageUrl?: string;\n name: string;\n}\n\nconst ProductImage: FC<React.PropsWithChildren<ProductImageProps>> = (props) => {\n const { isOpen, close, open } = useModal(ZoomProductImageType.zoomProductImage);\n const isDesktop = useIsDesktop();\n\n const closeModal = () => {\n close();\n ga4ProductsTracking.zoomImage(false);\n };\n const openModalClick = () => {\n open();\n ga4ProductsTracking.zoomImage(true);\n };\n\n return (\n <div className={styles.ProductImageContainer}>\n <CloudinaryImage\n onClick={openModalClick}\n url={props.imageUrl}\n name={props.name}\n fallbackUrl={missingProductImageUrl}\n transform=\"e_sharpen,f_auto,fl_clip,fl_progressive,q_90,c_lpad,g_center,h_330,w_330\"\n retinaTransform=\"e_sharpen,f_auto,fl_clip,fl_progressive,q_90,c_lpad,g_center,h_660,w_660\"\n cssClass={styles.ProductImage}\n />\n {isDesktop && (\n <div className={styles.ButtonPosition}>\n <IconButton\n icon={SearchIcon}\n label=\"Zooma bild\"\n theme=\"light\"\n size={40}\n onClick={openModalClick}\n />\n </div>\n )}\n <Modal isOpen={isOpen} close={closeModal} additionalClasses={styles.ZoomModal}>\n <div className={classnames(styles.CloseButtonDiv, 'u-posAbsolute')}>\n <IconButton\n icon={CloseIcon}\n label=\"Stäng\"\n theme=\"light\"\n size={40}\n onClick={closeModal}\n />\n </div>\n <picture className={classnames(styles.ImageContainer, 'u-bgWhite', 'u-paddingAlg')}>\n <CloudinaryImage\n url={props.imageUrl}\n cssClass={styles.Image}\n name={props.name}\n transform=\"e_sharpen,f_auto,fl_clip,fl_progressive,q_90,c_lpad,g_center,h_660,w_660\"\n />\n </picture>\n </Modal>\n </div>\n );\n};\n\nexport default ProductImage;\n","// extracted by mini-css-extract-plugin\nexport default {\"CloseButtonDiv\":\"AM_APjlv\",\"OpenButtonDiv\":\"th2VBobC\",\"ImageContainer\":\"UYGxjfUQ\",\"Image\":\"z4rCz8_K\",\"ZoomModal\":\"wOnVW_uS\",\"ButtonPosition\":\"zNJaHYtn\",\"ProductImage\":\"bq_yJGlm\",\"ProductImageContainer\":\"oQDxVVEv\"};","import { useCallback, useEffect, useId } from 'react';\n\nimport type { ApiRecipe } from '../../../../../../models/recipe/recipeModel';\nimport { RecipeTeaserSkeleton } from '../../../../../common/components/BaseRecipeTeaser';\nimport BuyableFoodboxTeaser from '../../../../../common/components/BuyableFoodboxTeaser';\nimport BuyableRecipeTeaser from '../../../../../common/components/BuyableRecipeTeaser';\nimport { useListBlockLazyLoading } from '../../../../../common/components/ListBlock';\nimport ListBlock from '../../../../../common/components/ListBlock/ListBlock';\nimport { BlockHeader } from '../../../../../common/components/ListBlock/ListBlockHeader';\nimport RecipeTypeComponentPicker from '../../../../../common/components/RecipeTypeComponentPicker';\nimport { useAsyncDispatcher } from '../../../../../common/hooks/useAsyncDispatcher';\nimport useBuyableRecipesBreakpoints from '../../../../../common/hooks/useBuyableRecipesBreakpoints';\nimport { useAppSelector } from '../../../../../common/hooks/useThunkDispatch';\nimport { storeSelectors } from '../../../../../common/selectors/storeSelectors';\nimport { ga4RecipesTracking } from '../../../../../common/tracking/ga4/recipes';\nimport recipeFlow from '../../../../../recipe/flow/recipeFlow';\n\ninterface RecipeRecommendationsByProductProps {\n productIdentifier: string;\n}\n\nconst RecipeRecommendationsByProduct = (props: RecipeRecommendationsByProductProps) => {\n const { execute, result, isLoading } = useAsyncDispatcher(recipeFlow.getRecipesByProduct, {\n initialLoadingState: true,\n });\n\n const currentProductionUnit = useAppSelector(storeSelectors.currentProductionUnit);\n\n const getRecipes = useCallback(() => {\n if (props.productIdentifier) {\n execute([props.productIdentifier], currentProductionUnit, 20);\n }\n }, [execute, currentProductionUnit, props.productIdentifier]);\n\n const { swiperOptions, mainSwiperClasses, cellsInRow } = useBuyableRecipesBreakpoints();\n\n const [inViewRef, inView] = useListBlockLazyLoading();\n\n useEffect(() => {\n if (inView) {\n getRecipes();\n }\n }, [inView, getRecipes]);\n\n const headerId = useId();\n\n if (!isLoading && !result?.length) {\n return null;\n }\n\n return (\n <ListBlock\n aria-labelledby={headerId}\n as=\"aside\"\n ref={inViewRef}\n headerSlot={!isLoading && <BlockHeader id={headerId}>Passande recept</BlockHeader>}\n isLoading={isLoading}\n items={result}\n useSwiper\n swiperOptions={swiperOptions}\n swiperMainClassName={mainSwiperClasses}\n cellsInRow={cellsInRow}\n gridClasses=\"Grid--gutterAxsm\"\n analyticsListName=\"Passande recept\"\n horizontalHidden={false}\n itemUniqueKey={(item) => item.externalId.toString()}\n renderItem={(recipe) => <RecipeItem recipe={recipe} />}\n renderSkeleton={() => <RecipeTeaserSkeleton />}\n />\n );\n};\n\nconst RecipeItem: React.FC<React.PropsWithChildren<{ recipe: ApiRecipe }>> = ({ recipe }) => {\n const handleBuyClick = (recipeExternalId: number, recipeName: string) => () => {\n ga4RecipesTracking.pdpRecipeRecommendations.buyButtonClick(recipeExternalId, recipeName);\n };\n\n const handleLinkClick = (recipeExternalId: number, recipeName: string) => () => {\n ga4RecipesTracking.pdpRecipeRecommendations.recipeTeaserClick(recipeExternalId, recipeName);\n };\n\n return (\n <RecipeTypeComponentPicker\n isFoodbox={recipe.isFoodBox}\n recipeSlot={\n <BuyableRecipeTeaser\n id={recipe.externalId.toString()}\n name={recipe.name}\n url={recipe.relativeUrl}\n rating={recipe.avgRating}\n co2ImpactKg={recipe.climateImpactKg}\n imageUrl={recipe.imageUrl}\n votes={recipe.numberOfVotes}\n defaultPortions={recipe.yieldValue}\n analyticsListName=\"PLP - Recipemodal\"\n onBuyClick={handleBuyClick(recipe.externalId, recipe.name)}\n onLinkClick={handleLinkClick(recipe.externalId, recipe.name)}\n />\n }\n foodboxSlot={\n <BuyableFoodboxTeaser\n id={recipe.externalId.toString()}\n name={recipe.name}\n url={recipe.relativeUrl}\n imageUrl={recipe.imageUrl}\n defaultPortions={recipe.yieldValue}\n analyticsListName=\"PLP - Recipemodal\"\n onBuyClick={handleBuyClick(recipe.externalId, recipe.name)}\n onLinkClick={handleLinkClick(recipe.externalId, recipe.name)}\n />\n }\n />\n );\n};\n\nexport default RecipeRecommendationsByProduct;\n","/* eslint-disable react/jsx-props-no-spreading */\nimport { Icon } from '@coop/components';\nimport { Warning1Icon } from '@coop/icons';\nimport classNames from 'classnames';\nimport type { FC } from 'react';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\n\nimport {\n createProductPageContext,\n trackSpaDY,\n updateDyStaticContext,\n} from '../../../../../utility/dynamicYield';\nimport { Helpers } from '../../../../../utility/helpers';\nimport { AddToCartButton } from '../../../../common/components/AddToCartButton';\nimport ProductPrice from '../../../../common/components/atoms/ProductPrice';\nimport VariantSelector from '../../../../common/components/atoms/VariantSelector';\nimport DynamicYieldBlock from '../../../../common/components/DynamicYieldBlock/DynamicYieldBlock';\nimport EcomPromoSplash from '../../../../common/components/molecules/EcomPromoSplash';\nimport PageProperties from '../../../../common/components/molecules/PageProperties';\nimport SamePromotionProductList from '../../../../common/components/organisms/SamePromotionProductList';\nimport { productFlow } from '../../../../common/flow/product/productFlow';\nimport trackingFlow from '../../../../common/flow/trackingFlow';\nimport { useAsyncDispatcher } from '../../../../common/hooks/useAsyncDispatcher';\nimport { useBuyableState } from '../../../../common/hooks/useBuyableProductState';\nimport { useCurrentPriceType } from '../../../../common/hooks/useCurrentPriceType';\nimport { useGroupError } from '../../../../common/hooks/useGroupError';\nimport { useLayoutSize } from '../../../../common/hooks/useLayoutSize';\nimport { useAppSelector } from '../../../../common/hooks/useThunkDispatch';\nimport { mapVariantPromotion } from '../../../../common/models/domain/ecommerce/promotion/promotionMappers';\nimport { storeSelectors } from '../../../../common/selectors/storeSelectors';\nimport { ErrorGroup } from '../../../../common/store/structureDefinitions/errorsState';\nimport { ga4ItemsTracking } from '../../../../common/tracking/ga4/items';\nimport { useIsB2BRoute } from '../../../../common/utils/b2bUtils';\nimport {\n getFormattedComparativePrice,\n mapProductToProps,\n} from '../../../../common/utils/productUtils';\nimport EpiContentArea from '../../../../episerver/components/base/EpiContentArea';\nimport { mapEpiDynamicYieldBlockToProps } from '../../../../episerver/components/blocks/EpiDynamicYieldBlock/EpiDynamicYieldBlock';\nimport { isDynamicYieldBlock } from '../../../../episerver/components/blocks/EpiDynamicYieldBlock/EpiDynamicYieldBlock.utils';\nimport { useCurrentProductOrSection } from '../../../hooks/useCurrentProductOrSection';\nimport useEcommerceSettings from '../../../hooks/useEcommerceSettings';\nimport ProductJsonLd from '../../JsonLd/ProductJsonLd';\nimport MaxPromotionUsage from '../../MaxPromotionUsage';\nimport SustainabilityDeclarationButton from '../../SustainabilityDeclarationButton/SustainabilityDeclarationButton';\nimport NotFoundPage from '../notfoundPage/NotFoundPage';\nimport ProductDetailsAccordion from './ProductDetailsAccordion';\nimport ProductDetailsBreadcrumbs from './ProductDetailsBreadcrumbs';\nimport ProductDetailsLabels from './ProductDetailsLabels';\nimport styles from './ProductDetailsPage.module.less';\nimport { getProductDetailsPageMetaData } from './ProductDetailsPage.utils';\nimport ProductImage from './ProductImage';\nimport RecipeRecommendationsByProduct from './RecipeRecommendationsByProduct/RecipeRecommendationsByProduct';\n\n/** Also known as PDP */\nconst ProductDetailsPage: FC = () => {\n const {\n routeData: { productId },\n } = useCurrentProductOrSection();\n\n const {\n execute,\n result: product,\n error,\n status,\n } = useAsyncDispatcher(productFlow.getProductById);\n\n const currentProductionUnit = useAppSelector(storeSelectors.currentProductionUnit);\n\n useEffect(() => {\n if (productId) {\n execute(productId, currentProductionUnit);\n }\n }, [execute, productId, currentProductionUnit]);\n\n const { setContentPageSize } = useLayoutSize();\n\n useEffect(() => {\n setContentPageSize('full');\n }, [setContentPageSize]);\n\n const [dyContextReady, setDyContextReady] = useState(false);\n\n useEffect(() => {\n if (productId) {\n const context = createProductPageContext(window.location.href, productId);\n trackSpaDY(context, window.location.href);\n trackingFlow.click({ productId }); // this will be sent to loop54, according to them, click can be tracked on pdp page.\n updateDyStaticContext(context);\n setDyContextReady(true);\n }\n }, [productId]);\n\n useGroupError(ErrorGroup.Global, error);\n\n if (!productId) {\n return null;\n }\n if (status === 'success' && !product) {\n return <NotFoundPage type=\"product\" />;\n }\n return (\n // this Fragment is necessary for Portal to work properly\n // eslint-disable-next-line react/jsx-no-useless-fragment\n <>{product && dyContextReady && <ProductDetails product={product} />}</>\n );\n};\n\nconst NicotineProductInformation = () => {\n return (\n <div className={styles.NicotineInformation}>\n <div className={styles.NicotineIcon}>\n <Icon icon={Warning1Icon} width={16} height={16} color=\"red\" />\n </div>\n <span>\n Nikotinläkemedel får inte säljas vid misstanke om langning till någon som inte fyllt\n 18 år\n </span>\n </div>\n );\n};\n\ninterface ProductDetailsProps {\n product: ApiProduct;\n}\n\nconst ProductDetails: FC<React.PropsWithChildren<ProductDetailsProps>> = (props) => {\n const product = useMemo(() => mapProductToProps(props.product), [props.product]);\n const currentProductionUnit = useAppSelector(storeSelectors.currentProductionUnit);\n\n const { currentPriceType } = useCurrentPriceType();\n\n const title =\n product.manufacturer && product.name.length + product.manufacturer.length < 45\n ? `${product.name} - ${product.manufacturer} - Coop`\n : `${product.name} - Coop`;\n\n const description = product.manufacturer\n ? `Köp ${product.name} från ${product.manufacturer} online på Coop.se. Välj mellan hemleverans eller upphämtning i butik. Handla här!`\n : `Köp ${product.name} online på Coop.se. Välj mellan hemleverans eller upphämtning i butik. Handla här!`;\n\n const { currentVariant, quantity, handleVariantChange, onQuantityUpdate } = useBuyableState(\n props.product,\n {\n isSilent: true,\n analyticsOptions: null,\n },\n );\n\n const { data: ecommerceSettings } = useEcommerceSettings();\n\n const hasVariants = !!product.variants?.length;\n\n useEffect(() => {\n if (props.product) {\n ga4ItemsTracking.viewItem(\n props.product.identifier,\n props.product.variants?.[0]?.id,\n currentProductionUnit,\n );\n }\n }, [currentProductionUnit, props.product]);\n\n const recycleFeeDataPrice =\n product.recycleFeeData && Helpers.getPrice(product.recycleFeeData, currentPriceType);\n\n const [showSimiliarityBlock, setShowSimiliarityBlock] = useState(\n !product?.promotion?.identifier,\n );\n const onPromoProductsLoaded = useCallback((promoProductsCount: number) => {\n if (promoProductsCount === 0) {\n setShowSimiliarityBlock(true);\n }\n }, []);\n\n const priceData = currentVariant?.priceData || product.priceData;\n const promotionPriceData = currentVariant?.promotionPriceData || product.promotionPriceData;\n\n const isB2BRoute = useIsB2BRoute();\n const { ogImage, canonicalUrl } = getProductDetailsPageMetaData(product, isB2BRoute);\n\n return (\n <>\n <PageProperties\n headData={{\n title,\n link: {\n canonical: canonicalUrl,\n },\n meta: {\n description,\n 'og:image': ogImage,\n },\n }}\n pageTypeNameForAnalytics=\"produktsida\"\n />\n <ProductJsonLd {...props.product} priceType={currentPriceType} />\n <ProductDetailsBreadcrumbs name={product.name} productUrl={product.url} />\n <div className=\"Grid\">\n <div className=\"Grid-cell u-marginBxlg\">\n <article className=\"ItemInfo\">\n <div className=\"ItemInfo-content\">\n <div className=\"ItemInfo-media\">\n <div className=\"ItemInfo-image\">\n <ProductImage name={product.name} imageUrl={product.imageUrl} />\n </div>\n <ProductDetailsLabels product={product} />\n <div className=\"ItemInfo-label-splash\">\n {product.promotion && (\n <div className=\"u-marginBsm u-lg-flex\">\n <EcomPromoSplash\n type=\"large\"\n promotion={product.promotion}\n priceType={currentPriceType}\n />\n </div>\n )}\n </div>\n </div>\n <div className=\"ItemInfo-details\">\n <div className=\"ItemInfo-info\">\n <div className=\"u-flexGrow\">\n <h1 className=\"ItemInfo-heading\">{product.name}</h1>\n <div className=\"ItemInfo-description\">\n {product.fromSweden && (\n <img\n className=\"u-marginRxxxxsm\"\n src=\"/Assets/Icons/flag-sweden.svg\"\n alt=\"Svensk flagga\"\n width=\"16\"\n height=\"10\"\n />\n )}\n <span className=\"ItemInfo-brand\">\n {product.manufacturer}\n {product.manufacturer && '.'}\n </span>\n <span>\n {product.packageSizeInformation &&\n ` ${product.packageSizeInformation}.`}\n </span>\n\n {product.comparativePriceData && (\n <div>\n {product.comparativePriceData &&\n getFormattedComparativePrice(\n Helpers.getPrice(\n product.comparativePriceData,\n currentPriceType,\n ),\n product.comparativeText,\n )}\n </div>\n )}\n\n {!!product.consumerInformationText?.length && (\n <div>\n {product.consumerInformationText.join(', ')}\n </div>\n )}\n\n {!!product.isPharmaceutical && <div>Läkemedel</div>}\n\n {!!recycleFeeDataPrice && recycleFeeDataPrice > 0 && (\n <div>\n +\n {Helpers.toEcommercePriceWithCurrency(\n recycleFeeDataPrice,\n 'hideRest',\n )}{' '}\n pant\n </div>\n )}\n\n {product.promotion?.maxUseText && (\n <div className=\"u-marginTxxsm\">\n <MaxPromotionUsage\n text={product.promotion?.maxUseText}\n withNotification\n />\n </div>\n )}\n </div>\n <div className=\"ItemInfo-cta\">\n {hasVariants && (\n <div className=\"ItemInfo-select\">\n <VariantSelector\n selectedVariantId={currentVariant?.id}\n variants={product.variants}\n handleVariantChange={handleVariantChange}\n />\n </div>\n )}\n\n <ProductPrice\n piecePrice={priceData}\n newPiecePrice={promotionPriceData}\n priceType={currentPriceType}\n promo={mapVariantPromotion(\n product.promotion,\n currentVariant || undefined,\n )}\n className={classNames(styles.ProductPrice)}\n orientation=\"row\"\n align=\"left\"\n showExcludingTaxInfo\n quantity={quantity}\n />\n </div>\n <div className=\"ItemInfo-button\">\n <AddToCartButton\n quantity={quantity}\n setQuantity={onQuantityUpdate}\n productName={product.name}\n />\n\n {product.promotion && (\n <div className=\"u-marginLmd u-lg-hidden\">\n <EcomPromoSplash\n type=\"default\"\n promotion={product.promotion}\n priceType={currentPriceType}\n />\n </div>\n )}\n </div>\n </div>\n </div>\n {props.product.details.isNicotineProduct && (\n <div className=\"u-sizeFull ItemInfo-info u-paddingTz u-paddingBz\">\n <NicotineProductInformation />\n </div>\n )}\n <div\n className=\"u-sizeFull ItemInfo-info u-paddingTz\"\n style={{ paddingBottom: 12 }}\n >\n <SustainabilityDeclarationButton\n className={styles.SustainabilityDeclarationButton}\n product={product}\n />\n </div>\n <div className=\"u-sizeFull ItemInfo-info u-paddingTz\">\n <ProductDetailsAccordion\n className={styles.ProductDetailsAccordion}\n defaultValue=\"priceHistory\" // always intially open priceHistory, business requirement\n nutrientInformation={product?.nutrientInformation}\n nutritionFacts={product?.nutritionFacts}\n listOfIngredients={product?.listOfIngredients}\n listOfNonFoodIngredients={product?.listOfNonFoodIngredients}\n maxStorageTemperature={product?.maxStorageTemperature}\n declarationOfOrigin={product?.declarationOfOrigin}\n catchData={product?.catchData}\n storageState={product?.storageState}\n countriesOfOrigin={product?.countriesOfOrigin}\n eanCode={product?.eanCode}\n description={product?.description}\n isMagazine={product?.isMagazine}\n // for now always use price with tax\n priceHistory={product?.historicalPriceData}\n compulsoryAdditiveLabel={product?.compulsoryAdditiveLabel}\n consumerInstructions={product?.consumerInstructions}\n replacementCountries={product?.replacementCountries}\n preparationInstructionsList={\n product?.preparationInstructionsList || []\n }\n healthattributeLabels={product?.healthattributeLabels}\n healthSafetyPrecautionaryStatementText={\n product?.healthSafetyPrecautionaryStatementText\n }\n healthSafetySignalStatementText={\n product?.healthSafetySignalStatementText\n }\n healthSafetySignalWordsCode={\n product?.healthSafetySignalWordsCode\n }\n priceType={currentPriceType}\n isPharmaceutical={product?.isPharmaceutical}\n regulatedArticleDescription={\n product?.regulatedArticleDescription ||\n product?.regulatedProductName\n }\n animalFoodData={product?.animalFoodData}\n />\n </div>\n </div>\n </div>\n </article>\n </div>\n <div className=\"Grid-cell\">\n <div className=\"Grid Grid--gutterVmd\">\n <div className=\"Grid-cell\">\n {showSimiliarityBlock && ecommerceSettings ? (\n <DynamicYieldBlock\n as=\"aside\"\n recommendationId={\n ecommerceSettings.similiarityBlockRecommendationId\n }\n onlyPromotions={false}\n analyticsListName={\n ecommerceSettings.similiarityBlockRecommendationGaList\n }\n useSwiper\n lazyLoad\n horizontalHidden={false}\n disableLink={false}\n disableAsyncLink={false}\n />\n ) : (\n <SamePromotionProductList\n product={product}\n onProductsLoaded={onPromoProductsLoaded}\n />\n )}\n </div>\n\n {ecommerceSettings && (\n <EpiContentArea\n items={ecommerceSettings.bottomContentArea}\n renderItem={(\n componentProps,\n _contentAreaItem,\n contentAreaItemClasses,\n ) => {\n if (isDynamicYieldBlock(componentProps)) {\n const mappedProps =\n mapEpiDynamicYieldBlockToProps(componentProps);\n\n return (\n <div className={contentAreaItemClasses}>\n <DynamicYieldBlock as=\"aside\" {...mappedProps} />\n </div>\n );\n }\n }}\n />\n )}\n <div className=\"Grid-cell\">\n <RecipeRecommendationsByProduct\n productIdentifier={product.identifier}\n />\n </div>\n </div>\n </div>\n </div>\n </>\n );\n};\n\nexport default ProductDetailsPage;\n","// extracted by mini-css-extract-plugin\nexport default {\"NicotineInformation\":\"Ga8AgvOg\",\"NicotineIcon\":\"OwTzeCh0\",\"Badges\":\"SpRlvvdV\",\"ProductImage\":\"usqQ75k8\",\"ProductPrice\":\"h_aHFv2h\",\"ProductDetailsAccordion\":\"uwMvRTkc\",\"SustainabilityDeclarationButton\":\"DCtprG9H\"};","import { appConfig } from '../../../../../appConfig';\nimport type { ProductProps } from '../../../../common/models/props/itemTeaserProps';\nimport { B2B_SEGMENT } from '../../../../common/utils/b2bUtils';\nimport { getCloudinaryUrl } from '../../../../common/utils/cloudinaryImageUtils';\nimport { ensureLeadingSlash } from '../../../../common/utils/stringUtils';\nimport { buildAbsoluteUrl } from '../../../utils/urlEcommerceUtils';\n\nexport const getProductDetailsPageMetaData = (product: ProductProps, isB2BRoute: boolean) => {\n let canonicalUrl = buildAbsoluteUrl(product.url);\n if (isB2BRoute) {\n canonicalUrl = canonicalUrl.replace(ensureLeadingSlash(B2B_SEGMENT), '');\n }\n\n return {\n canonicalUrl,\n ogImage: product.imageUrl\n ? getCloudinaryUrl(\n product.imageUrl,\n 'e_sharpen,f_auto,fl_clip,fl_progressive,q_90,c_lpad,g_center,h_330,w_330',\n appConfig.coopSettings.ecommerce.ogImage,\n )\n : undefined,\n };\n};\n","/* eslint-disable react/no-array-index-key */\n/* eslint-disable react/jsx-props-no-spreading */\n/* eslint-disable react/jsx-no-useless-fragment */\nimport classNames from 'classnames';\n\nimport { getCssClassForDisplayOptionWithDefaultTag } from '../../epiUtils';\nimport EpiComponentLoader from './EpiComponentLoader';\n\ninterface EpiContentAreaProps {\n items: ContentAreaItem[];\n epiTag?: DisplayOption;\n itemCssClass?: string;\n /** If you pass renderItem function, you are responsible for generating item itself as well as it's Grid cell.\n * Use contentAreaItem, contentAreaItemClasses parameters to get access to default values for items.\n */\n renderItem?: (\n componentProps: IContent,\n contentAreaItem: ContentAreaItem,\n contentAreaItemClasses: string,\n ) => React.ReactNode;\n}\n\nconst EpiContentArea = ({ items, epiTag, itemCssClass, renderItem }: EpiContentAreaProps) => {\n const areaItems = items?.filter((x) => !!x && !!x.contentLink.expanded) || [];\n\n return (\n <>\n {areaItems.map((contentAreaItem, index) => (\n <EpiComponentLoader\n expandedValue={contentAreaItem.contentLink.expanded!}\n options={{\n isContentAreaItem: true,\n }}\n key={`{${contentAreaItem.contentLink.guidValue}_${index}}`}\n >\n {(LazyComponent, epiComponentProps) => {\n const contentAreaItemClasses = classNames(\n getCssClassForDisplayOptionWithDefaultTag(\n contentAreaItem.displayOption || epiTag,\n ),\n itemCssClass,\n );\n\n return (\n <>\n {(renderItem &&\n renderItem(\n epiComponentProps,\n contentAreaItem,\n contentAreaItemClasses,\n )) || (\n <div className={contentAreaItemClasses}>\n <LazyComponent {...epiComponentProps} />\n </div>\n )}\n </>\n );\n }}\n </EpiComponentLoader>\n ))}\n </>\n );\n};\n\nexport default EpiContentArea;\n","import type { EpiDynamicYieldBlockType } from './epiDynamicYieldBlockType';\n\nexport const isDynamicYieldBlock = (content: IContent): content is EpiDynamicYieldBlockType =>\n content?.contentType?.includes('DynamicYieldBlockType') === true;\n"],"names":["exports","json_ld_1","Object","defineProperty","enumerable","get","JsonLd","value","helmetJsonLdProp","jsonLdScriptProps","React","item","options","type","dangerouslySetInnerHTML","__html","JSON","stringify","safeJsonLdReplacer","space","props","createElement","assign","innerHTML","ESCAPE_ENTITIES","freeze","ESCAPE_REGEX","RegExp","keys","join","ESCAPE_REPLACER","t","_","replace","link","data","meta","canonical","path","page","pagination","currentPage","hasPrevPage","hasNextPage","totalItems","pageSize","prevPage","nextPage","linkData","entries","filter","undefined","metaData","map","key","property","isDocumentHeadReadyForReactHelmet","useDocumentHeadIsPreparedForReactHelmet","Helmet","title","name","content","rel","href","children","defaultQueryKeys","useGaVirtualPageView","search","dispatch","canonicalUrl","URL","window","location","origin","toString","triggerString","queryString","triggerKeys","searchParams","URLSearchParams","Array","from","includes","reduce","acc","set","getFilteredQueryStringForVirtualPageView","queryStringTriggers","enable","sendEvent","useSavedInRef","c","setPageGaData","gaPageTypeName","pageTypeName","pageTitle","useEffect","current","headData","pageTypeNameForAnalytics","virtualPageViewQueryStringTriggers","setTitle","headPagination","breakpoints","cellsInRow","AREA_NEW_RECIPE_LIST","mainSwiperClasses","spaceBetween","swiperOptions","elementsToUpdateByTag","readyForReactHelmet","setReadyForReactHelmet","useState","stringifiedElements","parsedElementsToUpdateByTag","parse","document","getElementsByTagName","forEach","child","tagName","toLowerCase","tagEl","getAttribute","setAttribute","ref","useRef","useLayoutEffect","selectAll","state","featureFlags","featureFlagsSelectors","selectEnablePetFood","enablePetFood","filterProducts","failSilently","categoryType","filters","event","filter_category_1","filter_category_2","event_key","filterOffers","selectedCategory","sort","sortingLabel","zoomImage","open","event_action","getRobotsContent","noIndex","noFollow","getCanonical","url","Number","isInteger","String","getNextPage","pathname","getPrevPage","delete","stringifiedParams","listHeading","product","promotionId","promotion","identifier","execute","result","isLoading","useAsyncDispatcher","productFlow","getProductsForPromotion","initialLoadingState","currentProductionUnit","storeSelectors","useCallback","otherProductsOnPromotion","products","onProductsLoaded","length","gridAdditionalClasses","swiperMainClass","headerId","useId","ListBlock","as","headerSlot","id","items","useSwiper","swiperMainClassName","analyticsListName","horizontalHidden","gridClasses","itemUniqueKey","index","renderItem","_product","listPosition","BuyableProductTeaser","isALink","analyticsOptions","list","position","isAsyncLink","renderSkeleton","errorLoggedRef","hostname","priceType","error","console","log","Error","appInsights","trackException","exception","message","severityLevel","SeverityLevel","view","scoresTemplate","range","risk","lights","productScores","ps","score","template","find","st","paramId","param","Boolean","a","b","risks","curr","next","lowRisk","mediumRisk","highRisk","risksLabel","className","trim","alt","src","ean","missingData","isOpen","close","useModal","SustainabilityDeclaration","sizePx","additionalClasses","VisuallyHidden","ModalHeader","IconButton","icon","theme","size","label","onClick","frameBorder","tabIndex","handleClick","ga4SustainabilityEvents","manufacturer","priceData","ecommerce","sustainability","price","getPrice","IncludeTax","sustainabilityInfoApplicable","sustainabilityInfo","Icon","width","height","Heading","stylingElement","element","alignment","AnimalFoodTable","animalFoodTable","rows","row","animalWeight","displayName","guidingAmount","HeaderCell","Cell","ContentCell","AnimalFoodInfo","animalFoodData","targetedConsumptionBy","feedType","feedCompositionStatement","feedAnalyticalConstituentsStatement","feedAdditiveStatement","feedingInstructions","listOfIngredients","listOfNonFoodIngredients","countryOfOriginConfirm","healthSafetySignalWordsCode","healthattributeLabels","CloudinaryImage","image","transform","retinaTransform","healthSafetySignalStatementText","signalStatement","healthSafetyPrecautionaryStatementText","precautionaryStatement","storageState","code","regulatedArticleDescription","RawHtml","html","consumerInstructions","usageInstructions","compulsoryAdditiveLabel","animalFeedingTable","preparationInstructionsList","PreparationInstructions","pi","PreparationInstructionsParagraph","maxStorageTemperature","storageInstructions","declarationOfOrigin","replacementCountries","country","catchData","catchArea","catchMethod","countriesOfOrigin","ConfirmInfo","show","heading","renderTrigger","eanCode","isPharmaceutical","description","itemProp","sanitize","USE_PROFILES","isMagazine","unitsMap","Map","long","short","getUnitShortFromLongValue","longValue","shortUnit","values","unit","schemaPropMap","energi","fett","kolhydrat","protein","nacl","fiber","hasDailyIntakeInfo","nutritionFacts","some","fact","percentageOfDailyIntake","x","nutrientInformation","header","nutrientBasis","nutrientBasisQuantity","getUnitShortValue","nutrientBasisQuantityUnit","getNutrientBasis","dailyIntakeHtmlId","preparationState","toEcommercePriceWithCurrency","priceHistory","ProductDetailsAccordionItem","openAllAccordions","isPrerenderCrawler","Accordion","A","Item","Header","asChild","AccordionHeader","Trigger","Content","AccordionContent","forceMount","Root","collapsible","rounded","defaultValue","productUrl","sectionTree","sectionTrail","useCurrentSectionParams","breadcrumbs","appConfig","coopSettings","isLayoutRouterAsyncLink","array","Breadcrumbs","wrapperClasses","small","attributeLabels","attr","ProductBadge","dimensions","zoomable","zoomDimensions","zoomProductImage","isDesktop","closeModal","openModalClick","imageUrl","fallbackUrl","cssClass","Modal","RecipeItem","recipe","handleBuyClick","recipeExternalId","recipeName","pdpRecipeRecommendations","buyButtonClick","handleLinkClick","recipeTeaserClick","RecipeTypeComponentPicker","isFoodbox","isFoodBox","recipeSlot","BuyableRecipeTeaser","externalId","relativeUrl","rating","avgRating","co2ImpactKg","climateImpactKg","votes","numberOfVotes","defaultPortions","yieldValue","onBuyClick","onLinkClick","foodboxSlot","BuyableFoodboxTeaser","recipeFlow","getRecipesByProduct","getRecipes","productIdentifier","useBuyableRecipesBreakpoints","inViewRef","inView","NicotineProductInformation","color","ProductDetails","useMemo","currentPriceType","useCurrentPriceType","currentVariant","quantity","handleVariantChange","onQuantityUpdate","isSilent","ecommerceSettings","useEcommerceSettings","hasVariants","variants","viewItem","recycleFeeDataPrice","recycleFeeData","showSimiliarityBlock","setShowSimiliarityBlock","onPromoProductsLoaded","promoProductsCount","promotionPriceData","isB2BRoute","ogImage","getProductDetailsPageMetaData","PageProperties","EcomPromoSplash","fromSweden","packageSizeInformation","comparativePriceData","comparativeText","consumerInformationText","maxUseText","MaxPromotionUsage","text","withNotification","VariantSelector","selectedVariantId","ProductPrice","piecePrice","newPiecePrice","promo","orientation","align","showExcludingTaxInfo","AddToCartButton","setQuantity","productName","details","isNicotineProduct","style","paddingBottom","historicalPriceData","regulatedProductName","DynamicYieldBlock","recommendationId","similiarityBlockRecommendationId","onlyPromotions","similiarityBlockRecommendationGaList","lazyLoad","disableLink","disableAsyncLink","EpiContentArea","bottomContentArea","componentProps","_contentAreaItem","contentAreaItemClasses","isDynamicYieldBlock","mappedProps","mapEpiDynamicYieldBlockToProps","routeData","productId","useCurrentProductOrSection","status","getProductById","setContentPageSize","useLayoutSize","dyContextReady","setDyContextReady","context","trackingFlow","click","useGroupError","Global","NotFoundPage","epiTag","itemCssClass","areaItems","contentLink","expanded","contentAreaItem","expandedValue","isContentAreaItem","LazyComponent","epiComponentProps","displayOption","guidValue","contentType"],"sourceRoot":""}