{"version":3,"file":"app-86db41e7.xxxxxxxx.bundle.js","mappings":"mrBAAAA,EAAOC,QAAU,SAASC,GACzB,2DAA4BC,GAC3BD,EAAG,EAAQ,MACX,2BACF,C,mLC8HWE,E,ykGAFEC,EAA4B,uCAEzC,SAAWD,GACT,oCACA,gCACA,oCACA,4BACA,yBACD,CAND,CAAWA,IAAAA,EAAiB,KAqB5B,iBAkjBE,WACUE,EACAC,EACAC,EACAC,EACAC,EACAC,EACRC,GAPF,WACU,KAAAN,oCAAAA,EACA,KAAAC,cAAAA,EACA,KAAAC,aAAAA,EACA,KAAAC,aAAAA,EACA,KAAAC,KAAAA,EACA,KAAAC,UAAAA,EA7iBO,KAAAE,cAAwB,EACxB,KAAAC,YAAa,EAEtB,KAAAC,oBAAsG,KACtG,KAAAC,cAAgB,iBAChB,KAAAC,iBAA+C,GAE/C,KAAAC,SAAmB,EACnB,KAAAC,WAAqB,EACrB,KAAAC,qCAA+C,EAC/C,KAAAC,UAAoB,EACpB,KAAAC,mBAAoB,EACpB,KAAAC,KAA0B,OAC1B,KAAAC,iBAA8F,KAE9F,KAAAC,qBAA+C,GAE/C,KAAAC,oCAAsE,GACtE,KAAAC,wCAA0E,GAC1E,KAAAC,4BAA8D,GAC9D,KAAAC,sCAAwE,GACxE,KAAAC,mCAAmE,GACnE,KAAAC,oBAA6C,GAC7C,KAAAC,cAAe,EACf,KAAAC,sBAAwB,GACxB,KAAAC,gBAAsC,KACtC,KAAAC,OAAS,IACT,KAAAC,0BAA4B,IAASA,0BAKrC,KAAAC,qBAAuBjC,EAAkBkC,gBACzC,KAAAC,uBAAwB,EACxB,KAAAC,wBAAyB,EACzB,KAAAC,SAAW,uBAGX,KAAAC,0BAAqE,CAC3E,CACEC,IAAK,wBACLC,OAAQ,GACRC,UAAU,EACVC,YAAY,EACZC,SAAU,IAAO,iDAEnB,CACEJ,IAAK,yBACLC,OAAQ,wDACRC,UAAU,EACVC,YAAY,EACZC,SAAU,IAAO,0CAEnB,CACEJ,IAAK,2BACLC,OAAQ,GACRC,UAAU,EACVC,YAAY,EACZC,SAAU,IAAO,oDAEnB,CACEJ,IAAK,qBACLC,OAAQ,oDACRC,UAAU,EACVC,YAAY,EACZC,SAAU,IAAO,8CAgfnBC,KAAKC,qBAAuBrC,EAA4BsC,wBACxDF,KAAKC,qBAAqBE,YAAY,IAAI,KAG1CH,KAAKN,0BAA0BU,QAAQ,SAACC,GAClCA,EAAOT,SACTS,EAAOT,OAAS,EAAKlC,KAAK4C,GAAGD,EAAOT,QAExC,EACF,C,sBAq6CF,O,EA1+DaW,EAukBK,YAAAC,SAAhB,Y,wCAAyB,G,IACvBC,EAAc,iBACdC,EAAe,kBACfC,EAAY,eACZC,EAAe,kBACfC,EAAkB,qBAClBC,EAAuB,0BACvBC,EAAQ,WACRjD,EAAU,aACVD,EAAY,e,iCAYZmC,KAAKS,oBAAoCO,IAAnBP,EAA+BT,KAAKS,eAAiBA,EAC3ET,KAAKU,qBAAsCM,IAApBN,EAAgCV,KAAKU,gBAAkBA,EAC9EV,KAAKW,kBAAgCK,IAAjBL,EAA6BX,KAAKW,aAAeA,EACrEX,KAAKY,qBAAsCI,IAApBJ,EAAgCZ,KAAKY,gBAAkBA,EAC9EZ,KAAKa,wBAA4CG,IAAvBH,EAAmCb,KAAKa,mBAAqBA,EACvFb,KAAKc,6BACyBE,IAA5BF,EAAwCd,KAAKc,wBAA0BA,EACzEd,KAAKe,cAAwBC,IAAbD,EAAyBf,KAAKe,SAAWA,EACzDf,KAAKlC,gBAA4BkD,IAAflD,EAA2BkC,KAAKlC,WAAaA,EAC/DkC,KAAKnC,kBAAgCmD,IAAjBnD,EAA6BmC,KAAKnC,aAAeA,E,SAG7D,YAAAoD,SAAV,eAGMC,EAHN,OAEQC,EAA8BC,aAAaC,QAAQhE,GAEzD,IACE6D,EAAoD,OAAhCC,EAAuCG,KAAKC,MAAMJ,GAA+B,IACvG,CAAE,SAEAD,EAAoB,IACtB,CACiC,kBAAtBA,IACTlB,KAAKlC,WAAaoD,GAGhBlB,KAAKlC,YACPkC,KAAKrC,UAAU6D,eAAe,YAC5B,QAAe,EACjB,EAEJ,EAEU,YAAAC,SAAV,WACMzB,KAAKlC,aACP,QAAkBkC,KAEtB,EAEgB,YAAA0B,KAAhB,W,sGAQwE,OAL1C,MAAxB1B,KAAKY,kBACPZ,KAAKzB,KAAO,UAIwD,GAAMoD,QAAQC,IAAI,CACtF5B,KAAK1C,oCAAoCuE,0BACzC7B,KAAK1C,oCAAoCwE,sBACzC9B,KAAK1C,oCAAoCyE,4B,cAHrC,kBAAgE,SAIpE,IAJKtD,EAAoB,KAAER,EAAgB,KAAEc,EAAmB,KAMlEiB,KAAKvB,qBAAuBA,EAC5BuB,KAAK/B,iBAAmBA,EACxB+B,KAAKjB,oBAAsBA,EAGvBiB,KAAKY,gBACI,GAAMZ,KAAKY,iBADpB,M,cACFoB,EAAW,S,aAEXA,EAAWhC,KAAKiC,oB,iBAIlB,OADAjC,KAAKkC,aAAaF,GAClB,GAAMhC,KAAKmC,+BAA+BnC,KAAKgC,SAASI,c,cAAxD,SAEApC,KAAK7B,WAAY,E,UAGT,YAAAkE,OAAV,WACErC,KAAKsC,UACP,EAMA,sBACc,kCAAmB,C,IADjC,W,MAEE,MAAO,UAAGtC,KAAKa,mBAAkB,cAAmB,QAAb,EAAAb,KAAKgC,gBAAQ,eAAEO,cAA2BvC,KAAKgC,SAASO,aAA1B,UACvE,E,gCAEA,sBACY,4CAA6B,C,IADzC,sBAEE,OAAOvC,KAAKvB,qBAAqB+D,OAAO,SAACC,GACvC,OAAAA,EAAIC,qBAAqBC,SAAS,EAAKlC,eAAeA,eAAtD,EAEJ,E,gCAEA,sBACY,2CAA4B,C,IADxC,sBAEE,MAAO,CAELmC,SAAU5C,KAAKgC,SAASa,SAGxBL,OAAQ,0CACRM,iBAAiB,EAEjBC,WAAY,IAAO,uBACnBC,MAAO,SAACC,GACN,EAAKC,sBAAsBD,EAAIE,SAAWF,EAAIG,SAChD,EAEJ,E,gCAEA,sBACY,oCAAqB,C,IADjC,W,MAEE,OAAOC,OAAOC,MAAkB,QAAb,EAAAtD,KAAKgC,gBAAQ,eAAEuB,oBAAqB,CAAC,EAC1D,E,gCAEA,sBACY,yCAA0B,C,IADtC,WAEE,OACoC,OAAlCvD,KAAKgC,SAASwB,iBAA4BxD,KAAKgC,SAASwB,kBAAoB,KAAwBC,UAExG,E,gCAEA,sBAAY,4CAA6B,C,IAAzC,WACE,QAAOzD,KAAKgC,SAASuB,mBACjBF,OAAOK,OAAO1D,KAAKgC,SAASuB,mBAAmBI,MAAM,SAACC,GAAQ,OAAQ,IAARA,CAAA,EAEpE,E,IAEA,SAA0CC,G,YACxC,GAAIA,E,IACF,IAAkB,QAAA7D,KAAK8D,uBAAqB,8BAAE,CAAzC,IAAMnE,EAAG,QACZK,KAAKgC,SAASuB,kBAAkB5D,IAA2C,CAC7E,C,2GAEA,IAAkB,QAAAK,KAAK8D,uBAAqB,8BAAjCnE,EAAG,QACZK,KAAKgC,SAASuB,kBAAkB5D,IAA2C,C,kGAGjF,E,gCAEA,sBAQY,6CAA8B,C,IAR1C,WASE,QAAOK,KAAKgC,SAASuB,mBACjBF,OAAOK,OAAO1D,KAAKgC,SAASuB,mBAAmBQ,KAAK,SAACH,GAAQ,OAAQ,IAARA,CAAA,KAC1DP,OAAOK,OAAO1D,KAAKgC,SAASuB,mBAAmBI,MAAM,SAACC,GAAQ,OAAQ,IAARA,CAAA,EAEvE,E,gCAEA,sBAAY,uCAAwB,C,IAApC,WACE,OAA6E,KAArE5D,KAAKS,eAAeuD,iBAAmB,KAAgBC,SACjE,E,gCAEA,sBAAY,wCAAyB,C,IAArC,WACE,OAA8E,KAAtEjE,KAAKS,eAAeuD,iBAAmB,KAAgBE,UACjE,E,gCAEA,sBAAY,4CAA6B,C,IAAzC,WACE,OAAkF,KAA1ElE,KAAKS,eAAeuD,iBAAmB,KAAgBG,cACjE,E,gCAEA,sBAAY,wCAAyB,C,IAArC,WACE,OAA8E,KAAtEnE,KAAKS,eAAeuD,iBAAmB,KAAgBI,UACjE,E,gCAEA,sBAAY,6CAA8B,C,IAA1C,WACE,OAAmF,KAA3EpE,KAAKS,eAAeuD,iBAAmB,KAAgBK,eACjE,E,gCAEA,sBAAY,kCAAmB,C,IAA/B,WACE,OAAwE,KAAhErE,KAAKS,eAAeuD,iBAAmB,KAAgBM,IACjE,E,gCAEA,sBAAY,+CAAgC,C,IAA5C,WACE,OAAqF,KAA7EtE,KAAKS,eAAeuD,iBAAmB,KAAgBO,iBACjE,E,gCAEA,sBAAY,kCAAmB,C,IAA/B,WACE,OAAwE,KAAhEvE,KAAKS,eAAeuD,iBAAmB,KAAgBQ,IACjE,E,gCAMU,YAAAC,kBAAV,SAA4BC,EAAmBC,GAA/C,WACEvD,aAAawD,QAAQvH,EAA2BiE,KAAKuD,UAAUH,IAE3DA,IAAaC,EACf3E,KAAKrC,UAAU6D,eAAe,YAC5B,QAAe,EACjB,IACUkD,GAAYC,IACtB,QAAkB3E,KAEtB,EAMQ,YAAA8E,gBAAR,WACE9E,KAAKgC,SAAS+C,cAAcC,KAAK,CAC/BC,SAAU,KACVC,WAAY,KAId,IAAMC,EAAuBnF,KAAKgC,SAAS+C,cAAcK,OAAS,EAClEpF,KAAKtB,oCAAoCyG,GAAwBnF,KAAKzC,cACnE8H,iBAAiBrF,KAAKgC,SAAS+C,cAAsBO,OAAOH,IAC5DI,UAAUvF,KAAKwF,mBAAmB9D,KAAK1B,OAG1CA,KAAKwF,oBACP,EAEQ,YAAAC,mBAAR,SAA2BC,GACzB,IAAMC,EAAQ3F,KAAKgC,SAAS+C,cAAca,QAAQF,GAC9CC,GAAS,GACX3F,KAAKgC,SAAS+C,cAAcc,OAAOF,EAAO,GAK5C3F,KAAK8F,6CAEL9F,KAAKwF,qBAGsC,IAAvCxF,KAAKgC,SAAS+C,cAAcK,QAC9BpF,KAAK8E,iBAET,EAEQ,YAAA5B,sBAAR,SAA8BC,EAAkBC,GAC9C,IAAM2C,EAAM/F,KAAKgC,SAAS+C,cAE1B,KAAI3B,EAAW,GAAKA,GAAY2C,EAAIX,QAAUjC,IAAaC,GAA3D,CAIA,IAAM4C,EAAOD,EAAIF,OAAO1C,EAAU,GAAG,GACrC4C,EAAIF,OAAOzC,EAAU,EAAG4C,EAHxB,CAIF,EAEQ,YAAAC,qBAAR,SACEC,EACAC,G,QAFF,OAMMC,EAAa,EAAAC,gBAEXC,EAAkB,SACtBC,EACA5G,EACA6G,G,QAEMC,EAAWpD,OAAOqD,UAAUC,eAAeC,KAAKJ,EAAM,SACtDK,EAAcxD,OAAOqD,UAAUC,eAAeC,KAAKJ,EAAM,YACzDM,EAAczD,OAAOqD,UAAUC,eAAeC,KAAKJ,EAAM,YACzD3C,EAAQ0C,EAAY5G,GAa1B,GAXIkH,IACFT,EAAQA,EACLW,OAAOpH,GACPqH,WACAC,KAAK,WAAM,OAAAT,EAAKQ,QAAL,IAGZP,IACFL,EAAQA,EAAMW,OAAOpH,GAAKuH,UAAUV,EAAKW,QAGtCL,EAAL,CAEA,IAAMM,EAAWZ,EAAKY,SAEhBC,EAAgBD,EAEtB,GAAIE,MAAMC,QAAQ1D,GAAQ,CACxB,IAAM,EAAeuD,E,IAGrB,IAAmB,QAAAvD,GAAK,8BAAE,CAArB,IAAMmC,EAAI,QACT,EAAKwB,SAASxB,IAChB,EAAKC,qBAAqBD,EAAM,EAEpC,C,kGAGA,IAAMyB,EAAM,EAAKlK,cAAcmK,mBAAmB7D,GAAO0B,UAAU,SAACoC,G,oBAClE,IAAqB,QAAAA,GAAO,8BAAE,CAAzB,IAAM9B,EAAM,Q,IAEf,IAAsB,kBAAAA,EAAO+B,UAAoB,8BAAE,CAA9C,IAAMA,EAAO,QACZ,EAAKJ,SAASI,IAChB,EAAAvB,gBAAgBwB,IAAID,EAExB,C,kGAGA,IAAME,EAAajE,EAAMkE,MAAMlC,EAAOF,MAAOE,EAAOF,MAAQE,EAAOmC,Y,IACnE,IAAoB,kBAAAF,IAAU,8BAAE,CAA3B,IAAMG,EAAK,QACV,EAAKT,SAASS,IAChB,EAAKhC,qBAAqBgC,EAAO,EAErC,C,kGACF,C,kGACF,GAEA,EAAKpJ,sCAAsCmG,KAAKyC,EAClD,MAAW,EAAKD,SAAS3D,IACvB,EAAKoC,qBAAqBpC,EAA2CwD,EAtC/C,CAwC1B,EAEMa,EAA2B,SAC/BvI,EACAwI,G,QAEMtE,EAAQqC,EAAMvG,GAEpB,GAAK2H,MAAMC,QAAQ1D,GAUnB,I,eAAS8B,GACP,IAEIK,EAFEoC,EAAQD,EAAYxC,GAY1B,OAPEK,EAFU,uBAARrG,EAEKkE,EAAMwE,KAAK,SAACC,GAAc,SAAKd,SAASc,IAAcA,EAAUC,KAAOH,EAAMI,WAAnD,GAI1B3E,EAAM8B,GAGV,EAAK6B,SAASxB,GAIf3C,OAAOqD,UAAUC,eAAeC,KAAKZ,EAAM,UAE7C,EAAKC,qBAAqBD,EAAM,CAC9BnC,MAAOuE,I,iBAKP/E,OAAOqD,UAAUC,eAAeC,KAAKwB,EAAO,aAAeA,EAAMhB,UACnE,EAAKnB,qBACHD,EACAoC,EAAMhB,W,YA5BHzB,EAAQ,EAAGA,EAAQwC,EAAY/C,OAAQO,I,EAAvCA,Q,IATP,IAAoB,QAAAwC,GAAW,8BAAE,CAA5B,IAAMC,EAAK,QACd9B,EAAgBJ,EAAOvG,EAAKyI,EAC9B,C,kGAuCJ,E,IAEA,IAAkB,QAAA/E,OAAOC,KAAK6C,IAAiD,8BAAE,CAA5E,IAAMxG,EAAG,QACN8I,EAAYtC,EAASxG,GACtB8I,IAIDnB,MAAMC,QAAQkB,GAChBP,EAAyBvI,EAAK8I,GAIhCnC,EAAgBJ,EAAOvG,EAAK8I,GAC9B,C,kGAEArC,EAAMsC,GAAGxC,EACX,EAEQ,YAAAyC,sBAAR,sBAIQxC,GADwBnG,KAAK8D,sBAClBT,OAAOC,KAAKtD,KAAKgC,UAAU4G,OAC1C,SAACC,EAAKlJ,G,QACAmJ,EAAkB,yEAAkEnJ,GACpFoJ,EAAmB,iEAA0DpJ,GAGrE,yBAARA,GAAmC,EAAKqJ,iCAC1CF,EAAkB,2EAClBC,EAAmB,oEAGrB,IAAME,EAAgB,CACpBC,cAAe,EAAKxL,KAAK4C,GAAGwI,GAC5BK,MAAO,EAAKzL,KAAK4C,GAAGyI,IAGtB,GAAY,sBAARpJ,EAA6B,CAE/BsJ,EAAc7B,SAAW,CAAC,E,IAC1B,IAAmC,UAAKtD,uBAAqB,8BAAE,CAA1D,IAAMsF,EAAoB,QAC7BN,EAAkB,yEAAkEnJ,EAAG,YAAIyJ,GAC3FL,EAAmB,iEAA0DpJ,EAAG,YAAIyJ,GAEpFH,EAAc7B,SAASgC,GAAwB,CAC7CF,cAAe,EAAKxL,KAAK4C,GAAGwI,GAC5BK,MAAO,EAAKzL,KAAK4C,GAAGyI,GAExB,C,kGACF,CAIA,OAFAF,EAAIlJ,GAAmCsJ,EAEhCJ,CACT,EACA,CAAC,IAKHxF,OAAOgG,QAAQ,EAAoBC,qCAAqClJ,QAAQ,SAAC,G,IAAA,SAACT,EAAG,KAAEkE,EAAK,KAC1FsC,EAASxG,IAAmC,IAAA4J,OAC1C,CAAC,EACDpD,EAASxG,GACTkE,EAEJ,GAGA,IAAM2F,EAA+D,GA6BrE,OA5BAxJ,KAAKvB,qBAAqB2B,QAAQ,SAACgC,GACjCA,EAAYqH,WAAWrJ,QAAQ,SAACsJ,GAC9BF,EAA2BxE,KAAK,CAC9BwD,YAAakB,EAAUlB,YACvBW,MAAOO,EAAUC,cACjBT,cAAe,EAAKxL,KAAK4C,GAAG,yCAA0C,CACpEqJ,cAAeD,EAAUC,gBAE3B3C,SAAU,CACR4C,aAAc,CAAC,wBACfC,QAAO,W,MACL,OAAgC,QAAzB,EAAA7J,KAAKgC,SAASI,mBAAW,eAAEA,eAAgBA,EAAYA,aAAesH,EAAU1C,QACzF,GAEFpE,SAAU,CACRgH,aAAc,CAAC,oBAAqB,oCACpCC,QAAO,W,MACL,OAAO7J,KAAKgC,SAASa,UA7jCL,KA6jC0C,QAAzB,EAAA7C,KAAKgC,SAASI,mBAAW,eAAEA,YAC9D,IAGN,EACF,GACA+D,EAAS2D,mBAAqBN,EAEd,IAAI,IAAsBxJ,KAAMmG,EAAUnG,KAAKzC,eACpCwM,OAG7B,EAEQ,YAAAC,qBAAR,WACEhK,KAAKgC,SAASiI,mBAAmBjF,KAAK,MAGtC,IAAMkF,EAA4BlK,KAAKgC,SAASiI,mBAAmB7E,OAAS,EAC5EpF,KAAKrB,wCAAwCuL,GAA6BlK,KAAKzC,cAC5E8H,iBAAiBrF,KAAKgC,SAASiI,mBAA2B3E,OAAO4E,IACjE3E,UAAUvF,KAAKwF,mBAAmB9D,KAAK1B,OAG1CA,KAAKwF,oBACP,EAEQ,YAAA2E,wBAAR,SAAgCxE,GAC9B3F,KAAKgC,SAASiI,mBAAmBpE,OAAOF,EAAO,GAI/C3F,KAAKoK,iDAELpK,KAAKwF,qBAG2C,IAA5CxF,KAAKgC,SAASiI,mBAAmB7E,QACnCpF,KAAKgK,sBAET,EAEQ,YAAAK,OAAR,sBACE,GAAIrK,KAAK7B,UAGP6B,KAAKe,SAAS,KAAM,WAOtB,GAFAf,KAAKwF,qBAEDxF,KAAK9B,QAAS,CAEhB,IAAIoM,OAAoB,EACpBC,OAAqB,EACrBC,EAAqC,KAEzC,OAAQxK,KAAKzB,MACX,IAAK,OACH+L,EAAuB,qEACvBC,EAAwB,sEACxBC,EAAUxK,KAAKyK,4BACbzK,KAAK0K,uBAAuB1K,KAAK2K,qBAAsB3K,KAAKgC,WAE9D,MAEF,IAAK,SACHsI,EAAuB,iEACvBC,EAAwB,kEACxB,MAEF,QACE,MAAM,IAAIK,MAAM,wBAAiB5K,KAAKzB,OAG1CyB,KAAKxC,aACFqN,KAAK7K,KAAKhC,eACV8M,QAAQ,IAAc,CACrBlL,OAAQ0K,EACRS,YAAa,sBACbC,QAAST,EACTC,QAASA,EACTzJ,SAAU,SAACkK,GAET,EAAKzN,aAAa0N,KAAK,EAAKlN,eAExBiN,GAEF,EAAKlK,SAAS,KAAM,KAIxB,IAEDoK,YAAY,CAAEC,KAAM,WACzB,MAEEpL,KAAKe,SAAS,KAAM,KAExB,EAEQ,YAAAsK,UAAR,SAAkBC,GAChBtL,KAAKX,qBAAuBiM,CAC9B,EAGQ,YAAA9F,mBAAA,WACNxF,KAAK9B,SAAW8B,KAAKuL,wBAAwBvL,KAAK2K,qBAAsB3K,KAAKgC,SAC/E,EAEQ,YAAAwJ,qBAAR,WACExL,KAAKgC,SAASyJ,gBAAkB,IAClC,EAEQ,YAAAxJ,kBAAR,WAsEE,MArEmC,CACjC8C,cAAe,GACflC,UAAU,EACV6I,YAAY,EACZzB,mBAAoB,GACpB0B,cAAe,KACfC,kBAAmB,KACnBC,OAAQ,CACNC,UAAW,KACXC,aAAc,KACdC,cAAc,EACdC,qBAAsB,KACtBC,oBAAqB,KACrB3I,kBAAmB,CACjB4I,8BAA8B,EAC9BC,0BAA0B,EAC1BC,yBAAyB,EACzBC,+BAA+B,EAC/BC,2BAA2B,EAC3BC,0BAA0B,GAE5BpK,YAAa,KACboB,gBAAiB,KACjBiJ,oBAAoB,EACpBC,uBAAuB,EACvBC,sBAAuB,KACvBC,cAAe,KACfC,uBAAuB,EACvBC,sBAAsB,EACtBC,wBAAwB,EACxBC,0BAA0B,EAC1BC,mBAAmB,EACnB1K,aAAc,GACd2K,gBAAgB,EAChBC,cAAc,EACdC,WAAY,KACZC,4BAA6B,CAC3BC,MAAM,EACNC,SAAS,EACTC,WAAW,GAEbC,8BAA+B,CAC7BH,MAAM,EACNC,SAAS,EACTC,WAAW,GAEbE,aAAc,GACdC,qBAAqB,EACrBC,YAAa,KACbC,gBAAiB,CACfC,oBAAoB,EACpBC,oBAAoB,GAEtBC,kBAAkB,EAClBC,iBAAkB,KAClBC,oBAAqB,KACrBC,4BAA6B,CAC3Bb,MAAM,EACNC,SAAS,EACTC,WAAW,IAGfY,OAAO,EACPtE,mBAAoB,CAAC,EACrBuE,WAAYC,OAAOC,iBACnBC,WAAYF,OAAOC,iBACnB9C,gBAAiB,KAIrB,EAEQ,YAAAgD,0BAAR,SAAkCC,GAChC,MAAO,UAAGA,EAA0BC,sBAAqB,aAAKD,EAA0BE,uBAAsB,aAAKF,EAA0BG,yBAAwB,aAAKH,EAA0BI,mBACtM,EAEQ,YAAAC,qCAAR,SAA6CvG,G,MACrCwG,EAA6B,QAArB,EAAAhP,KAAKxB,wBAAgB,eAAEsL,mBAC/BmF,EAAe,qDAA8CzG,GAEnE,IAAKwG,IAAU1H,MAAMC,QAAQyH,GAC3B,MAAM,IAAIpE,MAAMqE,GAGlB,IAAMC,EAAoBF,EAAM3G,KAAK,SAAC8G,GAAS,OAAAA,EAAK3G,cAAgBA,CAArB,GAC/C,IAAK0G,EACH,MAAM,IAAItE,MAAMqE,GAGlB,OAAOC,CACT,EAEQ,YAAAE,8BAAR,SACEtF,GAEA,OAAOA,EAAmBlB,OACxB,SAACC,EAAKwG,GAGJ,GAAIA,EAAEC,SAAWD,EAAEC,QAAQlK,OAAS,EAAG,CACrC,IAAMmK,EAAiBF,EAAEC,QAAQjH,KAAK,SAACmH,GAAQ,OAAAA,EAAIC,WAAaJ,EAAExL,KAAnB,GAC/CgF,EAAIwG,EAAE9G,IAAMgH,EAAiBA,EAAeG,YAAc,IAC5D,MACE7G,EAAIwG,EAAE9G,IAAkB,OAAZ8G,EAAExL,MAAiB,KAAOyB,OAAO+J,EAAExL,OAEjD,OAAOgF,CACT,EACA,CAAC,EAEL,EAQQ,YAAA8G,mCAAR,WACE,MAAO,CACL7D,UAAW9L,KAAKgC,SAAS8J,UACzBC,aAA6C,OAA/B/L,KAAKgC,SAAS+J,aAAwB,KAAO6D,SAAS5P,KAAKgC,SAAS+J,aAAc,IAChGhH,eAAe,OAAU/E,KAAKgC,SAAS+C,eACvCiH,aAAchM,KAAKgC,SAASgK,aAC5BC,qBAAsBjM,KAAKgC,SAASiK,qBACpChC,mBAAoBjK,KAAKgC,SAASiI,mBAC/BzH,OAAO,SAACqN,GAAW,OAAW,OAAXA,CAAA,GACnBC,IAAI,SAACD,GAAW,OAAAA,EAAQE,gBAAR,GACnBpE,eAAe,OAAU3L,KAAKgC,SAAS2J,eACvCC,kBAAmB5L,KAAKgC,SAAS4J,kBACjCM,oBAAqBlM,KAAKgC,SAASkK,oBACnC3I,mBAAmB,OAAUvD,KAAKgC,SAASuB,mBAC3CnB,YAAapC,KAAKgC,SAASI,YAAaA,YACxCoB,gBAAiBxD,KAAKgC,SAASwB,gBAC/BiJ,mBAAoBzM,KAAKgC,SAASyK,mBAClCC,sBAAuB1M,KAAKgC,SAAS0K,sBACrCC,sBAAuB3M,KAAKgC,SAAS2K,sBACrCC,cAAe5M,KAAKgC,SAAS4K,cAC7BC,sBAAuB7M,KAAKgC,SAAS6K,sBACrCC,qBAAsB9M,KAAKgC,SAAS8K,qBACpCC,uBAAwB/M,KAAKgC,SAAS+K,uBACtCC,yBAA0BhN,KAAKgC,SAASgL,yBACxCC,kBAAmBjN,KAAKgC,SAASiL,kBACjCnD,mBAAoB9J,KAAKoP,8BAA8BpP,KAAKgC,SAAS8H,oBACrEvH,aAAcvC,KAAKgC,SAASO,aAC5B2K,eAAgBlN,KAAKgC,SAASkL,eAC9BC,aAAcnN,KAAKgC,SAASmL,aAC5B6C,kBAAmBhQ,KAAKgC,SAASyJ,gBAAkBzL,KAAKgC,SAASyJ,gBAAgB+C,WAAa,KAC9FyB,aAAcjQ,KAAKgC,SAASoL,WAAapN,KAAKgC,SAASoL,WAAW8C,qBAAuB,KACzF7C,4BAA6B,CAC3BC,KAAMtN,KAAKgC,SAASmO,mBACpB5C,QAASvN,KAAKgC,SAASoO,sBACvB5C,UAAWxN,KAAKgC,SAASqO,yBAE3B5C,8BAA+B,CAC7BH,KAAMtN,KAAKgC,SAASsO,qBACpB/C,QAASvN,KAAKgC,SAASuO,wBACvB/C,UAAWxN,KAAKgC,SAASwO,2BAE3B9C,aAAc1N,KAAKgC,SAAS0L,aAC5BC,oBAAqB3N,KAAKgC,SAAS2L,oBACnCC,YAAa5N,KAAKgC,SAAS4L,YAC3BC,gBAAiB,CACfC,mBAAoB9N,KAAKgC,SAAS8L,mBAClCC,mBAAoB/N,KAAKgC,SAAS+L,oBAEpCC,iBAAkBhO,KAAKgC,SAASgM,iBAChCC,iBAAkBjO,KAAKgC,SAASiM,iBAChCC,oBAAqBlO,KAAKgC,SAASkM,oBACnCC,4BAA6B,CAC3Bb,KAAMtN,KAAKgC,SAASyO,mBACpBlD,QAASvN,KAAKgC,SAAS0O,sBACvBlD,UAAWxN,KAAKgC,SAAS2O,yBAG/B,EAOQ,YAAAC,oCAAR,SACEC,EACAC,GAGA,GAAuB,OAAnBA,EACF,OAAO,KAGT,IAAKD,EAAqBvB,SAAmD,IAAxCuB,EAAqBvB,QAAQlK,OAEhE,OAAO0L,EAIT,IAAMvB,EAAiBsB,EAAqBvB,QAAQjH,KAAK,SAACmH,GAAQ,OAAAA,EAAIE,cAAgBoB,CAApB,GAElE,IAAKvB,EACH,MAAM,IAAI3E,MACR,iBAAUkG,EAAc,iDAAyCD,EAAqBlH,cAAa,MAGvG,OAAO4F,EAAeE,QACxB,EAEQ,YAAA/E,uBAAR,SAA+BqG,EAAuBC,GACpD,OAAO,OAAqBhR,KAAKiR,qBAAqBF,GAAI/Q,KAAKiR,qBAAqBD,GACtF,EAEQ,YAAAE,+BAAR,SACEC,EACA/O,GAFF,WAIE,OACEA,aAAW,EAAXA,EAAaqH,WAAWqG,IAAI,SAACX,G,MAAS,OACpC5G,GAAI4G,EAAK3G,YACT4I,KAAMjC,EAAKxF,cACX2F,QAASH,EAAKG,QACd5F,UAAWyF,EACXtL,MAAOsN,EACH,EAAKP,oCAAoCzB,EAAoC,QAA9B,EAAAgC,EAAahC,EAAK3G,oBAAY,QAAI,MACjF,KACJ6I,SAAUlC,EAAKkC,SACfrK,SAAUmI,EAAKnI,S,KACV,EAEX,EAEQ,YAAAsK,qBAAR,WACEtR,KAAKuR,gDACL,EAAAlL,gBAAgBwB,IAAI7H,KAAKgC,UACzBhC,KAAKiG,qBAAqBjG,KAAKgC,SAAUhC,KAAKxB,iBAChD,EAEQ,YAAAgT,kCAAR,SAA0C3N,GAExC,OAAOA,GAAS7D,KAAKyR,4BAA8BzR,KAAK0R,8BAC1D,EAEQ,YAAAlK,SAAR,SAAiB3D,GACf,OAAiB,OAAVA,GAAmC,iBAAVA,IAAuByD,MAAMC,QAAQ1D,EACvE,EAKQ,YAAA3B,aAAR,SAAqBF,G,UAEnBhC,KAAKsC,WAGLtC,KAAK9B,SAAU,EAGf,IAAIkE,EAA2C,KAC/C,GAAmC,MAA/BJ,EAAS6J,OAAOzJ,eAClBA,EAAoG,QAAtF,EAAApC,KAAKvB,qBAAqB4J,KAAK,SAACsJ,GAAO,OAAAA,EAAGvP,cAAgBJ,EAAS6J,OAAOzJ,WAAnC,UAA+C,QAAI,MAEtG,MAAM,IAAIwI,MAAM,uBAAgB5I,EAAS6J,OAAOzJ,YAAW,mCAA2BJ,EAASqM,aAOnG,IAAMtJ,GAAgB,OAAU/C,EAAS+C,eACzC/E,KAAKgC,SAAW,CACd8J,UAAW9J,EAAS6J,OAAOC,UAC3BC,cAA0C,QAA5B,EAAA/J,EAAS6J,OAAOE,oBAAY,eAAE6F,aAAc,KAC1D7M,cAAeA,EACflC,SAAUb,EAASa,SACnBmJ,aAAchK,EAAS6J,OAAOG,aAC9BC,qBAAsBjK,EAAS6J,OAAOI,qBACtChC,oBAAoB,OAAUjI,EAASiI,oBACvC0B,cAAe3J,EAAS2J,eACsD,QAAzE,EAAA5G,EAAcsD,KAAK,SAAC0I,GAAM,OAAAA,EAAE9L,UAAYjD,EAAS2J,cAAe1G,QAAtC,UAA+C,QAC1E,KACJ2G,kBAAmB5J,EAAS4J,kBAC5BM,oBAAqBlK,EAAS6J,OAAOK,oBACrC3I,mBAAmB,OAAUvB,EAAS6J,OAAOtI,mBAC7CnB,YAAaA,EACboB,gBAAiBxB,EAAS6J,OAAOrI,gBACjCiJ,mBAAoBzK,EAAS6J,OAAOY,mBACpCC,sBAAuB1K,EAAS6J,OAAOa,sBACvCC,sBAAuB3K,EAAS6J,OAAOc,sBACvCyB,MAAOpM,EAASoM,MAChBxB,cAAe5K,EAAS6J,OAAOe,cAC/BC,sBAAuB7K,EAAS6J,OAAOgB,sBACvCC,qBAAsB9K,EAAS6J,OAAOiB,qBACtCC,uBAAwB/K,EAAS6J,OAAOkB,uBACxCC,yBAA0BhL,EAAS6J,OAAOmB,yBAC1CC,kBAAmBjL,EAAS6J,OAAOoB,kBACnCnD,mBAAoB9J,KAAKkR,+BAA+BlP,EAAS8H,mBAAoB1H,GACrFiM,WAAYrM,EAASqM,WACrBG,WAAYxM,EAASwM,WACrBjM,aAAcP,EAAS6J,OAAOtJ,aAC9B2K,eAAgBlL,EAAS6J,OAAOqB,eAChCC,aAAcnL,EAAS6J,OAAOsB,aAC9B1B,gBAAiBzJ,EAASyJ,gBAC1B2B,WAAYpL,EAAS6J,OAAOuB,WAC5B+C,mBAAoBnO,EAAS6J,OAAOwB,4BAA4BC,KAChE8C,sBAAuBpO,EAAS6J,OAAOwB,4BAA4BE,QACnE8C,wBAAyBrO,EAAS6J,OAAOwB,4BAA4BG,UACrE8C,qBAAsBtO,EAAS6J,OAAO4B,8BAA8BH,KACpEiD,wBAAyBvO,EAAS6J,OAAO4B,8BAA8BF,QACvEiD,0BAA2BxO,EAAS6J,OAAO4B,8BAA8BD,UACzEE,aAAc1L,EAAS6J,OAAO6B,aAC9BC,oBAAqB3L,EAAS6J,OAAO8B,oBACrCC,YAAa5L,EAAS6J,OAAO+B,YAC7BE,mBAAoB9L,EAAS6J,OAAOgC,gBAAgBC,mBACpDC,mBAAoB/L,EAAS6J,OAAOgC,gBAAgBE,mBACpDC,iBAAkBhM,EAAS6J,OAAOmC,iBAClCC,iBAAkBjM,EAAS6J,OAAOoC,iBAClCC,oBAAqBlM,EAAS6J,OAAOqC,oBACrCuC,mBAAoBzO,EAAS6J,OAAOsC,4BAA4Bb,KAChEoD,sBAAuB1O,EAAS6J,OAAOsC,4BAA4BZ,QACnEoD,wBAAyB3O,EAAS6J,OAAOsC,4BAA4BX,WAGvExN,KAAK2K,sBAAuB,OAAU3K,KAAKgC,UAG3ChC,KAAKjC,oBAAsBiC,KAAK2I,wBAChC3I,KAAKxB,iBAAmBwB,KAAKjC,oBAAoB8T,WAGjD7R,KAAK8R,iCAGL9R,KAAKsR,sBACP,EAGc,YAAAnP,+BAAd,SAA6CC,G,0GAC3CpC,KAAK5B,qCAAsC,EAE3C4B,KAAKlB,mCAAmC+G,OAAO,IAE3CzD,aAAW,EAAXA,EAAa2P,cACf,GAAM/R,KAAK1C,oCACR0U,gEACChS,KAAKS,eAAeA,eACpBT,KAAKU,gBACLV,KAAKW,aACLyB,EAAYA,aAEb6P,KAAK,SAACC,G,MAGCC,EAAqBD,EAAQ1P,OACjC,SAAC4P,GACC,OAAAA,EAAEzD,sBAAwB,EAAK7N,yBAC9BsR,EAAEzD,uBAAyB,EAAK7N,yBAC/BsR,EAAEvD,yBAA2B,EAAKhO,kBAFpC,IAKJ,IAAK/B,oCAAmCkG,KAAI,eAAImN,IAAkB,GACpE,IAnBA,M,OACF,S,wBAqBFnS,KAAK5B,qCAAsC,E,UAGrC,YAAAiU,+BAAR,SAAuC3N,EAAmBC,G,YAExD,IAAmC,QAAA3E,KAAK8D,uBAAqB,8BAAE,CAA1D,IAAMsF,EAAoB,QAC7BpJ,KAAKC,qBAAqBqS,SAAS,CACjCC,OAAQvS,KAAKgC,SAASuB,kBACtBiP,aAAcpJ,GAElB,C,kGACF,EAEQ,YAAAqJ,sBAAR,SAA8BC,GAA9B,WAKE,GAJAA,EAAMC,kBAEN3S,KAAKhB,cAAgBgB,KAAKhB,aAErBgB,KAAKhB,eAINgB,KAAKZ,0BAAT,CAIA,IAAMwT,EAASF,EAAMG,OACfC,EAAOF,EAAOG,wBAGpBC,sBAAsB,WACfJ,GAAW,EAAK1T,kBAIrB,EAAKD,sBAAwB,gBAAS6T,EAAKG,MAAK,oBAAYH,EAAKI,IAAG,uDACtE,EAZA,CAaF,EAEQ,YAAAC,6BAAR,WACEnT,KAAKxC,aACFqN,KAAK7K,KAAKhC,eACV8M,QAAQ,IAA0B,CACjC/J,SAAUf,KAAKoT,wBAAwB1R,KAAK1B,QAE7CmL,YAAY,CAAEC,KAAM,WACzB,EAEQ,YAAAG,wBAAR,SAAgCwF,EAAuBC,GACrD,OAAoD,IAA7ChR,KAAK0K,uBAAuBqG,EAAGC,GAAG5L,MAC3C,EAEQ,YAAAU,2CAAR,WACE9F,KAAKqT,8CAEL,IAAK,IAAIC,EAAI,EAAGA,EAAItT,KAAKgC,SAAS+C,cAAcK,OAAQkO,IACtDtT,KAAKtB,oCAAoCsG,KACvChF,KAAKzC,cACF8H,iBAAiBrF,KAAKgC,SAAS+C,cAAsBO,OAAOgO,IAC5D/N,UAAUvF,KAAKwF,mBAAmB9D,KAAK1B,OAGhD,EAEQ,YAAAoK,+CAAR,WACEpK,KAAKuT,kDAEL,IAAK,IAAID,EAAI,EAAGA,EAAItT,KAAKgC,SAASiI,mBAAmB7E,OAAQkO,IAC3DtT,KAAKrB,wCAAwCqG,KAC3ChF,KAAKzC,cACF8H,iBAAiBrF,KAAKgC,SAASiI,mBAA2B3E,OAAOgO,IACjE/N,UAAUvF,KAAKwF,mBAAmB9D,KAAK1B,OAGhD,EAEQ,YAAAoT,wBAAR,SAAgC3H,GAE9BzL,KAAKxC,aAAa0N,KAAKlL,KAAKhC,eAEvByN,IAKLzL,KAAKgC,SAAUyJ,gBAAkBA,EACnC,EAEc,YAAA+H,KAAd,W,wCAAmBC,G,6BAAA,IAAAA,IAAAA,EAAA,M,0CACjB,OAAIzT,KAAK3B,SAEP,KAEF2B,KAAK3B,UAAW,EAChB2B,KAAKhB,cAAe,EAEH,GAAMgB,KAAKC,qBAAqBqS,a,OACjD,IADiB,SAA4CnL,MAI3D,OAFAnH,KAAK0T,+BACL1T,KAAK3B,UAAW,EAChB,IAQF,OAFImM,EAAqC,KAEjCxK,KAAKzB,MACX,IAAK,OACH+L,EAAuB,oEACvBC,EAAwB,qEACxBC,EAAUxK,KAAKyK,4BACbzK,KAAK0K,uBAAuB1K,KAAK2K,qBAAsB3K,KAAKgC,WAE9D,MAEF,IAAK,SACHsI,EAAuB,gEACvBC,EAAwB,iEACxB,MAEF,QACE,MAAM,IAAIK,MAAM,wBAAiB5K,KAAKzB,O,OAI1CyB,KAAKxC,aACFqN,KAAK7K,KAAKhC,eACV8M,QAAQ,IAAc,CACrBlL,OAAQ0K,EACRS,YAAa,qBACbC,QAAST,EACTC,QAASA,EACTzJ,SAAU,SAAO4S,GAAsB,oC,qEAErC3T,KAAKxC,aAAa0N,KAAKlL,KAAKhC,eAExB2V,GACF3T,KAAK1B,mBAAoB,EAGnBsV,EAAkB5T,KAAK2P,qCAC7B,GAAM3P,KAAKe,SAAS6S,EAAiBH,GAAgBI,MAAM,SAACC,GAE1DC,QAAQD,MAAM,4BAA6BA,GAC3C,EAAKrW,aAAaqW,MAChB,IAAI,IACF,EAAKpW,KAAK4C,GAAG,mFACb,EAAK5C,KAAK4C,GAAG,mFAKjB,EAAKhC,mBAAoB,EACzB,EAAKD,UAAW,CAClB,KAlBE,M,cAKF,S,aAgBA2B,KAAK3B,UAAW,E,mCAIrB8M,YAAY,CAAEC,KAAM,Y,UAGjB,YAAAsI,6BAAR,W,QACQM,EAAchU,KAAKiU,cACzB,GAAKD,EAAL,CAIA,IAAME,EAASF,EAAYG,iBAA8B,oB,WAI9CC,GACT,IAAMC,EAAwBD,aAAK,EAALA,EAAOE,cAAc,qBACnD,GAAID,EAAuB,CAGzB,IAAME,EAAiB,WACrBF,EAAsBE,eAAe,CACnCC,SAAU,SACVC,MAAO,SACPC,OAAQ,WAEZ,EAEA,GAAI,EAAK5W,WAAY,CACnB,IAAM6W,EAAQP,EAAMQ,aAAa,eACjC,EAAKvJ,UAAUsJ,GACf,EAAKhX,UAAU6D,eAAe+S,EAChC,MACEA,I,aAIJ,C,aAtBF,IAAoB,QAAAL,GAAM,oB,YAAV,SAAU,Y,kGAN1B,CA8BF,EAUQ,YAAApC,+BAAR,W,sBAAA,OAGEzO,OAAOC,KAAKtD,KAAKgC,UAAU5B,QAAQ,SAACT,GAClC,EAAKf,4BAA4BoG,KAC/B,EAAKzH,cAAc8H,iBAAiB,EAAKrD,SAAUrC,GAAK4F,UAAU,EAAKC,mBAAmB9D,KAAK,KAIjG,IAAMmT,EAAU,EAAKrW,iBAAkBmB,GACjC6G,EAAOc,MAAMC,QAAQsN,GAAWA,EAAQ,GAAKA,EAC/CrO,GAAQA,EAAKsO,UACf,EAAKlW,4BAA4BoG,KAC/B,EAAKzH,cAAc8H,iBAAiB,EAAKrD,SAAUrC,GAAK4F,UAAU,SAACb,EAAUC,GAC3E6B,EAAKsO,SAAUlO,KAAK,EAAMlC,EAAUC,EACtC,GAGN,G,IAIA,IAAmB,QAAA3E,KAAKgC,SAAS8H,oBAAkB,8BAAE,CAAhD,IAAMqF,EAAI,QAEbnP,KAAKpB,4BAA4BoG,KAC/BhF,KAAKzC,cAAc8H,iBAAiB8J,EAAM,SAAS5J,UAAUvF,KAAKwF,mBAAmB9D,KAAK1B,OAE9F,C,sGAIA,IAAmB,QAAAA,KAAKgC,SAAS+C,eAAa,8BAAnCoK,EAAI,QAEbnP,KAAKpB,4BAA4BoG,KAC/BhF,KAAKzC,cAAc8H,iBAAiB8J,EAAM,cAAc5J,UAAUvF,KAAKwF,mBAAmB9D,KAAK1B,O,kGAKnG,GAAIA,KAAKgC,SAASuB,kBAAmB,CACnC,IAAMO,EAAwBT,OAAOC,KAAKtD,KAAKgC,SAASuB,mB,WAG7C5D,GACT,EAAKf,4BAA4BoG,KAC/B,EAAKzH,cACF8H,iBAAiB,EAAKrD,SAASuB,kBAAmB5D,GAClD4F,UAAU,EAAKC,mBAAmB9D,KAAK,KAI5C,IAAM8E,EACM,QADE,EAAkG,QAAnG,EAAsB,QAArB,IAAKhI,wBAAgB,eAAE+E,yBAA2E,eAC5G6D,gBAAQ,eAAGzH,GACX6G,GAAQA,EAAKsO,UACf,EAAKlW,4BAA4BoG,KAC/B,EAAKzH,cACF8H,iBAAiB,EAAKrD,SAASuB,kBAAmB5D,GAClD4F,UAAU,SAACb,EAAUC,GACpB6B,EAAKsO,SAAUlO,KAAK,EAAMlC,EAAUC,EACtC,G,aAhBR,IAAkB,QAAAb,GAAqB,8B,EAAzB,Q,kGAoBhB,CAIA9D,KAAKoK,iDACLpK,KAAK8F,4CACP,EAEQ,YAAAiP,WAAR,SAAmBC,IACjB,QAAWhV,KAAMgV,EACnB,EAEQ,YAAA1S,SAAR,W,MACEtC,KAAKiV,sCACLjV,KAAKuT,kDACLvT,KAAKqT,8CACLrT,KAAKuR,gDAEmB,QAAxB,EAAAvR,KAAKjC,2BAAmB,SAAEmX,UAC1BlV,KAAKjC,oBAAsB,KAEvBiC,KAAKgC,WACP,EAAAqE,gBAAgBwB,IAAI7H,KAAKgC,UACzBhC,KAAKC,qBAAqBkV,aAAanV,KAAKgC,WAG9ChC,KAAKxB,iBAAmB,IAC1B,EAEQ,YAAAyW,oCAAR,W,MACkC,QAAhC,EAAAjV,KAAKpB,mCAA2B,SAAEwB,QAAQ,SAACgV,GAAM,OAAAA,EAAEF,SAAF,GACjDlV,KAAKpB,4BAA8B,EACrC,EAEQ,YAAA2U,gDAAR,WACEvT,KAAKrB,wCAAwCyB,QAAQ,SAACgV,GAAM,OAAAA,EAAEF,SAAF,GAC5DlV,KAAKrB,wCAA0C,EACjD,EAEQ,YAAA0U,4CAAR,WACErT,KAAKtB,oCAAoC0B,QAAQ,SAACgV,GAAM,OAAAA,EAAEF,SAAF,GACxDlV,KAAKtB,oCAAsC,EAC7C,EAEQ,YAAA6S,8CAAR,WACEvR,KAAKnB,sCAAsCuB,QAAQ,SAACgV,GAAM,OAAAA,EAAEF,SAAF,GAC1DlV,KAAKnB,sCAAwC,EAC/C,EAMQ,YAAAoS,qBAAR,SAA6B/K,G,kBAC3B,OAAO,EAAP,KACKA,GAAK,CAER9D,YAA2C,QAA9B,EAAiB,QAAjB,EAAA8D,EAAM9D,mBAAW,eAAEA,mBAAW,QAAI,KAC/CgL,WAAkD,QAAtC,EAAgB,QAAhB,EAAAlH,EAAMkH,kBAAU,eAAE8C,4BAAoB,QAAI,KAGtD1M,gBAAiB0C,EAAM1C,gBAC6D,QAAhF,EAAAxD,KAAK/B,iBAAiBoK,KAAK,SAACgN,GAAO,OAAAA,EAAG7R,kBAAoB0C,EAAM1C,eAA7B,UAA6C,eAAE8R,YAClF,KACJ7J,gBAAoD,QAAnC,EAAqB,QAArB,EAAAvF,EAAMuF,uBAAe,eAAElJ,oBAAY,QAAI,KAGxD0H,mBAAoB/D,EAAM+D,mBAAmB6F,IAAI,SAACD,GAAM,MAAK,OAAwB,QAAxB,EAAAA,aAAM,EAANA,EAAQE,wBAAgB,QAAI,IAAI,GAC7FxM,kBAC6B,MAA3B2C,EAAM3C,kBACF,KACCF,OAAOC,KAAK4C,EAAM3C,mBAA+DqF,OAAO,SAACC,EAAKlJ,GAE7F,OADAkJ,EAAIlJ,GAAOuG,EAAM3C,kBAAmB5D,GAC7BkJ,CACT,EAAG,CAAC,GACViB,mBAAoB5D,EAAM4D,mBAAmBlB,OAC3C,SAACC,EAAKsG,GAEJ,OADAtG,EAAIsG,EAAK5G,IAAM4G,EAAKtL,MACbgF,CACT,EACA,CAAC,GAKH8C,cAAsC,MAAvBzF,EAAMyF,cAAwBrK,KAAKuD,UAAUqB,EAAMyF,eAAiB,KACnF5G,cAAezD,KAAKuD,UAAUqB,EAAMnB,gBAExC,EASQ,YAAA0F,4BAAR,SAAoCD,GAApC,WACE,OAAOA,EACJsF,IAAI,SAACyF,G,kBAIgB,kBAAhBA,EAAOC,OACTD,EAAS,EAAH,KACDA,GAAM,CACTE,OACEF,EAAOE,QAAmC,iBAAlBF,EAAOE,OAC1BnU,KAAKC,MAAMgU,EAAOE,QAChB3F,IAAI,SAAC4F,GAAW,SAAKC,gCAAgCD,EAArC,GAChBE,KAAK,OACR,KACNC,MACEN,EAAOM,OAAiC,iBAAjBN,EAAOM,MACzBvU,KAAKC,MAAMgU,EAAOM,OAChB/F,IAAI,SAAC4F,GAAW,SAAKC,gCAAgCD,EAArC,GAChBE,KAAK,OACR,QAKU,kBAAhBL,EAAOC,OACTD,EAAS,EAAH,KACDA,GAAM,CACTE,OACEF,EAAOE,QAAmC,iBAAlBF,EAAOE,OAC3B,EAAKE,gCAAgCrU,KAAKC,MAAMgU,EAAOE,SACvD,KACNI,MACEN,EAAOM,OAAiC,iBAAjBN,EAAOM,MAC1B,EAAKF,gCAAgCrU,KAAKC,MAAMgU,EAAOM,QACvD,QAKV,IAAMC,EAAc,EAAKtX,iBAAkB+W,EAAOC,MAC9CO,EAAWzO,MAAMC,QAAQuO,GAAeA,EAAY,GAAKA,EAE7D,GAAIP,EAAOC,KAAMQ,WAAW,wBAG1B,GADMC,EAAQV,EAAOC,KAAMS,MAAM,6BACtB,CACT,IAAM,EAAKrG,SAASqG,EAAM,GAAI,IAGxBC,EAAkB,EAAKzX,qBAC1B0X,QAAQ,SAAC/T,GAAgB,OAAAA,EAAYqH,UAAZ,GACzBpB,KAAK,SAAC8G,GAAS,OAAAA,EAAK3G,cAAgB,CAArB,GAClB+M,EAAOC,KAAO,kBAAWU,aAAe,EAAfA,EAAiBvM,eAC1C4L,EAAOE,OACoB,iBAAlBF,EAAOE,OAC6D,QAAvE,EAAwB,QAAxB,EAAAS,aAAe,EAAfA,EAAiB5G,eAAO,eAAEjH,KAAK,SAACmH,GAAQ,OAAAA,EAAIC,WAAa8F,EAAOE,MAAxB,UAA+B,eAAE/F,YACzE6F,EAAOE,OACbF,EAAOM,MACmB,iBAAjBN,EAAOM,MAC4D,QAAtE,EAAwB,QAAxB,EAAAK,aAAe,EAAfA,EAAiB5G,eAAO,eAAEjH,KAAK,SAACmH,GAAQ,OAAAA,EAAIC,WAAa8F,EAAOM,KAAxB,UAA8B,eAAEnG,YACxE6F,EAAOM,KACf,OACK,GAAIN,EAAOC,KAAMQ,WAAW,uBAAwB,CAEzD,IAAMC,EACN,GADMA,EAAQV,EAAOC,KAAMS,MAAM,+BACtB,CACT,IAAMtQ,EAAQiK,SAASqG,EAAM,GAAI,IACjCV,EAAOC,KAAO,8BAAuB7P,EAAQ,GAE7C,IAAMyQ,EAA0B,EAAKtX,mCAAmCuJ,KACtE,SAAC+J,GAAM,OAAAA,EAAErC,mBAAqBwF,EAAOE,MAA9B,GAETF,EAAOE,OAASW,EACZ,EAAK3H,0BAA0B2H,GAC/Bb,EAAOE,OAEX,IAAMY,EAAyB,EAAKvX,mCAAmCuJ,KACrE,SAAC+J,GAAM,OAAAA,EAAErC,mBAAqBwF,EAAOM,KAA9B,GAETN,EAAOM,MAAQQ,EACX,EAAK5H,0BAA0B4H,GAC/Bd,EAAOM,KACb,CACF,MAAO,GAAe,QAAX,EAAAN,EAAOC,YAAI,eAAEQ,WAAW,sBAAuB,CAExDD,EAAgC,QAArB,IAAKvX,wBAAgB,eACX,kBAErB,IAAM8X,EAAkBf,EAAOC,KAAKzN,MAAM,IACtCuO,GAAmBP,GAAYA,EAAS3O,WAE1CmO,EAAS,EAAH,KACDA,GAAM,CACTC,MAAwC,QAAlC,EAAAO,EAAS3O,SAASkP,UAAgB,eAAEpN,gBAAiBqM,EAAOC,OAGxE,MAAWO,GAAYA,EAAS7M,gBAC9BqM,EAAS,EAAH,KACDA,GAAM,CACTC,KAAMO,EAAS7M,iBAInB,OAAOqM,CACT,GACCgB,KAAK,SAACxF,EAAGC,GAAC,QAAK,OAAO,QAAN,EAAAD,EAAEyE,YAAI,QAAI,IAAIgB,cAAoB,QAAN,EAAAxF,EAAEwE,YAAI,QAAI,GAAG,EAC9D,EAEQ,YAAAG,gCAAR,SAAwCc,GACtC,OAA8B,OAA1BA,EAAaxR,SACR,gBAASwR,EAAavR,YAExB,WAAIuR,EAAaxR,SAAQ,aAAKwR,EAAavR,WACpD,EAt5DwB,EAAAoE,oCAIpB,CACFwC,UAAW,CACTlJ,UAAU,EACVoE,UAAU,EACV0P,UAAW,KAEb3K,aAAc,CACZnJ,SAAU,CACRgH,aAAc,CAAC,wBACfC,QAAO,W,MACL,QAAiC,QAAzB,EAAA7J,KAAKgC,SAASI,mBAAW,eAAEuU,qBACrC,GAEFC,SAAU,CACRhN,aAAc,CAAC,qBACfC,QAAO,WACL,OAAI7J,KAAKgC,SAASa,SACkC,OAA3C7C,KAAK2K,qBAAqBoB,aAC7B,EACA6D,SAAS5P,KAAK2K,qBAAqBoB,aAAc,IAEhD,CACT,GAEF8K,SAAU,IACV7P,SAAU,CACR4C,aAAc,CAAC,wBACfC,QAAO,W,QACL,OAAsD,QAA/C,EAAyB,QAAzB,EAAA7J,KAAKgC,SAASI,mBAAW,eAAEuU,4BAAoB,QACxD,IAGJ5R,cAAe,CACbnC,SAAU,CACRgH,aAAc,CAAC,qBACfC,QAAO,WACL,OAAO7J,KAAKgC,SAASa,QACvB,GAEFmE,UAAU,EACVI,SAAU,CACRlC,WAAY,CACV8B,UAAU,EACVG,MAAK,SAACtD,GAEJ,IAAMiT,EAAc9W,KAAKgC,SAAS+C,cAAc+K,IAAI,SAACpK,GAAW,OAAAA,EAAOR,UAAP,GAChE,OAAiB,OAAVrB,GAAkBiT,EAAYlR,QAAQ/B,KAAWiT,EAAYC,YAAYlT,EAClF,KAINmI,aAAc,CACZpJ,SAAU,CACRgH,aAAc,CAAC,qBACfC,QAAO,WACL,OAAO7J,KAAKgC,SAASa,QACvB,GAEFiS,SAAQ,SAACpQ,EAAmBC,GACrBD,IAEH1E,KAAKgC,SAASiK,qBAAuBjM,KAAK2K,qBAAqBsB,qBAEnE,GAEFA,qBAAsB,CACpBrJ,SAAU,CACRgH,aAAc,CAAC,oBAAqB,yBACpCC,QAAO,WACL,OAAO7J,KAAKgC,SAASa,WAAa7C,KAAKgC,SAASgK,YAClD,GAEFhF,SAAU,CACR4C,aAAc,CAAC,yBACfC,QAAO,WACL,OAAO7J,KAAKgC,SAASgK,YACvB,IAGJ/B,mBAAoB,CAClBrH,SAAU,CACRgH,aAAc,CAAC,qBACfC,QAAO,WACL,OAAO7J,KAAKgC,SAASa,QACvB,GAEFmE,SAAU,CACR4C,aAAc,CAAC,qCACfC,QAAO,W,QACL,OAA8C,QAAvC,EAAyB,QAAzB,EAAA7J,KAAKgC,SAASI,mBAAW,eAAE2P,oBAAY,QAChD,IAGJpG,cAAe,CACb/I,UAAU,EACVoE,UAAU,GAEZ4E,kBAAmB,CACjBhJ,SAAU,CACRgH,aAAc,CAAC,oBAAqB,sDACpCC,QAAO,W,MACL,OAAO7J,KAAKgC,SAASa,YAAsC,QAAzB,EAAA7C,KAAKgC,SAASI,mBAAW,eAAE4U,8BAC/D,GAEFhQ,UAAU,GAEZkF,oBAAqB,CACnBtJ,UAAU,EACVoE,UAAU,GAEZzD,kBAAmB,CACjBX,SAAU,CACRgH,aAAc,CAAC,8BACfC,QAAO,WACL,OAAO7J,KAAKyR,0BACd,GAEFzK,SAAU,CACR4C,aAAc,CAAC,6BAA8B,kCAC7CC,QAAO,WACL,OAAQ7J,KAAKyR,6BAA+BzR,KAAK0R,8BACnD,GAEFtK,SAAU,CACR+E,6BAA8B,CAC5B2I,SAAU,EAAoBpO,UAAU2L,+BACxClL,MAAO,EAAoBT,UAAU8K,mCAEvCpF,yBAA0B,CACxB0I,SAAU,EAAoBpO,UAAU2L,+BACxClL,MAAO,EAAoBT,UAAU8K,mCAEvCnF,wBAAyB,CACvByI,SAAU,EAAoBpO,UAAU2L,+BACxClL,MAAO,EAAoBT,UAAU8K,mCAEvClF,8BAA+B,CAC7BwI,SAAU,EAAoBpO,UAAU2L,+BACxClL,MAAO,EAAoBT,UAAU8K,mCAEvCjF,0BAA2B,CACzBuI,SAAU,EAAoBpO,UAAU2L,+BACxClL,MAAO,EAAoBT,UAAU8K,mCAEvChF,yBAA0B,CACxBsI,SAAU,EAAoBpO,UAAU2L,+BACxClL,MAAO,EAAoBT,UAAU8K,qCAI3CpP,YAAa,CACXQ,SAAU,CACRgH,aAAc,CAAC,WAAY,kBAC3BC,QAAO,WACL,OAAO7J,KAAK3B,WAAa2B,KAAKgC,SAASoM,KACzC,GAEI0G,SAAQ,SAACpQ,EAAgCC,G,8GAMzCA,aAAQ,EAARA,EAAUvC,gBAAgBsC,aAAQ,EAARA,EAAUtC,aAApC,MAEF,GAAMpC,KAAKmC,+BAA+BuC,GAAUuN,KAAK,YACnDtN,aAAQ,EAARA,EAAUoN,iBAAiBrN,aAAQ,EAARA,EAAUqN,cAEvC,EAAK/P,SAASiI,mBAAmBpE,OAAO,KAC9BlB,aAAQ,EAARA,EAAUoN,gBAAgBrN,aAAQ,EAARA,EAAUqN,eAG9C,EAAK/P,SAASiI,mBAAmBjF,KAAK,KAE1C,I,OATA,S,wBAcEL,aAAQ,EAARA,EAAUgS,yBAAyBjS,aAAQ,EAARA,EAAUiS,wBAC/C3W,KAAKgC,SAAS+J,aAAe,OAI3BpH,aAAQ,EAARA,EAAUsS,qBAAqBvS,aAAQ,EAARA,EAAUuS,kBAC3CjX,KAAKgC,SAAS+C,cAAcc,OAAO,KACzBlB,aAAQ,EAARA,EAAUsS,oBAAoBvS,aAAQ,EAARA,EAAUuS,mBAElDjX,KAAK8E,mBAKHH,aAAQ,EAARA,EAAUqS,kCAAkCtS,aAAQ,EAARA,EAAUsS,iCACxDhX,KAAKgC,SAAS4J,kBAAoB,OAKhCjH,aAAQ,EAARA,EAAUvC,gBAAgBsC,aAAQ,EAARA,EAAUtC,eAChC8U,EAAyBlX,KAAKoP,8BAA8BpP,KAAKgC,SAAS8H,oBAChF9J,KAAKgC,SAAS8H,mBAAmBjE,OAAO,IACxC,EAAA7F,KAAKgC,SAAS8H,oBAAmB9E,KAAI,eAChChF,KAAKkR,+BAA+BgG,EAAwBxS,KAAS,KAK5E1E,KAAKsR,uB,WAGT5E,sBAAuB,CACrB9J,SAAU,CACRgH,aAAc,CAAC,qBACfC,QAAO,WACL,OAAO7J,KAAKgC,SAASa,QACvB,GAEFiS,SAAQ,SAACpQ,EAAmBC,GAEtBD,GACF1E,KAAKgC,SAAS6K,uBAAwB,EACtC7M,KAAKgC,SAAS8K,sBAAuB,GAGrC9M,KAAKgC,SAAS2K,sBAAwB3M,KAAK2K,qBAAqBgC,qBAEpE,GAEFA,sBAAuB,CACrB/J,SAAU,CACRgH,aAAc,CAAC,iCAAkC,qBACjDC,QAAO,WACL,OAAQ7J,KAAKgC,SAAS0K,uBAAyB1M,KAAKgC,SAASa,QAC/D,GAEFmE,SAAU,CACR4C,aAAc,CAAC,kCACfC,QAAS,WACP,OAAO7J,KAAKgC,SAAS0K,qBACvB,IAGJE,cAAe,CACbhK,SAAU,CACRgH,aAAc,CAAC,qBACfC,QAAO,WACL,OAAO7J,KAAKgC,SAASa,QACvB,GAEFmE,UAAU,GAEZ6F,sBAAuB,CACrBjK,SAAU,CACRgH,aAAc,CAAC,iCACfC,QAAO,WAEL,OAAO7J,KAAKgC,SAASa,UAAY7C,KAAKgC,SAAS8K,oBACjD,IAGJA,qBAAsB,CACpBlK,SAAU,CACRgH,aAAc,CAAC,oBAAqB,8BACpCC,QAAO,WACL,OAAO7J,KAAKgC,SAASa,UAAY7C,KAAKgC,SAASiL,iBACjD,GAEF6H,SAAQ,SAACpQ,EAAmBC,GAEtBD,IACF1E,KAAKgC,SAAS6K,uBAAwB,EAE1C,GAEFE,uBAAwB,CACtBnK,SAAU,CACRgH,aAAc,CAAC,6BACfC,QAAO,WACL,OAAQ7J,KAAKgC,SAASgM,gBACxB,GAEFhH,UAAU,GAEZgG,yBAA0B,CACxBpK,SAAU,CACRgH,aAAc,CAAC,6BACfC,QAAO,WACL,OAAQ7J,KAAKgC,SAASgM,gBACxB,GAEFhH,UAAU,GAEZiG,kBAAmB,CACjBrK,SAAU,CACRgH,aAAc,CAAC,qBACfC,QAAO,WACL,OAAO7J,KAAKgC,SAASa,QACvB,GAEFiS,SAAQ,SAACpQ,EAAmBC,GAEtBD,IACF1E,KAAKgC,SAAS6K,uBAAwB,EACtC7M,KAAKgC,SAAS8K,sBAAuB,EAEzC,EACA9F,UAAU,GAEZzE,aAAc,CACZK,SAAU,CACRgH,aAAc,CAAC,qBACfC,QAAO,WACL,OAAO7J,KAAKgC,SAASa,QACvB,GAEFmE,UAAU,EACV0P,UAAW,KAEbvJ,aAAc,CACZvK,SAAU,CACRgH,aAAc,CAAC,qBACfC,QAAO,WACL,OAAO7J,KAAKgC,SAASa,QACvB,GAEFmE,UAAU,GAEZyE,gBAAiB,CACfzE,UAAU,GAEZ0G,aAAc,CACZ9K,SAAU,CACRgH,aAAc,CAAC,qBACfC,QAAO,WACL,OAAO7J,KAAKgC,SAASa,QACvB,GAEFmE,UAAU,EACV0P,UAAW,KAEbvG,mBAAoB,CAClBvN,SAAU,CACRgH,aAAc,CAAC,8BACfC,QAAO,WACL,OAAO7J,KAAKyR,0BACd,GAEFzK,UAAU,GAEZoJ,sBAAuB,CACrBxN,SAAU,CACRgH,aAAc,CAAC,8BACfC,QAAO,WACL,OAAO7J,KAAKyR,0BACd,GAEFzK,UAAU,GAEZqJ,wBAAyB,CACvBzN,SAAU,CACRgH,aAAc,CAAC,8BACfC,QAAO,WACL,OAAO7J,KAAKyR,0BACd,GAEFzK,UAAU,GAEZsJ,qBAAsB,CACpB1N,SAAU,CACRgH,aAAc,CAAC,8BACfC,QAAO,WACL,OAAO7J,KAAKyR,0BACd,IAGJlB,wBAAyB,CACvB3N,SAAU,CACRgH,aAAc,CAAC,8BACfC,QAAO,WACL,OAAO7J,KAAKyR,0BACd,IAGJjB,0BAA2B,CACzB5N,SAAU,CACRgH,aAAc,CAAC,8BACfC,QAAO,WACL,OAAO7J,KAAKyR,0BACd,IAGJ9D,oBAAqB,CACnBmH,SAAQ,SAACpQ,EAAmBC,GACrBD,IAEH1E,KAAKgC,SAAS4L,YAAc5N,KAAK2K,qBAAqBiD,YAE1D,GAEFA,YAAa,CACXhL,SAAU,CACRgH,aAAc,CAAC,gCACfC,QAAO,WACL,OAAQ7J,KAAKgC,SAAS2L,mBACxB,GAEF3G,SAAU,CACR4C,aAAc,CAAC,gCACfC,QAAO,WACL,OAAO7J,KAAKgC,SAAS2L,mBACvB,IAGJG,mBAAoB,CAClBlL,SAAU,CACRgH,aAAc,CAAC,8BACfC,QAAO,WACL,OAAO7J,KAAKyR,0BACd,GAEFzK,UAAU,GAEZ+G,mBAAoB,CAClBnL,SAAU,CACRgH,aAAc,CAAC,8BACfC,QAAO,WACL,OAAO7J,KAAKyR,0BACd,GAEFzK,UAAU,GAEZgH,iBAAkB,CAChB8G,SAAQ,SAACpQ,EAAmBC,GACtBD,EAEG1E,KAAKgC,SAASkM,sBACjBlO,KAAKgC,SAASkM,oBAAsBlO,KAAKgC,SAASO,eAIpDvC,KAAKgC,SAAS+K,uBAAyB/M,KAAK2K,qBAAqBoC,uBACjE/M,KAAKgC,SAASgL,yBAA2BhN,KAAK2K,qBAAqBqC,yBACnEhN,KAAKgC,SAASiM,iBAAmBjO,KAAK2K,qBAAqBsD,iBAC3DjO,KAAKgC,SAASkM,oBAAsBlO,KAAK2K,qBAAqBuD,oBAElE,GAEFD,iBAAkB,CAChBrL,SAAU,CACRgH,aAAc,CAAC,6BACfC,QAAO,WACL,OAAQ7J,KAAKgC,SAASgM,gBACxB,GAEFhH,UAAU,EACV0P,UAAW,KAEbxI,oBAAqB,CACnBtL,SAAU,CACRgH,aAAc,CAAC,6BACfC,QAAO,WACL,OAAQ7J,KAAKgC,SAASgM,gBACxB,GAEFhH,SAAU,CACR4C,aAAc,CAAC,6BACfC,QAAO,WACL,OAAO7J,KAAKgC,SAASgM,gBACvB,GAEF0I,UAAW,MA3iBE,GAAhB,K,0DAIgB,GAAhB,K,4DACgB,GAAhB,K,+DACgB,GAAhB,K,8DACgB,GAAhB,K,gBAAyC,mB,EAAA,oBAAP/U,SAAAA,SAAO,W,sCACzB,GAAhB,K,kEACgB,GAAhB,K,uEACgB,GAAhB,K,6DACgB,GAAhB,K,0DA8pBD,IAAC,QAAa,qBAAsB,yB,2FAKpC,IAAC,QAAa,uBAAwB,kB,oGAOtC,IAAC,QAAa,qB,oGAiBd,IAAC,QAAa,8B,6FAKd,IAAC,QAAa,4B,mGAyBd,IAAC,QACC,0DACA,sDACA,qDACA,2DACA,uDACA,uD,uGAsaM,IADP,OAAS,IAAK,CAAEwV,SAAS,EAAMC,UAAU,I,0HAhpCZ,MAb/B,QACC,gGAED,IAAAC,c,uBA6jBmF,mB,OAAA,IAAnC,UAAmC,SAC5C,mBAD4C,OAC5C,IAAb,YAAa,SACF,mBADE,OACF,IAAZ,UAAY,SACE,mBADF,OACE,IAAd,YAAc,SAClB,mBADkB,OAClB,IAAJ,EAAAC,MAAA,EAAAA,MAAI,SACU,mBADV,OACU,IAAT,EAAAC,WAAA,EAAAA,WAAS,SAC4B,mBAD5B,OAC4B,IAA3B,EAAAC,6BAAA,EAAAA,6BAA2B,YAzjB/CjX,E,CAAb,E,0rDCnIA,aACE,WACUkX,EACAC,EACAC,EACAC,EACAC,EACAC,GALA,KAAAL,8CAAAA,EACA,KAAAC,4BAAAA,EACA,KAAAC,mCAAAA,EACA,KAAAC,4CAAAA,EACA,KAAAC,+BAAAA,EACA,KAAAC,wCAAAA,CACP,C,kBA6JL,O,EArKaC,EAmBE,YAAAC,mBAAb,W,qBAAmCrW,QAAO,W,qCACxC,OAAI,EAAoCsW,gBAC/B,CAAP,EAAO,EAAoCA,kBAGzC,EAAoCC,yBAIxC,EAAoCA,uBAA0B,6B,yDAE3C,O,sBAAA,GAAMlY,KAAK2X,mCAAmCQ,QAAQlG,KAAK,SAACmG,GAAM,OAAAA,EAAEC,IAAF,I,OAEjF,GAAe,QAFTC,EAAS,UAIb,MAAM,IAAI1N,MAAM,+CAIlB,OADA,EAAoCqN,gBAAkBK,EAC/C,CAAP,EAAOA,G,OAIP,M,WADA,EAAoCJ,uBAAyB,KACvD,E,uBAjBD,CAAP,EAAO,EAAoCA,wB,MAwBlC,YAAAK,wBAAb,W,qBAAwC5W,QAAO,W,qCAC7C,OAAI,EAAoC6W,qBAC/B,CAAP,EAAO,EAAoCA,uBAGzC,EAAoCC,8BAIxC,EAAoCA,4BAA+B,6B,yDAEhD,O,sBAAA,GAAMzY,KAAK8X,wCAAwCK,QAAQlG,KAAK,SAACmG,GAAM,OAAAA,EAAEC,IAAF,I,OAEtF,GAAe,QAFTC,EAAS,UAIb,MAAM,IAAI1N,MAAM,qDAIlB,OADA,EAAoC4N,qBAAuBF,EACpD,CAAP,EAAOA,G,OAIP,M,WADA,EAAoCG,4BAA8B,KAC5D,E,uBAjBD,CAAP,EAAO,EAAoCA,6B,MAwBlC,YAAA3W,oBAAb,W,qBAAoCH,QAAO,W,qCACzC,OAAI,EAAoC1D,iBAC/B,CAAP,EAAO,EAAoCA,mBAGzC,EAAoCya,0BAIxC,EAAoCA,wBAA2B,6B,yDAE5C,O,sBAAA,GAAM1Y,KAAK0X,4BAA4BS,QAAQlG,KAAK,SAACmG,GAAM,OAAAA,EAAEC,IAAF,I,OAE1E,GAAe,QAFTC,EAAS,UAIb,MAAM,IAAI1N,MAAM,gDAIlB,OADA,EAAoC3M,iBAAmBqa,EAChD,CAAP,EAAOA,G,OAIP,M,WADA,EAAoCI,wBAA0B,KACxD,E,uBAjBD,CAAP,EAAO,EAAoCA,yB,MAwBlC,YAAA1G,gEAAb,SACEvR,EACAC,EACAC,EACAyB,G,qBACCT,QAAO,W,yDAQO,OAPTgX,EAA6D,CACjElY,eAAc,EACdC,gBAAe,EACfC,aAAY,EACZyB,YAAW,GAGE,GAAMpC,KAAK4X,4CAA4CO,MAAMQ,GAAe1G,KAAK,SAACmG,GAAM,OAAAA,EAAEC,IAAF,I,OAEvG,GAAe,QAFTC,EAAS,UAIb,MAAM,IAAI1N,MAAM,4EAGlB,MAAO,CAAP,EAAO0N,G,MAGI,YAAAzW,wBAAb,W,qBAAwCF,QAAO,W,uDAC7C,OAAI,EAAoClD,qBAC/B,CAAP,EAAO,EAAoCA,sBAGzC,EAAoCma,4BAC/B,CAAP,EAAO,EAAoCA,6BAK7C,IAFMC,EAAU7Y,KAAKyX,8CAA8CU,QAAQlG,KAAK,SAACmG,GAAM,OAAAA,EAAEC,IAAF,IAEzEpG,KAAK,SAACqG,GAClB,GAAe,OAAXA,EAEF,MAAM,IAAI1N,MAAM,qDAGlB,EAAoCgO,4BAA8BC,CACpE,I,OAEA,OATA,SASO,CAAP,EAAOA,G,MAGI,YAAA9W,uBAAb,W,qBAAuCJ,QAAO,W,uDAC7B,SAAM3B,KAAK6X,+BAA+BM,QAAQlG,KAAK,SAACmG,GAAM,OAAAA,EAAEC,IAAF,I,OAE7E,GAAe,QAFTC,EAAS,UAIb,MAAM,IAAI1N,MAAM,oDAGlB,MAAO,CAAP,EAAO0N,G,MAzJM,EAAAE,qBAA8D,KAC9D,EAAAC,4BAA8E,KAC9E,EAAAR,gBAAoD,KACpD,EAAAC,uBAAoE,KACpE,EAAAja,iBAAsD,KACtD,EAAAya,wBAAsE,KACtE,EAAAja,qBAAsD,KACtD,EAAAma,4BAAsE,KAjBvC,E,mUAAA,GAD/C,IAAAvB,c,uBAG2G,mB,OAAA,IAAjD,UAAiD,SACxC,mBADwC,OACxC,IAA3B,UAA2B,SACc,mBADd,OACc,IAAlC,UAAkC,SACkB,mBADlB,OACkB,IAA3C,UAA2C,SAC1B,mBAD0B,OAC1B,IAA9B,UAA8B,SACkB,mBADlB,OACkB,IAAvC,UAAuC,YAP/EU,E,CAAb,E","sources":["webpack://iadviser/./src/routes/app-admin/question-collection-editor/question-collection-editor.ts?56e8","webpack://iadviser/./src/routes/app-admin/question-collection-editor/components/question-editor/question-editor.ts","webpack://iadviser/./src/routes/app-admin/question-collection-editor/question-collection-lookup-data.ts"],"sourcesContent":["module.exports = function(cb) {\n\trequire.ensure([], function(require) {\n\t\tcb(require(\"!!../../../../node_modules/ts-loader/index.js??ruleSet[1].rules[4].use[0]!./question-collection-editor.ts\"));\n\t}, \"question-collection-editor\");\n}","import { BindingEngine, computedFrom } from 'aurelia-binding';\r\nimport { autoinject } from 'aurelia-dependency-injection';\r\nimport { TaskQueue } from 'aurelia-framework';\r\nimport { I18N } from 'aurelia-i18n';\r\nimport { PLATFORM } from 'aurelia-pal';\r\nimport { useView } from 'aurelia-templating';\r\nimport { bindable } from 'aurelia-typed-observable-plugin';\r\nimport { ValidationController, ValidationControllerFactory, ValidationRules } from 'aurelia-validation';\r\nimport { ColumnDef } from 'components/forms/ia-select-table/ia-select-table';\r\nimport { ModalService } from 'components/modal/modal-service';\r\nimport {\r\n QuestionDocumentSection,\r\n QuestionFeature,\r\n type IQuestionAddOrUpdate,\r\n type IQuestionAnswer,\r\n type IQuestionCalculationSource,\r\n type IQuestionCollectionType,\r\n type IQuestionDisplayOnDocument,\r\n type IQuestionDisplayType,\r\n type IQuestionDisplayTypeAttribute,\r\n type IQuestionDisplayTypeAttributeOption,\r\n type IQuestionDocumentSection,\r\n type IQuestionFull,\r\n type IQuestionReportCode,\r\n type IRelatedQuestion,\r\n} from 'endpoints/admin/qce/shared-models';\r\nimport { features } from 'feature-support';\r\nimport { merge } from 'lodash';\r\nimport type { SortableOptions } from 'resources/attributes/sortable';\r\nimport { debounce } from 'resources/decorators/debounce-decorator';\r\nimport { FormValidationRenderer } from 'resources/form-validation-renderer';\r\nimport { IaToastMessage, IaToastService } from 'resources/services/ia-toast-service';\r\nimport type { ScrollDirection } from 'resources/tab-scroll';\r\nimport { disposeScrollTabs, initScrollTabs, scrollTabs } from 'resources/tab-scroll';\r\nimport { deepClone, getObjectDifferences, ObjectDifference } from 'resources/utilities/object-utils';\r\nimport {\r\n BuiltEntityMetadata,\r\n BuiltPropertyMetadata,\r\n EntityMetadata,\r\n EntityMetadataBuilder,\r\n EntityMetadataDefinition,\r\n IPropertyMetadataDefinition,\r\n} from 'resources/view-model-entity-metadata';\r\nimport { PostSaveAction } from '../../question-collection-editor';\r\nimport { QuestionCollectionLookupDataService } from '../../question-collection-lookup-data';\r\nimport { ChangesModal } from '../changes-modal/changes-modal';\r\nimport { FindRelatedQuestionModal } from '../find-related-question-modal/find-related-question-modal';\r\nimport styles from './question-editor.css';\r\n\r\ninterface IQuestionPropertyMetadataEntry extends IPropertyMetadataDefinition<\r\n IQuestionPropertyMetadataEntry,\r\n QuestionEditorModal\r\n> {\r\n attributeId?: number;\r\n qualifiedName?: string;\r\n}\r\n\r\ninterface IQuestionEditModelAttribute {\r\n id: number;\r\n name: string;\r\n options?: IQuestionDisplayTypeAttributeOption[];\r\n attribute: IQuestionDisplayTypeAttribute;\r\n value: string | number | null;\r\n synopsis: string;\r\n required: boolean;\r\n}\r\n\r\n/**\r\n * UI-centric shape used by the modal while editing a question.\r\n *\r\n * This intentionally differs from the API contracts so bindings can work with\r\n * richer objects (for example selected display type/report code objects) and\r\n * so transient UI concerns can be represented in a single model.\r\n */\r\ninterface IQuestionEditModel extends Record {\r\n alertText: string | null;\r\n answerLength: string | null;\r\n answerOptions: IQuestionAnswer[];\r\n approved: boolean;\r\n autorateFlag: boolean;\r\n autorateQuestionName: string | null;\r\n calculationSources: Array;\r\n defaultAnswer: IQuestionAnswer | null;\r\n defaultAnswerText: string | null;\r\n defaultScheduleText: string | null;\r\n displayOnDocument: IQuestionDisplayOnDocument;\r\n displayType: IQuestionDisplayType | null;\r\n documentSection: QuestionDocumentSection | null;\r\n hideOnWebQuoteFlag: boolean;\r\n interfaceQuestionFlag: boolean;\r\n interfaceQuestionName: string | null;\r\n isNew: boolean;\r\n lmiIdentifier: string | null;\r\n mandatoryOnPolicyFlag: boolean;\r\n mandatoryOnQuoteFlag: boolean;\r\n mandatoryOnWebFormFlag: boolean;\r\n onlyDisplayOnWebFormFlag: boolean;\r\n premiumRatingFlag: boolean;\r\n questionAttributes: IQuestionEditModelAttribute[];\r\n questionId: number | null;\r\n questionNo: number;\r\n questionText: string;\r\n quickQuoteFlag: boolean;\r\n readOnlyFlag: boolean;\r\n relatedQuestion: IRelatedQuestion | null;\r\n reportCode: IQuestionReportCode | null;\r\n scheduleAnswerBold: boolean;\r\n scheduleAnswerItalics: boolean;\r\n scheduleAnswerUnderline: boolean;\r\n scheduleQuestionBold: boolean;\r\n scheduleQuestionItalics: boolean;\r\n scheduleQuestionUnderline: boolean;\r\n scheduleText: string;\r\n summaryQuestionFlag: boolean;\r\n summaryText: string | null;\r\n suppressIfNullFlag: boolean;\r\n suppressIfZeroFlag: boolean;\r\n useOnWebFormFlag: boolean;\r\n webFormAlertText: string | null;\r\n webFormQuestionText: string | null;\r\n wizardQuestionBold: boolean;\r\n wizardQuestionItalics: boolean;\r\n wizardQuestionUnderline: boolean;\r\n}\r\n\r\ntype ChildModel = T extends Array ? U : T extends Record ? T : never;\r\n\r\nconst DropDownDisplayTypeId = 7;\r\nexport const TabbedModeLocalStorageKey = 'admin:qce:questionEditor:tabbedMode';\r\n\r\nconst enum QuestionEditorTab {\r\n QuestionDetails = 'questionDetails',\r\n AnswerOptions = 'answerOptions',\r\n DocumentOptions = 'documentOptions',\r\n FormOptions = 'formOptions',\r\n WebOptions = 'webOptions',\r\n}\r\n\r\n@useView(\r\n PLATFORM.moduleName('routes/app-admin/question-collection-editor/components/question-editor/question-editor.html'),\r\n)\r\n@autoinject()\r\n/**\r\n * View-model for creating/editing a question in the question collection editor.\r\n *\r\n * Responsibilities:\r\n * - Making all question properties available for editing (in association with the accompanying view), as appropriate\r\n * - Enforcing property editability and required status based on question state and collection features\r\n * - Tracking dirty status and prompting the user to save changes if they attempt to close with unsaved changes\r\n * - Generating an API-friendly update payload to send to the server on save\r\n */\r\nexport class QuestionEditorModal {\r\n @bindable public callback!: (\r\n updatedQuestion: IQuestionAddOrUpdate | null,\r\n postSaveAction: PostSaveAction | null,\r\n ) => Promise;\r\n @bindable public collectionId!: number;\r\n @bindable public collectionSetId!: number;\r\n @bindable public collectionType!: IQuestionCollectionType;\r\n @bindable public questionPromise!: Promise;\r\n @bindable public questionSequenceNo!: number;\r\n @bindable public questionGroupSequenceNo!: number;\r\n @bindable public readOnlyMode: boolean = true;\r\n @bindable public tabbedMode = false;\r\n\r\n private builtEntityMetadata: BuiltEntityMetadata | null = null;\r\n private dialogModalId = 'secondaryModal';\r\n private documentSections: IQuestionDocumentSection[] = [];\r\n private editorContent!: HTMLElement;\r\n private isDirty: boolean = false;\r\n private isLoading: boolean = true;\r\n private isLoadingPossibleCalculationSources: boolean = false;\r\n private isSaving: boolean = false;\r\n private isWaitingOnSubmit = false;\r\n private mode: 'create' | 'edit' = 'edit';\r\n private propertyMetadata: EntityMetadata | null = null;\r\n private question!: IQuestionEditModel;\r\n private questionDisplayTypes: IQuestionDisplayType[] = [];\r\n private questionInitialState!: IQuestionEditModel;\r\n private questionObserversAnswerOptionsIndex: Array<{ dispose: () => void }> = [];\r\n private questionObserversCalculationSourceIndex: Array<{ dispose: () => void }> = [];\r\n private questionObserversProperties: Array<{ dispose: () => void }> = [];\r\n private questionObserversValidationCollection: Array<{ dispose: () => void }> = [];\r\n private questionPossibleCalculationSources: IQuestionCalculationSource[] = [];\r\n private questionReportCodes: IQuestionReportCode[] = [];\r\n private saveMenuOpen = false;\r\n private saveMenuFallbackStyle = '';\r\n private saveMenuElement: HTMLElement | null = null;\r\n private styles = styles;\r\n private supportsAnchorPositioning = features.supportsAnchorPositioning;\r\n private tabUI!: HTMLElement;\r\n private validationController: ValidationController;\r\n\r\n // Tab Scroll Properties\r\n private currentlySelectedTab = QuestionEditorTab.QuestionDetails;\r\n private isLeftChevronDisabled = false;\r\n private isRightChevronDisabled = false;\r\n private tabClass = '.question-editor-tab';\r\n\r\n // Configuration\r\n private columnsCalculationSources: ColumnDef[] = [\r\n {\r\n key: 'sourceGroupSequenceNo',\r\n header: '',\r\n sortable: false,\r\n searchable: false,\r\n cssClass: styles['column--calculation-source-group-sequence-no'],\r\n },\r\n {\r\n key: 'sourceGroupDisplayName',\r\n header: 'questionCollectionEditor.sourceGroupDisplayNameHeader',\r\n sortable: false,\r\n searchable: false,\r\n cssClass: styles['column--calculation-source-group-name'],\r\n },\r\n {\r\n key: 'sourceQuestionSequenceNo',\r\n header: '',\r\n sortable: false,\r\n searchable: false,\r\n cssClass: styles['column--calculation-source-question-sequence-no'],\r\n },\r\n {\r\n key: 'sourceQuestionText',\r\n header: 'questionCollectionEditor.sourceQuestionTextHeader',\r\n sortable: false,\r\n searchable: true,\r\n cssClass: styles['column--calculation-source-question-text'],\r\n },\r\n ];\r\n\r\n // QuestionEditModel metadata configuration\r\n private static readonly questionEditModelMetadataDefinition: EntityMetadataDefinition<\r\n IQuestionEditModel,\r\n QuestionEditorModal,\r\n IQuestionPropertyMetadataEntry\r\n > = {\r\n alertText: {\r\n disabled: false,\r\n required: false,\r\n maxLength: 2000,\r\n },\r\n answerLength: {\r\n disabled: {\r\n computedFrom: ['question.displayType'],\r\n compute() {\r\n return !this.question.displayType?.hasFreeTextComponent;\r\n },\r\n },\r\n minValue: {\r\n computedFrom: ['question.approved'],\r\n compute() {\r\n if (this.question.approved) {\r\n return this.questionInitialState.answerLength === null\r\n ? 0\r\n : parseInt(this.questionInitialState.answerLength, 10);\r\n }\r\n return 0;\r\n },\r\n },\r\n maxValue: 500,\r\n required: {\r\n computedFrom: ['question.displayType'],\r\n compute() {\r\n return this.question.displayType?.hasFreeTextComponent ?? false;\r\n },\r\n },\r\n },\r\n answerOptions: {\r\n disabled: {\r\n computedFrom: ['question.approved'],\r\n compute() {\r\n return this.question.approved;\r\n },\r\n },\r\n required: true,\r\n children: {\r\n answerText: {\r\n required: true,\r\n valid(value: string) {\r\n // answer text must not be null and must be unique among the answer options\r\n const answerTexts = this.question.answerOptions.map((option) => option.answerText);\r\n return value !== null && answerTexts.indexOf(value) === answerTexts.lastIndexOf(value);\r\n },\r\n },\r\n },\r\n },\r\n autorateFlag: {\r\n disabled: {\r\n computedFrom: ['question.approved'],\r\n compute() {\r\n return this.question.approved;\r\n },\r\n },\r\n onChange(newValue: boolean, oldValue: boolean) {\r\n if (!newValue) {\r\n // if autorateFlag is being set to false, reset autorate question name\r\n this.question.autorateQuestionName = this.questionInitialState.autorateQuestionName;\r\n }\r\n },\r\n },\r\n autorateQuestionName: {\r\n disabled: {\r\n computedFrom: ['question.approved', 'question.autorateFlag'],\r\n compute() {\r\n return this.question.approved || !this.question.autorateFlag;\r\n },\r\n },\r\n required: {\r\n computedFrom: ['question.autorateFlag'],\r\n compute() {\r\n return this.question.autorateFlag;\r\n },\r\n },\r\n },\r\n calculationSources: {\r\n disabled: {\r\n computedFrom: ['question.approved'],\r\n compute() {\r\n return this.question.approved;\r\n },\r\n },\r\n required: {\r\n computedFrom: ['question.displayType.isCalculated'],\r\n compute() {\r\n return this.question.displayType?.isCalculated ?? false;\r\n },\r\n },\r\n },\r\n defaultAnswer: {\r\n disabled: false,\r\n required: false,\r\n },\r\n defaultAnswerText: {\r\n disabled: {\r\n computedFrom: ['question.approved', 'question.displayType.hasDefaultAnswerTextComponent'],\r\n compute() {\r\n return this.question.approved || !this.question.displayType?.hasDefaultAnswerTextComponent;\r\n },\r\n },\r\n required: false,\r\n },\r\n defaultScheduleText: {\r\n disabled: false,\r\n required: false,\r\n },\r\n displayOnDocument: {\r\n disabled: {\r\n computedFrom: ['documentOptionsAreDisabled'],\r\n compute() {\r\n return this.documentOptionsAreDisabled;\r\n },\r\n },\r\n required: {\r\n computedFrom: ['documentOptionsAreDisabled', 'questionAppearsOnSomeDocuments'],\r\n compute() {\r\n return !this.documentOptionsAreDisabled && !this.questionAppearsOnSomeDocuments;\r\n },\r\n },\r\n children: {\r\n clientIncompleteScheduleFlag: {\r\n onChange: QuestionEditorModal.prototype.onDisplayOnDocumentFlagChanged,\r\n valid: QuestionEditorModal.prototype.isDisplayOnDocumentSelectionValid,\r\n },\r\n clientPolicyScheduleFlag: {\r\n onChange: QuestionEditorModal.prototype.onDisplayOnDocumentFlagChanged,\r\n valid: QuestionEditorModal.prototype.isDisplayOnDocumentSelectionValid,\r\n },\r\n clientQuoteScheduleFlag: {\r\n onChange: QuestionEditorModal.prototype.onDisplayOnDocumentFlagChanged,\r\n valid: QuestionEditorModal.prototype.isDisplayOnDocumentSelectionValid,\r\n },\r\n insurerIncompleteScheduleFlag: {\r\n onChange: QuestionEditorModal.prototype.onDisplayOnDocumentFlagChanged,\r\n valid: QuestionEditorModal.prototype.isDisplayOnDocumentSelectionValid,\r\n },\r\n insurerPolicyScheduleFlag: {\r\n onChange: QuestionEditorModal.prototype.onDisplayOnDocumentFlagChanged,\r\n valid: QuestionEditorModal.prototype.isDisplayOnDocumentSelectionValid,\r\n },\r\n insurerQuoteScheduleFlag: {\r\n onChange: QuestionEditorModal.prototype.onDisplayOnDocumentFlagChanged,\r\n valid: QuestionEditorModal.prototype.isDisplayOnDocumentSelectionValid,\r\n },\r\n },\r\n },\r\n displayType: {\r\n disabled: {\r\n computedFrom: ['isSaving', 'question.isNew'],\r\n compute() {\r\n return this.isSaving || !this.question.isNew;\r\n },\r\n },\r\n async onChange(newValue: IQuestionDisplayType, oldValue: IQuestionDisplayType) {\r\n // Must deal with a bunch of state changes when the display type changes, including:\r\n\r\n // Calculation sources: if changing from a calculated display type to a non-calculated display type, clear them\r\n // if changing from a non-calculated display type to a calculated display type, initialize the calculation\r\n // sources with a single empty source\r\n if (oldValue?.displayType !== newValue?.displayType) {\r\n // Reset possible calculation sources when the display type changes\r\n await this.loadPossibleCalculationSources(newValue).then(() => {\r\n if (oldValue?.isCalculated && !newValue?.isCalculated) {\r\n // if changing from a calculated display type to a non-calculated display type, clear the calculation sources\r\n this.question.calculationSources.splice(0);\r\n } else if (!oldValue?.isCalculated && newValue?.isCalculated) {\r\n // if changing from a non-calculated display type to a calculated display type, initialize the calculation\r\n // sources with a single empty source\r\n this.question.calculationSources.push(null);\r\n }\r\n });\r\n }\r\n\r\n // Answer length: if changing from a display type that has a free text component to one that does not,\r\n // clear the answer length\r\n if (oldValue?.hasFreeTextComponent && !newValue?.hasFreeTextComponent) {\r\n this.question.answerLength = null;\r\n }\r\n\r\n // Answer options: if changing from a display type that has answer options to one that does not, clear the answer options\r\n if (oldValue?.hasAnswerOptions && !newValue?.hasAnswerOptions) {\r\n this.question.answerOptions.splice(0);\r\n } else if (!oldValue?.hasAnswerOptions && newValue?.hasAnswerOptions) {\r\n // if changing from a display type that does not have answer options to one that does, initialize the answer options\r\n this.answerOptionAdd();\r\n }\r\n\r\n // Default answer text: if changing from a display type that has a default answer text component to one that does not,\r\n // clear the default answer text\r\n if (oldValue?.hasDefaultAnswerTextComponent && !newValue?.hasDefaultAnswerTextComponent) {\r\n this.question.defaultAnswerText = null;\r\n }\r\n\r\n // Question Attributes: must re-build the attributes if the display type changes, since the attributes are\r\n // tied to the display type\r\n if (oldValue?.displayType !== newValue?.displayType) {\r\n const currentAttributesAsMap = this.generateQuestionAttributesMap(this.question.questionAttributes);\r\n this.question.questionAttributes.splice(0);\r\n this.question.questionAttributes.push(\r\n ...this.getQuestionEditModelAttributes(currentAttributesAsMap, newValue),\r\n );\r\n }\r\n\r\n // Validation: must be re-initialised if the display type changes, since the attributes change\r\n this.initializeValidation();\r\n },\r\n },\r\n interfaceQuestionFlag: {\r\n disabled: {\r\n computedFrom: ['question.approved'],\r\n compute() {\r\n return this.question.approved;\r\n },\r\n },\r\n onChange(newValue: boolean, oldValue: boolean) {\r\n // if enabling interface question, make mandatory on quote and policy true\r\n if (newValue) {\r\n this.question.mandatoryOnPolicyFlag = true;\r\n this.question.mandatoryOnQuoteFlag = true;\r\n } else {\r\n // if disabling interface question, reset interface question name\r\n this.question.interfaceQuestionName = this.questionInitialState.interfaceQuestionName;\r\n }\r\n },\r\n },\r\n interfaceQuestionName: {\r\n disabled: {\r\n computedFrom: ['question.interfaceQuestionFlag', 'question.approved'],\r\n compute() {\r\n return !this.question.interfaceQuestionFlag || this.question.approved;\r\n },\r\n },\r\n required: {\r\n computedFrom: ['question.interfaceQuestionFlag'],\r\n compute: function () {\r\n return this.question.interfaceQuestionFlag;\r\n },\r\n },\r\n },\r\n lmiIdentifier: {\r\n disabled: {\r\n computedFrom: ['question.approved'],\r\n compute() {\r\n return this.question.approved;\r\n },\r\n },\r\n required: false,\r\n },\r\n mandatoryOnPolicyFlag: {\r\n disabled: {\r\n computedFrom: ['question.mandatoryOnQuoteFlag'],\r\n compute() {\r\n // if the question is mandatory on quote, it must also be mandatory on policy, and so the checkbox is disabled\r\n return this.question.approved || this.question.mandatoryOnQuoteFlag;\r\n },\r\n },\r\n },\r\n mandatoryOnQuoteFlag: {\r\n disabled: {\r\n computedFrom: ['question.approved', 'question.premiumRatingFlag'],\r\n compute() {\r\n return this.question.approved || this.question.premiumRatingFlag;\r\n },\r\n },\r\n onChange(newValue: boolean, oldValue: boolean) {\r\n // if making mandatory on quote, also make mandatory on policy\r\n if (newValue) {\r\n this.question.mandatoryOnPolicyFlag = true;\r\n }\r\n },\r\n },\r\n mandatoryOnWebFormFlag: {\r\n disabled: {\r\n computedFrom: ['question.useOnWebFormFlag'],\r\n compute() {\r\n return !this.question.useOnWebFormFlag;\r\n },\r\n },\r\n required: false,\r\n },\r\n onlyDisplayOnWebFormFlag: {\r\n disabled: {\r\n computedFrom: ['question.useOnWebFormFlag'],\r\n compute() {\r\n return !this.question.useOnWebFormFlag;\r\n },\r\n },\r\n required: false,\r\n },\r\n premiumRatingFlag: {\r\n disabled: {\r\n computedFrom: ['question.approved'],\r\n compute() {\r\n return this.question.approved;\r\n },\r\n },\r\n onChange(newValue: boolean, oldValue: boolean) {\r\n // if enabling premium rating, make mandatory on quote and policy true\r\n if (newValue) {\r\n this.question.mandatoryOnPolicyFlag = true;\r\n this.question.mandatoryOnQuoteFlag = true;\r\n }\r\n },\r\n required: false,\r\n },\r\n questionText: {\r\n disabled: {\r\n computedFrom: ['question.approved'],\r\n compute() {\r\n return this.question.approved;\r\n },\r\n },\r\n required: true,\r\n maxLength: 2000,\r\n },\r\n readOnlyFlag: {\r\n disabled: {\r\n computedFrom: ['question.approved'],\r\n compute() {\r\n return this.question.approved;\r\n },\r\n },\r\n required: false,\r\n },\r\n relatedQuestion: {\r\n required: false,\r\n },\r\n scheduleText: {\r\n disabled: {\r\n computedFrom: ['question.approved'],\r\n compute() {\r\n return this.question.approved;\r\n },\r\n },\r\n required: false,\r\n maxLength: 2000,\r\n },\r\n scheduleAnswerBold: {\r\n disabled: {\r\n computedFrom: ['documentOptionsAreDisabled'],\r\n compute() {\r\n return this.documentOptionsAreDisabled;\r\n },\r\n },\r\n required: false,\r\n },\r\n scheduleAnswerItalics: {\r\n disabled: {\r\n computedFrom: ['documentOptionsAreDisabled'],\r\n compute() {\r\n return this.documentOptionsAreDisabled;\r\n },\r\n },\r\n required: false,\r\n },\r\n scheduleAnswerUnderline: {\r\n disabled: {\r\n computedFrom: ['documentOptionsAreDisabled'],\r\n compute() {\r\n return this.documentOptionsAreDisabled;\r\n },\r\n },\r\n required: false,\r\n },\r\n scheduleQuestionBold: {\r\n disabled: {\r\n computedFrom: ['documentOptionsAreDisabled'],\r\n compute() {\r\n return this.documentOptionsAreDisabled;\r\n },\r\n },\r\n },\r\n scheduleQuestionItalics: {\r\n disabled: {\r\n computedFrom: ['documentOptionsAreDisabled'],\r\n compute() {\r\n return this.documentOptionsAreDisabled;\r\n },\r\n },\r\n },\r\n scheduleQuestionUnderline: {\r\n disabled: {\r\n computedFrom: ['documentOptionsAreDisabled'],\r\n compute() {\r\n return this.documentOptionsAreDisabled;\r\n },\r\n },\r\n },\r\n summaryQuestionFlag: {\r\n onChange(newValue: boolean, oldValue: boolean) {\r\n if (!newValue) {\r\n // if summaryQuestionFlag is being set to false, reset summary text\r\n this.question.summaryText = this.questionInitialState.summaryText;\r\n }\r\n },\r\n },\r\n summaryText: {\r\n disabled: {\r\n computedFrom: ['question.summaryQuestionFlag'],\r\n compute() {\r\n return !this.question.summaryQuestionFlag;\r\n },\r\n },\r\n required: {\r\n computedFrom: ['question.summaryQuestionFlag'],\r\n compute() {\r\n return this.question.summaryQuestionFlag;\r\n },\r\n },\r\n },\r\n suppressIfNullFlag: {\r\n disabled: {\r\n computedFrom: ['documentOptionsAreDisabled'],\r\n compute() {\r\n return this.documentOptionsAreDisabled;\r\n },\r\n },\r\n required: false,\r\n },\r\n suppressIfZeroFlag: {\r\n disabled: {\r\n computedFrom: ['documentOptionsAreDisabled'],\r\n compute() {\r\n return this.documentOptionsAreDisabled;\r\n },\r\n },\r\n required: false,\r\n },\r\n useOnWebFormFlag: {\r\n onChange(newValue: boolean, oldValue: boolean) {\r\n if (newValue) {\r\n // if useOnWebFormFlag is being set to true and there is no webFormQuestionText, need to set default value from questionText\r\n if (!this.question.webFormQuestionText) {\r\n this.question.webFormQuestionText = this.question.questionText;\r\n }\r\n } else {\r\n // if useOnWebFormFlag is being set to false, reset web form specific fields\r\n this.question.mandatoryOnWebFormFlag = this.questionInitialState.mandatoryOnWebFormFlag;\r\n this.question.onlyDisplayOnWebFormFlag = this.questionInitialState.onlyDisplayOnWebFormFlag;\r\n this.question.webFormAlertText = this.questionInitialState.webFormAlertText;\r\n this.question.webFormQuestionText = this.questionInitialState.webFormQuestionText;\r\n }\r\n },\r\n },\r\n webFormAlertText: {\r\n disabled: {\r\n computedFrom: ['question.useOnWebFormFlag'],\r\n compute() {\r\n return !this.question.useOnWebFormFlag;\r\n },\r\n },\r\n required: false,\r\n maxLength: 2000,\r\n },\r\n webFormQuestionText: {\r\n disabled: {\r\n computedFrom: ['question.useOnWebFormFlag'],\r\n compute() {\r\n return !this.question.useOnWebFormFlag;\r\n },\r\n },\r\n required: {\r\n computedFrom: ['question.useOnWebFormFlag'],\r\n compute() {\r\n return this.question.useOnWebFormFlag;\r\n },\r\n },\r\n maxLength: 2000,\r\n },\r\n };\r\n\r\n //#region Aurelia Lifecycle Methods\r\n\r\n public constructor(\r\n private questionCollectionLookupDataService: QuestionCollectionLookupDataService,\r\n private bindingEngine: BindingEngine,\r\n private modalService: ModalService,\r\n private toastService: IaToastService,\r\n private i18n: I18N,\r\n private taskQueue: TaskQueue,\r\n validationControllerFactory: ValidationControllerFactory,\r\n ) {\r\n // Setup validation for this modal\r\n this.validationController = validationControllerFactory.createForCurrentScope();\r\n this.validationController.addRenderer(new FormValidationRenderer());\r\n\r\n // translate column headers on initialization\r\n this.columnsCalculationSources.forEach((column) => {\r\n if (column.header) {\r\n column.header = this.i18n.tr(column.header);\r\n }\r\n });\r\n }\r\n\r\n protected async activate({\r\n collectionType,\r\n collectionSetId,\r\n collectionId,\r\n questionPromise,\r\n questionSequenceNo,\r\n questionGroupSequenceNo,\r\n callback,\r\n tabbedMode,\r\n readOnlyMode,\r\n }: {\r\n collectionType: IQuestionCollectionType;\r\n collectionSetId: number;\r\n collectionId: number;\r\n questionPromise: Promise;\r\n questionSequenceNo: number;\r\n questionGroupSequenceNo: number;\r\n callback: (updatedQuestion: IQuestionAddOrUpdate | null, postSaveAction: PostSaveAction | null) => Promise;\r\n tabbedMode?: boolean;\r\n readOnlyMode?: boolean;\r\n }) {\r\n this.collectionType = collectionType === undefined ? this.collectionType : collectionType;\r\n this.collectionSetId = collectionSetId === undefined ? this.collectionSetId : collectionSetId;\r\n this.collectionId = collectionId === undefined ? this.collectionId : collectionId;\r\n this.questionPromise = questionPromise === undefined ? this.questionPromise : questionPromise;\r\n this.questionSequenceNo = questionSequenceNo === undefined ? this.questionSequenceNo : questionSequenceNo;\r\n this.questionGroupSequenceNo =\r\n questionGroupSequenceNo === undefined ? this.questionGroupSequenceNo : questionGroupSequenceNo;\r\n this.callback = callback === undefined ? this.callback : callback;\r\n this.tabbedMode = tabbedMode === undefined ? this.tabbedMode : tabbedMode;\r\n this.readOnlyMode = readOnlyMode === undefined ? this.readOnlyMode : readOnlyMode;\r\n }\r\n\r\n protected attached() {\r\n // Restore tabbed mode toggle from local storage\r\n const tabbedModeLocalStorageValue = localStorage.getItem(TabbedModeLocalStorageKey);\r\n let tabbedModeSetting;\r\n try {\r\n tabbedModeSetting = tabbedModeLocalStorageValue !== null ? JSON.parse(tabbedModeLocalStorageValue) : null;\r\n } catch {\r\n // malformed\r\n tabbedModeSetting = null;\r\n }\r\n if (typeof tabbedModeSetting === 'boolean') {\r\n this.tabbedMode = tabbedModeSetting;\r\n }\r\n\r\n if (this.tabbedMode) {\r\n this.taskQueue.queueMicroTask(() => {\r\n initScrollTabs(this);\r\n });\r\n }\r\n }\r\n\r\n protected detached() {\r\n if (this.tabbedMode) {\r\n disposeScrollTabs(this);\r\n }\r\n }\r\n\r\n protected async bind() {\r\n // Set mode to create if no question promise was provided\r\n // Doing this before async operations provides a better UI experience\r\n if (this.questionPromise == null) {\r\n this.mode = 'create';\r\n }\r\n\r\n // TODO: Handle errors, particularly for the question fetch\r\n const [questionDisplayTypes, documentSections, questionReportCodes] = await Promise.all([\r\n this.questionCollectionLookupDataService.getQuestionDisplayTypes(),\r\n this.questionCollectionLookupDataService.getDocumentSections(),\r\n this.questionCollectionLookupDataService.getQuestionReportCodes(),\r\n ]);\r\n\r\n this.questionDisplayTypes = questionDisplayTypes;\r\n this.documentSections = documentSections;\r\n this.questionReportCodes = questionReportCodes;\r\n\r\n let question: IQuestionFull;\r\n if (this.questionPromise) {\r\n question = await this.questionPromise;\r\n } else {\r\n question = this.createNewQuestion();\r\n }\r\n\r\n this.loadQuestion(question);\r\n await this.loadPossibleCalculationSources(this.question.displayType);\r\n\r\n this.isLoading = false;\r\n }\r\n\r\n protected unbind() {\r\n this.teardown();\r\n }\r\n\r\n //#endregion\r\n\r\n //#region Getters and Setters\r\n\r\n @computedFrom('questionSequenceNo', 'question.questionText')\r\n protected get questionDescription(): string {\r\n return `${this.questionSequenceNo}. ${!this.question?.questionText ? '' : this.question.questionText}`;\r\n }\r\n\r\n @computedFrom('questionDisplayTypes', 'collectionType')\r\n private get availableQuestionDisplayTypes(): IQuestionDisplayType[] {\r\n return this.questionDisplayTypes.filter((qdt) =>\r\n qdt.validCollectionTypes.includes(this.collectionType.collectionType),\r\n );\r\n }\r\n\r\n @computedFrom('question.approved')\r\n private get answerOptionsSortableOptions(): SortableOptions {\r\n return {\r\n // ensure sorting is only enabled if the question is not approved\r\n disabled: this.question.approved,\r\n\r\n // Block drag when clicking on/inside inputs\r\n filter: 'input, textarea, select, option, button',\r\n preventOnFilter: false,\r\n\r\n ghostClass: styles['answer-option-ghost'],\r\n onEnd: (evt) => {\r\n this.answerOptionsMoveItem(evt.oldIndex!, evt.newIndex!);\r\n },\r\n };\r\n }\r\n\r\n @computedFrom('question.displayOnDocument')\r\n private get displayOnDocumentKeys() {\r\n return Object.keys(this.question?.displayOnDocument || {});\r\n }\r\n\r\n @computedFrom('question.documentSection')\r\n private get documentOptionsAreDisabled(): boolean {\r\n return (\r\n this.question.documentSection === null || this.question.documentSection === QuestionDocumentSection.DoNotPrint\r\n );\r\n }\r\n\r\n private get questionAppearsOnAllDocuments(): boolean {\r\n return this.question.displayOnDocument\r\n ? Object.values(this.question.displayOnDocument).every((val) => val === true)\r\n : false;\r\n }\r\n\r\n private set questionAppearsOnAllDocuments(value: boolean) {\r\n if (value) {\r\n for (const key of this.displayOnDocumentKeys) {\r\n this.question.displayOnDocument[key as keyof IQuestionDisplayOnDocument] = true;\r\n }\r\n } else {\r\n for (const key of this.displayOnDocumentKeys) {\r\n this.question.displayOnDocument[key as keyof IQuestionDisplayOnDocument] = false;\r\n }\r\n }\r\n }\r\n\r\n @computedFrom(\r\n 'question.displayOnDocument.clientIncompleteScheduleFlag',\r\n 'question.displayOnDocument.clientPolicyScheduleFlag',\r\n 'question.displayOnDocument.clientQuoteScheduleFlag',\r\n 'question.displayOnDocument.insurerIncompleteScheduleFlag',\r\n 'question.displayOnDocument.insurerPolicyScheduleFlag',\r\n 'question.displayOnDocument.insurerQuoteScheduleFlag',\r\n )\r\n private get questionAppearsOnSomeDocuments(): boolean {\r\n return this.question.displayOnDocument\r\n ? Object.values(this.question.displayOnDocument).some((val) => val === true) &&\r\n !Object.values(this.question.displayOnDocument).every((val) => val === true)\r\n : false;\r\n }\r\n\r\n private get questionSupportsAutorate(): boolean {\r\n return (this.collectionType.optionalFeatures & QuestionFeature.Autorate) !== 0;\r\n }\r\n\r\n private get questionSupportsInterface(): boolean {\r\n return (this.collectionType.optionalFeatures & QuestionFeature.Interface) !== 0;\r\n }\r\n\r\n private get questionSupportsPremiumRating(): boolean {\r\n return (this.collectionType.optionalFeatures & QuestionFeature.PremiumRating) !== 0;\r\n }\r\n\r\n private get questionSupportsMandatory(): boolean {\r\n return (this.collectionType.optionalFeatures & QuestionFeature.Mandatory) !== 0;\r\n }\r\n\r\n private get questionSupportsMandatorySplit(): boolean {\r\n return (this.collectionType.optionalFeatures & QuestionFeature.MandatorySplit) !== 0;\r\n }\r\n\r\n private get questionSupportsLMI(): boolean {\r\n return (this.collectionType.optionalFeatures & QuestionFeature.LMI) !== 0;\r\n }\r\n\r\n private get questionSupportsCoverageDocument(): boolean {\r\n return (this.collectionType.optionalFeatures & QuestionFeature.CoverageDocument) !== 0;\r\n }\r\n\r\n private get questionSupportsWeb(): boolean {\r\n return (this.collectionType.optionalFeatures & QuestionFeature.Web) !== 0;\r\n }\r\n\r\n //#endregion\r\n\r\n //#region Convention-Based Change Handlers\r\n\r\n protected tabbedModeChanged(newValue: boolean, oldValue: boolean | undefined) {\r\n localStorage.setItem(TabbedModeLocalStorageKey, JSON.stringify(newValue));\r\n\r\n if (newValue && !oldValue) {\r\n this.taskQueue.queueMicroTask(() => {\r\n initScrollTabs(this);\r\n });\r\n } else if (!newValue && oldValue) {\r\n disposeScrollTabs(this);\r\n }\r\n }\r\n\r\n //#endregion\r\n\r\n //#region Private Methods\r\n\r\n private answerOptionAdd() {\r\n this.question.answerOptions.push({\r\n answerId: null,\r\n answerText: '',\r\n });\r\n\r\n // Add an observer for the new answer option item\r\n const newAnswerOptionIndex = this.question.answerOptions.length - 1;\r\n this.questionObserversAnswerOptionsIndex[newAnswerOptionIndex] = this.bindingEngine\r\n .propertyObserver(this.question.answerOptions as any, String(newAnswerOptionIndex))\r\n .subscribe(this.checkIsDirtyStatus.bind(this));\r\n\r\n // This will be dirty, but trigger it via the check as it will get debounced with other changes\r\n this.checkIsDirtyStatus();\r\n }\r\n\r\n private answerOptionDelete(option: IQuestionAnswer) {\r\n const index = this.question.answerOptions.indexOf(option);\r\n if (index > -1) {\r\n this.question.answerOptions.splice(index, 1);\r\n }\r\n\r\n // The answer option observers are based on index, so when one is removed we need to tear them all down and\r\n // rebuild them to ensure they are observing the correct items\r\n this.rebuildQuestionObserversAnswerOptionsIndex();\r\n\r\n this.checkIsDirtyStatus();\r\n\r\n // Ensure there is always at least one empty row for adding a new answer option\r\n if (this.question.answerOptions.length === 0) {\r\n this.answerOptionAdd();\r\n }\r\n }\r\n\r\n private answerOptionsMoveItem(oldIndex: number, newIndex: number) {\r\n const arr = this.question.answerOptions;\r\n\r\n if (newIndex < 0 || newIndex >= arr.length || oldIndex === newIndex) {\r\n return;\r\n }\r\n\r\n const item = arr.splice(oldIndex, 1)[0];\r\n arr.splice(newIndex, 0, item);\r\n }\r\n\r\n private buildValidationRules>(\r\n model: TModel,\r\n metadata: Partial<\r\n Record, IQuestionPropertyMetadataEntry | IQuestionPropertyMetadataEntry[]>\r\n >,\r\n ) {\r\n let rules: any = ValidationRules;\r\n\r\n const processModelKey = , K extends Extract>(\r\n targetModel: TTarget,\r\n key: K,\r\n meta: IQuestionPropertyMetadataEntry,\r\n ) => {\r\n const hasValid = Object.prototype.hasOwnProperty.call(meta, 'valid');\r\n const hasRequired = Object.prototype.hasOwnProperty.call(meta, 'required');\r\n const hasChildren = Object.prototype.hasOwnProperty.call(meta, 'children');\r\n const value = targetModel[key]; // typed as TTarget[K]\r\n\r\n if (hasRequired) {\r\n rules = rules\r\n .ensure(key)\r\n .required()\r\n .when(() => meta.required);\r\n }\r\n\r\n if (hasValid) {\r\n rules = rules.ensure(key).satisfies(meta.valid);\r\n }\r\n\r\n if (!hasChildren) return;\r\n\r\n const children = meta.children as Record;\r\n type TChild = ChildModel;\r\n const childMetadata = children as Partial, IQuestionPropertyMetadataEntry>>;\r\n\r\n if (Array.isArray(value)) {\r\n const itemMetadata = children as Partial>;\r\n\r\n // Initial rules for existing items\r\n for (const item of value) {\r\n if (this.isRecord(item)) {\r\n this.buildValidationRules(item, itemMetadata);\r\n }\r\n }\r\n\r\n // Keep rules in sync as items are added/removed\r\n const sub = this.bindingEngine.collectionObserver(value).subscribe((splices: any[]) => {\r\n for (const splice of splices) {\r\n // Remove rules for removed items\r\n for (const removed of splice.removed as unknown[]) {\r\n if (this.isRecord(removed)) {\r\n ValidationRules.off(removed);\r\n }\r\n }\r\n\r\n // Add rules for newly added items\r\n const addedItems = value.slice(splice.index, splice.index + splice.addedCount);\r\n for (const added of addedItems) {\r\n if (this.isRecord(added)) {\r\n this.buildValidationRules(added, itemMetadata);\r\n }\r\n }\r\n }\r\n });\r\n\r\n this.questionObserversValidationCollection.push(sub);\r\n } else if (this.isRecord(value)) {\r\n this.buildValidationRules(value as TChild & Record, childMetadata);\r\n }\r\n };\r\n\r\n const processArrayItemMetadata = >(\r\n key: K,\r\n metaEntries: IQuestionPropertyMetadataEntry[],\r\n ) => {\r\n const value = model[key];\r\n\r\n if (!Array.isArray(value)) {\r\n for (const entry of metaEntries) {\r\n processModelKey(model, key, entry);\r\n }\r\n return;\r\n }\r\n\r\n // For array-backed properties with per-item metadata (for example questionAttributes),\r\n // check for an `attributeId` property on each metadata entry and match it to the corresponding item in the model array\r\n // If the metadata entry doesn't have an `attributeId`, treat it as matching on index\r\n for (let index = 0; index < metaEntries.length; index++) {\r\n const entry = metaEntries[index];\r\n\r\n let item: Record | undefined;\r\n if (key === 'questionAttributes') {\r\n // Find the item in the model array that has a matching attributeId\r\n item = value.find((valueItem) => this.isRecord(valueItem) && valueItem.id === entry.attributeId) as\r\n Record | undefined;\r\n } else {\r\n // Just match by index\r\n item = value[index];\r\n }\r\n\r\n if (!this.isRecord(item)) {\r\n continue;\r\n }\r\n\r\n if (Object.prototype.hasOwnProperty.call(item, 'value')) {\r\n // Build rules against the item itself so each row gets its own metadata instance.\r\n this.buildValidationRules(item, {\r\n value: entry,\r\n } as Partial, IQuestionPropertyMetadataEntry>>);\r\n continue;\r\n }\r\n\r\n if (Object.prototype.hasOwnProperty.call(entry, 'children') && entry.children) {\r\n this.buildValidationRules(\r\n item,\r\n entry.children as Partial, IQuestionPropertyMetadataEntry>>,\r\n );\r\n }\r\n }\r\n };\r\n\r\n for (const key of Object.keys(metadata) as Array>) {\r\n const metaEntry = metadata[key];\r\n if (!metaEntry) {\r\n continue;\r\n }\r\n\r\n if (Array.isArray(metaEntry)) {\r\n processArrayItemMetadata(key, metaEntry);\r\n continue;\r\n }\r\n\r\n processModelKey(model, key, metaEntry);\r\n }\r\n\r\n rules.on(model);\r\n }\r\n\r\n private buildPropertyMetadata(): BuiltEntityMetadata {\r\n // Create a metadata object with an entry for each property, so that the metadata can be easily accessed by property name in the view\r\n // Add in display names for each property from i18n\r\n const displayOnDocumentKeys = this.displayOnDocumentKeys;\r\n const metadata = Object.keys(this.question).reduce(\r\n (acc, key) => {\r\n let i18nKeyFullName = `questionCollectionEditor.questionEditor.propertyQualifiedNames.${key}`;\r\n let i18nKeyShortName = `questionCollectionEditor.questionEditor.propertyLabels.${key}`;\r\n\r\n // Check if we're dealing with the mandatoryOnQuoteFlag key, as it can be translated to just \"Mandatory\" if the collection doesn't support mandatory split, to avoid confusion for the user\r\n if (key === 'mandatoryOnQuoteFlag' && !this.questionSupportsMandatorySplit) {\r\n i18nKeyFullName = `questionCollectionEditor.questionEditor.propertyQualifiedNames.mandatory`;\r\n i18nKeyShortName = `questionCollectionEditor.questionEditor.propertyLabels.mandatory`;\r\n }\r\n\r\n const labelMetadata = {\r\n qualifiedName: this.i18n.tr(i18nKeyFullName),\r\n label: this.i18n.tr(i18nKeyShortName),\r\n } as IQuestionPropertyMetadataEntry;\r\n\r\n if (key === 'displayOnDocument') {\r\n // process the sub-keys as well\r\n labelMetadata.children = {};\r\n for (const displayOnDocumentKey of this.displayOnDocumentKeys) {\r\n i18nKeyFullName = `questionCollectionEditor.questionEditor.propertyQualifiedNames.${key}.${displayOnDocumentKey}`;\r\n i18nKeyShortName = `questionCollectionEditor.questionEditor.propertyLabels.${key}.${displayOnDocumentKey}`;\r\n\r\n labelMetadata.children[displayOnDocumentKey] = {\r\n qualifiedName: this.i18n.tr(i18nKeyFullName),\r\n label: this.i18n.tr(i18nKeyShortName),\r\n };\r\n }\r\n }\r\n\r\n acc[key as keyof IQuestionEditModel] = labelMetadata;\r\n\r\n return acc;\r\n },\r\n {} as EntityMetadataDefinition,\r\n );\r\n\r\n // Add additional property metadata from the static questionEditModelMetadataDefinition object,\r\n // which includes rules for editability, required status, and validation, as well as metadata for child properties (for example the answer options)\r\n Object.entries(QuestionEditorModal.questionEditModelMetadataDefinition).forEach(([key, value]) => {\r\n metadata[key as keyof IQuestionEditModel] = merge(\r\n {},\r\n metadata[key as keyof IQuestionEditModel] as IQuestionPropertyMetadataEntry,\r\n value as IQuestionPropertyMetadataEntry,\r\n );\r\n });\r\n\r\n // add questionAttributes to the metadata for all possible attributes based on display type\r\n const questionAttributesMetadata: IQuestionPropertyMetadataEntry[] = [];\r\n this.questionDisplayTypes.forEach((displayType) => {\r\n displayType.attributes.forEach((attribute) => {\r\n questionAttributesMetadata.push({\r\n attributeId: attribute.attributeId,\r\n label: attribute.attributeName,\r\n qualifiedName: this.i18n.tr('questionAttributeQualifiedNameTemplate', {\r\n attributeName: attribute.attributeName,\r\n }),\r\n required: {\r\n computedFrom: ['question.displayType'],\r\n compute() {\r\n return this.question.displayType?.displayType === displayType.displayType && attribute.required;\r\n },\r\n },\r\n disabled: {\r\n computedFrom: ['question.approved', 'question.displayType.displayType'],\r\n compute() {\r\n return this.question.approved && this.question.displayType?.displayType !== DropDownDisplayTypeId;\r\n },\r\n },\r\n });\r\n });\r\n });\r\n metadata.questionAttributes = questionAttributesMetadata;\r\n\r\n const builder = new EntityMetadataBuilder(this, metadata, this.bindingEngine);\r\n const builtRules = builder.build();\r\n\r\n return builtRules;\r\n }\r\n\r\n private calculationSourceAdd() {\r\n this.question.calculationSources.push(null);\r\n\r\n // Add an observer for the new calculation source item\r\n const newCalculationSourceIndex = this.question.calculationSources.length - 1;\r\n this.questionObserversCalculationSourceIndex[newCalculationSourceIndex] = this.bindingEngine\r\n .propertyObserver(this.question.calculationSources as any, String(newCalculationSourceIndex))\r\n .subscribe(this.checkIsDirtyStatus.bind(this));\r\n\r\n // This will be dirty, but trigger it via the check as it will get debounced with other changes\r\n this.checkIsDirtyStatus();\r\n }\r\n\r\n private calculationSourceDelete(index: number) {\r\n this.question.calculationSources.splice(index, 1);\r\n\r\n // The calculation source observers are based on index, so when one is removed we need to tear them all down and\r\n // rebuild them to ensure they are observing the correct items\r\n this.rebuildQuestionObserversCalculationSourceIndex();\r\n\r\n this.checkIsDirtyStatus();\r\n\r\n // Ensure there is always at least one empty row for adding a new calculation source\r\n if (this.question.calculationSources.length === 0) {\r\n this.calculationSourceAdd();\r\n }\r\n }\r\n\r\n private cancel() {\r\n if (this.isLoading) {\r\n // If we're still loading, just close the modal without prompting, as there can't be any unsaved changes yet\r\n // Checking dirty status requires the model to be loaded\r\n this.callback(null, null);\r\n return;\r\n }\r\n\r\n // Force an isDirty check to ensure any unsaved changes are accounted for in the prompt\r\n this.checkIsDirtyStatus();\r\n\r\n if (this.isDirty) {\r\n // Get properties for confirmation dialog\r\n let translationKeyHeader: string;\r\n let translationKeyMessage: string;\r\n let changes: ObjectDifference[] | null = null;\r\n\r\n switch (this.mode) {\r\n case 'edit':\r\n translationKeyHeader = 'questionCollectionEditor.changesModal.discardQuestionChangesHeader';\r\n translationKeyMessage = 'questionCollectionEditor.changesModal.discardQuestionChangesMessage';\r\n changes = this.toDisplayFriendlyChangeList(\r\n this.getQuestionDifferences(this.questionInitialState, this.question),\r\n );\r\n break;\r\n\r\n case 'create':\r\n translationKeyHeader = 'questionCollectionEditor.changesModal.discardNewQuestionHeader';\r\n translationKeyMessage = 'questionCollectionEditor.changesModal.discardNewQuestionMessage';\r\n break;\r\n\r\n default:\r\n throw new Error(`Unknown mode: ${this.mode}`);\r\n }\r\n\r\n this.modalService\r\n .show(this.dialogModalId)\r\n .content(ChangesModal, {\r\n header: translationKeyHeader,\r\n headerClass: 'header-label--alert',\r\n message: translationKeyMessage,\r\n changes: changes,\r\n callback: (discardChanges: boolean) => {\r\n // Hide the Discard Changes modal\r\n this.modalService.hide(this.dialogModalId);\r\n\r\n if (discardChanges) {\r\n // No need to await this callback as we're not doing anything after it returns, and we want the modal to close immediately\r\n this.callback(null, null);\r\n }\r\n\r\n // else do nothing and allow the user to continue editing\r\n },\r\n })\r\n .withOptions({ type: 'wide-md' });\r\n } else {\r\n // No need to await this callback as we're not doing anything after it returns, and we want the modal to close immediately\r\n this.callback(null, null);\r\n }\r\n }\r\n\r\n private changeTab(tab: QuestionEditorTab) {\r\n this.currentlySelectedTab = tab;\r\n }\r\n\r\n @debounce(300, { leading: true, trailing: true })\r\n private checkIsDirtyStatus(): void {\r\n this.isDirty = !this.questionEditModelEquals(this.questionInitialState, this.question);\r\n }\r\n\r\n private clearRelatedQuestion(): void {\r\n this.question.relatedQuestion = null;\r\n }\r\n\r\n private createNewQuestion(): IQuestionFull {\r\n const newQuestion: IQuestionFull = {\r\n answerOptions: [],\r\n approved: false,\r\n calculated: false,\r\n calculationSources: [],\r\n defaultAnswer: null,\r\n defaultAnswerText: null,\r\n detail: {\r\n alertText: null,\r\n answerLength: null,\r\n autorateFlag: false,\r\n autorateQuestionName: null,\r\n defaultScheduleText: null,\r\n displayOnDocument: {\r\n clientIncompleteScheduleFlag: false,\r\n clientPolicyScheduleFlag: false,\r\n clientQuoteScheduleFlag: false,\r\n insurerIncompleteScheduleFlag: false,\r\n insurerPolicyScheduleFlag: false,\r\n insurerQuoteScheduleFlag: false,\r\n },\r\n displayType: null!,\r\n documentSection: null!,\r\n hideOnWebQuoteFlag: false,\r\n interfaceQuestionFlag: false,\r\n interfaceQuestionName: null,\r\n lmiIdentifier: null,\r\n mandatoryOnPolicyFlag: false,\r\n mandatoryOnQuoteFlag: false,\r\n mandatoryOnWebFormFlag: false,\r\n onlyDisplayOnWebFormFlag: false,\r\n premiumRatingFlag: false,\r\n questionText: '',\r\n quickQuoteFlag: false,\r\n readOnlyFlag: false,\r\n reportCode: null,\r\n scheduleAnswerFormatOptions: {\r\n bold: false,\r\n italics: false,\r\n underline: false,\r\n },\r\n scheduleQuestionFormatOptions: {\r\n bold: false,\r\n italics: false,\r\n underline: false,\r\n },\r\n scheduleText: '',\r\n summaryQuestionFlag: false,\r\n summaryText: null,\r\n suppressOptions: {\r\n suppressIfNullFlag: false,\r\n suppressIfZeroFlag: false,\r\n },\r\n useOnWebFormFlag: false,\r\n webFormAlertText: null,\r\n webFormQuestionText: null,\r\n wizardQuestionFormatOptions: {\r\n bold: false,\r\n italics: false,\r\n underline: false,\r\n },\r\n },\r\n isNew: true,\r\n questionAttributes: {},\r\n questionId: Number.MIN_SAFE_INTEGER,\r\n questionNo: Number.MIN_SAFE_INTEGER,\r\n relatedQuestion: null,\r\n };\r\n\r\n return newQuestion;\r\n }\r\n\r\n private getLabelCalculationSource(questionCalculationSource: IQuestionCalculationSource): string {\r\n return `${questionCalculationSource.sourceGroupSequenceNo}. ${questionCalculationSource.sourceGroupDisplayName}: ${questionCalculationSource.sourceQuestionSequenceNo}. ${questionCalculationSource.sourceQuestionText}`;\r\n }\r\n\r\n private getQuestionAttributePropertyMetadata(attributeId: number): IQuestionPropertyMetadataEntry | undefined {\r\n const attrs = this.propertyMetadata?.questionAttributes;\r\n const errorMessage = `No property metadata found for attributeId ${attributeId}`;\r\n\r\n if (!attrs || !Array.isArray(attrs)) {\r\n throw new Error(errorMessage);\r\n }\r\n\r\n const attributeMetadata = attrs.find((attr) => attr.attributeId === attributeId);\r\n if (!attributeMetadata) {\r\n throw new Error(errorMessage);\r\n }\r\n\r\n return attributeMetadata;\r\n }\r\n\r\n private generateQuestionAttributesMap(\r\n questionAttributes: IQuestionEditModelAttribute[],\r\n ): Record {\r\n return questionAttributes.reduce(\r\n (acc, x) => {\r\n // Options lists in the editor work on optionId, but the API expects the optionValue,\r\n // so we need to convert back before sending to the API\r\n if (x.options && x.options.length > 0) {\r\n const matchingOption = x.options.find((opt) => opt.optionId === x.value);\r\n acc[x.id] = matchingOption ? matchingOption.optionValue : null;\r\n } else {\r\n acc[x.id] = x.value === null ? null : String(x.value);\r\n }\r\n return acc;\r\n },\r\n {} as Record,\r\n );\r\n }\r\n\r\n /**\r\n * Produces the API update payload from the editor model.\r\n *\r\n * The editor model contains UI-friendly objects and nullable slots; this method\r\n * normalizes them into primitive identifiers and API contract structures.\r\n */\r\n private generateQuestionAddOrUpdatePayload(): IQuestionAddOrUpdate {\r\n return {\r\n alertText: this.question.alertText,\r\n answerLength: this.question.answerLength === null ? null : parseInt(this.question.answerLength, 10),\r\n answerOptions: deepClone(this.question.answerOptions),\r\n autorateFlag: this.question.autorateFlag,\r\n autorateQuestionName: this.question.autorateQuestionName,\r\n calculationSources: this.question.calculationSources\r\n .filter((source) => source !== null) // validation should mean this is never required\r\n .map((source) => source!.sourceQuestionId) as number[],\r\n defaultAnswer: deepClone(this.question.defaultAnswer),\r\n defaultAnswerText: this.question.defaultAnswerText,\r\n defaultScheduleText: this.question.defaultScheduleText,\r\n displayOnDocument: deepClone(this.question.displayOnDocument),\r\n displayType: this.question.displayType!.displayType,\r\n documentSection: this.question.documentSection!,\r\n hideOnWebQuoteFlag: this.question.hideOnWebQuoteFlag,\r\n interfaceQuestionFlag: this.question.interfaceQuestionFlag,\r\n interfaceQuestionName: this.question.interfaceQuestionName,\r\n lmiIdentifier: this.question.lmiIdentifier,\r\n mandatoryOnPolicyFlag: this.question.mandatoryOnPolicyFlag,\r\n mandatoryOnQuoteFlag: this.question.mandatoryOnQuoteFlag,\r\n mandatoryOnWebFormFlag: this.question.mandatoryOnWebFormFlag,\r\n onlyDisplayOnWebFormFlag: this.question.onlyDisplayOnWebFormFlag,\r\n premiumRatingFlag: this.question.premiumRatingFlag,\r\n questionAttributes: this.generateQuestionAttributesMap(this.question.questionAttributes),\r\n questionText: this.question.questionText,\r\n quickQuoteFlag: this.question.quickQuoteFlag,\r\n readOnlyFlag: this.question.readOnlyFlag,\r\n relatedQuestionNo: this.question.relatedQuestion ? this.question.relatedQuestion.questionNo : null,\r\n reportCodeId: this.question.reportCode ? this.question.reportCode.questionReportCodeId : null,\r\n scheduleAnswerFormatOptions: {\r\n bold: this.question.scheduleAnswerBold,\r\n italics: this.question.scheduleAnswerItalics,\r\n underline: this.question.scheduleAnswerUnderline,\r\n },\r\n scheduleQuestionFormatOptions: {\r\n bold: this.question.scheduleQuestionBold,\r\n italics: this.question.scheduleQuestionItalics,\r\n underline: this.question.scheduleQuestionUnderline,\r\n },\r\n scheduleText: this.question.scheduleText,\r\n summaryQuestionFlag: this.question.summaryQuestionFlag,\r\n summaryText: this.question.summaryText,\r\n suppressOptions: {\r\n suppressIfNullFlag: this.question.suppressIfNullFlag,\r\n suppressIfZeroFlag: this.question.suppressIfZeroFlag,\r\n },\r\n useOnWebFormFlag: this.question.useOnWebFormFlag,\r\n webFormAlertText: this.question.webFormAlertText,\r\n webFormQuestionText: this.question.webFormQuestionText,\r\n wizardQuestionFormatOptions: {\r\n bold: this.question.wizardQuestionBold,\r\n italics: this.question.wizardQuestionItalics,\r\n underline: this.question.wizardQuestionUnderline,\r\n },\r\n };\r\n }\r\n\r\n /**\r\n * Converts a raw attribute value coming from the API into the value expected by\r\n * the editor control. For option-backed attributes, this resolves to `optionId`;\r\n * for free-text attributes, the original value is preserved.\r\n */\r\n private getQuestionAttributeValueOrOptionId(\r\n attributeDescription: IQuestionDisplayTypeAttribute,\r\n attributeValue: string | null,\r\n ): string | number | null {\r\n // If the attribute value is null, return null\r\n if (attributeValue === null) {\r\n return null;\r\n }\r\n\r\n if (!attributeDescription.options || attributeDescription.options.length === 0) {\r\n // No options, attribute is a free text / numeric value\r\n return attributeValue;\r\n }\r\n\r\n // Attribute has options, return the optionId that matches the attributeValue\r\n const matchingOption = attributeDescription.options.find((opt) => opt.optionValue === attributeValue);\r\n\r\n if (!matchingOption) {\r\n throw new Error(\r\n `Value \"${attributeValue}\" not found in options for attribute \"${attributeDescription.attributeName}\"`,\r\n );\r\n }\r\n return matchingOption.optionId;\r\n }\r\n\r\n private getQuestionDifferences(a: IQuestionEditModel, b: IQuestionEditModel): ObjectDifference[] {\r\n return getObjectDifferences(this.toComparableQuestion(a), this.toComparableQuestion(b));\r\n }\r\n\r\n private getQuestionEditModelAttributes(\r\n attributeMap: Record,\r\n displayType: IQuestionDisplayType | null,\r\n ): IQuestionEditModelAttribute[] {\r\n return (\r\n displayType?.attributes.map((attr) => ({\r\n id: attr.attributeId,\r\n name: attr.attributeName,\r\n options: attr.options,\r\n attribute: attr,\r\n value: attributeMap\r\n ? this.getQuestionAttributeValueOrOptionId(attr, attributeMap[attr.attributeId] ?? null)\r\n : null,\r\n synopsis: attr.synopsis,\r\n required: attr.required,\r\n })) || []\r\n );\r\n }\r\n\r\n private initializeValidation() {\r\n this.teardownQuestionObserversValidationCollection();\r\n ValidationRules.off(this.question);\r\n this.buildValidationRules(this.question, this.propertyMetadata as any);\r\n }\r\n\r\n private isDisplayOnDocumentSelectionValid(value: boolean): boolean {\r\n // Must validate at least one document is checked\r\n return value || this.documentOptionsAreDisabled || this.questionAppearsOnSomeDocuments;\r\n }\r\n\r\n private isRecord(value: unknown): value is Record {\r\n return value !== null && typeof value === 'object' && !Array.isArray(value);\r\n }\r\n\r\n /**\r\n * Loads API question data into the editable UI model and wires change observers.\r\n */\r\n private loadQuestion(question: IQuestionFull) {\r\n // clean up any previously loaded question's observers and validation rules\r\n this.teardown();\r\n\r\n // reset dirty status\r\n this.isDirty = false;\r\n\r\n // find the display type for the question, if it's not null (new questions will have a null display type)\r\n let displayType: IQuestionDisplayType | null = null;\r\n if (question.detail.displayType != null) {\r\n displayType = this.questionDisplayTypes.find((dt) => dt.displayType === question.detail.displayType) ?? null;\r\n if (!displayType) {\r\n throw new Error(`Display type ${question.detail.displayType} not found for question ${question.questionId}`);\r\n }\r\n }\r\n\r\n // Load the question into the editor's question model.\r\n // This involves mapping from the IQuestionFull structure to the QuestionEditModel structure, which is more convenient for data binding in the editor.\r\n // We also need to transform some properties, such as questionAttributes, to include additional information needed for the editor UI.\r\n const answerOptions = deepClone(question.answerOptions);\r\n this.question = {\r\n alertText: question.detail.alertText,\r\n answerLength: question.detail.answerLength?.toString() || null,\r\n answerOptions: answerOptions,\r\n approved: question.approved,\r\n autorateFlag: question.detail.autorateFlag,\r\n autorateQuestionName: question.detail.autorateQuestionName,\r\n calculationSources: deepClone(question.calculationSources),\r\n defaultAnswer: question.defaultAnswer\r\n ? (answerOptions.find((a) => a.answerId == question.defaultAnswer!.answerId) ?? null)\r\n : null,\r\n defaultAnswerText: question.defaultAnswerText,\r\n defaultScheduleText: question.detail.defaultScheduleText,\r\n displayOnDocument: deepClone(question.detail.displayOnDocument),\r\n displayType: displayType,\r\n documentSection: question.detail.documentSection,\r\n hideOnWebQuoteFlag: question.detail.hideOnWebQuoteFlag,\r\n interfaceQuestionFlag: question.detail.interfaceQuestionFlag,\r\n interfaceQuestionName: question.detail.interfaceQuestionName,\r\n isNew: question.isNew,\r\n lmiIdentifier: question.detail.lmiIdentifier,\r\n mandatoryOnPolicyFlag: question.detail.mandatoryOnPolicyFlag,\r\n mandatoryOnQuoteFlag: question.detail.mandatoryOnQuoteFlag,\r\n mandatoryOnWebFormFlag: question.detail.mandatoryOnWebFormFlag,\r\n onlyDisplayOnWebFormFlag: question.detail.onlyDisplayOnWebFormFlag,\r\n premiumRatingFlag: question.detail.premiumRatingFlag,\r\n questionAttributes: this.getQuestionEditModelAttributes(question.questionAttributes, displayType),\r\n questionId: question.questionId,\r\n questionNo: question.questionNo,\r\n questionText: question.detail.questionText,\r\n quickQuoteFlag: question.detail.quickQuoteFlag,\r\n readOnlyFlag: question.detail.readOnlyFlag,\r\n relatedQuestion: question.relatedQuestion,\r\n reportCode: question.detail.reportCode,\r\n scheduleAnswerBold: question.detail.scheduleAnswerFormatOptions.bold,\r\n scheduleAnswerItalics: question.detail.scheduleAnswerFormatOptions.italics,\r\n scheduleAnswerUnderline: question.detail.scheduleAnswerFormatOptions.underline,\r\n scheduleQuestionBold: question.detail.scheduleQuestionFormatOptions.bold,\r\n scheduleQuestionItalics: question.detail.scheduleQuestionFormatOptions.italics,\r\n scheduleQuestionUnderline: question.detail.scheduleQuestionFormatOptions.underline,\r\n scheduleText: question.detail.scheduleText,\r\n summaryQuestionFlag: question.detail.summaryQuestionFlag,\r\n summaryText: question.detail.summaryText,\r\n suppressIfNullFlag: question.detail.suppressOptions.suppressIfNullFlag,\r\n suppressIfZeroFlag: question.detail.suppressOptions.suppressIfZeroFlag,\r\n useOnWebFormFlag: question.detail.useOnWebFormFlag,\r\n webFormAlertText: question.detail.webFormAlertText,\r\n webFormQuestionText: question.detail.webFormQuestionText,\r\n wizardQuestionBold: question.detail.wizardQuestionFormatOptions.bold,\r\n wizardQuestionItalics: question.detail.wizardQuestionFormatOptions.italics,\r\n wizardQuestionUnderline: question.detail.wizardQuestionFormatOptions.underline,\r\n };\r\n\r\n this.questionInitialState = deepClone(this.question);\r\n\r\n // Build the property metadata, which includes display names and rules for each property, based on the question's display type and other factors\r\n this.builtEntityMetadata = this.buildPropertyMetadata();\r\n this.propertyMetadata = this.builtEntityMetadata.properties;\r\n\r\n // subscribe to changes on question attributes to for attribute value changes that impact other attributes\r\n this.setupQuestionPropertyObservers();\r\n\r\n // setup validation now that the question is loaded, so that we have the correct metadata for validation rules\r\n this.initializeValidation();\r\n }\r\n\r\n /* Get and load calculated question sources if the question has a display type that supports calculation sources */\r\n private async loadPossibleCalculationSources(displayType: IQuestionDisplayType | null) {\r\n this.isLoadingPossibleCalculationSources = true;\r\n\r\n this.questionPossibleCalculationSources.splice(0);\r\n\r\n if (displayType?.isCalculated) {\r\n await this.questionCollectionLookupDataService\r\n .getPossibleCalculationSourcesForQuestionDisplayTypeInCollection(\r\n this.collectionType.collectionType,\r\n this.collectionSetId,\r\n this.collectionId,\r\n displayType.displayType,\r\n )\r\n .then((sources) => {\r\n // Filter out sources that are unavailable (i.e. after this question)\r\n const t = this;\r\n const availableQuestions = sources.filter(\r\n (e) =>\r\n e.sourceGroupSequenceNo < this.questionGroupSequenceNo ||\r\n (e.sourceGroupSequenceNo == this.questionGroupSequenceNo &&\r\n e.sourceQuestionSequenceNo < this.questionSequenceNo),\r\n );\r\n\r\n this.questionPossibleCalculationSources.push(...availableQuestions);\r\n });\r\n }\r\n\r\n this.isLoadingPossibleCalculationSources = false;\r\n }\r\n\r\n private onDisplayOnDocumentFlagChanged(newValue: boolean, oldValue: boolean): void {\r\n // Force validation to run on displayOnDocument values, as they are linked\r\n for (const displayOnDocumentKey of this.displayOnDocumentKeys) {\r\n this.validationController.validate({\r\n object: this.question.displayOnDocument,\r\n propertyName: displayOnDocumentKey,\r\n });\r\n }\r\n }\r\n\r\n private onSaveMenuButtonClick(event: Event) {\r\n event.stopPropagation();\r\n\r\n this.saveMenuOpen = !this.saveMenuOpen;\r\n\r\n if (!this.saveMenuOpen) {\r\n return;\r\n }\r\n\r\n if (this.supportsAnchorPositioning) {\r\n return;\r\n }\r\n\r\n const button = event.target as HTMLElement;\r\n const rect = button.getBoundingClientRect();\r\n\r\n // Action must be performed in the next animation frame to ensure that the menu element is rendered and can be positioned\r\n requestAnimationFrame(() => {\r\n if (!button || !this.saveMenuElement) {\r\n return;\r\n }\r\n\r\n this.saveMenuFallbackStyle = `left: ${rect.right}px; top: ${rect.top}px; transform: translateX(-100%) translateY(-102%);`;\r\n });\r\n }\r\n\r\n private openFindRelatedQuestionModal(): void {\r\n this.modalService\r\n .show(this.dialogModalId)\r\n .content(FindRelatedQuestionModal, {\r\n callback: this.relatedQuestionSelected.bind(this),\r\n })\r\n .withOptions({ type: 'wide-lg' });\r\n }\r\n\r\n private questionEditModelEquals(a: IQuestionEditModel, b: IQuestionEditModel): boolean {\r\n return this.getQuestionDifferences(a, b).length === 0;\r\n }\r\n\r\n private rebuildQuestionObserversAnswerOptionsIndex(): void {\r\n this.teardownQuestionAnswerOptionsIndexObservers();\r\n\r\n for (let i = 0; i < this.question.answerOptions.length; i++) {\r\n this.questionObserversAnswerOptionsIndex.push(\r\n this.bindingEngine\r\n .propertyObserver(this.question.answerOptions as any, String(i))\r\n .subscribe(this.checkIsDirtyStatus.bind(this)),\r\n );\r\n }\r\n }\r\n\r\n private rebuildQuestionObserversCalculationSourceIndex(): void {\r\n this.teardownQuestionObserversCalculationSourceIndex();\r\n\r\n for (let i = 0; i < this.question.calculationSources.length; i++) {\r\n this.questionObserversCalculationSourceIndex.push(\r\n this.bindingEngine\r\n .propertyObserver(this.question.calculationSources as any, String(i))\r\n .subscribe(this.checkIsDirtyStatus.bind(this)),\r\n );\r\n }\r\n }\r\n\r\n private relatedQuestionSelected(relatedQuestion: IRelatedQuestion | null): void {\r\n // Close the find related question modal\r\n this.modalService.hide(this.dialogModalId);\r\n\r\n if (!relatedQuestion) {\r\n // Modal was cancelled, do not update related question\r\n return;\r\n }\r\n\r\n this.question!.relatedQuestion = relatedQuestion;\r\n }\r\n\r\n private async save(postSaveAction: PostSaveAction | null = null) {\r\n if (this.isSaving) {\r\n // This shouldn't happen, but guard against multiple rapid clicks on the save button causing multiple submissions\r\n return;\r\n }\r\n this.isSaving = true;\r\n this.saveMenuOpen = false;\r\n\r\n const isValid = (await this.validationController.validate()).valid;\r\n if (!isValid) {\r\n this.scrollToFirstValidationError();\r\n this.isSaving = false;\r\n return;\r\n }\r\n\r\n // Get properties for confirmation dialog\r\n let translationKeyHeader: string;\r\n let translationKeyMessage: string;\r\n let changes: ObjectDifference[] | null = null;\r\n\r\n switch (this.mode) {\r\n case 'edit':\r\n translationKeyHeader = 'questionCollectionEditor.changesModal.acceptQuestionChangesHeader';\r\n translationKeyMessage = 'questionCollectionEditor.changesModal.acceptQuestionChangesMessage';\r\n changes = this.toDisplayFriendlyChangeList(\r\n this.getQuestionDifferences(this.questionInitialState, this.question),\r\n );\r\n break;\r\n\r\n case 'create':\r\n translationKeyHeader = 'questionCollectionEditor.changesModal.acceptNewQuestionHeader';\r\n translationKeyMessage = 'questionCollectionEditor.changesModal.acceptNewQuestionMessage';\r\n break;\r\n\r\n default:\r\n throw new Error(`Unknown mode: ${this.mode}`);\r\n }\r\n\r\n // Display a confirmation dialog\r\n this.modalService\r\n .show(this.dialogModalId)\r\n .content(ChangesModal, {\r\n header: translationKeyHeader,\r\n headerClass: 'header-label--info',\r\n message: translationKeyMessage,\r\n changes: changes,\r\n callback: async (acceptChanges: boolean) => {\r\n // Hide the Accept Changes modal\r\n this.modalService.hide(this.dialogModalId);\r\n\r\n if (acceptChanges) {\r\n this.isWaitingOnSubmit = true;\r\n\r\n // Generate the API payload and send it to the server via the callback provided by the parent component\r\n const questionPayload = this.generateQuestionAddOrUpdatePayload();\r\n await this.callback(questionPayload, postSaveAction).catch((error) => {\r\n // Display notification to the user regarding the update failure\r\n console.error('Failed to update question', error);\r\n this.toastService.error(\r\n new IaToastMessage(\r\n this.i18n.tr('questionCollectionEditor.questionEditor.errors.unknownQuestionSaveError.message'),\r\n this.i18n.tr('questionCollectionEditor.questionEditor.errors.unknownQuestionSaveError.title'),\r\n ),\r\n );\r\n\r\n // Allow the user to continue editing\r\n this.isWaitingOnSubmit = false;\r\n this.isSaving = false;\r\n });\r\n } else {\r\n // Allow the user to continue editing\r\n this.isSaving = false;\r\n }\r\n },\r\n })\r\n .withOptions({ type: 'wide-md' });\r\n }\r\n\r\n private scrollToFirstValidationError(): void {\r\n const contentRoot = this.editorContent;\r\n if (!contentRoot) {\r\n return;\r\n }\r\n\r\n const panels = contentRoot.querySelectorAll('div[data-tab-id]');\r\n\r\n //for (const tabId of tabIdsInOrder) {\r\n // const panel = contentRoot.querySelector(`[data-tab-id=\"${tabId}\"]`);\r\n for (const panel of panels) {\r\n const elementWithInputError = panel?.querySelector('.auFormInputError');\r\n if (elementWithInputError) {\r\n // in tabbed mode, we need to select the first tab with an error before scrolling\r\n\r\n const scrollIntoView = () => {\r\n elementWithInputError.scrollIntoView({\r\n behavior: 'smooth',\r\n block: 'center',\r\n inline: 'nearest',\r\n });\r\n };\r\n\r\n if (this.tabbedMode) {\r\n const tabId = panel.getAttribute('data-tab-id');\r\n this.changeTab(tabId as QuestionEditorTab);\r\n this.taskQueue.queueMicroTask(scrollIntoView);\r\n } else {\r\n scrollIntoView();\r\n }\r\n\r\n break;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Subscribes to model changes that affect dirty tracking and reactive field rules.\r\n *\r\n * We observe:\r\n * - top-level question fields,\r\n * - dynamic question attribute values, and\r\n * - each displayOnDocument flag.\r\n */\r\n private setupQuestionPropertyObservers() {\r\n // Get all properties of this.question, so we can observe them for edits,\r\n // and additionally for any properties that have onChange handlers in the propertyMetadata, so we can trigger those handlers when the property changes\r\n Object.keys(this.question).forEach((key) => {\r\n this.questionObserversProperties.push(\r\n this.bindingEngine.propertyObserver(this.question, key).subscribe(this.checkIsDirtyStatus.bind(this)),\r\n );\r\n\r\n // if the property has an onChange handler in propertyMetadata, also trigger that handler when the property changes\r\n const rawMeta = this.propertyMetadata![key as keyof IQuestionEditModel];\r\n const meta = Array.isArray(rawMeta) ? rawMeta[0] : rawMeta;\r\n if (meta && meta.onChange) {\r\n this.questionObserversProperties.push(\r\n this.bindingEngine.propertyObserver(this.question, key).subscribe((newValue, oldValue) => {\r\n meta.onChange!.call(this, newValue, oldValue);\r\n }),\r\n );\r\n }\r\n });\r\n\r\n // Additionally, observe changes to each attribute values of each question attribute\r\n // Individual attributes are static to the question display type, so we only need to observe for value changes\r\n for (const attr of this.question.questionAttributes) {\r\n // Watch the individual editable field\r\n this.questionObserversProperties.push(\r\n this.bindingEngine.propertyObserver(attr, 'value').subscribe(this.checkIsDirtyStatus.bind(this)),\r\n );\r\n }\r\n\r\n // Additionally, observe changes to each answer option value\r\n // Individual attributes are static to the question display type, so we only need to observe for value changes\r\n for (const attr of this.question.answerOptions) {\r\n // Watch the individual editable field\r\n this.questionObserversProperties.push(\r\n this.bindingEngine.propertyObserver(attr, 'answerText').subscribe(this.checkIsDirtyStatus.bind(this)),\r\n );\r\n }\r\n\r\n // Observe changes to displayOnDocument boolean properties\r\n if (this.question.displayOnDocument) {\r\n const displayOnDocumentKeys = Object.keys(this.question.displayOnDocument) as Array<\r\n keyof IQuestionDisplayOnDocument\r\n >;\r\n for (const key of displayOnDocumentKeys) {\r\n this.questionObserversProperties.push(\r\n this.bindingEngine\r\n .propertyObserver(this.question.displayOnDocument, key)\r\n .subscribe(this.checkIsDirtyStatus.bind(this)),\r\n );\r\n\r\n // if the property has an onChange handler in propertyMetadata, also trigger that handler when the property changes\r\n const meta = (this.propertyMetadata?.displayOnDocument as BuiltPropertyMetadata)\r\n ?.children?.[key];\r\n if (meta && meta.onChange) {\r\n this.questionObserversProperties.push(\r\n this.bindingEngine\r\n .propertyObserver(this.question.displayOnDocument, key)\r\n .subscribe((newValue, oldValue) => {\r\n meta.onChange!.call(this, newValue, oldValue);\r\n }),\r\n );\r\n }\r\n }\r\n }\r\n\r\n // Add additional observers for items in the calculationSources collection\r\n // These will also need to be rebuilt when the items are added/removed, but this is handled in the add/remove methods\r\n this.rebuildQuestionObserversCalculationSourceIndex();\r\n this.rebuildQuestionObserversAnswerOptionsIndex();\r\n }\r\n\r\n private scrollTabs(direction: ScrollDirection) {\r\n scrollTabs(this, direction);\r\n }\r\n\r\n private teardown(): void {\r\n this.teardownQuestionObserversProperties();\r\n this.teardownQuestionObserversCalculationSourceIndex();\r\n this.teardownQuestionAnswerOptionsIndexObservers();\r\n this.teardownQuestionObserversValidationCollection();\r\n\r\n this.builtEntityMetadata?.dispose();\r\n this.builtEntityMetadata = null;\r\n\r\n if (this.question) {\r\n ValidationRules.off(this.question);\r\n this.validationController.removeObject(this.question);\r\n }\r\n\r\n this.propertyMetadata = null;\r\n }\r\n\r\n private teardownQuestionObserversProperties() {\r\n this.questionObserversProperties?.forEach((s) => s.dispose());\r\n this.questionObserversProperties = [];\r\n }\r\n\r\n private teardownQuestionObserversCalculationSourceIndex() {\r\n this.questionObserversCalculationSourceIndex.forEach((s) => s.dispose());\r\n this.questionObserversCalculationSourceIndex = [];\r\n }\r\n\r\n private teardownQuestionAnswerOptionsIndexObservers() {\r\n this.questionObserversAnswerOptionsIndex.forEach((s) => s.dispose());\r\n this.questionObserversAnswerOptionsIndex = [];\r\n }\r\n\r\n private teardownQuestionObserversValidationCollection() {\r\n this.questionObserversValidationCollection.forEach((s) => s.dispose());\r\n this.questionObserversValidationCollection = [];\r\n }\r\n\r\n /**\r\n * Projects the edit model into a stable, comparison-friendly shape used for\r\n * dirty checking. Complex object references are reduced to identifying fields.\r\n */\r\n private toComparableQuestion(model: IQuestionEditModel) {\r\n return {\r\n ...model,\r\n // Compare by stable primitive ids where appropriate\r\n displayType: model.displayType?.displayType ?? null,\r\n reportCode: model.reportCode?.questionReportCodeId ?? null,\r\n\r\n // Compare by stable text where it is easier for display later\r\n documentSection: model.documentSection\r\n ? this.documentSections.find((ds) => ds.documentSection === model.documentSection)?.description\r\n : null,\r\n relatedQuestion: model.relatedQuestion?.questionText ?? null,\r\n\r\n // Keep only value-bearing fields where relevant\r\n calculationSources: model.calculationSources.map((source) => source?.sourceQuestionId ?? null),\r\n displayOnDocument:\r\n model.displayOnDocument == null\r\n ? null\r\n : (Object.keys(model.displayOnDocument) as Array).reduce((acc, key) => {\r\n acc[key] = model.displayOnDocument![key];\r\n return acc;\r\n }, {} as IQuestionDisplayOnDocument),\r\n questionAttributes: model.questionAttributes.reduce(\r\n (acc, attr) => {\r\n acc[attr.id] = attr.value;\r\n return acc;\r\n },\r\n {} as Record,\r\n ),\r\n\r\n // convert answer options to a JSON string, so that we can compare as text\r\n // In the event of a change, the diff can show the before and after text, which we can convert back from JSON and parse in the toDisplayFriendlyChangeList method\r\n defaultAnswer: model.defaultAnswer != null ? JSON.stringify(model.defaultAnswer) : null,\r\n answerOptions: JSON.stringify(model.answerOptions),\r\n };\r\n }\r\n\r\n /**\r\n * Converts raw object-difference paths into translated, user-facing labels\r\n * where metadata exists, then sorts the resulting changes by path.\r\n *\r\n * This is used by the discard-changes prompt so the list is readable and\r\n * presented in a stable alphabetical order.\r\n */\r\n private toDisplayFriendlyChangeList(changes: ObjectDifference[]): ObjectDifference[] {\r\n return changes\r\n .map((change) => {\r\n // Special handling for answerOptions changes to convert the JSON string back into a human readable list of\r\n // answer options with their ids and indexes, so that the discard changes modal can show meaningful before and\r\n // after values for answer option changes\r\n if (change.path === 'answerOptions') {\r\n change = {\r\n ...change,\r\n before:\r\n change.before && typeof change.before === 'string'\r\n ? (JSON.parse(change.before) as IQuestionAnswer[])\r\n .map((answer) => this.questionAnswerOptionDescription(answer))\r\n .join(';\\n')\r\n : null,\r\n after:\r\n change.after && typeof change.after === 'string'\r\n ? (JSON.parse(change.after) as IQuestionAnswer[])\r\n .map((answer) => this.questionAnswerOptionDescription(answer))\r\n .join(';\\n')\r\n : null,\r\n };\r\n }\r\n\r\n // Special handling for defaultAnswer to convert the JSON string back to a human readable form\r\n if (change.path === 'defaultAnswer') {\r\n change = {\r\n ...change,\r\n before:\r\n change.before && typeof change.before === 'string'\r\n ? this.questionAnswerOptionDescription(JSON.parse(change.before) as IQuestionAnswer)\r\n : null,\r\n after:\r\n change.after && typeof change.after === 'string'\r\n ? this.questionAnswerOptionDescription(JSON.parse(change.after) as IQuestionAnswer)\r\n : null,\r\n };\r\n }\r\n\r\n // Convert all path keys to friendly display names where possible using the property metadata\r\n const rawPropMeta = this.propertyMetadata![change.path as keyof typeof this.propertyMetadata];\r\n let propMeta = Array.isArray(rawPropMeta) ? rawPropMeta[0] : rawPropMeta;\r\n\r\n if (change.path!.startsWith('questionAttributes.')) {\r\n // Extract the attribute id from the path, which is in the format questionAttributes.\r\n const match = change.path!.match(/questionAttributes\\.(\\d+)/);\r\n if (match) {\r\n const id = parseInt(match[1], 10);\r\n\r\n // Find the matching attribute metadata from the question display types, which contains the label and options for all attributes\r\n const displayTypeAttr = this.questionDisplayTypes\r\n .flatMap((displayType) => displayType.attributes)\r\n .find((attr) => attr.attributeId === id);\r\n change.path = `Answer: ${displayTypeAttr?.attributeName}`;\r\n change.before =\r\n typeof change.before === 'number'\r\n ? displayTypeAttr?.options?.find((opt) => opt.optionId === change.before)?.optionValue\r\n : change.before;\r\n change.after =\r\n typeof change.after === 'number'\r\n ? displayTypeAttr?.options?.find((opt) => opt.optionId === change.after)?.optionValue\r\n : change.after;\r\n }\r\n } else if (change.path!.startsWith('calculationSources[')) {\r\n // Extract the calculation source index from the path, which is in the format calculationSources[]\r\n const match = change.path!.match(/calculationSources\\[(\\d+)\\]/);\r\n if (match) {\r\n const index = parseInt(match[1], 10);\r\n change.path = `Calculation Source #${index + 1}`;\r\n\r\n const beforeCalculationSource = this.questionPossibleCalculationSources.find(\r\n (e) => e.sourceQuestionId === change.before,\r\n );\r\n change.before = beforeCalculationSource\r\n ? this.getLabelCalculationSource(beforeCalculationSource)\r\n : change.before;\r\n\r\n const afterCalculationSource = this.questionPossibleCalculationSources.find(\r\n (e) => e.sourceQuestionId === change.after,\r\n );\r\n change.after = afterCalculationSource\r\n ? this.getLabelCalculationSource(afterCalculationSource)\r\n : change.after;\r\n }\r\n } else if (change.path?.startsWith('displayOnDocument.')) {\r\n // Extract the displayOnDocument type from the path, which is in the format displayOnDocument.\r\n propMeta = this.propertyMetadata?.[\r\n 'displayOnDocument'\r\n ] as BuiltPropertyMetadata;\r\n const documentFlagKey = change.path.slice('displayOnDocument.'.length);\r\n if (documentFlagKey && propMeta && propMeta.children) {\r\n // Find the matching label data from the children of the propMeta\r\n change = {\r\n ...change,\r\n path: propMeta.children[documentFlagKey]?.qualifiedName || change.path,\r\n };\r\n }\r\n } else if (propMeta && propMeta.qualifiedName) {\r\n change = {\r\n ...change,\r\n path: propMeta.qualifiedName,\r\n };\r\n }\r\n\r\n return change;\r\n })\r\n .sort((a, b) => (a.path ?? '').localeCompare(b.path ?? ''));\r\n }\r\n\r\n private questionAnswerOptionDescription(answerOption: IQuestionAnswer): string {\r\n if (answerOption.answerId === null) {\r\n return `#NEW. ${answerOption.answerText}`;\r\n }\r\n return `#${answerOption.answerId}. ${answerOption.answerText}`;\r\n }\r\n\r\n //#endregion\r\n}\r\n","import { autoinject } from 'aurelia-framework';\r\nimport {\r\n GetCalculationSourcesForDisplayTypeEndpoint,\r\n IRequestGetCalculationSourcesForDisplayType,\r\n} from 'endpoints/admin/qce/get-calculation-sources-for-display-type';\r\nimport { GetDocumentSectionsEndpoint } from 'endpoints/admin/qce/get-document-sections-endpoint';\r\nimport { GetQuestionCollectionApplyTypesEndpoint } from 'endpoints/admin/qce/get-question-collection-apply-types-endpoint';\r\nimport { GetQuestionCollectionQuestionDisplayTypesEndpoint } from 'endpoints/admin/qce/get-question-collection-question-display-types-endpoint';\r\nimport { GetQuestionCollectionTypesEndpoint } from 'endpoints/admin/qce/get-question-collection-types-endpoint';\r\nimport { GetQuestionReportCodesEndpoint } from 'endpoints/admin/qce/get-question-report-codes-endpoint';\r\nimport type {\r\n IQuestionCalculationSource,\r\n IQuestionCollectionApplyType,\r\n IQuestionCollectionType,\r\n IQuestionDisplayType,\r\n IQuestionDocumentSection,\r\n IQuestionReportCode,\r\n} from 'endpoints/admin/qce/shared-models';\r\n\r\n@autoinject()\r\nexport class QuestionCollectionLookupDataService {\r\n constructor(\r\n private questionCollectionQuestionDisplayTypeEndpoint: GetQuestionCollectionQuestionDisplayTypesEndpoint,\r\n private getDocumentSectionsEndpoint: GetDocumentSectionsEndpoint,\r\n private getQuestionCollectionTypesEndpoint: GetQuestionCollectionTypesEndpoint,\r\n private getCalculationSourcesForDisplayTypeEndpoint: GetCalculationSourcesForDisplayTypeEndpoint,\r\n private getQuestionReportCodesEndpoint: GetQuestionReportCodesEndpoint,\r\n private getQuestionCollectionApplyTypesEndpoint: GetQuestionCollectionApplyTypesEndpoint,\r\n ) {}\r\n\r\n private static collectionApplyTypes: IQuestionCollectionApplyType[] | null = null;\r\n private static collectionApplyTypesPromise: Promise | null = null;\r\n private static collectionTypes: IQuestionCollectionType[] | null = null;\r\n private static collectionTypesPromise: Promise | null = null;\r\n private static documentSections: IQuestionDocumentSection[] | null = null;\r\n private static documentSectionsPromise: Promise | null = null;\r\n private static questionDisplayTypes: IQuestionDisplayType[] | null = null;\r\n private static questionDisplayTypesPromise: Promise | null = null;\r\n\r\n public async getCollectionTypes(): Promise {\r\n if (QuestionCollectionLookupDataService.collectionTypes) {\r\n return QuestionCollectionLookupDataService.collectionTypes;\r\n }\r\n\r\n if (QuestionCollectionLookupDataService.collectionTypesPromise) {\r\n return QuestionCollectionLookupDataService.collectionTypesPromise;\r\n }\r\n\r\n QuestionCollectionLookupDataService.collectionTypesPromise = (async () => {\r\n try {\r\n const result = await this.getQuestionCollectionTypesEndpoint.fetch().then((r) => r.data);\r\n\r\n if (result === null) {\r\n // This should never happen since the endpoint should return an empty array if there are no display types, but we check just in case\r\n throw new Error('Received null response for collection types');\r\n }\r\n\r\n QuestionCollectionLookupDataService.collectionTypes = result;\r\n return result;\r\n } catch (error) {\r\n // Reset the promise on error so that future calls can retry\r\n QuestionCollectionLookupDataService.collectionTypesPromise = null;\r\n throw error;\r\n }\r\n })();\r\n\r\n return QuestionCollectionLookupDataService.collectionTypesPromise!;\r\n }\r\n\r\n public async getCollectionApplyTypes(): Promise {\r\n if (QuestionCollectionLookupDataService.collectionApplyTypes) {\r\n return QuestionCollectionLookupDataService.collectionApplyTypes;\r\n }\r\n\r\n if (QuestionCollectionLookupDataService.collectionApplyTypesPromise) {\r\n return QuestionCollectionLookupDataService.collectionApplyTypesPromise;\r\n }\r\n\r\n QuestionCollectionLookupDataService.collectionApplyTypesPromise = (async () => {\r\n try {\r\n const result = await this.getQuestionCollectionApplyTypesEndpoint.fetch().then((r) => r.data);\r\n\r\n if (result === null) {\r\n // This should never happen since the endpoint should return an empty array if there are no apply types, but we check just in case\r\n throw new Error('Received null response for collection apply types');\r\n }\r\n\r\n QuestionCollectionLookupDataService.collectionApplyTypes = result;\r\n return result;\r\n } catch (error) {\r\n // Reset the promise on error so that future calls can retry\r\n QuestionCollectionLookupDataService.collectionApplyTypesPromise = null;\r\n throw error;\r\n }\r\n })();\r\n\r\n return QuestionCollectionLookupDataService.collectionApplyTypesPromise!;\r\n }\r\n\r\n public async getDocumentSections(): Promise {\r\n if (QuestionCollectionLookupDataService.documentSections) {\r\n return QuestionCollectionLookupDataService.documentSections;\r\n }\r\n\r\n if (QuestionCollectionLookupDataService.documentSectionsPromise) {\r\n return QuestionCollectionLookupDataService.documentSectionsPromise;\r\n }\r\n\r\n QuestionCollectionLookupDataService.documentSectionsPromise = (async () => {\r\n try {\r\n const result = await this.getDocumentSectionsEndpoint.fetch().then((r) => r.data);\r\n\r\n if (result === null) {\r\n // This should never happen since the endpoint should return an empty array if there are no display types, but we check just in case\r\n throw new Error('Received null response for document sections');\r\n }\r\n\r\n QuestionCollectionLookupDataService.documentSections = result;\r\n return result;\r\n } catch (error) {\r\n // Reset the promise on error so that future calls can retry\r\n QuestionCollectionLookupDataService.documentSectionsPromise = null;\r\n throw error;\r\n }\r\n })();\r\n\r\n return QuestionCollectionLookupDataService.documentSectionsPromise!;\r\n }\r\n\r\n public async getPossibleCalculationSourcesForQuestionDisplayTypeInCollection(\r\n collectionType: string | number,\r\n collectionSetId: number,\r\n collectionId: number,\r\n displayType: string | number,\r\n ): Promise {\r\n const requestParams: IRequestGetCalculationSourcesForDisplayType = {\r\n collectionType,\r\n collectionSetId,\r\n collectionId,\r\n displayType,\r\n };\r\n\r\n const result = await this.getCalculationSourcesForDisplayTypeEndpoint.fetch(requestParams).then((r) => r.data);\r\n\r\n if (result === null) {\r\n // This should never happen since the endpoint should return an empty array if there are no calculation sources, but we check just in case\r\n throw new Error('Received null response for calculation sources for question display type');\r\n }\r\n\r\n return result;\r\n }\r\n\r\n public async getQuestionDisplayTypes(): Promise {\r\n if (QuestionCollectionLookupDataService.questionDisplayTypes) {\r\n return QuestionCollectionLookupDataService.questionDisplayTypes;\r\n }\r\n\r\n if (QuestionCollectionLookupDataService.questionDisplayTypesPromise) {\r\n return QuestionCollectionLookupDataService.questionDisplayTypesPromise;\r\n }\r\n\r\n const promise = this.questionCollectionQuestionDisplayTypeEndpoint.fetch().then((r) => r.data);\r\n\r\n await promise.then((result) => {\r\n if (result === null) {\r\n // This should never happen since the endpoint should return an empty array if there are no display types, but we check just in case\r\n throw new Error('Received null response for question display types');\r\n }\r\n\r\n QuestionCollectionLookupDataService.questionDisplayTypesPromise = promise as Promise;\r\n });\r\n\r\n return promise as Promise;\r\n }\r\n\r\n public async getQuestionReportCodes(): Promise {\r\n const result = await this.getQuestionReportCodesEndpoint.fetch().then((r) => r.data);\r\n\r\n if (result === null) {\r\n // This should never happen since the endpoint should return an empty array if there are no report codes, but we check just in case\r\n throw new Error('Received null response for question report codes');\r\n }\r\n\r\n return result;\r\n }\r\n}\r\n"],"names":["module","exports","cb","require","QuestionEditorTab","TabbedModeLocalStorageKey","questionCollectionLookupDataService","bindingEngine","modalService","toastService","i18n","taskQueue","validationControllerFactory","readOnlyMode","tabbedMode","builtEntityMetadata","dialogModalId","documentSections","isDirty","isLoading","isLoadingPossibleCalculationSources","isSaving","isWaitingOnSubmit","mode","propertyMetadata","questionDisplayTypes","questionObserversAnswerOptionsIndex","questionObserversCalculationSourceIndex","questionObserversProperties","questionObserversValidationCollection","questionPossibleCalculationSources","questionReportCodes","saveMenuOpen","saveMenuFallbackStyle","saveMenuElement","styles","supportsAnchorPositioning","currentlySelectedTab","QuestionDetails","isLeftChevronDisabled","isRightChevronDisabled","tabClass","columnsCalculationSources","key","header","sortable","searchable","cssClass","this","validationController","createForCurrentScope","addRenderer","forEach","column","tr","QuestionEditorModal","activate","collectionType","collectionSetId","collectionId","questionPromise","questionSequenceNo","questionGroupSequenceNo","callback","undefined","attached","tabbedModeSetting","tabbedModeLocalStorageValue","localStorage","getItem","JSON","parse","queueMicroTask","detached","bind","Promise","all","getQuestionDisplayTypes","getDocumentSections","getQuestionReportCodes","question","createNewQuestion","loadQuestion","loadPossibleCalculationSources","displayType","unbind","teardown","questionText","filter","qdt","validCollectionTypes","includes","disabled","approved","preventOnFilter","ghostClass","onEnd","evt","answerOptionsMoveItem","oldIndex","newIndex","Object","keys","displayOnDocument","documentSection","DoNotPrint","values","every","val","value","displayOnDocumentKeys","some","optionalFeatures","Autorate","Interface","PremiumRating","Mandatory","MandatorySplit","LMI","CoverageDocument","Web","tabbedModeChanged","newValue","oldValue","setItem","stringify","answerOptionAdd","answerOptions","push","answerId","answerText","newAnswerOptionIndex","length","propertyObserver","String","subscribe","checkIsDirtyStatus","answerOptionDelete","option","index","indexOf","splice","rebuildQuestionObserversAnswerOptionsIndex","arr","item","buildValidationRules","model","metadata","rules","ValidationRules","processModelKey","targetModel","meta","hasValid","prototype","hasOwnProperty","call","hasRequired","hasChildren","ensure","required","when","satisfies","valid","children","childMetadata","Array","isArray","isRecord","sub","collectionObserver","splices","removed","off","addedItems","slice","addedCount","added","processArrayItemMetadata","metaEntries","entry","find","valueItem","id","attributeId","metaEntry","on","buildPropertyMetadata","reduce","acc","i18nKeyFullName","i18nKeyShortName","questionSupportsMandatorySplit","labelMetadata","qualifiedName","label","displayOnDocumentKey","entries","questionEditModelMetadataDefinition","merge","questionAttributesMetadata","attributes","attribute","attributeName","computedFrom","compute","questionAttributes","build","calculationSourceAdd","calculationSources","newCalculationSourceIndex","calculationSourceDelete","rebuildQuestionObserversCalculationSourceIndex","cancel","translationKeyHeader","translationKeyMessage","changes","toDisplayFriendlyChangeList","getQuestionDifferences","questionInitialState","Error","show","content","headerClass","message","discardChanges","hide","withOptions","type","changeTab","tab","questionEditModelEquals","clearRelatedQuestion","relatedQuestion","calculated","defaultAnswer","defaultAnswerText","detail","alertText","answerLength","autorateFlag","autorateQuestionName","defaultScheduleText","clientIncompleteScheduleFlag","clientPolicyScheduleFlag","clientQuoteScheduleFlag","insurerIncompleteScheduleFlag","insurerPolicyScheduleFlag","insurerQuoteScheduleFlag","hideOnWebQuoteFlag","interfaceQuestionFlag","interfaceQuestionName","lmiIdentifier","mandatoryOnPolicyFlag","mandatoryOnQuoteFlag","mandatoryOnWebFormFlag","onlyDisplayOnWebFormFlag","premiumRatingFlag","quickQuoteFlag","readOnlyFlag","reportCode","scheduleAnswerFormatOptions","bold","italics","underline","scheduleQuestionFormatOptions","scheduleText","summaryQuestionFlag","summaryText","suppressOptions","suppressIfNullFlag","suppressIfZeroFlag","useOnWebFormFlag","webFormAlertText","webFormQuestionText","wizardQuestionFormatOptions","isNew","questionId","Number","MIN_SAFE_INTEGER","questionNo","getLabelCalculationSource","questionCalculationSource","sourceGroupSequenceNo","sourceGroupDisplayName","sourceQuestionSequenceNo","sourceQuestionText","getQuestionAttributePropertyMetadata","attrs","errorMessage","attributeMetadata","attr","generateQuestionAttributesMap","x","options","matchingOption","opt","optionId","optionValue","generateQuestionAddOrUpdatePayload","parseInt","source","map","sourceQuestionId","relatedQuestionNo","reportCodeId","questionReportCodeId","scheduleAnswerBold","scheduleAnswerItalics","scheduleAnswerUnderline","scheduleQuestionBold","scheduleQuestionItalics","scheduleQuestionUnderline","wizardQuestionBold","wizardQuestionItalics","wizardQuestionUnderline","getQuestionAttributeValueOrOptionId","attributeDescription","attributeValue","a","b","toComparableQuestion","getQuestionEditModelAttributes","attributeMap","name","synopsis","initializeValidation","teardownQuestionObserversValidationCollection","isDisplayOnDocumentSelectionValid","documentOptionsAreDisabled","questionAppearsOnSomeDocuments","dt","toString","properties","setupQuestionPropertyObservers","isCalculated","getPossibleCalculationSourcesForQuestionDisplayTypeInCollection","then","sources","availableQuestions","e","onDisplayOnDocumentFlagChanged","validate","object","propertyName","onSaveMenuButtonClick","event","stopPropagation","button","target","rect","getBoundingClientRect","requestAnimationFrame","right","top","openFindRelatedQuestionModal","relatedQuestionSelected","teardownQuestionAnswerOptionsIndexObservers","i","teardownQuestionObserversCalculationSourceIndex","save","postSaveAction","scrollToFirstValidationError","acceptChanges","questionPayload","catch","error","console","contentRoot","editorContent","panels","querySelectorAll","panel","elementWithInputError","querySelector","scrollIntoView","behavior","block","inline","tabId","getAttribute","rawMeta","onChange","scrollTabs","direction","teardownQuestionObserversProperties","dispose","removeObject","s","ds","description","change","path","before","answer","questionAnswerOptionDescription","join","after","rawPropMeta","propMeta","startsWith","match","displayTypeAttr","flatMap","beforeCalculationSource","afterCalculationSource","documentFlagKey","sort","localeCompare","answerOption","maxLength","hasFreeTextComponent","minValue","maxValue","answerTexts","lastIndexOf","hasDefaultAnswerTextComponent","hasAnswerOptions","currentAttributesAsMap","leading","trailing","autoinject","I18N","TaskQueue","ValidationControllerFactory","questionCollectionQuestionDisplayTypeEndpoint","getDocumentSectionsEndpoint","getQuestionCollectionTypesEndpoint","getCalculationSourcesForDisplayTypeEndpoint","getQuestionReportCodesEndpoint","getQuestionCollectionApplyTypesEndpoint","QuestionCollectionLookupDataService","getCollectionTypes","collectionTypes","collectionTypesPromise","fetch","r","data","result","getCollectionApplyTypes","collectionApplyTypes","collectionApplyTypesPromise","documentSectionsPromise","requestParams","questionDisplayTypesPromise","promise"],"sourceRoot":""}