{"version":3,"file":"main.2f708add78eefbbc.js","mappings":"6MAWaA,EAAoB,eAAAC,EAApBD,EAAoB,SAAAE,GAK/B,SAAAF,EAAoBG,GAA0B,IAAAC,EAAAC,cAAAC,KAAAN,IAC5CI,KAAAG,KAAAD,KAAAN,IADkBG,UAJpBC,EAAAI,YAAc,iBAEdJ,EAAAK,UAAoB,EAIlBL,EAAKM,SAASN,EAAKO,YAAYC,KAAM,UAAUR,CACjD,CAACS,cAAAb,EAAAE,IAAA,EAAAY,KAAAd,EAAA,EAAAe,IAAA,eAAAC,MAEM,SAAaC,GAClB,QAAQC,EAAI,EAAGA,EAAID,EAAOC,IACxBZ,KAAKa,MACT,GAAC,CAAAJ,IAAA,OAAAC,MAEM,WACLV,KAAKG,YACLH,KAAKI,SAASJ,KAAKa,KAAKP,KAAM,2CAA4C,CAACN,KAAKG,YAEzD,IAAnBH,KAAKG,WACTH,KAAKH,QAAQgB,KAAK,qBAEpB,GAAC,CAAAJ,IAAA,OAAAC,MAEM,WACDV,KAAKG,UAAY,IACnBH,KAAKG,YACLH,KAAKI,SAASJ,KAAKc,KAAKR,KAAM,2CAA4C,CAACN,KAAKG,YAEzD,IAAnBH,KAAKG,WACPH,KAAKH,QAAQiB,KAAK,sBAGxB,IAAC,CAjC8B,CAAQC,KAAkBpB,SAA9CD,0CAAmBsB,MAAAC,MAAA,0BAAnBvB,EAAmBwB,UAAA,kBAAAC,SAAA,CAAAH,OAAAI,MAAA,EAAAC,KAAA,EAAAC,OAAA,0IAAAC,SAAA,SAAAC,EAAAC,GAAA,EAAAD,ICT5BR,MADJ,kBACIA,CADoG,SACxDA,MAAA,GAChDA,iBAFsFA,MAAA,eACtCA,MAAA,GAAAA,MAAAS,EAAAvB,+EDSnCR,EAAmBgC,QAAnBhC,EAAmBiC,UAAAC,WANlB,SAMDlC,CAAoB,qCEX1B,IAAKmC,EAAZ,SAAYA,GACRA,SAAAC,OAAA,SACAD,EAAAE,SAAA,WACAF,EAAAG,QAAA,UAHQH,CAIZ,CAJA,CAAYA,GAAoB,qCCAzB,IAAKI,EAAZ,SAAYA,GACXA,SAAAC,OAAA,UACAD,EAAAE,MAAA,QACAF,EAAAG,UAAA,YACGH,EAAAI,SAAA,WACAJ,EAAAK,UAAA,YACAL,EAAAM,SAAA,WACAN,EAAAO,UAAA,YACAP,EAAAD,QAAA,UARQC,CASZ,CATA,CAAYA,GAAa,qCCAlB,IAAKQ,EAAZ,SAAYA,GACXA,SAAAP,OAAA,UACAO,EAAAC,KAAA,OACAD,EAAAE,UAAA,YAHWF,CAIZ,CAJA,CAAYA,GAAmB,6DCAlBG,EAAgB,eAAAC,EAAhBD,GAAgBpC,OAAA,SAAAoC,KAAA7C,OAAAC,KAAA4C,EAAA,GAAAC,SAAhBD,GACcE,SAAmB,WACnBD,EAAAE,eAAyB,iBACzBF,EAAAG,gBAA0B,kBAC1BH,EAAAI,YAAsB,cACtBJ,EAAAK,gBAA0B,kBAC1BL,EAAAM,IAAc,MACdN,EAAAO,oBAA8B,sBAC9BP,EAAAQ,aAAuB,eACvBR,EAAAS,sBAAgC,wBAChCT,EAAAU,cAAwB,gBACxBV,EAAAW,oBAA8B,sBAC9BX,EAAAY,0CAAoD,4CACpDZ,EAAAa,cAAwB,gBACxBb,EAAAc,kBAA4B,iBAC5Bd,EAAAe,sBAAgC,wBAChCf,EAAAgB,mBAA6B,qBAC7BhB,EAAAiB,iBAA2B,mBAC3BjB,EAAAkB,qBAA+B,uBAC/BlB,EAAAmB,YAAsB,cACtBnB,EAAAoB,sBAAgC,wBApB9CrB,CAAgB,qCCAtB,IAAKsB,EAAZ,SAAYA,GACRA,SAAAC,KAAA,OACAD,EAAAE,KAAA,OACAF,EAAAG,OAAA,SACAH,EAAAI,KAAA,OACAJ,EAAAK,OAAA,SACAL,EAAAM,QAAA,UACAN,EAAAO,YAAA,cACAP,EAAAQ,yBAAA,2BARQR,CASZ,CATA,CAAYA,GAAmB,qCCAxB,IAAKS,EAAZ,SAAYA,GACXA,SAAAR,KAAA,OACAQ,EAAAC,KAAA,OACAD,EAAAE,IAAA,MACAF,EAAAG,OAAA,SAJWH,CAKZ,CALA,CAAYA,GAAS,oCCGd,IAAKI,EAAZ,SAAYA,GACXA,SAAAC,IAAA,iBACAD,EAAAE,KAAA,uBACAF,EAAAG,GAAA,KAHWH,CAIZ,CAJA,CAAYA,GAAU,6DCQTI,GAAe3E,OA8CxB,SAAA2E,KAAApF,OAAAC,KAAAmF,GA5BOnF,KAAAoF,sBAAgC,EAYhCpF,KAAAqF,cAAwB,MASxBrF,KAAAsF,YAAsB,EACtBtF,KAAAuF,gBAA0BC,MAAQC,cAKlCzF,KAAA0F,6BAAuC,CAC9B,qJCzDPC,GAAmBnF,OAI5B,SAAAmF,KAAA5F,OAAAC,KAAA2F,GAHO3F,KAAA4F,GAAa,GACb5F,KAAA6F,OAAiB,EAET,GCJNC,GAA2BtF,OAQpC,SAAAsF,KAAA/F,OAAAC,KAAA8F,GANI9F,KAAA+F,UAAoB,GACpB/F,KAAAgG,SAAmB,GAEhBhG,KAAAiG,SAAmB,GACnBjG,KAAAkG,OAAiB,MAET,GCRNC,GAA0B3F,OAKnC,SAAA2F,KAAApG,OAAAC,KAAAmG,GAJOnG,KAAAiG,SAAmB,GACnBjG,KAAAkG,OAAiB,OACjBlG,KAAAoG,SAAmB,EAEX,YCObC,EAAmC,kCACnCC,EAAoC,mCACpCC,EAAkC,8BAK3BC,EAAgB,eAAAC,EAAhBD,EAAgB,WAyBzB,SAAAhG,KAdA,SAAAgG,IAAA,IAAA1G,EAAAE,MAAAD,OAAAC,KAAAwG,GANOxG,KAAA0G,eAAyB,KAO5B1G,KAAK2G,KAAO,IAAIC,QAAWC,OAAOC,OAClC9G,KAAK+G,UAASF,OAAOG,MAErBhH,KAAKiH,WAAaC,IAAYC,UAAUC,QACxCpH,KAAKqH,cAAgBH,IAAYC,UAAUE,cAC3CrH,KAAK6F,OAASqB,IAAYC,UAAUtB,UAEpCgB,OAAOS,KAAuBC,gBAAgBC,UAAU,SAAAC,GAEpD3H,EAAK4H,mBAAmBD,EAC5B,EACJ,EAEA,EAAAhH,IAAA,uBAAAC,MAIO,SAAqBiH,GAOxB,MAAO,CAAEC,QALK,IAAIC,KAAY,CAC1B,eAAgB,mBAChBC,cAAe,UAAYH,IAInC,GAEA,CAAAlH,IAAA,uBAAAC,MAIO,WAEH,IAAIqH,EAAmBC,aAAaC,QAAQ1B,GAC5C,GAAIwB,EAAkB,CAElB,IAAIG,EAAeC,KAAKC,MAAML,GAC1BM,EAAc,IAAI7C,KAEtB,GADkB,IAAIA,KAAK0C,EAAaI,YACtBD,EACd,SAAOE,MAAGL,EAElB,CAGA,IAAIM,EAAa,IAAI7C,EAMrB,OALA6C,EAAW5C,GAAK5F,KAAKqH,cACrBmB,EAAW3C,OAAS7F,KAAK6F,OAIlB7F,KAAK2G,KAAK8B,KAFOzI,KAAKiH,WAAajH,KAAK0G,eAAiB,+BAEX8B,GAAYE,QAC7DC,KAAI,SAACC,GACDZ,aAAaa,QAAQtC,EAAyB4B,KAAKW,UAAUF,GACjE,GAER,GAEA,CAAAnI,IAAA,qBAAAC,MAIO,SAAmBqI,GAEtB,IAAIC,KAAmBC,KAAA,GAAQjJ,KAAKkJ,aACpClJ,KAAKkJ,YAAcH,IAGdC,GACDhJ,KAAKkJ,YAAYC,gBAAkBH,EAAoBG,eACvDnJ,KAAKkJ,YAAYE,eAAiBJ,EAAoBI,eACtDpJ,KAAKqJ,qBAAoB,EAEjC,GAEA,CAAA5I,IAAA,sBAAAC,MAGO,SAAoB4I,GAAsD,IAA5BC,EAAAC,UAAAC,OAAA,QAAAC,IAAAF,UAAA,GAAAA,UAAA,GAA0B,GAC3E,GAAKxJ,KAAKkJ,YAAYS,MAItB,KAAIC,EAAO5J,KAAK+G,OAAO8C,YAAYC,SAASF,KAExCG,EAAsB,GACtB/D,EAAgB,GAEhBhG,KAAKkJ,YAAYE,eAAcpD,EAASgE,MAAWhK,KAAKkJ,YAAYE,aAAa9I,MAErF,IACI,KAAOsJ,GAAM,CACT,GAAIN,EAAiB,CACjB,IAC4CW,EAD5CC,KAAAC,KAC0BP,EAAKQ,SAASC,MAAI,QAAAC,EAAA,WAAE,IAAnCC,EAAWN,EAAAvJ,MAClB,GAAoB,WAAhB6J,GAA4C,UAAhBA,EAC5BC,QAAQC,MAAMF,EAAc,KAAOX,EAAKQ,SAASM,IAAIH,IACjDX,EAAKQ,SAASM,IAAIH,KAAcvE,EAASuE,GAAeX,EAAKQ,SAASM,IAAIH,QAE7E,CACD,IAAII,GAAQf,EAAKQ,SAASM,IAAIH,GAC9B,GAAII,GAAO,CACP,IAAIC,GAAiBb,EAAUc,UAAU,SAAAC,IAAC,OAAIA,GAAEC,QAAQJ,IAAS,KAAM,CAAE,GACrEC,IAAiB,GACjBb,EAAUiB,OAAOJ,GAAgB,EACzC,CACJ,CACJ,EAbA,IAAAV,EAAAzC,MAAAwC,EAAAC,EAAAe,KAAAC,MAAAZ,GAaC,OAAAa,IAAAjB,EAAAY,EAAAK,GAAA,SAAAjB,EAAAkB,GAAA,CACL,CAEA,IAAIxB,EAAKyB,WAAYzB,EAAKyB,SAAS5B,OAM/B,MAH4B,UAF5BG,EAAOA,EAAKyB,SAAS,IAEZC,IAAIC,YAAiD,KAAxB3B,EAAK0B,IAAIC,YAC3CxB,EAAUyB,KAAK5B,EAAK0B,IAAIC,WAIpC,CACJ,OAASE,IACLjB,QAAQkB,IAAI,qCAAuCD,GAAGE,QAC1D,CAGA,QAAAC,EAAA,EAAAC,EAAyBC,OAAOC,QAAQxC,GAAmBqC,EAAAC,EAAApC,OAAAmC,IAAE,CAAxD,IAAAI,KAAAC,KAAAJ,EAAAD,GAAA,GACD5F,EADSgG,EAAA,IAAOA,EAAA,EAEpB,CAGAhM,KAAKkM,uBAAuBnC,EAAUoC,KAAK,OAAQhE,KAAKW,UAAU9C,GAAS,CAC/E,GAEA,CAAAvF,IAAA,wBAAAC,MAIO,WAAqB,IAAA0L,EAAApM,KACxB,GAAKA,KAAKkJ,YAAYS,MAGtB,KAAI0C,EAAiB,IAAIlG,EACzBkG,EAAepG,SAAWjG,KAAKkJ,YAAYS,MAEvC3J,KAAKkJ,YAAYoD,0BAA4BtM,KAAKkJ,YAAYoD,yBAAyB3C,QACvF0C,EAAepG,SAAWjG,KAAKkJ,YAAYoD,yBAAyB3C,OAEpE3J,KAAKkJ,YAAYC,gBACjBkD,EAAenG,OAASlG,KAAKkJ,YAAYC,cAAc7I,MAC3D+L,EAAejG,SAAWmG,SAASnG,SAEnC,IAAIoG,EAAkBxM,KAAKiH,WAAajH,KAAK0G,eAAiB,iBAE9D1G,KAAKyM,uBAAuBjF,UAAU,SAAAG,GAClCyE,EAAKM,uBAA+B/E,EAAMA,MAAO6E,EAAiBH,GAC7D7E,UAAU,SAACoB,GAER+D,eAAe9D,QAAQxC,EAA0BuC,EACrD,EACR,EAAC,CACL,GAEA,CAAAnI,IAAA,sBAAAC,MAGO,WAAmB,IAAAkM,EAAA5M,KAElB6M,EAAYF,eAAe1E,QAAQ5B,GACvC,GAAkB,OAAdwG,EAAoB,CACpB,IAAIC,EAAgB9M,KAAKiH,WAAajH,KAAK0G,eAAiB,gBAAkBmG,EAE9ErC,QAAQkB,IAAI,wCACZ1L,KAAKyM,uBAAuBjF,UAAU,SAAAG,GAClCiF,EAAKF,uBAA+B/E,EAAMA,MAAOmF,EAAe,MAC3DtF,UAAU,WAEPmF,eAAeI,WAAWzG,GAC1BqG,eAAeI,WAAW1G,EAC9B,EACR,EACJ,CACJ,GAEA,CAAA5F,IAAA,yBAAAC,MAMO,SAAuBqF,EAAmBC,GAAgB,IAAAgH,EAAAC,EAAAjN,KAC7D,GAAKA,KAAKkJ,YAAYS,MAItB,KAAIkD,EAAYF,eAAe1E,QAAQ5B,GAEnC6G,EAAqBP,eAAe1E,QAAQ3B,GAG5C6G,EAAkB,IAAIrH,EAC1BqH,EAAgBN,UAAYA,QAAanD,EACzCyD,EAAgBpH,UAAYA,EAC5BoH,EAAgBnH,SAAWA,EAC3BmH,EAAgBD,mBAAqBA,QAAsBxD,EAC3DyD,EAAgBlH,SAAiC,QAAzB+G,EAAGhN,KAAKkJ,YAAYS,aAAK,IAAAqD,IAAI,UAEjDhN,KAAKkJ,YAAYoD,0BAA4BtM,KAAKkJ,YAAYoD,yBAAyB3C,QACvFwD,EAAgBlH,SAAWjG,KAAKkJ,YAAYoD,yBAAyB3C,OACrE3J,KAAKkJ,YAAYC,gBACjBgE,EAAgBjH,OAASlG,KAAKkJ,YAAYC,cAAc7I,MAG5D,IAAI8M,EAAmBpN,KAAKiH,WAAajH,KAAK0G,eAAiB,kBAE/D1G,KAAKyM,uBAAuBjF,UAAU,SAAAG,GAClCsF,EAAKP,uBAA4D/E,EAAMA,MAAOyF,EAAkBD,GAC3F3F,UAAU,SAACoB,GAER+D,eAAe9D,QAAQxC,EAA0BuC,EAAKiE,WACtDF,eAAe9D,QAAQvC,EAA2BsC,EAAKyE,WAC3D,EACR,EAAC,CACL,GAEA,CAAA5M,IAAA,yBAAAC,MAOO,SAA6BiH,EAAe2D,EAAa1C,GAE5D,OAAO5I,KAAK2G,KAAK8B,KAAW6C,EAAK1C,EAAM5I,KAAKsN,qBAAqB3F,GACrE,IAAC,CArPwB,GAqPxBlB,SArPQD,yCAAgB,4BAAhBA,EAAgB9E,QAAhB8E,EAAgB7E,UAAAC,WAFb,SAEH4E,CAAgB,8GCThB+G,EAAoB,eAAAC,EAApBD,EAAoB,SAAAE,GAE7B,SAAAF,EAAYG,GAAkB3N,cAAAC,KAAAuN,IAAA,EAAAtN,KAAAD,KAAAuN,EAAA,CACpBG,GACV,CAEAnN,cAAAgN,EAAAE,IAAA,EAAAjN,KAAA+M,EAAA,EAAA9M,IAAA,8BAAAC,MAGO,SAA4BiN,EAAiBC,GAChD,OAAO5N,KAAK6N,UAAUpF,KAAI,GAAAqF,OAAI9N,KAAKoH,QAAO,kDAAA0G,OAAiDH,GAAWC,EAC1G,GAEA,CAAAnN,IAAA,4BAAAC,MAIO,SAA0BiN,GAC7B,OAAO3N,KAAK6N,UAAUnD,IAAG,GAAAoD,OAAyB9N,KAAKoH,QAAO,yCAAA0G,OAAwCH,GAC1G,GAEA,CAAAlN,IAAA,sBAAAC,MAIO,SAAoBiN,GAA4C,IAA3BI,EAAAvE,UAAAC,OAAA,QAAAC,IAAAF,UAAA,IAAAA,UAAA,GACxC,OAAOxJ,KAAK6N,UAAUnD,IAAG,GAAAoD,OAAyB9N,KAAKoH,QAAO,wCAAA0G,OAAuCH,IAAW,EAAMI,EAC1H,GAEA,CAAAtN,IAAA,wBAAAC,MAKO,SAAsBsN,GACzB,OAAOhO,KAAK6N,UAAUnD,IAAG,GAAAoD,OAAuB9N,KAAKoH,QAAO,0CAAA0G,OAAyCE,GACzG,GAEA,CAAAvN,IAAA,8BAAAC,MAKO,SAA4BiN,EAAiBM,GAChD,OAAOjO,KAAK6N,UAAUpF,KAAI,GAAAqF,OAAuB9N,KAAKoH,QAAO,gDAAA0G,OAA+CH,GAAWM,EAC3H,GAEA,CAAAxN,IAAA,8BAAAC,MAIO,SAA4BiN,EAAiBM,GAChD,OAAOjO,KAAK6N,UAASK,OAAO,GAAAJ,OAAuB9N,KAAKoH,QAAO,gDAAA0G,OAA+CH,EAAO,KAAAG,OAAIG,EAAarI,IAC1I,GAEA,CAAAnF,IAAA,+BAAAC,MAIO,SAA6BiN,EAAiBM,GACjD,OAAOjO,KAAK6N,UAAUM,IAAG,GAAAL,OAAuB9N,KAAKoH,QAAO,iDAAA0G,OAAgDH,EAAO,KAAAG,OAAIG,EAAarI,IAAM,GAC9I,GAEA,CAAAnF,IAAA,mBAAAC,MAIO,WACH,OAAOV,KAAK6N,UAAUnD,IAAG,GAAAoD,OAAwB9N,KAAKoH,QAAO,qCAChDsB,QACG0F,KAAI,SAACxF,GACD,OAAIA,EAAKyF,gBACLzF,EAAKyF,cAAgB,IAAI7I,KAAKoD,EAAKyF,gBAChCzF,CACX,GAEpB,IAAC,CA5E4B,CAAQ0F,KAAWd,SAAvCD,0CAAmBvM,aAAA,4BAAnBuM,EAAmB7L,QAAnB6L,EAAmB5L,UAAAC,WAFhB,SAEH2L,CAAoB,qGCDpBgB,EAAe,eAAAC,EAAfD,EAAe,SAAAd,GAExB,SAAAc,EAAYb,GAAkB3N,cAAAC,KAAAuO,IAAA,EAAAtO,KAAAD,KAAAuO,EAAA,CACpBb,GACV,CAEAnN,cAAAgO,EAAAd,IAAA,EAAAjN,KAAA+N,EAAA,EAAA9N,IAAA,uBAAAC,MAKO,SAAqB+N,GAA0B,IAAAC,EAAAC,EAAAC,EAC9CC,EAAW,IAAIC,SAKnB,GAJAD,EAASE,OAAO,UAA+B,QAAtBL,EAAED,EAAaO,eAAO,IAAAN,IAAI,IACnDG,EAASE,OAAO,cAAuC,QAA1BJ,EAAEF,EAAaQ,mBAAW,IAAAN,IAAI,IAC3DE,EAASE,OAAO,UAA+B,QAAtBH,EAAEH,EAAa9C,eAAO,IAAAiD,IAAI,IAE/CH,EAAaS,YACtB,QAAStO,EAAI,EAAGA,EAAI6N,EAAaS,YAAYzF,OAAQ7I,IACpDiO,EAASE,OAAO,cAAeN,EAAaS,YAAYtO,IAIpD,OAAOZ,KAAK6N,UAAUpF,KAAI,GAAAqF,OAAkB9N,KAAKoH,QAAO,mCAAmCyH,EAC/F,GAEA,CAAApO,IAAA,sBAAAC,MAKO,SAAoByO,GACvB,OAAOnP,KAAK6N,UAAUpF,KAAI,GAAAqF,OAAwB9N,KAAKoH,QAAO,kCAAkC+H,EACpG,IAAC,CAjCuB,CAAQb,KAAWE,SAAlCD,0CAAcvN,aAAA,4BAAduN,EAAc7M,QAAd6M,EAAc5M,UAAAC,WAFX,SAEH2M,CAAe,qGCAfa,EAAc,eAAAC,EAAdD,EAAc,SAAA3B,GAEvB,SAAA2B,EAAY1B,GAAkB3N,cAAAC,KAAAoP,IAAA,EAAAnP,KAAAD,KAAAoP,EAAA,CACpB1B,GACV,CAEAnN,cAAA6O,EAAA3B,IAAA,EAAAjN,KAAA4O,EAAA,EAAA3O,IAAA,aAAAC,MAIO,WACH,OAAOV,KAAK6N,UAAUnD,IAAG,GAAAoD,OAAmB9N,KAAKoH,QAAO,wBAC5D,GAEA,CAAA3G,IAAA,YAAAC,MAKO,SAAUkF,GACb,OAAO5F,KAAK6N,UAAUnD,IAAG,GAAAoD,OAAiB9N,KAAKoH,QAAO,wBAAA0G,OAAuBlI,GACjF,GAEA,CAAAnF,IAAA,kBAAAC,MAIO,WACH,OAAOV,KAAK6N,UAAUnD,IAAG,GAAAoD,OAAmB9N,KAAKoH,QAAO,+BAC5D,GAEA,CAAA3G,IAAA,eAAAC,MAKO,SAAa4O,GAChB,IAAIT,EAAW,IAAIC,SACnBD,SAASE,OAAO,OAAQO,EAAUhP,MAClCuO,EAASE,OAAO,cAAeO,EAAUC,aACzCV,EAASE,OAAO,OAAQO,EAAUE,MAE3BxP,KAAK6N,UAAUpF,KAAI,GAAAqF,OAAiB9N,KAAKoH,QAAO,0BAA0ByH,EACrF,GAEA,CAAApO,IAAA,eAAAC,MAKQ,SAAawF,GACjB,IAAI2I,EAAW,IAAIC,SACnBD,SAASE,OAAO,KAAM7I,EAAON,IAC7BiJ,EAASE,OAAO,OAAQ7I,EAAO5F,MAC/BuO,EAASE,OAAO,cAAe7I,EAAOqJ,aACtCV,EAASE,OAAO,SAAU7I,EAAOuJ,OAAOlE,YAEpCrF,EAAOwJ,UACPb,EAASE,OAAO,WAAY7I,EAAOwJ,UAGhC1P,KAAK6N,UAAUpF,KAAI,GAAAqF,OAAiB9N,KAAKoH,QAAO,0BAA0ByH,EACrF,GAEA,CAAApO,IAAA,eAAAC,MAKO,SAAawF,GAChB,OAAOlG,KAAK6N,UAASK,OAAO,GAAAJ,OAAiB9N,KAAKoH,QAAO,2BAAA0G,OAA0B5H,EAAON,IAC9F,GAEA,CAAAnF,IAAA,gBAAAC,MAKQ,SAAcwF,GAClB,OAAOlG,KAAK6N,UAAUM,IAAG,GAAAL,OAAiB9N,KAAKoH,QAAO,4BAAA0G,OAA2B5H,EAAON,IAAM,GAClG,IAAC,CAhFsB,CAAQ0I,KAAWe,SAAjCD,0CAAapO,aAAA,4BAAboO,EAAa1N,QAAb0N,EAAazN,UAAAC,WAFV,SAEHwN,CAAc,qGCDdO,EAAY,eAAAC,EAAZD,EAAY,SAAAlC,GACxB,SAAAkC,EAAYjC,GAAkB3N,cAAAC,KAAA2P,IAAA,EAAA1P,KAAAD,KAAA2P,EAAA,CACvBjC,GACP,CAEAnN,cAAAoP,EAAAlC,IAAA,EAAAjN,KAAAmP,EAAA,EAAAlP,IAAA,aAAAC,MAKO,SAAWmP,GACjB,OAAO7P,KAAK6N,UAAUpF,KAAI,GAAAqF,OAAe9N,KAAKoH,QAAO,sBAAsByI,EAC5E,GAEA,CAAApP,IAAA,uBAAAC,MAMO,SAAqBoP,EAAiBD,GAC5C,OAAO7P,KAAK6N,UAAUpF,KAAI,GAAAqF,OAAe9N,KAAKoH,QAAO,iCAAA0G,OAAgCgC,GAAYD,EAClG,GAEA,CAAApP,IAAA,iBAAAC,MAIO,SAAeqP,GACrB,OAAO/P,KAAK6N,UAAUpF,KAAI,GAAAqF,OAAe9N,KAAKoH,QAAO,0BAA0B2I,EAChF,GAEA,CAAAtP,IAAA,aAAAC,MAKO,SAAWsP,GACjB,OAAOhQ,KAAK6N,UAAUpF,KAAI,GAAAqF,OAAe9N,KAAKoH,QAAO,sBAAsB4I,EAC5E,GAEA,CAAAvP,IAAA,uBAAAC,MAMO,SAAqBoP,EAAiBE,GAC5C,OAAOhQ,KAAK6N,UAAUpF,KAAI,GAAAqF,OAAe9N,KAAKoH,QAAO,iCAAA0G,OAAgCgC,GAAYE,EAClG,GAEG,CAAAvP,IAAA,aAAAC,MAKO,SAAWsP,GACd,OAAOhQ,KAAK6N,UAASK,OAAO,GAAAJ,OAAe9N,KAAKoH,QAAO,uBAAA0G,OAAsBkC,EAAKpK,IACtF,GAEA,CAAAnF,IAAA,cAAAC,MAKQ,SAAYsP,GAChB,OAAOhQ,KAAK6N,UAAUM,IAAG,GAAAL,OAAe9N,KAAKoH,QAAO,wBAAA0G,OAAuBkC,EAAKpK,IAAM,GAC1F,GAEA,CAAAnF,IAAA,oBAAAC,MAKQ,SAAkBsP,GACtB,OAAOhQ,KAAK6N,UAAUM,IAAG,GAAAL,OAAe9N,KAAKoH,QAAO,8BAAA0G,OAA6BkC,EAAKpK,IAAM,GAChG,GAEA,CAAAnF,IAAA,wBAAAC,MAIO,WACH,OAAOV,KAAK6N,UAAUM,IAAG,GAAAL,OAAe9N,KAAKoH,QAAO,iCAAiC,GACzF,GAEA,CAAA3G,IAAA,kBAAAC,MAIO,SAAgBuP,GACzB,IAAIC,EAAQ,CAAED,MAASA,GACjB,OAAOjQ,KAAK6N,UAAUpF,KAAI,GAAAqF,OAAe9N,KAAKoH,QAAO,2BAA2B8I,EACpF,IAAC,CA7FoB,CAAQ5B,KAAWsB,SAA/BD,0CAAW3O,aAAA,4BAAX2O,EAAWjO,QAAXiO,EAAWhO,UAAAC,WAFX,SAEA+N,CAAY,mICHZQ,GAAc3P,OACvB,SAAA2P,EACW7E,EACA8E,EACAxH,EACAyH,IAA0BtQ,OAAAC,KAAAmQ,GAH1BnQ,KAAAsL,MACAtL,KAAAoQ,SACApQ,KAAA4I,OACA5I,KAAAqQ,cACP,GAIKC,EAAU,eAAAC,EAAVD,EAAU,SAAA1Q,GAKnB,SAAA0Q,IAAA,IAAAxQ,EAAAC,cAAAC,KAAAsQ,IACIxQ,KAAAG,KAAAD,KAAAsQ,IAJIE,UAAY,IAAIC,IAChB3Q,EAAA4Q,MAA0B,GAK9B5Q,EAAK6Q,cAAa9J,OAAOD,MAEzB9G,EAAK0Q,UAAUhJ,UAAU,SAACoJ,GAAO,OAAK9Q,EAAK+Q,QAAQD,EAAQ,GAAE9Q,CACjE,CAACS,cAAA+P,EAAA1Q,IAAA,EAAAY,KAAA8P,EAAA,EAAA7P,IAAA,MAAAC,MAEM,SAAO4K,GAA0E,IAA7DwF,IAAAtH,UAAAC,OAAA,QAAAC,IAAAF,UAAA,KAAAA,UAAA,GAEvB,OAFyDA,UAAAC,OAAA,QAAAC,IAAAF,UAAA,IAAAA,UAAA,IAGrDxJ,KAAK+N,aAEF/N,KAAK+Q,kBAAkBzF,EAAK,MAAO,KAAMwF,EACpD,GAAC,CAAArQ,IAAA,OAAAC,MAEM,SAAQ4K,EAAa1C,GAAwE,IAA7DkI,IAAAtH,UAAAC,OAAA,QAAAC,IAAAF,UAAA,KAAAA,UAAA,GAEnC,OAFqEA,UAAAC,OAAA,QAAAC,IAAAF,UAAA,IAAAA,UAAA,IAGjExJ,KAAK+N,aAEF/N,KAAK+Q,kBAAkBzF,EAAK,OAAQ1C,EAAMkI,EACrD,GAAC,CAAArQ,IAAA,MAAAC,MAEM,SAAO4K,EAAa1C,GACvB,OAAO5I,KAAK+Q,kBAAkBzF,EAAK,MAAO1C,IADRY,UAAAC,OAAA,QAAAC,IAAAF,UAAA,KAAAA,UAAA,GAEtC,GAAC,CAAA/I,IAAA,SAAAC,MAEM,SAAU4K,GACb,OAAOtL,KAAK+Q,kBAAkBzF,EAAK,SAAU,OADnB9B,UAAAC,OAAA,QAAAC,IAAAF,UAAA,KAAAA,UAAA,GAE9B,GAAC,CAAA/I,IAAA,UAAAC,MAEO,SAAQsQ,GAA2B,IAAA5E,EAAApM,KAGvC,OAFAA,KAAKI,SAASJ,KAAK6Q,QAAQvQ,KAAM,oBAAqB,CAAC0Q,IAE/CA,EAAYZ,QAChB,IAAK,OACDpQ,KAAK2Q,WAAWlI,KAAKuI,EAAY1F,IAAK0F,EAAYpI,MAAMpB,UAAU,CAC9DyJ,KAAM,SAACC,GAAU9E,EAAK+E,gBAAgBH,EAAaE,EAAM,EACzDE,MAAO,SAACtG,GAAQsB,EAAKiF,aAAaL,EAAalG,EAAI,IAEvD,MACJ,IAAK,MACD9K,KAAK2Q,WAAWxC,IAAI6C,EAAY1F,IAAK0F,EAAYpI,MAAMpB,UAAU,CAC7DyJ,KAAM,SAACC,GAAU9E,EAAK+E,gBAAgBH,EAAaE,EAAM,EACzDE,MAAO,SAACtG,GAAQsB,EAAKiF,aAAaL,EAAalG,EAAI,IAEvD,MACJ,IAAK,SACD9K,KAAK2Q,WAAUzC,OAAQ8C,EAAY1F,KAAK9D,UAAU,CAC9CyJ,KAAM,SAACC,GAAU9E,EAAK+E,gBAAgBH,EAAaE,EAAM,EACzDE,MAAO,SAACtG,GAAQsB,EAAKiF,aAAaL,EAAalG,EAAI,IAEvD,MACJ,QACI9K,KAAK2Q,WAAWjG,IAAIsG,EAAY1F,KAAK5C,QAAK4I,QAAS9J,UAAU,CACzDyJ,KAAM,SAACC,GAAU9E,EAAK+E,gBAAgBH,EAAaE,EAAM,EACzDE,MAAO,SAACtG,GAAQsB,EAAKiF,aAAaL,EAAalG,EAAI,IAGnE,GAAC,CAAArK,IAAA,kBAAAC,MAEO,SAAgBsQ,EAA6BE,GACjD,IAAMK,EAAMP,EAAYX,aAEpBkB,IACAA,EAAIN,KAAKC,GACTK,EAAIC,YAGRxR,KAAK0Q,MAAMe,QACXzR,KAAK0R,kBACT,GAAC,CAAAjR,IAAA,eAAAC,MAEO,SAAasQ,EAA6BlG,GAC9C,IAAI6G,EAAqB7G,EAER,MAAbA,EAAE2E,SACFkC,EAAgB,CACZP,MAAO,CACHQ,MAAO,0HAEXhK,QAASkD,EAAElD,QACX6H,OAAQ3E,EAAE2E,SAGD,MAAb3E,EAAE2E,SACFkC,EAAgB,CACZP,MAAO,CACHQ,MAAO,0JAEXhK,QAASkD,EAAElD,QACX6H,OAAQ3E,EAAE2E,SAGD,MAAb3E,EAAE2E,SACFkC,EAAgB,CACZP,MAAO,CACHQ,MAAK,0IAEThK,QAASkD,EAAElD,QACX6H,OAAQ3E,EAAE2E,SAKlB,IAAM8B,EAAMP,EAAYX,aACxBkB,EAAIH,MAAMO,GACVJ,EAAIC,WACJxR,KAAK0Q,MAAMe,QACXzR,KAAK0R,kBACT,GAAC,CAAAjR,IAAA,aAAAC,MAEM,WAEH,QAAQE,EAAI,EAAGA,EAAIZ,KAAK0Q,MAAMjH,OAAQ7I,IAClCZ,KAAK0Q,MAAM9P,GAAGyP,aAAamB,WAG/BxR,KAAK0Q,MAAQ,EACjB,GAAC,CAAAjQ,IAAA,oBAAAC,MAEO,SAAkB4K,EAAa8E,EAAgBxH,EAAWkI,GAC9D,IAAMS,EAAM,IAAId,IACVG,EAAU,IAAIT,EAAe7E,EAAK8E,EAAQxH,EAAM2I,GAGlDM,EAAkB7R,KAAK0Q,MAAMoB,KAAK,SAAAhH,GAAC,OAAIA,EAAEQ,MAAQA,GAAOR,EAAEsF,SAAWA,GAAUjI,KAAKW,UAAUgC,EAAElC,QAAUT,KAAKW,UAAUF,EAAK,GAClI,GAAIiJ,GAAmBf,EAAkB,CACrCtG,QAAQkB,IAAI,yBAA0BkF,EAASiB,GAE/C,IAAIE,EAAQ/R,KAAK0Q,MAAM7F,UAAU,SAAAC,GAAC,OAAIA,EAAEQ,MAAQA,GAAOR,EAAEsF,SAAWA,GAAUjI,KAAKW,UAAUgC,EAAElC,QAAUT,KAAKW,UAAUF,EAAK,GACzHmJ,EAAQ,IACRF,EAAgBxB,aAAamB,WAC7BxR,KAAK0Q,MAAM1F,OAAO+G,EAAO,GAEjC,CAEA,OAAA/R,KAAK0Q,MAAMlF,KAAKoF,GAEU,IAAtB5Q,KAAK0Q,MAAMjH,QACXzJ,KAAK0R,mBAEFH,CACX,GAAC,CAAA9Q,IAAA,mBAAAC,MAEO,WAEAV,KAAK0Q,MAAMjH,OAAS,GACpBzJ,KAAK6Q,QAAQ7Q,KAAK0Q,MAAM,GAEhC,IAAC,CA5JkB,CAAQ3P,KAAkBwP,SAApCD,yCAAS,4BAATA,EAAS5O,QAAT4O,EAAS3O,UAAAC,WADI,SACb0O,CAAU,mICTDhC,EAAY,SAAA1O,GAM9B,SAAA0O,EAAY0D,GAAmB,IAAAlS,EAAAC,cAAAC,KAAAsO,IAC3BxO,KAAAG,KAAAD,KAAAsO,IAEKqC,WAAaqB,EAAUtH,IAAI9D,MAChC9G,EAAK+N,aAAYhH,OAAOyJ,KACxBxQ,EAAKsH,QAAUF,IAAY+K,SAAS7K,QAAQtH,CAChD,CAACS,cAAA+N,EAAA1O,IAAA,EAAAY,KAAA8N,EAAA,CAZ6B,CAAQvN,+LCD7BmR,GAAY1R,OA6FrB,SAAA0R,KAAAnS,OAAAC,KAAAkS,GAzFOlS,KAAAmS,iBAA2B,EAI3BnS,KAAAoS,sBAAgC,EA4ChCpS,KAAAqS,oBAA8B,EAI9BrS,KAAAsS,SAAsB3N,IAAUR,KAmChCnE,KAAAiQ,MAAgB,UAGnBjQ,KAAKuS,QAAU,GACfvS,KAAKwS,OAAS,GACdxS,KAAKyS,MAAQ,GACbzS,KAAK0S,aAAe,GACpB1S,KAAK2S,YAAc,IAAInN,KACvBxF,KAAK4S,aAAe,EACxB,iCC5FSC,EAA4B,eAAAC,EAA5BD,EAA4B,SAAAjT,GAOrC,SAAAiT,IAAA,IAAA/S,EAAAC,cAAAC,KAAA6S,IACI/S,KAAAG,KAAAD,KAAA6S,IACKzS,SAASN,EAAKO,YAAYC,KAAM,2CAA2CR,CACpF,CAEAS,cAAAsS,EAAAjT,IAAA,EAAAY,KAAAqS,EAAA,EAAApS,IAAA,mBAAAC,MAIO,SAAiBqS,GACpB/S,KAAKI,SAASJ,KAAKgT,iBAAiB1S,KAAM,2BAA4B,CAACyS,IAEvE,IAAI7M,EAAwB,KAS5B,KANAA,EAAS6M,EAAM3I,SAASM,IAAI,YACbqI,EAAM1H,SAAS5B,OAAS,IACnCvD,EAAS6M,EAAM1H,SAAS,GAAGjB,SAASM,IAAI,YAIvCxE,EAAQ,CACTlG,KAAKI,SAASJ,KAAKgT,iBAAiB1S,KAAM,sDAC1C,IAAI2S,EAAQC,OAAOC,SAASC,SAASC,MAAM,KAEvCC,EAAgBL,EAAMpI,UAAU,SAAAC,GAAC,MAAU,SAANA,CAAY,GACjDwI,GAAgB,GACiB,oBAA7BL,EAAMK,EAAgB,KACtBpN,EAAS+M,EAAMK,EAAgB,GAE3C,CAGA,IAAKpN,EAAQ,CACTlG,KAAKI,SAASJ,KAAKgT,iBAAiB1S,KAAM,2DAC1C,IAAIiT,EAAYL,OAAOC,SAASK,SAASH,MAAM,KAG3CnN,EADqB,IAArBqN,EAAU9J,OACD8J,EAAU,GAEVL,OAAOC,SAASK,SAASH,MAAM,KAAKI,MAAM,GAAG,GAAItH,KAAK,IACvE,CAGA,QAAKjG,GAAUgB,IAAYwM,gBAAgBC,SAASzN,EAAO0N,kBACvD1N,EAAS,SAGblG,KAAKI,SAASJ,KAAKgT,iBAAiB1S,KAAM,yBAA0B,CAAC4F,IAC9DA,CACX,GAEA,CAAAzF,IAAA,kBAAAC,MAIO,SAAgBqS,GAA6B,IAAAc,EAChD7T,KAAKI,SAASJ,KAAK8T,gBAAgBxT,KAAM,0BAA2B,CAACyS,IAErE,IAAI/I,EAAuB,KAE3BA,UAAQ+I,EAAM3I,SAASM,IAAI,WACbqI,EAAM1H,SAAS5B,OAAS,IAClCO,EAAQ+I,EAAM1H,SAAS,GAAGjB,SAASM,IAAI,UAG3C1K,KAAKI,SAASJ,KAAK8T,gBAAgBxT,KAAM,wBAAyB,CAAC0J,IACvD,QAAZ6J,EAAO7J,SAAK,IAAA6J,SAAInK,CACpB,GAEA,CAAAjJ,IAAA,oCAAAC,MAIO,SAAkCqS,GACrC,OAAA/S,KAAKI,SAASJ,KAAK+T,kCAAkCzT,KAAM,2CAA4C,CAACyS,EAAMiB,eAEvGjB,EAAMiB,aAAanJ,UAAU,SAAAC,GAAC,IAAAmJ,EAAA,MAA4B,qBAAX,QAAbA,EAAAnJ,EAAEoJ,mBAAW,IAAAD,OAAA,EAAbA,EAAeE,KAA0B,IAAI,CAC1F,GAEA,CAAA1T,IAAA,+BAAAC,MAIO,SAA6BqS,GAChC,OAAA/S,KAAKI,SAASJ,KAAKoU,6BAA6B9T,KAAM,sCAAuC,CAACyS,EAAMiB,eAE7FjB,EAAMiB,aAAanJ,UAAU,SAAAC,GAAC,IAAAuJ,EAAA,MAA4B,UAAX,QAAbA,EAAAvJ,EAAEoJ,mBAAW,IAAAG,OAAA,EAAbA,EAAeF,KAAe,IAAI,CAC/E,GAEA,CAAA1T,IAAA,6BAAAC,MAGO,SAA2BqS,GAC9B,OAAA/S,KAAKI,SAASJ,KAAKsU,2BAA2BhU,KAAM,mCAAoC,CAACyS,IAElFA,EAAMiB,aAAanJ,UAAU,SAAAC,GAAC,IAAAyJ,EAAA,MAA4B,aAAX,QAAbA,EAAAzJ,EAAEoJ,mBAAW,IAAAK,OAAA,EAAbA,EAAeJ,KAAkB,IAAI,CAClF,GAEA,CAAA1T,IAAA,2BAAAC,MAIO,SAAyB8T,GAC5B,OAAAxU,KAAKI,SAASJ,KAAKyU,yBAAyBnU,KAAM,iCAAkC,CAACkU,IAG9EA,EAAMlJ,IAAIqI,SAAS,QAC9B,GAEA,CAAAlT,IAAA,+BAAAC,MAIO,SAA6B8T,GAChC,OAAAxU,KAAKI,SAASJ,KAAK0U,6BAA6BpU,KAAM,qCAAsC,CAACkU,IAGtFA,EAAMlJ,IAAIqI,SAAS,YAC9B,GAEA,CAAAlT,IAAA,qBAAAC,MAOO,SAAmByR,EAA0BwC,EAAgBC,EAAejL,GAE/E,IAAIkL,EAA6B,IAAI3C,EACrC2C,SAAa1C,gBAAkBA,EAC/B0C,EAAaC,WAAaH,EAC1BE,EAAaD,MAAQA,EACrBC,EAAalL,MAAQA,EACrBkL,EAAaxC,oBAAqB,EAE3BwC,CACX,GAEA,CAAApU,IAAA,yBAAAC,MAIO,SAAuBmU,EAA4BE,EAAwB7O,EAAiC8D,GAC/GhK,KAAKI,SAASJ,KAAKgV,uBAAuB1U,KAAM,sCAEhD,IACF2U,GADkB,IAAIC,MACGC,YAAYJ,EAAWpN,OAE1CyN,EAASH,EAAa,wEACtBtL,EAAQsL,EAAa,sEACrBI,GAAYJ,EAAa,mEACzBK,EAAUL,EAAa,iEACvB5C,GAAqB4C,EAAa,iCAClC3C,EAAW2C,EAAa,uBACxBxC,GAAQwC,EAAa,gEACrBM,GAAaN,EAAa,oBAE9BJ,SAAa1L,cAAgBjD,EAC7B2O,EAAazL,aAAeY,EAC5B6K,EAAaO,OAASA,EACtBP,EAAalL,MAAQA,EACrBkL,EAAaQ,UAAYA,GACzBR,EAAaW,SAAWF,EACxBT,EAAaxC,mBAA2D,SAArCA,GAAmBuB,cACtDiB,EAAavC,SAAWA,EACxBuC,EAAa5E,MAAQsF,GACrBV,EAAapC,MAAQA,GACrBoC,EAAanC,aAAeqC,EAAWpN,MACvCkN,EAAalC,YAAc,IAAInN,KAAKuP,EAAWzM,YAC/CuM,EAAajC,aAAemC,EAAWnC,aAEvC5S,KAAKI,SAASJ,KAAKgV,uBAAuB1U,KAAM,oCAAqC,CAACuU,IAC/EA,CACX,GAEA,CAAApU,IAAA,cAAAC,MAGO,WACH,OAAOwS,OAAOC,SAASC,QAC3B,IAAC,CA7LoC,CAAQrS,KAAkB+R,SAAtDD,yCAA2B,4BAA3BA,EAA2BnR,QAA3BmR,EAA2BlR,UAAAC,WAFxB,SAEHiR,CAA4B,cCO5BvL,EAAsB,eAAAmO,EAAtBnO,EAAsB,SAAA1H,GAkC/B,SAAA0H,EAAoBoO,EAAmEC,GAAkB,IAAA7V,EAAAC,cAAAC,KAAAsH,IACrGxH,KAAAG,KAAAD,KAAAsH,IADgBoO,oBAAmE5V,EAAA6V,WAhC/E7V,EAAA8V,gBAAoC/O,OAAOgP,KAC3C/V,EAAAgW,iBAA+BjP,OAAOuI,KACtCtP,EAAAiW,oBAAqClP,OAAOmP,KAC5ClW,EAAAmW,uBAA2CpP,OAAO0G,KAClDzN,EAAAoW,+BAA2DrP,OAAOgM,GAClE/S,EAAAiH,UAAiBF,OAAOG,MAKflH,EAAAqW,cAAgB,IAAIC,IAA8B,IAAIlE,GAMhEpS,EAAA+U,aAAe,kBAAoB/U,EAAKqW,cAAcE,UAAU,EAMhEvW,EAAAyH,cAAgB,kBAAgCzH,EAAKqW,cAAcG,cAAc,EAEjFxW,EAAAyW,gBAA0B,GAC1BzW,EAAA0W,eAAqC,GASxC1W,EAAKM,SAASN,EAAKO,YAAYC,KAAM,oCAAoCR,CAC7E,CAEAS,cAAA+G,EAAA1H,IAAA,EAAAY,KAAA8G,EAAA,EAAA7G,IAAA,OAAAC,OAAA+V,KAAAC,MAAAC,SAAAC,KAIO,SAAAC,EAAW9D,EAA+ByB,GAA0B,IAAAtO,EAAA8D,EAAA6K,EAAAiC,EAAAC,GAAAC,EAAA,SAAAL,OAAAM,KAAA,SAAAC,GAAA,cAAAA,EAAAC,KAAAD,EAAAjG,MAAA,OAQnB,GAPpDjR,KAAKI,SAASJ,KAAKoX,KAAK9W,KAAM,6BAEhC4F,EAASlG,KAAKkW,4BAA4BlD,iBAAiBD,GACzD/S,KAAKuW,gBAAkBrQ,EACnB8D,EAAQhK,KAAKkW,4BAA4BpC,gBAAgBf,GAC7D/S,KAAKwW,eAAiBxM,IAElB6K,EAA6B7U,KAAK6U,gBACrBzC,qBAAoB,CAAA8E,EAAAjG,KAAA,SAEjC,GADTjR,KAAKI,SAASJ,KAAKoX,KAAK9W,KAAM,+CAEI,IAArByS,EAAMzH,IAAI7B,OAAY,CAAAyN,EAAAjG,KAAA,SACtB,OAAAjR,KAAKI,SAASJ,KAAKoX,KAAK9W,KAAM,4BAA4B4W,EAAAG,OAAA,sBAI/B,QAA1BP,EAAAjC,EAAa1L,qBAAa,IAAA2N,OAAA,EAA1BA,EAA4BvH,eAAgBrJ,IAAqC,QAAzB6Q,GAAAlC,EAAazL,oBAAY,IAAA2N,QAAA,EAAzBA,GAA2BzW,QAAS0J,EAAM,CAAAkN,EAAAjG,KAAA,SACnG,OAAAjR,KAAKI,SAASJ,KAAKoX,KAAK9W,KAAM,8DAA8D4W,EAAAG,OAAA,mBAKnE,QAAzBL,EAAAnC,EAAazL,oBAAY,IAAA4N,OAAA,EAAzBA,EAA2B1W,QAAS0J,GACpChK,KAAKI,SAASJ,KAAKoX,KAAK9W,KAAM,wDAEjC,QAAA4W,SAAAC,KAAA,GAAAD,EAAAjG,KAAA,GAIKjR,KAAKsX,kBAAkBvE,EAAOyB,EAAOtO,EAAQ8D,EAAO6K,GAAa,QAAAqC,EAAAjG,KAAA,iBAAAiG,EAAAC,KAAA,GAAAD,EAAAK,GAAAL,EAAAM,MAAA,IAGvExX,KAAKyX,SAASzX,KAAKoX,KAAK9W,KAAM,6BAA8B,CAAA4W,EAAAK,KAAK,QAErEvX,KAAKI,SAASJ,KAAKoX,KAAK9W,KAAM,8BAA8B,yBAAA4W,EAAAQ,OAAA,EAAAb,EAAA7W,KAAA,cAC/D,SApCYoX,EAAIO,EAAAC,GAAA,OAAAnB,EAAAoB,MAAA7X,KAAAwJ,UAAA,IAsCjB,CAAA/I,IAAA,oBAAAC,MAAA,eAAAoX,KAAApB,MAAAC,SAAAC,KAOO,SAAAmB,EAAwBhF,EAA+ByB,EAA4BtO,EAAgB8D,EAA2B6K,GAAsC,IAAA1L,EAAAC,GAAA,SAAAuN,OAAAM,KAAA,SAAAe,GAAA,cAAAA,EAAAb,KAAAa,EAAA/G,MAAA,OAIvK,GAHAjR,KAAKI,SAASJ,KAAKsX,kBAAkBhX,KAAM,wBACvC6I,OAAyCO,EACzCN,QAAuCM,EAEtCmL,GAAiBA,EAAazC,qBAAoB,CAAA4F,EAAA/G,KAAA,SAAA+G,SAAA/G,KAAA,EAC9BjR,KAAKiY,yBAAwB,OAAlDpD,SAAYmD,EAAAE,KAAAF,EAAA/G,KAAA,EAGMjR,KAAK4V,aAAauC,kBAAkBtD,EAAaC,WAAYD,EAAaD,MAAOC,EAAalL,MAAOzD,OAAQwD,GAAU,OAArI/B,OAEJkN,EAAe7U,KAAKkW,4BAA4BlB,uBAAuBH,EAF9DmD,EAAAE,UAEmFxO,OAAWA,GACvGsO,EAAA/G,KAAA,MAC6BmH,KAAcpY,KAAK8V,cAAcuC,mBAAkB,QAAhFxD,EAAatC,QAAOyF,EAAAE,KACpBlY,KAAKmW,cAAclF,KAAK4D,GAAc,QAK1C,KAFA1L,EAAgBnJ,KAAKsY,qBAAqBzD,EAAc3O,EAAQ6M,IAG/C,CAAAiF,EAAA/G,KAAA,SAAA+G,SAAA/G,KAAA,GAEPjR,KAAKuY,aAAapP,GAAc,QAEjCnJ,KAAKkW,4BAA4B9B,6BAA6BrB,KAC/D3J,GAAepJ,KAAKwY,oBAAoB3D,EAAc7K,IACzD,YAIDZ,GAAY,CAAA4O,EAAA/G,KAAA,SAAA+G,SAAA/G,KAAA,GACNjR,KAAKyY,YAAYrP,IAAa,SAIxCyL,EAAe7U,KAAK6U,gBACPzC,sBAAuB,EACpCpS,KAAKmW,cAAclF,KAAK4D,GACxB7U,KAAKI,SAASJ,KAAKsX,kBAAkBhX,KAAM,uBAE3CN,KAAK0Y,aAAa3F,EAAOyB,GAAO,yBAAAwD,EAAAN,OAAA,EAAAK,EAAA/X,KAAA,IAxCN,OAyC7B,SAzCYsX,EAAiBqB,EAAAC,EAAAC,EAAAC,EAAAC,GAAA,OAAAjB,EAAAD,MAAA7X,KAAAwJ,UAAA,EAP9B,IAkDA,CAAA/I,IAAA,yBAAAC,MAAA,eAAAsY,KAAAtC,MAAAC,SAAAC,KAIO,SAAAqC,IAAA,IAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAA3E,EAAAC,GAAAjL,EAAArJ,GAAAuU,EAAA0E,GAAA,SAAA5C,OAAAM,KAAA,SAAAuC,IAAA,cAAAA,GAAArC,KAAAqC,GAAAvI,MAAA,OACH,OAAAjR,KAAKI,SAASJ,KAAKiY,uBAAuB3X,KAAM,8BAEhDkZ,GAAAvI,KAAA,EAC0BjR,KAAKyZ,YAAW,OAAtCH,OACA3E,EAA2C,QAArCuE,GADNI,EAAME,GAAAtB,MACUpG,KAAK,SAAA4H,IAAC,MAAe,QAAXA,GAAEpZ,IAAc,UAAC,IAAA4Y,OAAA,EAAlCA,EAAoCxY,MAC7CkU,GAA0C,QAArCuE,EAAGG,EAAOxH,KAAK,SAAA4H,IAAC,MAAe,QAAXA,GAAEpZ,IAAc,UAAC,IAAA6Y,OAAA,EAAlCA,EAAoCzY,MAC5CiJ,EAA4C,QAAvCyP,EAAGE,EAAOxH,KAAK,SAAA4H,IAAC,MAAe,UAAXA,GAAEpZ,IAAgB,UAAC,IAAA8Y,OAAA,EAApCA,EAAsC1Y,MAC9CJ,GAA0C,QAAtC+Y,EAAGC,EAAOxH,KAAK,SAAA4H,IAAC,MAAe,SAAXA,GAAEpZ,IAAe,UAAC,IAAA+Y,OAAA,EAAnCA,EAAqC3Y,MAE5CmU,EAA6B7U,KAAKkW,4BAA4ByD,oBAAmB,EAAMhF,EAAQC,GAAOjL,GAEtGrJ,KACIiZ,GAAQjZ,GAAK+S,MAAM,KACvBwB,EAAaQ,UAAYkE,GAAM,GAC/B1E,EAAaW,SAAW+D,GAAM,IAGlCvZ,KAAKmW,cAAclF,KAAK4D,GAExB7U,KAAKI,SAASJ,KAAKiY,uBAAuB3X,KAAM,6BAA6BkZ,GAAAnC,OAAA,SACtExC,GAAY,yBAAA2E,GAAA9B,OAAA,EAAAuB,EAAAjZ,KAAA,IArBY,OAsBlC,SAtBYiY,IAAsB,OAAAe,EAAAnB,MAAA7X,KAAAwJ,UAAA,EAJnC,IA4BA,CAAA/I,IAAA,YAAAC,MAAA,eAAAkZ,KAAAlD,MAAAC,SAAAC,KAIO,SAAAiD,IAAA,SAAAlD,OAAAM,KAAA,SAAA6C,GAAA,cAAAA,EAAA3C,KAAA2C,EAAA7I,MAAA,OAAA6I,SAAA7I,KAAA,EAC4BjR,KAAK2V,SAASoE,aAAarP,IAAI,WAAqB,OAA7EsP,OAAOF,EAAAzC,OAAA,SACNvL,OAAOC,QADD+N,EAAA5B,KACiBoB,QAAQlL,IAAI,SAAA6L,GAAK,MAAK,CAAE3Z,KAAM2Z,EAAM,GAAIvZ,MAAOuZ,EAAM,GAAI,IAAE,wBAAAH,EAAApC,OAAA,EAAAmC,EAAA7Z,KAAA,IAFvE,OAGrB,SAHYyZ,IAAS,OAAAG,EAAA/B,MAAA7X,KAAAwJ,UAAA,EAJtB,IASA,CAAA/I,IAAA,SAAAC,MAAA,eAAAwZ,KAAAxD,MAAAC,SAAAC,KAIO,SAAAuD,IAAA,SAAAxD,OAAAM,KAAA,SAAAmD,GAAA,cAAAA,EAAAjD,KAAAiD,EAAAnJ,MAAA,OAEHjR,KAAKmW,cAAclF,KAAK,IAAIiB,GAC5BlS,KAAKmW,cAAc3E,WAEnBxR,KAAK2V,SAAS0E,UAAU,wBAAAD,EAAA1C,OAAA,EAAAyC,EAAAna,KAAA,IALT,OAMlB,SANYsa,IAAM,OAAAJ,EAAArC,MAAA7X,KAAAwJ,UAAA,EAJnB,IAYA,CAAA/I,IAAA,uBAAAC,MAGO,SAAqBmU,EAA4B1L,EAAuB4J,GAI3E,GAHA/S,KAAKI,SAASJ,KAAKsY,qBAAqBhY,KAAM,oCAGV,IAAhCuU,EAAatC,QAAQ9I,OAAzB,CAKA,IAAI8Q,EAAmB1F,EAAatC,QAAQT,KAAK,SAAA0I,GAAC,OAAIA,EAAEjL,YAAYqE,gBAAkBzK,EAAcyK,aAAa,GACjH,GAAI2G,EACA,OAAAva,KAAKI,SAASJ,KAAKsY,qBAAqBhY,KAAM,wCAAyC,CAAC6I,IACjFoR,EAIX,GAAyB,IAArBxH,EAAMzH,IAAI7B,OAGV,IAFAzJ,KAAKI,SAASJ,KAAKsY,qBAAqBhY,KAAM,gCAE1CuU,EAAatC,QAAQ9I,OAAS,GAI9B,OAAAzJ,KAAKI,SAASJ,KAAKsY,qBAAqBhY,KAAM,mEACvCuU,EAAatC,QAAQ,GAJ5BvS,KAAKI,SAASJ,KAAKsY,qBAAqBhY,KAAM,8CAIjB,CAjBrC,MAFIN,KAAKI,SAASJ,KAAKsY,qBAAqBhY,KAAM,+CAwBtD,GAEA,CAAAG,IAAA,sBAAAC,MAIO,SAAoBmU,EAA4B4F,GAGnD,GAFAza,KAAKI,SAASJ,KAAKwY,oBAAoBlY,KAAM,mCAEV,IAA/BuU,EAAarC,OAAO/I,QAMxB,GAAKgR,EAIL,KAAIC,EAAkB7F,EAAarC,OAAOV,KAAK,SAAA0I,GAAC,OAAIA,EAAEla,KAAKsT,gBAAkB6G,GAAY7G,aAAa,GACtG,YAAwBlK,IAApBgR,GACA1a,KAAKI,SAASJ,KAAKwY,oBAAoBlY,KAAM,8CAA+C,CAACma,IAI1FC,QAfH1a,KAAKI,SAASJ,KAAKwY,oBAAoBlY,KAAM,8CAgBrD,GAAC,CAAAG,IAAA,eAAAC,MAEM,SAAaqS,EAA+ByB,GAC/CxU,KAAKI,SAASJ,KAAK0Y,aAAapY,KAAM,+BAAgC,CAACyS,IACvE,IAAI8B,EAAe7U,KAAK6U,eAExB,GAAoC,IAAhCA,EAAatC,QAAQ9I,OAKzB,QAAmCC,IAA/BmL,EAAa1L,eAejB,IAAInJ,KAAKkW,4BAA4B9B,6BAA6BrB,KAG9D/S,KAAKkW,4BAA4B5B,2BAA2BvB,KAI5D/S,KAAKkW,4BAA4BnC,kCAAkChB,GAIvE,KAAM/S,KAAKkW,4BAA4BzB,yBAAyBD,KAAWxU,KAAKkW,4BAA4BxB,6BAA6BF,IAAgC,IAArBzB,EAAMzH,IAAI7B,OAAc,CAExK,GAAmC,IAA/BoL,EAAarC,OAAO/I,OAEpB,YADAzJ,KAAK+G,OAAO4T,SAAS,CAAC,OAAQ9F,EAAa1L,cAAcoG,YAAa,aAI1E,QAAkC7F,IAA9BmL,EAAazL,aAEb,YADApJ,KAAK+G,OAAO4T,SAAS,CAAC,OAAQ9F,EAAa1L,cAAcoG,YAAa,aAG9E,CACAvP,KAAKI,SAASJ,KAAK0Y,aAAapY,KAAM,0BAAyB,MAtC/D,CAEI,GAAyB,IAArByS,EAAMzH,IAAI7B,QAAgBoL,EAAatC,QAAQ9I,OAAS,EAExD,YADAzJ,KAAK+G,OAAO4T,SAAS,CAAC,OAAQ,oBAIlC,GAAyB,IAArB5H,EAAMzH,IAAI7B,QAAsC,oBAAtBsJ,EAAMzH,IAAI,GAAG6I,KACvC,OAGJnU,KAAK+G,OAAO4T,SAAS,CAAC,gBAE1B,MAjBI3a,KAAK+G,OAAO4T,SAAS,CAAC,gBA2C9B,GAEA,CAAAla,IAAA,4BAAAC,MAIO,SAA0BqU,EAAwB7O,EAAiC8D,GACtFhK,KAAKI,SAASJ,KAAK4a,0BAA0Bta,KAAM,sCACnD,IAAIuU,EAAe7U,KAAK6U,eAExBA,EAAe7U,KAAKkW,4BAA4BlB,uBAAuBH,EAAcE,EAAY7O,EAAQ8D,GACzGhK,KAAKmW,cAAclF,KAAK4D,GACxB7U,KAAKI,SAASJ,KAAK4a,0BAA0Bta,KAAM,oCAAqC,CAACuU,GAC7F,GAEA,CAAApU,IAAA,iCAAAC,MAIO,SAA+Bma,GAClC7a,KAAKI,SAASJ,KAAK8a,+BAA+Bxa,KAAM,oCAAqC,CAACua,IAC9F7a,KAAKmW,cAAclF,KAAK4J,GACxB7a,KAAKI,SAASJ,KAAK8a,+BAA+Bxa,KAAM,mCAAoC,CAACua,GACjG,GAEA,CAAApa,IAAA,eAAAC,MAAA,eAAAqa,KAAArE,MAAAC,SAAAC,KAIO,SAAAoE,EAAmB9U,GAAmB,IAAA2O,EAAArC,EAAA,SAAAmE,OAAAM,KAAA,SAAAgE,GAAA,cAAAA,EAAA9D,KAAA8D,EAAAhK,MAAA,OACzC,OAAAjR,KAAKI,SAASJ,KAAKuY,aAAajY,KAAM,mBAAoB,CAAC4F,IACvD2O,EAAe7U,KAAK6U,eACxBoG,EAAAhK,KAAA,EACkBjR,KAAK4V,aAAauC,kBAAkBtD,EAAaC,WAAYD,EAAaD,MAAOC,EAAalL,MAAOzD,EAAOqJ,iBAAa7F,GAAU,OAAjJ/B,OAEJkN,EAAe7U,KAAKkW,4BAA4BlB,uBAAuBH,EAF9DoG,EAAA/C,KAEmFhS,OAAQwD,GACpG1J,KAAKmW,cAAclF,KAAK4D,GACxBoG,EAAAhK,KAAA,KACmBmH,KAAcpY,KAAK+V,iBAAiBmF,kBAAiB,OAApE1I,OACJxS,KAAKmb,aADD3I,EAAMyI,EAAA/C,MAEV+C,EAAA5D,OAAA,SACO7E,GAAM,yBAAAyI,EAAAvD,OAAA,EAAAsD,EAAAhb,KAAA,IAZQ,OAaxB,SAbYuY,EAAY6C,GAAA,OAAAL,EAAAlD,MAAA7X,KAAAwJ,UAAA,EAJzB,IAmBA,CAAA/I,IAAA,gBAAAC,MAIO,SAAc6R,GACjBvS,KAAKI,SAASJ,KAAKqb,cAAc/a,KAAM,mBAAoB,CAACiS,IAC5D,IAAIsC,EAAe7U,KAAK6U,eACxBA,EAAatC,QAAUA,EACvBvS,KAAKmW,cAAclF,KAAK4D,EAC5B,GAEA,CAAApU,IAAA,eAAAC,MAIO,SAAa8R,GAChBxS,KAAKI,SAASJ,KAAKmb,aAAa7a,KAAM,kBAAmB,CAACkS,IAC1D,IAAIqC,EAAe7U,KAAK6U,eACxBA,EAAarC,OAASA,EAAO8I,OAAO,SAAAxQ,GAAC,OAAIA,EAAEyQ,cAAc,GACzDvb,KAAKmW,cAAclF,KAAK4D,EAC5B,GAEA,CAAApU,IAAA,cAAAC,MAAA,eAAA8a,KAAA9E,KAIO,SAAkB1M,GAAiB,IAAAoC,EAAApM,KAAE+N,EAAAvE,UAAAC,OAAA,QAAAC,IAAAF,UAAA,IAAAA,UAAA,GAA2B,OAAAmN,SAAAC,KAAA,SAAA6E,IAAA,IAAA5G,EAAA,SAAA8B,OAAAM,KAAA,SAAAyE,GAAA,cAAAA,EAAAvE,KAAAuE,EAAAzK,MAAA,OACnE7E,SAAKhM,SAASgM,EAAKqM,YAAYnY,KAAM,kBAAmB,CAAC0J,IACrD6K,EAAezI,EAAKyI,eACxB6G,EAAAzK,KAAA,KACqBmH,KAAchM,EAAK6J,oBAAoB0F,oBAAoB3R,EAAMpE,GAAImI,IAAY,OAAlG6N,OACJ5R,EAAM6R,mBADMH,EAAAxD,KAEZwD,EAAAzK,KAAA,EACkB7E,EAAKwJ,aAAauC,kBAAkBtD,EAAaC,WAAYD,EAAaD,MAAOC,EAAalL,MAAqC,MAA9BkL,EAAa1L,cAAwB,GAAK0L,EAAa1L,cAAcoG,YAAavF,EAAMpE,IAAG,OAElNiP,EAAezI,EAAK8J,4BAA4BlB,uBAAuBH,EAF9D6G,EAAAxD,KAEmFrD,EAAa1L,cAAea,GACxHoC,EAAK+J,cAAclF,KAAK4D,GAAc,yBAAA6G,EAAAhE,OAAA,EAAA+D,EAAA,EAV6B9E,EAU7B,GAVlB,OAWvB,SAXY8B,EAAWqD,GAAA,OAAAN,EAAA3D,MAAA7X,KAAAwJ,UAAA,EAJxB,IAiBA,CAAA/I,IAAA,uBAAAC,MAIO,SAAqBqb,GACxB/b,KAAKI,SAASJ,KAAKgc,qBAAqB1b,KAAM,8BAA+B,CAACyb,IAC9E,IAAIlH,EAAe7U,KAAK6U,eACxBA,EAAakH,kBAAoBA,EACjC/b,KAAKmW,cAAclF,KAAK4D,EAC5B,GAEA,CAAApU,IAAA,2BAAAC,MAGO,WACHV,KAAKI,SAASJ,KAAKic,yBAAyB3b,KAAM,sCAClD,IAAIuU,EAAe7U,KAAK6U,eACxBA,EAAaxC,oBAAqB,EAClCrS,KAAKmW,cAAclF,KAAK4D,EAC5B,GAEA,CAAApU,IAAA,WAAAC,MAGO,SAASwb,GACZlc,KAAKI,SAASJ,KAAKmc,SAAS7b,KAAM,qBAClC,IAAIuU,EAAe7U,KAAK6U,eACxBA,EAAa5E,MAAQiM,EACrBlc,KAAKmW,cAAclF,KAAK4D,EAC5B,KAzWA,IAAA4B,CAyWC,CAhZ8B,CAAQ1V,KAAkB0U,SAAhDnO,0CAAqBtG,MAAAC,MAAAD,MAkCuCob,MAAS,4BAlCrE9U,EAAqB5F,QAArB4F,EAAqB3F,UAAAC,WAFlB,SAEH0F,CAAsB,wKCVtB+U,EAAqB,eAAAC,EAArBD,EAAqB,SAAA5O,GAK9B,SAAA4O,EAAY3O,GAAkB,IAAA5N,EAAAC,cAAAC,KAAAqc,IAC1Bvc,KAAAG,KAAAD,KAAAqc,EAAA,CAAM3O,KAHF6O,yBAA+C1V,OAAOS,KAK1DxH,EAAKiH,UAASF,OAAOG,MAAQlH,CACjC,CAEAS,cAAA8b,EAAA5O,IAAA,EAAAjN,KAAA6b,EAAA,EAAA5b,IAAA,4BAAAC,OAAA8b,KAAA9F,MAAAC,SAAAC,KAIO,SAAAmB,EAAgC3C,EAAgBtF,GAAgB,IAAA2M,EAAA5B,EAAAxS,EAAAqU,EAAAC,EAAAC,EAAAxQ,EAAApM,KAAA,SAAA2W,OAAAM,KAAA,SAAAe,GAAA,cAAAA,EAAAb,KAAAa,EAAA/G,MAAA,OACnE,OAAAjR,KAAKI,SAASJ,KAAK6c,0BAA0Bvc,KAAM,yBAA0B,CAAC8U,EAAQtF,IAElF2M,KAAcxT,KAAA,GAAOjJ,KAAKuc,sBAAsB1H,gBACpDmD,EAAA/G,KAAA,KACoCmH,KAAcpY,KAAK8c,sCAAsC1H,EAAQtF,IAAU,QAA3G+K,EAAuB7C,EAAAE,MAEH/F,iBAAkB,EAC1C0I,EAAwBzI,sBAAuB,EAC/CyI,EAAwBxI,oBAAqB,EAC7CwI,EAAwBjI,aAAe,GACvCiI,EAAwBkC,sBAAwB/c,KAAK+G,OAAOuE,IAC5DuP,EAAwBvO,yBAA2BmQ,EAEnDzc,KAAKuc,sBAAsBzB,+BAA+BD,GAEtDxS,EAAc,IAAI7C,KAClBkX,EAAkB7B,EAAwBlI,YAAYqK,UAAY3U,EAAY2U,UAClFC,YAAUvG,QAAAC,SAAAC,KAAC,SAAAC,IAAA,SAAAF,OAAAM,KAAA,SAAAC,GAAA,cAAAA,EAAAC,KAAAD,EAAAjG,MAAA,OAAAiG,SAAAjG,KAAA,EAAoB7E,EAAK8Q,0BAAyB,wBAAAhG,EAAAQ,OAAA,EAAAb,EAAA,IAAK6F,GAGvE1c,KAAK+G,OAAO4T,SADuC,IAA1CE,EAAwBrI,OAAO/I,OACnB,CAAC,OAA6C,QAAvCkT,EAAE9B,EAAwB1R,qBAAa,IAAAwT,OAAA,EAArCA,EAAuCpN,YAAa,YAGpD,CAAC,OAA6C,QAAvCqN,EAAE/B,EAAwB1R,qBAAa,IAAAyT,OAAA,EAArCA,EAAuCrN,YAAa,cACrF,yBAAAyI,EAAAN,OAAA,EAAAK,EAAA/X,KAAA,IACJ,SA1BY6c,EAAyBlF,EAAAC,GAAA,OAAA4E,EAAA3E,MAAA7X,KAAAwJ,UAAA,IA4BtC,CAAA/I,IAAA,0BAAAC,MAAA,eAAAyc,KAAAzG,MAAAC,SAAAC,KAGO,SAAAqC,IAAA,IAAAwD,EAAA,SAAA9F,OAAAM,KAAA,SAAAuC,GAAA,cAAAA,EAAArC,KAAAqC,EAAAvI,MAAA,OACHjR,KAAKI,SAASJ,KAAKkd,wBAAwB5c,KAAM,yBAE7Cmc,KAAcxT,KAAA,GAAOjJ,KAAKuc,sBAAsB1H,iBAEjCvI,0BAEftM,KAAKuc,sBAAsBzB,+BAA+B2B,EAAenQ,0BAEzEtM,KAAK+G,OAAO4T,SAAS,CAAC8B,EAAeM,yBAIrC/c,KAAKuc,sBAAsBjC,SAAS,wBAAAd,EAAA9B,OAAA,EAAAuB,EAAAjZ,KAAA,IAbR,OAcnC,SAdYkd,IAAuB,OAAAC,EAAAtF,MAAA7X,KAAAwJ,UAAA,EAHpC,IAmBA,CAAA/I,IAAA,wCAAAC,MAKO,SAAsC0U,EAAgBtF,GACzD,OAAA9P,KAAKI,SAASJ,KAAK8c,sCAAsCxc,KAAM,6CAA8C,CAAC8U,EAAQtF,IAE/G9P,KAAK2Q,WAAWlI,KAAI,GAAAqF,OAAkB9N,KAAKoH,QAAO,qCAAA0G,OAAoCsH,EAAM,KAAAtH,OAAIgC,GAAY,IACtGpH,QACG0F,KAAI,SAACgP,GACD,OAAIA,EAAQzK,cACRyK,EAAQzK,YAAc,IAAInN,KAAK4X,EAAQzK,cAEpCyK,CACX,GAEpB,KApEA,IAAAZ,CAoEC,CA/E6B,CAAQlO,KAAWgO,SAAxCD,0CAAoBrb,aAAA,4BAApBqb,EAAoB3a,QAApB2a,EAAoB1a,UAAAC,WAFjB,SAEHya,CAAqB,uJCVrBgB,GAAU7c,OACnB,SAAA6c,EAAmB1V,EAAsBW,EAAyBsK,IAAoB7S,OAAAC,KAAAqd,GAAnErd,KAAA2H,QAAsB3H,KAAAsI,aAAyBtI,KAAA4S,cAAsB,iCCW/EiD,EAAoB,eAAAyH,EAApBzH,EAAoB,SAAApI,GAQ7B,SAAAoI,EAAYnI,GAAkB,IAAA5N,EAAAC,cAAAC,KAAA6V,IAC1B/V,KAAAG,KAAAD,KAAA6V,EAAA,CAAMnI,KAPF3G,UAAiBF,OAAOG,MAExBlH,EAAAyG,wBAAkC,gBAAgBzG,CAM1D,CAEAS,cAAAsV,EAAApI,IAAA,EAAAjN,KAAAqV,EAAA,EAAApV,IAAA,oBAAAC,OAAA6c,KAAA7G,MAAAC,SAAAC,KAGO,SAAAC,EAAwB/B,EAAoBF,EAAejL,EAA2B4F,EAAqB5B,GAAgB,IAAA6P,EAAA7V,EAAA,SAAAgP,OAAAM,KAAA,SAAAC,GAAA,cAAAA,EAAAC,KAAAD,EAAAjG,MAAA,OAC9H,OAAAjR,KAAKI,SAASJ,KAAKmY,kBAAkB7X,KAAM,oBAAqB,CAACiP,EAAa5B,IAE1E6P,EAAY,CACZnW,cAAeH,IAAY+K,SAAS5K,cACpCoW,kBAAmBvW,IAAY+K,SAASwL,kBACxC3I,WAAYA,EACZF,MAAOA,EACPjL,MAAOA,EACP4F,YAAaA,EACb5B,QAASA,GAEbuJ,EAAAjG,KAAA,KACkBmH,KAAcpY,KAAK0d,aAAaF,IAAW,OAAzD7V,SAAKuP,EAAAgB,MAEH5P,WAAa,IAAI9C,KAAKmC,EAAMW,YAElCN,aAAaa,QAAQ7I,KAAKuG,wBAAyB4B,KAAKW,UAAUnB,IAElE3H,KAAKI,SAASJ,KAAKmY,kBAAkB7X,KAAM,kBAAmB,CAACN,KAAKkI,eAAegP,EAAAG,OAAA,SAC5E1P,GAAK,wBAAAuP,EAAAQ,OAAA,EAAAb,EAAA7W,KAAA,IACf,SArBYmY,EAAiBR,EAAAC,EAAAe,EAAAC,EAAAC,GAAA,OAAA0E,EAAA1F,MAAA7X,KAAAwJ,UAAA,IAuB9B,CAAA/I,IAAA,eAAAC,MAKO,SAAa8c,GAAc,IAAApR,EAAApM,KAC9B,OAAAA,KAAKI,SAASJ,KAAK0d,aAAapd,KAAM,oBAAqB,CAACkd,IACrDxd,KAAK2Q,WAAWlI,KAAI,GAAAqF,OAAgB9N,KAAKoH,QAAO,qBAAqBoW,GACvE9U,QACGiV,KAAW,SAACvM,GACR,IAAIwM,EAAQ,eAAA9P,OAAkBsD,EAAM3B,OAAM,gBAAA3B,OAAesD,EAAMA,OAC/D,OAAqB,MAAjBA,EAAM3B,QAENrD,EAAKrF,OAAO4T,SAAS,CAAC,iBAE1BnQ,QAAQkB,IAAIkS,IAAQ,EACbC,KAAW,kBAAM,IAAIC,MAAK,yBAAAhQ,OAA0B8P,GAAW,EAC1E,GAEZ,GAEA,CAAAnd,IAAA,mBAAAC,MAKO,SAAiBqd,EAAanL,GAAoB,IAAAhG,EAAA5M,KACrDA,KAAKI,SAASJ,KAAKge,iBAAiB1d,KAAM,uBAE1C,IAAI2d,EAAe,CACftW,MAAOoW,EACPnL,aAAcA,GAGlB,OAAO5S,KAAK2Q,WAAWlI,KAAI,GAAAqF,OAAgB9N,KAAKoH,QAAO,6BAA6B6W,GAC3EvV,QACGC,KAAI,SAAAC,GACAgE,EAAK1E,aAAe,IAAImV,EACzCzU,EAAKjB,MACL,IAAInC,KAAKoD,EAAKN,YACdM,EAAKgK,cAEYhG,EAAKxM,SAASwM,EAAKoR,iBAAiB1d,KAAM,kBAAmB,CAACsM,EAAK1E,eACnEF,aAAaa,QAAQ+D,EAAKrG,wBAAyB4B,KAAKW,UAAU8D,EAAK1E,cAC3E,GAEhB,KAxEA,IAAAqV,CAwEC,CApF4B,CAAQjP,KAAWgP,SAAvCzH,0CAAmB7U,aAAA,4BAAnB6U,EAAmBnU,QAAnBmU,EAAmBlU,UAAAC,WAFhB,SAEHiU,CAAoB,qGCDpBG,EAAiB,eAAAkI,EAAjBlI,EAAiB,SAAAvI,GAE1B,SAAAuI,EAAYtI,GAAkB3N,cAAAC,KAAAgW,IAAA,EAAA/V,KAAAD,KAAAgW,EAAA,CACpBtI,GACV,CAEAnN,cAAAyV,EAAAvI,IAAA,EAAAjN,KAAAwV,EAAA,EAAAvV,IAAA,iBAAAC,MAIO,WACH,OAAOV,KAAK6N,UAAUnD,IAAG,GAAAoD,OAAkB9N,KAAKoH,QAAO,iCAC3D,GAEA,CAAA3G,IAAA,uBAAAC,MAIO,SAAqBoP,GACxB,OAAO9P,KAAK6N,UAAUnD,IAAG,GAAAoD,OAAkB9N,KAAKoH,QAAO,wCAAA0G,OAAuCgC,GAClG,GAEA,CAAArP,IAAA,wBAAAC,MAIO,SAAsBiN,GACzB,OAAO3N,KAAK6N,UAAUnD,IAAG,GAAAoD,OAAsB9N,KAAKoH,QAAO,uCAAA0G,OAAsCH,GACrG,GAEA,CAAAlN,IAAA,mBAAAC,MAIO,SAAiBiN,GACpB,OAAO3N,KAAK6N,UAAUnD,IAAG,GAAAoD,OAAiB9N,KAAKoH,QAAO,kCAAA0G,OAAiCH,GAC3F,GAEA,CAAAlN,IAAA,wCAAAC,MAKO,SAAsC0U,GACzC,OAAOpV,KAAK6N,UAAUnD,IAAG,GAAAoD,OAC3B9N,KAAKoH,QAAO,uDAAA0G,OAAsDsH,GAEpE,GAEA,CAAA3U,IAAA,kDAAAC,MAKO,SAAgDoP,EAAiBsF,GACpE,OAAOpV,KAAK6N,UAAUnD,IAAG,GAAAoD,OAC3B9N,KAAKoH,QAAO,iEAAA0G,OAAgEgC,EAAQ,KAAAhC,OAAIsH,GAE1F,GAEH,CAAA3U,IAAA,sBAAAC,MAKO,SAAoBiN,EAAiBqC,GAC3C,OAAOhQ,KAAK6N,UAASK,OAAO,GAAAJ,OACxB9N,KAAKoH,QAAO,qCAAA0G,OAAoCH,EAAO,KAAAG,OAAIkC,EAAKpK,IAErE,GAEA,CAAAnF,IAAA,uBAAAC,MAKO,SAAqBiN,EAAiBqC,GAC5C,OAAOhQ,KAAK6N,UAAUM,IAAG,GAAAL,OACrB9N,KAAKoH,QAAO,sCAAA0G,OAAqCH,EAAO,KAAAG,OAAIkC,EAAKpK,IAAM,GAE5E,IAAC,CAhF4B,CAAQ0I,KAAW4P,SAApClI,0CAAgBhV,aAAA,4BAAhBgV,EAAgBtU,QAAhBsU,EAAgBrU,UAAAC,WAFb,SAEHoU,CAAiB,oOCLjBmI,EAAY,eAAAC,EAAZD,EAAY,WAIrB,SAAA3d,KAFA,SAAA2d,EAAsC5R,IAAkBxM,OAAAC,KAAAme,GAAlBne,KAAAuM,UAAqB,EAE3D,EAAA9L,IAAA,cAAAC,MAIO,SAAYuP,GACf,IAAIoO,EAAYre,KAAKuM,SAAS+R,eAAe,aAEzCD,IACAA,EAAUE,KAAI,GAAAzQ,OAAMmC,EAAK,QACjC,GAAC,CAAAxP,IAAA,WAAAC,MAEM,WACH,IAAI2d,EAAYre,KAAKuM,SAAS+R,eAAe,aAE7C,OAAID,EACOA,EAAUE,KAAKC,QAAQ,OAAQ,IAAIA,QAAQ,YAAa,IAG5D,SACX,IAAC,CAvBoB,GAuBpBJ,SAvBQD,0CAAYnd,MAEDyd,MAAQ,4BAFnBN,EAAYzc,QAAZyc,EAAYxc,UAAAC,WAFT,SAEHuc,CAAY,wBCkBZO,EAAiB,eAAAC,EAAjBD,EAAiB,SAAA9e,GAwC1B,SAAA8e,IAAA,IAAA5e,EAAAC,cAAAC,KAAA0e,IACI5e,KAAAG,KAAAD,KAAA0e,IAvCJE,QAAUC,WAYA/e,EAAAyc,yBAA+C1V,OAAOS,KACtDxH,EAAAgf,gBAAoBjY,OAAOsX,GAG9Bre,EAAAif,uBAAiC,EACjCjf,EAAAmQ,MAAgB,UAChBnQ,EAAAkf,cAAwB,EAExBlf,EAAAmf,yBAAyC,IAAIC,KAC7Cpf,EAAAqf,kBAAkC,IAAID,KAEtCpf,EAAAsf,SAAmB,gBACnBtf,EAAAuf,WAA8B,IAAIla,IAIlCrF,EAAAwf,WAA2C,SAArBpY,IAAYqY,MAAwC,YAArBrY,IAAYqY,KAapEzf,EAAKD,WAAUgH,OAAOnH,KACtBI,EAAK0f,uBAAsB3Y,OAAO4Y,MAClC3f,EAAK4f,kBAAiB7Y,OAAO8Y,MAC7B7f,EAAK8f,kBAAiB/Y,OAAOgZ,MAE7B/f,EAAKggB,cAAajZ,OAAOG,MAAQlH,CACrC,CAACS,cAAAme,EAAA9e,IAAA,EAAAY,KAAAke,EAAA,EAAAje,IAAA,uBAAAiK,IA7CD,WAAiE,OAAO7I,GAAsB,GAAC,CAAApB,IAAA,sBAAAiK,IAC/F,WAA+D,OAAOxG,GAAqB,GAAC,CAAAzD,IAAA,sBAAAiK,IAC5F,WAA+D,OAAOjI,GAAqB,GAAC,CAAAhC,IAAA,gBAAAiK,IAC5F,WAAmD,OAAOzI,GAAe,GAAC,CAAAxB,IAAA,aAAAiK,IAC1E,WAA6C,OAAO3F,GAAY,GAAC,CAAAtE,IAAA,WAAAC,MA2C1D,WAAQ,IAAA0L,EAAApM,KACXA,KAAKI,SAASJ,KAAK+f,SAASzf,KAAM,eAElCN,KAAKiQ,MAAQjQ,KAAK8e,aAAakB,WAE/B,IAAIC,EAAsBjgB,KAAKuc,sBAAsBhV,gBAAgBC,UAAU,SAAAC,GAAI,IAAAyY,EAAAC,EAgBfC,EAfhEhU,EAAKlD,YAAczB,EACc,QAAjCyY,EAAI9T,EAAKlD,YAAYE,oBAAY,IAAA8W,GAA7BA,EAA+BG,cAAc/f,OACzD8L,EAAKgT,SAAwC,QAAhCe,EAAG/T,EAAKlD,YAAYE,oBAAY,IAAA+W,OAAA,EAA7BA,EAA+BE,cAAc/f,MASrD8L,EAAK2S,2BAAsErV,IAA9C0C,EAAKlD,YAAYoD,yBAG9CF,EAAKhM,SAASgM,EAAK2T,SAASzf,KAAM,iBAAkB,CAAC8L,EAAK6D,MAAO7D,EAAKlD,YAAY+G,aAC/DvG,IAAf0C,EAAK6D,YAA4CvG,IAArB0C,EAAKlD,cACjCkD,EAAK4S,aAAe5S,EAAK6D,QAAU7D,EAAKlD,YAAY+G,MACpD7D,EAAK6D,MAA8B,QAAzBmQ,EAAGhU,EAAKlD,YAAY+G,aAAK,IAAAmQ,IAAI,UACnChU,EAAK4S,cACL5S,EAAKhM,SAASgM,EAAK2T,SAASzf,KAAM,gBAAiB,CAAC8L,EAAK6D,QAGrE,GACAjQ,KAAKif,yBAAyBqB,IAAIL,GAGlCjgB,KAAK8f,WAAWS,OAAO/Y,UAAU,SAACgZ,GACxBA,aAAiBC,MAGvBvN,OAAOwN,SAAS,EAAG,EACvB,EACJ,GAAC,CAAAjgB,IAAA,cAAAC,MAEM,WACHV,KAAKI,SAASJ,KAAK2gB,YAAYrgB,KAAM,kBAErCN,KAAKif,yBAAyB2B,cAC9B5gB,KAAKmf,kBAAkByB,aAC3B,GAEA,CAAAngB,IAAA,eAAAC,MAGO,WAAsB,GAE7B,CAAAD,IAAA,YAAAC,MAMO,SAAUmgB,EAAcjP,EAAejG,GAC1C3L,KAAKI,SAASJ,KAAK8gB,UAAUxgB,KAAM,qBAAsB,CAACugB,EAAMjP,EAAOjG,IAEvE3L,KAAK0f,eAAeY,IAAI,CAACS,SAAUF,EAAMG,QAASpP,EAAOqP,OAAQtV,IAEjE3L,KAAKH,QAAQiB,MACjB,GAEA,CAAAL,IAAA,gBAAAC,MAIO,SAAcwgB,GAEjB,IAAIC,EAAkB,GAAArT,OAAM9N,KAAKohB,SAAQ,KAAAtT,OAAIoT,GAC7C,OAAOlhB,KAAKuc,sBAAsB1H,eAAepC,MAAMkB,SAASwN,EACpE,GAAC,CAAA1gB,IAAA,iBAAAC,MAEM,WACH,OAAIV,KAAKkJ,YAAYoJ,WAAa3N,IAAUC,IAKhD,IAAC,CArIyB,CAAQ7D,KAAkB4d,SAA3CD,yCAAgB,0BAAhBA,EAAgBxd,UAAA,mBAAAC,SAAA,CAAAH,OAAAI,MAAA,EAAAC,KAAA,EAAAE,SAAA,SAAAC,EAAAC,GAAA,EAAA4f,cAAA,IAAhB3C,CAAiB,sECjBR3d,EAAkB,WAUpC,SAAAP,KAFA,SAAAO,KAAAhB,OAAAC,KAAAe,GANQf,KAAAshB,OAAiB,QAElBthB,KAAAuhB,gBAA0B,4BAC1BvhB,KAAAwhB,gBAAwB,SACxBxhB,KAAAyhB,kBAA4B,SAEnB,EAEhB,EAAAhhB,IAAA,WAAAC,MAMO,SAAS0P,EAAgBzE,EAAiB+V,GAC7C,IAAIC,EAAgB3hB,KAAKK,YACrBuhB,KAAyBC,MAAWrc,KAAKsc,MAAM,sBAAuB9hB,KAAKshB,QAE3EI,EACAlX,QAAQuX,MAAK,IAAAjU,OAAK8T,EAAc,QAAA9T,OAAO6T,EAASrhB,KAAI,OAAAwN,OAAMsC,EAAM,OAAAtC,OAAMnC,GAAW+V,GAEjFlX,QAAQuX,MAAK,IAAAjU,OAAK8T,EAAc,QAAA9T,OAAO6T,EAASrhB,KAAI,OAAAwN,OAAMsC,EAAM,OAAAtC,OAAMnC,GAC9E,GAEA,CAAAlL,IAAA,UAAAC,MAMQ,SAAQ0P,EAAgBzE,EAAiB+V,GAC7C,IAAIC,EAAgB3hB,KAAKK,YACrBuhB,KAAyBC,MAAWrc,KAAKsc,MAAM,sBAAuB9hB,KAAKshB,QAE3EI,EACAlX,QAAQkB,IAAG,IAAAoC,OAAK8T,EAAc,QAAA9T,OAAO6T,EAASrhB,KAAI,OAAAwN,OAAMsC,EAAM,OAAAtC,OAAMnC,GAAW+V,GAE/ElX,QAAQkB,IAAG,IAAAoC,OAAK8T,EAAc,QAAA9T,OAAO6T,EAASrhB,KAAI,OAAAwN,OAAMsC,EAAM,OAAAtC,OAAMnC,GAC5E,GAEA,CAAAlL,IAAA,WAAAC,MAMQ,SAAS0P,EAAgBzE,EAAiB+V,GAC9C,IAAIC,EAAgB3hB,KAAKK,YACrBuhB,KAAyBC,MAAWrc,KAAKsc,MAAM,sBAAuB9hB,KAAKshB,QAE3EI,EACAlX,QAAQ4G,MAAK,IAAAtD,OAAK8T,EAAc,QAAA9T,OAAO6T,EAASrhB,KAAI,OAAAwN,OAAMsC,EAAM,OAAAtC,OAAMnC,GAAW+V,GAEjFlX,QAAQ4G,MAAK,IAAAtD,OAAK8T,EAAc,QAAA9T,OAAO6T,EAASrhB,KAAI,OAAAwN,OAAMsC,EAAM,OAAAtC,OAAMnC,GAC9E,IAAC,CAxDmC,oCCPjC,IAAMzE,EAAc,CAC1B8a,YAAY,EACZzC,KAAM,OACNtN,SAAU,CACT7K,QAAS,4BACTC,cAAe,uCACfoW,kBAAmB,oGAEpBwE,UAAW,wBACXC,KAAM,CACLC,SAAU,uBACVC,OAAQ,0CACRC,YAAa,0CACbC,OAAQ,CAAC,SAAU,UAAW,SAC9BC,MAAM,GAEP7O,gBAAiB,CAAC,GAAI,OACtBvM,UAAW,CACVC,QAAS,yDACTC,cAAe,uCACfxB,OAAQ,uPCPG2c,EAAwB,eAAAC,EAAxBD,EAAwB,SAAA5iB,GAInC,SAAA4iB,EAAoBzb,EAAwBlH,EAAsC6iB,EACrD/M,EAA2BgN,GAAiC,IAAA7iB,EAAAC,cAAAC,KAAAwiB,IACvF1iB,KAAAG,KAAAD,KAAAwiB,IAFkBzb,SAAwBjH,EAAAD,UAAsCC,EAAA4iB,uBACrD5iB,EAAA6V,WAA2B7V,EAAA6iB,cAEtD7iB,EAAKM,SAASN,EAAKO,YAAYC,KAAM,UAAUR,CACjD,CAACS,cAAAiiB,EAAA5iB,IAAA,EAAAY,KAAAgiB,EAAA,EAAA/hB,IAAA,WAAAC,OAAAkiB,KAAAlM,MAAAC,SAAAC,KAEM,SAAAmB,IAAA,IAAA3L,EAAApM,KAAA,SAAA2W,OAAAM,KAAA,SAAAe,GAAA,cAAAA,EAAAb,KAAAa,EAAA/G,MAAA,OACLjR,KAAKI,SAASJ,KAAK+f,SAASzf,KAAM,eAElCN,KAAKH,QAAQgB,OAGQb,KAAK2iB,YAAYE,WAAWna,QAC/C4S,KAAO,SAAC7T,GAAY,QAAOA,CAAC,MAC5B2G,KAAI,SAAC3G,GAAY,IAAAqb,EAAA,OAAsB,QAAtBA,EAAKrb,EAAE0K,uBAAe,IAAA2Q,IAAS,IAInCtb,UAAS,eAAAub,KAAArM,MAAAC,SAAAC,KAAC,SAAAC,EAAOmM,IAAsB,SAAArM,OAAAM,KAAA,SAAAC,IAAA,cAAAA,GAAAC,KAAAD,GAAAjG,MAAA,WAChD+R,GAAa,CAAA9L,GAAAjG,KAAA,QAAAiG,UAAAjG,KAAA,EAET7E,EAAKsW,qBAAqBtL,KAAKhL,EAAKrF,OAAO8C,YAAYD,KAAKE,SAAUsC,EAAKrF,OAAO8C,YAAYC,UAAS,OAC7GsC,EAAKvM,QAAQiB,OAAO,wBAAAoW,GAAAQ,OAAA,EAAAb,EAAA,IAEvB,gBAAAc,GAAA,OAAAoL,EAAAlL,MAAA7X,KAAAwJ,UAAA,EANuB,IAMrB,wBAAAwO,EAAAN,OAAA,EAAAK,EAAA/X,KAAA,IACJ,SAnBY+f,IAAQ,OAAA6C,EAAA/K,MAAA7X,KAAAwJ,UAAA,MAFpB,IAAAoZ,CAEoB,CAVc,CAAQ7hB,KAAkB0hB,SAAlDD,0CAAuBxhB,MAAAC,MAAAD,MAAAiiB,KAAAjiB,MAAAkiB,KAAAliB,MAKxBob,MAASpb,MAAAmiB,MAAA,0BALRX,EAAuBthB,UAAA,mBAAAC,SAAA,CAAAH,OAAAI,MAAA,EAAAC,KAAA,EAAAE,SAAA,SAAAC,EAAAC,GAAA,EAAAD,ICbpCR,MAAA,QAAIA,MAAA,qBAAeA,4BDaNwhB,CAAwB,cENxBY,EAAU,eAAAC,EAAVD,EAAU,SAAAzE,GAEnB,SAAAyE,EAAoBrc,GAAc,IAAAjH,EAAAC,cAAAC,KAAAojB,IAC9BtjB,KAAAG,KAAAD,KAAAojB,IADgBrc,SAEhBjH,EAAKM,SAASN,EAAKO,YAAYC,KAAM,UAAUR,CACnD,CAEAS,cAAA6iB,EAAAzE,IAAA,EAAAne,KAAA4iB,EAAA,EAAA3iB,IAAA,sBAAAC,OAAA4iB,KAAA5M,MAAAC,SAAAC,KAMQ,SAAAC,EAA0B9D,EAA+ByB,GAA0B,IAAA+O,EAAA,SAAA5M,OAAAM,KAAA,SAAAC,GAAA,cAAAA,EAAAC,KAAAD,EAAAjG,MAAA,OACvF,OAAAjR,KAAKI,SAASJ,KAAKwjB,oBAAoBljB,KAAM,kCAAmC,CAACyS,EAAOyB,IACxFxU,KAAKH,QAAQgB,OAAOqW,EAAAC,KAAA,EAAAD,EAAAjG,KAAA,EAGVjR,KAAKuc,sBAAsBnF,KAAKrE,EAAOyB,GAAM,UAG9CzB,EAAMnK,KAAK6a,KAAO,CAAAvM,EAAAjG,KAAA,eAAAiG,EAAAG,OAAA,UACZ,GAAI,OAKwC,GAFnDkM,EAAaxQ,EAAMnK,KAAK6a,MAEdzjB,KAAKuc,sBAAsB1H,eAC7BpC,MAAMkB,SAAS4P,GAAW,CAAArM,EAAAjG,KAAA,gBAAAiG,EAAAG,OAAA,UAC3B,GAAI,QAEf,OAAArX,KAAK+G,OAAO4T,SAAS,CAAC,cAAczD,EAAAG,OAAA,UAC7B,GAAK,QAAAH,SAAAC,KAAA,GAGZnX,KAAKH,QAAQiB,OAAOoW,EAAAwM,OAAA,6BAAAxM,EAAAQ,OAAA,EAAAb,EAAA7W,KAAA,iBAE3B,SAxBawjB,EAAmB7L,EAAAC,GAAA,OAAA0L,EAAAzL,MAAA7X,KAAAwJ,UAAA,KAAA/I,IAAA,cAAAC,MAAA,eAAAijB,KAAAjN,MAAAC,SAAAC,KA0B1B,SAAAmB,EAAkBhF,EAA+ByB,GAA0B,SAAAmC,OAAAM,KAAA,SAAAe,GAAA,cAAAA,EAAAb,KAAAa,EAAA/G,MAAA,OAAA+G,SAAA/G,KAAA,EACjEjR,KAAKwjB,oBAAoBzQ,EAAOyB,GAAM,cAAAwD,EAAAX,OAAA,SAAAW,EAAAE,MAAA,wBAAAF,EAAAN,OAAA,EAAAK,EAAA/X,KAAA,IAD/B,OAEvB,SAFY4jB,EAAWjL,EAAAC,GAAA,OAAA+K,EAAA9L,MAAA7X,KAAAwJ,UAAA,EA1BS,IA0BT,CAAA/I,IAAA,mBAAAC,MAAA,eAAAmjB,KAAAnN,MAAAC,SAAAC,KAIjB,SAAAqC,EAAuBlG,EAA+ByB,GAA0B,SAAAmC,OAAAM,KAAA,SAAAuC,GAAA,cAAAA,EAAArC,KAAAqC,EAAAvI,MAAA,OAAAuI,SAAAvI,KAAA,EACtEjR,KAAKwjB,oBAAoBzQ,EAAOyB,GAAM,cAAAgF,EAAAnC,OAAA,SAAAmC,EAAAtB,MAAA,wBAAAsB,EAAA9B,OAAA,EAAAuB,EAAAjZ,KAAA,IAD1B,OAE5B,SAFY8jB,EAAgBjL,EAAAC,GAAA,OAAA+K,EAAAhM,MAAA7X,KAAAwJ,UAAA,EAJL,MAhCxB,IAAA8Z,CAoC6B,CA3CV,CAAQ5E,KAAgB2E,SAAlCD,0CAASpiB,MAAAC,MAAA,4BAATmiB,EAAS1hB,QAAT0hB,EAASzhB,UAAAC,WAFN,SAEHwhB,CAAU,ICCVW,EAAgB,eAAAC,EAAhBD,EAAgB,SAAApF,GAC3B,SAAAoF,IAAAhkB,cAAAC,KAAA+jB,IAAA,EAAA9jB,KAAAD,KAAA+jB,EAEA,CAACxjB,cAAAwjB,EAAApF,IAAA,EAAAne,KAAAujB,EAAA,CAH0B,CAAQrF,KAAgBsF,SAAxCD,yCAAe,0BAAfA,EAAe7iB,UAAA,iBAAAC,SAAA,CAAAH,OAAAI,MAAA,GAAAC,KAAA,EAAAC,OAAA,8GAAAC,SAAA,SAAAC,EAAAC,GAAA,EAAAD,ICRmDR,MAA/E,UAA+EA,CAAxD,UAAwDA,CAAJ,OAAIA,CAAA,YAAQA,MAAA,mBAAsBA,UAAKA,MAAA,OAAGA,MAAA,mMAA6LA,QAAIA,MAAA,OAAGA,MAAA,8TAAwTA,QAAIA,MAAA,OAAGA,MAAA,4MAAqMA,QAAIA,MAAA,QAAGA,MAAA,oPAAmOA,QAAIA,MAAA,QAAGA,MAAA,mdAA4cA,QAAOA,MAAH,OAAGA,CAAA,aAAQA,MAAA,uBAAyBA,UAAIA,MAAA,QAAGA,MAAA,4cAAqcA,QAAIA,MAAA,QAAGA,MAAA,uRAAgRA,QAAIA,MAAA,QAAGA,MAAA,ySAA6RA,QAAIA,MAAA,QAAGA,MAAA,iTAA0SA,MAAA,UAAsCA,MAAA,4BAAqBA,QAAIA,MAAA,wUAA8VA,sUDQ1uG+iB,CAAgB,IEDhBE,EAAwB,eAAAC,EAAxBD,EAAwB,SAAAtF,GACnC,SAAAsF,IAAAlkB,cAAAC,KAAAikB,IAAA,EAAAhkB,KAAAD,KAAAikB,EAEA,CAAC1jB,cAAA0jB,EAAAtF,IAAA,EAAAne,KAAAyjB,EAAA,CAHkC,CAAQvF,KAAgBwF,SAAhDD,yCAAuB,0BAAvBA,EAAuB/iB,UAAA,eAAAC,SAAA,CAAAH,OAAAI,MAAA,EAAAC,KAAA,EAAAC,OAAA,qFAAAC,SAAA,SAAAC,EAAAC,GAAA,EAAAD,ICJ5BR,MAFR,UAEQA,CAFc,UAEdA,CAD+D,QAC3DA,MAAA,+LAA2LA,QAAKA,MAAA,QAE5MA,8BDEaijB,CAAwB,IEAxBE,EAAsB,eAAAC,EAAtBD,EAAsB,SAAAxF,GACjC,SAAAwF,IAAApkB,cAAAC,KAAAmkB,IAAA,EAAAlkB,KAAAD,KAAAmkB,EAEA,CAAC5jB,cAAA4jB,EAAAxF,IAAA,EAAAne,KAAA2jB,EAAA,CAHgC,CAAQzF,KAAgB0F,SAA9CD,yCAAqB,0BAArBA,EAAqBjjB,UAAA,eAAAC,SAAA,CAAAH,OAAAI,MAAA,EAAAC,KAAA,EAAAC,OAAA,qFAAAC,SAAA,SAAAC,EAAAC,GAAA,EAAAD,ICJ1BR,MAFR,UAEQA,CAFc,UAEdA,CAD+D,QAC3DA,MAAA,mEAEZA,gCDEamjB,CAAsB,IECtBE,EAAe,eAAAC,EAAfD,EAAe,SAAA1F,GAC1B,SAAA0F,IAAAtkB,cAAAC,KAAAqkB,IAAA,EAAApkB,KAAAD,KAAAqkB,EAEA,CAAC9jB,cAAA8jB,EAAA1F,IAAA,EAAAne,KAAA6jB,EAAA,CAHyB,CAAQ3F,KAAgB4F,SAAvCD,yCAAc,0BAAdA,EAAcnjB,UAAA,gBAAAC,SAAA,CAAAH,OAAAI,MAAA,GAAAC,KAAA,EAAAC,OAAA,6GAAAC,SAAA,SAAAC,EAAAC,GAAA,EAAAD,ICNfR,MAFZ,UAEYA,CAFW,UAEXA,CAD4C,OAC5CA,CAAA,YAAQA,MAAA,kBAAqBA,UAC9BA,MAAH,MAAGA,CAAA,YAAQA,MAAA,uBAA0BA,UACrCA,MAAA,OAAGA,MAAA,4HACGA,MAAA,WAAMA,MAAA,aAAMA,QAAQA,MAAA,mGAA2FA,QAClHA,MAAH,OAAGA,CAAA,aAAQA,MAAA,aAAeA,UAC1BA,MAAA,QAAGA,MAAA,gKAC+CA,QAC/CA,MAAH,OAAGA,CAAA,aAAQA,MAAA,gBAAkBA,UAC7BA,MAAA,QAAGA,MAAA,mbAICA,MAAA,UAAqCA,MAAA,0BAA2BA,UACpEA,MAAA,QAAGA,MAAA,wFAAiFA,QACjFA,MAAH,OAAGA,CAAA,aAAQA,MAAA,qBAAuBA,UAClCA,MAAA,QAAGA,MAAA,+dAIoDA,MAAA,UACbA,MAAA,0BAA2BA,UAClEA,MAAH,OAAGA,CAAA,aAAQA,MAAA,iBAAmBA,UAC9BA,MAAA,QAAGA,MAAA,4XAGuDA,QAC1DA,MAAA,QAAGA,MAAA,oHACHA,QACAA,MAAA,QAAGA,MAAA,sMACmFA,QACnFA,MAAH,OAAGA,CAAA,aAAQA,MAAA,YAAcA,UACzBA,MAAA,QAAGA,MAAA,4QAE8CA,QAC9CA,MAAH,OAAGA,CAAA,aAAQA,MAAA,cAAgBA,UAC3BA,MAAA,QAAGA,MAAA,wLACuEA,QACvEA,MAAH,OAAGA,CAAA,aAAQA,MAAA,mBAAqBA,UAChCA,MAAA,QAAGA,MAAA,sMACoFA,QACpFA,MAAH,OAAGA,CAAA,aAAQA,MAAA,gBAAkBA,UAC7BA,MAAA,QAAGA,MAAA,0DAA8CA,MAAA,UAAqCA,MAAA,0BAG9FA,uUDtCaqjB,CAAe,aERfE,GAAkB/jB,OAA/B,SAAA+jB,KAAAxkB,OAAAC,KAAAukB,GACWvkB,KAAAwkB,eAAyB,GACzBxkB,KAAAykB,mBAA6B,GAC7BzkB,KAAA0kB,kBAA4B,GAC5B1kB,KAAAkG,OAAiB,GACjBlG,KAAAgK,MAAgB,GAChBhK,KAAA2kB,OAAiB,EAC5B,sJC6BwB3jB,MAAA,cAA4DA,MAAA,sEAAgEA,+BAM5HA,MAAA,cAAyEA,MAAA,yCAAmCA,gDAhB5GA,MAFR,WAEQA,CAFmB,WAEnBA,CADsB,cACFA,MAAA,YAAMA,QAC1BA,MAAA,gBAA4DA,MAAA,yBAAA4jB,GAAA5jB,MAAA6jB,GAAA,IAAAC,EAAA9jB,qBAAA8jB,EAAAC,mBAAA7e,OAAA0e,KAAAE,EAAAC,mBAAA7e,OAAA0e,GAAA5jB,MAAA4jB,EAAA,GAGhE5jB,UAEIA,MADJ,WACIA,CADsB,cACHA,MAAA,WAAKA,QACxBA,MAAA,gBAA0DA,MAAA,yBAAA4jB,GAAA5jB,MAAA6jB,GAAA,IAAAC,EAAA9jB,qBAAA8jB,EAAAC,mBAAA/a,MAAA4a,KAAAE,EAAAC,mBAAA/a,MAAA4a,GAAA5jB,MAAA4jB,EAAA,GAA1D5jB,QAGAA,MAAA,GAAAgkB,GAAA,gBACJhkB,QAEIA,MADJ,YACIA,CADsB,eACFA,MAAA,aAAMA,QAC1BA,MAAA,kBAAqCA,MAAA,yBAAA4jB,GAAA5jB,MAAA6jB,GAAA,IAAAC,EAAA9jB,qBAAA8jB,EAAAC,mBAAAJ,OAAAC,KAAAE,EAAAC,mBAAAJ,OAAAC,GAAA5jB,MAAA4jB,EAAA,GACkB5jB,QACvDA,MAAA,GAAAikB,EAAA,gBAERjkB,4CAjBoEA,MAAA,GAAAA,MAAA,UAAA8jB,EAAAC,mBAAA7e,QAC9BlF,MAAA,UAAAA,MAAA,EAAAkkB,GAAAJ,EAAAC,mBAAA7e,QAAA4e,EAAAK,YAK4BnkB,MAAA,GAAAA,MAAA,UAAA8jB,EAAAC,mBAAA/a,OAC5BhJ,MAAA,UAAAA,MAAA,EAAAkkB,GAAAJ,EAAAC,mBAAA/a,OAAA8a,EAAAK,YAEtBnkB,MAAA,GAAAA,MAAA,OAAAokB,EAAAC,SAAAP,EAAAK,WAI6BnkB,MAAA,GAAAA,MAAA,UAAA8jB,EAAAC,mBAAAJ,QAE7B3jB,cAAA,QAAA8jB,EAAAC,mBAAAJ,QAAAG,EAAAK,kDAOZnkB,MADJ,WACIA,CADkC,iBACFA,MAAA,mBAAAA,MAAAskB,GAAA,IAAAR,EAAA9jB,QAAA,OAAAA,MAAS8jB,EAAAS,gBAAe,GAC5DvkB,WCzCT,IAAMwkB,GAAsB,eAAAC,EAAtBD,EAAsB,SAAA7G,GAUjC,SAAA6G,IAAA,IAAA1lB,EAAAC,cAAAC,KAAAwlB,IACE1lB,KAAAG,KAAAD,KAAAwlB,IATME,kBAAiC7e,OAAO0H,KAEtCzO,EAAAoG,OAAiB,GACjBpG,EAAAkK,WAA4BN,EAE/B5J,EAAAilB,mBAAyC,IAAIR,EAC7CzkB,EAAAqlB,WAAqB,EAAMrlB,CAIlC,CAACS,cAAAilB,EAAA7G,IAAA,EAAAne,KAAAglB,EAAA,EAAA/kB,IAAA,WAAAC,MAEe,YACdilB,OAAAH,EAAA,WAAAxlB,KAAA,EAAA2lB,CAAA,IAGA3lB,KAAKkG,OAASlG,KAAKuc,sBAAsBhG,gBACzCvW,KAAKgK,MAAQhK,KAAKuc,sBAAsB/F,eAGxCxW,KAAK+kB,mBAAmB7e,OAASlG,KAAKkG,OAElClG,KAAKgK,QACPhK,KAAK+kB,mBAAmB/a,MAAQhK,KAAKgK,MAEzC,GAAC,CAAAvJ,IAAA,cAAAC,MAEe,WACdV,KAAKI,SAASJ,KAAK2gB,YAAYrgB,KAAM,0BAErCN,KAAKif,yBAAyB2B,cAC9B5gB,KAAKmf,kBAAkByB,eAAW,EAElC+E,KAAAH,EAAA,cAAAxlB,KAAA,EAFkC,CAElC,GACF,GAAC,CAAAS,IAAA,gBAAAC,MAEM,WAAa,IAImDsM,EAAA4Y,EAAAC,EAJnDzZ,EAAApM,KAClBA,KAAKI,SAASJ,KAAKulB,cAAcjlB,KAAM,6BACvCN,KAAKmlB,WAAY,EAEbnlB,KAAK+kB,mBAAmB/a,OAAShK,KAAK+kB,mBAAmBJ,SACzD3kB,KAAKH,QAAQgB,OAEbb,KAAK+kB,mBAAmBP,eAAuC,QAAzBxX,EAAGhN,KAAKkJ,YAAYS,aAAK,IAAAqD,IAAI,GACnEhN,KAAK+kB,mBAAmBN,mBAA+C,QAA7BmB,EAAG5lB,KAAKkJ,YAAYmM,iBAAS,IAAAuQ,IAAI,GAC3E5lB,KAAK+kB,mBAAmBL,kBAA6C,QAA5BmB,EAAG7lB,KAAKkJ,YAAYsM,gBAAQ,IAAAqQ,IAAI,GAEzE7lB,KAAK0lB,eAAeI,oBAAoB9lB,KAAK+kB,oBACxCvd,UAAU,CACPyJ,KAAM,SAAC8U,GACH3Z,EAAK+Y,WAAY,EACjB/Y,EAAK2Y,mBAAqB,IAAIR,EAC9BnY,EAAK0U,UAAU,UAAW,YAAa,yCAC3C,EACA1P,MAAO,SAACtG,GAAQsB,EAAK0U,UAAU,QAAS,QAAS,+CAAiDhW,EAAG,IAGrH,IAAC,CA3DkC,CAAQ4T,KAAgB+G,SAA9CD,yCAAqB,0BAArBA,EAAqBtkB,UAAA,eAAAC,SAAA,CAAAH,OAAAI,MAAA,GAAAC,KAAA,EAAAC,OAAA,u/BAAAC,SAAA,SAAAC,EAAAC,GAAA,EAAAD,IDElBR,MAJhB,UAIgBA,CAJgD,UAIhDA,CAH4C,UAG5CA,CAFwD,UAExDA,CAD+B,QAC3BA,MAAA,kBACRA,UACAA,MAAA,WACIA,MAAA,yGAIhBA,cAIQA,MAFR,UAEQA,CAFU,UAEVA,CAD4B,aA0BxBA,MAxBA,GAAAglB,GAAA,sBAwBAhlB,CAxBiC,GAAAilB,EAAA,sBA+B7CjlB,YAEAA,MAAA,qGC/CawkB,CAAsB,eCDtBU,GAAc,eAAAC,EAAdD,EAAc,SAAAvH,GAEzB,SAAAuH,EAAoBnf,GAAc,IAAAjH,GAAAC,OAAAC,KAAAkmB,IAChCpmB,KAAAG,KAAAD,KAAAkmB,IADkBnf,SAGlB,IAAIkZ,EAAsBngB,EAAKyc,sBAAsBhV,gBAAgBC,UAAU,SAAAC,GAC7E3H,EAAKoJ,YAAczB,EACf3H,EAAKsmB,eAETtmB,EAAKif,2BAAsErV,IAA9C5J,EAAKoJ,YAAYoD,wBAClD,GACAxM,SAAKmf,yBAAyBqB,IAAIL,GAAqBngB,CACvD,CAACS,cAAA2lB,EAAAvH,IAAA,EAAAne,KAAA0lB,EAAA,EAAAzlB,IAAA,WAAAC,MAEe,WAAQ,IAAA2lB,EAItB,IAHAV,OAAAO,EAAA,WAAAlmB,KAAA,EAAA2lB,CAAA,IAGuB,aAD4B,QAAhCU,EAAGrmB,KAAKkJ,YAAYE,oBAAY,IAAAid,GAA4E,QAA5EA,EAA7BA,EAA+BxK,mBAAmB/J,KAAK,SAAChH,GAAC,MAA8B,oBAAzBA,EAAExK,KAAKsT,aAAmC,UAAC,IAAAyS,OAAA,EAAzGA,EAA2G3lB,OAC9F,KAAA4lB,EAC7BC,EAAuB,CAAC,OAA0C,MAAlCvmB,KAAKkJ,YAAYC,cAAwB,GAAKnJ,KAAKkJ,YAAYC,cAAcoG,YAA0C,QAA/B+W,EAAEtmB,KAAKkJ,YAAYE,oBAAY,IAAAkd,OAAA,EAA7BA,EAA+BhmB,MAC7JimB,EAAqB/a,KAAK,YAC1BxL,KAAK+G,OAAO4T,SAAS4L,EACvB,CAEF,GAAC,CAAA9lB,IAAA,cAAAC,MAEe,WACdV,KAAKI,SAASJ,KAAK2gB,YAAYrgB,KAAM,0BAErCN,KAAKif,yBAAyB2B,cAC9B5gB,KAAKmf,kBAAkByB,eAAW,EAElC+E,KAAAO,EAAA,cAAAlmB,KAAA,EAFkC,CAElC,GACJ,IAAC,CAjC0B,CAAQ0e,KAAgByH,SAAtCD,0CAAallB,MAAAC,MAAA,0BAAbilB,EAAahlB,UAAA,eAAAC,SAAA,CAAAH,OAAAI,MAAA,EAAAC,KAAA,EAAAC,OAAA,+KAAAC,SAAA,SAAAC,EAAAC,GAAA,EAAAD,ICNtBR,MADJ,UACIA,CADkB,WAEdA,MAAA,iBAERA,kDDGaklB,CAAc,0BEOrBM,GAAiB,CACnB,CAAErS,KAAM,GAAIsS,UAAWjE,EAAyBoB,YAAa,CAAC8C,OAC9D,CAAEvS,KAAM,iBAAkBsS,UAAWE,MACrC,CAAExS,KAAM,eAAgBsS,UAAWjB,GAAuB5T,MAAO,eAAgBgS,YAAa,CAAC8C,OAC/F,CAAEvS,KAAM,YAAasS,UAAWP,GAAetU,MAAO,YAAagS,YAAa,CAAC8C,OACjF,CAAEvS,KAAM,iBAAkBsS,UAAWxC,EAAyBrS,MAAO,YAAagS,YAAa,CAAC8C,OAChG,CAAEvS,KAAM,eAAgBsS,UAAWtC,EAAuBvS,MAAO,kBACjE,CAAEuC,KAAM,iBAAkBsS,UAAW1C,EAAiBnS,MAAO,WAC7D,CAAEuC,KAAM,gBAAiBsS,UAAWpC,EAAgBzS,MAAO,SAC3D,CAAEuC,KAAM,OAAQyS,aAAc,WAAF,OAAQC,QAAAC,IAAA,CAAAC,EAAAjc,EAAA,wGAAAic,EAAAjc,EAAA,yCAAAkc,KAAAD,EAAAE,KAAAF,EAAA,OAAqCC,KAAK,SAAAE,GAAC,OAAIA,EAAEC,UAAU,EAAC,EAAEvD,YAAa,CAAC8C,MAAgB5C,iBAAkB,CAAC4C,KAAetD,IAClK,CAAEjP,KAAM,OAAQyS,aAAc,WAAF,OAAQC,QAAAC,IAAA,CAAAC,EAAAjc,EAAA,wGAAAic,EAAAjc,EAAA,wGAAAic,EAAAjc,EAAA,6DAAAic,EAAAjc,EAAA,wGAAAic,EAAAjc,EAAA,wGAAAic,EAAAjc,EAAA,wGAAAic,EAAAjc,EAAA,UAAAic,EAAAjc,EAAA,yCAAAkc,KAAAD,EAAAE,KAAAF,EAAA,OAAqCC,KAAK,SAAAE,GAAC,OAAIA,EAAEE,UAAU,EAAC,EAAExD,YAAa,CAAC8C,MAAgB5C,iBAAkB,CAAC4C,KAAetD,IAClK,CAAEjP,KAAM,KAAMsS,UAAWtC,EAAuBP,YAAa,CAAC8C,QAOrDW,GAAgB,eAAAC,EAAhBD,GAAgB7mB,OACzB,SAAA6mB,EAAoBtgB,EAAwBlH,EAAsC0nB,EAA4CC,GAA2B,IAAA1nB,EAAAE,MAAAD,OAAAC,KAAAqnB,GAArIrnB,KAAA+G,SAAwB/G,KAAAH,UAAsCG,KAAAunB,mBAA4CvnB,KAAAwnB,mBAC1HxnB,KAAK+G,OAAOwZ,OAAO/Y,UAAU,SAACgZ,GACtBA,aAAiBiH,MACjB3nB,EAAKD,QAAQgB,OAGb2f,aAAiBkH,MACjB5nB,EAAKD,QAAQiB,OAGb0f,aAAiBmH,KAEjB7nB,EAAK0nB,iBAAiBzZ,aAGtByS,aAAiBC,MACjB3gB,EAAKynB,iBAAiBle,qBAAoB,EAElD,EACJ,GAACie,SApBQD,0CAAgBrmB,MAAAC,MAAAD,MAAAiiB,KAAAjiB,MAAAkiB,MAAAliB,MAAAmiB,MAAA,yBAAhBkE,gCAHCO,KAAaC,QAAQrB,IACrBoB,QAEDP,CAAgB,2DC1BhBS,GAAgB,eAAAC,EAAhBD,EAAgB,WAS3B,SAAAtnB,KARD,SAAAsnB,EAAoBE,EAAgCC,EAA2BvI,IAA8B3f,OAAAC,KAAA8nB,GAAzF9nB,KAAAgoB,SAAgChoB,KAAAioB,UAA2BjoB,KAAA0f,iBAE1EuI,EAAQC,YAEXloB,KAAKmoB,iCAELnoB,KAAKooB,4BAEP,EAAC,EAAA3nB,IAAA,iCAAAC,MAES,WAA8B,IAAAZ,EAAAE,KAEjCqoB,EAAeroB,KAAKgoB,OAAOM,SAAS5f,QAAK6f,MAAM,SAAAD,GAAQ,OAAiB,IAAbA,CAAiB,IAE9EE,KAAYC,MAAS,MAEA,UAArBvhB,KAAYqY,OACfiJ,KAAYC,MAAS,QAEbC,EAAa5a,MAAOua,EAAcG,GAE7BhhB,WAASkP,QAAAC,SAAAC,KAAC,SAAAC,IAAA,SAAAF,OAAAM,KAAA,SAAAC,GAAA,cAAAA,EAAAC,KAAAD,EAAAjG,MAAA,OAAAiG,SAAAC,KAAA,EAAAD,EAAAjG,KAAA,EAEUnR,EAAKmoB,QAAQU,iBAAgB,OACvDne,QAAQkB,IADSwL,EAAAgB,KACS,8BAAgC,kCAAkChB,EAAAjG,KAAA,gBAAAiG,EAAAC,KAAA,EAAAD,EAAAK,GAAAL,EAAAM,MAAA,GAE5FhN,QAAQ4G,MAAM,+BAA8B8F,EAAAK,IAAO,yBAAAL,EAAAQ,OAAA,EAAAb,EAAA,iBAG5D,GAAC,CAAApW,IAAA,4BAAAC,MAES,WAAyB,IAAA0L,EAAApM,KAElCA,KAAKioB,QAAQW,eAAephB,UAAU,SAACqhB,GACtC,OAAQA,EAAIhI,MACX,IAAK,mBACJrW,QAAQkB,IAAG,gCAAAoC,OAAiC+a,EAAIjK,QAAQkK,OACxD1c,EAAKsT,eAAeY,IAAI,CACvBS,SAAU,OACVC,QAAS,aACTC,OAAQ,uIACRxgB,IAAK,aACLsoB,KAAM,MAEP,MACD,IAAK,gBACJve,QAAQkB,IAAG,wBAAAoC,OAAyB+a,EAAIG,eAAeF,OACvDte,QAAQkB,IAAG,kCAAAoC,OAAmC+a,EAAII,cAAcH,OAChE,MACD,IAAK,8BACJte,QAAQkB,IAAG,kCAAAoC,OAAmC+a,EAAIjK,QAAQkK,KAAI,OAAAhb,OAAM+a,EAAIzX,QAG3E,EACD,IAAC,CAvD2B,GAuD3B2W,SAvDWD,0CAAgB9mB,mBAAAC,OAAAD,MAAAiiB,MAAA,4BAAhB6E,EAAgBpmB,QAAhBomB,EAAgBnmB,YAAhBmmB,CAAgB,ICDhBoB,GAAmB,eAAAC,EAAnBD,EAAmB,WAG9B,SAAA1oB,KAFD,SAAA0oB,EAAoBE,EAA4B1J,IAA8B3f,OAAAC,KAAAkpB,GAA1DlpB,KAAAopB,WAA4BppB,KAAA0f,iBACzC1f,KAAKqpB,yBACZ,EAAC,EAAA5oB,IAAA,0BAAAC,MAES,WAAuB,IAAAZ,EAAAE,KAEhCA,KAAKopB,SAASR,eACZlgB,QACA4S,KAAO,SAACuN,GAAG,MAA4C,kBAAbA,EAAIhI,IAAwB,IAEtErZ,UAAU,SAACqhB,GAEX/oB,EAAK4f,eAAeY,IAAI,CACvBS,SAAU,OACVC,QAAS,aACTC,OAAQ,4GACRqI,QAAQ,EACR7oB,IAAK,aAEP,EACF,IAAC,CArB8B,GAqB9B0oB,SArBWD,0CAAmBloB,MAAAC,OAAAD,MAAAiiB,MAAA,4BAAnBiG,EAAmBxnB,QAAnBwnB,EAAmBvnB,YAAnBunB,CAAmB,6ECL5BloB,MAAA,SAEIA,MAAA,WACJA,4BAH2BA,MAAA,aAAAA,MAAA,EAAAkkB,KAEkClkB,cAAA,SAAAuoB,EAAAC,sCAEzDxoB,MAAA,8BAAwGA,MAAA,SAAAuoB,EAAAC,aCEzG,IAAMC,GAAc,eAAAC,EAAdD,GAAcjpB,OAMvB,SAAAipB,KAAA1pB,OAAAC,KAAAypB,GAJSzpB,KAAAwpB,WAAqB,KACrBxpB,KAAA2pB,aAA6B,GAC7B3pB,KAAA4pB,YAAsB,CAEhB,GAACF,SANPD,yCAAc,0BAAdA,EAAcvoB,UAAA,iBAAA2oB,OAAA,CAAAL,WAAA,aAAAG,aAAA,eAAAC,YAAA,eAAAxoB,MAAA,EAAAC,KAAA,EAAAC,OAAA,mTAAAC,SAAA,SAAAC,EAAAC,GAAA,EAAAD,IDP3BR,MAAA,WAKQA,MAJJ,EAAA8oB,GAAA,UAII9oB,CAHiD,EAAA+oB,GAAA,aAIzD/oB,eALQA,cAAA,OAAAS,EAAAmoB,YAAA,GAIM5oB,cAAA,WAAAS,EAAAmoB,aAAA,IAAAnoB,EAAAmoB,+DCEDH,CAAc,ICDdO,GAAkB,eAAAC,EAAlBD,GAAkBxpB,OAK3B,SAAAwpB,KAAAjqB,OAAAC,KAAAgqB,GAHAhqB,KAAAkqB,UAAY1kB,MAAQ2kB,iBACpBnqB,KAAA4e,QAAUC,UAEM,GAACoL,SALRD,yCAAkB,0BAAlBA,EAAkB9oB,UAAA,iBAAAE,MAAA,GAAAC,KAAA,EAAAC,OAAA,6aAAAC,SAAA,SAAAC,EAAAC,GAAA,EAAAD,ICLvBR,MADR,aACQA,CADmD,WAE/CA,MAAA,kBACJA,QAGIA,MADJ,UACIA,CAD6B,YACAA,MAAA,GACjCA,UAEAA,MAAA,WAGIA,MADJ,UACIA,CAD4C,SACqCA,MAAA,qBAAeA,QAChGA,MAAA,UAAuDA,MAAA,sBAAeA,QACtEA,MAAA,UAAsDA,MAAA,mBAElEA,mBAVyCA,MAAA,GAAAA,MAAA,QAAAS,EAAAyoB,KAAA,oEAAAzoB,EAAAmd,QAAA,0CDA5BoL,CAAkB,qCEElBI,GAAa,eAAAC,EAAbD,EAAa,WAMtB,SAAA5pB,KAFA,SAAA4pB,EAAsC7d,IAAkBxM,OAAAC,KAAAoqB,GAAlBpqB,KAAAuM,WAF9BvM,KAAAsqB,YAA+BzjB,OAAO0jB,MAEa,EAE3D,EAAA9pB,IAAA,YAAAC,MAIO,WACH,OAAOV,KAAKsqB,SAASE,QAAQ,CAAC,sBAClC,GAEA,CAAA/pB,IAAA,YAAAC,MAIO,WACH,OAAOV,KAAKsqB,SAASE,QAAQ,CAAC,sBAClC,GAEA,CAAA/pB,IAAA,YAAAC,MAIO,WACH,OAAOV,KAAKsqB,SAASE,QAAQ,CAAC,sBAClC,GAEA,CAAA/pB,IAAA,YAAAC,MAIO,WACH,OAAOV,KAAKsqB,SAASE,QAAQ,CAAC,uBAClC,GAEA,CAAA/pB,IAAA,0BAAAC,MAGO,WACH,IAAI+pB,EAASle,SAASme,qBAAqB,UAAU,GACjDD,IACAA,EAAOE,MAAMC,WAAa,SAE9B,IAAIC,EAAUte,SAASme,qBAAqB,WAAW,GACnDG,IACAA,EAAQF,MAAMC,WAAa,SAE/B,IAAIE,EAASve,SAASme,qBAAqB,UAAU,GACjDI,IACAA,EAAOH,MAAMI,YAAc,QAEnC,GAEA,CAAAtqB,IAAA,2BAAAC,MAGO,WACH,IAAI+pB,EAASle,SAASme,qBAAqB,UAAU,GACjDD,IACAA,EAAOE,MAAMC,WAAa,OAE9B,IAAIC,EAAUte,SAASme,qBAAqB,WAAW,GACnDG,IACAA,EAAQF,MAAMC,WAAa,OAE/B,IAAIE,EAASve,SAASme,qBAAqB,UAAU,GACjDI,IACAA,EAAOH,MAAMI,YAAc,MAEnC,IAAC,CAxEqB,GAwErBV,SAxEQD,0CAAappB,MAIFyd,MAAQ,4BAJnB2L,EAAa1oB,QAAb0oB,EAAazoB,UAAAC,WAFV,SAEHwoB,CAAa,8DCP1BppB,MAAA,oCAAkDA,MAAA,OAAAuoB,EAAAyB,cCQ3C,IAAMC,GAA0B,eAAAC,EAA1BD,EAA0B,WAKpB,SAAAzqB,KAAjB,SAAAyqB,KAAAlrB,OAAAC,KAAAirB,GAHAjrB,KAAAmrB,gBAA0B,CAGV,EAAC,EAAA1qB,IAAA,WAAAC,MAEjB,WAC2B,SAArBwG,KAAYqY,OACdvf,KAAKmrB,gBAAiB,EACtBnrB,KAAKgrB,YAAc,wBAA0B9jB,KAAYqY,KAAO,IAEpE,IAAC,CAZoC,GAYpC2L,SAZUD,yCAA0B,0BAA1BA,EAA0B/pB,UAAA,6BAAAC,SAAA,CAAAH,MAF1B,CAAC2e,QAAeve,MAAA,EAAAC,KAAA,EAAAC,OAAA,uHAAAC,SAAA,SAAAC,EAAAC,GAAA,EAAAD,GDN7BR,MAAA,EAAAoqB,GAAA,wBAAYpqB,MAAA,OAAAS,EAAA0pB,4DCQCF,CAA0B,0BCP1BI,GAAa7qB,OACtB,SAAA6qB,EACW/qB,EACAmjB,EACA1Q,EACAuY,GAEmC,IADnCC,EAAA/hB,UAAAC,OAAA,QAAAC,IAAAF,UAAA,IAAAA,UAAA,GACAgiB,EAAAhiB,UAAAC,OAAA,QAAAC,IAAAF,UAAA,GAAAA,UAAA,GAAiC,IAAEzJ,OAAAC,KAAAqrB,GALnCrrB,KAAAM,OACAN,KAAAyjB,OACAzjB,KAAA+S,QACA/S,KAAAsrB,UACAtrB,KAAAurB,aACAvrB,KAAAwrB,wBACP,GAMKC,GAAQ,eAAAC,EAARD,GAAQjrB,OA8GjB,SAAAirB,KAAA1rB,OAAAC,KAAAyrB,GAvGOzrB,KAAA2rB,SAA4B,CAC/B,IAAIN,EAAc,YAAa,GAAI,GAAI,CACnC,IAAIA,EAAc,mBAAoB,iCAAkC,2BACxE,IAAIA,EAAc,UAAW,2DAA4D,4DACzF,IAAIA,EAAc,OAAQ,wDAAyD,yDACnF,IAAIA,EAAc,0BAA2B,qEAAsE,uEACnH,IAAIA,EAAc,mBAAoB,mEAAoE,qEAC1G,IAAIA,EAAc,UAAW,2DAA4D,4DACzF,IAAIA,EAAc,UAAW,2DAA4D,8DAE7F,IAAIA,EAAc,WAAY,GAAI,GAAI,CAClC,IAAIA,EAAc,WAAY,4DAA6D,6DAC3F,IAAIA,EAAc,mBAAoB,mEAAoE,qEAC1G,IAAIA,EAAc,mBAAoB,mEAAoE,qEAC1G,IAAIA,EAAc,iBAAkB,iEAAkE,mEACtG,IAAIA,EAAc,UAAW,2DAA4D,4DACzF,IAAIA,EAAc,iBAAkB,2DAA4D,4DAChG,IAAIA,EAAc,4BAA6B,wDAAyD,wDACxG,IAAIA,EAAc,mBAAoB,mEAAoE,qEAC1G,IAAIA,EAAc,qBAAsB,qEAAsE,uEAC9G,IAAIA,EAAc,UAAW,0DAA2D,4DACxF,IAAIA,EAAc,gBAAiB,gEAAiE,kEACpG,IAAIA,EAAc,uBAAwB,mEAAoE,yEAC9G,IAAIA,EAAc,oBAAqB,oEAAqE,sEAC5G,IAAIA,EAAc,gBAAiB,gEAAiE,kEACpG,IAAIA,EAAc,uBAAwB,uEAAwE,yEAClH,IAAIA,EAAc,sBAAuB,sEAAuE,0EAEpH,IAAIA,EAAc,aAAc,GAAI,GAAI,CACpC,IAAIA,EAAc,gBAAiB,gEAAiE,kEACpG,IAAIA,EAAc,gBAAiB,gEAAiE,kEACpG,IAAIA,EAAc,gBAAiB,gEAAiE,kEACpG,IAAIA,EAAc,wBAAyB,wEAAyE,4EAExH,IAAIA,EAAc,UAAW,GAAI,GAAI,CACjC,IAAIA,EAAc,UAAW,kDAAmD,kDAChF,IAAIA,EAAc,WAAY,mDAAoD,mDAClF,IAAIA,EAAc,mBAAoB,0DAA2D,2DACjG,IAAIA,EAAc,iBAAkB,yDAA0D,2DAElG,IAAIA,EAAc,OAAQ,GAAI,GAAI,CAC9B,IAAIA,EAAc,OAAQ,4CAA6C,4CACvE,IAAIA,EAAc,iBAAkB,qDAAsD,sDAC1F,IAAIA,EAAc,WAAY,gDAAiD,gDAC/E,IAAIA,EAAc,mBAAoB,uDAAwD,0DAElG,IAAIA,EAAc,UAAW,GAAI,GAAI,CACjC,IAAIA,EAAc,OAAQ,+CAAgD,4CAE9E,IAAIA,EAAc,iBAAkB,GAAI,GAAI,CACxC,IAAIA,EAAc,YAAa,iDAAkD,iDACjF,IAAIA,EAAc,iBAAkB,uDAAwD,sDAC5F,IAAIA,EAAc,WAAY,iDAAkD,kDAEpF,IAAIA,EAAc,SAAU,GAAI,GAAI,CAChC,IAAIA,EAAc,QAAS,6BAA8B,QAAI3hB,GAAW,EAAM,eAC9E,IAAI2hB,EAAc,sBAAuB,+BAAgC,QAAI3hB,GAAW,EAAM,eAC9F,IAAI2hB,EAAc,oBAAqB,iCAAkC,QAAI3hB,GAAW,EAAM,qBAGlG,IAAI2hB,EAAc,kBAAmB,GAAI,GAAI,CACzC,IAAIA,EAAc,gBAAiB,oDAAqD,sDACxF,IAAIA,EAAc,mBAAoB,uDAAwD,yDAC9F,IAAIA,EAAc,gBAAiB,oDAAqD,wDAE5F,IAAIA,EAAc,aAAc,GAAI,GAAI,CAEpC,IAAIA,EAAc,UAAW,oBAAqB,iBAClD,IAAIA,EAAc,QAAS,kBAAmB,eAC9C,IAAIA,EAAc,YAAa,sBAAuB,mBACtD,IAAIA,EAAc,UAAW,oBAAqB,iBAClD,IAAIA,EAAc,QAAS,kBAAmB,eAC9C,IAAIA,EAAc,eAAgB,yBAA0B,sBAC5D,IAAIA,EAAc,wBAAyB,iCAAkC,+BAC7E,IAAIA,EAAc,oBAAqB,6BAA8B,2BACrE,IAAIA,EAAc,eAAgB,wBAAyB,sBAC3D,IAAIA,EAAc,iBAAkB,qBAAsB,kBAC1D,IAAIA,EAAc,iBAAkB,0BAA2B,wBAC/D,IAAIA,EAAc,gBAAiB,yBAA0B,yBAEjE,IAAIA,EAAc,wBAAyB,GAAI,GAAI,CAC/C,IAAIA,EAAc,SAAU,+BAAgC,8BAC5D,IAAIA,EAAc,QAAS,8BAA+B,6BAC1D,IAAIA,EAAc,YAAa,kCAAmC,iCAClE,IAAIA,EAAc,kBAAmB,iCAAkC,uCACvE,IAAIA,EAAc,iBAAkB,sCAAuC,sCAC3E,IAAIA,EAAc,gBAAiB,qCAAsC,uCAE7E,IAAIA,EAAc,uBAAwB,GAAI,GAAI,CAC9C,IAAIA,EAAc,YAAa,kCAAmC,wCAClE,IAAIA,EAAc,YAAa,gCAAiC,wCAChE,IAAIA,EAAc,wBAAyB,4CAA6C,oDACxF,IAAIA,EAAc,mBAAoB,6CAA8C,+CACpF,IAAIA,EAAc,mBAAoB,8CAA+C,iDAEzF,IAAIA,EAAc,UAAW,GAAI,GAAI,CACjC,IAAIA,EAAc,kBAAmB,uCAAwC,wCAC7E,IAAIA,EAAc,cAAe,GAAK,QAAI3hB,GAAW,EAAM,iBAC3D,IAAI2hB,EAAc,wBAAyB,6CAA8C,sDACzF,IAAIA,EAAc,aAAc,GAAI,8BAI5B,GAACK,SA9GRD,yCAAQ,4BAARA,EAAQ/pB,QAAR+pB,EAAQ9pB,UAAAC,WAFL,SAEH6pB,CAAQ,ICARG,GAAY,eAAAC,EAAZD,EAAY,SAAAhsB,GAUrB,SAAAgsB,EAAoBE,GAAkB,IAAAhsB,EAAAC,cAAAC,KAAA4rB,IAClC9rB,KAAAG,KAAAD,KAAA4rB,IADgBE,WARZhsB,EAAAyc,yBAA+C1V,OAAOS,KAIvDxH,EAAA2S,MAAkB,GAOrB3S,EAAKmgB,oBAAsBngB,EAAKyc,sBAAsBhV,gBAAgBC,UAAU,SAAAqN,GAC5E/U,EAAKoG,OAAS2O,EAAa1L,cAC3BrJ,EAAKkK,MAAQ6K,EAAazL,aAC1BtJ,EAAK2S,MAAQoC,EAAapC,KAC9B,GAAG3S,CACP,CAACS,cAAAqrB,EAAAhsB,IAAA,EAAAY,KAAAorB,EAAA,EAAAnrB,IAAA,cAAAC,MAED,WAEQV,KAAKigB,qBACLjgB,KAAKigB,oBAAoBW,aAEjC,GAEA,CAAAngB,IAAA,eAAAC,MAIO,SAAaqrB,GAEhB,OAAO/rB,KAAKgsB,iBAAiBhsB,KAAK8rB,SAASH,SAAUI,EACzD,GAAC,CAAAtrB,IAAA,mBAAAC,MAEO,SAAiBurB,EAAiCF,GAAa,IAAA3f,EAAApM,KAC/DksB,EAA+B,GAEnC,YAAmBxiB,IAAf1J,KAAKyS,OAELwZ,EAAeE,QAAQ,SAACC,GACpB,IAAIC,EAAoBjgB,EAAKkgB,uBAAuBF,EAAeL,GAC/DM,GACAH,EAAiB1gB,KAAK6gB,EAC9B,GAGGH,CACX,GAEA,CAAAzrB,IAAA,yBAAAC,MAKQ,SAAuB0rB,EAA8BL,GAEzD,GAAIK,EAAcrZ,MAAMtJ,OAAS,GAC7B,GAA2B,KAAvB2iB,EAAc3I,MAAezjB,KAAKyS,MAAMkB,SAASyY,EAAc3I,MAC/D,OAAOzjB,KAAKusB,sCAAsCH,EAAeL,QAAO,GAEvEK,EAAcb,YACnB,GAA2B,KAAvBa,EAAc3I,MAAezjB,KAAKyS,MAAMkB,SAASyY,EAAc3I,MAC/D,OAAOzjB,KAAKusB,sCAAsCH,EAAeL,OAEpE,CAGD,IAAIS,EAAwB,GAI5B,GAHIJ,EAAcd,UACdkB,EAAYxsB,KAAKgsB,iBAAiBI,EAAcd,QAASS,IAEzDS,GAAaA,EAAU/iB,OAAS,EAChC,OAAOzJ,KAAKusB,sCAAsCH,EAAeL,EAASS,EAClF,CAGJ,GAEA,CAAA/rB,IAAA,wCAAAC,MAIO,SAAsC0rB,EAA8BL,EAAeS,GAAsB,IAAA5f,EAAA5M,KACxGysB,EAAcL,EAAcrZ,MAAMtJ,OAAS,EAAK2iB,EAAcrZ,WAAQrJ,EAE1E,OAAI+iB,IACIzsB,KAAKkG,SACLumB,EAAaA,EAAWjO,QAAQ,UAAWxe,KAAKkG,OAAOqJ,cAEvDvP,KAAKgK,QACLyiB,EAAaA,EAAWjO,QAAQ,SAAUxe,KAAKgK,MAAM1J,QAGtD,CACHosB,MAAON,EAAc9rB,KACrBmsB,WAAaA,EAAa,CAACA,QAAc/iB,EACzCijB,MAASH,GAAaA,EAAU/iB,OAAS,EAAK+iB,OAAY9iB,EAC1DqiB,QACKU,EACKV,EACCK,EAAcb,WACX,SAAC/K,GACC5T,EAAKggB,gBAAgBpM,EAAO4L,EAAcZ,wBAC1CO,GACJ,OACEriB,EAGtB,GAEA,CAAAjJ,IAAA,kBAAAC,MAGO,SAAgB8f,EAAYgL,GAG/B,IAAIlgB,EAC0BuhB,EAAAC,EAA9B,GAHA9sB,KAAKI,SAASJ,KAAK4sB,gBAAgBtsB,KAAM,yBAA0B,CAACkgB,EAAOgL,SAGxD9hB,IAAf1J,KAAKgK,MACLsB,EAAiF,QAA9EuhB,EAAa,QAAbC,EAAG9sB,KAAKgK,aAAK,IAAA8iB,OAAA,EAAVA,EAAYjR,mBAAmB/J,KAAK,SAAAhH,IAAC,OAAIA,GAAExK,OAASkrB,CAAsB,UAAC,IAAAqB,IAAIvhB,OACzF,QACyB5B,IAAhB1J,KAAKkG,OAAuB,KAAA6mB,EAAAC,EACjC1hB,EAAmF,QAAhFyhB,EAAc,QAAdC,EAAGhtB,KAAKkG,cAAM,IAAA8mB,OAAA,EAAXA,EAAaC,oBAAoBnb,KAAK,SAAAhH,IAAC,OAAIA,GAAExK,OAASkrB,CAAsB,UAAC,IAAAuB,IAAIzhB,CAC3F,KAAO,CAEP,IAE0BrB,GAFtBsI,EAAUvS,KAAKuc,sBAAsB1H,eAAetC,QACxDrI,MAAAC,MACmBoI,GAAO,IAA1B,IAAArI,GAAAzC,MAAAwC,GAAAC,GAAAe,KAAAC,MAA4B,KACpBgiB,GADOjjB,GAAAvJ,MACgBusB,oBAAoBnb,KAAK,SAAAhH,IAAC,OAAIA,GAAExK,OAASsC,KAAiBc,aAAa,GAClG,GAAqBgG,MAAjBwjB,GAA4B,CACxB5hB,EAAM4hB,GACN,KACJ,CACJ,CAAC,OAAA/hB,IAAAjB,GAAAY,EAAAK,GAAA,SAAAjB,GAAAkB,GAAA,CACL,CACIE,GACA4H,OAAOia,KAAK7hB,EAAI5K,MAAO,SAC/B,IAAC,CA1IoB,CAAQK,KAAkB8qB,SAAtCD,0CAAW5qB,MAAAC,IAAA,4BAAX2qB,EAAWlqB,QAAXkqB,EAAWjqB,UAAAC,WAFR,SAEHgqB,CAAY,2DCbb5qB,MAAA,yDAFRA,MAAA,iBAAWA,MAAA,yBAAA4jB,GAAA5jB,MAAA6jB,GAAA,IAAAC,EAAA9jB,qBAAA8jB,EAAAsI,YAAAxI,KAAAE,EAAAsI,YAAAxI,GAAA5jB,MAAA4jB,EAAA,GAAgD5jB,MAAA,oBAAAA,MAAA6jB,GAAA,IAAAC,EAAA9jB,QAAA,OAAAA,MAAU8jB,EAAAuI,gBAAe,GAChFrsB,MAAA,EAAAssB,GAAA,qBAGAtsB,MAAA,mBACJA,8BALWA,MAAA,UAAA8jB,EAAAsI,aAA0BpsB,MAAA,kBAIpBA,MAAA,GAAAA,MAAA,QAAA8jB,EAAAyI,kCAMTvsB,MAAA,yDAFRA,MAAA,iBAAWA,MAAA,yBAAA4jB,GAAA5jB,MAAAwsB,GAAA,IAAA1I,EAAA9jB,qBAAA8jB,EAAAsI,YAAAxI,KAAAE,EAAAsI,YAAAxI,GAAA5jB,MAAA4jB,EAAA,GAA0C5jB,MAAA,oBAAAA,MAAAwsB,GAAA,IAAA1I,EAAA9jB,QAAA,OAAAA,MAAU8jB,EAAAuI,gBAAe,GAC1ErsB,MAAA,EAAAysB,GAAA,qBAGAzsB,MAAA,cACJA,8BALWA,MAAA,UAAA8jB,EAAAsI,aAA0BpsB,MAAA,YAIzBA,MAAA,GAAAA,MAAA,QAAA8jB,EAAAyI,YCAT,IAAMG,GAAc,eAAAC,EAAdD,EAAc,SAAA9tB,GAYvB,SAAA8tB,EAAoBE,EAAkCC,GAA4B,IAAA/tB,EAAAC,cAAAC,KAAA0tB,IAC9E5tB,KAAAG,KAAAD,KAAA0tB,IADgBE,cAAkC9tB,EAAA+tB,gBAT5C/tB,EAAAguB,kBAA2C,IAAIC,MAOlDjuB,EAAAkuB,qBAA+B,EAIlCluB,EAAKstB,aAAc,EAAMttB,CAC7B,CAACS,cAAAmtB,EAAA9tB,IAAA,EAAAY,KAAAktB,EAAA,EAAAjtB,IAAA,cAAAC,MAED,SAAYutB,GAAsB,IAAA7hB,EAAApM,KAC9BA,KAAKI,SAASJ,KAAKkuB,YAAY5tB,KAAM,cAAe,CAAC2tB,KAEjDA,EAAQ/nB,QAAa+nB,EAAQjkB,SAC7BhK,KAAKmuB,QAAQnuB,KAAKkuB,YAAY5tB,KAAM,kDAAmD,CAAC2tB,IACxFjuB,KAAKutB,UAAYvtB,KAAK4tB,YAAYQ,aAAa,WAAQhiB,EAAKiiB,oBAAsB,IAEtFruB,KAAKI,SAASJ,KAAKkuB,YAAY5tB,KAAM,aACzC,GAAC,CAAAG,IAAA,kBAAAC,MAED,WAAe,IAAAkM,EAAA5M,KACXA,KAAKI,SAASJ,KAAKsuB,gBAAgBhuB,KAAM,eAEzCN,KAAK6tB,cAAcU,YAAY/mB,UAAU,SAACgnB,GACtC5hB,EAAKohB,oBAAsBQ,EAAOC,OACtC,GACAzuB,KAAKI,SAASJ,KAAKsuB,gBAAgBhuB,KAAM,aAC7C,GAAC,CAAAG,IAAA,qBAAAC,MAEM,WACHV,KAAKI,SAASJ,KAAKquB,mBAAmB/tB,KAAM,eACxCN,KAAKguB,qBACLhuB,KAAKqtB,gBAETrtB,KAAKI,SAASJ,KAAKquB,mBAAmB/tB,KAAM,aAChD,GAAC,CAAAG,IAAA,gBAAAC,MAEM,WACHV,KAAKI,SAASJ,KAAKqtB,cAAc/sB,KAAM,eACvCN,KAAKotB,aAAc,EACnBptB,KAAK8tB,kBAAkBY,KAAK1uB,KAAKotB,aAEjCptB,KAAK6tB,cAAcc,2BACnB3uB,KAAKI,SAASJ,KAAKqtB,cAAc/sB,KAAM,cAC3C,IAAC,CAnDsB,CAAQS,KAAkB4sB,SAAxCD,0CAAa1sB,MAAAC,IAAAD,MAAAiiB,IAAA,0BAAbyK,EAAaxsB,UAAA,eAAA2oB,OAAA,CAAAuD,YAAA,cAAAlnB,OAAA,SAAA8D,MAAA,SAAA4kB,QAAA,CAAAd,kBAAA,qBAAA3sB,SAAA,CAAAH,aAAAI,MAAA,EAAAC,KAAA,EAAAC,OAAA,iRAAAC,SAAA,SAAAC,EAAAC,GAAA,EAAAD,GDL1BR,MARA,EAAA6tB,GAAA,kBAQA7tB,CAR2B,EAAA8tB,GAAA,wBAA3B9tB,MAAAS,EAAAusB,oBAAA,gECaaN,CAAc,+ECXnB1sB,MADJ,UACIA,CAD6E,eAGzEA,MAAA,mBAAAA,MAAA6jB,GAAA,IAAAC,EAAA9jB,QAAA,OAAAA,MAAS8jB,EAAAiK,iBAAgB,GACjC/tB,qCAQIA,MAAA,sDACIA,MAAA,4CAAAA,MAAA,IAAA8jB,EAAAkK,2BAAA,oDAgBYhuB,MAAA,WAAmCA,MAAA,GAAcA,QAAKA,MAAA,aACXA,MAAA,aACvBA,MAAA,GAA4BA,6BAFbA,cAAA8jB,EAAA9a,MAAA1J,MAEfU,MAAA,GAAAA,MAAA8jB,EAAA9a,MAAAqW,cAAA/f,iCAGpBU,MAAA,WAAmCA,MAAA,GAAoBA,QAAKA,MAAA,aACjBA,MAAA,aACvBA,MAAA,GAAmCA,gCAFpBA,cAAAiuB,EAAA3uB,MAEfU,MAAA,GAAAA,MAAA,MAAAiuB,EAAA5O,cAAA,KAAA4O,EAAA5O,cAAA/f,8CAV5BU,MADJ,QACIA,CADiC,qBACgDA,MAAA,yBAAA4jB,GAAA5jB,MAAAwsB,GAAA,IAAA1I,EAAA9jB,MAAA,GAAAA,aAAA8jB,EAAA9a,MAAA4a,KAAAE,EAAA9a,MAAA4a,GAAA5jB,MAAA4jB,EAAA,GAC7E5jB,MAAA,sBAAAA,MAAAwsB,GAAA,IAAA1I,EAAA9jB,MAAA,UAAAA,MAAY8jB,EAAAoK,gBAAe,GAM3BluB,MALA,EAAAmuB,GAAA,qBAKAnuB,CALsC,EAAAouB,GAAA,sBAW9CpuB,iCAbyCA,cAAA,UAAA8jB,EAAA6E,cAA4C3oB,MAAA,UAAA8jB,EAAA9a,kCAejFhJ,MADJ,WACIA,CADoE,WACjCA,MAAA,GAAcA,QAAKA,MAAA,aAA6CA,MAAA,aAC/EA,MAAA,GACxBA,+BAFuCA,MAAA,GAAAA,MAAA8jB,EAAA9a,MAAA1J,MACfU,MAAA,GAAAA,MAAA8jB,EAAA9a,MAAAqW,cAAA/f,iCAlB5BU,MAAA,SAgBIA,MAfA,EAAAquB,GAAA,aAeAruB,CAfqC,EAAAsuB,GAAA,cAmBzCtuB,6BAnBUA,cAAA,OAAA8jB,EAAA6E,aAAAlgB,OAAA,GAeAzI,cAAA,OAAA8jB,EAAA6E,aAAAlgB,OAAA,8BArBVzI,MAFJ,WAEIA,CAD+C,UAG3CA,MAAA,YACJA,QAC6CA,MAA7C,YAA6CA,CAAA,aAC7CA,MAAA,EAAAuuB,GAAA,cAqBJvuB,4BA1BOA,cAAA,aAAA8jB,EAAAyB,sBAEqDvlB,cAAA,MAAA8jB,EAAA5b,YAAAC,cAAA7I,MAA/CU,MAAA,MAAA8jB,EAAA0K,YAAA1K,EAAA5b,YAAAC,eAAAnI,OAGHA,MAAA,GAAAA,MAAA,OAAA8jB,EAAA9a,kCAuBVhJ,MAAA,WACIA,MAAA,sBACJA,4BADmBA,cAAA,QAAA8jB,EAAA7e,UAAuFjF,MAAA,QAAA8jB,EAAA6H,+CAuBtG3rB,MAAA,iBAAoCA,MAAA,mBAAAA,MAAAyuB,GAAA,IAAA3K,EAAA9jB,QAAA,OAAAA,MAAS8jB,EAAAxK,SAAQ,GACHtZ,QAClDA,MAAA,iBACIA,MAAA,mBAAAA,MAAAyuB,GAAA,IAAA3K,EAAA9jB,QAAA,OAAAA,MAAS8jB,EAAA4K,0BAAyB,GAA6D1uB,8BAD/DA,cAAA,YAAA8jB,EAAA6K,gBAAA7K,EAAA8K,gBAAA9K,EAAA+K,cC1DrC,IAAMC,GAAmB,eAAAC,EAAnBD,EAAmB,SAAAnR,GAwB9B,SAAAmR,EAAoBE,EAAiCjpB,EAAwBkpB,EACnEC,EAAoDrC,GAA4B,IAAA/tB,EAAAC,cAAAC,KAAA8vB,IACxFhwB,KAAAG,KAAAD,KAAA8vB,IAFkBE,YAAiClwB,EAAAiH,SAAwBjH,EAAAmwB,cACnEnwB,EAAAowB,uBAAoDpwB,EAAA+tB,gBAvB9D/tB,EAAA8pB,YAAsB,EAEtB9pB,EAAA6pB,aAA6B,GAEtB7pB,EAAAmG,SAAmB,GACnBnG,EAAA6sB,MAAoB,GACpB7sB,EAAAqwB,sBAAgC,EAG9BrwB,EAAAstB,aAAuB,EACtBttB,EAAAguB,kBAA2C,IAAIC,MAElDjuB,EAAAswB,oBAA8B,EAC9BtwB,EAAA6vB,eAAyB,EACzB7vB,EAAA8vB,eAAyB,EACzB9vB,EAAA+vB,aAAuB,EAEvB/vB,EAAAymB,qBAAiC,CAAC,IAClCzmB,EAAAuwB,WAAsB,EAEtBvwB,EAAAkuB,qBAA+B,EAMpCluB,EAAK6sB,MAAQ,CACX,CACED,MAAO,QACP4D,KAAM,gBACN1qB,GAAI,aACJ+mB,MAAO,CACL,CAAED,MAAO,OAAQX,QAAS,WAAQjsB,EAAKywB,YAAY,UAAY,GAC/D,CAAE7D,MAAO,QAASX,QAAS,WAAQjsB,EAAKywB,YAAY,QAAU,GAC9D,CAAE7D,MAAO,OAAQX,QAAS,WAAQjsB,EAAKywB,YAAY,OAAS,KAGhE,CAAEC,WAAW,GACb,CAAE9D,MAAO,SAAU4D,KAAM,iBAAkBvE,QAAS,WAAQjsB,EAAKwa,QAAU,IAC3Exa,CACJ,CAACS,cAAAuvB,EAAAnR,IAAA,EAAAne,KAAAsvB,EAAA,EAAArvB,IAAA,WAAAC,MAEe,WAAQ,IAAA0L,EAAApM,MACtB2lB,OAAAmK,EAAA,WAAA9vB,KAAA,EAAA2lB,CAAA,IAEA,IAAI1F,EAAsBjgB,KAAKuc,sBAAsBhV,gBAAgBC,UAAU,SAAAC,GAC7E2E,EAAKlD,YAAczB,EACnB2E,EAAKqkB,sBACLrkB,EAAKga,cACP,GACApmB,KAAKif,yBAAyBqB,IAAIL,EACpC,GAAC,CAAAxf,IAAA,kBAAAC,MAED,WAAe,IAAAkM,EAAA5M,KACXA,KAAKI,SAASJ,KAAKsuB,gBAAgBhuB,KAAM,eAEzCN,KAAK6tB,cAAcU,YAAY/mB,UAAU,SAACgnB,GACtC5hB,EAAKohB,oBAAsBQ,EAAOC,QAC7B7hB,EAAKohB,qBACRphB,EAAKmiB,gBAEX,GACA/uB,KAAKI,SAASJ,KAAKsuB,gBAAgBhuB,KAAM,aAC7C,GAAC,CAAAG,IAAA,eAAAC,MAEe,WAAY,IAAAgwB,EAOY9K,EAAAC,EAMW8K,EAAAC,EAAAC,EAAAC,EAbvB7jB,EAAAjN,KAE1BA,KAAK4pB,YAAgB5pB,KAAKkJ,YAAYqJ,QAAWvS,KAAKkJ,YAAYqJ,QAAQ9I,OAAS,EACnFzJ,KAAKmJ,cAAgBnJ,KAAKkJ,YAAYC,cACxCnJ,KAAKumB,qBAAuB,CAAC,OAA8B,MAAtBvmB,KAAKmJ,cAAwB,GAAKnJ,KAAKmJ,cAAcoG,YAAa,aACrGvP,KAAKqwB,WAAarwB,KAAKkJ,YAAYsJ,OAAO/I,OAEtCzJ,KAAKkJ,YAAYiJ,kBACnBnS,KAAKiG,SAAQ,GAAA6H,OAAgC,QAAhC8X,EAAM5lB,KAAKkJ,YAAYmM,iBAAS,IAAAuQ,IAAI,GAAE,KAAA9X,OAA6B,QAA7B+X,EAAI7lB,KAAKkJ,YAAYsM,gBAAQ,IAAAqQ,IAAI,IACpF7lB,KAAKowB,mBAA+C,KAAzBpwB,KAAKiG,SAAS8qB,SAAmB/wB,KAAKkJ,YAAYmJ,mBAC7ErS,KAAKmwB,0BAAqEzmB,IAA9C1J,KAAKkJ,YAAYoD,yBAGzCtM,KAAKkJ,YAAYoD,0BACnBtM,KAAKiG,SAAQ,GAAA6H,OAAyD,QAAzD6iB,EAAM3wB,KAAKkJ,YAAYoD,yBAAyB+I,iBAAS,IAAAsb,IAAI,GAAE,KAAA7iB,OAAsD,QAAtD8iB,EAAI5wB,KAAKkJ,YAAYoD,yBAAyBkJ,gBAAQ,IAAAob,IAAI,GAAE,QAAA9iB,OAAiC,QAAjC+iB,EAAO7wB,KAAKkJ,YAAYmM,iBAAS,IAAAwb,IAAI,GAAE,KAAA/iB,OAA6B,QAA7BgjB,EAAI9wB,KAAKkJ,YAAYsM,gBAAQ,IAAAsb,IAAI,IAChN9wB,KAAKgvB,2BAA6BhvB,KAAKkJ,YAAYyJ,aAEgB,IAA/D3S,KAAK2sB,MAAM9hB,UAAU,SAAAC,IAAC,MAAgB,sBAAZA,GAAE4hB,KAA6B,KAC3D1sB,KAAK2sB,MAAMnhB,KAAK,CAAEglB,WAAW,IAC7BxwB,KAAK2sB,MAAMnhB,KAAK,CAAEkhB,MAAO,oBAAqB4D,KAAM,kBAAmBvE,QAAS,WAAQ9e,EAAK+jB,kBAAoB,MAK/GhxB,KAAK2sB,MAAMljB,OAAS,GACtBzJ,KAAK2sB,MAAM3hB,OAAO,EAAG,IAK3BhL,KAAK2pB,aAAsC,QAA1B+G,EAAG1wB,KAAKkJ,YAAYsJ,cAAM,IAAAke,IAAI,GAC/C1wB,KAAKgK,MAAQhK,KAAKkJ,YAAYE,YAChC,GAAC,CAAA3I,IAAA,iBAAAC,MAEM,WAEAV,KAAKguB,qBACRhuB,KAAK6tB,cAAcoD,0BAGrBjxB,KAAKotB,aAAc,EACnBptB,KAAK8tB,kBAAkBY,KAAK1uB,KAAKotB,YACnC,GAAC,CAAA3sB,IAAA,cAAAC,MAEM,SAAYwF,GACjB,OAAOlG,KAAKgwB,UAAUkB,+BAA+B,QAAUhrB,EAAOirB,aAAe,YAAcjrB,EAAOsJ,KAC5G,GAAC,CAAA/O,IAAA,SAAAC,MAEM,WAELV,KAAKuc,sBAAsBjC,QAC7B,GAAC,CAAA7Z,IAAA,gBAAAC,MAEM,WAEL,GADAV,KAAKI,SAASJ,KAAKkvB,cAAc5uB,KAAM,0BAA2B,CAACN,KAAKgK,aACrDN,IAAf1J,KAAKgK,MAAqB,KAAAonB,EAAAC,EACxBjoB,EAAepJ,KAAKuc,sBAAsB1H,eAAezL,aACzDkoB,EAAYloB,GAAc9I,KAC9BgxB,EAAqB,QAAZF,EAAGE,SAAS,IAAAF,OAAA,EAATA,EAAW5S,QAAQ,IAAK,OAIpCxe,KAAK+G,OAAOwqB,mBAAmBC,iBAAmB,WAChD,OAAO,CACT,EAGAxxB,KAAK+G,OAAO0qB,cAAczxB,KAAK+G,OAAOuE,IAAIkT,QAAiB,QAAV6S,EAACC,SAAS,IAAAD,IAAI,GAAIrxB,KAAKgK,MAAM1J,MAAO,CAAEoxB,oBAAqB,UAC9G,CACF,GAAC,CAAAjxB,IAAA,0BAAAC,MAEM,WAAuB,IAAAixB,EAAA3xB,KAC5BA,KAAKI,SAASJ,KAAK0vB,wBAAwBpvB,KAAM,+BAE7CN,KAAK2vB,eAAiB3vB,KAAK4vB,eAAiB5vB,KAAK6vB,aACnD7vB,KAAKiwB,YAAY2B,wBAAwBpqB,UAAU,CACjDyJ,KAAM,SAAC4gB,GAELF,EAAKpV,sBAAsBN,2BAC3B0V,EAAKvB,oBAAqB,CAC5B,GAGN,GAAC,CAAA3vB,IAAA,mBAAAC,MAEM,WACLV,KAAKI,SAASJ,KAAKgxB,iBAAiB1wB,KAAM,wBAC1CN,KAAKkwB,qBAAqBhT,yBAC5B,GAAC,CAAAzc,IAAA,cAAAC,MAEM,SAAYuP,GAAa,IAAA6hB,EAAA9xB,KAC9BA,KAAKI,SAASJ,KAAKuwB,YAAYjwB,KAAM,iBAAkB,CAAC2P,IACxDjQ,KAAKH,QAAQgB,OAEbb,KAAKiwB,YAAY8B,gBAAgB9hB,GAAOzI,UAAU,CAChDyJ,KAAM,SAAC4gB,GAELC,EAAKvV,sBAAsBJ,SAASlM,GACpC6hB,EAAKjyB,QAAQiB,MACf,GAEJ,GAAC,CAAAL,IAAA,sBAAAC,MAEM,WACLV,KAAKI,SAASJ,KAAKywB,oBAAoBnwB,KAAM,kBAE7CN,KAAK8e,aAAakT,YAAYhyB,KAAKkJ,YAAY+G,MACjD,IAAC,CA9K6B,CAAQyO,KAAgBqR,SAA3CD,0CAAkB9uB,MAAAC,MAAAD,MAAAiiB,MAAAjiB,MAAAkiB,MAAAliB,MAAAmiB,MAAAniB,MAAAixB,IAAA,0BAAlBnC,EAAkB5uB,UAAA,iBAAA2oB,OAAA,CAAAuD,YAAA,eAAAwB,QAAA,CAAAd,kBAAA,qBAAA3sB,SAAA,CAAAH,OAAAI,MAAA,GAAAC,KAAA,GAAAC,OAAA,2xDAAAC,SAAA,SAAAC,EAAAC,GAAA,EAAAD,IDhB/BR,MAAA,cACIA,MAAA,EAAAkxB,GAAA,aAMAlxB,MAAA,WACIA,MAAA,kBACJA,QAEAA,MAAA,WACIA,MAAA,4BACAA,MAAA,EAAAmxB,GAAA,mBAGJnxB,QAgCAA,MA9BA,EAAAoxB,GAAA,YA8BApxB,CA7BmD,EAAAqxB,GAAA,aAgCvDrxB,QAEAA,MAAA,gBAAUA,MAAA,6BAAA4jB,GAAA5jB,aAAAS,EAAA2rB,YAAAxI,KAAAnjB,EAAA2rB,YAAAxI,IAAA,GAC6B5jB,QAEvCA,MAAA,iBAA4CA,MAAA,yBAAA4jB,GAAA5jB,aAAAS,EAAA2uB,mBAAAxL,KAAAnjB,EAAA2uB,mBAAAxL,IAAA,GAExC5jB,MAAA,QACIA,MAAA,0GACJA,QAEIA,MADJ,OACIA,CADD,WAEKA,MAAA,0BAAAS,EAAAkuB,eAAuB,CAAI,GAAE3uB,MAAA,qBACrCA,UAEIA,MADJ,OACIA,CADD,WACwDA,MAAA,0BAAAS,EAAAmuB,eAAuB,CAAI,GAAE5uB,MAAA,qBACxFA,UAEIA,MADJ,OACIA,CADD,WACuDA,MAAA,0BAAAS,EAAAouB,aAAqB,CAAI,GAAE7uB,MAAA,mBACrFA,UACAA,MAAA,GAAAsxB,GAAA,sBAMJtxB,eA5EUA,cAAA,OAAAS,EAAAyH,YAAAC,eAO0BnI,MAAA,GAAmCA,MAAnC,eAAAS,EAAAkoB,aAAmC3oB,CAAD,cAAAS,EAAAmoB,aAKlD5oB,MAAA,GAAAA,MAAA,OAAAS,EAAA0uB,sBAKVnvB,cAAA,OAAAS,EAAAyH,YAAAiJ,iBAAA1Q,EAAAyH,YAAAC,eA8B0CnI,cAAA,OAAAS,EAAAyH,YAAAiJ,iBAK1CnR,cAAA,cAAAS,EAAA2rB,aACNpsB,MADoC,SAAAS,EAAAyH,YAAAC,cACpCnI,CADwE,QAAAS,EAAAyH,YAAAE,cAIxEpI,oBAAA,GAAAkkB,KADwClkB,MAAA,UAAAS,EAAA2uB,oBAC0BpvB,MADsB,WACtBA,CADoC,eACpCA,CAArB,eAAqBA,CAAD,6HCzCxD8uB,CAAmB,2CCDpB9uB,MADJ,UACIA,CAD0C,WAEtCA,MAAA,SACAA,MAAA,QAAIA,MAAA,GAAmBA,QACvBA,MAAA,OAAGA,MAAA,GACPA,UAGQA,MAFR,UAEQA,CAFkB,UAElBA,CADgB,cACcA,MAAA,mBAAAA,MAAA6jB,GAAA,IAAAC,EAAA9jB,QAAA,OAAAA,MAAS8jB,EAAAyN,YAAW,GAG9DvxB,wCARYA,MAAA,GAAAA,MAAAwxB,EAAAxR,SACDhgB,MAAA,GAAAA,MAAAwxB,EAAAvR,SCLZ,IAAMwR,GAAa,eAAAC,EAAbD,EAAa,SAAA7yB,GAGxB,SAAA6yB,EAAoBE,EAAsCC,EAA4CC,GAAwC,IAAA/yB,EAAAC,cAAAC,KAAAyyB,IAC5I3yB,KAAAG,KAAAD,KAAAyyB,IADkBE,gBAAsC7yB,EAAA8yB,mBAA4C9yB,EAAA+yB,sBAFtG/yB,EAAA8R,MAAQ,UAIN9R,EAAKM,SAASN,EAAKO,YAAYC,KAAM,UAAUR,CACjD,CAACS,cAAAkyB,EAAA7yB,IAAA,EAAAY,KAAAiyB,EAAA,EAAAhyB,IAAA,WAAAC,MAEM,WACLV,KAAK2yB,cAAcG,QAAS,EAC5B9yB,KAAKI,SAASJ,KAAK+f,SAASzf,KAAM,SACpC,GAAC,CAAAG,IAAA,YAAAC,MAEM,WAEP6L,SAAS4G,SAAS4f,QAClB,IAAC,CAhBuB,CAAQhyB,KAAkB2xB,SAAvCD,0CAAYzxB,MAAAC,MAAAD,MAAAiiB,IAAAjiB,MAAAkiB,IAAA,0BAAZuP,EAAYvxB,UAAA,eAAAC,SAAA,CAAAH,OAAAI,MAAA,EAAAC,KAAA,EAAAC,OAAA,6TAAAC,SAAA,SAAAC,EAAAC,GAAA,EAAAD,IDVzBR,MAFA,gBAEAA,CAF2B,gBAI3BA,MAAA,aACIA,MAAA,mBACJA,QAIAA,MAFA,eAEAA,CAFyB,eAGzBA,MAAA,eACIA,MAAA,EAAAgyB,GAAA,sBAcJhyB,yECdayxB,CAAa,0BCmCbQ,GAAU,eAAAC,EAAVD,GAAUzyB,OAAA,SAAAyyB,KAAAlzB,OAAAC,KAAAizB,EAAA,GAAAC,SAAVD,yCAAU,yBAAVA,gCAnBTE,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,KACAC,IACAC,IACAC,KACAC,IAIAP,KACAC,QAISN,CAAU,gDCrCVa,GAAgB,eAAAC,EAAhBD,EAAgB,WAIzB,SAAAtzB,KAFA,SAAAszB,EAAmB/sB,EAAwBlH,IAA4BE,OAAAC,KAAA8zB,GAApD9zB,KAAA+G,SAAwB/G,KAAAH,SAAgC,EAE3E,EAAAY,IAAA,YAAAC,MAGA,SAAUszB,EAAuB/iB,GAE7B,OAAOA,EAAKgjB,OAAOD,GAEdtrB,QACGiV,MAAW,SAACvM,GACR,IAAIwM,EAAW,GACf,GAAIxM,EAAMA,iBAAiB8iB,WACvB1pB,QAAQkB,IAAI,6BACZkS,EAAQ,UAAA9P,OAAasD,EAAMA,MAAMzF,cAAO,GAExCnB,QAAQkB,IAAI,6BACZkS,EAAQ,eAAA9P,OAAkBsD,EAAM3B,OAAM,gBAAA3B,OAAesD,EAAMA,OAEtC,MAAjBA,EAAM3B,OAAgB,CAEtBjF,QAAQ4G,MAAM,sBACd,IAAI+iB,EAAcH,EAAI1oB,IAAI+H,MAAM,KAChC+gB,UAAU,YAAW,oCAAAtmB,OAAsCqmB,EAAYA,EAAY1qB,OAAS,GAAE,KAAK,QACvG,CAEJe,eAAQkB,IAAIkS,IAAQ,EACbC,MAAWzM,EACtB,GAEZ,IAAC,CAhCwB,GAgCxB2iB,SAhCQD,0CAAgB9yB,MAAAC,MAAAD,MAAAiiB,KAAA,4BAAhB6Q,EAAgBpyB,QAAhBoyB,EAAgBnyB,UAAAC,WAFb,SAEHkyB,CAAgB,qCCGhBO,GAAe,eAAAC,EAAfD,EAAe,WAOxB,SAAA7zB,KAHA,SAAA6zB,EAAoBze,EAA2Csa,EACnDrwB,IAA4BE,OAAAC,KAAAq0B,GADpBr0B,KAAA4V,eAA2C5V,KAAAkwB,uBACnDlwB,KAAAH,UAHJG,KAAAuc,yBAA+C1V,OAAOS,IAGlB,EAE5C,EAAA7G,IAAA,YAAAC,MAGA,SAAUszB,EAAuB/iB,GAAiB,IAAAnR,EAAAE,KAG9C,GAAIg0B,EAAI1oB,IAAIqI,SAAS,QACjB,OAAO1C,EAAKgjB,OAAOD,GAIvB,IAOSO,EAAAC,EAPLpX,EAAUpd,KAAKuc,sBAAsB1H,eACzC,OAAIuI,EAAQzK,aAAeyK,EAAQzK,YAAc,IAAInN,KAE7C4X,EAAQ9Q,0BACRtM,KAAKkwB,qBAAqBhT,0BACnBuX,OAGPz0B,KAAKH,QAAQgB,OACNb,KAAK4V,aAAaoI,iBAAqC,QAArBuW,EAACnX,EAAQ1K,oBAAY,IAAA6hB,IAAI,GAAwB,QAAtBC,EAAEpX,EAAQxK,oBAAY,IAAA4hB,IAAI,IACjF9rB,QACGiV,MAAW,SAAAxS,GACPrL,SAAKD,QAAQiB,OACb0J,QAAQ4G,MAAM,sDAAuDjG,GACrEipB,UAAU,QAAS,kEAAmE,SACjFpN,KAAK,WAEFlnB,EAAKyc,sBAAsBjC,QAC/B,IAAC,EACEuD,MAAW,WAAQ,OAAO1S,CAAK,EAC1C,IAAC,EACDupB,MAAU,SAAAC,GACN70B,SAAKD,QAAQiB,OACbhB,EAAKyc,sBAAsB3B,0BAA0B+Z,EAAUvX,EAAQjU,cAAeiU,EAAQhU,cACvF6H,EAAKgjB,OAAOn0B,EAAK80B,SAASZ,EAAKW,EAAShtB,OACnD,KAMjBsJ,EAAKgjB,OAAOj0B,KAAK40B,SAASZ,EAAK5W,EAAQ1K,cAClD,GAEA,CAAAjS,IAAA,WAAAC,MAMQ,SAASszB,EAAuBrsB,GACpC,OAAOqsB,EAAIa,MAAM,CAAEC,WAAY,CAAEhtB,cAAe,UAAYH,IAChE,IAAC,CA5DuB,GA4DvB2sB,SA5DQD,0CAAerzB,MAAAC,MAAAD,MAAAiiB,MAAAjiB,MAAAkiB,KAAA,4BAAfmR,EAAe3yB,QAAf2yB,EAAe1yB,UAAAC,WAFZ,SAEHyyB,CAAe,qCCsDfU,GAAoB,eAAAC,EAApBD,GAAoBv0B,OAC7B,SAAAu0B,EAAoCE,GAChC,MADkEl1B,KAAAC,KAAA+0B,GAC9DE,EACA,MAAM,IAAInX,MAAK,GAAAhQ,OAAImnB,EAAY,uEAEvC,GAACD,SALQD,0CAAoB/zB,MAAA+zB,EAAA,6BAApBA,iCAZA,CACTtV,KACAE,MACDuV,QAAA,CAtBC/B,KACAC,KACAC,KACA8B,MACAvN,KACA4L,KACA4B,KACA9B,KACAC,KACAM,IACAwB,KACA5B,KACA6B,MACAC,MACAC,MACAC,KACAC,KACAC,SAcSZ,CAAoB,ICxC3Bpf,GAAW,YAAIigB,KAAS1uB,KAAYgb,MAqD7B2T,GAAS,eAAAC,EAATD,GAASr1B,OAAA,SAAAq1B,KAAA91B,OAAAC,KAAA61B,EAAA,GAAAC,SAATD,yCAAS,yBAATA,EAASE,UAAA,CAHRtD,mCAbD,CACTuD,MAEA,CAAEC,QAASC,MAAmBC,SAAU9B,GAAiB+B,OAAO,GAEhE,CAAEH,QAASC,MAAmBC,SAAUrC,GAAkBsC,OAAO,GAKjEtO,GACAoB,IACDgM,QAAA,CAzCC/B,KACAC,KACAC,KACA2C,MAEA3O,GAEAgP,KAAexO,QAAQ,CAAElS,cAEzB2gB,KAEAC,MAAoBC,SAAS,iBAAkB,CAI7CC,QAA+B,UAArBvvB,KAAYqY,KAItBmX,qBAAsB,6BAGxB3B,GAEA9B,GAEAW,KACAH,QAkBSoC,CAAS,IC3ElB3uB,KAAY8a,eACd2U,SAGFC,OAAyBC,gBAAgBhB,IAAUre,MAC1C,SAAArM,GAAG,OAAIX,QAAQ4G,MAAMjG,EAAI","names":["AppSpinnerComponent","_AppSpinnerComponent","_OptixComponentBase","spinner","_this","_classCallCheck","this","_callSuper","loadingText","showCount","logDebug","constructor","name","_inherits","_createClass","key","value","times","i","show","hide","OptixComponentBase","i0","i1","selectors","features","decls","vars","consts","template","rf","ctx","factory","ɵfac","providedIn","BusinessObjectStatus","Active","Disabled","Deleted","InsightStatus","NotSet","Draft","Requested","Rejected","Submitted","Accepted","Completed","InvestigationStatus","Open","Concluded","OptixSettingName","_OptixSettingName","Currency","CurrencySymbol","DefaultHomePage","XpasHomeUrl","XpasLiteHomeUrl","ETS","DisplayEnergyFilter","BaseInterval","RunningHoursUnitTypes","PemsUnitTypes","EnergyFilterOptions","AnalysisPageShowAbsorbedPowerForEquipment","UserManualUrl","EmissionsCo2Label","OperatingStatusLevels","LaePeriodTableTopX","DtuCostPerMinute","StorageCostPerMinute","ColdFlaring","EnableChartTypeSwitch","RolePagePermissions","None","Read","Create","Edit","Delete","Approve","SelfApprove","ViewAllAssetsOnDashboard","UserTypes","Opex","Erm","Client","EnergyUnit","Co2","MWth","MW","PageFilterModel","flareCategorySetLevel","ch4Co2eToggle","monthNumber","yearNumber","Date","getFullYear","fillPollutantWithNullAssets","AnalyticsLoginModel","id","apiKey","StartAnalyticsPageViewModel","pageTitle","pageData","username","tenant","StartAnalyticsSessionModel","referrer","localStorageSessionIdKey","localStoragePageViewIdKey","localStorageApiTokenKey","AnalyticsService","_AnalyticsService","baseApiVersion","http","HttpClient","inject","HttpBackend","router","Router","baseApiUrl","environment","analytics","baseUrl","applicationId","AppOktaSessionService","sessionState$","subscribe","s","sessionInfoUpdates","token","headers","HttpHeaders","Authorization","localStorageItem","localStorage","getItem","tokenDetails","JSON","parse","currentTime","expiryDate","of","loginModel","post","pipe","tap","data","setItem","stringify","newSessionInfo","originalSessionInfo","_objectSpread","sessionInfo","currentTenant","currentAsset","recordUserAnalytics","includePageData","additionalPageData","arguments","length","undefined","email","root","routerState","snapshot","pageRoute","asset","_step","_iterator","_createForOfIteratorHelper","paramMap","keys","_loop","paramMapKey","console","trace","get","param","rootParamIndex","findIndex","e","indexOf","splice","n","done","err","f","children","url","toString","push","ex","log","message","_i","_Object$entries","Object","entries","_Object$entries$_i","_slicedToArray","startAnalyticsPageView","join","_this2","sessionDetails","originalUserSessionState","document","sessionStartUrl","getNewAnalyticsToken","postToAnalyticsService","sessionStorage","_this3","sessionId","sessionEndUrl","removeItem","_this$sessionInfo$ema","_this4","previousPageViewId","pageViewDetails","pageViewStartUrl","pageViewId","getHttpHeaderOptions","AssetSettingService","_AssetSettingService","_ServiceBase","injector","assetId","assetSettingModel","httpQueue","concat","clearQueue","settingName","assetSetting","delete","put","map","assetDataTime","ServiceBase","SupportService","_SupportService","supportModel","_supportModel$subject","_supportModel$support","_supportModel$message","formData","FormData","append","subject","supportType","attachments","accessRequest","TenantService","_TenantService","newTenant","tenancyName","logo","status","logoFile","UserService","_UserService","newUser","tenantId","userModel","user","theme","model","PendingRequest","method","subscription","HttpQueue","_HttpQueue","requests$","Subject","queue","httpClient","request","execute","cancelDuplicates","addRequestToQueue","requestData","next","res","requestExecuted","error","requestError","share","sub","complete","shift","startNextRequest","responseError","title","existingRequest","find","index","_injector","optixApi","SessionState","isAuthenticated","isSessionInitialised","hasAcceptedPrivacy","userType","tenants","assets","roles","jsonWebToken","tokenExpiry","refreshToken","AppOktaSessionHelperService","_AppOktaSessionHelperService","route","getTenantFromUrl","paths","window","location","pathname","split","mainPathIndex","hostsplit","hostname","slice","optixSubDomains","includes","toLowerCase","_asset","getAssetFromUrl","isRequestedRouteForTenantSelector","pathFromRoot","_e$routeConfig","routeConfig","path","isRequestedRouteForRootAdmin","_e$routeConfig2","isRequestedRouteForSupport","_e$routeConfig3","state","isRequestedRouteForAdmin","isRequestedRouteForDashboard","oktaId","b2cId","sessionState","identityId","tokenModel","updateSessionFromToken","decodedToken","JwtHelperService","decodeToken","userId","firstname","surname","savedTheme","lastname","_AppOktaSessionService","_oktaStateService","oktaAuth","tokenService","SessionTokenService","tenantService","assetUserService","AssetUserService","assetSettingService","appOktaSessionHelperService","_sessionState","BehaviorSubject","getValue","asObservable","requestedTenant","requestedAsset","_init","_asyncToGenerator","_regeneratorRuntime","mark","_callee","_sessionState$current","_sessionState$current2","_sessionState$current3","wrap","_context","prev","init","abrupt","initialiseSession","t0","catch","logError","stop","_x","_x2","apply","_initialiseSession","_callee2","_context2","initialiseSessionState","sent","generateAuthToken","lastValueFrom","getUsersTenants","validateTenantAccess","selectTenant","validateAssetAccess","selectAsset","redirectUser","_x3","_x4","_x5","_x6","_x7","_initialiseSessionState","_callee3","_claims$find","_claims$find2","_claims$find3","_claims$find4","claims","names","_context3","getClaims","c","createSessionState","_getClaims","_callee4","_context4","tokenManager","idToken","entry","_logout","_callee5","_context5","signOut","logout","authorisedTenant","x","routeAsset","authorisedAsset","navigate","updateSessionFromNewToken","impersonatedUserSession","initialiseImpersonationSession","_selectTenant","_callee6","_context6","getUsersAssets","updateAssets","_x8","updateTenants","filter","userAccessible","_selectAsset","_callee7","_context7","getAllAssetSettings","settings","assetSettingModels","_x9","currentFlareStack","setCurrentFlareStack","setAcceptTermsAndPrivacy","newTheme","setTheme","OKTA_AUTH","ImpersonationService","_ImpersonationService","appOktaSessionService","_startImpersonationSession","currentSession","sessionDuration","_impersonatedUserSess","_impersonatedUserSess2","startImpersonationSession","createSessionStateForImpersonatedUser","impersonationAdminUrl","getTime","setTimeout","endImpersonationSession","_endImpersonationSession","session","TokenModel","_SessionTokenService","_generateAuthToken","authModel","applicationSecret","getAuthToken","catchError","errorMsg","throwError","Error","jwt","refreshAuthToken","refreshModel","_AssetUserService","ThemeService","_ThemeService","themeLink","getElementById","href","replace","DOCUMENT","AppComponentBase","_AppComponentBase","version","require","themeService","isImpersonatedSession","themeChanged","sessionStateSubscription","Subscription","pageSubscriptions","timezone","pageFilter","isProdMode","mode","confirmationService","ConfirmationService","messageService","MessageService","loadingSpinner","NgxSpinnerService","baseRouter","ngOnInit","getTheme","sessionSubscription","_this2$sessionInfo$cu","_this2$sessionInfo$cu2","_this2$sessionInfo$th","timezoneModel","add","events","event","NavigationEnd","scrollTo","ngOnDestroy","unsubscribe","type","showToast","severity","summary","detail","permission","fullPermissionName","pageName","encapsulation","locale","panelLoaderIcon","panelLoaderSize","panelLoaderColour","optionalParams","instance","logMessageDate","formatDate","now","debug","production","raygunKey","okta","clientId","issuer","redirectUri","scopes","pkce","AppInitialiserComponent","_AppInitialiserComponent","appOktaSesionService","authService","_ngOnInit","authState$","_s$isAuthenticated","_ref","authenticated","i2","i3","i4","RoleGuard","_RoleGuard","_canActivateInternal","routeRoles","canActivateInternal","role","finish","_canActivate","canActivate","_canActivateChild","canActivateChild","CookieComponent","_CookieComponent","FatalExceptionComponent","_FatalExceptionComponent","PageNotFoundComponent","_PageNotFoundComponent","TermsComponent","_TermsComponent","RequestAccessModel","requestorEmail","requestorFirstname","requestorLastname","reason","$event","_r1","ctx_r1","requestAssetAccess","UnauthorisedComponent_ng_template_11_small_11_Template","UnauthorisedComponent_ng_template_11_small_16_Template","_c0","submitted","asset_r3","invalid","_r4","submitRequest","UnauthorisedComponent","_UnauthorisedComponent","supportService","_superPropGet","_this$sessionInfo$fir","_this$sessionInfo$las","submitAccessRequest","r","UnauthorisedComponent_ng_template_11_Template","UnauthorisedComponent_ng_template_12_Template","ForbiddenPage","_ForbiddenPage","loadPageData","_this$sessionInfo$cur","_this$sessionInfo$cur2","navigationProperties","routes","component","OktaAuthGuard","OktaCallbackComponent","loadChildren","Promise","all","__webpack_require__","then","bind","m","MainModule","RootModule","AppRoutingModule","_AppRoutingModule","analyticsService","httpQueueService","RouteConfigLoadStart","RouteConfigLoadEnd","NavigationStart","RouterModule","forRoot","LogUpdateService","_LogUpdateService","appRef","updates","isEnabled","setupIntervalToCheckForUpdates","subscribeToVersionUpdates","appIsStable$","isStable","first","interval$","interval","appUpdate$","checkForUpdate","versionUpdates","evt","hash","life","currentVersion","latestVersion","PromptUpdateService","_PromptUpdateService","swUpdate","promptForVersionUpdates","sticky","ctx_r0","logoHeight","BrandComponent","_BrandComponent","tenantAssets","tenantCount","inputs","BrandComponent_a_1_Template","BrandComponent_img_2_Template","AppFooterComponent","_AppFooterComponent","year","getUTCFullYear","ScreenService","_ScreenService","observer","BreakpointObserver","observe","header","getElementsByTagName","style","marginLeft","section","footer","paddingLeft","messageText","EnvironmentBannerComponent","_EnvironmentBannerComponent","displayMessage","EnvironmentBannerComponent_p_message_0_Template","OptixMenuItem","subMenu","isExternal","externalUrlSettingName","MenuBase","_MenuBase","fullMenu","MenuService","_MenuService","menuBase","command","processOptixMenu","optixMenuItems","userSpecificMenu","forEach","optixMenuItem","validatedMenuItem","validateMenuItemAccess","convertOptixMenuItemToPrimeNgMenuItem","childMenu","routerLink","label","items","loadExternalUrl","_this$asset$assetSett","_this$asset","_this$tenant$tenantSe","_this$tenant","tenantSettingModels","userManualUrl","open","menuVisible","onHideSideBar","MenuComponent_Conditional_0_ng_template_1_Template","menuItems","_r3","MenuComponent_Conditional_1_ng_template_1_Template","MenuComponent","_MenuComponent","menuService","screenService","menuVisibleChange","EventEmitter","isSmallMediumScreen","changes","ngOnChanges","logInfo","getMenuItems","onMenuItemSelected","ngAfterViewInit","isBelowLg","result","matches","emit","removeMarginForMenuPanel","outputs","MenuComponent_Conditional_0_Template","MenuComponent_Conditional_1_Template","handleShowMenu","impersonationSessonEndTime","assetOption_r4","onAssetChange","AppHeaderComponent_div_7_div_5_div_1_ng_template_3_Template","AppHeaderComponent_div_7_div_5_div_1_ng_template_4_Template","AppHeaderComponent_div_7_div_5_div_1_Template","AppHeaderComponent_div_7_div_5_div_2_Template","AppHeaderComponent_div_7_div_5_Template","getSafeLogo","_r5","acceptedTermsAndPrivacy","privacyViewed","cookiesViewed","termsViewed","AppHeaderComponent","_AppHeaderComponent","sanitizer","userService","impersonationService","impersonationSession","displayTermsDialog","assetCount","icon","toggleTheme","separator","setThemeFromSession","_this$sessionInfo$ass","_this$sessionInfo$ori","_this$sessionInfo$ori2","_this$sessionInfo$fir2","_this$sessionInfo$las2","trim","endImpersonation","applyMarginForMenuPanel","bypassSecurityTrustResourceUrl","logoFileType","_assetName","_assetName2","assetName","routeReuseStrategy","shouldReuseRoute","navigateByUrl","onSameUrlNavigation","_this5","acceptTermsAndPrivacy","response","_this6","updateUserTheme","switchTheme","i5","AppHeaderComponent_div_1_Template","AppHeaderComponent_p_message_6_Template","AppHeaderComponent_div_7_Template","AppHeaderComponent_div_8_Template","AppHeaderComponent_ng_template_22_Template","reloadApp","message_r3","AppComponent","_AppComponent","primengConfig","logUpdateService","promptUpdateService","ripple","reload","AppComponent_ng_template_7_Template","HomeModule","_HomeModule","CommonModule","BrowserModule","BrowserAnimationsModule","MessageModule","MessagesModule","FormsModule","ButtonModule","InputTextModule","InputTextareaModule","ToastModule","CardModule","ErrorInterceptor","_ErrorInterceptor","req","handle","ErrorEvent","urlSections","Swal","AuthInterceptor","_AuthInterceptor","_session$jsonWebToken","_session$refreshToken","EMPTY","switchMap","newToken","addToken","clone","setHeaders","CoreComponentsModule","_CoreComponentsModule","parentModule","imports","NgxSpinnerModule","AvatarModule","SidebarModule","PanelMenuModule","MenuModule","DropdownModule","DialogModule","SplitButtonModule","InputSwitchModule","OktaAuth","AppModule","_AppModule","bootstrap","HttpClientModule","provide","HTTP_INTERCEPTORS","useClass","multi","OktaAuthModule","SharedModule","ServiceWorkerModule","register","enabled","registrationStrategy","enableProdMode","__NgCli_bootstrap_1","bootstrapModule"],"ignoreList":[],"sourceRoot":"webpack:///","sources":["./src/app/core/components/app-spinner/app-spinner.component.ts","./src/app/core/components/app-spinner/app-spinner.component.html","./src/app/core/models/constants/business-object-status-enum.ts","./src/app/core/models/constants/communications/insight-status-enum.ts","./src/app/core/models/constants/communications/investigation-status-enum.ts","./src/app/core/models/constants/optix-setting-name.constants.ts","./src/app/core/models/constants/permissions/role-page-permissions-enum.ts","./src/app/core/models/constants/permissions/user-types-enum.ts","./src/app/core/models/constants/views/energy-unit.enum.ts","./src/app/core/models/views/page-filter-model.ts","./src/app/core/models/analytics/analytics-login.model.ts","./src/app/core/models/analytics/start-analytics-page-view.model.ts","./src/app/core/models/analytics/start-analytics-session.model.ts","./src/app/core/services/analytics/analytics.service.ts","./src/app/core/services/asset/configuration/asset-setting.service.ts","./src/app/core/services/global/clients/support.service.ts","./src/app/core/services/global/clients/tenant.service.ts","./src/app/core/services/global/clients/user.service.ts","./src/app/core/services/http-queue.service.ts","./src/app/core/services/service-base.ts","./src/app/core/models/session/session-state.model.ts","./src/app/core/services/session/app-okta-session-helper.service.ts","./src/app/core/services/session/app-okta-session.service.ts","./src/app/core/services/session/impersonation.service.ts","./src/app/core/models/authentication/token.model.ts","./src/app/core/services/session/token/session-token.service.ts","./src/app/core/services/tenant/permissions/asset-user/asset-user.service.ts","./src/app/core/utils/theme/theme.service.ts","./src/app/core/utils/base-components/app-component-base.ts","./src/app/core/utils/base-components/optix-component-base.ts","./src/environments/environment.prod.ts","./src/app/app-initialiser.component.ts","./src/app/app-initialiser.component.html","./src/app/core/utils/guards/role-guard.ts","./src/app/modules/home/pages/cookie/cookie.component.ts","./src/app/modules/home/pages/cookie/cookie.component.html","./src/app/modules/home/pages/fatal-exception/fatal-exception.component.ts","./src/app/modules/home/pages/fatal-exception/fatal-exception.component.html","./src/app/modules/home/pages/page-not-found/page-not-found.component.ts","./src/app/modules/home/pages/page-not-found/page-not-found.component.html","./src/app/modules/home/pages/terms/terms.component.ts","./src/app/modules/home/pages/terms/terms.component.html","./src/app/core/models/global/clients/request-access.model.ts","./src/app/modules/home/pages/unauthorised/unauthorised.component.html","./src/app/modules/home/pages/unauthorised/unauthorised.component.ts","./src/app/modules/home/pages/forbidden/forbidden.page.ts","./src/app/modules/home/pages/forbidden/forbidden.page.html","./src/app/app-routing.module.ts","./src/app/core/services/service-worker/log-update.service.ts","./src/app/core/services/service-worker/prompt-update.service.ts","./src/app/core/components/brand/brand.component.html","./src/app/core/components/brand/brand.component.ts","./src/app/core/components/app-footer/app-footer.component.ts","./src/app/core/components/app-footer/app-footer.component.html","./src/app/core/services/screen.service.ts","./src/app/core/components/environment-banner/environment-banner.component.html","./src/app/core/components/environment-banner/environment-banner.component.ts","./src/app/core/services/session/menu/menu-base.ts","./src/app/core/services/session/menu/menu.service.ts","./src/app/core/components/app-menu/menu.component.html","./src/app/core/components/app-menu/menu.component.ts","./src/app/core/components/app-header/app-header.component.html","./src/app/core/components/app-header/app-header.component.ts","./src/app/app.component.html","./src/app/app.component.ts","./src/app/modules/home/home.module.ts","./src/app/core/utils/interceptors/error-interceptor.ts","./src/app/core/utils/interceptors/auth-interceptor.ts","./src/app/core/components/core-components.module.ts","./src/app/app.module.ts","./src/main.ts"],"sourcesContent":["import { Component, Injectable } from '@angular/core';\r\nimport { NgxSpinnerService } from 'ngx-spinner';\r\nimport { OptixComponentBase } from '../../utils/base-components/optix-component-base';\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\n@Component({\r\n selector: 'app-spinner',\r\n templateUrl: './app-spinner.component.html'\r\n})\r\nexport class AppSpinnerComponent extends OptixComponentBase {\r\n loadingText = \"Please wait...\"\r\n\r\n showCount: number = 0;\r\n\r\n constructor(private spinner: NgxSpinnerService) {\r\n super();\r\n this.logDebug(this.constructor.name, 'loaded');\r\n }\r\n\r\n public showMultiple(times: number): void {\r\n for(var i = 0; i < times; i++)\r\n this.show();\r\n }\r\n\r\n public show(): void {\r\n this.showCount++;\r\n this.logDebug(this.show.name, 'spinner show called, counter incremented', [this.showCount]);\r\n // Only call show on the spinner if the count is at 1\r\n if (this.showCount === 1) {\r\n\t\t this.spinner.show('applicationSpinner');\r\n\t } \r\n }\r\n\r\n public hide(): void {\r\n if (this.showCount > 0) {\r\n this.showCount--;\r\n this.logDebug(this.hide.name, 'spinner hide called, counter decremented', [this.showCount]);\r\n // Hide the spinner if the count has reached zero\r\n if (this.showCount === 0) {\r\n this.spinner.hide('applicationSpinner');\r\n }\r\n } \r\n }\r\n}\r\n","\r\n\r\n

{{loadingText}}

\r\n
\r\n","export enum BusinessObjectStatus {\r\n Active = \"Active\",\r\n Disabled = \"Disabled\",\r\n Deleted = \"Deleted\"\r\n}","export enum InsightStatus {\r\n\tNotSet = 'Not Set',\r\n\tDraft = 'Draft',\r\n\tRequested = 'Requested',\r\n Rejected = 'Rejected',\r\n Submitted = 'Submitted',\r\n Accepted = 'Accepted',\r\n Completed = 'Completed',\r\n Deleted = 'Deleted'\r\n}\r\n","export enum InvestigationStatus {\r\n\tNotSet = 'Not Set',\r\n\tOpen = 'Open',\r\n\tConcluded = 'Concluded'\r\n}\r\n","export class OptixSettingName {\r\n public static readonly Currency: string = 'Currency';\r\n public static readonly CurrencySymbol: string = 'CurrencySymbol';\r\n public static readonly DefaultHomePage: string = 'DefaultHomePage';\r\n public static readonly XpasHomeUrl: string = 'XpasHomeUrl';\r\n public static readonly XpasLiteHomeUrl: string = 'XpasLiteHomeUrl';\r\n public static readonly ETS: string = 'ETS';\r\n public static readonly DisplayEnergyFilter: string = 'DisplayEnergyFilter';\r\n public static readonly BaseInterval: string = 'BaseInterval';\r\n public static readonly RunningHoursUnitTypes: string = 'RunningHoursUnitTypes';\r\n public static readonly PemsUnitTypes: string = 'PemsUnitTypes';\r\n public static readonly EnergyFilterOptions: string = 'EnergyFilterOptions';\r\n public static readonly AnalysisPageShowAbsorbedPowerForEquipment: string = 'AnalysisPageShowAbsorbedPowerForEquipment';\r\n public static readonly UserManualUrl: string = 'UserManualUrl';\r\n public static readonly EmissionsCo2Label: string = 'CO2';\r\n public static readonly OperatingStatusLevels: string = 'OperatingStatusLevels';\r\n public static readonly LaePeriodTableTopX: string = 'LaePeriodTableTopX';\r\n public static readonly DtuCostPerMinute: string = 'DtuCostPerMinute';\r\n public static readonly StorageCostPerMinute: string = 'StorageCostPerMinute';\r\n public static readonly ColdFlaring: string = 'ColdFlaring';\r\n public static readonly EnableChartTypeSwitch: string = 'EnableChartTypeSwitch';\r\n}","export enum RolePagePermissions {\r\n None = \"None\",\r\n Read = \"Read\",\r\n Create = \"Create\",\r\n Edit = \"Edit\",\r\n Delete = \"Delete\",\r\n Approve = \"Approve\",\r\n SelfApprove = \"SelfApprove\",\r\n ViewAllAssetsOnDashboard = \"ViewAllAssetsOnDashboard\"\r\n}","export enum UserTypes {\r\n\tNone = 'None',\r\n\tOpex = 'Opex',\r\n\tErm = 'Erm',\r\n\tClient = 'Client',\r\n}\r\n","/**\r\n * The energy units\r\n */\r\nexport enum EnergyUnit {\r\n\tCo2 = 'CO2',\r\n\tMWth = 'MWthermal',\r\n\tMW = 'MW'\r\n}","import { LevelModel } from \"../asset/emissions/efficiency/level.model\";\r\nimport { FlareStackModel } from \"../asset/emissions/flaring/flare-stack-model\";\r\nimport { PemsYearModel } from \"../asset/emissions/pems/pems-year.model\";\r\nimport { PollutantTypeModel } from \"../asset/emissions/pems/pollutant-type-model\";\r\nimport { SystemModel } from \"../asset/inventory/system-model\";\r\nimport { UnitModel } from \"../asset/inventory/unit-model\";\r\nimport { ChartScale } from \"../constants/views/chart-scale-enum\";\r\nimport { EnergyUnit } from \"../constants/views/energy-unit.enum\";\r\nimport { TenantModel } from \"../global/clients/tenant-model\";\r\nimport { AssetCategorySetModel } from \"../tenant/permissions/asset-category-set.model\";\r\n\r\nexport class PageFilterModel {\r\n public chartName!: string;\r\n public pageName!: string;\r\n public pageArea!: string;\r\n\r\n public energyUnit!: EnergyUnit;\r\n public scale!: ChartScale;\r\n\r\n public initialDate!: Date;\r\n public endDate!: Date;\r\n\r\n public tag!: UnitModel;\r\n public pollutantType!: PollutantTypeModel;\r\n\r\n public fuelType!: string;\r\n\r\n public flareStack!: FlareStackModel;\r\n public flareCategorySet!: AssetCategorySetModel;\r\n public flareCategorySetLevel: number = 1;\r\n\r\n public plainTenant!: string;\r\n public tenant!: TenantModel;\r\n\r\n public username!: string;\r\n\r\n public powerType!: string;\r\n\r\n public initialDateLocal!: Date;\r\n public endDateLocal!: Date;\r\n\r\n public ch4Co2eToggle: string = 'ch4';\r\n\r\n public curveType!: string;\r\n\r\n public unitType!: string;\r\n public system!: string;\r\n public level!: LevelModel;\r\n public systemObject!: SystemModel;\r\n\r\n public monthNumber: number = 0;\r\n public yearNumber: number = (new Date()).getFullYear();\r\n\r\n public injectionLogId!: string;\r\n\r\n public pemsYear!: PemsYearModel;\r\n public fillPollutantWithNullAssets: boolean = false;\r\n constructor() { }\r\n}\r\n","export class AnalyticsLoginModel {\r\n public id: string = '';\r\n public apiKey: string = '';\r\n\r\n constructor() {}\r\n}","export class StartAnalyticsPageViewModel {\r\n\tpublic sessionId: string | undefined;\r\n\tpublic pageTitle: string = '';\r\n\tpublic pageData: string = '';\r\n\tpublic previousPageViewId: string | undefined;\r\n public username: string = '';\r\n public tenant: string = 'root';\r\n\r\n constructor() {}\r\n}\r\n\r\nexport class StartAnalyticsPageViewResponseModel {\r\n public sessionId: string = '';\r\n public pageViewId: string = '';\r\n\r\n constructor() {}\r\n}","export class StartAnalyticsSessionModel {\r\n public username: string = '';\r\n public tenant: string = 'root';\r\n public referrer: string = '';\r\n\r\n constructor() {}\r\n}","import { HttpBackend, HttpClient, HttpHeaders } from '@angular/common/http';\r\nimport { inject, Injectable } from '@angular/core';\r\nimport { Router } from '@angular/router';\r\nimport { Observable, of, Subscription, tap } from 'rxjs';\r\nimport { environment } from 'src/environments/environment';\r\nimport { AnalyticsLoginModel } from '../../models/analytics/analytics-login.model';\r\nimport { StartAnalyticsPageViewModel, StartAnalyticsPageViewResponseModel } from '../../models/analytics/start-analytics-page-view.model';\r\nimport { StartAnalyticsSessionModel } from '../../models/analytics/start-analytics-session.model';\r\nimport { TokenModel } from '../../models/authentication/token.model';\r\nimport { SessionState } from '../../models/session/session-state.model';\r\nimport { AppOktaSessionService } from '../session/app-okta-session.service';\r\n\r\nconst localStorageSessionIdKey: string = 'Opex.Optix2.Analytics.SessionId';\r\nconst localStoragePageViewIdKey: string = 'Opex.Optix2.Analytics.PageViewId';\r\nconst localStorageApiTokenKey: string = 'Opex.Optix2.Analytics.Token';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class AnalyticsService {\r\n public http: HttpClient;\r\n protected router: Router;\r\n\r\n public baseApiUrl: string;\r\n public baseApiVersion: string = 'v2';\r\n private applicationId: string;\r\n private apiKey: string;\r\n\r\n public sessionInfo!: SessionState;\r\n\r\n constructor() {\r\n this.http = new HttpClient(inject(HttpBackend));\r\n this.router = inject(Router);\r\n\r\n this.baseApiUrl = environment.analytics.baseUrl;\r\n this.applicationId = environment.analytics.applicationId;\r\n this.apiKey = environment.analytics.apiKey;\r\n\r\n inject(AppOktaSessionService).sessionState$().subscribe(s => {\r\n // Record the change of session info\r\n this.sessionInfoUpdates(s);\r\n });\r\n }\r\n\r\n /**\r\n * Gets the Http Header options.\r\n * @returns The Http Header options for connecting to the analytics api.\r\n */\r\n public getHttpHeaderOptions(token: string) {\r\n // Create the headers for the request\r\n let headers = new HttpHeaders({\r\n 'Content-Type': 'application/json',\r\n Authorization: 'bearer ' + token,\r\n });\r\n // Return the headers\r\n return { headers: headers };\r\n }\r\n\r\n /**\r\n * Gets a token for the api.\r\n * @returns The newly generated token\r\n */\r\n public getNewAnalyticsToken(): Observable {\r\n // Attempt to get the token details from local storage\r\n var localStorageItem = localStorage.getItem(localStorageApiTokenKey);\r\n if (localStorageItem) {\r\n // We have the token details, check that it has not expired, if it has, we need a new one\r\n let tokenDetails = JSON.parse(localStorageItem) as TokenModel;\r\n let currentTime = new Date();\r\n let tokenExpiry = new Date(tokenDetails.expiryDate);\r\n if (tokenExpiry > currentTime) {\r\n return of(tokenDetails);\r\n }\r\n }\r\n\r\n // Token hasn't been set, or has expired, so get a new token\r\n var loginModel = new AnalyticsLoginModel();\r\n loginModel.id = this.applicationId;\r\n loginModel.apiKey = this.apiKey;\r\n\r\n let authenticationUrl = this.baseApiUrl + this.baseApiVersion + '/Authentication/Authenticate';\r\n // Make the request\r\n return this.http.post(authenticationUrl, loginModel).pipe(\r\n tap((data) => {\r\n localStorage.setItem(localStorageApiTokenKey, JSON.stringify(data));\r\n })\r\n );\r\n }\r\n\r\n /**\r\n * Records the analytics if session info has changed\r\n * @param newSessionInfo The new session info details.\r\n */\r\n public sessionInfoUpdates(newSessionInfo: SessionState): void {\r\n // Update the session info\r\n let originalSessionInfo = { ...this.sessionInfo };\r\n this.sessionInfo = newSessionInfo;\r\n // If the tenant or asset has changed, record in the user analytics, or session hadn't\r\n // previously been set\r\n if (!originalSessionInfo ||\r\n this.sessionInfo.currentTenant !== originalSessionInfo.currentTenant ||\r\n this.sessionInfo.currentAsset !== originalSessionInfo.currentAsset) {\r\n this.recordUserAnalytics(true);\r\n }\r\n }\r\n\r\n /**\r\n * Records the user analytics\r\n */\r\n public recordUserAnalytics(includePageData: boolean, additionalPageData: any = {}): void {\r\n if (!this.sessionInfo.email) return;\r\n\r\n //console.trace('Navigated to: ' + this.router.url);\r\n\r\n let root = this.router.routerState.snapshot.root;\r\n\r\n let pageRoute: string[] = [];\r\n let pageData: any = {};\r\n // Add the asset the user is on by default\r\n if (this.sessionInfo.currentAsset) pageData['asset'] = this.sessionInfo.currentAsset.name;\r\n\r\n try {\r\n while (root) {\r\n if (includePageData) {\r\n // Get the route data\r\n for (const paramMapKey of root.paramMap.keys) {\r\n if (paramMapKey !== 'tenant' && paramMapKey !== 'asset') {\r\n console.trace(paramMapKey + ': ' + root.paramMap.get(paramMapKey));\r\n if (root.paramMap.get(paramMapKey)) pageData[paramMapKey] = root.paramMap.get(paramMapKey);\r\n }\r\n else {\r\n let param = root.paramMap.get(paramMapKey);\r\n if (param) {\r\n let rootParamIndex = pageRoute.findIndex(e => e.indexOf(param ?? '') > -1);\r\n if (rootParamIndex > -1)\r\n pageRoute.splice(rootParamIndex, 1);\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (root.children && root.children.length) {\r\n root = root.children[0];\r\n // Get the url if it is not the app or main portions of the url and there are not params\r\n if (root.url.toString() !== 'main' && root.url.toString() !== '')\r\n pageRoute.push(root.url.toString());\r\n } else {\r\n break;\r\n }\r\n }\r\n } catch (ex: any) {\r\n console.log('Error occurred getting page data: ' + ex.message);\r\n }\r\n\r\n // Add the additional page data to the page data collection\r\n for (var [key, value] of Object.entries(additionalPageData)) {\r\n pageData[key] = value;\r\n }\r\n\r\n // Record the start of the page view\r\n this.startAnalyticsPageView(pageRoute.join(' / '), JSON.stringify(pageData));\r\n }\r\n\r\n /**\r\n * Records the start of the session.\r\n * Will store the Session Id in session storage for future use.\r\n */\r\n public startAnalyticsSession(): void {\r\n if (!this.sessionInfo.email) return;\r\n\r\n // Create the model for passing to the request\r\n let sessionDetails = new StartAnalyticsSessionModel();\r\n sessionDetails.username = this.sessionInfo.email;\r\n // If the session is impersonated, record against the original user\r\n if (this.sessionInfo.originalUserSessionState && this.sessionInfo.originalUserSessionState.email)\r\n sessionDetails.username = this.sessionInfo.originalUserSessionState.email;\r\n\r\n if (this.sessionInfo.currentTenant)\r\n sessionDetails.tenant = this.sessionInfo.currentTenant.name;\r\n sessionDetails.referrer = document.referrer;\r\n\r\n let sessionStartUrl = this.baseApiUrl + this.baseApiVersion + \"/Session/Start\";\r\n // Start the session, and record the response in local storage\r\n this.getNewAnalyticsToken().subscribe(token => {\r\n this.postToAnalyticsService(token.token, sessionStartUrl, sessionDetails)\r\n .subscribe((data: string) => {\r\n // Store the session id in local storage\r\n sessionStorage.setItem(localStorageSessionIdKey, data);\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * Records the end of the session and clears the local storage.\r\n */\r\n public endAnalyticsSession(): void {\r\n // Get the session id\r\n let sessionId = sessionStorage.getItem(localStorageSessionIdKey);\r\n if (sessionId !== null) {\r\n let sessionEndUrl = this.baseApiUrl + this.baseApiVersion + \"/Session/End/\" + sessionId;\r\n // End the session\r\n console.log(\"Ending session in analytics service.\");\r\n this.getNewAnalyticsToken().subscribe(token => {\r\n this.postToAnalyticsService(token.token, sessionEndUrl, null)\r\n .subscribe(() => {\r\n // Remove the item from session storage\r\n sessionStorage.removeItem(localStoragePageViewIdKey);\r\n sessionStorage.removeItem(localStorageSessionIdKey);\r\n });\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Records the start of the page view.\r\n * Will store the returned Session Id and Page View Id in local storage.\r\n * @param pageTitle The title of the page the user is starting to view.\r\n * @param pageData The data passed to the page.\r\n */\r\n public startAnalyticsPageView(pageTitle: string, pageData: string): void {\r\n if (!this.sessionInfo.email)\r\n return;\r\n\r\n // Get the session id\r\n let sessionId = sessionStorage.getItem(localStorageSessionIdKey);\r\n // Get the previous page view id, if it exists\r\n let previousPageViewId = sessionStorage.getItem(localStoragePageViewIdKey);\r\n\r\n // Create the model for passing to the request\r\n let pageViewDetails = new StartAnalyticsPageViewModel();\r\n pageViewDetails.sessionId = sessionId ?? undefined;\r\n pageViewDetails.pageTitle = pageTitle;\r\n pageViewDetails.pageData = pageData;\r\n pageViewDetails.previousPageViewId = previousPageViewId ?? undefined;\r\n pageViewDetails.username = this.sessionInfo.email ?? 'unknown';\r\n // If the session is impersonated, record against the original user\r\n if (this.sessionInfo.originalUserSessionState && this.sessionInfo.originalUserSessionState.email)\r\n pageViewDetails.username = this.sessionInfo.originalUserSessionState.email;\r\n if (this.sessionInfo.currentTenant)\r\n pageViewDetails.tenant = this.sessionInfo.currentTenant.name;\r\n\r\n // Start the page view\r\n let pageViewStartUrl = this.baseApiUrl + this.baseApiVersion + \"/PageView/Start\";\r\n // Start the page view, and record the response in local storage\r\n this.getNewAnalyticsToken().subscribe(token => {\r\n this.postToAnalyticsService(token.token, pageViewStartUrl, pageViewDetails)\r\n .subscribe((data) => {\r\n // Store the session id and page view id in local storage\r\n sessionStorage.setItem(localStorageSessionIdKey, data.sessionId);\r\n sessionStorage.setItem(localStoragePageViewIdKey, data.pageViewId);\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * Posts the data to the analytics service\r\n * @param token The authentication token\r\n * @param url The url to post to\r\n * @param data The data to be posted\r\n * @returns The response\r\n */\r\n public postToAnalyticsService(token: string, url: string, data: any): Observable {\r\n // Post to the analytics service\r\n return this.http.post(url, data, this.getHttpHeaderOptions(token));\r\n }\r\n}\r\n","import { Injectable, Injector } from \"@angular/core\";\r\nimport { map, Observable } from \"rxjs\";\r\nimport { AssetDataTimeModel } from \"src/app/core/models/asset/configuration/asset-data-time.model\";\r\nimport { AssetSettingModel } from \"src/app/core/models/asset/configuration/asset-setting-model\";\r\nimport { OptixSettingModel } from \"src/app/core/models/global/configuration/optix-setting-model\";\r\nimport { ServiceBase } from \"../../service-base\";\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class AssetSettingService extends ServiceBase {\r\n\r\n constructor(injector: Injector) {\r\n super(injector);\r\n }\r\n\r\n /**\r\n * Saves the new asset setting.\r\n */\r\n public createAssetSettingByAssetId(assetId: string, assetSettingModel: AssetSettingModel): Observable {\r\n return this.httpQueue.post(`${this.baseUrl}v1/AssetSetting/CreateAssetSettingWithAssetId/${assetId}`, assetSettingModel);\r\n }\r\n\r\n /**\r\n * Gets all asset settings\r\n * @returns Observable with the asset settings.\r\n */\r\n public getAssetSettingsByAssetId(assetId: string): Observable {\r\n return this.httpQueue.get(`${this.baseUrl}v1/AssetSetting/GetSettingsByAssetId/${assetId}`);\r\n }\r\n\r\n /**\r\n * Gets all asset settings\r\n * @returns Observable with the asset settings.\r\n */\r\n public getAllAssetSettings(assetId: string, clearQueue: boolean = false): Observable {\r\n return this.httpQueue.get(`${this.baseUrl}v1/AssetSetting/GetAllAssetSettings/${assetId}`, true, clearQueue);\r\n }\r\n\r\n /**\r\n * Gets the customised setting of the asset.\r\n * @param settingName The name of the setting to get.\r\n * @returns Observable with the setting details.\r\n */\r\n public getAssetSettingByName(settingName: string): Observable {\r\n return this.httpQueue.get(`${this.baseUrl}v1/AssetSetting/GetAssetSettingByName/${settingName}`);\r\n }\r\n\r\n /**\r\n * Updates the asset settings.\r\n * @param assetId The id of the asset that the setting belongs to.\r\n * @param assetSetting The new setting details.\r\n */\r\n public updateAssetSettingByAssetId(assetId: string, assetSetting: AssetSettingModel) {\r\n return this.httpQueue.post(`${this.baseUrl}v1/AssetSetting/UpdateAssetSettingByAssetId/${assetId}`, assetSetting);\r\n }\r\n\r\n /**\r\n * Deletes the asset setting.\r\n * @returns Observable with the deleted asset setting details.\r\n */\r\n public deleteAssetSettingByAssetId(assetId: string, assetSetting: AssetSettingModel): Observable {\r\n return this.httpQueue.delete(`${this.baseUrl}v1/AssetSetting/DeleteAssetSettingByAssetId/${assetId}/${assetSetting.id}`);\r\n }\r\n\r\n /**\r\n * Restores the asset setting.\r\n * @returns Observable with the restored asset setting details.\r\n */\r\n public restoreAssetSettingByAssetId(assetId: string, assetSetting: AssetSettingModel): Observable {\r\n return this.httpQueue.put(`${this.baseUrl}v1/AssetSetting/RestoreAssetSettingByAssetId/${assetId}/${assetSetting.id}`, '');\r\n }\r\n\r\n /**\r\n * Gets the asset latest data time.\r\n * @returns Observable with the asset data time.\r\n */\r\n public getAssetDataTime(): Observable {\r\n return this.httpQueue.get(`${this.baseUrl}v1/AssetSetting/GetAssetDataTime`)\r\n .pipe(\r\n map((data: AssetDataTimeModel) => {\r\n if (data.assetDataTime)\r\n data.assetDataTime = new Date(data.assetDataTime);\r\n return data;\r\n })\r\n );\r\n }\r\n}","import { Injectable, Injector } from \"@angular/core\";\r\nimport { Observable } from \"rxjs\";\r\nimport { SupportModel } from \"src/app/core/models/global/clients/support.model\";\r\nimport { ServiceBase } from \"../../service-base\";\r\nimport { RequestAccessModel } from \"src/app/core/models/global/clients/request-access.model\";\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class SupportService extends ServiceBase {\r\n\r\n constructor(injector: Injector) {\r\n super(injector);\r\n }\r\n\r\n /**\r\n * Creates the support request.\r\n * @param supportModel The support details.\r\n * @returns Observable with the new tenant.\r\n */\r\n public submitSupportRequest(supportModel: SupportModel): Observable {\r\n let formData = new FormData();\r\n formData.append('subject', supportModel.subject ?? '');\r\n formData.append('supportType', supportModel.supportType ?? '');\r\n formData.append('message', supportModel.message ?? '');\r\n\r\n if (supportModel.attachments) {\r\n\t\t\tfor (var i = 0; i < supportModel.attachments.length; i++) {\r\n\t\t\t\tformData.append('attachments', supportModel.attachments[i]);\r\n\t\t\t}\r\n\t\t}\r\n\r\n return this.httpQueue.post(`${this.baseUrl}v1/Support/SubmitSupportRequest`, formData);\r\n }\r\n\r\n /**\r\n * Creates the access request.\r\n * @param supportModel The support details.\r\n * @returns Observable with the new tenant.\r\n */\r\n public submitAccessRequest(accessRequest: RequestAccessModel): Observable {\r\n return this.httpQueue.post(`${this.baseUrl}v1/Support/SubmitAccessRequest`, accessRequest);\r\n }\r\n}","import { Injectable, Injector } from \"@angular/core\";\r\nimport { Observable } from \"rxjs\";\r\nimport { CreateTenantModel } from \"src/app/core/models/global/clients/create-tenant-model\";\r\nimport { TenantModel } from \"src/app/core/models/global/clients/tenant-model\";\r\nimport { ServiceBase } from \"../../service-base\";\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class TenantService extends ServiceBase {\r\n\r\n constructor(injector: Injector) {\r\n super(injector);\r\n }\r\n\r\n /**\r\n * Gets all tenants\r\n * @returns Observable wit the tenats.\r\n */\r\n public getTenants(): Observable {\r\n return this.httpQueue.get(`${this.baseUrl}v1/tenant/gettenants`);\r\n }\r\n\r\n /**\r\n * Gets the tenant\r\n * @param id The id of the tenant to get\r\n * @returns Observable containing the tenant.\r\n */\r\n public getTenant(id: string): Observable {\r\n return this.httpQueue.get(`${this.baseUrl}v1/tenant/gettenant/${id}`);\r\n }\r\n\r\n /**\r\n * Gets the tenants for the current user.\r\n * @returns Observable with the tenants for the user.\r\n */\r\n public getUsersTenants(): Observable {\r\n return this.httpQueue.get(`${this.baseUrl}v1/tenant/gettenantsforuser`);\r\n }\r\n\r\n /**\r\n * Creates the new tenant.\r\n * @param newTenant The new tenant details.\r\n * @returns Observable with the new tenant.\r\n */\r\n public createTenant(newTenant: CreateTenantModel): Observable {\r\n let formData = new FormData();\r\n formData.append('name', newTenant.name);\r\n formData.append('tenancyName', newTenant.tenancyName);\r\n formData.append('logo', newTenant.logo);\r\n\r\n return this.httpQueue.post(`${this.baseUrl}v1/tenant/createtenant`, formData);\r\n }\r\n \r\n /**\r\n * Updates the tenant.\r\n * @param tenant The updated tenant details.\r\n * @returns Observable with the updated tenant.\r\n */\r\n public updateTenant(tenant: TenantModel): Observable {\r\n let formData = new FormData();\r\n formData.append('id', tenant.id);\r\n formData.append('name', tenant.name);\r\n formData.append('tenancyName', tenant.tenancyName);\r\n formData.append('status', tenant.status.toString());\r\n // If there is a new logo, set it\r\n if (tenant.logoFile) {\r\n formData.append('logoFile', tenant.logoFile);\r\n }\r\n\r\n return this.httpQueue.post(`${this.baseUrl}v1/tenant/updatetenant`, formData);\r\n }\r\n\r\n /**\r\n * Deletes the tenant.\r\n * @param tenant The tenant to be deleted.\r\n * @returns Observable with the deleted tenant details.\r\n */\r\n public deleteTenant(tenant: TenantModel): Observable {\r\n return this.httpQueue.delete(`${this.baseUrl}v1/tenant/deletetenant/${tenant.id}`);\r\n }\r\n\r\n /**\r\n * Restores the tenant.\r\n * @param tenant The tenant to be restored.\r\n * @returns Observable with the restored tenant details.\r\n */\r\n public restoreTenant(tenant: TenantModel): Observable {\r\n return this.httpQueue.put(`${this.baseUrl}v1/tenant/restoretenant/${tenant.id}`, '');\r\n }\r\n}","import { Injectable, Injector } from '@angular/core';\r\nimport { Observable } from 'rxjs';\r\nimport { UserModel } from 'src/app/core/models/global/clients/user-model';\r\nimport { ServiceBase } from '../../service-base';\r\n\r\n@Injectable({\r\n\tprovidedIn: 'root',\r\n})\r\nexport class UserService extends ServiceBase {\r\n\tconstructor(injector: Injector) {\r\n\t\tsuper(injector);\r\n\t}\r\n\r\n\t/**\r\n\t * Creates the new user.\r\n\t * @param newUser The new user details.\r\n\t * @returns Observable with the new user.\r\n\t */\r\n\tpublic createUser(newUser: UserModel): Observable {\r\n\t\treturn this.httpQueue.post(`${this.baseUrl}v1/User/CreateUser`, newUser);\r\n\t}\r\n\r\n\t/**\r\n\t * Creates the new user.\r\n\t * @param tenantId The tenant id\r\n\t * @param newUser The new user details.\r\n\t * @returns Observable with the new user.\r\n\t */\r\n\tpublic createUserByTenantId(tenantId:string, newUser: UserModel): Observable {\r\n\t\treturn this.httpQueue.post(`${this.baseUrl}v1/User/CreateUserByTenantId/${tenantId}`, newUser);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the user based on the email address.\r\n\t * @param newUser The new user details\r\n\t */\r\n\tpublic getUserByEmail(userModel: UserModel): Observable {\r\n\t\treturn this.httpQueue.post(`${this.baseUrl}v1/User/GetUserByEmail`, userModel);\r\n\t}\r\n\r\n\t/**\r\n\t * Updates the user.\r\n\t * @param user The updated user details.\r\n\t * @returns Observable with the updated user.\r\n\t */\r\n\tpublic updateUser(user: UserModel): Observable {\r\n\t\treturn this.httpQueue.post(`${this.baseUrl}v1/User/UpdateUser`, user);\r\n\t}\r\n\r\n\t/**\r\n\t * Updates the user.\r\n\t * @param tenantId The tenant id.\r\n\t * @param user The updated user details.\r\n\t * @returns Observable with the updated user.\r\n\t */\r\n\tpublic updateUserByTenantId(tenantId:string, user: UserModel): Observable {\r\n\t\treturn this.httpQueue.post(`${this.baseUrl}v1/User/UpdateUserByTenantId/${tenantId}`, user);\r\n\t}\r\n\r\n /**\r\n * Deletes the user.\r\n * @param user The user to be deleted.\r\n * @returns Observable with the deleted user details.\r\n */\r\n public deleteUser(user: UserModel): Observable {\r\n return this.httpQueue.delete(`${this.baseUrl}v1/User/DeleteUser/${user.id}`);\r\n }\r\n\r\n /**\r\n * Restores the user.\r\n * @param user The user to be restored.\r\n * @returns Observable with the restored user details.\r\n */\r\n public restoreUser(user: UserModel): Observable {\r\n return this.httpQueue.put(`${this.baseUrl}v1/User/RestoreUser/${user.id}`, '');\r\n }\r\n\r\n /**\r\n * Resets the user's password.\r\n * @param user The user to have the password reset.\r\n * @returns Observable with the updated user details.\r\n */\r\n public resetUserPassword(user: UserModel): Observable {\r\n return this.httpQueue.put(`${this.baseUrl}v1/User/ResetUserPassword/${user.id}`, '');\r\n }\r\n\r\n /**\r\n * Accepts the terms and privacy.\r\n * @returns Observable with the updated user details.\r\n */\r\n public acceptTermsAndPrivacy(): Observable {\r\n return this.httpQueue.put(`${this.baseUrl}v1/User/AcceptTermsAndPrivacy`, '');\r\n }\r\n\r\n /**\r\n * Updates the user's theme.\r\n * @returns Observable with the updated user details.\r\n */\r\n public updateUserTheme(theme: string): Observable {\r\n\t\tlet model = { \"theme\": theme };\r\n return this.httpQueue.post(`${this.baseUrl}v1/User/UpdateUserTheme`, model);\r\n }\r\n}\r\n","import { HttpClient, HttpErrorResponse, HttpResponse } from \"@angular/common/http\";\r\nimport { inject, Injectable } from \"@angular/core\";\r\nimport { share, Subject } from \"rxjs\";\r\nimport { OptixComponentBase } from \"../utils/base-components/optix-component-base\";\r\n\r\nexport class PendingRequest {\r\n constructor(\r\n public url: string,\r\n public method: string,\r\n public data: any,\r\n public subscription: Subject\r\n ) { }\r\n}\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class HttpQueue extends OptixComponentBase {\r\n private httpClient: HttpClient;\r\n private requests$ = new Subject();\r\n private queue: PendingRequest[] = [];\r\n\r\n constructor() {\r\n super();\r\n\r\n this.httpClient = inject(HttpClient);\r\n\r\n this.requests$.subscribe((request) => this.execute(request));\r\n }\r\n\r\n public get(url: string, cancelDuplicates: boolean = true, clearQueue: boolean = false) {\r\n // Clear the queue if required\r\n if (clearQueue)\r\n this.clearQueue();\r\n // Make the new request\r\n return this.addRequestToQueue(url, 'get', null, cancelDuplicates);\r\n }\r\n\r\n public post(url: string, data: any, cancelDuplicates: boolean = true, clearQueue: boolean = false) {\r\n // Clear the queue if required\r\n if (clearQueue)\r\n this.clearQueue();\r\n // Make the new request\r\n return this.addRequestToQueue(url, 'post', data, cancelDuplicates);\r\n }\r\n\r\n public put(url: string, data: any, cancelDuplicates: boolean = true) {\r\n return this.addRequestToQueue(url, 'put', data, cancelDuplicates);\r\n }\r\n\r\n public delete(url: string, cancelDuplicates: boolean = true) {\r\n return this.addRequestToQueue(url, 'delete', null, cancelDuplicates);\r\n }\r\n\r\n private execute(requestData: PendingRequest) {\r\n this.logDebug(this.execute.name, 'executing request', [requestData]);\r\n // Execute the request\r\n switch (requestData.method) {\r\n case 'post':\r\n this.httpClient.post(requestData.url, requestData.data).subscribe({\r\n next: (res) => { this.requestExecuted(requestData, res); },\r\n error: (e) => { this.requestError(requestData, e); }\r\n });\r\n break;\r\n case 'put':\r\n this.httpClient.put(requestData.url, requestData.data).subscribe({\r\n next: (res) => { this.requestExecuted(requestData, res); },\r\n error: (e) => { this.requestError(requestData, e); }\r\n });\r\n break;\r\n case 'delete':\r\n this.httpClient.delete(requestData.url).subscribe({\r\n next: (res) => { this.requestExecuted(requestData, res); },\r\n error: (e) => { this.requestError(requestData, e); }\r\n });\r\n break;\r\n default:\r\n this.httpClient.get(requestData.url).pipe(share()).subscribe({\r\n next: (res) => { this.requestExecuted(requestData, res); },\r\n error: (e) => { this.requestError(requestData, e); }\r\n });\r\n }\r\n }\r\n\r\n private requestExecuted(requestData: PendingRequest, res: any) {\r\n const sub = requestData.subscription;\r\n \r\n if (sub) {\r\n sub.next(res);\r\n sub.complete();\r\n }\r\n \r\n this.queue.shift();\r\n this.startNextRequest();\r\n }\r\n\r\n private requestError(requestData: PendingRequest, e: HttpErrorResponse) {\r\n let responseError: any = e;\r\n // For unauthorised or internal server errors, replace the message with more user friendly messages\r\n if (e.status === 403) {\r\n responseError = {\r\n error: {\r\n title: 'You are not authorised to perform this action. Please contact your administrator if you think you should have access.'\r\n },\r\n headers: e.headers,\r\n status: e.status\r\n };\r\n }\r\n if (e.status === 408) {\r\n responseError = {\r\n error: {\r\n title: 'The server timed out retrieving data. Please wait a moment, and try again by using the Update button. If the problem persists, please contact support.',\r\n },\r\n headers: e.headers,\r\n status: e.status,\r\n };\r\n }\r\n if (e.status === 500) {\r\n responseError = {\r\n error: {\r\n title: `We're sorry an unexpected error occurred and your request could not be processed. The error has been recorded and the team are on it.`,\r\n },\r\n headers: e.headers,\r\n status: e.status,\r\n };\r\n }\r\n\r\n // Update the request\r\n const sub = requestData.subscription;\r\n sub.error(responseError);\r\n sub.complete();\r\n this.queue.shift();\r\n this.startNextRequest();\r\n }\r\n\r\n public clearQueue() : void {\r\n // Complete each of the subscriptions and then clear the queue\r\n for(var i = 0; i < this.queue.length; i++) {\r\n this.queue[i].subscription.complete();\r\n }\r\n // Clear all requests from the http queue\r\n this.queue = [];\r\n }\r\n\r\n private addRequestToQueue(url: string, method: string, data: any, cancelDuplicates: boolean) {\r\n const sub = new Subject();\r\n const request = new PendingRequest(url, method, data, sub);\r\n\r\n // Check if the same request is already in the queue\r\n var existingRequest = this.queue.find(e => e.url === url && e.method === method && JSON.stringify(e.data) === JSON.stringify(data));\r\n if (existingRequest && cancelDuplicates) {\r\n console.log('found existing request', request, existingRequest);\r\n // If the request is not a position 0 (ie getting executed), complete it and remove it so it doesn't get executed\r\n var index = this.queue.findIndex(e => e.url === url && e.method === method && JSON.stringify(e.data) === JSON.stringify(data));\r\n if (index > 0) {\r\n existingRequest.subscription.complete();\r\n this.queue.splice(index, 1);\r\n }\r\n }\r\n\r\n this.queue.push(request);\r\n // If there is only 1 item in the queue, execute it\r\n if (this.queue.length === 1) {\r\n this.startNextRequest();\r\n }\r\n return sub;\r\n }\r\n\r\n private startNextRequest() {\r\n // get next request, if any.\r\n if (this.queue.length > 0) {\r\n this.execute(this.queue[0]);\r\n }\r\n }\r\n}","import { HttpClient } from \"@angular/common/http\";\r\nimport { inject, Injector } from \"@angular/core\";\r\nimport { environment } from \"src/environments/environment\";\r\nimport { OptixComponentBase } from \"../utils/base-components/optix-component-base\";\r\nimport { HttpQueue } from \"./http-queue.service\";\r\n\r\nexport abstract class ServiceBase extends OptixComponentBase {\r\n\r\n protected httpClient: HttpClient;\r\n protected httpQueue: HttpQueue;\r\n protected baseUrl!: string;\r\n\r\n constructor(_injector: Injector) { \r\n super();\r\n\r\n this.httpClient = _injector.get(HttpClient);\r\n this.httpQueue = inject(HttpQueue);\r\n this.baseUrl = environment.optixApi.baseUrl;\r\n }\r\n}","import { FlareStackModel } from \"../asset/emissions/flaring/flare-stack-model\";\r\nimport { UserTypes } from \"../constants/permissions/user-types-enum\";\r\nimport { TenantModel } from \"../global/clients/tenant-model\";\r\nimport { AssetModel } from \"../tenant/location/asset-model\";\r\n\r\nexport class SessionState {\r\n /**\r\n * Is the user authenticated\r\n */\r\n public isAuthenticated: boolean = false;\r\n /**\r\n * Has the session been initialised\r\n */\r\n public isSessionInitialised: boolean = false;\r\n /**\r\n * The tenants that the user has access to.\r\n */\r\n public tenants: TenantModel[];\r\n /**\r\n * The tenant that the user is currently accessing.\r\n */\r\n public currentTenant?: TenantModel;\r\n /**\r\n * The assets that the user has access to in the current tenant\r\n */\r\n public assets: AssetModel[];\r\n /**\r\n * The asset that the user is currently accessing\r\n */\r\n public currentAsset?: AssetModel;\r\n /**\r\n * The identity id of the logged in user\r\n */\r\n public identityId!: string;\r\n /**\r\n * The b2c id of the logged in user\r\n */\r\n public b2cId!: string;\r\n /**\r\n * The id of the logged in user\r\n */\r\n public userId?: string;\r\n /**\r\n * The email address of the logged in user\r\n */\r\n public email?: string;\r\n /**\r\n * The firstname of the logged in user\r\n */\r\n public firstname?: string;\r\n /**\r\n * The lastname of the logged in user\r\n */\r\n public lastname?: string;\r\n /**\r\n * Has the user accepted the privacy and terms etc\r\n */\r\n public hasAcceptedPrivacy: boolean = false;\r\n /**\r\n * The type of user\r\n */\r\n public userType: UserTypes = UserTypes.None;\r\n /**\r\n * The roles of the logged in user\r\n */\r\n public roles: string[];\r\n /**\r\n * The authorization JWT\r\n */\r\n public jsonWebToken: string;\r\n /**\r\n * The expiry for the token\r\n */\r\n public tokenExpiry: Date;\r\n /**\r\n * The refresh token\r\n */\r\n public refreshToken: string;\r\n /**\r\n * The currently selected flare stack\r\n */\r\n public currentFlareStack?: FlareStackModel;\r\n\r\n /**\r\n * The url that the admin impersonating the user came from\r\n */\r\n public impersonationAdminUrl?: string;\r\n\r\n /**\r\n * The original session state of the admin impersonating the user\r\n */\r\n public originalUserSessionState?: SessionState;\r\n\r\n /**\r\n * The theme of the application\r\n */\r\n public theme: string = 'default';\r\n \r\n constructor() {\r\n this.tenants = [];\r\n this.assets = [];\r\n this.roles = [];\r\n this.jsonWebToken = '';\r\n this.tokenExpiry = new Date();\r\n this.refreshToken = '';\r\n }\r\n}","import { Injectable } from \"@angular/core\";\r\nimport { OptixComponentBase } from \"../../utils/base-components/optix-component-base\";\r\nimport { ActivatedRouteSnapshot, RouterStateSnapshot } from \"@angular/router\";\r\nimport { environment } from \"src/environments/environment\";\r\nimport { SessionState } from \"../../models/session/session-state.model\";\r\nimport { TokenModel } from \"../../models/authentication/token.model\";\r\nimport { TenantModel } from \"../../models/global/clients/tenant-model\";\r\nimport { AssetModel } from \"../../models/tenant/location/asset-model\";\r\nimport { JwtHelperService } from \"@auth0/angular-jwt\";\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class AppOktaSessionHelperService extends OptixComponentBase {\r\n\r\n /**\r\n * Default constructor\r\n * @param _oktaStateService The okta state service\r\n * @param oktaAuth The okta authentication service\r\n */\r\n constructor() {\r\n super();\r\n this.logDebug(this.constructor.name, 'App Okta Session Helper Service Loaded!');\r\n }\r\n\r\n /**\r\n * Checks the url to see if the tenant has been set in it\r\n * @param route The route to check\r\n */\r\n public getTenantFromUrl(route: ActivatedRouteSnapshot): string {\r\n this.logDebug(this.getTenantFromUrl.name, 'started tenant url check', [route]);\r\n\r\n let tenant: string | null = null;\r\n\r\n // Check the route params initially\r\n tenant = route.paramMap.get('tenant');\r\n if (!tenant && route.children.length > 0) {\r\n tenant = route.children[0].paramMap.get('tenant');\r\n }\r\n\r\n // If the route param doesn't exist, check the path\r\n if (!tenant) {\r\n this.logDebug(this.getTenantFromUrl.name, 'tenant not found in route params, so checking path');\r\n let paths = window.location.pathname.split('/');\r\n // Find the main path and then take the next part as the tenant\r\n let mainPathIndex = paths.findIndex(e => e === 'main');\r\n if (mainPathIndex > -1) {\r\n if (paths[mainPathIndex + 1] !== 'tenant-selector')\r\n tenant = paths[mainPathIndex + 1];\r\n }\r\n }\r\n\r\n // If the route param doesn't exist, check the domain\r\n if (!tenant) {\r\n this.logDebug(this.getTenantFromUrl.name, 'tenant not found in route params, so checking subdomain');\r\n let hostsplit = window.location.hostname.split('.');\r\n // If there is only 1 part, ie. localhost, just return it, otherwise get the subdomain\r\n if (hostsplit.length === 1)\r\n tenant = hostsplit[0];\r\n else\r\n tenant = window.location.hostname.split('.').slice(0, -2).join('.');\r\n }\r\n\r\n // Switch the tenant name if its just localhost\r\n if (!tenant || environment.optixSubDomains.includes(tenant.toLowerCase())) {\r\n tenant = 'optix';\r\n }\r\n\r\n this.logDebug(this.getTenantFromUrl.name, 'ended tenant url check', [tenant]);\r\n return tenant;\r\n }\r\n\r\n /**\r\n * Checks the url to see if the asset has been set in it\r\n * @param route The route to check\r\n */\r\n public getAssetFromUrl(route: ActivatedRouteSnapshot): string | undefined {\r\n this.logDebug(this.getAssetFromUrl.name, 'started asset url check', [route]);\r\n\r\n let asset: string | null = null;\r\n // Check the route params initially\r\n asset = route.paramMap.get('asset');\r\n if (!asset && route.children.length > 0) {\r\n asset = route.children[0].paramMap.get('asset');\r\n }\r\n\r\n this.logDebug(this.getAssetFromUrl.name, 'ended asset url check', [asset]);\r\n return asset ?? undefined;\r\n }\r\n\r\n /**\r\n * Checks if the requested route is for the tenant selector page\r\n * @param route The route to check\r\n */\r\n public isRequestedRouteForTenantSelector(route: ActivatedRouteSnapshot): boolean {\r\n this.logDebug(this.isRequestedRouteForTenantSelector.name, 'checking if route is for tenant selector', [route.pathFromRoot]);\r\n // Check if the route is for the root module\r\n return route.pathFromRoot.findIndex(e => e.routeConfig?.path === 'tenant-selector') > -1;\r\n }\r\n\r\n /**\r\n * Checks if the requested route is for a root admin page\r\n * @param route The route to check\r\n */\r\n public isRequestedRouteForRootAdmin(route: ActivatedRouteSnapshot): boolean {\r\n this.logDebug(this.isRequestedRouteForRootAdmin.name, 'checking if route is for root admin', [route.pathFromRoot]);\r\n // Check if the route is for the root module\r\n return route.pathFromRoot.findIndex(e => e.routeConfig?.path === 'root') > -1;\r\n }\r\n\r\n /**\r\n * Checks if the requested route is for a support page\r\n */\r\n public isRequestedRouteForSupport(route: ActivatedRouteSnapshot): boolean {\r\n this.logDebug(this.isRequestedRouteForSupport.name, 'checking if route is for support', [route]);\r\n // Check if the route is for the root module\r\n return route.pathFromRoot.findIndex(e => e.routeConfig?.path === 'support') > -1;\r\n }\r\n\r\n /**\r\n * Checks if the requested route is for an admin page\r\n * @param route The route to check\r\n */\r\n public isRequestedRouteForAdmin(state: RouterStateSnapshot): boolean {\r\n this.logDebug(this.isRequestedRouteForAdmin.name, 'checking if route is for admin', [state]);\r\n // Check if the route is for the root module\r\n //return route.pathFromRoot.findIndex(e => e.routeConfig?.path === 'admin') > -1;\r\n return state.url.includes('admin');\r\n }\r\n\r\n /**\r\n * Checks if the requested route is for the dashboard page\r\n * @param route The route to check\r\n */\r\n public isRequestedRouteForDashboard(state: RouterStateSnapshot): boolean {\r\n this.logDebug(this.isRequestedRouteForDashboard.name, 'checking if route is for dashboard', [state]);\r\n // Check if the route is for the root module\r\n //return route.pathFromRoot.findIndex(e => e.routeConfig?.path === 'dashboard') > -1;\r\n return state.url.includes('dashboard');\r\n }\r\n\r\n /**\r\n * Creates a new session state\r\n * @param isAuthenticated Is the user authenticated\r\n * @param oktaId The okta id of the user\r\n * @param b2cId The b2c id of the user\r\n * @returns A new session state\r\n */\r\n public createSessionState(isAuthenticated: boolean, oktaId: string, b2cId: string, email: string): SessionState {\r\n // Create a new session state\r\n let sessionState: SessionState = new SessionState();\r\n sessionState.isAuthenticated = isAuthenticated;\r\n sessionState.identityId = oktaId;\r\n sessionState.b2cId = b2cId;\r\n sessionState.email = email;\r\n sessionState.hasAcceptedPrivacy = true;\r\n // Return the session state\r\n return sessionState;\r\n }\r\n\r\n /**\r\n * Updates the session details from the token\r\n * @param tokenModel The token model details\r\n */\r\n public updateSessionFromToken(sessionState: SessionState, tokenModel: TokenModel, tenant: TenantModel | undefined, asset: AssetModel | undefined): SessionState {\r\n this.logDebug(this.updateSessionFromToken.name, 'Entering session update from token');\r\n // Decode the token\r\n let jwtHelper = new JwtHelperService();\r\n\t\tlet decodedToken = jwtHelper.decodeToken(tokenModel.token);\r\n // Get the properties from the token\r\n let userId = decodedToken['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier'];\r\n let email = decodedToken['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress'];\r\n let firstname = decodedToken['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname'];\r\n let surname = decodedToken['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname'];\r\n let hasAcceptedPrivacy = decodedToken['Opex.Optix.HasAcceptedPrivacy'];\r\n let userType = decodedToken['Opex.Optix.UserType'];\r\n let roles = decodedToken['http://schemas.microsoft.com/ws/2008/06/identity/claims/role'];\r\n let savedTheme = decodedToken['Opex.Optix.Theme'];\r\n // Update the session\r\n sessionState.currentTenant = tenant;\r\n sessionState.currentAsset = asset;\r\n sessionState.userId = userId;\r\n sessionState.email = email;\r\n sessionState.firstname = firstname;\r\n sessionState.lastname = surname;\r\n sessionState.hasAcceptedPrivacy = (hasAcceptedPrivacy.toLowerCase() === \"true\");\r\n sessionState.userType = userType;\r\n sessionState.theme = savedTheme;\r\n sessionState.roles = roles;\r\n sessionState.jsonWebToken = tokenModel.token;\r\n sessionState.tokenExpiry = new Date(tokenModel.expiryDate);\r\n sessionState.refreshToken = tokenModel.refreshToken;\r\n\r\n this.logDebug(this.updateSessionFromToken.name, 'Exiting session update from token', [sessionState]);\r\n return sessionState;\r\n }\r\n\r\n /**\r\n * Gets the pathname from the window\r\n */\r\n public getPathname(): string {\r\n return window.location.pathname;\r\n }\r\n}","import { Inject, Injectable, inject } from \"@angular/core\";\r\nimport { BehaviorSubject, Observable, lastValueFrom } from \"rxjs\";\r\nimport OktaAuth, { IDToken } from \"@okta/okta-auth-js\";\r\nimport { OKTA_AUTH, OktaAuthStateService } from \"@okta/okta-angular\";\r\nimport { OptixComponentBase } from \"../../utils/base-components/optix-component-base\";\r\nimport { AssetSettingService } from \"../asset/configuration/asset-setting.service\";\r\nimport { AssetUserService } from \"../tenant/permissions/asset-user/asset-user.service\";\r\nimport { SessionTokenService } from \"./token/session-token.service\";\r\nimport { SessionState } from \"../../models/session/session-state.model\";\r\nimport { ActivatedRouteSnapshot, Router, RouterStateSnapshot } from \"@angular/router\";\r\nimport { AppOktaSessionHelperService } from \"./app-okta-session-helper.service\";\r\nimport { TenantService } from \"../global/clients/tenant.service\";\r\nimport { TenantModel } from \"../../models/global/clients/tenant-model\";\r\nimport { FlareStackModel } from \"../../models/asset/emissions/flaring/flare-stack-model\";\r\nimport { AssetModel } from \"../../models/tenant/location/asset-model\";\r\nimport { TokenModel } from \"../../models/authentication/token.model\";\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class AppOktaSessionService extends OptixComponentBase {\r\n\r\n private tokenService: SessionTokenService = inject(SessionTokenService);\r\n private tenantService: TenantService = inject(TenantService);\r\n private assetUserService: AssetUserService = inject(AssetUserService);\r\n private assetSettingService: AssetSettingService = inject(AssetSettingService);\r\n private appOktaSessionHelperService: AppOktaSessionHelperService = inject(AppOktaSessionHelperService);\r\n private router: Router = inject(Router);\r\n\r\n /**\r\n * The current state of the session\r\n */\r\n private readonly _sessionState = new BehaviorSubject(new SessionState());\r\n\r\n /**\r\n * Gets the current value of the session state\r\n * @returns The session state current value\r\n */\r\n public sessionState = (): SessionState => this._sessionState.getValue();\r\n\r\n /**\r\n * Gets the session state observable\r\n * @returns The session state observable\r\n */\r\n public sessionState$ = (): Observable => this._sessionState.asObservable();\r\n\r\n public requestedTenant: string = '';\r\n public requestedAsset: string | undefined = '';\r\n\r\n /**\r\n * Default constructor\r\n * @param _oktaStateService The okta state service\r\n * @param oktaAuth The okta authentication service\r\n */\r\n constructor(private _oktaStateService: OktaAuthStateService, @Inject(OKTA_AUTH) public oktaAuth: OktaAuth) {\r\n super();\r\n this.logDebug(this.constructor.name, 'App Okta Session Service Loaded!');\r\n }\r\n\r\n /**\r\n * Initialises the session\r\n * @param route The route to initialise the session for\r\n */\r\n public async init(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise {\r\n this.logDebug(this.init.name, 'OKTA Session init started');\r\n // Get the tenant and asset from the url\r\n\t\tvar tenant = this.appOktaSessionHelperService.getTenantFromUrl(route);\r\n this.requestedTenant = tenant;\r\n var asset = this.appOktaSessionHelperService.getAssetFromUrl(route);\r\n this.requestedAsset = asset;\r\n // Get the session state\r\n var sessionState: SessionState = this.sessionState();\r\n if (sessionState.isSessionInitialised) {\r\n\t\t\tthis.logDebug(this.init.name, 'Session already initialised and in progress');\r\n // If there is a url present, if not, ignore as it will have probably come from an OKTA token refresh\r\n if (route.url.length === 0) {\r\n this.logDebug(this.init.name, 'No URL present, ignoring');\r\n return;\r\n }\r\n // Check if the tenant or asset has changed\r\n if ((sessionState.currentTenant?.tenancyName === tenant) && (sessionState.currentAsset?.name === asset)) {\r\n this.logDebug(this.init.name, 'Session already initialised - tenant and asset not changed');\r\n return;\r\n }\r\n\r\n // If the asset has changed, just refresh the asset permissions\r\n if (sessionState.currentAsset?.name !== asset) {\r\n this.logDebug(this.init.name, 'Session already initialised - asset has been changed');\r\n //return this.initSessionForNewAsset(sessionState, route, tenant);\r\n }\r\n\t\t}\r\n // Initialise the session\r\n try {\r\n await this.initialiseSession(route, state, tenant, asset, sessionState);\r\n }\r\n catch(e) {\r\n this.logError(this.init.name, 'Error initialising session', [e]);\r\n }\r\n this.logDebug(this.init.name, 'OKTA Session init complete');\r\n }\r\n\r\n /**\r\n * Initialises the session\r\n * @param sessionState The current session state\r\n * @param route The route to initialise the session for\r\n * @param tenant The tenant to initialise the session for\r\n * @param asset The asset to initialise the session for\r\n */\r\n public async initialiseSession(route: ActivatedRouteSnapshot, state: RouterStateSnapshot, tenant: string, asset: string | undefined, sessionState: SessionState | undefined): Promise {\r\n this.logDebug(this.initialiseSession.name, 'Initialising session');\r\n let currentTenant: TenantModel | undefined = undefined;\r\n let currentAsset: AssetModel | undefined = undefined;\r\n // If the session state is not set, initialise a new session state\r\n if (!sessionState || !sessionState.isSessionInitialised) {\r\n sessionState = await this.initialiseSessionState();\r\n \r\n // Create the session token\r\n let token = await this.tokenService.generateAuthToken(sessionState.identityId, sessionState.b2cId, sessionState.email, tenant, undefined);\r\n // Update the session state with the token\r\n sessionState = this.appOktaSessionHelperService.updateSessionFromToken(sessionState, token, undefined, undefined);\r\n // Get the tenants for the user\r\n sessionState.tenants = await lastValueFrom(this.tenantService.getUsersTenants());\r\n this._sessionState.next(sessionState);\r\n }\r\n // Validate the tenant access\r\n currentTenant = this.validateTenantAccess(sessionState, tenant, route);\r\n\r\n // If the user has access to the tenant, select the tenant and get the assets\r\n if (currentTenant) {\r\n // Select the tenant\r\n await this.selectTenant(currentTenant);\r\n // Validate the asset access\r\n if (!this.appOktaSessionHelperService.isRequestedRouteForRootAdmin(route)) {\r\n currentAsset = this.validateAssetAccess(sessionState, asset);\r\n }\r\n }\r\n\r\n // If the user has access to the asset, set the asset\r\n if (currentAsset) {\r\n await this.selectAsset(currentAsset);\r\n }\r\n\r\n // Store the updated session state\r\n sessionState = this.sessionState();\r\n sessionState.isSessionInitialised = true;\r\n this._sessionState.next(sessionState);\r\n this.logDebug(this.initialiseSession.name, 'Session initialised');\r\n // Redirect the user if required\r\n this.redirectUser(route, state);\r\n }\r\n\r\n /**\r\n * Initialises the session state\r\n * @returns The session state\r\n */\r\n public async initialiseSessionState(): Promise {\r\n this.logDebug(this.initialiseSessionState.name, 'Initialising session state');\r\n\r\n // Get the claims and find the identity id claims\r\n let claims: any[] = await this.getClaims();\r\n let oktaId = claims.find(c => c.name === 'sub')?.value;\r\n let b2cId = claims.find(c => c.name === 'b2c')?.value;\r\n let email = claims.find(c => c.name === 'email')?.value;\r\n let name = claims.find(c => c.name === 'name')?.value;\r\n // Create a new session state\r\n let sessionState: SessionState = this.appOktaSessionHelperService.createSessionState(true, oktaId, b2cId, email);\r\n // If the name was found, split it into first and last name\r\n if (name) {\r\n let names = name.split(' ');\r\n sessionState.firstname = names[0];\r\n sessionState.lastname = names[1];\r\n }\r\n // Set the session state\r\n this._sessionState.next(sessionState);\r\n \r\n this.logDebug(this.initialiseSessionState.name, 'Session state initialised');\r\n return sessionState;\r\n }\r\n \r\n /**\r\n * Gets the claims from the Okta token\r\n * @returns Collection of claims from the Okta token\r\n */\r\n public async getClaims(): Promise {\r\n const idToken: IDToken = await this.oktaAuth.tokenManager.get('idToken') as IDToken;\r\n return Object.entries(idToken.claims).map(entry => ({ name: entry[0], value: entry[1] }));\r\n }\r\n\r\n /**\r\n * Logs the user out.\r\n * @param postLogoutUri The url to redirect the user to after logout\r\n */\r\n public async logout(): Promise {\r\n // Clear the session state\r\n this._sessionState.next(new SessionState());\r\n this._sessionState.complete();\r\n // Sign the user out\r\n this.oktaAuth.signOut();\r\n }\r\n\r\n /**\r\n * Validates the users access to the application and tenant\r\n */\r\n public validateTenantAccess(sessionState: SessionState, currentTenant: string, route: ActivatedRouteSnapshot): TenantModel | undefined {\r\n this.logDebug(this.validateTenantAccess.name, 'started validating tenant access');\r\n \r\n // If the user doesn't have any tenants, redirect them to unauthorised\r\n if (sessionState.tenants.length === 0) {\r\n this.logDebug(this.validateTenantAccess.name, 'user is not authorised to access any tenants');\r\n return undefined;\r\n }\r\n\r\n let authorisedTenant = sessionState.tenants.find(x => x.tenancyName.toLowerCase() === currentTenant.toLowerCase());\r\n if (authorisedTenant) {\r\n this.logDebug(this.validateTenantAccess.name, 'user authorised to access this tenant', [currentTenant]);\r\n return authorisedTenant;\r\n }\r\n \r\n // If the current route being requested is just to the root of the application\r\n if (route.url.length === 0) {\r\n this.logDebug(this.validateTenantAccess.name, 'application root requested');\r\n // there are multiple tenants, take them to the tenant selection screen since they are just accessing the root\r\n if (sessionState.tenants.length > 1) {\r\n this.logDebug(this.validateTenantAccess.name, 'user has multiple tenants, present selector');\r\n }\r\n else {\r\n this.logDebug(this.validateTenantAccess.name, 'user has only got access to a single tenant, set it as selected');\r\n return sessionState.tenants[0];\r\n }\r\n }\r\n \r\n return undefined;\r\n }\r\n\r\n /**\r\n * Validates the users access to the asset\r\n * @param assets The assets that the user has access to.\r\n */\r\n public validateAssetAccess(sessionState: SessionState, routeAsset: string | undefined): AssetModel | undefined {\r\n this.logDebug(this.validateAssetAccess.name, 'started validating asset access');\r\n // If the user doesn't have access to assets, take them to the no asset associations\r\n if (sessionState.assets.length === 0) {\r\n this.logDebug(this.validateAssetAccess.name, 'user is not authorised to access any assets');\r\n return undefined;\r\n }\r\n\r\n // Check if the asset is in the url\r\n if (!routeAsset) {\r\n return undefined;\r\n }\r\n\r\n let authorisedAsset = sessionState.assets.find(x => x.name.toLowerCase() === routeAsset?.toLowerCase());\r\n if (authorisedAsset === undefined) {\r\n this.logDebug(this.validateAssetAccess.name, 'user is not authorised to access this asset', [routeAsset]);\r\n }\r\n\r\n // Return the authorised asset\r\n return authorisedAsset;\r\n }\r\n\r\n public redirectUser(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): void {\r\n this.logDebug(this.redirectUser.name, 'redirecting user if required', [route]);\r\n let sessionState = this.sessionState();\r\n // If there are no tenants, send to unauthorised\r\n if (sessionState.tenants.length === 0) {\r\n this.router.navigate(['unauthorised']);\r\n return;\r\n }\r\n // User has access to at least 1 tenant\r\n if (sessionState.currentTenant === undefined) {\r\n // Tenant has not been found, if they just went to the root of the application and have multiple tenants, direct the user to the tenant selector\r\n if (route.url.length === 0 && sessionState.tenants.length > 1) {\r\n this.router.navigate(['main', 'tenant-selector']);\r\n return;\r\n }\r\n // If the user is already being directed to the tenant selector, do not redirect them\r\n if (route.url.length === 1 && route.url[0].path === 'tenant-selector')\r\n return;\r\n\r\n // The user has attempted to go to a specific tenant, and/or has access to only 1 tenant, but that is not the tenant they are attempting to access\r\n this.router.navigate(['unauthorised']);\r\n return;\r\n }\r\n // If the user is attempting to access an admin page, check the admin access\r\n if (this.appOktaSessionHelperService.isRequestedRouteForRootAdmin(route))\r\n return;\r\n\r\n if (this.appOktaSessionHelperService.isRequestedRouteForSupport(route))\r\n return;\r\n\r\n // Check if the user is attempting to access the tenant selector\r\n if (this.appOktaSessionHelperService.isRequestedRouteForTenantSelector(route))\r\n return;\r\n\r\n // If the user is not attempting to get to an admin page or dashboard, check the asset access\r\n if ((!this.appOktaSessionHelperService.isRequestedRouteForAdmin(state) && !this.appOktaSessionHelperService.isRequestedRouteForDashboard(state)) || route.url.length === 0) {\r\n // If the user has no assets, take the user to no asset associations\r\n if (sessionState.assets.length === 0) {\r\n this.router.navigate(['main', sessionState.currentTenant.tenancyName, 'noassets']);\r\n return;\r\n }\r\n // If the current asset cannot be found in the url, direct the user to the asset dashboard\r\n if (sessionState.currentAsset === undefined) {\r\n this.router.navigate(['main', sessionState.currentTenant.tenancyName, 'dashboard']);\r\n return;\r\n }\r\n }\r\n this.logDebug(this.redirectUser.name, 'No redirecting required');\r\n }\r\n\r\n /**\r\n * Updates the session details from the token\r\n * @param tokenModel The token model details\r\n */\r\n public updateSessionFromNewToken(tokenModel: TokenModel, tenant: TenantModel | undefined, asset: AssetModel | undefined) {\r\n this.logDebug(this.updateSessionFromNewToken.name, 'Entering session update from token');\r\n let sessionState = this.sessionState();\r\n // Update the session state with the new token\r\n sessionState = this.appOktaSessionHelperService.updateSessionFromToken(sessionState, tokenModel, tenant, asset);\r\n this._sessionState.next(sessionState);\r\n this.logDebug(this.updateSessionFromNewToken.name, 'Exiting session update from token', [sessionState]);\r\n }\r\n\r\n /**\r\n * Updates the session to be an impersonated session\r\n * @param impersonatedUserSession The impersonated user session details\r\n */\r\n public initialiseImpersonationSession(impersonatedUserSession: SessionState) {\r\n this.logDebug(this.initialiseImpersonationSession.name, 'initialising impersonated session', [impersonatedUserSession]);\r\n this._sessionState.next(impersonatedUserSession);\r\n this.logDebug(this.initialiseImpersonationSession.name, 'initialised impersonated session', [impersonatedUserSession]);\r\n }\r\n\r\n /**\r\n * Sets the selected tenant and loads the assets for the tenant\r\n * @param tenant The selected tenant\r\n */\r\n public async selectTenant(tenant: TenantModel): Promise {\r\n this.logDebug(this.selectTenant.name, 'Selecting tenant', [tenant]);\r\n let sessionState = this.sessionState(); \r\n // Get a new token for the asset\r\n var token = await this.tokenService.generateAuthToken(sessionState.identityId, sessionState.b2cId, sessionState.email, tenant.tenancyName, undefined);\r\n // Update the session state with the token\r\n sessionState = this.appOktaSessionHelperService.updateSessionFromToken(sessionState, token, tenant, undefined);\r\n this._sessionState.next(sessionState);\r\n // Get the assets for the tenant\r\n var assets = await lastValueFrom(this.assetUserService.getUsersAssets());\r\n this.updateAssets(assets);\r\n // Return the assets\r\n return assets;\r\n }\r\n\r\n /**\r\n * Sets the tenants that the user has access to\r\n * @param tenants the tenants that the user has access to\r\n */\r\n public updateTenants(tenants: TenantModel[]): void {\r\n this.logDebug(this.updateTenants.name, 'Updating tenants', [tenants]);\r\n let sessionState = this.sessionState();\r\n sessionState.tenants = tenants;\r\n this._sessionState.next(sessionState);\r\n }\r\n\r\n /**\r\n * Sets the assets that the user has access to\r\n * @param assets the assets that the user has access to\r\n */\r\n public updateAssets(assets: AssetModel[]): void {\r\n this.logDebug(this.updateAssets.name, 'Updating assets', [assets]);\r\n let sessionState = this.sessionState();\r\n sessionState.assets = assets.filter(e => e.userAccessible);\r\n this._sessionState.next(sessionState);\r\n }\r\n\r\n /**\r\n * Sets the selected asset\r\n * @param asset The selected asset\r\n */\r\n public async selectAsset(asset: AssetModel, clearQueue: boolean = false): Promise {\r\n this.logDebug(this.selectAsset.name, 'Selecting asset', [asset]);\r\n let sessionState = this.sessionState(); \r\n // Get the asset settings a new token with the users permissions for the asset\r\n var settings = await lastValueFrom(this.assetSettingService.getAllAssetSettings(asset.id, clearQueue));\r\n asset.assetSettingModels = settings;\r\n // Get a new token for the asset\r\n var token = await this.tokenService.generateAuthToken(sessionState.identityId, sessionState.b2cId, sessionState.email, sessionState.currentTenant == null ? '' : sessionState.currentTenant.tenancyName, asset.id);\r\n // Update the session state with the token\r\n sessionState = this.appOktaSessionHelperService.updateSessionFromToken(sessionState, token, sessionState.currentTenant, asset);\r\n this._sessionState.next(sessionState);\r\n }\r\n\r\n /**\r\n * Sets the current flare stack\r\n * @param currentFlareStack The flare stack selected\r\n */\r\n public setCurrentFlareStack(currentFlareStack: FlareStackModel): void {\r\n this.logDebug(this.setCurrentFlareStack.name, 'Setting current flare stack', [currentFlareStack]);\r\n let sessionState = this.sessionState();\r\n sessionState.currentFlareStack = currentFlareStack;\r\n this._sessionState.next(sessionState);\r\n }\r\n\r\n /**\r\n * Sets the acceptance of the terms and privacy\r\n */\r\n public setAcceptTermsAndPrivacy(): void {\r\n this.logDebug(this.setAcceptTermsAndPrivacy.name, 'Setting terms and privacy accepted');\r\n let sessionState = this.sessionState();\r\n sessionState.hasAcceptedPrivacy = true;\r\n this._sessionState.next(sessionState);\r\n }\r\n\r\n /**\r\n * Sets the theme in the session\r\n */\r\n public setTheme(newTheme: string): void {\r\n this.logDebug(this.setTheme.name, 'Setting new theme');\r\n let sessionState = this.sessionState();\r\n sessionState.theme = newTheme;\r\n this._sessionState.next(sessionState);\r\n }\r\n}","import { inject, Injectable, Injector } from \"@angular/core\";\r\nimport { Router } from \"@angular/router\";\r\nimport { lastValueFrom, map, Observable } from \"rxjs\";\r\nimport { SessionState } from \"../../models/session/session-state.model\";\r\nimport { ServiceBase } from \"../service-base\";\r\nimport { AppOktaSessionService } from \"./app-okta-session.service\";\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class ImpersonationService extends ServiceBase {\r\n\r\n private router: Router;\r\n private appOktaSessionService: AppOktaSessionService = inject(AppOktaSessionService);\r\n\r\n constructor(injector: Injector) {\r\n super(injector);\r\n // Initialise the services\r\n this.router = inject(Router);\r\n }\r\n\r\n /**\r\n * Initialises the user impersonation session\r\n * @param userId The Id of the user to be impersonated\r\n */\r\n public async startImpersonationSession(userId: string, tenantId: string): Promise {\r\n this.logDebug(this.startImpersonationSession.name, 'starting impersonation', [userId, tenantId]);\r\n // Get the current session\r\n let currentSession = {...this.appOktaSessionService.sessionState()};\r\n // Create a new session for the impersonated user\r\n let impersonatedUserSession = await lastValueFrom(this.createSessionStateForImpersonatedUser(userId, tenantId));\r\n // Update the current session with the impersonated user details\r\n impersonatedUserSession.isAuthenticated = true;\r\n impersonatedUserSession.isSessionInitialised = true;\r\n impersonatedUserSession.hasAcceptedPrivacy = true;\r\n impersonatedUserSession.refreshToken = '';\r\n impersonatedUserSession.impersonationAdminUrl = this.router.url;\r\n impersonatedUserSession.originalUserSessionState = currentSession;\r\n // Update the session\r\n this.appOktaSessionService.initialiseImpersonationSession(impersonatedUserSession);\r\n // Start a timer to end the session\r\n let currentTime = new Date();\r\n let sessionDuration = impersonatedUserSession.tokenExpiry.getTime() - currentTime.getTime();\r\n setTimeout(async () => { await this.endImpersonationSession(); }, sessionDuration);\r\n // Navigate the user to the dashboard\r\n if (impersonatedUserSession.assets.length === 0) {\r\n\t\t\tthis.router.navigate(['main', impersonatedUserSession.currentTenant?.tenancyName, 'noassets']);\r\n\t\t}\r\n else {\r\n this.router.navigate(['main', impersonatedUserSession.currentTenant?.tenancyName, 'dashboard']);\r\n }\r\n }\r\n\r\n /**\r\n * Ends the impersonation session\r\n */\r\n public async endImpersonationSession(): Promise {\r\n this.logDebug(this.endImpersonationSession.name, 'ending impersonation');\r\n // Get the current session\r\n let currentSession = {...this.appOktaSessionService.sessionState()};\r\n // Replace the impersonated session details with the original user session details\r\n if (currentSession.originalUserSessionState) {\r\n // Reset the session state back to the original\r\n this.appOktaSessionService.initialiseImpersonationSession(currentSession.originalUserSessionState);\r\n // Redirect the user back to the admin screen they started from\r\n this.router.navigate([currentSession.impersonationAdminUrl]);\r\n }\r\n else\r\n //this.appSessionService.logout(''); \r\n this.appOktaSessionService.logout();\r\n }\r\n\r\n /**\r\n * Creates the session details for the impersonated user\r\n * @param userId The id of the user being impersonated\r\n * @param tenantId The id if the tenant to impersonate the user in\r\n */\r\n public createSessionStateForImpersonatedUser(userId: string, tenantId: string): Observable {\r\n this.logDebug(this.createSessionStateForImpersonatedUser.name, 'creating impersonated user session details', [userId, tenantId]);\r\n // Get the session state\r\n return this.httpClient.post(`${this.baseUrl}v1/Impersonation/ImpersonateUser/${userId}/${tenantId}`, '')\r\n .pipe(\r\n map((session: SessionState) => {\r\n if (session.tokenExpiry)\r\n session.tokenExpiry = new Date(session.tokenExpiry);\r\n \r\n return session;\r\n })\r\n );\r\n }\r\n}","export class TokenModel {\r\n constructor(public token: string, public expiryDate: Date, public refreshToken: string){}\r\n}","import { inject, Injectable, Injector } from \"@angular/core\";\r\nimport { Observable, lastValueFrom, throwError } from \"rxjs\";\r\nimport { catchError, tap } from 'rxjs/operators';\r\nimport { TokenModel } from \"src/app/core/models/authentication/token.model\";\r\nimport { environment } from \"src/environments/environment\";\r\nimport { ServiceBase } from \"../../service-base\";\r\nimport { HttpErrorResponse } from \"@angular/common/http\";\r\nimport { Router } from \"@angular/router\";\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class SessionTokenService extends ServiceBase {\r\n\r\n private router: Router = inject(Router);\r\n\r\n private localStorageApiTokenKey: string = \"OptixApiToken\";\r\n \r\n public tokenDetails: TokenModel | undefined;\r\n\r\n constructor(injector: Injector) {\r\n super(injector);\r\n }\r\n\r\n /**\r\n * Generates a new auth token from the server\r\n */\r\n public async generateAuthToken(identityId: string, b2cId: string, email: string | undefined, tenancyName: string, assetId?: string): Promise {\r\n this.logDebug(this.generateAuthToken.name, \"Getting new token\", [tenancyName, assetId]);\r\n // Set the details to be sent to the server for the token\r\n var authModel = {\r\n applicationId: environment.optixApi.applicationId,\r\n applicationSecret: environment.optixApi.applicationSecret,\r\n identityId: identityId,\r\n b2cId: b2cId,\r\n email: email,\r\n tenancyName: tenancyName,\r\n assetId: assetId\r\n };\r\n // Make the request to the server\r\n let token = await lastValueFrom(this.getAuthToken(authModel));\r\n // Make the expiry date a date\r\n token.expiryDate = new Date(token.expiryDate);\r\n // Store the token in local storage\r\n localStorage.setItem(this.localStorageApiTokenKey, JSON.stringify(token));\r\n\r\n this.logDebug(this.generateAuthToken.name, 'Token retrieved', [this.tokenDetails]);\r\n return token;\r\n }\r\n\r\n /**\r\n * Gets the authentication token\r\n * @param authModel The authentication model to use to get the token\r\n * @returns The authentication token\r\n */\r\n public getAuthToken(authModel: any): Observable {\r\n this.logDebug(this.getAuthToken.name, \"Getting new token\", [authModel]);\r\n return this.httpClient.post(`${this.baseUrl}v1/authentication`, authModel)\r\n .pipe(\r\n catchError((error: HttpErrorResponse) => {\r\n let errorMsg = `Error Code: ${error.status}, Message: ${error.error}`;\r\n if (error.status === 401) {\r\n // Redirect the user to the unauthorised page\r\n this.router.navigate(['unauthorised']);\r\n }\r\n console.log(errorMsg);\r\n return throwError(() => new Error(`Failed to get token - ${errorMsg}`));\r\n })\r\n );\r\n }\r\n\r\n /**\r\n * Gets a refreshed jwt\r\n * @param jwt The current jwt for the user.\r\n * @param refreshToken The refresh token used to validate the current user\r\n */\r\n public refreshAuthToken(jwt: string, refreshToken: string) : Observable {\r\n this.logDebug(this.refreshAuthToken.name, 'refreshing token...');\r\n // Create the model for generating the token\r\n let refreshModel = {\r\n token: jwt,\r\n refreshToken: refreshToken\r\n }\r\n // Get a new refreshed jwt\r\n return this.httpClient.post(`${this.baseUrl}v1/authentication/refresh`, refreshModel)\r\n .pipe(\r\n tap(data => {\r\n this.tokenDetails = new TokenModel(\r\n\t\t\t\t\t\t\tdata.token,\r\n\t\t\t\t\t\t\tnew Date(data.expiryDate),\r\n\t\t\t\t\t\t\tdata.refreshToken\r\n\t\t\t\t\t\t);\r\n this.logDebug(this.refreshAuthToken.name, 'token retrieved', [this.tokenDetails]);\r\n localStorage.setItem(this.localStorageApiTokenKey, JSON.stringify(this.tokenDetails));\r\n })\r\n );\r\n }\r\n}","import { Injectable, Injector } from \"@angular/core\";\r\nimport { Observable } from \"rxjs\";\r\nimport { UserModel } from \"src/app/core/models/global/clients/user-model\";\r\nimport { AssetModel } from \"src/app/core/models/tenant/location/asset-model\";\r\nimport { AssetUserModel } from \"src/app/core/models/tenant/permissions/asset-user-model\";\r\nimport { UserAssetModel } from \"src/app/core/models/tenant/permissions/user-asset-model\";\r\nimport { ServiceBase } from \"../../../service-base\";\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class AssetUserService extends ServiceBase {\r\n\r\n constructor(injector: Injector) {\r\n super(injector);\r\n }\r\n\r\n /**\r\n * Gets the tenants for the current user.\r\n * @returns Observable with the tenants for the user.\r\n */\r\n public getUsersAssets(): Observable {\r\n return this.httpQueue.get(`${this.baseUrl}v1/assetuser/getassetsforuser`);\r\n }\r\n\r\n /**\r\n * Gets the tenant's assets for the current user.\r\n * @returns Observable with the tenants for the user.\r\n */\r\n public getUsersTenantAssets(tenantId: string): Observable {\r\n return this.httpQueue.get(`${this.baseUrl}v1/AssetUser/GetTenantAssetsForUser/${tenantId}`);\r\n }\r\n\r\n /**\r\n * Gets the users for the asset\r\n * @param assetId The id of the asset to get the users for\r\n */\r\n public getAssetUsersForAsset(assetId: string): Observable {\r\n return this.httpQueue.get(`${this.baseUrl}v1/assetuser/getassetusersforasset/${assetId}`);\r\n }\r\n\r\n /**\r\n * Gets the users for the asset\r\n * @param assetId The id of the asset to get the users for\r\n */\r\n public getUsersForAsset(assetId: string): Observable {\r\n return this.httpQueue.get(`${this.baseUrl}v1/AssetUser/GetUsersForAsset/${assetId}`);\r\n }\r\n\r\n /**\r\n * Gets the users assets with permission.\r\n * @param userId The id of the user to the the assets and permissions for.\r\n * @returns Collection of UserAssetModels\r\n */\r\n public GetAssetsForTenantWithUserPermissions(userId: string): Observable {\r\n return this.httpQueue.get(\r\n\t\t\t`${this.baseUrl}v1/AssetUser/GetAssetsForTenantWithUserPermissions/${userId}`\r\n\t\t);\r\n }\r\n\r\n /**\r\n * Gets the users assets with permission.\r\n * @param userId The id of the user to the the assets and permissions for.\r\n * @returns Collection of UserAssetModels\r\n */\r\n public GetAssetsForTenantWithUserPermissionsByTenantId(tenantId:string, userId: string): Observable {\r\n return this.httpQueue.get(\r\n\t\t\t`${this.baseUrl}v1/AssetUser/GetAssetsForTenantWithUserPermissionsByTenantId/${tenantId}/${userId}`\r\n\t\t);\r\n }\r\n\r\n\t/**\r\n\t * Deletes the user.\r\n\t * @param user The user to be deleted.\r\n\t * @returns Observable with the deleted user details.\r\n\t */\r\n\tpublic deleteUserByAssetId(assetId: string, user: UserModel): Observable {\r\n\t\treturn this.httpQueue.delete(\r\n\t\t\t`${this.baseUrl}v1/AssetUser/DeleteUserByAssetId/${assetId}/${user.id}`\r\n\t\t);\r\n\t}\r\n\r\n\t/**\r\n\t * Restore the user.\r\n\t * @param user The user to be restore.\r\n\t * @returns Observable with the restored user details.\r\n\t */\r\n\tpublic restoreUserByAssetId(assetId: string, user: UserModel): Observable {\r\n\t\treturn this.httpQueue.put(\r\n\t\t\t`${this.baseUrl}v1/AssetUser/RestoreUserByAssetId/${assetId}/${user.id}`, ''\r\n\t\t);\r\n\t}\r\n}","import { DOCUMENT } from \"@angular/common\";\r\nimport { Inject, Injectable } from \"@angular/core\";\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class ThemeService {\r\n\r\n constructor(@Inject(DOCUMENT) private document: Document) {}\r\n\r\n /**\r\n * Switches the theme of the application\r\n * @param theme The name of the selected theme\r\n */\r\n public switchTheme(theme: string) {\r\n let themeLink = this.document.getElementById('app-theme') as HTMLLinkElement;\r\n\r\n if (themeLink)\r\n themeLink.href = `${theme}.css`;\r\n }\r\n\r\n public getTheme(): string {\r\n let themeLink = this.document.getElementById('app-theme') as HTMLLinkElement;\r\n\r\n if (themeLink) {\r\n return themeLink.href.replace('.css', '').replace(/^.*[\\\\\\/]/, '');\r\n }\r\n\r\n return 'default';\r\n }\r\n}","import { Component, inject, OnDestroy, OnInit } from \"@angular/core\";\r\nimport { ConfirmationService, MessageService } from \"primeng/api\";\r\nimport { Subscription } from \"rxjs\";\r\nimport { AppSpinnerComponent } from \"../../components/app-spinner/app-spinner.component\";\r\nimport { BusinessObjectStatus } from \"../../models/constants/business-object-status-enum\";\r\nimport { SessionState } from \"../../models/session/session-state.model\";\r\nimport { OptixComponentBase } from \"./optix-component-base\";\r\nimport { RolePagePermissions } from '../../models/constants/permissions/role-page-permissions-enum';\r\nimport { InvestigationStatus } from \"../../models/constants/communications/investigation-status-enum\";\r\nimport { InsightStatus } from \"../../models/constants/communications/insight-status-enum\";\r\nimport { PageFilterModel } from \"../../models/views/page-filter-model\";\r\nimport { NgxSpinnerService, Size } from \"ngx-spinner\";\r\nimport { EnergyUnit } from \"../../models/constants/views/energy-unit.enum\";\r\nimport { NavigationEnd, Router } from \"@angular/router\";\r\nimport { AppOktaSessionService } from \"../../services/session/app-okta-session.service\";\r\nimport { ThemeService } from \"../theme/theme.service\";\r\nimport { environment } from 'src/environments/environment';\r\nimport { UserTypes } from \"../../models/constants/permissions/user-types-enum\";\r\n\r\ndeclare var require: any;\r\n\r\n@Component({\r\n template: ''\r\n})\r\nexport class AppComponentBase extends OptixComponentBase implements OnInit, OnDestroy {\r\n \r\n version = require('../../../../../package.json').version;\r\n\r\n public get BusinessObjectStatus(): typeof BusinessObjectStatus { return BusinessObjectStatus; }\r\n public get RolePagePermissions(): typeof RolePagePermissions { return RolePagePermissions; }\r\n public get InvestigationStatus(): typeof InvestigationStatus { return InvestigationStatus; }\r\n public get InsightStatus(): typeof InsightStatus { return InsightStatus; }\r\n public get EnergyUnit(): typeof EnergyUnit { return EnergyUnit; }\r\n \r\n public spinner: AppSpinnerComponent;\r\n public confirmationService: ConfirmationService;\r\n public messageService: MessageService;\r\n public loadingSpinner: NgxSpinnerService;\r\n protected appOktaSessionService: AppOktaSessionService = inject(AppOktaSessionService);\r\n protected themeService: any = inject(ThemeService);\r\n\r\n public sessionInfo!: SessionState;\r\n public isImpersonatedSession: boolean = false;\r\n public theme: string = 'default';\r\n public themeChanged: boolean = false;\r\n \r\n public sessionStateSubscription: Subscription = new Subscription();\r\n public pageSubscriptions: Subscription = new Subscription();\r\n\r\n public timezone: string = \"Europe/London\";\r\n public pageFilter: PageFilterModel = new PageFilterModel();\r\n\r\n private baseRouter: Router;\r\n\r\n public isProdMode: boolean = environment.mode === 'prod' || environment.mode === 'staging';\r\n\r\n /**\r\n * This is page name as it appears in the database\r\n */\r\n public pageName!: string;\r\n\r\n /**\r\n * Default constructor\r\n */\r\n constructor() { \r\n super();\r\n\r\n this.spinner = inject(AppSpinnerComponent);\r\n this.confirmationService = inject(ConfirmationService);\r\n this.messageService = inject(MessageService);\r\n this.loadingSpinner = inject(NgxSpinnerService);\r\n\r\n this.baseRouter = inject(Router);\r\n }\r\n\r\n public ngOnInit(): void {\r\n this.logDebug(this.ngOnInit.name, 'Base OnInit');\r\n // Get the theme\r\n this.theme = this.themeService.getTheme();\r\n // Subscribe to the session object\r\n let sessionSubscription = this.appOktaSessionService.sessionState$().subscribe(s => {\r\n this.sessionInfo = s;\r\n if (this.sessionInfo.currentAsset?.timezoneModel.name)\r\n\t\t\t\tthis.timezone = this.sessionInfo.currentAsset?.timezoneModel.name;\r\n // If there is no current asset, load the page data as we are most likely on a dashboard selection or admin page that doesnt use the page header filters\r\n // if (!this.sessionInfo.currentAsset && (\r\n // (this.isImpersonatedSession && this.sessionInfo.originalUserSessionState !== undefined) ||\r\n // (!this.isImpersonatedSession && this.sessionInfo.originalUserSessionState === undefined) ||\r\n // (!this.isImpersonatedSession && this.sessionInfo.originalUserSessionState !== undefined)\r\n // ))\r\n // this.loadPageData();\r\n // Set if the session is impersonated\r\n this.isImpersonatedSession = this.sessionInfo.originalUserSessionState !== undefined;\r\n\r\n // Update the theme\r\n this.logDebug(this.ngOnInit.name, 'checking theme', [this.theme, this.sessionInfo.theme]);\r\n if (this.theme !== undefined && this.sessionInfo !== undefined) {\r\n this.themeChanged = this.theme !== this.sessionInfo.theme;\r\n this.theme = this.sessionInfo.theme ?? 'default';\r\n if (this.themeChanged) {\r\n this.logDebug(this.ngOnInit.name, 'Theme changed', [this.theme]);\r\n }\r\n } \r\n });\r\n this.sessionStateSubscription.add(sessionSubscription);\r\n\r\n // Auto scroll the user back to the top of the page after navigation\r\n this.baseRouter.events.subscribe((event) => { \r\n if (!(event instanceof NavigationEnd)) { \r\n return; \r\n } \r\n window.scrollTo(0, 0) \r\n });\r\n }\r\n\r\n public ngOnDestroy(): void {\r\n this.logDebug(this.ngOnDestroy.name, 'Base OnDestroy');\r\n // Unsubscribe from all subscriptions\r\n this.sessionStateSubscription.unsubscribe();\r\n this.pageSubscriptions.unsubscribe();\r\n }\r\n\r\n /**\r\n * Loads the page data, to be overridden on the page/component to load the specific page data\r\n */\r\n public loadPageData(): void {}\r\n\r\n /**\r\n * Displays the toast message\r\n * @param type The type of toast ('success', 'error', 'warning')\r\n * @param title The title of the toast\r\n * @param message The message of the toast\r\n */\r\n public showToast(type: string, title: string, message: string): void {\r\n this.logDebug(this.showToast.name, 'Displaying message', [type, title, message]);\r\n // Display the success message\r\n this.messageService.add({severity: type, summary: title, detail: message});\r\n // Hide the spinner if it is being displayed\r\n this.spinner.hide();\r\n }\r\n\r\n /**\r\n * Checks the requested permission of this page for the user\r\n * @param permission The permission to check if the current user has on this page\r\n */\r\n public hasPermission(permission: RolePagePermissions): boolean {\r\n // Create the full permission name and check against the user's roles\r\n let fullPermissionName = `${this.pageName}_${permission}`;\r\n return this.appOktaSessionService.sessionState().roles.includes(fullPermissionName);\r\n }\r\n\r\n public isInternalUser(): boolean {\r\n if (this.sessionInfo.userType === UserTypes.Opex) {\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n }\r\n}","import { formatDate } from '@angular/common';\r\nimport { Size } from 'ngx-spinner';\r\n\r\n/**\r\n * The purpose of the Optix Component base is to be a common base class for all other\r\n * base components, providing helper methods that can be used by all.\r\n */\r\nexport abstract class OptixComponentBase {\r\n\r\n private locale: string = \"en-GB\";\r\n\r\n public panelLoaderIcon: string = 'ball-clip-rotate-multiple';\r\n public panelLoaderSize: Size = 'medium';\r\n public panelLoaderColour: string = '#7cae15';\r\n\r\n constructor() { }\r\n\r\n /**\r\n * Writes a debug level message to the console.\r\n * @param method The method writing the debug message.\r\n * @param message The message to printed in the console.\r\n * @param optionalParams Any params to be included in the message.\r\n */\r\n public logDebug(method: string, message: string, optionalParams?: any[]) {\r\n let instance: any = this.constructor;\r\n let logMessageDate: string = formatDate(Date.now(),'yyyy-MM-dd HH:mm:ss', this.locale);\r\n\r\n if (optionalParams)\r\n console.debug(`[${logMessageDate}] : ${instance.name} : ${method} : ${message}`, optionalParams);\r\n else\r\n console.debug(`[${logMessageDate}] : ${instance.name} : ${method} : ${message}`);\r\n }\r\n\r\n /**\r\n * Writes a info level message to the console.\r\n * @param method The method writing the info message.\r\n * @param message The message to printed in the console.\r\n * @param optionalParams Any params to be included in the message.\r\n */\r\n public logInfo(method: string, message: string, optionalParams?: any[]) {\r\n let instance: any = this.constructor;\r\n let logMessageDate: string = formatDate(Date.now(),'yyyy-MM-dd HH:mm:ss', this.locale);\r\n\r\n if (optionalParams)\r\n console.log(`[${logMessageDate}] : ${instance.name} : ${method} : ${message}`, optionalParams);\r\n else\r\n console.log(`[${logMessageDate}] : ${instance.name} : ${method} : ${message}`);\r\n }\r\n\r\n /**\r\n * Writes a error level message to the console.\r\n * @param method The method writing the error message.\r\n * @param message The message to printed in the console.\r\n * @param optionalParams Any params to be included in the message.\r\n */\r\n public logError(method: string, message: string, optionalParams?: any[]) {\r\n let instance: any = this.constructor;\r\n let logMessageDate: string = formatDate(Date.now(),'yyyy-MM-dd HH:mm:ss', this.locale);\r\n\r\n if (optionalParams)\r\n console.error(`[${logMessageDate}] : ${instance.name} : ${method} : ${message}`, optionalParams);\r\n else\r\n console.error(`[${logMessageDate}] : ${instance.name} : ${method} : ${message}`);\r\n }\r\n}","export const environment = {\r\n\tproduction: true,\r\n\tmode: 'prod',\r\n\toptixApi: {\r\n\t\tbaseUrl: 'https://api.emissions.ai/',\r\n\t\tapplicationId: '00000000-0000-0000-0000-000000000001',\r\n\t\tapplicationSecret: 'eaf599a6f17645d7a6d5e45ce2342fa9b0867bbb202c4953aec95a38a04e980f830f116538ca48c2b488a3e4fffe2f94'\r\n\t},\r\n\traygunKey: 'ra9ktxXrvPBhpJ7Xu9dfQ',\r\n\tokta: {\r\n\t\tclientId: '0oafnm0zwg6lVSQOx697',\r\n\t\tissuer: 'https://apps.ermauth.com/oauth2/default',\r\n\t\tredirectUri: 'https://app.emissions.ai/login/callback',\r\n\t\tscopes: ['openid', 'profile', 'email'],\r\n\t\tpkce: true\r\n\t},\r\n\toptixSubDomains: ['', 'app'],\r\n\tanalytics: {\r\n\t\tbaseUrl: 'https://emissions-ai-prod-analytics.azurewebsites.net/',\r\n\t\tapplicationId: '00000000-0000-0000-0000-000000000003',\r\n\t\tapiKey: 'b2da3fc8846a4f3a89208c73a8a4a064-d9f4a67314af47ef8f9420c9ca7a43a3'\r\n\t}\r\n};\r\n","import { Component, Inject, OnInit } from '@angular/core';\r\nimport { Router } from '@angular/router';\r\nimport { AppSpinnerComponent } from './core/components/app-spinner/app-spinner.component';\r\nimport { OptixComponentBase } from './core/utils/base-components/optix-component-base';\r\nimport { AppOktaSessionService } from './core/services/session/app-okta-session.service';\r\nimport { Observable, filter, map } from 'rxjs';\r\nimport { OKTA_AUTH, OktaAuthStateService } from '@okta/okta-angular';\r\nimport OktaAuth, { AuthState } from '@okta/okta-auth-js';\r\n\r\n@Component({\r\n selector: '',\r\n templateUrl: './app-initialiser.component.html'\r\n})\r\nexport class AppInitialiserComponent extends OptixComponentBase implements OnInit {\r\n \r\n private authenticated$!: Observable;\r\n\r\n constructor(private router: Router, private spinner: AppSpinnerComponent, private appOktaSesionService: AppOktaSessionService,\r\n @Inject(OKTA_AUTH) private oktaAuth: OktaAuth, public authService: OktaAuthStateService) {\r\n super();\r\n this.logDebug(this.constructor.name, 'loaded');\r\n }\r\n\r\n public async ngOnInit(): Promise {\r\n this.logDebug(this.ngOnInit.name, 'initialised');\r\n \r\n this.spinner.show();\r\n \r\n // Get the authenticated state\r\n let authenticated$ = this.authService.authState$.pipe(\r\n filter((s: AuthState) => !!s),\r\n map((s: AuthState) => s.isAuthenticated ?? false)\r\n );\r\n \r\n // Subscribe to the authenticated state and initialise the session when authenticated\r\n authenticated$.subscribe(async (authenticated: boolean) => {\r\n if (authenticated) {\r\n // Initialise the session state\r\n await this.appOktaSesionService.init(this.router.routerState.root.snapshot, this.router.routerState.snapshot);\r\n this.spinner.hide();\r\n }\r\n });\r\n }\r\n}\r\n","

Initialising...

","import { Injectable } from '@angular/core';\r\nimport { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router, CanActivateChild } from '@angular/router';\r\nimport { AppComponentBase } from '../base-components/app-component-base';\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class RoleGuard extends AppComponentBase implements CanActivate, CanActivateChild {\r\n \r\n constructor(private router: Router) { \r\n super();\r\n this.logDebug(this.constructor.name, 'loaded');\r\n }\r\n\r\n /**\r\n * Checks if the token has permissions to activate the route\r\n * @param route The route being requested\r\n * @param state The route state\r\n * @returns true if the route can be activated\r\n */\r\n private async canActivateInternal(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise {\r\n this.logDebug(this.canActivateInternal.name, 'ensuring session is initialised', [route, state]);\r\n this.spinner.show();\r\n try {\r\n // Initialise the session\r\n await this.appOktaSessionService.init(route, state);\r\n \r\n // If the route hasn't any role data, nothing to check\r\n if (!route.data['role'])\r\n return true;\r\n\r\n // Check the roles match the role required for the route\r\n let routeRoles = route.data['role'];\r\n // Get the users current roles\r\n let session = this.appOktaSessionService.sessionState();\r\n if (session.roles.includes(routeRoles))\r\n return true;\r\n // User doesn't have permission to access the route, send them to unauthorised\r\n this.router.navigate(['forbidden']);\r\n return false;\r\n }\r\n finally {\r\n this.spinner.hide();\r\n }\r\n }\r\n\r\n public async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise {\r\n return await this.canActivateInternal(route, state);\r\n }\r\n\r\n public async canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise {\r\n return await this.canActivateInternal(route, state);\r\n }\r\n}","import { Component, Injector } from '@angular/core';\r\nimport { AppComponentBase } from 'src/app/core/utils/base-components/app-component-base';\r\n\r\n@Component({\r\n selector: 'app-cookie',\r\n templateUrl: './cookie.component.html',\r\n styleUrls: ['./cookie.component.css'],\r\n})\r\nexport class CookieComponent extends AppComponentBase {\r\n constructor() {\r\n super();\r\n }\r\n}\r\n","

COOKIE POLICY

A cookie is a small piece of text sent to your browser by a website you visit. It helps the website to remember information about your visit, like your preferred language or other settings.

A cookie helps analyse web traffic or lets website operators know when you visit a particular site. Cookies allow web applications to respond to you as an individual. The web application can tailor its operations to your needs, likes and dislikes by gathering and remembering information about your preferences.

This website uses Google Analytics, a web analytics service provided by Google, Inc. Google Analytics sets a cookie in order to evaluate the use of our website and compile reports on user activity.

It may use a set of cookies to collect information and report website usage statistics without personally identifying individual visitors to ourselves or to Google. The main cookie used by Google Analytics is the ‘__ga’ cookie.

Google stores the information collected by the cookie on servers in the United States. Google may also transfer this information to third parties where required to do so by law, or where such third parties process the information on Google's behalf. Google will not associate your IP address with any other data held by Google. By using opex-group.com, you consent to the processing of data about you by Google in the manner and for the purposes set out above.

MANAGING COOKIES

Some people prefer not to allow cookies, which is why most browsers give you the ability to manage cookies to suit you. Some browsers limit or delete cookies, so you may want to review your cookie settings and ads settings. In some browsers you can set up rules to manage cookies on a site-by-site basis, giving you more fine-grained control over your privacy. What this means is that you can disallow cookies from all sites except those that you trust.

For example in the Google Chrome browser, the Tools menu contains an option to Clear Browsing Data. You can use this option to delete cookies and other site and plug-in data, including data stored on your device by the Adobe Flash Player (commonly known as Flash cookies).

Another feature of Chrome is its incognito mode. You can browse in incognito mode when you don’t want your website visits or downloads to be recorded in your browsing and download histories. Any cookies created while in incognito mode are deleted after you close all incognito windows.

Other browsers include Microsoft Edge, Internet Explorer, Mozilla Firefox, Safari and Opera; as well as others. Please consult the relevant documentation for the browser you are using to find what cookie management options are available in your chosen browser. Alternatively, you may wish to visit www.aboutcookies.org which contains comprehensive information on how to do this on a wide variety of browsers. You will also find details on how to delete cookies from your computer as well as more general information about cookies. For information on how to do this on the browser of your mobile device you will need to refer to your manual.

","import { Component, Injector } from '@angular/core';\r\nimport { AppComponentBase } from 'src/app/core/utils/base-components/app-component-base';\r\n\r\n@Component({\r\n selector: 'app-root',\r\n templateUrl: './fatal-exception.component.html',\r\n})\r\nexport class FatalExceptionComponent extends AppComponentBase {\r\n constructor() {\r\n super();\r\n }\r\n}\r\n","\r\n
\r\n
\r\n

We're sorry a fatal exception has occurred in the application and needs to be restarted. This error has been recorded. Please logout and login back in again, and then retry your action.

>\r\n
\r\n
","import { Component, Injector } from '@angular/core';\r\nimport { AppComponentBase } from 'src/app/core/utils/base-components/app-component-base';\r\n\r\n@Component({\r\n selector: 'app-root',\r\n templateUrl: './page-not-found.component.html',\r\n})\r\nexport class PageNotFoundComponent extends AppComponentBase {\r\n constructor() {\r\n super();\r\n }\r\n}\r\n","\r\n
\r\n
\r\n

We're sorry the page you were looking for could not be found.

\r\n
\r\n
","import { Component } from '@angular/core';\r\nimport { AppComponentBase } from 'src/app/core/utils/base-components/app-component-base';\r\n\r\n@Component({\r\n selector: 'app-terms',\r\n templateUrl: './terms.component.html',\r\n styleUrls: ['./terms.component.css'],\r\n})\r\nexport class TermsComponent extends AppComponentBase {\r\n constructor() {\r\n super();\r\n }\r\n}\r\n","
\r\n
\r\n

TERMS OF USE

\r\n

LEGAL INFORMATION

\r\n

Operational Excellence (OPEX) Group Limited (“OPEX Group”) is registered in Scotland. Registration Number\r\n SC382192 Registered Address: OPEX Digital Collaboration Centre, 18 Carden Place, Aberdeen, AB10 1UQ

\r\n

ACCESS

\r\n

Access to this website is permitted on a temporary basis and we reserve the right to withdraw or amend the\r\n service we provide on the site without notice.

\r\n

COPYRIGHT

\r\n

This website is protected by copyright. Permission is given for the downloading and temporary storage of one\r\n or more of these pages for the purpose of viewing on a personal computer or monitor. The reproduction,\r\n permanent storage, or retransmission of the contents of this website is prohibited without the prior written\r\n consent of OPEX Group. For permission to reproduce any of the contents of this website please contact us -\r\n ERMOPEXinfo@erm.com

\r\n

Unless otherwise stated all contents of this website are copyright of OPEX Group.

\r\n

ACCESSIBILITY

\r\n

OPEX Group is committed to providing a website that is accessible to the widest possible audience. We\r\n actively work to ensure that this website is accessible and have taken great care to ensure that it meets\r\n standard accessibility requirements. In doing so, we believe this site meets the WCAG 2.0 AA guidelines laid\r\n down by the World Wide Web Consortium (W3C). If you have any problem accessing any part of this site or\r\n would like further information please contact us - ERMOPEXinfo@erm.com

\r\n

DISCLAIMER

\r\n

OPEX Group will use reasonable care to ensure that information is accurate at the time it is added to this\r\n site. Please note, however, that OPEX Group cannot guarantee the information is accurate and it shall not be\r\n liable for any losses or damage that anyone may suffer as a result of relying on this information. The\r\n information may be changed by OPEX Group at any time.

\r\n

OPEX Group assumes no responsibility for the contents of any other websites to which this website has links.\r\n

\r\n

This website is not guaranteed to be free from any so-called computer viruses and it is strongly recommended\r\n that you check for such viruses before down-loading it to your computer equipment.

\r\n

LINKS

\r\n

Any links to third party websites are provided solely for the purpose of your convenience. Such websites are\r\n operated and controlled by third parties and their inclusion does not imply any endorsement or approval by\r\n OPEX Group of the materials on such websites.

\r\n

CHANGES

\r\n

OPEX Group reserves the right to amend or replace the Terms of Use at any time. If we make any substantial\r\n changes, we will notify you by posting a prominent notice on the site.

\r\n

JURISDICTION

\r\n

The Terms and Conditions shall be governed by and construed in accordance with the Laws of Scotland and any\r\n disputes that may arise will be subject to the jurisdiction of the Scottish courts.

\r\n

ENQUIRIES

\r\n

For all enquiries please contact OPEX Group – ERMOPEXinfo@erm.com\r\n

\r\n
\r\n
","export class RequestAccessModel {\r\n public requestorEmail: string = '';\r\n public requestorFirstname: string = '';\r\n public requestorLastname: string = '';\r\n public tenant: string = '';\r\n public asset: string = '';\r\n public reason: string = '';\r\n}","\r\n\r\n\r\n
\r\n
\r\n
\r\n
\r\n

Unauthorised

\r\n
\r\n
\r\n You are not authorised to access this page. If you require access, please fill in the form below.\r\n
\r\n
\r\n
\r\n
\r\n\r\n
\r\n
\r\n \r\n \r\n
\r\n
\r\n \r\n \r\n
\r\n
\r\n \r\n \r\n The name of the asset you are requesting access too is required.\r\n
\r\n
\r\n \r\n \r\n Access request reason are required.\r\n
\r\n
\r\n
\r\n\r\n \r\n
\r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n\r\n","import { Component, inject, OnDestroy, OnInit } from '@angular/core';\r\nimport { RequestAccessModel } from 'src/app/core/models/global/clients/request-access.model';\r\nimport { SupportService } from 'src/app/core/services/global/clients/support.service';\r\nimport { AppComponentBase } from 'src/app/core/utils/base-components/app-component-base';\r\n\r\n@Component({\r\n selector: 'app-root',\r\n templateUrl: './unauthorised.component.html',\r\n})\r\nexport class UnauthorisedComponent extends AppComponentBase implements OnInit, OnDestroy {\r\n \r\n private supportService: SupportService = inject(SupportService);\r\n\r\n protected tenant: string = '';\r\n protected asset: string | undefined = undefined;\r\n\r\n public requestAssetAccess: RequestAccessModel = new RequestAccessModel();\r\n public submitted: boolean = false;\r\n\r\n constructor() {\r\n super();\r\n }\r\n\r\n public override ngOnInit(): void {\r\n super.ngOnInit();\r\n\r\n // Get the requested tenant and asset from the session\r\n this.tenant = this.appOktaSessionService.requestedTenant;\r\n this.asset = this.appOktaSessionService.requestedAsset;\r\n\r\n // Set the tenant initially in the request model\r\n this.requestAssetAccess.tenant = this.tenant;\r\n // Append the asset if it exists\r\n if (this.asset) {\r\n this.requestAssetAccess.asset = this.asset;\r\n }\r\n }\r\n\r\n public override ngOnDestroy(): void {\r\n this.logDebug(this.ngOnDestroy.name, 'Unauthorised OnDestroy');\r\n // Unsubscribe from all subscriptions\r\n this.sessionStateSubscription.unsubscribe();\r\n this.pageSubscriptions.unsubscribe();\r\n\r\n super.ngOnDestroy();\r\n }\r\n\r\n public submitRequest(): void {\r\n this.logDebug(this.submitRequest.name, 'submitting access request');\r\n this.submitted = true;\r\n // Validate the support request\r\n if (this.requestAssetAccess.asset && this.requestAssetAccess.reason) {\r\n this.spinner.show();\r\n // Update the requestor details\r\n this.requestAssetAccess.requestorEmail = this.sessionInfo.email ?? '';\r\n this.requestAssetAccess.requestorFirstname = this.sessionInfo.firstname ?? '';\r\n this.requestAssetAccess.requestorLastname = this.sessionInfo.lastname ?? '';\r\n\r\n this.supportService.submitAccessRequest(this.requestAssetAccess)\r\n .subscribe({\r\n next: (r) => {\r\n this.submitted = false;\r\n this.requestAssetAccess = new RequestAccessModel();\r\n this.showToast('success', 'Submitted', 'The access request has been submitted.');\r\n },\r\n error: (e) => { this.showToast('error', 'Error', 'The access request could not be submitted - ' + e) }\r\n });\r\n }\r\n}\r\n}\r\n","import { Component, OnDestroy, OnInit } from '@angular/core';\r\nimport { Router } from '@angular/router';\r\nimport { AppComponentBase } from 'src/app/core/utils/base-components/app-component-base';\r\n\r\n@Component({\r\n selector: 'app-root',\r\n templateUrl: './forbidden.page.html',\r\n})\r\nexport class ForbiddenPage extends AppComponentBase implements OnInit, OnDestroy {\r\n \r\n constructor(private router: Router) {\r\n super();\r\n\r\n let sessionSubscription = this.appOktaSessionService.sessionState$().subscribe(s => {\r\n this.sessionInfo = s;\r\n this.loadPageData();\r\n // Set if the session is impersonated\r\n this.isImpersonatedSession = this.sessionInfo.originalUserSessionState !== undefined;\r\n });\r\n this.sessionStateSubscription.add(sessionSubscription);\r\n }\r\n\r\n public override ngOnInit(): void {\r\n super.ngOnInit();\r\n\r\n let homePageSetting = this.sessionInfo.currentAsset?.assetSettingModels.find((e) => e.name.toLowerCase() === 'defaulthomepage')?.value;\r\n if (homePageSetting == \"redirect\") {\r\n let navigationProperties = ['main', this.sessionInfo.currentTenant == null ? '' : this.sessionInfo.currentTenant.tenancyName, this.sessionInfo.currentAsset?.name];\r\n navigationProperties.push('redirect');\r\n this.router.navigate(navigationProperties);\r\n }\r\n \r\n }\r\n\r\n public override ngOnDestroy(): void {\r\n this.logDebug(this.ngOnDestroy.name, 'Unauthorised OnDestroy');\r\n // Unsubscribe from all subscriptions\r\n this.sessionStateSubscription.unsubscribe();\r\n this.pageSubscriptions.unsubscribe();\r\n\r\n super.ngOnDestroy();\r\n}\r\n}\r\n","\r\n
\r\n
\r\n \r\n
\r\n
","import { NgModule } from '@angular/core';\r\nimport { NavigationEnd, NavigationStart, RouteConfigLoadEnd, RouteConfigLoadStart, Router, RouterModule, Routes } from '@angular/router';\r\nimport { AppInitialiserComponent } from './app-initialiser.component';\r\nimport { AppSpinnerComponent } from './core/components/app-spinner/app-spinner.component';\r\nimport { AnalyticsService } from './core/services/analytics/analytics.service';\r\nimport { RoleGuard } from './core/utils/guards/role-guard';\r\nimport { CookieComponent } from './modules/home/pages/cookie/cookie.component';\r\nimport { FatalExceptionComponent } from './modules/home/pages/fatal-exception/fatal-exception.component';\r\nimport { PageNotFoundComponent } from './modules/home/pages/page-not-found/page-not-found.component';\r\nimport { TermsComponent } from './modules/home/pages/terms/terms.component';\r\nimport { UnauthorisedComponent } from './modules/home/pages/unauthorised/unauthorised.component';\r\nimport { OktaAuthGuard, OktaCallbackComponent } from '@okta/okta-angular';\r\nimport { ForbiddenPage } from './modules/home/pages/forbidden/forbidden.page';\r\nimport { HttpQueue } from './core/services/http-queue.service';\r\n\r\nconst routes: Routes = [\r\n { path: '', component: AppInitialiserComponent, canActivate: [OktaAuthGuard] },\r\n { path: 'login/callback', component: OktaCallbackComponent },\r\n { path: 'unauthorised', component: UnauthorisedComponent, title: 'Unauthorised', canActivate: [OktaAuthGuard] },\r\n { path: 'forbidden', component: ForbiddenPage, title: 'Forbidden', canActivate: [OktaAuthGuard] },\r\n { path: 'fatalexception', component: FatalExceptionComponent, title: 'Exception', canActivate: [OktaAuthGuard] },\r\n { path: 'pagenotfound', component: PageNotFoundComponent, title: 'Page Not Found' },\r\n { path: 'account/cookie', component: CookieComponent, title: 'Cookies' },\r\n { path: 'account/terms', component: TermsComponent, title: 'Terms' },\r\n { path: 'main', loadChildren: () => import('./modules/main/main.module').then(m => m.MainModule), canActivate: [OktaAuthGuard], canActivateChild: [OktaAuthGuard, RoleGuard] },\r\n { path: 'root', loadChildren: () => import('./modules/root/root.module').then(m => m.RootModule), canActivate: [OktaAuthGuard], canActivateChild: [OktaAuthGuard, RoleGuard] },\r\n { path: '**', component: PageNotFoundComponent, canActivate: [OktaAuthGuard] }\r\n];\r\n\r\n@NgModule({\r\n imports: [RouterModule.forRoot(routes)],\r\n exports: [RouterModule]\r\n})\r\nexport class AppRoutingModule {\r\n constructor(private router: Router, private spinner: AppSpinnerComponent, private analyticsService: AnalyticsService, private httpQueueService: HttpQueue) {\r\n this.router.events.subscribe((event) => {\r\n if (event instanceof RouteConfigLoadStart) {\r\n this.spinner.show();\r\n }\r\n \r\n if (event instanceof RouteConfigLoadEnd) {\r\n this.spinner.hide();\r\n }\r\n\r\n if (event instanceof NavigationStart) {\r\n // Clear the queue\r\n this.httpQueueService.clearQueue();\r\n }\r\n \r\n if (event instanceof NavigationEnd) {\r\n this.analyticsService.recordUserAnalytics(true);\r\n }\r\n });\r\n }\r\n}\r\n","import { ApplicationRef, Injectable } from '@angular/core';\r\nimport { SwUpdate } from '@angular/service-worker';\r\nimport { MessageService } from 'primeng/api';\r\nimport { concat, first, interval } from 'rxjs';\r\nimport { environment } from 'src/environments/environment';\r\n\r\n@Injectable()\r\nexport class LogUpdateService {\r\n\tconstructor(private appRef: ApplicationRef, private updates: SwUpdate, private messageService: MessageService) {\r\n\t\t// Only setup service worker updates if it has been enabled\r\n\t\tif (updates.isEnabled) {\r\n\t\t\t// Setup the interval to check for updates\r\n\t\t\tthis.setupIntervalToCheckForUpdates();\r\n\t\t\t// Subscribe to updates\r\n\t\t\tthis.subscribeToVersionUpdates();\r\n\t\t}\r\n\t}\r\n\r\n\tprotected setupIntervalToCheckForUpdates(): void {\r\n\t\t// Subscribe to app updates\r\n\t\tconst appIsStable$ = this.appRef.isStable.pipe(first(isStable => isStable === true));\r\n \t// Default the interval to 2 hours\r\n\t\tlet interval$ = interval(2 * 60 * 60 * 1000);\r\n\t\t// If the environment is dev, change the interval to 30 minutes since it gets updated more often\r\n\t\tif (environment.mode === 'local')\r\n\t\t\tinterval$ = interval(30 * 60 * 1000);\r\n\r\n \tconst appUpdate$ = concat(appIsStable$, interval$);\r\n\r\n \tappUpdate$.subscribe(async () => {\r\n \t\ttry {\r\n \t\tconst updateFound = await this.updates.checkForUpdate();\r\n \t\tconsole.log(updateFound ? 'A new version is available.' : 'Already on the latest version.');\r\n \t\t} catch (err) {\r\n \t\tconsole.error('Failed to check for updates:', err);\r\n \t\t}\r\n \t});\r\n\t}\r\n\r\n\tprotected subscribeToVersionUpdates(): void {\r\n\t\t// Subscribe to version updates and log\r\n\t\tthis.updates.versionUpdates.subscribe((evt) => {\r\n\t\t\tswitch (evt.type) {\r\n\t\t\t\tcase 'VERSION_DETECTED':\r\n\t\t\t\t\tconsole.log(`Downloading new app version: ${evt.version.hash}`);\r\n\t\t\t\t\tthis.messageService.add({\r\n\t\t\t\t\t\tseverity: 'info', \r\n\t\t\t\t\t\tsummary: 'App Update', \r\n\t\t\t\t\t\tdetail: 'A new version of the app has been detected, this will be downloaded and installed in the background, you do not need to do anything.',\r\n\t\t\t\t\t\tkey: 'UpdateInfo',\r\n\t\t\t\t\t\tlife: 10000\r\n\t\t\t\t\t});\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase 'VERSION_READY':\r\n\t\t\t\t\tconsole.log(`Current app version: ${evt.currentVersion.hash}`);\r\n\t\t\t\t\tconsole.log(`New app version ready for use: ${evt.latestVersion.hash}`);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase 'VERSION_INSTALLATION_FAILED':\r\n\t\t\t\t\tconsole.log(`Failed to install app version '${evt.version.hash}': ${evt.error}`);\r\n\t\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { SwUpdate, VersionReadyEvent } from '@angular/service-worker';\r\nimport { MessageService } from 'primeng/api';\r\nimport { filter } from 'rxjs';\r\n\r\n@Injectable()\r\nexport class PromptUpdateService {\r\n\tconstructor(private swUpdate: SwUpdate, private messageService: MessageService) {\r\n this.promptForVersionUpdates();\r\n\t}\r\n\r\n\tprotected promptForVersionUpdates(): void {\r\n\t\t// Subscribe to when a new version is available\r\n\t\tthis.swUpdate.versionUpdates\r\n\t\t\t.pipe(\r\n\t\t\t\tfilter((evt): evt is VersionReadyEvent => evt.type === 'VERSION_READY')\r\n\t\t\t)\r\n\t\t\t.subscribe((evt) => {\r\n\t\t\t\t// Display prompt to reload\r\n\t\t\t\tthis.messageService.add({\r\n\t\t\t\t\tseverity: 'info',\r\n\t\t\t\t\tsummary: 'App Update',\r\n\t\t\t\t\tdetail: 'The app update has been installed and is ready for use. Please reload the app to get the latest version.',\r\n\t\t\t\t\tsticky: true,\r\n\t\t\t\t\tkey: 'UpdateNow'\r\n\t\t\t\t});\r\n\t\t\t});\r\n\t}\r\n}\r\n","","import { Component, Input } from '@angular/core';\r\nimport { AssetModel } from '../../models/tenant/location/asset-model';\r\n\r\n@Component({\r\n templateUrl: './brand.component.html',\r\n selector: 'brand-logo'\r\n})\r\nexport class BrandComponent{\r\n \r\n @Input() logoHeight: string = \"64\";\r\n @Input() tenantAssets: AssetModel[] = [];\r\n @Input() tenantCount: number = 0;\r\n \r\n constructor() {}\r\n}\r\n","import { Component } from '@angular/core';\r\n\r\n@Component({\r\n templateUrl: './app-footer.component.html',\r\n selector: 'app-footer'\r\n})\r\nexport class AppFooterComponent{\r\n \r\n year = (new Date()).getUTCFullYear();\r\n version = require('../../../../../package.json').version;\r\n \r\n constructor() { }\r\n}\r\n","","import { Inject, inject, Injectable } from '@angular/core';\r\nimport { BreakpointObserver, BreakpointState } from '@angular/cdk/layout';\r\nimport { Observable } from 'rxjs';\r\nimport { DOCUMENT } from '@angular/common';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class ScreenService {\r\n \r\n private observer: BreakpointObserver = inject(BreakpointObserver);\r\n\r\n constructor(@Inject(DOCUMENT) private document: Document) {}\r\n \r\n /**\r\n * Gets if the screen size is below the small breakpoint.\r\n * @returns Observable\r\n */\r\n public isBelowSm(): Observable {\r\n return this.observer.observe(['(max-width: 575px)']);\r\n }\r\n \r\n /**\r\n * Gets if the screen size is below the medium breakpoint.\r\n * @returns Observable\r\n */\r\n public isBelowMd(): Observable {\r\n return this.observer.observe(['(max-width: 767px)']);\r\n }\r\n \r\n /**\r\n * Gets if the screen size is below the large breakpoint.\r\n * @returns Observable\r\n */\r\n public isBelowLg(): Observable {\r\n return this.observer.observe(['(max-width: 991px)']);\r\n }\r\n \r\n /**\r\n * Gets if the screen size is below the extra large breakpoint.\r\n * @returns Observable\r\n */\r\n public isBelowXl(): Observable {\r\n return this.observer.observe(['(max-width: 1199px)']);\r\n }\r\n\r\n /**\r\n * Applies a margin to the header, section and footer to allow for the menu panel.\r\n */\r\n public applyMarginForMenuPanel(): void {\r\n let header = document.getElementsByTagName('header')[0];\r\n if (header) {\r\n header.style.marginLeft = '320px';\r\n }\r\n let section = document.getElementsByTagName('section')[0];\r\n if (section) {\r\n section.style.marginLeft = '320px';\r\n }\r\n let footer = document.getElementsByTagName('footer')[0];\r\n if (footer) {\r\n footer.style.paddingLeft = '320px';\r\n }\r\n }\r\n\r\n /**\r\n * Removes a margin from the header, section and footer to allow for the menu panel.\r\n */\r\n public removeMarginForMenuPanel(): void {\r\n let header = document.getElementsByTagName('header')[0];\r\n if (header) {\r\n header.style.marginLeft = '0px';\r\n }\r\n let section = document.getElementsByTagName('section')[0];\r\n if (section) {\r\n section.style.marginLeft = '0px';\r\n }\r\n let footer = document.getElementsByTagName('footer')[0];\r\n if (footer) {\r\n footer.style.paddingLeft = '0px';\r\n }\r\n }\r\n}","\r\n","import { Component, OnInit } from '@angular/core';\r\nimport { environment } from 'src/environments/environment';\r\nimport { Message, MessageService } from 'primeng/api';\r\n\r\n@Component({\r\n selector: 'app-environment-banner',\r\n templateUrl: './environment-banner.component.html',\r\n providers: [MessageService]\r\n})\r\nexport class EnvironmentBannerComponent implements OnInit {\r\n\r\n displayMessage: boolean = false;\r\n messageText!: string;\r\n\r\n constructor() { }\r\n\r\n ngOnInit() { \r\n if (environment.mode !== 'prod') {\r\n this.displayMessage = true;\r\n this.messageText = 'You are currently in ' + environment.mode + '!';\r\n }\r\n }\r\n\r\n}\r\n","import { Injectable } from \"@angular/core\";\r\n\r\nexport class OptixMenuItem {\r\n constructor(\r\n public name: string,\r\n public role: string,\r\n public route: string,\r\n public subMenu?: OptixMenuItem[],\r\n public isExternal: boolean = false,\r\n public externalUrlSettingName: string = ''\r\n ) { }\r\n}\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class MenuBase {\r\n\r\n /**\r\n * Full list of the menu items that could appear.\r\n * Parent menu items cannot have a route, if it does, this will prevent checking and\r\n * adding of any child items\r\n */\r\n public fullMenu: OptixMenuItem[] = [\r\n new OptixMenuItem('Dashboard', '', '', [\r\n new OptixMenuItem('Tenant Dashboard', 'App.Tenant.AssetDashboard_Read', '/main/:tenant/dashboard'),\r\n new OptixMenuItem('Landing', 'App.Tenant.Asset.Emissions.EnergyEfficiency.Landing_Read', '/main/:tenant/:asset/emissions/energy-efficiency/landing'),\r\n new OptixMenuItem('Home', 'App.Tenant.Asset.Emissions.EnergyEfficiency.Home_Read', '/main/:tenant/:asset/emissions/energy-efficiency/home'),\r\n new OptixMenuItem('e.AI Operational Report', 'App.Tenant.Asset.Emissions.EnergyEfficiency.OperationalReport_Read', '/main/:tenant/:asset/emissions/energy-efficiency/operational-report'),\r\n new OptixMenuItem('Operating Status', 'App.Tenant.Asset.Emissions.EnergyEfficiency.OperatingStatus_Read', '/main/:tenant/:asset/emissions/energy-efficiency/operating-status'),\r\n new OptixMenuItem('History', 'App.Tenant.Asset.Emissions.EnergyEfficiency.History_Read', '/main/:tenant/:asset/emissions/energy-efficiency/history'),\r\n new OptixMenuItem('Summary', 'App.Tenant.Asset.Emissions.EnergyEfficiency.Summary_Read', '/main/:tenant/:asset/emissions/energy-efficiency/summary')\r\n ]),\r\n new OptixMenuItem('Analysis', '', '', [\r\n new OptixMenuItem('Analysis', 'App.Tenant.Asset.Emissions.EnergyEfficiency.Analysis_Read', '/main/:tenant/:asset/emissions/energy-efficiency/analysis'),\r\n new OptixMenuItem('Turbine Analysis', 'App.Tenant.Asset.Emissions.EnergyEfficiency.TurbineAnalysis_Read', '/main/:tenant/:asset/emissions/energy-efficiency/turbine-analysis'),\r\n new OptixMenuItem('Furnace Analysis', 'App.Tenant.Asset.Emissions.EnergyEfficiency.FurnaceAnalysis_Read', '/main/:tenant/:asset/emissions/energy-efficiency/furnace-analysis'),\r\n new OptixMenuItem('Steam Analysis', 'App.Tenant.Asset.Emissions.EnergyEfficiency.SteamAnalysis_Read', '/main/:tenant/:asset/emissions/energy-efficiency/steam-analysis'),\r\n new OptixMenuItem('Boilers', 'App.Tenant.Asset.Emissions.EnergyEfficiency.Boilers_Read', '/main/:tenant/:asset/emissions/energy-efficiency/boilers'),\r\n new OptixMenuItem('Heaters (WHRU)', 'App.Tenant.Asset.Emissions.EnergyEfficiency.Heaters_Read', '/main/:tenant/:asset/emissions/energy-efficiency/heaters'),\r\n new OptixMenuItem('Waste Heat Recovery (WHR)', 'App.Tenant.Asset.Emissions.EnergyEfficiency.Whru_Read', '/main/:tenant/:asset/emissions/energy-efficiency/whr'),\r\n new OptixMenuItem('Power Generation', 'App.Tenant.Asset.Emissions.EnergyEfficiency.PowerGeneration_Read', '/main/:tenant/:asset/emissions/energy-efficiency/power-generation'),\r\n new OptixMenuItem('Import Electricity', 'App.Tenant.Asset.Emissions.EnergyEfficiency.ImportElectricity_Read', '/main/:tenant/:asset/emissions/energy-efficiency/import-electricity'),\r\n new OptixMenuItem('Hot Oil', 'App.Tenant.Asset.Emissions.EnergyEfficiency.HotOil_Read', '/main/:tenant/:asset/emissions/energy-efficiency/hot-oil'),\r\n new OptixMenuItem('Fired Heaters', 'App.Tenant.Asset.Emissions.EnergyEfficiency.FiredHeaters_Read', '/main/:tenant/:asset/emissions/energy-efficiency/fired-heaters'),\r\n new OptixMenuItem('Performance Baseline', 'App.Tenant.Asset.Emissions.EnergyEfficiency.DynamicBaseline_Read', '/main/:tenant/:asset/emissions/energy-efficiency/performance-baseline'),\r\n new OptixMenuItem('Thermal Oxidizers', 'App.Tenant.Asset.Emissions.EnergyEfficiency.ThermalOxidizers_Read', '/main/:tenant/:asset/emissions/energy-efficiency/thermal-oxidizers'),\r\n new OptixMenuItem('Crude Arrival', 'App.Tenant.Asset.Emissions.EnergyEfficiency.CrudeArrival_Read', '/main/:tenant/:asset/emissions/energy-efficiency/crude-arrival'),\r\n new OptixMenuItem('Statistical Analysis', 'App.Tenant.Asset.Emissions.EnergyEfficiency.StatisticalAnalysis_Read', '/main/:tenant/:asset/emissions/energy-efficiency/statistical-analysis'),\r\n new OptixMenuItem('Performance Profile', 'App.Tenant.Asset.Emissions.EnergyEfficiency.PerformanceProfile_Read', '/main/:tenant/:asset/emissions/energy-efficiency/performance-profile')\r\n ]),\r\n new OptixMenuItem('Compliance', '', '', [\r\n new OptixMenuItem('Energy Report', 'App.Tenant.Asset.Emissions.EnergyEfficiency.EnergyReport_Read', '/main/:tenant/:asset/emissions/energy-efficiency/energy-report'),\r\n new OptixMenuItem('Running Hours', 'App.Tenant.Asset.Emissions.EnergyEfficiency.RunningHours_Read', '/main/:tenant/:asset/emissions/energy-efficiency/running-hours'),\r\n new OptixMenuItem('System Status', 'App.Tenant.Asset.Emissions.EnergyEfficiency.SystemStatus_Read', '/main/:tenant/:asset/emissions/energy-efficiency/system-status'),\r\n new OptixMenuItem('Diesel Reconciliation', 'App.Tenant.Asset.Emissions.EnergyEfficiency.DieselReconciliation_Read', '/main/:tenant/:asset/emissions/energy-efficiency/diesel-reconciliation')\r\n ]),\r\n new OptixMenuItem('Flaring', '', '', [\r\n new OptixMenuItem('Summary', 'App.Tenant.Asset.Emissions.Flaring.Summary_Read', '/main/:tenant/:asset/emissions/flaring/summary'),\r\n new OptixMenuItem('Analysis', 'App.Tenant.Asset.Emissions.Flaring.Analysis_Read', '/main/:tenant/:asset/emissions/flaring/analysis'),\r\n new OptixMenuItem('Consent Tracking', 'App.Tenant.Asset.Emissions.Flaring.ConsentTracking_Read', '/main/:tenant/:asset/emissions/flaring/consent-tracking'),\r\n new OptixMenuItem('Reconciliation', 'App.Tenant.Asset.Emissions.Flaring.Reconciliation_Read', '/main/:tenant/:asset/emissions/flaring/reconciliation')\r\n ]),\r\n new OptixMenuItem('PEMS', '', '', [\r\n new OptixMenuItem('Home', 'App.Tenant.Asset.Emissions.Pems.Home_Read', '/main/:tenant/:asset/emissions/pems/home'),\r\n new OptixMenuItem('Mass Emissions', 'App.Tenant.Asset.Emissions.Pems.MassEmissions_Read', '/main/:tenant/:asset/emissions/pems/mass-emissions'),\r\n new OptixMenuItem('Analysis', 'App.Tenant.Asset.Emissions.Pems.Analysis_Read', '/main/:tenant/:asset/emissions/pems/analysis'),\r\n new OptixMenuItem('Operating Status', 'App.Tenant.Asset.Emissions.Pems.OperatingStatus_Read', '/main/:tenant/:asset/emissions/pems/operating-status')\r\n ]),\r\n new OptixMenuItem('Methane', '', '', [\r\n new OptixMenuItem('Home', 'App.Tenant.Asset.Emissions.Methane.Home_Read', '/main/:tenant/:asset/emissions/methane'),\r\n ]),\r\n new OptixMenuItem('Communications', '', '', [\r\n new OptixMenuItem('Dashboard', 'App.Tenant.Asset.Communications.Dashboard_Read', '/main/:tenant/:asset/communications/dashboard'),\r\n new OptixMenuItem('Investigations', 'App.Tenant.Asset.Communications.XInvestigations_Read', '/main/:tenant/:asset/communications/investigations'),\r\n new OptixMenuItem('Insights', 'App.Tenant.Asset.Communications.XInsights_Read', '/main/:tenant/:asset/communications/insights')\r\n ]),\r\n new OptixMenuItem('Trends', '', '', [\r\n new OptixMenuItem('X-PAS', 'App.Tenant.Asset.XPAS_Read', '', undefined, true, 'XpasHomeUrl'),\r\n new OptixMenuItem('Trends emissions.AI', 'App.Tenant.Asset.Trends_Read', '', undefined, true, 'XpasHomeUrl'),\r\n new OptixMenuItem('Trends X-PAS Lite', 'App.Tenant.Asset.XPASLite_Read', '', undefined, true, 'XpasLiteHomeUrl'),\r\n\r\n ]),\r\n new OptixMenuItem('Asset Injection', '', '', [\r\n new OptixMenuItem('Master Portal', 'App.Tenant.Asset.AssetInjection.MasterPortal_Read', '/main/:tenant/:asset/asset-injection/master-portal'),\r\n new OptixMenuItem('Injection Portal', 'App.Tenant.Asset.AssetInjection.InjectionPortal_Read', '/main/:tenant/:asset/asset-injection/injection-portal'),\r\n new OptixMenuItem('Client Portal', 'App.Tenant.Asset.AssetInjection.ClientPortal_Read', '/main/:tenant/:asset/asset-injection/client-portal')\r\n ]),\r\n new OptixMenuItem('Root Admin', '', '', [\r\n //new OptixMenuItem('Api Test', '', '/root/api-test', ''),\r\n new OptixMenuItem('Tenants', 'Root.Tenants_Read', '/root/tenants'),\r\n new OptixMenuItem('Users', 'Root.Users_Read', '/root/users'),\r\n new OptixMenuItem('Analytics', 'Root.Analytics_Read', '/root/analytics'),\r\n new OptixMenuItem('Modules', 'Root.Modules_Read', '/root/modules'),\r\n new OptixMenuItem('Roles', 'Root.Roles_Read', '/root/roles'),\r\n new OptixMenuItem('Applications', 'Root.Applications_Read', '/root/applications'),\r\n new OptixMenuItem('Notification Messages', 'Root.NotificationMessages_Read', '/root/notification-messages'),\r\n new OptixMenuItem('Federated Domains', 'Root.FederatedDomains_Read', '/root/federated-domains'),\r\n new OptixMenuItem('User Manuals', 'Root.UserManuals_Read', '/root/user-manuals'),\r\n new OptixMenuItem('OPTiX Settings', 'Root.Settings_Read', '/root/settings'),\r\n new OptixMenuItem('Chart Settings', 'Root.ChartSettings_Read', '/root/chart-settings'),\r\n new OptixMenuItem('Card Settings', 'Root.CardSettings_Read', '/root/card-settings')\r\n ]),\r\n new OptixMenuItem('Tenant Administration', '', '', [\r\n new OptixMenuItem('Assets', 'App.Tenant.Admin.Assets_Read', '/main/:tenant/admin/assets'),\r\n new OptixMenuItem('Users', 'App.Tenant.Admin.Users_Read', '/main/:tenant/admin/users'),\r\n new OptixMenuItem('Analytics', 'App.Tenant.Admin.Analytics_Read', '/main/:tenant/admin/analytics'),\r\n new OptixMenuItem('Tenant Settings', 'App.Tenant.Admin.Settings_Read', '/main/:tenant/admin/tenant-settings'),\r\n new OptixMenuItem('Chart Settings', 'App.Tenant.Admin.ChartSettings_Read', '/main/:tenant/admin/chart-settings'),\r\n new OptixMenuItem('Card Settings', 'App.Tenant.Admin.CardSettings_Read', '/main/:tenant/admin/card-settings')\r\n ]),\r\n new OptixMenuItem('Asset Administration', '', '', [\r\n new OptixMenuItem('Analytics', 'App.Tenant.Asset.Analytics_Read', '/main/:tenant/:asset/admin/analytics'),\r\n new OptixMenuItem('Inventory', 'App.Tenant.Asset.Systems_Read', '/main/:tenant/:asset/admin/inventory'),\r\n new OptixMenuItem('Notification Messages', 'App.Tenant.Asset.Admin.Notifications_Read', '/main/:tenant/:asset/admin/notification-messages'),\r\n new OptixMenuItem('Units Of Measure', 'App.Tenant.Asset.Admin.UnitsOfMeasure_Read', '/main/:tenant/:asset/admin/units-of-measure'),\r\n new OptixMenuItem('Database Scaling', 'App.Tenant.Asset.Admin.DatabaseScaling_Read', '/main/:tenant/:asset/admin/database-scaling')\r\n ]),\r\n new OptixMenuItem('Support', '', '', [\r\n new OptixMenuItem('File Repository', 'App.Tenant.Asset.FileRepository_Read', '/main/:tenant/:asset/file-repository'),\r\n new OptixMenuItem('User Manual', '', '', undefined, true, 'UserManualUrl'),\r\n new OptixMenuItem('Support Documentation', 'App.Tenant.Asset.SupportDocumentation_Read', '/main/support/:tenant/:asset/support-documentation'),\r\n new OptixMenuItem('Contact Us', '', '/main/support/contact-us'),\r\n ])\r\n ]\r\n\r\n constructor() { }\r\n}","import { Injectable, OnDestroy, inject } from \"@angular/core\";\r\nimport { MenuItem } from \"primeng/api\";\r\nimport { TenantModel } from \"src/app/core/models/global/clients/tenant-model\";\r\nimport { AssetModel } from \"src/app/core/models/tenant/location/asset-model\";\r\nimport { OptixComponentBase } from \"src/app/core/utils/base-components/optix-component-base\";\r\nimport { MenuBase, OptixMenuItem } from \"./menu-base\";\r\nimport { Subscription } from \"rxjs\";\r\nimport { AppOktaSessionService } from \"../app-okta-session.service\";\r\nimport { OptixSettingName } from \"src/app/core/models/constants/optix-setting-name.constants\";\r\nimport { OptixSettingModel } from \"src/app/core/models/global/configuration/optix-setting-model\";\r\nimport { TenantSettingModel } from \"src/app/core/models/tenant/configuration/tenant-setting-model\";\r\nimport { AssetSettingModel } from \"src/app/core/models/asset/configuration/asset-setting-model\";\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class MenuService extends OptixComponentBase implements OnDestroy {\r\n\r\n private appOktaSessionService: AppOktaSessionService = inject(AppOktaSessionService);\r\n\r\n public tenant?: TenantModel;\r\n public asset?: AssetModel;\r\n public roles: string[] = [];\r\n\r\n private sessionSubscription!: Subscription;\r\n\r\n constructor(private menuBase: MenuBase) {\r\n super();\r\n\r\n this.sessionSubscription = this.appOktaSessionService.sessionState$().subscribe(sessionState => {\r\n this.tenant = sessionState.currentTenant;\r\n this.asset = sessionState.currentAsset;\r\n this.roles = sessionState.roles;\r\n });\r\n }\r\n\r\n ngOnDestroy(): void {\r\n // End the subscription to the session\r\n if (this.sessionSubscription) {\r\n this.sessionSubscription.unsubscribe();\r\n }\r\n }\r\n\r\n /**\r\n * The menu items for the user.\r\n * @returns Collection of menu items\r\n */\r\n public getMenuItems(command?: any): MenuItem[] {\r\n // Build the optix menu\r\n return this.processOptixMenu(this.menuBase.fullMenu, command);\r\n }\r\n\r\n private processOptixMenu(optixMenuItems: OptixMenuItem[], command?: any): MenuItem[] {\r\n var userSpecificMenu: MenuItem[] = [];\r\n // Only attempt to build the menu if the roles have been initialised.\r\n if (this.roles !== undefined) {\r\n // Get all the menu items that the user has the roles for\r\n optixMenuItems.forEach((optixMenuItem) => {\r\n let validatedMenuItem = this.validateMenuItemAccess(optixMenuItem, command);\r\n if (validatedMenuItem)\r\n userSpecificMenu.push(validatedMenuItem);\r\n });\r\n }\r\n\r\n return userSpecificMenu;\r\n }\r\n\r\n /**\r\n * Validates the user has access to the menu item\r\n * @param optixMenuItem The menu item to check the user has access to\r\n * @param roles The roles that the user has\r\n */\r\n private validateMenuItemAccess(optixMenuItem: OptixMenuItem, command?: any): MenuItem | undefined {\r\n // If the menu item has a route specified, check the permissions for that route\r\n if (optixMenuItem.route.length > 0) {\r\n if (optixMenuItem.role === '' || this.roles.includes(optixMenuItem.role)) \r\n return this.convertOptixMenuItemToPrimeNgMenuItem(optixMenuItem, command);\r\n }\r\n else if (optixMenuItem.isExternal) {\r\n if (optixMenuItem.role === '' || this.roles.includes(optixMenuItem.role)) \r\n return this.convertOptixMenuItemToPrimeNgMenuItem(optixMenuItem, command);\r\n }\r\n else {\r\n // The menu item has child menu items, so convert each of the child menu items and then create a\r\n // new primary menu item\r\n var childMenu: MenuItem[] = [];\r\n if (optixMenuItem.subMenu)\r\n childMenu = this.processOptixMenu(optixMenuItem.subMenu, command);\r\n // Create the menu itme with its child menu items\r\n if (childMenu && childMenu.length > 0)\r\n return this.convertOptixMenuItemToPrimeNgMenuItem(optixMenuItem, command, childMenu);\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n /**\r\n * Converts the optix style menu item to a PrimeNG menu item.\r\n * @param optixMenuItem The optix menu item to be converted.\r\n */\r\n public convertOptixMenuItemToPrimeNgMenuItem(optixMenuItem: OptixMenuItem, command?: any, childMenu?: MenuItem[]): MenuItem {\r\n let routerLink = (optixMenuItem.route.length > 0) ? optixMenuItem.route : undefined;\r\n // Make replacements of the route params\r\n if (routerLink) {\r\n if (this.tenant)\r\n routerLink = routerLink.replace(\":tenant\", this.tenant.tenancyName);\r\n\r\n if (this.asset)\r\n routerLink = routerLink.replace(\":asset\", this.asset.name);\r\n }\r\n\r\n return {\r\n label: optixMenuItem.name,\r\n routerLink: (routerLink ? [routerLink] : undefined),\r\n items: ((childMenu && childMenu.length > 0) ? childMenu : undefined),\r\n command: (\r\n (routerLink) \r\n ? command\r\n : (optixMenuItem.isExternal)\r\n ? (event) => {\r\n this.loadExternalUrl(event, optixMenuItem.externalUrlSettingName);\r\n command();\r\n }\r\n : undefined\r\n )\r\n };\r\n }\r\n\r\n /**\r\n * Gets the external url from the app settings for the asset and opens the url in a new tab\r\n */\r\n public loadExternalUrl(event: any, externalUrlSettingName: string) {\r\n this.logDebug(this.loadExternalUrl.name, 'launching external url', [event, externalUrlSettingName]);\r\n // Get the setting and launch the url in a new tab\r\n let url: OptixSettingModel | TenantSettingModel | AssetSettingModel | undefined;\r\n if (this.asset !== undefined) {\r\n url = this.asset?.assetSettingModels.find(e => e.name === externalUrlSettingName) ?? url;\r\n }\r\n else if (this.tenant !== undefined ) {\r\n url = this.tenant?.tenantSettingModels.find(e => e.name === externalUrlSettingName) ?? url;\r\n } else {\r\n // get all the tenants of the user\r\n let tenants = this.appOktaSessionService.sessionState().tenants;\r\n // find the first tenant with a link to the user manual\r\n for (let tenant of tenants) {\r\n let userManualUrl = tenant.tenantSettingModels.find(e => e.name === OptixSettingName.UserManualUrl);\r\n if (userManualUrl != undefined) {\r\n url = userManualUrl;\r\n break;\r\n }\r\n }\r\n }\r\n if (url)\r\n window.open(url.value, '_blank');\r\n }\r\n}","@if (isSmallMediumScreen) {\r\n \r\n \r\n \r\n \r\n \r\n \r\n}\r\n@else {\r\n \r\n \r\n \r\n \r\n \r\n \r\n}\r\n","import { AfterViewInit, Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core';\r\nimport { MenuItem } from 'primeng/api';\r\nimport { TenantModel } from '../../models/global/clients/tenant-model';\r\nimport { AssetModel } from '../../models/tenant/location/asset-model';\r\nimport { MenuService } from '../../services/session/menu/menu.service';\r\nimport { OptixComponentBase } from '../../utils/base-components/optix-component-base';\r\nimport { ScreenService } from '../../services/screen.service';\r\nimport { BreakpointState } from '@angular/cdk/layout';\r\n\r\n@Component({\r\n templateUrl: './menu.component.html',\r\n selector: 'menu-bar'\r\n})\r\nexport class MenuComponent extends OptixComponentBase implements OnChanges, AfterViewInit {\r\n \r\n @Input() menuVisible: boolean;\r\n @Output() menuVisibleChange: EventEmitter = new EventEmitter();\r\n\r\n @Input() tenant?: TenantModel;\r\n @Input() asset?: AssetModel;\r\n \r\n public menuItems!: MenuItem[];\r\n\r\n public isSmallMediumScreen: boolean = false;\r\n \r\n constructor(private menuService: MenuService, private screenService: ScreenService) {\r\n super();\r\n this.menuVisible = false;\r\n }\r\n \r\n ngOnChanges(changes: SimpleChanges): void {\r\n this.logDebug(this.ngOnChanges.name, 'Entering...', [changes]);\r\n // If the tenant or asset has changed, refresh the menu\r\n if (changes['tenant'] || changes['asset']) {\r\n this.logInfo(this.ngOnChanges.name, 'Refreshing menu after change to tenant or asset', [changes]);\r\n this.menuItems = this.menuService.getMenuItems(() => { this.onMenuItemSelected(); });\r\n }\r\n this.logDebug(this.ngOnChanges.name, 'Leaving...');\r\n }\r\n\r\n ngAfterViewInit(): void {\r\n this.logDebug(this.ngAfterViewInit.name, 'Entering...');\r\n // Subscribe to if the screen size changes\r\n this.screenService.isBelowLg().subscribe((result: BreakpointState) => {\r\n this.isSmallMediumScreen = result.matches;\r\n });\r\n this.logDebug(this.ngAfterViewInit.name, 'Leaving...');\r\n }\r\n\r\n public onMenuItemSelected(): void {\r\n this.logDebug(this.onMenuItemSelected.name, 'Entering...');\r\n if (this.isSmallMediumScreen) {\r\n this.onHideSideBar();\r\n }\r\n this.logDebug(this.onMenuItemSelected.name, 'Leaving...');\r\n }\r\n \r\n public onHideSideBar(): void {\r\n this.logDebug(this.onHideSideBar.name, 'Entering...');\r\n this.menuVisible = false;\r\n this.menuVisibleChange.emit(this.menuVisible);\r\n // Animate the main content to the left\r\n this.screenService.removeMarginForMenuPanel();\r\n this.logDebug(this.onHideSideBar.name, 'Leaving....');\r\n }\r\n}\r\n","
\r\n
\r\n \r\n
\r\n\r\n
\r\n \r\n
\r\n\r\n
\r\n \r\n \r\n
\r\n\r\n
\r\n \r\n \"{{sessionInfo.currentTenant.name}}\"\r\n \r\n \r\n
\r\n
1\">\r\n \r\n \r\n

{{asset.name}}

{{asset.timezoneModel.name}}\r\n
\r\n \r\n

{{assetOption.name}}

{{assetOption.timezoneModel?.name}}\r\n
\r\n
\r\n
\r\n
\r\n

{{asset.name}}

{{asset.timezoneModel.name}}\r\n
\r\n
\r\n
\r\n\r\n
\r\n \r\n
\r\n
\r\n\r\n\r\n\r\n\r\n

\r\n Please click the links to view the policies and terms. Once all have been viewed, you may accept.\r\n

\r\n

\r\n Privacy Policy\r\n

\r\n

\r\n Cookies Policy\r\n

\r\n

\r\n Terms of Use\r\n

\r\n \r\n \r\n \r\n \r\n
","import { AfterViewInit, Component, EventEmitter, Input, OnInit, Output } from '@angular/core';\r\nimport { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';\r\nimport { Router } from '@angular/router';\r\nimport { MenuItem } from 'primeng/api';\r\nimport { TenantModel } from '../../models/global/clients/tenant-model';\r\nimport { AssetModel } from '../../models/tenant/location/asset-model';\r\nimport { UserService } from '../../services/global/clients/user.service';\r\nimport { ImpersonationService } from '../../services/session/impersonation.service';\r\nimport { AppComponentBase } from '../../utils/base-components/app-component-base';\r\nimport { ScreenService } from '../../services/screen.service';\r\nimport { BreakpointState } from '@angular/cdk/layout';\r\n\r\n@Component({\r\n templateUrl: './app-header.component.html',\r\n selector: 'app-header'\r\n})\r\nexport class AppHeaderComponent extends AppComponentBase implements OnInit, AfterViewInit {\r\n\r\n tenantCount: number = 0;\r\n asset: AssetModel | undefined;\r\n tenantAssets: AssetModel[] = [];\r\n\r\n public username: string = '';\r\n public items: MenuItem[] = [];\r\n public impersonationSession: boolean = false;\r\n public impersonationSessonEndTime!: Date;\r\n\r\n @Input() menuVisible: boolean = false;\r\n @Output() menuVisibleChange: EventEmitter = new EventEmitter();\r\n\r\n public displayTermsDialog: boolean = false;\r\n public privacyViewed: boolean = false;\r\n public cookiesViewed: boolean = false;\r\n public termsViewed: boolean = false;\r\n public currentTenant: TenantModel | undefined;\r\n public navigationProperties: string[] = [\"\"];\r\n public assetCount : number = 0;\r\n\r\n public isSmallMediumScreen: boolean = false;\r\n\r\n constructor(private sanitizer: DomSanitizer, private router: Router, private userService: UserService, \r\n private impersonationService: ImpersonationService, private screenService: ScreenService) {\r\n super();\r\n\r\n this.items = [\r\n { \r\n label: 'Theme', \r\n icon: 'pi pi-palette', \r\n id: 'theme-menu',\r\n items: [\r\n { label: 'Dark', command: () => { this.toggleTheme('default'); } },\r\n { label: 'Light', command: () => { this.toggleTheme('light'); } },\r\n { label: 'Blue', command: () => { this.toggleTheme('blue'); } },\r\n ]\r\n },\r\n { separator: true },\r\n { label: 'Logout', icon: 'pi pi-sign-out', command: () => { this.logout(); } }\r\n ];\r\n }\r\n\r\n public override ngOnInit(): void {\r\n super.ngOnInit();\r\n\r\n let sessionSubscription = this.appOktaSessionService.sessionState$().subscribe(s => {\r\n this.sessionInfo = s;\r\n this.setThemeFromSession();\r\n this.loadPageData();\r\n });\r\n this.sessionStateSubscription.add(sessionSubscription);\r\n }\r\n\r\n ngAfterViewInit(): void {\r\n this.logDebug(this.ngAfterViewInit.name, 'Entering...');\r\n // Subscribe to if the screen size changes\r\n this.screenService.isBelowLg().subscribe((result: BreakpointState) => {\r\n this.isSmallMediumScreen = result.matches;\r\n if (!this.isSmallMediumScreen) {\r\n this.handleShowMenu();\r\n }\r\n });\r\n this.logDebug(this.ngAfterViewInit.name, 'Leaving...');\r\n }\r\n\r\n public override loadPageData(): void {\r\n // Get the session info\r\n this.tenantCount = ((this.sessionInfo.tenants) ? this.sessionInfo.tenants.length : 0);\r\n this.currentTenant = this.sessionInfo.currentTenant;\r\n\t\tthis.navigationProperties = ['main', this.currentTenant == null ? '' : this.currentTenant.tenancyName, 'dashboard'];\r\n this.assetCount = this.sessionInfo.assets.length;\r\n\r\n if (this.sessionInfo.isAuthenticated) {\r\n this.username = `${this.sessionInfo.firstname ?? ''} ${this.sessionInfo.lastname ?? ''}`;\r\n this.displayTermsDialog = (this.username.trim() !== '') && !this.sessionInfo.hasAcceptedPrivacy;\r\n this.impersonationSession = this.sessionInfo.originalUserSessionState !== undefined;\r\n\r\n // Change the username text if the user is impersonating another user\r\n if (this.sessionInfo.originalUserSessionState) {\r\n this.username = `${this.sessionInfo.originalUserSessionState.firstname ?? ''} ${this.sessionInfo.originalUserSessionState.lastname ?? ''} as ${this.sessionInfo.firstname ?? ''} ${this.sessionInfo.lastname ?? ''}`;\r\n this.impersonationSessonEndTime = this.sessionInfo.tokenExpiry;\r\n // Since the session is being impersonated, add an option to return to original session\r\n if (this.items.findIndex(e => e.label === 'End Impersonation') === -1) {\r\n this.items.push({ separator: true });\r\n this.items.push({ label: 'End Impersonation', icon: 'pi pi-power-off', command: () => { this.endImpersonation(); } });\r\n }\r\n }\r\n else {\r\n // Remove the end impersonation options from the menu if present\r\n if (this.items.length > 3) {\r\n this.items.splice(3, 2);\r\n }\r\n }\r\n }\r\n\r\n this.tenantAssets = this.sessionInfo.assets ?? [];\r\n this.asset = this.sessionInfo.currentAsset;\r\n }\r\n\r\n public handleShowMenu() {\r\n // If the screen is large, animate the main content to the right\r\n if (!this.isSmallMediumScreen) {\r\n this.screenService.applyMarginForMenuPanel();\r\n }\r\n // Show the menu\r\n this.menuVisible = true;\r\n this.menuVisibleChange.emit(this.menuVisible);\r\n }\r\n\r\n public getSafeLogo(tenant: TenantModel): SafeResourceUrl {\r\n return this.sanitizer.bypassSecurityTrustResourceUrl(\"data:\" + tenant.logoFileType + \";base64, \" + tenant.logo);\r\n }\r\n\r\n public logout() {\r\n //this.appSessionService.logout(this.document.location.origin);\r\n this.appOktaSessionService.logout();\r\n }\r\n\r\n public onAssetChange() {\r\n this.logDebug(this.onAssetChange.name, 'asset selection changed', [this.asset]);\r\n if (this.asset !== undefined) {\r\n var currentAsset = this.appOktaSessionService.sessionState().currentAsset;\r\n var assetName = currentAsset?.name;\r\n assetName = assetName?.replace(' ', '%20');\r\n // Set the router reuse strategy to ensure the page gets reloaded, otherwise Angular gets too smart\r\n // for itself and realises that just the asset param has changed in the route and doesn't reinitialise\r\n // the page/component\r\n this.router.routeReuseStrategy.shouldReuseRoute = function () {\r\n return false;\r\n }\r\n //this.router.onSameUrlNavigation = 'reload';\r\n \r\n this.router.navigateByUrl(this.router.url.replace(assetName ?? '', this.asset.name), { onSameUrlNavigation: 'reload' });\r\n }\r\n }\r\n\r\n public acceptedTermsAndPrivacy(): void {\r\n this.logDebug(this.acceptedTermsAndPrivacy.name, 'accepting terms and privacy');\r\n // Accept the terms and privacy\r\n if (this.privacyViewed && this.cookiesViewed && this.termsViewed) {\r\n this.userService.acceptTermsAndPrivacy().subscribe({\r\n next: (response) => {\r\n // Update the session state with the acceptance\r\n this.appOktaSessionService.setAcceptTermsAndPrivacy();\r\n this.displayTermsDialog = false;\r\n },\r\n });\r\n }\r\n }\r\n\r\n public endImpersonation(): void {\r\n this.logDebug(this.endImpersonation.name, 'ending impersonation');\r\n this.impersonationService.endImpersonationSession();\r\n }\r\n\r\n public toggleTheme(theme: string): void {\r\n this.logDebug(this.toggleTheme.name, 'changing theme', [theme]);\r\n this.spinner.show();\r\n // Update the theme\r\n this.userService.updateUserTheme(theme).subscribe({\r\n next: (response) => {\r\n // Update the application theme\r\n this.appOktaSessionService.setTheme(theme);\r\n this.spinner.hide();\r\n },\r\n });\r\n }\r\n \r\n public setThemeFromSession(): void {\r\n this.logDebug(this.setThemeFromSession.name, 'changing theme');\r\n // Update the application theme\r\n this.themeService.switchTheme(this.sessionInfo.theme);\r\n }\r\n}\r\n","\r\n\r\n\r\n\r\n\r\n
\r\n \r\n
\r\n\r\n\r\n\r\n\r\n\r\n \r\n
\r\n
\r\n \r\n

{{message.summary}}

\r\n

{{message.detail}}

\r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n
\r\n
","import { Component, Inject, OnInit } from '@angular/core';\r\nimport { PrimeNGConfig } from 'primeng/api';\r\nimport { OptixComponentBase } from './core/utils/base-components/optix-component-base';\r\nimport { LogUpdateService } from './core/services/service-worker/log-update.service';\r\nimport { PromptUpdateService } from './core/services/service-worker/prompt-update.service';\r\nimport { OKTA_AUTH, OktaAuthStateService } from '@okta/okta-angular';\r\nimport OktaAuth, { AuthState } from '@okta/okta-auth-js';\r\nimport { Observable, filter, lastValueFrom, map } from 'rxjs';\r\n\r\n@Component({\r\n selector: 'app-root',\r\n templateUrl: './app.component.html'\r\n})\r\nexport class AppComponent extends OptixComponentBase implements OnInit {\r\n title = 'optix 2';\r\n\r\n constructor(private primengConfig: PrimeNGConfig, private logUpdateService: LogUpdateService, private promptUpdateService: PromptUpdateService) {\r\n super();\r\n this.logDebug(this.constructor.name, 'loaded');\r\n }\r\n\r\n public ngOnInit(): void {\r\n this.primengConfig.ripple = true;\r\n this.logDebug(this.ngOnInit.name, 'loaded');\r\n }\r\n\r\n public reloadApp(): void {\r\n\t\t// Reload the page to update to the latest version.\r\n\t\tdocument.location.reload();\r\n }\r\n}\r\n","import { CommonModule } from '@angular/common';\r\nimport { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';\r\nimport { BrowserModule } from '@angular/platform-browser';\r\nimport { BrowserAnimationsModule } from '@angular/platform-browser/animations';\r\nimport { MessageModule } from 'primeng/message';\r\nimport { MessagesModule } from 'primeng/messages';\r\nimport { CookieComponent } from './pages/cookie/cookie.component';\r\nimport { FatalExceptionComponent } from './pages/fatal-exception/fatal-exception.component';\r\nimport { PageNotFoundComponent } from './pages/page-not-found/page-not-found.component';\r\nimport { TermsComponent } from './pages/terms/terms.component';\r\nimport { UnauthorisedComponent } from './pages/unauthorised/unauthorised.component';\r\nimport { ForbiddenPage } from './pages/forbidden/forbidden.page';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { ButtonModule } from 'primeng/button';\r\nimport { InputTextModule } from 'primeng/inputtext';\r\nimport { InputTextareaModule } from 'primeng/inputtextarea';\r\nimport { ToastModule } from 'primeng/toast';\r\nimport { CardModule } from 'primeng/card';\r\n\r\n@NgModule({\r\n declarations: [\r\n CookieComponent,\r\n FatalExceptionComponent,\r\n PageNotFoundComponent,\r\n TermsComponent,\r\n UnauthorisedComponent,\r\n ForbiddenPage\r\n ],\r\n imports: [\r\n CommonModule,\r\n BrowserModule,\r\n BrowserAnimationsModule,\r\n MessageModule,\r\n MessagesModule,\r\n FormsModule,\r\n ButtonModule,\r\n InputTextModule,\r\n InputTextareaModule,\r\n ToastModule,\r\n CardModule\r\n ],\r\n providers: [],\r\n exports: [\r\n MessageModule,\r\n MessagesModule\r\n ],\r\n schemas: [ CUSTOM_ELEMENTS_SCHEMA ]\r\n})\r\nexport class HomeModule {}\r\n","import { HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';\r\nimport { Injectable } from '@angular/core';\r\nimport { Router } from '@angular/router';\r\nimport { empty, Observable, throwError } from 'rxjs';\r\nimport { catchError, finalize } from 'rxjs/operators';\r\nimport Swal from 'sweetalert2';\r\nimport { AppSpinnerComponent } from '../../components/app-spinner/app-spinner.component';\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class ErrorInterceptor implements HttpInterceptor {\r\n\r\n constructor(public router: Router, private spinner: AppSpinnerComponent) { }\r\n\r\n /**\r\n * The HTTP Interceptor\r\n */\r\n intercept(req: HttpRequest, next: HttpHandler): Observable> {\r\n // Add the error handler to the request\r\n return next.handle(req)\r\n //.pipe(finalize(() => this.spinner.hide()))\r\n .pipe(\r\n catchError((error: HttpErrorResponse) => {\r\n let errorMsg = '';\r\n if (error.error instanceof ErrorEvent) {\r\n console.log('This is client side error');\r\n errorMsg = `Error: ${error.error.message}`;\r\n } else {\r\n console.log('This is server side error');\r\n errorMsg = `Error Code: ${error.status}, Message: ${error.error}`;\r\n\r\n if (error.status === 403) {\r\n // Request was forbidden.\r\n console.error('Forbidden request.');\r\n let urlSections = req.url.split('/');\r\n Swal.fire('Forbidden', `You are not authorised to access ${urlSections[urlSections.length - 1]}.`, 'error');\r\n }\r\n }\r\n console.log(errorMsg);\r\n return throwError(error);\r\n })\r\n );\r\n }\r\n}","import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';\r\nimport { Inject, Injectable, inject } from '@angular/core';\r\nimport { EMPTY, Observable, throwError } from 'rxjs';\r\nimport { catchError, switchMap } from 'rxjs/operators';\r\nimport { AppSpinnerComponent } from '../../components/app-spinner/app-spinner.component';\r\nimport { ImpersonationService } from '../../services/session/impersonation.service';\r\nimport { SessionTokenService } from '../../services/session/token/session-token.service';\r\nimport Swal from 'sweetalert2';\r\nimport { DOCUMENT } from '@angular/common';\r\nimport { AppOktaSessionService } from '../../services/session/app-okta-session.service';\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class AuthInterceptor implements HttpInterceptor {\r\n\r\n private appOktaSessionService: AppOktaSessionService = inject(AppOktaSessionService);\r\n\r\n constructor(private tokenService: SessionTokenService, private impersonationService: ImpersonationService, \r\n private spinner: AppSpinnerComponent) { }\r\n\r\n /**\r\n * The HTTP Interceptor\r\n */\r\n intercept(req: HttpRequest, next: HttpHandler): Observable> {\r\n \r\n // If the request is to the authentication endpoint, skip adding the header\r\n if (req.url.includes('auth'))\r\n return next.handle(req);\r\n\r\n // Get the token and add it to the request\r\n //let session = this.appOktaSessionService.sessionState();\r\n let session = this.appOktaSessionService.sessionState();\r\n if (session.tokenExpiry && session.tokenExpiry < new Date()) {\r\n // If the session has been impersonated, end the session since it has expired\r\n if (session.originalUserSessionState) {\r\n this.impersonationService.endImpersonationSession();\r\n return EMPTY;\r\n }\r\n else {\r\n this.spinner.show();\r\n return this.tokenService.refreshAuthToken(session.jsonWebToken ?? '', session.refreshToken ?? '')\r\n .pipe(\r\n catchError(err => {\r\n this.spinner.hide();\r\n console.error('AuthInterceptor-Internal API Server Error Occurred.', err);\r\n Swal.fire('Error', \"Your session could not be authorised, please log back in again.\", 'error', )\r\n .then(() => {\r\n //this.appSessionService.logout(this.document.location.origin);\r\n this.appOktaSessionService.logout();\r\n });\r\n return throwError(() => { return err; });\r\n }),\r\n switchMap(newToken => {\r\n this.spinner.hide();\r\n this.appOktaSessionService.updateSessionFromNewToken(newToken, session.currentTenant, session.currentAsset);\r\n return next.handle(this.addToken(req, newToken.token));\r\n })\r\n );\r\n }\r\n }\r\n \r\n\r\n return next.handle(this.addToken(req, session.jsonWebToken));\r\n }\r\n \r\n /**\r\n * Adds the bearer token header to the request\r\n * @param req The HTTP request being made.\r\n * @param token The token to be added to the header.\r\n * @returns The HTTP request with the header set.\r\n */\r\n private addToken(req: HttpRequest, token?: string): HttpRequest {\r\n return req.clone({ setHeaders: { Authorization: 'Bearer ' + token }});\r\n }\r\n}","import { CommonModule } from '@angular/common';\r\nimport { CUSTOM_ELEMENTS_SCHEMA, NgModule, Optional, SkipSelf } from '@angular/core';\r\nimport { BrowserModule } from '@angular/platform-browser';\r\nimport { BrowserAnimationsModule } from '@angular/platform-browser/animations';\r\nimport { RouterModule } from '@angular/router';\r\nimport { NgxSpinnerModule } from 'ngx-spinner';\r\nimport { AvatarModule } from 'primeng/avatar';\r\nimport { MessageModule } from 'primeng/message';\r\nimport { MessagesModule } from 'primeng/messages';\r\nimport { CardModule } from 'primeng/card';\r\nimport { SidebarModule } from 'primeng/sidebar';\r\nimport { ButtonModule } from 'primeng/button';\r\nimport { PanelMenuModule } from 'primeng/panelmenu';\r\nimport { MenuModule } from 'primeng/menu';\r\nimport { AppSpinnerComponent } from './app-spinner/app-spinner.component';\r\nimport { AppFooterComponent } from './app-footer/app-footer.component';\r\nimport { AppHeaderComponent } from './app-header/app-header.component';\r\nimport { BrandComponent } from './brand/brand.component';\r\nimport { EnvironmentBannerComponent } from './environment-banner/environment-banner.component';\r\nimport { MenuComponent } from './app-menu/menu.component';\r\nimport { ConfirmationService, MessageService } from 'primeng/api';\r\nimport { DropdownModule } from 'primeng/dropdown';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { DialogModule } from 'primeng/dialog';\r\nimport { SplitButtonModule } from 'primeng/splitbutton';\r\nimport { InputSwitchModule } from 'primeng/inputswitch';\r\n\r\n@NgModule({\r\n declarations: [\r\n AppSpinnerComponent,\r\n BrandComponent,\r\n AppFooterComponent,\r\n AppHeaderComponent,\r\n EnvironmentBannerComponent,\r\n MenuComponent\r\n ],\r\n imports: [\r\n CommonModule,\r\n BrowserModule,\r\n BrowserAnimationsModule,\r\n NgxSpinnerModule,\r\n RouterModule,\r\n FormsModule,\r\n AvatarModule,\r\n MessageModule,\r\n MessagesModule,\r\n CardModule,\r\n SidebarModule,\r\n ButtonModule,\r\n PanelMenuModule,\r\n MenuModule,\r\n DropdownModule,\r\n DialogModule,\r\n SplitButtonModule,\r\n InputSwitchModule\r\n ],\r\n providers: [\r\n ConfirmationService,\r\n MessageService\r\n ],\r\n exports: [\r\n AppSpinnerComponent,\r\n AppFooterComponent,\r\n AppHeaderComponent,\r\n MenuComponent\r\n ],\r\n schemas: [ CUSTOM_ELEMENTS_SCHEMA ]\r\n})\r\nexport class CoreComponentsModule {\r\n constructor(@Optional() @SkipSelf() parentModule: CoreComponentsModule) {\r\n if (parentModule) {\r\n throw new Error(`${parentModule} has already been loaded. Import Core module in the AppModule only.`);\r\n }\r\n }\r\n}\r\n","import { NgModule, CUSTOM_ELEMENTS_SCHEMA, ErrorHandler } from '@angular/core';\r\nimport { BrowserModule } from '@angular/platform-browser';\r\nimport { BrowserAnimationsModule } from '@angular/platform-browser/animations';\r\nimport { AppRoutingModule } from './app-routing.module';\r\nimport { AppComponent } from './app.component';\r\nimport { ServiceWorkerModule } from '@angular/service-worker';\r\nimport { environment } from '../environments/environment';\r\nimport { RaygunErrorHandler } from './app-config/app.raygun.setup';\r\nimport { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';\r\nimport { CommonModule } from '@angular/common';\r\nimport { AppInitialiserComponent } from './app-initialiser.component';\r\nimport { SharedModule } from 'primeng/api';\r\nimport { HomeModule } from './modules/home/home.module';\r\nimport { ErrorInterceptor } from './core/utils/interceptors/error-interceptor';\r\nimport { AuthInterceptor } from './core/utils/interceptors/auth-interceptor';\r\nimport { CoreComponentsModule } from './core/components/core-components.module';\r\nimport { TitleStrategy } from '@angular/router';\r\nimport { AppTitleBuilder } from './core/utils/title-strategy/app-title-builder.strategy';\r\nimport { LogUpdateService } from './core/services/service-worker/log-update.service';\r\nimport { PromptUpdateService } from './core/services/service-worker/prompt-update.service';\r\nimport { ToastModule } from 'primeng/toast';\r\nimport { ButtonModule } from 'primeng/button';\r\nimport OktaAuth from '@okta/okta-auth-js';\r\nimport { OktaAuthModule } from '@okta/okta-angular';\r\n\r\n/**\r\n * Okta Authentication Configuration\r\n */\r\nconst oktaAuth = new OktaAuth(environment.okta);\r\n\r\n@NgModule({\r\n declarations: [\r\n AppComponent,\r\n AppInitialiserComponent\r\n ],\r\n imports: [\r\n CommonModule,\r\n BrowserModule,\r\n BrowserAnimationsModule,\r\n HttpClientModule,\r\n // Main App Routing Module\r\n AppRoutingModule,\r\n // Okta Auth Module\r\n OktaAuthModule.forRoot({ oktaAuth }),\r\n // PrimeNG Shared Module\r\n SharedModule,\r\n // PWA Service Wroker\r\n ServiceWorkerModule.register('ngsw-worker.js', {\r\n // Only Enable the service worker when the app is not in local dev\r\n // mode, we don't want the service worker interupting local development\r\n // see the readme for instructions on enabling the service worker\r\n enabled: (environment.mode !== 'local'),\r\n //enabled: true,\r\n // Register the ServiceWorker as soon as the app is stable\r\n // or after 30 seconds (whichever comes first).\r\n registrationStrategy: 'registerWhenStable:30000'\r\n }),\r\n // Optix Core Components Module\r\n CoreComponentsModule,\r\n // Optix Home Module\r\n HomeModule,\r\n //PrimeNg Modules\r\n ToastModule,\r\n ButtonModule\r\n ],\r\n providers: [\r\n HttpClientModule,\r\n // Optix HTTP Request Interceptors\r\n { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },\r\n //{ provide: HTTP_INTERCEPTORS, useClass: SpinnerInterceptor, multi: true },\r\n { provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true },\r\n // Raygun Error Catcher\r\n //{ provide: ErrorHandler, useClass: RaygunErrorHandler },\r\n //{ provide: TitleStrategy, useClass: AppTitleBuilder },\r\n // Service Worker Helpers\r\n LogUpdateService,\r\n PromptUpdateService\r\n ],\r\n bootstrap: [AppComponent],\r\n schemas: [ CUSTOM_ELEMENTS_SCHEMA ]\r\n})\r\nexport class AppModule { }\r\n","import { enableProdMode } from '@angular/core';\r\nimport { platformBrowserDynamic } from '@angular/platform-browser-dynamic';\r\n\r\nimport { AppModule } from './app/app.module';\r\nimport { environment } from './environments/environment';\r\n\r\nif (environment.production) {\r\n enableProdMode();\r\n}\r\n\r\nplatformBrowserDynamic().bootstrapModule(AppModule)\r\n .catch(err => console.error(err));\r\n"],"x_google_ignoreList":[]}