{"version":3,"sources":["../src/strategies/standard-authorization-url.strategy.ts","../src/strategies/standard-token-exchange.strategy.ts","../src/providers/base.provider.ts","../src/providers/generic.provider.ts","../src/profile/base-profile-fetcher.ts","../src/profile/google-profile-fetcher.ts","../src/profile/github-profile-fetcher.ts","../src/profile/microsoft-profile-fetcher.ts","../src/profile/generic-profile-fetcher.ts","../src/profile/profile-fetcher-factory.ts","../src/providers/provider.factory.ts","../src/storage/memory.adapter.ts","../src/utils/crypto.ts","../src/facade/oauth2.facade.ts","../src/utils/seal.ts"],"names":["StandardAuthorizationUrlStrategy","params","value","key","config","state","codeChallenge","extraParams","StandardTokenExchangeStrategy","code","codeVerifier","response","errorText","data","tokenData","refreshToken","rawResponse","refreshTokenFallback","_a","_b","_c","_d","_e","now","accessToken","rawRefreshToken","rawExpiresIn","expiresInSeconds","scope","tokenType","obj","customPaths","defaultPaths","paths","path","keys","current","OAuth2Provider","authUrlStrategy","tokenStrategy","profileFetcher","GenericOAuth2Provider","BaseProfileFetcher","profileEndpoint","rawData","GoogleProfileFetcher","GitHubProfileFetcher","MicrosoftProfileFetcher","GenericProfileFetcher","mapping","additionalHeaders","ProfileFetcherFactory","providerType","options","customFetcher","profileUrl","providerName","OAuth2ProviderFactory","_OAuth2ProviderFactory","type","customProfileFetcher","presetConfig","mergedConfig","name","InMemoryStorageAdapter","input","existingToken","updatedToken","newToken","query","tokens","t","provider","email","tenant","id","userId","update","token","expiredTokens","newState","maxAge","expiredStates","fetcher","createCodeVerifier","randomBytes","createCodeChallenge","verifier","createHash","generateState","OAuth2Client","authUrl","authState","providerInstance","tenantName","profile","error","savedToken","storedToken","tenantInfo","queryWithExpired","expirationBuffer","expiresAt","s","refreshPromises","bufferMs","shouldRefreshAt","tenants","seal","d","sealData","unseal","unsealData"],"mappings":"8EAGO,IAAMA,CAAAA,CAAN,KAA2E,CACtE,cAAA,CAAeC,EAAoD,CAM3E,OALiB,OAAO,OAAA,CAAQA,CAAM,EACnC,MAAA,CAAO,CAAC,EAAGC,CAAK,IAAMA,CAAAA,GAAU,MAAS,CAAA,CAEzC,GAAA,CAAI,CAAC,CAACC,EAAKD,CAAK,CAAA,GAAM,GAAGC,CAAG,CAAA,CAAA,EAAI,mBAAmBD,CAAe,CAAC,EAAE,CAAA,CAExD,IAAA,CAAK,GAAG,CAC1B,CAEA,yBAAyBE,CAAAA,CAAsBC,CAAAA,CAAeC,EAAgC,CAC5F,IAAML,CAAAA,CAA6C,CACjD,SAAA,CAAWG,CAAAA,CAAO,SAClB,YAAA,CAAcA,CAAAA,CAAO,YACrB,aAAA,CAAe,MAAA,CACf,MAAOA,CAAAA,CAAO,MAAA,CAAO,KAAK,GAAG,CAAA,CAC7B,MAAAC,CACF,CAAA,CAAA,CAGKD,EAAO,OAAA,EAAWA,CAAAA,CAAO,OAASE,CAAAA,GACrCL,CAAAA,CAAO,cAAA,CAAiBK,CAAAA,CACxBL,CAAAA,CAAO,qBAAA,CAAwB,QAIjC,IAAMM,CAAAA,CAAc,CAClB,GAAGH,CAAAA,CAAO,iBACV,GAAGA,CAAAA,CAAO,eACZ,CAAA,CAEA,OAAA,MAAA,CAAO,OAAOH,CAAAA,CAAQM,CAAW,EAE1B,CAAA,EAAGH,CAAAA,CAAO,gBAAgB,CAAA,CAAA,EAAI,IAAA,CAAK,cAAA,CAAeH,CAAM,CAAC,CAAA,CAClE,CACF,ECnCO,IAAMO,EAAN,KAAqE,CAChE,eAAeP,CAAAA,CAAoD,CAK3E,OAJiB,MAAA,CAAO,OAAA,CAAQA,CAAM,CAAA,CACnC,MAAA,CAAO,CAAC,EAAGC,CAAK,CAAA,GAAMA,CAAAA,GAAU,MAAS,CAAA,CACzC,GAAA,CAAI,CAAC,CAACC,CAAAA,CAAKD,CAAK,IAAM,CAAA,EAAGC,CAAG,IAAI,kBAAA,CAAmBD,CAAe,CAAC,CAAA,CAAE,CAAA,CAExD,KAAK,GAAG,CAC1B,CAEA,MAAM,oBAAA,CACJO,EACAL,CAAAA,CACAM,CAAAA,CACsB,CACtB,IAAMT,CAAAA,CAA6C,CACjD,WAAY,oBAAA,CACZ,IAAA,CAAAQ,EACA,YAAA,CAAcL,CAAAA,CAAO,YACrB,SAAA,CAAWA,CAAAA,CAAO,QACpB,CAAA,CAAA,CAGKA,CAAAA,CAAO,SAAWA,CAAAA,CAAO,IAAA,GAASM,EACrCT,CAAAA,CAAO,aAAA,CAAgBS,EACdN,CAAAA,CAAO,YAAA,GAChBH,CAAAA,CAAO,aAAA,CAAgBG,CAAAA,CAAO,YAAA,CAAA,CAGhC,IAAMO,CAAAA,CAAW,MAAM,MAAMP,CAAAA,CAAO,QAAA,CAAU,CAC5C,MAAA,CAAQ,MAAA,CACR,OAAA,CAAS,CACP,cAAA,CAAgB,mCAClB,EACA,IAAA,CAAM,IAAA,CAAK,eAAeH,CAAM,CAClC,CAAC,CAAA,CAED,GAAI,CAACU,CAAAA,CAAS,EAAA,CAAI,CAChB,IAAMC,CAAAA,CAAY,MAAMD,EAAS,IAAA,EAAK,CACtC,MAAM,IAAI,KAAA,CAAM,0BAA0BA,CAAAA,CAAS,UAAU,MAAMC,CAAS,CAAA,CAAE,CAChF,CAEA,IAAMC,EAAO,MAAMF,CAAAA,CAAS,IAAA,EAAK,CAG3BG,CAAAA,CAAYV,CAAAA,CAAO,gBAAkBS,CAAAA,CAAKT,CAAAA,CAAO,eAAe,CAAA,CAAIS,CAAAA,CAE1E,OAAO,IAAA,CAAK,sBAAA,CAAuBC,EAAWD,CAAAA,CAAM,MAAA,CAAWT,CAAM,CACvE,CAEA,MAAM,YAAA,CAAaW,CAAAA,CAAsBX,EAA4C,CACnF,IAAMH,CAAAA,CAA6C,CACjD,UAAA,CAAY,eAAA,CACZ,cAAec,CAAAA,CACf,SAAA,CAAWX,EAAO,QACpB,CAAA,CAGI,EAAEA,CAAAA,CAAO,OAAA,EAAWA,EAAO,IAAA,CAAA,EAASA,CAAAA,CAAO,eAC7CH,CAAAA,CAAO,aAAA,CAAgBG,EAAO,YAAA,CAAA,CAGhC,IAAMO,EAAW,MAAM,KAAA,CAAMP,CAAAA,CAAO,QAAA,CAAU,CAC5C,MAAA,CAAQ,OACR,OAAA,CAAS,CACP,eAAgB,mCAClB,CAAA,CACA,KAAM,IAAA,CAAK,cAAA,CAAeH,CAAM,CAClC,CAAC,CAAA,CAED,GAAI,CAACU,CAAAA,CAAS,GAAI,CAChB,IAAMC,EAAY,MAAMD,CAAAA,CAAS,IAAA,EAAK,CACtC,MAAM,IAAI,MAAM,CAAA,sBAAA,EAAyBA,CAAAA,CAAS,UAAU,CAAA,GAAA,EAAMC,CAAS,EAAE,CAC/E,CAEA,IAAMC,CAAAA,CAAO,MAAMF,EAAS,IAAA,EAAK,CAC3BG,EAAYV,CAAAA,CAAO,eAAA,CAAkBS,EAAKT,CAAAA,CAAO,eAAe,CAAA,CAAIS,CAAAA,CAE1E,OAAO,IAAA,CAAK,uBAAuBC,CAAAA,CAAWD,CAAAA,CAAME,EAAcX,CAAM,CAC1E,CAEU,sBAAA,CACRU,CAAAA,CACAE,EACAC,CAAAA,CACAb,CAAAA,CACa,CAxFjB,IAAAc,CAAAA,CAAAC,EAAAC,CAAAA,CAAAC,CAAAA,CAAAC,EAyFI,IAAMC,CAAAA,CAAM,IAAA,CAAK,GAAA,EAAI,CAGfC,CAAAA,CAAc,KAAK,YAAA,CACvBV,CAAAA,CAAAA,CACAI,EAAAd,CAAAA,EAAA,IAAA,CAAA,MAAA,CAAAA,EAAQ,UAAA,GAAR,IAAA,CAAA,MAAA,CAAAc,EAAoB,WAAA,CAGpB,CACE,2BACA,yBAAA,CACA,cAAA,CACA,cACA,oBAAA,CACA,mBACF,CACF,CAAA,CAEA,GAAI,CAACM,CAAAA,CACH,MAAM,IAAI,MAAM,gDAAgD,CAAA,CAGlE,IAAMC,CAAAA,CACJ,IAAA,CAAK,aAAaX,CAAAA,CAAAA,CAAWK,CAAAA,CAAAf,CAAAA,EAAA,IAAA,CAAA,MAAA,CAAAA,CAAAA,CAAQ,UAAA,GAAR,YAAAe,CAAAA,CAAoB,YAAA,CAAc,CAC7D,2BAAA,CACA,0BAAA,CACA,gBACA,cAAA,CACA,qBAAA,CACA,oBACF,CAAC,CAAA,EAAKF,CAAAA,CAEFS,EAAe,IAAA,CAAK,YAAA,CAAaZ,GAAWM,CAAAA,CAAAhB,CAAAA,EAAA,YAAAA,CAAAA,CAAQ,UAAA,GAAR,YAAAgB,CAAAA,CAAoB,SAAA,CAAW,CAC/E,wBAAA,CACA,uBAAA,CACA,aACA,WAAA,CACA,kBAAA,CACA,iBACF,CAAC,CAAA,CAKKO,CAAAA,CAAAA,CAFJ,OAAOD,CAAAA,EAAiB,QAAA,CAAW,SAASA,CAAAA,CAAc,EAAE,EAAIA,CAAAA,GAEtB,IAAA,CAEtCE,EAAQ,IAAA,CAAK,YAAA,CAAad,GAAWO,CAAAA,CAAAjB,CAAAA,EAAA,YAAAA,CAAAA,CAAQ,UAAA,GAAR,YAAAiB,CAAAA,CAAoB,KAAA,CAAO,CACpE,mBAAA,CACA,OAAA,CACA,aACF,CAAC,CAAA,CAEKQ,CAAAA,CACJ,KAAK,YAAA,CAAaf,CAAAA,CAAAA,CAAWQ,EAAAlB,CAAAA,EAAA,IAAA,CAAA,MAAA,CAAAA,EAAQ,UAAA,GAAR,IAAA,CAAA,MAAA,CAAAkB,EAAoB,SAAA,CAAW,CAC1D,yBACA,uBAAA,CACA,YAAA,CACA,YACA,kBAAA,CACA,iBACF,CAAC,CAAA,EAAK,QAAA,CAER,OAAO,CACL,WAAA,CAAAE,CAAAA,CACA,aAAcC,CAAAA,CACd,SAAA,CAAW,IAAI,IAAA,CAAKF,CAAAA,CAAMI,EAAmB,GAAI,CAAA,CACjD,SAAA,CAAWA,CAAAA,CACX,SAAA,CAAAE,CAAAA,CACA,MAAAD,CAAAA,CACA,SAAA,CAAWL,EACX,GAAA,CAAKP,CACP,CACF,CASQ,YAAA,CACNc,CAAAA,CACAC,CAAAA,CACAC,CAAAA,CACK,CAEL,GAAID,CAAAA,CAAa,CACf,IAAME,CAAAA,CAAQ,KAAA,CAAM,QAAQF,CAAW,CAAA,CAAIA,EAAc,CAACA,CAAW,EACrE,IAAA,IAAWG,CAAAA,IAAQD,EAAO,CACxB,IAAM/B,EAAQ,IAAA,CAAK,cAAA,CAAe4B,CAAAA,CAAKI,CAAI,CAAA,CAC3C,GAAIhC,IAAU,MAAA,CAAW,OAAOA,CAClC,CACF,CAGA,GAAI8B,CAAAA,CACF,IAAA,IAAWE,KAAQF,CAAAA,CAAc,CAC/B,IAAM9B,CAAAA,CAAQ,IAAA,CAAK,eAAe4B,CAAAA,CAAKI,CAAI,EAC3C,GAAIhC,CAAAA,GAAU,MAAA,CAAW,OAAOA,CAClC,CAIJ,CAQQ,cAAA,CAAe4B,CAAAA,CAA0BI,EAAmB,CAClE,IAAMC,EAAOD,CAAAA,CAAK,KAAA,CAAM,GAAG,CAAA,CACvBE,CAAAA,CAAeN,EAEnB,IAAA,IAAW3B,CAAAA,IAAOgC,EAChB,GAAIC,CAAAA,EAAW,OAAOA,CAAAA,EAAY,QAAA,EAAYjC,CAAAA,IAAOiC,CAAAA,CACnDA,CAAAA,CAAUA,CAAAA,CAAQjC,CAAG,CAAA,CAAA,KAErB,OAIJ,OAAOiC,CACT,CACF,EChNO,IAAeC,CAAAA,CAAf,KAA8B,CAKnC,WAAA,CACYjC,CAAAA,CACVkC,EACAC,CAAAA,CACAC,CAAAA,CACA,CAJU,IAAA,CAAA,MAAA,CAAApC,CAAAA,CAKV,KAAK,eAAA,CAAkBkC,CAAAA,EAAmB,IAAA,CAAK,8BAAA,EAA+B,CAC9E,IAAA,CAAK,cAAgBC,CAAAA,EAAiB,IAAA,CAAK,6BAA4B,CACvE,IAAA,CAAK,eAAiBC,EACxB,CAbU,gBACA,aAAA,CACA,cAAA,CAkBV,MAAM,YAAA,CAAahB,CAAAA,CAA2C,CAC5D,GAAI,CAAC,KAAK,cAAA,CACR,MAAM,IAAI,KAAA,CAAM,kDAAkD,CAAA,CAEpE,OAAO,IAAA,CAAK,cAAA,CAAe,cAAcA,CAAW,CACtD,CAEA,kBAAA,EAA6B,CAC3B,GAAI,CAAC,IAAA,CAAK,eACR,MAAM,IAAI,MAAM,kDAAkD,CAAA,CAEpE,OAAO,IAAA,CAAK,cAAA,CAAe,WAAA,EAC7B,CAEA,iBAAA,CAAkBgB,EAA0C,CAC1D,IAAA,CAAK,eAAiBA,EACxB,CAEA,mBAA6B,CAC3B,OAAO,CAAC,CAAC,IAAA,CAAK,cAChB,CAEA,wBAAA,CAAyBnC,EAAeC,CAAAA,CAAgC,CACtE,OAAO,IAAA,CAAK,eAAA,CAAgB,wBAAA,CAAyB,IAAA,CAAK,MAAA,CAAQD,CAAAA,CAAOC,CAAa,CACxF,CAEA,MAAM,oBAAA,CAAqBG,CAAAA,CAAcC,EAA6C,CACpF,OAAO,IAAA,CAAK,aAAA,CAAc,oBAAA,CAAqBD,CAAAA,CAAM,KAAK,MAAA,CAAQC,CAAY,CAChF,CAEA,MAAM,aAAaK,CAAAA,CAA4C,CAC7D,OAAO,IAAA,CAAK,aAAA,CAAc,YAAA,CAAaA,EAAc,IAAA,CAAK,MAAM,CAClE,CACF,MCtDa0B,CAAAA,CAAN,cAAoCJ,CAAe,CACxD,WAAA,CACEjC,EACAkC,CAAAA,CACAC,CAAAA,CACAC,EACA,CACA,KAAA,CAAMpC,EAAQkC,CAAAA,CAAiBC,CAAAA,CAAeC,CAAc,EAC9D,CAEU,8BAAA,EAA2D,CACnE,OAAO,IAAIxC,CACb,CAEU,2BAAA,EAAqD,CAC7D,OAAO,IAAIQ,CACb,CACF,MCtBsBkC,CAAAA,CAAf,KAAkC,CACvC,WAAA,CAAsBC,CAAAA,CAAyB,CAAzB,IAAA,CAAA,eAAA,CAAAA,EAA0B,CAOhD,MAAM,aAAA,CAAcnB,CAAAA,CAA2C,CAC7D,IAAMb,CAAAA,CAAW,MAAM,KAAA,CAAM,IAAA,CAAK,gBAAiB,CACjD,OAAA,CAAS,CACP,aAAA,CAAe,CAAA,OAAA,EAAUa,CAAW,CAAA,CAAA,CACpC,MAAA,CAAQ,mBACR,GAAG,IAAA,CAAK,sBACV,CACF,CAAC,CAAA,CAED,GAAI,CAACb,EAAS,EAAA,CACZ,MAAM,IAAI,KAAA,CACR,CAAA,6BAAA,EAAgC,KAAK,eAAe,CAAA,EAAA,EAAKA,CAAAA,CAAS,UAAU,CAAA,CAC9E,CAAA,CAGF,IAAMiC,CAAAA,CAAU,MAAMjC,EAAS,IAAA,EAAK,CACpC,OAAO,IAAA,CAAK,gBAAA,CAAiBiC,CAAO,CACtC,CAcU,oBAAA,EAA+C,CACvD,OAAO,EACT,CAKA,WAAA,EAAsB,CACpB,OAAO,IAAA,CAAK,eACd,CACF,MChDaC,CAAAA,CAAN,cAAmCH,CAAmB,CAC3D,WAAA,EAAc,CACZ,KAAA,CAAM,+CAA+C,EACvD,CAEA,gBAAA,CAAiBE,CAAAA,CAA2B,CAC1C,OAAO,CACL,MAAOA,CAAAA,CAAQ,KAAA,CACf,KAAMA,CAAAA,CAAQ,IAAA,CACd,GAAIA,CAAAA,CAAQ,EAAA,CACZ,OAAQA,CAAAA,CAAQ,OAAA,CAChB,SAAUA,CAAAA,CAAQ,KAAA,CAClB,IAAKA,CACP,CACF,CACF,ECfO,IAAME,CAAAA,CAAN,cAAmCJ,CAAmB,CAC3D,aAAc,CACZ,KAAA,CAAM,6BAA6B,EACrC,CAEU,iBAAiBE,CAAAA,CAA2B,CARxD,IAAA1B,CAAAA,CASI,OAAO,CACL,KAAA,CAAO0B,CAAAA,CAAQ,MACf,IAAA,CAAMA,CAAAA,CAAQ,IAAA,EAAQA,CAAAA,CAAQ,KAAA,CAC9B,EAAA,CAAA,CAAI1B,EAAA0B,CAAAA,CAAQ,EAAA,GAAR,YAAA1B,CAAAA,CAAY,QAAA,EAAA,CAChB,OAAQ0B,CAAAA,CAAQ,UAAA,CAChB,QAAA,CAAUA,CAAAA,CAAQ,KAAA,CAClB,GAAA,CAAKA,CACP,CACF,CAEU,sBAA+C,CACvD,OAAO,CACL,YAAA,CAAc,sBAChB,CACF,CACF,ECrBO,IAAMG,EAAN,cAAsCL,CAAmB,CAC9D,WAAA,EAAc,CACZ,MAAM,qCAAqC,EAC7C,CAEU,gBAAA,CAAiBE,CAAAA,CAA2B,CACpD,OAAO,CACL,MAAOA,CAAAA,CAAQ,IAAA,EAAQA,EAAQ,iBAAA,CAC/B,IAAA,CAAMA,CAAAA,CAAQ,WAAA,CACd,EAAA,CAAIA,CAAAA,CAAQ,GACZ,MAAA,CAAQ,MAAA,CACR,SAAUA,CAAAA,CAAQ,iBAAA,CAClB,IAAKA,CACP,CACF,CACF,ECLO,IAAMI,EAAN,cAAoCN,CAAmB,CAC5D,WAAA,CACEC,CAAAA,CACQM,EACAC,CAAAA,CACR,CACA,KAAA,CAAMP,CAAe,CAAA,CAHb,IAAA,CAAA,OAAA,CAAAM,EACA,IAAA,CAAA,iBAAA,CAAAC,EAGV,CAEU,gBAAA,CAAiBN,CAAAA,CAA2B,CACpD,OAAI,IAAA,CAAK,QACA,CACL,KAAA,CAAO,KAAK,iBAAA,CAAkBA,CAAAA,CAAS,KAAK,OAAA,CAAQ,KAAK,EACzD,IAAA,CAAM,IAAA,CAAK,OAAA,CAAQ,IAAA,CAAO,IAAA,CAAK,iBAAA,CAAkBA,EAAS,IAAA,CAAK,OAAA,CAAQ,IAAI,CAAA,CAAI,MAAA,CAC/E,GAAI,IAAA,CAAK,OAAA,CAAQ,EAAA,CAAK,IAAA,CAAK,iBAAA,CAAkBA,CAAAA,CAAS,KAAK,OAAA,CAAQ,EAAE,EAAI,MAAA,CACzE,MAAA,CAAQ,KAAK,OAAA,CAAQ,MAAA,CACjB,IAAA,CAAK,iBAAA,CAAkBA,CAAAA,CAAS,IAAA,CAAK,QAAQ,MAAM,CAAA,CACnD,OACJ,QAAA,CAAU,IAAA,CAAK,QAAQ,QAAA,CACnB,IAAA,CAAK,kBAAkBA,CAAAA,CAAS,IAAA,CAAK,QAAQ,QAAQ,CAAA,CACrD,OACJ,MAAA,CAAQ,IAAA,CAAK,QAAQ,MAAA,CACjB,IAAA,CAAK,iBAAA,CAAkBA,CAAAA,CAAS,IAAA,CAAK,OAAA,CAAQ,MAAM,CAAA,CACnD,MAAA,CACJ,WAAY,IAAA,CAAK,OAAA,CAAQ,WACrB,IAAA,CAAK,iBAAA,CAAkBA,EAAS,IAAA,CAAK,OAAA,CAAQ,UAAU,CAAA,CACvD,MAAA,CACJ,IAAKA,CACP,CAAA,CAIK,CACL,KAAA,CAAOA,CAAAA,CAAQ,KAAA,EAASA,CAAAA,CAAQ,IAAA,EAAQA,CAAAA,CAAQ,aAChD,IAAA,CAAMA,CAAAA,CAAQ,MAAQA,CAAAA,CAAQ,WAAA,EAAeA,EAAQ,SAAA,CACrD,EAAA,CAAIA,EAAQ,EAAA,EAAMA,CAAAA,CAAQ,KAAOA,CAAAA,CAAQ,OAAA,CACzC,OAAQA,CAAAA,CAAQ,MAAA,EAAUA,EAAQ,OAAA,EAAWA,CAAAA,CAAQ,UAAA,CACrD,QAAA,CAAUA,CAAAA,CAAQ,QAAA,EAAYA,EAAQ,KAAA,EAASA,CAAAA,CAAQ,mBACvD,MAAA,CAAQA,CAAAA,CAAQ,QAAUA,CAAAA,CAAQ,YAAA,EAAgBA,CAAAA,CAAQ,eAAA,EAAmBA,CAAAA,CAAQ,OAAA,CACrF,WACEA,CAAAA,CAAQ,UAAA,EACRA,EAAQ,cAAA,EACRA,CAAAA,CAAQ,mBACRA,CAAAA,CAAQ,SAAA,CACV,GAAA,CAAKA,CACP,CACF,CAEU,sBAA+C,CACvD,OAAO,KAAK,iBAAA,EAAqB,EACnC,CAEQ,iBAAA,CAAkBd,EAAUI,CAAAA,CAAmB,CACrD,OAAOA,CAAAA,CAAK,KAAA,CAAM,GAAG,CAAA,CAAE,MAAA,CAAO,CAACE,CAAAA,CAASjC,CAAAA,GAAQiC,CAAAA,EAAA,IAAA,CAAA,MAAA,CAAAA,CAAAA,CAAUjC,CAAAA,CAAAA,CAAM2B,CAAG,CACrE,CACF,ECtDO,IAAMqB,CAAAA,CAAN,KAA4B,CACjC,OAAO,qBACLC,CAAAA,CACAhD,CAAAA,CACAiD,EACAC,CAAAA,CACgC,CAEhC,GAAIA,CAAAA,CACF,OAAOA,EAIT,GAAID,CAAAA,EAAA,IAAA,EAAAA,CAAAA,CAAS,UAAA,CACX,OAAO,IAAIL,CAAAA,CACTK,CAAAA,CAAQ,WACRA,CAAAA,CAAQ,cAAA,CACRA,EAAQ,cACV,CAAA,CAIF,OAAQD,CAAAA,EACN,KAAK,QAAA,CACH,OAAO,IAAIP,CAAAA,CACb,KAAK,SACH,OAAO,IAAIC,CAAAA,CACb,KAAK,WAAA,CACL,KAAK,UACH,OAAO,IAAIC,EACb,KAAK,UAAA,CACH,OAAO,IAAIC,CAAAA,CACT,4DACF,CAAA,CACF,KAAK,SAAA,CACL,QAEE,IAAMO,CAAAA,CAAanD,EAAO,UAAA,EAAcA,CAAAA,CAAO,YAC/C,OAAKmD,CAAAA,CAIE,IAAIP,CAAAA,CAAsBO,CAAU,CAAA,CAFzC,MAGN,CACF,CAEA,OAAO,4BAAA,CACLC,CAAAA,CACAhB,EACM,CAEN,IAAA,CAAK,eAAe,GAAA,CAAIgB,CAAAA,CAAchB,CAAc,EACtD,CAEA,OAAe,cAAA,CAAiB,IAAI,IAEpC,OAAO,uBAAA,CAAwBgB,CAAAA,CAAsD,CACnF,OAAO,IAAA,CAAK,eAAe,GAAA,CAAIA,CAAY,CAC7C,CACF,EC1DO,IAAMC,CAAAA,CAAN,MAAMC,CAAiD,CAC5D,OAAe,cAAuD,CACpE,MAAA,CAAQ,CACN,gBAAA,CAAkB,8CAAA,CAClB,SAAU,qCAAA,CACV,UAAA,CAAY,+CAAA,CACZ,OAAA,CAAS,IAAA,CACT,eAAA,CAAiB,CACf,WAAA,CAAa,SAAA,CACb,OAAQ,SACV,CACF,EACA,MAAA,CAAQ,CACN,iBAAkB,0CAAA,CAClB,QAAA,CAAU,8CACV,UAAA,CAAY,6BACd,EACA,SAAA,CAAW,CACT,iBAAkB,gEAAA,CAClB,QAAA,CAAU,4DAAA,CACV,UAAA,CAAY,qCAAA,CACZ,OAAA,CAAS,IACX,CAAA,CACA,OAAA,CAAS,CACP,gBAAA,CAAkB,gEAAA,CAClB,SAAU,4DAAA,CACV,UAAA,CAAY,qCAAA,CACZ,OAAA,CAAS,IAAA,CACT,eAAA,CAAiB,CACf,MAAA,CAAQ,gBACV,CACF,CAAA,CACA,QAAA,CAAU,CACR,gBAAA,CAAkB,6CAAA,CAClB,QAAA,CAAU,qDAAA,CACV,UAAA,CAAY,4DACd,CACF,CAAA,CAEA,cAAA,CACEC,EACAvD,CAAAA,CACAwD,CAAAA,CACgB,CAChB,IAAMC,CAAAA,CAAeF,IAAS,SAAA,CAAYD,CAAAA,CAAsB,cAAcC,CAAI,CAAA,EAAK,EAAC,CAAI,GAGtFG,CAAAA,CAA6B,CACjC,GAAGD,CAAAA,CACH,GAAGzD,CAAAA,CAEH,iBAAkBA,CAAAA,CAAO,gBAAA,EAAoByD,EAAa,gBAAA,EAAoB,EAAA,CAC9E,SAAUzD,CAAAA,CAAO,QAAA,EAAYyD,EAAa,QAAA,EAAY,EAAA,CACtD,WAAYzD,CAAAA,CAAO,UAAA,EAAcyD,EAAa,UAAA,CAC9C,eAAA,CAAiB,CACf,GAAIA,CAAAA,CAAa,eAAA,EAAmB,EAAC,CACrC,GAAIzD,EAAO,eAAA,EAAmB,EAChC,CACF,CAAA,CAEMoC,EAAiBW,CAAAA,CAAsB,oBAAA,CAC3CQ,EACAG,CAAAA,CACA,MAAA,CACAF,CACF,CAAA,CAEA,OAAO,IAAInB,CAAAA,CAAsBqB,CAAAA,CAAc,OAAW,MAAA,CAAWtB,CAAc,CACrF,CAEA,OAAO,cAAA,CAAeuB,EAAc3D,CAAAA,CAAqC,CACvEsD,EAAsB,aAAA,CAAcK,CAAI,EAAI3D,EAC9C,CAEA,OAAO,eAAA,CAAgB2D,CAAAA,CAAiD,CACtE,OAAOL,CAAAA,CAAsB,aAAA,CAAcK,CAAI,CACjD,CACF,EClFO,IAAMC,CAAAA,CAAN,KAAuD,CACpD,MAAA,CAAmC,IAAI,IACvC,MAAA,CAA0C,IAAI,IAC9C,eAAA,CAAmD,IAAI,IAEvD,UAAA,EAAqB,CAC3B,OAAO,IAAA,CAAK,MAAA,GAAS,QAAA,CAAS,EAAE,EAAE,SAAA,CAAU,CAAC,EAAI,IAAA,CAAK,GAAA,EAAI,CAAE,QAAA,CAAS,EAAE,CACzE,CAGA,MAAM,SAAA,CAAUC,EAA6C,CAE3D,IAAMC,EAAgB,MAAM,IAAA,CAAK,SAASD,CAAAA,CAAM,QAAA,CAAUA,EAAM,KAAA,CAAOA,CAAAA,CAAM,MAAM,CAAA,CAEnF,GAAIC,EAAe,CAEjB,IAAMC,CAAAA,CAA4B,CAChC,GAAGD,CAAAA,CACH,GAAGD,CAAAA,CACH,EAAA,CAAIC,EAAc,EAAA,CAClB,SAAA,CAAWA,EAAc,SAAA,CACzB,SAAA,CAAW,IAAI,IACjB,CAAA,CACA,YAAK,MAAA,CAAO,GAAA,CAAIA,EAAc,EAAA,CAAIC,CAAY,EACvCA,CACT,CAGA,IAAMC,CAAAA,CAAwB,CAC5B,GAAGH,EACH,EAAA,CAAI,IAAA,CAAK,YAAW,CACpB,SAAA,CAAW,IAAI,IAAA,CACf,SAAA,CAAW,IAAI,IACjB,CAAA,CACA,OAAA,IAAA,CAAK,OAAO,GAAA,CAAIG,CAAAA,CAAS,GAAIA,CAAQ,CAAA,CAC9BA,CACT,CAEA,MAAM,WAAA,CAAYC,CAAAA,CAA2C,CAC3D,IAAIC,EAAS,KAAA,CAAM,IAAA,CAAK,KAAK,MAAA,CAAO,MAAA,EAAQ,CAAA,CAoB5C,GAjBID,EAAM,EAAA,GACRC,CAAAA,CAASA,EAAO,MAAA,CAAQC,CAAAA,EAAMA,EAAE,EAAA,GAAOF,CAAAA,CAAM,EAAE,CAAA,CAAA,CAE7CA,CAAAA,CAAM,QAAA,GACRC,CAAAA,CAASA,CAAAA,CAAO,MAAA,CAAQC,GAAMA,CAAAA,CAAE,QAAA,GAAaF,EAAM,QAAQ,CAAA,CAAA,CAEzDA,EAAM,MAAA,GACRC,CAAAA,CAASA,EAAO,MAAA,CAAQC,CAAAA,EAAMA,EAAE,MAAA,GAAWF,CAAAA,CAAM,MAAM,CAAA,CAAA,CAErDA,CAAAA,CAAM,QACRC,CAAAA,CAASA,CAAAA,CAAO,MAAA,CAAQC,CAAAA,EAAMA,CAAAA,CAAE,KAAA,GAAUF,EAAM,KAAK,CAAA,CAAA,CAEnDA,EAAM,MAAA,GAAW,MAAA,GACnBC,EAASA,CAAAA,CAAO,MAAA,CAAQC,GAAMA,CAAAA,CAAE,MAAA,GAAWF,EAAM,MAAM,CAAA,CAAA,CAIrD,CAACA,CAAAA,CAAM,cAAA,CAAgB,CACzB,IAAM9C,CAAAA,CAAM,IAAI,IAAA,EAAK,CAAE,OAAA,GACvB+C,CAAAA,CAASA,CAAAA,CAAO,OAAQC,CAAAA,EACJ,IAAI,KAAKA,CAAAA,CAAE,KAAA,CAAM,SAAS,CAAA,CAAE,OAAA,EAAQ,EAClChD,CACrB,EACH,CAGA,OAAI8C,CAAAA,CAAM,MAAA,GAAW,SACnBC,CAAAA,CAASA,CAAAA,CAAO,KAAA,CAAMD,CAAAA,CAAM,MAAM,CAAA,CAAA,CAEhCA,EAAM,KAAA,GAAU,MAAA,GAClBC,EAASA,CAAAA,CAAO,KAAA,CAAM,EAAGD,CAAAA,CAAM,KAAK,GAG/BC,CACT,CAEA,MAAM,QAAA,CAASE,CAAAA,CAAkBC,EAAeC,CAAAA,CAA8C,CAE5F,QADgB,MAAM,IAAA,CAAK,WAAA,CAAY,CAAE,QAAA,CAAAF,CAAAA,CAAU,MAAAC,CAAAA,CAAO,MAAA,CAAAC,EAAQ,cAAA,CAAgB,IAAK,CAAC,CAAA,EACzE,CAAC,GAAK,IACvB,CAEA,MAAM,YAAA,CAAaC,CAAAA,CAAyC,CAE1D,OAAA,CADgB,MAAM,KAAK,WAAA,CAAY,CAAE,EAAA,CAAAA,CAAAA,CAAI,cAAA,CAAgB,IAAK,CAAC,CAAA,EACpD,CAAC,GAAK,IACvB,CAEA,MAAM,iBAAA,CAAkBC,CAAAA,CAAwC,CAC9D,OAAO,IAAA,CAAK,YAAY,CAAE,MAAA,CAAAA,CAAO,CAAC,CACpC,CAEA,MAAM,gBAAA,CAAiBH,CAAAA,CAAuC,CAC5D,OAAO,IAAA,CAAK,YAAY,CAAE,KAAA,CAAAA,CAAM,CAAC,CACnC,CAEA,MAAM,mBAAA,CAAoBD,CAAAA,CAA0C,CAClE,OAAO,IAAA,CAAK,YAAY,CAAE,QAAA,CAAAA,CAAS,CAAC,CACtC,CAEA,MAAM,WAAA,CAAYI,CAAAA,CAAgBJ,CAAAA,CAA0C,CAC1E,OAAO,KAAK,WAAA,CAAY,CAAE,OAAAI,CAAAA,CAAQ,QAAA,CAAAJ,CAAS,CAAC,CAC9C,CAEA,MAAM,iBAAA,CACJI,EACAJ,CAAAA,CACAC,CAAAA,CAC6B,CAE7B,OAAA,CADgB,MAAM,KAAK,WAAA,CAAY,CAAE,MAAA,CAAAG,CAAAA,CAAQ,QAAA,CAAAJ,CAAAA,CAAU,MAAAC,CAAM,CAAC,GACnD,CAAC,CAAA,EAAK,IACvB,CAEA,MAAM,UAAUG,CAAAA,CAAgBJ,CAAAA,CAA0C,CACxE,OAAO,IAAA,CAAK,YAAY,CAAE,MAAA,CAAAI,EAAQ,QAAA,CAAAJ,CAAS,CAAC,CAC9C,CAEA,MAAM,YAAYG,CAAAA,CAAYE,CAAAA,CAAuD,CACnF,IAAMC,CAAAA,CAAQ,KAAK,MAAA,CAAO,GAAA,CAAIH,CAAE,CAAA,CAChC,GAAI,CAACG,CAAAA,CAAO,OAAO,KAEnB,IAAMX,CAAAA,CAA4B,CAChC,GAAGW,CAAAA,CACH,GAAID,CAAAA,CAAO,KAAA,EAAS,CAAE,MAAOA,CAAAA,CAAO,KAAM,EAC1C,GAAIA,CAAAA,CAAO,UAAY,CAAE,QAAA,CAAU,CAAE,GAAGC,CAAAA,CAAM,QAAA,CAAU,GAAGD,CAAAA,CAAO,QAAS,CAAE,CAAA,CAC7E,SAAA,CAAW,IAAI,IACjB,CAAA,CACA,OAAA,IAAA,CAAK,MAAA,CAAO,GAAA,CAAIF,CAAAA,CAAIR,CAAY,CAAA,CACzBA,CACT,CAEA,MAAM,WAAA,CAAYQ,EAA8B,CAC9C,OAAO,KAAK,MAAA,CAAO,MAAA,CAAOA,CAAE,CAC9B,CAEA,MAAM,0BAAA,CACJH,CAAAA,CACAC,EACAC,CAAAA,CACkB,CAClB,IAAMI,CAAAA,CAAQ,MAAM,IAAA,CAAK,SAASN,CAAAA,CAAUC,CAAAA,CAAOC,CAAM,CAAA,CACzD,OAAKI,EACE,IAAA,CAAK,MAAA,CAAO,OAAOA,CAAAA,CAAM,EAAE,EADf,KAErB,CAEA,MAAM,mBAAA,EAAuC,CAC3C,IAAMvD,CAAAA,CAAM,IAAI,IAAA,EAAK,CAAE,OAAA,EAAQ,CACzBwD,EAAgB,KAAA,CAAM,IAAA,CAAK,KAAK,MAAA,CAAO,OAAA,EAAS,CAAA,CACnD,MAAA,CAAO,CAAC,EAAGD,CAAK,CAAA,GACG,IAAI,KAAKA,CAAAA,CAAM,KAAA,CAAM,SAAS,CAAA,CAAE,OAAA,EAAQ,CACvCvD,CACpB,CAAA,CACA,GAAA,CAAI,CAAC,CAACoD,CAAE,IAAMA,CAAE,CAAA,CAEnB,OAAAI,CAAAA,CAAc,OAAA,CAASJ,CAAAA,EAAO,IAAA,CAAK,MAAA,CAAO,MAAA,CAAOA,CAAE,CAAC,CAAA,CAC7CI,EAAc,MACvB,CAGA,MAAM,sBAAA,CACJ1E,CAAAA,CAC6B,CAC7B,IAAM2E,CAAAA,CAA+B,CACnC,GAAG3E,CAAAA,CACH,SAAA,CAAW,IAAI,IAAA,CAAK,IAAA,CAAK,KAAK,CAChC,EACA,OAAA,IAAA,CAAK,MAAA,CAAO,IAAIA,CAAAA,CAAM,KAAA,CAAO2E,CAAQ,CAAA,CAC9BA,CACT,CAEA,MAAM,qBAAA,CAAsB3E,CAAAA,CAAmD,CAC7E,OAAO,IAAA,CAAK,OAAO,GAAA,CAAIA,CAAK,GAAK,IACnC,CAEA,MAAM,wBAAA,CAAyBA,CAAAA,CAAiC,CAC9D,OAAO,IAAA,CAAK,OAAO,MAAA,CAAOA,CAAK,CACjC,CAEA,MAAM,sBAAwC,CAC5C,IAAMkB,CAAAA,CAAM,IAAI,IAAA,EAAK,CAAE,SAAQ,CACzB0D,CAAAA,CAAS,GAAK,EAAA,CAAK,GAAA,CAEnBC,EAAgB,KAAA,CAAM,IAAA,CAAK,KAAK,MAAA,CAAO,OAAA,EAAS,CAAA,CACnD,MAAA,CAAO,CAAC,EAAG7E,CAAK,CAAA,GACEkB,CAAAA,CAAMlB,CAAAA,CAAM,SAAA,CAAU,OAAA,EAAQ,CAC7B4E,CACnB,CAAA,CACA,GAAA,CAAI,CAAC,CAAC9E,CAAG,IAAMA,CAAG,CAAA,CAErB,OAAA+E,CAAAA,CAAc,OAAA,CAAS/E,CAAAA,EAAQ,KAAK,MAAA,CAAO,MAAA,CAAOA,CAAG,CAAC,CAAA,CAC/C+E,EAAc,MACvB,CAGA,sBAAA,CAAuB1B,CAAAA,CAAsB2B,CAAAA,CAAmC,CAC9E,KAAK,eAAA,CAAgB,GAAA,CAAI3B,EAAc2B,CAAO,EAChD,CAEA,iBAAA,CAAkB3B,CAAAA,CAAsD,CACtE,OAAO,IAAA,CAAK,gBAAgB,GAAA,CAAIA,CAAY,CAC9C,CAEA,kBAAA,EAAsD,CACpD,OAAO,IAAI,GAAA,CAAI,IAAA,CAAK,eAAe,CACrC,CACF,ECrNO,IAAM4B,EAAqB,IAChCC,kBAAAA,CAAY,EAAE,CAAA,CACX,QAAA,CAAS,QAAQ,CAAA,CACjB,OAAA,CAAQ,gBAAiB,EAAE,CAAA,CAC3B,SAAA,CAAU,CAAA,CAAG,GAAG,CAAA,CAERC,EAAuBC,CAAAA,EAC3BC,iBAAAA,CAAW,QAAQ,CAAA,CAAE,MAAA,CAAOD,CAAQ,CAAA,CAAE,MAAA,CAAO,WAAW,CAAA,CAGpDE,CAAAA,CAAgB,IACpBJ,kBAAAA,CAAY,EAAE,EAAE,QAAA,CAAS,WAAW,EC+BtC,IAAMK,CAAAA,CAAN,KAAmB,CAChB,OAAA,CACA,eAAA,CACA,UAAyC,IAAI,GAAA,CAC7C,gBAA6C,IAAI,GAAA,CACjD,IACA,kBAAA,CAER,WAAA,CAAYrC,CAAAA,CAAyB,EAAC,CAAG,CApD3C,IAAAnC,CAAAA,CAAAC,CAAAA,CAAAC,EAqDI,IAAA,CAAK,OAAA,CAAUiC,EAAQ,OAAA,EAAW,IAAIW,CAAAA,CACtC,IAAA,CAAK,eAAA,CAAkB,IAAIP,EAC3B,IAAA,CAAK,GAAA,CAAM,KAAK,GAAA,CAGhB,IAAA,CAAK,mBAAqB,CACxB,OAAA,CAAA,CAAA,CAASvC,EAAAmC,CAAAA,CAAQ,WAAA,GAAR,YAAAnC,CAAAA,CAAqB,OAAA,GAAW,KACzC,aAAA,CAAA,CAAA,CAAeC,CAAAA,CAAAkC,EAAQ,WAAA,GAAR,IAAA,CAAA,MAAA,CAAAlC,CAAAA,CAAqB,aAAA,GAAiB,EAAA,CACrD,cAAA,CAAA,CAAgBC,EAAAiC,CAAAA,CAAQ,WAAA,GAAR,YAAAjC,CAAAA,CAAqB,cACvC,EAGIiC,CAAAA,CAAQ,SAAA,EACV,OAAO,OAAA,CAAQA,CAAAA,CAAQ,SAAS,CAAA,CAAE,OAAA,CAAQ,CAAC,CAACU,CAAAA,CAAM3D,CAAM,CAAA,GAAM,CAC5D,IAAA,CAAK,gBAAA,CAAiB2D,CAAAA,CAAM3D,CAAM,EACpC,CAAC,EAEL,CAKA,gBAAA,CAAiB2D,CAAAA,CAAc3D,EAA4B,CACzD,IAAA,CAAK,gBAAgB,GAAA,CAAI2D,CAAAA,CAAM3D,CAAM,CAAA,CAGrC,IAAMkD,EAAgB,IAAA,CAAK,OAAA,CAAQ,kBAAkBS,CAAI,CAAA,CAGnDX,CAAAA,CAAe,IAAA,CAAK,kBAAA,CAAmBW,CAAAA,CAAM3D,CAAM,CAAA,CACnDoE,CAAAA,CAAW,KAAK,eAAA,CAAgB,cAAA,CAAepB,EAAchD,CAAAA,CAAQkD,CAAa,CAAA,CAExF,IAAA,CAAK,SAAA,CAAU,GAAA,CAAIS,EAAMS,CAAQ,EACnC,CAKA,MAAM,SAAA,CAAUnB,EAAwE,CA3F1F,IAAAnC,CAAAA,CA4FI,IAAMsD,CAAAA,CAAW,IAAA,CAAK,UAAU,GAAA,CAAInB,CAAAA,CAAQ,QAAQ,CAAA,CACpD,GAAI,CAACmB,CAAAA,CAAU,MAAM,IAAI,KAAA,CAAM,CAAA,SAAA,EAAYnB,EAAQ,QAAQ,CAAA,UAAA,CAAY,EAEvE,IAAMhD,CAAAA,CAAQoF,GAAc,CACxBE,CAAAA,CACAC,CAAAA,CAIJ,GAAA,CAAA,CAFqB1E,CAAAA,CAAA,IAAA,CAAK,gBAAgB,GAAA,CAAImC,CAAAA,CAAQ,QAAQ,CAAA,GAAzC,IAAA,CAAA,MAAA,CAAAnC,EAA4C,OAAA,GAAWmC,CAAAA,CAAQ,QAElE,CAChB,IAAM3C,EAAe0E,CAAAA,EAAmB,CAClC9E,EAAgBgF,CAAAA,CAAoB5E,CAAY,EACtDiF,CAAAA,CAAUnB,CAAAA,CAAS,wBAAA,CAAyBnE,CAAAA,CAAOC,CAAa,CAAA,CAChEsF,EAAY,CACV,KAAA,CAAAvF,EACA,YAAA,CAAAK,CAAAA,CACA,OAAQ,IAAA,CAAK,eAAA,CAAgB,IAAI2C,CAAAA,CAAQ,QAAQ,EACjD,QAAA,CAAU,CACR,GAAGA,CAAAA,CAAQ,QAAA,CACX,OAAQA,CAAAA,CAAQ,MAAA,CAChB,KAAA,CAAOA,CAAAA,CAAQ,KAAA,CACf,QAAA,CAAUA,EAAQ,QAAA,CAClB,MAAA,CAAQA,EAAQ,MAAA,CAChB,UAAA,CAAYA,EAAQ,UACtB,CACF,EACF,CAAA,KACEsC,CAAAA,CAAUnB,CAAAA,CAAS,yBAAyBnE,CAAK,CAAA,CACjDuF,EAAY,CACV,KAAA,CAAAvF,EACA,MAAA,CAAQ,IAAA,CAAK,eAAA,CAAgB,GAAA,CAAIgD,CAAAA,CAAQ,QAAQ,EACjD,QAAA,CAAU,CACR,GAAGA,CAAAA,CAAQ,QAAA,CACX,OAAQA,CAAAA,CAAQ,MAAA,CAChB,MAAOA,CAAAA,CAAQ,KAAA,CACf,SAAUA,CAAAA,CAAQ,QAAA,CAClB,OAAQA,CAAAA,CAAQ,MAAA,CAChB,WAAYA,CAAAA,CAAQ,UACtB,CACF,CAAA,CAGF,OAAA,MAAM,IAAA,CAAK,QAAQ,sBAAA,CAAuBuC,CAAS,EAC5C,CAAE,GAAA,CAAKD,EAAS,KAAA,CAAAtF,CAAM,CAC/B,CAKA,MAAM,eAAeI,CAAAA,CAAcJ,CAAAA,CAAwC,CA7I7E,IAAAa,CAAAA,CAAAC,EAAAC,CAAAA,CAAAC,CAAAA,CAAAC,CAAAA,CA8II,IAAMsE,CAAAA,CAAY,MAAM,KAAK,OAAA,CAAQ,qBAAA,CAAsBvF,CAAK,CAAA,CAChE,GAAI,CAACuF,CAAAA,CAAW,MAAM,IAAI,KAAA,CAAM,0BAA0B,EAE1D,IAAMpB,CAAAA,CAAAA,CAAWtD,EAAA0E,CAAAA,CAAU,QAAA,GAAV,YAAA1E,CAAAA,CAAoB,QAAA,CACrC,GAAI,CAACsD,CAAAA,CAAU,MAAM,IAAI,KAAA,CAAM,2CAA2C,EAE1E,IAAMqB,CAAAA,CAAmB,KAAK,SAAA,CAAU,GAAA,CAAIrB,CAAQ,CAAA,CACpD,GAAI,CAACqB,EAAkB,MAAM,IAAI,MAAM,CAAA,SAAA,EAAYrB,CAAQ,YAAY,CAAA,CAGvE,IAAMF,CAAAA,CAAS,MAAMuB,CAAAA,CAAiB,oBAAA,CAAqBpF,EAAMmF,CAAAA,CAAU,YAAY,EAGjFhB,CAAAA,CAAAA,CAASzD,CAAAA,CAAAyE,EAAU,QAAA,GAAV,IAAA,CAAA,MAAA,CAAAzE,EAAoB,MAAA,CAC7BsD,CAAAA,CAAAA,CAAQrD,EAAAwE,CAAAA,CAAU,QAAA,GAAV,YAAAxE,CAAAA,CAAoB,KAAA,CAC5BsD,GAASrD,CAAAA,CAAAuE,CAAAA,CAAU,QAAA,GAAV,IAAA,CAAA,MAAA,CAAAvE,CAAAA,CAAoB,MAAA,CAC7ByE,GAAaxE,CAAAA,CAAAsE,CAAAA,CAAU,WAAV,IAAA,CAAA,MAAA,CAAAtE,CAAAA,CAAoB,WAEvC,GAAI,CAACsD,GAAU,CAACH,CAAAA,CACd,MAAM,IAAI,KAAA,CAAM,uDAAuD,CAAA,CAIzE,IAAIsB,EACJ,GAAIF,CAAAA,CAAiB,iBAAA,EAAkB,CACrC,GAAI,CACFE,EAAU,MAAMF,CAAAA,CAAiB,aAAavB,CAAAA,CAAO,WAAW,EAClE,CAAA,MAAS0B,CAAAA,CAAO,CACd,OAAA,CAAQ,IAAA,CAAK,gCAAiCA,CAAK,EACrD,CAIF,IAAMC,CAAAA,CAAa,MAAM,IAAA,CAAK,OAAA,CAAQ,SAAA,CAAU,CAC9C,QAAA,CAAAzB,CAAAA,CACA,OAAAI,CAAAA,CACA,KAAA,CAAA,CAAOmB,GAAA,IAAA,CAAA,MAAA,CAAAA,CAAAA,CAAS,QAAStB,CAAAA,CACzB,MAAA,CAAA,CAAQsB,CAAAA,EAAA,IAAA,CAAA,MAAA,CAAAA,CAAAA,CAAS,MAAA,GAAUrB,EAC3B,UAAA,CAAA,CAAYqB,CAAAA,EAAA,YAAAA,CAAAA,CAAS,UAAA,GAAcD,EACnC,KAAA,CAAOxB,CAAAA,CACP,QAAA,CAAU,CACR,GAAGsB,CAAAA,CAAU,SACb,cAAA,CAAgB,CAAC,CAACG,CACpB,CACF,CAAC,CAAA,CAGD,MAAM,KAAK,OAAA,CAAQ,wBAAA,CAAyB1F,CAAK,CAAA,CAGjD,IAAMD,EAAS,IAAA,CAAK,eAAA,CAAgB,IAAIoE,CAAQ,CAAA,CAChD,OAAIpE,CAAAA,EAAA,IAAA,EAAAA,CAAAA,CAAQ,WACV,MAAMA,CAAAA,CAAO,UAAUwE,CAAAA,CAAQN,CAAM,EAGhC,CACL,KAAA,CAAO2B,EACP,OAAA,CAAAF,CACF,CACF,CAKA,MAAM,eACJvB,CAAAA,CACAC,CAAAA,CACApB,EAA8C,EAAC,CAC9B,CAEjB,OAAA,CADc,MAAM,IAAA,CAAK,cAAcmB,CAAAA,CAAUC,CAAAA,CAAOpB,CAAO,CAAA,EAClD,WACf,CAKA,MAAM,aAAA,CACJmB,EACAC,CAAAA,CACApB,CAAAA,CAA8C,EAAC,CACzB,CACtB,IAAM6C,CAAAA,CAAc,MAAM,KAAK,OAAA,CAAQ,QAAA,CAAS1B,CAAAA,CAAUC,CAAAA,CAAOpB,CAAAA,CAAQ,MAAM,EAC/E,GAAI,CAAC6C,EAAa,CAChB,IAAMC,EAAa9C,CAAAA,CAAQ,MAAA,CAAS,CAAA,YAAA,EAAeA,CAAAA,CAAQ,MAAM,CAAA,CAAA,CAAK,GACtE,MAAM,IAAI,MAAM,CAAA,4BAAA,EAA+BmB,CAAQ,WAAWC,CAAK,CAAA,EAAG0B,CAAU,CAAA,CAAE,CACxF,CAKA,GAAI,EAFF9C,CAAAA,CAAQ,cAAgB,KAAA,EAAS,IAAA,CAAK,eAAe6C,CAAAA,CAAY,KAAA,CAAO7C,CAAO,CAAA,CAAA,CAG/E,OAAO6C,EAAY,KAAA,CAIrB,GAAI,CAACA,CAAAA,CAAY,KAAA,CAAM,aACrB,MAAM,IAAI,KAAA,CAAM,8CAA8C,CAAA,CAGhE,IAAML,EAAmB,IAAA,CAAK,SAAA,CAAU,IAAIrB,CAAQ,CAAA,CACpD,GAAI,CAACqB,CAAAA,CAAkB,MAAM,IAAI,KAAA,CAAM,YAAYrB,CAAQ,CAAA,UAAA,CAAY,EAEvE,IAAMJ,CAAAA,CAAW,MAAMyB,CAAAA,CAAiB,YAAA,CAAaK,CAAAA,CAAY,KAAA,CAAM,YAAY,CAAA,CACnF,aAAM,IAAA,CAAK,OAAA,CAAQ,YAAYA,CAAAA,CAAY,EAAA,CAAI,CAAE,KAAA,CAAO9B,CAAS,CAAC,CAAA,CAE3DA,CACT,CAKA,MAAM,WAAA,CAAYC,EAA2C,CAG3D,IAAM+B,EACJ,IAAA,CAAK,kBAAA,CAAmB,OAAA,EAAW,CAAC/B,CAAAA,CAAM,cAAA,CACtC,CAAE,GAAGA,CAAAA,CAAO,eAAgB,IAAK,CAAA,CACjCA,EAEAC,CAAAA,CAAS,MAAM,IAAA,CAAK,OAAA,CAAQ,WAAA,CAAY8B,CAAgB,EAE9D,OAAI,IAAA,CAAK,mBAAmB,OAAA,EAAW,CAAC/B,EAAM,cAAA,CAAA,CACpB,MAAM,IAAA,CAAK,qBAAA,CAAsBC,CAAM,CAAA,EAExC,OAAQQ,CAAAA,EACX,IAAI,KAAKA,CAAAA,CAAM,KAAA,CAAM,SAAS,CAAA,CAAE,OAAA,GAC/B,IAAA,CAAK,GAAA,EACzB,CAAA,CAGIR,CACT,CAKA,MAAM,iBAAA,CAAkBM,EAAwC,CAC9D,OAAO,IAAA,CAAK,WAAA,CAAY,CAAE,MAAA,CAAAA,CAAO,CAAC,CACpC,CAKA,MAAM,gBAAA,CAAiBH,EAAuC,CAC5D,OAAO,KAAK,WAAA,CAAY,CAAE,MAAAA,CAAM,CAAC,CACnC,CAKA,MAAM,YAAYD,CAAAA,CAAkBC,CAAAA,CAAeC,CAAAA,CAAmC,CACpF,OAAO,IAAA,CAAK,QAAQ,0BAAA,CAA2BF,CAAAA,CAAUC,EAAOC,CAAM,CACxE,CAKA,MAAM,oBAAA,EAAwC,CAC5C,OAAO,IAAA,CAAK,QAAQ,mBAAA,EACtB,CAKA,MAAM,oBAAA,EAAwC,CAC5C,OAAO,IAAA,CAAK,OAAA,CAAQ,oBAAA,EACtB,CAGQ,eAAeI,CAAAA,CAAoBzB,CAAAA,CAAwB,EAAC,CAAY,CAC9E,GAAM,CAAE,gBAAA,CAAAgD,CAAAA,CAAmB,GAAI,CAAA,CAAIhD,CAAAA,CAEnC,GAAIyB,CAAAA,CAAM,SAAA,EAAaA,EAAM,SAAA,GAAc,MAAA,CAAW,CACpD,IAAMwB,CAAAA,CAAYxB,CAAAA,CAAM,SAAA,CAAYA,CAAAA,CAAM,SAAA,CAAY,IAEtD,OADqB,IAAA,CAAK,KAAI,CAAIuB,CAAAA,CAAmB,KAC9BC,CACzB,CAEA,IAAMA,CAAAA,CAAY,IAAI,KAAKxB,CAAAA,CAAM,SAAS,EAAE,OAAA,EAAQ,CAEpD,OADqB,IAAA,CAAK,GAAA,EAAI,CAAIuB,CAAAA,CAAmB,GAAA,EAC9BC,CACzB,CAEQ,kBAAA,CAAmBvC,CAAAA,CAAc3D,EAAoC,CArU/E,IAAAc,EAuUI,IAAMyE,CAAAA,CAAUvF,EAAO,gBAAA,CAAiB,WAAA,GAGxC,OAAIuF,CAAAA,CAAQ,SAAS,qBAAqB,CAAA,CAAU,SAChDA,CAAAA,CAAQ,QAAA,CAAS,YAAY,CAAA,CAAU,QAAA,CACvCA,CAAAA,CAAQ,SAAS,cAAc,CAAA,CAAU,WACzCA,CAAAA,CAAQ,QAAA,CAAS,eAAe,CAAA,EAAKA,CAAAA,CAAQ,SAAS,qBAAqB,CAAA,CAG3E5B,EAAK,WAAA,EAAY,CAAE,SAAS,SAAS,CAAA,EAAA,CACrC7C,EAAAd,CAAAA,CAAO,MAAA,GAAP,IAAA,EAAAc,CAAAA,CAAe,IAAA,CAAMqF,CAAAA,EAAMA,EAAE,QAAA,CAAS,SAAS,GAExC,SAAA,CAEF,WAAA,CAIF,SACT,CAKA,MAAc,qBAAA,CAAsBjC,CAAAA,CAA+C,CACjF,IAAMkC,EAAkBlC,CAAAA,CAAO,GAAA,CAAI,MAAOQ,CAAAA,EAAU,CAClD,GAAI,IAAA,CAAK,kBAAA,CAAmBA,CAAK,CAAA,CAC/B,GAAI,CACF,IAAMN,CAAAA,CAAW,IAAA,CAAK,UAAU,GAAA,CAAIM,CAAAA,CAAM,QAAQ,CAAA,CAClD,GAAI,CAACN,CAAAA,CACH,OAAA,OAAA,CAAQ,KAAK,CAAA,SAAA,EAAYM,CAAAA,CAAM,QAAQ,CAAA,4BAAA,CAA8B,CAAA,CAC9DA,EAGT,GAAI,CAACA,CAAAA,CAAM,KAAA,CAAM,YAAA,CACf,OAAA,OAAA,CAAQ,KAAK,CAAA,+BAAA,EAAkCA,CAAAA,CAAM,QAAQ,CAAA,CAAA,EAAIA,CAAAA,CAAM,KAAK,CAAA,CAAE,CAAA,CACvEA,EAGT,IAAMV,CAAAA,CAAW,MAAMI,CAAAA,CAAS,YAAA,CAAaM,EAAM,KAAA,CAAM,YAAY,EAErE,OADgB,MAAM,IAAA,CAAK,OAAA,CAAQ,WAAA,CAAYA,CAAAA,CAAM,GAAI,CAAE,KAAA,CAAOV,CAAS,CAAC,CAAA,EAC1DU,CACpB,CAAA,MAASkB,CAAAA,CAAO,CACd,OAAI,IAAA,CAAK,mBAAmB,cAAA,EAC1B,IAAA,CAAK,mBAAmB,cAAA,CAAeA,CAAAA,CAAgBlB,CAAK,CAAA,CAE9D,OAAA,CAAQ,KAAA,CAAM,CAAA,4BAAA,EAA+BA,CAAAA,CAAM,QAAQ,IAAIA,CAAAA,CAAM,KAAK,IAAKkB,CAAK,CAAA,CAC7ElB,CACT,CAEF,OAAOA,CACT,CAAC,CAAA,CAED,OAAO,QAAQ,GAAA,CAAI0B,CAAe,CACpC,CAKQ,kBAAA,CAAmBN,EAAmC,CAE5D,GAAI,CAACA,CAAAA,CAAY,KAAA,CAAM,YAAA,CACrB,OAAO,MAAA,CAIT,IAAMI,EAAY,IAAI,IAAA,CAAKJ,EAAY,KAAA,CAAM,SAAS,EAAE,OAAA,EAAQ,CAC1D3E,EAAM,IAAA,CAAK,GAAA,GAGjB,GAAIA,CAAAA,EAAO+E,EACT,OAAO,KAAA,CAIT,IAAMG,CAAAA,CAAW,IAAA,CAAK,kBAAA,CAAmB,cAAiB,EAAA,CAAK,GAAA,CACzDC,EAAkBJ,CAAAA,CAAYG,CAAAA,CAEpC,OAAOlF,CAAAA,EAAOmF,CAChB,CAKA,wBAAA,CAAyBrD,CAAAA,CAA4C,CACnE,IAAA,CAAK,kBAAA,CAAqB,CAAE,GAAG,IAAA,CAAK,mBAAoB,GAAGA,CAAQ,EACrE,CAKA,MAAM,sBAAA,CAAuBmB,EAAkBI,CAAAA,CAAwC,CACrF,OAAO,IAAA,CAAK,WAAA,CAAY,CAAE,QAAA,CAAAJ,CAAAA,CAAU,OAAAI,CAAO,CAAC,CAC9C,CAKA,MAAM,WAAWJ,CAAAA,CAAkBC,CAAAA,CAAkC,CAEnE,IAAMkC,CAAAA,CAAAA,CADS,MAAM,IAAA,CAAK,WAAA,CAAY,CAAE,SAAAnC,CAAAA,CAAU,KAAA,CAAAC,CAAM,CAAC,CAAA,EAEtD,IAAKF,CAAAA,EAAMA,CAAAA,CAAE,MAAM,CAAA,CACnB,MAAA,CAAQG,CAAAA,EAA6BA,IAAW,MAAS,CAAA,CAC5D,OAAO,CAAC,GAAG,IAAI,GAAA,CAAIiC,CAAO,CAAC,CAC7B,CAKA,MAAM,qBACJnC,CAAAA,CACAC,CAAAA,CACAqB,EAC6B,CAE7B,OAAA,CADe,MAAM,IAAA,CAAK,WAAA,CAAY,CAAE,QAAA,CAAAtB,CAAAA,CAAU,MAAAC,CAAM,CAAC,GAC3C,IAAA,CAAMF,CAAAA,EAAMA,EAAE,UAAA,GAAeuB,CAAU,CAAA,EAAK,IAC5D,CAKA,MAAM,kBAAkBtB,CAAAA,CAAkBC,CAAAA,CAAeC,EAAkC,CAEzF,OADc,MAAM,IAAA,CAAK,OAAA,CAAQ,SAASF,CAAAA,CAAUC,CAAAA,CAAOC,CAAM,CAAA,GAChD,IACnB,CAKA,MAAM,oBAAA,CACJF,EACAC,CAAAA,CAC8E,CAE9E,OAAA,CADe,MAAM,IAAA,CAAK,WAAA,CAAY,CAAE,QAAA,CAAAD,CAAAA,CAAU,MAAAC,CAAM,CAAC,GAC3C,GAAA,CAAKK,CAAAA,GAAW,CAC5B,KAAA,CAAAA,CAAAA,CACA,OAAQA,CAAAA,CAAM,MAAA,CACd,WAAYA,CAAAA,CAAM,UACpB,EAAE,CACJ,CACF,MCjda8B,EAAAA,CAAO,CAAIC,EAAM1G,CAAAA,GAAgB2G,oBAAAA,CAASD,CAAAA,CAAG,CAAE,QAAA,CAAU1G,CAAI,CAAC,CAAA,CAC9D4G,EAAAA,CAAS,CAAI,CAAA,CAAW5G,CAAAA,GAAgB6G,uBAAc,CAAA,CAAG,CAAE,QAAA,CAAU7G,CAAI,CAAC","file":"index.cjs","sourcesContent":["import { OAuth2Config } from '../types';\nimport { AuthorizationUrlStrategy } from './authorization-url.strategy';\n\nexport class StandardAuthorizationUrlStrategy implements AuthorizationUrlStrategy {\n  protected buildUrlParams(params: Record<string, string | undefined>): string {\n    const filtered = Object.entries(params)\n      .filter(([, value]) => value !== undefined)\n\n      .map(([key, value]) => `${key}=${encodeURIComponent(value as string)}`);\n\n    return filtered.join('&');\n  }\n\n  generateAuthorizationUrl(config: OAuth2Config, state: string, codeChallenge?: string): string {\n    const params: Record<string, string | undefined> = {\n      client_id: config.clientId,\n      redirect_uri: config.redirectUri,\n      response_type: 'code',\n      scope: config.scopes.join(' '),\n      state,\n    };\n\n    // Add PKCE parameters\n    if ((config.usePKCE || config.pkce) && codeChallenge) {\n      params.code_challenge = codeChallenge;\n      params.code_challenge_method = 'S256';\n    }\n\n    // Merge additional parameters (for both additionalParams and extraAuthParams)\n    const extraParams = {\n      ...config.additionalParams,\n      ...config.extraAuthParams,\n    };\n\n    Object.assign(params, extraParams);\n\n    return `${config.authorizationUrl}?${this.buildUrlParams(params)}`;\n  }\n}\n","import { OAuth2Config, OAuth2Token } from '../types';\nimport { TokenExchangeStrategy } from './token-exchange.strategy';\n\nexport class StandardTokenExchangeStrategy implements TokenExchangeStrategy {\n  protected buildUrlParams(params: Record<string, string | undefined>): string {\n    const filtered = Object.entries(params)\n      .filter(([, value]) => value !== undefined)\n      .map(([key, value]) => `${key}=${encodeURIComponent(value as string)}`);\n\n    return filtered.join('&');\n  }\n\n  async exchangeCodeForToken(\n    code: string,\n    config: OAuth2Config,\n    codeVerifier?: string,\n  ): Promise<OAuth2Token> {\n    const params: Record<string, string | undefined> = {\n      grant_type: 'authorization_code',\n      code,\n      redirect_uri: config.redirectUri,\n      client_id: config.clientId,\n    };\n\n    // Handle PKCE\n    if ((config.usePKCE || config.pkce) && codeVerifier) {\n      params.code_verifier = codeVerifier;\n    } else if (config.clientSecret) {\n      params.client_secret = config.clientSecret;\n    }\n\n    const response = await fetch(config.tokenUrl, {\n      method: 'POST',\n      headers: {\n        'Content-Type': 'application/x-www-form-urlencoded',\n      },\n      body: this.buildUrlParams(params),\n    });\n\n    if (!response.ok) {\n      const errorText = await response.text();\n      throw new Error(`Token exchange failed: ${response.statusText} - ${errorText}`);\n    }\n\n    const data = await response.json();\n\n    // Handle nested response (e.g., Outlook might nest tokens)\n    const tokenData = config.responseRootKey ? data[config.responseRootKey] : data;\n\n    return this.normalizeTokenResponse(tokenData, data, undefined, config);\n  }\n\n  async refreshToken(refreshToken: string, config: OAuth2Config): Promise<OAuth2Token> {\n    const params: Record<string, string | undefined> = {\n      grant_type: 'refresh_token',\n      refresh_token: refreshToken,\n      client_id: config.clientId,\n    };\n\n    // Only add client_secret if not using PKCE\n    if (!(config.usePKCE || config.pkce) && config.clientSecret) {\n      params.client_secret = config.clientSecret;\n    }\n\n    const response = await fetch(config.tokenUrl, {\n      method: 'POST',\n      headers: {\n        'Content-Type': 'application/x-www-form-urlencoded',\n      },\n      body: this.buildUrlParams(params),\n    });\n\n    if (!response.ok) {\n      const errorText = await response.text();\n      throw new Error(`Token refresh failed: ${response.statusText} - ${errorText}`);\n    }\n\n    const data = await response.json();\n    const tokenData = config.responseRootKey ? data[config.responseRootKey] : data;\n\n    return this.normalizeTokenResponse(tokenData, data, refreshToken, config);\n  }\n\n  protected normalizeTokenResponse(\n    tokenData: Record<string, any>,\n    rawResponse: Record<string, any>,\n    refreshTokenFallback?: string,\n    config?: OAuth2Config,\n  ): OAuth2Token {\n    const now = Date.now();\n\n    // Extract values using custom paths if provided, otherwise use defaults\n    const accessToken = this.extractValue(\n      tokenData,\n      config?.tokenPaths?.accessToken,\n      // Default paths: For providers like Slack that return both bot and user tokens,\n      // prioritize the user token in authed_user over the root-level bot token\n      [\n        'authed_user.access_token',\n        'authed_user.accessToken',\n        'access_token',\n        'accessToken',\n        'token.access_token',\n        'token.accessToken',\n      ],\n    );\n\n    if (!accessToken) {\n      throw new Error('Token response did not include an access_token');\n    }\n\n    const rawRefreshToken =\n      this.extractValue(tokenData, config?.tokenPaths?.refreshToken, [\n        'authed_user.refresh_token',\n        'authed_user.refreshToken',\n        'refresh_token',\n        'refreshToken',\n        'token.refresh_token',\n        'token.refreshToken',\n      ]) ?? refreshTokenFallback;\n\n    const rawExpiresIn = this.extractValue(tokenData, config?.tokenPaths?.expiresIn, [\n      'authed_user.expires_in',\n      'authed_user.expiresIn',\n      'expires_in',\n      'expiresIn',\n      'token.expires_in',\n      'token.expiresIn',\n    ]);\n\n    const parsedExpiresIn =\n      typeof rawExpiresIn === 'string' ? parseInt(rawExpiresIn, 10) : rawExpiresIn;\n\n    const expiresInSeconds = parsedExpiresIn || 3600;\n\n    const scope = this.extractValue(tokenData, config?.tokenPaths?.scope, [\n      'authed_user.scope',\n      'scope',\n      'token.scope',\n    ]);\n\n    const tokenType =\n      this.extractValue(tokenData, config?.tokenPaths?.tokenType, [\n        'authed_user.token_type',\n        'authed_user.tokenType',\n        'token_type',\n        'tokenType',\n        'token.token_type',\n        'token.tokenType',\n      ]) ?? 'Bearer';\n\n    return {\n      accessToken,\n      refreshToken: rawRefreshToken,\n      expiresAt: new Date(now + expiresInSeconds * 1000),\n      expiresIn: expiresInSeconds,\n      tokenType,\n      scope,\n      createdAt: now,\n      raw: rawResponse,\n    };\n  }\n\n  /**\n   * Extract a value from a nested object using a dot-notation path\n   * @param obj The object to extract from\n   * @param customPaths Custom path(s) provided by config (takes priority)\n   * @param defaultPaths Default fallback paths to try\n   * @returns The extracted value or undefined\n   */\n  private extractValue(\n    obj: Record<string, any>,\n    customPaths?: string | string[],\n    defaultPaths?: string[],\n  ): any {\n    // Try custom paths first if provided\n    if (customPaths) {\n      const paths = Array.isArray(customPaths) ? customPaths : [customPaths];\n      for (const path of paths) {\n        const value = this.getNestedValue(obj, path);\n        if (value !== undefined) return value;\n      }\n    }\n\n    // Fall back to default paths\n    if (defaultPaths) {\n      for (const path of defaultPaths) {\n        const value = this.getNestedValue(obj, path);\n        if (value !== undefined) return value;\n      }\n    }\n\n    return undefined;\n  }\n\n  /**\n   * Get a nested value from an object using dot notation (e.g., 'authed_user.access_token')\n   * @param obj The object to traverse\n   * @param path The dot-notation path\n   * @returns The value at the path or undefined\n   */\n  private getNestedValue(obj: Record<string, any>, path: string): any {\n    const keys = path.split('.');\n    let current: any = obj;\n\n    for (const key of keys) {\n      if (current && typeof current === 'object' && key in current) {\n        current = current[key];\n      } else {\n        return undefined;\n      }\n    }\n\n    return current;\n  }\n}\n","import { OAuth2Config, OAuth2Token } from '../types';\n\nimport { AuthorizationUrlStrategy } from '../strategies/authorization-url.strategy';\nimport { TokenExchangeStrategy } from '../strategies/token-exchange.strategy';\nimport { UserProfile } from './interfaces/profile-fetcher.interface';\nimport { BaseProfileFetcher } from '../profile/base-profile-fetcher';\n\nexport abstract class OAuth2Provider {\n  protected authUrlStrategy: AuthorizationUrlStrategy;\n  protected tokenStrategy: TokenExchangeStrategy;\n  protected profileFetcher?: BaseProfileFetcher;\n\n  constructor(\n    protected config: OAuth2Config,\n    authUrlStrategy?: AuthorizationUrlStrategy,\n    tokenStrategy?: TokenExchangeStrategy,\n    profileFetcher?: BaseProfileFetcher,\n  ) {\n    this.authUrlStrategy = authUrlStrategy || this.createAuthorizationUrlStrategy();\n    this.tokenStrategy = tokenStrategy || this.createTokenExchangeStrategy();\n    this.profileFetcher = profileFetcher;\n  }\n\n  // Factory methods\n  protected abstract createAuthorizationUrlStrategy(): AuthorizationUrlStrategy;\n  protected abstract createTokenExchangeStrategy(): TokenExchangeStrategy;\n\n  // Profile fetching methods\n  async fetchProfile(accessToken: string): Promise<UserProfile> {\n    if (!this.profileFetcher) {\n      throw new Error('Profile fetcher not configured for this provider');\n    }\n    return this.profileFetcher.fetchUserInfo(accessToken);\n  }\n\n  getProfileEndpoint(): string {\n    if (!this.profileFetcher) {\n      throw new Error('Profile fetcher not configured for this provider');\n    }\n    return this.profileFetcher.getEndpoint();\n  }\n\n  setProfileFetcher(profileFetcher: BaseProfileFetcher): void {\n    this.profileFetcher = profileFetcher;\n  }\n\n  hasProfileFetcher(): boolean {\n    return !!this.profileFetcher;\n  }\n\n  generateAuthorizationUrl(state: string, codeChallenge?: string): string {\n    return this.authUrlStrategy.generateAuthorizationUrl(this.config, state, codeChallenge);\n  }\n\n  async exchangeCodeForToken(code: string, codeVerifier?: string): Promise<OAuth2Token> {\n    return this.tokenStrategy.exchangeCodeForToken(code, this.config, codeVerifier);\n  }\n\n  async refreshToken(refreshToken: string): Promise<OAuth2Token> {\n    return this.tokenStrategy.refreshToken(refreshToken, this.config);\n  }\n}\n","import { AuthorizationUrlStrategy } from '../strategies/authorization-url.strategy';\nimport { StandardAuthorizationUrlStrategy } from '../strategies/standard-authorization-url.strategy';\nimport { StandardTokenExchangeStrategy } from '../strategies/standard-token-exchange.strategy';\nimport { TokenExchangeStrategy } from '../strategies/token-exchange.strategy';\nimport { OAuth2Provider } from './base.provider';\nimport { BaseProfileFetcher } from '../profile/base-profile-fetcher';\n\nexport class GenericOAuth2Provider extends OAuth2Provider {\n  constructor(\n    config: any,\n    authUrlStrategy?: AuthorizationUrlStrategy,\n    tokenStrategy?: TokenExchangeStrategy,\n    profileFetcher?: BaseProfileFetcher,\n  ) {\n    super(config, authUrlStrategy, tokenStrategy, profileFetcher);\n  }\n\n  protected createAuthorizationUrlStrategy(): AuthorizationUrlStrategy {\n    return new StandardAuthorizationUrlStrategy();\n  }\n\n  protected createTokenExchangeStrategy(): TokenExchangeStrategy {\n    return new StandardTokenExchangeStrategy();\n  }\n}\n","import { UserProfile } from '../providers/interfaces/profile-fetcher.interface';\n\nexport abstract class BaseProfileFetcher {\n  constructor(protected profileEndpoint: string) {}\n\n  /**\n   * Fetch user profile information from the OAuth provider\n   * @param accessToken The OAuth access token\n   * @returns Promise resolving to standardized user profile\n   */\n  async fetchUserInfo(accessToken: string): Promise<UserProfile> {\n    const response = await fetch(this.profileEndpoint, {\n      headers: {\n        Authorization: `Bearer ${accessToken}`,\n        Accept: 'application/json',\n        ...this.getAdditionalHeaders(),\n      },\n    });\n\n    if (!response.ok) {\n      throw new Error(\n        `Failed to fetch profile from ${this.profileEndpoint}: ${response.statusText}`,\n      );\n    }\n\n    const rawData = await response.json();\n    return this.mapToUserProfile(rawData);\n  }\n\n  /**\n   * Map the raw API response to our standardized UserProfile structure\n   * Override this method to customize mapping for different providers\n   * @param rawData The raw API response data\n   * @returns UserProfile with optional tenant information\n   */\n  protected abstract mapToUserProfile(rawData: any): UserProfile;\n\n  /**\n   * Get additional headers if needed for the profile request\n   * Override this method to add provider-specific headers\n   */\n  protected getAdditionalHeaders(): Record<string, string> {\n    return {};\n  }\n\n  /**\n   * Get the profile endpoint URL\n   */\n  getEndpoint(): string {\n    return this.profileEndpoint;\n  }\n}\n","import { BaseProfileFetcher } from './base-profile-fetcher';\nimport { UserProfile } from '../providers/interfaces/profile-fetcher.interface';\n\nexport class GoogleProfileFetcher extends BaseProfileFetcher {\n  constructor() {\n    super('https://www.googleapis.com/oauth2/v2/userinfo');\n  }\n\n  mapToUserProfile(rawData: any): UserProfile {\n    return {\n      email: rawData.email,\n      name: rawData.name,\n      id: rawData.id,\n      avatar: rawData.picture,\n      username: rawData.email,\n      raw: rawData,\n    };\n  }\n}\n","import { BaseProfileFetcher } from './base-profile-fetcher';\nimport { UserProfile } from '../providers/interfaces/profile-fetcher.interface';\n\nexport class GitHubProfileFetcher extends BaseProfileFetcher {\n  constructor() {\n    super('https://api.github.com/user');\n  }\n\n  protected mapToUserProfile(rawData: any): UserProfile {\n    return {\n      email: rawData.email,\n      name: rawData.name || rawData.login,\n      id: rawData.id?.toString(),\n      avatar: rawData.avatar_url,\n      username: rawData.login,\n      raw: rawData,\n    };\n  }\n\n  protected getAdditionalHeaders(): Record<string, string> {\n    return {\n      'User-Agent': 'OAuth2-Token-Manager', // GitHub requires User-Agent\n    };\n  }\n}\n","import { BaseProfileFetcher } from './base-profile-fetcher';\nimport { UserProfile } from '../providers/interfaces/profile-fetcher.interface';\n\nexport class MicrosoftProfileFetcher extends BaseProfileFetcher {\n  constructor() {\n    super('https://graph.microsoft.com/v1.0/me');\n  }\n\n  protected mapToUserProfile(rawData: any): UserProfile {\n    return {\n      email: rawData.mail || rawData.userPrincipalName,\n      name: rawData.displayName,\n      id: rawData.id,\n      avatar: undefined, // Microsoft Graph doesn't include avatar in basic profile\n      username: rawData.userPrincipalName,\n      raw: rawData,\n    };\n  }\n}\n","import { BaseProfileFetcher } from './base-profile-fetcher';\nimport { UserProfile } from '../providers/interfaces/profile-fetcher.interface';\n\nexport interface ProfileMapping {\n  email: string;\n  name?: string;\n  id?: string;\n  avatar?: string;\n  username?: string;\n  tenant?: string; // Path to tenant/workspace ID in the raw data\n  tenantName?: string; // Path to tenant/workspace name in the raw data\n}\n\nexport class GenericProfileFetcher extends BaseProfileFetcher {\n  constructor(\n    profileEndpoint: string,\n    private mapping?: ProfileMapping,\n    private additionalHeaders?: Record<string, string>,\n  ) {\n    super(profileEndpoint);\n  }\n\n  protected mapToUserProfile(rawData: any): UserProfile {\n    if (this.mapping) {\n      return {\n        email: this.getNestedProperty(rawData, this.mapping.email),\n        name: this.mapping.name ? this.getNestedProperty(rawData, this.mapping.name) : undefined,\n        id: this.mapping.id ? this.getNestedProperty(rawData, this.mapping.id) : undefined,\n        avatar: this.mapping.avatar\n          ? this.getNestedProperty(rawData, this.mapping.avatar)\n          : undefined,\n        username: this.mapping.username\n          ? this.getNestedProperty(rawData, this.mapping.username)\n          : undefined,\n        tenant: this.mapping.tenant\n          ? this.getNestedProperty(rawData, this.mapping.tenant)\n          : undefined,\n        tenantName: this.mapping.tenantName\n          ? this.getNestedProperty(rawData, this.mapping.tenantName)\n          : undefined,\n        raw: rawData,\n      };\n    }\n\n    // Default generic mapping\n    return {\n      email: rawData.email || rawData.mail || rawData.emailAddress,\n      name: rawData.name || rawData.displayName || rawData.full_name,\n      id: rawData.id || rawData.sub || rawData.user_id,\n      avatar: rawData.avatar || rawData.picture || rawData.avatar_url,\n      username: rawData.username || rawData.login || rawData.preferred_username,\n      tenant: rawData.tenant || rawData.workspace_id || rawData.organization_id || rawData.team_id,\n      tenantName:\n        rawData.tenantName ||\n        rawData.workspace_name ||\n        rawData.organization_name ||\n        rawData.team_name,\n      raw: rawData,\n    };\n  }\n\n  protected getAdditionalHeaders(): Record<string, string> {\n    return this.additionalHeaders || {};\n  }\n\n  private getNestedProperty(obj: any, path: string): any {\n    return path.split('.').reduce((current, key) => current?.[key], obj);\n  }\n}\n","import { BaseProfileFetcher } from './base-profile-fetcher';\nimport { GoogleProfileFetcher } from './google-profile-fetcher';\nimport { GitHubProfileFetcher } from './github-profile-fetcher';\nimport { MicrosoftProfileFetcher } from './microsoft-profile-fetcher';\nimport { GenericProfileFetcher, ProfileMapping } from './generic-profile-fetcher';\nimport { ProviderType } from '../providers/provider.factory';\nimport { OAuth2Config } from '../types';\n\nexport interface ProfileFetcherOptions {\n  profileUrl?: string;\n  profileMapping?: ProfileMapping;\n  profileHeaders?: Record<string, string>;\n}\n\nexport class ProfileFetcherFactory {\n  static createProfileFetcher(\n    providerType: ProviderType,\n    config: OAuth2Config,\n    options?: ProfileFetcherOptions,\n    customFetcher?: BaseProfileFetcher,\n  ): BaseProfileFetcher | undefined {\n    // If a custom fetcher is provided, use it directly\n    if (customFetcher) {\n      return customFetcher;\n    }\n\n    // If custom options are provided, use GenericProfileFetcher\n    if (options?.profileUrl) {\n      return new GenericProfileFetcher(\n        options.profileUrl,\n        options.profileMapping,\n        options.profileHeaders,\n      );\n    }\n\n    // Use provider-specific fetchers for known providers\n    switch (providerType) {\n      case 'google':\n        return new GoogleProfileFetcher();\n      case 'github':\n        return new GitHubProfileFetcher();\n      case 'microsoft':\n      case 'outlook':\n        return new MicrosoftProfileFetcher();\n      case 'facebook':\n        return new GenericProfileFetcher(\n          'https://graph.facebook.com/me?fields=id,name,email,picture',\n        );\n      case 'generic':\n      default:\n        // For generic providers, use the profileUrl from config if available\n        const profileUrl = config.profileUrl || config.userInfoUrl;\n        if (!profileUrl) {\n          // Return undefined instead of throwing - profileUrl is optional if custom fetcher will be set later\n          return undefined;\n        }\n        return new GenericProfileFetcher(profileUrl);\n    }\n  }\n\n  static registerCustomProfileFetcher(\n    providerName: string,\n    profileFetcher: BaseProfileFetcher,\n  ): void {\n    // Store custom profile fetchers for later use\n    this.customFetchers.set(providerName, profileFetcher);\n  }\n\n  private static customFetchers = new Map<string, BaseProfileFetcher>();\n\n  static getCustomProfileFetcher(providerName: string): BaseProfileFetcher | undefined {\n    return this.customFetchers.get(providerName);\n  }\n}\n","import { OAuth2Config } from '../types';\nimport { OAuth2Provider } from './base.provider';\nimport { GenericOAuth2Provider } from './generic.provider';\nimport { ProfileFetcherFactory } from '../profile/profile-fetcher-factory';\n\nexport type ProviderType = 'google' | 'github' | 'microsoft' | 'outlook' | 'facebook' | 'generic';\n\nexport interface ProviderFactory {\n  createProvider(\n    type: ProviderType,\n    config: OAuth2Config,\n    customProfileFetcher?: import('../profile/base-profile-fetcher').BaseProfileFetcher,\n  ): OAuth2Provider;\n}\n\nexport class OAuth2ProviderFactory implements ProviderFactory {\n  private static presetConfigs: Record<string, Partial<OAuth2Config>> = {\n    google: {\n      authorizationUrl: 'https://accounts.google.com/o/oauth2/v2/auth',\n      tokenUrl: 'https://oauth2.googleapis.com/token',\n      profileUrl: 'https://www.googleapis.com/oauth2/v2/userinfo',\n      usePKCE: true,\n      extraAuthParams: {\n        access_type: 'offline',\n        prompt: 'consent',\n      },\n    },\n    github: {\n      authorizationUrl: 'https://github.com/login/oauth/authorize',\n      tokenUrl: 'https://github.com/login/oauth/access_token',\n      profileUrl: 'https://api.github.com/user',\n    },\n    microsoft: {\n      authorizationUrl: 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize',\n      tokenUrl: 'https://login.microsoftonline.com/common/oauth2/v2.0/token',\n      profileUrl: 'https://graph.microsoft.com/v1.0/me',\n      usePKCE: true,\n    },\n    outlook: {\n      authorizationUrl: 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize',\n      tokenUrl: 'https://login.microsoftonline.com/common/oauth2/v2.0/token',\n      profileUrl: 'https://graph.microsoft.com/v1.0/me',\n      usePKCE: true,\n      extraAuthParams: {\n        prompt: 'select_account',\n      },\n    },\n    facebook: {\n      authorizationUrl: 'https://www.facebook.com/v12.0/dialog/oauth',\n      tokenUrl: 'https://graph.facebook.com/v12.0/oauth/access_token',\n      profileUrl: 'https://graph.facebook.com/me?fields=id,name,email,picture',\n    },\n  };\n\n  createProvider(\n    type: ProviderType,\n    config: OAuth2Config,\n    customProfileFetcher?: import('../profile/base-profile-fetcher').BaseProfileFetcher,\n  ): OAuth2Provider {\n    const presetConfig = type !== 'generic' ? OAuth2ProviderFactory.presetConfigs[type] || {} : {};\n\n    // Only override preset values if the user explicitly provides them (not empty strings)\n    const mergedConfig: OAuth2Config = {\n      ...presetConfig,\n      ...config,\n      // Don't override preset URLs with empty strings\n      authorizationUrl: config.authorizationUrl || presetConfig.authorizationUrl || '',\n      tokenUrl: config.tokenUrl || presetConfig.tokenUrl || '',\n      profileUrl: config.profileUrl || presetConfig.profileUrl,\n      extraAuthParams: {\n        ...(presetConfig.extraAuthParams || {}),\n        ...(config.extraAuthParams || {}),\n      },\n    };\n\n    const profileFetcher = ProfileFetcherFactory.createProfileFetcher(\n      type,\n      mergedConfig,\n      undefined,\n      customProfileFetcher,\n    );\n\n    return new GenericOAuth2Provider(mergedConfig, undefined, undefined, profileFetcher);\n  }\n\n  static registerPreset(name: string, config: Partial<OAuth2Config>): void {\n    OAuth2ProviderFactory.presetConfigs[name] = config;\n  }\n\n  static getPresetConfig(name: string): Partial<OAuth2Config> | undefined {\n    return OAuth2ProviderFactory.presetConfigs[name];\n  }\n}\n","import { AuthorizationState } from '../types';\nimport {\n  StorageAdapter,\n  StoredToken,\n  SaveTokenInput,\n  UpdateTokenInput,\n  TokenQuery,\n} from './interfaces';\nimport { BaseProfileFetcher } from '../profile/base-profile-fetcher';\n\nexport class InMemoryStorageAdapter implements StorageAdapter {\n  private tokens: Map<string, StoredToken> = new Map();\n  private states: Map<string, AuthorizationState> = new Map();\n  private profileFetchers: Map<string, BaseProfileFetcher> = new Map();\n\n  private generateId(): string {\n    return Math.random().toString(36).substring(2) + Date.now().toString(36);\n  }\n\n  // Token operations\n  async saveToken(input: SaveTokenInput): Promise<StoredToken> {\n    // Check if token with same provider + email + tenant exists\n    const existingToken = await this.getToken(input.provider, input.email, input.tenant);\n\n    if (existingToken) {\n      // Replace existing token\n      const updatedToken: StoredToken = {\n        ...existingToken,\n        ...input,\n        id: existingToken.id,\n        createdAt: existingToken.createdAt,\n        updatedAt: new Date(),\n      };\n      this.tokens.set(existingToken.id, updatedToken);\n      return updatedToken;\n    }\n\n    // Create new token\n    const newToken: StoredToken = {\n      ...input,\n      id: this.generateId(),\n      createdAt: new Date(),\n      updatedAt: new Date(),\n    };\n    this.tokens.set(newToken.id, newToken);\n    return newToken;\n  }\n\n  async queryTokens(query: TokenQuery): Promise<StoredToken[]> {\n    let tokens = Array.from(this.tokens.values());\n\n    // Apply filters\n    if (query.id) {\n      tokens = tokens.filter((t) => t.id === query.id);\n    }\n    if (query.provider) {\n      tokens = tokens.filter((t) => t.provider === query.provider);\n    }\n    if (query.userId) {\n      tokens = tokens.filter((t) => t.userId === query.userId);\n    }\n    if (query.email) {\n      tokens = tokens.filter((t) => t.email === query.email);\n    }\n    if (query.tenant !== undefined) {\n      tokens = tokens.filter((t) => t.tenant === query.tenant);\n    }\n\n    // Filter out expired tokens unless explicitly requested\n    if (!query.includeExpired) {\n      const now = new Date().getTime();\n      tokens = tokens.filter((t) => {\n        const expiresAt = new Date(t.token.expiresAt).getTime();\n        return expiresAt >= now;\n      });\n    }\n\n    // Apply pagination\n    if (query.offset !== undefined) {\n      tokens = tokens.slice(query.offset);\n    }\n    if (query.limit !== undefined) {\n      tokens = tokens.slice(0, query.limit);\n    }\n\n    return tokens;\n  }\n\n  async getToken(provider: string, email: string, tenant?: string): Promise<StoredToken | null> {\n    const results = await this.queryTokens({ provider, email, tenant, includeExpired: true });\n    return results[0] || null;\n  }\n\n  async getTokenById(id: string): Promise<StoredToken | null> {\n    const results = await this.queryTokens({ id, includeExpired: true });\n    return results[0] || null;\n  }\n\n  async getTokensByUserId(userId: string): Promise<StoredToken[]> {\n    return this.queryTokens({ userId });\n  }\n\n  async getTokensByEmail(email: string): Promise<StoredToken[]> {\n    return this.queryTokens({ email });\n  }\n\n  async getTokensByProvider(provider: string): Promise<StoredToken[]> {\n    return this.queryTokens({ provider });\n  }\n\n  async getAccounts(userId: string, provider: string): Promise<StoredToken[]> {\n    return this.queryTokens({ userId, provider });\n  }\n\n  async getTokensForEmail(\n    userId: string,\n    provider: string,\n    email: string,\n  ): Promise<StoredToken | null> {\n    const results = await this.queryTokens({ userId, provider, email });\n    return results[0] || null;\n  }\n\n  async getTokens(userId: string, provider: string): Promise<StoredToken[]> {\n    return this.queryTokens({ userId, provider });\n  }\n\n  async updateToken(id: string, update: UpdateTokenInput): Promise<StoredToken | null> {\n    const token = this.tokens.get(id);\n    if (!token) return null;\n\n    const updatedToken: StoredToken = {\n      ...token,\n      ...(update.token && { token: update.token }),\n      ...(update.metadata && { metadata: { ...token.metadata, ...update.metadata } }),\n      updatedAt: new Date(),\n    };\n    this.tokens.set(id, updatedToken);\n    return updatedToken;\n  }\n\n  async deleteToken(id: string): Promise<boolean> {\n    return this.tokens.delete(id);\n  }\n\n  async deleteTokenByProviderEmail(\n    provider: string,\n    email: string,\n    tenant?: string,\n  ): Promise<boolean> {\n    const token = await this.getToken(provider, email, tenant);\n    if (!token) return false;\n    return this.tokens.delete(token.id);\n  }\n\n  async deleteExpiredTokens(): Promise<number> {\n    const now = new Date().getTime();\n    const expiredTokens = Array.from(this.tokens.entries())\n      .filter(([, token]) => {\n        const expiresAt = new Date(token.token.expiresAt).getTime();\n        return expiresAt < now;\n      })\n      .map(([id]) => id);\n\n    expiredTokens.forEach((id) => this.tokens.delete(id));\n    return expiredTokens.length;\n  }\n\n  // Authorization state operations\n  async saveAuthorizationState(\n    state: Omit<AuthorizationState, 'createdAt'>,\n  ): Promise<AuthorizationState> {\n    const newState: AuthorizationState = {\n      ...state,\n      createdAt: new Date(Date.now()),\n    };\n    this.states.set(state.state, newState);\n    return newState;\n  }\n\n  async getAuthorizationState(state: string): Promise<AuthorizationState | null> {\n    return this.states.get(state) || null;\n  }\n\n  async deleteAuthorizationState(state: string): Promise<boolean> {\n    return this.states.delete(state);\n  }\n\n  async cleanupExpiredStates(): Promise<number> {\n    const now = new Date().getTime();\n    const maxAge = 10 * 60 * 1000; // 10 minutes\n\n    const expiredStates = Array.from(this.states.entries())\n      .filter(([, state]) => {\n        const stateAge = now - state.createdAt.getTime();\n        return stateAge > maxAge;\n      })\n      .map(([key]) => key);\n\n    expiredStates.forEach((key) => this.states.delete(key));\n    return expiredStates.length;\n  }\n\n  // Profile fetcher operations\n  registerProfileFetcher(providerName: string, fetcher: BaseProfileFetcher): void {\n    this.profileFetchers.set(providerName, fetcher);\n  }\n\n  getProfileFetcher(providerName: string): BaseProfileFetcher | undefined {\n    return this.profileFetchers.get(providerName);\n  }\n\n  getProfileFetchers(): Map<string, BaseProfileFetcher> {\n    return new Map(this.profileFetchers);\n  }\n}\n","import { createHash, randomBytes } from 'crypto';\n\nexport const createCodeVerifier = () =>\n  randomBytes(32)\n    .toString('base64')\n    .replace(/[^a-zA-Z0-9]/g, '')\n    .substring(0, 128);\n\nexport const createCodeChallenge = (verifier: string): string => {\n  return createHash('sha256').update(verifier).digest('base64url');\n};\n\nexport const generateState = (): string => {\n  return randomBytes(16).toString('base64url');\n};\n","import { OAuth2Config, OAuth2Token, AuthorizationState } from '../types';\nimport { OAuth2ProviderFactory, ProviderType } from '../providers/provider.factory';\nimport { StorageAdapter, StoredToken, TokenQuery } from '../storage/interfaces';\nimport { InMemoryStorageAdapter } from '../storage/memory.adapter';\nimport { ProviderFactory } from '../providers/provider.factory';\nimport { createCodeVerifier, createCodeChallenge, generateState } from '../utils/crypto';\nimport { OAuth2Provider } from '../providers/base.provider';\nimport { UserProfile } from '../providers/interfaces/profile-fetcher.interface';\n\nexport interface OAuth2Options {\n  storage?: StorageAdapter;\n  providers?: Record<string, OAuth2Config>;\n  autoRefresh?: AutoRefreshOptions;\n}\n\nexport interface AutoRefreshOptions {\n  enabled?: boolean;\n  refreshBuffer?: number; // minutes before expiry to refresh\n  onRefreshError?: (error: Error, token: StoredToken) => void;\n}\n\nexport interface AuthorizationOptions {\n  provider: string;\n  userId: string;\n  email: string;\n  tenant?: string; // For multi-tenant providers like Slack\n  tenantName?: string; // Human-readable tenant name\n  scopes?: string[];\n  metadata?: Record<string, any>;\n  usePKCE?: boolean;\n}\n\nexport interface TokenOptions {\n  autoRefresh?: boolean;\n  refreshBuffer?: number; // minutes before expiry to refresh\n  expirationBuffer?: number; // seconds before expiry to consider expired\n  defaultExpiresIn?: number; // default expiration in seconds\n}\n\nexport interface CallbackResult {\n  token: StoredToken;\n  profile?: UserProfile;\n}\n\nexport class OAuth2Client {\n  private storage: StorageAdapter;\n  private providerFactory: ProviderFactory;\n  private providers: Map<string, OAuth2Provider> = new Map();\n  private providerConfigs: Map<string, OAuth2Config> = new Map();\n  private now: () => number;\n  private autoRefreshOptions: AutoRefreshOptions;\n\n  constructor(options: OAuth2Options = {}) {\n    this.storage = options.storage || new InMemoryStorageAdapter();\n    this.providerFactory = new OAuth2ProviderFactory();\n    this.now = Date.now;\n\n    // Set default auto-refresh options - enabled by default\n    this.autoRefreshOptions = {\n      enabled: options.autoRefresh?.enabled ?? true, // Enabled by default\n      refreshBuffer: options.autoRefresh?.refreshBuffer ?? 10, // 10 minutes before expiry (safe for Google's 1-hour tokens)\n      onRefreshError: options.autoRefresh?.onRefreshError,\n    };\n\n    // Register predefined providers\n    if (options.providers) {\n      Object.entries(options.providers).forEach(([name, config]) => {\n        this.registerProvider(name, config);\n      });\n    }\n  }\n\n  /**\n   * Register a provider configuration\n   */\n  registerProvider(name: string, config: OAuth2Config): void {\n    this.providerConfigs.set(name, config);\n\n    // Check if storage has a custom profile fetcher for this provider\n    const customFetcher = this.storage.getProfileFetcher(name);\n\n    // Determine provider type based on configuration\n    const providerType = this.detectProviderType(name, config);\n    const provider = this.providerFactory.createProvider(providerType, config, customFetcher);\n\n    this.providers.set(name, provider);\n  }\n\n  /**\n   * Start OAuth2 authorization flow\n   */\n  async authorize(options: AuthorizationOptions): Promise<{ url: string; state: string }> {\n    const provider = this.providers.get(options.provider);\n    if (!provider) throw new Error(`Provider ${options.provider} not found`);\n\n    const state = generateState();\n    let authUrl: string;\n    let authState: Omit<AuthorizationState, 'createdAt'>;\n\n    const requiresPKCE = this.providerConfigs.get(options.provider)?.usePKCE || options.usePKCE;\n\n    if (requiresPKCE) {\n      const codeVerifier = createCodeVerifier();\n      const codeChallenge = createCodeChallenge(codeVerifier);\n      authUrl = provider.generateAuthorizationUrl(state, codeChallenge);\n      authState = {\n        state,\n        codeVerifier,\n        config: this.providerConfigs.get(options.provider)!,\n        metadata: {\n          ...options.metadata,\n          userId: options.userId,\n          email: options.email,\n          provider: options.provider,\n          tenant: options.tenant,\n          tenantName: options.tenantName,\n        },\n      };\n    } else {\n      authUrl = provider.generateAuthorizationUrl(state);\n      authState = {\n        state,\n        config: this.providerConfigs.get(options.provider)!,\n        metadata: {\n          ...options.metadata,\n          userId: options.userId,\n          email: options.email,\n          provider: options.provider,\n          tenant: options.tenant,\n          tenantName: options.tenantName,\n        },\n      };\n    }\n\n    await this.storage.saveAuthorizationState(authState);\n    return { url: authUrl, state };\n  }\n\n  /**\n   * Handle OAuth2 callback\n   */\n  async handleCallback(code: string, state: string): Promise<CallbackResult> {\n    const authState = await this.storage.getAuthorizationState(state);\n    if (!authState) throw new Error('Invalid or expired state');\n\n    const provider = authState.metadata?.provider;\n    if (!provider) throw new Error('Provider not found in authorization state');\n\n    const providerInstance = this.providers.get(provider);\n    if (!providerInstance) throw new Error(`Provider ${provider} not found`);\n\n    // Exchange code for tokens\n    const tokens = await providerInstance.exchangeCodeForToken(code, authState.codeVerifier);\n\n    // Extract user data from metadata\n    const userId = authState.metadata?.userId;\n    const email = authState.metadata?.email;\n    const tenant = authState.metadata?.tenant;\n    const tenantName = authState.metadata?.tenantName;\n\n    if (!userId || !email) {\n      throw new Error('User ID and email are required in authorization state');\n    }\n\n    // Fetch profile if available\n    let profile: UserProfile | undefined;\n    if (providerInstance.hasProfileFetcher()) {\n      try {\n        profile = await providerInstance.fetchProfile(tokens.accessToken);\n      } catch (error) {\n        console.warn('Failed to fetch user profile:', error);\n      }\n    }\n\n    // Save token - use profile data if available, otherwise fall back to authorization state\n    const savedToken = await this.storage.saveToken({\n      provider,\n      userId,\n      email: profile?.email || email,\n      tenant: profile?.tenant || tenant,\n      tenantName: profile?.tenantName || tenantName,\n      token: tokens,\n      metadata: {\n        ...authState.metadata,\n        profileFetched: !!profile,\n      },\n    });\n\n    // Clean up authorization state\n    await this.storage.deleteAuthorizationState(state);\n\n    // Call onSuccess callback if defined\n    const config = this.providerConfigs.get(provider);\n    if (config?.onSuccess) {\n      await config.onSuccess(userId, tokens);\n    }\n\n    return {\n      token: savedToken,\n      profile,\n    };\n  }\n\n  /**\n   * Get a valid access token (auto-refresh if needed)\n   */\n  async getAccessToken(\n    provider: string,\n    email: string,\n    options: TokenOptions & { tenant?: string } = {},\n  ): Promise<string> {\n    const token = await this.getValidToken(provider, email, options);\n    return token.accessToken;\n  }\n\n  /**\n   * Get a valid token (auto-refresh if needed)\n   */\n  async getValidToken(\n    provider: string,\n    email: string,\n    options: TokenOptions & { tenant?: string } = {},\n  ): Promise<OAuth2Token> {\n    const storedToken = await this.storage.getToken(provider, email, options.tenant);\n    if (!storedToken) {\n      const tenantInfo = options.tenant ? ` and tenant ${options.tenant}` : '';\n      throw new Error(`No token found for provider ${provider}, email ${email}${tenantInfo}`);\n    }\n\n    const needsRefresh =\n      options.autoRefresh !== false && this.isTokenExpired(storedToken.token, options);\n\n    if (!needsRefresh) {\n      return storedToken.token;\n    }\n\n    // Refresh the token\n    if (!storedToken.token.refreshToken) {\n      throw new Error('Token expired and no refresh token available');\n    }\n\n    const providerInstance = this.providers.get(provider);\n    if (!providerInstance) throw new Error(`Provider ${provider} not found`);\n\n    const newToken = await providerInstance.refreshToken(storedToken.token.refreshToken);\n    await this.storage.updateToken(storedToken.id, { token: newToken });\n\n    return newToken;\n  }\n\n  /**\n   * Query tokens with automatic refresh\n   */\n  async queryTokens(query: TokenQuery): Promise<StoredToken[]> {\n    // When auto-refresh is enabled, we need to include expired tokens\n    // so we can attempt to refresh them\n    const queryWithExpired =\n      this.autoRefreshOptions.enabled && !query.includeExpired\n        ? { ...query, includeExpired: true }\n        : query;\n\n    const tokens = await this.storage.queryTokens(queryWithExpired);\n\n    if (this.autoRefreshOptions.enabled && !query.includeExpired) {\n      const refreshedTokens = await this.refreshTokensIfNeeded(tokens);\n      // Filter out tokens that are still expired after refresh attempt\n      return refreshedTokens.filter((token) => {\n        const expiresAt = new Date(token.token.expiresAt).getTime();\n        return expiresAt > this.now();\n      });\n    }\n\n    return tokens;\n  }\n\n  /**\n   * Get all tokens for a user\n   */\n  async getTokensByUserId(userId: string): Promise<StoredToken[]> {\n    return this.queryTokens({ userId });\n  }\n\n  /**\n   * Get all tokens for an email\n   */\n  async getTokensByEmail(email: string): Promise<StoredToken[]> {\n    return this.queryTokens({ email });\n  }\n\n  /**\n   * Delete a token\n   */\n  async deleteToken(provider: string, email: string, tenant?: string): Promise<boolean> {\n    return this.storage.deleteTokenByProviderEmail(provider, email, tenant);\n  }\n\n  /**\n   * Delete all expired tokens\n   */\n  async cleanupExpiredTokens(): Promise<number> {\n    return this.storage.deleteExpiredTokens();\n  }\n\n  /**\n   * Clean up expired authorization states\n   */\n  async cleanupExpiredStates(): Promise<number> {\n    return this.storage.cleanupExpiredStates();\n  }\n\n  // Helper methods\n  private isTokenExpired(token: OAuth2Token, options: TokenOptions = {}): boolean {\n    const { expirationBuffer = 300 } = options;\n\n    if (token.createdAt && token.expiresIn !== undefined) {\n      const expiresAt = token.createdAt + token.expiresIn * 1000;\n      const effectiveNow = this.now() + expirationBuffer * 1000;\n      return effectiveNow >= expiresAt;\n    }\n\n    const expiresAt = new Date(token.expiresAt).getTime();\n    const effectiveNow = this.now() + expirationBuffer * 1000;\n    return effectiveNow >= expiresAt;\n  }\n\n  private detectProviderType(name: string, config: OAuth2Config): ProviderType {\n    // Try to detect based on the authorization URL\n    const authUrl = config.authorizationUrl.toLowerCase();\n\n    // Check for known providers that have specific implementations\n    if (authUrl.includes('accounts.google.com')) return 'google';\n    if (authUrl.includes('github.com')) return 'github';\n    if (authUrl.includes('facebook.com')) return 'facebook';\n    if (authUrl.includes('microsoft.com') || authUrl.includes('microsoftonline.com')) {\n      // Check if it's specifically for Outlook\n      if (\n        name.toLowerCase().includes('outlook') ||\n        config.scopes?.some((s) => s.includes('outlook'))\n      ) {\n        return 'outlook';\n      }\n      return 'microsoft';\n    }\n\n    // Default to generic provider for all others\n    return 'generic';\n  }\n\n  /**\n   * Refresh tokens if they are near expiration\n   */\n  private async refreshTokensIfNeeded(tokens: StoredToken[]): Promise<StoredToken[]> {\n    const refreshPromises = tokens.map(async (token) => {\n      if (this.shouldRefreshToken(token)) {\n        try {\n          const provider = this.providers.get(token.provider);\n          if (!provider) {\n            console.warn(`Provider ${token.provider} not found for token refresh`);\n            return token;\n          }\n\n          if (!token.token.refreshToken) {\n            console.warn(`No refresh token available for ${token.provider}:${token.email}`);\n            return token;\n          }\n\n          const newToken = await provider.refreshToken(token.token.refreshToken);\n          const updated = await this.storage.updateToken(token.id, { token: newToken });\n          return updated || token;\n        } catch (error) {\n          if (this.autoRefreshOptions.onRefreshError) {\n            this.autoRefreshOptions.onRefreshError(error as Error, token);\n          }\n          console.error(`Failed to refresh token for ${token.provider}:${token.email}:`, error);\n          return token;\n        }\n      }\n      return token;\n    });\n\n    return Promise.all(refreshPromises);\n  }\n\n  /**\n   * Check if a token should be refreshed\n   */\n  private shouldRefreshToken(storedToken: StoredToken): boolean {\n    // Skip if no refresh token\n    if (!storedToken.token.refreshToken) {\n      return false;\n    }\n\n    // Check if token is expired or near expiration\n    const expiresAt = new Date(storedToken.token.expiresAt).getTime();\n    const now = this.now();\n\n    // If already expired, definitely try to refresh\n    if (now >= expiresAt) {\n      return true;\n    }\n\n    // Otherwise, check if within refresh buffer\n    const bufferMs = this.autoRefreshOptions.refreshBuffer! * 60 * 1000;\n    const shouldRefreshAt = expiresAt - bufferMs;\n\n    return now >= shouldRefreshAt;\n  }\n\n  /**\n   * Update auto-refresh options\n   */\n  updateAutoRefreshOptions(options: Partial<AutoRefreshOptions>): void {\n    this.autoRefreshOptions = { ...this.autoRefreshOptions, ...options };\n  }\n\n  /**\n   * Get all tokens for a specific provider and user across all tenants\n   */\n  async getTokensAcrossTenants(provider: string, userId: string): Promise<StoredToken[]> {\n    return this.queryTokens({ provider, userId });\n  }\n\n  /**\n   * Get all tenants for a specific provider and email\n   */\n  async getTenants(provider: string, email: string): Promise<string[]> {\n    const tokens = await this.queryTokens({ provider, email });\n    const tenants = tokens\n      .map((t) => t.tenant)\n      .filter((tenant): tenant is string => tenant !== undefined);\n    return [...new Set(tenants)]; // Return unique tenants\n  }\n\n  /**\n   * Get token by tenant name (useful for Slack workspaces with human-readable names)\n   */\n  async getTokenByTenantName(\n    provider: string,\n    email: string,\n    tenantName: string,\n  ): Promise<StoredToken | null> {\n    const tokens = await this.queryTokens({ provider, email });\n    return tokens.find((t) => t.tenantName === tenantName) || null;\n  }\n\n  /**\n   * Check if a token exists for a specific tenant\n   */\n  async hasTokenForTenant(provider: string, email: string, tenant: string): Promise<boolean> {\n    const token = await this.storage.getToken(provider, email, tenant);\n    return token !== null;\n  }\n\n  /**\n   * Get all tokens with their tenant information\n   */\n  async getMultiTenantTokens(\n    provider: string,\n    email: string,\n  ): Promise<Array<{ token: StoredToken; tenant?: string; tenantName?: string }>> {\n    const tokens = await this.queryTokens({ provider, email });\n    return tokens.map((token) => ({\n      token,\n      tenant: token.tenant,\n      tenantName: token.tenantName,\n    }));\n  }\n}\n","import { sealData, unsealData } from 'iron-session';\n\nexport const seal = <T>(d: T, key: string) => sealData(d, { password: key });\nexport const unseal = <T>(s: string, key: string) => unsealData<T>(s, { password: key });\n"]}