flightdeck 0.2.14 → 0.2.16

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.
package/dist/lib.js CHANGED
@@ -1,9 +1,5 @@
1
- var x=Object.defineProperty;var A=(e,i)=>{for(var t in i)x(e,t,{get:i[t],enumerable:!0,configurable:!0,set:(o)=>i[t]=()=>o})};import{execSync as w,spawn as C}from"node:child_process";import{createServer as _}from"node:http";import{homedir as R}from"node:os";import{resolve as b}from"node:path";import{inspect as U}from"node:util";import{Future as p}from"atom.io/internal";import{discoverType as $}from"atom.io/introspection";import{fromEntries as v,toEntries as u}from"atom.io/json";import{ChildSocket as H}from"atom.io/realtime-server";import{CronJob as K}from"cron";import{FilesystemStorage as j}from"safedeposit";import{z as l}from"zod";import{createEnv as P}from"@t3-oss/env-core";import{z as I}from"zod";var L=P({server:{FLIGHTDECK_SECRET:I.string().optional()},clientPrefix:"NEVER",client:{},runtimeEnv:import.meta.env,emptyStringAsUndefined:!0});var le=["downloaded","installed"],ce=["notified","confirmed"];function G(e){return/^\d+\.\d+\.\d+$/.test(e)||!Number.isNaN(Number.parseFloat(e))}class O{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:i}=L,{flightdeckRootDir:t=b(R(),".flightdeck")}=e,o=e.port??8080,n=`http://localhost:${o}`,c=u(e.services);if(this.services=v(c.map(([s])=>[s,null])),this.serviceIdx=v(c.map(([s],r)=>[s,r])),this.defaultServicesReadyToUpdate=v(c.map(([s,{waitFor:r}])=>[s,!r])),this.servicesReadyToUpdate={...this.defaultServicesReadyToUpdate},this.autoRespawnDeadServices=!0,this.logger=new S(this.options.packageName,process.pid,void 0,{jsonLogging:this.options.jsonLogging??!1}),this.serviceLoggers=v(c.map(([s])=>[s,new S(this.options.packageName,process.pid,s,{jsonLogging:this.options.jsonLogging??!1})])),this.servicesLive=c.map(()=>new p(()=>{})),this.servicesDead=c.map(()=>new p(()=>{})),this.live.use(Promise.all(this.servicesLive)),this.dead.use(Promise.all(this.servicesDead)),this.storage=new j({path:b(t,"storage",e.packageName)}),i===void 0)this.logger.warn("No FLIGHTDECK_SECRET environment variable found. FlightDeck will not run an update server.");else _((s,r)=>{let g=[];s.on("data",(a)=>{g.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 ${i}`;if(a!==`Bearer ${i}`)throw this.logger.info(`Unauthorized: needed \`${d}\`, got \`${a}\``),401;let f=new URL(s.url,n);this.logger.info(s.method,f.pathname);let h=Buffer.concat(g).toString();if(!G(h))throw 400;r.writeHead(200),r.end(),this.storage.setItem("updatePhase","notified"),this.storage.setItem("updateAwaitedVersion",h);let{checkAvailability:T}=e.scripts;if(T){this.updateAvailabilityChecker?.stop(),this.seekUpdate(h);let F=this.storage.getItem("updatePhase");if(this.logger.info('> storage("updatePhase") >',F),F==="notified")this.updateAvailabilityChecker=new K("30 * * * * *",()=>{this.seekUpdate(h)}),this.updateAvailabilityChecker.start()}else this.downloadPackage()}catch(d){if(this.logger.error(d,s.url),typeof d==="number")r.writeHead(d),r.end()}finally{g=[]}})}).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:i}=this.options.scripts;if(!i){this.logger.info("No checkAvailability script found.");return}try{let t=w(`${i} ${e}`);this.logger.info("Check stdout:",t.toString()),this.updateAvailabilityChecker?.stop(),this.storage.setItem("updatePhase","confirmed"),this.downloadPackage(),this.announceUpdate()}catch(t){if(t instanceof Error)this.logger.error("Check failed:",t.message);else{let o=$(t);this.logger.error("Check threw",o,t)}}}announceUpdate(){for(let e of u(this.services)){let[i,t]=e;if(t){if(this.options.services[i].waitFor)t.emit("updatesReady")}else this.startService(i)}}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[i]of u(this.services))this.startService(i);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[i,...t]=this.options.services[e].run.split(" "),o=C(i,t,{cwd:this.options.flightdeckRootDir,env:import.meta.env}),n=this.serviceLoggers[e],c=this.services[e]=new H(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 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 r=this.storage.getItem("updatePhase");if(this.logger.info('> storage("updatePhase") >',r),r==="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=w(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=w(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 i=this.services[e];if(i){if(this.logger.info(`Stopping service "${e}"...`),this.servicesDead[this.serviceIdx[e]].use(new Promise((t)=>{i.emit("timeToStop"),i.process.once("close",(o)=>{this.logger.info(`Stopped service "${e}"; exited with code ${o}`),this.services[e]=null,t()})})),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!",de=l.object({level:l.union([l.literal(m),l.literal(y),l.literal(k)]),timestamp:l.number(),package:l.string(),service:l.string().optional(),process:l.number(),body:l.string()}),V="line-format",N="value",pe={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},[V]:[{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"}],[N]:{timestamp:{kind:"integer"},level:{kind:"string"},package:{kind:"string"},service:{kind:"string"},process:{kind:"integer"},body:{kind:"string"}}};class S{packageName;serviceName;jsonLogging;processCode;constructor(e,i,t,o){if(this.packageName=e,t)this.serviceName=t;this.processCode=i,this.jsonLogging=o?.jsonLogging??!1}log(e,...i){if(this.jsonLogging){let t=i.map((n)=>typeof n==="string"?n:U(n,!1,null,!0)).join(" ");if(t.includes(`
2
- `))t=`
3
- ${t.split(`
4
- `).join(`
5
- `)}`;let o={timestamp:Date.now(),level:e,process:this.processCode,package:this.packageName,body:t};if(this.serviceName)o.service=this.serviceName;process.stdout.write(JSON.stringify(o)+`
6
- `)}else{let t=this.serviceName?`${this.packageName}:${this.serviceName}`:this.packageName;switch(e){case m:console.log(`${t}:`,...i);break;case y:console.warn(`${t}:`,...i);break;case k:console.error(`${t}:`,...i);break}}}info(...e){this.log(m,...e)}warn(...e){this.log(y,...e)}error(...e){this.log(k,...e)}}var E={};A(E,{scramble:()=>B,alert:()=>D});async function D({secret:e,endpoint:i,version:t}){return await fetch(i,{method:"POST",headers:{"Content-Type":"text/plain;charset=UTF-8",Authorization:`Bearer ${e}`},body:t})}async function B({packageConfig:e,secretsConfig:i,publishedPackages:t}){let o=[];for(let s of t)if(s.name in e){let r=s.name,{endpoint:g}=e[r],a=i[r],d=s.version,f=D({secret:a,endpoint:g,version:d}).then((h)=>[r,h]);o.push(f)}let n=await Promise.all(o);return Object.fromEntries(n)}export{G as isVersionNumber,de as flightDeckLogSchema,E as Klaxon,S as FlightDeckLogger,O as FlightDeck,y as FLIGHTDECK_WARN,ce as FLIGHTDECK_UPDATE_PHASES,le as FLIGHTDECK_SETUP_PHASES,pe as FLIGHTDECK_LNAV_FORMAT,m as FLIGHTDECK_INFO,k as FLIGHTDECK_ERROR};
7
-
8
- //# debugId=F5FF89C57D926E5564756E2164756E21
9
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2ZsaWdodGRlY2subGliLnRzIiwgIi4uL3NyYy9mbGlnaHRkZWNrLmVudi50cyIsICIuLi9zcmMva2xheG9uLmxpYi50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsKICAgICJpbXBvcnQgeyBleGVjU3luYywgc3Bhd24gfSBmcm9tIFwibm9kZTpjaGlsZF9wcm9jZXNzXCJcbmltcG9ydCB0eXBlIHsgU2VydmVyIH0gZnJvbSBcIm5vZGU6aHR0cFwiXG5pbXBvcnQgeyBjcmVhdGVTZXJ2ZXIgfSBmcm9tIFwibm9kZTpodHRwXCJcbmltcG9ydCB7IGhvbWVkaXIgfSBmcm9tIFwibm9kZTpvc1wiXG5pbXBvcnQgeyByZXNvbHZlIH0gZnJvbSBcIm5vZGU6cGF0aFwiXG5pbXBvcnQgeyBpbnNwZWN0IH0gZnJvbSBcIm5vZGU6dXRpbFwiXG5cbmltcG9ydCB7IEZ1dHVyZSB9IGZyb20gXCJhdG9tLmlvL2ludGVybmFsXCJcbmltcG9ydCB7IGRpc2NvdmVyVHlwZSB9IGZyb20gXCJhdG9tLmlvL2ludHJvc3BlY3Rpb25cIlxuaW1wb3J0IHsgZnJvbUVudHJpZXMsIHRvRW50cmllcyB9IGZyb20gXCJhdG9tLmlvL2pzb25cIlxuaW1wb3J0IHsgQ2hpbGRTb2NrZXQgfSBmcm9tIFwiYXRvbS5pby9yZWFsdGltZS1zZXJ2ZXJcIlxuaW1wb3J0IHsgQ3JvbkpvYiB9IGZyb20gXCJjcm9uXCJcbmltcG9ydCB7IEZpbGVzeXN0ZW1TdG9yYWdlIH0gZnJvbSBcInNhZmVkZXBvc2l0XCJcbmltcG9ydCB7IHogfSBmcm9tIFwiem9kXCJcblxuaW1wb3J0IHR5cGUgeyBMbmF2Rm9ybWF0IH0gZnJvbSBcIi4uL2dlbi9sbmF2LWZvcm1hdC1zY2hlbWEuZ2VuXCJcbmltcG9ydCB7IGVudiB9IGZyb20gXCIuL2ZsaWdodGRlY2suZW52XCJcblxuZXhwb3J0IGNvbnN0IEZMSUdIVERFQ0tfU0VUVVBfUEhBU0VTID0gW2Bkb3dubG9hZGVkYCwgYGluc3RhbGxlZGBdIGFzIGNvbnN0XG5cbmV4cG9ydCB0eXBlIEZsaWdodERlY2tTZXR1cFBoYXNlID0gKHR5cGVvZiBGTElHSFRERUNLX1NFVFVQX1BIQVNFUylbbnVtYmVyXVxuXG5leHBvcnQgY29uc3QgRkxJR0hUREVDS19VUERBVEVfUEhBU0VTID0gW2Bub3RpZmllZGAsIGBjb25maXJtZWRgXSBhcyBjb25zdFxuXG5leHBvcnQgdHlwZSBGbGlnaHREZWNrVXBkYXRlUGhhc2UgPSAodHlwZW9mIEZMSUdIVERFQ0tfVVBEQVRFX1BIQVNFUylbbnVtYmVyXVxuXG5leHBvcnQgZnVuY3Rpb24gaXNWZXJzaW9uTnVtYmVyKHZlcnNpb246IHN0cmluZyk6IGJvb2xlYW4ge1xuXHRyZXR1cm4gKFxuXHRcdC9eXFxkK1xcLlxcZCtcXC5cXGQrJC8udGVzdCh2ZXJzaW9uKSB8fCAhTnVtYmVyLmlzTmFOKE51bWJlci5wYXJzZUZsb2F0KHZlcnNpb24pKVxuXHQpXG59XG5cbmV4cG9ydCB0eXBlIEZsaWdodERlY2tPcHRpb25zPFMgZXh0ZW5kcyBzdHJpbmcgPSBzdHJpbmc+ID0ge1xuXHRwYWNrYWdlTmFtZTogc3RyaW5nXG5cdHNlcnZpY2VzOiB7IFtzZXJ2aWNlIGluIFNdOiB7IHJ1bjogc3RyaW5nOyB3YWl0Rm9yOiBib29sZWFuIH0gfVxuXHRzY3JpcHRzOiB7XG5cdFx0ZG93bmxvYWQ6IHN0cmluZ1xuXHRcdGluc3RhbGw6IHN0cmluZ1xuXHRcdGNoZWNrQXZhaWxhYmlsaXR5Pzogc3RyaW5nXG5cdH1cblx0cG9ydD86IG51bWJlciB8IHVuZGVmaW5lZFxuXHRmbGlnaHRkZWNrUm9vdERpcj86IHN0cmluZyB8IHVuZGVmaW5lZFxuXHRqc29uTG9nZ2luZz86IGJvb2xlYW4gfCB1bmRlZmluZWRcbn1cblxuZXhwb3J0IGNsYXNzIEZsaWdodERlY2s8UyBleHRlbmRzIHN0cmluZyA9IHN0cmluZz4ge1xuXHRwcm90ZWN0ZWQgc2FmZXR5ID0gMFxuXG5cdHByb3RlY3RlZCBzdG9yYWdlOiBGaWxlc3lzdGVtU3RvcmFnZTx7XG5cdFx0c2V0dXBQaGFzZTogRmxpZ2h0RGVja1NldHVwUGhhc2Vcblx0XHR1cGRhdGVQaGFzZTogRmxpZ2h0RGVja1VwZGF0ZVBoYXNlXG5cdFx0dXBkYXRlQXdhaXRlZFZlcnNpb246IHN0cmluZ1xuXHR9PlxuXHRwcm90ZWN0ZWQgd2ViaG9va1NlcnZlcjogU2VydmVyXG5cdHByb3RlY3RlZCBzZXJ2aWNlczoge1xuXHRcdFtzZXJ2aWNlIGluIFNdOiBDaGlsZFNvY2tldDxcblx0XHRcdHsgdGltZVRvU3RvcDogW107IHVwZGF0ZXNSZWFkeTogW10gfSxcblx0XHRcdHsgcmVhZHlUb1VwZGF0ZTogW107IGFsaXZlOiBbXSB9XG5cdFx0PiB8IG51bGxcblx0fVxuXHRwcm90ZWN0ZWQgc2VydmljZUlkeDogeyByZWFkb25seSBbc2VydmljZSBpbiBTXTogbnVtYmVyIH1cblx0cHVibGljIGRlZmF1bHRTZXJ2aWNlc1JlYWR5VG9VcGRhdGU6IHsgcmVhZG9ubHkgW3NlcnZpY2UgaW4gU106IGJvb2xlYW4gfVxuXHRwdWJsaWMgc2VydmljZXNSZWFkeVRvVXBkYXRlOiB7IFtzZXJ2aWNlIGluIFNdOiBib29sZWFuIH1cblx0cHVibGljIGF1dG9SZXNwYXduRGVhZFNlcnZpY2VzOiBib29sZWFuXG5cblx0cHJvdGVjdGVkIGxvZ2dlcjogUGljazxDb25zb2xlLCBgZXJyb3JgIHwgYGluZm9gIHwgYHdhcm5gPlxuXHRwcm90ZWN0ZWQgc2VydmljZUxvZ2dlcnM6IHtcblx0XHRyZWFkb25seSBbc2VydmljZSBpbiBTXTogRmxpZ2h0RGVja0xvZ2dlclxuXHR9XG5cblx0cHJvdGVjdGVkIHVwZGF0ZUF2YWlsYWJpbGl0eUNoZWNrZXI6IENyb25Kb2IgfCBudWxsID0gbnVsbFxuXG5cdHB1YmxpYyBzZXJ2aWNlc0xpdmU6IEZ1dHVyZTx2b2lkPltdXG5cdHB1YmxpYyBzZXJ2aWNlc0RlYWQ6IEZ1dHVyZTx2b2lkPltdXG5cdHB1YmxpYyBsaXZlID0gbmV3IEZ1dHVyZSgoKSA9PiB7fSlcblx0cHVibGljIGRlYWQgPSBuZXcgRnV0dXJlKCgpID0+IHt9KVxuXG5cdHByb3RlY3RlZCByZXN0YXJ0VGltZXM6IG51bWJlcltdID0gW11cblxuXHRwdWJsaWMgY29uc3RydWN0b3IocHVibGljIHJlYWRvbmx5IG9wdGlvbnM6IEZsaWdodERlY2tPcHRpb25zPFM+KSB7XG5cdFx0Y29uc3QgeyBGTElHSFRERUNLX1NFQ1JFVCB9ID0gZW52XG5cdFx0Y29uc3QgeyBmbGlnaHRkZWNrUm9vdERpciA9IHJlc29sdmUoaG9tZWRpcigpLCBgLmZsaWdodGRlY2tgKSB9ID0gb3B0aW9uc1xuXHRcdGNvbnN0IHBvcnQgPSBvcHRpb25zLnBvcnQgPz8gODA4MFxuXHRcdGNvbnN0IG9yaWdpbiA9IGBodHRwOi8vbG9jYWxob3N0OiR7cG9ydH1gXG5cblx0XHRjb25zdCBzZXJ2aWNlc0VudHJpZXMgPSB0b0VudHJpZXMob3B0aW9ucy5zZXJ2aWNlcylcblx0XHR0aGlzLnNlcnZpY2VzID0gZnJvbUVudHJpZXMoXG5cdFx0XHRzZXJ2aWNlc0VudHJpZXMubWFwKChbc2VydmljZU5hbWVdKSA9PiBbc2VydmljZU5hbWUsIG51bGxdKSxcblx0XHQpXG5cdFx0dGhpcy5zZXJ2aWNlSWR4ID0gZnJvbUVudHJpZXMoXG5cdFx0XHRzZXJ2aWNlc0VudHJpZXMubWFwKChbc2VydmljZU5hbWVdLCBpZHgpID0+IFtzZXJ2aWNlTmFtZSwgaWR4XSksXG5cdFx0KVxuXHRcdHRoaXMuZGVmYXVsdFNlcnZpY2VzUmVhZHlUb1VwZGF0ZSA9IGZyb21FbnRyaWVzKFxuXHRcdFx0c2VydmljZXNFbnRyaWVzLm1hcCgoW3NlcnZpY2VOYW1lLCB7IHdhaXRGb3IgfV0pID0+IFtcblx0XHRcdFx0c2VydmljZU5hbWUsXG5cdFx0XHRcdCF3YWl0Rm9yLFxuXHRcdFx0XSksXG5cdFx0KVxuXHRcdHRoaXMuc2VydmljZXNSZWFkeVRvVXBkYXRlID0geyAuLi50aGlzLmRlZmF1bHRTZXJ2aWNlc1JlYWR5VG9VcGRhdGUgfVxuXHRcdHRoaXMuYXV0b1Jlc3Bhd25EZWFkU2VydmljZXMgPSB0cnVlXG5cblx0XHR0aGlzLmxvZ2dlciA9IG5ldyBGbGlnaHREZWNrTG9nZ2VyKFxuXHRcdFx0dGhpcy5vcHRpb25zLnBhY2thZ2VOYW1lLFxuXHRcdFx0cHJvY2Vzcy5waWQsXG5cdFx0XHR1bmRlZmluZWQsXG5cdFx0XHR7IGpzb25Mb2dnaW5nOiB0aGlzLm9wdGlvbnMuanNvbkxvZ2dpbmcgPz8gZmFsc2UgfSxcblx0XHQpXG5cdFx0dGhpcy5zZXJ2aWNlTG9nZ2VycyA9IGZyb21FbnRyaWVzKFxuXHRcdFx0c2VydmljZXNFbnRyaWVzLm1hcCgoW3NlcnZpY2VOYW1lXSkgPT4gW1xuXHRcdFx0XHRzZXJ2aWNlTmFtZSxcblx0XHRcdFx0bmV3IEZsaWdodERlY2tMb2dnZXIoXG5cdFx0XHRcdFx0dGhpcy5vcHRpb25zLnBhY2thZ2VOYW1lLFxuXHRcdFx0XHRcdHByb2Nlc3MucGlkLFxuXHRcdFx0XHRcdHNlcnZpY2VOYW1lLFxuXHRcdFx0XHRcdHsganNvbkxvZ2dpbmc6IHRoaXMub3B0aW9ucy5qc29uTG9nZ2luZyA/PyBmYWxzZSB9LFxuXHRcdFx0XHQpLFxuXHRcdFx0XSksXG5cdFx0KVxuXG5cdFx0dGhpcy5zZXJ2aWNlc0xpdmUgPSBzZXJ2aWNlc0VudHJpZXMubWFwKCgpID0+IG5ldyBGdXR1cmUoKCkgPT4ge30pKVxuXHRcdHRoaXMuc2VydmljZXNEZWFkID0gc2VydmljZXNFbnRyaWVzLm1hcCgoKSA9PiBuZXcgRnV0dXJlKCgpID0+IHt9KSlcblx0XHR0aGlzLmxpdmUudXNlKFByb21pc2UuYWxsKHRoaXMuc2VydmljZXNMaXZlKSlcblx0XHR0aGlzLmRlYWQudXNlKFByb21pc2UuYWxsKHRoaXMuc2VydmljZXNEZWFkKSlcblxuXHRcdHRoaXMuc3RvcmFnZSA9IG5ldyBGaWxlc3lzdGVtU3RvcmFnZSh7XG5cdFx0XHRwYXRoOiByZXNvbHZlKGZsaWdodGRlY2tSb290RGlyLCBgc3RvcmFnZWAsIG9wdGlvbnMucGFja2FnZU5hbWUpLFxuXHRcdH0pXG5cblx0XHRpZiAoRkxJR0hUREVDS19TRUNSRVQgPT09IHVuZGVmaW5lZCkge1xuXHRcdFx0dGhpcy5sb2dnZXIud2Fybihcblx0XHRcdFx0YE5vIEZMSUdIVERFQ0tfU0VDUkVUIGVudmlyb25tZW50IHZhcmlhYmxlIGZvdW5kLiBGbGlnaHREZWNrIHdpbGwgbm90IHJ1biBhbiB1cGRhdGUgc2VydmVyLmAsXG5cdFx0XHQpXG5cdFx0fSBlbHNlIHtcblx0XHRcdGNyZWF0ZVNlcnZlcigocmVxLCByZXMpID0+IHtcblx0XHRcdFx0bGV0IGRhdGE6IFVpbnQ4QXJyYXlbXSA9IFtdXG5cdFx0XHRcdHJlcVxuXHRcdFx0XHRcdC5vbihgZGF0YWAsIChjaHVuaykgPT4ge1xuXHRcdFx0XHRcdFx0ZGF0YS5wdXNoKGNodW5rIGluc3RhbmNlb2YgQnVmZmVyID8gY2h1bmsgOiBCdWZmZXIuZnJvbShjaHVuaykpXG5cdFx0XHRcdFx0fSlcblx0XHRcdFx0XHQub24oYGVuZGAsICgpID0+IHtcblx0XHRcdFx0XHRcdGNvbnN0IGF1dGhIZWFkZXIgPSByZXEuaGVhZGVycy5hdXRob3JpemF0aW9uXG5cdFx0XHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdFx0XHRpZiAodHlwZW9mIHJlcS51cmwgPT09IGB1bmRlZmluZWRgKSB0aHJvdyA0MDBcblx0XHRcdFx0XHRcdFx0Y29uc3QgZXhwZWN0ZWRBdXRoSGVhZGVyID0gYEJlYXJlciAke0ZMSUdIVERFQ0tfU0VDUkVUfWBcblx0XHRcdFx0XHRcdFx0aWYgKGF1dGhIZWFkZXIgIT09IGBCZWFyZXIgJHtGTElHSFRERUNLX1NFQ1JFVH1gKSB7XG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhcblx0XHRcdFx0XHRcdFx0XHRcdGBVbmF1dGhvcml6ZWQ6IG5lZWRlZCBcXGAke2V4cGVjdGVkQXV0aEhlYWRlcn1cXGAsIGdvdCBcXGAke2F1dGhIZWFkZXJ9XFxgYCxcblx0XHRcdFx0XHRcdFx0XHQpXG5cdFx0XHRcdFx0XHRcdFx0dGhyb3cgNDAxXG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0Y29uc3QgdXJsID0gbmV3IFVSTChyZXEudXJsLCBvcmlnaW4pXG5cdFx0XHRcdFx0XHRcdHRoaXMubG9nZ2VyLmluZm8ocmVxLm1ldGhvZCwgdXJsLnBhdGhuYW1lKVxuXG5cdFx0XHRcdFx0XHRcdGNvbnN0IHZlcnNpb25Gb3JlaWduSW5wdXQgPSBCdWZmZXIuY29uY2F0KGRhdGEpLnRvU3RyaW5nKClcblx0XHRcdFx0XHRcdFx0aWYgKCFpc1ZlcnNpb25OdW1iZXIodmVyc2lvbkZvcmVpZ25JbnB1dCkpIHtcblx0XHRcdFx0XHRcdFx0XHR0aHJvdyA0MDBcblx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdHJlcy53cml0ZUhlYWQoMjAwKVxuXHRcdFx0XHRcdFx0XHRyZXMuZW5kKClcblxuXHRcdFx0XHRcdFx0XHR0aGlzLnN0b3JhZ2Uuc2V0SXRlbShgdXBkYXRlUGhhc2VgLCBgbm90aWZpZWRgKVxuXHRcdFx0XHRcdFx0XHR0aGlzLnN0b3JhZ2Uuc2V0SXRlbShgdXBkYXRlQXdhaXRlZFZlcnNpb25gLCB2ZXJzaW9uRm9yZWlnbklucHV0KVxuXHRcdFx0XHRcdFx0XHRjb25zdCB7IGNoZWNrQXZhaWxhYmlsaXR5IH0gPSBvcHRpb25zLnNjcmlwdHNcblx0XHRcdFx0XHRcdFx0aWYgKGNoZWNrQXZhaWxhYmlsaXR5KSB7XG5cdFx0XHRcdFx0XHRcdFx0dGhpcy51cGRhdGVBdmFpbGFiaWxpdHlDaGVja2VyPy5zdG9wKClcblx0XHRcdFx0XHRcdFx0XHR0aGlzLnNlZWtVcGRhdGUodmVyc2lvbkZvcmVpZ25JbnB1dClcblx0XHRcdFx0XHRcdFx0XHRjb25zdCB1cGRhdGVQaGFzZSA9IHRoaXMuc3RvcmFnZS5nZXRJdGVtKGB1cGRhdGVQaGFzZWApXG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhgPiBzdG9yYWdlKFwidXBkYXRlUGhhc2VcIikgPmAsIHVwZGF0ZVBoYXNlKVxuXHRcdFx0XHRcdFx0XHRcdGlmICh1cGRhdGVQaGFzZSA9PT0gYG5vdGlmaWVkYCkge1xuXHRcdFx0XHRcdFx0XHRcdFx0dGhpcy51cGRhdGVBdmFpbGFiaWxpdHlDaGVja2VyID0gbmV3IENyb25Kb2IoXG5cdFx0XHRcdFx0XHRcdFx0XHRcdGAzMCAqICogKiAqICpgLFxuXHRcdFx0XHRcdFx0XHRcdFx0XHQoKSA9PiB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0dGhpcy5zZWVrVXBkYXRlKHZlcnNpb25Gb3JlaWduSW5wdXQpXG5cdFx0XHRcdFx0XHRcdFx0XHRcdH0sXG5cdFx0XHRcdFx0XHRcdFx0XHQpXG5cdFx0XHRcdFx0XHRcdFx0XHR0aGlzLnVwZGF0ZUF2YWlsYWJpbGl0eUNoZWNrZXIuc3RhcnQoKVxuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHR0aGlzLmRvd25sb2FkUGFja2FnZSgpXG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH0gY2F0Y2ggKHRocm93bikge1xuXHRcdFx0XHRcdFx0XHR0aGlzLmxvZ2dlci5lcnJvcih0aHJvd24sIHJlcS51cmwpXG5cdFx0XHRcdFx0XHRcdGlmICh0eXBlb2YgdGhyb3duID09PSBgbnVtYmVyYCkge1xuXHRcdFx0XHRcdFx0XHRcdHJlcy53cml0ZUhlYWQodGhyb3duKVxuXHRcdFx0XHRcdFx0XHRcdHJlcy5lbmQoKVxuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9IGZpbmFsbHkge1xuXHRcdFx0XHRcdFx0XHRkYXRhID0gW11cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9KVxuXHRcdFx0fSkubGlzdGVuKHBvcnQsICgpID0+IHtcblx0XHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhgU2VydmVyIHN0YXJ0ZWQgb24gcG9ydCAke3BvcnR9YClcblx0XHRcdH0pXG5cdFx0fVxuXG5cdFx0dGhpcy5zdGFydEFsbFNlcnZpY2VzKClcblx0XHRcdC50aGVuKCgpID0+IHtcblx0XHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhgQWxsIHNlcnZpY2VzIHN0YXJ0ZWQuYClcblx0XHRcdH0pXG5cdFx0XHQuY2F0Y2goKHRocm93bikgPT4ge1xuXHRcdFx0XHRpZiAodGhyb3duIGluc3RhbmNlb2YgRXJyb3IpIHtcblx0XHRcdFx0XHR0aGlzLmxvZ2dlci5lcnJvcihgRmFpbGVkIHRvIHN0YXJ0IGFsbCBzZXJ2aWNlczpgLCB0aHJvd24ubWVzc2FnZSlcblx0XHRcdFx0fVxuXHRcdFx0fSlcblx0fVxuXG5cdHByb3RlY3RlZCBzZWVrVXBkYXRlKHZlcnNpb246IHN0cmluZyk6IHZvaWQge1xuXHRcdHRoaXMubG9nZ2VyLmluZm8oYENoZWNraW5nIGZvciB1cGRhdGVzLi4uYClcblx0XHRjb25zdCB7IGNoZWNrQXZhaWxhYmlsaXR5IH0gPSB0aGlzLm9wdGlvbnMuc2NyaXB0c1xuXHRcdGlmICghY2hlY2tBdmFpbGFiaWxpdHkpIHtcblx0XHRcdHRoaXMubG9nZ2VyLmluZm8oYE5vIGNoZWNrQXZhaWxhYmlsaXR5IHNjcmlwdCBmb3VuZC5gKVxuXHRcdFx0cmV0dXJuXG5cdFx0fVxuXHRcdHRyeSB7XG5cdFx0XHRjb25zdCBvdXQgPSBleGVjU3luYyhgJHtjaGVja0F2YWlsYWJpbGl0eX0gJHt2ZXJzaW9ufWApXG5cdFx0XHR0aGlzLmxvZ2dlci5pbmZvKGBDaGVjayBzdGRvdXQ6YCwgb3V0LnRvU3RyaW5nKCkpXG5cdFx0XHR0aGlzLnVwZGF0ZUF2YWlsYWJpbGl0eUNoZWNrZXI/LnN0b3AoKVxuXHRcdFx0dGhpcy5zdG9yYWdlLnNldEl0ZW0oYHVwZGF0ZVBoYXNlYCwgYGNvbmZpcm1lZGApXG5cdFx0XHR0aGlzLmRvd25sb2FkUGFja2FnZSgpXG5cdFx0XHR0aGlzLmFubm91bmNlVXBkYXRlKClcblx0XHR9IGNhdGNoICh0aHJvd24pIHtcblx0XHRcdGlmICh0aHJvd24gaW5zdGFuY2VvZiBFcnJvcikge1xuXHRcdFx0XHR0aGlzLmxvZ2dlci5lcnJvcihgQ2hlY2sgZmFpbGVkOmAsIHRocm93bi5tZXNzYWdlKVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Y29uc3QgdGhyb3duVHlwZSA9IGRpc2NvdmVyVHlwZSh0aHJvd24pXG5cdFx0XHRcdHRoaXMubG9nZ2VyLmVycm9yKGBDaGVjayB0aHJld2AsIHRocm93blR5cGUsIHRocm93bilcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRwcm90ZWN0ZWQgYW5ub3VuY2VVcGRhdGUoKTogdm9pZCB7XG5cdFx0Zm9yIChjb25zdCBlbnRyeSBvZiB0b0VudHJpZXModGhpcy5zZXJ2aWNlcykpIHtcblx0XHRcdGNvbnN0IFtzZXJ2aWNlTmFtZSwgc2VydmljZV0gPSBlbnRyeVxuXHRcdFx0aWYgKHNlcnZpY2UpIHtcblx0XHRcdFx0aWYgKHRoaXMub3B0aW9ucy5zZXJ2aWNlc1tzZXJ2aWNlTmFtZV0ud2FpdEZvcikge1xuXHRcdFx0XHRcdHNlcnZpY2UuZW1pdChgdXBkYXRlc1JlYWR5YClcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dGhpcy5zdGFydFNlcnZpY2Uoc2VydmljZU5hbWUpXG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0cHJvdGVjdGVkIHRyeVVwZGF0ZSgpOiB2b2lkIHtcblx0XHRpZiAodG9FbnRyaWVzKHRoaXMuc2VydmljZXNSZWFkeVRvVXBkYXRlKS5ldmVyeSgoWywgaXNSZWFkeV0pID0+IGlzUmVhZHkpKSB7XG5cdFx0XHR0aGlzLmxvZ2dlci5pbmZvKGBBbGwgc2VydmljZXMgYXJlIHJlYWR5IHRvIHVwZGF0ZS5gKVxuXHRcdFx0dGhpcy5zdG9wQWxsU2VydmljZXMoKVxuXHRcdFx0XHQudGhlbigoKSA9PiB7XG5cdFx0XHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhgQWxsIHNlcnZpY2VzIHN0b3BwZWQ7IHN0YXJ0aW5nIHVwIGZyZXNoLi4uYClcblx0XHRcdFx0XHR0aGlzLnN0YXJ0QWxsU2VydmljZXMoKVxuXHRcdFx0XHRcdFx0LnRoZW4oKCkgPT4ge1xuXHRcdFx0XHRcdFx0XHR0aGlzLmxvZ2dlci5pbmZvKGBBbGwgc2VydmljZXMgc3RhcnRlZDsgd2UncmUgYmFjayBvbmxpbmUuYClcblx0XHRcdFx0XHRcdH0pXG5cdFx0XHRcdFx0XHQuY2F0Y2goKHRocm93bikgPT4ge1xuXHRcdFx0XHRcdFx0XHRpZiAodGhyb3duIGluc3RhbmNlb2YgRXJyb3IpIHtcblx0XHRcdFx0XHRcdFx0XHR0aGlzLmxvZ2dlci5lcnJvcihcblx0XHRcdFx0XHRcdFx0XHRcdGBGYWlsZWQgdG8gc3RhcnQgYWxsIHNlcnZpY2VzOmAsXG5cdFx0XHRcdFx0XHRcdFx0XHR0aHJvd24ubWVzc2FnZSxcblx0XHRcdFx0XHRcdFx0XHQpXG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH0pXG5cdFx0XHRcdH0pXG5cdFx0XHRcdC5jYXRjaCgodGhyb3duKSA9PiB7XG5cdFx0XHRcdFx0aWYgKHRocm93biBpbnN0YW5jZW9mIEVycm9yKSB7XG5cdFx0XHRcdFx0XHR0aGlzLmxvZ2dlci5lcnJvcihgRmFpbGVkIHRvIHN0b3AgYWxsIHNlcnZpY2VzOmAsIHRocm93bi5tZXNzYWdlKVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSlcblx0XHR9XG5cdH1cblxuXHRwcm90ZWN0ZWQgc3RhcnRBbGxTZXJ2aWNlcygpOiBGdXR1cmU8dW5rbm93bj4ge1xuXHRcdHRoaXMubG9nZ2VyLmluZm8oYFN0YXJ0aW5nIGFsbCBzZXJ2aWNlcy4uLmApXG5cdFx0dGhpcy5hdXRvUmVzcGF3bkRlYWRTZXJ2aWNlcyA9IHRydWVcblx0XHRjb25zdCBzZXR1cFBoYXNlID0gdGhpcy5zdG9yYWdlLmdldEl0ZW0oYHNldHVwUGhhc2VgKVxuXHRcdHRoaXMubG9nZ2VyLmluZm8oYD4gc3RvcmFnZShcInNldHVwUGhhc2VcIikgPmAsIHNldHVwUGhhc2UpXG5cdFx0c3dpdGNoIChzZXR1cFBoYXNlKSB7XG5cdFx0XHRjYXNlIG51bGw6XG5cdFx0XHRcdHRoaXMubG9nZ2VyLmluZm8oYFN0YXJ0aW5nIGZyb20gc2NyYXRjaC5gKVxuXHRcdFx0XHR0aGlzLmRvd25sb2FkUGFja2FnZSgpXG5cdFx0XHRcdHRoaXMuaW5zdGFsbFBhY2thZ2UoKVxuXHRcdFx0XHRyZXR1cm4gdGhpcy5zdGFydEFsbFNlcnZpY2VzKClcblx0XHRcdGNhc2UgYGRvd25sb2FkZWRgOlxuXHRcdFx0XHR0aGlzLmxvZ2dlci5pbmZvKGBGb3VuZCBwYWNrYWdlIGRvd25sb2FkZWQgYnV0IG5vdCBpbnN0YWxsZWQuYClcblx0XHRcdFx0dGhpcy5pbnN0YWxsUGFja2FnZSgpXG5cdFx0XHRcdHJldHVybiB0aGlzLnN0YXJ0QWxsU2VydmljZXMoKVxuXHRcdFx0Y2FzZSBgaW5zdGFsbGVkYDoge1xuXHRcdFx0XHRmb3IgKGNvbnN0IFtzZXJ2aWNlTmFtZV0gb2YgdG9FbnRyaWVzKHRoaXMuc2VydmljZXMpKSB7XG5cdFx0XHRcdFx0dGhpcy5zdGFydFNlcnZpY2Uoc2VydmljZU5hbWUpXG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHRoaXMubGl2ZVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHByb3RlY3RlZCBzdGFydFNlcnZpY2Uoc2VydmljZU5hbWU6IFMpOiB2b2lkIHtcblx0XHR0aGlzLmxvZ2dlci5pbmZvKFxuXHRcdFx0YFN0YXJ0aW5nIHNlcnZpY2UgJHt0aGlzLm9wdGlvbnMucGFja2FnZU5hbWV9Ojoke3NlcnZpY2VOYW1lfSwgdHJ5ICR7dGhpcy5zYWZldHl9LzIuLi5gLFxuXHRcdClcblx0XHRpZiAodGhpcy5zYWZldHkgPj0gMikge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKGBPdXQgb2YgdHJpZXMuLi5gKVxuXHRcdH1cblx0XHR0aGlzLnNhZmV0eSsrXG5cblx0XHRjb25zdCBbZXhlLCAuLi5hcmdzXSA9IHRoaXMub3B0aW9ucy5zZXJ2aWNlc1tzZXJ2aWNlTmFtZV0ucnVuLnNwbGl0KGAgYClcblx0XHRjb25zdCBzZXJ2aWNlUHJvY2VzcyA9IHNwYXduKGV4ZSwgYXJncywge1xuXHRcdFx0Y3dkOiB0aGlzLm9wdGlvbnMuZmxpZ2h0ZGVja1Jvb3REaXIsXG5cdFx0XHRlbnY6IGltcG9ydC5tZXRhLmVudixcblx0XHR9KVxuXHRcdGNvbnN0IHNlcnZpY2VMb2dnZXIgPSB0aGlzLnNlcnZpY2VMb2dnZXJzW3NlcnZpY2VOYW1lXVxuXHRcdGNvbnN0IHNlcnZpY2UgPSAodGhpcy5zZXJ2aWNlc1tzZXJ2aWNlTmFtZV0gPSBuZXcgQ2hpbGRTb2NrZXQoXG5cdFx0XHRzZXJ2aWNlUHJvY2Vzcyxcblx0XHRcdGAke3RoaXMub3B0aW9ucy5wYWNrYWdlTmFtZX06OiR7c2VydmljZU5hbWV9YCxcblx0XHRcdHNlcnZpY2VMb2dnZXIsXG5cdFx0KSlcblx0XHRzZXJ2aWNlTG9nZ2VyLnByb2Nlc3NDb2RlID0gc2VydmljZS5wcm9jZXNzLnBpZCA/PyAtMVxuXHRcdHRoaXMuc2VydmljZXNbc2VydmljZU5hbWVdLm9uQW55KCguLi5tZXNzYWdlcykgPT4ge1xuXHRcdFx0c2VydmljZUxvZ2dlci5pbmZvKGDwn5KsYCwgLi4ubWVzc2FnZXMpXG5cdFx0fSlcblx0XHR0aGlzLnNlcnZpY2VzW3NlcnZpY2VOYW1lXS5vbihgcmVhZHlUb1VwZGF0ZWAsICgpID0+IHtcblx0XHRcdHRoaXMubG9nZ2VyLmluZm8oYFNlcnZpY2UgXCIke3NlcnZpY2VOYW1lfVwiIGlzIHJlYWR5IHRvIHVwZGF0ZS5gKVxuXHRcdFx0dGhpcy5zZXJ2aWNlc1JlYWR5VG9VcGRhdGVbc2VydmljZU5hbWVdID0gdHJ1ZVxuXHRcdFx0dGhpcy50cnlVcGRhdGUoKVxuXHRcdH0pXG5cdFx0dGhpcy5zZXJ2aWNlc1tzZXJ2aWNlTmFtZV0ub24oYGFsaXZlYCwgKCkgPT4ge1xuXHRcdFx0dGhpcy5zZXJ2aWNlc0xpdmVbdGhpcy5zZXJ2aWNlSWR4W3NlcnZpY2VOYW1lXV0udXNlKFByb21pc2UucmVzb2x2ZSgpKVxuXHRcdFx0dGhpcy5zZXJ2aWNlc0RlYWRbdGhpcy5zZXJ2aWNlSWR4W3NlcnZpY2VOYW1lXV0gPSBuZXcgRnV0dXJlKCgpID0+IHt9KVxuXHRcdFx0aWYgKHRoaXMuZGVhZC5kb25lKSB7XG5cdFx0XHRcdHRoaXMuZGVhZCA9IG5ldyBGdXR1cmUoKCkgPT4ge30pXG5cdFx0XHR9XG5cdFx0XHR0aGlzLmRlYWQudXNlKFByb21pc2UuYWxsKHRoaXMuc2VydmljZXNEZWFkKSlcblx0XHR9KVxuXHRcdHRoaXMuc2VydmljZXNbc2VydmljZU5hbWVdLnByb2Nlc3Mub25jZShgY2xvc2VgLCAoZXhpdENvZGUpID0+IHtcblx0XHRcdHRoaXMubG9nZ2VyLmluZm8oXG5cdFx0XHRcdGBBdXRvLXJlc3Bhd24gc2F3IFwiJHtzZXJ2aWNlTmFtZX1cIiBleGl0IHdpdGggY29kZSAke2V4aXRDb2RlfWAsXG5cdFx0XHQpXG5cdFx0XHR0aGlzLnNlcnZpY2VzW3NlcnZpY2VOYW1lXSA9IG51bGxcblx0XHRcdGlmICghdGhpcy5hdXRvUmVzcGF3bkRlYWRTZXJ2aWNlcykge1xuXHRcdFx0XHR0aGlzLmxvZ2dlci5pbmZvKGBBdXRvLXJlc3Bhd24gaXMgb2ZmOyBcIiR7c2VydmljZU5hbWV9XCIgcmVzdHMuYClcblx0XHRcdFx0cmV0dXJuXG5cdFx0XHR9XG5cdFx0XHRjb25zdCB1cGRhdGVQaGFzZSA9IHRoaXMuc3RvcmFnZS5nZXRJdGVtKGB1cGRhdGVQaGFzZWApXG5cdFx0XHR0aGlzLmxvZ2dlci5pbmZvKGA+IHN0b3JhZ2UoXCJ1cGRhdGVQaGFzZVwiKSA+YCwgdXBkYXRlUGhhc2UpXG5cdFx0XHRjb25zdCB1cGRhdGVzQXJlUmVhZHkgPSB1cGRhdGVQaGFzZSA9PT0gYGNvbmZpcm1lZGBcblx0XHRcdGlmICh1cGRhdGVzQXJlUmVhZHkpIHtcblx0XHRcdFx0dGhpcy5zZXJ2aWNlTG9nZ2Vyc1tzZXJ2aWNlTmFtZV0uaW5mbyhgVXBkYXRpbmcgYmVmb3JlIHN0YXJ0dXAuLi5gKVxuXHRcdFx0XHR0aGlzLnJlc3RhcnRUaW1lcyA9IFtdXG5cdFx0XHRcdHRoaXMuaW5zdGFsbFBhY2thZ2UoKVxuXHRcdFx0XHR0aGlzLnN0YXJ0U2VydmljZShzZXJ2aWNlTmFtZSlcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGNvbnN0IG5vdyA9IERhdGUubm93KClcblx0XHRcdFx0Y29uc3QgZml2ZU1pbnV0ZXNBZ28gPSBub3cgLSA1ICogNjAgKiAxMDAwXG5cdFx0XHRcdHRoaXMucmVzdGFydFRpbWVzID0gdGhpcy5yZXN0YXJ0VGltZXMuZmlsdGVyKFxuXHRcdFx0XHRcdCh0aW1lKSA9PiB0aW1lID4gZml2ZU1pbnV0ZXNBZ28sXG5cdFx0XHRcdClcblx0XHRcdFx0dGhpcy5yZXN0YXJ0VGltZXMucHVzaChub3cpXG5cblx0XHRcdFx0aWYgKHRoaXMucmVzdGFydFRpbWVzLmxlbmd0aCA8IDUpIHtcblx0XHRcdFx0XHR0aGlzLnNlcnZpY2VMb2dnZXJzW3NlcnZpY2VOYW1lXS5pbmZvKGBDcmFzaGVkLiBSZXN0YXJ0aW5nLi4uYClcblx0XHRcdFx0XHR0aGlzLnN0YXJ0U2VydmljZShzZXJ2aWNlTmFtZSlcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHR0aGlzLnNlcnZpY2VMb2dnZXJzW3NlcnZpY2VOYW1lXS5pbmZvKFxuXHRcdFx0XHRcdFx0YENyYXNoZWQgNSB0aW1lcyBpbiA1IG1pbnV0ZXMuIE5vdCByZXN0YXJ0aW5nLmAsXG5cdFx0XHRcdFx0KVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSlcblx0XHR0aGlzLnNhZmV0eSA9IDBcblx0fVxuXG5cdHByb3RlY3RlZCBkb3dubG9hZFBhY2thZ2UoKTogdm9pZCB7XG5cdFx0dGhpcy5sb2dnZXIuaW5mbyhgRG93bmxvYWRpbmcuLi5gKVxuXHRcdHRyeSB7XG5cdFx0XHRjb25zdCBvdXQgPSBleGVjU3luYyh0aGlzLm9wdGlvbnMuc2NyaXB0cy5kb3dubG9hZClcblx0XHRcdHRoaXMubG9nZ2VyLmluZm8oYERvd25sb2FkIHN0ZG91dDpgLCBvdXQudG9TdHJpbmcoKSlcblx0XHRcdHRoaXMuc3RvcmFnZS5zZXRJdGVtKGBzZXR1cFBoYXNlYCwgYGRvd25sb2FkZWRgKVxuXHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhgRG93bmxvYWRlZCFgKVxuXHRcdH0gY2F0Y2ggKHRocm93bikge1xuXHRcdFx0aWYgKHRocm93biBpbnN0YW5jZW9mIEVycm9yKSB7XG5cdFx0XHRcdHRoaXMubG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gZ2V0IHRoZSBsYXRlc3QgcmVsZWFzZTogJHt0aHJvd24ubWVzc2FnZX1gKVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuXG5cdFx0fVxuXHR9XG5cblx0cHJvdGVjdGVkIGluc3RhbGxQYWNrYWdlKCk6IHZvaWQge1xuXHRcdHRoaXMubG9nZ2VyLmluZm8oYEluc3RhbGxpbmcuLi5gKVxuXG5cdFx0dHJ5IHtcblx0XHRcdGNvbnN0IG91dCA9IGV4ZWNTeW5jKHRoaXMub3B0aW9ucy5zY3JpcHRzLmluc3RhbGwpXG5cdFx0XHR0aGlzLmxvZ2dlci5pbmZvKGBJbnN0YWxsIHN0ZG91dDpgLCBvdXQudG9TdHJpbmcoKSlcblx0XHRcdHRoaXMuc3RvcmFnZS5zZXRJdGVtKGBzZXR1cFBoYXNlYCwgYGluc3RhbGxlZGApXG5cdFx0XHR0aGlzLmxvZ2dlci5pbmZvKGBJbnN0YWxsZWQhYClcblx0XHR9IGNhdGNoICh0aHJvd24pIHtcblx0XHRcdGlmICh0aHJvd24gaW5zdGFuY2VvZiBFcnJvcikge1xuXHRcdFx0XHR0aGlzLmxvZ2dlci5lcnJvcihgRmFpbGVkIHRvIGdldCB0aGUgbGF0ZXN0IHJlbGVhc2U6ICR7dGhyb3duLm1lc3NhZ2V9YClcblx0XHRcdH1cblx0XHRcdHJldHVyblxuXHRcdH1cblx0fVxuXG5cdHB1YmxpYyBzdG9wQWxsU2VydmljZXMoKTogRnV0dXJlPHVua25vd24+IHtcblx0XHR0aGlzLmxvZ2dlci5pbmZvKGBTdG9wcGluZyBhbGwgc2VydmljZXMuLi4gYXV0by1yZXNwYXduIGRpc2FibGVkLmApXG5cdFx0dGhpcy5hdXRvUmVzcGF3bkRlYWRTZXJ2aWNlcyA9IGZhbHNlXG5cdFx0Zm9yIChjb25zdCBbc2VydmljZU5hbWVdIG9mIHRvRW50cmllcyh0aGlzLnNlcnZpY2VzKSkge1xuXHRcdFx0dGhpcy5zdG9wU2VydmljZShzZXJ2aWNlTmFtZSlcblx0XHR9XG5cdFx0cmV0dXJuIHRoaXMuZGVhZFxuXHR9XG5cblx0cHVibGljIHN0b3BTZXJ2aWNlKHNlcnZpY2VOYW1lOiBTKTogdm9pZCB7XG5cdFx0Y29uc3Qgc2VydmljZSA9IHRoaXMuc2VydmljZXNbc2VydmljZU5hbWVdXG5cdFx0aWYgKHNlcnZpY2UpIHtcblx0XHRcdHRoaXMubG9nZ2VyLmluZm8oYFN0b3BwaW5nIHNlcnZpY2UgXCIke3NlcnZpY2VOYW1lfVwiLi4uYClcblx0XHRcdHRoaXMuc2VydmljZXNEZWFkW3RoaXMuc2VydmljZUlkeFtzZXJ2aWNlTmFtZV1dLnVzZShcblx0XHRcdFx0bmV3IFByb21pc2UoKHBhc3MpID0+IHtcblx0XHRcdFx0XHRzZXJ2aWNlLmVtaXQoYHRpbWVUb1N0b3BgKVxuXHRcdFx0XHRcdHNlcnZpY2UucHJvY2Vzcy5vbmNlKGBjbG9zZWAsIChleGl0Q29kZSkgPT4ge1xuXHRcdFx0XHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhcblx0XHRcdFx0XHRcdFx0YFN0b3BwZWQgc2VydmljZSBcIiR7c2VydmljZU5hbWV9XCI7IGV4aXRlZCB3aXRoIGNvZGUgJHtleGl0Q29kZX1gLFxuXHRcdFx0XHRcdFx0KVxuXHRcdFx0XHRcdFx0dGhpcy5zZXJ2aWNlc1tzZXJ2aWNlTmFtZV0gPSBudWxsXG5cdFx0XHRcdFx0XHRwYXNzKClcblx0XHRcdFx0XHR9KVxuXHRcdFx0XHR9KSxcblx0XHRcdClcblx0XHRcdHRoaXMuZGVhZC51c2UoUHJvbWlzZS5hbGwodGhpcy5zZXJ2aWNlc0RlYWQpKVxuXHRcdFx0dGhpcy5zZXJ2aWNlc0xpdmVbdGhpcy5zZXJ2aWNlSWR4W3NlcnZpY2VOYW1lXV0gPSBuZXcgRnV0dXJlKCgpID0+IHt9KVxuXHRcdFx0aWYgKHRoaXMubGl2ZS5kb25lKSB7XG5cdFx0XHRcdHRoaXMubGl2ZSA9IG5ldyBGdXR1cmUoKCkgPT4ge30pXG5cdFx0XHR9XG5cdFx0XHR0aGlzLmxpdmUudXNlKFByb21pc2UuYWxsKHRoaXMuc2VydmljZXNMaXZlKSlcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhpcy5zZXJ2aWNlTG9nZ2Vyc1tzZXJ2aWNlTmFtZV0uZXJyb3IoXG5cdFx0XHRcdGBUcmllZCB0byBzdG9wIHNlcnZpY2UsIGJ1dCBpdCB3YXNuJ3QgcnVubmluZy5gLFxuXHRcdFx0KVxuXHRcdH1cblx0fVxufVxuXG5leHBvcnQgY29uc3QgRkxJR0hUREVDS19JTkZPID0gYGluZm9gXG5leHBvcnQgY29uc3QgRkxJR0hUREVDS19XQVJOID0gYHdhcm5gXG5leHBvcnQgY29uc3QgRkxJR0hUREVDS19FUlJPUiA9IGBFUlIhYFxuXG5leHBvcnQgY29uc3QgZmxpZ2h0RGVja0xvZ1NjaGVtYSA9IHoub2JqZWN0KHtcblx0bGV2ZWw6IHoudW5pb24oW1xuXHRcdHoubGl0ZXJhbChGTElHSFRERUNLX0lORk8pLFxuXHRcdHoubGl0ZXJhbChGTElHSFRERUNLX1dBUk4pLFxuXHRcdHoubGl0ZXJhbChGTElHSFRERUNLX0VSUk9SKSxcblx0XSksXG5cdHRpbWVzdGFtcDogei5udW1iZXIoKSxcblx0cGFja2FnZTogei5zdHJpbmcoKSxcblx0c2VydmljZTogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuXHRwcm9jZXNzOiB6Lm51bWJlcigpLFxuXHRib2R5OiB6LnN0cmluZygpLFxufSlcbmV4cG9ydCB0eXBlIEZsaWdodERlY2tMb2cgPSB6LmluZmVyPHR5cGVvZiBmbGlnaHREZWNrTG9nU2NoZW1hPlxuXG5jb25zdCBMSU5FX0ZPUk1BVCA9IGBsaW5lLWZvcm1hdGAgc2F0aXNmaWVzIGtleW9mIExuYXZGb3JtYXRcbmNvbnN0IFZBTFVFID0gYHZhbHVlYCBzYXRpc2ZpZXMga2V5b2YgTG5hdkZvcm1hdFxuXG5leHBvcnQgdHlwZSBMbmF2Rm9ybWF0VmlzdWFsQ29tcG9uZW50ID0gRXhjbHVkZTxcblx0RXhjbHVkZTxMbmF2Rm9ybWF0W2BsaW5lLWZvcm1hdGBdLCB1bmRlZmluZWQ+W251bWJlcl0sXG5cdHN0cmluZ1xuPlxuXG5leHBvcnQgdHlwZSBMbmF2Rm9ybWF0QnJlYWtkb3duID0gRXhjbHVkZTxMbmF2Rm9ybWF0W2B2YWx1ZWBdLCB1bmRlZmluZWQ+XG5leHBvcnQgdHlwZSBNZW1iZXJPZjxUPiA9IFRba2V5b2YgVF1cbmV4cG9ydCB0eXBlIExuYXZGb3JtYXRWYWx1ZURlZmluaXRpb24gPSBNZW1iZXJPZjxMbmF2Rm9ybWF0QnJlYWtkb3duPlxuXG5leHBvcnQgdHlwZSBGbGlnaHREZWNrRm9ybWF0ID0ge1xuXHRbTElORV9GT1JNQVRdOiAoXG5cdFx0fCBzdHJpbmdcblx0XHR8IChMbmF2Rm9ybWF0VmlzdWFsQ29tcG9uZW50ICYge1xuXHRcdFx0XHRmaWVsZDoga2V5b2YgRmxpZ2h0RGVja0xvZyB8IGBfX2xldmVsX19gIHwgYF9fdGltZXN0YW1wX19gXG5cdFx0ICB9KVxuXHQpW11cblx0W1ZBTFVFXToge1xuXHRcdFtLIGluIGtleW9mIEZsaWdodERlY2tMb2ddOiBMbmF2Rm9ybWF0VmFsdWVEZWZpbml0aW9uICYge1xuXHRcdFx0a2luZDogRmxpZ2h0RGVja0xvZ1tLXSBleHRlbmRzIG51bWJlciB8IHVuZGVmaW5lZFxuXHRcdFx0XHQ/IGBpbnRlZ2VyYFxuXHRcdFx0XHQ6IEZsaWdodERlY2tMb2dbS10gZXh0ZW5kcyBzdHJpbmcgfCB1bmRlZmluZWRcblx0XHRcdFx0XHQ/IGBzdHJpbmdgXG5cdFx0XHRcdFx0OiBuZXZlclxuXHRcdH1cblx0fVxufVxuXG5leHBvcnQgY29uc3QgRkxJR0hUREVDS19MTkFWX0ZPUk1BVCA9IHtcblx0dGl0bGU6IGBGbGlnaHREZWNrIExvZ2AsXG5cdGRlc2NyaXB0aW9uOiBgRm9ybWF0IGZvciBldmVudHMgbG9nZ2VkIGJ5IHRoZSBGbGlnaHREZWNrIHByb2Nlc3MgbWFuYWdlci5gLFxuXHRcImZpbGUtdHlwZVwiOiBganNvbmAsXG5cdFwidGltZXN0YW1wLWZpZWxkXCI6IGB0aW1lc3RhbXBgLFxuXHRcInRpbWVzdGFtcC1kaXZpc29yXCI6IDEwMDAsXG5cdFwibW9kdWxlLWZpZWxkXCI6IGBwYWNrYWdlYCxcblx0XCJvcGlkLWZpZWxkXCI6IGBzZXJ2aWNlYCxcblx0XCJsZXZlbC1maWVsZFwiOiBgbGV2ZWxgLFxuXHRsZXZlbDoge1xuXHRcdGluZm86IEZMSUdIVERFQ0tfSU5GTyxcblx0XHR3YXJuaW5nOiBGTElHSFRERUNLX1dBUk4sXG5cdFx0ZXJyb3I6IEZMSUdIVERFQ0tfRVJST1IsXG5cdH0sXG5cblx0W0xJTkVfRk9STUFUXTogW1xuXHRcdHtcblx0XHRcdGZpZWxkOiBgbGV2ZWxgLFxuXHRcdH0sXG5cdFx0e1xuXHRcdFx0cHJlZml4OiBgIGAsXG5cdFx0XHRmaWVsZDogYF9fdGltZXN0YW1wX19gLFxuXHRcdFx0XCJ0aW1lc3RhbXAtZm9ybWF0XCI6IGAlWS0lbS0lZFQlSDolTTolUy4lTCVaYCxcblx0XHR9LFxuXHRcdHtcblx0XHRcdHByZWZpeDogYCBgLFxuXHRcdFx0ZmllbGQ6IGBwcm9jZXNzYCxcblx0XHRcdFwibWluLXdpZHRoXCI6IDUsXG5cdFx0fSxcblx0XHR7XG5cdFx0XHRwcmVmaXg6IGA6YCxcblx0XHRcdGZpZWxkOiBgcGFja2FnZWAsXG5cdFx0fSxcblx0XHR7XG5cdFx0XHRwcmVmaXg6IGA6YCxcblx0XHRcdGZpZWxkOiBgc2VydmljZWAsXG5cdFx0XHRcImRlZmF1bHQtdmFsdWVcIjogYGAsXG5cdFx0fSxcblx0XHR7XG5cdFx0XHRwcmVmaXg6IGA6IGAsXG5cdFx0XHRmaWVsZDogYGJvZHlgLFxuXHRcdH0sXG5cdF0sXG5cblx0W1ZBTFVFXToge1xuXHRcdHRpbWVzdGFtcDoge1xuXHRcdFx0a2luZDogYGludGVnZXJgLFxuXHRcdH0sXG5cdFx0bGV2ZWw6IHtcblx0XHRcdGtpbmQ6IGBzdHJpbmdgLFxuXHRcdH0sXG5cdFx0cGFja2FnZToge1xuXHRcdFx0a2luZDogYHN0cmluZ2AsXG5cdFx0fSxcblx0XHRzZXJ2aWNlOiB7XG5cdFx0XHRraW5kOiBgc3RyaW5nYCxcblx0XHR9LFxuXHRcdHByb2Nlc3M6IHtcblx0XHRcdGtpbmQ6IGBpbnRlZ2VyYCxcblx0XHR9LFxuXHRcdGJvZHk6IHtcblx0XHRcdGtpbmQ6IGBzdHJpbmdgLFxuXHRcdH0sXG5cdH0sXG59IGFzIGNvbnN0IHNhdGlzZmllcyBGbGlnaHREZWNrRm9ybWF0ICYgTG5hdkZvcm1hdFxuXG5leHBvcnQgY2xhc3MgRmxpZ2h0RGVja0xvZ2dlclxuXHRpbXBsZW1lbnRzIFBpY2s8Q29uc29sZSwgYGVycm9yYCB8IGBpbmZvYCB8IGB3YXJuYD5cbntcblx0cHVibGljIHJlYWRvbmx5IHBhY2thZ2VOYW1lOiBzdHJpbmdcblx0cHVibGljIHJlYWRvbmx5IHNlcnZpY2VOYW1lPzogc3RyaW5nXG5cdHB1YmxpYyByZWFkb25seSBqc29uTG9nZ2luZzogYm9vbGVhblxuXHRwdWJsaWMgcHJvY2Vzc0NvZGU6IG51bWJlclxuXHRwdWJsaWMgY29uc3RydWN0b3IoXG5cdFx0cGFja2FnZU5hbWU6IHN0cmluZyxcblx0XHRwcm9jZXNzQ29kZTogbnVtYmVyLFxuXHRcdHNlcnZpY2VOYW1lPzogc3RyaW5nLFxuXHRcdG9wdGlvbnM/OiB7IGpzb25Mb2dnaW5nOiBib29sZWFuIH0sXG5cdCkge1xuXHRcdHRoaXMucGFja2FnZU5hbWUgPSBwYWNrYWdlTmFtZVxuXHRcdGlmIChzZXJ2aWNlTmFtZSkge1xuXHRcdFx0dGhpcy5zZXJ2aWNlTmFtZSA9IHNlcnZpY2VOYW1lXG5cdFx0fVxuXHRcdHRoaXMucHJvY2Vzc0NvZGUgPSBwcm9jZXNzQ29kZVxuXHRcdHRoaXMuanNvbkxvZ2dpbmcgPSBvcHRpb25zPy5qc29uTG9nZ2luZyA/PyBmYWxzZVxuXHR9XG5cdHByb3RlY3RlZCBsb2coXG5cdFx0bGV2ZWw6XG5cdFx0XHR8IHR5cGVvZiBGTElHSFRERUNLX0VSUk9SXG5cdFx0XHR8IHR5cGVvZiBGTElHSFRERUNLX0lORk9cblx0XHRcdHwgdHlwZW9mIEZMSUdIVERFQ0tfV0FSTixcblx0XHQuLi5tZXNzYWdlczogdW5rbm93bltdXG5cdCk6IHZvaWQge1xuXHRcdGlmICh0aGlzLmpzb25Mb2dnaW5nKSB7XG5cdFx0XHRsZXQgYm9keSA9IG1lc3NhZ2VzXG5cdFx0XHRcdC5tYXAoKG1lc3NhZ2UpID0+XG5cdFx0XHRcdFx0dHlwZW9mIG1lc3NhZ2UgPT09IGBzdHJpbmdgXG5cdFx0XHRcdFx0XHQ/IG1lc3NhZ2Vcblx0XHRcdFx0XHRcdDogaW5zcGVjdChtZXNzYWdlLCBmYWxzZSwgbnVsbCwgdHJ1ZSksXG5cdFx0XHRcdClcblx0XHRcdFx0LmpvaW4oYCBgKVxuXHRcdFx0aWYgKGJvZHkuaW5jbHVkZXMoYFxcbmApKSB7XG5cdFx0XHRcdGJvZHkgPSBgXFxuICAke2JvZHkuc3BsaXQoYFxcbmApLmpvaW4oYFxcbiAgYCl9YFxuXHRcdFx0fVxuXHRcdFx0Y29uc3QgbG9nOiBGbGlnaHREZWNrTG9nID0ge1xuXHRcdFx0XHR0aW1lc3RhbXA6IERhdGUubm93KCksXG5cdFx0XHRcdGxldmVsLFxuXHRcdFx0XHRwcm9jZXNzOiB0aGlzLnByb2Nlc3NDb2RlLFxuXHRcdFx0XHRwYWNrYWdlOiB0aGlzLnBhY2thZ2VOYW1lLFxuXHRcdFx0XHRib2R5LFxuXHRcdFx0fVxuXHRcdFx0aWYgKHRoaXMuc2VydmljZU5hbWUpIHtcblx0XHRcdFx0bG9nLnNlcnZpY2UgPSB0aGlzLnNlcnZpY2VOYW1lXG5cdFx0XHR9XG5cdFx0XHRwcm9jZXNzLnN0ZG91dC53cml0ZShKU09OLnN0cmluZ2lmeShsb2cpICsgYFxcbmApXG5cdFx0fSBlbHNlIHtcblx0XHRcdGNvbnN0IHNvdXJjZSA9IHRoaXMuc2VydmljZU5hbWVcblx0XHRcdFx0PyBgJHt0aGlzLnBhY2thZ2VOYW1lfToke3RoaXMuc2VydmljZU5hbWV9YFxuXHRcdFx0XHQ6IHRoaXMucGFja2FnZU5hbWVcblx0XHRcdHN3aXRjaCAobGV2ZWwpIHtcblx0XHRcdFx0Y2FzZSBGTElHSFRERUNLX0lORk86XG5cdFx0XHRcdFx0Y29uc29sZS5sb2coYCR7c291cmNlfTpgLCAuLi5tZXNzYWdlcylcblx0XHRcdFx0XHRicmVha1xuXHRcdFx0XHRjYXNlIEZMSUdIVERFQ0tfV0FSTjpcblx0XHRcdFx0XHRjb25zb2xlLndhcm4oYCR7c291cmNlfTpgLCAuLi5tZXNzYWdlcylcblx0XHRcdFx0XHRicmVha1xuXHRcdFx0XHRjYXNlIEZMSUdIVERFQ0tfRVJST1I6XG5cdFx0XHRcdFx0Y29uc29sZS5lcnJvcihgJHtzb3VyY2V9OmAsIC4uLm1lc3NhZ2VzKVxuXHRcdFx0XHRcdGJyZWFrXG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cdHB1YmxpYyBpbmZvKC4uLm1lc3NhZ2VzOiB1bmtub3duW10pOiB2b2lkIHtcblx0XHR0aGlzLmxvZyhGTElHSFRERUNLX0lORk8sIC4uLm1lc3NhZ2VzKVxuXHR9XG5cblx0cHVibGljIHdhcm4oLi4ubWVzc2FnZXM6IHVua25vd25bXSk6IHZvaWQge1xuXHRcdHRoaXMubG9nKEZMSUdIVERFQ0tfV0FSTiwgLi4ubWVzc2FnZXMpXG5cdH1cblxuXHRwdWJsaWMgZXJyb3IoLi4ubWVzc2FnZXM6IHVua25vd25bXSk6IHZvaWQge1xuXHRcdHRoaXMubG9nKEZMSUdIVERFQ0tfRVJST1IsIC4uLm1lc3NhZ2VzKVxuXHR9XG59XG4iLAogICAgImltcG9ydCB7IGNyZWF0ZUVudiB9IGZyb20gXCJAdDMtb3NzL2Vudi1jb3JlXCJcbmltcG9ydCB7IHogfSBmcm9tIFwiem9kXCJcblxuZXhwb3J0IGNvbnN0IGVudiA9IGNyZWF0ZUVudih7XG5cdHNlcnZlcjogeyBGTElHSFRERUNLX1NFQ1JFVDogei5zdHJpbmcoKS5vcHRpb25hbCgpIH0sXG5cdGNsaWVudFByZWZpeDogYE5FVkVSYCxcblx0Y2xpZW50OiB7fSxcblx0cnVudGltZUVudjogaW1wb3J0Lm1ldGEuZW52LFxuXHRlbXB0eVN0cmluZ0FzVW5kZWZpbmVkOiB0cnVlLFxufSlcbiIsCiAgICAiZXhwb3J0IHR5cGUgQWxlcnRPcHRpb25zID0ge1xuXHRzZWNyZXQ6IHN0cmluZ1xuXHRlbmRwb2ludDogc3RyaW5nXG5cdHZlcnNpb246IHN0cmluZ1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYWxlcnQoe1xuXHRzZWNyZXQsXG5cdGVuZHBvaW50LFxuXHR2ZXJzaW9uLFxufTogQWxlcnRPcHRpb25zKTogUHJvbWlzZTxSZXNwb25zZT4ge1xuXHRjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKGVuZHBvaW50LCB7XG5cdFx0bWV0aG9kOiBgUE9TVGAsXG5cdFx0aGVhZGVyczoge1xuXHRcdFx0XCJDb250ZW50LVR5cGVcIjogYHRleHQvcGxhaW47Y2hhcnNldD1VVEYtOGAsXG5cdFx0XHRBdXRob3JpemF0aW9uOiBgQmVhcmVyICR7c2VjcmV0fWAsXG5cdFx0fSxcblx0XHRib2R5OiB2ZXJzaW9uLFxuXHR9KVxuXG5cdHJldHVybiByZXNwb25zZVxufVxuXG4vKipcbiAqIEBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2NoYW5nZXNldHMvYWN0aW9uL2Jsb2IvbWFpbi9zcmMvcnVuLnRzXG4gKi9cbmV4cG9ydCB0eXBlIENoYW5nZXNldHNQdWJsaXNoZWRQYWNrYWdlID0ge1xuXHRuYW1lOiBzdHJpbmdcblx0dmVyc2lvbjogc3RyaW5nXG59XG5cbi8qKlxuICogQHNlZSBodHRwczovL2dpdGh1Yi5jb20vY2hhbmdlc2V0cy9hY3Rpb24vYmxvYi9tYWluL3NyYy9ydW4udHNcbiAqL1xuZXhwb3J0IHR5cGUgQ2hhbmdlc2V0c1B1Ymxpc2hSZXN1bHQgPVxuXHR8IHtcblx0XHRcdHB1Ymxpc2hlZDogdHJ1ZVxuXHRcdFx0cHVibGlzaGVkUGFja2FnZXM6IENoYW5nZXNldHNQdWJsaXNoZWRQYWNrYWdlW11cblx0ICB9XG5cdHwgeyBwdWJsaXNoZWQ6IGZhbHNlIH1cblxuZXhwb3J0IHR5cGUgUGFja2FnZUNvbmZpZzxLIGV4dGVuZHMgc3RyaW5nPiA9IHtcblx0W2tleSBpbiBLXTogeyBlbmRwb2ludDogc3RyaW5nIH1cbn1cbmV4cG9ydCB0eXBlIFNlY3JldHNDb25maWc8SyBleHRlbmRzIHN0cmluZz4gPSB7XG5cdFtrZXkgaW4gS106IHN0cmluZ1xufVxuXG5leHBvcnQgdHlwZSBTY3JhbWJsZU9wdGlvbnM8SyBleHRlbmRzIHN0cmluZyA9IHN0cmluZz4gPSB7XG5cdHBhY2thZ2VDb25maWc6IFBhY2thZ2VDb25maWc8Sz5cblx0c2VjcmV0c0NvbmZpZzogU2VjcmV0c0NvbmZpZzxLPlxuXHRwdWJsaXNoZWRQYWNrYWdlczogQ2hhbmdlc2V0c1B1Ymxpc2hlZFBhY2thZ2VbXVxufVxuXG5leHBvcnQgdHlwZSBTY3JhbWJsZVJlc3VsdDxLIGV4dGVuZHMgc3RyaW5nID0gc3RyaW5nPiA9IHtcblx0W2tleSBpbiBLXTogUmVzcG9uc2Vcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNjcmFtYmxlPEsgZXh0ZW5kcyBzdHJpbmcgPSBzdHJpbmc+KHtcblx0cGFja2FnZUNvbmZpZyxcblx0c2VjcmV0c0NvbmZpZyxcblx0cHVibGlzaGVkUGFja2FnZXMsXG59OiBTY3JhbWJsZU9wdGlvbnM8Sz4pOiBQcm9taXNlPFNjcmFtYmxlUmVzdWx0PEs+PiB7XG5cdGNvbnN0IGFsZXJ0UmVzdWx0czogUHJvbWlzZTxyZWFkb25seSBbSywgUmVzcG9uc2VdPltdID0gW11cblx0Zm9yIChjb25zdCBwdWJsaXNoZWRQYWNrYWdlIG9mIHB1Ymxpc2hlZFBhY2thZ2VzKSB7XG5cdFx0aWYgKHB1Ymxpc2hlZFBhY2thZ2UubmFtZSBpbiBwYWNrYWdlQ29uZmlnKSB7XG5cdFx0XHRjb25zdCBuYW1lID0gcHVibGlzaGVkUGFja2FnZS5uYW1lIGFzIEtcblx0XHRcdGNvbnN0IHsgZW5kcG9pbnQgfSA9IHBhY2thZ2VDb25maWdbbmFtZV1cblx0XHRcdGNvbnN0IHNlY3JldCA9IHNlY3JldHNDb25maWdbbmFtZV1cblx0XHRcdGNvbnN0IHZlcnNpb24gPSBwdWJsaXNoZWRQYWNrYWdlLnZlcnNpb25cblx0XHRcdGNvbnN0IGFsZXJ0UmVzdWx0UHJvbWlzZSA9IGFsZXJ0KHsgc2VjcmV0LCBlbmRwb2ludCwgdmVyc2lvbiB9KS50aGVuKFxuXHRcdFx0XHQoYWxlcnRSZXN1bHQpID0+IFtuYW1lLCBhbGVydFJlc3VsdF0gYXMgY29uc3QsXG5cdFx0XHQpXG5cdFx0XHRhbGVydFJlc3VsdHMucHVzaChhbGVydFJlc3VsdFByb21pc2UpXG5cdFx0fVxuXHR9XG5cdGNvbnN0IGFsZXJ0UmVzdWx0c1Jlc29sdmVkID0gYXdhaXQgUHJvbWlzZS5hbGwoYWxlcnRSZXN1bHRzKVxuXHRjb25zdCBzY3JhbWJsZVJlc3VsdCA9IE9iamVjdC5mcm9tRW50cmllcyhcblx0XHRhbGVydFJlc3VsdHNSZXNvbHZlZCxcblx0KSBhcyBTY3JhbWJsZVJlc3VsdDxLPlxuXHRyZXR1cm4gc2NyYW1ibGVSZXN1bHRcbn1cbiIKICBdLAogICJtYXBwaW5ncyI6ICI4SEFBQSxtQkFBUyxXQUFVLDJCQUVuQix1QkFBUyxrQkFDVCxrQkFBUyxnQkFDVCxrQkFBUyxrQkFDVCxrQkFBUyxrQkFFVCxpQkFBUyx5QkFDVCx1QkFBUyw4QkFDVCxzQkFBUyxlQUFhLHFCQUN0QixzQkFBUyxnQ0FDVCxrQkFBUyxhQUNULDRCQUFTLG9CQUNULFlBQVMsWUNiVCxvQkFBUyx5QkFDVCxZQUFTLFlBRUYsSUFBTSxFQUFNLEVBQVUsQ0FDNUIsT0FBUSxDQUFFLGtCQUFtQixFQUFFLE9BQU8sRUFBRSxTQUFTLENBQUUsRUFDbkQsYUFBYyxRQUNkLE9BQVEsQ0FBQyxFQUNULFdBQVksWUFBWSxJQUN4Qix1QkFBd0IsRUFDekIsQ0FBQyxFRFNNLElBQU0sR0FBMEIsQ0FBQyxhQUFjLFdBQVcsRUFJcEQsR0FBMkIsQ0FBQyxXQUFZLFdBQVcsRUFJekQsU0FBUyxDQUFlLENBQUMsRUFBMEIsQ0FDekQsTUFDQyxrQkFBa0IsS0FBSyxDQUFPLElBQU0sT0FBTyxNQUFNLE9BQU8sV0FBVyxDQUFPLENBQUMsRUFpQnRFLE1BQU0sQ0FBc0MsQ0FrQ2YsUUFqQ3pCLE9BQVMsRUFFVCxRQUtBLGNBQ0EsU0FNQSxXQUNILDZCQUNBLHNCQUNBLHdCQUVHLE9BQ0EsZUFJQSwwQkFBNEMsS0FFL0MsYUFDQSxhQUNBLEtBQU8sSUFBSSxFQUFPLElBQU0sRUFBRSxFQUMxQixLQUFPLElBQUksRUFBTyxJQUFNLEVBQUUsRUFFdkIsYUFBeUIs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R0FBSSxLQUFLLFlBQWEsQ0FDckIsSUFBSSxFQUFPLEVBQ1QsSUFBSSxDQUFDLFdBQ0UsSUFBWSxTQUNoQixFQUNBLEVBQVEsRUFBUyxHQUFPLEtBQU0sRUFBSSxDQUN0QyxFQUNDLEtBQUssR0FBRyxFQUNWLEdBQUksRUFBSyxTQUFTO0FBQUEsQ0FBSSxFQUNyQixFQUFPO0FBQUEsSUFBTyxFQUFLLE1BQU07QUFBQSxDQUFJLEVBQUUsS0FBSztBQUFBLEdBQU0sSUFFM0MsSUFBTSxFQUFxQixDQUMxQixVQUFXLEtBQUssSUFBSSxFQUNwQixRQUNBLFFBQVMsS0FBSyxZQUNkLFFBQVMsS0FBSyxZQUNkLE1BQ0QsRUFDQSxHQUFJLEtBQUssWUFDUixFQUFJLFFBQVUsS0FBSyxZQUVwQixRQUFRLE9BQU8sTUFBTSxLQUFLLFVBQVUsQ0FBRyxFQUFJO0FBQUEsQ0FBSSxNQUN6QyxDQUNOLElBQU0sRUFBUyxLQUFLLFlBQ2pCLEdBQUcsS0FBSyxlQUFlLEtBQUssY0FDNUIsS0FBSyxZQUNSLE9BQVEsUUFDRixFQUNKLFFBQVEsSUFBSSxHQUFHLEtBQVcsR0FBRyxDQUFRLEVBQ3JDLFdBQ0ksRUFDSixRQUFRLEtBQUssR0FBRyxLQUFXLEdBQUcsQ0FBUSxFQUN0QyxXQUNJLEVBQ0osUUFBUSxNQUFNLEdBQUcsS0FBVyxHQUFHLENBQVEsRUFDdkMsUUFJRyxJQUFJLElBQUksRUFBMkIsQ0FDekMsS0FBSyxJQUFJLEVBQWlCLEdBQUcsQ0FBUSxFQUcvQixJQUFJLElBQUksRUFBMkIsQ0FDekMsS0FBSyxJQUFJLEVBQWlCLEdBQUcsQ0FBUSxFQUcvQixLQUFLLElBQUksRUFBMkIsQ0FDMUMsS0FBSyxJQUFJLEVBQWtCLEdBQUcsQ0FBUSxFQUV4Qyw0Q0VqbkJBLGVBQXNCLENBQUssRUFDMUIsU0FDQSxXQUNBLFdBQ21DLENBVW5DLE9BVGlCLE1BQU0sTUFBTSxFQUFVLENBQ3RDLE9BQVEsT0FDUixRQUFTLENBQ1IsZUFBZ0IsMkJBQ2hCLGNBQWUsVUFBVSxHQUMxQixFQUNBLEtBQU0sQ0FDUCxDQUFDLEVBd0NGLGVBQXNCLENBQW1DLEVBQ3hELGdCQUNBLGdCQUNBLHFCQUNrRCxDQUNsRCxJQUFNLEVBQWtELENBQUMsRUFDekQsUUFBVyxLQUFvQixFQUM5QixHQUFJLEVBQWlCLFFBQVEsRUFBZSxDQUMzQyxJQUFNLEVBQU8sRUFBaUIsTUFDdEIsWUFBYSxFQUFjLEdBQzdCLEVBQVMsRUFBYyxHQUN2QixFQUFVLEVBQWlCLFFBQzNCLEVBQXFCLEVBQU0sQ0FBRSxTQUFRLFdBQVUsU0FBUSxDQUFDLEVBQUUsS0FDL0QsQ0FBQyxJQUFnQixDQUFDLEVBQU0sQ0FBVyxDQUNwQyxFQUNBLEVBQWEsS0FBSyxDQUFrQixFQUd0QyxJQUFNLEVBQXVCLE1BQU0sUUFBUSxJQUFJLENBQVksRUFJM0QsT0FIdUIsT0FBTyxZQUM3QixDQUNEIiwKICAiZGVidWdJZCI6ICJGNUZGODlDNTdEOTI2RTU1NjQ3NTZFMjE2NDc1NkUyMSIsCiAgIm5hbWVzIjogW10KfQ==
1
+ export { FLIGHTDECK_ERROR, FLIGHTDECK_INFO, FLIGHTDECK_LNAV_FORMAT, FLIGHTDECK_SETUP_PHASES, FLIGHTDECK_UPDATE_PHASES, FLIGHTDECK_WARN, FlightDeck, FlightDeckLogger, flightDeckLogSchema, isVersionNumber } from './chunk-AP2UJF2F.js';
2
+ export { klaxon_lib_exports as Klaxon } from './chunk-ZID4FJKY.js';
3
+ import './chunk-PZ5AY32C.js';
4
+ //# sourceMappingURL=lib.js.map
5
+ //# sourceMappingURL=lib.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"lib.js"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flightdeck",
3
- "version": "0.2.14",
3
+ "version": "0.2.16",
4
4
  "license": "MIT",
5
5
  "author": {
6
6
  "name": "Jeremy Banka",
@@ -23,43 +23,41 @@
23
23
  "main": "dist/lib.js",
24
24
  "types": "dist/lib.d.ts",
25
25
  "bin": {
26
- "flightdeck": "./dist/flightdeck.bin.js",
27
- "klaxon": "./dist/klaxon.bin.js"
26
+ "flightdeck": "./bin/flightdeck.bin.js",
27
+ "klaxon": "./bin/klaxon.bin.js"
28
28
  },
29
29
  "dependencies": {
30
30
  "@t3-oss/env-core": "0.12.0",
31
- "cron": "3.5.0",
31
+ "cron": "4.0.0",
32
32
  "zod": "3.24.2",
33
- "atom.io": "0.30.7",
33
+ "atom.io": "0.31.1",
34
34
  "comline": "0.1.9",
35
35
  "safedeposit": "0.1.0"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@biomejs/js-api": "0.7.1",
39
39
  "@biomejs/wasm-nodejs": "1.9.4",
40
- "@types/node": "22.13.4",
40
+ "@types/node": "22.13.5",
41
41
  "@types/tmp": "0.2.6",
42
- "bun-types": "1.2.2",
42
+ "bun-types": "1.2.3",
43
43
  "concurrently": "9.1.2",
44
- "eslint": "9.20.1",
44
+ "eslint": "9.21.0",
45
45
  "json-schema-to-zod": "2.6.0",
46
46
  "rimraf": "6.0.1",
47
47
  "tmp": "0.2.3",
48
48
  "tsup": "8.3.6",
49
- "vitest": "3.0.5",
49
+ "vitest": "3.0.6",
50
50
  "varmint": "0.4.2"
51
51
  },
52
52
  "scripts": {
53
53
  "gen": "bun ./__scripts__/gen.bun.ts",
54
- "build": "rimraf dist && concurrently \"bun:build:*\" && concurrently \"bun:schema:*\"",
55
- "build:js": "bun ./__scripts__/build.bun.ts",
56
- "build:dts": "tsup",
54
+ "build": "tsup-node && rm -f dist/*.x.d.ts && bun ./__scripts__/build-lnav.bun.ts",
57
55
  "schema:flightdeck": "bun ./src/flightdeck.bin.ts --outdir=dist -- schema",
58
56
  "lint:biome": "biome check -- .",
59
57
  "lint:eslint": "eslint -- .",
60
58
  "lint:types": "tsc --noEmit",
61
- "lint:types:watch": "tsc --watch --noEmit",
62
- "lint": "bun run lint:biome && bun run lint:eslint && bun run lint:types",
59
+ "watch:types": "tsc --watch --noEmit",
60
+ "lint": "concurrently \"bun:lint:*\"",
63
61
  "test": "vitest",
64
62
  "test:once": "vitest run",
65
63
  "postversion": "biome format --write package.json"
@@ -1,64 +0,0 @@
1
- {
2
- "type": "object",
3
- "properties": {
4
- "port": {
5
- "type": "number"
6
- },
7
- "packageName": {
8
- "type": "string"
9
- },
10
- "services": {
11
- "type": "object",
12
- "additionalProperties": {
13
- "type": "object",
14
- "properties": {
15
- "run": {
16
- "type": "string"
17
- },
18
- "waitFor": {
19
- "type": "boolean"
20
- }
21
- },
22
- "required": [
23
- "run",
24
- "waitFor"
25
- ],
26
- "additionalProperties": false
27
- }
28
- },
29
- "flightdeckRootDir": {
30
- "type": "string"
31
- },
32
- "scripts": {
33
- "type": "object",
34
- "properties": {
35
- "download": {
36
- "type": "string"
37
- },
38
- "install": {
39
- "type": "string"
40
- },
41
- "checkAvailability": {
42
- "type": "string"
43
- }
44
- },
45
- "required": [
46
- "download",
47
- "install",
48
- "checkAvailability"
49
- ],
50
- "additionalProperties": false
51
- },
52
- "jsonLogging": {
53
- "type": "boolean"
54
- }
55
- },
56
- "required": [
57
- "packageName",
58
- "services",
59
- "flightdeckRootDir",
60
- "scripts"
61
- ],
62
- "additionalProperties": false,
63
- "$schema": "http://json-schema.org/draft-07/schema#"
64
- }
@@ -1,10 +0,0 @@
1
- #!/usr/bin/env node
2
- var R=Object.defineProperty;var X=(e,i)=>{for(var t in i)R(e,t,{get:i[t],enumerable:!0,configurable:!0,set:(o)=>i[t]=()=>o})};import*as T from"node:path";import{cli as z,optional as J,parseBooleanOption as q,parseNumberOption as W}from"comline";import{z as r}from"zod";import{execSync as F,spawn as U}from"node:child_process";import{createServer as $}from"node:http";import{homedir as j}from"node:os";import{resolve as A}from"node:path";import{inspect as O}from"node:util";import{Future as d}from"atom.io/internal";import{discoverType as H}from"atom.io/introspection";import{fromEntries as k,toEntries as f}from"atom.io/json";import{ChildSocket as G}from"atom.io/realtime-server";import{CronJob as N}from"cron";import{FilesystemStorage as K}from"safedeposit";import{z as a}from"zod";import{createEnv as I}from"@t3-oss/env-core";import{z as _}from"zod";var x=I({server:{FLIGHTDECK_SECRET:_.string().optional()},clientPrefix:"NEVER",client:{},runtimeEnv:import.meta.env,emptyStringAsUndefined:!0});var ve=["downloaded","installed"],ke=["notified","confirmed"];function M(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 d(()=>{});dead=new d(()=>{});restartTimes=[];constructor(e){this.options=e;let{FLIGHTDECK_SECRET:i}=x,{flightdeckRootDir:t=A(j(),".flightdeck")}=e,o=e.port??8080,c=`http://localhost:${o}`,p=f(e.services);if(this.services=k(p.map(([s])=>[s,null])),this.serviceIdx=k(p.map(([s],n)=>[s,n])),this.defaultServicesReadyToUpdate=k(p.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(p.map(([s])=>[s,new u(this.options.packageName,process.pid,s,{jsonLogging:this.options.jsonLogging??!1})])),this.servicesLive=p.map(()=>new d(()=>{})),this.servicesDead=p.map(()=>new d(()=>{})),this.live.use(Promise.all(this.servicesLive)),this.dead.use(Promise.all(this.servicesDead)),this.storage=new K({path:A(t,"storage",e.packageName)}),i===void 0)this.logger.warn("No FLIGHTDECK_SECRET environment variable found. FlightDeck will not run an update server.");else $((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 ${i}`;if(l!==`Bearer ${i}`)throw this.logger.info(`Unauthorized: needed \`${h}\`, got \`${l}\``),401;let S=new URL(s.url,c);this.logger.info(s.method,S.pathname);let v=Buffer.concat(m).toString();if(!M(v))throw 400;n.writeHead(200),n.end(),this.storage.setItem("updatePhase","notified"),this.storage.setItem("updateAwaitedVersion",v);let{checkAvailability:C}=e.scripts;if(C){this.updateAvailabilityChecker?.stop(),this.seekUpdate(v);let E=this.storage.getItem("updatePhase");if(this.logger.info('> storage("updatePhase") >',E),E==="notified")this.updateAvailabilityChecker=new N("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:i}=this.options.scripts;if(!i){this.logger.info("No checkAvailability script found.");return}try{let t=F(`${i} ${e}`);this.logger.info("Check stdout:",t.toString()),this.updateAvailabilityChecker?.stop(),this.storage.setItem("updatePhase","confirmed"),this.downloadPackage(),this.announceUpdate()}catch(t){if(t instanceof Error)this.logger.error("Check failed:",t.message);else{let o=H(t);this.logger.error("Check threw",o,t)}}}announceUpdate(){for(let e of f(this.services)){let[i,t]=e;if(t){if(this.options.services[i].waitFor)t.emit("updatesReady")}else this.startService(i)}}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[i]of f(this.services))this.startService(i);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[i,...t]=this.options.services[e].run.split(" "),o=U(i,t,{cwd:this.options.flightdeckRootDir,env:import.meta.env}),c=this.serviceLoggers[e],p=this.services[e]=new G(o,`${this.options.packageName}::${e}`,c);c.processCode=p.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 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 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((S)=>S>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=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 f(this.services))this.stopService(e);return this.dead}stopService(e){let i=this.services[e];if(i){if(this.logger.info(`Stopping service "${e}"...`),this.servicesDead[this.serviceIdx[e]].use(new Promise((t)=>{i.emit("timeToStop"),i.process.once("close",(o)=>{this.logger.info(`Stopped service "${e}"; exited with code ${o}`),this.services[e]=null,t()})})),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 w="info",b="warn",y="ERR!",we=a.object({level:a.union([a.literal(w),a.literal(b),a.literal(y)]),timestamp:a.number(),package:a.string(),service:a.string().optional(),process:a.number(),body:a.string()}),V="line-format",B="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:w,warning:b,error:y},[V]:[{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"}],[B]:{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,i,t,o){if(this.packageName=e,t)this.serviceName=t;this.processCode=i,this.jsonLogging=o?.jsonLogging??!1}log(e,...i){if(this.jsonLogging){let t=i.map((c)=>typeof c==="string"?c:O(c,!1,null,!0)).join(" ");if(t.includes(`
3
- `))t=`
4
- ${t.split(`
5
- `).join(`
6
- `)}`;let o={timestamp:Date.now(),level:e,process:this.processCode,package:this.packageName,body:t};if(this.serviceName)o.service=this.serviceName;process.stdout.write(JSON.stringify(o)+`
7
- `)}else{let t=this.serviceName?`${this.packageName}:${this.serviceName}`:this.packageName;switch(e){case w:console.log(`${t}:`,...i);break;case b:console.warn(`${t}:`,...i);break;case y:console.error(`${t}:`,...i);break}}}info(...e){this.log(w,...e)}warn(...e){this.log(b,...e)}error(...e){this.log(y,...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 P={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:W},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:q}}},Y={optionsSchema:r.object({outdir:r.string().optional()}),options:{outdir:{flag:"o",required:!1,description:"Directory to write the schema to.",example:"--outdir=./dist"}}},Z=z({cliName:"flightdeck",routes:J({schema:null,$configPath:null}),routeOptions:{"":P,$configPath:P,schema:Y},debugOutput:!0,discoverConfigPath:(e)=>{if(e[0]==="schema")return;return e[0]??T.join(process.cwd(),"flightdeck.config.json")}},console),{inputs:D,writeJsonSchema:Q}=Z(process.argv);switch(D.case){case"schema":{let{outdir:e}=D.opts;Q(e??".")}break;default:{let e=new L(D.opts);process.on("close",async()=>{await e.stopAllServices()})}}
8
-
9
- //# debugId=6467DBABFBD56FAE64756E2164756E21
10
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2ZsaWdodGRlY2suYmluLnRzIiwgIi4uL3NyYy9mbGlnaHRkZWNrLmxpYi50cyIsICIuLi9zcmMvZmxpZ2h0ZGVjay5lbnYudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbCiAgICAiIyEvdXNyL2Jpbi9lbnYgbm9kZVxuXG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gXCJub2RlOnBhdGhcIlxuXG5pbXBvcnQgdHlwZSB7IE9wdGlvbnNHcm91cCB9IGZyb20gXCJjb21saW5lXCJcbmltcG9ydCB7IGNsaSwgb3B0aW9uYWwsIHBhcnNlQm9vbGVhbk9wdGlvbiwgcGFyc2VOdW1iZXJPcHRpb24gfSBmcm9tIFwiY29tbGluZVwiXG5pbXBvcnQgeyB6IH0gZnJvbSBcInpvZFwiXG5cbmltcG9ydCB0eXBlIHsgRmxpZ2h0RGVja09wdGlvbnMgfSBmcm9tIFwiLi9mbGlnaHRkZWNrLmxpYlwiXG5pbXBvcnQgeyBGbGlnaHREZWNrLCBGbGlnaHREZWNrTG9nZ2VyIH0gZnJvbSBcIi4vZmxpZ2h0ZGVjay5saWJcIlxuXG5jb25zdCBDTElfTE9HR0VSID0gbmV3IEZsaWdodERlY2tMb2dnZXIoYGNvbWxpbmVgLCBwcm9jZXNzLnBpZCwgdW5kZWZpbmVkLCB7XG5cdGpzb25Mb2dnaW5nOiB0cnVlLFxufSlcbk9iamVjdC5hc3NpZ24oY29uc29sZSwge1xuXHRsb2c6IENMSV9MT0dHRVIuaW5mby5iaW5kKENMSV9MT0dHRVIpLFxuXHRpbmZvOiBDTElfTE9HR0VSLmluZm8uYmluZChDTElfTE9HR0VSKSxcblx0d2FybjogQ0xJX0xPR0dFUi53YXJuLmJpbmQoQ0xJX0xPR0dFUiksXG5cdGVycm9yOiBDTElfTE9HR0VSLmVycm9yLmJpbmQoQ0xJX0xPR0dFUiksXG59KVxuXG5jb25zdCBGTElHSFRERUNLX01BTlVBTCA9IHtcblx0b3B0aW9uc1NjaGVtYTogei5vYmplY3Qoe1xuXHRcdHBvcnQ6IHoubnVtYmVyKCkub3B0aW9uYWwoKSxcblx0XHRwYWNrYWdlTmFtZTogei5zdHJpbmcoKSxcblx0XHRzZXJ2aWNlczogei5yZWNvcmQoei5vYmplY3QoeyBydW46IHouc3RyaW5nKCksIHdhaXRGb3I6IHouYm9vbGVhbigpIH0pKSxcblx0XHRmbGlnaHRkZWNrUm9vdERpcjogei5zdHJpbmcoKSxcblx0XHRzY3JpcHRzOiB6Lm9iamVjdCh7XG5cdFx0XHRkb3dubG9hZDogei5zdHJpbmcoKSxcblx0XHRcdGluc3RhbGw6IHouc3RyaW5nKCksXG5cdFx0XHRjaGVja0F2YWlsYWJpbGl0eTogei5zdHJpbmcoKSxcblx0XHR9KSxcblx0XHRqc29uTG9nZ2luZzogei5ib29sZWFuKCkub3B0aW9uYWwoKSxcblx0fSksXG5cdG9wdGlvbnM6IHtcblx0XHRwb3J0OiB7XG5cdFx0XHRmbGFnOiBgcGAsXG5cdFx0XHRyZXF1aXJlZDogZmFsc2UsXG5cdFx0XHRkZXNjcmlwdGlvbjogYFBvcnQgdG8gcnVuIHRoZSBmbGlnaHRkZWNrIHNlcnZlciBvbi5gLFxuXHRcdFx0ZXhhbXBsZTogYC0tcG9ydD04MDgwYCxcblx0XHRcdHBhcnNlOiBwYXJzZU51bWJlck9wdGlvbixcblx0XHR9LFxuXHRcdHBhY2thZ2VOYW1lOiB7XG5cdFx0XHRmbGFnOiBgbmAsXG5cdFx0XHRyZXF1aXJlZDogdHJ1ZSxcblx0XHRcdGRlc2NyaXB0aW9uOiBgTmFtZSBvZiB0aGUgcGFja2FnZS5gLFxuXHRcdFx0ZXhhbXBsZTogYC0tcGFja2FnZU5hbWU9XFxcIm15LWFwcFxcXCJgLFxuXHRcdH0sXG5cdFx0c2VydmljZXM6IHtcblx0XHRcdGZsYWc6IGBzYCxcblx0XHRcdHJlcXVpcmVkOiB0cnVlLFxuXHRcdFx0ZGVzY3JpcHRpb246IGBNYXAgb2Ygc2VydmljZSBuYW1lcyB0byBleGVjdXRhYmxlcy5gLFxuXHRcdFx0ZXhhbXBsZTogYC0tc2VydmljZXM9XCJ7XFxcXFwiZnJvbnRlbmRcXFxcXCI6e1xcXFxcInJ1blxcXFxcIjpcXFxcXCIuL2Zyb250ZW5kXFxcXFwiLFxcXFxcIndhaXRGb3JcXFxcXCI6ZmFsc2V9LFxcXFxcImJhY2tlbmRcXFxcXCI6e1xcXFxcInJ1blxcXFxcIjpcXFxcXCIuL2JhY2tlbmRcXFxcXCIsXFxcXFwid2FpdEZvclxcXFxcIjp0cnVlfX1cImAsXG5cdFx0XHRwYXJzZTogSlNPTi5wYXJzZSxcblx0XHR9LFxuXHRcdGZsaWdodGRlY2tSb290RGlyOiB7XG5cdFx0XHRmbGFnOiBgZGAsXG5cdFx0XHRyZXF1aXJlZDogdHJ1ZSxcblx0XHRcdGRlc2NyaXB0aW9uOiBgRGlyZWN0b3J5IHdoZXJlIHRoZSBzZXJ2aWNlIGlzIHN0b3JlZC5gLFxuXHRcdFx0ZXhhbXBsZTogYC0tZmxpZ2h0ZGVja1Jvb3REaXI9XFxcIi4vc2VydmljZXMvc2FtcGxlL3JlcG8vbXktYXBwL2N1cnJlbnRcXFwiYCxcblx0XHR9LFxuXHRcdHNjcmlwdHM6IHtcblx0XHRcdGZsYWc6IGByYCxcblx0XHRcdHJlcXVpcmVkOiB0cnVlLFxuXHRcdFx0ZGVzY3JpcHRpb246IGBNYXAgb2Ygc2NyaXB0cyB0byBydW4uYCxcblx0XHRcdGV4YW1wbGU6IGAtLXNjcmlwdHM9XCJ7XFxcXFwiZG93bmxvYWRcXFxcXCI6XFxcXFwibnBtIGlcIixcXFxcXCJpbnN0YWxsXFxcXFwiOlxcXFxcIm5wbSBydW4gYnVpbGRcXFxcXCJ9XCJgLFxuXHRcdFx0cGFyc2U6IEpTT04ucGFyc2UsXG5cdFx0fSxcblx0XHRqc29uTG9nZ2luZzoge1xuXHRcdFx0ZmxhZzogYGpgLFxuXHRcdFx0cmVxdWlyZWQ6IGZhbHNlLFxuXHRcdFx0ZGVzY3JpcHRpb246IGBFbmFibGUganNvbiBsb2dnaW5nLmAsXG5cdFx0XHRleGFtcGxlOiBgLS1qc29uTG9nZ2luZ2AsXG5cdFx0XHRwYXJzZTogcGFyc2VCb29sZWFuT3B0aW9uLFxuXHRcdH0sXG5cdH0sXG59IHNhdGlzZmllcyBPcHRpb25zR3JvdXA8RmxpZ2h0RGVja09wdGlvbnM+XG5cbmNvbnN0IFNDSEVNQV9NQU5VQUwgPSB7XG5cdG9wdGlvbnNTY2hlbWE6IHoub2JqZWN0KHtcblx0XHRvdXRkaXI6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcblx0fSksXG5cdG9wdGlvbnM6IHtcblx0XHRvdXRkaXI6IHtcblx0XHRcdGZsYWc6IGBvYCxcblx0XHRcdHJlcXVpcmVkOiBmYWxzZSxcblx0XHRcdGRlc2NyaXB0aW9uOiBgRGlyZWN0b3J5IHRvIHdyaXRlIHRoZSBzY2hlbWEgdG8uYCxcblx0XHRcdGV4YW1wbGU6IGAtLW91dGRpcj0uL2Rpc3RgLFxuXHRcdH0sXG5cdH0sXG59IHNhdGlzZmllcyBPcHRpb25zR3JvdXA8eyBvdXRkaXI/OiBzdHJpbmcgfCB1bmRlZmluZWQgfT5cblxuY29uc3QgcGFyc2UgPSBjbGkoXG5cdHtcblx0XHRjbGlOYW1lOiBgZmxpZ2h0ZGVja2AsXG5cdFx0cm91dGVzOiBvcHRpb25hbCh7IHNjaGVtYTogbnVsbCwgJGNvbmZpZ1BhdGg6IG51bGwgfSksXG5cdFx0cm91dGVPcHRpb25zOiB7XG5cdFx0XHRcIlwiOiBGTElHSFRERUNLX01BTlVBTCxcblx0XHRcdCRjb25maWdQYXRoOiBGTElHSFRERUNLX01BTlVBTCxcblx0XHRcdHNjaGVtYTogU0NIRU1BX01BTlVBTCxcblx0XHR9LFxuXHRcdGRlYnVnT3V0cHV0OiB0cnVlLFxuXHRcdGRpc2NvdmVyQ29uZmlnUGF0aDogKGFyZ3MpID0+IHtcblx0XHRcdGlmIChhcmdzWzBdID09PSBgc2NoZW1hYCkge1xuXHRcdFx0XHRyZXR1cm5cblx0XHRcdH1cblx0XHRcdGNvbnN0IGNvbmZpZ1BhdGggPVxuXHRcdFx0XHRhcmdzWzBdID8/IHBhdGguam9pbihwcm9jZXNzLmN3ZCgpLCBgZmxpZ2h0ZGVjay5jb25maWcuanNvbmApXG5cdFx0XHRyZXR1cm4gY29uZmlnUGF0aFxuXHRcdH0sXG5cdH0sXG5cdGNvbnNvbGUsXG4pXG5cbmNvbnN0IHsgaW5wdXRzLCB3cml0ZUpzb25TY2hlbWEgfSA9IHBhcnNlKHByb2Nlc3MuYXJndilcblxuc3dpdGNoIChpbnB1dHMuY2FzZSkge1xuXHRjYXNlIGBzY2hlbWFgOlxuXHRcdHtcblx0XHRcdGNvbnN0IHsgb3V0ZGlyIH0gPSBpbnB1dHMub3B0c1xuXHRcdFx0d3JpdGVKc29uU2NoZW1hKG91dGRpciA/PyBgLmApXG5cdFx0fVxuXHRcdGJyZWFrXG5cdGRlZmF1bHQ6IHtcblx0XHRjb25zdCBmbGlnaHREZWNrID0gbmV3IEZsaWdodERlY2soaW5wdXRzLm9wdHMpXG5cdFx0cHJvY2Vzcy5vbihgY2xvc2VgLCBhc3luYyAoKSA9PiB7XG5cdFx0XHRhd2FpdCBmbGlnaHREZWNrLnN0b3BBbGxTZXJ2aWNlcygpXG5cdFx0fSlcblx0fVxufVxuIiwKICAgICJpbXBvcnQgeyBleGVjU3luYywgc3Bhd24gfSBmcm9tIFwibm9kZTpjaGlsZF9wcm9jZXNzXCJcbmltcG9ydCB0eXBlIHsgU2VydmVyIH0gZnJvbSBcIm5vZGU6aHR0cFwiXG5pbXBvcnQgeyBjcmVhdGVTZXJ2ZXIgfSBmcm9tIFwibm9kZTpodHRwXCJcbmltcG9ydCB7IGhvbWVkaXIgfSBmcm9tIFwibm9kZTpvc1wiXG5pbXBvcnQgeyByZXNvbHZlIH0gZnJvbSBcIm5vZGU6cGF0aFwiXG5pbXBvcnQgeyBpbnNwZWN0IH0gZnJvbSBcIm5vZGU6dXRpbFwiXG5cbmltcG9ydCB7IEZ1dHVyZSB9IGZyb20gXCJhdG9tLmlvL2ludGVybmFsXCJcbmltcG9ydCB7IGRpc2NvdmVyVHlwZSB9IGZyb20gXCJhdG9tLmlvL2ludHJvc3BlY3Rpb25cIlxuaW1wb3J0IHsgZnJvbUVudHJpZXMsIHRvRW50cmllcyB9IGZyb20gXCJhdG9tLmlvL2pzb25cIlxuaW1wb3J0IHsgQ2hpbGRTb2NrZXQgfSBmcm9tIFwiYXRvbS5pby9yZWFsdGltZS1zZXJ2ZXJcIlxuaW1wb3J0IHsgQ3JvbkpvYiB9IGZyb20gXCJjcm9uXCJcbmltcG9ydCB7IEZpbGVzeXN0ZW1TdG9yYWdlIH0gZnJvbSBcInNhZmVkZXBvc2l0XCJcbmltcG9ydCB7IHogfSBmcm9tIFwiem9kXCJcblxuaW1wb3J0IHR5cGUgeyBMbmF2Rm9ybWF0IH0gZnJvbSBcIi4uL2dlbi9sbmF2LWZvcm1hdC1zY2hlbWEuZ2VuXCJcbmltcG9ydCB7IGVudiB9IGZyb20gXCIuL2ZsaWdodGRlY2suZW52XCJcblxuZXhwb3J0IGNvbnN0IEZMSUdIVERFQ0tfU0VUVVBfUEhBU0VTID0gW2Bkb3dubG9hZGVkYCwgYGluc3RhbGxlZGBdIGFzIGNvbnN0XG5cbmV4cG9ydCB0eXBlIEZsaWdodERlY2tTZXR1cFBoYXNlID0gKHR5cGVvZiBGTElHSFRERUNLX1NFVFVQX1BIQVNFUylbbnVtYmVyXVxuXG5leHBvcnQgY29uc3QgRkxJR0hUREVDS19VUERBVEVfUEhBU0VTID0gW2Bub3RpZmllZGAsIGBjb25maXJtZWRgXSBhcyBjb25zdFxuXG5leHBvcnQgdHlwZSBGbGlnaHREZWNrVXBkYXRlUGhhc2UgPSAodHlwZW9mIEZMSUdIVERFQ0tfVVBEQVRFX1BIQVNFUylbbnVtYmVyXVxuXG5leHBvcnQgZnVuY3Rpb24gaXNWZXJzaW9uTnVtYmVyKHZlcnNpb246IHN0cmluZyk6IGJvb2xlYW4ge1xuXHRyZXR1cm4gKFxuXHRcdC9eXFxkK1xcLlxcZCtcXC5cXGQrJC8udGVzdCh2ZXJzaW9uKSB8fCAhTnVtYmVyLmlzTmFOKE51bWJlci5wYXJzZUZsb2F0KHZlcnNpb24pKVxuXHQpXG59XG5cbmV4cG9ydCB0eXBlIEZsaWdodERlY2tPcHRpb25zPFMgZXh0ZW5kcyBzdHJpbmcgPSBzdHJpbmc+ID0ge1xuXHRwYWNrYWdlTmFtZTogc3RyaW5nXG5cdHNlcnZpY2VzOiB7IFtzZXJ2aWNlIGluIFNdOiB7IHJ1bjogc3RyaW5nOyB3YWl0Rm9yOiBib29sZWFuIH0gfVxuXHRzY3JpcHRzOiB7XG5cdFx0ZG93bmxvYWQ6IHN0cmluZ1xuXHRcdGluc3RhbGw6IHN0cmluZ1xuXHRcdGNoZWNrQXZhaWxhYmlsaXR5Pzogc3RyaW5nXG5cdH1cblx0cG9ydD86IG51bWJlciB8IHVuZGVmaW5lZFxuXHRmbGlnaHRkZWNrUm9vdERpcj86IHN0cmluZyB8IHVuZGVmaW5lZFxuXHRqc29uTG9nZ2luZz86IGJvb2xlYW4gfCB1bmRlZmluZWRcbn1cblxuZXhwb3J0IGNsYXNzIEZsaWdodERlY2s8UyBleHRlbmRzIHN0cmluZyA9IHN0cmluZz4ge1xuXHRwcm90ZWN0ZWQgc2FmZXR5ID0gMFxuXG5cdHByb3RlY3RlZCBzdG9yYWdlOiBGaWxlc3lzdGVtU3RvcmFnZTx7XG5cdFx0c2V0dXBQaGFzZTogRmxpZ2h0RGVja1NldHVwUGhhc2Vcblx0XHR1cGRhdGVQaGFzZTogRmxpZ2h0RGVja1VwZGF0ZVBoYXNlXG5cdFx0dXBkYXRlQXdhaXRlZFZlcnNpb246IHN0cmluZ1xuXHR9PlxuXHRwcm90ZWN0ZWQgd2ViaG9va1NlcnZlcjogU2VydmVyXG5cdHByb3RlY3RlZCBzZXJ2aWNlczoge1xuXHRcdFtzZXJ2aWNlIGluIFNdOiBDaGlsZFNvY2tldDxcblx0XHRcdHsgdGltZVRvU3RvcDogW107IHVwZGF0ZXNSZWFkeTogW10gfSxcblx0XHRcdHsgcmVhZHlUb1VwZGF0ZTogW107IGFsaXZlOiBbXSB9XG5cdFx0PiB8IG51bGxcblx0fVxuXHRwcm90ZWN0ZWQgc2VydmljZUlkeDogeyByZWFkb25seSBbc2VydmljZSBpbiBTXTogbnVtYmVyIH1cblx0cHVibGljIGRlZmF1bHRTZXJ2aWNlc1JlYWR5VG9VcGRhdGU6IHsgcmVhZG9ubHkgW3NlcnZpY2UgaW4gU106IGJvb2xlYW4gfVxuXHRwdWJsaWMgc2VydmljZXNSZWFkeVRvVXBkYXRlOiB7IFtzZXJ2aWNlIGluIFNdOiBib29sZWFuIH1cblx0cHVibGljIGF1dG9SZXNwYXduRGVhZFNlcnZpY2VzOiBib29sZWFuXG5cblx0cHJvdGVjdGVkIGxvZ2dlcjogUGljazxDb25zb2xlLCBgZXJyb3JgIHwgYGluZm9gIHwgYHdhcm5gPlxuXHRwcm90ZWN0ZWQgc2VydmljZUxvZ2dlcnM6IHtcblx0XHRyZWFkb25seSBbc2VydmljZSBpbiBTXTogRmxpZ2h0RGVja0xvZ2dlclxuXHR9XG5cblx0cHJvdGVjdGVkIHVwZGF0ZUF2YWlsYWJpbGl0eUNoZWNrZXI6IENyb25Kb2IgfCBudWxsID0gbnVsbFxuXG5cdHB1YmxpYyBzZXJ2aWNlc0xpdmU6IEZ1dHVyZTx2b2lkPltdXG5cdHB1YmxpYyBzZXJ2aWNlc0RlYWQ6IEZ1dHVyZTx2b2lkPltdXG5cdHB1YmxpYyBsaXZlID0gbmV3IEZ1dHVyZSgoKSA9PiB7fSlcblx0cHVibGljIGRlYWQgPSBuZXcgRnV0dXJlKCgpID0+IHt9KVxuXG5cdHByb3RlY3RlZCByZXN0YXJ0VGltZXM6IG51bWJlcltdID0gW11cblxuXHRwdWJsaWMgY29uc3RydWN0b3IocHVibGljIHJlYWRvbmx5IG9wdGlvbnM6IEZsaWdodERlY2tPcHRpb25zPFM+KSB7XG5cdFx0Y29uc3QgeyBGTElHSFRERUNLX1NFQ1JFVCB9ID0gZW52XG5cdFx0Y29uc3QgeyBmbGlnaHRkZWNrUm9vdERpciA9IHJlc29sdmUoaG9tZWRpcigpLCBgLmZsaWdodGRlY2tgKSB9ID0gb3B0aW9uc1xuXHRcdGNvbnN0IHBvcnQgPSBvcHRpb25zLnBvcnQgPz8gODA4MFxuXHRcdGNvbnN0IG9yaWdpbiA9IGBodHRwOi8vbG9jYWxob3N0OiR7cG9ydH1gXG5cblx0XHRjb25zdCBzZXJ2aWNlc0VudHJpZXMgPSB0b0VudHJpZXMob3B0aW9ucy5zZXJ2aWNlcylcblx0XHR0aGlzLnNlcnZpY2VzID0gZnJvbUVudHJpZXMoXG5cdFx0XHRzZXJ2aWNlc0VudHJpZXMubWFwKChbc2VydmljZU5hbWVdKSA9PiBbc2VydmljZU5hbWUsIG51bGxdKSxcblx0XHQpXG5cdFx0dGhpcy5zZXJ2aWNlSWR4ID0gZnJvbUVudHJpZXMoXG5cdFx0XHRzZXJ2aWNlc0VudHJpZXMubWFwKChbc2VydmljZU5hbWVdLCBpZHgpID0+IFtzZXJ2aWNlTmFtZSwgaWR4XSksXG5cdFx0KVxuXHRcdHRoaXMuZGVmYXVsdFNlcnZpY2VzUmVhZHlUb1VwZGF0ZSA9IGZyb21FbnRyaWVzKFxuXHRcdFx0c2VydmljZXNFbnRyaWVzLm1hcCgoW3NlcnZpY2VOYW1lLCB7IHdhaXRGb3IgfV0pID0+IFtcblx0XHRcdFx0c2VydmljZU5hbWUsXG5cdFx0XHRcdCF3YWl0Rm9yLFxuXHRcdFx0XSksXG5cdFx0KVxuXHRcdHRoaXMuc2VydmljZXNSZWFkeVRvVXBkYXRlID0geyAuLi50aGlzLmRlZmF1bHRTZXJ2aWNlc1JlYWR5VG9VcGRhdGUgfVxuXHRcdHRoaXMuYXV0b1Jlc3Bhd25EZWFkU2VydmljZXMgPSB0cnVlXG5cblx0XHR0aGlzLmxvZ2dlciA9IG5ldyBGbGlnaHREZWNrTG9nZ2VyKFxuXHRcdFx0dGhpcy5vcHRpb25zLnBhY2thZ2VOYW1lLFxuXHRcdFx0cHJvY2Vzcy5waWQsXG5cdFx0XHR1bmRlZmluZWQsXG5cdFx0XHR7IGpzb25Mb2dnaW5nOiB0aGlzLm9wdGlvbnMuanNvbkxvZ2dpbmcgPz8gZmFsc2UgfSxcblx0XHQpXG5cdFx0dGhpcy5zZXJ2aWNlTG9nZ2VycyA9IGZyb21FbnRyaWVzKFxuXHRcdFx0c2VydmljZXNFbnRyaWVzLm1hcCgoW3NlcnZpY2VOYW1lXSkgPT4gW1xuXHRcdFx0XHRzZXJ2aWNlTmFtZSxcblx0XHRcdFx0bmV3IEZsaWdodERlY2tMb2dnZXIoXG5cdFx0XHRcdFx0dGhpcy5vcHRpb25zLnBhY2thZ2VOYW1lLFxuXHRcdFx0XHRcdHByb2Nlc3MucGlkLFxuXHRcdFx0XHRcdHNlcnZpY2VOYW1lLFxuXHRcdFx0XHRcdHsganNvbkxvZ2dpbmc6IHRoaXMub3B0aW9ucy5qc29uTG9nZ2luZyA/PyBmYWxzZSB9LFxuXHRcdFx0XHQpLFxuXHRcdFx0XSksXG5cdFx0KVxuXG5cdFx0dGhpcy5zZXJ2aWNlc0xpdmUgPSBzZXJ2aWNlc0VudHJpZXMubWFwKCgpID0+IG5ldyBGdXR1cmUoKCkgPT4ge30pKVxuXHRcdHRoaXMuc2VydmljZXNEZWFkID0gc2VydmljZXNFbnRyaWVzLm1hcCgoKSA9PiBuZXcgRnV0dXJlKCgpID0+IHt9KSlcblx0XHR0aGlzLmxpdmUudXNlKFByb21pc2UuYWxsKHRoaXMuc2VydmljZXNMaXZlKSlcblx0XHR0aGlzLmRlYWQudXNlKFByb21pc2UuYWxsKHRoaXMuc2VydmljZXNEZWFkKSlcblxuXHRcdHRoaXMuc3RvcmFnZSA9IG5ldyBGaWxlc3lzdGVtU3RvcmFnZSh7XG5cdFx0XHRwYXRoOiByZXNvbHZlKGZsaWdodGRlY2tSb290RGlyLCBgc3RvcmFnZWAsIG9wdGlvbnMucGFja2FnZU5hbWUpLFxuXHRcdH0pXG5cblx0XHRpZiAoRkxJR0hUREVDS19TRUNSRVQgPT09IHVuZGVmaW5lZCkge1xuXHRcdFx0dGhpcy5sb2dnZXIud2Fybihcblx0XHRcdFx0YE5vIEZMSUdIVERFQ0tfU0VDUkVUIGVudmlyb25tZW50IHZhcmlhYmxlIGZvdW5kLiBGbGlnaHREZWNrIHdpbGwgbm90IHJ1biBhbiB1cGRhdGUgc2VydmVyLmAsXG5cdFx0XHQpXG5cdFx0fSBlbHNlIHtcblx0XHRcdGNyZWF0ZVNlcnZlcigocmVxLCByZXMpID0+IHtcblx0XHRcdFx0bGV0IGRhdGE6IFVpbnQ4QXJyYXlbXSA9IFtdXG5cdFx0XHRcdHJlcVxuXHRcdFx0XHRcdC5vbihgZGF0YWAsIChjaHVuaykgPT4ge1xuXHRcdFx0XHRcdFx0ZGF0YS5wdXNoKGNodW5rIGluc3RhbmNlb2YgQnVmZmVyID8gY2h1bmsgOiBCdWZmZXIuZnJvbShjaHVuaykpXG5cdFx0XHRcdFx0fSlcblx0XHRcdFx0XHQub24oYGVuZGAsICgpID0+IHtcblx0XHRcdFx0XHRcdGNvbnN0IGF1dGhIZWFkZXIgPSByZXEuaGVhZGVycy5hdXRob3JpemF0aW9uXG5cdFx0XHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdFx0XHRpZiAodHlwZW9mIHJlcS51cmwgPT09IGB1bmRlZmluZWRgKSB0aHJvdyA0MDBcblx0XHRcdFx0XHRcdFx0Y29uc3QgZXhwZWN0ZWRBdXRoSGVhZGVyID0gYEJlYXJlciAke0ZMSUdIVERFQ0tfU0VDUkVUfWBcblx0XHRcdFx0XHRcdFx0aWYgKGF1dGhIZWFkZXIgIT09IGBCZWFyZXIgJHtGTElHSFRERUNLX1NFQ1JFVH1gKSB7XG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhcblx0XHRcdFx0XHRcdFx0XHRcdGBVbmF1dGhvcml6ZWQ6IG5lZWRlZCBcXGAke2V4cGVjdGVkQXV0aEhlYWRlcn1cXGAsIGdvdCBcXGAke2F1dGhIZWFkZXJ9XFxgYCxcblx0XHRcdFx0XHRcdFx0XHQpXG5cdFx0XHRcdFx0XHRcdFx0dGhyb3cgNDAxXG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0Y29uc3QgdXJsID0gbmV3IFVSTChyZXEudXJsLCBvcmlnaW4pXG5cdFx0XHRcdFx0XHRcdHRoaXMubG9nZ2VyLmluZm8ocmVxLm1ldGhvZCwgdXJsLnBhdGhuYW1lKVxuXG5cdFx0XHRcdFx0XHRcdGNvbnN0IHZlcnNpb25Gb3JlaWduSW5wdXQgPSBCdWZmZXIuY29uY2F0KGRhdGEpLnRvU3RyaW5nKClcblx0XHRcdFx0XHRcdFx0aWYgKCFpc1ZlcnNpb25OdW1iZXIodmVyc2lvbkZvcmVpZ25JbnB1dCkpIHtcblx0XHRcdFx0XHRcdFx0XHR0aHJvdyA0MDBcblx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdHJlcy53cml0ZUhlYWQoMjAwKVxuXHRcdFx0XHRcdFx0XHRyZXMuZW5kKClcblxuXHRcdFx0XHRcdFx0XHR0aGlzLnN0b3JhZ2Uuc2V0SXRlbShgdXBkYXRlUGhhc2VgLCBgbm90aWZpZWRgKVxuXHRcdFx0XHRcdFx0XHR0aGlzLnN0b3JhZ2Uuc2V0SXRlbShgdXBkYXRlQXdhaXRlZFZlcnNpb25gLCB2ZXJzaW9uRm9yZWlnbklucHV0KVxuXHRcdFx0XHRcdFx0XHRjb25zdCB7IGNoZWNrQXZhaWxhYmlsaXR5IH0gPSBvcHRpb25zLnNjcmlwdHNcblx0XHRcdFx0XHRcdFx0aWYgKGNoZWNrQXZhaWxhYmlsaXR5KSB7XG5cdFx0XHRcdFx0XHRcdFx0dGhpcy51cGRhdGVBdmFpbGFiaWxpdHlDaGVja2VyPy5zdG9wKClcblx0XHRcdFx0XHRcdFx0XHR0aGlzLnNlZWtVcGRhdGUodmVyc2lvbkZvcmVpZ25JbnB1dClcblx0XHRcdFx0XHRcdFx0XHRjb25zdCB1cGRhdGVQaGFzZSA9IHRoaXMuc3RvcmFnZS5nZXRJdGVtKGB1cGRhdGVQaGFzZWApXG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhgPiBzdG9yYWdlKFwidXBkYXRlUGhhc2VcIikgPmAsIHVwZGF0ZVBoYXNlKVxuXHRcdFx0XHRcdFx0XHRcdGlmICh1cGRhdGVQaGFzZSA9PT0gYG5vdGlmaWVkYCkge1xuXHRcdFx0XHRcdFx0XHRcdFx0dGhpcy51cGRhdGVBdmFpbGFiaWxpdHlDaGVja2VyID0gbmV3IENyb25Kb2IoXG5cdFx0XHRcdFx0XHRcdFx0XHRcdGAzMCAqICogKiAqICpgLFxuXHRcdFx0XHRcdFx0XHRcdFx0XHQoKSA9PiB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0dGhpcy5zZWVrVXBkYXRlKHZlcnNpb25Gb3JlaWduSW5wdXQpXG5cdFx0XHRcdFx0XHRcdFx0XHRcdH0sXG5cdFx0XHRcdFx0XHRcdFx0XHQpXG5cdFx0XHRcdFx0XHRcdFx0XHR0aGlzLnVwZGF0ZUF2YWlsYWJpbGl0eUNoZWNrZXIuc3RhcnQoKVxuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHR0aGlzLmRvd25sb2FkUGFja2FnZSgpXG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH0gY2F0Y2ggKHRocm93bikge1xuXHRcdFx0XHRcdFx0XHR0aGlzLmxvZ2dlci5lcnJvcih0aHJvd24sIHJlcS51cmwpXG5cdFx0XHRcdFx0XHRcdGlmICh0eXBlb2YgdGhyb3duID09PSBgbnVtYmVyYCkge1xuXHRcdFx0XHRcdFx0XHRcdHJlcy53cml0ZUhlYWQodGhyb3duKVxuXHRcdFx0XHRcdFx0XHRcdHJlcy5lbmQoKVxuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9IGZpbmFsbHkge1xuXHRcdFx0XHRcdFx0XHRkYXRhID0gW11cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9KVxuXHRcdFx0fSkubGlzdGVuKHBvcnQsICgpID0+IHtcblx0XHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhgU2VydmVyIHN0YXJ0ZWQgb24gcG9ydCAke3BvcnR9YClcblx0XHRcdH0pXG5cdFx0fVxuXG5cdFx0dGhpcy5zdGFydEFsbFNlcnZpY2VzKClcblx0XHRcdC50aGVuKCgpID0+IHtcblx0XHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhgQWxsIHNlcnZpY2VzIHN0YXJ0ZWQuYClcblx0XHRcdH0pXG5cdFx0XHQuY2F0Y2goKHRocm93bikgPT4ge1xuXHRcdFx0XHRpZiAodGhyb3duIGluc3RhbmNlb2YgRXJyb3IpIHtcblx0XHRcdFx0XHR0aGlzLmxvZ2dlci5lcnJvcihgRmFpbGVkIHRvIHN0YXJ0IGFsbCBzZXJ2aWNlczpgLCB0aHJvd24ubWVzc2FnZSlcblx0XHRcdFx0fVxuXHRcdFx0fSlcblx0fVxuXG5cdHByb3RlY3RlZCBzZWVrVXBkYXRlKHZlcnNpb246IHN0cmluZyk6IHZvaWQge1xuXHRcdHRoaXMubG9nZ2VyLmluZm8oYENoZWNraW5nIGZvciB1cGRhdGVzLi4uYClcblx0XHRjb25zdCB7IGNoZWNrQXZhaWxhYmlsaXR5IH0gPSB0aGlzLm9wdGlvbnMuc2NyaXB0c1xuXHRcdGlmICghY2hlY2tBdmFpbGFiaWxpdHkpIHtcblx0XHRcdHRoaXMubG9nZ2VyLmluZm8oYE5vIGNoZWNrQXZhaWxhYmlsaXR5IHNjcmlwdCBmb3VuZC5gKVxuXHRcdFx0cmV0dXJuXG5cdFx0fVxuXHRcdHRyeSB7XG5cdFx0XHRjb25zdCBvdXQgPSBleGVjU3luYyhgJHtjaGVja0F2YWlsYWJpbGl0eX0gJHt2ZXJzaW9ufWApXG5cdFx0XHR0aGlzLmxvZ2dlci5pbmZvKGBDaGVjayBzdGRvdXQ6YCwgb3V0LnRvU3RyaW5nKCkpXG5cdFx0XHR0aGlzLnVwZGF0ZUF2YWlsYWJpbGl0eUNoZWNrZXI/LnN0b3AoKVxuXHRcdFx0dGhpcy5zdG9yYWdlLnNldEl0ZW0oYHVwZGF0ZVBoYXNlYCwgYGNvbmZpcm1lZGApXG5cdFx0XHR0aGlzLmRvd25sb2FkUGFja2FnZSgpXG5cdFx0XHR0aGlzLmFubm91bmNlVXBkYXRlKClcblx0XHR9IGNhdGNoICh0aHJvd24pIHtcblx0XHRcdGlmICh0aHJvd24gaW5zdGFuY2VvZiBFcnJvcikge1xuXHRcdFx0XHR0aGlzLmxvZ2dlci5lcnJvcihgQ2hlY2sgZmFpbGVkOmAsIHRocm93bi5tZXNzYWdlKVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Y29uc3QgdGhyb3duVHlwZSA9IGRpc2NvdmVyVHlwZSh0aHJvd24pXG5cdFx0XHRcdHRoaXMubG9nZ2VyLmVycm9yKGBDaGVjayB0aHJld2AsIHRocm93blR5cGUsIHRocm93bilcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRwcm90ZWN0ZWQgYW5ub3VuY2VVcGRhdGUoKTogdm9pZCB7XG5cdFx0Zm9yIChjb25zdCBlbnRyeSBvZiB0b0VudHJpZXModGhpcy5zZXJ2aWNlcykpIHtcblx0XHRcdGNvbnN0IFtzZXJ2aWNlTmFtZSwgc2VydmljZV0gPSBlbnRyeVxuXHRcdFx0aWYgKHNlcnZpY2UpIHtcblx0XHRcdFx0aWYgKHRoaXMub3B0aW9ucy5zZXJ2aWNlc1tzZXJ2aWNlTmFtZV0ud2FpdEZvcikge1xuXHRcdFx0XHRcdHNlcnZpY2UuZW1pdChgdXBkYXRlc1JlYWR5YClcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dGhpcy5zdGFydFNlcnZpY2Uoc2VydmljZU5hbWUpXG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0cHJvdGVjdGVkIHRyeVVwZGF0ZSgpOiB2b2lkIHtcblx0XHRpZiAodG9FbnRyaWVzKHRoaXMuc2VydmljZXNSZWFkeVRvVXBkYXRlKS5ldmVyeSgoWywgaXNSZWFkeV0pID0+IGlzUmVhZHkpKSB7XG5cdFx0XHR0aGlzLmxvZ2dlci5pbmZvKGBBbGwgc2VydmljZXMgYXJlIHJlYWR5IHRvIHVwZGF0ZS5gKVxuXHRcdFx0dGhpcy5zdG9wQWxsU2VydmljZXMoKVxuXHRcdFx0XHQudGhlbigoKSA9PiB7XG5cdFx0XHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhgQWxsIHNlcnZpY2VzIHN0b3BwZWQ7IHN0YXJ0aW5nIHVwIGZyZXNoLi4uYClcblx0XHRcdFx0XHR0aGlzLnN0YXJ0QWxsU2VydmljZXMoKVxuXHRcdFx0XHRcdFx0LnRoZW4oKCkgPT4ge1xuXHRcdFx0XHRcdFx0XHR0aGlzLmxvZ2dlci5pbmZvKGBBbGwgc2VydmljZXMgc3RhcnRlZDsgd2UncmUgYmFjayBvbmxpbmUuYClcblx0XHRcdFx0XHRcdH0pXG5cdFx0XHRcdFx0XHQuY2F0Y2goKHRocm93bikgPT4ge1xuXHRcdFx0XHRcdFx0XHRpZiAodGhyb3duIGluc3RhbmNlb2YgRXJyb3IpIHtcblx0XHRcdFx0XHRcdFx0XHR0aGlzLmxvZ2dlci5lcnJvcihcblx0XHRcdFx0XHRcdFx0XHRcdGBGYWlsZWQgdG8gc3RhcnQgYWxsIHNlcnZpY2VzOmAsXG5cdFx0XHRcdFx0XHRcdFx0XHR0aHJvd24ubWVzc2FnZSxcblx0XHRcdFx0XHRcdFx0XHQpXG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH0pXG5cdFx0XHRcdH0pXG5cdFx0XHRcdC5jYXRjaCgodGhyb3duKSA9PiB7XG5cdFx0XHRcdFx0aWYgKHRocm93biBpbnN0YW5jZW9mIEVycm9yKSB7XG5cdFx0XHRcdFx0XHR0aGlzLmxvZ2dlci5lcnJvcihgRmFpbGVkIHRvIHN0b3AgYWxsIHNlcnZpY2VzOmAsIHRocm93bi5tZXNzYWdlKVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSlcblx0XHR9XG5cdH1cblxuXHRwcm90ZWN0ZWQgc3RhcnRBbGxTZXJ2aWNlcygpOiBGdXR1cmU8dW5rbm93bj4ge1xuXHRcdHRoaXMubG9nZ2VyLmluZm8oYFN0YXJ0aW5nIGFsbCBzZXJ2aWNlcy4uLmApXG5cdFx0dGhpcy5hdXRvUmVzcGF3bkRlYWRTZXJ2aWNlcyA9IHRydWVcblx0XHRjb25zdCBzZXR1cFBoYXNlID0gdGhpcy5zdG9yYWdlLmdldEl0ZW0oYHNldHVwUGhhc2VgKVxuXHRcdHRoaXMubG9nZ2VyLmluZm8oYD4gc3RvcmFnZShcInNldHVwUGhhc2VcIikgPmAsIHNldHVwUGhhc2UpXG5cdFx0c3dpdGNoIChzZXR1cFBoYXNlKSB7XG5cdFx0XHRjYXNlIG51bGw6XG5cdFx0XHRcdHRoaXMubG9nZ2VyLmluZm8oYFN0YXJ0aW5nIGZyb20gc2NyYXRjaC5gKVxuXHRcdFx0XHR0aGlzLmRvd25sb2FkUGFja2FnZSgpXG5cdFx0XHRcdHRoaXMuaW5zdGFsbFBhY2thZ2UoKVxuXHRcdFx0XHRyZXR1cm4gdGhpcy5zdGFydEFsbFNlcnZpY2VzKClcblx0XHRcdGNhc2UgYGRvd25sb2FkZWRgOlxuXHRcdFx0XHR0aGlzLmxvZ2dlci5pbmZvKGBGb3VuZCBwYWNrYWdlIGRvd25sb2FkZWQgYnV0IG5vdCBpbnN0YWxsZWQuYClcblx0XHRcdFx0dGhpcy5pbnN0YWxsUGFja2FnZSgpXG5cdFx0XHRcdHJldHVybiB0aGlzLnN0YXJ0QWxsU2VydmljZXMoKVxuXHRcdFx0Y2FzZSBgaW5zdGFsbGVkYDoge1xuXHRcdFx0XHRmb3IgKGNvbnN0IFtzZXJ2aWNlTmFtZV0gb2YgdG9FbnRyaWVzKHRoaXMuc2VydmljZXMpKSB7XG5cdFx0XHRcdFx0dGhpcy5zdGFydFNlcnZpY2Uoc2VydmljZU5hbWUpXG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHRoaXMubGl2ZVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHByb3RlY3RlZCBzdGFydFNlcnZpY2Uoc2VydmljZU5hbWU6IFMpOiB2b2lkIHtcblx0XHR0aGlzLmxvZ2dlci5pbmZvKFxuXHRcdFx0YFN0YXJ0aW5nIHNlcnZpY2UgJHt0aGlzLm9wdGlvbnMucGFja2FnZU5hbWV9Ojoke3NlcnZpY2VOYW1lfSwgdHJ5ICR7dGhpcy5zYWZldHl9LzIuLi5gLFxuXHRcdClcblx0XHRpZiAodGhpcy5zYWZldHkgPj0gMikge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKGBPdXQgb2YgdHJpZXMuLi5gKVxuXHRcdH1cblx0XHR0aGlzLnNhZmV0eSsrXG5cblx0XHRjb25zdCBbZXhlLCAuLi5hcmdzXSA9IHRoaXMub3B0aW9ucy5zZXJ2aWNlc1tzZXJ2aWNlTmFtZV0ucnVuLnNwbGl0KGAgYClcblx0XHRjb25zdCBzZXJ2aWNlUHJvY2VzcyA9IHNwYXduKGV4ZSwgYXJncywge1xuXHRcdFx0Y3dkOiB0aGlzLm9wdGlvbnMuZmxpZ2h0ZGVja1Jvb3REaXIsXG5cdFx0XHRlbnY6IGltcG9ydC5tZXRhLmVudixcblx0XHR9KVxuXHRcdGNvbnN0IHNlcnZpY2VMb2dnZXIgPSB0aGlzLnNlcnZpY2VMb2dnZXJzW3NlcnZpY2VOYW1lXVxuXHRcdGNvbnN0IHNlcnZpY2UgPSAodGhpcy5zZXJ2aWNlc1tzZXJ2aWNlTmFtZV0gPSBuZXcgQ2hpbGRTb2NrZXQoXG5cdFx0XHRzZXJ2aWNlUHJvY2Vzcyxcblx0XHRcdGAke3RoaXMub3B0aW9ucy5wYWNrYWdlTmFtZX06OiR7c2VydmljZU5hbWV9YCxcblx0XHRcdHNlcnZpY2VMb2dnZXIsXG5cdFx0KSlcblx0XHRzZXJ2aWNlTG9nZ2VyLnByb2Nlc3NDb2RlID0gc2VydmljZS5wcm9jZXNzLnBpZCA/PyAtMVxuXHRcdHRoaXMuc2VydmljZXNbc2VydmljZU5hbWVdLm9uQW55KCguLi5tZXNzYWdlcykgPT4ge1xuXHRcdFx0c2VydmljZUxvZ2dlci5pbmZvKGDwn5KsYCwgLi4ubWVzc2FnZXMpXG5cdFx0fSlcblx0XHR0aGlzLnNlcnZpY2VzW3NlcnZpY2VOYW1lXS5vbihgcmVhZHlUb1VwZGF0ZWAsICgpID0+IHtcblx0XHRcdHRoaXMubG9nZ2VyLmluZm8oYFNlcnZpY2UgXCIke3NlcnZpY2VOYW1lfVwiIGlzIHJlYWR5IHRvIHVwZGF0ZS5gKVxuXHRcdFx0dGhpcy5zZXJ2aWNlc1JlYWR5VG9VcGRhdGVbc2VydmljZU5hbWVdID0gdHJ1ZVxuXHRcdFx0dGhpcy50cnlVcGRhdGUoKVxuXHRcdH0pXG5cdFx0dGhpcy5zZXJ2aWNlc1tzZXJ2aWNlTmFtZV0ub24oYGFsaXZlYCwgKCkgPT4ge1xuXHRcdFx0dGhpcy5zZXJ2aWNlc0xpdmVbdGhpcy5zZXJ2aWNlSWR4W3NlcnZpY2VOYW1lXV0udXNlKFByb21pc2UucmVzb2x2ZSgpKVxuXHRcdFx0dGhpcy5zZXJ2aWNlc0RlYWRbdGhpcy5zZXJ2aWNlSWR4W3NlcnZpY2VOYW1lXV0gPSBuZXcgRnV0dXJlKCgpID0+IHt9KVxuXHRcdFx0aWYgKHRoaXMuZGVhZC5kb25lKSB7XG5cdFx0XHRcdHRoaXMuZGVhZCA9IG5ldyBGdXR1cmUoKCkgPT4ge30pXG5cdFx0XHR9XG5cdFx0XHR0aGlzLmRlYWQudXNlKFByb21pc2UuYWxsKHRoaXMuc2VydmljZXNEZWFkKSlcblx0XHR9KVxuXHRcdHRoaXMuc2VydmljZXNbc2VydmljZU5hbWVdLnByb2Nlc3Mub25jZShgY2xvc2VgLCAoZXhpdENvZGUpID0+IHtcblx0XHRcdHRoaXMubG9nZ2VyLmluZm8oXG5cdFx0XHRcdGBBdXRvLXJlc3Bhd24gc2F3IFwiJHtzZXJ2aWNlTmFtZX1cIiBleGl0IHdpdGggY29kZSAke2V4aXRDb2RlfWAsXG5cdFx0XHQpXG5cdFx0XHR0aGlzLnNlcnZpY2VzW3NlcnZpY2VOYW1lXSA9IG51bGxcblx0XHRcdGlmICghdGhpcy5hdXRvUmVzcGF3bkRlYWRTZXJ2aWNlcykge1xuXHRcdFx0XHR0aGlzLmxvZ2dlci5pbmZvKGBBdXRvLXJlc3Bhd24gaXMgb2ZmOyBcIiR7c2VydmljZU5hbWV9XCIgcmVzdHMuYClcblx0XHRcdFx0cmV0dXJuXG5cdFx0XHR9XG5cdFx0XHRjb25zdCB1cGRhdGVQaGFzZSA9IHRoaXMuc3RvcmFnZS5nZXRJdGVtKGB1cGRhdGVQaGFzZWApXG5cdFx0XHR0aGlzLmxvZ2dlci5pbmZvKGA+IHN0b3JhZ2UoXCJ1cGRhdGVQaGFzZVwiKSA+YCwgdXBkYXRlUGhhc2UpXG5cdFx0XHRjb25zdCB1cGRhdGVzQXJlUmVhZHkgPSB1cGRhdGVQaGFzZSA9PT0gYGNvbmZpcm1lZGBcblx0XHRcdGlmICh1cGRhdGVzQXJlUmVhZHkpIHtcblx0XHRcdFx0dGhpcy5zZXJ2aWNlTG9nZ2Vyc1tzZXJ2aWNlTmFtZV0uaW5mbyhgVXBkYXRpbmcgYmVmb3JlIHN0YXJ0dXAuLi5gKVxuXHRcdFx0XHR0aGlzLnJlc3RhcnRUaW1lcyA9IFtdXG5cdFx0XHRcdHRoaXMuaW5zdGFsbFBhY2thZ2UoKVxuXHRcdFx0XHR0aGlzLnN0YXJ0U2VydmljZShzZXJ2aWNlTmFtZSlcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGNvbnN0IG5vdyA9IERhdGUubm93KClcblx0XHRcdFx0Y29uc3QgZml2ZU1pbnV0ZXNBZ28gPSBub3cgLSA1ICogNjAgKiAxMDAwXG5cdFx0XHRcdHRoaXMucmVzdGFydFRpbWVzID0gdGhpcy5yZXN0YXJ0VGltZXMuZmlsdGVyKFxuXHRcdFx0XHRcdCh0aW1lKSA9PiB0aW1lID4gZml2ZU1pbnV0ZXNBZ28sXG5cdFx0XHRcdClcblx0XHRcdFx0dGhpcy5yZXN0YXJ0VGltZXMucHVzaChub3cpXG5cblx0XHRcdFx0aWYgKHRoaXMucmVzdGFydFRpbWVzLmxlbmd0aCA8IDUpIHtcblx0XHRcdFx0XHR0aGlzLnNlcnZpY2VMb2dnZXJzW3NlcnZpY2VOYW1lXS5pbmZvKGBDcmFzaGVkLiBSZXN0YXJ0aW5nLi4uYClcblx0XHRcdFx0XHR0aGlzLnN0YXJ0U2VydmljZShzZXJ2aWNlTmFtZSlcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHR0aGlzLnNlcnZpY2VMb2dnZXJzW3NlcnZpY2VOYW1lXS5pbmZvKFxuXHRcdFx0XHRcdFx0YENyYXNoZWQgNSB0aW1lcyBpbiA1IG1pbnV0ZXMuIE5vdCByZXN0YXJ0aW5nLmAsXG5cdFx0XHRcdFx0KVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSlcblx0XHR0aGlzLnNhZmV0eSA9IDBcblx0fVxuXG5cdHByb3RlY3RlZCBkb3dubG9hZFBhY2thZ2UoKTogdm9pZCB7XG5cdFx0dGhpcy5sb2dnZXIuaW5mbyhgRG93bmxvYWRpbmcuLi5gKVxuXHRcdHRyeSB7XG5cdFx0XHRjb25zdCBvdXQgPSBleGVjU3luYyh0aGlzLm9wdGlvbnMuc2NyaXB0cy5kb3dubG9hZClcblx0XHRcdHRoaXMubG9nZ2VyLmluZm8oYERvd25sb2FkIHN0ZG91dDpgLCBvdXQudG9TdHJpbmcoKSlcblx0XHRcdHRoaXMuc3RvcmFnZS5zZXRJdGVtKGBzZXR1cFBoYXNlYCwgYGRvd25sb2FkZWRgKVxuXHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhgRG93bmxvYWRlZCFgKVxuXHRcdH0gY2F0Y2ggKHRocm93bikge1xuXHRcdFx0aWYgKHRocm93biBpbnN0YW5jZW9mIEVycm9yKSB7XG5cdFx0XHRcdHRoaXMubG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gZ2V0IHRoZSBsYXRlc3QgcmVsZWFzZTogJHt0aHJvd24ubWVzc2FnZX1gKVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuXG5cdFx0fVxuXHR9XG5cblx0cHJvdGVjdGVkIGluc3RhbGxQYWNrYWdlKCk6IHZvaWQge1xuXHRcdHRoaXMubG9nZ2VyLmluZm8oYEluc3RhbGxpbmcuLi5gKVxuXG5cdFx0dHJ5IHtcblx0XHRcdGNvbnN0IG91dCA9IGV4ZWNTeW5jKHRoaXMub3B0aW9ucy5zY3JpcHRzLmluc3RhbGwpXG5cdFx0XHR0aGlzLmxvZ2dlci5pbmZvKGBJbnN0YWxsIHN0ZG91dDpgLCBvdXQudG9TdHJpbmcoKSlcblx0XHRcdHRoaXMuc3RvcmFnZS5zZXRJdGVtKGBzZXR1cFBoYXNlYCwgYGluc3RhbGxlZGApXG5cdFx0XHR0aGlzLmxvZ2dlci5pbmZvKGBJbnN0YWxsZWQhYClcblx0XHR9IGNhdGNoICh0aHJvd24pIHtcblx0XHRcdGlmICh0aHJvd24gaW5zdGFuY2VvZiBFcnJvcikge1xuXHRcdFx0XHR0aGlzLmxvZ2dlci5lcnJvcihgRmFpbGVkIHRvIGdldCB0aGUgbGF0ZXN0IHJlbGVhc2U6ICR7dGhyb3duLm1lc3NhZ2V9YClcblx0XHRcdH1cblx0XHRcdHJldHVyblxuXHRcdH1cblx0fVxuXG5cdHB1YmxpYyBzdG9wQWxsU2VydmljZXMoKTogRnV0dXJlPHVua25vd24+IHtcblx0XHR0aGlzLmxvZ2dlci5pbmZvKGBTdG9wcGluZyBhbGwgc2VydmljZXMuLi4gYXV0by1yZXNwYXduIGRpc2FibGVkLmApXG5cdFx0dGhpcy5hdXRvUmVzcGF3bkRlYWRTZXJ2aWNlcyA9IGZhbHNlXG5cdFx0Zm9yIChjb25zdCBbc2VydmljZU5hbWVdIG9mIHRvRW50cmllcyh0aGlzLnNlcnZpY2VzKSkge1xuXHRcdFx0dGhpcy5zdG9wU2VydmljZShzZXJ2aWNlTmFtZSlcblx0XHR9XG5cdFx0cmV0dXJuIHRoaXMuZGVhZFxuXHR9XG5cblx0cHVibGljIHN0b3BTZXJ2aWNlKHNlcnZpY2VOYW1lOiBTKTogdm9pZCB7XG5cdFx0Y29uc3Qgc2VydmljZSA9IHRoaXMuc2VydmljZXNbc2VydmljZU5hbWVdXG5cdFx0aWYgKHNlcnZpY2UpIHtcblx0XHRcdHRoaXMubG9nZ2VyLmluZm8oYFN0b3BwaW5nIHNlcnZpY2UgXCIke3NlcnZpY2VOYW1lfVwiLi4uYClcblx0XHRcdHRoaXMuc2VydmljZXNEZWFkW3RoaXMuc2VydmljZUlkeFtzZXJ2aWNlTmFtZV1dLnVzZShcblx0XHRcdFx0bmV3IFByb21pc2UoKHBhc3MpID0+IHtcblx0XHRcdFx0XHRzZXJ2aWNlLmVtaXQoYHRpbWVUb1N0b3BgKVxuXHRcdFx0XHRcdHNlcnZpY2UucHJvY2Vzcy5vbmNlKGBjbG9zZWAsIChleGl0Q29kZSkgPT4ge1xuXHRcdFx0XHRcdFx0dGhpcy5sb2dnZXIuaW5mbyhcblx0XHRcdFx0XHRcdFx0YFN0b3BwZWQgc2VydmljZSBcIiR7c2VydmljZU5hbWV9XCI7IGV4aXRlZCB3aXRoIGNvZGUgJHtleGl0Q29kZX1gLFxuXHRcdFx0XHRcdFx0KVxuXHRcdFx0XHRcdFx0dGhpcy5zZXJ2aWNlc1tzZXJ2aWNlTmFtZV0gPSBudWxsXG5cdFx0XHRcdFx0XHRwYXNzKClcblx0XHRcdFx0XHR9KVxuXHRcdFx0XHR9KSxcblx0XHRcdClcblx0XHRcdHRoaXMuZGVhZC51c2UoUHJvbWlzZS5hbGwodGhpcy5zZXJ2aWNlc0RlYWQpKVxuXHRcdFx0dGhpcy5zZXJ2aWNlc0xpdmVbdGhpcy5zZXJ2aWNlSWR4W3NlcnZpY2VOYW1lXV0gPSBuZXcgRnV0dXJlKCgpID0+IHt9KVxuXHRcdFx0aWYgKHRoaXMubGl2ZS5kb25lKSB7XG5cdFx0XHRcdHRoaXMubGl2ZSA9IG5ldyBGdXR1cmUoKCkgPT4ge30pXG5cdFx0XHR9XG5cdFx0XHR0aGlzLmxpdmUudXNlKFByb21pc2UuYWxsKHRoaXMuc2VydmljZXNMaXZlKSlcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhpcy5zZXJ2aWNlTG9nZ2Vyc1tzZXJ2aWNlTmFtZV0uZXJyb3IoXG5cdFx0XHRcdGBUcmllZCB0byBzdG9wIHNlcnZpY2UsIGJ1dCBpdCB3YXNuJ3QgcnVubmluZy5gLFxuXHRcdFx0KVxuXHRcdH1cblx0fVxufVxuXG5leHBvcnQgY29uc3QgRkxJR0hUREVDS19JTkZPID0gYGluZm9gXG5leHBvcnQgY29uc3QgRkxJR0hUREVDS19XQVJOID0gYHdhcm5gXG5leHBvcnQgY29uc3QgRkxJR0hUREVDS19FUlJPUiA9IGBFUlIhYFxuXG5leHBvcnQgY29uc3QgZmxpZ2h0RGVja0xvZ1NjaGVtYSA9IHoub2JqZWN0KHtcblx0bGV2ZWw6IHoudW5pb24oW1xuXHRcdHoubGl0ZXJhbChGTElHSFRERUNLX0lORk8pLFxuXHRcdHoubGl0ZXJhbChGTElHSFRERUNLX1dBUk4pLFxuXHRcdHoubGl0ZXJhbChGTElHSFRERUNLX0VSUk9SKSxcblx0XSksXG5cdHRpbWVzdGFtcDogei5udW1iZXIoKSxcblx0cGFja2FnZTogei5zdHJpbmcoKSxcblx0c2VydmljZTogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuXHRwcm9jZXNzOiB6Lm51bWJlcigpLFxuXHRib2R5OiB6LnN0cmluZygpLFxufSlcbmV4cG9ydCB0eXBlIEZsaWdodERlY2tMb2cgPSB6LmluZmVyPHR5cGVvZiBmbGlnaHREZWNrTG9nU2NoZW1hPlxuXG5jb25zdCBMSU5FX0ZPUk1BVCA9IGBsaW5lLWZvcm1hdGAgc2F0aXNmaWVzIGtleW9mIExuYXZGb3JtYXRcbmNvbnN0IFZBTFVFID0gYHZhbHVlYCBzYXRpc2ZpZXMga2V5b2YgTG5hdkZvcm1hdFxuXG5leHBvcnQgdHlwZSBMbmF2Rm9ybWF0VmlzdWFsQ29tcG9uZW50ID0gRXhjbHVkZTxcblx0RXhjbHVkZTxMbmF2Rm9ybWF0W2BsaW5lLWZvcm1hdGBdLCB1bmRlZmluZWQ+W251bWJlcl0sXG5cdHN0cmluZ1xuPlxuXG5leHBvcnQgdHlwZSBMbmF2Rm9ybWF0QnJlYWtkb3duID0gRXhjbHVkZTxMbmF2Rm9ybWF0W2B2YWx1ZWBdLCB1bmRlZmluZWQ+XG5leHBvcnQgdHlwZSBNZW1iZXJPZjxUPiA9IFRba2V5b2YgVF1cbmV4cG9ydCB0eXBlIExuYXZGb3JtYXRWYWx1ZURlZmluaXRpb24gPSBNZW1iZXJPZjxMbmF2Rm9ybWF0QnJlYWtkb3duPlxuXG5leHBvcnQgdHlwZSBGbGlnaHREZWNrRm9ybWF0ID0ge1xuXHRbTElORV9GT1JNQVRdOiAoXG5cdFx0fCBzdHJpbmdcblx0XHR8IChMbmF2Rm9ybWF0VmlzdWFsQ29tcG9uZW50ICYge1xuXHRcdFx0XHRmaWVsZDoga2V5b2YgRmxpZ2h0RGVja0xvZyB8IGBfX2xldmVsX19gIHwgYF9fdGltZXN0YW1wX19gXG5cdFx0ICB9KVxuXHQpW11cblx0W1ZBTFVFXToge1xuXHRcdFtLIGluIGtleW9mIEZsaWdodERlY2tMb2ddOiBMbmF2Rm9ybWF0VmFsdWVEZWZpbml0aW9uICYge1xuXHRcdFx0a2luZDogRmxpZ2h0RGVja0xvZ1tLXSBleHRlbmRzIG51bWJlciB8IHVuZGVmaW5lZFxuXHRcdFx0XHQ/IGBpbnRlZ2VyYFxuXHRcdFx0XHQ6IEZsaWdodERlY2tMb2dbS10gZXh0ZW5kcyBzdHJpbmcgfCB1bmRlZmluZWRcblx0XHRcdFx0XHQ/IGBzdHJpbmdgXG5cdFx0XHRcdFx0OiBuZXZlclxuXHRcdH1cblx0fVxufVxuXG5leHBvcnQgY29uc3QgRkxJR0hUREVDS19MTkFWX0ZPUk1BVCA9IHtcblx0dGl0bGU6IGBGbGlnaHREZWNrIExvZ2AsXG5cdGRlc2NyaXB0aW9uOiBgRm9ybWF0IGZvciBldmVudHMgbG9nZ2VkIGJ5IHRoZSBGbGlnaHREZWNrIHByb2Nlc3MgbWFuYWdlci5gLFxuXHRcImZpbGUtdHlwZVwiOiBganNvbmAsXG5cdFwidGltZXN0YW1wLWZpZWxkXCI6IGB0aW1lc3RhbXBgLFxuXHRcInRpbWVzdGFtcC1kaXZpc29yXCI6IDEwMDAsXG5cdFwibW9kdWxlLWZpZWxkXCI6IGBwYWNrYWdlYCxcblx0XCJvcGlkLWZpZWxkXCI6IGBzZXJ2aWNlYCxcblx0XCJsZXZlbC1maWVsZFwiOiBgbGV2ZWxgLFxuXHRsZXZlbDoge1xuXHRcdGluZm86IEZMSUdIVERFQ0tfSU5GTyxcblx0XHR3YXJuaW5nOiBGTElHSFRERUNLX1dBUk4sXG5cdFx0ZXJyb3I6IEZMSUdIVERFQ0tfRVJST1IsXG5cdH0sXG5cblx0W0xJTkVfRk9STUFUXTogW1xuXHRcdHtcblx0XHRcdGZpZWxkOiBgbGV2ZWxgLFxuXHRcdH0sXG5cdFx0e1xuXHRcdFx0cHJlZml4OiBgIGAsXG5cdFx0XHRmaWVsZDogYF9fdGltZXN0YW1wX19gLFxuXHRcdFx0XCJ0aW1lc3RhbXAtZm9ybWF0XCI6IGAlWS0lbS0lZFQlSDolTTolUy4lTCVaYCxcblx0XHR9LFxuXHRcdHtcblx0XHRcdHByZWZpeDogYCBgLFxuXHRcdFx0ZmllbGQ6IGBwcm9jZXNzYCxcblx0XHRcdFwibWluLXdpZHRoXCI6IDUsXG5cdFx0fSxcblx0XHR7XG5cdFx0XHRwcmVmaXg6IGA6YCxcblx0XHRcdGZpZWxkOiBgcGFja2FnZWAsXG5cdFx0fSxcblx0XHR7XG5cdFx0XHRwcmVmaXg6IGA6YCxcblx0XHRcdGZpZWxkOiBgc2VydmljZWAsXG5cdFx0XHRcImRlZmF1bHQtdmFsdWVcIjogYGAsXG5cdFx0fSxcblx0XHR7XG5cdFx0XHRwcmVmaXg6IGA6IGAsXG5cdFx0XHRmaWVsZDogYGJvZHlgLFxuXHRcdH0sXG5cdF0sXG5cblx0W1ZBTFVFXToge1xuXHRcdHRpbWVzdGFtcDoge1xuXHRcdFx0a2luZDogYGludGVnZXJgLFxuXHRcdH0sXG5cdFx0bGV2ZWw6IHtcblx0XHRcdGtpbmQ6IGBzdHJpbmdgLFxuXHRcdH0sXG5cdFx0cGFja2FnZToge1xuXHRcdFx0a2luZDogYHN0cmluZ2AsXG5cdFx0fSxcblx0XHRzZXJ2aWNlOiB7XG5cdFx0XHRraW5kOiBgc3RyaW5nYCxcblx0XHR9LFxuXHRcdHByb2Nlc3M6IHtcblx0XHRcdGtpbmQ6IGBpbnRlZ2VyYCxcblx0XHR9LFxuXHRcdGJvZHk6IHtcblx0XHRcdGtpbmQ6IGBzdHJpbmdgLFxuXHRcdH0sXG5cdH0sXG59IGFzIGNvbnN0IHNhdGlzZmllcyBGbGlnaHREZWNrRm9ybWF0ICYgTG5hdkZvcm1hdFxuXG5leHBvcnQgY2xhc3MgRmxpZ2h0RGVja0xvZ2dlclxuXHRpbXBsZW1lbnRzIFBpY2s8Q29uc29sZSwgYGVycm9yYCB8IGBpbmZvYCB8IGB3YXJuYD5cbntcblx0cHVibGljIHJlYWRvbmx5IHBhY2thZ2VOYW1lOiBzdHJpbmdcblx0cHVibGljIHJlYWRvbmx5IHNlcnZpY2VOYW1lPzogc3RyaW5nXG5cdHB1YmxpYyByZWFkb25seSBqc29uTG9nZ2luZzogYm9vbGVhblxuXHRwdWJsaWMgcHJvY2Vzc0NvZGU6IG51bWJlclxuXHRwdWJsaWMgY29uc3RydWN0b3IoXG5cdFx0cGFja2FnZU5hbWU6IHN0cmluZyxcblx0XHRwcm9jZXNzQ29kZTogbnVtYmVyLFxuXHRcdHNlcnZpY2VOYW1lPzogc3RyaW5nLFxuXHRcdG9wdGlvbnM/OiB7IGpzb25Mb2dnaW5nOiBib29sZWFuIH0sXG5cdCkge1xuXHRcdHRoaXMucGFja2FnZU5hbWUgPSBwYWNrYWdlTmFtZVxuXHRcdGlmIChzZXJ2aWNlTmFtZSkge1xuXHRcdFx0dGhpcy5zZXJ2aWNlTmFtZSA9IHNlcnZpY2VOYW1lXG5cdFx0fVxuXHRcdHRoaXMucHJvY2Vzc0NvZGUgPSBwcm9jZXNzQ29kZVxuXHRcdHRoaXMuanNvbkxvZ2dpbmcgPSBvcHRpb25zPy5qc29uTG9nZ2luZyA/PyBmYWxzZVxuXHR9XG5cdHByb3RlY3RlZCBsb2coXG5cdFx0bGV2ZWw6XG5cdFx0XHR8IHR5cGVvZiBGTElHSFRERUNLX0VSUk9SXG5cdFx0XHR8IHR5cGVvZiBGTElHSFRERUNLX0lORk9cblx0XHRcdHwgdHlwZW9mIEZMSUdIVERFQ0tfV0FSTixcblx0XHQuLi5tZXNzYWdlczogdW5rbm93bltdXG5cdCk6IHZvaWQge1xuXHRcdGlmICh0aGlzLmpzb25Mb2dnaW5nKSB7XG5cdFx0XHRsZXQgYm9keSA9IG1lc3NhZ2VzXG5cdFx0XHRcdC5tYXAoKG1lc3NhZ2UpID0+XG5cdFx0XHRcdFx0dHlwZW9mIG1lc3NhZ2UgPT09IGBzdHJpbmdgXG5cdFx0XHRcdFx0XHQ/IG1lc3NhZ2Vcblx0XHRcdFx0XHRcdDogaW5zcGVjdChtZXNzYWdlLCBmYWxzZSwgbnVsbCwgdHJ1ZSksXG5cdFx0XHRcdClcblx0XHRcdFx0LmpvaW4oYCBgKVxuXHRcdFx0aWYgKGJvZHkuaW5jbHVkZXMoYFxcbmApKSB7XG5cdFx0XHRcdGJvZHkgPSBgXFxuICAke2JvZHkuc3BsaXQoYFxcbmApLmpvaW4oYFxcbiAgYCl9YFxuXHRcdFx0fVxuXHRcdFx0Y29uc3QgbG9nOiBGbGlnaHREZWNrTG9nID0ge1xuXHRcdFx0XHR0aW1lc3RhbXA6IERhdGUubm93KCksXG5cdFx0XHRcdGxldmVsLFxuXHRcdFx0XHRwcm9jZXNzOiB0aGlzLnByb2Nlc3NDb2RlLFxuXHRcdFx0XHRwYWNrYWdlOiB0aGlzLnBhY2thZ2VOYW1lLFxuXHRcdFx0XHRib2R5LFxuXHRcdFx0fVxuXHRcdFx0aWYgKHRoaXMuc2VydmljZU5hbWUpIHtcblx0XHRcdFx0bG9nLnNlcnZpY2UgPSB0aGlzLnNlcnZpY2VOYW1lXG5cdFx0XHR9XG5cdFx0XHRwcm9jZXNzLnN0ZG91dC53cml0ZShKU09OLnN0cmluZ2lmeShsb2cpICsgYFxcbmApXG5cdFx0fSBlbHNlIHtcblx0XHRcdGNvbnN0IHNvdXJjZSA9IHRoaXMuc2VydmljZU5hbWVcblx0XHRcdFx0PyBgJHt0aGlzLnBhY2thZ2VOYW1lfToke3RoaXMuc2VydmljZU5hbWV9YFxuXHRcdFx0XHQ6IHRoaXMucGFja2FnZU5hbWVcblx0XHRcdHN3aXRjaCAobGV2ZWwpIHtcblx0XHRcdFx0Y2FzZSBGTElHSFRERUNLX0lORk86XG5cdFx0XHRcdFx0Y29uc29sZS5sb2coYCR7c291cmNlfTpgLCAuLi5tZXNzYWdlcylcblx0XHRcdFx0XHRicmVha1xuXHRcdFx0XHRjYXNlIEZMSUdIVERFQ0tfV0FSTjpcblx0XHRcdFx0XHRjb25zb2xlLndhcm4oYCR7c291cmNlfTpgLCAuLi5tZXNzYWdlcylcblx0XHRcdFx0XHRicmVha1xuXHRcdFx0XHRjYXNlIEZMSUdIVERFQ0tfRVJST1I6XG5cdFx0XHRcdFx0Y29uc29sZS5lcnJvcihgJHtzb3VyY2V9OmAsIC4uLm1lc3NhZ2VzKVxuXHRcdFx0XHRcdGJyZWFrXG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cdHB1YmxpYyBpbmZvKC4uLm1lc3NhZ2VzOiB1bmtub3duW10pOiB2b2lkIHtcblx0XHR0aGlzLmxvZyhGTElHSFRERUNLX0lORk8sIC4uLm1lc3NhZ2VzKVxuXHR9XG5cblx0cHVibGljIHdhcm4oLi4ubWVzc2FnZXM6IHVua25vd25bXSk6IHZvaWQge1xuXHRcdHRoaXMubG9nKEZMSUdIVERFQ0tfV0FSTiwgLi4ubWVzc2FnZXMpXG5cdH1cblxuXHRwdWJsaWMgZXJyb3IoLi4ubWVzc2FnZXM6IHVua25vd25bXSk6IHZvaWQge1xuXHRcdHRoaXMubG9nKEZMSUdIVERFQ0tfRVJST1IsIC4uLm1lc3NhZ2VzKVxuXHR9XG59XG4iLAogICAgImltcG9ydCB7IGNyZWF0ZUVudiB9IGZyb20gXCJAdDMtb3NzL2Vudi1jb3JlXCJcbmltcG9ydCB7IHogfSBmcm9tIFwiem9kXCJcblxuZXhwb3J0IGNvbnN0IGVudiA9IGNyZWF0ZUVudih7XG5cdHNlcnZlcjogeyBGTElHSFRERUNLX1NFQ1JFVDogei5zdHJpbmcoKS5vcHRpb25hbCgpIH0sXG5cdGNsaWVudFByZWZpeDogYE5FVkVSYCxcblx0Y2xpZW50OiB7fSxcblx0cnVudGltZUVudjogaW1wb3J0Lm1ldGEuZW52LFxuXHRlbXB0eVN0cmluZ0FzVW5kZWZpbmVkOiB0cnVlLFxufSlcbiIKICBdLAogICJtYXBwaW5n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T0FBTyxFQUFHLFFBQVMsRUFBRSxRQUFRLENBQUUsQ0FBQyxDQUFDLEVBQ3RFLGtCQUFtQixFQUFFLE9BQU8sRUFDNUIsUUFBUyxFQUFFLE9BQU8sQ0FDakIsU0FBVSxFQUFFLE9BQU8sRUFDbkIsUUFBUyxFQUFFLE9BQU8sRUFDbEIsa0JBQW1CLEVBQUUsT0FBTyxDQUM3QixDQUFDLEVBQ0QsWUFBYSxFQUFFLFFBQVEsRUFBRSxTQUFTLENBQ25DLENBQUMsRUFDRCxRQUFTLENBQ1IsS0FBTSxDQUNMLEtBQU0sSUFDTixTQUFVLEdBQ1YsWUFBYSx3Q0FDYixRQUFTLGNBQ1QsTUFBTyxDQUNSLEVBQ0EsWUFBYSxDQUNaLEtBQU0sSUFDTixTQUFVLEdBQ1YsWUFBYSx1QkFDYixRQUFTLHdCQUNWLEVBQ0EsU0FBVSxDQUNULEtBQU0sSUFDTixTQUFVLEdBQ1YsWUFBYSx1Q0FDYixRQUFTLDhJQUNULE1BQU8sS0FBSyxLQUNiLEVBQ0Esa0JBQW1CLENBQ2xCLEtBQU0sSUFDTixTQUFVLEdBQ1YsWUFBYSx5Q0FDYixRQUFTLDZEQUNWLEVBQ0EsUUFBUyxDQUNSLEtBQU0sSUFDTixTQUFVLEdBQ1YsWUFBYSx5QkFDYixRQUFTLDJFQUNULE1BQU8sS0FBSyxLQUNiLEVBQ0EsWUFBYSxDQUNaLEtBQU0sSUFDTixTQUFVLEdBQ1YsWUFBYSx1QkFDYixRQUFTLGdCQUNULE1BQU8sQ0FDUixDQUNELENBQ0QsRUFFTSxFQUFnQixDQUNyQixjQUFlLEVBQUUsT0FBTyxDQUN2QixPQUFRLEVBQUUsT0FBTyxFQUFFLFNBQVMsQ0FDN0IsQ0FBQyxFQUNELFFBQVMsQ0FDUixPQUFRLENBQ1AsS0FBTSxJQUNOLFNBQVUsR0FDVixZQUFhLG9DQUNiLFFBQVMsaUJBQ1YsQ0FDRCxDQUNELEVBRU0sRUFBUSxFQUNiLENBQ0MsUUFBUyxhQUNULE9BQVEsRUFBUyxDQUFFLE9BQVEsS0FBTSxZQUFhLElBQUssQ0FBQyxFQUNwRCxhQUFjLENBQ2IsR0FBSSxFQUNKLFlBQWEsRUFDYixPQUFRLENBQ1QsRUFDQSxZQUFhLEdBQ2IsbUJBQW9CLENBQUMsSUFBUyxDQUM3QixHQUFJLEVBQUssS0FBTyxTQUNmLE9BSUQsT0FEQyxFQUFLLElBQVcsT0FBSyxRQUFRLElBQUksRUFBRyx3QkFBd0IsRUFHL0QsRUFDQSxPQUNELEdBRVEsU0FBUSxtQkFBb0IsRUFBTSxRQUFRLElBQUksRUFFdEQsT0FBUSxFQUFPLFVBQ1QsU0FDSixDQUNDLElBQVEsVUFBVyxFQUFPLEtBQzFCLEVBQWdCLEdBQVUsR0FBRyxDQUM5QixDQUNBLGNBQ1EsQ0FDUixJQUFNLEVBQWEsSUFBSSxFQUFXLEVBQU8sSUFBSSxFQUM3QyxRQUFRLEdBQUcsUUFBUyxTQUFZLENBQy9CLE1BQU0sRUFBVyxnQkFBZ0IsRUFDakMsQ0FDRiIsCiAgImRlYnVnSWQiOiAiNjQ2N0RCQUJGQkQ1NkZBRTY0NzU2RTIxNjQ3NTZFMjEiLAogICJuYW1lcyI6IFtdCn0=
@@ -1,64 +0,0 @@
1
- {
2
- "type": "object",
3
- "properties": {
4
- "port": {
5
- "type": "number"
6
- },
7
- "packageName": {
8
- "type": "string"
9
- },
10
- "services": {
11
- "type": "object",
12
- "additionalProperties": {
13
- "type": "object",
14
- "properties": {
15
- "run": {
16
- "type": "string"
17
- },
18
- "waitFor": {
19
- "type": "boolean"
20
- }
21
- },
22
- "required": [
23
- "run",
24
- "waitFor"
25
- ],
26
- "additionalProperties": false
27
- }
28
- },
29
- "flightdeckRootDir": {
30
- "type": "string"
31
- },
32
- "scripts": {
33
- "type": "object",
34
- "properties": {
35
- "download": {
36
- "type": "string"
37
- },
38
- "install": {
39
- "type": "string"
40
- },
41
- "checkAvailability": {
42
- "type": "string"
43
- }
44
- },
45
- "required": [
46
- "download",
47
- "install",
48
- "checkAvailability"
49
- ],
50
- "additionalProperties": false
51
- },
52
- "jsonLogging": {
53
- "type": "boolean"
54
- }
55
- },
56
- "required": [
57
- "packageName",
58
- "services",
59
- "flightdeckRootDir",
60
- "scripts"
61
- ],
62
- "additionalProperties": false,
63
- "$schema": "http://json-schema.org/draft-07/schema#"
64
- }
@@ -1,10 +0,0 @@
1
- {
2
- "type": "object",
3
- "properties": {
4
- "outdir": {
5
- "type": "string"
6
- }
7
- },
8
- "additionalProperties": false,
9
- "$schema": "http://json-schema.org/draft-07/schema#"
10
- }
@@ -1,5 +0,0 @@
1
- #!/usr/bin/env node
2
- var L=Object.defineProperty;var M=(q,w)=>{for(var x in w)L(q,x,{get:w[x],enumerable:!0,configurable:!0,set:(y)=>w[x]=()=>y})};import{cli as N,required as O}from"comline";import{z as j}from"zod";var E={};M(E,{scramble:()=>B,alert:()=>D});async function D({secret:q,endpoint:w,version:x}){return await fetch(w,{method:"POST",headers:{"Content-Type":"text/plain;charset=UTF-8",Authorization:`Bearer ${q}`},body:x})}async function B({packageConfig:q,secretsConfig:w,publishedPackages:x}){let y=[];for(let z of x)if(z.name in q){let A=z.name,{endpoint:G}=q[A],H=w[A],I=z.version,J=D({secret:H,endpoint:G,version:I}).then((K)=>[A,K]);y.push(J)}let F=await Promise.all(y);return Object.fromEntries(F)}var Q=j.object({packageConfig:j.record(j.string(),j.object({endpoint:j.string()})),secretsConfig:j.record(j.string(),j.string()),publishedPackages:j.array(j.object({name:j.string(),version:j.string()}))}),T=N({cliName:"klaxon",routes:O({scramble:null}),routeOptions:{scramble:{options:{packageConfig:{description:"Maps the names of your packages to the endpoints that klaxon will POST to.",example:'--packageConfig="{\\"my-app\\":{\\"endpoint\\":\\"https://my-app.com\\"}}"',flag:"c",parse:JSON.parse,required:!0},secretsConfig:{description:"Maps the names of your packages to the secrets that klaxon will use to authenticate with their respective endpoints.",example:'--secretsConfig="{\\"my-app\\":\\"XXXX-XXXX-XXXX\\"}"',flag:"s",parse:JSON.parse,required:!0},publishedPackages:{description:'The output of the "Publish" step in Changesets.',example:'--publishedPackages="[{\\"name\\":\\"my-app\\",\\"version\\":\\"0.0.0\\"}]"',flag:"p",parse:JSON.parse,required:!0}},optionsSchema:Q}}}),{inputs:U}=T(process.argv);await B(U.opts).then((q)=>{console.log(q)});
3
-
4
- //# debugId=F19DE54014786B8464756E2164756E21
5
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2tsYXhvbi5iaW4udHMiLCAiLi4vc3JjL2tsYXhvbi5saWIudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbCiAgICAiIyEvdXNyL2Jpbi9lbnYgbm9kZVxuXG5pbXBvcnQgeyBjbGksIHJlcXVpcmVkIH0gZnJvbSBcImNvbWxpbmVcIlxuaW1wb3J0IHsgeiB9IGZyb20gXCJ6b2RcIlxuXG5pbXBvcnQgKiBhcyBLbGF4b24gZnJvbSBcIi4va2xheG9uLmxpYlwiXG5cbmNvbnN0IGNoYW5nZXNldHNQdWJsaXNoZWRQYWNrYWdlc1NjaGVtYTogei5ab2RTY2hlbWE8S2xheG9uLlNjcmFtYmxlT3B0aW9ucz4gPVxuXHR6Lm9iamVjdCh7XG5cdFx0cGFja2FnZUNvbmZpZzogei5yZWNvcmQoei5zdHJpbmcoKSwgei5vYmplY3QoeyBlbmRwb2ludDogei5zdHJpbmcoKSB9KSksXG5cdFx0c2VjcmV0c0NvbmZpZzogei5yZWNvcmQoei5zdHJpbmcoKSwgei5zdHJpbmcoKSksXG5cdFx0cHVibGlzaGVkUGFja2FnZXM6IHouYXJyYXkoXG5cdFx0XHR6Lm9iamVjdCh7XG5cdFx0XHRcdG5hbWU6IHouc3RyaW5nKCksXG5cdFx0XHRcdHZlcnNpb246IHouc3RyaW5nKCksXG5cdFx0XHR9KSxcblx0XHQpLFxuXHR9KVxuXG5jb25zdCBrbGF4b24gPSBjbGkoe1xuXHRjbGlOYW1lOiBga2xheG9uYCxcblx0cm91dGVzOiByZXF1aXJlZCh7XG5cdFx0c2NyYW1ibGU6IG51bGwsXG5cdH0pLFxuXHRyb3V0ZU9wdGlvbnM6IHtcblx0XHRzY3JhbWJsZToge1xuXHRcdFx0b3B0aW9uczoge1xuXHRcdFx0XHRwYWNrYWdlQ29uZmlnOiB7XG5cdFx0XHRcdFx0ZGVzY3JpcHRpb246IGBNYXBzIHRoZSBuYW1lcyBvZiB5b3VyIHBhY2thZ2VzIHRvIHRoZSBlbmRwb2ludHMgdGhhdCBrbGF4b24gd2lsbCBQT1NUIHRvLmAsXG5cdFx0XHRcdFx0ZXhhbXBsZTogYC0tcGFja2FnZUNvbmZpZz1cIntcXFxcXCJteS1hcHBcXFxcXCI6e1xcXFxcImVuZHBvaW50XFxcXFwiOlxcXFxcImh0dHBzOi8vbXktYXBwLmNvbVxcXFxcIn19XCJgLFxuXHRcdFx0XHRcdGZsYWc6IGBjYCxcblx0XHRcdFx0XHRwYXJzZTogSlNPTi5wYXJzZSxcblx0XHRcdFx0XHRyZXF1aXJlZDogdHJ1ZSxcblx0XHRcdFx0fSxcblx0XHRcdFx0c2VjcmV0c0NvbmZpZzoge1xuXHRcdFx0XHRcdGRlc2NyaXB0aW9uOiBgTWFwcyB0aGUgbmFtZXMgb2YgeW91ciBwYWNrYWdlcyB0byB0aGUgc2VjcmV0cyB0aGF0IGtsYXhvbiB3aWxsIHVzZSB0byBhdXRoZW50aWNhdGUgd2l0aCB0aGVpciByZXNwZWN0aXZlIGVuZHBvaW50cy5gLFxuXHRcdFx0XHRcdGV4YW1wbGU6IGAtLXNlY3JldHNDb25maWc9XCJ7XFxcXFwibXktYXBwXFxcXFwiOlxcXFxcIlhYWFgtWFhYWC1YWFhYXFxcXFwifVwiYCxcblx0XHRcdFx0XHRmbGFnOiBgc2AsXG5cdFx0XHRcdFx0cGFyc2U6IEpTT04ucGFyc2UsXG5cdFx0XHRcdFx0cmVxdWlyZWQ6IHRydWUsXG5cdFx0XHRcdH0sXG5cdFx0XHRcdHB1Ymxpc2hlZFBhY2thZ2VzOiB7XG5cdFx0XHRcdFx0ZGVzY3JpcHRpb246IGBUaGUgb3V0cHV0IG9mIHRoZSBcIlB1Ymxpc2hcIiBzdGVwIGluIENoYW5nZXNldHMuYCxcblx0XHRcdFx0XHRleGFtcGxlOiBgLS1wdWJsaXNoZWRQYWNrYWdlcz1cIlt7XFxcXFwibmFtZVxcXFxcIjpcXFxcXCJteS1hcHBcXFxcXCIsXFxcXFwidmVyc2lvblxcXFxcIjpcXFxcXCIwLjAuMFxcXFxcIn1dXCJgLFxuXHRcdFx0XHRcdGZsYWc6IGBwYCxcblx0XHRcdFx0XHRwYXJzZTogSlNPTi5wYXJzZSxcblx0XHRcdFx0XHRyZXF1aXJlZDogdHJ1ZSxcblx0XHRcdFx0fSxcblx0XHRcdH0sXG5cdFx0XHRvcHRpb25zU2NoZW1hOiBjaGFuZ2VzZXRzUHVibGlzaGVkUGFja2FnZXNTY2hlbWEsXG5cdFx0fSxcblx0fSxcbn0pXG5cbmNvbnN0IHsgaW5wdXRzIH0gPSBrbGF4b24ocHJvY2Vzcy5hcmd2KVxuYXdhaXQgS2xheG9uLnNjcmFtYmxlKGlucHV0cy5vcHRzKS50aGVuKChzY3JhbWJsZVJlc3VsdCkgPT4ge1xuXHRjb25zb2xlLmxvZyhzY3JhbWJsZVJlc3VsdClcbn0pXG4iLAogICAgImV4cG9ydCB0eXBlIEFsZXJ0T3B0aW9ucyA9IHtcblx0c2VjcmV0OiBzdHJpbmdcblx0ZW5kcG9pbnQ6IHN0cmluZ1xuXHR2ZXJzaW9uOiBzdHJpbmdcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGFsZXJ0KHtcblx0c2VjcmV0LFxuXHRlbmRwb2ludCxcblx0dmVyc2lvbixcbn06IEFsZXJ0T3B0aW9ucyk6IFByb21pc2U8UmVzcG9uc2U+IHtcblx0Y29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChlbmRwb2ludCwge1xuXHRcdG1ldGhvZDogYFBPU1RgLFxuXHRcdGhlYWRlcnM6IHtcblx0XHRcdFwiQ29udGVudC1UeXBlXCI6IGB0ZXh0L3BsYWluO2NoYXJzZXQ9VVRGLThgLFxuXHRcdFx0QXV0aG9yaXphdGlvbjogYEJlYXJlciAke3NlY3JldH1gLFxuXHRcdH0sXG5cdFx0Ym9keTogdmVyc2lvbixcblx0fSlcblxuXHRyZXR1cm4gcmVzcG9uc2Vcbn1cblxuLyoqXG4gKiBAc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFuZ2VzZXRzL2FjdGlvbi9ibG9iL21haW4vc3JjL3J1bi50c1xuICovXG5leHBvcnQgdHlwZSBDaGFuZ2VzZXRzUHVibGlzaGVkUGFja2FnZSA9IHtcblx0bmFtZTogc3RyaW5nXG5cdHZlcnNpb246IHN0cmluZ1xufVxuXG4vKipcbiAqIEBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2NoYW5nZXNldHMvYWN0aW9uL2Jsb2IvbWFpbi9zcmMvcnVuLnRzXG4gKi9cbmV4cG9ydCB0eXBlIENoYW5nZXNldHNQdWJsaXNoUmVzdWx0ID1cblx0fCB7XG5cdFx0XHRwdWJsaXNoZWQ6IHRydWVcblx0XHRcdHB1Ymxpc2hlZFBhY2thZ2VzOiBDaGFuZ2VzZXRzUHVibGlzaGVkUGFja2FnZVtdXG5cdCAgfVxuXHR8IHsgcHVibGlzaGVkOiBmYWxzZSB9XG5cbmV4cG9ydCB0eXBlIFBhY2thZ2VDb25maWc8SyBleHRlbmRzIHN0cmluZz4gPSB7XG5cdFtrZXkgaW4gS106IHsgZW5kcG9pbnQ6IHN0cmluZyB9XG59XG5leHBvcnQgdHlwZSBTZWNyZXRzQ29uZmlnPEsgZXh0ZW5kcyBzdHJpbmc+ID0ge1xuXHRba2V5IGluIEtdOiBzdHJpbmdcbn1cblxuZXhwb3J0IHR5cGUgU2NyYW1ibGVPcHRpb25zPEsgZXh0ZW5kcyBzdHJpbmcgPSBzdHJpbmc+ID0ge1xuXHRwYWNrYWdlQ29uZmlnOiBQYWNrYWdlQ29uZmlnPEs+XG5cdHNlY3JldHNDb25maWc6IFNlY3JldHNDb25maWc8Sz5cblx0cHVibGlzaGVkUGFja2FnZXM6IENoYW5nZXNldHNQdWJsaXNoZWRQYWNrYWdlW11cbn1cblxuZXhwb3J0IHR5cGUgU2NyYW1ibGVSZXN1bHQ8SyBleHRlbmRzIHN0cmluZyA9IHN0cmluZz4gPSB7XG5cdFtrZXkgaW4gS106IFJlc3BvbnNlXG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzY3JhbWJsZTxLIGV4dGVuZHMgc3RyaW5nID0gc3RyaW5nPih7XG5cdHBhY2thZ2VDb25maWcsXG5cdHNlY3JldHNDb25maWcsXG5cdHB1Ymxpc2hlZFBhY2thZ2VzLFxufTogU2NyYW1ibGVPcHRpb25zPEs+KTogUHJvbWlzZTxTY3JhbWJsZVJlc3VsdDxLPj4ge1xuXHRjb25zdCBhbGVydFJlc3VsdHM6IFByb21pc2U8cmVhZG9ubHkgW0ssIFJlc3BvbnNlXT5bXSA9IFtdXG5cdGZvciAoY29uc3QgcHVibGlzaGVkUGFja2FnZSBvZiBwdWJsaXNoZWRQYWNrYWdlcykge1xuXHRcdGlmIChwdWJsaXNoZWRQYWNrYWdlLm5hbWUgaW4gcGFja2FnZUNvbmZpZykge1xuXHRcdFx0Y29uc3QgbmFtZSA9IHB1Ymxpc2hlZFBhY2thZ2UubmFtZSBhcyBLXG5cdFx0XHRjb25zdCB7IGVuZHBvaW50IH0gPSBwYWNrYWdlQ29uZmlnW25hbWVdXG5cdFx0XHRjb25zdCBzZWNyZXQgPSBzZWNyZXRzQ29uZmlnW25hbWVdXG5cdFx0XHRjb25zdCB2ZXJzaW9uID0gcHVibGlzaGVkUGFja2FnZS52ZXJzaW9uXG5cdFx0XHRjb25zdCBhbGVydFJlc3VsdFByb21pc2UgPSBhbGVydCh7IHNlY3JldCwgZW5kcG9pbnQsIHZlcnNpb24gfSkudGhlbihcblx0XHRcdFx0KGFsZXJ0UmVzdWx0KSA9PiBbbmFtZSwgYWxlcnRSZXN1bHRdIGFzIGNvbnN0LFxuXHRcdFx0KVxuXHRcdFx0YWxlcnRSZXN1bHRzLnB1c2goYWxlcnRSZXN1bHRQcm9taXNlKVxuXHRcdH1cblx0fVxuXHRjb25zdCBhbGVydFJlc3VsdHNSZXNvbHZlZCA9IGF3YWl0IFByb21pc2UuYWxsKGFsZXJ0UmVzdWx0cylcblx0Y29uc3Qgc2NyYW1ibGVSZXN1bHQgPSBPYmplY3QuZnJvbUVudHJpZXMoXG5cdFx0YWxlcnRSZXN1bHRzUmVzb2x2ZWQsXG5cdCkgYXMgU2NyYW1ibGVSZXN1bHQ8Sz5cblx0cmV0dXJuIHNjcmFtYmxlUmVzdWx0XG59XG4iCiAgXSwKICAibWFwcGluZ3MiOiAiOzhIQUVBLGNBQVMsY0FBSyxnQkFDZCxZQUFTLHVEQ0dULGVBQXNCLENBQUssRUFDMUIsU0FDQSxXQUNBLFdBQ21DLENBVW5DLE9BVGlCLE1BQU0sTUFBTSxFQUFVLENBQ3RDLE9BQVEsT0FDUixRQUFTLENBQ1IsZUFBZ0IsMkJBQ2hCLGNBQWUsVUFBVSxHQUMxQixFQUNBLEtBQU0sQ0FDUCxDQUFDLEVBd0NGLGVBQXNCLENBQW1DLEVBQ3hELGdCQUNBLGdCQUNBLHFCQUNrRCxDQUNsRCxJQUFNLEVBQWtELENBQUMsRUFDekQsUUFBVyxLQUFvQixFQUM5QixHQUFJLEVBQWlCLFFBQVEsRUFBZSxDQUMzQyxJQUFNLEVBQU8sRUFBaUIsTUFDdEIsWUFBYSxFQUFjLEdBQzdCLEVBQVMsRUFBYyxHQUN2QixFQUFVLEVBQWlCLFFBQzNCLEVBQXFCLEVBQU0sQ0FBRSxTQUFRLFdBQVUsU0FBUSxDQUFDLEVBQUUsS0FDL0QsQ0FBQyxJQUFnQixDQUFDLEVBQU0sQ0FBVyxDQUNwQyxFQUNBLEVBQWEsS0FBSyxDQUFrQixFQUd0QyxJQUFNLEVBQXVCLE1BQU0sUUFBUSxJQUFJLENBQVksRUFJM0QsT0FIdUIsT0FBTyxZQUM3QixDQUNELEVEeEVELElBQU0sRUFDTCxFQUFFLE9BQU8sQ0FDUixjQUFlLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRyxFQUFFLE9BQU8sQ0FBRSxTQUFVLEVBQUUsT0FBTyxDQUFFLENBQUMsQ0FBQyxFQUN0RSxjQUFlLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRyxFQUFFLE9BQU8sQ0FBQyxFQUM5QyxrQkFBbUIsRUFBRSxNQUNwQixFQUFFLE9BQU8sQ0FDUixLQUFNLEVBQUUsT0FBTyxFQUNmLFFBQVMsRUFBRSxPQUFPLENBQ25CLENBQUMsQ0FDRixDQUNELENBQUMsRUFFSSxFQUFTLEVBQUksQ0FDbEIsUUFBUyxTQUNULE9BQVEsRUFBUyxDQUNoQixTQUFVLElBQ1gsQ0FBQyxFQUNELGFBQWMsQ0FDYixTQUFVLENBQ1QsUUFBUyxDQUNSLGNBQWUsQ0FDZCxZQUFhLDZFQUNiLFFBQVMsNkVBQ1QsS0FBTSxJQUNOLE1BQU8sS0FBSyxNQUNaLFNBQVUsRUFDWCxFQUNBLGNBQWUsQ0FDZCxZQUFhLHVIQUNiLFFBQVMsd0RBQ1QsS0FBTSxJQUNOLE1BQU8sS0FBSyxNQUNaLFNBQVUsRUFDWCxFQUNBLGtCQUFtQixDQUNsQixZQUFhLGtEQUNiLFFBQVMsOEVBQ1QsS0FBTSxJQUNOLE1BQU8sS0FBSyxNQUNaLFNBQVUsRUFDWCxDQUNELEVBQ0EsY0FBZSxDQUNoQixDQUNELENBQ0QsQ0FBQyxHQUVPLFVBQVcsRUFBTyxRQUFRLElBQUksRUFDdEMsTUFBYSxFQUFTLEVBQU8sSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFtQixDQUMzRCxRQUFRLElBQUksQ0FBYyxFQUMxQiIsCiAgImRlYnVnSWQiOiAiRjE5REU1NDAxNDc4NkI4NDY0NzU2RTIxNjQ3NTZFMjEiLAogICJuYW1lcyI6IFtdCn0=
File without changes
File without changes