presta
Version:
Hyper minimal framework for the modern web.
57 lines (55 loc) • 93.8 kB
JavaScript
#!/usr/bin/env node
var Qe=Object.create;var V=Object.defineProperty,Xe=Object.defineProperties,Ye=Object.getOwnPropertyDescriptor,Ze=Object.getOwnPropertyDescriptors,et=Object.getOwnPropertyNames,ue=Object.getOwnPropertySymbols,tt=Object.getPrototypeOf,pe=Object.prototype.hasOwnProperty,rt=Object.prototype.propertyIsEnumerable;var me=(e,t,r)=>t in e?V(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,d=(e,t)=>{for(var r in t||(t={}))pe.call(t,r)&&me(e,r,t[r]);if(ue)for(var r of ue(t))rt.call(t,r)&&me(e,r,t[r]);return e},P=(e,t)=>Xe(e,Ze(t)),ot=e=>V(e,"__esModule",{value:!0});var st=(e,t,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of et(t))!pe.call(e,o)&&o!=="default"&&V(e,o,{get:()=>t[o],enumerable:!(r=Ye(t,o))||r.enumerable});return e},l=e=>st(ot(V(e!=null?Qe(tt(e)):{},"default",e&&e.__esModule&&"default"in e?{get:()=>e.default,enumerable:!0}:{value:e,enumerable:!0})),e);var ze=l(require("fs-extra")),Je=l(require("sade"));var it="presta",nt="0.40.5",at="Hyper minimal framework for the modern web.",lt="index.js",ct="index.d.ts",ut={presta:"cli.js"},pt={build:"node scripts/build",cloc:"pnpx cloc lib/*.ts",typecheck:"pnpx tsc --noEmit"},mt={type:"git",url:"git+ssh://git@github.com/sure-thing/presta.git"},dt="estrattonbailey",gt="MIT",ft={url:"https://github.com/sure-thing/presta/issues"},ht="https://github.com/sure-thing/presta#readme",bt={"@netlify/functions":"^0.7.2","@types/mime-types":"^2.1.0",chokidar:"^3.4.3",deepmerge:"^4.2.2",esbuild:"^0.12.28","esbuild-register":"^2.6.0",filewatcher:"^3.0.1","fs-extra":"^9.0.1","get-port":"^5.1.1",kleur:"^4.1.4","mime-types":"^2.1.31","module-alias":"^2.2.2",ms:"^2.1.2",picomatch:"^2.3.0","pocket.io":"^0.1.4","query-string":"^6.14.1","raw-body":"^2.4.1",regexparam:"^1.3.0","route-sort":"^1.0.0",sade:"^1.7.3",sirv:"^1.0.7","tiny-glob":"^0.2.9","watch-dependency-graph":"^2.6.1"},yt={"@types/fs-extra":"^9.0.12","@types/picomatch":"^2.2.4","@types/sade":"^1.7.3",proxyquire:"^2.1.3","supertest-fetch":"^1.4.3"},de={name:it,version:nt,description:at,main:lt,types:ct,bin:ut,scripts:pt,repository:mt,author:dt,license:gt,bugs:ft,homepage:ht,dependencies:bt,devDependencies:yt};var R=l(require("kleur"));var v={PRODUCTION:"production",DEVELOPMENT:"development"};var xt={pid:process.pid,cwd:process.cwd(),env:v.PRODUCTION,debug:!1};function L(e){return global.__presta__=e,e}function F(){return global.__presta__||L(xt),global.__presta__}var w;(function(i){i.Debug="debug",i.Info="info",i.Warn="warn",i.Err="error"})(w||(w={}));var ge=[],vt={[w.Debug]:"magenta",[w.Info]:"blue",[w.Warn]:"yellow",[w.Err]:"red"};function G(e){if(process.env.TESTING)ge.push(e);else{let t=F().debug,r=F().env===v.PRODUCTION?"prod":"dev";if(!t&&e.level===w.Debug)return;console.log([R.default.gray(r),R.default[vt[e.level||"info"]](e.label),e.message,e.duration?R.default.gray("+"+e.duration):"",e.error?`
${e.error.stack||e.error}
`:""].filter(Boolean).join(" "))}}function p(e){G(d({level:w.Debug},e))}function b(e){G(d({level:w.Info},e))}function C(e){G(d({level:w.Warn},e))}function g(e){G(d({level:w.Err},e))}function q(...e){process.env.TESTING?ge.push(e):console.log(...e)}function k(){process.env.TESTING||console.log("")}var he=l(require("fs")),S=l(require("path"));function fe(){let e={};function t(n,...c){e[n]&&e[n].map(s=>s(...c))}function r(n,c){return e[n]=e[n]?e[n].concat(c):[c],()=>e[n].splice(e[n].indexOf(c),1)}function o(){e={}}function i(n){return e[n]||[]}return{emit:t,on:r,clear:o,listeners:i}}var be="presta.config.js";function ye(e,{cwd:t}){return e.files&&(e.files=[].concat(e.files).map(r=>S.default.resolve(t,r))),e.output&&(e.output=S.default.resolve(t,e.output)),e.assets&&(e.assets=S.default.resolve(t,e.assets)),e}function $(e,t=!1){let r=S.default.resolve(e||be);try{return require(r)}catch(o){return he.default.existsSync(r)&&(g({label:"error",error:o}),t&&process.exit(1)),{}}}async function xe(){return p({label:"debug",message:"config file values cleared"}),L(await O(P(d({},F()),{config:{}})))}async function O({cwd:e=process.cwd(),env:t=F().env,config:r={},cli:o={}}){r=ye(d({},r),{cwd:e}),o=ye(d({},o),{cwd:e});let i={output:S.default.resolve(e,o.output||r.output||"build"),assets:S.default.resolve(o.assets||r.assets||"public"),files:o.files&&o.files.length?o.files:r.files?[].concat(r.files):[]},n=o.port?parseInt(o.port):r.port||4e3,c=F(),s=c.events||fe();s.clear();let u=L(P(d(d({},c),i),{env:t,cwd:e,port:n,debug:o.debug||F().debug,configFilepath:S.default.resolve(o.config||be),staticOutputDir:S.default.join(i.output,"static"),functionsOutputDir:S.default.join(i.output,"functions"),functionsManifest:S.default.join(i.output,"routes.json"),events:s,hooks:{emitPostBuild(a){s.emit("postBuild",a)},onPostBuild(a){return s.on("postBuild",a)},emitBuildFile(a){s.emit("buildFile",a)},onBuildFile(a){return s.on("buildFile",a)},emitBrowserRefresh(){s.emit("browserRefresh")},onBrowserRefresh(a){return s.on("browserRefresh",a)}}}));return r.plugins&&await Promise.all(r.plugins.map(a=>{try{return a(F)}catch(m){g({label:"error",error:m})}})),p({label:"debug",message:`config created ${JSON.stringify(u)}`}),u}var Q=l(require("fs-extra")),Te=l(require("watch-dependency-graph")),$e=l(require("chokidar")),Ie=l(require("picomatch"));var z=l(require("fs-extra")),te=l(require("path")),we=l(require("route-sort"));function ve(e){for(var t=5381,r=e.length;r;)t=t*33^e.charCodeAt(--r);return(t>>>0).toString(36)}function wt(e,t){let{route:r}=require(e),o=te.default.basename(e).split(".").reverse().slice(1).reverse().join("."),i=te.default.join(t.functionsOutputDir,t.env===v.PRODUCTION?o+"-"+ve(z.default.readFileSync(e,"utf8"))+".js":o+".js");return p({label:"debug",message:`generating ${o} lambda`}),delete require.cache[e],delete require.cache[i],z.default.outputFileSync(i,`import { wrapHandler } from 'presta';
import * as file from '${e}';
export const route = file.route
export const handler = wrapHandler(file)`),[r,i]}function J(e,t){let r=e.map(n=>{try{return wt(n,t)}catch(c){return g({label:"error",error:c}),null}}).filter(Boolean),o=(0,we.default)(r.map(n=>n[0])),i={};for(let n of o){let c=r.find(s=>s[0]===n);c&&(i[n]=c[1])}return z.default.outputFileSync(t.functionsManifest,JSON.stringify(i)),r}var re=l(require("fs-extra")),Se=l(require("path")),Ee=l(require("tiny-glob/sync"));function T(e){return/export\s.+\sroute\s+\=/.test(re.default.readFileSync(e,"utf-8"))}function B(e){return/export\s.+\sgetStaticPaths/.test(re.default.readFileSync(e,"utf-8"))}function _(e){try{return[].concat(e.files).map(t=>(0,Ee.default)(t,{cwd:e.cwd})).flat().map(t=>Se.default.resolve(e.cwd,t))}catch(t){return g({label:"paths",message:"no files found",error:t}),[]}}var Re=l(require("fs-extra")),oe=l(require("path")),Oe=l(require("mime-types"));function E(){let e=process.hrtime();return()=>{let[t,r]=process.hrtime(e),o=r/1e6;return t<1?(o>=1?o.toFixed(0):o.toFixed(2))+"ms":t+"."+o.toFixed(0)+"s"}}var Pe=l(require("regexparam"));function Fe(e,t){let[r]=e.split("?"),o=(0,Pe.default)(t),i=0,n={},c=o.pattern.exec(r)||[];for(;i<o.keys.length;)n[o.keys[i]]=c[++i];return n}function St(e){return typeof e=="object"?JSON.stringify(e):e}function K(e){let{isBase64Encoded:t=!1,statusCode:r=200,headers:o={},multiValueHeaders:i={},body:n="",html:c=void 0,json:s=void 0,xml:u=void 0}=typeof e=="string"?{body:e}:e,a="text/html; charset=utf-8";return s?a="application/json; charset=utf-8":u&&(a="application/xml; charset=utf-8"),{isBase64Encoded:t,statusCode:r,headers:d({"Content-Type":a},o),multiValueHeaders:i,body:St(n||c||s||u||"")}}var I={};var Ce=l(require("fs-extra")),ke=l(require("path"));function M(e,t){p({label:"debug",message:`removing old static file ${e}`}),Ce.default.remove(ke.default.join(t.staticOutputDir,e))}function Et(e,t="html"){return oe.default.extname(e)?e:t==="html"?`${e}/index.html`:`${e}.${t}`}function H(e,t){return new Promise(async(r,o)=>{p({label:"debug",message:`rendering ${JSON.stringify(e)}`});let i=[];for(let n of e){let c=n.replace(t.cwd,"");try{delete require.cache[n];let s=require(n),u=await s.getStaticPaths(),a=I[n]=I[n]||[],m=[];if(!u||!u.length){C({label:"paths",message:`${c} - no paths to render`}),a.forEach(y=>M(y,t));continue}for(let y of u){let W=E(),f={path:y,routeParameters:s.route?Fe(y,s.route):{}},j=K(await s.handler(f,{})),x=j.headers?j.headers["Content-Type"]:"",U=x&&Oe.default.extension(x)||"html",D=Et(y,U);i.push(D),m.push(D),Re.default.outputFileSync(oe.default.join(t.staticOutputDir,D),j.body,"utf-8"),b({label:"built",message:y,duration:W()})}for(let y of a)m.includes(y)||M(y,t);I[n]=m}catch(s){t.env==="development"?(g({label:"error",message:"errors detected, pausing...",error:s}),r({allGeneratedFiles:i})):(g({label:"error",error:s}),o(s));break}}r({allGeneratedFiles:i})})}function X(e,t){let r=E();J(e,t),e.length&&b({label:"built",message:"lambdas",duration:r()})}async function je(e){let t=_(e),r=Q.default.existsSync(e.configFilepath);t.length||C({label:"paths",message:"no files configured"}),X(t.filter(T),e);let o=(0,Te.default)({alias:{"@":e.cwd}}),i=$e.default.watch(e.cwd,{ignoreInitial:!0,ignored:[e.output,e.assets]});async function n(){t=_(e),await H(t.filter(B),e),X(t.filter(T),e)}async function c(s){B(s)&&await H([s],e),T(s)&&X(t.filter(T),e),e.hooks.emitBrowserRefresh()}e.hooks.onBuildFile(({file:s})=>{c(s)}),o.on("remove",async([s])=>{p({label:"watch",message:`fileWatcher - removed ${s}`}),t.splice(t.indexOf(s),1),X(t.filter(T),e),s===e.configFilepath&&(e=await xe(),r=!1,n()),(I[s]||[]).forEach(u=>M(u,e))}),o.on("change",async([s])=>{if(p({label:"watch",message:`fileWatcher - changed ${s}`}),s===e.configFilepath){delete require.cache[e.configFilepath];try{e=await O({config:$(e.configFilepath)}),n()}catch(u){g({label:"error",error:u})}}else c(s)}),o.on("error",s=>{g({label:"error",error:s})}),i.on("all",async(s,u)=>{if(!(!/add|change/.test(s)||!Q.default.existsSync(u)||Q.default.lstatSync(u).isDirectory())&&((0,Ie.default)(e.files)(u)&&!t.includes(u)&&(p({label:"watch",message:`globalWatcher - add ${u}`}),t.push(u),o.add(u),c(u)),u===e.configFilepath&&!r)){p({label:"watch",message:`globalWatcher - add config file ${u}`}),o.add(e.configFilepath);try{e=await O({config:$(e.configFilepath)}),r=!0,n()}catch(a){g({label:"error",error:a})}}}),o.add(t),r&&o.add(e.configFilepath);try{t.map(require)}catch(s){g({label:"error",error:s})}}var se=l(require("fs-extra")),De=l(require("esbuild"));function Pt(e){try{return require(e)}catch(t){return{}}}async function Be(e){let t=E(),r=_(e),o=r.filter(B),i=r.filter(T);if(p({label:"build",message:"starting build"}),!o.length&&!i.length)C({label:"files",message:"no files were found, nothing to build"});else{let n="",c=0,s="",u="",a=await Promise.allSettled([(async()=>{if(o.length){let m=E(),{allGeneratedFiles:y}=await H(o,e);n=m(),c=y.length}})(),(async()=>{if(i.length){let m=E();J(i,e),await(0,De.build)({entryPoints:Object.values(require(e.functionsManifest)),outdir:e.functionsOutputDir,bundle:!0,platform:"node",target:["node12"],minify:!0,allowOverwrite:!0,define:{PRESTA_SERVERLESS_RUNTIME:"true"}}),s=m()}})(),(async()=>{if(se.default.existsSync(e.assets)){let m=E();se.default.copySync(e.assets,e.staticOutputDir),u=m()}})()]);if(a.find(m=>m.status==="rejected")){p({label:"build",message:"build partially failed"}),a.forEach(m=>{m.status==="rejected"&&g({label:"error",error:m.reason})}),process.exit(1);return}(n||s)&&k(),n&&b({label:"static",message:`rendered ${c} file(s)`,duration:n}),s&&b({label:"lambda",message:`compiled ${i.length} function(s)`,duration:s}),u&&b({label:"assets",message:`copied in ${u}`}),e.hooks.emitPostBuild({output:e.output,staticOutput:e.staticOutputDir,functionsOutput:e.functionsOutputDir,functionsManifest:Pt(e.functionsManifest)}),(n||s)&&(k(),b({label:"complete",message:`in ${t()}`}),k())}}var ie=l(require("fs")),Y=l(require("path")),Ue=l(require("http")),Ve=l(require("get-port")),ne=l(require("sirv")),Le=l(require("chokidar")),Ge=l(require("mime-types")),qe=l(require("regexparam"));var _e=`<!-- built with presta https://npm.im/presta -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>404</title>
<link
rel="stylesheet"
type="text/css"
href="https://unpkg.com/svbstrate@4.1.1/dist/svbstrate.css"
/>
</head>
<body>
<div class="f aic jcc" style="height: 100vh">
<h2 class="p1" style="color: blue">404 Not Found</h2>
</div>
</body>
</html>`;var Me=l(require("url")),He=l(require("query-string")),Ne=l(require("raw-body")),Ae=l(require("mime-types")),Ft=/image|audio|video|application\/pdf|application\/zip|applicaton\/octet-stream/i;function Ct(e){return Boolean(e)&&Ft.test(e)}async function We(e){var n;let t=String(e.headers["x-forwarded-for"])||e.connection.remoteAddress||"",r=(n=t.split(t.includes(".")?":":",").pop())==null?void 0:n.trim(),o=Ct(e.headers["content-type"]||""),i=e.headers["content-length"]?await(0,Ne.default)(e,{limit:"1mb",encoding:Ae.default.charset(e.headers["content-type"]||"")||void 0}):void 0;return{path:e.url,httpMethod:e.method,headers:P(d({},e.headers),{"client-ip":r}),multiValueHeaders:Object.keys(e.headers).reduce((c,s)=>e.headers[s]&&!e.headers[s].includes(",")?c:P(d({},c),{[s]:e.headers[s].split(",")}),{}),queryStringParameters:(0,He.parse)((0,Me.parse)(e.url).query),body:i?new Buffer(i).toString(o?"base64":"utf8"):null,isBase64Encoded:o}}function N(e,t){let r=K(t);for(let o in t.multiValueHeaders)e.setHeader(o,String(t.multiValueHeaders[o]));for(let o in t.headers)e.setHeader(o,String(t.headers[o]));e.statusCode=r.statusCode,e.write(r.body),e.end()}var kt=["position: fixed","bottom: 24px","right: 24px","width: 32px","height: 32px","border-radius: 32px","background: white","color: #FF7A93","font-size: 20px","font-weight: bold","text-align: center","line-height: 31px","box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.04), 0px 4px 8px rgba(0, 0, 0, 0.04), 0px 16px 24px rgba(0, 0, 0, 0.04), 0px 24px 32px rgba(0, 0, 0, 0.04)"],Z=`
<div style="${kt.join(";")}">~</div>
`;function Rt(e,t){let r=Y.default.join(e,t);if(!Y.default.extname(t))try{return ie.default.readFileSync(Y.default.join(e,t,"index.html"),"utf8")}catch(o){}return ie.default.readFileSync(r,"utf8")}function Ot({port:e}){return`
<script>
(function (global) {
try {
const socketio = document.createElement('script')
socketio.src = 'https://unpkg.com/pocket.io@0.1.4/min.js'
socketio.onload = function init () {
var disconnected = false
var socket = io('http://localhost:${e}', {
reconnectionAttempts: 3
})
socket.on('connect', function() { console.log('presta connected on port ${e}') })
socket.on('refresh', function() {
global.location.reload()
})
socket.on('disconnect', function() {
disconnected = true
})
socket.on('reconnect_failed', function(e) {
if (disconnected) return
console.error("presta - connection to server on :${e} failed")
})
}
document.head.appendChild(socketio)
} catch (e) {}
})(this);
<\/script>
`}function Tt({port:e,config:t}){let r=Ot({port:e}),o=t.staticOutputDir,i=t.assets;return async function(c,s){let u=E(),a=c.url;p({label:"debug",message:`attempting to serve user static asset ${a}`}),(0,ne.default)(i,{dev:!0})(c,s,()=>{p({label:"debug",message:`attempting to serve generated static asset ${a}`}),(0,ne.default)(o,{dev:!0})(c,s,async()=>{try{delete require.cache[t.functionsManifest];let m=require(t.functionsManifest),W=Object.keys(m).map(f=>({matcher:(0,qe.default)(f),route:f})).filter(({matcher:f})=>f.pattern.test(a.split("?")[0])).map(({route:f})=>m[f])[0];if(W){p({label:"debug",message:`attempting to render lambda for ${a}`});let{handler:f}=require(W),j=await We(c),x=await f(j,{}),U=x.headers||{},D=x.statusCode>299&&x.statusCode<399,ce=U["Content-Type"],Ke=ce?Ge.default.extension(ce):"html";b({label:"serve",message:`${x.statusCode} ${D?U.Location:a}`,duration:u()}),N(s,{statusCode:x.statusCode,headers:x.headers,multiValueHeaders:x.multiValueHeaders,body:Ke==="html"?(x.body||"").split("</body>")[0]+r+Z:x.body})}else{p({label:"debug",message:`attempting to render static 404.html page for ${a}`});try{let f=Rt(o,"404")+r+Z;C({label:"serve",message:`404 ${a}`,duration:u()}),N(s,{statusCode:404,body:f})}catch(f){f.message.includes("ENOENT")||console.error(f),p({label:"debug",message:`rendering default 404 HTML page for ${a}`}),C({label:"serve",message:`404 ${a}`,duration:u()}),N(s,{statusCode:404,body:_e+r+Z})}}}catch(m){p({label:"debug",message:`rendering default 500 HTML page for ${a}`}),g({label:"serve",message:`500 ${a}`,error:m,duration:u()}),N(s,{statusCode:500,body:""+r+Z})}})})}}async function ae(e){let t=await(0,Ve.default)({port:e.port}),r=Ue.default.createServer(Tt({port:t,config:e})).listen(t),o=require("pocket.io")(r,{serveClient:!1});return e.hooks.onBrowserRefresh(()=>{p({label:"debug",message:"refresh event received"}),o.emit("refresh")}),Le.default.watch(e.assets,{ignoreInitial:!0}).on("all",()=>{e.hooks.emitBrowserRefresh()}),{port:t}}var A=(0,Je.default)("presta"),ee="presta.config.js";function le(e={}){require("module-alias").addAliases({"@":process.cwd(),"presta:internal":__dirname}),require("esbuild-register/dist/node").register(e)}A.version(de.version).option("--config, -c",`Path to a config file. (default ${ee})`).option("--output, -o","Specify output directory for built files. (default ./build)").option("--assets, -a","Specify static asset directory. (default ./public)").option("--debug, -d","Enable debug mode (prints more logs)").example("dev index.jsx -o dist").example("dev 'pages/*.tsx' -o static").example("'pages/*.tsx'").example("-c site.json").example("serve -p 8080");A.command("build","Build project to output directory.",{default:!0}).example("").example("files/**/*.js").example(`-c ${ee}`).action(async e=>{le(),console.clear();let t=await O({env:v.PRODUCTION,config:$(e.config,!0),cli:P(d({},e),{files:e._})});ze.default.emptyDirSync(t.output),q(`${R.default.blue("presta build")}`),k(),await Be(t)});A.command("dev","Start Presta dev server and watch files",{alias:"watch"}).option("--port, -p","Port to run the local server. (default 4000)").option("--no-serve, -n","Do not run local dev server. (default false)").describe("Watch project and build to output directory.").example("dev").example("dev ./files/**/*.js").example("dev ./files/**/*.js -o ./out").example(`dev -c ${ee}`).action(async e=>{le(),console.clear();let t=await O({env:v.DEVELOPMENT,config:$(e.config),cli:P(d({},e),{files:e._})});if(e.n)b({label:"dev"}),k();else{let r=await ae(t);q(`${R.default.blue("presta dev")} - http://localhost:${r.port}`),k()}je(t)});A.command("serve").option("--port, -p","Port to run the local server. (default 4000)").describe("Serve built files, lambdas, and static assets.").example("serve").example("serve -o ./out -p 8080").example(`serve -c ${ee}`).action(async e=>{le(),console.clear();let t=await O({env:v.PRODUCTION,config:$(e.config),cli:e}),r=await ae(t);q(`${R.default.blue("presta serve")} - http://localhost:${r.port}`),k()});A.parse(process.argv);
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsibGliL2NsaS50cyIsICJsaWIvbG9nLnRzIiwgImxpYi9jb25zdGFudHMudHMiLCAibGliL2N1cnJlbnRQcmVzdGFJbnN0YW5jZS50cyIsICJsaWIvY29uZmlnLnRzIiwgImxpYi9jcmVhdGVFbWl0dGVyLnRzIiwgImxpYi93YXRjaC50cyIsICJsaWIvb3V0cHV0TGFtYmRhcy50cyIsICJsaWIvaGFzaENvbnRlbnQudHMiLCAibGliL2dldEZpbGVzLnRzIiwgImxpYi9yZW5kZXJTdGF0aWNFbnRyaWVzLnRzIiwgImxpYi90aW1lci50cyIsICJsaWIvZ2V0Um91dGVQYXJhbXMudHMiLCAibGliL25vcm1hbGl6ZVJlc3BvbnNlLnRzIiwgImxpYi9idWlsdFN0YXRpY0ZpbGVzLnRzIiwgImxpYi9yZW1vdmVCdWlsdFN0YXRpY0ZpbGUudHMiLCAibGliL2J1aWxkLnRzIiwgImxpYi9zZXJ2ZS50cyIsICJsaWIvZGVmYXVsdDQwNC50cyIsICJsaWIvcmVxdWVzdFRvRXZlbnQudHMiLCAibGliL3NlbmRTZXJ2ZXJsZXNzUmVzcG9uc2UudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIiMhL3Vzci9iaW4vZW52IG5vZGVcblxuaW1wb3J0IGZzIGZyb20gJ2ZzLWV4dHJhJ1xuaW1wb3J0IHNhZGUgZnJvbSAnc2FkZSdcblxuaW1wb3J0IHBrZyBmcm9tICcuLi9wYWNrYWdlLmpzb24nXG5cbmltcG9ydCAqIGFzIGxvZ2dlciBmcm9tICcuL2xvZydcbmltcG9ydCB7IGNyZWF0ZUNvbmZpZywgZ2V0Q29uZmlnRmlsZSB9IGZyb20gJy4vY29uZmlnJ1xuaW1wb3J0IHsgd2F0Y2ggfSBmcm9tICcuL3dhdGNoJ1xuaW1wb3J0IHsgYnVpbGQgfSBmcm9tICcuL2J1aWxkJ1xuaW1wb3J0IHsgc2VydmUgfSBmcm9tICcuL3NlcnZlJ1xuaW1wb3J0IHsgRW52IH0gZnJvbSAnLi9jb25zdGFudHMnXG5cbmNvbnN0IHByb2cgPSBzYWRlKCdwcmVzdGEnKVxuY29uc3QgQ09ORklHX0RFRkFVTFQgPSAncHJlc3RhLmNvbmZpZy5qcydcblxuZnVuY3Rpb24gcmVnaXN0ZXJSdW50aW1lKG9wdGlvbnMgPSB7fSkge1xuICByZXF1aXJlKCdtb2R1bGUtYWxpYXMnKS5hZGRBbGlhc2VzKHtcbiAgICAnQCc6IHByb2Nlc3MuY3dkKCksXG4gICAgJ3ByZXN0YTppbnRlcm5hbCc6IF9fZGlybmFtZSwgLy8gd2hlcmV2ZXIgdGhpcyBpcyBydW5uaW5nIGZyb21cbiAgfSlcblxuICByZXF1aXJlKCdlc2J1aWxkLXJlZ2lzdGVyL2Rpc3Qvbm9kZScpLnJlZ2lzdGVyKG9wdGlvbnMpXG59XG5cbnByb2dcbiAgLnZlcnNpb24ocGtnLnZlcnNpb24pXG4gIC8vIGRvIG5vdCBwcm92aWRlIGRlZmF1bHQgY29uZmlnIGhlcmVcbiAgLm9wdGlvbignLS1jb25maWcsIC1jJywgYFBhdGggdG8gYSBjb25maWcgZmlsZS4gIChkZWZhdWx0ICR7Q09ORklHX0RFRkFVTFR9KWApXG4gIC5vcHRpb24oJy0tb3V0cHV0LCAtbycsIGBTcGVjaWZ5IG91dHB1dCBkaXJlY3RvcnkgZm9yIGJ1aWx0IGZpbGVzLiAgKGRlZmF1bHQgLi9idWlsZClgKVxuICAub3B0aW9uKCctLWFzc2V0cywgLWEnLCBgU3BlY2lmeSBzdGF0aWMgYXNzZXQgZGlyZWN0b3J5LiAgKGRlZmF1bHQgLi9wdWJsaWMpYClcbiAgLm9wdGlvbignLS1kZWJ1ZywgLWQnLCBgRW5hYmxlIGRlYnVnIG1vZGUgKHByaW50cyBtb3JlIGxvZ3MpYClcbiAgLmV4YW1wbGUoYGRldiBpbmRleC5qc3ggLW8gZGlzdGApXG4gIC5leGFtcGxlKGBkZXYgJ3BhZ2VzLyoudHN4JyAtbyBzdGF0aWNgKVxuICAuZXhhbXBsZShgJ3BhZ2VzLyoudHN4J2ApXG4gIC5leGFtcGxlKGAtYyBzaXRlLmpzb25gKVxuICAuZXhhbXBsZShgc2VydmUgLXAgODA4MGApXG5cbnByb2dcbiAgLmNvbW1hbmQoJ2J1aWxkJywgJ0J1aWxkIHByb2plY3QgdG8gb3V0cHV0IGRpcmVjdG9yeS4nLCB7IGRlZmF1bHQ6IHRydWUgfSlcbiAgLmV4YW1wbGUoYGApXG4gIC5leGFtcGxlKGBmaWxlcy8qKi8qLmpzYClcbiAgLmV4YW1wbGUoYC1jICR7Q09ORklHX0RFRkFVTFR9YClcbiAgLmFjdGlvbihhc3luYyAob3B0cykgPT4ge1xuICAgIHJlZ2lzdGVyUnVudGltZSgpXG5cbiAgICBjb25zb2xlLmNsZWFyKClcblxuICAgIGNvbnN0IGNvbmZpZyA9IGF3YWl0IGNyZWF0ZUNvbmZpZyh7XG4gICAgICBlbnY6IEVudi5QUk9EVUNUSU9OLFxuICAgICAgY29uZmlnOiBnZXRDb25maWdGaWxlKG9wdHMuY29uZmlnLCB0cnVlKSxcbiAgICAgIGNsaToge1xuICAgICAgICAuLi5vcHRzLFxuICAgICAgICBmaWxlczogb3B0cy5fLFxuICAgICAgfSxcbiAgICB9KVxuXG4gICAgZnMuZW1wdHlEaXJTeW5jKGNvbmZpZy5vdXRwdXQpXG5cbiAgICBsb2dnZXIucmF3KGAke2xvZ2dlci5jb2xvcnMuYmx1ZSgncHJlc3RhIGJ1aWxkJyl9YClcbiAgICBsb2dnZXIubmV3bGluZSgpXG5cbiAgICBhd2FpdCBidWlsZChjb25maWcpXG4gIH0pXG5cbnByb2dcbiAgLmNvbW1hbmQoJ2RldicsICdTdGFydCBQcmVzdGEgZGV2IHNlcnZlciBhbmQgd2F0Y2ggZmlsZXMnLCB7IGFsaWFzOiAnd2F0Y2gnIH0pXG4gIC5vcHRpb24oJy0tcG9ydCwgLXAnLCBgUG9ydCB0byBydW4gdGhlIGxvY2FsIHNlcnZlci4gIChkZWZhdWx0IDQwMDApYClcbiAgLm9wdGlvbignLS1uby1zZXJ2ZSwgLW4nLCBgRG8gbm90IHJ1biBsb2NhbCBkZXYgc2VydmVyLiAgKGRlZmF1bHQgZmFsc2UpYClcbiAgLmRlc2NyaWJlKCdXYXRjaCBwcm9qZWN0IGFuZCBidWlsZCB0byBvdXRwdXQgZGlyZWN0b3J5LicpXG4gIC5leGFtcGxlKGBkZXZgKVxuICAuZXhhbXBsZShgZGV2IC4vZmlsZXMvKiovKi5qc2ApXG4gIC5leGFtcGxlKGBkZXYgLi9maWxlcy8qKi8qLmpzIC1vIC4vb3V0YClcbiAgLmV4YW1wbGUoYGRldiAtYyAke0NPTkZJR19ERUZBVUxUfWApXG4gIC5hY3Rpb24oYXN5bmMgKG9wdHMpID0+IHtcbiAgICByZWdpc3RlclJ1bnRpbWUoKVxuXG4gICAgY29uc29sZS5jbGVhcigpXG5cbiAgICBjb25zdCBjb25maWcgPSBhd2FpdCBjcmVhdGVDb25maWcoe1xuICAgICAgZW52OiBFbnYuREVWRUxPUE1FTlQsXG4gICAgICBjb25maWc6IGdldENvbmZpZ0ZpbGUob3B0cy5jb25maWcpLFxuICAgICAgY2xpOiB7XG4gICAgICAgIC4uLm9wdHMsXG4gICAgICAgIGZpbGVzOiBvcHRzLl8sXG4gICAgICB9LFxuICAgIH0pXG5cbiAgICBpZiAoIW9wdHMubikge1xuICAgICAgY29uc3Qgc2VydmVyID0gYXdhaXQgc2VydmUoY29uZmlnKVxuXG4gICAgICBsb2dnZXIucmF3KGAke2xvZ2dlci5jb2xvcnMuYmx1ZSgncHJlc3RhIGRldicpfSAtIGh0dHA6Ly9sb2NhbGhvc3Q6JHtzZXJ2ZXIucG9ydH1gKVxuICAgICAgbG9nZ2VyLm5ld2xpbmUoKVxuICAgIH0gZWxzZSB7XG4gICAgICBsb2dnZXIuaW5mbyh7XG4gICAgICAgIGxhYmVsOiAnZGV2JyxcbiAgICAgIH0pXG4gICAgICBsb2dnZXIubmV3bGluZSgpXG4gICAgfVxuXG4gICAgd2F0Y2goY29uZmlnKVxuICB9KVxuXG5wcm9nXG4gIC5jb21tYW5kKCdzZXJ2ZScpXG4gIC5vcHRpb24oJy0tcG9ydCwgLXAnLCBgUG9ydCB0byBydW4gdGhlIGxvY2FsIHNlcnZlci4gIChkZWZhdWx0IDQwMDApYClcbiAgLmRlc2NyaWJlKCdTZXJ2ZSBidWlsdCBmaWxlcywgbGFtYmRhcywgYW5kIHN0YXRpYyBhc3NldHMuJylcbiAgLmV4YW1wbGUoYHNlcnZlYClcbiAgLmV4YW1wbGUoYHNlcnZlIC1vIC4vb3V0IC1wIDgwODBgKVxuICAuZXhhbXBsZShgc2VydmUgLWMgJHtDT05GSUdfREVGQVVMVH1gKVxuICAuYWN0aW9uKGFzeW5jIChvcHRzKSA9PiB7XG4gICAgcmVnaXN0ZXJSdW50aW1lKClcblxuICAgIGNvbnNvbGUuY2xlYXIoKVxuXG4gICAgY29uc3QgY29uZmlnID0gYXdhaXQgY3JlYXRlQ29uZmlnKHtcbiAgICAgIGVudjogRW52LlBST0RVQ1RJT04sXG4gICAgICBjb25maWc6IGdldENvbmZpZ0ZpbGUob3B0cy5jb25maWcpLFxuICAgICAgY2xpOiBvcHRzLFxuICAgIH0pXG4gICAgY29uc3Qgc2VydmVyID0gYXdhaXQgc2VydmUoY29uZmlnKVxuXG4gICAgbG9nZ2VyLnJhdyhgJHtsb2dnZXIuY29sb3JzLmJsdWUoJ3ByZXN0YSBzZXJ2ZScpfSAtIGh0dHA6Ly9sb2NhbGhvc3Q6JHtzZXJ2ZXIucG9ydH1gKVxuICAgIGxvZ2dlci5uZXdsaW5lKClcbiAgfSlcblxucHJvZy5wYXJzZShwcm9jZXNzLmFyZ3YpXG4iLCAiaW1wb3J0IGMsIHsgS2xldXIgfSBmcm9tICdrbGV1cidcblxuaW1wb3J0IHsgZ2V0Q3VycmVudFByZXN0YUluc3RhbmNlIH0gZnJvbSAnLi9jdXJyZW50UHJlc3RhSW5zdGFuY2UnXG5pbXBvcnQgeyBFbnYgfSBmcm9tICcuL2NvbnN0YW50cydcblxuZXhwb3J0IGVudW0gTGV2ZWxzIHtcbiAgRGVidWcgPSAnZGVidWcnLFxuICBJbmZvID0gJ2luZm8nLFxuICBXYXJuID0gJ3dhcm4nLFxuICBFcnIgPSAnZXJyb3InLFxufVxuXG5leHBvcnQgdHlwZSBNZXNzYWdlID0ge1xuICBsZXZlbD86IExldmVsc1xuICBsYWJlbDogc3RyaW5nIHwgbnVtYmVyXG4gIG1lc3NhZ2U/OiBzdHJpbmdcbiAgZHVyYXRpb24/OiBzdHJpbmcgfCBudW1iZXJcbiAgZXJyb3I/OiBFcnJvclxufVxuXG5sZXQgbG9nczogYW55W10gPSBbXVxuXG5jb25zdCBjb2xvcnMgPSB7XG4gIFtMZXZlbHMuRGVidWddOiAnbWFnZW50YScsXG4gIFtMZXZlbHMuSW5mb106ICdibHVlJyxcbiAgW0xldmVscy5XYXJuXTogJ3llbGxvdycsXG4gIFtMZXZlbHMuRXJyXTogJ3JlZCcsXG59XG5cbmV4cG9ydCB7IGMgYXMgY29sb3JzIH1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldExvZ3MoKSB7XG4gIGlmICghcHJvY2Vzcy5lbnYuVEVTVElORykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW50ZXJuYWwgbWV0aG9kIHdhcyBjYWxsZWQgb3V0c2lkZSB0ZXN0IG1vZGUnKVxuICB9XG5cbiAgcmV0dXJuIGxvZ3Ncbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGxvZ2dlcihtZXNzYWdlOiBNZXNzYWdlKSB7XG4gIGlmIChwcm9jZXNzLmVudi5URVNUSU5HKSB7XG4gICAgbG9ncy5wdXNoKG1lc3NhZ2UpXG4gIH0gZWxzZSB7XG4gICAgY29uc3QgZGVidWcgPSBnZXRDdXJyZW50UHJlc3RhSW5zdGFuY2UoKS5kZWJ1Z1xuICAgIGNvbnN0IGNvbnRleHQgPSBnZXRDdXJyZW50UHJlc3RhSW5zdGFuY2UoKS5lbnYgPT09IEVudi5QUk9EVUNUSU9OID8gJ3Byb2QnIDogJ2RldidcblxuICAgIGlmICghZGVidWcgJiYgbWVzc2FnZS5sZXZlbCA9PT0gTGV2ZWxzLkRlYnVnKSByZXR1cm5cblxuICAgIGNvbnNvbGUubG9nKFxuICAgICAgW1xuICAgICAgICBjLmdyYXkoY29udGV4dCksXG4gICAgICAgIGNbY29sb3JzW21lc3NhZ2UubGV2ZWwgfHwgJ2luZm8nXSBhcyBrZXlvZiBLbGV1cl0obWVzc2FnZS5sYWJlbCksXG4gICAgICAgIG1lc3NhZ2UubWVzc2FnZSxcbiAgICAgICAgbWVzc2FnZS5kdXJhdGlvbiA/IGMuZ3JheSgnKycgKyBtZXNzYWdlLmR1cmF0aW9uKSA6ICcnLFxuICAgICAgICBtZXNzYWdlLmVycm9yID8gYFxcblxcbiR7bWVzc2FnZS5lcnJvci5zdGFjayB8fCBtZXNzYWdlLmVycm9yfVxcblxcbmAgOiAnJyxcbiAgICAgIF1cbiAgICAgICAgLmZpbHRlcihCb29sZWFuKVxuICAgICAgICAuam9pbignICcpXG4gICAgKVxuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkZWJ1ZyhtZXNzYWdlOiBNZXNzYWdlKSB7XG4gIGxvZ2dlcih7IGxldmVsOiBMZXZlbHMuRGVidWcsIC4uLm1lc3NhZ2UgfSlcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGluZm8obWVzc2FnZTogTWVzc2FnZSkge1xuICBsb2dnZXIoeyBsZXZlbDogTGV2ZWxzLkluZm8sIC4uLm1lc3NhZ2UgfSlcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHdhcm4obWVzc2FnZTogTWVzc2FnZSkge1xuICBsb2dnZXIoeyBsZXZlbDogTGV2ZWxzLldhcm4sIC4uLm1lc3NhZ2UgfSlcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGVycm9yKG1lc3NhZ2U6IE1lc3NhZ2UpIHtcbiAgbG9nZ2VyKHsgbGV2ZWw6IExldmVscy5FcnIsIC4uLm1lc3NhZ2UgfSlcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJhdyguLi5hcmdzOiBhbnlbXSkge1xuICBpZiAocHJvY2Vzcy5lbnYuVEVTVElORykge1xuICAgIGxvZ3MucHVzaChhcmdzKVxuICB9IGVsc2Uge1xuICAgIGNvbnNvbGUubG9nKC4uLmFyZ3MpXG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG5ld2xpbmUoKSB7XG4gIGlmIChwcm9jZXNzLmVudi5URVNUSU5HKSByZXR1cm5cbiAgY29uc29sZS5sb2coJycpXG59XG4iLCAiZXhwb3J0IGNvbnN0IEVudiA9IHtcbiAgUFJPRFVDVElPTjogJ3Byb2R1Y3Rpb24nLFxuICBERVZFTE9QTUVOVDogJ2RldmVsb3BtZW50Jyxcbn1cbiIsICJpbXBvcnQgeyBQcmVzdGEgfSBmcm9tICcuL3R5cGVzJ1xuaW1wb3J0IHsgRW52IH0gZnJvbSAnLi9jb25zdGFudHMnXG5cbmNvbnN0IGRlZmF1bHRDb25maWcgPSB7XG4gIHBpZDogcHJvY2Vzcy5waWQsXG4gIGN3ZDogcHJvY2Vzcy5jd2QoKSxcbiAgZW52OiBFbnYuUFJPRFVDVElPTixcbiAgZGVidWc6IGZhbHNlLFxufSBhcyBQcmVzdGFcblxuZXhwb3J0IGZ1bmN0aW9uIHNldEN1cnJlbnRQcmVzdGFJbnN0YW5jZShjb25maWc6IFByZXN0YSk6IFByZXN0YSB7XG4gIC8vIEB0cy1pZ25vcmVcbiAgZ2xvYmFsLl9fcHJlc3RhX18gPSBjb25maWdcbiAgcmV0dXJuIGNvbmZpZ1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q3VycmVudFByZXN0YUluc3RhbmNlKCk6IFByZXN0YSB7XG4gIC8vIEB0cy1pZ25vcmVcbiAgaWYgKCFnbG9iYWwuX19wcmVzdGFfXykge1xuICAgIHNldEN1cnJlbnRQcmVzdGFJbnN0YW5jZShkZWZhdWx0Q29uZmlnKVxuICB9XG5cbiAgLy8gQHRzLWlnbm9yZVxuICByZXR1cm4gZ2xvYmFsLl9fcHJlc3RhX19cbn1cbiIsICJpbXBvcnQgZnMgZnJvbSAnZnMnXG5pbXBvcnQgcGF0aCBmcm9tICdwYXRoJ1xuXG5pbXBvcnQgKiBhcyBsb2dnZXIgZnJvbSAnLi9sb2cnXG5pbXBvcnQgeyBjcmVhdGVFbWl0dGVyLCBjcmVhdGVFbWl0SG9vaywgY3JlYXRlT25Ib29rIH0gZnJvbSAnLi9jcmVhdGVFbWl0dGVyJ1xuaW1wb3J0IHsgc2V0Q3VycmVudFByZXN0YUluc3RhbmNlLCBnZXRDdXJyZW50UHJlc3RhSW5zdGFuY2UgfSBmcm9tICcuL2N1cnJlbnRQcmVzdGFJbnN0YW5jZSdcbmltcG9ydCB7IFByZXN0YSwgQ29uZmlnLCBDTEksIENhbGxhYmxlIH0gZnJvbSAnLi90eXBlcydcbmltcG9ydCB7IEVudiB9IGZyb20gJy4vY29uc3RhbnRzJ1xuXG5jb25zdCBkZWZhdWx0Q29uZmlnRmlsZXBhdGggPSAncHJlc3RhLmNvbmZpZy5qcydcblxuZnVuY3Rpb24gcmVzb2x2ZUFic29sdXRlUGF0aHMoXG4gIGNvbmZpZzoge1xuICAgIGZpbGVzPzogc3RyaW5nIHwgc3RyaW5nW11cbiAgICBvdXRwdXQ/OiBzdHJpbmdcbiAgICBhc3NldHM/OiBzdHJpbmdcbiAgfSxcbiAgeyBjd2QgfTogeyBjd2Q6IHN0cmluZyB9XG4pIHtcbiAgaWYgKGNvbmZpZy5maWxlcykgY29uZmlnLmZpbGVzID0gKFtdIGFzIHN0cmluZ1tdKS5jb25jYXQoY29uZmlnLmZpbGVzKS5tYXAoKHApID0+IHBhdGgucmVzb2x2ZShjd2QsIHApKVxuICBpZiAoY29uZmlnLm91dHB1dCkgY29uZmlnLm91dHB1dCA9IHBhdGgucmVzb2x2ZShjd2QsIGNvbmZpZy5vdXRwdXQpXG4gIGlmIChjb25maWcuYXNzZXRzKSBjb25maWcuYXNzZXRzID0gcGF0aC5yZXNvbHZlKGN3ZCwgY29uZmlnLmFzc2V0cylcbiAgcmV0dXJuIGNvbmZpZ1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBfY2xlYXJDdXJyZW50Q29uZmlnKCkge1xuICAvLyBAdHMtaWdub3JlXG4gIGdsb2JhbC5fX3ByZXN0YV9fID0ge1xuICAgIHBpZDogcHJvY2Vzcy5waWQsXG4gICAgY3dkOiBwcm9jZXNzLmN3ZCgpLFxuICAgIGVudjogRW52LlBST0RVQ1RJT04sXG4gIH1cbn1cblxuLyoqXG4gKiBGZXRjaCBhIGNvbmZpZyBmaWxlLiBJZiBvbmUgd2FzIHNwZWNpZmllZCBieSB0aGUgdXNlciwgbGV0IHRoZW0ga25vdyBpZlxuICogYW55dGhpbmcgZ29lcyB3cm9uZy4gT3V0c2lkZSB3YXRjaCBtb2RlLCB0aGlzIHNob3VsZCBleGl0KDEpIGlmIHRoZSB1c2VyXG4gKiBwcm92aWRlZCBhIGNvbmZpZyBhbmQgdGhlcmUgd2FzIGFuIGVycm9yXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRDb25maWdGaWxlKGZpbGVwYXRoPzogc3RyaW5nLCBzaG91bGRFeGl0OiBib29sZWFuID0gZmFsc2UpIHtcbiAgY29uc3QgZnAgPSBwYXRoLnJlc29sdmUoZmlsZXBhdGggfHwgZGVmYXVsdENvbmZpZ0ZpbGVwYXRoKVxuXG4gIHRyeSB7XG4gICAgcmV0dXJuIHJlcXVpcmUoZnApXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBjb25zdCBleGlzdHMgPSBmcy5leGlzdHNTeW5jKGZwKVxuXG4gICAgLy8gY29uZmlnIGZpbGUgZXhpc3RzLCBzaG91bGQgbG9nIGVycm9yLCBvdGhlcndpc2UgaWdub3JlIG1pc3NpbmcgZmlsZVxuICAgIGlmIChleGlzdHMpIHtcbiAgICAgIGxvZ2dlci5lcnJvcih7XG4gICAgICAgIGxhYmVsOiAnZXJyb3InLFxuICAgICAgICBlcnJvcjogZSBhcyBFcnJvcixcbiAgICAgIH0pXG5cbiAgICAgIC8vIHdlJ3JlIG5vdCBpbiB3YXRjaCBtb2RlLCBleGl0IGJ1aWxkXG4gICAgICBpZiAoc2hvdWxkRXhpdCkgcHJvY2Vzcy5leGl0KDEpXG4gICAgfVxuXG4gICAgcmV0dXJuIHt9XG4gIH1cbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IGluc3RhbmNlIF93aXRob3V0XyBhbnkgdmFsdWVzIHByb3ZpZGVkIGJ5IHRoZSBjb25maWcgZmlsZS5cbiAqIFRoaXMgaXMgdXNlZCB3aGVuIHRoZSB1c2VyIGRlbGV0ZXMgdGhlaXIgY29uZmlnIGZpbGUuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZW1vdmVDb25maWdWYWx1ZXMoKSB7XG4gIGxvZ2dlci5kZWJ1Zyh7XG4gICAgbGFiZWw6ICdkZWJ1ZycsXG4gICAgbWVzc2FnZTogYGNvbmZpZyBmaWxlIHZhbHVlcyBjbGVhcmVkYCxcbiAgfSlcblxuICByZXR1cm4gc2V0Q3VycmVudFByZXN0YUluc3RhbmNlKFxuICAgIGF3YWl0IGNyZWF0ZUNvbmZpZyh7XG4gICAgICAuLi5nZXRDdXJyZW50UHJlc3RhSW5zdGFuY2UoKSxcbiAgICAgIGNvbmZpZzoge30sXG4gICAgfSlcbiAgKVxufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY3JlYXRlQ29uZmlnKHtcbiAgY3dkID0gcHJvY2Vzcy5jd2QoKSxcbiAgZW52ID0gZ2V0Q3VycmVudFByZXN0YUluc3RhbmNlKCkuZW52LFxuICBjb25maWcgPSB7fSxcbiAgY2xpID0ge30sXG59OiB7XG4gIGN3ZD86IHN0cmluZ1xuICBlbnY/OiBzdHJpbmdcbiAgY29uZmlnPzogUGFydGlhbDxDb25maWc+XG4gIGNsaT86IFBhcnRpYWw8Q0xJPlxufSkge1xuICBjb25maWcgPSByZXNvbHZlQWJzb2x1dGVQYXRocyh7IC4uLmNvbmZpZyB9LCB7IGN3ZCB9KSAvLyBjbG9uZSByZWFkLW9ubHkgb2JqXG4gIGNsaSA9IHJlc29sdmVBYnNvbHV0ZVBhdGhzKHsgLi4uY2xpIH0sIHsgY3dkIH0pXG5cbiAgLy8gY29tYmluZWQgY29uZmlnLCBwcmVmZXJlbmNlIHRvIENMSSBhcmdzXG4gIGNvbnN0IG1lcmdlZCA9IHtcbiAgICBvdXRwdXQ6IHBhdGgucmVzb2x2ZShjd2QsIGNsaS5vdXRwdXQgfHwgY29uZmlnLm91dHB1dCB8fCAnYnVpbGQnKSxcbiAgICBhc3NldHM6IHBhdGgucmVzb2x2ZShjbGkuYXNzZXRzIHx8IGNvbmZpZy5hc3NldHMgfHwgJ3B1YmxpYycpLFxuICAgIGZpbGVzOiBjbGkuZmlsZXMgJiYgY2xpLmZpbGVzLmxlbmd0aCA/IGNsaS5maWxlcyA6IGNvbmZpZy5maWxlcyA/IChbXSBhcyBzdHJpbmdbXSkuY29uY2F0KGNvbmZpZy5maWxlcykgOiBbXSxcbiAgfVxuICBjb25zdCBwb3J0ID0gY2xpLnBvcnQgPyBwYXJzZUludChjbGkucG9ydCkgOiBjb25maWcucG9ydCB8fCA0MDAwXG5cbiAgY29uc3QgcHJldmlvdXMgPSBnZXRDdXJyZW50UHJlc3RhSW5zdGFuY2UoKVxuICAvLyBvbmx5IGNyZWF0ZSBvbmNlXG4gIGNvbnN0IGVtaXR0ZXIgPSBwcmV2aW91cy5ldmVudHMgfHwgY3JlYXRlRW1pdHRlcigpXG5cbiAgLy8gZGVyZWdpc3RlciBvbGQgZXZlbnRzXG4gIGVtaXR0ZXIuY2xlYXIoKVxuXG4gIC8vIHNldCBpbnN0YW5jZVxuICBjb25zdCBuZXh0OiBQcmVzdGEgPSBzZXRDdXJyZW50UHJlc3RhSW5zdGFuY2Uoe1xuICAgIC4uLnByZXZpb3VzLFxuICAgIC4uLm1lcmdlZCwgLy8gb3ZlcndyaXRlcyBldmVyeSB0aW1lXG4gICAgZW52LFxuICAgIGN3ZCxcbiAgICBwb3J0LFxuICAgIGRlYnVnOiBjbGkuZGVidWcgfHwgZ2V0Q3VycmVudFByZXN0YUluc3RhbmNlKCkuZGVidWcsXG4gICAgY29uZmlnRmlsZXBhdGg6IHBhdGgucmVzb2x2ZShjbGkuY29uZmlnIHx8IGRlZmF1bHRDb25maWdGaWxlcGF0aCksXG4gICAgc3RhdGljT3V0cHV0RGlyOiBwYXRoLmpvaW4obWVyZ2VkLm91dHB1dCwgJ3N0YXRpYycpLFxuICAgIGZ1bmN0aW9uc091dHB1dERpcjogcGF0aC5qb2luKG1lcmdlZC5vdXRwdXQsICdmdW5jdGlvbnMnKSxcbiAgICBmdW5jdGlvbnNNYW5pZmVzdDogcGF0aC5qb2luKG1lcmdlZC5vdXRwdXQsICdyb3V0ZXMuanNvbicpLFxuICAgIGV2ZW50czogZW1pdHRlcixcbiAgICBob29rczoge1xuICAgICAgZW1pdFBvc3RCdWlsZChwcm9wcykge1xuICAgICAgICBlbWl0dGVyLmVtaXQoJ3Bvc3RCdWlsZCcsIHByb3BzKVxuICAgICAgfSxcbiAgICAgIG9uUG9zdEJ1aWxkKGNiKSB7XG4gICAgICAgIHJldHVybiBlbWl0dGVyLm9uKCdwb3N0QnVpbGQnLCBjYilcbiAgICAgIH0sXG4gICAgICBlbWl0QnVpbGRGaWxlKHByb3BzKSB7XG4gICAgICAgIGVtaXR0ZXIuZW1pdCgnYnVpbGRGaWxlJywgcHJvcHMpXG4gICAgICB9LFxuICAgICAgb25CdWlsZEZpbGUoY2IpIHtcbiAgICAgICAgcmV0dXJuIGVtaXR0ZXIub24oJ2J1aWxkRmlsZScsIGNiKVxuICAgICAgfSxcbiAgICAgIGVtaXRCcm93c2VyUmVmcmVzaCgpIHtcbiAgICAgICAgZW1pdHRlci5lbWl0KCdicm93c2VyUmVmcmVzaCcpXG4gICAgICB9LFxuICAgICAgb25Ccm93c2VyUmVmcmVzaChjYikge1xuICAgICAgICByZXR1cm4gZW1pdHRlci5vbignYnJvd3NlclJlZnJlc2gnLCBjYilcbiAgICAgIH0sXG4gICAgfSxcbiAgfSlcblxuICBpZiAoY29uZmlnLnBsdWdpbnMpIHtcbiAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIGNvbmZpZy5wbHVnaW5zLm1hcCgocCkgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHJldHVybiBwKGdldEN1cnJlbnRQcmVzdGFJbnN0YW5jZSlcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIGxvZ2dlci5lcnJvcih7XG4gICAgICAgICAgICBsYWJlbDogJ2Vycm9yJyxcbiAgICAgICAgICAgIGVycm9yOiBlIGFzIEVycm9yLFxuICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgKVxuICB9XG5cbiAgbG9nZ2VyLmRlYnVnKHtcbiAgICBsYWJlbDogJ2RlYnVnJyxcbiAgICBtZXNzYWdlOiBgY29uZmlnIGNyZWF0ZWQgJHtKU09OLnN0cmluZ2lmeShuZXh0KX1gLFxuICB9KVxuXG4gIHJldHVybiBuZXh0XG59XG4iLCAiaW1wb3J0IHsgQ2FsbGFibGUgfSBmcm9tICcuL3R5cGVzJ1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlRW1pdHRlcigpIHtcbiAgbGV0IGV2ZW50czogeyBbZXZlbnQ6IHN0cmluZ106IENhbGxhYmxlW10gfSA9IHt9XG5cbiAgZnVuY3Rpb24gZW1pdChldjogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSk6IHZvaWQge1xuICAgIGV2ZW50c1tldl0gPyBldmVudHNbZXZdLm1hcCgoZm46IENhbGxhYmxlKSA9PiBmbiguLi5hcmdzKSkgOiBbXVxuICB9XG5cbiAgZnVuY3Rpb24gb24oZXY6IHN0cmluZywgZm46ICguLi5hcmdzOiBhbnlbXSkgPT4gdm9pZCkge1xuICAgIGV2ZW50c1tldl0gPSBldmVudHNbZXZdID8gZXZlbnRzW2V2XS5jb25jYXQoZm4pIDogW2ZuXVxuICAgIHJldHVybiAoKSA9PiBldmVudHNbZXZdLnNwbGljZShldmVudHNbZXZdLmluZGV4T2YoZm4pLCAxKVxuICB9XG5cbiAgZnVuY3Rpb24gY2xlYXIoKSB7XG4gICAgZXZlbnRzID0ge31cbiAgfVxuXG4gIGZ1bmN0aW9uIGxpc3RlbmVycyhldjogc3RyaW5nKSB7XG4gICAgcmV0dXJuIGV2ZW50c1tldl0gfHwgW11cbiAgfVxuXG4gIHJldHVybiB7XG4gICAgZW1pdCxcbiAgICBvbixcbiAgICBjbGVhcixcbiAgICBsaXN0ZW5lcnMsXG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUVtaXRIb29rKG5hbWU6IHN0cmluZywgZW1pdHRlcjogUmV0dXJuVHlwZTx0eXBlb2YgY3JlYXRlRW1pdHRlcj4pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGhvb2s8VD4ocHJvcHM6IFQpIHtcbiAgICBlbWl0dGVyLmVtaXQobmFtZSwgcHJvcHMpXG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZU9uSG9vayhuYW1lOiBzdHJpbmcsIGVtaXR0ZXI6IFJldHVyblR5cGU8dHlwZW9mIGNyZWF0ZUVtaXR0ZXI+KSB7XG4gIHJldHVybiBmdW5jdGlvbiBob29rKGNhbGxiYWNrOiBDYWxsYWJsZSkge1xuICAgIHJldHVybiBlbWl0dGVyLm9uKG5hbWUsIGNhbGxiYWNrKVxuICB9XG59XG4iLCAiaW1wb3J0IGZzIGZyb20gJ2ZzLWV4dHJhJ1xuLy8gQHRzLWlnbm9yZVxuaW1wb3J0IGdyYXBoIGZyb20gJ3dhdGNoLWRlcGVuZGVuY3ktZ3JhcGgnXG5pbXBvcnQgY2hva2lkYXIgZnJvbSAnY2hva2lkYXInXG5pbXBvcnQgbWF0Y2ggZnJvbSAncGljb21hdGNoJ1xuXG5pbXBvcnQgeyBvdXRwdXRMYW1iZGFzIH0gZnJvbSAnLi9vdXRwdXRMYW1iZGFzJ1xuaW1wb3J0ICogYXMgbG9nZ2VyIGZyb20gJy4vbG9nJ1xuaW1wb3J0IHsgZ2V0RmlsZXMsIGlzU3RhdGljLCBpc0R5bmFtaWMgfSBmcm9tICcuL2dldEZpbGVzJ1xuaW1wb3J0IHsgcmVuZGVyU3RhdGljRW50cmllcyB9IGZyb20gJy4vcmVuZGVyU3RhdGljRW50cmllcydcbmltcG9ydCB7IHRpbWVyIH0gZnJvbSAnLi90aW1lcidcbmltcG9ydCB7IGNyZWF0ZUNvbmZpZywgcmVtb3ZlQ29uZmlnVmFsdWVzLCBnZXRDb25maWdGaWxlIH0gZnJvbSAnLi9jb25maWcnXG5pbXBvcnQgeyBidWlsdFN0YXRpY0ZpbGVzIH0gZnJvbSAnLi9idWlsdFN0YXRpY0ZpbGVzJ1xuaW1wb3J0IHsgcmVtb3ZlQnVpbHRTdGF0aWNGaWxlIH0gZnJvbSAnLi9yZW1vdmVCdWlsdFN0YXRpY0ZpbGUnXG5pbXBvcnQgeyBQcmVzdGEgfSBmcm9tICcuL3R5cGVzJ1xuXG4vKlxuICogV3JhcHMgb3V0cHV0TGFtYmRhcyBmb3IgbG9nZ2luZ1xuICovXG5mdW5jdGlvbiB1cGRhdGVMYW1iZGFzKGlucHV0czogc3RyaW5nW10sIGNvbmZpZzogUHJlc3RhKSB7XG4gIGNvbnN0IHRpbWUgPSB0aW1lcigpXG5cbiAgLy8gYWx3YXlzIHdyaXRlIHRoaXMsIGV2ZW4gaWYgaW5wdXRzID0gW11cbiAgb3V0cHV0TGFtYmRhcyhpbnB1dHMsIGNvbmZpZylcblxuICAvLyBpZiB1c2VyIGFjdHVhbGx5IGhhcyByb3V0ZXMgY29uZmlndXJlZCwgZ2l2ZSBmZWVkYmFja1xuICBpZiAoaW5wdXRzLmxlbmd0aCkge1xuICAgIGxvZ2dlci5pbmZvKHtcbiAgICAgIGxhYmVsOiAnYnVpbHQnLFxuICAgICAgbWVzc2FnZTogYGxhbWJkYXNgLFxuICAgICAgZHVyYXRpb246IHRpbWUoKSxcbiAgICB9KVxuICB9XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB3YXRjaChjb25maWc6IFByZXN0YSkge1xuICAvKlxuICAgKiBHZXQgZmlsZXMgdGhhdCBtYXRjaCBzdGF0aWMvZHluYW1pYyBwYXR0ZXJzIGF0IHN0YXJ0dXBcbiAgICovXG4gIGxldCBmaWxlcyA9IGdldEZpbGVzKGNvbmZpZylcbiAgbGV0IGhhc0NvbmZpZ0ZpbGUgPSBmcy5leGlzdHNTeW5jKGNvbmZpZy5jb25maWdGaWxlcGF0aClcblxuICBpZiAoIWZpbGVzLmxlbmd0aCkge1xuICAgIGxvZ2dlci53YXJuKHtcbiAgICAgIGxhYmVsOiAncGF0aHMnLFxuICAgICAgbWVzc2FnZTogJ25vIGZpbGVzIGNvbmZpZ3VyZWQnLFxuICAgIH0pXG4gIH1cblxuICAvKlxuICAgKiBDcmVhdGUgaW5pdGlhbCBkeW5hbWljIGVudHJ5IHJlZ2FyZGxlc3Mgb2YgaWYgdGhlIHVzZXIgaGFzIHJvdXRlcywgYmMgd2VcbiAgICogbmVlZCB0aGlzIGZpbGUgdG8gc2VydmUgNDA0IGxvY2FsbHlcbiAgICovXG4gIHVwZGF0ZUxhbWJkYXMoZmlsZXMuZmlsdGVyKGlzRHluYW1pYyksIGNvbmZpZylcblxuICAvKlxuICAgKiBTZXQgdXAgYWxsIHdhdGNoZXJzXG4gICAqL1xuICBjb25zdCBmaWxlV2F0Y2hlciA9IGdyYXBoKHsgYWxpYXM6IHsgJ0AnOiBjb25maWcuY3dkIH0gfSlcbiAgY29uc3QgZ2xvYmFsV2F0Y2hlciA9IGNob2tpZGFyLndhdGNoKGNvbmZpZy5jd2QsIHtcbiAgICBpZ25vcmVJbml0aWFsOiB0cnVlLFxuICAgIGlnbm9yZWQ6IFtjb25maWcub3V0cHV0LCBjb25maWcuYXNzZXRzXSxcbiAgfSlcblxuICAvKlxuICAgKiBPbiBhIGNvbmZpZyB1cGRhdGUsIHRoZSB1c2VyIG1heSBoYXZlIHBhc3NlZCBpbiBhIG5ldyBgZmlsZXNgIGFycmF5IG9yXG4gICAqIG90aGVyIGdsb2JhbCBjb25maWcgcmVxdWlyZWQgYnkgYWxsIGZpbGVzLCBzbyB3ZSBuZWVkIHRvIHJlLWZldGNoIGFsbFxuICAgKiBmaWxlcyBhbmQgcmVidWlsZCBldmVyeXRoaW5nLlxuICAgKi9cbiAgYXN5bmMgZnVuY3Rpb24gaGFuZGxlQ29uZmlnVXBkYXRlKCkge1xuICAgIGZpbGVzID0gZ2V0RmlsZXMoY29uZmlnKVxuICAgIGF3YWl0IHJlbmRlclN0YXRpY0VudHJpZXMoZmlsZXMuZmlsdGVyKGlzU3RhdGljKSwgY29uZmlnKVxuICAgIHVwZGF0ZUxhbWJkYXMoZmlsZXMuZmlsdGVyKGlzRHluYW1pYyksIGNvbmZpZylcbiAgfVxuXG4gIC8qXG4gICAqIE9uIGEgY2hhbmdlZCBmaWxlLCB3ZSBjYW4ganVzdCByZW5kZXIgaXRcbiAgICovXG4gIGFzeW5jIGZ1bmN0aW9uIGhhbmRsZUZpbGVDaGFuZ2UoZmlsZTogc3RyaW5nKSB7XG4gICAgLy8gcmVuZGVyIGp1c3QgZmlsZSB0aGF0IGNoYW5nZWRcbiAgICBpZiAoaXNTdGF0aWMoZmlsZSkpIHtcbiAgICAgIGF3YWl0IHJlbmRlclN0YXRpY0VudHJpZXMoW2ZpbGVdLCBjb25maWcpXG4gICAgfVxuXG4gICAgLy8gdXBkYXRlIGR5bmFtaWMgZW50cnkgd2l0aCBBTEwgZHluYW1pYyBmaWxlc1xuICAgIGlmIChpc0R5bmFtaWMoZmlsZSkpIHtcbiAgICAgIHVwZGF0ZUxhbWJkYXMoZmlsZXMuZmlsdGVyKGlzRHluYW1pYyksIGNvbmZpZylcbiAgICB9XG5cbiAgICBjb25maWcuaG9va3MuZW1pdEJyb3dzZXJSZWZyZXNoKClcbiAgfVxuXG4gIGNvbmZpZy5ob29rcy5vbkJ1aWxkRmlsZSgoeyBmaWxlIH0pID0+IHtcbiAgICBoYW5kbGVGaWxlQ2hhbmdlKGZpbGUpXG4gIH0pXG5cbiAgZmlsZVdhdGNoZXIub24oJ3JlbW92ZScsIGFzeW5jIChbaWRdOiBzdHJpbmdbXSkgPT4ge1xuICAgIGxvZ2dlci5kZWJ1Zyh7XG4gICAgICBsYWJlbDogJ3dhdGNoJyxcbiAgICAgIG1lc3NhZ2U6IGBmaWxlV2F0Y2hlciAtIHJlbW92ZWQgJHtpZH1gLFxuICAgIH0pXG5cbiAgICAvLyByZW1vdmUgZnJvbSBsb2NhbCBoYXNoXG4gICAgZmlsZXMuc3BsaWNlKGZpbGVzLmluZGV4T2YoaWQpLCAxKVxuXG4gICAgLy8gdXBkYXRlIHRoaXMgcmVnYXJkbGVzcywgbm90IHN1cmUgaWYgW2lkXSB3YXMgZHluYW1pYyBvciBzdGF0aWNcbiAgICB1cGRhdGVMYW1iZGFzKGZpbGVzLmZpbHRlcihpc0R5bmFtaWMpLCBjb25maWcpXG5cbiAgICAvLyBpZiBpdCB3YXMgY29uZmlnLCB3ZSBnb3R0YSBkbyBhIHJlc3RhcnRcbiAgICBpZiAoaWQgPT09IGNvbmZpZy5jb25maWdGaWxlcGF0aCkge1xuICAgICAgLy8gZmlsdGVyIG91dCB2YWx1ZXMgZnJvbSB0aGUgY29uZmlnIGZpbGVcbiAgICAgIGNvbmZpZyA9IGF3YWl0IHJlbW92ZUNvbmZpZ1ZhbHVlcygpXG5cbiAgICAgIC8vIHJlc2V0IHRoaXMhXG4gICAgICBoYXNDb25maWdGaWxlID0gZmFsc2VcblxuICAgICAgaGFuZGxlQ29uZmlnVXBkYXRlKClcbiAgICB9XG5cbiAgICA7KGJ1aWx0U3RhdGljRmlsZXNbaWRdIHx8IFtdKS5mb3JFYWNoKChmaWxlKSA9PiByZW1vdmVCdWlsdFN0YXRpY0ZpbGUoZmlsZSwgY29uZmlnKSlcbiAgfSlcblxuICBmaWxlV2F0Y2hlci5vbignY2hhbmdlJywgYXN5bmMgKFtpZF06IHN0cmluZ1tdKSA9PiB7XG4gICAgbG9nZ2VyLmRlYnVnKHtcbiAgICAgIGxhYmVsOiAnd2F0Y2gnLFxuICAgICAgbWVzc2FnZTogYGZpbGVXYXRjaGVyIC0gY2hhbmdlZCAke2lkfWAsXG4gICAgfSlcblxuICAgIGlmIChpZCA9PT0gY29uZmlnLmNvbmZpZ0ZpbGVwYXRoKSB7XG4gICAgICAvLyBjbGVhciBjb25maWcgZmlsZSBmb3IgcmUtcmVxdWlyZVxuICAgICAgZGVsZXRlIHJlcXVpcmUuY2FjaGVbY29uZmlnLmNvbmZpZ0ZpbGVwYXRoXVxuXG4gICAgICB0cnkge1xuICAgICAgICAvLyBtZXJnZSBpbiBuZXcgdmFsdWVzIGZyb20gY29uZmlnIGZpbGVcbiAgICAgICAgY29uZmlnID0gYXdhaXQgY3JlYXRlQ29uZmlnKHtcbiAgICAgICAgICBjb25maWc6IGdldENvbmZpZ0ZpbGUoY29uZmlnLmNvbmZpZ0ZpbGVwYXRoKSxcbiAgICAgICAgfSlcblxuICAgICAgICBoYW5kbGVDb25maWdVcGRhdGUoKVxuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBsb2dnZXIuZXJyb3Ioe1xuICAgICAgICAgIGxhYmVsOiAnZXJyb3InLFxuICAgICAgICAgIGVycm9yOiBlIGFzIEVycm9yLFxuICAgICAgICB9KVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBoYW5kbGVGaWxlQ2hhbmdlKGlkKVxuICAgIH1cbiAgfSlcblxuICBmaWxlV2F0Y2hlci5vbignZXJyb3InLCAoZTogRXJyb3IpID0+IHtcbiAgICBsb2dnZXIuZXJyb3Ioe1xuICAgICAgbGFiZWw6ICdlcnJvcicsXG4gICAgICBlcnJvcjogZSxcbiAgICB9KVxuICB9KVxuXG4gIC8qXG4gICAqIGdsb2JhbFdhdGNoZXIgd2F0Y2hlcyB0aGUgcmF3IGZpbGUgZ2xvYnMgcGFzc2VkIHRvIHRoZSBDTEkgb3IgYXMgYGZpbGVzYFxuICAgKiBpbiB0aGUgY29uZmlnLiBJZiBjaGVja3Mgb24gYWRkL2NoYW5nZSB0byBzZWUgaWYgYSBmaWxlIHNob3VsZCBiZSB1cGdyYWRlZFxuICAgKiB0byBhIGEgUHJlc3RhIHNvdXJjZSBmaWxlLCBhbmQgYWRkZWQgdG8gdGhlIGZpbGVXYXRjaGVyLiBJdCBhbHNvIHdhdGNoZXNcbiAgICogZm9yIGFkZGl0aW9uIG9mIGEgY29uZmlnIGZpbGUuXG4gICAqL1xuICBnbG9iYWxXYXRjaGVyLm9uKCdhbGwnLCBhc3luYyAoZXZlbnQsIGZpbGUpID0+IHtcbiAgICAvLyBpZ25vcmUgZXZlbnRzIGhhbmRsZWQgYnkgd2RnLCBvciBhbnkgZGlyZWN0b3J5IGV2ZW50c1xuICAgIGlmICghL2FkZHxjaGFuZ2UvLnRlc3QoZXZlbnQpIHx8ICFmcy5leGlzdHNTeW5jKGZpbGUpIHx8IGZzLmxzdGF0U3luYyhmaWxlKS5pc0RpcmVjdG9yeSgpKSByZXR1cm5cblxuICAgIC8vIGlmIGEgZmlsZSBjaGFuZ2UgbWF0Y2hlcyBhbnkgcGFnZXMgZ2xvYnNcbiAgICBpZiAobWF0Y2goY29uZmlnLmZpbGVzKShmaWxlKSAmJiAhZmlsZXMuaW5jbHVkZXMoZmlsZSkpIHtcbiAgICAgIGxvZ2dlci5kZWJ1Zyh7XG4gICAgICAgIGxhYmVsOiAnd2F0Y2gnLFxuICAgICAgICBtZXNzYWdlOiBgZ2xvYmFsV2F0Y2hlciAtIGFkZCAke2ZpbGV9YCxcbiAgICAgIH0pXG5cbiAgICAgIGZpbGVzLnB1c2goZmlsZSlcblxuICAgICAgZmlsZVdhdGNoZXIuYWRkKGZpbGUpXG5cbiAgICAgIGhhbmRsZUZpbGVDaGFuZ2UoZmlsZSlcbiAgICB9XG5cbiAgICAvLyBpZiBmaWxlIG1hdGNoZXMgY29uZmlnIGZpbGUgYW5kIHdlIGRvbid0IGFscmVhZHkgaGF2ZSBvbmVcbiAgICBpZiAoZmlsZSA9PT0gY29uZmlnLmNvbmZpZ0ZpbGVwYXRoICYmICFoYXNDb25maWdGaWxlKSB7XG4gICAgICBsb2dnZXIuZGVidWcoe1xuICAgICAgICBsYWJlbDogJ3dhdGNoJyxcbiAgICAgICAgbWVzc2FnZTogYGdsb2JhbFdhdGNoZXIgLSBhZGQgY29uZmlnIGZpbGUgJHtmaWxlfWAsXG4gICAgICB9KVxuXG4gICAgICBmaWxlV2F0Y2hlci5hZGQoY29uZmlnLmNvbmZpZ0ZpbGVwYXRoKVxuXG4gICAgICB0cnkge1xuICAgICAgICAvLyBtZXJnZSBpbiBuZXcgdmFsdWVzIGZyb20gY29uZmlnIGZpbGVcbiAgICAgICAgY29uZmlnID0gYXdhaXQgY3JlYXRlQ29uZmlnKHtcbiAgICAgICAgICBjb25maWc6IGdldENvbmZpZ0ZpbGUoY29uZmlnLmNvbmZpZ0ZpbGVwYXRoKSxcbiAgICAgICAgfSlcblxuICAgICAgICBoYXNDb25maWdGaWxlID0gdHJ1ZVxuXG4gICAgICAgIGhhbmRsZUNvbmZpZ1VwZGF0ZSgpXG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGxvZ2dlci5lcnJvcih7XG4gICAgICAgICAgbGFiZWw6ICdlcnJvcicsXG4gICAgICAgICAgZXJyb3I6IGUgYXMgRXJyb3IsXG4gICAgICAgIH0pXG4gICAgICB9XG4gICAgfVxuICB9KVxuXG4gIC8qKlxuICAgKiBJbml0IHdhdGNoaW5nIGFmdGVyIGV2ZW50IHN1YnNjcmlwdGlvbnNcbiAgICovXG4gIGZpbGVXYXRjaGVyLmFkZChmaWxlcylcbiAgaWYgKGhhc0NvbmZpZ0ZpbGUpIGZpbGVXYXRjaGVyLmFkZChjb25maWcuY29uZmlnRmlsZXBhdGgpXG5cbiAgLyoqXG4gICAqIFByaW1lIGZpbGVzIHRvIGNoZWNrIGZvciBlcnJvcnMgb24gc3RhcnR1cCBhbmQgcmVnaXN0ZXIgYW55IHBsdWdpbnNcbiAgICovXG4gIHRyeSB7XG4gICAgZmlsZXMubWFwKHJlcXVpcmUpXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBsb2dnZXIuZXJyb3Ioe1xuICAgICAgbGFiZWw6ICdlcnJvcicsXG4gICAgICBlcnJvcjogZSBhcyBFcnJvcixcbiAgICB9KVxuICB9XG59XG4iLCAiaW1wb3J0IGZzIGZyb20gJ2ZzLWV4dHJhJ1xuaW1wb3J0IHBhdGggZnJvbSAncGF0aCdcbmltcG9ydCByc29ydCBmcm9tICdyb3V0ZS1zb3J0J1xuXG5pbXBvcnQgeyBoYXNoQ29udGVudCB9IGZyb20gJy4vaGFzaENvbnRlbnQnXG5pbXBvcnQgKiBhcyBsb2dnZXIgZnJvbSAnLi9sb2cnXG5pbXBvcnQgeyBQcmVzdGEgfSBmcm9tICcuL3R5cGVzJ1xuaW1wb3J0IHsgRW52IH0gZnJvbSAnLi9jb25zdGFudHMnXG5cbmV4cG9ydCBmdW5jdGlvbiBvdXRwdXRMYW1iZGEoaW5wdXQ6IHN0cmluZywgY29uZmlnOiBQcmVzdGEpOiBbc3RyaW5nLCBzdHJpbmddIHtcbiAgY29uc3QgeyByb3V0ZSB9ID0gcmVxdWlyZShpbnB1dClcbiAgY29uc3QgbmFtZSA9IHBhdGguYmFzZW5hbWUoaW5wdXQpLnNwbGl0KCcuJykucmV2ZXJzZSgpLnNsaWNlKDEpLnJldmVyc2UoKS5qb2luKCcuJylcbiAgY29uc3Qgb3V0cHV0ID0gcGF0aC5qb2luKFxuICAgIGNvbmZpZy5mdW5jdGlvbnNPdXRwdXREaXIsXG4gICAgY29uZmlnLmVudiA9PT0gRW52LlBST0RVQ1RJT04gPyBuYW1lICsgJy0nICsgaGFzaENvbnRlbnQoZnMucmVhZEZpbGVTeW5jKGlucHV0LCAndXRmOCcpKSArICcuanMnIDogbmFtZSArICcuanMnXG4gIClcblxuICBsb2dnZXIuZGVidWcoe1xuICAgIGxhYmVsOiAnZGVidWcnLFxuICAgIG1lc3NhZ2U6IGBnZW5lcmF0aW5nICR7bmFtZX0gbGFtYmRhYCxcbiAgfSlcblxuICAvLyBpbXBvcnRhbnQgZm9yIHdhdGNoIHRhc2tcbiAgZGVsZXRlIHJlcXVpcmUuY2FjaGVbaW5wdXRdXG4gIGRlbGV0ZSByZXF1aXJlLmNhY2hlW291dHB1dF1cblxuICBmcy5vdXRwdXRGaWxlU3luYyhcbiAgICBvdXRwdXQsXG4gICAgYGltcG9ydCB7IHdyYXBIYW5kbGVyIH0gZnJvbSAncHJlc3RhJztcbmltcG9ydCAqIGFzIGZpbGUgZnJvbSAnJHtpbnB1dH0nO1xuZXhwb3J0IGNvbnN0IHJvdXRlID0gZmlsZS5yb3V0ZVxuZXhwb3J0IGNvbnN0IGhhbmRsZXIgPSB3cmFwSGFuZGxlcihmaWxlKWBcbiAgKVxuXG4gIHJldHVybiBbcm91dGUsIG91dHB1dF1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG91dHB1dExhbWJkYXMoaW5wdXRzOiBzdHJpbmdbXSwgY29uZmlnOiBQcmVzdGEpIHtcbiAgY29uc3QgbGFtYmRhcyA9IGlucHV0c1xuICAgIC5tYXAoKGlucHV0KSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gb3V0cHV0TGFtYmRhKGlucHV0LCBjb25maWcpXG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGxvZ2dlci5lcnJvcih7XG4gICAgICAgICAgbGFiZWw6ICdlcnJvcicsXG4gICAgICAgICAgZXJyb3I6IGUgYXMgRXJyb3IsXG4gICAgICAgIH0pXG4gICAgICAgIHJldHVybiBudWxsXG4gICAgICB9XG4gICAgfSlcbiAgICAuZmlsdGVyKEJvb2xlYW4pIGFzIFtzdHJpbmcsIHN0cmluZ11bXVxuXG4gIGNvbnN0IHNvcnRlZCA9IHJzb3J0KGxhbWJkYXMubWFwKChsKSA9PiBsWzBdKSlcbiAgY29uc3QgbWFuaWZlc3Q6IHsgW3JvdXRlOiBzdHJpbmddOiBzdHJpbmcgfSA9IHt9XG5cbiAgZm9yIChjb25zdCByb3V0ZSBvZiBzb3J0ZWQpIHtcbiAgICBjb25zdCBtYXRjaCA9IGxhbWJkYXMuZmluZCgobCkgPT4gbFswXSA9PT0gcm91dGUpXG5cbiAgICBpZiAobWF0Y2gpIHtcbiAgICAgIG1hbmlmZXN0W3JvdXRlXSA9IG1hdGNoWzFdXG4gICAgfVxuICB9XG5cbiAgZnMub3V0cHV0RmlsZVN5bmMoY29uZmlnLmZ1bmN0aW9uc01hbmlmZXN0LCBKU09OLnN0cmluZ2lmeShtYW5pZmVzdCkpXG5cbiAgcmV0dXJuIGxhbWJkYXNcbn1cbiIsICJleHBvcnQgZnVuY3Rpb24gaGFzaENvbnRlbnQoY29udGVudDogc3RyaW5nKSB7XG4gIHZhciBoID0gNTM4MSxcbiAgICBpID0gY29udGVudC5sZW5ndGhcblxuICB3aGlsZSAoaSkgaCA9IChoICogMzMpIF4gY29udGVudC5jaGFyQ29kZUF0KC0taSlcblxuICByZXR1cm4gKGggPj4+IDApLnRvU3RyaW5nKDM2KVxufVxuIiwgImltcG9ydCBmcyBmcm9tICdmcy1leHRyYSdcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnXG5pbXBvcnQgZ2xvYlN5bmMgZnJvbSAndGlueS1nbG9iL3N5bmMnXG5cbmltcG9ydCAqIGFzIGxvZ2dlciBmcm9tICcuL2xvZydcbmltcG9ydCB7IFByZXN0YSB9IGZyb20gJy4vdHlwZXMnXG5cbmV4cG9ydCBmdW5jdGlvbiBpc0R5bmFtaWMoZmlsZTogc3RyaW5nKSB7XG4gIHJldHVybiAvZXhwb3J0XFxzLitcXHNyb3V0ZVxccytcXD0vLnRlc3QoZnMucmVhZEZpbGVTeW5jKGZpbGUsICd1dGYtOCcpKVxufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNTdGF0aWMoZmlsZTogc3RyaW5nKSB7XG4gIHJldHVybiAvZXhwb3J0XFxzLitcXHNnZXRTdGF0aWNQYXRocy8udGVzdChmcy5yZWFkRmlsZVN5bmMoZmlsZSwgJ3V0Zi04JykpXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1ByZXN0YUZpbGUoZmlsZTogc3RyaW5nKSB7XG4gIHJldHVybiBpc1N0YXRpYyhmaWxlKSB8fCBpc0R5bmFtaWMoZmlsZSlcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEZpbGVzKGNvbmZpZzogUHJlc3RhKTogc3RyaW5nW10ge1xuICB0cnkge1xuICAgIHJldHVybiAoW10gYXMgc3RyaW5nW10pXG4gICAgICAuY29uY2F0KGNvbmZpZy5maWxlcylcbiAgICAgIC5tYXAoKGZpbGUpID0+IGdsb2JTeW5jKGZpbGUsIHsgY3dkOiBjb25maWcuY3dkIH0pKVxuICAgICAgLmZsYXQoKVxuICAgICAgLm1hcCgoZmlsZSkgPT4gcGF0aC5yZXNvbHZlKGNvbmZpZy5jd2QsIGZpbGUpKSAvLyBtYWtlIGFic29sdXRlXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBsb2dnZXIuZXJyb3Ioe1xuICAgICAgbGFiZWw6ICdwYXRocycsXG4gICAgICBtZXNzYWdlOiBgbm8gZmlsZXMgZm91bmRgLFxuICAgICAgZXJyb3I6IGUgYXMgRXJyb3IsXG4gICAgfSlcblxuICAgIHJldHVybiBbXVxuICB9XG59XG4iLCAiaW1wb3J0IGZzIGZyb20gJ2ZzLWV4dHJhJ1xuaW1wb3J0IHBhdGggZnJvbSAncGF0aCdcbmltcG9ydCBtaW1lIGZyb20gJ21pbWUtdHlwZXMnXG5cbmltcG9ydCAqIGFzIGxvZ2dlciBmcm9tICcuL2xvZydcbmltcG9ydCB7IHRpbWVyIH0gZnJvbSAnLi90aW1lcidcbmltcG9ydCB7IGdldFJvdXRlUGFyYW1zIH0gZnJvbSAnLi9nZXRSb3V0ZVBhcmFtcydcbmltcG9ydCB7IG5vcm1hbGl6ZVJlc3BvbnNlIH0gZnJvbSAnLi9ub3JtYWxpemVSZXNwb25zZSdcbmltcG9ydCB7IGJ1aWx0U3RhdGljRmlsZXMgfSBmcm9tICcuL2J1aWx0U3RhdGljRmlsZXMnXG5pbXBvcnQgeyByZW1vdmVCdWlsdFN0YXRpY0ZpbGUgfSBmcm9tICcuL3JlbW92ZUJ1aWx0U3RhdGljRmlsZSdcbmltcG9ydCB7IFByZXN0YSB9IGZyb20gJy4vdHlwZXMnXG5cbmV4cG9ydCBmdW5jdGlvbiBwYXRobmFtZVRvRmlsZShwYXRobmFtZTogc3RyaW5nLCBleHQgPSAnaHRtbCcpIHtcbiAgcmV0dXJuICEhcGF0aC5leHRuYW1lKHBhdGhuYW1lKVxuICAgID8gcGF0aG5hbWUgLy8gaWYgcGF0aCBoYXMgZXh0ZW5zaW9uLCB1c2UgaXRcbiAgICA6IGV4dCA9PT0gJ2h0bWwnXG4gICAgPyBgJHtwYXRobmFtZX0vaW5kZXguaHRtbGAgLy8gaWYgSFRNTCBpcyBpbmZlcnJlZCwgY3JlYXRlIGluZGV4XG4gICAgOiBgJHtwYXRobmFtZX0uJHtleHR9YCAvLyBhbnl0aGluZyBidXQgSFRNTCB3aWxsIG5lZWQgYW4gZXh0ZW5zaW9uLCBvdGhlcndpc2UgYnJvd3NlcnMgd2lsbCByZW5kZXIgYXMgdGV4dFxufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVuZGVyU3RhdGljRW50cmllcyhlbnRyaWVzOiBzdHJpbmdbXSwgY29uZmlnOiBQcmVzdGEpOiBQcm9taXNlPHsgYWxsR2VuZXJhdGVkRmlsZXM6IHN0cmluZ1tdIH0+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKGFzeW5jICh5LCBuKSA9PiB7XG4gICAgbG9nZ2VyLmRlYnVnKHtcbiAgICAgIGxhYmVsOiAnZGVidWcnLFxuICAgICAgbWVzc2FnZTogYHJlbmRlcmluZyAke0pTT04uc3RyaW5naWZ5KGVudHJpZXMpfWAsXG4gICAgfSlcblxuICAgIGNvbnN0IGFsbEdlbmVyYXRlZEZpbGVzOiBzdHJpbmdbXSA9IFtdXG5cbiAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIGVudHJpZXMpIHtcbiAgICAgIGNvbnN0IGxvY2F0aW9uID0gZW50cnkucmVwbGFjZShjb25maWcuY3dkLCAnJylcblxuICAgICAgdHJ5IHtcbiAgICAgICAgZGVsZXRlIHJlcXVpcmUuY2FjaGVbZW50cnldXG5cbiAgICAgICAgY29uc3QgZmlsZSA9IHJlcXVpcmUoZW50cnkpXG4gICAgICAgIGNvbnN0IHBhdGhzID0gYXdhaXQgZmlsZS5nZXRTdGF0aWNQYXRocygpXG5cbiAgICAgICAgY29uc3QgcHJldkZpbGVzID0gKGJ1aWx0U3RhdGljRmlsZXNbZW50cnldID0gYnVpbHRTdGF0aWNGaWxlc1tlbnRyeV0gfHwgW10pXG4gICAgICAgIGNvbnN0IG5leHRGaWxlczogc3RyaW5nW10gPSBbXVxuXG4gICAgICAgIGlmICghcGF0aHMgfHwgIXBhdGhzLmxlbmd0aCkge1xuICAgICAgICAgIGxvZ2dlci53YXJuKHtcbiAgICAgICAgICAgIGxhYmVsOiAncGF0aHMnLFxuICAgICAgICAgICAgbWVzc2FnZTogYCR7bG9jYXRpb259IC0gbm8gcGF0aHMgdG8gcmVuZGVyYCxcbiAgICAgICAgICB9KVxuXG4gICAgICAgICAgcHJldkZpbGVzLmZvckVhY2goKGZpbGUpID0+IHJlbW92ZUJ1aWx0U3RhdGljRmlsZShmaWxlLCBjb25maWcpKVxuXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoY29uc3QgdXJsIG9mIHBhdGhzKSB7XG4gICAgICAgICAgY29uc3QgdGltZSA9IHRpbWVyKClcbiAgICAgICAgICBjb2