najm-auth 0.1.6 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of najm-auth might be problematic. Click here for more details.

package/dist/index.mjs CHANGED
@@ -1,12 +1,2998 @@
1
- var ns=Object.defineProperty;var os=(e,t)=>{for(var a in t)ns(e,a,{get:t[a],enumerable:!0,configurable:!0,set:(i)=>t[a]=()=>i})};var n=function(e,t,a,i){var l=arguments.length,c=l<3?t:i===null?i=Object.getOwnPropertyDescriptor(t,a):i,d;if(typeof Reflect==="object"&&typeof Reflect.decorate==="function")c=Reflect.decorate(e,t,a,i);else for(var E=e.length-1;E>=0;E--)if(d=e[E])c=(l<3?d(c):l>3?d(t,a,c):d(t,a))||c;return l>3&&c&&Object.defineProperty(t,a,c),c},u=(e,t)=>(a,i)=>t(a,i,e),r=(e,t)=>{if(typeof Reflect==="object"&&typeof Reflect.metadata==="function")return Reflect.metadata(e,t)};import{Injectable as cs}from"najm-api";import Fe from"bcrypt";class J{constructor(){}async hashPassword(e){if(!e)return null;if(typeof e!=="string"||e.trim().length===0)return null;return Fe.hash(e,10)}async comparePassword(e,t){return Fe.compare(e,t)}}J=n([cs(),r("design:paramtypes",[])],J);import{setCookie as us,Injectable as ps,deleteCookie as ls}from"najm-api";import ms from"timestring";class G{setRefreshCookie(e){let t=ms(process.env.REFRESH_EXPIRES_IN,"s");us("refreshToken",e,{httpOnly:!1,sameSite:"Lax",maxAge:t,path:"/api/auth/refresh"})}clearRefreshCookie(){ls("refreshToken",{httpOnly:!1,sameSite:"Lax",path:"/api/auth/refresh",maxAge:0})}}G=n([ps()],G);import{Controller as Ds,Get as He,Post as We,Params as Qs,Body as Xe,User as Zs,t as ne}from"najm-api";import{t as ct}from"najm-api";import{Injectable as Ws,getCurrentLanguage as Xs}from"najm-api";import{rolesTable as U,usersTable as y,permissionsTable as Ve,rolePermissionsTable as be}from"@/database/schema";import{eq as T,ne as ys}from"drizzle-orm";import{Repository as ds}from"najm-api";class M{getUser(){return{id:y.id,email:y.email,emailVerified:y.emailVerified,image:y.image,status:y.status,roleId:y.roleId,role:U.name,createdAt:y.createdAt,updatedAt:y.updatedAt}}async getAll(){let e=await this.db.select(this.getUser()).from(y).leftJoin(U,T(y.roleId,U.id));return Promise.all(e.map(async(t)=>({...t,permissions:await this.getUserPermissions(t.id)})))}async getById(e){let[t]=await this.db.select(this.getUser()).from(y).leftJoin(U,T(y.roleId,U.id)).where(T(y.id,e)).limit(1);if(!t)return t;return{...t,permissions:await this.getUserPermissions(t.id)}}async getByEmail(e){let[t]=await this.db.select(this.getUser()).from(y).leftJoin(U,T(y.roleId,U.id)).where(T(y.email,e));return t}async create(e){let[t]=await this.db.insert(y).values(e).returning();return t}async update(e,t){let[a]=await this.db.update(y).set(t).where(T(y.id,e)).returning();return a}async delete(e){let[t]=await this.db.delete(y).where(T(y.id,e)).returning();return t}async deleteAll(){let e=await this.db.select({id:U.id}).from(U).where(T(U.name,"admin")).limit(1);if(e.length===0)return await this.db.delete(y).returning();return await this.db.delete(y).where(ys(y.roleId,e[0].id)).returning()}async getRoleNameById(e){let[t]=await this.db.select({roleName:U.name}).from(y).leftJoin(U,T(y.roleId,U.id)).where(T(y.id,e));return t.roleName}async getUserPassword(e){let[t]=await this.db.select({id:y.id,email:y.email,password:y.password}).from(y).where(T(y.email,e)).limit(1);return t.password}async getUserPermissions(e){let[t]=await this.db.select({roleId:y.roleId}).from(y).where(T(y.id,e)).limit(1);if(!t||!t.roleId)return[];return(await this.db.select({name:Ve.name}).from(be).leftJoin(Ve,T(be.permissionId,Ve.id)).where(T(be.roleId,t.roleId))).map((i)=>i.name).filter((i)=>i)}}M=n([ds()],M);import{Injectable as hs,t as j}from"najm-api";import{parseSchema as gs}from"@/shared";import{userSchema as fs}from"@/lib/validations";class C{userRepository;encryptionService;constructor(e,t){this.userRepository=e;this.encryptionService=t}async validateCreateUser(e){return gs(fs,e)}async isEmailExists(e){return!!await this.userRepository.getByEmail(e)}async isPasswordValid(e,t){return!!await this.encryptionService.comparePassword(e,t)}async isUserExist(e){return!!await this.userRepository.getById(e)}async checkUserIdIsUnique(e){if(!e)return;if(await this.userRepository.getById(e))throw new Error(j("users.errors.idExists"))}async isCorrectPass(e){return e&&typeof e==="string"&&e.trim().length>0}async hasRole(e,t){let a=await this.userRepository.getRoleNameById(e);if(!a)throw Error(j("auth.errors.accessDenied"));if(!t.some((l)=>a.toLowerCase()===l.toLowerCase()))throw Error(j("auth.errors.accessDenied"));return!0}async checkUserExistsByEmail(e){let t=await this.userRepository.getByEmail(e);if(!t)throw new Error(j("auth.errors.invalidCredentials"));return t}async checkUserExists(e){let t=await this.isUserExist(e);if(!t)throw new Error(j("users.errors.notFound"));return t}async checkEmailUnique(e,t=null){if(!e)return;let a=await this.userRepository.getByEmail(e);if(a&&a.id!==t)throw new Error(j("auth.errors.emailExists"))}async checkEmailExists(e){let t=await this.userRepository.getByEmail(e);if(!t)throw new Error(j("users.errors.notFound"));return t}async checkPasswordValid(e,t){if(!await this.isPasswordValid(e,t))throw new Error(j("auth.errors.invalidCredentials"))}}C=n([hs(),r("design:paramtypes",[typeof M==="undefined"?Object:M,typeof J==="undefined"?Object:J])],C);import{Injectable as Vs,setLanguage as bs,getCurrentLanguage as _s,Transactional as $s}from"najm-api";import{rolesTable as P}from"@/database/schema";import{eq as ke}from"drizzle-orm";import{Repository as ws}from"najm-api";class H{async getAll(){return await this.db.select().from(P)}async getById(e){let[t]=await this.db.select().from(P).where(ke(P.id,e));return t}async getByName(e){let[t]=await this.db.select().from(P).where(ke(P.name,e));return t}async create(e){let[t]=await this.db.insert(P).values(e).returning();return t}async update(e,t){let[a]=await this.db.update(P).set(t).where(ke(P.id,e)).returning();return a}async delete(e){let[t]=await this.db.delete(P).where(ke(P.id,e)).returning();return t}}H=n([ws()],H);import{Injectable as xs,t as Te}from"najm-api";import{parseSchema as vs}from"@/shared";import{roleSchema as ks}from"@/lib/validations";class K{roleRepository;constructor(e){this.roleRepository=e}async validateCreateRole(e){return vs(ks,e)}async isRoleNameExists(e){return!!await this.roleRepository.getByName(e)}async isRoleIdExists(e){return!!await this.roleRepository.getById(e)}async checkNameUnique(e,t=null){if(!e)return;let a=await this.roleRepository.getByName(e);if(a&&a.id!==t)throw new Error(Te("roles.errors.exists"))}async checkRoleExists(e){if(!await this.isRoleIdExists(e))throw new Error(Te("roles.errors.notFound"))}async checkRoleExistsByName(e){if(!await this.isRoleNameExists(e))throw new Error(Te("roles.errors.notFound"))}async checkAdminRoleExists(){let e=await this.roleRepository.getByName("admin");if(!e)throw new Error(Te("users.errors.adminRoleNotFound"));return e}}K=n([xs(),r("design:paramtypes",[typeof H==="undefined"?Object:H])],K);import{Injectable as st,Headers as ze,createGuard as rt,GuardParams as Ns,Ctx as et}from"najm-api";import{tokensTable as se,usersTable as g,rolesTable as re,permissionsTable as _e,rolePermissionsTable as $e}from"@/database/schema";import{eq as I}from"drizzle-orm";import{Repository as Ts}from"najm-api";class O{async storeRefreshToken(e){return await this.db.insert(se).values(e).onConflictDoUpdate({target:se.userId,set:{token:e.token,expiresAt:e.expiresAt}}).returning()}async getRefreshToken(e){let[t]=await this.db.select().from(se).where(I(se.userId,e));return t?.token}async revokeToken(e){let[t]=await this.db.delete(se).where(I(se.userId,e)).returning();return t}async isUserExists(e){let[t]=await this.db.select({id:g.id}).from(g).where(I(g.id,e)).limit(1);return!!t}async getRoleNameById(e){let[t]=await this.db.select({roleName:re.name}).from(g).leftJoin(re,I(g.roleId,re.id)).where(I(g.id,e)).limit(1);return t?.roleName}async getUserPermissions(e){let[t]=await this.db.select({roleId:g.roleId}).from(g).where(I(g.id,e)).limit(1);if(!t||!t.roleId)return[];return(await this.db.select({name:_e.name}).from($e).leftJoin(_e,I($e.permissionId,_e.id)).where(I($e.roleId,t.roleId))).map((i)=>i.name).filter((i)=>i)}async getUser(e){let[t]=await this.db.select({id:g.id,email:g.email,status:g.status,roleId:g.roleId,roleName:re.name,createdAt:g.createdAt,updatedAt:g.updatedAt}).from(g).leftJoin(re,I(g.roleId,re.id)).where(I(g.id,e)).limit(1);return t?{...t,role:t.roleName}:null}}O=n([Ts()],O);import{t as ae}from"najm-api";import{getCookie as Ss,Injectable as Es}from"najm-api";import Se from"jsonwebtoken";import{jwtDecode as Us}from"jwt-decode";import Rs from"timestring";class A{tokenRepository;accessSecretKey=process.env.JWT_ACCESS_SECRET;accessExpiresIn=process.env.ACCESS_EXPIRES_IN;refreshSecretKey=process.env.JWT_REFRESH_SECRET;refreshExpiresIn=process.env.REFRESH_EXPIRES_IN;constructor(e){this.tokenRepository=e}extractAccessToken(e){if(e&&e.startsWith("Bearer"))return e.split(" ")[1];throw new Error(ae("auth.errors.tokenMissing"))}verifyAccessToken(e){try{return Se.verify(e,this.accessSecretKey)}catch(t){throw new Error(ae("auth.errors.tokenVerificationFailed"))}}verifyRefreshToken(e){try{return Se.verify(e,this.refreshSecretKey).userId}catch(t){throw new Error(ae("auth.errors.tokenVerificationFailed"))}}async getUserIdByAccessToken(e){let t=this.extractAccessToken(e),i=this.verifyAccessToken(t).userId;if(!await this.tokenRepository.isUserExists(i))throw new Error(ae("users.errors.notFound"));return i}async storeRefreshToken(e,t){let a=Rs(this.refreshExpiresIn,"s"),i={userId:e,token:t,expiresAt:new Date(Date.now()+a*1000).toISOString()};await this.tokenRepository.storeRefreshToken(i)}getTokenExpire(e){return Us(e).exp}generateAccessToken(e){let t={expiresIn:this.accessExpiresIn};return Se.sign(e,this.accessSecretKey,t)}generateRefreshToken(e){let t={expiresIn:this.refreshExpiresIn};return Se.sign(e,this.refreshSecretKey,t)}async generateTokens(e){let t={userId:e},a=await this.generateAccessToken(t),i=await this.generateRefreshToken(t),l=this.getTokenExpire(a),c=this.getTokenExpire(i);return await this.storeRefreshToken(e,i),{accessToken:a,refreshToken:i,accessTokenExpiresAt:l,refreshTokenExpiresAt:c}}async refreshTokens(){let e=Ss("refreshToken"),t=this.verifyRefreshToken(e);if(!await this.tokenRepository.isUserExists(t))throw new Error(ae("users.errors.notFound"));let i=await this.tokenRepository.getRefreshToken(t);if(e!=i)throw new Error(ae("auth.errors.refreshTokenInvalid"));return await this.generateTokens(t)}async revokeToken(e){return await this.tokenRepository.revokeToken(e)}async getUserPermissions(e){if(!e)return;let t=await this.getUserIdByAccessToken(e);return await this.tokenRepository.getUserPermissions(t)}async getUserRole(e){if(!e)return;let t=await this.getUserIdByAccessToken(e);return await this.tokenRepository.getRoleNameById(t)}async getUser(e){if(!e)return;let t=await this.getUserIdByAccessToken(e),a=await this.tokenRepository.getUser(t);if(!a)return null;return a}async storeUserInCache(e,t){let a=t.get("user");if(a)return a;let i=await this.getUser(e);if(i)t.set("user",i);return i}}A=n([Es(),r("design:paramtypes",[typeof O==="undefined"?Object:O])],A);var f={ADMIN:"admin",PRINCIPAL:"principal",ACCOUNTING:"accounting",SECRETARY:"secretary",TEACHER:"teacher",STUDENT:"student",PARENT:"parent"},tt={ADMINISTRATORS:[f.ADMIN,f.PRINCIPAL],FINANCIAL:[f.ADMIN,f.ACCOUNTING],STAFF:[f.ADMIN,f.PRINCIPAL,f.ACCOUNTING,f.SECRETARY,f.TEACHER],END_USERS:[f.STUDENT,f.PARENT],ALL:[f.ADMIN,f.PRINCIPAL,f.ACCOUNTING,f.SECRETARY,f.TEACHER,f.STUDENT,f.PARENT]};class Ee{isInGroup(e,t){return t.includes(e?.toLowerCase())}isAdministrator(e){return this.isInGroup(e,tt.ADMINISTRATORS)}isStaff(e){return this.isInGroup(e,tt.STAFF)}hasAnyRole(e,t){return t.includes(e?.toLowerCase())}hasExactRole(e,t){return e?.toLowerCase()===t?.toLowerCase()}}Ee=n([st()],Ee);class q{roleChecker;tokenService;constructor(e,t){this.roleChecker=e;this.tokenService=t}async isAuth(e,t){return!!await this.tokenService.storeUserInCache(e,t)}async hasRoles(e,t,a){try{let i=await this.tokenService.storeUserInCache(e,t);if(!i?.role)return!1;let l=Array.isArray(a)?a:[a];return this.roleChecker.hasAnyRole(i.role,l)}catch{return!1}}}n([u(0,ze("authorization")),u(1,et()),r("design:type",Function),r("design:paramtypes",[Object,Object]),r("design:returntype",Object)],q.prototype,"isAuth",null),n([u(0,ze("authorization")),u(1,et()),u(2,Ns()),r("design:type",Function),r("design:paramtypes",[Object,Object,Object]),r("design:returntype",Object)],q.prototype,"hasRoles",null),q=n([st(),r("design:paramtypes",[typeof Ee==="undefined"?Object:Ee,typeof A==="undefined"?Object:A])],q);var ie=()=>V("admin"),Ra=()=>V("principal"),Na=()=>V("accounting"),Ka=()=>V("secretary"),Aa=()=>V("teacher"),Ba=()=>V("parent"),Pa=()=>V("student"),Ia=()=>V("admin","principal"),Va=()=>V("admin","accounting"),ba=()=>V("admin","principal","accounting","secretary","teacher"),_a=rt(q,"isAuth"),V=(...e)=>rt(q,"hasRoles")(...e);import{Controller as As,Get as at,Post as Bs,Put as Ps,Delete as Is,Params as Je,Body as it,t as pe}from"najm-api";import{Injectable as Ks}from"najm-api";class B{roleRepository;roleValidator;constructor(e,t){this.roleRepository=e;this.roleValidator=t}async getAll(){return await this.roleRepository.getAll()}async getById(e){return await this.roleValidator.checkRoleExists(e),await this.roleRepository.getById(e)}async getByName(e){return await this.roleRepository.getByName(e)}async create(e){return await this.roleValidator.validateCreateRole(e),await this.roleValidator.checkNameUnique(e.name),await this.roleRepository.create(e)}async update(e,t){return await this.roleValidator.checkRoleExists(e),await this.roleValidator.checkNameUnique(t.name,e),await this.roleRepository.update(e,t)}async delete(e){return await this.roleValidator.checkRoleExists(e),await this.roleRepository.delete(e)}async seedDefaultRoles(e){let t=[];for(let i of e)if(!await this.roleValidator.isRoleNameExists(i.name))t.push(i);return await Promise.all(t.map((i)=>this.roleRepository.create(i)))}async getRoleIdByName(e){return(await this.getByName(e))?.id}}B=n([Ks(),r("design:paramtypes",[typeof H==="undefined"?Object:H,typeof K==="undefined"?Object:K])],B);class le{roleService;constructor(e){this.roleService=e}async getRoles(){return{data:await this.roleService.getAll(),message:pe("roles.success.retrieved"),status:"success"}}async getRole(e){return{data:await this.roleService.getById(e),message:pe("roles.success.retrieved"),status:"success"}}async createRole(e){return{data:await this.roleService.create(e),message:pe("roles.success.created"),status:"success"}}async updateRole(e,t){return{data:await this.roleService.update(e,t),message:pe("roles.success.updated"),status:"success"}}async deleteRole(e){return{data:await this.roleService.delete(e),message:pe("roles.success.deleted"),status:"success"}}}n([at(),ie(),r("design:type",Function),r("design:paramtypes",[]),r("design:returntype",Promise)],le.prototype,"getRoles",null),n([at("/:id"),ie(),u(0,Je("id")),r("design:type",Function),r("design:paramtypes",[Object]),r("design:returntype",Promise)],le.prototype,"getRole",null),n([Bs(),ie(),u(0,it()),r("design:type",Function),r("design:paramtypes",[Object]),r("design:returntype",Promise)],le.prototype,"createRole",null),n([Ps("/:id"),ie(),u(0,Je("id")),u(1,it()),r("design:type",Function),r("design:paramtypes",[Object,Object]),r("design:returntype",Promise)],le.prototype,"updateRole",null),n([Is("/:id"),ie(),u(0,Je("id")),r("design:type",Function),r("design:paramtypes",[Object]),r("design:returntype",Promise)],le.prototype,"deleteRole",null),le=n([As("/roles"),r("design:paramtypes",[typeof B==="undefined"?Object:B])],le);import{nanoid as Js}from"nanoid";import{clean as Ms}from"@/shared";class W{roleValidator;roleService;userRepository;userValidator;encryptionService;constructor(e,t,a,i,l){this.roleValidator=e;this.roleService=t;this.userRepository=a;this.userValidator=i;this.encryptionService=l}sanitizeUser(e){if(!e)return e;let{password:t,...a}=e;return a}sanitizeUsers(e){return e.map((t)=>this.sanitizeUser(t))}async resolveUserRole(e,t){if(e)return await this.roleValidator.checkRoleExists(e),e;if(t){let i=await this.roleService.getByName(t);if(i)return i.id;throw new Error(`Role '${t}' not found`)}return(await this.roleService.getByName("Student")).id}async getAll(){let e=await this.userRepository.getAll();return this.sanitizeUsers(e)}async getById(e){await this.userValidator.checkUserExists(e);let t=await this.userRepository.getById(e);return this.sanitizeUser(t)}async getByEmail(e){let t=await this.userValidator.checkUserExistsByEmail(e);return this.sanitizeUser(t)}async create(e){let{id:t,email:a,image:i,emailVerified:l,password:c,roleId:d,role:E}=e,ue=t||Js(5),ss=c||"12345678";await this.userValidator.checkEmailUnique(e.email),await this.userValidator.checkUserIdIsUnique(t);let rs=await this.encryptionService.hashPassword(ss),as=await this.resolveUserRole(d,E),qe={id:ue,email:a,image:i,password:rs,roleId:as,emailVerified:l,status:"pending"};await this.userValidator.validateCreateUser(qe);let is=await this.userRepository.create(qe);return this.sanitizeUser(is)}async update(e,t){let{password:a,image:i}=t;await this.userValidator.checkUserExists(e),await this.userValidator.checkEmailUnique(t.email,e);let l=await this.userRepository.getById(e),c=await this.encryptionService.hashPassword(a),d={...t,image:i,...c&&{password:c}},E=Ms(d),ue=await this.userRepository.update(e,E);return this.sanitizeUser(ue)}async delete(e){await this.userValidator.checkUserExists(e);let t=await this.userRepository.delete(e);return this.sanitizeUser(t)}async deleteAll(){let e=await this.userRepository.deleteAll();return this.sanitizeUsers(e)}async getRoleName(e){return await this.userValidator.checkUserExists(e),await this.userRepository.getRoleNameById(e)}async getPassword(e){return await this.userValidator.checkUserExistsByEmail(e),await this.userRepository.getUserPassword(e)}async assignRole(e,t,a){await this.userValidator.checkUserExists(e);let i=await this.resolveUserRole(t,a),l=await this.userRepository.update(e,{roleId:i});return this.sanitizeUser(l)}async removeRole(e){await this.userValidator.checkUserExists(e);let t=await this.userRepository.update(e,{roleId:null});return this.sanitizeUser(t)}async seedAdminUser(){let t=await this.roleValidator.checkAdminRoleExists(),a=await this.userRepository.getByEmail("admin@admin.com");if(a)await this.delete(a.id);let i=await this.create({id:"USR00",name:"System Administrator",email:"admin@admin.com",password:"12345678",image:null,roleId:t.id,status:"active",emailVerified:!0});return this.sanitizeUser(i)}async updateLang(e){return bs(e),e}async getLang(){return _s()}}n([$s(),r("design:type",Function),r("design:paramtypes",[Object]),r("design:returntype",Promise)],W.prototype,"create",null),W=n([Vs(),r("design:paramtypes",[typeof K==="undefined"?Object:K,typeof B==="undefined"?Object:B,typeof M==="undefined"?Object:M,typeof C==="undefined"?Object:C,typeof J==="undefined"?Object:J])],W);import{Controller as Cs,Get as me,Post as Me,Put as Hs,Delete as Ce,Params as X,Body as nt,t as R}from"najm-api";import{isAdmin as b,isAuth as ot}from"@/roles/RoleGuards";class ye{userService;constructor(e){this.userService=e}async getUsers(){return{data:await this.userService.getAll(),message:R("users.success.retrieved"),status:"success"}}async getLang(){return{data:{language:await this.userService.getLang()},message:R("users.success.retrieved"),status:"success"}}async updateLang(e){return{data:await this.userService.updateLang(e),message:R("users.success.updated"),status:"success"}}async getUser(e){return{data:await this.userService.getById(e),message:R("users.success.retrieved"),status:"success"}}async getByEmail(e){return{data:await this.userService.getByEmail(e),message:R("users.success.retrieved"),status:"success"}}async getRole(e){return{data:await this.userService.getRoleName(e),message:R("users.success.retrieved"),status:"success"}}async create(e){return{data:await this.userService.create(e),message:R("users.success.created"),status:"success"}}async update(e,t){return{data:await this.userService.update(e,t),message:R("users.success.updated"),status:"success"}}async delete(e){return{data:await this.userService.delete(e),message:R("users.success.deleted"),status:"success"}}async deleteAll(){return{data:await this.userService.deleteAll(),message:R("users.success.allDeleted"),status:"success"}}async assignRole(e,t){return await this.userService.assignRole(e,t),{message:R("users.success.updated"),status:"success"}}async removeRole(e){return await this.userService.removeRole(e),{message:R("users.success.updated"),status:"success"}}}n([me(),b(),r("design:type",Function),r("design:paramtypes",[]),r("design:returntype",Promise)],ye.prototype,"getUsers",null),n([me("/lang"),ot(),r("design:type",Function),r("design:paramtypes",[]),r("design:returntype",Promise)],ye.prototype,"getLang",null),n([Me("/lang/:language"),ot(),u(0,X("language")),r("design:type",Function),r("design:paramtypes",[Object]),r("design:returntype",Promise)],ye.prototype,"updateLang",null),n([me("/:id"),b(),u(0,X("id")),r("design:type",Function),r("design:paramtypes",[Object]),r("design:returntype",Promise)],ye.prototype,"getUser",null),n([me("/email/:email"),b(),u(0,X("email")),r("design:type",Function),r("design:paramtypes",[Object]),r("design:returntype",Promise)],ye.prototype,"getByEmail",null),n([me("/role/:userId"),b(),u(0,X("userId")),r("design:type",Function),r("design:paramtypes",[Object]),r("design:returntype",Promise)],ye.prototype,"getRole",null),n([Me(),b(),u(0,nt()),r("design:type",Function),r("design:paramtypes",[Object]),r("design:returntype",Promise)],ye.prototype,"create",null),n([Hs("/:id"),b(),u(0,X("id")),u(1,nt()),r("design:type",Function),r("design:paramtypes",[Object,Object]),r("design:returntype",Promise)],ye.prototype,"update",null),n([Ce("/:id"),b(),u(0,X("id")),r("design:type",Function),r("design:paramtypes",[Object]),r("design:returntype",Promise)],ye.prototype,"delete",null),n([Ce(),b(),r("design:type",Function),r("design:paramtypes",[]),r("design:returntype",Promise)],ye.prototype,"deleteAll",null),n([Me("/assign/:userId/:roleId"),b(),u(0,X("userId")),u(1,X("roleId")),r("design:type",Function),r("design:paramtypes",[Object,Object]),r("design:returntype",Promise)],ye.prototype,"assignRole",null),n([Ce("/remove/:userId"),b(),u(0,X("userId")),r("design:type",Function),r("design:paramtypes",[Object]),r("design:returntype",Promise)],ye.prototype,"removeRole",null),ye=n([Cs("/users"),r("design:paramtypes",[typeof W==="undefined"?Object:W])],ye);class F{tokenService;userService;userValidator;cookieService;constructor(e,t,a,i){this.tokenService=e;this.userService=t;this.userValidator=a;this.cookieService=i}async registerUser(e){return await this.userService.create(e)}async loginUser(e){let{email:t,password:a}=e;if(!t||!a)throw new Error(ct("auth.errors.invalidCredentials"));let i=await this.userService.getPassword(t),{id:l}=await this.userService.getByEmail(t);await this.userValidator.checkPasswordValid(a,i);let c=await this.tokenService.generateTokens(l);return this.cookieService.setRefreshCookie(c.refreshToken),c}async refreshTokens(){let e=await this.tokenService.refreshTokens();return this.cookieService.setRefreshCookie(e.refreshToken),e}async logoutUser(e){return await this.userValidator.checkUserExists(e),await this.tokenService.revokeToken(e),this.cookieService.clearRefreshCookie(),{data:null,message:ct("auth.success.logout")}}async getUserProfile(e){let t=Xs();return{...e,language:t}}async forgotPassword(e){}}F=n([Ws(),r("design:paramtypes",[typeof A==="undefined"?Object:A,typeof W==="undefined"?Object:W,typeof C==="undefined"?Object:C,typeof G==="undefined"?Object:G])],F);import{isAuth as ut}from"@/roles/RoleGuards";class de{authService;constructor(e){this.authService=e}async registerUser(e){return{data:await this.authService.registerUser(e),message:ne("auth.success.register"),status:"success"}}async loginUser(e){return{data:await this.authService.loginUser(e),message:ne("auth.success.login"),status:"success"}}async refreshTokens(){return{data:await this.authService.refreshTokens(),message:ne("auth.success.tokenRefreshed"),status:"success"}}async logoutUser(e){return{data:await this.authService.logoutUser(e),message:ne("auth.success.logout"),status:"success"}}async userProfile(e){return{data:await this.authService.getUserProfile(e),message:ne("users.success.retrieved"),status:"success"}}async forgotPassword(e){return{data:await this.authService.forgotPassword(e.email),message:ne("auth.success.passwordReset"),status:"success"}}}n([We("/register"),u(0,Xe()),r("design:type",Function),r("design:paramtypes",[Object]),r("design:returntype",Promise)],de.prototype,"registerUser",null),n([We("/login"),u(0,Xe()),r("design:type",Function),r("design:paramtypes",[Object]),r("design:returntype",Promise)],de.prototype,"loginUser",null),n([He("/refresh"),r("design:type",Function),r("design:paramtypes",[]),r("design:returntype",Promise)],de.prototype,"refreshTokens",null),n([He("/logout/:id"),u(0,Qs("id")),r("design:type",Function),r("design:paramtypes",[Object]),r("design:returntype",Promise)],de.prototype,"logoutUser",null),n([He("/me"),ut(),u(0,Zs()),r("design:type",Function),r("design:paramtypes",[Object]),r("design:returntype",Promise)],de.prototype,"userProfile",null),n([We("/forgot-password"),ut(),u(0,Xe()),r("design:type",Function),r("design:paramtypes",[Object]),r("design:returntype",Promise)],de.prototype,"forgotPassword",null),de=n([Ds("/auth"),r("design:paramtypes",[typeof F==="undefined"?Object:F])],de);var Ue={userType:{values:["admin","teacher","student","parent"],translationKey:"enums.userType"},userStatus:{values:["active","inactive","pending"],translationKey:"enums.userStatus"},tokenStatus:{values:["active","revoked","expired"],translationKey:"enums.tokenStatus"},tokenType:{values:["access","refresh"],translationKey:"enums.tokenType"},fileStatus:{values:["active","deleted","archived"],translationKey:"enums.fileStatus"},gender:{values:["M","F"],translationKey:"common.gender"},studentStatus:{values:["active","inactive","graduated","transferred"],translationKey:"students.status"},teacherStatus:{values:["active","inactive","onLeave"],translationKey:"teachers.status"},employmentType:{values:["fullTime","partTime","contract","temporary"],translationKey:"teachers.employmentType"},relationshipType:{values:["father","mother","guardian","stepparent","grandparent","other"],translationKey:"parents.relationships"},semester:{values:["spring","summer","fall","winter"],translationKey:"academic.semester"},classStatus:{values:["active","completed","cancelled"],translationKey:"classes.status"},sectionStatus:{values:["active","inactive","archived"],translationKey:"sections.status"},language:{values:["en","fr","ar","es"],translationKey:"common.languages"},enrollmentStatus:{values:["enrolled","completed","dropped","failed"],translationKey:"enrollments.status"},assignmentStatus:{values:["active","completed","cancelled"],translationKey:"assignments.status"},calendarSystem:{values:["SEMESTER","TRIMESTER","QUARTER"],translationKey:"settings.calendarSystem"},assessmentType:{values:["quiz","assignment","project","participation","test","presentation"],translationKey:"assessments.type"},assessmentStatus:{values:["scheduled","active","completed","cancelled"],translationKey:"assessments.status"},submissionType:{values:["online","paper","presentation","practical","discussion"],translationKey:"assessments.submissionType"},examType:{values:["midterm","final","standardized"],translationKey:"exams.type"},examSecurity:{values:["low","medium","high"],translationKey:"exams.security"},examStatus:{values:["scheduled","active","completed","cancelled","rescheduled"],translationKey:"exams.status"},gradeStatus:{values:["graded","pending","draft","reviewed"],translationKey:"grades.status"},attendanceStatus:{values:["present","absent","late","excused"],translationKey:"attendance.status"},proficiencyLevel:{values:["beginner","intermediate","advanced","expert"],translationKey:"common.proficiencyLevel"},dayOfWeek:{values:["monday","tuesday","wednesday","thursday","friday","saturday","sunday"],translationKey:"common.days"},alertType:{values:["academic","attendance","behavioral","health","system","announcement","reminder","emergency"],translationKey:"alerts.type"},alertPriority:{values:["low","medium","high","critical"],translationKey:"alerts.priority"},alertStatus:{values:["active","acknowledged","resolved","dismissed"],translationKey:"alerts.status"},feeTypeStatus:{values:["active","inactive","archived"],translationKey:"fees.typeStatus"},feeCategory:{values:["tuition","registration","transport","cafeteria","books","sports","uniform","technology","fieldtrip","other"],translationKey:"feeTypes.category"},paymentType:{values:["recurring","oneTime"],translationKey:"payments.type"},schedule:{values:["monthly","quarterly","semester","annually","oneTime"],translationKey:"fees.schedule"},feeStatus:{values:["pending","partiallyPaid","paid","overdue"],translationKey:"fees.status"},feeInstallmentStatus:{values:["pending","partiallyPaid","paid","overdue"],translationKey:"fees.installmentStatus"},paymentMethod:{values:["cash","bankTransfer","check","creditCard","debitCard","online","mobilePayment"],translationKey:"payments.methods"},paymentStatus:{values:["completed","pending","failed","refunded"],translationKey:"payments.status"},eventType:{values:["academic","sports","cultural","holiday","exam","meeting","workshop","fieldtrip","ceremony","conference","other"],translationKey:"events.type"},eventStatus:{values:["scheduled","ongoing","completed","cancelled","postponed"],translationKey:"events.status"},eventVisibility:{values:["public","private","teachers","students","parents","staff"],translationKey:"events.visibility"},participantType:{values:["student","teacher","parent","staff"],translationKey:"events.participantType"},expenseCategory:{values:["salary","utilities","maintenance","supplies","equipment","transport","food","security","cleaning","insurance","rent","tax","marketing","training","technology","miscellaneous"],translationKey:"expenses.categories"},expenseStatus:{values:["pending","approved","paid","rejected","cancelled"],translationKey:"expenses.status"},trackerMode:{values:["tracking","gprs","sms","sleepTime","sleepShock","sleepDeep"],translationKey:"tracker.mode"},driverStatus:{values:["active","inactive","onLeave","suspended"],translationKey:"transport.driverStatus"},vehicleStatus:{values:["active","inactive","maintenance","retired"],translationKey:"transport.vehicleStatus"},vehicleType:{values:["sedan","minibus","fullbus","shuttle"],translationKey:"transport.vehicleType"},vehicleDocumentType:{values:["insurance","registration","inspection","emission","license"],translationKey:"transport.documentType"},busStatus:{values:["active","inactive","maintenance","retired"],translationKey:"transport.busStatus"},refuelStatus:{values:["pending","completed","cancelled"],translationKey:"transport.refuelStatus"},fuelType:{values:["gasoline","diesel","electric","hybrid","lpg","cng"],translationKey:"transport.fuelType"},maintenanceType:{values:["scheduled","repair","inspection","oilChange","filterChange","other"],translationKey:"transport.maintenanceType"},maintenanceStatus:{values:["scheduled","inProgress","completed","cancelled","overdue"],translationKey:"transport.maintenanceStatus"},maritalStatus:{values:["single","married","divorced","widowed","separated"],translationKey:"parents.maritalStatus"}},Ji=(e)=>Ue[e],Mi=(e)=>Ue[e]?.values||[];import{z as s}from"zod";import{z as js}from"zod";var o=(e)=>{let t=Ue[e]?.values;if(!t)throw new Error(`Enum ${e} not found`);return js.enum(t)},Xi=o("userType"),pt=o("userStatus"),Di=o("tokenStatus"),Qi=o("tokenType"),Zi=o("fileStatus"),he=o("gender"),lt=o("studentStatus"),mt=o("teacherStatus"),yt=o("employmentType"),dt=o("relationshipType"),ji=o("semester"),Li=o("classStatus"),ht=o("sectionStatus"),gt=o("language"),Yi=o("enrollmentStatus"),Gi=o("assignmentStatus"),ft=o("calendarSystem"),wt=o("assessmentType"),xt=o("assessmentStatus"),Oi=o("submissionType"),vt=o("examType"),qi=o("examSecurity"),kt=o("examStatus"),Tt=o("gradeStatus"),De=o("attendanceStatus"),Fi=o("proficiencyLevel"),zi=o("dayOfWeek"),St=o("alertType"),Et=o("alertPriority"),Ut=o("alertStatus"),Rt=o("feeTypeStatus"),Nt=o("paymentType"),Kt=o("schedule"),At=o("feeStatus"),Bt=o("feeInstallmentStatus"),ge=o("paymentMethod"),Pt=o("paymentStatus"),It=o("eventType"),Vt=o("eventStatus"),bt=o("eventVisibility"),_t=o("participantType"),$t=o("expenseCategory"),Jt=o("expenseStatus"),en=o("trackerMode"),Mt=o("driverStatus"),Ct=o("vehicleStatus"),Ht=o("vehicleType"),tn=o("vehicleDocumentType"),sn=o("busStatus"),Wt=o("refuelStatus"),Xt=o("fuelType"),rn=o("maintenanceType"),an=o("maintenanceStatus"),nn=o("maritalStatus");var h=s.preprocess((e)=>e??"",s.string().min(1,"ID is required")),m=s.string().min(1,"ID cannot be empty").nullish().optional(),oe=s.string().email("Invalid email format").or(s.literal("")),z=s.string().regex(/^[\+]?[1-9][\d]{0,15}$/,"Invalid phone number"),D=s.string().min(2,"Name must be at least 2 characters").max(100,"Name too long"),x=s.string().regex(/^(\d{4}-\d{2}-\d{2}|\d{2}\/\d{2}\/\d{4}|\d{2}-\d{2}-\d{2}|\d{2}-\d{2}-\d{4})$/,"Date must be in YYYY-MM-DD, MM/DD/YYYY, DD/MM/YYYY, DD-MM-YY, or DD-MM-YYYY format"),Q=s.string().regex(/^\d{4}-\d{2}-\d{2}$/,"Date must be in YYYY-MM-DD format").nullable().optional(),Re=s.string().regex(/^([01]?[0-9]|2[0-3]):[0-5][0-9]$/,"Time must be in HH:MM format").optional().nullable(),Qe=s.string().min(8,"CIN must be at least 8 characters").max(20,"CIN too long"),Ne=s.string().max(500,"Address too long").optional(),Ze=s.string().min(9,"Academic year is required").regex(/^\d{4}-\d{4}$/,"Academic year must be in YYYY-YYYY format"),p=()=>{let e=(i)=>{return Object.assign(i,{positive:(c="Must be positive")=>e(i.refine((d)=>d>0,{message:c})),min:(c,d)=>e(i.refine((E)=>E>=c,{message:d||`Must be at least ${c}`})),max:(c,d)=>e(i.refine((E)=>E<=c,{message:d||`Cannot exceed ${c}`})),int:(c="Must be an integer")=>e(i.refine((d)=>Number.isInteger(d),{message:c}))})},t=(i)=>{if(i===null||i===void 0||Number.isNaN(i))return!1;if(typeof i==="number")return!0;if(typeof i==="string"){let l=i.trim();return l!==""&&!isNaN(Number(l))}return!1},a=s.any().refine(t,{message:"Must be a valid number"}).transform((i)=>typeof i==="string"?Number(i):i);return e(a)},pn=s.object({id:m,username:D.max(50).optional(),email:oe,password:s.string().min(8,"Password must be at least 8 characters"),roleId:m,roleName:D.max(50).optional(),lastLogin:Q,image:s.union([s.string(),s.instanceof(File),s.undefined()]).optional(),emailVerified:s.boolean().default(!1),status:pt,createdAt:Q}),ln=s.object({id:m,name:D.max(50),description:s.string().max(255,"Description too long").optional(),createdAt:Q}),Ls=s.object({id:m,classId:h,sectionId:h,studentCode:s.string(),name:D,email:oe,phone:z.nullish(),address:Ne,dateOfBirth:Q,gender:he,enrollmentDate:x,medicalConditions:s.string().max(1000,"Medical conditions description too long").nullish().optional(),previousSchool:s.string().max(500,"Previous school name too long").optional().nullable(),image:s.union([s.string(),s.instanceof(File),s.null()]).optional(),status:lt.default("active")}),Ys=s.object({id:m,name:D,email:oe.optional(),phone:z,gender:he.optional(),address:Ne,dateOfBirth:Q,cin:Qe,occupation:s.string().max(100,"Occupation too long").optional(),nationality:s.string().max(100,"Nationality too long").optional(),maritalStatus:s.string().max(50,"Marital status too long").optional(),relationshipType:dt,image:s.union([s.string(),s.instanceof(File),s.null()]).optional(),isEmergencyContact:s.boolean().optional().default(!1),financialResponsibility:s.boolean().optional().default(!1)}),mn=s.object({id:m,name:D,email:oe,cin:Qe,phone:z,address:Ne,gender:he.optional(),licenseNumber:s.string().min(5,"License number must be at least 5 characters").max(20,"License number too long"),licenseType:s.string().max(10,"License type too long"),licenseExpiry:x,hireDate:x,salary:p().positive("Salary must be positive").optional(),yearsOfExperience:p().int().min(0,"Years of experience must be non-negative").optional(),emergencyContact:D.optional(),emergencyPhone:z.optional(),image:s.union([s.string(),s.instanceof(File),s.null()]).optional(),status:Mt.default("active"),notes:s.string().max(1000,"Notes too long").optional().nullable()}),Gs=s.object({id:m,name:D,cin:Qe,email:oe,phone:z,address:Ne,gender:he.optional(),emergencyContact:D.optional(),emergencyPhone:z,status:mt.default("active"),image:s.union([s.string(),s.instanceof(File),s.null()]).optional()}),Os=s.object({specialization:s.string().max(100,"Specialization too long").optional(),yearsOfExperience:p().int().min(0,"Years of experience must be non-negative").optional(),salary:p().positive("Salary must be positive").optional(),hireDate:x,bankAccount:s.coerce.string().max(100,{message:"Bank account too long"}).optional(),employmentType:yt.optional(),workloadHours:p().int().min(0,"Workload hours must be non-negative").max(60,"Workload hours cannot exceed 60").optional(),academicDegrees:s.string().max(500,"Academic degrees description too long").optional()}),qs=s.object({classId:s.string().min(1,"Class is required"),sectionIds:s.array(s.string()).min(1,"At least one section is required"),subjectIds:s.array(s.string()).min(1,"At least one subject is required"),academicYear:s.string().optional()}),Fs=s.object({assignments:s.array(qs).min(1,"At least one parent is required")}),yn=s.object({...Gs.shape,...Os.shape,...Fs.shape}),dn=s.object({id:m,name:s.string().min(2,"Fee type name must be at least 2 characters").max(100,"Fee type name too long"),description:s.string().max(500,"Description too long").optional().nullable(),category:s.string(),amount:p().positive("Amount must be greater than 0").max(1e5,"Amount too large"),paymentType:Nt.default("recurring"),status:Rt.default("active").optional()}),zs=s.object({id:m,studentId:h,feeTypeId:h,academicYear:Ze.optional(),status:At.optional(),schedule:Kt,baseAmount:p().positive("Base amount must be positive").optional(),grossAmount:p().positive("Gross amount must be positive").optional(),netAmount:p().optional(),paidAmount:p().min(0,"Paid amount cannot be negative").optional(),discountAmount:p().min(0,"Discount cannot be negative").optional(),discountReason:s.string().max(500,"Discount reason too long").optional().nullable(),assignedBy:m.nullable(),notes:s.string().max(1000,"Notes too long").optional().nullable()}),Dt=zs.omit({studentId:!0}),hn=s.object({studentId:h,fees:s.array(Dt).min(1,"At least one fee is required")}),gn=s.object({feeId:m,number:p().int().min(1,"Installment must be at least 1"),dueDate:x,amount:p().positive("Amount must be greater than 0").max(1e5,"Amount too large"),paidAmount:p().min(0,"Paid amount cannot be negative").max(1e5,"Amount too large").optional(),status:Bt.optional()}),fn=s.object({studentId:m,amount:p().positive("Amount must be greater than 0").max(1e5,"Amount too large").optional(),paymentMethod:ge,paymentDate:x,checkNumber:s.preprocess((e)=>e===""?null:e,s.string().max(50,"Check number too long").optional().nullable()),checkDueDate:s.preprocess((e)=>e===""?null:e,Q.nullable()),transactionRef:s.preprocess((e)=>e===""?null:e,s.string().max(100,"Transaction reference too long").optional().nullable()),receiptNumber:s.preprocess((e)=>e===""?null:e,s.string().max(50,"Receipt number too long").optional().nullable()),status:Pt.default("completed"),processedBy:m,notes:s.preprocess((e)=>e===""?null:e,s.string().max(1000,"Notes too long").optional().nullable()),allocations:s.array(s.object({feeId:m,number:s.number().int().positive("Installment must be a positive number"),amount:p().positive("Amount must be greater than 0")})).optional().nullable()}),wn=s.object({paymentId:s.string().min(1,"Payment ID is required"),feeId:s.string().min(1,"Fee ID is required"),installmentId:s.string().optional(),amount:s.number().positive("Amount must be positive"),type:s.enum(["fee","installment"]).default("installment"),notes:s.string().optional()}),er=s.object({parents:s.array(Ys).optional().default([])}),tr=s.object({fees:s.array(Dt).min(1,"At least one fee is required")}),xn=s.object({...Ls.shape,...er.shape,...tr.shape}),vn=s.object({id:m,code:s.string().min(2,"Subject code must be at least 2 characters").max(10,"Subject code too long"),name:s.string().min(2,"Subject name must be at least 2 characters").max(100,"Subject name too long"),description:s.string().max(500,"Description too long").optional(),gradeLevel:p().int().min(1).max(12).optional()}),kn=s.object({id:m,classId:h,name:s.string().min(1,"Section name is required").max(10,"Section name too long"),maxStudents:p().int().min(1,"Max students must be at least 1").max(100,"Max students cannot exceed 100").default(30),roomNumber:p().max(1e4,"Room number too long").optional(),status:ht.default("active")}),Tn=s.object({id:m,name:s.string().min(1,"Class name is required").max(50,"Class name too long"),description:s.string().max(500,"Description too long").optional(),academicYear:Ze,level:s.string().min(1,"Class level is required")}),Sn=s.object({studentId:h,teacherId:h,subjectId:h,sectionId:h,date:x,status:De.default("present"),notes:s.string().max(500,"Notes too long").optional()}),sr=s.object({classId:h,sectionId:h,subjectId:h,teacherId:h,teacherAssignmentId:m,title:s.string().min(3,"Title must be at least 3 characters").max(200,"Title too long"),description:s.string().max(1000,"Description too long").optional().nullable(),type:wt.default("quiz"),date:x,duration:p().int().min(1,"Duration must be at least 1 minute").max(480,"Duration cannot exceed 8 hours"),totalMarks:p().positive("Total marks must be greater than 0").max(1000,"Total marks cannot exceed 1000"),passingMarks:p().min(0,"Passing marks must be non-negative").max(1000,"Passing marks cannot exceed 1000"),instructions:s.string().max(2000,"Instructions too long").optional().nullable(),status:xt.default("scheduled"),assessmentId:m}),En=s.object({assessments:s.array(sr).min(1,"At least one assessment is required").max(50,"Cannot create more than 50 assessments at once")}),Un=s.object({assessmentId:h,teacherId:h,subjectId:h,sectionId:h,studentId:h,gradeId:h,assessmentTitle:s.string().min(3,"Assessment title must be at least 3 characters").max(200,"Assessment title too long").optional(),marksObtained:p().min(0,"Marks obtained must be non-negative").max(1000,"Marks obtained cannot exceed 1000"),feedback:s.string().max(1000,"Feedback too long").optional().nullable(),status:Tt.default("graded")}),Rn=s.object({classId:m,sectionId:h,subjectId:h,teacherId:h,examId:h,teacherAssignmentId:h,title:s.string().min(3,"Title must be at least 3 characters").max(200,"Title too long"),description:s.string().max(1000,"Description too long").optional().nullable(),type:vt.default("midterm"),date:x,startTime:Re,endTime:Re,duration:p().int().min(30,"Exam duration must be at least 30 minutes").max(480,"Duration cannot exceed 8 hours"),totalMarks:p().positive("Total marks must be greater than 0").max(1000,"Total marks cannot exceed 1000"),passingMarks:p().min(0,"Passing marks must be non-negative").max(1000,"Passing marks cannot exceed 1000"),roomNumber:p().max(50,"Room number too long").optional().nullable(),allowedMaterials:s.string().max(500,"Allowed materials description too long").optional().nullable(),instructions:s.string().max(2000,"Instructions too long").optional().nullable(),status:kt.default("scheduled")}),Nn=s.object({title:s.string().min(3,"Title must be at least 3 characters").max(200,"Title too long"),content:s.string().min(10,"Content must be at least 10 characters").max(5000,"Content too long"),authorId:m,targetAudience:s.enum(["all","students","teachers","parents","class"]),classId:m,isPublished:s.boolean().default(!1),publishDate:s.string().datetime("Invalid publish date").optional(),expiryDate:s.string().datetime("Invalid expiry date").optional()}),Kn=s.object({type:St,title:s.string().min(3,"Title must be at least 3 characters").max(200,"Title too long"),message:s.string().min(10,"Message must be at least 10 characters").max(2000,"Message too long"),priority:Et.default("medium"),status:Ut.default("active"),studentId:m,teacherId:m,classId:m,subjectId:m,targetAudience:s.enum(["all","students","teachers","parents"]).optional(),authorId:m,isRead:s.boolean().default(!1)}),An=s.object({title:s.string().min(3,"Title must be at least 3 characters").max(200,"Title too long"),description:s.string().max(5000,"Description too long").optional().nullable(),type:It,startDate:x,endDate:x,startTime:Re,endTime:Re,location:s.string().max(200,"Location too long").optional().nullable(),venue:s.string().max(200,"Venue too long").optional().nullable(),organizerId:m,classId:m.nullable(),sectionId:m.nullable(),visibility:bt.default("public"),status:Vt.default("scheduled"),capacity:p().int().positive("Capacity must be positive").optional().nullable(),registrationRequired:s.boolean().default(!1),registrationDeadline:Q.nullable(),attachments:s.any().optional().nullable(),notes:s.string().max(2000,"Notes too long").optional().nullable()}),Bn=s.object({eventId:m,participantId:m,participantType:_t,attendanceStatus:De.optional().nullable(),notes:s.string().max(500,"Notes too long").optional().nullable()}),Pn=s.object({id:m,category:$t,title:s.string().min(3,"Title must be at least 3 characters").max(200,"Title too long"),amount:p().positive("Amount must be greater than 0").max(1e7,"Amount too large"),expenseDate:x,paymentMethod:ge.optional().nullable(),paymentDate:Q.nullable(),vendor:s.string().max(200,"Vendor name too long").optional().nullable(),invoiceNumber:s.string().max(100,"Invoice number too long").optional().nullable(),receiptNumber:s.string().max(100,"Receipt number too long").optional().nullable(),checkNumber:s.string().max(50,"Check number too long").optional().nullable(),transactionRef:s.string().max(100,"Transaction reference too long").optional().nullable(),status:Jt.default("pending"),notes:s.string().max(1000,"Notes too long").optional().nullable()}),In=s.object({action:s.enum(["approve","reject"]),rejectionReason:s.string().min(10,"Rejection reason must be at least 10 characters").max(1000,"Rejection reason too long").optional().nullable()}),Vn=s.object({paymentMethod:ge,paymentDate:x,checkNumber:s.string().max(50,"Check number too long").optional().nullable(),transactionRef:s.string().max(100,"Transaction reference too long").optional().nullable(),notes:s.string().max(1000,"Notes too long").optional().nullable()}),bn=s.object({id:m,name:s.string().min(2,"Vehicle name must be at least 2 characters").max(100,"Vehicle name too long"),brand:s.string().min(2,"Brand must be at least 2 characters").max(100,"Brand too long"),model:s.string().min(2,"Model must be at least 2 characters").max(100,"Model too long"),year:p().int().min(1900,"Year must be after 1900").max(new Date().getFullYear()+1,"Year cannot be in future"),type:Ht.default("fullbus"),capacity:p().int().min(1,"Capacity must be at least 1").max(200,"Capacity cannot exceed 200"),licensePlate:s.string().min(2,"License plate must be at least 2 characters").max(50,"License plate too long"),driverId:m.nullable(),image:s.string().max(500,"Image path too long").optional().nullable().default("novehicle.png"),purchaseDate:Q.nullable(),purchasePrice:p().min(0,"Purchase price must be non-negative").max(1e7,"Purchase price too large").optional().nullable(),initialMileage:p().min(0,"Initial mileage must be non-negative").max(1e7,"Initial mileage too large").optional().nullable(),currentMileage:p().min(0,"Current mileage must be non-negative").max(1e7,"Current mileage too large").optional().nullable(),status:Ct.default("active"),notes:s.string().max(1000,"Notes too long").optional().nullable()}),_n=s.object({id:m,busId:m,refuelDate:x,quantity:p().positive("Quantity must be greater than 0").max(1e4,"Quantity too large"),unitPrice:p().positive("Unit price must be greater than 0").max(1e5,"Unit price too large"),totalCost:p().positive("Total cost must be greater than 0").max(1e7,"Total cost too large").optional(),fuelType:Xt.default("diesel"),odometer:p().min(0,"Odometer must be non-negative").max(1e7,"Odometer value too large").optional().nullable(),fuelStation:s.string().max(200,"Fuel station name too long").optional().nullable(),invoiceNumber:s.string().max(100,"Invoice number too long").optional().nullable(),paymentMethod:ge.optional().nullable(),paidBy:m.nullable(),status:Wt.default("completed"),notes:s.string().max(1000,"Notes too long").optional().nullable()}),$n=s.object({schoolName:s.string().min(2,"School name must be at least 2 characters").max(200,"School name too long"),schoolAddress:s.string().max(500,"School address too long").optional(),schoolPhone:z,schoolEmail:oe,schoolWebsite:s.string().url("Must be a valid URL").max(255,"School website URL too long").optional(),schoolLogo:s.string().url("Must be a valid image URL").max(255,"School logo URL too long").optional(),currentAcademicYear:Ze,gradingScale:s.any().optional(),attendanceRequirement:p().min(0,"Attendance requirement must be non-negative").max(100,"Attendance requirement cannot exceed 100").default(75),maxClassSize:p().int("Max class size must be an integer").min(1,"Max class size must be at least 1").max(200,"Max class size cannot exceed 200").default(34),minimumPassingGrade:p().min(0,"Minimum passing grade must be non-negative").max(100,"Minimum passing grade cannot exceed 100").default(60),defaultExamDuration:p().int("Default exam duration must be in minutes").min(15,"Exam duration must be at least 15 minutes").max(480,"Exam duration cannot exceed 480 minutes").default(120),calendarSystem:ft.default("SEMESTER"),startMonth:s.string().default("september"),endMonth:s.string().default("june"),academicAlerts:s.boolean().default(!0),attendanceAlerts:s.boolean().default(!0),eventAlerts:s.boolean().default(!0),homeworkAlerts:s.boolean().default(!0),feesReminder:s.boolean().default(!0),feesOverdueAlerts:s.boolean().default(!0),emailNotifications:s.boolean().default(!0),smsNotifications:s.boolean().default(!1),parentNotifications:s.boolean().default(!0),lowGradeAlerts:s.boolean().default(!0),allowLateSubmission:s.boolean().default(!0),examResultsAlerts:s.boolean().default(!0),disciplinaryAlerts:s.boolean().default(!0),achievementAlerts:s.boolean().default(!0),maintenanceNotifications:s.boolean().default(!0),twoFactorEnabled:s.boolean().default(!1),sessionTimeout:s.string().regex(/^\d{1,4}$/,"Session timeout must be a number between 1-9999 minutes").default("60"),passwordRequireSymbols:s.boolean().default(!0),loginNotifications:s.boolean().default(!0),parentAccessEnabled:s.boolean().default(!0),teacherAccessEnabled:s.boolean().default(!0),studentAccessEnabled:s.boolean().default(!0),timeZone:s.string().min(1,"Time zone is required").default("UTC"),language:gt.default("en"),theme:s.enum(["light","dark","system"]).default("system"),dateFormat:s.enum(["YYYY-MM-DD","MM/DD/YYYY","DD/MM/YYYY","DD-MM-YY","DD-MM-YYYY"]).default("MM/DD/YYYY"),timeFormat:s.enum(["12","24"]).default("12"),currency:s.string().length(3,"Currency must be a 3-letter ISO code").regex(/^[A-Z]{3}$/,"Currency must be uppercase ISO code").default("USD"),gradingPeriods:p().int("Grading periods must be an integer").min(1,"Grading periods must be at least 1").max(12,"Grading periods cannot exceed 12").default(4),schoolStartTime:s.string().regex(/^([01]?[0-9]|2[0-3]):[0-5][0-9]$/,"Invalid start time format (HH:MM)").default("08:00"),schoolEndTime:s.string().regex(/^([01]?[0-9]|2[0-3]):[0-5][0-9]$/,"Invalid end time format (HH:MM)").default("15:00"),lunchBreakDuration:p().int("Lunch break duration must be in minutes").min(15,"Lunch break must be at least 15 minutes").max(120,"Lunch break cannot exceed 120 minutes").default(30),maintenanceMode:s.boolean().default(!1),autoBackup:s.boolean().default(!0)}),Jn=s.object({id:m}),Mn=s.object({page:p().int().min(1).default(1),limit:p().int().min(1).max(100).default(10)}),Cn=s.object({dateFrom:x,dateTo:x});import{permissionsTable as w,rolePermissionsTable as S,rolesTable as fe}from"@/database/schema";import{eq as N,and as Qt}from"drizzle-orm";import{Repository as rr}from"najm-api";class _{async getAll(){return await this.db.select().from(w)}async getById(e){let[t]=await this.db.select().from(w).where(N(w.id,e));return t}async getByName(e){let[t]=await this.db.select().from(w).where(N(w.name,e));return t}async create(e){let[t]=await this.db.insert(w).values(e).returning();return t}async update(e,t){let[a]=await this.db.update(w).set(t).where(N(w.id,e)).returning();return a}async delete(e){let[t]=await this.db.delete(w).where(N(w.id,e)).returning();return t}async getPermissionsByRole(e){return await this.db.select({id:w.id,name:w.name,description:w.description,resource:w.resource,action:w.action}).from(S).leftJoin(w,N(S.permissionId,w.id)).where(N(S.roleId,e))}async getRolesByPermission(e){return await this.db.select({id:fe.id,name:fe.name,description:fe.description}).from(S).leftJoin(fe,N(S.roleId,fe.id)).where(N(S.permissionId,e))}async assignPermissionToRole(e,t){let[a]=await this.db.insert(S).values({roleId:e,permissionId:t}).returning();return a}async removePermissionFromRole(e,t){let[a]=await this.db.delete(S).where(Qt(N(S.roleId,e),N(S.permissionId,t))).returning();return a}async checkRoleHasPermission(e,t){let[a]=await this.db.select().from(S).where(Qt(N(S.roleId,e),N(S.permissionId,t)));return!!a}async deleteAll(){return await this.db.delete(S),await this.db.delete(w).returning()}}_=n([rr()],_);import{createGuard as ar,Injectable as ir,GuardParams as nr,Headers as or,Ctx as cr}from"najm-api";class ee{tokenService;constructor(e){this.tokenService=e}async getUserPermissions(e){let t=await this.tokenService.getUserPermissions(e);if(!t||!Array.isArray(t))return null;return t}checkPermissionMatch(e,t){if(e.includes(t))return!0;let[a,i]=t.split(":");if(a&&i){if(e.includes(`${a}:*`))return!0;if(e.includes(`*:${i}`))return!0}if(e.includes("*:*"))return!0;return!1}async hasPermission(e,t,a){await this.tokenService.storeUserInCache(e,t);let i=await this.getUserPermissions(e);if(!i)return!1;return this.checkPermissionMatch(i,a)}}n([u(0,or("authorization")),u(1,cr()),u(2,nr()),r("design:type",Function),r("design:paramtypes",[Object,Object,Object]),r("design:returntype",Object)],ee.prototype,"hasPermission",null),ee=n([ir(),r("design:paramtypes",[typeof A==="undefined"?Object:A])],ee);var ur=(...e)=>ar(ee,"hasPermission")(...e);import{Controller as dr,Get as Ae,Post as Zt,Put as hr,Delete as je,Params as Z,Body as jt,t as $}from"najm-api";import{Injectable as yr}from"najm-api";import{Injectable as pr,t as Ke}from"najm-api";import{parseSchema as lr}from"@/shared";import{z as we}from"zod";var mr=we.object({name:we.string().min(1,"Permission name is required"),description:we.string().optional(),resource:we.string().min(1,"Resource is required"),action:we.string().min(1,"Action is required")});class L{permissionRepository;roleValidator;constructor(e,t){this.permissionRepository=e;this.roleValidator=t}async validateCreatePermission(e){return lr(mr,e)}async isPermissionExists(e){return!!await this.permissionRepository.getById(e)}async isPermissionNameExists(e){return!!await this.permissionRepository.getByName(e)}async checkPermissionExists(e){let t=await this.isPermissionExists(e);if(!t)throw new Error(Ke("permissions.errors.notFound"));return t}async checkPermissionExistsByName(e){let t=await this.isPermissionNameExists(e);if(!t)throw new Error(Ke("permissions.errors.notFound"));return t}async checkPermissionNameUnique(e,t=null){if(!e)return;let a=await this.permissionRepository.getByName(e);if(a&&a.id!==t)throw new Error(Ke("permissions.errors.nameExists"))}async checkRoleExists(e){return await this.roleValidator.checkRoleExists(e)}async checkRoleExistsByName(e){return await this.roleValidator.checkRoleExistsByName(e)}async checkRoleHasPermission(e,t){if(await this.roleValidator.checkRoleExists(e),await this.checkPermissionExists(t),await this.permissionRepository.checkRoleHasPermission(e,t))throw new Error(Ke("permissions.errors.roleAlreadyHasPermission"))}}L=n([pr(),r("design:paramtypes",[typeof _==="undefined"?Object:_,typeof K==="undefined"?Object:K])],L);class Y{permissionRepository;permissionValidator;roleService;constructor(e,t,a){this.permissionRepository=e;this.permissionValidator=t;this.roleService=a}async getAll(){return await this.permissionRepository.getAll()}async getById(e){return await this.permissionValidator.checkPermissionExists(e),await this.permissionRepository.getById(e)}async getByName(e){return await this.permissionRepository.getByName(e)}async getByResource(e){return await this.permissionRepository.getAll().then((t)=>t.filter((a)=>a.resource===e))}async create(e){return await this.permissionValidator.validateCreatePermission(e),await this.permissionValidator.checkPermissionNameUnique(e.name),await this.permissionRepository.create(e)}async update(e,t){return await this.permissionValidator.checkPermissionExists(e),await this.permissionValidator.checkPermissionNameUnique(t.name,e),await this.permissionRepository.update(e,t)}async delete(e){return await this.permissionValidator.checkPermissionExists(e),await this.permissionRepository.delete(e)}async getPermissionsByRole(e){return await this.permissionRepository.getPermissionsByRole(e)}async getRolesByPermission(e){return await this.permissionValidator.checkPermissionExists(e),await this.permissionRepository.getRolesByPermission(e)}async assignPermissionToRole(e,t){return await this.permissionValidator.checkRoleHasPermission(e,t),await this.permissionRepository.assignPermissionToRole(e,t)}async removePermissionFromRole(e,t){return await this.permissionRepository.removePermissionFromRole(e,t)}async seedDefaultPermissions(e){let t=[];for(let a of e)try{let i=await this.create(a);t.push(i)}catch(i){continue}return t}async seedDefaultRolePermissions(e){let t=[];for(let{roleName:a,permissions:i}of e)try{await this.permissionValidator.checkRoleExistsByName(a);let l=await this.roleService.getByName(a);for(let c of i)try{await this.permissionValidator.checkPermissionExistsByName(c);let d=await this.getByName(c);await this.permissionValidator.checkRoleHasPermission(l.id,d.id),await this.assignPermissionToRole(l.id,d.id),t.push({role:a,permission:c})}catch(d){continue}}catch(l){continue}return t}async deleteAll(){return await this.permissionRepository.deleteAll()}}Y=n([yr(),r("design:paramtypes",[typeof _==="undefined"?Object:_,typeof L==="undefined"?Object:L,typeof B==="undefined"?Object:B])],Y);import{isAdmin as Lt}from"@/roles/RoleGuards";class ce{permissionService;constructor(e){this.permissionService=e}async getPermissions(){return{data:await this.permissionService.getAll(),message:$("permissions.success.retrieved"),status:"success"}}async getPermission(e){return{data:await this.permissionService.getById(e),message:$("permissions.success.retrieved"),status:"success"}}async create(e){return{data:await this.permissionService.create(e),message:$("permissions.success.created"),status:"success"}}async update(e,t){return{data:await this.permissionService.update(e,t),message:$("permissions.success.updated"),status:"success"}}async delete(e){return{data:await this.permissionService.delete(e),message:$("permissions.success.deleted"),status:"success"}}async getByRole(e){return{data:await this.permissionService.getPermissionsByRole(e),message:$("permissions.success.retrieved"),status:"success"}}async getRolesByPermission(e){return{data:await this.permissionService.getRolesByPermission(e),message:$("permissions.success.retrieved"),status:"success"}}async assignToRole(e,t){return{data:await this.permissionService.assignPermissionToRole(e,t),message:$("permissions.success.assigned"),status:"success"}}async removeFromRole(e,t){return{data:await this.permissionService.removePermissionFromRole(e,t),message:$("permissions.success.removed"),status:"success"}}async deleteAll(){return{data:await this.permissionService.deleteAll(),message:$("permissions.success.allDeleted"),status:"success"}}}n([Ae(),r("design:type",Function),r("design:paramtypes",[]),r("design:returntype",Promise)],ce.prototype,"getPermissions",null),n([Ae("/:id"),u(0,Z("id")),r("design:type",Function),r("design:paramtypes",[String]),r("design:returntype",Promise)],ce.prototype,"getPermission",null),n([Zt(),u(0,jt()),r("design:type",Function),r("design:paramtypes",[Object]),r("design:returntype",Promise)],ce.prototype,"create",null),n([hr("/:id"),u(0,Z("id")),u(1,jt()),r("design:type",Function),r("design:paramtypes",[String,Object]),r("design:returntype",Promise)],ce.prototype,"update",null),n([je("/:id"),u(0,Z("id")),r("design:type",Function),r("design:paramtypes",[String]),r("design:returntype",Promise)],ce.prototype,"delete",null),n([Ae("/role/:roleId"),u(0,Z("roleId")),r("design:type",Function),r("design:paramtypes",[String]),r("design:returntype",Promise)],ce.prototype,"getByRole",null),n([Ae("/roles/:permissionId"),u(0,Z("permissionId")),r("design:type",Function),r("design:paramtypes",[String]),r("design:returntype",Promise)],ce.prototype,"getRolesByPermission",null),n([Zt("/assign/:roleId/:permissionId"),u(0,Z("roleId")),u(1,Z("permissionId")),r("design:type",Function),r("design:paramtypes",[String,String]),r("design:returntype",Promise)],ce.prototype,"assignToRole",null),n([je("/remove/:roleId/:permissionId"),u(0,Z("roleId")),u(1,Z("permissionId")),r("design:type",Function),r("design:paramtypes",[String,String]),r("design:returntype",Promise)],ce.prototype,"removeFromRole",null),n([je(),Lt(),r("design:type",Function),r("design:paramtypes",[]),r("design:returntype",Promise)],ce.prototype,"deleteAll",null),ce=n([dr("/permissions"),Lt(),r("design:paramtypes",[typeof Y==="undefined"?Object:Y])],ce);import*as Yt from"fs/promises";import*as Le from"path";import gr from"lodash.isempty";import{sql as v}from"drizzle-orm";var fr=Le.join(process.cwd(),"avatars"),Ao=async(e,t)=>{try{return await e.parseAsync(t)}catch(a){let l=(a.issues||a.errors||[]).map((c)=>`${c.path.join(".")}: ${c.message}`).join("; ");throw new Error(l)}},Bo=(e)=>{let t={};for(let[a,i]of Object.entries(e))if(i!==null&&i!==void 0&&i!=="")t[a]=i;return t},Po=async(e)=>{try{let t=Le.join(fr,e),a=await Yt.readFile(t);return new File([a],e,{type:"image/png"})}catch(t){return null}},Gt=(e)=>{if(!e)return null;let t;if(e instanceof Date)t=e;else if(typeof e==="string")t=new Date(e);else return null;if(isNaN(t.getTime()))return null;return t.toISOString().split("T")[0]};function Io(e){if(!e)return null;let t=Gt(e);if(!t)return null;let a=new Date(t),i=new Date,l=i.getFullYear()-a.getFullYear(),c=i.getMonth()-a.getMonth();if(c<0||c===0&&i.getDate()<a.getDate())l--;return l}function Vo(e){if(!e)return null;let t=Gt(e);if(!t)return null;let a=new Date(t),i=new Date,l=i.getFullYear()-a.getFullYear(),c=i.getMonth()-a.getMonth();if(c<0||c===0&&i.getDate()<a.getDate())l--;return l}function bo(e,t){let a={};for(let i of t)if(e[i]!==void 0)a[i]=e[i];return a}var _o=gr;function $o(e,t){let i=Object.entries(e).flatMap(([c,d])=>[v.raw(`'${c}'`),d]),l=v`json_agg(json_build_object(${v.join(i,v`, `)})`;if(t)l=v`${l} ORDER BY ${t}`;return l=v`${l})`,v`COALESCE(${l}, '[]'::json)`}function Jo(e,t,a,i){let c=Object.entries(e).flatMap(([E,ue])=>[v.raw(`'${E}'`),ue]),d=v`
2
- SELECT json_agg(DISTINCT json_build_object(${v.join(c,v`, `)}))
3
- FROM ${t}
4
- WHERE ${a}
5
- `;if(i)d=v`
6
- SELECT json_agg(json_build_object(${v.join(c,v`, `)}) ORDER BY ${i})
7
- FROM ${t}
8
- WHERE ${a}
9
- `;return v`COALESCE((${d}), '[]'::json)`}var Mo=(e)=>typeof e==="string"&&e.trim().length>0&&(e.startsWith("/")||e.startsWith("http")||e.startsWith("storage/")),Co=(e)=>!!e&&typeof e!=="string"&&e instanceof File;import{drizzle as Sr}from"drizzle-orm/postgres-js";var Oe={};os(Oe,{usersTable:()=>Ye,tokensTable:()=>zt,timestamps:()=>ve,rolesTable:()=>Ie,rolePermissionsTable:()=>es,permissionsTable:()=>Ge,idField:()=>te});import{pgTable as xe,text as k,boolean as vr,timestamp as Pe}from"drizzle-orm/pg-core";import{nanoid as kr}from"nanoid";import{sql as Tr}from"drizzle-orm";import{getEnumConfig as wr}from"@/lib/ENUMS";import{pgEnum as xr}from"drizzle-orm/pg-core";var Be=(e)=>{let t=wr(e);if(!t)throw new Error(`Enum ${e} not found`);let a=t.name||e;return xr(a,t.values)},Ot=Be("userStatus"),qt=Be("tokenStatus"),Ft=Be("tokenType"),Do=Be("studentStatus");var ve={createdAt:Pe("created_at",{mode:"string"}).defaultNow(),updatedAt:Pe("updated_at",{mode:"string"}).defaultNow().$onUpdate(()=>Tr`CURRENT_TIMESTAMP`)},te=(e=5)=>k("id").primaryKey().notNull().$defaultFn(()=>kr(e)),Ie=xe("roles",{id:te(),name:k("name").notNull(),description:k("description")}),Ye=xe("users",{id:te(8),email:k("email").notNull().unique(),emailVerified:vr("email_verified").default(!1),password:k("password").notNull(),image:k("image").default("noavatar.png"),status:Ot("status").default("pending"),roleId:k("role_id").references(()=>Ie.id),lastLogin:Pe("last_login",{mode:"string"}),...ve}),zt=xe("tokens",{id:te(10),userId:k("user_id").references(()=>Ye.id,{onDelete:"cascade"}).unique().notNull(),token:k("token").notNull(),type:Ft("type").default("refresh"),status:qt("status").default("active"),expiresAt:Pe("expires_at",{mode:"string"}).notNull(),...ve}),Ge=xe("permissions",{id:te(),name:k("name").notNull().unique(),description:k("description"),resource:k("resource").notNull(),action:k("action").notNull(),...ve}),es=xe("role_permissions",{id:te(),roleId:k("role_id").references(()=>Ie.id).notNull(),permissionId:k("permission_id").references(()=>Ge.id).notNull(),...ve});var ts=process.env.DB_URL?Sr(process.env.DB_URL,{schema:Oe}):null;if(ts)console.warn("⚠️ najm-auth: Using standalone DB instance. This should only be used for development.");var Er={name:"najm-auth",version:"0.1.3",database:"auth",controllers:[ye,de,le,ce],services:[W,F,G,J,B,Y,A],repositories:[M,H,_,O],providers:[C,K,L,q,ee],onSetup:async()=>{console.log(" ✓ najm-auth plugin initialized"),console.log(" - Authentication endpoints ready"),console.log(" - Authorization system active"),console.log(" - Database connection established")},onTeardown:async()=>{console.log(" ✓ najm-auth plugin cleanup complete")}};export{Ht as vehicleTypeEnum,Ct as vehicleStatusEnum,bn as vehicleSchema,tn as vehicleDocumentTypeEnum,Ye as usersTable,Xi as userTypeEnum,pt as userStatusEnum,pn as userSchema,en as trackerModeEnum,zt as tokensTable,Qi as tokenTypeEnum,Di as tokenStatusEnum,mt as teacherStatusEnum,Os as teacherProfessionalSchema,Gs as teacherPersonalSchema,yn as teacherFullSchema,Oi as submissionTypeEnum,vn as subjectSchema,lt as studentStatusEnum,Ls as studentSchema,$n as settingsSchema,ji as semesterEnum,ht as sectionStatusEnum,kn as sectionSchema,Kt as scheduleEnum,Ie as rolesTable,ln as roleSchema,es as rolePermissionsTable,dt as relationshipTypeEnum,Wt as refuelStatusEnum,_n as refuelSchema,Fi as proficiencyLevelEnum,bo as pickProps,Ge as permissionsTable,Nt as paymentTypeEnum,Pt as paymentStatusEnum,ge as paymentMethodEnum,wn as paymentAllocationSchema,_t as participantTypeEnum,Ao as parseSchema,er as parentsSchema,Ys as parentSchema,Mn as paginationSchema,nn as maritalStatusEnum,rn as maintenanceTypeEnum,an as maintenanceStatusEnum,gt as languageEnum,Jo as jsonAggSubquery,$o as jsonAgg,Aa as isTeacher,Pa as isStudent,ba as isStaff,Ka as isSecretary,Ra as isPrincipal,Mo as isPath,Ba as isParent,Va as isFinancial,Co as isFile,_o as isEmpty,_a as isAuth,Ia as isAdministrator,ie as isAdmin,Na as isAccounting,Jn as idParamSchema,te as idField,Tt as gradeStatusEnum,Un as gradeSchema,Mi as getEnumValues,Ji as getEnumConfig,Po as getAvatarFile,he as genderEnum,xn as fullStudentSchema,Xt as fuelTypeEnum,Gt as formatDate,Zi as fileStatusEnum,tr as feesSchema,Rt as feeTypeStatusEnum,dn as feeTypeSchema,At as feeStatusEnum,zs as feeSchema,fn as feePaymentSchema,Bt as feeInstallmentStatusEnum,gn as feeInstallmentSchema,Jt as expenseStatusEnum,Pn as expenseSchema,Vn as expensePaymentSchema,$t as expenseCategoryEnum,In as expenseApprovalSchema,vt as examTypeEnum,kt as examStatusEnum,qi as examSecurityEnum,Rn as examSchema,bt as eventVisibilityEnum,It as eventTypeEnum,Vt as eventStatusEnum,An as eventSchema,Bn as eventParticipantSchema,Yi as enrollmentStatusEnum,yt as employmentTypeEnum,Mt as driverStatusEnum,mn as driverSchema,ts as db,zi as dayOfWeekEnum,Cn as dateRangeSchema,Bo as clean,Li as classStatusEnum,Tn as classSchema,ft as calendarSystemEnum,Vo as calculateYearsOfExperience,Io as calculateAge,sn as busStatusEnum,Dt as bulkFeeItemSchema,hn as bulkFeeFormSchema,En as bulkAssessmentSchema,fr as avatarsPath,De as attendanceStatusEnum,Sn as attendanceSchema,Fs as assignmentsSchema,Gi as assignmentStatusEnum,qs as assignmentSchema,wt as assessmentTypeEnum,xt as assessmentStatusEnum,sr as assessmentSchema,Nn as announcementSchema,St as alertTypeEnum,Ut as alertStatusEnum,Kn as alertSchema,Et as alertPriorityEnum,C as UserValidator,W as UserService,M as UserRepository,ye as UserController,A as TokenService,O as TokenRepository,K as RoleValidator,B as RoleService,H as RoleRepository,q as RoleGuards,le as RoleController,Ee as RoleChecker,V as Role,tt as ROLE_GROUPS,f as ROLES,L as PermissionValidator,Y as PermissionService,_ as PermissionRepository,ee as PermissionGuards,ce as PermissionController,ur as Permission,J as EncryptionService,Ue as ENUMS,G as CookieService,F as AuthService,Er as AuthPlugin,de as AuthController};
10
-
11
- //# debugId=46440D7F5E9F307264756E2164756E21
12
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsic3JjXFxhdXRoXFxFbmNyeXB0aW9uU2VydmljZS50cyIsICJzcmNcXGF1dGhcXENvb2tpZVNlcnZpY2UudHMiLCAic3JjXFxhdXRoXFxBdXRoQ29udHJvbGxlci50cyIsICJzcmNcXGF1dGhcXEF1dGhTZXJ2aWNlLnRzIiwgInNyY1xcdXNlcnNcXFVzZXJSZXBvc2l0b3J5LnRzIiwgInNyY1xcdXNlcnNcXFVzZXJWYWxpZGF0b3IudHMiLCAic3JjXFx1c2Vyc1xcVXNlclNlcnZpY2UudHMiLCAic3JjXFxyb2xlc1xcUm9sZVJlcG9zaXRvcnkudHMiLCAic3JjXFxyb2xlc1xcUm9sZVZhbGlkYXRvci50cyIsICJzcmNcXHJvbGVzXFxSb2xlR3VhcmRzLnRzIiwgInNyY1xcdG9rZW5zXFxUb2tlblJlcG9zaXRvcnkudHMiLCAic3JjXFx0b2tlbnNcXFRva2VuU2VydmljZS50cyIsICJzcmNcXHJvbGVzXFxSb2xlQ29udHJvbGxlci50cyIsICJzcmNcXHJvbGVzXFxSb2xlU2VydmljZS50cyIsICJzcmNcXHVzZXJzXFxVc2VyQ29udHJvbGxlci50cyIsICJzcmNcXGxpYlxcRU5VTVMudHMiLCAic3JjXFxsaWJcXHZhbGlkYXRpb25zLnRzIiwgInNyY1xcbGliXFxab2RFbnVtLnRzIiwgInNyY1xccGVybWlzc2lvbnNcXFBlcm1pc3Npb25SZXBvc2l0b3J5LnRzIiwgInNyY1xccGVybWlzc2lvbnNcXFBlcm1pc3Npb25HdWFyZHMudHMiLCAic3JjXFxwZXJtaXNzaW9uc1xcUGVybWlzc2lvbkNvbnRyb2xsZXIudHMiLCAic3JjXFxwZXJtaXNzaW9uc1xcUGVybWlzc2lvblNlcnZpY2UudHMiLCAic3JjXFxwZXJtaXNzaW9uc1xcUGVybWlzc2lvblZhbGlkYXRvci50cyIsICJzcmNcXHNoYXJlZFxcaW5kZXgudHMiLCAic3JjXFxkYXRhYmFzZVxcZGIudHMiLCAic3JjXFxkYXRhYmFzZVxcc2NoZW1hXFxpbmRleC50cyIsICJzcmNcXGRhdGFiYXNlXFxzY2hlbWFcXFBnRW51bS50cyIsICJzcmNcXHBsdWdpbi50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsKICAgICJcbmltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICduYWptLWFwaSc7XG5pbXBvcnQgYmNyeXB0IGZyb20gJ2JjcnlwdCdcblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIEVuY3J5cHRpb25TZXJ2aWNlIHtcbiAgY29uc3RydWN0b3IoKSB7IH1cblxuICBhc3luYyBoYXNoUGFzc3dvcmQocGFzc3dvcmQpIHtcbiAgICBpZiAoIXBhc3N3b3JkKSByZXR1cm4gbnVsbDtcbiAgICBpZiAodHlwZW9mIHBhc3N3b3JkICE9PSAnc3RyaW5nJyB8fCBwYXNzd29yZC50cmltKCkubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIGJjcnlwdC5oYXNoKHBhc3N3b3JkLCAxMCk7XG4gIH1cblxuICBhc3luYyBjb21wYXJlUGFzc3dvcmQocGFzc3dvcmQsIGhhc2hlZFBhc3N3b3JkKSB7XG4gICAgcmV0dXJuIGJjcnlwdC5jb21wYXJlKHBhc3N3b3JkLCBoYXNoZWRQYXNzd29yZCk7XG4gIH1cblxufVxuIiwKICAgICJcbmltcG9ydCB7IHNldENvb2tpZSwgSW5qZWN0YWJsZSwgZGVsZXRlQ29va2llIH0gZnJvbSAnbmFqbS1hcGknO1xuaW1wb3J0IHRpbWVzdHJpbmcgZnJvbSAndGltZXN0cmluZyc7XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBDb29raWVTZXJ2aWNlIHtcblxuICBzZXRSZWZyZXNoQ29va2llKHJlZnJlc2hUb2tlbikge1xuICAgIGNvbnN0IG1heEFnZSA9IHRpbWVzdHJpbmcocHJvY2Vzcy5lbnYuUkVGUkVTSF9FWFBJUkVTX0lOLCAncycpOyAgLy8vICcxeSdcbiAgICBzZXRDb29raWUoJ3JlZnJlc2hUb2tlbicsIHJlZnJlc2hUb2tlbiwge1xuICAgICAgaHR0cE9ubHk6IGZhbHNlLFxuICAgICAgc2FtZVNpdGU6ICdMYXgnLFxuICAgICAgbWF4QWdlLFxuICAgICAgcGF0aDogJy9hcGkvYXV0aC9yZWZyZXNoJyxcbiAgICB9KVxuICB9XG5cbiAgY2xlYXJSZWZyZXNoQ29va2llKCk6IHZvaWQge1xuICAgIGRlbGV0ZUNvb2tpZSgncmVmcmVzaFRva2VuJywge1xuICAgICAgaHR0cE9ubHk6IGZhbHNlLFxuICAgICAgc2FtZVNpdGU6ICdMYXgnLFxuICAgICAgcGF0aDogJy9hcGkvYXV0aC9yZWZyZXNoJyxcbiAgICAgIG1heEFnZTogMFxuICAgIH0pO1xuICB9XG5cblxufVxuIiwKICAgICJpbXBvcnQgeyBDb250cm9sbGVyLCBHZXQsIFBvc3QsIFBhcmFtcywgQm9keSwgVXNlciwgdCB9IGZyb20gJ25ham0tYXBpJztcbmltcG9ydCB7IEF1dGhTZXJ2aWNlIH0gZnJvbSAnLi9BdXRoU2VydmljZSc7XG5pbXBvcnQgeyBpc0F1dGggfSBmcm9tICdAL3JvbGVzL1JvbGVHdWFyZHMnO1xuXG5cbkBDb250cm9sbGVyKCcvYXV0aCcpXG5leHBvcnQgY2xhc3MgQXV0aENvbnRyb2xsZXIge1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGF1dGhTZXJ2aWNlOiBBdXRoU2VydmljZSkgeyB9XG5cbiAgQFBvc3QoJy9yZWdpc3RlcicpXG4gIGFzeW5jIHJlZ2lzdGVyVXNlcihAQm9keSgpIGJvZHkpIHtcbiAgICBjb25zdCBkYXRhID0gYXdhaXQgdGhpcy5hdXRoU2VydmljZS5yZWdpc3RlclVzZXIoYm9keSk7XG4gICAgcmV0dXJuIHtcbiAgICAgIGRhdGEsXG4gICAgICBtZXNzYWdlOiB0KCdhdXRoLnN1Y2Nlc3MucmVnaXN0ZXInKSxcbiAgICAgIHN0YXR1czogJ3N1Y2Nlc3MnXG4gICAgfTtcbiAgfVxuXG4gIEBQb3N0KCcvbG9naW4nKVxuICBhc3luYyBsb2dpblVzZXIoQEJvZHkoKSBib2R5KSB7XG4gICAgY29uc3QgZGF0YSA9IGF3YWl0IHRoaXMuYXV0aFNlcnZpY2UubG9naW5Vc2VyKGJvZHkpO1xuICAgIHJldHVybiB7XG4gICAgICBkYXRhLFxuICAgICAgbWVzc2FnZTogdCgnYXV0aC5zdWNjZXNzLmxvZ2luJyksXG4gICAgICBzdGF0dXM6ICdzdWNjZXNzJ1xuICAgIH07XG4gIH1cblxuICBAR2V0KCcvcmVmcmVzaCcpXG4gIGFzeW5jIHJlZnJlc2hUb2tlbnMoKSB7XG4gICAgY29uc3QgZGF0YSA9IGF3YWl0IHRoaXMuYXV0aFNlcnZpY2UucmVmcmVzaFRva2VucygpO1xuICAgIHJldHVybiB7XG4gICAgICBkYXRhLFxuICAgICAgbWVzc2FnZTogdCgnYXV0aC5zdWNjZXNzLnRva2VuUmVmcmVzaGVkJyksXG4gICAgICBzdGF0dXM6ICdzdWNjZXNzJ1xuICAgIH07XG4gIH1cblxuICBAR2V0KCcvbG9nb3V0LzppZCcpXG4gIGFzeW5jIGxvZ291dFVzZXIoQFBhcmFtcygnaWQnKSBpZCkge1xuICAgIGNvbnN0IGRhdGEgPSBhd2FpdCB0aGlzLmF1dGhTZXJ2aWNlLmxvZ291dFVzZXIoaWQpO1xuICAgIHJldHVybiB7XG4gICAgICBkYXRhLFxuICAgICAgbWVzc2FnZTogdCgnYXV0aC5zdWNjZXNzLmxvZ291dCcpLFxuICAgICAgc3RhdHVzOiAnc3VjY2VzcydcbiAgICB9O1xuICB9XG5cblxuICBAR2V0KCcvbWUnKVxuICBAaXNBdXRoKClcbiAgYXN5bmMgdXNlclByb2ZpbGUoQFVzZXIoKSB1c2VyKSB7XG4gICAgY29uc3QgZGF0YSA9IGF3YWl0IHRoaXMuYXV0aFNlcnZpY2UuZ2V0VXNlclByb2ZpbGUodXNlcik7XG4gICAgcmV0dXJuIHtcbiAgICAgIGRhdGEsXG4gICAgICBtZXNzYWdlOiB0KCd1c2Vycy5zdWNjZXNzLnJldHJpZXZlZCcpLFxuICAgICAgc3RhdHVzOiAnc3VjY2VzcydcbiAgICB9O1xuICB9XG5cbiAgQFBvc3QoJy9mb3Jnb3QtcGFzc3dvcmQnKVxuICBAaXNBdXRoKClcbiAgYXN5bmMgZm9yZ290UGFzc3dvcmQoQEJvZHkoKSBib2R5KSB7XG4gICAgY29uc3QgZGF0YSA9IGF3YWl0IHRoaXMuYXV0aFNlcnZpY2UuZm9yZ290UGFzc3dvcmQoYm9keS5lbWFpbCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIGRhdGEsXG4gICAgICBtZXNzYWdlOiB0KCdhdXRoLnN1Y2Nlc3MucGFzc3dvcmRSZXNldCcpLFxuICAgICAgc3RhdHVzOiAnc3VjY2VzcydcbiAgICB9O1xuICB9XG59IiwKICAgICJpbXBvcnQgeyB0IH0gZnJvbSAnbmFqbS1hcGknO1xuaW1wb3J0IHsgSW5qZWN0YWJsZSwgZ2V0Q3VycmVudExhbmd1YWdlIH0gZnJvbSAnbmFqbS1hcGknO1xuaW1wb3J0IHsgVXNlclNlcnZpY2UsIFVzZXJWYWxpZGF0b3IgfSBmcm9tICcuLi91c2Vycyc7XG5pbXBvcnQgeyBUb2tlblNlcnZpY2UgfSBmcm9tICcuLi90b2tlbnMnO1xuaW1wb3J0IHsgQ29va2llU2VydmljZSB9IGZyb20gJy4vQ29va2llU2VydmljZSc7XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBBdXRoU2VydmljZSB7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSB0b2tlblNlcnZpY2U6IFRva2VuU2VydmljZSxcbiAgICBwcml2YXRlIHVzZXJTZXJ2aWNlOiBVc2VyU2VydmljZSxcbiAgICBwcml2YXRlIHVzZXJWYWxpZGF0b3I6IFVzZXJWYWxpZGF0b3IsXG4gICAgcHJpdmF0ZSBjb29raWVTZXJ2aWNlOiBDb29raWVTZXJ2aWNlLFxuICApIHsgfVxuXG4gIGFzeW5jIHJlZ2lzdGVyVXNlcihib2R5KSB7XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMudXNlclNlcnZpY2UuY3JlYXRlKGJvZHkpXG4gIH1cblxuICBhc3luYyBsb2dpblVzZXIoYm9keSkge1xuICAgIGNvbnN0IHsgZW1haWwsIHBhc3N3b3JkIH0gPSBib2R5O1xuXG4gICAgaWYgKCFlbWFpbCB8fCAhcGFzc3dvcmQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcih0KCdhdXRoLmVycm9ycy5pbnZhbGlkQ3JlZGVudGlhbHMnKSlcbiAgICB9XG5cbiAgICBjb25zdCBleGlzdGluZ1Bhc3N3b3JkID0gYXdhaXQgdGhpcy51c2VyU2VydmljZS5nZXRQYXNzd29yZChlbWFpbCk7XG4gICAgY29uc3QgeyBpZCB9ID0gYXdhaXQgdGhpcy51c2VyU2VydmljZS5nZXRCeUVtYWlsKGVtYWlsKTtcbiAgICBhd2FpdCB0aGlzLnVzZXJWYWxpZGF0b3IuY2hlY2tQYXNzd29yZFZhbGlkKHBhc3N3b3JkLCBleGlzdGluZ1Bhc3N3b3JkKTtcblxuICAgIGNvbnN0IGRhdGEgPSBhd2FpdCB0aGlzLnRva2VuU2VydmljZS5nZW5lcmF0ZVRva2VucyhpZCk7XG4gICAgdGhpcy5jb29raWVTZXJ2aWNlLnNldFJlZnJlc2hDb29raWUoZGF0YS5yZWZyZXNoVG9rZW4pXG4gICAgcmV0dXJuIGRhdGE7XG4gIH1cblxuICBhc3luYyByZWZyZXNoVG9rZW5zKCkge1xuICAgIGNvbnN0IGRhdGEgPSBhd2FpdCB0aGlzLnRva2VuU2VydmljZS5yZWZyZXNoVG9rZW5zKCk7XG4gICAgdGhpcy5jb29raWVTZXJ2aWNlLnNldFJlZnJlc2hDb29raWUoZGF0YS5yZWZyZXNoVG9rZW4pO1xuICAgIHJldHVybiBkYXRhO1xuICB9XG5cbiAgYXN5bmMgbG9nb3V0VXNlcih1c2VySWQpIHtcbiAgICBhd2FpdCB0aGlzLnVzZXJWYWxpZGF0b3IuY2hlY2tVc2VyRXhpc3RzKHVzZXJJZCk7XG4gICAgYXdhaXQgdGhpcy50b2tlblNlcnZpY2UucmV2b2tlVG9rZW4odXNlcklkKTtcbiAgICB0aGlzLmNvb2tpZVNlcnZpY2UuY2xlYXJSZWZyZXNoQ29va2llKCk7XG4gICAgcmV0dXJuIHsgZGF0YTogbnVsbCwgbWVzc2FnZTogdCgnYXV0aC5zdWNjZXNzLmxvZ291dCcpIH07XG4gIH1cblxuICBhc3luYyBnZXRVc2VyUHJvZmlsZSh1c2VyRGF0YSkge1xuICAgIGNvbnN0IGxhbmcgPSBnZXRDdXJyZW50TGFuZ3VhZ2UoKTtcbiAgICByZXR1cm4ge1xuICAgICAgLi4udXNlckRhdGEsXG4gICAgICBsYW5ndWFnZTogbGFuZyxcbiAgICB9O1xuICB9XG5cbiAgYXN5bmMgZm9yZ290UGFzc3dvcmQoZW1haWwpIHtcblxuICB9XG59XG5cblxuIiwKICAgICJcbmltcG9ydCB7IHJvbGVzVGFibGUsIHVzZXJzVGFibGUsIHBlcm1pc3Npb25zVGFibGUsIHJvbGVQZXJtaXNzaW9uc1RhYmxlIH0gZnJvbSAnQC9kYXRhYmFzZS9zY2hlbWEnO1xuaW1wb3J0IHsgZXEsIG5lIH0gZnJvbSAnZHJpenpsZS1vcm0nO1xuaW1wb3J0IHsgUmVwb3NpdG9yeSxEQiB9IGZyb20gJ25ham0tYXBpJztcblxuQFJlcG9zaXRvcnkoKVxuZXhwb3J0IGNsYXNzIFVzZXJSZXBvc2l0b3J5IHtcbiAgZGVjbGFyZSBkYjogREI7XG5cbiAgcHJpdmF0ZSBnZXRVc2VyKCkge1xuICAgIHJldHVybiB7XG4gICAgICBpZDogdXNlcnNUYWJsZS5pZCxcbiAgICAgIGVtYWlsOiB1c2Vyc1RhYmxlLmVtYWlsLFxuICAgICAgZW1haWxWZXJpZmllZDogdXNlcnNUYWJsZS5lbWFpbFZlcmlmaWVkLFxuICAgICAgaW1hZ2U6IHVzZXJzVGFibGUuaW1hZ2UsXG4gICAgICBzdGF0dXM6IHVzZXJzVGFibGUuc3RhdHVzLFxuICAgICAgcm9sZUlkOiB1c2Vyc1RhYmxlLnJvbGVJZCxcbiAgICAgIHJvbGU6IHJvbGVzVGFibGUubmFtZSxcbiAgICAgIGNyZWF0ZWRBdDogdXNlcnNUYWJsZS5jcmVhdGVkQXQsXG4gICAgICB1cGRhdGVkQXQ6IHVzZXJzVGFibGUudXBkYXRlZEF0LFxuICAgIH07XG4gIH1cblxuICBhc3luYyBnZXRBbGwoKSB7XG4gICAgY29uc3QgYWxsVXNlcnMgPSBhd2FpdCB0aGlzLmRiXG4gICAgICAuc2VsZWN0KHRoaXMuZ2V0VXNlcigpKVxuICAgICAgLmZyb20odXNlcnNUYWJsZSlcbiAgICAgIC5sZWZ0Sm9pbihyb2xlc1RhYmxlLCBlcSh1c2Vyc1RhYmxlLnJvbGVJZCwgcm9sZXNUYWJsZS5pZCkpO1xuXG4gICAgLy8gQWRkIHBlcm1pc3Npb25zIHRvIGVhY2ggdXNlclxuICAgIHJldHVybiBQcm9taXNlLmFsbChhbGxVc2Vycy5tYXAoYXN5bmMgKHVzZXIpID0+ICh7XG4gICAgICAuLi51c2VyLFxuICAgICAgcGVybWlzc2lvbnM6IGF3YWl0IHRoaXMuZ2V0VXNlclBlcm1pc3Npb25zKHVzZXIuaWQpXG4gICAgfSkpKTtcbiAgfVxuXG4gIGFzeW5jIGdldEJ5SWQoaWQpIHtcbiAgICBjb25zdCBbdXNlcl0gPSBhd2FpdCB0aGlzLmRiXG4gICAgICAuc2VsZWN0KHRoaXMuZ2V0VXNlcigpKVxuICAgICAgLmZyb20odXNlcnNUYWJsZSlcbiAgICAgIC5sZWZ0Sm9pbihyb2xlc1RhYmxlLCBlcSh1c2Vyc1RhYmxlLnJvbGVJZCwgcm9sZXNUYWJsZS5pZCkpXG4gICAgICAud2hlcmUoZXEodXNlcnNUYWJsZS5pZCwgaWQpKVxuICAgICAgLmxpbWl0KDEpO1xuXG4gICAgaWYgKCF1c2VyKSByZXR1cm4gdXNlcjtcblxuICAgIHJldHVybiB7XG4gICAgICAuLi51c2VyLFxuICAgICAgcGVybWlzc2lvbnM6IGF3YWl0IHRoaXMuZ2V0VXNlclBlcm1pc3Npb25zKHVzZXIuaWQpXG4gICAgfTtcbiAgfVxuXG4gIGFzeW5jIGdldEJ5RW1haWwoZW1haWwpIHtcbiAgICBjb25zdCBbZXhpc3RpbmdVc2VyXSA9IGF3YWl0IHRoaXMuZGJcbiAgICAgIC5zZWxlY3QodGhpcy5nZXRVc2VyKCkpXG4gICAgICAuZnJvbSh1c2Vyc1RhYmxlKVxuICAgICAgLmxlZnRKb2luKHJvbGVzVGFibGUsIGVxKHVzZXJzVGFibGUucm9sZUlkLCByb2xlc1RhYmxlLmlkKSlcbiAgICAgIC53aGVyZShlcSh1c2Vyc1RhYmxlLmVtYWlsLCBlbWFpbCkpO1xuICAgIHJldHVybiBleGlzdGluZ1VzZXI7XG4gIH1cblxuXG4gIGFzeW5jIGNyZWF0ZShkYXRhKSB7XG4gICAgY29uc3QgW25ld1VzZXJdID0gYXdhaXQgdGhpcy5kYi5pbnNlcnQodXNlcnNUYWJsZSkudmFsdWVzKGRhdGEpLnJldHVybmluZygpO1xuICAgIHJldHVybiBuZXdVc2VyO1xuICB9XG5cbiAgYXN5bmMgdXBkYXRlKGlkLCBkYXRhKSB7XG4gICAgY29uc3QgW3VwZGF0ZWRVc2VyXSA9IGF3YWl0IHRoaXMuZGIudXBkYXRlKHVzZXJzVGFibGUpLnNldChkYXRhKS53aGVyZShlcSh1c2Vyc1RhYmxlLmlkLCBpZCkpLnJldHVybmluZygpO1xuICAgIHJldHVybiB1cGRhdGVkVXNlcjtcbiAgfVxuXG4gIGFzeW5jIGRlbGV0ZShpZCkge1xuICAgIGNvbnN0IFtkZWxldGVkVXNlcl0gPSBhd2FpdCB0aGlzLmRiLmRlbGV0ZSh1c2Vyc1RhYmxlKS53aGVyZShlcSh1c2Vyc1RhYmxlLmlkLCBpZCkpLnJldHVybmluZygpO1xuICAgIHJldHVybiBkZWxldGVkVXNlcjtcbiAgfVxuXG4gIGFzeW5jIGRlbGV0ZUFsbCgpIHtcbiAgICBjb25zdCBhZG1pblJvbGUgPSBhd2FpdCB0aGlzLmRiXG4gICAgICAuc2VsZWN0KHsgaWQ6IHJvbGVzVGFibGUuaWQgfSlcbiAgICAgIC5mcm9tKHJvbGVzVGFibGUpXG4gICAgICAud2hlcmUoZXEocm9sZXNUYWJsZS5uYW1lLCAnYWRtaW4nKSlcbiAgICAgIC5saW1pdCgxKTtcblxuICAgIGlmIChhZG1pblJvbGUubGVuZ3RoID09PSAwKSB7XG4gICAgICBjb25zdCBkZWxldGVkVXNlcnMgPSBhd2FpdCB0aGlzLmRiLmRlbGV0ZSh1c2Vyc1RhYmxlKS5yZXR1cm5pbmcoKTtcbiAgICAgIHJldHVybiBkZWxldGVkVXNlcnM7XG4gICAgfVxuICAgIGNvbnN0IGRlbGV0ZWRVc2VycyA9IGF3YWl0IHRoaXMuZGJcbiAgICAgIC5kZWxldGUodXNlcnNUYWJsZSlcbiAgICAgIC53aGVyZShuZSh1c2Vyc1RhYmxlLnJvbGVJZCwgYWRtaW5Sb2xlWzBdLmlkKSlcbiAgICAgIC5yZXR1cm5pbmcoKTtcblxuICAgIHJldHVybiBkZWxldGVkVXNlcnM7XG4gIH1cblxuICBhc3luYyBnZXRSb2xlTmFtZUJ5SWQodXNlcklkKSB7XG4gICAgY29uc3QgW3JvbGVdID0gYXdhaXQgdGhpcy5kYi5zZWxlY3Qoe1xuICAgICAgcm9sZU5hbWU6IHJvbGVzVGFibGUubmFtZVxuICAgIH0pXG4gICAgICAuZnJvbSh1c2Vyc1RhYmxlKVxuICAgICAgLmxlZnRKb2luKHJvbGVzVGFibGUsIGVxKHVzZXJzVGFibGUucm9sZUlkLCByb2xlc1RhYmxlLmlkKSlcbiAgICAgIC53aGVyZShlcSh1c2Vyc1RhYmxlLmlkLCB1c2VySWQpKVxuXG4gICAgcmV0dXJuIHJvbGUucm9sZU5hbWVcbiAgfVxuXG4gIGFzeW5jIGdldFVzZXJQYXNzd29yZChlbWFpbCkge1xuICAgIGNvbnN0IFt1c2VyXSA9IGF3YWl0IHRoaXMuZGJcbiAgICAgIC5zZWxlY3Qoe1xuICAgICAgICBpZDogdXNlcnNUYWJsZS5pZCxcbiAgICAgICAgZW1haWw6IHVzZXJzVGFibGUuZW1haWwsXG4gICAgICAgIHBhc3N3b3JkOiB1c2Vyc1RhYmxlLnBhc3N3b3JkXG4gICAgICB9KVxuICAgICAgLmZyb20odXNlcnNUYWJsZSlcbiAgICAgIC53aGVyZShlcSh1c2Vyc1RhYmxlLmVtYWlsLCBlbWFpbCkpXG4gICAgICAubGltaXQoMSk7XG4gICAgcmV0dXJuIHVzZXIucGFzc3dvcmQ7XG4gIH1cblxuICBhc3luYyBnZXRVc2VyUGVybWlzc2lvbnModXNlcklkKSB7XG4gICAgY29uc3QgW3VzZXJdID0gYXdhaXQgdGhpcy5kYlxuICAgICAgLnNlbGVjdCh7IHJvbGVJZDogdXNlcnNUYWJsZS5yb2xlSWQgfSlcbiAgICAgIC5mcm9tKHVzZXJzVGFibGUpXG4gICAgICAud2hlcmUoZXEodXNlcnNUYWJsZS5pZCwgdXNlcklkKSlcbiAgICAgIC5saW1pdCgxKTtcblxuICAgIGlmICghdXNlciB8fCAhdXNlci5yb2xlSWQpIHJldHVybiBbXTtcblxuICAgIGNvbnN0IHVzZXJQZXJtaXNzaW9ucyA9IGF3YWl0IHRoaXMuZGJcbiAgICAgIC5zZWxlY3Qoe1xuICAgICAgICBuYW1lOiBwZXJtaXNzaW9uc1RhYmxlLm5hbWUsXG4gICAgICB9KVxuICAgICAgLmZyb20ocm9sZVBlcm1pc3Npb25zVGFibGUpXG4gICAgICAubGVmdEpvaW4ocGVybWlzc2lvbnNUYWJsZSwgZXEocm9sZVBlcm1pc3Npb25zVGFibGUucGVybWlzc2lvbklkLCBwZXJtaXNzaW9uc1RhYmxlLmlkKSlcbiAgICAgIC53aGVyZShlcShyb2xlUGVybWlzc2lvbnNUYWJsZS5yb2xlSWQsIHVzZXIucm9sZUlkKSk7XG5cbiAgICByZXR1cm4gdXNlclBlcm1pc3Npb25zLm1hcChwID0+IHAubmFtZSkuZmlsdGVyKG5hbWUgPT4gbmFtZSk7XG4gIH1cblxufSIsCiAgICAiaW1wb3J0IHsgSW5qZWN0YWJsZSwgdCB9IGZyb20gJ25ham0tYXBpJztcbmltcG9ydCB7IFVzZXJSZXBvc2l0b3J5IH0gZnJvbSAnLi9Vc2VyUmVwb3NpdG9yeSc7XG5pbXBvcnQgeyBFbmNyeXB0aW9uU2VydmljZSB9IGZyb20gJy4uL2F1dGgnO1xuaW1wb3J0IHsgcGFyc2VTY2hlbWEgfSBmcm9tICdAL3NoYXJlZCc7XG5pbXBvcnQgeyB1c2VyU2NoZW1hIH0gZnJvbSAnQC9saWIvdmFsaWRhdGlvbnMnO1xuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgVXNlclZhbGlkYXRvciB7XG4gICBjb25zdHJ1Y3RvcihcbiAgICAgIHByaXZhdGUgdXNlclJlcG9zaXRvcnk6IFVzZXJSZXBvc2l0b3J5LFxuICAgICAgcHJpdmF0ZSBlbmNyeXB0aW9uU2VydmljZTogRW5jcnlwdGlvblNlcnZpY2UsXG4gICApIHsgfVxuXG4gICBhc3luYyB2YWxpZGF0ZUNyZWF0ZVVzZXIoZGF0YSkge1xuICAgICAgcmV0dXJuIHBhcnNlU2NoZW1hKHVzZXJTY2hlbWEsIGRhdGEpO1xuICAgfVxuXG4gICBhc3luYyBpc0VtYWlsRXhpc3RzKGVtYWlsKSB7XG4gICAgICBjb25zdCBleGlzdGluZ1VzZXIgPSBhd2FpdCB0aGlzLnVzZXJSZXBvc2l0b3J5LmdldEJ5RW1haWwoZW1haWwpO1xuICAgICAgcmV0dXJuICEhZXhpc3RpbmdVc2VyXG4gICB9XG5cbiAgIGFzeW5jIGlzUGFzc3dvcmRWYWxpZChwYXNzd29yZCwgaGFzaGVkUGFzc3dvcmQpIHtcbiAgICAgIGNvbnN0IGlzUGFzc3dvcmRWYWxpZCA9IGF3YWl0IHRoaXMuZW5jcnlwdGlvblNlcnZpY2UuY29tcGFyZVBhc3N3b3JkKHBhc3N3b3JkLCBoYXNoZWRQYXNzd29yZCk7XG4gICAgICByZXR1cm4gISFpc1Bhc3N3b3JkVmFsaWRcbiAgIH1cblxuICAgYXN5bmMgaXNVc2VyRXhpc3QoaWQpIHtcbiAgICAgIGNvbnN0IGV4aXN0aW5nVXNlciA9IGF3YWl0IHRoaXMudXNlclJlcG9zaXRvcnkuZ2V0QnlJZChpZCk7XG4gICAgICByZXR1cm4gISFleGlzdGluZ1VzZXJcbiAgIH1cblxuICAgYXN5bmMgY2hlY2tVc2VySWRJc1VuaXF1ZShpZCkge1xuICAgICAgaWYgKCFpZCkgcmV0dXJuO1xuICAgICAgY29uc3QgZXhpc3RpbmdVc2VyID0gYXdhaXQgdGhpcy51c2VyUmVwb3NpdG9yeS5nZXRCeUlkKGlkKTtcbiAgICAgIGlmIChleGlzdGluZ1VzZXIpIHtcbiAgICAgICAgIHRocm93IG5ldyBFcnJvcih0KCd1c2Vycy5lcnJvcnMuaWRFeGlzdHMnKSk7XG4gICAgICB9XG4gICB9XG5cbiAgIGFzeW5jIGlzQ29ycmVjdFBhc3MocGFzc3dvcmQpIHtcbiAgICAgIHJldHVybiBwYXNzd29yZCAmJlxuICAgICAgICAgdHlwZW9mIHBhc3N3b3JkID09PSAnc3RyaW5nJyAmJlxuICAgICAgICAgcGFzc3dvcmQudHJpbSgpLmxlbmd0aCA+IDA7XG4gICB9XG5cbiAgIGFzeW5jIGhhc1JvbGUodXNlcklkLCByb2xlcykge1xuICAgICAgY29uc3Qgcm9sZU5hbWUgPSBhd2FpdCB0aGlzLnVzZXJSZXBvc2l0b3J5LmdldFJvbGVOYW1lQnlJZCh1c2VySWQpO1xuXG4gICAgICBpZiAoIXJvbGVOYW1lKSB7XG4gICAgICAgICB0aHJvdyBFcnJvcih0KCdhdXRoLmVycm9ycy5hY2Nlc3NEZW5pZWQnKSlcbiAgICAgIH1cblxuICAgICAgY29uc3QgaGFzUm9sZSA9IHJvbGVzLnNvbWUoXG4gICAgICAgICBpdGVtID0+IHJvbGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09IGl0ZW0udG9Mb3dlckNhc2UoKVxuICAgICAgKVxuXG4gICAgICBpZiAoIWhhc1JvbGUpIHtcbiAgICAgICAgIHRocm93IEVycm9yKHQoJ2F1dGguZXJyb3JzLmFjY2Vzc0RlbmllZCcpKVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gdHJ1ZVxuXG4gICB9XG5cbiAgIC8vPT09PT09PT09PT09PT09PT09PT09PT0gdGhyb3cgZXJyb3JzXG5cbiAgIGFzeW5jIGNoZWNrVXNlckV4aXN0c0J5RW1haWwoZW1haWwpIHtcbiAgICAgIGNvbnN0IHVzZXIgPSBhd2FpdCB0aGlzLnVzZXJSZXBvc2l0b3J5LmdldEJ5RW1haWwoZW1haWwpO1xuICAgICAgaWYgKCF1c2VyKSB7XG4gICAgICAgICB0aHJvdyBuZXcgRXJyb3IodCgnYXV0aC5lcnJvcnMuaW52YWxpZENyZWRlbnRpYWxzJykpXG4gICAgICB9XG4gICAgICByZXR1cm4gdXNlclxuICAgfVxuXG4gICBhc3luYyBjaGVja1VzZXJFeGlzdHMoaWQpIHtcbiAgICAgIGNvbnN0IHVzZXJFeGlzdHMgPSBhd2FpdCB0aGlzLmlzVXNlckV4aXN0KGlkKTtcbiAgICAgIGlmICghdXNlckV4aXN0cykge1xuICAgICAgICAgdGhyb3cgbmV3IEVycm9yKHQoJ3VzZXJzLmVycm9ycy5ub3RGb3VuZCcpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB1c2VyRXhpc3RzO1xuICAgfVxuXG5cbiAgIGFzeW5jIGNoZWNrRW1haWxVbmlxdWUoZW1haWwsIGV4Y2x1ZGVJZCA9IG51bGwpIHtcbiAgICAgIGlmICghZW1haWwpIHJldHVybjtcbiAgICAgIGNvbnN0IGV4aXN0aW5nVXNlciA9IGF3YWl0IHRoaXMudXNlclJlcG9zaXRvcnkuZ2V0QnlFbWFpbChlbWFpbCk7XG4gICAgICBpZiAoZXhpc3RpbmdVc2VyICYmIGV4aXN0aW5nVXNlci5pZCAhPT0gZXhjbHVkZUlkKSB7XG4gICAgICAgICB0aHJvdyBuZXcgRXJyb3IodCgnYXV0aC5lcnJvcnMuZW1haWxFeGlzdHMnKSk7XG4gICAgICB9XG4gICB9XG5cbiAgIGFzeW5jIGNoZWNrRW1haWxFeGlzdHMoZW1haWwpIHtcbiAgICAgIGNvbnN0IHVzZXIgPSBhd2FpdCB0aGlzLnVzZXJSZXBvc2l0b3J5LmdldEJ5RW1haWwoZW1haWwpO1xuICAgICAgaWYgKCF1c2VyKSB7XG4gICAgICAgICB0aHJvdyBuZXcgRXJyb3IodCgndXNlcnMuZXJyb3JzLm5vdEZvdW5kJykpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHVzZXI7XG4gICB9XG5cbiAgIGFzeW5jIGNoZWNrUGFzc3dvcmRWYWxpZChwYXNzd29yZCwgaGFzaGVkUGFzc3dvcmQpIHtcbiAgICAgIGNvbnN0IGlzUGFzc3dvcmRWYWxpZCA9IGF3YWl0IHRoaXMuaXNQYXNzd29yZFZhbGlkKHBhc3N3b3JkLCBoYXNoZWRQYXNzd29yZCk7XG4gICAgICBpZiAoIWlzUGFzc3dvcmRWYWxpZCkge1xuICAgICAgICAgdGhyb3cgbmV3IEVycm9yKHQoJ2F1dGguZXJyb3JzLmludmFsaWRDcmVkZW50aWFscycpKVxuICAgICAgfVxuICAgfVxuXG59IiwKICAgICJpbXBvcnQgeyBJbmplY3RhYmxlLCBzZXRMYW5ndWFnZSwgZ2V0Q3VycmVudExhbmd1YWdlLCBUcmFuc2FjdGlvbmFsIH0gZnJvbSAnbmFqbS1hcGknO1xuaW1wb3J0IHsgVXNlclJlcG9zaXRvcnkgfSBmcm9tICcuL1VzZXJSZXBvc2l0b3J5JztcbmltcG9ydCB7IFVzZXJWYWxpZGF0b3IgfSBmcm9tICcuL1VzZXJWYWxpZGF0b3InO1xuaW1wb3J0IHsgUm9sZVNlcnZpY2UsIFJvbGVWYWxpZGF0b3IgfSBmcm9tICcuLi9yb2xlcyc7XG5pbXBvcnQgeyBFbmNyeXB0aW9uU2VydmljZSB9IGZyb20gJy4uL2F1dGgnO1xuaW1wb3J0IHsgbmFub2lkIH0gZnJvbSAnbmFub2lkJztcbmltcG9ydCB7IGNsZWFuIH0gZnJvbSAnQC9zaGFyZWQnO1xuXG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBVc2VyU2VydmljZSB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcm9sZVZhbGlkYXRvcjogUm9sZVZhbGlkYXRvcixcbiAgICBwcml2YXRlIHJvbGVTZXJ2aWNlOiBSb2xlU2VydmljZSxcbiAgICBwcml2YXRlIHVzZXJSZXBvc2l0b3J5OiBVc2VyUmVwb3NpdG9yeSxcbiAgICBwcml2YXRlIHVzZXJWYWxpZGF0b3I6IFVzZXJWYWxpZGF0b3IsXG4gICAgcHJpdmF0ZSBlbmNyeXB0aW9uU2VydmljZTogRW5jcnlwdGlvblNlcnZpY2UsXG4gICkgeyB9XG5cbiAgcHJpdmF0ZSBzYW5pdGl6ZVVzZXIodXNlcikge1xuICAgIGlmICghdXNlcikgcmV0dXJuIHVzZXI7XG4gICAgY29uc3QgeyBwYXNzd29yZCwgLi4uc2FuaXRpemVkVXNlciB9ID0gdXNlcjtcbiAgICByZXR1cm4gc2FuaXRpemVkVXNlcjtcbiAgfVxuXG4gIHByaXZhdGUgc2FuaXRpemVVc2Vycyh1c2Vycykge1xuICAgIHJldHVybiB1c2Vycy5tYXAodXNlciA9PiB0aGlzLnNhbml0aXplVXNlcih1c2VyKSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHJlc29sdmVVc2VyUm9sZShyb2xlSWQsIHJvbGVOYW1lKSB7XG5cbiAgICBpZiAocm9sZUlkKSB7XG4gICAgICBhd2FpdCB0aGlzLnJvbGVWYWxpZGF0b3IuY2hlY2tSb2xlRXhpc3RzKHJvbGVJZCk7XG4gICAgICByZXR1cm4gcm9sZUlkO1xuICAgIH1cblxuICAgIGlmIChyb2xlTmFtZSkge1xuICAgICAgY29uc3Qgcm9sZUJ5TmFtZSA9IGF3YWl0IHRoaXMucm9sZVNlcnZpY2UuZ2V0QnlOYW1lKHJvbGVOYW1lKTtcbiAgICAgIGlmIChyb2xlQnlOYW1lKSB7XG4gICAgICAgIHJldHVybiByb2xlQnlOYW1lLmlkO1xuICAgICAgfVxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBSb2xlICcke3JvbGVOYW1lfScgbm90IGZvdW5kYCk7XG4gICAgfVxuXG4gICAgY29uc3QgZGVmYXVsdFJvbGUgPSBhd2FpdCB0aGlzLnJvbGVTZXJ2aWNlLmdldEJ5TmFtZSgnU3R1ZGVudCcpO1xuICAgIHJldHVybiBkZWZhdWx0Um9sZS5pZDtcbiAgfVxuXG4gIGFzeW5jIGdldEFsbCgpIHtcbiAgICBjb25zdCB1c2VycyA9IGF3YWl0IHRoaXMudXNlclJlcG9zaXRvcnkuZ2V0QWxsKCk7XG4gICAgcmV0dXJuIHRoaXMuc2FuaXRpemVVc2Vycyh1c2Vycyk7XG4gIH1cblxuICBhc3luYyBnZXRCeUlkKGlkKSB7XG4gICAgYXdhaXQgdGhpcy51c2VyVmFsaWRhdG9yLmNoZWNrVXNlckV4aXN0cyhpZCk7XG4gICAgY29uc3QgdXNlciA9IGF3YWl0IHRoaXMudXNlclJlcG9zaXRvcnkuZ2V0QnlJZChpZCk7XG4gICAgcmV0dXJuIHRoaXMuc2FuaXRpemVVc2VyKHVzZXIpO1xuICB9XG5cbiAgYXN5bmMgZ2V0QnlFbWFpbChlbWFpbCkge1xuICAgIGNvbnN0IHVzZXIgPSBhd2FpdCB0aGlzLnVzZXJWYWxpZGF0b3IuY2hlY2tVc2VyRXhpc3RzQnlFbWFpbChlbWFpbCk7XG4gICAgcmV0dXJuIHRoaXMuc2FuaXRpemVVc2VyKHVzZXIpO1xuICB9XG5cbiAgQFRyYW5zYWN0aW9uYWwoKVxuICBhc3luYyBjcmVhdGUoZGF0YSkge1xuICAgIGNvbnN0IHsgaWQsIGVtYWlsLCBpbWFnZSwgZW1haWxWZXJpZmllZCwgcGFzc3dvcmQsIHJvbGVJZCwgcm9sZSB9ID0gZGF0YTtcbiAgICBsZXQgdXNlcklkID0gaWQgfHwgbmFub2lkKDUpO1xuICAgIGxldCBwYXNzID0gcGFzc3dvcmQgfHwgJzEyMzQ1Njc4JztcblxuICAgIGF3YWl0IHRoaXMudXNlclZhbGlkYXRvci5jaGVja0VtYWlsVW5pcXVlKGRhdGEuZW1haWwpO1xuICAgIGF3YWl0IHRoaXMudXNlclZhbGlkYXRvci5jaGVja1VzZXJJZElzVW5pcXVlKGlkKTtcblxuICAgIGNvbnN0IGhhc2hlZFBhc3N3b3JkID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5oYXNoUGFzc3dvcmQocGFzcyk7XG4gICAgY29uc3QgcmVzb2x2ZWRSb2xlSWQgPSBhd2FpdCB0aGlzLnJlc29sdmVVc2VyUm9sZShyb2xlSWQsIHJvbGUpO1xuXG4gICAgY29uc3QgdXNlckRldGFpbHMgPSB7XG4gICAgICBpZDogdXNlcklkLFxuICAgICAgZW1haWwsXG4gICAgICBpbWFnZSxcbiAgICAgIHBhc3N3b3JkOiBoYXNoZWRQYXNzd29yZCxcbiAgICAgIHJvbGVJZDogcmVzb2x2ZWRSb2xlSWQsXG4gICAgICBlbWFpbFZlcmlmaWVkLFxuICAgICAgc3RhdHVzOiAncGVuZGluZydcbiAgICB9O1xuXG4gICAgYXdhaXQgdGhpcy51c2VyVmFsaWRhdG9yLnZhbGlkYXRlQ3JlYXRlVXNlcih1c2VyRGV0YWlscyk7XG4gICAgY29uc3QgbmV3VXNlciA9IGF3YWl0IHRoaXMudXNlclJlcG9zaXRvcnkuY3JlYXRlKHVzZXJEZXRhaWxzKTtcblxuICAgIHJldHVybiB0aGlzLnNhbml0aXplVXNlcihuZXdVc2VyKTtcblxuXG4gIH1cblxuICBhc3luYyB1cGRhdGUoaWQsIGRhdGEpIHtcblxuICAgIGNvbnN0IHsgcGFzc3dvcmQsIGltYWdlIH0gPSBkYXRhO1xuXG4gICAgYXdhaXQgdGhpcy51c2VyVmFsaWRhdG9yLmNoZWNrVXNlckV4aXN0cyhpZCk7XG4gICAgYXdhaXQgdGhpcy51c2VyVmFsaWRhdG9yLmNoZWNrRW1haWxVbmlxdWUoZGF0YS5lbWFpbCwgaWQpO1xuXG4gICAgY29uc3QgY3VycmVudFVzZXIgPSBhd2FpdCB0aGlzLnVzZXJSZXBvc2l0b3J5LmdldEJ5SWQoaWQpO1xuICAgIGNvbnN0IGhhc2hlZFBhc3N3b3JkID0gYXdhaXQgdGhpcy5lbmNyeXB0aW9uU2VydmljZS5oYXNoUGFzc3dvcmQocGFzc3dvcmQpO1xuXG4gICAgY29uc3QgdXBkYXRlRGF0YSA9IHtcbiAgICAgIC4uLmRhdGEsXG4gICAgICBpbWFnZSxcbiAgICAgIC4uLihoYXNoZWRQYXNzd29yZCAmJiB7IHBhc3N3b3JkOiBoYXNoZWRQYXNzd29yZCB9KVxuICAgIH07XG5cbiAgICBjb25zdCBjbGVhbmVkVXBkYXRlRGF0YSA9IGNsZWFuKHVwZGF0ZURhdGEpO1xuICAgIGNvbnN0IHVwZGF0ZWRVc2VyID0gYXdhaXQgdGhpcy51c2VyUmVwb3NpdG9yeS51cGRhdGUoaWQsIGNsZWFuZWRVcGRhdGVEYXRhKTtcbiAgICByZXR1cm4gdGhpcy5zYW5pdGl6ZVVzZXIodXBkYXRlZFVzZXIpO1xuICB9XG5cbiAgYXN5bmMgZGVsZXRlKGlkKSB7XG4gICAgYXdhaXQgdGhpcy51c2VyVmFsaWRhdG9yLmNoZWNrVXNlckV4aXN0cyhpZCk7XG4gICAgY29uc3QgdXNlciA9IGF3YWl0IHRoaXMudXNlclJlcG9zaXRvcnkuZGVsZXRlKGlkKTtcbiAgICByZXR1cm4gdGhpcy5zYW5pdGl6ZVVzZXIodXNlcik7XG4gIH1cblxuICBhc3luYyBkZWxldGVBbGwoKSB7XG4gICAgY29uc3QgZGVsZXRlZFVzZXJzID0gYXdhaXQgdGhpcy51c2VyUmVwb3NpdG9yeS5kZWxldGVBbGwoKTtcbiAgICByZXR1cm4gdGhpcy5zYW5pdGl6ZVVzZXJzKGRlbGV0ZWRVc2Vycyk7XG4gIH1cblxuICBhc3luYyBnZXRSb2xlTmFtZShpZCkge1xuICAgIGF3YWl0IHRoaXMudXNlclZhbGlkYXRvci5jaGVja1VzZXJFeGlzdHMoaWQpO1xuICAgIHJldHVybiBhd2FpdCB0aGlzLnVzZXJSZXBvc2l0b3J5LmdldFJvbGVOYW1lQnlJZChpZCk7XG4gIH1cblxuICBhc3luYyBnZXRQYXNzd29yZChlbWFpbCkge1xuICAgIGF3YWl0IHRoaXMudXNlclZhbGlkYXRvci5jaGVja1VzZXJFeGlzdHNCeUVtYWlsKGVtYWlsKTtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy51c2VyUmVwb3NpdG9yeS5nZXRVc2VyUGFzc3dvcmQoZW1haWwpO1xuICB9XG5cbiAgYXN5bmMgYXNzaWduUm9sZShpZCwgcm9sZUlkLCByb2xlTmFtZT8pIHtcbiAgICBhd2FpdCB0aGlzLnVzZXJWYWxpZGF0b3IuY2hlY2tVc2VyRXhpc3RzKGlkKTtcbiAgICBjb25zdCByZXNvbHZlZFJvbGVJZCA9IGF3YWl0IHRoaXMucmVzb2x2ZVVzZXJSb2xlKHJvbGVJZCwgcm9sZU5hbWUpO1xuICAgIGNvbnN0IHVwZGF0ZWRVc2VyID0gYXdhaXQgdGhpcy51c2VyUmVwb3NpdG9yeS51cGRhdGUoaWQsIHsgcm9sZUlkOiByZXNvbHZlZFJvbGVJZCB9KTtcbiAgICByZXR1cm4gdGhpcy5zYW5pdGl6ZVVzZXIodXBkYXRlZFVzZXIpO1xuICB9XG5cbiAgYXN5bmMgcmVtb3ZlUm9sZShpZCkge1xuICAgIGF3YWl0IHRoaXMudXNlclZhbGlkYXRvci5jaGVja1VzZXJFeGlzdHMoaWQpO1xuICAgIGNvbnN0IHVwZGF0ZWRVc2VyID0gYXdhaXQgdGhpcy51c2VyUmVwb3NpdG9yeS51cGRhdGUoaWQsIHsgcm9sZUlkOiBudWxsIH0pO1xuICAgIHJldHVybiB0aGlzLnNhbml0aXplVXNlcih1cGRhdGVkVXNlcik7XG4gIH1cblxuICBhc3luYyBzZWVkQWRtaW5Vc2VyKCkge1xuICAgIGNvbnN0IGVtYWlsID0gJ2FkbWluQGFkbWluLmNvbSc7XG4gICAgY29uc3QgYWRtaW5Sb2xlID0gYXdhaXQgdGhpcy5yb2xlVmFsaWRhdG9yLmNoZWNrQWRtaW5Sb2xlRXhpc3RzKCk7XG5cbiAgICBjb25zdCBleGlzdGluZ1VzZXIgPSBhd2FpdCB0aGlzLnVzZXJSZXBvc2l0b3J5LmdldEJ5RW1haWwoZW1haWwpO1xuXG4gICAgaWYgKGV4aXN0aW5nVXNlcikge1xuICAgICAgYXdhaXQgdGhpcy5kZWxldGUoZXhpc3RpbmdVc2VyLmlkKTtcbiAgICB9XG5cbiAgICBjb25zdCBuZXdBZG1pblVzZXIgPSBhd2FpdCB0aGlzLmNyZWF0ZSh7XG4gICAgICBpZDogJ1VTUjAwJyxcbiAgICAgIG5hbWU6ICdTeXN0ZW0gQWRtaW5pc3RyYXRvcicsXG4gICAgICBlbWFpbCxcbiAgICAgIHBhc3N3b3JkOiAnMTIzNDU2NzgnLFxuICAgICAgaW1hZ2U6bnVsbCxcbiAgICAgIHJvbGVJZDogYWRtaW5Sb2xlLmlkLFxuICAgICAgc3RhdHVzOiAnYWN0aXZlJyxcbiAgICAgIGVtYWlsVmVyaWZpZWQ6IHRydWVcbiAgICB9KTtcblxuICAgIHJldHVybiB0aGlzLnNhbml0aXplVXNlcihuZXdBZG1pblVzZXIpO1xuICB9XG5cbiAgYXN5bmMgdXBkYXRlTGFuZyhsYW5ndWFnZSkge1xuICAgIHNldExhbmd1YWdlKGxhbmd1YWdlKVxuICAgIHJldHVybiBsYW5ndWFnZVxuICB9XG5cbiAgYXN5bmMgZ2V0TGFuZygpIHtcbiAgICByZXR1cm4gZ2V0Q3VycmVudExhbmd1YWdlKCk7XG4gIH1cblxufSIsCiAgICAiXG5cbmltcG9ydCB7IHJvbGVzVGFibGUgfSBmcm9tICdAL2RhdGFiYXNlL3NjaGVtYSc7XG5pbXBvcnQgeyBlcSB9IGZyb20gJ2RyaXp6bGUtb3JtJztcbmltcG9ydCB7IFJlcG9zaXRvcnksIERCIH0gZnJvbSAnbmFqbS1hcGknO1xuXG5AUmVwb3NpdG9yeSgpXG5leHBvcnQgY2xhc3MgUm9sZVJlcG9zaXRvcnkge1xuXG4gIGRlY2xhcmUgZGI6IERCO1xuXG4gIGFzeW5jIGdldEFsbCgpIHtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5kYi5zZWxlY3QoKS5mcm9tKHJvbGVzVGFibGUpO1xuICB9XG5cbiAgYXN5bmMgZ2V0QnlJZChpZDpzdHJpbmcpIHtcbiAgICBjb25zdCBbZXhpc3RpbmdSb2xlXSA9IGF3YWl0IHRoaXMuZGIuc2VsZWN0KCkuZnJvbShyb2xlc1RhYmxlKS53aGVyZShlcShyb2xlc1RhYmxlLmlkLCBpZCkpO1xuICAgIHJldHVybiBleGlzdGluZ1JvbGU7XG4gIH1cblxuICBhc3luYyBnZXRCeU5hbWUobmFtZTpzdHJpbmcpIHtcbiAgICBjb25zdCBbZXhpc3RpbmdSb2xlXSA9IGF3YWl0IHRoaXMuZGIuc2VsZWN0KCkuZnJvbShyb2xlc1RhYmxlKS53aGVyZShlcShyb2xlc1RhYmxlLm5hbWUsIG5hbWUpKTtcbiAgICByZXR1cm4gZXhpc3RpbmdSb2xlXG4gIH1cblxuICBhc3luYyBjcmVhdGUoZGF0YSkge1xuICAgIGNvbnN0IFtuZXdSb2xlXSA9IGF3YWl0IHRoaXMuZGIuaW5zZXJ0KHJvbGVzVGFibGUpLnZhbHVlcyhkYXRhKS5yZXR1cm5pbmcoKTtcbiAgICByZXR1cm4gbmV3Um9sZVxuICB9XG5cbiAgYXN5bmMgdXBkYXRlKGlkLCBkYXRhKSB7XG4gICAgY29uc3QgW3VwZGF0ZWRSb2xlXSA9IGF3YWl0IHRoaXMuZGIudXBkYXRlKHJvbGVzVGFibGUpXG4gICAgICAuc2V0KGRhdGEpXG4gICAgICAud2hlcmUoZXEocm9sZXNUYWJsZS5pZCwgaWQpKVxuICAgICAgLnJldHVybmluZygpO1xuXG4gICAgICByZXR1cm4gdXBkYXRlZFJvbGVcbiAgfVxuXG4gIGFzeW5jIGRlbGV0ZShpZCkge1xuICAgIGNvbnN0IFtkZWxldGVkUm9sZV0gPSBhd2FpdCB0aGlzLmRiLmRlbGV0ZShyb2xlc1RhYmxlKVxuICAgICAgLndoZXJlKGVxKHJvbGVzVGFibGUuaWQsIGlkKSlcbiAgICAgIC5yZXR1cm5pbmcoKTtcbiAgICAgIHJldHVybiBkZWxldGVkUm9sZVxuICB9XG59XG4iLAogICAgImltcG9ydCB7IEluamVjdGFibGUsIHQgfSBmcm9tICduYWptLWFwaSc7XG5pbXBvcnQgeyBSb2xlUmVwb3NpdG9yeSB9IGZyb20gJy4vUm9sZVJlcG9zaXRvcnknO1xuaW1wb3J0IHsgcGFyc2VTY2hlbWEgfSBmcm9tICdAL3NoYXJlZCc7XG5pbXBvcnQgeyByb2xlU2NoZW1hIH0gZnJvbSAnQC9saWIvdmFsaWRhdGlvbnMnO1xuXG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBSb2xlVmFsaWRhdG9yIHtcbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJpdmF0ZSByb2xlUmVwb3NpdG9yeTogUm9sZVJlcG9zaXRvcnksXG4gICAgKSB7IH1cblxuICAgIGFzeW5jIHZhbGlkYXRlQ3JlYXRlUm9sZShkYXRhKSB7XG4gICAgICAgIHJldHVybiBwYXJzZVNjaGVtYShyb2xlU2NoZW1hLCBkYXRhKTtcbiAgICB9XG5cbiAgICBhc3luYyBpc1JvbGVOYW1lRXhpc3RzKHJvbGVOYW1lOiBzdHJpbmcpIHtcbiAgICAgICAgY29uc3QgZXhpc3RpbmdSb2xlID0gYXdhaXQgdGhpcy5yb2xlUmVwb3NpdG9yeS5nZXRCeU5hbWUocm9sZU5hbWUpO1xuICAgICAgICByZXR1cm4gISFleGlzdGluZ1JvbGU7XG4gICAgfVxuXG4gICAgYXN5bmMgaXNSb2xlSWRFeGlzdHMoaWQ6IHN0cmluZykge1xuICAgICAgICBjb25zdCBleGlzdGluZ1JvbGUgPSBhd2FpdCB0aGlzLnJvbGVSZXBvc2l0b3J5LmdldEJ5SWQoaWQpO1xuICAgICAgICByZXR1cm4gISFleGlzdGluZ1JvbGU7XG4gICAgfVxuXG4gICAgYXN5bmMgY2hlY2tOYW1lVW5pcXVlKHJvbGVOYW1lOiBzdHJpbmcsIGV4Y2x1ZGVJZCA9IG51bGwpIHtcbiAgICAgICAgaWYgKCFyb2xlTmFtZSkgcmV0dXJuO1xuICAgICAgICBjb25zdCBleGlzdGluZ1JvbGUgPSBhd2FpdCB0aGlzLnJvbGVSZXBvc2l0b3J5LmdldEJ5TmFtZShyb2xlTmFtZSk7XG5cbiAgICAgICAgaWYgKGV4aXN0aW5nUm9sZSAmJiBleGlzdGluZ1JvbGUuaWQgIT09IGV4Y2x1ZGVJZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKHQoJ3JvbGVzLmVycm9ycy5leGlzdHMnKSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhc3luYyBjaGVja1JvbGVFeGlzdHMoaWQ6IHN0cmluZykge1xuICAgICAgICBjb25zdCByb2xlSWRFeGlzdHMgPSBhd2FpdCB0aGlzLmlzUm9sZUlkRXhpc3RzKGlkKTtcbiAgICAgICAgaWYgKCFyb2xlSWRFeGlzdHMpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcih0KCdyb2xlcy5lcnJvcnMubm90Rm91bmQnKSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhc3luYyBjaGVja1JvbGVFeGlzdHNCeU5hbWUocm9sZU5hbWU6IHN0cmluZykge1xuICAgICAgICBjb25zdCByb2xlTmFtZUV4aXN0cyA9IGF3YWl0IHRoaXMuaXNSb2xlTmFtZUV4aXN0cyhyb2xlTmFtZSk7XG4gICAgICAgIGlmICghcm9sZU5hbWVFeGlzdHMpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcih0KCdyb2xlcy5lcnJvcnMubm90Rm91bmQnKSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhc3luYyBjaGVja0FkbWluUm9sZUV4aXN0cygpIHtcbiAgICAgICAgY29uc3QgYWRtaW5Sb2xlID0gYXdhaXQgdGhpcy5yb2xlUmVwb3NpdG9yeS5nZXRCeU5hbWUoJ2FkbWluJyk7XG4gICAgICAgIGlmICghYWRtaW5Sb2xlKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IodCgndXNlcnMuZXJyb3JzLmFkbWluUm9sZU5vdEZvdW5kJykpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhZG1pblJvbGU7XG4gICAgfVxufSIsCiAgICAiaW1wb3J0IHsgSW5qZWN0YWJsZSwgSGVhZGVycywgY3JlYXRlR3VhcmQsIEd1YXJkUGFyYW1zLCBDdHggfSBmcm9tIFwibmFqbS1hcGlcIjtcbmltcG9ydCB7IFRva2VuU2VydmljZSB9IGZyb20gXCIuLi90b2tlbnNcIjtcblxuLy8gPT09PT09PT09PT09IENPTlNUQU5UUyA9PT09PT09PT09PT0gLy9cblxuZXhwb3J0IGNvbnN0IFJPTEVTID0ge1xuICBBRE1JTjogJ2FkbWluJyxcbiAgUFJJTkNJUEFMOiAncHJpbmNpcGFsJyxcbiAgQUNDT1VOVElORzogJ2FjY291bnRpbmcnLFxuICBTRUNSRVRBUlk6ICdzZWNyZXRhcnknLFxuICBURUFDSEVSOiAndGVhY2hlcicsXG4gIFNUVURFTlQ6ICdzdHVkZW50JyxcbiAgUEFSRU5UOiAncGFyZW50Jyxcbn0gYXMgY29uc3Q7XG5cbmV4cG9ydCBjb25zdCBST0xFX0dST1VQUyA9IHtcbiAgQURNSU5JU1RSQVRPUlM6IFtST0xFUy5BRE1JTiwgUk9MRVMuUFJJTkNJUEFMXSxcbiAgRklOQU5DSUFMOiBbUk9MRVMuQURNSU4sIFJPTEVTLkFDQ09VTlRJTkddLFxuICBTVEFGRjogW1JPTEVTLkFETUlOLCBST0xFUy5QUklOQ0lQQUwsIFJPTEVTLkFDQ09VTlRJTkcsIFJPTEVTLlNFQ1JFVEFSWSwgUk9MRVMuVEVBQ0hFUl0sXG4gIEVORF9VU0VSUzogW1JPTEVTLlNUVURFTlQsIFJPTEVTLlBBUkVOVF0sXG4gIEFMTDogW1JPTEVTLkFETUlOLCBST0xFUy5QUklOQ0lQQUwsIFJPTEVTLkFDQ09VTlRJTkcsIFJPTEVTLlNFQ1JFVEFSWSwgUk9MRVMuVEVBQ0hFUiwgUk9MRVMuU1RVREVOVCwgUk9MRVMuUEFSRU5UXSxcbn0gYXMgY29uc3Q7XG5cbmV4cG9ydCB0eXBlIFJvbGUgPSB0eXBlb2YgUk9MRVNba2V5b2YgdHlwZW9mIFJPTEVTXTtcbmV4cG9ydCB0eXBlIFJvbGVHcm91cCA9IHR5cGVvZiBST0xFX0dST1VQU1trZXlvZiB0eXBlb2YgUk9MRV9HUk9VUFNdO1xuXG4vLyA9PT09PT09PT09PT0gUk9MRSBDSEVDS0VSIChJbmplY3RhYmxlIGZvciBTZXJ2aWNlcykgPT09PT09PT09PT09IC8vXG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBSb2xlQ2hlY2tlciB7XG4gIGlzSW5Hcm91cCh1c2VyUm9sZSwgZ3JvdXA6IHJlYWRvbmx5IHN0cmluZ1tdKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGdyb3VwLmluY2x1ZGVzKHVzZXJSb2xlPy50b0xvd2VyQ2FzZSgpKTtcbiAgfVxuXG4gIGlzQWRtaW5pc3RyYXRvcih1c2VyUm9sZSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmlzSW5Hcm91cCh1c2VyUm9sZSwgUk9MRV9HUk9VUFMuQURNSU5JU1RSQVRPUlMpO1xuICB9XG5cbiAgaXNTdGFmZih1c2VyUm9sZSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmlzSW5Hcm91cCh1c2VyUm9sZSwgUk9MRV9HUk9VUFMuU1RBRkYpO1xuICB9XG5cbiAgaGFzQW55Um9sZSh1c2VyUm9sZSwgcm9sZXM6IHJlYWRvbmx5IHN0cmluZ1tdKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHJvbGVzLmluY2x1ZGVzKHVzZXJSb2xlPy50b0xvd2VyQ2FzZSgpKTtcbiAgfVxuXG4gIGhhc0V4YWN0Um9sZSh1c2VyUm9sZSwgcmVxdWlyZWRSb2xlKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHVzZXJSb2xlPy50b0xvd2VyQ2FzZSgpID09PSByZXF1aXJlZFJvbGU/LnRvTG93ZXJDYXNlKCk7XG4gIH1cblxufVxuXG4vLyA9PT09PT09PT09PT0gUk9MRSBHVUFSRFMgKEluamVjdGFibGUgZm9yIERlY29yYXRvcnMpID09PT09PT09PT09PSAvL1xuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgUm9sZUd1YXJkcyB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcm9sZUNoZWNrZXI6IFJvbGVDaGVja2VyLFxuICAgIHByaXZhdGUgdG9rZW5TZXJ2aWNlOiBUb2tlblNlcnZpY2VcbiAgKSB7IH1cblxuICBhc3luYyBpc0F1dGgoQEhlYWRlcnMoJ2F1dGhvcml6YXRpb24nKSBhdXRoLCBAQ3R4KCkgY3R4KSB7XG4gICAgY29uc3QgdXNlciA9IGF3YWl0IHRoaXMudG9rZW5TZXJ2aWNlLnN0b3JlVXNlckluQ2FjaGUoYXV0aCwgY3R4KTtcbiAgICByZXR1cm4gISF1c2VyO1xuICB9XG5cbiAgYXN5bmMgaGFzUm9sZXMoQEhlYWRlcnMoJ2F1dGhvcml6YXRpb24nKSBhdXRoLCBAQ3R4KCkgY3R4LCBAR3VhcmRQYXJhbXMoKSByb2xlcykge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCB1c2VyID0gYXdhaXQgdGhpcy50b2tlblNlcnZpY2Uuc3RvcmVVc2VySW5DYWNoZShhdXRoLCBjdHgpO1xuICAgICAgaWYgKCF1c2VyPy5yb2xlKSByZXR1cm4gZmFsc2U7XG4gICAgICBjb25zdCByb2xlQXJyYXkgPSBBcnJheS5pc0FycmF5KHJvbGVzKSA/IHJvbGVzIDogW3JvbGVzXTtcbiAgICAgIHJldHVybiB0aGlzLnJvbGVDaGVja2VyLmhhc0FueVJvbGUodXNlci5yb2xlLCByb2xlQXJyYXkpO1xuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxufVxuXG4vLyA9PT09PT09PT09PT0gRVhQT1JURUQgR1VBUkQgREVDT1JBVE9SUyA9PT09PT09PT09PT0gLy9cblxuZXhwb3J0IGNvbnN0IGlzQWRtaW4gPSAoKSA9PiBSb2xlKCdhZG1pbicpO1xuZXhwb3J0IGNvbnN0IGlzUHJpbmNpcGFsID0gKCkgPT4gUm9sZSgncHJpbmNpcGFsJyk7XG5leHBvcnQgY29uc3QgaXNBY2NvdW50aW5nID0gKCkgPT4gUm9sZSgnYWNjb3VudGluZycpO1xuZXhwb3J0IGNvbnN0IGlzU2VjcmV0YXJ5ID0gKCkgPT4gUm9sZSgnc2VjcmV0YXJ5Jyk7XG5leHBvcnQgY29uc3QgaXNUZWFjaGVyID0gKCkgPT4gUm9sZSgndGVhY2hlcicpO1xuZXhwb3J0IGNvbnN0IGlzUGFyZW50ID0gKCkgPT4gUm9sZSgncGFyZW50Jyk7XG5leHBvcnQgY29uc3QgaXNTdHVkZW50ID0gKCkgPT4gUm9sZSgnc3R1ZGVudCcpO1xuZXhwb3J0IGNvbnN0IGlzQWRtaW5pc3RyYXRvciA9ICgpID0+IFJvbGUoJ2FkbWluJywgJ3ByaW5jaXBhbCcpO1xuZXhwb3J0IGNvbnN0IGlzRmluYW5jaWFsID0gKCkgPT4gUm9sZSgnYWRtaW4nLCAnYWNjb3VudGluZycpO1xuZXhwb3J0IGNvbnN0IGlzU3RhZmYgPSAoKSA9PiBSb2xlKCdhZG1pbicsICdwcmluY2lwYWwnLCAnYWNjb3VudGluZycsICdzZWNyZXRhcnknLCAndGVhY2hlcicpO1xuZXhwb3J0IGNvbnN0IGlzQXV0aCA9IGNyZWF0ZUd1YXJkKFJvbGVHdWFyZHMsICdpc0F1dGgnKTtcblxuZXhwb3J0IGNvbnN0IFJvbGUgPSAoLi4ucm9sZXMpID0+IGNyZWF0ZUd1YXJkKFJvbGVHdWFyZHMsICdoYXNSb2xlcycpKC4uLnJvbGVzKTtcbiIsCiAgICAiXG5pbXBvcnQgeyB0b2tlbnNUYWJsZSwgdXNlcnNUYWJsZSwgcm9sZXNUYWJsZSwgcGVybWlzc2lvbnNUYWJsZSwgcm9sZVBlcm1pc3Npb25zVGFibGUgfSBmcm9tICdAL2RhdGFiYXNlL3NjaGVtYSc7XG5pbXBvcnQgeyBlcSB9IGZyb20gJ2RyaXp6bGUtb3JtJztcbmltcG9ydCB7IFJlcG9zaXRvcnksIERCIH0gZnJvbSAnbmFqbS1hcGknO1xuXG5AUmVwb3NpdG9yeSgpXG5leHBvcnQgY2xhc3MgVG9rZW5SZXBvc2l0b3J5IHtcbiAgZGVjbGFyZSBkYjogREI7XG5cbiAgYXN5bmMgc3RvcmVSZWZyZXNoVG9rZW4odG9rZW5EYXRhOiB7IHVzZXJJZDogc3RyaW5nOyB0b2tlbjogc3RyaW5nOyBleHBpcmVzQXQ6IHN0cmluZyB9KSB7XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuZGJcbiAgICAgIC5pbnNlcnQodG9rZW5zVGFibGUpXG4gICAgICAudmFsdWVzKHRva2VuRGF0YSlcbiAgICAgIC5vbkNvbmZsaWN0RG9VcGRhdGUoe1xuICAgICAgICB0YXJnZXQ6IHRva2Vuc1RhYmxlLnVzZXJJZCxcbiAgICAgICAgc2V0OiB7XG4gICAgICAgICAgdG9rZW46IHRva2VuRGF0YS50b2tlbixcbiAgICAgICAgICBleHBpcmVzQXQ6IHRva2VuRGF0YS5leHBpcmVzQXQsXG4gICAgICAgIH1cbiAgICAgIH0pLnJldHVybmluZygpO1xuICB9XG5cbiAgYXN5bmMgZ2V0UmVmcmVzaFRva2VuKHVzZXJJZDogc3RyaW5nKSB7XG4gICAgY29uc3QgW3Rva2VuXSA9IGF3YWl0IHRoaXMuZGIuc2VsZWN0KCkuZnJvbSh0b2tlbnNUYWJsZSkud2hlcmUoZXEodG9rZW5zVGFibGUudXNlcklkLCB1c2VySWQpKTtcbiAgICByZXR1cm4gdG9rZW4/LnRva2VuO1xuICB9XG5cbiAgYXN5bmMgcmV2b2tlVG9rZW4odXNlcklkOiBzdHJpbmcpIHtcbiAgICBjb25zdCBbZGVsZXRlZFRva2VuXSA9IGF3YWl0IHRoaXMuZGIuZGVsZXRlKHRva2Vuc1RhYmxlKS53aGVyZShlcSh0b2tlbnNUYWJsZS51c2VySWQsIHVzZXJJZCkpLnJldHVybmluZygpO1xuICAgIHJldHVybiBkZWxldGVkVG9rZW47XG4gIH1cblxuICBhc3luYyBpc1VzZXJFeGlzdHModXNlcklkOiBzdHJpbmcpIHtcbiAgICBjb25zdCBbdXNlcl0gPSBhd2FpdCB0aGlzLmRiXG4gICAgICAuc2VsZWN0KHsgaWQ6IHVzZXJzVGFibGUuaWQgfSlcbiAgICAgIC5mcm9tKHVzZXJzVGFibGUpXG4gICAgICAud2hlcmUoZXEodXNlcnNUYWJsZS5pZCwgdXNlcklkKSlcbiAgICAgIC5saW1pdCgxKTtcbiAgICByZXR1cm4gISF1c2VyO1xuICB9XG5cbiAgYXN5bmMgZ2V0Um9sZU5hbWVCeUlkKHVzZXJJZDogc3RyaW5nKSB7XG4gICAgY29uc3QgW3JvbGVdID0gYXdhaXQgdGhpcy5kYi5zZWxlY3Qoe1xuICAgICAgcm9sZU5hbWU6IHJvbGVzVGFibGUubmFtZVxuICAgIH0pXG4gICAgICAuZnJvbSh1c2Vyc1RhYmxlKVxuICAgICAgLmxlZnRKb2luKHJvbGVzVGFibGUsIGVxKHVzZXJzVGFibGUucm9sZUlkLCByb2xlc1RhYmxlLmlkKSlcbiAgICAgIC53aGVyZShlcSh1c2Vyc1RhYmxlLmlkLCB1c2VySWQpKVxuICAgICAgLmxpbWl0KDEpO1xuXG4gICAgcmV0dXJuIHJvbGU/LnJvbGVOYW1lO1xuICB9XG5cbiAgYXN5bmMgZ2V0VXNlclBlcm1pc3Npb25zKHVzZXJJZDogc3RyaW5nKSB7XG4gICAgY29uc3QgW3VzZXJdID0gYXdhaXQgdGhpcy5kYlxuICAgICAgLnNlbGVjdCh7IHJvbGVJZDogdXNlcnNUYWJsZS5yb2xlSWQgfSlcbiAgICAgIC5mcm9tKHVzZXJzVGFibGUpXG4gICAgICAud2hlcmUoZXEodXNlcnNUYWJsZS5pZCwgdXNlcklkKSlcbiAgICAgIC5saW1pdCgxKTtcblxuICAgIGlmICghdXNlciB8fCAhdXNlci5yb2xlSWQpIHJldHVybiBbXTtcblxuICAgIGNvbnN0IHVzZXJQZXJtaXNzaW9ucyA9IGF3YWl0IHRoaXMuZGJcbiAgICAgIC5zZWxlY3Qoe1xuICAgICAgICBuYW1lOiBwZXJtaXNzaW9uc1RhYmxlLm5hbWUsXG4gICAgICB9KVxuICAgICAgLmZyb20ocm9sZVBlcm1pc3Npb25zVGFibGUpXG4gICAgICAubGVmdEpvaW4ocGVybWlzc2lvbnNUYWJsZSwgZXEocm9sZVBlcm1pc3Npb25zVGFibGUucGVybWlzc2lvbklkLCBwZXJtaXNzaW9uc1RhYmxlLmlkKSlcbiAgICAgIC53aGVyZShlcShyb2xlUGVybWlzc2lvbnNUYWJsZS5yb2xlSWQsIHVzZXIucm9sZUlkKSk7XG5cbiAgICByZXR1cm4gdXNlclBlcm1pc3Npb25zLm1hcChwID0+IHAubmFtZSkuZmlsdGVyKG5hbWUgPT4gbmFtZSk7XG4gIH1cblxuICBhc3luYyBnZXRVc2VyKHVzZXJJZDogc3RyaW5nKSB7XG4gICAgY29uc3QgW3VzZXJdID0gYXdhaXQgdGhpcy5kYlxuICAgICAgLnNlbGVjdCh7XG4gICAgICAgIGlkOiB1c2Vyc1RhYmxlLmlkLFxuICAgICAgICBlbWFpbDogdXNlcnNUYWJsZS5lbWFpbCxcbiAgICAgICAgc3RhdHVzOiB1c2Vyc1RhYmxlLnN0YXR1cyxcbiAgICAgICAgcm9sZUlkOiB1c2Vyc1RhYmxlLnJvbGVJZCxcbiAgICAgICAgcm9sZU5hbWU6IHJvbGVzVGFibGUubmFtZSxcbiAgICAgICAgY3JlYXRlZEF0OiB1c2Vyc1RhYmxlLmNyZWF0ZWRBdCxcbiAgICAgICAgdXBkYXRlZEF0OiB1c2Vyc1RhYmxlLnVwZGF0ZWRBdCxcbiAgICAgIH0pXG4gICAgICAuZnJvbSh1c2Vyc1RhYmxlKVxuICAgICAgLmxlZnRKb2luKHJvbGVzVGFibGUsIGVxKHVzZXJzVGFibGUucm9sZUlkLCByb2xlc1RhYmxlLmlkKSlcbiAgICAgIC53aGVyZShlcSh1c2Vyc1RhYmxlLmlkLCB1c2VySWQpKVxuICAgICAgLmxpbWl0KDEpO1xuXG4gICAgcmV0dXJuIHVzZXIgPyB7IC4uLnVzZXIsIHJvbGU6IHVzZXIucm9sZU5hbWUgfSA6IG51bGw7XG4gIH1cbn0iLAogICAgImltcG9ydCB7IHQgfSBmcm9tICduYWptLWFwaSc7XG5pbXBvcnQgeyBnZXRDb29raWUsIEluamVjdGFibGUsIEN0eCwgSGVhZGVycyB9IGZyb20gJ25ham0tYXBpJztcbmltcG9ydCBqd3QgZnJvbSAnanNvbndlYnRva2VuJ1xuaW1wb3J0IHsgand0RGVjb2RlIH0gZnJvbSAnand0LWRlY29kZSc7XG5pbXBvcnQgeyBUb2tlblJlcG9zaXRvcnkgfSBmcm9tICcuL1Rva2VuUmVwb3NpdG9yeSc7XG5pbXBvcnQgdGltZXN0cmluZyBmcm9tICd0aW1lc3RyaW5nJztcblxuaW50ZXJmYWNlIEp3dFBheWxvYWQge1xuICB1c2VySWQ6IHN0cmluZztcbiAgZXhwPzogbnVtYmVyO1xuICBpYXQ/OiBudW1iZXI7XG59XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBUb2tlblNlcnZpY2Uge1xuXG4gIHByaXZhdGUgYWNjZXNzU2VjcmV0S2V5ID0gcHJvY2Vzcy5lbnYuSldUX0FDQ0VTU19TRUNSRVQ7XG4gIHByaXZhdGUgYWNjZXNzRXhwaXJlc0luID0gcHJvY2Vzcy5lbnYuQUNDRVNTX0VYUElSRVNfSU47XG4gIHByaXZhdGUgcmVmcmVzaFNlY3JldEtleSA9IHByb2Nlc3MuZW52LkpXVF9SRUZSRVNIX1NFQ1JFVDtcbiAgcHJpdmF0ZSByZWZyZXNoRXhwaXJlc0luID0gcHJvY2Vzcy5lbnYuUkVGUkVTSF9FWFBJUkVTX0lOO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgdG9rZW5SZXBvc2l0b3J5OiBUb2tlblJlcG9zaXRvcnlcbiAgKSB7IH1cblxuICAvLz09PT0gVmFsaWRhdGUgdG9rZW5zXG5cbiAgZXh0cmFjdEFjY2Vzc1Rva2VuKGF1dGhvcml6YXRpb24pIHtcbiAgICBpZiAoYXV0aG9yaXphdGlvbiAmJiBhdXRob3JpemF0aW9uLnN0YXJ0c1dpdGgoJ0JlYXJlcicpKSB7XG4gICAgICByZXR1cm4gYXV0aG9yaXphdGlvbi5zcGxpdCgnICcpWzFdXG4gICAgfVxuICAgIHRocm93IG5ldyBFcnJvcih0KCdhdXRoLmVycm9ycy50b2tlbk1pc3NpbmcnKSlcbiAgfVxuXG4gIHZlcmlmeUFjY2Vzc1Rva2VuKHRva2VuOiBzdHJpbmcpOiBKd3RQYXlsb2FkIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGp3dC52ZXJpZnkodG9rZW4sIHRoaXMuYWNjZXNzU2VjcmV0S2V5KSBhcyBKd3RQYXlsb2FkO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IodCgnYXV0aC5lcnJvcnMudG9rZW5WZXJpZmljYXRpb25GYWlsZWQnKSlcbiAgICB9XG4gIH1cblxuICB2ZXJpZnlSZWZyZXNoVG9rZW4odG9rZW46IHN0cmluZyk6IHN0cmluZyB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGRlY29kZWQgPSBqd3QudmVyaWZ5KHRva2VuLCB0aGlzLnJlZnJlc2hTZWNyZXRLZXkpIGFzIEp3dFBheWxvYWQ7XG4gICAgICByZXR1cm4gZGVjb2RlZC51c2VySWQ7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcih0KCdhdXRoLmVycm9ycy50b2tlblZlcmlmaWNhdGlvbkZhaWxlZCcpKVxuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGdldFVzZXJJZEJ5QWNjZXNzVG9rZW4oaGVhZGVyOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIGNvbnN0IHRva2VuID0gdGhpcy5leHRyYWN0QWNjZXNzVG9rZW4oaGVhZGVyKTtcbiAgICBjb25zdCBkZWNvZGVkVG9rZW4gPSB0aGlzLnZlcmlmeUFjY2Vzc1Rva2VuKHRva2VuKTtcbiAgICBjb25zdCB1c2VySWQgPSBkZWNvZGVkVG9rZW4udXNlcklkO1xuICAgIGNvbnN0IHVzZXJFeGlzdHMgPSBhd2FpdCB0aGlzLnRva2VuUmVwb3NpdG9yeS5pc1VzZXJFeGlzdHModXNlcklkKTtcblxuICAgIGlmICghdXNlckV4aXN0cykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKHQoJ3VzZXJzLmVycm9ycy5ub3RGb3VuZCcpKVxuICAgIH1cblxuICAgIHJldHVybiB1c2VySWQ7XG4gIH1cblxuICAvLz09PSBHZW5lcmF0ZSB0b2tlbnNcblxuICBhc3luYyBzdG9yZVJlZnJlc2hUb2tlbih1c2VySWQsIHJlZnJlc2hUb2tlbikge1xuICAgIGNvbnN0IGV4cGlyZUluU2Vjb25kID0gdGltZXN0cmluZyh0aGlzLnJlZnJlc2hFeHBpcmVzSW4sICdzJyk7XG4gICAgY29uc3QgdG9rZW5EYXRhID0ge1xuICAgICAgdXNlcklkLFxuICAgICAgdG9rZW46IHJlZnJlc2hUb2tlbixcbiAgICAgIGV4cGlyZXNBdDogbmV3IERhdGUoRGF0ZS5ub3coKSArIGV4cGlyZUluU2Vjb25kICogMTAwMCkudG9JU09TdHJpbmcoKVxuICAgIH1cbiAgICBhd2FpdCB0aGlzLnRva2VuUmVwb3NpdG9yeS5zdG9yZVJlZnJlc2hUb2tlbih0b2tlbkRhdGEpO1xuICB9XG5cbiAgZ2V0VG9rZW5FeHBpcmUodG9rZW4pOiBudW1iZXIgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiBqd3REZWNvZGUodG9rZW4pLmV4cFxuICB9XG5cbiAgZ2VuZXJhdGVBY2Nlc3NUb2tlbihkYXRhOiB7IHVzZXJJZDogc3RyaW5nIH0pOiBzdHJpbmcge1xuICAgIGNvbnN0IG9wdGlvbnMgPSB7IGV4cGlyZXNJbjogdGhpcy5hY2Nlc3NFeHBpcmVzSW4gfSBhcyBhbnk7XG4gICAgcmV0dXJuIGp3dC5zaWduKGRhdGEsIHRoaXMuYWNjZXNzU2VjcmV0S2V5LCBvcHRpb25zKTtcbiAgfVxuXG4gIGdlbmVyYXRlUmVmcmVzaFRva2VuKGRhdGE6IHsgdXNlcklkOiBzdHJpbmcgfSk6IHN0cmluZyB7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHsgZXhwaXJlc0luOiB0aGlzLnJlZnJlc2hFeHBpcmVzSW4gfSBhcyBhbnk7XG4gICAgcmV0dXJuIGp3dC5zaWduKGRhdGEsIHRoaXMucmVmcmVzaFNlY3JldEtleSwgb3B0aW9ucyk7XG4gIH1cblxuICBhc3luYyBnZW5lcmF0ZVRva2Vucyh1c2VySWQpIHtcbiAgICBjb25zdCB0b2tlbkRhdGEgPSB7IHVzZXJJZCB9XG4gICAgY29uc3QgYWNjZXNzVG9rZW4gPSBhd2FpdCB0aGlzLmdlbmVyYXRlQWNjZXNzVG9rZW4odG9rZW5EYXRhKTtcbiAgICBjb25zdCByZWZyZXNoVG9rZW4gPSBhd2FpdCB0aGlzLmdlbmVyYXRlUmVmcmVzaFRva2VuKHRva2VuRGF0YSk7XG4gICAgY29uc3QgYWNjZXNzVG9rZW5FeHBpcmVzQXQgPSB0aGlzLmdldFRva2VuRXhwaXJlKGFjY2Vzc1Rva2VuKTtcbiAgICBjb25zdCByZWZyZXNoVG9rZW5FeHBpcmVzQXQgPSB0aGlzLmdldFRva2VuRXhwaXJlKHJlZnJlc2hUb2tlbik7XG4gICAgYXdhaXQgdGhpcy5zdG9yZVJlZnJlc2hUb2tlbih1c2VySWQsIHJlZnJlc2hUb2tlbik7XG5cbiAgICByZXR1cm4ge1xuICAgICAgYWNjZXNzVG9rZW4sXG4gICAgICByZWZyZXNoVG9rZW4sXG4gICAgICBhY2Nlc3NUb2tlbkV4cGlyZXNBdCxcbiAgICAgIHJlZnJlc2hUb2tlbkV4cGlyZXNBdCxcbiAgICB9XG4gIH1cblxuICBhc3luYyByZWZyZXNoVG9rZW5zKCkge1xuICAgIGNvbnN0IG5ld1JlZnJlc2hUb2tlbiA9IGdldENvb2tpZSgncmVmcmVzaFRva2VuJyk7XG4gICAgY29uc3QgdXNlcklkID0gdGhpcy52ZXJpZnlSZWZyZXNoVG9rZW4obmV3UmVmcmVzaFRva2VuKTtcbiAgICBjb25zdCB1c2VyRXhpc3RzID0gYXdhaXQgdGhpcy50b2tlblJlcG9zaXRvcnkuaXNVc2VyRXhpc3RzKHVzZXJJZCk7XG5cbiAgICBpZiAoIXVzZXJFeGlzdHMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcih0KCd1c2Vycy5lcnJvcnMubm90Rm91bmQnKSk7XG4gICAgfVxuXG4gICAgY29uc3Qgc3RvcmVkUmVmcmVzaFRva2VuID0gYXdhaXQgdGhpcy50b2tlblJlcG9zaXRvcnkuZ2V0UmVmcmVzaFRva2VuKHVzZXJJZClcblxuICAgIGlmIChuZXdSZWZyZXNoVG9rZW4gIT0gc3RvcmVkUmVmcmVzaFRva2VuKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IodCgnYXV0aC5lcnJvcnMucmVmcmVzaFRva2VuSW52YWxpZCcpKVxuICAgIH1cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5nZW5lcmF0ZVRva2Vucyh1c2VySWQpXG4gIH1cblxuICBhc3luYyByZXZva2VUb2tlbih1c2VySWQpIHtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy50b2tlblJlcG9zaXRvcnkucmV2b2tlVG9rZW4odXNlcklkKVxuICB9XG5cbiAgYXN5bmMgZ2V0VXNlclBlcm1pc3Npb25zKGF1dGgpIHtcbiAgICBpZiAoIWF1dGgpIHJldHVybjtcbiAgICBjb25zdCB1c2VySWQgPSBhd2FpdCB0aGlzLmdldFVzZXJJZEJ5QWNjZXNzVG9rZW4oYXV0aCk7XG4gICAgY29uc3QgcGVybWlzc2lvbnMgPSBhd2FpdCB0aGlzLnRva2VuUmVwb3NpdG9yeS5nZXRVc2VyUGVybWlzc2lvbnModXNlcklkKTtcbiAgICByZXR1cm4gcGVybWlzc2lvbnM7XG4gIH1cblxuICBhc3luYyBnZXRVc2VyUm9sZShhdXRoKSB7XG4gICAgaWYgKCFhdXRoKSByZXR1cm47XG4gICAgY29uc3QgdXNlcklkID0gYXdhaXQgdGhpcy5nZXRVc2VySWRCeUFjY2Vzc1Rva2VuKGF1dGgpO1xuICAgIGNvbnN0IHJvbGVOYW1lID0gYXdhaXQgdGhpcy50b2tlblJlcG9zaXRvcnkuZ2V0Um9sZU5hbWVCeUlkKHVzZXJJZCk7XG4gICAgcmV0dXJuIHJvbGVOYW1lO1xuICB9XG5cbiAgYXN5bmMgZ2V0VXNlcihhdXRoKSB7XG4gICAgaWYgKCFhdXRoKSByZXR1cm47XG4gICAgY29uc3QgdXNlcklkID0gYXdhaXQgdGhpcy5nZXRVc2VySWRCeUFjY2Vzc1Rva2VuKGF1dGgpO1xuICAgIGNvbnN0IHVzZXIgPSBhd2FpdCB0aGlzLnRva2VuUmVwb3NpdG9yeS5nZXRVc2VyKHVzZXJJZCk7XG4gICAgaWYgKCF1c2VyKSByZXR1cm4gbnVsbDtcbiAgICByZXR1cm4gdXNlcjtcbiAgfVxuXG4gIGFzeW5jIHN0b3JlVXNlckluQ2FjaGUoYXV0aCwgY3R4KSB7XG4gICAgY29uc3QgY2FjaGVkVXNlciA9IGN0eC5nZXQoJ3VzZXInKTtcbiAgICBpZiAoY2FjaGVkVXNlcikgcmV0dXJuIGNhY2hlZFVzZXI7XG4gICAgY29uc3QgdXNlciA9IGF3YWl0IHRoaXMuZ2V0VXNlcihhdXRoKTtcbiAgICBpZiAodXNlcikge1xuICAgICAgY3R4LnNldCgndXNlcicsIHVzZXIpO1xuICAgIH1cbiAgICByZXR1cm4gdXNlcjtcbiAgfVxuXG59IiwKICAgICJpbXBvcnQgeyBDb250cm9sbGVyLCBHZXQsIFBvc3QsIFB1dCwgRGVsZXRlLCBQYXJhbXMsIEJvZHksdCwgVXNlciB9IGZyb20gJ25ham0tYXBpJztcbmltcG9ydCB7IFJvbGVTZXJ2aWNlIH0gZnJvbSAnLi9Sb2xlU2VydmljZSc7XG5pbXBvcnQgeyBpc0FkbWluIH0gZnJvbSAnLi9Sb2xlR3VhcmRzJztcblxuQENvbnRyb2xsZXIoJy9yb2xlcycpXG5leHBvcnQgY2xhc3MgUm9sZUNvbnRyb2xsZXIge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJvbGVTZXJ2aWNlOiBSb2xlU2VydmljZSxcbiAgKSB7IH1cblxuICBAR2V0KClcbiAgQGlzQWRtaW4oKVxuICBhc3luYyBnZXRSb2xlcygpIHtcbiAgICBjb25zdCByb2xlcyA9IGF3YWl0IHRoaXMucm9sZVNlcnZpY2UuZ2V0QWxsKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIGRhdGE6IHJvbGVzLFxuICAgICAgbWVzc2FnZTogdCgncm9sZXMuc3VjY2Vzcy5yZXRyaWV2ZWQnKSxcbiAgICAgIHN0YXR1czogJ3N1Y2Nlc3MnXG4gICAgfTtcbiAgfVxuXG4gIEBHZXQoJy86aWQnKVxuICBAaXNBZG1pbigpXG4gIGFzeW5jIGdldFJvbGUoQFBhcmFtcygnaWQnKSBpZCkge1xuICAgIGNvbnN0IHJvbGUgPSBhd2FpdCB0aGlzLnJvbGVTZXJ2aWNlLmdldEJ5SWQoaWQpO1xuICAgIHJldHVybiB7XG4gICAgICBkYXRhOiByb2xlLFxuICAgICAgbWVzc2FnZTogdCgncm9sZXMuc3VjY2Vzcy5yZXRyaWV2ZWQnKSxcbiAgICAgIHN0YXR1czogJ3N1Y2Nlc3MnXG4gICAgfTtcbiAgfVxuXG4gIEBQb3N0KClcbiAgQGlzQWRtaW4oKVxuICBhc3luYyBjcmVhdGVSb2xlKEBCb2R5KCkgYm9keSkge1xuICAgIGNvbnN0IG5ld1JvbGUgPSBhd2FpdCB0aGlzLnJvbGVTZXJ2aWNlLmNyZWF0ZShib2R5KTtcbiAgICByZXR1cm4ge1xuICAgICAgZGF0YTogbmV3Um9sZSxcbiAgICAgIG1lc3NhZ2U6IHQoJ3JvbGVzLnN1Y2Nlc3MuY3JlYXRlZCcpLFxuICAgICAgc3RhdHVzOiAnc3VjY2VzcydcbiAgICB9O1xuICB9XG5cbiAgQFB1dCgnLzppZCcpXG4gIEBpc0FkbWluKClcbiAgYXN5bmMgdXBkYXRlUm9sZShAUGFyYW1zKCdpZCcpIGlkLCBAQm9keSgpIGJvZHkpIHtcbiAgICBjb25zdCB1cGRhdGVkUm9sZSA9IGF3YWl0IHRoaXMucm9sZVNlcnZpY2UudXBkYXRlKGlkLCBib2R5KTtcbiAgICByZXR1cm4ge1xuICAgICAgZGF0YTogdXBkYXRlZFJvbGUsXG4gICAgICBtZXNzYWdlOiB0KCdyb2xlcy5zdWNjZXNzLnVwZGF0ZWQnKSxcbiAgICAgIHN0YXR1czogJ3N1Y2Nlc3MnXG4gICAgfTtcbiAgfVxuXG4gIEBEZWxldGUoJy86aWQnKVxuICBAaXNBZG1pbigpXG4gIGFzeW5jIGRlbGV0ZVJvbGUoQFBhcmFtcygnaWQnKSBpZCkge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMucm9sZVNlcnZpY2UuZGVsZXRlKGlkKTtcbiAgICByZXR1cm4ge1xuICAgICAgZGF0YTogcmVzdWx0LFxuICAgICAgbWVzc2FnZTogdCgncm9sZXMuc3VjY2Vzcy5kZWxldGVkJyksXG4gICAgICBzdGF0dXM6ICdzdWNjZXNzJ1xuICAgIH07XG4gIH1cbn0iLAogICAgIlxuaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ25ham0tYXBpJztcbmltcG9ydCB7IFJvbGVSZXBvc2l0b3J5IH0gZnJvbSAnLi9Sb2xlUmVwb3NpdG9yeSc7XG5pbXBvcnQgeyBSb2xlVmFsaWRhdG9yIH0gZnJvbSAnLi9Sb2xlVmFsaWRhdG9yJztcblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIFJvbGVTZXJ2aWNlIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByb2xlUmVwb3NpdG9yeTogUm9sZVJlcG9zaXRvcnksXG4gICAgcHJpdmF0ZSByb2xlVmFsaWRhdG9yOiBSb2xlVmFsaWRhdG9yXG4gICkgeyB9XG5cbiAgYXN5bmMgZ2V0QWxsKCkge1xuICAgIHJldHVybiBhd2FpdCB0aGlzLnJvbGVSZXBvc2l0b3J5LmdldEFsbCgpO1xuICB9XG5cbiAgYXN5bmMgZ2V0QnlJZChpZCkge1xuICAgIGF3YWl0IHRoaXMucm9sZVZhbGlkYXRvci5jaGVja1JvbGVFeGlzdHMoaWQpO1xuICAgIHJldHVybiBhd2FpdCB0aGlzLnJvbGVSZXBvc2l0b3J5LmdldEJ5SWQoaWQpO1xuICB9XG5cbiAgYXN5bmMgZ2V0QnlOYW1lKG5hbWUpIHtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yb2xlUmVwb3NpdG9yeS5nZXRCeU5hbWUobmFtZSk7XG4gIH1cblxuICBhc3luYyBjcmVhdGUoZGF0YSkge1xuICAgIGF3YWl0IHRoaXMucm9sZVZhbGlkYXRvci52YWxpZGF0ZUNyZWF0ZVJvbGUoZGF0YSk7XG4gICAgYXdhaXQgdGhpcy5yb2xlVmFsaWRhdG9yLmNoZWNrTmFtZVVuaXF1ZShkYXRhLm5hbWUpO1xuICAgIHJldHVybiBhd2FpdCB0aGlzLnJvbGVSZXBvc2l0b3J5LmNyZWF0ZShkYXRhKTtcbiAgfVxuXG4gIGFzeW5jIHVwZGF0ZShpZCwgZGF0YSkge1xuICAgIGF3YWl0IHRoaXMucm9sZVZhbGlkYXRvci5jaGVja1JvbGVFeGlzdHMoaWQpO1xuICAgIGF3YWl0IHRoaXMucm9sZVZhbGlkYXRvci5jaGVja05hbWVVbmlxdWUoZGF0YS5uYW1lLCBpZCk7XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucm9sZVJlcG9zaXRvcnkudXBkYXRlKGlkLCBkYXRhKTtcbiAgfVxuXG4gIGFzeW5jIGRlbGV0ZShpZCkge1xuICAgIGF3YWl0IHRoaXMucm9sZVZhbGlkYXRvci5jaGVja1JvbGVFeGlzdHMoaWQpO1xuICAgIHJldHVybiBhd2FpdCB0aGlzLnJvbGVSZXBvc2l0b3J5LmRlbGV0ZShpZCk7XG4gIH1cblxuICBhc3luYyBzZWVkRGVmYXVsdFJvbGVzKGRlZmF1bHRSb2xlcykge1xuXG4gICAgY29uc3Qgcm9sZXNUb0NyZWF0ZSA9IFtdO1xuXG4gICAgZm9yIChjb25zdCByb2xlIG9mIGRlZmF1bHRSb2xlcykge1xuICAgICAgY29uc3QgZXhpc3RzID0gYXdhaXQgdGhpcy5yb2xlVmFsaWRhdG9yLmlzUm9sZU5hbWVFeGlzdHMocm9sZS5uYW1lKTtcbiAgICAgIGlmICghZXhpc3RzKSB7XG4gICAgICAgIHJvbGVzVG9DcmVhdGUucHVzaChyb2xlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBjcmVhdGVkUm9sZXMgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIHJvbGVzVG9DcmVhdGUubWFwKHJvbGUgPT4gdGhpcy5yb2xlUmVwb3NpdG9yeS5jcmVhdGUocm9sZSkpXG4gICAgKTtcblxuICAgIHJldHVybiBjcmVhdGVkUm9sZXM7XG4gIH1cblxuICBhc3luYyBnZXRSb2xlSWRCeU5hbWUobmFtZSkge1xuICAgIGNvbnN0IHRlYWNoZXJSb2xlID0gYXdhaXQgdGhpcy5nZXRCeU5hbWUobmFtZSk7XG4gICAgcmV0dXJuIHRlYWNoZXJSb2xlPy5pZDtcbiAgfVxuXG5cbn0iLAogICAgImltcG9ydCB7IENvbnRyb2xsZXIsIEdldCwgUG9zdCwgUHV0LCBEZWxldGUsIFBhcmFtcywgQm9keSwgdCB9IGZyb20gJ25ham0tYXBpJztcbmltcG9ydCB7IFVzZXJTZXJ2aWNlIH0gZnJvbSAnLi9Vc2VyU2VydmljZSc7XG5cbmltcG9ydCB7IGlzQWRtaW4sIGlzQXV0aCB9IGZyb20gJ0Avcm9sZXMvUm9sZUd1YXJkcyc7XG5cbkBDb250cm9sbGVyKCcvdXNlcnMnKVxuZXhwb3J0IGNsYXNzIFVzZXJDb250cm9sbGVyIHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSB1c2VyU2VydmljZTogVXNlclNlcnZpY2UpIHsgfVxuXG4gIEBHZXQoKVxuICBAaXNBZG1pbigpIFxuICBhc3luYyBnZXRVc2VycygpIHtcbiAgICBjb25zdCB1c2VycyA9IGF3YWl0IHRoaXMudXNlclNlcnZpY2UuZ2V0QWxsKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIGRhdGE6IHVzZXJzLFxuICAgICAgbWVzc2FnZTogdCgndXNlcnMuc3VjY2Vzcy5yZXRyaWV2ZWQnKSxcbiAgICAgIHN0YXR1czogJ3N1Y2Nlc3MnXG4gICAgfTtcbiAgfVxuXG4gIEBHZXQoJy9sYW5nJylcbiAgQGlzQXV0aCgpIFxuICBhc3luYyBnZXRMYW5nKCkge1xuICAgIGNvbnN0IGxhbmd1YWdlID0gYXdhaXQgdGhpcy51c2VyU2VydmljZS5nZXRMYW5nKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIGRhdGE6IHsgbGFuZ3VhZ2UgfSxcbiAgICAgIG1lc3NhZ2U6IHQoJ3VzZXJzLnN1Y2Nlc3MucmV0cmlldmVkJyksXG4gICAgICBzdGF0dXM6ICdzdWNjZXNzJ1xuICAgIH07XG4gIH1cblxuICBAUG9zdCgnL2xhbmcvOmxhbmd1YWdlJylcbiAgQGlzQXV0aCgpIFxuICBhc3luYyB1cGRhdGVMYW5nKEBQYXJhbXMoJ2xhbmd1YWdlJykgbGFuZ3VhZ2UpIHtcbiAgICBjb25zdCBkYXRhID0gYXdhaXQgdGhpcy51c2VyU2VydmljZS51cGRhdGVMYW5nKGxhbmd1YWdlKTtcbiAgICByZXR1cm4ge1xuICAgICAgZGF0YSxcbiAgICAgIG1lc3NhZ2U6IHQoJ3VzZXJzLnN1Y2Nlc3MudXBkYXRlZCcpLFxuICAgICAgc3RhdHVzOiAnc3VjY2VzcydcbiAgICB9O1xuICB9XG5cbiAgQEdldCgnLzppZCcpXG4gIEBpc0FkbWluKCkgXG4gIGFzeW5jIGdldFVzZXIoQFBhcmFtcygnaWQnKSBpZCkge1xuICAgIGNvbnN0IHVzZXIgPSBhd2FpdCB0aGlzLnVzZXJTZXJ2aWNlLmdldEJ5SWQoaWQpO1xuICAgIHJldHVybiB7XG4gICAgICBkYXRhOiB1c2VyLFxuICAgICAgbWVzc2FnZTogdCgndXNlcnMuc3VjY2Vzcy5yZXRyaWV2ZWQnKSxcbiAgICAgIHN0YXR1czogJ3N1Y2Nlc3MnXG4gICAgfTtcbiAgfVxuXG4gIEBHZXQoJy9lbWFpbC86ZW1haWwnKVxuICBAaXNBZG1pbigpXG4gIGFzeW5jIGdldEJ5RW1haWwoQFBhcmFtcygnZW1haWwnKSBlbWFpbCkge1xuICAgIGNvbnN0IHVzZXIgPSBhd2FpdCB0aGlzLnVzZXJTZXJ2aWNlLmdldEJ5RW1haWwoZW1haWwpO1xuICAgIHJldHVybiB7XG4gICAgICBkYXRhOiB1c2VyLFxuICAgICAgbWVzc2FnZTogdCgndXNlcnMuc3VjY2Vzcy5yZXRyaWV2ZWQnKSxcbiAgICAgIHN0YXR1czogJ3N1Y2Nlc3MnXG4gICAgfTtcbiAgfVxuXG5cbiAgQEdldCgnL3JvbGUvOnVzZXJJZCcpXG4gIEBpc0FkbWluKCkgXG4gIGFzeW5jIGdldFJvbGUoQFBhcmFtcygndXNlcklkJykgdXNlcklkKSB7XG4gICAgY29uc3Qgcm9sZSA9IGF3YWl0IHRoaXMudXNlclNlcnZpY2UuZ2V0Um9sZU5hbWUodXNlcklkKTtcblxuICAgIHJldHVybiB7XG4gICAgICBkYXRhOiByb2xlLFxuICAgICAgbWVzc2FnZTogdCgndXNlcnMuc3VjY2Vzcy5yZXRyaWV2ZWQnKSxcbiAgICAgIHN0YXR1czogJ3N1Y2Nlc3MnXG4gICAgfTtcbiAgfVxuXG4gIEBQb3N0KClcbiAgQGlzQWRtaW4oKSBcbiAgYXN5bmMgY3JlYXRlKEBCb2R5KCkgYm9keSkge1xuICAgIGNvbnN0IG5ld1VzZXIgPSBhd2FpdCB0aGlzLnVzZXJTZXJ2aWNlLmNyZWF0ZShib2R5KTtcbiAgICByZXR1cm4ge1xuICAgICAgZGF0YTogbmV3VXNlcixcbiAgICAgIG1lc3NhZ2U6IHQoJ3VzZXJzLnN1Y2Nlc3MuY3JlYXRlZCcpLFxuICAgICAgc3RhdHVzOiAnc3VjY2VzcydcbiAgICB9O1xuICB9XG5cbiAgQFB1dCgnLzppZCcpXG4gIEBpc0FkbWluKCkgXG4gIGFzeW5jIHVwZGF0ZShAUGFyYW1zKCdpZCcpIGlkLCBAQm9keSgpIGJvZHkpIHtcbiAgICBjb25zdCB1cGRhdGVkVXNlciA9IGF3YWl0IHRoaXMudXNlclNlcnZpY2UudXBkYXRlKGlkLCBib2R5KTtcbiAgICByZXR1cm4ge1xuICAgICAgZGF0YTogdXBkYXRlZFVzZXIsXG4gICAgICBtZXNzYWdlOiB0KCd1c2Vycy5zdWNjZXNzLnVwZGF0ZWQnKSxcbiAgICAgIHN0YXR1czogJ3N1Y2Nlc3MnXG4gICAgfTtcbiAgfVxuXG4gIEBEZWxldGUoJy86aWQnKVxuICBAaXNBZG1pbigpIFxuICBhc3luYyBkZWxldGUoQFBhcmFtcygnaWQnKSBpZCkge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMudXNlclNlcnZpY2UuZGVsZXRlKGlkKTtcbiAgICByZXR1cm4ge1xuICAgICAgZGF0YTogcmVzdWx0LFxuICAgICAgbWVzc2FnZTogdCgndXNlcnMuc3VjY2Vzcy5kZWxldGVkJyksXG4gICAgICBzdGF0dXM6ICdzdWNjZXNzJ1xuICAgIH07XG4gIH1cblxuICBARGVsZXRlKClcbiAgQGlzQWRtaW4oKSBcbiAgYXN5bmMgZGVsZXRlQWxsKCkge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMudXNlclNlcnZpY2UuZGVsZXRlQWxsKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIGRhdGE6IHJlc3VsdCxcbiAgICAgIG1lc3NhZ2U6IHQoJ3VzZXJzLnN1Y2Nlc3MuYWxsRGVsZXRlZCcpLFxuICAgICAgc3RhdHVzOiAnc3VjY2VzcydcbiAgICB9O1xuICB9XG5cbiAgQFBvc3QoJy9hc3NpZ24vOnVzZXJJZC86cm9sZUlkJylcbiAgQGlzQWRtaW4oKSBcbiAgYXN5bmMgYXNzaWduUm9sZShAUGFyYW1zKCd1c2VySWQnKSB1c2VySWQsIEBQYXJhbXMoJ3JvbGVJZCcpIHJvbGVJZCkge1xuICAgIGF3YWl0IHRoaXMudXNlclNlcnZpY2UuYXNzaWduUm9sZSh1c2VySWQsIHJvbGVJZCk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgbWVzc2FnZTogdCgndXNlcnMuc3VjY2Vzcy51cGRhdGVkJyksXG4gICAgICBzdGF0dXM6ICdzdWNjZXNzJ1xuICAgIH07XG4gIH1cblxuICBARGVsZXRlKCcvcmVtb3ZlLzp1c2VySWQnKVxuICBAaXNBZG1pbigpIFxuICBhc3luYyByZW1vdmVSb2xlKEBQYXJhbXMoJ3VzZXJJZCcpIHVzZXJJZCkge1xuICAgIGF3YWl0IHRoaXMudXNlclNlcnZpY2UucmVtb3ZlUm9sZSh1c2VySWQpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIG1lc3NhZ2U6IHQoJ3VzZXJzLnN1Y2Nlc3MudXBkYXRlZCcpLFxuICAgICAgc3RhdHVzOiAnc3VjY2VzcydcbiAgICB9O1xuICB9XG5cbn0iLAogICAgImV4cG9ydCBjb25zdCBFTlVNUyA9IHtcclxuICAvLyBDb3JlIFN5c3RlbVxyXG4gIHVzZXJUeXBlOiB7XHJcbiAgICB2YWx1ZXM6IFsnYWRtaW4nLCAndGVhY2hlcicsICdzdHVkZW50JywgJ3BhcmVudCddLFxyXG4gICAgdHJhbnNsYXRpb25LZXk6ICdlbnVtcy51c2VyVHlwZSdcclxuICB9LFxyXG4gIHVzZXJTdGF0dXM6IHtcclxuICAgIHZhbHVlczogWydhY3RpdmUnLCAnaW5hY3RpdmUnLCAncGVuZGluZyddLFxyXG4gICAgdHJhbnNsYXRpb25LZXk6ICdlbnVtcy51c2VyU3RhdHVzJ1xyXG4gIH0sXHJcbiAgdG9rZW5TdGF0dXM6IHtcclxuICAgIHZhbHVlczogWydhY3RpdmUnLCAncmV2b2tlZCcsICdleHBpcmVkJ10sXHJcbiAgICB0cmFuc2xhdGlvbktleTogJ2VudW1zLnRva2VuU3RhdHVzJ1xyXG4gIH0sXHJcbiAgdG9rZW5UeXBlOiB7XHJcbiAgICB2YWx1ZXM6IFsnYWNjZXNzJywgJ3JlZnJlc2gnXSxcclxuICAgIHRyYW5zbGF0aW9uS2V5OiAnZW51bXMudG9rZW5UeXBlJ1xyXG4gIH0sXHJcbiAgZmlsZVN0YXR1czoge1xyXG4gICAgdmFsdWVzOiBbJ2FjdGl2ZScsICdkZWxldGVkJywgJ2FyY2hpdmVkJ10sXHJcbiAgICB0cmFuc2xhdGlvbktleTogJ2VudW1zLmZpbGVTdGF0dXMnXHJcbiAgfSxcclxuXHJcbiAgLy8gRWR1Y2F0aW9uYWwgU3lzdGVtXHJcbiAgZ2VuZGVyOiB7XHJcbiAgICB2YWx1ZXM6IFsnTScsICdGJ10sXHJcbiAgICB0cmFuc2xhdGlvbktleTogJ2NvbW1vbi5nZW5kZXInXHJcbiAgfSxcclxuICBzdHVkZW50U3RhdHVzOiB7XHJcbiAgICB2YWx1ZXM6IFsnYWN0aXZlJywgJ2luYWN0aXZlJywgJ2dyYWR1YXRlZCcsICd0cmFuc2ZlcnJlZCddLFxyXG4gICAgdHJhbnNsYXRpb25LZXk6ICdzdHVkZW50cy5zdGF0dXMnXHJcbiAgfSxcclxuICB0ZWFjaGVyU3RhdHVzOiB7XHJcbiAgICB2YWx1ZXM6IFsnYWN0aXZlJywgJ2luYWN0aXZlJywgJ29uTGVhdmUnXSxcclxuICAgIHRyYW5zbGF0aW9uS2V5OiAndGVhY2hlcnMuc3RhdHVzJyxcclxuICB9LFxyXG4gIGVtcGxveW1lbnRUeXBlOiB7XHJcbiAgICB2YWx1ZXM6IFsnZnVsbFRpbWUnLCAncGFydFRpbWUnLCAnY29udHJhY3QnLCAndGVtcG9yYXJ5J10sXHJcbiAgICB0cmFuc2xhdGlvbktleTogJ3RlYWNoZXJzLmVtcGxveW1lbnRUeXBlJyxcclxuICB9LFxyXG4gIHJlbGF0aW9uc2hpcFR5cGU6IHtcclxuICAgIHZhbHVlczogWydmYXRoZXInLCAnbW90aGVyJywgJ2d1YXJkaWFuJywgJ3N0ZXBwYXJlbnQnLCAnZ3JhbmRwYXJlbnQnLCAnb3RoZXInXSxcclxuICAgIHRyYW5zbGF0aW9uS2V5OiAncGFyZW50cy5yZWxhdGlvbnNoaXBzJ1xyXG4gIH0sXHJcbiAgc2VtZXN0ZXI6IHtcclxuICAgIHZhbHVlczogWydzcHJpbmcnLCAnc3VtbWVyJywgJ2ZhbGwnLCAnd2ludGVyJ10sXHJcbiAgICB0cmFuc2xhdGlvbktleTogJ2FjYWRlbWljLnNlbWVzdGVyJ1xyXG4gIH0sXHJcbiAgY2xhc3NTdGF0dXM6IHtcclxuICAgIHZhbHVlczogWydhY3RpdmUnLCAnY29tcGxldGVkJywgJ2NhbmNlbGxlZCddLFxyXG4gICAgdHJhbnNsYXRpb25LZXk6ICdjbGFzc2VzLnN0YXR1cydcclxuICB9LFxyXG4gIHNlY3Rpb25TdGF0dXM6IHtcclxuICAgIHZhbHVlczogWydhY3RpdmUnLCAnaW5hY3RpdmUnLCAnYXJjaGl2ZWQnXSxcclxuICAgIHRyYW5zbGF0aW9uS2V5OiAnc2VjdGlvbnMuc3RhdHVzJ1xyXG4gIH0sXHJcbiAgbGFuZ3VhZ2U6IHtcclxuICAgIHZhbHVlczogWydlbicsICdmcicsICdhcicsICdlcyddLFxyXG4gICAgdHJhbnNsYXRpb25LZXk6ICdjb21tb24ubGFuZ3VhZ2VzJ1xyXG4gIH0sXHJcbiAgZW5yb2xsbWVudFN0YXR1czoge1xyXG4gICAgdmFsdWVzOiBbJ2Vucm9sbGVkJywgJ2NvbXBsZXRlZCcsICdkcm9wcGVkJywgJ2ZhaWxlZCddLFxyXG4gICAgdHJhbnNsYXRpb25LZXk6ICdlbnJvbGxtZW50cy5zdGF0dXMnXHJcbiAgfSxcclxuICBhc3NpZ25tZW50U3RhdHVzOiB7XHJcbiAgICB2YWx1ZXM6IFsnYWN0aXZlJywgJ2NvbXBsZXRlZCcsICdjYW5jZWxsZWQnXSxcclxuICAgIHRyYW5zbGF0aW9uS2V5OiAnYXNzaWdubWVudHMuc3RhdHVzJ1xyXG4gIH0sXHJcblxyXG4gIGNhbGVuZGFyU3lzdGVtOiB7XHJcbiAgICB2YWx1ZXM6IFsnU0VNRVNURVInLCAnVFJJTUVTVEVSJywgJ1FVQVJURVInXSxcclxuICAgIHRyYW5zbGF0aW9uS2V5OiAnc2V0dGluZ3MuY2FsZW5kYXJTeXN0ZW0nXHJcbiAgfSxcclxuXHJcbiAgLy8gQXNzZXNzbWVudCAmIEV4YW1zXHJcbiAgYXNzZXNzbWVudFR5cGU6IHtcclxuICAgIHZhbHVlczogWydxdWl6JywgJ2Fzc2lnbm1lbnQnLCAncHJvamVjdCcsICdwYXJ0aWNpcGF0aW9uJywgJ3Rlc3QnLCAncHJlc2VudGF0aW9uJ10sXHJcbiAgICB0cmFuc2xhdGlvbktleTogJ2Fzc2Vzc21lbnRzLnR5cGUnXHJcbiAgfSxcclxuICBhc3Nlc3NtZW50U3RhdHVzOiB7XHJcbiAgICB2YWx1ZXM6IFsnc2NoZWR1bGVkJywgJ2FjdGl2ZScsICdjb21wbGV0ZWQnLCAnY2FuY2VsbGVkJ10sXHJcbiAgICB0cmFuc2xhdGlvbktleTogJ2Fzc2Vzc21lbnRzLnN0YXR1cydcclxuICB9LFxyXG4gIHN1Ym1pc3Npb25UeXBlOiB7XHJcbiAgICB2YWx1ZXM6IFsnb25saW5lJywgJ3BhcGVyJywgJ3ByZXNlbnRhdGlvbicsICdwcmFjdGljYWwnLCAnZGlzY3Vzc2lvbiddLFxyXG4gICAgdHJhbnNsYXRpb25LZXk6ICdhc3Nlc3NtZW50cy5zdWJtaXNzaW9uVHlwZSdcclxuICB9LFxyXG4gIGV4YW1UeXBlOiB7XHJcbiAgICB2YWx1ZXM6IFsnbWlkdGVybScsICdmaW5hbCcsICdzdGFuZGFyZGl6ZWQnXSxcclxuICAgIHRyYW5zbGF0aW9uS2V5OiAnZXhhbXMudHlwZSdcclxuICB9LFxyXG4gIGV4YW1TZWN1cml0eToge1xyXG4gICAgdmFsdWVzOiBbJ2xvdycsICdtZWRpdW0nLCAnaGlnaCddLFxyXG4gICAgdHJhbnNsYXRpb25LZXk6ICdleGFtcy5zZWN1cml0eSdcclxuICB9LFxyXG4gIGV4YW1TdGF0dXM6IHtcclxuICAgIHZhbHVlczogWydzY2hlZHVsZWQnLCAnYWN0aXZlJywgJ2NvbXBsZXRlZCcsICdjYW5jZWxsZWQnLCAncmVzY2hlZHVsZWQnXSxcclxuICAgIHRyYW5zbGF0aW9uS2V5OiAnZXhhbXMuc3RhdHVzJ1xyXG4gIH0sXHJcbiAgZ3JhZGVTdGF0dXM6IHtcclxuICAgIHZhbHVlczogWydncmFkZWQnLCAncGVuZGluZycsICdkcmFmdCcsICdyZXZpZXdlZCddLFxyXG4gICAgdHJhbnNsYXRpb25LZXk6ICdncmFkZXMuc3RhdHVzJ1xyXG4gIH0sXHJcbiAgYXR0ZW5kYW5jZVN0YXR1czoge1xyXG4gICAgdmFsdWVzOiBbJ3ByZXNlbnQnLCAnYWJzZW50JywgJ2xhdGUnLCAnZXhjdXNlZCddLFxyXG4gICAgdHJhbnNsYXRpb25LZXk6ICdhdHRlbmRhbmNlLnN0YXR1cydcclxuICB9LFxyXG4gIHByb2ZpY2llbmN5TGV2ZWw6IHtcclxuICAgIHZhbHVlczogWydiZWdpbm5lcicsICdpbnRlcm1lZGlhdGUnLCAnYWR2YW5jZWQnLCAnZXhwZXJ0J10sXHJcbiAgICB0cmFuc2xhdGlvbktleTogJ2NvbW1vbi5wcm9maWNpZW5jeUxldmVsJ1xyXG4gIH0sXHJcbiAgZGF5T2ZXZWVrOiB7XHJcbiAgICB2YWx1ZXM6IFsnbW9uZGF5JywgJ3R1ZXNkYXknLCAnd2VkbmVzZGF5JywgJ3RodXJzZGF5JywgJ2ZyaWRheScsICdzYXR1cmRheScsICdzdW5kYXknXSxcclxuICAgIHRyYW5zbGF0aW9uS2V5OiAnY29tbW9uLmRheXMnXHJcbiAgfSxcclxuXHJcbiAgLy8gQWxlcnRzXHJcbiAgYWxlcnRUeXBlOiB7XHJcbiAgICB2YWx1ZXM6IFsnYWNhZGVtaWMnLCAnYXR0ZW5kYW5jZScsICdiZWhhdmlvcmFsJywgJ2hlYWx0aCcsICdzeXN0ZW0nLCAnYW5ub3VuY2VtZW50JywgJ3JlbWluZGVyJywgJ2VtZXJnZW5jeSddLFxyXG4gICAgdHJhbnNsYXRpb25LZXk6ICdhbGVydHMudHlwZSdcclxuICB9LFxyXG4gIGFsZXJ0UHJpb3JpdHk6IHtcclxuICAgIHZhbHVlczogWydsb3cnLCAnbWVkaXVtJywgJ2hpZ2gnLCAnY3JpdGljYWwnXSxcclxuICAgIHRyYW5zbGF0aW9uS2V5OiAnYWxlcnRzLnByaW9yaXR5J1xyXG4gIH0sXHJcbiAgYWxlcnRTdGF0dXM6IHtcclxuICAgIHZhbHVlczogWydhY3RpdmUnLCAnYWNrbm93bGVkZ2VkJywgJ3Jlc29sdmVkJywgJ2Rpc21pc3NlZCddLFxyXG4gICAgdHJhbnNsYXRpb25LZXk6ICdhbGVydHMuc3RhdHVzJ1xyXG4gIH0sXHJcblxyXG4gIC8vIEZlZXMgJiBQYXltZW50c1xyXG4gIGZlZVR5cGVTdGF0dXM6IHtcclxuICAgIHZhbHVlczogWydhY3RpdmUnLCAnaW5hY3RpdmUnLCAnYXJjaGl2ZWQnXSxcclxuICAgIHRyYW5zbGF0aW9uS2V5OiAnZmVlcy50eXBlU3RhdHVzJ1xyXG4gIH0sXHJcbiAgZmVlQ2F0ZWdvcnk6IHtcclxuICAgIHZhbHVlczogWyd0dWl0aW9uJywgJ3JlZ2lzdHJhdGlvbicsICd0cmFuc3BvcnQnLCAnY2FmZXRlcmlhJywgJ2Jvb2tzJywgJ3Nwb3J0cycsICd1bmlmb3JtJywgJ3RlY2hub2xvZ3knLCAnZmllbGR0cmlwJywgJ290aGVyJ10sXHJcbiAgICB0cmFuc2xhdGlvbktleTogJ2ZlZVR5cGVzLmNhdGVnb3J5J1xyXG4gIH0sXHJcbiAgcGF5bWVudFR5cGU6IHtcclxuICAgIHZhbHVlczogWydyZWN1cnJpbmcnLCAnb25lVGltZSddLFxyXG4gICAgdHJhbnNsYXRpb25LZXk6ICdwYXltZW50cy50eXBlJyxcclxuICB9LFxyXG4gIHNjaGVkdWxlOiB7XHJcbiAgICB2YWx1ZXM6IFsnbW9udGhseScsICdxdWFydGVybHknLCAnc2VtZXN0ZXInLCAnYW5udWFsbHknLCAnb25lVGltZSddLFxyXG4gICAgdHJhbnNsYXRpb25LZXk6ICdmZWVzLnNjaGVkdWxlJyxcclxuICB9LFxyXG4gIGZlZVN0YXR1czoge1xyXG4gICAgdmFsdWVzOiBbJ3BlbmRpbmcnLCAncGFydGlhbGx5UGFpZCcsICdwYWlkJywgJ292ZXJkdWUnXSxcclxuICAgIHRyYW5zbGF0aW9uS2V5OiAnZmVlcy5zdGF0dXMnLFxyXG4gIH0sXHJcbiAgZmVlSW5zdGFsbG1lbnRTdGF0dXM6IHtcclxuICAgIHZhbHVlczogWydwZW5kaW5nJywgJ3BhcnRpYWxseVBhaWQnLCAncGFpZCcsICdvdmVyZHVlJ10sXHJcbiAgICB0cmFuc2xhdGlvbktleTogJ2ZlZXMuaW5zdGFsbG1lbnRTdGF0dXMnLFxyXG4gIH0sXHJcbiAgcGF5bWVudE1ldGhvZDoge1xyXG4gICAgdmFsdWVzOiBbJ2Nhc2gnLCAnYmFua1RyYW5zZmVyJywgJ2NoZWNrJywgJ2NyZWRpdENhcmQnLCAnZGViaXRDYXJkJywgJ29ubGluZScsICdtb2JpbGVQYXltZW50J10sXHJcbiAgICB0cmFuc2xhdGlvbktleTogJ3BheW1lbnRzLm1ldGhvZHMnLFxyXG4gIH0sXHJcbiAgXHJcbiAgcGF5bWVudFN0YXR1czoge1xyXG4gICAgdmFsdWVzOiBbJ2NvbXBsZXRlZCcsICdwZW5kaW5nJywgJ2ZhaWxlZCcsICdyZWZ1bmRlZCddLFxyXG4gICAgdHJhbnNsYXRpb25LZXk6ICdwYXltZW50cy5zdGF0dXMnXHJcbiAgfSxcclxuXHJcbiAgLy8gRXZlbnRzXHJcbiAgZXZlbnRUeXBlOiB7XHJcbiAgICB2YWx1ZXM6IFsnYWNhZGVtaWMnLCAnc3BvcnRzJywgJ2N1bHR1cmFsJywgJ2hvbGlkYXknLCAnZXhhbScsICdtZWV0aW5nJywgJ3dvcmtzaG9wJywgJ2ZpZWxkdHJpcCcsICdjZXJlbW9ueScsICdjb25mZXJlbmNlJywgJ290aGVyJ10sXHJcbiAgICB0cmFuc2xhdGlvbktleTogJ2V2ZW50cy50eXBlJ1xyXG4gIH0sXHJcbiAgZXZlbnRTdGF0dXM6IHtcclxuICAgIHZhbHVlczogWydzY2hlZHVsZWQnLCAnb25nb2luZycsICdjb21wbGV0ZWQnLCAnY2FuY2VsbGVkJywgJ3Bvc3Rwb25lZCddLFxyXG4gICAgdHJhbnNsYXRpb25LZXk6ICdldmVudHMuc3RhdHVzJ1xyXG4gIH0sXHJcbiAgZXZlbnRWaXNpYmlsaXR5OiB7XHJcbiAgICB2YWx1ZXM6IFsncHVibGljJywgJ3ByaXZhdGUnLCAndGVhY2hlcnMnLCAnc3R1ZGVudHMnLCAncGFyZW50cycsICdzdGFmZiddLFxyXG4gICAgdHJhbnNsYXRpb25LZXk6ICdldmVudHMudmlzaWJpbGl0eSdcclxuICB9LFxyXG4gIHBhcnRpY2lwYW50VHlwZToge1xyXG4gICAgdmFsdWVzOiBbJ3N0dWRlbnQnLCAndGVhY2hlcicsICdwYXJlbnQnLCAnc3RhZmYnXSxcclxuICAgIHRyYW5zbGF0aW9uS2V5OiAnZXZlbnRzLnBhcnRpY2lwYW50VHlwZSdcclxuICB9LFxyXG5cclxuICAvLyBFeHBlbnNlc1xyXG4gIGV4cGVuc2VDYXRlZ29yeToge1xyXG4gICAgdmFsdWVzOiBbJ3NhbGFyeScsICd1dGlsaXRpZXMnLCAnbWFpbnRlbmFuY2UnLCAnc3VwcGxpZXMnLCAnZXF1aXBtZW50JywgJ3RyYW5zcG9ydCcsICdmb29kJywgJ3NlY3VyaXR5JywgJ2NsZWFuaW5nJywgJ2luc3VyYW5jZScsICdyZW50JywgJ3RheCcsICdtYXJrZXRpbmcnLCAndHJhaW5pbmcnLCAndGVjaG5vbG9neScsICdtaXNjZWxsYW5lb3VzJ10sXHJcbiAgICB0cmFuc2xhdGlvbktleTogJ2V4cGVuc2VzLmNhdGVnb3JpZXMnXHJcbiAgfSxcclxuICBleHBlbnNlU3RhdHVzOiB7XHJcbiAgICB2YWx1ZXM6IFsncGVuZGluZycsICdhcHByb3ZlZCcsICdwYWlkJywgJ3JlamVjdGVkJywgJ2NhbmNlbGxlZCddLFxyXG4gICAgdHJhbnNsYXRpb25LZXk6ICdleHBlbnNlcy5zdGF0dXMnXHJcbiAgfSxcclxuXHJcbiAgLy8gVHJhY2tlclxyXG4gIHRyYWNrZXJNb2RlOiB7XHJcbiAgICB2YWx1ZXM6IFsndHJhY2tpbmcnLCAnZ3BycycsICdzbXMnLCAnc2xlZXBUaW1lJywgJ3NsZWVwU2hvY2snLCAnc2xlZXBEZWVwJ10sXHJcbiAgICB0cmFuc2xhdGlvbktleTogJ3RyYWNrZXIubW9kZScsXHJcbiAgfSxcclxuXHJcbiAgLy8gVHJhbnNwb3J0XHJcbiAgZHJpdmVyU3RhdHVzOiB7XHJcbiAgICB2YWx1ZXM6IFsnYWN0aXZlJywgJ2luYWN0aXZlJywgJ29uTGVhdmUnLCAnc3VzcGVuZGVkJ10sXHJcbiAgICB0cmFuc2xhdGlvbktleTogJ3RyYW5zcG9ydC5kcml2ZXJTdGF0dXMnLFxyXG4gIH0sXHJcbiAgdmVoaWNsZVN0YXR1czoge1xyXG4gICAgdmFsdWVzOiBbJ2FjdGl2ZScsICdpbmFjdGl2ZScsICdtYWludGVuYW5jZScsICdyZXRpcmVkJ10sXHJcbiAgICB0cmFuc2xhdGlvbktleTogJ3RyYW5zcG9ydC52ZWhpY2xlU3RhdHVzJ1xyXG4gIH0sXHJcbiAgdmVoaWNsZVR5cGU6IHtcclxuICAgIHZhbHVlczogWydzZWRhbicsICdtaW5pYnVzJywgJ2Z1bGxidXMnLCAnc2h1dHRsZSddLFxyXG4gICAgdHJhbnNsYXRpb25LZXk6ICd0cmFuc3BvcnQudmVoaWNsZVR5cGUnXHJcbiAgfSxcclxuICB2ZWhpY2xlRG9jdW1lbnRUeXBlOiB7XHJcbiAgICB2YWx1ZXM6IFsnaW5zdXJhbmNlJywgJ3JlZ2lzdHJhdGlvbicsICdpbnNwZWN0aW9uJywgJ2VtaXNzaW9uJywgJ2xpY2Vuc2UnXSxcclxuICAgIHRyYW5zbGF0aW9uS2V5OiAndHJhbnNwb3J0LmRvY3VtZW50VHlwZSdcclxuICB9LFxyXG4gIGJ1c1N0YXR1czoge1xyXG4gICAgdmFsdWVzOiBbJ2FjdGl2ZScsICdpbmFjdGl2ZScsICdtYWludGVuYW5jZScsICdyZXRpcmVkJ10sXHJcbiAgICB0cmFuc2xhdGlvbktleTogJ3RyYW5zcG9ydC5idXNTdGF0dXMnXHJcbiAgfSxcclxuICByZWZ1ZWxTdGF0dXM6IHtcclxuICAgIHZhbHVlczogWydwZW5kaW5nJywgJ2NvbXBsZXRlZCcsICdjYW5jZWxsZWQnXSxcclxuICAgIHRyYW5zbGF0aW9uS2V5OiAndHJhbnNwb3J0LnJlZnVlbFN0YXR1cydcclxuICB9LFxyXG4gIGZ1ZWxUeXBlOiB7XHJcbiAgICB2YWx1ZXM6IFsnZ2Fzb2xpbmUnLCAnZGllc2VsJywgJ2VsZWN0cmljJywgJ2h5YnJpZCcsICdscGcnLCAnY25nJ10sXHJcbiAgICB0cmFuc2xhdGlvbktleTogJ3RyYW5zcG9ydC5mdWVsVHlwZSdcclxuICB9LFxyXG4gIG1haW50ZW5hbmNlVHlwZToge1xyXG4gICAgdmFsdWVzOiBbJ3NjaGVkdWxlZCcsICdyZXBhaXInLCAnaW5zcGVjdGlvbicsICdvaWxDaGFuZ2UnLCAnZmlsdGVyQ2hhbmdlJywgJ290aGVyJ10sXHJcbiAgICB0cmFuc2xhdGlvbktleTogJ3RyYW5zcG9ydC5tYWludGVuYW5jZVR5cGUnLFxyXG4gIH0sXHJcbiAgbWFpbnRlbmFuY2VTdGF0dXM6IHtcclxuICAgIHZhbHVlczogWydzY2hlZHVsZWQnLCAnaW5Qcm9ncmVzcycsICdjb21wbGV0ZWQnLCAnY2FuY2VsbGVkJywgJ292ZXJkdWUnXSxcclxuICAgIHRyYW5zbGF0aW9uS2V5OiAndHJhbnNwb3J0Lm1haW50ZW5hbmNlU3RhdHVzJyxcclxuICB9LFxyXG5cclxuICAvLyBQZXJzb25hbFxyXG4gIG1hcml0YWxTdGF0dXM6IHtcclxuICAgIHZhbHVlczogWydzaW5nbGUnLCAnbWFycmllZCcsICdkaXZvcmNlZCcsICd3aWRvd2VkJywgJ3NlcGFyYXRlZCddLFxyXG4gICAgdHJhbnNsYXRpb25LZXk6ICdwYXJlbnRzLm1hcml0YWxTdGF0dXMnXHJcbiAgfVxyXG59XHJcblxyXG4vLyBIZWxwZXIgZnVuY3Rpb25zXHJcbmV4cG9ydCBjb25zdCBnZXRFbnVtQ29uZmlnID0gKGVudW1LZXkpID0+IEVOVU1TW2VudW1LZXldXHJcbmV4cG9ydCBjb25zdCBnZXRFbnVtVmFsdWVzID0gKGVudW1LZXkpID0+IEVOVU1TW2VudW1LZXldPy52YWx1ZXMgfHwgW10iLAogICAgImltcG9ydCB7IHogfSBmcm9tICd6b2QnO1xuaW1wb3J0IHsgYWxlcnRQcmlvcml0eUVudW0sIGFsZXJ0U3RhdHVzRW51bSwgYWxlcnRUeXBlRW51bSwgYXNzZXNzbWVudFN0YXR1c0VudW0sIGFzc2Vzc21lbnRUeXBlRW51bSwgYXR0ZW5kYW5jZVN0YXR1c0VudW0sIGNhbGVuZGFyU3lzdGVtRW51bSwgZHJpdmVyU3RhdHVzRW51bSwgZW1wbG95bWVudFR5cGVFbnVtLCBldmVudFN0YXR1c0VudW0sIGV2ZW50VHlwZUVudW0sIGV2ZW50VmlzaWJpbGl0eUVudW0sIGV4YW1TdGF0dXNFbnVtLCBleGFtVHlwZUVudW0sIGV4cGVuc2VDYXRlZ29yeUVudW0sIGV4cGVuc2VTdGF0dXNFbnVtLCBmZWVTdGF0dXNFbnVtLCBmZWVUeXBlU3RhdHVzRW51bSwgZnVlbFR5cGVFbnVtLCBnZW5kZXJFbnVtLCBncmFkZVN0YXR1c0VudW0sIGxhbmd1YWdlRW51bSwgcGFydGljaXBhbnRUeXBlRW51bSwgcGF5bWVudE1ldGhvZEVudW0sIGZlZUluc3RhbGxtZW50U3RhdHVzRW51bSwgcGF5bWVudFN0YXR1c0VudW0sIHBheW1lbnRUeXBlRW51bSwgcmVmdWVsU3RhdHVzRW51bSwgcmVsYXRpb25zaGlwVHlwZUVudW0sIHNjaGVkdWxlRW51bSwgc2VjdGlvblN0YXR1c0VudW0sIHN0dWRlbnRTdGF0dXNFbnVtLCB0ZWFjaGVyU3RhdHVzRW51bSwgdXNlclN0YXR1c0VudW0sIHZlaGljbGVTdGF0dXNFbnVtLCB2ZWhpY2xlVHlwZUVudW0gfSBmcm9tICcuL1pvZEVudW0nO1xuXG5jb25zdCByZXF1aXJlZElkID0gei5wcmVwcm9jZXNzKCh2YWwpID0+IHZhbCA/PyBcIlwiLCB6LnN0cmluZygpLm1pbigxLCBcIklEIGlzIHJlcXVpcmVkXCIpKTtcbmNvbnN0IG9wdGlvbmFsSWQgPSB6LnN0cmluZygpLm1pbigxLCBcIklEIGNhbm5vdCBiZSBlbXB0eVwiKS5udWxsaXNoKCkub3B0aW9uYWwoKTtcbmNvbnN0IGVtYWlsRmllbGQgPSB6LnN0cmluZygpLmVtYWlsKCdJbnZhbGlkIGVtYWlsIGZvcm1hdCcpLm9yKHoubGl0ZXJhbChcIlwiKSk7XG5jb25zdCBwaG9uZUZpZWxkID0gei5zdHJpbmcoKS5yZWdleCgvXltcXCtdP1sxLTldW1xcZF17MCwxNX0kLywgJ0ludmFsaWQgcGhvbmUgbnVtYmVyJyk7XG5jb25zdCBuYW1lRmllbGQgPSB6LnN0cmluZygpLm1pbigyLCAnTmFtZSBtdXN0IGJlIGF0IGxlYXN0IDIgY2hhcmFjdGVycycpLm1heCgxMDAsICdOYW1lIHRvbyBsb25nJyk7XG5jb25zdCBkYXRlRmllbGQgPSB6LnN0cmluZygpLnJlZ2V4KC9eKFxcZHs0fS1cXGR7Mn0tXFxkezJ9fFxcZHsyfVxcL1xcZHsyfVxcL1xcZHs0fXxcXGR7Mn0tXFxkezJ9LVxcZHsyfXxcXGR7Mn0tXFxkezJ9LVxcZHs0fSkkLywgJ0RhdGUgbXVzdCBiZSBpbiBZWVlZLU1NLURELCBNTS9ERC9ZWVlZLCBERC9NTS9ZWVlZLCBERC1NTS1ZWSwgb3IgREQtTU0tWVlZWSBmb3JtYXQnKTtcbmNvbnN0IG9wdGlvbmFsRGF0ZUZpZWxkID0gei5zdHJpbmcoKS5yZWdleCgvXlxcZHs0fS1cXGR7Mn0tXFxkezJ9JC8sICdEYXRlIG11c3QgYmUgaW4gWVlZWS1NTS1ERCBmb3JtYXQnKS5udWxsYWJsZSgpLm9wdGlvbmFsKCk7XG5jb25zdCB0aW1lRmllbGQgPSB6LnN0cmluZygpLnJlZ2V4KC9eKFswMV0/WzAtOV18MlswLTNdKTpbMC01XVswLTldJC8sICdUaW1lIG11c3QgYmUgaW4gSEg6TU0gZm9ybWF0Jykub3B0aW9uYWwoKS5udWxsYWJsZSgpO1xuY29uc3QgY2luRmllbGQgPSB6LnN0cmluZygpLm1pbig4LCAnQ0lOIG11c3QgYmUgYXQgbGVhc3QgOCBjaGFyYWN0ZXJzJykubWF4KDIwLCAnQ0lOIHRvbyBsb25nJyk7XG5jb25zdCBhZGRyZXNzRmllbGQgPSB6LnN0cmluZygpLm1heCg1MDAsICdBZGRyZXNzIHRvbyBsb25nJykub3B0aW9uYWwoKTtcbmNvbnN0IGFjYWRlbWljWWVhckZpZWxkID0gei5zdHJpbmcoKS5taW4oOSwgJ0FjYWRlbWljIHllYXIgaXMgcmVxdWlyZWQnKS5yZWdleCgvXlxcZHs0fS1cXGR7NH0kLywgJ0FjYWRlbWljIHllYXIgbXVzdCBiZSBpbiBZWVlZLVlZWVkgZm9ybWF0Jyk7XG5cblxuY29uc3QgbnVtID0gKCkgPT4ge1xuICBjb25zdCBjcmVhdGVDaGFpbmFibGUgPSAoY3VycmVudFNjaGVtYTogei5ab2RUeXBlQW55KTogYW55ID0+IHtcbiAgICBjb25zdCBtZXRob2RzID0ge1xuICAgICAgcG9zaXRpdmU6IChtc2cgPSAnTXVzdCBiZSBwb3NpdGl2ZScpID0+XG4gICAgICAgIGNyZWF0ZUNoYWluYWJsZShjdXJyZW50U2NoZW1hLnJlZmluZSgodmFsOiBudW1iZXIpID0+IHZhbCA+IDAsIHsgbWVzc2FnZTogbXNnIH0pKSxcblxuICAgICAgbWluOiAodmFsdWU6IG51bWJlciwgbXNnPzogc3RyaW5nKSA9PlxuICAgICAgICBjcmVhdGVDaGFpbmFibGUoY3VycmVudFNjaGVtYS5yZWZpbmUoXG4gICAgICAgICAgKHZhbDogbnVtYmVyKSA9PiB2YWwgPj0gdmFsdWUsXG4gICAgICAgICAgeyBtZXNzYWdlOiBtc2cgfHwgYE11c3QgYmUgYXQgbGVhc3QgJHt2YWx1ZX1gIH1cbiAgICAgICAgKSksXG5cbiAgICAgIG1heDogKHZhbHVlOiBudW1iZXIsIG1zZz86IHN0cmluZykgPT5cbiAgICAgICAgY3JlYXRlQ2hhaW5hYmxlKGN1cnJlbnRTY2hlbWEucmVmaW5lKFxuICAgICAgICAgICh2YWw6IG51bWJlcikgPT4gdmFsIDw9IHZhbHVlLFxuICAgICAgICAgIHsgbWVzc2FnZTogbXNnIHx8IGBDYW5ub3QgZXhjZWVkICR7dmFsdWV9YCB9XG4gICAgICAgICkpLFxuXG4gICAgICBpbnQ6IChtc2cgPSAnTXVzdCBiZSBhbiBpbnRlZ2VyJykgPT5cbiAgICAgICAgY3JlYXRlQ2hhaW5hYmxlKGN1cnJlbnRTY2hlbWEucmVmaW5lKFxuICAgICAgICAgICh2YWw6IG51bWJlcikgPT4gTnVtYmVyLmlzSW50ZWdlcih2YWwpLFxuICAgICAgICAgIHsgbWVzc2FnZTogbXNnIH1cbiAgICAgICAgKSlcbiAgICB9O1xuXG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oY3VycmVudFNjaGVtYSwgbWV0aG9kcyk7XG4gIH07XG5cbiAgY29uc3QgaXNWYWxpZE51bWJlciA9ICh2YWw6IGFueSkgPT4ge1xuICAgIGlmICh2YWwgPT09IG51bGwgfHwgdmFsID09PSB1bmRlZmluZWQgfHwgTnVtYmVyLmlzTmFOKHZhbCkpIHJldHVybiBmYWxzZTtcbiAgICBpZiAodHlwZW9mIHZhbCA9PT0gJ251bWJlcicpIHJldHVybiB0cnVlO1xuICAgIGlmICh0eXBlb2YgdmFsID09PSAnc3RyaW5nJykge1xuICAgICAgY29uc3QgdHJpbW1lZCA9IHZhbC50cmltKCk7XG4gICAgICByZXR1cm4gdHJpbW1lZCAhPT0gJycgJiYgIWlzTmFOKE51bWJlcih0cmltbWVkKSk7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfTtcblxuICBjb25zdCBiYXNlU2NoZW1hID0gei5hbnkoKVxuICAgIC5yZWZpbmUoaXNWYWxpZE51bWJlciwgeyBtZXNzYWdlOiAnTXVzdCBiZSBhIHZhbGlkIG51bWJlcicgfSlcbiAgICAudHJhbnNmb3JtKCh2YWwpID0+IHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnID8gTnVtYmVyKHZhbCkgOiB2YWwpO1xuXG4gIHJldHVybiBjcmVhdGVDaGFpbmFibGUoYmFzZVNjaGVtYSk7XG59O1xuLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0vL1xuLy8gVVNFUi1ST0xFIFZBTElEQVRJT04gU0NIRU1BXG4vLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PS8vXG5cbmV4cG9ydCBjb25zdCB1c2VyU2NoZW1hID0gei5vYmplY3Qoe1xuICBpZDogb3B0aW9uYWxJZCxcbiAgdXNlcm5hbWU6IG5hbWVGaWVsZC5tYXgoNTApLm9wdGlvbmFsKCksXG4gIGVtYWlsOiBlbWFpbEZpZWxkLFxuICBwYXNzd29yZDogei5zdHJpbmcoKS5taW4oOCwgXCJQYXNzd29yZCBtdXN0IGJlIGF0IGxlYXN0IDggY2hhcmFjdGVyc1wiKSxcbiAgcm9sZUlkOiBvcHRpb25hbElkLFxuICByb2xlTmFtZTogbmFtZUZpZWxkLm1heCg1MCkub3B0aW9uYWwoKSxcbiAgbGFzdExvZ2luOiBvcHRpb25hbERhdGVGaWVsZCxcbiAgaW1hZ2U6IHoudW5pb24oW3ouc3RyaW5nKCksIHouaW5zdGFuY2VvZihGaWxlKSwgei51bmRlZmluZWQoKV0pLm9wdGlvbmFsKCksXG4gIGVtYWlsVmVyaWZpZWQ6IHouYm9vbGVhbigpLmRlZmF1bHQoZmFsc2UpLFxuICBzdGF0dXM6IHVzZXJTdGF0dXNFbnVtLFxuICBjcmVhdGVkQXQ6IG9wdGlvbmFsRGF0ZUZpZWxkLFxufSk7XG5cbmV4cG9ydCBjb25zdCByb2xlU2NoZW1hID0gei5vYmplY3Qoe1xuICBpZDogb3B0aW9uYWxJZCxcbiAgbmFtZTogbmFtZUZpZWxkLm1heCg1MCksXG4gIGRlc2NyaXB0aW9uOiB6LnN0cmluZygpLm1heCgyNTUsIFwiRGVzY3JpcHRpb24gdG9vIGxvbmdcIikub3B0aW9uYWwoKSxcbiAgY3JlYXRlZEF0OiBvcHRpb25hbERhdGVGaWVsZCxcbn0pO1xuXG4vLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PS8vXG4vLyBQRU9QTEUgVkFMSURBVElPTiBTQ0hFTUFTXG4vLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PS8vXG5cbmV4cG9ydCBjb25zdCBzdHVkZW50U2NoZW1hID0gei5vYmplY3Qoe1xuICBpZDogb3B0aW9uYWxJZCxcbiAgY2xhc3NJZDogcmVxdWlyZWRJZCxcbiAgc2VjdGlvbklkOiByZXF1aXJlZElkLFxuICBzdHVkZW50Q29kZTogei5zdHJpbmcoKSxcbiAgbmFtZTogbmFtZUZpZWxkLFxuICBlbWFpbDogZW1haWxGaWVsZCxcbiAgcGhvbmU6IHBob25lRmllbGQubnVsbGlzaCgpLFxuICBhZGRyZXNzOiBhZGRyZXNzRmllbGQsXG4gIGRhdGVPZkJpcnRoOiBvcHRpb25hbERhdGVGaWVsZCxcbiAgZ2VuZGVyOiBnZW5kZXJFbnVtLFxuICBlbnJvbGxtZW50RGF0ZTogZGF0ZUZpZWxkLFxuICBtZWRpY2FsQ29uZGl0aW9uczogei5zdHJpbmcoKS5tYXgoMTAwMCwgJ01lZGljYWwgY29uZGl0aW9ucyBkZXNjcmlwdGlvbiB0b28gbG9uZycpLm51bGxpc2goKS5vcHRpb25hbCgpLFxuICBwcmV2aW91c1NjaG9vbDogei5zdHJpbmcoKS5tYXgoNTAwLCAnUHJldmlvdXMgc2Nob29sIG5hbWUgdG9vIGxvbmcnKS5vcHRpb25hbCgpLm51bGxhYmxlKCksXG4gIGltYWdlOiB6LnVuaW9uKFt6LnN0cmluZygpLCB6Lmluc3RhbmNlb2YoRmlsZSksIHoubnVsbCgpXSkub3B0aW9uYWwoKSxcbiAgc3RhdHVzOiBzdHVkZW50U3RhdHVzRW51bS5kZWZhdWx0KCdhY3RpdmUnKSxcbn0pO1xuXG5leHBvcnQgY29uc3QgcGFyZW50U2NoZW1hID0gei5vYmplY3Qoe1xuICBpZDogb3B0aW9uYWxJZCxcbiAgbmFtZTogbmFtZUZpZWxkLFxuICBlbWFpbDogZW1haWxGaWVsZC5vcHRpb25hbCgpLFxuICBwaG9uZTogcGhvbmVGaWVsZCxcbiAgZ2VuZGVyOiBnZW5kZXJFbnVtLm9wdGlvbmFsKCksXG4gIGFkZHJlc3M6IGFkZHJlc3NGaWVsZCxcbiAgZGF0ZU9mQmlydGg6IG9wdGlvbmFsRGF0ZUZpZWxkLFxuICBjaW46IGNpbkZpZWxkLFxuICBvY2N1cGF0aW9uOiB6LnN0cmluZygpLm1heCgxMDAsICdPY2N1cGF0aW9uIHRvbyBsb25nJykub3B0aW9uYWwoKSxcbiAgbmF0aW9uYWxpdHk6IHouc3RyaW5nKCkubWF4KDEwMCwgJ05hdGlvbmFsaXR5IHRvbyBsb25nJykub3B0aW9uYWwoKSxcbiAgbWFyaXRhbFN0YXR1czogei5zdHJpbmcoKS5tYXgoNTAsICdNYXJpdGFsIHN0YXR1cyB0b28gbG9uZycpLm9wdGlvbmFsKCksXG4gIHJlbGF0aW9uc2hpcFR5cGU6IHJlbGF0aW9uc2hpcFR5cGVFbnVtLFxuICBpbWFnZTogei51bmlvbihbei5zdHJpbmcoKSwgei5pbnN0YW5jZW9mKEZpbGUpLCB6Lm51bGwoKV0pLm9wdGlvbmFsKCksXG4gIGlzRW1lcmdlbmN5Q29udGFjdDogei5ib29sZWFuKCkub3B0aW9uYWwoKS5kZWZhdWx0KGZhbHNlKSxcbiAgZmluYW5jaWFsUmVzcG9uc2liaWxpdHk6IHouYm9vbGVhbigpLm9wdGlvbmFsKCkuZGVmYXVsdChmYWxzZSksXG59KTtcblxuZXhwb3J0IGNvbnN0IGRyaXZlclNjaGVtYSA9IHoub2JqZWN0KHtcbiAgaWQ6IG9wdGlvbmFsSWQsXG4gIG5hbWU6IG5hbWVGaWVsZCxcbiAgZW1haWw6IGVtYWlsRmllbGQsXG4gIGNpbjogY2luRmllbGQsXG4gIHBob25lOiBwaG9uZUZpZWxkLFxuICBhZGRyZXNzOiBhZGRyZXNzRmllbGQsXG4gIGdlbmRlcjogZ2VuZGVyRW51bS5vcHRpb25hbCgpLFxuICBsaWNlbnNlTnVtYmVyOiB6LnN0cmluZygpLm1pbig1LCAnTGljZW5zZSBudW1iZXIgbXVzdCBiZSBhdCBsZWFzdCA1IGNoYXJhY3RlcnMnKS5tYXgoMjAsICdMaWNlbnNlIG51bWJlciB0b28gbG9uZycpLFxuICBsaWNlbnNlVHlwZTogei5zdHJpbmcoKS5tYXgoMTAsICdMaWNlbnNlIHR5cGUgdG9vIGxvbmcnKSxcbiAgbGljZW5zZUV4cGlyeTogZGF0ZUZpZWxkLFxuICBoaXJlRGF0ZTogZGF0ZUZpZWxkLFxuICBzYWxhcnk6IG51bSgpLnBvc2l0aXZlKCdTYWxhcnkgbXVzdCBiZSBwb3NpdGl2ZScpLm9wdGlvbmFsKCksXG4gIHllYXJzT2ZFeHBlcmllbmNlOiBudW0oKS5pbnQoKS5taW4oMCwgJ1llYXJzIG9mIGV4cGVyaWVuY2UgbXVzdCBiZSBub24tbmVnYXRpdmUnKS5vcHRpb25hbCgpLFxuICBlbWVyZ2VuY3lDb250YWN0OiBuYW1lRmllbGQub3B0aW9uYWwoKSxcbiAgZW1lcmdlbmN5UGhvbmU6IHBob25lRmllbGQub3B0aW9uYWwoKSxcbiAgaW1hZ2U6IHoudW5pb24oW3ouc3RyaW5nKCksIHouaW5zdGFuY2VvZihGaWxlKSwgei5udWxsKCldKS5vcHRpb25hbCgpLFxuICBzdGF0dXM6IGRyaXZlclN0YXR1c0VudW0uZGVmYXVsdCgnYWN0aXZlJyksXG4gIG5vdGVzOiB6LnN0cmluZygpLm1heCgxMDAwLCAnTm90ZXMgdG9vIGxvbmcnKS5vcHRpb25hbCgpLm51bGxhYmxlKCksXG59KTtcblxuZXhwb3J0IGNvbnN0IHRlYWNoZXJQZXJzb25hbFNjaGVtYSA9IHoub2JqZWN0KHtcbiAgaWQ6IG9wdGlvbmFsSWQsXG4gIG5hbWU6IG5hbWVGaWVsZCxcbiAgY2luOiBjaW5GaWVsZCxcbiAgZW1haWw6IGVtYWlsRmllbGQsXG4gIHBob25lOiBwaG9uZUZpZWxkLFxuICBhZGRyZXNzOiBhZGRyZXNzRmllbGQsXG4gIGdlbmRlcjogZ2VuZGVyRW51bS5vcHRpb25hbCgpLFxuICBlbWVyZ2VuY3lDb250YWN0OiBuYW1lRmllbGQub3B0aW9uYWwoKSxcbiAgZW1lcmdlbmN5UGhvbmU6IHBob25lRmllbGQsXG4gIHN0YXR1czogdGVhY2hlclN0YXR1c0VudW0uZGVmYXVsdCgnYWN0aXZlJyksXG4gIGltYWdlOiB6LnVuaW9uKFt6LnN0cmluZygpLCB6Lmluc3RhbmNlb2YoRmlsZSksIHoubnVsbCgpXSkub3B0aW9uYWwoKSxcbn0pO1xuXG5leHBvcnQgY29uc3QgdGVhY2hlclByb2Zlc3Npb25hbFNjaGVtYSA9IHoub2JqZWN0KHtcbiAgc3BlY2lhbGl6YXRpb246IHouc3RyaW5nKCkubWF4KDEwMCwgJ1NwZWNpYWxpemF0aW9uIHRvbyBsb25nJykub3B0aW9uYWwoKSxcbiAgeWVhcnNPZkV4cGVyaWVuY2U6IG51bSgpLmludCgpLm1pbigwLCAnWWVhcnMgb2YgZXhwZXJpZW5jZSBtdXN0IGJlIG5vbi1uZWdhdGl2ZScpLm9wdGlvbmFsKCksXG4gIHNhbGFyeTogbnVtKCkucG9zaXRpdmUoJ1NhbGFyeSBtdXN0IGJlIHBvc2l0aXZlJykub3B0aW9uYWwoKSxcbiAgaGlyZURhdGU6IGRhdGVGaWVsZCxcbmJhbmtBY2NvdW50OiB6LmNvZXJjZVxuICAuc3RyaW5nKClcbiAgLm1heCgxMDAsIHsgbWVzc2FnZTogJ0JhbmsgYWNjb3VudCB0b28gbG9uZycgfSlcbiAgLm9wdGlvbmFsKCksXG4gIGVtcGxveW1lbnRUeXBlOiBlbXBsb3ltZW50VHlwZUVudW0ub3B0aW9uYWwoKSxcbiAgICB3b3JrbG9hZEhvdXJzOiBudW0oKS5pbnQoKS5taW4oMCwgJ1dvcmtsb2FkIGhvdXJzIG11c3QgYmUgbm9uLW5lZ2F0aXZlJykubWF4KDYwLCAnV29ya2xvYWQgaG91cnMgY2Fubm90IGV4Y2VlZCA2MCcpLm9wdGlvbmFsKCksXG4gICAgYWNhZGVtaWNEZWdyZWVzOiB6LnN0cmluZygpLm1heCg1MDAsICdBY2FkZW1pYyBkZWdyZWVzIGRlc2NyaXB0aW9uIHRvbyBsb25nJykub3B0aW9uYWwoKSxcbn0pO1xuXG5leHBvcnQgY29uc3QgYXNzaWdubWVudFNjaGVtYSA9IHoub2JqZWN0KHtcbiAgY2xhc3NJZDogei5zdHJpbmcoKS5taW4oMSwgJ0NsYXNzIGlzIHJlcXVpcmVkJyksXG4gIHNlY3Rpb25JZHM6IHouYXJyYXkoei5zdHJpbmcoKSkubWluKDEsICdBdCBsZWFzdCBvbmUgc2VjdGlvbiBpcyByZXF1aXJlZCcpLFxuICBzdWJqZWN0SWRzOiB6LmFycmF5KHouc3RyaW5nKCkpLm1pbigxLCAnQXQgbGVhc3Qgb25lIHN1YmplY3QgaXMgcmVxdWlyZWQnKSxcbiAgYWNhZGVtaWNZZWFyOiB6LnN0cmluZygpLm9wdGlvbmFsKClcbn0pO1xuXG5leHBvcnQgY29uc3QgYXNzaWdubWVudHNTY2hlbWEgPSB6Lm9iamVjdCh7XG4gIGFzc2lnbm1lbnRzOiB6LmFycmF5KGFzc2lnbm1lbnRTY2hlbWEpLm1pbigxLCAnQXQgbGVhc3Qgb25lIHBhcmVudCBpcyByZXF1aXJlZCcpXG59KVxuXG5leHBvcnQgY29uc3QgdGVhY2hlckZ1bGxTY2hlbWEgPSB6Lm9iamVjdCh7XG4gIC4uLnRlYWNoZXJQZXJzb25hbFNjaGVtYS5zaGFwZSxcbiAgLi4udGVhY2hlclByb2Zlc3Npb25hbFNjaGVtYS5zaGFwZSxcbiAgLi4uYXNzaWdubWVudHNTY2hlbWEuc2hhcGUsXG59KTtcblxuLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0vL1xuLy8gRkVFUyBWQUxJREFUSU9OIFNDSEVNQVNcbi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ly9cblxuZXhwb3J0IGNvbnN0IGZlZVR5cGVTY2hlbWEgPSB6Lm9iamVjdCh7XG4gIGlkOiBvcHRpb25hbElkLFxuICBuYW1lOiB6LnN0cmluZygpLm1pbigyLCAnRmVlIHR5cGUgbmFtZSBtdXN0IGJlIGF0IGxlYXN0IDIgY2hhcmFjdGVycycpLm1heCgxMDAsICdGZWUgdHlwZSBuYW1lIHRvbyBsb25nJyksXG4gIGRlc2NyaXB0aW9uOiB6LnN0cmluZygpLm1heCg1MDAsICdEZXNjcmlwdGlvbiB0b28gbG9uZycpLm9wdGlvbmFsKCkubnVsbGFibGUoKSxcbiAgY2F0ZWdvcnk6IHouc3RyaW5nKCksXG4gIGFtb3VudDogbnVtKCkucG9zaXRpdmUoJ0Ftb3VudCBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAwJykubWF4KDFfMDAwXzAwLCAnQW1vdW50IHRvbyBsYXJnZScpLFxuICBwYXltZW50VHlwZTogcGF5bWVudFR5cGVFbnVtLmRlZmF1bHQoJ3JlY3VycmluZycpLFxuICBzdGF0dXM6IGZlZVR5cGVTdGF0dXNFbnVtLmRlZmF1bHQoJ2FjdGl2ZScpLm9wdGlvbmFsKCksXG59KTtcblxuZXhwb3J0IGNvbnN0IGZlZVNjaGVtYSA9IHoub2JqZWN0KHtcbiAgaWQ6IG9wdGlvbmFsSWQsXG4gIHN0dWRlbnRJZDogcmVxdWlyZWRJZCxcbiAgZmVlVHlwZUlkOiByZXF1aXJlZElkLFxuICBhY2FkZW1pY1llYXI6IGFjYWRlbWljWWVhckZpZWxkLm9wdGlvbmFsKCksXG4gIHN0YXR1czogZmVlU3RhdHVzRW51bS5vcHRpb25hbCgpLFxuICBzY2hlZHVsZTogc2NoZWR1bGVFbnVtLFxuICBiYXNlQW1vdW50OiBudW0oKS5wb3NpdGl2ZSgnQmFzZSBhbW91bnQgbXVzdCBiZSBwb3NpdGl2ZScpLm9wdGlvbmFsKCksXG4gIGdyb3NzQW1vdW50OiBudW0oKS5wb3NpdGl2ZSgnR3Jvc3MgYW1vdW50IG11c3QgYmUgcG9zaXRpdmUnKS5vcHRpb25hbCgpLFxuICBuZXRBbW91bnQ6IG51bSgpLm9wdGlvbmFsKCksXG4gIHBhaWRBbW91bnQ6IG51bSgpLm1pbigwLCAnUGFpZCBhbW91bnQgY2Fubm90IGJlIG5lZ2F0aXZlJykub3B0aW9uYWwoKSxcbiAgZGlzY291bnRBbW91bnQ6IG51bSgpLm1pbigwLCAnRGlzY291bnQgY2Fubm90IGJlIG5lZ2F0aXZlJykub3B0aW9uYWwoKSxcbiAgZGlzY291bnRSZWFzb246IHouc3RyaW5nKCkubWF4KDUwMCwgJ0Rpc2NvdW50IHJlYXNvbiB0b28gbG9uZycpLm9wdGlvbmFsKCkubnVsbGFibGUoKSxcbiAgYXNzaWduZWRCeTogb3B0aW9uYWxJZC5udWxsYWJsZSgpLFxuICBub3Rlczogei5zdHJpbmcoKS5tYXgoMTAwMCwgJ05vdGVzIHRvbyBsb25nJykub3B0aW9uYWwoKS5udWxsYWJsZSgpLFxufSlcblxuZXhwb3J0IGNvbnN0IGJ1bGtGZWVJdGVtU2NoZW1hID0gZmVlU2NoZW1hLm9taXQoeyBzdHVkZW50SWQ6IHRydWUgfSlcblxuZXhwb3J0IGNvbnN0IGJ1bGtGZWVGb3JtU2NoZW1hID0gei5vYmplY3Qoe1xuICBzdHVkZW50SWQ6IHJlcXVpcmVkSWQsXG4gIGZlZXM6IHouYXJyYXkoYnVsa0ZlZUl0ZW1TY2hlbWEpLm1pbigxLCAnQXQgbGVhc3Qgb25lIGZlZSBpcyByZXF1aXJlZCcpXG59KTtcblxuZXhwb3J0IGNvbnN0IGZlZUluc3RhbGxtZW50U2NoZW1hID0gei5vYmplY3Qoe1xuICBmZWVJZDogb3B0aW9uYWxJZCxcbiAgbnVtYmVyOiBudW0oKS5pbnQoKS5taW4oMSwgJ0luc3RhbGxtZW50IG11c3QgYmUgYXQgbGVhc3QgMScpLFxuICBkdWVEYXRlOiBkYXRlRmllbGQsXG4gIGFtb3VudDogbnVtKCkucG9zaXRpdmUoJ0Ftb3VudCBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAwJykubWF4KDFfMDAwXzAwLCAnQW1vdW50IHRvbyBsYXJnZScpLFxuICBwYWlkQW1vdW50OiBudW0oKS5taW4oMCwgJ1BhaWQgYW1vdW50IGNhbm5vdCBiZSBuZWdhdGl2ZScpLm1heCgxXzAwMF8wMCwgJ0Ftb3VudCB0b28gbGFyZ2UnKS5vcHRpb25hbCgpLFxuICBzdGF0dXM6IGZlZUluc3RhbGxtZW50U3RhdHVzRW51bS5vcHRpb25hbCgpLFxufSk7XG5cbmV4cG9ydCBjb25zdCBmZWVQYXltZW50U2NoZW1hID0gei5vYmplY3Qoe1xuICBzdHVkZW50SWQ6IG9wdGlvbmFsSWQsXG4gIGFtb3VudDogbnVtKCkucG9zaXRpdmUoJ0Ftb3VudCBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAwJykubWF4KDFfMDAwXzAwLCAnQW1vdW50IHRvbyBsYXJnZScpLm9wdGlvbmFsKCksXG4gIHBheW1lbnRNZXRob2Q6IHBheW1lbnRNZXRob2RFbnVtLFxuICBwYXltZW50RGF0ZTogZGF0ZUZpZWxkLFxuICBjaGVja051bWJlcjogei5wcmVwcm9jZXNzKCh2YWwpID0+IHZhbCA9PT0gXCJcIiA/IG51bGwgOiB2YWwsIHouc3RyaW5nKCkubWF4KDUwLCAnQ2hlY2sgbnVtYmVyIHRvbyBsb25nJykub3B0aW9uYWwoKS5udWxsYWJsZSgpKSxcbiAgY2hlY2tEdWVEYXRlOiB6LnByZXByb2Nlc3MoKHZhbCkgPT4gdmFsID09PSBcIlwiID8gbnVsbCA6IHZhbCwgb3B0aW9uYWxEYXRlRmllbGQubnVsbGFibGUoKSksXG4gIHRyYW5zYWN0aW9uUmVmOiB6LnByZXByb2Nlc3MoKHZhbCkgPT4gdmFsID09PSBcIlwiID8gbnVsbCA6IHZhbCwgei5zdHJpbmcoKS5tYXgoMTAwLCAnVHJhbnNhY3Rpb24gcmVmZXJlbmNlIHRvbyBsb25nJykub3B0aW9uYWwoKS5udWxsYWJsZSgpKSxcbiAgcmVjZWlwdE51bWJlcjogei5wcmVwcm9jZXNzKCh2YWwpID0+IHZhbCA9PT0gXCJcIiA/IG51bGwgOiB2YWwsIHouc3RyaW5nKCkubWF4KDUwLCAnUmVjZWlwdCBudW1iZXIgdG9vIGxvbmcnKS5vcHRpb25hbCgpLm51bGxhYmxlKCkpLFxuICBzdGF0dXM6IHBheW1lbnRTdGF0dXNFbnVtLmRlZmF1bHQoJ2NvbXBsZXRlZCcpLFxuICBwcm9jZXNzZWRCeTogb3B0aW9uYWxJZCxcbiAgbm90ZXM6IHoucHJlcHJvY2VzcygodmFsKSA9PiB2YWwgPT09IFwiXCIgPyBudWxsIDogdmFsLCB6LnN0cmluZygpLm1heCgxMDAwLCAnTm90ZXMgdG9vIGxvbmcnKS5vcHRpb25hbCgpLm51bGxhYmxlKCkpLFxuICBhbGxvY2F0aW9uczogei5hcnJheSh6Lm9iamVjdCh7XG4gICAgZmVlSWQ6IG9wdGlvbmFsSWQsXG4gICAgbnVtYmVyOiB6Lm51bWJlcigpLmludCgpLnBvc2l0aXZlKCdJbnN0YWxsbWVudCBtdXN0IGJlIGEgcG9zaXRpdmUgbnVtYmVyJyksXG4gICAgYW1vdW50OiBudW0oKS5wb3NpdGl2ZSgnQW1vdW50IG11c3QgYmUgZ3JlYXRlciB0aGFuIDAnKVxuICB9KSkub3B0aW9uYWwoKS5udWxsYWJsZSgpLFxufSlcblxuZXhwb3J0IGNvbnN0IHBheW1lbnRBbGxvY2F0aW9uU2NoZW1hID0gei5vYmplY3Qoe1xuICBwYXltZW50SWQ6IHouc3RyaW5nKCkubWluKDEsICdQYXltZW50IElEIGlzIHJlcXVpcmVkJyksXG4gIGZlZUlkOiB6LnN0cmluZygpLm1pbigxLCAnRmVlIElEIGlzIHJlcXVpcmVkJyksXG4gIGluc3RhbGxtZW50SWQ6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbiAgYW1vdW50OiB6Lm51bWJlcigpLnBvc2l0aXZlKCdBbW91bnQgbXVzdCBiZSBwb3NpdGl2ZScpLFxuICB0eXBlOiB6LmVudW0oWydmZWUnLCAnaW5zdGFsbG1lbnQnXSkuZGVmYXVsdCgnaW5zdGFsbG1lbnQnKSxcbiAgbm90ZXM6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbn0pO1xuXG5leHBvcnQgY29uc3QgcGFyZW50c1NjaGVtYSA9IHoub2JqZWN0KHtcbiAgcGFyZW50czogei5hcnJheShwYXJlbnRTY2hlbWEpLm9wdGlvbmFsKCkuZGVmYXVsdChbXSlcbn0pXG5cbmV4cG9ydCBjb25zdCBmZWVzU2NoZW1hID0gei5vYmplY3Qoe1xuICBmZWVzOiB6LmFycmF5KGJ1bGtGZWVJdGVtU2NoZW1hKS5taW4oMSwgJ0F0IGxlYXN0IG9uZSBmZWUgaXMgcmVxdWlyZWQnKVxufSlcblxuZXhwb3J0IGNvbnN0IGZ1bGxTdHVkZW50U2NoZW1hID0gei5vYmplY3Qoe1xuICAuLi5zdHVkZW50U2NoZW1hLnNoYXBlLFxuICAuLi5wYXJlbnRzU2NoZW1hLnNoYXBlLFxuICAuLi5mZWVzU2NoZW1hLnNoYXBlXG59KTtcblxuLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0vL1xuLy8gU0NIT09MIFNUUlVDVFVSRSBWQUxJREFUSU9OIFNDSEVNQVNcbi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ly9cblxuZXhwb3J0IGNvbnN0IHN1YmplY3RTY2hlbWEgPSB6Lm9iamVjdCh7XG4gIGlkOiBvcHRpb25hbElkLFxuICBjb2RlOiB6LnN0cmluZygpLm1pbigyLCAnU3ViamVjdCBjb2RlIG11c3QgYmUgYXQgbGVhc3QgMiBjaGFyYWN0ZXJzJykubWF4KDEwLCAnU3ViamVjdCBjb2RlIHRvbyBsb25nJyksXG4gIG5hbWU6IHouc3RyaW5nKCkubWluKDIsICdTdWJqZWN0IG5hbWUgbXVzdCBiZSBhdCBsZWFzdCAyIGNoYXJhY3RlcnMnKS5tYXgoMTAwLCAnU3ViamVjdCBuYW1lIHRvbyBsb25nJyksXG4gIGRlc2NyaXB0aW9uOiB6LnN0cmluZygpLm1heCg1MDAsICdEZXNjcmlwdGlvbiB0b28gbG9uZycpLm9wdGlvbmFsKCksXG4gIGdyYWRlTGV2ZWw6IG51bSgpLmludCgpLm1pbigxKS5tYXgoMTIpLm9wdGlvbmFsKCksXG59KTtcblxuZXhwb3J0IGNvbnN0IHNlY3Rpb25TY2hlbWEgPSB6Lm9iamVjdCh7XG4gIGlkOiBvcHRpb25hbElkLFxuICBjbGFzc0lkOiByZXF1aXJlZElkLFxuICBuYW1lOiB6LnN0cmluZygpLm1pbigxLCAnU2VjdGlvbiBuYW1lIGlzIHJlcXVpcmVkJykubWF4KDEwLCAnU2VjdGlvbiBuYW1lIHRvbyBsb25nJyksXG4gIG1heFN0dWRlbnRzOiBudW0oKS5pbnQoKS5taW4oMSwgJ01heCBzdHVkZW50cyBtdXN0IGJlIGF0IGxlYXN0IDEnKS5tYXgoMTAwLCAnTWF4IHN0dWRlbnRzIGNhbm5vdCBleGNlZWQgMTAwJykuZGVmYXVsdCgzMCksXG4gIHJvb21OdW1iZXI6IG51bSgpLm1heCgxMDAwMCwgJ1Jvb20gbnVtYmVyIHRvbyBsb25nJykub3B0aW9uYWwoKSxcbiAgc3RhdHVzOiBzZWN0aW9uU3RhdHVzRW51bS5kZWZhdWx0KCdhY3RpdmUnKSxcbn0pO1xuXG5leHBvcnQgY29uc3QgY2xhc3NTY2hlbWEgPSB6Lm9iamVjdCh7XG4gIGlkOiBvcHRpb25hbElkLFxuICBuYW1lOiB6LnN0cmluZygpLm1pbigxLCAnQ2xhc3MgbmFtZSBpcyByZXF1aXJlZCcpLm1heCg1MCwgJ0NsYXNzIG5hbWUgdG9vIGxvbmcnKSxcbiAgZGVzY3JpcHRpb246IHouc3RyaW5nKCkubWF4KDUwMCwgJ0Rlc2NyaXB0aW9uIHRvbyBsb25nJykub3B0aW9uYWwoKSxcbiAgYWNhZGVtaWNZZWFyOiBhY2FkZW1pY1llYXJGaWVsZCxcbiAgbGV2ZWw6IHouc3RyaW5nKCkubWluKDEsICdDbGFzcyBsZXZlbCBpcyByZXF1aXJlZCcpLFxufSk7XG5cbmV4cG9ydCBjb25zdCBhdHRlbmRhbmNlU2NoZW1hID0gei5vYmplY3Qoe1xuICBzdHVkZW50SWQ6IHJlcXVpcmVkSWQsXG4gIHRlYWNoZXJJZDogcmVxdWlyZWRJZCxcbiAgc3ViamVjdElkOiByZXF1aXJlZElkLFxuICBzZWN0aW9uSWQ6IHJlcXVpcmVkSWQsXG4gIGRhdGU6IGRhdGVGaWVsZCxcbiAgc3RhdHVzOiBhdHRlbmRhbmNlU3RhdHVzRW51bS5kZWZhdWx0KCdwcmVzZW50JyksXG4gIG5vdGVzOiB6LnN0cmluZygpLm1heCg1MDAsICdOb3RlcyB0b28gbG9uZycpLm9wdGlvbmFsKCksXG59KVxuXG5leHBvcnQgY29uc3QgYXNzZXNzbWVudFNjaGVtYSA9IHoub2JqZWN0KHtcbiAgY2xhc3NJZDogcmVxdWlyZWRJZCxcbiAgc2VjdGlvbklkOiByZXF1aXJlZElkLFxuICBzdWJqZWN0SWQ6IHJlcXVpcmVkSWQsXG4gIHRlYWNoZXJJZDogcmVxdWlyZWRJZCxcbiAgdGVhY2hlckFzc2lnbm1lbnRJZDogb3B0aW9uYWxJZCxcbiAgdGl0bGU6IHouc3RyaW5nKCkubWluKDMsICdUaXRsZSBtdXN0IGJlIGF0IGxlYXN0IDMgY2hhcmFjdGVycycpLm1heCgyMDAsICdUaXRsZSB0b28gbG9uZycpLFxuICBkZXNjcmlwdGlvbjogei5zdHJpbmcoKS5tYXgoMTAwMCwgJ0Rlc2NyaXB0aW9uIHRvbyBsb25nJykub3B0aW9uYWwoKS5udWxsYWJsZSgpLFxuICB0eXBlOiBhc3Nlc3NtZW50VHlwZUVudW0uZGVmYXVsdCgncXVpeicpLFxuICBkYXRlOiBkYXRlRmllbGQsXG4gIGR1cmF0aW9uOiBudW0oKS5pbnQoKS5taW4oMSwgJ0R1cmF0aW9uIG11c3QgYmUgYXQgbGVhc3QgMSBtaW51dGUnKS5tYXgoNDgwLCAnRHVyYXRpb24gY2Fubm90IGV4Y2VlZCA4IGhvdXJzJyksXG4gIHRvdGFsTWFya3M6IG51bSgpLnBvc2l0aXZlKCdUb3RhbCBtYXJrcyBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAwJykubWF4KDEwMDAsICdUb3RhbCBtYXJrcyBjYW5ub3QgZXhjZWVkIDEwMDAnKSxcbiAgcGFzc2luZ01hcmtzOiBudW0oKS5taW4oMCwgJ1Bhc3NpbmcgbWFya3MgbXVzdCBiZSBub24tbmVnYXRpdmUnKS5tYXgoMTAwMCwgJ1Bhc3NpbmcgbWFya3MgY2Fubm90IGV4Y2VlZCAxMDAwJyksXG4gIGluc3RydWN0aW9uczogei5zdHJpbmcoKS5tYXgoMjAwMCwgJ0luc3RydWN0aW9ucyB0b28gbG9uZycpLm9wdGlvbmFsKCkubnVsbGFibGUoKSxcbiAgc3RhdHVzOiBhc3Nlc3NtZW50U3RhdHVzRW51bS5kZWZhdWx0KCdzY2hlZHVsZWQnKSxcbiAgYXNzZXNzbWVudElkOiBvcHRpb25hbElkLFxufSlcblxuZXhwb3J0IGNvbnN0IGJ1bGtBc3Nlc3NtZW50U2NoZW1hID0gei5vYmplY3Qoe1xuICBhc3Nlc3NtZW50czogei5hcnJheShhc3Nlc3NtZW50U2NoZW1hKVxuICAgIC5taW4oMSwgJ0F0IGxlYXN0IG9uZSBhc3Nlc3NtZW50IGlzIHJlcXVpcmVkJylcbiAgICAubWF4KDUwLCAnQ2Fubm90IGNyZWF0ZSBtb3JlIHRoYW4gNTAgYXNzZXNzbWVudHMgYXQgb25jZScpLFxufSlcblxuZXhwb3J0IGNvbnN0IGdyYWRlU2NoZW1hID0gei5vYmplY3Qoe1xuICBhc3Nlc3NtZW50SWQ6IHJlcXVpcmVkSWQsXG4gIHRlYWNoZXJJZDogcmVxdWlyZWRJZCxcbiAgc3ViamVjdElkOiByZXF1aXJlZElkLFxuICBzZWN0aW9uSWQ6IHJlcXVpcmVkSWQsXG4gIHN0dWRlbnRJZDogcmVxdWlyZWRJZCxcbiAgZ3JhZGVJZDogcmVxdWlyZWRJZCxcbiAgYXNzZXNzbWVudFRpdGxlOiB6LnN0cmluZygpLm1pbigzLCAnQXNzZXNzbWVudCB0aXRsZSBtdXN0IGJlIGF0IGxlYXN0IDMgY2hhcmFjdGVycycpLm1heCgyMDAsICdBc3Nlc3NtZW50IHRpdGxlIHRvbyBsb25nJykub3B0aW9uYWwoKSxcbiAgbWFya3NPYnRhaW5lZDogbnVtKCkubWluKDAsICdNYXJrcyBvYnRhaW5lZCBtdXN0IGJlIG5vbi1uZWdhdGl2ZScpLm1heCgxMDAwLCAnTWFya3Mgb2J0YWluZWQgY2Fubm90IGV4Y2VlZCAxMDAwJyksXG4gIGZlZWRiYWNrOiB6LnN0cmluZygpLm1heCgxMDAwLCAnRmVlZGJhY2sgdG9vIGxvbmcnKS5vcHRpb25hbCgpLm51bGxhYmxlKCksXG4gIHN0YXR1czogZ3JhZGVTdGF0dXNFbnVtLmRlZmF1bHQoJ2dyYWRlZCcpLFxufSlcblxuZXhwb3J0IGNvbnN0IGV4YW1TY2hlbWEgPSB6Lm9iamVjdCh7XG4gIGNsYXNzSWQ6IG9wdGlvbmFsSWQsXG4gIHNlY3Rpb25JZDogcmVxdWlyZWRJZCxcbiAgc3ViamVjdElkOiByZXF1aXJlZElkLFxuICB0ZWFjaGVySWQ6IHJlcXVpcmVkSWQsXG4gIGV4YW1JZDogcmVxdWlyZWRJZCxcbiAgdGVhY2hlckFzc2lnbm1lbnRJZDogcmVxdWlyZWRJZCxcbiAgdGl0bGU6IHouc3RyaW5nKCkubWluKDMsICdUaXRsZSBtdXN0IGJlIGF0IGxlYXN0IDMgY2hhcmFjdGVycycpLm1heCgyMDAsICdUaXRsZSB0b28gbG9uZycpLFxuICBkZXNjcmlwdGlvbjogei5zdHJpbmcoKS5tYXgoMTAwMCwgJ0Rlc2NyaXB0aW9uIHRvbyBsb25nJykub3B0aW9uYWwoKS5udWxsYWJsZSgpLFxuICB0eXBlOiBleGFtVHlwZUVudW0uZGVmYXVsdCgnbWlkdGVybScpLFxuICBkYXRlOiBkYXRlRmllbGQsXG4gIHN0YXJ0VGltZTogdGltZUZpZWxkLFxuICBlbmRUaW1lOiB0aW1lRmllbGQsXG4gIGR1cmF0aW9uOiBudW0oKS5pbnQoKS5taW4oMzAsICdFeGFtIGR1cmF0aW9uIG11c3QgYmUgYXQgbGVhc3QgMzAgbWludXRlcycpLm1heCg0ODAsICdEdXJhdGlvbiBjYW5ub3QgZXhjZWVkIDggaG91cnMnKSxcbiAgdG90YWxNYXJrczogbnVtKCkucG9zaXRpdmUoJ1RvdGFsIG1hcmtzIG11c3QgYmUgZ3JlYXRlciB0aGFuIDAnKS5tYXgoMTAwMCwgJ1RvdGFsIG1hcmtzIGNhbm5vdCBleGNlZWQgMTAwMCcpLFxuICBwYXNzaW5nTWFya3M6IG51bSgpLm1pbigwLCAnUGFzc2luZyBtYXJrcyBtdXN0IGJlIG5vbi1uZWdhdGl2ZScpLm1heCgxMDAwLCAnUGFzc2luZyBtYXJrcyBjYW5ub3QgZXhjZWVkIDEwMDAnKSxcbiAgcm9vbU51bWJlcjogbnVtKCkubWF4KDUwLCAnUm9vbSBudW1iZXIgdG9vIGxvbmcnKS5vcHRpb25hbCgpLm51bGxhYmxlKCksXG4gIGFsbG93ZWRNYXRlcmlhbHM6IHouc3RyaW5nKCkubWF4KDUwMCwgJ0FsbG93ZWQgbWF0ZXJpYWxzIGRlc2NyaXB0aW9uIHRvbyBsb25nJykub3B0aW9uYWwoKS5udWxsYWJsZSgpLFxuICBpbnN0cnVjdGlvbnM6IHouc3RyaW5nKCkubWF4KDIwMDAsICdJbnN0cnVjdGlvbnMgdG9vIGxvbmcnKS5vcHRpb25hbCgpLm51bGxhYmxlKCksXG4gIHN0YXR1czogZXhhbVN0YXR1c0VudW0uZGVmYXVsdCgnc2NoZWR1bGVkJyksXG59KVxuXG4vLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PS8vXG4vLyBBTk5PVU5DRU1FTlQgVkFMSURBVElPTiBTQ0hFTUFcbi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ly9cblxuZXhwb3J0IGNvbnN0IGFubm91bmNlbWVudFNjaGVtYSA9IHoub2JqZWN0KHtcbiAgdGl0bGU6IHouc3RyaW5nKCkubWluKDMsICdUaXRsZSBtdXN0IGJlIGF0IGxlYXN0IDMgY2hhcmFjdGVycycpLm1heCgyMDAsICdUaXRsZSB0b28gbG9uZycpLFxuICBjb250ZW50OiB6LnN0cmluZygpLm1pbigxMCwgJ0NvbnRlbnQgbXVzdCBiZSBhdCBsZWFzdCAxMCBjaGFyYWN0ZXJzJykubWF4KDUwMDAsICdDb250ZW50IHRvbyBsb25nJyksXG4gIGF1dGhvcklkOiBvcHRpb25hbElkLFxuICB0YXJnZXRBdWRpZW5jZTogei5lbnVtKFsnYWxsJywgJ3N0dWRlbnRzJywgJ3RlYWNoZXJzJywgJ3BhcmVudHMnLCAnY2xhc3MnXSksXG4gIGNsYXNzSWQ6IG9wdGlvbmFsSWQsXG4gIGlzUHVibGlzaGVkOiB6LmJvb2xlYW4oKS5kZWZhdWx0KGZhbHNlKSxcbiAgcHVibGlzaERhdGU6IHouc3RyaW5nKCkuZGF0ZXRpbWUoJ0ludmFsaWQgcHVibGlzaCBkYXRlJykub3B0aW9uYWwoKSxcbiAgZXhwaXJ5RGF0ZTogei5zdHJpbmcoKS5kYXRldGltZSgnSW52YWxpZCBleHBpcnkgZGF0ZScpLm9wdGlvbmFsKCksXG59KVxuXG4vLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PS8vXG4vLyBBTEVSVCBWQUxJREFUSU9OIFNDSEVNQVxuLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0vL1xuXG5leHBvcnQgY29uc3QgYWxlcnRTY2hlbWEgPSB6Lm9iamVjdCh7XG4gIHR5cGU6IGFsZXJ0VHlwZUVudW0sXG4gIHRpdGxlOiB6LnN0cmluZygpLm1pbigzLCAnVGl0bGUgbXVzdCBiZSBhdCBsZWFzdCAzIGNoYXJhY3RlcnMnKS5tYXgoMjAwLCAnVGl0bGUgdG9vIGxvbmcnKSxcbiAgbWVzc2FnZTogei5zdHJpbmcoKS5taW4oMTAsICdNZXNzYWdlIG11c3QgYmUgYXQgbGVhc3QgMTAgY2hhcmFjdGVycycpLm1heCgyMDAwLCAnTWVzc2FnZSB0b28gbG9uZycpLFxuICBwcmlvcml0eTogYWxlcnRQcmlvcml0eUVudW0uZGVmYXVsdCgnbWVkaXVtJyksXG4gIHN0YXR1czogYWxlcnRTdGF0dXNFbnVtLmRlZmF1bHQoJ2FjdGl2ZScpLFxuICBzdHVkZW50SWQ6IG9wdGlvbmFsSWQsXG4gIHRlYWNoZXJJZDogb3B0aW9uYWxJZCxcbiAgY2xhc3NJZDogb3B0aW9uYWxJZCxcbiAgc3ViamVjdElkOiBvcHRpb25hbElkLFxuICB0YXJnZXRBdWRpZW5jZTogei5lbnVtKFsnYWxsJywgJ3N0dWRlbnRzJywgJ3RlYWNoZXJzJywgJ3BhcmVudHMnXSkub3B0aW9uYWwoKSxcbiAgYXV0aG9ySWQ6IG9wdGlvbmFsSWQsXG4gIGlzUmVhZDogei5ib29sZWFuKCkuZGVmYXVsdChmYWxzZSksXG59KTtcblxuLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0vL1xuLy8gRVZFTlRTIFZBTElEQVRJT04gU0NIRU1BU1xuLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0vL1xuXG5leHBvcnQgY29uc3QgZXZlbnRTY2hlbWEgPSB6Lm9iamVjdCh7XG4gIHRpdGxlOiB6LnN0cmluZygpLm1pbigzLCAnVGl0bGUgbXVzdCBiZSBhdCBsZWFzdCAzIGNoYXJhY3RlcnMnKS5tYXgoMjAwLCAnVGl0bGUgdG9vIGxvbmcnKSxcbiAgZGVzY3JpcHRpb246IHouc3RyaW5nKCkubWF4KDUwMDAsICdEZXNjcmlwdGlvbiB0b28gbG9uZycpLm9wdGlvbmFsKCkubnVsbGFibGUoKSxcbiAgdHlwZTogZXZlbnRUeXBlRW51bSxcbiAgc3RhcnREYXRlOiBkYXRlRmllbGQsXG4gIGVuZERhdGU6IGRhdGVGaWVsZCxcbiAgc3RhcnRUaW1lOiB0aW1lRmllbGQsXG4gIGVuZFRpbWU6IHRpbWVGaWVsZCxcbiAgbG9jYXRpb246IHouc3RyaW5nKCkubWF4KDIwMCwgJ0xvY2F0aW9uIHRvbyBsb25nJykub3B0aW9uYWwoKS5udWxsYWJsZSgpLFxuICB2ZW51ZTogei5zdHJpbmcoKS5tYXgoMjAwLCAnVmVudWUgdG9vIGxvbmcnKS5vcHRpb25hbCgpLm51bGxhYmxlKCksXG4gIG9yZ2FuaXplcklkOiBvcHRpb25hbElkLFxuICBjbGFzc0lkOiBvcHRpb25hbElkLm51bGxhYmxlKCksXG4gIHNlY3Rpb25JZDogb3B0aW9uYWxJZC5udWxsYWJsZSgpLFxuICB2aXNpYmlsaXR5OiBldmVudFZpc2liaWxpdHlFbnVtLmRlZmF1bHQoJ3B1YmxpYycpLFxuICBzdGF0dXM6IGV2ZW50U3RhdHVzRW51bS5kZWZhdWx0KCdzY2hlZHVsZWQnKSxcbiAgY2FwYWNpdHk6IG51bSgpLmludCgpLnBvc2l0aXZlKCdDYXBhY2l0eSBtdXN0IGJlIHBvc2l0aXZlJykub3B0aW9uYWwoKS5udWxsYWJsZSgpLFxuICByZWdpc3RyYXRpb25SZXF1aXJlZDogei5ib29sZWFuKCkuZGVmYXVsdChmYWxzZSksXG4gIHJlZ2lzdHJhdGlvbkRlYWRsaW5lOiBvcHRpb25hbERhdGVGaWVsZC5udWxsYWJsZSgpLFxuICBhdHRhY2htZW50czogei5hbnkoKS5vcHRpb25hbCgpLm51bGxhYmxlKCksXG4gIG5vdGVzOiB6LnN0cmluZygpLm1heCgyMDAwLCAnTm90ZXMgdG9vIGxvbmcnKS5vcHRpb25hbCgpLm51bGxhYmxlKCksXG59KVxuXG5leHBvcnQgY29uc3QgZXZlbnRQYXJ0aWNpcGFudFNjaGVtYSA9IHoub2JqZWN0KHtcbiAgZXZlbnRJZDogb3B0aW9uYWxJZCxcbiAgcGFydGljaXBhbnRJZDogb3B0aW9uYWxJZCxcbiAgcGFydGljaXBhbnRUeXBlOiBwYXJ0aWNpcGFudFR5cGVFbnVtLFxuICBhdHRlbmRhbmNlU3RhdHVzOiBhdHRlbmRhbmNlU3RhdHVzRW51bS5vcHRpb25hbCgpLm51bGxhYmxlKCksXG4gIG5vdGVzOiB6LnN0cmluZygpLm1heCg1MDAsICdOb3RlcyB0b28gbG9uZycpLm9wdGlvbmFsKCkubnVsbGFibGUoKSxcbn0pO1xuXG4vLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PS8vXG4vLyBFWFBFTlNFUyBWQUxJREFUSU9OIFNDSEVNQVNcbi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ly9cblxuZXhwb3J0IGNvbnN0IGV4cGVuc2VTY2hlbWEgPSB6Lm9iamVjdCh7XG4gIGlkOiBvcHRpb25hbElkLFxuICBjYXRlZ29yeTogZXhwZW5zZUNhdGVnb3J5RW51bSxcbiAgdGl0bGU6IHouc3RyaW5nKCkubWluKDMsICdUaXRsZSBtdXN0IGJlIGF0IGxlYXN0IDMgY2hhcmFjdGVycycpLm1heCgyMDAsICdUaXRsZSB0b28gbG9uZycpLFxuICBhbW91bnQ6IG51bSgpLnBvc2l0aXZlKCdBbW91bnQgbXVzdCBiZSBncmVhdGVyIHRoYW4gMCcpLm1heCgxMDAwMDAwMCwgJ0Ftb3VudCB0b28gbGFyZ2UnKSxcbiAgZXhwZW5zZURhdGU6IGRhdGVGaWVsZCxcbiAgcGF5bWVudE1ldGhvZDogcGF5bWVudE1ldGhvZEVudW0ub3B0aW9uYWwoKS5udWxsYWJsZSgpLFxuICBwYXltZW50RGF0ZTogb3B0aW9uYWxEYXRlRmllbGQubnVsbGFibGUoKSxcbiAgdmVuZG9yOiB6LnN0cmluZygpLm1heCgyMDAsICdWZW5kb3IgbmFtZSB0b28gbG9uZycpLm9wdGlvbmFsKCkubnVsbGFibGUoKSxcbiAgaW52b2ljZU51bWJlcjogei5zdHJpbmcoKS5tYXgoMTAwLCAnSW52b2ljZSBudW1iZXIgdG9vIGxvbmcnKS5vcHRpb25hbCgpLm51bGxhYmxlKCksXG4gIHJlY2VpcHROdW1iZXI6IHouc3RyaW5nKCkubWF4KDEwMCwgJ1JlY2VpcHQgbnVtYmVyIHRvbyBsb25nJykub3B0aW9uYWwoKS5udWxsYWJsZSgpLFxuICBjaGVja051bWJlcjogei5zdHJpbmcoKS5tYXgoNTAsICdDaGVjayBudW1iZXIgdG9vIGxvbmcnKS5vcHRpb25hbCgpLm51bGxhYmxlKCksXG4gIHRyYW5zYWN0aW9uUmVmOiB6LnN0cmluZygpLm1heCgxMDAsICdUcmFuc2FjdGlvbiByZWZlcmVuY2UgdG9vIGxvbmcnKS5vcHRpb25hbCgpLm51bGxhYmxlKCksXG4gIHN0YXR1czogZXhwZW5zZVN0YXR1c0VudW0uZGVmYXVsdCgncGVuZGluZycpLFxuICBub3Rlczogei5zdHJpbmcoKS5tYXgoMTAwMCwgJ05vdGVzIHRvbyBsb25nJykub3B0aW9uYWwoKS5udWxsYWJsZSgpLFxufSk7XG5cbmV4cG9ydCBjb25zdCBleHBlbnNlQXBwcm92YWxTY2hlbWEgPSB6Lm9iamVjdCh7XG4gIGFjdGlvbjogei5lbnVtKFsnYXBwcm92ZScsICdyZWplY3QnXSksXG4gIHJlamVjdGlvblJlYXNvbjogei5zdHJpbmcoKS5taW4oMTAsICdSZWplY3Rpb24gcmVhc29uIG11c3QgYmUgYXQgbGVhc3QgMTAgY2hhcmFjdGVycycpLm1heCgxMDAwLCAnUmVqZWN0aW9uIHJlYXNvbiB0b28gbG9uZycpLm9wdGlvbmFsKCkubnVsbGFibGUoKSxcbn0pXG5cbmV4cG9ydCBjb25zdCBleHBlbnNlUGF5bWVudFNjaGVtYSA9IHoub2JqZWN0KHtcbiAgcGF5bWVudE1ldGhvZDogcGF5bWVudE1ldGhvZEVudW0sXG4gIHBheW1lbnREYXRlOiBkYXRlRmllbGQsXG4gIGNoZWNrTnVtYmVyOiB6LnN0cmluZygpLm1heCg1MCwgJ0NoZWNrIG51bWJlciB0b28gbG9uZycpLm9wdGlvbmFsKCkubnVsbGFibGUoKSxcbiAgdHJhbnNhY3Rpb25SZWY6IHouc3RyaW5nKCkubWF4KDEwMCwgJ1RyYW5zYWN0aW9uIHJlZmVyZW5jZSB0b28gbG9uZycpLm9wdGlvbmFsKCkubnVsbGFibGUoKSxcbiAgbm90ZXM6IHouc3RyaW5nKCkubWF4KDEwMDAsICdOb3RlcyB0b28gbG9uZycpLm9wdGlvbmFsKCkubnVsbGFibGUoKSxcbn0pXG5cbi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ly9cbi8vIFRSQU5TUE9SVCBWQUxJREFUSU9OIFNDSEVNQVNcbi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ly9cblxuZXhwb3J0IGNvbnN0IHZlaGljbGVTY2hlbWEgPSB6Lm9iamVjdCh7XG4gIGlkOiBvcHRpb25hbElkLFxuICBuYW1lOiB6LnN0cmluZygpLm1pbigyLCAnVmVoaWNsZSBuYW1lIG11c3QgYmUgYXQgbGVhc3QgMiBjaGFyYWN0ZXJzJykubWF4KDEwMCwgJ1ZlaGljbGUgbmFtZSB0b28gbG9uZycpLFxuICBicmFuZDogei5zdHJpbmcoKS5taW4oMiwgJ0JyYW5kIG11c3QgYmUgYXQgbGVhc3QgMiBjaGFyYWN0ZXJzJykubWF4KDEwMCwgJ0JyYW5kIHRvbyBsb25nJyksXG4gIG1vZGVsOiB6LnN0cmluZygpLm1pbigyLCAnTW9kZWwgbXVzdCBiZSBhdCBsZWFzdCAyIGNoYXJhY3RlcnMnKS5tYXgoMTAwLCAnTW9kZWwgdG9vIGxvbmcnKSxcbiAgeWVhcjogbnVtKCkuaW50KCkubWluKDE5MDAsICdZZWFyIG11c3QgYmUgYWZ0ZXIgMTkwMCcpLm1heChuZXcgRGF0ZSgpLmdldEZ1bGxZZWFyKCkgKyAxLCAnWWVhciBjYW5ub3QgYmUgaW4gZnV0dXJlJyksXG4gIHR5cGU6IHZlaGljbGVUeXBlRW51bS5kZWZhdWx0KCdmdWxsYnVzJyksXG4gIGNhcGFjaXR5OiBudW0oKS5pbnQoKS5taW4oMSwgJ0NhcGFjaXR5IG11c3QgYmUgYXQgbGVhc3QgMScpLm1heCgyMDAsICdDYXBhY2l0eSBjYW5ub3QgZXhjZWVkIDIwMCcpLFxuICBsaWNlbnNlUGxhdGU6IHouc3RyaW5nKCkubWluKDIsICdMaWNlbnNlIHBsYXRlIG11c3QgYmUgYXQgbGVhc3QgMiBjaGFyYWN0ZXJzJykubWF4KDUwLCAnTGljZW5zZSBwbGF0ZSB0b28gbG9uZycpLFxuICBkcml2ZXJJZDogb3B0aW9uYWxJZC5udWxsYWJsZSgpLFxuICBpbWFnZTogei5zdHJpbmcoKS5tYXgoNTAwLCAnSW1hZ2UgcGF0aCB0b28gbG9uZycpLm9wdGlvbmFsKCkubnVsbGFibGUoKS5kZWZhdWx0KCdub3ZlaGljbGUucG5nJyksXG4gIHB1cmNoYXNlRGF0ZTogb3B0aW9uYWxEYXRlRmllbGQubnVsbGFibGUoKSxcbiAgcHVyY2hhc2VQcmljZTogbnVtKCkubWluKDAsICdQdXJjaGFzZSBwcmljZSBtdXN0IGJlIG5vbi1uZWdhdGl2ZScpLm1heCgxMDAwMDAwMCwgJ1B1cmNoYXNlIHByaWNlIHRvbyBsYXJnZScpLm9wdGlvbmFsKCkubnVsbGFibGUoKSxcbiAgaW5pdGlhbE1pbGVhZ2U6IG51bSgpLm1pbigwLCAnSW5pdGlhbCBtaWxlYWdlIG11c3QgYmUgbm9uLW5lZ2F0aXZlJykubWF4KDEwMDAwMDAwLCAnSW5pdGlhbCBtaWxlYWdlIHRvbyBsYXJnZScpLm9wdGlvbmFsKCkubnVsbGFibGUoKSxcbiAgY3VycmVudE1pbGVhZ2U6IG51bSgpLm1pbigwLCAnQ3VycmVudCBtaWxlYWdlIG11c3QgYmUgbm9uLW5lZ2F0aXZlJykubWF4KDEwMDAwMDAwLCAnQ3VycmVudCBtaWxlYWdlIHRvbyBsYXJnZScpLm9wdGlvbmFsKCkubnVsbGFibGUoKSxcbiAgc3RhdHVzOiB2ZWhpY2xlU3RhdHVzRW51bS5kZWZhdWx0KCdhY3RpdmUnKSxcbiAgbm90ZXM6IHouc3RyaW5nKCkubWF4KDEwMDAsICdOb3RlcyB0b28gbG9uZycpLm9wdGlvbmFsKCkubnVsbGFibGUoKSxcbn0pO1xuXG5leHBvcnQgY29uc3QgcmVmdWVsU2NoZW1hID0gei5vYmplY3Qoe1xuICBpZDogb3B0aW9uYWxJZCxcbiAgYnVzSWQ6IG9wdGlvbmFsSWQsXG4gIHJlZnVlbERhdGU6IGRhdGVGaWVsZCxcbiAgcXVhbnRpdHk6IG51bSgpLnBvc2l0aXZlKCdRdWFudGl0eSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAwJykubWF4KDEwMDAwLCAnUXVhbnRpdHkgdG9vIGxhcmdlJyksXG4gIHVuaXRQcmljZTogbnVtKCkucG9zaXRpdmUoJ1VuaXQgcHJpY2UgbXVzdCBiZSBncmVhdGVyIHRoYW4gMCcpLm1heCgxMDAwMDAsICdVbml0IHByaWNlIHRvbyBsYXJnZScpLFxuICB0b3RhbENvc3Q6IG51bSgpLnBvc2l0aXZlKCdUb3RhbCBjb3N0IG11c3QgYmUgZ3JlYXRlciB0aGFuIDAnKS5tYXgoMTAwMDAwMDAsICdUb3RhbCBjb3N0IHRvbyBsYXJnZScpLm9wdGlvbmFsKCksXG4gIGZ1ZWxUeXBlOiBmdWVsVHlwZUVudW0uZGVmYXVsdCgnZGllc2VsJyksXG4gIG9kb21ldGVyOiBudW0oKS5taW4oMCwgJ09kb21ldGVyIG11c3QgYmUgbm9uLW5lZ2F0aXZlJykubWF4KDEwMDAwMDAwLCAnT2RvbWV0ZXIgdmFsdWUgdG9vIGxhcmdlJykub3B0aW9uYWwoKS5udWxsYWJsZSgpLFxuICBmdWVsU3RhdGlvbjogei5zdHJpbmcoKS5tYXgoMjAwLCAnRnVlbCBzdGF0aW9uIG5hbWUgdG9vIGxvbmcnKS5vcHRpb25hbCgpLm51bGxhYmxlKCksXG4gIGludm9pY2VOdW1iZXI6IHouc3RyaW5nKCkubWF4KDEwMCwgJ0ludm9pY2UgbnVtYmVyIHRvbyBsb25nJykub3B0aW9uYWwoKS5udWxsYWJsZSgpLFxuICBwYXltZW50TWV0aG9kOiBwYXltZW50TWV0aG9kRW51bS5vcHRpb25hbCgpLm51bGxhYmxlKCksXG4gIHBhaWRCeTogb3B0aW9uYWxJZC5udWxsYWJsZSgpLFxuICBzdGF0dXM6IHJlZnVlbFN0YXR1c0VudW0uZGVmYXVsdCgnY29tcGxldGVkJyksXG4gIG5vdGVzOiB6LnN0cmluZygpLm1heCgxMDAwLCAnTm90ZXMgdG9vIGxvbmcnKS5vcHRpb25hbCgpLm51bGxhYmxlKCksXG59KTtcblxuLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0vL1xuLy8gU0VUVElOR1MgVkFMSURBVElPTiBTQ0hFTUFcbi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ly9cblxuZXhwb3J0IGNvbnN0IHNldHRpbmdzU2NoZW1hID0gei5vYmplY3Qoe1xuICAvLyBTY2hvb2wgSW5mb3JtYXRpb25cbiAgc2Nob29sTmFtZTogei5zdHJpbmcoKS5taW4oMiwgJ1NjaG9vbCBuYW1lIG11c3QgYmUgYXQgbGVhc3QgMiBjaGFyYWN0ZXJzJykubWF4KDIwMCwgJ1NjaG9vbCBuYW1lIHRvbyBsb25nJyksXG4gIHNjaG9vbEFkZHJlc3M6IHouc3RyaW5nKCkubWF4KDUwMCwgJ1NjaG9vbCBhZGRyZXNzIHRvbyBsb25nJykub3B0aW9uYWwoKSxcbiAgc2Nob29sUGhvbmU6IHBob25lRmllbGQsXG4gIHNjaG9vbEVtYWlsOiBlbWFpbEZpZWxkLFxuICBzY2hvb2xXZWJzaXRlOiB6LnN0cmluZygpLnVybCgnTXVzdCBiZSBhIHZhbGlkIFVSTCcpLm1heCgyNTUsICdTY2hvb2wgd2Vic2l0ZSBVUkwgdG9vIGxvbmcnKS5vcHRpb25hbCgpLCAvLyBOZXdcbiAgc2Nob29sTG9nbzogei5zdHJpbmcoKS51cmwoJ011c3QgYmUgYSB2YWxpZCBpbWFnZSBVUkwnKS5tYXgoMjU1LCAnU2Nob29sIGxvZ28gVVJMIHRvbyBsb25nJykub3B0aW9uYWwoKSwgLy8gTmV3XG4gIGN1cnJlbnRBY2FkZW1pY1llYXI6IGFjYWRlbWljWWVhckZpZWxkLFxuXG4gIC8vIEFjYWRlbWljIFNldHRpbmdzXG4gIGdyYWRpbmdTY2FsZTogei5hbnkoKS5vcHRpb25hbCgpLFxuICBhdHRlbmRhbmNlUmVxdWlyZW1lbnQ6IG51bSgpLm1pbigwLCAnQXR0ZW5kYW5jZSByZXF1aXJlbWVudCBtdXN0IGJlIG5vbi1uZWdhdGl2ZScpLm1heCgxMDAsICdBdHRlbmRhbmNlIHJlcXVpcmVtZW50IGNhbm5vdCBleGNlZWQgMTAwJykuZGVmYXVsdCg3NS4wMCksXG4gIG1heENsYXNzU2l6ZTogbnVtKCkuaW50KCdNYXggY2xhc3Mgc2l6ZSBtdXN0IGJlIGFuIGludGVnZXInKS5taW4oMSwgJ01heCBjbGFzcyBzaXplIG11c3QgYmUgYXQgbGVhc3QgMScpLm1heCgyMDAsICdNYXggY2xhc3Mgc2l6ZSBjYW5ub3QgZXhjZWVkIDIwMCcpLmRlZmF1bHQoMzQpLFxuICBtaW5pbXVtUGFzc2luZ0dyYWRlOiBudW0oKS5taW4oMCwgJ01pbmltdW0gcGFzc2luZyBncmFkZSBtdXN0IGJlIG5vbi1uZWdhdGl2ZScpLm1heCgxMDAsICdNaW5pbXVtIHBhc3NpbmcgZ3JhZGUgY2Fubm90IGV4Y2VlZCAxMDAnKS5kZWZhdWx0KDYwLjAwKSxcbiAgZGVmYXVsdEV4YW1EdXJhdGlvbjogbnVtKCkuaW50KCdEZWZhdWx0IGV4YW0gZHVyYXRpb24gbXVzdCBiZSBpbiBtaW51dGVzJykubWluKDE1LCAnRXhhbSBkdXJhdGlvbiBtdXN0IGJlIGF0IGxlYXN0IDE1IG1pbnV0ZXMnKS5tYXgoNDgwLCAnRXhhbSBkdXJhdGlvbiBjYW5ub3QgZXhjZWVkIDQ4MCBtaW51dGVzJykuZGVmYXVsdCgxMjApLFxuICBjYWxlbmRhclN5c3RlbTogY2FsZW5kYXJTeXN0ZW1FbnVtLmRlZmF1bHQoJ1NFTUVTVEVSJyksXG4gIHN0YXJ0TW9udGg6IHouc3RyaW5nKCkuZGVmYXVsdCgnc2VwdGVtYmVyJyksXG4gIGVuZE1vbnRoOiB6LnN0cmluZygpLmRlZmF1bHQoJ2p1bmUnKSxcblxuICAvLyBOb3RpZmljYXRpb24gU2V0dGluZ3NcbiAgYWNhZGVtaWNBbGVydHM6IHouYm9vbGVhbigpLmRlZmF1bHQodHJ1ZSksXG4gIGF0dGVuZGFuY2VBbGVydHM6IHouYm9vbGVhbigpLmRlZmF1bHQodHJ1ZSksXG4gIGV2ZW50QWxlcnRzOiB6LmJvb2xlYW4oKS5kZWZhdWx0KHRydWUpLFxuICBob21ld29ya0FsZXJ0czogei5ib29sZWFuKCkuZGVmYXVsdCh0cnVlKSxcbiAgZmVlc1JlbWluZGVyOiB6LmJvb2xlYW4oKS5kZWZhdWx0KHRydWUpLFxuICBmZWVzT3ZlcmR1ZUFsZXJ0czogei5ib29sZWFuKCkuZGVmYXVsdCh0cnVlKSxcbiAgZW1haWxOb3RpZmljYXRpb25zOiB6LmJvb2xlYW4oKS5kZWZhdWx0KHRydWUpLFxuICBzbXNOb3RpZmljYXRpb25zOiB6LmJvb2xlYW4oKS5kZWZhdWx0KGZhbHNlKSxcbiAgcGFyZW50Tm90aWZpY2F0aW9uczogei5ib29sZWFuKCkuZGVmYXVsdCh0cnVlKSxcbiAgbG93R3JhZGVBbGVydHM6IHouYm9vbGVhbigpLmRlZmF1bHQodHJ1ZSksXG4gIGFsbG93TGF0ZVN1Ym1pc3Npb246IHouYm9vbGVhbigpLmRlZmF1bHQodHJ1ZSksXG4gIGV4YW1SZXN1bHRzQWxlcnRzOiB6LmJvb2xlYW4oKS5kZWZhdWx0KHRydWUpLFxuICBkaXNjaXBsaW5hcnlBbGVydHM6IHouYm9vbGVhbigpLmRlZmF1bHQodHJ1ZSksXG4gIGFjaGlldmVtZW50QWxlcnRzOiB6LmJvb2xlYW4oKS5kZWZhdWx0KHRydWUpLFxuICBtYWludGVuYW5jZU5vdGlmaWNhdGlvbnM6IHouYm9vbGVhbigpLmRlZmF1bHQodHJ1ZSksXG5cbiAgLy8gU2VjdXJpdHkgU2V0dGluZ3NcbiAgdHdvRmFjdG9yRW5hYmxlZDogei5ib29sZWFuKCkuZGVmYXVsdChmYWxzZSksXG4gIHNlc3Npb25UaW1lb3V0OiB6LnN0cmluZygpLnJlZ2V4KC9eXFxkezEsNH0kLywgJ1Nlc3Npb24gdGltZW91dCBtdXN0IGJlIGEgbnVtYmVyIGJldHdlZW4gMS05OTk5IG1pbnV0ZXMnKS5kZWZhdWx0KCc2MCcpLFxuICBwYXNzd29yZFJlcXVpcmVTeW1ib2xzOiB6LmJvb2xlYW4oKS5kZWZhdWx0KHRydWUpLFxuICBsb2dpbk5vdGlmaWNhdGlvbnM6IHouYm9vbGVhbigpLmRlZmF1bHQodHJ1ZSksXG4gIHBhcmVudEFjY2Vzc0VuYWJsZWQ6IHouYm9vbGVhbigpLmRlZmF1bHQodHJ1ZSksXG4gIHRlYWNoZXJBY2Nlc3NFbmFibGVkOiB6LmJvb2xlYW4oKS5kZWZhdWx0KHRydWUpLFxuICBzdHVkZW50QWNjZXNzRW5hYmxlZDogei5ib29sZWFuKCkuZGVmYXVsdCh0cnVlKSxcblxuICAvLyBTeXN0ZW0gUHJlZmVyZW5jZXNcbiAgdGltZVpvbmU6IHouc3RyaW5nKCkubWluKDEsICdUaW1lIHpvbmUgaXMgcmVxdWlyZWQnKS5kZWZhdWx0KCdVVEMnKSxcbiAgbGFuZ3VhZ2U6IGxhbmd1YWdlRW51bS5kZWZhdWx0KCdlbicpLFxuICB0aGVtZTogei5lbnVtKFsnbGlnaHQnLCAnZGFyaycsICdzeXN0ZW0nXSkuZGVmYXVsdCgnc3lzdGVtJyksXG4gIGRhdGVGb3JtYXQ6IHouZW51bShbJ1lZWVktTU0tREQnLCAnTU0vREQvWVlZWScsICdERC9NTS9ZWVlZJywgJ0RELU1NLVlZJywgJ0RELU1NLVlZWVknXSkuZGVmYXVsdCgnTU0vREQvWVlZWScpLCAvLyBBZGp1c3RlZCBkZWZhdWx0IHRvIG1hdGNoIHRhYmxlXG4gIHRpbWVGb3JtYXQ6IHouZW51bShbJzEyJywgJzI0J10pLmRlZmF1bHQoJzEyJyksXG4gIGN1cnJlbmN5OiB6LnN0cmluZygpLmxlbmd0aCgzLCAnQ3VycmVuY3kgbXVzdCBiZSBhIDMtbGV0dGVyIElTTyBjb2RlJykucmVnZXgoL15bQS1aXXszfSQvLCAnQ3VycmVuY3kgbXVzdCBiZSB1cHBlcmNhc2UgSVNPIGNvZGUnKS5kZWZhdWx0KCdVU0QnKSxcblxuICAvLyBBY2FkZW1pYyBDYWxlbmRhciBTZXR0aW5nc1xuICBncmFkaW5nUGVyaW9kczogbnVtKCkuaW50KCdHcmFkaW5nIHBlcmlvZHMgbXVzdCBiZSBhbiBpbnRlZ2VyJykubWluKDEsICdHcmFkaW5nIHBlcmlvZHMgbXVzdCBiZSBhdCBsZWFzdCAxJykubWF4KDEyLCAnR3JhZGluZyBwZXJpb2RzIGNhbm5vdCBleGNlZWQgMTInKS5kZWZhdWx0KDQpLFxuICBzY2hvb2xTdGFydFRpbWU6IHouc3RyaW5nKCkucmVnZXgoL14oWzAxXT9bMC05XXwyWzAtM10pOlswLTVdWzAtOV0kLywgJ0ludmFsaWQgc3RhcnQgdGltZSBmb3JtYXQgKEhIOk1NKScpLmRlZmF1bHQoJzA4OjAwJyksXG4gIHNjaG9vbEVuZFRpbWU6IHouc3RyaW5nKCkucmVnZXgoL14oWzAxXT9bMC05XXwyWzAtM10pOlswLTVdWzAtOV0kLywgJ0ludmFsaWQgZW5kIHRpbWUgZm9ybWF0IChISDpNTSknKS5kZWZhdWx0KCcxNTowMCcpLFxuICBsdW5jaEJyZWFrRHVyYXRpb246IG51bSgpLmludCgnTHVuY2ggYnJlYWsgZHVyYXRpb24gbXVzdCBiZSBpbiBtaW51dGVzJykubWluKDE1LCAnTHVuY2ggYnJlYWsgbXVzdCBiZSBhdCBsZWFzdCAxNSBtaW51dGVzJykubWF4KDEyMCwgJ0x1bmNoIGJyZWFrIGNhbm5vdCBleGNlZWQgMTIwIG1pbnV0ZXMnKS5kZWZhdWx0KDMwKSxcblxuICAvLyBNYWludGVuYW5jZSAmIEJhY2t1cCBTZXR0aW5nc1xuICBtYWludGVuYW5jZU1vZGU6IHouYm9vbGVhbigpLmRlZmF1bHQoZmFsc2UpLFxuICBhdXRvQmFja3VwOiB6LmJvb2xlYW4oKS5kZWZhdWx0KHRydWUpLFxuXG59KTtcblxuLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0vL1xuLy8gVVRJTElUWSBTQ0hFTUFTXG4vLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PS8vXG5cbmV4cG9ydCBjb25zdCBpZFBhcmFtU2NoZW1hID0gei5vYmplY3Qoe1xuICBpZDogb3B0aW9uYWxJZCxcbn0pO1xuXG5leHBvcnQgY29uc3QgcGFnaW5hdGlvblNjaGVtYSA9IHoub2JqZWN0KHtcbiAgcGFnZTogbnVtKCkuaW50KCkubWluKDEpLmRlZmF1bHQoMSksXG4gIGxpbWl0OiBudW0oKS5pbnQoKS5taW4oMSkubWF4KDEwMCkuZGVmYXVsdCgxMCksXG59KTtcblxuZXhwb3J0IGNvbnN0IGRhdGVSYW5nZVNjaGVtYSA9IHoub2JqZWN0KHtcbiAgZGF0ZUZyb206IGRhdGVGaWVsZCxcbiAgZGF0ZVRvOiBkYXRlRmllbGQsXG59KVxuXG4iLAogICAgIi8vIGxpYi92YWxpZGF0aW9ucy9lbnVtcy5qc1xyXG5pbXBvcnQgeyB6IH0gZnJvbSAnem9kJ1xyXG5pbXBvcnQgeyBFTlVNUyB9IGZyb20gJy4vRU5VTVMnXHJcblxyXG5jb25zdCBjcmVhdGVab2RFbnVtID0gKGVudW1LZXkpID0+IHtcclxuICBjb25zdCB2YWx1ZXMgPSBFTlVNU1tlbnVtS2V5XT8udmFsdWVzXHJcbiAgaWYgKCF2YWx1ZXMpIHRocm93IG5ldyBFcnJvcihgRW51bSAke2VudW1LZXl9IG5vdCBmb3VuZGApXHJcbiAgcmV0dXJuIHouZW51bSh2YWx1ZXMpXHJcbn1cclxuXHJcbi8vIENvcmUgU3lzdGVtXHJcbmV4cG9ydCBjb25zdCB1c2VyVHlwZUVudW0gPSBjcmVhdGVab2RFbnVtKCd1c2VyVHlwZScpXHJcbmV4cG9ydCBjb25zdCB1c2VyU3RhdHVzRW51bSA9IGNyZWF0ZVpvZEVudW0oJ3VzZXJTdGF0dXMnKVxyXG5leHBvcnQgY29uc3QgdG9rZW5TdGF0dXNFbnVtID0gY3JlYXRlWm9kRW51bSgndG9rZW5TdGF0dXMnKVxyXG5leHBvcnQgY29uc3QgdG9rZW5UeXBlRW51bSA9IGNyZWF0ZVpvZEVudW0oJ3Rva2VuVHlwZScpXHJcbmV4cG9ydCBjb25zdCBmaWxlU3RhdHVzRW51bSA9IGNyZWF0ZVpvZEVudW0oJ2ZpbGVTdGF0dXMnKVxyXG5cclxuLy8gRWR1Y2F0aW9uYWwgU3lzdGVtXHJcbmV4cG9ydCBjb25zdCBnZW5kZXJFbnVtID0gY3JlYXRlWm9kRW51bSgnZ2VuZGVyJylcclxuZXhwb3J0IGNvbnN0IHN0dWRlbnRTdGF0dXNFbnVtID0gY3JlYXRlWm9kRW51bSgnc3R1ZGVudFN0YXR1cycpXHJcbmV4cG9ydCBjb25zdCB0ZWFjaGVyU3RhdHVzRW51bSA9IGNyZWF0ZVpvZEVudW0oJ3RlYWNoZXJTdGF0dXMnKVxyXG5leHBvcnQgY29uc3QgZW1wbG95bWVudFR5cGVFbnVtID0gY3JlYXRlWm9kRW51bSgnZW1wbG95bWVudFR5cGUnKVxyXG5leHBvcnQgY29uc3QgcmVsYXRpb25zaGlwVHlwZUVudW0gPSBjcmVhdGVab2RFbnVtKCdyZWxhdGlvbnNoaXBUeXBlJylcclxuZXhwb3J0IGNvbnN0IHNlbWVzdGVyRW51bSA9IGNyZWF0ZVpvZEVudW0oJ3NlbWVzdGVyJylcclxuZXhwb3J0IGNvbnN0IGNsYXNzU3RhdHVzRW51bSA9IGNyZWF0ZVpvZEVudW0oJ2NsYXNzU3RhdHVzJylcclxuZXhwb3J0IGNvbnN0IHNlY3Rpb25TdGF0dXNFbnVtID0gY3JlYXRlWm9kRW51bSgnc2VjdGlvblN0YXR1cycpXHJcbmV4cG9ydCBjb25zdCBsYW5ndWFnZUVudW0gPSBjcmVhdGVab2RFbnVtKCdsYW5ndWFnZScpXHJcbmV4cG9ydCBjb25zdCBlbnJvbGxtZW50U3RhdHVzRW51bSA9IGNyZWF0ZVpvZEVudW0oJ2Vucm9sbG1lbnRTdGF0dXMnKVxyXG5leHBvcnQgY29uc3QgYXNzaWdubWVudFN0YXR1c0VudW0gPSBjcmVhdGVab2RFbnVtKCdhc3NpZ25tZW50U3RhdHVzJylcclxuZXhwb3J0IGNvbnN0IGNhbGVuZGFyU3lzdGVtRW51bSA9IGNyZWF0ZVpvZEVudW0oJ2NhbGVuZGFyU3lzdGVtJylcclxuXHJcbi8vIEFzc2Vzc21lbnQgJiBFeGFtc1xyXG5leHBvcnQgY29uc3QgYXNzZXNzbWVudFR5cGVFbnVtID0gY3JlYXRlWm9kRW51bSgnYXNzZXNzbWVudFR5cGUnKVxyXG5leHBvcnQgY29uc3QgYXNzZXNzbWVudFN0YXR1c0VudW0gPSBjcmVhdGVab2RFbnVtKCdhc3Nlc3NtZW50U3RhdHVzJylcclxuZXhwb3J0IGNvbnN0IHN1Ym1pc3Npb25UeXBlRW51bSA9IGNyZWF0ZVpvZEVudW0oJ3N1Ym1pc3Npb25UeXBlJylcclxuZXhwb3J0IGNvbnN0IGV4YW1UeXBlRW51bSA9IGNyZWF0ZVpvZEVudW0oJ2V4YW1UeXBlJylcclxuZXhwb3J0IGNvbnN0IGV4YW1TZWN1cml0eUVudW0gPSBjcmVhdGVab2RFbnVtKCdleGFtU2VjdXJpdHknKVxyXG5leHBvcnQgY29uc3QgZXhhbVN0YXR1c0VudW0gPSBjcmVhdGVab2RFbnVtKCdleGFtU3RhdHVzJylcclxuZXhwb3J0IGNvbnN0IGdyYWRlU3RhdHVzRW51bSA9IGNyZWF0ZVpvZEVudW0oJ2dyYWRlU3RhdHVzJylcclxuZXhwb3J0IGNvbnN0IGF0dGVuZGFuY2VTdGF0dXNFbnVtID0gY3JlYXRlWm9kRW51bSgnYXR0ZW5kYW5jZVN0YXR1cycpXHJcbmV4cG9ydCBjb25zdCBwcm9maWNpZW5jeUxldmVsRW51bSA9IGNyZWF0ZVpvZEVudW0oJ3Byb2ZpY2llbmN5TGV2ZWwnKVxyXG5leHBvcnQgY29uc3QgZGF5T2ZXZWVrRW51bSA9IGNyZWF0ZVpvZEVudW0oJ2RheU9mV2VlaycpXHJcblxyXG4vLyBBbGVydHNcclxuZXhwb3J0IGNvbnN0IGFsZXJ0VHlwZUVudW0gPSBjcmVhdGVab2RFbnVtKCdhbGVydFR5cGUnKVxyXG5leHBvcnQgY29uc3QgYWxlcnRQcmlvcml0eUVudW0gPSBjcmVhdGVab2RFbnVtKCdhbGVydFByaW9yaXR5JylcclxuZXhwb3J0IGNvbnN0IGFsZXJ0U3RhdHVzRW51bSA9IGNyZWF0ZVpvZEVudW0oJ2FsZXJ0U3RhdHVzJylcclxuXHJcbi8vIEZlZXMgJiBQYXltZW50c1xyXG5leHBvcnQgY29uc3QgZmVlVHlwZVN0YXR1c0VudW0gPSBjcmVhdGVab2RFbnVtKCdmZWVUeXBlU3RhdHVzJylcclxuZXhwb3J0IGNvbnN0IHBheW1lbnRUeXBlRW51bSA9IGNyZWF0ZVpvZEVudW0oJ3BheW1lbnRUeXBlJylcclxuZXhwb3J0IGNvbnN0IHNjaGVkdWxlRW51bSA9IGNyZWF0ZVpvZEVudW0oJ3NjaGVkdWxlJylcclxuZXhwb3J0IGNvbnN0IGZlZVN0YXR1c0VudW0gPSBjcmVhdGVab2RFbnVtKCdmZWVTdGF0dXMnKVxyXG5leHBvcnQgY29uc3QgZmVlSW5zdGFsbG1lbnRTdGF0dXNFbnVtID0gY3JlYXRlWm9kRW51bSgnZmVlSW5zdGFsbG1lbnRTdGF0dXMnKVxyXG5leHBvcnQgY29uc3QgcGF5bWVudE1ldGhvZEVudW0gPSBjcmVhdGVab2RFbnVtKCdwYXltZW50TWV0aG9kJylcclxuZXhwb3J0IGNvbnN0IHBheW1lbnRTdGF0dXNFbnVtID0gY3JlYXRlWm9kRW51bSgncGF5bWVudFN0YXR1cycpXHJcblxyXG4vLyBFdmVudHNcclxuZXhwb3J0IGNvbnN0IGV2ZW50VHlwZUVudW0gPSBjcmVhdGVab2RFbnVtKCdldmVudFR5cGUnKVxyXG5leHBvcnQgY29uc3QgZXZlbnRTdGF0dXNFbnVtID0gY3JlYXRlWm9kRW51bSgnZXZlbnRTdGF0dXMnKVxyXG5leHBvcnQgY29uc3QgZXZlbnRWaXNpYmlsaXR5RW51bSA9IGNyZWF0ZVpvZEVudW0oJ2V2ZW50VmlzaWJpbGl0eScpXHJcbmV4cG9ydCBjb25zdCBwYXJ0aWNpcGFudFR5cGVFbnVtID0gY3JlYXRlWm9kRW51bSgncGFydGljaXBhbnRUeXBlJylcclxuXHJcbi8vIEV4cGVuc2VzXHJcbmV4cG9ydCBjb25zdCBleHBlbnNlQ2F0ZWdvcnlFbnVtID0gY3JlYXRlWm9kRW51bSgnZXhwZW5zZUNhdGVnb3J5JylcclxuZXhwb3J0IGNvbnN0IGV4cGVuc2VTdGF0dXNFbnVtID0gY3JlYXRlWm9kRW51bSgnZXhwZW5zZVN0YXR1cycpXHJcblxyXG4vLyBUcmFja2VyXHJcbmV4cG9ydCBjb25zdCB0cmFja2VyTW9kZUVudW0gPSBjcmVhdGVab2RFbnVtKCd0cmFja2VyTW9kZScpXHJcblxyXG4vLyBUcmFuc3BvcnRcclxuZXhwb3J0IGNvbnN0IGRyaXZlclN0YXR1c0VudW0gPSBjcmVhdGVab2RFbnVtKCdkcml2ZXJTdGF0dXMnKVxyXG5leHBvcnQgY29uc3QgdmVoaWNsZVN0YXR1c0VudW0gPSBjcmVhdGVab2RFbnVtKCd2ZWhpY2xlU3RhdHVzJylcclxuZXhwb3J0IGNvbnN0IHZlaGljbGVUeXBlRW51bSA9IGNyZWF0ZVpvZEVudW0oJ3ZlaGljbGVUeXBlJylcclxuZXhwb3J0IGNvbnN0IHZlaGljbGVEb2N1bWVudFR5cGVFbnVtID0gY3JlYXRlWm9kRW51bSgndmVoaWNsZURvY3VtZW50VHlwZScpXHJcbmV4cG9ydCBjb25zdCBidXNTdGF0dXNFbnVtID0gY3JlYXRlWm9kRW51bSgnYnVzU3RhdHVzJylcclxuZXhwb3J0IGNvbnN0IHJlZnVlbFN0YXR1c0VudW0gPSBjcmVhdGVab2RFbnVtKCdyZWZ1ZWxTdGF0dXMnKVxyXG5leHBvcnQgY29uc3QgZnVlbFR5cGVFbnVtID0gY3JlYXRlWm9kRW51bSgnZnVlbFR5cGUnKVxyXG5leHBvcnQgY29uc3QgbWFpbnRlbmFuY2VUeXBlRW51bSA9IGNyZWF0ZVpvZEVudW0oJ21haW50ZW5hbmNlVHlwZScpXHJcbmV4cG9ydCBjb25zdCBtYWludGVuYW5jZVN0YXR1c0VudW0gPSBjcmVhdGVab2RFbnVtKCdtYWludGVuYW5jZVN0YXR1cycpXHJcblxyXG4vLyBQZXJzb25hbFxyXG5leHBvcnQgY29uc3QgbWFyaXRhbFN0YXR1c0VudW0gPSBjcmVhdGVab2RFbnVtKCdtYXJpdGFsU3RhdHVzJykiLAogICAgIlxuXG5pbXBvcnQgeyBwZXJtaXNzaW9uc1RhYmxlLCByb2xlUGVybWlzc2lvbnNUYWJsZSwgcm9sZXNUYWJsZSB9IGZyb20gJ0AvZGF0YWJhc2Uvc2NoZW1hJztcbmltcG9ydCB7IGVxLCBhbmQgfSBmcm9tICdkcml6emxlLW9ybSc7XG5pbXBvcnQgeyBSZXBvc2l0b3J5LCBEQiB9IGZyb20gJ25ham0tYXBpJztcblxuQFJlcG9zaXRvcnkoKVxuZXhwb3J0IGNsYXNzIFBlcm1pc3Npb25SZXBvc2l0b3J5IHtcbiAgZGVjbGFyZSBkYjogREI7XG5cbiAgYXN5bmMgZ2V0QWxsKCkge1xuICAgIHJldHVybiBhd2FpdCB0aGlzLmRiLnNlbGVjdCgpLmZyb20ocGVybWlzc2lvbnNUYWJsZSk7XG4gIH1cblxuICBhc3luYyBnZXRCeUlkKGlkOiBzdHJpbmcpIHtcbiAgICBjb25zdCBbZXhpc3RpbmdQZXJtaXNzaW9uXSA9IGF3YWl0IHRoaXMuZGJcbiAgICAgIC5zZWxlY3QoKVxuICAgICAgLmZyb20ocGVybWlzc2lvbnNUYWJsZSlcbiAgICAgIC53aGVyZShlcShwZXJtaXNzaW9uc1RhYmxlLmlkLCBpZCkpO1xuICAgIHJldHVybiBleGlzdGluZ1Blcm1pc3Npb247XG4gIH1cblxuICBhc3luYyBnZXRCeU5hbWUobmFtZTogc3RyaW5nKSB7XG4gICAgY29uc3QgW2V4aXN0aW5nUGVybWlzc2lvbl0gPSBhd2FpdCB0aGlzLmRiXG4gICAgICAuc2VsZWN0KClcbiAgICAgIC5mcm9tKHBlcm1pc3Npb25zVGFibGUpXG4gICAgICAud2hlcmUoZXEocGVybWlzc2lvbnNUYWJsZS5uYW1lLCBuYW1lKSk7XG4gICAgcmV0dXJuIGV4aXN0aW5nUGVybWlzc2lvbjtcbiAgfVxuXG4gIGFzeW5jIGNyZWF0ZShkYXRhKSB7XG4gICAgY29uc3QgW25ld1Blcm1pc3Npb25dID0gYXdhaXQgdGhpcy5kYlxuICAgICAgLmluc2VydChwZXJtaXNzaW9uc1RhYmxlKVxuICAgICAgLnZhbHVlcyhkYXRhKVxuICAgICAgLnJldHVybmluZygpO1xuICAgIHJldHVybiBuZXdQZXJtaXNzaW9uO1xuICB9XG5cbiAgYXN5bmMgdXBkYXRlKGlkOiBzdHJpbmcsIGRhdGEpIHtcbiAgICBjb25zdCBbdXBkYXRlZFBlcm1pc3Npb25dID0gYXdhaXQgdGhpcy5kYlxuICAgICAgLnVwZGF0ZShwZXJtaXNzaW9uc1RhYmxlKVxuICAgICAgLnNldChkYXRhKVxuICAgICAgLndoZXJlKGVxKHBlcm1pc3Npb25zVGFibGUuaWQsIGlkKSlcbiAgICAgIC5yZXR1cm5pbmcoKTtcbiAgICByZXR1cm4gdXBkYXRlZFBlcm1pc3Npb247XG4gIH1cblxuICBhc3luYyBkZWxldGUoaWQ6IHN0cmluZykge1xuICAgIGNvbnN0IFtkZWxldGVkUGVybWlzc2lvbl0gPSBhd2FpdCB0aGlzLmRiXG4gICAgICAuZGVsZXRlKHBlcm1pc3Npb25zVGFibGUpXG4gICAgICAud2hlcmUoZXEocGVybWlzc2lvbnNUYWJsZS5pZCwgaWQpKVxuICAgICAgLnJldHVybmluZygpO1xuICAgIHJldHVybiBkZWxldGVkUGVybWlzc2lvbjtcbiAgfVxuXG4gIGFzeW5jIGdldFBlcm1pc3Npb25zQnlSb2xlKHJvbGVJZDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuZGJcbiAgICAgIC5zZWxlY3Qoe1xuICAgICAgICBpZDogcGVybWlzc2lvbnNUYWJsZS5pZCxcbiAgICAgICAgbmFtZTogcGVybWlzc2lvbnNUYWJsZS5uYW1lLFxuICAgICAgICBkZXNjcmlwdGlvbjogcGVybWlzc2lvbnNUYWJsZS5kZXNjcmlwdGlvbixcbiAgICAgICAgcmVzb3VyY2U6IHBlcm1pc3Npb25zVGFibGUucmVzb3VyY2UsXG4gICAgICAgIGFjdGlvbjogcGVybWlzc2lvbnNUYWJsZS5hY3Rpb24sXG4gICAgICB9KVxuICAgICAgLmZyb20ocm9sZVBlcm1pc3Npb25zVGFibGUpXG4gICAgICAubGVmdEpvaW4ocGVybWlzc2lvbnNUYWJsZSwgZXEocm9sZVBlcm1pc3Npb25zVGFibGUucGVybWlzc2lvbklkLCBwZXJtaXNzaW9uc1RhYmxlLmlkKSlcbiAgICAgIC53aGVyZShlcShyb2xlUGVybWlzc2lvbnNUYWJsZS5yb2xlSWQsIHJvbGVJZCkpO1xuICB9XG5cbiAgYXN5bmMgZ2V0Um9sZXNCeVBlcm1pc3Npb24ocGVybWlzc2lvbklkOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5kYlxuICAgICAgLnNlbGVjdCh7XG4gICAgICAgIGlkOiByb2xlc1RhYmxlLmlkLFxuICAgICAgICBuYW1lOiByb2xlc1RhYmxlLm5hbWUsXG4gICAgICAgIGRlc2NyaXB0aW9uOiByb2xlc1RhYmxlLmRlc2NyaXB0aW9uLFxuICAgICAgfSlcbiAgICAgIC5mcm9tKHJvbGVQZXJtaXNzaW9uc1RhYmxlKVxuICAgICAgLmxlZnRKb2luKHJvbGVzVGFibGUsIGVxKHJvbGVQZXJtaXNzaW9uc1RhYmxlLnJvbGVJZCwgcm9sZXNUYWJsZS5pZCkpXG4gICAgICAud2hlcmUoZXEocm9sZVBlcm1pc3Npb25zVGFibGUucGVybWlzc2lvbklkLCBwZXJtaXNzaW9uSWQpKTtcbiAgfVxuXG4gIGFzeW5jIGFzc2lnblBlcm1pc3Npb25Ub1JvbGUocm9sZUlkOiBzdHJpbmcsIHBlcm1pc3Npb25JZDogc3RyaW5nKSB7XG4gICAgY29uc3QgW25ld1JvbGVQZXJtaXNzaW9uXSA9IGF3YWl0IHRoaXMuZGJcbiAgICAgIC5pbnNlcnQocm9sZVBlcm1pc3Npb25zVGFibGUpXG4gICAgICAudmFsdWVzKHsgcm9sZUlkLCBwZXJtaXNzaW9uSWQgfSlcbiAgICAgIC5yZXR1cm5pbmcoKTtcbiAgICByZXR1cm4gbmV3Um9sZVBlcm1pc3Npb247XG4gIH1cblxuICBhc3luYyByZW1vdmVQZXJtaXNzaW9uRnJvbVJvbGUocm9sZUlkOiBzdHJpbmcsIHBlcm1pc3Npb25JZDogc3RyaW5nKSB7XG4gICAgY29uc3QgW2RlbGV0ZWRSb2xlUGVybWlzc2lvbl0gPSBhd2FpdCB0aGlzLmRiXG4gICAgICAuZGVsZXRlKHJvbGVQZXJtaXNzaW9uc1RhYmxlKVxuICAgICAgLndoZXJlKGFuZChlcShyb2xlUGVybWlzc2lvbnNUYWJsZS5yb2xlSWQsIHJvbGVJZCksIGVxKHJvbGVQZXJtaXNzaW9uc1RhYmxlLnBlcm1pc3Npb25JZCwgcGVybWlzc2lvbklkKSkpXG4gICAgICAucmV0dXJuaW5nKCk7XG4gICAgcmV0dXJuIGRlbGV0ZWRSb2xlUGVybWlzc2lvbjtcbiAgfVxuXG4gIGFzeW5jIGNoZWNrUm9sZUhhc1Blcm1pc3Npb24ocm9sZUlkOiBzdHJpbmcsIHBlcm1pc3Npb25JZDogc3RyaW5nKSB7XG4gICAgY29uc3QgW3JvbGVQZXJtaXNzaW9uXSA9IGF3YWl0IHRoaXMuZGJcbiAgICAgIC5zZWxlY3QoKVxuICAgICAgLmZyb20ocm9sZVBlcm1pc3Npb25zVGFibGUpXG4gICAgICAud2hlcmUoYW5kKGVxKHJvbGVQZXJtaXNzaW9uc1RhYmxlLnJvbGVJZCwgcm9sZUlkKSwgZXEocm9sZVBlcm1pc3Npb25zVGFibGUucGVybWlzc2lvbklkLCBwZXJtaXNzaW9uSWQpKSk7XG4gICAgcmV0dXJuICEhcm9sZVBlcm1pc3Npb247XG4gIH1cblxuICBhc3luYyBkZWxldGVBbGwoKSB7XG4gICAgLy8gRmlyc3QgZGVsZXRlIGFsbCByb2xlLXBlcm1pc3Npb24gcmVsYXRpb25zaGlwc1xuICAgIGF3YWl0IHRoaXMuZGIuZGVsZXRlKHJvbGVQZXJtaXNzaW9uc1RhYmxlKTtcblxuICAgIC8vIFRoZW4gZGVsZXRlIGFsbCBwZXJtaXNzaW9uc1xuICAgIGNvbnN0IGRlbGV0ZWRQZXJtaXNzaW9ucyA9IGF3YWl0IHRoaXMuZGJcbiAgICAgIC5kZWxldGUocGVybWlzc2lvbnNUYWJsZSlcbiAgICAgIC5yZXR1cm5pbmcoKTtcblxuICAgIHJldHVybiBkZWxldGVkUGVybWlzc2lvbnM7XG4gIH1cbn0iLAogICAgImltcG9ydCB7IGNyZWF0ZUd1YXJkLCBJbmplY3RhYmxlLCBHdWFyZFBhcmFtcywgSGVhZGVycywgQ3R4IH0gZnJvbSBcIm5ham0tYXBpXCI7XG5pbXBvcnQgeyBUb2tlblNlcnZpY2UgfSBmcm9tIFwiLi4vdG9rZW5zXCI7XG5cblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIFBlcm1pc3Npb25HdWFyZHMge1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHRva2VuU2VydmljZTogVG9rZW5TZXJ2aWNlKSB7IH1cblxuICBwcml2YXRlIGFzeW5jIGdldFVzZXJQZXJtaXNzaW9ucyhhdXRoKSB7XG4gICAgY29uc3QgcGVybWlzc2lvbnMgPSBhd2FpdCB0aGlzLnRva2VuU2VydmljZS5nZXRVc2VyUGVybWlzc2lvbnMoYXV0aCk7XG4gICAgaWYgKCFwZXJtaXNzaW9ucyB8fCAhQXJyYXkuaXNBcnJheShwZXJtaXNzaW9ucykpIHJldHVybiBudWxsO1xuICAgIHJldHVybiBwZXJtaXNzaW9ucztcbiAgfVxuXG4gIHByaXZhdGUgY2hlY2tQZXJtaXNzaW9uTWF0Y2gocGVybWlzc2lvbnM6IHN0cmluZ1tdLCByZXF1aXJlZFBlcm1pc3Npb246IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGlmIChwZXJtaXNzaW9ucy5pbmNsdWRlcyhyZXF1aXJlZFBlcm1pc3Npb24pKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBjb25zdCBbcmVxdWlyZWRBY3Rpb24sIHJlcXVpcmVkUmVzb3VyY2VdID0gcmVxdWlyZWRQZXJtaXNzaW9uLnNwbGl0KCc6Jyk7XG4gICAgaWYgKHJlcXVpcmVkQWN0aW9uICYmIHJlcXVpcmVkUmVzb3VyY2UpIHtcbiAgICAgIGlmIChwZXJtaXNzaW9ucy5pbmNsdWRlcyhgJHtyZXF1aXJlZEFjdGlvbn06KmApKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgICAgaWYgKHBlcm1pc3Npb25zLmluY2x1ZGVzKGAqOiR7cmVxdWlyZWRSZXNvdXJjZX1gKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHBlcm1pc3Npb25zLmluY2x1ZGVzKCcqOionKSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG5cbiAgYXN5bmMgaGFzUGVybWlzc2lvbihASGVhZGVycygnYXV0aG9yaXphdGlvbicpIGF1dGgsIEBDdHgoKSBjdHgsIEBHdWFyZFBhcmFtcygpIHJlcXVpcmVkUGVybWlzc2lvbikge1xuICAgIFxuICAgIGF3YWl0IHRoaXMudG9rZW5TZXJ2aWNlLnN0b3JlVXNlckluQ2FjaGUoYXV0aCwgY3R4KTtcbiAgICBjb25zdCBwZXJtaXNzaW9ucyA9IGF3YWl0IHRoaXMuZ2V0VXNlclBlcm1pc3Npb25zKGF1dGgpO1xuICAgIGlmICghcGVybWlzc2lvbnMpIHJldHVybiBmYWxzZTtcbiAgICBjb25zdCBjaGVjayA9IHRoaXMuY2hlY2tQZXJtaXNzaW9uTWF0Y2gocGVybWlzc2lvbnMsIHJlcXVpcmVkUGVybWlzc2lvbik7XG4gICAgcmV0dXJuIGNoZWNrXG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IFBlcm1pc3Npb24gPSAoLi4ucGVybWlzc2lvbnMpID0+IGNyZWF0ZUd1YXJkKFBlcm1pc3Npb25HdWFyZHMsICdoYXNQZXJtaXNzaW9uJykoLi4ucGVybWlzc2lvbnMpO1xuXG4iLAogICAgImltcG9ydCB7IENvbnRyb2xsZXIsIEdldCwgUG9zdCwgUHV0LCBEZWxldGUsIFBhcmFtcywgQm9keSwgdCB9IGZyb20gJ25ham0tYXBpJztcbmltcG9ydCB7IFBlcm1pc3Npb25TZXJ2aWNlIH0gZnJvbSAnLi9QZXJtaXNzaW9uU2VydmljZSc7XG5pbXBvcnQgeyBpc0FkbWluIH0gZnJvbSAnQC9yb2xlcy9Sb2xlR3VhcmRzJztcblxuQENvbnRyb2xsZXIoJy9wZXJtaXNzaW9ucycpXG5AaXNBZG1pbigpXG5leHBvcnQgY2xhc3MgUGVybWlzc2lvbkNvbnRyb2xsZXIge1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHBlcm1pc3Npb25TZXJ2aWNlOiBQZXJtaXNzaW9uU2VydmljZSkgeyB9XG5cbiAgQEdldCgpXG4gIGFzeW5jIGdldFBlcm1pc3Npb25zKCkge1xuICAgIGNvbnN0IHBlcm1pc3Npb25zID0gYXdhaXQgdGhpcy5wZXJtaXNzaW9uU2VydmljZS5nZXRBbGwoKTtcbiAgICByZXR1cm4ge1xuICAgICAgZGF0YTogcGVybWlzc2lvbnMsXG4gICAgICBtZXNzYWdlOiB0KCdwZXJtaXNzaW9ucy5zdWNjZXNzLnJldHJpZXZlZCcpLFxuICAgICAgc3RhdHVzOiAnc3VjY2VzcydcbiAgICB9O1xuICB9XG5cbiAgQEdldCgnLzppZCcpXG4gIGFzeW5jIGdldFBlcm1pc3Npb24oQFBhcmFtcygnaWQnKSBpZDogc3RyaW5nKSB7XG4gICAgY29uc3QgcGVybWlzc2lvbiA9IGF3YWl0IHRoaXMucGVybWlzc2lvblNlcnZpY2UuZ2V0QnlJZChpZCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIGRhdGE6IHBlcm1pc3Npb24sXG4gICAgICBtZXNzYWdlOiB0KCdwZXJtaXNzaW9ucy5zdWNjZXNzLnJldHJpZXZlZCcpLFxuICAgICAgc3RhdHVzOiAnc3VjY2VzcydcbiAgICB9O1xuICB9XG5cbiAgQFBvc3QoKVxuICBhc3luYyBjcmVhdGUoQEJvZHkoKSBib2R5KSB7XG4gICAgY29uc3QgbmV3UGVybWlzc2lvbiA9IGF3YWl0IHRoaXMucGVybWlzc2lvblNlcnZpY2UuY3JlYXRlKGJvZHkpO1xuICAgIHJldHVybiB7XG4gICAgICBkYXRhOiBuZXdQZXJtaXNzaW9uLFxuICAgICAgbWVzc2FnZTogdCgncGVybWlzc2lvbnMuc3VjY2Vzcy5jcmVhdGVkJyksXG4gICAgICBzdGF0dXM6ICdzdWNjZXNzJ1xuICAgIH07XG4gIH1cblxuICBAUHV0KCcvOmlkJylcbiAgYXN5bmMgdXBkYXRlKEBQYXJhbXMoJ2lkJykgaWQ6IHN0cmluZywgQEJvZHkoKSBib2R5KSB7XG4gICAgY29uc3QgdXBkYXRlZFBlcm1pc3Npb24gPSBhd2FpdCB0aGlzLnBlcm1pc3Npb25TZXJ2aWNlLnVwZGF0ZShpZCwgYm9keSk7XG4gICAgcmV0dXJuIHtcbiAgICAgIGRhdGE6IHVwZGF0ZWRQZXJtaXNzaW9uLFxuICAgICAgbWVzc2FnZTogdCgncGVybWlzc2lvbnMuc3VjY2Vzcy51cGRhdGVkJyksXG4gICAgICBzdGF0dXM6ICdzdWNjZXNzJ1xuICAgIH07XG4gIH1cblxuICBARGVsZXRlKCcvOmlkJylcbiAgYXN5bmMgZGVsZXRlKEBQYXJhbXMoJ2lkJykgaWQ6IHN0cmluZykge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMucGVybWlzc2lvblNlcnZpY2UuZGVsZXRlKGlkKTtcbiAgICByZXR1cm4ge1xuICAgICAgZGF0YTogcmVzdWx0LFxuICAgICAgbWVzc2FnZTogdCgncGVybWlzc2lvbnMuc3VjY2Vzcy5kZWxldGVkJyksXG4gICAgICBzdGF0dXM6ICdzdWNjZXNzJ1xuICAgIH07XG4gIH1cblxuICBAR2V0KCcvcm9sZS86cm9sZUlkJylcbiAgYXN5bmMgZ2V0QnlSb2xlKEBQYXJhbXMoJ3JvbGVJZCcpIHJvbGVJZDogc3RyaW5nKSB7XG4gICAgY29uc3QgcGVybWlzc2lvbnMgPSBhd2FpdCB0aGlzLnBlcm1pc3Npb25TZXJ2aWNlLmdldFBlcm1pc3Npb25zQnlSb2xlKHJvbGVJZCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIGRhdGE6IHBlcm1pc3Npb25zLFxuICAgICAgbWVzc2FnZTogdCgncGVybWlzc2lvbnMuc3VjY2Vzcy5yZXRyaWV2ZWQnKSxcbiAgICAgIHN0YXR1czogJ3N1Y2Nlc3MnXG4gICAgfTtcbiAgfVxuXG4gIEBHZXQoJy9yb2xlcy86cGVybWlzc2lvbklkJylcbiAgYXN5bmMgZ2V0Um9sZXNCeVBlcm1pc3Npb24oQFBhcmFtcygncGVybWlzc2lvbklkJykgcGVybWlzc2lvbklkOiBzdHJpbmcpIHtcbiAgICBjb25zdCByb2xlcyA9IGF3YWl0IHRoaXMucGVybWlzc2lvblNlcnZpY2UuZ2V0Um9sZXNCeVBlcm1pc3Npb24ocGVybWlzc2lvbklkKTtcbiAgICByZXR1cm4ge1xuICAgICAgZGF0YTogcm9sZXMsXG4gICAgICBtZXNzYWdlOiB0KCdwZXJtaXNzaW9ucy5zdWNjZXNzLnJldHJpZXZlZCcpLFxuICAgICAgc3RhdHVzOiAnc3VjY2VzcydcbiAgICB9O1xuICB9XG5cbiAgQFBvc3QoJy9hc3NpZ24vOnJvbGVJZC86cGVybWlzc2lvbklkJylcbiAgYXN5bmMgYXNzaWduVG9Sb2xlKFxuICAgIEBQYXJhbXMoJ3JvbGVJZCcpIHJvbGVJZDogc3RyaW5nLFxuICAgIEBQYXJhbXMoJ3Blcm1pc3Npb25JZCcpIHBlcm1pc3Npb25JZDogc3RyaW5nXG4gICkge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMucGVybWlzc2lvblNlcnZpY2UuYXNzaWduUGVybWlzc2lvblRvUm9sZShyb2xlSWQsIHBlcm1pc3Npb25JZCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIGRhdGE6IHJlc3VsdCxcbiAgICAgIG1lc3NhZ2U6IHQoJ3Blcm1pc3Npb25zLnN1Y2Nlc3MuYXNzaWduZWQnKSxcbiAgICAgIHN0YXR1czogJ3N1Y2Nlc3MnXG4gICAgfTtcbiAgfVxuXG4gIEBEZWxldGUoJy9yZW1vdmUvOnJvbGVJZC86cGVybWlzc2lvbklkJylcbiAgYXN5bmMgcmVtb3ZlRnJvbVJvbGUoXG4gICAgQFBhcmFtcygncm9sZUlkJykgcm9sZUlkOiBzdHJpbmcsXG4gICAgQFBhcmFtcygncGVybWlzc2lvbklkJykgcGVybWlzc2lvbklkOiBzdHJpbmdcbiAgKSB7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5wZXJtaXNzaW9uU2VydmljZS5yZW1vdmVQZXJtaXNzaW9uRnJvbVJvbGUocm9sZUlkLCBwZXJtaXNzaW9uSWQpO1xuICAgIHJldHVybiB7XG4gICAgICBkYXRhOiByZXN1bHQsXG4gICAgICBtZXNzYWdlOiB0KCdwZXJtaXNzaW9ucy5zdWNjZXNzLnJlbW92ZWQnKSxcbiAgICAgIHN0YXR1czogJ3N1Y2Nlc3MnXG4gICAgfTtcbiAgfVxuXG4gIEBEZWxldGUoKVxuICBAaXNBZG1pbigpXG4gIGFzeW5jIGRlbGV0ZUFsbCgpIHtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLnBlcm1pc3Npb25TZXJ2aWNlLmRlbGV0ZUFsbCgpO1xuICAgIHJldHVybiB7XG4gICAgICBkYXRhOiByZXN1bHQsXG4gICAgICBtZXNzYWdlOiB0KCdwZXJtaXNzaW9ucy5zdWNjZXNzLmFsbERlbGV0ZWQnKSxcbiAgICAgIHN0YXR1czogJ3N1Y2Nlc3MnXG4gICAgfTtcbiAgfVxufSIsCiAgICAiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ25ham0tYXBpJztcbmltcG9ydCB7IFBlcm1pc3Npb25SZXBvc2l0b3J5IH0gZnJvbSAnLi9QZXJtaXNzaW9uUmVwb3NpdG9yeSc7XG5pbXBvcnQgeyBQZXJtaXNzaW9uVmFsaWRhdG9yIH0gZnJvbSAnLi9QZXJtaXNzaW9uVmFsaWRhdG9yJztcbmltcG9ydCB7IFJvbGVTZXJ2aWNlIH0gZnJvbSAnLi4vcm9sZXMvUm9sZVNlcnZpY2UnO1xuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgUGVybWlzc2lvblNlcnZpY2Uge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHBlcm1pc3Npb25SZXBvc2l0b3J5OiBQZXJtaXNzaW9uUmVwb3NpdG9yeSxcbiAgICBwcml2YXRlIHBlcm1pc3Npb25WYWxpZGF0b3I6IFBlcm1pc3Npb25WYWxpZGF0b3IsXG4gICAgcHJpdmF0ZSByb2xlU2VydmljZTogUm9sZVNlcnZpY2VcbiAgKSB7IH1cblxuICBhc3luYyBnZXRBbGwoKSB7XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucGVybWlzc2lvblJlcG9zaXRvcnkuZ2V0QWxsKCk7XG4gIH1cblxuICBhc3luYyBnZXRCeUlkKGlkOiBzdHJpbmcpIHtcbiAgICBhd2FpdCB0aGlzLnBlcm1pc3Npb25WYWxpZGF0b3IuY2hlY2tQZXJtaXNzaW9uRXhpc3RzKGlkKTtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5wZXJtaXNzaW9uUmVwb3NpdG9yeS5nZXRCeUlkKGlkKTtcbiAgfVxuXG4gIGFzeW5jIGdldEJ5TmFtZShuYW1lOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5wZXJtaXNzaW9uUmVwb3NpdG9yeS5nZXRCeU5hbWUobmFtZSk7XG4gIH1cblxuICBhc3luYyBnZXRCeVJlc291cmNlKHJlc291cmNlOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5wZXJtaXNzaW9uUmVwb3NpdG9yeS5nZXRBbGwoKS50aGVuKHBlcm1pc3Npb25zID0+XG4gICAgICBwZXJtaXNzaW9ucy5maWx0ZXIocCA9PiBwLnJlc291cmNlID09PSByZXNvdXJjZSlcbiAgICApO1xuICB9XG5cbiAgYXN5bmMgY3JlYXRlKGRhdGEpIHtcbiAgICBhd2FpdCB0aGlzLnBlcm1pc3Npb25WYWxpZGF0b3IudmFsaWRhdGVDcmVhdGVQZXJtaXNzaW9uKGRhdGEpO1xuICAgIGF3YWl0IHRoaXMucGVybWlzc2lvblZhbGlkYXRvci5jaGVja1Blcm1pc3Npb25OYW1lVW5pcXVlKGRhdGEubmFtZSk7XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucGVybWlzc2lvblJlcG9zaXRvcnkuY3JlYXRlKGRhdGEpO1xuICB9XG5cbiAgYXN5bmMgdXBkYXRlKGlkOiBzdHJpbmcsIGRhdGEpIHtcbiAgICBhd2FpdCB0aGlzLnBlcm1pc3Npb25WYWxpZGF0b3IuY2hlY2tQZXJtaXNzaW9uRXhpc3RzKGlkKTtcbiAgICBhd2FpdCB0aGlzLnBlcm1pc3Npb25WYWxpZGF0b3IuY2hlY2tQZXJtaXNzaW9uTmFtZVVuaXF1ZShkYXRhLm5hbWUsIGlkKTtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5wZXJtaXNzaW9uUmVwb3NpdG9yeS51cGRhdGUoaWQsIGRhdGEpO1xuICB9XG5cbiAgYXN5bmMgZGVsZXRlKGlkOiBzdHJpbmcpIHtcbiAgICBhd2FpdCB0aGlzLnBlcm1pc3Npb25WYWxpZGF0b3IuY2hlY2tQZXJtaXNzaW9uRXhpc3RzKGlkKTtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5wZXJtaXNzaW9uUmVwb3NpdG9yeS5kZWxldGUoaWQpO1xuICB9XG5cbiAgYXN5bmMgZ2V0UGVybWlzc2lvbnNCeVJvbGUocm9sZUlkOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5wZXJtaXNzaW9uUmVwb3NpdG9yeS5nZXRQZXJtaXNzaW9uc0J5Um9sZShyb2xlSWQpO1xuICB9XG5cbiAgYXN5bmMgZ2V0Um9sZXNCeVBlcm1pc3Npb24ocGVybWlzc2lvbklkOiBzdHJpbmcpIHtcbiAgICBhd2FpdCB0aGlzLnBlcm1pc3Npb25WYWxpZGF0b3IuY2hlY2tQZXJtaXNzaW9uRXhpc3RzKHBlcm1pc3Npb25JZCk7XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucGVybWlzc2lvblJlcG9zaXRvcnkuZ2V0Um9sZXNCeVBlcm1pc3Npb24ocGVybWlzc2lvbklkKTtcbiAgfVxuXG4gIGFzeW5jIGFzc2lnblBlcm1pc3Npb25Ub1JvbGUocm9sZUlkOiBzdHJpbmcsIHBlcm1pc3Npb25JZDogc3RyaW5nKSB7XG4gICAgYXdhaXQgdGhpcy5wZXJtaXNzaW9uVmFsaWRhdG9yLmNoZWNrUm9sZUhhc1Blcm1pc3Npb24ocm9sZUlkLCBwZXJtaXNzaW9uSWQpO1xuICAgIHJldHVybiBhd2FpdCB0aGlzLnBlcm1pc3Npb25SZXBvc2l0b3J5LmFzc2lnblBlcm1pc3Npb25Ub1JvbGUocm9sZUlkLCBwZXJtaXNzaW9uSWQpO1xuICB9XG5cbiAgYXN5bmMgcmVtb3ZlUGVybWlzc2lvbkZyb21Sb2xlKHJvbGVJZDogc3RyaW5nLCBwZXJtaXNzaW9uSWQ6IHN0cmluZykge1xuICAgIHJldHVybiBhd2FpdCB0aGlzLnBlcm1pc3Npb25SZXBvc2l0b3J5LnJlbW92ZVBlcm1pc3Npb25Gcm9tUm9sZShyb2xlSWQsIHBlcm1pc3Npb25JZCk7XG4gIH1cblxuICBhc3luYyBzZWVkRGVmYXVsdFBlcm1pc3Npb25zKGRlZmF1bHRQZXJtaXNzaW9ucykge1xuICAgIGNvbnN0IGNyZWF0ZWRQZXJtaXNzaW9ucyA9IFtdO1xuXG4gICAgZm9yIChjb25zdCBwZXJtaXNzaW9uIG9mIGRlZmF1bHRQZXJtaXNzaW9ucykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcGVybWlzc2lvbkVudGl0eSA9IGF3YWl0IHRoaXMuY3JlYXRlKHBlcm1pc3Npb24pO1xuICAgICAgICBjcmVhdGVkUGVybWlzc2lvbnMucHVzaChwZXJtaXNzaW9uRW50aXR5KTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gY3JlYXRlZFBlcm1pc3Npb25zO1xuICB9XG5cbiAgYXN5bmMgc2VlZERlZmF1bHRSb2xlUGVybWlzc2lvbnMoZGVmYXVsdFJvbGVQZXJtaXNzaW9ucykge1xuICAgIGNvbnN0IHJlc3VsdHMgPSBbXTtcblxuICAgIGZvciAoY29uc3QgeyByb2xlTmFtZSwgcGVybWlzc2lvbnMgfSBvZiBkZWZhdWx0Um9sZVBlcm1pc3Npb25zKSB7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCB0aGlzLnBlcm1pc3Npb25WYWxpZGF0b3IuY2hlY2tSb2xlRXhpc3RzQnlOYW1lKHJvbGVOYW1lKTtcbiAgICAgICAgY29uc3Qgcm9sZSA9IGF3YWl0IHRoaXMucm9sZVNlcnZpY2UuZ2V0QnlOYW1lKHJvbGVOYW1lKTtcblxuICAgICAgICBmb3IgKGNvbnN0IHBlcm1pc3Npb25OYW1lIG9mIHBlcm1pc3Npb25zKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMucGVybWlzc2lvblZhbGlkYXRvci5jaGVja1Blcm1pc3Npb25FeGlzdHNCeU5hbWUocGVybWlzc2lvbk5hbWUpO1xuICAgICAgICAgICAgY29uc3QgcGVybWlzc2lvbiA9IGF3YWl0IHRoaXMuZ2V0QnlOYW1lKHBlcm1pc3Npb25OYW1lKTtcblxuICAgICAgICAgICAgYXdhaXQgdGhpcy5wZXJtaXNzaW9uVmFsaWRhdG9yLmNoZWNrUm9sZUhhc1Blcm1pc3Npb24ocm9sZS5pZCwgcGVybWlzc2lvbi5pZCk7XG5cbiAgICAgICAgICAgIGF3YWl0IHRoaXMuYXNzaWduUGVybWlzc2lvblRvUm9sZShyb2xlLmlkLCBwZXJtaXNzaW9uLmlkKTtcbiAgICAgICAgICAgIHJlc3VsdHMucHVzaCh7IHJvbGU6IHJvbGVOYW1lLCBwZXJtaXNzaW9uOiBwZXJtaXNzaW9uTmFtZSB9KTtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0cztcbiAgfVxuXG4gIGFzeW5jIGRlbGV0ZUFsbCgpIHtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5wZXJtaXNzaW9uUmVwb3NpdG9yeS5kZWxldGVBbGwoKTtcbiAgfVxuXG59IiwKICAgICJpbXBvcnQgeyBJbmplY3RhYmxlLCB0IH0gZnJvbSAnbmFqbS1hcGknO1xuaW1wb3J0IHsgUGVybWlzc2lvblJlcG9zaXRvcnkgfSBmcm9tICcuL1Blcm1pc3Npb25SZXBvc2l0b3J5JztcbmltcG9ydCB7IFJvbGVWYWxpZGF0b3IgfSBmcm9tICcuLi9yb2xlcyc7XG5pbXBvcnQgeyBwYXJzZVNjaGVtYSB9IGZyb20gJ0Avc2hhcmVkJztcbmltcG9ydCB7IHogfSBmcm9tICd6b2QnO1xuXG5jb25zdCBwZXJtaXNzaW9uU2NoZW1hID0gei5vYmplY3Qoe1xuICBuYW1lOiB6LnN0cmluZygpLm1pbigxLCAnUGVybWlzc2lvbiBuYW1lIGlzIHJlcXVpcmVkJyksXG4gIGRlc2NyaXB0aW9uOiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG4gIHJlc291cmNlOiB6LnN0cmluZygpLm1pbigxLCAnUmVzb3VyY2UgaXMgcmVxdWlyZWQnKSxcbiAgYWN0aW9uOiB6LnN0cmluZygpLm1pbigxLCAnQWN0aW9uIGlzIHJlcXVpcmVkJyksXG59KTtcblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIFBlcm1pc3Npb25WYWxpZGF0b3Ige1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHBlcm1pc3Npb25SZXBvc2l0b3J5OiBQZXJtaXNzaW9uUmVwb3NpdG9yeSxcbiAgICBwcml2YXRlIHJvbGVWYWxpZGF0b3I6IFJvbGVWYWxpZGF0b3JcbiAgKSB7fVxuXG4gIGFzeW5jIHZhbGlkYXRlQ3JlYXRlUGVybWlzc2lvbihkYXRhKSB7XG4gICAgcmV0dXJuIHBhcnNlU2NoZW1hKHBlcm1pc3Npb25TY2hlbWEsIGRhdGEpO1xuICB9XG5cbiAgYXN5bmMgaXNQZXJtaXNzaW9uRXhpc3RzKGlkOiBzdHJpbmcpIHtcbiAgICBjb25zdCBleGlzdGluZ1Blcm1pc3Npb24gPSBhd2FpdCB0aGlzLnBlcm1pc3Npb25SZXBvc2l0b3J5LmdldEJ5SWQoaWQpO1xuICAgIHJldHVybiAhIWV4aXN0aW5nUGVybWlzc2lvbjtcbiAgfVxuXG4gIGFzeW5jIGlzUGVybWlzc2lvbk5hbWVFeGlzdHMobmFtZTogc3RyaW5nKSB7XG4gICAgY29uc3QgZXhpc3RpbmdQZXJtaXNzaW9uID0gYXdhaXQgdGhpcy5wZXJtaXNzaW9uUmVwb3NpdG9yeS5nZXRCeU5hbWUobmFtZSk7XG4gICAgcmV0dXJuICEhZXhpc3RpbmdQZXJtaXNzaW9uO1xuICB9XG5cbiAgLy89PT09PT09PT09PT09PT09PT09PT09PSB0aHJvdyBlcnJvcnNcblxuICBhc3luYyBjaGVja1Blcm1pc3Npb25FeGlzdHMoaWQ6IHN0cmluZykge1xuICAgIGNvbnN0IHBlcm1pc3Npb25FeGlzdHMgPSBhd2FpdCB0aGlzLmlzUGVybWlzc2lvbkV4aXN0cyhpZCk7XG4gICAgaWYgKCFwZXJtaXNzaW9uRXhpc3RzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IodCgncGVybWlzc2lvbnMuZXJyb3JzLm5vdEZvdW5kJykpO1xuICAgIH1cbiAgICByZXR1cm4gcGVybWlzc2lvbkV4aXN0cztcbiAgfVxuXG4gIGFzeW5jIGNoZWNrUGVybWlzc2lvbkV4aXN0c0J5TmFtZShuYW1lOiBzdHJpbmcpIHtcbiAgICBjb25zdCBwZXJtaXNzaW9uRXhpc3RzID0gYXdhaXQgdGhpcy5pc1Blcm1pc3Npb25OYW1lRXhpc3RzKG5hbWUpO1xuICAgIGlmICghcGVybWlzc2lvbkV4aXN0cykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKHQoJ3Blcm1pc3Npb25zLmVycm9ycy5ub3RGb3VuZCcpKTtcbiAgICB9XG4gICAgcmV0dXJuIHBlcm1pc3Npb25FeGlzdHM7XG4gIH1cblxuICBhc3luYyBjaGVja1Blcm1pc3Npb25OYW1lVW5pcXVlKG5hbWU6IHN0cmluZywgZXhjbHVkZUlkID0gbnVsbCkge1xuICAgIGlmICghbmFtZSkgcmV0dXJuO1xuICAgIGNvbnN0IGV4aXN0aW5nUGVybWlzc2lvbiA9IGF3YWl0IHRoaXMucGVybWlzc2lvblJlcG9zaXRvcnkuZ2V0QnlOYW1lKG5hbWUpO1xuICAgIGlmIChleGlzdGluZ1Blcm1pc3Npb24gJiYgZXhpc3RpbmdQZXJtaXNzaW9uLmlkICE9PSBleGNsdWRlSWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcih0KCdwZXJtaXNzaW9ucy5lcnJvcnMubmFtZUV4aXN0cycpKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBjaGVja1JvbGVFeGlzdHMoaWQ6IHN0cmluZykge1xuICAgIHJldHVybiBhd2FpdCB0aGlzLnJvbGVWYWxpZGF0b3IuY2hlY2tSb2xlRXhpc3RzKGlkKTtcbiAgfVxuXG4gIGFzeW5jIGNoZWNrUm9sZUV4aXN0c0J5TmFtZShuYW1lOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yb2xlVmFsaWRhdG9yLmNoZWNrUm9sZUV4aXN0c0J5TmFtZShuYW1lKTtcbiAgfVxuXG4gIGFzeW5jIGNoZWNrUm9sZUhhc1Blcm1pc3Npb24ocm9sZUlkOiBzdHJpbmcsIHBlcm1pc3Npb25JZDogc3RyaW5nKSB7XG4gICAgYXdhaXQgdGhpcy5yb2xlVmFsaWRhdG9yLmNoZWNrUm9sZUV4aXN0cyhyb2xlSWQpO1xuICAgIGF3YWl0IHRoaXMuY2hlY2tQZXJtaXNzaW9uRXhpc3RzKHBlcm1pc3Npb25JZCk7XG5cbiAgICBjb25zdCBoYXNQZXJtaXNzaW9uID0gYXdhaXQgdGhpcy5wZXJtaXNzaW9uUmVwb3NpdG9yeS5jaGVja1JvbGVIYXNQZXJtaXNzaW9uKHJvbGVJZCwgcGVybWlzc2lvbklkKTtcbiAgICBpZiAoaGFzUGVybWlzc2lvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKHQoJ3Blcm1pc3Npb25zLmVycm9ycy5yb2xlQWxyZWFkeUhhc1Blcm1pc3Npb24nKSk7XG4gICAgfVxuICB9XG5cbn0iLAogICAgIlxuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMvcHJvbWlzZXMnO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCBfaXNFbXB0eSBmcm9tICdsb2Rhc2guaXNlbXB0eSc7XG5pbXBvcnQgeyBTUUwsIHNxbCB9IGZyb20gJ2RyaXp6bGUtb3JtJztcbmltcG9ydCB7IEFueVBnQ29sdW1uIH0gZnJvbSAnZHJpenpsZS1vcm0vcGctY29yZSc7XG5cbmV4cG9ydCBjb25zdCBhdmF0YXJzUGF0aCA9IHBhdGguam9pbihwcm9jZXNzLmN3ZCgpLCAnYXZhdGFycycpO1xuXG5leHBvcnQgY29uc3QgcGFyc2VTY2hlbWEgPSBhc3luYyAoc2NoZW1hLCBkYXRhKSA9PiB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGF3YWl0IHNjaGVtYS5wYXJzZUFzeW5jKGRhdGEpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGNvbnN0IGVycm9ycyA9IGVycm9yLmlzc3VlcyB8fCBlcnJvci5lcnJvcnMgfHwgW107XG4gICAgY29uc3QgZXJyb3JNZXNzYWdlID0gZXJyb3JzXG4gICAgICAubWFwKGVyciA9PiBgJHtlcnIucGF0aC5qb2luKCcuJyl9OiAke2Vyci5tZXNzYWdlfWApXG4gICAgICAuam9pbignOyAnKTtcbiAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3JNZXNzYWdlKTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IGNsZWFuID0gKG9iajogYW55KTogYW55ID0+IHtcbiAgY29uc3QgY2xlYW5lZCA9IHt9O1xuXG4gIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKG9iaikpIHtcbiAgICBpZiAodmFsdWUgIT09IG51bGwgJiYgdmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gJycpIHtcbiAgICAgIGNsZWFuZWRba2V5XSA9IHZhbHVlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBjbGVhbmVkO1xufVxuXG5leHBvcnQgY29uc3QgZ2V0QXZhdGFyRmlsZSA9IGFzeW5jIChmaWxlTmFtZSkgPT4ge1xuICB0cnkge1xuICAgIGNvbnN0IGZpbGVQYXRoID0gcGF0aC5qb2luKGF2YXRhcnNQYXRoLCBmaWxlTmFtZSk7XG4gICAgY29uc3QgYnVmZmVyOiBhbnkgPSBhd2FpdCBmcy5yZWFkRmlsZShmaWxlUGF0aCk7XG4gICAgY29uc3QgZmlsZSA9IG5ldyBGaWxlKFtidWZmZXJdLCBmaWxlTmFtZSwge1xuICAgICAgdHlwZTogJ2ltYWdlL3BuZydcbiAgICB9KTtcbiAgICByZXR1cm4gZmlsZTtcbiAgfVxuICBjYXRjaCAoZXJyb3IpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG5leHBvcnQgY29uc3QgZm9ybWF0RGF0ZSA9IChkYXRlVmFsdWUpID0+IHtcbiAgaWYgKCFkYXRlVmFsdWUpIHJldHVybiBudWxsO1xuXG4gIGxldCBkYXRlOiBEYXRlO1xuXG4gIGlmIChkYXRlVmFsdWUgaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgZGF0ZSA9IGRhdGVWYWx1ZTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgZGF0ZVZhbHVlID09PSAnc3RyaW5nJykge1xuICAgIGRhdGUgPSBuZXcgRGF0ZShkYXRlVmFsdWUpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgaWYgKGlzTmFOKGRhdGUuZ2V0VGltZSgpKSkgcmV0dXJuIG51bGw7XG5cbiAgcmV0dXJuIGRhdGUudG9JU09TdHJpbmcoKS5zcGxpdCgnVCcpWzBdO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY2FsY3VsYXRlQWdlKGRhdGVPZkJpcnRoKSB7XG4gIGlmICghZGF0ZU9mQmlydGgpIHJldHVybiBudWxsO1xuXG4gIGNvbnN0IGZvcm1hdHRlZERhdGUgPSBmb3JtYXREYXRlKGRhdGVPZkJpcnRoKTtcbiAgaWYgKCFmb3JtYXR0ZWREYXRlKSByZXR1cm4gbnVsbDtcblxuICBjb25zdCBiaXJ0aCA9IG5ldyBEYXRlKGZvcm1hdHRlZERhdGUpO1xuICBjb25zdCB0b2RheSA9IG5ldyBEYXRlKCk7XG4gIGxldCBhZ2UgPSB0b2RheS5nZXRGdWxsWWVhcigpIC0gYmlydGguZ2V0RnVsbFllYXIoKTtcbiAgY29uc3QgbW9udGhEaWZmID0gdG9kYXkuZ2V0TW9udGgoKSAtIGJpcnRoLmdldE1vbnRoKCk7XG5cbiAgaWYgKG1vbnRoRGlmZiA8IDAgfHwgKG1vbnRoRGlmZiA9PT0gMCAmJiB0b2RheS5nZXREYXRlKCkgPCBiaXJ0aC5nZXREYXRlKCkpKSB7XG4gICAgYWdlLS07XG4gIH1cblxuICByZXR1cm4gYWdlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY2FsY3VsYXRlWWVhcnNPZkV4cGVyaWVuY2UoaGlyZURhdGUpIHtcbiAgaWYgKCFoaXJlRGF0ZSkgcmV0dXJuIG51bGw7XG5cbiAgY29uc3QgZm9ybWF0dGVkRGF0ZSA9IGZvcm1hdERhdGUoaGlyZURhdGUpO1xuICBpZiAoIWZvcm1hdHRlZERhdGUpIHJldHVybiBudWxsO1xuXG4gIGNvbnN0IGhpcmUgPSBuZXcgRGF0ZShmb3JtYXR0ZWREYXRlKTtcbiAgY29uc3QgdG9kYXkgPSBuZXcgRGF0ZSgpO1xuICBsZXQgeWVhcnMgPSB0b2RheS5nZXRGdWxsWWVhcigpIC0gaGlyZS5nZXRGdWxsWWVhcigpO1xuICBjb25zdCBtb250aERpZmYgPSB0b2RheS5nZXRNb250aCgpIC0gaGlyZS5nZXRNb250aCgpO1xuXG4gIGlmIChtb250aERpZmYgPCAwIHx8IChtb250aERpZmYgPT09IDAgJiYgdG9kYXkuZ2V0RGF0ZSgpIDwgaGlyZS5nZXREYXRlKCkpKSB7XG4gICAgeWVhcnMtLTtcbiAgfVxuXG4gIHJldHVybiB5ZWFycztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBpY2tQcm9wczxUPihzb3VyY2U6IFQsIGtleXMpOiBQYXJ0aWFsPFQ+IHtcbiAgY29uc3QgcmVzdWx0ID0ge307XG5cbiAgZm9yIChjb25zdCBrZXkgb2Yga2V5cykge1xuICAgIGlmIChzb3VyY2Vba2V5XSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXN1bHRba2V5XSA9IHNvdXJjZVtrZXldO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmV4cG9ydCBjb25zdCBpc0VtcHR5ID0gX2lzRW1wdHk7XG5cbmV4cG9ydCBmdW5jdGlvbiBqc29uQWdnKFxuICBmaWVsZHM6IFJlY29yZDxzdHJpbmcsIEFueVBnQ29sdW1uPixcbiAgb3JkZXJCeT86IEFueVBnQ29sdW1uIHwgU1FMXG4pIHtcbiAgY29uc3QgZmllbGRFbnRyaWVzID0gT2JqZWN0LmVudHJpZXMoZmllbGRzKTtcbiAgY29uc3QganNvbkJ1aWxkQXJncyA9IGZpZWxkRW50cmllcy5mbGF0TWFwKChba2V5LCBjb2x1bW5dKSA9PiBbXG4gICAgc3FsLnJhdyhgJyR7a2V5fSdgKSxcbiAgICBjb2x1bW5cbiAgXSk7XG5cbiAgbGV0IGFnZ3JlZ2F0aW9uID0gc3FsYGpzb25fYWdnKGpzb25fYnVpbGRfb2JqZWN0KCR7c3FsLmpvaW4oanNvbkJ1aWxkQXJncywgc3FsYCwgYCl9KWA7XG5cbiAgaWYgKG9yZGVyQnkpIHtcbiAgICBhZ2dyZWdhdGlvbiA9IHNxbGAke2FnZ3JlZ2F0aW9ufSBPUkRFUiBCWSAke29yZGVyQnl9YDtcbiAgfVxuXG4gIGFnZ3JlZ2F0aW9uID0gc3FsYCR7YWdncmVnYXRpb259KWA7XG5cbiAgLy8gV3JhcCB3aXRoIENPQUxFU0NFIHRvIHJldHVybiBlbXB0eSBhcnJheSBpbnN0ZWFkIG9mIG51bGxcbiAgcmV0dXJuIHNxbGBDT0FMRVNDRSgke2FnZ3JlZ2F0aW9ufSwgJ1tdJzo6anNvbilgO1xufVxuXG5leHBvcnQgZnVuY3Rpb24ganNvbkFnZ1N1YnF1ZXJ5KFxuICBmaWVsZHM6IFJlY29yZDxzdHJpbmcsIEFueVBnQ29sdW1uPixcbiAgZnJvbTogYW55LFxuICB3aGVyZTogU1FMLFxuICBvcmRlckJ5PzogQW55UGdDb2x1bW4gfCBTUUxcbikge1xuICBjb25zdCBmaWVsZEVudHJpZXMgPSBPYmplY3QuZW50cmllcyhmaWVsZHMpO1xuICBjb25zdCBqc29uQnVpbGRBcmdzID0gZmllbGRFbnRyaWVzLmZsYXRNYXAoKFtrZXksIGNvbHVtbl0pID0+IFtcbiAgICBzcWwucmF3KGAnJHtrZXl9J2ApLFxuICAgIGNvbHVtblxuICBdKTtcblxuICBsZXQgYWdncmVnYXRpb24gPSBzcWxgXG4gICAgU0VMRUNUIGpzb25fYWdnKERJU1RJTkNUIGpzb25fYnVpbGRfb2JqZWN0KCR7c3FsLmpvaW4oanNvbkJ1aWxkQXJncywgc3FsYCwgYCl9KSlcbiAgICBGUk9NICR7ZnJvbX1cbiAgICBXSEVSRSAke3doZXJlfVxuICBgO1xuXG4gIGlmIChvcmRlckJ5KSB7XG4gICAgYWdncmVnYXRpb24gPSBzcWxgXG4gICAgICBTRUxFQ1QganNvbl9hZ2coanNvbl9idWlsZF9vYmplY3QoJHtzcWwuam9pbihqc29uQnVpbGRBcmdzLCBzcWxgLCBgKX0pIE9SREVSIEJZICR7b3JkZXJCeX0pXG4gICAgICBGUk9NICR7ZnJvbX1cbiAgICAgIFdIRVJFICR7d2hlcmV9XG4gICAgYDtcbiAgfVxuXG4gIHJldHVybiBzcWxgQ09BTEVTQ0UoKCR7YWdncmVnYXRpb259KSwgJ1tdJzo6anNvbilgO1xufVxuXG5leHBvcnQgY29uc3QgaXNQYXRoID0gKGltZykgPT5cbiAgdHlwZW9mIGltZyA9PT0gJ3N0cmluZycgJiYgaW1nLnRyaW0oKS5sZW5ndGggPiAwICYmIChpbWcuc3RhcnRzV2l0aCgnLycpIHx8IGltZy5zdGFydHNXaXRoKCdodHRwJykgfHwgaW1nLnN0YXJ0c1dpdGgoJ3N0b3JhZ2UvJykpO1xuXG5cbmV4cG9ydCBjb25zdCBpc0ZpbGUgPSAoaW1nKSA9PlxuICAhIWltZyAmJiB0eXBlb2YgaW1nICE9PSAnc3RyaW5nJyAmJiBpbWcgaW5zdGFuY2VvZiBGaWxlO1xuXG4iLAogICAgImltcG9ydCB7IGRyaXp6bGUsIFBvc3RncmVzSnNEYXRhYmFzZSB9IGZyb20gJ2RyaXp6bGUtb3JtL3Bvc3RncmVzLWpzJztcbmltcG9ydCAqIGFzIHNjaGVtYSBmcm9tICcuL3NjaGVtYSc7XG5pbXBvcnQgeyBEQiBhcyBHZW5lcmljREIgfSBmcm9tICduYWptLWFwaSc7XG5cbmV4cG9ydCB0eXBlIERCID0gUG9zdGdyZXNKc0RhdGFiYXNlPHR5cGVvZiBzY2hlbWE+O1xuXG4vKipcbiAqIOKaoO+4jyAgSU1QT1JUQU5UOiBEZXZlbG9wbWVudC1Pbmx5IERhdGFiYXNlIEluc3RhbmNlXG4gKlxuICogVGhpcyBEQiBpbnN0YW5jZSBpcyBPTkxZIGZvciBzdGFuZGFsb25lIGRldmVsb3BtZW50IGFuZCB0ZXN0aW5nLlxuICogV2hlbiB1c2VkIGFzIGEgcGx1Z2luIGluIHByb2R1Y3Rpb24sIHRoZSBkYXRhYmFzZSB3aWxsIGJlIGluamVjdGVkXG4gKiBhdXRvbWF0aWNhbGx5IGJ5IHRoZSBuYWptLWFwaSBwbHVnaW4gc3lzdGVtLlxuICpcbiAqIERPIE5PVCB1c2UgdGhpcyBpbiBwcm9kdWN0aW9uIC0gaXQgY3JlYXRlcyBhIGR1cGxpY2F0ZSBjb25uZWN0aW9uIVxuICpcbiAqIEluIHByb2R1Y3Rpb246XG4gKiAtIFVzZSBuYWptLWF1dGggYXMgYSBwbHVnaW46IGBpbXBvcnQgeyBBdXRoUGx1Z2luIH0gZnJvbSAnbmFqbS1hdXRoL3BsdWdpbidgXG4gKiAtIFRoZSBtYWluIGFwcCByZWdpc3RlcnMgdGhlIGRhdGFiYXNlIGluIERhdGFiYXNlUmVnaXN0cnlcbiAqIC0gUmVwb3NpdG9yaWVzIGdldCB0aGUgREIgYXV0b21hdGljYWxseSBpbmplY3RlZCB2aWEgZGVwZW5kZW5jeSBpbmplY3Rpb25cbiAqXG4gKiBAZXhhbXBsZSBQcm9kdWN0aW9uIFVzYWdlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBpbXBvcnQgeyBTZXJ2ZXIsIERhdGFiYXNlUmVnaXN0cnkgfSBmcm9tICduYWptLWFwaSc7XG4gKiBpbXBvcnQgeyBBdXRoUGx1Z2luIH0gZnJvbSAnbmFqbS1hdXRoL3BsdWdpbic7XG4gKlxuICogY29uc3QgYXBwID0gYXdhaXQgU2VydmVyKHtcbiAqICAgZGF0YWJhc2VzOiB7XG4gKiAgICAgYXV0aDogbXlEYkluc3RhbmNlICAvLyBTaW5nbGUgc291cmNlIG9mIHRydXRoXG4gKiAgIH0sXG4gKiAgIHBsdWdpbnM6IFtBdXRoUGx1Z2luXVxuICogfSk7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGNvbnN0IGRiOiBEQiB8IEdlbmVyaWNEQiA9IHByb2Nlc3MuZW52LkRCX1VSTFxuICA/IGRyaXp6bGUocHJvY2Vzcy5lbnYuREJfVVJMLCB7IHNjaGVtYSB9KVxuICA6IG51bGwgYXMgYW55OyAgLy8gV2lsbCBiZSBpbmplY3RlZCBieSBwbHVnaW4gc3lzdGVtIGluIHByb2R1Y3Rpb25cblxuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSAnZGV2ZWxvcG1lbnQnICYmIGRiKSB7XG4gIGNvbnNvbGUud2Fybign4pqg77iPICBuYWptLWF1dGg6IFVzaW5nIHN0YW5kYWxvbmUgREIgaW5zdGFuY2UuIFRoaXMgc2hvdWxkIG9ubHkgYmUgdXNlZCBmb3IgZGV2ZWxvcG1lbnQuJyk7XG59IiwKICAgICJpbXBvcnQgeyBwZ1RhYmxlLCB0ZXh0LCBib29sZWFuLCB0aW1lc3RhbXAgfSBmcm9tICdkcml6emxlLW9ybS9wZy1jb3JlJztcclxuaW1wb3J0IHsgbmFub2lkIH0gZnJvbSAnbmFub2lkJztcclxuXHJcbmltcG9ydCB7IHNxbCB9IGZyb20gJ2RyaXp6bGUtb3JtJztcclxuaW1wb3J0IHsgdG9rZW5TdGF0dXNFbnVtLCB0b2tlblR5cGVFbnVtLCB1c2VyU3RhdHVzRW51bSB9IGZyb20gJy4vUGdFbnVtJztcclxuXHJcbmV4cG9ydCBjb25zdCB0aW1lc3RhbXBzID0ge1xyXG4gIGNyZWF0ZWRBdDogdGltZXN0YW1wKCdjcmVhdGVkX2F0JywgeyBtb2RlOiAnc3RyaW5nJyB9KS5kZWZhdWx0Tm93KCksXHJcbiAgdXBkYXRlZEF0OiB0aW1lc3RhbXAoJ3VwZGF0ZWRfYXQnLCB7IG1vZGU6ICdzdHJpbmcnIH0pLmRlZmF1bHROb3coKS4kb25VcGRhdGUoKCkgPT4gc3FsYENVUlJFTlRfVElNRVNUQU1QYCksXHJcbn07XHJcblxyXG5leHBvcnQgY29uc3QgaWRGaWVsZCA9IChsZW5ndGggPSA1KSA9PlxyXG4gIHRleHQoJ2lkJykucHJpbWFyeUtleSgpLm5vdE51bGwoKS4kZGVmYXVsdEZuKCgpID0+IG5hbm9pZChsZW5ndGgpKTtcclxuXHJcbmV4cG9ydCBjb25zdCByb2xlc1RhYmxlID0gcGdUYWJsZSgncm9sZXMnLCB7XHJcbiAgaWQ6IGlkRmllbGQoKSxcclxuICBuYW1lOiB0ZXh0KCduYW1lJykubm90TnVsbCgpLFxyXG4gIGRlc2NyaXB0aW9uOiB0ZXh0KCdkZXNjcmlwdGlvbicpLFxyXG59KTtcclxuXHJcbmV4cG9ydCBjb25zdCB1c2Vyc1RhYmxlID0gcGdUYWJsZSgndXNlcnMnLCB7XHJcbiAgaWQ6IGlkRmllbGQoOCksXHJcbiAgZW1haWw6IHRleHQoJ2VtYWlsJykubm90TnVsbCgpLnVuaXF1ZSgpLFxyXG4gIGVtYWlsVmVyaWZpZWQ6IGJvb2xlYW4oJ2VtYWlsX3ZlcmlmaWVkJykuZGVmYXVsdChmYWxzZSksXHJcbiAgcGFzc3dvcmQ6IHRleHQoJ3Bhc3N3b3JkJykubm90TnVsbCgpLFxyXG4gIGltYWdlOiB0ZXh0KCdpbWFnZScpLmRlZmF1bHQoJ25vYXZhdGFyLnBuZycpLFxyXG4gIHN0YXR1czogdXNlclN0YXR1c0VudW0oJ3N0YXR1cycpLmRlZmF1bHQoJ3BlbmRpbmcnKSxcclxuICByb2xlSWQ6IHRleHQoJ3JvbGVfaWQnKS5yZWZlcmVuY2VzKCgpID0+IHJvbGVzVGFibGUuaWQpLFxyXG4gIGxhc3RMb2dpbjogdGltZXN0YW1wKCdsYXN0X2xvZ2luJywgeyBtb2RlOiAnc3RyaW5nJyB9KSxcclxuICAuLi50aW1lc3RhbXBzLFxyXG59KTtcclxuXHJcbmV4cG9ydCBjb25zdCB0b2tlbnNUYWJsZSA9IHBnVGFibGUoJ3Rva2VucycsIHtcclxuICBpZDogaWRGaWVsZCgxMCksXHJcbiAgdXNlcklkOiB0ZXh0KCd1c2VyX2lkJykucmVmZXJlbmNlcygoKSA9PiB1c2Vyc1RhYmxlLmlkLCB7IG9uRGVsZXRlOiAnY2FzY2FkZScgfSkudW5pcXVlKCkubm90TnVsbCgpLFxyXG4gIHRva2VuOiB0ZXh0KCd0b2tlbicpLm5vdE51bGwoKSxcclxuICB0eXBlOiB0b2tlblR5cGVFbnVtKCd0eXBlJykuZGVmYXVsdCgncmVmcmVzaCcpLFxyXG4gIHN0YXR1czogdG9rZW5TdGF0dXNFbnVtKCdzdGF0dXMnKS5kZWZhdWx0KCdhY3RpdmUnKSxcclxuICBleHBpcmVzQXQ6IHRpbWVzdGFtcCgnZXhwaXJlc19hdCcsIHsgbW9kZTogJ3N0cmluZycgfSkubm90TnVsbCgpLFxyXG4gIC4uLnRpbWVzdGFtcHMsXHJcbn0pO1xyXG5cclxuXHJcbmV4cG9ydCBjb25zdCBwZXJtaXNzaW9uc1RhYmxlID0gcGdUYWJsZSgncGVybWlzc2lvbnMnLCB7XHJcbiAgaWQ6IGlkRmllbGQoKSxcclxuICBuYW1lOiB0ZXh0KCduYW1lJykubm90TnVsbCgpLnVuaXF1ZSgpLFxyXG4gIGRlc2NyaXB0aW9uOiB0ZXh0KCdkZXNjcmlwdGlvbicpLFxyXG4gIHJlc291cmNlOiB0ZXh0KCdyZXNvdXJjZScpLm5vdE51bGwoKSxcclxuICBhY3Rpb246IHRleHQoJ2FjdGlvbicpLm5vdE51bGwoKSxcclxuICAuLi50aW1lc3RhbXBzLFxyXG59KTtcclxuXHJcblxyXG5leHBvcnQgY29uc3Qgcm9sZVBlcm1pc3Npb25zVGFibGUgPSBwZ1RhYmxlKCdyb2xlX3Blcm1pc3Npb25zJywge1xyXG4gIGlkOiBpZEZpZWxkKCksXHJcbiAgcm9sZUlkOiB0ZXh0KCdyb2xlX2lkJykucmVmZXJlbmNlcygoKSA9PiByb2xlc1RhYmxlLmlkKS5ub3ROdWxsKCksXHJcbiAgcGVybWlzc2lvbklkOiB0ZXh0KCdwZXJtaXNzaW9uX2lkJykucmVmZXJlbmNlcygoKSA9PiBwZXJtaXNzaW9uc1RhYmxlLmlkKS5ub3ROdWxsKCksXHJcbiAgLi4udGltZXN0YW1wcyxcclxufSk7XHJcblxyXG5leHBvcnQgdHlwZSBVc2VyID0gdHlwZW9mIHVzZXJzVGFibGUuJGluZmVyU2VsZWN0O1xyXG5leHBvcnQgdHlwZSBOZXdVc2VyID0gdHlwZW9mIHVzZXJzVGFibGUuJGluZmVySW5zZXJ0O1xyXG5leHBvcnQgdHlwZSBUb2tlbiA9IHR5cGVvZiB0b2tlbnNUYWJsZS4kaW5mZXJTZWxlY3Q7XHJcbmV4cG9ydCB0eXBlIE5ld1Rva2VuID0gdHlwZW9mIHRva2Vuc1RhYmxlLiRpbmZlckluc2VydDtcclxuZXhwb3J0IHR5cGUgUm9sZSA9IHR5cGVvZiByb2xlc1RhYmxlLiRpbmZlclNlbGVjdDtcclxuZXhwb3J0IHR5cGUgTmV3Um9sZSA9IHR5cGVvZiByb2xlc1RhYmxlLiRpbmZlckluc2VydDtcclxuZXhwb3J0IHR5cGUgUGVybWlzc2lvbiA9IHR5cGVvZiBwZXJtaXNzaW9uc1RhYmxlLiRpbmZlclNlbGVjdDtcclxuZXhwb3J0IHR5cGUgTmV3UGVybWlzc2lvbiA9IHR5cGVvZiBwZXJtaXNzaW9uc1RhYmxlLiRpbmZlckluc2VydDtcclxuZXhwb3J0IHR5cGUgUm9sZVBlcm1pc3Npb24gPSB0eXBlb2Ygcm9sZVBlcm1pc3Npb25zVGFibGUuJGluZmVyU2VsZWN0O1xyXG5leHBvcnQgdHlwZSBOZXdSb2xlUGVybWlzc2lvbiA9IHR5cGVvZiByb2xlUGVybWlzc2lvbnNUYWJsZS4kaW5mZXJJbnNlcnQ7XHJcbiIsCiAgICAiLy8gLS0tIERyaXp6bGUgcGdFbnVtIEdlbmVyYXRpb24gLS0tXG5pbXBvcnQgeyBnZXRFbnVtQ29uZmlnIH0gZnJvbSBcIkAvbGliL0VOVU1TXCI7XG5pbXBvcnQgeyBwZ0VudW0gfSBmcm9tIFwiZHJpenpsZS1vcm0vcGctY29yZVwiO1xuXG5jb25zdCBjcmVhdGVQZ0VudW0gPSAoZW51bUtleSkgPT4ge1xuICBjb25zdCBjb25maWcgPSBnZXRFbnVtQ29uZmlnKGVudW1LZXkpXG4gIGlmICghY29uZmlnKSB0aHJvdyBuZXcgRXJyb3IoYEVudW0gJHtlbnVtS2V5fSBub3QgZm91bmRgKVxuICBjb25zdCBlbnVtTmFtZSA9IGNvbmZpZy5uYW1lIHx8IGVudW1LZXlcbiAgcmV0dXJuIHBnRW51bShlbnVtTmFtZSwgY29uZmlnLnZhbHVlcylcbn1cblxuZXhwb3J0IGNvbnN0IHVzZXJTdGF0dXNFbnVtID0gY3JlYXRlUGdFbnVtKCd1c2VyU3RhdHVzJyk7XG5leHBvcnQgY29uc3QgdG9rZW5TdGF0dXNFbnVtID0gY3JlYXRlUGdFbnVtKCd0b2tlblN0YXR1cycpO1xuZXhwb3J0IGNvbnN0IHRva2VuVHlwZUVudW0gPSBjcmVhdGVQZ0VudW0oJ3Rva2VuVHlwZScpO1xuZXhwb3J0IGNvbnN0IHN0dWRlbnRTdGF0dXNFbnVtID0gY3JlYXRlUGdFbnVtKCdzdHVkZW50U3RhdHVzJyk7XG4iLAogICAgImltcG9ydCB7IFBsdWdpbkNvbmZpZyB9IGZyb20gJ25ham0tYXBpJztcclxuXHJcbi8vIEltcG9ydCBhbGwgY29udHJvbGxlcnNcclxuaW1wb3J0IHsgVXNlckNvbnRyb2xsZXIgfSBmcm9tICcuL3VzZXJzL1VzZXJDb250cm9sbGVyJztcclxuaW1wb3J0IHsgQXV0aENvbnRyb2xsZXIgfSBmcm9tICcuL2F1dGgvQXV0aENvbnRyb2xsZXInO1xyXG5pbXBvcnQgeyBSb2xlQ29udHJvbGxlciB9IGZyb20gJy4vcm9sZXMvUm9sZUNvbnRyb2xsZXInO1xyXG5pbXBvcnQgeyBQZXJtaXNzaW9uQ29udHJvbGxlciB9IGZyb20gJy4vcGVybWlzc2lvbnMvUGVybWlzc2lvbkNvbnRyb2xsZXInO1xyXG5cclxuLy8gSW1wb3J0IGFsbCBzZXJ2aWNlc1xyXG5pbXBvcnQgeyBVc2VyU2VydmljZSB9IGZyb20gJy4vdXNlcnMvVXNlclNlcnZpY2UnO1xyXG5pbXBvcnQgeyBBdXRoU2VydmljZSB9IGZyb20gJy4vYXV0aC9BdXRoU2VydmljZSc7XHJcbmltcG9ydCB7IENvb2tpZVNlcnZpY2UgfSBmcm9tICcuL2F1dGgvQ29va2llU2VydmljZSc7XHJcbmltcG9ydCB7IEVuY3J5cHRpb25TZXJ2aWNlIH0gZnJvbSAnLi9hdXRoL0VuY3J5cHRpb25TZXJ2aWNlJztcclxuaW1wb3J0IHsgUm9sZVNlcnZpY2UgfSBmcm9tICcuL3JvbGVzL1JvbGVTZXJ2aWNlJztcclxuaW1wb3J0IHsgUGVybWlzc2lvblNlcnZpY2UgfSBmcm9tICcuL3Blcm1pc3Npb25zL1Blcm1pc3Npb25TZXJ2aWNlJztcclxuaW1wb3J0IHsgVG9rZW5TZXJ2aWNlIH0gZnJvbSAnLi90b2tlbnMvVG9rZW5TZXJ2aWNlJztcclxuXHJcbi8vIEltcG9ydCBhbGwgcmVwb3NpdG9yaWVzXHJcbmltcG9ydCB7IFVzZXJSZXBvc2l0b3J5IH0gZnJvbSAnLi91c2Vycy9Vc2VyUmVwb3NpdG9yeSc7XHJcbmltcG9ydCB7IFJvbGVSZXBvc2l0b3J5IH0gZnJvbSAnLi9yb2xlcy9Sb2xlUmVwb3NpdG9yeSc7XHJcbmltcG9ydCB7IFBlcm1pc3Npb25SZXBvc2l0b3J5IH0gZnJvbSAnLi9wZXJtaXNzaW9ucy9QZXJtaXNzaW9uUmVwb3NpdG9yeSc7XHJcbmltcG9ydCB7IFRva2VuUmVwb3NpdG9yeSB9IGZyb20gJy4vdG9rZW5zL1Rva2VuUmVwb3NpdG9yeSc7XHJcblxyXG4vLyBJbXBvcnQgYWxsIHZhbGlkYXRvcnNcclxuaW1wb3J0IHsgVXNlclZhbGlkYXRvciB9IGZyb20gJy4vdXNlcnMvVXNlclZhbGlkYXRvcic7XHJcbmltcG9ydCB7IFJvbGVWYWxpZGF0b3IgfSBmcm9tICcuL3JvbGVzL1JvbGVWYWxpZGF0b3InO1xyXG5pbXBvcnQgeyBQZXJtaXNzaW9uVmFsaWRhdG9yIH0gZnJvbSAnLi9wZXJtaXNzaW9ucy9QZXJtaXNzaW9uVmFsaWRhdG9yJztcclxuXHJcbi8vIEltcG9ydCBhbGwgZ3VhcmRzXHJcbmltcG9ydCB7IFJvbGVHdWFyZHMgfSBmcm9tICcuL3JvbGVzL1JvbGVHdWFyZHMnO1xyXG5pbXBvcnQgeyBQZXJtaXNzaW9uR3VhcmRzIH0gZnJvbSAnLi9wZXJtaXNzaW9ucy9QZXJtaXNzaW9uR3VhcmRzJztcclxuXHJcbi8qKlxyXG4gKiBuYWptLWF1dGggUGx1Z2luIENvbmZpZ3VyYXRpb25cclxuICpcclxuICogVGhpcyBwbHVnaW4gcHJvdmlkZXMgY29tcHJlaGVuc2l2ZSBhdXRoZW50aWNhdGlvbiBhbmQgYXV0aG9yaXphdGlvbiBmZWF0dXJlczpcclxuICogLSBVc2VyIG1hbmFnZW1lbnQgd2l0aCBzZWN1cmUgcGFzc3dvcmQgaGFzaGluZ1xyXG4gKiAtIFJvbGUtYmFzZWQgYWNjZXNzIGNvbnRyb2wgKFJCQUMpXHJcbiAqIC0gUGVybWlzc2lvbiBtYW5hZ2VtZW50IHdpdGggZ3VhcmRzXHJcbiAqIC0gSldUIHRva2VuIGF1dGhlbnRpY2F0aW9uXHJcbiAqIC0gU2Vzc2lvbiBtYW5hZ2VtZW50IHdpdGggY29va2llc1xyXG4gKiAtIEVuY3J5cHRpb24gdXRpbGl0aWVzXHJcbiAqXHJcbiAqIEBleGFtcGxlXHJcbiAqIGBgYHR5cGVzY3JpcHRcclxuICogaW1wb3J0IHsgU2VydmVyIH0gZnJvbSAnbmFqbS1hcGknO1xyXG4gKiBpbXBvcnQgeyBBdXRoUGx1Z2luIH0gZnJvbSAnbmFqbS1hdXRoL3BsdWdpbic7XHJcbiAqIGltcG9ydCB7IGRiIH0gZnJvbSAnLi9kYXRhYmFzZSc7XHJcbiAqXHJcbiAqIGNvbnN0IGFwcCA9IGF3YWl0IFNlcnZlcih7XHJcbiAqICAgZGF0YWJhc2VzOiB7XHJcbiAqICAgICBkZWZhdWx0OiBkYixcclxuICogICAgIGF1dGg6IGRiICAvLyBDYW4gdXNlIHNhbWUgREIgb3Igc2VwYXJhdGVcclxuICogICB9LFxyXG4gKiAgIHBsdWdpbnM6IFtBdXRoUGx1Z2luXVxyXG4gKiB9KTtcclxuICogYGBgXHJcbiAqL1xyXG5leHBvcnQgY29uc3QgQXV0aFBsdWdpbjogUGx1Z2luQ29uZmlnID0ge1xyXG4gIG5hbWU6ICduYWptLWF1dGgnLFxyXG4gIHZlcnNpb246ICcwLjEuMycsXHJcblxyXG4gIC8qKlxyXG4gICAqIERhdGFiYXNlIGNvbmZpZ3VyYXRpb25cclxuICAgKiBCeSBkZWZhdWx0IHVzZXMgJ2F1dGgnIGRhdGFiYXNlLCBidXQgY2FuIGJlIGNoYW5nZWQgdG8gJ2RlZmF1bHQnXHJcbiAgICogVGhlIG1haW4gYXBwbGljYXRpb24gc2hvdWxkIHJlZ2lzdGVyIHRoaXMgZGF0YWJhc2UgaW4gRGF0YWJhc2VSZWdpc3RyeVxyXG4gICAqL1xyXG4gIGRhdGFiYXNlOiAnYXV0aCcsXHJcblxyXG4gIC8qKlxyXG4gICAqIEhUVFAgQ29udHJvbGxlcnNcclxuICAgKiBQcm92aWRlcyBSRVNUIEFQSSBlbmRwb2ludHMgZm9yIGF1dGhlbnRpY2F0aW9uIGFuZCBhdXRob3JpemF0aW9uXHJcbiAgICovXHJcbiAgY29udHJvbGxlcnM6IFtcclxuICAgIFVzZXJDb250cm9sbGVyLCAgICAgICAvLyAvdXNlcnMgLSBVc2VyIENSVUQgb3BlcmF0aW9uc1xyXG4gICAgQXV0aENvbnRyb2xsZXIsICAgICAgIC8vIC9hdXRoIC0gTG9naW4sIGxvZ291dCwgcmVnaXN0ZXIsIHZlcmlmeVxyXG4gICAgUm9sZUNvbnRyb2xsZXIsICAgICAgIC8vIC9yb2xlcyAtIFJvbGUgbWFuYWdlbWVudFxyXG4gICAgUGVybWlzc2lvbkNvbnRyb2xsZXIsIC8vIC9wZXJtaXNzaW9ucyAtIFBlcm1pc3Npb24gbWFuYWdlbWVudFxyXG4gIF0sXHJcblxyXG4gIC8qKlxyXG4gICAqIEJ1c2luZXNzIExvZ2ljIFNlcnZpY2VzXHJcbiAgICogQ29yZSBzZXJ2aWNlcyBmb3IgYXV0aGVudGljYXRpb24gYW5kIGF1dGhvcml6YXRpb25cclxuICAgKi9cclxuICBzZXJ2aWNlczogW1xyXG4gICAgVXNlclNlcnZpY2UsICAgICAgICAvLyBVc2VyIGJ1c2luZXNzIGxvZ2ljXHJcbiAgICBBdXRoU2VydmljZSwgICAgICAgIC8vIEF1dGhlbnRpY2F0aW9uIGxvZ2ljIChsb2dpbiwgcmVnaXN0ZXIsIHZlcmlmeSlcclxuICAgIENvb2tpZVNlcnZpY2UsICAgICAgLy8gQ29va2llIG1hbmFnZW1lbnQgZm9yIHNlc3Npb25zXHJcbiAgICBFbmNyeXB0aW9uU2VydmljZSwgIC8vIFBhc3N3b3JkIGhhc2hpbmcgYW5kIGVuY3J5cHRpb25cclxuICAgIFJvbGVTZXJ2aWNlLCAgICAgICAgLy8gUm9sZSBtYW5hZ2VtZW50IGxvZ2ljXHJcbiAgICBQZXJtaXNzaW9uU2VydmljZSwgIC8vIFBlcm1pc3Npb24gbWFuYWdlbWVudCBsb2dpY1xyXG4gICAgVG9rZW5TZXJ2aWNlLCAgICAgICAvLyBKV1QgdG9rZW4gZ2VuZXJhdGlvbiBhbmQgdmFsaWRhdGlvblxyXG4gIF0sXHJcblxyXG4gIC8qKlxyXG4gICAqIERhdGEgQWNjZXNzIFJlcG9zaXRvcmllc1xyXG4gICAqIERhdGFiYXNlIGFjY2VzcyBsYXllciBmb3IgZW50aXRpZXNcclxuICAgKi9cclxuICByZXBvc2l0b3JpZXM6IFtcclxuICAgIFVzZXJSZXBvc2l0b3J5LCAgICAgICAvLyBVc2VycyB0YWJsZSBhY2Nlc3NcclxuICAgIFJvbGVSZXBvc2l0b3J5LCAgICAgICAvLyBSb2xlcyB0YWJsZSBhY2Nlc3NcclxuICAgIFBlcm1pc3Npb25SZXBvc2l0b3J5LCAvLyBQZXJtaXNzaW9ucyB0YWJsZSBhY2Nlc3NcclxuICAgIFRva2VuUmVwb3NpdG9yeSwgICAgICAvLyBUb2tlbnMgdGFibGUgYWNjZXNzXHJcbiAgXSxcclxuXHJcbiAgLyoqXHJcbiAgICogQWRkaXRpb25hbCBQcm92aWRlcnNcclxuICAgKiBWYWxpZGF0b3JzIGFuZCBHdWFyZHMgZm9yIHJlcXVlc3QgdmFsaWRhdGlvbiBhbmQgcm91dGUgcHJvdGVjdGlvblxyXG4gICAqL1xyXG4gIHByb3ZpZGVyczogW1xyXG4gICAgVXNlclZhbGlkYXRvciwgICAgICAgLy8gVXNlciBkYXRhIHZhbGlkYXRpb25cclxuICAgIFJvbGVWYWxpZGF0b3IsICAgICAgIC8vIFJvbGUgZGF0YSB2YWxpZGF0aW9uXHJcbiAgICBQZXJtaXNzaW9uVmFsaWRhdG9yLCAvLyBQZXJtaXNzaW9uIGRhdGEgdmFsaWRhdGlvblxyXG4gICAgUm9sZUd1YXJkcywgICAgICAgICAgLy8gUm9sZS1iYXNlZCByb3V0ZSBndWFyZHNcclxuICAgIFBlcm1pc3Npb25HdWFyZHMsICAgIC8vIFBlcm1pc3Npb24tYmFzZWQgcm91dGUgZ3VhcmRzXHJcbiAgXSxcclxuXHJcbiAgLyoqXHJcbiAgICogU2V0dXAgaG9vayAtIGNhbGxlZCBhZnRlciBwbHVnaW4gcmVnaXN0cmF0aW9uXHJcbiAgICovXHJcbiAgb25TZXR1cDogYXN5bmMgKCkgPT4ge1xyXG4gICAgY29uc29sZS5sb2coJyAg4pyTIG5ham0tYXV0aCBwbHVnaW4gaW5pdGlhbGl6ZWQnKTtcclxuICAgIGNvbnNvbGUubG9nKCcgICAgLSBBdXRoZW50aWNhdGlvbiBlbmRwb2ludHMgcmVhZHknKTtcclxuICAgIGNvbnNvbGUubG9nKCcgICAgLSBBdXRob3JpemF0aW9uIHN5c3RlbSBhY3RpdmUnKTtcclxuICAgIGNvbnNvbGUubG9nKCcgICAgLSBEYXRhYmFzZSBjb25uZWN0aW9uIGVzdGFibGlzaGVkJyk7XHJcbiAgfSxcclxuXHJcbiAgLyoqXHJcbiAgICogVGVhcmRvd24gaG9vayAtIGNhbGxlZCBiZWZvcmUgcGx1Z2luIHJlbW92YWxcclxuICAgKi9cclxuICBvblRlYXJkb3duOiBhc3luYyAoKSA9PiB7XHJcbiAgICBjb25zb2xlLmxvZygnICDinJMgbmFqbS1hdXRoIHBsdWdpbiBjbGVhbnVwIGNvbXBsZXRlJyk7XHJcbiAgfSxcclxufTsiCiAgXSwKICAibWFwcGluZ3MiOiAiK2tCQUNBLHFCQUFTLGtCQUNULHVCQUdPLE1BQU0sQ0FBa0IsQ0FDN0IsV0FBVyxFQUFHLE9BRVIsYUFBWSxDQUFDLEVBQVUsQ0FDM0IsSUFBSyxFQUFVLE9BQU8sS0FDdEIsR0FBSSxPQUFPLElBQWEsVUFBWSxFQUFTLEtBQUssRUFBRSxTQUFXLEVBQzdELE9BQU8sS0FFVCxPQUFPLEdBQU8sS0FBSyxFQUFVLEVBQUUsT0FHM0IsZ0JB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LEdBQVcsRUFBRSxFQUN0RCxVQUFXLEdBQVUsYUFBYyxDQUFFLEtBQU0sUUFBUyxDQUFDLEtBQ2xELEVBQ0wsQ0FBQyxFQUVZLEdBQWMsR0FBUSxTQUFVLENBQzNDLEdBQUksR0FBUSxFQUFFLEVBQ2QsT0FBUSxFQUFLLFNBQVMsRUFBRSxXQUFXLElBQU0sR0FBVyxHQUFJLENBQUUsU0FBVSxTQUFVLENBQUMsRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUNsRyxNQUFPLEVBQUssT0FBTyxFQUFFLFFBQVEsRUFDN0IsS0FBTSxHQUFjLE1BQU0sRUFBRSxRQUFRLFNBQVMsRUFDN0MsT0FBUSxHQUFnQixRQUFRLEVBQUUsUUFBUSxRQUFRLEVBQ2xELFVBQVcsR0FBVSxhQUFjLENBQUUsS0FBTSxRQUFTLENBQUMsRUFBRSxRQUFRLEtBQzVELEVBQ0wsQ0FBQyxFQUdZLEdBQW1CLEdBQVEsY0FBZSxDQUNyRCxHQUFJLEdBQVEsRUFDWixLQUFNLEVBQUssTUFBTSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQ3BDLFlBQWEsRUFBSyxhQUFhLEVBQy9CLFNBQVUsRUFBSyxVQUFVLEVBQUUsUUFBUSxFQUNuQyxPQUFRLEVBQUssUUFBUSxFQUFFLFFBQVEsS0FDNUIsRUFDTCxDQUFDLEVBR1ksR0FBdUIsR0FBUSxtQkFBb0IsQ0FDOUQsR0FBSSxHQUFRLEVBQ1osT0FBUSxFQUFLLFNBQVMsRUFBRSxXQUFXLElBQU0sR0FBVyxFQUFFLEVBQUUsUUFBUSxFQUNoRSxhQUFjLEVBQUssZUFBZSxFQUFFLFdBQVcsSUFBTSxHQUFpQixFQUFFLEVBQUUsUUFBUSxLQUMvRSxFQUNMLENBQUMsRUR6Qk0sSUFBTSxHQUFxQixRQUFRLElBQUksT0FDMUMsR0FBUSxRQUFRLElBQUksT0FBUSxDQUFFLFNBQU8sQ0FBQyxFQUN0QyxLQUVKLEdBQThDLEdBQzVDLFFBQVEsS0FBSyx3RkFBdUYsRUdvQi9GLElBQU0sR0FBMkIsQ0FDdEMsS0FBTSxZQUNOLFFBQVMsUUFPVCxTQUFVLE9BTVYsWUFBYSxDQUNYLEdBQ0EsR0FDQSxHQUNBLEVBQ0YsRUFNQSxTQUFVLENBQ1IsRUFDQSxFQUNBLEVBQ0EsRUFDQSxFQUNBLEVBQ0EsQ0FDRixFQU1BLGFBQWMsQ0FDWixFQUNBLEVBQ0EsRUFDQSxDQUNGLEVBTUEsVUFBVyxDQUNULEVBQ0EsRUFDQSxFQUNBLEVBQ0EsRUFDRixFQUtBLFFBQVMsU0FBWSxDQUNuQixRQUFRLElBQUksa0NBQWlDLEVBQzdDLFFBQVEsSUFBSSxzQ0FBc0MsRUFDbEQsUUFBUSxJQUFJLG1DQUFtQyxFQUMvQyxRQUFRLElBQUksdUNBQXVDLEdBTXJELFdBQVksU0FBWSxDQUN0QixRQUFRLElBQUksdUNBQXNDLEVBRXREIiwKICAiZGVidWdJZCI6ICI0NjQ0MEQ3RjVFOUYzMDcyNjQ3NTZFMjE2NDc1NkUyMSIsCiAgIm5hbWVzIjogW10KfQ==
1
+ var __defProp = Object.defineProperty;
2
+ var __export = (target, all) => {
3
+ for (var name in all)
4
+ __defProp(target, name, {
5
+ get: all[name],
6
+ enumerable: true,
7
+ configurable: true,
8
+ set: (newValue) => all[name] = () => newValue
9
+ });
10
+ };
11
+ var __legacyDecorateClassTS = function(decorators, target, key, desc) {
12
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
13
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
14
+ r = Reflect.decorate(decorators, target, key, desc);
15
+ else
16
+ for (var i = decorators.length - 1;i >= 0; i--)
17
+ if (d = decorators[i])
18
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
19
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
20
+ };
21
+ var __legacyDecorateParamTS = (index, decorator) => (target, key) => decorator(target, key, index);
22
+ var __legacyMetadataTS = (k, v) => {
23
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
24
+ return Reflect.metadata(k, v);
25
+ };
26
+
27
+ // src/auth/EncryptionService.ts
28
+ import { Injectable } from "najm-api";
29
+ import bcrypt from "bcrypt";
30
+ class EncryptionService {
31
+ constructor() {}
32
+ async hashPassword(password) {
33
+ if (!password)
34
+ return null;
35
+ if (typeof password !== "string" || password.trim().length === 0) {
36
+ return null;
37
+ }
38
+ return bcrypt.hash(password, 10);
39
+ }
40
+ async comparePassword(password, hashedPassword) {
41
+ return bcrypt.compare(password, hashedPassword);
42
+ }
43
+ }
44
+ EncryptionService = __legacyDecorateClassTS([
45
+ Injectable(),
46
+ __legacyMetadataTS("design:paramtypes", [])
47
+ ], EncryptionService);
48
+ // src/auth/CookieService.ts
49
+ import { setCookie, Injectable as Injectable2, deleteCookie } from "najm-api";
50
+ import timestring from "timestring";
51
+ class CookieService {
52
+ setRefreshCookie(refreshToken) {
53
+ const maxAge = timestring(process.env.REFRESH_EXPIRES_IN, "s");
54
+ setCookie("refreshToken", refreshToken, {
55
+ httpOnly: false,
56
+ sameSite: "Lax",
57
+ maxAge,
58
+ path: "/api/auth/refresh"
59
+ });
60
+ }
61
+ clearRefreshCookie() {
62
+ deleteCookie("refreshToken", {
63
+ httpOnly: false,
64
+ sameSite: "Lax",
65
+ path: "/api/auth/refresh",
66
+ maxAge: 0
67
+ });
68
+ }
69
+ }
70
+ CookieService = __legacyDecorateClassTS([
71
+ Injectable2()
72
+ ], CookieService);
73
+ // src/auth/AuthController.ts
74
+ import { Controller as Controller3, Get as Get3, Post as Post3, Params as Params3, Body as Body3, User as User2, t as t7 } from "najm-api";
75
+
76
+ // src/auth/AuthService.ts
77
+ import { t as t6 } from "najm-api";
78
+ import { Injectable as Injectable9, getCurrentLanguage as getCurrentLanguage2 } from "najm-api";
79
+
80
+ // src/users/UserRepository.ts
81
+ import { rolesTable, usersTable, permissionsTable, rolePermissionsTable } from "@/database/schema";
82
+ import { eq, ne } from "drizzle-orm";
83
+ import { Repository } from "najm-api";
84
+ class UserRepository {
85
+ getUser() {
86
+ return {
87
+ id: usersTable.id,
88
+ email: usersTable.email,
89
+ emailVerified: usersTable.emailVerified,
90
+ image: usersTable.image,
91
+ status: usersTable.status,
92
+ roleId: usersTable.roleId,
93
+ role: rolesTable.name,
94
+ createdAt: usersTable.createdAt,
95
+ updatedAt: usersTable.updatedAt
96
+ };
97
+ }
98
+ async getAll() {
99
+ const allUsers = await this.db.select(this.getUser()).from(usersTable).leftJoin(rolesTable, eq(usersTable.roleId, rolesTable.id));
100
+ return Promise.all(allUsers.map(async (user) => ({
101
+ ...user,
102
+ permissions: await this.getUserPermissions(user.id)
103
+ })));
104
+ }
105
+ async getById(id) {
106
+ const [user] = await this.db.select(this.getUser()).from(usersTable).leftJoin(rolesTable, eq(usersTable.roleId, rolesTable.id)).where(eq(usersTable.id, id)).limit(1);
107
+ if (!user)
108
+ return user;
109
+ return {
110
+ ...user,
111
+ permissions: await this.getUserPermissions(user.id)
112
+ };
113
+ }
114
+ async getByEmail(email) {
115
+ const [existingUser] = await this.db.select(this.getUser()).from(usersTable).leftJoin(rolesTable, eq(usersTable.roleId, rolesTable.id)).where(eq(usersTable.email, email));
116
+ return existingUser;
117
+ }
118
+ async create(data) {
119
+ const [newUser] = await this.db.insert(usersTable).values(data).returning();
120
+ return newUser;
121
+ }
122
+ async update(id, data) {
123
+ const [updatedUser] = await this.db.update(usersTable).set(data).where(eq(usersTable.id, id)).returning();
124
+ return updatedUser;
125
+ }
126
+ async delete(id) {
127
+ const [deletedUser] = await this.db.delete(usersTable).where(eq(usersTable.id, id)).returning();
128
+ return deletedUser;
129
+ }
130
+ async deleteAll() {
131
+ const adminRole = await this.db.select({ id: rolesTable.id }).from(rolesTable).where(eq(rolesTable.name, "admin")).limit(1);
132
+ if (adminRole.length === 0) {
133
+ const deletedUsers2 = await this.db.delete(usersTable).returning();
134
+ return deletedUsers2;
135
+ }
136
+ const deletedUsers = await this.db.delete(usersTable).where(ne(usersTable.roleId, adminRole[0].id)).returning();
137
+ return deletedUsers;
138
+ }
139
+ async getRoleNameById(userId) {
140
+ const [role] = await this.db.select({
141
+ roleName: rolesTable.name
142
+ }).from(usersTable).leftJoin(rolesTable, eq(usersTable.roleId, rolesTable.id)).where(eq(usersTable.id, userId));
143
+ return role.roleName;
144
+ }
145
+ async getUserPassword(email) {
146
+ const [user] = await this.db.select({
147
+ id: usersTable.id,
148
+ email: usersTable.email,
149
+ password: usersTable.password
150
+ }).from(usersTable).where(eq(usersTable.email, email)).limit(1);
151
+ return user.password;
152
+ }
153
+ async getUserPermissions(userId) {
154
+ const [user] = await this.db.select({ roleId: usersTable.roleId }).from(usersTable).where(eq(usersTable.id, userId)).limit(1);
155
+ if (!user || !user.roleId)
156
+ return [];
157
+ const userPermissions = await this.db.select({
158
+ name: permissionsTable.name
159
+ }).from(rolePermissionsTable).leftJoin(permissionsTable, eq(rolePermissionsTable.permissionId, permissionsTable.id)).where(eq(rolePermissionsTable.roleId, user.roleId));
160
+ return userPermissions.map((p) => p.name).filter((name) => name);
161
+ }
162
+ }
163
+ UserRepository = __legacyDecorateClassTS([
164
+ Repository()
165
+ ], UserRepository);
166
+ // src/users/UserValidator.ts
167
+ import { Injectable as Injectable3, t } from "najm-api";
168
+ import { parseSchema } from "@/shared";
169
+ import { userSchema } from "@/lib/validations";
170
+ class UserValidator {
171
+ userRepository;
172
+ encryptionService;
173
+ constructor(userRepository, encryptionService) {
174
+ this.userRepository = userRepository;
175
+ this.encryptionService = encryptionService;
176
+ }
177
+ async validateCreateUser(data) {
178
+ return parseSchema(userSchema, data);
179
+ }
180
+ async isEmailExists(email) {
181
+ const existingUser = await this.userRepository.getByEmail(email);
182
+ return !!existingUser;
183
+ }
184
+ async isPasswordValid(password, hashedPassword) {
185
+ const isPasswordValid = await this.encryptionService.comparePassword(password, hashedPassword);
186
+ return !!isPasswordValid;
187
+ }
188
+ async isUserExist(id) {
189
+ const existingUser = await this.userRepository.getById(id);
190
+ return !!existingUser;
191
+ }
192
+ async checkUserIdIsUnique(id) {
193
+ if (!id)
194
+ return;
195
+ const existingUser = await this.userRepository.getById(id);
196
+ if (existingUser) {
197
+ throw new Error(t("users.errors.idExists"));
198
+ }
199
+ }
200
+ async isCorrectPass(password) {
201
+ return password && typeof password === "string" && password.trim().length > 0;
202
+ }
203
+ async hasRole(userId, roles) {
204
+ const roleName = await this.userRepository.getRoleNameById(userId);
205
+ if (!roleName) {
206
+ throw Error(t("auth.errors.accessDenied"));
207
+ }
208
+ const hasRole = roles.some((item) => roleName.toLowerCase() === item.toLowerCase());
209
+ if (!hasRole) {
210
+ throw Error(t("auth.errors.accessDenied"));
211
+ }
212
+ return true;
213
+ }
214
+ async checkUserExistsByEmail(email) {
215
+ const user = await this.userRepository.getByEmail(email);
216
+ if (!user) {
217
+ throw new Error(t("auth.errors.invalidCredentials"));
218
+ }
219
+ return user;
220
+ }
221
+ async checkUserExists(id) {
222
+ const userExists = await this.isUserExist(id);
223
+ if (!userExists) {
224
+ throw new Error(t("users.errors.notFound"));
225
+ }
226
+ return userExists;
227
+ }
228
+ async checkEmailUnique(email, excludeId = null) {
229
+ if (!email)
230
+ return;
231
+ const existingUser = await this.userRepository.getByEmail(email);
232
+ if (existingUser && existingUser.id !== excludeId) {
233
+ throw new Error(t("auth.errors.emailExists"));
234
+ }
235
+ }
236
+ async checkEmailExists(email) {
237
+ const user = await this.userRepository.getByEmail(email);
238
+ if (!user) {
239
+ throw new Error(t("users.errors.notFound"));
240
+ }
241
+ return user;
242
+ }
243
+ async checkPasswordValid(password, hashedPassword) {
244
+ const isPasswordValid = await this.isPasswordValid(password, hashedPassword);
245
+ if (!isPasswordValid) {
246
+ throw new Error(t("auth.errors.invalidCredentials"));
247
+ }
248
+ }
249
+ }
250
+ UserValidator = __legacyDecorateClassTS([
251
+ Injectable3(),
252
+ __legacyMetadataTS("design:paramtypes", [
253
+ typeof UserRepository === "undefined" ? Object : UserRepository,
254
+ typeof EncryptionService === "undefined" ? Object : EncryptionService
255
+ ])
256
+ ], UserValidator);
257
+ // src/users/UserService.ts
258
+ import { Injectable as Injectable8, setLanguage, getCurrentLanguage, Transactional } from "najm-api";
259
+
260
+ // src/roles/RoleRepository.ts
261
+ import { rolesTable as rolesTable2 } from "@/database/schema";
262
+ import { eq as eq2 } from "drizzle-orm";
263
+ import { Repository as Repository2 } from "najm-api";
264
+ class RoleRepository {
265
+ async getAll() {
266
+ return await this.db.select().from(rolesTable2);
267
+ }
268
+ async getById(id) {
269
+ const [existingRole] = await this.db.select().from(rolesTable2).where(eq2(rolesTable2.id, id));
270
+ return existingRole;
271
+ }
272
+ async getByName(name) {
273
+ const [existingRole] = await this.db.select().from(rolesTable2).where(eq2(rolesTable2.name, name));
274
+ return existingRole;
275
+ }
276
+ async create(data) {
277
+ const [newRole] = await this.db.insert(rolesTable2).values(data).returning();
278
+ return newRole;
279
+ }
280
+ async update(id, data) {
281
+ const [updatedRole] = await this.db.update(rolesTable2).set(data).where(eq2(rolesTable2.id, id)).returning();
282
+ return updatedRole;
283
+ }
284
+ async delete(id) {
285
+ const [deletedRole] = await this.db.delete(rolesTable2).where(eq2(rolesTable2.id, id)).returning();
286
+ return deletedRole;
287
+ }
288
+ }
289
+ RoleRepository = __legacyDecorateClassTS([
290
+ Repository2()
291
+ ], RoleRepository);
292
+ // src/roles/RoleValidator.ts
293
+ import { Injectable as Injectable4, t as t2 } from "najm-api";
294
+ import { parseSchema as parseSchema2 } from "@/shared";
295
+ import { roleSchema } from "@/lib/validations";
296
+ class RoleValidator {
297
+ roleRepository;
298
+ constructor(roleRepository) {
299
+ this.roleRepository = roleRepository;
300
+ }
301
+ async validateCreateRole(data) {
302
+ return parseSchema2(roleSchema, data);
303
+ }
304
+ async isRoleNameExists(roleName) {
305
+ const existingRole = await this.roleRepository.getByName(roleName);
306
+ return !!existingRole;
307
+ }
308
+ async isRoleIdExists(id) {
309
+ const existingRole = await this.roleRepository.getById(id);
310
+ return !!existingRole;
311
+ }
312
+ async checkNameUnique(roleName, excludeId = null) {
313
+ if (!roleName)
314
+ return;
315
+ const existingRole = await this.roleRepository.getByName(roleName);
316
+ if (existingRole && existingRole.id !== excludeId) {
317
+ throw new Error(t2("roles.errors.exists"));
318
+ }
319
+ }
320
+ async checkRoleExists(id) {
321
+ const roleIdExists = await this.isRoleIdExists(id);
322
+ if (!roleIdExists) {
323
+ throw new Error(t2("roles.errors.notFound"));
324
+ }
325
+ }
326
+ async checkRoleExistsByName(roleName) {
327
+ const roleNameExists = await this.isRoleNameExists(roleName);
328
+ if (!roleNameExists) {
329
+ throw new Error(t2("roles.errors.notFound"));
330
+ }
331
+ }
332
+ async checkAdminRoleExists() {
333
+ const adminRole = await this.roleRepository.getByName("admin");
334
+ if (!adminRole) {
335
+ throw new Error(t2("users.errors.adminRoleNotFound"));
336
+ }
337
+ return adminRole;
338
+ }
339
+ }
340
+ RoleValidator = __legacyDecorateClassTS([
341
+ Injectable4(),
342
+ __legacyMetadataTS("design:paramtypes", [
343
+ typeof RoleRepository === "undefined" ? Object : RoleRepository
344
+ ])
345
+ ], RoleValidator);
346
+ // src/roles/RoleGuards.ts
347
+ import { Injectable as Injectable6, Headers as Headers2, createGuard, GuardParams, Ctx as Ctx2 } from "najm-api";
348
+
349
+ // src/tokens/TokenRepository.ts
350
+ import { tokensTable, usersTable as usersTable2, rolesTable as rolesTable3, permissionsTable as permissionsTable2, rolePermissionsTable as rolePermissionsTable2 } from "@/database/schema";
351
+ import { eq as eq3 } from "drizzle-orm";
352
+ import { Repository as Repository3 } from "najm-api";
353
+ class TokenRepository {
354
+ async storeRefreshToken(tokenData) {
355
+ return await this.db.insert(tokensTable).values(tokenData).onConflictDoUpdate({
356
+ target: tokensTable.userId,
357
+ set: {
358
+ token: tokenData.token,
359
+ expiresAt: tokenData.expiresAt
360
+ }
361
+ }).returning();
362
+ }
363
+ async getRefreshToken(userId) {
364
+ const [token] = await this.db.select().from(tokensTable).where(eq3(tokensTable.userId, userId));
365
+ return token?.token;
366
+ }
367
+ async revokeToken(userId) {
368
+ const [deletedToken] = await this.db.delete(tokensTable).where(eq3(tokensTable.userId, userId)).returning();
369
+ return deletedToken;
370
+ }
371
+ async isUserExists(userId) {
372
+ const [user] = await this.db.select({ id: usersTable2.id }).from(usersTable2).where(eq3(usersTable2.id, userId)).limit(1);
373
+ return !!user;
374
+ }
375
+ async getRoleNameById(userId) {
376
+ const [role] = await this.db.select({
377
+ roleName: rolesTable3.name
378
+ }).from(usersTable2).leftJoin(rolesTable3, eq3(usersTable2.roleId, rolesTable3.id)).where(eq3(usersTable2.id, userId)).limit(1);
379
+ return role?.roleName;
380
+ }
381
+ async getUserPermissions(userId) {
382
+ const [user] = await this.db.select({ roleId: usersTable2.roleId }).from(usersTable2).where(eq3(usersTable2.id, userId)).limit(1);
383
+ if (!user || !user.roleId)
384
+ return [];
385
+ const userPermissions = await this.db.select({
386
+ name: permissionsTable2.name
387
+ }).from(rolePermissionsTable2).leftJoin(permissionsTable2, eq3(rolePermissionsTable2.permissionId, permissionsTable2.id)).where(eq3(rolePermissionsTable2.roleId, user.roleId));
388
+ return userPermissions.map((p) => p.name).filter((name) => name);
389
+ }
390
+ async getUser(userId) {
391
+ const [user] = await this.db.select({
392
+ id: usersTable2.id,
393
+ email: usersTable2.email,
394
+ status: usersTable2.status,
395
+ roleId: usersTable2.roleId,
396
+ roleName: rolesTable3.name,
397
+ createdAt: usersTable2.createdAt,
398
+ updatedAt: usersTable2.updatedAt
399
+ }).from(usersTable2).leftJoin(rolesTable3, eq3(usersTable2.roleId, rolesTable3.id)).where(eq3(usersTable2.id, userId)).limit(1);
400
+ return user ? { ...user, role: user.roleName } : null;
401
+ }
402
+ }
403
+ TokenRepository = __legacyDecorateClassTS([
404
+ Repository3()
405
+ ], TokenRepository);
406
+ // src/tokens/TokenService.ts
407
+ import { t as t3 } from "najm-api";
408
+ import { getCookie, Injectable as Injectable5 } from "najm-api";
409
+ import jwt from "jsonwebtoken";
410
+ import { jwtDecode } from "jwt-decode";
411
+ import timestring2 from "timestring";
412
+ class TokenService {
413
+ tokenRepository;
414
+ accessSecretKey = process.env.JWT_ACCESS_SECRET;
415
+ accessExpiresIn = process.env.ACCESS_EXPIRES_IN;
416
+ refreshSecretKey = process.env.JWT_REFRESH_SECRET;
417
+ refreshExpiresIn = process.env.REFRESH_EXPIRES_IN;
418
+ constructor(tokenRepository) {
419
+ this.tokenRepository = tokenRepository;
420
+ }
421
+ extractAccessToken(authorization) {
422
+ if (authorization && authorization.startsWith("Bearer")) {
423
+ return authorization.split(" ")[1];
424
+ }
425
+ throw new Error(t3("auth.errors.tokenMissing"));
426
+ }
427
+ verifyAccessToken(token) {
428
+ try {
429
+ return jwt.verify(token, this.accessSecretKey);
430
+ } catch (error) {
431
+ throw new Error(t3("auth.errors.tokenVerificationFailed"));
432
+ }
433
+ }
434
+ verifyRefreshToken(token) {
435
+ try {
436
+ const decoded = jwt.verify(token, this.refreshSecretKey);
437
+ return decoded.userId;
438
+ } catch (error) {
439
+ throw new Error(t3("auth.errors.tokenVerificationFailed"));
440
+ }
441
+ }
442
+ async getUserIdByAccessToken(header) {
443
+ const token = this.extractAccessToken(header);
444
+ const decodedToken = this.verifyAccessToken(token);
445
+ const userId = decodedToken.userId;
446
+ const userExists = await this.tokenRepository.isUserExists(userId);
447
+ if (!userExists) {
448
+ throw new Error(t3("users.errors.notFound"));
449
+ }
450
+ return userId;
451
+ }
452
+ async storeRefreshToken(userId, refreshToken) {
453
+ const expireInSecond = timestring2(this.refreshExpiresIn, "s");
454
+ const tokenData = {
455
+ userId,
456
+ token: refreshToken,
457
+ expiresAt: new Date(Date.now() + expireInSecond * 1000).toISOString()
458
+ };
459
+ await this.tokenRepository.storeRefreshToken(tokenData);
460
+ }
461
+ getTokenExpire(token) {
462
+ return jwtDecode(token).exp;
463
+ }
464
+ generateAccessToken(data) {
465
+ const options = { expiresIn: this.accessExpiresIn };
466
+ return jwt.sign(data, this.accessSecretKey, options);
467
+ }
468
+ generateRefreshToken(data) {
469
+ const options = { expiresIn: this.refreshExpiresIn };
470
+ return jwt.sign(data, this.refreshSecretKey, options);
471
+ }
472
+ async generateTokens(userId) {
473
+ const tokenData = { userId };
474
+ const accessToken = await this.generateAccessToken(tokenData);
475
+ const refreshToken = await this.generateRefreshToken(tokenData);
476
+ const accessTokenExpiresAt = this.getTokenExpire(accessToken);
477
+ const refreshTokenExpiresAt = this.getTokenExpire(refreshToken);
478
+ await this.storeRefreshToken(userId, refreshToken);
479
+ return {
480
+ accessToken,
481
+ refreshToken,
482
+ accessTokenExpiresAt,
483
+ refreshTokenExpiresAt
484
+ };
485
+ }
486
+ async refreshTokens() {
487
+ const newRefreshToken = getCookie("refreshToken");
488
+ const userId = this.verifyRefreshToken(newRefreshToken);
489
+ const userExists = await this.tokenRepository.isUserExists(userId);
490
+ if (!userExists) {
491
+ throw new Error(t3("users.errors.notFound"));
492
+ }
493
+ const storedRefreshToken = await this.tokenRepository.getRefreshToken(userId);
494
+ if (newRefreshToken != storedRefreshToken) {
495
+ throw new Error(t3("auth.errors.refreshTokenInvalid"));
496
+ }
497
+ return await this.generateTokens(userId);
498
+ }
499
+ async revokeToken(userId) {
500
+ return await this.tokenRepository.revokeToken(userId);
501
+ }
502
+ async getUserPermissions(auth) {
503
+ if (!auth)
504
+ return;
505
+ const userId = await this.getUserIdByAccessToken(auth);
506
+ const permissions = await this.tokenRepository.getUserPermissions(userId);
507
+ return permissions;
508
+ }
509
+ async getUserRole(auth) {
510
+ if (!auth)
511
+ return;
512
+ const userId = await this.getUserIdByAccessToken(auth);
513
+ const roleName = await this.tokenRepository.getRoleNameById(userId);
514
+ return roleName;
515
+ }
516
+ async getUser(auth) {
517
+ if (!auth)
518
+ return;
519
+ const userId = await this.getUserIdByAccessToken(auth);
520
+ const user = await this.tokenRepository.getUser(userId);
521
+ if (!user)
522
+ return null;
523
+ return user;
524
+ }
525
+ async storeUserInCache(auth, ctx) {
526
+ const cachedUser = ctx.get("user");
527
+ if (cachedUser)
528
+ return cachedUser;
529
+ const user = await this.getUser(auth);
530
+ if (user) {
531
+ ctx.set("user", user);
532
+ }
533
+ return user;
534
+ }
535
+ }
536
+ TokenService = __legacyDecorateClassTS([
537
+ Injectable5(),
538
+ __legacyMetadataTS("design:paramtypes", [
539
+ typeof TokenRepository === "undefined" ? Object : TokenRepository
540
+ ])
541
+ ], TokenService);
542
+ // src/roles/RoleGuards.ts
543
+ var ROLES = {
544
+ ADMIN: "admin",
545
+ PRINCIPAL: "principal",
546
+ ACCOUNTING: "accounting",
547
+ SECRETARY: "secretary",
548
+ TEACHER: "teacher",
549
+ STUDENT: "student",
550
+ PARENT: "parent"
551
+ };
552
+ var ROLE_GROUPS = {
553
+ ADMINISTRATORS: [ROLES.ADMIN, ROLES.PRINCIPAL],
554
+ FINANCIAL: [ROLES.ADMIN, ROLES.ACCOUNTING],
555
+ STAFF: [ROLES.ADMIN, ROLES.PRINCIPAL, ROLES.ACCOUNTING, ROLES.SECRETARY, ROLES.TEACHER],
556
+ END_USERS: [ROLES.STUDENT, ROLES.PARENT],
557
+ ALL: [ROLES.ADMIN, ROLES.PRINCIPAL, ROLES.ACCOUNTING, ROLES.SECRETARY, ROLES.TEACHER, ROLES.STUDENT, ROLES.PARENT]
558
+ };
559
+
560
+ class RoleChecker {
561
+ isInGroup(userRole, group) {
562
+ return group.includes(userRole?.toLowerCase());
563
+ }
564
+ isAdministrator(userRole) {
565
+ return this.isInGroup(userRole, ROLE_GROUPS.ADMINISTRATORS);
566
+ }
567
+ isStaff(userRole) {
568
+ return this.isInGroup(userRole, ROLE_GROUPS.STAFF);
569
+ }
570
+ hasAnyRole(userRole, roles) {
571
+ return roles.includes(userRole?.toLowerCase());
572
+ }
573
+ hasExactRole(userRole, requiredRole) {
574
+ return userRole?.toLowerCase() === requiredRole?.toLowerCase();
575
+ }
576
+ }
577
+ RoleChecker = __legacyDecorateClassTS([
578
+ Injectable6()
579
+ ], RoleChecker);
580
+
581
+ class RoleGuards {
582
+ roleChecker;
583
+ tokenService;
584
+ constructor(roleChecker, tokenService) {
585
+ this.roleChecker = roleChecker;
586
+ this.tokenService = tokenService;
587
+ }
588
+ async isAuth(auth, ctx) {
589
+ const user = await this.tokenService.storeUserInCache(auth, ctx);
590
+ return !!user;
591
+ }
592
+ async hasRoles(auth, ctx, roles) {
593
+ try {
594
+ const user = await this.tokenService.storeUserInCache(auth, ctx);
595
+ if (!user?.role)
596
+ return false;
597
+ const roleArray = Array.isArray(roles) ? roles : [roles];
598
+ return this.roleChecker.hasAnyRole(user.role, roleArray);
599
+ } catch {
600
+ return false;
601
+ }
602
+ }
603
+ }
604
+ __legacyDecorateClassTS([
605
+ __legacyDecorateParamTS(0, Headers2("authorization")),
606
+ __legacyDecorateParamTS(1, Ctx2()),
607
+ __legacyMetadataTS("design:type", Function),
608
+ __legacyMetadataTS("design:paramtypes", [
609
+ Object,
610
+ Object
611
+ ]),
612
+ __legacyMetadataTS("design:returntype", Object)
613
+ ], RoleGuards.prototype, "isAuth", null);
614
+ __legacyDecorateClassTS([
615
+ __legacyDecorateParamTS(0, Headers2("authorization")),
616
+ __legacyDecorateParamTS(1, Ctx2()),
617
+ __legacyDecorateParamTS(2, GuardParams()),
618
+ __legacyMetadataTS("design:type", Function),
619
+ __legacyMetadataTS("design:paramtypes", [
620
+ Object,
621
+ Object,
622
+ Object
623
+ ]),
624
+ __legacyMetadataTS("design:returntype", Object)
625
+ ], RoleGuards.prototype, "hasRoles", null);
626
+ RoleGuards = __legacyDecorateClassTS([
627
+ Injectable6(),
628
+ __legacyMetadataTS("design:paramtypes", [
629
+ typeof RoleChecker === "undefined" ? Object : RoleChecker,
630
+ typeof TokenService === "undefined" ? Object : TokenService
631
+ ])
632
+ ], RoleGuards);
633
+ var isAdmin = () => Role("admin");
634
+ var isPrincipal = () => Role("principal");
635
+ var isAccounting = () => Role("accounting");
636
+ var isSecretary = () => Role("secretary");
637
+ var isTeacher = () => Role("teacher");
638
+ var isParent = () => Role("parent");
639
+ var isStudent = () => Role("student");
640
+ var isAdministrator = () => Role("admin", "principal");
641
+ var isFinancial = () => Role("admin", "accounting");
642
+ var isStaff = () => Role("admin", "principal", "accounting", "secretary", "teacher");
643
+ var isAuth = createGuard(RoleGuards, "isAuth");
644
+ var Role = (...roles) => createGuard(RoleGuards, "hasRoles")(...roles);
645
+ // src/roles/RoleController.ts
646
+ import { Controller, Get, Post, Put, Delete, Params, Body, t as t4 } from "najm-api";
647
+
648
+ // src/roles/RoleService.ts
649
+ import { Injectable as Injectable7 } from "najm-api";
650
+ class RoleService {
651
+ roleRepository;
652
+ roleValidator;
653
+ constructor(roleRepository, roleValidator) {
654
+ this.roleRepository = roleRepository;
655
+ this.roleValidator = roleValidator;
656
+ }
657
+ async getAll() {
658
+ return await this.roleRepository.getAll();
659
+ }
660
+ async getById(id) {
661
+ await this.roleValidator.checkRoleExists(id);
662
+ return await this.roleRepository.getById(id);
663
+ }
664
+ async getByName(name) {
665
+ return await this.roleRepository.getByName(name);
666
+ }
667
+ async create(data) {
668
+ await this.roleValidator.validateCreateRole(data);
669
+ await this.roleValidator.checkNameUnique(data.name);
670
+ return await this.roleRepository.create(data);
671
+ }
672
+ async update(id, data) {
673
+ await this.roleValidator.checkRoleExists(id);
674
+ await this.roleValidator.checkNameUnique(data.name, id);
675
+ return await this.roleRepository.update(id, data);
676
+ }
677
+ async delete(id) {
678
+ await this.roleValidator.checkRoleExists(id);
679
+ return await this.roleRepository.delete(id);
680
+ }
681
+ async seedDefaultRoles(defaultRoles) {
682
+ const rolesToCreate = [];
683
+ for (const role of defaultRoles) {
684
+ const exists = await this.roleValidator.isRoleNameExists(role.name);
685
+ if (!exists) {
686
+ rolesToCreate.push(role);
687
+ }
688
+ }
689
+ const createdRoles = await Promise.all(rolesToCreate.map((role) => this.roleRepository.create(role)));
690
+ return createdRoles;
691
+ }
692
+ async getRoleIdByName(name) {
693
+ const teacherRole = await this.getByName(name);
694
+ return teacherRole?.id;
695
+ }
696
+ }
697
+ RoleService = __legacyDecorateClassTS([
698
+ Injectable7(),
699
+ __legacyMetadataTS("design:paramtypes", [
700
+ typeof RoleRepository === "undefined" ? Object : RoleRepository,
701
+ typeof RoleValidator === "undefined" ? Object : RoleValidator
702
+ ])
703
+ ], RoleService);
704
+
705
+ // src/roles/RoleController.ts
706
+ class RoleController {
707
+ roleService;
708
+ constructor(roleService) {
709
+ this.roleService = roleService;
710
+ }
711
+ async getRoles() {
712
+ const roles = await this.roleService.getAll();
713
+ return {
714
+ data: roles,
715
+ message: t4("roles.success.retrieved"),
716
+ status: "success"
717
+ };
718
+ }
719
+ async getRole(id) {
720
+ const role = await this.roleService.getById(id);
721
+ return {
722
+ data: role,
723
+ message: t4("roles.success.retrieved"),
724
+ status: "success"
725
+ };
726
+ }
727
+ async createRole(body) {
728
+ const newRole = await this.roleService.create(body);
729
+ return {
730
+ data: newRole,
731
+ message: t4("roles.success.created"),
732
+ status: "success"
733
+ };
734
+ }
735
+ async updateRole(id, body) {
736
+ const updatedRole = await this.roleService.update(id, body);
737
+ return {
738
+ data: updatedRole,
739
+ message: t4("roles.success.updated"),
740
+ status: "success"
741
+ };
742
+ }
743
+ async deleteRole(id) {
744
+ const result = await this.roleService.delete(id);
745
+ return {
746
+ data: result,
747
+ message: t4("roles.success.deleted"),
748
+ status: "success"
749
+ };
750
+ }
751
+ }
752
+ __legacyDecorateClassTS([
753
+ Get(),
754
+ isAdmin(),
755
+ __legacyMetadataTS("design:type", Function),
756
+ __legacyMetadataTS("design:paramtypes", []),
757
+ __legacyMetadataTS("design:returntype", Promise)
758
+ ], RoleController.prototype, "getRoles", null);
759
+ __legacyDecorateClassTS([
760
+ Get("/:id"),
761
+ isAdmin(),
762
+ __legacyDecorateParamTS(0, Params("id")),
763
+ __legacyMetadataTS("design:type", Function),
764
+ __legacyMetadataTS("design:paramtypes", [
765
+ Object
766
+ ]),
767
+ __legacyMetadataTS("design:returntype", Promise)
768
+ ], RoleController.prototype, "getRole", null);
769
+ __legacyDecorateClassTS([
770
+ Post(),
771
+ isAdmin(),
772
+ __legacyDecorateParamTS(0, Body()),
773
+ __legacyMetadataTS("design:type", Function),
774
+ __legacyMetadataTS("design:paramtypes", [
775
+ Object
776
+ ]),
777
+ __legacyMetadataTS("design:returntype", Promise)
778
+ ], RoleController.prototype, "createRole", null);
779
+ __legacyDecorateClassTS([
780
+ Put("/:id"),
781
+ isAdmin(),
782
+ __legacyDecorateParamTS(0, Params("id")),
783
+ __legacyDecorateParamTS(1, Body()),
784
+ __legacyMetadataTS("design:type", Function),
785
+ __legacyMetadataTS("design:paramtypes", [
786
+ Object,
787
+ Object
788
+ ]),
789
+ __legacyMetadataTS("design:returntype", Promise)
790
+ ], RoleController.prototype, "updateRole", null);
791
+ __legacyDecorateClassTS([
792
+ Delete("/:id"),
793
+ isAdmin(),
794
+ __legacyDecorateParamTS(0, Params("id")),
795
+ __legacyMetadataTS("design:type", Function),
796
+ __legacyMetadataTS("design:paramtypes", [
797
+ Object
798
+ ]),
799
+ __legacyMetadataTS("design:returntype", Promise)
800
+ ], RoleController.prototype, "deleteRole", null);
801
+ RoleController = __legacyDecorateClassTS([
802
+ Controller("/roles"),
803
+ __legacyMetadataTS("design:paramtypes", [
804
+ typeof RoleService === "undefined" ? Object : RoleService
805
+ ])
806
+ ], RoleController);
807
+ // src/users/UserService.ts
808
+ import { nanoid } from "nanoid";
809
+ import { clean } from "@/shared";
810
+ class UserService {
811
+ roleValidator;
812
+ roleService;
813
+ userRepository;
814
+ userValidator;
815
+ encryptionService;
816
+ constructor(roleValidator, roleService, userRepository, userValidator, encryptionService) {
817
+ this.roleValidator = roleValidator;
818
+ this.roleService = roleService;
819
+ this.userRepository = userRepository;
820
+ this.userValidator = userValidator;
821
+ this.encryptionService = encryptionService;
822
+ }
823
+ sanitizeUser(user) {
824
+ if (!user)
825
+ return user;
826
+ const { password, ...sanitizedUser } = user;
827
+ return sanitizedUser;
828
+ }
829
+ sanitizeUsers(users) {
830
+ return users.map((user) => this.sanitizeUser(user));
831
+ }
832
+ async resolveUserRole(roleId, roleName) {
833
+ if (roleId) {
834
+ await this.roleValidator.checkRoleExists(roleId);
835
+ return roleId;
836
+ }
837
+ if (roleName) {
838
+ const roleByName = await this.roleService.getByName(roleName);
839
+ if (roleByName) {
840
+ return roleByName.id;
841
+ }
842
+ throw new Error(`Role '${roleName}' not found`);
843
+ }
844
+ const defaultRole = await this.roleService.getByName("Student");
845
+ return defaultRole.id;
846
+ }
847
+ async getAll() {
848
+ const users = await this.userRepository.getAll();
849
+ return this.sanitizeUsers(users);
850
+ }
851
+ async getById(id) {
852
+ await this.userValidator.checkUserExists(id);
853
+ const user = await this.userRepository.getById(id);
854
+ return this.sanitizeUser(user);
855
+ }
856
+ async getByEmail(email) {
857
+ const user = await this.userValidator.checkUserExistsByEmail(email);
858
+ return this.sanitizeUser(user);
859
+ }
860
+ async create(data) {
861
+ const { id, email, image, emailVerified, password, roleId, role } = data;
862
+ let userId = id || nanoid(5);
863
+ let pass = password || "12345678";
864
+ await this.userValidator.checkEmailUnique(data.email);
865
+ await this.userValidator.checkUserIdIsUnique(id);
866
+ const hashedPassword = await this.encryptionService.hashPassword(pass);
867
+ const resolvedRoleId = await this.resolveUserRole(roleId, role);
868
+ const userDetails = {
869
+ id: userId,
870
+ email,
871
+ image,
872
+ password: hashedPassword,
873
+ roleId: resolvedRoleId,
874
+ emailVerified,
875
+ status: "pending"
876
+ };
877
+ await this.userValidator.validateCreateUser(userDetails);
878
+ const newUser = await this.userRepository.create(userDetails);
879
+ return this.sanitizeUser(newUser);
880
+ }
881
+ async update(id, data) {
882
+ const { password, image } = data;
883
+ await this.userValidator.checkUserExists(id);
884
+ await this.userValidator.checkEmailUnique(data.email, id);
885
+ const currentUser = await this.userRepository.getById(id);
886
+ const hashedPassword = await this.encryptionService.hashPassword(password);
887
+ const updateData = {
888
+ ...data,
889
+ image,
890
+ ...hashedPassword && { password: hashedPassword }
891
+ };
892
+ const cleanedUpdateData = clean(updateData);
893
+ const updatedUser = await this.userRepository.update(id, cleanedUpdateData);
894
+ return this.sanitizeUser(updatedUser);
895
+ }
896
+ async delete(id) {
897
+ await this.userValidator.checkUserExists(id);
898
+ const user = await this.userRepository.delete(id);
899
+ return this.sanitizeUser(user);
900
+ }
901
+ async deleteAll() {
902
+ const deletedUsers = await this.userRepository.deleteAll();
903
+ return this.sanitizeUsers(deletedUsers);
904
+ }
905
+ async getRoleName(id) {
906
+ await this.userValidator.checkUserExists(id);
907
+ return await this.userRepository.getRoleNameById(id);
908
+ }
909
+ async getPassword(email) {
910
+ await this.userValidator.checkUserExistsByEmail(email);
911
+ return await this.userRepository.getUserPassword(email);
912
+ }
913
+ async assignRole(id, roleId, roleName) {
914
+ await this.userValidator.checkUserExists(id);
915
+ const resolvedRoleId = await this.resolveUserRole(roleId, roleName);
916
+ const updatedUser = await this.userRepository.update(id, { roleId: resolvedRoleId });
917
+ return this.sanitizeUser(updatedUser);
918
+ }
919
+ async removeRole(id) {
920
+ await this.userValidator.checkUserExists(id);
921
+ const updatedUser = await this.userRepository.update(id, { roleId: null });
922
+ return this.sanitizeUser(updatedUser);
923
+ }
924
+ async seedAdminUser() {
925
+ const email = "admin@admin.com";
926
+ const adminRole = await this.roleValidator.checkAdminRoleExists();
927
+ const existingUser = await this.userRepository.getByEmail(email);
928
+ if (existingUser) {
929
+ await this.delete(existingUser.id);
930
+ }
931
+ const newAdminUser = await this.create({
932
+ id: "USR00",
933
+ name: "System Administrator",
934
+ email,
935
+ password: "12345678",
936
+ image: null,
937
+ roleId: adminRole.id,
938
+ status: "active",
939
+ emailVerified: true
940
+ });
941
+ return this.sanitizeUser(newAdminUser);
942
+ }
943
+ async updateLang(language) {
944
+ setLanguage(language);
945
+ return language;
946
+ }
947
+ async getLang() {
948
+ return getCurrentLanguage();
949
+ }
950
+ }
951
+ __legacyDecorateClassTS([
952
+ Transactional(),
953
+ __legacyMetadataTS("design:type", Function),
954
+ __legacyMetadataTS("design:paramtypes", [
955
+ Object
956
+ ]),
957
+ __legacyMetadataTS("design:returntype", Promise)
958
+ ], UserService.prototype, "create", null);
959
+ UserService = __legacyDecorateClassTS([
960
+ Injectable8(),
961
+ __legacyMetadataTS("design:paramtypes", [
962
+ typeof RoleValidator === "undefined" ? Object : RoleValidator,
963
+ typeof RoleService === "undefined" ? Object : RoleService,
964
+ typeof UserRepository === "undefined" ? Object : UserRepository,
965
+ typeof UserValidator === "undefined" ? Object : UserValidator,
966
+ typeof EncryptionService === "undefined" ? Object : EncryptionService
967
+ ])
968
+ ], UserService);
969
+ // src/users/UserController.ts
970
+ import { Controller as Controller2, Get as Get2, Post as Post2, Put as Put2, Delete as Delete2, Params as Params2, Body as Body2, t as t5 } from "najm-api";
971
+ import { isAdmin as isAdmin2, isAuth as isAuth2 } from "@/roles/RoleGuards";
972
+ class UserController {
973
+ userService;
974
+ constructor(userService) {
975
+ this.userService = userService;
976
+ }
977
+ async getUsers() {
978
+ const users = await this.userService.getAll();
979
+ return {
980
+ data: users,
981
+ message: t5("users.success.retrieved"),
982
+ status: "success"
983
+ };
984
+ }
985
+ async getLang() {
986
+ const language = await this.userService.getLang();
987
+ return {
988
+ data: { language },
989
+ message: t5("users.success.retrieved"),
990
+ status: "success"
991
+ };
992
+ }
993
+ async updateLang(language) {
994
+ const data = await this.userService.updateLang(language);
995
+ return {
996
+ data,
997
+ message: t5("users.success.updated"),
998
+ status: "success"
999
+ };
1000
+ }
1001
+ async getUser(id) {
1002
+ const user = await this.userService.getById(id);
1003
+ return {
1004
+ data: user,
1005
+ message: t5("users.success.retrieved"),
1006
+ status: "success"
1007
+ };
1008
+ }
1009
+ async getByEmail(email) {
1010
+ const user = await this.userService.getByEmail(email);
1011
+ return {
1012
+ data: user,
1013
+ message: t5("users.success.retrieved"),
1014
+ status: "success"
1015
+ };
1016
+ }
1017
+ async getRole(userId) {
1018
+ const role = await this.userService.getRoleName(userId);
1019
+ return {
1020
+ data: role,
1021
+ message: t5("users.success.retrieved"),
1022
+ status: "success"
1023
+ };
1024
+ }
1025
+ async create(body) {
1026
+ const newUser = await this.userService.create(body);
1027
+ return {
1028
+ data: newUser,
1029
+ message: t5("users.success.created"),
1030
+ status: "success"
1031
+ };
1032
+ }
1033
+ async update(id, body) {
1034
+ const updatedUser = await this.userService.update(id, body);
1035
+ return {
1036
+ data: updatedUser,
1037
+ message: t5("users.success.updated"),
1038
+ status: "success"
1039
+ };
1040
+ }
1041
+ async delete(id) {
1042
+ const result = await this.userService.delete(id);
1043
+ return {
1044
+ data: result,
1045
+ message: t5("users.success.deleted"),
1046
+ status: "success"
1047
+ };
1048
+ }
1049
+ async deleteAll() {
1050
+ const result = await this.userService.deleteAll();
1051
+ return {
1052
+ data: result,
1053
+ message: t5("users.success.allDeleted"),
1054
+ status: "success"
1055
+ };
1056
+ }
1057
+ async assignRole(userId, roleId) {
1058
+ await this.userService.assignRole(userId, roleId);
1059
+ return {
1060
+ message: t5("users.success.updated"),
1061
+ status: "success"
1062
+ };
1063
+ }
1064
+ async removeRole(userId) {
1065
+ await this.userService.removeRole(userId);
1066
+ return {
1067
+ message: t5("users.success.updated"),
1068
+ status: "success"
1069
+ };
1070
+ }
1071
+ }
1072
+ __legacyDecorateClassTS([
1073
+ Get2(),
1074
+ isAdmin2(),
1075
+ __legacyMetadataTS("design:type", Function),
1076
+ __legacyMetadataTS("design:paramtypes", []),
1077
+ __legacyMetadataTS("design:returntype", Promise)
1078
+ ], UserController.prototype, "getUsers", null);
1079
+ __legacyDecorateClassTS([
1080
+ Get2("/lang"),
1081
+ isAuth2(),
1082
+ __legacyMetadataTS("design:type", Function),
1083
+ __legacyMetadataTS("design:paramtypes", []),
1084
+ __legacyMetadataTS("design:returntype", Promise)
1085
+ ], UserController.prototype, "getLang", null);
1086
+ __legacyDecorateClassTS([
1087
+ Post2("/lang/:language"),
1088
+ isAuth2(),
1089
+ __legacyDecorateParamTS(0, Params2("language")),
1090
+ __legacyMetadataTS("design:type", Function),
1091
+ __legacyMetadataTS("design:paramtypes", [
1092
+ Object
1093
+ ]),
1094
+ __legacyMetadataTS("design:returntype", Promise)
1095
+ ], UserController.prototype, "updateLang", null);
1096
+ __legacyDecorateClassTS([
1097
+ Get2("/:id"),
1098
+ isAdmin2(),
1099
+ __legacyDecorateParamTS(0, Params2("id")),
1100
+ __legacyMetadataTS("design:type", Function),
1101
+ __legacyMetadataTS("design:paramtypes", [
1102
+ Object
1103
+ ]),
1104
+ __legacyMetadataTS("design:returntype", Promise)
1105
+ ], UserController.prototype, "getUser", null);
1106
+ __legacyDecorateClassTS([
1107
+ Get2("/email/:email"),
1108
+ isAdmin2(),
1109
+ __legacyDecorateParamTS(0, Params2("email")),
1110
+ __legacyMetadataTS("design:type", Function),
1111
+ __legacyMetadataTS("design:paramtypes", [
1112
+ Object
1113
+ ]),
1114
+ __legacyMetadataTS("design:returntype", Promise)
1115
+ ], UserController.prototype, "getByEmail", null);
1116
+ __legacyDecorateClassTS([
1117
+ Get2("/role/:userId"),
1118
+ isAdmin2(),
1119
+ __legacyDecorateParamTS(0, Params2("userId")),
1120
+ __legacyMetadataTS("design:type", Function),
1121
+ __legacyMetadataTS("design:paramtypes", [
1122
+ Object
1123
+ ]),
1124
+ __legacyMetadataTS("design:returntype", Promise)
1125
+ ], UserController.prototype, "getRole", null);
1126
+ __legacyDecorateClassTS([
1127
+ Post2(),
1128
+ isAdmin2(),
1129
+ __legacyDecorateParamTS(0, Body2()),
1130
+ __legacyMetadataTS("design:type", Function),
1131
+ __legacyMetadataTS("design:paramtypes", [
1132
+ Object
1133
+ ]),
1134
+ __legacyMetadataTS("design:returntype", Promise)
1135
+ ], UserController.prototype, "create", null);
1136
+ __legacyDecorateClassTS([
1137
+ Put2("/:id"),
1138
+ isAdmin2(),
1139
+ __legacyDecorateParamTS(0, Params2("id")),
1140
+ __legacyDecorateParamTS(1, Body2()),
1141
+ __legacyMetadataTS("design:type", Function),
1142
+ __legacyMetadataTS("design:paramtypes", [
1143
+ Object,
1144
+ Object
1145
+ ]),
1146
+ __legacyMetadataTS("design:returntype", Promise)
1147
+ ], UserController.prototype, "update", null);
1148
+ __legacyDecorateClassTS([
1149
+ Delete2("/:id"),
1150
+ isAdmin2(),
1151
+ __legacyDecorateParamTS(0, Params2("id")),
1152
+ __legacyMetadataTS("design:type", Function),
1153
+ __legacyMetadataTS("design:paramtypes", [
1154
+ Object
1155
+ ]),
1156
+ __legacyMetadataTS("design:returntype", Promise)
1157
+ ], UserController.prototype, "delete", null);
1158
+ __legacyDecorateClassTS([
1159
+ Delete2(),
1160
+ isAdmin2(),
1161
+ __legacyMetadataTS("design:type", Function),
1162
+ __legacyMetadataTS("design:paramtypes", []),
1163
+ __legacyMetadataTS("design:returntype", Promise)
1164
+ ], UserController.prototype, "deleteAll", null);
1165
+ __legacyDecorateClassTS([
1166
+ Post2("/assign/:userId/:roleId"),
1167
+ isAdmin2(),
1168
+ __legacyDecorateParamTS(0, Params2("userId")),
1169
+ __legacyDecorateParamTS(1, Params2("roleId")),
1170
+ __legacyMetadataTS("design:type", Function),
1171
+ __legacyMetadataTS("design:paramtypes", [
1172
+ Object,
1173
+ Object
1174
+ ]),
1175
+ __legacyMetadataTS("design:returntype", Promise)
1176
+ ], UserController.prototype, "assignRole", null);
1177
+ __legacyDecorateClassTS([
1178
+ Delete2("/remove/:userId"),
1179
+ isAdmin2(),
1180
+ __legacyDecorateParamTS(0, Params2("userId")),
1181
+ __legacyMetadataTS("design:type", Function),
1182
+ __legacyMetadataTS("design:paramtypes", [
1183
+ Object
1184
+ ]),
1185
+ __legacyMetadataTS("design:returntype", Promise)
1186
+ ], UserController.prototype, "removeRole", null);
1187
+ UserController = __legacyDecorateClassTS([
1188
+ Controller2("/users"),
1189
+ __legacyMetadataTS("design:paramtypes", [
1190
+ typeof UserService === "undefined" ? Object : UserService
1191
+ ])
1192
+ ], UserController);
1193
+ // src/auth/AuthService.ts
1194
+ class AuthService {
1195
+ tokenService;
1196
+ userService;
1197
+ userValidator;
1198
+ cookieService;
1199
+ constructor(tokenService, userService, userValidator, cookieService) {
1200
+ this.tokenService = tokenService;
1201
+ this.userService = userService;
1202
+ this.userValidator = userValidator;
1203
+ this.cookieService = cookieService;
1204
+ }
1205
+ async registerUser(body) {
1206
+ return await this.userService.create(body);
1207
+ }
1208
+ async loginUser(body) {
1209
+ const { email, password } = body;
1210
+ if (!email || !password) {
1211
+ throw new Error(t6("auth.errors.invalidCredentials"));
1212
+ }
1213
+ const existingPassword = await this.userService.getPassword(email);
1214
+ const { id } = await this.userService.getByEmail(email);
1215
+ await this.userValidator.checkPasswordValid(password, existingPassword);
1216
+ const data = await this.tokenService.generateTokens(id);
1217
+ this.cookieService.setRefreshCookie(data.refreshToken);
1218
+ return data;
1219
+ }
1220
+ async refreshTokens() {
1221
+ const data = await this.tokenService.refreshTokens();
1222
+ this.cookieService.setRefreshCookie(data.refreshToken);
1223
+ return data;
1224
+ }
1225
+ async logoutUser(userId) {
1226
+ await this.userValidator.checkUserExists(userId);
1227
+ await this.tokenService.revokeToken(userId);
1228
+ this.cookieService.clearRefreshCookie();
1229
+ return { data: null, message: t6("auth.success.logout") };
1230
+ }
1231
+ async getUserProfile(userData) {
1232
+ const lang = getCurrentLanguage2();
1233
+ return {
1234
+ ...userData,
1235
+ language: lang
1236
+ };
1237
+ }
1238
+ async forgotPassword(email) {}
1239
+ }
1240
+ AuthService = __legacyDecorateClassTS([
1241
+ Injectable9(),
1242
+ __legacyMetadataTS("design:paramtypes", [
1243
+ typeof TokenService === "undefined" ? Object : TokenService,
1244
+ typeof UserService === "undefined" ? Object : UserService,
1245
+ typeof UserValidator === "undefined" ? Object : UserValidator,
1246
+ typeof CookieService === "undefined" ? Object : CookieService
1247
+ ])
1248
+ ], AuthService);
1249
+
1250
+ // src/auth/AuthController.ts
1251
+ import { isAuth as isAuth3 } from "@/roles/RoleGuards";
1252
+ class AuthController {
1253
+ authService;
1254
+ constructor(authService) {
1255
+ this.authService = authService;
1256
+ }
1257
+ async registerUser(body) {
1258
+ const data = await this.authService.registerUser(body);
1259
+ return {
1260
+ data,
1261
+ message: t7("auth.success.register"),
1262
+ status: "success"
1263
+ };
1264
+ }
1265
+ async loginUser(body) {
1266
+ const data = await this.authService.loginUser(body);
1267
+ return {
1268
+ data,
1269
+ message: t7("auth.success.login"),
1270
+ status: "success"
1271
+ };
1272
+ }
1273
+ async refreshTokens() {
1274
+ const data = await this.authService.refreshTokens();
1275
+ return {
1276
+ data,
1277
+ message: t7("auth.success.tokenRefreshed"),
1278
+ status: "success"
1279
+ };
1280
+ }
1281
+ async logoutUser(id) {
1282
+ const data = await this.authService.logoutUser(id);
1283
+ return {
1284
+ data,
1285
+ message: t7("auth.success.logout"),
1286
+ status: "success"
1287
+ };
1288
+ }
1289
+ async userProfile(user) {
1290
+ const data = await this.authService.getUserProfile(user);
1291
+ return {
1292
+ data,
1293
+ message: t7("users.success.retrieved"),
1294
+ status: "success"
1295
+ };
1296
+ }
1297
+ async forgotPassword(body) {
1298
+ const data = await this.authService.forgotPassword(body.email);
1299
+ return {
1300
+ data,
1301
+ message: t7("auth.success.passwordReset"),
1302
+ status: "success"
1303
+ };
1304
+ }
1305
+ }
1306
+ __legacyDecorateClassTS([
1307
+ Post3("/register"),
1308
+ __legacyDecorateParamTS(0, Body3()),
1309
+ __legacyMetadataTS("design:type", Function),
1310
+ __legacyMetadataTS("design:paramtypes", [
1311
+ Object
1312
+ ]),
1313
+ __legacyMetadataTS("design:returntype", Promise)
1314
+ ], AuthController.prototype, "registerUser", null);
1315
+ __legacyDecorateClassTS([
1316
+ Post3("/login"),
1317
+ __legacyDecorateParamTS(0, Body3()),
1318
+ __legacyMetadataTS("design:type", Function),
1319
+ __legacyMetadataTS("design:paramtypes", [
1320
+ Object
1321
+ ]),
1322
+ __legacyMetadataTS("design:returntype", Promise)
1323
+ ], AuthController.prototype, "loginUser", null);
1324
+ __legacyDecorateClassTS([
1325
+ Get3("/refresh"),
1326
+ __legacyMetadataTS("design:type", Function),
1327
+ __legacyMetadataTS("design:paramtypes", []),
1328
+ __legacyMetadataTS("design:returntype", Promise)
1329
+ ], AuthController.prototype, "refreshTokens", null);
1330
+ __legacyDecorateClassTS([
1331
+ Get3("/logout/:id"),
1332
+ __legacyDecorateParamTS(0, Params3("id")),
1333
+ __legacyMetadataTS("design:type", Function),
1334
+ __legacyMetadataTS("design:paramtypes", [
1335
+ Object
1336
+ ]),
1337
+ __legacyMetadataTS("design:returntype", Promise)
1338
+ ], AuthController.prototype, "logoutUser", null);
1339
+ __legacyDecorateClassTS([
1340
+ Get3("/me"),
1341
+ isAuth3(),
1342
+ __legacyDecorateParamTS(0, User2()),
1343
+ __legacyMetadataTS("design:type", Function),
1344
+ __legacyMetadataTS("design:paramtypes", [
1345
+ Object
1346
+ ]),
1347
+ __legacyMetadataTS("design:returntype", Promise)
1348
+ ], AuthController.prototype, "userProfile", null);
1349
+ __legacyDecorateClassTS([
1350
+ Post3("/forgot-password"),
1351
+ isAuth3(),
1352
+ __legacyDecorateParamTS(0, Body3()),
1353
+ __legacyMetadataTS("design:type", Function),
1354
+ __legacyMetadataTS("design:paramtypes", [
1355
+ Object
1356
+ ]),
1357
+ __legacyMetadataTS("design:returntype", Promise)
1358
+ ], AuthController.prototype, "forgotPassword", null);
1359
+ AuthController = __legacyDecorateClassTS([
1360
+ Controller3("/auth"),
1361
+ __legacyMetadataTS("design:paramtypes", [
1362
+ typeof AuthService === "undefined" ? Object : AuthService
1363
+ ])
1364
+ ], AuthController);
1365
+ // src/lib/ENUMS.ts
1366
+ var ENUMS = {
1367
+ userType: {
1368
+ values: ["admin", "teacher", "student", "parent"],
1369
+ translationKey: "enums.userType"
1370
+ },
1371
+ userStatus: {
1372
+ values: ["active", "inactive", "pending"],
1373
+ translationKey: "enums.userStatus"
1374
+ },
1375
+ tokenStatus: {
1376
+ values: ["active", "revoked", "expired"],
1377
+ translationKey: "enums.tokenStatus"
1378
+ },
1379
+ tokenType: {
1380
+ values: ["access", "refresh"],
1381
+ translationKey: "enums.tokenType"
1382
+ },
1383
+ fileStatus: {
1384
+ values: ["active", "deleted", "archived"],
1385
+ translationKey: "enums.fileStatus"
1386
+ },
1387
+ gender: {
1388
+ values: ["M", "F"],
1389
+ translationKey: "common.gender"
1390
+ },
1391
+ studentStatus: {
1392
+ values: ["active", "inactive", "graduated", "transferred"],
1393
+ translationKey: "students.status"
1394
+ },
1395
+ teacherStatus: {
1396
+ values: ["active", "inactive", "onLeave"],
1397
+ translationKey: "teachers.status"
1398
+ },
1399
+ employmentType: {
1400
+ values: ["fullTime", "partTime", "contract", "temporary"],
1401
+ translationKey: "teachers.employmentType"
1402
+ },
1403
+ relationshipType: {
1404
+ values: ["father", "mother", "guardian", "stepparent", "grandparent", "other"],
1405
+ translationKey: "parents.relationships"
1406
+ },
1407
+ semester: {
1408
+ values: ["spring", "summer", "fall", "winter"],
1409
+ translationKey: "academic.semester"
1410
+ },
1411
+ classStatus: {
1412
+ values: ["active", "completed", "cancelled"],
1413
+ translationKey: "classes.status"
1414
+ },
1415
+ sectionStatus: {
1416
+ values: ["active", "inactive", "archived"],
1417
+ translationKey: "sections.status"
1418
+ },
1419
+ language: {
1420
+ values: ["en", "fr", "ar", "es"],
1421
+ translationKey: "common.languages"
1422
+ },
1423
+ enrollmentStatus: {
1424
+ values: ["enrolled", "completed", "dropped", "failed"],
1425
+ translationKey: "enrollments.status"
1426
+ },
1427
+ assignmentStatus: {
1428
+ values: ["active", "completed", "cancelled"],
1429
+ translationKey: "assignments.status"
1430
+ },
1431
+ calendarSystem: {
1432
+ values: ["SEMESTER", "TRIMESTER", "QUARTER"],
1433
+ translationKey: "settings.calendarSystem"
1434
+ },
1435
+ assessmentType: {
1436
+ values: ["quiz", "assignment", "project", "participation", "test", "presentation"],
1437
+ translationKey: "assessments.type"
1438
+ },
1439
+ assessmentStatus: {
1440
+ values: ["scheduled", "active", "completed", "cancelled"],
1441
+ translationKey: "assessments.status"
1442
+ },
1443
+ submissionType: {
1444
+ values: ["online", "paper", "presentation", "practical", "discussion"],
1445
+ translationKey: "assessments.submissionType"
1446
+ },
1447
+ examType: {
1448
+ values: ["midterm", "final", "standardized"],
1449
+ translationKey: "exams.type"
1450
+ },
1451
+ examSecurity: {
1452
+ values: ["low", "medium", "high"],
1453
+ translationKey: "exams.security"
1454
+ },
1455
+ examStatus: {
1456
+ values: ["scheduled", "active", "completed", "cancelled", "rescheduled"],
1457
+ translationKey: "exams.status"
1458
+ },
1459
+ gradeStatus: {
1460
+ values: ["graded", "pending", "draft", "reviewed"],
1461
+ translationKey: "grades.status"
1462
+ },
1463
+ attendanceStatus: {
1464
+ values: ["present", "absent", "late", "excused"],
1465
+ translationKey: "attendance.status"
1466
+ },
1467
+ proficiencyLevel: {
1468
+ values: ["beginner", "intermediate", "advanced", "expert"],
1469
+ translationKey: "common.proficiencyLevel"
1470
+ },
1471
+ dayOfWeek: {
1472
+ values: ["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"],
1473
+ translationKey: "common.days"
1474
+ },
1475
+ alertType: {
1476
+ values: ["academic", "attendance", "behavioral", "health", "system", "announcement", "reminder", "emergency"],
1477
+ translationKey: "alerts.type"
1478
+ },
1479
+ alertPriority: {
1480
+ values: ["low", "medium", "high", "critical"],
1481
+ translationKey: "alerts.priority"
1482
+ },
1483
+ alertStatus: {
1484
+ values: ["active", "acknowledged", "resolved", "dismissed"],
1485
+ translationKey: "alerts.status"
1486
+ },
1487
+ feeTypeStatus: {
1488
+ values: ["active", "inactive", "archived"],
1489
+ translationKey: "fees.typeStatus"
1490
+ },
1491
+ feeCategory: {
1492
+ values: ["tuition", "registration", "transport", "cafeteria", "books", "sports", "uniform", "technology", "fieldtrip", "other"],
1493
+ translationKey: "feeTypes.category"
1494
+ },
1495
+ paymentType: {
1496
+ values: ["recurring", "oneTime"],
1497
+ translationKey: "payments.type"
1498
+ },
1499
+ schedule: {
1500
+ values: ["monthly", "quarterly", "semester", "annually", "oneTime"],
1501
+ translationKey: "fees.schedule"
1502
+ },
1503
+ feeStatus: {
1504
+ values: ["pending", "partiallyPaid", "paid", "overdue"],
1505
+ translationKey: "fees.status"
1506
+ },
1507
+ feeInstallmentStatus: {
1508
+ values: ["pending", "partiallyPaid", "paid", "overdue"],
1509
+ translationKey: "fees.installmentStatus"
1510
+ },
1511
+ paymentMethod: {
1512
+ values: ["cash", "bankTransfer", "check", "creditCard", "debitCard", "online", "mobilePayment"],
1513
+ translationKey: "payments.methods"
1514
+ },
1515
+ paymentStatus: {
1516
+ values: ["completed", "pending", "failed", "refunded"],
1517
+ translationKey: "payments.status"
1518
+ },
1519
+ eventType: {
1520
+ values: ["academic", "sports", "cultural", "holiday", "exam", "meeting", "workshop", "fieldtrip", "ceremony", "conference", "other"],
1521
+ translationKey: "events.type"
1522
+ },
1523
+ eventStatus: {
1524
+ values: ["scheduled", "ongoing", "completed", "cancelled", "postponed"],
1525
+ translationKey: "events.status"
1526
+ },
1527
+ eventVisibility: {
1528
+ values: ["public", "private", "teachers", "students", "parents", "staff"],
1529
+ translationKey: "events.visibility"
1530
+ },
1531
+ participantType: {
1532
+ values: ["student", "teacher", "parent", "staff"],
1533
+ translationKey: "events.participantType"
1534
+ },
1535
+ expenseCategory: {
1536
+ values: ["salary", "utilities", "maintenance", "supplies", "equipment", "transport", "food", "security", "cleaning", "insurance", "rent", "tax", "marketing", "training", "technology", "miscellaneous"],
1537
+ translationKey: "expenses.categories"
1538
+ },
1539
+ expenseStatus: {
1540
+ values: ["pending", "approved", "paid", "rejected", "cancelled"],
1541
+ translationKey: "expenses.status"
1542
+ },
1543
+ trackerMode: {
1544
+ values: ["tracking", "gprs", "sms", "sleepTime", "sleepShock", "sleepDeep"],
1545
+ translationKey: "tracker.mode"
1546
+ },
1547
+ driverStatus: {
1548
+ values: ["active", "inactive", "onLeave", "suspended"],
1549
+ translationKey: "transport.driverStatus"
1550
+ },
1551
+ vehicleStatus: {
1552
+ values: ["active", "inactive", "maintenance", "retired"],
1553
+ translationKey: "transport.vehicleStatus"
1554
+ },
1555
+ vehicleType: {
1556
+ values: ["sedan", "minibus", "fullbus", "shuttle"],
1557
+ translationKey: "transport.vehicleType"
1558
+ },
1559
+ vehicleDocumentType: {
1560
+ values: ["insurance", "registration", "inspection", "emission", "license"],
1561
+ translationKey: "transport.documentType"
1562
+ },
1563
+ busStatus: {
1564
+ values: ["active", "inactive", "maintenance", "retired"],
1565
+ translationKey: "transport.busStatus"
1566
+ },
1567
+ refuelStatus: {
1568
+ values: ["pending", "completed", "cancelled"],
1569
+ translationKey: "transport.refuelStatus"
1570
+ },
1571
+ fuelType: {
1572
+ values: ["gasoline", "diesel", "electric", "hybrid", "lpg", "cng"],
1573
+ translationKey: "transport.fuelType"
1574
+ },
1575
+ maintenanceType: {
1576
+ values: ["scheduled", "repair", "inspection", "oilChange", "filterChange", "other"],
1577
+ translationKey: "transport.maintenanceType"
1578
+ },
1579
+ maintenanceStatus: {
1580
+ values: ["scheduled", "inProgress", "completed", "cancelled", "overdue"],
1581
+ translationKey: "transport.maintenanceStatus"
1582
+ },
1583
+ maritalStatus: {
1584
+ values: ["single", "married", "divorced", "widowed", "separated"],
1585
+ translationKey: "parents.maritalStatus"
1586
+ }
1587
+ };
1588
+ var getEnumConfig = (enumKey) => ENUMS[enumKey];
1589
+ var getEnumValues = (enumKey) => ENUMS[enumKey]?.values || [];
1590
+ // src/lib/validations.ts
1591
+ import { z as z2 } from "zod";
1592
+
1593
+ // src/lib/ZodEnum.ts
1594
+ import { z } from "zod";
1595
+ var createZodEnum = (enumKey) => {
1596
+ const values = ENUMS[enumKey]?.values;
1597
+ if (!values)
1598
+ throw new Error(`Enum ${enumKey} not found`);
1599
+ return z.enum(values);
1600
+ };
1601
+ var userTypeEnum = createZodEnum("userType");
1602
+ var userStatusEnum = createZodEnum("userStatus");
1603
+ var tokenStatusEnum = createZodEnum("tokenStatus");
1604
+ var tokenTypeEnum = createZodEnum("tokenType");
1605
+ var fileStatusEnum = createZodEnum("fileStatus");
1606
+ var genderEnum = createZodEnum("gender");
1607
+ var studentStatusEnum = createZodEnum("studentStatus");
1608
+ var teacherStatusEnum = createZodEnum("teacherStatus");
1609
+ var employmentTypeEnum = createZodEnum("employmentType");
1610
+ var relationshipTypeEnum = createZodEnum("relationshipType");
1611
+ var semesterEnum = createZodEnum("semester");
1612
+ var classStatusEnum = createZodEnum("classStatus");
1613
+ var sectionStatusEnum = createZodEnum("sectionStatus");
1614
+ var languageEnum = createZodEnum("language");
1615
+ var enrollmentStatusEnum = createZodEnum("enrollmentStatus");
1616
+ var assignmentStatusEnum = createZodEnum("assignmentStatus");
1617
+ var calendarSystemEnum = createZodEnum("calendarSystem");
1618
+ var assessmentTypeEnum = createZodEnum("assessmentType");
1619
+ var assessmentStatusEnum = createZodEnum("assessmentStatus");
1620
+ var submissionTypeEnum = createZodEnum("submissionType");
1621
+ var examTypeEnum = createZodEnum("examType");
1622
+ var examSecurityEnum = createZodEnum("examSecurity");
1623
+ var examStatusEnum = createZodEnum("examStatus");
1624
+ var gradeStatusEnum = createZodEnum("gradeStatus");
1625
+ var attendanceStatusEnum = createZodEnum("attendanceStatus");
1626
+ var proficiencyLevelEnum = createZodEnum("proficiencyLevel");
1627
+ var dayOfWeekEnum = createZodEnum("dayOfWeek");
1628
+ var alertTypeEnum = createZodEnum("alertType");
1629
+ var alertPriorityEnum = createZodEnum("alertPriority");
1630
+ var alertStatusEnum = createZodEnum("alertStatus");
1631
+ var feeTypeStatusEnum = createZodEnum("feeTypeStatus");
1632
+ var paymentTypeEnum = createZodEnum("paymentType");
1633
+ var scheduleEnum = createZodEnum("schedule");
1634
+ var feeStatusEnum = createZodEnum("feeStatus");
1635
+ var feeInstallmentStatusEnum = createZodEnum("feeInstallmentStatus");
1636
+ var paymentMethodEnum = createZodEnum("paymentMethod");
1637
+ var paymentStatusEnum = createZodEnum("paymentStatus");
1638
+ var eventTypeEnum = createZodEnum("eventType");
1639
+ var eventStatusEnum = createZodEnum("eventStatus");
1640
+ var eventVisibilityEnum = createZodEnum("eventVisibility");
1641
+ var participantTypeEnum = createZodEnum("participantType");
1642
+ var expenseCategoryEnum = createZodEnum("expenseCategory");
1643
+ var expenseStatusEnum = createZodEnum("expenseStatus");
1644
+ var trackerModeEnum = createZodEnum("trackerMode");
1645
+ var driverStatusEnum = createZodEnum("driverStatus");
1646
+ var vehicleStatusEnum = createZodEnum("vehicleStatus");
1647
+ var vehicleTypeEnum = createZodEnum("vehicleType");
1648
+ var vehicleDocumentTypeEnum = createZodEnum("vehicleDocumentType");
1649
+ var busStatusEnum = createZodEnum("busStatus");
1650
+ var refuelStatusEnum = createZodEnum("refuelStatus");
1651
+ var fuelTypeEnum = createZodEnum("fuelType");
1652
+ var maintenanceTypeEnum = createZodEnum("maintenanceType");
1653
+ var maintenanceStatusEnum = createZodEnum("maintenanceStatus");
1654
+ var maritalStatusEnum = createZodEnum("maritalStatus");
1655
+
1656
+ // src/lib/validations.ts
1657
+ var requiredId = z2.preprocess((val) => val ?? "", z2.string().min(1, "ID is required"));
1658
+ var optionalId = z2.string().min(1, "ID cannot be empty").nullish().optional();
1659
+ var emailField = z2.string().email("Invalid email format").or(z2.literal(""));
1660
+ var phoneField = z2.string().regex(/^[\+]?[1-9][\d]{0,15}$/, "Invalid phone number");
1661
+ var nameField = z2.string().min(2, "Name must be at least 2 characters").max(100, "Name too long");
1662
+ var dateField = z2.string().regex(/^(\d{4}-\d{2}-\d{2}|\d{2}\/\d{2}\/\d{4}|\d{2}-\d{2}-\d{2}|\d{2}-\d{2}-\d{4})$/, "Date must be in YYYY-MM-DD, MM/DD/YYYY, DD/MM/YYYY, DD-MM-YY, or DD-MM-YYYY format");
1663
+ var optionalDateField = z2.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Date must be in YYYY-MM-DD format").nullable().optional();
1664
+ var timeField = z2.string().regex(/^([01]?[0-9]|2[0-3]):[0-5][0-9]$/, "Time must be in HH:MM format").optional().nullable();
1665
+ var cinField = z2.string().min(8, "CIN must be at least 8 characters").max(20, "CIN too long");
1666
+ var addressField = z2.string().max(500, "Address too long").optional();
1667
+ var academicYearField = z2.string().min(9, "Academic year is required").regex(/^\d{4}-\d{4}$/, "Academic year must be in YYYY-YYYY format");
1668
+ var num = () => {
1669
+ const createChainable = (currentSchema) => {
1670
+ const methods = {
1671
+ positive: (msg = "Must be positive") => createChainable(currentSchema.refine((val) => val > 0, { message: msg })),
1672
+ min: (value, msg) => createChainable(currentSchema.refine((val) => val >= value, { message: msg || `Must be at least ${value}` })),
1673
+ max: (value, msg) => createChainable(currentSchema.refine((val) => val <= value, { message: msg || `Cannot exceed ${value}` })),
1674
+ int: (msg = "Must be an integer") => createChainable(currentSchema.refine((val) => Number.isInteger(val), { message: msg }))
1675
+ };
1676
+ return Object.assign(currentSchema, methods);
1677
+ };
1678
+ const isValidNumber = (val) => {
1679
+ if (val === null || val === undefined || Number.isNaN(val))
1680
+ return false;
1681
+ if (typeof val === "number")
1682
+ return true;
1683
+ if (typeof val === "string") {
1684
+ const trimmed = val.trim();
1685
+ return trimmed !== "" && !isNaN(Number(trimmed));
1686
+ }
1687
+ return false;
1688
+ };
1689
+ const baseSchema = z2.any().refine(isValidNumber, { message: "Must be a valid number" }).transform((val) => typeof val === "string" ? Number(val) : val);
1690
+ return createChainable(baseSchema);
1691
+ };
1692
+ var userSchema2 = z2.object({
1693
+ id: optionalId,
1694
+ username: nameField.max(50).optional(),
1695
+ email: emailField,
1696
+ password: z2.string().min(8, "Password must be at least 8 characters"),
1697
+ roleId: optionalId,
1698
+ roleName: nameField.max(50).optional(),
1699
+ lastLogin: optionalDateField,
1700
+ image: z2.union([z2.string(), z2.instanceof(File), z2.undefined()]).optional(),
1701
+ emailVerified: z2.boolean().default(false),
1702
+ status: userStatusEnum,
1703
+ createdAt: optionalDateField
1704
+ });
1705
+ var roleSchema2 = z2.object({
1706
+ id: optionalId,
1707
+ name: nameField.max(50),
1708
+ description: z2.string().max(255, "Description too long").optional(),
1709
+ createdAt: optionalDateField
1710
+ });
1711
+ var studentSchema = z2.object({
1712
+ id: optionalId,
1713
+ classId: requiredId,
1714
+ sectionId: requiredId,
1715
+ studentCode: z2.string(),
1716
+ name: nameField,
1717
+ email: emailField,
1718
+ phone: phoneField.nullish(),
1719
+ address: addressField,
1720
+ dateOfBirth: optionalDateField,
1721
+ gender: genderEnum,
1722
+ enrollmentDate: dateField,
1723
+ medicalConditions: z2.string().max(1000, "Medical conditions description too long").nullish().optional(),
1724
+ previousSchool: z2.string().max(500, "Previous school name too long").optional().nullable(),
1725
+ image: z2.union([z2.string(), z2.instanceof(File), z2.null()]).optional(),
1726
+ status: studentStatusEnum.default("active")
1727
+ });
1728
+ var parentSchema = z2.object({
1729
+ id: optionalId,
1730
+ name: nameField,
1731
+ email: emailField.optional(),
1732
+ phone: phoneField,
1733
+ gender: genderEnum.optional(),
1734
+ address: addressField,
1735
+ dateOfBirth: optionalDateField,
1736
+ cin: cinField,
1737
+ occupation: z2.string().max(100, "Occupation too long").optional(),
1738
+ nationality: z2.string().max(100, "Nationality too long").optional(),
1739
+ maritalStatus: z2.string().max(50, "Marital status too long").optional(),
1740
+ relationshipType: relationshipTypeEnum,
1741
+ image: z2.union([z2.string(), z2.instanceof(File), z2.null()]).optional(),
1742
+ isEmergencyContact: z2.boolean().optional().default(false),
1743
+ financialResponsibility: z2.boolean().optional().default(false)
1744
+ });
1745
+ var driverSchema = z2.object({
1746
+ id: optionalId,
1747
+ name: nameField,
1748
+ email: emailField,
1749
+ cin: cinField,
1750
+ phone: phoneField,
1751
+ address: addressField,
1752
+ gender: genderEnum.optional(),
1753
+ licenseNumber: z2.string().min(5, "License number must be at least 5 characters").max(20, "License number too long"),
1754
+ licenseType: z2.string().max(10, "License type too long"),
1755
+ licenseExpiry: dateField,
1756
+ hireDate: dateField,
1757
+ salary: num().positive("Salary must be positive").optional(),
1758
+ yearsOfExperience: num().int().min(0, "Years of experience must be non-negative").optional(),
1759
+ emergencyContact: nameField.optional(),
1760
+ emergencyPhone: phoneField.optional(),
1761
+ image: z2.union([z2.string(), z2.instanceof(File), z2.null()]).optional(),
1762
+ status: driverStatusEnum.default("active"),
1763
+ notes: z2.string().max(1000, "Notes too long").optional().nullable()
1764
+ });
1765
+ var teacherPersonalSchema = z2.object({
1766
+ id: optionalId,
1767
+ name: nameField,
1768
+ cin: cinField,
1769
+ email: emailField,
1770
+ phone: phoneField,
1771
+ address: addressField,
1772
+ gender: genderEnum.optional(),
1773
+ emergencyContact: nameField.optional(),
1774
+ emergencyPhone: phoneField,
1775
+ status: teacherStatusEnum.default("active"),
1776
+ image: z2.union([z2.string(), z2.instanceof(File), z2.null()]).optional()
1777
+ });
1778
+ var teacherProfessionalSchema = z2.object({
1779
+ specialization: z2.string().max(100, "Specialization too long").optional(),
1780
+ yearsOfExperience: num().int().min(0, "Years of experience must be non-negative").optional(),
1781
+ salary: num().positive("Salary must be positive").optional(),
1782
+ hireDate: dateField,
1783
+ bankAccount: z2.coerce.string().max(100, { message: "Bank account too long" }).optional(),
1784
+ employmentType: employmentTypeEnum.optional(),
1785
+ workloadHours: num().int().min(0, "Workload hours must be non-negative").max(60, "Workload hours cannot exceed 60").optional(),
1786
+ academicDegrees: z2.string().max(500, "Academic degrees description too long").optional()
1787
+ });
1788
+ var assignmentSchema = z2.object({
1789
+ classId: z2.string().min(1, "Class is required"),
1790
+ sectionIds: z2.array(z2.string()).min(1, "At least one section is required"),
1791
+ subjectIds: z2.array(z2.string()).min(1, "At least one subject is required"),
1792
+ academicYear: z2.string().optional()
1793
+ });
1794
+ var assignmentsSchema = z2.object({
1795
+ assignments: z2.array(assignmentSchema).min(1, "At least one parent is required")
1796
+ });
1797
+ var teacherFullSchema = z2.object({
1798
+ ...teacherPersonalSchema.shape,
1799
+ ...teacherProfessionalSchema.shape,
1800
+ ...assignmentsSchema.shape
1801
+ });
1802
+ var feeTypeSchema = z2.object({
1803
+ id: optionalId,
1804
+ name: z2.string().min(2, "Fee type name must be at least 2 characters").max(100, "Fee type name too long"),
1805
+ description: z2.string().max(500, "Description too long").optional().nullable(),
1806
+ category: z2.string(),
1807
+ amount: num().positive("Amount must be greater than 0").max(1e5, "Amount too large"),
1808
+ paymentType: paymentTypeEnum.default("recurring"),
1809
+ status: feeTypeStatusEnum.default("active").optional()
1810
+ });
1811
+ var feeSchema = z2.object({
1812
+ id: optionalId,
1813
+ studentId: requiredId,
1814
+ feeTypeId: requiredId,
1815
+ academicYear: academicYearField.optional(),
1816
+ status: feeStatusEnum.optional(),
1817
+ schedule: scheduleEnum,
1818
+ baseAmount: num().positive("Base amount must be positive").optional(),
1819
+ grossAmount: num().positive("Gross amount must be positive").optional(),
1820
+ netAmount: num().optional(),
1821
+ paidAmount: num().min(0, "Paid amount cannot be negative").optional(),
1822
+ discountAmount: num().min(0, "Discount cannot be negative").optional(),
1823
+ discountReason: z2.string().max(500, "Discount reason too long").optional().nullable(),
1824
+ assignedBy: optionalId.nullable(),
1825
+ notes: z2.string().max(1000, "Notes too long").optional().nullable()
1826
+ });
1827
+ var bulkFeeItemSchema = feeSchema.omit({ studentId: true });
1828
+ var bulkFeeFormSchema = z2.object({
1829
+ studentId: requiredId,
1830
+ fees: z2.array(bulkFeeItemSchema).min(1, "At least one fee is required")
1831
+ });
1832
+ var feeInstallmentSchema = z2.object({
1833
+ feeId: optionalId,
1834
+ number: num().int().min(1, "Installment must be at least 1"),
1835
+ dueDate: dateField,
1836
+ amount: num().positive("Amount must be greater than 0").max(1e5, "Amount too large"),
1837
+ paidAmount: num().min(0, "Paid amount cannot be negative").max(1e5, "Amount too large").optional(),
1838
+ status: feeInstallmentStatusEnum.optional()
1839
+ });
1840
+ var feePaymentSchema = z2.object({
1841
+ studentId: optionalId,
1842
+ amount: num().positive("Amount must be greater than 0").max(1e5, "Amount too large").optional(),
1843
+ paymentMethod: paymentMethodEnum,
1844
+ paymentDate: dateField,
1845
+ checkNumber: z2.preprocess((val) => val === "" ? null : val, z2.string().max(50, "Check number too long").optional().nullable()),
1846
+ checkDueDate: z2.preprocess((val) => val === "" ? null : val, optionalDateField.nullable()),
1847
+ transactionRef: z2.preprocess((val) => val === "" ? null : val, z2.string().max(100, "Transaction reference too long").optional().nullable()),
1848
+ receiptNumber: z2.preprocess((val) => val === "" ? null : val, z2.string().max(50, "Receipt number too long").optional().nullable()),
1849
+ status: paymentStatusEnum.default("completed"),
1850
+ processedBy: optionalId,
1851
+ notes: z2.preprocess((val) => val === "" ? null : val, z2.string().max(1000, "Notes too long").optional().nullable()),
1852
+ allocations: z2.array(z2.object({
1853
+ feeId: optionalId,
1854
+ number: z2.number().int().positive("Installment must be a positive number"),
1855
+ amount: num().positive("Amount must be greater than 0")
1856
+ })).optional().nullable()
1857
+ });
1858
+ var paymentAllocationSchema = z2.object({
1859
+ paymentId: z2.string().min(1, "Payment ID is required"),
1860
+ feeId: z2.string().min(1, "Fee ID is required"),
1861
+ installmentId: z2.string().optional(),
1862
+ amount: z2.number().positive("Amount must be positive"),
1863
+ type: z2.enum(["fee", "installment"]).default("installment"),
1864
+ notes: z2.string().optional()
1865
+ });
1866
+ var parentsSchema = z2.object({
1867
+ parents: z2.array(parentSchema).optional().default([])
1868
+ });
1869
+ var feesSchema = z2.object({
1870
+ fees: z2.array(bulkFeeItemSchema).min(1, "At least one fee is required")
1871
+ });
1872
+ var fullStudentSchema = z2.object({
1873
+ ...studentSchema.shape,
1874
+ ...parentsSchema.shape,
1875
+ ...feesSchema.shape
1876
+ });
1877
+ var subjectSchema = z2.object({
1878
+ id: optionalId,
1879
+ code: z2.string().min(2, "Subject code must be at least 2 characters").max(10, "Subject code too long"),
1880
+ name: z2.string().min(2, "Subject name must be at least 2 characters").max(100, "Subject name too long"),
1881
+ description: z2.string().max(500, "Description too long").optional(),
1882
+ gradeLevel: num().int().min(1).max(12).optional()
1883
+ });
1884
+ var sectionSchema = z2.object({
1885
+ id: optionalId,
1886
+ classId: requiredId,
1887
+ name: z2.string().min(1, "Section name is required").max(10, "Section name too long"),
1888
+ maxStudents: num().int().min(1, "Max students must be at least 1").max(100, "Max students cannot exceed 100").default(30),
1889
+ roomNumber: num().max(1e4, "Room number too long").optional(),
1890
+ status: sectionStatusEnum.default("active")
1891
+ });
1892
+ var classSchema = z2.object({
1893
+ id: optionalId,
1894
+ name: z2.string().min(1, "Class name is required").max(50, "Class name too long"),
1895
+ description: z2.string().max(500, "Description too long").optional(),
1896
+ academicYear: academicYearField,
1897
+ level: z2.string().min(1, "Class level is required")
1898
+ });
1899
+ var attendanceSchema = z2.object({
1900
+ studentId: requiredId,
1901
+ teacherId: requiredId,
1902
+ subjectId: requiredId,
1903
+ sectionId: requiredId,
1904
+ date: dateField,
1905
+ status: attendanceStatusEnum.default("present"),
1906
+ notes: z2.string().max(500, "Notes too long").optional()
1907
+ });
1908
+ var assessmentSchema = z2.object({
1909
+ classId: requiredId,
1910
+ sectionId: requiredId,
1911
+ subjectId: requiredId,
1912
+ teacherId: requiredId,
1913
+ teacherAssignmentId: optionalId,
1914
+ title: z2.string().min(3, "Title must be at least 3 characters").max(200, "Title too long"),
1915
+ description: z2.string().max(1000, "Description too long").optional().nullable(),
1916
+ type: assessmentTypeEnum.default("quiz"),
1917
+ date: dateField,
1918
+ duration: num().int().min(1, "Duration must be at least 1 minute").max(480, "Duration cannot exceed 8 hours"),
1919
+ totalMarks: num().positive("Total marks must be greater than 0").max(1000, "Total marks cannot exceed 1000"),
1920
+ passingMarks: num().min(0, "Passing marks must be non-negative").max(1000, "Passing marks cannot exceed 1000"),
1921
+ instructions: z2.string().max(2000, "Instructions too long").optional().nullable(),
1922
+ status: assessmentStatusEnum.default("scheduled"),
1923
+ assessmentId: optionalId
1924
+ });
1925
+ var bulkAssessmentSchema = z2.object({
1926
+ assessments: z2.array(assessmentSchema).min(1, "At least one assessment is required").max(50, "Cannot create more than 50 assessments at once")
1927
+ });
1928
+ var gradeSchema = z2.object({
1929
+ assessmentId: requiredId,
1930
+ teacherId: requiredId,
1931
+ subjectId: requiredId,
1932
+ sectionId: requiredId,
1933
+ studentId: requiredId,
1934
+ gradeId: requiredId,
1935
+ assessmentTitle: z2.string().min(3, "Assessment title must be at least 3 characters").max(200, "Assessment title too long").optional(),
1936
+ marksObtained: num().min(0, "Marks obtained must be non-negative").max(1000, "Marks obtained cannot exceed 1000"),
1937
+ feedback: z2.string().max(1000, "Feedback too long").optional().nullable(),
1938
+ status: gradeStatusEnum.default("graded")
1939
+ });
1940
+ var examSchema = z2.object({
1941
+ classId: optionalId,
1942
+ sectionId: requiredId,
1943
+ subjectId: requiredId,
1944
+ teacherId: requiredId,
1945
+ examId: requiredId,
1946
+ teacherAssignmentId: requiredId,
1947
+ title: z2.string().min(3, "Title must be at least 3 characters").max(200, "Title too long"),
1948
+ description: z2.string().max(1000, "Description too long").optional().nullable(),
1949
+ type: examTypeEnum.default("midterm"),
1950
+ date: dateField,
1951
+ startTime: timeField,
1952
+ endTime: timeField,
1953
+ duration: num().int().min(30, "Exam duration must be at least 30 minutes").max(480, "Duration cannot exceed 8 hours"),
1954
+ totalMarks: num().positive("Total marks must be greater than 0").max(1000, "Total marks cannot exceed 1000"),
1955
+ passingMarks: num().min(0, "Passing marks must be non-negative").max(1000, "Passing marks cannot exceed 1000"),
1956
+ roomNumber: num().max(50, "Room number too long").optional().nullable(),
1957
+ allowedMaterials: z2.string().max(500, "Allowed materials description too long").optional().nullable(),
1958
+ instructions: z2.string().max(2000, "Instructions too long").optional().nullable(),
1959
+ status: examStatusEnum.default("scheduled")
1960
+ });
1961
+ var announcementSchema = z2.object({
1962
+ title: z2.string().min(3, "Title must be at least 3 characters").max(200, "Title too long"),
1963
+ content: z2.string().min(10, "Content must be at least 10 characters").max(5000, "Content too long"),
1964
+ authorId: optionalId,
1965
+ targetAudience: z2.enum(["all", "students", "teachers", "parents", "class"]),
1966
+ classId: optionalId,
1967
+ isPublished: z2.boolean().default(false),
1968
+ publishDate: z2.string().datetime("Invalid publish date").optional(),
1969
+ expiryDate: z2.string().datetime("Invalid expiry date").optional()
1970
+ });
1971
+ var alertSchema = z2.object({
1972
+ type: alertTypeEnum,
1973
+ title: z2.string().min(3, "Title must be at least 3 characters").max(200, "Title too long"),
1974
+ message: z2.string().min(10, "Message must be at least 10 characters").max(2000, "Message too long"),
1975
+ priority: alertPriorityEnum.default("medium"),
1976
+ status: alertStatusEnum.default("active"),
1977
+ studentId: optionalId,
1978
+ teacherId: optionalId,
1979
+ classId: optionalId,
1980
+ subjectId: optionalId,
1981
+ targetAudience: z2.enum(["all", "students", "teachers", "parents"]).optional(),
1982
+ authorId: optionalId,
1983
+ isRead: z2.boolean().default(false)
1984
+ });
1985
+ var eventSchema = z2.object({
1986
+ title: z2.string().min(3, "Title must be at least 3 characters").max(200, "Title too long"),
1987
+ description: z2.string().max(5000, "Description too long").optional().nullable(),
1988
+ type: eventTypeEnum,
1989
+ startDate: dateField,
1990
+ endDate: dateField,
1991
+ startTime: timeField,
1992
+ endTime: timeField,
1993
+ location: z2.string().max(200, "Location too long").optional().nullable(),
1994
+ venue: z2.string().max(200, "Venue too long").optional().nullable(),
1995
+ organizerId: optionalId,
1996
+ classId: optionalId.nullable(),
1997
+ sectionId: optionalId.nullable(),
1998
+ visibility: eventVisibilityEnum.default("public"),
1999
+ status: eventStatusEnum.default("scheduled"),
2000
+ capacity: num().int().positive("Capacity must be positive").optional().nullable(),
2001
+ registrationRequired: z2.boolean().default(false),
2002
+ registrationDeadline: optionalDateField.nullable(),
2003
+ attachments: z2.any().optional().nullable(),
2004
+ notes: z2.string().max(2000, "Notes too long").optional().nullable()
2005
+ });
2006
+ var eventParticipantSchema = z2.object({
2007
+ eventId: optionalId,
2008
+ participantId: optionalId,
2009
+ participantType: participantTypeEnum,
2010
+ attendanceStatus: attendanceStatusEnum.optional().nullable(),
2011
+ notes: z2.string().max(500, "Notes too long").optional().nullable()
2012
+ });
2013
+ var expenseSchema = z2.object({
2014
+ id: optionalId,
2015
+ category: expenseCategoryEnum,
2016
+ title: z2.string().min(3, "Title must be at least 3 characters").max(200, "Title too long"),
2017
+ amount: num().positive("Amount must be greater than 0").max(1e7, "Amount too large"),
2018
+ expenseDate: dateField,
2019
+ paymentMethod: paymentMethodEnum.optional().nullable(),
2020
+ paymentDate: optionalDateField.nullable(),
2021
+ vendor: z2.string().max(200, "Vendor name too long").optional().nullable(),
2022
+ invoiceNumber: z2.string().max(100, "Invoice number too long").optional().nullable(),
2023
+ receiptNumber: z2.string().max(100, "Receipt number too long").optional().nullable(),
2024
+ checkNumber: z2.string().max(50, "Check number too long").optional().nullable(),
2025
+ transactionRef: z2.string().max(100, "Transaction reference too long").optional().nullable(),
2026
+ status: expenseStatusEnum.default("pending"),
2027
+ notes: z2.string().max(1000, "Notes too long").optional().nullable()
2028
+ });
2029
+ var expenseApprovalSchema = z2.object({
2030
+ action: z2.enum(["approve", "reject"]),
2031
+ rejectionReason: z2.string().min(10, "Rejection reason must be at least 10 characters").max(1000, "Rejection reason too long").optional().nullable()
2032
+ });
2033
+ var expensePaymentSchema = z2.object({
2034
+ paymentMethod: paymentMethodEnum,
2035
+ paymentDate: dateField,
2036
+ checkNumber: z2.string().max(50, "Check number too long").optional().nullable(),
2037
+ transactionRef: z2.string().max(100, "Transaction reference too long").optional().nullable(),
2038
+ notes: z2.string().max(1000, "Notes too long").optional().nullable()
2039
+ });
2040
+ var vehicleSchema = z2.object({
2041
+ id: optionalId,
2042
+ name: z2.string().min(2, "Vehicle name must be at least 2 characters").max(100, "Vehicle name too long"),
2043
+ brand: z2.string().min(2, "Brand must be at least 2 characters").max(100, "Brand too long"),
2044
+ model: z2.string().min(2, "Model must be at least 2 characters").max(100, "Model too long"),
2045
+ year: num().int().min(1900, "Year must be after 1900").max(new Date().getFullYear() + 1, "Year cannot be in future"),
2046
+ type: vehicleTypeEnum.default("fullbus"),
2047
+ capacity: num().int().min(1, "Capacity must be at least 1").max(200, "Capacity cannot exceed 200"),
2048
+ licensePlate: z2.string().min(2, "License plate must be at least 2 characters").max(50, "License plate too long"),
2049
+ driverId: optionalId.nullable(),
2050
+ image: z2.string().max(500, "Image path too long").optional().nullable().default("novehicle.png"),
2051
+ purchaseDate: optionalDateField.nullable(),
2052
+ purchasePrice: num().min(0, "Purchase price must be non-negative").max(1e7, "Purchase price too large").optional().nullable(),
2053
+ initialMileage: num().min(0, "Initial mileage must be non-negative").max(1e7, "Initial mileage too large").optional().nullable(),
2054
+ currentMileage: num().min(0, "Current mileage must be non-negative").max(1e7, "Current mileage too large").optional().nullable(),
2055
+ status: vehicleStatusEnum.default("active"),
2056
+ notes: z2.string().max(1000, "Notes too long").optional().nullable()
2057
+ });
2058
+ var refuelSchema = z2.object({
2059
+ id: optionalId,
2060
+ busId: optionalId,
2061
+ refuelDate: dateField,
2062
+ quantity: num().positive("Quantity must be greater than 0").max(1e4, "Quantity too large"),
2063
+ unitPrice: num().positive("Unit price must be greater than 0").max(1e5, "Unit price too large"),
2064
+ totalCost: num().positive("Total cost must be greater than 0").max(1e7, "Total cost too large").optional(),
2065
+ fuelType: fuelTypeEnum.default("diesel"),
2066
+ odometer: num().min(0, "Odometer must be non-negative").max(1e7, "Odometer value too large").optional().nullable(),
2067
+ fuelStation: z2.string().max(200, "Fuel station name too long").optional().nullable(),
2068
+ invoiceNumber: z2.string().max(100, "Invoice number too long").optional().nullable(),
2069
+ paymentMethod: paymentMethodEnum.optional().nullable(),
2070
+ paidBy: optionalId.nullable(),
2071
+ status: refuelStatusEnum.default("completed"),
2072
+ notes: z2.string().max(1000, "Notes too long").optional().nullable()
2073
+ });
2074
+ var settingsSchema = z2.object({
2075
+ schoolName: z2.string().min(2, "School name must be at least 2 characters").max(200, "School name too long"),
2076
+ schoolAddress: z2.string().max(500, "School address too long").optional(),
2077
+ schoolPhone: phoneField,
2078
+ schoolEmail: emailField,
2079
+ schoolWebsite: z2.string().url("Must be a valid URL").max(255, "School website URL too long").optional(),
2080
+ schoolLogo: z2.string().url("Must be a valid image URL").max(255, "School logo URL too long").optional(),
2081
+ currentAcademicYear: academicYearField,
2082
+ gradingScale: z2.any().optional(),
2083
+ attendanceRequirement: num().min(0, "Attendance requirement must be non-negative").max(100, "Attendance requirement cannot exceed 100").default(75),
2084
+ maxClassSize: num().int("Max class size must be an integer").min(1, "Max class size must be at least 1").max(200, "Max class size cannot exceed 200").default(34),
2085
+ minimumPassingGrade: num().min(0, "Minimum passing grade must be non-negative").max(100, "Minimum passing grade cannot exceed 100").default(60),
2086
+ defaultExamDuration: num().int("Default exam duration must be in minutes").min(15, "Exam duration must be at least 15 minutes").max(480, "Exam duration cannot exceed 480 minutes").default(120),
2087
+ calendarSystem: calendarSystemEnum.default("SEMESTER"),
2088
+ startMonth: z2.string().default("september"),
2089
+ endMonth: z2.string().default("june"),
2090
+ academicAlerts: z2.boolean().default(true),
2091
+ attendanceAlerts: z2.boolean().default(true),
2092
+ eventAlerts: z2.boolean().default(true),
2093
+ homeworkAlerts: z2.boolean().default(true),
2094
+ feesReminder: z2.boolean().default(true),
2095
+ feesOverdueAlerts: z2.boolean().default(true),
2096
+ emailNotifications: z2.boolean().default(true),
2097
+ smsNotifications: z2.boolean().default(false),
2098
+ parentNotifications: z2.boolean().default(true),
2099
+ lowGradeAlerts: z2.boolean().default(true),
2100
+ allowLateSubmission: z2.boolean().default(true),
2101
+ examResultsAlerts: z2.boolean().default(true),
2102
+ disciplinaryAlerts: z2.boolean().default(true),
2103
+ achievementAlerts: z2.boolean().default(true),
2104
+ maintenanceNotifications: z2.boolean().default(true),
2105
+ twoFactorEnabled: z2.boolean().default(false),
2106
+ sessionTimeout: z2.string().regex(/^\d{1,4}$/, "Session timeout must be a number between 1-9999 minutes").default("60"),
2107
+ passwordRequireSymbols: z2.boolean().default(true),
2108
+ loginNotifications: z2.boolean().default(true),
2109
+ parentAccessEnabled: z2.boolean().default(true),
2110
+ teacherAccessEnabled: z2.boolean().default(true),
2111
+ studentAccessEnabled: z2.boolean().default(true),
2112
+ timeZone: z2.string().min(1, "Time zone is required").default("UTC"),
2113
+ language: languageEnum.default("en"),
2114
+ theme: z2.enum(["light", "dark", "system"]).default("system"),
2115
+ dateFormat: z2.enum(["YYYY-MM-DD", "MM/DD/YYYY", "DD/MM/YYYY", "DD-MM-YY", "DD-MM-YYYY"]).default("MM/DD/YYYY"),
2116
+ timeFormat: z2.enum(["12", "24"]).default("12"),
2117
+ currency: z2.string().length(3, "Currency must be a 3-letter ISO code").regex(/^[A-Z]{3}$/, "Currency must be uppercase ISO code").default("USD"),
2118
+ gradingPeriods: num().int("Grading periods must be an integer").min(1, "Grading periods must be at least 1").max(12, "Grading periods cannot exceed 12").default(4),
2119
+ schoolStartTime: z2.string().regex(/^([01]?[0-9]|2[0-3]):[0-5][0-9]$/, "Invalid start time format (HH:MM)").default("08:00"),
2120
+ schoolEndTime: z2.string().regex(/^([01]?[0-9]|2[0-3]):[0-5][0-9]$/, "Invalid end time format (HH:MM)").default("15:00"),
2121
+ lunchBreakDuration: num().int("Lunch break duration must be in minutes").min(15, "Lunch break must be at least 15 minutes").max(120, "Lunch break cannot exceed 120 minutes").default(30),
2122
+ maintenanceMode: z2.boolean().default(false),
2123
+ autoBackup: z2.boolean().default(true)
2124
+ });
2125
+ var idParamSchema = z2.object({
2126
+ id: optionalId
2127
+ });
2128
+ var paginationSchema = z2.object({
2129
+ page: num().int().min(1).default(1),
2130
+ limit: num().int().min(1).max(100).default(10)
2131
+ });
2132
+ var dateRangeSchema = z2.object({
2133
+ dateFrom: dateField,
2134
+ dateTo: dateField
2135
+ });
2136
+ // src/permissions/PermissionRepository.ts
2137
+ import { permissionsTable as permissionsTable3, rolePermissionsTable as rolePermissionsTable3, rolesTable as rolesTable4 } from "@/database/schema";
2138
+ import { eq as eq4, and } from "drizzle-orm";
2139
+ import { Repository as Repository4 } from "najm-api";
2140
+ class PermissionRepository {
2141
+ async getAll() {
2142
+ return await this.db.select().from(permissionsTable3);
2143
+ }
2144
+ async getById(id) {
2145
+ const [existingPermission] = await this.db.select().from(permissionsTable3).where(eq4(permissionsTable3.id, id));
2146
+ return existingPermission;
2147
+ }
2148
+ async getByName(name) {
2149
+ const [existingPermission] = await this.db.select().from(permissionsTable3).where(eq4(permissionsTable3.name, name));
2150
+ return existingPermission;
2151
+ }
2152
+ async create(data) {
2153
+ const [newPermission] = await this.db.insert(permissionsTable3).values(data).returning();
2154
+ return newPermission;
2155
+ }
2156
+ async update(id, data) {
2157
+ const [updatedPermission] = await this.db.update(permissionsTable3).set(data).where(eq4(permissionsTable3.id, id)).returning();
2158
+ return updatedPermission;
2159
+ }
2160
+ async delete(id) {
2161
+ const [deletedPermission] = await this.db.delete(permissionsTable3).where(eq4(permissionsTable3.id, id)).returning();
2162
+ return deletedPermission;
2163
+ }
2164
+ async getPermissionsByRole(roleId) {
2165
+ return await this.db.select({
2166
+ id: permissionsTable3.id,
2167
+ name: permissionsTable3.name,
2168
+ description: permissionsTable3.description,
2169
+ resource: permissionsTable3.resource,
2170
+ action: permissionsTable3.action
2171
+ }).from(rolePermissionsTable3).leftJoin(permissionsTable3, eq4(rolePermissionsTable3.permissionId, permissionsTable3.id)).where(eq4(rolePermissionsTable3.roleId, roleId));
2172
+ }
2173
+ async getRolesByPermission(permissionId) {
2174
+ return await this.db.select({
2175
+ id: rolesTable4.id,
2176
+ name: rolesTable4.name,
2177
+ description: rolesTable4.description
2178
+ }).from(rolePermissionsTable3).leftJoin(rolesTable4, eq4(rolePermissionsTable3.roleId, rolesTable4.id)).where(eq4(rolePermissionsTable3.permissionId, permissionId));
2179
+ }
2180
+ async assignPermissionToRole(roleId, permissionId) {
2181
+ const [newRolePermission] = await this.db.insert(rolePermissionsTable3).values({ roleId, permissionId }).returning();
2182
+ return newRolePermission;
2183
+ }
2184
+ async removePermissionFromRole(roleId, permissionId) {
2185
+ const [deletedRolePermission] = await this.db.delete(rolePermissionsTable3).where(and(eq4(rolePermissionsTable3.roleId, roleId), eq4(rolePermissionsTable3.permissionId, permissionId))).returning();
2186
+ return deletedRolePermission;
2187
+ }
2188
+ async checkRoleHasPermission(roleId, permissionId) {
2189
+ const [rolePermission] = await this.db.select().from(rolePermissionsTable3).where(and(eq4(rolePermissionsTable3.roleId, roleId), eq4(rolePermissionsTable3.permissionId, permissionId)));
2190
+ return !!rolePermission;
2191
+ }
2192
+ async deleteAll() {
2193
+ await this.db.delete(rolePermissionsTable3);
2194
+ const deletedPermissions = await this.db.delete(permissionsTable3).returning();
2195
+ return deletedPermissions;
2196
+ }
2197
+ }
2198
+ PermissionRepository = __legacyDecorateClassTS([
2199
+ Repository4()
2200
+ ], PermissionRepository);
2201
+ // src/permissions/PermissionGuards.ts
2202
+ import { createGuard as createGuard2, Injectable as Injectable10, GuardParams as GuardParams2, Headers as Headers3, Ctx as Ctx3 } from "najm-api";
2203
+ class PermissionGuards {
2204
+ tokenService;
2205
+ constructor(tokenService) {
2206
+ this.tokenService = tokenService;
2207
+ }
2208
+ async getUserPermissions(auth) {
2209
+ const permissions = await this.tokenService.getUserPermissions(auth);
2210
+ if (!permissions || !Array.isArray(permissions))
2211
+ return null;
2212
+ return permissions;
2213
+ }
2214
+ checkPermissionMatch(permissions, requiredPermission) {
2215
+ if (permissions.includes(requiredPermission)) {
2216
+ return true;
2217
+ }
2218
+ const [requiredAction, requiredResource] = requiredPermission.split(":");
2219
+ if (requiredAction && requiredResource) {
2220
+ if (permissions.includes(`${requiredAction}:*`)) {
2221
+ return true;
2222
+ }
2223
+ if (permissions.includes(`*:${requiredResource}`)) {
2224
+ return true;
2225
+ }
2226
+ }
2227
+ if (permissions.includes("*:*")) {
2228
+ return true;
2229
+ }
2230
+ return false;
2231
+ }
2232
+ async hasPermission(auth, ctx, requiredPermission) {
2233
+ await this.tokenService.storeUserInCache(auth, ctx);
2234
+ const permissions = await this.getUserPermissions(auth);
2235
+ if (!permissions)
2236
+ return false;
2237
+ const check = this.checkPermissionMatch(permissions, requiredPermission);
2238
+ return check;
2239
+ }
2240
+ }
2241
+ __legacyDecorateClassTS([
2242
+ __legacyDecorateParamTS(0, Headers3("authorization")),
2243
+ __legacyDecorateParamTS(1, Ctx3()),
2244
+ __legacyDecorateParamTS(2, GuardParams2()),
2245
+ __legacyMetadataTS("design:type", Function),
2246
+ __legacyMetadataTS("design:paramtypes", [
2247
+ Object,
2248
+ Object,
2249
+ Object
2250
+ ]),
2251
+ __legacyMetadataTS("design:returntype", Object)
2252
+ ], PermissionGuards.prototype, "hasPermission", null);
2253
+ PermissionGuards = __legacyDecorateClassTS([
2254
+ Injectable10(),
2255
+ __legacyMetadataTS("design:paramtypes", [
2256
+ typeof TokenService === "undefined" ? Object : TokenService
2257
+ ])
2258
+ ], PermissionGuards);
2259
+ var Permission = (...permissions) => createGuard2(PermissionGuards, "hasPermission")(...permissions);
2260
+ // src/permissions/PermissionController.ts
2261
+ import { Controller as Controller4, Get as Get4, Post as Post4, Put as Put3, Delete as Delete3, Params as Params4, Body as Body4, t as t9 } from "najm-api";
2262
+
2263
+ // src/permissions/PermissionService.ts
2264
+ import { Injectable as Injectable12 } from "najm-api";
2265
+
2266
+ // src/permissions/PermissionValidator.ts
2267
+ import { Injectable as Injectable11, t as t8 } from "najm-api";
2268
+ import { parseSchema as parseSchema3 } from "@/shared";
2269
+ import { z as z3 } from "zod";
2270
+ var permissionSchema = z3.object({
2271
+ name: z3.string().min(1, "Permission name is required"),
2272
+ description: z3.string().optional(),
2273
+ resource: z3.string().min(1, "Resource is required"),
2274
+ action: z3.string().min(1, "Action is required")
2275
+ });
2276
+
2277
+ class PermissionValidator {
2278
+ permissionRepository;
2279
+ roleValidator;
2280
+ constructor(permissionRepository, roleValidator) {
2281
+ this.permissionRepository = permissionRepository;
2282
+ this.roleValidator = roleValidator;
2283
+ }
2284
+ async validateCreatePermission(data) {
2285
+ return parseSchema3(permissionSchema, data);
2286
+ }
2287
+ async isPermissionExists(id) {
2288
+ const existingPermission = await this.permissionRepository.getById(id);
2289
+ return !!existingPermission;
2290
+ }
2291
+ async isPermissionNameExists(name) {
2292
+ const existingPermission = await this.permissionRepository.getByName(name);
2293
+ return !!existingPermission;
2294
+ }
2295
+ async checkPermissionExists(id) {
2296
+ const permissionExists = await this.isPermissionExists(id);
2297
+ if (!permissionExists) {
2298
+ throw new Error(t8("permissions.errors.notFound"));
2299
+ }
2300
+ return permissionExists;
2301
+ }
2302
+ async checkPermissionExistsByName(name) {
2303
+ const permissionExists = await this.isPermissionNameExists(name);
2304
+ if (!permissionExists) {
2305
+ throw new Error(t8("permissions.errors.notFound"));
2306
+ }
2307
+ return permissionExists;
2308
+ }
2309
+ async checkPermissionNameUnique(name, excludeId = null) {
2310
+ if (!name)
2311
+ return;
2312
+ const existingPermission = await this.permissionRepository.getByName(name);
2313
+ if (existingPermission && existingPermission.id !== excludeId) {
2314
+ throw new Error(t8("permissions.errors.nameExists"));
2315
+ }
2316
+ }
2317
+ async checkRoleExists(id) {
2318
+ return await this.roleValidator.checkRoleExists(id);
2319
+ }
2320
+ async checkRoleExistsByName(name) {
2321
+ return await this.roleValidator.checkRoleExistsByName(name);
2322
+ }
2323
+ async checkRoleHasPermission(roleId, permissionId) {
2324
+ await this.roleValidator.checkRoleExists(roleId);
2325
+ await this.checkPermissionExists(permissionId);
2326
+ const hasPermission = await this.permissionRepository.checkRoleHasPermission(roleId, permissionId);
2327
+ if (hasPermission) {
2328
+ throw new Error(t8("permissions.errors.roleAlreadyHasPermission"));
2329
+ }
2330
+ }
2331
+ }
2332
+ PermissionValidator = __legacyDecorateClassTS([
2333
+ Injectable11(),
2334
+ __legacyMetadataTS("design:paramtypes", [
2335
+ typeof PermissionRepository === "undefined" ? Object : PermissionRepository,
2336
+ typeof RoleValidator === "undefined" ? Object : RoleValidator
2337
+ ])
2338
+ ], PermissionValidator);
2339
+
2340
+ // src/permissions/PermissionService.ts
2341
+ class PermissionService {
2342
+ permissionRepository;
2343
+ permissionValidator;
2344
+ roleService;
2345
+ constructor(permissionRepository, permissionValidator, roleService) {
2346
+ this.permissionRepository = permissionRepository;
2347
+ this.permissionValidator = permissionValidator;
2348
+ this.roleService = roleService;
2349
+ }
2350
+ async getAll() {
2351
+ return await this.permissionRepository.getAll();
2352
+ }
2353
+ async getById(id) {
2354
+ await this.permissionValidator.checkPermissionExists(id);
2355
+ return await this.permissionRepository.getById(id);
2356
+ }
2357
+ async getByName(name) {
2358
+ return await this.permissionRepository.getByName(name);
2359
+ }
2360
+ async getByResource(resource) {
2361
+ return await this.permissionRepository.getAll().then((permissions) => permissions.filter((p) => p.resource === resource));
2362
+ }
2363
+ async create(data) {
2364
+ await this.permissionValidator.validateCreatePermission(data);
2365
+ await this.permissionValidator.checkPermissionNameUnique(data.name);
2366
+ return await this.permissionRepository.create(data);
2367
+ }
2368
+ async update(id, data) {
2369
+ await this.permissionValidator.checkPermissionExists(id);
2370
+ await this.permissionValidator.checkPermissionNameUnique(data.name, id);
2371
+ return await this.permissionRepository.update(id, data);
2372
+ }
2373
+ async delete(id) {
2374
+ await this.permissionValidator.checkPermissionExists(id);
2375
+ return await this.permissionRepository.delete(id);
2376
+ }
2377
+ async getPermissionsByRole(roleId) {
2378
+ return await this.permissionRepository.getPermissionsByRole(roleId);
2379
+ }
2380
+ async getRolesByPermission(permissionId) {
2381
+ await this.permissionValidator.checkPermissionExists(permissionId);
2382
+ return await this.permissionRepository.getRolesByPermission(permissionId);
2383
+ }
2384
+ async assignPermissionToRole(roleId, permissionId) {
2385
+ await this.permissionValidator.checkRoleHasPermission(roleId, permissionId);
2386
+ return await this.permissionRepository.assignPermissionToRole(roleId, permissionId);
2387
+ }
2388
+ async removePermissionFromRole(roleId, permissionId) {
2389
+ return await this.permissionRepository.removePermissionFromRole(roleId, permissionId);
2390
+ }
2391
+ async seedDefaultPermissions(defaultPermissions) {
2392
+ const createdPermissions = [];
2393
+ for (const permission of defaultPermissions) {
2394
+ try {
2395
+ const permissionEntity = await this.create(permission);
2396
+ createdPermissions.push(permissionEntity);
2397
+ } catch (error) {
2398
+ continue;
2399
+ }
2400
+ }
2401
+ return createdPermissions;
2402
+ }
2403
+ async seedDefaultRolePermissions(defaultRolePermissions) {
2404
+ const results = [];
2405
+ for (const { roleName, permissions } of defaultRolePermissions) {
2406
+ try {
2407
+ await this.permissionValidator.checkRoleExistsByName(roleName);
2408
+ const role = await this.roleService.getByName(roleName);
2409
+ for (const permissionName of permissions) {
2410
+ try {
2411
+ await this.permissionValidator.checkPermissionExistsByName(permissionName);
2412
+ const permission = await this.getByName(permissionName);
2413
+ await this.permissionValidator.checkRoleHasPermission(role.id, permission.id);
2414
+ await this.assignPermissionToRole(role.id, permission.id);
2415
+ results.push({ role: roleName, permission: permissionName });
2416
+ } catch (error) {
2417
+ continue;
2418
+ }
2419
+ }
2420
+ } catch (error) {
2421
+ continue;
2422
+ }
2423
+ }
2424
+ return results;
2425
+ }
2426
+ async deleteAll() {
2427
+ return await this.permissionRepository.deleteAll();
2428
+ }
2429
+ }
2430
+ PermissionService = __legacyDecorateClassTS([
2431
+ Injectable12(),
2432
+ __legacyMetadataTS("design:paramtypes", [
2433
+ typeof PermissionRepository === "undefined" ? Object : PermissionRepository,
2434
+ typeof PermissionValidator === "undefined" ? Object : PermissionValidator,
2435
+ typeof RoleService === "undefined" ? Object : RoleService
2436
+ ])
2437
+ ], PermissionService);
2438
+
2439
+ // src/permissions/PermissionController.ts
2440
+ import { isAdmin as isAdmin3 } from "@/roles/RoleGuards";
2441
+ class PermissionController {
2442
+ permissionService;
2443
+ constructor(permissionService) {
2444
+ this.permissionService = permissionService;
2445
+ }
2446
+ async getPermissions() {
2447
+ const permissions = await this.permissionService.getAll();
2448
+ return {
2449
+ data: permissions,
2450
+ message: t9("permissions.success.retrieved"),
2451
+ status: "success"
2452
+ };
2453
+ }
2454
+ async getPermission(id) {
2455
+ const permission = await this.permissionService.getById(id);
2456
+ return {
2457
+ data: permission,
2458
+ message: t9("permissions.success.retrieved"),
2459
+ status: "success"
2460
+ };
2461
+ }
2462
+ async create(body) {
2463
+ const newPermission = await this.permissionService.create(body);
2464
+ return {
2465
+ data: newPermission,
2466
+ message: t9("permissions.success.created"),
2467
+ status: "success"
2468
+ };
2469
+ }
2470
+ async update(id, body) {
2471
+ const updatedPermission = await this.permissionService.update(id, body);
2472
+ return {
2473
+ data: updatedPermission,
2474
+ message: t9("permissions.success.updated"),
2475
+ status: "success"
2476
+ };
2477
+ }
2478
+ async delete(id) {
2479
+ const result = await this.permissionService.delete(id);
2480
+ return {
2481
+ data: result,
2482
+ message: t9("permissions.success.deleted"),
2483
+ status: "success"
2484
+ };
2485
+ }
2486
+ async getByRole(roleId) {
2487
+ const permissions = await this.permissionService.getPermissionsByRole(roleId);
2488
+ return {
2489
+ data: permissions,
2490
+ message: t9("permissions.success.retrieved"),
2491
+ status: "success"
2492
+ };
2493
+ }
2494
+ async getRolesByPermission(permissionId) {
2495
+ const roles = await this.permissionService.getRolesByPermission(permissionId);
2496
+ return {
2497
+ data: roles,
2498
+ message: t9("permissions.success.retrieved"),
2499
+ status: "success"
2500
+ };
2501
+ }
2502
+ async assignToRole(roleId, permissionId) {
2503
+ const result = await this.permissionService.assignPermissionToRole(roleId, permissionId);
2504
+ return {
2505
+ data: result,
2506
+ message: t9("permissions.success.assigned"),
2507
+ status: "success"
2508
+ };
2509
+ }
2510
+ async removeFromRole(roleId, permissionId) {
2511
+ const result = await this.permissionService.removePermissionFromRole(roleId, permissionId);
2512
+ return {
2513
+ data: result,
2514
+ message: t9("permissions.success.removed"),
2515
+ status: "success"
2516
+ };
2517
+ }
2518
+ async deleteAll() {
2519
+ const result = await this.permissionService.deleteAll();
2520
+ return {
2521
+ data: result,
2522
+ message: t9("permissions.success.allDeleted"),
2523
+ status: "success"
2524
+ };
2525
+ }
2526
+ }
2527
+ __legacyDecorateClassTS([
2528
+ Get4(),
2529
+ __legacyMetadataTS("design:type", Function),
2530
+ __legacyMetadataTS("design:paramtypes", []),
2531
+ __legacyMetadataTS("design:returntype", Promise)
2532
+ ], PermissionController.prototype, "getPermissions", null);
2533
+ __legacyDecorateClassTS([
2534
+ Get4("/:id"),
2535
+ __legacyDecorateParamTS(0, Params4("id")),
2536
+ __legacyMetadataTS("design:type", Function),
2537
+ __legacyMetadataTS("design:paramtypes", [
2538
+ String
2539
+ ]),
2540
+ __legacyMetadataTS("design:returntype", Promise)
2541
+ ], PermissionController.prototype, "getPermission", null);
2542
+ __legacyDecorateClassTS([
2543
+ Post4(),
2544
+ __legacyDecorateParamTS(0, Body4()),
2545
+ __legacyMetadataTS("design:type", Function),
2546
+ __legacyMetadataTS("design:paramtypes", [
2547
+ Object
2548
+ ]),
2549
+ __legacyMetadataTS("design:returntype", Promise)
2550
+ ], PermissionController.prototype, "create", null);
2551
+ __legacyDecorateClassTS([
2552
+ Put3("/:id"),
2553
+ __legacyDecorateParamTS(0, Params4("id")),
2554
+ __legacyDecorateParamTS(1, Body4()),
2555
+ __legacyMetadataTS("design:type", Function),
2556
+ __legacyMetadataTS("design:paramtypes", [
2557
+ String,
2558
+ Object
2559
+ ]),
2560
+ __legacyMetadataTS("design:returntype", Promise)
2561
+ ], PermissionController.prototype, "update", null);
2562
+ __legacyDecorateClassTS([
2563
+ Delete3("/:id"),
2564
+ __legacyDecorateParamTS(0, Params4("id")),
2565
+ __legacyMetadataTS("design:type", Function),
2566
+ __legacyMetadataTS("design:paramtypes", [
2567
+ String
2568
+ ]),
2569
+ __legacyMetadataTS("design:returntype", Promise)
2570
+ ], PermissionController.prototype, "delete", null);
2571
+ __legacyDecorateClassTS([
2572
+ Get4("/role/:roleId"),
2573
+ __legacyDecorateParamTS(0, Params4("roleId")),
2574
+ __legacyMetadataTS("design:type", Function),
2575
+ __legacyMetadataTS("design:paramtypes", [
2576
+ String
2577
+ ]),
2578
+ __legacyMetadataTS("design:returntype", Promise)
2579
+ ], PermissionController.prototype, "getByRole", null);
2580
+ __legacyDecorateClassTS([
2581
+ Get4("/roles/:permissionId"),
2582
+ __legacyDecorateParamTS(0, Params4("permissionId")),
2583
+ __legacyMetadataTS("design:type", Function),
2584
+ __legacyMetadataTS("design:paramtypes", [
2585
+ String
2586
+ ]),
2587
+ __legacyMetadataTS("design:returntype", Promise)
2588
+ ], PermissionController.prototype, "getRolesByPermission", null);
2589
+ __legacyDecorateClassTS([
2590
+ Post4("/assign/:roleId/:permissionId"),
2591
+ __legacyDecorateParamTS(0, Params4("roleId")),
2592
+ __legacyDecorateParamTS(1, Params4("permissionId")),
2593
+ __legacyMetadataTS("design:type", Function),
2594
+ __legacyMetadataTS("design:paramtypes", [
2595
+ String,
2596
+ String
2597
+ ]),
2598
+ __legacyMetadataTS("design:returntype", Promise)
2599
+ ], PermissionController.prototype, "assignToRole", null);
2600
+ __legacyDecorateClassTS([
2601
+ Delete3("/remove/:roleId/:permissionId"),
2602
+ __legacyDecorateParamTS(0, Params4("roleId")),
2603
+ __legacyDecorateParamTS(1, Params4("permissionId")),
2604
+ __legacyMetadataTS("design:type", Function),
2605
+ __legacyMetadataTS("design:paramtypes", [
2606
+ String,
2607
+ String
2608
+ ]),
2609
+ __legacyMetadataTS("design:returntype", Promise)
2610
+ ], PermissionController.prototype, "removeFromRole", null);
2611
+ __legacyDecorateClassTS([
2612
+ Delete3(),
2613
+ isAdmin3(),
2614
+ __legacyMetadataTS("design:type", Function),
2615
+ __legacyMetadataTS("design:paramtypes", []),
2616
+ __legacyMetadataTS("design:returntype", Promise)
2617
+ ], PermissionController.prototype, "deleteAll", null);
2618
+ PermissionController = __legacyDecorateClassTS([
2619
+ Controller4("/permissions"),
2620
+ isAdmin3(),
2621
+ __legacyMetadataTS("design:paramtypes", [
2622
+ typeof PermissionService === "undefined" ? Object : PermissionService
2623
+ ])
2624
+ ], PermissionController);
2625
+ // src/shared/index.ts
2626
+ import * as fs from "fs/promises";
2627
+ import * as path from "path";
2628
+ import _isEmpty from "lodash.isempty";
2629
+ var avatarsPath = path.join(process.cwd(), "avatars");
2630
+ var parseSchema4 = async (schema, data) => {
2631
+ try {
2632
+ return await schema.parseAsync(data);
2633
+ } catch (error) {
2634
+ const errors = error.issues || error.errors || [];
2635
+ const errorMessage = errors.map((err) => `${err.path.join(".")}: ${err.message}`).join("; ");
2636
+ throw new Error(errorMessage);
2637
+ }
2638
+ };
2639
+ var clean2 = (obj) => {
2640
+ const cleaned = {};
2641
+ for (const [key, value] of Object.entries(obj)) {
2642
+ if (value !== null && value !== undefined && value !== "") {
2643
+ cleaned[key] = value;
2644
+ }
2645
+ }
2646
+ return cleaned;
2647
+ };
2648
+ var getAvatarFile = async (fileName) => {
2649
+ try {
2650
+ const filePath = path.join(avatarsPath, fileName);
2651
+ const buffer = await fs.readFile(filePath);
2652
+ const file = new File([buffer], fileName, {
2653
+ type: "image/png"
2654
+ });
2655
+ return file;
2656
+ } catch (error) {
2657
+ return null;
2658
+ }
2659
+ };
2660
+ var formatDate = (dateValue) => {
2661
+ if (!dateValue)
2662
+ return null;
2663
+ let date;
2664
+ if (dateValue instanceof Date) {
2665
+ date = dateValue;
2666
+ } else if (typeof dateValue === "string") {
2667
+ date = new Date(dateValue);
2668
+ } else {
2669
+ return null;
2670
+ }
2671
+ if (isNaN(date.getTime()))
2672
+ return null;
2673
+ return date.toISOString().split("T")[0];
2674
+ };
2675
+ function calculateAge(dateOfBirth) {
2676
+ if (!dateOfBirth)
2677
+ return null;
2678
+ const formattedDate = formatDate(dateOfBirth);
2679
+ if (!formattedDate)
2680
+ return null;
2681
+ const birth = new Date(formattedDate);
2682
+ const today = new Date;
2683
+ let age = today.getFullYear() - birth.getFullYear();
2684
+ const monthDiff = today.getMonth() - birth.getMonth();
2685
+ if (monthDiff < 0 || monthDiff === 0 && today.getDate() < birth.getDate()) {
2686
+ age--;
2687
+ }
2688
+ return age;
2689
+ }
2690
+ function calculateYearsOfExperience(hireDate) {
2691
+ if (!hireDate)
2692
+ return null;
2693
+ const formattedDate = formatDate(hireDate);
2694
+ if (!formattedDate)
2695
+ return null;
2696
+ const hire = new Date(formattedDate);
2697
+ const today = new Date;
2698
+ let years = today.getFullYear() - hire.getFullYear();
2699
+ const monthDiff = today.getMonth() - hire.getMonth();
2700
+ if (monthDiff < 0 || monthDiff === 0 && today.getDate() < hire.getDate()) {
2701
+ years--;
2702
+ }
2703
+ return years;
2704
+ }
2705
+ function pickProps(source, keys) {
2706
+ const result = {};
2707
+ for (const key of keys) {
2708
+ if (source[key] !== undefined) {
2709
+ result[key] = source[key];
2710
+ }
2711
+ }
2712
+ return result;
2713
+ }
2714
+ var isEmpty = _isEmpty;
2715
+ var isPath = (img) => typeof img === "string" && img.trim().length > 0 && (img.startsWith("/") || img.startsWith("http") || img.startsWith("storage/"));
2716
+ var isFile = (img) => !!img && typeof img !== "string" && img instanceof File;
2717
+ // src/database/db.ts
2718
+ import { drizzle } from "drizzle-orm/postgres-js";
2719
+
2720
+ // src/database/schema/index.ts
2721
+ var exports_schema = {};
2722
+ __export(exports_schema, {
2723
+ usersTable: () => usersTable3,
2724
+ tokensTable: () => tokensTable2,
2725
+ timestamps: () => timestamps,
2726
+ rolesTable: () => rolesTable5,
2727
+ rolePermissionsTable: () => rolePermissionsTable4,
2728
+ permissionsTable: () => permissionsTable4,
2729
+ idField: () => idField
2730
+ });
2731
+ import { pgTable, text, boolean, timestamp } from "drizzle-orm/pg-core";
2732
+ import { nanoid as nanoid2 } from "nanoid";
2733
+ import { sql } from "drizzle-orm";
2734
+
2735
+ // src/database/schema/PgEnum.ts
2736
+ import { getEnumConfig as getEnumConfig2 } from "@/lib/ENUMS";
2737
+ import { pgEnum } from "drizzle-orm/pg-core";
2738
+ var createPgEnum = (enumKey) => {
2739
+ const config = getEnumConfig2(enumKey);
2740
+ if (!config)
2741
+ throw new Error(`Enum ${enumKey} not found`);
2742
+ const enumName = config.name || enumKey;
2743
+ return pgEnum(enumName, config.values);
2744
+ };
2745
+ var userStatusEnum2 = createPgEnum("userStatus");
2746
+ var tokenStatusEnum2 = createPgEnum("tokenStatus");
2747
+ var tokenTypeEnum2 = createPgEnum("tokenType");
2748
+ var studentStatusEnum2 = createPgEnum("studentStatus");
2749
+
2750
+ // src/database/schema/index.ts
2751
+ var timestamps = {
2752
+ createdAt: timestamp("created_at", { mode: "string" }).defaultNow(),
2753
+ updatedAt: timestamp("updated_at", { mode: "string" }).defaultNow().$onUpdate(() => sql`CURRENT_TIMESTAMP`)
2754
+ };
2755
+ var idField = (length = 5) => text("id").primaryKey().notNull().$defaultFn(() => nanoid2(length));
2756
+ var rolesTable5 = pgTable("roles", {
2757
+ id: idField(),
2758
+ name: text("name").notNull(),
2759
+ description: text("description")
2760
+ });
2761
+ var usersTable3 = pgTable("users", {
2762
+ id: idField(8),
2763
+ email: text("email").notNull().unique(),
2764
+ emailVerified: boolean("email_verified").default(false),
2765
+ password: text("password").notNull(),
2766
+ image: text("image").default("noavatar.png"),
2767
+ status: userStatusEnum2("status").default("pending"),
2768
+ roleId: text("role_id").references(() => rolesTable5.id),
2769
+ lastLogin: timestamp("last_login", { mode: "string" }),
2770
+ ...timestamps
2771
+ });
2772
+ var tokensTable2 = pgTable("tokens", {
2773
+ id: idField(10),
2774
+ userId: text("user_id").references(() => usersTable3.id, { onDelete: "cascade" }).unique().notNull(),
2775
+ token: text("token").notNull(),
2776
+ type: tokenTypeEnum2("type").default("refresh"),
2777
+ status: tokenStatusEnum2("status").default("active"),
2778
+ expiresAt: timestamp("expires_at", { mode: "string" }).notNull(),
2779
+ ...timestamps
2780
+ });
2781
+ var permissionsTable4 = pgTable("permissions", {
2782
+ id: idField(),
2783
+ name: text("name").notNull().unique(),
2784
+ description: text("description"),
2785
+ resource: text("resource").notNull(),
2786
+ action: text("action").notNull(),
2787
+ ...timestamps
2788
+ });
2789
+ var rolePermissionsTable4 = pgTable("role_permissions", {
2790
+ id: idField(),
2791
+ roleId: text("role_id").references(() => rolesTable5.id).notNull(),
2792
+ permissionId: text("permission_id").references(() => permissionsTable4.id).notNull(),
2793
+ ...timestamps
2794
+ });
2795
+
2796
+ // src/database/db.ts
2797
+ var db = process.env.DB_URL ? drizzle(process.env.DB_URL, { schema: exports_schema }) : null;
2798
+ if (db) {
2799
+ console.warn("⚠️ najm-auth: Using standalone DB instance. This should only be used for development.");
2800
+ }
2801
+ // src/plugin.ts
2802
+ var AuthPlugin = {
2803
+ name: "najm-auth",
2804
+ version: "0.1.3",
2805
+ database: "auth",
2806
+ controllers: [
2807
+ UserController,
2808
+ AuthController,
2809
+ RoleController,
2810
+ PermissionController
2811
+ ],
2812
+ services: [
2813
+ UserService,
2814
+ AuthService,
2815
+ CookieService,
2816
+ EncryptionService,
2817
+ RoleService,
2818
+ PermissionService,
2819
+ TokenService
2820
+ ],
2821
+ repositories: [
2822
+ UserRepository,
2823
+ RoleRepository,
2824
+ PermissionRepository,
2825
+ TokenRepository
2826
+ ],
2827
+ providers: [
2828
+ UserValidator,
2829
+ RoleValidator,
2830
+ PermissionValidator,
2831
+ RoleGuards,
2832
+ PermissionGuards
2833
+ ],
2834
+ onSetup: async () => {
2835
+ console.log(" ✓ najm-auth plugin initialized");
2836
+ console.log(" - Authentication endpoints ready");
2837
+ console.log(" - Authorization system active");
2838
+ console.log(" - Database connection established");
2839
+ },
2840
+ onTeardown: async () => {
2841
+ console.log(" ✓ najm-auth plugin cleanup complete");
2842
+ }
2843
+ };
2844
+ export {
2845
+ vehicleTypeEnum,
2846
+ vehicleStatusEnum,
2847
+ vehicleSchema,
2848
+ vehicleDocumentTypeEnum,
2849
+ usersTable3 as usersTable,
2850
+ userTypeEnum,
2851
+ userStatusEnum,
2852
+ userSchema2 as userSchema,
2853
+ trackerModeEnum,
2854
+ tokensTable2 as tokensTable,
2855
+ tokenTypeEnum,
2856
+ tokenStatusEnum,
2857
+ teacherStatusEnum,
2858
+ teacherProfessionalSchema,
2859
+ teacherPersonalSchema,
2860
+ teacherFullSchema,
2861
+ submissionTypeEnum,
2862
+ subjectSchema,
2863
+ studentStatusEnum,
2864
+ studentSchema,
2865
+ settingsSchema,
2866
+ semesterEnum,
2867
+ sectionStatusEnum,
2868
+ sectionSchema,
2869
+ scheduleEnum,
2870
+ rolesTable5 as rolesTable,
2871
+ roleSchema2 as roleSchema,
2872
+ rolePermissionsTable4 as rolePermissionsTable,
2873
+ relationshipTypeEnum,
2874
+ refuelStatusEnum,
2875
+ refuelSchema,
2876
+ proficiencyLevelEnum,
2877
+ pickProps,
2878
+ permissionsTable4 as permissionsTable,
2879
+ paymentTypeEnum,
2880
+ paymentStatusEnum,
2881
+ paymentMethodEnum,
2882
+ paymentAllocationSchema,
2883
+ participantTypeEnum,
2884
+ parseSchema4 as parseSchema,
2885
+ parentsSchema,
2886
+ parentSchema,
2887
+ paginationSchema,
2888
+ maritalStatusEnum,
2889
+ maintenanceTypeEnum,
2890
+ maintenanceStatusEnum,
2891
+ languageEnum,
2892
+ isTeacher,
2893
+ isStudent,
2894
+ isStaff,
2895
+ isSecretary,
2896
+ isPrincipal,
2897
+ isPath,
2898
+ isParent,
2899
+ isFinancial,
2900
+ isFile,
2901
+ isEmpty,
2902
+ isAuth,
2903
+ isAdministrator,
2904
+ isAdmin,
2905
+ isAccounting,
2906
+ idParamSchema,
2907
+ idField,
2908
+ gradeStatusEnum,
2909
+ gradeSchema,
2910
+ getEnumValues,
2911
+ getEnumConfig,
2912
+ getAvatarFile,
2913
+ genderEnum,
2914
+ fullStudentSchema,
2915
+ fuelTypeEnum,
2916
+ formatDate,
2917
+ fileStatusEnum,
2918
+ feesSchema,
2919
+ feeTypeStatusEnum,
2920
+ feeTypeSchema,
2921
+ feeStatusEnum,
2922
+ feeSchema,
2923
+ feePaymentSchema,
2924
+ feeInstallmentStatusEnum,
2925
+ feeInstallmentSchema,
2926
+ expenseStatusEnum,
2927
+ expenseSchema,
2928
+ expensePaymentSchema,
2929
+ expenseCategoryEnum,
2930
+ expenseApprovalSchema,
2931
+ examTypeEnum,
2932
+ examStatusEnum,
2933
+ examSecurityEnum,
2934
+ examSchema,
2935
+ eventVisibilityEnum,
2936
+ eventTypeEnum,
2937
+ eventStatusEnum,
2938
+ eventSchema,
2939
+ eventParticipantSchema,
2940
+ enrollmentStatusEnum,
2941
+ employmentTypeEnum,
2942
+ driverStatusEnum,
2943
+ driverSchema,
2944
+ db,
2945
+ dayOfWeekEnum,
2946
+ dateRangeSchema,
2947
+ clean2 as clean,
2948
+ classStatusEnum,
2949
+ classSchema,
2950
+ calendarSystemEnum,
2951
+ calculateYearsOfExperience,
2952
+ calculateAge,
2953
+ busStatusEnum,
2954
+ bulkFeeItemSchema,
2955
+ bulkFeeFormSchema,
2956
+ bulkAssessmentSchema,
2957
+ avatarsPath,
2958
+ attendanceStatusEnum,
2959
+ attendanceSchema,
2960
+ assignmentsSchema,
2961
+ assignmentStatusEnum,
2962
+ assignmentSchema,
2963
+ assessmentTypeEnum,
2964
+ assessmentStatusEnum,
2965
+ assessmentSchema,
2966
+ announcementSchema,
2967
+ alertTypeEnum,
2968
+ alertStatusEnum,
2969
+ alertSchema,
2970
+ alertPriorityEnum,
2971
+ UserValidator,
2972
+ UserService,
2973
+ UserRepository,
2974
+ UserController,
2975
+ TokenService,
2976
+ TokenRepository,
2977
+ RoleValidator,
2978
+ RoleService,
2979
+ RoleRepository,
2980
+ RoleGuards,
2981
+ RoleController,
2982
+ RoleChecker,
2983
+ Role,
2984
+ ROLE_GROUPS,
2985
+ ROLES,
2986
+ PermissionValidator,
2987
+ PermissionService,
2988
+ PermissionRepository,
2989
+ PermissionGuards,
2990
+ PermissionController,
2991
+ Permission,
2992
+ EncryptionService,
2993
+ ENUMS,
2994
+ CookieService,
2995
+ AuthService,
2996
+ AuthPlugin,
2997
+ AuthController
2998
+ };