UNPKG

@jahands/dagger-helpers

Version:

dagger.io helpers for my own projects - not meant for public use

4 lines 125 kB
var M={workersMonorepo:{ignore:["**/node_modules/","**/.env","**/.secret","**/.wrangler","**/.dev.vars","**/.turbo/","**/dist/","**/dist2/","**/.DS_Store","**/.astro/","**/.next/","*.env"]}};import{AsyncLocalStorage as N}from"node:async_hooks";var E=new N;function B(e){let t=e.toString().replace(/(\r\n|\n|\r)/gm,""),n=t.match(/(?:async\s*)?(?:function\s*[\w\s]*)?\(([^)]*)\)/)??t.match(/^\s*(?:async\s*)?\(([^)]*)\)/);if(!n||typeof n[1]>"u")return console.warn("Could not extract parameter names from function string:",t),[];let o=n[1].replace(/\/\*.*?\*\//g,"").replace(/\/\/.*?$/gm,"");return o.trim()?o.split(",").map(s=>s.split(/[:=]/)[0]?.trim()??"").filter(s=>s.length>0):[]}function D(){return function(e,t,n){if(typeof n>"u"||typeof n.value!="function")throw new Error(`@ParamsToEnv decorator can only be applied to methods, not: ${String(t)}`);let r=n.value,o=null;n.value=function(...s){let c=E.getStore();o===null&&(o=B(r),o.length,s.length);let l={},w=new Set;o?.forEach((k,U)=>{/^[A-Z0-9_]+$/.test(k)&&(w.add(k),U<s.length&&(l[k]=s[U]))});let C={...c?.mergedEnv??{},...l},z={currentParams:w,mergedEnv:C};return E.run(z,()=>r.apply(this,s))}}}var m=Symbol.for("@ts-pattern/matcher"),Z=Symbol.for("@ts-pattern/isVariadic"),b="@ts-pattern/anonymous-select-key",F=e=>!!(e&&typeof e=="object"),T=e=>e&&!!e[m],f=(e,t,n)=>{if(T(e)){let r=e[m](),{matched:o,selections:s}=r.match(t);return o&&s&&Object.keys(s).forEach(c=>n(c,s[c])),o}if(F(e)){if(!F(t))return!1;if(Array.isArray(e)){if(!Array.isArray(t))return!1;let r=[],o=[],s=[];for(let c of e.keys()){let l=e[c];T(l)&&l[Z]?s.push(l):s.length?o.push(l):r.push(l)}if(s.length){if(s.length>1)throw new Error("Pattern error: Using `...P.array(...)` several times in a single pattern is not allowed.");if(t.length<r.length+o.length)return!1;let c=t.slice(0,r.length),l=o.length===0?[]:t.slice(-o.length),w=t.slice(r.length,o.length===0?1/0:-o.length);return r.every((g,C)=>f(g,c[C],n))&&o.every((g,C)=>f(g,l[C],n))&&(s.length===0||f(s[0],w,n))}return e.length===t.length&&e.every((c,l)=>f(c,t[l],n))}return Reflect.ownKeys(e).every(r=>{let o=e[r];return(r in t||T(s=o)&&s[m]().matcherType==="optional")&&f(o,t[r],n);var s})}return Object.is(t,e)},S=e=>{var t,n,r;return F(e)?T(e)?(t=(n=(r=e[m]()).getSelectionKeys)==null?void 0:n.call(r))!=null?t:[]:Array.isArray(e)?$(e,S):$(Object.values(e),S):[]},$=(e,t)=>e.reduce((n,r)=>n.concat(t(r)),[]);function u(e){return Object.assign(e,{optional:()=>W(e),and:t=>a(e,t),or:t=>J(e,t),select:t=>t===void 0?L(e):L(t,e)})}function W(e){return u({[m]:()=>({match:t=>{let n={},r=(o,s)=>{n[o]=s};return t===void 0?(S(e).forEach(o=>r(o,void 0)),{matched:!0,selections:n}):{matched:f(e,t,r),selections:n}},getSelectionKeys:()=>S(e),matcherType:"optional"})})}function a(...e){return u({[m]:()=>({match:t=>{let n={},r=(o,s)=>{n[o]=s};return{matched:e.every(o=>f(o,t,r)),selections:n}},getSelectionKeys:()=>$(e,S),matcherType:"and"})})}function J(...e){return u({[m]:()=>({match:t=>{let n={},r=(o,s)=>{n[o]=s};return $(e,S).forEach(o=>r(o,void 0)),{matched:e.some(o=>f(o,t,r)),selections:n}},getSelectionKeys:()=>$(e,S),matcherType:"or"})})}function i(e){return{[m]:()=>({match:t=>({matched:!!e(t)})})}}function L(...e){let t=typeof e[0]=="string"?e[0]:void 0,n=e.length===2?e[1]:typeof e[0]=="string"?void 0:e[0];return u({[m]:()=>({match:r=>{let o={[t??b]:r};return{matched:n===void 0||f(n,r,(s,c)=>{o[s]=c}),selections:o}},getSelectionKeys:()=>[t??b].concat(n===void 0?[]:S(n))})})}function p(e){return typeof e=="number"}function d(e){return typeof e=="string"}function y(e){return typeof e=="bigint"}var le=u(i(function(e){return!0}));var v=e=>Object.assign(u(e),{startsWith:t=>{return v(a(e,(n=t,i(r=>d(r)&&r.startsWith(n)))));var n},endsWith:t=>{return v(a(e,(n=t,i(r=>d(r)&&r.endsWith(n)))));var n},minLength:t=>v(a(e,(n=>i(r=>d(r)&&r.length>=n))(t))),length:t=>v(a(e,(n=>i(r=>d(r)&&r.length===n))(t))),maxLength:t=>v(a(e,(n=>i(r=>d(r)&&r.length<=n))(t))),includes:t=>{return v(a(e,(n=t,i(r=>d(r)&&r.includes(n)))));var n},regex:t=>{return v(a(e,(n=t,i(r=>d(r)&&!!r.match(n)))));var n}}),ue=v(i(d)),h=e=>Object.assign(u(e),{between:(t,n)=>h(a(e,((r,o)=>i(s=>p(s)&&r<=s&&o>=s))(t,n))),lt:t=>h(a(e,(n=>i(r=>p(r)&&r<n))(t))),gt:t=>h(a(e,(n=>i(r=>p(r)&&r>n))(t))),lte:t=>h(a(e,(n=>i(r=>p(r)&&r<=n))(t))),gte:t=>h(a(e,(n=>i(r=>p(r)&&r>=n))(t))),int:()=>h(a(e,i(t=>p(t)&&Number.isInteger(t)))),finite:()=>h(a(e,i(t=>p(t)&&Number.isFinite(t)))),positive:()=>h(a(e,i(t=>p(t)&&t>0))),negative:()=>h(a(e,i(t=>p(t)&&t<0)))}),pe=h(i(p)),x=e=>Object.assign(u(e),{between:(t,n)=>x(a(e,((r,o)=>i(s=>y(s)&&r<=s&&o>=s))(t,n))),lt:t=>x(a(e,(n=>i(r=>y(r)&&r<n))(t))),gt:t=>x(a(e,(n=>i(r=>y(r)&&r>n))(t))),lte:t=>x(a(e,(n=>i(r=>y(r)&&r<=n))(t))),gte:t=>x(a(e,(n=>i(r=>y(r)&&r>=n))(t))),positive:()=>x(a(e,i(t=>y(t)&&t>0))),negative:()=>x(a(e,i(t=>y(t)&&t<0)))}),he=x(i(y)),fe=u(i(function(e){return typeof e=="boolean"})),me=u(i(function(e){return typeof e=="symbol"})),ge=u(i(function(e){return e==null})),de=u(i(function(e){return e!=null}));var P=class extends Error{constructor(t){let n;try{n=JSON.stringify(t)}catch{n=t}super(`Pattern matching error: no pattern matches value ${n}`),this.input=void 0,this.input=t}},R={matched:!1,value:void 0};function _(e){return new j(e,R)}var j=class e{constructor(t,n){this.input=void 0,this.state=void 0,this.input=t,this.state=n}with(...t){if(this.state.matched)return this;let n=t[t.length-1],r=[t[0]],o;t.length===3&&typeof t[1]=="function"?o=t[1]:t.length>2&&r.push(...t.slice(1,t.length-1));let s=!1,c={},l=(g,C)=>{s=!0,c[g]=C},w=!r.some(g=>f(g,this.input,l))||o&&!o(this.input)?R:{matched:!0,value:n(s?b in c?c[b]:c:this.input,this.input)};return new e(this.input,w)}when(t,n){if(this.state.matched)return this;let r=!!t(this.input);return new e(this.input,r?{matched:!0,value:n(this.input,this.input)}:R)}otherwise(t){return this.state.matched?this.state.value:t(this.input)}exhaustive(t=q){return this.state.matched?this.state.value:t(this.input)}run(){return this.exhaustive()}returnType(){return this}};function q(e){throw new P(e)}function V(e){return t=>{let r=(Array.isArray(t)?t:[t]).map(o=>o.trim().split(` `).map(s=>s.trim()).join(` `));return _(e).with("sh",()=>["sh","-c",`set -eu; ${r}`]).with("bash",()=>["bash","-c",`set -euo pipefail; ${r}`]).with("zsh",()=>["zsh","-c",`set -euo pipefail; ${r}`]).exhaustive()}}import I from"node:path";import{join as Y}from"node:path";import{existsSync as ee}from"node:fs";import{dirname as Q}from"node:path";import{isAbsolute as G,join as Ce,resolve as H}from"node:path";function K(e,t){return G(e)?e:H(t||".",e)}function O(e,t){let{stop:n,cwd:r}=t||{},o=K(e,r),s=!n,c,l=[];for(n&&(n=K(n,r));(s||o!==n)&&(l.push(o),o=Q(c=o),o!==c););return l}function A(e,t){let n,r,o=t&&t.cwd||"";for(n of O(o,t))if(r=Y(n,e),ee(r))return r}function te(e){e=e??process.cwd();let t=A("pnpm-lock.yaml",{cwd:e});if(!t)throw new Error("could not determine repo root path: unable to find pnpm-lock.yaml");let n=I.dirname(t),r=A("dagger.json",{cwd:e,stop:n});if(!r)throw new Error("could not determine dagger.json path: unable to find dagger.json");return I.relative(n,I.dirname(r))}function ne(e){if(!e)return"";if(e.includes("_")){let n="",r=e.split("_");for(let o=0;o<r.length;o++){let s=r[o];s&&(n.length===0?n+=s.toLowerCase():n+=s[0].toUpperCase()+s.slice(1).toLowerCase())}return n}return/^[A-Z0-9]+$/.test(e)?e.toLowerCase():e[0]===e[0].toLowerCase()?e:e[0].toLowerCase()+e.slice(1)}function re(e){let t={};for(let n in e)if(Object.prototype.hasOwnProperty.call(e,n)){let r=ne(n);t[r]=e[n]}return t}function oe(e){return e?e.replace(/([A-Z])([A-Z][a-z])/g,"$1_$2").replace(/([a-z\d])([A-Z])/g,"$1_$2").replace(/([a-z])(\d)/g,"$1_$2").toUpperCase():""}function se(e){let t={};for(let n in e)if(Object.prototype.hasOwnProperty.call(e,n)){let r=oe(n);t[r]=e[n]}return t}export{D as ParamsToEnv,M as constants,re as convertToCamel,se as convertToSnake,E as envStorage,te as getModulePath,V as shell}; //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2NvbnN0YW50cy50cyIsICIuLi9zcmMvZW52LnRzIiwgIi4uLy4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS90cy1wYXR0ZXJuQDUuNy4wL25vZGVfbW9kdWxlcy90cy1wYXR0ZXJuL3NyYy9pbnRlcm5hbHMvc3ltYm9scy50cyIsICIuLi8uLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vdHMtcGF0dGVybkA1LjcuMC9ub2RlX21vZHVsZXMvdHMtcGF0dGVybi9zcmMvaW50ZXJuYWxzL2hlbHBlcnMudHMiLCAiLi4vLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3RzLXBhdHRlcm5ANS43LjAvbm9kZV9tb2R1bGVzL3RzLXBhdHRlcm4vc3JjL2lzLW1hdGNoaW5nLnRzIiwgIi4uLy4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS90cy1wYXR0ZXJuQDUuNy4wL25vZGVfbW9kdWxlcy90cy1wYXR0ZXJuL3NyYy9wYXR0ZXJucy50cyIsICIuLi8uLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vdHMtcGF0dGVybkA1LjcuMC9ub2RlX21vZHVsZXMvdHMtcGF0dGVybi9zcmMvZXJyb3JzLnRzIiwgIi4uLy4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS90cy1wYXR0ZXJuQDUuNy4wL25vZGVfbW9kdWxlcy90cy1wYXR0ZXJuL3NyYy9tYXRjaC50cyIsICIuLi9zcmMvc2hlbGwudHMiLCAiLi4vc3JjL3BhdGgudHMiLCAiLi4vLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2VtcGF0aGljQDEuMS4wL25vZGVfbW9kdWxlcy9lbXBhdGhpYy9maW5kLm1qcyIsICIuLi8uLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vZW1wYXRoaWNAMS4xLjAvbm9kZV9tb2R1bGVzL2VtcGF0aGljL3dhbGsubWpzIiwgIi4uLy4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9lbXBhdGhpY0AxLjEuMC9ub2RlX21vZHVsZXMvZW1wYXRoaWMvcmVzb2x2ZS5tanMiLCAiLi4vc3JjL2NvbnZlcnQvc25ha2UtdG8tY2FtZWwudHMiLCAiLi4vc3JjL2NvbnZlcnQvY2FtZWwtdG8tc25ha2UudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKiB2YXJpb3VzIGNvbnN0YW50cyBmb3IgZGFnZ2VyIG1vZHVsZXMgaW4gbXkgcmVwb3MgKi9cbmV4cG9ydCBjb25zdCBjb25zdGFudHMgPSB7XG5cdC8qKiBjb25zdGFudHMgZm9yIHdvcmtlcnMtbW9ub3JlcG8gKi9cblx0d29ya2Vyc01vbm9yZXBvOiB7XG5cdFx0LyoqIGRlZmF1bHQgc291cmNlIGlnbm9yZSBsaXN0ICovXG5cdFx0aWdub3JlOiBbXG5cdFx0XHQnKiovbm9kZV9tb2R1bGVzLycsXG5cdFx0XHQnKiovLmVudicsXG5cdFx0XHQnKiovLnNlY3JldCcsXG5cdFx0XHQnKiovLndyYW5nbGVyJyxcblx0XHRcdCcqKi8uZGV2LnZhcnMnLFxuXHRcdFx0JyoqLy50dXJiby8nLFxuXHRcdFx0JyoqL2Rpc3QvJyxcblx0XHRcdCcqKi9kaXN0Mi8nLFxuXHRcdFx0JyoqLy5EU19TdG9yZScsXG5cdFx0XHQnKiovLmFzdHJvLycsXG5cdFx0XHQnKiovLm5leHQvJyxcblx0XHRcdCcqLmVudicsXG5cdFx0XSBzYXRpc2ZpZXMgc3RyaW5nW10sXG5cdH0sXG59IGFzIGNvbnN0XG4iLCAiaW1wb3J0IHsgQXN5bmNMb2NhbFN0b3JhZ2UgfSBmcm9tICdub2RlOmFzeW5jX2hvb2tzJ1xuXG5pbXBvcnQgdHlwZSB7IFNlY3JldCB9IGZyb20gJ0BkYWdnZXIuaW8vZGFnZ2VyJ1xuXG4vKipcbiAqIFN0cnVjdHVyZSBzdG9yZWQgaW4gQXN5bmNMb2NhbFN0b3JhZ2UsIGNvbnRhaW5pbmcgYm90aCB0aGUgZnVsbHkgbWVyZ2VkXG4gKiBlbnZpcm9ubWVudCB2YXJpYWJsZXMgYW5kIHRoZSBzZXQgb2YgdmFyaWFibGVzIGV4cGxpY2l0bHkgcGFzc2VkIHRvIHRoZVxuICogY3VycmVudCBkZWNvcmF0ZWQgZnVuY3Rpb24gY2FsbC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBFbnZDb250ZXh0IHtcblx0Y3VycmVudFBhcmFtczogU2V0PHN0cmluZz5cblx0bWVyZ2VkRW52OiBSZWNvcmQ8c3RyaW5nLCBTZWNyZXQgfCBzdHJpbmcgfCB1bmRlZmluZWQ+XG59XG5cbi8qKlxuICogU3RvcmUgZm9yIGVudmlyb25tZW50IHZhcmlhYmxlcyBhY2Nlc3NpYmxlIHZpYSBBc3luY0xvY2FsU3RvcmFnZVxuICovXG5leHBvcnQgY29uc3QgZW52U3RvcmFnZSA9IG5ldyBBc3luY0xvY2FsU3RvcmFnZTxFbnZDb250ZXh0PigpXG5cbi8qKlxuICogSGVscGVyIHRvIGV4dHJhY3QgcGFyYW1ldGVyIG5hbWVzIGZyb20gYSBmdW5jdGlvbidzIHNvdXJjZSBjb2RlLlxuICogTm90ZTogVGhpcyBhcHByb2FjaCB1c2luZyBGdW5jdGlvbi50b1N0cmluZygpIGNhbiBiZSBmcmFnaWxlIGFuZCBtaWdodFxuICogYnJlYWsgd2l0aCBjb2RlIG1pbmlmaWNhdGlvbiBvciBjb21wbGV4IGZ1bmN0aW9uIGRlZmluaXRpb25zLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZXh0cmFjdFBhcmFtTmFtZXMoZnVuYzogRnVuY3Rpb24pOiBzdHJpbmdbXSB7XG5cdGNvbnN0IGZ1bmNTdHIgPSBmdW5jLnRvU3RyaW5nKCkucmVwbGFjZSgvKFxcclxcbnxcXG58XFxyKS9nbSwgJycpXG5cdC8vIFJlZ2V4IHRvIGZpbmQgcGFyYW1ldGVyIGxpc3Qgd2l0aGluIHBhcmVudGhlc2VzLCBoYW5kbGVzIHZhcmlvdXMgZnVuY3Rpb24gZGVmaW5pdGlvbiBzdHlsZXNcblx0Y29uc3QgcGFyYW1zTWF0Y2ggPVxuXHRcdGZ1bmNTdHIubWF0Y2goLyg/OmFzeW5jXFxzKik/KD86ZnVuY3Rpb25cXHMqW1xcd1xcc10qKT9cXCgoW14pXSopXFwpLykgPz9cblx0XHRmdW5jU3RyLm1hdGNoKC9eXFxzKig/OmFzeW5jXFxzKik/XFwoKFteKV0qKVxcKS8pIC8vIEFycm93IGZ1bmN0aW9uIHN1cHBvcnRcblxuXHRpZiAoIXBhcmFtc01hdGNoIHx8IHR5cGVvZiBwYXJhbXNNYXRjaFsxXSA9PT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRjb25zb2xlLndhcm4oJ0NvdWxkIG5vdCBleHRyYWN0IHBhcmFtZXRlciBuYW1lcyBmcm9tIGZ1bmN0aW9uIHN0cmluZzonLCBmdW5jU3RyKVxuXHRcdHJldHVybiBbXVxuXHR9XG5cdGNvbnN0IHBhcmFtc1N0ciA9IHBhcmFtc01hdGNoWzFdXG5cblx0Ly8gUmVtb3ZlIGNvbW1lbnRzLCBkZWZhdWx0IHZhbHVlcywgYW5kIHR5cGUgYW5ub3RhdGlvbnMgdG8gaXNvbGF0ZSBuYW1lc1xuXHRjb25zdCBjbGVhbmVkUGFyYW1zU3RyID0gcGFyYW1zU3RyXG5cdFx0LnJlcGxhY2UoL1xcL1xcKi4qP1xcKlxcLy9nLCAnJykgLy8gUmVtb3ZlIGJsb2NrIGNvbW1lbnRzXG5cdFx0LnJlcGxhY2UoL1xcL1xcLy4qPyQvZ20sICcnKSAvLyBSZW1vdmUgbGluZSBjb21tZW50c1xuXG5cdGlmICghY2xlYW5lZFBhcmFtc1N0ci50cmltKCkpIHtcblx0XHRyZXR1cm4gW10gLy8gTm8gcGFyYW1ldGVyc1xuXHR9XG5cblx0cmV0dXJuIGNsZWFuZWRQYXJhbXNTdHJcblx0XHQuc3BsaXQoJywnKVxuXHRcdC5tYXAoKHBhcmFtKSA9PiB7XG5cdFx0XHQvLyBSZW1vdmUgdHlwZSBhbm5vdGF0aW9ucyAoZS5nLiwgXCI6IFNlY3JldFwiKSBhbmQgZGVmYXVsdCBpbml0aWFsaXplcnMgKGUuZy4sIFwiPSAnZGVmYXVsdCdcIilcblx0XHRcdGNvbnN0IG5hbWVQYXJ0ID0gcGFyYW0uc3BsaXQoL1s6PV0vKVswXVxuXHRcdFx0cmV0dXJuIG5hbWVQYXJ0Py50cmltKCkgPz8gJydcblx0XHR9KVxuXHRcdC5maWx0ZXIoKG5hbWUpID0+IG5hbWUubGVuZ3RoID4gMCkgLy8gRmlsdGVyIG91dCBlbXB0eSBzdHJpbmdzIGZyb20gdHJhaWxpbmcgY29tbWFzIGV0Yy5cbn1cblxuLyoqXG4gKiBEZWNvcmF0b3IgZmFjdG9yeSB0aGF0IHdyYXBzIGEgbWV0aG9kIHRvIGNhcHR1cmUgaXRzIGFyZ3VtZW50cyBiYXNlZCBvblxuICogZXh0cmFjdGVkIHBhcmFtZXRlciBuYW1lcyBhbmQgc3RvcmUgdGhlbSBpbiBBc3luY0xvY2FsU3RvcmFnZS5cbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gUGFyYW1zVG9FbnYoKTogTWV0aG9kRGVjb3JhdG9yIHtcblx0cmV0dXJuIGZ1bmN0aW9uIChfdGFyZ2V0OiBhbnksIHByb3BlcnR5S2V5OiBzdHJpbmcgfCBzeW1ib2wsIGRlc2NyaXB0b3I6IFByb3BlcnR5RGVzY3JpcHRvcikge1xuXHRcdGlmICh0eXBlb2YgZGVzY3JpcHRvciA9PT0gJ3VuZGVmaW5lZCcgfHwgdHlwZW9mIGRlc2NyaXB0b3IudmFsdWUgIT09ICdmdW5jdGlvbicpIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcihcblx0XHRcdFx0YEBQYXJhbXNUb0VudiBkZWNvcmF0b3IgY2FuIG9ubHkgYmUgYXBwbGllZCB0byBtZXRob2RzLCBub3Q6ICR7U3RyaW5nKHByb3BlcnR5S2V5KX1gXG5cdFx0XHQpXG5cdFx0fVxuXHRcdGNvbnN0IG9yaWdpbmFsTWV0aG9kID0gZGVzY3JpcHRvci52YWx1ZVxuXG5cdFx0bGV0IHBhcmFtTmFtZXM6IHN0cmluZ1tdIHwgbnVsbCA9IG51bGwgLy8gQ2FjaGUgcGFyYW1ldGVyIG5hbWVzIGxhemlseVxuXG5cdFx0ZGVzY3JpcHRvci52YWx1ZSA9IGZ1bmN0aW9uICguLi5hcmdzOiBhbnlbXSk6IGFueSB7XG5cdFx0XHRjb25zdCBwYXJlbnRDb250ZXh0ID0gZW52U3RvcmFnZS5nZXRTdG9yZSgpXG5cblx0XHRcdGlmIChwYXJhbU5hbWVzID09PSBudWxsKSB7XG5cdFx0XHRcdHBhcmFtTmFtZXMgPSBleHRyYWN0UGFyYW1OYW1lcyhvcmlnaW5hbE1ldGhvZClcblx0XHRcdFx0Ly8gQmFzaWMgdmFsaWRhdGlvbjogQ2hlY2sgaWYgdGhlIG51bWJlciBvZiBleHRyYWN0ZWQgbmFtZXMgbWF0Y2hlcyB0aGUgbnVtYmVyIG9mIGFyZ3VtZW50cyByZWNlaXZlZC5cblx0XHRcdFx0Ly8gVGhpcyBtaWdodCBiZSBpbmFjY3VyYXRlIGlmIG9wdGlvbmFsIHBhcmFtZXRlcnMgYXJlbid0IHBhc3NlZC5cblx0XHRcdFx0aWYgKHBhcmFtTmFtZXMubGVuZ3RoICE9PSBhcmdzLmxlbmd0aCAmJiB0eXBlb2YgcHJvcGVydHlLZXkgPT09ICdzdHJpbmcnKSB7XG5cdFx0XHRcdFx0Ly8gTG9nIGEgd2FybmluZyBidXQgYXR0ZW1wdCB0byBwcm9jZWVkLiBUaGUgY29udGV4dCBtaWdodCBiZSBpbmNvbXBsZXRlLlxuXHRcdFx0XHRcdC8vIE5vdGU6IERpc2FibGluZyB0aGlzIGZvciBub3cgYmVjYXVzZSBvcHRpb25hbCBwYXJhbWV0ZXJzIHRyaWdnZXIgdGhpcyB3YXJuaW5nLlxuXHRcdFx0XHRcdC8vIGNvbnNvbGUud2Fybihcblx0XHRcdFx0XHQvLyBcdGBQYXJhbWV0ZXIgbmFtZSBleHRyYWN0aW9uL2FyZ3VtZW50IGNvdW50IG1pc21hdGNoIGZvciAke3Byb3BlcnR5S2V5fTogYCArXG5cdFx0XHRcdFx0Ly8gXHRcdGBFeHRyYWN0ZWQgJHtwYXJhbU5hbWVzLmxlbmd0aH0gbmFtZXMgKCR7cGFyYW1OYW1lcy5qb2luKCcsICcpfSksIHJlY2VpdmVkICR7YXJncy5sZW5ndGh9IGFyZ3MuIGAgK1xuXHRcdFx0XHRcdC8vIFx0XHRgQ29udGV4dCBpbiBBc3luY0xvY2FsU3RvcmFnZSBtYXkgYmUgaW5jb21wbGV0ZSBvciBpbmNvcnJlY3QuYFxuXHRcdFx0XHRcdC8vIClcblx0XHRcdFx0XHQvLyBPcHRpb25hbGx5LCB5b3UgY291bGQgdHJ5IHRvIHBhZCBwYXJhbU5hbWVzIG9yIHRydW5jYXRlIGFyZ3MsIGJ1dCBpdCdzIHJpc2t5LlxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdGNvbnN0IG5ld0VudjogUmVjb3JkPHN0cmluZywgU2VjcmV0IHwgc3RyaW5nIHwgdW5kZWZpbmVkPiA9IHt9XG5cdFx0XHRjb25zdCBjdXJyZW50UGFyYW1zID0gbmV3IFNldDxzdHJpbmc+KCkgLy8gVHJhY2sgcGFyYW1zIGZvciBjdXJyZW50IG1ldGhvZFxuXHRcdFx0cGFyYW1OYW1lcz8uZm9yRWFjaCgobmFtZSwgaW5kZXgpID0+IHtcblx0XHRcdFx0Ly8gQ2hlY2sgaWYgdGhlIHBhcmFtIG5hbWUgbWF0Y2hlcyB0aGUgRU5WX1ZBUiBwYXR0ZXJuXG5cdFx0XHRcdGlmICgvXltBLVowLTlfXSskLy50ZXN0KG5hbWUpKSB7XG5cdFx0XHRcdFx0Ly8gQWRkIGFsbCBtYXRjaGluZyBkZWZpbmVkIHBhcmFtZXRlciBuYW1lcyB0byBjdXJyZW50UGFyYW1zXG5cdFx0XHRcdFx0Y3VycmVudFBhcmFtcy5hZGQobmFtZSlcblx0XHRcdFx0XHQvLyBPbmx5IGFkZCB0byBuZXdFbnYgaWYgYXJndW1lbnQgd2FzIGFjdHVhbGx5IHBhc3NlZFxuXHRcdFx0XHRcdGlmIChpbmRleCA8IGFyZ3MubGVuZ3RoKSB7XG5cdFx0XHRcdFx0XHRuZXdFbnZbbmFtZV0gPSBhcmdzW2luZGV4XVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHQvLyBJZiBwYXJhbU5hbWVzLmxlbmd0aCA+IGFyZ3MubGVuZ3RoLCBzb21lIG5hbWVzIHdvbid0IGdldCBhIHZhbHVlLCB3aGljaCBpcyBleHBlY3RlZCBmb3Igb3B0aW9uYWwgcGFyYW1zLlxuXHRcdFx0fSlcblxuXHRcdFx0Ly8gbWVyZ2UgcGFyZW50IGNvbnRleHQgd2l0aCBuZXcgY29udGV4dCAobmV3IHRha2VzIHByZWNlZGVuY2UpXG5cdFx0XHRjb25zdCBwYXJlbnRNZXJnZWRFbnYgPSBwYXJlbnRDb250ZXh0Py5tZXJnZWRFbnYgPz8ge31cblx0XHRcdGNvbnN0IG1lcmdlZEVudiA9IHsgLi4ucGFyZW50TWVyZ2VkRW52LCAuLi5uZXdFbnYgfVxuXG5cdFx0XHQvLyBQcmVwYXJlIGNvbnRleHQgb2JqZWN0IGZvciBzdG9yYWdlXG5cdFx0XHRjb25zdCBjb250ZXh0VG9TdG9yZTogRW52Q29udGV4dCA9IHtcblx0XHRcdFx0Y3VycmVudFBhcmFtcyxcblx0XHRcdFx0bWVyZ2VkRW52LFxuXHRcdFx0fVxuXG5cdFx0XHQvLyBydW4gdGhlIG9yaWdpbmFsIG1ldGhvZCB3aXRoaW4gdGhlIEFzeW5jTG9jYWxTdG9yYWdlIGNvbnRleHQgdXNpbmcgdGhlIG1lcmdlZCBlbnZcblx0XHRcdHJldHVybiBlbnZTdG9yYWdlLnJ1bihjb250ZXh0VG9TdG9yZSwgKCkgPT4ge1xuXHRcdFx0XHQvLyBUaGUgb3JpZ2luYWwgbWV0aG9kIGlzIGNhbGxlZCB3aXRoIGl0cyBvcmlnaW5hbCBhcmd1bWVudHNcblx0XHRcdFx0cmV0dXJuIG9yaWdpbmFsTWV0aG9kLmFwcGx5KHRoaXMsIGFyZ3MpXG5cdFx0XHR9KVxuXHRcdH1cblx0fVxufVxuIiwgIi8qKlxuICogU3ltYm9scyB1c2VkIGludGVybmFsbHkgd2l0aGluIHRzLXBhdHRlcm4gdG8gY29uc3RydWN0IGFuZCBkaXNjcmltaW5hdGVcbiAqIEd1YXJkLCBOb3QsIGFuZCBTZWxlY3QsIGFuZCBBbm9ueW1vdXNTZWxlY3QgcGF0dGVybnNcbiAqXG4gKiBTeW1ib2xzIGhhdmUgdGhlIGFkdmFudGFnZSBvZiBub3QgYXBwZWFyaW5nIGluIGF1dG8tY29tcGxldGUgc3VnZ2VzdGlvbnMgaW5cbiAqIHVzZXIgZGVmaW5lZCBwYXR0ZXJucywgYW5kIGVsaW1pbmF0ZSB0aGUgcmlzayBvZiBwcm9wZXJ0eVxuICogb3ZlcmxhcCBiZXR3ZWVuIHRzLXBhdHRlcm4gaW50ZXJuYWxzIGFuZCB1c2VyIGRlZmluZWQgcGF0dGVybnMuXG4gKlxuICogVGhlc2Ugc3ltYm9scyBoYXZlIHRvIGJlIHZpc2libGUgdG8gdHNjIGZvciB0eXBlIGluZmVyZW5jZSB0byB3b3JrLCBidXRcbiAqIHVzZXJzIHNob3VsZCBub3QgaW1wb3J0IHRoZW1cbiAqIEBtb2R1bGVcbiAqIEBwcml2YXRlXG4gKiBAaW50ZXJuYWxcbiAqL1xuXG5leHBvcnQgY29uc3QgbWF0Y2hlciA9IFN5bWJvbC5mb3IoJ0B0cy1wYXR0ZXJuL21hdGNoZXInKTtcbmV4cG9ydCB0eXBlIG1hdGNoZXIgPSB0eXBlb2YgbWF0Y2hlcjtcblxuZXhwb3J0IGNvbnN0IHVuc2V0ID0gU3ltYm9sLmZvcignQHRzLXBhdHRlcm4vdW5zZXQnKTtcbmV4cG9ydCB0eXBlIHVuc2V0ID0gdHlwZW9mIHVuc2V0O1xuXG5leHBvcnQgY29uc3QgaXNWYXJpYWRpYyA9IFN5bWJvbC5mb3IoJ0B0cy1wYXR0ZXJuL2lzVmFyaWFkaWMnKTtcbmV4cG9ydCB0eXBlIGlzVmFyaWFkaWMgPSB0eXBlb2YgaXNWYXJpYWRpYztcblxuLy8gY2FuJ3QgYmUgYSBzeW1ib2wgYmVjYXVzZSB0aGlzIGtleSBoYXMgdG8gYmUgZW51bWVyYWJsZS5cbmV4cG9ydCBjb25zdCBhbm9ueW1vdXNTZWxlY3RLZXkgPSAnQHRzLXBhdHRlcm4vYW5vbnltb3VzLXNlbGVjdC1rZXknO1xuZXhwb3J0IHR5cGUgYW5vbnltb3VzU2VsZWN0S2V5ID0gdHlwZW9mIGFub255bW91c1NlbGVjdEtleTtcblxuZXhwb3J0IGNvbnN0IG92ZXJyaWRlID0gU3ltYm9sLmZvcignQHRzLXBhdHRlcm4vb3ZlcnJpZGUnKTtcbmV4cG9ydCB0eXBlIG92ZXJyaWRlID0gdHlwZW9mIG92ZXJyaWRlO1xuIiwgIi8qKlxuICogQG1vZHVsZVxuICogQHByaXZhdGVcbiAqIEBpbnRlcm5hbFxuICovXG5cbmltcG9ydCAqIGFzIHN5bWJvbHMgZnJvbSAnLi9zeW1ib2xzJztcbmltcG9ydCB7IFNlbGVjdGlvblR5cGUgfSBmcm9tICcuLi90eXBlcy9GaW5kU2VsZWN0ZWQnO1xuaW1wb3J0IHsgUGF0dGVybiwgTWF0Y2hlciwgTWF0Y2hlclR5cGUsIEFueU1hdGNoZXIgfSBmcm9tICcuLi90eXBlcy9QYXR0ZXJuJztcblxuLy8gQGludGVybmFsXG5leHBvcnQgY29uc3QgaXNPYmplY3QgPSAodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBPYmplY3QgPT5cbiAgQm9vbGVhbih2YWx1ZSAmJiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnKTtcblxuLy8gICBAaW50ZXJuYWxcbmV4cG9ydCBjb25zdCBpc01hdGNoZXIgPSAoXG4gIHg6IHVua25vd25cbik6IHggaXMgTWF0Y2hlcjx1bmtub3duLCB1bmtub3duLCBNYXRjaGVyVHlwZSwgU2VsZWN0aW9uVHlwZT4gPT4ge1xuICBjb25zdCBwYXR0ZXJuID0geCBhcyBNYXRjaGVyPHVua25vd24sIHVua25vd24sIE1hdGNoZXJUeXBlLCBTZWxlY3Rpb25UeXBlPjtcbiAgcmV0dXJuIHBhdHRlcm4gJiYgISFwYXR0ZXJuW3N5bWJvbHMubWF0Y2hlcl07XG59O1xuXG4vLyBAaW50ZXJuYWxcbmNvbnN0IGlzT3B0aW9uYWxQYXR0ZXJuID0gKFxuICB4OiB1bmtub3duXG4pOiB4IGlzIE1hdGNoZXI8dW5rbm93biwgdW5rbm93biwgJ29wdGlvbmFsJywgU2VsZWN0aW9uVHlwZT4gPT4ge1xuICByZXR1cm4gaXNNYXRjaGVyKHgpICYmIHhbc3ltYm9scy5tYXRjaGVyXSgpLm1hdGNoZXJUeXBlID09PSAnb3B0aW9uYWwnO1xufTtcblxuLy8gdGVsbHMgdXMgaWYgdGhlIHZhbHVlIG1hdGNoZXMgYSBnaXZlbiBwYXR0ZXJuLlxuLy8gQGludGVybmFsXG5leHBvcnQgY29uc3QgbWF0Y2hQYXR0ZXJuID0gKFxuICBwYXR0ZXJuOiBhbnksXG4gIHZhbHVlOiBhbnksXG4gIHNlbGVjdDogKGtleTogc3RyaW5nLCB2YWx1ZTogdW5rbm93bikgPT4gdm9pZFxuKTogYm9vbGVhbiA9PiB7XG4gIGlmIChpc01hdGNoZXIocGF0dGVybikpIHtcbiAgICBjb25zdCBtYXRjaGVyID0gcGF0dGVybltzeW1ib2xzLm1hdGNoZXJdKCk7XG4gICAgY29uc3QgeyBtYXRjaGVkLCBzZWxlY3Rpb25zIH0gPSBtYXRjaGVyLm1hdGNoKHZhbHVlKTtcbiAgICBpZiAobWF0Y2hlZCAmJiBzZWxlY3Rpb25zKSB7XG4gICAgICBPYmplY3Qua2V5cyhzZWxlY3Rpb25zKS5mb3JFYWNoKChrZXkpID0+IHNlbGVjdChrZXksIHNlbGVjdGlvbnNba2V5XSkpO1xuICAgIH1cbiAgICByZXR1cm4gbWF0Y2hlZDtcbiAgfVxuXG4gIGlmIChpc09iamVjdChwYXR0ZXJuKSkge1xuICAgIGlmICghaXNPYmplY3QodmFsdWUpKSByZXR1cm4gZmFsc2U7XG5cbiAgICAvLyBUdXBsZSBwYXR0ZXJuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkocGF0dGVybikpIHtcbiAgICAgIGlmICghQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHJldHVybiBmYWxzZTtcbiAgICAgIGxldCBzdGFydFBhdHRlcm5zID0gW107XG4gICAgICBsZXQgZW5kUGF0dGVybnMgPSBbXTtcbiAgICAgIGxldCB2YXJpYWRpY1BhdHRlcm5zOiBBbnlNYXRjaGVyW10gPSBbXTtcblxuICAgICAgZm9yIChjb25zdCBpIG9mIHBhdHRlcm4ua2V5cygpKSB7XG4gICAgICAgIGNvbnN0IHN1YnBhdHRlcm4gPSBwYXR0ZXJuW2ldO1xuICAgICAgICBpZiAoaXNNYXRjaGVyKHN1YnBhdHRlcm4pICYmIHN1YnBhdHRlcm5bc3ltYm9scy5pc1ZhcmlhZGljXSkge1xuICAgICAgICAgIHZhcmlhZGljUGF0dGVybnMucHVzaChzdWJwYXR0ZXJuKTtcbiAgICAgICAgfSBlbHNlIGlmICh2YXJpYWRpY1BhdHRlcm5zLmxlbmd0aCkge1xuICAgICAgICAgIGVuZFBhdHRlcm5zLnB1c2goc3VicGF0dGVybik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc3RhcnRQYXR0ZXJucy5wdXNoKHN1YnBhdHRlcm4pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICh2YXJpYWRpY1BhdHRlcm5zLmxlbmd0aCkge1xuICAgICAgICBpZiAodmFyaWFkaWNQYXR0ZXJucy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgYFBhdHRlcm4gZXJyb3I6IFVzaW5nIFxcYC4uLlAuYXJyYXkoLi4uKVxcYCBzZXZlcmFsIHRpbWVzIGluIGEgc2luZ2xlIHBhdHRlcm4gaXMgbm90IGFsbG93ZWQuYFxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodmFsdWUubGVuZ3RoIDwgc3RhcnRQYXR0ZXJucy5sZW5ndGggKyBlbmRQYXR0ZXJucy5sZW5ndGgpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzdGFydFZhbHVlcyA9IHZhbHVlLnNsaWNlKDAsIHN0YXJ0UGF0dGVybnMubGVuZ3RoKTtcbiAgICAgICAgY29uc3QgZW5kVmFsdWVzID1cbiAgICAgICAgICBlbmRQYXR0ZXJucy5sZW5ndGggPT09IDAgPyBbXSA6IHZhbHVlLnNsaWNlKC1lbmRQYXR0ZXJucy5sZW5ndGgpO1xuICAgICAgICBjb25zdCBtaWRkbGVWYWx1ZXMgPSB2YWx1ZS5zbGljZShcbiAgICAgICAgICBzdGFydFBhdHRlcm5zLmxlbmd0aCxcbiAgICAgICAgICBlbmRQYXR0ZXJucy5sZW5ndGggPT09IDAgPyBJbmZpbml0eSA6IC1lbmRQYXR0ZXJucy5sZW5ndGhcbiAgICAgICAgKTtcblxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgIHN0YXJ0UGF0dGVybnMuZXZlcnkoKHN1YlBhdHRlcm4sIGkpID0+XG4gICAgICAgICAgICBtYXRjaFBhdHRlcm4oc3ViUGF0dGVybiwgc3RhcnRWYWx1ZXNbaV0sIHNlbGVjdClcbiAgICAgICAgICApICYmXG4gICAgICAgICAgZW5kUGF0dGVybnMuZXZlcnkoKHN1YlBhdHRlcm4sIGkpID0+XG4gICAgICAgICAgICBtYXRjaFBhdHRlcm4oc3ViUGF0dGVybiwgZW5kVmFsdWVzW2ldLCBzZWxlY3QpXG4gICAgICAgICAgKSAmJlxuICAgICAgICAgICh2YXJpYWRpY1BhdHRlcm5zLmxlbmd0aCA9PT0gMFxuICAgICAgICAgICAgPyB0cnVlXG4gICAgICAgICAgICA6IG1hdGNoUGF0dGVybih2YXJpYWRpY1BhdHRlcm5zWzBdLCBtaWRkbGVWYWx1ZXMsIHNlbGVjdCkpXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBwYXR0ZXJuLmxlbmd0aCA9PT0gdmFsdWUubGVuZ3RoXG4gICAgICAgID8gcGF0dGVybi5ldmVyeSgoc3ViUGF0dGVybiwgaSkgPT5cbiAgICAgICAgICAgIG1hdGNoUGF0dGVybihzdWJQYXR0ZXJuLCB2YWx1ZVtpXSwgc2VsZWN0KVxuICAgICAgICAgIClcbiAgICAgICAgOiBmYWxzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gUmVmbGVjdC5vd25LZXlzKHBhdHRlcm4pLmV2ZXJ5KChrKTogYm9vbGVhbiA9PiB7XG4gICAgICBjb25zdCBzdWJQYXR0ZXJuID0gcGF0dGVybltrXTtcblxuICAgICAgcmV0dXJuIChcbiAgICAgICAgKGsgaW4gdmFsdWUgfHwgaXNPcHRpb25hbFBhdHRlcm4oc3ViUGF0dGVybikpICYmXG4gICAgICAgIG1hdGNoUGF0dGVybihzdWJQYXR0ZXJuLCB2YWx1ZVtrXSwgc2VsZWN0KVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiBPYmplY3QuaXModmFsdWUsIHBhdHRlcm4pO1xufTtcblxuLy8gQGludGVybmFsXG5leHBvcnQgY29uc3QgZ2V0U2VsZWN0aW9uS2V5cyA9IChwYXR0ZXJuOiBhbnkpOiBzdHJpbmdbXSA9PiB7XG4gIGlmIChpc09iamVjdChwYXR0ZXJuKSkge1xuICAgIGlmIChpc01hdGNoZXIocGF0dGVybikpIHtcbiAgICAgIHJldHVybiBwYXR0ZXJuW3N5bWJvbHMubWF0Y2hlcl0oKS5nZXRTZWxlY3Rpb25LZXlzPy4oKSA/PyBbXTtcbiAgICB9XG4gICAgaWYgKEFycmF5LmlzQXJyYXkocGF0dGVybikpIHJldHVybiBmbGF0TWFwKHBhdHRlcm4sIGdldFNlbGVjdGlvbktleXMpO1xuICAgIHJldHVybiBmbGF0TWFwKE9iamVjdC52YWx1ZXMocGF0dGVybiksIGdldFNlbGVjdGlvbktleXMpO1xuICB9XG4gIHJldHVybiBbXTtcbn07XG5cbi8vIEBpbnRlcm5hbFxuZXhwb3J0IGNvbnN0IGZsYXRNYXAgPSA8YSwgYj4oXG4gIHhzOiByZWFkb25seSBhW10sXG4gIGY6ICh2OiBhKSA9PiByZWFkb25seSBiW11cbik6IGJbXSA9PiB4cy5yZWR1Y2U8YltdPigoYWNjLCB4KSA9PiBhY2MuY29uY2F0KGYoeCkpLCBbXSk7XG4iLCAiaW1wb3J0IHsgTWF0Y2hlZFZhbHVlLCBQYXR0ZXJuLCBVbmtub3duUHJvcGVydGllcyB9IGZyb20gJy4vdHlwZXMvUGF0dGVybic7XG5pbXBvcnQgKiBhcyBQIGZyb20gJy4vcGF0dGVybnMnO1xuaW1wb3J0IHsgbWF0Y2hQYXR0ZXJuIH0gZnJvbSAnLi9pbnRlcm5hbHMvaGVscGVycyc7XG5pbXBvcnQgeyBXaXRoRGVmYXVsdCB9IGZyb20gJy4vdHlwZXMvaGVscGVycyc7XG5cbi8qKlxuICogVGhpcyBjb25zdHJhaW50IGFsbG93cyB1c2luZyBhZGRpdGlvbmFsIHByb3BlcnRpZXNcbiAqIGluIG9iamVjdCBwYXR0ZXJucy4gU2VlIFwic2hvdWxkIGFsbG93IHRhcmdldHRpbmcgdW5rbm93biBwcm9wZXJ0aWVzXCJcbiAqIHVuaXQgdGVzdCBpbiBgaXMtbWF0Y2hpbmcudGVzdC50c2AuXG4gKi9cbnR5cGUgUGF0dGVybkNvbnN0cmFpbnQ8VD4gPSBUIGV4dGVuZHMgcmVhZG9ubHkgYW55W11cbiAgPyBQLlBhdHRlcm48VD5cbiAgOiBUIGV4dGVuZHMgb2JqZWN0XG4gID8gUC5QYXR0ZXJuPFQ+ICYgVW5rbm93blByb3BlcnRpZXNcbiAgOiBQLlBhdHRlcm48VD47XG5cbi8qKlxuICogYGlzTWF0Y2hpbmdgIHRha2VzIHBhdHRlcm4gYW5kIHJldHVybnMgYSAqKnR5cGUgZ3VhcmQqKiBmdW5jdGlvbiwgY2hlY2hpbmcgaWYgYSB2YWx1ZSBtYXRjaGVzIHRoaXMgcGF0dGVybi5cbiAqXG4gKiBbUmVhZCAgZG9jdW1lbnRhdGlvbiBmb3IgYGlzTWF0Y2hpbmdgIG9uIEdpdEh1Yl0oaHR0cHM6Ly9naXRodWIuY29tL2d2ZXJnbmF1ZC90cy1wYXR0ZXJuI2lzbWF0Y2hpbmcpXG4gKlxuICogQGV4YW1wbGVcbiAqICBjb25zdCBoYXNOYW1lID0gaXNNYXRjaGluZyh7IG5hbWU6IFAuc3RyaW5nIH0pXG4gKlxuICogIGRlY2xhcmUgbGV0IGlucHV0OiB1bmtub3duXG4gKlxuICogIGlmIChoYXNOYW1lKGlucHV0KSkge1xuICogICAgLy8gYGlucHV0YCBpbmZlcnJlZCBhcyB7IG5hbWU6IHN0cmluZyB9XG4gKiAgICByZXR1cm4gaW5wdXQubmFtZVxuICogIH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzTWF0Y2hpbmc8Y29uc3QgcCBleHRlbmRzIFBhdHRlcm48dW5rbm93bj4+KFxuICBwYXR0ZXJuOiBwXG4pOiAodmFsdWU6IHVua25vd24pID0+IHZhbHVlIGlzIFAuaW5mZXI8cD47XG4vKipcbiAqIGBpc01hdGNoaW5nYCB0YWtlcyBwYXR0ZXJuIGFuZCBhIHZhbHVlIGFuZCBjaGVja3MgaWYgdGhlIHZhbHVlIG1hdGNoZXMgdGhpcyBwYXR0ZXJuLlxuICpcbiAqIFtSZWFkICBkb2N1bWVudGF0aW9uIGZvciBgaXNNYXRjaGluZ2Agb24gR2l0SHViXShodHRwczovL2dpdGh1Yi5jb20vZ3ZlcmduYXVkL3RzLXBhdHRlcm4jaXNtYXRjaGluZylcbiAqXG4gKiBAZXhhbXBsZVxuICogIGRlY2xhcmUgbGV0IGlucHV0OiB1bmtub3duXG4gKlxuICogIGlmIChpc01hdGNoaW5nKHsgbmFtZTogUC5zdHJpbmcgfSwgaW5wdXQpKSB7XG4gKiAgICAvLyBgaW5wdXRgIGluZmVycmVkIGFzIHsgbmFtZTogc3RyaW5nIH1cbiAqICAgIHJldHVybiBpbnB1dC5uYW1lXG4gKiAgfVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNNYXRjaGluZzxjb25zdCBULCBjb25zdCBQIGV4dGVuZHMgUGF0dGVybkNvbnN0cmFpbnQ8VD4+KFxuICBwYXR0ZXJuOiBQLFxuICB2YWx1ZTogVFxuKTogdmFsdWUgaXMgVCAmIFdpdGhEZWZhdWx0PFAubmFycm93PFQsIFA+LCBQLmluZmVyPFA+PjtcblxuZXhwb3J0IGZ1bmN0aW9uIGlzTWF0Y2hpbmc8Y29uc3QgcCBleHRlbmRzIFBhdHRlcm48YW55Pj4oXG4gIC4uLmFyZ3M6IFtwYXR0ZXJuOiBwLCB2YWx1ZT86IGFueV1cbik6IGJvb2xlYW4gfCAoKHZhbGU6IGFueSkgPT4gYm9vbGVhbikge1xuICBpZiAoYXJncy5sZW5ndGggPT09IDEpIHtcbiAgICBjb25zdCBbcGF0dGVybl0gPSBhcmdzO1xuICAgIHJldHVybiAodmFsdWU6IGFueSk6IHZhbHVlIGlzIE1hdGNoZWRWYWx1ZTxhbnksIFAuaW5mZXI8cD4+ID0+XG4gICAgICBtYXRjaFBhdHRlcm4ocGF0dGVybiwgdmFsdWUsICgpID0+IHt9KTtcbiAgfVxuICBpZiAoYXJncy5sZW5ndGggPT09IDIpIHtcbiAgICBjb25zdCBbcGF0dGVybiwgdmFsdWVdID0gYXJncztcbiAgICByZXR1cm4gbWF0Y2hQYXR0ZXJuKHBhdHRlcm4sIHZhbHVlLCAoKSA9PiB7fSk7XG4gIH1cblxuICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgYGlzTWF0Y2hpbmcgd2Fzbid0IGdpdmVuIHRoZSByaWdodCBudW1iZXIgb2YgYXJndW1lbnRzOiBleHBlY3RlZCAxIG9yIDIsIHJlY2VpdmVkICR7YXJncy5sZW5ndGh9LmBcbiAgKTtcbn1cbiIsICIvKipcbiAqIFRoZSBgUGAgbW9kdWxlIGNvbnRhaW5zIHBhdHRlcm5zIGZvciBwcmltaXRpdmUgdHlwZXMsIHdpbGRjYXJkcyBhbmRcbiAqIG90aGVyIHBhdHRlcm4tbWF0Y2hpbmcgdXRpbGl0aWVzLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyBtYXRjaFBhdHRlcm4sIGdldFNlbGVjdGlvbktleXMsIGZsYXRNYXAgfSBmcm9tICcuL2ludGVybmFscy9oZWxwZXJzJztcbmltcG9ydCAqIGFzIHN5bWJvbHMgZnJvbSAnLi9pbnRlcm5hbHMvc3ltYm9scyc7XG5pbXBvcnQgeyBtYXRjaGVyIH0gZnJvbSAnLi9pbnRlcm5hbHMvc3ltYm9scyc7XG5pbXBvcnQgeyBpc01hdGNoaW5nIH0gZnJvbSAnLi9pcy1tYXRjaGluZyc7XG5pbXBvcnQgeyBFeHRyYWN0UHJlY2lzZVZhbHVlIH0gZnJvbSAnLi90eXBlcy9FeHRyYWN0UHJlY2lzZVZhbHVlJztcbmltcG9ydCB7IEZuIH0gZnJvbSAnLi90eXBlcy9oZWxwZXJzJztcbmltcG9ydCB7IEludmVydFBhdHRlcm4gfSBmcm9tICcuL3R5cGVzL0ludmVydFBhdHRlcm4nO1xuaW1wb3J0IHtcbiAgUGF0dGVybixcbiAgVW5rbm93blBhdHRlcm4sXG4gIE9wdGlvbmFsUCxcbiAgQXJyYXlQLFxuICBNYXBQLFxuICBTZXRQLFxuICBBbmRQLFxuICBPclAsXG4gIE5vdFAsXG4gIEd1YXJkUCxcbiAgU2VsZWN0UCxcbiAgQW5vbnltb3VzU2VsZWN0UCxcbiAgR3VhcmRFeGNsdWRlUCxcbiAgQ3VzdG9tUCxcbiAgTWF0Y2hlcixcbiAgU3RyaW5nUGF0dGVybixcbiAgQW55UGF0dGVybixcbiAgTnVtYmVyUGF0dGVybixcbiAgQm9vbGVhblBhdHRlcm4sXG4gIEJpZ0ludFBhdHRlcm4sXG4gIE51bGxpc2hQYXR0ZXJuLFxuICBTeW1ib2xQYXR0ZXJuLFxuICBDaGFpbmFibGUsXG4gIEJpZ0ludENoYWluYWJsZSxcbiAgTnVtYmVyQ2hhaW5hYmxlLFxuICBTdHJpbmdDaGFpbmFibGUsXG4gIEFycmF5Q2hhaW5hYmxlLFxuICBWYXJpYWRpYyxcbiAgTm9uTnVsbGFibGVQYXR0ZXJuLFxufSBmcm9tICcuL3R5cGVzL1BhdHRlcm4nO1xuXG5leHBvcnQgdHlwZSB7XG4gIC8qKlxuICAgKiBgUGF0dGVybjxUPmAgaXMgdGhlIHR5cGUgb2YgYWxsIHBhdHRlcm5zXG4gICAqIHRoYXQgY2FuIG1hdGNoIGEgdmFsdWUgb2YgdHlwZSBgVGAuXG4gICAqL1xuICBQYXR0ZXJuLFxuXG4gIC8qKlxuICAgKiBgdW5zdGFibGVfRm5gIGNhbiBiZSB1c2VkIHRvIGNyZWF0ZWQgYVxuICAgKiBhIE1hdGNoYWJsZSBpbnN0YW5jZSDigJMgYSBjdXN0b20gdHlwZSB0aGF0XG4gICAqIGNhbiBiZSB1c2VkIGFzIGEgcGF0dGVybi5cbiAgICpcbiAgICogQGV4cGVyaW1lbnRhbCBUaGlzIGZlYXR1cmUgaXMgdW5zdGFibGUuXG4gICAqL1xuICBGbiBhcyB1bnN0YWJsZV9Gbixcbn07XG5cbmV4cG9ydCB7IG1hdGNoZXIgfTtcblxuLyoqXG4gKiBBIGBNYXRjaGFibGVgIGlzIGFuIG9iamVjdCBpbXBsZW1lbnRpbmdcbiAqIHRoZSBNYXRjaGVyIFByb3RvY29sLiBJdCBtdXN0IGhhdmUgYSBgW1AubWF0Y2hlcl06IFAuTWF0Y2hlcjxOYXJyb3dGbj5gXG4gKiBrZXksIHdoaWNoIGRlZmluZXMgaG93IHRoaXMgb2JqZWN0IHNob3VsZCBiZSBtYXRjaGVkIGJ5IFRTLVBhdHRlcm4uXG4gKlxuICogQGV4cGVyaW1lbnRhbCBUaGlzIGZlYXR1cmUgaXMgdW5zdGFibGUuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHRzXG4gKiBjbGFzcyBTb21lPFQ+IGltcGxlbWVudHMgUC51bnN0YWJsZV9NYXRjaGFibGUge1xuICogIFtQLm1hdGNoZXJdKCk6IFAudW5zdGFibGVfTWF0Y2hlcjxTb21lPFQ+PlxuICogfVxuICogYGBgXG4gKi9cbmV4cG9ydCB0eXBlIHVuc3RhYmxlX01hdGNoYWJsZTxcbiAgbmFycm93ZWRPckZuLFxuICBpbnB1dCA9IHVua25vd24sXG4gIHBhdHRlcm4gPSBuZXZlclxuPiA9IEN1c3RvbVA8aW5wdXQsIHBhdHRlcm4sIG5hcnJvd2VkT3JGbj47XG5cbi8qKlxuICogQSBgTWF0Y2hlcmAgaXMgYW4gb2JqZWN0IHdpdGggYG1hdGNoYCBmdW5jdGlvbiwgd2hpY2hcbiAqIGRlZmluZXMgaG93IHRoaXMgb2JqZWN0IHNob3VsZCBiZSBtYXRjaGVkIGJ5IFRTLVBhdHRlcm4uXG4gKlxuICogQGV4cGVyaW1lbnRhbCBUaGlzIGZlYXR1cmUgaXMgdW5zdGFibGUuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHRzXG4gKiBjbGFzcyBTb21lPFQ+IGltcGxlbWVudHMgUC51bnN0YWJsZV9NYXRjaGFibGUge1xuICogIFtQLm1hdGNoZXJdKCk6IFAudW5zdGFibGVfTWF0Y2hlcjxTb21lPFQ+PlxuICogfVxuICogYGBgXG4gKi9cbmV4cG9ydCB0eXBlIHVuc3RhYmxlX01hdGNoZXI8XG4gIG5hcnJvd2VkT3JGbixcbiAgaW5wdXQgPSB1bmtub3duLFxuICBwYXR0ZXJuID0gbmV2ZXJcbj4gPSBSZXR1cm5UeXBlPEN1c3RvbVA8aW5wdXQsIHBhdHRlcm4sIG5hcnJvd2VkT3JGbj5bbWF0Y2hlcl0+O1xuXG4vKipcbiAqIGBQLmluZmVyPHR5cGVvZiBzb21lUGF0dGVybj5gIHdpbGwgcmV0dXJuIHRoZSB0eXBlIG9mIHRoZSB2YWx1ZVxuICogbWF0Y2hlZCBieSB0aGlzIHBhdHRlcm4uXG4gKlxuICogW1JlYWQgdGhlIGRvY3VtZW50YXRpb24gZm9yIGBQLmluZmVyYCBvbiBHaXRIdWJdKGh0dHBzOi8vZ2l0aHViLmNvbS9ndmVyZ25hdWQvdHMtcGF0dGVybiNwaW5mZXIpXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHVzZXJQYXR0ZXJuID0geyBuYW1lOiBQLnN0cmluZ8KgfVxuICogdHlwZSBVc2VyID0gUC5pbmZlcjx0eXBlb2YgdXNlclBhdHRlcm4+XG4gKi9cbmV4cG9ydCB0eXBlIGluZmVyPHBhdHRlcm4+ID0gSW52ZXJ0UGF0dGVybjxOb0luZmVyPHBhdHRlcm4+LCB1bmtub3duPjtcblxuLyoqXG4gKiBgUC5uYXJyb3c8SW5wdXQsIFBhdHRlcm4+YCB3aWxsIG5hcnJvdyB0aGUgaW5wdXQgdHlwZSB0byBvbmx5IGtlZXBcbiAqIHRoZSBzZXQgb2YgdmFsdWVzIHRoYXQgYXJlIGNvbXBhdGlibGUgd2l0aCB0aGUgcHJvdmlkZWQgcGF0dGVybiB0eXBlLlxuICpcbiAqIFtSZWFkIHRoZSBkb2N1bWVudGF0aW9uIGZvciBgUC5uYXJyb3dgIG9uIEdpdEh1Yl0oaHR0cHM6Ly9naXRodWIuY29tL2d2ZXJnbmF1ZC90cy1wYXR0ZXJuI3BuYXJyb3cpXG4gKlxuICogQGV4YW1wbGVcbiAqIHR5cGUgSW5wdXQgPSBbJ2EnIHwgJ2InIHwgJ2MnLCAnYScgfCAnYicgfCAnYyddXG4gKiBjb25zdCBQYXR0ZXJuID0gWydhJywgUC51bmlvbignYScsICdiJyldIGFzIGNvbnN0XG4gKlxuICogdHlwZSBOYXJyb3dlZCA9IFAubmFycm93PElucHV0LCB0eXBlb2YgUGF0dGVybj5cbiAqIC8vICAgICBePyBbJ2EnLCAnYScgfCAnYiddXG4gKi9cbmV4cG9ydCB0eXBlIG5hcnJvdzxpbnB1dCwgcGF0dGVybj4gPSBFeHRyYWN0UHJlY2lzZVZhbHVlPFxuICBpbnB1dCxcbiAgSW52ZXJ0UGF0dGVybjxwYXR0ZXJuLCBpbnB1dD5cbj47XG5cbmZ1bmN0aW9uIGNoYWluYWJsZTxwYXR0ZXJuIGV4dGVuZHMgTWF0Y2hlcjxhbnksIGFueSwgYW55LCBhbnksIGFueT4+KFxuICBwYXR0ZXJuOiBwYXR0ZXJuXG4pOiBDaGFpbmFibGU8cGF0dGVybj4ge1xuICByZXR1cm4gT2JqZWN0LmFzc2lnbihwYXR0ZXJuLCB7XG4gICAgb3B0aW9uYWw6ICgpID0+IG9wdGlvbmFsKHBhdHRlcm4pLFxuICAgIGFuZDogKHAyOiBhbnkpID0+IGludGVyc2VjdGlvbihwYXR0ZXJuLCBwMiksXG4gICAgb3I6IChwMjogYW55KSA9PiB1bmlvbihwYXR0ZXJuLCBwMiksXG4gICAgc2VsZWN0OiAoa2V5OiBhbnkpID0+XG4gICAgICBrZXkgPT09IHVuZGVmaW5lZCA/IHNlbGVjdChwYXR0ZXJuKSA6IHNlbGVjdChrZXksIHBhdHRlcm4pLFxuICB9KSBhcyBDaGFpbmFibGU8cGF0dGVybj47XG59XG5cbmNvbnN0IHZhcmlhZGljID0gPHBhdHRlcm4gZXh0ZW5kcyB7fT4ocGF0dGVybjogcGF0dGVybik6IFZhcmlhZGljPHBhdHRlcm4+ID0+XG4gIE9iamVjdC5hc3NpZ24ocGF0dGVybiwge1xuICAgIFtTeW1ib2wuaXRlcmF0b3JdKCk6IEl0ZXJhdG9yPHBhdHRlcm4sIHZvaWQsIHVuZGVmaW5lZD4ge1xuICAgICAgbGV0IGkgPSAwO1xuICAgICAgY29uc3QgdmFyaWFkaWNQYXR0ZXJuID0gT2JqZWN0LmFzc2lnbihwYXR0ZXJuLCB7XG4gICAgICAgIFtzeW1ib2xzLmlzVmFyaWFkaWNdOiB0cnVlLFxuICAgICAgfSk7XG4gICAgICBjb25zdCB2YWx1ZXM6IEl0ZXJhdG9yUmVzdWx0PHBhdHRlcm4sIHZvaWQ+W10gPSBbXG4gICAgICAgIHsgdmFsdWU6IHZhcmlhZGljUGF0dGVybiwgZG9uZTogZmFsc2UgfSxcbiAgICAgICAgeyBkb25lOiB0cnVlLCB2YWx1ZTogdW5kZWZpbmVkIH0sXG4gICAgICBdO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgbmV4dDogKCkgPT4gdmFsdWVzW2krK10gPz8gdmFsdWVzLmF0KC0xKSEsXG4gICAgICB9O1xuICAgIH0sXG4gIH0pO1xuXG5mdW5jdGlvbiBhcnJheUNoYWluYWJsZTxwYXR0ZXJuIGV4dGVuZHMgTWF0Y2hlcjxhbnksIGFueSwgYW55LCBhbnksIGFueT4+KFxuICBwYXR0ZXJuOiBwYXR0ZXJuXG4pOiBBcnJheUNoYWluYWJsZTxwYXR0ZXJuPiB7XG4gIHJldHVybiBPYmplY3QuYXNzaWduKHZhcmlhZGljKHBhdHRlcm4pLCB7XG4gICAgb3B0aW9uYWw6ICgpID0+IGFycmF5Q2hhaW5hYmxlKG9wdGlvbmFsKHBhdHRlcm4pKSxcbiAgICBzZWxlY3Q6IChrZXk6IGFueSkgPT5cbiAgICAgIGFycmF5Q2hhaW5hYmxlKFxuICAgICAgICBrZXkgPT09IHVuZGVmaW5lZCA/IHNlbGVjdChwYXR0ZXJuKSA6IHNlbGVjdChrZXksIHBhdHRlcm4pXG4gICAgICApLFxuICB9KSBhcyBhbnk7XG59XG5cbi8qKlxuICogYFAub3B0aW9uYWwoc3VicGF0dGVybilgIHRha2VzIGEgc3ViIHBhdHRlcm4gYW5kIHJldHVybnMgYSBwYXR0ZXJuIHdoaWNoIG1hdGNoZXMgaWYgdGhlXG4gKiBrZXkgaXMgdW5kZWZpbmVkIG9yIGlmIGl0IGlzIGRlZmluZWQgYW5kIHRoZSBzdWIgcGF0dGVybiBtYXRjaGVzIGl0cyB2YWx1ZS5cbiAqXG4gKiBbUmVhZCB0aGUgZG9jdW1lbnRhdGlvbiBmb3IgYFAub3B0aW9uYWxgIG9uIEdpdEh1Yl0oaHR0cHM6Ly9naXRodWIuY29tL2d2ZXJnbmF1ZC90cy1wYXR0ZXJuI3BvcHRpb25hbC1wYXR0ZXJucylcbiAqXG4gKiBAZXhhbXBsZVxuICogIG1hdGNoKHZhbHVlKVxuICogICAud2l0aCh7IGdyZWV0aW5nOiBQLm9wdGlvbmFsKCdIZWxsbycpIH0sICgpID0+ICd3aWxsIG1hdGNoIHsgZ3JlZXRpbmc/OiBcIkhlbGxvXCLCoH0nKVxuICovXG5leHBvcnQgZnVuY3Rpb24gb3B0aW9uYWw8XG4gIGlucHV0LFxuICBjb25zdCBwYXR0ZXJuIGV4dGVuZHMgdW5rbm93biBleHRlbmRzIGlucHV0ID8gVW5rbm93blBhdHRlcm4gOiBQYXR0ZXJuPGlucHV0PlxuPihwYXR0ZXJuOiBwYXR0ZXJuKTogQ2hhaW5hYmxlPE9wdGlvbmFsUDxpbnB1dCwgcGF0dGVybj4sICdvcHRpb25hbCc+IHtcbiAgcmV0dXJuIGNoYWluYWJsZSh7XG4gICAgW21hdGNoZXJdKCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgbWF0Y2g6IDxVbmtub3duSW5wdXQ+KHZhbHVlOiBVbmtub3duSW5wdXQgfCBpbnB1dCkgPT4ge1xuICAgICAgICAgIGxldCBzZWxlY3Rpb25zOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duW10+ID0ge307XG4gICAgICAgICAgY29uc3Qgc2VsZWN0b3IgPSAoa2V5OiBzdHJpbmcsIHZhbHVlOiBhbnkpID0+IHtcbiAgICAgICAgICAgIHNlbGVjdGlvbnNba2V5XSA9IHZhbHVlO1xuICAgICAgICAgIH07XG4gICAgICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGdldFNlbGVjdGlvbktleXMocGF0dGVybikuZm9yRWFjaCgoa2V5KSA9PlxuICAgICAgICAgICAgICBzZWxlY3RvcihrZXksIHVuZGVmaW5lZClcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICByZXR1cm4geyBtYXRjaGVkOiB0cnVlLCBzZWxlY3Rpb25zIH07XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IG1hdGNoZWQgPSBtYXRjaFBhdHRlcm4ocGF0dGVybiwgdmFsdWUsIHNlbGVjdG9yKTtcbiAgICAgICAgICByZXR1cm4geyBtYXRjaGVkLCBzZWxlY3Rpb25zIH07XG4gICAgICAgIH0sXG4gICAgICAgIGdldFNlbGVjdGlvbktleXM6ICgpID0+IGdldFNlbGVjdGlvbktleXMocGF0dGVybiksXG4gICAgICAgIG1hdGNoZXJUeXBlOiAnb3B0aW9uYWwnLFxuICAgICAgfTtcbiAgICB9LFxuICB9KTtcbn1cblxudHlwZSBVbndyYXBBcnJheTx4cz4gPSB4cyBleHRlbmRzIHJlYWRvbmx5IChpbmZlciB4KVtdID8geCA6IG5ldmVyO1xuXG50eXBlIFVud3JhcFNldDx4cz4gPSB4cyBleHRlbmRzIFNldDxpbmZlciB4PiA/IHggOiBuZXZlcjtcblxudHlwZSBVbndyYXBNYXBLZXk8eHM+ID0geHMgZXh0ZW5kcyBNYXA8aW5mZXIgaywgYW55PiA/IGsgOiBuZXZlcjtcblxudHlwZSBVbndyYXBNYXBWYWx1ZTx4cz4gPSB4cyBleHRlbmRzIE1hcDxhbnksIGluZmVyIHY+ID8gdiA6IG5ldmVyO1xuXG50eXBlIFdpdGhEZWZhdWx0PGEsIGI+ID0gW2FdIGV4dGVuZHMgW25ldmVyXSA/IGIgOiBhO1xuXG4vKipcbiAqIGBQLmFycmF5KHN1YnBhdHRlcm4pYCB0YWtlcyBhIHN1YiBwYXR0ZXJuIGFuZCByZXR1cm5zIGEgcGF0dGVybiwgd2hpY2ggbWF0Y2hlc1xuICogYXJyYXlzIGlmIGFsbCB0aGVpciBlbGVtZW50cyBtYXRjaCB0aGUgc3ViIHBhdHRlcm4uXG4gKlxuICogW1JlYWQgdGhlIGRvY3VtZW50YXRpb24gZm9yIGBQLmFycmF5YCBvbiBHaXRIdWJdKGh0dHBzOi8vZ2l0aHViLmNvbS9ndmVyZ25hdWQvdHMtcGF0dGVybiNwYXJyYXktcGF0dGVybnMpXG4gKlxuICogQGV4YW1wbGVcbiAqICBtYXRjaCh2YWx1ZSlcbiAqICAgLndpdGgoeyB1c2VyczogUC5hcnJheSh7IG5hbWU6IFAuc3RyaW5nIH0pIH0sICgpID0+ICd3aWxsIG1hdGNoIHsgbmFtZTogc3RyaW5nwqB9W10nKVxuICovXG5leHBvcnQgZnVuY3Rpb24gYXJyYXk8aW5wdXQ+KCk6IEFycmF5Q2hhaW5hYmxlPEFycmF5UDxpbnB1dCwgdW5rbm93bj4+O1xuZXhwb3J0IGZ1bmN0aW9uIGFycmF5PFxuICBpbnB1dCxcbiAgY29uc3QgcGF0dGVybiBleHRlbmRzIFBhdHRlcm48V2l0aERlZmF1bHQ8VW53cmFwQXJyYXk8aW5wdXQ+LCB1bmtub3duPj5cbj4ocGF0dGVybjogcGF0dGVybik6IEFycmF5Q2hhaW5hYmxlPEFycmF5UDxpbnB1dCwgcGF0dGVybj4+O1xuZXhwb3J0IGZ1bmN0aW9uIGFycmF5KFxuICAuLi5hcmdzOiBbcGF0dGVybj86IGFueV1cbik6IEFycmF5Q2hhaW5hYmxlPEFycmF5UDxhbnksIGFueT4+IHtcbiAgcmV0dXJuIGFycmF5Q2hhaW5hYmxlKHtcbiAgICBbbWF0Y2hlcl0oKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBtYXRjaDogKHZhbHVlOiBhbnkpID0+IHtcbiAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkodmFsdWUpKSByZXR1cm4geyBtYXRjaGVkOiBmYWxzZSB9O1xuXG4gICAgICAgICAgaWYgKGFyZ3MubGVuZ3RoID09PSAwKSByZXR1cm4geyBtYXRjaGVkOiB0cnVlIH07XG5cbiAgICAgICAgICBjb25zdCBwYXR0ZXJuID0gYXJnc1swXTtcbiAgICAgICAgICBsZXQgc2VsZWN0aW9uczogUmVjb3JkPHN0cmluZywgdW5rbm93bltdPiA9IHt9O1xuXG4gICAgICAgICAgaWYgKHZhbHVlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgZ2V0U2VsZWN0aW9uS2V5cyhwYXR0ZXJuKS5mb3JFYWNoKChrZXkpID0+IHtcbiAgICAgICAgICAgICAgc2VsZWN0aW9uc1trZXldID0gW107XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiB7IG1hdGNoZWQ6IHRydWUsIHNlbGVjdGlvbnMgfTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBzZWxlY3RvciA9IChrZXk6IHN0cmluZywgdmFsdWU6IHVua25vd24pID0+IHtcbiAgICAgICAgICAgIHNlbGVjdGlvbnNba2V5XSA9IChzZWxlY3Rpb25zW2tleV0gfHwgW10pLmNvbmNhdChbdmFsdWVdKTtcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgY29uc3QgbWF0Y2hlZCA9IHZhbHVlLmV2ZXJ5KCh2KSA9PlxuICAgICAgICAgICAgbWF0Y2hQYXR0ZXJuKHBhdHRlcm4sIHYsIHNlbGVjdG9yKVxuICAgICAgICAgICk7XG5cbiAgICAgICAgICByZXR1cm4geyBtYXRjaGVkLCBzZWxlY3Rpb25zIH07XG4gICAgICAgIH0sXG4gICAgICAgIGdldFNlbGVjdGlvbktleXM6ICgpID0+XG4gICAgICAgICAgYXJncy5sZW5ndGggPT09IDAgPyBbXSA6IGdldFNlbGVjdGlvbktleXMoYXJnc1swXSksXG4gICAgICB9O1xuICAgIH0sXG4gIH0pO1xufVxuXG4vKipcbiAqIGBQLnNldChzdWJwYXR0ZXJuKWAgdGFrZXMgYSBzdWIgcGF0dGVybiBhbmQgcmV0dXJucyBhIHBhdHRlcm4gdGhhdCBtYXRjaGVzXG4gKiBzZXRzIGlmIGFsbCB0aGVpciBlbGVtZW50cyBtYXRjaCB0aGUgc3ViIHBhdHRlcm4uXG4gKlxuICogW1JlYWQgYFAuc2V0YCBkb2N1bWVudGF0aW9uIG9uIEdpdEh1Yl0oaHR0cHM6Ly9naXRodWIuY29tL2d2ZXJnbmF1ZC90cy1wYXR0ZXJuI3BzZXQtcGF0dGVybnMpXG4gKlxuICogQGV4YW1wbGVcbiAqICBtYXRjaCh2YWx1ZSlcbiAqICAgLndpdGgoeyB1c2VyczogUC5zZXQoUC5zdHJpbmcpIH0sICgpID0+ICd3aWxsIG1hdGNoIFNldDxzdHJpbmc+JylcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNldDxpbnB1dD4oKTogQ2hhaW5hYmxlPFNldFA8aW5wdXQsIHVua25vd24+PjtcbmV4cG9ydCBmdW5jdGlvbiBzZXQ8XG4gIGlucHV0LFxuICBjb25zdCBwYXR0ZXJuIGV4dGVuZHMgUGF0dGVybjxXaXRoRGVmYXVsdDxVbndyYXBTZXQ8aW5wdXQ+LCB1bmtub3duPj5cbj4ocGF0dGVybjogcGF0dGVybik6IENoYWluYWJsZTxTZXRQPGlucHV0LCBwYXR0ZXJuPj47XG5leHBvcnQgZnVuY3Rpb24gc2V0PFxuICBpbnB1dCxcbiAgY29uc3QgcGF0dGVybiBleHRlbmRzIFBhdHRlcm48V2l0aERlZmF1bHQ8VW53cmFwU2V0PGlucHV0PiwgdW5rbm93bj4+XG4+KC4uLmFyZ3M6IFtwYXR0ZXJuPzogcGF0dGVybl0pOiBDaGFpbmFibGU8U2V0UDxpbnB1dCwgcGF0dGVybj4+IHtcbiAgcmV0dXJuIGNoYWluYWJsZSh7XG4gICAgW21hdGNoZXJdKCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgbWF0Y2g6IDxVbmtub3duSW5wdXQ+KHZhbHVlOiBVbmtub3duSW5wdXQgfCBpbnB1dCkgPT4ge1xuICAgICAgICAgIGlmICghKHZhbHVlIGluc3RhbmNlb2YgU2V0KSkgcmV0dXJuIHsgbWF0Y2hlZDogZmFsc2UgfTtcblxuICAgICAgICAgIGxldCBzZWxlY3Rpb25zOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duW10+ID0ge307XG5cbiAgICAgICAgICBpZiAodmFsdWUuc2l6ZSA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHsgbWF0Y2hlZDogdHJ1ZSwgc2VsZWN0aW9ucyB9O1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChhcmdzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHsgbWF0Y2hlZDogdHJ1ZSB9O1xuXG4gICAgICAgICAgY29uc3Qgc2VsZWN0b3IgPSAoa2V5OiBzdHJpbmcsIHZhbHVlOiB1bmtub3duKSA9PiB7XG4gICAgICAgICAgICBzZWxlY3Rpb25zW2tleV0gPSAoc2VsZWN0aW9uc1trZXldIHx8IFtdKS5jb25jYXQoW3ZhbHVlXSk7XG4gICAgICAgICAgfTtcblxuICAgICAgICAgIGNvbnN0IHBhdHRlcm4gPSBhcmdzWzBdO1xuXG4gICAgICAgICAgY29uc3QgbWF0Y2hlZCA9IHNldEV2ZXJ5KHZhbHVlLCAodikgPT5cbiAgICAgICAgICAgIG1hdGNoUGF0dGVybihwYXR0ZXJuLCB2LCBzZWxlY3RvcilcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgcmV0dXJuIHsgbWF0Y2hlZCwgc2VsZWN0aW9ucyB9O1xuICAgICAgICB9LFxuICAgICAgICBnZXRTZWxlY3Rpb25LZXlzOiAoKSA9PlxuICAgICAgICAgIGFyZ3MubGVuZ3RoID09PSAwID8gW10gOiBnZXRTZWxlY3Rpb25LZXlzKGFyZ3NbMF0pLFxuICAgICAgfTtcbiAgICB9LFxuICB9KTtcbn1cblxuY29uc3Qgc2V0RXZlcnkgPSA8VD4oc2V0OiBTZXQ8VD4sIHByZWRpY2F0ZTogKHZhbHVlOiBUKSA9PiBib29sZWFuKSA9PiB7XG4gIGZvciAoY29uc3QgdmFsdWUgb2Ygc2V0KSB7XG4gICAgaWYgKHByZWRpY2F0ZSh2YWx1ZSkpIGNvbnRpbnVlO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbi8qKlxuICogYFAubWFwKGtleVBhdHRlcm4sIHZhbHVlUGF0dGVybilgIHRha2VzIGEgc3VicGF0dGVybiB0byBtYXRjaCBhZ2FpbnN0IHRoZVxuICoga2V5LCBhIHN1YnBhdHRlcm4gdG8gbWF0Y2ggYWdhaW5zdCB0aGUgdmFsdWUgYW5kIHJldHVybnMgYSBwYXR0ZXJuIHRoYXRcbiAqIG1hdGNoZXMgb24gbWFwcyB3aGVyZSBhbGwgZWxlbWVudHMgaW5zaWRlIHRoZSBtYXAgbWF0Y2ggdGhvc2UgdHdvXG4gKiBzdWJwYXR0ZXJucy5cbiAqXG4gKiBbUmVhZCBgUC5tYXBgIGRvY3VtZW50YXRpb24gb24gR2l0SHViXShodHRwczovL2dpdGh1Yi5jb20vZ3ZlcmduYXVkL3RzLXBhdHRlcm4jcG1hcC1wYXR0ZXJucylcbiAqXG4gKiBAZXhhbXBsZVxuICogIG1hdGNoKHZhbHVlKVxuICogICAud2l0aCh7IHVzZXJzOiBQLm1hcChQLm1hcChQLnN0cmluZywgUC5udW1iZXIpKSB9LCAobWFwKSA9PiBgbWFwJ3MgdHlwZSBpcyBNYXA8c3RyaW5nLCBudW1iZXI+YClcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1hcDxpbnB1dD4oKTogQ2hhaW5hYmxlPE1hcFA8aW5wdXQsIHVua25vd24sIHVua25vd24+PjtcbmV4cG9ydCBmdW5jdGlvbiBtYXA8XG4gIGlucHV0LFxuICBjb25zdCBwa2V5IGV4dGVuZHMgUGF0dGVybjxXaXRoRGVmYXVsdDxVbndyYXBNYXBLZXk8aW5wdXQ+LCB1bmtub3duPj4sXG4gIGNvbnN0IHB2YWx1ZSBleHRlbmRzIFBhdHRlcm48V2l0aERlZmF1bHQ8VW53cmFwTWFwVmFsdWU8aW5wdXQ+LCB1bmtub3duPj5cbj4ocGF0dGVybktleTogcGtleSwgcGF0dGVyblZhbHVlOiBwdmFsdWUpOiBDaGFpbmFibGU8TWFwUDxpbnB1dCwgcGtleSwgcHZhbHVlPj47XG5leHBvcnQgZnVuY3Rpb24gbWFwPFxuICBpbnB1dCxcbiAgY29uc3QgcGtleSBleHRlbmRzIFBhdHRlcm48V2l0aERlZmF1bHQ8VW53cmFwTWFwS2V5PGlucHV0PiwgdW5rbm93bj4+LFxuICBjb25zdCBwdmFsdWUgZXh0ZW5kcyBQYXR0ZXJuPFdpdGhEZWZhdWx0PFVud3JhcE1hcFZhbHVlPGlucHV0PiwgdW5rbm93bj4+XG4+KFxuICAuLi5hcmdzOiBbcGF0dGVybktleT86IHBrZXksIHBhdHRlcm5WYWx1ZT86IHB2YWx1ZV1cbik6IENoYWluYWJsZTxNYXBQPGlucHV0LCBwa2V5LCBwdmFsdWU+PiB7XG4gIHJldHVybiBjaGFpbmFibGUoe1xuICAgIFttYXRjaGVyXSgpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIG1hdGNoOiA8VW5rbm93bklucHV0Pih2YWx1ZTogVW5rbm93bklucHV0IHwgaW5wdXQpID0+IHtcbiAgICAgICAgICBpZiAoISh2YWx1ZSBpbnN0YW5jZW9mIE1hcCkpIHJldHVybiB7IG1hdGNoZWQ6IGZhbHNlIH07XG5cbiAgICAgICAgICBsZXQgc2VsZWN0aW9uczogUmVjb3JkPHN0cmluZywgdW5rbm93bltdPiA9IHt9O1xuXG4gICAgICAgICAgaWYgKHZhbHVlLnNpemUgPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiB7IG1hdGNoZWQ6IHRydWUsIHNlbGVjdGlvbnMgfTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBzZWxlY3RvciA9IChrZXk6IHN0cmluZywgdmFsdWU6IHVua25vd24pID0+IHtcbiAgICAgICAgICAgIHNlbGVjdGlvbnNba2V5XSA9IChzZWxlY3Rpb25zW2tleV0gfHwgW10pLmNvbmNhdChbdmFsdWVdKTtcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgaWYgKGFyZ3MubGVuZ3RoID09PSAwKSByZXR1cm4geyBtYXRjaGVkOiB0cnVlIH07XG4gICAgICAgICAgaWYgKGFyZ3MubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgIGBcXGBQLm1hcFxcYCB3YXNuXFwndCBnaXZlbiBlbm91Z2ggYXJndW1lbnRzLiBFeHBlY3RlZCAoa2V5LCB2YWx1ZSksIHJlY2VpdmVkICR7YXJnc1swXT8udG9TdHJpbmcoKX1gXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBbcGF0dGVybktleSwgcGF0dGVyblZhbHVlXSA9IGFyZ3M7XG5cbiAgICAgICAgICBjb25zdCBtYXRjaGVkID0gbWFwRXZlcnkodmFsdWUsICh2LCBrKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBrZXlNYXRjaCA9IG1hdGNoUGF0dGVybihwYXR0ZXJuS2V5LCBrLCBzZWxlY3Rvcik7XG4gICAgICAgICAgICBjb25zdCB2YWx1ZU1hdGNoID0gbWF0Y2hQYXR0ZXJuKHBhdHRlcm5WYWx1ZSwgdiwgc2VsZWN0b3IpO1xuICAgICAgICAgICAgcmV0dXJuIGtleU1hdGNoICYmIHZhbHVlTWF0Y2g7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICByZXR1cm4geyBtYXRjaGVkLCBzZWxlY3Rpb25zIH07XG4gICAgICAgIH0sXG4gICAgICAgIGdldFNlbGVjdGlvbktleXM6ICgpID0+XG4gICAgICAgICAgYXJncy5sZW5ndGggPT09IDBcbiAgICAgICAgICAgID8gW11cbiAgICAgICAgICAgIDogWy4uLmdldFNlbGVjdGlvbktleXMoYXJnc1swXSksIC4uLmdldFNlbGVjdGlvbktleXMoYXJnc1sxXSldLFxuICAgICAgfTtcbiAgICB9LFxuICB9KTtcbn1cblxuY29uc3QgbWFwRXZlcnkgPSA8SywgVD4oXG4gIG1hcDogTWFwPEssIFQ+LFxuICBwcmVkaWNhdGU6ICh2YWx1ZTogVCwga2V5OiBLKSA9PiBib29sZWFuXG4pID0+IHtcbiAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgbWFwLmVudHJpZXMoKSkge1xuICAgIGlmIChwcmVkaWNhdGUodmFsdWUsIGtleSkpIGNvbnRpbnVlO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbi8qKlxuICogYFAuaW50ZXJzZWN0aW9uKC4uLnBhdHRlcm5zKWAgcmV0dXJucyBhIHBhdHRlcm4gd2hpY2ggbWF0Y2hlc1xuICogb25seSBpZiAqKmV2ZXJ5KiogcGF0dGVybnMgcHJvdmlkZWQgaW4gcGFyYW1ldGVyIG1hdGNoIHRoZSBpbnB1dC5cbiAqXG4gKiBbUmVhZCB0aGUgZG9jdW1lbnRhdGlvbiBmb3IgYFAuaW50ZXJzZWN0aW9uYCBvbiBHaXRIdWJdKGh0dHBzOi8vZ2l0aHViLmNvbS9ndmVyZ25hdWQvdHMtcGF0dGVybiNwaW50ZXJzZWN0aW9uLXBhdHRlcm5zKVxuICpcbiAqIEBleGFtcGxlXG4gKiAgbWF0Y2godmFsdWUpXG4gKiAgIC53aXRoKFxuICogICAgIHtcbiAqICAgICAgIHVzZXI6IFAuaW50ZXJzZWN0aW9uKFxuICogICAgICAgICB7IGZpcnN0bmFtZTogUC5zdHJpbmcgfSxcbiAqICAgICAgICAgeyBsYXN0bmFtZTogUC5zdHJpbmcgfSxcbiAqICAgICAgICAgeyBhZ2U6IFAud2hlbihhZ2UgPT4gYWdlID4gMjEpIH1cbiAqICAgICAgIClcbiAqICAgICB9LFxuICogICAgICh7IHVzZXIgfSkgPT4gJ3dpbGwgbWF0Y2ggeyBmaXJzdG5hbWU6IHN0cmluZywgbGFzdG5hbWU6IHN0cmluZywgYWdlOiBudW1iZXIgfSBpZiBhZ2UgPiAyMSdcbiAqICAgKVxuICovXG5leHBvcnQgZnVuY3Rpb24gaW50ZXJzZWN0aW9uPFxuICBpbnB1dCxcbiAgY29uc3QgcGF0dGVybnMgZXh0ZW5kcyByZWFkb25seSBbUGF0dGVybjxpbnB1dD4sIC4uLlBhdHRlcm48aW5wdXQ+W11dXG4+KC4uLnBhdHRlcm5zOiBwYXR0ZXJucyk6IENoYWluYWJsZTxBbmRQPGlucHV0LCBwYXR0ZXJucz4+IHtcbiAgcmV0dXJuIGNoYWluYWJsZSh7XG4gICAgW21hdGNoZXJdOiAoKSA9PiAoe1xuICAgICAgbWF0Y2g6ICh2YWx1ZSkgPT4ge1xuICAgICAgICBsZXQgc2VsZWN0aW9uczogUmVjb3JkPHN0cmluZywgdW5rbm93bltdPiA9IHt9O1xuICAgICAgICBjb25zdCBzZWxlY3RvciA9IChrZXk6IHN0cmluZywgdmFsdWU6IGFueSkgPT4ge1xuICAgICAgICAgIHNlbGVjdGlvbnNba2V5XSA9IHZhbHVlO1xuICAgICAgICB9O1xuICAgICAgICBjb25zdCBtYXRjaGVkID0gKHBhdHRlcm5zIGFzIHJlYWRvbmx5IFVua25vd25QYXR0ZXJuW10pLmV2ZXJ5KChwKSA9PlxuICAgICAgICAgIG1hdGNoUGF0dGVybihwLCB2YWx1ZSwgc2VsZWN0b3IpXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiB7IG1hdGNoZWQsIHNlbGVjdGlvbnMgfTtcbiAgICAgIH0sXG4gICAgICBnZXRTZWxlY3Rpb25LZXlzOiAoKSA9PlxuICAgICAgICBmbGF0TWFwKHBhdHRlcm5zIGFzIHJlYWRvbmx5IFVua25vd25QYXR0ZXJuW10sIGdldFNlbGVjdGlvbktleXMpLFxuICAgICAgbWF0Y2hlclR5cGU6ICdhbmQnLFxuICAgIH0pLFxuICB9KTtcbn1cblxuLyoqXG4gKiBgUC51bmlvbiguLi5wYXR0ZXJucylgIHJldHVybnMgYSBwYXR0ZXJuIHdoaWNoIG1hdGNoZXNcbiAqIGlmICoqYXQgbGVhc3Qgb25lKiogb2YgdGhlIHBhdHRlcm5zIHByb3ZpZGVkIGluIHBhcmFtZXRlciBtYXRjaCB0aGUgaW5wdXQuXG4gKlxuICogW1JlYWQgdGhlIGRvY3VtZW50YXRpb24gZm9yIGBQLnVuaW9uYCBvbiBHaXRIdWJdKGh0dHBzOi8vZ2l0aHViLmNvbS9ndmVyZ25hdWQvdHMtcGF0dGVybiNwdW5pb24tcGF0dGVybnMpXG4gKlxuICogQGV4YW1wbGVcbiAqICBtYXRjaCh2YWx1ZSlcbiAqICAgLndpdGgoXG4gKiAgICAgeyB0eXBlOiBQLnVuaW9uKCdhJywgJ2InLCAnYycpIH0sXG4gKiAgICAgKHsgdHlwZSB9KSA9PiAnd2lsbCBtYXRjaCB7IHR5cGU6IFwiYVwiIHwgXCJiXCIgfCBcImNcIiB9J1xuICogICApXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1bmlvbjxcbiAgaW5wdXQsXG4gIGNvbnN0IHBhdHRlcm5zIGV4dGVuZHMgcmVhZG9ubHkgW1BhdHRlcm48aW5wdXQ+LCAuLi5QYXR0ZXJuPGlucHV0PltdXVxuPiguLi5wYXR0ZXJuczogcGF0dGVybnMpOiBDaGFpbmFibGU8T3JQPGlucHV0LCBwYXR0ZXJucz4+IHtcbiAgcmV0dXJuIGNoYWluYWJsZSh7XG4gICAgW21hdGNoZXJdOiAoKSA9PiAoe1xuICAgICAgbWF0Y2g6IDxVbmtub3duSW5wdXQ+KHZhbHVlOiBVbmtub3duSW5wdXQgfCBpbnB1dCkgPT4ge1xuICAgICAgICBsZXQgc2VsZWN0aW9uczogUmVjb3JkPHN0cmluZywgdW5rbm93bltdPiA9IHt9O1xuICAgICAgICBjb25zdCBzZWxlY3RvciA9IChrZXk6IHN0cmluZywgdmFsdWU6IGFueSkgPT4ge1xuICAgICAgICAgIHNlbGVjdGlvbnNba2V5XSA9IHZhbHVlO1xuICAgICAgICB9O1xuICAgICAgICBmbGF0TWFwKFxuICAgICAgICAgIHBhdHRlcm5zIGFzIHJlYWRvbmx5IFVua25vd25QYXR0ZXJuW10sXG4gICAgICAgICAgZ2V0U2VsZWN0aW9uS2V5c1xuICAgICAgICApLmZvckVhY2goKGtleSkgPT4gc2VsZWN0b3Ioa2V5LCB1bmRlZmluZWQpKTtcbiAgICAgICAgY29uc3QgbWF0Y2hlZCA9IChwYXR0ZXJucyBhcyByZWFkb25seSBVbmtub3duUGF0dGVybltdKS5zb21lKChwKSA9PlxuICAgICAgICAgIG1hdGNoUGF0dGVybihwLCB2YWx1ZSwgc2VsZWN0b3IpXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiB7IG1hdGNoZWQsIHNlbGVjdGlvbnMgfTtcbiAgICAgIH0sXG4gICAgICBnZXRTZWxlY3Rpb25LZXlzOiAoKSA9PlxuICAgICAgICBmbGF0TWFwKHBhdHRlcm5zIGFzIHJlYWRvbmx5IFVua25vd25QYXR0ZXJuW10sIGdldFNlbGVjdGlvbktleXMpLFxuICAgICAgbWF0Y2hlclR5cGU6ICdvcicsXG4gICAgfSksXG4gIH0pO1xufVxuXG4vKipcbiAqIGBQLm5vdChwYXR0ZXJuKWAgcmV0dXJucyBhIHBhdHRlcm4gd2hpY2ggbWF0Y2hlcyBpZiB0aGUgc3ViIHBhdHRlcm5cbiAqIGRvZXNuJ3QgbWF0Y2guXG4gKlxuICogW1JlYWQgdGhlIGRvY3VtZW50YXRpb24gZm9yIGBQLm5vdGAgb24gR2l0SHViXShodHRwczovL2dpdGh1Yi5jb20vZ3ZlcmduYXVkL3RzLXBhdHRlcm4jcG5vdC1wYXR0ZXJucylcbiAqXG4gKiBAZXhhbXBsZVxuICogIG1hdGNoPHsgYTogc3RyaW5nIHwgbnVtYmVyIH0+KHZhbHVlKVxuICogICAud2l0aCh7IGE6IFAubm90KFAuc3RyaW5nKSB9LCAoeCkgPT4gJ3dpbGwgbWF0Y2ggeyBhOiBudW1iZXIgfSdcbiAqICAgKVxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBub3Q8XG4gIGlucHV0LFxuICBjb25zdCBwYXR0ZXJuIGV4dGVuZHMgUGF0dGVybjxpbnB1dD4gfCBVbmtub3duUGF0dGVyblxuPihwYXR0ZXJuOiBwYXR0ZXJuKTogQ2hhaW5hYmxlPE5vdFA8aW5wdXQsIHBhdHRlcm4+PiB7XG4gIHJldHVybiBjaGFpbmFibGUoe1xuICAgIFttYXRjaGVyXTogKCkgPT4gKHtcbiAgICAgIG1hdGNoOiA8VW5rbm93bklucHV0Pih2YWx1ZTogVW5rbm93bklucHV0IHwgaW5wdXQpID0+ICh7XG4gICAgICAgIG1hdGNoZWQ6ICFtYXRjaFBhdHRlcm4ocGF0dGVybiwgdmFsdWUsICgpID0+IHt9KSxcbiAgICAgIH0pLFxuICAgICAgZ2V0U2VsZWN0aW9uS2V5czogKCkgPT4gW10sXG4gICAgICBtYXRjaGVyVHlwZTogJ25vdCcsXG4gICAgfSksXG4gIH0pO1xufVxuXG4vKipcbiAqIGBQLndoZW4oKHZhbHVlKSA9PiBib29sZWFuKWAgcmV0dXJucyBhIHBhdHRlcm4gd2hpY2ggbWF0Y2hlc1xuICogaWYgdGhlIHByZWRpY2F0ZSByZXR1cm5zIHRydWUgZm9yIHRoZSBjdXJyZW50IGlucHV0LlxuICpcbiAqIFtSZWFkIHRoZSBkb2N1bWVudGF0aW9uIGZvciBgUC53aGVuYCBvbiBHaXRIdWJdKGh0dHBzOi8vZ2l0aHViLmNvbS9ndmVyZ25hdWQvdHMtcGF0dGVybiNwd2hlbi1wYXR0ZXJucylcbiAqXG4gKiBAZXhhbXBsZVxuICogIG1hdGNoPHsgYWdlOiBudW1iZXIgfT4odmFsdWUpXG4gKiAgIC53aXRoKHsgYWdlOiBQLndoZW4oYWdlID0+IGFnZSA+IDIxKSB9LCAoeCkgPT4gJ3dpbGwgbWF0Y2ggaWYgdmFsdWUuYWdlID4gMjEnXG4gKiAgIClcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdoZW48aW5wdXQsIHByZWRpY2F0ZSBleHRlbmRzICh2YWx1ZTogaW5wdXQpID0+IHVua25vd24+KFxuICBwcmVkaWNhdGU6IHByZWRpY2F0ZVxuKTogR3VhcmRQPFxuICBpbnB1dCxcbiAgcHJlZGljYXRlIGV4dGVuZHMgKHZhbHVlOiBhbnkpID0+IHZhbHVlIGlzIGluZmVyIG5hcnJvd2VkID8gbmFycm93ZWQgOiBuZXZlclxuPjtcbmV4cG9ydCBmdW5jdGlvbiB3aGVuPGlucHV0LCBuYXJyb3dlZCBleHRlbmRzIGlucHV0LCBleGNsdWRlZD4oXG4gIHByZWRpY2F0ZTogKGlucHV0OiBpbnB1dCkgPT4gaW5wdXQgaXMgbmFycm93ZWRcbik6IEd1YXJkRXhjbHVkZVA8aW5wdXQsIG5hcnJvd2VkLCBleGNsdWRlZD47XG5leHBvcnQgZnVuY3Rpb24gd2hlbjxpbnB1dCwgcHJlZGljYXRlIGV4dGVuZHMgKHZhbHVlOiBpbnB1dCkgPT4gdW5rbm93bj4oXG4gIHByZWRpY2F0ZTogcHJlZGljYXRlXG4pOiBHdWFyZFA8XG4gIGlucHV0LFxuICBwcmVkaWNhdGUgZXh0ZW5kcyAodmFsdWU6IGFueSkgPT4gdmFsdWUgaXMgaW5mZXIgbmFycm93ZWQgPyBuYXJyb3dlZCA6IG5ldmVyXG4+IHtcbiAgcmV0dXJuIHtcbiAgICBbbWF0Y2hlcl06ICgpID0+ICh7XG4gICAgICBtYXRjaDogPFVua25vd25JbnB1dD4odmFsdWU6IFVua25vd25JbnB1dCB8IGlucHV0KSA9PiAoe1xuICAgICAgICBtYXRjaGVkOiBCb29sZWFuKHByZWRpY2F0ZSh2YWx1ZSBhcyBpbnB1dCkpLFxuICAgICAgfSksXG4gICAgfSksXG4gIH07XG59XG5cbi8qKlxuICogYFAuc2VsZWN0KClgIGlzIGEgcGF0dGVybiB3aGljaCB3aWxsIGFsd2F5cyBtYXRjaCxcbiAqIGFuZCB3aWxsIGluamVjdCB0aGUgc2VsZWN0ZWQgcGllY2Ugb2YgaW5wdXQgaW4gdGhlIGhhbmRsZXIgZnVuY3Rpb24uXG4gKlxuICogW1JlYWQgdGhlIGRvY3VtZW50YXRpb24gZm9yIG