flightdeck 0.2.6 → 0.2.8

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.
@@ -1,8 +1,10 @@
1
1
  #!/usr/bin/env node
2
- var U=Object.defineProperty;var oe=(e,t)=>{for(var i in t)U(e,i,{get:t[i],enumerable:!0,configurable:!0,set:(o)=>t[i]=()=>o})};import*as I from"node:path";import{cli as Q,optional as W,parseBooleanOption as X,parseNumberOption as ee}from"comline";import{z as r}from"zod";import{execSync as D,spawn as M}from"node:child_process";import{createServer as G}from"node:http";import{homedir as V}from"node:os";import{resolve as _}from"node:path";import{inspect as F}from"node:util";import{Future as p}from"atom.io/internal";import{discoverType as B}from"atom.io/introspection";import{fromEntries as k,toEntries as f}from"atom.io/json";import{ChildSocket as J}from"atom.io/realtime-server";import{CronJob as z}from"cron";import{z as c}from"zod";import{existsSync as b,mkdirSync as T,readdirSync as A,readFileSync as j,rmSync as E,statSync as C,writeFileSync as O}from"node:fs";import{resolve as w}from"node:path";class S{rootDir;constructor(e){if(this.rootDir=e.path,!b(this.rootDir))T(this.rootDir,{recursive:!0})}getItem(e){let t=w(this.rootDir,e);if(b(t))return j(t,"utf-8");return null}setItem(e,t){let i=w(this.rootDir,e);O(i,t)}removeItem(e){let t=w(this.rootDir,e);if(b(t))E(t)}key(e){return A(this.rootDir).sort((o,g)=>{let a=C(o);return C(g).ctimeMs-a.ctimeMs})[e]??null}clear(){E(this.rootDir,{recursive:!0}),T(this.rootDir,{recursive:!0})}get length(){return A(this.rootDir).length}}import{createEnv as K}from"@t3-oss/env-core";import{z as H}from"zod";var R=K({server:{FLIGHTDECK_SECRET:H.string().optional()},clientPrefix:"NEVER",client:{},runtimeEnv:import.meta.env,emptyStringAsUndefined:!0});var Le=["downloaded","installed"],Pe=["notified","confirmed"];function q(e){return/^\d+\.\d+\.\d+$/.test(e)||!Number.isNaN(Number.parseFloat(e))}class L{options;safety=0;storage;webhookServer;services;serviceIdx;defaultServicesReadyToUpdate;servicesReadyToUpdate;autoRespawnDeadServices;logger;serviceLoggers;updateAvailabilityChecker=null;servicesLive;servicesDead;live=new p(()=>{});dead=new p(()=>{});restartTimes=[];constructor(e){this.options=e;let{FLIGHTDECK_SECRET:t}=R,{flightdeckRootDir:i=_(V(),".flightdeck")}=e,o=e.port??8080,g=`http://localhost:${o}`,a=f(e.services);if(this.services=k(a.map(([s])=>[s,null])),this.serviceIdx=k(a.map(([s],n)=>[s,n])),this.defaultServicesReadyToUpdate=k(a.map(([s,{waitFor:n}])=>[s,!n])),this.servicesReadyToUpdate={...this.defaultServicesReadyToUpdate},this.autoRespawnDeadServices=!0,this.logger=new u(this.options.packageName,process.pid,void 0,{jsonLogging:this.options.jsonLogging??!1}),this.serviceLoggers=k(a.map(([s])=>[s,new u(this.options.packageName,process.pid,s,{jsonLogging:this.options.jsonLogging??!1})])),this.servicesLive=a.map(()=>new p(()=>{})),this.servicesDead=a.map(()=>new p(()=>{})),this.live.use(Promise.all(this.servicesLive)),this.dead.use(Promise.all(this.servicesDead)),this.storage=new S({path:_(i,"storage",e.packageName)}),t===void 0)this.logger.warn("No FLIGHTDECK_SECRET environment variable found. FlightDeck will not run an update server.");else G((s,n)=>{let m=[];s.on("data",(l)=>{m.push(l instanceof Buffer?l:Buffer.from(l))}).on("end",()=>{let l=s.headers.authorization;try{if(typeof s.url==="undefined")throw 400;let h=`Bearer ${t}`;if(l!==`Bearer ${t}`)throw this.logger.info(`Unauthorized: needed \`${h}\`, got \`${l}\``),401;let y=new URL(s.url,g);this.logger.info(s.method,y.pathname);let v=Buffer.concat(m).toString();if(!q(v))throw 400;n.writeHead(200),n.end(),this.storage.setItem("updatePhase","notified"),this.storage.setItem("updateAwaitedVersion",v);let{checkAvailability:N}=e.scripts;if(N){this.updateAvailabilityChecker?.stop(),this.seekUpdate(v);let x=this.storage.getItem("updatePhase");if(this.logger.info('> storage("updatePhase") >',x),x==="notified")this.updateAvailabilityChecker=new z("30 * * * * *",()=>{this.seekUpdate(v)}),this.updateAvailabilityChecker.start()}else this.downloadPackage()}catch(h){if(this.logger.error(h,s.url),typeof h==="number")n.writeHead(h),n.end()}finally{m=[]}})}).listen(o,()=>{this.logger.info(`Server started on port ${o}`)});this.startAllServices().then(()=>{this.logger.info("All services started.")}).catch((s)=>{if(s instanceof Error)this.logger.error("Failed to start all services:",s.message)})}seekUpdate(e){this.logger.info("Checking for updates...");let{checkAvailability:t}=this.options.scripts;if(!t){this.logger.info("No checkAvailability script found.");return}try{let i=D(`${t} ${e}`);this.logger.info("Check stdout:",i.toString()),this.updateAvailabilityChecker?.stop(),this.storage.setItem("updatePhase","confirmed"),this.downloadPackage(),this.announceUpdate()}catch(i){if(i instanceof Error)this.logger.error("Check failed:",i.message);else{let o=B(i);this.logger.error("Check threw",o,i)}}}announceUpdate(){for(let e of f(this.services)){let[t,i]=e;if(i){if(this.options.services[t].waitFor)i.emit("updatesReady")}else this.startService(t)}}tryUpdate(){if(f(this.servicesReadyToUpdate).every(([,e])=>e))this.logger.info("All services are ready to update."),this.stopAllServices().then(()=>{this.logger.info("All services stopped; starting up fresh..."),this.startAllServices().then(()=>{this.logger.info("All services started; we're back online.")}).catch((e)=>{if(e instanceof Error)this.logger.error("Failed to start all services:",e.message)})}).catch((e)=>{if(e instanceof Error)this.logger.error("Failed to stop all services:",e.message)})}startAllServices(){this.logger.info("Starting all services..."),this.autoRespawnDeadServices=!0;let e=this.storage.getItem("setupPhase");switch(this.logger.info('> storage("setupPhase") >',e),e){case null:return this.logger.info("Starting from scratch."),this.downloadPackage(),this.installPackage(),this.startAllServices();case"downloaded":return this.logger.info("Found package downloaded but not installed."),this.installPackage(),this.startAllServices();case"installed":{for(let[t]of f(this.services))this.startService(t);return this.live}}}startService(e){if(this.logger.info(`Starting service ${this.options.packageName}::${e}, try ${this.safety}/2...`),this.safety>=2)throw new Error("Out of tries...");this.safety++;let[t,...i]=this.options.services[e].run.split(" "),o=M(t,i,{cwd:this.options.flightdeckRootDir,env:import.meta.env}),g=this.serviceLoggers[e],a=this.services[e]=new J(o,`${this.options.packageName}::${e}`,g);g.processCode=a.process.pid??-1,this.services[e].onAny((...s)=>{g.info("\uD83D\uDCAC",...s)}),this.services[e].on("readyToUpdate",()=>{this.logger.info(`Service "${e}" is ready to update.`),this.servicesReadyToUpdate[e]=!0,this.tryUpdate()}),this.services[e].on("alive",()=>{if(this.servicesLive[this.serviceIdx[e]].use(Promise.resolve()),this.servicesDead[this.serviceIdx[e]]=new p(()=>{}),this.dead.done)this.dead=new p(()=>{});this.dead.use(Promise.all(this.servicesDead))}),this.services[e].process.once("close",(s)=>{if(this.logger.info(`Auto-respawn saw "${e}" exit with code ${s}`),this.services[e]=null,!this.autoRespawnDeadServices){this.logger.info(`Auto-respawn is off; "${e}" rests.`);return}let n=this.storage.getItem("updatePhase");if(this.logger.info('> storage("updatePhase") >',n),n==="confirmed")this.serviceLoggers[e].info("Updating before startup..."),this.restartTimes=[],this.installPackage(),this.startService(e);else{let l=Date.now(),h=l-300000;if(this.restartTimes=this.restartTimes.filter((y)=>y>h),this.restartTimes.push(l),this.restartTimes.length<5)this.serviceLoggers[e].info("Crashed. Restarting..."),this.startService(e);else this.serviceLoggers[e].info("Crashed 5 times in 5 minutes. Not restarting.")}}),this.safety=0}downloadPackage(){this.logger.info("Downloading...");try{let e=D(this.options.scripts.download);this.logger.info("Download stdout:",e.toString()),this.storage.setItem("setupPhase","downloaded"),this.logger.info("Downloaded!")}catch(e){if(e instanceof Error)this.logger.error(`Failed to get the latest release: ${e.message}`);return}}installPackage(){this.logger.info("Installing...");try{let e=D(this.options.scripts.install);this.logger.info("Install stdout:",e.toString()),this.storage.setItem("setupPhase","installed"),this.logger.info("Installed!")}catch(e){if(e instanceof Error)this.logger.error(`Failed to get the latest release: ${e.message}`);return}}stopAllServices(){this.logger.info("Stopping all services... auto-respawn disabled."),this.autoRespawnDeadServices=!1;for(let[e]of f(this.services))this.stopService(e);return this.dead}stopService(e){let t=this.services[e];if(t){if(this.logger.info(`Stopping service "${e}"...`),this.servicesDead[this.serviceIdx[e]].use(new Promise((i)=>{t.emit("timeToStop"),t.process.once("close",(o)=>{this.logger.info(`Stopped service "${e}"; exited with code ${o}`),this.services[e]=null,i()})})),this.dead.use(Promise.all(this.servicesDead)),this.servicesLive[this.serviceIdx[e]]=new p(()=>{}),this.live.done)this.live=new p(()=>{});this.live.use(Promise.all(this.servicesLive))}else this.serviceLoggers[e].error("Tried to stop service, but it wasn't running.")}}var xe=c.object({level:c.union([c.literal("info"),c.literal("warn"),c.literal("ERR!")]),timestamp:c.number(),package:c.string(),service:c.string().optional(),process:c.number(),body:c.string()}),Y="line-format",Z="value",Te={title:"FlightDeck Log",description:"Format for events logged by the FlightDeck process manager.","file-type":"json","timestamp-field":"timestamp","subsecond-field":"subsecond","subsecond-units":"milli","opid-field":"service","level-field":"level",level:{info:"info",warning:"warn",error:"err!"},"ordered-by-time":!0,[Y]:[{prefix:" ",field:"__timestamp__","timestamp-format":"%Y-%m-%dT%H:%M:%S.%L%Z"},{prefix:" ",field:"process","min-width":5},{prefix:":",field:"package"},{prefix:":",field:"service","default-value":""},{prefix:"[",field:"__level__",suffix:"]"},{prefix:": ",field:"body"}],[Z]:{timestamp:{kind:"integer"},level:{kind:"string"},package:{kind:"string"},service:{kind:"string"},process:{kind:"integer"},body:{kind:"string"}}};class u{packageName;serviceName;jsonLogging;processCode;constructor(e,t,i,o){if(this.packageName=e,i)this.serviceName=i;this.processCode=t,this.jsonLogging=o?.jsonLogging??!1}info(...e){if(this.jsonLogging){let t={timestamp:Date.now(),level:"info",process:this.processCode,package:this.packageName,body:e.map((i)=>typeof i==="string"?i:F(i,!1,null,!0)).join(" ")};if(this.serviceName)t.service=this.serviceName;process.stdout.write(JSON.stringify(t)+`
3
- `)}else{let t=this.serviceName?`${this.packageName}::${this.serviceName}`:this.packageName;console.log(`${t}:`,...e)}}warn(...e){if(this.jsonLogging){let t={timestamp:Date.now(),level:"warn",process:this.processCode,package:this.packageName,body:e.map((i)=>typeof i==="string"?i:F(i,!1,null,!0)).join(" ")};if(this.serviceName)t.service=this.serviceName;process.stdout.write(JSON.stringify(t)+`
4
- `)}else{let t=this.serviceName?`${this.packageName}::${this.serviceName}`:this.packageName;console.warn(`${t}:`,...e)}}error(...e){if(this.jsonLogging){let t={timestamp:Date.now()+Math.floor(Math.random()*1000),level:"ERR!",process:this.processCode,package:this.packageName,body:e.map((i)=>typeof i==="string"?i:F(i,!1,null,!0)).join(" ")};if(this.serviceName)t.service=this.serviceName;process.stdout.write(JSON.stringify(t)+`
5
- `)}else{let t=this.serviceName?`${this.packageName}::${this.serviceName}`:this.packageName;console.error(`${t}:`,...e)}}}var d=new u("comline",process.pid,void 0,{jsonLogging:!0});Object.assign(console,{log:d.info.bind(d),info:d.info.bind(d),warn:d.warn.bind(d),error:d.error.bind(d)});var $={optionsSchema:r.object({port:r.number().optional(),packageName:r.string(),services:r.record(r.object({run:r.string(),waitFor:r.boolean()})),flightdeckRootDir:r.string(),scripts:r.object({download:r.string(),install:r.string(),checkAvailability:r.string()}),jsonLogging:r.boolean().optional()}),options:{port:{flag:"p",required:!1,description:"Port to run the flightdeck server on.",example:"--port=8080",parse:ee},packageName:{flag:"n",required:!0,description:"Name of the package.",example:'--packageName="my-app"'},services:{flag:"s",required:!0,description:"Map of service names to executables.",example:'--services="{\\"frontend\\":{\\"run\\":\\"./frontend\\",\\"waitFor\\":false},\\"backend\\":{\\"run\\":\\"./backend\\",\\"waitFor\\":true}}"',parse:JSON.parse},flightdeckRootDir:{flag:"d",required:!0,description:"Directory where the service is stored.",example:'--flightdeckRootDir="./services/sample/repo/my-app/current"'},scripts:{flag:"r",required:!0,description:"Map of scripts to run.",example:'--scripts="{\\"download\\":\\"npm i",\\"install\\":\\"npm run build\\"}"',parse:JSON.parse},jsonLogging:{flag:"j",required:!1,description:"Enable json logging.",example:"--jsonLogging",parse:X}}},te={optionsSchema:r.object({outdir:r.string().optional()}),options:{outdir:{flag:"o",required:!1,description:"Directory to write the schema to.",example:"--outdir=./dist"}}},ie=Q({cliName:"flightdeck",routes:W({schema:null,$configPath:null}),routeOptions:{"":$,$configPath:$,schema:te},debugOutput:!0,discoverConfigPath:(e)=>{if(e[0]==="schema")return;return e[0]??I.join(process.cwd(),"flightdeck.config.json")}},console),{inputs:P,writeJsonSchema:se}=ie(process.argv);switch(P.case){case"schema":{let{outdir:e}=P.opts;se(e??".")}break;default:{let e=new L(P.opts);process.on("close",async()=>{await e.stopAllServices()})}}
2
+ var K=Object.defineProperty;var ae=(e,t)=>{for(var i in t)K(e,i,{get:t[i],enumerable:!0,configurable:!0,set:(o)=>t[i]=()=>o})};import*as O from"node:path";import{cli as ee,optional as te,parseBooleanOption as ie,parseNumberOption as se}from"comline";import{z as r}from"zod";import{execSync as x,spawn as V}from"node:child_process";import{createServer as B}from"node:http";import{homedir as z}from"node:os";import{resolve as U}from"node:path";import{inspect as J}from"node:util";import{Future as d}from"atom.io/internal";import{discoverType as q}from"atom.io/introspection";import{fromEntries as k,toEntries as f}from"atom.io/json";import{ChildSocket as W}from"atom.io/realtime-server";import{CronJob as Y}from"cron";import{z as l}from"zod";import{existsSync as D,mkdirSync as A,readdirSync as C,readFileSync as H,rmSync as R,statSync as I,writeFileSync as G}from"node:fs";import{resolve as F}from"node:path";class L{rootDir;constructor(e){if(this.rootDir=e.path,!D(this.rootDir))A(this.rootDir,{recursive:!0})}getItem(e){let t=F(this.rootDir,e);if(D(t))return H(t,"utf-8");return null}setItem(e,t){let i=F(this.rootDir,e);G(i,t)}removeItem(e){let t=F(this.rootDir,e);if(D(t))R(t)}key(e){return C(this.rootDir).sort((o,n)=>{let c=I(o);return I(n).ctimeMs-c.ctimeMs})[e]??null}clear(){R(this.rootDir,{recursive:!0}),A(this.rootDir,{recursive:!0})}get length(){return C(this.rootDir).length}}import{createEnv as N}from"@t3-oss/env-core";import{z as M}from"zod";var _=N({server:{FLIGHTDECK_SECRET:M.string().optional()},clientPrefix:"NEVER",client:{},runtimeEnv:import.meta.env,emptyStringAsUndefined:!0});var Te=["downloaded","installed"],Ee=["notified","confirmed"];function Z(e){return/^\d+\.\d+\.\d+$/.test(e)||!Number.isNaN(Number.parseFloat(e))}class P{options;safety=0;storage;webhookServer;services;serviceIdx;defaultServicesReadyToUpdate;servicesReadyToUpdate;autoRespawnDeadServices;logger;serviceLoggers;updateAvailabilityChecker=null;servicesLive;servicesDead;live=new d(()=>{});dead=new d(()=>{});restartTimes=[];constructor(e){this.options=e;let{FLIGHTDECK_SECRET:t}=_,{flightdeckRootDir:i=U(z(),".flightdeck")}=e,o=e.port??8080,n=`http://localhost:${o}`,c=f(e.services);if(this.services=k(c.map(([s])=>[s,null])),this.serviceIdx=k(c.map(([s],a)=>[s,a])),this.defaultServicesReadyToUpdate=k(c.map(([s,{waitFor:a}])=>[s,!a])),this.servicesReadyToUpdate={...this.defaultServicesReadyToUpdate},this.autoRespawnDeadServices=!0,this.logger=new u(this.options.packageName,process.pid,void 0,{jsonLogging:this.options.jsonLogging??!1}),this.serviceLoggers=k(c.map(([s])=>[s,new u(this.options.packageName,process.pid,s,{jsonLogging:this.options.jsonLogging??!1})])),this.servicesLive=c.map(()=>new d(()=>{})),this.servicesDead=c.map(()=>new d(()=>{})),this.live.use(Promise.all(this.servicesLive)),this.dead.use(Promise.all(this.servicesDead)),this.storage=new L({path:U(i,"storage",e.packageName)}),t===void 0)this.logger.warn("No FLIGHTDECK_SECRET environment variable found. FlightDeck will not run an update server.");else B((s,a)=>{let m=[];s.on("data",(p)=>{m.push(p instanceof Buffer?p:Buffer.from(p))}).on("end",()=>{let p=s.headers.authorization;try{if(typeof s.url==="undefined")throw 400;let h=`Bearer ${t}`;if(p!==`Bearer ${t}`)throw this.logger.info(`Unauthorized: needed \`${h}\`, got \`${p}\``),401;let S=new URL(s.url,n);this.logger.info(s.method,S.pathname);let v=Buffer.concat(m).toString();if(!Z(v))throw 400;a.writeHead(200),a.end(),this.storage.setItem("updatePhase","notified"),this.storage.setItem("updateAwaitedVersion",v);let{checkAvailability:j}=e.scripts;if(j){this.updateAvailabilityChecker?.stop(),this.seekUpdate(v);let E=this.storage.getItem("updatePhase");if(this.logger.info('> storage("updatePhase") >',E),E==="notified")this.updateAvailabilityChecker=new Y("30 * * * * *",()=>{this.seekUpdate(v)}),this.updateAvailabilityChecker.start()}else this.downloadPackage()}catch(h){if(this.logger.error(h,s.url),typeof h==="number")a.writeHead(h),a.end()}finally{m=[]}})}).listen(o,()=>{this.logger.info(`Server started on port ${o}`)});this.startAllServices().then(()=>{this.logger.info("All services started.")}).catch((s)=>{if(s instanceof Error)this.logger.error("Failed to start all services:",s.message)})}seekUpdate(e){this.logger.info("Checking for updates...");let{checkAvailability:t}=this.options.scripts;if(!t){this.logger.info("No checkAvailability script found.");return}try{let i=x(`${t} ${e}`);this.logger.info("Check stdout:",i.toString()),this.updateAvailabilityChecker?.stop(),this.storage.setItem("updatePhase","confirmed"),this.downloadPackage(),this.announceUpdate()}catch(i){if(i instanceof Error)this.logger.error("Check failed:",i.message);else{let o=q(i);this.logger.error("Check threw",o,i)}}}announceUpdate(){for(let e of f(this.services)){let[t,i]=e;if(i){if(this.options.services[t].waitFor)i.emit("updatesReady")}else this.startService(t)}}tryUpdate(){if(f(this.servicesReadyToUpdate).every(([,e])=>e))this.logger.info("All services are ready to update."),this.stopAllServices().then(()=>{this.logger.info("All services stopped; starting up fresh..."),this.startAllServices().then(()=>{this.logger.info("All services started; we're back online.")}).catch((e)=>{if(e instanceof Error)this.logger.error("Failed to start all services:",e.message)})}).catch((e)=>{if(e instanceof Error)this.logger.error("Failed to stop all services:",e.message)})}startAllServices(){this.logger.info("Starting all services..."),this.autoRespawnDeadServices=!0;let e=this.storage.getItem("setupPhase");switch(this.logger.info('> storage("setupPhase") >',e),e){case null:return this.logger.info("Starting from scratch."),this.downloadPackage(),this.installPackage(),this.startAllServices();case"downloaded":return this.logger.info("Found package downloaded but not installed."),this.installPackage(),this.startAllServices();case"installed":{for(let[t]of f(this.services))this.startService(t);return this.live}}}startService(e){if(this.logger.info(`Starting service ${this.options.packageName}::${e}, try ${this.safety}/2...`),this.safety>=2)throw new Error("Out of tries...");this.safety++;let[t,...i]=this.options.services[e].run.split(" "),o=V(t,i,{cwd:this.options.flightdeckRootDir,env:import.meta.env}),n=this.serviceLoggers[e],c=this.services[e]=new W(o,`${this.options.packageName}::${e}`,n);n.processCode=c.process.pid??-1,this.services[e].onAny((...s)=>{n.info("\uD83D\uDCAC",...s)}),this.services[e].on("readyToUpdate",()=>{this.logger.info(`Service "${e}" is ready to update.`),this.servicesReadyToUpdate[e]=!0,this.tryUpdate()}),this.services[e].on("alive",()=>{if(this.servicesLive[this.serviceIdx[e]].use(Promise.resolve()),this.servicesDead[this.serviceIdx[e]]=new d(()=>{}),this.dead.done)this.dead=new d(()=>{});this.dead.use(Promise.all(this.servicesDead))}),this.services[e].process.once("close",(s)=>{if(this.logger.info(`Auto-respawn saw "${e}" exit with code ${s}`),this.services[e]=null,!this.autoRespawnDeadServices){this.logger.info(`Auto-respawn is off; "${e}" rests.`);return}let a=this.storage.getItem("updatePhase");if(this.logger.info('> storage("updatePhase") >',a),a==="confirmed")this.serviceLoggers[e].info("Updating before startup..."),this.restartTimes=[],this.installPackage(),this.startService(e);else{let p=Date.now(),h=p-300000;if(this.restartTimes=this.restartTimes.filter((S)=>S>h),this.restartTimes.push(p),this.restartTimes.length<5)this.serviceLoggers[e].info("Crashed. Restarting..."),this.startService(e);else this.serviceLoggers[e].info("Crashed 5 times in 5 minutes. Not restarting.")}}),this.safety=0}downloadPackage(){this.logger.info("Downloading...");try{let e=x(this.options.scripts.download);this.logger.info("Download stdout:",e.toString()),this.storage.setItem("setupPhase","downloaded"),this.logger.info("Downloaded!")}catch(e){if(e instanceof Error)this.logger.error(`Failed to get the latest release: ${e.message}`);return}}installPackage(){this.logger.info("Installing...");try{let e=x(this.options.scripts.install);this.logger.info("Install stdout:",e.toString()),this.storage.setItem("setupPhase","installed"),this.logger.info("Installed!")}catch(e){if(e instanceof Error)this.logger.error(`Failed to get the latest release: ${e.message}`);return}}stopAllServices(){this.logger.info("Stopping all services... auto-respawn disabled."),this.autoRespawnDeadServices=!1;for(let[e]of f(this.services))this.stopService(e);return this.dead}stopService(e){let t=this.services[e];if(t){if(this.logger.info(`Stopping service "${e}"...`),this.servicesDead[this.serviceIdx[e]].use(new Promise((i)=>{t.emit("timeToStop"),t.process.once("close",(o)=>{this.logger.info(`Stopped service "${e}"; exited with code ${o}`),this.services[e]=null,i()})})),this.dead.use(Promise.all(this.servicesDead)),this.servicesLive[this.serviceIdx[e]]=new d(()=>{}),this.live.done)this.live=new d(()=>{});this.live.use(Promise.all(this.servicesLive))}else this.serviceLoggers[e].error("Tried to stop service, but it wasn't running.")}}var y="info",b="warn",w="ERR!",Ae=l.object({level:l.union([l.literal(y),l.literal(b),l.literal(w)]),timestamp:l.number(),package:l.string(),service:l.string().optional(),process:l.number(),body:l.string()}),Q="line-format",X="value",Ce={title:"FlightDeck Log",description:"Format for events logged by the FlightDeck process manager.","file-type":"json","timestamp-field":"timestamp","timestamp-divisor":1000,"module-field":"package","opid-field":"service","level-field":"level",level:{info:y,warning:b,error:w},[Q]:[{field:"level"},{prefix:" ",field:"__timestamp__","timestamp-format":"%Y-%m-%dT%H:%M:%S.%L%Z"},{prefix:" ",field:"process","min-width":5},{prefix:":",field:"package"},{prefix:":",field:"service","default-value":""},{prefix:": ",field:"body"}],[X]:{timestamp:{kind:"integer"},level:{kind:"string"},package:{kind:"string"},service:{kind:"string"},process:{kind:"integer"},body:{kind:"string"}}};class u{packageName;serviceName;jsonLogging;processCode;constructor(e,t,i,o){if(this.packageName=e,i)this.serviceName=i;this.processCode=t,this.jsonLogging=o?.jsonLogging??!1}log(e,...t){if(this.jsonLogging){let i=t.map((n)=>typeof n==="string"?n:J(n,!1,null,!0)).join(" ");if(i.includes(`
3
+ `))i=`
4
+ ${i.split(`
5
+ `).join(`
6
+ `)}`;let o={timestamp:Date.now(),level:e,process:this.processCode,package:this.packageName,body:i};if(this.serviceName)o.service=this.serviceName;process.stdout.write(JSON.stringify(o)+`
7
+ `)}else{let i=this.serviceName?`${this.packageName}:${this.serviceName}`:this.packageName;switch(e){case y:console.log(`${i}:`,...t);break;case b:console.warn(`${i}:`,...t);break;case w:console.error(`${i}:`,...t);break}}}info(...e){this.log(y,...e)}warn(...e){this.log(b,...e)}error(...e){this.log(w,...e)}}var g=new u("comline",process.pid,void 0,{jsonLogging:!0});Object.assign(console,{log:g.info.bind(g),info:g.info.bind(g),warn:g.warn.bind(g),error:g.error.bind(g)});var $={optionsSchema:r.object({port:r.number().optional(),packageName:r.string(),services:r.record(r.object({run:r.string(),waitFor:r.boolean()})),flightdeckRootDir:r.string(),scripts:r.object({download:r.string(),install:r.string(),checkAvailability:r.string()}),jsonLogging:r.boolean().optional()}),options:{port:{flag:"p",required:!1,description:"Port to run the flightdeck server on.",example:"--port=8080",parse:se},packageName:{flag:"n",required:!0,description:"Name of the package.",example:'--packageName="my-app"'},services:{flag:"s",required:!0,description:"Map of service names to executables.",example:'--services="{\\"frontend\\":{\\"run\\":\\"./frontend\\",\\"waitFor\\":false},\\"backend\\":{\\"run\\":\\"./backend\\",\\"waitFor\\":true}}"',parse:JSON.parse},flightdeckRootDir:{flag:"d",required:!0,description:"Directory where the service is stored.",example:'--flightdeckRootDir="./services/sample/repo/my-app/current"'},scripts:{flag:"r",required:!0,description:"Map of scripts to run.",example:'--scripts="{\\"download\\":\\"npm i",\\"install\\":\\"npm run build\\"}"',parse:JSON.parse},jsonLogging:{flag:"j",required:!1,description:"Enable json logging.",example:"--jsonLogging",parse:ie}}},oe={optionsSchema:r.object({outdir:r.string().optional()}),options:{outdir:{flag:"o",required:!1,description:"Directory to write the schema to.",example:"--outdir=./dist"}}},re=ee({cliName:"flightdeck",routes:te({schema:null,$configPath:null}),routeOptions:{"":$,$configPath:$,schema:oe},debugOutput:!0,discoverConfigPath:(e)=>{if(e[0]==="schema")return;return e[0]??O.join(process.cwd(),"flightdeck.config.json")}},console),{inputs:T,writeJsonSchema:ne}=re(process.argv);switch(T.case){case"schema":{let{outdir:e}=T.opts;ne(e??".")}break;default:{let e=new P(T.opts);process.on("close",async()=>{await e.stopAllServices()})}}
6
8
 
7
- //# debugId=A4E0587AA743E84E64756E2164756E21
8
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2ZsaWdodGRlY2suYmluLnRzIiwgIi4uL3NyYy9mbGlnaHRkZWNrLmxpYi50cyIsICIuLi9zcmMvZmlsZXN5c3RlbS1zdG9yYWdlLnRzIiwgIi4uL3NyYy9mbGlnaHRkZWNrLmVudi50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsKICAgICIjIS91c3IvYmluL2VudiBub2RlXG5cbmltcG9ydCAqIGFzIHBhdGggZnJvbSBcIm5vZGU6cGF0aFwiXG5cbmltcG9ydCB0eXBlIHsgT3B0aW9uc0dyb3VwIH0gZnJvbSBcImNvbWxpbmVcIlxuaW1wb3J0IHsgY2xpLCBvcHRpb25hbCwgcGFyc2VCb29sZWFuT3B0aW9uLCBwYXJzZU51bWJlck9wdGlvbiB9IGZyb20gXCJjb21saW5lXCJcbmltcG9ydCB7IHogfSBmcm9tIFwiem9kXCJcblxuaW1wb3J0IHR5cGUgeyBGbGlnaHREZWNrT3B0aW9ucyB9IGZyb20gXCIuL2ZsaWdodGRlY2subGliXCJcbmltcG9ydCB7IEZsaWdodERlY2ssIEZsaWdodERlY2tMb2dnZXIgfSBmcm9tIFwiLi9mbGlnaHRkZWNrLmxpYlwiXG5cbmNvbnN0IENMSV9MT0dHRVIgPSBuZXcgRmxpZ2h0RGVja0xvZ2dlcihgY29tbGluZWAsIHByb2Nlc3MucGlkLCB1bmRlZmluZWQsIHtcblx0anNvbkxvZ2dpbmc6IHRydWUsXG59KVxuT2JqZWN0LmFzc2lnbihjb25zb2xlLCB7XG5cdGxvZzogQ0xJX0xPR0dFUi5pbmZvLmJpbmQoQ0xJX0xPR0dFUiksXG5cdGluZm86IENMSV9MT0dHRVIuaW5mby5iaW5kKENMSV9MT0dHRVIpLFxuXHR3YXJuOiBDTElfTE9HR0VSLndhcm4uYmluZChDTElfTE9HR0VSKSxcblx0ZXJyb3I6IENMSV9MT0dHRVIuZXJyb3IuYmluZChDTElfTE9HR0VSKSxcbn0pXG5cbmNvbnN0IEZMSUdIVERFQ0tfTUFOVUFMID0ge1xuXHRvcHRpb25zU2NoZW1hOiB6Lm9iamVjdCh7XG5cdFx0cG9ydDogei5udW1iZXIoKS5vcHRpb25hbCgpLFxuXHRcdHBhY2thZ2VOYW1lOiB6LnN0cmluZygpLFxuXHRcdHNlcnZpY2VzOiB6LnJlY29yZCh6Lm9iamVjdCh7IHJ1bjogei5zdHJpbmcoKSwgd2FpdEZvcjogei5ib29sZWFuKCkgfSkpLFxuXHRcdGZsaWdodGRlY2tSb290RGlyOiB6LnN0cmluZygpLFxuXHRcdHNjcmlwdHM6IHoub2JqZWN0KHtcblx0XHRcdGRvd25sb2FkOiB6LnN0cmluZygpLFxuXHRcdFx0aW5zdGFsbDogei5zdHJpbmcoKSxcblx0XHRcdGNoZWNrQXZhaWxhYmlsaXR5OiB6LnN0cmluZygpLFxuXHRcdH0pLFxuXHRcdGpzb25Mb2dnaW5nOiB6LmJvb2xlYW4oKS5vcHRpb25hbCgpLFxuXHR9KSxcblx0b3B0aW9uczoge1xuXHRcdHBvcnQ6IHtcblx0XHRcdGZsYWc6IGBwYCxcblx0XHRcdHJlcXVpcmVkOiBmYWxzZSxcblx0XHRcdGRlc2NyaXB0aW9uOiBgUG9ydCB0byBydW4gdGhlIGZsaWdodGRlY2sgc2VydmVyIG9uLmAsXG5cdFx0XHRleGFtcGxlOiBgLS1wb3J0PTgwODBgLFxuXHRcdFx0cGFyc2U6IHBhcnNlTnVtYmVyT3B0aW9uLFxuXHRcdH0sXG5cdFx0cGFja2FnZU5hbWU6IHtcblx0XHRcdGZsYWc6IGBuYCxcblx0XHRcdHJlcXVpcmVkOiB0cnVlLFxuXHRcdFx0ZGVzY3JpcHRpb246IGBOYW1lIG9mIHRoZSBwYWNrYWdlLmAsXG5cdFx0XHRleGFtcGxlOiBgLS1wYWNrYWdlTmFtZT1cXFwibXktYXBwXFxcImAsXG5cdFx0fSxcblx0XHRzZXJ2aWNlczoge1xuXHRcdFx0ZmxhZzogYHNgLFxuXHRcdFx0cmVxdWlyZWQ6IHRydWUsXG5cdFx0XHRkZXNjcmlwdGlvbjogYE1hcCBvZiBzZXJ2aWNlIG5hbWVzIHRvIGV4ZWN1dGFibGVzLmAsXG5cdFx0XHRleGFtcGxlOiBgLS1zZXJ2aWNlcz1cIntcXFxcXCJmcm9udGVuZFxcXFxcIjp7XFxcXFwicnVuXFxcXFwiOlxcXFxcIi4vZnJvbnRlbmRcXFxcXCIsXFxcXFwid2FpdEZvclxcXFxcIjpmYWxzZX0sXFxcXFwiYmFja2VuZFxcXFxcIjp7XFxcXFwicnVuXFxcXFwiOlxcXFxcIi4vYmFja2VuZFxcXFxcIixcXFxcXCJ3YWl0Rm9yXFxcXFwiOnRydWV9fVwiYCxcblx0XHRcdHBhcnNlOiBKU09OLnBhcnNlLFxuXHRcdH0sXG5cdFx0ZmxpZ2h0ZGVja1Jvb3REaXI6IHtcblx0XHRcdGZsYWc6IGBkYCxcblx0XHRcdHJlcXVpcmVkOiB0cnVlLFxuXHRcdFx0ZGVzY3JpcHRpb246IGBEaXJlY3Rvcnkgd2hlcmUgdGhlIHNlcnZpY2UgaXMgc3RvcmVkLmAsXG5cdFx0XHRleGFtcGxlOiBgLS1mbGlnaHRkZWNrUm9vdERpcj1cXFwiLi9zZXJ2aWNlcy9zYW1wbGUvcmVwby9teS1hcHAvY3VycmVudFxcXCJgLFxuXHRcdH0sXG5cdFx0c2NyaXB0czoge1xuXHRcdFx0ZmxhZzogYHJgLFxuXHRcdFx0cmVxdWlyZWQ6IHRydWUsXG5cdFx0XHRkZXNjcmlwdGlvbjogYE1hcCBvZiBzY3JpcHRzIHRvIHJ1bi5gLFxuXHRcdFx0ZXhhbXBsZTogYC0tc2NyaXB0cz1cIntcXFxcXCJkb3dubG9hZFxcXFxcIjpcXFxcXCJucG0gaVwiLFxcXFxcImluc3RhbGxcXFxcXCI6XFxcXFwibnBtIHJ1biBidWlsZFxcXFxcIn1cImAsXG5cdFx0XHRwYXJzZTogSlNPTi5wYXJzZSxcblx0XHR9LFxuXHRcdGpzb25Mb2dnaW5nOiB7XG5cdFx0XHRmbGFnOiBgamAsXG5cdFx0XHRyZXF1aXJlZDogZmFsc2UsXG5cdFx0XHRkZXNjcmlwdGlvbjogYEVuYWJsZSBqc29uIGxvZ2dpbmcuYCxcblx0XHRcdGV4YW1wbGU6IGAtLWpzb25Mb2dnaW5nYCxcblx0XHRcdHBhcnNlOiBwYXJzZUJvb2xlYW5PcHRpb24sXG5cdFx0fSxcblx0fSxcbn0gc2F0aXNmaWVzIE9wdGlvbnNHcm91cDxGbGlnaHREZWNrT3B0aW9ucz5cblxuY29uc3QgU0NIRU1BX01BTlVBTCA9IHtcblx0b3B0aW9uc1NjaGVtYTogei5vYmplY3Qoe1xuXHRcdG91dGRpcjogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuXHR9KSxcblx0b3B0aW9uczoge1xuXHRcdG91dGRpcjoge1xuXHRcdFx0ZmxhZzogYG9gLFxuXHRcdFx0cmVxdWlyZWQ6IGZhbHNlLFxuXHRcdFx0ZGVzY3JpcHRpb246IGBEaXJlY3RvcnkgdG8gd3JpdGUgdGhlIHNjaGVtYSB0by5gLFxuXHRcdFx0ZXhhbXBsZTogYC0tb3V0ZGlyPS4vZGlzdGAsXG5cdFx0fSxcblx0fSxcbn0gc2F0aXNmaWVzIE9wdGlvbnNHcm91cDx7IG91dGRpcj86IHN0cmluZyB8IHVuZGVmaW5lZCB9PlxuXG5jb25zdCBwYXJzZSA9IGNsaShcblx0e1xuXHRcdGNsaU5hbWU6IGBmbGlnaHRkZWNrYCxcblx0XHRyb3V0ZXM6IG9wdGlvbmFsKHsgc2NoZW1hOiBudWxsLCAkY29uZmlnUGF0aDogbnVsbCB9KSxcblx0XHRyb3V0ZU9wdGlvbnM6IHtcblx0XHRcdFwiXCI6IEZMSUdIVERFQ0tfTUFOVUFMLFxuXHRcdFx0JGNvbmZpZ1BhdGg6IEZMSUdIVERFQ0tfTUFOVUFMLFxuXHRcdFx0c2NoZW1hOiBTQ0hFTUFfTUFOVUFMLFxuXHRcdH0sXG5cdFx0ZGVidWdPdXRwdXQ6IHRydWUsXG5cdFx0ZGlzY292ZXJDb25maWdQYXRoOiAoYXJncykgPT4ge1xuXHRcdFx0aWYgKGFyZ3NbMF0gPT09IGBzY2hlbWFgKSB7XG5cdFx0XHRcdHJldHVyblxuXHRcdFx0fVxuXHRcdFx0Y29uc3QgY29uZmlnUGF0aCA9XG5cdFx0XHRcdGFyZ3NbMF0gPz8gcGF0aC5qb2luKHByb2Nlc3MuY3dkKCksIGBmbGlnaHRkZWNrLmNvbmZpZy5qc29uYClcblx0XHRcdHJldHVybiBjb25maWdQYXRoXG5cdFx0fSxcblx0fSxcblx0Y29uc29sZSxcbilcblxuY29uc3QgeyBpbnB1dHMsIHdyaXRlSnNvblNjaGVtYSB9ID0gcGFyc2UocHJvY2Vzcy5hcmd2KVxuXG5zd2l0Y2ggKGlucHV0cy5jYXNlKSB7XG5cdGNhc2UgYHNjaGVtYWA6XG5cdFx0e1xuXHRcdFx0Y29uc3QgeyBvdXRkaXIgfSA9IGlucHV0cy5vcHRzXG5cdFx0XHR3cml0ZUpzb25TY2hlbWEob3V0ZGlyID8/IGAuYClcblx0XHR9XG5cdFx0YnJlYWtcblx0ZGVmYXVsdDoge1xuXHRcdGNvbnN0IGZsaWdodERlY2sgPSBuZXcgRmxpZ2h0RGVjayhpbnB1dHMub3B0cylcblx0XHRwcm9jZXNzLm9uKGBjbG9zZWAsIGFzeW5jICgpID0+IHtcblx0XHRcdGF3YWl0IGZsaWdodERlY2suc3RvcEFsbFNlcnZpY2VzKClcblx0XHR9KVxuXHR9XG59XG4iLAogICAgImltcG9ydCB7IGV4ZWNTeW5jLCBzcGF3biB9IGZyb20gXCJub2RlOmNoaWxkX3Byb2Nlc3NcIlxuaW1wb3J0IHR5cGUgeyBTZXJ2ZXIgfSBmcm9tIFwibm9kZTpodHRwXCJcbmltcG9ydCB7IGNyZWF0ZVNlcnZlciB9IGZyb20gXCJub2RlOmh0dHBcIlxuaW1wb3J0IHsgaG9tZWRpciB9IGZyb20gXCJub2RlOm9zXCJcbmltcG9ydCB7IHJlc29sdmUgfSBmcm9tIFwibm9kZTpwYXRoXCJcbmltcG9ydCB7IGluc3BlY3QgfSBmcm9tIFwibm9kZTp1dGlsXCJcblxuaW1wb3J0IHsgRnV0dXJlIH0gZnJvbSBcImF0b20uaW8vaW50ZXJuYWxcIlxuaW1wb3J0IHsgZGlzY292ZXJUeXBlIH0gZnJvbSBcImF0b20uaW8vaW50cm9zcGVjdGlvblwiXG5pbXBvcnQgeyBmcm9tRW50cmllcywgdG9FbnRyaWVzIH0gZnJvbSBcImF0b20uaW8vanNvblwiXG5pbXBvcnQgeyBDaGlsZFNvY2tldCB9IGZyb20gXCJhdG9tLmlvL3JlYWx0aW1lLXNlcnZlclwiXG5pbXBvcnQgeyBDcm9uSm9iIH0gZnJvbSBcImNyb25cIlxuaW1wb3J0IHsgeiB9IGZyb20gXCJ6b2RcIlxuXG5pbXBvcnQgdHlwZSB7IExuYXZGb3JtYXQgfSBmcm9tIFwiLi4vZ2VuL2xuYXYtZm9ybWF0LXNjaGVtYS5nZW5cIlxuaW1wb3J0IHsgRmlsZXN5c3RlbVN0b3JhZ2UgfSBmcm9tIFwiLi9maWxlc3lzdGVtLXN0b3JhZ2VcIlxuaW1wb3J0IHsgZW52IH0gZnJvbSBcIi4vZmxpZ2h0ZGVjay5lbnZcIlxuXG5leHBvcnQgY29uc3QgRkxJR0hUREVDS19TRVRVUF9QSEFTRVMgPSBbYGRvd25sb2FkZWRgLCBgaW5zdGFsbGVkYF0gYXMgY29uc3RcblxuZXhwb3J0IHR5cGUgRmxpZ2h0RGVja1NldHVwUGhhc2UgPSAodHlwZW9mIEZMSUdIVERFQ0tfU0VUVVBfUEhBU0VTKVtudW1iZXJdXG5cbmV4cG9ydCBjb25zdCBGTElHSFRERUNLX1VQREFURV9QSEFTRVMgPSBbYG5vdGlmaWVkYCwgYGNvbmZpcm1lZGBdIGFzIGNvbnN0XG5cbmV4cG9ydCB0eXBlIEZsaWdodERlY2tVcGRhdGVQaGFzZSA9ICh0eXBlb2YgRkxJR0hUREVDS19VUERBVEVfUEhBU0VTKVtudW1iZXJdXG5cbmV4cG9ydCBmdW5jdGlvbiBpc1ZlcnNpb25OdW1iZXIodmVyc2lvbjogc3RyaW5nKTogYm9vbGVhbiB7XG5cdHJldHVybiAoXG5cdFx0L15cXGQrXFwuXFxkK1xcLlxcZCskLy50ZXN0KHZlcnNpb24pIHx8ICFOdW1iZXIuaXNOYU4oTnVtYmVyLnBhcnNlRmxvYXQodmVyc2lvbikpXG5cdClcbn1cblxuZXhwb3J0IHR5cGUgRmxpZ2h0RGVja09wdGlvbnM8UyBleHRlbmRzIHN0cmluZyA9IHN0cmluZz4gPSB7XG5cdHBhY2thZ2VOYW1lOiBzdHJpbmdcblx0c2VydmljZXM6IHsgW3NlcnZpY2UgaW4gU106IHsgcnVuOiBzdHJpbmc7IHdhaXRGb3I6IGJvb2xlYW4gfSB9XG5cdHNjcmlwdHM6IHtcblx0XHRkb3dubG9hZDogc3RyaW5nXG5cdFx0aW5zdGFsbDogc3RyaW5nXG5cdFx0Y2hlY2tBdmFpbGFiaWxpdHk/OiBzdHJpbmdcblx0fVxuXHRwb3J0PzogbnVtYmVyIHwgdW5kZWZpbmVkXG5cdGZsaWdodGRlY2tSb290RGlyPzogc3RyaW5nIHwgdW5kZWZpbmVkXG5cdGpzb25Mb2dnaW5nPzogYm9vbGVhbiB8IHVuZGVmaW5lZFxufVxuXG5leHBvcnQgY2xhc3MgRmxpZ2h0RGVjazxTIGV4dGVuZHMgc3RyaW5nID0gc3RyaW5nPiB7XG5cdHByb3RlY3RlZCBzYWZldHkgPSAwXG5cblx0cHJvdGVjdGVkIHN0b3JhZ2U6IEZpbGVzeXN0ZW1TdG9yYWdlPHtcblx0XHRzZXR1cFBoYXNlOiBGbGlnaHREZWNrU2V0dXBQaGFzZVxuXHRcdHVwZGF0ZVBoYXNlOiBGbGlnaHREZWNrVXBkYXRlUGhhc2Vcblx0XHR1cGRhdGVBd2FpdGVkVmVyc2lvbjogc3RyaW5nXG5cdH0+XG5cdHByb3RlY3RlZCB3ZWJob29rU2VydmVyOiBTZXJ2ZXJcblx0cHJvdGVjdGVkIHNlcnZpY2VzOiB7XG5cdFx0W3NlcnZpY2UgaW4gU106IENoaWxkU29ja2V0PFxuXHRcdFx0eyB0aW1lVG9TdG9wOiBbXTsgdXBkYXRlc1JlYWR5OiBbXSB9LFxuXHRcdFx0eyByZWFkeVRvVXBkYXRlOiBbXTsgYWxpdmU6IFtdIH1cblx0XHQ+IHwgbnVsbFxuXHR9XG5cdHByb3RlY3RlZCBzZXJ2aWNlSWR4OiB7IHJlYWRvbmx5IFtzZXJ2aWNlIGluIFNdOiBudW1iZXIgfVxuXHRwdWJsaWMgZGVmYXVsdFNlcnZpY2VzUmVhZHlUb1VwZGF0ZTogeyByZWFkb25seSBbc2VydmljZSBpbiBTXTogYm9vbGVhbiB9XG5cdHB1YmxpYyBzZXJ2aWNlc1JlYWR5VG9VcGRhdGU6IHsgW3NlcnZpY2UgaW4gU106IGJvb2xlYW4gfVxuXHRwdWJsaWMgYXV0b1Jlc3Bhd25EZWFkU2VydmljZXM6IGJvb2xlYW5cblxuXHRwcm90ZWN0ZWQgbG9nZ2VyOiBQaWNrPENvbnNvbGUsIGBlcnJvcmAgfCBgaW5mb2AgfCBgd2FybmA+XG5cdHByb3RlY3RlZCBzZXJ2aWNlTG9nZ2Vyczoge1xuXHRcdHJlYWRvbmx5IFtzZXJ2aWNlIGluIFNdOiBGbGlnaHREZWNrTG9nZ2VyXG5cdH1cblxuXHRwcm90ZWN0ZWQgdXBkYXRlQXZhaWxhYmlsaXR5Q2hlY2tlcjogQ3JvbkpvYiB8IG51bGwgPSBudWxsXG5cblx0cHVibGljIHNlcnZpY2VzTGl2ZTogRnV0dXJlPHZvaWQ+W11cblx0cHVibGljIHNlcnZpY2VzRGVhZDogRnV0dXJlPHZvaWQ+W11cblx0cHVibGljIGxpdmUgPSBuZXcgRnV0dXJlKCgpID0+IHt9KVxuXHRwdWJsaWMgZGVhZCA9IG5ldyBGdXR1cmUoKCkgPT4ge30pXG5cblx0cHJvdGVjdGVkIHJlc3RhcnRUaW1lczogbnVtYmVyW10gPSBbXVxuXG5cdHB1YmxpYyBjb25zdHJ1Y3RvcihwdWJsaWMgcmVhZG9ubHkgb3B0aW9uczogRmxpZ2h0RGVja09wdGlvbnM8Uz4pIHtcblx0XHRjb25zdCB7IEZMSUdIVERFQ0tfU0VDUkVUIH0gPSBlbnZcblx0XHRjb25zdCB7IGZsaWdodGRlY2tSb290RGlyID0gcmVzb2x2ZShob21lZGlyKCksIGAuZmxpZ2h0ZGVja2ApIH0gPSBvcHRpb25zXG5cdFx0Y29uc3QgcG9ydCA9IG9wdGlvbnMucG9ydCA/PyA4MDgwXG5cdFx0Y29uc3Qgb3JpZ2luID0gYGh0dHA6Ly9sb2NhbGhvc3Q6JHtwb3J0fWBcblxuXHRcdGNvbnN0IHNlcnZpY2VzRW50cmllcyA9IHRvRW50cmllcyhvcHRpb25zLnNlcnZpY2VzKVxuXHRcdHRoaXMuc2VydmljZXMgPSBmcm9tRW50cmllcyhcblx0XHRcdHNlcnZpY2VzRW50cmllcy5tYXAoKFtzZXJ2aWNlTmFtZV0pID0+IFtzZXJ2aWNlTmFtZSwgbnVsbF0pLFxuXHRcdClcblx0XHR0aGlzLnNlcnZpY2VJZHggPSBmcm9tRW50cmllcyhcblx0XHRcdHNlcnZpY2VzRW50cmllcy5tYXAoKFtzZXJ2aWNlTmFtZV0sIGlkeCkgPT4gW3NlcnZpY2VOYW1lLCBpZHhdKSxcblx0XHQpXG5cdFx0dGhpcy5kZWZhdWx0U2VydmljZXNSZWFkeVRvVXBkYXRlID0gZnJvbUVudHJpZXMoXG5cdFx0XHRzZXJ2aWNlc0VudHJpZXMubWFwKChbc2VydmljZU5hbWUsIHsgd2FpdEZvciB9XSkgPT4gW1xuXHRcdFx0XHRzZXJ2aWNlTmFtZSxcblx0XHRcdFx0IXdhaXRGb3IsXG5cdFx0XHRdKSxcblx0XHQpXG5cdFx0dGhpcy5zZXJ2aWNlc1JlYWR5VG9VcGRhdGUgPSB7IC4uLnRoaXMuZGVmYXVsdFNlcnZpY2VzUmVhZHlUb1VwZGF0ZSB9XG5cdFx0dGhpcy5hdXRvUmVzcGF3bkRlYWRTZXJ2aWNlcyA9IHRydWVcblxuXHRcdHRoaXMubG9nZ2VyID0gbmV3IEZsaWdodERlY2tMb2dnZXIoXG5cdFx0XHR0aGlzLm9wdGlvbnMucGFja2FnZU5hbWUsXG5cdFx0XHRwcm9jZXNzLnBpZCxcblx0XHRcdHVuZGVmaW5lZCxcblx0XHRcdHsganNvbkxvZ2dpbmc6IHRoaXMub3B0aW9ucy5qc29uTG9nZ2luZyA/PyBmYWxzZSB9LFxuXHRcdClcblx0XHR0aGlzLnNlcnZpY2VMb2dnZXJzID0gZnJvbUVudHJpZXMoXG5cdFx0XHRzZXJ2aWNlc0VudHJpZXMubWFwKChbc2VydmljZU5hbWVdKSA9PiBbXG5cdFx0XHRcdHNlcnZpY2VOYW1lLFxuXHRcdFx0XHRuZXcgRmxpZ2h0RGVja0xvZ2dlcihcblx0XHRcdFx0XHR0aGlzLm9wdGlvbnMucGFja2FnZU5hbWUsXG5cdFx0XHRcdFx0cHJvY2Vzcy5waWQsXG5cdFx0XHRcdFx0c2VydmljZU5hbWUsXG5cdFx0XHRcdFx0eyBqc29uTG9nZ2luZzogdGhpcy5vcHRpb25zLmpzb25Mb2dnaW5nID8/IGZhbHNlIH0sXG5cdFx0XHRcdCksXG5cdFx0XHRdKSxcblx0XHQpXG5cblx0XHR0aGlzLnNlcnZpY2VzTGl2ZSA9IHNlcnZpY2VzRW50cmllcy5tYXAoKCkgPT4gbmV3IEZ1dHVyZSgoKSA9PiB7fSkpXG5cdFx0dGhpcy5zZXJ2aWNlc0RlYWQgPSBzZXJ2aWNlc0VudHJpZXMubWFwKCgpID0+IG5ldyBGdXR1cmUoKCkgPT4ge30pKVxuXHRcdHRoaXMubGl2ZS51c2UoUHJvbWlzZS5hbGwodGhpcy5zZXJ2aWNlc0xpdmUpKVxuXHRcdHRoaXMuZGVhZC51c2UoUHJvbWlzZS5hbGwodGhpcy5zZXJ2aWNlc0RlYWQpKVxuXG5cdFx0dGhpcy5zdG9yYWdlID0gbmV3IEZpbGVzeXN0ZW1TdG9yYWdlKHtcblx0XHRcdHBhdGg6IHJlc29sdmUoZmxpZ2h0ZGVja1Jvb3REaXIsIGBzdG9yYWdlYCwgb3B0aW9ucy5wYWNrYWdlTmFtZSksXG5cdFx0fSlcblxuXHRcdGlmIChGTElHSFRERUNLX1NFQ1JFVCA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHR0aGlzLmxvZ2dlci53YXJuKFxuXHRcdFx0XHRgTm8gRkxJR0hUREVDS19TRUNSRVQgZW52aXJvbm1lbnQgdmFyaWFibGUgZm91bmQuIEZsaWdodERlY2sgd2lsbCBub3QgcnVuIGFuIHVwZGF0ZSBzZXJ2ZXIuYCxcblx0XHRcdClcblx0XHR9IGVsc2Uge1xuXHRcdFx0Y3JlYXRlU2VydmVyKChyZXEsIHJlcykgPT4ge1xuXHRcdFx0XHRsZXQgZGF0YTogVWludDhBcnJheVtdID0gW11cblx0XHRcdFx0cmVxXG5cdFx0XHRcdFx0Lm9uKGBkYXRhYCwgKGNodW5rKSA9PiB7XG5cdFx0XHRcdFx0XHRkYXRhLnB1c2goY2h1bmsgaW5zdGFuY2VvZiBCdWZmZXIgPyBjaHVuayA6IEJ1ZmZlci5mcm9tKGNodW5rKSlcblx0XHRcdFx0XHR9KVxuXHRcdFx0XHRcdC5vbihgZW5kYCwgKCkgPT4ge1xuXHRcdFx0XHRcdFx0Y29uc3QgYXV0aEhlYWRlciA9IHJlcS5oZWFkZXJzLmF1dGhvcml6YXRpb25cblx0XHRcdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0XHRcdGlmICh0eXBlb2YgcmVxLnVybCA9PT0gYHVuZGVmaW5lZGApIHRocm93IDQwMFxuXHRcdFx0XHRcdFx0XHRjb25zdCBleHBlY3RlZEF1dGhIZWFkZXIgPSBgQmVhcmVyICR7RkxJR0hUREVDS19TRUNSRVR9YFxuXHRcdFx0XHRcdFx0XHRpZiAoYXV0aEhlYWRlciAhPT0gYEJlYXJlciAke0ZMSUdIVERFQ0tfU0VDUkVUfWApIHtcblx0XHRcdFx0XHRcdFx0XHR0aGlzLmxvZ2dlci5pbmZvKFxuXHRcdFx0XHRcdFx0XHRcdFx0YFVuYXV0aG9yaXplZDogbmVlZGVkIFxcYCR7ZXhwZWN0ZWRBdXRoSGVhZGVyfVxcYCwgZ290IFxcYCR7YXV0aEhlYWRlcn1cXGBgLFxuXHRcdFx0XHRcdFx0XHRcdClcblx0XHRcdFx0XHRcdFx0XHR0aHJvdyA0MDFcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRjb25zdCB1cmwgPSBuZXcgVVJMKHJlcS51cmwsIG9yaWdpbilcblx0XHRcdFx0XHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhyZXEubWV0aG9kLCB1cmwucGF0aG5hbWUpXG5cblx0XHRcdFx0XHRcdFx0Y29uc3QgdmVyc2lvbkZvcmVpZ25JbnB1dCA9IEJ1ZmZlci5jb25jYXQoZGF0YSkudG9TdHJpbmcoKVxuXHRcdFx0XHRcdFx0XHRpZiAoIWlzVmVyc2lvbk51bWJlcih2ZXJzaW9uRm9yZWlnbklucHV0KSkge1xuXHRcdFx0XHRcdFx0XHRcdHRocm93IDQwMFxuXHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0cmVzLndyaXRlSGVhZCgyMDApXG5cdFx0XHRcdFx0XHRcdHJlcy5lbmQoKVxuXG5cdFx0XHRcdFx0XHRcdHRoaXMuc3RvcmFnZS5zZXRJdGVtKGB1cGRhdGVQaGFzZWAsIGBub3RpZmllZGApXG5cdFx0XHRcdFx0XHRcdHRoaXMuc3RvcmFnZS5zZXRJdGVtKGB1cGRhdGVBd2FpdGVkVmVyc2lvbmAsIHZlcnNpb25Gb3JlaWduSW5wdXQpXG5cdFx0XHRcdFx0XHRcdGNvbnN0IHsgY2hlY2tBdmFpbGFiaWxpdHkgfSA9IG9wdGlvbnMuc2NyaXB0c1xuXHRcdFx0XHRcdFx0XHRpZiAoY2hlY2tBdmFpbGFiaWxpdHkpIHtcblx0XHRcdFx0XHRcdFx0XHR0aGlzLnVwZGF0ZUF2YWlsYWJpbGl0eUNoZWNrZXI/LnN0b3AoKVxuXHRcdFx0XHRcdFx0XHRcdHRoaXMuc2Vla1VwZGF0ZSh2ZXJzaW9uRm9yZWlnbklucHV0KVxuXHRcdFx0XHRcdFx0XHRcdGNvbnN0IHVwZGF0ZVBoYXNlID0gdGhpcy5zdG9yYWdlLmdldEl0ZW0oYHVwZGF0ZVBoYXNlYClcblx0XHRcdFx0XHRcdFx0XHR0aGlzLmxvZ2dlci5pbmZvKGA+IHN0b3JhZ2UoXCJ1cGRhdGVQaGFzZVwiKSA+YCwgdXBkYXRlUGhhc2UpXG5cdFx0XHRcdFx0XHRcdFx0aWYgKHVwZGF0ZVBoYXNlID09PSBgbm90aWZpZWRgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHR0aGlzLnVwZGF0ZUF2YWlsYWJpbGl0eUNoZWNrZXIgPSBuZXcgQ3JvbkpvYihcblx0XHRcdFx0XHRcdFx0XHRcdFx0YDMwICogKiAqICogKmAsXG5cdFx0XHRcdFx0XHRcdFx0XHRcdCgpID0+IHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHR0aGlzLnNlZWtVcGRhdGUodmVyc2lvbkZvcmVpZ25JbnB1dClcblx0XHRcdFx0XHRcdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRcdFx0XHRcdClcblx0XHRcdFx0XHRcdFx0XHRcdHRoaXMudXBkYXRlQXZhaWxhYmlsaXR5Q2hlY2tlci5zdGFydCgpXG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRcdHRoaXMuZG93bmxvYWRQYWNrYWdlKClcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fSBjYXRjaCAodGhyb3duKSB7XG5cdFx0XHRcdFx0XHRcdHRoaXMubG9nZ2VyLmVycm9yKHRocm93biwgcmVxLnVybClcblx0XHRcdFx0XHRcdFx0aWYgKHR5cGVvZiB0aHJvd24gPT09IGBudW1iZXJgKSB7XG5cdFx0XHRcdFx0XHRcdFx0cmVzLndyaXRlSGVhZCh0aHJvd24pXG5cdFx0XHRcdFx0XHRcdFx0cmVzLmVuZCgpXG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH0gZmluYWxseSB7XG5cdFx0XHRcdFx0XHRcdGRhdGEgPSBbXVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0pXG5cdFx0XHR9KS5saXN0ZW4ocG9ydCwgKCkgPT4ge1xuXHRcdFx0XHR0aGlzLmxvZ2dlci5pbmZvKGBTZXJ2ZXIgc3RhcnRlZCBvbiBwb3J0ICR7cG9ydH1gKVxuXHRcdFx0fSlcblx0XHR9XG5cblx0XHR0aGlzLnN0YXJ0QWxsU2VydmljZXMoKVxuXHRcdFx0LnRoZW4oKCkgPT4ge1xuXHRcdFx0XHR0aGlzLmxvZ2dlci5pbmZvKGBBbGwgc2VydmljZXMgc3RhcnRlZC5gKVxuXHRcdFx0fSlcblx0XHRcdC5jYXRjaCgodGhyb3duKSA9PiB7XG5cdFx0XHRcdGlmICh0aHJvd24gaW5zdGFuY2VvZiBFcnJvcikge1xuXHRcdFx0XHRcdHRoaXMubG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gc3RhcnQgYWxsIHNlcnZpY2VzOmAsIHRocm93bi5tZXNzYWdlKVxuXHRcdFx0XHR9XG5cdFx0XHR9KVxuXHR9XG5cblx0cHJvdGVjdGVkIHNlZWtVcGRhdGUodmVyc2lvbjogc3RyaW5nKTogdm9pZCB7XG5cdFx0dGhpcy5sb2dnZXIuaW5mbyhgQ2hlY2tpbmcgZm9yIHVwZGF0ZXMuLi5gKVxuXHRcdGNvbnN0IHsgY2hlY2tBdmFpbGFiaWxpdHkgfSA9IHRoaXMub3B0aW9ucy5zY3JpcHRzXG5cdFx0aWYgKCFjaGVja0F2YWlsYWJpbGl0eSkge1xuXHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhgTm8gY2hlY2tBdmFpbGFiaWxpdHkgc2NyaXB0IGZvdW5kLmApXG5cdFx0XHRyZXR1cm5cblx0XHR9XG5cdFx0dHJ5IHtcblx0XHRcdGNvbnN0IG91dCA9IGV4ZWNTeW5jKGAke2NoZWNrQXZhaWxhYmlsaXR5fSAke3ZlcnNpb259YClcblx0XHRcdHRoaXMubG9nZ2VyLmluZm8oYENoZWNrIHN0ZG91dDpgLCBvdXQudG9TdHJpbmcoKSlcblx0XHRcdHRoaXMudXBkYXRlQXZhaWxhYmlsaXR5Q2hlY2tlcj8uc3RvcCgpXG5cdFx0XHR0aGlzLnN0b3JhZ2Uuc2V0SXRlbShgdXBkYXRlUGhhc2VgLCBgY29uZmlybWVkYClcblx0XHRcdHRoaXMuZG93bmxvYWRQYWNrYWdlKClcblx0XHRcdHRoaXMuYW5ub3VuY2VVcGRhdGUoKVxuXHRcdH0gY2F0Y2ggKHRocm93bikge1xuXHRcdFx0aWYgKHRocm93biBpbnN0YW5jZW9mIEVycm9yKSB7XG5cdFx0XHRcdHRoaXMubG9nZ2VyLmVycm9yKGBDaGVjayBmYWlsZWQ6YCwgdGhyb3duLm1lc3NhZ2UpXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRjb25zdCB0aHJvd25UeXBlID0gZGlzY292ZXJUeXBlKHRocm93bilcblx0XHRcdFx0dGhpcy5sb2dnZXIuZXJyb3IoYENoZWNrIHRocmV3YCwgdGhyb3duVHlwZSwgdGhyb3duKVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHByb3RlY3RlZCBhbm5vdW5jZVVwZGF0ZSgpOiB2b2lkIHtcblx0XHRmb3IgKGNvbnN0IGVudHJ5IG9mIHRvRW50cmllcyh0aGlzLnNlcnZpY2VzKSkge1xuXHRcdFx0Y29uc3QgW3NlcnZpY2VOYW1lLCBzZXJ2aWNlXSA9IGVudHJ5XG5cdFx0XHRpZiAoc2VydmljZSkge1xuXHRcdFx0XHRpZiAodGhpcy5vcHRpb25zLnNlcnZpY2VzW3NlcnZpY2VOYW1lXS53YWl0Rm9yKSB7XG5cdFx0XHRcdFx0c2VydmljZS5lbWl0KGB1cGRhdGVzUmVhZHlgKVxuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0aGlzLnN0YXJ0U2VydmljZShzZXJ2aWNlTmFtZSlcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRwcm90ZWN0ZWQgdHJ5VXBkYXRlKCk6IHZvaWQge1xuXHRcdGlmICh0b0VudHJpZXModGhpcy5zZXJ2aWNlc1JlYWR5VG9VcGRhdGUpLmV2ZXJ5KChbLCBpc1JlYWR5XSkgPT4gaXNSZWFkeSkpIHtcblx0XHRcdHRoaXMubG9nZ2VyLmluZm8oYEFsbCBzZXJ2aWNlcyBhcmUgcmVhZHkgdG8gdXBkYXRlLmApXG5cdFx0XHR0aGlzLnN0b3BBbGxTZXJ2aWNlcygpXG5cdFx0XHRcdC50aGVuKCgpID0+IHtcblx0XHRcdFx0XHR0aGlzLmxvZ2dlci5pbmZvKGBBbGwgc2VydmljZXMgc3RvcHBlZDsgc3RhcnRpbmcgdXAgZnJlc2guLi5gKVxuXHRcdFx0XHRcdHRoaXMuc3RhcnRBbGxTZXJ2aWNlcygpXG5cdFx0XHRcdFx0XHQudGhlbigoKSA9PiB7XG5cdFx0XHRcdFx0XHRcdHRoaXMubG9nZ2VyLmluZm8oYEFsbCBzZXJ2aWNlcyBzdGFydGVkOyB3ZSdyZSBiYWNrIG9ubGluZS5gKVxuXHRcdFx0XHRcdFx0fSlcblx0XHRcdFx0XHRcdC5jYXRjaCgodGhyb3duKSA9PiB7XG5cdFx0XHRcdFx0XHRcdGlmICh0aHJvd24gaW5zdGFuY2VvZiBFcnJvcikge1xuXHRcdFx0XHRcdFx0XHRcdHRoaXMubG9nZ2VyLmVycm9yKFxuXHRcdFx0XHRcdFx0XHRcdFx0YEZhaWxlZCB0byBzdGFydCBhbGwgc2VydmljZXM6YCxcblx0XHRcdFx0XHRcdFx0XHRcdHRocm93bi5tZXNzYWdlLFxuXHRcdFx0XHRcdFx0XHRcdClcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fSlcblx0XHRcdFx0fSlcblx0XHRcdFx0LmNhdGNoKCh0aHJvd24pID0+IHtcblx0XHRcdFx0XHRpZiAodGhyb3duIGluc3RhbmNlb2YgRXJyb3IpIHtcblx0XHRcdFx0XHRcdHRoaXMubG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gc3RvcCBhbGwgc2VydmljZXM6YCwgdGhyb3duLm1lc3NhZ2UpXG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KVxuXHRcdH1cblx0fVxuXG5cdHByb3RlY3RlZCBzdGFydEFsbFNlcnZpY2VzKCk6IEZ1dHVyZTx1bmtub3duPiB7XG5cdFx0dGhpcy5sb2dnZXIuaW5mbyhgU3RhcnRpbmcgYWxsIHNlcnZpY2VzLi4uYClcblx0XHR0aGlzLmF1dG9SZXNwYXduRGVhZFNlcnZpY2VzID0gdHJ1ZVxuXHRcdGNvbnN0IHNldHVwUGhhc2UgPSB0aGlzLnN0b3JhZ2UuZ2V0SXRlbShgc2V0dXBQaGFzZWApXG5cdFx0dGhpcy5sb2dnZXIuaW5mbyhgPiBzdG9yYWdlKFwic2V0dXBQaGFzZVwiKSA+YCwgc2V0dXBQaGFzZSlcblx0XHRzd2l0Y2ggKHNldHVwUGhhc2UpIHtcblx0XHRcdGNhc2UgbnVsbDpcblx0XHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhgU3RhcnRpbmcgZnJvbSBzY3JhdGNoLmApXG5cdFx0XHRcdHRoaXMuZG93bmxvYWRQYWNrYWdlKClcblx0XHRcdFx0dGhpcy5pbnN0YWxsUGFja2FnZSgpXG5cdFx0XHRcdHJldHVybiB0aGlzLnN0YXJ0QWxsU2VydmljZXMoKVxuXHRcdFx0Y2FzZSBgZG93bmxvYWRlZGA6XG5cdFx0XHRcdHRoaXMubG9nZ2VyLmluZm8oYEZvdW5kIHBhY2thZ2UgZG93bmxvYWRlZCBidXQgbm90IGluc3RhbGxlZC5gKVxuXHRcdFx0XHR0aGlzLmluc3RhbGxQYWNrYWdlKClcblx0XHRcdFx0cmV0dXJuIHRoaXMuc3RhcnRBbGxTZXJ2aWNlcygpXG5cdFx0XHRjYXNlIGBpbnN0YWxsZWRgOiB7XG5cdFx0XHRcdGZvciAoY29uc3QgW3NlcnZpY2VOYW1lXSBvZiB0b0VudHJpZXModGhpcy5zZXJ2aWNlcykpIHtcblx0XHRcdFx0XHR0aGlzLnN0YXJ0U2VydmljZShzZXJ2aWNlTmFtZSlcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gdGhpcy5saXZlXG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0cHJvdGVjdGVkIHN0YXJ0U2VydmljZShzZXJ2aWNlTmFtZTogUyk6IHZvaWQge1xuXHRcdHRoaXMubG9nZ2VyLmluZm8oXG5cdFx0XHRgU3RhcnRpbmcgc2VydmljZSAke3RoaXMub3B0aW9ucy5wYWNrYWdlTmFtZX06OiR7c2VydmljZU5hbWV9LCB0cnkgJHt0aGlzLnNhZmV0eX0vMi4uLmAsXG5cdFx0KVxuXHRcdGlmICh0aGlzLnNhZmV0eSA+PSAyKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoYE91dCBvZiB0cmllcy4uLmApXG5cdFx0fVxuXHRcdHRoaXMuc2FmZXR5KytcblxuXHRcdGNvbnN0IFtleGUsIC4uLmFyZ3NdID0gdGhpcy5vcHRpb25zLnNlcnZpY2VzW3NlcnZpY2VOYW1lXS5ydW4uc3BsaXQoYCBgKVxuXHRcdGNvbnN0IHNlcnZpY2VQcm9jZXNzID0gc3Bhd24oZXhlLCBhcmdzLCB7XG5cdFx0XHRjd2Q6IHRoaXMub3B0aW9ucy5mbGlnaHRkZWNrUm9vdERpcixcblx0XHRcdGVudjogaW1wb3J0Lm1ldGEuZW52LFxuXHRcdH0pXG5cdFx0Y29uc3Qgc2VydmljZUxvZ2dlciA9IHRoaXMuc2VydmljZUxvZ2dlcnNbc2VydmljZU5hbWVdXG5cdFx0Y29uc3Qgc2VydmljZSA9ICh0aGlzLnNlcnZpY2VzW3NlcnZpY2VOYW1lXSA9IG5ldyBDaGlsZFNvY2tldChcblx0XHRcdHNlcnZpY2VQcm9jZXNzLFxuXHRcdFx0YCR7dGhpcy5vcHRpb25zLnBhY2thZ2VOYW1lfTo6JHtzZXJ2aWNlTmFtZX1gLFxuXHRcdFx0c2VydmljZUxvZ2dlcixcblx0XHQpKVxuXHRcdHNlcnZpY2VMb2dnZXIucHJvY2Vzc0NvZGUgPSBzZXJ2aWNlLnByb2Nlc3MucGlkID8/IC0xXG5cdFx0dGhpcy5zZXJ2aWNlc1tzZXJ2aWNlTmFtZV0ub25BbnkoKC4uLm1lc3NhZ2VzKSA9PiB7XG5cdFx0XHRzZXJ2aWNlTG9nZ2VyLmluZm8oYPCfkqxgLCAuLi5tZXNzYWdlcylcblx0XHR9KVxuXHRcdHRoaXMuc2VydmljZXNbc2VydmljZU5hbWVdLm9uKGByZWFkeVRvVXBkYXRlYCwgKCkgPT4ge1xuXHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhgU2VydmljZSBcIiR7c2VydmljZU5hbWV9XCIgaXMgcmVhZHkgdG8gdXBkYXRlLmApXG5cdFx0XHR0aGlzLnNlcnZpY2VzUmVhZHlUb1VwZGF0ZVtzZXJ2aWNlTmFtZV0gPSB0cnVlXG5cdFx0XHR0aGlzLnRyeVVwZGF0ZSgpXG5cdFx0fSlcblx0XHR0aGlzLnNlcnZpY2VzW3NlcnZpY2VOYW1lXS5vbihgYWxpdmVgLCAoKSA9PiB7XG5cdFx0XHR0aGlzLnNlcnZpY2VzTGl2ZVt0aGlzLnNlcnZpY2VJZHhbc2VydmljZU5hbWVdXS51c2UoUHJvbWlzZS5yZXNvbHZlKCkpXG5cdFx0XHR0aGlzLnNlcnZpY2VzRGVhZFt0aGlzLnNlcnZpY2VJZHhbc2VydmljZU5hbWVdXSA9IG5ldyBGdXR1cmUoKCkgPT4ge30pXG5cdFx0XHRpZiAodGhpcy5kZWFkLmRvbmUpIHtcblx0XHRcdFx0dGhpcy5kZWFkID0gbmV3IEZ1dHVyZSgoKSA9PiB7fSlcblx0XHRcdH1cblx0XHRcdHRoaXMuZGVhZC51c2UoUHJvbWlzZS5hbGwodGhpcy5zZXJ2aWNlc0RlYWQpKVxuXHRcdH0pXG5cdFx0dGhpcy5zZXJ2aWNlc1tzZXJ2aWNlTmFtZV0ucHJvY2Vzcy5vbmNlKGBjbG9zZWAsIChleGl0Q29kZSkgPT4ge1xuXHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhcblx0XHRcdFx0YEF1dG8tcmVzcGF3biBzYXcgXCIke3NlcnZpY2VOYW1lfVwiIGV4aXQgd2l0aCBjb2RlICR7ZXhpdENvZGV9YCxcblx0XHRcdClcblx0XHRcdHRoaXMuc2VydmljZXNbc2VydmljZU5hbWVdID0gbnVsbFxuXHRcdFx0aWYgKCF0aGlzLmF1dG9SZXNwYXduRGVhZFNlcnZpY2VzKSB7XG5cdFx0XHRcdHRoaXMubG9nZ2VyLmluZm8oYEF1dG8tcmVzcGF3biBpcyBvZmY7IFwiJHtzZXJ2aWNlTmFtZX1cIiByZXN0cy5gKVxuXHRcdFx0XHRyZXR1cm5cblx0XHRcdH1cblx0XHRcdGNvbnN0IHVwZGF0ZVBoYXNlID0gdGhpcy5zdG9yYWdlLmdldEl0ZW0oYHVwZGF0ZVBoYXNlYClcblx0XHRcdHRoaXMubG9nZ2VyLmluZm8oYD4gc3RvcmFnZShcInVwZGF0ZVBoYXNlXCIpID5gLCB1cGRhdGVQaGFzZSlcblx0XHRcdGNvbnN0IHVwZGF0ZXNBcmVSZWFkeSA9IHVwZGF0ZVBoYXNlID09PSBgY29uZmlybWVkYFxuXHRcdFx0aWYgKHVwZGF0ZXNBcmVSZWFkeSkge1xuXHRcdFx0XHR0aGlzLnNlcnZpY2VMb2dnZXJzW3NlcnZpY2VOYW1lXS5pbmZvKGBVcGRhdGluZyBiZWZvcmUgc3RhcnR1cC4uLmApXG5cdFx0XHRcdHRoaXMucmVzdGFydFRpbWVzID0gW11cblx0XHRcdFx0dGhpcy5pbnN0YWxsUGFja2FnZSgpXG5cdFx0XHRcdHRoaXMuc3RhcnRTZXJ2aWNlKHNlcnZpY2VOYW1lKVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Y29uc3Qgbm93ID0gRGF0ZS5ub3coKVxuXHRcdFx0XHRjb25zdCBmaXZlTWludXRlc0FnbyA9IG5vdyAtIDUgKiA2MCAqIDEwMDBcblx0XHRcdFx0dGhpcy5yZXN0YXJ0VGltZXMgPSB0aGlzLnJlc3RhcnRUaW1lcy5maWx0ZXIoXG5cdFx0XHRcdFx0KHRpbWUpID0+IHRpbWUgPiBmaXZlTWludXRlc0Fnbyxcblx0XHRcdFx0KVxuXHRcdFx0XHR0aGlzLnJlc3RhcnRUaW1lcy5wdXNoKG5vdylcblxuXHRcdFx0XHRpZiAodGhpcy5yZXN0YXJ0VGltZXMubGVuZ3RoIDwgNSkge1xuXHRcdFx0XHRcdHRoaXMuc2VydmljZUxvZ2dlcnNbc2VydmljZU5hbWVdLmluZm8oYENyYXNoZWQuIFJlc3RhcnRpbmcuLi5gKVxuXHRcdFx0XHRcdHRoaXMuc3RhcnRTZXJ2aWNlKHNlcnZpY2VOYW1lKVxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHRoaXMuc2VydmljZUxvZ2dlcnNbc2VydmljZU5hbWVdLmluZm8oXG5cdFx0XHRcdFx0XHRgQ3Jhc2hlZCA1IHRpbWVzIGluIDUgbWludXRlcy4gTm90IHJlc3RhcnRpbmcuYCxcblx0XHRcdFx0XHQpXG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9KVxuXHRcdHRoaXMuc2FmZXR5ID0gMFxuXHR9XG5cblx0cHJvdGVjdGVkIGRvd25sb2FkUGFja2FnZSgpOiB2b2lkIHtcblx0XHR0aGlzLmxvZ2dlci5pbmZvKGBEb3dubG9hZGluZy4uLmApXG5cdFx0dHJ5IHtcblx0XHRcdGNvbnN0IG91dCA9IGV4ZWNTeW5jKHRoaXMub3B0aW9ucy5zY3JpcHRzLmRvd25sb2FkKVxuXHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhgRG93bmxvYWQgc3Rkb3V0OmAsIG91dC50b1N0cmluZygpKVxuXHRcdFx0dGhpcy5zdG9yYWdlLnNldEl0ZW0oYHNldHVwUGhhc2VgLCBgZG93bmxvYWRlZGApXG5cdFx0XHR0aGlzLmxvZ2dlci5pbmZvKGBEb3dubG9hZGVkIWApXG5cdFx0fSBjYXRjaCAodGhyb3duKSB7XG5cdFx0XHRpZiAodGhyb3duIGluc3RhbmNlb2YgRXJyb3IpIHtcblx0XHRcdFx0dGhpcy5sb2dnZXIuZXJyb3IoYEZhaWxlZCB0byBnZXQgdGhlIGxhdGVzdCByZWxlYXNlOiAke3Rocm93bi5tZXNzYWdlfWApXG5cdFx0XHR9XG5cdFx0XHRyZXR1cm5cblx0XHR9XG5cdH1cblxuXHRwcm90ZWN0ZWQgaW5zdGFsbFBhY2thZ2UoKTogdm9pZCB7XG5cdFx0dGhpcy5sb2dnZXIuaW5mbyhgSW5zdGFsbGluZy4uLmApXG5cblx0XHR0cnkge1xuXHRcdFx0Y29uc3Qgb3V0ID0gZXhlY1N5bmModGhpcy5vcHRpb25zLnNjcmlwdHMuaW5zdGFsbClcblx0XHRcdHRoaXMubG9nZ2VyLmluZm8oYEluc3RhbGwgc3Rkb3V0OmAsIG91dC50b1N0cmluZygpKVxuXHRcdFx0dGhpcy5zdG9yYWdlLnNldEl0ZW0oYHNldHVwUGhhc2VgLCBgaW5zdGFsbGVkYClcblx0XHRcdHRoaXMubG9nZ2VyLmluZm8oYEluc3RhbGxlZCFgKVxuXHRcdH0gY2F0Y2ggKHRocm93bikge1xuXHRcdFx0aWYgKHRocm93biBpbnN0YW5jZW9mIEVycm9yKSB7XG5cdFx0XHRcdHRoaXMubG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gZ2V0IHRoZSBsYXRlc3QgcmVsZWFzZTogJHt0aHJvd24ubWVzc2FnZX1gKVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuXG5cdFx0fVxuXHR9XG5cblx0cHVibGljIHN0b3BBbGxTZXJ2aWNlcygpOiBGdXR1cmU8dW5rbm93bj4ge1xuXHRcdHRoaXMubG9nZ2VyLmluZm8oYFN0b3BwaW5nIGFsbCBzZXJ2aWNlcy4uLiBhdXRvLXJlc3Bhd24gZGlzYWJsZWQuYClcblx0XHR0aGlzLmF1dG9SZXNwYXduRGVhZFNlcnZpY2VzID0gZmFsc2Vcblx0XHRmb3IgKGNvbnN0IFtzZXJ2aWNlTmFtZV0gb2YgdG9FbnRyaWVzKHRoaXMuc2VydmljZXMpKSB7XG5cdFx0XHR0aGlzLnN0b3BTZXJ2aWNlKHNlcnZpY2VOYW1lKVxuXHRcdH1cblx0XHRyZXR1cm4gdGhpcy5kZWFkXG5cdH1cblxuXHRwdWJsaWMgc3RvcFNlcnZpY2Uoc2VydmljZU5hbWU6IFMpOiB2b2lkIHtcblx0XHRjb25zdCBzZXJ2aWNlID0gdGhpcy5zZXJ2aWNlc1tzZXJ2aWNlTmFtZV1cblx0XHRpZiAoc2VydmljZSkge1xuXHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhgU3RvcHBpbmcgc2VydmljZSBcIiR7c2VydmljZU5hbWV9XCIuLi5gKVxuXHRcdFx0dGhpcy5zZXJ2aWNlc0RlYWRbdGhpcy5zZXJ2aWNlSWR4W3NlcnZpY2VOYW1lXV0udXNlKFxuXHRcdFx0XHRuZXcgUHJvbWlzZSgocGFzcykgPT4ge1xuXHRcdFx0XHRcdHNlcnZpY2UuZW1pdChgdGltZVRvU3RvcGApXG5cdFx0XHRcdFx0c2VydmljZS5wcm9jZXNzLm9uY2UoYGNsb3NlYCwgKGV4aXRDb2RlKSA9PiB7XG5cdFx0XHRcdFx0XHR0aGlzLmxvZ2dlci5pbmZvKFxuXHRcdFx0XHRcdFx0XHRgU3RvcHBlZCBzZXJ2aWNlIFwiJHtzZXJ2aWNlTmFtZX1cIjsgZXhpdGVkIHdpdGggY29kZSAke2V4aXRDb2RlfWAsXG5cdFx0XHRcdFx0XHQpXG5cdFx0XHRcdFx0XHR0aGlzLnNlcnZpY2VzW3NlcnZpY2VOYW1lXSA9IG51bGxcblx0XHRcdFx0XHRcdHBhc3MoKVxuXHRcdFx0XHRcdH0pXG5cdFx0XHRcdH0pLFxuXHRcdFx0KVxuXHRcdFx0dGhpcy5kZWFkLnVzZShQcm9taXNlLmFsbCh0aGlzLnNlcnZpY2VzRGVhZCkpXG5cdFx0XHR0aGlzLnNlcnZpY2VzTGl2ZVt0aGlzLnNlcnZpY2VJZHhbc2VydmljZU5hbWVdXSA9IG5ldyBGdXR1cmUoKCkgPT4ge30pXG5cdFx0XHRpZiAodGhpcy5saXZlLmRvbmUpIHtcblx0XHRcdFx0dGhpcy5saXZlID0gbmV3IEZ1dHVyZSgoKSA9PiB7fSlcblx0XHRcdH1cblx0XHRcdHRoaXMubGl2ZS51c2UoUHJvbWlzZS5hbGwodGhpcy5zZXJ2aWNlc0xpdmUpKVxuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aGlzLnNlcnZpY2VMb2dnZXJzW3NlcnZpY2VOYW1lXS5lcnJvcihcblx0XHRcdFx0YFRyaWVkIHRvIHN0b3Agc2VydmljZSwgYnV0IGl0IHdhc24ndCBydW5uaW5nLmAsXG5cdFx0XHQpXG5cdFx0fVxuXHR9XG59XG5cbmV4cG9ydCBjb25zdCBmbGlnaHREZWNrTG9nU2NoZW1hID0gei5vYmplY3Qoe1xuXHRsZXZlbDogei51bmlvbihbei5saXRlcmFsKGBpbmZvYCksIHoubGl0ZXJhbChgd2FybmApLCB6LmxpdGVyYWwoYEVSUiFgKV0pLFxuXHR0aW1lc3RhbXA6IHoubnVtYmVyKCksXG5cdHBhY2thZ2U6IHouc3RyaW5nKCksXG5cdHNlcnZpY2U6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcblx0cHJvY2Vzczogei5udW1iZXIoKSxcblx0Ym9keTogei5zdHJpbmcoKSxcbn0pXG5leHBvcnQgdHlwZSBGbGlnaHREZWNrTG9nID0gei5pbmZlcjx0eXBlb2YgZmxpZ2h0RGVja0xvZ1NjaGVtYT5cblxuY29uc3QgTElORV9GT1JNQVQgPSBgbGluZS1mb3JtYXRgIHNhdGlzZmllcyBrZXlvZiBMbmF2Rm9ybWF0XG5jb25zdCBWQUxVRSA9IGB2YWx1ZWAgc2F0aXNmaWVzIGtleW9mIExuYXZGb3JtYXRcblxuZXhwb3J0IHR5cGUgTG5hdkZvcm1hdFZpc3VhbENvbXBvbmVudCA9IEV4Y2x1ZGU8XG5cdEV4Y2x1ZGU8TG5hdkZvcm1hdFtgbGluZS1mb3JtYXRgXSwgdW5kZWZpbmVkPltudW1iZXJdLFxuXHRzdHJpbmdcbj5cblxuZXhwb3J0IHR5cGUgTG5hdkZvcm1hdEJyZWFrZG93biA9IEV4Y2x1ZGU8TG5hdkZvcm1hdFtgdmFsdWVgXSwgdW5kZWZpbmVkPlxuZXhwb3J0IHR5cGUgTWVtYmVyT2Y8VD4gPSBUW2tleW9mIFRdXG5leHBvcnQgdHlwZSBMbmF2Rm9ybWF0VmFsdWVEZWZpbml0aW9uID0gTWVtYmVyT2Y8TG5hdkZvcm1hdEJyZWFrZG93bj5cblxuZXhwb3J0IHR5cGUgRmxpZ2h0RGVja0Zvcm1hdCA9IHtcblx0W0xJTkVfRk9STUFUXTogKFxuXHRcdHwgc3RyaW5nXG5cdFx0fCAoTG5hdkZvcm1hdFZpc3VhbENvbXBvbmVudCAmIHtcblx0XHRcdFx0ZmllbGQ6IGtleW9mIEZsaWdodERlY2tMb2cgfCBgX19sZXZlbF9fYCB8IGBfX3RpbWVzdGFtcF9fYFxuXHRcdCAgfSlcblx0KVtdXG5cdFtWQUxVRV06IHtcblx0XHRbSyBpbiBrZXlvZiBGbGlnaHREZWNrTG9nXTogTG5hdkZvcm1hdFZhbHVlRGVmaW5pdGlvbiAmIHtcblx0XHRcdGtpbmQ6IEZsaWdodERlY2tMb2dbS10gZXh0ZW5kcyBudW1iZXIgfCB1bmRlZmluZWRcblx0XHRcdFx0PyBgaW50ZWdlcmBcblx0XHRcdFx0OiBGbGlnaHREZWNrTG9nW0tdIGV4dGVuZHMgc3RyaW5nIHwgdW5kZWZpbmVkXG5cdFx0XHRcdFx0PyBgc3RyaW5nYFxuXHRcdFx0XHRcdDogbmV2ZXJcblx0XHR9XG5cdH1cbn1cblxuZXhwb3J0IGNvbnN0IEZMSUdIVERFQ0tfTE5BVl9GT1JNQVQgPSB7XG5cdHRpdGxlOiBgRmxpZ2h0RGVjayBMb2dgLFxuXHRkZXNjcmlwdGlvbjogYEZvcm1hdCBmb3IgZXZlbnRzIGxvZ2dlZCBieSB0aGUgRmxpZ2h0RGVjayBwcm9jZXNzIG1hbmFnZXIuYCxcblx0XCJmaWxlLXR5cGVcIjogYGpzb25gLFxuXHRcInRpbWVzdGFtcC1maWVsZFwiOiBgdGltZXN0YW1wYCxcblx0XCJzdWJzZWNvbmQtZmllbGRcIjogYHN1YnNlY29uZGAsXG5cdFwic3Vic2Vjb25kLXVuaXRzXCI6IGBtaWxsaWAsXG5cdFwib3BpZC1maWVsZFwiOiBgc2VydmljZWAsXG5cdFwibGV2ZWwtZmllbGRcIjogYGxldmVsYCxcblx0bGV2ZWw6IHtcblx0XHRpbmZvOiBgaW5mb2AsXG5cdFx0d2FybmluZzogYHdhcm5gLFxuXHRcdGVycm9yOiBgZXJyIWAsXG5cdH0sXG5cdFwib3JkZXJlZC1ieS10aW1lXCI6IHRydWUsXG5cblx0W0xJTkVfRk9STUFUXTogW1xuXHRcdHtcblx0XHRcdHByZWZpeDogYCBgLFxuXHRcdFx0ZmllbGQ6IGBfX3RpbWVzdGFtcF9fYCxcblx0XHRcdFwidGltZXN0YW1wLWZvcm1hdFwiOiBgJVktJW0tJWRUJUg6JU06JVMuJUwlWmAsXG5cdFx0fSxcblx0XHR7XG5cdFx0XHRwcmVmaXg6IGAgYCxcblx0XHRcdGZpZWxkOiBgcHJvY2Vzc2AsXG5cdFx0XHRcIm1pbi13aWR0aFwiOiA1LFxuXHRcdH0sXG5cdFx0e1xuXHRcdFx0cHJlZml4OiBgOmAsXG5cdFx0XHRmaWVsZDogYHBhY2thZ2VgLFxuXHRcdH0sXG5cdFx0e1xuXHRcdFx0cHJlZml4OiBgOmAsXG5cdFx0XHRmaWVsZDogYHNlcnZpY2VgLFxuXHRcdFx0XCJkZWZhdWx0LXZhbHVlXCI6IGBgLFxuXHRcdH0sXG5cdFx0e1xuXHRcdFx0cHJlZml4OiBgW2AsXG5cdFx0XHRmaWVsZDogYF9fbGV2ZWxfX2AsXG5cdFx0XHRzdWZmaXg6IGBdYCxcblx0XHR9LFxuXHRcdHtcblx0XHRcdHByZWZpeDogYDogYCxcblx0XHRcdGZpZWxkOiBgYm9keWAsXG5cdFx0fSxcblx0XSxcblxuXHRbVkFMVUVdOiB7XG5cdFx0dGltZXN0YW1wOiB7XG5cdFx0XHRraW5kOiBgaW50ZWdlcmAsXG5cdFx0fSxcblx0XHRsZXZlbDoge1xuXHRcdFx0a2luZDogYHN0cmluZ2AsXG5cdFx0fSxcblx0XHRwYWNrYWdlOiB7XG5cdFx0XHRraW5kOiBgc3RyaW5nYCxcblx0XHR9LFxuXHRcdHNlcnZpY2U6IHtcblx0XHRcdGtpbmQ6IGBzdHJpbmdgLFxuXHRcdH0sXG5cdFx0cHJvY2Vzczoge1xuXHRcdFx0a2luZDogYGludGVnZXJgLFxuXHRcdH0sXG5cdFx0Ym9keToge1xuXHRcdFx0a2luZDogYHN0cmluZ2AsXG5cdFx0fSxcblx0fSxcbn0gYXMgY29uc3Qgc2F0aXNmaWVzIEZsaWdodERlY2tGb3JtYXQgJiBMbmF2Rm9ybWF0XG5cbmV4cG9ydCBjbGFzcyBGbGlnaHREZWNrTG9nZ2VyXG5cdGltcGxlbWVudHMgUGljazxDb25zb2xlLCBgZXJyb3JgIHwgYGluZm9gIHwgYHdhcm5gPlxue1xuXHRwdWJsaWMgcmVhZG9ubHkgcGFja2FnZU5hbWU6IHN0cmluZ1xuXHRwdWJsaWMgcmVhZG9ubHkgc2VydmljZU5hbWU/OiBzdHJpbmdcblx0cHVibGljIHJlYWRvbmx5IGpzb25Mb2dnaW5nOiBib29sZWFuXG5cdHB1YmxpYyBwcm9jZXNzQ29kZTogbnVtYmVyXG5cdHB1YmxpYyBjb25zdHJ1Y3Rvcihcblx0XHRwYWNrYWdlTmFtZTogc3RyaW5nLFxuXHRcdHByb2Nlc3NDb2RlOiBudW1iZXIsXG5cdFx0c2VydmljZU5hbWU/OiBzdHJpbmcsXG5cdFx0b3B0aW9ucz86IHsganNvbkxvZ2dpbmc6IGJvb2xlYW4gfSxcblx0KSB7XG5cdFx0dGhpcy5wYWNrYWdlTmFtZSA9IHBhY2thZ2VOYW1lXG5cdFx0aWYgKHNlcnZpY2VOYW1lKSB7XG5cdFx0XHR0aGlzLnNlcnZpY2VOYW1lID0gc2VydmljZU5hbWVcblx0XHR9XG5cdFx0dGhpcy5wcm9jZXNzQ29kZSA9IHByb2Nlc3NDb2RlXG5cdFx0dGhpcy5qc29uTG9nZ2luZyA9IG9wdGlvbnM/Lmpzb25Mb2dnaW5nID8/IGZhbHNlXG5cdH1cblx0cHVibGljIGluZm8oLi4ubWVzc2FnZXM6IHVua25vd25bXSk6IHZvaWQge1xuXHRcdGlmICh0aGlzLmpzb25Mb2dnaW5nKSB7XG5cdFx0XHRjb25zdCBsb2c6IEZsaWdodERlY2tMb2cgPSB7XG5cdFx0XHRcdHRpbWVzdGFtcDogRGF0ZS5ub3coKSxcblx0XHRcdFx0bGV2ZWw6IGBpbmZvYCxcblx0XHRcdFx0cHJvY2VzczogdGhpcy5wcm9jZXNzQ29kZSxcblx0XHRcdFx0cGFja2FnZTogdGhpcy5wYWNrYWdlTmFtZSxcblx0XHRcdFx0Ym9keTogbWVzc2FnZXNcblx0XHRcdFx0XHQubWFwKChtZXNzYWdlKSA9PlxuXHRcdFx0XHRcdFx0dHlwZW9mIG1lc3NhZ2UgPT09IGBzdHJpbmdgXG5cdFx0XHRcdFx0XHRcdD8gbWVzc2FnZVxuXHRcdFx0XHRcdFx0XHQ6IGluc3BlY3QobWVzc2FnZSwgZmFsc2UsIG51bGwsIHRydWUpLFxuXHRcdFx0XHRcdClcblx0XHRcdFx0XHQuam9pbihgIGApLFxuXHRcdFx0fVxuXHRcdFx0aWYgKHRoaXMuc2VydmljZU5hbWUpIHtcblx0XHRcdFx0bG9nLnNlcnZpY2UgPSB0aGlzLnNlcnZpY2VOYW1lXG5cdFx0XHR9XG5cdFx0XHRwcm9jZXNzLnN0ZG91dC53cml0ZShKU09OLnN0cmluZ2lmeShsb2cpICsgYFxcbmApXG5cdFx0fSBlbHNlIHtcblx0XHRcdGNvbnN0IHNvdXJjZSA9IHRoaXMuc2VydmljZU5hbWVcblx0XHRcdFx0PyBgJHt0aGlzLnBhY2thZ2VOYW1lfTo6JHt0aGlzLnNlcnZpY2VOYW1lfWBcblx0XHRcdFx0OiB0aGlzLnBhY2thZ2VOYW1lXG5cdFx0XHRjb25zb2xlLmxvZyhgJHtzb3VyY2V9OmAsIC4uLm1lc3NhZ2VzKVxuXHRcdH1cblx0fVxuXG5cdHB1YmxpYyB3YXJuKC4uLm1lc3NhZ2VzOiB1bmtub3duW10pOiB2b2lkIHtcblx0XHRpZiAodGhpcy5qc29uTG9nZ2luZykge1xuXHRcdFx0Y29uc3QgbG9nOiBGbGlnaHREZWNrTG9nID0ge1xuXHRcdFx0XHR0aW1lc3RhbXA6IERhdGUubm93KCksXG5cdFx0XHRcdGxldmVsOiBgd2FybmAsXG5cdFx0XHRcdHByb2Nlc3M6IHRoaXMucHJvY2Vzc0NvZGUsXG5cdFx0XHRcdHBhY2thZ2U6IHRoaXMucGFja2FnZU5hbWUsXG5cdFx0XHRcdGJvZHk6IG1lc3NhZ2VzXG5cdFx0XHRcdFx0Lm1hcCgobWVzc2FnZSkgPT5cblx0XHRcdFx0XHRcdHR5cGVvZiBtZXNzYWdlID09PSBgc3RyaW5nYFxuXHRcdFx0XHRcdFx0XHQ/IG1lc3NhZ2Vcblx0XHRcdFx0XHRcdFx0OiBpbnNwZWN0KG1lc3NhZ2UsIGZhbHNlLCBudWxsLCB0cnVlKSxcblx0XHRcdFx0XHQpXG5cdFx0XHRcdFx0LmpvaW4oYCBgKSxcblx0XHRcdH1cblx0XHRcdGlmICh0aGlzLnNlcnZpY2VOYW1lKSB7XG5cdFx0XHRcdGxvZy5zZXJ2aWNlID0gdGhpcy5zZXJ2aWNlTmFtZVxuXHRcdFx0fVxuXHRcdFx0cHJvY2Vzcy5zdGRvdXQud3JpdGUoSlNPTi5zdHJpbmdpZnkobG9nKSArIGBcXG5gKVxuXHRcdH0gZWxzZSB7XG5cdFx0XHRjb25zdCBzb3VyY2UgPSB0aGlzLnNlcnZpY2VOYW1lXG5cdFx0XHRcdD8gYCR7dGhpcy5wYWNrYWdlTmFtZX06OiR7dGhpcy5zZXJ2aWNlTmFtZX1gXG5cdFx0XHRcdDogdGhpcy5wYWNrYWdlTmFtZVxuXHRcdFx0Y29uc29sZS53YXJuKGAke3NvdXJjZX06YCwgLi4ubWVzc2FnZXMpXG5cdFx0fVxuXHR9XG5cblx0cHVibGljIGVycm9yKC4uLm1lc3NhZ2VzOiB1bmtub3duW10pOiB2b2lkIHtcblx0XHRpZiAodGhpcy5qc29uTG9nZ2luZykge1xuXHRcdFx0Y29uc3QgbG9nOiBGbGlnaHREZWNrTG9nID0ge1xuXHRcdFx0XHR0aW1lc3RhbXA6IERhdGUubm93KCkgKyBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiAxMDAwKSxcblx0XHRcdFx0bGV2ZWw6IGBFUlIhYCxcblx0XHRcdFx0cHJvY2VzczogdGhpcy5wcm9jZXNzQ29kZSxcblx0XHRcdFx0cGFja2FnZTogdGhpcy5wYWNrYWdlTmFtZSxcblx0XHRcdFx0Ym9keTogbWVzc2FnZXNcblx0XHRcdFx0XHQubWFwKChtZXNzYWdlKSA9PlxuXHRcdFx0XHRcdFx0dHlwZW9mIG1lc3NhZ2UgPT09IGBzdHJpbmdgXG5cdFx0XHRcdFx0XHRcdD8gbWVzc2FnZVxuXHRcdFx0XHRcdFx0XHQ6IGluc3BlY3QobWVzc2FnZSwgZmFsc2UsIG51bGwsIHRydWUpLFxuXHRcdFx0XHRcdClcblx0XHRcdFx0XHQuam9pbihgIGApLFxuXHRcdFx0fVxuXHRcdFx0aWYgKHRoaXMuc2VydmljZU5hbWUpIHtcblx0XHRcdFx0bG9nLnNlcnZpY2UgPSB0aGlzLnNlcnZpY2VOYW1lXG5cdFx0XHR9XG5cdFx0XHRwcm9jZXNzLnN0ZG91dC53cml0ZShKU09OLnN0cmluZ2lmeShsb2cpICsgYFxcbmApXG5cdFx0fSBlbHNlIHtcblx0XHRcdGNvbnN0IHNvdXJjZSA9IHRoaXMuc2VydmljZU5hbWVcblx0XHRcdFx0PyBgJHt0aGlzLnBhY2thZ2VOYW1lfTo6JHt0aGlzLnNlcnZpY2VOYW1lfWBcblx0XHRcdFx0OiB0aGlzLnBhY2thZ2VOYW1lXG5cdFx0XHRjb25zb2xlLmVycm9yKGAke3NvdXJjZX06YCwgLi4ubWVzc2FnZXMpXG5cdFx0fVxuXHR9XG59XG4iLAogICAgImltcG9ydCB7XG5cdGV4aXN0c1N5bmMsXG5cdG1rZGlyU3luYyxcblx0cmVhZGRpclN5bmMsXG5cdHJlYWRGaWxlU3luYyxcblx0cm1TeW5jLFxuXHRzdGF0U3luYyxcblx0d3JpdGVGaWxlU3luYyxcbn0gZnJvbSBcIm5vZGU6ZnNcIlxuaW1wb3J0IHsgcmVzb2x2ZSB9IGZyb20gXCJub2RlOnBhdGhcIlxuXG5leHBvcnQgdHlwZSBGaWxlc3lzdGVtU3RvcmFnZU9wdGlvbnMgPSB7XG5cdHBhdGg6IHN0cmluZ1xufVxuXG5leHBvcnQgY2xhc3MgRmlsZXN5c3RlbVN0b3JhZ2U8XG5cdFQgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0gUmVjb3JkPHN0cmluZywgc3RyaW5nPixcbj4gaW1wbGVtZW50cyBTdG9yYWdlXG57XG5cdHB1YmxpYyByb290RGlyOiBzdHJpbmdcblxuXHRwdWJsaWMgY29uc3RydWN0b3Iob3B0aW9uczogRmlsZXN5c3RlbVN0b3JhZ2VPcHRpb25zKSB7XG5cdFx0dGhpcy5yb290RGlyID0gb3B0aW9ucy5wYXRoXG5cdFx0aWYgKCFleGlzdHNTeW5jKHRoaXMucm9vdERpcikpIHtcblx0XHRcdG1rZGlyU3luYyh0aGlzLnJvb3REaXIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pXG5cdFx0fVxuXHR9XG5cblx0cHVibGljIGdldEl0ZW08SyBleHRlbmRzIHN0cmluZyAmIGtleW9mIFQ+KGtleTogSyk6IFRbS10gfCBudWxsIHtcblx0XHRjb25zdCBmaWxlUGF0aCA9IHJlc29sdmUodGhpcy5yb290RGlyLCBrZXkpXG5cdFx0aWYgKGV4aXN0c1N5bmMoZmlsZVBhdGgpKSB7XG5cdFx0XHRyZXR1cm4gcmVhZEZpbGVTeW5jKGZpbGVQYXRoLCBgdXRmLThgKSBhcyBUW0tdXG5cdFx0fVxuXHRcdHJldHVybiBudWxsXG5cdH1cblxuXHRwdWJsaWMgc2V0SXRlbTxLIGV4dGVuZHMgc3RyaW5nICYga2V5b2YgVD4oa2V5OiBLLCB2YWx1ZTogVFtLXSk6IHZvaWQge1xuXHRcdGNvbnN0IGZpbGVQYXRoID0gcmVzb2x2ZSh0aGlzLnJvb3REaXIsIGtleSlcblx0XHR3cml0ZUZpbGVTeW5jKGZpbGVQYXRoLCB2YWx1ZSlcblx0fVxuXG5cdHB1YmxpYyByZW1vdmVJdGVtPEsgZXh0ZW5kcyBzdHJpbmcgJiBrZXlvZiBUPihrZXk6IEspOiB2b2lkIHtcblx0XHRjb25zdCBmaWxlUGF0aCA9IHJlc29sdmUodGhpcy5yb290RGlyLCBrZXkpXG5cdFx0aWYgKGV4aXN0c1N5bmMoZmlsZVBhdGgpKSB7XG5cdFx0XHRybVN5bmMoZmlsZVBhdGgpXG5cdFx0fVxuXHR9XG5cblx0cHVibGljIGtleShpbmRleDogbnVtYmVyKTogKHN0cmluZyAmIGtleW9mIFQpIHwgbnVsbCB7XG5cdFx0Y29uc3QgZmlsZVBhdGhzID0gcmVhZGRpclN5bmModGhpcy5yb290RGlyKVxuXHRcdGNvbnN0IGZpbGVQYXRoc0J5RGF0ZUNyZWF0ZWQgPSBmaWxlUGF0aHMuc29ydCgoYSwgYikgPT4ge1xuXHRcdFx0Y29uc3QgYVN0YXQgPSBzdGF0U3luYyhhKVxuXHRcdFx0Y29uc3QgYlN0YXQgPSBzdGF0U3luYyhiKVxuXHRcdFx0cmV0dXJuIGJTdGF0LmN0aW1lTXMgLSBhU3RhdC5jdGltZU1zXG5cdFx0fSlcblx0XHRyZXR1cm4gKGZpbGVQYXRoc0J5RGF0ZUNyZWF0ZWRbaW5kZXhdIGFzIHN0cmluZyAmIGtleW9mIFQpID8/IG51bGxcblx0fVxuXG5cdHB1YmxpYyBjbGVhcigpOiB2b2lkIHtcblx0XHRybVN5bmModGhpcy5yb290RGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KVxuXHRcdG1rZGlyU3luYyh0aGlzLnJvb3REaXIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pXG5cdH1cblxuXHRwdWJsaWMgZ2V0IGxlbmd0aCgpOiBudW1iZXIge1xuXHRcdHJldHVybiByZWFkZGlyU3luYyh0aGlzLnJvb3REaXIpLmxlbmd0aFxuXHR9XG59XG4iLAogICAgImltcG9ydCB7IGNyZWF0ZUVudiB9IGZyb20gXCJAdDMtb3NzL2Vudi1jb3JlXCJcbmltcG9ydCB7IHogfSBmcm9tIFwiem9kXCJcblxuZXhwb3J0IGNvbnN0IGVudiA9IGNyZWF0ZUVudih7XG5cdHNlcnZlcjogeyBGTElHSFRERUNLX1NFQ1JFVDogei5zdHJpbmcoKS5vcHRpb25hbCgpIH0sXG5cdGNsaWVudFByZWZpeDogYE5FVkVSYCxcblx0Y2xpZW50OiB7fSxcblx0cnVudGltZUVudjogaW1wb3J0Lm1ldGEuZW52LFxuXHRlbXB0eVN0cmluZ0FzVW5kZWZpbmVkOiB0cnVlLFxufSlcbiIKICBdLAogICJtYXBwaW5ncyI6ICI7K0hBRUEsNEJBR0EsY0FBUyxjQUFLLHdCQUFVLHVCQUFvQixpQkFDNUMsWUFBUyxZQ05ULG1CQUFTLFdBQVUsMkJBRW5CLHVCQUFTLGtCQUNULGtCQUFTLGdCQUNULGtCQUFTLGtCQUNULGtCQUFTLGtCQUVULGlCQUFTLHlCQUNULHVCQUFTLDhCQUNULHNCQUFTLGVBQWEscUJBQ3RCLHNCQUFTLGdDQUNULGtCQUFTLGFBQ1QsWUFBUyxZ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QUNWLENBQ0QsQ0FDRCxFQUVNLEdBQVEsRUFDYixDQUNDLFFBQVMsYUFDVCxPQUFRLEVBQVMsQ0FBRSxPQUFRLEtBQU0sWUFBYSxJQUFLLENBQUMsRUFDcEQsYUFBYyxDQUNiLEdBQUksRUFDSixZQUFhLEVBQ2IsT0FBUSxFQUNULEVBQ0EsWUFBYSxHQUNiLG1CQUFvQixDQUFDLElBQVMsQ0FDN0IsR0FBSSxFQUFLLEtBQU8sU0FDZixPQUlELE9BREMsRUFBSyxJQUFXLE9BQUssUUFBUSxJQUFJLEVBQUcsd0JBQXdCLEVBRy9ELEVBQ0EsT0FDRCxHQUVRLFNBQVEsb0JBQW9CLEdBQU0sUUFBUSxJQUFJLEVBRXRELE9BQVEsRUFBTyxVQUNULFNBQ0osQ0FDQyxJQUFRLFVBQVcsRUFBTyxLQUMxQixHQUFnQixHQUFVLEdBQUcsQ0FDOUIsQ0FDQSxjQUNRLENBQ1IsSUFBTSxFQUFhLElBQUksRUFBVyxFQUFPLElBQUksRUFDN0MsUUFBUSxHQUFHLFFBQVMsU0FBWSxDQUMvQixNQUFNLEVBQVcsZ0JBQWdCLEVBQ2pDLENBQ0YiLAogICJkZWJ1Z0lkIjogIkE0RTA1ODdBQTc0M0U4NEU2NDc1NkUyMTY0NzU2RTIxIiwKICAibmFtZXMiOiBbXQp9
9
+ //# debugId=8C257A7694D940D664756E2164756E21
10
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2ZsaWdodGRlY2suYmluLnRzIiwgIi4uL3NyYy9mbGlnaHRkZWNrLmxpYi50cyIsICIuLi9zcmMvZmlsZXN5c3RlbS1zdG9yYWdlLnRzIiwgIi4uL3NyYy9mbGlnaHRkZWNrLmVudi50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsKICAgICIjIS91c3IvYmluL2VudiBub2RlXG5cbmltcG9ydCAqIGFzIHBhdGggZnJvbSBcIm5vZGU6cGF0aFwiXG5cbmltcG9ydCB0eXBlIHsgT3B0aW9uc0dyb3VwIH0gZnJvbSBcImNvbWxpbmVcIlxuaW1wb3J0IHsgY2xpLCBvcHRpb25hbCwgcGFyc2VCb29sZWFuT3B0aW9uLCBwYXJzZU51bWJlck9wdGlvbiB9IGZyb20gXCJjb21saW5lXCJcbmltcG9ydCB7IHogfSBmcm9tIFwiem9kXCJcblxuaW1wb3J0IHR5cGUgeyBGbGlnaHREZWNrT3B0aW9ucyB9IGZyb20gXCIuL2ZsaWdodGRlY2subGliXCJcbmltcG9ydCB7IEZsaWdodERlY2ssIEZsaWdodERlY2tMb2dnZXIgfSBmcm9tIFwiLi9mbGlnaHRkZWNrLmxpYlwiXG5cbmNvbnN0IENMSV9MT0dHRVIgPSBuZXcgRmxpZ2h0RGVja0xvZ2dlcihgY29tbGluZWAsIHByb2Nlc3MucGlkLCB1bmRlZmluZWQsIHtcblx0anNvbkxvZ2dpbmc6IHRydWUsXG59KVxuT2JqZWN0LmFzc2lnbihjb25zb2xlLCB7XG5cdGxvZzogQ0xJX0xPR0dFUi5pbmZvLmJpbmQoQ0xJX0xPR0dFUiksXG5cdGluZm86IENMSV9MT0dHRVIuaW5mby5iaW5kKENMSV9MT0dHRVIpLFxuXHR3YXJuOiBDTElfTE9HR0VSLndhcm4uYmluZChDTElfTE9HR0VSKSxcblx0ZXJyb3I6IENMSV9MT0dHRVIuZXJyb3IuYmluZChDTElfTE9HR0VSKSxcbn0pXG5cbmNvbnN0IEZMSUdIVERFQ0tfTUFOVUFMID0ge1xuXHRvcHRpb25zU2NoZW1hOiB6Lm9iamVjdCh7XG5cdFx0cG9ydDogei5udW1iZXIoKS5vcHRpb25hbCgpLFxuXHRcdHBhY2thZ2VOYW1lOiB6LnN0cmluZygpLFxuXHRcdHNlcnZpY2VzOiB6LnJlY29yZCh6Lm9iamVjdCh7IHJ1bjogei5zdHJpbmcoKSwgd2FpdEZvcjogei5ib29sZWFuKCkgfSkpLFxuXHRcdGZsaWdodGRlY2tSb290RGlyOiB6LnN0cmluZygpLFxuXHRcdHNjcmlwdHM6IHoub2JqZWN0KHtcblx0XHRcdGRvd25sb2FkOiB6LnN0cmluZygpLFxuXHRcdFx0aW5zdGFsbDogei5zdHJpbmcoKSxcblx0XHRcdGNoZWNrQXZhaWxhYmlsaXR5OiB6LnN0cmluZygpLFxuXHRcdH0pLFxuXHRcdGpzb25Mb2dnaW5nOiB6LmJvb2xlYW4oKS5vcHRpb25hbCgpLFxuXHR9KSxcblx0b3B0aW9uczoge1xuXHRcdHBvcnQ6IHtcblx0XHRcdGZsYWc6IGBwYCxcblx0XHRcdHJlcXVpcmVkOiBmYWxzZSxcblx0XHRcdGRlc2NyaXB0aW9uOiBgUG9ydCB0byBydW4gdGhlIGZsaWdodGRlY2sgc2VydmVyIG9uLmAsXG5cdFx0XHRleGFtcGxlOiBgLS1wb3J0PTgwODBgLFxuXHRcdFx0cGFyc2U6IHBhcnNlTnVtYmVyT3B0aW9uLFxuXHRcdH0sXG5cdFx0cGFja2FnZU5hbWU6IHtcblx0XHRcdGZsYWc6IGBuYCxcblx0XHRcdHJlcXVpcmVkOiB0cnVlLFxuXHRcdFx0ZGVzY3JpcHRpb246IGBOYW1lIG9mIHRoZSBwYWNrYWdlLmAsXG5cdFx0XHRleGFtcGxlOiBgLS1wYWNrYWdlTmFtZT1cXFwibXktYXBwXFxcImAsXG5cdFx0fSxcblx0XHRzZXJ2aWNlczoge1xuXHRcdFx0ZmxhZzogYHNgLFxuXHRcdFx0cmVxdWlyZWQ6IHRydWUsXG5cdFx0XHRkZXNjcmlwdGlvbjogYE1hcCBvZiBzZXJ2aWNlIG5hbWVzIHRvIGV4ZWN1dGFibGVzLmAsXG5cdFx0XHRleGFtcGxlOiBgLS1zZXJ2aWNlcz1cIntcXFxcXCJmcm9udGVuZFxcXFxcIjp7XFxcXFwicnVuXFxcXFwiOlxcXFxcIi4vZnJvbnRlbmRcXFxcXCIsXFxcXFwid2FpdEZvclxcXFxcIjpmYWxzZX0sXFxcXFwiYmFja2VuZFxcXFxcIjp7XFxcXFwicnVuXFxcXFwiOlxcXFxcIi4vYmFja2VuZFxcXFxcIixcXFxcXCJ3YWl0Rm9yXFxcXFwiOnRydWV9fVwiYCxcblx0XHRcdHBhcnNlOiBKU09OLnBhcnNlLFxuXHRcdH0sXG5cdFx0ZmxpZ2h0ZGVja1Jvb3REaXI6IHtcblx0XHRcdGZsYWc6IGBkYCxcblx0XHRcdHJlcXVpcmVkOiB0cnVlLFxuXHRcdFx0ZGVzY3JpcHRpb246IGBEaXJlY3Rvcnkgd2hlcmUgdGhlIHNlcnZpY2UgaXMgc3RvcmVkLmAsXG5cdFx0XHRleGFtcGxlOiBgLS1mbGlnaHRkZWNrUm9vdERpcj1cXFwiLi9zZXJ2aWNlcy9zYW1wbGUvcmVwby9teS1hcHAvY3VycmVudFxcXCJgLFxuXHRcdH0sXG5cdFx0c2NyaXB0czoge1xuXHRcdFx0ZmxhZzogYHJgLFxuXHRcdFx0cmVxdWlyZWQ6IHRydWUsXG5cdFx0XHRkZXNjcmlwdGlvbjogYE1hcCBvZiBzY3JpcHRzIHRvIHJ1bi5gLFxuXHRcdFx0ZXhhbXBsZTogYC0tc2NyaXB0cz1cIntcXFxcXCJkb3dubG9hZFxcXFxcIjpcXFxcXCJucG0gaVwiLFxcXFxcImluc3RhbGxcXFxcXCI6XFxcXFwibnBtIHJ1biBidWlsZFxcXFxcIn1cImAsXG5cdFx0XHRwYXJzZTogSlNPTi5wYXJzZSxcblx0XHR9LFxuXHRcdGpzb25Mb2dnaW5nOiB7XG5cdFx0XHRmbGFnOiBgamAsXG5cdFx0XHRyZXF1aXJlZDogZmFsc2UsXG5cdFx0XHRkZXNjcmlwdGlvbjogYEVuYWJsZSBqc29uIGxvZ2dpbmcuYCxcblx0XHRcdGV4YW1wbGU6IGAtLWpzb25Mb2dnaW5nYCxcblx0XHRcdHBhcnNlOiBwYXJzZUJvb2xlYW5PcHRpb24sXG5cdFx0fSxcblx0fSxcbn0gc2F0aXNmaWVzIE9wdGlvbnNHcm91cDxGbGlnaHREZWNrT3B0aW9ucz5cblxuY29uc3QgU0NIRU1BX01BTlVBTCA9IHtcblx0b3B0aW9uc1NjaGVtYTogei5vYmplY3Qoe1xuXHRcdG91dGRpcjogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuXHR9KSxcblx0b3B0aW9uczoge1xuXHRcdG91dGRpcjoge1xuXHRcdFx0ZmxhZzogYG9gLFxuXHRcdFx0cmVxdWlyZWQ6IGZhbHNlLFxuXHRcdFx0ZGVzY3JpcHRpb246IGBEaXJlY3RvcnkgdG8gd3JpdGUgdGhlIHNjaGVtYSB0by5gLFxuXHRcdFx0ZXhhbXBsZTogYC0tb3V0ZGlyPS4vZGlzdGAsXG5cdFx0fSxcblx0fSxcbn0gc2F0aXNmaWVzIE9wdGlvbnNHcm91cDx7IG91dGRpcj86IHN0cmluZyB8IHVuZGVmaW5lZCB9PlxuXG5jb25zdCBwYXJzZSA9IGNsaShcblx0e1xuXHRcdGNsaU5hbWU6IGBmbGlnaHRkZWNrYCxcblx0XHRyb3V0ZXM6IG9wdGlvbmFsKHsgc2NoZW1hOiBudWxsLCAkY29uZmlnUGF0aDogbnVsbCB9KSxcblx0XHRyb3V0ZU9wdGlvbnM6IHtcblx0XHRcdFwiXCI6IEZMSUdIVERFQ0tfTUFOVUFMLFxuXHRcdFx0JGNvbmZpZ1BhdGg6IEZMSUdIVERFQ0tfTUFOVUFMLFxuXHRcdFx0c2NoZW1hOiBTQ0hFTUFfTUFOVUFMLFxuXHRcdH0sXG5cdFx0ZGVidWdPdXRwdXQ6IHRydWUsXG5cdFx0ZGlzY292ZXJDb25maWdQYXRoOiAoYXJncykgPT4ge1xuXHRcdFx0aWYgKGFyZ3NbMF0gPT09IGBzY2hlbWFgKSB7XG5cdFx0XHRcdHJldHVyblxuXHRcdFx0fVxuXHRcdFx0Y29uc3QgY29uZmlnUGF0aCA9XG5cdFx0XHRcdGFyZ3NbMF0gPz8gcGF0aC5qb2luKHByb2Nlc3MuY3dkKCksIGBmbGlnaHRkZWNrLmNvbmZpZy5qc29uYClcblx0XHRcdHJldHVybiBjb25maWdQYXRoXG5cdFx0fSxcblx0fSxcblx0Y29uc29sZSxcbilcblxuY29uc3QgeyBpbnB1dHMsIHdyaXRlSnNvblNjaGVtYSB9ID0gcGFyc2UocHJvY2Vzcy5hcmd2KVxuXG5zd2l0Y2ggKGlucHV0cy5jYXNlKSB7XG5cdGNhc2UgYHNjaGVtYWA6XG5cdFx0e1xuXHRcdFx0Y29uc3QgeyBvdXRkaXIgfSA9IGlucHV0cy5vcHRzXG5cdFx0XHR3cml0ZUpzb25TY2hlbWEob3V0ZGlyID8/IGAuYClcblx0XHR9XG5cdFx0YnJlYWtcblx0ZGVmYXVsdDoge1xuXHRcdGNvbnN0IGZsaWdodERlY2sgPSBuZXcgRmxpZ2h0RGVjayhpbnB1dHMub3B0cylcblx0XHRwcm9jZXNzLm9uKGBjbG9zZWAsIGFzeW5jICgpID0+IHtcblx0XHRcdGF3YWl0IGZsaWdodERlY2suc3RvcEFsbFNlcnZpY2VzKClcblx0XHR9KVxuXHR9XG59XG4iLAogICAgImltcG9ydCB7IGV4ZWNTeW5jLCBzcGF3biB9IGZyb20gXCJub2RlOmNoaWxkX3Byb2Nlc3NcIlxuaW1wb3J0IHR5cGUgeyBTZXJ2ZXIgfSBmcm9tIFwibm9kZTpodHRwXCJcbmltcG9ydCB7IGNyZWF0ZVNlcnZlciB9IGZyb20gXCJub2RlOmh0dHBcIlxuaW1wb3J0IHsgaG9tZWRpciB9IGZyb20gXCJub2RlOm9zXCJcbmltcG9ydCB7IHJlc29sdmUgfSBmcm9tIFwibm9kZTpwYXRoXCJcbmltcG9ydCB7IGluc3BlY3QgfSBmcm9tIFwibm9kZTp1dGlsXCJcblxuaW1wb3J0IHsgRnV0dXJlIH0gZnJvbSBcImF0b20uaW8vaW50ZXJuYWxcIlxuaW1wb3J0IHsgZGlzY292ZXJUeXBlIH0gZnJvbSBcImF0b20uaW8vaW50cm9zcGVjdGlvblwiXG5pbXBvcnQgeyBmcm9tRW50cmllcywgdG9FbnRyaWVzIH0gZnJvbSBcImF0b20uaW8vanNvblwiXG5pbXBvcnQgeyBDaGlsZFNvY2tldCB9IGZyb20gXCJhdG9tLmlvL3JlYWx0aW1lLXNlcnZlclwiXG5pbXBvcnQgeyBDcm9uSm9iIH0gZnJvbSBcImNyb25cIlxuaW1wb3J0IHsgeiB9IGZyb20gXCJ6b2RcIlxuXG5pbXBvcnQgdHlwZSB7IExuYXZGb3JtYXQgfSBmcm9tIFwiLi4vZ2VuL2xuYXYtZm9ybWF0LXNjaGVtYS5nZW5cIlxuaW1wb3J0IHsgRmlsZXN5c3RlbVN0b3JhZ2UgfSBmcm9tIFwiLi9maWxlc3lzdGVtLXN0b3JhZ2VcIlxuaW1wb3J0IHsgZW52IH0gZnJvbSBcIi4vZmxpZ2h0ZGVjay5lbnZcIlxuXG5leHBvcnQgY29uc3QgRkxJR0hUREVDS19TRVRVUF9QSEFTRVMgPSBbYGRvd25sb2FkZWRgLCBgaW5zdGFsbGVkYF0gYXMgY29uc3RcblxuZXhwb3J0IHR5cGUgRmxpZ2h0RGVja1NldHVwUGhhc2UgPSAodHlwZW9mIEZMSUdIVERFQ0tfU0VUVVBfUEhBU0VTKVtudW1iZXJdXG5cbmV4cG9ydCBjb25zdCBGTElHSFRERUNLX1VQREFURV9QSEFTRVMgPSBbYG5vdGlmaWVkYCwgYGNvbmZpcm1lZGBdIGFzIGNvbnN0XG5cbmV4cG9ydCB0eXBlIEZsaWdodERlY2tVcGRhdGVQaGFzZSA9ICh0eXBlb2YgRkxJR0hUREVDS19VUERBVEVfUEhBU0VTKVtudW1iZXJdXG5cbmV4cG9ydCBmdW5jdGlvbiBpc1ZlcnNpb25OdW1iZXIodmVyc2lvbjogc3RyaW5nKTogYm9vbGVhbiB7XG5cdHJldHVybiAoXG5cdFx0L15cXGQrXFwuXFxkK1xcLlxcZCskLy50ZXN0KHZlcnNpb24pIHx8ICFOdW1iZXIuaXNOYU4oTnVtYmVyLnBhcnNlRmxvYXQodmVyc2lvbikpXG5cdClcbn1cblxuZXhwb3J0IHR5cGUgRmxpZ2h0RGVja09wdGlvbnM8UyBleHRlbmRzIHN0cmluZyA9IHN0cmluZz4gPSB7XG5cdHBhY2thZ2VOYW1lOiBzdHJpbmdcblx0c2VydmljZXM6IHsgW3NlcnZpY2UgaW4gU106IHsgcnVuOiBzdHJpbmc7IHdhaXRGb3I6IGJvb2xlYW4gfSB9XG5cdHNjcmlwdHM6IHtcblx0XHRkb3dubG9hZDogc3RyaW5nXG5cdFx0aW5zdGFsbDogc3RyaW5nXG5cdFx0Y2hlY2tBdmFpbGFiaWxpdHk/OiBzdHJpbmdcblx0fVxuXHRwb3J0PzogbnVtYmVyIHwgdW5kZWZpbmVkXG5cdGZsaWdodGRlY2tSb290RGlyPzogc3RyaW5nIHwgdW5kZWZpbmVkXG5cdGpzb25Mb2dnaW5nPzogYm9vbGVhbiB8IHVuZGVmaW5lZFxufVxuXG5leHBvcnQgY2xhc3MgRmxpZ2h0RGVjazxTIGV4dGVuZHMgc3RyaW5nID0gc3RyaW5nPiB7XG5cdHByb3RlY3RlZCBzYWZldHkgPSAwXG5cblx0cHJvdGVjdGVkIHN0b3JhZ2U6IEZpbGVzeXN0ZW1TdG9yYWdlPHtcblx0XHRzZXR1cFBoYXNlOiBGbGlnaHREZWNrU2V0dXBQaGFzZVxuXHRcdHVwZGF0ZVBoYXNlOiBGbGlnaHREZWNrVXBkYXRlUGhhc2Vcblx0XHR1cGRhdGVBd2FpdGVkVmVyc2lvbjogc3RyaW5nXG5cdH0+XG5cdHByb3RlY3RlZCB3ZWJob29rU2VydmVyOiBTZXJ2ZXJcblx0cHJvdGVjdGVkIHNlcnZpY2VzOiB7XG5cdFx0W3NlcnZpY2UgaW4gU106IENoaWxkU29ja2V0PFxuXHRcdFx0eyB0aW1lVG9TdG9wOiBbXTsgdXBkYXRlc1JlYWR5OiBbXSB9LFxuXHRcdFx0eyByZWFkeVRvVXBkYXRlOiBbXTsgYWxpdmU6IFtdIH1cblx0XHQ+IHwgbnVsbFxuXHR9XG5cdHByb3RlY3RlZCBzZXJ2aWNlSWR4OiB7IHJlYWRvbmx5IFtzZXJ2aWNlIGluIFNdOiBudW1iZXIgfVxuXHRwdWJsaWMgZGVmYXVsdFNlcnZpY2VzUmVhZHlUb1VwZGF0ZTogeyByZWFkb25seSBbc2VydmljZSBpbiBTXTogYm9vbGVhbiB9XG5cdHB1YmxpYyBzZXJ2aWNlc1JlYWR5VG9VcGRhdGU6IHsgW3NlcnZpY2UgaW4gU106IGJvb2xlYW4gfVxuXHRwdWJsaWMgYXV0b1Jlc3Bhd25EZWFkU2VydmljZXM6IGJvb2xlYW5cblxuXHRwcm90ZWN0ZWQgbG9nZ2VyOiBQaWNrPENvbnNvbGUsIGBlcnJvcmAgfCBgaW5mb2AgfCBgd2FybmA+XG5cdHByb3RlY3RlZCBzZXJ2aWNlTG9nZ2Vyczoge1xuXHRcdHJlYWRvbmx5IFtzZXJ2aWNlIGluIFNdOiBGbGlnaHREZWNrTG9nZ2VyXG5cdH1cblxuXHRwcm90ZWN0ZWQgdXBkYXRlQXZhaWxhYmlsaXR5Q2hlY2tlcjogQ3JvbkpvYiB8IG51bGwgPSBudWxsXG5cblx0cHVibGljIHNlcnZpY2VzTGl2ZTogRnV0dXJlPHZvaWQ+W11cblx0cHVibGljIHNlcnZpY2VzRGVhZDogRnV0dXJlPHZvaWQ+W11cblx0cHVibGljIGxpdmUgPSBuZXcgRnV0dXJlKCgpID0+IHt9KVxuXHRwdWJsaWMgZGVhZCA9IG5ldyBGdXR1cmUoKCkgPT4ge30pXG5cblx0cHJvdGVjdGVkIHJlc3RhcnRUaW1lczogbnVtYmVyW10gPSBbXVxuXG5cdHB1YmxpYyBjb25zdHJ1Y3RvcihwdWJsaWMgcmVhZG9ubHkgb3B0aW9uczogRmxpZ2h0RGVja09wdGlvbnM8Uz4pIHtcblx0XHRjb25zdCB7IEZMSUdIVERFQ0tfU0VDUkVUIH0gPSBlbnZcblx0XHRjb25zdCB7IGZsaWdodGRlY2tSb290RGlyID0gcmVzb2x2ZShob21lZGlyKCksIGAuZmxpZ2h0ZGVja2ApIH0gPSBvcHRpb25zXG5cdFx0Y29uc3QgcG9ydCA9IG9wdGlvbnMucG9ydCA/PyA4MDgwXG5cdFx0Y29uc3Qgb3JpZ2luID0gYGh0dHA6Ly9sb2NhbGhvc3Q6JHtwb3J0fWBcblxuXHRcdGNvbnN0IHNlcnZpY2VzRW50cmllcyA9IHRvRW50cmllcyhvcHRpb25zLnNlcnZpY2VzKVxuXHRcdHRoaXMuc2VydmljZXMgPSBmcm9tRW50cmllcyhcblx0XHRcdHNlcnZpY2VzRW50cmllcy5tYXAoKFtzZXJ2aWNlTmFtZV0pID0+IFtzZXJ2aWNlTmFtZSwgbnVsbF0pLFxuXHRcdClcblx0XHR0aGlzLnNlcnZpY2VJZHggPSBmcm9tRW50cmllcyhcblx0XHRcdHNlcnZpY2VzRW50cmllcy5tYXAoKFtzZXJ2aWNlTmFtZV0sIGlkeCkgPT4gW3NlcnZpY2VOYW1lLCBpZHhdKSxcblx0XHQpXG5cdFx0dGhpcy5kZWZhdWx0U2VydmljZXNSZWFkeVRvVXBkYXRlID0gZnJvbUVudHJpZXMoXG5cdFx0XHRzZXJ2aWNlc0VudHJpZXMubWFwKChbc2VydmljZU5hbWUsIHsgd2FpdEZvciB9XSkgPT4gW1xuXHRcdFx0XHRzZXJ2aWNlTmFtZSxcblx0XHRcdFx0IXdhaXRGb3IsXG5cdFx0XHRdKSxcblx0XHQpXG5cdFx0dGhpcy5zZXJ2aWNlc1JlYWR5VG9VcGRhdGUgPSB7IC4uLnRoaXMuZGVmYXVsdFNlcnZpY2VzUmVhZHlUb1VwZGF0ZSB9XG5cdFx0dGhpcy5hdXRvUmVzcGF3bkRlYWRTZXJ2aWNlcyA9IHRydWVcblxuXHRcdHRoaXMubG9nZ2VyID0gbmV3IEZsaWdodERlY2tMb2dnZXIoXG5cdFx0XHR0aGlzLm9wdGlvbnMucGFja2FnZU5hbWUsXG5cdFx0XHRwcm9jZXNzLnBpZCxcblx0XHRcdHVuZGVmaW5lZCxcblx0XHRcdHsganNvbkxvZ2dpbmc6IHRoaXMub3B0aW9ucy5qc29uTG9nZ2luZyA/PyBmYWxzZSB9LFxuXHRcdClcblx0XHR0aGlzLnNlcnZpY2VMb2dnZXJzID0gZnJvbUVudHJpZXMoXG5cdFx0XHRzZXJ2aWNlc0VudHJpZXMubWFwKChbc2VydmljZU5hbWVdKSA9PiBbXG5cdFx0XHRcdHNlcnZpY2VOYW1lLFxuXHRcdFx0XHRuZXcgRmxpZ2h0RGVja0xvZ2dlcihcblx0XHRcdFx0XHR0aGlzLm9wdGlvbnMucGFja2FnZU5hbWUsXG5cdFx0XHRcdFx0cHJvY2Vzcy5waWQsXG5cdFx0XHRcdFx0c2VydmljZU5hbWUsXG5cdFx0XHRcdFx0eyBqc29uTG9nZ2luZzogdGhpcy5vcHRpb25zLmpzb25Mb2dnaW5nID8/IGZhbHNlIH0sXG5cdFx0XHRcdCksXG5cdFx0XHRdKSxcblx0XHQpXG5cblx0XHR0aGlzLnNlcnZpY2VzTGl2ZSA9IHNlcnZpY2VzRW50cmllcy5tYXAoKCkgPT4gbmV3IEZ1dHVyZSgoKSA9PiB7fSkpXG5cdFx0dGhpcy5zZXJ2aWNlc0RlYWQgPSBzZXJ2aWNlc0VudHJpZXMubWFwKCgpID0+IG5ldyBGdXR1cmUoKCkgPT4ge30pKVxuXHRcdHRoaXMubGl2ZS51c2UoUHJvbWlzZS5hbGwodGhpcy5zZXJ2aWNlc0xpdmUpKVxuXHRcdHRoaXMuZGVhZC51c2UoUHJvbWlzZS5hbGwodGhpcy5zZXJ2aWNlc0RlYWQpKVxuXG5cdFx0dGhpcy5zdG9yYWdlID0gbmV3IEZpbGVzeXN0ZW1TdG9yYWdlKHtcblx0XHRcdHBhdGg6IHJlc29sdmUoZmxpZ2h0ZGVja1Jvb3REaXIsIGBzdG9yYWdlYCwgb3B0aW9ucy5wYWNrYWdlTmFtZSksXG5cdFx0fSlcblxuXHRcdGlmIChGTElHSFRERUNLX1NFQ1JFVCA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHR0aGlzLmxvZ2dlci53YXJuKFxuXHRcdFx0XHRgTm8gRkxJR0hUREVDS19TRUNSRVQgZW52aXJvbm1lbnQgdmFyaWFibGUgZm91bmQuIEZsaWdodERlY2sgd2lsbCBub3QgcnVuIGFuIHVwZGF0ZSBzZXJ2ZXIuYCxcblx0XHRcdClcblx0XHR9IGVsc2Uge1xuXHRcdFx0Y3JlYXRlU2VydmVyKChyZXEsIHJlcykgPT4ge1xuXHRcdFx0XHRsZXQgZGF0YTogVWludDhBcnJheVtdID0gW11cblx0XHRcdFx0cmVxXG5cdFx0XHRcdFx0Lm9uKGBkYXRhYCwgKGNodW5rKSA9PiB7XG5cdFx0XHRcdFx0XHRkYXRhLnB1c2goY2h1bmsgaW5zdGFuY2VvZiBCdWZmZXIgPyBjaHVuayA6IEJ1ZmZlci5mcm9tKGNodW5rKSlcblx0XHRcdFx0XHR9KVxuXHRcdFx0XHRcdC5vbihgZW5kYCwgKCkgPT4ge1xuXHRcdFx0XHRcdFx0Y29uc3QgYXV0aEhlYWRlciA9IHJlcS5oZWFkZXJzLmF1dGhvcml6YXRpb25cblx0XHRcdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0XHRcdGlmICh0eXBlb2YgcmVxLnVybCA9PT0gYHVuZGVmaW5lZGApIHRocm93IDQwMFxuXHRcdFx0XHRcdFx0XHRjb25zdCBleHBlY3RlZEF1dGhIZWFkZXIgPSBgQmVhcmVyICR7RkxJR0hUREVDS19TRUNSRVR9YFxuXHRcdFx0XHRcdFx0XHRpZiAoYXV0aEhlYWRlciAhPT0gYEJlYXJlciAke0ZMSUdIVERFQ0tfU0VDUkVUfWApIHtcblx0XHRcdFx0XHRcdFx0XHR0aGlzLmxvZ2dlci5pbmZvKFxuXHRcdFx0XHRcdFx0XHRcdFx0YFVuYXV0aG9yaXplZDogbmVlZGVkIFxcYCR7ZXhwZWN0ZWRBdXRoSGVhZGVyfVxcYCwgZ290IFxcYCR7YXV0aEhlYWRlcn1cXGBgLFxuXHRcdFx0XHRcdFx0XHRcdClcblx0XHRcdFx0XHRcdFx0XHR0aHJvdyA0MDFcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRjb25zdCB1cmwgPSBuZXcgVVJMKHJlcS51cmwsIG9yaWdpbilcblx0XHRcdFx0XHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhyZXEubWV0aG9kLCB1cmwucGF0aG5hbWUpXG5cblx0XHRcdFx0XHRcdFx0Y29uc3QgdmVyc2lvbkZvcmVpZ25JbnB1dCA9IEJ1ZmZlci5jb25jYXQoZGF0YSkudG9TdHJpbmcoKVxuXHRcdFx0XHRcdFx0XHRpZiAoIWlzVmVyc2lvbk51bWJlcih2ZXJzaW9uRm9yZWlnbklucHV0KSkge1xuXHRcdFx0XHRcdFx0XHRcdHRocm93IDQwMFxuXHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0cmVzLndyaXRlSGVhZCgyMDApXG5cdFx0XHRcdFx0XHRcdHJlcy5lbmQoKVxuXG5cdFx0XHRcdFx0XHRcdHRoaXMuc3RvcmFnZS5zZXRJdGVtKGB1cGRhdGVQaGFzZWAsIGBub3RpZmllZGApXG5cdFx0XHRcdFx0XHRcdHRoaXMuc3RvcmFnZS5zZXRJdGVtKGB1cGRhdGVBd2FpdGVkVmVyc2lvbmAsIHZlcnNpb25Gb3JlaWduSW5wdXQpXG5cdFx0XHRcdFx0XHRcdGNvbnN0IHsgY2hlY2tBdmFpbGFiaWxpdHkgfSA9IG9wdGlvbnMuc2NyaXB0c1xuXHRcdFx0XHRcdFx0XHRpZiAoY2hlY2tBdmFpbGFiaWxpdHkpIHtcblx0XHRcdFx0XHRcdFx0XHR0aGlzLnVwZGF0ZUF2YWlsYWJpbGl0eUNoZWNrZXI/LnN0b3AoKVxuXHRcdFx0XHRcdFx0XHRcdHRoaXMuc2Vla1VwZGF0ZSh2ZXJzaW9uRm9yZWlnbklucHV0KVxuXHRcdFx0XHRcdFx0XHRcdGNvbnN0IHVwZGF0ZVBoYXNlID0gdGhpcy5zdG9yYWdlLmdldEl0ZW0oYHVwZGF0ZVBoYXNlYClcblx0XHRcdFx0XHRcdFx0XHR0aGlzLmxvZ2dlci5pbmZvKGA+IHN0b3JhZ2UoXCJ1cGRhdGVQaGFzZVwiKSA+YCwgdXBkYXRlUGhhc2UpXG5cdFx0XHRcdFx0XHRcdFx0aWYgKHVwZGF0ZVBoYXNlID09PSBgbm90aWZpZWRgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHR0aGlzLnVwZGF0ZUF2YWlsYWJpbGl0eUNoZWNrZXIgPSBuZXcgQ3JvbkpvYihcblx0XHRcdFx0XHRcdFx0XHRcdFx0YDMwICogKiAqICogKmAsXG5cdFx0XHRcdFx0XHRcdFx0XHRcdCgpID0+IHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHR0aGlzLnNlZWtVcGRhdGUodmVyc2lvbkZvcmVpZ25JbnB1dClcblx0XHRcdFx0XHRcdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRcdFx0XHRcdClcblx0XHRcdFx0XHRcdFx0XHRcdHRoaXMudXBkYXRlQXZhaWxhYmlsaXR5Q2hlY2tlci5zdGFydCgpXG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRcdHRoaXMuZG93bmxvYWRQYWNrYWdlKClcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fSBjYXRjaCAodGhyb3duKSB7XG5cdFx0XHRcdFx0XHRcdHRoaXMubG9nZ2VyLmVycm9yKHRocm93biwgcmVxLnVybClcblx0XHRcdFx0XHRcdFx0aWYgKHR5cGVvZiB0aHJvd24gPT09IGBudW1iZXJgKSB7XG5cdFx0XHRcdFx0XHRcdFx0cmVzLndyaXRlSGVhZCh0aHJvd24pXG5cdFx0XHRcdFx0XHRcdFx0cmVzLmVuZCgpXG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH0gZmluYWxseSB7XG5cdFx0XHRcdFx0XHRcdGRhdGEgPSBbXVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0pXG5cdFx0XHR9KS5saXN0ZW4ocG9ydCwgKCkgPT4ge1xuXHRcdFx0XHR0aGlzLmxvZ2dlci5pbmZvKGBTZXJ2ZXIgc3RhcnRlZCBvbiBwb3J0ICR7cG9ydH1gKVxuXHRcdFx0fSlcblx0XHR9XG5cblx0XHR0aGlzLnN0YXJ0QWxsU2VydmljZXMoKVxuXHRcdFx0LnRoZW4oKCkgPT4ge1xuXHRcdFx0XHR0aGlzLmxvZ2dlci5pbmZvKGBBbGwgc2VydmljZXMgc3RhcnRlZC5gKVxuXHRcdFx0fSlcblx0XHRcdC5jYXRjaCgodGhyb3duKSA9PiB7XG5cdFx0XHRcdGlmICh0aHJvd24gaW5zdGFuY2VvZiBFcnJvcikge1xuXHRcdFx0XHRcdHRoaXMubG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gc3RhcnQgYWxsIHNlcnZpY2VzOmAsIHRocm93bi5tZXNzYWdlKVxuXHRcdFx0XHR9XG5cdFx0XHR9KVxuXHR9XG5cblx0cHJvdGVjdGVkIHNlZWtVcGRhdGUodmVyc2lvbjogc3RyaW5nKTogdm9pZCB7XG5cdFx0dGhpcy5sb2dnZXIuaW5mbyhgQ2hlY2tpbmcgZm9yIHVwZGF0ZXMuLi5gKVxuXHRcdGNvbnN0IHsgY2hlY2tBdmFpbGFiaWxpdHkgfSA9IHRoaXMub3B0aW9ucy5zY3JpcHRzXG5cdFx0aWYgKCFjaGVja0F2YWlsYWJpbGl0eSkge1xuXHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhgTm8gY2hlY2tBdmFpbGFiaWxpdHkgc2NyaXB0IGZvdW5kLmApXG5cdFx0XHRyZXR1cm5cblx0XHR9XG5cdFx0dHJ5IHtcblx0XHRcdGNvbnN0IG91dCA9IGV4ZWNTeW5jKGAke2NoZWNrQXZhaWxhYmlsaXR5fSAke3ZlcnNpb259YClcblx0XHRcdHRoaXMubG9nZ2VyLmluZm8oYENoZWNrIHN0ZG91dDpgLCBvdXQudG9TdHJpbmcoKSlcblx0XHRcdHRoaXMudXBkYXRlQXZhaWxhYmlsaXR5Q2hlY2tlcj8uc3RvcCgpXG5cdFx0XHR0aGlzLnN0b3JhZ2Uuc2V0SXRlbShgdXBkYXRlUGhhc2VgLCBgY29uZmlybWVkYClcblx0XHRcdHRoaXMuZG93bmxvYWRQYWNrYWdlKClcblx0XHRcdHRoaXMuYW5ub3VuY2VVcGRhdGUoKVxuXHRcdH0gY2F0Y2ggKHRocm93bikge1xuXHRcdFx0aWYgKHRocm93biBpbnN0YW5jZW9mIEVycm9yKSB7XG5cdFx0XHRcdHRoaXMubG9nZ2VyLmVycm9yKGBDaGVjayBmYWlsZWQ6YCwgdGhyb3duLm1lc3NhZ2UpXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRjb25zdCB0aHJvd25UeXBlID0gZGlzY292ZXJUeXBlKHRocm93bilcblx0XHRcdFx0dGhpcy5sb2dnZXIuZXJyb3IoYENoZWNrIHRocmV3YCwgdGhyb3duVHlwZSwgdGhyb3duKVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHByb3RlY3RlZCBhbm5vdW5jZVVwZGF0ZSgpOiB2b2lkIHtcblx0XHRmb3IgKGNvbnN0IGVudHJ5IG9mIHRvRW50cmllcyh0aGlzLnNlcnZpY2VzKSkge1xuXHRcdFx0Y29uc3QgW3NlcnZpY2VOYW1lLCBzZXJ2aWNlXSA9IGVudHJ5XG5cdFx0XHRpZiAoc2VydmljZSkge1xuXHRcdFx0XHRpZiAodGhpcy5vcHRpb25zLnNlcnZpY2VzW3NlcnZpY2VOYW1lXS53YWl0Rm9yKSB7XG5cdFx0XHRcdFx0c2VydmljZS5lbWl0KGB1cGRhdGVzUmVhZHlgKVxuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0aGlzLnN0YXJ0U2VydmljZShzZXJ2aWNlTmFtZSlcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRwcm90ZWN0ZWQgdHJ5VXBkYXRlKCk6IHZvaWQge1xuXHRcdGlmICh0b0VudHJpZXModGhpcy5zZXJ2aWNlc1JlYWR5VG9VcGRhdGUpLmV2ZXJ5KChbLCBpc1JlYWR5XSkgPT4gaXNSZWFkeSkpIHtcblx0XHRcdHRoaXMubG9nZ2VyLmluZm8oYEFsbCBzZXJ2aWNlcyBhcmUgcmVhZHkgdG8gdXBkYXRlLmApXG5cdFx0XHR0aGlzLnN0b3BBbGxTZXJ2aWNlcygpXG5cdFx0XHRcdC50aGVuKCgpID0+IHtcblx0XHRcdFx0XHR0aGlzLmxvZ2dlci5pbmZvKGBBbGwgc2VydmljZXMgc3RvcHBlZDsgc3RhcnRpbmcgdXAgZnJlc2guLi5gKVxuXHRcdFx0XHRcdHRoaXMuc3RhcnRBbGxTZXJ2aWNlcygpXG5cdFx0XHRcdFx0XHQudGhlbigoKSA9PiB7XG5cdFx0XHRcdFx0XHRcdHRoaXMubG9nZ2VyLmluZm8oYEFsbCBzZXJ2aWNlcyBzdGFydGVkOyB3ZSdyZSBiYWNrIG9ubGluZS5gKVxuXHRcdFx0XHRcdFx0fSlcblx0XHRcdFx0XHRcdC5jYXRjaCgodGhyb3duKSA9PiB7XG5cdFx0XHRcdFx0XHRcdGlmICh0aHJvd24gaW5zdGFuY2VvZiBFcnJvcikge1xuXHRcdFx0XHRcdFx0XHRcdHRoaXMubG9nZ2VyLmVycm9yKFxuXHRcdFx0XHRcdFx0XHRcdFx0YEZhaWxlZCB0byBzdGFydCBhbGwgc2VydmljZXM6YCxcblx0XHRcdFx0XHRcdFx0XHRcdHRocm93bi5tZXNzYWdlLFxuXHRcdFx0XHRcdFx0XHRcdClcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fSlcblx0XHRcdFx0fSlcblx0XHRcdFx0LmNhdGNoKCh0aHJvd24pID0+IHtcblx0XHRcdFx0XHRpZiAodGhyb3duIGluc3RhbmNlb2YgRXJyb3IpIHtcblx0XHRcdFx0XHRcdHRoaXMubG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gc3RvcCBhbGwgc2VydmljZXM6YCwgdGhyb3duLm1lc3NhZ2UpXG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KVxuXHRcdH1cblx0fVxuXG5cdHByb3RlY3RlZCBzdGFydEFsbFNlcnZpY2VzKCk6IEZ1dHVyZTx1bmtub3duPiB7XG5cdFx0dGhpcy5sb2dnZXIuaW5mbyhgU3RhcnRpbmcgYWxsIHNlcnZpY2VzLi4uYClcblx0XHR0aGlzLmF1dG9SZXNwYXduRGVhZFNlcnZpY2VzID0gdHJ1ZVxuXHRcdGNvbnN0IHNldHVwUGhhc2UgPSB0aGlzLnN0b3JhZ2UuZ2V0SXRlbShgc2V0dXBQaGFzZWApXG5cdFx0dGhpcy5sb2dnZXIuaW5mbyhgPiBzdG9yYWdlKFwic2V0dXBQaGFzZVwiKSA+YCwgc2V0dXBQaGFzZSlcblx0XHRzd2l0Y2ggKHNldHVwUGhhc2UpIHtcblx0XHRcdGNhc2UgbnVsbDpcblx0XHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhgU3RhcnRpbmcgZnJvbSBzY3JhdGNoLmApXG5cdFx0XHRcdHRoaXMuZG93bmxvYWRQYWNrYWdlKClcblx0XHRcdFx0dGhpcy5pbnN0YWxsUGFja2FnZSgpXG5cdFx0XHRcdHJldHVybiB0aGlzLnN0YXJ0QWxsU2VydmljZXMoKVxuXHRcdFx0Y2FzZSBgZG93bmxvYWRlZGA6XG5cdFx0XHRcdHRoaXMubG9nZ2VyLmluZm8oYEZvdW5kIHBhY2thZ2UgZG93bmxvYWRlZCBidXQgbm90IGluc3RhbGxlZC5gKVxuXHRcdFx0XHR0aGlzLmluc3RhbGxQYWNrYWdlKClcblx0XHRcdFx0cmV0dXJuIHRoaXMuc3RhcnRBbGxTZXJ2aWNlcygpXG5cdFx0XHRjYXNlIGBpbnN0YWxsZWRgOiB7XG5cdFx0XHRcdGZvciAoY29uc3QgW3NlcnZpY2VOYW1lXSBvZiB0b0VudHJpZXModGhpcy5zZXJ2aWNlcykpIHtcblx0XHRcdFx0XHR0aGlzLnN0YXJ0U2VydmljZShzZXJ2aWNlTmFtZSlcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gdGhpcy5saXZlXG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0cHJvdGVjdGVkIHN0YXJ0U2VydmljZShzZXJ2aWNlTmFtZTogUyk6IHZvaWQge1xuXHRcdHRoaXMubG9nZ2VyLmluZm8oXG5cdFx0XHRgU3RhcnRpbmcgc2VydmljZSAke3RoaXMub3B0aW9ucy5wYWNrYWdlTmFtZX06OiR7c2VydmljZU5hbWV9LCB0cnkgJHt0aGlzLnNhZmV0eX0vMi4uLmAsXG5cdFx0KVxuXHRcdGlmICh0aGlzLnNhZmV0eSA+PSAyKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoYE91dCBvZiB0cmllcy4uLmApXG5cdFx0fVxuXHRcdHRoaXMuc2FmZXR5KytcblxuXHRcdGNvbnN0IFtleGUsIC4uLmFyZ3NdID0gdGhpcy5vcHRpb25zLnNlcnZpY2VzW3NlcnZpY2VOYW1lXS5ydW4uc3BsaXQoYCBgKVxuXHRcdGNvbnN0IHNlcnZpY2VQcm9jZXNzID0gc3Bhd24oZXhlLCBhcmdzLCB7XG5cdFx0XHRjd2Q6IHRoaXMub3B0aW9ucy5mbGlnaHRkZWNrUm9vdERpcixcblx0XHRcdGVudjogaW1wb3J0Lm1ldGEuZW52LFxuXHRcdH0pXG5cdFx0Y29uc3Qgc2VydmljZUxvZ2dlciA9IHRoaXMuc2VydmljZUxvZ2dlcnNbc2VydmljZU5hbWVdXG5cdFx0Y29uc3Qgc2VydmljZSA9ICh0aGlzLnNlcnZpY2VzW3NlcnZpY2VOYW1lXSA9IG5ldyBDaGlsZFNvY2tldChcblx0XHRcdHNlcnZpY2VQcm9jZXNzLFxuXHRcdFx0YCR7dGhpcy5vcHRpb25zLnBhY2thZ2VOYW1lfTo6JHtzZXJ2aWNlTmFtZX1gLFxuXHRcdFx0c2VydmljZUxvZ2dlcixcblx0XHQpKVxuXHRcdHNlcnZpY2VMb2dnZXIucHJvY2Vzc0NvZGUgPSBzZXJ2aWNlLnByb2Nlc3MucGlkID8/IC0xXG5cdFx0dGhpcy5zZXJ2aWNlc1tzZXJ2aWNlTmFtZV0ub25BbnkoKC4uLm1lc3NhZ2VzKSA9PiB7XG5cdFx0XHRzZXJ2aWNlTG9nZ2VyLmluZm8oYPCfkqxgLCAuLi5tZXNzYWdlcylcblx0XHR9KVxuXHRcdHRoaXMuc2VydmljZXNbc2VydmljZU5hbWVdLm9uKGByZWFkeVRvVXBkYXRlYCwgKCkgPT4ge1xuXHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhgU2VydmljZSBcIiR7c2VydmljZU5hbWV9XCIgaXMgcmVhZHkgdG8gdXBkYXRlLmApXG5cdFx0XHR0aGlzLnNlcnZpY2VzUmVhZHlUb1VwZGF0ZVtzZXJ2aWNlTmFtZV0gPSB0cnVlXG5cdFx0XHR0aGlzLnRyeVVwZGF0ZSgpXG5cdFx0fSlcblx0XHR0aGlzLnNlcnZpY2VzW3NlcnZpY2VOYW1lXS5vbihgYWxpdmVgLCAoKSA9PiB7XG5cdFx0XHR0aGlzLnNlcnZpY2VzTGl2ZVt0aGlzLnNlcnZpY2VJZHhbc2VydmljZU5hbWVdXS51c2UoUHJvbWlzZS5yZXNvbHZlKCkpXG5cdFx0XHR0aGlzLnNlcnZpY2VzRGVhZFt0aGlzLnNlcnZpY2VJZHhbc2VydmljZU5hbWVdXSA9IG5ldyBGdXR1cmUoKCkgPT4ge30pXG5cdFx0XHRpZiAodGhpcy5kZWFkLmRvbmUpIHtcblx0XHRcdFx0dGhpcy5kZWFkID0gbmV3IEZ1dHVyZSgoKSA9PiB7fSlcblx0XHRcdH1cblx0XHRcdHRoaXMuZGVhZC51c2UoUHJvbWlzZS5hbGwodGhpcy5zZXJ2aWNlc0RlYWQpKVxuXHRcdH0pXG5cdFx0dGhpcy5zZXJ2aWNlc1tzZXJ2aWNlTmFtZV0ucHJvY2Vzcy5vbmNlKGBjbG9zZWAsIChleGl0Q29kZSkgPT4ge1xuXHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhcblx0XHRcdFx0YEF1dG8tcmVzcGF3biBzYXcgXCIke3NlcnZpY2VOYW1lfVwiIGV4aXQgd2l0aCBjb2RlICR7ZXhpdENvZGV9YCxcblx0XHRcdClcblx0XHRcdHRoaXMuc2VydmljZXNbc2VydmljZU5hbWVdID0gbnVsbFxuXHRcdFx0aWYgKCF0aGlzLmF1dG9SZXNwYXduRGVhZFNlcnZpY2VzKSB7XG5cdFx0XHRcdHRoaXMubG9nZ2VyLmluZm8oYEF1dG8tcmVzcGF3biBpcyBvZmY7IFwiJHtzZXJ2aWNlTmFtZX1cIiByZXN0cy5gKVxuXHRcdFx0XHRyZXR1cm5cblx0XHRcdH1cblx0XHRcdGNvbnN0IHVwZGF0ZVBoYXNlID0gdGhpcy5zdG9yYWdlLmdldEl0ZW0oYHVwZGF0ZVBoYXNlYClcblx0XHRcdHRoaXMubG9nZ2VyLmluZm8oYD4gc3RvcmFnZShcInVwZGF0ZVBoYXNlXCIpID5gLCB1cGRhdGVQaGFzZSlcblx0XHRcdGNvbnN0IHVwZGF0ZXNBcmVSZWFkeSA9IHVwZGF0ZVBoYXNlID09PSBgY29uZmlybWVkYFxuXHRcdFx0aWYgKHVwZGF0ZXNBcmVSZWFkeSkge1xuXHRcdFx0XHR0aGlzLnNlcnZpY2VMb2dnZXJzW3NlcnZpY2VOYW1lXS5pbmZvKGBVcGRhdGluZyBiZWZvcmUgc3RhcnR1cC4uLmApXG5cdFx0XHRcdHRoaXMucmVzdGFydFRpbWVzID0gW11cblx0XHRcdFx0dGhpcy5pbnN0YWxsUGFja2FnZSgpXG5cdFx0XHRcdHRoaXMuc3RhcnRTZXJ2aWNlKHNlcnZpY2VOYW1lKVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Y29uc3Qgbm93ID0gRGF0ZS5ub3coKVxuXHRcdFx0XHRjb25zdCBmaXZlTWludXRlc0FnbyA9IG5vdyAtIDUgKiA2MCAqIDEwMDBcblx0XHRcdFx0dGhpcy5yZXN0YXJ0VGltZXMgPSB0aGlzLnJlc3RhcnRUaW1lcy5maWx0ZXIoXG5cdFx0XHRcdFx0KHRpbWUpID0+IHRpbWUgPiBmaXZlTWludXRlc0Fnbyxcblx0XHRcdFx0KVxuXHRcdFx0XHR0aGlzLnJlc3RhcnRUaW1lcy5wdXNoKG5vdylcblxuXHRcdFx0XHRpZiAodGhpcy5yZXN0YXJ0VGltZXMubGVuZ3RoIDwgNSkge1xuXHRcdFx0XHRcdHRoaXMuc2VydmljZUxvZ2dlcnNbc2VydmljZU5hbWVdLmluZm8oYENyYXNoZWQuIFJlc3RhcnRpbmcuLi5gKVxuXHRcdFx0XHRcdHRoaXMuc3RhcnRTZXJ2aWNlKHNlcnZpY2VOYW1lKVxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHRoaXMuc2VydmljZUxvZ2dlcnNbc2VydmljZU5hbWVdLmluZm8oXG5cdFx0XHRcdFx0XHRgQ3Jhc2hlZCA1IHRpbWVzIGluIDUgbWludXRlcy4gTm90IHJlc3RhcnRpbmcuYCxcblx0XHRcdFx0XHQpXG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9KVxuXHRcdHRoaXMuc2FmZXR5ID0gMFxuXHR9XG5cblx0cHJvdGVjdGVkIGRvd25sb2FkUGFja2FnZSgpOiB2b2lkIHtcblx0XHR0aGlzLmxvZ2dlci5pbmZvKGBEb3dubG9hZGluZy4uLmApXG5cdFx0dHJ5IHtcblx0XHRcdGNvbnN0IG91dCA9IGV4ZWNTeW5jKHRoaXMub3B0aW9ucy5zY3JpcHRzLmRvd25sb2FkKVxuXHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhgRG93bmxvYWQgc3Rkb3V0OmAsIG91dC50b1N0cmluZygpKVxuXHRcdFx0dGhpcy5zdG9yYWdlLnNldEl0ZW0oYHNldHVwUGhhc2VgLCBgZG93bmxvYWRlZGApXG5cdFx0XHR0aGlzLmxvZ2dlci5pbmZvKGBEb3dubG9hZGVkIWApXG5cdFx0fSBjYXRjaCAodGhyb3duKSB7XG5cdFx0XHRpZiAodGhyb3duIGluc3RhbmNlb2YgRXJyb3IpIHtcblx0XHRcdFx0dGhpcy5sb2dnZXIuZXJyb3IoYEZhaWxlZCB0byBnZXQgdGhlIGxhdGVzdCByZWxlYXNlOiAke3Rocm93bi5tZXNzYWdlfWApXG5cdFx0XHR9XG5cdFx0XHRyZXR1cm5cblx0XHR9XG5cdH1cblxuXHRwcm90ZWN0ZWQgaW5zdGFsbFBhY2thZ2UoKTogdm9pZCB7XG5cdFx0dGhpcy5sb2dnZXIuaW5mbyhgSW5zdGFsbGluZy4uLmApXG5cblx0XHR0cnkge1xuXHRcdFx0Y29uc3Qgb3V0ID0gZXhlY1N5bmModGhpcy5vcHRpb25zLnNjcmlwdHMuaW5zdGFsbClcblx0XHRcdHRoaXMubG9nZ2VyLmluZm8oYEluc3RhbGwgc3Rkb3V0OmAsIG91dC50b1N0cmluZygpKVxuXHRcdFx0dGhpcy5zdG9yYWdlLnNldEl0ZW0oYHNldHVwUGhhc2VgLCBgaW5zdGFsbGVkYClcblx0XHRcdHRoaXMubG9nZ2VyLmluZm8oYEluc3RhbGxlZCFgKVxuXHRcdH0gY2F0Y2ggKHRocm93bikge1xuXHRcdFx0aWYgKHRocm93biBpbnN0YW5jZW9mIEVycm9yKSB7XG5cdFx0XHRcdHRoaXMubG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gZ2V0IHRoZSBsYXRlc3QgcmVsZWFzZTogJHt0aHJvd24ubWVzc2FnZX1gKVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuXG5cdFx0fVxuXHR9XG5cblx0cHVibGljIHN0b3BBbGxTZXJ2aWNlcygpOiBGdXR1cmU8dW5rbm93bj4ge1xuXHRcdHRoaXMubG9nZ2VyLmluZm8oYFN0b3BwaW5nIGFsbCBzZXJ2aWNlcy4uLiBhdXRvLXJlc3Bhd24gZGlzYWJsZWQuYClcblx0XHR0aGlzLmF1dG9SZXNwYXduRGVhZFNlcnZpY2VzID0gZmFsc2Vcblx0XHRmb3IgKGNvbnN0IFtzZXJ2aWNlTmFtZV0gb2YgdG9FbnRyaWVzKHRoaXMuc2VydmljZXMpKSB7XG5cdFx0XHR0aGlzLnN0b3BTZXJ2aWNlKHNlcnZpY2VOYW1lKVxuXHRcdH1cblx0XHRyZXR1cm4gdGhpcy5kZWFkXG5cdH1cblxuXHRwdWJsaWMgc3RvcFNlcnZpY2Uoc2VydmljZU5hbWU6IFMpOiB2b2lkIHtcblx0XHRjb25zdCBzZXJ2aWNlID0gdGhpcy5zZXJ2aWNlc1tzZXJ2aWNlTmFtZV1cblx0XHRpZiAoc2VydmljZSkge1xuXHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhgU3RvcHBpbmcgc2VydmljZSBcIiR7c2VydmljZU5hbWV9XCIuLi5gKVxuXHRcdFx0dGhpcy5zZXJ2aWNlc0RlYWRbdGhpcy5zZXJ2aWNlSWR4W3NlcnZpY2VOYW1lXV0udXNlKFxuXHRcdFx0XHRuZXcgUHJvbWlzZSgocGFzcykgPT4ge1xuXHRcdFx0XHRcdHNlcnZpY2UuZW1pdChgdGltZVRvU3RvcGApXG5cdFx0XHRcdFx0c2VydmljZS5wcm9jZXNzLm9uY2UoYGNsb3NlYCwgKGV4aXRDb2RlKSA9PiB7XG5cdFx0XHRcdFx0XHR0aGlzLmxvZ2dlci5pbmZvKFxuXHRcdFx0XHRcdFx0XHRgU3RvcHBlZCBzZXJ2aWNlIFwiJHtzZXJ2aWNlTmFtZX1cIjsgZXhpdGVkIHdpdGggY29kZSAke2V4aXRDb2RlfWAsXG5cdFx0XHRcdFx0XHQpXG5cdFx0XHRcdFx0XHR0aGlzLnNlcnZpY2VzW3NlcnZpY2VOYW1lXSA9IG51bGxcblx0XHRcdFx0XHRcdHBhc3MoKVxuXHRcdFx0XHRcdH0pXG5cdFx0XHRcdH0pLFxuXHRcdFx0KVxuXHRcdFx0dGhpcy5kZWFkLnVzZShQcm9taXNlLmFsbCh0aGlzLnNlcnZpY2VzRGVhZCkpXG5cdFx0XHR0aGlzLnNlcnZpY2VzTGl2ZVt0aGlzLnNlcnZpY2VJZHhbc2VydmljZU5hbWVdXSA9IG5ldyBGdXR1cmUoKCkgPT4ge30pXG5cdFx0XHRpZiAodGhpcy5saXZlLmRvbmUpIHtcblx0XHRcdFx0dGhpcy5saXZlID0gbmV3IEZ1dHVyZSgoKSA9PiB7fSlcblx0XHRcdH1cblx0XHRcdHRoaXMubGl2ZS51c2UoUHJvbWlzZS5hbGwodGhpcy5zZXJ2aWNlc0xpdmUpKVxuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aGlzLnNlcnZpY2VMb2dnZXJzW3NlcnZpY2VOYW1lXS5lcnJvcihcblx0XHRcdFx0YFRyaWVkIHRvIHN0b3Agc2VydmljZSwgYnV0IGl0IHdhc24ndCBydW5uaW5nLmAsXG5cdFx0XHQpXG5cdFx0fVxuXHR9XG59XG5cbmV4cG9ydCBjb25zdCBGTElHSFRERUNLX0lORk8gPSBgaW5mb2BcbmV4cG9ydCBjb25zdCBGTElHSFRERUNLX1dBUk4gPSBgd2FybmBcbmV4cG9ydCBjb25zdCBGTElHSFRERUNLX0VSUk9SID0gYEVSUiFgXG5cbmV4cG9ydCBjb25zdCBmbGlnaHREZWNrTG9nU2NoZW1hID0gei5vYmplY3Qoe1xuXHRsZXZlbDogei51bmlvbihbXG5cdFx0ei5saXRlcmFsKEZMSUdIVERFQ0tfSU5GTyksXG5cdFx0ei5saXRlcmFsKEZMSUdIVERFQ0tfV0FSTiksXG5cdFx0ei5saXRlcmFsKEZMSUdIVERFQ0tfRVJST1IpLFxuXHRdKSxcblx0dGltZXN0YW1wOiB6Lm51bWJlcigpLFxuXHRwYWNrYWdlOiB6LnN0cmluZygpLFxuXHRzZXJ2aWNlOiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG5cdHByb2Nlc3M6IHoubnVtYmVyKCksXG5cdGJvZHk6IHouc3RyaW5nKCksXG59KVxuZXhwb3J0IHR5cGUgRmxpZ2h0RGVja0xvZyA9IHouaW5mZXI8dHlwZW9mIGZsaWdodERlY2tMb2dTY2hlbWE+XG5cbmNvbnN0IExJTkVfRk9STUFUID0gYGxpbmUtZm9ybWF0YCBzYXRpc2ZpZXMga2V5b2YgTG5hdkZvcm1hdFxuY29uc3QgVkFMVUUgPSBgdmFsdWVgIHNhdGlzZmllcyBrZXlvZiBMbmF2Rm9ybWF0XG5cbmV4cG9ydCB0eXBlIExuYXZGb3JtYXRWaXN1YWxDb21wb25lbnQgPSBFeGNsdWRlPFxuXHRFeGNsdWRlPExuYXZGb3JtYXRbYGxpbmUtZm9ybWF0YF0sIHVuZGVmaW5lZD5bbnVtYmVyXSxcblx0c3RyaW5nXG4+XG5cbmV4cG9ydCB0eXBlIExuYXZGb3JtYXRCcmVha2Rvd24gPSBFeGNsdWRlPExuYXZGb3JtYXRbYHZhbHVlYF0sIHVuZGVmaW5lZD5cbmV4cG9ydCB0eXBlIE1lbWJlck9mPFQ+ID0gVFtrZXlvZiBUXVxuZXhwb3J0IHR5cGUgTG5hdkZvcm1hdFZhbHVlRGVmaW5pdGlvbiA9IE1lbWJlck9mPExuYXZGb3JtYXRCcmVha2Rvd24+XG5cbmV4cG9ydCB0eXBlIEZsaWdodERlY2tGb3JtYXQgPSB7XG5cdFtMSU5FX0ZPUk1BVF06IChcblx0XHR8IHN0cmluZ1xuXHRcdHwgKExuYXZGb3JtYXRWaXN1YWxDb21wb25lbnQgJiB7XG5cdFx0XHRcdGZpZWxkOiBrZXlvZiBGbGlnaHREZWNrTG9nIHwgYF9fbGV2ZWxfX2AgfCBgX190aW1lc3RhbXBfX2Bcblx0XHQgIH0pXG5cdClbXVxuXHRbVkFMVUVdOiB7XG5cdFx0W0sgaW4ga2V5b2YgRmxpZ2h0RGVja0xvZ106IExuYXZGb3JtYXRWYWx1ZURlZmluaXRpb24gJiB7XG5cdFx0XHRraW5kOiBGbGlnaHREZWNrTG9nW0tdIGV4dGVuZHMgbnVtYmVyIHwgdW5kZWZpbmVkXG5cdFx0XHRcdD8gYGludGVnZXJgXG5cdFx0XHRcdDogRmxpZ2h0RGVja0xvZ1tLXSBleHRlbmRzIHN0cmluZyB8IHVuZGVmaW5lZFxuXHRcdFx0XHRcdD8gYHN0cmluZ2Bcblx0XHRcdFx0XHQ6IG5ldmVyXG5cdFx0fVxuXHR9XG59XG5cbmV4cG9ydCBjb25zdCBGTElHSFRERUNLX0xOQVZfRk9STUFUID0ge1xuXHR0aXRsZTogYEZsaWdodERlY2sgTG9nYCxcblx0ZGVzY3JpcHRpb246IGBGb3JtYXQgZm9yIGV2ZW50cyBsb2dnZWQgYnkgdGhlIEZsaWdodERlY2sgcHJvY2VzcyBtYW5hZ2VyLmAsXG5cdFwiZmlsZS10eXBlXCI6IGBqc29uYCxcblx0XCJ0aW1lc3RhbXAtZmllbGRcIjogYHRpbWVzdGFtcGAsXG5cdFwidGltZXN0YW1wLWRpdmlzb3JcIjogMTAwMCxcblx0XCJtb2R1bGUtZmllbGRcIjogYHBhY2thZ2VgLFxuXHRcIm9waWQtZmllbGRcIjogYHNlcnZpY2VgLFxuXHRcImxldmVsLWZpZWxkXCI6IGBsZXZlbGAsXG5cdGxldmVsOiB7XG5cdFx0aW5mbzogRkxJR0hUREVDS19JTkZPLFxuXHRcdHdhcm5pbmc6IEZMSUdIVERFQ0tfV0FSTixcblx0XHRlcnJvcjogRkxJR0hUREVDS19FUlJPUixcblx0fSxcblxuXHRbTElORV9GT1JNQVRdOiBbXG5cdFx0e1xuXHRcdFx0ZmllbGQ6IGBsZXZlbGAsXG5cdFx0fSxcblx0XHR7XG5cdFx0XHRwcmVmaXg6IGAgYCxcblx0XHRcdGZpZWxkOiBgX190aW1lc3RhbXBfX2AsXG5cdFx0XHRcInRpbWVzdGFtcC1mb3JtYXRcIjogYCVZLSVtLSVkVCVIOiVNOiVTLiVMJVpgLFxuXHRcdH0sXG5cdFx0e1xuXHRcdFx0cHJlZml4OiBgIGAsXG5cdFx0XHRmaWVsZDogYHByb2Nlc3NgLFxuXHRcdFx0XCJtaW4td2lkdGhcIjogNSxcblx0XHR9LFxuXHRcdHtcblx0XHRcdHByZWZpeDogYDpgLFxuXHRcdFx0ZmllbGQ6IGBwYWNrYWdlYCxcblx0XHR9LFxuXHRcdHtcblx0XHRcdHByZWZpeDogYDpgLFxuXHRcdFx0ZmllbGQ6IGBzZXJ2aWNlYCxcblx0XHRcdFwiZGVmYXVsdC12YWx1ZVwiOiBgYCxcblx0XHR9LFxuXHRcdHtcblx0XHRcdHByZWZpeDogYDogYCxcblx0XHRcdGZpZWxkOiBgYm9keWAsXG5cdFx0fSxcblx0XSxcblxuXHRbVkFMVUVdOiB7XG5cdFx0dGltZXN0YW1wOiB7XG5cdFx0XHRraW5kOiBgaW50ZWdlcmAsXG5cdFx0fSxcblx0XHRsZXZlbDoge1xuXHRcdFx0a2luZDogYHN0cmluZ2AsXG5cdFx0fSxcblx0XHRwYWNrYWdlOiB7XG5cdFx0XHRraW5kOiBgc3RyaW5nYCxcblx0XHR9LFxuXHRcdHNlcnZpY2U6IHtcblx0XHRcdGtpbmQ6IGBzdHJpbmdgLFxuXHRcdH0sXG5cdFx0cHJvY2Vzczoge1xuXHRcdFx0a2luZDogYGludGVnZXJgLFxuXHRcdH0sXG5cdFx0Ym9keToge1xuXHRcdFx0a2luZDogYHN0cmluZ2AsXG5cdFx0fSxcblx0fSxcbn0gYXMgY29uc3Qgc2F0aXNmaWVzIEZsaWdodERlY2tGb3JtYXQgJiBMbmF2Rm9ybWF0XG5cbmV4cG9ydCBjbGFzcyBGbGlnaHREZWNrTG9nZ2VyXG5cdGltcGxlbWVudHMgUGljazxDb25zb2xlLCBgZXJyb3JgIHwgYGluZm9gIHwgYHdhcm5gPlxue1xuXHRwdWJsaWMgcmVhZG9ubHkgcGFja2FnZU5hbWU6IHN0cmluZ1xuXHRwdWJsaWMgcmVhZG9ubHkgc2VydmljZU5hbWU/OiBzdHJpbmdcblx0cHVibGljIHJlYWRvbmx5IGpzb25Mb2dnaW5nOiBib29sZWFuXG5cdHB1YmxpYyBwcm9jZXNzQ29kZTogbnVtYmVyXG5cdHB1YmxpYyBjb25zdHJ1Y3Rvcihcblx0XHRwYWNrYWdlTmFtZTogc3RyaW5nLFxuXHRcdHByb2Nlc3NDb2RlOiBudW1iZXIsXG5cdFx0c2VydmljZU5hbWU/OiBzdHJpbmcsXG5cdFx0b3B0aW9ucz86IHsganNvbkxvZ2dpbmc6IGJvb2xlYW4gfSxcblx0KSB7XG5cdFx0dGhpcy5wYWNrYWdlTmFtZSA9IHBhY2thZ2VOYW1lXG5cdFx0aWYgKHNlcnZpY2VOYW1lKSB7XG5cdFx0XHR0aGlzLnNlcnZpY2VOYW1lID0gc2VydmljZU5hbWVcblx0XHR9XG5cdFx0dGhpcy5wcm9jZXNzQ29kZSA9IHByb2Nlc3NDb2RlXG5cdFx0dGhpcy5qc29uTG9nZ2luZyA9IG9wdGlvbnM/Lmpzb25Mb2dnaW5nID8/IGZhbHNlXG5cdH1cblx0cHJvdGVjdGVkIGxvZyhcblx0XHRsZXZlbDpcblx0XHRcdHwgdHlwZW9mIEZMSUdIVERFQ0tfRVJST1Jcblx0XHRcdHwgdHlwZW9mIEZMSUdIVERFQ0tfSU5GT1xuXHRcdFx0fCB0eXBlb2YgRkxJR0hUREVDS19XQVJOLFxuXHRcdC4uLm1lc3NhZ2VzOiB1bmtub3duW11cblx0KTogdm9pZCB7XG5cdFx0aWYgKHRoaXMuanNvbkxvZ2dpbmcpIHtcblx0XHRcdGxldCBib2R5ID0gbWVzc2FnZXNcblx0XHRcdFx0Lm1hcCgobWVzc2FnZSkgPT5cblx0XHRcdFx0XHR0eXBlb2YgbWVzc2FnZSA9PT0gYHN0cmluZ2Bcblx0XHRcdFx0XHRcdD8gbWVzc2FnZVxuXHRcdFx0XHRcdFx0OiBpbnNwZWN0KG1lc3NhZ2UsIGZhbHNlLCBudWxsLCB0cnVlKSxcblx0XHRcdFx0KVxuXHRcdFx0XHQuam9pbihgIGApXG5cdFx0XHRpZiAoYm9keS5pbmNsdWRlcyhgXFxuYCkpIHtcblx0XHRcdFx0Ym9keSA9IGBcXG4gICR7Ym9keS5zcGxpdChgXFxuYCkuam9pbihgXFxuICBgKX1gXG5cdFx0XHR9XG5cdFx0XHRjb25zdCBsb2c6IEZsaWdodERlY2tMb2cgPSB7XG5cdFx0XHRcdHRpbWVzdGFtcDogRGF0ZS5ub3coKSxcblx0XHRcdFx0bGV2ZWwsXG5cdFx0XHRcdHByb2Nlc3M6IHRoaXMucHJvY2Vzc0NvZGUsXG5cdFx0XHRcdHBhY2thZ2U6IHRoaXMucGFja2FnZU5hbWUsXG5cdFx0XHRcdGJvZHksXG5cdFx0XHR9XG5cdFx0XHRpZiAodGhpcy5zZXJ2aWNlTmFtZSkge1xuXHRcdFx0XHRsb2cuc2VydmljZSA9IHRoaXMuc2VydmljZU5hbWVcblx0XHRcdH1cblx0XHRcdHByb2Nlc3Muc3Rkb3V0LndyaXRlKEpTT04uc3RyaW5naWZ5KGxvZykgKyBgXFxuYClcblx0XHR9IGVsc2Uge1xuXHRcdFx0Y29uc3Qgc291cmNlID0gdGhpcy5zZXJ2aWNlTmFtZVxuXHRcdFx0XHQ/IGAke3RoaXMucGFja2FnZU5hbWV9OiR7dGhpcy5zZXJ2aWNlTmFtZX1gXG5cdFx0XHRcdDogdGhpcy5wYWNrYWdlTmFtZVxuXHRcdFx0c3dpdGNoIChsZXZlbCkge1xuXHRcdFx0XHRjYXNlIEZMSUdIVERFQ0tfSU5GTzpcblx0XHRcdFx0XHRjb25zb2xlLmxvZyhgJHtzb3VyY2V9OmAsIC4uLm1lc3NhZ2VzKVxuXHRcdFx0XHRcdGJyZWFrXG5cdFx0XHRcdGNhc2UgRkxJR0hUREVDS19XQVJOOlxuXHRcdFx0XHRcdGNvbnNvbGUud2FybihgJHtzb3VyY2V9OmAsIC4uLm1lc3NhZ2VzKVxuXHRcdFx0XHRcdGJyZWFrXG5cdFx0XHRcdGNhc2UgRkxJR0hUREVDS19FUlJPUjpcblx0XHRcdFx0XHRjb25zb2xlLmVycm9yKGAke3NvdXJjZX06YCwgLi4ubWVzc2FnZXMpXG5cdFx0XHRcdFx0YnJlYWtcblx0XHRcdH1cblx0XHR9XG5cdH1cblx0cHVibGljIGluZm8oLi4ubWVzc2FnZXM6IHVua25vd25bXSk6IHZvaWQge1xuXHRcdHRoaXMubG9nKEZMSUdIVERFQ0tfSU5GTywgLi4ubWVzc2FnZXMpXG5cdH1cblxuXHRwdWJsaWMgd2FybiguLi5tZXNzYWdlczogdW5rbm93bltdKTogdm9pZCB7XG5cdFx0dGhpcy5sb2coRkxJR0hUREVDS19XQVJOLCAuLi5tZXNzYWdlcylcblx0fVxuXG5cdHB1YmxpYyBlcnJvciguLi5tZXNzYWdlczogdW5rbm93bltdKTogdm9pZCB7XG5cdFx0dGhpcy5sb2coRkxJR0hUREVDS19FUlJPUiwgLi4ubWVzc2FnZXMpXG5cdH1cbn1cbiIsCiAgICAiaW1wb3J0IHtcblx0ZXhpc3RzU3luYyxcblx0bWtkaXJTeW5jLFxuXHRyZWFkZGlyU3luYyxcblx0cmVhZEZpbGVTeW5jLFxuXHRybVN5bmMsXG5cdHN0YXRTeW5jLFxuXHR3cml0ZUZpbGVTeW5jLFxufSBmcm9tIFwibm9kZTpmc1wiXG5pbXBvcnQgeyByZXNvbHZlIH0gZnJvbSBcIm5vZGU6cGF0aFwiXG5cbmV4cG9ydCB0eXBlIEZpbGVzeXN0ZW1TdG9yYWdlT3B0aW9ucyA9IHtcblx0cGF0aDogc3RyaW5nXG59XG5cbmV4cG9ydCBjbGFzcyBGaWxlc3lzdGVtU3RvcmFnZTxcblx0VCBleHRlbmRzIFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+LFxuPiBpbXBsZW1lbnRzIFN0b3JhZ2Vcbntcblx0cHVibGljIHJvb3REaXI6IHN0cmluZ1xuXG5cdHB1YmxpYyBjb25zdHJ1Y3RvcihvcHRpb25zOiBGaWxlc3lzdGVtU3RvcmFnZU9wdGlvbnMpIHtcblx0XHR0aGlzLnJvb3REaXIgPSBvcHRpb25zLnBhdGhcblx0XHRpZiAoIWV4aXN0c1N5bmModGhpcy5yb290RGlyKSkge1xuXHRcdFx0bWtkaXJTeW5jKHRoaXMucm9vdERpciwgeyByZWN1cnNpdmU6IHRydWUgfSlcblx0XHR9XG5cdH1cblxuXHRwdWJsaWMgZ2V0SXRlbTxLIGV4dGVuZHMgc3RyaW5nICYga2V5b2YgVD4oa2V5OiBLKTogVFtLXSB8IG51bGwge1xuXHRcdGNvbnN0IGZpbGVQYXRoID0gcmVzb2x2ZSh0aGlzLnJvb3REaXIsIGtleSlcblx0XHRpZiAoZXhpc3RzU3luYyhmaWxlUGF0aCkpIHtcblx0XHRcdHJldHVybiByZWFkRmlsZVN5bmMoZmlsZVBhdGgsIGB1dGYtOGApIGFzIFRbS11cblx0XHR9XG5cdFx0cmV0dXJuIG51bGxcblx0fVxuXG5cdHB1YmxpYyBzZXRJdGVtPEsgZXh0ZW5kcyBzdHJpbmcgJiBrZXlvZiBUPihrZXk6IEssIHZhbHVlOiBUW0tdKTogdm9pZCB7XG5cdFx0Y29uc3QgZmlsZVBhdGggPSByZXNvbHZlKHRoaXMucm9vdERpciwga2V5KVxuXHRcdHdyaXRlRmlsZVN5bmMoZmlsZVBhdGgsIHZhbHVlKVxuXHR9XG5cblx0cHVibGljIHJlbW92ZUl0ZW08SyBleHRlbmRzIHN0cmluZyAmIGtleW9mIFQ+KGtleTogSyk6IHZvaWQge1xuXHRcdGNvbnN0IGZpbGVQYXRoID0gcmVzb2x2ZSh0aGlzLnJvb3REaXIsIGtleSlcblx0XHRpZiAoZXhpc3RzU3luYyhmaWxlUGF0aCkpIHtcblx0XHRcdHJtU3luYyhmaWxlUGF0aClcblx0XHR9XG5cdH1cblxuXHRwdWJsaWMga2V5KGluZGV4OiBudW1iZXIpOiAoc3RyaW5nICYga2V5b2YgVCkgfCBudWxsIHtcblx0XHRjb25zdCBmaWxlUGF0aHMgPSByZWFkZGlyU3luYyh0aGlzLnJvb3REaXIpXG5cdFx0Y29uc3QgZmlsZVBhdGhzQnlEYXRlQ3JlYXRlZCA9IGZpbGVQYXRocy5zb3J0KChhLCBiKSA9PiB7XG5cdFx0XHRjb25zdCBhU3RhdCA9IHN0YXRTeW5jKGEpXG5cdFx0XHRjb25zdCBiU3RhdCA9IHN0YXRTeW5jKGIpXG5cdFx0XHRyZXR1cm4gYlN0YXQuY3RpbWVNcyAtIGFTdGF0LmN0aW1lTXNcblx0XHR9KVxuXHRcdHJldHVybiAoZmlsZVBhdGhzQnlEYXRlQ3JlYXRlZFtpbmRleF0gYXMgc3RyaW5nICYga2V5b2YgVCkgPz8gbnVsbFxuXHR9XG5cblx0cHVibGljIGNsZWFyKCk6IHZvaWQge1xuXHRcdHJtU3luYyh0aGlzLnJvb3REaXIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pXG5cdFx0bWtkaXJTeW5jKHRoaXMucm9vdERpciwgeyByZWN1cnNpdmU6IHRydWUgfSlcblx0fVxuXG5cdHB1YmxpYyBnZXQgbGVuZ3RoKCk6IG51bWJlciB7XG5cdFx0cmV0dXJuIHJlYWRkaXJTeW5jKHRoaXMucm9vdERpcikubGVuZ3RoXG5cdH1cbn1cbiIsCiAgICAiaW1wb3J0IHsgY3JlYXRlRW52IH0gZnJvbSBcIkB0My1vc3MvZW52LWNvcmVcIlxuaW1wb3J0IHsgeiB9IGZyb20gXCJ6b2RcIlxuXG5leHBvcnQgY29uc3QgZW52ID0gY3JlYXRlRW52KHtcblx0c2VydmVyOiB7IEZMSUdIVERFQ0tfU0VDUkVUOiB6LnN0cmluZygpLm9wdGlvbmFsKCkgfSxcblx0Y2xpZW50UHJlZml4OiBgTkVWRVJgLFxuXHRjbGllbnQ6IHt9LFxuXHRydW50aW1lRW52OiBpbXBvcnQubWV0YS5lbnYsXG5cdGVtcHR5U3RyaW5nQXNVbmRlZmluZWQ6IHRydWUsXG59KVxuIgogIF0sCiAgIm1hcHBp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QU8sRUFDbEIsa0JBQW1CLEVBQUUsT0FBTyxDQUM3QixDQUFDLEVBQ0QsWUFBYSxFQUFFLFFBQVEsRUFBRSxTQUFTLENBQ25DLENBQUMsRUFDRCxRQUFTLENBQ1IsS0FBTSxDQUNMLEtBQU0sSUFDTixTQUFVLEdBQ1YsWUFBYSx3Q0FDYixRQUFTLGNBQ1QsTUFBTyxFQUNSLEVBQ0EsWUFBYSxDQUNaLEtBQU0sSUFDTixTQUFVLEdBQ1YsWUFBYSx1QkFDYixRQUFTLHdCQUNWLEVBQ0EsU0FBVSxDQUNULEtBQU0sSUFDTixTQUFVLEdBQ1YsWUFBYSx1Q0FDYixRQUFTLDhJQUNULE1BQU8sS0FBSyxLQUNiLEVBQ0Esa0JBQW1CLENBQ2xCLEtBQU0sSUFDTixTQUFVLEdBQ1YsWUFBYSx5Q0FDYixRQUFTLDZEQUNWLEVBQ0EsUUFBUyxDQUNSLEtBQU0sSUFDTixTQUFVLEdBQ1YsWUFBYSx5QkFDYixRQUFTLDJFQUNULE1BQU8sS0FBSyxLQUNiLEVBQ0EsWUFBYSxDQUNaLEtBQU0sSUFDTixTQUFVLEdBQ1YsWUFBYSx1QkFDYixRQUFTLGdCQUNULE1BQU8sRUFDUixDQUNELENBQ0QsRUFFTSxHQUFnQixDQUNyQixjQUFlLEVBQUUsT0FBTyxDQUN2QixPQUFRLEVBQUUsT0FBTyxFQUFFLFNBQVMsQ0FDN0IsQ0FBQyxFQUNELFFBQVMsQ0FDUixPQUFRLENBQ1AsS0FBTSxJQUNOLFNBQVUsR0FDVixZQUFhLG9DQUNiLFFBQVMsaUJBQ1YsQ0FDRCxDQUNELEVBRU0sR0FBUSxHQUNiLENBQ0MsUUFBUyxhQUNULE9BQVEsR0FBUyxDQUFFLE9BQVEsS0FBTSxZQUFhLElBQUssQ0FBQyxFQUNwRCxhQUFjLENBQ2IsR0FBSSxFQUNKLFlBQWEsRUFDYixPQUFRLEVBQ1QsRUFDQSxZQUFhLEdBQ2IsbUJBQW9CLENBQUMsSUFBUyxDQUM3QixHQUFJLEVBQUssS0FBTyxTQUNmLE9BSUQsT0FEQyxFQUFLLElBQVcsT0FBSyxRQUFRLElBQUksRUFBRyx3QkFBd0IsRUFHL0QsRUFDQSxPQUNELEdBRVEsU0FBUSxvQkFBb0IsR0FBTSxRQUFRLElBQUksRUFFdEQsT0FBUSxFQUFPLFVBQ1QsU0FDSixDQUNDLElBQVEsVUFBVyxFQUFPLEtBQzFCLEdBQWdCLEdBQVUsR0FBRyxDQUM5QixDQUNBLGNBQ1EsQ0FDUixJQUFNLEVBQWEsSUFBSSxFQUFXLEVBQU8sSUFBSSxFQUM3QyxRQUFRLEdBQUcsUUFBUyxTQUFZLENBQy9CLE1BQU0sRUFBVyxnQkFBZ0IsRUFDakMsQ0FDRiIsCiAgImRlYnVnSWQiOiAiOEMyNTdBNzY5NEQ5NDBENjY0NzU2RTIxNjQ3NTZFMjEiLAogICJuYW1lcyI6IFtdCn0=
@@ -5,17 +5,19 @@
5
5
  "description": "Format for events logged by the FlightDeck process manager.",
6
6
  "file-type": "json",
7
7
  "timestamp-field": "timestamp",
8
- "subsecond-field": "subsecond",
9
- "subsecond-units": "milli",
8
+ "timestamp-divisor": 1000,
9
+ "module-field": "package",
10
10
  "opid-field": "service",
11
11
  "level-field": "level",
12
12
  "level": {
13
13
  "info": "info",
14
14
  "warning": "warn",
15
- "error": "err!"
15
+ "error": "ERR!"
16
16
  },
17
- "ordered-by-time": true,
18
17
  "line-format": [
18
+ {
19
+ "field": "level"
20
+ },
19
21
  {
20
22
  "prefix": " ",
21
23
  "field": "__timestamp__",
@@ -35,11 +37,6 @@
35
37
  "field": "service",
36
38
  "default-value": ""
37
39
  },
38
- {
39
- "prefix": "[",
40
- "field": "__level__",
41
- "suffix": "]"
42
- },
43
40
  {
44
41
  "prefix": ": ",
45
42
  "field": "body"
package/dist/lib.d.ts CHANGED
@@ -867,6 +867,9 @@ declare class FlightDeck<S extends string = string> {
867
867
  stopAllServices(): Future<unknown>;
868
868
  stopService(serviceName: S): void;
869
869
  }
870
+ declare const FLIGHTDECK_INFO = "info";
871
+ declare const FLIGHTDECK_WARN = "warn";
872
+ declare const FLIGHTDECK_ERROR = "ERR!";
870
873
  declare const flightDeckLogSchema: z.ZodObject<{
871
874
  level: z.ZodUnion<[z.ZodLiteral<"info">, z.ZodLiteral<"warn">, z.ZodLiteral<"ERR!">]>;
872
875
  timestamp: z.ZodNumber;
@@ -911,17 +914,18 @@ declare const FLIGHTDECK_LNAV_FORMAT: {
911
914
  readonly description: "Format for events logged by the FlightDeck process manager.";
912
915
  readonly "file-type": "json";
913
916
  readonly "timestamp-field": "timestamp";
914
- readonly "subsecond-field": "subsecond";
915
- readonly "subsecond-units": "milli";
917
+ readonly "timestamp-divisor": 1000;
918
+ readonly "module-field": "package";
916
919
  readonly "opid-field": "service";
917
920
  readonly "level-field": "level";
918
921
  readonly level: {
919
922
  readonly info: "info";
920
923
  readonly warning: "warn";
921
- readonly error: "err!";
924
+ readonly error: "ERR!";
922
925
  };
923
- readonly "ordered-by-time": true;
924
926
  readonly "line-format": [{
927
+ readonly field: "level";
928
+ }, {
925
929
  readonly prefix: " ";
926
930
  readonly field: "__timestamp__";
927
931
  readonly "timestamp-format": "%Y-%m-%dT%H:%M:%S.%L%Z";
@@ -936,10 +940,6 @@ declare const FLIGHTDECK_LNAV_FORMAT: {
936
940
  readonly prefix: ":";
937
941
  readonly field: "service";
938
942
  readonly "default-value": "";
939
- }, {
940
- readonly prefix: "[";
941
- readonly field: "__level__";
942
- readonly suffix: "]";
943
943
  }, {
944
944
  readonly prefix: ": ";
945
945
  readonly field: "body";
@@ -973,6 +973,7 @@ declare class FlightDeckLogger implements Pick<Console, `error` | `info` | `warn
973
973
  constructor(packageName: string, processCode: number, serviceName?: string, options?: {
974
974
  jsonLogging: boolean;
975
975
  });
976
+ protected log(level: typeof FLIGHTDECK_ERROR | typeof FLIGHTDECK_INFO | typeof FLIGHTDECK_WARN, ...messages: unknown[]): void;
976
977
  info(...messages: unknown[]): void;
977
978
  warn(...messages: unknown[]): void;
978
979
  error(...messages: unknown[]): void;
@@ -1031,4 +1032,4 @@ declare namespace klaxon_lib {
1031
1032
  export { type klaxon_lib_AlertOptions as AlertOptions, type klaxon_lib_ChangesetsPublishResult as ChangesetsPublishResult, type klaxon_lib_ChangesetsPublishedPackage as ChangesetsPublishedPackage, type klaxon_lib_PackageConfig as PackageConfig, type klaxon_lib_ScrambleOptions as ScrambleOptions, type klaxon_lib_ScrambleResult as ScrambleResult, type klaxon_lib_SecretsConfig as SecretsConfig, klaxon_lib_alert as alert, klaxon_lib_scramble as scramble };
1032
1033
  }
1033
1034
 
1034
- export { FLIGHTDECK_LNAV_FORMAT, FLIGHTDECK_SETUP_PHASES, FLIGHTDECK_UPDATE_PHASES, FilesystemStorage, type FilesystemStorageOptions, FlightDeck, type FlightDeckFormat, type FlightDeckLog, FlightDeckLogger, type FlightDeckOptions, type FlightDeckSetupPhase, type FlightDeckUpdatePhase, klaxon_lib as Klaxon, type LnavFormatBreakdown, type LnavFormatValueDefinition, type LnavFormatVisualComponent, type MemberOf, flightDeckLogSchema, isVersionNumber };
1035
+ export { FLIGHTDECK_ERROR, FLIGHTDECK_INFO, FLIGHTDECK_LNAV_FORMAT, FLIGHTDECK_SETUP_PHASES, FLIGHTDECK_UPDATE_PHASES, FLIGHTDECK_WARN, FilesystemStorage, type FilesystemStorageOptions, FlightDeck, type FlightDeckFormat, type FlightDeckLog, FlightDeckLogger, type FlightDeckOptions, type FlightDeckSetupPhase, type FlightDeckUpdatePhase, klaxon_lib as Klaxon, type LnavFormatBreakdown, type LnavFormatValueDefinition, type LnavFormatVisualComponent, type MemberOf, flightDeckLogSchema, isVersionNumber };
package/dist/lib.js CHANGED
@@ -1,7 +1,9 @@
1
- var I=Object.defineProperty;var _=(e,t)=>{for(var i in t)I(e,i,{get:t[i],enumerable:!0,configurable:!0,set:(r)=>t[i]=()=>r})};import{existsSync as m,mkdirSync as F,readdirSync as L,readFileSync as U,rmSync as x,statSync as T,writeFileSync as R}from"node:fs";import{resolve as y}from"node:path";class k{rootDir;constructor(e){if(this.rootDir=e.path,!m(this.rootDir))F(this.rootDir,{recursive:!0})}getItem(e){let t=y(this.rootDir,e);if(m(t))return U(t,"utf-8");return null}setItem(e,t){let i=y(this.rootDir,e);R(i,t)}removeItem(e){let t=y(this.rootDir,e);if(m(t))x(t)}key(e){return L(this.rootDir).sort((r,c)=>{let n=T(r);return T(c).ctimeMs-n.ctimeMs})[e]??null}clear(){x(this.rootDir,{recursive:!0}),F(this.rootDir,{recursive:!0})}get length(){return L(this.rootDir).length}}import{execSync as S,spawn as j}from"node:child_process";import{createServer as H}from"node:http";import{homedir as O}from"node:os";import{resolve as E}from"node:path";import{inspect as w}from"node:util";import{Future as h}from"atom.io/internal";import{discoverType as M}from"atom.io/introspection";import{fromEntries as v,toEntries as u}from"atom.io/json";import{ChildSocket as V}from"atom.io/realtime-server";import{CronJob as B}from"cron";import{z as l}from"zod";import{createEnv as K}from"@t3-oss/env-core";import{z as N}from"zod";var P=K({server:{FLIGHTDECK_SECRET:N.string().optional()},clientPrefix:"NEVER",client:{},runtimeEnv:import.meta.env,emptyStringAsUndefined:!0});var ve=["downloaded","installed"],me=["notified","confirmed"];function G(e){return/^\d+\.\d+\.\d+$/.test(e)||!Number.isNaN(Number.parseFloat(e))}class z{options;safety=0;storage;webhookServer;services;serviceIdx;defaultServicesReadyToUpdate;servicesReadyToUpdate;autoRespawnDeadServices;logger;serviceLoggers;updateAvailabilityChecker=null;servicesLive;servicesDead;live=new h(()=>{});dead=new h(()=>{});restartTimes=[];constructor(e){this.options=e;let{FLIGHTDECK_SECRET:t}=P,{flightdeckRootDir:i=E(O(),".flightdeck")}=e,r=e.port??8080,c=`http://localhost:${r}`,n=u(e.services);if(this.services=v(n.map(([s])=>[s,null])),this.serviceIdx=v(n.map(([s],o)=>[s,o])),this.defaultServicesReadyToUpdate=v(n.map(([s,{waitFor:o}])=>[s,!o])),this.servicesReadyToUpdate={...this.defaultServicesReadyToUpdate},this.autoRespawnDeadServices=!0,this.logger=new b(this.options.packageName,process.pid,void 0,{jsonLogging:this.options.jsonLogging??!1}),this.serviceLoggers=v(n.map(([s])=>[s,new b(this.options.packageName,process.pid,s,{jsonLogging:this.options.jsonLogging??!1})])),this.servicesLive=n.map(()=>new h(()=>{})),this.servicesDead=n.map(()=>new h(()=>{})),this.live.use(Promise.all(this.servicesLive)),this.dead.use(Promise.all(this.servicesDead)),this.storage=new k({path:E(i,"storage",e.packageName)}),t===void 0)this.logger.warn("No FLIGHTDECK_SECRET environment variable found. FlightDeck will not run an update server.");else H((s,o)=>{let p=[];s.on("data",(a)=>{p.push(a instanceof Buffer?a:Buffer.from(a))}).on("end",()=>{let a=s.headers.authorization;try{if(typeof s.url==="undefined")throw 400;let d=`Bearer ${t}`;if(a!==`Bearer ${t}`)throw this.logger.info(`Unauthorized: needed \`${d}\`, got \`${a}\``),401;let f=new URL(s.url,c);this.logger.info(s.method,f.pathname);let g=Buffer.concat(p).toString();if(!G(g))throw 400;o.writeHead(200),o.end(),this.storage.setItem("updatePhase","notified"),this.storage.setItem("updateAwaitedVersion",g);let{checkAvailability:$}=e.scripts;if($){this.updateAvailabilityChecker?.stop(),this.seekUpdate(g);let D=this.storage.getItem("updatePhase");if(this.logger.info('> storage("updatePhase") >',D),D==="notified")this.updateAvailabilityChecker=new B("30 * * * * *",()=>{this.seekUpdate(g)}),this.updateAvailabilityChecker.start()}else this.downloadPackage()}catch(d){if(this.logger.error(d,s.url),typeof d==="number")o.writeHead(d),o.end()}finally{p=[]}})}).listen(r,()=>{this.logger.info(`Server started on port ${r}`)});this.startAllServices().then(()=>{this.logger.info("All services started.")}).catch((s)=>{if(s instanceof Error)this.logger.error("Failed to start all services:",s.message)})}seekUpdate(e){this.logger.info("Checking for updates...");let{checkAvailability:t}=this.options.scripts;if(!t){this.logger.info("No checkAvailability script found.");return}try{let i=S(`${t} ${e}`);this.logger.info("Check stdout:",i.toString()),this.updateAvailabilityChecker?.stop(),this.storage.setItem("updatePhase","confirmed"),this.downloadPackage(),this.announceUpdate()}catch(i){if(i instanceof Error)this.logger.error("Check failed:",i.message);else{let r=M(i);this.logger.error("Check threw",r,i)}}}announceUpdate(){for(let e of u(this.services)){let[t,i]=e;if(i){if(this.options.services[t].waitFor)i.emit("updatesReady")}else this.startService(t)}}tryUpdate(){if(u(this.servicesReadyToUpdate).every(([,e])=>e))this.logger.info("All services are ready to update."),this.stopAllServices().then(()=>{this.logger.info("All services stopped; starting up fresh..."),this.startAllServices().then(()=>{this.logger.info("All services started; we're back online.")}).catch((e)=>{if(e instanceof Error)this.logger.error("Failed to start all services:",e.message)})}).catch((e)=>{if(e instanceof Error)this.logger.error("Failed to stop all services:",e.message)})}startAllServices(){this.logger.info("Starting all services..."),this.autoRespawnDeadServices=!0;let e=this.storage.getItem("setupPhase");switch(this.logger.info('> storage("setupPhase") >',e),e){case null:return this.logger.info("Starting from scratch."),this.downloadPackage(),this.installPackage(),this.startAllServices();case"downloaded":return this.logger.info("Found package downloaded but not installed."),this.installPackage(),this.startAllServices();case"installed":{for(let[t]of u(this.services))this.startService(t);return this.live}}}startService(e){if(this.logger.info(`Starting service ${this.options.packageName}::${e}, try ${this.safety}/2...`),this.safety>=2)throw new Error("Out of tries...");this.safety++;let[t,...i]=this.options.services[e].run.split(" "),r=j(t,i,{cwd:this.options.flightdeckRootDir,env:import.meta.env}),c=this.serviceLoggers[e],n=this.services[e]=new V(r,`${this.options.packageName}::${e}`,c);c.processCode=n.process.pid??-1,this.services[e].onAny((...s)=>{c.info("\uD83D\uDCAC",...s)}),this.services[e].on("readyToUpdate",()=>{this.logger.info(`Service "${e}" is ready to update.`),this.servicesReadyToUpdate[e]=!0,this.tryUpdate()}),this.services[e].on("alive",()=>{if(this.servicesLive[this.serviceIdx[e]].use(Promise.resolve()),this.servicesDead[this.serviceIdx[e]]=new h(()=>{}),this.dead.done)this.dead=new h(()=>{});this.dead.use(Promise.all(this.servicesDead))}),this.services[e].process.once("close",(s)=>{if(this.logger.info(`Auto-respawn saw "${e}" exit with code ${s}`),this.services[e]=null,!this.autoRespawnDeadServices){this.logger.info(`Auto-respawn is off; "${e}" rests.`);return}let o=this.storage.getItem("updatePhase");if(this.logger.info('> storage("updatePhase") >',o),o==="confirmed")this.serviceLoggers[e].info("Updating before startup..."),this.restartTimes=[],this.installPackage(),this.startService(e);else{let a=Date.now(),d=a-300000;if(this.restartTimes=this.restartTimes.filter((f)=>f>d),this.restartTimes.push(a),this.restartTimes.length<5)this.serviceLoggers[e].info("Crashed. Restarting..."),this.startService(e);else this.serviceLoggers[e].info("Crashed 5 times in 5 minutes. Not restarting.")}}),this.safety=0}downloadPackage(){this.logger.info("Downloading...");try{let e=S(this.options.scripts.download);this.logger.info("Download stdout:",e.toString()),this.storage.setItem("setupPhase","downloaded"),this.logger.info("Downloaded!")}catch(e){if(e instanceof Error)this.logger.error(`Failed to get the latest release: ${e.message}`);return}}installPackage(){this.logger.info("Installing...");try{let e=S(this.options.scripts.install);this.logger.info("Install stdout:",e.toString()),this.storage.setItem("setupPhase","installed"),this.logger.info("Installed!")}catch(e){if(e instanceof Error)this.logger.error(`Failed to get the latest release: ${e.message}`);return}}stopAllServices(){this.logger.info("Stopping all services... auto-respawn disabled."),this.autoRespawnDeadServices=!1;for(let[e]of u(this.services))this.stopService(e);return this.dead}stopService(e){let t=this.services[e];if(t){if(this.logger.info(`Stopping service "${e}"...`),this.servicesDead[this.serviceIdx[e]].use(new Promise((i)=>{t.emit("timeToStop"),t.process.once("close",(r)=>{this.logger.info(`Stopped service "${e}"; exited with code ${r}`),this.services[e]=null,i()})})),this.dead.use(Promise.all(this.servicesDead)),this.servicesLive[this.serviceIdx[e]]=new h(()=>{}),this.live.done)this.live=new h(()=>{});this.live.use(Promise.all(this.servicesLive))}else this.serviceLoggers[e].error("Tried to stop service, but it wasn't running.")}}var ye=l.object({level:l.union([l.literal("info"),l.literal("warn"),l.literal("ERR!")]),timestamp:l.number(),package:l.string(),service:l.string().optional(),process:l.number(),body:l.string()}),J="line-format",Y="value",ke={title:"FlightDeck Log",description:"Format for events logged by the FlightDeck process manager.","file-type":"json","timestamp-field":"timestamp","subsecond-field":"subsecond","subsecond-units":"milli","opid-field":"service","level-field":"level",level:{info:"info",warning:"warn",error:"err!"},"ordered-by-time":!0,[J]:[{prefix:" ",field:"__timestamp__","timestamp-format":"%Y-%m-%dT%H:%M:%S.%L%Z"},{prefix:" ",field:"process","min-width":5},{prefix:":",field:"package"},{prefix:":",field:"service","default-value":""},{prefix:"[",field:"__level__",suffix:"]"},{prefix:": ",field:"body"}],[Y]:{timestamp:{kind:"integer"},level:{kind:"string"},package:{kind:"string"},service:{kind:"string"},process:{kind:"integer"},body:{kind:"string"}}};class b{packageName;serviceName;jsonLogging;processCode;constructor(e,t,i,r){if(this.packageName=e,i)this.serviceName=i;this.processCode=t,this.jsonLogging=r?.jsonLogging??!1}info(...e){if(this.jsonLogging){let t={timestamp:Date.now(),level:"info",process:this.processCode,package:this.packageName,body:e.map((i)=>typeof i==="string"?i:w(i,!1,null,!0)).join(" ")};if(this.serviceName)t.service=this.serviceName;process.stdout.write(JSON.stringify(t)+`
2
- `)}else{let t=this.serviceName?`${this.packageName}::${this.serviceName}`:this.packageName;console.log(`${t}:`,...e)}}warn(...e){if(this.jsonLogging){let t={timestamp:Date.now(),level:"warn",process:this.processCode,package:this.packageName,body:e.map((i)=>typeof i==="string"?i:w(i,!1,null,!0)).join(" ")};if(this.serviceName)t.service=this.serviceName;process.stdout.write(JSON.stringify(t)+`
3
- `)}else{let t=this.serviceName?`${this.packageName}::${this.serviceName}`:this.packageName;console.warn(`${t}:`,...e)}}error(...e){if(this.jsonLogging){let t={timestamp:Date.now()+Math.floor(Math.random()*1000),level:"ERR!",process:this.processCode,package:this.packageName,body:e.map((i)=>typeof i==="string"?i:w(i,!1,null,!0)).join(" ")};if(this.serviceName)t.service=this.serviceName;process.stdout.write(JSON.stringify(t)+`
4
- `)}else{let t=this.serviceName?`${this.packageName}::${this.serviceName}`:this.packageName;console.error(`${t}:`,...e)}}}var C={};_(C,{scramble:()=>Z,alert:()=>A});async function A({secret:e,endpoint:t,version:i}){return await fetch(t,{method:"POST",headers:{"Content-Type":"text/plain;charset=UTF-8",Authorization:`Bearer ${e}`},body:i})}async function Z({packageConfig:e,secretsConfig:t,publishedPackages:i}){let r=[];for(let s of i)if(s.name in e){let o=s.name,{endpoint:p}=e[o],a=t[o],d=s.version,f=A({secret:a,endpoint:p,version:d}).then((g)=>[o,g]);r.push(f)}let c=await Promise.all(r);return Object.fromEntries(c)}export{G as isVersionNumber,ye as flightDeckLogSchema,C as Klaxon,b as FlightDeckLogger,z as FlightDeck,k as FilesystemStorage,me as FLIGHTDECK_UPDATE_PHASES,ve as FLIGHTDECK_SETUP_PHASES,ke as FLIGHTDECK_LNAV_FORMAT};
1
+ var U=Object.defineProperty;var $=(e,t)=>{for(var i in t)U(e,i,{get:t[i],enumerable:!0,configurable:!0,set:(r)=>t[i]=()=>r})};import{existsSync as S,mkdirSync as T,readdirSync as x,readFileSync as K,rmSync as E,statSync as P,writeFileSync as H}from"node:fs";import{resolve as w}from"node:path";class b{rootDir;constructor(e){if(this.rootDir=e.path,!S(this.rootDir))T(this.rootDir,{recursive:!0})}getItem(e){let t=w(this.rootDir,e);if(S(t))return K(t,"utf-8");return null}setItem(e,t){let i=w(this.rootDir,e);H(i,t)}removeItem(e){let t=w(this.rootDir,e);if(S(t))E(t)}key(e){return x(this.rootDir).sort((r,n)=>{let a=P(r);return P(n).ctimeMs-a.ctimeMs})[e]??null}clear(){E(this.rootDir,{recursive:!0}),T(this.rootDir,{recursive:!0})}get length(){return x(this.rootDir).length}}import{execSync as F,spawn as G}from"node:child_process";import{createServer as V}from"node:http";import{homedir as B}from"node:os";import{resolve as I}from"node:path";import{inspect as M}from"node:util";import{Future as p}from"atom.io/internal";import{discoverType as N}from"atom.io/introspection";import{fromEntries as v,toEntries as u}from"atom.io/json";import{ChildSocket as z}from"atom.io/realtime-server";import{CronJob as J}from"cron";import{z as c}from"zod";import{createEnv as O}from"@t3-oss/env-core";import{z as j}from"zod";var A=O({server:{FLIGHTDECK_SECRET:j.string().optional()},clientPrefix:"NEVER",client:{},runtimeEnv:import.meta.env,emptyStringAsUndefined:!0});var ke=["downloaded","installed"],Se=["notified","confirmed"];function W(e){return/^\d+\.\d+\.\d+$/.test(e)||!Number.isNaN(Number.parseFloat(e))}class Y{options;safety=0;storage;webhookServer;services;serviceIdx;defaultServicesReadyToUpdate;servicesReadyToUpdate;autoRespawnDeadServices;logger;serviceLoggers;updateAvailabilityChecker=null;servicesLive;servicesDead;live=new p(()=>{});dead=new p(()=>{});restartTimes=[];constructor(e){this.options=e;let{FLIGHTDECK_SECRET:t}=A,{flightdeckRootDir:i=I(B(),".flightdeck")}=e,r=e.port??8080,n=`http://localhost:${r}`,a=u(e.services);if(this.services=v(a.map(([s])=>[s,null])),this.serviceIdx=v(a.map(([s],o)=>[s,o])),this.defaultServicesReadyToUpdate=v(a.map(([s,{waitFor:o}])=>[s,!o])),this.servicesReadyToUpdate={...this.defaultServicesReadyToUpdate},this.autoRespawnDeadServices=!0,this.logger=new D(this.options.packageName,process.pid,void 0,{jsonLogging:this.options.jsonLogging??!1}),this.serviceLoggers=v(a.map(([s])=>[s,new D(this.options.packageName,process.pid,s,{jsonLogging:this.options.jsonLogging??!1})])),this.servicesLive=a.map(()=>new p(()=>{})),this.servicesDead=a.map(()=>new p(()=>{})),this.live.use(Promise.all(this.servicesLive)),this.dead.use(Promise.all(this.servicesDead)),this.storage=new b({path:I(i,"storage",e.packageName)}),t===void 0)this.logger.warn("No FLIGHTDECK_SECRET environment variable found. FlightDeck will not run an update server.");else V((s,o)=>{let h=[];s.on("data",(l)=>{h.push(l instanceof Buffer?l:Buffer.from(l))}).on("end",()=>{let l=s.headers.authorization;try{if(typeof s.url==="undefined")throw 400;let d=`Bearer ${t}`;if(l!==`Bearer ${t}`)throw this.logger.info(`Unauthorized: needed \`${d}\`, got \`${l}\``),401;let f=new URL(s.url,n);this.logger.info(s.method,f.pathname);let g=Buffer.concat(h).toString();if(!W(g))throw 400;o.writeHead(200),o.end(),this.storage.setItem("updatePhase","notified"),this.storage.setItem("updateAwaitedVersion",g);let{checkAvailability:_}=e.scripts;if(_){this.updateAvailabilityChecker?.stop(),this.seekUpdate(g);let L=this.storage.getItem("updatePhase");if(this.logger.info('> storage("updatePhase") >',L),L==="notified")this.updateAvailabilityChecker=new J("30 * * * * *",()=>{this.seekUpdate(g)}),this.updateAvailabilityChecker.start()}else this.downloadPackage()}catch(d){if(this.logger.error(d,s.url),typeof d==="number")o.writeHead(d),o.end()}finally{h=[]}})}).listen(r,()=>{this.logger.info(`Server started on port ${r}`)});this.startAllServices().then(()=>{this.logger.info("All services started.")}).catch((s)=>{if(s instanceof Error)this.logger.error("Failed to start all services:",s.message)})}seekUpdate(e){this.logger.info("Checking for updates...");let{checkAvailability:t}=this.options.scripts;if(!t){this.logger.info("No checkAvailability script found.");return}try{let i=F(`${t} ${e}`);this.logger.info("Check stdout:",i.toString()),this.updateAvailabilityChecker?.stop(),this.storage.setItem("updatePhase","confirmed"),this.downloadPackage(),this.announceUpdate()}catch(i){if(i instanceof Error)this.logger.error("Check failed:",i.message);else{let r=N(i);this.logger.error("Check threw",r,i)}}}announceUpdate(){for(let e of u(this.services)){let[t,i]=e;if(i){if(this.options.services[t].waitFor)i.emit("updatesReady")}else this.startService(t)}}tryUpdate(){if(u(this.servicesReadyToUpdate).every(([,e])=>e))this.logger.info("All services are ready to update."),this.stopAllServices().then(()=>{this.logger.info("All services stopped; starting up fresh..."),this.startAllServices().then(()=>{this.logger.info("All services started; we're back online.")}).catch((e)=>{if(e instanceof Error)this.logger.error("Failed to start all services:",e.message)})}).catch((e)=>{if(e instanceof Error)this.logger.error("Failed to stop all services:",e.message)})}startAllServices(){this.logger.info("Starting all services..."),this.autoRespawnDeadServices=!0;let e=this.storage.getItem("setupPhase");switch(this.logger.info('> storage("setupPhase") >',e),e){case null:return this.logger.info("Starting from scratch."),this.downloadPackage(),this.installPackage(),this.startAllServices();case"downloaded":return this.logger.info("Found package downloaded but not installed."),this.installPackage(),this.startAllServices();case"installed":{for(let[t]of u(this.services))this.startService(t);return this.live}}}startService(e){if(this.logger.info(`Starting service ${this.options.packageName}::${e}, try ${this.safety}/2...`),this.safety>=2)throw new Error("Out of tries...");this.safety++;let[t,...i]=this.options.services[e].run.split(" "),r=G(t,i,{cwd:this.options.flightdeckRootDir,env:import.meta.env}),n=this.serviceLoggers[e],a=this.services[e]=new z(r,`${this.options.packageName}::${e}`,n);n.processCode=a.process.pid??-1,this.services[e].onAny((...s)=>{n.info("\uD83D\uDCAC",...s)}),this.services[e].on("readyToUpdate",()=>{this.logger.info(`Service "${e}" is ready to update.`),this.servicesReadyToUpdate[e]=!0,this.tryUpdate()}),this.services[e].on("alive",()=>{if(this.servicesLive[this.serviceIdx[e]].use(Promise.resolve()),this.servicesDead[this.serviceIdx[e]]=new p(()=>{}),this.dead.done)this.dead=new p(()=>{});this.dead.use(Promise.all(this.servicesDead))}),this.services[e].process.once("close",(s)=>{if(this.logger.info(`Auto-respawn saw "${e}" exit with code ${s}`),this.services[e]=null,!this.autoRespawnDeadServices){this.logger.info(`Auto-respawn is off; "${e}" rests.`);return}let o=this.storage.getItem("updatePhase");if(this.logger.info('> storage("updatePhase") >',o),o==="confirmed")this.serviceLoggers[e].info("Updating before startup..."),this.restartTimes=[],this.installPackage(),this.startService(e);else{let l=Date.now(),d=l-300000;if(this.restartTimes=this.restartTimes.filter((f)=>f>d),this.restartTimes.push(l),this.restartTimes.length<5)this.serviceLoggers[e].info("Crashed. Restarting..."),this.startService(e);else this.serviceLoggers[e].info("Crashed 5 times in 5 minutes. Not restarting.")}}),this.safety=0}downloadPackage(){this.logger.info("Downloading...");try{let e=F(this.options.scripts.download);this.logger.info("Download stdout:",e.toString()),this.storage.setItem("setupPhase","downloaded"),this.logger.info("Downloaded!")}catch(e){if(e instanceof Error)this.logger.error(`Failed to get the latest release: ${e.message}`);return}}installPackage(){this.logger.info("Installing...");try{let e=F(this.options.scripts.install);this.logger.info("Install stdout:",e.toString()),this.storage.setItem("setupPhase","installed"),this.logger.info("Installed!")}catch(e){if(e instanceof Error)this.logger.error(`Failed to get the latest release: ${e.message}`);return}}stopAllServices(){this.logger.info("Stopping all services... auto-respawn disabled."),this.autoRespawnDeadServices=!1;for(let[e]of u(this.services))this.stopService(e);return this.dead}stopService(e){let t=this.services[e];if(t){if(this.logger.info(`Stopping service "${e}"...`),this.servicesDead[this.serviceIdx[e]].use(new Promise((i)=>{t.emit("timeToStop"),t.process.once("close",(r)=>{this.logger.info(`Stopped service "${e}"; exited with code ${r}`),this.services[e]=null,i()})})),this.dead.use(Promise.all(this.servicesDead)),this.servicesLive[this.serviceIdx[e]]=new p(()=>{}),this.live.done)this.live=new p(()=>{});this.live.use(Promise.all(this.servicesLive))}else this.serviceLoggers[e].error("Tried to stop service, but it wasn't running.")}}var m="info",y="warn",k="ERR!",we=c.object({level:c.union([c.literal(m),c.literal(y),c.literal(k)]),timestamp:c.number(),package:c.string(),service:c.string().optional(),process:c.number(),body:c.string()}),Z="line-format",Q="value",be={title:"FlightDeck Log",description:"Format for events logged by the FlightDeck process manager.","file-type":"json","timestamp-field":"timestamp","timestamp-divisor":1000,"module-field":"package","opid-field":"service","level-field":"level",level:{info:m,warning:y,error:k},[Z]:[{field:"level"},{prefix:" ",field:"__timestamp__","timestamp-format":"%Y-%m-%dT%H:%M:%S.%L%Z"},{prefix:" ",field:"process","min-width":5},{prefix:":",field:"package"},{prefix:":",field:"service","default-value":""},{prefix:": ",field:"body"}],[Q]:{timestamp:{kind:"integer"},level:{kind:"string"},package:{kind:"string"},service:{kind:"string"},process:{kind:"integer"},body:{kind:"string"}}};class D{packageName;serviceName;jsonLogging;processCode;constructor(e,t,i,r){if(this.packageName=e,i)this.serviceName=i;this.processCode=t,this.jsonLogging=r?.jsonLogging??!1}log(e,...t){if(this.jsonLogging){let i=t.map((n)=>typeof n==="string"?n:M(n,!1,null,!0)).join(" ");if(i.includes(`
2
+ `))i=`
3
+ ${i.split(`
4
+ `).join(`
5
+ `)}`;let r={timestamp:Date.now(),level:e,process:this.processCode,package:this.packageName,body:i};if(this.serviceName)r.service=this.serviceName;process.stdout.write(JSON.stringify(r)+`
6
+ `)}else{let i=this.serviceName?`${this.packageName}:${this.serviceName}`:this.packageName;switch(e){case m:console.log(`${i}:`,...t);break;case y:console.warn(`${i}:`,...t);break;case k:console.error(`${i}:`,...t);break}}}info(...e){this.log(m,...e)}warn(...e){this.log(y,...e)}error(...e){this.log(k,...e)}}var R={};$(R,{scramble:()=>X,alert:()=>C});async function C({secret:e,endpoint:t,version:i}){return await fetch(t,{method:"POST",headers:{"Content-Type":"text/plain;charset=UTF-8",Authorization:`Bearer ${e}`},body:i})}async function X({packageConfig:e,secretsConfig:t,publishedPackages:i}){let r=[];for(let s of i)if(s.name in e){let o=s.name,{endpoint:h}=e[o],l=t[o],d=s.version,f=C({secret:l,endpoint:h,version:d}).then((g)=>[o,g]);r.push(f)}let n=await Promise.all(r);return Object.fromEntries(n)}export{W as isVersionNumber,we as flightDeckLogSchema,R as Klaxon,D as FlightDeckLogger,Y as FlightDeck,b as FilesystemStorage,y as FLIGHTDECK_WARN,Se as FLIGHTDECK_UPDATE_PHASES,ke as FLIGHTDECK_SETUP_PHASES,be as FLIGHTDECK_LNAV_FORMAT,m as FLIGHTDECK_INFO,k as FLIGHTDECK_ERROR};
5
7
 
6
- //# debugId=D614A1AC9E2EE18564756E2164756E21
7
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2ZpbGVzeXN0ZW0tc3RvcmFnZS50cyIsICIuLi9zcmMvZmxpZ2h0ZGVjay5saWIudHMiLCAiLi4vc3JjL2ZsaWdodGRlY2suZW52LnRzIiwgIi4uL3NyYy9rbGF4b24ubGliLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWwogICAgImltcG9ydCB7XG5cdGV4aXN0c1N5bmMsXG5cdG1rZGlyU3luYyxcblx0cmVhZGRpclN5bmMsXG5cdHJlYWRGaWxlU3luYyxcblx0cm1TeW5jLFxuXHRzdGF0U3luYyxcblx0d3JpdGVGaWxlU3luYyxcbn0gZnJvbSBcIm5vZGU6ZnNcIlxuaW1wb3J0IHsgcmVzb2x2ZSB9IGZyb20gXCJub2RlOnBhdGhcIlxuXG5leHBvcnQgdHlwZSBGaWxlc3lzdGVtU3RvcmFnZU9wdGlvbnMgPSB7XG5cdHBhdGg6IHN0cmluZ1xufVxuXG5leHBvcnQgY2xhc3MgRmlsZXN5c3RlbVN0b3JhZ2U8XG5cdFQgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0gUmVjb3JkPHN0cmluZywgc3RyaW5nPixcbj4gaW1wbGVtZW50cyBTdG9yYWdlXG57XG5cdHB1YmxpYyByb290RGlyOiBzdHJpbmdcblxuXHRwdWJsaWMgY29uc3RydWN0b3Iob3B0aW9uczogRmlsZXN5c3RlbVN0b3JhZ2VPcHRpb25zKSB7XG5cdFx0dGhpcy5yb290RGlyID0gb3B0aW9ucy5wYXRoXG5cdFx0aWYgKCFleGlzdHNTeW5jKHRoaXMucm9vdERpcikpIHtcblx0XHRcdG1rZGlyU3luYyh0aGlzLnJvb3REaXIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pXG5cdFx0fVxuXHR9XG5cblx0cHVibGljIGdldEl0ZW08SyBleHRlbmRzIHN0cmluZyAmIGtleW9mIFQ+KGtleTogSyk6IFRbS10gfCBudWxsIHtcblx0XHRjb25zdCBmaWxlUGF0aCA9IHJlc29sdmUodGhpcy5yb290RGlyLCBrZXkpXG5cdFx0aWYgKGV4aXN0c1N5bmMoZmlsZVBhdGgpKSB7XG5cdFx0XHRyZXR1cm4gcmVhZEZpbGVTeW5jKGZpbGVQYXRoLCBgdXRmLThgKSBhcyBUW0tdXG5cdFx0fVxuXHRcdHJldHVybiBudWxsXG5cdH1cblxuXHRwdWJsaWMgc2V0SXRlbTxLIGV4dGVuZHMgc3RyaW5nICYga2V5b2YgVD4oa2V5OiBLLCB2YWx1ZTogVFtLXSk6IHZvaWQge1xuXHRcdGNvbnN0IGZpbGVQYXRoID0gcmVzb2x2ZSh0aGlzLnJvb3REaXIsIGtleSlcblx0XHR3cml0ZUZpbGVTeW5jKGZpbGVQYXRoLCB2YWx1ZSlcblx0fVxuXG5cdHB1YmxpYyByZW1vdmVJdGVtPEsgZXh0ZW5kcyBzdHJpbmcgJiBrZXlvZiBUPihrZXk6IEspOiB2b2lkIHtcblx0XHRjb25zdCBmaWxlUGF0aCA9IHJlc29sdmUodGhpcy5yb290RGlyLCBrZXkpXG5cdFx0aWYgKGV4aXN0c1N5bmMoZmlsZVBhdGgpKSB7XG5cdFx0XHRybVN5bmMoZmlsZVBhdGgpXG5cdFx0fVxuXHR9XG5cblx0cHVibGljIGtleShpbmRleDogbnVtYmVyKTogKHN0cmluZyAmIGtleW9mIFQpIHwgbnVsbCB7XG5cdFx0Y29uc3QgZmlsZVBhdGhzID0gcmVhZGRpclN5bmModGhpcy5yb290RGlyKVxuXHRcdGNvbnN0IGZpbGVQYXRoc0J5RGF0ZUNyZWF0ZWQgPSBmaWxlUGF0aHMuc29ydCgoYSwgYikgPT4ge1xuXHRcdFx0Y29uc3QgYVN0YXQgPSBzdGF0U3luYyhhKVxuXHRcdFx0Y29uc3QgYlN0YXQgPSBzdGF0U3luYyhiKVxuXHRcdFx0cmV0dXJuIGJTdGF0LmN0aW1lTXMgLSBhU3RhdC5jdGltZU1zXG5cdFx0fSlcblx0XHRyZXR1cm4gKGZpbGVQYXRoc0J5RGF0ZUNyZWF0ZWRbaW5kZXhdIGFzIHN0cmluZyAmIGtleW9mIFQpID8/IG51bGxcblx0fVxuXG5cdHB1YmxpYyBjbGVhcigpOiB2b2lkIHtcblx0XHRybVN5bmModGhpcy5yb290RGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KVxuXHRcdG1rZGlyU3luYyh0aGlzLnJvb3REaXIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pXG5cdH1cblxuXHRwdWJsaWMgZ2V0IGxlbmd0aCgpOiBudW1iZXIge1xuXHRcdHJldHVybiByZWFkZGlyU3luYyh0aGlzLnJvb3REaXIpLmxlbmd0aFxuXHR9XG59XG4iLAogICAgImltcG9ydCB7IGV4ZWNTeW5jLCBzcGF3biB9IGZyb20gXCJub2RlOmNoaWxkX3Byb2Nlc3NcIlxuaW1wb3J0IHR5cGUgeyBTZXJ2ZXIgfSBmcm9tIFwibm9kZTpodHRwXCJcbmltcG9ydCB7IGNyZWF0ZVNlcnZlciB9IGZyb20gXCJub2RlOmh0dHBcIlxuaW1wb3J0IHsgaG9tZWRpciB9IGZyb20gXCJub2RlOm9zXCJcbmltcG9ydCB7IHJlc29sdmUgfSBmcm9tIFwibm9kZTpwYXRoXCJcbmltcG9ydCB7IGluc3BlY3QgfSBmcm9tIFwibm9kZTp1dGlsXCJcblxuaW1wb3J0IHsgRnV0dXJlIH0gZnJvbSBcImF0b20uaW8vaW50ZXJuYWxcIlxuaW1wb3J0IHsgZGlzY292ZXJUeXBlIH0gZnJvbSBcImF0b20uaW8vaW50cm9zcGVjdGlvblwiXG5pbXBvcnQgeyBmcm9tRW50cmllcywgdG9FbnRyaWVzIH0gZnJvbSBcImF0b20uaW8vanNvblwiXG5pbXBvcnQgeyBDaGlsZFNvY2tldCB9IGZyb20gXCJhdG9tLmlvL3JlYWx0aW1lLXNlcnZlclwiXG5pbXBvcnQgeyBDcm9uSm9iIH0gZnJvbSBcImNyb25cIlxuaW1wb3J0IHsgeiB9IGZyb20gXCJ6b2RcIlxuXG5pbXBvcnQgdHlwZSB7IExuYXZGb3JtYXQgfSBmcm9tIFwiLi4vZ2VuL2xuYXYtZm9ybWF0LXNjaGVtYS5nZW5cIlxuaW1wb3J0IHsgRmlsZXN5c3RlbVN0b3JhZ2UgfSBmcm9tIFwiLi9maWxlc3lzdGVtLXN0b3JhZ2VcIlxuaW1wb3J0IHsgZW52IH0gZnJvbSBcIi4vZmxpZ2h0ZGVjay5lbnZcIlxuXG5leHBvcnQgY29uc3QgRkxJR0hUREVDS19TRVRVUF9QSEFTRVMgPSBbYGRvd25sb2FkZWRgLCBgaW5zdGFsbGVkYF0gYXMgY29uc3RcblxuZXhwb3J0IHR5cGUgRmxpZ2h0RGVja1NldHVwUGhhc2UgPSAodHlwZW9mIEZMSUdIVERFQ0tfU0VUVVBfUEhBU0VTKVtudW1iZXJdXG5cbmV4cG9ydCBjb25zdCBGTElHSFRERUNLX1VQREFURV9QSEFTRVMgPSBbYG5vdGlmaWVkYCwgYGNvbmZpcm1lZGBdIGFzIGNvbnN0XG5cbmV4cG9ydCB0eXBlIEZsaWdodERlY2tVcGRhdGVQaGFzZSA9ICh0eXBlb2YgRkxJR0hUREVDS19VUERBVEVfUEhBU0VTKVtudW1iZXJdXG5cbmV4cG9ydCBmdW5jdGlvbiBpc1ZlcnNpb25OdW1iZXIodmVyc2lvbjogc3RyaW5nKTogYm9vbGVhbiB7XG5cdHJldHVybiAoXG5cdFx0L15cXGQrXFwuXFxkK1xcLlxcZCskLy50ZXN0KHZlcnNpb24pIHx8ICFOdW1iZXIuaXNOYU4oTnVtYmVyLnBhcnNlRmxvYXQodmVyc2lvbikpXG5cdClcbn1cblxuZXhwb3J0IHR5cGUgRmxpZ2h0RGVja09wdGlvbnM8UyBleHRlbmRzIHN0cmluZyA9IHN0cmluZz4gPSB7XG5cdHBhY2thZ2VOYW1lOiBzdHJpbmdcblx0c2VydmljZXM6IHsgW3NlcnZpY2UgaW4gU106IHsgcnVuOiBzdHJpbmc7IHdhaXRGb3I6IGJvb2xlYW4gfSB9XG5cdHNjcmlwdHM6IHtcblx0XHRkb3dubG9hZDogc3RyaW5nXG5cdFx0aW5zdGFsbDogc3RyaW5nXG5cdFx0Y2hlY2tBdmFpbGFiaWxpdHk/OiBzdHJpbmdcblx0fVxuXHRwb3J0PzogbnVtYmVyIHwgdW5kZWZpbmVkXG5cdGZsaWdodGRlY2tSb290RGlyPzogc3RyaW5nIHwgdW5kZWZpbmVkXG5cdGpzb25Mb2dnaW5nPzogYm9vbGVhbiB8IHVuZGVmaW5lZFxufVxuXG5leHBvcnQgY2xhc3MgRmxpZ2h0RGVjazxTIGV4dGVuZHMgc3RyaW5nID0gc3RyaW5nPiB7XG5cdHByb3RlY3RlZCBzYWZldHkgPSAwXG5cblx0cHJvdGVjdGVkIHN0b3JhZ2U6IEZpbGVzeXN0ZW1TdG9yYWdlPHtcblx0XHRzZXR1cFBoYXNlOiBGbGlnaHREZWNrU2V0dXBQaGFzZVxuXHRcdHVwZGF0ZVBoYXNlOiBGbGlnaHREZWNrVXBkYXRlUGhhc2Vcblx0XHR1cGRhdGVBd2FpdGVkVmVyc2lvbjogc3RyaW5nXG5cdH0+XG5cdHByb3RlY3RlZCB3ZWJob29rU2VydmVyOiBTZXJ2ZXJcblx0cHJvdGVjdGVkIHNlcnZpY2VzOiB7XG5cdFx0W3NlcnZpY2UgaW4gU106IENoaWxkU29ja2V0PFxuXHRcdFx0eyB0aW1lVG9TdG9wOiBbXTsgdXBkYXRlc1JlYWR5OiBbXSB9LFxuXHRcdFx0eyByZWFkeVRvVXBkYXRlOiBbXTsgYWxpdmU6IFtdIH1cblx0XHQ+IHwgbnVsbFxuXHR9XG5cdHByb3RlY3RlZCBzZXJ2aWNlSWR4OiB7IHJlYWRvbmx5IFtzZXJ2aWNlIGluIFNdOiBudW1iZXIgfVxuXHRwdWJsaWMgZGVmYXVsdFNlcnZpY2VzUmVhZHlUb1VwZGF0ZTogeyByZWFkb25seSBbc2VydmljZSBpbiBTXTogYm9vbGVhbiB9XG5cdHB1YmxpYyBzZXJ2aWNlc1JlYWR5VG9VcGRhdGU6IHsgW3NlcnZpY2UgaW4gU106IGJvb2xlYW4gfVxuXHRwdWJsaWMgYXV0b1Jlc3Bhd25EZWFkU2VydmljZXM6IGJvb2xlYW5cblxuXHRwcm90ZWN0ZWQgbG9nZ2VyOiBQaWNrPENvbnNvbGUsIGBlcnJvcmAgfCBgaW5mb2AgfCBgd2FybmA+XG5cdHByb3RlY3RlZCBzZXJ2aWNlTG9nZ2Vyczoge1xuXHRcdHJlYWRvbmx5IFtzZXJ2aWNlIGluIFNdOiBGbGlnaHREZWNrTG9nZ2VyXG5cdH1cblxuXHRwcm90ZWN0ZWQgdXBkYXRlQXZhaWxhYmlsaXR5Q2hlY2tlcjogQ3JvbkpvYiB8IG51bGwgPSBudWxsXG5cblx0cHVibGljIHNlcnZpY2VzTGl2ZTogRnV0dXJlPHZvaWQ+W11cblx0cHVibGljIHNlcnZpY2VzRGVhZDogRnV0dXJlPHZvaWQ+W11cblx0cHVibGljIGxpdmUgPSBuZXcgRnV0dXJlKCgpID0+IHt9KVxuXHRwdWJsaWMgZGVhZCA9IG5ldyBGdXR1cmUoKCkgPT4ge30pXG5cblx0cHJvdGVjdGVkIHJlc3RhcnRUaW1lczogbnVtYmVyW10gPSBbXVxuXG5cdHB1YmxpYyBjb25zdHJ1Y3RvcihwdWJsaWMgcmVhZG9ubHkgb3B0aW9uczogRmxpZ2h0RGVja09wdGlvbnM8Uz4pIHtcblx0XHRjb25zdCB7IEZMSUdIVERFQ0tfU0VDUkVUIH0gPSBlbnZcblx0XHRjb25zdCB7IGZsaWdodGRlY2tSb290RGlyID0gcmVzb2x2ZShob21lZGlyKCksIGAuZmxpZ2h0ZGVja2ApIH0gPSBvcHRpb25zXG5cdFx0Y29uc3QgcG9ydCA9IG9wdGlvbnMucG9ydCA/PyA4MDgwXG5cdFx0Y29uc3Qgb3JpZ2luID0gYGh0dHA6Ly9sb2NhbGhvc3Q6JHtwb3J0fWBcblxuXHRcdGNvbnN0IHNlcnZpY2VzRW50cmllcyA9IHRvRW50cmllcyhvcHRpb25zLnNlcnZpY2VzKVxuXHRcdHRoaXMuc2VydmljZXMgPSBmcm9tRW50cmllcyhcblx0XHRcdHNlcnZpY2VzRW50cmllcy5tYXAoKFtzZXJ2aWNlTmFtZV0pID0+IFtzZXJ2aWNlTmFtZSwgbnVsbF0pLFxuXHRcdClcblx0XHR0aGlzLnNlcnZpY2VJZHggPSBmcm9tRW50cmllcyhcblx0XHRcdHNlcnZpY2VzRW50cmllcy5tYXAoKFtzZXJ2aWNlTmFtZV0sIGlkeCkgPT4gW3NlcnZpY2VOYW1lLCBpZHhdKSxcblx0XHQpXG5cdFx0dGhpcy5kZWZhdWx0U2VydmljZXNSZWFkeVRvVXBkYXRlID0gZnJvbUVudHJpZXMoXG5cdFx0XHRzZXJ2aWNlc0VudHJpZXMubWFwKChbc2VydmljZU5hbWUsIHsgd2FpdEZvciB9XSkgPT4gW1xuXHRcdFx0XHRzZXJ2aWNlTmFtZSxcblx0XHRcdFx0IXdhaXRGb3IsXG5cdFx0XHRdKSxcblx0XHQpXG5cdFx0dGhpcy5zZXJ2aWNlc1JlYWR5VG9VcGRhdGUgPSB7IC4uLnRoaXMuZGVmYXVsdFNlcnZpY2VzUmVhZHlUb1VwZGF0ZSB9XG5cdFx0dGhpcy5hdXRvUmVzcGF3bkRlYWRTZXJ2aWNlcyA9IHRydWVcblxuXHRcdHRoaXMubG9nZ2VyID0gbmV3IEZsaWdodERlY2tMb2dnZXIoXG5cdFx0XHR0aGlzLm9wdGlvbnMucGFja2FnZU5hbWUsXG5cdFx0XHRwcm9jZXNzLnBpZCxcblx0XHRcdHVuZGVmaW5lZCxcblx0XHRcdHsganNvbkxvZ2dpbmc6IHRoaXMub3B0aW9ucy5qc29uTG9nZ2luZyA/PyBmYWxzZSB9LFxuXHRcdClcblx0XHR0aGlzLnNlcnZpY2VMb2dnZXJzID0gZnJvbUVudHJpZXMoXG5cdFx0XHRzZXJ2aWNlc0VudHJpZXMubWFwKChbc2VydmljZU5hbWVdKSA9PiBbXG5cdFx0XHRcdHNlcnZpY2VOYW1lLFxuXHRcdFx0XHRuZXcgRmxpZ2h0RGVja0xvZ2dlcihcblx0XHRcdFx0XHR0aGlzLm9wdGlvbnMucGFja2FnZU5hbWUsXG5cdFx0XHRcdFx0cHJvY2Vzcy5waWQsXG5cdFx0XHRcdFx0c2VydmljZU5hbWUsXG5cdFx0XHRcdFx0eyBqc29uTG9nZ2luZzogdGhpcy5vcHRpb25zLmpzb25Mb2dnaW5nID8/IGZhbHNlIH0sXG5cdFx0XHRcdCksXG5cdFx0XHRdKSxcblx0XHQpXG5cblx0XHR0aGlzLnNlcnZpY2VzTGl2ZSA9IHNlcnZpY2VzRW50cmllcy5tYXAoKCkgPT4gbmV3IEZ1dHVyZSgoKSA9PiB7fSkpXG5cdFx0dGhpcy5zZXJ2aWNlc0RlYWQgPSBzZXJ2aWNlc0VudHJpZXMubWFwKCgpID0+IG5ldyBGdXR1cmUoKCkgPT4ge30pKVxuXHRcdHRoaXMubGl2ZS51c2UoUHJvbWlzZS5hbGwodGhpcy5zZXJ2aWNlc0xpdmUpKVxuXHRcdHRoaXMuZGVhZC51c2UoUHJvbWlzZS5hbGwodGhpcy5zZXJ2aWNlc0RlYWQpKVxuXG5cdFx0dGhpcy5zdG9yYWdlID0gbmV3IEZpbGVzeXN0ZW1TdG9yYWdlKHtcblx0XHRcdHBhdGg6IHJlc29sdmUoZmxpZ2h0ZGVja1Jvb3REaXIsIGBzdG9yYWdlYCwgb3B0aW9ucy5wYWNrYWdlTmFtZSksXG5cdFx0fSlcblxuXHRcdGlmIChGTElHSFRERUNLX1NFQ1JFVCA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHR0aGlzLmxvZ2dlci53YXJuKFxuXHRcdFx0XHRgTm8gRkxJR0hUREVDS19TRUNSRVQgZW52aXJvbm1lbnQgdmFyaWFibGUgZm91bmQuIEZsaWdodERlY2sgd2lsbCBub3QgcnVuIGFuIHVwZGF0ZSBzZXJ2ZXIuYCxcblx0XHRcdClcblx0XHR9IGVsc2Uge1xuXHRcdFx0Y3JlYXRlU2VydmVyKChyZXEsIHJlcykgPT4ge1xuXHRcdFx0XHRsZXQgZGF0YTogVWludDhBcnJheVtdID0gW11cblx0XHRcdFx0cmVxXG5cdFx0XHRcdFx0Lm9uKGBkYXRhYCwgKGNodW5rKSA9PiB7XG5cdFx0XHRcdFx0XHRkYXRhLnB1c2goY2h1bmsgaW5zdGFuY2VvZiBCdWZmZXIgPyBjaHVuayA6IEJ1ZmZlci5mcm9tKGNodW5rKSlcblx0XHRcdFx0XHR9KVxuXHRcdFx0XHRcdC5vbihgZW5kYCwgKCkgPT4ge1xuXHRcdFx0XHRcdFx0Y29uc3QgYXV0aEhlYWRlciA9IHJlcS5oZWFkZXJzLmF1dGhvcml6YXRpb25cblx0XHRcdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0XHRcdGlmICh0eXBlb2YgcmVxLnVybCA9PT0gYHVuZGVmaW5lZGApIHRocm93IDQwMFxuXHRcdFx0XHRcdFx0XHRjb25zdCBleHBlY3RlZEF1dGhIZWFkZXIgPSBgQmVhcmVyICR7RkxJR0hUREVDS19TRUNSRVR9YFxuXHRcdFx0XHRcdFx0XHRpZiAoYXV0aEhlYWRlciAhPT0gYEJlYXJlciAke0ZMSUdIVERFQ0tfU0VDUkVUfWApIHtcblx0XHRcdFx0XHRcdFx0XHR0aGlzLmxvZ2dlci5pbmZvKFxuXHRcdFx0XHRcdFx0XHRcdFx0YFVuYXV0aG9yaXplZDogbmVlZGVkIFxcYCR7ZXhwZWN0ZWRBdXRoSGVhZGVyfVxcYCwgZ290IFxcYCR7YXV0aEhlYWRlcn1cXGBgLFxuXHRcdFx0XHRcdFx0XHRcdClcblx0XHRcdFx0XHRcdFx0XHR0aHJvdyA0MDFcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRjb25zdCB1cmwgPSBuZXcgVVJMKHJlcS51cmwsIG9yaWdpbilcblx0XHRcdFx0XHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhyZXEubWV0aG9kLCB1cmwucGF0aG5hbWUpXG5cblx0XHRcdFx0XHRcdFx0Y29uc3QgdmVyc2lvbkZvcmVpZ25JbnB1dCA9IEJ1ZmZlci5jb25jYXQoZGF0YSkudG9TdHJpbmcoKVxuXHRcdFx0XHRcdFx0XHRpZiAoIWlzVmVyc2lvbk51bWJlcih2ZXJzaW9uRm9yZWlnbklucHV0KSkge1xuXHRcdFx0XHRcdFx0XHRcdHRocm93IDQwMFxuXHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0cmVzLndyaXRlSGVhZCgyMDApXG5cdFx0XHRcdFx0XHRcdHJlcy5lbmQoKVxuXG5cdFx0XHRcdFx0XHRcdHRoaXMuc3RvcmFnZS5zZXRJdGVtKGB1cGRhdGVQaGFzZWAsIGBub3RpZmllZGApXG5cdFx0XHRcdFx0XHRcdHRoaXMuc3RvcmFnZS5zZXRJdGVtKGB1cGRhdGVBd2FpdGVkVmVyc2lvbmAsIHZlcnNpb25Gb3JlaWduSW5wdXQpXG5cdFx0XHRcdFx0XHRcdGNvbnN0IHsgY2hlY2tBdmFpbGFiaWxpdHkgfSA9IG9wdGlvbnMuc2NyaXB0c1xuXHRcdFx0XHRcdFx0XHRpZiAoY2hlY2tBdmFpbGFiaWxpdHkpIHtcblx0XHRcdFx0XHRcdFx0XHR0aGlzLnVwZGF0ZUF2YWlsYWJpbGl0eUNoZWNrZXI/LnN0b3AoKVxuXHRcdFx0XHRcdFx0XHRcdHRoaXMuc2Vla1VwZGF0ZSh2ZXJzaW9uRm9yZWlnbklucHV0KVxuXHRcdFx0XHRcdFx0XHRcdGNvbnN0IHVwZGF0ZVBoYXNlID0gdGhpcy5zdG9yYWdlLmdldEl0ZW0oYHVwZGF0ZVBoYXNlYClcblx0XHRcdFx0XHRcdFx0XHR0aGlzLmxvZ2dlci5pbmZvKGA+IHN0b3JhZ2UoXCJ1cGRhdGVQaGFzZVwiKSA+YCwgdXBkYXRlUGhhc2UpXG5cdFx0XHRcdFx0XHRcdFx0aWYgKHVwZGF0ZVBoYXNlID09PSBgbm90aWZpZWRgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHR0aGlzLnVwZGF0ZUF2YWlsYWJpbGl0eUNoZWNrZXIgPSBuZXcgQ3JvbkpvYihcblx0XHRcdFx0XHRcdFx0XHRcdFx0YDMwICogKiAqICogKmAsXG5cdFx0XHRcdFx0XHRcdFx0XHRcdCgpID0+IHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHR0aGlzLnNlZWtVcGRhdGUodmVyc2lvbkZvcmVpZ25JbnB1dClcblx0XHRcdFx0XHRcdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRcdFx0XHRcdClcblx0XHRcdFx0XHRcdFx0XHRcdHRoaXMudXBkYXRlQXZhaWxhYmlsaXR5Q2hlY2tlci5zdGFydCgpXG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRcdHRoaXMuZG93bmxvYWRQYWNrYWdlKClcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fSBjYXRjaCAodGhyb3duKSB7XG5cdFx0XHRcdFx0XHRcdHRoaXMubG9nZ2VyLmVycm9yKHRocm93biwgcmVxLnVybClcblx0XHRcdFx0XHRcdFx0aWYgKHR5cGVvZiB0aHJvd24gPT09IGBudW1iZXJgKSB7XG5cdFx0XHRcdFx0XHRcdFx0cmVzLndyaXRlSGVhZCh0aHJvd24pXG5cdFx0XHRcdFx0XHRcdFx0cmVzLmVuZCgpXG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH0gZmluYWxseSB7XG5cdFx0XHRcdFx0XHRcdGRhdGEgPSBbXVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0pXG5cdFx0XHR9KS5saXN0ZW4ocG9ydCwgKCkgPT4ge1xuXHRcdFx0XHR0aGlzLmxvZ2dlci5pbmZvKGBTZXJ2ZXIgc3RhcnRlZCBvbiBwb3J0ICR7cG9ydH1gKVxuXHRcdFx0fSlcblx0XHR9XG5cblx0XHR0aGlzLnN0YXJ0QWxsU2VydmljZXMoKVxuXHRcdFx0LnRoZW4oKCkgPT4ge1xuXHRcdFx0XHR0aGlzLmxvZ2dlci5pbmZvKGBBbGwgc2VydmljZXMgc3RhcnRlZC5gKVxuXHRcdFx0fSlcblx0XHRcdC5jYXRjaCgodGhyb3duKSA9PiB7XG5cdFx0XHRcdGlmICh0aHJvd24gaW5zdGFuY2VvZiBFcnJvcikge1xuXHRcdFx0XHRcdHRoaXMubG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gc3RhcnQgYWxsIHNlcnZpY2VzOmAsIHRocm93bi5tZXNzYWdlKVxuXHRcdFx0XHR9XG5cdFx0XHR9KVxuXHR9XG5cblx0cHJvdGVjdGVkIHNlZWtVcGRhdGUodmVyc2lvbjogc3RyaW5nKTogdm9pZCB7XG5cdFx0dGhpcy5sb2dnZXIuaW5mbyhgQ2hlY2tpbmcgZm9yIHVwZGF0ZXMuLi5gKVxuXHRcdGNvbnN0IHsgY2hlY2tBdmFpbGFiaWxpdHkgfSA9IHRoaXMub3B0aW9ucy5zY3JpcHRzXG5cdFx0aWYgKCFjaGVja0F2YWlsYWJpbGl0eSkge1xuXHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhgTm8gY2hlY2tBdmFpbGFiaWxpdHkgc2NyaXB0IGZvdW5kLmApXG5cdFx0XHRyZXR1cm5cblx0XHR9XG5cdFx0dHJ5IHtcblx0XHRcdGNvbnN0IG91dCA9IGV4ZWNTeW5jKGAke2NoZWNrQXZhaWxhYmlsaXR5fSAke3ZlcnNpb259YClcblx0XHRcdHRoaXMubG9nZ2VyLmluZm8oYENoZWNrIHN0ZG91dDpgLCBvdXQudG9TdHJpbmcoKSlcblx0XHRcdHRoaXMudXBkYXRlQXZhaWxhYmlsaXR5Q2hlY2tlcj8uc3RvcCgpXG5cdFx0XHR0aGlzLnN0b3JhZ2Uuc2V0SXRlbShgdXBkYXRlUGhhc2VgLCBgY29uZmlybWVkYClcblx0XHRcdHRoaXMuZG93bmxvYWRQYWNrYWdlKClcblx0XHRcdHRoaXMuYW5ub3VuY2VVcGRhdGUoKVxuXHRcdH0gY2F0Y2ggKHRocm93bikge1xuXHRcdFx0aWYgKHRocm93biBpbnN0YW5jZW9mIEVycm9yKSB7XG5cdFx0XHRcdHRoaXMubG9nZ2VyLmVycm9yKGBDaGVjayBmYWlsZWQ6YCwgdGhyb3duLm1lc3NhZ2UpXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRjb25zdCB0aHJvd25UeXBlID0gZGlzY292ZXJUeXBlKHRocm93bilcblx0XHRcdFx0dGhpcy5sb2dnZXIuZXJyb3IoYENoZWNrIHRocmV3YCwgdGhyb3duVHlwZSwgdGhyb3duKVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHByb3RlY3RlZCBhbm5vdW5jZVVwZGF0ZSgpOiB2b2lkIHtcblx0XHRmb3IgKGNvbnN0IGVudHJ5IG9mIHRvRW50cmllcyh0aGlzLnNlcnZpY2VzKSkge1xuXHRcdFx0Y29uc3QgW3NlcnZpY2VOYW1lLCBzZXJ2aWNlXSA9IGVudHJ5XG5cdFx0XHRpZiAoc2VydmljZSkge1xuXHRcdFx0XHRpZiAodGhpcy5vcHRpb25zLnNlcnZpY2VzW3NlcnZpY2VOYW1lXS53YWl0Rm9yKSB7XG5cdFx0XHRcdFx0c2VydmljZS5lbWl0KGB1cGRhdGVzUmVhZHlgKVxuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0aGlzLnN0YXJ0U2VydmljZShzZXJ2aWNlTmFtZSlcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRwcm90ZWN0ZWQgdHJ5VXBkYXRlKCk6IHZvaWQge1xuXHRcdGlmICh0b0VudHJpZXModGhpcy5zZXJ2aWNlc1JlYWR5VG9VcGRhdGUpLmV2ZXJ5KChbLCBpc1JlYWR5XSkgPT4gaXNSZWFkeSkpIHtcblx0XHRcdHRoaXMubG9nZ2VyLmluZm8oYEFsbCBzZXJ2aWNlcyBhcmUgcmVhZHkgdG8gdXBkYXRlLmApXG5cdFx0XHR0aGlzLnN0b3BBbGxTZXJ2aWNlcygpXG5cdFx0XHRcdC50aGVuKCgpID0+IHtcblx0XHRcdFx0XHR0aGlzLmxvZ2dlci5pbmZvKGBBbGwgc2VydmljZXMgc3RvcHBlZDsgc3RhcnRpbmcgdXAgZnJlc2guLi5gKVxuXHRcdFx0XHRcdHRoaXMuc3RhcnRBbGxTZXJ2aWNlcygpXG5cdFx0XHRcdFx0XHQudGhlbigoKSA9PiB7XG5cdFx0XHRcdFx0XHRcdHRoaXMubG9nZ2VyLmluZm8oYEFsbCBzZXJ2aWNlcyBzdGFydGVkOyB3ZSdyZSBiYWNrIG9ubGluZS5gKVxuXHRcdFx0XHRcdFx0fSlcblx0XHRcdFx0XHRcdC5jYXRjaCgodGhyb3duKSA9PiB7XG5cdFx0XHRcdFx0XHRcdGlmICh0aHJvd24gaW5zdGFuY2VvZiBFcnJvcikge1xuXHRcdFx0XHRcdFx0XHRcdHRoaXMubG9nZ2VyLmVycm9yKFxuXHRcdFx0XHRcdFx0XHRcdFx0YEZhaWxlZCB0byBzdGFydCBhbGwgc2VydmljZXM6YCxcblx0XHRcdFx0XHRcdFx0XHRcdHRocm93bi5tZXNzYWdlLFxuXHRcdFx0XHRcdFx0XHRcdClcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fSlcblx0XHRcdFx0fSlcblx0XHRcdFx0LmNhdGNoKCh0aHJvd24pID0+IHtcblx0XHRcdFx0XHRpZiAodGhyb3duIGluc3RhbmNlb2YgRXJyb3IpIHtcblx0XHRcdFx0XHRcdHRoaXMubG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gc3RvcCBhbGwgc2VydmljZXM6YCwgdGhyb3duLm1lc3NhZ2UpXG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KVxuXHRcdH1cblx0fVxuXG5cdHByb3RlY3RlZCBzdGFydEFsbFNlcnZpY2VzKCk6IEZ1dHVyZTx1bmtub3duPiB7XG5cdFx0dGhpcy5sb2dnZXIuaW5mbyhgU3RhcnRpbmcgYWxsIHNlcnZpY2VzLi4uYClcblx0XHR0aGlzLmF1dG9SZXNwYXduRGVhZFNlcnZpY2VzID0gdHJ1ZVxuXHRcdGNvbnN0IHNldHVwUGhhc2UgPSB0aGlzLnN0b3JhZ2UuZ2V0SXRlbShgc2V0dXBQaGFzZWApXG5cdFx0dGhpcy5sb2dnZXIuaW5mbyhgPiBzdG9yYWdlKFwic2V0dXBQaGFzZVwiKSA+YCwgc2V0dXBQaGFzZSlcblx0XHRzd2l0Y2ggKHNldHVwUGhhc2UpIHtcblx0XHRcdGNhc2UgbnVsbDpcblx0XHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhgU3RhcnRpbmcgZnJvbSBzY3JhdGNoLmApXG5cdFx0XHRcdHRoaXMuZG93bmxvYWRQYWNrYWdlKClcblx0XHRcdFx0dGhpcy5pbnN0YWxsUGFja2FnZSgpXG5cdFx0XHRcdHJldHVybiB0aGlzLnN0YXJ0QWxsU2VydmljZXMoKVxuXHRcdFx0Y2FzZSBgZG93bmxvYWRlZGA6XG5cdFx0XHRcdHRoaXMubG9nZ2VyLmluZm8oYEZvdW5kIHBhY2thZ2UgZG93bmxvYWRlZCBidXQgbm90IGluc3RhbGxlZC5gKVxuXHRcdFx0XHR0aGlzLmluc3RhbGxQYWNrYWdlKClcblx0XHRcdFx0cmV0dXJuIHRoaXMuc3RhcnRBbGxTZXJ2aWNlcygpXG5cdFx0XHRjYXNlIGBpbnN0YWxsZWRgOiB7XG5cdFx0XHRcdGZvciAoY29uc3QgW3NlcnZpY2VOYW1lXSBvZiB0b0VudHJpZXModGhpcy5zZXJ2aWNlcykpIHtcblx0XHRcdFx0XHR0aGlzLnN0YXJ0U2VydmljZShzZXJ2aWNlTmFtZSlcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gdGhpcy5saXZlXG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0cHJvdGVjdGVkIHN0YXJ0U2VydmljZShzZXJ2aWNlTmFtZTogUyk6IHZvaWQge1xuXHRcdHRoaXMubG9nZ2VyLmluZm8oXG5cdFx0XHRgU3RhcnRpbmcgc2VydmljZSAke3RoaXMub3B0aW9ucy5wYWNrYWdlTmFtZX06OiR7c2VydmljZU5hbWV9LCB0cnkgJHt0aGlzLnNhZmV0eX0vMi4uLmAsXG5cdFx0KVxuXHRcdGlmICh0aGlzLnNhZmV0eSA+PSAyKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoYE91dCBvZiB0cmllcy4uLmApXG5cdFx0fVxuXHRcdHRoaXMuc2FmZXR5KytcblxuXHRcdGNvbnN0IFtleGUsIC4uLmFyZ3NdID0gdGhpcy5vcHRpb25zLnNlcnZpY2VzW3NlcnZpY2VOYW1lXS5ydW4uc3BsaXQoYCBgKVxuXHRcdGNvbnN0IHNlcnZpY2VQcm9jZXNzID0gc3Bhd24oZXhlLCBhcmdzLCB7XG5cdFx0XHRjd2Q6IHRoaXMub3B0aW9ucy5mbGlnaHRkZWNrUm9vdERpcixcblx0XHRcdGVudjogaW1wb3J0Lm1ldGEuZW52LFxuXHRcdH0pXG5cdFx0Y29uc3Qgc2VydmljZUxvZ2dlciA9IHRoaXMuc2VydmljZUxvZ2dlcnNbc2VydmljZU5hbWVdXG5cdFx0Y29uc3Qgc2VydmljZSA9ICh0aGlzLnNlcnZpY2VzW3NlcnZpY2VOYW1lXSA9IG5ldyBDaGlsZFNvY2tldChcblx0XHRcdHNlcnZpY2VQcm9jZXNzLFxuXHRcdFx0YCR7dGhpcy5vcHRpb25zLnBhY2thZ2VOYW1lfTo6JHtzZXJ2aWNlTmFtZX1gLFxuXHRcdFx0c2VydmljZUxvZ2dlcixcblx0XHQpKVxuXHRcdHNlcnZpY2VMb2dnZXIucHJvY2Vzc0NvZGUgPSBzZXJ2aWNlLnByb2Nlc3MucGlkID8/IC0xXG5cdFx0dGhpcy5zZXJ2aWNlc1tzZXJ2aWNlTmFtZV0ub25BbnkoKC4uLm1lc3NhZ2VzKSA9PiB7XG5cdFx0XHRzZXJ2aWNlTG9nZ2VyLmluZm8oYPCfkqxgLCAuLi5tZXNzYWdlcylcblx0XHR9KVxuXHRcdHRoaXMuc2VydmljZXNbc2VydmljZU5hbWVdLm9uKGByZWFkeVRvVXBkYXRlYCwgKCkgPT4ge1xuXHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhgU2VydmljZSBcIiR7c2VydmljZU5hbWV9XCIgaXMgcmVhZHkgdG8gdXBkYXRlLmApXG5cdFx0XHR0aGlzLnNlcnZpY2VzUmVhZHlUb1VwZGF0ZVtzZXJ2aWNlTmFtZV0gPSB0cnVlXG5cdFx0XHR0aGlzLnRyeVVwZGF0ZSgpXG5cdFx0fSlcblx0XHR0aGlzLnNlcnZpY2VzW3NlcnZpY2VOYW1lXS5vbihgYWxpdmVgLCAoKSA9PiB7XG5cdFx0XHR0aGlzLnNlcnZpY2VzTGl2ZVt0aGlzLnNlcnZpY2VJZHhbc2VydmljZU5hbWVdXS51c2UoUHJvbWlzZS5yZXNvbHZlKCkpXG5cdFx0XHR0aGlzLnNlcnZpY2VzRGVhZFt0aGlzLnNlcnZpY2VJZHhbc2VydmljZU5hbWVdXSA9IG5ldyBGdXR1cmUoKCkgPT4ge30pXG5cdFx0XHRpZiAodGhpcy5kZWFkLmRvbmUpIHtcblx0XHRcdFx0dGhpcy5kZWFkID0gbmV3IEZ1dHVyZSgoKSA9PiB7fSlcblx0XHRcdH1cblx0XHRcdHRoaXMuZGVhZC51c2UoUHJvbWlzZS5hbGwodGhpcy5zZXJ2aWNlc0RlYWQpKVxuXHRcdH0pXG5cdFx0dGhpcy5zZXJ2aWNlc1tzZXJ2aWNlTmFtZV0ucHJvY2Vzcy5vbmNlKGBjbG9zZWAsIChleGl0Q29kZSkgPT4ge1xuXHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhcblx0XHRcdFx0YEF1dG8tcmVzcGF3biBzYXcgXCIke3NlcnZpY2VOYW1lfVwiIGV4aXQgd2l0aCBjb2RlICR7ZXhpdENvZGV9YCxcblx0XHRcdClcblx0XHRcdHRoaXMuc2VydmljZXNbc2VydmljZU5hbWVdID0gbnVsbFxuXHRcdFx0aWYgKCF0aGlzLmF1dG9SZXNwYXduRGVhZFNlcnZpY2VzKSB7XG5cdFx0XHRcdHRoaXMubG9nZ2VyLmluZm8oYEF1dG8tcmVzcGF3biBpcyBvZmY7IFwiJHtzZXJ2aWNlTmFtZX1cIiByZXN0cy5gKVxuXHRcdFx0XHRyZXR1cm5cblx0XHRcdH1cblx0XHRcdGNvbnN0IHVwZGF0ZVBoYXNlID0gdGhpcy5zdG9yYWdlLmdldEl0ZW0oYHVwZGF0ZVBoYXNlYClcblx0XHRcdHRoaXMubG9nZ2VyLmluZm8oYD4gc3RvcmFnZShcInVwZGF0ZVBoYXNlXCIpID5gLCB1cGRhdGVQaGFzZSlcblx0XHRcdGNvbnN0IHVwZGF0ZXNBcmVSZWFkeSA9IHVwZGF0ZVBoYXNlID09PSBgY29uZmlybWVkYFxuXHRcdFx0aWYgKHVwZGF0ZXNBcmVSZWFkeSkge1xuXHRcdFx0XHR0aGlzLnNlcnZpY2VMb2dnZXJzW3NlcnZpY2VOYW1lXS5pbmZvKGBVcGRhdGluZyBiZWZvcmUgc3RhcnR1cC4uLmApXG5cdFx0XHRcdHRoaXMucmVzdGFydFRpbWVzID0gW11cblx0XHRcdFx0dGhpcy5pbnN0YWxsUGFja2FnZSgpXG5cdFx0XHRcdHRoaXMuc3RhcnRTZXJ2aWNlKHNlcnZpY2VOYW1lKVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Y29uc3Qgbm93ID0gRGF0ZS5ub3coKVxuXHRcdFx0XHRjb25zdCBmaXZlTWludXRlc0FnbyA9IG5vdyAtIDUgKiA2MCAqIDEwMDBcblx0XHRcdFx0dGhpcy5yZXN0YXJ0VGltZXMgPSB0aGlzLnJlc3RhcnRUaW1lcy5maWx0ZXIoXG5cdFx0XHRcdFx0KHRpbWUpID0+IHRpbWUgPiBmaXZlTWludXRlc0Fnbyxcblx0XHRcdFx0KVxuXHRcdFx0XHR0aGlzLnJlc3RhcnRUaW1lcy5wdXNoKG5vdylcblxuXHRcdFx0XHRpZiAodGhpcy5yZXN0YXJ0VGltZXMubGVuZ3RoIDwgNSkge1xuXHRcdFx0XHRcdHRoaXMuc2VydmljZUxvZ2dlcnNbc2VydmljZU5hbWVdLmluZm8oYENyYXNoZWQuIFJlc3RhcnRpbmcuLi5gKVxuXHRcdFx0XHRcdHRoaXMuc3RhcnRTZXJ2aWNlKHNlcnZpY2VOYW1lKVxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHRoaXMuc2VydmljZUxvZ2dlcnNbc2VydmljZU5hbWVdLmluZm8oXG5cdFx0XHRcdFx0XHRgQ3Jhc2hlZCA1IHRpbWVzIGluIDUgbWludXRlcy4gTm90IHJlc3RhcnRpbmcuYCxcblx0XHRcdFx0XHQpXG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9KVxuXHRcdHRoaXMuc2FmZXR5ID0gMFxuXHR9XG5cblx0cHJvdGVjdGVkIGRvd25sb2FkUGFja2FnZSgpOiB2b2lkIHtcblx0XHR0aGlzLmxvZ2dlci5pbmZvKGBEb3dubG9hZGluZy4uLmApXG5cdFx0dHJ5IHtcblx0XHRcdGNvbnN0IG91dCA9IGV4ZWNTeW5jKHRoaXMub3B0aW9ucy5zY3JpcHRzLmRvd25sb2FkKVxuXHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhgRG93bmxvYWQgc3Rkb3V0OmAsIG91dC50b1N0cmluZygpKVxuXHRcdFx0dGhpcy5zdG9yYWdlLnNldEl0ZW0oYHNldHVwUGhhc2VgLCBgZG93bmxvYWRlZGApXG5cdFx0XHR0aGlzLmxvZ2dlci5pbmZvKGBEb3dubG9hZGVkIWApXG5cdFx0fSBjYXRjaCAodGhyb3duKSB7XG5cdFx0XHRpZiAodGhyb3duIGluc3RhbmNlb2YgRXJyb3IpIHtcblx0XHRcdFx0dGhpcy5sb2dnZXIuZXJyb3IoYEZhaWxlZCB0byBnZXQgdGhlIGxhdGVzdCByZWxlYXNlOiAke3Rocm93bi5tZXNzYWdlfWApXG5cdFx0XHR9XG5cdFx0XHRyZXR1cm5cblx0XHR9XG5cdH1cblxuXHRwcm90ZWN0ZWQgaW5zdGFsbFBhY2thZ2UoKTogdm9pZCB7XG5cdFx0dGhpcy5sb2dnZXIuaW5mbyhgSW5zdGFsbGluZy4uLmApXG5cblx0XHR0cnkge1xuXHRcdFx0Y29uc3Qgb3V0ID0gZXhlY1N5bmModGhpcy5vcHRpb25zLnNjcmlwdHMuaW5zdGFsbClcblx0XHRcdHRoaXMubG9nZ2VyLmluZm8oYEluc3RhbGwgc3Rkb3V0OmAsIG91dC50b1N0cmluZygpKVxuXHRcdFx0dGhpcy5zdG9yYWdlLnNldEl0ZW0oYHNldHVwUGhhc2VgLCBgaW5zdGFsbGVkYClcblx0XHRcdHRoaXMubG9nZ2VyLmluZm8oYEluc3RhbGxlZCFgKVxuXHRcdH0gY2F0Y2ggKHRocm93bikge1xuXHRcdFx0aWYgKHRocm93biBpbnN0YW5jZW9mIEVycm9yKSB7XG5cdFx0XHRcdHRoaXMubG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gZ2V0IHRoZSBsYXRlc3QgcmVsZWFzZTogJHt0aHJvd24ubWVzc2FnZX1gKVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuXG5cdFx0fVxuXHR9XG5cblx0cHVibGljIHN0b3BBbGxTZXJ2aWNlcygpOiBGdXR1cmU8dW5rbm93bj4ge1xuXHRcdHRoaXMubG9nZ2VyLmluZm8oYFN0b3BwaW5nIGFsbCBzZXJ2aWNlcy4uLiBhdXRvLXJlc3Bhd24gZGlzYWJsZWQuYClcblx0XHR0aGlzLmF1dG9SZXNwYXduRGVhZFNlcnZpY2VzID0gZmFsc2Vcblx0XHRmb3IgKGNvbnN0IFtzZXJ2aWNlTmFtZV0gb2YgdG9FbnRyaWVzKHRoaXMuc2VydmljZXMpKSB7XG5cdFx0XHR0aGlzLnN0b3BTZXJ2aWNlKHNlcnZpY2VOYW1lKVxuXHRcdH1cblx0XHRyZXR1cm4gdGhpcy5kZWFkXG5cdH1cblxuXHRwdWJsaWMgc3RvcFNlcnZpY2Uoc2VydmljZU5hbWU6IFMpOiB2b2lkIHtcblx0XHRjb25zdCBzZXJ2aWNlID0gdGhpcy5zZXJ2aWNlc1tzZXJ2aWNlTmFtZV1cblx0XHRpZiAoc2VydmljZSkge1xuXHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhgU3RvcHBpbmcgc2VydmljZSBcIiR7c2VydmljZU5hbWV9XCIuLi5gKVxuXHRcdFx0dGhpcy5zZXJ2aWNlc0RlYWRbdGhpcy5zZXJ2aWNlSWR4W3NlcnZpY2VOYW1lXV0udXNlKFxuXHRcdFx0XHRuZXcgUHJvbWlzZSgocGFzcykgPT4ge1xuXHRcdFx0XHRcdHNlcnZpY2UuZW1pdChgdGltZVRvU3RvcGApXG5cdFx0XHRcdFx0c2VydmljZS5wcm9jZXNzLm9uY2UoYGNsb3NlYCwgKGV4aXRDb2RlKSA9PiB7XG5cdFx0XHRcdFx0XHR0aGlzLmxvZ2dlci5pbmZvKFxuXHRcdFx0XHRcdFx0XHRgU3RvcHBlZCBzZXJ2aWNlIFwiJHtzZXJ2aWNlTmFtZX1cIjsgZXhpdGVkIHdpdGggY29kZSAke2V4aXRDb2RlfWAsXG5cdFx0XHRcdFx0XHQpXG5cdFx0XHRcdFx0XHR0aGlzLnNlcnZpY2VzW3NlcnZpY2VOYW1lXSA9IG51bGxcblx0XHRcdFx0XHRcdHBhc3MoKVxuXHRcdFx0XHRcdH0pXG5cdFx0XHRcdH0pLFxuXHRcdFx0KVxuXHRcdFx0dGhpcy5kZWFkLnVzZShQcm9taXNlLmFsbCh0aGlzLnNlcnZpY2VzRGVhZCkpXG5cdFx0XHR0aGlzLnNlcnZpY2VzTGl2ZVt0aGlzLnNlcnZpY2VJZHhbc2VydmljZU5hbWVdXSA9IG5ldyBGdXR1cmUoKCkgPT4ge30pXG5cdFx0XHRpZiAodGhpcy5saXZlLmRvbmUpIHtcblx0XHRcdFx0dGhpcy5saXZlID0gbmV3IEZ1dHVyZSgoKSA9PiB7fSlcblx0XHRcdH1cblx0XHRcdHRoaXMubGl2ZS51c2UoUHJvbWlzZS5hbGwodGhpcy5zZXJ2aWNlc0xpdmUpKVxuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aGlzLnNlcnZpY2VMb2dnZXJzW3NlcnZpY2VOYW1lXS5lcnJvcihcblx0XHRcdFx0YFRyaWVkIHRvIHN0b3Agc2VydmljZSwgYnV0IGl0IHdhc24ndCBydW5uaW5nLmAsXG5cdFx0XHQpXG5cdFx0fVxuXHR9XG59XG5cbmV4cG9ydCBjb25zdCBmbGlnaHREZWNrTG9nU2NoZW1hID0gei5vYmplY3Qoe1xuXHRsZXZlbDogei51bmlvbihbei5saXRlcmFsKGBpbmZvYCksIHoubGl0ZXJhbChgd2FybmApLCB6LmxpdGVyYWwoYEVSUiFgKV0pLFxuXHR0aW1lc3RhbXA6IHoubnVtYmVyKCksXG5cdHBhY2thZ2U6IHouc3RyaW5nKCksXG5cdHNlcnZpY2U6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcblx0cHJvY2Vzczogei5udW1iZXIoKSxcblx0Ym9keTogei5zdHJpbmcoKSxcbn0pXG5leHBvcnQgdHlwZSBGbGlnaHREZWNrTG9nID0gei5pbmZlcjx0eXBlb2YgZmxpZ2h0RGVja0xvZ1NjaGVtYT5cblxuY29uc3QgTElORV9GT1JNQVQgPSBgbGluZS1mb3JtYXRgIHNhdGlzZmllcyBrZXlvZiBMbmF2Rm9ybWF0XG5jb25zdCBWQUxVRSA9IGB2YWx1ZWAgc2F0aXNmaWVzIGtleW9mIExuYXZGb3JtYXRcblxuZXhwb3J0IHR5cGUgTG5hdkZvcm1hdFZpc3VhbENvbXBvbmVudCA9IEV4Y2x1ZGU8XG5cdEV4Y2x1ZGU8TG5hdkZvcm1hdFtgbGluZS1mb3JtYXRgXSwgdW5kZWZpbmVkPltudW1iZXJdLFxuXHRzdHJpbmdcbj5cblxuZXhwb3J0IHR5cGUgTG5hdkZvcm1hdEJyZWFrZG93biA9IEV4Y2x1ZGU8TG5hdkZvcm1hdFtgdmFsdWVgXSwgdW5kZWZpbmVkPlxuZXhwb3J0IHR5cGUgTWVtYmVyT2Y8VD4gPSBUW2tleW9mIFRdXG5leHBvcnQgdHlwZSBMbmF2Rm9ybWF0VmFsdWVEZWZpbml0aW9uID0gTWVtYmVyT2Y8TG5hdkZvcm1hdEJyZWFrZG93bj5cblxuZXhwb3J0IHR5cGUgRmxpZ2h0RGVja0Zvcm1hdCA9IHtcblx0W0xJTkVfRk9STUFUXTogKFxuXHRcdHwgc3RyaW5nXG5cdFx0fCAoTG5hdkZvcm1hdFZpc3VhbENvbXBvbmVudCAmIHtcblx0XHRcdFx0ZmllbGQ6IGtleW9mIEZsaWdodERlY2tMb2cgfCBgX19sZXZlbF9fYCB8IGBfX3RpbWVzdGFtcF9fYFxuXHRcdCAgfSlcblx0KVtdXG5cdFtWQUxVRV06IHtcblx0XHRbSyBpbiBrZXlvZiBGbGlnaHREZWNrTG9nXTogTG5hdkZvcm1hdFZhbHVlRGVmaW5pdGlvbiAmIHtcblx0XHRcdGtpbmQ6IEZsaWdodERlY2tMb2dbS10gZXh0ZW5kcyBudW1iZXIgfCB1bmRlZmluZWRcblx0XHRcdFx0PyBgaW50ZWdlcmBcblx0XHRcdFx0OiBGbGlnaHREZWNrTG9nW0tdIGV4dGVuZHMgc3RyaW5nIHwgdW5kZWZpbmVkXG5cdFx0XHRcdFx0PyBgc3RyaW5nYFxuXHRcdFx0XHRcdDogbmV2ZXJcblx0XHR9XG5cdH1cbn1cblxuZXhwb3J0IGNvbnN0IEZMSUdIVERFQ0tfTE5BVl9GT1JNQVQgPSB7XG5cdHRpdGxlOiBgRmxpZ2h0RGVjayBMb2dgLFxuXHRkZXNjcmlwdGlvbjogYEZvcm1hdCBmb3IgZXZlbnRzIGxvZ2dlZCBieSB0aGUgRmxpZ2h0RGVjayBwcm9jZXNzIG1hbmFnZXIuYCxcblx0XCJmaWxlLXR5cGVcIjogYGpzb25gLFxuXHRcInRpbWVzdGFtcC1maWVsZFwiOiBgdGltZXN0YW1wYCxcblx0XCJzdWJzZWNvbmQtZmllbGRcIjogYHN1YnNlY29uZGAsXG5cdFwic3Vic2Vjb25kLXVuaXRzXCI6IGBtaWxsaWAsXG5cdFwib3BpZC1maWVsZFwiOiBgc2VydmljZWAsXG5cdFwibGV2ZWwtZmllbGRcIjogYGxldmVsYCxcblx0bGV2ZWw6IHtcblx0XHRpbmZvOiBgaW5mb2AsXG5cdFx0d2FybmluZzogYHdhcm5gLFxuXHRcdGVycm9yOiBgZXJyIWAsXG5cdH0sXG5cdFwib3JkZXJlZC1ieS10aW1lXCI6IHRydWUsXG5cblx0W0xJTkVfRk9STUFUXTogW1xuXHRcdHtcblx0XHRcdHByZWZpeDogYCBgLFxuXHRcdFx0ZmllbGQ6IGBfX3RpbWVzdGFtcF9fYCxcblx0XHRcdFwidGltZXN0YW1wLWZvcm1hdFwiOiBgJVktJW0tJWRUJUg6JU06JVMuJUwlWmAsXG5cdFx0fSxcblx0XHR7XG5cdFx0XHRwcmVmaXg6IGAgYCxcblx0XHRcdGZpZWxkOiBgcHJvY2Vzc2AsXG5cdFx0XHRcIm1pbi13aWR0aFwiOiA1LFxuXHRcdH0sXG5cdFx0e1xuXHRcdFx0cHJlZml4OiBgOmAsXG5cdFx0XHRmaWVsZDogYHBhY2thZ2VgLFxuXHRcdH0sXG5cdFx0e1xuXHRcdFx0cHJlZml4OiBgOmAsXG5cdFx0XHRmaWVsZDogYHNlcnZpY2VgLFxuXHRcdFx0XCJkZWZhdWx0LXZhbHVlXCI6IGBgLFxuXHRcdH0sXG5cdFx0e1xuXHRcdFx0cHJlZml4OiBgW2AsXG5cdFx0XHRmaWVsZDogYF9fbGV2ZWxfX2AsXG5cdFx0XHRzdWZmaXg6IGBdYCxcblx0XHR9LFxuXHRcdHtcblx0XHRcdHByZWZpeDogYDogYCxcblx0XHRcdGZpZWxkOiBgYm9keWAsXG5cdFx0fSxcblx0XSxcblxuXHRbVkFMVUVdOiB7XG5cdFx0dGltZXN0YW1wOiB7XG5cdFx0XHRraW5kOiBgaW50ZWdlcmAsXG5cdFx0fSxcblx0XHRsZXZlbDoge1xuXHRcdFx0a2luZDogYHN0cmluZ2AsXG5cdFx0fSxcblx0XHRwYWNrYWdlOiB7XG5cdFx0XHRraW5kOiBgc3RyaW5nYCxcblx0XHR9LFxuXHRcdHNlcnZpY2U6IHtcblx0XHRcdGtpbmQ6IGBzdHJpbmdgLFxuXHRcdH0sXG5cdFx0cHJvY2Vzczoge1xuXHRcdFx0a2luZDogYGludGVnZXJgLFxuXHRcdH0sXG5cdFx0Ym9keToge1xuXHRcdFx0a2luZDogYHN0cmluZ2AsXG5cdFx0fSxcblx0fSxcbn0gYXMgY29uc3Qgc2F0aXNmaWVzIEZsaWdodERlY2tGb3JtYXQgJiBMbmF2Rm9ybWF0XG5cbmV4cG9ydCBjbGFzcyBGbGlnaHREZWNrTG9nZ2VyXG5cdGltcGxlbWVudHMgUGljazxDb25zb2xlLCBgZXJyb3JgIHwgYGluZm9gIHwgYHdhcm5gPlxue1xuXHRwdWJsaWMgcmVhZG9ubHkgcGFja2FnZU5hbWU6IHN0cmluZ1xuXHRwdWJsaWMgcmVhZG9ubHkgc2VydmljZU5hbWU/OiBzdHJpbmdcblx0cHVibGljIHJlYWRvbmx5IGpzb25Mb2dnaW5nOiBib29sZWFuXG5cdHB1YmxpYyBwcm9jZXNzQ29kZTogbnVtYmVyXG5cdHB1YmxpYyBjb25zdHJ1Y3Rvcihcblx0XHRwYWNrYWdlTmFtZTogc3RyaW5nLFxuXHRcdHByb2Nlc3NDb2RlOiBudW1iZXIsXG5cdFx0c2VydmljZU5hbWU/OiBzdHJpbmcsXG5cdFx0b3B0aW9ucz86IHsganNvbkxvZ2dpbmc6IGJvb2xlYW4gfSxcblx0KSB7XG5cdFx0dGhpcy5wYWNrYWdlTmFtZSA9IHBhY2thZ2VOYW1lXG5cdFx0aWYgKHNlcnZpY2VOYW1lKSB7XG5cdFx0XHR0aGlzLnNlcnZpY2VOYW1lID0gc2VydmljZU5hbWVcblx0XHR9XG5cdFx0dGhpcy5wcm9jZXNzQ29kZSA9IHByb2Nlc3NDb2RlXG5cdFx0dGhpcy5qc29uTG9nZ2luZyA9IG9wdGlvbnM/Lmpzb25Mb2dnaW5nID8/IGZhbHNlXG5cdH1cblx0cHVibGljIGluZm8oLi4ubWVzc2FnZXM6IHVua25vd25bXSk6IHZvaWQge1xuXHRcdGlmICh0aGlzLmpzb25Mb2dnaW5nKSB7XG5cdFx0XHRjb25zdCBsb2c6IEZsaWdodERlY2tMb2cgPSB7XG5cdFx0XHRcdHRpbWVzdGFtcDogRGF0ZS5ub3coKSxcblx0XHRcdFx0bGV2ZWw6IGBpbmZvYCxcblx0XHRcdFx0cHJvY2VzczogdGhpcy5wcm9jZXNzQ29kZSxcblx0XHRcdFx0cGFja2FnZTogdGhpcy5wYWNrYWdlTmFtZSxcblx0XHRcdFx0Ym9keTogbWVzc2FnZXNcblx0XHRcdFx0XHQubWFwKChtZXNzYWdlKSA9PlxuXHRcdFx0XHRcdFx0dHlwZW9mIG1lc3NhZ2UgPT09IGBzdHJpbmdgXG5cdFx0XHRcdFx0XHRcdD8gbWVzc2FnZVxuXHRcdFx0XHRcdFx0XHQ6IGluc3BlY3QobWVzc2FnZSwgZmFsc2UsIG51bGwsIHRydWUpLFxuXHRcdFx0XHRcdClcblx0XHRcdFx0XHQuam9pbihgIGApLFxuXHRcdFx0fVxuXHRcdFx0aWYgKHRoaXMuc2VydmljZU5hbWUpIHtcblx0XHRcdFx0bG9nLnNlcnZpY2UgPSB0aGlzLnNlcnZpY2VOYW1lXG5cdFx0XHR9XG5cdFx0XHRwcm9jZXNzLnN0ZG91dC53cml0ZShKU09OLnN0cmluZ2lmeShsb2cpICsgYFxcbmApXG5cdFx0fSBlbHNlIHtcblx0XHRcdGNvbnN0IHNvdXJjZSA9IHRoaXMuc2VydmljZU5hbWVcblx0XHRcdFx0PyBgJHt0aGlzLnBhY2thZ2VOYW1lfTo6JHt0aGlzLnNlcnZpY2VOYW1lfWBcblx0XHRcdFx0OiB0aGlzLnBhY2thZ2VOYW1lXG5cdFx0XHRjb25zb2xlLmxvZyhgJHtzb3VyY2V9OmAsIC4uLm1lc3NhZ2VzKVxuXHRcdH1cblx0fVxuXG5cdHB1YmxpYyB3YXJuKC4uLm1lc3NhZ2VzOiB1bmtub3duW10pOiB2b2lkIHtcblx0XHRpZiAodGhpcy5qc29uTG9nZ2luZykge1xuXHRcdFx0Y29uc3QgbG9nOiBGbGlnaHREZWNrTG9nID0ge1xuXHRcdFx0XHR0aW1lc3RhbXA6IERhdGUubm93KCksXG5cdFx0XHRcdGxldmVsOiBgd2FybmAsXG5cdFx0XHRcdHByb2Nlc3M6IHRoaXMucHJvY2Vzc0NvZGUsXG5cdFx0XHRcdHBhY2thZ2U6IHRoaXMucGFja2FnZU5hbWUsXG5cdFx0XHRcdGJvZHk6IG1lc3NhZ2VzXG5cdFx0XHRcdFx0Lm1hcCgobWVzc2FnZSkgPT5cblx0XHRcdFx0XHRcdHR5cGVvZiBtZXNzYWdlID09PSBgc3RyaW5nYFxuXHRcdFx0XHRcdFx0XHQ/IG1lc3NhZ2Vcblx0XHRcdFx0XHRcdFx0OiBpbnNwZWN0KG1lc3NhZ2UsIGZhbHNlLCBudWxsLCB0cnVlKSxcblx0XHRcdFx0XHQpXG5cdFx0XHRcdFx0LmpvaW4oYCBgKSxcblx0XHRcdH1cblx0XHRcdGlmICh0aGlzLnNlcnZpY2VOYW1lKSB7XG5cdFx0XHRcdGxvZy5zZXJ2aWNlID0gdGhpcy5zZXJ2aWNlTmFtZVxuXHRcdFx0fVxuXHRcdFx0cHJvY2Vzcy5zdGRvdXQud3JpdGUoSlNPTi5zdHJpbmdpZnkobG9nKSArIGBcXG5gKVxuXHRcdH0gZWxzZSB7XG5cdFx0XHRjb25zdCBzb3VyY2UgPSB0aGlzLnNlcnZpY2VOYW1lXG5cdFx0XHRcdD8gYCR7dGhpcy5wYWNrYWdlTmFtZX06OiR7dGhpcy5zZXJ2aWNlTmFtZX1gXG5cdFx0XHRcdDogdGhpcy5wYWNrYWdlTmFtZVxuXHRcdFx0Y29uc29sZS53YXJuKGAke3NvdXJjZX06YCwgLi4ubWVzc2FnZXMpXG5cdFx0fVxuXHR9XG5cblx0cHVibGljIGVycm9yKC4uLm1lc3NhZ2VzOiB1bmtub3duW10pOiB2b2lkIHtcblx0XHRpZiAodGhpcy5qc29uTG9nZ2luZykge1xuXHRcdFx0Y29uc3QgbG9nOiBGbGlnaHREZWNrTG9nID0ge1xuXHRcdFx0XHR0aW1lc3RhbXA6IERhdGUubm93KCkgKyBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiAxMDAwKSxcblx0XHRcdFx0bGV2ZWw6IGBFUlIhYCxcblx0XHRcdFx0cHJvY2VzczogdGhpcy5wcm9jZXNzQ29kZSxcblx0XHRcdFx0cGFja2FnZTogdGhpcy5wYWNrYWdlTmFtZSxcblx0XHRcdFx0Ym9keTogbWVzc2FnZXNcblx0XHRcdFx0XHQubWFwKChtZXNzYWdlKSA9PlxuXHRcdFx0XHRcdFx0dHlwZW9mIG1lc3NhZ2UgPT09IGBzdHJpbmdgXG5cdFx0XHRcdFx0XHRcdD8gbWVzc2FnZVxuXHRcdFx0XHRcdFx0XHQ6IGluc3BlY3QobWVzc2FnZSwgZmFsc2UsIG51bGwsIHRydWUpLFxuXHRcdFx0XHRcdClcblx0XHRcdFx0XHQuam9pbihgIGApLFxuXHRcdFx0fVxuXHRcdFx0aWYgKHRoaXMuc2VydmljZU5hbWUpIHtcblx0XHRcdFx0bG9nLnNlcnZpY2UgPSB0aGlzLnNlcnZpY2VOYW1lXG5cdFx0XHR9XG5cdFx0XHRwcm9jZXNzLnN0ZG91dC53cml0ZShKU09OLnN0cmluZ2lmeShsb2cpICsgYFxcbmApXG5cdFx0fSBlbHNlIHtcblx0XHRcdGNvbnN0IHNvdXJjZSA9IHRoaXMuc2VydmljZU5hbWVcblx0XHRcdFx0PyBgJHt0aGlzLnBhY2thZ2VOYW1lfTo6JHt0aGlzLnNlcnZpY2VOYW1lfWBcblx0XHRcdFx0OiB0aGlzLnBhY2thZ2VOYW1lXG5cdFx0XHRjb25zb2xlLmVycm9yKGAke3NvdXJjZX06YCwgLi4ubWVzc2FnZXMpXG5cdFx0fVxuXHR9XG59XG4iLAogICAgImltcG9ydCB7IGNyZWF0ZUVudiB9IGZyb20gXCJAdDMtb3NzL2Vudi1jb3JlXCJcbmltcG9ydCB7IHogfSBmcm9tIFwiem9kXCJcblxuZXhwb3J0IGNvbnN0IGVudiA9IGNyZWF0ZUVudih7XG5cdHNlcnZlcjogeyBGTElHSFRERUNLX1NFQ1JFVDogei5zdHJpbmcoKS5vcHRpb25hbCgpIH0sXG5cdGNsaWVudFByZWZpeDogYE5FVkVSYCxcblx0Y2xpZW50OiB7fSxcblx0cnVudGltZUVudjogaW1wb3J0Lm1ldGEuZW52LFxuXHRlbXB0eVN0cmluZ0FzVW5kZWZpbmVkOiB0cnVlLFxufSlcbiIsCiAgICAiZXhwb3J0IHR5cGUgQWxlcnRPcHRpb25zID0ge1xuXHRzZWNyZXQ6IHN0cmluZ1xuXHRlbmRwb2ludDogc3RyaW5nXG5cdHZlcnNpb246IHN0cmluZ1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYWxlcnQoe1xuXHRzZWNyZXQsXG5cdGVuZHBvaW50LFxuXHR2ZXJzaW9uLFxufTogQWxlcnRPcHRpb25zKTogUHJvbWlzZTxSZXNwb25zZT4ge1xuXHRjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKGVuZHBvaW50LCB7XG5cdFx0bWV0aG9kOiBgUE9TVGAsXG5cdFx0aGVhZGVyczoge1xuXHRcdFx0XCJDb250ZW50LVR5cGVcIjogYHRleHQvcGxhaW47Y2hhcnNldD1VVEYtOGAsXG5cdFx0XHRBdXRob3JpemF0aW9uOiBgQmVhcmVyICR7c2VjcmV0fWAsXG5cdFx0fSxcblx0XHRib2R5OiB2ZXJzaW9uLFxuXHR9KVxuXG5cdHJldHVybiByZXNwb25zZVxufVxuXG4vKipcbiAqIEBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2NoYW5nZXNldHMvYWN0aW9uL2Jsb2IvbWFpbi9zcmMvcnVuLnRzXG4gKi9cbmV4cG9ydCB0eXBlIENoYW5nZXNldHNQdWJsaXNoZWRQYWNrYWdlID0ge1xuXHRuYW1lOiBzdHJpbmdcblx0dmVyc2lvbjogc3RyaW5nXG59XG5cbi8qKlxuICogQHNlZSBodHRwczovL2dpdGh1Yi5jb20vY2hhbmdlc2V0cy9hY3Rpb24vYmxvYi9tYWluL3NyYy9ydW4udHNcbiAqL1xuZXhwb3J0IHR5cGUgQ2hhbmdlc2V0c1B1Ymxpc2hSZXN1bHQgPVxuXHR8IHtcblx0XHRcdHB1Ymxpc2hlZDogdHJ1ZVxuXHRcdFx0cHVibGlzaGVkUGFja2FnZXM6IENoYW5nZXNldHNQdWJsaXNoZWRQYWNrYWdlW11cblx0ICB9XG5cdHwgeyBwdWJsaXNoZWQ6IGZhbHNlIH1cblxuZXhwb3J0IHR5cGUgUGFja2FnZUNvbmZpZzxLIGV4dGVuZHMgc3RyaW5nPiA9IHtcblx0W2tleSBpbiBLXTogeyBlbmRwb2ludDogc3RyaW5nIH1cbn1cbmV4cG9ydCB0eXBlIFNlY3JldHNDb25maWc8SyBleHRlbmRzIHN0cmluZz4gPSB7XG5cdFtrZXkgaW4gS106IHN0cmluZ1xufVxuXG5leHBvcnQgdHlwZSBTY3JhbWJsZU9wdGlvbnM8SyBleHRlbmRzIHN0cmluZyA9IHN0cmluZz4gPSB7XG5cdHBhY2thZ2VDb25maWc6IFBhY2thZ2VDb25maWc8Sz5cblx0c2VjcmV0c0NvbmZpZzogU2VjcmV0c0NvbmZpZzxLPlxuXHRwdWJsaXNoZWRQYWNrYWdlczogQ2hhbmdlc2V0c1B1Ymxpc2hlZFBhY2thZ2VbXVxufVxuXG5leHBvcnQgdHlwZSBTY3JhbWJsZVJlc3VsdDxLIGV4dGVuZHMgc3RyaW5nID0gc3RyaW5nPiA9IHtcblx0W2tleSBpbiBLXTogUmVzcG9uc2Vcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNjcmFtYmxlPEsgZXh0ZW5kcyBzdHJpbmcgPSBzdHJpbmc+KHtcblx0cGFja2FnZUNvbmZpZyxcblx0c2VjcmV0c0NvbmZpZyxcblx0cHVibGlzaGVkUGFja2FnZXMsXG59OiBTY3JhbWJsZU9wdGlvbnM8Sz4pOiBQcm9taXNlPFNjcmFtYmxlUmVzdWx0PEs+PiB7XG5cdGNvbnN0IGFsZXJ0UmVzdWx0czogUHJvbWlzZTxyZWFkb25seSBbSywgUmVzcG9uc2VdPltdID0gW11cblx0Zm9yIChjb25zdCBwdWJsaXNoZWRQYWNrYWdlIG9mIHB1Ymxpc2hlZFBhY2thZ2VzKSB7XG5cdFx0aWYgKHB1Ymxpc2hlZFBhY2thZ2UubmFtZSBpbiBwYWNrYWdlQ29uZmlnKSB7XG5cdFx0XHRjb25zdCBuYW1lID0gcHVibGlzaGVkUGFja2FnZS5uYW1lIGFzIEtcblx0XHRcdGNvbnN0IHsgZW5kcG9pbnQgfSA9IHBhY2thZ2VDb25maWdbbmFtZV1cblx0XHRcdGNvbnN0IHNlY3JldCA9IHNlY3JldHNDb25maWdbbmFtZV1cblx0XHRcdGNvbnN0IHZlcnNpb24gPSBwdWJsaXNoZWRQYWNrYWdlLnZlcnNpb25cblx0XHRcdGNvbnN0IGFsZXJ0UmVzdWx0UHJvbWlzZSA9IGFsZXJ0KHsgc2VjcmV0LCBlbmRwb2ludCwgdmVyc2lvbiB9KS50aGVuKFxuXHRcdFx0XHQoYWxlcnRSZXN1bHQpID0+IFtuYW1lLCBhbGVydFJlc3VsdF0gYXMgY29uc3QsXG5cdFx0XHQpXG5cdFx0XHRhbGVydFJlc3VsdHMucHVzaChhbGVydFJlc3VsdFByb21pc2UpXG5cdFx0fVxuXHR9XG5cdGNvbnN0IGFsZXJ0UmVzdWx0c1Jlc29sdmVkID0gYXdhaXQgUHJvbWlzZS5hbGwoYWxlcnRSZXN1bHRzKVxuXHRjb25zdCBzY3JhbWJsZVJlc3VsdCA9IE9iamVjdC5mcm9tRW50cmllcyhcblx0XHRhbGVydFJlc3VsdHNSZXNvbHZlZCxcblx0KSBhcyBTY3JhbWJsZVJlc3VsdDxLPlxuXHRyZXR1cm4gc2NyYW1ibGVSZXN1bHRcbn1cbiIKICBdLAogICJtYXBwaW5ncyI6ICI4SEFBQSxxQkFDQyxlQUNBLGlCQUNBLGtCQUNBLFlBQ0EsY0FDQSxtQkFDQSxnQkFFRCxrQkFBUyxrQkFNRixNQUFNLENBR2IsQ0FDUSxRQUVBLFdBQVcsQ0FBQyxFQUFtQyxDQUVyRCxHQURBLEtBQUssUUFBVSxFQUFRLE1BQ2xCLEVBQVcsS0FBSyxPQUFPLEVBQzNCLEVBQVUsS0FBSyxRQUFTLENBQUUsVUFBVyxFQUFLLENBQUMsRUFJdEMsT0FBbUMsQ0FBQyxFQUFxQixDQUMvRCxJQUFNLEVBQVcsRUFBUSxLQUFLLFFBQVMsQ0FBRyxFQUMxQyxHQUFJLEVBQVcsQ0FBUSxFQUN0QixPQUFPLEVBQWEsRUFBVSxPQUFPLEVBRXRDLE9BQU8sS0FHRCxPQUFtQyxDQUFDLEVBQVEsRUFBbUIsQ0FDckUsSUFBTSxFQUFXLEVBQVEsS0FBSyxRQUFTLENBQUcsRUFDMUMsRUFBYyxFQUFVLENBQUssRUFHdkIsVUFBc0MsQ0FBQyxFQUFjLENBQzNELElBQU0sRUFBVyxFQUFRLEtBQUssUUFBUyxDQUFHLEVBQzFDLEdBQUksRUFBVyxDQUFRLEVBQ3RCLEVBQU8sQ0FBUSxFQUlWLEdBQUcsQ0FBQyxFQUEwQyxDQU9wRCxPQU5rQixFQUFZLEtBQUssT0FBTyxFQUNELEtBQUssQ0FBQyxFQUFHLElBQU0sQ0FDdkQsSUFBTSxFQUFRLEVBQVMsQ0FBQyxFQUV4QixPQURjLEVBQVMsQ0FBQyxFQUNYLFFBQVUsRUFBTSxRQUM3QixFQUM4QixJQUErQixLQUd4RCxLQUFLLEVBQVMsQ0FDcEIsRUFBTyxLQUFLLFFBQVMsQ0FBRSxVQUFXLEVBQUssQ0FBQyxFQUN4QyxFQUFVLEtBQUssUUFBUyxDQUFFLFVBQVcsRUFBSyxDQUFDLEtBR2pDLE9BQU0sRUFBVyxDQUMzQixPQUFPLEVBQVksS0FBSyxPQUFPLEVBQUUsT0FFbkMsQ0NsRUEsbUJBQVMsV0FBVSwyQkFFbkIsdUJBQVMsa0JBQ1Qsa0JBQVMsZ0JBQ1Qsa0JBQVMsa0JBQ1Qsa0JBQVMsa0JBRVQsaUJBQVMseUJBQ1QsdUJBQVMsOEJBQ1Qsc0JBQVMsZUFBYSxxQkFDdEIsc0JBQVMsZ0NBQ1Qsa0JBQVMsYUFDVCxZQUFTLFlDWlQsb0JBQVMseUJBQ1QsWUFBUyxZQUVGLElBQU0sRUFBTSxFQUFVLENBQzVCLE9BQVEsQ0FBRSxrQkFBbUIsRUFBRSxPQUFPLEVBQUUsU0FBUyxDQUFFLEVBQ25ELGFBQWMsUUFDZCxPQUFRLENBQUMsRUFDVCxXQUFZLFlBQVksSUFDeEIsdUJBQXdCLEVBQ3pCLENBQUMsRURTTSxJQUFNLEdBQTBCLENBQUMsYUFBYyxXQUFXLEVBSXBELEdBQTJCLENBQUMsV0FBWSxXQUFXLEVBSXpELFNBQVMsQ0FBZSxDQUFDLEVBQTBCLENBQ3pELE1BQ0Msa0JBQWtCLEtBQUssQ0FBTyxJQUFNLE9BQU8sTUFBTSxPQUFPLFdBQVcsQ0FBTyxDQUFDLEVBaUJ0RSxNQUFNLENBQXNDLENBa0NmLFFBakN6QixPQUFTLEVBRVQsUUFLQSxjQUNBLFNBTUEsV0FDSCw2QkFDQSxzQkFDQSx3QkFFRyxPQUNBLGVBSUEsMEJBQTRDLEtBRS9DLGFBQ0EsYUFDQSxLQUFPLElBQUksRUFBTyxJQUFNLEVBQUUsRUFDMUIsS0FBTyxJQUFJLEVBQU8sSUFBTSxFQUFFLEVBRXZCLGFBQXlCLENBQUMsRUFFN0IsV0FBVyxDQUFpQixFQUErQixDQUEvQixlQUNsQyxJQUFRLHFCQUFzQixHQUN0QixvQkFBb0IsRUFBUSxFQUFRLEVBQUcsYUFBYSxHQUFNLEVBQzVELEVBQU8sRUFBUSxNQUFRLEtBQ3ZCLEVBQVMsb0JBQW9CLElBRTdCLEVBQWtCLEVBQVUsRUFBUSxRQUFRLEVBMkNsRCxHQTFDQSxLQUFLLFNBQVcsRUFDZixFQUFnQixJQUFJLEVBQUUsS0FBaUIsQ0FBQyxFQUFhLElBQUksQ0FBQyxDQUMzRCxFQUNBLEtBQUssV0FBYSxFQUNqQixFQUFnQixJQUFJLEVBQUUsR0FBYyxJQUFRLENBQUMsRUFBYSxDQUFHLENBQUMsQ0FDL0QsRUFDQSxLQUFLLDZCQUErQixFQUNuQyxFQUFnQixJQUFJLEVBQUUsR0FBZSxjQUFlLENBQ25ELEdBQ0MsQ0FDRixDQUFDLENBQ0YsRUFDQSxLQUFLLHNCQUF3QixJQUFLLEtBQUssNEJBQTZCLEVBQ3BFLEtBQUssd0JBQTBCLEdBRS9CLEtBQUssT0FBUyxJQUFJLEVBQ2pCLEtBQUssUUFBUSxZQUNiLFFBQVEsSUFDUixPQUNBLENBQUUsWUFBYSxLQUFLLFFBQVEsYUFBZSxFQUFNLENBQ2xELEVBQ0EsS0FBSyxlQUFpQixFQUNyQixFQUFnQixJQUFJLEVBQUUsS0FBaUIsQ0FDdEMsRUFDQSxJQUFJLEVBQ0gsS0FBSyxRQUFRLFlBQ2IsUUFBUSxJQUNSLEVBQ0EsQ0FBRSxZQUFhLEtBQUssUUFBUSxhQUFlLEVBQU0sQ0FDbEQsQ0FDRCxDQUFDLENBQ0YsRUFFQSxLQUFLLGFBQWUsRUFBZ0IsSUFBSSxJQUFNLElBQUksRUFBTyxJQUFNLEVBQUUsQ0FBQyxFQUNsRSxLQUFLLGFBQWUsRUFBZ0IsSUFBSSxJQUFNLElBQUksRUFBTyxJQUFNLEVBQUUsQ0FBQyxFQUNsRSxLQUFLLEtBQUssSUFBSSxRQUFRLElBQUksS0FBSyxZQUFZLENBQUMsRUFDNUMsS0FBSyxLQUFLLElBQUksUUFBUSxJQUFJLEtBQUssWUFBWSxDQUFDLEVBRTVDLEtBQUssUUFBVSxJQUFJLEVBQWtCLENBQ3BDLEtBQU0sRUFBUSxFQUFtQixVQUFXLEVBQVEsV0FBVyxDQUNoRSxDQUFDLEVBRUcsSUFBc0IsT0FDekIsS0FBSyxPQUFPLEtBQ1gsNEZBQ0QsTUFFQSxHQUFhLENBQUMsRUFBSyxJQUFRLENBQzFCLElBQUksRUFBcUIsQ0FBQyxFQUMxQixFQUNFLEdBQUcsT0FBUSxDQUFDLElBQVUsQ0FDdEIsRUFBSyxLQUFLLGFBQWlCLE9BQVMsRUFBUSxPQUFPLEtBQUssQ0FBSyxDQUFDLEVBQzlELEVBQ0EsR0FBRyxNQUFPLElBQU0sQ0FDaEIsSUFBTSxFQUFhLEVBQUksUUFBUSxjQUMvQixHQUFJLENBQ0gsVUFBVyxFQUFJLE1BQVEsWUFBYSxLQUFNLEtBQzFDLElBQU0sRUFBcUIsVUFBVSxJQUNyQyxHQUFJLElBQWUsVUFBVSxJQUk1QixNQUhBLEtBQUssT0FBTyxLQUNYLDBCQUEwQixjQUErQixLQUMxRCxFQUNNLElBRVAsSUFBTSxFQUFNLElBQUksSUFBSSxFQUFJLElBQUssQ0FBTSxFQUNuQyxLQUFLLE9BQU8sS0FBSyxFQUFJLE9BQVEsRUFBSSxRQUFRLEVBRXpDLElBQU0sRUFBc0IsT0FBTyxPQUFPLENBQUksRUFBRSxTQUFTLEVBQ3pELElBQUssRUFBZ0IsQ0FBbUIsRUFDdkMsS0FBTSxLQUdQLEVBQUksVUFBVSxHQUFHLEVBQ2pCLEVBQUksSUFBSSxFQUVSLEtBQUssUUFBUSxRQUFRLGNBQWUsVUFBVSxFQUM5QyxLQUFLLFFBQVEsUUFBUSx1QkFBd0IsQ0FBbUIsRUFDaEUsSUFBUSxxQkFBc0IsRUFBUSxRQUN0QyxHQUFJLEVBQW1CLENBQ3RCLEtBQUssMkJBQTJCLEtBQUssRUFDckMsS0FBSyxXQUFXLENBQW1CLEVBQ25DLElBQU0sRUFBYyxLQUFLLFFBQVEsUUFBUSxhQUFhLEVBRXRELEdBREEsS0FBSyxPQUFPLEtBQUssNkJBQThCLENBQVcsRUFDdEQsSUFBZ0IsV0FDbkIsS0FBSywwQkFBNEIsSUFBSSxFQUNwQyxlQUNBLElBQU0sQ0FDTCxLQUFLLFdBQVcsQ0FBbUIsRUFFckMsRUFDQSxLQUFLLDBCQUEwQixNQUFNLE1BR3RDLE1BQUssZ0JBQWdCLFFBRWQsRUFBUCxDQUVELEdBREEsS0FBSyxPQUFPLE1BQU0sRUFBUSxFQUFJLEdBQUcsU0FDdEIsSUFBVyxTQUNyQixFQUFJLFVBQVUsQ0FBTSxFQUNwQixFQUFJLElBQUksU0FFUixDQUNELEVBQU8sQ0FBQyxHQUVULEVBQ0YsRUFBRSxPQUFPLEVBQU0sSUFBTSxDQUNyQixLQUFLLE9BQU8sS0FBSywwQkFBMEIsR0FBTSxFQUNqRCxFQUdGLEtBQUssaUJBQWlCLEVBQ3BCLEtBQUssSUFBTSxDQUNYLEtBQUssT0FBTyxLQUFLLHVCQUF1QixFQUN4QyxFQUNBLE1BQU0sQ0FBQyxJQUFXLENBQ2xCLEdBQUksYUFBa0IsTUFDckIsS0FBSyxPQUFPLE1BQU0sZ0NBQWlDLEVBQU8sT0FBTyxFQUVsRSxFQUdPLFVBQVUsQ0FBQyxFQUF1QixDQUMzQyxLQUFLLE9BQU8sS0FBSyx5QkFBeUIsRUFDMUMsSUFBUSxxQkFBc0IsS0FBSyxRQUFRLFFBQzNDLElBQUssRUFBbUIsQ0FDdkIsS0FBSyxPQUFPLEtBQUssb0NBQW9DLEVBQ3JELE9BRUQsR0FBSSxDQUNILElBQU0sRUFBTSxFQUFTLEdBQUcsS0FBcUIsR0FBUyxFQUN0RCxLQUFLLE9BQU8sS0FBSyxnQkFBaUIsRUFBSSxTQUFTLENBQUMsRUFDaEQsS0FBSywyQkFBMkIsS0FBSyxFQUNyQyxLQUFLLFFBQVEsUUFBUSxjQUFlLFdBQVcsRUFDL0MsS0FBSyxnQkFBZ0IsRUFDckIsS0FBSyxlQUFlLFFBQ1osRUFBUCxDQUNELEdBQUksYUFBa0IsTUFDckIsS0FBSyxPQUFPLE1BQU0sZ0JBQWlCLEVBQU8sT0FBTyxNQUMzQyxDQUNOLElBQU0sRUFBYSxFQUFhLENBQU0sRUFDdEMsS0FBSyxPQUFPLE1BQU0sY0FBZSxFQUFZLENBQU0sSUFLNUMsY0FBYyxFQUFTLENBQ2hDLFFBQVcsS0FBUyxFQUFVLEtBQUssUUFBUSxFQUFHLENBQzdDLElBQU8sRUFBYSxHQUFXLEVBQy9CLEdBQUksR0FDSCxHQUFJLEtBQUssUUFBUSxTQUFTLEdBQWEsUUFDdEMsRUFBUSxLQUFLLGNBQWMsTUFHNUIsTUFBSyxhQUFhLENBQVcsR0FLdEIsU0FBUyxFQUFTLENBQzNCLEdBQUksRUFBVSxLQUFLLHFCQUFxQixFQUFFLE1BQU0sR0FBSSxLQUFhLENBQU8sRUFDdkUsS0FBSyxPQUFPLEtBQUssbUNBQW1DLEVBQ3BELEtBQUssZ0JBQWdCLEVBQ25CLEtBQUssSUFBTSxDQUNYLEtBQUssT0FBTyxLQUFLLDRDQUE0QyxFQUM3RCxLQUFLLGlCQUFpQixFQUNwQixLQUFLLElBQU0sQ0FDWCxLQUFLLE9BQU8sS0FBSywwQ0FBMEMsRUFDM0QsRUFDQSxNQUFNLENBQUMsSUFBVyxDQUNsQixHQUFJLGFBQWtCLE1BQ3JCLEtBQUssT0FBTyxNQUNYLGdDQUNBLEVBQU8sT0FDUixFQUVELEVBQ0YsRUFDQSxNQUFNLENBQUMsSUFBVyxDQUNsQixHQUFJLGFBQWtCLE1BQ3JCLEtBQUssT0FBTyxNQUFNLCtCQUFnQyxFQUFPLE9BQU8sRUFFakUsRUFJTSxnQkFBZ0IsRUFBb0IsQ0FDN0MsS0FBSyxPQUFPLEtBQUssMEJBQTBCLEVBQzNDLEtBQUssd0JBQTBCLEdBQy9CLElBQU0sRUFBYSxLQUFLLFFBQVEsUUFBUSxZQUFZLEVBRXBELE9BREEsS0FBSyxPQUFPLEtBQUssNEJBQTZCLENBQVUsRUFDaEQsUUFDRixLQUlKLE9BSEEsS0FBSyxPQUFPLEtBQUssd0JBQXdCLEVBQ3pDLEtBQUssZ0JBQWdCLEVBQ3JCLEtBQUssZUFBZSxFQUNiLEtBQUssaUJBQWlCLE1BQ3pCLGFBR0osT0FGQSxLQUFLLE9BQU8sS0FBSyw2Q0FBNkMsRUFDOUQsS0FBSyxlQUFlLEVBQ2IsS0FBSyxpQkFBaUIsTUFDekIsWUFBYSxDQUNqQixRQUFZLEtBQWdCLEVBQVUsS0FBSyxRQUFRLEVBQ2xELEtBQUssYUFBYSxDQUFXLEVBRTlCLE9BQU8sS0FBSyxJQUNiLEdBSVEsWUFBWSxDQUFDLEVBQXNCLENBSTVDLEdBSEEsS0FBSyxPQUFPLEtBQ1gsb0JBQW9CLEtBQUssUUFBUSxnQkFBZ0IsVUFBb0IsS0FBSyxhQUMzRSxFQUNJLEtBQUssUUFBVSxFQUNsQixNQUFNLElBQUksTUFBTSxpQkFBaUIsRUFFbEMsS0FBSyxTQUVMLElBQU8sS0FBUSxHQUFRLEtBQUssUUFBUSxTQUFTLEdBQWEsSUFBSSxNQUFNLEdBQUcsRUFDakUsRUFBaUIsRUFBTSxFQUFLLEVBQU0sQ0FDdkMsSUFBSyxLQUFLLFFBQVEsa0JBQ2xCLElBQUssWUFBWSxHQUNsQixDQUFDLEVBQ0ssRUFBZ0IsS0FBSyxlQUFlLEdBQ3BDLEVBQVcsS0FBSyxTQUFTLEdBQWUsSUFBSSxFQUNqRCxFQUNBLEdBQUcsS0FBSyxRQUFRLGdCQUFnQixJQUNoQyxDQUNELEVBQ0EsRUFBYyxZQUFjLEVBQVEsUUFBUSxLQUFPLEdBQ25ELEtBQUssU0FBUyxHQUFhLE1BQU0sSUFBSSxJQUFhLENBQ2pELEVBQWMsS0FBSyxlQUFLLEdBQUcsQ0FBUSxFQUNuQyxFQUNELEtBQUssU0FBUyxHQUFhLEdBQUcsZ0JBQWlCLElBQU0sQ0FDcEQsS0FBSyxPQUFPLEtBQUssWUFBWSx3QkFBa0MsRUFDL0QsS0FBSyxzQkFBc0IsR0FBZSxHQUMxQyxLQUFLLFVBQVUsRUFDZixFQUNELEtBQUssU0FBUyxHQUFhLEdBQUcsUUFBUyxJQUFNLENBRzVDLEdBRkEsS0FBSyxhQUFhLEtBQUssV0FBVyxJQUFjLElBQUksUUFBUSxRQUFRLENBQUMsRUFDckUsS0FBSyxhQUFhLEtBQUssV0FBVyxJQUFnQixJQUFJLEVBQU8sSUFBTSxFQUFFLEVBQ2pFLEtBQUssS0FBSyxLQUNiLEtBQUssS0FBTyxJQUFJLEVBQU8sSUFBTSxFQUFFLEVBRWhDLEtBQUssS0FBSyxJQUFJLFFBQVEsSUFBSSxLQUFLLFlBQVksQ0FBQyxFQUM1QyxFQUNELEtBQUssU0FBUyxHQUFhLFFBQVEsS0FBSyxRQUFTLENBQUMsSUFBYSxDQUs5RCxHQUpBLEtBQUssT0FBTyxLQUNYLHFCQUFxQixxQkFBK0IsR0FDckQsRUFDQSxLQUFLLFNBQVMsR0FBZSxNQUN4QixLQUFLLHdCQUF5QixDQUNsQyxLQUFLLE9BQU8sS0FBSyx5QkFBeUIsV0FBcUIsRUFDL0QsT0FFRCxJQUFNLEVBQWMsS0FBSyxRQUFRLFFBQVEsYUFBYSxFQUd0RCxHQUZBLEtBQUssT0FBTyxLQUFLLDZCQUE4QixDQUFXLEVBQ2xDLElBQWdCLFlBRXZDLEtBQUssZUFBZSxHQUFhLEtBQUssNEJBQTRCLEVBQ2xFLEtBQUssYUFBZSxDQUFDLEVBQ3JCLEtBQUssZUFBZSxFQUNwQixLQUFLLGFBQWEsQ0FBVyxNQUN2QixDQUNOLElBQU0sRUFBTSxLQUFLLElBQUksRUFDZixFQUFpQixFQUFNLE9BTTdCLEdBTEEsS0FBSyxhQUFlLEtBQUssYUFBYSxPQUNyQyxDQUFDLElBQVMsRUFBTyxDQUNsQixFQUNBLEtBQUssYUFBYSxLQUFLLENBQUcsRUFFdEIsS0FBSyxhQUFhLE9BQVMsRUFDOUIsS0FBSyxlQUFlLEdBQWEsS0FBSyx3QkFBd0IsRUFDOUQsS0FBSyxhQUFhLENBQVcsTUFFN0IsTUFBSyxlQUFlLEdBQWEsS0FDaEMsK0NBQ0QsR0FHRixFQUNELEtBQUssT0FBUyxFQUdMLGVBQWUsRUFBUyxDQUNqQyxLQUFLLE9BQU8sS0FBSyxnQkFBZ0IsRUFDakMsR0FBSSxDQUNILElBQU0sRUFBTSxFQUFTLEtBQUssUUFBUSxRQUFRLFFBQVEsRUFDbEQsS0FBSyxPQUFPLEtBQUssbUJBQW9CLEVBQUksU0FBUyxDQUFDLEVBQ25ELEtBQUssUUFBUSxRQUFRLGFBQWMsWUFBWSxFQUMvQyxLQUFLLE9BQU8sS0FBSyxhQUFhLFFBQ3RCLEVBQVAsQ0FDRCxHQUFJLGFBQWtCLE1BQ3JCLEtBQUssT0FBTyxNQUFNLHFDQUFxQyxFQUFPLFNBQVMsRUFFeEUsUUFJUSxjQUFjLEVBQVMsQ0FDaEMsS0FBSyxPQUFPLEtBQUssZUFBZSxFQUVoQyxHQUFJLENBQ0gsSUFBTSxFQUFNLEVBQVMsS0FBSyxRQUFRLFFBQVEsT0FBTyxFQUNqRCxLQUFLLE9BQU8sS0FBSyxrQkFBbUIsRUFBSSxTQUFTLENBQUMsRUFDbEQsS0FBSyxRQUFRLFFBQVEsYUFBYyxXQUFXLEVBQzlDLEtBQUssT0FBTyxLQUFLLFlBQVksUUFDckIsRUFBUCxDQUNELEdBQUksYUFBa0IsTUFDckIsS0FBSyxPQUFPLE1BQU0scUNBQXFDLEVBQU8sU0FBUyxFQUV4RSxRQUlLLGVBQWUsRUFBb0IsQ0FDekMsS0FBSyxPQUFPLEtBQUssaURBQWlELEVBQ2xFLEtBQUssd0JBQTBCLEdBQy9CLFFBQVksS0FBZ0IsRUFBVSxLQUFLLFFBQVEsRUFDbEQsS0FBSyxZQUFZLENBQVcsRUFFN0IsT0FBTyxLQUFLLEtBR04sV0FBVyxDQUFDLEVBQXNCLENBQ3hDLElBQU0sRUFBVSxLQUFLLFNBQVMsR0FDOUIsR0FBSSxFQUFTLENBZ0JaLEdBZkEsS0FBSyxPQUFPLEtBQUsscUJBQXFCLE9BQWlCLEVBQ3ZELEtBQUssYUFBYSxLQUFLLFdBQVcsSUFBYyxJQUMvQyxJQUFJLFFBQVEsQ0FBQyxJQUFTLENBQ3JCLEVBQVEsS0FBSyxZQUFZLEVBQ3pCLEVBQVEsUUFBUSxLQUFLLFFBQVMsQ0FBQyxJQUFhLENBQzNDLEtBQUssT0FBTyxLQUNYLG9CQUFvQix3QkFBa0MsR0FDdkQsRUFDQSxLQUFLLFNBQVMsR0FBZSxLQUM3QixFQUFLLEVBQ0wsRUFDRCxDQUNGLEVBQ0EsS0FBSyxLQUFLLElBQUksUUFBUSxJQUFJLEtBQUssWUFBWSxDQUFDLEVBQzVDLEtBQUssYUFBYSxLQUFLLFdBQVcsSUFBZ0IsSUFBSSxFQUFPLElBQU0sRUFBRSxFQUNqRSxLQUFLLEtBQUssS0FDYixLQUFLLEtBQU8sSUFBSSxFQUFPLElBQU0sRUFBRSxFQUVoQyxLQUFLLEtBQUssSUFBSSxRQUFRLElBQUksS0FBSyxZQUFZLENBQUMsTUFFNUMsTUFBSyxlQUFlLEdBQWEsTUFDaEMsK0NBQ0QsRUFHSCxDQUVPLElBQU0sR0FBc0IsRUFBRSxPQUFPLENBQzNDLE1BQU8sRUFBRSxNQUFNLENBQUMsRUFBRSxRQUFRLE1BQU0sRUFBRyxFQUFFLFFBQVEsTUFBTSxFQUFHLEVBQUUsUUFBUSxNQUFNLENBQUMsQ0FBQyxFQUN4RSxVQUFXLEVBQUUsT0FBTyxFQUNwQixRQUFTLEVBQUUsT0FBTyxFQUNsQixRQUFTLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFDN0IsUUFBUyxFQUFFLE9BQU8sRUFDbEIsS0FBTSxFQUFFLE9BQU8sQ0FDaEIsQ0FBQyxFQUdLLEVBQWMsY0FDZCxFQUFRLFFBNkJELEdBQXlCLENBQ3JDLE1BQU8saUJBQ1AsWUFBYSw4REFDYixZQUFhLE9BQ2Isa0JBQW1CLFlBQ25CLGtCQUFtQixZQUNuQixrQkFBbUIsUUFDbkIsYUFBYyxVQUNkLGNBQWUsUUFDZixNQUFPLENBQ04sS0FBTSxPQUNOLFFBQVMsT0FDVCxNQUFPLE1BQ1IsRUFDQSxrQkFBbUIsSUFFbEIsR0FBYyxDQUNkLENBQ0MsT0FBUSxJQUNSLE1BQU8sZ0JBQ1AsbUJBQW9CLHdCQUNyQixFQUNBLENBQ0MsT0FBUSxJQUNSLE1BQU8sVUFDUCxZQUFhLENBQ2QsRUFDQSxDQUNDLE9BQVEsSUFDUixNQUFPLFNBQ1IsRUFDQSxDQUNDLE9BQVEsSUFDUixNQUFPLFVBQ1AsZ0JBQWlCLEVBQ2xCLEVBQ0EsQ0FDQyxPQUFRLElBQ1IsTUFBTyxZQUNQLE9BQVEsR0FDVCxFQUNBLENBQ0MsT0FBUSxLQUNSLE1BQU8sTUFDUixDQUNELEdBRUMsR0FBUSxDQUNSLFVBQVcsQ0FDVixLQUFNLFNBQ1AsRUFDQSxNQUFPLENBQ04sS0FBTSxRQUNQLEVBQ0EsUUFBUyxDQUNSLEtBQU0sUUFDUCxFQUNBLFFBQVMsQ0FDUixLQUFNLFFBQ1AsRUFDQSxRQUFTLENBQ1IsS0FBTSxTQUNQLEVBQ0EsS0FBTSxDQUNMLEtBQU0sUUFDUCxDQUNELENBQ0QsRUFFTyxNQUFNLENBRWIsQ0FDaUIsWUFDQSxZQUNBLFlBQ1QsWUFDQSxXQUFXLENBQ2pCLEVBQ0EsRUFDQSxFQUNBLEVBQ0MsQ0FFRCxHQURBLEtBQUssWUFBYyxFQUNmLEVBQ0gsS0FBSyxZQUFjLEVBRXBCLEtBQUssWUFBYyxFQUNuQixLQUFLLFlBQWMsR0FBUyxhQUFlLEdBRXJDLElBQUksSUFBSSxFQUEyQixDQUN6QyxHQUFJLEtBQUssWUFBYSxDQUNyQixJQUFNLEVBQXFCLENBQzFCLFVBQVcsS0FBSyxJQUFJLEVBQ3BCLE1BQU8sT0FDUCxRQUFTLEtBQUssWUFDZCxRQUFTLEtBQUssWUFDZCxLQUFNLEVBQ0osSUFBSSxDQUFDLFdBQ0UsSUFBWSxTQUNoQixFQUNBLEVBQVEsRUFBUyxHQUFPLEtBQU0sRUFBSSxDQUN0QyxFQUNDLEtBQUssR0FBRyxDQUNYLEVBQ0EsR0FBSSxLQUFLLFlBQ1IsRUFBSSxRQUFVLEtBQUssWUFFcEIsUUFBUSxPQUFPLE1BQU0sS0FBSyxVQUFVLENBQUcsRUFBSTtBQUFBLENBQUksTUFDekMsQ0FDTixJQUFNLEVBQVMsS0FBSyxZQUNqQixHQUFHLEtBQUssZ0JBQWdCLEtBQUssY0FDN0IsS0FBSyxZQUNSLFFBQVEsSUFBSSxHQUFHLEtBQVcsR0FBRyxDQUFRLEdBSWhDLElBQUksSUFBSSxFQUEyQixDQUN6QyxHQUFJLEtBQUssWUFBYSxDQUNyQixJQUFNLEVBQXFCLENBQzFCLFVBQVcsS0FBSyxJQUFJLEVBQ3BCLE1BQU8sT0FDUCxRQUFTLEtBQUssWUFDZCxRQUFTLEtBQUssWUFDZCxLQUFNLEVBQ0osSUFBSSxDQUFDLFdBQ0UsSUFBWSxTQUNoQixFQUNBLEVBQVEsRUFBUyxHQUFPLEtBQU0sRUFBSSxDQUN0QyxFQUNDLEtBQUssR0FBRyxDQUNYLEVBQ0EsR0FBSSxLQUFLLFlBQ1IsRUFBSSxRQUFVLEtBQUssWUFFcEIsUUFBUSxPQUFPLE1BQU0sS0FBSyxVQUFVLENBQUcsRUFBSTtBQUFBLENBQUksTUFDekMsQ0FDTixJQUFNLEVBQVMsS0FBSyxZQUNqQixHQUFHLEtBQUssZ0JBQWdCLEtBQUssY0FDN0IsS0FBSyxZQUNSLFFBQVEsS0FBSyxHQUFHLEtBQVcsR0FBRyxDQUFRLEdBSWpDLEtBQUssSUFBSSxFQUEyQixDQUMxQyxHQUFJLEtBQUssWUFBYSxDQUNyQixJQUFNLEVBQXFCLENBQzFCLFVBQVcsS0FBSyxJQUFJLEVBQUksS0FBSyxNQUFNLEtBQUssT0FBTyxFQUFJLElBQUksRUFDdkQsTUFBTyxPQUNQLFFBQVMsS0FBSyxZQUNkLFFBQVMsS0FBSyxZQUNkLEtBQU0sRUFDSixJQUFJLENBQUMsV0FDRSxJQUFZLFNBQ2hCLEVBQ0EsRUFBUSxFQUFTLEdBQU8sS0FBTSxFQUFJLENBQ3RDLEVBQ0MsS0FBSyxHQUFHLENBQ1gsRUFDQSxHQUFJLEtBQUssWUFDUixFQUFJLFFBQVUsS0FBSyxZQUVwQixRQUFRLE9BQU8sTUFBTSxLQUFLLFVBQVUsQ0FBRyxFQUFJO0FBQUEsQ0FBSSxNQUN6QyxDQUNOLElBQU0sRUFBUyxLQUFLLFlBQ2pCLEdBQUcsS0FBSyxnQkFBZ0IsS0FBSyxjQUM3QixLQUFLLFlBQ1IsUUFBUSxNQUFNLEdBQUcsS0FBVyxHQUFHLENBQVEsR0FHMUMsNENFbm9CQSxlQUFzQixDQUFLLEVBQzFCLFNBQ0EsV0FDQSxXQUNtQyxDQVVuQyxPQVRpQixNQUFNLE1BQU0sRUFBVSxDQUN0QyxPQUFRLE9BQ1IsUUFBUyxDQUNSLGVBQWdCLDJCQUNoQixjQUFlLFVBQVUsR0FDMUIsRUFDQSxLQUFNLENBQ1AsQ0FBQyxFQXdDRixlQUFzQixDQUFtQyxFQUN4RCxnQkFDQSxnQkFDQSxxQkFDa0QsQ0FDbEQsSUFBTSxFQUFrRCxDQUFDLEVBQ3pELFFBQVcsS0FBb0IsRUFDOUIsR0FBSSxFQUFpQixRQUFRLEVBQWUsQ0FDM0MsSUFBTSxFQUFPLEVBQWlCLE1BQ3RCLFlBQWEsRUFBYyxHQUM3QixFQUFTLEVBQWMsR0FDdkIsRUFBVSxFQUFpQixRQUMzQixFQUFxQixFQUFNLENBQUUsU0FBUSxXQUFVLFNBQVEsQ0FBQyxFQUFFLEtBQy9ELENBQUMsSUFBZ0IsQ0FBQyxFQUFNLENBQVcsQ0FDcEMsRUFDQSxFQUFhLEtBQUssQ0FBa0IsRUFHdEMsSUFBTSxFQUF1QixNQUFNLFFBQVEsSUFBSSxDQUFZLEVBSTNELE9BSHVCLE9BQU8sWUFDN0IsQ0FDRCIsCiAgImRlYnVnSWQiOiAiRDYxNEExQUM5RTJFRTE4NTY0NzU2RTIxNjQ3NTZFMjEiLAogICJuYW1lcyI6IFtdCn0=
8
+ //# debugId=16A02FFB0350BCFF64756E2164756E21
9
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2ZpbGVzeXN0ZW0tc3RvcmFnZS50cyIsICIuLi9zcmMvZmxpZ2h0ZGVjay5saWIudHMiLCAiLi4vc3JjL2ZsaWdodGRlY2suZW52LnRzIiwgIi4uL3NyYy9rbGF4b24ubGliLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWwogICAgImltcG9ydCB7XG5cdGV4aXN0c1N5bmMsXG5cdG1rZGlyU3luYyxcblx0cmVhZGRpclN5bmMsXG5cdHJlYWRGaWxlU3luYyxcblx0cm1TeW5jLFxuXHRzdGF0U3luYyxcblx0d3JpdGVGaWxlU3luYyxcbn0gZnJvbSBcIm5vZGU6ZnNcIlxuaW1wb3J0IHsgcmVzb2x2ZSB9IGZyb20gXCJub2RlOnBhdGhcIlxuXG5leHBvcnQgdHlwZSBGaWxlc3lzdGVtU3RvcmFnZU9wdGlvbnMgPSB7XG5cdHBhdGg6IHN0cmluZ1xufVxuXG5leHBvcnQgY2xhc3MgRmlsZXN5c3RlbVN0b3JhZ2U8XG5cdFQgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0gUmVjb3JkPHN0cmluZywgc3RyaW5nPixcbj4gaW1wbGVtZW50cyBTdG9yYWdlXG57XG5cdHB1YmxpYyByb290RGlyOiBzdHJpbmdcblxuXHRwdWJsaWMgY29uc3RydWN0b3Iob3B0aW9uczogRmlsZXN5c3RlbVN0b3JhZ2VPcHRpb25zKSB7XG5cdFx0dGhpcy5yb290RGlyID0gb3B0aW9ucy5wYXRoXG5cdFx0aWYgKCFleGlzdHNTeW5jKHRoaXMucm9vdERpcikpIHtcblx0XHRcdG1rZGlyU3luYyh0aGlzLnJvb3REaXIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pXG5cdFx0fVxuXHR9XG5cblx0cHVibGljIGdldEl0ZW08SyBleHRlbmRzIHN0cmluZyAmIGtleW9mIFQ+KGtleTogSyk6IFRbS10gfCBudWxsIHtcblx0XHRjb25zdCBmaWxlUGF0aCA9IHJlc29sdmUodGhpcy5yb290RGlyLCBrZXkpXG5cdFx0aWYgKGV4aXN0c1N5bmMoZmlsZVBhdGgpKSB7XG5cdFx0XHRyZXR1cm4gcmVhZEZpbGVTeW5jKGZpbGVQYXRoLCBgdXRmLThgKSBhcyBUW0tdXG5cdFx0fVxuXHRcdHJldHVybiBudWxsXG5cdH1cblxuXHRwdWJsaWMgc2V0SXRlbTxLIGV4dGVuZHMgc3RyaW5nICYga2V5b2YgVD4oa2V5OiBLLCB2YWx1ZTogVFtLXSk6IHZvaWQge1xuXHRcdGNvbnN0IGZpbGVQYXRoID0gcmVzb2x2ZSh0aGlzLnJvb3REaXIsIGtleSlcblx0XHR3cml0ZUZpbGVTeW5jKGZpbGVQYXRoLCB2YWx1ZSlcblx0fVxuXG5cdHB1YmxpYyByZW1vdmVJdGVtPEsgZXh0ZW5kcyBzdHJpbmcgJiBrZXlvZiBUPihrZXk6IEspOiB2b2lkIHtcblx0XHRjb25zdCBmaWxlUGF0aCA9IHJlc29sdmUodGhpcy5yb290RGlyLCBrZXkpXG5cdFx0aWYgKGV4aXN0c1N5bmMoZmlsZVBhdGgpKSB7XG5cdFx0XHRybVN5bmMoZmlsZVBhdGgpXG5cdFx0fVxuXHR9XG5cblx0cHVibGljIGtleShpbmRleDogbnVtYmVyKTogKHN0cmluZyAmIGtleW9mIFQpIHwgbnVsbCB7XG5cdFx0Y29uc3QgZmlsZVBhdGhzID0gcmVhZGRpclN5bmModGhpcy5yb290RGlyKVxuXHRcdGNvbnN0IGZpbGVQYXRoc0J5RGF0ZUNyZWF0ZWQgPSBmaWxlUGF0aHMuc29ydCgoYSwgYikgPT4ge1xuXHRcdFx0Y29uc3QgYVN0YXQgPSBzdGF0U3luYyhhKVxuXHRcdFx0Y29uc3QgYlN0YXQgPSBzdGF0U3luYyhiKVxuXHRcdFx0cmV0dXJuIGJTdGF0LmN0aW1lTXMgLSBhU3RhdC5jdGltZU1zXG5cdFx0fSlcblx0XHRyZXR1cm4gKGZpbGVQYXRoc0J5RGF0ZUNyZWF0ZWRbaW5kZXhdIGFzIHN0cmluZyAmIGtleW9mIFQpID8/IG51bGxcblx0fVxuXG5cdHB1YmxpYyBjbGVhcigpOiB2b2lkIHtcblx0XHRybVN5bmModGhpcy5yb290RGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KVxuXHRcdG1rZGlyU3luYyh0aGlzLnJvb3REaXIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pXG5cdH1cblxuXHRwdWJsaWMgZ2V0IGxlbmd0aCgpOiBudW1iZXIge1xuXHRcdHJldHVybiByZWFkZGlyU3luYyh0aGlzLnJvb3REaXIpLmxlbmd0aFxuXHR9XG59XG4iLAogICAgImltcG9ydCB7IGV4ZWNTeW5jLCBzcGF3biB9IGZyb20gXCJub2RlOmNoaWxkX3Byb2Nlc3NcIlxuaW1wb3J0IHR5cGUgeyBTZXJ2ZXIgfSBmcm9tIFwibm9kZTpodHRwXCJcbmltcG9ydCB7IGNyZWF0ZVNlcnZlciB9IGZyb20gXCJub2RlOmh0dHBcIlxuaW1wb3J0IHsgaG9tZWRpciB9IGZyb20gXCJub2RlOm9zXCJcbmltcG9ydCB7IHJlc29sdmUgfSBmcm9tIFwibm9kZTpwYXRoXCJcbmltcG9ydCB7IGluc3BlY3QgfSBmcm9tIFwibm9kZTp1dGlsXCJcblxuaW1wb3J0IHsgRnV0dXJlIH0gZnJvbSBcImF0b20uaW8vaW50ZXJuYWxcIlxuaW1wb3J0IHsgZGlzY292ZXJUeXBlIH0gZnJvbSBcImF0b20uaW8vaW50cm9zcGVjdGlvblwiXG5pbXBvcnQgeyBmcm9tRW50cmllcywgdG9FbnRyaWVzIH0gZnJvbSBcImF0b20uaW8vanNvblwiXG5pbXBvcnQgeyBDaGlsZFNvY2tldCB9IGZyb20gXCJhdG9tLmlvL3JlYWx0aW1lLXNlcnZlclwiXG5pbXBvcnQgeyBDcm9uSm9iIH0gZnJvbSBcImNyb25cIlxuaW1wb3J0IHsgeiB9IGZyb20gXCJ6b2RcIlxuXG5pbXBvcnQgdHlwZSB7IExuYXZGb3JtYXQgfSBmcm9tIFwiLi4vZ2VuL2xuYXYtZm9ybWF0LXNjaGVtYS5nZW5cIlxuaW1wb3J0IHsgRmlsZXN5c3RlbVN0b3JhZ2UgfSBmcm9tIFwiLi9maWxlc3lzdGVtLXN0b3JhZ2VcIlxuaW1wb3J0IHsgZW52IH0gZnJvbSBcIi4vZmxpZ2h0ZGVjay5lbnZcIlxuXG5leHBvcnQgY29uc3QgRkxJR0hUREVDS19TRVRVUF9QSEFTRVMgPSBbYGRvd25sb2FkZWRgLCBgaW5zdGFsbGVkYF0gYXMgY29uc3RcblxuZXhwb3J0IHR5cGUgRmxpZ2h0RGVja1NldHVwUGhhc2UgPSAodHlwZW9mIEZMSUdIVERFQ0tfU0VUVVBfUEhBU0VTKVtudW1iZXJdXG5cbmV4cG9ydCBjb25zdCBGTElHSFRERUNLX1VQREFURV9QSEFTRVMgPSBbYG5vdGlmaWVkYCwgYGNvbmZpcm1lZGBdIGFzIGNvbnN0XG5cbmV4cG9ydCB0eXBlIEZsaWdodERlY2tVcGRhdGVQaGFzZSA9ICh0eXBlb2YgRkxJR0hUREVDS19VUERBVEVfUEhBU0VTKVtudW1iZXJdXG5cbmV4cG9ydCBmdW5jdGlvbiBpc1ZlcnNpb25OdW1iZXIodmVyc2lvbjogc3RyaW5nKTogYm9vbGVhbiB7XG5cdHJldHVybiAoXG5cdFx0L15cXGQrXFwuXFxkK1xcLlxcZCskLy50ZXN0KHZlcnNpb24pIHx8ICFOdW1iZXIuaXNOYU4oTnVtYmVyLnBhcnNlRmxvYXQodmVyc2lvbikpXG5cdClcbn1cblxuZXhwb3J0IHR5cGUgRmxpZ2h0RGVja09wdGlvbnM8UyBleHRlbmRzIHN0cmluZyA9IHN0cmluZz4gPSB7XG5cdHBhY2thZ2VOYW1lOiBzdHJpbmdcblx0c2VydmljZXM6IHsgW3NlcnZpY2UgaW4gU106IHsgcnVuOiBzdHJpbmc7IHdhaXRGb3I6IGJvb2xlYW4gfSB9XG5cdHNjcmlwdHM6IHtcblx0XHRkb3dubG9hZDogc3RyaW5nXG5cdFx0aW5zdGFsbDogc3RyaW5nXG5cdFx0Y2hlY2tBdmFpbGFiaWxpdHk/OiBzdHJpbmdcblx0fVxuXHRwb3J0PzogbnVtYmVyIHwgdW5kZWZpbmVkXG5cdGZsaWdodGRlY2tSb290RGlyPzogc3RyaW5nIHwgdW5kZWZpbmVkXG5cdGpzb25Mb2dnaW5nPzogYm9vbGVhbiB8IHVuZGVmaW5lZFxufVxuXG5leHBvcnQgY2xhc3MgRmxpZ2h0RGVjazxTIGV4dGVuZHMgc3RyaW5nID0gc3RyaW5nPiB7XG5cdHByb3RlY3RlZCBzYWZldHkgPSAwXG5cblx0cHJvdGVjdGVkIHN0b3JhZ2U6IEZpbGVzeXN0ZW1TdG9yYWdlPHtcblx0XHRzZXR1cFBoYXNlOiBGbGlnaHREZWNrU2V0dXBQaGFzZVxuXHRcdHVwZGF0ZVBoYXNlOiBGbGlnaHREZWNrVXBkYXRlUGhhc2Vcblx0XHR1cGRhdGVBd2FpdGVkVmVyc2lvbjogc3RyaW5nXG5cdH0+XG5cdHByb3RlY3RlZCB3ZWJob29rU2VydmVyOiBTZXJ2ZXJcblx0cHJvdGVjdGVkIHNlcnZpY2VzOiB7XG5cdFx0W3NlcnZpY2UgaW4gU106IENoaWxkU29ja2V0PFxuXHRcdFx0eyB0aW1lVG9TdG9wOiBbXTsgdXBkYXRlc1JlYWR5OiBbXSB9LFxuXHRcdFx0eyByZWFkeVRvVXBkYXRlOiBbXTsgYWxpdmU6IFtdIH1cblx0XHQ+IHwgbnVsbFxuXHR9XG5cdHByb3RlY3RlZCBzZXJ2aWNlSWR4OiB7IHJlYWRvbmx5IFtzZXJ2aWNlIGluIFNdOiBudW1iZXIgfVxuXHRwdWJsaWMgZGVmYXVsdFNlcnZpY2VzUmVhZHlUb1VwZGF0ZTogeyByZWFkb25seSBbc2VydmljZSBpbiBTXTogYm9vbGVhbiB9XG5cdHB1YmxpYyBzZXJ2aWNlc1JlYWR5VG9VcGRhdGU6IHsgW3NlcnZpY2UgaW4gU106IGJvb2xlYW4gfVxuXHRwdWJsaWMgYXV0b1Jlc3Bhd25EZWFkU2VydmljZXM6IGJvb2xlYW5cblxuXHRwcm90ZWN0ZWQgbG9nZ2VyOiBQaWNrPENvbnNvbGUsIGBlcnJvcmAgfCBgaW5mb2AgfCBgd2FybmA+XG5cdHByb3RlY3RlZCBzZXJ2aWNlTG9nZ2Vyczoge1xuXHRcdHJlYWRvbmx5IFtzZXJ2aWNlIGluIFNdOiBGbGlnaHREZWNrTG9nZ2VyXG5cdH1cblxuXHRwcm90ZWN0ZWQgdXBkYXRlQXZhaWxhYmlsaXR5Q2hlY2tlcjogQ3JvbkpvYiB8IG51bGwgPSBudWxsXG5cblx0cHVibGljIHNlcnZpY2VzTGl2ZTogRnV0dXJlPHZvaWQ+W11cblx0cHVibGljIHNlcnZpY2VzRGVhZDogRnV0dXJlPHZvaWQ+W11cblx0cHVibGljIGxpdmUgPSBuZXcgRnV0dXJlKCgpID0+IHt9KVxuXHRwdWJsaWMgZGVhZCA9IG5ldyBGdXR1cmUoKCkgPT4ge30pXG5cblx0cHJvdGVjdGVkIHJlc3RhcnRUaW1lczogbnVtYmVyW10gPSBbXVxuXG5cdHB1YmxpYyBjb25zdHJ1Y3RvcihwdWJsaWMgcmVhZG9ubHkgb3B0aW9uczogRmxpZ2h0RGVja09wdGlvbnM8Uz4pIHtcblx0XHRjb25zdCB7IEZMSUdIVERFQ0tfU0VDUkVUIH0gPSBlbnZcblx0XHRjb25zdCB7IGZsaWdodGRlY2tSb290RGlyID0gcmVzb2x2ZShob21lZGlyKCksIGAuZmxpZ2h0ZGVja2ApIH0gPSBvcHRpb25zXG5cdFx0Y29uc3QgcG9ydCA9IG9wdGlvbnMucG9ydCA/PyA4MDgwXG5cdFx0Y29uc3Qgb3JpZ2luID0gYGh0dHA6Ly9sb2NhbGhvc3Q6JHtwb3J0fWBcblxuXHRcdGNvbnN0IHNlcnZpY2VzRW50cmllcyA9IHRvRW50cmllcyhvcHRpb25zLnNlcnZpY2VzKVxuXHRcdHRoaXMuc2VydmljZXMgPSBmcm9tRW50cmllcyhcblx0XHRcdHNlcnZpY2VzRW50cmllcy5tYXAoKFtzZXJ2aWNlTmFtZV0pID0+IFtzZXJ2aWNlTmFtZSwgbnVsbF0pLFxuXHRcdClcblx0XHR0aGlzLnNlcnZpY2VJZHggPSBmcm9tRW50cmllcyhcblx0XHRcdHNlcnZpY2VzRW50cmllcy5tYXAoKFtzZXJ2aWNlTmFtZV0sIGlkeCkgPT4gW3NlcnZpY2VOYW1lLCBpZHhdKSxcblx0XHQpXG5cdFx0dGhpcy5kZWZhdWx0U2VydmljZXNSZWFkeVRvVXBkYXRlID0gZnJvbUVudHJpZXMoXG5cdFx0XHRzZXJ2aWNlc0VudHJpZXMubWFwKChbc2VydmljZU5hbWUsIHsgd2FpdEZvciB9XSkgPT4gW1xuXHRcdFx0XHRzZXJ2aWNlTmFtZSxcblx0XHRcdFx0IXdhaXRGb3IsXG5cdFx0XHRdKSxcblx0XHQpXG5cdFx0dGhpcy5zZXJ2aWNlc1JlYWR5VG9VcGRhdGUgPSB7IC4uLnRoaXMuZGVmYXVsdFNlcnZpY2VzUmVhZHlUb1VwZGF0ZSB9XG5cdFx0dGhpcy5hdXRvUmVzcGF3bkRlYWRTZXJ2aWNlcyA9IHRydWVcblxuXHRcdHRoaXMubG9nZ2VyID0gbmV3IEZsaWdodERlY2tMb2dnZXIoXG5cdFx0XHR0aGlzLm9wdGlvbnMucGFja2FnZU5hbWUsXG5cdFx0XHRwcm9jZXNzLnBpZCxcblx0XHRcdHVuZGVmaW5lZCxcblx0XHRcdHsganNvbkxvZ2dpbmc6IHRoaXMub3B0aW9ucy5qc29uTG9nZ2luZyA/PyBmYWxzZSB9LFxuXHRcdClcblx0XHR0aGlzLnNlcnZpY2VMb2dnZXJzID0gZnJvbUVudHJpZXMoXG5cdFx0XHRzZXJ2aWNlc0VudHJpZXMubWFwKChbc2VydmljZU5hbWVdKSA9PiBbXG5cdFx0XHRcdHNlcnZpY2VOYW1lLFxuXHRcdFx0XHRuZXcgRmxpZ2h0RGVja0xvZ2dlcihcblx0XHRcdFx0XHR0aGlzLm9wdGlvbnMucGFja2FnZU5hbWUsXG5cdFx0XHRcdFx0cHJvY2Vzcy5waWQsXG5cdFx0XHRcdFx0c2VydmljZU5hbWUsXG5cdFx0XHRcdFx0eyBqc29uTG9nZ2luZzogdGhpcy5vcHRpb25zLmpzb25Mb2dnaW5nID8/IGZhbHNlIH0sXG5cdFx0XHRcdCksXG5cdFx0XHRdKSxcblx0XHQpXG5cblx0XHR0aGlzLnNlcnZpY2VzTGl2ZSA9IHNlcnZpY2VzRW50cmllcy5tYXAoKCkgPT4gbmV3IEZ1dHVyZSgoKSA9PiB7fSkpXG5cdFx0dGhpcy5zZXJ2aWNlc0RlYWQgPSBzZXJ2aWNlc0VudHJpZXMubWFwKCgpID0+IG5ldyBGdXR1cmUoKCkgPT4ge30pKVxuXHRcdHRoaXMubGl2ZS51c2UoUHJvbWlzZS5hbGwodGhpcy5zZXJ2aWNlc0xpdmUpKVxuXHRcdHRoaXMuZGVhZC51c2UoUHJvbWlzZS5hbGwodGhpcy5zZXJ2aWNlc0RlYWQpKVxuXG5cdFx0dGhpcy5zdG9yYWdlID0gbmV3IEZpbGVzeXN0ZW1TdG9yYWdlKHtcblx0XHRcdHBhdGg6IHJlc29sdmUoZmxpZ2h0ZGVja1Jvb3REaXIsIGBzdG9yYWdlYCwgb3B0aW9ucy5wYWNrYWdlTmFtZSksXG5cdFx0fSlcblxuXHRcdGlmIChGTElHSFRERUNLX1NFQ1JFVCA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHR0aGlzLmxvZ2dlci53YXJuKFxuXHRcdFx0XHRgTm8gRkxJR0hUREVDS19TRUNSRVQgZW52aXJvbm1lbnQgdmFyaWFibGUgZm91bmQuIEZsaWdodERlY2sgd2lsbCBub3QgcnVuIGFuIHVwZGF0ZSBzZXJ2ZXIuYCxcblx0XHRcdClcblx0XHR9IGVsc2Uge1xuXHRcdFx0Y3JlYXRlU2VydmVyKChyZXEsIHJlcykgPT4ge1xuXHRcdFx0XHRsZXQgZGF0YTogVWludDhBcnJheVtdID0gW11cblx0XHRcdFx0cmVxXG5cdFx0XHRcdFx0Lm9uKGBkYXRhYCwgKGNodW5rKSA9PiB7XG5cdFx0XHRcdFx0XHRkYXRhLnB1c2goY2h1bmsgaW5zdGFuY2VvZiBCdWZmZXIgPyBjaHVuayA6IEJ1ZmZlci5mcm9tKGNodW5rKSlcblx0XHRcdFx0XHR9KVxuXHRcdFx0XHRcdC5vbihgZW5kYCwgKCkgPT4ge1xuXHRcdFx0XHRcdFx0Y29uc3QgYXV0aEhlYWRlciA9IHJlcS5oZWFkZXJzLmF1dGhvcml6YXRpb25cblx0XHRcdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0XHRcdGlmICh0eXBlb2YgcmVxLnVybCA9PT0gYHVuZGVmaW5lZGApIHRocm93IDQwMFxuXHRcdFx0XHRcdFx0XHRjb25zdCBleHBlY3RlZEF1dGhIZWFkZXIgPSBgQmVhcmVyICR7RkxJR0hUREVDS19TRUNSRVR9YFxuXHRcdFx0XHRcdFx0XHRpZiAoYXV0aEhlYWRlciAhPT0gYEJlYXJlciAke0ZMSUdIVERFQ0tfU0VDUkVUfWApIHtcblx0XHRcdFx0XHRcdFx0XHR0aGlzLmxvZ2dlci5pbmZvKFxuXHRcdFx0XHRcdFx0XHRcdFx0YFVuYXV0aG9yaXplZDogbmVlZGVkIFxcYCR7ZXhwZWN0ZWRBdXRoSGVhZGVyfVxcYCwgZ290IFxcYCR7YXV0aEhlYWRlcn1cXGBgLFxuXHRcdFx0XHRcdFx0XHRcdClcblx0XHRcdFx0XHRcdFx0XHR0aHJvdyA0MDFcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRjb25zdCB1cmwgPSBuZXcgVVJMKHJlcS51cmwsIG9yaWdpbilcblx0XHRcdFx0XHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhyZXEubWV0aG9kLCB1cmwucGF0aG5hbWUpXG5cblx0XHRcdFx0XHRcdFx0Y29uc3QgdmVyc2lvbkZvcmVpZ25JbnB1dCA9IEJ1ZmZlci5jb25jYXQoZGF0YSkudG9TdHJpbmcoKVxuXHRcdFx0XHRcdFx0XHRpZiAoIWlzVmVyc2lvbk51bWJlcih2ZXJzaW9uRm9yZWlnbklucHV0KSkge1xuXHRcdFx0XHRcdFx0XHRcdHRocm93IDQwMFxuXHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0cmVzLndyaXRlSGVhZCgyMDApXG5cdFx0XHRcdFx0XHRcdHJlcy5lbmQoKVxuXG5cdFx0XHRcdFx0XHRcdHRoaXMuc3RvcmFnZS5zZXRJdGVtKGB1cGRhdGVQaGFzZWAsIGBub3RpZmllZGApXG5cdFx0XHRcdFx0XHRcdHRoaXMuc3RvcmFnZS5zZXRJdGVtKGB1cGRhdGVBd2FpdGVkVmVyc2lvbmAsIHZlcnNpb25Gb3JlaWduSW5wdXQpXG5cdFx0XHRcdFx0XHRcdGNvbnN0IHsgY2hlY2tBdmFpbGFiaWxpdHkgfSA9IG9wdGlvbnMuc2NyaXB0c1xuXHRcdFx0XHRcdFx0XHRpZiAoY2hlY2tBdmFpbGFiaWxpdHkpIHtcblx0XHRcdFx0XHRcdFx0XHR0aGlzLnVwZGF0ZUF2YWlsYWJpbGl0eUNoZWNrZXI/LnN0b3AoKVxuXHRcdFx0XHRcdFx0XHRcdHRoaXMuc2Vla1VwZGF0ZSh2ZXJzaW9uRm9yZWlnbklucHV0KVxuXHRcdFx0XHRcdFx0XHRcdGNvbnN0IHVwZGF0ZVBoYXNlID0gdGhpcy5zdG9yYWdlLmdldEl0ZW0oYHVwZGF0ZVBoYXNlYClcblx0XHRcdFx0XHRcdFx0XHR0aGlzLmxvZ2dlci5pbmZvKGA+IHN0b3JhZ2UoXCJ1cGRhdGVQaGFzZVwiKSA+YCwgdXBkYXRlUGhhc2UpXG5cdFx0XHRcdFx0XHRcdFx0aWYgKHVwZGF0ZVBoYXNlID09PSBgbm90aWZpZWRgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHR0aGlzLnVwZGF0ZUF2YWlsYWJpbGl0eUNoZWNrZXIgPSBuZXcgQ3JvbkpvYihcblx0XHRcdFx0XHRcdFx0XHRcdFx0YDMwICogKiAqICogKmAsXG5cdFx0XHRcdFx0XHRcdFx0XHRcdCgpID0+IHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHR0aGlzLnNlZWtVcGRhdGUodmVyc2lvbkZvcmVpZ25JbnB1dClcblx0XHRcdFx0XHRcdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRcdFx0XHRcdClcblx0XHRcdFx0XHRcdFx0XHRcdHRoaXMudXBkYXRlQXZhaWxhYmlsaXR5Q2hlY2tlci5zdGFydCgpXG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRcdHRoaXMuZG93bmxvYWRQYWNrYWdlKClcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fSBjYXRjaCAodGhyb3duKSB7XG5cdFx0XHRcdFx0XHRcdHRoaXMubG9nZ2VyLmVycm9yKHRocm93biwgcmVxLnVybClcblx0XHRcdFx0XHRcdFx0aWYgKHR5cGVvZiB0aHJvd24gPT09IGBudW1iZXJgKSB7XG5cdFx0XHRcdFx0XHRcdFx0cmVzLndyaXRlSGVhZCh0aHJvd24pXG5cdFx0XHRcdFx0XHRcdFx0cmVzLmVuZCgpXG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH0gZmluYWxseSB7XG5cdFx0XHRcdFx0XHRcdGRhdGEgPSBbXVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0pXG5cdFx0XHR9KS5saXN0ZW4ocG9ydCwgKCkgPT4ge1xuXHRcdFx0XHR0aGlzLmxvZ2dlci5pbmZvKGBTZXJ2ZXIgc3RhcnRlZCBvbiBwb3J0ICR7cG9ydH1gKVxuXHRcdFx0fSlcblx0XHR9XG5cblx0XHR0aGlzLnN0YXJ0QWxsU2VydmljZXMoKVxuXHRcdFx0LnRoZW4oKCkgPT4ge1xuXHRcdFx0XHR0aGlzLmxvZ2dlci5pbmZvKGBBbGwgc2VydmljZXMgc3RhcnRlZC5gKVxuXHRcdFx0fSlcblx0XHRcdC5jYXRjaCgodGhyb3duKSA9PiB7XG5cdFx0XHRcdGlmICh0aHJvd24gaW5zdGFuY2VvZiBFcnJvcikge1xuXHRcdFx0XHRcdHRoaXMubG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gc3RhcnQgYWxsIHNlcnZpY2VzOmAsIHRocm93bi5tZXNzYWdlKVxuXHRcdFx0XHR9XG5cdFx0XHR9KVxuXHR9XG5cblx0cHJvdGVjdGVkIHNlZWtVcGRhdGUodmVyc2lvbjogc3RyaW5nKTogdm9pZCB7XG5cdFx0dGhpcy5sb2dnZXIuaW5mbyhgQ2hlY2tpbmcgZm9yIHVwZGF0ZXMuLi5gKVxuXHRcdGNvbnN0IHsgY2hlY2tBdmFpbGFiaWxpdHkgfSA9IHRoaXMub3B0aW9ucy5zY3JpcHRzXG5cdFx0aWYgKCFjaGVja0F2YWlsYWJpbGl0eSkge1xuXHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhgTm8gY2hlY2tBdmFpbGFiaWxpdHkgc2NyaXB0IGZvdW5kLmApXG5cdFx0XHRyZXR1cm5cblx0XHR9XG5cdFx0dHJ5IHtcblx0XHRcdGNvbnN0IG91dCA9IGV4ZWNTeW5jKGAke2NoZWNrQXZhaWxhYmlsaXR5fSAke3ZlcnNpb259YClcblx0XHRcdHRoaXMubG9nZ2VyLmluZm8oYENoZWNrIHN0ZG91dDpgLCBvdXQudG9TdHJpbmcoKSlcblx0XHRcdHRoaXMudXBkYXRlQXZhaWxhYmlsaXR5Q2hlY2tlcj8uc3RvcCgpXG5cdFx0XHR0aGlzLnN0b3JhZ2Uuc2V0SXRlbShgdXBkYXRlUGhhc2VgLCBgY29uZmlybWVkYClcblx0XHRcdHRoaXMuZG93bmxvYWRQYWNrYWdlKClcblx0XHRcdHRoaXMuYW5ub3VuY2VVcGRhdGUoKVxuXHRcdH0gY2F0Y2ggKHRocm93bikge1xuXHRcdFx0aWYgKHRocm93biBpbnN0YW5jZW9mIEVycm9yKSB7XG5cdFx0XHRcdHRoaXMubG9nZ2VyLmVycm9yKGBDaGVjayBmYWlsZWQ6YCwgdGhyb3duLm1lc3NhZ2UpXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRjb25zdCB0aHJvd25UeXBlID0gZGlzY292ZXJUeXBlKHRocm93bilcblx0XHRcdFx0dGhpcy5sb2dnZXIuZXJyb3IoYENoZWNrIHRocmV3YCwgdGhyb3duVHlwZSwgdGhyb3duKVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHByb3RlY3RlZCBhbm5vdW5jZVVwZGF0ZSgpOiB2b2lkIHtcblx0XHRmb3IgKGNvbnN0IGVudHJ5IG9mIHRvRW50cmllcyh0aGlzLnNlcnZpY2VzKSkge1xuXHRcdFx0Y29uc3QgW3NlcnZpY2VOYW1lLCBzZXJ2aWNlXSA9IGVudHJ5XG5cdFx0XHRpZiAoc2VydmljZSkge1xuXHRcdFx0XHRpZiAodGhpcy5vcHRpb25zLnNlcnZpY2VzW3NlcnZpY2VOYW1lXS53YWl0Rm9yKSB7XG5cdFx0XHRcdFx0c2VydmljZS5lbWl0KGB1cGRhdGVzUmVhZHlgKVxuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0aGlzLnN0YXJ0U2VydmljZShzZXJ2aWNlTmFtZSlcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRwcm90ZWN0ZWQgdHJ5VXBkYXRlKCk6IHZvaWQge1xuXHRcdGlmICh0b0VudHJpZXModGhpcy5zZXJ2aWNlc1JlYWR5VG9VcGRhdGUpLmV2ZXJ5KChbLCBpc1JlYWR5XSkgPT4gaXNSZWFkeSkpIHtcblx0XHRcdHRoaXMubG9nZ2VyLmluZm8oYEFsbCBzZXJ2aWNlcyBhcmUgcmVhZHkgdG8gdXBkYXRlLmApXG5cdFx0XHR0aGlzLnN0b3BBbGxTZXJ2aWNlcygpXG5cdFx0XHRcdC50aGVuKCgpID0+IHtcblx0XHRcdFx0XHR0aGlzLmxvZ2dlci5pbmZvKGBBbGwgc2VydmljZXMgc3RvcHBlZDsgc3RhcnRpbmcgdXAgZnJlc2guLi5gKVxuXHRcdFx0XHRcdHRoaXMuc3RhcnRBbGxTZXJ2aWNlcygpXG5cdFx0XHRcdFx0XHQudGhlbigoKSA9PiB7XG5cdFx0XHRcdFx0XHRcdHRoaXMubG9nZ2VyLmluZm8oYEFsbCBzZXJ2aWNlcyBzdGFydGVkOyB3ZSdyZSBiYWNrIG9ubGluZS5gKVxuXHRcdFx0XHRcdFx0fSlcblx0XHRcdFx0XHRcdC5jYXRjaCgodGhyb3duKSA9PiB7XG5cdFx0XHRcdFx0XHRcdGlmICh0aHJvd24gaW5zdGFuY2VvZiBFcnJvcikge1xuXHRcdFx0XHRcdFx0XHRcdHRoaXMubG9nZ2VyLmVycm9yKFxuXHRcdFx0XHRcdFx0XHRcdFx0YEZhaWxlZCB0byBzdGFydCBhbGwgc2VydmljZXM6YCxcblx0XHRcdFx0XHRcdFx0XHRcdHRocm93bi5tZXNzYWdlLFxuXHRcdFx0XHRcdFx0XHRcdClcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fSlcblx0XHRcdFx0fSlcblx0XHRcdFx0LmNhdGNoKCh0aHJvd24pID0+IHtcblx0XHRcdFx0XHRpZiAodGhyb3duIGluc3RhbmNlb2YgRXJyb3IpIHtcblx0XHRcdFx0XHRcdHRoaXMubG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gc3RvcCBhbGwgc2VydmljZXM6YCwgdGhyb3duLm1lc3NhZ2UpXG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KVxuXHRcdH1cblx0fVxuXG5cdHByb3RlY3RlZCBzdGFydEFsbFNlcnZpY2VzKCk6IEZ1dHVyZTx1bmtub3duPiB7XG5cdFx0dGhpcy5sb2dnZXIuaW5mbyhgU3RhcnRpbmcgYWxsIHNlcnZpY2VzLi4uYClcblx0XHR0aGlzLmF1dG9SZXNwYXduRGVhZFNlcnZpY2VzID0gdHJ1ZVxuXHRcdGNvbnN0IHNldHVwUGhhc2UgPSB0aGlzLnN0b3JhZ2UuZ2V0SXRlbShgc2V0dXBQaGFzZWApXG5cdFx0dGhpcy5sb2dnZXIuaW5mbyhgPiBzdG9yYWdlKFwic2V0dXBQaGFzZVwiKSA+YCwgc2V0dXBQaGFzZSlcblx0XHRzd2l0Y2ggKHNldHVwUGhhc2UpIHtcblx0XHRcdGNhc2UgbnVsbDpcblx0XHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhgU3RhcnRpbmcgZnJvbSBzY3JhdGNoLmApXG5cdFx0XHRcdHRoaXMuZG93bmxvYWRQYWNrYWdlKClcblx0XHRcdFx0dGhpcy5pbnN0YWxsUGFja2FnZSgpXG5cdFx0XHRcdHJldHVybiB0aGlzLnN0YXJ0QWxsU2VydmljZXMoKVxuXHRcdFx0Y2FzZSBgZG93bmxvYWRlZGA6XG5cdFx0XHRcdHRoaXMubG9nZ2VyLmluZm8oYEZvdW5kIHBhY2thZ2UgZG93bmxvYWRlZCBidXQgbm90IGluc3RhbGxlZC5gKVxuXHRcdFx0XHR0aGlzLmluc3RhbGxQYWNrYWdlKClcblx0XHRcdFx0cmV0dXJuIHRoaXMuc3RhcnRBbGxTZXJ2aWNlcygpXG5cdFx0XHRjYXNlIGBpbnN0YWxsZWRgOiB7XG5cdFx0XHRcdGZvciAoY29uc3QgW3NlcnZpY2VOYW1lXSBvZiB0b0VudHJpZXModGhpcy5zZXJ2aWNlcykpIHtcblx0XHRcdFx0XHR0aGlzLnN0YXJ0U2VydmljZShzZXJ2aWNlTmFtZSlcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gdGhpcy5saXZlXG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0cHJvdGVjdGVkIHN0YXJ0U2VydmljZShzZXJ2aWNlTmFtZTogUyk6IHZvaWQge1xuXHRcdHRoaXMubG9nZ2VyLmluZm8oXG5cdFx0XHRgU3RhcnRpbmcgc2VydmljZSAke3RoaXMub3B0aW9ucy5wYWNrYWdlTmFtZX06OiR7c2VydmljZU5hbWV9LCB0cnkgJHt0aGlzLnNhZmV0eX0vMi4uLmAsXG5cdFx0KVxuXHRcdGlmICh0aGlzLnNhZmV0eSA+PSAyKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoYE91dCBvZiB0cmllcy4uLmApXG5cdFx0fVxuXHRcdHRoaXMuc2FmZXR5KytcblxuXHRcdGNvbnN0IFtleGUsIC4uLmFyZ3NdID0gdGhpcy5vcHRpb25zLnNlcnZpY2VzW3NlcnZpY2VOYW1lXS5ydW4uc3BsaXQoYCBgKVxuXHRcdGNvbnN0IHNlcnZpY2VQcm9jZXNzID0gc3Bhd24oZXhlLCBhcmdzLCB7XG5cdFx0XHRjd2Q6IHRoaXMub3B0aW9ucy5mbGlnaHRkZWNrUm9vdERpcixcblx0XHRcdGVudjogaW1wb3J0Lm1ldGEuZW52LFxuXHRcdH0pXG5cdFx0Y29uc3Qgc2VydmljZUxvZ2dlciA9IHRoaXMuc2VydmljZUxvZ2dlcnNbc2VydmljZU5hbWVdXG5cdFx0Y29uc3Qgc2VydmljZSA9ICh0aGlzLnNlcnZpY2VzW3NlcnZpY2VOYW1lXSA9IG5ldyBDaGlsZFNvY2tldChcblx0XHRcdHNlcnZpY2VQcm9jZXNzLFxuXHRcdFx0YCR7dGhpcy5vcHRpb25zLnBhY2thZ2VOYW1lfTo6JHtzZXJ2aWNlTmFtZX1gLFxuXHRcdFx0c2VydmljZUxvZ2dlcixcblx0XHQpKVxuXHRcdHNlcnZpY2VMb2dnZXIucHJvY2Vzc0NvZGUgPSBzZXJ2aWNlLnByb2Nlc3MucGlkID8/IC0xXG5cdFx0dGhpcy5zZXJ2aWNlc1tzZXJ2aWNlTmFtZV0ub25BbnkoKC4uLm1lc3NhZ2VzKSA9PiB7XG5cdFx0XHRzZXJ2aWNlTG9nZ2VyLmluZm8oYPCfkqxgLCAuLi5tZXNzYWdlcylcblx0XHR9KVxuXHRcdHRoaXMuc2VydmljZXNbc2VydmljZU5hbWVdLm9uKGByZWFkeVRvVXBkYXRlYCwgKCkgPT4ge1xuXHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhgU2VydmljZSBcIiR7c2VydmljZU5hbWV9XCIgaXMgcmVhZHkgdG8gdXBkYXRlLmApXG5cdFx0XHR0aGlzLnNlcnZpY2VzUmVhZHlUb1VwZGF0ZVtzZXJ2aWNlTmFtZV0gPSB0cnVlXG5cdFx0XHR0aGlzLnRyeVVwZGF0ZSgpXG5cdFx0fSlcblx0XHR0aGlzLnNlcnZpY2VzW3NlcnZpY2VOYW1lXS5vbihgYWxpdmVgLCAoKSA9PiB7XG5cdFx0XHR0aGlzLnNlcnZpY2VzTGl2ZVt0aGlzLnNlcnZpY2VJZHhbc2VydmljZU5hbWVdXS51c2UoUHJvbWlzZS5yZXNvbHZlKCkpXG5cdFx0XHR0aGlzLnNlcnZpY2VzRGVhZFt0aGlzLnNlcnZpY2VJZHhbc2VydmljZU5hbWVdXSA9IG5ldyBGdXR1cmUoKCkgPT4ge30pXG5cdFx0XHRpZiAodGhpcy5kZWFkLmRvbmUpIHtcblx0XHRcdFx0dGhpcy5kZWFkID0gbmV3IEZ1dHVyZSgoKSA9PiB7fSlcblx0XHRcdH1cblx0XHRcdHRoaXMuZGVhZC51c2UoUHJvbWlzZS5hbGwodGhpcy5zZXJ2aWNlc0RlYWQpKVxuXHRcdH0pXG5cdFx0dGhpcy5zZXJ2aWNlc1tzZXJ2aWNlTmFtZV0ucHJvY2Vzcy5vbmNlKGBjbG9zZWAsIChleGl0Q29kZSkgPT4ge1xuXHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhcblx0XHRcdFx0YEF1dG8tcmVzcGF3biBzYXcgXCIke3NlcnZpY2VOYW1lfVwiIGV4aXQgd2l0aCBjb2RlICR7ZXhpdENvZGV9YCxcblx0XHRcdClcblx0XHRcdHRoaXMuc2VydmljZXNbc2VydmljZU5hbWVdID0gbnVsbFxuXHRcdFx0aWYgKCF0aGlzLmF1dG9SZXNwYXduRGVhZFNlcnZpY2VzKSB7XG5cdFx0XHRcdHRoaXMubG9nZ2VyLmluZm8oYEF1dG8tcmVzcGF3biBpcyBvZmY7IFwiJHtzZXJ2aWNlTmFtZX1cIiByZXN0cy5gKVxuXHRcdFx0XHRyZXR1cm5cblx0XHRcdH1cblx0XHRcdGNvbnN0IHVwZGF0ZVBoYXNlID0gdGhpcy5zdG9yYWdlLmdldEl0ZW0oYHVwZGF0ZVBoYXNlYClcblx0XHRcdHRoaXMubG9nZ2VyLmluZm8oYD4gc3RvcmFnZShcInVwZGF0ZVBoYXNlXCIpID5gLCB1cGRhdGVQaGFzZSlcblx0XHRcdGNvbnN0IHVwZGF0ZXNBcmVSZWFkeSA9IHVwZGF0ZVBoYXNlID09PSBgY29uZmlybWVkYFxuXHRcdFx0aWYgKHVwZGF0ZXNBcmVSZWFkeSkge1xuXHRcdFx0XHR0aGlzLnNlcnZpY2VMb2dnZXJzW3NlcnZpY2VOYW1lXS5pbmZvKGBVcGRhdGluZyBiZWZvcmUgc3RhcnR1cC4uLmApXG5cdFx0XHRcdHRoaXMucmVzdGFydFRpbWVzID0gW11cblx0XHRcdFx0dGhpcy5pbnN0YWxsUGFja2FnZSgpXG5cdFx0XHRcdHRoaXMuc3RhcnRTZXJ2aWNlKHNlcnZpY2VOYW1lKVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Y29uc3Qgbm93ID0gRGF0ZS5ub3coKVxuXHRcdFx0XHRjb25zdCBmaXZlTWludXRlc0FnbyA9IG5vdyAtIDUgKiA2MCAqIDEwMDBcblx0XHRcdFx0dGhpcy5yZXN0YXJ0VGltZXMgPSB0aGlzLnJlc3RhcnRUaW1lcy5maWx0ZXIoXG5cdFx0XHRcdFx0KHRpbWUpID0+IHRpbWUgPiBmaXZlTWludXRlc0Fnbyxcblx0XHRcdFx0KVxuXHRcdFx0XHR0aGlzLnJlc3RhcnRUaW1lcy5wdXNoKG5vdylcblxuXHRcdFx0XHRpZiAodGhpcy5yZXN0YXJ0VGltZXMubGVuZ3RoIDwgNSkge1xuXHRcdFx0XHRcdHRoaXMuc2VydmljZUxvZ2dlcnNbc2VydmljZU5hbWVdLmluZm8oYENyYXNoZWQuIFJlc3RhcnRpbmcuLi5gKVxuXHRcdFx0XHRcdHRoaXMuc3RhcnRTZXJ2aWNlKHNlcnZpY2VOYW1lKVxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHRoaXMuc2VydmljZUxvZ2dlcnNbc2VydmljZU5hbWVdLmluZm8oXG5cdFx0XHRcdFx0XHRgQ3Jhc2hlZCA1IHRpbWVzIGluIDUgbWludXRlcy4gTm90IHJlc3RhcnRpbmcuYCxcblx0XHRcdFx0XHQpXG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9KVxuXHRcdHRoaXMuc2FmZXR5ID0gMFxuXHR9XG5cblx0cHJvdGVjdGVkIGRvd25sb2FkUGFja2FnZSgpOiB2b2lkIHtcblx0XHR0aGlzLmxvZ2dlci5pbmZvKGBEb3dubG9hZGluZy4uLmApXG5cdFx0dHJ5IHtcblx0XHRcdGNvbnN0IG91dCA9IGV4ZWNTeW5jKHRoaXMub3B0aW9ucy5zY3JpcHRzLmRvd25sb2FkKVxuXHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhgRG93bmxvYWQgc3Rkb3V0OmAsIG91dC50b1N0cmluZygpKVxuXHRcdFx0dGhpcy5zdG9yYWdlLnNldEl0ZW0oYHNldHVwUGhhc2VgLCBgZG93bmxvYWRlZGApXG5cdFx0XHR0aGlzLmxvZ2dlci5pbmZvKGBEb3dubG9hZGVkIWApXG5cdFx0fSBjYXRjaCAodGhyb3duKSB7XG5cdFx0XHRpZiAodGhyb3duIGluc3RhbmNlb2YgRXJyb3IpIHtcblx0XHRcdFx0dGhpcy5sb2dnZXIuZXJyb3IoYEZhaWxlZCB0byBnZXQgdGhlIGxhdGVzdCByZWxlYXNlOiAke3Rocm93bi5tZXNzYWdlfWApXG5cdFx0XHR9XG5cdFx0XHRyZXR1cm5cblx0XHR9XG5cdH1cblxuXHRwcm90ZWN0ZWQgaW5zdGFsbFBhY2thZ2UoKTogdm9pZCB7XG5cdFx0dGhpcy5sb2dnZXIuaW5mbyhgSW5zdGFsbGluZy4uLmApXG5cblx0XHR0cnkge1xuXHRcdFx0Y29uc3Qgb3V0ID0gZXhlY1N5bmModGhpcy5vcHRpb25zLnNjcmlwdHMuaW5zdGFsbClcblx0XHRcdHRoaXMubG9nZ2VyLmluZm8oYEluc3RhbGwgc3Rkb3V0OmAsIG91dC50b1N0cmluZygpKVxuXHRcdFx0dGhpcy5zdG9yYWdlLnNldEl0ZW0oYHNldHVwUGhhc2VgLCBgaW5zdGFsbGVkYClcblx0XHRcdHRoaXMubG9nZ2VyLmluZm8oYEluc3RhbGxlZCFgKVxuXHRcdH0gY2F0Y2ggKHRocm93bikge1xuXHRcdFx0aWYgKHRocm93biBpbnN0YW5jZW9mIEVycm9yKSB7XG5cdFx0XHRcdHRoaXMubG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gZ2V0IHRoZSBsYXRlc3QgcmVsZWFzZTogJHt0aHJvd24ubWVzc2FnZX1gKVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuXG5cdFx0fVxuXHR9XG5cblx0cHVibGljIHN0b3BBbGxTZXJ2aWNlcygpOiBGdXR1cmU8dW5rbm93bj4ge1xuXHRcdHRoaXMubG9nZ2VyLmluZm8oYFN0b3BwaW5nIGFsbCBzZXJ2aWNlcy4uLiBhdXRvLXJlc3Bhd24gZGlzYWJsZWQuYClcblx0XHR0aGlzLmF1dG9SZXNwYXduRGVhZFNlcnZpY2VzID0gZmFsc2Vcblx0XHRmb3IgKGNvbnN0IFtzZXJ2aWNlTmFtZV0gb2YgdG9FbnRyaWVzKHRoaXMuc2VydmljZXMpKSB7XG5cdFx0XHR0aGlzLnN0b3BTZXJ2aWNlKHNlcnZpY2VOYW1lKVxuXHRcdH1cblx0XHRyZXR1cm4gdGhpcy5kZWFkXG5cdH1cblxuXHRwdWJsaWMgc3RvcFNlcnZpY2Uoc2VydmljZU5hbWU6IFMpOiB2b2lkIHtcblx0XHRjb25zdCBzZXJ2aWNlID0gdGhpcy5zZXJ2aWNlc1tzZXJ2aWNlTmFtZV1cblx0XHRpZiAoc2VydmljZSkge1xuXHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhgU3RvcHBpbmcgc2VydmljZSBcIiR7c2VydmljZU5hbWV9XCIuLi5gKVxuXHRcdFx0dGhpcy5zZXJ2aWNlc0RlYWRbdGhpcy5zZXJ2aWNlSWR4W3NlcnZpY2VOYW1lXV0udXNlKFxuXHRcdFx0XHRuZXcgUHJvbWlzZSgocGFzcykgPT4ge1xuXHRcdFx0XHRcdHNlcnZpY2UuZW1pdChgdGltZVRvU3RvcGApXG5cdFx0XHRcdFx0c2VydmljZS5wcm9jZXNzLm9uY2UoYGNsb3NlYCwgKGV4aXRDb2RlKSA9PiB7XG5cdFx0XHRcdFx0XHR0aGlzLmxvZ2dlci5pbmZvKFxuXHRcdFx0XHRcdFx0XHRgU3RvcHBlZCBzZXJ2aWNlIFwiJHtzZXJ2aWNlTmFtZX1cIjsgZXhpdGVkIHdpdGggY29kZSAke2V4aXRDb2RlfWAsXG5cdFx0XHRcdFx0XHQpXG5cdFx0XHRcdFx0XHR0aGlzLnNlcnZpY2VzW3NlcnZpY2VOYW1lXSA9IG51bGxcblx0XHRcdFx0XHRcdHBhc3MoKVxuXHRcdFx0XHRcdH0pXG5cdFx0XHRcdH0pLFxuXHRcdFx0KVxuXHRcdFx0dGhpcy5kZWFkLnVzZShQcm9taXNlLmFsbCh0aGlzLnNlcnZpY2VzRGVhZCkpXG5cdFx0XHR0aGlzLnNlcnZpY2VzTGl2ZVt0aGlzLnNlcnZpY2VJZHhbc2VydmljZU5hbWVdXSA9IG5ldyBGdXR1cmUoKCkgPT4ge30pXG5cdFx0XHRpZiAodGhpcy5saXZlLmRvbmUpIHtcblx0XHRcdFx0dGhpcy5saXZlID0gbmV3IEZ1dHVyZSgoKSA9PiB7fSlcblx0XHRcdH1cblx0XHRcdHRoaXMubGl2ZS51c2UoUHJvbWlzZS5hbGwodGhpcy5zZXJ2aWNlc0xpdmUpKVxuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aGlzLnNlcnZpY2VMb2dnZXJzW3NlcnZpY2VOYW1lXS5lcnJvcihcblx0XHRcdFx0YFRyaWVkIHRvIHN0b3Agc2VydmljZSwgYnV0IGl0IHdhc24ndCBydW5uaW5nLmAsXG5cdFx0XHQpXG5cdFx0fVxuXHR9XG59XG5cbmV4cG9ydCBjb25zdCBGTElHSFRERUNLX0lORk8gPSBgaW5mb2BcbmV4cG9ydCBjb25zdCBGTElHSFRERUNLX1dBUk4gPSBgd2FybmBcbmV4cG9ydCBjb25zdCBGTElHSFRERUNLX0VSUk9SID0gYEVSUiFgXG5cbmV4cG9ydCBjb25zdCBmbGlnaHREZWNrTG9nU2NoZW1hID0gei5vYmplY3Qoe1xuXHRsZXZlbDogei51bmlvbihbXG5cdFx0ei5saXRlcmFsKEZMSUdIVERFQ0tfSU5GTyksXG5cdFx0ei5saXRlcmFsKEZMSUdIVERFQ0tfV0FSTiksXG5cdFx0ei5saXRlcmFsKEZMSUdIVERFQ0tfRVJST1IpLFxuXHRdKSxcblx0dGltZXN0YW1wOiB6Lm51bWJlcigpLFxuXHRwYWNrYWdlOiB6LnN0cmluZygpLFxuXHRzZXJ2aWNlOiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG5cdHByb2Nlc3M6IHoubnVtYmVyKCksXG5cdGJvZHk6IHouc3RyaW5nKCksXG59KVxuZXhwb3J0IHR5cGUgRmxpZ2h0RGVja0xvZyA9IHouaW5mZXI8dHlwZW9mIGZsaWdodERlY2tMb2dTY2hlbWE+XG5cbmNvbnN0IExJTkVfRk9STUFUID0gYGxpbmUtZm9ybWF0YCBzYXRpc2ZpZXMga2V5b2YgTG5hdkZvcm1hdFxuY29uc3QgVkFMVUUgPSBgdmFsdWVgIHNhdGlzZmllcyBrZXlvZiBMbmF2Rm9ybWF0XG5cbmV4cG9ydCB0eXBlIExuYXZGb3JtYXRWaXN1YWxDb21wb25lbnQgPSBFeGNsdWRlPFxuXHRFeGNsdWRlPExuYXZGb3JtYXRbYGxpbmUtZm9ybWF0YF0sIHVuZGVmaW5lZD5bbnVtYmVyXSxcblx0c3RyaW5nXG4+XG5cbmV4cG9ydCB0eXBlIExuYXZGb3JtYXRCcmVha2Rvd24gPSBFeGNsdWRlPExuYXZGb3JtYXRbYHZhbHVlYF0sIHVuZGVmaW5lZD5cbmV4cG9ydCB0eXBlIE1lbWJlck9mPFQ+ID0gVFtrZXlvZiBUXVxuZXhwb3J0IHR5cGUgTG5hdkZvcm1hdFZhbHVlRGVmaW5pdGlvbiA9IE1lbWJlck9mPExuYXZGb3JtYXRCcmVha2Rvd24+XG5cbmV4cG9ydCB0eXBlIEZsaWdodERlY2tGb3JtYXQgPSB7XG5cdFtMSU5FX0ZPUk1BVF06IChcblx0XHR8IHN0cmluZ1xuXHRcdHwgKExuYXZGb3JtYXRWaXN1YWxDb21wb25lbnQgJiB7XG5cdFx0XHRcdGZpZWxkOiBrZXlvZiBGbGlnaHREZWNrTG9nIHwgYF9fbGV2ZWxfX2AgfCBgX190aW1lc3RhbXBfX2Bcblx0XHQgIH0pXG5cdClbXVxuXHRbVkFMVUVdOiB7XG5cdFx0W0sgaW4ga2V5b2YgRmxpZ2h0RGVja0xvZ106IExuYXZGb3JtYXRWYWx1ZURlZmluaXRpb24gJiB7XG5cdFx0XHRraW5kOiBGbGlnaHREZWNrTG9nW0tdIGV4dGVuZHMgbnVtYmVyIHwgdW5kZWZpbmVkXG5cdFx0XHRcdD8gYGludGVnZXJgXG5cdFx0XHRcdDogRmxpZ2h0RGVja0xvZ1tLXSBleHRlbmRzIHN0cmluZyB8IHVuZGVmaW5lZFxuXHRcdFx0XHRcdD8gYHN0cmluZ2Bcblx0XHRcdFx0XHQ6IG5ldmVyXG5cdFx0fVxuXHR9XG59XG5cbmV4cG9ydCBjb25zdCBGTElHSFRERUNLX0xOQVZfRk9STUFUID0ge1xuXHR0aXRsZTogYEZsaWdodERlY2sgTG9nYCxcblx0ZGVzY3JpcHRpb246IGBGb3JtYXQgZm9yIGV2ZW50cyBsb2dnZWQgYnkgdGhlIEZsaWdodERlY2sgcHJvY2VzcyBtYW5hZ2VyLmAsXG5cdFwiZmlsZS10eXBlXCI6IGBqc29uYCxcblx0XCJ0aW1lc3RhbXAtZmllbGRcIjogYHRpbWVzdGFtcGAsXG5cdFwidGltZXN0YW1wLWRpdmlzb3JcIjogMTAwMCxcblx0XCJtb2R1bGUtZmllbGRcIjogYHBhY2thZ2VgLFxuXHRcIm9waWQtZmllbGRcIjogYHNlcnZpY2VgLFxuXHRcImxldmVsLWZpZWxkXCI6IGBsZXZlbGAsXG5cdGxldmVsOiB7XG5cdFx0aW5mbzogRkxJR0hUREVDS19JTkZPLFxuXHRcdHdhcm5pbmc6IEZMSUdIVERFQ0tfV0FSTixcblx0XHRlcnJvcjogRkxJR0hUREVDS19FUlJPUixcblx0fSxcblxuXHRbTElORV9GT1JNQVRdOiBbXG5cdFx0e1xuXHRcdFx0ZmllbGQ6IGBsZXZlbGAsXG5cdFx0fSxcblx0XHR7XG5cdFx0XHRwcmVmaXg6IGAgYCxcblx0XHRcdGZpZWxkOiBgX190aW1lc3RhbXBfX2AsXG5cdFx0XHRcInRpbWVzdGFtcC1mb3JtYXRcIjogYCVZLSVtLSVkVCVIOiVNOiVTLiVMJVpgLFxuXHRcdH0sXG5cdFx0e1xuXHRcdFx0cHJlZml4OiBgIGAsXG5cdFx0XHRmaWVsZDogYHByb2Nlc3NgLFxuXHRcdFx0XCJtaW4td2lkdGhcIjogNSxcblx0XHR9LFxuXHRcdHtcblx0XHRcdHByZWZpeDogYDpgLFxuXHRcdFx0ZmllbGQ6IGBwYWNrYWdlYCxcblx0XHR9LFxuXHRcdHtcblx0XHRcdHByZWZpeDogYDpgLFxuXHRcdFx0ZmllbGQ6IGBzZXJ2aWNlYCxcblx0XHRcdFwiZGVmYXVsdC12YWx1ZVwiOiBgYCxcblx0XHR9LFxuXHRcdHtcblx0XHRcdHByZWZpeDogYDogYCxcblx0XHRcdGZpZWxkOiBgYm9keWAsXG5cdFx0fSxcblx0XSxcblxuXHRbVkFMVUVdOiB7XG5cdFx0dGltZXN0YW1wOiB7XG5cdFx0XHRraW5kOiBgaW50ZWdlcmAsXG5cdFx0fSxcblx0XHRsZXZlbDoge1xuXHRcdFx0a2luZDogYHN0cmluZ2AsXG5cdFx0fSxcblx0XHRwYWNrYWdlOiB7XG5cdFx0XHRraW5kOiBgc3RyaW5nYCxcblx0XHR9LFxuXHRcdHNlcnZpY2U6IHtcblx0XHRcdGtpbmQ6IGBzdHJpbmdgLFxuXHRcdH0sXG5cdFx0cHJvY2Vzczoge1xuXHRcdFx0a2luZDogYGludGVnZXJgLFxuXHRcdH0sXG5cdFx0Ym9keToge1xuXHRcdFx0a2luZDogYHN0cmluZ2AsXG5cdFx0fSxcblx0fSxcbn0gYXMgY29uc3Qgc2F0aXNmaWVzIEZsaWdodERlY2tGb3JtYXQgJiBMbmF2Rm9ybWF0XG5cbmV4cG9ydCBjbGFzcyBGbGlnaHREZWNrTG9nZ2VyXG5cdGltcGxlbWVudHMgUGljazxDb25zb2xlLCBgZXJyb3JgIHwgYGluZm9gIHwgYHdhcm5gPlxue1xuXHRwdWJsaWMgcmVhZG9ubHkgcGFja2FnZU5hbWU6IHN0cmluZ1xuXHRwdWJsaWMgcmVhZG9ubHkgc2VydmljZU5hbWU/OiBzdHJpbmdcblx0cHVibGljIHJlYWRvbmx5IGpzb25Mb2dnaW5nOiBib29sZWFuXG5cdHB1YmxpYyBwcm9jZXNzQ29kZTogbnVtYmVyXG5cdHB1YmxpYyBjb25zdHJ1Y3Rvcihcblx0XHRwYWNrYWdlTmFtZTogc3RyaW5nLFxuXHRcdHByb2Nlc3NDb2RlOiBudW1iZXIsXG5cdFx0c2VydmljZU5hbWU/OiBzdHJpbmcsXG5cdFx0b3B0aW9ucz86IHsganNvbkxvZ2dpbmc6IGJvb2xlYW4gfSxcblx0KSB7XG5cdFx0dGhpcy5wYWNrYWdlTmFtZSA9IHBhY2thZ2VOYW1lXG5cdFx0aWYgKHNlcnZpY2VOYW1lKSB7XG5cdFx0XHR0aGlzLnNlcnZpY2VOYW1lID0gc2VydmljZU5hbWVcblx0XHR9XG5cdFx0dGhpcy5wcm9jZXNzQ29kZSA9IHByb2Nlc3NDb2RlXG5cdFx0dGhpcy5qc29uTG9nZ2luZyA9IG9wdGlvbnM/Lmpzb25Mb2dnaW5nID8/IGZhbHNlXG5cdH1cblx0cHJvdGVjdGVkIGxvZyhcblx0XHRsZXZlbDpcblx0XHRcdHwgdHlwZW9mIEZMSUdIVERFQ0tfRVJST1Jcblx0XHRcdHwgdHlwZW9mIEZMSUdIVERFQ0tfSU5GT1xuXHRcdFx0fCB0eXBlb2YgRkxJR0hUREVDS19XQVJOLFxuXHRcdC4uLm1lc3NhZ2VzOiB1bmtub3duW11cblx0KTogdm9pZCB7XG5cdFx0aWYgKHRoaXMuanNvbkxvZ2dpbmcpIHtcblx0XHRcdGxldCBib2R5ID0gbWVzc2FnZXNcblx0XHRcdFx0Lm1hcCgobWVzc2FnZSkgPT5cblx0XHRcdFx0XHR0eXBlb2YgbWVzc2FnZSA9PT0gYHN0cmluZ2Bcblx0XHRcdFx0XHRcdD8gbWVzc2FnZVxuXHRcdFx0XHRcdFx0OiBpbnNwZWN0KG1lc3NhZ2UsIGZhbHNlLCBudWxsLCB0cnVlKSxcblx0XHRcdFx0KVxuXHRcdFx0XHQuam9pbihgIGApXG5cdFx0XHRpZiAoYm9keS5pbmNsdWRlcyhgXFxuYCkpIHtcblx0XHRcdFx0Ym9keSA9IGBcXG4gICR7Ym9keS5zcGxpdChgXFxuYCkuam9pbihgXFxuICBgKX1gXG5cdFx0XHR9XG5cdFx0XHRjb25zdCBsb2c6IEZsaWdodERlY2tMb2cgPSB7XG5cdFx0XHRcdHRpbWVzdGFtcDogRGF0ZS5ub3coKSxcblx0XHRcdFx0bGV2ZWwsXG5cdFx0XHRcdHByb2Nlc3M6IHRoaXMucHJvY2Vzc0NvZGUsXG5cdFx0XHRcdHBhY2thZ2U6IHRoaXMucGFja2FnZU5hbWUsXG5cdFx0XHRcdGJvZHksXG5cdFx0XHR9XG5cdFx0XHRpZiAodGhpcy5zZXJ2aWNlTmFtZSkge1xuXHRcdFx0XHRsb2cuc2VydmljZSA9IHRoaXMuc2VydmljZU5hbWVcblx0XHRcdH1cblx0XHRcdHByb2Nlc3Muc3Rkb3V0LndyaXRlKEpTT04uc3RyaW5naWZ5KGxvZykgKyBgXFxuYClcblx0XHR9IGVsc2Uge1xuXHRcdFx0Y29uc3Qgc291cmNlID0gdGhpcy5zZXJ2aWNlTmFtZVxuXHRcdFx0XHQ/IGAke3RoaXMucGFja2FnZU5hbWV9OiR7dGhpcy5zZXJ2aWNlTmFtZX1gXG5cdFx0XHRcdDogdGhpcy5wYWNrYWdlTmFtZVxuXHRcdFx0c3dpdGNoIChsZXZlbCkge1xuXHRcdFx0XHRjYXNlIEZMSUdIVERFQ0tfSU5GTzpcblx0XHRcdFx0XHRjb25zb2xlLmxvZyhgJHtzb3VyY2V9OmAsIC4uLm1lc3NhZ2VzKVxuXHRcdFx0XHRcdGJyZWFrXG5cdFx0XHRcdGNhc2UgRkxJR0hUREVDS19XQVJOOlxuXHRcdFx0XHRcdGNvbnNvbGUud2FybihgJHtzb3VyY2V9OmAsIC4uLm1lc3NhZ2VzKVxuXHRcdFx0XHRcdGJyZWFrXG5cdFx0XHRcdGNhc2UgRkxJR0hUREVDS19FUlJPUjpcblx0XHRcdFx0XHRjb25zb2xlLmVycm9yKGAke3NvdXJjZX06YCwgLi4ubWVzc2FnZXMpXG5cdFx0XHRcdFx0YnJlYWtcblx0XHRcdH1cblx0XHR9XG5cdH1cblx0cHVibGljIGluZm8oLi4ubWVzc2FnZXM6IHVua25vd25bXSk6IHZvaWQge1xuXHRcdHRoaXMubG9nKEZMSUdIVERFQ0tfSU5GTywgLi4ubWVzc2FnZXMpXG5cdH1cblxuXHRwdWJsaWMgd2FybiguLi5tZXNzYWdlczogdW5rbm93bltdKTogdm9pZCB7XG5cdFx0dGhpcy5sb2coRkxJR0hUREVDS19XQVJOLCAuLi5tZXNzYWdlcylcblx0fVxuXG5cdHB1YmxpYyBlcnJvciguLi5tZXNzYWdlczogdW5rbm93bltdKTogdm9pZCB7XG5cdFx0dGhpcy5sb2coRkxJR0hUREVDS19FUlJPUiwgLi4ubWVzc2FnZXMpXG5cdH1cbn1cbiIsCiAgICAiaW1wb3J0IHsgY3JlYXRlRW52IH0gZnJvbSBcIkB0My1vc3MvZW52LWNvcmVcIlxuaW1wb3J0IHsgeiB9IGZyb20gXCJ6b2RcIlxuXG5leHBvcnQgY29uc3QgZW52ID0gY3JlYXRlRW52KHtcblx0c2VydmVyOiB7IEZMSUdIVERFQ0tfU0VDUkVUOiB6LnN0cmluZygpLm9wdGlvbmFsKCkgfSxcblx0Y2xpZW50UHJlZml4OiBgTkVWRVJgLFxuXHRjbGllbnQ6IHt9LFxuXHRydW50aW1lRW52OiBpbXBvcnQubWV0YS5lbnYsXG5cdGVtcHR5U3RyaW5nQXNVbmRlZmluZWQ6IHRydWUsXG59KVxuIiwKICAgICJleHBvcnQgdHlwZSBBbGVydE9wdGlvbnMgPSB7XG5cdHNlY3JldDogc3RyaW5nXG5cdGVuZHBvaW50OiBzdHJpbmdcblx0dmVyc2lvbjogc3RyaW5nXG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBhbGVydCh7XG5cdHNlY3JldCxcblx0ZW5kcG9pbnQsXG5cdHZlcnNpb24sXG59OiBBbGVydE9wdGlvbnMpOiBQcm9taXNlPFJlc3BvbnNlPiB7XG5cdGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goZW5kcG9pbnQsIHtcblx0XHRtZXRob2Q6IGBQT1NUYCxcblx0XHRoZWFkZXJzOiB7XG5cdFx0XHRcIkNvbnRlbnQtVHlwZVwiOiBgdGV4dC9wbGFpbjtjaGFyc2V0PVVURi04YCxcblx0XHRcdEF1dGhvcml6YXRpb246IGBCZWFyZXIgJHtzZWNyZXR9YCxcblx0XHR9LFxuXHRcdGJvZHk6IHZlcnNpb24sXG5cdH0pXG5cblx0cmV0dXJuIHJlc3BvbnNlXG59XG5cbi8qKlxuICogQHNlZSBodHRwczovL2dpdGh1Yi5jb20vY2hhbmdlc2V0cy9hY3Rpb24vYmxvYi9tYWluL3NyYy9ydW4udHNcbiAqL1xuZXhwb3J0IHR5cGUgQ2hhbmdlc2V0c1B1Ymxpc2hlZFBhY2thZ2UgPSB7XG5cdG5hbWU6IHN0cmluZ1xuXHR2ZXJzaW9uOiBzdHJpbmdcbn1cblxuLyoqXG4gKiBAc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFuZ2VzZXRzL2FjdGlvbi9ibG9iL21haW4vc3JjL3J1bi50c1xuICovXG5leHBvcnQgdHlwZSBDaGFuZ2VzZXRzUHVibGlzaFJlc3VsdCA9XG5cdHwge1xuXHRcdFx0cHVibGlzaGVkOiB0cnVlXG5cdFx0XHRwdWJsaXNoZWRQYWNrYWdlczogQ2hhbmdlc2V0c1B1Ymxpc2hlZFBhY2thZ2VbXVxuXHQgIH1cblx0fCB7IHB1Ymxpc2hlZDogZmFsc2UgfVxuXG5leHBvcnQgdHlwZSBQYWNrYWdlQ29uZmlnPEsgZXh0ZW5kcyBzdHJpbmc+ID0ge1xuXHRba2V5IGluIEtdOiB7IGVuZHBvaW50OiBzdHJpbmcgfVxufVxuZXhwb3J0IHR5cGUgU2VjcmV0c0NvbmZpZzxLIGV4dGVuZHMgc3RyaW5nPiA9IHtcblx0W2tleSBpbiBLXTogc3RyaW5nXG59XG5cbmV4cG9ydCB0eXBlIFNjcmFtYmxlT3B0aW9uczxLIGV4dGVuZHMgc3RyaW5nID0gc3RyaW5nPiA9IHtcblx0cGFja2FnZUNvbmZpZzogUGFja2FnZUNvbmZpZzxLPlxuXHRzZWNyZXRzQ29uZmlnOiBTZWNyZXRzQ29uZmlnPEs+XG5cdHB1Ymxpc2hlZFBhY2thZ2VzOiBDaGFuZ2VzZXRzUHVibGlzaGVkUGFja2FnZVtdXG59XG5cbmV4cG9ydCB0eXBlIFNjcmFtYmxlUmVzdWx0PEsgZXh0ZW5kcyBzdHJpbmcgPSBzdHJpbmc+ID0ge1xuXHRba2V5IGluIEtdOiBSZXNwb25zZVxufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc2NyYW1ibGU8SyBleHRlbmRzIHN0cmluZyA9IHN0cmluZz4oe1xuXHRwYWNrYWdlQ29uZmlnLFxuXHRzZWNyZXRzQ29uZmlnLFxuXHRwdWJsaXNoZWRQYWNrYWdlcyxcbn06IFNjcmFtYmxlT3B0aW9uczxLPik6IFByb21pc2U8U2NyYW1ibGVSZXN1bHQ8Sz4+IHtcblx0Y29uc3QgYWxlcnRSZXN1bHRzOiBQcm9taXNlPHJlYWRvbmx5IFtLLCBSZXNwb25zZV0+W10gPSBbXVxuXHRmb3IgKGNvbnN0IHB1Ymxpc2hlZFBhY2thZ2Ugb2YgcHVibGlzaGVkUGFja2FnZXMpIHtcblx0XHRpZiAocHVibGlzaGVkUGFja2FnZS5uYW1lIGluIHBhY2thZ2VDb25maWcpIHtcblx0XHRcdGNvbnN0IG5hbWUgPSBwdWJsaXNoZWRQYWNrYWdlLm5hbWUgYXMgS1xuXHRcdFx0Y29uc3QgeyBlbmRwb2ludCB9ID0gcGFja2FnZUNvbmZpZ1tuYW1lXVxuXHRcdFx0Y29uc3Qgc2VjcmV0ID0gc2VjcmV0c0NvbmZpZ1tuYW1lXVxuXHRcdFx0Y29uc3QgdmVyc2lvbiA9IHB1Ymxpc2hlZFBhY2thZ2UudmVyc2lvblxuXHRcdFx0Y29uc3QgYWxlcnRSZXN1bHRQcm9taXNlID0gYWxlcnQoeyBzZWNyZXQsIGVuZHBvaW50LCB2ZXJzaW9uIH0pLnRoZW4oXG5cdFx0XHRcdChhbGVydFJlc3VsdCkgPT4gW25hbWUsIGFsZXJ0UmVzdWx0XSBhcyBjb25zdCxcblx0XHRcdClcblx0XHRcdGFsZXJ0UmVzdWx0cy5wdXNoKGFsZXJ0UmVzdWx0UHJvbWlzZSlcblx0XHR9XG5cdH1cblx0Y29uc3QgYWxlcnRSZXN1bHRzUmVzb2x2ZWQgPSBhd2FpdCBQcm9taXNlLmFsbChhbGVydFJlc3VsdHMpXG5cdGNvbnN0IHNjcmFtYmxlUmVzdWx0ID0gT2JqZWN0LmZyb21FbnRyaWVzKFxuXHRcdGFsZXJ0UmVzdWx0c1Jlc29sdmVkLFxuXHQpIGFzIFNjcmFtYmxlUmVzdWx0PEs+XG5cdHJldHVybiBzY3JhbWJsZVJlc3VsdFxufVxuIgogIF0sCiAgIm1hcHBpbmdzIjogIjhIQUFBLHFCQUNDLGVBQ0EsaUJBQ0Esa0JBQ0EsWUFDQSxjQUNBLG1CQUNBLGdCQUVELGtCQUFTLGtCQU1GLE1BQU0sQ0FHYixDQUNRLFFBRUEsV0FBVyxDQUFDLEVBQW1DLENBRXJELEdBREEsS0FBSyxRQUFVLEVBQVEsTUFDbEIsRUFBVyxLQUFLLE9BQU8sRUFDM0IsRUFBVSxLQUFLLFFBQVMsQ0FBRSxVQUFXLEVBQUssQ0FBQyxFQUl0QyxPQUFtQyxDQUFDLEVBQXFCLENBQy9ELElBQU0sRUFBVyxFQUFRLEtBQUssUUFBUyxDQUFHLEVBQzFDLEdBQUksRUFBVyxDQUFRLEVBQ3RCLE9BQU8sRUFBYSxFQUFVLE9BQU8sRUFFdEMsT0FBTyxLQUdELE9BQW1DLENBQUMsRUFBUSxFQUFtQixDQUNyRSxJQUFNLEVBQVcsRUFBUSxLQUFLLFFBQVMsQ0FBRyxFQUMxQyxFQUFjLEVBQVUsQ0FBSyxFQUd2QixVQUFzQyxDQUFDLEVBQWMsQ0FDM0QsSUFBTSxFQUFXLEVBQVEsS0FBSyxRQUFTLENBQUcsRUFDMUMsR0FBSSxFQUFXLENBQVEsRUFDdEIsRUFBTyxDQUFRLEVBSVYsR0FBRyxDQUFDLEVBQTBDLENBT3BELE9BTmtCLEVBQVksS0FBSyxPQUFPLEVBQ0QsS0FBSyxDQUFDLEVBQUcsSUFBTSxDQUN2RCxJQUFNLEVBQVEsRUFBUyxDQUFDLEVBRXhCLE9BRGMsRUFBUyxDQUFDLEVBQ1gsUUFBVSxFQUFNLFFBQzdCLEVBQzhCLElBQStC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RUFBSyxTQUFTO0FBQUEsQ0FBSSxFQUNyQixFQUFPO0FBQUEsSUFBTyxFQUFLLE1BQU07QUFBQSxDQUFJLEVBQUUsS0FBSztBQUFBLEdBQU0sSUFFM0MsSUFBTSxFQUFxQixDQUMxQixVQUFXLEtBQUssSUFBSSxFQUNwQixRQUNBLFFBQVMsS0FBSyxZQUNkLFFBQVMsS0FBSyxZQUNkLE1BQ0QsRUFDQSxHQUFJLEtBQUssWUFDUixFQUFJLFFBQVUsS0FBSyxZQUVwQixRQUFRLE9BQU8sTUFBTSxLQUFLLFVBQVUsQ0FBRyxFQUFJO0FBQUEsQ0FBSSxNQUN6QyxDQUNOLElBQU0sRUFBUyxLQUFLLFlBQ2pCLEdBQUcsS0FBSyxlQUFlLEtBQUssY0FDNUIsS0FBSyxZQUNSLE9BQVEsUUFDRixFQUNKLFFBQVEsSUFBSSxHQUFHLEtBQVcsR0FBRyxDQUFRLEVBQ3JDLFdBQ0ksRUFDSixRQUFRLEtBQUssR0FBRyxLQUFXLEdBQUcsQ0FBUSxFQUN0QyxXQUNJLEVBQ0osUUFBUSxNQUFNLEdBQUcsS0FBVyxHQUFHLENBQVEsRUFDdkMsUUFJRyxJQUFJLElBQUksRUFBMkIsQ0FDekMsS0FBSyxJQUFJLEVBQWlCLEdBQUcsQ0FBUSxFQUcvQixJQUFJLElBQUksRUFBMkIsQ0FDekMsS0FBSyxJQUFJLEVBQWlCLEdBQUcsQ0FBUSxFQUcvQixLQUFLLElBQUksRUFBMkIsQ0FDMUMsS0FBSyxJQUFJLEVBQWtCLEdBQUcsQ0FBUSxFQUV4Qyw0Q0VqbkJBLGVBQXNCLENBQUssRUFDMUIsU0FDQSxXQUNBLFdBQ21DLENBVW5DLE9BVGlCLE1BQU0sTUFBTSxFQUFVLENBQ3RDLE9BQVEsT0FDUixRQUFTLENBQ1IsZUFBZ0IsMkJBQ2hCLGNBQWUsVUFBVSxHQUMxQixFQUNBLEtBQU0sQ0FDUCxDQUFDLEVBd0NGLGVBQXNCLENBQW1DLEVBQ3hELGdCQUNBLGdCQUNBLHFCQUNrRCxDQUNsRCxJQUFNLEVBQWtELENBQUMsRUFDekQsUUFBVyxLQUFvQixFQUM5QixHQUFJLEVBQWlCLFFBQVEsRUFBZSxDQUMzQyxJQUFNLEVBQU8sRUFBaUIsTUFDdEIsWUFBYSxFQUFjLEdBQzdCLEVBQVMsRUFBYyxHQUN2QixFQUFVLEVBQWlCLFFBQzNCLEVBQXFCLEVBQU0sQ0FBRSxTQUFRLFdBQVUsU0FBUSxDQUFDLEVBQUUsS0FDL0QsQ0FBQyxJQUFnQixDQUFDLEVBQU0sQ0FBVyxDQUNwQyxFQUNBLEVBQWEsS0FBSyxDQUFrQixFQUd0QyxJQUFNLEVBQXVCLE1BQU0sUUFBUSxJQUFJLENBQVksRUFJM0QsT0FIdUIsT0FBTyxZQUM3QixDQUNEIiwKICAiZGVidWdJZCI6ICIxNkEwMkZGQjAzNTBCQ0ZGNjQ3NTZFMjE2NDc1NkUyMSIsCiAgIm5hbWVzIjogW10KfQ==
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flightdeck",
3
- "version": "0.2.6",
3
+ "version": "0.2.8",
4
4
  "license": "MIT",
5
5
  "author": {
6
6
  "name": "Jeremy Banka",
@@ -438,8 +438,16 @@ export class FlightDeck<S extends string = string> {
438
438
  }
439
439
  }
440
440
 
441
+ export const FLIGHTDECK_INFO = `info`
442
+ export const FLIGHTDECK_WARN = `warn`
443
+ export const FLIGHTDECK_ERROR = `ERR!`
444
+
441
445
  export const flightDeckLogSchema = z.object({
442
- level: z.union([z.literal(`info`), z.literal(`warn`), z.literal(`ERR!`)]),
446
+ level: z.union([
447
+ z.literal(FLIGHTDECK_INFO),
448
+ z.literal(FLIGHTDECK_WARN),
449
+ z.literal(FLIGHTDECK_ERROR),
450
+ ]),
443
451
  timestamp: z.number(),
444
452
  package: z.string(),
445
453
  service: z.string().optional(),
@@ -483,18 +491,20 @@ export const FLIGHTDECK_LNAV_FORMAT = {
483
491
  description: `Format for events logged by the FlightDeck process manager.`,
484
492
  "file-type": `json`,
485
493
  "timestamp-field": `timestamp`,
486
- "subsecond-field": `subsecond`,
487
- "subsecond-units": `milli`,
494
+ "timestamp-divisor": 1000,
495
+ "module-field": `package`,
488
496
  "opid-field": `service`,
489
497
  "level-field": `level`,
490
498
  level: {
491
- info: `info`,
492
- warning: `warn`,
493
- error: `err!`,
499
+ info: FLIGHTDECK_INFO,
500
+ warning: FLIGHTDECK_WARN,
501
+ error: FLIGHTDECK_ERROR,
494
502
  },
495
- "ordered-by-time": true,
496
503
 
497
504
  [LINE_FORMAT]: [
505
+ {
506
+ field: `level`,
507
+ },
498
508
  {
499
509
  prefix: ` `,
500
510
  field: `__timestamp__`,
@@ -514,11 +524,6 @@ export const FLIGHTDECK_LNAV_FORMAT = {
514
524
  field: `service`,
515
525
  "default-value": ``,
516
526
  },
517
- {
518
- prefix: `[`,
519
- field: `__level__`,
520
- suffix: `]`,
521
- },
522
527
  {
523
528
  prefix: `: `,
524
529
  field: `body`,
@@ -567,20 +572,30 @@ export class FlightDeckLogger
567
572
  this.processCode = processCode
568
573
  this.jsonLogging = options?.jsonLogging ?? false
569
574
  }
570
- public info(...messages: unknown[]): void {
575
+ protected log(
576
+ level:
577
+ | typeof FLIGHTDECK_ERROR
578
+ | typeof FLIGHTDECK_INFO
579
+ | typeof FLIGHTDECK_WARN,
580
+ ...messages: unknown[]
581
+ ): void {
571
582
  if (this.jsonLogging) {
583
+ let body = messages
584
+ .map((message) =>
585
+ typeof message === `string`
586
+ ? message
587
+ : inspect(message, false, null, true),
588
+ )
589
+ .join(` `)
590
+ if (body.includes(`\n`)) {
591
+ body = `\n ${body.split(`\n`).join(`\n `)}`
592
+ }
572
593
  const log: FlightDeckLog = {
573
594
  timestamp: Date.now(),
574
- level: `info`,
595
+ level,
575
596
  process: this.processCode,
576
597
  package: this.packageName,
577
- body: messages
578
- .map((message) =>
579
- typeof message === `string`
580
- ? message
581
- : inspect(message, false, null, true),
582
- )
583
- .join(` `),
598
+ body,
584
599
  }
585
600
  if (this.serviceName) {
586
601
  log.service = this.serviceName
@@ -588,63 +603,30 @@ export class FlightDeckLogger
588
603
  process.stdout.write(JSON.stringify(log) + `\n`)
589
604
  } else {
590
605
  const source = this.serviceName
591
- ? `${this.packageName}::${this.serviceName}`
606
+ ? `${this.packageName}:${this.serviceName}`
592
607
  : this.packageName
593
- console.log(`${source}:`, ...messages)
608
+ switch (level) {
609
+ case FLIGHTDECK_INFO:
610
+ console.log(`${source}:`, ...messages)
611
+ break
612
+ case FLIGHTDECK_WARN:
613
+ console.warn(`${source}:`, ...messages)
614
+ break
615
+ case FLIGHTDECK_ERROR:
616
+ console.error(`${source}:`, ...messages)
617
+ break
618
+ }
594
619
  }
595
620
  }
621
+ public info(...messages: unknown[]): void {
622
+ this.log(FLIGHTDECK_INFO, ...messages)
623
+ }
596
624
 
597
625
  public warn(...messages: unknown[]): void {
598
- if (this.jsonLogging) {
599
- const log: FlightDeckLog = {
600
- timestamp: Date.now(),
601
- level: `warn`,
602
- process: this.processCode,
603
- package: this.packageName,
604
- body: messages
605
- .map((message) =>
606
- typeof message === `string`
607
- ? message
608
- : inspect(message, false, null, true),
609
- )
610
- .join(` `),
611
- }
612
- if (this.serviceName) {
613
- log.service = this.serviceName
614
- }
615
- process.stdout.write(JSON.stringify(log) + `\n`)
616
- } else {
617
- const source = this.serviceName
618
- ? `${this.packageName}::${this.serviceName}`
619
- : this.packageName
620
- console.warn(`${source}:`, ...messages)
621
- }
626
+ this.log(FLIGHTDECK_WARN, ...messages)
622
627
  }
623
628
 
624
629
  public error(...messages: unknown[]): void {
625
- if (this.jsonLogging) {
626
- const log: FlightDeckLog = {
627
- timestamp: Date.now() + Math.floor(Math.random() * 1000),
628
- level: `ERR!`,
629
- process: this.processCode,
630
- package: this.packageName,
631
- body: messages
632
- .map((message) =>
633
- typeof message === `string`
634
- ? message
635
- : inspect(message, false, null, true),
636
- )
637
- .join(` `),
638
- }
639
- if (this.serviceName) {
640
- log.service = this.serviceName
641
- }
642
- process.stdout.write(JSON.stringify(log) + `\n`)
643
- } else {
644
- const source = this.serviceName
645
- ? `${this.packageName}::${this.serviceName}`
646
- : this.packageName
647
- console.error(`${source}:`, ...messages)
648
- }
630
+ this.log(FLIGHTDECK_ERROR, ...messages)
649
631
  }
650
632
  }