tasq/node_modules/onnxruntime-web/dist/ort-web.js

28541 lines
3.7 MiB

/*!
* ONNX Runtime Web v1.14.0
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory(require("onnxruntime-common"));
else if(typeof define === 'function' && define.amd)
define([], factory);
else {
var a = typeof exports === 'object' ? factory(require("onnxruntime-common")) : factory(root["ort"]);
for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
}
})(self, (__WEBPACK_EXTERNAL_MODULE_onnxruntime_common__) => {
return /******/ (() => { // webpackBootstrap
/******/ var __webpack_modules__ = ({
/***/ "./lib/wasm/binding/ort-wasm-threaded.js":
/*!***********************************************!*\
!*** ./lib/wasm/binding/ort-wasm-threaded.js ***!
\***********************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
var __filename = "/index.js";
var __dirname = "/";
var ortWasmThreaded = (() => {
var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined;
if (true) _scriptDir = _scriptDir || __filename;
return (
function(ortWasmThreaded) {
ortWasmThreaded = ortWasmThreaded || {};
function d(){m.buffer!=n&&p(m.buffer);return aa}function q(){m.buffer!=n&&p(m.buffer);return ba}function r(){m.buffer!=n&&p(m.buffer);return ca}function v(){m.buffer!=n&&p(m.buffer);return da}function ea(){m.buffer!=n&&p(m.buffer);return fa}var x;x||(x=typeof ortWasmThreaded !== 'undefined' ? ortWasmThreaded : {});var ha,ia;x.ready=new Promise(function(a,b){ha=a;ia=b});
var ja=Object.assign({},x),ka="./this.program",la=(a,b)=>{throw b;},ma="object"==typeof window,y="function"==typeof importScripts,B="object"==typeof process&&"object"==typeof process.versions&&"string"==typeof process.versions.node,C=x.ENVIRONMENT_IS_PTHREAD||!1,D="";function na(a){return x.locateFile?x.locateFile(a,D):D+a}var oa,pa,qa,fs,ra,sa;
if(B){D=y?(__webpack_require__(/*! path */ "?75c6").dirname)(D)+"/":__dirname+"/";sa=()=>{ra||(fs=__webpack_require__(/*! fs */ "?63c8"),ra=__webpack_require__(/*! path */ "?75c6"))};oa=function(b,c){sa();b=ra.normalize(b);return fs.readFileSync(b,c?void 0:"utf8")};qa=b=>{b=oa(b,!0);b.buffer||(b=new Uint8Array(b));return b};pa=(b,c,e)=>{sa();b=ra.normalize(b);fs.readFile(b,function(f,h){f?e(f):c(h.buffer)})};1<process.argv.length&&(ka=process.argv[1].replace(/\\/g,"/"));process.argv.slice(2);process.on("uncaughtException",function(b){if(!(b instanceof E))throw b;});process.on("unhandledRejection",
function(b){throw b;});la=(b,c)=>{if(F())throw process.exitCode=b,c;c instanceof E||G("exiting due to exception: "+c);process.exit(b)};x.inspect=function(){return"[Emscripten Module object]"};let a;try{a=__webpack_require__(/*! worker_threads */ "?c6f7")}catch(b){throw console.error('The "worker_threads" module is not supported in this node.js build - perhaps a newer version is needed?'),b;}__webpack_require__.g.Worker=a.Worker}else if(ma||y)y?D=self.location.href:"undefined"!=typeof document&&document.currentScript&&(D=document.currentScript.src),
_scriptDir&&(D=_scriptDir),0!==D.indexOf("blob:")?D=D.substr(0,D.replace(/[?#].*/,"").lastIndexOf("/")+1):D="",B||(oa=a=>{var b=new XMLHttpRequest;b.open("GET",a,!1);b.send(null);return b.responseText},y&&(qa=a=>{var b=new XMLHttpRequest;b.open("GET",a,!1);b.responseType="arraybuffer";b.send(null);return new Uint8Array(b.response)}),pa=(a,b,c)=>{var e=new XMLHttpRequest;e.open("GET",a,!0);e.responseType="arraybuffer";e.onload=()=>{200==e.status||0==e.status&&e.response?b(e.response):c()};e.onerror=
c;e.send(null)});B&&"undefined"==typeof performance&&(__webpack_require__.g.performance=(__webpack_require__(/*! perf_hooks */ "?674f").performance));var ta=console.log.bind(console),ua=console.warn.bind(console);B&&(sa(),ta=a=>fs.writeSync(1,a+"\n"),ua=a=>fs.writeSync(2,a+"\n"));var va=x.print||ta,G=x.printErr||ua;Object.assign(x,ja);ja=null;x.thisProgram&&(ka=x.thisProgram);x.quit&&(la=x.quit);var H;x.wasmBinary&&(H=x.wasmBinary);var noExitRuntime=x.noExitRuntime||!1;"object"!=typeof WebAssembly&&I("no native wasm support detected");
var m,wa,xa=!1,ya="undefined"!=typeof TextDecoder?new TextDecoder("utf8"):void 0;
function za(a,b,c){b>>>=0;var e=b+c;for(c=b;a[c]&&!(c>=e);)++c;if(16<c-b&&a.buffer&&ya)return ya.decode(a.buffer instanceof SharedArrayBuffer?a.slice(b,c):a.subarray(b,c));for(e="";b<c;){var f=a[b++];if(f&128){var h=a[b++]&63;if(192==(f&224))e+=String.fromCharCode((f&31)<<6|h);else{var k=a[b++]&63;f=224==(f&240)?(f&15)<<12|h<<6|k:(f&7)<<18|h<<12|k<<6|a[b++]&63;65536>f?e+=String.fromCharCode(f):(f-=65536,e+=String.fromCharCode(55296|f>>10,56320|f&1023))}}else e+=String.fromCharCode(f)}return e}
function Aa(a,b){return(a>>>=0)?za(q(),a,b):""}
function Ba(a,b,c,e){c>>>=0;if(!(0<e))return 0;var f=c;e=c+e-1;for(var h=0;h<a.length;++h){var k=a.charCodeAt(h);if(55296<=k&&57343>=k){var l=a.charCodeAt(++h);k=65536+((k&1023)<<10)|l&1023}if(127>=k){if(c>=e)break;b[c++>>>0]=k}else{if(2047>=k){if(c+1>=e)break;b[c++>>>0]=192|k>>6}else{if(65535>=k){if(c+2>=e)break;b[c++>>>0]=224|k>>12}else{if(c+3>=e)break;b[c++>>>0]=240|k>>18;b[c++>>>0]=128|k>>12&63}b[c++>>>0]=128|k>>6&63}b[c++>>>0]=128|k&63}}b[c>>>0]=0;return c-f}
function Ca(a){for(var b=0,c=0;c<a.length;++c){var e=a.charCodeAt(c);127>=e?b++:2047>=e?b+=2:55296<=e&&57343>=e?(b+=4,++c):b+=3}return b}var n,aa,ba,ca,da,fa;C&&(n=x.buffer);function p(a){n=a;x.HEAP8=aa=new Int8Array(a);x.HEAP16=new Int16Array(a);x.HEAP32=ca=new Int32Array(a);x.HEAPU8=ba=new Uint8Array(a);x.HEAPU16=new Uint16Array(a);x.HEAPU32=da=new Uint32Array(a);x.HEAPF32=new Float32Array(a);x.HEAPF64=fa=new Float64Array(a)}var Da=x.INITIAL_MEMORY||16777216;
if(C)m=x.wasmMemory,n=x.buffer;else if(x.wasmMemory)m=x.wasmMemory;else if(m=new WebAssembly.Memory({initial:Da/65536,maximum:65536,shared:!0}),!(m.buffer instanceof SharedArrayBuffer))throw G("requested a shared WebAssembly.Memory but the returned buffer is not a SharedArrayBuffer, indicating that while the browser has SharedArrayBuffer it does not have WebAssembly threads support - you may need to set a flag"),B&&console.log("(on node you may need: --experimental-wasm-threads --experimental-wasm-bulk-memory and also use a recent version)"),
Error("bad memory");m&&(n=m.buffer);Da=n.byteLength;p(n);var Ea,Fa=[],Ga=[],Ha=[],Ia=[],Ja=0;function F(){return noExitRuntime||0<Ja}function Ka(){var a=x.preRun.shift();Fa.unshift(a)}var L=0,La=null,M=null;function I(a){if(C)postMessage({cmd:"onAbort",arg:a});else if(x.onAbort)x.onAbort(a);a="Aborted("+a+")";G(a);xa=!0;a=new WebAssembly.RuntimeError(a+". Build with -sASSERTIONS for more info.");ia(a);throw a;}function Ma(){return O.startsWith("data:application/octet-stream;base64,")}var O;O="ort-wasm-threaded.wasm";
Ma()||(O=na(O));function Na(){var a=O;try{if(a==O&&H)return new Uint8Array(H);if(qa)return qa(a);throw"both async and sync fetching of the wasm failed";}catch(b){I(b)}}
function Oa(){if(!H&&(ma||y)){if("function"==typeof fetch&&!O.startsWith("file://"))return fetch(O,{credentials:"same-origin"}).then(function(a){if(!a.ok)throw"failed to load wasm binary file at '"+O+"'";return a.arrayBuffer()}).catch(function(){return Na()});if(pa)return new Promise(function(a,b){pa(O,function(c){a(new Uint8Array(c))},b)})}return Promise.resolve().then(function(){return Na()})}var Pa={};
function E(a){this.name="ExitStatus";this.message="Program terminated with exit("+a+")";this.status=a}function Qa(a){(a=P.Vb[a])||I();P.mc(a)}function Ra(a){var b=P.Cc();if(!b)return 6;P.ac.push(b);P.Vb[a.Ub]=b;b.Ub=a.Ub;var c={cmd:"run",start_routine:a.Ic,arg:a.zc,pthread_ptr:a.Ub};b.$b=()=>{c.time=performance.now();b.postMessage(c,a.Nc)};b.loaded&&(b.$b(),delete b.$b);return 0}function Sa(a){if(C)return Q(1,1,a);if(!F()){P.oc();if(x.onExit)x.onExit(a);xa=!0}la(a,new E(a))}
function Ta(a,b){if(!b&&C)throw Ua(a),"unwind";F()||C||(Va(),R(Ha),Wa(0),Xa[1].length&&Ya(1,10),Xa[2].length&&Ya(2,10),P.oc());Sa(a)}
var P={Yb:[],ac:[],qc:[],Vb:{},fc:function(){C&&P.Ec()},Pc:function(){},Ec:function(){P.receiveObjectTransfer=P.Gc;P.threadInitTLS=P.pc;P.setExitStatus=P.nc;noExitRuntime=!1},nc:function(){},oc:function(){for(var a of Object.values(P.Vb))P.mc(a);for(a of P.Yb)a.terminate();P.Yb=[]},mc:function(a){var b=a.Ub;delete P.Vb[b];P.Yb.push(a);P.ac.splice(P.ac.indexOf(a),1);a.Ub=0;Za(b)},Gc:function(){},pc:function(){P.qc.forEach(a=>a())},Fc:function(a,b){a.onmessage=c=>{c=c.data;var e=c.cmd;a.Ub&&(P.Bc=a.Ub);
if(c.targetThread&&c.targetThread!=$a()){var f=P.Vb[c.Qc];f?f.postMessage(c,c.transferList):G('Internal error! Worker sent a message "'+e+'" to target pthread '+c.targetThread+", but that thread no longer exists!")}else if("processProxyingQueue"===e)ab(c.queue);else if("spawnThread"===e)Ra(c);else if("cleanupThread"===e)Qa(c.thread);else if("killThread"===e)c=c.thread,e=P.Vb[c],delete P.Vb[c],e.terminate(),Za(c),P.ac.splice(P.ac.indexOf(e),1),e.Ub=0;else if("cancelThread"===e)P.Vb[c.thread].postMessage({cmd:"cancel"});
else if("loaded"===e)a.loaded=!0,b&&b(a),a.$b&&(a.$b(),delete a.$b);else if("print"===e)va("Thread "+c.threadId+": "+c.text);else if("printErr"===e)G("Thread "+c.threadId+": "+c.text);else if("alert"===e)alert("Thread "+c.threadId+": "+c.text);else if("setimmediate"===c.target)a.postMessage(c);else if("onAbort"===e){if(x.onAbort)x.onAbort(c.arg)}else e&&G("worker sent an unknown command "+e);P.Bc=void 0};a.onerror=c=>{G("worker sent an error! "+c.filename+":"+c.lineno+": "+c.message);throw c;};B&&
(a.on("message",function(c){a.onmessage({data:c})}),a.on("error",function(c){a.onerror(c)}),a.on("detachedExit",function(){}));a.postMessage({cmd:"load",urlOrBlob:x.mainScriptUrlOrBlob||_scriptDir,wasmMemory:m,wasmModule:wa})},yc:function(){var a=na("ort-wasm-threaded.worker.js");P.Yb.push(new Worker(a))},Cc:function(){0==P.Yb.length&&(P.yc(),P.Fc(P.Yb[0]));return P.Yb.pop()}};x.PThread=P;function R(a){for(;0<a.length;)a.shift()(x)}function bb(a){var b=S();a=a();U(b);return a}
x.establishStackSpace=function(){var a=$a(),b=r()[a+44>>2>>>0];a=r()[a+48>>2>>>0];cb(b,b-a);U(b)};function Ua(a){if(C)return Q(2,0,a);try{Ta(a)}catch(b){b instanceof E||"unwind"==b||la(1,b)}}var db=[];function V(a){var b=db[a];b||(a>=db.length&&(db.length=a+1),db[a]=b=Ea.get(a));return b}x.invokeEntryPoint=function(a,b){a=V(a)(b);F()?P.nc(a):eb(a)};function fb(a,b){d().set(a,b>>>0)}var gb=[],hb=0,W=0;
function X(a){this.Zb=a;this.Sb=a-24;this.xc=function(b){v()[this.Sb+4>>2>>>0]=b};this.bc=function(){return v()[this.Sb+4>>2>>>0]};this.wc=function(b){v()[this.Sb+8>>2>>>0]=b};this.Dc=function(){return v()[this.Sb+8>>2>>>0]};this.rc=function(){r()[this.Sb>>2>>>0]=0};this.hc=function(b){b=b?1:0;d()[this.Sb+12>>0>>>0]=b};this.uc=function(){return 0!=d()[this.Sb+12>>0>>>0]};this.ic=function(b){b=b?1:0;d()[this.Sb+13>>0>>>0]=b};this.kc=function(){return 0!=d()[this.Sb+13>>0>>>0]};this.fc=function(b,c){this.cc(0);
this.xc(b);this.wc(c);this.rc();this.hc(!1);this.ic(!1)};this.sc=function(){Atomics.add(r(),this.Sb>>2,1)};this.Hc=function(){return 1===Atomics.sub(r(),this.Sb>>2,1)};this.cc=function(b){v()[this.Sb+16>>2>>>0]=b};this.tc=function(){return v()[this.Sb+16>>2>>>0]};this.vc=function(){if(ib(this.bc()))return v()[this.Zb>>2>>>0];var b=this.tc();return 0!==b?b:this.Zb}}function jb(a){return kb((new X(a)).Sb)}function lb(a,b,c,e){return C?Q(3,1,a,b,c,e):mb(a,b,c,e)}
function mb(a,b,c,e){if("undefined"==typeof SharedArrayBuffer)return G("Current environment does not support SharedArrayBuffer, pthreads are not available!"),6;var f=[];if(C&&0===f.length)return lb(a,b,c,e);a={Ic:c,Ub:a,zc:e,Nc:f};return C?(a.Oc="spawnThread",postMessage(a,f),0):Ra(a)}function nb(a,b,c){return C?Q(4,1,a,b,c):0}function ob(a,b){if(C)return Q(5,1,a,b)}function pb(a,b){if(C)return Q(6,1,a,b)}function qb(a,b,c){if(C)return Q(7,1,a,b,c)}function rb(a,b,c){return C?Q(8,1,a,b,c):0}
function sb(a,b){if(C)return Q(9,1,a,b)}function tb(a,b,c){if(C)return Q(10,1,a,b,c)}function ub(a,b,c,e){if(C)return Q(11,1,a,b,c,e)}function vb(a,b,c,e){if(C)return Q(12,1,a,b,c,e)}function wb(a,b,c,e){if(C)return Q(13,1,a,b,c,e)}function xb(a){if(C)return Q(14,1,a)}function yb(a,b){if(C)return Q(15,1,a,b)}function zb(a,b,c){if(C)return Q(16,1,a,b,c)}function ab(a){Atomics.store(r(),a>>2,1);$a()&&Ab(a);Atomics.compareExchange(r(),a>>2,1,0)}x.executeNotifiedProxyingQueue=ab;
function Bb(a){return v()[a>>>2]+4294967296*r()[a+4>>>2]}function Cb(a,b,c,e,f,h){return C?Q(17,1,a,b,c,e,f,h):-52}function Db(a,b,c,e,f,h){if(C)return Q(18,1,a,b,c,e,f,h)}function Eb(a){var b=Ca(a)+1,c=Fb(b);c&&Ba(a,d(),c,b);return c}
function Gb(a,b,c){function e(t){return(t=t.toTimeString().match(/\(([A-Za-z ]+)\)$/))?t[1]:"GMT"}if(C)return Q(19,1,a,b,c);var f=(new Date).getFullYear(),h=new Date(f,0,1),k=new Date(f,6,1);f=h.getTimezoneOffset();var l=k.getTimezoneOffset(),u=Math.max(f,l);r()[a>>2>>>0]=60*u;r()[b>>2>>>0]=Number(f!=l);a=e(h);b=e(k);a=Eb(a);b=Eb(b);l<f?(v()[c>>2>>>0]=a,v()[c+4>>2>>>0]=b):(v()[c>>2>>>0]=b,v()[c+4>>2>>>0]=a)}function Hb(a,b,c){Hb.Ac||(Hb.Ac=!0,Gb(a,b,c))}var Ib,Jb;
Jb=B?()=>{var a=process.hrtime();return 1E3*a[0]+a[1]/1E6}:C?()=>performance.now()-x.__performance_now_clock_drift:()=>performance.now();function Q(a,b){var c=arguments.length-2,e=arguments;return bb(()=>{for(var f=Kb(8*c),h=f>>3,k=0;k<c;k++){var l=e[2+k];ea()[h+k>>>0]=l}return Lb(a,c,f,b)})}var Mb=[],Nb={};
function Ob(){if(!Pb){var a={USER:"web_user",LOGNAME:"web_user",PATH:"/",PWD:"/",HOME:"/home/web_user",LANG:("object"==typeof navigator&&navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8",_:ka||"./this.program"},b;for(b in Nb)void 0===Nb[b]?delete a[b]:a[b]=Nb[b];var c=[];for(b in a)c.push(b+"="+a[b]);Pb=c}return Pb}var Pb;
function Qb(a,b){if(C)return Q(20,1,a,b);var c=0;Ob().forEach(function(e,f){var h=b+c;f=v()[a+4*f>>2>>>0]=h;for(h=0;h<e.length;++h)d()[f++>>0>>>0]=e.charCodeAt(h);d()[f>>0>>>0]=0;c+=e.length+1});return 0}function Rb(a,b){if(C)return Q(21,1,a,b);var c=Ob();v()[a>>2>>>0]=c.length;var e=0;c.forEach(function(f){e+=f.length+1});v()[b>>2>>>0]=e;return 0}function Sb(a){return C?Q(22,1,a):52}function Tb(a,b,c,e){return C?Q(23,1,a,b,c,e):52}function Ub(a,b,c,e,f){return C?Q(24,1,a,b,c,e,f):70}
var Xa=[null,[],[]];function Ya(a,b){var c=Xa[a];0===b||10===b?((1===a?va:G)(za(c,0)),c.length=0):c.push(b)}function Vb(a,b,c,e){if(C)return Q(25,1,a,b,c,e);for(var f=0,h=0;h<c;h++){var k=v()[b>>2>>>0],l=v()[b+4>>2>>>0];b+=8;for(var u=0;u<l;u++)Ya(a,q()[k+u>>>0]);f+=l}v()[e>>2>>>0]=f;return 0}var Y=0;
function Wb(){if("object"==typeof crypto&&"function"==typeof crypto.getRandomValues){var a=new Uint8Array(1);return()=>{crypto.getRandomValues(a);return a[0]}}if(B)try{var b=__webpack_require__(Object(function webpackMissingModule() { var e = new Error("Cannot find module 'crypto'"); e.code = 'MODULE_NOT_FOUND'; throw e; }()));return()=>b.randomBytes(1)[0]}catch(c){}return()=>I("randomDevice")}function Xb(a,b){Xb.lc||(Xb.lc=Wb());for(var c=0;c<b;c++)d()[a+c>>0>>>0]=Xb.lc();return 0}function Yb(a){return 0===a%4&&(0!==a%100||0===a%400)}var Zb=[31,29,31,30,31,30,31,31,30,31,30,31],$b=[31,28,31,30,31,30,31,31,30,31,30,31];
function ac(a){var b=Array(Ca(a)+1);Ba(a,b,0,b.length);return b}
function bc(a,b,c,e){function f(g,w,z){for(g="number"==typeof g?g.toString():g||"";g.length<w;)g=z[0]+g;return g}function h(g,w){return f(g,w,"0")}function k(g,w){function z(T){return 0>T?-1:0<T?1:0}var N;0===(N=z(g.getFullYear()-w.getFullYear()))&&0===(N=z(g.getMonth()-w.getMonth()))&&(N=z(g.getDate()-w.getDate()));return N}function l(g){switch(g.getDay()){case 0:return new Date(g.getFullYear()-1,11,29);case 1:return g;case 2:return new Date(g.getFullYear(),0,3);case 3:return new Date(g.getFullYear(),
0,2);case 4:return new Date(g.getFullYear(),0,1);case 5:return new Date(g.getFullYear()-1,11,31);case 6:return new Date(g.getFullYear()-1,11,30)}}function u(g){var w=g.Wb;for(g=new Date((new Date(g.Xb+1900,0,1)).getTime());0<w;){var z=g.getMonth(),N=(Yb(g.getFullYear())?Zb:$b)[z];if(w>N-g.getDate())w-=N-g.getDate()+1,g.setDate(1),11>z?g.setMonth(z+1):(g.setMonth(0),g.setFullYear(g.getFullYear()+1));else{g.setDate(g.getDate()+w);break}}z=new Date(g.getFullYear()+1,0,4);w=l(new Date(g.getFullYear(),
0,4));z=l(z);return 0>=k(w,g)?0>=k(z,g)?g.getFullYear()+1:g.getFullYear():g.getFullYear()-1}var t=r()[e+40>>2>>>0];e={Lc:r()[e>>2>>>0],Kc:r()[e+4>>2>>>0],dc:r()[e+8>>2>>>0],jc:r()[e+12>>2>>>0],ec:r()[e+16>>2>>>0],Xb:r()[e+20>>2>>>0],Tb:r()[e+24>>2>>>0],Wb:r()[e+28>>2>>>0],Rc:r()[e+32>>2>>>0],Jc:r()[e+36>>2>>>0],Mc:t?Aa(t):""};c=Aa(c);t={"%c":"%a %b %d %H:%M:%S %Y","%D":"%m/%d/%y","%F":"%Y-%m-%d","%h":"%b","%r":"%I:%M:%S %p","%R":"%H:%M","%T":"%H:%M:%S","%x":"%m/%d/%y","%X":"%H:%M:%S","%Ec":"%c","%EC":"%C",
"%Ex":"%m/%d/%y","%EX":"%H:%M:%S","%Ey":"%y","%EY":"%Y","%Od":"%d","%Oe":"%e","%OH":"%H","%OI":"%I","%Om":"%m","%OM":"%M","%OS":"%S","%Ou":"%u","%OU":"%U","%OV":"%V","%Ow":"%w","%OW":"%W","%Oy":"%y"};for(var A in t)c=c.replace(new RegExp(A,"g"),t[A]);var K="Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" "),J="January February March April May June July August September October November December".split(" ");t={"%a":function(g){return K[g.Tb].substring(0,3)},"%A":function(g){return K[g.Tb]},
"%b":function(g){return J[g.ec].substring(0,3)},"%B":function(g){return J[g.ec]},"%C":function(g){return h((g.Xb+1900)/100|0,2)},"%d":function(g){return h(g.jc,2)},"%e":function(g){return f(g.jc,2," ")},"%g":function(g){return u(g).toString().substring(2)},"%G":function(g){return u(g)},"%H":function(g){return h(g.dc,2)},"%I":function(g){g=g.dc;0==g?g=12:12<g&&(g-=12);return h(g,2)},"%j":function(g){for(var w=0,z=0;z<=g.ec-1;w+=(Yb(g.Xb+1900)?Zb:$b)[z++]);return h(g.jc+w,3)},"%m":function(g){return h(g.ec+
1,2)},"%M":function(g){return h(g.Kc,2)},"%n":function(){return"\n"},"%p":function(g){return 0<=g.dc&&12>g.dc?"AM":"PM"},"%S":function(g){return h(g.Lc,2)},"%t":function(){return"\t"},"%u":function(g){return g.Tb||7},"%U":function(g){return h(Math.floor((g.Wb+7-g.Tb)/7),2)},"%V":function(g){var w=Math.floor((g.Wb+7-(g.Tb+6)%7)/7);2>=(g.Tb+371-g.Wb-2)%7&&w++;if(w)53==w&&(z=(g.Tb+371-g.Wb)%7,4==z||3==z&&Yb(g.Xb)||(w=1));else{w=52;var z=(g.Tb+7-g.Wb-1)%7;(4==z||5==z&&Yb(g.Xb%400-1))&&w++}return h(w,
2)},"%w":function(g){return g.Tb},"%W":function(g){return h(Math.floor((g.Wb+7-(g.Tb+6)%7)/7),2)},"%y":function(g){return(g.Xb+1900).toString().substring(2)},"%Y":function(g){return g.Xb+1900},"%z":function(g){g=g.Jc;var w=0<=g;g=Math.abs(g)/60;return(w?"+":"-")+String("0000"+(g/60*100+g%60)).slice(-4)},"%Z":function(g){return g.Mc},"%%":function(){return"%"}};c=c.replace(/%%/g,"\x00\x00");for(A in t)c.includes(A)&&(c=c.replace(new RegExp(A,"g"),t[A](e)));c=c.replace(/\0\0/g,"%");A=ac(c);if(A.length>
b)return 0;fb(A,a);return A.length-1}P.fc();
var cc=[null,Sa,Ua,lb,nb,ob,pb,qb,rb,sb,tb,ub,vb,wb,xb,yb,zb,Cb,Db,Gb,Qb,Rb,Sb,Tb,Ub,Vb],Pc={b:function(a){return Fb(a+24)+24},n:function(a){a=new X(a);a.uc()||(a.hc(!0),hb--);a.ic(!1);gb.push(a);a.sc();return a.vc()},ma:function(a){G("Unexpected exception thrown, this is not properly supported - aborting");xa=!0;throw a;},x:function(){Z(0);var a=gb.pop();if(a.Hc()&&!a.kc()){var b=a.Dc();b&&V(b)(a.Zb);jb(a.Zb)}W=0},e:function(){var a=W;if(!a)return Y=0;var b=new X(a);b.cc(a);var c=b.bc();if(!c)return Y=
0,a;for(var e=Array.prototype.slice.call(arguments),f=0;f<e.length;f++){var h=e[f];if(0===h||h===c)break;if(dc(h,c,b.Sb+16))return Y=h,a}Y=c;return a},l:function(){var a=W;if(!a)return Y=0;var b=new X(a);b.cc(a);var c=b.bc();if(!c)return Y=0,a;for(var e=Array.prototype.slice.call(arguments),f=0;f<e.length;f++){var h=e[f];if(0===h||h===c)break;if(dc(h,c,b.Sb+16))return Y=h,a}Y=c;return a},h:function(){var a=W;if(!a)return Y=0;var b=new X(a);b.cc(a);var c=b.bc();if(!c)return Y=0,a;for(var e=Array.prototype.slice.call(arguments),
f=0;f<e.length;f++){var h=e[f];if(0===h||h===c)break;if(dc(h,c,b.Sb+16))return Y=h,a}Y=c;return a},t:jb,M:function(){var a=gb.pop();a||I("no exception to throw");var b=a.Zb;a.kc()||(gb.push(a),a.ic(!0),a.hc(!1),hb++);W=b;throw b;},c:function(a,b,c){(new X(a)).fc(b,c);W=a;hb++;throw a;},pa:function(){return hb},Fa:function(a){ec(a,!y,1,!ma);P.pc()},T:function(a){C?postMessage({cmd:"cleanupThread",thread:a}):Qa(a)},xa:mb,j:function(a){W||(W=a);throw a;},H:nb,Ma:ob,ua:pb,wa:qb,oa:rb,Ka:sb,Ca:tb,Ja:ub,
V:vb,va:wb,sa:xb,La:yb,ta:zb,Ta:function(){},X:function(){I("To use dlopen, you need enable dynamic linking, see https://github.com/emscripten-core/emscripten/wiki/Linking")},Ua:function(){I("To use dlopen, you need enable dynamic linking, see https://github.com/emscripten-core/emscripten/wiki/Linking")},W:function(){return Date.now()},ya:function(){return 2097152},Oa:function(){return!0},za:function(a,b,c,e){if(a==b)setTimeout(()=>ab(e));else if(C)postMessage({targetThread:a,cmd:"processProxyingQueue",
queue:e});else{a=P.Vb[a];if(!a)return;a.postMessage({cmd:"processProxyingQueue",queue:e})}return 1},Ea:function(){return-1},Pa:function(a,b){a=new Date(1E3*Bb(a));r()[b>>2>>>0]=a.getUTCSeconds();r()[b+4>>2>>>0]=a.getUTCMinutes();r()[b+8>>2>>>0]=a.getUTCHours();r()[b+12>>2>>>0]=a.getUTCDate();r()[b+16>>2>>>0]=a.getUTCMonth();r()[b+20>>2>>>0]=a.getUTCFullYear()-1900;r()[b+24>>2>>>0]=a.getUTCDay();a=(a.getTime()-Date.UTC(a.getUTCFullYear(),0,1,0,0,0,0))/864E5|0;r()[b+28>>2>>>0]=a},Qa:function(a,b){a=
new Date(1E3*Bb(a));r()[b>>2>>>0]=a.getSeconds();r()[b+4>>2>>>0]=a.getMinutes();r()[b+8>>2>>>0]=a.getHours();r()[b+12>>2>>>0]=a.getDate();r()[b+16>>2>>>0]=a.getMonth();r()[b+20>>2>>>0]=a.getFullYear()-1900;r()[b+24>>2>>>0]=a.getDay();var c=new Date(a.getFullYear(),0,1),e=(a.getTime()-c.getTime())/864E5|0;r()[b+28>>2>>>0]=e;r()[b+36>>2>>>0]=-(60*a.getTimezoneOffset());e=(new Date(a.getFullYear(),6,1)).getTimezoneOffset();c=c.getTimezoneOffset();a=(e!=c&&a.getTimezoneOffset()==Math.min(c,e))|0;r()[b+
32>>2>>>0]=a},Ra:function(a){var b=new Date(r()[a+20>>2>>>0]+1900,r()[a+16>>2>>>0],r()[a+12>>2>>>0],r()[a+8>>2>>>0],r()[a+4>>2>>>0],r()[a>>2>>>0],0),c=r()[a+32>>2>>>0],e=b.getTimezoneOffset(),f=new Date(b.getFullYear(),0,1),h=(new Date(b.getFullYear(),6,1)).getTimezoneOffset(),k=f.getTimezoneOffset(),l=Math.min(k,h);0>c?r()[a+32>>2>>>0]=Number(h!=k&&l==e):0<c!=(l==e)&&(h=Math.max(k,h),b.setTime(b.getTime()+6E4*((0<c?l:h)-e)));r()[a+24>>2>>>0]=b.getDay();c=(b.getTime()-f.getTime())/864E5|0;r()[a+28>>
2>>>0]=c;r()[a>>2>>>0]=b.getSeconds();r()[a+4>>2>>>0]=b.getMinutes();r()[a+8>>2>>>0]=b.getHours();r()[a+12>>2>>>0]=b.getDate();r()[a+16>>2>>>0]=b.getMonth();return b.getTime()/1E3|0},Aa:Cb,Ba:Db,Sa:Hb,y:function(){I("")},U:function(){if(!B&&!y){var a="Blocking on the main thread is very dangerous, see https://emscripten.org/docs/porting/pthreads.html#blocking-on-the-main-browser-thread";Ib||(Ib={});Ib[a]||(Ib[a]=1,B&&(a="warning: "+a),G(a))}},ra:function(){return 4294901760},B:Jb,Ia:function(a,b,
c){q().copyWithin(a>>>0,b>>>0,b+c>>>0)},F:function(){return B?(__webpack_require__(/*! os */ "?aedb").cpus)().length:navigator.hardwareConcurrency},Da:function(a,b,c){Mb.length=b;c>>=3;for(var e=0;e<b;e++)Mb[e]=ea()[c+e>>>0];return(0>a?Pa[-a-1]:cc[a]).apply(null,Mb)},qa:function(a){var b=q().length;a>>>=0;if(a<=b||4294901760<a)return!1;for(var c=1;4>=c;c*=2){var e=b*(1+.2/c);e=Math.min(e,a+100663296);var f=Math;e=Math.max(a,e);f=f.min.call(f,4294901760,e+(65536-e%65536)%65536);a:{try{m.grow(f-n.byteLength+65535>>>16);p(m.buffer);
var h=1;break a}catch(k){}h=void 0}if(h)return!0}return!1},Na:function(){throw"unwind";},Ga:Qb,Ha:Rb,J:Ta,I:Sb,S:Tb,ga:Ub,R:Vb,d:function(){return Y},na:Xb,ia:fc,ja:gc,K:hc,f:ic,P:jc,Q:kc,k:lc,p:mc,q:nc,N:oc,s:pc,w:qc,L:rc,E:sc,aa:tc,_:uc,Z:vc,ca:wc,$:xc,ba:yc,Y:zc,g:Ac,r:Bc,i:Cc,ha:Dc,m:Ec,v:Fc,u:Gc,O:Hc,A:Ic,ka:Jc,C:Kc,D:Lc,fa:Mc,da:Nc,ea:Oc,o:function(a){return a},a:m||x.wasmMemory,G:function(a){Y=a},la:bc,z:function(a,b,c,e){return bc(a,b,c,e)}};
(function(){function a(f,h){x.asm=f.exports;P.qc.push(x.asm.sb);Ea=x.asm.ub;Ga.unshift(x.asm.Va);wa=h;C||(L--,x.monitorRunDependencies&&x.monitorRunDependencies(L),0==L&&(null!==La&&(clearInterval(La),La=null),M&&(f=M,M=null,f())))}function b(f){a(f.instance,f.module)}function c(f){return Oa().then(function(h){return WebAssembly.instantiate(h,e)}).then(function(h){return h}).then(f,function(h){G("failed to asynchronously prepare wasm: "+h);I(h)})}var e={a:Pc};C||(L++,x.monitorRunDependencies&&x.monitorRunDependencies(L));
if(x.instantiateWasm)try{return x.instantiateWasm(e,a)}catch(f){return G("Module.instantiateWasm callback failed with error: "+f),!1}(function(){return H||"function"!=typeof WebAssembly.instantiateStreaming||Ma()||O.startsWith("file://")||B||"function"!=typeof fetch?c(b):fetch(O,{credentials:"same-origin"}).then(function(f){return WebAssembly.instantiateStreaming(f,e).then(b,function(h){G("wasm streaming compile failed: "+h);G("falling back to ArrayBuffer instantiation");return c(b)})})})().catch(ia);
return{}})();x.___wasm_call_ctors=function(){return(x.___wasm_call_ctors=x.asm.Va).apply(null,arguments)};x._OrtInit=function(){return(x._OrtInit=x.asm.Wa).apply(null,arguments)};x._OrtCreateSessionOptions=function(){return(x._OrtCreateSessionOptions=x.asm.Xa).apply(null,arguments)};x._OrtAppendExecutionProvider=function(){return(x._OrtAppendExecutionProvider=x.asm.Ya).apply(null,arguments)};x._OrtAddSessionConfigEntry=function(){return(x._OrtAddSessionConfigEntry=x.asm.Za).apply(null,arguments)};
x._OrtReleaseSessionOptions=function(){return(x._OrtReleaseSessionOptions=x.asm._a).apply(null,arguments)};x._OrtCreateSession=function(){return(x._OrtCreateSession=x.asm.$a).apply(null,arguments)};x._OrtReleaseSession=function(){return(x._OrtReleaseSession=x.asm.ab).apply(null,arguments)};x._OrtGetInputCount=function(){return(x._OrtGetInputCount=x.asm.bb).apply(null,arguments)};x._OrtGetOutputCount=function(){return(x._OrtGetOutputCount=x.asm.cb).apply(null,arguments)};
x._OrtGetInputName=function(){return(x._OrtGetInputName=x.asm.db).apply(null,arguments)};x._OrtGetOutputName=function(){return(x._OrtGetOutputName=x.asm.eb).apply(null,arguments)};x._OrtFree=function(){return(x._OrtFree=x.asm.fb).apply(null,arguments)};x._OrtCreateTensor=function(){return(x._OrtCreateTensor=x.asm.gb).apply(null,arguments)};x._OrtGetTensorData=function(){return(x._OrtGetTensorData=x.asm.hb).apply(null,arguments)};
x._OrtReleaseTensor=function(){return(x._OrtReleaseTensor=x.asm.ib).apply(null,arguments)};x._OrtCreateRunOptions=function(){return(x._OrtCreateRunOptions=x.asm.jb).apply(null,arguments)};x._OrtAddRunConfigEntry=function(){return(x._OrtAddRunConfigEntry=x.asm.kb).apply(null,arguments)};x._OrtReleaseRunOptions=function(){return(x._OrtReleaseRunOptions=x.asm.lb).apply(null,arguments)};x._OrtRun=function(){return(x._OrtRun=x.asm.mb).apply(null,arguments)};
x._OrtEndProfiling=function(){return(x._OrtEndProfiling=x.asm.nb).apply(null,arguments)};var $a=x._pthread_self=function(){return($a=x._pthread_self=x.asm.ob).apply(null,arguments)},Fb=x._malloc=function(){return(Fb=x._malloc=x.asm.pb).apply(null,arguments)},kb=x._free=function(){return(kb=x._free=x.asm.qb).apply(null,arguments)},Wa=x._fflush=function(){return(Wa=x._fflush=x.asm.rb).apply(null,arguments)};x.__emscripten_tls_init=function(){return(x.__emscripten_tls_init=x.asm.sb).apply(null,arguments)};
var Va=x.___funcs_on_exit=function(){return(Va=x.___funcs_on_exit=x.asm.tb).apply(null,arguments)},ec=x.__emscripten_thread_init=function(){return(ec=x.__emscripten_thread_init=x.asm.vb).apply(null,arguments)};x.__emscripten_thread_crashed=function(){return(x.__emscripten_thread_crashed=x.asm.wb).apply(null,arguments)};
var Lb=x._emscripten_run_in_main_runtime_thread_js=function(){return(Lb=x._emscripten_run_in_main_runtime_thread_js=x.asm.xb).apply(null,arguments)},Ab=x.__emscripten_proxy_execute_task_queue=function(){return(Ab=x.__emscripten_proxy_execute_task_queue=x.asm.yb).apply(null,arguments)},Za=x.__emscripten_thread_free_data=function(){return(Za=x.__emscripten_thread_free_data=x.asm.zb).apply(null,arguments)},eb=x.__emscripten_thread_exit=function(){return(eb=x.__emscripten_thread_exit=x.asm.Ab).apply(null,
arguments)},Z=x._setThrew=function(){return(Z=x._setThrew=x.asm.Bb).apply(null,arguments)},cb=x._emscripten_stack_set_limits=function(){return(cb=x._emscripten_stack_set_limits=x.asm.Cb).apply(null,arguments)},S=x.stackSave=function(){return(S=x.stackSave=x.asm.Db).apply(null,arguments)},U=x.stackRestore=function(){return(U=x.stackRestore=x.asm.Eb).apply(null,arguments)},Kb=x.stackAlloc=function(){return(Kb=x.stackAlloc=x.asm.Fb).apply(null,arguments)},dc=x.___cxa_can_catch=function(){return(dc=x.___cxa_can_catch=
x.asm.Gb).apply(null,arguments)},ib=x.___cxa_is_pointer_type=function(){return(ib=x.___cxa_is_pointer_type=x.asm.Hb).apply(null,arguments)},Qc=x.dynCall_j=function(){return(Qc=x.dynCall_j=x.asm.Ib).apply(null,arguments)},Rc=x.dynCall_iiiiij=function(){return(Rc=x.dynCall_iiiiij=x.asm.Jb).apply(null,arguments)},Sc=x.dynCall_jii=function(){return(Sc=x.dynCall_jii=x.asm.Kb).apply(null,arguments)},Tc=x.dynCall_viiiiij=function(){return(Tc=x.dynCall_viiiiij=x.asm.Lb).apply(null,arguments)},Uc=x.dynCall_vjji=
function(){return(Uc=x.dynCall_vjji=x.asm.Mb).apply(null,arguments)},Vc=x.dynCall_viiijjjii=function(){return(Vc=x.dynCall_viiijjjii=x.asm.Nb).apply(null,arguments)},Wc=x.dynCall_iij=function(){return(Wc=x.dynCall_iij=x.asm.Ob).apply(null,arguments)},Xc=x.dynCall_ji=function(){return(Xc=x.dynCall_ji=x.asm.Pb).apply(null,arguments)},Yc=x.dynCall_iiiiiij=function(){return(Yc=x.dynCall_iiiiiij=x.asm.Qb).apply(null,arguments)},Zc=x.dynCall_iiij=function(){return(Zc=x.dynCall_iiij=x.asm.Rb).apply(null,
arguments)};function ic(a,b){var c=S();try{return V(a)(b)}catch(e){U(c);if(e!==e+0)throw e;Z(1,0)}}function Bc(a,b){var c=S();try{V(a)(b)}catch(e){U(c);if(e!==e+0)throw e;Z(1,0)}}function Cc(a,b,c){var e=S();try{V(a)(b,c)}catch(f){U(e);if(f!==f+0)throw f;Z(1,0)}}function lc(a,b,c){var e=S();try{return V(a)(b,c)}catch(f){U(e);if(f!==f+0)throw f;Z(1,0)}}function mc(a,b,c,e){var f=S();try{return V(a)(b,c,e)}catch(h){U(f);if(h!==h+0)throw h;Z(1,0)}}
function qc(a,b,c,e,f,h,k){var l=S();try{return V(a)(b,c,e,f,h,k)}catch(u){U(l);if(u!==u+0)throw u;Z(1,0)}}function Ac(a){var b=S();try{V(a)()}catch(c){U(b);if(c!==c+0)throw c;Z(1,0)}}function pc(a,b,c,e,f,h){var k=S();try{return V(a)(b,c,e,f,h)}catch(l){U(k);if(l!==l+0)throw l;Z(1,0)}}function nc(a,b,c,e,f){var h=S();try{return V(a)(b,c,e,f)}catch(k){U(h);if(k!==k+0)throw k;Z(1,0)}}function Ec(a,b,c,e){var f=S();try{V(a)(b,c,e)}catch(h){U(f);if(h!==h+0)throw h;Z(1,0)}}
function Gc(a,b,c,e,f,h){var k=S();try{V(a)(b,c,e,f,h)}catch(l){U(k);if(l!==l+0)throw l;Z(1,0)}}function Fc(a,b,c,e,f){var h=S();try{V(a)(b,c,e,f)}catch(k){U(h);if(k!==k+0)throw k;Z(1,0)}}function Ic(a,b,c,e,f,h,k,l){var u=S();try{V(a)(b,c,e,f,h,k,l)}catch(t){U(u);if(t!==t+0)throw t;Z(1,0)}}function kc(a,b,c){var e=S();try{return V(a)(b,c)}catch(f){U(e);if(f!==f+0)throw f;Z(1,0)}}function jc(a,b,c){var e=S();try{return V(a)(b,c)}catch(f){U(e);if(f!==f+0)throw f;Z(1,0)}}
function Jc(a,b,c,e,f,h,k,l,u){var t=S();try{V(a)(b,c,e,f,h,k,l,u)}catch(A){U(t);if(A!==A+0)throw A;Z(1,0)}}function Hc(a,b,c,e,f,h,k){var l=S();try{V(a)(b,c,e,f,h,k)}catch(u){U(l);if(u!==u+0)throw u;Z(1,0)}}function oc(a,b,c,e,f,h){var k=S();try{return V(a)(b,c,e,f,h)}catch(l){U(k);if(l!==l+0)throw l;Z(1,0)}}function rc(a,b,c,e,f,h,k,l){var u=S();try{return V(a)(b,c,e,f,h,k,l)}catch(t){U(u);if(t!==t+0)throw t;Z(1,0)}}
function sc(a,b,c,e,f,h,k,l,u,t,A,K){var J=S();try{return V(a)(b,c,e,f,h,k,l,u,t,A,K)}catch(g){U(J);if(g!==g+0)throw g;Z(1,0)}}function Kc(a,b,c,e,f,h,k,l,u,t,A){var K=S();try{V(a)(b,c,e,f,h,k,l,u,t,A)}catch(J){U(K);if(J!==J+0)throw J;Z(1,0)}}function Lc(a,b,c,e,f,h,k,l,u,t,A,K,J,g,w,z){var N=S();try{V(a)(b,c,e,f,h,k,l,u,t,A,K,J,g,w,z)}catch(T){U(N);if(T!==T+0)throw T;Z(1,0)}}function hc(a){var b=S();try{return V(a)()}catch(c){U(b);if(c!==c+0)throw c;Z(1,0)}}
function gc(a,b,c){var e=S();try{return V(a)(b,c)}catch(f){U(e);if(f!==f+0)throw f;Z(1,0)}}function fc(a,b,c){var e=S();try{return V(a)(b,c)}catch(f){U(e);if(f!==f+0)throw f;Z(1,0)}}function Dc(a,b,c,e){var f=S();try{V(a)(b,c,e)}catch(h){U(f);if(h!==h+0)throw h;Z(1,0)}}function Mc(a,b,c,e,f,h,k,l){var u=S();try{Tc(a,b,c,e,f,h,k,l)}catch(t){U(u);if(t!==t+0)throw t;Z(1,0)}}function Oc(a,b,c,e,f,h){var k=S();try{Uc(a,b,c,e,f,h)}catch(l){U(k);if(l!==l+0)throw l;Z(1,0)}}
function Nc(a,b,c,e,f,h,k,l,u,t,A,K){var J=S();try{Vc(a,b,c,e,f,h,k,l,u,t,A,K)}catch(g){U(J);if(g!==g+0)throw g;Z(1,0)}}function wc(a,b,c,e){var f=S();try{return Wc(a,b,c,e)}catch(h){U(f);if(h!==h+0)throw h;Z(1,0)}}function yc(a,b){var c=S();try{return Xc(a,b)}catch(e){U(c);if(e!==e+0)throw e;Z(1,0)}}function tc(a,b,c,e,f,h,k,l){var u=S();try{return Yc(a,b,c,e,f,h,k,l)}catch(t){U(u);if(t!==t+0)throw t;Z(1,0)}}function xc(a){var b=S();try{return Qc(a)}catch(c){U(b);if(c!==c+0)throw c;Z(1,0)}}
function uc(a,b,c,e,f,h,k){var l=S();try{return Rc(a,b,c,e,f,h,k)}catch(u){U(l);if(u!==u+0)throw u;Z(1,0)}}function vc(a,b,c,e,f){var h=S();try{return Zc(a,b,c,e,f)}catch(k){U(h);if(k!==k+0)throw k;Z(1,0)}}function zc(a,b,c){var e=S();try{return Sc(a,b,c)}catch(f){U(e);if(f!==f+0)throw f;Z(1,0)}}x.UTF8ToString=Aa;x.stringToUTF8=function(a,b,c){return Ba(a,q(),b,c)};x.lengthBytesUTF8=Ca;x.keepRuntimeAlive=F;x.wasmMemory=m;x.stackSave=S;x.stackRestore=U;x.stackAlloc=Kb;x.ExitStatus=E;x.PThread=P;var $c;
M=function ad(){$c||bd();$c||(M=ad)};
function bd(){function a(){if(!$c&&($c=!0,x.calledRun=!0,!xa)){C||R(Ga);ha(x);if(x.onRuntimeInitialized)x.onRuntimeInitialized();if(!C){if(x.postRun)for("function"==typeof x.postRun&&(x.postRun=[x.postRun]);x.postRun.length;){var b=x.postRun.shift();Ia.unshift(b)}R(Ia)}}}if(!(0<L))if(C)ha(x),C||R(Ga),postMessage({cmd:"loaded"});else{if(x.preRun)for("function"==typeof x.preRun&&(x.preRun=[x.preRun]);x.preRun.length;)Ka();R(Fa);0<L||(x.setStatus?(x.setStatus("Running..."),setTimeout(function(){setTimeout(function(){x.setStatus("")},
1);a()},1)):a())}}if(x.preInit)for("function"==typeof x.preInit&&(x.preInit=[x.preInit]);0<x.preInit.length;)x.preInit.pop()();bd();
return ortWasmThreaded.ready
}
);
})();
if (true)
module.exports = ortWasmThreaded;
else {}
/***/ }),
/***/ "./lib/wasm/binding/ort-wasm.js":
/*!**************************************!*\
!*** ./lib/wasm/binding/ort-wasm.js ***!
\**************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
var __filename = "/index.js";
var __dirname = "/";
var ortWasm = (() => {
var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined;
if (true) _scriptDir = _scriptDir || __filename;
return (
function(ortWasm) {
ortWasm = ortWasm || {};
var d;d||(d=typeof ortWasm !== 'undefined' ? ortWasm : {});var aa,ba;d.ready=new Promise(function(a,b){aa=a;ba=b});var ca=Object.assign({},d),da="./this.program",ea=(a,b)=>{throw b;},fa="object"==typeof window,m="function"==typeof importScripts,p="object"==typeof process&&"object"==typeof process.versions&&"string"==typeof process.versions.node,q="",ha,r,v,fs,y,ia;
if(p)q=m?(__webpack_require__(/*! path */ "?75c6").dirname)(q)+"/":__dirname+"/",ia=()=>{y||(fs=__webpack_require__(/*! fs */ "?63c8"),y=__webpack_require__(/*! path */ "?75c6"))},ha=function(a,b){ia();a=y.normalize(a);return fs.readFileSync(a,b?void 0:"utf8")},v=a=>{a=ha(a,!0);a.buffer||(a=new Uint8Array(a));return a},r=(a,b,c)=>{ia();a=y.normalize(a);fs.readFile(a,function(e,f){e?c(e):b(f.buffer)})},1<process.argv.length&&(da=process.argv[1].replace(/\\/g,"/")),process.argv.slice(2),process.on("uncaughtException",function(a){if(!(a instanceof ja))throw a;}),process.on("unhandledRejection",
function(a){throw a;}),ea=(a,b)=>{if(noExitRuntime||0<ka)throw process.exitCode=a,b;b instanceof ja||z("exiting due to exception: "+b);process.exit(a)},d.inspect=function(){return"[Emscripten Module object]"};else if(fa||m)m?q=self.location.href:"undefined"!=typeof document&&document.currentScript&&(q=document.currentScript.src),_scriptDir&&(q=_scriptDir),0!==q.indexOf("blob:")?q=q.substr(0,q.replace(/[?#].*/,"").lastIndexOf("/")+1):q="",ha=a=>{var b=new XMLHttpRequest;b.open("GET",a,!1);b.send(null);
return b.responseText},m&&(v=a=>{var b=new XMLHttpRequest;b.open("GET",a,!1);b.responseType="arraybuffer";b.send(null);return new Uint8Array(b.response)}),r=(a,b,c)=>{var e=new XMLHttpRequest;e.open("GET",a,!0);e.responseType="arraybuffer";e.onload=()=>{200==e.status||0==e.status&&e.response?b(e.response):c()};e.onerror=c;e.send(null)};var la=d.print||console.log.bind(console),z=d.printErr||console.warn.bind(console);Object.assign(d,ca);ca=null;d.thisProgram&&(da=d.thisProgram);d.quit&&(ea=d.quit);
var A;d.wasmBinary&&(A=d.wasmBinary);var noExitRuntime=d.noExitRuntime||!1;"object"!=typeof WebAssembly&&B("no native wasm support detected");var ma,D=!1,na="undefined"!=typeof TextDecoder?new TextDecoder("utf8"):void 0;
function oa(a,b,c){b>>>=0;var e=b+c;for(c=b;a[c]&&!(c>=e);)++c;if(16<c-b&&a.buffer&&na)return na.decode(a.subarray(b,c));for(e="";b<c;){var f=a[b++];if(f&128){var h=a[b++]&63;if(192==(f&224))e+=String.fromCharCode((f&31)<<6|h);else{var k=a[b++]&63;f=224==(f&240)?(f&15)<<12|h<<6|k:(f&7)<<18|h<<12|k<<6|a[b++]&63;65536>f?e+=String.fromCharCode(f):(f-=65536,e+=String.fromCharCode(55296|f>>10,56320|f&1023))}}else e+=String.fromCharCode(f)}return e}function pa(a,b){return(a>>>=0)?oa(G,a,b):""}
function qa(a,b,c,e){c>>>=0;if(!(0<e))return 0;var f=c;e=c+e-1;for(var h=0;h<a.length;++h){var k=a.charCodeAt(h);if(55296<=k&&57343>=k){var l=a.charCodeAt(++h);k=65536+((k&1023)<<10)|l&1023}if(127>=k){if(c>=e)break;b[c++>>>0]=k}else{if(2047>=k){if(c+1>=e)break;b[c++>>>0]=192|k>>6}else{if(65535>=k){if(c+2>=e)break;b[c++>>>0]=224|k>>12}else{if(c+3>=e)break;b[c++>>>0]=240|k>>18;b[c++>>>0]=128|k>>12&63}b[c++>>>0]=128|k>>6&63}b[c++>>>0]=128|k&63}}b[c>>>0]=0;return c-f}
function ra(a){for(var b=0,c=0;c<a.length;++c){var e=a.charCodeAt(c);127>=e?b++:2047>=e?b+=2:55296<=e&&57343>=e?(b+=4,++c):b+=3}return b}var sa,H,G,I,J;function ta(){var a=ma.buffer;sa=a;d.HEAP8=H=new Int8Array(a);d.HEAP16=new Int16Array(a);d.HEAP32=I=new Int32Array(a);d.HEAPU8=G=new Uint8Array(a);d.HEAPU16=new Uint16Array(a);d.HEAPU32=J=new Uint32Array(a);d.HEAPF32=new Float32Array(a);d.HEAPF64=new Float64Array(a)}var ua,va=[],wa=[],xa=[],ya=[],ka=0;
function za(){var a=d.preRun.shift();va.unshift(a)}var K=0,Aa=null,L=null;function B(a){if(d.onAbort)d.onAbort(a);a="Aborted("+a+")";z(a);D=!0;a=new WebAssembly.RuntimeError(a+". Build with -sASSERTIONS for more info.");ba(a);throw a;}function Ba(){return N.startsWith("data:application/octet-stream;base64,")}var N;N="ort-wasm.wasm";if(!Ba()){var Ca=N;N=d.locateFile?d.locateFile(Ca,q):q+Ca}
function Da(){var a=N;try{if(a==N&&A)return new Uint8Array(A);if(v)return v(a);throw"both async and sync fetching of the wasm failed";}catch(b){B(b)}}
function Ea(){if(!A&&(fa||m)){if("function"==typeof fetch&&!N.startsWith("file://"))return fetch(N,{credentials:"same-origin"}).then(function(a){if(!a.ok)throw"failed to load wasm binary file at '"+N+"'";return a.arrayBuffer()}).catch(function(){return Da()});if(r)return new Promise(function(a,b){r(N,function(c){a(new Uint8Array(c))},b)})}return Promise.resolve().then(function(){return Da()})}function ja(a){this.name="ExitStatus";this.message="Program terminated with exit("+a+")";this.status=a}
function O(a){for(;0<a.length;)a.shift()(d)}var P=[],Q=0,R=0;
function S(a){this.Db=a;this.zb=a-24;this.Ub=function(b){J[this.zb+4>>2>>>0]=b};this.Eb=function(){return J[this.zb+4>>2>>>0]};this.Sb=function(b){J[this.zb+8>>2>>>0]=b};this.Wb=function(){return J[this.zb+8>>2>>>0]};this.Tb=function(){I[this.zb>>2>>>0]=0};this.Ib=function(b){H[this.zb+12>>0>>>0]=b?1:0};this.Pb=function(){return 0!=H[this.zb+12>>0>>>0]};this.Jb=function(b){H[this.zb+13>>0>>>0]=b?1:0};this.Lb=function(){return 0!=H[this.zb+13>>0>>>0]};this.Rb=function(b,c){this.Fb(0);this.Ub(b);this.Sb(c);
this.Tb();this.Ib(!1);this.Jb(!1)};this.Nb=function(){I[this.zb>>2>>>0]+=1};this.Xb=function(){var b=I[this.zb>>2>>>0];I[this.zb>>2>>>0]=b-1;return 1===b};this.Fb=function(b){J[this.zb+16>>2>>>0]=b};this.Ob=function(){return J[this.zb+16>>2>>>0]};this.Qb=function(){if(Fa(this.Eb()))return J[this.Db>>2>>>0];var b=this.Ob();return 0!==b?b:this.Db}}function Ga(a){return Ha((new S(a)).zb)}var T=[];function U(a){var b=T[a];b||(a>=T.length&&(T.length=a+1),T[a]=b=ua.get(a));return b}
function Ia(a){var b=ra(a)+1,c=Ja(b);c&&qa(a,H,c,b);return c}function Ka(a,b,c){function e(n){return(n=n.toTimeString().match(/\(([A-Za-z ]+)\)$/))?n[1]:"GMT"}var f=(new Date).getFullYear(),h=new Date(f,0,1),k=new Date(f,6,1);f=h.getTimezoneOffset();var l=k.getTimezoneOffset();I[a>>2>>>0]=60*Math.max(f,l);I[b>>2>>>0]=Number(f!=l);a=e(h);b=e(k);a=Ia(a);b=Ia(b);l<f?(J[c>>2>>>0]=a,J[c+4>>2>>>0]=b):(J[c>>2>>>0]=b,J[c+4>>2>>>0]=a)}function La(a,b,c){La.Vb||(La.Vb=!0,Ka(a,b,c))}var Ma={};
function Na(){if(!Oa){var a={USER:"web_user",LOGNAME:"web_user",PATH:"/",PWD:"/",HOME:"/home/web_user",LANG:("object"==typeof navigator&&navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8",_:da||"./this.program"},b;for(b in Ma)void 0===Ma[b]?delete a[b]:a[b]=Ma[b];var c=[];for(b in a)c.push(b+"="+a[b]);Oa=c}return Oa}var Oa,Pa=[null,[],[]];function Qa(a,b){var c=Pa[a];0===b||10===b?((1===a?la:z)(oa(c,0)),c.length=0):c.push(b)}var V=0;
function Ra(){if("object"==typeof crypto&&"function"==typeof crypto.getRandomValues){var a=new Uint8Array(1);return()=>{crypto.getRandomValues(a);return a[0]}}if(p)try{var b=__webpack_require__(Object(function webpackMissingModule() { var e = new Error("Cannot find module 'crypto'"); e.code = 'MODULE_NOT_FOUND'; throw e; }()));return()=>b.randomBytes(1)[0]}catch(c){}return()=>B("randomDevice")}function W(a,b){W.Mb||(W.Mb=Ra());for(var c=0;c<b;c++)H[a+c>>0>>>0]=W.Mb();return 0}function Sa(a){return 0===a%4&&(0!==a%100||0===a%400)}var Ta=[31,29,31,30,31,30,31,31,30,31,30,31],Ua=[31,28,31,30,31,30,31,31,30,31,30,31];
function Va(a){var b=Array(ra(a)+1);qa(a,b,0,b.length);return b}
function Wa(a,b,c,e){function f(g,u,w){for(g="number"==typeof g?g.toString():g||"";g.length<u;)g=w[0]+g;return g}function h(g,u){return f(g,u,"0")}function k(g,u){function w(M){return 0>M?-1:0<M?1:0}var F;0===(F=w(g.getFullYear()-u.getFullYear()))&&0===(F=w(g.getMonth()-u.getMonth()))&&(F=w(g.getDate()-u.getDate()));return F}function l(g){switch(g.getDay()){case 0:return new Date(g.getFullYear()-1,11,29);case 1:return g;case 2:return new Date(g.getFullYear(),0,3);case 3:return new Date(g.getFullYear(),
0,2);case 4:return new Date(g.getFullYear(),0,1);case 5:return new Date(g.getFullYear()-1,11,31);case 6:return new Date(g.getFullYear()-1,11,30)}}function n(g){var u=g.Bb;for(g=new Date((new Date(g.Cb+1900,0,1)).getTime());0<u;){var w=g.getMonth(),F=(Sa(g.getFullYear())?Ta:Ua)[w];if(u>F-g.getDate())u-=F-g.getDate()+1,g.setDate(1),11>w?g.setMonth(w+1):(g.setMonth(0),g.setFullYear(g.getFullYear()+1));else{g.setDate(g.getDate()+u);break}}w=new Date(g.getFullYear()+1,0,4);u=l(new Date(g.getFullYear(),
0,4));w=l(w);return 0>=k(u,g)?0>=k(w,g)?g.getFullYear()+1:g.getFullYear():g.getFullYear()-1}var t=I[e+40>>2>>>0];e={$b:I[e>>2>>>0],Zb:I[e+4>>2>>>0],Gb:I[e+8>>2>>>0],Kb:I[e+12>>2>>>0],Hb:I[e+16>>2>>>0],Cb:I[e+20>>2>>>0],Ab:I[e+24>>2>>>0],Bb:I[e+28>>2>>>0],bc:I[e+32>>2>>>0],Yb:I[e+36>>2>>>0],ac:t?pa(t):""};c=pa(c);t={"%c":"%a %b %d %H:%M:%S %Y","%D":"%m/%d/%y","%F":"%Y-%m-%d","%h":"%b","%r":"%I:%M:%S %p","%R":"%H:%M","%T":"%H:%M:%S","%x":"%m/%d/%y","%X":"%H:%M:%S","%Ec":"%c","%EC":"%C","%Ex":"%m/%d/%y",
"%EX":"%H:%M:%S","%Ey":"%y","%EY":"%Y","%Od":"%d","%Oe":"%e","%OH":"%H","%OI":"%I","%Om":"%m","%OM":"%M","%OS":"%S","%Ou":"%u","%OU":"%U","%OV":"%V","%Ow":"%w","%OW":"%W","%Oy":"%y"};for(var x in t)c=c.replace(new RegExp(x,"g"),t[x]);var E="Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" "),C="January February March April May June July August September October November December".split(" ");t={"%a":function(g){return E[g.Ab].substring(0,3)},"%A":function(g){return E[g.Ab]},"%b":function(g){return C[g.Hb].substring(0,
3)},"%B":function(g){return C[g.Hb]},"%C":function(g){return h((g.Cb+1900)/100|0,2)},"%d":function(g){return h(g.Kb,2)},"%e":function(g){return f(g.Kb,2," ")},"%g":function(g){return n(g).toString().substring(2)},"%G":function(g){return n(g)},"%H":function(g){return h(g.Gb,2)},"%I":function(g){g=g.Gb;0==g?g=12:12<g&&(g-=12);return h(g,2)},"%j":function(g){for(var u=0,w=0;w<=g.Hb-1;u+=(Sa(g.Cb+1900)?Ta:Ua)[w++]);return h(g.Kb+u,3)},"%m":function(g){return h(g.Hb+1,2)},"%M":function(g){return h(g.Zb,
2)},"%n":function(){return"\n"},"%p":function(g){return 0<=g.Gb&&12>g.Gb?"AM":"PM"},"%S":function(g){return h(g.$b,2)},"%t":function(){return"\t"},"%u":function(g){return g.Ab||7},"%U":function(g){return h(Math.floor((g.Bb+7-g.Ab)/7),2)},"%V":function(g){var u=Math.floor((g.Bb+7-(g.Ab+6)%7)/7);2>=(g.Ab+371-g.Bb-2)%7&&u++;if(u)53==u&&(w=(g.Ab+371-g.Bb)%7,4==w||3==w&&Sa(g.Cb)||(u=1));else{u=52;var w=(g.Ab+7-g.Bb-1)%7;(4==w||5==w&&Sa(g.Cb%400-1))&&u++}return h(u,2)},"%w":function(g){return g.Ab},"%W":function(g){return h(Math.floor((g.Bb+
7-(g.Ab+6)%7)/7),2)},"%y":function(g){return(g.Cb+1900).toString().substring(2)},"%Y":function(g){return g.Cb+1900},"%z":function(g){g=g.Yb;var u=0<=g;g=Math.abs(g)/60;return(u?"+":"-")+String("0000"+(g/60*100+g%60)).slice(-4)},"%Z":function(g){return g.ac},"%%":function(){return"%"}};c=c.replace(/%%/g,"\x00\x00");for(x in t)c.includes(x)&&(c=c.replace(new RegExp(x,"g"),t[x](e)));c=c.replace(/\0\0/g,"%");x=Va(c);if(x.length>b)return 0;H.set(x,a>>>0);return x.length-1}
var Jb={a:function(a){return Ja(a+24)+24},m:function(a){a=new S(a);a.Pb()||(a.Ib(!0),Q--);a.Jb(!1);P.push(a);a.Nb();return a.Qb()},ia:function(a){z("Unexpected exception thrown, this is not properly supported - aborting");D=!0;throw a;},w:function(){X(0);var a=P.pop();if(a.Xb()&&!a.Lb()){var b=a.Wb();b&&U(b)(a.Db);Ga(a.Db)}R=0},d:function(){var a=R;if(!a)return V=0;var b=new S(a);b.Fb(a);var c=b.Eb();if(!c)return V=0,a;for(var e=Array.prototype.slice.call(arguments),f=0;f<e.length;f++){var h=e[f];
if(0===h||h===c)break;if(Xa(h,c,b.zb+16))return V=h,a}V=c;return a},k:function(){var a=R;if(!a)return V=0;var b=new S(a);b.Fb(a);var c=b.Eb();if(!c)return V=0,a;for(var e=Array.prototype.slice.call(arguments),f=0;f<e.length;f++){var h=e[f];if(0===h||h===c)break;if(Xa(h,c,b.zb+16))return V=h,a}V=c;return a},g:function(){var a=R;if(!a)return V=0;var b=new S(a);b.Fb(a);var c=b.Eb();if(!c)return V=0,a;for(var e=Array.prototype.slice.call(arguments),f=0;f<e.length;f++){var h=e[f];if(0===h||h===c)break;
if(Xa(h,c,b.zb+16))return V=h,a}V=c;return a},s:Ga,L:function(){var a=P.pop();a||B("no exception to throw");var b=a.Db;a.Lb()||(P.push(a),a.Jb(!0),a.Ib(!1),Q++);R=b;throw b;},b:function(a,b,c){(new S(a)).Rb(b,c);R=a;Q++;throw a;},la:function(){return Q},i:function(a){R||(R=a);throw a;},H:function(){return 0},Ba:function(){},pa:function(){},ra:function(){},ka:function(){return 0},za:function(){},ua:function(){},ya:function(){},R:function(){},qa:function(){},na:function(){},Aa:function(){},oa:function(){},
Ha:function(){},Ja:function(){B("To use dlopen, you need enable dynamic linking, see https://github.com/emscripten-core/emscripten/wiki/Linking")},Ia:function(){B("To use dlopen, you need enable dynamic linking, see https://github.com/emscripten-core/emscripten/wiki/Linking")},S:function(){return Date.now()},Ca:function(){return!0},Da:function(a,b){a=new Date(1E3*(J[a>>>2]+4294967296*I[a+4>>>2]));I[b>>2>>>0]=a.getUTCSeconds();I[b+4>>2>>>0]=a.getUTCMinutes();I[b+8>>2>>>0]=a.getUTCHours();I[b+12>>2>>>
0]=a.getUTCDate();I[b+16>>2>>>0]=a.getUTCMonth();I[b+20>>2>>>0]=a.getUTCFullYear()-1900;I[b+24>>2>>>0]=a.getUTCDay();I[b+28>>2>>>0]=(a.getTime()-Date.UTC(a.getUTCFullYear(),0,1,0,0,0,0))/864E5|0},Ea:function(a,b){a=new Date(1E3*(J[a>>>2]+4294967296*I[a+4>>>2]));I[b>>2>>>0]=a.getSeconds();I[b+4>>2>>>0]=a.getMinutes();I[b+8>>2>>>0]=a.getHours();I[b+12>>2>>>0]=a.getDate();I[b+16>>2>>>0]=a.getMonth();I[b+20>>2>>>0]=a.getFullYear()-1900;I[b+24>>2>>>0]=a.getDay();var c=new Date(a.getFullYear(),0,1);I[b+
28>>2>>>0]=(a.getTime()-c.getTime())/864E5|0;I[b+36>>2>>>0]=-(60*a.getTimezoneOffset());var e=(new Date(a.getFullYear(),6,1)).getTimezoneOffset();c=c.getTimezoneOffset();I[b+32>>2>>>0]=(e!=c&&a.getTimezoneOffset()==Math.min(c,e))|0},Fa:function(a){var b=new Date(I[a+20>>2>>>0]+1900,I[a+16>>2>>>0],I[a+12>>2>>>0],I[a+8>>2>>>0],I[a+4>>2>>>0],I[a>>2>>>0],0),c=I[a+32>>2>>>0],e=b.getTimezoneOffset(),f=new Date(b.getFullYear(),0,1),h=(new Date(b.getFullYear(),6,1)).getTimezoneOffset(),k=f.getTimezoneOffset(),
l=Math.min(k,h);0>c?I[a+32>>2>>>0]=Number(h!=k&&l==e):0<c!=(l==e)&&(h=Math.max(k,h),b.setTime(b.getTime()+6E4*((0<c?l:h)-e)));I[a+24>>2>>>0]=b.getDay();I[a+28>>2>>>0]=(b.getTime()-f.getTime())/864E5|0;I[a>>2>>>0]=b.getSeconds();I[a+4>>2>>>0]=b.getMinutes();I[a+8>>2>>>0]=b.getHours();I[a+12>>2>>>0]=b.getDate();I[a+16>>2>>>0]=b.getMonth();return b.getTime()/1E3|0},sa:function(){return-52},ta:function(){},Ga:La,B:function(){B("")},ma:function(){return 4294901760},I:p?()=>{var a=process.hrtime();return 1E3*
a[0]+a[1]/1E6}:()=>performance.now(),xa:function(a,b,c){G.copyWithin(a>>>0,b>>>0,b+c>>>0)},G:function(a){var b=G.length;a>>>=0;if(4294901760<a)return!1;for(var c=1;4>=c;c*=2){var e=b*(1+.2/c);e=Math.min(e,a+100663296);var f=Math;e=Math.max(a,e);f=f.min.call(f,4294901760,e+(65536-e%65536)%65536);a:{try{ma.grow(f-sa.byteLength+65535>>>16);ta();var h=1;break a}catch(k){}h=void 0}if(h)return!0}return!1},va:function(a,b){var c=0;Na().forEach(function(e,f){var h=b+c;f=J[a+4*f>>2>>>0]=h;for(h=0;h<e.length;++h)H[f++>>
0>>>0]=e.charCodeAt(h);H[f>>0>>>0]=0;c+=e.length+1});return 0},wa:function(a,b){var c=Na();J[a>>2>>>0]=c.length;var e=0;c.forEach(function(f){e+=f.length+1});J[b>>2>>>0]=e;return 0},ba:function(a){noExitRuntime||0<ka||(Ya(),O(xa),Za(0),Pa[1].length&&Qa(1,10),Pa[2].length&&Qa(2,10));if(!(noExitRuntime||0<ka)){if(d.onExit)d.onExit(a);D=!0}ea(a,new ja(a))},E:function(){return 52},Q:function(){return 52},ca:function(){return 70},P:function(a,b,c,e){for(var f=0,h=0;h<c;h++){var k=J[b>>2>>>0],l=J[b+4>>
2>>>0];b+=8;for(var n=0;n<l;n++)Qa(a,G[k+n>>>0]);f+=l}J[e>>2>>>0]=f;return 0},c:function(){return V},ja:W,ea:$a,fa:ab,J:bb,e:cb,N:db,O:eb,j:fb,o:gb,p:hb,M:ib,r:jb,v:kb,K:lb,D:mb,X:nb,V:ob,U:pb,Z:qb,W:rb,Y:sb,T:tb,f:ub,q:vb,h:wb,da:xb,l:yb,t:zb,u:Ab,x:Bb,z:Cb,ga:Db,A:Eb,C:Fb,aa:Gb,_:Hb,$:Ib,n:function(a){return a},F:function(a){V=a},ha:Wa,y:function(a,b,c,e){return Wa(a,b,c,e)}};
(function(){function a(f){d.asm=f.exports;ma=d.asm.Ka;ta();ua=d.asm.ib;wa.unshift(d.asm.La);K--;d.monitorRunDependencies&&d.monitorRunDependencies(K);0==K&&(null!==Aa&&(clearInterval(Aa),Aa=null),L&&(f=L,L=null,f()))}function b(f){a(f.instance)}function c(f){return Ea().then(function(h){return WebAssembly.instantiate(h,e)}).then(function(h){return h}).then(f,function(h){z("failed to asynchronously prepare wasm: "+h);B(h)})}var e={a:Jb};K++;d.monitorRunDependencies&&d.monitorRunDependencies(K);if(d.instantiateWasm)try{return d.instantiateWasm(e,
a)}catch(f){return z("Module.instantiateWasm callback failed with error: "+f),!1}(function(){return A||"function"!=typeof WebAssembly.instantiateStreaming||Ba()||N.startsWith("file://")||p||"function"!=typeof fetch?c(b):fetch(N,{credentials:"same-origin"}).then(function(f){return WebAssembly.instantiateStreaming(f,e).then(b,function(h){z("wasm streaming compile failed: "+h);z("falling back to ArrayBuffer instantiation");return c(b)})})})().catch(ba);return{}})();
d.___wasm_call_ctors=function(){return(d.___wasm_call_ctors=d.asm.La).apply(null,arguments)};d._OrtInit=function(){return(d._OrtInit=d.asm.Ma).apply(null,arguments)};d._OrtCreateSessionOptions=function(){return(d._OrtCreateSessionOptions=d.asm.Na).apply(null,arguments)};d._OrtAppendExecutionProvider=function(){return(d._OrtAppendExecutionProvider=d.asm.Oa).apply(null,arguments)};d._OrtAddSessionConfigEntry=function(){return(d._OrtAddSessionConfigEntry=d.asm.Pa).apply(null,arguments)};
d._OrtReleaseSessionOptions=function(){return(d._OrtReleaseSessionOptions=d.asm.Qa).apply(null,arguments)};d._OrtCreateSession=function(){return(d._OrtCreateSession=d.asm.Ra).apply(null,arguments)};d._OrtReleaseSession=function(){return(d._OrtReleaseSession=d.asm.Sa).apply(null,arguments)};d._OrtGetInputCount=function(){return(d._OrtGetInputCount=d.asm.Ta).apply(null,arguments)};d._OrtGetOutputCount=function(){return(d._OrtGetOutputCount=d.asm.Ua).apply(null,arguments)};
d._OrtGetInputName=function(){return(d._OrtGetInputName=d.asm.Va).apply(null,arguments)};d._OrtGetOutputName=function(){return(d._OrtGetOutputName=d.asm.Wa).apply(null,arguments)};d._OrtFree=function(){return(d._OrtFree=d.asm.Xa).apply(null,arguments)};d._OrtCreateTensor=function(){return(d._OrtCreateTensor=d.asm.Ya).apply(null,arguments)};d._OrtGetTensorData=function(){return(d._OrtGetTensorData=d.asm.Za).apply(null,arguments)};
d._OrtReleaseTensor=function(){return(d._OrtReleaseTensor=d.asm._a).apply(null,arguments)};d._OrtCreateRunOptions=function(){return(d._OrtCreateRunOptions=d.asm.$a).apply(null,arguments)};d._OrtAddRunConfigEntry=function(){return(d._OrtAddRunConfigEntry=d.asm.ab).apply(null,arguments)};d._OrtReleaseRunOptions=function(){return(d._OrtReleaseRunOptions=d.asm.bb).apply(null,arguments)};d._OrtRun=function(){return(d._OrtRun=d.asm.cb).apply(null,arguments)};
d._OrtEndProfiling=function(){return(d._OrtEndProfiling=d.asm.db).apply(null,arguments)};
var Ja=d._malloc=function(){return(Ja=d._malloc=d.asm.eb).apply(null,arguments)},Ha=d._free=function(){return(Ha=d._free=d.asm.fb).apply(null,arguments)},Za=d._fflush=function(){return(Za=d._fflush=d.asm.gb).apply(null,arguments)},Ya=d.___funcs_on_exit=function(){return(Ya=d.___funcs_on_exit=d.asm.hb).apply(null,arguments)},X=d._setThrew=function(){return(X=d._setThrew=d.asm.jb).apply(null,arguments)},Y=d.stackSave=function(){return(Y=d.stackSave=d.asm.kb).apply(null,arguments)},Z=d.stackRestore=
function(){return(Z=d.stackRestore=d.asm.lb).apply(null,arguments)},Kb=d.stackAlloc=function(){return(Kb=d.stackAlloc=d.asm.mb).apply(null,arguments)},Xa=d.___cxa_can_catch=function(){return(Xa=d.___cxa_can_catch=d.asm.nb).apply(null,arguments)},Fa=d.___cxa_is_pointer_type=function(){return(Fa=d.___cxa_is_pointer_type=d.asm.ob).apply(null,arguments)},Lb=d.dynCall_j=function(){return(Lb=d.dynCall_j=d.asm.pb).apply(null,arguments)},Mb=d.dynCall_iiiiij=function(){return(Mb=d.dynCall_iiiiij=d.asm.qb).apply(null,
arguments)},Nb=d.dynCall_jii=function(){return(Nb=d.dynCall_jii=d.asm.rb).apply(null,arguments)},Ob=d.dynCall_viiiiij=function(){return(Ob=d.dynCall_viiiiij=d.asm.sb).apply(null,arguments)},Pb=d.dynCall_vjji=function(){return(Pb=d.dynCall_vjji=d.asm.tb).apply(null,arguments)},Qb=d.dynCall_viiijjjii=function(){return(Qb=d.dynCall_viiijjjii=d.asm.ub).apply(null,arguments)},Rb=d.dynCall_iij=function(){return(Rb=d.dynCall_iij=d.asm.vb).apply(null,arguments)},Sb=d.dynCall_ji=function(){return(Sb=d.dynCall_ji=
d.asm.wb).apply(null,arguments)},Tb=d.dynCall_iiiiiij=function(){return(Tb=d.dynCall_iiiiiij=d.asm.xb).apply(null,arguments)},Ub=d.dynCall_iiij=function(){return(Ub=d.dynCall_iiij=d.asm.yb).apply(null,arguments)};function cb(a,b){var c=Y();try{return U(a)(b)}catch(e){Z(c);if(e!==e+0)throw e;X(1,0)}}function vb(a,b){var c=Y();try{U(a)(b)}catch(e){Z(c);if(e!==e+0)throw e;X(1,0)}}function wb(a,b,c){var e=Y();try{U(a)(b,c)}catch(f){Z(e);if(f!==f+0)throw f;X(1,0)}}
function fb(a,b,c){var e=Y();try{return U(a)(b,c)}catch(f){Z(e);if(f!==f+0)throw f;X(1,0)}}function gb(a,b,c,e){var f=Y();try{return U(a)(b,c,e)}catch(h){Z(f);if(h!==h+0)throw h;X(1,0)}}function kb(a,b,c,e,f,h,k){var l=Y();try{return U(a)(b,c,e,f,h,k)}catch(n){Z(l);if(n!==n+0)throw n;X(1,0)}}function ub(a){var b=Y();try{U(a)()}catch(c){Z(b);if(c!==c+0)throw c;X(1,0)}}function jb(a,b,c,e,f,h){var k=Y();try{return U(a)(b,c,e,f,h)}catch(l){Z(k);if(l!==l+0)throw l;X(1,0)}}
function hb(a,b,c,e,f){var h=Y();try{return U(a)(b,c,e,f)}catch(k){Z(h);if(k!==k+0)throw k;X(1,0)}}function yb(a,b,c,e){var f=Y();try{U(a)(b,c,e)}catch(h){Z(f);if(h!==h+0)throw h;X(1,0)}}function Ab(a,b,c,e,f,h){var k=Y();try{U(a)(b,c,e,f,h)}catch(l){Z(k);if(l!==l+0)throw l;X(1,0)}}function zb(a,b,c,e,f){var h=Y();try{U(a)(b,c,e,f)}catch(k){Z(h);if(k!==k+0)throw k;X(1,0)}}function Bb(a,b,c,e,f,h,k){var l=Y();try{U(a)(b,c,e,f,h,k)}catch(n){Z(l);if(n!==n+0)throw n;X(1,0)}}
function Cb(a,b,c,e,f,h,k,l){var n=Y();try{U(a)(b,c,e,f,h,k,l)}catch(t){Z(n);if(t!==t+0)throw t;X(1,0)}}function eb(a,b,c){var e=Y();try{return U(a)(b,c)}catch(f){Z(e);if(f!==f+0)throw f;X(1,0)}}function db(a,b,c){var e=Y();try{return U(a)(b,c)}catch(f){Z(e);if(f!==f+0)throw f;X(1,0)}}function Db(a,b,c,e,f,h,k,l,n){var t=Y();try{U(a)(b,c,e,f,h,k,l,n)}catch(x){Z(t);if(x!==x+0)throw x;X(1,0)}}function ib(a,b,c,e,f,h){var k=Y();try{return U(a)(b,c,e,f,h)}catch(l){Z(k);if(l!==l+0)throw l;X(1,0)}}
function lb(a,b,c,e,f,h,k,l){var n=Y();try{return U(a)(b,c,e,f,h,k,l)}catch(t){Z(n);if(t!==t+0)throw t;X(1,0)}}function mb(a,b,c,e,f,h,k,l,n,t,x,E){var C=Y();try{return U(a)(b,c,e,f,h,k,l,n,t,x,E)}catch(g){Z(C);if(g!==g+0)throw g;X(1,0)}}function Eb(a,b,c,e,f,h,k,l,n,t,x){var E=Y();try{U(a)(b,c,e,f,h,k,l,n,t,x)}catch(C){Z(E);if(C!==C+0)throw C;X(1,0)}}function Fb(a,b,c,e,f,h,k,l,n,t,x,E,C,g,u,w){var F=Y();try{U(a)(b,c,e,f,h,k,l,n,t,x,E,C,g,u,w)}catch(M){Z(F);if(M!==M+0)throw M;X(1,0)}}
function bb(a){var b=Y();try{return U(a)()}catch(c){Z(b);if(c!==c+0)throw c;X(1,0)}}function ab(a,b,c){var e=Y();try{return U(a)(b,c)}catch(f){Z(e);if(f!==f+0)throw f;X(1,0)}}function $a(a,b,c){var e=Y();try{return U(a)(b,c)}catch(f){Z(e);if(f!==f+0)throw f;X(1,0)}}function xb(a,b,c,e){var f=Y();try{U(a)(b,c,e)}catch(h){Z(f);if(h!==h+0)throw h;X(1,0)}}function Gb(a,b,c,e,f,h,k,l){var n=Y();try{Ob(a,b,c,e,f,h,k,l)}catch(t){Z(n);if(t!==t+0)throw t;X(1,0)}}
function Ib(a,b,c,e,f,h){var k=Y();try{Pb(a,b,c,e,f,h)}catch(l){Z(k);if(l!==l+0)throw l;X(1,0)}}function Hb(a,b,c,e,f,h,k,l,n,t,x,E){var C=Y();try{Qb(a,b,c,e,f,h,k,l,n,t,x,E)}catch(g){Z(C);if(g!==g+0)throw g;X(1,0)}}function qb(a,b,c,e){var f=Y();try{return Rb(a,b,c,e)}catch(h){Z(f);if(h!==h+0)throw h;X(1,0)}}function sb(a,b){var c=Y();try{return Sb(a,b)}catch(e){Z(c);if(e!==e+0)throw e;X(1,0)}}
function nb(a,b,c,e,f,h,k,l){var n=Y();try{return Tb(a,b,c,e,f,h,k,l)}catch(t){Z(n);if(t!==t+0)throw t;X(1,0)}}function rb(a){var b=Y();try{return Lb(a)}catch(c){Z(b);if(c!==c+0)throw c;X(1,0)}}function ob(a,b,c,e,f,h,k){var l=Y();try{return Mb(a,b,c,e,f,h,k)}catch(n){Z(l);if(n!==n+0)throw n;X(1,0)}}function pb(a,b,c,e,f){var h=Y();try{return Ub(a,b,c,e,f)}catch(k){Z(h);if(k!==k+0)throw k;X(1,0)}}function tb(a,b,c){var e=Y();try{return Nb(a,b,c)}catch(f){Z(e);if(f!==f+0)throw f;X(1,0)}}
d.UTF8ToString=pa;d.stringToUTF8=function(a,b,c){return qa(a,G,b,c)};d.lengthBytesUTF8=ra;d.stackSave=Y;d.stackRestore=Z;d.stackAlloc=Kb;var Vb;L=function Wb(){Vb||Xb();Vb||(L=Wb)};
function Xb(){function a(){if(!Vb&&(Vb=!0,d.calledRun=!0,!D)){O(wa);aa(d);if(d.onRuntimeInitialized)d.onRuntimeInitialized();if(d.postRun)for("function"==typeof d.postRun&&(d.postRun=[d.postRun]);d.postRun.length;){var b=d.postRun.shift();ya.unshift(b)}O(ya)}}if(!(0<K)){if(d.preRun)for("function"==typeof d.preRun&&(d.preRun=[d.preRun]);d.preRun.length;)za();O(va);0<K||(d.setStatus?(d.setStatus("Running..."),setTimeout(function(){setTimeout(function(){d.setStatus("")},1);a()},1)):a())}}
if(d.preInit)for("function"==typeof d.preInit&&(d.preInit=[d.preInit]);0<d.preInit.length;)d.preInit.pop()();Xb();
return ortWasm.ready
}
);
})();
if (true)
module.exports = ortWasm;
else {}
/***/ }),
/***/ "./node_modules/@protobufjs/aspromise/index.js":
/*!*****************************************************!*\
!*** ./node_modules/@protobufjs/aspromise/index.js ***!
\*****************************************************/
/***/ ((module) => {
"use strict";
module.exports = asPromise;
/**
* Callback as used by {@link util.asPromise}.
* @typedef asPromiseCallback
* @type {function}
* @param {Error|null} error Error, if any
* @param {...*} params Additional arguments
* @returns {undefined}
*/
/**
* Returns a promise from a node-style callback function.
* @memberof util
* @param {asPromiseCallback} fn Function to call
* @param {*} ctx Function context
* @param {...*} params Function arguments
* @returns {Promise<*>} Promisified function
*/
function asPromise(fn, ctx/*, varargs */) {
var params = new Array(arguments.length - 1),
offset = 0,
index = 2,
pending = true;
while (index < arguments.length)
params[offset++] = arguments[index++];
return new Promise(function executor(resolve, reject) {
params[offset] = function callback(err/*, varargs */) {
if (pending) {
pending = false;
if (err)
reject(err);
else {
var params = new Array(arguments.length - 1),
offset = 0;
while (offset < params.length)
params[offset++] = arguments[offset];
resolve.apply(null, params);
}
}
};
try {
fn.apply(ctx || null, params);
} catch (err) {
if (pending) {
pending = false;
reject(err);
}
}
});
}
/***/ }),
/***/ "./node_modules/@protobufjs/base64/index.js":
/*!**************************************************!*\
!*** ./node_modules/@protobufjs/base64/index.js ***!
\**************************************************/
/***/ ((__unused_webpack_module, exports) => {
"use strict";
/**
* A minimal base64 implementation for number arrays.
* @memberof util
* @namespace
*/
var base64 = exports;
/**
* Calculates the byte length of a base64 encoded string.
* @param {string} string Base64 encoded string
* @returns {number} Byte length
*/
base64.length = function length(string) {
var p = string.length;
if (!p)
return 0;
var n = 0;
while (--p % 4 > 1 && string.charAt(p) === "=")
++n;
return Math.ceil(string.length * 3) / 4 - n;
};
// Base64 encoding table
var b64 = new Array(64);
// Base64 decoding table
var s64 = new Array(123);
// 65..90, 97..122, 48..57, 43, 47
for (var i = 0; i < 64;)
s64[b64[i] = i < 26 ? i + 65 : i < 52 ? i + 71 : i < 62 ? i - 4 : i - 59 | 43] = i++;
/**
* Encodes a buffer to a base64 encoded string.
* @param {Uint8Array} buffer Source buffer
* @param {number} start Source start
* @param {number} end Source end
* @returns {string} Base64 encoded string
*/
base64.encode = function encode(buffer, start, end) {
var parts = null,
chunk = [];
var i = 0, // output index
j = 0, // goto index
t; // temporary
while (start < end) {
var b = buffer[start++];
switch (j) {
case 0:
chunk[i++] = b64[b >> 2];
t = (b & 3) << 4;
j = 1;
break;
case 1:
chunk[i++] = b64[t | b >> 4];
t = (b & 15) << 2;
j = 2;
break;
case 2:
chunk[i++] = b64[t | b >> 6];
chunk[i++] = b64[b & 63];
j = 0;
break;
}
if (i > 8191) {
(parts || (parts = [])).push(String.fromCharCode.apply(String, chunk));
i = 0;
}
}
if (j) {
chunk[i++] = b64[t];
chunk[i++] = 61;
if (j === 1)
chunk[i++] = 61;
}
if (parts) {
if (i)
parts.push(String.fromCharCode.apply(String, chunk.slice(0, i)));
return parts.join("");
}
return String.fromCharCode.apply(String, chunk.slice(0, i));
};
var invalidEncoding = "invalid encoding";
/**
* Decodes a base64 encoded string to a buffer.
* @param {string} string Source string
* @param {Uint8Array} buffer Destination buffer
* @param {number} offset Destination offset
* @returns {number} Number of bytes written
* @throws {Error} If encoding is invalid
*/
base64.decode = function decode(string, buffer, offset) {
var start = offset;
var j = 0, // goto index
t; // temporary
for (var i = 0; i < string.length;) {
var c = string.charCodeAt(i++);
if (c === 61 && j > 1)
break;
if ((c = s64[c]) === undefined)
throw Error(invalidEncoding);
switch (j) {
case 0:
t = c;
j = 1;
break;
case 1:
buffer[offset++] = t << 2 | (c & 48) >> 4;
t = c;
j = 2;
break;
case 2:
buffer[offset++] = (t & 15) << 4 | (c & 60) >> 2;
t = c;
j = 3;
break;
case 3:
buffer[offset++] = (t & 3) << 6 | c;
j = 0;
break;
}
}
if (j === 1)
throw Error(invalidEncoding);
return offset - start;
};
/**
* Tests if the specified string appears to be base64 encoded.
* @param {string} string String to test
* @returns {boolean} `true` if probably base64 encoded, otherwise false
*/
base64.test = function test(string) {
return /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(string);
};
/***/ }),
/***/ "./node_modules/@protobufjs/eventemitter/index.js":
/*!********************************************************!*\
!*** ./node_modules/@protobufjs/eventemitter/index.js ***!
\********************************************************/
/***/ ((module) => {
"use strict";
module.exports = EventEmitter;
/**
* Constructs a new event emitter instance.
* @classdesc A minimal event emitter.
* @memberof util
* @constructor
*/
function EventEmitter() {
/**
* Registered listeners.
* @type {Object.<string,*>}
* @private
*/
this._listeners = {};
}
/**
* Registers an event listener.
* @param {string} evt Event name
* @param {function} fn Listener
* @param {*} [ctx] Listener context
* @returns {util.EventEmitter} `this`
*/
EventEmitter.prototype.on = function on(evt, fn, ctx) {
(this._listeners[evt] || (this._listeners[evt] = [])).push({
fn : fn,
ctx : ctx || this
});
return this;
};
/**
* Removes an event listener or any matching listeners if arguments are omitted.
* @param {string} [evt] Event name. Removes all listeners if omitted.
* @param {function} [fn] Listener to remove. Removes all listeners of `evt` if omitted.
* @returns {util.EventEmitter} `this`
*/
EventEmitter.prototype.off = function off(evt, fn) {
if (evt === undefined)
this._listeners = {};
else {
if (fn === undefined)
this._listeners[evt] = [];
else {
var listeners = this._listeners[evt];
for (var i = 0; i < listeners.length;)
if (listeners[i].fn === fn)
listeners.splice(i, 1);
else
++i;
}
}
return this;
};
/**
* Emits an event by calling its listeners with the specified arguments.
* @param {string} evt Event name
* @param {...*} args Arguments
* @returns {util.EventEmitter} `this`
*/
EventEmitter.prototype.emit = function emit(evt) {
var listeners = this._listeners[evt];
if (listeners) {
var args = [],
i = 1;
for (; i < arguments.length;)
args.push(arguments[i++]);
for (i = 0; i < listeners.length;)
listeners[i].fn.apply(listeners[i++].ctx, args);
}
return this;
};
/***/ }),
/***/ "./node_modules/@protobufjs/float/index.js":
/*!*************************************************!*\
!*** ./node_modules/@protobufjs/float/index.js ***!
\*************************************************/
/***/ ((module) => {
"use strict";
module.exports = factory(factory);
/**
* Reads / writes floats / doubles from / to buffers.
* @name util.float
* @namespace
*/
/**
* Writes a 32 bit float to a buffer using little endian byte order.
* @name util.float.writeFloatLE
* @function
* @param {number} val Value to write
* @param {Uint8Array} buf Target buffer
* @param {number} pos Target buffer offset
* @returns {undefined}
*/
/**
* Writes a 32 bit float to a buffer using big endian byte order.
* @name util.float.writeFloatBE
* @function
* @param {number} val Value to write
* @param {Uint8Array} buf Target buffer
* @param {number} pos Target buffer offset
* @returns {undefined}
*/
/**
* Reads a 32 bit float from a buffer using little endian byte order.
* @name util.float.readFloatLE
* @function
* @param {Uint8Array} buf Source buffer
* @param {number} pos Source buffer offset
* @returns {number} Value read
*/
/**
* Reads a 32 bit float from a buffer using big endian byte order.
* @name util.float.readFloatBE
* @function
* @param {Uint8Array} buf Source buffer
* @param {number} pos Source buffer offset
* @returns {number} Value read
*/
/**
* Writes a 64 bit double to a buffer using little endian byte order.
* @name util.float.writeDoubleLE
* @function
* @param {number} val Value to write
* @param {Uint8Array} buf Target buffer
* @param {number} pos Target buffer offset
* @returns {undefined}
*/
/**
* Writes a 64 bit double to a buffer using big endian byte order.
* @name util.float.writeDoubleBE
* @function
* @param {number} val Value to write
* @param {Uint8Array} buf Target buffer
* @param {number} pos Target buffer offset
* @returns {undefined}
*/
/**
* Reads a 64 bit double from a buffer using little endian byte order.
* @name util.float.readDoubleLE
* @function
* @param {Uint8Array} buf Source buffer
* @param {number} pos Source buffer offset
* @returns {number} Value read
*/
/**
* Reads a 64 bit double from a buffer using big endian byte order.
* @name util.float.readDoubleBE
* @function
* @param {Uint8Array} buf Source buffer
* @param {number} pos Source buffer offset
* @returns {number} Value read
*/
// Factory function for the purpose of node-based testing in modified global environments
function factory(exports) {
// float: typed array
if (typeof Float32Array !== "undefined") (function() {
var f32 = new Float32Array([ -0 ]),
f8b = new Uint8Array(f32.buffer),
le = f8b[3] === 128;
function writeFloat_f32_cpy(val, buf, pos) {
f32[0] = val;
buf[pos ] = f8b[0];
buf[pos + 1] = f8b[1];
buf[pos + 2] = f8b[2];
buf[pos + 3] = f8b[3];
}
function writeFloat_f32_rev(val, buf, pos) {
f32[0] = val;
buf[pos ] = f8b[3];
buf[pos + 1] = f8b[2];
buf[pos + 2] = f8b[1];
buf[pos + 3] = f8b[0];
}
/* istanbul ignore next */
exports.writeFloatLE = le ? writeFloat_f32_cpy : writeFloat_f32_rev;
/* istanbul ignore next */
exports.writeFloatBE = le ? writeFloat_f32_rev : writeFloat_f32_cpy;
function readFloat_f32_cpy(buf, pos) {
f8b[0] = buf[pos ];
f8b[1] = buf[pos + 1];
f8b[2] = buf[pos + 2];
f8b[3] = buf[pos + 3];
return f32[0];
}
function readFloat_f32_rev(buf, pos) {
f8b[3] = buf[pos ];
f8b[2] = buf[pos + 1];
f8b[1] = buf[pos + 2];
f8b[0] = buf[pos + 3];
return f32[0];
}
/* istanbul ignore next */
exports.readFloatLE = le ? readFloat_f32_cpy : readFloat_f32_rev;
/* istanbul ignore next */
exports.readFloatBE = le ? readFloat_f32_rev : readFloat_f32_cpy;
// float: ieee754
})(); else (function() {
function writeFloat_ieee754(writeUint, val, buf, pos) {
var sign = val < 0 ? 1 : 0;
if (sign)
val = -val;
if (val === 0)
writeUint(1 / val > 0 ? /* positive */ 0 : /* negative 0 */ 2147483648, buf, pos);
else if (isNaN(val))
writeUint(2143289344, buf, pos);
else if (val > 3.4028234663852886e+38) // +-Infinity
writeUint((sign << 31 | 2139095040) >>> 0, buf, pos);
else if (val < 1.1754943508222875e-38) // denormal
writeUint((sign << 31 | Math.round(val / 1.401298464324817e-45)) >>> 0, buf, pos);
else {
var exponent = Math.floor(Math.log(val) / Math.LN2),
mantissa = Math.round(val * Math.pow(2, -exponent) * 8388608) & 8388607;
writeUint((sign << 31 | exponent + 127 << 23 | mantissa) >>> 0, buf, pos);
}
}
exports.writeFloatLE = writeFloat_ieee754.bind(null, writeUintLE);
exports.writeFloatBE = writeFloat_ieee754.bind(null, writeUintBE);
function readFloat_ieee754(readUint, buf, pos) {
var uint = readUint(buf, pos),
sign = (uint >> 31) * 2 + 1,
exponent = uint >>> 23 & 255,
mantissa = uint & 8388607;
return exponent === 255
? mantissa
? NaN
: sign * Infinity
: exponent === 0 // denormal
? sign * 1.401298464324817e-45 * mantissa
: sign * Math.pow(2, exponent - 150) * (mantissa + 8388608);
}
exports.readFloatLE = readFloat_ieee754.bind(null, readUintLE);
exports.readFloatBE = readFloat_ieee754.bind(null, readUintBE);
})();
// double: typed array
if (typeof Float64Array !== "undefined") (function() {
var f64 = new Float64Array([-0]),
f8b = new Uint8Array(f64.buffer),
le = f8b[7] === 128;
function writeDouble_f64_cpy(val, buf, pos) {
f64[0] = val;
buf[pos ] = f8b[0];
buf[pos + 1] = f8b[1];
buf[pos + 2] = f8b[2];
buf[pos + 3] = f8b[3];
buf[pos + 4] = f8b[4];
buf[pos + 5] = f8b[5];
buf[pos + 6] = f8b[6];
buf[pos + 7] = f8b[7];
}
function writeDouble_f64_rev(val, buf, pos) {
f64[0] = val;
buf[pos ] = f8b[7];
buf[pos + 1] = f8b[6];
buf[pos + 2] = f8b[5];
buf[pos + 3] = f8b[4];
buf[pos + 4] = f8b[3];
buf[pos + 5] = f8b[2];
buf[pos + 6] = f8b[1];
buf[pos + 7] = f8b[0];
}
/* istanbul ignore next */
exports.writeDoubleLE = le ? writeDouble_f64_cpy : writeDouble_f64_rev;
/* istanbul ignore next */
exports.writeDoubleBE = le ? writeDouble_f64_rev : writeDouble_f64_cpy;
function readDouble_f64_cpy(buf, pos) {
f8b[0] = buf[pos ];
f8b[1] = buf[pos + 1];
f8b[2] = buf[pos + 2];
f8b[3] = buf[pos + 3];
f8b[4] = buf[pos + 4];
f8b[5] = buf[pos + 5];
f8b[6] = buf[pos + 6];
f8b[7] = buf[pos + 7];
return f64[0];
}
function readDouble_f64_rev(buf, pos) {
f8b[7] = buf[pos ];
f8b[6] = buf[pos + 1];
f8b[5] = buf[pos + 2];
f8b[4] = buf[pos + 3];
f8b[3] = buf[pos + 4];
f8b[2] = buf[pos + 5];
f8b[1] = buf[pos + 6];
f8b[0] = buf[pos + 7];
return f64[0];
}
/* istanbul ignore next */
exports.readDoubleLE = le ? readDouble_f64_cpy : readDouble_f64_rev;
/* istanbul ignore next */
exports.readDoubleBE = le ? readDouble_f64_rev : readDouble_f64_cpy;
// double: ieee754
})(); else (function() {
function writeDouble_ieee754(writeUint, off0, off1, val, buf, pos) {
var sign = val < 0 ? 1 : 0;
if (sign)
val = -val;
if (val === 0) {
writeUint(0, buf, pos + off0);
writeUint(1 / val > 0 ? /* positive */ 0 : /* negative 0 */ 2147483648, buf, pos + off1);
} else if (isNaN(val)) {
writeUint(0, buf, pos + off0);
writeUint(2146959360, buf, pos + off1);
} else if (val > 1.7976931348623157e+308) { // +-Infinity
writeUint(0, buf, pos + off0);
writeUint((sign << 31 | 2146435072) >>> 0, buf, pos + off1);
} else {
var mantissa;
if (val < 2.2250738585072014e-308) { // denormal
mantissa = val / 5e-324;
writeUint(mantissa >>> 0, buf, pos + off0);
writeUint((sign << 31 | mantissa / 4294967296) >>> 0, buf, pos + off1);
} else {
var exponent = Math.floor(Math.log(val) / Math.LN2);
if (exponent === 1024)
exponent = 1023;
mantissa = val * Math.pow(2, -exponent);
writeUint(mantissa * 4503599627370496 >>> 0, buf, pos + off0);
writeUint((sign << 31 | exponent + 1023 << 20 | mantissa * 1048576 & 1048575) >>> 0, buf, pos + off1);
}
}
}
exports.writeDoubleLE = writeDouble_ieee754.bind(null, writeUintLE, 0, 4);
exports.writeDoubleBE = writeDouble_ieee754.bind(null, writeUintBE, 4, 0);
function readDouble_ieee754(readUint, off0, off1, buf, pos) {
var lo = readUint(buf, pos + off0),
hi = readUint(buf, pos + off1);
var sign = (hi >> 31) * 2 + 1,
exponent = hi >>> 20 & 2047,
mantissa = 4294967296 * (hi & 1048575) + lo;
return exponent === 2047
? mantissa
? NaN
: sign * Infinity
: exponent === 0 // denormal
? sign * 5e-324 * mantissa
: sign * Math.pow(2, exponent - 1075) * (mantissa + 4503599627370496);
}
exports.readDoubleLE = readDouble_ieee754.bind(null, readUintLE, 0, 4);
exports.readDoubleBE = readDouble_ieee754.bind(null, readUintBE, 4, 0);
})();
return exports;
}
// uint helpers
function writeUintLE(val, buf, pos) {
buf[pos ] = val & 255;
buf[pos + 1] = val >>> 8 & 255;
buf[pos + 2] = val >>> 16 & 255;
buf[pos + 3] = val >>> 24;
}
function writeUintBE(val, buf, pos) {
buf[pos ] = val >>> 24;
buf[pos + 1] = val >>> 16 & 255;
buf[pos + 2] = val >>> 8 & 255;
buf[pos + 3] = val & 255;
}
function readUintLE(buf, pos) {
return (buf[pos ]
| buf[pos + 1] << 8
| buf[pos + 2] << 16
| buf[pos + 3] << 24) >>> 0;
}
function readUintBE(buf, pos) {
return (buf[pos ] << 24
| buf[pos + 1] << 16
| buf[pos + 2] << 8
| buf[pos + 3]) >>> 0;
}
/***/ }),
/***/ "./node_modules/@protobufjs/inquire/index.js":
/*!***************************************************!*\
!*** ./node_modules/@protobufjs/inquire/index.js ***!
\***************************************************/
/***/ ((module) => {
"use strict";
module.exports = inquire;
/**
* Requires a module only if available.
* @memberof util
* @param {string} moduleName Module to require
* @returns {?Object} Required module if available and not empty, otherwise `null`
*/
function inquire(moduleName) {
try {
var mod = eval("quire".replace(/^/,"re"))(moduleName); // eslint-disable-line no-eval
if (mod && (mod.length || Object.keys(mod).length))
return mod;
} catch (e) {} // eslint-disable-line no-empty
return null;
}
/***/ }),
/***/ "./node_modules/@protobufjs/pool/index.js":
/*!************************************************!*\
!*** ./node_modules/@protobufjs/pool/index.js ***!
\************************************************/
/***/ ((module) => {
"use strict";
module.exports = pool;
/**
* An allocator as used by {@link util.pool}.
* @typedef PoolAllocator
* @type {function}
* @param {number} size Buffer size
* @returns {Uint8Array} Buffer
*/
/**
* A slicer as used by {@link util.pool}.
* @typedef PoolSlicer
* @type {function}
* @param {number} start Start offset
* @param {number} end End offset
* @returns {Uint8Array} Buffer slice
* @this {Uint8Array}
*/
/**
* A general purpose buffer pool.
* @memberof util
* @function
* @param {PoolAllocator} alloc Allocator
* @param {PoolSlicer} slice Slicer
* @param {number} [size=8192] Slab size
* @returns {PoolAllocator} Pooled allocator
*/
function pool(alloc, slice, size) {
var SIZE = size || 8192;
var MAX = SIZE >>> 1;
var slab = null;
var offset = SIZE;
return function pool_alloc(size) {
if (size < 1 || size > MAX)
return alloc(size);
if (offset + size > SIZE) {
slab = alloc(SIZE);
offset = 0;
}
var buf = slice.call(slab, offset, offset += size);
if (offset & 7) // align to 32 bit
offset = (offset | 7) + 1;
return buf;
};
}
/***/ }),
/***/ "./node_modules/@protobufjs/utf8/index.js":
/*!************************************************!*\
!*** ./node_modules/@protobufjs/utf8/index.js ***!
\************************************************/
/***/ ((__unused_webpack_module, exports) => {
"use strict";
/**
* A minimal UTF8 implementation for number arrays.
* @memberof util
* @namespace
*/
var utf8 = exports;
/**
* Calculates the UTF8 byte length of a string.
* @param {string} string String
* @returns {number} Byte length
*/
utf8.length = function utf8_length(string) {
var len = 0,
c = 0;
for (var i = 0; i < string.length; ++i) {
c = string.charCodeAt(i);
if (c < 128)
len += 1;
else if (c < 2048)
len += 2;
else if ((c & 0xFC00) === 0xD800 && (string.charCodeAt(i + 1) & 0xFC00) === 0xDC00) {
++i;
len += 4;
} else
len += 3;
}
return len;
};
/**
* Reads UTF8 bytes as a string.
* @param {Uint8Array} buffer Source buffer
* @param {number} start Source start
* @param {number} end Source end
* @returns {string} String read
*/
utf8.read = function utf8_read(buffer, start, end) {
var len = end - start;
if (len < 1)
return "";
var parts = null,
chunk = [],
i = 0, // char offset
t; // temporary
while (start < end) {
t = buffer[start++];
if (t < 128)
chunk[i++] = t;
else if (t > 191 && t < 224)
chunk[i++] = (t & 31) << 6 | buffer[start++] & 63;
else if (t > 239 && t < 365) {
t = ((t & 7) << 18 | (buffer[start++] & 63) << 12 | (buffer[start++] & 63) << 6 | buffer[start++] & 63) - 0x10000;
chunk[i++] = 0xD800 + (t >> 10);
chunk[i++] = 0xDC00 + (t & 1023);
} else
chunk[i++] = (t & 15) << 12 | (buffer[start++] & 63) << 6 | buffer[start++] & 63;
if (i > 8191) {
(parts || (parts = [])).push(String.fromCharCode.apply(String, chunk));
i = 0;
}
}
if (parts) {
if (i)
parts.push(String.fromCharCode.apply(String, chunk.slice(0, i)));
return parts.join("");
}
return String.fromCharCode.apply(String, chunk.slice(0, i));
};
/**
* Writes a string as UTF8 bytes.
* @param {string} string Source string
* @param {Uint8Array} buffer Destination buffer
* @param {number} offset Destination offset
* @returns {number} Bytes written
*/
utf8.write = function utf8_write(string, buffer, offset) {
var start = offset,
c1, // character 1
c2; // character 2
for (var i = 0; i < string.length; ++i) {
c1 = string.charCodeAt(i);
if (c1 < 128) {
buffer[offset++] = c1;
} else if (c1 < 2048) {
buffer[offset++] = c1 >> 6 | 192;
buffer[offset++] = c1 & 63 | 128;
} else if ((c1 & 0xFC00) === 0xD800 && ((c2 = string.charCodeAt(i + 1)) & 0xFC00) === 0xDC00) {
c1 = 0x10000 + ((c1 & 0x03FF) << 10) + (c2 & 0x03FF);
++i;
buffer[offset++] = c1 >> 18 | 240;
buffer[offset++] = c1 >> 12 & 63 | 128;
buffer[offset++] = c1 >> 6 & 63 | 128;
buffer[offset++] = c1 & 63 | 128;
} else {
buffer[offset++] = c1 >> 12 | 224;
buffer[offset++] = c1 >> 6 & 63 | 128;
buffer[offset++] = c1 & 63 | 128;
}
}
return offset - start;
};
/***/ }),
/***/ "./node_modules/guid-typescript/dist/guid.js":
/*!***************************************************!*\
!*** ./node_modules/guid-typescript/dist/guid.js ***!
\***************************************************/
/***/ ((__unused_webpack_module, exports) => {
"use strict";
exports.__esModule = true;
var Guid = /** @class */ (function () {
function Guid(guid) {
if (!guid) {
throw new TypeError("Invalid argument; `value` has no value.");
}
this.value = Guid.EMPTY;
if (guid && Guid.isGuid(guid)) {
this.value = guid;
}
}
Guid.isGuid = function (guid) {
var value = guid.toString();
return guid && (guid instanceof Guid || Guid.validator.test(value));
};
Guid.create = function () {
return new Guid([Guid.gen(2), Guid.gen(1), Guid.gen(1), Guid.gen(1), Guid.gen(3)].join("-"));
};
Guid.createEmpty = function () {
return new Guid("emptyguid");
};
Guid.parse = function (guid) {
return new Guid(guid);
};
Guid.raw = function () {
return [Guid.gen(2), Guid.gen(1), Guid.gen(1), Guid.gen(1), Guid.gen(3)].join("-");
};
Guid.gen = function (count) {
var out = "";
for (var i = 0; i < count; i++) {
// tslint:disable-next-line:no-bitwise
out += (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
}
return out;
};
Guid.prototype.equals = function (other) {
// Comparing string `value` against provided `guid` will auto-call
// toString on `guid` for comparison
return Guid.isGuid(other) && this.value === other.toString();
};
Guid.prototype.isEmpty = function () {
return this.value === Guid.EMPTY;
};
Guid.prototype.toString = function () {
return this.value;
};
Guid.prototype.toJSON = function () {
return {
value: this.value
};
};
Guid.validator = new RegExp("^[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}$", "i");
Guid.EMPTY = "00000000-0000-0000-0000-000000000000";
return Guid;
}());
exports.Guid = Guid;
/***/ }),
/***/ "./node_modules/long/src/long.js":
/*!***************************************!*\
!*** ./node_modules/long/src/long.js ***!
\***************************************/
/***/ ((module) => {
module.exports = Long;
/**
* wasm optimizations, to do native i64 multiplication and divide
*/
var wasm = null;
try {
wasm = new WebAssembly.Instance(new WebAssembly.Module(new Uint8Array([
0, 97, 115, 109, 1, 0, 0, 0, 1, 13, 2, 96, 0, 1, 127, 96, 4, 127, 127, 127, 127, 1, 127, 3, 7, 6, 0, 1, 1, 1, 1, 1, 6, 6, 1, 127, 1, 65, 0, 11, 7, 50, 6, 3, 109, 117, 108, 0, 1, 5, 100, 105, 118, 95, 115, 0, 2, 5, 100, 105, 118, 95, 117, 0, 3, 5, 114, 101, 109, 95, 115, 0, 4, 5, 114, 101, 109, 95, 117, 0, 5, 8, 103, 101, 116, 95, 104, 105, 103, 104, 0, 0, 10, 191, 1, 6, 4, 0, 35, 0, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 126, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 127, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 128, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 129, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 130, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11
])), {}).exports;
} catch (e) {
// no wasm support :(
}
/**
* Constructs a 64 bit two's-complement integer, given its low and high 32 bit values as *signed* integers.
* See the from* functions below for more convenient ways of constructing Longs.
* @exports Long
* @class A Long class for representing a 64 bit two's-complement integer value.
* @param {number} low The low (signed) 32 bits of the long
* @param {number} high The high (signed) 32 bits of the long
* @param {boolean=} unsigned Whether unsigned or not, defaults to signed
* @constructor
*/
function Long(low, high, unsigned) {
/**
* The low 32 bits as a signed value.
* @type {number}
*/
this.low = low | 0;
/**
* The high 32 bits as a signed value.
* @type {number}
*/
this.high = high | 0;
/**
* Whether unsigned or not.
* @type {boolean}
*/
this.unsigned = !!unsigned;
}
// The internal representation of a long is the two given signed, 32-bit values.
// We use 32-bit pieces because these are the size of integers on which
// Javascript performs bit-operations. For operations like addition and
// multiplication, we split each number into 16 bit pieces, which can easily be
// multiplied within Javascript's floating-point representation without overflow
// or change in sign.
//
// In the algorithms below, we frequently reduce the negative case to the
// positive case by negating the input(s) and then post-processing the result.
// Note that we must ALWAYS check specially whether those values are MIN_VALUE
// (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as
// a positive number, it overflows back into a negative). Not handling this
// case would often result in infinite recursion.
//
// Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the from*
// methods on which they depend.
/**
* An indicator used to reliably determine if an object is a Long or not.
* @type {boolean}
* @const
* @private
*/
Long.prototype.__isLong__;
Object.defineProperty(Long.prototype, "__isLong__", { value: true });
/**
* @function
* @param {*} obj Object
* @returns {boolean}
* @inner
*/
function isLong(obj) {
return (obj && obj["__isLong__"]) === true;
}
/**
* Tests if the specified object is a Long.
* @function
* @param {*} obj Object
* @returns {boolean}
*/
Long.isLong = isLong;
/**
* A cache of the Long representations of small integer values.
* @type {!Object}
* @inner
*/
var INT_CACHE = {};
/**
* A cache of the Long representations of small unsigned integer values.
* @type {!Object}
* @inner
*/
var UINT_CACHE = {};
/**
* @param {number} value
* @param {boolean=} unsigned
* @returns {!Long}
* @inner
*/
function fromInt(value, unsigned) {
var obj, cachedObj, cache;
if (unsigned) {
value >>>= 0;
if (cache = (0 <= value && value < 256)) {
cachedObj = UINT_CACHE[value];
if (cachedObj)
return cachedObj;
}
obj = fromBits(value, (value | 0) < 0 ? -1 : 0, true);
if (cache)
UINT_CACHE[value] = obj;
return obj;
} else {
value |= 0;
if (cache = (-128 <= value && value < 128)) {
cachedObj = INT_CACHE[value];
if (cachedObj)
return cachedObj;
}
obj = fromBits(value, value < 0 ? -1 : 0, false);
if (cache)
INT_CACHE[value] = obj;
return obj;
}
}
/**
* Returns a Long representing the given 32 bit integer value.
* @function
* @param {number} value The 32 bit integer in question
* @param {boolean=} unsigned Whether unsigned or not, defaults to signed
* @returns {!Long} The corresponding Long value
*/
Long.fromInt = fromInt;
/**
* @param {number} value
* @param {boolean=} unsigned
* @returns {!Long}
* @inner
*/
function fromNumber(value, unsigned) {
if (isNaN(value))
return unsigned ? UZERO : ZERO;
if (unsigned) {
if (value < 0)
return UZERO;
if (value >= TWO_PWR_64_DBL)
return MAX_UNSIGNED_VALUE;
} else {
if (value <= -TWO_PWR_63_DBL)
return MIN_VALUE;
if (value + 1 >= TWO_PWR_63_DBL)
return MAX_VALUE;
}
if (value < 0)
return fromNumber(-value, unsigned).neg();
return fromBits((value % TWO_PWR_32_DBL) | 0, (value / TWO_PWR_32_DBL) | 0, unsigned);
}
/**
* Returns a Long representing the given value, provided that it is a finite number. Otherwise, zero is returned.
* @function
* @param {number} value The number in question
* @param {boolean=} unsigned Whether unsigned or not, defaults to signed
* @returns {!Long} The corresponding Long value
*/
Long.fromNumber = fromNumber;
/**
* @param {number} lowBits
* @param {number} highBits
* @param {boolean=} unsigned
* @returns {!Long}
* @inner
*/
function fromBits(lowBits, highBits, unsigned) {
return new Long(lowBits, highBits, unsigned);
}
/**
* Returns a Long representing the 64 bit integer that comes by concatenating the given low and high bits. Each is
* assumed to use 32 bits.
* @function
* @param {number} lowBits The low 32 bits
* @param {number} highBits The high 32 bits
* @param {boolean=} unsigned Whether unsigned or not, defaults to signed
* @returns {!Long} The corresponding Long value
*/
Long.fromBits = fromBits;
/**
* @function
* @param {number} base
* @param {number} exponent
* @returns {number}
* @inner
*/
var pow_dbl = Math.pow; // Used 4 times (4*8 to 15+4)
/**
* @param {string} str
* @param {(boolean|number)=} unsigned
* @param {number=} radix
* @returns {!Long}
* @inner
*/
function fromString(str, unsigned, radix) {
if (str.length === 0)
throw Error('empty string');
if (str === "NaN" || str === "Infinity" || str === "+Infinity" || str === "-Infinity")
return ZERO;
if (typeof unsigned === 'number') {
// For goog.math.long compatibility
radix = unsigned,
unsigned = false;
} else {
unsigned = !! unsigned;
}
radix = radix || 10;
if (radix < 2 || 36 < radix)
throw RangeError('radix');
var p;
if ((p = str.indexOf('-')) > 0)
throw Error('interior hyphen');
else if (p === 0) {
return fromString(str.substring(1), unsigned, radix).neg();
}
// Do several (8) digits each time through the loop, so as to
// minimize the calls to the very expensive emulated div.
var radixToPower = fromNumber(pow_dbl(radix, 8));
var result = ZERO;
for (var i = 0; i < str.length; i += 8) {
var size = Math.min(8, str.length - i),
value = parseInt(str.substring(i, i + size), radix);
if (size < 8) {
var power = fromNumber(pow_dbl(radix, size));
result = result.mul(power).add(fromNumber(value));
} else {
result = result.mul(radixToPower);
result = result.add(fromNumber(value));
}
}
result.unsigned = unsigned;
return result;
}
/**
* Returns a Long representation of the given string, written using the specified radix.
* @function
* @param {string} str The textual representation of the Long
* @param {(boolean|number)=} unsigned Whether unsigned or not, defaults to signed
* @param {number=} radix The radix in which the text is written (2-36), defaults to 10
* @returns {!Long} The corresponding Long value
*/
Long.fromString = fromString;
/**
* @function
* @param {!Long|number|string|!{low: number, high: number, unsigned: boolean}} val
* @param {boolean=} unsigned
* @returns {!Long}
* @inner
*/
function fromValue(val, unsigned) {
if (typeof val === 'number')
return fromNumber(val, unsigned);
if (typeof val === 'string')
return fromString(val, unsigned);
// Throws for non-objects, converts non-instanceof Long:
return fromBits(val.low, val.high, typeof unsigned === 'boolean' ? unsigned : val.unsigned);
}
/**
* Converts the specified value to a Long using the appropriate from* function for its type.
* @function
* @param {!Long|number|string|!{low: number, high: number, unsigned: boolean}} val Value
* @param {boolean=} unsigned Whether unsigned or not, defaults to signed
* @returns {!Long}
*/
Long.fromValue = fromValue;
// NOTE: the compiler should inline these constant values below and then remove these variables, so there should be
// no runtime penalty for these.
/**
* @type {number}
* @const
* @inner
*/
var TWO_PWR_16_DBL = 1 << 16;
/**
* @type {number}
* @const
* @inner
*/
var TWO_PWR_24_DBL = 1 << 24;
/**
* @type {number}
* @const
* @inner
*/
var TWO_PWR_32_DBL = TWO_PWR_16_DBL * TWO_PWR_16_DBL;
/**
* @type {number}
* @const
* @inner
*/
var TWO_PWR_64_DBL = TWO_PWR_32_DBL * TWO_PWR_32_DBL;
/**
* @type {number}
* @const
* @inner
*/
var TWO_PWR_63_DBL = TWO_PWR_64_DBL / 2;
/**
* @type {!Long}
* @const
* @inner
*/
var TWO_PWR_24 = fromInt(TWO_PWR_24_DBL);
/**
* @type {!Long}
* @inner
*/
var ZERO = fromInt(0);
/**
* Signed zero.
* @type {!Long}
*/
Long.ZERO = ZERO;
/**
* @type {!Long}
* @inner
*/
var UZERO = fromInt(0, true);
/**
* Unsigned zero.
* @type {!Long}
*/
Long.UZERO = UZERO;
/**
* @type {!Long}
* @inner
*/
var ONE = fromInt(1);
/**
* Signed one.
* @type {!Long}
*/
Long.ONE = ONE;
/**
* @type {!Long}
* @inner
*/
var UONE = fromInt(1, true);
/**
* Unsigned one.
* @type {!Long}
*/
Long.UONE = UONE;
/**
* @type {!Long}
* @inner
*/
var NEG_ONE = fromInt(-1);
/**
* Signed negative one.
* @type {!Long}
*/
Long.NEG_ONE = NEG_ONE;
/**
* @type {!Long}
* @inner
*/
var MAX_VALUE = fromBits(0xFFFFFFFF|0, 0x7FFFFFFF|0, false);
/**
* Maximum signed value.
* @type {!Long}
*/
Long.MAX_VALUE = MAX_VALUE;
/**
* @type {!Long}
* @inner
*/
var MAX_UNSIGNED_VALUE = fromBits(0xFFFFFFFF|0, 0xFFFFFFFF|0, true);
/**
* Maximum unsigned value.
* @type {!Long}
*/
Long.MAX_UNSIGNED_VALUE = MAX_UNSIGNED_VALUE;
/**
* @type {!Long}
* @inner
*/
var MIN_VALUE = fromBits(0, 0x80000000|0, false);
/**
* Minimum signed value.
* @type {!Long}
*/
Long.MIN_VALUE = MIN_VALUE;
/**
* @alias Long.prototype
* @inner
*/
var LongPrototype = Long.prototype;
/**
* Converts the Long to a 32 bit integer, assuming it is a 32 bit integer.
* @returns {number}
*/
LongPrototype.toInt = function toInt() {
return this.unsigned ? this.low >>> 0 : this.low;
};
/**
* Converts the Long to a the nearest floating-point representation of this value (double, 53 bit mantissa).
* @returns {number}
*/
LongPrototype.toNumber = function toNumber() {
if (this.unsigned)
return ((this.high >>> 0) * TWO_PWR_32_DBL) + (this.low >>> 0);
return this.high * TWO_PWR_32_DBL + (this.low >>> 0);
};
/**
* Converts the Long to a string written in the specified radix.
* @param {number=} radix Radix (2-36), defaults to 10
* @returns {string}
* @override
* @throws {RangeError} If `radix` is out of range
*/
LongPrototype.toString = function toString(radix) {
radix = radix || 10;
if (radix < 2 || 36 < radix)
throw RangeError('radix');
if (this.isZero())
return '0';
if (this.isNegative()) { // Unsigned Longs are never negative
if (this.eq(MIN_VALUE)) {
// We need to change the Long value before it can be negated, so we remove
// the bottom-most digit in this base and then recurse to do the rest.
var radixLong = fromNumber(radix),
div = this.div(radixLong),
rem1 = div.mul(radixLong).sub(this);
return div.toString(radix) + rem1.toInt().toString(radix);
} else
return '-' + this.neg().toString(radix);
}
// Do several (6) digits each time through the loop, so as to
// minimize the calls to the very expensive emulated div.
var radixToPower = fromNumber(pow_dbl(radix, 6), this.unsigned),
rem = this;
var result = '';
while (true) {
var remDiv = rem.div(radixToPower),
intval = rem.sub(remDiv.mul(radixToPower)).toInt() >>> 0,
digits = intval.toString(radix);
rem = remDiv;
if (rem.isZero())
return digits + result;
else {
while (digits.length < 6)
digits = '0' + digits;
result = '' + digits + result;
}
}
};
/**
* Gets the high 32 bits as a signed integer.
* @returns {number} Signed high bits
*/
LongPrototype.getHighBits = function getHighBits() {
return this.high;
};
/**
* Gets the high 32 bits as an unsigned integer.
* @returns {number} Unsigned high bits
*/
LongPrototype.getHighBitsUnsigned = function getHighBitsUnsigned() {
return this.high >>> 0;
};
/**
* Gets the low 32 bits as a signed integer.
* @returns {number} Signed low bits
*/
LongPrototype.getLowBits = function getLowBits() {
return this.low;
};
/**
* Gets the low 32 bits as an unsigned integer.
* @returns {number} Unsigned low bits
*/
LongPrototype.getLowBitsUnsigned = function getLowBitsUnsigned() {
return this.low >>> 0;
};
/**
* Gets the number of bits needed to represent the absolute value of this Long.
* @returns {number}
*/
LongPrototype.getNumBitsAbs = function getNumBitsAbs() {
if (this.isNegative()) // Unsigned Longs are never negative
return this.eq(MIN_VALUE) ? 64 : this.neg().getNumBitsAbs();
var val = this.high != 0 ? this.high : this.low;
for (var bit = 31; bit > 0; bit--)
if ((val & (1 << bit)) != 0)
break;
return this.high != 0 ? bit + 33 : bit + 1;
};
/**
* Tests if this Long's value equals zero.
* @returns {boolean}
*/
LongPrototype.isZero = function isZero() {
return this.high === 0 && this.low === 0;
};
/**
* Tests if this Long's value equals zero. This is an alias of {@link Long#isZero}.
* @returns {boolean}
*/
LongPrototype.eqz = LongPrototype.isZero;
/**
* Tests if this Long's value is negative.
* @returns {boolean}
*/
LongPrototype.isNegative = function isNegative() {
return !this.unsigned && this.high < 0;
};
/**
* Tests if this Long's value is positive.
* @returns {boolean}
*/
LongPrototype.isPositive = function isPositive() {
return this.unsigned || this.high >= 0;
};
/**
* Tests if this Long's value is odd.
* @returns {boolean}
*/
LongPrototype.isOdd = function isOdd() {
return (this.low & 1) === 1;
};
/**
* Tests if this Long's value is even.
* @returns {boolean}
*/
LongPrototype.isEven = function isEven() {
return (this.low & 1) === 0;
};
/**
* Tests if this Long's value equals the specified's.
* @param {!Long|number|string} other Other value
* @returns {boolean}
*/
LongPrototype.equals = function equals(other) {
if (!isLong(other))
other = fromValue(other);
if (this.unsigned !== other.unsigned && (this.high >>> 31) === 1 && (other.high >>> 31) === 1)
return false;
return this.high === other.high && this.low === other.low;
};
/**
* Tests if this Long's value equals the specified's. This is an alias of {@link Long#equals}.
* @function
* @param {!Long|number|string} other Other value
* @returns {boolean}
*/
LongPrototype.eq = LongPrototype.equals;
/**
* Tests if this Long's value differs from the specified's.
* @param {!Long|number|string} other Other value
* @returns {boolean}
*/
LongPrototype.notEquals = function notEquals(other) {
return !this.eq(/* validates */ other);
};
/**
* Tests if this Long's value differs from the specified's. This is an alias of {@link Long#notEquals}.
* @function
* @param {!Long|number|string} other Other value
* @returns {boolean}
*/
LongPrototype.neq = LongPrototype.notEquals;
/**
* Tests if this Long's value differs from the specified's. This is an alias of {@link Long#notEquals}.
* @function
* @param {!Long|number|string} other Other value
* @returns {boolean}
*/
LongPrototype.ne = LongPrototype.notEquals;
/**
* Tests if this Long's value is less than the specified's.
* @param {!Long|number|string} other Other value
* @returns {boolean}
*/
LongPrototype.lessThan = function lessThan(other) {
return this.comp(/* validates */ other) < 0;
};
/**
* Tests if this Long's value is less than the specified's. This is an alias of {@link Long#lessThan}.
* @function
* @param {!Long|number|string} other Other value
* @returns {boolean}
*/
LongPrototype.lt = LongPrototype.lessThan;
/**
* Tests if this Long's value is less than or equal the specified's.
* @param {!Long|number|string} other Other value
* @returns {boolean}
*/
LongPrototype.lessThanOrEqual = function lessThanOrEqual(other) {
return this.comp(/* validates */ other) <= 0;
};
/**
* Tests if this Long's value is less than or equal the specified's. This is an alias of {@link Long#lessThanOrEqual}.
* @function
* @param {!Long|number|string} other Other value
* @returns {boolean}
*/
LongPrototype.lte = LongPrototype.lessThanOrEqual;
/**
* Tests if this Long's value is less than or equal the specified's. This is an alias of {@link Long#lessThanOrEqual}.
* @function
* @param {!Long|number|string} other Other value
* @returns {boolean}
*/
LongPrototype.le = LongPrototype.lessThanOrEqual;
/**
* Tests if this Long's value is greater than the specified's.
* @param {!Long|number|string} other Other value
* @returns {boolean}
*/
LongPrototype.greaterThan = function greaterThan(other) {
return this.comp(/* validates */ other) > 0;
};
/**
* Tests if this Long's value is greater than the specified's. This is an alias of {@link Long#greaterThan}.
* @function
* @param {!Long|number|string} other Other value
* @returns {boolean}
*/
LongPrototype.gt = LongPrototype.greaterThan;
/**
* Tests if this Long's value is greater than or equal the specified's.
* @param {!Long|number|string} other Other value
* @returns {boolean}
*/
LongPrototype.greaterThanOrEqual = function greaterThanOrEqual(other) {
return this.comp(/* validates */ other) >= 0;
};
/**
* Tests if this Long's value is greater than or equal the specified's. This is an alias of {@link Long#greaterThanOrEqual}.
* @function
* @param {!Long|number|string} other Other value
* @returns {boolean}
*/
LongPrototype.gte = LongPrototype.greaterThanOrEqual;
/**
* Tests if this Long's value is greater than or equal the specified's. This is an alias of {@link Long#greaterThanOrEqual}.
* @function
* @param {!Long|number|string} other Other value
* @returns {boolean}
*/
LongPrototype.ge = LongPrototype.greaterThanOrEqual;
/**
* Compares this Long's value with the specified's.
* @param {!Long|number|string} other Other value
* @returns {number} 0 if they are the same, 1 if the this is greater and -1
* if the given one is greater
*/
LongPrototype.compare = function compare(other) {
if (!isLong(other))
other = fromValue(other);
if (this.eq(other))
return 0;
var thisNeg = this.isNegative(),
otherNeg = other.isNegative();
if (thisNeg && !otherNeg)
return -1;
if (!thisNeg && otherNeg)
return 1;
// At this point the sign bits are the same
if (!this.unsigned)
return this.sub(other).isNegative() ? -1 : 1;
// Both are positive if at least one is unsigned
return (other.high >>> 0) > (this.high >>> 0) || (other.high === this.high && (other.low >>> 0) > (this.low >>> 0)) ? -1 : 1;
};
/**
* Compares this Long's value with the specified's. This is an alias of {@link Long#compare}.
* @function
* @param {!Long|number|string} other Other value
* @returns {number} 0 if they are the same, 1 if the this is greater and -1
* if the given one is greater
*/
LongPrototype.comp = LongPrototype.compare;
/**
* Negates this Long's value.
* @returns {!Long} Negated Long
*/
LongPrototype.negate = function negate() {
if (!this.unsigned && this.eq(MIN_VALUE))
return MIN_VALUE;
return this.not().add(ONE);
};
/**
* Negates this Long's value. This is an alias of {@link Long#negate}.
* @function
* @returns {!Long} Negated Long
*/
LongPrototype.neg = LongPrototype.negate;
/**
* Returns the sum of this and the specified Long.
* @param {!Long|number|string} addend Addend
* @returns {!Long} Sum
*/
LongPrototype.add = function add(addend) {
if (!isLong(addend))
addend = fromValue(addend);
// Divide each number into 4 chunks of 16 bits, and then sum the chunks.
var a48 = this.high >>> 16;
var a32 = this.high & 0xFFFF;
var a16 = this.low >>> 16;
var a00 = this.low & 0xFFFF;
var b48 = addend.high >>> 16;
var b32 = addend.high & 0xFFFF;
var b16 = addend.low >>> 16;
var b00 = addend.low & 0xFFFF;
var c48 = 0, c32 = 0, c16 = 0, c00 = 0;
c00 += a00 + b00;
c16 += c00 >>> 16;
c00 &= 0xFFFF;
c16 += a16 + b16;
c32 += c16 >>> 16;
c16 &= 0xFFFF;
c32 += a32 + b32;
c48 += c32 >>> 16;
c32 &= 0xFFFF;
c48 += a48 + b48;
c48 &= 0xFFFF;
return fromBits((c16 << 16) | c00, (c48 << 16) | c32, this.unsigned);
};
/**
* Returns the difference of this and the specified Long.
* @param {!Long|number|string} subtrahend Subtrahend
* @returns {!Long} Difference
*/
LongPrototype.subtract = function subtract(subtrahend) {
if (!isLong(subtrahend))
subtrahend = fromValue(subtrahend);
return this.add(subtrahend.neg());
};
/**
* Returns the difference of this and the specified Long. This is an alias of {@link Long#subtract}.
* @function
* @param {!Long|number|string} subtrahend Subtrahend
* @returns {!Long} Difference
*/
LongPrototype.sub = LongPrototype.subtract;
/**
* Returns the product of this and the specified Long.
* @param {!Long|number|string} multiplier Multiplier
* @returns {!Long} Product
*/
LongPrototype.multiply = function multiply(multiplier) {
if (this.isZero())
return ZERO;
if (!isLong(multiplier))
multiplier = fromValue(multiplier);
// use wasm support if present
if (wasm) {
var low = wasm.mul(this.low,
this.high,
multiplier.low,
multiplier.high);
return fromBits(low, wasm.get_high(), this.unsigned);
}
if (multiplier.isZero())
return ZERO;
if (this.eq(MIN_VALUE))
return multiplier.isOdd() ? MIN_VALUE : ZERO;
if (multiplier.eq(MIN_VALUE))
return this.isOdd() ? MIN_VALUE : ZERO;
if (this.isNegative()) {
if (multiplier.isNegative())
return this.neg().mul(multiplier.neg());
else
return this.neg().mul(multiplier).neg();
} else if (multiplier.isNegative())
return this.mul(multiplier.neg()).neg();
// If both longs are small, use float multiplication
if (this.lt(TWO_PWR_24) && multiplier.lt(TWO_PWR_24))
return fromNumber(this.toNumber() * multiplier.toNumber(), this.unsigned);
// Divide each long into 4 chunks of 16 bits, and then add up 4x4 products.
// We can skip products that would overflow.
var a48 = this.high >>> 16;
var a32 = this.high & 0xFFFF;
var a16 = this.low >>> 16;
var a00 = this.low & 0xFFFF;
var b48 = multiplier.high >>> 16;
var b32 = multiplier.high & 0xFFFF;
var b16 = multiplier.low >>> 16;
var b00 = multiplier.low & 0xFFFF;
var c48 = 0, c32 = 0, c16 = 0, c00 = 0;
c00 += a00 * b00;
c16 += c00 >>> 16;
c00 &= 0xFFFF;
c16 += a16 * b00;
c32 += c16 >>> 16;
c16 &= 0xFFFF;
c16 += a00 * b16;
c32 += c16 >>> 16;
c16 &= 0xFFFF;
c32 += a32 * b00;
c48 += c32 >>> 16;
c32 &= 0xFFFF;
c32 += a16 * b16;
c48 += c32 >>> 16;
c32 &= 0xFFFF;
c32 += a00 * b32;
c48 += c32 >>> 16;
c32 &= 0xFFFF;
c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48;
c48 &= 0xFFFF;
return fromBits((c16 << 16) | c00, (c48 << 16) | c32, this.unsigned);
};
/**
* Returns the product of this and the specified Long. This is an alias of {@link Long#multiply}.
* @function
* @param {!Long|number|string} multiplier Multiplier
* @returns {!Long} Product
*/
LongPrototype.mul = LongPrototype.multiply;
/**
* Returns this Long divided by the specified. The result is signed if this Long is signed or
* unsigned if this Long is unsigned.
* @param {!Long|number|string} divisor Divisor
* @returns {!Long} Quotient
*/
LongPrototype.divide = function divide(divisor) {
if (!isLong(divisor))
divisor = fromValue(divisor);
if (divisor.isZero())
throw Error('division by zero');
// use wasm support if present
if (wasm) {
// guard against signed division overflow: the largest
// negative number / -1 would be 1 larger than the largest
// positive number, due to two's complement.
if (!this.unsigned &&
this.high === -0x80000000 &&
divisor.low === -1 && divisor.high === -1) {
// be consistent with non-wasm code path
return this;
}
var low = (this.unsigned ? wasm.div_u : wasm.div_s)(
this.low,
this.high,
divisor.low,
divisor.high
);
return fromBits(low, wasm.get_high(), this.unsigned);
}
if (this.isZero())
return this.unsigned ? UZERO : ZERO;
var approx, rem, res;
if (!this.unsigned) {
// This section is only relevant for signed longs and is derived from the
// closure library as a whole.
if (this.eq(MIN_VALUE)) {
if (divisor.eq(ONE) || divisor.eq(NEG_ONE))
return MIN_VALUE; // recall that -MIN_VALUE == MIN_VALUE
else if (divisor.eq(MIN_VALUE))
return ONE;
else {
// At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|.
var halfThis = this.shr(1);
approx = halfThis.div(divisor).shl(1);
if (approx.eq(ZERO)) {
return divisor.isNegative() ? ONE : NEG_ONE;
} else {
rem = this.sub(divisor.mul(approx));
res = approx.add(rem.div(divisor));
return res;
}
}
} else if (divisor.eq(MIN_VALUE))
return this.unsigned ? UZERO : ZERO;
if (this.isNegative()) {
if (divisor.isNegative())
return this.neg().div(divisor.neg());
return this.neg().div(divisor).neg();
} else if (divisor.isNegative())
return this.div(divisor.neg()).neg();
res = ZERO;
} else {
// The algorithm below has not been made for unsigned longs. It's therefore
// required to take special care of the MSB prior to running it.
if (!divisor.unsigned)
divisor = divisor.toUnsigned();
if (divisor.gt(this))
return UZERO;
if (divisor.gt(this.shru(1))) // 15 >>> 1 = 7 ; with divisor = 8 ; true
return UONE;
res = UZERO;
}
// Repeat the following until the remainder is less than other: find a
// floating-point that approximates remainder / other *from below*, add this
// into the result, and subtract it from the remainder. It is critical that
// the approximate value is less than or equal to the real value so that the
// remainder never becomes negative.
rem = this;
while (rem.gte(divisor)) {
// Approximate the result of division. This may be a little greater or
// smaller than the actual value.
approx = Math.max(1, Math.floor(rem.toNumber() / divisor.toNumber()));
// We will tweak the approximate result by changing it in the 48-th digit or
// the smallest non-fractional digit, whichever is larger.
var log2 = Math.ceil(Math.log(approx) / Math.LN2),
delta = (log2 <= 48) ? 1 : pow_dbl(2, log2 - 48),
// Decrease the approximation until it is smaller than the remainder. Note
// that if it is too large, the product overflows and is negative.
approxRes = fromNumber(approx),
approxRem = approxRes.mul(divisor);
while (approxRem.isNegative() || approxRem.gt(rem)) {
approx -= delta;
approxRes = fromNumber(approx, this.unsigned);
approxRem = approxRes.mul(divisor);
}
// We know the answer can't be zero... and actually, zero would cause
// infinite recursion since we would make no progress.
if (approxRes.isZero())
approxRes = ONE;
res = res.add(approxRes);
rem = rem.sub(approxRem);
}
return res;
};
/**
* Returns this Long divided by the specified. This is an alias of {@link Long#divide}.
* @function
* @param {!Long|number|string} divisor Divisor
* @returns {!Long} Quotient
*/
LongPrototype.div = LongPrototype.divide;
/**
* Returns this Long modulo the specified.
* @param {!Long|number|string} divisor Divisor
* @returns {!Long} Remainder
*/
LongPrototype.modulo = function modulo(divisor) {
if (!isLong(divisor))
divisor = fromValue(divisor);
// use wasm support if present
if (wasm) {
var low = (this.unsigned ? wasm.rem_u : wasm.rem_s)(
this.low,
this.high,
divisor.low,
divisor.high
);
return fromBits(low, wasm.get_high(), this.unsigned);
}
return this.sub(this.div(divisor).mul(divisor));
};
/**
* Returns this Long modulo the specified. This is an alias of {@link Long#modulo}.
* @function
* @param {!Long|number|string} divisor Divisor
* @returns {!Long} Remainder
*/
LongPrototype.mod = LongPrototype.modulo;
/**
* Returns this Long modulo the specified. This is an alias of {@link Long#modulo}.
* @function
* @param {!Long|number|string} divisor Divisor
* @returns {!Long} Remainder
*/
LongPrototype.rem = LongPrototype.modulo;
/**
* Returns the bitwise NOT of this Long.
* @returns {!Long}
*/
LongPrototype.not = function not() {
return fromBits(~this.low, ~this.high, this.unsigned);
};
/**
* Returns the bitwise AND of this Long and the specified.
* @param {!Long|number|string} other Other Long
* @returns {!Long}
*/
LongPrototype.and = function and(other) {
if (!isLong(other))
other = fromValue(other);
return fromBits(this.low & other.low, this.high & other.high, this.unsigned);
};
/**
* Returns the bitwise OR of this Long and the specified.
* @param {!Long|number|string} other Other Long
* @returns {!Long}
*/
LongPrototype.or = function or(other) {
if (!isLong(other))
other = fromValue(other);
return fromBits(this.low | other.low, this.high | other.high, this.unsigned);
};
/**
* Returns the bitwise XOR of this Long and the given one.
* @param {!Long|number|string} other Other Long
* @returns {!Long}
*/
LongPrototype.xor = function xor(other) {
if (!isLong(other))
other = fromValue(other);
return fromBits(this.low ^ other.low, this.high ^ other.high, this.unsigned);
};
/**
* Returns this Long with bits shifted to the left by the given amount.
* @param {number|!Long} numBits Number of bits
* @returns {!Long} Shifted Long
*/
LongPrototype.shiftLeft = function shiftLeft(numBits) {
if (isLong(numBits))
numBits = numBits.toInt();
if ((numBits &= 63) === 0)
return this;
else if (numBits < 32)
return fromBits(this.low << numBits, (this.high << numBits) | (this.low >>> (32 - numBits)), this.unsigned);
else
return fromBits(0, this.low << (numBits - 32), this.unsigned);
};
/**
* Returns this Long with bits shifted to the left by the given amount. This is an alias of {@link Long#shiftLeft}.
* @function
* @param {number|!Long} numBits Number of bits
* @returns {!Long} Shifted Long
*/
LongPrototype.shl = LongPrototype.shiftLeft;
/**
* Returns this Long with bits arithmetically shifted to the right by the given amount.
* @param {number|!Long} numBits Number of bits
* @returns {!Long} Shifted Long
*/
LongPrototype.shiftRight = function shiftRight(numBits) {
if (isLong(numBits))
numBits = numBits.toInt();
if ((numBits &= 63) === 0)
return this;
else if (numBits < 32)
return fromBits((this.low >>> numBits) | (this.high << (32 - numBits)), this.high >> numBits, this.unsigned);
else
return fromBits(this.high >> (numBits - 32), this.high >= 0 ? 0 : -1, this.unsigned);
};
/**
* Returns this Long with bits arithmetically shifted to the right by the given amount. This is an alias of {@link Long#shiftRight}.
* @function
* @param {number|!Long} numBits Number of bits
* @returns {!Long} Shifted Long
*/
LongPrototype.shr = LongPrototype.shiftRight;
/**
* Returns this Long with bits logically shifted to the right by the given amount.
* @param {number|!Long} numBits Number of bits
* @returns {!Long} Shifted Long
*/
LongPrototype.shiftRightUnsigned = function shiftRightUnsigned(numBits) {
if (isLong(numBits))
numBits = numBits.toInt();
numBits &= 63;
if (numBits === 0)
return this;
else {
var high = this.high;
if (numBits < 32) {
var low = this.low;
return fromBits((low >>> numBits) | (high << (32 - numBits)), high >>> numBits, this.unsigned);
} else if (numBits === 32)
return fromBits(high, 0, this.unsigned);
else
return fromBits(high >>> (numBits - 32), 0, this.unsigned);
}
};
/**
* Returns this Long with bits logically shifted to the right by the given amount. This is an alias of {@link Long#shiftRightUnsigned}.
* @function
* @param {number|!Long} numBits Number of bits
* @returns {!Long} Shifted Long
*/
LongPrototype.shru = LongPrototype.shiftRightUnsigned;
/**
* Returns this Long with bits logically shifted to the right by the given amount. This is an alias of {@link Long#shiftRightUnsigned}.
* @function
* @param {number|!Long} numBits Number of bits
* @returns {!Long} Shifted Long
*/
LongPrototype.shr_u = LongPrototype.shiftRightUnsigned;
/**
* Converts this Long to signed.
* @returns {!Long} Signed long
*/
LongPrototype.toSigned = function toSigned() {
if (!this.unsigned)
return this;
return fromBits(this.low, this.high, false);
};
/**
* Converts this Long to unsigned.
* @returns {!Long} Unsigned long
*/
LongPrototype.toUnsigned = function toUnsigned() {
if (this.unsigned)
return this;
return fromBits(this.low, this.high, true);
};
/**
* Converts this Long to its byte representation.
* @param {boolean=} le Whether little or big endian, defaults to big endian
* @returns {!Array.<number>} Byte representation
*/
LongPrototype.toBytes = function toBytes(le) {
return le ? this.toBytesLE() : this.toBytesBE();
};
/**
* Converts this Long to its little endian byte representation.
* @returns {!Array.<number>} Little endian byte representation
*/
LongPrototype.toBytesLE = function toBytesLE() {
var hi = this.high,
lo = this.low;
return [
lo & 0xff,
lo >>> 8 & 0xff,
lo >>> 16 & 0xff,
lo >>> 24 ,
hi & 0xff,
hi >>> 8 & 0xff,
hi >>> 16 & 0xff,
hi >>> 24
];
};
/**
* Converts this Long to its big endian byte representation.
* @returns {!Array.<number>} Big endian byte representation
*/
LongPrototype.toBytesBE = function toBytesBE() {
var hi = this.high,
lo = this.low;
return [
hi >>> 24 ,
hi >>> 16 & 0xff,
hi >>> 8 & 0xff,
hi & 0xff,
lo >>> 24 ,
lo >>> 16 & 0xff,
lo >>> 8 & 0xff,
lo & 0xff
];
};
/**
* Creates a Long from its byte representation.
* @param {!Array.<number>} bytes Byte representation
* @param {boolean=} unsigned Whether unsigned or not, defaults to signed
* @param {boolean=} le Whether little or big endian, defaults to big endian
* @returns {Long} The corresponding Long value
*/
Long.fromBytes = function fromBytes(bytes, unsigned, le) {
return le ? Long.fromBytesLE(bytes, unsigned) : Long.fromBytesBE(bytes, unsigned);
};
/**
* Creates a Long from its little endian byte representation.
* @param {!Array.<number>} bytes Little endian byte representation
* @param {boolean=} unsigned Whether unsigned or not, defaults to signed
* @returns {Long} The corresponding Long value
*/
Long.fromBytesLE = function fromBytesLE(bytes, unsigned) {
return new Long(
bytes[0] |
bytes[1] << 8 |
bytes[2] << 16 |
bytes[3] << 24,
bytes[4] |
bytes[5] << 8 |
bytes[6] << 16 |
bytes[7] << 24,
unsigned
);
};
/**
* Creates a Long from its big endian byte representation.
* @param {!Array.<number>} bytes Big endian byte representation
* @param {boolean=} unsigned Whether unsigned or not, defaults to signed
* @returns {Long} The corresponding Long value
*/
Long.fromBytesBE = function fromBytesBE(bytes, unsigned) {
return new Long(
bytes[4] << 24 |
bytes[5] << 16 |
bytes[6] << 8 |
bytes[7],
bytes[0] << 24 |
bytes[1] << 16 |
bytes[2] << 8 |
bytes[3],
unsigned
);
};
/***/ }),
/***/ "./node_modules/onnx-proto/dist/onnx.js":
/*!**********************************************!*\
!*** ./node_modules/onnx-proto/dist/onnx.js ***!
\**********************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
/*eslint-disable block-scoped-var, id-length, no-control-regex, no-magic-numbers, no-prototype-builtins, no-redeclare, no-shadow, no-var, sort-vars*/
var $protobuf = __webpack_require__(/*! protobufjs/minimal */ "./node_modules/protobufjs/minimal.js");
// Common aliases
var $Reader = $protobuf.Reader, $Writer = $protobuf.Writer, $util = $protobuf.util;
// Exported root namespace
var $root = $protobuf.roots["default"] || ($protobuf.roots["default"] = {});
$root.onnx = (function() {
/**
* Namespace onnx.
* @exports onnx
* @namespace
*/
var onnx = {};
/**
* Version enum.
* @name onnx.Version
* @enum {string}
* @property {number} _START_VERSION=0 _START_VERSION value
* @property {number} IR_VERSION_2017_10_10=1 IR_VERSION_2017_10_10 value
* @property {number} IR_VERSION_2017_10_30=2 IR_VERSION_2017_10_30 value
* @property {number} IR_VERSION_2017_11_3=3 IR_VERSION_2017_11_3 value
* @property {number} IR_VERSION_2019_1_22=4 IR_VERSION_2019_1_22 value
* @property {number} IR_VERSION=5 IR_VERSION value
*/
onnx.Version = (function() {
var valuesById = {}, values = Object.create(valuesById);
values[valuesById[0] = "_START_VERSION"] = 0;
values[valuesById[1] = "IR_VERSION_2017_10_10"] = 1;
values[valuesById[2] = "IR_VERSION_2017_10_30"] = 2;
values[valuesById[3] = "IR_VERSION_2017_11_3"] = 3;
values[valuesById[4] = "IR_VERSION_2019_1_22"] = 4;
values[valuesById[5] = "IR_VERSION"] = 5;
return values;
})();
onnx.AttributeProto = (function() {
/**
* Properties of an AttributeProto.
* @memberof onnx
* @interface IAttributeProto
* @property {string|null} [name] AttributeProto name
* @property {string|null} [refAttrName] AttributeProto refAttrName
* @property {string|null} [docString] AttributeProto docString
* @property {onnx.AttributeProto.AttributeType|null} [type] AttributeProto type
* @property {number|null} [f] AttributeProto f
* @property {number|Long|null} [i] AttributeProto i
* @property {Uint8Array|null} [s] AttributeProto s
* @property {onnx.ITensorProto|null} [t] AttributeProto t
* @property {onnx.IGraphProto|null} [g] AttributeProto g
* @property {Array.<number>|null} [floats] AttributeProto floats
* @property {Array.<number|Long>|null} [ints] AttributeProto ints
* @property {Array.<Uint8Array>|null} [strings] AttributeProto strings
* @property {Array.<onnx.ITensorProto>|null} [tensors] AttributeProto tensors
* @property {Array.<onnx.IGraphProto>|null} [graphs] AttributeProto graphs
*/
/**
* Constructs a new AttributeProto.
* @memberof onnx
* @classdesc Represents an AttributeProto.
* @implements IAttributeProto
* @constructor
* @param {onnx.IAttributeProto=} [properties] Properties to set
*/
function AttributeProto(properties) {
this.floats = [];
this.ints = [];
this.strings = [];
this.tensors = [];
this.graphs = [];
if (properties)
for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
if (properties[keys[i]] != null)
this[keys[i]] = properties[keys[i]];
}
/**
* AttributeProto name.
* @member {string} name
* @memberof onnx.AttributeProto
* @instance
*/
AttributeProto.prototype.name = "";
/**
* AttributeProto refAttrName.
* @member {string} refAttrName
* @memberof onnx.AttributeProto
* @instance
*/
AttributeProto.prototype.refAttrName = "";
/**
* AttributeProto docString.
* @member {string} docString
* @memberof onnx.AttributeProto
* @instance
*/
AttributeProto.prototype.docString = "";
/**
* AttributeProto type.
* @member {onnx.AttributeProto.AttributeType} type
* @memberof onnx.AttributeProto
* @instance
*/
AttributeProto.prototype.type = 0;
/**
* AttributeProto f.
* @member {number} f
* @memberof onnx.AttributeProto
* @instance
*/
AttributeProto.prototype.f = 0;
/**
* AttributeProto i.
* @member {number|Long} i
* @memberof onnx.AttributeProto
* @instance
*/
AttributeProto.prototype.i = $util.Long ? $util.Long.fromBits(0,0,false) : 0;
/**
* AttributeProto s.
* @member {Uint8Array} s
* @memberof onnx.AttributeProto
* @instance
*/
AttributeProto.prototype.s = $util.newBuffer([]);
/**
* AttributeProto t.
* @member {onnx.ITensorProto|null|undefined} t
* @memberof onnx.AttributeProto
* @instance
*/
AttributeProto.prototype.t = null;
/**
* AttributeProto g.
* @member {onnx.IGraphProto|null|undefined} g
* @memberof onnx.AttributeProto
* @instance
*/
AttributeProto.prototype.g = null;
/**
* AttributeProto floats.
* @member {Array.<number>} floats
* @memberof onnx.AttributeProto
* @instance
*/
AttributeProto.prototype.floats = $util.emptyArray;
/**
* AttributeProto ints.
* @member {Array.<number|Long>} ints
* @memberof onnx.AttributeProto
* @instance
*/
AttributeProto.prototype.ints = $util.emptyArray;
/**
* AttributeProto strings.
* @member {Array.<Uint8Array>} strings
* @memberof onnx.AttributeProto
* @instance
*/
AttributeProto.prototype.strings = $util.emptyArray;
/**
* AttributeProto tensors.
* @member {Array.<onnx.ITensorProto>} tensors
* @memberof onnx.AttributeProto
* @instance
*/
AttributeProto.prototype.tensors = $util.emptyArray;
/**
* AttributeProto graphs.
* @member {Array.<onnx.IGraphProto>} graphs
* @memberof onnx.AttributeProto
* @instance
*/
AttributeProto.prototype.graphs = $util.emptyArray;
/**
* Creates a new AttributeProto instance using the specified properties.
* @function create
* @memberof onnx.AttributeProto
* @static
* @param {onnx.IAttributeProto=} [properties] Properties to set
* @returns {onnx.AttributeProto} AttributeProto instance
*/
AttributeProto.create = function create(properties) {
return new AttributeProto(properties);
};
/**
* Encodes the specified AttributeProto message. Does not implicitly {@link onnx.AttributeProto.verify|verify} messages.
* @function encode
* @memberof onnx.AttributeProto
* @static
* @param {onnx.IAttributeProto} message AttributeProto message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
AttributeProto.encode = function encode(message, writer) {
if (!writer)
writer = $Writer.create();
if (message.name != null && message.hasOwnProperty("name"))
writer.uint32(/* id 1, wireType 2 =*/10).string(message.name);
if (message.f != null && message.hasOwnProperty("f"))
writer.uint32(/* id 2, wireType 5 =*/21).float(message.f);
if (message.i != null && message.hasOwnProperty("i"))
writer.uint32(/* id 3, wireType 0 =*/24).int64(message.i);
if (message.s != null && message.hasOwnProperty("s"))
writer.uint32(/* id 4, wireType 2 =*/34).bytes(message.s);
if (message.t != null && message.hasOwnProperty("t"))
$root.onnx.TensorProto.encode(message.t, writer.uint32(/* id 5, wireType 2 =*/42).fork()).ldelim();
if (message.g != null && message.hasOwnProperty("g"))
$root.onnx.GraphProto.encode(message.g, writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim();
if (message.floats != null && message.floats.length) {
writer.uint32(/* id 7, wireType 2 =*/58).fork();
for (var i = 0; i < message.floats.length; ++i)
writer.float(message.floats[i]);
writer.ldelim();
}
if (message.ints != null && message.ints.length) {
writer.uint32(/* id 8, wireType 2 =*/66).fork();
for (var i = 0; i < message.ints.length; ++i)
writer.int64(message.ints[i]);
writer.ldelim();
}
if (message.strings != null && message.strings.length)
for (var i = 0; i < message.strings.length; ++i)
writer.uint32(/* id 9, wireType 2 =*/74).bytes(message.strings[i]);
if (message.tensors != null && message.tensors.length)
for (var i = 0; i < message.tensors.length; ++i)
$root.onnx.TensorProto.encode(message.tensors[i], writer.uint32(/* id 10, wireType 2 =*/82).fork()).ldelim();
if (message.graphs != null && message.graphs.length)
for (var i = 0; i < message.graphs.length; ++i)
$root.onnx.GraphProto.encode(message.graphs[i], writer.uint32(/* id 11, wireType 2 =*/90).fork()).ldelim();
if (message.docString != null && message.hasOwnProperty("docString"))
writer.uint32(/* id 13, wireType 2 =*/106).string(message.docString);
if (message.type != null && message.hasOwnProperty("type"))
writer.uint32(/* id 20, wireType 0 =*/160).int32(message.type);
if (message.refAttrName != null && message.hasOwnProperty("refAttrName"))
writer.uint32(/* id 21, wireType 2 =*/170).string(message.refAttrName);
return writer;
};
/**
* Encodes the specified AttributeProto message, length delimited. Does not implicitly {@link onnx.AttributeProto.verify|verify} messages.
* @function encodeDelimited
* @memberof onnx.AttributeProto
* @static
* @param {onnx.IAttributeProto} message AttributeProto message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
AttributeProto.encodeDelimited = function encodeDelimited(message, writer) {
return this.encode(message, writer).ldelim();
};
/**
* Decodes an AttributeProto message from the specified reader or buffer.
* @function decode
* @memberof onnx.AttributeProto
* @static
* @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
* @param {number} [length] Message length if known beforehand
* @returns {onnx.AttributeProto} AttributeProto
* @throws {Error} If the payload is not a reader or valid buffer
* @throws {$protobuf.util.ProtocolError} If required fields are missing
*/
AttributeProto.decode = function decode(reader, length) {
if (!(reader instanceof $Reader))
reader = $Reader.create(reader);
var end = length === undefined ? reader.len : reader.pos + length, message = new $root.onnx.AttributeProto();
while (reader.pos < end) {
var tag = reader.uint32();
switch (tag >>> 3) {
case 1:
message.name = reader.string();
break;
case 21:
message.refAttrName = reader.string();
break;
case 13:
message.docString = reader.string();
break;
case 20:
message.type = reader.int32();
break;
case 2:
message.f = reader.float();
break;
case 3:
message.i = reader.int64();
break;
case 4:
message.s = reader.bytes();
break;
case 5:
message.t = $root.onnx.TensorProto.decode(reader, reader.uint32());
break;
case 6:
message.g = $root.onnx.GraphProto.decode(reader, reader.uint32());
break;
case 7:
if (!(message.floats && message.floats.length))
message.floats = [];
if ((tag & 7) === 2) {
var end2 = reader.uint32() + reader.pos;
while (reader.pos < end2)
message.floats.push(reader.float());
} else
message.floats.push(reader.float());
break;
case 8:
if (!(message.ints && message.ints.length))
message.ints = [];
if ((tag & 7) === 2) {
var end2 = reader.uint32() + reader.pos;
while (reader.pos < end2)
message.ints.push(reader.int64());
} else
message.ints.push(reader.int64());
break;
case 9:
if (!(message.strings && message.strings.length))
message.strings = [];
message.strings.push(reader.bytes());
break;
case 10:
if (!(message.tensors && message.tensors.length))
message.tensors = [];
message.tensors.push($root.onnx.TensorProto.decode(reader, reader.uint32()));
break;
case 11:
if (!(message.graphs && message.graphs.length))
message.graphs = [];
message.graphs.push($root.onnx.GraphProto.decode(reader, reader.uint32()));
break;
default:
reader.skipType(tag & 7);
break;
}
}
return message;
};
/**
* Decodes an AttributeProto message from the specified reader or buffer, length delimited.
* @function decodeDelimited
* @memberof onnx.AttributeProto
* @static
* @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
* @returns {onnx.AttributeProto} AttributeProto
* @throws {Error} If the payload is not a reader or valid buffer
* @throws {$protobuf.util.ProtocolError} If required fields are missing
*/
AttributeProto.decodeDelimited = function decodeDelimited(reader) {
if (!(reader instanceof $Reader))
reader = new $Reader(reader);
return this.decode(reader, reader.uint32());
};
/**
* Verifies an AttributeProto message.
* @function verify
* @memberof onnx.AttributeProto
* @static
* @param {Object.<string,*>} message Plain object to verify
* @returns {string|null} `null` if valid, otherwise the reason why it is not
*/
AttributeProto.verify = function verify(message) {
if (typeof message !== "object" || message === null)
return "object expected";
if (message.name != null && message.hasOwnProperty("name"))
if (!$util.isString(message.name))
return "name: string expected";
if (message.refAttrName != null && message.hasOwnProperty("refAttrName"))
if (!$util.isString(message.refAttrName))
return "refAttrName: string expected";
if (message.docString != null && message.hasOwnProperty("docString"))
if (!$util.isString(message.docString))
return "docString: string expected";
if (message.type != null && message.hasOwnProperty("type"))
switch (message.type) {
default:
return "type: enum value expected";
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
break;
}
if (message.f != null && message.hasOwnProperty("f"))
if (typeof message.f !== "number")
return "f: number expected";
if (message.i != null && message.hasOwnProperty("i"))
if (!$util.isInteger(message.i) && !(message.i && $util.isInteger(message.i.low) && $util.isInteger(message.i.high)))
return "i: integer|Long expected";
if (message.s != null && message.hasOwnProperty("s"))
if (!(message.s && typeof message.s.length === "number" || $util.isString(message.s)))
return "s: buffer expected";
if (message.t != null && message.hasOwnProperty("t")) {
var error = $root.onnx.TensorProto.verify(message.t);
if (error)
return "t." + error;
}
if (message.g != null && message.hasOwnProperty("g")) {
var error = $root.onnx.GraphProto.verify(message.g);
if (error)
return "g." + error;
}
if (message.floats != null && message.hasOwnProperty("floats")) {
if (!Array.isArray(message.floats))
return "floats: array expected";
for (var i = 0; i < message.floats.length; ++i)
if (typeof message.floats[i] !== "number")
return "floats: number[] expected";
}
if (message.ints != null && message.hasOwnProperty("ints")) {
if (!Array.isArray(message.ints))
return "ints: array expected";
for (var i = 0; i < message.ints.length; ++i)
if (!$util.isInteger(message.ints[i]) && !(message.ints[i] && $util.isInteger(message.ints[i].low) && $util.isInteger(message.ints[i].high)))
return "ints: integer|Long[] expected";
}
if (message.strings != null && message.hasOwnProperty("strings")) {
if (!Array.isArray(message.strings))
return "strings: array expected";
for (var i = 0; i < message.strings.length; ++i)
if (!(message.strings[i] && typeof message.strings[i].length === "number" || $util.isString(message.strings[i])))
return "strings: buffer[] expected";
}
if (message.tensors != null && message.hasOwnProperty("tensors")) {
if (!Array.isArray(message.tensors))
return "tensors: array expected";
for (var i = 0; i < message.tensors.length; ++i) {
var error = $root.onnx.TensorProto.verify(message.tensors[i]);
if (error)
return "tensors." + error;
}
}
if (message.graphs != null && message.hasOwnProperty("graphs")) {
if (!Array.isArray(message.graphs))
return "graphs: array expected";
for (var i = 0; i < message.graphs.length; ++i) {
var error = $root.onnx.GraphProto.verify(message.graphs[i]);
if (error)
return "graphs." + error;
}
}
return null;
};
/**
* Creates an AttributeProto message from a plain object. Also converts values to their respective internal types.
* @function fromObject
* @memberof onnx.AttributeProto
* @static
* @param {Object.<string,*>} object Plain object
* @returns {onnx.AttributeProto} AttributeProto
*/
AttributeProto.fromObject = function fromObject(object) {
if (object instanceof $root.onnx.AttributeProto)
return object;
var message = new $root.onnx.AttributeProto();
if (object.name != null)
message.name = String(object.name);
if (object.refAttrName != null)
message.refAttrName = String(object.refAttrName);
if (object.docString != null)
message.docString = String(object.docString);
switch (object.type) {
case "UNDEFINED":
case 0:
message.type = 0;
break;
case "FLOAT":
case 1:
message.type = 1;
break;
case "INT":
case 2:
message.type = 2;
break;
case "STRING":
case 3:
message.type = 3;
break;
case "TENSOR":
case 4:
message.type = 4;
break;
case "GRAPH":
case 5:
message.type = 5;
break;
case "FLOATS":
case 6:
message.type = 6;
break;
case "INTS":
case 7:
message.type = 7;
break;
case "STRINGS":
case 8:
message.type = 8;
break;
case "TENSORS":
case 9:
message.type = 9;
break;
case "GRAPHS":
case 10:
message.type = 10;
break;
}
if (object.f != null)
message.f = Number(object.f);
if (object.i != null)
if ($util.Long)
(message.i = $util.Long.fromValue(object.i)).unsigned = false;
else if (typeof object.i === "string")
message.i = parseInt(object.i, 10);
else if (typeof object.i === "number")
message.i = object.i;
else if (typeof object.i === "object")
message.i = new $util.LongBits(object.i.low >>> 0, object.i.high >>> 0).toNumber();
if (object.s != null)
if (typeof object.s === "string")
$util.base64.decode(object.s, message.s = $util.newBuffer($util.base64.length(object.s)), 0);
else if (object.s.length)
message.s = object.s;
if (object.t != null) {
if (typeof object.t !== "object")
throw TypeError(".onnx.AttributeProto.t: object expected");
message.t = $root.onnx.TensorProto.fromObject(object.t);
}
if (object.g != null) {
if (typeof object.g !== "object")
throw TypeError(".onnx.AttributeProto.g: object expected");
message.g = $root.onnx.GraphProto.fromObject(object.g);
}
if (object.floats) {
if (!Array.isArray(object.floats))
throw TypeError(".onnx.AttributeProto.floats: array expected");
message.floats = [];
for (var i = 0; i < object.floats.length; ++i)
message.floats[i] = Number(object.floats[i]);
}
if (object.ints) {
if (!Array.isArray(object.ints))
throw TypeError(".onnx.AttributeProto.ints: array expected");
message.ints = [];
for (var i = 0; i < object.ints.length; ++i)
if ($util.Long)
(message.ints[i] = $util.Long.fromValue(object.ints[i])).unsigned = false;
else if (typeof object.ints[i] === "string")
message.ints[i] = parseInt(object.ints[i], 10);
else if (typeof object.ints[i] === "number")
message.ints[i] = object.ints[i];
else if (typeof object.ints[i] === "object")
message.ints[i] = new $util.LongBits(object.ints[i].low >>> 0, object.ints[i].high >>> 0).toNumber();
}
if (object.strings) {
if (!Array.isArray(object.strings))
throw TypeError(".onnx.AttributeProto.strings: array expected");
message.strings = [];
for (var i = 0; i < object.strings.length; ++i)
if (typeof object.strings[i] === "string")
$util.base64.decode(object.strings[i], message.strings[i] = $util.newBuffer($util.base64.length(object.strings[i])), 0);
else if (object.strings[i].length)
message.strings[i] = object.strings[i];
}
if (object.tensors) {
if (!Array.isArray(object.tensors))
throw TypeError(".onnx.AttributeProto.tensors: array expected");
message.tensors = [];
for (var i = 0; i < object.tensors.length; ++i) {
if (typeof object.tensors[i] !== "object")
throw TypeError(".onnx.AttributeProto.tensors: object expected");
message.tensors[i] = $root.onnx.TensorProto.fromObject(object.tensors[i]);
}
}
if (object.graphs) {
if (!Array.isArray(object.graphs))
throw TypeError(".onnx.AttributeProto.graphs: array expected");
message.graphs = [];
for (var i = 0; i < object.graphs.length; ++i) {
if (typeof object.graphs[i] !== "object")
throw TypeError(".onnx.AttributeProto.graphs: object expected");
message.graphs[i] = $root.onnx.GraphProto.fromObject(object.graphs[i]);
}
}
return message;
};
/**
* Creates a plain object from an AttributeProto message. Also converts values to other types if specified.
* @function toObject
* @memberof onnx.AttributeProto
* @static
* @param {onnx.AttributeProto} message AttributeProto
* @param {$protobuf.IConversionOptions} [options] Conversion options
* @returns {Object.<string,*>} Plain object
*/
AttributeProto.toObject = function toObject(message, options) {
if (!options)
options = {};
var object = {};
if (options.arrays || options.defaults) {
object.floats = [];
object.ints = [];
object.strings = [];
object.tensors = [];
object.graphs = [];
}
if (options.defaults) {
object.name = "";
object.f = 0;
if ($util.Long) {
var long = new $util.Long(0, 0, false);
object.i = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
} else
object.i = options.longs === String ? "0" : 0;
if (options.bytes === String)
object.s = "";
else {
object.s = [];
if (options.bytes !== Array)
object.s = $util.newBuffer(object.s);
}
object.t = null;
object.g = null;
object.docString = "";
object.type = options.enums === String ? "UNDEFINED" : 0;
object.refAttrName = "";
}
if (message.name != null && message.hasOwnProperty("name"))
object.name = message.name;
if (message.f != null && message.hasOwnProperty("f"))
object.f = options.json && !isFinite(message.f) ? String(message.f) : message.f;
if (message.i != null && message.hasOwnProperty("i"))
if (typeof message.i === "number")
object.i = options.longs === String ? String(message.i) : message.i;
else
object.i = options.longs === String ? $util.Long.prototype.toString.call(message.i) : options.longs === Number ? new $util.LongBits(message.i.low >>> 0, message.i.high >>> 0).toNumber() : message.i;
if (message.s != null && message.hasOwnProperty("s"))
object.s = options.bytes === String ? $util.base64.encode(message.s, 0, message.s.length) : options.bytes === Array ? Array.prototype.slice.call(message.s) : message.s;
if (message.t != null && message.hasOwnProperty("t"))
object.t = $root.onnx.TensorProto.toObject(message.t, options);
if (message.g != null && message.hasOwnProperty("g"))
object.g = $root.onnx.GraphProto.toObject(message.g, options);
if (message.floats && message.floats.length) {
object.floats = [];
for (var j = 0; j < message.floats.length; ++j)
object.floats[j] = options.json && !isFinite(message.floats[j]) ? String(message.floats[j]) : message.floats[j];
}
if (message.ints && message.ints.length) {
object.ints = [];
for (var j = 0; j < message.ints.length; ++j)
if (typeof message.ints[j] === "number")
object.ints[j] = options.longs === String ? String(message.ints[j]) : message.ints[j];
else
object.ints[j] = options.longs === String ? $util.Long.prototype.toString.call(message.ints[j]) : options.longs === Number ? new $util.LongBits(message.ints[j].low >>> 0, message.ints[j].high >>> 0).toNumber() : message.ints[j];
}
if (message.strings && message.strings.length) {
object.strings = [];
for (var j = 0; j < message.strings.length; ++j)
object.strings[j] = options.bytes === String ? $util.base64.encode(message.strings[j], 0, message.strings[j].length) : options.bytes === Array ? Array.prototype.slice.call(message.strings[j]) : message.strings[j];
}
if (message.tensors && message.tensors.length) {
object.tensors = [];
for (var j = 0; j < message.tensors.length; ++j)
object.tensors[j] = $root.onnx.TensorProto.toObject(message.tensors[j], options);
}
if (message.graphs && message.graphs.length) {
object.graphs = [];
for (var j = 0; j < message.graphs.length; ++j)
object.graphs[j] = $root.onnx.GraphProto.toObject(message.graphs[j], options);
}
if (message.docString != null && message.hasOwnProperty("docString"))
object.docString = message.docString;
if (message.type != null && message.hasOwnProperty("type"))
object.type = options.enums === String ? $root.onnx.AttributeProto.AttributeType[message.type] : message.type;
if (message.refAttrName != null && message.hasOwnProperty("refAttrName"))
object.refAttrName = message.refAttrName;
return object;
};
/**
* Converts this AttributeProto to JSON.
* @function toJSON
* @memberof onnx.AttributeProto
* @instance
* @returns {Object.<string,*>} JSON object
*/
AttributeProto.prototype.toJSON = function toJSON() {
return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
};
/**
* AttributeType enum.
* @name onnx.AttributeProto.AttributeType
* @enum {string}
* @property {number} UNDEFINED=0 UNDEFINED value
* @property {number} FLOAT=1 FLOAT value
* @property {number} INT=2 INT value
* @property {number} STRING=3 STRING value
* @property {number} TENSOR=4 TENSOR value
* @property {number} GRAPH=5 GRAPH value
* @property {number} FLOATS=6 FLOATS value
* @property {number} INTS=7 INTS value
* @property {number} STRINGS=8 STRINGS value
* @property {number} TENSORS=9 TENSORS value
* @property {number} GRAPHS=10 GRAPHS value
*/
AttributeProto.AttributeType = (function() {
var valuesById = {}, values = Object.create(valuesById);
values[valuesById[0] = "UNDEFINED"] = 0;
values[valuesById[1] = "FLOAT"] = 1;
values[valuesById[2] = "INT"] = 2;
values[valuesById[3] = "STRING"] = 3;
values[valuesById[4] = "TENSOR"] = 4;
values[valuesById[5] = "GRAPH"] = 5;
values[valuesById[6] = "FLOATS"] = 6;
values[valuesById[7] = "INTS"] = 7;
values[valuesById[8] = "STRINGS"] = 8;
values[valuesById[9] = "TENSORS"] = 9;
values[valuesById[10] = "GRAPHS"] = 10;
return values;
})();
return AttributeProto;
})();
onnx.ValueInfoProto = (function() {
/**
* Properties of a ValueInfoProto.
* @memberof onnx
* @interface IValueInfoProto
* @property {string|null} [name] ValueInfoProto name
* @property {onnx.ITypeProto|null} [type] ValueInfoProto type
* @property {string|null} [docString] ValueInfoProto docString
*/
/**
* Constructs a new ValueInfoProto.
* @memberof onnx
* @classdesc Represents a ValueInfoProto.
* @implements IValueInfoProto
* @constructor
* @param {onnx.IValueInfoProto=} [properties] Properties to set
*/
function ValueInfoProto(properties) {
if (properties)
for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
if (properties[keys[i]] != null)
this[keys[i]] = properties[keys[i]];
}
/**
* ValueInfoProto name.
* @member {string} name
* @memberof onnx.ValueInfoProto
* @instance
*/
ValueInfoProto.prototype.name = "";
/**
* ValueInfoProto type.
* @member {onnx.ITypeProto|null|undefined} type
* @memberof onnx.ValueInfoProto
* @instance
*/
ValueInfoProto.prototype.type = null;
/**
* ValueInfoProto docString.
* @member {string} docString
* @memberof onnx.ValueInfoProto
* @instance
*/
ValueInfoProto.prototype.docString = "";
/**
* Creates a new ValueInfoProto instance using the specified properties.
* @function create
* @memberof onnx.ValueInfoProto
* @static
* @param {onnx.IValueInfoProto=} [properties] Properties to set
* @returns {onnx.ValueInfoProto} ValueInfoProto instance
*/
ValueInfoProto.create = function create(properties) {
return new ValueInfoProto(properties);
};
/**
* Encodes the specified ValueInfoProto message. Does not implicitly {@link onnx.ValueInfoProto.verify|verify} messages.
* @function encode
* @memberof onnx.ValueInfoProto
* @static
* @param {onnx.IValueInfoProto} message ValueInfoProto message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
ValueInfoProto.encode = function encode(message, writer) {
if (!writer)
writer = $Writer.create();
if (message.name != null && message.hasOwnProperty("name"))
writer.uint32(/* id 1, wireType 2 =*/10).string(message.name);
if (message.type != null && message.hasOwnProperty("type"))
$root.onnx.TypeProto.encode(message.type, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
if (message.docString != null && message.hasOwnProperty("docString"))
writer.uint32(/* id 3, wireType 2 =*/26).string(message.docString);
return writer;
};
/**
* Encodes the specified ValueInfoProto message, length delimited. Does not implicitly {@link onnx.ValueInfoProto.verify|verify} messages.
* @function encodeDelimited
* @memberof onnx.ValueInfoProto
* @static
* @param {onnx.IValueInfoProto} message ValueInfoProto message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
ValueInfoProto.encodeDelimited = function encodeDelimited(message, writer) {
return this.encode(message, writer).ldelim();
};
/**
* Decodes a ValueInfoProto message from the specified reader or buffer.
* @function decode
* @memberof onnx.ValueInfoProto
* @static
* @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
* @param {number} [length] Message length if known beforehand
* @returns {onnx.ValueInfoProto} ValueInfoProto
* @throws {Error} If the payload is not a reader or valid buffer
* @throws {$protobuf.util.ProtocolError} If required fields are missing
*/
ValueInfoProto.decode = function decode(reader, length) {
if (!(reader instanceof $Reader))
reader = $Reader.create(reader);
var end = length === undefined ? reader.len : reader.pos + length, message = new $root.onnx.ValueInfoProto();
while (reader.pos < end) {
var tag = reader.uint32();
switch (tag >>> 3) {
case 1:
message.name = reader.string();
break;
case 2:
message.type = $root.onnx.TypeProto.decode(reader, reader.uint32());
break;
case 3:
message.docString = reader.string();
break;
default:
reader.skipType(tag & 7);
break;
}
}
return message;
};
/**
* Decodes a ValueInfoProto message from the specified reader or buffer, length delimited.
* @function decodeDelimited
* @memberof onnx.ValueInfoProto
* @static
* @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
* @returns {onnx.ValueInfoProto} ValueInfoProto
* @throws {Error} If the payload is not a reader or valid buffer
* @throws {$protobuf.util.ProtocolError} If required fields are missing
*/
ValueInfoProto.decodeDelimited = function decodeDelimited(reader) {
if (!(reader instanceof $Reader))
reader = new $Reader(reader);
return this.decode(reader, reader.uint32());
};
/**
* Verifies a ValueInfoProto message.
* @function verify
* @memberof onnx.ValueInfoProto
* @static
* @param {Object.<string,*>} message Plain object to verify
* @returns {string|null} `null` if valid, otherwise the reason why it is not
*/
ValueInfoProto.verify = function verify(message) {
if (typeof message !== "object" || message === null)
return "object expected";
if (message.name != null && message.hasOwnProperty("name"))
if (!$util.isString(message.name))
return "name: string expected";
if (message.type != null && message.hasOwnProperty("type")) {
var error = $root.onnx.TypeProto.verify(message.type);
if (error)
return "type." + error;
}
if (message.docString != null && message.hasOwnProperty("docString"))
if (!$util.isString(message.docString))
return "docString: string expected";
return null;
};
/**
* Creates a ValueInfoProto message from a plain object. Also converts values to their respective internal types.
* @function fromObject
* @memberof onnx.ValueInfoProto
* @static
* @param {Object.<string,*>} object Plain object
* @returns {onnx.ValueInfoProto} ValueInfoProto
*/
ValueInfoProto.fromObject = function fromObject(object) {
if (object instanceof $root.onnx.ValueInfoProto)
return object;
var message = new $root.onnx.ValueInfoProto();
if (object.name != null)
message.name = String(object.name);
if (object.type != null) {
if (typeof object.type !== "object")
throw TypeError(".onnx.ValueInfoProto.type: object expected");
message.type = $root.onnx.TypeProto.fromObject(object.type);
}
if (object.docString != null)
message.docString = String(object.docString);
return message;
};
/**
* Creates a plain object from a ValueInfoProto message. Also converts values to other types if specified.
* @function toObject
* @memberof onnx.ValueInfoProto
* @static
* @param {onnx.ValueInfoProto} message ValueInfoProto
* @param {$protobuf.IConversionOptions} [options] Conversion options
* @returns {Object.<string,*>} Plain object
*/
ValueInfoProto.toObject = function toObject(message, options) {
if (!options)
options = {};
var object = {};
if (options.defaults) {
object.name = "";
object.type = null;
object.docString = "";
}
if (message.name != null && message.hasOwnProperty("name"))
object.name = message.name;
if (message.type != null && message.hasOwnProperty("type"))
object.type = $root.onnx.TypeProto.toObject(message.type, options);
if (message.docString != null && message.hasOwnProperty("docString"))
object.docString = message.docString;
return object;
};
/**
* Converts this ValueInfoProto to JSON.
* @function toJSON
* @memberof onnx.ValueInfoProto
* @instance
* @returns {Object.<string,*>} JSON object
*/
ValueInfoProto.prototype.toJSON = function toJSON() {
return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
};
return ValueInfoProto;
})();
onnx.NodeProto = (function() {
/**
* Properties of a NodeProto.
* @memberof onnx
* @interface INodeProto
* @property {Array.<string>|null} [input] NodeProto input
* @property {Array.<string>|null} [output] NodeProto output
* @property {string|null} [name] NodeProto name
* @property {string|null} [opType] NodeProto opType
* @property {string|null} [domain] NodeProto domain
* @property {Array.<onnx.IAttributeProto>|null} [attribute] NodeProto attribute
* @property {string|null} [docString] NodeProto docString
*/
/**
* Constructs a new NodeProto.
* @memberof onnx
* @classdesc Represents a NodeProto.
* @implements INodeProto
* @constructor
* @param {onnx.INodeProto=} [properties] Properties to set
*/
function NodeProto(properties) {
this.input = [];
this.output = [];
this.attribute = [];
if (properties)
for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
if (properties[keys[i]] != null)
this[keys[i]] = properties[keys[i]];
}
/**
* NodeProto input.
* @member {Array.<string>} input
* @memberof onnx.NodeProto
* @instance
*/
NodeProto.prototype.input = $util.emptyArray;
/**
* NodeProto output.
* @member {Array.<string>} output
* @memberof onnx.NodeProto
* @instance
*/
NodeProto.prototype.output = $util.emptyArray;
/**
* NodeProto name.
* @member {string} name
* @memberof onnx.NodeProto
* @instance
*/
NodeProto.prototype.name = "";
/**
* NodeProto opType.
* @member {string} opType
* @memberof onnx.NodeProto
* @instance
*/
NodeProto.prototype.opType = "";
/**
* NodeProto domain.
* @member {string} domain
* @memberof onnx.NodeProto
* @instance
*/
NodeProto.prototype.domain = "";
/**
* NodeProto attribute.
* @member {Array.<onnx.IAttributeProto>} attribute
* @memberof onnx.NodeProto
* @instance
*/
NodeProto.prototype.attribute = $util.emptyArray;
/**
* NodeProto docString.
* @member {string} docString
* @memberof onnx.NodeProto
* @instance
*/
NodeProto.prototype.docString = "";
/**
* Creates a new NodeProto instance using the specified properties.
* @function create
* @memberof onnx.NodeProto
* @static
* @param {onnx.INodeProto=} [properties] Properties to set
* @returns {onnx.NodeProto} NodeProto instance
*/
NodeProto.create = function create(properties) {
return new NodeProto(properties);
};
/**
* Encodes the specified NodeProto message. Does not implicitly {@link onnx.NodeProto.verify|verify} messages.
* @function encode
* @memberof onnx.NodeProto
* @static
* @param {onnx.INodeProto} message NodeProto message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
NodeProto.encode = function encode(message, writer) {
if (!writer)
writer = $Writer.create();
if (message.input != null && message.input.length)
for (var i = 0; i < message.input.length; ++i)
writer.uint32(/* id 1, wireType 2 =*/10).string(message.input[i]);
if (message.output != null && message.output.length)
for (var i = 0; i < message.output.length; ++i)
writer.uint32(/* id 2, wireType 2 =*/18).string(message.output[i]);
if (message.name != null && message.hasOwnProperty("name"))
writer.uint32(/* id 3, wireType 2 =*/26).string(message.name);
if (message.opType != null && message.hasOwnProperty("opType"))
writer.uint32(/* id 4, wireType 2 =*/34).string(message.opType);
if (message.attribute != null && message.attribute.length)
for (var i = 0; i < message.attribute.length; ++i)
$root.onnx.AttributeProto.encode(message.attribute[i], writer.uint32(/* id 5, wireType 2 =*/42).fork()).ldelim();
if (message.docString != null && message.hasOwnProperty("docString"))
writer.uint32(/* id 6, wireType 2 =*/50).string(message.docString);
if (message.domain != null && message.hasOwnProperty("domain"))
writer.uint32(/* id 7, wireType 2 =*/58).string(message.domain);
return writer;
};
/**
* Encodes the specified NodeProto message, length delimited. Does not implicitly {@link onnx.NodeProto.verify|verify} messages.
* @function encodeDelimited
* @memberof onnx.NodeProto
* @static
* @param {onnx.INodeProto} message NodeProto message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
NodeProto.encodeDelimited = function encodeDelimited(message, writer) {
return this.encode(message, writer).ldelim();
};
/**
* Decodes a NodeProto message from the specified reader or buffer.
* @function decode
* @memberof onnx.NodeProto
* @static
* @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
* @param {number} [length] Message length if known beforehand
* @returns {onnx.NodeProto} NodeProto
* @throws {Error} If the payload is not a reader or valid buffer
* @throws {$protobuf.util.ProtocolError} If required fields are missing
*/
NodeProto.decode = function decode(reader, length) {
if (!(reader instanceof $Reader))
reader = $Reader.create(reader);
var end = length === undefined ? reader.len : reader.pos + length, message = new $root.onnx.NodeProto();
while (reader.pos < end) {
var tag = reader.uint32();
switch (tag >>> 3) {
case 1:
if (!(message.input && message.input.length))
message.input = [];
message.input.push(reader.string());
break;
case 2:
if (!(message.output && message.output.length))
message.output = [];
message.output.push(reader.string());
break;
case 3:
message.name = reader.string();
break;
case 4:
message.opType = reader.string();
break;
case 7:
message.domain = reader.string();
break;
case 5:
if (!(message.attribute && message.attribute.length))
message.attribute = [];
message.attribute.push($root.onnx.AttributeProto.decode(reader, reader.uint32()));
break;
case 6:
message.docString = reader.string();
break;
default:
reader.skipType(tag & 7);
break;
}
}
return message;
};
/**
* Decodes a NodeProto message from the specified reader or buffer, length delimited.
* @function decodeDelimited
* @memberof onnx.NodeProto
* @static
* @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
* @returns {onnx.NodeProto} NodeProto
* @throws {Error} If the payload is not a reader or valid buffer
* @throws {$protobuf.util.ProtocolError} If required fields are missing
*/
NodeProto.decodeDelimited = function decodeDelimited(reader) {
if (!(reader instanceof $Reader))
reader = new $Reader(reader);
return this.decode(reader, reader.uint32());
};
/**
* Verifies a NodeProto message.
* @function verify
* @memberof onnx.NodeProto
* @static
* @param {Object.<string,*>} message Plain object to verify
* @returns {string|null} `null` if valid, otherwise the reason why it is not
*/
NodeProto.verify = function verify(message) {
if (typeof message !== "object" || message === null)
return "object expected";
if (message.input != null && message.hasOwnProperty("input")) {
if (!Array.isArray(message.input))
return "input: array expected";
for (var i = 0; i < message.input.length; ++i)
if (!$util.isString(message.input[i]))
return "input: string[] expected";
}
if (message.output != null && message.hasOwnProperty("output")) {
if (!Array.isArray(message.output))
return "output: array expected";
for (var i = 0; i < message.output.length; ++i)
if (!$util.isString(message.output[i]))
return "output: string[] expected";
}
if (message.name != null && message.hasOwnProperty("name"))
if (!$util.isString(message.name))
return "name: string expected";
if (message.opType != null && message.hasOwnProperty("opType"))
if (!$util.isString(message.opType))
return "opType: string expected";
if (message.domain != null && message.hasOwnProperty("domain"))
if (!$util.isString(message.domain))
return "domain: string expected";
if (message.attribute != null && message.hasOwnProperty("attribute")) {
if (!Array.isArray(message.attribute))
return "attribute: array expected";
for (var i = 0; i < message.attribute.length; ++i) {
var error = $root.onnx.AttributeProto.verify(message.attribute[i]);
if (error)
return "attribute." + error;
}
}
if (message.docString != null && message.hasOwnProperty("docString"))
if (!$util.isString(message.docString))
return "docString: string expected";
return null;
};
/**
* Creates a NodeProto message from a plain object. Also converts values to their respective internal types.
* @function fromObject
* @memberof onnx.NodeProto
* @static
* @param {Object.<string,*>} object Plain object
* @returns {onnx.NodeProto} NodeProto
*/
NodeProto.fromObject = function fromObject(object) {
if (object instanceof $root.onnx.NodeProto)
return object;
var message = new $root.onnx.NodeProto();
if (object.input) {
if (!Array.isArray(object.input))
throw TypeError(".onnx.NodeProto.input: array expected");
message.input = [];
for (var i = 0; i < object.input.length; ++i)
message.input[i] = String(object.input[i]);
}
if (object.output) {
if (!Array.isArray(object.output))
throw TypeError(".onnx.NodeProto.output: array expected");
message.output = [];
for (var i = 0; i < object.output.length; ++i)
message.output[i] = String(object.output[i]);
}
if (object.name != null)
message.name = String(object.name);
if (object.opType != null)
message.opType = String(object.opType);
if (object.domain != null)
message.domain = String(object.domain);
if (object.attribute) {
if (!Array.isArray(object.attribute))
throw TypeError(".onnx.NodeProto.attribute: array expected");
message.attribute = [];
for (var i = 0; i < object.attribute.length; ++i) {
if (typeof object.attribute[i] !== "object")
throw TypeError(".onnx.NodeProto.attribute: object expected");
message.attribute[i] = $root.onnx.AttributeProto.fromObject(object.attribute[i]);
}
}
if (object.docString != null)
message.docString = String(object.docString);
return message;
};
/**
* Creates a plain object from a NodeProto message. Also converts values to other types if specified.
* @function toObject
* @memberof onnx.NodeProto
* @static
* @param {onnx.NodeProto} message NodeProto
* @param {$protobuf.IConversionOptions} [options] Conversion options
* @returns {Object.<string,*>} Plain object
*/
NodeProto.toObject = function toObject(message, options) {
if (!options)
options = {};
var object = {};
if (options.arrays || options.defaults) {
object.input = [];
object.output = [];
object.attribute = [];
}
if (options.defaults) {
object.name = "";
object.opType = "";
object.docString = "";
object.domain = "";
}
if (message.input && message.input.length) {
object.input = [];
for (var j = 0; j < message.input.length; ++j)
object.input[j] = message.input[j];
}
if (message.output && message.output.length) {
object.output = [];
for (var j = 0; j < message.output.length; ++j)
object.output[j] = message.output[j];
}
if (message.name != null && message.hasOwnProperty("name"))
object.name = message.name;
if (message.opType != null && message.hasOwnProperty("opType"))
object.opType = message.opType;
if (message.attribute && message.attribute.length) {
object.attribute = [];
for (var j = 0; j < message.attribute.length; ++j)
object.attribute[j] = $root.onnx.AttributeProto.toObject(message.attribute[j], options);
}
if (message.docString != null && message.hasOwnProperty("docString"))
object.docString = message.docString;
if (message.domain != null && message.hasOwnProperty("domain"))
object.domain = message.domain;
return object;
};
/**
* Converts this NodeProto to JSON.
* @function toJSON
* @memberof onnx.NodeProto
* @instance
* @returns {Object.<string,*>} JSON object
*/
NodeProto.prototype.toJSON = function toJSON() {
return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
};
return NodeProto;
})();
onnx.ModelProto = (function() {
/**
* Properties of a ModelProto.
* @memberof onnx
* @interface IModelProto
* @property {number|Long|null} [irVersion] ModelProto irVersion
* @property {Array.<onnx.IOperatorSetIdProto>|null} [opsetImport] ModelProto opsetImport
* @property {string|null} [producerName] ModelProto producerName
* @property {string|null} [producerVersion] ModelProto producerVersion
* @property {string|null} [domain] ModelProto domain
* @property {number|Long|null} [modelVersion] ModelProto modelVersion
* @property {string|null} [docString] ModelProto docString
* @property {onnx.IGraphProto|null} [graph] ModelProto graph
* @property {Array.<onnx.IStringStringEntryProto>|null} [metadataProps] ModelProto metadataProps
*/
/**
* Constructs a new ModelProto.
* @memberof onnx
* @classdesc Represents a ModelProto.
* @implements IModelProto
* @constructor
* @param {onnx.IModelProto=} [properties] Properties to set
*/
function ModelProto(properties) {
this.opsetImport = [];
this.metadataProps = [];
if (properties)
for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
if (properties[keys[i]] != null)
this[keys[i]] = properties[keys[i]];
}
/**
* ModelProto irVersion.
* @member {number|Long} irVersion
* @memberof onnx.ModelProto
* @instance
*/
ModelProto.prototype.irVersion = $util.Long ? $util.Long.fromBits(0,0,false) : 0;
/**
* ModelProto opsetImport.
* @member {Array.<onnx.IOperatorSetIdProto>} opsetImport
* @memberof onnx.ModelProto
* @instance
*/
ModelProto.prototype.opsetImport = $util.emptyArray;
/**
* ModelProto producerName.
* @member {string} producerName
* @memberof onnx.ModelProto
* @instance
*/
ModelProto.prototype.producerName = "";
/**
* ModelProto producerVersion.
* @member {string} producerVersion
* @memberof onnx.ModelProto
* @instance
*/
ModelProto.prototype.producerVersion = "";
/**
* ModelProto domain.
* @member {string} domain
* @memberof onnx.ModelProto
* @instance
*/
ModelProto.prototype.domain = "";
/**
* ModelProto modelVersion.
* @member {number|Long} modelVersion
* @memberof onnx.ModelProto
* @instance
*/
ModelProto.prototype.modelVersion = $util.Long ? $util.Long.fromBits(0,0,false) : 0;
/**
* ModelProto docString.
* @member {string} docString
* @memberof onnx.ModelProto
* @instance
*/
ModelProto.prototype.docString = "";
/**
* ModelProto graph.
* @member {onnx.IGraphProto|null|undefined} graph
* @memberof onnx.ModelProto
* @instance
*/
ModelProto.prototype.graph = null;
/**
* ModelProto metadataProps.
* @member {Array.<onnx.IStringStringEntryProto>} metadataProps
* @memberof onnx.ModelProto
* @instance
*/
ModelProto.prototype.metadataProps = $util.emptyArray;
/**
* Creates a new ModelProto instance using the specified properties.
* @function create
* @memberof onnx.ModelProto
* @static
* @param {onnx.IModelProto=} [properties] Properties to set
* @returns {onnx.ModelProto} ModelProto instance
*/
ModelProto.create = function create(properties) {
return new ModelProto(properties);
};
/**
* Encodes the specified ModelProto message. Does not implicitly {@link onnx.ModelProto.verify|verify} messages.
* @function encode
* @memberof onnx.ModelProto
* @static
* @param {onnx.IModelProto} message ModelProto message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
ModelProto.encode = function encode(message, writer) {
if (!writer)
writer = $Writer.create();
if (message.irVersion != null && message.hasOwnProperty("irVersion"))
writer.uint32(/* id 1, wireType 0 =*/8).int64(message.irVersion);
if (message.producerName != null && message.hasOwnProperty("producerName"))
writer.uint32(/* id 2, wireType 2 =*/18).string(message.producerName);
if (message.producerVersion != null && message.hasOwnProperty("producerVersion"))
writer.uint32(/* id 3, wireType 2 =*/26).string(message.producerVersion);
if (message.domain != null && message.hasOwnProperty("domain"))
writer.uint32(/* id 4, wireType 2 =*/34).string(message.domain);
if (message.modelVersion != null && message.hasOwnProperty("modelVersion"))
writer.uint32(/* id 5, wireType 0 =*/40).int64(message.modelVersion);
if (message.docString != null && message.hasOwnProperty("docString"))
writer.uint32(/* id 6, wireType 2 =*/50).string(message.docString);
if (message.graph != null && message.hasOwnProperty("graph"))
$root.onnx.GraphProto.encode(message.graph, writer.uint32(/* id 7, wireType 2 =*/58).fork()).ldelim();
if (message.opsetImport != null && message.opsetImport.length)
for (var i = 0; i < message.opsetImport.length; ++i)
$root.onnx.OperatorSetIdProto.encode(message.opsetImport[i], writer.uint32(/* id 8, wireType 2 =*/66).fork()).ldelim();
if (message.metadataProps != null && message.metadataProps.length)
for (var i = 0; i < message.metadataProps.length; ++i)
$root.onnx.StringStringEntryProto.encode(message.metadataProps[i], writer.uint32(/* id 14, wireType 2 =*/114).fork()).ldelim();
return writer;
};
/**
* Encodes the specified ModelProto message, length delimited. Does not implicitly {@link onnx.ModelProto.verify|verify} messages.
* @function encodeDelimited
* @memberof onnx.ModelProto
* @static
* @param {onnx.IModelProto} message ModelProto message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
ModelProto.encodeDelimited = function encodeDelimited(message, writer) {
return this.encode(message, writer).ldelim();
};
/**
* Decodes a ModelProto message from the specified reader or buffer.
* @function decode
* @memberof onnx.ModelProto
* @static
* @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
* @param {number} [length] Message length if known beforehand
* @returns {onnx.ModelProto} ModelProto
* @throws {Error} If the payload is not a reader or valid buffer
* @throws {$protobuf.util.ProtocolError} If required fields are missing
*/
ModelProto.decode = function decode(reader, length) {
if (!(reader instanceof $Reader))
reader = $Reader.create(reader);
var end = length === undefined ? reader.len : reader.pos + length, message = new $root.onnx.ModelProto();
while (reader.pos < end) {
var tag = reader.uint32();
switch (tag >>> 3) {
case 1:
message.irVersion = reader.int64();
break;
case 8:
if (!(message.opsetImport && message.opsetImport.length))
message.opsetImport = [];
message.opsetImport.push($root.onnx.OperatorSetIdProto.decode(reader, reader.uint32()));
break;
case 2:
message.producerName = reader.string();
break;
case 3:
message.producerVersion = reader.string();
break;
case 4:
message.domain = reader.string();
break;
case 5:
message.modelVersion = reader.int64();
break;
case 6:
message.docString = reader.string();
break;
case 7:
message.graph = $root.onnx.GraphProto.decode(reader, reader.uint32());
break;
case 14:
if (!(message.metadataProps && message.metadataProps.length))
message.metadataProps = [];
message.metadataProps.push($root.onnx.StringStringEntryProto.decode(reader, reader.uint32()));
break;
default:
reader.skipType(tag & 7);
break;
}
}
return message;
};
/**
* Decodes a ModelProto message from the specified reader or buffer, length delimited.
* @function decodeDelimited
* @memberof onnx.ModelProto
* @static
* @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
* @returns {onnx.ModelProto} ModelProto
* @throws {Error} If the payload is not a reader or valid buffer
* @throws {$protobuf.util.ProtocolError} If required fields are missing
*/
ModelProto.decodeDelimited = function decodeDelimited(reader) {
if (!(reader instanceof $Reader))
reader = new $Reader(reader);
return this.decode(reader, reader.uint32());
};
/**
* Verifies a ModelProto message.
* @function verify
* @memberof onnx.ModelProto
* @static
* @param {Object.<string,*>} message Plain object to verify
* @returns {string|null} `null` if valid, otherwise the reason why it is not
*/
ModelProto.verify = function verify(message) {
if (typeof message !== "object" || message === null)
return "object expected";
if (message.irVersion != null && message.hasOwnProperty("irVersion"))
if (!$util.isInteger(message.irVersion) && !(message.irVersion && $util.isInteger(message.irVersion.low) && $util.isInteger(message.irVersion.high)))
return "irVersion: integer|Long expected";
if (message.opsetImport != null && message.hasOwnProperty("opsetImport")) {
if (!Array.isArray(message.opsetImport))
return "opsetImport: array expected";
for (var i = 0; i < message.opsetImport.length; ++i) {
var error = $root.onnx.OperatorSetIdProto.verify(message.opsetImport[i]);
if (error)
return "opsetImport." + error;
}
}
if (message.producerName != null && message.hasOwnProperty("producerName"))
if (!$util.isString(message.producerName))
return "producerName: string expected";
if (message.producerVersion != null && message.hasOwnProperty("producerVersion"))
if (!$util.isString(message.producerVersion))
return "producerVersion: string expected";
if (message.domain != null && message.hasOwnProperty("domain"))
if (!$util.isString(message.domain))
return "domain: string expected";
if (message.modelVersion != null && message.hasOwnProperty("modelVersion"))
if (!$util.isInteger(message.modelVersion) && !(message.modelVersion && $util.isInteger(message.modelVersion.low) && $util.isInteger(message.modelVersion.high)))
return "modelVersion: integer|Long expected";
if (message.docString != null && message.hasOwnProperty("docString"))
if (!$util.isString(message.docString))
return "docString: string expected";
if (message.graph != null && message.hasOwnProperty("graph")) {
var error = $root.onnx.GraphProto.verify(message.graph);
if (error)
return "graph." + error;
}
if (message.metadataProps != null && message.hasOwnProperty("metadataProps")) {
if (!Array.isArray(message.metadataProps))
return "metadataProps: array expected";
for (var i = 0; i < message.metadataProps.length; ++i) {
var error = $root.onnx.StringStringEntryProto.verify(message.metadataProps[i]);
if (error)
return "metadataProps." + error;
}
}
return null;
};
/**
* Creates a ModelProto message from a plain object. Also converts values to their respective internal types.
* @function fromObject
* @memberof onnx.ModelProto
* @static
* @param {Object.<string,*>} object Plain object
* @returns {onnx.ModelProto} ModelProto
*/
ModelProto.fromObject = function fromObject(object) {
if (object instanceof $root.onnx.ModelProto)
return object;
var message = new $root.onnx.ModelProto();
if (object.irVersion != null)
if ($util.Long)
(message.irVersion = $util.Long.fromValue(object.irVersion)).unsigned = false;
else if (typeof object.irVersion === "string")
message.irVersion = parseInt(object.irVersion, 10);
else if (typeof object.irVersion === "number")
message.irVersion = object.irVersion;
else if (typeof object.irVersion === "object")
message.irVersion = new $util.LongBits(object.irVersion.low >>> 0, object.irVersion.high >>> 0).toNumber();
if (object.opsetImport) {
if (!Array.isArray(object.opsetImport))
throw TypeError(".onnx.ModelProto.opsetImport: array expected");
message.opsetImport = [];
for (var i = 0; i < object.opsetImport.length; ++i) {
if (typeof object.opsetImport[i] !== "object")
throw TypeError(".onnx.ModelProto.opsetImport: object expected");
message.opsetImport[i] = $root.onnx.OperatorSetIdProto.fromObject(object.opsetImport[i]);
}
}
if (object.producerName != null)
message.producerName = String(object.producerName);
if (object.producerVersion != null)
message.producerVersion = String(object.producerVersion);
if (object.domain != null)
message.domain = String(object.domain);
if (object.modelVersion != null)
if ($util.Long)
(message.modelVersion = $util.Long.fromValue(object.modelVersion)).unsigned = false;
else if (typeof object.modelVersion === "string")
message.modelVersion = parseInt(object.modelVersion, 10);
else if (typeof object.modelVersion === "number")
message.modelVersion = object.modelVersion;
else if (typeof object.modelVersion === "object")
message.modelVersion = new $util.LongBits(object.modelVersion.low >>> 0, object.modelVersion.high >>> 0).toNumber();
if (object.docString != null)
message.docString = String(object.docString);
if (object.graph != null) {
if (typeof object.graph !== "object")
throw TypeError(".onnx.ModelProto.graph: object expected");
message.graph = $root.onnx.GraphProto.fromObject(object.graph);
}
if (object.metadataProps) {
if (!Array.isArray(object.metadataProps))
throw TypeError(".onnx.ModelProto.metadataProps: array expected");
message.metadataProps = [];
for (var i = 0; i < object.metadataProps.length; ++i) {
if (typeof object.metadataProps[i] !== "object")
throw TypeError(".onnx.ModelProto.metadataProps: object expected");
message.metadataProps[i] = $root.onnx.StringStringEntryProto.fromObject(object.metadataProps[i]);
}
}
return message;
};
/**
* Creates a plain object from a ModelProto message. Also converts values to other types if specified.
* @function toObject
* @memberof onnx.ModelProto
* @static
* @param {onnx.ModelProto} message ModelProto
* @param {$protobuf.IConversionOptions} [options] Conversion options
* @returns {Object.<string,*>} Plain object
*/
ModelProto.toObject = function toObject(message, options) {
if (!options)
options = {};
var object = {};
if (options.arrays || options.defaults) {
object.opsetImport = [];
object.metadataProps = [];
}
if (options.defaults) {
if ($util.Long) {
var long = new $util.Long(0, 0, false);
object.irVersion = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
} else
object.irVersion = options.longs === String ? "0" : 0;
object.producerName = "";
object.producerVersion = "";
object.domain = "";
if ($util.Long) {
var long = new $util.Long(0, 0, false);
object.modelVersion = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
} else
object.modelVersion = options.longs === String ? "0" : 0;
object.docString = "";
object.graph = null;
}
if (message.irVersion != null && message.hasOwnProperty("irVersion"))
if (typeof message.irVersion === "number")
object.irVersion = options.longs === String ? String(message.irVersion) : message.irVersion;
else
object.irVersion = options.longs === String ? $util.Long.prototype.toString.call(message.irVersion) : options.longs === Number ? new $util.LongBits(message.irVersion.low >>> 0, message.irVersion.high >>> 0).toNumber() : message.irVersion;
if (message.producerName != null && message.hasOwnProperty("producerName"))
object.producerName = message.producerName;
if (message.producerVersion != null && message.hasOwnProperty("producerVersion"))
object.producerVersion = message.producerVersion;
if (message.domain != null && message.hasOwnProperty("domain"))
object.domain = message.domain;
if (message.modelVersion != null && message.hasOwnProperty("modelVersion"))
if (typeof message.modelVersion === "number")
object.modelVersion = options.longs === String ? String(message.modelVersion) : message.modelVersion;
else
object.modelVersion = options.longs === String ? $util.Long.prototype.toString.call(message.modelVersion) : options.longs === Number ? new $util.LongBits(message.modelVersion.low >>> 0, message.modelVersion.high >>> 0).toNumber() : message.modelVersion;
if (message.docString != null && message.hasOwnProperty("docString"))
object.docString = message.docString;
if (message.graph != null && message.hasOwnProperty("graph"))
object.graph = $root.onnx.GraphProto.toObject(message.graph, options);
if (message.opsetImport && message.opsetImport.length) {
object.opsetImport = [];
for (var j = 0; j < message.opsetImport.length; ++j)
object.opsetImport[j] = $root.onnx.OperatorSetIdProto.toObject(message.opsetImport[j], options);
}
if (message.metadataProps && message.metadataProps.length) {
object.metadataProps = [];
for (var j = 0; j < message.metadataProps.length; ++j)
object.metadataProps[j] = $root.onnx.StringStringEntryProto.toObject(message.metadataProps[j], options);
}
return object;
};
/**
* Converts this ModelProto to JSON.
* @function toJSON
* @memberof onnx.ModelProto
* @instance
* @returns {Object.<string,*>} JSON object
*/
ModelProto.prototype.toJSON = function toJSON() {
return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
};
return ModelProto;
})();
onnx.StringStringEntryProto = (function() {
/**
* Properties of a StringStringEntryProto.
* @memberof onnx
* @interface IStringStringEntryProto
* @property {string|null} [key] StringStringEntryProto key
* @property {string|null} [value] StringStringEntryProto value
*/
/**
* Constructs a new StringStringEntryProto.
* @memberof onnx
* @classdesc Represents a StringStringEntryProto.
* @implements IStringStringEntryProto
* @constructor
* @param {onnx.IStringStringEntryProto=} [properties] Properties to set
*/
function StringStringEntryProto(properties) {
if (properties)
for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
if (properties[keys[i]] != null)
this[keys[i]] = properties[keys[i]];
}
/**
* StringStringEntryProto key.
* @member {string} key
* @memberof onnx.StringStringEntryProto
* @instance
*/
StringStringEntryProto.prototype.key = "";
/**
* StringStringEntryProto value.
* @member {string} value
* @memberof onnx.StringStringEntryProto
* @instance
*/
StringStringEntryProto.prototype.value = "";
/**
* Creates a new StringStringEntryProto instance using the specified properties.
* @function create
* @memberof onnx.StringStringEntryProto
* @static
* @param {onnx.IStringStringEntryProto=} [properties] Properties to set
* @returns {onnx.StringStringEntryProto} StringStringEntryProto instance
*/
StringStringEntryProto.create = function create(properties) {
return new StringStringEntryProto(properties);
};
/**
* Encodes the specified StringStringEntryProto message. Does not implicitly {@link onnx.StringStringEntryProto.verify|verify} messages.
* @function encode
* @memberof onnx.StringStringEntryProto
* @static
* @param {onnx.IStringStringEntryProto} message StringStringEntryProto message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
StringStringEntryProto.encode = function encode(message, writer) {
if (!writer)
writer = $Writer.create();
if (message.key != null && message.hasOwnProperty("key"))
writer.uint32(/* id 1, wireType 2 =*/10).string(message.key);
if (message.value != null && message.hasOwnProperty("value"))
writer.uint32(/* id 2, wireType 2 =*/18).string(message.value);
return writer;
};
/**
* Encodes the specified StringStringEntryProto message, length delimited. Does not implicitly {@link onnx.StringStringEntryProto.verify|verify} messages.
* @function encodeDelimited
* @memberof onnx.StringStringEntryProto
* @static
* @param {onnx.IStringStringEntryProto} message StringStringEntryProto message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
StringStringEntryProto.encodeDelimited = function encodeDelimited(message, writer) {
return this.encode(message, writer).ldelim();
};
/**
* Decodes a StringStringEntryProto message from the specified reader or buffer.
* @function decode
* @memberof onnx.StringStringEntryProto
* @static
* @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
* @param {number} [length] Message length if known beforehand
* @returns {onnx.StringStringEntryProto} StringStringEntryProto
* @throws {Error} If the payload is not a reader or valid buffer
* @throws {$protobuf.util.ProtocolError} If required fields are missing
*/
StringStringEntryProto.decode = function decode(reader, length) {
if (!(reader instanceof $Reader))
reader = $Reader.create(reader);
var end = length === undefined ? reader.len : reader.pos + length, message = new $root.onnx.StringStringEntryProto();
while (reader.pos < end) {
var tag = reader.uint32();
switch (tag >>> 3) {
case 1:
message.key = reader.string();
break;
case 2:
message.value = reader.string();
break;
default:
reader.skipType(tag & 7);
break;
}
}
return message;
};
/**
* Decodes a StringStringEntryProto message from the specified reader or buffer, length delimited.
* @function decodeDelimited
* @memberof onnx.StringStringEntryProto
* @static
* @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
* @returns {onnx.StringStringEntryProto} StringStringEntryProto
* @throws {Error} If the payload is not a reader or valid buffer
* @throws {$protobuf.util.ProtocolError} If required fields are missing
*/
StringStringEntryProto.decodeDelimited = function decodeDelimited(reader) {
if (!(reader instanceof $Reader))
reader = new $Reader(reader);
return this.decode(reader, reader.uint32());
};
/**
* Verifies a StringStringEntryProto message.
* @function verify
* @memberof onnx.StringStringEntryProto
* @static
* @param {Object.<string,*>} message Plain object to verify
* @returns {string|null} `null` if valid, otherwise the reason why it is not
*/
StringStringEntryProto.verify = function verify(message) {
if (typeof message !== "object" || message === null)
return "object expected";
if (message.key != null && message.hasOwnProperty("key"))
if (!$util.isString(message.key))
return "key: string expected";
if (message.value != null && message.hasOwnProperty("value"))
if (!$util.isString(message.value))
return "value: string expected";
return null;
};
/**
* Creates a StringStringEntryProto message from a plain object. Also converts values to their respective internal types.
* @function fromObject
* @memberof onnx.StringStringEntryProto
* @static
* @param {Object.<string,*>} object Plain object
* @returns {onnx.StringStringEntryProto} StringStringEntryProto
*/
StringStringEntryProto.fromObject = function fromObject(object) {
if (object instanceof $root.onnx.StringStringEntryProto)
return object;
var message = new $root.onnx.StringStringEntryProto();
if (object.key != null)
message.key = String(object.key);
if (object.value != null)
message.value = String(object.value);
return message;
};
/**
* Creates a plain object from a StringStringEntryProto message. Also converts values to other types if specified.
* @function toObject
* @memberof onnx.StringStringEntryProto
* @static
* @param {onnx.StringStringEntryProto} message StringStringEntryProto
* @param {$protobuf.IConversionOptions} [options] Conversion options
* @returns {Object.<string,*>} Plain object
*/
StringStringEntryProto.toObject = function toObject(message, options) {
if (!options)
options = {};
var object = {};
if (options.defaults) {
object.key = "";
object.value = "";
}
if (message.key != null && message.hasOwnProperty("key"))
object.key = message.key;
if (message.value != null && message.hasOwnProperty("value"))
object.value = message.value;
return object;
};
/**
* Converts this StringStringEntryProto to JSON.
* @function toJSON
* @memberof onnx.StringStringEntryProto
* @instance
* @returns {Object.<string,*>} JSON object
*/
StringStringEntryProto.prototype.toJSON = function toJSON() {
return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
};
return StringStringEntryProto;
})();
onnx.TensorAnnotation = (function() {
/**
* Properties of a TensorAnnotation.
* @memberof onnx
* @interface ITensorAnnotation
* @property {string|null} [tensorName] TensorAnnotation tensorName
* @property {Array.<onnx.IStringStringEntryProto>|null} [quantParameterTensorNames] TensorAnnotation quantParameterTensorNames
*/
/**
* Constructs a new TensorAnnotation.
* @memberof onnx
* @classdesc Represents a TensorAnnotation.
* @implements ITensorAnnotation
* @constructor
* @param {onnx.ITensorAnnotation=} [properties] Properties to set
*/
function TensorAnnotation(properties) {
this.quantParameterTensorNames = [];
if (properties)
for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
if (properties[keys[i]] != null)
this[keys[i]] = properties[keys[i]];
}
/**
* TensorAnnotation tensorName.
* @member {string} tensorName
* @memberof onnx.TensorAnnotation
* @instance
*/
TensorAnnotation.prototype.tensorName = "";
/**
* TensorAnnotation quantParameterTensorNames.
* @member {Array.<onnx.IStringStringEntryProto>} quantParameterTensorNames
* @memberof onnx.TensorAnnotation
* @instance
*/
TensorAnnotation.prototype.quantParameterTensorNames = $util.emptyArray;
/**
* Creates a new TensorAnnotation instance using the specified properties.
* @function create
* @memberof onnx.TensorAnnotation
* @static
* @param {onnx.ITensorAnnotation=} [properties] Properties to set
* @returns {onnx.TensorAnnotation} TensorAnnotation instance
*/
TensorAnnotation.create = function create(properties) {
return new TensorAnnotation(properties);
};
/**
* Encodes the specified TensorAnnotation message. Does not implicitly {@link onnx.TensorAnnotation.verify|verify} messages.
* @function encode
* @memberof onnx.TensorAnnotation
* @static
* @param {onnx.ITensorAnnotation} message TensorAnnotation message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
TensorAnnotation.encode = function encode(message, writer) {
if (!writer)
writer = $Writer.create();
if (message.tensorName != null && message.hasOwnProperty("tensorName"))
writer.uint32(/* id 1, wireType 2 =*/10).string(message.tensorName);
if (message.quantParameterTensorNames != null && message.quantParameterTensorNames.length)
for (var i = 0; i < message.quantParameterTensorNames.length; ++i)
$root.onnx.StringStringEntryProto.encode(message.quantParameterTensorNames[i], writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
return writer;
};
/**
* Encodes the specified TensorAnnotation message, length delimited. Does not implicitly {@link onnx.TensorAnnotation.verify|verify} messages.
* @function encodeDelimited
* @memberof onnx.TensorAnnotation
* @static
* @param {onnx.ITensorAnnotation} message TensorAnnotation message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
TensorAnnotation.encodeDelimited = function encodeDelimited(message, writer) {
return this.encode(message, writer).ldelim();
};
/**
* Decodes a TensorAnnotation message from the specified reader or buffer.
* @function decode
* @memberof onnx.TensorAnnotation
* @static
* @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
* @param {number} [length] Message length if known beforehand
* @returns {onnx.TensorAnnotation} TensorAnnotation
* @throws {Error} If the payload is not a reader or valid buffer
* @throws {$protobuf.util.ProtocolError} If required fields are missing
*/
TensorAnnotation.decode = function decode(reader, length) {
if (!(reader instanceof $Reader))
reader = $Reader.create(reader);
var end = length === undefined ? reader.len : reader.pos + length, message = new $root.onnx.TensorAnnotation();
while (reader.pos < end) {
var tag = reader.uint32();
switch (tag >>> 3) {
case 1:
message.tensorName = reader.string();
break;
case 2:
if (!(message.quantParameterTensorNames && message.quantParameterTensorNames.length))
message.quantParameterTensorNames = [];
message.quantParameterTensorNames.push($root.onnx.StringStringEntryProto.decode(reader, reader.uint32()));
break;
default:
reader.skipType(tag & 7);
break;
}
}
return message;
};
/**
* Decodes a TensorAnnotation message from the specified reader or buffer, length delimited.
* @function decodeDelimited
* @memberof onnx.TensorAnnotation
* @static
* @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
* @returns {onnx.TensorAnnotation} TensorAnnotation
* @throws {Error} If the payload is not a reader or valid buffer
* @throws {$protobuf.util.ProtocolError} If required fields are missing
*/
TensorAnnotation.decodeDelimited = function decodeDelimited(reader) {
if (!(reader instanceof $Reader))
reader = new $Reader(reader);
return this.decode(reader, reader.uint32());
};
/**
* Verifies a TensorAnnotation message.
* @function verify
* @memberof onnx.TensorAnnotation
* @static
* @param {Object.<string,*>} message Plain object to verify
* @returns {string|null} `null` if valid, otherwise the reason why it is not
*/
TensorAnnotation.verify = function verify(message) {
if (typeof message !== "object" || message === null)
return "object expected";
if (message.tensorName != null && message.hasOwnProperty("tensorName"))
if (!$util.isString(message.tensorName))
return "tensorName: string expected";
if (message.quantParameterTensorNames != null && message.hasOwnProperty("quantParameterTensorNames")) {
if (!Array.isArray(message.quantParameterTensorNames))
return "quantParameterTensorNames: array expected";
for (var i = 0; i < message.quantParameterTensorNames.length; ++i) {
var error = $root.onnx.StringStringEntryProto.verify(message.quantParameterTensorNames[i]);
if (error)
return "quantParameterTensorNames." + error;
}
}
return null;
};
/**
* Creates a TensorAnnotation message from a plain object. Also converts values to their respective internal types.
* @function fromObject
* @memberof onnx.TensorAnnotation
* @static
* @param {Object.<string,*>} object Plain object
* @returns {onnx.TensorAnnotation} TensorAnnotation
*/
TensorAnnotation.fromObject = function fromObject(object) {
if (object instanceof $root.onnx.TensorAnnotation)
return object;
var message = new $root.onnx.TensorAnnotation();
if (object.tensorName != null)
message.tensorName = String(object.tensorName);
if (object.quantParameterTensorNames) {
if (!Array.isArray(object.quantParameterTensorNames))
throw TypeError(".onnx.TensorAnnotation.quantParameterTensorNames: array expected");
message.quantParameterTensorNames = [];
for (var i = 0; i < object.quantParameterTensorNames.length; ++i) {
if (typeof object.quantParameterTensorNames[i] !== "object")
throw TypeError(".onnx.TensorAnnotation.quantParameterTensorNames: object expected");
message.quantParameterTensorNames[i] = $root.onnx.StringStringEntryProto.fromObject(object.quantParameterTensorNames[i]);
}
}
return message;
};
/**
* Creates a plain object from a TensorAnnotation message. Also converts values to other types if specified.
* @function toObject
* @memberof onnx.TensorAnnotation
* @static
* @param {onnx.TensorAnnotation} message TensorAnnotation
* @param {$protobuf.IConversionOptions} [options] Conversion options
* @returns {Object.<string,*>} Plain object
*/
TensorAnnotation.toObject = function toObject(message, options) {
if (!options)
options = {};
var object = {};
if (options.arrays || options.defaults)
object.quantParameterTensorNames = [];
if (options.defaults)
object.tensorName = "";
if (message.tensorName != null && message.hasOwnProperty("tensorName"))
object.tensorName = message.tensorName;
if (message.quantParameterTensorNames && message.quantParameterTensorNames.length) {
object.quantParameterTensorNames = [];
for (var j = 0; j < message.quantParameterTensorNames.length; ++j)
object.quantParameterTensorNames[j] = $root.onnx.StringStringEntryProto.toObject(message.quantParameterTensorNames[j], options);
}
return object;
};
/**
* Converts this TensorAnnotation to JSON.
* @function toJSON
* @memberof onnx.TensorAnnotation
* @instance
* @returns {Object.<string,*>} JSON object
*/
TensorAnnotation.prototype.toJSON = function toJSON() {
return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
};
return TensorAnnotation;
})();
onnx.GraphProto = (function() {
/**
* Properties of a GraphProto.
* @memberof onnx
* @interface IGraphProto
* @property {Array.<onnx.INodeProto>|null} [node] GraphProto node
* @property {string|null} [name] GraphProto name
* @property {Array.<onnx.ITensorProto>|null} [initializer] GraphProto initializer
* @property {string|null} [docString] GraphProto docString
* @property {Array.<onnx.IValueInfoProto>|null} [input] GraphProto input
* @property {Array.<onnx.IValueInfoProto>|null} [output] GraphProto output
* @property {Array.<onnx.IValueInfoProto>|null} [valueInfo] GraphProto valueInfo
* @property {Array.<onnx.ITensorAnnotation>|null} [quantizationAnnotation] GraphProto quantizationAnnotation
*/
/**
* Constructs a new GraphProto.
* @memberof onnx
* @classdesc Represents a GraphProto.
* @implements IGraphProto
* @constructor
* @param {onnx.IGraphProto=} [properties] Properties to set
*/
function GraphProto(properties) {
this.node = [];
this.initializer = [];
this.input = [];
this.output = [];
this.valueInfo = [];
this.quantizationAnnotation = [];
if (properties)
for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
if (properties[keys[i]] != null)
this[keys[i]] = properties[keys[i]];
}
/**
* GraphProto node.
* @member {Array.<onnx.INodeProto>} node
* @memberof onnx.GraphProto
* @instance
*/
GraphProto.prototype.node = $util.emptyArray;
/**
* GraphProto name.
* @member {string} name
* @memberof onnx.GraphProto
* @instance
*/
GraphProto.prototype.name = "";
/**
* GraphProto initializer.
* @member {Array.<onnx.ITensorProto>} initializer
* @memberof onnx.GraphProto
* @instance
*/
GraphProto.prototype.initializer = $util.emptyArray;
/**
* GraphProto docString.
* @member {string} docString
* @memberof onnx.GraphProto
* @instance
*/
GraphProto.prototype.docString = "";
/**
* GraphProto input.
* @member {Array.<onnx.IValueInfoProto>} input
* @memberof onnx.GraphProto
* @instance
*/
GraphProto.prototype.input = $util.emptyArray;
/**
* GraphProto output.
* @member {Array.<onnx.IValueInfoProto>} output
* @memberof onnx.GraphProto
* @instance
*/
GraphProto.prototype.output = $util.emptyArray;
/**
* GraphProto valueInfo.
* @member {Array.<onnx.IValueInfoProto>} valueInfo
* @memberof onnx.GraphProto
* @instance
*/
GraphProto.prototype.valueInfo = $util.emptyArray;
/**
* GraphProto quantizationAnnotation.
* @member {Array.<onnx.ITensorAnnotation>} quantizationAnnotation
* @memberof onnx.GraphProto
* @instance
*/
GraphProto.prototype.quantizationAnnotation = $util.emptyArray;
/**
* Creates a new GraphProto instance using the specified properties.
* @function create
* @memberof onnx.GraphProto
* @static
* @param {onnx.IGraphProto=} [properties] Properties to set
* @returns {onnx.GraphProto} GraphProto instance
*/
GraphProto.create = function create(properties) {
return new GraphProto(properties);
};
/**
* Encodes the specified GraphProto message. Does not implicitly {@link onnx.GraphProto.verify|verify} messages.
* @function encode
* @memberof onnx.GraphProto
* @static
* @param {onnx.IGraphProto} message GraphProto message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
GraphProto.encode = function encode(message, writer) {
if (!writer)
writer = $Writer.create();
if (message.node != null && message.node.length)
for (var i = 0; i < message.node.length; ++i)
$root.onnx.NodeProto.encode(message.node[i], writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
if (message.name != null && message.hasOwnProperty("name"))
writer.uint32(/* id 2, wireType 2 =*/18).string(message.name);
if (message.initializer != null && message.initializer.length)
for (var i = 0; i < message.initializer.length; ++i)
$root.onnx.TensorProto.encode(message.initializer[i], writer.uint32(/* id 5, wireType 2 =*/42).fork()).ldelim();
if (message.docString != null && message.hasOwnProperty("docString"))
writer.uint32(/* id 10, wireType 2 =*/82).string(message.docString);
if (message.input != null && message.input.length)
for (var i = 0; i < message.input.length; ++i)
$root.onnx.ValueInfoProto.encode(message.input[i], writer.uint32(/* id 11, wireType 2 =*/90).fork()).ldelim();
if (message.output != null && message.output.length)
for (var i = 0; i < message.output.length; ++i)
$root.onnx.ValueInfoProto.encode(message.output[i], writer.uint32(/* id 12, wireType 2 =*/98).fork()).ldelim();
if (message.valueInfo != null && message.valueInfo.length)
for (var i = 0; i < message.valueInfo.length; ++i)
$root.onnx.ValueInfoProto.encode(message.valueInfo[i], writer.uint32(/* id 13, wireType 2 =*/106).fork()).ldelim();
if (message.quantizationAnnotation != null && message.quantizationAnnotation.length)
for (var i = 0; i < message.quantizationAnnotation.length; ++i)
$root.onnx.TensorAnnotation.encode(message.quantizationAnnotation[i], writer.uint32(/* id 14, wireType 2 =*/114).fork()).ldelim();
return writer;
};
/**
* Encodes the specified GraphProto message, length delimited. Does not implicitly {@link onnx.GraphProto.verify|verify} messages.
* @function encodeDelimited
* @memberof onnx.GraphProto
* @static
* @param {onnx.IGraphProto} message GraphProto message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
GraphProto.encodeDelimited = function encodeDelimited(message, writer) {
return this.encode(message, writer).ldelim();
};
/**
* Decodes a GraphProto message from the specified reader or buffer.
* @function decode
* @memberof onnx.GraphProto
* @static
* @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
* @param {number} [length] Message length if known beforehand
* @returns {onnx.GraphProto} GraphProto
* @throws {Error} If the payload is not a reader or valid buffer
* @throws {$protobuf.util.ProtocolError} If required fields are missing
*/
GraphProto.decode = function decode(reader, length) {
if (!(reader instanceof $Reader))
reader = $Reader.create(reader);
var end = length === undefined ? reader.len : reader.pos + length, message = new $root.onnx.GraphProto();
while (reader.pos < end) {
var tag = reader.uint32();
switch (tag >>> 3) {
case 1:
if (!(message.node && message.node.length))
message.node = [];
message.node.push($root.onnx.NodeProto.decode(reader, reader.uint32()));
break;
case 2:
message.name = reader.string();
break;
case 5:
if (!(message.initializer && message.initializer.length))
message.initializer = [];
message.initializer.push($root.onnx.TensorProto.decode(reader, reader.uint32()));
break;
case 10:
message.docString = reader.string();
break;
case 11:
if (!(message.input && message.input.length))
message.input = [];
message.input.push($root.onnx.ValueInfoProto.decode(reader, reader.uint32()));
break;
case 12:
if (!(message.output && message.output.length))
message.output = [];
message.output.push($root.onnx.ValueInfoProto.decode(reader, reader.uint32()));
break;
case 13:
if (!(message.valueInfo && message.valueInfo.length))
message.valueInfo = [];
message.valueInfo.push($root.onnx.ValueInfoProto.decode(reader, reader.uint32()));
break;
case 14:
if (!(message.quantizationAnnotation && message.quantizationAnnotation.length))
message.quantizationAnnotation = [];
message.quantizationAnnotation.push($root.onnx.TensorAnnotation.decode(reader, reader.uint32()));
break;
default:
reader.skipType(tag & 7);
break;
}
}
return message;
};
/**
* Decodes a GraphProto message from the specified reader or buffer, length delimited.
* @function decodeDelimited
* @memberof onnx.GraphProto
* @static
* @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
* @returns {onnx.GraphProto} GraphProto
* @throws {Error} If the payload is not a reader or valid buffer
* @throws {$protobuf.util.ProtocolError} If required fields are missing
*/
GraphProto.decodeDelimited = function decodeDelimited(reader) {
if (!(reader instanceof $Reader))
reader = new $Reader(reader);
return this.decode(reader, reader.uint32());
};
/**
* Verifies a GraphProto message.
* @function verify
* @memberof onnx.GraphProto
* @static
* @param {Object.<string,*>} message Plain object to verify
* @returns {string|null} `null` if valid, otherwise the reason why it is not
*/
GraphProto.verify = function verify(message) {
if (typeof message !== "object" || message === null)
return "object expected";
if (message.node != null && message.hasOwnProperty("node")) {
if (!Array.isArray(message.node))
return "node: array expected";
for (var i = 0; i < message.node.length; ++i) {
var error = $root.onnx.NodeProto.verify(message.node[i]);
if (error)
return "node." + error;
}
}
if (message.name != null && message.hasOwnProperty("name"))
if (!$util.isString(message.name))
return "name: string expected";
if (message.initializer != null && message.hasOwnProperty("initializer")) {
if (!Array.isArray(message.initializer))
return "initializer: array expected";
for (var i = 0; i < message.initializer.length; ++i) {
var error = $root.onnx.TensorProto.verify(message.initializer[i]);
if (error)
return "initializer." + error;
}
}
if (message.docString != null && message.hasOwnProperty("docString"))
if (!$util.isString(message.docString))
return "docString: string expected";
if (message.input != null && message.hasOwnProperty("input")) {
if (!Array.isArray(message.input))
return "input: array expected";
for (var i = 0; i < message.input.length; ++i) {
var error = $root.onnx.ValueInfoProto.verify(message.input[i]);
if (error)
return "input." + error;
}
}
if (message.output != null && message.hasOwnProperty("output")) {
if (!Array.isArray(message.output))
return "output: array expected";
for (var i = 0; i < message.output.length; ++i) {
var error = $root.onnx.ValueInfoProto.verify(message.output[i]);
if (error)
return "output." + error;
}
}
if (message.valueInfo != null && message.hasOwnProperty("valueInfo")) {
if (!Array.isArray(message.valueInfo))
return "valueInfo: array expected";
for (var i = 0; i < message.valueInfo.length; ++i) {
var error = $root.onnx.ValueInfoProto.verify(message.valueInfo[i]);
if (error)
return "valueInfo." + error;
}
}
if (message.quantizationAnnotation != null && message.hasOwnProperty("quantizationAnnotation")) {
if (!Array.isArray(message.quantizationAnnotation))
return "quantizationAnnotation: array expected";
for (var i = 0; i < message.quantizationAnnotation.length; ++i) {
var error = $root.onnx.TensorAnnotation.verify(message.quantizationAnnotation[i]);
if (error)
return "quantizationAnnotation." + error;
}
}
return null;
};
/**
* Creates a GraphProto message from a plain object. Also converts values to their respective internal types.
* @function fromObject
* @memberof onnx.GraphProto
* @static
* @param {Object.<string,*>} object Plain object
* @returns {onnx.GraphProto} GraphProto
*/
GraphProto.fromObject = function fromObject(object) {
if (object instanceof $root.onnx.GraphProto)
return object;
var message = new $root.onnx.GraphProto();
if (object.node) {
if (!Array.isArray(object.node))
throw TypeError(".onnx.GraphProto.node: array expected");
message.node = [];
for (var i = 0; i < object.node.length; ++i) {
if (typeof object.node[i] !== "object")
throw TypeError(".onnx.GraphProto.node: object expected");
message.node[i] = $root.onnx.NodeProto.fromObject(object.node[i]);
}
}
if (object.name != null)
message.name = String(object.name);
if (object.initializer) {
if (!Array.isArray(object.initializer))
throw TypeError(".onnx.GraphProto.initializer: array expected");
message.initializer = [];
for (var i = 0; i < object.initializer.length; ++i) {
if (typeof object.initializer[i] !== "object")
throw TypeError(".onnx.GraphProto.initializer: object expected");
message.initializer[i] = $root.onnx.TensorProto.fromObject(object.initializer[i]);
}
}
if (object.docString != null)
message.docString = String(object.docString);
if (object.input) {
if (!Array.isArray(object.input))
throw TypeError(".onnx.GraphProto.input: array expected");
message.input = [];
for (var i = 0; i < object.input.length; ++i) {
if (typeof object.input[i] !== "object")
throw TypeError(".onnx.GraphProto.input: object expected");
message.input[i] = $root.onnx.ValueInfoProto.fromObject(object.input[i]);
}
}
if (object.output) {
if (!Array.isArray(object.output))
throw TypeError(".onnx.GraphProto.output: array expected");
message.output = [];
for (var i = 0; i < object.output.length; ++i) {
if (typeof object.output[i] !== "object")
throw TypeError(".onnx.GraphProto.output: object expected");
message.output[i] = $root.onnx.ValueInfoProto.fromObject(object.output[i]);
}
}
if (object.valueInfo) {
if (!Array.isArray(object.valueInfo))
throw TypeError(".onnx.GraphProto.valueInfo: array expected");
message.valueInfo = [];
for (var i = 0; i < object.valueInfo.length; ++i) {
if (typeof object.valueInfo[i] !== "object")
throw TypeError(".onnx.GraphProto.valueInfo: object expected");
message.valueInfo[i] = $root.onnx.ValueInfoProto.fromObject(object.valueInfo[i]);
}
}
if (object.quantizationAnnotation) {
if (!Array.isArray(object.quantizationAnnotation))
throw TypeError(".onnx.GraphProto.quantizationAnnotation: array expected");
message.quantizationAnnotation = [];
for (var i = 0; i < object.quantizationAnnotation.length; ++i) {
if (typeof object.quantizationAnnotation[i] !== "object")
throw TypeError(".onnx.GraphProto.quantizationAnnotation: object expected");
message.quantizationAnnotation[i] = $root.onnx.TensorAnnotation.fromObject(object.quantizationAnnotation[i]);
}
}
return message;
};
/**
* Creates a plain object from a GraphProto message. Also converts values to other types if specified.
* @function toObject
* @memberof onnx.GraphProto
* @static
* @param {onnx.GraphProto} message GraphProto
* @param {$protobuf.IConversionOptions} [options] Conversion options
* @returns {Object.<string,*>} Plain object
*/
GraphProto.toObject = function toObject(message, options) {
if (!options)
options = {};
var object = {};
if (options.arrays || options.defaults) {
object.node = [];
object.initializer = [];
object.input = [];
object.output = [];
object.valueInfo = [];
object.quantizationAnnotation = [];
}
if (options.defaults) {
object.name = "";
object.docString = "";
}
if (message.node && message.node.length) {
object.node = [];
for (var j = 0; j < message.node.length; ++j)
object.node[j] = $root.onnx.NodeProto.toObject(message.node[j], options);
}
if (message.name != null && message.hasOwnProperty("name"))
object.name = message.name;
if (message.initializer && message.initializer.length) {
object.initializer = [];
for (var j = 0; j < message.initializer.length; ++j)
object.initializer[j] = $root.onnx.TensorProto.toObject(message.initializer[j], options);
}
if (message.docString != null && message.hasOwnProperty("docString"))
object.docString = message.docString;
if (message.input && message.input.length) {
object.input = [];
for (var j = 0; j < message.input.length; ++j)
object.input[j] = $root.onnx.ValueInfoProto.toObject(message.input[j], options);
}
if (message.output && message.output.length) {
object.output = [];
for (var j = 0; j < message.output.length; ++j)
object.output[j] = $root.onnx.ValueInfoProto.toObject(message.output[j], options);
}
if (message.valueInfo && message.valueInfo.length) {
object.valueInfo = [];
for (var j = 0; j < message.valueInfo.length; ++j)
object.valueInfo[j] = $root.onnx.ValueInfoProto.toObject(message.valueInfo[j], options);
}
if (message.quantizationAnnotation && message.quantizationAnnotation.length) {
object.quantizationAnnotation = [];
for (var j = 0; j < message.quantizationAnnotation.length; ++j)
object.quantizationAnnotation[j] = $root.onnx.TensorAnnotation.toObject(message.quantizationAnnotation[j], options);
}
return object;
};
/**
* Converts this GraphProto to JSON.
* @function toJSON
* @memberof onnx.GraphProto
* @instance
* @returns {Object.<string,*>} JSON object
*/
GraphProto.prototype.toJSON = function toJSON() {
return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
};
return GraphProto;
})();
onnx.TensorProto = (function() {
/**
* Properties of a TensorProto.
* @memberof onnx
* @interface ITensorProto
* @property {Array.<number|Long>|null} [dims] TensorProto dims
* @property {number|null} [dataType] TensorProto dataType
* @property {onnx.TensorProto.ISegment|null} [segment] TensorProto segment
* @property {Array.<number>|null} [floatData] TensorProto floatData
* @property {Array.<number>|null} [int32Data] TensorProto int32Data
* @property {Array.<Uint8Array>|null} [stringData] TensorProto stringData
* @property {Array.<number|Long>|null} [int64Data] TensorProto int64Data
* @property {string|null} [name] TensorProto name
* @property {string|null} [docString] TensorProto docString
* @property {Uint8Array|null} [rawData] TensorProto rawData
* @property {Array.<onnx.IStringStringEntryProto>|null} [externalData] TensorProto externalData
* @property {onnx.TensorProto.DataLocation|null} [dataLocation] TensorProto dataLocation
* @property {Array.<number>|null} [doubleData] TensorProto doubleData
* @property {Array.<number|Long>|null} [uint64Data] TensorProto uint64Data
*/
/**
* Constructs a new TensorProto.
* @memberof onnx
* @classdesc Represents a TensorProto.
* @implements ITensorProto
* @constructor
* @param {onnx.ITensorProto=} [properties] Properties to set
*/
function TensorProto(properties) {
this.dims = [];
this.floatData = [];
this.int32Data = [];
this.stringData = [];
this.int64Data = [];
this.externalData = [];
this.doubleData = [];
this.uint64Data = [];
if (properties)
for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
if (properties[keys[i]] != null)
this[keys[i]] = properties[keys[i]];
}
/**
* TensorProto dims.
* @member {Array.<number|Long>} dims
* @memberof onnx.TensorProto
* @instance
*/
TensorProto.prototype.dims = $util.emptyArray;
/**
* TensorProto dataType.
* @member {number} dataType
* @memberof onnx.TensorProto
* @instance
*/
TensorProto.prototype.dataType = 0;
/**
* TensorProto segment.
* @member {onnx.TensorProto.ISegment|null|undefined} segment
* @memberof onnx.TensorProto
* @instance
*/
TensorProto.prototype.segment = null;
/**
* TensorProto floatData.
* @member {Array.<number>} floatData
* @memberof onnx.TensorProto
* @instance
*/
TensorProto.prototype.floatData = $util.emptyArray;
/**
* TensorProto int32Data.
* @member {Array.<number>} int32Data
* @memberof onnx.TensorProto
* @instance
*/
TensorProto.prototype.int32Data = $util.emptyArray;
/**
* TensorProto stringData.
* @member {Array.<Uint8Array>} stringData
* @memberof onnx.TensorProto
* @instance
*/
TensorProto.prototype.stringData = $util.emptyArray;
/**
* TensorProto int64Data.
* @member {Array.<number|Long>} int64Data
* @memberof onnx.TensorProto
* @instance
*/
TensorProto.prototype.int64Data = $util.emptyArray;
/**
* TensorProto name.
* @member {string} name
* @memberof onnx.TensorProto
* @instance
*/
TensorProto.prototype.name = "";
/**
* TensorProto docString.
* @member {string} docString
* @memberof onnx.TensorProto
* @instance
*/
TensorProto.prototype.docString = "";
/**
* TensorProto rawData.
* @member {Uint8Array} rawData
* @memberof onnx.TensorProto
* @instance
*/
TensorProto.prototype.rawData = $util.newBuffer([]);
/**
* TensorProto externalData.
* @member {Array.<onnx.IStringStringEntryProto>} externalData
* @memberof onnx.TensorProto
* @instance
*/
TensorProto.prototype.externalData = $util.emptyArray;
/**
* TensorProto dataLocation.
* @member {onnx.TensorProto.DataLocation} dataLocation
* @memberof onnx.TensorProto
* @instance
*/
TensorProto.prototype.dataLocation = 0;
/**
* TensorProto doubleData.
* @member {Array.<number>} doubleData
* @memberof onnx.TensorProto
* @instance
*/
TensorProto.prototype.doubleData = $util.emptyArray;
/**
* TensorProto uint64Data.
* @member {Array.<number|Long>} uint64Data
* @memberof onnx.TensorProto
* @instance
*/
TensorProto.prototype.uint64Data = $util.emptyArray;
/**
* Creates a new TensorProto instance using the specified properties.
* @function create
* @memberof onnx.TensorProto
* @static
* @param {onnx.ITensorProto=} [properties] Properties to set
* @returns {onnx.TensorProto} TensorProto instance
*/
TensorProto.create = function create(properties) {
return new TensorProto(properties);
};
/**
* Encodes the specified TensorProto message. Does not implicitly {@link onnx.TensorProto.verify|verify} messages.
* @function encode
* @memberof onnx.TensorProto
* @static
* @param {onnx.ITensorProto} message TensorProto message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
TensorProto.encode = function encode(message, writer) {
if (!writer)
writer = $Writer.create();
if (message.dims != null && message.dims.length) {
writer.uint32(/* id 1, wireType 2 =*/10).fork();
for (var i = 0; i < message.dims.length; ++i)
writer.int64(message.dims[i]);
writer.ldelim();
}
if (message.dataType != null && message.hasOwnProperty("dataType"))
writer.uint32(/* id 2, wireType 0 =*/16).int32(message.dataType);
if (message.segment != null && message.hasOwnProperty("segment"))
$root.onnx.TensorProto.Segment.encode(message.segment, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
if (message.floatData != null && message.floatData.length) {
writer.uint32(/* id 4, wireType 2 =*/34).fork();
for (var i = 0; i < message.floatData.length; ++i)
writer.float(message.floatData[i]);
writer.ldelim();
}
if (message.int32Data != null && message.int32Data.length) {
writer.uint32(/* id 5, wireType 2 =*/42).fork();
for (var i = 0; i < message.int32Data.length; ++i)
writer.int32(message.int32Data[i]);
writer.ldelim();
}
if (message.stringData != null && message.stringData.length)
for (var i = 0; i < message.stringData.length; ++i)
writer.uint32(/* id 6, wireType 2 =*/50).bytes(message.stringData[i]);
if (message.int64Data != null && message.int64Data.length) {
writer.uint32(/* id 7, wireType 2 =*/58).fork();
for (var i = 0; i < message.int64Data.length; ++i)
writer.int64(message.int64Data[i]);
writer.ldelim();
}
if (message.name != null && message.hasOwnProperty("name"))
writer.uint32(/* id 8, wireType 2 =*/66).string(message.name);
if (message.rawData != null && message.hasOwnProperty("rawData"))
writer.uint32(/* id 9, wireType 2 =*/74).bytes(message.rawData);
if (message.doubleData != null && message.doubleData.length) {
writer.uint32(/* id 10, wireType 2 =*/82).fork();
for (var i = 0; i < message.doubleData.length; ++i)
writer.double(message.doubleData[i]);
writer.ldelim();
}
if (message.uint64Data != null && message.uint64Data.length) {
writer.uint32(/* id 11, wireType 2 =*/90).fork();
for (var i = 0; i < message.uint64Data.length; ++i)
writer.uint64(message.uint64Data[i]);
writer.ldelim();
}
if (message.docString != null && message.hasOwnProperty("docString"))
writer.uint32(/* id 12, wireType 2 =*/98).string(message.docString);
if (message.externalData != null && message.externalData.length)
for (var i = 0; i < message.externalData.length; ++i)
$root.onnx.StringStringEntryProto.encode(message.externalData[i], writer.uint32(/* id 13, wireType 2 =*/106).fork()).ldelim();
if (message.dataLocation != null && message.hasOwnProperty("dataLocation"))
writer.uint32(/* id 14, wireType 0 =*/112).int32(message.dataLocation);
return writer;
};
/**
* Encodes the specified TensorProto message, length delimited. Does not implicitly {@link onnx.TensorProto.verify|verify} messages.
* @function encodeDelimited
* @memberof onnx.TensorProto
* @static
* @param {onnx.ITensorProto} message TensorProto message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
TensorProto.encodeDelimited = function encodeDelimited(message, writer) {
return this.encode(message, writer).ldelim();
};
/**
* Decodes a TensorProto message from the specified reader or buffer.
* @function decode
* @memberof onnx.TensorProto
* @static
* @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
* @param {number} [length] Message length if known beforehand
* @returns {onnx.TensorProto} TensorProto
* @throws {Error} If the payload is not a reader or valid buffer
* @throws {$protobuf.util.ProtocolError} If required fields are missing
*/
TensorProto.decode = function decode(reader, length) {
if (!(reader instanceof $Reader))
reader = $Reader.create(reader);
var end = length === undefined ? reader.len : reader.pos + length, message = new $root.onnx.TensorProto();
while (reader.pos < end) {
var tag = reader.uint32();
switch (tag >>> 3) {
case 1:
if (!(message.dims && message.dims.length))
message.dims = [];
if ((tag & 7) === 2) {
var end2 = reader.uint32() + reader.pos;
while (reader.pos < end2)
message.dims.push(reader.int64());
} else
message.dims.push(reader.int64());
break;
case 2:
message.dataType = reader.int32();
break;
case 3:
message.segment = $root.onnx.TensorProto.Segment.decode(reader, reader.uint32());
break;
case 4:
if (!(message.floatData && message.floatData.length))
message.floatData = [];
if ((tag & 7) === 2) {
var end2 = reader.uint32() + reader.pos;
while (reader.pos < end2)
message.floatData.push(reader.float());
} else
message.floatData.push(reader.float());
break;
case 5:
if (!(message.int32Data && message.int32Data.length))
message.int32Data = [];
if ((tag & 7) === 2) {
var end2 = reader.uint32() + reader.pos;
while (reader.pos < end2)
message.int32Data.push(reader.int32());
} else
message.int32Data.push(reader.int32());
break;
case 6:
if (!(message.stringData && message.stringData.length))
message.stringData = [];
message.stringData.push(reader.bytes());
break;
case 7:
if (!(message.int64Data && message.int64Data.length))
message.int64Data = [];
if ((tag & 7) === 2) {
var end2 = reader.uint32() + reader.pos;
while (reader.pos < end2)
message.int64Data.push(reader.int64());
} else
message.int64Data.push(reader.int64());
break;
case 8:
message.name = reader.string();
break;
case 12:
message.docString = reader.string();
break;
case 9:
message.rawData = reader.bytes();
break;
case 13:
if (!(message.externalData && message.externalData.length))
message.externalData = [];
message.externalData.push($root.onnx.StringStringEntryProto.decode(reader, reader.uint32()));
break;
case 14:
message.dataLocation = reader.int32();
break;
case 10:
if (!(message.doubleData && message.doubleData.length))
message.doubleData = [];
if ((tag & 7) === 2) {
var end2 = reader.uint32() + reader.pos;
while (reader.pos < end2)
message.doubleData.push(reader.double());
} else
message.doubleData.push(reader.double());
break;
case 11:
if (!(message.uint64Data && message.uint64Data.length))
message.uint64Data = [];
if ((tag & 7) === 2) {
var end2 = reader.uint32() + reader.pos;
while (reader.pos < end2)
message.uint64Data.push(reader.uint64());
} else
message.uint64Data.push(reader.uint64());
break;
default:
reader.skipType(tag & 7);
break;
}
}
return message;
};
/**
* Decodes a TensorProto message from the specified reader or buffer, length delimited.
* @function decodeDelimited
* @memberof onnx.TensorProto
* @static
* @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
* @returns {onnx.TensorProto} TensorProto
* @throws {Error} If the payload is not a reader or valid buffer
* @throws {$protobuf.util.ProtocolError} If required fields are missing
*/
TensorProto.decodeDelimited = function decodeDelimited(reader) {
if (!(reader instanceof $Reader))
reader = new $Reader(reader);
return this.decode(reader, reader.uint32());
};
/**
* Verifies a TensorProto message.
* @function verify
* @memberof onnx.TensorProto
* @static
* @param {Object.<string,*>} message Plain object to verify
* @returns {string|null} `null` if valid, otherwise the reason why it is not
*/
TensorProto.verify = function verify(message) {
if (typeof message !== "object" || message === null)
return "object expected";
if (message.dims != null && message.hasOwnProperty("dims")) {
if (!Array.isArray(message.dims))
return "dims: array expected";
for (var i = 0; i < message.dims.length; ++i)
if (!$util.isInteger(message.dims[i]) && !(message.dims[i] && $util.isInteger(message.dims[i].low) && $util.isInteger(message.dims[i].high)))
return "dims: integer|Long[] expected";
}
if (message.dataType != null && message.hasOwnProperty("dataType"))
if (!$util.isInteger(message.dataType))
return "dataType: integer expected";
if (message.segment != null && message.hasOwnProperty("segment")) {
var error = $root.onnx.TensorProto.Segment.verify(message.segment);
if (error)
return "segment." + error;
}
if (message.floatData != null && message.hasOwnProperty("floatData")) {
if (!Array.isArray(message.floatData))
return "floatData: array expected";
for (var i = 0; i < message.floatData.length; ++i)
if (typeof message.floatData[i] !== "number")
return "floatData: number[] expected";
}
if (message.int32Data != null && message.hasOwnProperty("int32Data")) {
if (!Array.isArray(message.int32Data))
return "int32Data: array expected";
for (var i = 0; i < message.int32Data.length; ++i)
if (!$util.isInteger(message.int32Data[i]))
return "int32Data: integer[] expected";
}
if (message.stringData != null && message.hasOwnProperty("stringData")) {
if (!Array.isArray(message.stringData))
return "stringData: array expected";
for (var i = 0; i < message.stringData.length; ++i)
if (!(message.stringData[i] && typeof message.stringData[i].length === "number" || $util.isString(message.stringData[i])))
return "stringData: buffer[] expected";
}
if (message.int64Data != null && message.hasOwnProperty("int64Data")) {
if (!Array.isArray(message.int64Data))
return "int64Data: array expected";
for (var i = 0; i < message.int64Data.length; ++i)
if (!$util.isInteger(message.int64Data[i]) && !(message.int64Data[i] && $util.isInteger(message.int64Data[i].low) && $util.isInteger(message.int64Data[i].high)))
return "int64Data: integer|Long[] expected";
}
if (message.name != null && message.hasOwnProperty("name"))
if (!$util.isString(message.name))
return "name: string expected";
if (message.docString != null && message.hasOwnProperty("docString"))
if (!$util.isString(message.docString))
return "docString: string expected";
if (message.rawData != null && message.hasOwnProperty("rawData"))
if (!(message.rawData && typeof message.rawData.length === "number" || $util.isString(message.rawData)))
return "rawData: buffer expected";
if (message.externalData != null && message.hasOwnProperty("externalData")) {
if (!Array.isArray(message.externalData))
return "externalData: array expected";
for (var i = 0; i < message.externalData.length; ++i) {
var error = $root.onnx.StringStringEntryProto.verify(message.externalData[i]);
if (error)
return "externalData." + error;
}
}
if (message.dataLocation != null && message.hasOwnProperty("dataLocation"))
switch (message.dataLocation) {
default:
return "dataLocation: enum value expected";
case 0:
case 1:
break;
}
if (message.doubleData != null && message.hasOwnProperty("doubleData")) {
if (!Array.isArray(message.doubleData))
return "doubleData: array expected";
for (var i = 0; i < message.doubleData.length; ++i)
if (typeof message.doubleData[i] !== "number")
return "doubleData: number[] expected";
}
if (message.uint64Data != null && message.hasOwnProperty("uint64Data")) {
if (!Array.isArray(message.uint64Data))
return "uint64Data: array expected";
for (var i = 0; i < message.uint64Data.length; ++i)
if (!$util.isInteger(message.uint64Data[i]) && !(message.uint64Data[i] && $util.isInteger(message.uint64Data[i].low) && $util.isInteger(message.uint64Data[i].high)))
return "uint64Data: integer|Long[] expected";
}
return null;
};
/**
* Creates a TensorProto message from a plain object. Also converts values to their respective internal types.
* @function fromObject
* @memberof onnx.TensorProto
* @static
* @param {Object.<string,*>} object Plain object
* @returns {onnx.TensorProto} TensorProto
*/
TensorProto.fromObject = function fromObject(object) {
if (object instanceof $root.onnx.TensorProto)
return object;
var message = new $root.onnx.TensorProto();
if (object.dims) {
if (!Array.isArray(object.dims))
throw TypeError(".onnx.TensorProto.dims: array expected");
message.dims = [];
for (var i = 0; i < object.dims.length; ++i)
if ($util.Long)
(message.dims[i] = $util.Long.fromValue(object.dims[i])).unsigned = false;
else if (typeof object.dims[i] === "string")
message.dims[i] = parseInt(object.dims[i], 10);
else if (typeof object.dims[i] === "number")
message.dims[i] = object.dims[i];
else if (typeof object.dims[i] === "object")
message.dims[i] = new $util.LongBits(object.dims[i].low >>> 0, object.dims[i].high >>> 0).toNumber();
}
if (object.dataType != null)
message.dataType = object.dataType | 0;
if (object.segment != null) {
if (typeof object.segment !== "object")
throw TypeError(".onnx.TensorProto.segment: object expected");
message.segment = $root.onnx.TensorProto.Segment.fromObject(object.segment);
}
if (object.floatData) {
if (!Array.isArray(object.floatData))
throw TypeError(".onnx.TensorProto.floatData: array expected");
message.floatData = [];
for (var i = 0; i < object.floatData.length; ++i)
message.floatData[i] = Number(object.floatData[i]);
}
if (object.int32Data) {
if (!Array.isArray(object.int32Data))
throw TypeError(".onnx.TensorProto.int32Data: array expected");
message.int32Data = [];
for (var i = 0; i < object.int32Data.length; ++i)
message.int32Data[i] = object.int32Data[i] | 0;
}
if (object.stringData) {
if (!Array.isArray(object.stringData))
throw TypeError(".onnx.TensorProto.stringData: array expected");
message.stringData = [];
for (var i = 0; i < object.stringData.length; ++i)
if (typeof object.stringData[i] === "string")
$util.base64.decode(object.stringData[i], message.stringData[i] = $util.newBuffer($util.base64.length(object.stringData[i])), 0);
else if (object.stringData[i].length)
message.stringData[i] = object.stringData[i];
}
if (object.int64Data) {
if (!Array.isArray(object.int64Data))
throw TypeError(".onnx.TensorProto.int64Data: array expected");
message.int64Data = [];
for (var i = 0; i < object.int64Data.length; ++i)
if ($util.Long)
(message.int64Data[i] = $util.Long.fromValue(object.int64Data[i])).unsigned = false;
else if (typeof object.int64Data[i] === "string")
message.int64Data[i] = parseInt(object.int64Data[i], 10);
else if (typeof object.int64Data[i] === "number")
message.int64Data[i] = object.int64Data[i];
else if (typeof object.int64Data[i] === "object")
message.int64Data[i] = new $util.LongBits(object.int64Data[i].low >>> 0, object.int64Data[i].high >>> 0).toNumber();
}
if (object.name != null)
message.name = String(object.name);
if (object.docString != null)
message.docString = String(object.docString);
if (object.rawData != null)
if (typeof object.rawData === "string")
$util.base64.decode(object.rawData, message.rawData = $util.newBuffer($util.base64.length(object.rawData)), 0);
else if (object.rawData.length)
message.rawData = object.rawData;
if (object.externalData) {
if (!Array.isArray(object.externalData))
throw TypeError(".onnx.TensorProto.externalData: array expected");
message.externalData = [];
for (var i = 0; i < object.externalData.length; ++i) {
if (typeof object.externalData[i] !== "object")
throw TypeError(".onnx.TensorProto.externalData: object expected");
message.externalData[i] = $root.onnx.StringStringEntryProto.fromObject(object.externalData[i]);
}
}
switch (object.dataLocation) {
case "DEFAULT":
case 0:
message.dataLocation = 0;
break;
case "EXTERNAL":
case 1:
message.dataLocation = 1;
break;
}
if (object.doubleData) {
if (!Array.isArray(object.doubleData))
throw TypeError(".onnx.TensorProto.doubleData: array expected");
message.doubleData = [];
for (var i = 0; i < object.doubleData.length; ++i)
message.doubleData[i] = Number(object.doubleData[i]);
}
if (object.uint64Data) {
if (!Array.isArray(object.uint64Data))
throw TypeError(".onnx.TensorProto.uint64Data: array expected");
message.uint64Data = [];
for (var i = 0; i < object.uint64Data.length; ++i)
if ($util.Long)
(message.uint64Data[i] = $util.Long.fromValue(object.uint64Data[i])).unsigned = true;
else if (typeof object.uint64Data[i] === "string")
message.uint64Data[i] = parseInt(object.uint64Data[i], 10);
else if (typeof object.uint64Data[i] === "number")
message.uint64Data[i] = object.uint64Data[i];
else if (typeof object.uint64Data[i] === "object")
message.uint64Data[i] = new $util.LongBits(object.uint64Data[i].low >>> 0, object.uint64Data[i].high >>> 0).toNumber(true);
}
return message;
};
/**
* Creates a plain object from a TensorProto message. Also converts values to other types if specified.
* @function toObject
* @memberof onnx.TensorProto
* @static
* @param {onnx.TensorProto} message TensorProto
* @param {$protobuf.IConversionOptions} [options] Conversion options
* @returns {Object.<string,*>} Plain object
*/
TensorProto.toObject = function toObject(message, options) {
if (!options)
options = {};
var object = {};
if (options.arrays || options.defaults) {
object.dims = [];
object.floatData = [];
object.int32Data = [];
object.stringData = [];
object.int64Data = [];
object.doubleData = [];
object.uint64Data = [];
object.externalData = [];
}
if (options.defaults) {
object.dataType = 0;
object.segment = null;
object.name = "";
if (options.bytes === String)
object.rawData = "";
else {
object.rawData = [];
if (options.bytes !== Array)
object.rawData = $util.newBuffer(object.rawData);
}
object.docString = "";
object.dataLocation = options.enums === String ? "DEFAULT" : 0;
}
if (message.dims && message.dims.length) {
object.dims = [];
for (var j = 0; j < message.dims.length; ++j)
if (typeof message.dims[j] === "number")
object.dims[j] = options.longs === String ? String(message.dims[j]) : message.dims[j];
else
object.dims[j] = options.longs === String ? $util.Long.prototype.toString.call(message.dims[j]) : options.longs === Number ? new $util.LongBits(message.dims[j].low >>> 0, message.dims[j].high >>> 0).toNumber() : message.dims[j];
}
if (message.dataType != null && message.hasOwnProperty("dataType"))
object.dataType = message.dataType;
if (message.segment != null && message.hasOwnProperty("segment"))
object.segment = $root.onnx.TensorProto.Segment.toObject(message.segment, options);
if (message.floatData && message.floatData.length) {
object.floatData = [];
for (var j = 0; j < message.floatData.length; ++j)
object.floatData[j] = options.json && !isFinite(message.floatData[j]) ? String(message.floatData[j]) : message.floatData[j];
}
if (message.int32Data && message.int32Data.length) {
object.int32Data = [];
for (var j = 0; j < message.int32Data.length; ++j)
object.int32Data[j] = message.int32Data[j];
}
if (message.stringData && message.stringData.length) {
object.stringData = [];
for (var j = 0; j < message.stringData.length; ++j)
object.stringData[j] = options.bytes === String ? $util.base64.encode(message.stringData[j], 0, message.stringData[j].length) : options.bytes === Array ? Array.prototype.slice.call(message.stringData[j]) : message.stringData[j];
}
if (message.int64Data && message.int64Data.length) {
object.int64Data = [];
for (var j = 0; j < message.int64Data.length; ++j)
if (typeof message.int64Data[j] === "number")
object.int64Data[j] = options.longs === String ? String(message.int64Data[j]) : message.int64Data[j];
else
object.int64Data[j] = options.longs === String ? $util.Long.prototype.toString.call(message.int64Data[j]) : options.longs === Number ? new $util.LongBits(message.int64Data[j].low >>> 0, message.int64Data[j].high >>> 0).toNumber() : message.int64Data[j];
}
if (message.name != null && message.hasOwnProperty("name"))
object.name = message.name;
if (message.rawData != null && message.hasOwnProperty("rawData"))
object.rawData = options.bytes === String ? $util.base64.encode(message.rawData, 0, message.rawData.length) : options.bytes === Array ? Array.prototype.slice.call(message.rawData) : message.rawData;
if (message.doubleData && message.doubleData.length) {
object.doubleData = [];
for (var j = 0; j < message.doubleData.length; ++j)
object.doubleData[j] = options.json && !isFinite(message.doubleData[j]) ? String(message.doubleData[j]) : message.doubleData[j];
}
if (message.uint64Data && message.uint64Data.length) {
object.uint64Data = [];
for (var j = 0; j < message.uint64Data.length; ++j)
if (typeof message.uint64Data[j] === "number")
object.uint64Data[j] = options.longs === String ? String(message.uint64Data[j]) : message.uint64Data[j];
else
object.uint64Data[j] = options.longs === String ? $util.Long.prototype.toString.call(message.uint64Data[j]) : options.longs === Number ? new $util.LongBits(message.uint64Data[j].low >>> 0, message.uint64Data[j].high >>> 0).toNumber(true) : message.uint64Data[j];
}
if (message.docString != null && message.hasOwnProperty("docString"))
object.docString = message.docString;
if (message.externalData && message.externalData.length) {
object.externalData = [];
for (var j = 0; j < message.externalData.length; ++j)
object.externalData[j] = $root.onnx.StringStringEntryProto.toObject(message.externalData[j], options);
}
if (message.dataLocation != null && message.hasOwnProperty("dataLocation"))
object.dataLocation = options.enums === String ? $root.onnx.TensorProto.DataLocation[message.dataLocation] : message.dataLocation;
return object;
};
/**
* Converts this TensorProto to JSON.
* @function toJSON
* @memberof onnx.TensorProto
* @instance
* @returns {Object.<string,*>} JSON object
*/
TensorProto.prototype.toJSON = function toJSON() {
return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
};
/**
* DataType enum.
* @name onnx.TensorProto.DataType
* @enum {string}
* @property {number} UNDEFINED=0 UNDEFINED value
* @property {number} FLOAT=1 FLOAT value
* @property {number} UINT8=2 UINT8 value
* @property {number} INT8=3 INT8 value
* @property {number} UINT16=4 UINT16 value
* @property {number} INT16=5 INT16 value
* @property {number} INT32=6 INT32 value
* @property {number} INT64=7 INT64 value
* @property {number} STRING=8 STRING value
* @property {number} BOOL=9 BOOL value
* @property {number} FLOAT16=10 FLOAT16 value
* @property {number} DOUBLE=11 DOUBLE value
* @property {number} UINT32=12 UINT32 value
* @property {number} UINT64=13 UINT64 value
* @property {number} COMPLEX64=14 COMPLEX64 value
* @property {number} COMPLEX128=15 COMPLEX128 value
* @property {number} BFLOAT16=16 BFLOAT16 value
*/
TensorProto.DataType = (function() {
var valuesById = {}, values = Object.create(valuesById);
values[valuesById[0] = "UNDEFINED"] = 0;
values[valuesById[1] = "FLOAT"] = 1;
values[valuesById[2] = "UINT8"] = 2;
values[valuesById[3] = "INT8"] = 3;
values[valuesById[4] = "UINT16"] = 4;
values[valuesById[5] = "INT16"] = 5;
values[valuesById[6] = "INT32"] = 6;
values[valuesById[7] = "INT64"] = 7;
values[valuesById[8] = "STRING"] = 8;
values[valuesById[9] = "BOOL"] = 9;
values[valuesById[10] = "FLOAT16"] = 10;
values[valuesById[11] = "DOUBLE"] = 11;
values[valuesById[12] = "UINT32"] = 12;
values[valuesById[13] = "UINT64"] = 13;
values[valuesById[14] = "COMPLEX64"] = 14;
values[valuesById[15] = "COMPLEX128"] = 15;
values[valuesById[16] = "BFLOAT16"] = 16;
return values;
})();
TensorProto.Segment = (function() {
/**
* Properties of a Segment.
* @memberof onnx.TensorProto
* @interface ISegment
* @property {number|Long|null} [begin] Segment begin
* @property {number|Long|null} [end] Segment end
*/
/**
* Constructs a new Segment.
* @memberof onnx.TensorProto
* @classdesc Represents a Segment.
* @implements ISegment
* @constructor
* @param {onnx.TensorProto.ISegment=} [properties] Properties to set
*/
function Segment(properties) {
if (properties)
for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
if (properties[keys[i]] != null)
this[keys[i]] = properties[keys[i]];
}
/**
* Segment begin.
* @member {number|Long} begin
* @memberof onnx.TensorProto.Segment
* @instance
*/
Segment.prototype.begin = $util.Long ? $util.Long.fromBits(0,0,false) : 0;
/**
* Segment end.
* @member {number|Long} end
* @memberof onnx.TensorProto.Segment
* @instance
*/
Segment.prototype.end = $util.Long ? $util.Long.fromBits(0,0,false) : 0;
/**
* Creates a new Segment instance using the specified properties.
* @function create
* @memberof onnx.TensorProto.Segment
* @static
* @param {onnx.TensorProto.ISegment=} [properties] Properties to set
* @returns {onnx.TensorProto.Segment} Segment instance
*/
Segment.create = function create(properties) {
return new Segment(properties);
};
/**
* Encodes the specified Segment message. Does not implicitly {@link onnx.TensorProto.Segment.verify|verify} messages.
* @function encode
* @memberof onnx.TensorProto.Segment
* @static
* @param {onnx.TensorProto.ISegment} message Segment message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
Segment.encode = function encode(message, writer) {
if (!writer)
writer = $Writer.create();
if (message.begin != null && message.hasOwnProperty("begin"))
writer.uint32(/* id 1, wireType 0 =*/8).int64(message.begin);
if (message.end != null && message.hasOwnProperty("end"))
writer.uint32(/* id 2, wireType 0 =*/16).int64(message.end);
return writer;
};
/**
* Encodes the specified Segment message, length delimited. Does not implicitly {@link onnx.TensorProto.Segment.verify|verify} messages.
* @function encodeDelimited
* @memberof onnx.TensorProto.Segment
* @static
* @param {onnx.TensorProto.ISegment} message Segment message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
Segment.encodeDelimited = function encodeDelimited(message, writer) {
return this.encode(message, writer).ldelim();
};
/**
* Decodes a Segment message from the specified reader or buffer.
* @function decode
* @memberof onnx.TensorProto.Segment
* @static
* @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
* @param {number} [length] Message length if known beforehand
* @returns {onnx.TensorProto.Segment} Segment
* @throws {Error} If the payload is not a reader or valid buffer
* @throws {$protobuf.util.ProtocolError} If required fields are missing
*/
Segment.decode = function decode(reader, length) {
if (!(reader instanceof $Reader))
reader = $Reader.create(reader);
var end = length === undefined ? reader.len : reader.pos + length, message = new $root.onnx.TensorProto.Segment();
while (reader.pos < end) {
var tag = reader.uint32();
switch (tag >>> 3) {
case 1:
message.begin = reader.int64();
break;
case 2:
message.end = reader.int64();
break;
default:
reader.skipType(tag & 7);
break;
}
}
return message;
};
/**
* Decodes a Segment message from the specified reader or buffer, length delimited.
* @function decodeDelimited
* @memberof onnx.TensorProto.Segment
* @static
* @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
* @returns {onnx.TensorProto.Segment} Segment
* @throws {Error} If the payload is not a reader or valid buffer
* @throws {$protobuf.util.ProtocolError} If required fields are missing
*/
Segment.decodeDelimited = function decodeDelimited(reader) {
if (!(reader instanceof $Reader))
reader = new $Reader(reader);
return this.decode(reader, reader.uint32());
};
/**
* Verifies a Segment message.
* @function verify
* @memberof onnx.TensorProto.Segment
* @static
* @param {Object.<string,*>} message Plain object to verify
* @returns {string|null} `null` if valid, otherwise the reason why it is not
*/
Segment.verify = function verify(message) {
if (typeof message !== "object" || message === null)
return "object expected";
if (message.begin != null && message.hasOwnProperty("begin"))
if (!$util.isInteger(message.begin) && !(message.begin && $util.isInteger(message.begin.low) && $util.isInteger(message.begin.high)))
return "begin: integer|Long expected";
if (message.end != null && message.hasOwnProperty("end"))
if (!$util.isInteger(message.end) && !(message.end && $util.isInteger(message.end.low) && $util.isInteger(message.end.high)))
return "end: integer|Long expected";
return null;
};
/**
* Creates a Segment message from a plain object. Also converts values to their respective internal types.
* @function fromObject
* @memberof onnx.TensorProto.Segment
* @static
* @param {Object.<string,*>} object Plain object
* @returns {onnx.TensorProto.Segment} Segment
*/
Segment.fromObject = function fromObject(object) {
if (object instanceof $root.onnx.TensorProto.Segment)
return object;
var message = new $root.onnx.TensorProto.Segment();
if (object.begin != null)
if ($util.Long)
(message.begin = $util.Long.fromValue(object.begin)).unsigned = false;
else if (typeof object.begin === "string")
message.begin = parseInt(object.begin, 10);
else if (typeof object.begin === "number")
message.begin = object.begin;
else if (typeof object.begin === "object")
message.begin = new $util.LongBits(object.begin.low >>> 0, object.begin.high >>> 0).toNumber();
if (object.end != null)
if ($util.Long)
(message.end = $util.Long.fromValue(object.end)).unsigned = false;
else if (typeof object.end === "string")
message.end = parseInt(object.end, 10);
else if (typeof object.end === "number")
message.end = object.end;
else if (typeof object.end === "object")
message.end = new $util.LongBits(object.end.low >>> 0, object.end.high >>> 0).toNumber();
return message;
};
/**
* Creates a plain object from a Segment message. Also converts values to other types if specified.
* @function toObject
* @memberof onnx.TensorProto.Segment
* @static
* @param {onnx.TensorProto.Segment} message Segment
* @param {$protobuf.IConversionOptions} [options] Conversion options
* @returns {Object.<string,*>} Plain object
*/
Segment.toObject = function toObject(message, options) {
if (!options)
options = {};
var object = {};
if (options.defaults) {
if ($util.Long) {
var long = new $util.Long(0, 0, false);
object.begin = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
} else
object.begin = options.longs === String ? "0" : 0;
if ($util.Long) {
var long = new $util.Long(0, 0, false);
object.end = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
} else
object.end = options.longs === String ? "0" : 0;
}
if (message.begin != null && message.hasOwnProperty("begin"))
if (typeof message.begin === "number")
object.begin = options.longs === String ? String(message.begin) : message.begin;
else
object.begin = options.longs === String ? $util.Long.prototype.toString.call(message.begin) : options.longs === Number ? new $util.LongBits(message.begin.low >>> 0, message.begin.high >>> 0).toNumber() : message.begin;
if (message.end != null && message.hasOwnProperty("end"))
if (typeof message.end === "number")
object.end = options.longs === String ? String(message.end) : message.end;
else
object.end = options.longs === String ? $util.Long.prototype.toString.call(message.end) : options.longs === Number ? new $util.LongBits(message.end.low >>> 0, message.end.high >>> 0).toNumber() : message.end;
return object;
};
/**
* Converts this Segment to JSON.
* @function toJSON
* @memberof onnx.TensorProto.Segment
* @instance
* @returns {Object.<string,*>} JSON object
*/
Segment.prototype.toJSON = function toJSON() {
return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
};
return Segment;
})();
/**
* DataLocation enum.
* @name onnx.TensorProto.DataLocation
* @enum {string}
* @property {number} DEFAULT=0 DEFAULT value
* @property {number} EXTERNAL=1 EXTERNAL value
*/
TensorProto.DataLocation = (function() {
var valuesById = {}, values = Object.create(valuesById);
values[valuesById[0] = "DEFAULT"] = 0;
values[valuesById[1] = "EXTERNAL"] = 1;
return values;
})();
return TensorProto;
})();
onnx.TensorShapeProto = (function() {
/**
* Properties of a TensorShapeProto.
* @memberof onnx
* @interface ITensorShapeProto
* @property {Array.<onnx.TensorShapeProto.IDimension>|null} [dim] TensorShapeProto dim
*/
/**
* Constructs a new TensorShapeProto.
* @memberof onnx
* @classdesc Represents a TensorShapeProto.
* @implements ITensorShapeProto
* @constructor
* @param {onnx.ITensorShapeProto=} [properties] Properties to set
*/
function TensorShapeProto(properties) {
this.dim = [];
if (properties)
for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
if (properties[keys[i]] != null)
this[keys[i]] = properties[keys[i]];
}
/**
* TensorShapeProto dim.
* @member {Array.<onnx.TensorShapeProto.IDimension>} dim
* @memberof onnx.TensorShapeProto
* @instance
*/
TensorShapeProto.prototype.dim = $util.emptyArray;
/**
* Creates a new TensorShapeProto instance using the specified properties.
* @function create
* @memberof onnx.TensorShapeProto
* @static
* @param {onnx.ITensorShapeProto=} [properties] Properties to set
* @returns {onnx.TensorShapeProto} TensorShapeProto instance
*/
TensorShapeProto.create = function create(properties) {
return new TensorShapeProto(properties);
};
/**
* Encodes the specified TensorShapeProto message. Does not implicitly {@link onnx.TensorShapeProto.verify|verify} messages.
* @function encode
* @memberof onnx.TensorShapeProto
* @static
* @param {onnx.ITensorShapeProto} message TensorShapeProto message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
TensorShapeProto.encode = function encode(message, writer) {
if (!writer)
writer = $Writer.create();
if (message.dim != null && message.dim.length)
for (var i = 0; i < message.dim.length; ++i)
$root.onnx.TensorShapeProto.Dimension.encode(message.dim[i], writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
return writer;
};
/**
* Encodes the specified TensorShapeProto message, length delimited. Does not implicitly {@link onnx.TensorShapeProto.verify|verify} messages.
* @function encodeDelimited
* @memberof onnx.TensorShapeProto
* @static
* @param {onnx.ITensorShapeProto} message TensorShapeProto message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
TensorShapeProto.encodeDelimited = function encodeDelimited(message, writer) {
return this.encode(message, writer).ldelim();
};
/**
* Decodes a TensorShapeProto message from the specified reader or buffer.
* @function decode
* @memberof onnx.TensorShapeProto
* @static
* @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
* @param {number} [length] Message length if known beforehand
* @returns {onnx.TensorShapeProto} TensorShapeProto
* @throws {Error} If the payload is not a reader or valid buffer
* @throws {$protobuf.util.ProtocolError} If required fields are missing
*/
TensorShapeProto.decode = function decode(reader, length) {
if (!(reader instanceof $Reader))
reader = $Reader.create(reader);
var end = length === undefined ? reader.len : reader.pos + length, message = new $root.onnx.TensorShapeProto();
while (reader.pos < end) {
var tag = reader.uint32();
switch (tag >>> 3) {
case 1:
if (!(message.dim && message.dim.length))
message.dim = [];
message.dim.push($root.onnx.TensorShapeProto.Dimension.decode(reader, reader.uint32()));
break;
default:
reader.skipType(tag & 7);
break;
}
}
return message;
};
/**
* Decodes a TensorShapeProto message from the specified reader or buffer, length delimited.
* @function decodeDelimited
* @memberof onnx.TensorShapeProto
* @static
* @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
* @returns {onnx.TensorShapeProto} TensorShapeProto
* @throws {Error} If the payload is not a reader or valid buffer
* @throws {$protobuf.util.ProtocolError} If required fields are missing
*/
TensorShapeProto.decodeDelimited = function decodeDelimited(reader) {
if (!(reader instanceof $Reader))
reader = new $Reader(reader);
return this.decode(reader, reader.uint32());
};
/**
* Verifies a TensorShapeProto message.
* @function verify
* @memberof onnx.TensorShapeProto
* @static
* @param {Object.<string,*>} message Plain object to verify
* @returns {string|null} `null` if valid, otherwise the reason why it is not
*/
TensorShapeProto.verify = function verify(message) {
if (typeof message !== "object" || message === null)
return "object expected";
if (message.dim != null && message.hasOwnProperty("dim")) {
if (!Array.isArray(message.dim))
return "dim: array expected";
for (var i = 0; i < message.dim.length; ++i) {
var error = $root.onnx.TensorShapeProto.Dimension.verify(message.dim[i]);
if (error)
return "dim." + error;
}
}
return null;
};
/**
* Creates a TensorShapeProto message from a plain object. Also converts values to their respective internal types.
* @function fromObject
* @memberof onnx.TensorShapeProto
* @static
* @param {Object.<string,*>} object Plain object
* @returns {onnx.TensorShapeProto} TensorShapeProto
*/
TensorShapeProto.fromObject = function fromObject(object) {
if (object instanceof $root.onnx.TensorShapeProto)
return object;
var message = new $root.onnx.TensorShapeProto();
if (object.dim) {
if (!Array.isArray(object.dim))
throw TypeError(".onnx.TensorShapeProto.dim: array expected");
message.dim = [];
for (var i = 0; i < object.dim.length; ++i) {
if (typeof object.dim[i] !== "object")
throw TypeError(".onnx.TensorShapeProto.dim: object expected");
message.dim[i] = $root.onnx.TensorShapeProto.Dimension.fromObject(object.dim[i]);
}
}
return message;
};
/**
* Creates a plain object from a TensorShapeProto message. Also converts values to other types if specified.
* @function toObject
* @memberof onnx.TensorShapeProto
* @static
* @param {onnx.TensorShapeProto} message TensorShapeProto
* @param {$protobuf.IConversionOptions} [options] Conversion options
* @returns {Object.<string,*>} Plain object
*/
TensorShapeProto.toObject = function toObject(message, options) {
if (!options)
options = {};
var object = {};
if (options.arrays || options.defaults)
object.dim = [];
if (message.dim && message.dim.length) {
object.dim = [];
for (var j = 0; j < message.dim.length; ++j)
object.dim[j] = $root.onnx.TensorShapeProto.Dimension.toObject(message.dim[j], options);
}
return object;
};
/**
* Converts this TensorShapeProto to JSON.
* @function toJSON
* @memberof onnx.TensorShapeProto
* @instance
* @returns {Object.<string,*>} JSON object
*/
TensorShapeProto.prototype.toJSON = function toJSON() {
return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
};
TensorShapeProto.Dimension = (function() {
/**
* Properties of a Dimension.
* @memberof onnx.TensorShapeProto
* @interface IDimension
* @property {number|Long|null} [dimValue] Dimension dimValue
* @property {string|null} [dimParam] Dimension dimParam
* @property {string|null} [denotation] Dimension denotation
*/
/**
* Constructs a new Dimension.
* @memberof onnx.TensorShapeProto
* @classdesc Represents a Dimension.
* @implements IDimension
* @constructor
* @param {onnx.TensorShapeProto.IDimension=} [properties] Properties to set
*/
function Dimension(properties) {
if (properties)
for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
if (properties[keys[i]] != null)
this[keys[i]] = properties[keys[i]];
}
/**
* Dimension dimValue.
* @member {number|Long} dimValue
* @memberof onnx.TensorShapeProto.Dimension
* @instance
*/
Dimension.prototype.dimValue = $util.Long ? $util.Long.fromBits(0,0,false) : 0;
/**
* Dimension dimParam.
* @member {string} dimParam
* @memberof onnx.TensorShapeProto.Dimension
* @instance
*/
Dimension.prototype.dimParam = "";
/**
* Dimension denotation.
* @member {string} denotation
* @memberof onnx.TensorShapeProto.Dimension
* @instance
*/
Dimension.prototype.denotation = "";
// OneOf field names bound to virtual getters and setters
var $oneOfFields;
/**
* Dimension value.
* @member {"dimValue"|"dimParam"|undefined} value
* @memberof onnx.TensorShapeProto.Dimension
* @instance
*/
Object.defineProperty(Dimension.prototype, "value", {
get: $util.oneOfGetter($oneOfFields = ["dimValue", "dimParam"]),
set: $util.oneOfSetter($oneOfFields)
});
/**
* Creates a new Dimension instance using the specified properties.
* @function create
* @memberof onnx.TensorShapeProto.Dimension
* @static
* @param {onnx.TensorShapeProto.IDimension=} [properties] Properties to set
* @returns {onnx.TensorShapeProto.Dimension} Dimension instance
*/
Dimension.create = function create(properties) {
return new Dimension(properties);
};
/**
* Encodes the specified Dimension message. Does not implicitly {@link onnx.TensorShapeProto.Dimension.verify|verify} messages.
* @function encode
* @memberof onnx.TensorShapeProto.Dimension
* @static
* @param {onnx.TensorShapeProto.IDimension} message Dimension message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
Dimension.encode = function encode(message, writer) {
if (!writer)
writer = $Writer.create();
if (message.dimValue != null && message.hasOwnProperty("dimValue"))
writer.uint32(/* id 1, wireType 0 =*/8).int64(message.dimValue);
if (message.dimParam != null && message.hasOwnProperty("dimParam"))
writer.uint32(/* id 2, wireType 2 =*/18).string(message.dimParam);
if (message.denotation != null && message.hasOwnProperty("denotation"))
writer.uint32(/* id 3, wireType 2 =*/26).string(message.denotation);
return writer;
};
/**
* Encodes the specified Dimension message, length delimited. Does not implicitly {@link onnx.TensorShapeProto.Dimension.verify|verify} messages.
* @function encodeDelimited
* @memberof onnx.TensorShapeProto.Dimension
* @static
* @param {onnx.TensorShapeProto.IDimension} message Dimension message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
Dimension.encodeDelimited = function encodeDelimited(message, writer) {
return this.encode(message, writer).ldelim();
};
/**
* Decodes a Dimension message from the specified reader or buffer.
* @function decode
* @memberof onnx.TensorShapeProto.Dimension
* @static
* @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
* @param {number} [length] Message length if known beforehand
* @returns {onnx.TensorShapeProto.Dimension} Dimension
* @throws {Error} If the payload is not a reader or valid buffer
* @throws {$protobuf.util.ProtocolError} If required fields are missing
*/
Dimension.decode = function decode(reader, length) {
if (!(reader instanceof $Reader))
reader = $Reader.create(reader);
var end = length === undefined ? reader.len : reader.pos + length, message = new $root.onnx.TensorShapeProto.Dimension();
while (reader.pos < end) {
var tag = reader.uint32();
switch (tag >>> 3) {
case 1:
message.dimValue = reader.int64();
break;
case 2:
message.dimParam = reader.string();
break;
case 3:
message.denotation = reader.string();
break;
default:
reader.skipType(tag & 7);
break;
}
}
return message;
};
/**
* Decodes a Dimension message from the specified reader or buffer, length delimited.
* @function decodeDelimited
* @memberof onnx.TensorShapeProto.Dimension
* @static
* @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
* @returns {onnx.TensorShapeProto.Dimension} Dimension
* @throws {Error} If the payload is not a reader or valid buffer
* @throws {$protobuf.util.ProtocolError} If required fields are missing
*/
Dimension.decodeDelimited = function decodeDelimited(reader) {
if (!(reader instanceof $Reader))
reader = new $Reader(reader);
return this.decode(reader, reader.uint32());
};
/**
* Verifies a Dimension message.
* @function verify
* @memberof onnx.TensorShapeProto.Dimension
* @static
* @param {Object.<string,*>} message Plain object to verify
* @returns {string|null} `null` if valid, otherwise the reason why it is not
*/
Dimension.verify = function verify(message) {
if (typeof message !== "object" || message === null)
return "object expected";
var properties = {};
if (message.dimValue != null && message.hasOwnProperty("dimValue")) {
properties.value = 1;
if (!$util.isInteger(message.dimValue) && !(message.dimValue && $util.isInteger(message.dimValue.low) && $util.isInteger(message.dimValue.high)))
return "dimValue: integer|Long expected";
}
if (message.dimParam != null && message.hasOwnProperty("dimParam")) {
if (properties.value === 1)
return "value: multiple values";
properties.value = 1;
if (!$util.isString(message.dimParam))
return "dimParam: string expected";
}
if (message.denotation != null && message.hasOwnProperty("denotation"))
if (!$util.isString(message.denotation))
return "denotation: string expected";
return null;
};
/**
* Creates a Dimension message from a plain object. Also converts values to their respective internal types.
* @function fromObject
* @memberof onnx.TensorShapeProto.Dimension
* @static
* @param {Object.<string,*>} object Plain object
* @returns {onnx.TensorShapeProto.Dimension} Dimension
*/
Dimension.fromObject = function fromObject(object) {
if (object instanceof $root.onnx.TensorShapeProto.Dimension)
return object;
var message = new $root.onnx.TensorShapeProto.Dimension();
if (object.dimValue != null)
if ($util.Long)
(message.dimValue = $util.Long.fromValue(object.dimValue)).unsigned = false;
else if (typeof object.dimValue === "string")
message.dimValue = parseInt(object.dimValue, 10);
else if (typeof object.dimValue === "number")
message.dimValue = object.dimValue;
else if (typeof object.dimValue === "object")
message.dimValue = new $util.LongBits(object.dimValue.low >>> 0, object.dimValue.high >>> 0).toNumber();
if (object.dimParam != null)
message.dimParam = String(object.dimParam);
if (object.denotation != null)
message.denotation = String(object.denotation);
return message;
};
/**
* Creates a plain object from a Dimension message. Also converts values to other types if specified.
* @function toObject
* @memberof onnx.TensorShapeProto.Dimension
* @static
* @param {onnx.TensorShapeProto.Dimension} message Dimension
* @param {$protobuf.IConversionOptions} [options] Conversion options
* @returns {Object.<string,*>} Plain object
*/
Dimension.toObject = function toObject(message, options) {
if (!options)
options = {};
var object = {};
if (options.defaults)
object.denotation = "";
if (message.dimValue != null && message.hasOwnProperty("dimValue")) {
if (typeof message.dimValue === "number")
object.dimValue = options.longs === String ? String(message.dimValue) : message.dimValue;
else
object.dimValue = options.longs === String ? $util.Long.prototype.toString.call(message.dimValue) : options.longs === Number ? new $util.LongBits(message.dimValue.low >>> 0, message.dimValue.high >>> 0).toNumber() : message.dimValue;
if (options.oneofs)
object.value = "dimValue";
}
if (message.dimParam != null && message.hasOwnProperty("dimParam")) {
object.dimParam = message.dimParam;
if (options.oneofs)
object.value = "dimParam";
}
if (message.denotation != null && message.hasOwnProperty("denotation"))
object.denotation = message.denotation;
return object;
};
/**
* Converts this Dimension to JSON.
* @function toJSON
* @memberof onnx.TensorShapeProto.Dimension
* @instance
* @returns {Object.<string,*>} JSON object
*/
Dimension.prototype.toJSON = function toJSON() {
return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
};
return Dimension;
})();
return TensorShapeProto;
})();
onnx.TypeProto = (function() {
/**
* Properties of a TypeProto.
* @memberof onnx
* @interface ITypeProto
* @property {onnx.TypeProto.ITensor|null} [tensorType] TypeProto tensorType
* @property {string|null} [denotation] TypeProto denotation
*/
/**
* Constructs a new TypeProto.
* @memberof onnx
* @classdesc Represents a TypeProto.
* @implements ITypeProto
* @constructor
* @param {onnx.ITypeProto=} [properties] Properties to set
*/
function TypeProto(properties) {
if (properties)
for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
if (properties[keys[i]] != null)
this[keys[i]] = properties[keys[i]];
}
/**
* TypeProto tensorType.
* @member {onnx.TypeProto.ITensor|null|undefined} tensorType
* @memberof onnx.TypeProto
* @instance
*/
TypeProto.prototype.tensorType = null;
/**
* TypeProto denotation.
* @member {string} denotation
* @memberof onnx.TypeProto
* @instance
*/
TypeProto.prototype.denotation = "";
// OneOf field names bound to virtual getters and setters
var $oneOfFields;
/**
* TypeProto value.
* @member {"tensorType"|undefined} value
* @memberof onnx.TypeProto
* @instance
*/
Object.defineProperty(TypeProto.prototype, "value", {
get: $util.oneOfGetter($oneOfFields = ["tensorType"]),
set: $util.oneOfSetter($oneOfFields)
});
/**
* Creates a new TypeProto instance using the specified properties.
* @function create
* @memberof onnx.TypeProto
* @static
* @param {onnx.ITypeProto=} [properties] Properties to set
* @returns {onnx.TypeProto} TypeProto instance
*/
TypeProto.create = function create(properties) {
return new TypeProto(properties);
};
/**
* Encodes the specified TypeProto message. Does not implicitly {@link onnx.TypeProto.verify|verify} messages.
* @function encode
* @memberof onnx.TypeProto
* @static
* @param {onnx.ITypeProto} message TypeProto message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
TypeProto.encode = function encode(message, writer) {
if (!writer)
writer = $Writer.create();
if (message.tensorType != null && message.hasOwnProperty("tensorType"))
$root.onnx.TypeProto.Tensor.encode(message.tensorType, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
if (message.denotation != null && message.hasOwnProperty("denotation"))
writer.uint32(/* id 6, wireType 2 =*/50).string(message.denotation);
return writer;
};
/**
* Encodes the specified TypeProto message, length delimited. Does not implicitly {@link onnx.TypeProto.verify|verify} messages.
* @function encodeDelimited
* @memberof onnx.TypeProto
* @static
* @param {onnx.ITypeProto} message TypeProto message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
TypeProto.encodeDelimited = function encodeDelimited(message, writer) {
return this.encode(message, writer).ldelim();
};
/**
* Decodes a TypeProto message from the specified reader or buffer.
* @function decode
* @memberof onnx.TypeProto
* @static
* @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
* @param {number} [length] Message length if known beforehand
* @returns {onnx.TypeProto} TypeProto
* @throws {Error} If the payload is not a reader or valid buffer
* @throws {$protobuf.util.ProtocolError} If required fields are missing
*/
TypeProto.decode = function decode(reader, length) {
if (!(reader instanceof $Reader))
reader = $Reader.create(reader);
var end = length === undefined ? reader.len : reader.pos + length, message = new $root.onnx.TypeProto();
while (reader.pos < end) {
var tag = reader.uint32();
switch (tag >>> 3) {
case 1:
message.tensorType = $root.onnx.TypeProto.Tensor.decode(reader, reader.uint32());
break;
case 6:
message.denotation = reader.string();
break;
default:
reader.skipType(tag & 7);
break;
}
}
return message;
};
/**
* Decodes a TypeProto message from the specified reader or buffer, length delimited.
* @function decodeDelimited
* @memberof onnx.TypeProto
* @static
* @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
* @returns {onnx.TypeProto} TypeProto
* @throws {Error} If the payload is not a reader or valid buffer
* @throws {$protobuf.util.ProtocolError} If required fields are missing
*/
TypeProto.decodeDelimited = function decodeDelimited(reader) {
if (!(reader instanceof $Reader))
reader = new $Reader(reader);
return this.decode(reader, reader.uint32());
};
/**
* Verifies a TypeProto message.
* @function verify
* @memberof onnx.TypeProto
* @static
* @param {Object.<string,*>} message Plain object to verify
* @returns {string|null} `null` if valid, otherwise the reason why it is not
*/
TypeProto.verify = function verify(message) {
if (typeof message !== "object" || message === null)
return "object expected";
var properties = {};
if (message.tensorType != null && message.hasOwnProperty("tensorType")) {
properties.value = 1;
{
var error = $root.onnx.TypeProto.Tensor.verify(message.tensorType);
if (error)
return "tensorType." + error;
}
}
if (message.denotation != null && message.hasOwnProperty("denotation"))
if (!$util.isString(message.denotation))
return "denotation: string expected";
return null;
};
/**
* Creates a TypeProto message from a plain object. Also converts values to their respective internal types.
* @function fromObject
* @memberof onnx.TypeProto
* @static
* @param {Object.<string,*>} object Plain object
* @returns {onnx.TypeProto} TypeProto
*/
TypeProto.fromObject = function fromObject(object) {
if (object instanceof $root.onnx.TypeProto)
return object;
var message = new $root.onnx.TypeProto();
if (object.tensorType != null) {
if (typeof object.tensorType !== "object")
throw TypeError(".onnx.TypeProto.tensorType: object expected");
message.tensorType = $root.onnx.TypeProto.Tensor.fromObject(object.tensorType);
}
if (object.denotation != null)
message.denotation = String(object.denotation);
return message;
};
/**
* Creates a plain object from a TypeProto message. Also converts values to other types if specified.
* @function toObject
* @memberof onnx.TypeProto
* @static
* @param {onnx.TypeProto} message TypeProto
* @param {$protobuf.IConversionOptions} [options] Conversion options
* @returns {Object.<string,*>} Plain object
*/
TypeProto.toObject = function toObject(message, options) {
if (!options)
options = {};
var object = {};
if (options.defaults)
object.denotation = "";
if (message.tensorType != null && message.hasOwnProperty("tensorType")) {
object.tensorType = $root.onnx.TypeProto.Tensor.toObject(message.tensorType, options);
if (options.oneofs)
object.value = "tensorType";
}
if (message.denotation != null && message.hasOwnProperty("denotation"))
object.denotation = message.denotation;
return object;
};
/**
* Converts this TypeProto to JSON.
* @function toJSON
* @memberof onnx.TypeProto
* @instance
* @returns {Object.<string,*>} JSON object
*/
TypeProto.prototype.toJSON = function toJSON() {
return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
};
TypeProto.Tensor = (function() {
/**
* Properties of a Tensor.
* @memberof onnx.TypeProto
* @interface ITensor
* @property {number|null} [elemType] Tensor elemType
* @property {onnx.ITensorShapeProto|null} [shape] Tensor shape
*/
/**
* Constructs a new Tensor.
* @memberof onnx.TypeProto
* @classdesc Represents a Tensor.
* @implements ITensor
* @constructor
* @param {onnx.TypeProto.ITensor=} [properties] Properties to set
*/
function Tensor(properties) {
if (properties)
for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
if (properties[keys[i]] != null)
this[keys[i]] = properties[keys[i]];
}
/**
* Tensor elemType.
* @member {number} elemType
* @memberof onnx.TypeProto.Tensor
* @instance
*/
Tensor.prototype.elemType = 0;
/**
* Tensor shape.
* @member {onnx.ITensorShapeProto|null|undefined} shape
* @memberof onnx.TypeProto.Tensor
* @instance
*/
Tensor.prototype.shape = null;
/**
* Creates a new Tensor instance using the specified properties.
* @function create
* @memberof onnx.TypeProto.Tensor
* @static
* @param {onnx.TypeProto.ITensor=} [properties] Properties to set
* @returns {onnx.TypeProto.Tensor} Tensor instance
*/
Tensor.create = function create(properties) {
return new Tensor(properties);
};
/**
* Encodes the specified Tensor message. Does not implicitly {@link onnx.TypeProto.Tensor.verify|verify} messages.
* @function encode
* @memberof onnx.TypeProto.Tensor
* @static
* @param {onnx.TypeProto.ITensor} message Tensor message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
Tensor.encode = function encode(message, writer) {
if (!writer)
writer = $Writer.create();
if (message.elemType != null && message.hasOwnProperty("elemType"))
writer.uint32(/* id 1, wireType 0 =*/8).int32(message.elemType);
if (message.shape != null && message.hasOwnProperty("shape"))
$root.onnx.TensorShapeProto.encode(message.shape, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
return writer;
};
/**
* Encodes the specified Tensor message, length delimited. Does not implicitly {@link onnx.TypeProto.Tensor.verify|verify} messages.
* @function encodeDelimited
* @memberof onnx.TypeProto.Tensor
* @static
* @param {onnx.TypeProto.ITensor} message Tensor message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
Tensor.encodeDelimited = function encodeDelimited(message, writer) {
return this.encode(message, writer).ldelim();
};
/**
* Decodes a Tensor message from the specified reader or buffer.
* @function decode
* @memberof onnx.TypeProto.Tensor
* @static
* @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
* @param {number} [length] Message length if known beforehand
* @returns {onnx.TypeProto.Tensor} Tensor
* @throws {Error} If the payload is not a reader or valid buffer
* @throws {$protobuf.util.ProtocolError} If required fields are missing
*/
Tensor.decode = function decode(reader, length) {
if (!(reader instanceof $Reader))
reader = $Reader.create(reader);
var end = length === undefined ? reader.len : reader.pos + length, message = new $root.onnx.TypeProto.Tensor();
while (reader.pos < end) {
var tag = reader.uint32();
switch (tag >>> 3) {
case 1:
message.elemType = reader.int32();
break;
case 2:
message.shape = $root.onnx.TensorShapeProto.decode(reader, reader.uint32());
break;
default:
reader.skipType(tag & 7);
break;
}
}
return message;
};
/**
* Decodes a Tensor message from the specified reader or buffer, length delimited.
* @function decodeDelimited
* @memberof onnx.TypeProto.Tensor
* @static
* @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
* @returns {onnx.TypeProto.Tensor} Tensor
* @throws {Error} If the payload is not a reader or valid buffer
* @throws {$protobuf.util.ProtocolError} If required fields are missing
*/
Tensor.decodeDelimited = function decodeDelimited(reader) {
if (!(reader instanceof $Reader))
reader = new $Reader(reader);
return this.decode(reader, reader.uint32());
};
/**
* Verifies a Tensor message.
* @function verify
* @memberof onnx.TypeProto.Tensor
* @static
* @param {Object.<string,*>} message Plain object to verify
* @returns {string|null} `null` if valid, otherwise the reason why it is not
*/
Tensor.verify = function verify(message) {
if (typeof message !== "object" || message === null)
return "object expected";
if (message.elemType != null && message.hasOwnProperty("elemType"))
if (!$util.isInteger(message.elemType))
return "elemType: integer expected";
if (message.shape != null && message.hasOwnProperty("shape")) {
var error = $root.onnx.TensorShapeProto.verify(message.shape);
if (error)
return "shape." + error;
}
return null;
};
/**
* Creates a Tensor message from a plain object. Also converts values to their respective internal types.
* @function fromObject
* @memberof onnx.TypeProto.Tensor
* @static
* @param {Object.<string,*>} object Plain object
* @returns {onnx.TypeProto.Tensor} Tensor
*/
Tensor.fromObject = function fromObject(object) {
if (object instanceof $root.onnx.TypeProto.Tensor)
return object;
var message = new $root.onnx.TypeProto.Tensor();
if (object.elemType != null)
message.elemType = object.elemType | 0;
if (object.shape != null) {
if (typeof object.shape !== "object")
throw TypeError(".onnx.TypeProto.Tensor.shape: object expected");
message.shape = $root.onnx.TensorShapeProto.fromObject(object.shape);
}
return message;
};
/**
* Creates a plain object from a Tensor message. Also converts values to other types if specified.
* @function toObject
* @memberof onnx.TypeProto.Tensor
* @static
* @param {onnx.TypeProto.Tensor} message Tensor
* @param {$protobuf.IConversionOptions} [options] Conversion options
* @returns {Object.<string,*>} Plain object
*/
Tensor.toObject = function toObject(message, options) {
if (!options)
options = {};
var object = {};
if (options.defaults) {
object.elemType = 0;
object.shape = null;
}
if (message.elemType != null && message.hasOwnProperty("elemType"))
object.elemType = message.elemType;
if (message.shape != null && message.hasOwnProperty("shape"))
object.shape = $root.onnx.TensorShapeProto.toObject(message.shape, options);
return object;
};
/**
* Converts this Tensor to JSON.
* @function toJSON
* @memberof onnx.TypeProto.Tensor
* @instance
* @returns {Object.<string,*>} JSON object
*/
Tensor.prototype.toJSON = function toJSON() {
return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
};
return Tensor;
})();
return TypeProto;
})();
onnx.OperatorSetIdProto = (function() {
/**
* Properties of an OperatorSetIdProto.
* @memberof onnx
* @interface IOperatorSetIdProto
* @property {string|null} [domain] OperatorSetIdProto domain
* @property {number|Long|null} [version] OperatorSetIdProto version
*/
/**
* Constructs a new OperatorSetIdProto.
* @memberof onnx
* @classdesc Represents an OperatorSetIdProto.
* @implements IOperatorSetIdProto
* @constructor
* @param {onnx.IOperatorSetIdProto=} [properties] Properties to set
*/
function OperatorSetIdProto(properties) {
if (properties)
for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
if (properties[keys[i]] != null)
this[keys[i]] = properties[keys[i]];
}
/**
* OperatorSetIdProto domain.
* @member {string} domain
* @memberof onnx.OperatorSetIdProto
* @instance
*/
OperatorSetIdProto.prototype.domain = "";
/**
* OperatorSetIdProto version.
* @member {number|Long} version
* @memberof onnx.OperatorSetIdProto
* @instance
*/
OperatorSetIdProto.prototype.version = $util.Long ? $util.Long.fromBits(0,0,false) : 0;
/**
* Creates a new OperatorSetIdProto instance using the specified properties.
* @function create
* @memberof onnx.OperatorSetIdProto
* @static
* @param {onnx.IOperatorSetIdProto=} [properties] Properties to set
* @returns {onnx.OperatorSetIdProto} OperatorSetIdProto instance
*/
OperatorSetIdProto.create = function create(properties) {
return new OperatorSetIdProto(properties);
};
/**
* Encodes the specified OperatorSetIdProto message. Does not implicitly {@link onnx.OperatorSetIdProto.verify|verify} messages.
* @function encode
* @memberof onnx.OperatorSetIdProto
* @static
* @param {onnx.IOperatorSetIdProto} message OperatorSetIdProto message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
OperatorSetIdProto.encode = function encode(message, writer) {
if (!writer)
writer = $Writer.create();
if (message.domain != null && message.hasOwnProperty("domain"))
writer.uint32(/* id 1, wireType 2 =*/10).string(message.domain);
if (message.version != null && message.hasOwnProperty("version"))
writer.uint32(/* id 2, wireType 0 =*/16).int64(message.version);
return writer;
};
/**
* Encodes the specified OperatorSetIdProto message, length delimited. Does not implicitly {@link onnx.OperatorSetIdProto.verify|verify} messages.
* @function encodeDelimited
* @memberof onnx.OperatorSetIdProto
* @static
* @param {onnx.IOperatorSetIdProto} message OperatorSetIdProto message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
OperatorSetIdProto.encodeDelimited = function encodeDelimited(message, writer) {
return this.encode(message, writer).ldelim();
};
/**
* Decodes an OperatorSetIdProto message from the specified reader or buffer.
* @function decode
* @memberof onnx.OperatorSetIdProto
* @static
* @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
* @param {number} [length] Message length if known beforehand
* @returns {onnx.OperatorSetIdProto} OperatorSetIdProto
* @throws {Error} If the payload is not a reader or valid buffer
* @throws {$protobuf.util.ProtocolError} If required fields are missing
*/
OperatorSetIdProto.decode = function decode(reader, length) {
if (!(reader instanceof $Reader))
reader = $Reader.create(reader);
var end = length === undefined ? reader.len : reader.pos + length, message = new $root.onnx.OperatorSetIdProto();
while (reader.pos < end) {
var tag = reader.uint32();
switch (tag >>> 3) {
case 1:
message.domain = reader.string();
break;
case 2:
message.version = reader.int64();
break;
default:
reader.skipType(tag & 7);
break;
}
}
return message;
};
/**
* Decodes an OperatorSetIdProto message from the specified reader or buffer, length delimited.
* @function decodeDelimited
* @memberof onnx.OperatorSetIdProto
* @static
* @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
* @returns {onnx.OperatorSetIdProto} OperatorSetIdProto
* @throws {Error} If the payload is not a reader or valid buffer
* @throws {$protobuf.util.ProtocolError} If required fields are missing
*/
OperatorSetIdProto.decodeDelimited = function decodeDelimited(reader) {
if (!(reader instanceof $Reader))
reader = new $Reader(reader);
return this.decode(reader, reader.uint32());
};
/**
* Verifies an OperatorSetIdProto message.
* @function verify
* @memberof onnx.OperatorSetIdProto
* @static
* @param {Object.<string,*>} message Plain object to verify
* @returns {string|null} `null` if valid, otherwise the reason why it is not
*/
OperatorSetIdProto.verify = function verify(message) {
if (typeof message !== "object" || message === null)
return "object expected";
if (message.domain != null && message.hasOwnProperty("domain"))
if (!$util.isString(message.domain))
return "domain: string expected";
if (message.version != null && message.hasOwnProperty("version"))
if (!$util.isInteger(message.version) && !(message.version && $util.isInteger(message.version.low) && $util.isInteger(message.version.high)))
return "version: integer|Long expected";
return null;
};
/**
* Creates an OperatorSetIdProto message from a plain object. Also converts values to their respective internal types.
* @function fromObject
* @memberof onnx.OperatorSetIdProto
* @static
* @param {Object.<string,*>} object Plain object
* @returns {onnx.OperatorSetIdProto} OperatorSetIdProto
*/
OperatorSetIdProto.fromObject = function fromObject(object) {
if (object instanceof $root.onnx.OperatorSetIdProto)
return object;
var message = new $root.onnx.OperatorSetIdProto();
if (object.domain != null)
message.domain = String(object.domain);
if (object.version != null)
if ($util.Long)
(message.version = $util.Long.fromValue(object.version)).unsigned = false;
else if (typeof object.version === "string")
message.version = parseInt(object.version, 10);
else if (typeof object.version === "number")
message.version = object.version;
else if (typeof object.version === "object")
message.version = new $util.LongBits(object.version.low >>> 0, object.version.high >>> 0).toNumber();
return message;
};
/**
* Creates a plain object from an OperatorSetIdProto message. Also converts values to other types if specified.
* @function toObject
* @memberof onnx.OperatorSetIdProto
* @static
* @param {onnx.OperatorSetIdProto} message OperatorSetIdProto
* @param {$protobuf.IConversionOptions} [options] Conversion options
* @returns {Object.<string,*>} Plain object
*/
OperatorSetIdProto.toObject = function toObject(message, options) {
if (!options)
options = {};
var object = {};
if (options.defaults) {
object.domain = "";
if ($util.Long) {
var long = new $util.Long(0, 0, false);
object.version = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
} else
object.version = options.longs === String ? "0" : 0;
}
if (message.domain != null && message.hasOwnProperty("domain"))
object.domain = message.domain;
if (message.version != null && message.hasOwnProperty("version"))
if (typeof message.version === "number")
object.version = options.longs === String ? String(message.version) : message.version;
else
object.version = options.longs === String ? $util.Long.prototype.toString.call(message.version) : options.longs === Number ? new $util.LongBits(message.version.low >>> 0, message.version.high >>> 0).toNumber() : message.version;
return object;
};
/**
* Converts this OperatorSetIdProto to JSON.
* @function toJSON
* @memberof onnx.OperatorSetIdProto
* @instance
* @returns {Object.<string,*>} JSON object
*/
OperatorSetIdProto.prototype.toJSON = function toJSON() {
return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
};
return OperatorSetIdProto;
})();
return onnx;
})();
module.exports = $root;
/***/ }),
/***/ "./node_modules/protobufjs/minimal.js":
/*!********************************************!*\
!*** ./node_modules/protobufjs/minimal.js ***!
\********************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
// minimal library entry point.
module.exports = __webpack_require__(/*! ./src/index-minimal */ "./node_modules/protobufjs/src/index-minimal.js");
/***/ }),
/***/ "./node_modules/protobufjs/src/index-minimal.js":
/*!******************************************************!*\
!*** ./node_modules/protobufjs/src/index-minimal.js ***!
\******************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
var protobuf = exports;
/**
* Build type, one of `"full"`, `"light"` or `"minimal"`.
* @name build
* @type {string}
* @const
*/
protobuf.build = "minimal";
// Serialization
protobuf.Writer = __webpack_require__(/*! ./writer */ "./node_modules/protobufjs/src/writer.js");
protobuf.BufferWriter = __webpack_require__(/*! ./writer_buffer */ "./node_modules/protobufjs/src/writer_buffer.js");
protobuf.Reader = __webpack_require__(/*! ./reader */ "./node_modules/protobufjs/src/reader.js");
protobuf.BufferReader = __webpack_require__(/*! ./reader_buffer */ "./node_modules/protobufjs/src/reader_buffer.js");
// Utility
protobuf.util = __webpack_require__(/*! ./util/minimal */ "./node_modules/protobufjs/src/util/minimal.js");
protobuf.rpc = __webpack_require__(/*! ./rpc */ "./node_modules/protobufjs/src/rpc.js");
protobuf.roots = __webpack_require__(/*! ./roots */ "./node_modules/protobufjs/src/roots.js");
protobuf.configure = configure;
/* istanbul ignore next */
/**
* Reconfigures the library according to the environment.
* @returns {undefined}
*/
function configure() {
protobuf.util._configure();
protobuf.Writer._configure(protobuf.BufferWriter);
protobuf.Reader._configure(protobuf.BufferReader);
}
// Set up buffer utility according to the environment
configure();
/***/ }),
/***/ "./node_modules/protobufjs/src/reader.js":
/*!***********************************************!*\
!*** ./node_modules/protobufjs/src/reader.js ***!
\***********************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
module.exports = Reader;
var util = __webpack_require__(/*! ./util/minimal */ "./node_modules/protobufjs/src/util/minimal.js");
var BufferReader; // cyclic
var LongBits = util.LongBits,
utf8 = util.utf8;
/* istanbul ignore next */
function indexOutOfRange(reader, writeLength) {
return RangeError("index out of range: " + reader.pos + " + " + (writeLength || 1) + " > " + reader.len);
}
/**
* Constructs a new reader instance using the specified buffer.
* @classdesc Wire format reader using `Uint8Array` if available, otherwise `Array`.
* @constructor
* @param {Uint8Array} buffer Buffer to read from
*/
function Reader(buffer) {
/**
* Read buffer.
* @type {Uint8Array}
*/
this.buf = buffer;
/**
* Read buffer position.
* @type {number}
*/
this.pos = 0;
/**
* Read buffer length.
* @type {number}
*/
this.len = buffer.length;
}
var create_array = typeof Uint8Array !== "undefined"
? function create_typed_array(buffer) {
if (buffer instanceof Uint8Array || Array.isArray(buffer))
return new Reader(buffer);
throw Error("illegal buffer");
}
/* istanbul ignore next */
: function create_array(buffer) {
if (Array.isArray(buffer))
return new Reader(buffer);
throw Error("illegal buffer");
};
var create = function create() {
return util.Buffer
? function create_buffer_setup(buffer) {
return (Reader.create = function create_buffer(buffer) {
return util.Buffer.isBuffer(buffer)
? new BufferReader(buffer)
/* istanbul ignore next */
: create_array(buffer);
})(buffer);
}
/* istanbul ignore next */
: create_array;
};
/**
* Creates a new reader using the specified buffer.
* @function
* @param {Uint8Array|Buffer} buffer Buffer to read from
* @returns {Reader|BufferReader} A {@link BufferReader} if `buffer` is a Buffer, otherwise a {@link Reader}
* @throws {Error} If `buffer` is not a valid buffer
*/
Reader.create = create();
Reader.prototype._slice = util.Array.prototype.subarray || /* istanbul ignore next */ util.Array.prototype.slice;
/**
* Reads a varint as an unsigned 32 bit value.
* @function
* @returns {number} Value read
*/
Reader.prototype.uint32 = (function read_uint32_setup() {
var value = 4294967295; // optimizer type-hint, tends to deopt otherwise (?!)
return function read_uint32() {
value = ( this.buf[this.pos] & 127 ) >>> 0; if (this.buf[this.pos++] < 128) return value;
value = (value | (this.buf[this.pos] & 127) << 7) >>> 0; if (this.buf[this.pos++] < 128) return value;
value = (value | (this.buf[this.pos] & 127) << 14) >>> 0; if (this.buf[this.pos++] < 128) return value;
value = (value | (this.buf[this.pos] & 127) << 21) >>> 0; if (this.buf[this.pos++] < 128) return value;
value = (value | (this.buf[this.pos] & 15) << 28) >>> 0; if (this.buf[this.pos++] < 128) return value;
/* istanbul ignore if */
if ((this.pos += 5) > this.len) {
this.pos = this.len;
throw indexOutOfRange(this, 10);
}
return value;
};
})();
/**
* Reads a varint as a signed 32 bit value.
* @returns {number} Value read
*/
Reader.prototype.int32 = function read_int32() {
return this.uint32() | 0;
};
/**
* Reads a zig-zag encoded varint as a signed 32 bit value.
* @returns {number} Value read
*/
Reader.prototype.sint32 = function read_sint32() {
var value = this.uint32();
return value >>> 1 ^ -(value & 1) | 0;
};
/* eslint-disable no-invalid-this */
function readLongVarint() {
// tends to deopt with local vars for octet etc.
var bits = new LongBits(0, 0);
var i = 0;
if (this.len - this.pos > 4) { // fast route (lo)
for (; i < 4; ++i) {
// 1st..4th
bits.lo = (bits.lo | (this.buf[this.pos] & 127) << i * 7) >>> 0;
if (this.buf[this.pos++] < 128)
return bits;
}
// 5th
bits.lo = (bits.lo | (this.buf[this.pos] & 127) << 28) >>> 0;
bits.hi = (bits.hi | (this.buf[this.pos] & 127) >> 4) >>> 0;
if (this.buf[this.pos++] < 128)
return bits;
i = 0;
} else {
for (; i < 3; ++i) {
/* istanbul ignore if */
if (this.pos >= this.len)
throw indexOutOfRange(this);
// 1st..3th
bits.lo = (bits.lo | (this.buf[this.pos] & 127) << i * 7) >>> 0;
if (this.buf[this.pos++] < 128)
return bits;
}
// 4th
bits.lo = (bits.lo | (this.buf[this.pos++] & 127) << i * 7) >>> 0;
return bits;
}
if (this.len - this.pos > 4) { // fast route (hi)
for (; i < 5; ++i) {
// 6th..10th
bits.hi = (bits.hi | (this.buf[this.pos] & 127) << i * 7 + 3) >>> 0;
if (this.buf[this.pos++] < 128)
return bits;
}
} else {
for (; i < 5; ++i) {
/* istanbul ignore if */
if (this.pos >= this.len)
throw indexOutOfRange(this);
// 6th..10th
bits.hi = (bits.hi | (this.buf[this.pos] & 127) << i * 7 + 3) >>> 0;
if (this.buf[this.pos++] < 128)
return bits;
}
}
/* istanbul ignore next */
throw Error("invalid varint encoding");
}
/* eslint-enable no-invalid-this */
/**
* Reads a varint as a signed 64 bit value.
* @name Reader#int64
* @function
* @returns {Long} Value read
*/
/**
* Reads a varint as an unsigned 64 bit value.
* @name Reader#uint64
* @function
* @returns {Long} Value read
*/
/**
* Reads a zig-zag encoded varint as a signed 64 bit value.
* @name Reader#sint64
* @function
* @returns {Long} Value read
*/
/**
* Reads a varint as a boolean.
* @returns {boolean} Value read
*/
Reader.prototype.bool = function read_bool() {
return this.uint32() !== 0;
};
function readFixed32_end(buf, end) { // note that this uses `end`, not `pos`
return (buf[end - 4]
| buf[end - 3] << 8
| buf[end - 2] << 16
| buf[end - 1] << 24) >>> 0;
}
/**
* Reads fixed 32 bits as an unsigned 32 bit integer.
* @returns {number} Value read
*/
Reader.prototype.fixed32 = function read_fixed32() {
/* istanbul ignore if */
if (this.pos + 4 > this.len)
throw indexOutOfRange(this, 4);
return readFixed32_end(this.buf, this.pos += 4);
};
/**
* Reads fixed 32 bits as a signed 32 bit integer.
* @returns {number} Value read
*/
Reader.prototype.sfixed32 = function read_sfixed32() {
/* istanbul ignore if */
if (this.pos + 4 > this.len)
throw indexOutOfRange(this, 4);
return readFixed32_end(this.buf, this.pos += 4) | 0;
};
/* eslint-disable no-invalid-this */
function readFixed64(/* this: Reader */) {
/* istanbul ignore if */
if (this.pos + 8 > this.len)
throw indexOutOfRange(this, 8);
return new LongBits(readFixed32_end(this.buf, this.pos += 4), readFixed32_end(this.buf, this.pos += 4));
}
/* eslint-enable no-invalid-this */
/**
* Reads fixed 64 bits.
* @name Reader#fixed64
* @function
* @returns {Long} Value read
*/
/**
* Reads zig-zag encoded fixed 64 bits.
* @name Reader#sfixed64
* @function
* @returns {Long} Value read
*/
/**
* Reads a float (32 bit) as a number.
* @function
* @returns {number} Value read
*/
Reader.prototype.float = function read_float() {
/* istanbul ignore if */
if (this.pos + 4 > this.len)
throw indexOutOfRange(this, 4);
var value = util.float.readFloatLE(this.buf, this.pos);
this.pos += 4;
return value;
};
/**
* Reads a double (64 bit float) as a number.
* @function
* @returns {number} Value read
*/
Reader.prototype.double = function read_double() {
/* istanbul ignore if */
if (this.pos + 8 > this.len)
throw indexOutOfRange(this, 4);
var value = util.float.readDoubleLE(this.buf, this.pos);
this.pos += 8;
return value;
};
/**
* Reads a sequence of bytes preceeded by its length as a varint.
* @returns {Uint8Array} Value read
*/
Reader.prototype.bytes = function read_bytes() {
var length = this.uint32(),
start = this.pos,
end = this.pos + length;
/* istanbul ignore if */
if (end > this.len)
throw indexOutOfRange(this, length);
this.pos += length;
if (Array.isArray(this.buf)) // plain array
return this.buf.slice(start, end);
return start === end // fix for IE 10/Win8 and others' subarray returning array of size 1
? new this.buf.constructor(0)
: this._slice.call(this.buf, start, end);
};
/**
* Reads a string preceeded by its byte length as a varint.
* @returns {string} Value read
*/
Reader.prototype.string = function read_string() {
var bytes = this.bytes();
return utf8.read(bytes, 0, bytes.length);
};
/**
* Skips the specified number of bytes if specified, otherwise skips a varint.
* @param {number} [length] Length if known, otherwise a varint is assumed
* @returns {Reader} `this`
*/
Reader.prototype.skip = function skip(length) {
if (typeof length === "number") {
/* istanbul ignore if */
if (this.pos + length > this.len)
throw indexOutOfRange(this, length);
this.pos += length;
} else {
do {
/* istanbul ignore if */
if (this.pos >= this.len)
throw indexOutOfRange(this);
} while (this.buf[this.pos++] & 128);
}
return this;
};
/**
* Skips the next element of the specified wire type.
* @param {number} wireType Wire type received
* @returns {Reader} `this`
*/
Reader.prototype.skipType = function(wireType) {
switch (wireType) {
case 0:
this.skip();
break;
case 1:
this.skip(8);
break;
case 2:
this.skip(this.uint32());
break;
case 3:
while ((wireType = this.uint32() & 7) !== 4) {
this.skipType(wireType);
}
break;
case 5:
this.skip(4);
break;
/* istanbul ignore next */
default:
throw Error("invalid wire type " + wireType + " at offset " + this.pos);
}
return this;
};
Reader._configure = function(BufferReader_) {
BufferReader = BufferReader_;
Reader.create = create();
BufferReader._configure();
var fn = util.Long ? "toLong" : /* istanbul ignore next */ "toNumber";
util.merge(Reader.prototype, {
int64: function read_int64() {
return readLongVarint.call(this)[fn](false);
},
uint64: function read_uint64() {
return readLongVarint.call(this)[fn](true);
},
sint64: function read_sint64() {
return readLongVarint.call(this).zzDecode()[fn](false);
},
fixed64: function read_fixed64() {
return readFixed64.call(this)[fn](true);
},
sfixed64: function read_sfixed64() {
return readFixed64.call(this)[fn](false);
}
});
};
/***/ }),
/***/ "./node_modules/protobufjs/src/reader_buffer.js":
/*!******************************************************!*\
!*** ./node_modules/protobufjs/src/reader_buffer.js ***!
\******************************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
module.exports = BufferReader;
// extends Reader
var Reader = __webpack_require__(/*! ./reader */ "./node_modules/protobufjs/src/reader.js");
(BufferReader.prototype = Object.create(Reader.prototype)).constructor = BufferReader;
var util = __webpack_require__(/*! ./util/minimal */ "./node_modules/protobufjs/src/util/minimal.js");
/**
* Constructs a new buffer reader instance.
* @classdesc Wire format reader using node buffers.
* @extends Reader
* @constructor
* @param {Buffer} buffer Buffer to read from
*/
function BufferReader(buffer) {
Reader.call(this, buffer);
/**
* Read buffer.
* @name BufferReader#buf
* @type {Buffer}
*/
}
BufferReader._configure = function () {
/* istanbul ignore else */
if (util.Buffer)
BufferReader.prototype._slice = util.Buffer.prototype.slice;
};
/**
* @override
*/
BufferReader.prototype.string = function read_string_buffer() {
var len = this.uint32(); // modifies pos
return this.buf.utf8Slice
? this.buf.utf8Slice(this.pos, this.pos = Math.min(this.pos + len, this.len))
: this.buf.toString("utf-8", this.pos, this.pos = Math.min(this.pos + len, this.len));
};
/**
* Reads a sequence of bytes preceeded by its length as a varint.
* @name BufferReader#bytes
* @function
* @returns {Buffer} Value read
*/
BufferReader._configure();
/***/ }),
/***/ "./node_modules/protobufjs/src/roots.js":
/*!**********************************************!*\
!*** ./node_modules/protobufjs/src/roots.js ***!
\**********************************************/
/***/ ((module) => {
"use strict";
module.exports = {};
/**
* Named roots.
* This is where pbjs stores generated structures (the option `-r, --root` specifies a name).
* Can also be used manually to make roots available accross modules.
* @name roots
* @type {Object.<string,Root>}
* @example
* // pbjs -r myroot -o compiled.js ...
*
* // in another module:
* require("./compiled.js");
*
* // in any subsequent module:
* var root = protobuf.roots["myroot"];
*/
/***/ }),
/***/ "./node_modules/protobufjs/src/rpc.js":
/*!********************************************!*\
!*** ./node_modules/protobufjs/src/rpc.js ***!
\********************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
/**
* Streaming RPC helpers.
* @namespace
*/
var rpc = exports;
/**
* RPC implementation passed to {@link Service#create} performing a service request on network level, i.e. by utilizing http requests or websockets.
* @typedef RPCImpl
* @type {function}
* @param {Method|rpc.ServiceMethod<Message<{}>,Message<{}>>} method Reflected or static method being called
* @param {Uint8Array} requestData Request data
* @param {RPCImplCallback} callback Callback function
* @returns {undefined}
* @example
* function rpcImpl(method, requestData, callback) {
* if (protobuf.util.lcFirst(method.name) !== "myMethod") // compatible with static code
* throw Error("no such method");
* asynchronouslyObtainAResponse(requestData, function(err, responseData) {
* callback(err, responseData);
* });
* }
*/
/**
* Node-style callback as used by {@link RPCImpl}.
* @typedef RPCImplCallback
* @type {function}
* @param {Error|null} error Error, if any, otherwise `null`
* @param {Uint8Array|null} [response] Response data or `null` to signal end of stream, if there hasn't been an error
* @returns {undefined}
*/
rpc.Service = __webpack_require__(/*! ./rpc/service */ "./node_modules/protobufjs/src/rpc/service.js");
/***/ }),
/***/ "./node_modules/protobufjs/src/rpc/service.js":
/*!****************************************************!*\
!*** ./node_modules/protobufjs/src/rpc/service.js ***!
\****************************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
module.exports = Service;
var util = __webpack_require__(/*! ../util/minimal */ "./node_modules/protobufjs/src/util/minimal.js");
// Extends EventEmitter
(Service.prototype = Object.create(util.EventEmitter.prototype)).constructor = Service;
/**
* A service method callback as used by {@link rpc.ServiceMethod|ServiceMethod}.
*
* Differs from {@link RPCImplCallback} in that it is an actual callback of a service method which may not return `response = null`.
* @typedef rpc.ServiceMethodCallback
* @template TRes extends Message<TRes>
* @type {function}
* @param {Error|null} error Error, if any
* @param {TRes} [response] Response message
* @returns {undefined}
*/
/**
* A service method part of a {@link rpc.Service} as created by {@link Service.create}.
* @typedef rpc.ServiceMethod
* @template TReq extends Message<TReq>
* @template TRes extends Message<TRes>
* @type {function}
* @param {TReq|Properties<TReq>} request Request message or plain object
* @param {rpc.ServiceMethodCallback<TRes>} [callback] Node-style callback called with the error, if any, and the response message
* @returns {Promise<Message<TRes>>} Promise if `callback` has been omitted, otherwise `undefined`
*/
/**
* Constructs a new RPC service instance.
* @classdesc An RPC service as returned by {@link Service#create}.
* @exports rpc.Service
* @extends util.EventEmitter
* @constructor
* @param {RPCImpl} rpcImpl RPC implementation
* @param {boolean} [requestDelimited=false] Whether requests are length-delimited
* @param {boolean} [responseDelimited=false] Whether responses are length-delimited
*/
function Service(rpcImpl, requestDelimited, responseDelimited) {
if (typeof rpcImpl !== "function")
throw TypeError("rpcImpl must be a function");
util.EventEmitter.call(this);
/**
* RPC implementation. Becomes `null` once the service is ended.
* @type {RPCImpl|null}
*/
this.rpcImpl = rpcImpl;
/**
* Whether requests are length-delimited.
* @type {boolean}
*/
this.requestDelimited = Boolean(requestDelimited);
/**
* Whether responses are length-delimited.
* @type {boolean}
*/
this.responseDelimited = Boolean(responseDelimited);
}
/**
* Calls a service method through {@link rpc.Service#rpcImpl|rpcImpl}.
* @param {Method|rpc.ServiceMethod<TReq,TRes>} method Reflected or static method
* @param {Constructor<TReq>} requestCtor Request constructor
* @param {Constructor<TRes>} responseCtor Response constructor
* @param {TReq|Properties<TReq>} request Request message or plain object
* @param {rpc.ServiceMethodCallback<TRes>} callback Service callback
* @returns {undefined}
* @template TReq extends Message<TReq>
* @template TRes extends Message<TRes>
*/
Service.prototype.rpcCall = function rpcCall(method, requestCtor, responseCtor, request, callback) {
if (!request)
throw TypeError("request must be specified");
var self = this;
if (!callback)
return util.asPromise(rpcCall, self, method, requestCtor, responseCtor, request);
if (!self.rpcImpl) {
setTimeout(function() { callback(Error("already ended")); }, 0);
return undefined;
}
try {
return self.rpcImpl(
method,
requestCtor[self.requestDelimited ? "encodeDelimited" : "encode"](request).finish(),
function rpcCallback(err, response) {
if (err) {
self.emit("error", err, method);
return callback(err);
}
if (response === null) {
self.end(/* endedByRPC */ true);
return undefined;
}
if (!(response instanceof responseCtor)) {
try {
response = responseCtor[self.responseDelimited ? "decodeDelimited" : "decode"](response);
} catch (err) {
self.emit("error", err, method);
return callback(err);
}
}
self.emit("data", response, method);
return callback(null, response);
}
);
} catch (err) {
self.emit("error", err, method);
setTimeout(function() { callback(err); }, 0);
return undefined;
}
};
/**
* Ends this service and emits the `end` event.
* @param {boolean} [endedByRPC=false] Whether the service has been ended by the RPC implementation.
* @returns {rpc.Service} `this`
*/
Service.prototype.end = function end(endedByRPC) {
if (this.rpcImpl) {
if (!endedByRPC) // signal end to rpcImpl
this.rpcImpl(null, null, null);
this.rpcImpl = null;
this.emit("end").off();
}
return this;
};
/***/ }),
/***/ "./node_modules/protobufjs/src/util/longbits.js":
/*!******************************************************!*\
!*** ./node_modules/protobufjs/src/util/longbits.js ***!
\******************************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
module.exports = LongBits;
var util = __webpack_require__(/*! ../util/minimal */ "./node_modules/protobufjs/src/util/minimal.js");
/**
* Constructs new long bits.
* @classdesc Helper class for working with the low and high bits of a 64 bit value.
* @memberof util
* @constructor
* @param {number} lo Low 32 bits, unsigned
* @param {number} hi High 32 bits, unsigned
*/
function LongBits(lo, hi) {
// note that the casts below are theoretically unnecessary as of today, but older statically
// generated converter code might still call the ctor with signed 32bits. kept for compat.
/**
* Low bits.
* @type {number}
*/
this.lo = lo >>> 0;
/**
* High bits.
* @type {number}
*/
this.hi = hi >>> 0;
}
/**
* Zero bits.
* @memberof util.LongBits
* @type {util.LongBits}
*/
var zero = LongBits.zero = new LongBits(0, 0);
zero.toNumber = function() { return 0; };
zero.zzEncode = zero.zzDecode = function() { return this; };
zero.length = function() { return 1; };
/**
* Zero hash.
* @memberof util.LongBits
* @type {string}
*/
var zeroHash = LongBits.zeroHash = "\0\0\0\0\0\0\0\0";
/**
* Constructs new long bits from the specified number.
* @param {number} value Value
* @returns {util.LongBits} Instance
*/
LongBits.fromNumber = function fromNumber(value) {
if (value === 0)
return zero;
var sign = value < 0;
if (sign)
value = -value;
var lo = value >>> 0,
hi = (value - lo) / 4294967296 >>> 0;
if (sign) {
hi = ~hi >>> 0;
lo = ~lo >>> 0;
if (++lo > 4294967295) {
lo = 0;
if (++hi > 4294967295)
hi = 0;
}
}
return new LongBits(lo, hi);
};
/**
* Constructs new long bits from a number, long or string.
* @param {Long|number|string} value Value
* @returns {util.LongBits} Instance
*/
LongBits.from = function from(value) {
if (typeof value === "number")
return LongBits.fromNumber(value);
if (util.isString(value)) {
/* istanbul ignore else */
if (util.Long)
value = util.Long.fromString(value);
else
return LongBits.fromNumber(parseInt(value, 10));
}
return value.low || value.high ? new LongBits(value.low >>> 0, value.high >>> 0) : zero;
};
/**
* Converts this long bits to a possibly unsafe JavaScript number.
* @param {boolean} [unsigned=false] Whether unsigned or not
* @returns {number} Possibly unsafe number
*/
LongBits.prototype.toNumber = function toNumber(unsigned) {
if (!unsigned && this.hi >>> 31) {
var lo = ~this.lo + 1 >>> 0,
hi = ~this.hi >>> 0;
if (!lo)
hi = hi + 1 >>> 0;
return -(lo + hi * 4294967296);
}
return this.lo + this.hi * 4294967296;
};
/**
* Converts this long bits to a long.
* @param {boolean} [unsigned=false] Whether unsigned or not
* @returns {Long} Long
*/
LongBits.prototype.toLong = function toLong(unsigned) {
return util.Long
? new util.Long(this.lo | 0, this.hi | 0, Boolean(unsigned))
/* istanbul ignore next */
: { low: this.lo | 0, high: this.hi | 0, unsigned: Boolean(unsigned) };
};
var charCodeAt = String.prototype.charCodeAt;
/**
* Constructs new long bits from the specified 8 characters long hash.
* @param {string} hash Hash
* @returns {util.LongBits} Bits
*/
LongBits.fromHash = function fromHash(hash) {
if (hash === zeroHash)
return zero;
return new LongBits(
( charCodeAt.call(hash, 0)
| charCodeAt.call(hash, 1) << 8
| charCodeAt.call(hash, 2) << 16
| charCodeAt.call(hash, 3) << 24) >>> 0
,
( charCodeAt.call(hash, 4)
| charCodeAt.call(hash, 5) << 8
| charCodeAt.call(hash, 6) << 16
| charCodeAt.call(hash, 7) << 24) >>> 0
);
};
/**
* Converts this long bits to a 8 characters long hash.
* @returns {string} Hash
*/
LongBits.prototype.toHash = function toHash() {
return String.fromCharCode(
this.lo & 255,
this.lo >>> 8 & 255,
this.lo >>> 16 & 255,
this.lo >>> 24 ,
this.hi & 255,
this.hi >>> 8 & 255,
this.hi >>> 16 & 255,
this.hi >>> 24
);
};
/**
* Zig-zag encodes this long bits.
* @returns {util.LongBits} `this`
*/
LongBits.prototype.zzEncode = function zzEncode() {
var mask = this.hi >> 31;
this.hi = ((this.hi << 1 | this.lo >>> 31) ^ mask) >>> 0;
this.lo = ( this.lo << 1 ^ mask) >>> 0;
return this;
};
/**
* Zig-zag decodes this long bits.
* @returns {util.LongBits} `this`
*/
LongBits.prototype.zzDecode = function zzDecode() {
var mask = -(this.lo & 1);
this.lo = ((this.lo >>> 1 | this.hi << 31) ^ mask) >>> 0;
this.hi = ( this.hi >>> 1 ^ mask) >>> 0;
return this;
};
/**
* Calculates the length of this longbits when encoded as a varint.
* @returns {number} Length
*/
LongBits.prototype.length = function length() {
var part0 = this.lo,
part1 = (this.lo >>> 28 | this.hi << 4) >>> 0,
part2 = this.hi >>> 24;
return part2 === 0
? part1 === 0
? part0 < 16384
? part0 < 128 ? 1 : 2
: part0 < 2097152 ? 3 : 4
: part1 < 16384
? part1 < 128 ? 5 : 6
: part1 < 2097152 ? 7 : 8
: part2 < 128 ? 9 : 10;
};
/***/ }),
/***/ "./node_modules/protobufjs/src/util/minimal.js":
/*!*****************************************************!*\
!*** ./node_modules/protobufjs/src/util/minimal.js ***!
\*****************************************************/
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
"use strict";
var util = exports;
// used to return a Promise where callback is omitted
util.asPromise = __webpack_require__(/*! @protobufjs/aspromise */ "./node_modules/@protobufjs/aspromise/index.js");
// converts to / from base64 encoded strings
util.base64 = __webpack_require__(/*! @protobufjs/base64 */ "./node_modules/@protobufjs/base64/index.js");
// base class of rpc.Service
util.EventEmitter = __webpack_require__(/*! @protobufjs/eventemitter */ "./node_modules/@protobufjs/eventemitter/index.js");
// float handling accross browsers
util.float = __webpack_require__(/*! @protobufjs/float */ "./node_modules/@protobufjs/float/index.js");
// requires modules optionally and hides the call from bundlers
util.inquire = __webpack_require__(/*! @protobufjs/inquire */ "./node_modules/@protobufjs/inquire/index.js");
// converts to / from utf8 encoded strings
util.utf8 = __webpack_require__(/*! @protobufjs/utf8 */ "./node_modules/@protobufjs/utf8/index.js");
// provides a node-like buffer pool in the browser
util.pool = __webpack_require__(/*! @protobufjs/pool */ "./node_modules/@protobufjs/pool/index.js");
// utility to work with the low and high bits of a 64 bit value
util.LongBits = __webpack_require__(/*! ./longbits */ "./node_modules/protobufjs/src/util/longbits.js");
/**
* Whether running within node or not.
* @memberof util
* @type {boolean}
*/
util.isNode = Boolean(typeof __webpack_require__.g !== "undefined"
&& __webpack_require__.g
&& __webpack_require__.g.process
&& __webpack_require__.g.process.versions
&& __webpack_require__.g.process.versions.node);
/**
* Global object reference.
* @memberof util
* @type {Object}
*/
util.global = util.isNode && __webpack_require__.g
|| typeof window !== "undefined" && window
|| typeof self !== "undefined" && self
|| this; // eslint-disable-line no-invalid-this
/**
* An immuable empty array.
* @memberof util
* @type {Array.<*>}
* @const
*/
util.emptyArray = Object.freeze ? Object.freeze([]) : /* istanbul ignore next */ []; // used on prototypes
/**
* An immutable empty object.
* @type {Object}
* @const
*/
util.emptyObject = Object.freeze ? Object.freeze({}) : /* istanbul ignore next */ {}; // used on prototypes
/**
* Tests if the specified value is an integer.
* @function
* @param {*} value Value to test
* @returns {boolean} `true` if the value is an integer
*/
util.isInteger = Number.isInteger || /* istanbul ignore next */ function isInteger(value) {
return typeof value === "number" && isFinite(value) && Math.floor(value) === value;
};
/**
* Tests if the specified value is a string.
* @param {*} value Value to test
* @returns {boolean} `true` if the value is a string
*/
util.isString = function isString(value) {
return typeof value === "string" || value instanceof String;
};
/**
* Tests if the specified value is a non-null object.
* @param {*} value Value to test
* @returns {boolean} `true` if the value is a non-null object
*/
util.isObject = function isObject(value) {
return value && typeof value === "object";
};
/**
* Checks if a property on a message is considered to be present.
* This is an alias of {@link util.isSet}.
* @function
* @param {Object} obj Plain object or message instance
* @param {string} prop Property name
* @returns {boolean} `true` if considered to be present, otherwise `false`
*/
util.isset =
/**
* Checks if a property on a message is considered to be present.
* @param {Object} obj Plain object or message instance
* @param {string} prop Property name
* @returns {boolean} `true` if considered to be present, otherwise `false`
*/
util.isSet = function isSet(obj, prop) {
var value = obj[prop];
if (value != null && obj.hasOwnProperty(prop)) // eslint-disable-line eqeqeq, no-prototype-builtins
return typeof value !== "object" || (Array.isArray(value) ? value.length : Object.keys(value).length) > 0;
return false;
};
/**
* Any compatible Buffer instance.
* This is a minimal stand-alone definition of a Buffer instance. The actual type is that exported by node's typings.
* @interface Buffer
* @extends Uint8Array
*/
/**
* Node's Buffer class if available.
* @type {Constructor<Buffer>}
*/
util.Buffer = (function() {
try {
var Buffer = util.inquire("buffer").Buffer;
// refuse to use non-node buffers if not explicitly assigned (perf reasons):
return Buffer.prototype.utf8Write ? Buffer : /* istanbul ignore next */ null;
} catch (e) {
/* istanbul ignore next */
return null;
}
})();
// Internal alias of or polyfull for Buffer.from.
util._Buffer_from = null;
// Internal alias of or polyfill for Buffer.allocUnsafe.
util._Buffer_allocUnsafe = null;
/**
* Creates a new buffer of whatever type supported by the environment.
* @param {number|number[]} [sizeOrArray=0] Buffer size or number array
* @returns {Uint8Array|Buffer} Buffer
*/
util.newBuffer = function newBuffer(sizeOrArray) {
/* istanbul ignore next */
return typeof sizeOrArray === "number"
? util.Buffer
? util._Buffer_allocUnsafe(sizeOrArray)
: new util.Array(sizeOrArray)
: util.Buffer
? util._Buffer_from(sizeOrArray)
: typeof Uint8Array === "undefined"
? sizeOrArray
: new Uint8Array(sizeOrArray);
};
/**
* Array implementation used in the browser. `Uint8Array` if supported, otherwise `Array`.
* @type {Constructor<Uint8Array>}
*/
util.Array = typeof Uint8Array !== "undefined" ? Uint8Array /* istanbul ignore next */ : Array;
/**
* Any compatible Long instance.
* This is a minimal stand-alone definition of a Long instance. The actual type is that exported by long.js.
* @interface Long
* @property {number} low Low bits
* @property {number} high High bits
* @property {boolean} unsigned Whether unsigned or not
*/
/**
* Long.js's Long class if available.
* @type {Constructor<Long>}
*/
util.Long = /* istanbul ignore next */ util.global.dcodeIO && /* istanbul ignore next */ util.global.dcodeIO.Long
|| /* istanbul ignore next */ util.global.Long
|| util.inquire("long");
/**
* Regular expression used to verify 2 bit (`bool`) map keys.
* @type {RegExp}
* @const
*/
util.key2Re = /^true|false|0|1$/;
/**
* Regular expression used to verify 32 bit (`int32` etc.) map keys.
* @type {RegExp}
* @const
*/
util.key32Re = /^-?(?:0|[1-9][0-9]*)$/;
/**
* Regular expression used to verify 64 bit (`int64` etc.) map keys.
* @type {RegExp}
* @const
*/
util.key64Re = /^(?:[\\x00-\\xff]{8}|-?(?:0|[1-9][0-9]*))$/;
/**
* Converts a number or long to an 8 characters long hash string.
* @param {Long|number} value Value to convert
* @returns {string} Hash
*/
util.longToHash = function longToHash(value) {
return value
? util.LongBits.from(value).toHash()
: util.LongBits.zeroHash;
};
/**
* Converts an 8 characters long hash string to a long or number.
* @param {string} hash Hash
* @param {boolean} [unsigned=false] Whether unsigned or not
* @returns {Long|number} Original value
*/
util.longFromHash = function longFromHash(hash, unsigned) {
var bits = util.LongBits.fromHash(hash);
if (util.Long)
return util.Long.fromBits(bits.lo, bits.hi, unsigned);
return bits.toNumber(Boolean(unsigned));
};
/**
* Merges the properties of the source object into the destination object.
* @memberof util
* @param {Object.<string,*>} dst Destination object
* @param {Object.<string,*>} src Source object
* @param {boolean} [ifNotSet=false] Merges only if the key is not already set
* @returns {Object.<string,*>} Destination object
*/
function merge(dst, src, ifNotSet) { // used by converters
for (var keys = Object.keys(src), i = 0; i < keys.length; ++i)
if (dst[keys[i]] === undefined || !ifNotSet)
dst[keys[i]] = src[keys[i]];
return dst;
}
util.merge = merge;
/**
* Converts the first character of a string to lower case.
* @param {string} str String to convert
* @returns {string} Converted string
*/
util.lcFirst = function lcFirst(str) {
return str.charAt(0).toLowerCase() + str.substring(1);
};
/**
* Creates a custom error constructor.
* @memberof util
* @param {string} name Error name
* @returns {Constructor<Error>} Custom error constructor
*/
function newError(name) {
function CustomError(message, properties) {
if (!(this instanceof CustomError))
return new CustomError(message, properties);
// Error.call(this, message);
// ^ just returns a new error instance because the ctor can be called as a function
Object.defineProperty(this, "message", { get: function() { return message; } });
/* istanbul ignore next */
if (Error.captureStackTrace) // node
Error.captureStackTrace(this, CustomError);
else
Object.defineProperty(this, "stack", { value: new Error().stack || "" });
if (properties)
merge(this, properties);
}
(CustomError.prototype = Object.create(Error.prototype)).constructor = CustomError;
Object.defineProperty(CustomError.prototype, "name", { get: function() { return name; } });
CustomError.prototype.toString = function toString() {
return this.name + ": " + this.message;
};
return CustomError;
}
util.newError = newError;
/**
* Constructs a new protocol error.
* @classdesc Error subclass indicating a protocol specifc error.
* @memberof util
* @extends Error
* @template T extends Message<T>
* @constructor
* @param {string} message Error message
* @param {Object.<string,*>} [properties] Additional properties
* @example
* try {
* MyMessage.decode(someBuffer); // throws if required fields are missing
* } catch (e) {
* if (e instanceof ProtocolError && e.instance)
* console.log("decoded so far: " + JSON.stringify(e.instance));
* }
*/
util.ProtocolError = newError("ProtocolError");
/**
* So far decoded message instance.
* @name util.ProtocolError#instance
* @type {Message<T>}
*/
/**
* A OneOf getter as returned by {@link util.oneOfGetter}.
* @typedef OneOfGetter
* @type {function}
* @returns {string|undefined} Set field name, if any
*/
/**
* Builds a getter for a oneof's present field name.
* @param {string[]} fieldNames Field names
* @returns {OneOfGetter} Unbound getter
*/
util.oneOfGetter = function getOneOf(fieldNames) {
var fieldMap = {};
for (var i = 0; i < fieldNames.length; ++i)
fieldMap[fieldNames[i]] = 1;
/**
* @returns {string|undefined} Set field name, if any
* @this Object
* @ignore
*/
return function() { // eslint-disable-line consistent-return
for (var keys = Object.keys(this), i = keys.length - 1; i > -1; --i)
if (fieldMap[keys[i]] === 1 && this[keys[i]] !== undefined && this[keys[i]] !== null)
return keys[i];
};
};
/**
* A OneOf setter as returned by {@link util.oneOfSetter}.
* @typedef OneOfSetter
* @type {function}
* @param {string|undefined} value Field name
* @returns {undefined}
*/
/**
* Builds a setter for a oneof's present field name.
* @param {string[]} fieldNames Field names
* @returns {OneOfSetter} Unbound setter
*/
util.oneOfSetter = function setOneOf(fieldNames) {
/**
* @param {string} name Field name
* @returns {undefined}
* @this Object
* @ignore
*/
return function(name) {
for (var i = 0; i < fieldNames.length; ++i)
if (fieldNames[i] !== name)
delete this[fieldNames[i]];
};
};
/**
* Default conversion options used for {@link Message#toJSON} implementations.
*
* These options are close to proto3's JSON mapping with the exception that internal types like Any are handled just like messages. More precisely:
*
* - Longs become strings
* - Enums become string keys
* - Bytes become base64 encoded strings
* - (Sub-)Messages become plain objects
* - Maps become plain objects with all string keys
* - Repeated fields become arrays
* - NaN and Infinity for float and double fields become strings
*
* @type {IConversionOptions}
* @see https://developers.google.com/protocol-buffers/docs/proto3?hl=en#json
*/
util.toJSONOptions = {
longs: String,
enums: String,
bytes: String,
json: true
};
// Sets up buffer utility according to the environment (called in index-minimal)
util._configure = function() {
var Buffer = util.Buffer;
/* istanbul ignore if */
if (!Buffer) {
util._Buffer_from = util._Buffer_allocUnsafe = null;
return;
}
// because node 4.x buffers are incompatible & immutable
// see: https://github.com/dcodeIO/protobuf.js/pull/665
util._Buffer_from = Buffer.from !== Uint8Array.from && Buffer.from ||
/* istanbul ignore next */
function Buffer_from(value, encoding) {
return new Buffer(value, encoding);
};
util._Buffer_allocUnsafe = Buffer.allocUnsafe ||
/* istanbul ignore next */
function Buffer_allocUnsafe(size) {
return new Buffer(size);
};
};
/***/ }),
/***/ "./node_modules/protobufjs/src/writer.js":
/*!***********************************************!*\
!*** ./node_modules/protobufjs/src/writer.js ***!
\***********************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
module.exports = Writer;
var util = __webpack_require__(/*! ./util/minimal */ "./node_modules/protobufjs/src/util/minimal.js");
var BufferWriter; // cyclic
var LongBits = util.LongBits,
base64 = util.base64,
utf8 = util.utf8;
/**
* Constructs a new writer operation instance.
* @classdesc Scheduled writer operation.
* @constructor
* @param {function(*, Uint8Array, number)} fn Function to call
* @param {number} len Value byte length
* @param {*} val Value to write
* @ignore
*/
function Op(fn, len, val) {
/**
* Function to call.
* @type {function(Uint8Array, number, *)}
*/
this.fn = fn;
/**
* Value byte length.
* @type {number}
*/
this.len = len;
/**
* Next operation.
* @type {Writer.Op|undefined}
*/
this.next = undefined;
/**
* Value to write.
* @type {*}
*/
this.val = val; // type varies
}
/* istanbul ignore next */
function noop() {} // eslint-disable-line no-empty-function
/**
* Constructs a new writer state instance.
* @classdesc Copied writer state.
* @memberof Writer
* @constructor
* @param {Writer} writer Writer to copy state from
* @ignore
*/
function State(writer) {
/**
* Current head.
* @type {Writer.Op}
*/
this.head = writer.head;
/**
* Current tail.
* @type {Writer.Op}
*/
this.tail = writer.tail;
/**
* Current buffer length.
* @type {number}
*/
this.len = writer.len;
/**
* Next state.
* @type {State|null}
*/
this.next = writer.states;
}
/**
* Constructs a new writer instance.
* @classdesc Wire format writer using `Uint8Array` if available, otherwise `Array`.
* @constructor
*/
function Writer() {
/**
* Current length.
* @type {number}
*/
this.len = 0;
/**
* Operations head.
* @type {Object}
*/
this.head = new Op(noop, 0, 0);
/**
* Operations tail
* @type {Object}
*/
this.tail = this.head;
/**
* Linked forked states.
* @type {Object|null}
*/
this.states = null;
// When a value is written, the writer calculates its byte length and puts it into a linked
// list of operations to perform when finish() is called. This both allows us to allocate
// buffers of the exact required size and reduces the amount of work we have to do compared
// to first calculating over objects and then encoding over objects. In our case, the encoding
// part is just a linked list walk calling operations with already prepared values.
}
var create = function create() {
return util.Buffer
? function create_buffer_setup() {
return (Writer.create = function create_buffer() {
return new BufferWriter();
})();
}
/* istanbul ignore next */
: function create_array() {
return new Writer();
};
};
/**
* Creates a new writer.
* @function
* @returns {BufferWriter|Writer} A {@link BufferWriter} when Buffers are supported, otherwise a {@link Writer}
*/
Writer.create = create();
/**
* Allocates a buffer of the specified size.
* @param {number} size Buffer size
* @returns {Uint8Array} Buffer
*/
Writer.alloc = function alloc(size) {
return new util.Array(size);
};
// Use Uint8Array buffer pool in the browser, just like node does with buffers
/* istanbul ignore else */
if (util.Array !== Array)
Writer.alloc = util.pool(Writer.alloc, util.Array.prototype.subarray);
/**
* Pushes a new operation to the queue.
* @param {function(Uint8Array, number, *)} fn Function to call
* @param {number} len Value byte length
* @param {number} val Value to write
* @returns {Writer} `this`
* @private
*/
Writer.prototype._push = function push(fn, len, val) {
this.tail = this.tail.next = new Op(fn, len, val);
this.len += len;
return this;
};
function writeByte(val, buf, pos) {
buf[pos] = val & 255;
}
function writeVarint32(val, buf, pos) {
while (val > 127) {
buf[pos++] = val & 127 | 128;
val >>>= 7;
}
buf[pos] = val;
}
/**
* Constructs a new varint writer operation instance.
* @classdesc Scheduled varint writer operation.
* @extends Op
* @constructor
* @param {number} len Value byte length
* @param {number} val Value to write
* @ignore
*/
function VarintOp(len, val) {
this.len = len;
this.next = undefined;
this.val = val;
}
VarintOp.prototype = Object.create(Op.prototype);
VarintOp.prototype.fn = writeVarint32;
/**
* Writes an unsigned 32 bit value as a varint.
* @param {number} value Value to write
* @returns {Writer} `this`
*/
Writer.prototype.uint32 = function write_uint32(value) {
// here, the call to this.push has been inlined and a varint specific Op subclass is used.
// uint32 is by far the most frequently used operation and benefits significantly from this.
this.len += (this.tail = this.tail.next = new VarintOp(
(value = value >>> 0)
< 128 ? 1
: value < 16384 ? 2
: value < 2097152 ? 3
: value < 268435456 ? 4
: 5,
value)).len;
return this;
};
/**
* Writes a signed 32 bit value as a varint.
* @function
* @param {number} value Value to write
* @returns {Writer} `this`
*/
Writer.prototype.int32 = function write_int32(value) {
return value < 0
? this._push(writeVarint64, 10, LongBits.fromNumber(value)) // 10 bytes per spec
: this.uint32(value);
};
/**
* Writes a 32 bit value as a varint, zig-zag encoded.
* @param {number} value Value to write
* @returns {Writer} `this`
*/
Writer.prototype.sint32 = function write_sint32(value) {
return this.uint32((value << 1 ^ value >> 31) >>> 0);
};
function writeVarint64(val, buf, pos) {
while (val.hi) {
buf[pos++] = val.lo & 127 | 128;
val.lo = (val.lo >>> 7 | val.hi << 25) >>> 0;
val.hi >>>= 7;
}
while (val.lo > 127) {
buf[pos++] = val.lo & 127 | 128;
val.lo = val.lo >>> 7;
}
buf[pos++] = val.lo;
}
/**
* Writes an unsigned 64 bit value as a varint.
* @param {Long|number|string} value Value to write
* @returns {Writer} `this`
* @throws {TypeError} If `value` is a string and no long library is present.
*/
Writer.prototype.uint64 = function write_uint64(value) {
var bits = LongBits.from(value);
return this._push(writeVarint64, bits.length(), bits);
};
/**
* Writes a signed 64 bit value as a varint.
* @function
* @param {Long|number|string} value Value to write
* @returns {Writer} `this`
* @throws {TypeError} If `value` is a string and no long library is present.
*/
Writer.prototype.int64 = Writer.prototype.uint64;
/**
* Writes a signed 64 bit value as a varint, zig-zag encoded.
* @param {Long|number|string} value Value to write
* @returns {Writer} `this`
* @throws {TypeError} If `value` is a string and no long library is present.
*/
Writer.prototype.sint64 = function write_sint64(value) {
var bits = LongBits.from(value).zzEncode();
return this._push(writeVarint64, bits.length(), bits);
};
/**
* Writes a boolish value as a varint.
* @param {boolean} value Value to write
* @returns {Writer} `this`
*/
Writer.prototype.bool = function write_bool(value) {
return this._push(writeByte, 1, value ? 1 : 0);
};
function writeFixed32(val, buf, pos) {
buf[pos ] = val & 255;
buf[pos + 1] = val >>> 8 & 255;
buf[pos + 2] = val >>> 16 & 255;
buf[pos + 3] = val >>> 24;
}
/**
* Writes an unsigned 32 bit value as fixed 32 bits.
* @param {number} value Value to write
* @returns {Writer} `this`
*/
Writer.prototype.fixed32 = function write_fixed32(value) {
return this._push(writeFixed32, 4, value >>> 0);
};
/**
* Writes a signed 32 bit value as fixed 32 bits.
* @function
* @param {number} value Value to write
* @returns {Writer} `this`
*/
Writer.prototype.sfixed32 = Writer.prototype.fixed32;
/**
* Writes an unsigned 64 bit value as fixed 64 bits.
* @param {Long|number|string} value Value to write
* @returns {Writer} `this`
* @throws {TypeError} If `value` is a string and no long library is present.
*/
Writer.prototype.fixed64 = function write_fixed64(value) {
var bits = LongBits.from(value);
return this._push(writeFixed32, 4, bits.lo)._push(writeFixed32, 4, bits.hi);
};
/**
* Writes a signed 64 bit value as fixed 64 bits.
* @function
* @param {Long|number|string} value Value to write
* @returns {Writer} `this`
* @throws {TypeError} If `value` is a string and no long library is present.
*/
Writer.prototype.sfixed64 = Writer.prototype.fixed64;
/**
* Writes a float (32 bit).
* @function
* @param {number} value Value to write
* @returns {Writer} `this`
*/
Writer.prototype.float = function write_float(value) {
return this._push(util.float.writeFloatLE, 4, value);
};
/**
* Writes a double (64 bit float).
* @function
* @param {number} value Value to write
* @returns {Writer} `this`
*/
Writer.prototype.double = function write_double(value) {
return this._push(util.float.writeDoubleLE, 8, value);
};
var writeBytes = util.Array.prototype.set
? function writeBytes_set(val, buf, pos) {
buf.set(val, pos); // also works for plain array values
}
/* istanbul ignore next */
: function writeBytes_for(val, buf, pos) {
for (var i = 0; i < val.length; ++i)
buf[pos + i] = val[i];
};
/**
* Writes a sequence of bytes.
* @param {Uint8Array|string} value Buffer or base64 encoded string to write
* @returns {Writer} `this`
*/
Writer.prototype.bytes = function write_bytes(value) {
var len = value.length >>> 0;
if (!len)
return this._push(writeByte, 1, 0);
if (util.isString(value)) {
var buf = Writer.alloc(len = base64.length(value));
base64.decode(value, buf, 0);
value = buf;
}
return this.uint32(len)._push(writeBytes, len, value);
};
/**
* Writes a string.
* @param {string} value Value to write
* @returns {Writer} `this`
*/
Writer.prototype.string = function write_string(value) {
var len = utf8.length(value);
return len
? this.uint32(len)._push(utf8.write, len, value)
: this._push(writeByte, 1, 0);
};
/**
* Forks this writer's state by pushing it to a stack.
* Calling {@link Writer#reset|reset} or {@link Writer#ldelim|ldelim} resets the writer to the previous state.
* @returns {Writer} `this`
*/
Writer.prototype.fork = function fork() {
this.states = new State(this);
this.head = this.tail = new Op(noop, 0, 0);
this.len = 0;
return this;
};
/**
* Resets this instance to the last state.
* @returns {Writer} `this`
*/
Writer.prototype.reset = function reset() {
if (this.states) {
this.head = this.states.head;
this.tail = this.states.tail;
this.len = this.states.len;
this.states = this.states.next;
} else {
this.head = this.tail = new Op(noop, 0, 0);
this.len = 0;
}
return this;
};
/**
* Resets to the last state and appends the fork state's current write length as a varint followed by its operations.
* @returns {Writer} `this`
*/
Writer.prototype.ldelim = function ldelim() {
var head = this.head,
tail = this.tail,
len = this.len;
this.reset().uint32(len);
if (len) {
this.tail.next = head.next; // skip noop
this.tail = tail;
this.len += len;
}
return this;
};
/**
* Finishes the write operation.
* @returns {Uint8Array} Finished buffer
*/
Writer.prototype.finish = function finish() {
var head = this.head.next, // skip noop
buf = this.constructor.alloc(this.len),
pos = 0;
while (head) {
head.fn(head.val, buf, pos);
pos += head.len;
head = head.next;
}
// this.head = this.tail = null;
return buf;
};
Writer._configure = function(BufferWriter_) {
BufferWriter = BufferWriter_;
Writer.create = create();
BufferWriter._configure();
};
/***/ }),
/***/ "./node_modules/protobufjs/src/writer_buffer.js":
/*!******************************************************!*\
!*** ./node_modules/protobufjs/src/writer_buffer.js ***!
\******************************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
module.exports = BufferWriter;
// extends Writer
var Writer = __webpack_require__(/*! ./writer */ "./node_modules/protobufjs/src/writer.js");
(BufferWriter.prototype = Object.create(Writer.prototype)).constructor = BufferWriter;
var util = __webpack_require__(/*! ./util/minimal */ "./node_modules/protobufjs/src/util/minimal.js");
/**
* Constructs a new buffer writer instance.
* @classdesc Wire format writer using node buffers.
* @extends Writer
* @constructor
*/
function BufferWriter() {
Writer.call(this);
}
BufferWriter._configure = function () {
/**
* Allocates a buffer of the specified size.
* @function
* @param {number} size Buffer size
* @returns {Buffer} Buffer
*/
BufferWriter.alloc = util._Buffer_allocUnsafe;
BufferWriter.writeBytesBuffer = util.Buffer && util.Buffer.prototype instanceof Uint8Array && util.Buffer.prototype.set.name === "set"
? function writeBytesBuffer_set(val, buf, pos) {
buf.set(val, pos); // faster than copy (requires node >= 4 where Buffers extend Uint8Array and set is properly inherited)
// also works for plain array values
}
/* istanbul ignore next */
: function writeBytesBuffer_copy(val, buf, pos) {
if (val.copy) // Buffer values
val.copy(buf, pos, 0, val.length);
else for (var i = 0; i < val.length;) // plain array values
buf[pos++] = val[i++];
};
};
/**
* @override
*/
BufferWriter.prototype.bytes = function write_bytes_buffer(value) {
if (util.isString(value))
value = util._Buffer_from(value, "base64");
var len = value.length >>> 0;
this.uint32(len);
if (len)
this._push(BufferWriter.writeBytesBuffer, len, value);
return this;
};
function writeStringBuffer(val, buf, pos) {
if (val.length < 40) // plain js is faster for short strings (probably due to redundant assertions)
util.utf8.write(val, buf, pos);
else if (buf.utf8Write)
buf.utf8Write(val, pos);
else
buf.write(val, pos);
}
/**
* @override
*/
BufferWriter.prototype.string = function write_string_buffer(value) {
var len = util.Buffer.byteLength(value);
this.uint32(len);
if (len)
this._push(writeStringBuffer, len, value);
return this;
};
/**
* Finishes the write operation.
* @name BufferWriter#finish
* @function
* @returns {Buffer} Finished buffer
*/
BufferWriter._configure();
/***/ }),
/***/ "./lib/backend-onnxjs.ts":
/*!*******************************!*\
!*** ./lib/backend-onnxjs.ts ***!
\*******************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.onnxjsBackend = void 0;
const session_1 = __webpack_require__(/*! ./onnxjs/session */ "./lib/onnxjs/session.ts");
const session_handler_1 = __webpack_require__(/*! ./onnxjs/session-handler */ "./lib/onnxjs/session-handler.ts");
class OnnxjsBackend {
// eslint-disable-next-line @typescript-eslint/no-empty-function
async init() { }
async createSessionHandler(pathOrBuffer, options) {
// NOTE: Session.Config(from onnx.js) is not compatible with InferenceSession.SessionOptions(from
// onnxruntime-common).
// In future we should remove Session.Config and use InferenceSession.SessionOptions.
// Currently we allow this to happen to make test runner work.
const session = new session_1.Session(options);
// typescript cannot merge method override correctly (so far in 4.2.3). need if-else to call the method.
if (typeof pathOrBuffer === 'string') {
await session.loadModel(pathOrBuffer);
}
else {
await session.loadModel(pathOrBuffer);
}
return new session_handler_1.OnnxjsSessionHandler(session);
}
}
exports.onnxjsBackend = new OnnxjsBackend();
/***/ }),
/***/ "./lib/backend-wasm.ts":
/*!*****************************!*\
!*** ./lib/backend-wasm.ts ***!
\*****************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.wasmBackend = exports.initializeFlags = void 0;
const onnxruntime_common_1 = __webpack_require__(/*! onnxruntime-common */ "onnxruntime-common");
const os_1 = __webpack_require__(/*! os */ "?0757");
const proxy_wrapper_1 = __webpack_require__(/*! ./wasm/proxy-wrapper */ "./lib/wasm/proxy-wrapper.ts");
const session_handler_1 = __webpack_require__(/*! ./wasm/session-handler */ "./lib/wasm/session-handler.ts");
/**
* This function initializes all flags for WebAssembly.
*
* Those flags are accessible from `ort.env.wasm`. Users are allow to set those flags before the first inference session
* being created, to override default value.
*/
const initializeFlags = () => {
if (typeof onnxruntime_common_1.env.wasm.initTimeout !== 'number' || onnxruntime_common_1.env.wasm.initTimeout < 0) {
onnxruntime_common_1.env.wasm.initTimeout = 0;
}
if (typeof onnxruntime_common_1.env.wasm.simd !== 'boolean') {
onnxruntime_common_1.env.wasm.simd = true;
}
if (typeof onnxruntime_common_1.env.wasm.proxy !== 'boolean') {
onnxruntime_common_1.env.wasm.proxy = false;
}
if (typeof onnxruntime_common_1.env.wasm.numThreads !== 'number' || !Number.isInteger(onnxruntime_common_1.env.wasm.numThreads) || onnxruntime_common_1.env.wasm.numThreads <= 0) {
const numCpuLogicalCores = typeof navigator === 'undefined' ? (0, os_1.cpus)().length : navigator.hardwareConcurrency;
onnxruntime_common_1.env.wasm.numThreads = Math.min(4, Math.ceil((numCpuLogicalCores || 1) / 2));
}
};
exports.initializeFlags = initializeFlags;
class OnnxruntimeWebAssemblyBackend {
async init() {
// populate wasm flags
(0, exports.initializeFlags)();
// init wasm
await (0, proxy_wrapper_1.initWasm)();
}
async createSessionHandler(pathOrBuffer, options) {
const handler = new session_handler_1.OnnxruntimeWebAssemblySessionHandler();
await handler.loadModel(pathOrBuffer, options);
return Promise.resolve(handler);
}
}
exports.wasmBackend = new OnnxruntimeWebAssemblyBackend();
/***/ }),
/***/ "./lib/index.ts":
/*!**********************!*\
!*** ./lib/index.ts ***!
\**********************/
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
/* eslint-disable @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports */
// We use "require" instead of "import" here because import statement must be put in top level. Our current code does
// not allow terser to tree-shaking code as expected because some codes are treated as having side effects.
// So we import code inside the if-clause to allow terser remove the code safely.
__exportStar(__webpack_require__(/*! onnxruntime-common */ "onnxruntime-common"), exports);
const onnxruntime_common_1 = __webpack_require__(/*! onnxruntime-common */ "onnxruntime-common");
if (true) {
const onnxjsBackend = (__webpack_require__(/*! ./backend-onnxjs */ "./lib/backend-onnxjs.ts").onnxjsBackend);
(0, onnxruntime_common_1.registerBackend)('webgl', onnxjsBackend, -10);
}
if (true) {
const wasmBackend = (__webpack_require__(/*! ./backend-wasm */ "./lib/backend-wasm.ts").wasmBackend);
(0, onnxruntime_common_1.registerBackend)('cpu', wasmBackend, 10);
(0, onnxruntime_common_1.registerBackend)('wasm', wasmBackend, 10);
(0, onnxruntime_common_1.registerBackend)('xnnpack', wasmBackend, 9);
}
/***/ }),
/***/ "./lib/onnxjs/attribute-with-cache-key.ts":
/*!************************************************!*\
!*** ./lib/onnxjs/attribute-with-cache-key.ts ***!
\************************************************/
/***/ ((__unused_webpack_module, exports) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.createAttributeWithCacheKey = void 0;
class AttributeWithCacheKeyImpl {
constructor(attribute) {
Object.assign(this, attribute);
}
get cacheKey() {
if (!this._cacheKey) {
this._cacheKey =
Object.getOwnPropertyNames(this).sort().map(name => `${this[name]}`).join(';');
}
return this._cacheKey;
}
}
const createAttributeWithCacheKey = (attribute) => new AttributeWithCacheKeyImpl(attribute);
exports.createAttributeWithCacheKey = createAttributeWithCacheKey;
/***/ }),
/***/ "./lib/onnxjs/attribute.ts":
/*!*********************************!*\
!*** ./lib/onnxjs/attribute.ts ***!
\*********************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.Attribute = void 0;
const onnx_proto_1 = __webpack_require__(/*! onnx-proto */ "./node_modules/onnx-proto/dist/onnx.js");
const ort_generated_1 = __webpack_require__(/*! ./ort-schema/ort-generated */ "./lib/onnxjs/ort-schema/ort-generated.ts");
const tensor_1 = __webpack_require__(/*! ./tensor */ "./lib/onnxjs/tensor.ts");
const util_1 = __webpack_require__(/*! ./util */ "./lib/onnxjs/util.ts");
var ortFbs = ort_generated_1.onnxruntime.experimental.fbs;
class Attribute {
constructor(attributes) {
this._attributes = new Map();
if (attributes !== null && attributes !== undefined) {
for (const attr of attributes) {
if (attr instanceof onnx_proto_1.onnx.AttributeProto) {
this._attributes.set(attr.name, [Attribute.getValue(attr), Attribute.getType(attr)]);
}
else if (attr instanceof ortFbs.Attribute) {
this._attributes.set(attr.name(), [Attribute.getValue(attr), Attribute.getType(attr)]);
}
}
if (this._attributes.size < attributes.length) {
throw new Error('duplicated attribute names');
}
}
}
set(key, type, value) {
this._attributes.set(key, [value, type]);
}
delete(key) {
this._attributes.delete(key);
}
getFloat(key, defaultValue) {
return this.get(key, 'float', defaultValue);
}
getInt(key, defaultValue) {
return this.get(key, 'int', defaultValue);
}
getString(key, defaultValue) {
return this.get(key, 'string', defaultValue);
}
getTensor(key, defaultValue) {
return this.get(key, 'tensor', defaultValue);
}
getFloats(key, defaultValue) {
return this.get(key, 'floats', defaultValue);
}
getInts(key, defaultValue) {
return this.get(key, 'ints', defaultValue);
}
getStrings(key, defaultValue) {
return this.get(key, 'strings', defaultValue);
}
getTensors(key, defaultValue) {
return this.get(key, 'tensors', defaultValue);
}
get(key, type, defaultValue) {
const valueAndType = this._attributes.get(key);
if (valueAndType === undefined) {
if (defaultValue !== undefined) {
return defaultValue;
}
throw new Error(`required attribute not found: ${key}`);
}
if (valueAndType[1] !== type) {
throw new Error(`type mismatch: expected ${type} but got ${valueAndType[1]}`);
}
return valueAndType[0];
}
static getType(attr) {
const type = attr instanceof onnx_proto_1.onnx.AttributeProto ? (attr).type : attr.type();
switch (type) {
case onnx_proto_1.onnx.AttributeProto.AttributeType.FLOAT:
return 'float';
case onnx_proto_1.onnx.AttributeProto.AttributeType.INT:
return 'int';
case onnx_proto_1.onnx.AttributeProto.AttributeType.STRING:
return 'string';
case onnx_proto_1.onnx.AttributeProto.AttributeType.TENSOR:
return 'tensor';
case onnx_proto_1.onnx.AttributeProto.AttributeType.FLOATS:
return 'floats';
case onnx_proto_1.onnx.AttributeProto.AttributeType.INTS:
return 'ints';
case onnx_proto_1.onnx.AttributeProto.AttributeType.STRINGS:
return 'strings';
case onnx_proto_1.onnx.AttributeProto.AttributeType.TENSORS:
return 'tensors';
default:
throw new Error(`attribute type is not supported yet: ${onnx_proto_1.onnx.AttributeProto.AttributeType[type]}`);
}
}
static getValue(attr) {
const attrType = attr instanceof onnx_proto_1.onnx.AttributeProto ? attr.type : attr.type();
if (attrType === onnx_proto_1.onnx.AttributeProto.AttributeType.GRAPH || attrType === onnx_proto_1.onnx.AttributeProto.AttributeType.GRAPHS) {
throw new Error('graph attribute is not supported yet');
}
const value = this.getValueNoCheck(attr);
// cast LONG to number
if (attrType === onnx_proto_1.onnx.AttributeProto.AttributeType.INT && util_1.LongUtil.isLong(value)) {
return util_1.LongUtil.longToNumber(value);
}
// cast LONG[] to number[]
if (attrType === onnx_proto_1.onnx.AttributeProto.AttributeType.INTS) {
const arr = value;
const numberValue = new Array(arr.length);
for (let i = 0; i < arr.length; i++) {
const maybeLong = arr[i];
numberValue[i] = util_1.LongUtil.longToNumber(maybeLong);
}
return numberValue;
}
// cast onnx.TensorProto to onnxjs.Tensor
if (attrType === onnx_proto_1.onnx.AttributeProto.AttributeType.TENSOR) {
return attr instanceof onnx_proto_1.onnx.AttributeProto ? tensor_1.Tensor.fromProto(value) :
tensor_1.Tensor.fromOrtTensor(value);
}
// cast onnx.TensorProto[] to onnxjs.Tensor[]
if (attrType === onnx_proto_1.onnx.AttributeProto.AttributeType.TENSORS) {
if (attr instanceof onnx_proto_1.onnx.AttributeProto) {
const tensorProtos = value;
return tensorProtos.map(value => tensor_1.Tensor.fromProto(value));
}
else if (attr instanceof ortFbs.Attribute) {
const tensorProtos = value;
return tensorProtos.map(value => tensor_1.Tensor.fromOrtTensor(value));
}
}
// cast Uint8Array to string
if (attrType === onnx_proto_1.onnx.AttributeProto.AttributeType.STRING) {
// string in onnx attribute is of uint8array type, so we need to convert it to string below. While in ort format,
// string attributes are returned as string, so no conversion is needed.
if (attr instanceof onnx_proto_1.onnx.AttributeProto) {
const utf8String = value;
return (0, util_1.decodeUtf8String)(utf8String);
}
}
// cast Uint8Array[] to string[]
if (attrType === onnx_proto_1.onnx.AttributeProto.AttributeType.STRINGS) {
// strings in onnx attribute is returned as uint8array[], so we need to convert it to string[] below. While in ort
// format strings attributes are returned as string[], so no conversion is needed.
if (attr instanceof onnx_proto_1.onnx.AttributeProto) {
const utf8Strings = value;
return utf8Strings.map(util_1.decodeUtf8String);
}
}
return value;
}
static getValueNoCheck(attr) {
return attr instanceof (onnx_proto_1.onnx.AttributeProto) ? this.getValueNoCheckFromOnnxFormat(attr) :
this.getValueNoCheckFromOrtFormat(attr);
}
static getValueNoCheckFromOnnxFormat(attr) {
switch (attr.type) {
case onnx_proto_1.onnx.AttributeProto.AttributeType.FLOAT:
return attr.f;
case onnx_proto_1.onnx.AttributeProto.AttributeType.INT:
return attr.i;
case onnx_proto_1.onnx.AttributeProto.AttributeType.STRING:
return attr.s;
case onnx_proto_1.onnx.AttributeProto.AttributeType.TENSOR:
return attr.t;
case onnx_proto_1.onnx.AttributeProto.AttributeType.GRAPH:
return attr.g;
case onnx_proto_1.onnx.AttributeProto.AttributeType.FLOATS:
return attr.floats;
case onnx_proto_1.onnx.AttributeProto.AttributeType.INTS:
return attr.ints;
case onnx_proto_1.onnx.AttributeProto.AttributeType.STRINGS:
return attr.strings;
case onnx_proto_1.onnx.AttributeProto.AttributeType.TENSORS:
return attr.tensors;
case onnx_proto_1.onnx.AttributeProto.AttributeType.GRAPHS:
return attr.graphs;
default:
throw new Error(`unsupported attribute type: ${onnx_proto_1.onnx.AttributeProto.AttributeType[attr.type]}`);
}
}
static getValueNoCheckFromOrtFormat(attr) {
switch (attr.type()) {
case ortFbs.AttributeType.FLOAT:
return attr.f();
case ortFbs.AttributeType.INT:
return attr.i();
case ortFbs.AttributeType.STRING:
return attr.s();
case ortFbs.AttributeType.TENSOR:
return attr.t();
case ortFbs.AttributeType.GRAPH:
return attr.g();
case ortFbs.AttributeType.FLOATS:
return attr.floatsArray();
case ortFbs.AttributeType.INTS: {
const ints = [];
for (let i = 0; i < attr.intsLength(); i++) {
ints.push(attr.ints(i));
}
return ints;
}
case ortFbs.AttributeType.STRINGS: {
const strings = [];
for (let i = 0; i < attr.stringsLength(); i++) {
strings.push(attr.strings(i));
}
return strings;
}
case ortFbs.AttributeType.TENSORS: {
const tensors = [];
for (let i = 0; i < attr.tensorsLength(); i++) {
tensors.push(attr.tensors(i));
}
return tensors;
}
// case ortFbs.AttributeType.GRAPHS:
// TODO: Subgraph not supported yet.
// const graphs = [];
// for (let i = 0; i < attr.graphsLength(); i++) {
// graphs.push(attr.graphs(i)!);
// }
// return graphs;
default:
throw new Error(`unsupported attribute type: ${ortFbs.AttributeType[attr.type()]}`);
}
}
}
exports.Attribute = Attribute;
/***/ }),
/***/ "./lib/onnxjs/backend.ts":
/*!*******************************!*\
!*** ./lib/onnxjs/backend.ts ***!
\*******************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.resolveBackend = exports.backend = void 0;
const backend_webgl_1 = __webpack_require__(/*! ./backends/backend-webgl */ "./lib/onnxjs/backends/backend-webgl.ts");
// caches all initialized backend instances
const backendsCache = new Map();
exports.backend = {
webgl: new backend_webgl_1.WebGLBackend(),
};
/**
* Resolve a reference to the backend. If a hint is specified, the corresponding
* backend will be used.
*/
async function resolveBackend(hint) {
if (!hint) {
return resolveBackend(['webgl']);
}
else {
const hints = typeof hint === 'string' ? [hint] : hint;
for (const backendHint of hints) {
const cache = backendsCache.get(backendHint);
if (cache) {
return cache;
}
const backend = await tryLoadBackend(backendHint);
if (backend) {
return backend;
}
}
}
throw new Error('no available backend to use');
}
exports.resolveBackend = resolveBackend;
async function tryLoadBackend(backendHint) {
const backendObj = exports.backend;
if (typeof backendObj[backendHint] !== 'undefined' && isBackend(backendObj[backendHint])) {
const backend = backendObj[backendHint];
let init = backend.initialize();
if (typeof init === 'object' && 'then' in init) {
init = await init;
}
if (init) {
backendsCache.set(backendHint, backend);
return backend;
}
}
return undefined;
}
function isBackend(obj) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const o = obj;
// check if an object is a Backend instance
if ('initialize' in o && typeof o.initialize === 'function' && // initialize()
'createSessionHandler' in o && typeof o.createSessionHandler === 'function' && // createSessionHandler()
'dispose' in o && typeof o.dispose === 'function' // dispose()
) {
return true;
}
return false;
}
/***/ }),
/***/ "./lib/onnxjs/backends/backend-webgl.ts":
/*!**********************************************!*\
!*** ./lib/onnxjs/backends/backend-webgl.ts ***!
\**********************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.WebGLBackend = void 0;
const onnxruntime_common_1 = __webpack_require__(/*! onnxruntime-common */ "onnxruntime-common");
const instrument_1 = __webpack_require__(/*! ../instrument */ "./lib/onnxjs/instrument.ts");
const session_handler_1 = __webpack_require__(/*! ./webgl/session-handler */ "./lib/onnxjs/backends/webgl/session-handler.ts");
const webgl_context_factory_1 = __webpack_require__(/*! ./webgl/webgl-context-factory */ "./lib/onnxjs/backends/webgl/webgl-context-factory.ts");
/**
* WebGLBackend is the entry point for all WebGL opeartions
* When it starts it created the WebGLRenderingContext
* and other main framework components such as Program and Texture Managers
*/
class WebGLBackend {
get contextId() {
return onnxruntime_common_1.env.webgl.contextId;
}
set contextId(value) {
onnxruntime_common_1.env.webgl.contextId = value;
}
get matmulMaxBatchSize() {
return onnxruntime_common_1.env.webgl.matmulMaxBatchSize;
}
set matmulMaxBatchSize(value) {
onnxruntime_common_1.env.webgl.matmulMaxBatchSize = value;
}
get textureCacheMode() {
return onnxruntime_common_1.env.webgl.textureCacheMode;
}
set textureCacheMode(value) {
onnxruntime_common_1.env.webgl.textureCacheMode = value;
}
get pack() {
return onnxruntime_common_1.env.webgl.pack;
}
set pack(value) {
onnxruntime_common_1.env.webgl.pack = value;
}
get async() {
return onnxruntime_common_1.env.webgl.async;
}
set async(value) {
onnxruntime_common_1.env.webgl.async = value;
}
initialize() {
try {
this.glContext = (0, webgl_context_factory_1.createWebGLContext)(this.contextId);
if (typeof this.matmulMaxBatchSize !== 'number') {
this.matmulMaxBatchSize = 16;
}
if (typeof this.textureCacheMode !== 'string') {
this.textureCacheMode = 'full';
}
if (typeof this.pack !== 'boolean') {
this.pack = false;
}
if (typeof this.async !== 'boolean') {
this.async = false;
}
instrument_1.Logger.setWithEnv(onnxruntime_common_1.env);
instrument_1.Logger.verbose('WebGLBackend', `Created WebGLContext: ${typeof this.glContext} with matmulMaxBatchSize: ${this.matmulMaxBatchSize}; textureCacheMode: ${this.textureCacheMode}; pack: ${this.pack}; async: ${this.async}.`);
return true;
}
catch (e) {
instrument_1.Logger.warning('WebGLBackend', `Unable to initialize WebGLBackend. ${e}`);
return false;
}
}
createSessionHandler(context) {
return new session_handler_1.WebGLSessionHandler(this, context);
}
dispose() {
this.glContext.dispose();
}
}
exports.WebGLBackend = WebGLBackend;
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/glsl-coordinate-lib.ts":
/*!**********************************************************!*\
!*** ./lib/onnxjs/backends/webgl/glsl-coordinate-lib.ts ***!
\**********************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.CoordsGlslLib = void 0;
const util_1 = __webpack_require__(/*! ../../util */ "./lib/onnxjs/util.ts");
const glsl_definitions_1 = __webpack_require__(/*! ./glsl-definitions */ "./lib/onnxjs/backends/webgl/glsl-definitions.ts");
const glsl_source_1 = __webpack_require__(/*! ./glsl-source */ "./lib/onnxjs/backends/webgl/glsl-source.ts");
const texture_layout_strategy_1 = __webpack_require__(/*! ./texture-layout-strategy */ "./lib/onnxjs/backends/webgl/texture-layout-strategy.ts");
const utils_1 = __webpack_require__(/*! ./utils */ "./lib/onnxjs/backends/webgl/utils.ts");
/**
* GLSL Library responsible for data types and routines for manipulating
* coordinates and mapping to/from tensor indices
*/
class CoordsGlslLib extends glsl_definitions_1.GlslLib {
constructor(context) {
super(context);
}
getFunctions() {
return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, this.offsetToCoords()), this.coordsToOffset()), this.toVec()), this.valueFrom()), this.getCommonUtilFuncs()), this.getInputsSamplingSnippets()), this.getOutputSamplingSnippet());
}
getCustomTypes() {
return {};
}
/**
* Produces a function that can map from
* 2D normalzied coordinates (s,t) to a flat offset
*/
offsetToCoords() {
const funcName = 'offsetToCoords';
return {
offsetToCoords: new glsl_definitions_1.GlslLibRoutine(`
vec2 ${funcName}(int offset, int width, int height) {
int t = offset / width;
int s = offset - t*width;
vec2 coords = (vec2(s,t) + vec2(0.5,0.5)) / vec2(width, height);
return coords;
}
`)
};
}
/**
* Produces a function that can map from
* 2D normalzied coordinates (s,t) to a flat offset
*/
coordsToOffset() {
const funcName = 'coordsToOffset';
return {
coordsToOffset: new glsl_definitions_1.GlslLibRoutine(`
int ${funcName}(vec2 coords, int width, int height) {
float s = coords.s * float(width);
float t = coords.t * float(height);
int offset = int(t) * width + int(s);
return offset;
}
`)
};
}
/**
* Generates code for output sampler.
*/
getOutputSamplingSnippet() {
const outputLayout = this.context.outputTextureLayout;
if (outputLayout.isPacked) {
return this.getPackedOutputSamplingSnippet(outputLayout);
}
else {
return this.getUnpackedOutputSamplingSnippet(outputLayout);
}
}
/**
* Generates code for packed output sampler.
*/
getPackedOutputSamplingSnippet(outputLayout) {
const outShape = outputLayout.unpackedShape;
const outTexShape = [outputLayout.width, outputLayout.height];
const result = {};
const funcName = 'getOutputCoords';
switch (outShape.length) {
case 0:
result[funcName] = this.getOutputScalarCoords();
break;
case 1:
result[funcName] = this.getOutputPacked1DCoords(outShape, outTexShape);
break;
case 2:
result[funcName] = this.getOutputPacked2DCoords(outShape, outTexShape);
break;
case 3:
result[funcName] =
this.getOutputPacked3DCoords(outShape, outTexShape);
break;
default:
result[funcName] = this.getOutputPackedNDCoords(outShape, outTexShape);
}
const glsl = (0, glsl_source_1.getGlsl)(this.context.glContext.version);
// TODO we need this to properly return a packed vec4 from kernels.
// Replace all '{glsl.output} = result' with 'setOutput(result)' in all kernels.
const floatTextureSetRGBASource = `
void setOutput(vec4 val) {
${glsl.output} = val;
}
`;
const floatTextureSetRGBAFuncName = 'floatTextureSetRGBA';
result[floatTextureSetRGBAFuncName] = new glsl_definitions_1.GlslLibRoutine(floatTextureSetRGBASource);
return result;
}
/**
* Generates code for unpacked output sampler.
*/
getUnpackedOutputSamplingSnippet(outputLayout) {
const outShape = outputLayout.unpackedShape;
const outTexShape = [outputLayout.width, outputLayout.height];
const result = {};
const funcName = 'getOutputCoords';
switch (outShape.length) {
case 0:
result[funcName] = this.getOutputScalarCoords();
break;
case 1:
result[funcName] = this.getOutputUnpacked1DCoords(outShape, outTexShape);
break;
case 2:
result[funcName] =
this.getOutputUnpacked2DCoords(outShape, outTexShape);
break;
case 3:
result[funcName] =
this.getOutputUnpacked3DCoords(outShape, outTexShape);
break;
case 4:
result[funcName] = this.getOutputUnpacked4DCoords(outShape, outTexShape);
break;
case 5:
result[funcName] = this.getOutputUnpacked5DCoords(outShape, outTexShape);
break;
case 6:
result[funcName] = this.getOutputUnpacked6DCoords(outShape, outTexShape);
break;
default:
throw new Error(`Unsupported output dimensionality: ${outShape.length}`);
}
const glsl = (0, glsl_source_1.getGlsl)(this.context.glContext.version);
// TODO we need this to properly return a packed vec4 from kernels.
// Replace all '{glsl.output} = result' with 'setOutput(result)' in all kernels.
const floatTextureSetRSource = `
void setOutput(float val) {
${glsl.output} = vec4(val, 0, 0, 0);
}
`;
const floatTextureSetRFuncName = 'floatTextureSetR';
result[floatTextureSetRFuncName] = new glsl_definitions_1.GlslLibRoutine(floatTextureSetRSource);
return result;
}
/**
* Scalar output coordinates.
*/
getOutputScalarCoords() {
return new glsl_definitions_1.GlslLibRoutine(`
int getOutputCoords() {
return 0;
}
`);
}
/**
* 1D packed output coordinates.
*/
getOutputPacked1DCoords(shape, texShape) {
const packedTexShape = texShape;
let source = '';
if (packedTexShape[0] === 1) {
source = `
int getOutputCoords() {
return 2 * int(TexCoords.y * ${packedTexShape[1]}.0);
}
`;
return new glsl_definitions_1.GlslLibRoutine(source);
}
if (packedTexShape[1] === 1) {
source = `
int getOutputCoords() {
return 2 * int(TexCoords.x * ${packedTexShape[0]}.0);
}
`;
return new glsl_definitions_1.GlslLibRoutine(source);
}
source = `
int getOutputCoords() {
ivec2 resTexRC = ivec2(TexCoords.xy *
vec2(${packedTexShape[0]}, ${packedTexShape[1]}));
return 2 * (resTexRC.y * ${packedTexShape[0]} + resTexRC.x);
}
`;
return new glsl_definitions_1.GlslLibRoutine(source);
}
/**
* 2D packed output coordinates.
*/
getOutputPacked2DCoords(shape, texShape) {
let source = '';
if (util_1.ArrayUtil.arraysEqual(shape, texShape)) {
source = `
ivec2 getOutputCoords() {
return 2 * ivec2(TexCoords.xy * vec2(${texShape[0]}, ${texShape[1]}));
}
`;
return new glsl_definitions_1.GlslLibRoutine(source);
}
const packedTexShape = texShape;
// texels needed to accommodate a logical row
const texelsInLogicalRow = Math.ceil(shape[1] / 2);
/**
* getOutputCoords
*
* resTexRC: The rows and columns of the texels. If you move over one
* texel to the right in the packed texture, you are moving over one column
* (not two).
*
* index: The texel index
*/
source = `
ivec2 getOutputCoords() {
ivec2 resTexRC = ivec2(TexCoords.xy *
vec2(${packedTexShape[0]}, ${packedTexShape[1]}));
int index = resTexRC.y * ${packedTexShape[0]} + resTexRC.x;
// reverse r and c order for packed texture
int r = imod(index, ${texelsInLogicalRow}) * 2;
int c = 2 * (index / ${texelsInLogicalRow});
return ivec2(r, c);
}
`;
return new glsl_definitions_1.GlslLibRoutine(source);
}
/**
* 3D packed output coordinates.
*/
getOutputPacked3DCoords(shape, texShape) {
const packedTexShape = [texShape[0], texShape[1]];
const texelsInLogicalRow = Math.ceil(shape[2] / 2);
const texelsInBatch = texelsInLogicalRow * Math.ceil(shape[1] / 2);
const source = `
ivec3 getOutputCoords() {
ivec2 resTexRC = ivec2(TexCoords.xy *
vec2(${packedTexShape[0]}, ${packedTexShape[1]}));
int index = resTexRC.y * ${packedTexShape[0]} + resTexRC.x;
int b = index / ${texelsInBatch};
index -= b * ${texelsInBatch};
// reverse r and c order for packed texture
int r = imod(index, ${texelsInLogicalRow}) * 2;
int c = 2 * (index / ${texelsInLogicalRow});
return ivec3(b, r, c);
}
`;
return new glsl_definitions_1.GlslLibRoutine(source);
}
/**
* ND packed output coordinates.
*/
getOutputPackedNDCoords(shape, texShape) {
const packedTexShape = [texShape[0], texShape[1]];
const texelsInLogicalRow = Math.ceil(shape[shape.length - 1] / 2);
const texelsInBatch = texelsInLogicalRow * Math.ceil(shape[shape.length - 2] / 2);
let texelsInBatchN = texelsInBatch;
let batches = '';
let coords = 'b, r, c';
for (let b = 2; b < shape.length - 1; b++) {
texelsInBatchN *= shape[shape.length - b - 1];
batches = `
int b${b} = index / ${texelsInBatchN};
index -= b${b} * ${texelsInBatchN};
` + batches;
coords = `b${b}, ` + coords;
}
const source = `
ivec${shape.length} getOutputCoords() {
ivec2 resTexRC = ivec2(TexCoords.xy *
vec2(${packedTexShape[0]}, ${packedTexShape[1]}));
int index = resTexRC.y * ${packedTexShape[0]} + resTexRC.x;
${batches}
int b = index / ${texelsInBatch};
index -= b * ${texelsInBatch};
// reverse r and c order for packed texture
int r = imod(index, ${texelsInLogicalRow}) * 2;
int c = 2 * (index / ${texelsInLogicalRow});
return ivec${shape.length}(${coords});
}
`;
return new glsl_definitions_1.GlslLibRoutine(source);
}
/**
* Unpacked 1D output coordinates.
*/
getOutputUnpacked1DCoords(shape, texShape) {
const source = `
int getOutputCoords() {
ivec2 resTexRC = ivec2(TexCoords.xy *
vec2(${texShape[0]}, ${texShape[1]}));
return resTexRC.y * ${texShape[0]} + resTexRC.x;
}
`;
return new glsl_definitions_1.GlslLibRoutine(source);
}
/**
* Unpacked 2D output coordinates.
*/
getOutputUnpacked2DCoords(shape, texShape) {
const source = `
ivec2 getOutputCoords() {
ivec2 resTexRC = ivec2(TexCoords.xy *
vec2(${texShape[0]}, ${texShape[1]}));
int index = resTexRC.y * ${texShape[0]} + resTexRC.x;
int r = index / ${shape[1]};
int c = index - r * ${shape[1]};
return ivec2(r, c);
}
`;
return new glsl_definitions_1.GlslLibRoutine(source);
}
/**
* Unpacked 3D output coordinates.
*/
getOutputUnpacked3DCoords(shape, texShape) {
let source = '';
const rank = shape.length;
let strides = null;
if (rank < 2) {
strides = [];
}
strides = new Array(rank - 1);
strides[rank - 2] = shape[rank - 1];
for (let i = rank - 3; i >= 0; --i) {
strides[i] = strides[i + 1] * shape[i + 1];
}
const coordsToCompute = ['r', 'c', 'd'];
const coordsFromIndexSnippet = strides
.map((stride, i) => {
const line1 = `int ${coordsToCompute[i]} = index / ${stride}`;
const line2 = i === strides.length - 1 ?
`int ${coordsToCompute[i + 1]} = index - ${coordsToCompute[i]} * ${stride}` :
`index -= ${coordsToCompute[i]} * ${stride}`;
return `${line1}; ${line2};`;
})
.join('');
source = `
ivec3 getOutputCoords() {
ivec2 resTexRC = ivec2(TexCoords.xy *
vec2(${texShape[0]}, ${texShape[1]}));
int index = resTexRC.y * ${texShape[0]} + resTexRC.x;
${coordsFromIndexSnippet}
return ivec3(r, c, d);
}
`;
return new glsl_definitions_1.GlslLibRoutine(source);
}
/**
* Unpacked 4D output coordinates.
*/
getOutputUnpacked4DCoords(shape, texShape) {
let source = '';
const rank = shape.length;
let strides = null;
if (rank < 2) {
strides = [];
}
strides = new Array(rank - 1);
strides[rank - 2] = shape[rank - 1];
for (let i = rank - 3; i >= 0; --i) {
strides[i] = strides[i + 1] * shape[i + 1];
}
const coordsToCompute = ['r', 'c', 'd', 'd2'];
const coordsFromIndexSnippet = strides
.map((stride, i) => {
const line1 = `int ${coordsToCompute[i]} = index / ${stride}`;
const line2 = i === strides.length - 1 ?
`int ${coordsToCompute[i + 1]} = index - ${coordsToCompute[i]} * ${stride}` :
`index -= ${coordsToCompute[i]} * ${stride}`;
return `${line1}; ${line2};`;
})
.join('');
source = `
ivec4 getOutputCoords() {
ivec2 resTexRC = ivec2(TexCoords.xy *
vec2(${texShape[0]}, ${texShape[1]}));
int index = resTexRC.y * ${texShape[0]} + resTexRC.x;
${coordsFromIndexSnippet}
return ivec4(r, c, d, d2);
}
`;
return new glsl_definitions_1.GlslLibRoutine(source);
}
/**
* Unpacked 5D output coordinates.
*/
getOutputUnpacked5DCoords(shape, texShape) {
let source = '';
const rank = shape.length;
let strides = null;
if (rank < 2) {
strides = [];
}
strides = new Array(rank - 1);
strides[rank - 2] = shape[rank - 1];
for (let i = rank - 3; i >= 0; --i) {
strides[i] = strides[i + 1] * shape[i + 1];
}
const coordsToCompute = ['r', 'c', 'd', 'd2', 'd3'];
const coordsFromIndexSnippet = strides
.map((stride, i) => {
const line1 = `int ${coordsToCompute[i]} = index / ${stride}`;
const line2 = i === strides.length - 1 ?
`int ${coordsToCompute[i + 1]} = index - ${coordsToCompute[i]} * ${stride}` :
`index -= ${coordsToCompute[i]} * ${stride}`;
return `${line1}; ${line2};`;
})
.join('');
source = `
ivec5 getOutputCoords() {
ivec2 resTexRC = ivec2(TexCoords.xy *
vec2(${texShape[0]}, ${texShape[1]}));
int index = resTexRC.y * ${texShape[0]} + resTexRC.x;
${coordsFromIndexSnippet}
return ivec5(r, c, d, d2, d3);
}
`;
return new glsl_definitions_1.GlslLibRoutine(source);
}
/**
* Unpacked 6D output coordinates.
*/
getOutputUnpacked6DCoords(shape, texShape) {
let source = '';
const rank = shape.length;
let strides = null;
if (rank < 2) {
strides = [];
}
strides = new Array(rank - 1);
strides[rank - 2] = shape[rank - 1];
for (let i = rank - 3; i >= 0; --i) {
strides[i] = strides[i + 1] * shape[i + 1];
}
const coordsToCompute = ['r', 'c', 'd', 'd2', 'd3', 'd4'];
const coordsFromIndexSnippet = strides
.map((stride, i) => {
const line1 = `int ${coordsToCompute[i]} = index / ${stride}`;
const line2 = i === strides.length - 1 ?
`int ${coordsToCompute[i + 1]} = index - ${coordsToCompute[i]} * ${stride}` :
`index -= ${coordsToCompute[i]} * ${stride}`;
return `${line1}; ${line2};`;
})
.join('');
source = `
ivec6 getOutputCoords() {
ivec2 resTexRC = ivec2(TexCoords.xy *
vec2(${texShape[0]}, ${texShape[1]}));
int index = resTexRC.y * ${texShape[0]} + resTexRC.x;
${coordsFromIndexSnippet}
return ivec6(r, c, d, d2, d3, d4);
}
`;
return new glsl_definitions_1.GlslLibRoutine(source);
}
/**
* Generates code for common UV coords computation utility functions.
*/
getCommonUtilFuncs() {
const result = {};
let funcName = 'uvFromFlat';
result[funcName] = new glsl_definitions_1.GlslLibRoutine(`
vec2 uvFromFlat(int texNumR, int texNumC, int index) {
int texC = index / texNumR;
int texR = index - texC * texNumR;
// TODO: swap texR, texC order in following function so row is corresponding to u and column is corresponding to
// v.
return (vec2(texR, texC) + halfCR) / vec2(texNumR, texNumC);
}
`);
funcName = 'packedUVfrom1D';
result[funcName] = new glsl_definitions_1.GlslLibRoutine(`
vec2 packedUVfrom1D(int texNumR, int texNumC, int index) {
int texelIndex = index / 2;
int texR = texelIndex / texNumC;
int texC = texelIndex - texR * texNumC;
return (vec2(texC, texR) + halfCR) / vec2(texNumC, texNumR);
}
`);
funcName = 'packedUVfrom2D';
result[funcName] = new glsl_definitions_1.GlslLibRoutine(`
vec2 packedUVfrom2D(int texNumR, int texNumC, int texelsInLogicalRow, int row, int col) {
int texelIndex = (row / 2) * texelsInLogicalRow + (col / 2);
int texR = texelIndex / texNumC;
int texC = texelIndex - texR * texNumC;
return (vec2(texC, texR) + halfCR) / vec2(texNumC, texNumR);
}
`);
funcName = 'packedUVfrom3D';
result[funcName] = new glsl_definitions_1.GlslLibRoutine(`
vec2 packedUVfrom3D(int texNumR, int texNumC,
int texelsInBatch, int texelsInLogicalRow, int b,
int row, int col) {
int index = b * texelsInBatch + (row / 2) * texelsInLogicalRow + (col / 2);
int texR = index / texNumC;
int texC = index - texR * texNumC;
return (vec2(texC, texR) + halfCR) / vec2(texNumC, texNumR);
}
`);
funcName = 'sampleTexture';
const glsl = (0, glsl_source_1.getGlsl)(this.context.glContext.version);
result[funcName] = new glsl_definitions_1.GlslLibRoutine(`
float sampleTexture(sampler2D textureSampler, vec2 uv) {
return ${glsl.texture2D}(textureSampler, uv).r;
}`);
return result;
}
/**
* Constructing snippets for inputs
*/
getInputsSamplingSnippets() {
const result = {};
const outputLayout = this.context.outputTextureLayout;
this.context.programInfo.inputNames.forEach((samplerName, i) => {
const inputLayout = this.context.inputTextureLayouts[i];
const funcName = (0, utils_1.generateShaderFuncNameFromInputSamplerName)(samplerName);
if (inputLayout.isPacked) {
result[funcName] = this.getPackedSamplerFromInput(funcName, samplerName, inputLayout);
}
else {
result[funcName] = this.getUnpackedSamplerFromInput(funcName, samplerName, inputLayout);
}
const outCoordFuncName = (0, utils_1.generateShaderFuncNameFromInputSamplerNameAtOutCoords)(samplerName);
if (inputLayout.unpackedShape.length <= outputLayout.unpackedShape.length) {
if (inputLayout.isPacked) {
result[outCoordFuncName] =
this.getPackedSamplerAtOutputCoords(outCoordFuncName, inputLayout, outputLayout, samplerName);
}
else {
result[outCoordFuncName] =
this.getUnpackedSamplerAtOutputCoords(outCoordFuncName, inputLayout, outputLayout, samplerName);
}
}
});
return result;
}
/**
* Constructing snippets for output coordinates of samplers
*/
getPackedSamplerAtOutputCoords(funcName, inputLayout, outputLayout, name) {
const inShape = inputLayout.unpackedShape;
const outShape = outputLayout.unpackedShape;
const texName = name;
const texFuncSnippet = (0, utils_1.generateShaderFuncNameFromInputSamplerName)(texName);
const inRank = inShape.length;
const outRank = outShape.length;
const broadcastDims = util_1.BroadcastUtil.getBroadcastDims(inShape, outShape);
const type = (0, utils_1.getCoordsDataType)(outRank);
const rankDiff = outRank - inRank;
let coordsSnippet;
const fields = (0, utils_1.getGlChannels)();
if (inRank === 0) {
coordsSnippet = '';
}
else if (outRank < 2 && broadcastDims.length >= 1) {
coordsSnippet = 'coords = 0;';
}
else {
coordsSnippet = broadcastDims.map(d => `coords.${fields[d + rankDiff]} = 0;`).join('\n');
}
let unpackedCoordsSnippet = '';
if (outRank < 2 && inRank > 0) {
unpackedCoordsSnippet = 'coords';
}
else {
unpackedCoordsSnippet = inShape.map((s, i) => `coords.${fields[i + rankDiff]}`).join(', ');
}
let output = 'return outputValue;';
const inSize = util_1.ShapeUtil.size(inShape);
const isInputScalar = inSize === 1;
const outSize = util_1.ShapeUtil.size(outShape);
const isOutputScalar = outSize === 1;
if (inRank === 1 && !isInputScalar && !isOutputScalar) {
output = `
return vec4(outputValue.xy, outputValue.xy);
`;
}
else if (isInputScalar && !isOutputScalar) {
if (outRank === 1) {
output = `
return vec4(outputValue.x, outputValue.x, 0., 0.);
`;
}
else {
output = `
return vec4(outputValue.x);
`;
}
}
else if (broadcastDims.length) {
const rows = inRank - 2;
const cols = inRank - 1;
if (broadcastDims.indexOf(rows) > -1 && broadcastDims.indexOf(cols) > -1) {
output = 'return vec4(outputValue.x);';
}
else if (broadcastDims.indexOf(rows) > -1) {
output = 'return vec4(outputValue.x, outputValue.y, ' +
'outputValue.x, outputValue.y);';
}
else if (broadcastDims.indexOf(cols) > -1) {
output = 'return vec4(outputValue.xx, outputValue.zz);';
}
}
const swapLastDimsSnippet = `
int lastDim = coords.${fields[outRank - 1]};
coords.${fields[outRank - 1]} = coords.${fields[outRank - 2]};
coords.${fields[outRank - 2]} = lastDim;
`;
const source = `
vec4 ${funcName}() {
${type} coords = getOutputCoords();
${swapLastDimsSnippet}
${coordsSnippet}
vec4 outputValue = ${texFuncSnippet}(${unpackedCoordsSnippet});
${output}
}
`;
return new glsl_definitions_1.GlslLibRoutine(source, ['coordinates.getOutputCoords']);
}
/**
* Constructing snippets for unpacked output coordinates of samplers
*/
getUnpackedSamplerAtOutputCoords(funcName, inputLayout, outputLayout, name) {
const outTexShape = [outputLayout.width, outputLayout.height];
const inTexShape = [inputLayout.width, inputLayout.height];
const inRank = inputLayout.unpackedShape.length;
const outRank = outputLayout.unpackedShape.length;
const inShape = inputLayout.unpackedShape;
const outShape = outputLayout.unpackedShape;
const texFuncSnippet = (0, utils_1.generateShaderFuncNameFromInputSamplerName)(name);
if (inRank === outRank && util_1.ArrayUtil.arraysEqual(inTexShape, outTexShape)) {
const source = `
float ${funcName}() {
return sampleTexture(${name}, TexCoords);
}
`;
return new glsl_definitions_1.GlslLibRoutine(source, ['coordinates.sampleTexture']);
}
const type = (0, utils_1.getCoordsDataType)(outRank);
const broadcastDims = util_1.BroadcastUtil.getBroadcastDims(inShape, outShape);
const rankDiff = outRank - inRank;
let coordsSnippet;
const fields = (0, utils_1.getGlChannels)();
if (inRank === 0) {
coordsSnippet = '';
}
else if (outRank < 2 && broadcastDims.length >= 1) {
coordsSnippet = 'coords = 0;';
}
else {
coordsSnippet = broadcastDims.map(d => `coords.${fields[d + rankDiff]} = 0;`).join('\n');
}
let unpackedCoordsSnippet = '';
if (outRank < 2 && inRank > 0) {
unpackedCoordsSnippet = 'coords';
}
else {
unpackedCoordsSnippet = inputLayout.unpackedShape.map((s, i) => `coords.${fields[i + rankDiff]}`).join(', ');
}
const source = `
float ${funcName}() {
${type} coords = getOutputCoords();
${coordsSnippet}
return ${texFuncSnippet}(${unpackedCoordsSnippet});
}
`;
return new glsl_definitions_1.GlslLibRoutine(source, ['coordinates.getOutputCoords']);
}
/**
* Constructing snippets for packed operations.
*/
getPackedSamplerFromInput(funcName, name, inputLayout) {
switch (inputLayout.unpackedShape.length) {
case 0:
return this.getPackedSamplerScalar(funcName, name);
case 1:
return this.getPackedSampler1D(funcName, name, inputLayout);
case 2:
return this.getPackedSampler2D(funcName, name, inputLayout);
case 3:
return this.getPackedSampler3D(funcName, name, inputLayout);
default:
return this.getPackedSamplerND(funcName, name, inputLayout);
}
}
/**
* Constructing snippets for unpacked operations.
*/
getUnpackedSamplerFromInput(funcName, name, inputLayout) {
const shape = inputLayout.unpackedShape;
switch (shape.length) {
case 0:
return this.getUnpackedSamplerScalar(funcName, name, inputLayout);
case 1:
return this.getUnpackedSampler1D(funcName, name, inputLayout);
case 2:
return this.getUnpackedSampler2D(funcName, name, inputLayout);
case 3:
return this.getUnpackedSampler3D(funcName, name, inputLayout);
case 4:
return this.getUnpackedSampler4D(funcName, name, inputLayout);
case 5:
return this.getUnpackedSampler5D(funcName, name, inputLayout);
case 6:
return this.getUnpackedSampler6D(funcName, name, inputLayout);
default:
// TODO support more dimensionalities
throw new Error(`Unsupported dimension ${shape.length}-D`);
}
}
/**
* Packed scalar snippet.
*/
getPackedSamplerScalar(funcName, name) {
const glsl = (0, glsl_source_1.getGlsl)(this.context.glContext.version);
const source = `
vec4 ${funcName}() {
return ${glsl.texture2D}(${name}, halfCR);
}
`;
return new glsl_definitions_1.GlslLibRoutine(source);
}
/**
* Packed 1D snippet.
*/
getPackedSampler1D(funcName, name, inputLayout) {
const texShape = [inputLayout.width, inputLayout.height];
const packedTexShape = [texShape[1], texShape[0]];
const glsl = (0, glsl_source_1.getGlsl)(this.context.glContext.version);
const packedSampler = `vec4 ${funcName}(int index) {
vec2 uv = packedUVfrom1D(
${packedTexShape[0]}, ${packedTexShape[1]}, index);
return ${glsl.texture2D}(${name}, uv);
}`;
const source = packedSampler;
return new glsl_definitions_1.GlslLibRoutine(source, ['coordinates.packedUVfrom1D']);
}
/**
* Packed 2D snippet.
*/
getPackedSampler2D(funcName, name, inputLayout) {
const shape = inputLayout.unpackedShape;
const texShape = [inputLayout.width, inputLayout.height];
const glsl = (0, glsl_source_1.getGlsl)(this.context.glContext.version);
const texNumR = texShape[0];
const texNumC = texShape[1];
if (texShape != null && util_1.ArrayUtil.arraysEqual(shape, texShape)) {
const packedSampler = `vec4 ${funcName}(int row, int col) {
vec2 uv = (vec2(col, row) + halfCR) / vec2(${texNumC}.0, ${texNumR}.0);
return ${glsl.texture2D}(${name}, uv);
}`;
return new glsl_definitions_1.GlslLibRoutine(packedSampler);
}
const packedTexShape = texShape;
const valuesPerRow = Math.ceil(shape[1] / 2);
const packedSampler = `vec4 ${funcName}(int row, int col) {
vec2 uv = packedUVfrom2D(${packedTexShape[1]}, ${packedTexShape[0]}, ${valuesPerRow}, row, col);
return ${glsl.texture2D}(${name}, uv);
}`;
const source = packedSampler;
return new glsl_definitions_1.GlslLibRoutine(source, ['coordinates.packedUVfrom2D']);
}
/**
* Packed 3D snippet.
*/
getPackedSampler3D(funcName, name, inputLayout) {
const shape = inputLayout.unpackedShape;
const texShape = [inputLayout.width, inputLayout.height];
const packedTexShape = [texShape[0], texShape[1]];
const glsl = (0, glsl_source_1.getGlsl)(this.context.glContext.version);
if (shape[0] === 1) {
const squeezedShape = shape.slice(1);
const keptDims = [1, 2];
const newInputShape = (0, utils_1.squeezeInputShape)(shape, squeezedShape);
const params = ['b', 'row', 'col'];
// Deep copy of input texture layout.
const newInputLayout = JSON.parse(JSON.stringify(inputLayout));
newInputLayout.unpackedShape = newInputShape;
const samplerRoutine = this.getPackedSamplerFromInput(funcName, name, newInputLayout);
const packedSampler = `${samplerRoutine.routineBody}
vec4 ${funcName}(int b, int row, int col) {
return ${funcName}(${(0, utils_1.getSqueezedParams)(params, keptDims)});
} `;
const source = packedSampler;
return new glsl_definitions_1.GlslLibRoutine(source, samplerRoutine.dependencies);
}
const texNumR = packedTexShape[0];
const texNumC = packedTexShape[1];
const valuesPerRow = Math.ceil(shape[2] / 2);
const texelsInBatch = valuesPerRow * Math.ceil(shape[1] / 2);
const packedSampler = `vec4 ${funcName}(int b, int row, int col) {
vec2 uv = packedUVfrom3D(
${texNumC}, ${texNumR}, ${texelsInBatch}, ${valuesPerRow}, b, row, col);
return ${glsl.texture2D}(${name}, uv);}`;
const source = packedSampler;
return new glsl_definitions_1.GlslLibRoutine(source, ['coordinates.packedUVfrom3D']);
}
/*
* Packed ND snippet.
*/
getPackedSamplerND(funcName, name, inputLayout) {
const shape = inputLayout.unpackedShape;
const rank = shape.length;
const texShape = [inputLayout.width, inputLayout.height];
const glsl = (0, glsl_source_1.getGlsl)(this.context.glContext.version);
const packedTexShape = [texShape[0], texShape[1]];
const texNumR = packedTexShape[1];
const texNumC = packedTexShape[0];
const valuesPerRow = Math.ceil(shape[rank - 1] / 2);
let texelsInBatch = valuesPerRow * Math.ceil(shape[rank - 2] / 2);
let params = 'int b, int row, int col';
let index = `b * ${texelsInBatch} + (row / 2) * ${valuesPerRow} + (col / 2)`;
for (let b = 2; b < rank - 1; b++) {
params = `int b${b}, ` + params;
texelsInBatch *= shape[rank - b - 1];
index = `b${b} * ${texelsInBatch} + ` + index;
}
const packedSampler = `vec4 ${funcName}(${params}) {
int index = ${index};
int texR = index / ${texNumC};
int texC = index - texR * ${texNumC};
vec2 uv = (vec2(texC, texR) + halfCR) / vec2(${texNumC}, ${texNumR});
return ${glsl.texture2D}(${name}, uv);
}`;
const source = packedSampler;
return new glsl_definitions_1.GlslLibRoutine(source);
}
/**
* Unpacked scalar snippet.
*/
getUnpackedSamplerScalar(funcName, name, inputLayout) {
const [texNumR, texNumC] = [inputLayout.width, inputLayout.height];
if (texNumR === 1 && texNumC === 1) {
const source = `
float ${funcName}() {
return sampleTexture(${name}, halfCR);
}
`;
return new glsl_definitions_1.GlslLibRoutine(source, ['coordinates.sampleTexture']);
}
const source = `
float ${funcName}() {
int offset_${name} = coordsToOffset(TexCoords, ${texNumR}, ${texNumC});
vec2 uv = uvFromFlat(${texNumR}, ${texNumC}, offset_${name});
return sampleTexture(${name}, uv);
}
`;
return new glsl_definitions_1.GlslLibRoutine(source, ['coordinates.uvFromFlat', 'coordinates.sampleTexture', 'coordinates.coordsToOffset']);
}
/**
* Unpacked 1D snippet.
*/
getUnpackedSampler1D(funcName, name, inputLayout) {
const tNumR = inputLayout.width;
const tNumC = inputLayout.height;
if (tNumC === 1 && tNumR === 1) {
const source = `
float ${funcName}(int index) {
return sampleTexture(${name}, halfCR);
}
`;
return new glsl_definitions_1.GlslLibRoutine(source, ['coordinates.sampleTexture']);
}
if (tNumC === 1) {
const source = `
float ${funcName}(int index) {
vec2 uv = vec2((float(index) + 0.5) / ${tNumR}.0, 0.5);
return sampleTexture(${name}, uv);
}
`;
return new glsl_definitions_1.GlslLibRoutine(source, ['coordinates.sampleTexture']);
}
if (tNumR === 1) {
const source = `
float ${funcName}(int index) {
vec2 uv = vec2(0.5, (float(index) + 0.5) / ${tNumC}.0);
return sampleTexture(${name}, uv);
}
`;
return new glsl_definitions_1.GlslLibRoutine(source, ['coordinates.sampleTexture']);
}
const source = `
float ${funcName}(int index) {
vec2 uv = uvFromFlat(${tNumR}, ${tNumC}, index);
return sampleTexture(${name}, uv);
}
`;
return new glsl_definitions_1.GlslLibRoutine(source, ['coordinates.uvFromFlat', 'coordinates.sampleTexture']);
}
/**
* Unpacked 2D snippet.
*/
getUnpackedSampler2D(funcName, name, inputLayout) {
const shape = inputLayout.unpackedShape;
// TODO: modify row/col order for other dimensions.
const texShape = [inputLayout.height, inputLayout.width];
if (texShape != null && util_1.ArrayUtil.arraysEqual(shape, texShape)) {
const texNumR = texShape[1];
const texNumC = texShape[0];
const source = `
float ${funcName}(int row, int col) {
vec2 uv = (vec2(row, col) + halfCR) / vec2(${texNumR}.0, ${texNumC}.0);
return sampleTexture(${name}, uv);
}
`;
return new glsl_definitions_1.GlslLibRoutine(source, ['coordinates.sampleTexture']);
}
const { newShape, keptDims } = (0, texture_layout_strategy_1.squeezeShape)(shape);
const squeezedShape = newShape;
if (squeezedShape.length < shape.length) {
const newInputShape = (0, utils_1.squeezeInputShape)(shape, squeezedShape);
// Deep copy of input texture layout.
const newInputLayout = JSON.parse(JSON.stringify(inputLayout));
newInputLayout.unpackedShape = newInputShape;
const params = ['col', 'row'];
const source = `
${this.getUnpackedSamplerFromInput(funcName, name, newInputLayout).routineBody}
float ${funcName}(int row, int col) {
return ${funcName}(${(0, utils_1.getSqueezedParams)(params, keptDims)});
}
`;
return new glsl_definitions_1.GlslLibRoutine(source, ['coordinates.sampleTexture']);
}
const texNumR = texShape[1];
const texNumC = texShape[0];
if (texNumC === 1) {
const source = `
float ${funcName}(int row, int col) {
int offset_${name} = coordsToOffset(TexCoords, ${texNumR}, ${texNumC});
float index = dot(vec3(row, col, offset_${name}), vec3(${shape[1]}, 1, 1));
vec2 uv = vec2(0.5, (index + 0.5) / ${texNumR}.0);
return sampleTexture(${name}, uv);
}
`;
return new glsl_definitions_1.GlslLibRoutine(source, ['coordinates.sampleTexture', 'coordinates.coordsToOffset']);
}
if (texNumR === 1) {
const source = `
float ${funcName}(int row, int col) {
int offset_${name} = coordsToOffset(TexCoords, ${texNumR}, ${texNumC});
float index = dot(vec3(row, col, offset_${name}), vec3(${shape[1]}, 1, 1));
vec2 uv = vec2((index + 0.5) / ${texNumC}.0, 0.5);
return sampleTexture(${name}, uv);
}
`;
return new glsl_definitions_1.GlslLibRoutine(source, ['coordinates.sampleTexture', 'coordinates.coordsToOffset']);
}
const source = `
float ${funcName}(int row, int col) {
int index = col * ${shape[1]} + row;
vec2 uv = uvFromFlat(${texNumR}, ${texNumC}, index);
return sampleTexture(${name}, uv);
}
`;
return new glsl_definitions_1.GlslLibRoutine(source, ['coordinates.uvFromFlat', 'coordinates.sampleTexture', 'coordinates.coordsToOffset']);
}
/**
* Unpacked 3D snippet.
*/
getUnpackedSampler3D(funcName, name, inputLayout) {
const shape = inputLayout.unpackedShape;
const stride0 = shape[1] * shape[2];
const stride1 = shape[2];
const { newShape, keptDims } = (0, texture_layout_strategy_1.squeezeShape)(shape);
const squeezedShape = newShape;
if (squeezedShape.length < shape.length) {
const newInputShape = (0, utils_1.squeezeInputShape)(shape, squeezedShape);
const params = ['batch', 'col', 'row'];
// Deep copy of input texture layout.
const newInputLayout = JSON.parse(JSON.stringify(inputLayout));
newInputLayout.unpackedShape = newInputShape;
const routine = this.getUnpackedSamplerFromInput(funcName, name, newInputLayout);
// TODO: revisit the logic here to make it simpler
const revDims = keptDims.reverse();
const source = `
${routine.routineBody}
float ${funcName}(int batch, int row, int col) {
return ${funcName}(${(0, utils_1.getSqueezedParams)(params, revDims)});
}
`;
return new glsl_definitions_1.GlslLibRoutine(source, routine.dependencies);
}
const texNumR = inputLayout.width;
const texNumC = inputLayout.height;
const source = `
float ${funcName}(int depth, int row, int col) {
// Explicitly use integer operations as dot() only works on floats.
int index = depth * ${stride0} + col * ${stride1} + row;
vec2 uv = uvFromFlat(${texNumR}, ${texNumC}, index);
return sampleTexture(${name}, uv);
}
`;
return new glsl_definitions_1.GlslLibRoutine(source, ['coordinates.uvFromFlat', 'coordinates.sampleTexture', 'coordinates.coordsToOffset']);
}
/**
* Unpacked 4D snippet.
*/
getUnpackedSampler4D(funcName, name, inputLayout) {
const shape = inputLayout.unpackedShape;
const stride2 = shape[3];
const stride1 = shape[2] * stride2;
const stride0 = shape[1] * stride1;
//
// TODO: re-enable this shortcut once the index calculation bug is fixed.
//
// const {newShape, keptDims} = squeezeShape(shape as number[]);
// if (newShape.length < shape.length) {
// const newInputShape = squeezeInputShape(shape, newShape);
// const params = ['row', 'col', 'depth', 'depth2'];
// // Deep copy of input texture layout.
// const newInputLayout: TextureLayout = JSON.parse(JSON.stringify(inputLayout));
// newInputLayout.unpackedShape = newInputShape;
// const source = `
// ${this.getUnpackedSamplerFromInput(funcName, name, newInputLayout).routineBody}
// float ${funcName}(int row, int col, int depth, int depth2) {
// return ${funcName}(${getSqueezedParams(params, keptDims)});
// }
// `;
// return new GlslLibRoutine(
// source, ['coordinates.uvFromFlat', 'coordinates.sampleTexture', 'coordinates.coordsToOffset']);
// }
const texNumR = inputLayout.width;
const texNumC = inputLayout.height;
const source = `
float ${funcName}(int row, int col, int depth, int depth2) {
int index = row * ${stride0} + col * ${stride1} +
depth2 * ${stride2} + depth;
vec2 uv = uvFromFlat(${texNumR}, ${texNumC}, index);
return sampleTexture(${name}, uv);
}
`;
return new glsl_definitions_1.GlslLibRoutine(source, ['coordinates.uvFromFlat', 'coordinates.sampleTexture']);
}
/**
* Unpacked 5D snippet.
*/
getUnpackedSampler5D(funcName, name, inputLayout) {
const shape = inputLayout.unpackedShape;
const stride3 = shape[4];
const stride2 = shape[3] * stride3;
const stride1 = shape[2] * stride2;
const stride0 = shape[1] * stride1;
const { newShape, keptDims } = (0, texture_layout_strategy_1.squeezeShape)(shape);
if (newShape.length < shape.length) {
const newInputShape = (0, utils_1.squeezeInputShape)(shape, newShape);
const params = ['row', 'col', 'depth', 'depth2', 'depth3'];
// Deep copy of input texture layout.
const newInputLayout = JSON.parse(JSON.stringify(inputLayout));
newInputLayout.unpackedShape = newInputShape;
const source = `
${this.getUnpackedSamplerFromInput(funcName, name, newInputLayout).routineBody}
float ${funcName}(int row, int col, int depth, int depth2, int depth3) {
return ${funcName}(${(0, utils_1.getSqueezedParams)(params, keptDims)});
}
`;
return new glsl_definitions_1.GlslLibRoutine(source, ['coordinates.sampleTexture', 'coordinates.uvFromFlat']);
}
const texNumR = inputLayout.width;
const texNumC = inputLayout.height;
const source = `
float ${funcName}(int row, int col, int depth, int depth2, int depth3) {
int index = row * ${stride0} + col * ${stride1} + depth * ${stride2} +
depth3 * ${stride3} + depth2;
vec2 uv = uvFromFlat(${texNumR}, ${texNumC}, index);
return sampleTexture(${name}, uv);
}
`;
return new glsl_definitions_1.GlslLibRoutine(source, ['coordinates.sampleTexture', 'coordinates.uvFromFlat']);
}
/**
* Unpacked 6D snippet.
*/
getUnpackedSampler6D(funcName, name, inputLayout) {
const shape = inputLayout.unpackedShape;
const stride4 = shape[5];
const stride3 = shape[4] * stride4;
const stride2 = shape[3] * stride3;
const stride1 = shape[2] * stride2;
const stride0 = shape[1] * stride1;
const { newShape, keptDims } = (0, texture_layout_strategy_1.squeezeShape)(shape);
if (newShape.length < shape.length) {
const newInputShape = (0, utils_1.squeezeInputShape)(shape, newShape);
const params = ['row', 'col', 'depth', 'depth2', 'depth3', 'depth4'];
// Deep copy of input texture layout.
const newInputLayout = JSON.parse(JSON.stringify(inputLayout));
newInputLayout.unpackedShape = newInputShape;
const source = `
${this.getUnpackedSamplerFromInput(funcName, name, newInputLayout).routineBody}
float ${funcName}(int row, int col, int depth,
int depth2, int depth3, int depth4) {
return ${funcName}(${(0, utils_1.getSqueezedParams)(params, keptDims)});
}
`;
return new glsl_definitions_1.GlslLibRoutine(source, ['coordinates.sampleTexture', 'coordinates.uvFromFlat']);
}
const texNumR = inputLayout.width;
const texNumC = inputLayout.height;
const source = `
float ${funcName}(int row, int col, int depth,
int depth2, int depth3, int depth4) {
int index = row * ${stride0} + col * ${stride1} + depth * ${stride2} +
depth2 * ${stride3} + depth3 * ${stride4} + depth4;
vec2 uv = uvFromFlat(${texNumR}, ${texNumC}, index);
return sampleTexture(${name}, uv);
}
`;
return new glsl_definitions_1.GlslLibRoutine(source, ['coordinates.uvFromFlat', 'coordinates.sampleTexture', 'coordinates.coordsToOffset']);
}
/**
* This is the main function to map from the given texture coordiantes (s,t)
* to logical indices for the output
* There will only be one single variation of this
* Also see coordsToOffset and offsetToIndices for input-specific versions
*/
toVec() {
const output = this.context.outputTextureLayout;
const rank = output.shape.length;
const strides = output.strides;
const xScale = output.width;
const yScale = output.height;
const stridesBlock = [];
for (let i = 0; i < rank - 1; ++i) {
stridesBlock.push(`
c[${i}] = offset / ${strides[i]};`);
stridesBlock.push(`
offset -= c[${i}] * ${strides[i]};`);
}
stridesBlock.push(`
c[${rank - 1}] = offset;`);
const body = `
void toVec(vec2 texCoords, out int c[${rank}]) {
int offset = coordsToOffset(texCoords, ${xScale}, ${yScale});
${stridesBlock.join('')}
}
void toVec(int offset, out int c[${rank}]) {
${stridesBlock.join('')}
}
`;
return { toVec: new glsl_definitions_1.GlslLibRoutine(body, ['coordinates.coordsToOffset']) };
}
/**
* These are value getter functions generated for each input
* Each function is hardwired to the name and dimensions of the input
* An '_T' variation is also produced which accesses values as if the
* input was transposed
*/
valueFrom() {
const result = {};
this.context.programInfo.inputNames.forEach((name, i) => {
const layout = this.context.inputTextureLayouts[i];
const shape = layout.unpackedShape.length > 0 ? layout.unpackedShape : layout.shape;
const rank = shape.length;
let funcName = `_${name}`;
result[funcName] = new glsl_definitions_1.GlslLibRoutine(this.getValueFromSingle(name, rank, layout.width, layout.height, false), [`shapeUtils.indicesToOffset${funcName}`, 'coordinates.offsetToCoords', 'fragcolor.getColorAsFloat']);
funcName = funcName + '_T';
result[funcName] = new glsl_definitions_1.GlslLibRoutine(this.getValueFromSingle(name, rank, layout.width, layout.height, true), [`shapeUtils.indicesToOffset${funcName}`, 'coordinates.offsetToCoords', 'fragcolor.getColorAsFloat']);
});
return result;
}
/**
* Produces one value getter function for the name and rank given
* If a transpose is set proper offsetToCoords mapping will be used
* @param name name of the function
* @param rank rank of the input
* @param transpose whether or not should generate a transpose variation
*/
getValueFromSingle(varName, rank, width, height, transpose) {
let name = `_${varName}`;
if (transpose) {
name = name + '_T';
}
const glsl = (0, glsl_source_1.getGlsl)(this.context.glContext.version);
return `
float ${name}(int m[${rank}]) {
int offset = indicesToOffset${name}(m);
vec2 coords = offsetToCoords(offset, ${width}, ${height});
float value = getColorAsFloat(${glsl.texture2D}(${varName}, coords));
return value;
}
`;
}
/**
* Produces a packed value getter function for the name and rank given
* If a transpose is set proper offsetToCoords mapping will be used
* @param name name of the function
* @param rank rank of the input
* @param transpose whether or not should generate a transpose variation
*/
getPackedValueFrom(varName, rank, width, height, transpose) {
let name = `_${varName}_Pack`;
if (transpose) {
name = name + '_T';
}
const glsl = (0, glsl_source_1.getGlsl)(this.context.glContext.version);
return `
vec4 ${name}(int m[${rank}]) {
int offset = indicesToOffset_${varName}(m);
vec2 coords = offsetToCoords(offset, ${width}, ${height});
return ${glsl.texture2D}(${varName}, coords);
}
`;
}
}
exports.CoordsGlslLib = CoordsGlslLib;
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/glsl-definitions.ts":
/*!*******************************************************!*\
!*** ./lib/onnxjs/backends/webgl/glsl-definitions.ts ***!
\*******************************************************/
/***/ ((__unused_webpack_module, exports) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.TopologicalSortGlslRoutines = exports.GlslLibRoutineNode = exports.GlslLibRoutine = exports.GlslLib = exports.GlslContext = exports.FunctionType = void 0;
/* eslint-disable @typescript-eslint/naming-convention */
var FunctionType;
(function (FunctionType) {
FunctionType[FunctionType["ValueBased"] = 0] = "ValueBased";
FunctionType[FunctionType["Positional"] = 1] = "Positional";
})(FunctionType = exports.FunctionType || (exports.FunctionType = {}));
class GlslContext {
constructor(glContext, programInfo, inputTextureLayouts, outputTextureLayout) {
this.glContext = glContext;
this.programInfo = programInfo;
this.inputTextureLayouts = inputTextureLayouts;
this.outputTextureLayout = outputTextureLayout;
}
}
exports.GlslContext = GlslContext;
class GlslLib {
constructor(context) {
this.context = context;
}
}
exports.GlslLib = GlslLib;
// abstraction to represent a GLSL library routine and it's dependencies
class GlslLibRoutine {
constructor(routineBody, dependencies) {
this.routineBody = routineBody;
this.dependencies = dependencies;
}
}
exports.GlslLibRoutine = GlslLibRoutine;
// abstraction to represent a GLSL library routine and it's dependencies AS GRAPH Nodes
// this level of abstraction is used to topologically sort routines before fragment shade inclusion
class GlslLibRoutineNode {
constructor(name, routineBody, dependencies) {
this.name = name;
if (dependencies) {
this.dependencies = dependencies;
}
else {
this.dependencies = [];
}
if (routineBody) {
this.routineBody = routineBody;
}
}
addDependency(node) {
if (node) {
this.dependencies.push(node);
}
}
}
exports.GlslLibRoutineNode = GlslLibRoutineNode;
// topologically sort GLSL library routines (graph nodes abstraction) before shader script inclusion
class TopologicalSortGlslRoutines {
static returnOrderedNodes(nodes) {
if (!nodes || nodes.length === 0) {
return [];
}
if (nodes.length === 1) {
return nodes;
}
const cycleCheck = new Set();
const alreadyTraversed = new Set();
const result = new Array();
this.createOrderedNodes(nodes, cycleCheck, alreadyTraversed, result);
return result;
}
static createOrderedNodes(graphNodes, cycleCheck, alreadyTraversed, result) {
for (let i = 0; i < graphNodes.length; ++i) {
this.dfsTraverse(graphNodes[i], cycleCheck, alreadyTraversed, result);
}
}
static dfsTraverse(root, cycleCheck, alreadyTraversed, result) {
// if this root has already been traversed return
if (!root || alreadyTraversed.has(root.name)) {
return;
}
// cyclic dependency has been detected
if (cycleCheck.has(root.name)) {
throw new Error('Cyclic dependency detected. Can\'t topologically sort routines needed for shader.');
}
// hold this node to detect cycles if any
cycleCheck.add(root.name);
// traverse children in a dfs fashion
const dependencies = root.dependencies;
if (dependencies && dependencies.length > 0) {
for (let i = 0; i < dependencies.length; ++i) {
this.dfsTraverse(dependencies[i], cycleCheck, alreadyTraversed, result);
}
}
// add to result holder
result.push(root);
// mark this node as traversed so that we don't traverse from this again
alreadyTraversed.add(root.name);
// release the hold
cycleCheck.delete(root.name);
}
}
exports.TopologicalSortGlslRoutines = TopologicalSortGlslRoutines;
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/glsl-encoding-lib.ts":
/*!********************************************************!*\
!*** ./lib/onnxjs/backends/webgl/glsl-encoding-lib.ts ***!
\********************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.EncodingGlslLib = void 0;
const glsl_definitions_1 = __webpack_require__(/*! ./glsl-definitions */ "./lib/onnxjs/backends/webgl/glsl-definitions.ts");
/**
* This GLSL library handles routines converting
* float32 to/from Unsigned byte or float 16
*/
class EncodingGlslLib extends glsl_definitions_1.GlslLib {
constructor(context) {
super(context);
}
getFunctions() {
return Object.assign(Object.assign({}, this.encodeFloat32()), this.decodeFloat32());
}
getCustomTypes() {
return {};
}
encodeFloat32() {
return {
encode: new glsl_definitions_1.GlslLibRoutine(`highp vec4 encode(highp float f) {
return vec4(f, 0.0, 0.0, 0.0);
}
`)
};
}
decodeFloat32() {
return {
decode: new glsl_definitions_1.GlslLibRoutine(`highp float decode(highp vec4 rgba) {
return rgba.r;
}
`)
};
}
/**
* returns the routine to encode encode a 32bit float to a vec4 (of unsigned bytes)
* @credit: https://stackoverflow.com/questions/7059962/how-do-i-convert-a-vec4-rgba-value-to-a-float
*/
encodeUint8() {
const endianness = EncodingGlslLib.isLittleEndian() ? 'rgba.rgba=rgba.abgr;' : '';
return {
encode: new glsl_definitions_1.GlslLibRoutine(`
highp vec4 encode(highp float f) {
highp float F = abs(f);
highp float Sign = step(0.0,-f);
highp float Exponent = floor(log2(F));
highp float Mantissa = (exp2(- Exponent) * F);
Exponent = floor(log2(F) + 127.0) + floor(log2(Mantissa));
highp vec4 rgba;
rgba[0] = 128.0 * Sign + floor(Exponent*exp2(-1.0));
rgba[1] = 128.0 * mod(Exponent,2.0) + mod(floor(Mantissa*128.0),128.0);
rgba[2] = floor(mod(floor(Mantissa*exp2(23.0 -8.0)),exp2(8.0)));
rgba[3] = floor(exp2(23.0)*mod(Mantissa,exp2(-15.0)));
${endianness}
rgba = rgba / 255.0; // values need to be normalized to [0,1]
return rgba;
}
`)
};
}
/**
* returns the routine to encode a vec4 of unsigned bytes to float32
* @credit: https://stackoverflow.com/questions/7059962/how-do-i-convert-a-vec4-rgba-value-to-a-float
*/
decodeUint8() {
const endianness = EncodingGlslLib.isLittleEndian() ? 'rgba.rgba=rgba.abgr;' : '';
return {
decode: new glsl_definitions_1.GlslLibRoutine(`
highp float decode(highp vec4 rgba) {
rgba = rgba * 255.0; // values need to be de-normalized from [0,1] to [0,255]
${endianness}
highp float Sign = 1.0 - step(128.0,rgba[0])*2.0;
highp float Exponent = 2.0 * mod(rgba[0],128.0) + step(128.0,rgba[1]) - 127.0;
highp float Mantissa = mod(rgba[1],128.0)*65536.0 + rgba[2]*256.0 +rgba[3] + float(0x800000);
highp float Result = Sign * exp2(Exponent) * (Mantissa * exp2(-23.0 ));
return Result;
}
`)
};
}
/**
* Determines if the machine is little endian or not
* @credit: https://gist.github.com/TooTallNate/4750953
*/
static isLittleEndian() {
const b = new ArrayBuffer(4);
const a = new Uint32Array(b);
const c = new Uint8Array(b);
a[0] = 0xdeadbeef;
if (c[0] === 0xef) {
return true;
}
if (c[0] === 0xde) {
return false;
}
throw new Error('unknown endianness');
}
}
exports.EncodingGlslLib = EncodingGlslLib;
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/glsl-fragcolor-lib.ts":
/*!*********************************************************!*\
!*** ./lib/onnxjs/backends/webgl/glsl-fragcolor-lib.ts ***!
\*********************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.FragColorGlslLib = void 0;
const glsl_definitions_1 = __webpack_require__(/*! ./glsl-definitions */ "./lib/onnxjs/backends/webgl/glsl-definitions.ts");
const glsl_source_1 = __webpack_require__(/*! ./glsl-source */ "./lib/onnxjs/backends/webgl/glsl-source.ts");
/**
* This GLSL library handles routines around reading a texlet and writing to it
* Reading and writing could be more than just dealing with one channel
* It may require encoding/decoding to/from 4 channels into one
*/
class FragColorGlslLib extends glsl_definitions_1.GlslLib {
constructor(context) {
super(context);
}
getFunctions() {
return Object.assign(Object.assign({}, this.setFragColor()), this.getColorAsFloat());
}
getCustomTypes() {
return {};
}
setFragColor() {
const glsl = (0, glsl_source_1.getGlsl)(this.context.glContext.version);
return {
setFragColor: new glsl_definitions_1.GlslLibRoutine(`
void setFragColor(float value) {
${glsl.output} = encode(value);
}
`, ['encoding.encode'])
};
}
getColorAsFloat() {
return {
getColorAsFloat: new glsl_definitions_1.GlslLibRoutine(`
float getColorAsFloat(vec4 color) {
return decode(color);
}
`, ['encoding.decode'])
};
}
}
exports.FragColorGlslLib = FragColorGlslLib;
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/glsl-function-inliner.ts":
/*!************************************************************!*\
!*** ./lib/onnxjs/backends/webgl/glsl-function-inliner.ts ***!
\************************************************************/
/***/ ((__unused_webpack_module, exports) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.replaceInlines = void 0;
const INLINE_FUNC_DEF_REGEX = /@inline[\s\n\r]+(\w+)[\s\n\r]+([0-9a-zA-Z_]+)\s*\(([^)]*)\)\s*{(([^}]|[\n\r])*)}/gm;
const FUNC_CALL_REGEX = '(\\w+)?\\s+([_0-9a-zA-Z]+)\\s+=\\s+__FUNC__\\((.*)\\)\\s*;';
/**
* GLSL preprocessor responsible for resolving @inline directives
*/
function replaceInlines(script) {
const inlineDefs = {};
let match;
while ((match = INLINE_FUNC_DEF_REGEX.exec(script)) !== null) {
const params = match[3]
.split(',')
.map(s => {
const tokens = s.trim().split(' ');
if (tokens && tokens.length === 2) {
return { type: tokens[0], name: tokens[1] };
}
return null;
})
.filter(v => v !== null);
inlineDefs[match[2]] = { params, body: match[4] };
}
for (const name in inlineDefs) {
const regexString = FUNC_CALL_REGEX.replace('__FUNC__', name);
const regex = new RegExp(regexString, 'gm');
while ((match = regex.exec(script)) !== null) {
const type = match[1];
const variable = match[2];
const params = match[3].split(',');
const declLine = (type) ? `${type} ${variable};` : '';
let newBody = inlineDefs[name].body;
let paramRedecLine = '';
inlineDefs[name].params.forEach((v, i) => {
if (v) {
paramRedecLine += `${v.type} ${v.name} = ${params[i]};\n`;
}
});
newBody = `${paramRedecLine}\n ${newBody}`;
newBody = newBody.replace('return', `${variable} = `);
const replacement = `
${declLine}
{
${newBody}
}
`;
script = script.replace(match[0], replacement);
}
}
script = script.replace(INLINE_FUNC_DEF_REGEX, '');
return script;
}
exports.replaceInlines = replaceInlines;
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/glsl-preprocessor.ts":
/*!********************************************************!*\
!*** ./lib/onnxjs/backends/webgl/glsl-preprocessor.ts ***!
\********************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.GlslPreprocessor = void 0;
const glsl_definitions_1 = __webpack_require__(/*! ./glsl-definitions */ "./lib/onnxjs/backends/webgl/glsl-definitions.ts");
const glsl_function_inliner_1 = __webpack_require__(/*! ./glsl-function-inliner */ "./lib/onnxjs/backends/webgl/glsl-function-inliner.ts");
const glsl_registered_libs_1 = __webpack_require__(/*! ./glsl-registered-libs */ "./lib/onnxjs/backends/webgl/glsl-registered-libs.ts");
const glsl_source_1 = __webpack_require__(/*! ./glsl-source */ "./lib/onnxjs/backends/webgl/glsl-source.ts");
/**
* Preprocessor for the additions to the GLSL language
* It deals with:
* @include directives
* @inline
* Loop unrolling (not implemented)
* Macro resolution (not implemented)
*/
class GlslPreprocessor {
constructor(glContext, programInfo, inputTextureLayouts, outputTextureLayout) {
this.libs = {};
this.glslLibRoutineDependencyGraph = {};
this.context = new glsl_definitions_1.GlslContext(glContext, programInfo, inputTextureLayouts, outputTextureLayout);
// construct GlslLibs
Object.keys(glsl_registered_libs_1.glslRegistry).forEach((name) => {
const lib = new glsl_registered_libs_1.glslRegistry[name](this.context);
this.libs[name] = lib;
});
// construct GlslRoutineDependencyGraph
const map = this.glslLibRoutineDependencyGraph;
for (const libName in this.libs) {
const lib = this.libs[libName];
const routinesInLib = lib.getFunctions();
for (const routine in routinesInLib) {
const key = libName + '.' + routine;
let currentNode;
if (map[key]) {
currentNode = map[key];
currentNode.routineBody = routinesInLib[routine].routineBody;
}
else {
currentNode = new glsl_definitions_1.GlslLibRoutineNode(key, routinesInLib[routine].routineBody);
map[key] = currentNode;
}
const dependencies = routinesInLib[routine].dependencies;
if (dependencies) {
for (let i = 0; i < dependencies.length; ++i) {
if (!map[dependencies[i]]) {
const node = new glsl_definitions_1.GlslLibRoutineNode(dependencies[i]);
map[dependencies[i]] = node;
currentNode.addDependency(node);
}
else {
currentNode.addDependency(map[dependencies[i]]);
}
}
}
}
}
}
preprocess() {
const programInfo = this.context.programInfo;
let source = programInfo.shaderSource;
// append main() function
if (!this.context.programInfo.hasMain) {
source = `${source}
${(0, glsl_source_1.getDefaultFragShaderMain)(this.context.glContext.version, this.context.outputTextureLayout.shape.length)}`;
}
// replace inlines
source = (0, glsl_function_inliner_1.replaceInlines)(source);
// concat final source string
return `${(0, glsl_source_1.getFragShaderPreamble)(this.context.glContext.version)}
${this.getUniforms(programInfo.inputNames, programInfo.variables)}
${this.getImports(source)}
${source}`;
}
getImports(script) {
const routinesIncluded = this.selectGlslLibRoutinesToBeIncluded(script);
if (routinesIncluded.length === 0) {
return '';
}
let routines = '';
for (let i = 0; i < routinesIncluded.length; ++i) {
if (routinesIncluded[i].routineBody) {
routines += routinesIncluded[i].routineBody + '\n';
}
else {
throw new Error(`Missing body for the Glsl Library routine: ${routinesIncluded[i].name}`);
}
}
return routines;
}
selectGlslLibRoutinesToBeIncluded(script) {
const nodes = [];
Object.keys(this.glslLibRoutineDependencyGraph).forEach(classAndRoutine => {
const routine = classAndRoutine.split('.')[1];
if (script.indexOf(routine) !== -1) {
nodes.push(this.glslLibRoutineDependencyGraph[classAndRoutine]);
}
});
return glsl_definitions_1.TopologicalSortGlslRoutines.returnOrderedNodes(nodes);
}
getUniforms(samplers, variables) {
const uniformLines = [];
if (samplers) {
for (const sampler of samplers) {
uniformLines.push(`uniform sampler2D ${sampler};`);
}
}
if (variables) {
for (const variable of variables) {
uniformLines.push(`uniform ${variable.type} ${variable.name}${variable.arrayLength ? `[${variable.arrayLength}]` : ''};`);
}
}
return uniformLines.join('\n');
}
}
exports.GlslPreprocessor = GlslPreprocessor;
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/glsl-registered-libs.ts":
/*!***********************************************************!*\
!*** ./lib/onnxjs/backends/webgl/glsl-registered-libs.ts ***!
\***********************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.glslRegistry = void 0;
const glsl_coordinate_lib_1 = __webpack_require__(/*! ./glsl-coordinate-lib */ "./lib/onnxjs/backends/webgl/glsl-coordinate-lib.ts");
const glsl_encoding_lib_1 = __webpack_require__(/*! ./glsl-encoding-lib */ "./lib/onnxjs/backends/webgl/glsl-encoding-lib.ts");
const glsl_fragcolor_lib_1 = __webpack_require__(/*! ./glsl-fragcolor-lib */ "./lib/onnxjs/backends/webgl/glsl-fragcolor-lib.ts");
const glsl_shape_utils_lib_1 = __webpack_require__(/*! ./glsl-shape-utils-lib */ "./lib/onnxjs/backends/webgl/glsl-shape-utils-lib.ts");
const glsl_vec_lib_1 = __webpack_require__(/*! ./glsl-vec-lib */ "./lib/onnxjs/backends/webgl/glsl-vec-lib.ts");
exports.glslRegistry = {
'encoding': glsl_encoding_lib_1.EncodingGlslLib,
'fragcolor': glsl_fragcolor_lib_1.FragColorGlslLib,
'vec': glsl_vec_lib_1.VecGlslLib,
'shapeUtils': glsl_shape_utils_lib_1.ShapeUtilsGlslLib,
'coordinates': glsl_coordinate_lib_1.CoordsGlslLib,
// 'arrays': ArrayGlslSLib
};
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/glsl-shape-utils-lib.ts":
/*!***********************************************************!*\
!*** ./lib/onnxjs/backends/webgl/glsl-shape-utils-lib.ts ***!
\***********************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.ShapeUtilsGlslLib = void 0;
const glsl_definitions_1 = __webpack_require__(/*! ./glsl-definitions */ "./lib/onnxjs/backends/webgl/glsl-definitions.ts");
/**
* GLSL Library responsible for data types and routines for manipulating
* coordinates and mapping to/from tensor indices
*/
class ShapeUtilsGlslLib extends glsl_definitions_1.GlslLib {
constructor(context) {
super(context);
}
getFunctions() {
return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, this.bcastIndex()), this.bcastMatmulIndex()), this.offsetToIndices()), this.indicesToOffset()), this.incrementIndices());
}
getCustomTypes() {
return {};
}
bcastIndex() {
const outputRank = this.context.outputTextureLayout.shape.length;
const result = {};
this.context.programInfo.inputNames.forEach((name, i) => {
const shape = this.context.inputTextureLayouts[i].unpackedShape;
if (shape.length <= outputRank) {
const rank = shape.length;
const dimOffset = outputRank - rank;
const funcName = `bcastIndices_${name}`;
let block = '';
for (let i = 0; i < rank; ++i) {
block += `
realIndices[${i}] = int( mod(float(bcastedIndices[${dimOffset + i}]), ${shape[i]}.0) );
`;
}
const body = `
void ${funcName} (int bcastedIndices[${outputRank}], out int realIndices[${rank}]) {
${block}
}
`;
result[funcName] = new glsl_definitions_1.GlslLibRoutine(body);
}
});
return result;
}
bcastMatmulIndex() {
const outputRank = this.context.outputTextureLayout.shape.length;
const result = {};
this.context.programInfo.inputNames.forEach((name, i) => {
const shape = this.context.inputTextureLayouts[i].shape;
if (!(shape.length < 2 || shape.length > outputRank)) {
const rank = shape.length;
const dimOffset = outputRank - rank;
const funcName = `bcastMatmulIndices_${name}`;
let block = '';
for (let i = 0; i < rank - 2; ++i) {
block += `
realIndices[${i}] = int( mod(float(bcastedIndices[${dimOffset + i}]), ${shape[i]}.0) );
`;
}
const body = `
void ${funcName}(int bcastedIndices[${outputRank}], out int realIndices[${rank}]) {
${block}
realIndices[${rank - 1}] = bcastedIndices[${outputRank - 1}];
realIndices[${rank - 2}] = bcastedIndices[${outputRank - 2}];
}
`;
result[funcName] = new glsl_definitions_1.GlslLibRoutine(body);
}
});
return result;
}
indicesToOffset() {
const result = {};
this.context.programInfo.inputNames.forEach((name, i) => {
const shape = this.context.inputTextureLayouts[i].shape;
const strides = this.context.inputTextureLayouts[i].strides;
const rank = shape.length;
let funcName = `indicesToOffset_${name}`;
result[funcName] = new glsl_definitions_1.GlslLibRoutine(ShapeUtilsGlslLib.indexToOffsetSingle(funcName, rank, strides));
funcName = `indicesToOffset_${name}_T`;
result[funcName] =
new glsl_definitions_1.GlslLibRoutine(ShapeUtilsGlslLib.indexToOffsetSingle(funcName, rank, strides.slice().reverse()));
});
return result;
}
static indexToOffsetSingle(name, rank, strides) {
let block = '';
for (let i = rank - 1; i >= 0; --i) {
block += `
offset += indices[${i}] * ${strides[i]};
`;
}
return `
int ${name}(int indices[${rank}]) {
int offset = 0;
${block}
return offset;
}
`;
}
offsetToIndices() {
const result = {};
this.context.programInfo.inputNames.forEach((name, i) => {
const shape = this.context.inputTextureLayouts[i].shape;
const strides = this.context.inputTextureLayouts[i].strides;
const rank = shape.length;
let funcName = `offsetToIndices_${name}`;
result[funcName] = new glsl_definitions_1.GlslLibRoutine(ShapeUtilsGlslLib.offsetToIndicesSingle(funcName, rank, strides));
funcName = `offsetToIndices_${name}_T`;
result[funcName] =
new glsl_definitions_1.GlslLibRoutine(ShapeUtilsGlslLib.offsetToIndicesSingle(funcName, rank, strides.slice().reverse()));
});
return result;
}
static offsetToIndicesSingle(name, rank, strides) {
const stridesBlock = [];
for (let i = 0; i < rank - 1; ++i) {
stridesBlock.push(`
indices[${i}] = offset / ${strides[i]};`);
stridesBlock.push(`
offset -= indices[${i}] * ${strides[i]};`);
}
stridesBlock.push(`
indices[${rank - 1}] = offset;`);
return `
void ${name}(int offset, out int indices[${rank}]) {
${stridesBlock.join('')}
}
`;
}
incrementIndices() {
const result = {};
this.context.programInfo.inputNames.forEach((name, i) => {
const shape = this.context.inputTextureLayouts[i].shape;
const rank = shape.length;
const funcName = `incrementIndices_${name}`;
let shapeInit = '';
for (let i = 0; i < rank; ++i) {
shapeInit += `
shape[${i}] = ${shape[i]};`;
}
const body = `
void ${funcName}(int axis, out int indices[${rank}]) {
int shape[${rank}];
${shapeInit};
for(int i = ${rank} -1 ; i >= 0; --i) {
if(i > axis) continue;
indices[i] += 1;
if(indices[i] < shape[i]) {
break;
}
indices[i] = 0;
}
}
`;
result[funcName] = new glsl_definitions_1.GlslLibRoutine(body);
});
return result;
}
}
exports.ShapeUtilsGlslLib = ShapeUtilsGlslLib;
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/glsl-source.ts":
/*!**************************************************!*\
!*** ./lib/onnxjs/backends/webgl/glsl-source.ts ***!
\**************************************************/
/***/ ((__unused_webpack_module, exports) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getDefaultFragShaderMain = exports.getFragShaderPreamble = exports.getVertexShaderSource = exports.getGlsl = void 0;
const GLSL_ES_2_0 = {
version: '',
attribute: 'attribute',
varyingVertex: 'varying',
varyingFrag: 'varying',
texture2D: 'texture2D',
output: 'gl_FragColor',
outputDeclaration: '',
};
const GLSL_ES_3_0 = {
version: '#version 300 es',
attribute: 'in',
varyingVertex: 'out',
varyingFrag: 'in',
texture2D: 'texture',
output: 'outputColor',
outputDeclaration: 'out vec4 outputColor;',
};
function getGlsl(version) {
return version === 1 ? GLSL_ES_2_0 : GLSL_ES_3_0;
}
exports.getGlsl = getGlsl;
function getVertexShaderSource(version) {
const glsl = getGlsl(version);
return `${glsl.version}
precision highp float;
${glsl.attribute} vec3 position;
${glsl.attribute} vec2 textureCoord;
${glsl.varyingVertex} vec2 TexCoords;
void main()
{
gl_Position = vec4(position, 1.0);
TexCoords = textureCoord;
}`;
}
exports.getVertexShaderSource = getVertexShaderSource;
function getFragShaderPreamble(version) {
const glsl = getGlsl(version);
return `${glsl.version}
precision highp float;
precision highp int;
precision highp sampler2D;
${glsl.varyingFrag} vec2 TexCoords;
${glsl.outputDeclaration}
const vec2 halfCR = vec2(0.5, 0.5);
// Custom vector types to handle higher dimenalities.
struct ivec5
{
int x;
int y;
int z;
int w;
int u;
};
struct ivec6
{
int x;
int y;
int z;
int w;
int u;
int v;
};
int imod(int x, int y) {
return x - y * (x / y);
}
`;
}
exports.getFragShaderPreamble = getFragShaderPreamble;
function getDefaultFragShaderMain(version, outputShapeLength) {
const glsl = getGlsl(version);
return `
void main() {
int indices[${outputShapeLength}];
toVec(TexCoords, indices);
vec4 result = vec4(process(indices));
${glsl.output} = result;
}
`;
}
exports.getDefaultFragShaderMain = getDefaultFragShaderMain;
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/glsl-vec-lib.ts":
/*!***************************************************!*\
!*** ./lib/onnxjs/backends/webgl/glsl-vec-lib.ts ***!
\***************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.VecGlslLib = void 0;
const glsl_definitions_1 = __webpack_require__(/*! ./glsl-definitions */ "./lib/onnxjs/backends/webgl/glsl-definitions.ts");
/**
* GLSL Library responsible for vec routines
* Vec is an varible length int array. The length is fixed at the time of
* generating the library functions from the dimensions of the output.
*/
class VecGlslLib extends glsl_definitions_1.GlslLib {
constructor(context) {
super(context);
}
getCustomTypes() {
return {};
}
getFunctions() {
return Object.assign(Object.assign(Object.assign(Object.assign({}, this.binaryVecFunctions()), this.copyVec()), this.setVecItem()), this.getVecItem());
}
binaryVecFunctions() {
const outputLayout = this.context.outputTextureLayout;
const rank = outputLayout.shape.length;
const nameOp = { add: '+=', sub: '-=', mul: '*=', div: '/=' };
const result = {};
for (const name in nameOp) {
const fname = `${name}Vec`;
let assignmentBlock = '';
for (let i = 0; i < rank; ++i) {
assignmentBlock += `
dest[${i}] ${nameOp[name]} src[${i}];
`;
}
const body = `
void ${fname}(int src[${rank}], out int dest[${rank}]) {
${assignmentBlock}
}
`;
result[fname] = new glsl_definitions_1.GlslLibRoutine(body);
}
return result;
}
copyVec() {
const outputLayout = this.context.outputTextureLayout;
const rank = outputLayout.shape.length;
let assignmentBlock = '';
for (let i = 0; i < rank; ++i) {
assignmentBlock += `
dest[${i}] = src[${i}];
`;
}
const body = `
void copyVec(int src[${rank}], out int dest[${rank}]) {
${assignmentBlock}
}
`;
return { copyVec: new glsl_definitions_1.GlslLibRoutine(body) };
}
setVecItem() {
const outputLayout = this.context.outputTextureLayout;
const rank = outputLayout.shape.length;
let block = `
if(index < 0)
index =${rank} + index;
if (index == 0)
m[0] = value;
`;
for (let i = 1; i < rank - 1; ++i) {
block += `
else if (index == ${i})
m[${i}] = value;
`;
}
block += `
else
m[${rank - 1}] = value;
`;
const body = `
void setVecItem(out int m[${rank}], int index, int value) {
${block}
}
`;
return { setVecItem: new glsl_definitions_1.GlslLibRoutine(body) };
}
getVecItem() {
const outputLayout = this.context.outputTextureLayout;
const rank = outputLayout.shape.length;
let block = `
if(index < 0)
index = ${rank} + index;
if (index == 0)
return m[0];
`;
for (let i = 1; i < rank - 1; ++i) {
block += `
else if (index == ${i})
return m[${i}];
`;
}
block += `
else
return m[${rank - 1}];
`;
const body = `
int getVecItem(int m[${rank}], int index) {
${block}
}
`;
return { getVecItem: new glsl_definitions_1.GlslLibRoutine(body) };
}
}
exports.VecGlslLib = VecGlslLib;
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/inference-handler.ts":
/*!********************************************************!*\
!*** ./lib/onnxjs/backends/webgl/inference-handler.ts ***!
\********************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.WebGLInferenceHandler = void 0;
const instrument_1 = __webpack_require__(/*! ../../instrument */ "./lib/onnxjs/instrument.ts");
const tensor_1 = __webpack_require__(/*! ../../tensor */ "./lib/onnxjs/tensor.ts");
const util_1 = __webpack_require__(/*! ../../util */ "./lib/onnxjs/util.ts");
const pack_1 = __webpack_require__(/*! ./ops/pack */ "./lib/onnxjs/backends/webgl/ops/pack.ts");
const reshape_packed_1 = __webpack_require__(/*! ./ops/reshape-packed */ "./lib/onnxjs/backends/webgl/ops/reshape-packed.ts");
const uint8_encode_1 = __webpack_require__(/*! ./ops/uint8-encode */ "./lib/onnxjs/backends/webgl/ops/uint8-encode.ts");
const unpack_1 = __webpack_require__(/*! ./ops/unpack */ "./lib/onnxjs/backends/webgl/ops/unpack.ts");
const texture_layout_1 = __webpack_require__(/*! ./texture-layout */ "./lib/onnxjs/backends/webgl/texture-layout.ts");
const types_1 = __webpack_require__(/*! ./types */ "./lib/onnxjs/backends/webgl/types.ts");
const getProgramInfoUniqueKey = (programInfo, inputTextureDatas) => {
const inputs = inputTextureDatas.map(texture => `${texture.unpackedShape.join(',')};${texture.width}x${texture.height}`)
.join('_');
let key = programInfo.name;
if (programInfo.cacheHint) {
key += '[' + programInfo.cacheHint + ']';
}
key += ':' + inputs;
return key;
};
class WebGLInferenceHandler {
constructor(session) {
this.session = session;
this.packedTextureDataCache = new Map();
this.unpackedTextureDataCache = new Map();
}
/**
* @returns [width, height]
*/
calculateTextureWidthAndHeight(shape, textureType) {
return (0, texture_layout_1.calculateTextureWidthAndHeight)(this.session.layoutStrategy, shape, textureType);
}
executeProgram(program, inputs) {
if (inputs.length < program.inputNames.length) {
throw new Error(`Input size mustn't be less than ${program.inputNames.length}.`);
}
if (program.inputNames.length !== program.inputTypes.length) {
throw new Error('input names size does not match input types');
}
// create texture info for input
const inputTextureDatas = [];
for (let i = 0; i < program.inputNames.length; ++i) {
inputTextureDatas[i] = this.getOrCreateTextureData(inputs[i], program.inputTypes[i]);
}
const key = getProgramInfoUniqueKey(program, inputTextureDatas);
let artifact = this.session.programManager.getArtifact(key);
const programInfo = artifact ?
artifact.programInfo :
(typeof program.get === 'function' ? program.get() :
program);
// create texture info for output
const outputTextureLayout = (0, texture_layout_1.createTextureLayoutFromTextureType)(this.session.layoutStrategy, programInfo.output.dims, programInfo.output.textureType);
const outputTextureData = this.createTextureData(outputTextureLayout, programInfo.output.type);
if (!artifact) {
artifact = this.session.programManager.build(programInfo, inputTextureDatas, outputTextureData);
this.session.programManager.setArtifact(key, artifact);
}
this.runProgram(artifact, inputTextureDatas, outputTextureData);
return outputTextureData;
}
run(program, inputs) {
const outputTextureData = this.executeProgram(program, inputs);
return outputTextureData.tensor;
}
runProgram(artifact, inputs, output) {
// input should match
for (let i = 0; i < inputs.length; ++i) {
if (!!inputs[i].isPacked !== (artifact.programInfo.inputTypes[i] === types_1.TextureType.packed)) {
throw new Error(`input[${i}] property packed inconsistent`);
}
}
// output should match
if (!!output.isPacked !== (artifact.programInfo.output.textureType === types_1.TextureType.packed)) {
throw new Error('output property packed inconsistent');
}
this.session.programManager.run(artifact, inputs, output);
}
/**
* Create a TextureData object from a tensor.
* Usage = Encoder.Usage.UploadOnly.
* If a related texture data is found in cache, returns it;
* Otherwise:
* Creates a new texture layout if not provided;
* Creates WebGLTexture with the layout;
* Upload tensor data to the texture;
* Creates a texture data object associated with the given tensor.
* @param tensor the tensor with data to upload
*/
getOrCreateTextureData(tensor, textureType) {
let td = this.getTextureData(tensor.dataId, textureType === types_1.TextureType.packed);
if (!td) {
// check if we have texture data in different type
td = this.getTextureData(tensor.dataId, textureType !== types_1.TextureType.packed);
if (td) {
if (textureType === types_1.TextureType.packed) {
return this.pack(td);
}
else {
return this.unpack(td);
}
}
}
if (!td) {
const layout = (0, texture_layout_1.createTextureLayoutFromTextureType)(this.session.layoutStrategy, tensor.dims, textureType);
if (textureType === types_1.TextureType.packedLastDimension) {
const group = 1;
const channels = 4;
const shape = tensor.dims;
if (shape.length === 4) {
// pre-processing for kernel data of Conv.
//
// TODO: currently this is a hacking to overwrite Conv's weight. The correct way to do this should be:
// 1. implement texture based const-folding
// 2. create a WebGL program "preprocessConvWeight" to do the same work as below
// 3. run the program before dotProduct.
//
const adjustedKernelShape = [shape[0], Math.ceil((shape[1] * shape[2] * shape[3]) / channels)];
const adjustedLayout = (0, texture_layout_1.createTextureLayoutFromTextureType)(this.session.layoutStrategy, adjustedKernelShape, textureType);
let buffer = tensor.numberData;
if (shape[1] * shape[2] * shape[3] % channels !== 0) {
const numFeatureMaps = shape[0];
const oldRowSize = shape[1] * shape[2] * shape[3];
const newRowSize = Math.ceil(oldRowSize * group / channels) * channels;
const newSize = numFeatureMaps * newRowSize;
buffer = new Float32Array(newSize);
for (let f = 0; f < numFeatureMaps; ++f) {
const oldOffset = f * oldRowSize;
const newOffset = f * newRowSize + f % group * oldRowSize;
buffer.set(tensor.numberData.subarray(oldOffset, oldOffset + oldRowSize), newOffset);
}
}
return this.createTextureData(adjustedLayout, tensor.type, buffer, tensor, 1 /* Encoder.Usage.UploadOnly */);
}
}
if (textureType === types_1.TextureType.packed) {
const unpackedTextureLayout = (0, texture_layout_1.createTextureLayoutFromShape)(this.session.layoutStrategy, tensor.dims, 1, [], { reverseWH: true });
const unpackedTextureData = this.createTextureData(unpackedTextureLayout, tensor.type, tensor.numberData, tensor, 1 /* Encoder.Usage.UploadOnly */);
td = this.pack(unpackedTextureData);
}
else {
td = this.createTextureData(layout, tensor.type, tensor.numberData, tensor, 1 /* Encoder.Usage.UploadOnly */);
}
}
return td;
}
/**
* Create a TextureData object using the given data and bind to the given tensor.
* Usage = Encoder.Usage.UploadOnly.
* NOTE: this function is a hack for Conv implementation. should remove this function, after rewriting Conv
* implementation by Graph.Transformer
* @param dataType the tensor data type
* @param data the actual data to upload
* @param tensor the tensor to bind. tensor's data is ignored.
*/
createTextureDataFromLayoutBindTensor(layout, dataType, data, tensor) {
return this.createTextureData(layout, dataType, data, tensor, 1 /* Encoder.Usage.UploadOnly */);
}
createTextureData(layout, dataType, data, tensor, usage) {
instrument_1.Logger.verbose('InferenceHandler', `Creating TextureData: layout:[${JSON.stringify(layout)}]`);
const texture = this.session.textureManager.createTextureFromLayout(dataType, layout, data, usage);
return this.createTextureDataFromTexture(layout, dataType, texture, tensor);
}
reshapeUnpacked(input, reshapedDims) {
const inputTD = this.getOrCreateTextureData(input, types_1.TextureType.unpacked);
const newTextureLayout = {
channels: inputTD.channels,
height: inputTD.height,
width: inputTD.width,
// handle reshaping into scalar Tensors
shape: reshapedDims.length !== 0 ? reshapedDims : [1],
strides: util_1.ShapeUtil.computeStrides(reshapedDims),
unpackedShape: reshapedDims,
};
const newTextureData = this.createTextureDataFromTexture(newTextureLayout, input.type, inputTD.texture);
return newTextureData.tensor;
}
reshapePacked(input, reshapedDims) {
const inputTD = this.getOrCreateTextureData(input, types_1.TextureType.packed);
// check if the reshape is 'cheap'
if ((0, reshape_packed_1.isReshapeCheap)(input.dims, reshapedDims)) {
const newTextureLayout = {
channels: inputTD.channels,
height: inputTD.height,
width: inputTD.width,
// handle reshaping into scalar Tensors
shape: reshapedDims.length !== 0 ? reshapedDims : [1],
strides: util_1.ShapeUtil.computeStrides(reshapedDims),
unpackedShape: reshapedDims,
isPacked: true
};
const newTextureData = this.createTextureDataFromTexture(newTextureLayout, input.type, inputTD.texture);
return newTextureData.tensor;
}
const squeezedInputShape = (0, reshape_packed_1.processDims3D)(input.dims);
const squeezedOutputShape = (0, reshape_packed_1.processDims3D)(reshapedDims);
const squeezedInputTensor = this.reshapePacked(input, squeezedInputShape);
const squeezedOutputTensor = this.run((0, reshape_packed_1.createPackedReshape3DProgramInfoLoader)(this, squeezedInputTensor, squeezedOutputShape), [squeezedInputTensor]);
const outputTensor = this.reshapePacked(squeezedOutputTensor, reshapedDims);
return outputTensor;
}
cast(input, type) {
const inputTD = this.getOrCreateTextureData(input, types_1.TextureType.unpacked);
const newTextureData = this.createTextureDataFromTexture(inputTD, type, inputTD.texture);
return newTextureData.tensor;
}
createTextureDataFromTexture(layout, dataType, texture, tensor, tensorId) {
const textureData = Object.assign(Object.assign({}, layout), { tensor: tensor ||
new tensor_1.Tensor(layout.unpackedShape, dataType, (_id) => this.readTexture(textureData), async (_id) => this.readTextureAsync(textureData), undefined, tensorId), texture });
this.setTextureData(textureData.tensor.dataId, textureData, layout.isPacked);
return textureData;
}
getTextureData(tensorId, isPacked = false) {
return this.session.isInitializer(tensorId) ? this.session.getTextureData(tensorId, isPacked) :
isPacked ? this.packedTextureDataCache.get(tensorId) :
this.unpackedTextureDataCache.get(tensorId);
}
setTextureData(tensorId, td, isPacked = false) {
if (this.session.isInitializer(tensorId)) {
this.session.setTextureData(tensorId, td, isPacked);
}
else {
(isPacked ? this.packedTextureDataCache : this.unpackedTextureDataCache).set(tensorId, td);
}
}
isTextureLayoutCached(tensor, isPacked = false) {
return !!this.getTextureData(tensor.dataId, isPacked);
}
dispose() {
this.session.textureManager.clearActiveTextures();
this.packedTextureDataCache.forEach(td => this.session.textureManager.releaseTexture(td));
this.packedTextureDataCache = new Map();
this.unpackedTextureDataCache.forEach(td => this.session.textureManager.releaseTexture(td));
this.unpackedTextureDataCache = new Map();
}
readTexture(textureData) {
if (textureData.isPacked) {
return this.readTexture(this.unpack(textureData));
}
if (!this.session.backend.glContext.isFloat32DownloadSupported) {
return this.session.textureManager.readUint8TextureAsFloat((0, uint8_encode_1.encodeAsUint8)(this, textureData));
}
return this.session.textureManager.readTexture(textureData, textureData.tensor.type, textureData.channels);
}
async readTextureAsync(textureData) {
if (textureData.isPacked) {
return this.readTextureAsync(this.unpack(textureData));
}
if (!this.session.backend.glContext.isFloat32DownloadSupported) {
return this.session.textureManager.readUint8TextureAsFloat((0, uint8_encode_1.encodeAsUint8)(this, textureData));
}
return this.session.textureManager.readTextureAsync(textureData, textureData.tensor.type, textureData.channels);
}
pack(input) {
const outputTextureData = this.executeProgram((0, pack_1.createPackProgramInfoLoader)(this, input.tensor), [input.tensor]);
return outputTextureData;
}
unpack(input) {
const outputTextureData = this.executeProgram((0, unpack_1.createUnpackProgramInfoLoader)(this, input.tensor), [input.tensor]);
return outputTextureData;
}
}
exports.WebGLInferenceHandler = WebGLInferenceHandler;
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/op-resolve-rules.ts":
/*!*******************************************************!*\
!*** ./lib/onnxjs/backends/webgl/op-resolve-rules.ts ***!
\*******************************************************/
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.WEBGL_OP_RESOLVE_RULES = void 0;
const batch_normalization_1 = __webpack_require__(/*! ./ops/batch-normalization */ "./lib/onnxjs/backends/webgl/ops/batch-normalization.ts");
const binaryOps = __importStar(__webpack_require__(/*! ./ops/binary-op */ "./lib/onnxjs/backends/webgl/ops/binary-op.ts"));
const cast_1 = __webpack_require__(/*! ./ops/cast */ "./lib/onnxjs/backends/webgl/ops/cast.ts");
const concat_1 = __webpack_require__(/*! ./ops/concat */ "./lib/onnxjs/backends/webgl/ops/concat.ts");
const conv_1 = __webpack_require__(/*! ./ops/conv */ "./lib/onnxjs/backends/webgl/ops/conv.ts");
const conv_transpose_1 = __webpack_require__(/*! ./ops/conv-transpose */ "./lib/onnxjs/backends/webgl/ops/conv-transpose.ts");
const depth_to_space_1 = __webpack_require__(/*! ./ops/depth-to-space */ "./lib/onnxjs/backends/webgl/ops/depth-to-space.ts");
const flatten_1 = __webpack_require__(/*! ./ops/flatten */ "./lib/onnxjs/backends/webgl/ops/flatten.ts");
const gather_1 = __webpack_require__(/*! ./ops/gather */ "./lib/onnxjs/backends/webgl/ops/gather.ts");
const gemm_1 = __webpack_require__(/*! ./ops/gemm */ "./lib/onnxjs/backends/webgl/ops/gemm.ts");
const image_scaler_1 = __webpack_require__(/*! ./ops/image-scaler */ "./lib/onnxjs/backends/webgl/ops/image-scaler.ts");
const instance_normalization_1 = __webpack_require__(/*! ./ops/instance-normalization */ "./lib/onnxjs/backends/webgl/ops/instance-normalization.ts");
const matmul_1 = __webpack_require__(/*! ./ops/matmul */ "./lib/onnxjs/backends/webgl/ops/matmul.ts");
const pad_1 = __webpack_require__(/*! ./ops/pad */ "./lib/onnxjs/backends/webgl/ops/pad.ts");
const pool_1 = __webpack_require__(/*! ./ops/pool */ "./lib/onnxjs/backends/webgl/ops/pool.ts");
const reduce_1 = __webpack_require__(/*! ./ops/reduce */ "./lib/onnxjs/backends/webgl/ops/reduce.ts");
const reshape_1 = __webpack_require__(/*! ./ops/reshape */ "./lib/onnxjs/backends/webgl/ops/reshape.ts");
const resize_packed_1 = __webpack_require__(/*! ./ops/resize-packed */ "./lib/onnxjs/backends/webgl/ops/resize-packed.ts");
const shape_1 = __webpack_require__(/*! ./ops/shape */ "./lib/onnxjs/backends/webgl/ops/shape.ts");
const slice_1 = __webpack_require__(/*! ./ops/slice */ "./lib/onnxjs/backends/webgl/ops/slice.ts");
const softmax_1 = __webpack_require__(/*! ./ops/softmax */ "./lib/onnxjs/backends/webgl/ops/softmax.ts");
const split_1 = __webpack_require__(/*! ./ops/split */ "./lib/onnxjs/backends/webgl/ops/split.ts");
const squeeze_1 = __webpack_require__(/*! ./ops/squeeze */ "./lib/onnxjs/backends/webgl/ops/squeeze.ts");
const sum_1 = __webpack_require__(/*! ./ops/sum */ "./lib/onnxjs/backends/webgl/ops/sum.ts");
const tile_1 = __webpack_require__(/*! ./ops/tile */ "./lib/onnxjs/backends/webgl/ops/tile.ts");
const transpose_1 = __webpack_require__(/*! ./ops/transpose */ "./lib/onnxjs/backends/webgl/ops/transpose.ts");
const unaryOps = __importStar(__webpack_require__(/*! ./ops/unary-op */ "./lib/onnxjs/backends/webgl/ops/unary-op.ts"));
const unsqueeze_1 = __webpack_require__(/*! ./ops/unsqueeze */ "./lib/onnxjs/backends/webgl/ops/unsqueeze.ts");
const upsample_1 = __webpack_require__(/*! ./ops/upsample */ "./lib/onnxjs/backends/webgl/ops/upsample.ts");
exports.WEBGL_OP_RESOLVE_RULES = [
['Abs', '', '6+', unaryOps.abs],
['Acos', '', '7+', unaryOps.acos],
['Add', '', '7+', binaryOps.add],
['And', '', '7+', binaryOps.and],
['Asin', '', '7+', unaryOps.asin],
['Atan', '', '7+', unaryOps.atan],
// TODO: support new attributes for AveragePool-10
['AveragePool', '', '7+', pool_1.averagePool, pool_1.parseAveragePoolAttributes],
['BatchNormalization', '', '7+', batch_normalization_1.batchNormalization, batch_normalization_1.parseBatchNormalizationAttributes],
['Cast', '', '6+', cast_1.cast, cast_1.parseCastAttributes],
['Ceil', '', '6+', unaryOps.ceil],
['Clip', '', '6-10', unaryOps.clip, unaryOps.parseClipAttributes],
['Clip', '', '11+', unaryOps.clipV11],
['Concat', '', '4+', concat_1.concat, concat_1.parseConcatAttributes],
['Conv', '', '1+', conv_1.conv, conv_1.parseConvAttributes],
['ConvTranspose', '', '1+', conv_transpose_1.convTranspose, conv_transpose_1.parseConvTransposeAttributes],
['Cos', '', '7+', unaryOps.cos],
['Div', '', '7+', binaryOps.div],
['Dropout', '', '7+', unaryOps.identity],
['DepthToSpace', '', '1+', depth_to_space_1.depthToSpace, depth_to_space_1.parseDepthToSpaceAttributes],
['Equal', '', '7+', binaryOps.equal],
['Elu', '', '6+', unaryOps.elu, unaryOps.parseEluAttributes],
['Exp', '', '6+', unaryOps.exp],
['Flatten', '', '1+', flatten_1.flatten, flatten_1.parseFlattenAttributes],
['Floor', '', '6+', unaryOps.floor],
['FusedConv', 'com.microsoft', '1+', conv_1.conv, conv_1.parseConvAttributes],
['Gather', '', '1+', gather_1.gather, gather_1.parseGatherAttributes],
['Gemm', '', '7-10', gemm_1.gemm, gemm_1.parseGemmAttributesV7],
['Gemm', '', '11+', gemm_1.gemm, gemm_1.parseGemmAttributesV11],
['GlobalAveragePool', '', '1+', pool_1.globalAveragePool, pool_1.parseGlobalAveragePoolAttributes],
['GlobalMaxPool', '', '1+', pool_1.globalMaxPool],
['Greater', '', '7+', binaryOps.greater],
['Identity', '', '1+', unaryOps.identity],
['ImageScaler', '', '1+', image_scaler_1.imageScaler, image_scaler_1.parseImageScalerAttributes],
['InstanceNormalization', '', '6+', instance_normalization_1.instanceNormalization, instance_normalization_1.parseInstanceNormalizationAttributes],
['LeakyRelu', '', '6+', unaryOps.leakyRelu, unaryOps.parseLeakyReluAttributes],
['Less', '', '7+', binaryOps.less],
['Log', '', '6+', unaryOps.log],
['MatMul', '', '1+', matmul_1.matMul, matmul_1.parseMatMulAttributes],
// TODO: support new attributes for MaxPool-8 and MaxPool-10
['MaxPool', '', '1+', pool_1.maxPool, pool_1.parseMaxPoolAttributes],
['Mul', '', '7+', binaryOps.mul],
['Neg', '', '6+', unaryOps.neg],
['Not', '', '1+', unaryOps.not],
['Or', '', '7+', binaryOps.or],
['Pad', '', '2-10', pad_1.padV2, pad_1.parsePadAttributesV2],
['Pad', '', '11+', pad_1.padV11, pad_1.parsePadAttributesV11],
['Pow', '', '7+', binaryOps.pow],
['PRelu', '', '7+', binaryOps.pRelu],
['ReduceLogSum', '', '1+', reduce_1.reduceLogSum, reduce_1.parseReduceAttributes],
['ReduceMax', '', '1+', reduce_1.reduceMax, reduce_1.parseReduceAttributes],
['ReduceMean', '', '1+', reduce_1.reduceMean, reduce_1.parseReduceAttributes],
['ReduceMin', '', '1+', reduce_1.reduceMin, reduce_1.parseReduceAttributes],
['ReduceProd', '', '1+', reduce_1.reduceProd, reduce_1.parseReduceAttributes],
['ReduceSum', '', '1-12', reduce_1.reduceSum, reduce_1.parseReduceAttributes],
['ReduceSumSquare', '', '1+', reduce_1.reduceLogSumSquare, reduce_1.parseReduceAttributes],
['Relu', '', '6+', unaryOps.relu],
['Reshape', '', '5+', reshape_1.reshape],
['Resize', '', '10', resize_packed_1.resize, resize_packed_1.parseResizeAttributesV10],
['Resize', '', '11+', resize_packed_1.resize, resize_packed_1.parseResizeAttributesV11],
['Shape', '', '1+', shape_1.shape],
['Sigmoid', '', '6+', unaryOps.sigmoid],
['Sin', '', '7+', unaryOps.sin],
['Slice', '', '10+', slice_1.sliceV10],
['Slice', '', '1-9', slice_1.slice, slice_1.parseSliceAttributes],
// The "semantic" meaning of axis has changed in opset-13.
['Softmax', '', '1-12', softmax_1.softmax, softmax_1.parseSoftmaxAttributes],
['Softmax', '', '13+', softmax_1.softmaxV13, softmax_1.parseSoftmaxAttributesV13],
// 'Split' operator has an optional attribute 'split'
// this attribute determines how the specified axis of input data is split.
// When the attribute is missing, we need the count of number of outputs
// so that we can determine the 'split' attribute from the runtime input to the Operator
['Split', '', '2-12', split_1.split, split_1.parseSplitAttributes],
['Sqrt', '', '6+', unaryOps.sqrt],
['Squeeze', '', '1-12', squeeze_1.squeeze, squeeze_1.parseSqueezeAttributes],
['Squeeze', '', '13+', squeeze_1.squeezeV13],
['Sub', '', '7+', binaryOps.sub],
['Sum', '', '6+', sum_1.sum],
['Tan', '', '7+', unaryOps.tan],
['Tanh', '', '6+', unaryOps.tanh],
['Tile', '', '6+', tile_1.tile],
['Transpose', '', '1+', transpose_1.transpose, transpose_1.parseTransposeAttributes],
['Upsample', '', '7-8', upsample_1.upsample, upsample_1.parseUpsampleAttributesV7],
['Upsample', '', '9', upsample_1.upsample, upsample_1.parseUpsampleAttributesV9],
['Unsqueeze', '', '1-12', unsqueeze_1.unsqueeze, unsqueeze_1.parseUnsqueezeAttributes],
['Unsqueeze', '', '13+', unsqueeze_1.unsqueezeV13],
['Xor', '', '7+', binaryOps.xor],
];
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/ops/batch-normalization.ts":
/*!**************************************************************!*\
!*** ./lib/onnxjs/backends/webgl/ops/batch-normalization.ts ***!
\**************************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.parseBatchNormalizationAttributes = exports.batchNormalization = void 0;
const attribute_with_cache_key_1 = __webpack_require__(/*! ../../../attribute-with-cache-key */ "./lib/onnxjs/attribute-with-cache-key.ts");
const glsl_source_1 = __webpack_require__(/*! ../glsl-source */ "./lib/onnxjs/backends/webgl/glsl-source.ts");
const types_1 = __webpack_require__(/*! ../types */ "./lib/onnxjs/backends/webgl/types.ts");
const batchNormalizationProgramMetadata = {
name: 'BatchNormalization',
inputNames: ['A', 'Scale', 'B', 'Mean', 'Variance'],
inputTypes: [types_1.TextureType.unpacked, types_1.TextureType.unpacked, types_1.TextureType.unpacked, types_1.TextureType.unpacked, types_1.TextureType.unpacked]
};
const batchNormalization = (inferenceHandler, inputs, attributes) => {
validateInputs(inputs);
const output = inferenceHandler.run(Object.assign(Object.assign({}, batchNormalizationProgramMetadata), { cacheHint: attributes.cacheKey, get: () => createBatchNormalizationProgramInfo(inferenceHandler, inputs, attributes) }), inputs);
return [output];
};
exports.batchNormalization = batchNormalization;
const parseBatchNormalizationAttributes = (node) => {
const epsilon = node.attributes.getFloat('epsilon', 1e-5);
const momentum = node.attributes.getFloat('momentum', 0.9);
const spatial = node.attributes.getInt('spatial', 1);
return (0, attribute_with_cache_key_1.createAttributeWithCacheKey)({ epsilon, momentum, spatial });
};
exports.parseBatchNormalizationAttributes = parseBatchNormalizationAttributes;
const createBatchNormalizationProgramInfo = (inferenceHandler, inputs, attributes) => {
const glsl = (0, glsl_source_1.getGlsl)(inferenceHandler.session.backend.glContext.version);
const rank = inputs[0].dims.length;
const [scaleWidth, scaleHeight] = inferenceHandler.calculateTextureWidthAndHeight(inputs[1].dims, types_1.TextureType.unpacked);
const shaderSource = `
float process(int[${rank}] indices) {
vec2 position = offsetToCoords(indices[1], ${scaleWidth}, ${scaleHeight});
float scale = getColorAsFloat(${glsl.texture2D}(Scale, position));
float mean = getColorAsFloat(${glsl.texture2D}(Mean, position));
float variance = getColorAsFloat(${glsl.texture2D}(Variance, position));
float b = getColorAsFloat(${glsl.texture2D}(B, position));
return scale * ( (_A(indices) - mean) / sqrt(variance + float(${attributes.epsilon})) ) + b;
}`;
return Object.assign(Object.assign({}, batchNormalizationProgramMetadata), { output: { dims: inputs[0].dims, type: inputs[0].type, textureType: types_1.TextureType.unpacked }, shaderSource });
};
const validateInputs = (inputs) => {
if (!inputs || inputs.length !== 5) {
throw new Error('BatchNormalization requires 5 inputs.');
}
const X = inputs[0];
const scale = inputs[1];
const B = inputs[2];
const mean = inputs[3];
const var_ = inputs[4];
// input should atleast have three dimensions - N,C,dim1,...,dimn
// other inputs can have only one dimensions
if (X.dims.length < 3 || scale.dims.length !== 1 || B.dims.length !== 1 || mean.dims.length !== 1 ||
var_.dims.length !== 1) {
throw new Error('invalid input shape.');
}
if (scale.dims[0] !== X.dims[1] || B.dims[0] !== X.dims[1] || mean.dims[0] !== X.dims[1] ||
var_.dims[0] !== X.dims[1]) {
throw new Error('invalid input shape.');
}
if ((X.type !== 'float32' && X.type !== 'float64') || (scale.type !== 'float32' && scale.type !== 'float64') ||
(B.type !== 'float32' && B.type !== 'float64') || (mean.type !== 'float32' && mean.type !== 'float64') ||
(var_.type !== 'float32' && var_.type !== 'float64')) {
throw new Error('invalid input tensor types.');
}
};
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/ops/binary-op.ts":
/*!****************************************************!*\
!*** ./lib/onnxjs/backends/webgl/ops/binary-op.ts ***!
\****************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.xor = exports.sub = exports.pRelu = exports.pow = exports.or = exports.mul = exports.less = exports.greater = exports.equal = exports.div = exports.and = exports.add = exports.glslPRelu = exports.glslPow = exports.glslXor = exports.glslOr = exports.glslAnd = exports.glslLess = exports.glslGreater = exports.glslEqual = exports.glslSub = exports.glslMul = exports.glslDiv = exports.glslAdd = void 0;
const util_1 = __webpack_require__(/*! ../../../util */ "./lib/onnxjs/util.ts");
const glsl_definitions_1 = __webpack_require__(/*! ../glsl-definitions */ "./lib/onnxjs/backends/webgl/glsl-definitions.ts");
const glsl_source_1 = __webpack_require__(/*! ../glsl-source */ "./lib/onnxjs/backends/webgl/glsl-source.ts");
const types_1 = __webpack_require__(/*! ../types */ "./lib/onnxjs/backends/webgl/types.ts");
function glslAdd() {
const name = 'add_';
const body = `
float ${name}(float a, float b) {
return a + b;
}
vec4 ${name}(vec4 v1, vec4 v2) {
return v1 + v2;
}
`;
return { body, name, type: glsl_definitions_1.FunctionType.ValueBased };
}
exports.glslAdd = glslAdd;
function glslDiv() {
const name = 'div_';
const body = `
float ${name}(float a, float b) {
return a / b;
}
vec4 ${name}(vec4 v1, vec4 v2) {
return v1 / v2;
}
`;
return { body, name, type: glsl_definitions_1.FunctionType.ValueBased };
}
exports.glslDiv = glslDiv;
function glslMul() {
const name = 'mul_';
const body = `
float ${name}(float a, float b) {
return a * b;
}
vec4 ${name}(vec4 v1, vec4 v2) {
return v1 * v2;
}
`;
return { body, name, type: glsl_definitions_1.FunctionType.ValueBased };
}
exports.glslMul = glslMul;
function glslSub() {
const name = 'sub_';
const body = `
float ${name}(float a, float b) {
return a - b;
}
vec4 ${name}(vec4 v1, vec4 v2) {
return v1 - v2;
}
`;
return { body, name, type: glsl_definitions_1.FunctionType.ValueBased };
}
exports.glslSub = glslSub;
function glslEqual() {
const name = 'equal_';
const body = `
float ${name}(float a, float b) {
return float(a == b);
}
vec4 ${name}(vec4 v1, vec4 v2) {
return vec4(equal(v1, v2));
}
`;
return { body, name, type: glsl_definitions_1.FunctionType.ValueBased };
}
exports.glslEqual = glslEqual;
function glslGreater() {
const name = 'greater_';
const body = `
float ${name}(float a, float b) {
return float(a > b);
}
vec4 ${name}(vec4 v1, vec4 v2) {
return vec4( v1.r > v2.r ,
v1.g > v2.g,
v1.b > v2.b,
v1.a > v2.a );
}
`;
return { body, name, type: glsl_definitions_1.FunctionType.ValueBased };
}
exports.glslGreater = glslGreater;
function glslLess() {
const name = 'less_';
const body = `
float ${name}(float a, float b) {
return float(a < b);
}
vec4 ${name}(vec4 v1, vec4 v2) {
return vec4( v1.r < v2.r ,
v1.g < v2.g,
v1.b < v2.b,
v1.a < v2.a );
}
`;
return { body, name, type: glsl_definitions_1.FunctionType.ValueBased };
}
exports.glslLess = glslLess;
function glslAnd() {
const name = 'and_';
const body = `
float ${name}(float a, float b) {
return float( bool(a) && bool(b) );
}
vec4 ${name}(vec4 v1, vec4 v2) {
bvec4 b1 = bvec4(v1);
bvec4 b2 = bvec4(v2);
return vec4( b1.r && b2.r ,
b1.g && b2.g,
b1.b && b2.b,
b1.a && b2.a );
}
`;
return { body, name, type: glsl_definitions_1.FunctionType.ValueBased };
}
exports.glslAnd = glslAnd;
function glslOr() {
const name = 'or_';
const body = `
float ${name}(float a, float b) {
return float( bool(a) || bool(b) );
}
vec4 ${name}(vec4 v1, vec4 v2) {
bvec4 b1 = bvec4(v1);
bvec4 b2 = bvec4(v2);
return vec4( b1.r || b2.r ,
b1.g || b2.g,
b1.b || b2.b,
b1.a || b2.a );
}
`;
return { body, name, type: glsl_definitions_1.FunctionType.ValueBased };
}
exports.glslOr = glslOr;
function glslXor() {
const name = 'xor_';
const body = `
float ${name}(float a, float b) {
return float( bool(a) ^^ bool(b) );
}
vec4 ${name}(vec4 v1, vec4 v2) {
bvec4 b1 = bvec4(v1);
bvec4 b2 = bvec4(v2);
return vec4( b1.r ^^ b2.r ,
b1.g ^^ b2.g,
b1.b ^^ b2.b,
b1.a ^^ b2.a );
}
`;
return { body, name, type: glsl_definitions_1.FunctionType.ValueBased };
}
exports.glslXor = glslXor;
function glslPow() {
return glslBuiltinBinary('pow');
}
exports.glslPow = glslPow;
function glslPRelu() {
const name = 'prelu_';
const body = `
float ${name}(float a, float b) {
return a < 0.0 ? a * b: a;
}
vec4 ${name}(vec4 v1, vec4 v2) {
return vec4(
v1.r < 0.0 ? v1.r * v2.r: v1.r,
v1.g < 0.0 ? v1.g * v2.g: v1.g,
v1.b < 0.0 ? v1.b * v2.b: v1.b,
v1.a < 0.0 ? v1.a * v2.a: v1.a
);
}
`;
return { body, name, type: glsl_definitions_1.FunctionType.ValueBased };
}
exports.glslPRelu = glslPRelu;
function glslBuiltinBinary(fname) {
const name = `${fname}_`;
const body = `
float ${name}(float a, float b) {
return ${fname}(a, b);
}
vec4 ${name}(vec4 v1, vec4 v2) {
return ${fname}(v1, v2);
}
`;
return { body, name, type: glsl_definitions_1.FunctionType.ValueBased };
}
const createBinaryProgramInfoLoader = (handler, inputs, glslFunc, outputTensorType = inputs[0].type, cacheKey) => {
const textureType = handler.session.pack ? types_1.TextureType.packed : types_1.TextureType.unpacked;
return {
name: glslFunc.name,
inputNames: ['A', 'B'],
inputTypes: [textureType, textureType],
cacheHint: cacheKey,
get: () => createBinaryProgramInfo(handler, inputs, glslFunc, outputTensorType)
};
};
const createBinaryProgramInfo = (handler, inputs, glslFunc, outputTensorType = inputs[0].type) => {
const textureType = handler.session.pack ? types_1.TextureType.packed : types_1.TextureType.unpacked;
const isBroadcast = !util_1.ShapeUtil.areEqual(inputs[0].dims, inputs[1].dims);
let outputShape = inputs[0].dims;
const usePackedTexture = handler.session.pack;
if (isBroadcast) {
const calculatedShape = util_1.BroadcastUtil.calcShape(inputs[0].dims, inputs[1].dims, false);
if (!calculatedShape) {
throw new Error('Can\'t perform binary op on the given tensors');
}
outputShape = calculatedShape;
const outputRank = outputShape.length;
const aRank = inputs[0].dims.length !== 0 ? inputs[0].dims.length : 1;
const bRank = inputs[1].dims.length !== 0 ? inputs[1].dims.length : 1;
const aBcast = inputs[0].dims.length !== 0 ? 'bcastIndices_A(indices, aindices);' : 'aindices[0] = 0;';
const bBcast = inputs[1].dims.length !== 0 ? 'bcastIndices_B(indices, bindices);' : 'bindices[0] = 0;';
const glsl = (0, glsl_source_1.getGlsl)(handler.session.backend.glContext.version);
const shaderSource = usePackedTexture ? `
${glslFunc.body}
void main() {
vec4 a = getAAtOutCoords();
vec4 b = getBAtOutCoords();
vec4 result = ${glslFunc.name}(a, b);
${glsl.output} = result;
}` :
`
${glslFunc.body}
float process(int indices[${outputRank}]) {
int aindices[${aRank}];
int bindices[${bRank}];
${aBcast}
${bBcast}
return ${glslFunc.name}(_A(aindices), _B(bindices));
}`;
return {
name: glslFunc.name,
inputNames: ['A', 'B'],
inputTypes: [textureType, textureType],
output: { dims: outputShape, type: outputTensorType, textureType },
shaderSource,
hasMain: usePackedTexture
};
}
const glsl = (0, glsl_source_1.getGlsl)(handler.session.backend.glContext.version);
const shaderSource = `
${glslFunc.body}
void main() {
vec4 v1 = ${glsl.texture2D}(A, TexCoords);
vec4 v2 = ${glsl.texture2D}(B, TexCoords);
vec4 result = ${glslFunc.name}(v1, v2);
${glsl.output} = result;
}
`;
return {
name: glslFunc.name,
inputNames: ['A', 'B'],
inputTypes: [textureType, textureType],
output: { dims: inputs[0].dims, type: outputTensorType, textureType },
shaderSource,
hasMain: true
};
};
const add = (handler, inputs) => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslAdd()), inputs)];
exports.add = add;
const and = (handler, inputs) => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslAnd(), 'bool'), inputs)];
exports.and = and;
const div = (handler, inputs) => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslDiv()), inputs)];
exports.div = div;
const equal = (handler, inputs) => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslEqual(), 'bool'), inputs)];
exports.equal = equal;
const greater = (handler, inputs) => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslGreater(), 'bool'), inputs)];
exports.greater = greater;
const less = (handler, inputs) => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslLess(), 'bool'), inputs)];
exports.less = less;
const mul = (handler, inputs) => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslMul()), inputs)];
exports.mul = mul;
const or = (handler, inputs) => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslOr(), 'bool'), inputs)];
exports.or = or;
const pow = (handler, inputs) => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslPow()), inputs)];
exports.pow = pow;
const pRelu = (handler, inputs) => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslPRelu()), inputs)];
exports.pRelu = pRelu;
const sub = (handler, inputs) => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslSub()), inputs)];
exports.sub = sub;
const xor = (handler, inputs) => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslXor(), 'bool'), inputs)];
exports.xor = xor;
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/ops/cast.ts":
/*!***********************************************!*\
!*** ./lib/onnxjs/backends/webgl/ops/cast.ts ***!
\***********************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.parseCastAttributes = exports.cast = void 0;
const util_1 = __webpack_require__(/*! ../../../util */ "./lib/onnxjs/util.ts");
const cast = (handler, inputs, to) => {
validateInputs(inputs);
return [handler.cast(inputs[0], to)];
};
exports.cast = cast;
const parseCastAttributes = (node) => util_1.ProtoUtil.tensorDataTypeFromProto(node.attributes.getInt('to'));
exports.parseCastAttributes = parseCastAttributes;
const validateInputs = (inputs) => {
if (!inputs || inputs.length !== 1) {
throw new Error('Cast requires 1 input.');
}
if (inputs[0].type === 'string') {
throw new Error('Invalid input type.');
}
};
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/ops/concat-packed.ts":
/*!********************************************************!*\
!*** ./lib/onnxjs/backends/webgl/ops/concat-packed.ts ***!
\********************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.createPackedConcatProgramInfoLoader = void 0;
const glsl_source_1 = __webpack_require__(/*! ../glsl-source */ "./lib/onnxjs/backends/webgl/glsl-source.ts");
const types_1 = __webpack_require__(/*! ../types */ "./lib/onnxjs/backends/webgl/types.ts");
const utils_1 = __webpack_require__(/*! ../utils */ "./lib/onnxjs/backends/webgl/utils.ts");
const packing_utils_1 = __webpack_require__(/*! ./packing-utils */ "./lib/onnxjs/backends/webgl/ops/packing-utils.ts");
const createPackedConcatProgramMetadata = (inputCount, cacheHint) => ({
name: 'Concat (packed)',
inputNames: Array.from({ length: inputCount }, (v, i) => `X${i}`),
inputTypes: Array(inputCount).fill(types_1.TextureType.packed),
cacheHint
});
const createPackedConcatProgramInfo = (handler, metadata, inputs, axis) => {
const inputShape = inputs[0].dims.slice();
if (axis >= inputShape.length || axis < (-1 * inputShape.length)) {
throw new Error('axis specified for concat doesn\'t match input dimensionality');
}
if (axis < 0) {
axis = inputShape.length + axis;
}
// ensure all of the non-concatenated axes match each other
// calculate the shape of the output tensor while we do that
const outputShape = inputShape.slice(0);
for (let i = 1; i < inputs.length; i++) {
const dataNShape = inputs[i].dims.slice();
for (let axisIndex = 0; axisIndex < inputShape.length; axisIndex++) {
// add to the placeholder for computing output shape
if (axisIndex === axis) {
outputShape[axis] += dataNShape[axisIndex];
}
// ensure all non-cancatenated axes match each other
else if (inputShape[axisIndex] !== dataNShape[axisIndex]) {
throw new Error('non concat dimensions must match');
}
}
}
const rank = outputShape.length;
const coords = (0, packing_utils_1.getChannels)('coords', rank);
const dtype = (0, utils_1.getCoordsDataType)(rank);
const unpackChannel = (0, packing_utils_1.unpackFromChannel)();
const shapes = inputs.map(i => i.dims);
const channels = (0, utils_1.getGlChannels)(rank);
const offsets = new Array(shapes.length - 1);
offsets[0] = shapes[0][axis];
for (let i = 1; i < offsets.length; i++) {
offsets[i] = offsets[i - 1] + shapes[i][axis];
}
const channel = channels[axis];
const lastChannels = channels.slice(-2);
const allChannels = channels.join();
let getValueSnippet = `if (${channel} < ${offsets[0]}) {
return getChannel(
getX0(${allChannels}), vec2(${lastChannels.join()}));
}`;
for (let i = 1; i < offsets.length; i++) {
const shift = offsets[i - 1];
getValueSnippet += `
if (${channel} < ${offsets[i]} && ${channel} >= ${offsets[i - 1]}) {
return getChannel(
getX${i}(${getShiftedChannelsSnippet(channels, channel, shift)}),
vec2(${getShiftedChannelsSnippet(lastChannels, channel, shift)}));
}`;
}
const lastIndex = offsets.length;
const shift = offsets[offsets.length - 1];
getValueSnippet += `
return getChannel(
getX${lastIndex}(${getShiftedChannelsSnippet(channels, channel, shift)}),
vec2(${getShiftedChannelsSnippet(lastChannels, channel, shift)}));`;
const glsl = (0, glsl_source_1.getGlsl)(handler.session.backend.glContext.version);
const shaderSource = `
${unpackChannel}
float getValue(${channels.map(x => 'int ' + x)}) {
${getValueSnippet}
}
void main() {
${dtype} coords = getOutputCoords();
int lastDim = coords.${channels[rank - 1]};
coords.${channels[rank - 1]} = coords.${channels[rank - 2]};
coords.${channels[rank - 2]} = lastDim;
vec4 result = vec4(getValue(${coords}), 0., 0., 0.);
${coords[rank - 1]} = ${coords[rank - 1]} + 1;
if (${coords[rank - 1]} < ${outputShape[rank - 1]}) {
result.g = getValue(${coords});
}
${coords[rank - 2]} = ${coords[rank - 2]} + 1;
if (${coords[rank - 2]} < ${outputShape[rank - 2]}) {
result.a = getValue(${coords});
}
${coords[rank - 1]} = ${coords[rank - 1]} - 1;
if (${coords[rank - 2]} < ${outputShape[rank - 2]} &&
${coords[rank - 1]} < ${outputShape[rank - 1]}) {
result.b = getValue(${coords});
}
${glsl.output} = result;
}
`;
return Object.assign(Object.assign({}, metadata), { output: { dims: outputShape, type: inputs[0].type, textureType: types_1.TextureType.packed }, shaderSource, hasMain: true });
};
const createPackedConcatProgramInfoLoader = (handler, inputs, attributes) => {
const metadata = createPackedConcatProgramMetadata(inputs.length, attributes.cacheKey);
return Object.assign(Object.assign({}, metadata), { get: () => createPackedConcatProgramInfo(handler, metadata, inputs, attributes.axis) });
};
exports.createPackedConcatProgramInfoLoader = createPackedConcatProgramInfoLoader;
const getShiftedChannelsSnippet = (channels, channel, shift) => {
const channelIdx = channels.indexOf(channel);
const res = channels.map((c, idx) => {
if (idx === channelIdx) {
return `${c} - ${shift}`;
}
else {
return c;
}
});
return res.join();
};
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/ops/concat.ts":
/*!*************************************************!*\
!*** ./lib/onnxjs/backends/webgl/ops/concat.ts ***!
\*************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.parseConcatAttributes = exports.concat = void 0;
const attribute_with_cache_key_1 = __webpack_require__(/*! ../../../attribute-with-cache-key */ "./lib/onnxjs/attribute-with-cache-key.ts");
const types_1 = __webpack_require__(/*! ../types */ "./lib/onnxjs/backends/webgl/types.ts");
const concat_packed_1 = __webpack_require__(/*! ./concat-packed */ "./lib/onnxjs/backends/webgl/ops/concat-packed.ts");
const concat = (inferenceHandler, inputs, attributes) => {
validateInputs(inputs);
if (inferenceHandler.session.pack && inputs[0].dims.length > 1) {
const output = inferenceHandler.run((0, concat_packed_1.createPackedConcatProgramInfoLoader)(inferenceHandler, inputs, attributes), inputs);
return [output];
}
else {
const output = inferenceHandler.run(createUnpackedConcatProgramInfoLoader(inferenceHandler, inputs, attributes), inputs);
return [output];
}
};
exports.concat = concat;
const createUnpackedConcatProgramMetadata = (inputCount, cacheHint) => ({
name: 'Concat',
inputNames: Array.from({ length: inputCount }, (v, i) => `X${i}`),
inputTypes: Array(inputCount).fill(types_1.TextureType.unpacked),
cacheHint
});
const createUnpackedConcatProgramInfo = (handler, metadata, inputs, axis) => {
const inputShape = inputs[0].dims.slice();
if (axis >= inputShape.length || axis < (-1 * inputShape.length)) {
throw new Error('axis specified for concat doesn\'t match input dimensionality');
}
if (axis < 0) {
axis = inputShape.length + axis;
}
// ensure all of the non-concatenated axes match each other
// calculate the shape of the output tensor while we do that
const outputShape = inputShape.slice(0);
for (let i = 1; i < inputs.length; i++) {
const dataNShape = inputs[i].dims.slice();
for (let axisIndex = 0; axisIndex < inputShape.length; axisIndex++) {
// add to the placeholder for computing output shape
if (axisIndex === axis) {
outputShape[axis] += dataNShape[axisIndex];
}
// ensure all non-cancatenated axes match each other
else if (inputShape[axisIndex] !== dataNShape[axisIndex]) {
throw new Error('non concat dimensions must match');
}
}
}
const rank = outputShape.length;
const sizeInConcatAxis = new Array(inputs.length);
let previousSum = 0;
for (let i = 0; i < sizeInConcatAxis.length; ++i) {
previousSum += inputs[i].dims[axis];
sizeInConcatAxis[i] = previousSum;
}
let getTextureIndexWhereDataResidesMethod = '';
// in most cases linear search is sufficient, as in most scenarios, only 2 tensors are concatenated
if (inputs.length < 5) {
getTextureIndexWhereDataResidesMethod = getTextureIndexWhereDataResidesLinearSearch(sizeInConcatAxis);
}
else {
getTextureIndexWhereDataResidesMethod = getTextureIndexWhereDataResidesBinarySearch(sizeInConcatAxis);
}
const fetchDataFromCorrectTextureMethod = getFetchDataFromCorrectTextureMethod(inputs.length, rank);
const getSizeInConcatAxisValueFromIndexMethod = getGetSizeInConcatAxisValueFromIndexMethod(sizeInConcatAxis);
const shaderSource = `
${fetchDataFromCorrectTextureMethod}
${getSizeInConcatAxisValueFromIndexMethod}
${getTextureIndexWhereDataResidesMethod}
float process(int indices[${rank}]) {
int textureIndex = getTextureWhereDataResides (indices[${axis}]);
if(textureIndex != 0) {
indices[${axis}] = indices[${axis}] - int(getSizeInConcatAxisValueFromIndex(textureIndex-int(1)));
}
return fetchDataFromCorrectTexture(textureIndex, indices);
}`;
return Object.assign(Object.assign({}, metadata), { output: { dims: outputShape, type: inputs[0].type, textureType: types_1.TextureType.unpacked }, shaderSource });
};
const createUnpackedConcatProgramInfoLoader = (handler, inputs, attributes) => {
const metadata = createUnpackedConcatProgramMetadata(inputs.length, attributes.cacheKey);
return Object.assign(Object.assign({}, metadata), { get: () => createUnpackedConcatProgramInfo(handler, metadata, inputs, attributes.axis) });
};
const getTextureIndexWhereDataResidesLinearSearch = (sizeInConcatAxis) => {
const searchAxis = sizeInConcatAxis.map((size, i) => `if(index<${size}) {return ${i};}
`);
return `int getTextureWhereDataResides(int index) {
${searchAxis.join('')}
}`;
};
// TODO: Implement BinarySearch in GLSL
const getTextureIndexWhereDataResidesBinarySearch = (sizeInConcatAxis) => getTextureIndexWhereDataResidesLinearSearch(sizeInConcatAxis);
const getFetchDataFromCorrectTextureMethod = (numberOfTensors, tensorRank) => {
const codeLines = [`float fetchDataFromCorrectTexture(int textureIndex, int indices[${tensorRank}]) {`];
for (let i = 0; i < numberOfTensors; ++i) {
if (i === 0) {
codeLines.push('\t' +
`if (textureIndex == ${i}) { return _X${i}(indices); }`);
}
else if (i === numberOfTensors - 1) {
codeLines.push('\t' +
`else { return _X${i}(indices); }`);
}
else {
codeLines.push('\t' +
`else if (textureIndex == ${i}) { return _X${i}(indices); }`);
}
}
codeLines.push('\t' +
'}');
return codeLines.join('\n');
};
const getGetSizeInConcatAxisValueFromIndexMethod = (sizeInConcatAxis) => {
const codeLines = ['int getSizeInConcatAxisValueFromIndex(int index) {'];
for (let i = 0; i < sizeInConcatAxis.length; ++i) {
if (i === 0) {
codeLines.push('\t' +
`if (index == ${i}) { return ${sizeInConcatAxis[i]}; }`);
}
else if (i === sizeInConcatAxis.length - 1) {
codeLines.push('\t' +
`else { return ${sizeInConcatAxis[i]}; }`);
}
else {
codeLines.push('\t' +
`else if (index == ${i}) { return ${sizeInConcatAxis[i]}; }`);
}
}
codeLines.push('\t' +
'}');
return codeLines.join('\n');
};
const parseConcatAttributes = (node) => (0, attribute_with_cache_key_1.createAttributeWithCacheKey)({ axis: node.attributes.getInt('axis') });
exports.parseConcatAttributes = parseConcatAttributes;
const validateInputs = (inputs) => {
if (!inputs || inputs.length < 1) {
throw new Error('too few inputs');
}
const inputType = inputs[0].type;
const inputDimensionality = inputs[0].dims.length;
// TODO: Support string concat
if (inputType === 'string') {
throw new Error('string tensor is not supported yet');
}
for (const input of inputs) {
// make sure types of all inputs match
if (input.type !== inputType) {
throw new Error('input tensors should be one type');
}
// make sure the dimensionality of all inputs are the same
if (input.dims.length !== inputDimensionality) {
throw new Error('input tensors should have the same shape');
}
}
};
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/ops/conv-grouped.ts":
/*!*******************************************************!*\
!*** ./lib/onnxjs/backends/webgl/ops/conv-grouped.ts ***!
\*******************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.createUnpackedGroupedConvProgramInfoLoader = void 0;
const instrument_1 = __webpack_require__(/*! ../../../instrument */ "./lib/onnxjs/instrument.ts");
const glsl_source_1 = __webpack_require__(/*! ../glsl-source */ "./lib/onnxjs/backends/webgl/glsl-source.ts");
const types_1 = __webpack_require__(/*! ../types */ "./lib/onnxjs/backends/webgl/types.ts");
const conv_1 = __webpack_require__(/*! ./conv */ "./lib/onnxjs/backends/webgl/ops/conv.ts");
const fuse_utils_1 = __webpack_require__(/*! ./fuse-utils */ "./lib/onnxjs/backends/webgl/ops/fuse-utils.ts");
const createUnpackedGroupedConvProgramMetadata = (hasBias, cacheHint) => ({
name: 'GroupedConv',
inputNames: hasBias ? ['X', 'W', 'Bias'] : ['X', 'W'],
inputTypes: hasBias ? [types_1.TextureType.unpacked, types_1.TextureType.unpacked, types_1.TextureType.unpacked] :
[types_1.TextureType.unpacked, types_1.TextureType.unpacked],
cacheHint
});
const createUnpackedGroupedConvProgramInfo = (inferenceHandler, inputs, metadata, attributes) => {
const hasBias = inputs.length > 2;
const processBias = hasBias ? 'value += getBias(output_channel);' : '';
const xShape = inputs[0].dims.slice();
const wShape = inputs[1].dims.slice();
const outputChannelsPerGroup = wShape[0] / attributes.group;
instrument_1.Logger.verbose('GroupedConv', `autpPad:${attributes.autoPad}, dilations:${attributes.dilations}, group:${attributes.group}, kernelShape:${attributes.kernelShape}, pads:${attributes.pads}, strides:${attributes.strides}`);
const outputShape = (0, conv_1.calculateOutputShape)(xShape, wShape, attributes.dilations, attributes.pads, attributes.strides);
const glsl = (0, glsl_source_1.getGlsl)(inferenceHandler.session.backend.glContext.version);
const { activationFunction, applyActivation } = (0, fuse_utils_1.getActivationSnippet)(attributes);
const shaderSource = `
const ivec2 strides = ivec2(${attributes.strides[0]}, ${attributes.strides[1]});
const ivec2 pads = ivec2(${attributes.pads[0]}, ${attributes.pads[1]});
${activationFunction}
void main() {
ivec4 coords = getOutputCoords();
int batch = coords.x;
int output_channel = coords.y;
ivec2 xRCCorner = coords.zw * strides - pads;
int group_id = output_channel / ${outputChannelsPerGroup};
float value = 0.0;
for (int wInChannel = 0; wInChannel < ${wShape[1]}; wInChannel++) {
int input_channel = group_id * ${wShape[1]} + wInChannel;
for (int wHeight = 0; wHeight < ${wShape[2]}; wHeight++) {
int xHeight = xRCCorner.x + wHeight * ${attributes.dilations[0]};
if (xHeight < 0 || xHeight >= ${xShape[2]}) {
continue;
}
for (int wWidth = 0; wWidth < ${wShape[3]}; wWidth++) {
int xWidth = xRCCorner.y + wWidth * ${attributes.dilations[1]};
if (xWidth < 0 || xWidth >= ${xShape[3]}) {
continue;
}
float xVal = getX(batch, input_channel, xWidth, xHeight);
float wVal = getW(output_channel, wInChannel, wWidth, wHeight);
value += xVal*wVal;
}
}
}
${processBias}
${applyActivation}
${glsl.output} = vec4(value, .0, .0, .0);
}
`;
return Object.assign(Object.assign({}, metadata), { output: { dims: outputShape, type: inputs[0].type, textureType: types_1.TextureType.unpacked }, shaderSource, hasMain: true });
};
const createUnpackedGroupedConvProgramInfoLoader = (inferenceHandler, inputs, attributes) => {
const metadata = createUnpackedGroupedConvProgramMetadata(inputs.length > 2, attributes.cacheKey);
return Object.assign(Object.assign({}, metadata), { get: () => createUnpackedGroupedConvProgramInfo(inferenceHandler, inputs, metadata, attributes) });
};
exports.createUnpackedGroupedConvProgramInfoLoader = createUnpackedGroupedConvProgramInfoLoader;
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/ops/conv-pack.ts":
/*!****************************************************!*\
!*** ./lib/onnxjs/backends/webgl/ops/conv-pack.ts ***!
\****************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.conv2DPacked = exports.conv2DPackedPointwise = void 0;
const conv_1 = __webpack_require__(/*! ./conv */ "./lib/onnxjs/backends/webgl/ops/conv.ts");
const im2col_pack_1 = __webpack_require__(/*! ./im2col-pack */ "./lib/onnxjs/backends/webgl/ops/im2col-pack.ts");
const matmul_pack_1 = __webpack_require__(/*! ./matmul-pack */ "./lib/onnxjs/backends/webgl/ops/matmul-pack.ts");
const conv2DPackedPointwise = (inferenceHandler, inputs, attributes) => {
const xshape = inputs[0].dims;
const kshape = inputs[1].dims;
const outputShape = (0, conv_1.calculateOutputShape)(xshape, kshape, attributes.dilations, attributes.pads, attributes.strides);
const reshapedX = inferenceHandler.reshapePacked(inputs[0], [xshape[1], xshape[2] * xshape[3]]);
const reshapedK = inferenceHandler.reshapePacked(inputs[1], [kshape[0], kshape[1]]);
const matmulInputs = inputs.length > 2 ? [reshapedK, reshapedX, inputs[2]] : [reshapedK, reshapedX];
const matmulOutput = inferenceHandler.run((0, matmul_pack_1.createPackedMatmulProgramInfoLoader)(inferenceHandler, matmulInputs, attributes), matmulInputs);
return inferenceHandler.reshapePacked(matmulOutput, outputShape);
};
exports.conv2DPackedPointwise = conv2DPackedPointwise;
const conv2DPacked = (inferenceHandler, inputs, attributes) => {
const xshape = inputs[0].dims;
const kshape = inputs[1].dims;
const outputShape = (0, conv_1.calculateOutputShape)(xshape, kshape, attributes.dilations, attributes.pads, attributes.strides);
// run im2col
const im2colOutput = inferenceHandler.run((0, im2col_pack_1.createPackedIm2ColProgramInfoLoader)(inferenceHandler, inputs[0], inputs[1], outputShape, attributes), [inputs[0]]);
// reshape kernel
const kernelReshaped = inferenceHandler.reshapePacked(inputs[1], [kshape[0], kshape[1] * kshape[2] * kshape[3]]);
// run matmul
const matmulInputs = (inputs.length === 3) ? [kernelReshaped, im2colOutput, inputs[2]] : [kernelReshaped, im2colOutput];
const matmulOutput = inferenceHandler.run((0, matmul_pack_1.createPackedMatmulProgramInfoLoader)(inferenceHandler, matmulInputs, attributes), matmulInputs);
// reshape output
const outputReshaped = inferenceHandler.reshapePacked(matmulOutput, outputShape);
return outputReshaped;
};
exports.conv2DPacked = conv2DPacked;
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/ops/conv-transpose.ts":
/*!*********************************************************!*\
!*** ./lib/onnxjs/backends/webgl/ops/conv-transpose.ts ***!
\*********************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.parseConvTransposeAttributes = exports.convTranspose = void 0;
const attribute_with_cache_key_1 = __webpack_require__(/*! ../../../attribute-with-cache-key */ "./lib/onnxjs/attribute-with-cache-key.ts");
const glsl_source_1 = __webpack_require__(/*! ../glsl-source */ "./lib/onnxjs/backends/webgl/glsl-source.ts");
const types_1 = __webpack_require__(/*! ../types */ "./lib/onnxjs/backends/webgl/types.ts");
const fuse_utils_1 = __webpack_require__(/*! ./fuse-utils */ "./lib/onnxjs/backends/webgl/ops/fuse-utils.ts");
const computeTotalPad = (inDim, stride, adj, kernel, dilation, outSize) => (inDim - 1) * stride + adj + (kernel - 1) * dilation + 1 - outSize;
const distributePadding = (totalPad, autoPad, pads, head, tail) => {
const smallPad = Math.floor(totalPad / 2);
if (autoPad === 'SAME_UPPER') {
pads[head] = smallPad;
pads[tail] = totalPad - smallPad;
}
else if (autoPad === 'SAME_LOWER') {
pads[head] = totalPad - smallPad;
pads[tail] = smallPad;
}
};
const calculateOutputShapeAndPads = (inputShape, kernelShape, dilations, autoPad, pads, strides, outputPadding, outputShape) => {
const spatialRank = inputShape.length - 2;
const updateShape = outputShape.length === 0;
for (let i = 0; i < spatialRank; ++i) {
const outSize = updateShape ? inputShape[i + 2] * strides[i] : outputShape[i];
const totalPad = computeTotalPad(inputShape[i + 2], strides[i], pads[i], kernelShape[i], dilations[i], outSize);
distributePadding(totalPad, autoPad, pads, i, i + spatialRank);
if (updateShape) {
outputShape.push(strides[i] * (inputShape[i + 2] - 1) + outputPadding[i] + (kernelShape[i] - 1) * dilations[i] + 1 -
pads[i] - pads[i + spatialRank]);
}
}
};
const convTranspose = (inferenceHandler, inputs, attributes) => {
validateInputs(inputs, attributes); // currently will fail if not convTranspose2D
return convTranspose2d(inferenceHandler, inputs, attributes);
};
exports.convTranspose = convTranspose;
const convTranspose2d = (inferenceHandler, inputs, attributes) => {
const adjustedAttributes = getAdjustedConvTransposeAttributes(attributes, inputs);
return [convTranspose2DUnpacked(inferenceHandler, inputs, adjustedAttributes)];
};
const createConvTransposeProgramMetadata = (hasBias, cacheHint) => ({
name: 'ConvTranspose',
inputNames: hasBias ? ['X', 'W', 'B'] : ['X', 'W'],
inputTypes: hasBias ? [types_1.TextureType.unpacked, types_1.TextureType.unpacked, types_1.TextureType.unpacked] :
[types_1.TextureType.unpacked, types_1.TextureType.unpacked],
cacheHint
});
const createUnpackedConvTransposeProgramInfo = (inferenceHandler, inputs, metadata, attributes) => {
const hasBias = inputs.length > 2;
const valueInit = hasBias ? 'getB(output_channel)' : '0.0';
const xShape = inputs[0].dims;
const wShape = inputs[1].dims;
const outputChannelsPerGroup = wShape[1];
const inputChannelsPerGroup = wShape[0] / attributes.group;
const outputShape = [inputs[0].dims[0], inputs[1].dims[1] * attributes.group, ...attributes.outputShape];
const glsl = (0, glsl_source_1.getGlsl)(inferenceHandler.session.backend.glContext.version);
const { activationFunction, applyActivation } = (0, fuse_utils_1.getActivationSnippet)(attributes);
const shaderSource = `
const ivec2 strides = ivec2(${attributes.strides[0]}, ${attributes.strides[1]});
const ivec2 pads = ivec2(${attributes.pads[0]}, ${attributes.pads[1]});
${activationFunction}
void main() {
ivec4 coords = getOutputCoords();
int batch = coords.x;
int output_channel = coords.y;
ivec2 loc = coords.zw + pads;
int group_id = output_channel / ${outputChannelsPerGroup};
int wOutChannel = output_channel - group_id * ${outputChannelsPerGroup};
float value = ${valueInit};
for (int inChannelOffset = 0; inChannelOffset < ${inputChannelsPerGroup}; inChannelOffset++) {
int input_channel = group_id * ${inputChannelsPerGroup} + inChannelOffset;
for (int wWOff = 0; wWOff < ${wShape[2]}; wWOff++) {
for (int wHOff = 0; wHOff < ${wShape[3]}; wHOff++) {
ivec2 wOff = ivec2(wWOff * ${attributes.dilations[0]}, wHOff * ${attributes.dilations[1]});
ivec2 wLoc = loc - wOff;
ivec2 wLocIn = wLoc / strides;
if (
wLocIn * strides == wLoc &&
wLocIn.x >= 0 && wLocIn.x < ${xShape[2]} &&
wLocIn.y >= 0 && wLocIn.y < ${xShape[3]}
) {
float xVal = getX(batch, input_channel, wLocIn.y, wLocIn.x);
float wVal = getW(input_channel, wOutChannel, wHOff, wWOff);
value += xVal * wVal;
}
}
}
}
${applyActivation}
${glsl.output} = vec4(value, .0, .0, .0);
}
`;
return Object.assign(Object.assign({}, metadata), { output: { dims: outputShape, type: inputs[0].type, textureType: types_1.TextureType.unpacked }, shaderSource, hasMain: true });
};
const createUnpackedConvTransposeProgramInfoLoader = (inferenceHandler, inputs, attributes) => {
const metadata = createConvTransposeProgramMetadata(inputs.length > 2, attributes.cacheKey);
return Object.assign(Object.assign({}, metadata), { get: () => createUnpackedConvTransposeProgramInfo(inferenceHandler, inputs, metadata, attributes) });
};
const convTranspose2DUnpacked = (inferenceHandler, inputs, attributes) => {
const result = inferenceHandler.run(createUnpackedConvTransposeProgramInfoLoader(inferenceHandler, inputs, attributes), inputs);
return result;
};
const getAdjustedConvTransposeAttributes = (attributes, inputs) => {
const kernelShape = attributes.kernelShape.slice();
// if kernelShape is not specified in the attributes of this op, infer it from the weight tensor dims
if (attributes.kernelShape.length === 0) {
for (let i = 2; i < inputs[1].dims.length; ++i) {
kernelShape.push(inputs[1].dims[i]);
}
}
const pads = attributes.pads.slice();
const outputShape = attributes.outputShape.slice();
const inputShape = inputs[0].dims;
// If outputShape is not specified in the attributes of this op, infer it from the parameters
// Similarly, automatically infer pads if not specified
calculateOutputShapeAndPads(inputShape, kernelShape, attributes.dilations, attributes.autoPad, pads, attributes.strides, attributes.outputPadding, outputShape);
// always return a new object so does not modify the original attributes
const newAttributes = Object.assign({}, attributes);
Object.assign(newAttributes, { kernelShape, pads, outputShape, cacheKey: attributes.cacheKey });
return newAttributes;
};
const parseConvTransposeAttributes = (node) => {
const attributes = node.attributes;
const activationAttributes = (0, fuse_utils_1.parseInternalActivationAttributes)(attributes);
// TODO : Make this generic enough to compute default attributes for multi-dimensional conv
const autoPad = attributes.getString('auto_pad', 'NOTSET');
const dilations = attributes.getInts('dilations', [1, 1]);
const group = attributes.getInt('group', 1);
const kernelShape = attributes.getInts('kernel_shape', []);
const outputPadding = attributes.getInts('output_padding', [0, 0]);
const outputShape = attributes.getInts('output_shape', []);
const pads = attributes.getInts('pads', [0, 0, 0, 0]);
const strides = attributes.getInts('strides', [1, 1]);
return (0, attribute_with_cache_key_1.createAttributeWithCacheKey)(Object.assign({ autoPad, dilations, group, kernelShape, outputPadding, outputShape, pads, strides }, activationAttributes));
};
exports.parseConvTransposeAttributes = parseConvTransposeAttributes;
const validateInputs = (inputs, attributes) => {
// Refer to the below link for all input checks
// https://github.com/onnx/onnx/blob/main/docs/Operators.md#Conv
if (!inputs || (inputs.length !== 2 && inputs.length !== 3)) {
throw new Error('Conv requires 2 or 3 inputs');
}
// TODO : Need to add support for multi-dimensional conv
if (inputs[0].dims.length !== 4 || inputs[1].dims.length !== 4) {
throw new Error('currently only support 2-dimensional conv');
}
// FILTER_IN_CHANNEL should be equal to DATA_CHANNEL
const dataChannel = inputs[0].dims[1];
const filterInChannel = inputs[1].dims[0];
if (dataChannel !== filterInChannel) {
throw new Error('FILTER_IN_CHANNEL should be equal to DATA_CHANNEL');
}
const featureMaps = inputs[1].dims[1] * attributes.group;
// if bias is provided it should be 1D and the number of elements should be equal to the number of feature maps
if (inputs.length === 3 && (inputs[2].dims.length !== 1 || inputs[2].dims[0] !== featureMaps)) {
throw new Error('invalid bias');
}
const spatialRank = inputs[0].dims.length - 2;
// wrong dilations dimension
if (attributes.dilations.length !== spatialRank) {
throw new Error(`dilations should be ${spatialRank}D`);
}
// Wrong strides dimension
if (attributes.strides.length !== spatialRank) {
throw new Error(`strides should be ${spatialRank}D`);
}
// Wrong pads dimension
if (attributes.pads.length !== spatialRank * 2) {
throw new Error(`pads should be ${spatialRank * 2}D`);
}
// Wrong output padding dimension
if (attributes.outputPadding.length !== spatialRank) {
throw new Error(`output_padding should be ${spatialRank}D`);
}
// if kernelShape is specified, it's data length must be 2 less than dims length of the weights tensor
// (the first 2 dims are batch_size and channels)
if (attributes.kernelShape.length !== 0 && attributes.kernelShape.length !== inputs[1].dims.length - 2) {
throw new Error('invalid kernel shape');
}
// as with kernelShape, must have same number of spatial dims as input
if (attributes.outputShape.length !== 0 && attributes.outputShape.length !== inputs[0].dims.length - 2) {
throw new Error('invalid output shape');
}
// TODO : Need to add support for float64
if (inputs[0].type !== 'float32' || inputs[1].type !== 'float32') {
throw new Error('ConvTranspose input(X,W) should be float tensor');
}
if (inputs.length === 3 && inputs[2].type !== 'float32') {
throw new Error('ConvTranspose input(bias) should be float tensor');
}
};
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/ops/conv.ts":
/*!***********************************************!*\
!*** ./lib/onnxjs/backends/webgl/ops/conv.ts ***!
\***********************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.parseConvAttributes = exports.conv = exports.calculateOutputShape = void 0;
const attribute_with_cache_key_1 = __webpack_require__(/*! ../../../attribute-with-cache-key */ "./lib/onnxjs/attribute-with-cache-key.ts");
const util_1 = __webpack_require__(/*! ../../../util */ "./lib/onnxjs/util.ts");
const conv_grouped_1 = __webpack_require__(/*! ./conv-grouped */ "./lib/onnxjs/backends/webgl/ops/conv-grouped.ts");
const conv_pack_1 = __webpack_require__(/*! ./conv-pack */ "./lib/onnxjs/backends/webgl/ops/conv-pack.ts");
const dot_product_1 = __webpack_require__(/*! ./dot-product */ "./lib/onnxjs/backends/webgl/ops/dot-product.ts");
const fuse_utils_1 = __webpack_require__(/*! ./fuse-utils */ "./lib/onnxjs/backends/webgl/ops/fuse-utils.ts");
const im2col_1 = __webpack_require__(/*! ./im2col */ "./lib/onnxjs/backends/webgl/ops/im2col.ts");
const matmul_1 = __webpack_require__(/*! ./matmul */ "./lib/onnxjs/backends/webgl/ops/matmul.ts");
const calculateOutputShape = (inputShape, kernelShape, dilations, adjustPads, strides) => {
const batchSize = inputShape[0];
const inputSpatialShape = inputShape.slice(2);
const spatialRank = inputSpatialShape.length;
const outChannels = kernelShape[0];
const kernelSpatialShape = kernelShape.slice(2);
const dilatedKernelShape = kernelSpatialShape.map((v, i) => v + (v - 1) * (dilations[i] - 1));
const inputSpatialShapeWithPad = inputSpatialShape.map((v, i) => v + adjustPads[i] + adjustPads[i + spatialRank]);
const outputSpatialShape = inputSpatialShapeWithPad.map((v, i) => Math.floor((v - dilatedKernelShape[i] + strides[i]) / strides[i]));
const outputShape = [batchSize, outChannels].concat(...outputSpatialShape);
return outputShape;
};
exports.calculateOutputShape = calculateOutputShape;
const conv = (inferenceHandler, inputs, attributes) => {
validateInputs(inputs, attributes); // currently will fail if not conv2D
return conv2d(inferenceHandler, inputs, attributes);
};
exports.conv = conv;
const conv2d = (inferenceHandler, inputs, attributes) => {
const adjustedAttributes = getAdjustedConvAttributes(attributes, inputs);
const packMode = inferenceHandler.session.pack;
const isPointwise = adjustedAttributes.kernelShape[0] === 1 && adjustedAttributes.kernelShape[1] === 1;
if (adjustedAttributes.group > 1) {
const result = inferenceHandler.run((0, conv_grouped_1.createUnpackedGroupedConvProgramInfoLoader)(inferenceHandler, inputs, adjustedAttributes), inputs);
return [result];
}
else if (isPointwise && packMode) {
return [conv2DUnpackedPointwise(inferenceHandler, inputs, adjustedAttributes)];
}
else if (packMode && inputs[0].dims.length === 4 && inputs[0].dims[0] === 1 && !isPointwise) {
return [(0, conv_pack_1.conv2DPacked)(inferenceHandler, inputs, adjustedAttributes)];
}
else {
return [conv2DUnpacked(inferenceHandler, inputs, adjustedAttributes)];
}
};
const conv2DUnpackedPointwise = (inferenceHandler, inputs, attributes) => {
const xshape = inputs[0].dims;
const kshape = inputs[1].dims;
const outputShape = (0, exports.calculateOutputShape)(xshape, kshape, attributes.dilations, attributes.pads, attributes.strides);
const reshapedX = inferenceHandler.reshapeUnpacked(inputs[0], [xshape[1], xshape[2] * xshape[3]]);
const reshapedK = inferenceHandler.reshapeUnpacked(inputs[1], [kshape[0], kshape[1]]);
const matmulInputs = inputs.length > 2 ? [reshapedK, reshapedX, inputs[2]] : [reshapedK, reshapedX];
const matmulOutput = inferenceHandler.run((0, matmul_1.createMatmulProgramInfoLoader)(matmulInputs, attributes), matmulInputs);
return inferenceHandler.reshapeUnpacked(matmulOutput, outputShape);
};
const conv2DUnpacked = (inferenceHandler, inputs, attributes) => {
const xshape = inputs[0].dims;
const kshape = inputs[1].dims;
const outputShape = (0, exports.calculateOutputShape)(xshape, kshape, attributes.dilations, attributes.pads, attributes.strides);
const xIm2Col = inferenceHandler.run((0, im2col_1.createIm2ColProgramInfoLoader)(inferenceHandler, inputs[0], inputs[1], outputShape, attributes), [inputs[0]]);
const dotProductInputs = inputs.length === 3 ? [xIm2Col, inputs[1], inputs[2]] : [xIm2Col, inputs[1]];
const output = inferenceHandler.run((0, dot_product_1.createDotProductProgramInfoLoader)(inferenceHandler, inputs, outputShape, attributes), dotProductInputs);
return output;
};
const getAdjustedConvAttributes = (attributes, inputs) => {
const kernelShape = attributes.kernelShape.slice();
// if kernelShape is not specified in the attributes of this op, infer it from the weight tensor dims
if (attributes.kernelShape.length === 0) {
for (let i = 2; i < inputs[1].dims.length; ++i) {
kernelShape.push(inputs[1].dims[i]);
}
}
const pads = attributes.pads.slice();
util_1.PoolConvUtil.adjustPadsBasedOnAutoPad(inputs[0].dims, attributes.strides, attributes.dilations, kernelShape, pads, attributes.autoPad);
// always return a new object so does not modify the original attributes
const newAttributes = Object.assign({}, attributes);
Object.assign(newAttributes, { kernelShape, pads, cacheKey: attributes.cacheKey });
return newAttributes;
};
const parseConvAttributes = (node) => {
const attributes = node.attributes;
const activationAttributes = (0, fuse_utils_1.parseInternalActivationAttributes)(attributes);
// TODO : Make this generic enough to compute default attributes for multi-dimensional conv
const autoPad = attributes.getString('auto_pad', 'NOTSET');
const dilations = attributes.getInts('dilations', [1, 1]);
const group = attributes.getInt('group', 1);
const kernelShape = attributes.getInts('kernel_shape', []);
const pads = attributes.getInts('pads', [0, 0, 0, 0]);
const strides = attributes.getInts('strides', [1, 1]);
return (0, attribute_with_cache_key_1.createAttributeWithCacheKey)(Object.assign({ autoPad, dilations, group, kernelShape, pads, strides }, activationAttributes));
};
exports.parseConvAttributes = parseConvAttributes;
const validateInputs = (inputs, attributes) => {
// Refer to the below link for all input checks
// https://github.com/onnx/onnx/blob/main/docs/Operators.md#Conv
if (!inputs || (inputs.length !== 2 && inputs.length !== 3)) {
throw new Error('Conv requires 2 or 3 inputs');
}
// TODO : Need to add support for multi-dimensional conv
if (inputs[0].dims.length !== 4 || inputs[1].dims.length !== 4) {
throw new Error('currently only support 2-dimensional conv');
}
// FILTER_IN_CHANNEL should be equal to DATA_CHANNEL
const dataChannel = inputs[0].dims[1];
const filterInChannel = inputs[1].dims[1] * attributes.group;
if (dataChannel !== filterInChannel) {
throw new Error('FILTER_IN_CHANNEL should be equal to DATA_CHANNEL');
}
// if bias is provided it should be 1D and the number of elements should be equal to the number of feature maps
if (inputs.length === 3 && (inputs[2].dims.length !== 1 || inputs[1].dims[0] !== inputs[2].dims[0])) {
throw new Error('invalid bias');
}
const spatialRank = inputs[0].dims.length - 2;
// wrong dilations dimension
if (attributes.dilations.length !== spatialRank) {
throw new Error(`dilations should be ${spatialRank}D`);
}
// Wrong strides dimension
if (attributes.strides.length !== spatialRank) {
throw new Error(`strides should be ${spatialRank}D`);
}
// Wrong pads dimension
if (attributes.pads.length !== spatialRank * 2) {
throw new Error(`pads should be ${spatialRank * 2}D`);
}
// if kernelShape is specified, it's data length must be 2 less than dims length of the weights tensor
// (the first 2 dims are batch_size and channels)
if (attributes.kernelShape.length !== 0 && attributes.kernelShape.length !== inputs[1].dims.length - 2) {
throw new Error('invalid kernel shape');
}
// TODO : Need to add support for float64
if (inputs[0].type !== 'float32' || inputs[1].type !== 'float32') {
throw new Error('Conv input(X,W) should be float tensor');
}
if (inputs.length === 3 && inputs[2].type !== 'float32') {
throw new Error('Conv input(bias) should be float tensor');
}
};
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/ops/depth-to-space.ts":
/*!*********************************************************!*\
!*** ./lib/onnxjs/backends/webgl/ops/depth-to-space.ts ***!
\*********************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.parseDepthToSpaceAttributes = exports.depthToSpace = void 0;
const transpose_1 = __webpack_require__(/*! ./transpose */ "./lib/onnxjs/backends/webgl/ops/transpose.ts");
const depthToSpace = (inferenceHandler, inputs, attributes) => {
validateInputs(inputs);
const blocksize = attributes.blocksize;
const blocksizeSqr = blocksize * blocksize;
const transposePerm = attributes.mode === 'DCR' ? [0, 3, 4, 1, 5, 2] : [0, 1, 4, 2, 5, 3];
const firstReshapeShape = attributes.mode === 'DCR' ?
[
inputs[0].dims[0], blocksize, blocksize, inputs[0].dims[1] / blocksizeSqr, inputs[0].dims[2],
inputs[0].dims[3]
] :
[
inputs[0].dims[0], inputs[0].dims[1] / blocksizeSqr, blocksize, blocksize, inputs[0].dims[2],
inputs[0].dims[3]
];
// const transpose = new WebGLTranspose();
// const attributes = new Attribute(undefined);
// attributes.set('perm', 'ints', transposePerm);
// transpose.initialize(attributes);
// First reshape
const firstReshapedTensor = inferenceHandler.reshapeUnpacked(inputs[0], firstReshapeShape);
// transpose
const transposeAttributes = { perm: transposePerm, cacheKey: `${transposePerm}` };
const [transposeOutput] = (0, transpose_1.transpose)(inferenceHandler, [firstReshapedTensor], transposeAttributes);
// Second reshape
const secondReshapeShape = [
inputs[0].dims[0], inputs[0].dims[1] / blocksizeSqr, inputs[0].dims[2] * blocksize,
inputs[0].dims[3] * blocksize
];
const result = inferenceHandler.reshapeUnpacked(transposeOutput, secondReshapeShape);
return [result];
};
exports.depthToSpace = depthToSpace;
const parseDepthToSpaceAttributes = (node) => {
// processing node attributes
const blocksize = node.attributes.getInt('blocksize');
if (blocksize < 1) {
throw new Error(`blocksize must be >= 1, but got : ${blocksize} for DepthToSpace`);
}
const mode = node.attributes.getString('mode', 'DCR');
if (mode !== 'DCR' && mode !== 'CRD') {
throw new Error(`unrecognized mode: ${mode} for DepthToSpace`);
}
return { mode, blocksize };
};
exports.parseDepthToSpaceAttributes = parseDepthToSpaceAttributes;
const validateInputs = (inputs) => {
if (inputs.length !== 1) {
throw new Error(`DepthToSpace expect 1 inputs, but got ${inputs.length}`);
}
// Input has to be a 4-D tensor
// TODO: Support string depth-to-space.
if (inputs[0].type === 'string' || inputs[0].dims.length !== 4) {
throw new TypeError('DepthToSpace input should be a 4-D numeric tensor');
}
};
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/ops/dot-product.ts":
/*!******************************************************!*\
!*** ./lib/onnxjs/backends/webgl/ops/dot-product.ts ***!
\******************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.createDotProductProgramInfoLoader = void 0;
const util_1 = __webpack_require__(/*! ../../../util */ "./lib/onnxjs/util.ts");
const glsl_source_1 = __webpack_require__(/*! ../glsl-source */ "./lib/onnxjs/backends/webgl/glsl-source.ts");
const types_1 = __webpack_require__(/*! ../types */ "./lib/onnxjs/backends/webgl/types.ts");
const fuse_utils_1 = __webpack_require__(/*! ./fuse-utils */ "./lib/onnxjs/backends/webgl/ops/fuse-utils.ts");
const im2col_1 = __webpack_require__(/*! ./im2col */ "./lib/onnxjs/backends/webgl/ops/im2col.ts");
const createDotProductProgramMetadata = (hasBias, attributes) => ({
name: 'ConvDotProduct',
inputNames: hasBias ? ['Im2Col', 'K', 'B'] : ['Im2Col', 'K'],
inputTypes: hasBias ? [types_1.TextureType.unpacked, types_1.TextureType.packedLastDimension, types_1.TextureType.unpacked] :
[types_1.TextureType.unpacked, types_1.TextureType.packedLastDimension],
cacheKey: attributes.activationCacheKey
});
const createDotProductProgramInfo = (inferenceHandler, metadata, inputs, outputShape, attributes) => {
const xshape = inputs[0].dims;
const kshape = inputs[1].dims;
const adjustedKernelShape = [kshape[0], Math.ceil((xshape[1] * kshape[2] * kshape[3]) / 4)];
const im2colShape = (0, im2col_1.calculateIm2ColDims)(xshape, kshape, outputShape);
const [kWidth, kHeight] = inferenceHandler.calculateTextureWidthAndHeight(adjustedKernelShape, types_1.TextureType.packedLastDimension);
const im2colStrides = util_1.ShapeUtil.computeStrides(im2colShape);
const [im2colWidth, im2colHeight] = inferenceHandler.calculateTextureWidthAndHeight(im2colShape, types_1.TextureType.packedLastDimension);
const rank = outputShape.length;
const initValue = (inputs.length < 3) ? '0.0' : '_B(b)';
const sharedDim = Math.ceil(xshape[1] * kshape[2] * kshape[3] / 4);
const { activationFunction, applyActivation } = (0, fuse_utils_1.getActivationSnippet)(attributes);
const glsl = (0, glsl_source_1.getGlsl)(inferenceHandler.session.backend.glContext.version);
const shaderSource = `
${activationFunction}
float process(int indices[${rank}]) {
int b[1];
b[0] = indices[1];
int im2col[4];
im2col[0] = indices[0];
im2col[1] = indices[2];
im2col[2] = indices[3];
int im2colOffset = im2col[0] * ${im2colStrides[0]} + im2col[1] * ${im2colStrides[1]} + im2col[2] * ${im2colStrides[2]};
int kernelOffset = indices[1] * ${adjustedKernelShape[1]};
float value = ${initValue};
for (int i = 0; i < ${sharedDim}; ++i) {
vec2 im2colCoords = offsetToCoords(im2colOffset, ${im2colWidth}, ${im2colHeight});
vec2 kernelCoords = offsetToCoords(kernelOffset, ${kWidth}, ${kHeight});
value += dot(${glsl.texture2D}(Im2Col, im2colCoords), ${glsl.texture2D}(K, kernelCoords));
++im2colOffset;
++kernelOffset;
}
${applyActivation}
return value;
}`;
return Object.assign(Object.assign({}, metadata), { output: { dims: outputShape, type: inputs[0].type, textureType: types_1.TextureType.unpacked }, shaderSource });
};
const createDotProductProgramInfoLoader = (inferenceHandler, inputs, outputShape, attributes) => {
const metadata = createDotProductProgramMetadata(inputs.length > 2, attributes);
return Object.assign(Object.assign({}, metadata), { get: () => createDotProductProgramInfo(inferenceHandler, metadata, inputs, outputShape, attributes) });
};
exports.createDotProductProgramInfoLoader = createDotProductProgramInfoLoader;
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/ops/flatten.ts":
/*!**************************************************!*\
!*** ./lib/onnxjs/backends/webgl/ops/flatten.ts ***!
\**************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.parseFlattenAttributes = exports.flatten = void 0;
const util_1 = __webpack_require__(/*! ../../../util */ "./lib/onnxjs/util.ts");
const flatten = (inferenceHandler, inputs, axis) => {
validateInputs(inputs, axis);
const outputDims = util_1.ShapeUtil.flattenShape(inputs[0].dims, axis);
return [inferenceHandler.reshapeUnpacked(inputs[0], outputDims)];
};
exports.flatten = flatten;
const parseFlattenAttributes = (node) => node.attributes.getInt('axis', 1); // default axis is 1
exports.parseFlattenAttributes = parseFlattenAttributes;
const validateInputs = (inputs, axis) => {
if (!inputs || inputs.length !== 1) {
throw new Error('Flatten requires 1 input.');
}
const r = inputs[0].dims.length;
if (r === 0) {
throw new Error('scalar tensor is not supported.');
}
if (axis < -r || axis > r) {
throw new Error('Invalid axis');
}
// TODO: Support string type
if (inputs[0].type === 'string') {
throw new Error('string tensor is not supported.');
}
};
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/ops/fuse-utils.ts":
/*!*****************************************************!*\
!*** ./lib/onnxjs/backends/webgl/ops/fuse-utils.ts ***!
\*****************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.parseInternalActivationAttributes = exports.getActivationSnippet = void 0;
const util_1 = __webpack_require__(/*! ../../../util */ "./lib/onnxjs/util.ts");
const unary_op_1 = __webpack_require__(/*! ./unary-op */ "./lib/onnxjs/backends/webgl/ops/unary-op.ts");
function getActivationSnippet(attributes) {
let func;
switch (attributes.activation) {
case 'Relu':
func = (0, unary_op_1.glslRelu)();
break;
case 'Sigmoid':
func = (0, unary_op_1.glslSigmoid)();
break;
case 'Clip':
func = (0, unary_op_1.glslClip)(attributes.clipMin, attributes.clipMax);
break;
// TODO: adding other activations that can be fused.
default:
return { activationFunction: '', applyActivation: '' };
}
const activationName = func.name;
const activationFunction = func.body;
const applyActivation = `value = ${activationName}_(value);`;
return { activationFunction, applyActivation };
}
exports.getActivationSnippet = getActivationSnippet;
const parseInternalActivationAttributes = (attributes) => {
const activation = attributes.getString('activation', '');
if (activation === 'Clip') {
const [clipMin, clipMax] = attributes.getFloats('activation_params', [util_1.MIN_CLIP, util_1.MAX_CLIP]);
return { activation, clipMax, clipMin, activationCacheKey: `${activation}:${clipMin},${clipMax}` };
}
return { activation, activationCacheKey: activation };
};
exports.parseInternalActivationAttributes = parseInternalActivationAttributes;
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/ops/gather.ts":
/*!*************************************************!*\
!*** ./lib/onnxjs/backends/webgl/ops/gather.ts ***!
\*************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.parseGatherAttributes = exports.gather = void 0;
const attribute_with_cache_key_1 = __webpack_require__(/*! ../../../attribute-with-cache-key */ "./lib/onnxjs/attribute-with-cache-key.ts");
const operators_1 = __webpack_require__(/*! ../../../operators */ "./lib/onnxjs/operators.ts");
const util_1 = __webpack_require__(/*! ../../../util */ "./lib/onnxjs/util.ts");
const types_1 = __webpack_require__(/*! ../types */ "./lib/onnxjs/backends/webgl/types.ts");
const gather = (inferenceHandler, inputs, attributes) => {
validateInputs(inputs, attributes.axis);
const output = inferenceHandler.run(createGatherProgramInfoLoader(inferenceHandler, inputs, attributes), inputs);
return [output];
};
exports.gather = gather;
const parseGatherAttributes = (node) => (0, attribute_with_cache_key_1.createAttributeWithCacheKey)({ axis: node.attributes.getInt('axis', 0) });
exports.parseGatherAttributes = parseGatherAttributes;
const gatherProgramMetadata = {
name: 'Gather',
inputNames: ['A', 'B'],
inputTypes: [types_1.TextureType.unpacked, types_1.TextureType.unpacked],
};
const createGatherProgramInfo = (handler, metadata, inputs, axis) => {
const inputShape = inputs[0].dims.slice();
const indexDataShape = inputs[1].dims.slice();
const outputShape = new Array(inputShape.length + indexDataShape.length - 1);
axis = util_1.ShapeUtil.normalizeAxis(axis, inputShape.length);
const indexCopyOps = [];
for (let i = 0; i < outputShape.length; i++) {
// outputShape is divided into three parts: A, B, C
// |0 axis| axis + indexDataShape.length | end|
// | A | B | C |
//
// inputIdx: [A, inputs[1][B], C]
if (i < axis) { // A
outputShape[i] = inputShape[i];
indexCopyOps.push(`inputIdx[${i}] = outputIdx[${i}];`);
}
else {
if (i < axis + indexDataShape.length) { // B
outputShape[i] = indexDataShape[i - axis];
indexCopyOps.push(`indexDataIdx[${i - axis}] = outputIdx[${i}];`);
}
else { // C
outputShape[i] = inputShape[i - indexDataShape.length + 1]; // skip 1 for axis
indexCopyOps.push(`inputIdx[${i - indexDataShape.length + 1}] = outputIdx[${i}];`);
}
}
}
const orank = outputShape.length || 1;
const irank = inputShape.length;
const iDrank = indexDataShape.length || 1;
const shaderSource = `
float process(int outputIdx[${orank}]) {
int inputIdx[${irank}];
int indexDataIdx[${iDrank}];
indexDataIdx[0] = 0;
${indexCopyOps.join('\n ')}
int idx = int(_B(indexDataIdx));
inputIdx[${axis}] = idx < 0 ? idx + ${inputShape[axis]} : idx;
return _A(inputIdx);
}`;
return Object.assign(Object.assign({}, metadata), { output: { dims: outputShape, type: inputs[0].type, textureType: types_1.TextureType.unpacked }, shaderSource });
};
const createGatherProgramInfoLoader = (handler, inputs, attributes) => {
const metadata = Object.assign(Object.assign({}, gatherProgramMetadata), { cacheHint: attributes.cacheKey });
return Object.assign(Object.assign({}, metadata), { get: () => createGatherProgramInfo(handler, metadata, inputs, attributes.axis) });
};
const validateInputs = (inputs, axis) => {
if (!inputs || inputs.length !== 2) {
throw new Error('Gather requires 2 inputs.');
}
const tensorRank = inputs[0].dims.length;
if (tensorRank < 1) {
throw new Error('Invalid input shape.');
}
if (axis < -tensorRank || axis > tensorRank - 1) {
throw new Error('Invalid axis.');
}
if (operators_1.NUMBER_TYPES.indexOf(inputs[0].type) === -1) {
throw new Error('Invaid input type.');
}
if (inputs[1].type !== 'int32' && inputs[1].type !== 'int16') {
throw new Error('Invaid input type.');
}
};
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/ops/gemm.ts":
/*!***********************************************!*\
!*** ./lib/onnxjs/backends/webgl/ops/gemm.ts ***!
\***********************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.parseGemmAttributesV11 = exports.parseGemmAttributesV7 = exports.gemm = void 0;
const attribute_with_cache_key_1 = __webpack_require__(/*! ../../../attribute-with-cache-key */ "./lib/onnxjs/attribute-with-cache-key.ts");
const util_1 = __webpack_require__(/*! ../../../util */ "./lib/onnxjs/util.ts");
const types_1 = __webpack_require__(/*! ../types */ "./lib/onnxjs/backends/webgl/types.ts");
const gemm = (inferenceHandler, inputs, attributes) => {
validateInputs(inputs, attributes);
const output = inferenceHandler.run(createGemmProgramInfoLoader(inputs, attributes), inputs);
return [output];
};
exports.gemm = gemm;
const parseGemmAttributes = (node, isOptionalC) => {
const transA = node.attributes.getInt('transA', 0) !== 0;
const transB = node.attributes.getInt('transB', 0) !== 0;
const alpha = node.attributes.getFloat('alpha', 1.0);
const beta = node.attributes.getFloat('beta', 1.0);
return (0, attribute_with_cache_key_1.createAttributeWithCacheKey)({ transA, transB, alpha, beta, isOptionalC });
};
const parseGemmAttributesV7 = (node) => parseGemmAttributes(node, false);
exports.parseGemmAttributesV7 = parseGemmAttributesV7;
const parseGemmAttributesV11 = (node) => parseGemmAttributes(node, true);
exports.parseGemmAttributesV11 = parseGemmAttributesV11;
const createGemmProgramInfoLoader = (inputs, attributes) => {
const metadata = {
name: 'Gemm',
inputNames: inputs.length === 3 ? ['A', 'B', 'C'] : ['A', 'B'],
inputTypes: inputs.length === 3 ? [types_1.TextureType.unpacked, types_1.TextureType.unpacked, types_1.TextureType.unpacked] :
[types_1.TextureType.unpacked, types_1.TextureType.unpacked],
key: attributes.cacheKey
};
return Object.assign(Object.assign({}, metadata), { get: () => createGemmProgramInfo(metadata, inputs, attributes) });
};
const createGemmProgramInfo = (metadata, inputs, attributes) => {
const aShape = inputs[0].dims.slice();
const bShape = inputs[1].dims.slice();
const [M, N] = util_1.GemmUtil.getShapeOfGemmResult(aShape, attributes.transA, bShape, attributes.transB, inputs.length === 3 ? inputs[2].dims : undefined);
const outputShape = [M, N];
if (!outputShape) {
throw new Error('Can\'t use gemm on the given tensors');
}
let sharedDim = aShape[aShape.length - 1];
let line = '';
if (attributes.transA) {
sharedDim = aShape[0];
}
if (attributes.transA && attributes.transB) {
line = 'value += _A_T(a) * _B_T(b);';
}
else if (attributes.transA && !attributes.transB) {
line = 'value += _A_T(a) * _B(b);';
}
else if (!attributes.transA && attributes.transB) {
line = 'value += _A(a) * _B_T(b);';
}
else if (!attributes.transA && !attributes.transB) {
line = 'value += _A(a) * _B(b);';
}
const rank = outputShape.length;
const declareC = inputs.length === 3 ? `int c[${inputs[2].dims.length}];` : '';
const broadcastC = inputs.length === 3 ? 'bcastIndices_C(indices, c);' : '';
const calculateC = inputs.length === 3 ? 'value += beta * _C(c);' : '';
const shaderSource = `
float process(int indices[${rank}]) {
int a[${rank}];
int b[${rank}];
${declareC}
copyVec(indices, a);
copyVec(indices, b);
${broadcastC}
float value = 0.0;
for (int k=0; k<${sharedDim}; ++k) {
a[${rank - 1}] = k;
b[${rank - 2}] = k;
${line}
}
value = value * alpha;
${calculateC}
return value;
}`;
return Object.assign(Object.assign({}, metadata), { output: { dims: outputShape, type: inputs[0].type, textureType: types_1.TextureType.unpacked }, variables: [
{ name: 'alpha', type: 'float', data: attributes.alpha }, { name: 'beta', type: 'float', data: attributes.beta }
], shaderSource });
};
const validateInputs = (inputs, attributes) => {
if (!inputs) {
throw new Error('Input is missing');
}
if (attributes.isOptionalC && (inputs.length < 2 || inputs.length > 3)) {
throw new Error('Invaid input shape.');
}
if (!attributes.isOptionalC && inputs.length !== 3) {
throw new Error('Gemm requires 3 inputs');
}
// 'C' can be of dimensionality 1 or 2 only
if (inputs.length === 3 && inputs[2].dims.length !== 1 && inputs[2].dims.length !== 2) {
throw new Error('Invalid input shape of C');
}
if ((inputs[0].type !== 'float32' && inputs[0].type !== 'float64') ||
(inputs[1].type !== 'float32' && inputs[1].type !== 'float64') ||
(inputs.length === 3 && inputs[2].type !== 'float32' && inputs[2].type !== 'float64')) {
throw new Error('Invalid input type.');
}
if ((inputs[0].type !== inputs[1].type) || (inputs.length === 3 && inputs[0].type !== inputs[2].type)) {
throw new Error('Input types are mismatched');
}
};
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/ops/im2col-pack.ts":
/*!******************************************************!*\
!*** ./lib/onnxjs/backends/webgl/ops/im2col-pack.ts ***!
\******************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.createPackedIm2ColProgramInfoLoader = void 0;
const glsl_source_1 = __webpack_require__(/*! ../glsl-source */ "./lib/onnxjs/backends/webgl/glsl-source.ts");
const types_1 = __webpack_require__(/*! ../types */ "./lib/onnxjs/backends/webgl/types.ts");
const packing_utils_1 = __webpack_require__(/*! ./packing-utils */ "./lib/onnxjs/backends/webgl/ops/packing-utils.ts");
const createPackedIm2ColProgramMetadata = (cacheHint) => ({
name: 'Im2Col (packed)',
inputNames: ['A'],
inputTypes: [types_1.TextureType.packed],
cacheHint,
});
const createPackedIm2ColProgramInfo = (inferenceHandler, metadata, x, w, outputShape, attributes) => {
const xshape = x.dims;
const wshape = w.dims;
const rowDim = 2;
const colDim = 3;
const rank = outputShape.length;
const im2colShape = [wshape[1] * wshape[2] * wshape[3], outputShape[2] * outputShape[3]];
const kernelSize = wshape[2] * wshape[3];
const unpackChannel = (0, packing_utils_1.unpackFromChannel)();
const glsl = (0, glsl_source_1.getGlsl)(inferenceHandler.session.backend.glContext.version);
let unrolled = '';
for (let row = 0; row <= 1; row++) {
for (let col = 0; col <= 1; col++) {
unrolled += `
blockIndex = rc.x + ${col};
pos = rc.y + ${row};
if(blockIndex < ${im2colShape[1]} && pos < ${im2colShape[0]}) {
offsetY = int(blockIndex / (${outputShape[rank - 1]})) * ${attributes.strides[0]} -
${attributes.pads[0]};
d0 = offsetY + ${attributes.dilations[0]} * (imod(pos, ${kernelSize}) / ${wshape[2]});
if(d0 < ${xshape[rowDim]} && d0 >= 0) {
offsetX = imod(blockIndex, ${outputShape[rank - 1]}) * ${attributes.strides[1]} -
${attributes.pads[1]};
d1 = offsetX + ${attributes.dilations[1]} * imod(imod(pos, ${kernelSize}), ${wshape[2]});
if(d1 < ${xshape[colDim]} && d1 >= 0) {
ch = int(float(pos)/ ${kernelSize}.);
innerDims = vec2(d0, d1);
result[${row * 2 + col}] = getChannel(
getA(0, ch, int(innerDims.x),
int(innerDims.y)), innerDims);
}
}
}
`;
}
}
const shaderSource = `
${unpackChannel}
void main() {
ivec2 rc = getOutputCoords();
vec4 result = vec4(0.0);
int blockIndex, pos, offsetY, d0, offsetX, d1, ch;
vec2 innerDims;
${unrolled}
${glsl.output} = result;
}
`;
return Object.assign(Object.assign({}, metadata), { output: { dims: im2colShape, type: x.type, textureType: types_1.TextureType.packed }, shaderSource, hasMain: true });
};
const createPackedIm2ColProgramInfoLoader = (inferenceHandler, x, w, outputShape, attributes) => {
const metadata = createPackedIm2ColProgramMetadata(attributes.cacheKey);
return Object.assign(Object.assign({}, metadata), { get: () => createPackedIm2ColProgramInfo(inferenceHandler, metadata, x, w, outputShape, attributes) });
};
exports.createPackedIm2ColProgramInfoLoader = createPackedIm2ColProgramInfoLoader;
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/ops/im2col.ts":
/*!*************************************************!*\
!*** ./lib/onnxjs/backends/webgl/ops/im2col.ts ***!
\*************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.calculateIm2ColDims = exports.createIm2ColProgramInfoLoader = void 0;
const types_1 = __webpack_require__(/*! ../types */ "./lib/onnxjs/backends/webgl/types.ts");
const createIm2ColProgramMetadata = (cacheHint) => ({
name: 'Im2Col',
inputNames: ['X'],
inputTypes: [types_1.TextureType.unpacked],
cacheHint,
});
const createIm2ColProgramInfo = (inferenceHandler, metadata, x, w, outputShape, attributes) => {
const xshape = x.dims;
const wshape = w.dims;
const rank = outputShape.length;
const im2colDims = (0, exports.calculateIm2ColDims)(xshape, wshape, outputShape, 4);
const shaderSource = `
const int XC = ${xshape[1]};
const int XH = ${xshape[2]};
const int XW = ${xshape[3]};
const int KH = ${attributes.kernelShape[0]};
const int KW = ${attributes.kernelShape[1]};
const int dilationH = ${attributes.dilations[0]};
const int dilationW = ${attributes.dilations[1]};
const int strideH = ${attributes.strides[0]};
const int strideW = ${attributes.strides[1]};
const int padH = ${attributes.pads[0]};
const int padW = ${attributes.pads[1]};
const int KHKW = KH*KW;
const int XCKHKW = XC * KHKW;
const int outputChannels = 4;
vec4 process(int indices[${rank}]) {
int b = indices[0]; // batch size
int oh = indices[1] * strideH - padH; //output height
int ow = indices[2] * strideW - padW; //output width
int p = indices[3] * outputChannels; //patch
vec4 value = vec4(0.0);
for(int i=0; i < outputChannels; ++i) {
if(p < XCKHKW) {
int patchC = p / KHKW;
int patchH = (p - patchC*KHKW) / KW;
int patchW = (p - patchC*KHKW) - patchH * KW;
int xh2 = oh + patchH * dilationH;
int xw2 = ow + patchW * dilationW;
int x[${xshape.length}];
x[0] = b;
x[1] = patchC;
x[2] = xh2;
x[3] = xw2;
if(xh2 >= 0 &&
xh2 < XH &&
xw2 >= 0 &&
xw2 < XW) {
value[i] = _X(x);
}
}
++p;
}
return value;
}
`;
return Object.assign(Object.assign({}, metadata), { output: { dims: im2colDims, type: x.type, textureType: types_1.TextureType.packedLastDimension }, shaderSource });
};
const createIm2ColProgramInfoLoader = (inferenceHandler, x, w, outputShape, attributes) => {
const metadata = createIm2ColProgramMetadata(attributes.cacheKey);
return Object.assign(Object.assign({}, metadata), { get: () => createIm2ColProgramInfo(inferenceHandler, metadata, x, w, outputShape, attributes) });
};
exports.createIm2ColProgramInfoLoader = createIm2ColProgramInfoLoader;
const calculateIm2ColDims = (inputShape, kernelShape, outputShape, channels = 4) => [outputShape[0], outputShape[2], outputShape[3],
Math.ceil(inputShape[1] * kernelShape[2] * kernelShape[3] / channels)];
exports.calculateIm2ColDims = calculateIm2ColDims;
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/ops/image-scaler.ts":
/*!*******************************************************!*\
!*** ./lib/onnxjs/backends/webgl/ops/image-scaler.ts ***!
\*******************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.parseImageScalerAttributes = exports.imageScaler = void 0;
const attribute_with_cache_key_1 = __webpack_require__(/*! ../../../attribute-with-cache-key */ "./lib/onnxjs/attribute-with-cache-key.ts");
const types_1 = __webpack_require__(/*! ../types */ "./lib/onnxjs/backends/webgl/types.ts");
const imageScaler = (inferenceHandler, inputs, attributes) => {
validateInputs(inputs);
const output = inferenceHandler.run(createImageScalerProgramInfoLoader(inferenceHandler, inputs, attributes), inputs);
return [output];
};
exports.imageScaler = imageScaler;
const parseImageScalerAttributes = (node) => {
const scale = node.attributes.getFloat('scale');
const bias = node.attributes.getFloats('bias');
return (0, attribute_with_cache_key_1.createAttributeWithCacheKey)({ scale, bias });
};
exports.parseImageScalerAttributes = parseImageScalerAttributes;
const imageScalerProgramMetadata = {
name: 'ImageScaler',
inputNames: ['X'],
inputTypes: [types_1.TextureType.unpacked],
};
const createImageScalerProgramInfo = (handler, metadata, inputs, attributes) => {
const outputShape = inputs[0].dims.slice();
const rank = outputShape.length;
const getBiasMethod = createGetBiasMethod(attributes.bias.length);
const shaderSource = `
${getBiasMethod}
float process(int indices[${rank}]) {
return _X(indices) * scale + getBias(bias, indices[1]);
}`;
return Object.assign(Object.assign({}, metadata), { output: { dims: outputShape, type: inputs[0].type, textureType: types_1.TextureType.unpacked }, variables: [
{ name: 'bias', type: 'float', arrayLength: attributes.bias.length, data: attributes.bias },
{ name: 'scale', type: 'float', data: attributes.scale }
], shaderSource });
};
const createImageScalerProgramInfoLoader = (handler, inputs, attributes) => {
const metadata = Object.assign(Object.assign({}, imageScalerProgramMetadata), { cacheHint: attributes.cacheKey });
return Object.assign(Object.assign({}, metadata), { get: () => createImageScalerProgramInfo(handler, metadata, inputs, attributes) });
};
const createGetBiasMethod = (numChannels) => {
const codeLines = [`float getBias(float bias[${numChannels}], int channel) {`];
for (let i = 0; i < numChannels; ++i) {
if (i === 0) {
codeLines.push('\t' +
`if (channel == ${i}) { return bias[${i}]; }`);
}
else if (i === numChannels - 1) {
codeLines.push('\t' +
`else { return bias[${i}]; }`);
}
else {
codeLines.push('\t' +
`else if (channel == ${i}) { return bias[${i}]; }`);
}
}
codeLines.push('\t' +
'}');
return codeLines.join('\n');
};
const validateInputs = (inputs) => {
if (!inputs || inputs.length !== 1) {
throw new Error('ImageScaler requires 1 input.');
}
if (inputs[0].dims.length !== 4) {
throw new Error('Invalid input shape.');
}
if (inputs[0].type !== 'float32' && inputs[0].type !== 'float64') {
throw new Error('Invalid input type.');
}
};
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/ops/instance-normalization.ts":
/*!*****************************************************************!*\
!*** ./lib/onnxjs/backends/webgl/ops/instance-normalization.ts ***!
\*****************************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.parseInstanceNormalizationAttributes = exports.instanceNormalization = void 0;
const glsl_source_1 = __webpack_require__(/*! ../glsl-source */ "./lib/onnxjs/backends/webgl/glsl-source.ts");
const types_1 = __webpack_require__(/*! ../types */ "./lib/onnxjs/backends/webgl/types.ts");
const instanceNormalization = (inferenceHandler, inputs, epsilon) => {
validateInputs(inputs);
const meanAndVariance = inferenceHandler.run(createMeanAndVarianceProgramInfoLoader(inputs[0]), inputs);
const output = inferenceHandler.run(createComputeOutputProgramInfoLoader(inferenceHandler, inputs[0], epsilon, meanAndVariance.dims), [inputs[0], meanAndVariance, inputs[1], inputs[2]]);
return [output];
};
exports.instanceNormalization = instanceNormalization;
const parseInstanceNormalizationAttributes = (node) => node.attributes.getFloat('epsilon', 1e-5);
exports.parseInstanceNormalizationAttributes = parseInstanceNormalizationAttributes;
const meanAndVarianceProgramMetadata = {
name: 'InstanceNormalization_MeanAndVariance',
inputNames: ['X'],
inputTypes: [types_1.TextureType.unpacked],
};
const createMeanAndVarianceProgramInfo = (metadata, input) => {
const xDims = input.dims.slice();
const channel = xDims[1];
const channelSize = xDims[2] * xDims[3];
const outputShape = [xDims[0], channel];
const shaderSource = `
vec4 process(int[2] indices) {
vec4 v = vec4(0.0);
int a[4];
a[0] = indices[0];
a[1] = indices[1];
float temp = 0.0;
for(int a2=0; a2<${xDims[2]}; a2++) {
a[2] = a2;
for(int a3=0; a3<${xDims[3]}; a3++) {
a[3] = a3;
float x = _X(a);
temp += x;
}
}
float mean = temp / float(${channelSize});
temp = 0.0;
for(int a2=0; a2<${xDims[2]}; a2++) {
a[2] = a2;
for(int a3=0; a3<${xDims[3]}; a3++) {
a[3] = a3;
float x = _X(a);
temp += (x - mean) * (x - mean);
}
}
v.r = mean;
v.g = temp / float(${channelSize});
return v;
}`;
return Object.assign(Object.assign({}, metadata), { output: { dims: outputShape, type: input.type, textureType: types_1.TextureType.packedLastDimension }, shaderSource });
};
const createMeanAndVarianceProgramInfoLoader = (input) => (Object.assign(Object.assign({}, meanAndVarianceProgramMetadata), { get: () => createMeanAndVarianceProgramInfo(meanAndVarianceProgramMetadata, input) }));
const computeOutputProgramMetadata = {
name: 'InstanceNormalization_ComputeOutput',
inputNames: ['X', 'MeanAndVariance', 'Scale', 'B'],
inputTypes: [types_1.TextureType.unpacked, types_1.TextureType.packedLastDimension, types_1.TextureType.unpacked, types_1.TextureType.unpacked],
};
const createComputeOutputProgramInfo = (inferenceHandler, metadata, input, epsilon, meanAndVarianceShape) => {
const glsl = (0, glsl_source_1.getGlsl)(inferenceHandler.session.backend.glContext.version);
const [textureWidth, textureHeight] = inferenceHandler.calculateTextureWidthAndHeight(meanAndVarianceShape, types_1.TextureType.packedLastDimension);
const [meanAndVarianceWidth, meanAndVarianceHeight] = [textureWidth / 4, textureHeight];
const shaderSource = `
vec4 get_MeanAndVariance(int[2] mv) {
int offset = indicesToOffset_MeanAndVariance(mv);
vec2 coords = offsetToCoords(offset, ${meanAndVarianceWidth}, ${meanAndVarianceHeight});
return ${glsl.texture2D}(MeanAndVariance, coords);
}
float process(int[4] indices) {
int mv[2];
mv[0] = indices[0];
mv[1] = indices[1];
vec4 mean_and_variance = get_MeanAndVariance(mv);
float mean = mean_and_variance.r;
float variance = mean_and_variance.g;
int sb[1];
sb[0] = indices[1];
float scale = _Scale(sb);
float b = _B(sb);
return scale * (_X(indices) - mean) / sqrt(variance + epsilon) + b;
}`;
return Object.assign(Object.assign({}, metadata), { output: { dims: input.dims, type: input.type, textureType: types_1.TextureType.unpacked }, variables: [{ name: 'epsilon', type: 'float', data: epsilon }], shaderSource });
};
const createComputeOutputProgramInfoLoader = (inferenceHandler, input, epsilon, meanAndVarianceShape) => {
const metadata = Object.assign(Object.assign({}, computeOutputProgramMetadata), { cacheHint: `${epsilon}` });
return Object.assign(Object.assign({}, metadata), { get: () => createComputeOutputProgramInfo(inferenceHandler, metadata, input, epsilon, meanAndVarianceShape) });
};
const validateInputs = (inputs) => {
if (!inputs || inputs.length !== 3) {
throw new Error('InstanceNormalization requires 3 inputs.');
}
const X = inputs[0];
const scale = inputs[1];
const B = inputs[2];
// input should at least have three dimensions - N,C,dim1,...,dimn
// other inputs can have only one dimensions
if (X.dims.length < 3 || scale.dims.length !== 1 || B.dims.length !== 1) {
throw new Error('Invalid input shape.');
}
if (scale.dims[0] !== X.dims[1] || B.dims[0] !== X.dims[1]) {
throw new Error('Input shapes are mismatched.');
}
if ((X.type !== 'float32' && X.type !== 'float64') || (scale.type !== 'float32' && scale.type !== 'float64') ||
(B.type !== 'float32' && B.type !== 'float64')) {
throw new Error('Invalid input type.');
}
if (inputs[0].dims.length !== 4) {
throw new Error('Only support 4-D input shape.');
}
};
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/ops/matmul-pack.ts":
/*!******************************************************!*\
!*** ./lib/onnxjs/backends/webgl/ops/matmul-pack.ts ***!
\******************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.createPackedMatmulProgramInfoLoader = void 0;
const util_1 = __webpack_require__(/*! ../../../util */ "./lib/onnxjs/util.ts");
const glsl_source_1 = __webpack_require__(/*! ../glsl-source */ "./lib/onnxjs/backends/webgl/glsl-source.ts");
const types_1 = __webpack_require__(/*! ../types */ "./lib/onnxjs/backends/webgl/types.ts");
const utils_1 = __webpack_require__(/*! ../utils */ "./lib/onnxjs/backends/webgl/utils.ts");
const fuse_utils_1 = __webpack_require__(/*! ./fuse-utils */ "./lib/onnxjs/backends/webgl/ops/fuse-utils.ts");
const matmul_1 = __webpack_require__(/*! ./matmul */ "./lib/onnxjs/backends/webgl/ops/matmul.ts");
const createPackedMatmulProgramMetadata = (hasBias, cacheHint) => ({
name: 'MatMul (packed)',
inputNames: hasBias ? ['A', 'B', 'Bias'] : ['A', 'B'],
inputTypes: hasBias ? [types_1.TextureType.packed, types_1.TextureType.packed, types_1.TextureType.packed] :
[types_1.TextureType.packed, types_1.TextureType.packed],
cacheHint
});
const createPackedMatmulProgramInfo = (inferenceHandler, metadata, inputs, activationAttributes) => {
const hasBias = inputs.length > 2;
const processBias = hasBias ? 'value += getBiasForMatmul();' : '';
const aShape = inputs[0].dims;
const bShape = inputs[1].dims;
const outputShape = util_1.BroadcastUtil.calcShape(aShape, bShape, true);
const isBroadcast = !util_1.ShapeUtil.areEqual(inputs[0].dims, inputs[1].dims);
if (!outputShape) {
throw new Error('Can\'t use matmul on the given tensors');
}
const sharedDim = aShape[aShape.length - 1];
const sharedDimIndex = Math.ceil(sharedDim / 2);
const aRank = aShape.length;
const bRank = bShape.length;
const glsl = (0, glsl_source_1.getGlsl)(inferenceHandler.session.backend.glContext.version);
const coordsDataType = (0, utils_1.getCoordsDataType)(outputShape.length);
const outRank = outputShape.length;
const allGlChannels = (0, utils_1.getGlChannels)();
const { activationFunction, applyActivation } = (0, fuse_utils_1.getActivationSnippet)(activationAttributes);
const getBiasForMatmulSnippet = hasBias ? `${(0, matmul_1.getBiasForMatmul)(coordsDataType, allGlChannels, inputs[2].dims, outputShape, true)}` : '';
const getBcastedSamplerForMatmulSnippet = isBroadcast ? `${getBcastSamplerForMatmul(coordsDataType, allGlChannels, inputs, outputShape)}` : '';
const getSamplerAInLoopSnippet = isBroadcast ? 'getAAtOutCoordsMatmul(i)' : `getA(${getA(allGlChannels, aRank)})`;
const getSamplerBInLoopSnippet = isBroadcast ? 'getBAtOutCoordsMatmul(i)' : `getB(${getB(allGlChannels, bRank)})`;
const getOutputCoordsSnippet = isBroadcast ? '' : `${coordsDataType} rc =
getOutputCoords(); int lastDim = rc.${allGlChannels[outRank - 1]}; rc.${allGlChannels[outRank - 1]} =
rc.${allGlChannels[outRank - 2]}; rc.${allGlChannels[outRank - 2]} = lastDim;
`;
const shaderSource = `
${getBcastedSamplerForMatmulSnippet}
${getBiasForMatmulSnippet}
${activationFunction}
void main() {
${getOutputCoordsSnippet}
vec4 value = vec4(0);
for (int i = 0; i < ${sharedDimIndex}; i++) {
vec4 a = ${getSamplerAInLoopSnippet};
vec4 b = ${getSamplerBInLoopSnippet};
value += (a.rrbb * b.rgrg);
value += (a.ggaa * b.baba);
}
${processBias}
${applyActivation}
${glsl.output} = value;
}`;
return Object.assign(Object.assign({}, metadata), { output: { dims: outputShape, type: inputs[0].type, textureType: types_1.TextureType.packed }, shaderSource, hasMain: true });
};
const createPackedMatmulProgramInfoLoader = (inferenceHandler, inputs, activationAttributes) => {
const metadata = createPackedMatmulProgramMetadata(inputs.length > 2, activationAttributes.activationCacheKey);
return Object.assign(Object.assign({}, metadata), { get: () => createPackedMatmulProgramInfo(inferenceHandler, metadata, inputs, activationAttributes) });
};
exports.createPackedMatmulProgramInfoLoader = createPackedMatmulProgramInfoLoader;
function getBcastSamplerForMatmul(coordsDataType, allGlChannels, inputs, outShape) {
let unpackedACoordsSnippet = [];
let unpackedBCoordsSnippet = [];
const inAShape = inputs[0].dims;
const inBShape = inputs[1].dims;
const inARank = inAShape.length;
const inBRank = inBShape.length;
const outRank = outShape.length;
const rankADiff = outRank - inARank;
const rankBDiff = outRank - inBRank;
unpackedACoordsSnippet = inAShape.map((s, i) => `coords.${allGlChannels[i + rankADiff]}`);
unpackedACoordsSnippet[inARank - 1] = 'i*2';
unpackedACoordsSnippet.join(', ');
unpackedBCoordsSnippet = inBShape.map((s, i) => `coords.${allGlChannels[i + rankBDiff]}`);
unpackedBCoordsSnippet[inBRank - 2] = 'i*2';
unpackedBCoordsSnippet.join(', ');
const broadcastADims = util_1.BroadcastUtil.getBroadcastDims(inAShape, outShape);
const broadcastBDims = util_1.BroadcastUtil.getBroadcastDims(inBShape, outShape);
const coordsASnippet = broadcastADims.map(d => `coords.${allGlChannels[d + rankADiff]} = 0;`).join('\n');
const coordsBSnippet = broadcastBDims.map(d => `coords.${allGlChannels[d + rankBDiff]} = 0;`).join('\n');
const swapDimSnippet = `int lastDim = coords.${allGlChannels[outRank - 1]};
coords.${allGlChannels[outRank - 1]} = coords.${allGlChannels[outRank - 2]};
coords.${allGlChannels[outRank - 2]} = lastDim;`;
const getBcastSamplerMatmulSource = `
vec4 getAAtOutCoordsMatmul(int i) {
${coordsDataType} coords = getOutputCoords();
${swapDimSnippet}
${coordsASnippet}
vec4 outputValue = getA(${unpackedACoordsSnippet});
return outputValue;
}
vec4 getBAtOutCoordsMatmul(int i) {
${coordsDataType} coords = getOutputCoords();
${swapDimSnippet}
${coordsBSnippet}
vec4 outputValue = getB(${unpackedBCoordsSnippet});
return outputValue;
}`;
return getBcastSamplerMatmulSource;
}
function getA(allGlChannels, rank) {
let res = '';
for (let i = 0; i < rank - 2; i++) {
res += `rc.${allGlChannels[i]}, `;
}
res += `rc.${allGlChannels[rank - 2]}, ` +
'i*2';
return res;
}
function getB(allGlChannels, rank) {
let res = '';
for (let i = 0; i < rank - 2; i++) {
res += `rc.${allGlChannels[i]}, `;
}
res += 'i*2, ' +
`rc.${allGlChannels[rank - 1]}`;
return res;
}
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/ops/matmul.ts":
/*!*************************************************!*\
!*** ./lib/onnxjs/backends/webgl/ops/matmul.ts ***!
\*************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getBiasForMatmul = exports.createMatmulProgramInfoLoader = exports.parseMatMulAttributes = exports.matMul = void 0;
const util_1 = __webpack_require__(/*! ../../../util */ "./lib/onnxjs/util.ts");
const types_1 = __webpack_require__(/*! ../types */ "./lib/onnxjs/backends/webgl/types.ts");
const utils_1 = __webpack_require__(/*! ../utils */ "./lib/onnxjs/backends/webgl/utils.ts");
const fuse_utils_1 = __webpack_require__(/*! ./fuse-utils */ "./lib/onnxjs/backends/webgl/ops/fuse-utils.ts");
const matmul_pack_1 = __webpack_require__(/*! ./matmul-pack */ "./lib/onnxjs/backends/webgl/ops/matmul-pack.ts");
const matMul = (inferenceHandler, inputs, attributes) => {
validateInputs(inputs);
if (inferenceHandler.session.pack) {
return [inferenceHandler.run((0, matmul_pack_1.createPackedMatmulProgramInfoLoader)(inferenceHandler, inputs, attributes), inputs)];
}
else {
return [inferenceHandler.run(createMatmulProgramInfoLoader(inputs, attributes), inputs)];
}
};
exports.matMul = matMul;
const parseMatMulAttributes = (node) => (0, fuse_utils_1.parseInternalActivationAttributes)(node.attributes);
exports.parseMatMulAttributes = parseMatMulAttributes;
const createMatmulProgramMetadata = (hasBias, cacheHint) => ({
name: 'MatMul',
inputNames: hasBias ? ['A', 'B', 'Bias'] : ['A', 'B'],
inputTypes: hasBias ? [types_1.TextureType.unpacked, types_1.TextureType.unpacked, types_1.TextureType.unpacked] :
[types_1.TextureType.unpacked, types_1.TextureType.unpacked],
cacheHint
});
function createMatmulProgramInfo(metadata, inputs, activationAttributes) {
const aShape = inputs[0].dims;
const bShape = inputs[1].dims;
const outputShape = util_1.BroadcastUtil.calcShape(aShape, bShape, true);
if (!outputShape) {
throw new Error('Can\'t use matmul on the given tensors');
}
const coordsDataType = (0, utils_1.getCoordsDataType)(outputShape.length);
const allGlChannels = (0, utils_1.getGlChannels)();
const { activationFunction, applyActivation } = (0, fuse_utils_1.getActivationSnippet)(activationAttributes);
const hasBias = inputs.length > 2;
const processBias = hasBias ? 'value += getBiasForMatmul();' : '';
const getBiasForMatmulSnippet = hasBias ? `${getBiasForMatmul(coordsDataType, allGlChannels, inputs[2].dims, outputShape, false)}` : '';
const rank = outputShape.length;
const arank = aShape.length;
const brank = bShape.length;
const sharedDim = aShape[aShape.length - 1];
const shaderSource = `
${activationFunction}
${getBiasForMatmulSnippet}
float process(int indices[${rank}]) {
int a[${arank}];
int b[${brank}];
bcastMatmulIndices_A(indices, a);
bcastMatmulIndices_B(indices, b);
float value;
for (int k=0; k<${sharedDim}; ++k) {
a[${arank - 1}] = k;
b[${brank - 2}] = k;
value += _A(a) * _B(b);
}
${processBias}
${applyActivation}
return value;
}`;
return Object.assign(Object.assign({}, metadata), { output: { dims: outputShape, type: inputs[0].type, textureType: types_1.TextureType.unpacked }, shaderSource });
}
function createMatmulProgramInfoLoader(inputs, activationAttributes) {
const metadata = createMatmulProgramMetadata(inputs.length > 2, activationAttributes.activationCacheKey);
return Object.assign(Object.assign({}, metadata), { get: () => createMatmulProgramInfo(metadata, inputs, activationAttributes) });
}
exports.createMatmulProgramInfoLoader = createMatmulProgramInfoLoader;
const validateInputs = (inputs) => {
if (!inputs || inputs.length !== 2) {
throw new Error('MatMul requires 2 inputs.');
}
if (inputs[0].dims[inputs[0].dims.length - 1] !== inputs[1].dims[inputs[1].dims.length - 2]) {
throw new Error('shared dimension does not match.');
}
if ((inputs[0].type !== 'float32' && inputs[0].type !== 'float64') ||
(inputs[1].type !== 'float32' && inputs[1].type !== 'float64')) {
throw new Error('inputs should be float type');
}
if (inputs[0].type !== inputs[1].type) {
throw new Error('inputs types should match');
}
};
function getBiasForMatmul(coordsDataType, allGlChannels, inShape, outShape, isPacked) {
let unpackedCoordsSnippet = '';
const inRank = inShape.length;
const outRank = outShape.length;
const rankDiff = outRank - inRank;
if (outRank < 2 && inRank > 0) {
unpackedCoordsSnippet = 'coords';
}
else {
unpackedCoordsSnippet = inShape.map((s, i) => `coords.${allGlChannels[i + rankDiff]}`).join(', ');
}
const broadcastDims = util_1.BroadcastUtil.getBroadcastDims(inShape, outShape);
const coordsSnippet = broadcastDims.map(d => `coords.${allGlChannels[d + rankDiff]} = 0;`).join('\n');
const inSize = util_1.ShapeUtil.size(inShape);
const isInputScalar = inSize === 1;
let output = 'vec4(outputValue.xx, outputValue.yy)';
if (isInputScalar) {
output = 'vec4(outputValue.x)';
}
const getBiasForMatmulSource = isPacked ? `
vec4 getBiasForMatmul() {
${coordsDataType} coords = getOutputCoords();
${coordsSnippet}
vec4 outputValue = getBias(${unpackedCoordsSnippet});
return ${output};
}` :
`
float getBiasForMatmul() {
${coordsDataType} coords = getOutputCoords();
${coordsSnippet}
return getBias(coords.x);
}`;
return getBiasForMatmulSource;
}
exports.getBiasForMatmul = getBiasForMatmul;
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/ops/pack.ts":
/*!***********************************************!*\
!*** ./lib/onnxjs/backends/webgl/ops/pack.ts ***!
\***********************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.createPackProgramInfoLoader = void 0;
const glsl_source_1 = __webpack_require__(/*! ../glsl-source */ "./lib/onnxjs/backends/webgl/glsl-source.ts");
const types_1 = __webpack_require__(/*! ../types */ "./lib/onnxjs/backends/webgl/types.ts");
const utils_1 = __webpack_require__(/*! ../utils */ "./lib/onnxjs/backends/webgl/utils.ts");
const packing_utils_1 = __webpack_require__(/*! ./packing-utils */ "./lib/onnxjs/backends/webgl/ops/packing-utils.ts");
const packProgramMetadata = {
name: 'pack',
inputNames: ['A'],
inputTypes: [types_1.TextureType.unpackedReversed]
};
const createPackProgramInfo = (handler, input) => {
const glsl = (0, glsl_source_1.getGlsl)(handler.session.backend.glContext.version);
const inputShape = input.dims;
const inputRank = inputShape.length;
// createTextureLayoutFromShape won't change output rank. Need to verify by running tests
const outputRank = input.dims.length;
const coordsDataType = (0, utils_1.getCoordsDataType)(outputRank);
const channels = (0, packing_utils_1.getChannels)('rc', outputRank);
const setup = getSetup(outputRank, channels, inputShape[inputShape.length - 2], inputShape[inputShape.length - 1]);
let reversedInputWH;
if (inputRank === 0) {
reversedInputWH = [1, 1];
}
else if (inputRank === 1) {
reversedInputWH = [inputShape[0], 1];
}
else {
reversedInputWH = [inputShape[outputRank - 1], inputShape[outputRank - 2]];
}
const outOfBoundsCondition = getOutOfBoundsCondition(outputRank, reversedInputWH, channels);
const output = getOutput(inputShape, channels);
const shaderSource = `
void main() {
${coordsDataType} rc = getOutputCoords();
if(${outOfBoundsCondition}) {
${glsl.output} = vec4(0);
} else {
${setup}
${glsl.output} = vec4(${output});
}
}
`;
return Object.assign(Object.assign({}, packProgramMetadata), { hasMain: true, output: { dims: input.dims, type: input.type, textureType: types_1.TextureType.packed }, shaderSource });
};
const createPackProgramInfoLoader = (handler, input) => (Object.assign(Object.assign({}, packProgramMetadata), { get: () => createPackProgramInfo(handler, input) }));
exports.createPackProgramInfoLoader = createPackProgramInfoLoader;
/**
* check output coordinate location and return false if it is outside input's width/height boundary
*/
function getOutOfBoundsCondition(rank, shape, dims) {
if (rank === 0) {
return 'false';
}
if (rank === 1) {
return `rc > ${shape[0]}`;
}
let cond = '';
for (let i = rank - 2; i < rank; i++) {
cond += `${dims[i]} >= ${shape[i - rank + 2]}`;
if (i < rank - 1) {
cond += '||';
}
}
return cond;
}
/**
* code snippet to sample input texture with output coordiantes
*/
function getOutput(shape, dims) {
const rank = shape.length;
if (rank === 0) {
return 'getA(), 0, 0, 0';
}
if (rank === 1) {
return `getA(rc),
rc + 1 >= ${shape[0]} ? 0. : getA(rc + 1),
0, 0`;
}
const coord00 = 'r, c';
const coord01 = 'r, cp1';
const coord10 = 'rp1, c';
const coord11 = 'rp1, cp1';
let D = '';
if (rank > 2) {
for (let i = 0; i < rank - 2; ++i) {
D = D + `${dims[i]},`;
}
}
return `getA(${D}${coord00}),
rEdge ? 0. : getA(${D}${coord10}),
cEdge ? 0. : getA(${D}${coord01}),
rEdge || cEdge ? 0. : getA(${D}${coord11})`;
}
/**
* code snippet to setup 4 coordinates and edge conditions
*/
function getSetup(rank, dims, rows, cols) {
if (rank === 0 || rank === 1) {
return '';
}
// rank >= 2 for width+height pack.
else {
const setup = `
int r = ${dims[rank - 2]};
int c = ${dims[rank - 1]};
int rp1 = ${dims[rank - 2]} + 1;
int cp1 = ${dims[rank - 1]} + 1;
bool rEdge = rp1 >= ${cols};
bool cEdge = cp1 >= ${rows};
`;
return setup;
}
}
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/ops/packing-utils.ts":
/*!********************************************************!*\
!*** ./lib/onnxjs/backends/webgl/ops/packing-utils.ts ***!
\********************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.unpackFromChannel = exports.getChannels = exports.getVecChannels = void 0;
const utils_1 = __webpack_require__(/*! ../utils */ "./lib/onnxjs/backends/webgl/utils.ts");
function getVecChannels(name, rank) {
return (0, utils_1.getGlChannels)(rank).map(d => `${name}.${d}`);
}
exports.getVecChannels = getVecChannels;
function getChannels(name, rank) {
if (rank === 1) {
return [name];
}
return getVecChannels(name, rank);
}
exports.getChannels = getChannels;
function unpackFromChannel() {
return `
float getChannel(vec4 frag, int dim) {
int modCoord = imod(dim, 2);
return modCoord == 0 ? frag.r : frag.g;
}
float getChannel(vec4 frag, vec2 innerDims) {
vec2 modCoord = mod(innerDims, 2.);
return modCoord.x == 0. ?
(modCoord.y == 0. ? frag.r : frag.g) :
(modCoord.y == 0. ? frag.b : frag.a);
}
`;
}
exports.unpackFromChannel = unpackFromChannel;
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/ops/pad.ts":
/*!**********************************************!*\
!*** ./lib/onnxjs/backends/webgl/ops/pad.ts ***!
\**********************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.parsePadAttributesV11 = exports.padV11 = exports.parsePadAttributesV2 = exports.padV2 = void 0;
const attribute_with_cache_key_1 = __webpack_require__(/*! ../../../attribute-with-cache-key */ "./lib/onnxjs/attribute-with-cache-key.ts");
const util_1 = __webpack_require__(/*! ../../../util */ "./lib/onnxjs/util.ts");
const glsl_source_1 = __webpack_require__(/*! ../glsl-source */ "./lib/onnxjs/backends/webgl/glsl-source.ts");
const types_1 = __webpack_require__(/*! ../types */ "./lib/onnxjs/backends/webgl/types.ts");
const padProgramMetadata = {
name: 'Pad',
inputNames: ['A'],
inputTypes: [types_1.TextureType.unpacked],
};
const padV2 = (inferenceHandler, inputs, attributes) => {
validateInputsV2(inputs);
const output = inferenceHandler.run(Object.assign(Object.assign({}, padProgramMetadata), { cacheHint: attributes.cacheKey, get: () => createPadProgramInfo(inferenceHandler, inputs[0], attributes) }), inputs);
return [output];
};
exports.padV2 = padV2;
const parsePadAttributesV2 = (node) => {
const mode = node.attributes.getString('mode', 'constant');
const value = node.attributes.getFloat('value', 0.0);
const pads = node.attributes.getInts('pads');
return (0, attribute_with_cache_key_1.createAttributeWithCacheKey)({ mode, value, pads });
};
exports.parsePadAttributesV2 = parsePadAttributesV2;
const padV11 = (inferenceHandler, inputs, mode) => {
validateInputsV11(inputs);
const attrubutes = generatePadAttributesFromInputs(inferenceHandler, inputs, mode);
return (0, exports.padV2)(inferenceHandler, [inputs[0]], attrubutes);
};
exports.padV11 = padV11;
const parsePadAttributesV11 = (node) => node.attributes.getString('mode', 'constant');
exports.parsePadAttributesV11 = parsePadAttributesV11;
const generatePadAttributesFromInputs = (inferenceHandler, inputs, mode) => {
if (!inferenceHandler.session.isInitializer(inputs[1].dataId) ||
(inputs.length >= 3 && !inferenceHandler.session.isInitializer(inputs[2].dataId))) {
throw new Error('dynamic pad attributes are not allowed');
}
const pads = Array.from(inputs[1].integerData);
const value = (inputs.length >= 3) ? inputs[2].floatData[0] : 0.0;
return (0, attribute_with_cache_key_1.createAttributeWithCacheKey)({ mode, pads, value });
};
const createPadProgramInfo = (inferenceHandler, input, attributes) => {
const outputShape = util_1.ShapeUtil.padShape(input.dims.slice(), attributes.pads);
const rank = outputShape.length;
const padFunction = getPadFunction(inferenceHandler, input, attributes);
const shaderSource = `
${padFunction}
float process(int[${rank}] indices) {
return padA(indices);
}`;
return {
name: 'Pad',
inputNames: ['A'],
inputTypes: [types_1.TextureType.unpacked],
output: { dims: outputShape, type: input.type, textureType: types_1.TextureType.unpacked },
shaderSource
};
};
const validateInputsV2 = (inputs) => {
if (!inputs || inputs.length !== 1) {
throw new Error('Pad requires 1 input');
}
if (inputs[0].type !== 'float32' && inputs[0].type !== 'float64') {
throw new Error('Invalid input type.');
}
};
const validateInputsV11 = (inputs) => {
if (!inputs || (inputs.length !== 2 && inputs.length !== 3)) {
throw new Error('Pad requires 2 or 3 inputs');
}
if (inputs[1].type !== 'int32') {
throw new Error('Invalid input type.');
}
if (inputs.length >= 3 && inputs[2].type === 'string') {
throw new Error('Invalid input type.');
}
};
const getPadFunction = (inferenceHandler, input, attributes) => {
const glsl = (0, glsl_source_1.getGlsl)(inferenceHandler.session.backend.glContext.version);
const [width, height] = inferenceHandler.calculateTextureWidthAndHeight(input.dims, types_1.TextureType.unpacked);
const strides = util_1.ShapeUtil.computeStrides(input.dims);
switch (attributes.mode) {
case 'constant':
return getPadConstant(glsl, input.dims, strides, width, height, attributes.pads, attributes.value);
case 'reflect':
return getPadReflect(glsl, input.dims, strides, width, height, attributes.pads);
case 'edge':
return getPadEdge(glsl, input.dims, strides, width, height, attributes.pads);
default:
throw new Error('Invalid mode');
}
};
const getPadConstant = (glsl, shape, strides, width, height, pads, value) => {
const rank = shape.length;
let block = '';
for (let i = rank - 1; i >= 0; --i) {
block += `
k = m[${i}] - ${pads[i]};
if (k < 0) return constant;
if (k >= ${shape[i]}) return constant;
offset += k * ${strides[i]};
`;
}
return `
float padA(int m[${rank}]) {
const float constant = float(${value});
int offset = 0;
int k = 0;
${block}
vec2 coords = offsetToCoords(offset, ${width}, ${height});
float value = getColorAsFloat(${glsl.texture2D}(A, coords));
return value;
}
`;
};
const getPadReflect = (glsl, shape, strides, width, height, pads) => {
const rank = shape.length;
let block = '';
for (let i = rank - 1; i >= 0; --i) {
block += `
k = m[${i}] - ${pads[i]};
if (k < 0) { k = -k; }
{
const int _2n_1 = ${2 * (shape[i] - 1)};
k = int( mod( float(k), float(_2n_1) ) ) ;
if(k >= ${shape[i]}) { k = _2n_1 - k; }
}
offset += k * ${strides[i]};
`;
}
return `
float padA(int m[${rank}]) {
int offset = 0;
int k = 0;
${block}
vec2 coords = offsetToCoords(offset, ${width}, ${height});
float value = getColorAsFloat(${glsl.texture2D}(A, coords));
return value;
}
`;
};
const getPadEdge = (glsl, shape, strides, width, height, pads) => {
const rank = shape.length;
let block = '';
for (let i = rank - 1; i >= 0; --i) {
block += `
k = m[${i}] - ${pads[i]};
if (k < 0) k = 0;
if (k >= ${shape[i]}) k = ${shape[i] - 1};
offset += k * ${strides[i]};
`;
}
return `
float padA(int m[${rank}]) {
int offset = 0;
int k = 0;
${block}
vec2 coords = offsetToCoords(offset, ${width}, ${height});
float value = getColorAsFloat(${glsl.texture2D}(A, coords));
return value;
}
`;
};
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/ops/pool.ts":
/*!***********************************************!*\
!*** ./lib/onnxjs/backends/webgl/ops/pool.ts ***!
\***********************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.globalMaxPool = exports.parseMaxPoolAttributes = exports.maxPool = exports.parseGlobalAveragePoolAttributes = exports.globalAveragePool = exports.parseAveragePoolAttributes = exports.averagePool = void 0;
const attribute_with_cache_key_1 = __webpack_require__(/*! ../../../attribute-with-cache-key */ "./lib/onnxjs/attribute-with-cache-key.ts");
const util_1 = __webpack_require__(/*! ../../../util */ "./lib/onnxjs/util.ts");
const types_1 = __webpack_require__(/*! ../types */ "./lib/onnxjs/backends/webgl/types.ts");
const averagePool = (inferenceHandler, inputs, attributes) => {
validateInputs(inputs);
const metadata = { name: 'AveragePool', inputNames: ['X'], inputTypes: [types_1.TextureType.unpacked], cacheHint: attributes.cacheKey };
const output = inferenceHandler.run(Object.assign(Object.assign({}, metadata), { get: () => createAveragePoolProgramInfo(inputs, metadata, false, attributes) }), inputs);
return [output];
};
exports.averagePool = averagePool;
const parseAveragePoolAttributes = (node) => {
const autoPad = node.attributes.getString('auto_pad', 'NOTSET');
const ceilMode = node.attributes.getInt('ceil_mode', 0);
const countIncludePad = (node.attributes.getInt('count_include_pad', 0) === 0 ? false : true);
const kernelShape = node.attributes.getInts('kernel_shape');
const strides = node.attributes.getInts('strides', []);
const pads = node.attributes.getInts('pads', []);
// TODO: support attribute 'ceil_mode'
if (ceilMode !== 0) {
throw new Error('using ceil() in shape computation is not yet supported for AveragePool');
}
return (0, attribute_with_cache_key_1.createAttributeWithCacheKey)({ autoPad, ceilMode, countIncludePad, kernelShape, strides, pads });
};
exports.parseAveragePoolAttributes = parseAveragePoolAttributes;
const createAveragePoolProgramInfo = (inputs, metadata, isGlobalOperator, attributes) => {
const [adjustedAttributes, outputShape] = getAdjustedPoolAttributesAndOutputShape(inputs, attributes, isGlobalOperator);
const kernelSize = util_1.ShapeUtil.size(adjustedAttributes.kernelShape);
const op1 = 'value += _X(x);';
let op2 = '';
if (adjustedAttributes.countIncludePad) {
op2 += `value /= float(${kernelSize});`;
}
else {
op2 += `value /= float(${kernelSize} - pad);`;
}
const poolingCode = generatePoolingCode(inputs[0].dims, adjustedAttributes, op1, op2, '0.0');
const shaderSource = `
${poolingCode}
`;
return Object.assign(Object.assign({}, metadata), { output: { dims: outputShape, type: inputs[0].type, textureType: types_1.TextureType.unpacked }, shaderSource });
};
const globalAveragePool = (inferenceHandler, inputs, attributes) => {
validateInputs(inputs);
const metadata = {
name: 'GlobalAveragePool',
inputNames: ['X'],
inputTypes: [types_1.TextureType.unpacked],
cacheHint: `${attributes.countIncludePad}`
};
const output = inferenceHandler.run(Object.assign(Object.assign({}, metadata), { get: () => createAveragePoolProgramInfo(inputs, metadata, true, attributes) }), inputs);
return [output];
};
exports.globalAveragePool = globalAveragePool;
const parseGlobalAveragePoolAttributes = (node) => {
const countIncludePad = (node.attributes.getInt('count_include_pad', 0) === 0 ? false : true);
return (0, attribute_with_cache_key_1.createAttributeWithCacheKey)({ autoPad: '', ceilMode: 0, countIncludePad, kernelShape: [], strides: [], pads: [] });
};
exports.parseGlobalAveragePoolAttributes = parseGlobalAveragePoolAttributes;
const maxPool = (inferenceHandler, inputs, attributes) => {
validateInputs(inputs);
const metadata = { name: 'MaxPool', inputNames: ['X'], inputTypes: [types_1.TextureType.unpacked], cacheHint: attributes.cacheKey };
const output = inferenceHandler.run(Object.assign(Object.assign({}, metadata), { get: () => createMaxPoolProgramInfo(inputs, metadata, false, attributes) }), inputs);
return [output];
};
exports.maxPool = maxPool;
const parseMaxPoolAttributes = (node) => {
const autoPad = node.attributes.getString('auto_pad', 'NOTSET');
const ceilMode = node.attributes.getInt('ceil_mode', 0);
const kernelShape = node.attributes.getInts('kernel_shape');
const strides = node.attributes.getInts('strides', []);
const pads = node.attributes.getInts('pads', []);
const storageOrder = node.attributes.getInt('storage_order', 0);
const dilations = node.attributes.getInts('dilations', []);
// TODO: support attribute 'ceil_mode' and 'storage_order'
if (storageOrder !== 0) {
throw new Error('column major storage order is not yet supported for MaxPool');
}
if (ceilMode !== 0) {
throw new Error('using ceil() in shape computation is not yet supported for MaxPool');
}
return (0, attribute_with_cache_key_1.createAttributeWithCacheKey)({ autoPad, ceilMode, countIncludePad: false, kernelShape, strides, pads, storageOrder, dilations });
};
exports.parseMaxPoolAttributes = parseMaxPoolAttributes;
const createMaxPoolProgramInfo = (inputs, metadata, isGlobalOperator, attributes) => {
const [adjustedAttributes, outputShape] = getAdjustedPoolAttributesAndOutputShape(inputs, attributes, isGlobalOperator);
const op1 = `
value = max(_X(x), value);
`;
const op2 = '';
const poolingCode = generatePoolingCode(inputs[0].dims, adjustedAttributes, op1, op2, '-1e5');
const shaderSource = `
${poolingCode}
`;
return Object.assign(Object.assign({}, metadata), { output: { dims: outputShape, type: inputs[0].type, textureType: types_1.TextureType.unpacked }, shaderSource });
};
const getAdjustedPoolAttributesAndOutputShape = (inputs, attributes, isGlobalOperator) => {
const inputShape = inputs[0].dims.slice();
const hasDilations = Object.hasOwnProperty.call(attributes, 'dilations');
const kernelShape = attributes.kernelShape.slice();
const strides = attributes.strides.slice();
const dilations = hasDilations ? attributes.dilations.slice() : [];
const pads = attributes.pads.slice();
util_1.PoolConvUtil.adjustPoolAttributes(isGlobalOperator, inputShape, kernelShape, strides, dilations, pads);
const outputShape = util_1.PoolConvUtil.computePoolOutputShape(isGlobalOperator, inputShape, strides, dilations, kernelShape, pads, attributes.autoPad);
const newAttributes = Object.assign({}, attributes);
if (hasDilations) {
Object.assign(newAttributes, { kernelShape, strides, pads, dilations, cacheKey: attributes.cacheKey });
}
else {
Object.assign(newAttributes, { kernelShape, strides, pads, cacheKey: attributes.cacheKey });
}
return [newAttributes, outputShape];
};
const globalMaxPoolAttributes = {
autoPad: '',
ceilMode: 0,
countIncludePad: false,
kernelShape: [],
strides: [],
pads: [],
storageOrder: 0,
dilations: [],
cacheKey: ''
};
const globalMaxPoolMetadata = {
name: 'GlobalMaxPool',
inputNames: ['X'],
inputTypes: [types_1.TextureType.unpacked]
};
const globalMaxPool = (inferenceHandler, inputs) => {
validateInputs(inputs);
const output = inferenceHandler.run(Object.assign(Object.assign({}, globalMaxPoolMetadata), { get: () => createMaxPoolProgramInfo(inputs, globalMaxPoolMetadata, true, globalMaxPoolAttributes) }), inputs);
return [output];
};
exports.globalMaxPool = globalMaxPool;
const validateInputs = (inputs) => {
if (!inputs || inputs.length !== 1) {
throw new Error('Pool ops requires 1 input.');
}
if (inputs[0].type !== 'float32' && inputs[0].type !== 'float64') {
throw new Error('Invalid input type.');
}
};
const generatePoolingCode = (inputDims, attributes, op1, op2, start) => {
const rank = inputDims.length;
if (attributes.kernelShape.length <= 2) {
const kw = attributes.kernelShape[attributes.kernelShape.length - 1];
const sw = attributes.strides[attributes.strides.length - 1];
const pwStart = attributes.pads[attributes.pads.length / 2 - 1];
const pwEnd = attributes.pads[attributes.pads.length - 1];
const dimW = inputDims[rank - 1];
let codeW = '';
let codeH = '';
let codeHEnd = '';
if (pwStart + pwEnd !== 0) {
codeW = `
for (int i = 0; i < ${kw}; i++) {
x[${rank} - 1] = indices[${rank} - 1] * ${sw} - ${pwStart} + i;
if (x[${rank} - 1] < 0 || x[${rank} - 1] >= ${dimW}) {
pad++;
continue;
}
${op1}
}`;
}
else {
codeW = `
for (int i = 0; i < ${kw}; i++) {
x[${rank} - 1] = indices[${rank} - 1] * ${sw} - ${pwStart} + i;
${op1}
}`;
}
if (attributes.kernelShape.length === 2) {
const kh = attributes.kernelShape[attributes.kernelShape.length - 2];
const sh = attributes.strides[attributes.strides.length - 2];
const phStart = attributes.pads[attributes.pads.length / 2 - 2];
const phEnd = attributes.pads[attributes.pads.length - 2];
const dimH = inputDims[rank - 2];
if (phStart + phEnd !== 0) {
codeH = `
for (int j = 0; j < ${kh}; j++) {
x[${rank} - 2] = indices[${rank} - 2] * ${sh} - ${phStart} + j;
if (x[${rank} - 2] < 0 || x[${rank} - 2] >= ${dimH}) {
pad+= ${kw};
continue;
}
`;
}
else {
codeH = `
for (int j = 0; j < ${kh}; j++) {
x[${rank} - 2] = indices[${rank} - 2] * ${sh} - ${phStart} + j;
`;
}
codeHEnd = `
}
`;
}
const poolingCode = `
float process(int indices[${rank}]) {
int x[${rank}];
copyVec(indices, x);
float value = ${start};
int pad = 0;
${codeH}
${codeW}
${codeHEnd}
${op2}
return value;
}
`;
return poolingCode;
}
else {
const kernelSize = util_1.ShapeUtil.size(attributes.kernelShape);
const kernelStrides = util_1.ShapeUtil.computeStrides(attributes.kernelShape);
const stridesRank = kernelStrides.length;
const padsRank = attributes.pads.length;
const offsetToIndicesFunction = offsetToIndices(stridesRank);
const copyInputDims = copyArray(inputDims, 'inputDims');
const copyPads = copyArray(attributes.pads, 'pads');
const copyKernelStrides = copyArray(kernelStrides, 'kernelStrides');
const copyStrides = copyArray(attributes.strides, 'strides');
const hasPads = attributes.pads.reduce((sum, cur) => sum + cur);
let padCode = '';
if (hasPads) {
padCode = `
if (x[j] >= inputDims[j] || x[j] < 0) {
pad++;
isPad = true;
break;
}
}
if (!isPad) {
${op1}
}`;
}
else {
padCode = `
}
${op1}
`;
}
const poolingCode = `
${offsetToIndicesFunction}
float process(int indices[${rank}]) {
int x[${rank}];
copyVec(indices, x);
int offset[${stridesRank}];
int pads[${padsRank}];
int inputDims[${rank}];
int kernelStrides[${stridesRank}];
int strides[${stridesRank}];
${copyPads}
${copyInputDims}
${copyStrides}
${copyKernelStrides}
float value = ${start};
int pad = 0;
bool isPad = false;
for (int i = 0; i < ${kernelSize}; i++) {
offsetToIndices(i, kernelStrides, offset);
isPad = false;
for (int j = ${rank} - ${stridesRank}; j < ${rank}; j++) {
x[j] = indices[j] * strides[j - ${rank} + ${stridesRank}]
+ offset[j - ${rank} + ${stridesRank}] - pads[j - 2];
${padCode}
}
${op2}
return value;
}
`;
return poolingCode;
}
};
const copyArray = (array, arrayName) => {
let block = '';
for (let i = 0; i < array.length; i++) {
block += `
${arrayName}[${i}] = ${array[i]};
`;
}
return block;
};
const offsetToIndices = (rank) => `
void offsetToIndices(int offset, int[${rank}] strides, out int[${rank}] indices) {
if (${rank} == 0) {
return;
}
for (int i = 0; i < ${rank} - 1; ++i) {
indices[i] = offset / strides[i];
offset -= indices[i] * strides[i];
}
indices[${rank} - 1] = offset;
}`;
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/ops/reduce.ts":
/*!*************************************************!*\
!*** ./lib/onnxjs/backends/webgl/ops/reduce.ts ***!
\*************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.reduceLogSumSquare = exports.reduceLogSum = exports.reduceProd = exports.reduceMin = exports.reduceMax = exports.reduceMean = exports.reduceSum = exports.parseReduceAttributes = void 0;
const attribute_with_cache_key_1 = __webpack_require__(/*! ../../../attribute-with-cache-key */ "./lib/onnxjs/attribute-with-cache-key.ts");
const operators_1 = __webpack_require__(/*! ../../../operators */ "./lib/onnxjs/operators.ts");
const util_1 = __webpack_require__(/*! ../../../util */ "./lib/onnxjs/util.ts");
const types_1 = __webpack_require__(/*! ../types */ "./lib/onnxjs/backends/webgl/types.ts");
const reduce = (inferenceHandler, inputs, attributes, name, reduceOp) => {
validateInputs(inputs);
const reduceProgramMetadata = {
name,
inputNames: ['A'],
inputTypes: [types_1.TextureType.unpacked],
};
const output = inferenceHandler.run(Object.assign(Object.assign({}, reduceProgramMetadata), { cacheHint: attributes.cacheKey, get: () => createReduceProgramInfo(inferenceHandler, inputs, attributes, name, reduceOp, reduceProgramMetadata) }), inputs);
return [output];
};
const parseReduceAttributes = (node) => {
const axes = node.attributes.getInts('axes', []);
const keepDims = node.attributes.getInt('keepdims', 1) === 1;
return (0, attribute_with_cache_key_1.createAttributeWithCacheKey)({ axes, keepDims });
};
exports.parseReduceAttributes = parseReduceAttributes;
const createReduceProgramInfo = (handler, inputs, attributes, name, reduceOp, reduceProgramMetadata) => {
const outputShape = [];
const iRank = inputs[0].dims.length || 1;
const idxCopy = []; // copy output indexes to input indexes
const axes = util_1.ShapeUtil.normalizeAxes(attributes.axes, inputs[0].dims.length);
const ops = reduceOp(inputs, axes);
let reduceOps = ops[1];
for (let k = 0; k < inputs[0].dims.length; k++) {
// if this axis is reduced
if (axes.indexOf(k) >= 0 || axes.length === 0) {
if (attributes.keepDims) {
outputShape.push(1);
} // else { remove the axis from outputShape; }
// loop over the d-th axis
reduceOps = `
for(int j${k} = 0; j${k} < ${inputs[0].dims[k]}; j${k}++) {
inputIdx[${k}] = j${k};
${reduceOps}
}`;
}
else {
idxCopy.push(`inputIdx[${k}] = outputIdx[${outputShape.length}];`);
outputShape.push(inputs[0].dims[k]);
}
}
const oRank = outputShape.length || 1;
const shaderSource = `
float process(int outputIdx[${oRank}]) {
float value; // final result
int inputIdx[${iRank}]; // addressing input data
${idxCopy.join('\n')}
${ops[0]} // init ops for reduce max/min
${reduceOps}
${ops[2]} // final computation for reduce mean
return value;
}`;
return Object.assign(Object.assign({}, reduceProgramMetadata), { output: { dims: outputShape, type: inputs[0].type, textureType: types_1.TextureType.unpacked }, shaderSource });
};
const validateInputs = (inputs) => {
if (!inputs || inputs.length !== 1) {
throw new Error('Reduce op requires 1 input.');
}
if (operators_1.NUMBER_TYPES.indexOf(inputs[0].type) === -1) {
throw new Error('Invalid input type.');
}
};
const reduceSum = (inferenceHandler, inputs, attributes) => {
const reduceOp = () => ['value = 0.0;', 'value += _A(inputIdx);', ''];
return reduce(inferenceHandler, inputs, attributes, 'ReduceSum', reduceOp);
};
exports.reduceSum = reduceSum;
const reduceMean = (inferenceHandler, inputs, attributes) => {
const reduceOp = (inputs, axes) => {
let size = 1.0;
for (let k = 0; k < inputs[0].dims.length; k++) {
if (axes.indexOf(k) >= 0 || axes.length === 0) {
size *= inputs[0].dims[k];
}
}
return ['value = 0.0;', 'value += _A(inputIdx);', `value /= ${size}.;`]; // ensure real number with `.`
};
return reduce(inferenceHandler, inputs, attributes, 'ReduceMean', reduceOp);
};
exports.reduceMean = reduceMean;
const reduceMax = (inferenceHandler, inputs, attributes) => {
const reduceOp = (inputs, axes) => {
const idxZero = [];
for (let k = 0; k < inputs[0].dims.length; k++) {
if (axes.indexOf(k) >= 0 || axes.length === 0) {
idxZero.push(`inputIdx[${k}] = 0;`); // first element
}
}
return [`${idxZero.join('\n')}\nvalue = _A(inputIdx);`, 'value = max(value, _A(inputIdx));', ''];
};
return reduce(inferenceHandler, inputs, attributes, 'ReduceMax', reduceOp);
};
exports.reduceMax = reduceMax;
const reduceMin = (inferenceHandler, inputs, attributes) => {
const reduceOp = (inputs, axes) => {
const idxZero = [];
for (let k = 0; k < inputs[0].dims.length; k++) {
if (axes.indexOf(k) >= 0 || axes.length === 0) {
idxZero.push(`inputIdx[${k}] = 0;`); // first element
}
}
return [`${idxZero.join('\n')}\nvalue = _A(inputIdx);`, 'value = min(value, _A(inputIdx));', ''];
};
return reduce(inferenceHandler, inputs, attributes, 'ReduceMin', reduceOp);
};
exports.reduceMin = reduceMin;
const reduceProd = (inferenceHandler, inputs, attributes) => {
const reduceOp = () => ['value = 1.0;', 'value *= _A(inputIdx);', ''];
return reduce(inferenceHandler, inputs, attributes, 'ReduceProd', reduceOp);
};
exports.reduceProd = reduceProd;
const reduceLogSum = (inferenceHandler, inputs, attributes) => {
const reduceOp = () => ['value = 0.0;', 'value += _A(inputIdx);', 'value = log(value);'];
return reduce(inferenceHandler, inputs, attributes, 'ReduceLogSum', reduceOp);
};
exports.reduceLogSum = reduceLogSum;
const reduceLogSumSquare = (inferenceHandler, inputs, attributes) => {
const reduceOp = () => ['float t; value = 0.0;', 't = _A(inputIdx); value += t * t;', ''];
return reduce(inferenceHandler, inputs, attributes, 'ReduceLogSumSquare', reduceOp);
};
exports.reduceLogSumSquare = reduceLogSumSquare;
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/ops/reshape-packed.ts":
/*!*********************************************************!*\
!*** ./lib/onnxjs/backends/webgl/ops/reshape-packed.ts ***!
\*********************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.isReshapeCheap = exports.processDims3D = exports.createPackedReshape3DProgramInfoLoader = void 0;
const util_1 = __webpack_require__(/*! ../../../util */ "./lib/onnxjs/util.ts");
const glsl_source_1 = __webpack_require__(/*! ../glsl-source */ "./lib/onnxjs/backends/webgl/glsl-source.ts");
const types_1 = __webpack_require__(/*! ../types */ "./lib/onnxjs/backends/webgl/types.ts");
const packing_utils_1 = __webpack_require__(/*! ./packing-utils */ "./lib/onnxjs/backends/webgl/ops/packing-utils.ts");
const createPackedReshape3DProgramMetadata = (outputShape3D) => ({ name: 'Reshape (packed)', inputTypes: [types_1.TextureType.packed], inputNames: ['A'], cacheHint: `${outputShape3D}` });
const createPackedReshape3DProgramInfo = (handler, input3D, metadata, outputShape3D) => {
const inputShape3D = input3D.dims;
const squeezedOutputShape = outputShape3D;
let mainLoop = '';
for (let i = 0; i < 4; i++) {
let outputCoords = '';
switch (i) {
case 0:
outputCoords = 'outputCoords = rc;';
break;
case 1:
outputCoords = 'outputCoords = ivec3(rc.x, rc.y+1, rc.z);';
break;
case 2:
outputCoords = 'outputCoords = ivec3(rc.x, rc.y, rc.z+1);';
break;
case 3:
outputCoords = 'outputCoords = ivec3(rc.x, rc.y+1, rc.z+1);';
break;
default:
throw new Error();
}
mainLoop += `
${outputCoords}
${i > 0 ? 'if(outputCoords.y < rows && outputCoords.z < cols){' : ''}
int flattenedIndex = getFlattenedIndex(outputCoords);
ivec3 inputRC = inputCoordsFromReshapedOutCoords(flattenedIndex);
vec2 innerDims = vec2(float(inputRC.y),float(inputRC.z));
result[${i}] = getChannel(getA(inputRC.x, inputRC.y, inputRC.z), innerDims);
${i > 0 ? '}' : ''}
`;
}
const glsl = (0, glsl_source_1.getGlsl)(handler.session.backend.glContext.version);
const shaderSource = `
${getReshapedInputCoords(inputShape3D)}
${getFlattenedIndexFrom3D(squeezedOutputShape)}
${(0, packing_utils_1.unpackFromChannel)()}
void main() {
ivec3 rc = getOutputCoords();
vec4 result = vec4(0.0);
ivec3 outputCoords;
int rows = ${squeezedOutputShape[2]};
int cols = ${squeezedOutputShape[1]};
${mainLoop}
${glsl.output} = result;
}
`;
return Object.assign(Object.assign({}, metadata), { output: { dims: squeezedOutputShape, type: input3D.type, textureType: types_1.TextureType.packed }, shaderSource, hasMain: true });
};
const createPackedReshape3DProgramInfoLoader = (handler, input3D, outputShape3D) => {
const metadata = createPackedReshape3DProgramMetadata(outputShape3D);
return Object.assign(Object.assign({}, metadata), { get: () => createPackedReshape3DProgramInfo(handler, input3D, metadata, outputShape3D) });
};
exports.createPackedReshape3DProgramInfoLoader = createPackedReshape3DProgramInfoLoader;
function processDims3D(shape) {
if (shape.length === 0) {
return [1, 1, 1];
}
// TODO: squeeze other shapes to 2D case
let batch = 1;
for (let i = 0; i < shape.length - 2; ++i) {
batch *= shape[i];
}
return [batch, shape.length > 1 ? shape[shape.length - 2] : 1, shape[shape.length - 1]];
}
exports.processDims3D = processDims3D;
// For packed reshape, we need to re-arrange texel data for output shape.
// Our pack is designed to pack a 2x2 tile in last h and w dimension, so
// for the reshaped new tensor, we just need to re-arrange the last h and
// w dimension. For any shape that is not in 3D, i.e. [batch, W, H], we
// first convert it to 3D by collapsing other dimension to batch dim, then
// process with the last two dimensions.
// Note: we only need the shape tensor to calculate output shape, so the
// content in shape tensor is never uploaded to GPU. It is always kept in CPU.
// TODO: optimize the algorithm -- in some cases, if the last two dims are
// the same between input shape and output shape, the packed reshape can be
// treated as no-op.
function isReshapeCheap(dims, reshapedDims) {
let isCheapReshape = false;
if (dims.length === 0 || reshapedDims.length === 0) { // scalar
isCheapReshape = true;
}
else if (dims.length < 2 || reshapedDims.length < 2) { // 1D
isCheapReshape = dims[dims.length - 1] === reshapedDims[reshapedDims.length - 1];
}
else { // 2D +
isCheapReshape = dims[dims.length - 1] === reshapedDims[reshapedDims.length - 1] &&
dims[dims.length - 2] === reshapedDims[reshapedDims.length - 2];
}
return isCheapReshape;
}
exports.isReshapeCheap = isReshapeCheap;
function getReshapedInputCoords(shape) {
const strides = util_1.ShapeUtil.computeStrides(shape);
const coords = ['b', 'r', 'c'];
const index = 'index';
const coordsFromIndexSnippet = strides
.map((stride, i) => {
const line1 = `int ${coords[i]} = ${index} / ${stride}`;
const line2 = i === strides.length - 1 ?
`int ${coords[i + 1]} = ${index} - ${coords[i]} * ${stride}` :
`index -= ${coords[i]} * ${stride}`;
return `${line1}; ${line2};`;
})
.join('');
return `
ivec3 inputCoordsFromReshapedOutCoords(int index) {
${coordsFromIndexSnippet}
return ivec3(b, r, c);
}
`;
}
function getFlattenedIndexFrom3D(shape) {
const strides = util_1.ShapeUtil.computeStrides(shape);
return `
int getFlattenedIndex(ivec3 coords) {
// reverse y, z order
return coords.x * ${strides[0]} + coords.z * ${strides[1]} + coords.y;
}
`;
}
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/ops/reshape.ts":
/*!**************************************************!*\
!*** ./lib/onnxjs/backends/webgl/ops/reshape.ts ***!
\**************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.reshape = void 0;
const util_1 = __webpack_require__(/*! ../../../util */ "./lib/onnxjs/util.ts");
const reshape = (handler, inputs) => {
const reshapedDims = util_1.ShapeUtil.calculateReshapedDims(inputs[0].dims, inputs[1].integerData);
if (handler.session.pack) {
return [handler.reshapePacked(inputs[0], reshapedDims)];
}
else {
return [handler.reshapeUnpacked(inputs[0], reshapedDims)];
}
};
exports.reshape = reshape;
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/ops/resize-packed.ts":
/*!********************************************************!*\
!*** ./lib/onnxjs/backends/webgl/ops/resize-packed.ts ***!
\********************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.parseResizeAttributesV11 = exports.parseResizeAttributesV10 = exports.resize = void 0;
const glsl_source_1 = __webpack_require__(/*! ../glsl-source */ "./lib/onnxjs/backends/webgl/glsl-source.ts");
const types_1 = __webpack_require__(/*! ../types */ "./lib/onnxjs/backends/webgl/types.ts");
const utils_1 = __webpack_require__(/*! ../utils */ "./lib/onnxjs/backends/webgl/utils.ts");
const packing_utils_1 = __webpack_require__(/*! ./packing-utils */ "./lib/onnxjs/backends/webgl/ops/packing-utils.ts");
const upsample_1 = __webpack_require__(/*! ./upsample */ "./lib/onnxjs/backends/webgl/ops/upsample.ts");
const resizeProgramMetadata = {
name: 'Resize',
inputNames: ['A'],
inputTypes: [types_1.TextureType.packed]
};
const resize = (inferenceHandler, inputs, attributes) => {
(0, upsample_1.validateInputs)(inputs, attributes);
const output = inferenceHandler.run(Object.assign(Object.assign({}, resizeProgramMetadata), { cacheHint: attributes.cacheKey, get: () => createPackedResizeProgramInfo(inferenceHandler, inputs, attributes) }), inputs);
return [output];
};
exports.resize = resize;
const parseResizeAttributesV10 = (node) => (0, upsample_1.parseUpsampleAttributes)(node, 10);
exports.parseResizeAttributesV10 = parseResizeAttributesV10;
const parseResizeAttributesV11 = (node) => (0, upsample_1.parseUpsampleAttributes)(node, 11);
exports.parseResizeAttributesV11 = parseResizeAttributesV11;
const createPackedResizeProgramInfo = (inferenceHandler, inputs, attributes) => {
const glsl = (0, glsl_source_1.getGlsl)(inferenceHandler.session.backend.glContext.version);
const [scales, outputShape] = prepareInputs(inputs, attributes);
const isSame = scales.every((s) => s === 1) && attributes.coordinateTransformMode !== 'tf_crop_and_resize';
if (isSame) {
return Object.assign(Object.assign({}, resizeProgramMetadata), { output: { dims: outputShape, type: inputs[0].type, textureType: types_1.TextureType.packed }, hasMain: true, shaderSource: `void main() {
vec4 v = ${glsl.texture2D}(X, TexCoords);
${glsl.output} = v;
}` });
}
const dim = outputShape.length;
if (dim < 2) {
throw new Error(`output dimension should be at least 2, but got ${dim}`);
}
const outputHeight = outputShape[dim - 2];
const outputWidth = outputShape[dim - 1];
const inputShape = inputs[0].dims;
if (dim !== inputShape.length) {
throw new Error(`output dimension should match input ${inputShape.length}, but got ${dim}`);
}
const inputHeight = inputShape[dim - 2];
const inputWidth = inputShape[dim - 1];
const scalesHeight = scales[dim - 2];
const scalesWidth = scales[dim - 1];
let getSourceFracIndex = '';
if (attributes.mode !== 'linear') {
// TODO: support other modes
throw new Error(`resize (packed) does not support mode: '${attributes.mode}'`);
}
switch (attributes.coordinateTransformMode) {
case 'asymmetric':
getSourceFracIndex = `
vec4 getSourceFracIndex(ivec4 coords) {
return vec4(coords) / scaleWHWH;
}
`;
break;
case 'half_pixel':
getSourceFracIndex = `
vec4 getSourceFracIndex(ivec4 coords) {
return (vec4(coords) + 0.5) / scaleWHWH - 0.5;
}
`;
break;
case 'pytorch_half_pixel':
getSourceFracIndex = `
vec4 getSourceFracIndex(ivec4 coords) {
vec4 fcoords = vec4(coords);
return vec4(
${outputWidth}.0 > 1.0 ? (fcoords.x + 0.5) / scaleWHWH.x - 0.5 : 0.0,
${outputHeight}.0 > 1.0 ? (fcoords.y + 0.5) / scaleWHWH.y - 0.5 : 0.0,
${outputWidth}.0 > 1.0 ? (fcoords.z + 0.5) / scaleWHWH.z - 0.5 : 0.0,
${outputHeight}.0 > 1.0 ? (fcoords.w + 0.5) / scaleWHWH.w - 0.5 : 0.0
);
}
`;
break;
case 'align_corners':
getSourceFracIndex = `
vec4 getSourceFracIndex(ivec4 coords) {
vec4 resized = vec4(${outputWidth}.0 - 1.0, ${outputHeight}.0 - 1.0, ${outputWidth}.0 - 1.0,
${outputHeight}.0 - 1.0);
vec4 original = vec4(${inputWidth}.0 - 1.0, ${inputHeight}.0 - 1.0, ${inputWidth}.0 - 1.0,
${inputHeight}.0 - 1.0);
vec4 new_scale = original / resized;
return vec4(coords) * new_scale;
}
`;
break;
default:
// TODO:supporting other coordinateTransformModes
throw new Error(`resize (packed) does not support coordinateTransformMode: \
'${attributes.coordinateTransformMode}'`);
}
const coordsDataType = (0, utils_1.getCoordsDataType)(dim);
const unpackChannel = (0, packing_utils_1.unpackFromChannel)();
const shaderSource = `
const vec2 inputWH = vec2(${inputHeight}.0, ${inputWidth}.0);
const vec4 scaleWHWH = vec4(float(${scalesHeight}), float(${scalesWidth}), float(${scalesHeight}), float(${scalesWidth}));
${unpackChannel}
${getSourceFracIndex}
float getAValue(int x10, int r, int c, int d) {
return getChannel(getA(x10, r, c, d), vec2(c, d));
}
void main() {
${coordsDataType} rc = getOutputCoords();
int batch = rc[0];
int depth = rc[1];
// retrieve the 4 coordinates that is used in the 4 packed output values.
ivec4 coords = ivec4(rc.wz, rc.w + 1, rc.z + 1);
// calculate the source index in fraction
vec4 sourceFrac = getSourceFracIndex(coords);
// get the lower and upper bound of the 4 values that will be packed into one texel.
ivec4 x00 = ivec4(max(sourceFrac.xy, vec2(0.0)), min(inputWH - 1.0, ceil(sourceFrac.xy)));
ivec4 x01 = ivec4(max(sourceFrac.xw, vec2(0.0)), min(inputWH - 1.0, ceil(sourceFrac.xw)));
ivec4 x10 = ivec4(max(sourceFrac.zy, vec2(0.0)), min(inputWH - 1.0, ceil(sourceFrac.zy)));
ivec4 x11 = ivec4(max(sourceFrac.zw, vec2(0.0)), min(inputWH - 1.0, ceil(sourceFrac.zw)));
bool hasNextRow = rc.w < ${outputHeight - 1};
bool hasNextCol = rc.z < ${outputWidth - 1};
// pack x00, x01, x10, x11's top-left corner into one vec4 structure
vec4 topLeft = vec4(
getAValue(batch, depth, x00.x, x00.y),
hasNextCol ? getAValue(batch, depth, x01.x, x01.y) : 0.0,
hasNextRow ? getAValue(batch, depth, x10.x, x10.y) : 0.0,
(hasNextRow && hasNextCol) ? getAValue(batch, depth, x11.x, x11.y) : 0.0);
// pack x00, x01, x10, x11's top-right corner into one vec4 structure
vec4 topRight = vec4(
getAValue(batch, depth, x00.x, x00.w),
hasNextCol ? getAValue(batch, depth, x01.x, x01.w) : 0.0,
hasNextRow ? getAValue(batch, depth, x10.x, x10.w) : 0.0,
(hasNextRow && hasNextCol) ? getAValue(batch, depth, x11.x, x11.w) : 0.0);
// pack x00, x01, x10, x11's bottom-left corner into one vec4 structure
vec4 bottomLeft = vec4(
getAValue(batch, depth, x00.z, x00.y),
hasNextCol ? getAValue(batch, depth, x01.z, x01.y) : 0.0,
hasNextRow ? getAValue(batch, depth, x10.z, x10.y) : 0.0,
(hasNextRow && hasNextCol) ? getAValue(batch, depth, x11.z, x11.y) : 0.0);
// pack x00, x01, x10, x11's bottom-right corner into one vec4 structure
vec4 bottomRight = vec4(
getAValue(batch, depth, x00.z, x00.w),
hasNextCol ? getAValue(batch, depth, x01.z, x01.w) : 0.0,
hasNextRow ? getAValue(batch, depth, x10.z, x10.w) : 0.0,
(hasNextRow && hasNextCol) ? getAValue(batch, depth, x11.z, x11.w) : 0.0);
// calculate the interpolation fraction on u and v direction
vec4 frac = vec4(sourceFrac) - floor(sourceFrac);
vec4 clampFrac = clamp(frac, vec4(0.0), vec4(1.0));
vec4 top = mix(topLeft, topRight, clampFrac.ywyw);
vec4 bottom = mix(bottomLeft, bottomRight, clampFrac.ywyw);
vec4 newValue = mix(top, bottom, clampFrac.xxzz);
${glsl.output} = vec4(newValue);
}
`;
return Object.assign(Object.assign({}, resizeProgramMetadata), { output: { dims: outputShape, type: inputs[0].type, textureType: types_1.TextureType.packed }, hasMain: true, shaderSource });
};
const prepareInputs = (inputs, attributes) => {
const x = inputs[0];
const xDims = x.dims;
let scales = attributes.scales;
let outputSizes;
if (scales.length === 0) {
const scalesTensor = inputs[attributes.scalesInputIdx];
if (scalesTensor && scalesTensor.size !== 0) {
if (inputs[attributes.sizesInputIdx]) {
throw new Error('Only one of scales or sizes must be provided as input.');
}
scales = parseScalesData(scalesTensor, attributes.mode, attributes.isResize);
}
else {
const sizesTensor = inputs[attributes.sizesInputIdx];
if (!sizesTensor || sizesTensor.size === 0) {
throw new Error('Either scales or sizes MUST be provided as input.');
}
outputSizes = Array.from(sizesTensor.integerData);
scales = parseScalesDataFromOutputSize(outputSizes, xDims, attributes.mode, attributes.isResize);
}
}
else {
if (inputs[attributes.sizesInputIdx]) {
throw new Error('Only one of scales or sizes must be provided as input.');
}
}
const yDims = outputSizes || (xDims.map((dim, i) => Math.floor(dim * scales[i])));
return [scales, yDims];
};
const parseScalesData = (scale, mode, isResize) => {
const scales = Array.from(scale.floatData);
(0, upsample_1.scalesValidation)(scales, mode, isResize);
return scales;
};
const parseScalesDataFromOutputSize = (yDims, xDims, mode, isResize) => {
const length = xDims.length;
const scales = new Array(length);
for (let i = 0, end = length; i < end; i++) {
if (xDims[i] === 0) {
if (yDims[i] !== 0) {
throw new Error('Input dim is zero but required output dim is non-zero.');
}
scales[i] = 1;
}
else {
scales[i] = yDims[i] / xDims[i];
}
}
(0, upsample_1.scalesValidation)(scales, mode, isResize);
return scales;
};
// roi data is not used yet. but leave here for future usage.
// const getRoi = (inputs: Tensor[], attributes: UpsampleAttributes) : number[] => {
// let roi: number[] = [];
// if (attributes.needRoiInput) {
// if (attributes.roiInputIdx <= 0) {
// throw new Error('Invalid roi input index.');
// }
// const roiTensor = inputs[attributes.roiInputIdx];
// roi = roiTensor.size > 0 ? Array.from(roiTensor.floatData) : [];
// } else {
// roi = new Array(inputs[0].dims.length * 2).fill(0);
// }
// return roi;
// };
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/ops/shape.ts":
/*!************************************************!*\
!*** ./lib/onnxjs/backends/webgl/ops/shape.ts ***!
\************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.shape = void 0;
const tensor_1 = __webpack_require__(/*! ../../../tensor */ "./lib/onnxjs/tensor.ts");
const shape = (inferenceHandler, inputs) => {
validateInputs(inputs);
return [new tensor_1.Tensor([inputs[0].dims.length], 'int32', undefined, undefined, new Int32Array(inputs[0].dims))];
};
exports.shape = shape;
const validateInputs = (inputs) => {
if (!inputs || inputs.length !== 1) {
throw new Error('Shape requires 1 input.');
}
};
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/ops/slice.ts":
/*!************************************************!*\
!*** ./lib/onnxjs/backends/webgl/ops/slice.ts ***!
\************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.sliceV10 = exports.parseSliceAttributes = exports.slice = void 0;
const attribute_with_cache_key_1 = __webpack_require__(/*! ../../../attribute-with-cache-key */ "./lib/onnxjs/attribute-with-cache-key.ts");
const operators_1 = __webpack_require__(/*! ../../../operators */ "./lib/onnxjs/operators.ts");
const util_1 = __webpack_require__(/*! ../../../util */ "./lib/onnxjs/util.ts");
const types_1 = __webpack_require__(/*! ../types */ "./lib/onnxjs/backends/webgl/types.ts");
const sliceProgramMetadata = {
name: 'Slice',
inputNames: ['A'],
inputTypes: [types_1.TextureType.unpacked]
};
const slice = (inferenceHandler, inputs, attributes) => {
validateInputs(inputs);
const output = inferenceHandler.run(Object.assign(Object.assign({}, sliceProgramMetadata), { cacheHint: attributes.cacheKey, get: () => createSliceProgramInfo(inferenceHandler, inputs[0], attributes) }), inputs);
return [output];
};
exports.slice = slice;
const parseSliceAttributes = (node) => {
const starts = node.attributes.getInts('starts');
const ends = node.attributes.getInts('ends');
const axes = node.attributes.getInts('axes', []);
return (0, attribute_with_cache_key_1.createAttributeWithCacheKey)({ starts, ends, axes });
};
exports.parseSliceAttributes = parseSliceAttributes;
const createSliceProgramInfo = (inferenceHandler, input, attributes) => {
const axes = (attributes.axes.length === 0) ? input.dims.slice(0).map((val, i) => i) : attributes.axes;
const normalizedAxes = util_1.ShapeUtil.normalizeAxes(axes, input.dims.length);
const starts = attributes.starts.map((start, i) => {
if (start > input.dims[normalizedAxes[i]] - 1) {
return input.dims[normalizedAxes[i]];
}
return util_1.ShapeUtil.normalizeAxis(start, input.dims[normalizedAxes[i]]);
});
const ends = attributes.ends.map((end, i) => {
if (end > input.dims[normalizedAxes[i]] - 1) {
return input.dims[normalizedAxes[i]];
}
return util_1.ShapeUtil.normalizeAxis(end, input.dims[normalizedAxes[i]]);
});
const outputShape = input.dims.slice();
const sliceOps = [];
for (let i = 0; i < normalizedAxes.length; i++) {
outputShape[normalizedAxes[i]] = ends[i] - starts[i];
if (starts[i] > 0) {
sliceOps.push(`outputIdx[${normalizedAxes[i]}] += ${starts[i]};`);
} // else { sliceOps.push(`outputIdx[${normalizedAxes[i]}] += 0;`); }
}
const rank = outputShape.length;
const shaderSource = `
float process(int outputIdx[${rank}]) {
${sliceOps.join('\n ')}
return _A(outputIdx);
}`;
return Object.assign(Object.assign({}, sliceProgramMetadata), { output: { dims: outputShape, type: input.type, textureType: types_1.TextureType.unpacked }, shaderSource });
};
const validateInputs = (inputs) => {
if (!inputs || inputs.length !== 1) {
throw new Error('Slice requires 1 input.');
}
if (operators_1.NUMBER_TYPES.indexOf(inputs[0].type) === -1) {
throw new Error('Invalid input type.');
}
};
const sliceV10 = (inferenceHandler, inputs) => {
validateInputsV10(inputs);
const attributes = generateSliceAttributesFromInputs(inferenceHandler, inputs);
const output = inferenceHandler.run(Object.assign(Object.assign({}, sliceProgramMetadata), { cacheHint: attributes.cacheKey, get: () => createSliceProgramInfo(inferenceHandler, inputs[0], attributes) }), [inputs[0]]);
return [output];
};
exports.sliceV10 = sliceV10;
const generateSliceAttributesFromInputs = (inferenceHandler, inputs) => {
if (!inferenceHandler.session.isInitializer(inputs[1].dataId) ||
!inferenceHandler.session.isInitializer(inputs[2].dataId) ||
(inputs.length >= 4 && !inferenceHandler.session.isInitializer(inputs[3].dataId)) ||
(inputs.length >= 5 && !inferenceHandler.session.isInitializer(inputs[4].dataId))) {
throw new Error('dynamic slice attributes are not allowed');
}
if (inputs.length >= 5 && inputs[4].integerData.some((i) => i !== 1)) {
throw new Error('currently non-1 steps is not supported for Slice');
}
const starts = Array.from(inputs[1].integerData);
const ends = Array.from(inputs[2].integerData);
const axes = inputs.length >= 4 ? Array.from(inputs[3].integerData) : [];
const cacheKey = `${axes};${starts};${ends}`;
return { starts, ends, axes, cacheKey };
};
const validateInputsV10 = (inputs) => {
if (!inputs || inputs.length < 3 || inputs.length > 5) {
throw new Error('Invalid input number.');
}
if (inputs[1].type !== 'int32' || inputs[1].dims.length !== 1) {
throw new Error('Invalid input type.');
}
if (inputs[2].type !== 'int32' || inputs[2].dims.length !== 1) {
throw new Error('Invalid input type.');
}
if (inputs.length >= 4 && (inputs[3].type !== 'int32' || inputs[3].dims.length !== 1)) {
throw new Error('Invalid input type.');
}
if (inputs.length >= 5 && (inputs[4].type !== 'int32' || inputs[4].dims.length !== 1)) {
throw new Error('Invalid input type.');
}
};
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/ops/softmax.ts":
/*!**************************************************!*\
!*** ./lib/onnxjs/backends/webgl/ops/softmax.ts ***!
\**************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.softmaxV13 = exports.parseSoftmaxAttributesV13 = exports.parseSoftmaxAttributes = exports.softmax = void 0;
const attribute_with_cache_key_1 = __webpack_require__(/*! ../../../attribute-with-cache-key */ "./lib/onnxjs/attribute-with-cache-key.ts");
const util_1 = __webpack_require__(/*! ../../../util */ "./lib/onnxjs/util.ts");
const glsl_source_1 = __webpack_require__(/*! ../glsl-source */ "./lib/onnxjs/backends/webgl/glsl-source.ts");
const types_1 = __webpack_require__(/*! ../types */ "./lib/onnxjs/backends/webgl/types.ts");
const transpose_1 = __webpack_require__(/*! ./transpose */ "./lib/onnxjs/backends/webgl/ops/transpose.ts");
const softmaxComputeMaxProgramMetadata = {
name: 'SoftmaxComputeMax',
inputNames: ['A'],
inputTypes: [types_1.TextureType.unpacked],
};
const softmaxComputeScaleProgramMetadata = {
name: 'SoftmaxComputeScale',
inputNames: ['A', 'Max'],
inputTypes: [types_1.TextureType.unpacked, types_1.TextureType.unpacked],
};
const softmaxProgramMetadata = {
name: 'SoftMax',
inputNames: ['A', 'Max', 'Norm'],
inputTypes: [types_1.TextureType.unpacked, types_1.TextureType.unpacked, types_1.TextureType.unpacked],
};
const softmax = (inferenceHandler, inputs, attributes) => {
validateInputs(inputs);
const inputShape = inputs[0].dims.slice();
const axis = util_1.ShapeUtil.normalizeAxis(attributes.axis, inputShape.length);
const logicalRowCount = util_1.ShapeUtil.sizeToDimension(inputShape, axis);
const featureCount = util_1.ShapeUtil.sizeFromDimension(inputShape, axis);
const output = computeSoftmax(inferenceHandler, inputs, attributes, logicalRowCount, featureCount);
return output;
};
exports.softmax = softmax;
const parseSoftmaxAttributes = (node) => (0, attribute_with_cache_key_1.createAttributeWithCacheKey)({ axis: node.attributes.getInt('axis', 1) });
exports.parseSoftmaxAttributes = parseSoftmaxAttributes;
const parseSoftmaxAttributesV13 = (node) => (0, attribute_with_cache_key_1.createAttributeWithCacheKey)({ axis: node.attributes.getInt('axis', -1) });
exports.parseSoftmaxAttributesV13 = parseSoftmaxAttributesV13;
// The "semantic" meaning of axis has changed in opset-13.
// Please compare: https://github.com/onnx/onnx/blob/main/docs/Operators.md#Softmax
// with https://github.com/onnx/onnx/blob/main/docs/Changelog.md#Softmax-11 for detailed explanations
// To account for the opset-13 behavior, our plan will be to transpose the "axis" dim to the innermost dim
// and perform softmax and then reverse the transpose. We can skip the transposing aspect if the axis is already
// the innermost dim
const softmaxV13 = (inferenceHandler, inputs, attributes) => {
validateInputs(inputs);
const inputShape = inputs[0].dims.slice();
const axis = util_1.ShapeUtil.normalizeAxis(attributes.axis, inputShape.length);
const rank = inputShape.length;
const isTransposeRequired = (axis !== rank - 1) ? true : false;
const transposedInputShape = [];
let perm = [];
let transposedInputs = [];
let transposeAttribute;
if (isTransposeRequired) {
perm = Array.from({ length: rank }).map((_, i) => i);
// swap the innermost dim with the dim corresponding to axis
perm[axis] = rank - 1;
perm[rank - 1] = axis;
perm.map(p => transposedInputShape.push(inputShape[p]));
transposeAttribute = (0, attribute_with_cache_key_1.createAttributeWithCacheKey)({ perm });
transposedInputs = (0, transpose_1.transpose)(inferenceHandler, inputs, transposeAttribute);
}
const logicalRowCount = isTransposeRequired ? util_1.ShapeUtil.sizeToDimension(transposedInputShape, rank - 1) :
util_1.ShapeUtil.sizeToDimension(inputShape, rank - 1);
const featureCount = isTransposeRequired ? util_1.ShapeUtil.sizeFromDimension(transposedInputShape, rank - 1) :
util_1.ShapeUtil.sizeFromDimension(inputShape, rank - 1);
const output = computeSoftmax(inferenceHandler, isTransposeRequired ? transposedInputs : inputs, attributes, logicalRowCount, featureCount);
if (isTransposeRequired) {
const reversedOutput = (0, transpose_1.transpose)(inferenceHandler, output, transposeAttribute);
return reversedOutput;
}
else {
return output;
}
};
exports.softmaxV13 = softmaxV13;
const computeSoftmax = (inferenceHandler, inputs, attributes, logicalRowCount, featureCount) => {
const computeMaxProgramInfo = createComputeMaxProgramInfo(inferenceHandler, inputs[0], logicalRowCount, featureCount, [logicalRowCount]);
const max = inferenceHandler.run(Object.assign(Object.assign({}, softmaxComputeMaxProgramMetadata), { cacheHint: attributes.cacheKey, get: () => computeMaxProgramInfo }), inputs);
const computeScaleProgramInfo = createComputScaleProgramInfo(inferenceHandler, inputs[0], logicalRowCount, featureCount, computeMaxProgramInfo.output.dims, [logicalRowCount]);
const scale = inferenceHandler.run(Object.assign(Object.assign({}, softmaxComputeScaleProgramMetadata), { cacheHint: attributes.cacheKey, get: () => computeScaleProgramInfo }), [inputs[0], max]);
const softMaxProgramInfo = createSoftMaxProgramInfo(inferenceHandler, inputs[0], logicalRowCount, featureCount, computeMaxProgramInfo.output.dims, computeScaleProgramInfo.output.dims);
const output = inferenceHandler.run(Object.assign(Object.assign({}, softmaxProgramMetadata), { cacheHint: attributes.cacheKey, get: () => softMaxProgramInfo }), [inputs[0], max, scale]);
return [output];
};
/**
* Create a texture that contains the maximum value of each of the 'N' rows
*/
const createComputeMaxProgramInfo = (inferenceHandler, input, logicalRowCount, featureCount, outputShape) => {
const [textureWidth, textureHeight] = inferenceHandler.calculateTextureWidthAndHeight(input.dims, types_1.TextureType.unpacked);
const rank = outputShape.length;
if (logicalRowCount < 1 || featureCount < 1) {
throw new Error('Logical row count N and feature count D must be greater than or equal to 1');
}
if (outputShape.length !== 1) {
throw new Error('Dimensionality of the output should be 1');
}
if (outputShape[0] !== logicalRowCount) {
throw new Error('Shape of the output should be equal to logical row count');
}
const glsl = (0, glsl_source_1.getGlsl)(inferenceHandler.session.backend.glContext.version);
const shaderSource = `
float process(int[${rank}] indices) {
int logical_row_start_offset = indices[0] * ${featureCount};
float max = getColorAsFloat(${glsl.texture2D}(A, offsetToCoords(logical_row_start_offset, ${textureWidth},
${textureHeight} )));
for(int i=1; i<${featureCount}; ++i)
{
float current = getColorAsFloat(${glsl.texture2D}(A, offsetToCoords(logical_row_start_offset + i,
${textureWidth}, ${textureHeight})));
if(current > max)
max = current;
}
return max;
}`;
return Object.assign(Object.assign({}, softmaxComputeMaxProgramMetadata), { output: { dims: outputShape, type: input.type, textureType: types_1.TextureType.unpacked }, shaderSource });
};
/**
* Create a texture that contains the normalization factor for each of the 'N' rows
*/
const createComputScaleProgramInfo = (inferenceHandler, input, logicalRowCount, featureCount, maxElementPerLogicalRow, outputShape) => {
const [textureWidth, textureHeight] = inferenceHandler.calculateTextureWidthAndHeight(input.dims, types_1.TextureType.unpacked);
const rank = outputShape.length;
if (logicalRowCount < 1 || featureCount < 1) {
throw new Error('Logical row count N and feature count D must be greater than or equal to 1');
}
if (outputShape.length !== 1) {
throw new Error('Dimensionality of the output should be 1');
}
if (outputShape[0] !== logicalRowCount) {
throw new Error('Shape of the output should be equal to logical row count');
}
if (maxElementPerLogicalRow.length !== 1) {
throw new Error('Dimensionality of the intermediate results should be 1');
}
if (maxElementPerLogicalRow[0] !== logicalRowCount) {
throw new Error('Shape of the intermediate results should be equal to logical row count');
}
const glsl = (0, glsl_source_1.getGlsl)(inferenceHandler.session.backend.glContext.version);
const shaderSource = `
float process(int[${rank}] indices) {
int logical_row_start_offset = indices[0] * ${featureCount};
float norm_factor = 0.0;
float max = _Max(indices);
for(int i=0; i<${featureCount}; ++i)
{
norm_factor += exp(getColorAsFloat(${glsl.texture2D}(A, offsetToCoords(logical_row_start_offset + i,
${textureWidth}, ${textureHeight}))) - max);
}
return norm_factor;
}`;
return Object.assign(Object.assign({}, softmaxComputeScaleProgramMetadata), { output: { dims: outputShape, type: input.type, textureType: types_1.TextureType.unpacked }, shaderSource });
};
const createSoftMaxProgramInfo = (inferenceHandler, input, logicalRowCount, featureCount, maxElementPerLogicalRow, normalizationPerLogicalRow) => {
const [textureWidth, textureHeight] = inferenceHandler.calculateTextureWidthAndHeight(input.dims, types_1.TextureType.unpacked);
const rank = input.dims.length;
if (logicalRowCount < 1 || featureCount < 1) {
throw new Error('Logical row count N and feature count D must be greater than or equal to 1');
}
if (maxElementPerLogicalRow.length !== 1 || normalizationPerLogicalRow.length !== 1) {
throw new Error('Dimensionality of the intermediate results should be 1');
}
if (maxElementPerLogicalRow[0] !== logicalRowCount || normalizationPerLogicalRow[0] !== logicalRowCount) {
throw new Error('Shape of the intermediate results should be equal to logical row count');
}
const shaderSource = `
float process(int[${rank}] indices) {
// get offset of current logical tensor index from the 2-D texture coordinates (TexCoords)
int offset = coordsToOffset(TexCoords, ${textureWidth}, ${textureHeight});
//determine the logical row for this index
int logical_row_index[1];
logical_row_index[0] = offset / ${featureCount};
float norm_factor = _Norm(logical_row_index);
// avoid possible division by 0
// if norm_facor is 0, all elements are zero
// if so, return 0
if(norm_factor == 0.0)
return 0.0;
return exp(_A(indices) - _Max(logical_row_index)) / norm_factor;
}`;
return Object.assign(Object.assign({}, softmaxProgramMetadata), { output: { dims: input.dims, type: input.type, textureType: types_1.TextureType.unpacked }, shaderSource });
};
const validateInputs = (inputs) => {
if (!inputs || inputs.length !== 1) {
throw new Error('Softmax requires 1 input.');
}
if (inputs[0].type !== 'float32' && inputs[0].type !== 'float64') {
throw new Error('Invalid input type');
}
};
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/ops/split.ts":
/*!************************************************!*\
!*** ./lib/onnxjs/backends/webgl/ops/split.ts ***!
\************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.parseSplitAttributes = exports.split = void 0;
const attribute_with_cache_key_1 = __webpack_require__(/*! ../../../attribute-with-cache-key */ "./lib/onnxjs/attribute-with-cache-key.ts");
const util_1 = __webpack_require__(/*! ../../../util */ "./lib/onnxjs/util.ts");
const types_1 = __webpack_require__(/*! ../types */ "./lib/onnxjs/backends/webgl/types.ts");
const splitProgramMetadata = {
name: 'Split',
inputNames: ['A'],
inputTypes: [types_1.TextureType.unpacked],
};
const split = (inferenceHandler, inputs, attributes) => {
validateInputs(inputs);
const axis = util_1.ShapeUtil.normalizeAxis(attributes.axis, inputs[0].dims.length);
const count = getProgramCount(inferenceHandler, inputs, axis, attributes);
const output = [];
for (let i = 0; i < count; ++i) {
output.push(inferenceHandler.run(Object.assign(Object.assign({}, splitProgramMetadata), { cacheHint: `${attributes.cacheKey};${i}`, get: () => createSplitProgramInfo(inferenceHandler, inputs[0], attributes, axis, i) }), inputs));
}
return output;
};
exports.split = split;
const parseSplitAttributes = (node) => {
const axis = node.attributes.getInt('axis', 0);
const split = node.attributes.getInts('split', []);
const numOutputs = node.outputs.length;
return (0, attribute_with_cache_key_1.createAttributeWithCacheKey)({ axis, split, numOutputs });
};
exports.parseSplitAttributes = parseSplitAttributes;
const getProgramCount = (inferenceHandler, inputs, axis, attributes) => {
const [, offsets] = util_1.SplitUtil.splitShape(inputs[0].dims, axis, attributes.split, attributes.numOutputs);
return offsets.length;
};
const createSplitProgramInfo = (inferenceHandler, input, attributes, axis, index) => {
const [shapes, offsets] = util_1.SplitUtil.splitShape(input.dims, axis, attributes.split, attributes.numOutputs);
const offset = offsets[index];
const outputShape = shapes[index];
const rank = outputShape.length;
const shaderSource = `
float process(int indices[${rank}]) {
indices[${axis}] += ${offset};
return _A(indices);
}
`;
return Object.assign(Object.assign({}, splitProgramMetadata), { cacheHint: `${attributes.cacheKey}:${index}`, output: { dims: outputShape, type: input.type, textureType: types_1.TextureType.unpacked }, shaderSource });
};
const validateInputs = (inputs) => {
if (!inputs || inputs.length !== 1) {
throw new Error('Split requires one input.');
}
if (inputs[0].type !== 'int8' && inputs[0].type !== 'uint8' && inputs[0].type !== 'int16' &&
inputs[0].type !== 'uint16' && inputs[0].type !== 'int32' && inputs[0].type !== 'uint32' &&
inputs[0].type !== 'float32' && inputs[0].type !== 'float64' && inputs[0].type !== 'bool') {
throw new Error('Invalid input type.');
}
};
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/ops/squeeze.ts":
/*!**************************************************!*\
!*** ./lib/onnxjs/backends/webgl/ops/squeeze.ts ***!
\**************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.parseSqueezeAttributes = exports.squeezeV13 = exports.squeeze = void 0;
const util_1 = __webpack_require__(/*! ../../../util */ "./lib/onnxjs/util.ts");
const squeeze = (inferenceHandler, inputs, axes) => {
validateInputs(inputs);
const outputShape = util_1.ShapeUtil.squeezeShape(inputs[0].dims, axes);
const output = inferenceHandler.reshapeUnpacked(inputs[0], outputShape);
return [output];
};
exports.squeeze = squeeze;
const squeezeV13 = (inferenceHandler, inputs) => {
validateInputsV13(inputs);
return (0, exports.squeeze)(inferenceHandler, [inputs[0]], Array.from(inputs[1].integerData));
};
exports.squeezeV13 = squeezeV13;
const parseSqueezeAttributes = (node) => node.attributes.getInts('axes');
exports.parseSqueezeAttributes = parseSqueezeAttributes;
const validateInputs = (inputs) => {
if (!inputs || inputs.length !== 1) {
throw new Error('Squeeze requires 1 input.');
}
if (inputs[0].type === 'string') {
throw new Error('invalid input tensor types.');
}
};
const validateInputsV13 = (inputs) => {
if (!inputs || inputs.length !== 2) {
throw new Error('Squeeze requires 2 inputs.');
}
if (inputs[1].type !== 'int32') {
throw new Error('Invalid input type.');
}
};
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/ops/sum.ts":
/*!**********************************************!*\
!*** ./lib/onnxjs/backends/webgl/ops/sum.ts ***!
\**********************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.sum = void 0;
const glsl_source_1 = __webpack_require__(/*! ../glsl-source */ "./lib/onnxjs/backends/webgl/glsl-source.ts");
const types_1 = __webpack_require__(/*! ../types */ "./lib/onnxjs/backends/webgl/types.ts");
const sum = (inferenceHandler, inputs) => {
validateInputs(inputs);
const sumProgramMetadata = {
name: 'Sum',
inputNames: inputs.map((v, i) => `X${i}`),
inputTypes: new Array(inputs.length).fill(types_1.TextureType.unpacked)
};
const output = inferenceHandler.run(Object.assign(Object.assign({}, sumProgramMetadata), { get: () => createSumProgramInfo(inferenceHandler, inputs, sumProgramMetadata) }), inputs);
return [output];
};
exports.sum = sum;
const createSumProgramInfo = (inferenceHandler, inputs, sumProgramMetadata) => {
const glsl = (0, glsl_source_1.getGlsl)(inferenceHandler.session.backend.glContext.version);
const outputShape = inputs[0].dims.slice();
const sumLine = inputs.map((v, i) => `${glsl.texture2D}(X${i},TexCoords)`).join(' + ');
const shaderSource = `
void main() {
vec4 result = ${sumLine};
${glsl.output} = result;
}
`;
return Object.assign(Object.assign({}, sumProgramMetadata), { output: { dims: outputShape, type: inputs[0].type, textureType: types_1.TextureType.unpacked }, hasMain: true, shaderSource });
};
const validateInputs = (inputs) => {
if (!inputs || inputs.length === 0) {
throw new Error('Sum requires inputs.');
}
const length = inputs[0].dims.length;
for (let i = 1; i < inputs.length; i++) {
if (length !== inputs[i].dims.length) {
throw new Error('Input shapes are mismatched.');
}
for (let j = 0; j < length; j++) {
if (inputs[0].dims[j] !== inputs[i].dims[j]) {
throw new Error('Input shapes are not matched.');
}
}
}
if (inputs[0].type !== 'float32' && inputs[0].type !== 'float64') {
throw new Error('Invalid input type.');
}
for (let i = 1; i < inputs.length; i++) {
if (inputs[0].type !== inputs[i].type) {
throw new Error('Input types are not matched.');
}
}
};
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/ops/tile.ts":
/*!***********************************************!*\
!*** ./lib/onnxjs/backends/webgl/ops/tile.ts ***!
\***********************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.tile = void 0;
const operators_1 = __webpack_require__(/*! ../../../operators */ "./lib/onnxjs/operators.ts");
const types_1 = __webpack_require__(/*! ../types */ "./lib/onnxjs/backends/webgl/types.ts");
const tile = (inferenceHandler, inputs) => {
validateInputs(inputs);
const tileProgramMetadata = {
name: 'Tile',
inputNames: ['A'],
inputTypes: [types_1.TextureType.unpacked],
};
const output = inferenceHandler.run(Object.assign(Object.assign({}, tileProgramMetadata), { get: () => createTileProgramInfo(inferenceHandler, inputs, tileProgramMetadata) }), inputs);
return [output];
};
exports.tile = tile;
const createTileProgramInfo = (handler, inputs, tileProgramMetadata) => {
const inputShape = inputs[0].dims.slice();
const outputShape = new Array(inputShape.length);
const tileOps = [];
for (let i = 0; i < inputShape.length; i++) {
outputShape[i] = inputShape[i] * inputs[1].numberData[i];
tileOps.push(`inputIdx[${i}] = int(mod(float(outputIdx[${i}]), ${inputShape[i]}.));`);
}
const rank = outputShape.length;
const shaderSource = `
float process(int outputIdx[${rank}]) {
int inputIdx[${rank}];
${tileOps.join('\n')}
return _A(inputIdx);
}
`;
return Object.assign(Object.assign({}, tileProgramMetadata), { output: { dims: outputShape, type: inputs[0].type, textureType: types_1.TextureType.unpacked }, shaderSource });
};
const validateInputs = (inputs) => {
if (!inputs || inputs.length !== 2) {
throw new Error('Tile requires 2 input.');
}
if (inputs[1].dims.length !== 1) {
throw new Error('The second input shape must 1 dimension.');
}
if (inputs[1].dims[0] !== inputs[0].dims.length) {
throw new Error('Invalid input shape.');
}
if (operators_1.NUMBER_TYPES.indexOf(inputs[0].type) === -1) {
throw new Error('Invalid input type.');
}
if (inputs[1].type !== 'int32' && inputs[1].type !== 'int16') {
throw new Error('Invalid repeat type.');
}
};
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/ops/transpose.ts":
/*!****************************************************!*\
!*** ./lib/onnxjs/backends/webgl/ops/transpose.ts ***!
\****************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.parseTransposeAttributes = exports.transpose = void 0;
const attribute_with_cache_key_1 = __webpack_require__(/*! ../../../attribute-with-cache-key */ "./lib/onnxjs/attribute-with-cache-key.ts");
const util_1 = __webpack_require__(/*! ../../../util */ "./lib/onnxjs/util.ts");
const types_1 = __webpack_require__(/*! ../types */ "./lib/onnxjs/backends/webgl/types.ts");
const transposeProgramMetadata = {
name: 'Transpose',
inputNames: ['A'],
inputTypes: [types_1.TextureType.unpacked]
};
const transpose = (inferenceHandler, inputs, attributes) => {
validateInputs(inputs);
const output = inferenceHandler.run(Object.assign(Object.assign({}, transposeProgramMetadata), { cacheHint: attributes.cacheKey, get: () => createTransposeProgramInfo(inferenceHandler, inputs[0], attributes.perm) }), inputs);
return [output];
};
exports.transpose = transpose;
const parseTransposeAttributes = (node) => (0, attribute_with_cache_key_1.createAttributeWithCacheKey)({ perm: node.attributes.getInts('perm', []) });
exports.parseTransposeAttributes = parseTransposeAttributes;
const createTransposeProgramInfo = (inferenceHandler, input, perm) => {
const inputShape = input.dims;
perm = getAdjustedPerm(inputShape, perm);
const unpackedOutputShape = getOutputShape(inputShape, perm);
const rank = inputShape.length;
// A dims=[${inputs[0].dims.toString()}]
// out Dims=[${unpackedOutputShape.toString()}]
// based on perm=[${perm.toString()}]
const shaderSource = `
${getPermFunctionBody('perm', perm, rank)}
float process(int indices[${rank}]) {
int a[${rank}];
perm(a, indices);
return _A(a);
}`;
return Object.assign(Object.assign({}, transposeProgramMetadata), { output: { dims: unpackedOutputShape, type: input.type, textureType: types_1.TextureType.unpacked }, shaderSource });
};
const getAdjustedPerm = (inputShape, perm) => {
if (perm && perm.length !== inputShape.length) {
perm = [...(inputShape.keys())].reverse();
}
return perm;
};
const getOutputShape = (inputShape, perm) => {
perm = getAdjustedPerm(inputShape, perm);
return util_1.ShapeUtil.sortBasedOnPerm(inputShape, perm);
};
const getPermFunctionBody = (name, perm, rank) => {
const reverseFunc = [];
reverseFunc.push(`void ${name}(out int a[${rank}], int src[${rank}]) {`);
for (let i = 0; i < rank; ++i) {
reverseFunc.push(`\ta[${perm[i]}]=src[${i}];`);
}
reverseFunc.push('\t}');
return reverseFunc.join('\n');
};
const validateInputs = (inputs) => {
if (!inputs || inputs.length !== 1) {
throw new Error('Transpose requires 1 input.');
}
if (inputs[0].type !== 'float32' && inputs[0].type !== 'float64') {
throw new Error('input should be float tensor');
}
};
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/ops/uint8-encode.ts":
/*!*******************************************************!*\
!*** ./lib/onnxjs/backends/webgl/ops/uint8-encode.ts ***!
\*******************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.encodeAsUint8 = void 0;
const glsl_source_1 = __webpack_require__(/*! ../glsl-source */ "./lib/onnxjs/backends/webgl/glsl-source.ts");
const types_1 = __webpack_require__(/*! ../types */ "./lib/onnxjs/backends/webgl/types.ts");
const encodeAsUint8 = (inferenceHandler, input) => {
const outputShape = input.shape;
const glsl = (0, glsl_source_1.getGlsl)(inferenceHandler.session.backend.glContext.version);
/**
* https://github.com/tensorflow/tfjs-core/blob/master/src/kernels/webgl/encode_float_gpu.ts
*/
const shaderSource = `
const float FLOAT_MAX = 1.70141184e38;
const float FLOAT_MIN = 1.17549435e-38;
bool isNaN(float val) {
return (val < 1.0 || 0.0 < val || val == 0.0) ? false : true;
}
highp vec4 encodeAsUint8(highp float v) {
if (isNaN(v)) {
return vec4(255, 255, 255, 255);
}
highp float av = abs(v);
if(av < FLOAT_MIN) {
return vec4(0.0, 0.0, 0.0, 0.0);
} else if(v > FLOAT_MAX) {
return vec4(0.0, 0.0, 128.0, 127.0) / 255.0;
} else if(v < -FLOAT_MAX) {
return vec4(0.0, 0.0, 128.0, 255.0) / 255.0;
}
highp vec4 c = vec4(0,0,0,0);
highp float e = floor(log2(av));
highp float m = exp2(fract(log2(av))) - 1.0;
c[2] = floor(128.0 * m);
m -= c[2] / 128.0;
c[1] = floor(32768.0 * m);
m -= c[1] / 32768.0;
c[0] = floor(8388608.0 * m);
highp float ebias = e + 127.0;
c[3] = floor(ebias / 2.0);
ebias -= c[3] * 2.0;
c[2] += floor(ebias) * 128.0;
c[3] += 128.0 * step(0.0, -v);
return c / 255.0;
}
void main() {
float value = ${glsl.texture2D}(X,TexCoords).r;
${glsl.output} = encodeAsUint8(value);
}`;
const programInfo = {
name: 'Uint8Encode',
inputTypes: [types_1.TextureType.unpacked],
inputNames: ['X'],
output: { dims: outputShape, type: input.tensor.type, textureType: types_1.TextureType.downloadUint8AsFloat },
shaderSource,
hasMain: true
};
return inferenceHandler.executeProgram(programInfo, [input.tensor]);
};
exports.encodeAsUint8 = encodeAsUint8;
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/ops/unary-op.ts":
/*!***************************************************!*\
!*** ./lib/onnxjs/backends/webgl/ops/unary-op.ts ***!
\***************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.tanh = exports.tan = exports.sqrt = exports.sin = exports.sigmoid = exports.relu = exports.not = exports.neg = exports.log = exports.parseLeakyReluAttributes = exports.leakyRelu = exports.identity = exports.floor = exports.exp = exports.parseEluAttributes = exports.elu = exports.cos = exports.ceil = exports.clipV11 = exports.parseClipAttributes = exports.clip = exports.atan = exports.asin = exports.acos = exports.abs = exports.glslTanh = exports.glslTan = exports.glslSqrt = exports.glslSigmoid = exports.glslRelu = exports.glslSin = exports.glslNot = exports.glslNeg = exports.glslLog = exports.glslLeakyRelu = exports.glslIdentity = exports.glslClip = exports.glslFloor = exports.glslExp = exports.glslElu = exports.glslCos = exports.glslCeil = exports.glslAtan = exports.glslAsin = exports.glslAcos = exports.glslAbs = void 0;
const attribute_with_cache_key_1 = __webpack_require__(/*! ../../../attribute-with-cache-key */ "./lib/onnxjs/attribute-with-cache-key.ts");
const util_1 = __webpack_require__(/*! ../../../util */ "./lib/onnxjs/util.ts");
const glsl_definitions_1 = __webpack_require__(/*! ../glsl-definitions */ "./lib/onnxjs/backends/webgl/glsl-definitions.ts");
const glsl_source_1 = __webpack_require__(/*! ../glsl-source */ "./lib/onnxjs/backends/webgl/glsl-source.ts");
const types_1 = __webpack_require__(/*! ../types */ "./lib/onnxjs/backends/webgl/types.ts");
function glslAbs() {
return glslBuiltinUnary('abs');
}
exports.glslAbs = glslAbs;
function glslAcos() {
return glslBuiltinUnary('acos');
}
exports.glslAcos = glslAcos;
function glslAsin() {
return glslBuiltinUnary('asin');
}
exports.glslAsin = glslAsin;
function glslAtan() {
return glslBuiltinUnary('atan');
}
exports.glslAtan = glslAtan;
function glslCeil() {
return glslBuiltinUnary('ceil');
}
exports.glslCeil = glslCeil;
function glslCos() {
return glslBuiltinUnary('cos');
}
exports.glslCos = glslCos;
function glslElu(alpha) {
const name = 'elu';
const body = `
const float alpha = float(${alpha});
float ${name}_(float a) {
return a >= 0.0 ? a: (exp(a) - 1.0) * alpha;
}
vec4 ${name}_(vec4 v) {
return vec4(${name}_(v.x), ${name}_(v.y), ${name}_(v.z), ${name}_(v.w));
}
`;
return { body, name, type: glsl_definitions_1.FunctionType.ValueBased };
}
exports.glslElu = glslElu;
function glslExp() {
return glslBuiltinUnary('exp');
}
exports.glslExp = glslExp;
function glslFloor() {
return glslBuiltinUnary('floor');
}
exports.glslFloor = glslFloor;
function glslClip(min, max) {
const name = 'clip';
const body = `
const float min = float(${min});
const float max = float(${max});
float ${name}_(float a) {
return clamp(a, min, max);
}
vec4 ${name}_(vec4 v) {
return clamp(v, min, max);
}
`;
return { body, name, type: glsl_definitions_1.FunctionType.ValueBased };
}
exports.glslClip = glslClip;
function glslIdentity() {
const name = 'indentity';
const body = `
float ${name}_(float a) {
return a;
}
vec4 ${name}_(vec4 v) {
return v;
}
`;
return { body, name, type: glsl_definitions_1.FunctionType.ValueBased };
}
exports.glslIdentity = glslIdentity;
function glslLeakyRelu(alpha) {
const name = 'leakyRelu';
const body = `
const float alpha = float(${alpha});
float ${name}_(float a) {
return a < 0.0 ? a * alpha : a;
}
vec4 ${name}_(vec4 v) {
return vec4(${name}_(v.x), ${name}_(v.y), ${name}_(v.z), ${name}_(v.w));
}
`;
return { body, name, type: glsl_definitions_1.FunctionType.ValueBased };
}
exports.glslLeakyRelu = glslLeakyRelu;
function glslLog() {
return glslBuiltinUnary('log');
}
exports.glslLog = glslLog;
function glslNeg() {
const name = 'neg';
const body = `
float ${name}_(float a) {
return -a;
}
vec4 ${name}_(vec4 v) {
return -v;
}
`;
return { body, name, type: glsl_definitions_1.FunctionType.ValueBased };
}
exports.glslNeg = glslNeg;
function glslNot() {
const name = 'not';
const body = `
float ${name}_(float a) {
return float( ! bool(a) );
}
bool ${name}_(bool a) {
return !a;
}
vec4 ${name}_(vec4 v) {
return vec4(!bool(v.x), !bool(v.y), !bool(v.z), !bool(v.w));
}
bvec4 ${name}_(bvec4 v) {
return bvec4(!v.x, !v.y, !v.z, !v.w);
}
`;
return { body, name, type: glsl_definitions_1.FunctionType.ValueBased };
}
exports.glslNot = glslNot;
function glslSin() {
return glslBuiltinUnary('sin');
}
exports.glslSin = glslSin;
function glslRelu() {
const name = 'relu';
const body = `
float ${name}_(float a) {
return max( a, 0.0 );
}
vec4 ${name}_(vec4 v) {
return max( v, 0.0 );
}
`;
return { body, name, type: glsl_definitions_1.FunctionType.ValueBased };
}
exports.glslRelu = glslRelu;
function glslSigmoid() {
const name = 'sigmoid';
const body = `
float ${name}_(float a) {
return 1.0 / (1.0 + exp(-a));
}
vec4 ${name}_(vec4 v) {
return 1.0 / (1.0 + exp(-v));
}
`;
return { body, name, type: glsl_definitions_1.FunctionType.ValueBased };
}
exports.glslSigmoid = glslSigmoid;
function glslSqrt() {
return glslBuiltinUnary('sqrt');
}
exports.glslSqrt = glslSqrt;
function glslTan() {
return glslBuiltinUnary('tan');
}
exports.glslTan = glslTan;
function glslTanh() {
const name = 'tanh';
const body = `
float ${name}_(float a) {
a = clamp(a, -10., 10.);
a = exp(2.*a);
return (a - 1.) / (a + 1.);
}
vec4 ${name}_(vec4 v) {
v = clamp(v, -10., 10.);
v = exp(2.*v);
return (v - 1.) / (v + 1.);
}
`;
return { body, name, type: glsl_definitions_1.FunctionType.ValueBased };
}
exports.glslTanh = glslTanh;
function glslBuiltinUnary(name) {
const body = `
float ${name}_(float a) {
return ${name}(a);
}
vec4 ${name}_(vec4 v) {
return ${name}(v);
}
`;
return { body, name, type: glsl_definitions_1.FunctionType.ValueBased };
}
/////
/////
/////
const createElementwiseProgramInfo = (handler, metadata, input, glslFunc) => {
const textureType = handler.session.pack ? types_1.TextureType.packed : types_1.TextureType.unpacked;
const glsl = (0, glsl_source_1.getGlsl)(handler.session.backend.glContext.version);
return Object.assign(Object.assign({}, metadata), { output: { dims: input.dims, type: input.type, textureType }, shaderSource: `
${glslFunc.body}
void main() {
vec4 v = ${glsl.texture2D}(A, TexCoords);
v = ${glslFunc.name}_(v);
${glsl.output} = v;
}
`, hasMain: true });
};
const createElementwiseProgramInfoLoader = (handler, input, glslFunc, cacheKey) => {
const textureType = handler.session.pack ? types_1.TextureType.packed : types_1.TextureType.unpacked;
const metadata = { name: glslFunc.name, inputTypes: [textureType], inputNames: ['A'], cacheHint: cacheKey };
return Object.assign(Object.assign({}, metadata), { get: () => createElementwiseProgramInfo(handler, metadata, input, glslFunc) });
};
const abs = (handler, inputs) => [handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslAbs()), inputs)];
exports.abs = abs;
const acos = (handler, inputs) => [handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslAcos()), inputs)];
exports.acos = acos;
const asin = (handler, inputs) => [handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslAsin()), inputs)];
exports.asin = asin;
const atan = (handler, inputs) => [handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslAtan()), inputs)];
exports.atan = atan;
const clip = (handler, inputs, attributes) => [handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslClip(attributes.min, attributes.max), attributes.cacheKey), inputs)];
exports.clip = clip;
const parseClipAttributes = (node) => (0, attribute_with_cache_key_1.createAttributeWithCacheKey)({ min: node.attributes.getFloat('min', util_1.MIN_CLIP), max: node.attributes.getFloat('max', util_1.MAX_CLIP) });
exports.parseClipAttributes = parseClipAttributes;
const clipV11 = (handler, inputs) => {
const attributes = generateClipAttributesFromInputs(handler, inputs);
return (0, exports.clip)(handler, [inputs[0]], attributes);
};
exports.clipV11 = clipV11;
const generateClipAttributesFromInputs = (handler, inputs) => {
if (inputs.length >= 3 &&
(!handler.session.isInitializer(inputs[1].dataId) || !handler.session.isInitializer(inputs[2].dataId))) {
throw new Error('dynamic clip attributes are not allowed');
}
const min = (inputs.length >= 3) ? inputs[1].numberData[0] : util_1.MIN_CLIP;
const max = (inputs.length >= 3) ? inputs[2].numberData[0] : util_1.MAX_CLIP;
return (0, attribute_with_cache_key_1.createAttributeWithCacheKey)({ min, max });
};
const ceil = (handler, inputs) => [handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslCeil()), inputs)];
exports.ceil = ceil;
const cos = (handler, inputs) => [handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslCos()), inputs)];
exports.cos = cos;
const elu = (handler, inputs, attributes) => [handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslElu(attributes.alpha), attributes.cacheKey), inputs)];
exports.elu = elu;
const parseEluAttributes = (node) => (0, attribute_with_cache_key_1.createAttributeWithCacheKey)({ alpha: node.attributes.getFloat('alpha', 1.0) });
exports.parseEluAttributes = parseEluAttributes;
const exp = (handler, inputs) => [handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslExp()), inputs)];
exports.exp = exp;
const floor = (handler, inputs) => [handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslFloor()), inputs)];
exports.floor = floor;
const identity = (handler, inputs) => [handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslIdentity()), inputs)];
exports.identity = identity;
const leakyRelu = (handler, inputs, attributes) => [handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslLeakyRelu(attributes.alpha), attributes.cacheKey), inputs)];
exports.leakyRelu = leakyRelu;
const parseLeakyReluAttributes = (node) => (0, attribute_with_cache_key_1.createAttributeWithCacheKey)({ alpha: node.attributes.getFloat('alpha', 0.01) });
exports.parseLeakyReluAttributes = parseLeakyReluAttributes;
const log = (handler, inputs) => [handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslLog()), inputs)];
exports.log = log;
const neg = (handler, inputs) => [handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslNeg()), inputs)];
exports.neg = neg;
const not = (handler, inputs) => [handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslNot()), inputs)];
exports.not = not;
const relu = (handler, inputs) => [handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslRelu()), inputs)];
exports.relu = relu;
const sigmoid = (handler, inputs) => [handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslSigmoid()), inputs)];
exports.sigmoid = sigmoid;
const sin = (handler, inputs) => [handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslSin()), inputs)];
exports.sin = sin;
const sqrt = (handler, inputs) => [handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslSqrt()), inputs)];
exports.sqrt = sqrt;
const tan = (handler, inputs) => [handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslTan()), inputs)];
exports.tan = tan;
const tanh = (handler, inputs) => [handler.run(createElementwiseProgramInfoLoader(handler, inputs[0], glslTanh()), inputs)];
exports.tanh = tanh;
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/ops/unpack.ts":
/*!*************************************************!*\
!*** ./lib/onnxjs/backends/webgl/ops/unpack.ts ***!
\*************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.createUnpackProgramInfoLoader = exports.createUnpackProgramInfo = void 0;
const glsl_source_1 = __webpack_require__(/*! ../glsl-source */ "./lib/onnxjs/backends/webgl/glsl-source.ts");
const types_1 = __webpack_require__(/*! ../types */ "./lib/onnxjs/backends/webgl/types.ts");
const utils_1 = __webpack_require__(/*! ../utils */ "./lib/onnxjs/backends/webgl/utils.ts");
const packing_utils_1 = __webpack_require__(/*! ./packing-utils */ "./lib/onnxjs/backends/webgl/ops/packing-utils.ts");
const unpackProgramMetadata = {
name: 'unpack',
inputNames: ['A'],
inputTypes: [types_1.TextureType.packed]
};
const createUnpackProgramInfo = (handler, input) => {
const rank = input.dims.length;
const channels = (0, packing_utils_1.getChannels)('rc', rank);
const innerDims = channels.slice(-2);
const coordsDataType = (0, utils_1.getCoordsDataType)(rank);
const unpackChannel = (0, packing_utils_1.unpackFromChannel)();
const isScalar = (input.dims.length === 0);
const sourceCoords = isScalar ? '' : getSourceCoords(rank, channels);
const coords = rank <= 1 ? 'rc' : `vec2(${innerDims.join(',')})`;
const glsl = (0, glsl_source_1.getGlsl)(handler.session.backend.glContext.version);
const shaderSource = `
${unpackChannel}
void main() {
${coordsDataType} rc = getOutputCoords();
// Sample the texture with the coords to get the rgba channel value.
vec4 packedInput = getA(${sourceCoords});
${glsl.output} = vec4(getChannel(packedInput, ${coords}), 0, 0, 0);
}
`;
return Object.assign(Object.assign({}, unpackProgramMetadata), { hasMain: true, output: { dims: input.dims, type: input.type, textureType: types_1.TextureType.unpacked }, shaderSource });
};
exports.createUnpackProgramInfo = createUnpackProgramInfo;
const createUnpackProgramInfoLoader = (handler, input) => (Object.assign(Object.assign({}, unpackProgramMetadata), { get: () => (0, exports.createUnpackProgramInfo)(handler, input) }));
exports.createUnpackProgramInfoLoader = createUnpackProgramInfoLoader;
function getSourceCoords(rank, dims) {
if (rank === 1) {
return 'rc';
}
let coords = '';
for (let i = 0; i < rank; i++) {
coords += dims[i];
if (i < rank - 1) {
coords += ',';
}
}
return coords;
}
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/ops/unsqueeze.ts":
/*!****************************************************!*\
!*** ./lib/onnxjs/backends/webgl/ops/unsqueeze.ts ***!
\****************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.parseUnsqueezeAttributes = exports.unsqueezeV13 = exports.unsqueeze = void 0;
const util_1 = __webpack_require__(/*! ../../../util */ "./lib/onnxjs/util.ts");
const unsqueeze = (inferenceHandler, inputs, axes) => {
validateInputs(inputs);
const outputShape = util_1.ShapeUtil.unsqueezeShape(inputs[0].dims, axes);
const output = inferenceHandler.reshapeUnpacked(inputs[0], outputShape);
return [output];
};
exports.unsqueeze = unsqueeze;
const unsqueezeV13 = (inferenceHandler, inputs) => {
validateInputsV13(inputs);
return (0, exports.unsqueeze)(inferenceHandler, [inputs[0]], Array.from(inputs[1].integerData));
};
exports.unsqueezeV13 = unsqueezeV13;
const parseUnsqueezeAttributes = (node) => node.attributes.getInts('axes');
exports.parseUnsqueezeAttributes = parseUnsqueezeAttributes;
const validateInputs = (inputs) => {
if (!inputs || inputs.length !== 1) {
throw new Error('Unsqueeze requires 1 input.');
}
if (inputs[0].type === 'string') {
throw new Error('invalid input tensor types.');
}
};
const validateInputsV13 = (inputs) => {
if (!inputs || inputs.length !== 2) {
throw new Error('Unsqueeze requires 2 inputs.');
}
if (inputs[1].type !== 'int32') {
throw new Error('Invalid input type.');
}
};
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/ops/upsample.ts":
/*!***************************************************!*\
!*** ./lib/onnxjs/backends/webgl/ops/upsample.ts ***!
\***************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.scalesValidation = exports.validateInputs = exports.parseUpsampleAttributes = exports.parseUpsampleAttributesV9 = exports.parseUpsampleAttributesV7 = exports.upsample = void 0;
const attribute_with_cache_key_1 = __webpack_require__(/*! ../../../attribute-with-cache-key */ "./lib/onnxjs/attribute-with-cache-key.ts");
const glsl_source_1 = __webpack_require__(/*! ../glsl-source */ "./lib/onnxjs/backends/webgl/glsl-source.ts");
const types_1 = __webpack_require__(/*! ../types */ "./lib/onnxjs/backends/webgl/types.ts");
const upsampleProgramMetadata = {
name: 'Upsample',
inputNames: ['X'],
inputTypes: [types_1.TextureType.unpacked],
};
const upsample = (inferenceHandler, inputs, attributes) => {
(0, exports.validateInputs)(inputs, attributes);
const output = inferenceHandler.run(Object.assign(Object.assign({}, upsampleProgramMetadata), { cacheHint: attributes.cacheKey, get: () => createUpsampleProgramInfo(inferenceHandler, inputs, attributes) }), inputs);
return [output];
};
exports.upsample = upsample;
const parseUpsampleAttributesV7 = (node) => (0, exports.parseUpsampleAttributes)(node, 7);
exports.parseUpsampleAttributesV7 = parseUpsampleAttributesV7;
const parseUpsampleAttributesV9 = (node) => (0, exports.parseUpsampleAttributes)(node, 9);
exports.parseUpsampleAttributesV9 = parseUpsampleAttributesV9;
const parseUpsampleAttributes = (node, opset) => {
const isResize = (opset >= 10);
// processing node attributes
const mode = node.attributes.getString('mode', 'nearest');
if (mode !== 'nearest' && mode !== 'linear' && (opset < 11 || mode !== 'cubic')) {
throw new Error(`unrecognized mode: ${mode}`);
}
let scales = [];
if (opset < 9) {
scales = node.attributes.getFloats('scales');
(0, exports.scalesValidation)(scales, mode, isResize);
}
const extrapolationValue = node.attributes.getFloat('extrapolation_value', 0.0);
const coordinateTransformMode = opset > 10 ? node.attributes.getString('coordinate_transformation_mode', 'half_pixel') : 'asymmetric';
if ([
'asymmetric', 'pytorch_half_pixel', 'tf_half_pixel_for_nn', 'align_corners', 'tf_crop_and_resize', 'half_pixel'
].indexOf(coordinateTransformMode) === -1) {
throw new Error(`coordinate_transform_mode '${coordinateTransformMode}' is not supported`);
}
const needRoiInput = (coordinateTransformMode === 'tf_crop_and_resize');
const useExtrapolation = needRoiInput;
const nearestMode = (mode === 'nearest' && opset >= 11) ? node.attributes.getString('nearest_mode', 'round_prefer_floor') : '';
if (['round_prefer_floor', 'round_prefer_ceil', 'floor', 'ceil', ''].indexOf(nearestMode) === -1) {
throw new Error(`nearest_mode '${nearestMode}' is not supported`);
}
const cubicCoefficientA = node.attributes.getFloat('cubic_coeff_a', -0.75);
const excludeOutside = node.attributes.getInt('exclude_outside', 0) !== 0;
if (excludeOutside && mode !== 'cubic') {
throw new Error('exclude_outside can be set to 1 only when mode is CUBIC.');
}
const useNearest2xOptimization = (opset < 11) ? true : (mode === 'nearest' && coordinateTransformMode === 'asymmetric' && nearestMode === 'floor');
let roiInputIdx = 0;
let scalesInputIdx = 0;
let sizesInputIdx = 0;
if (opset > 10) {
// handle when roiInput is not given
if (node.inputs.length > 2) {
roiInputIdx = 1;
scalesInputIdx = 2;
sizesInputIdx = 3;
}
else {
scalesInputIdx = 1;
sizesInputIdx = 2;
}
}
else if (opset === 9) {
scalesInputIdx = 1;
}
return (0, attribute_with_cache_key_1.createAttributeWithCacheKey)({
opset,
isResize,
mode,
scales,
extrapolationValue,
coordinateTransformMode,
useExtrapolation,
needRoiInput,
nearestMode,
cubicCoefficientA,
excludeOutside,
useNearest2xOptimization,
roiInputIdx,
scalesInputIdx,
sizesInputIdx
});
};
exports.parseUpsampleAttributes = parseUpsampleAttributes;
const createUpsampleProgramInfo = (inferenceHandler, inputs, attributes) => {
const glsl = (0, glsl_source_1.getGlsl)(inferenceHandler.session.backend.glContext.version);
const [inputWidth, inputHeight] = inferenceHandler.calculateTextureWidthAndHeight(inputs[0].dims, types_1.TextureType.unpacked);
const outputShape = inputs[0].dims.map((dim, i) => Math.floor(dim * attributes.scales[i]));
const [outputWidth, outputHeight] = inferenceHandler.calculateTextureWidthAndHeight(outputShape, types_1.TextureType.unpacked);
const dim = outputShape.length;
const outputPitches = new Array(dim);
const inputPitches = new Array(dim);
let precalculatedPitches = `
int output_pitches[${dim}];
int input_pitches[${dim}];
`;
for (let d = dim - 1; d >= 0; d--) {
outputPitches[d] = (d === dim - 1) ? 1 : outputPitches[d + 1] * outputShape[d + 1];
inputPitches[d] = (d === dim - 1) ? 1 : inputPitches[d + 1] * inputs[0].dims[d + 1];
precalculatedPitches += `
output_pitches[${d}] = ${outputPitches[d]};
input_pitches[${d}] = ${inputPitches[d]};
`;
}
const getInputFloatFunction = `
float getInputFloat(int index) {
vec2 coords = offsetToCoords(index, ${inputWidth}, ${inputHeight});
float value = getColorAsFloat(${glsl.texture2D}(X, coords));
return value;
}
`;
const shaderSource = attributes.mode === 'nearest' ?
// nearest
`
${getInputFloatFunction}
float process(int indices[${dim}]) {
int input_index = 0;
int output_index = coordsToOffset(TexCoords, ${outputWidth}, ${outputHeight});
${precalculatedPitches}
int d, m;
for (int dim = 0; dim < ${dim}; ++dim) {
d = output_index / output_pitches[dim];
m = output_index - d * output_pitches[dim];
output_index = m;
if (scales[dim] != 1 && d > 0) {
int d2 = d / scales[dim];
m = d - d2 * scales[dim];
d = d2;
}
input_index += input_pitches[dim] * d;
}
return getInputFloat(input_index);
}` :
dim === 4 ?
// bilinear 4D
`
${getInputFloatFunction}
float process(int indices[4]) {
int input_index = 0;
int output_index = coordsToOffset(TexCoords, ${outputWidth}, ${outputHeight});
${precalculatedPitches}
int m;
int index_of_dim0, index_of_dim1, index_of_dim2, index_of_dim3;
index_of_dim0 = output_index / output_pitches[0];
m = output_index - index_of_dim0 * output_pitches[0];
index_of_dim1 = m / output_pitches[1];
m = m - index_of_dim1 * output_pitches[1];
index_of_dim2 = m / output_pitches[2];
m = m - index_of_dim2 * output_pitches[2];
index_of_dim3 = m;
int index_of_input_dim2, index_of_input_dim3, x_offset, y_offset;
index_of_input_dim2 = index_of_dim2 / scales[2];
y_offset = index_of_dim2 - index_of_input_dim2 * scales[2];
index_of_input_dim3 = index_of_dim3 / scales[3];
x_offset = index_of_dim3 - index_of_input_dim3 * scales[3];
input_index = index_of_dim0 * input_pitches[0] +
index_of_dim1 * input_pitches[1] +
index_of_input_dim2 * input_pitches[2] +
index_of_input_dim3;
float x00 = getInputFloat(input_index);
float x10, x01, x11;
bool end_of_dim2 = false;
if (index_of_input_dim2 == (${inputs[0].dims[2]} - 1)) {
// It's the end in dimension 2
x01 = x00;
end_of_dim2 = true;
} else {
x01 = getInputFloat(input_index + input_pitches[2]);
}
if (index_of_input_dim3 == (input_pitches[2] - 1)) {
// It's the end in dimension 3
x10 = x00;
x11 = x01;
}
else {
x10 = getInputFloat(input_index + 1);
x11 = end_of_dim2 ? x10 : getInputFloat(input_index + input_pitches[2] + 1);
}
float y0 = x00 + float(y_offset) * (x01 - x00) / float(scales[2]);
float y1 = x10 + float(y_offset) * (x11 - x10) / float(scales[2]);
return y0 + float(x_offset) * (y1 - y0) / float(scales[3]);
}` :
// bilinear 2D
`
${getInputFloatFunction}
float process(int indices[2]) {
int input_index = 0;
int output_index = coordsToOffset(TexCoords, ${outputWidth}, ${outputHeight});
${precalculatedPitches}
int m;
int index_of_dim0, index_of_dim1;
index_of_dim0 = output_index / output_pitches[0];
m = output_index - index_of_dim0 * output_pitches[0];
index_of_dim1 = m;
int index_of_input_dim0, index_of_input_dim1, x_offset, y_offset;
index_of_input_dim0 = index_of_dim0 / scales[0];
y_offset = index_of_dim0 - index_of_input_dim0 * scales[0];
index_of_input_dim1 = index_of_dim1 / scales[1];
x_offset = index_of_dim1 - index_of_input_dim1 * scales[1];
input_index = index_of_input_dim0 * input_pitches[0] + index_of_input_dim1;
float x00 = getInputFloat(input_index);
float x10, x01, x11;
bool end_of_dim0 = false;
if (index_of_input_dim0 == (${inputs[0].dims[0]} - 1)) {
// It's the end in dimension 0
x01 = x00;
end_of_dim0 = true;
} else {
x01 = getInputFloat(input_index + input_pitches[0]);
}
if (index_of_input_dim1 == (input_pitches[0] - 1)) {
// It's the end in dimension 1
x10 = x00;
x11 = x01;
}
else {
x10 = getInputFloat(input_index + 1);
x11 = end_of_dim0 ? x10 : getInputFloat(input_index + input_pitches[0] + 1);
}
float y0 = x00 + float(y_offset) * (x01 - x00) / float(scales[0]);
float y1 = x10 + float(y_offset) * (x11 - x10) / float(scales[0]);
return y0 + float(x_offset) * (y1 - y0) / float(scales[1]);
}`;
return Object.assign(Object.assign({}, upsampleProgramMetadata), { output: { dims: outputShape, type: inputs[0].type, textureType: types_1.TextureType.unpacked }, shaderSource, variables: [{
name: 'scales',
type: 'int',
arrayLength: attributes.scales.length,
data: attributes.scales.map(x => Math.ceil(x))
}] });
};
const validateInputs = (inputs, attribute) => {
if (!inputs || (attribute.opset < 9 && inputs.length !== 1) ||
(attribute.opset >= 9 && attribute.opset < 11 && inputs.length !== 2) ||
(attribute.opset >= 11 && inputs.length < 2)) {
throw new Error('invalid inputs.');
}
if (attribute.scales.length > 0 && inputs[0].dims.length !== attribute.scales.length) {
throw new Error('Invalid input shape.');
}
if (inputs[0].type === 'string') {
throw new Error('Invalid input tensor types.');
}
};
exports.validateInputs = validateInputs;
const scalesValidation = (scales, mode, isResize) => {
if (!isResize) {
for (const scale of scales) {
if (scale < 1) {
throw new Error('Scale value should be greater than or equal to 1.');
}
}
}
else {
for (const scale of scales) {
if (scale <= 0) {
throw new Error('Scale value should be greater than 0.');
}
}
}
if (mode === 'linear' || mode === 'cubic') {
if (scales.length !== 2 && (scales.length !== 4 || scales[0] !== 1 || scales[1] !== 1)) {
throw new Error(`'Linear' mode and 'Cubic' mode only support 2-D inputs ('Bilinear', 'Bicubic') \
or 4-D inputs with the corresponding outermost 2 scale values being 1 \
in the ${isResize ? 'Resize' : 'Upsample'} opeartor.`);
}
}
};
exports.scalesValidation = scalesValidation;
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/program-manager.ts":
/*!******************************************************!*\
!*** ./lib/onnxjs/backends/webgl/program-manager.ts ***!
\******************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.ProgramManager = void 0;
const onnxruntime_common_1 = __webpack_require__(/*! onnxruntime-common */ "onnxruntime-common");
const instrument_1 = __webpack_require__(/*! ../../instrument */ "./lib/onnxjs/instrument.ts");
const glsl_preprocessor_1 = __webpack_require__(/*! ./glsl-preprocessor */ "./lib/onnxjs/backends/webgl/glsl-preprocessor.ts");
const glsl_source_1 = __webpack_require__(/*! ./glsl-source */ "./lib/onnxjs/backends/webgl/glsl-source.ts");
/**
* ProgramManager is the main class behind running computations
* It builds ProgramInfo's into Artifacts
* It compiles given ProgramInfo's into WebGL Prorams (cached as Artifacts)
* Uses the artifact to run the computation by calling Draw on
* the WebGL drawing buffer
* ProgramManager automatically maps (binds) input variables to their
* corresponding Location's in the binary program
*/
class ProgramManager {
constructor(profiler, glContext, textureLayoutStrategy) {
this.profiler = profiler;
this.glContext = glContext;
this.textureLayoutStrategy = textureLayoutStrategy;
this.repo = new Map();
this.attributesBound = false;
}
getArtifact(key) {
return this.repo.get(key);
}
setArtifact(key, artifact) {
this.repo.set(key, artifact);
}
run(buildArtifact, inputs, output) {
var _a;
this.profiler.event('op', `ProgramManager.run ${(_a = buildArtifact.programInfo.name) !== null && _a !== void 0 ? _a : 'unknown kernel'}`, () => {
var _a;
const gl = this.glContext.gl;
const program = buildArtifact.program;
gl.useProgram(program);
try {
this.bindOutput(output);
if (!this.attributesBound) {
this.bindAttributes(buildArtifact.attribLocations);
}
this.bindUniforms(buildArtifact.uniformLocations, (_a = buildArtifact.programInfo.variables) !== null && _a !== void 0 ? _a : [], inputs);
}
catch (err) {
instrument_1.Logger.error('ProgramManager', buildArtifact.programInfo.shaderSource);
throw err;
}
this.profiler.event('backend', 'GlContext.draw()', () => {
this.glContext.draw();
});
}, this.glContext);
}
dispose() {
if (this.vertexShader) {
this.glContext.deleteShader(this.vertexShader);
}
this.repo.forEach(a => this.glContext.deleteProgram(a.program));
}
build(programInfo, inputTextureLayouts, outputTextureLayout) {
return this.profiler.event('backend', 'ProgramManager.build', () => {
const preprocessor = new glsl_preprocessor_1.GlslPreprocessor(this.glContext, programInfo, inputTextureLayouts, outputTextureLayout);
const fragScript = preprocessor.preprocess();
const program = this.compile(fragScript);
const artifact = {
programInfo,
program,
uniformLocations: this.getUniformLocations(program, preprocessor.context.programInfo.inputNames, preprocessor.context.programInfo.variables),
attribLocations: this.getAttribLocations(program)
};
return artifact;
});
}
compile(fragShaderScript) {
if (!this.vertexShader) {
instrument_1.Logger.verbose('ProrgramManager', 'Compiling and caching Vertex shader for the first time');
const vertexShaderScript = (0, glsl_source_1.getVertexShaderSource)(this.glContext.version);
this.vertexShader = this.glContext.compileShader(vertexShaderScript, this.glContext.gl.VERTEX_SHADER);
}
if (onnxruntime_common_1.env.debug) {
instrument_1.Logger.verbose('ProrgramManager', `FragShader:
${fragShaderScript}
`);
}
const fragShader = this.glContext.compileShader(fragShaderScript, this.glContext.gl.FRAGMENT_SHADER);
const program = this.glContext.createProgram(this.vertexShader, fragShader);
this.glContext.deleteShader(fragShader);
return program;
}
bindOutput(td) {
const width = td.width;
const height = td.height;
instrument_1.Logger.verbose('ProrgramManager', `Binding output texture to Framebuffer: w/h=${width}/${height}, shape=${td.shape}, type=${td.tensor.type}`);
this.glContext.attachFramebuffer(td.texture, width, height);
}
bindAttributes(attribLocations) {
const positionHandle = attribLocations.position;
const textureCoordHandle = attribLocations.textureCoord;
this.glContext.setVertexAttributes(positionHandle, textureCoordHandle);
this.attributesBound = true;
}
bindUniforms(uniformLocations, variables, textures) {
var _a;
const gl = this.glContext.gl;
let texturePosition = 0;
for (const { name, type, location, arrayLength } of uniformLocations) {
const value = (_a = variables.find(v => v.name === name)) === null || _a === void 0 ? void 0 : _a.data;
if (type !== 'sampler2D' && !value) {
throw new Error(`variable '${name}' does not have data defined in program info`);
}
switch (type) {
case 'sampler2D':
this.bindTexture(textures[texturePosition], location, texturePosition);
texturePosition++;
break;
case 'float':
if (arrayLength) {
gl.uniform1fv(location, value);
}
else {
gl.uniform1f(location, value);
}
break;
case 'int':
if (arrayLength) {
gl.uniform1iv(location, value);
}
else {
gl.uniform1i(location, value);
}
break;
default:
throw new Error(`Uniform not implemented: ${type}`);
}
}
}
bindTexture(td, uniformHandle, position) {
this.glContext.bindTextureToUniform(td.texture, position, uniformHandle);
}
getAttribLocations(program) {
return {
position: this.getAttribLocation(program, 'position'),
textureCoord: this.getAttribLocation(program, 'textureCoord')
};
}
getUniformLocations(program, samplers, variables) {
const uniformLocations = [];
if (samplers) {
for (const sampler of samplers) {
uniformLocations.push({ name: sampler, type: 'sampler2D', location: this.getUniformLocation(program, sampler) });
}
}
if (variables) {
for (const variable of variables) {
uniformLocations.push(Object.assign(Object.assign({}, variable), { location: this.getUniformLocation(program, variable.name) }));
}
}
return uniformLocations;
}
getUniformLocation(program, name) {
const gl = this.glContext.gl;
const reference = gl.getUniformLocation(program, name);
if (reference === null) {
throw new Error(`Uniform ${name} not found.`);
}
return reference;
}
getAttribLocation(program, name) {
const gl = this.glContext.gl;
const attributeLocation = gl.getAttribLocation(program, name);
return attributeLocation;
}
}
exports.ProgramManager = ProgramManager;
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/session-handler.ts":
/*!******************************************************!*\
!*** ./lib/onnxjs/backends/webgl/session-handler.ts ***!
\******************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.WebGLSessionHandler = void 0;
const instrument_1 = __webpack_require__(/*! ../../instrument */ "./lib/onnxjs/instrument.ts");
const opset_1 = __webpack_require__(/*! ../../opset */ "./lib/onnxjs/opset.ts");
const inference_handler_1 = __webpack_require__(/*! ./inference-handler */ "./lib/onnxjs/backends/webgl/inference-handler.ts");
const op_resolve_rules_1 = __webpack_require__(/*! ./op-resolve-rules */ "./lib/onnxjs/backends/webgl/op-resolve-rules.ts");
const program_manager_1 = __webpack_require__(/*! ./program-manager */ "./lib/onnxjs/backends/webgl/program-manager.ts");
const texture_layout_strategy_1 = __webpack_require__(/*! ./texture-layout-strategy */ "./lib/onnxjs/backends/webgl/texture-layout-strategy.ts");
const texture_manager_1 = __webpack_require__(/*! ./texture-manager */ "./lib/onnxjs/backends/webgl/texture-manager.ts");
class WebGLSessionHandler {
constructor(backend, context) {
this.backend = backend;
this.context = context;
this.layoutStrategy = new texture_layout_strategy_1.PreferLogicalStrategy(backend.glContext.maxTextureSize);
this.programManager = new program_manager_1.ProgramManager(this.context.profiler, backend.glContext, this.layoutStrategy);
this.textureManager = new texture_manager_1.TextureManager(backend.glContext, this.layoutStrategy, this.context.profiler, { reuseTextures: backend.textureCacheMode === 'full' });
this.packedTextureDataCache = new Map();
this.unpackedTextureDataCache = new Map();
this.pack = backend.pack;
this.pack2unpackMap = new Map();
this.unpack2packMap = new Map();
}
createInferenceHandler() {
return new inference_handler_1.WebGLInferenceHandler(this);
}
onGraphInitialized(graph) {
const initializers = graph.getValues().filter(v => v.from === -1 && v.tensor).map(v => v.tensor.dataId);
this.initializers = new Set(initializers);
}
isInitializer(tensorId) {
return this.initializers ? this.initializers.has(tensorId) : false;
}
addInitializer(tensorId) {
this.initializers.add(tensorId);
}
getTextureData(tensorId, isPacked) {
if (isPacked) {
return this.packedTextureDataCache.get(tensorId);
}
else {
return this.unpackedTextureDataCache.get(tensorId);
}
}
setTextureData(tensorId, textureData, isPacked = false) {
instrument_1.Logger.verbose('WebGLSessionHandler', 'Storing Texture data in cache');
if (isPacked) {
this.packedTextureDataCache.set(tensorId, textureData);
}
else {
this.unpackedTextureDataCache.set(tensorId, textureData);
}
}
dispose() {
this.programManager.dispose();
this.textureManager.clearActiveTextures();
this.packedTextureDataCache.forEach(td => this.textureManager.releaseTexture(td, true));
this.packedTextureDataCache = new Map();
this.unpackedTextureDataCache.forEach(td => this.textureManager.releaseTexture(td, true));
this.unpackedTextureDataCache = new Map();
}
resolve(node, opsets, graph) {
const op = (0, opset_1.resolveOperator)(node, opsets, op_resolve_rules_1.WEBGL_OP_RESOLVE_RULES);
return { impl: op.opImpl, context: op.opInit ? op.opInit(node, graph) : node };
}
}
exports.WebGLSessionHandler = WebGLSessionHandler;
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/texture-data-encoder.ts":
/*!***********************************************************!*\
!*** ./lib/onnxjs/backends/webgl/texture-data-encoder.ts ***!
\***********************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.Uint8DataEncoder = exports.RGBAFloatDataEncoder = exports.RedFloat32DataEncoder = void 0;
const instrument_1 = __webpack_require__(/*! ../../instrument */ "./lib/onnxjs/instrument.ts");
/**
* WebGL2 data encoder
* Uses R32F as the format for texlet
*/
class RedFloat32DataEncoder {
constructor(gl, channels = 1) {
if (channels === 1) {
this.internalFormat = gl.R32F;
this.format = gl.RED;
this.textureType = gl.FLOAT;
this.channelSize = channels;
}
else if (channels === 4) {
this.internalFormat = gl.RGBA32F;
this.format = gl.RGBA;
this.textureType = gl.FLOAT;
this.channelSize = channels;
}
else {
throw new Error(`Invalid number of channels: ${channels}`);
}
}
encode(src, textureSize) {
let result;
let source;
if (src.constructor !== Float32Array) {
instrument_1.Logger.warning('Encoder', 'data was not of type Float32; creating new Float32Array');
source = new Float32Array(src);
}
if (textureSize * this.channelSize > src.length) {
instrument_1.Logger.warning('Encoder', 'Source data too small. Allocating larger array');
source = src;
result = this.allocate(textureSize * this.channelSize);
source.forEach((v, i) => result[i] = v);
}
else {
source = src;
result = source;
}
return result;
}
allocate(size) {
return new Float32Array(size * 4);
}
decode(buffer, dataSize) {
if (this.channelSize === 1) {
const filteredData = buffer.filter((value, index) => index % 4 === 0).subarray(0, dataSize);
return filteredData;
}
return buffer.subarray(0, dataSize);
}
}
exports.RedFloat32DataEncoder = RedFloat32DataEncoder;
/**
* Data encoder for WebGL 1 with support for floating point texture
*/
class RGBAFloatDataEncoder {
constructor(gl, channels = 1, textureType) {
if (channels !== 1 && channels !== 4) {
throw new Error(`Invalid number of channels: ${channels}`);
}
this.internalFormat = gl.RGBA;
this.format = gl.RGBA;
this.channelSize = channels;
this.textureType = textureType || gl.FLOAT;
}
encode(src, textureSize) {
let dest = src;
if (this.channelSize === 1) {
instrument_1.Logger.verbose('Encoder', 'Exploding into a larger array');
dest = this.allocate(textureSize);
src.forEach((v, i) => dest[i * 4] = v);
}
return dest;
}
allocate(size) {
return new Float32Array(size * 4);
}
decode(buffer, dataSize) {
if (this.channelSize === 1) {
const filteredData = buffer.filter((value, index) => index % 4 === 0).subarray(0, dataSize);
return filteredData;
}
return buffer.subarray(0, dataSize);
}
}
exports.RGBAFloatDataEncoder = RGBAFloatDataEncoder;
class Uint8DataEncoder {
constructor(gl, channels = 1) {
this.channelSize = 4;
if (channels === 1) {
this.internalFormat = gl.ALPHA;
this.format = gl.ALPHA; // not tested
this.textureType = gl.UNSIGNED_BYTE;
this.channelSize = channels;
}
else if (channels === 4) {
this.internalFormat = gl.RGBA;
this.format = gl.RGBA;
this.textureType = gl.UNSIGNED_BYTE;
this.channelSize = channels;
}
else {
throw new Error(`Invalid number of channels: ${channels}`);
}
}
encode(src, _textureSize) {
return new Uint8Array(src.buffer, src.byteOffset, src.byteLength);
}
allocate(size) {
return new Uint8Array(size * this.channelSize);
}
decode(buffer, dataSize) {
if (buffer instanceof Uint8Array) {
return buffer.subarray(0, dataSize);
}
throw new Error(`Invalid array type: ${buffer.constructor}`);
}
}
exports.Uint8DataEncoder = Uint8DataEncoder;
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/texture-layout-strategy.ts":
/*!**************************************************************!*\
!*** ./lib/onnxjs/backends/webgl/texture-layout-strategy.ts ***!
\**************************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getBatchDim = exports.sizeToSquarishShape = exports.getRowsCols = exports.sizeFromShape = exports.isInt = exports.parseAxisParam = exports.squeezeShape = exports.PreferLogicalStrategy = exports.AlwaysKeepOriginalSizeStrategy = void 0;
const instrument_1 = __webpack_require__(/*! ../../instrument */ "./lib/onnxjs/instrument.ts");
const util_1 = __webpack_require__(/*! ../../util */ "./lib/onnxjs/util.ts");
/**
* This strategy try to find the minimal max(W,H) that fulfills (W * H == totalSize)
*/
class AlwaysKeepOriginalSizeStrategy {
constructor(maxTextureSize) {
this.maxTextureSize = maxTextureSize;
}
computeTextureWH(shape, prefs) {
// scalar tensor
if (shape.length === 0) {
return [1, 1];
}
const maxTextureSize = this.maxTextureSize;
if (prefs && prefs.breakAxis !== undefined) {
// check to see if dims fit
const wsize = prefs.breakAxis >= shape.length ? 1 : shape.slice(prefs.breakAxis).reduce((a, b) => a * b);
const hsize = prefs.breakAxis <= 0 ? 1 : shape.slice(0, prefs.breakAxis).reduce((a, b) => a * b);
if (wsize > maxTextureSize || hsize > maxTextureSize) {
// ignore preferences
// continue with default layout
instrument_1.Logger.verbose('TextureLayout', `Given width/height preferences were unattainable: shape:${shape}, breakAxis:${prefs.breakAxis}`);
}
else {
return [wsize, hsize];
}
}
const totalSize = shape.reduce((a, b) => a * b);
let width = Math.floor(Math.sqrt(totalSize));
for (; width < maxTextureSize && width < totalSize; width++) {
if (totalSize % width === 0) {
break;
}
}
if (width >= maxTextureSize || totalSize % width !== 0) {
throw new Error(`The given dimensions are outside this GPU's boundaries: ${shape}`);
}
return [width, totalSize / width];
}
}
exports.AlwaysKeepOriginalSizeStrategy = AlwaysKeepOriginalSizeStrategy;
class PreferLogicalStrategy {
constructor(maxTextureSize) {
this.maxTextureSize = maxTextureSize;
}
computeTextureWH(shape, prefs) {
const wh = this.computeTexture(shape, prefs);
if (prefs && prefs.isPacked) {
wh[0] /= 2;
wh[1] /= 2;
}
if (prefs && prefs.reverseWH) {
return [wh[1], wh[0]];
}
return wh;
}
computeTexture(shape, prefs) {
const isPacked = prefs && prefs.isPacked;
// scalar tensor
if (shape.length === 0) {
return isPacked ? [2, 2] : [1, 1];
}
let maxTextureSize = this.maxTextureSize;
if (prefs && prefs.breakAxis !== undefined) {
// check to see if dims fit
const wsize = prefs.breakAxis >= shape.length ? 1 : shape.slice(prefs.breakAxis).reduce((a, b) => a * b);
const hsize = prefs.breakAxis <= 0 ? 1 : shape.slice(0, prefs.breakAxis).reduce((a, b) => a * b);
if (wsize > maxTextureSize || hsize > maxTextureSize) {
// ignore preferences
// continue with default layout
instrument_1.Logger.verbose('TextureLayout', `Given width/height preferences were unattainable: shape:${shape}, breakAxis:${prefs.breakAxis}`);
}
else {
return [wsize, hsize];
}
}
let logShape = shape.slice(0);
if (isPacked) {
maxTextureSize = maxTextureSize * 2;
// This logic ensures we accurately count the number of packed texels needed
// to accommodate the tensor. We can only pack values in the same texel if
// they are from adjacent pairs of rows/cols within the same batch. So if a
// tensor has 3 rows, we pretend it has 4 rows in order to account for the
// fact that the texels containing the third row are half empty.
logShape = logShape.map((d, i) => i >= logShape.length - 2 ? (logShape[i] % 2 === 0 ? logShape[i] : logShape[i] + 1) : logShape[i]);
// Packed texture height is at least 2 (the channel height of a single
// texel).
if (logShape.length === 1) {
logShape = [2, logShape[0]];
}
}
// If logical shape is 2, we don't squeeze, since we want to match physical.
if (logShape.length !== 2) {
const squeezeResult = squeezeShape(logShape);
logShape = squeezeResult.newShape;
}
const size = sizeFromShape(logShape);
if (logShape.length <= 1 && size <= maxTextureSize) {
return [1, size];
}
else if (logShape.length === 2 && logShape[0] <= maxTextureSize && logShape[1] <= maxTextureSize) {
return logShape;
}
else if (logShape.length === 3 && logShape[0] * logShape[1] <= maxTextureSize && logShape[2] <= maxTextureSize) {
return [logShape[0] * logShape[1], logShape[2]];
}
else if (logShape.length === 3 && logShape[0] <= maxTextureSize && logShape[1] * logShape[2] <= maxTextureSize) {
return [logShape[0], logShape[1] * logShape[2]];
}
else if (logShape.length === 4 && logShape[0] * logShape[1] * logShape[2] <= maxTextureSize &&
logShape[3] <= maxTextureSize) {
return [logShape[0] * logShape[1] * logShape[2], logShape[3]];
}
else if (logShape.length === 4 && logShape[0] <= maxTextureSize &&
logShape[1] * logShape[2] * logShape[3] <= maxTextureSize) {
return [logShape[0], logShape[1] * logShape[2] * logShape[3]];
}
else {
if (isPacked) {
// For packed textures size equals the number of channels required to
// accommodate the texture data. However in order to squarify such that
// inner dimensions stay even, we rewrite size to equal the number of
// texels. Then in the return statement we rehydrate the squarified
// dimensions to channel units.
return sizeToSquarishShape(size / 4).map(d => d * 2);
}
return sizeToSquarishShape(size);
}
}
}
exports.PreferLogicalStrategy = PreferLogicalStrategy;
function squeezeShape(shape, axis) {
const newShape = [];
const keptDims = [];
const isEmptyArray = axis != null && Array.isArray(axis) && axis.length === 0;
const axes = (axis == null || isEmptyArray) ? null : parseAxisParam(axis, shape).sort();
let j = 0;
for (let i = 0; i < shape.length; ++i) {
if (axes != null) {
if (axes[j] === i && shape[i] !== 1) {
throw new Error(`Can't squeeze axis ${i} since its dim '${shape[i]}' is not 1`);
}
if ((axes[j] == null || axes[j] > i) && shape[i] === 1) {
newShape.push(shape[i]);
keptDims.push(i);
}
if (axes[j] <= i) {
j++;
}
}
if (shape[i] !== 1) {
newShape.push(shape[i]);
keptDims.push(i);
}
}
return { newShape, keptDims };
}
exports.squeezeShape = squeezeShape;
function parseAxisParam(axis, shape) {
const rank = shape.length;
// Normalize input
axis = axis == null ? shape.map((s, i) => i) : [].concat(axis);
// Check for valid range
(0, util_1.assert)(axis.every(ax => ax >= -rank && ax < rank), () => `All values in axis param must be in range [-${rank}, ${rank}) but ` +
`got axis ${axis}`);
// Check for only integers
(0, util_1.assert)(axis.every(isInt), () => 'All values in axis param must be integers but ' +
`got axis ${axis}`);
// Handle negative axis.
return axis.map(a => a < 0 ? rank + a : a);
}
exports.parseAxisParam = parseAxisParam;
function isInt(a) {
return a % 1 === 0;
}
exports.isInt = isInt;
function sizeFromShape(shape) {
if (shape.length === 0) {
// Scalar.
return 1;
}
let size = shape[0];
for (let i = 1; i < shape.length; i++) {
size *= shape[i];
}
return size;
}
exports.sizeFromShape = sizeFromShape;
function getRowsCols(shape) {
if (shape.length === 0) {
throw Error('Cannot get rows and columns of an empty shape array.');
}
return [shape.length > 1 ? shape[shape.length - 2] : 1, shape[shape.length - 1]];
}
exports.getRowsCols = getRowsCols;
function sizeToSquarishShape(size) {
const width = Math.ceil(Math.sqrt(size));
return [width, Math.ceil(size / width)];
}
exports.sizeToSquarishShape = sizeToSquarishShape;
function getBatchDim(shape, dimsToSkip = 2) {
return sizeFromShape(shape.slice(0, shape.length - dimsToSkip));
}
exports.getBatchDim = getBatchDim;
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/texture-layout.ts":
/*!*****************************************************!*\
!*** ./lib/onnxjs/backends/webgl/texture-layout.ts ***!
\*****************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.createTextureLayoutFromShape = exports.calculateTextureWidthAndHeight = exports.createTextureLayoutFromTextureType = void 0;
const util_1 = __webpack_require__(/*! ../../util */ "./lib/onnxjs/util.ts");
const types_1 = __webpack_require__(/*! ./types */ "./lib/onnxjs/backends/webgl/types.ts");
const createTextureLayoutFromTextureType = (textureLayoutStrategy, shape, textureType) => {
const channel = (textureType === types_1.TextureType.unpacked || textureType === types_1.TextureType.unpackedReversed) ? 1 : 4;
const isPacked = textureType === types_1.TextureType.packed;
const reverseWH = (textureType === types_1.TextureType.unpackedReversed || textureType === types_1.TextureType.packed);
const breakAxis = textureType === types_1.TextureType.packedLastDimension ? shape.length - 1 : undefined;
const unpackedShape = textureType === types_1.TextureType.packedLastDimension ?
shape.map((d, i) => i === shape.length - 1 ? d * 4 : d) :
undefined;
return (0, exports.createTextureLayoutFromShape)(textureLayoutStrategy, shape, channel, unpackedShape, { isPacked, reverseWH, breakAxis });
};
exports.createTextureLayoutFromTextureType = createTextureLayoutFromTextureType;
const calculateTextureWidthAndHeight = (textureLayoutStrategy, shape, textureType) => {
const layout = (0, exports.createTextureLayoutFromTextureType)(textureLayoutStrategy, shape, textureType);
return [layout.width, layout.height];
};
exports.calculateTextureWidthAndHeight = calculateTextureWidthAndHeight;
/**
* Create a TextureLayout object from shape.
*/
const createTextureLayoutFromShape = (textureLayoutStrategy, shape, channels = 1, unpackedShape, prefs) => {
const isPacked = !!(prefs && prefs.isPacked);
const [width, height] = textureLayoutStrategy.computeTextureWH(isPacked ? unpackedShape || shape : shape, prefs);
const rank = shape.length;
let inferredDims = shape.slice(0);
if (rank === 0) {
inferredDims = [1];
}
if (channels === 1) {
// unpackedShape will take `shape` and not `inferredDims` so as to create a scalar Tensor if need be
unpackedShape = shape;
}
else if (isPacked) {
if (channels !== 4) {
throw new Error('a packed texture must be 4-channel');
}
unpackedShape = shape;
if (rank > 0) {
inferredDims[rank - 1] = Math.ceil(inferredDims[rank - 1] / 2);
}
if (rank > 1) {
inferredDims[rank - 2] = Math.ceil(inferredDims[rank - 2] / 2);
}
}
else if (!unpackedShape) {
throw new Error('Unpacked shape is needed when using channels > 1');
}
return {
width,
height,
channels,
isPacked,
shape: inferredDims,
strides: util_1.ShapeUtil.computeStrides(inferredDims),
unpackedShape,
reversedWH: (prefs && prefs.reverseWH)
};
};
exports.createTextureLayoutFromShape = createTextureLayoutFromShape;
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/texture-manager.ts":
/*!******************************************************!*\
!*** ./lib/onnxjs/backends/webgl/texture-manager.ts ***!
\******************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.TextureManager = void 0;
const instrument_1 = __webpack_require__(/*! ../../instrument */ "./lib/onnxjs/instrument.ts");
/**
* TextureManager is the mainly responsible for caching Textures
* Textures are cached in 2 levels:
* 1. the texures which are associated with a dataId (from Tensor)
* Caching these is crucial to performance. These are In-use Textures
* 2. textures which are not in use by any current ProgramInfo/Tensor
* These are called Free Textures
* TextureManager is also used to help creating textures. For this it
* uses WebGLContext and TextureLayoutStrategy
*/
class TextureManager {
constructor(glContext, layoutStrategy, profiler, config) {
this.glContext = glContext;
this.layoutStrategy = layoutStrategy;
this.profiler = profiler;
this.config = config;
this.pendingRead = new Map();
if (config.reuseTextures) {
this.inUseTextures = new Map();
this.idleTextures = new Map();
this.textureLookup = new Map();
}
}
createTextureFromLayout(dataType, layout, data, usage) {
const textureDataType = this.toEncoderType(dataType);
const encoder = this.glContext.getEncoder(textureDataType, layout.channels || 1, usage);
if (layout.isPacked && usage === 1 /* Encoder.Usage.UploadOnly */) {
throw new Error('not implemented');
}
const width = layout.width;
const height = layout.height;
let key;
let inUseTextures;
if (this.config.reuseTextures) {
key = `${width}x${height}_${encoder.format}_${encoder.internalFormat}_${encoder.textureType}`;
inUseTextures = this.inUseTextures.get(key);
if (!inUseTextures) {
inUseTextures = [];
this.inUseTextures.set(key, inUseTextures);
}
const idleTextures = this.idleTextures.get(key);
if (idleTextures && idleTextures.length > 0) {
const texture = idleTextures.pop();
inUseTextures.push(texture);
if (usage === 1 /* Encoder.Usage.UploadOnly */) {
this.glContext.updateTexture(texture, width, height, encoder, this.toTextureData(dataType, data));
}
return texture;
}
}
instrument_1.Logger.verbose('TextureManager', `Creating new texture of size ${layout.width}x${layout.height}`);
const texture = this.glContext.allocateTexture(width, height, encoder, this.toTextureData(dataType, data));
if (this.config.reuseTextures) {
inUseTextures.push(texture);
this.textureLookup.set(texture, key);
}
return texture;
}
readTexture(td, dataType, channels) {
if (!channels) {
channels = 1;
}
return this.profiler.event('backend', 'TextureManager.readTexture', () => {
const dataSize = td.shape.reduce((a, b) => a * b) * channels;
const data = this.glContext.readTexture(td.texture, td.width, td.height, dataSize, this.toEncoderType(dataType), channels);
return this.toTensorData(dataType, data);
});
}
async readTextureAsync(td, dataType, channels) {
const dataId = td.tensor.dataId;
if (!channels) {
channels = 1;
}
if (this.pendingRead.has(dataId)) {
const subscribers = this.pendingRead.get(dataId);
return new Promise(resolve => subscribers === null || subscribers === void 0 ? void 0 : subscribers.push(resolve));
}
return this.profiler.event('backend', 'TextureManager.readTextureAsync', async () => {
this.pendingRead.set(dataId, []);
const dataSize = td.shape.reduce((a, b) => a * b) * channels;
// add a fence waiting for the data to be ready
await this.glContext.createAndWaitForFence();
const data = this.glContext.readTexture(td.texture, td.width, td.height, dataSize, this.toEncoderType(dataType), channels);
const tensorData = this.toTensorData(dataType, data);
const subscribers = this.pendingRead.get(dataId);
this.pendingRead.delete(dataId);
subscribers === null || subscribers === void 0 ? void 0 : subscribers.forEach(resolve => resolve(tensorData));
return tensorData;
});
}
readUint8TextureAsFloat(td) {
return this.profiler.event('backend', 'TextureManager.readUint8TextureAsFloat', () => {
const dataSize = td.shape.reduce((a, b) => a * b);
const data = this.glContext.readTexture(td.texture, td.width, td.height, dataSize * 4, 'byte', 4);
return new Float32Array(data.buffer, data.byteOffset, dataSize);
});
}
releaseTexture(textureData, deleteTexture) {
let key;
if (this.config.reuseTextures) {
key = this.textureLookup.get(textureData.texture);
if (key) {
if (deleteTexture) {
this.textureLookup.delete(key);
}
const inUseTextures = this.inUseTextures.get(key);
if (inUseTextures) {
const index = inUseTextures.indexOf(textureData.texture);
if (index !== -1) {
inUseTextures.splice(index, 1);
let idleTextures = this.idleTextures.get(key);
if (!idleTextures) {
idleTextures = [];
this.idleTextures.set(key, idleTextures);
}
idleTextures.push(textureData.texture);
}
}
}
}
if (!key || deleteTexture) {
instrument_1.Logger.verbose('TextureManager', `Deleting texture of size ${textureData.width}x${textureData.height}`);
this.glContext.deleteTexture(textureData.texture);
}
}
toTensorData(dataType, data) {
switch (dataType) {
case 'int16':
return data instanceof Int16Array ? data : Int16Array.from(data);
case 'int32':
return data instanceof Int32Array ? data : Int32Array.from(data);
case 'int8':
return data instanceof Int8Array ? data : Int8Array.from(data);
case 'uint16':
return data instanceof Uint16Array ? data : Uint16Array.from(data);
case 'uint32':
return data instanceof Uint32Array ? data : Uint32Array.from(data);
case 'uint8':
case 'bool':
return data instanceof Uint8Array ? data : Uint8Array.from(data);
case 'float32':
return data instanceof Float32Array ? data : Float32Array.from(data);
case 'float64':
return data instanceof Float64Array ? data : Float64Array.from(data);
default:
throw new Error(`TensorData type ${dataType} is not supported`);
}
}
toTextureData(dataType, data) {
if (!data) {
return undefined;
}
return (data instanceof Float32Array) ? data : new Float32Array(data);
/*
switch (dataType) {
case 'int16':
case 'int32':
case 'uint16':
case 'uint32':
return (data.constructor === Uint32Array) ? data as Uint32Array : new Uint32Array(data);
case 'int8':
case 'uint8':
case 'bool':
return (data.constructor === Uint8Array) ? data as Uint8Array : new Uint8Array(data);
case 'float32':
case 'float64':
return (data.constructor === Float32Array) ? data as Float32Array : new Float32Array(data);
default:
throw new Error(`TensorData type ${dataType} is not supported`);
}
*/
}
toEncoderType(_dataType) {
return 'float';
// switch (dataType) {
// case 'int16':
// case 'int32':
// case 'uint16':
// case 'uint32':
// return 'int';
// case 'uint8':
// case 'bool':
// return 'byte';
// case 'float32':
// case 'float64':
// return 'float';
// default:
// throw new Error(`TensorData type ${dataType} is not supported`);
// }
}
clearActiveTextures() {
this.glContext.clearActiveTextures();
}
}
exports.TextureManager = TextureManager;
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/types.ts":
/*!********************************************!*\
!*** ./lib/onnxjs/backends/webgl/types.ts ***!
\********************************************/
/***/ ((__unused_webpack_module, exports) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.TextureType = void 0;
var TextureType;
(function (TextureType) {
TextureType[TextureType["unpacked"] = 0] = "unpacked";
TextureType[TextureType["unpackedReversed"] = 1] = "unpackedReversed";
TextureType[TextureType["packed"] = 2] = "packed";
TextureType[TextureType["downloadUint8AsFloat"] = 3] = "downloadUint8AsFloat";
TextureType[TextureType["packedLastDimension"] = 4] = "packedLastDimension"; // <-- ONLY used in old ONNX.js Conv implementation for input W (deprecated)
})(TextureType = exports.TextureType || (exports.TextureType = {}));
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/utils.ts":
/*!********************************************!*\
!*** ./lib/onnxjs/backends/webgl/utils.ts ***!
\********************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getGlChannels = exports.getCoordsDataType = exports.getSqueezedParams = exports.squeezeInputShape = exports.generateShaderFuncNameFromInputSamplerNameAtOutCoords = exports.generateShaderFuncNameFromInputSamplerName = exports.repeatedTry = exports.getPackedShape = void 0;
const util_1 = __webpack_require__(/*! ../../util */ "./lib/onnxjs/util.ts");
/**
* Given a non RGBA shape calculate the R version
* It is assumed that the dimensions are multiples of given channels
* NOTE: it is always the last dim that gets packed.
* @param unpackedShape original shape to create a packed version from
*/
function getPackedShape(unpackedShape) {
const len = unpackedShape.length;
return unpackedShape.slice(0, len - 1).concat(unpackedShape[len - 1] / 4);
}
exports.getPackedShape = getPackedShape;
async function repeatedTry(checkFn, delayFn = (_counter) => 0, maxCounter) {
return new Promise((resolve, reject) => {
let tryCount = 0;
const tryFn = () => {
if (checkFn()) {
resolve();
return;
}
tryCount++;
const nextBackoff = delayFn(tryCount);
if (maxCounter != null && tryCount >= maxCounter) {
reject();
return;
}
setTimeout(tryFn, nextBackoff);
};
tryFn();
});
}
exports.repeatedTry = repeatedTry;
/**
* Generates the function name from an input sampler name.
* @param samplerName Name of the sampler.
*/
function generateShaderFuncNameFromInputSamplerName(samplerName) {
(0, util_1.assert)(typeof samplerName !== 'undefined' && samplerName.length !== 0, () => 'empty string found for sampler name');
return 'get' + samplerName.charAt(0).toUpperCase() + samplerName.slice(1);
}
exports.generateShaderFuncNameFromInputSamplerName = generateShaderFuncNameFromInputSamplerName;
/**
* Generates the function name from an input sampler name at output coordinates.
* @param samplerName Name of the sampler.
*/
function generateShaderFuncNameFromInputSamplerNameAtOutCoords(samplerName) {
(0, util_1.assert)(typeof samplerName !== 'undefined' && samplerName.length !== 0, () => 'empty string found for sampler name');
return 'get' + samplerName.charAt(0).toUpperCase() + samplerName.slice(1) + 'AtOutCoords';
}
exports.generateShaderFuncNameFromInputSamplerNameAtOutCoords = generateShaderFuncNameFromInputSamplerNameAtOutCoords;
/** Returns a new input shape (a copy) that has a squeezed logical shape. */
function squeezeInputShape(inputShape, squeezedShape) {
// Deep copy.
let newInputShape = JSON.parse(JSON.stringify(inputShape));
newInputShape = squeezedShape;
return newInputShape;
}
exports.squeezeInputShape = squeezeInputShape;
/** Returns a list of squeezed parameters for shader functions */
function getSqueezedParams(params, keptDims) {
return keptDims.map(d => params[d]).join(', ');
}
exports.getSqueezedParams = getSqueezedParams;
/** Returns the data type for different ranks. */
function getCoordsDataType(rank) {
if (rank <= 1) {
return 'int';
}
else if (rank === 2) {
return 'ivec2';
}
else if (rank === 3) {
return 'ivec3';
}
else if (rank === 4) {
return 'ivec4';
}
else if (rank === 5) {
return 'ivec5';
}
else if (rank === 6) {
return 'ivec6';
}
else {
throw Error(`GPU for rank ${rank} is not yet supported`);
}
}
exports.getCoordsDataType = getCoordsDataType;
function getGlChannels(rank = 6) {
return ['x', 'y', 'z', 'w', 'u', 'v'].slice(0, rank);
}
exports.getGlChannels = getGlChannels;
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/webgl-context-factory.ts":
/*!************************************************************!*\
!*** ./lib/onnxjs/backends/webgl/webgl-context-factory.ts ***!
\************************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.createNewWebGLContext = exports.createWebGLContext = void 0;
const instrument_1 = __webpack_require__(/*! ../../instrument */ "./lib/onnxjs/instrument.ts");
const webgl_context_1 = __webpack_require__(/*! ./webgl-context */ "./lib/onnxjs/backends/webgl/webgl-context.ts");
const cache = {};
/**
* This factory function creates proper WebGLRenderingContext based on
* the current browsers capabilities
* The order is from higher/most recent versions to most basic
*/
function createWebGLContext(contextId) {
let context;
if ((!contextId || contextId === 'webgl2') && 'webgl2' in cache) {
context = cache.webgl2;
}
else if ((!contextId || contextId === 'webgl') && 'webgl' in cache) {
context = cache.webgl;
}
context = context || createNewWebGLContext(contextId);
contextId = contextId || context.version === 1 ? 'webgl' : 'webgl2';
const gl = context.gl;
cache[contextId] = context;
if (gl.isContextLost()) {
delete cache[contextId];
return createWebGLContext(contextId);
}
gl.disable(gl.DEPTH_TEST);
gl.disable(gl.STENCIL_TEST);
gl.disable(gl.BLEND);
gl.disable(gl.DITHER);
gl.disable(gl.POLYGON_OFFSET_FILL);
gl.disable(gl.SAMPLE_COVERAGE);
gl.enable(gl.SCISSOR_TEST);
gl.enable(gl.CULL_FACE);
gl.cullFace(gl.BACK);
return context;
}
exports.createWebGLContext = createWebGLContext;
function createNewWebGLContext(contextId) {
const canvas = createCanvas();
const contextAttributes = {
alpha: false,
depth: false,
antialias: false,
stencil: false,
preserveDrawingBuffer: false,
premultipliedAlpha: false,
failIfMajorPerformanceCaveat: false
};
let gl;
const ca = contextAttributes;
if (!contextId || contextId === 'webgl2') {
gl = canvas.getContext('webgl2', ca);
if (gl) {
try {
return new webgl_context_1.WebGLContext(gl, 2);
}
catch (err) {
instrument_1.Logger.warning('GlContextFactory', `failed to create WebGLContext using contextId 'webgl2'. Error: ${err}`);
}
}
}
if (!contextId || contextId === 'webgl') {
gl = canvas.getContext('webgl', ca) || canvas.getContext('experimental-webgl', ca);
if (gl) {
try {
return new webgl_context_1.WebGLContext(gl, 1);
}
catch (err) {
instrument_1.Logger.warning('GlContextFactory', `failed to create WebGLContext using contextId 'webgl' or 'experimental-webgl'. Error: ${err}`);
}
}
}
throw new Error('WebGL is not supported');
}
exports.createNewWebGLContext = createNewWebGLContext;
function createCanvas() {
if (typeof document === 'undefined') {
if (typeof OffscreenCanvas === 'undefined') {
throw new TypeError('failed to create canvas: OffscreenCanvas is not supported');
}
return new OffscreenCanvas(1, 1);
}
const canvas = document.createElement('canvas');
canvas.width = 1;
canvas.height = 1;
return canvas;
}
/***/ }),
/***/ "./lib/onnxjs/backends/webgl/webgl-context.ts":
/*!****************************************************!*\
!*** ./lib/onnxjs/backends/webgl/webgl-context.ts ***!
\****************************************************/
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.WebGLContext = exports.linearSearchLastTrue = void 0;
const onnxruntime_common_1 = __webpack_require__(/*! onnxruntime-common */ "onnxruntime-common");
const DataEncoders = __importStar(__webpack_require__(/*! ./texture-data-encoder */ "./lib/onnxjs/backends/webgl/texture-data-encoder.ts"));
const utils_1 = __webpack_require__(/*! ./utils */ "./lib/onnxjs/backends/webgl/utils.ts");
function linearSearchLastTrue(arr) {
let i = 0;
for (; i < arr.length; ++i) {
const isDone = arr[i]();
if (!isDone) {
break;
}
}
return i - 1;
}
exports.linearSearchLastTrue = linearSearchLastTrue;
/**
* Abstraction and wrapper around WebGLRenderingContext and its operations
*/
class WebGLContext {
constructor(gl, version) {
this.frameBufferBound = false;
this.itemsToPoll = [];
this.gl = gl;
this.version = version;
this.getExtensions();
this.vertexbuffer = this.createVertexbuffer();
this.framebuffer = this.createFramebuffer();
this.queryVitalParameters();
}
allocateTexture(width, height, encoder, data) {
const gl = this.gl;
// create the texture
const texture = gl.createTexture();
// bind the texture so the following methods effect this texture.
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
const buffer = data ? encoder.encode(data, width * height) : null;
gl.texImage2D(gl.TEXTURE_2D, 0, // Level of detail.
encoder.internalFormat, width, height, 0, // Always 0 in OpenGL ES.
encoder.format, encoder.textureType, buffer);
this.checkError();
return texture;
}
updateTexture(texture, width, height, encoder, data) {
const gl = this.gl;
gl.bindTexture(gl.TEXTURE_2D, texture);
const buffer = encoder.encode(data, width * height);
gl.texSubImage2D(gl.TEXTURE_2D, 0, // level
0, // xoffset
0, // yoffset
width, height, encoder.format, encoder.textureType, buffer);
this.checkError();
}
attachFramebuffer(texture, width, height) {
const gl = this.gl;
// Make it the target for framebuffer operations - including rendering.
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); // 0, we aren't using MIPMAPs
this.checkError();
gl.viewport(0, 0, width, height);
gl.scissor(0, 0, width, height);
}
readTexture(texture, width, height, dataSize, dataType, channels) {
const gl = this.gl;
if (!channels) {
channels = 1;
}
if (!this.frameBufferBound) {
this.attachFramebuffer(texture, width, height);
}
const encoder = this.getEncoder(dataType, channels);
const buffer = encoder.allocate(width * height);
// bind texture to framebuffer
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); // 0, we aren't using MIPMAPs
// TODO: Check if framebuffer is ready
gl.readPixels(0, 0, width, height, gl.RGBA, encoder.textureType, buffer);
this.checkError();
// unbind FB
return encoder.decode(buffer, dataSize);
}
isFramebufferReady() {
// TODO: Implement logic to check if the framebuffer is ready
return true;
}
getActiveTexture() {
const gl = this.gl;
const n = gl.getParameter(this.gl.ACTIVE_TEXTURE);
return `TEXTURE${(n - gl.TEXTURE0)}`;
}
getTextureBinding() {
return this.gl.getParameter(this.gl.TEXTURE_BINDING_2D);
}
getFramebufferBinding() {
return this.gl.getParameter(this.gl.FRAMEBUFFER_BINDING);
}
setVertexAttributes(positionHandle, textureCoordHandle) {
const gl = this.gl;
gl.vertexAttribPointer(positionHandle, 3, gl.FLOAT, false, 20, 0);
gl.enableVertexAttribArray(positionHandle);
if (textureCoordHandle !== -1) {
gl.vertexAttribPointer(textureCoordHandle, 2, gl.FLOAT, false, 20, 12);
gl.enableVertexAttribArray(textureCoordHandle);
}
this.checkError();
}
createProgram(vertexShader, fragShader) {
const gl = this.gl;
const program = gl.createProgram();
// the program consists of our shaders
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragShader);
gl.linkProgram(program);
return program;
}
compileShader(shaderSource, shaderType) {
const gl = this.gl;
const shader = gl.createShader(shaderType);
if (!shader) {
throw new Error(`createShader() returned null with type ${shaderType}`);
}
gl.shaderSource(shader, shaderSource);
gl.compileShader(shader);
if (gl.getShaderParameter(shader, gl.COMPILE_STATUS) === false) {
throw new Error(`Failed to compile shader: ${gl.getShaderInfoLog(shader)}
Shader source:
${shaderSource}`);
}
return shader;
}
deleteShader(shader) {
this.gl.deleteShader(shader);
}
bindTextureToUniform(texture, position, uniformHandle) {
const gl = this.gl;
gl.activeTexture(gl.TEXTURE0 + position);
this.checkError();
gl.bindTexture(gl.TEXTURE_2D, texture);
this.checkError();
gl.uniform1i(uniformHandle, position);
this.checkError();
}
draw() {
this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4);
this.checkError();
}
checkError() {
if (onnxruntime_common_1.env.debug) {
const gl = this.gl;
const error = gl.getError();
let label = '';
switch (error) {
case (gl.NO_ERROR):
return;
case (gl.INVALID_ENUM):
label = 'INVALID_ENUM';
break;
case (gl.INVALID_VALUE):
label = 'INVALID_VALUE';
break;
case (gl.INVALID_OPERATION):
label = 'INVALID_OPERATION';
break;
case (gl.INVALID_FRAMEBUFFER_OPERATION):
label = 'INVALID_FRAMEBUFFER_OPERATION';
break;
case (gl.OUT_OF_MEMORY):
label = 'OUT_OF_MEMORY';
break;
case (gl.CONTEXT_LOST_WEBGL):
label = 'CONTEXT_LOST_WEBGL';
break;
default:
label = `Unknown WebGL Error: ${error.toString(16)}`;
}
throw new Error(label);
}
}
deleteTexture(texture) {
this.gl.deleteTexture(texture);
}
deleteProgram(program) {
this.gl.deleteProgram(program);
}
getEncoder(dataType, channels, usage = 0 /* Encoder.Usage.Default */) {
if (this.version === 2) {
return new DataEncoders.RedFloat32DataEncoder(this.gl, channels);
}
switch (dataType) {
case 'float':
if (usage === 1 /* Encoder.Usage.UploadOnly */ || this.isRenderFloat32Supported) {
return new DataEncoders.RGBAFloatDataEncoder(this.gl, channels);
}
else {
return new DataEncoders.RGBAFloatDataEncoder(this.gl, channels, this.textureHalfFloatExtension.HALF_FLOAT_OES);
}
case 'int':
throw new Error('not implemented');
case 'byte':
return new DataEncoders.Uint8DataEncoder(this.gl, channels);
default:
throw new Error(`Invalid dataType: ${dataType}`);
}
}
clearActiveTextures() {
const gl = this.gl;
for (let unit = 0; unit < this.maxTextureImageUnits; ++unit) {
gl.activeTexture(gl.TEXTURE0 + unit);
gl.bindTexture(gl.TEXTURE_2D, null);
}
}
dispose() {
if (this.disposed) {
return;
}
const gl = this.gl;
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.deleteFramebuffer(this.framebuffer);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
gl.deleteBuffer(this.vertexbuffer);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
gl.finish();
this.disposed = true;
}
createDefaultGeometry() {
// Sets of x,y,z(=0),s,t coordinates.
return new Float32Array([
-1.0, 1.0, 0.0, 0.0, 1.0,
-1.0, -1.0, 0.0, 0.0, 0.0,
1.0, 1.0, 0.0, 1.0, 1.0,
1.0, -1.0, 0.0, 1.0, 0.0 // lower right
]);
}
createVertexbuffer() {
const gl = this.gl;
const buffer = gl.createBuffer();
if (!buffer) {
throw new Error('createBuffer() returned null');
}
const geometry = this.createDefaultGeometry();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, geometry, gl.STATIC_DRAW);
this.checkError();
return buffer;
}
createFramebuffer() {
const fb = this.gl.createFramebuffer();
if (!fb) {
throw new Error('createFramebuffer returned null');
}
return fb;
}
queryVitalParameters() {
const gl = this.gl;
this.isFloatTextureAttachableToFrameBuffer = this.checkFloatTextureAttachableToFrameBuffer();
this.isRenderFloat32Supported = this.checkRenderFloat32();
this.isFloat32DownloadSupported = this.checkFloat32Download();
if (this.version === 1 && !this.textureHalfFloatExtension && !this.isRenderFloat32Supported) {
throw new Error('both float32 and float16 TextureType are not supported');
}
this.isBlendSupported = !this.isRenderFloat32Supported || this.checkFloat32Blend();
// this.maxCombinedTextureImageUnits = gl.getParameter(gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS);
this.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);
this.maxTextureImageUnits = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS);
// this.maxCubeMapTextureSize = gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE);
// this.shadingLanguageVersion = gl.getParameter(gl.SHADING_LANGUAGE_VERSION);
// this.webglVendor = gl.getParameter(gl.VENDOR);
// this.webglVersion = gl.getParameter(gl.VERSION);
if (this.version === 2) {
// this.max3DTextureSize = gl.getParameter(WebGL2RenderingContext.MAX_3D_TEXTURE_SIZE);
// this.maxArrayTextureLayers = gl.getParameter(WebGL2RenderingContext.MAX_ARRAY_TEXTURE_LAYERS);
// this.maxColorAttachments = gl.getParameter(WebGL2RenderingContext.MAX_COLOR_ATTACHMENTS);
// this.maxDrawBuffers = gl.getParameter(WebGL2RenderingContext.MAX_DRAW_BUFFERS);
}
}
getExtensions() {
if (this.version === 2) {
this.colorBufferFloatExtension = this.gl.getExtension('EXT_color_buffer_float');
this.disjointTimerQueryWebgl2Extension = this.gl.getExtension('EXT_disjoint_timer_query_webgl2');
}
else {
this.textureFloatExtension = this.gl.getExtension('OES_texture_float');
this.textureHalfFloatExtension = this.gl.getExtension('OES_texture_half_float');
}
}
checkFloatTextureAttachableToFrameBuffer() {
// test whether Float32 texture is supported:
// STEP.1 create a float texture
const gl = this.gl;
const texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
// eslint-disable-next-line @typescript-eslint/naming-convention
const internalFormat = this.version === 2 ? gl.RGBA32F : gl.RGBA;
gl.texImage2D(gl.TEXTURE_2D, 0, internalFormat, 1, 1, 0, gl.RGBA, gl.FLOAT, null);
// STEP.2 bind a frame buffer
const frameBuffer = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);
// STEP.3 attach texture to framebuffer
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
// STEP.4 test whether framebuffer is complete
const isComplete = gl.checkFramebufferStatus(gl.FRAMEBUFFER) === gl.FRAMEBUFFER_COMPLETE;
gl.bindTexture(gl.TEXTURE_2D, null);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.deleteTexture(texture);
gl.deleteFramebuffer(frameBuffer);
return isComplete;
}
checkRenderFloat32() {
if (this.version === 2) {
if (!this.colorBufferFloatExtension) {
return false;
}
}
else {
if (!this.textureFloatExtension) {
return false;
}
}
return this.isFloatTextureAttachableToFrameBuffer;
}
checkFloat32Download() {
if (this.version === 2) {
if (!this.colorBufferFloatExtension) {
return false;
}
}
else {
if (!this.textureFloatExtension) {
return false;
}
if (!this.gl.getExtension('WEBGL_color_buffer_float')) {
return false;
}
}
return this.isFloatTextureAttachableToFrameBuffer;
}
/**
* Check whether GL_BLEND is supported
*/
checkFloat32Blend() {
// it looks like currently (2019-05-08) there is no easy way to detect whether BLEND is supported
// https://github.com/microsoft/onnxjs/issues/145
const gl = this.gl;
let texture;
let frameBuffer;
let vertexShader;
let fragmentShader;
let program;
try {
texture = gl.createTexture();
frameBuffer = gl.createFramebuffer();
gl.bindTexture(gl.TEXTURE_2D, texture);
// eslint-disable-next-line @typescript-eslint/naming-convention
const internalFormat = this.version === 2 ? gl.RGBA32F : gl.RGBA;
gl.texImage2D(gl.TEXTURE_2D, 0, internalFormat, 1, 1, 0, gl.RGBA, gl.FLOAT, null);
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
gl.enable(gl.BLEND);
vertexShader = gl.createShader(gl.VERTEX_SHADER);
if (!vertexShader) {
return false;
}
gl.shaderSource(vertexShader, 'void main(){}');
gl.compileShader(vertexShader);
fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
if (!fragmentShader) {
return false;
}
gl.shaderSource(fragmentShader, 'precision highp float;void main(){gl_FragColor=vec4(0.5);}');
gl.compileShader(fragmentShader);
program = gl.createProgram();
if (!program) {
return false;
}
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);
gl.drawArrays(gl.POINTS, 0, 1);
return gl.getError() === gl.NO_ERROR;
}
finally {
gl.disable(gl.BLEND);
if (program) {
gl.deleteProgram(program);
}
if (vertexShader) {
gl.deleteShader(vertexShader);
}
if (fragmentShader) {
gl.deleteShader(fragmentShader);
}
if (frameBuffer) {
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.deleteFramebuffer(frameBuffer);
}
if (texture) {
gl.bindTexture(gl.TEXTURE_2D, null);
gl.deleteTexture(texture);
}
}
}
beginTimer() {
if (this.version === 2 && this.disjointTimerQueryWebgl2Extension) {
const gl2 = this.gl;
const ext = this.disjointTimerQueryWebgl2Extension;
const query = gl2.createQuery();
gl2.beginQuery(ext.TIME_ELAPSED_EXT, query);
return query;
}
else {
// TODO: add webgl 1 handling.
throw new Error('WebGL1 profiling currently not supported.');
}
}
endTimer() {
if (this.version === 2 && this.disjointTimerQueryWebgl2Extension) {
const gl2 = this.gl;
const ext = this.disjointTimerQueryWebgl2Extension;
gl2.endQuery(ext.TIME_ELAPSED_EXT);
return;
}
else {
// TODO: add webgl 1 handling.
throw new Error('WebGL1 profiling currently not supported');
}
}
isTimerResultAvailable(query) {
let available = false, disjoint = false;
if (this.version === 2 && this.disjointTimerQueryWebgl2Extension) {
const gl2 = this.gl;
const ext = this.disjointTimerQueryWebgl2Extension;
available = gl2.getQueryParameter(query, gl2.QUERY_RESULT_AVAILABLE);
disjoint = gl2.getParameter(ext.GPU_DISJOINT_EXT);
}
else {
// TODO: add webgl 1 handling.
throw new Error('WebGL1 profiling currently not supported');
}
return available && !disjoint;
}
getTimerResult(query) {
let timeElapsed = 0;
if (this.version === 2) {
const gl2 = this.gl;
timeElapsed = gl2.getQueryParameter(query, gl2.QUERY_RESULT);
gl2.deleteQuery(query);
}
else {
// TODO: add webgl 1 handling.
throw new Error('WebGL1 profiling currently not supported');
}
// return miliseconds
return timeElapsed / 1000000;
}
async waitForQueryAndGetTime(query) {
await (0, utils_1.repeatedTry)(() => this.isTimerResultAvailable(query));
return this.getTimerResult(query);
}
async createAndWaitForFence() {
const fenceContext = this.createFence(this.gl);
return this.pollFence(fenceContext);
}
createFence(gl) {
let isFencePassed;
const gl2 = gl;
const query = gl2.fenceSync(gl2.SYNC_GPU_COMMANDS_COMPLETE, 0);
gl.flush();
if (query === null) {
isFencePassed = () => true;
}
else {
isFencePassed = () => {
const status = gl2.clientWaitSync(query, 0, 0);
return status === gl2.ALREADY_SIGNALED || status === gl2.CONDITION_SATISFIED;
};
}
return { query, isFencePassed };
}
async pollFence(fenceContext) {
return new Promise(resolve => {
void this.addItemToPoll(() => fenceContext.isFencePassed(), () => resolve());
});
}
pollItems() {
// Find the last query that has finished.
const index = linearSearchLastTrue(this.itemsToPoll.map(x => x.isDoneFn));
for (let i = 0; i <= index; ++i) {
const { resolveFn } = this.itemsToPoll[i];
resolveFn();
}
this.itemsToPoll = this.itemsToPoll.slice(index + 1);
}
async addItemToPoll(isDoneFn, resolveFn) {
this.itemsToPoll.push({ isDoneFn, resolveFn });
if (this.itemsToPoll.length > 1) {
// We already have a running loop that polls.
return;
}
// Start a new loop that polls.
await (0, utils_1.repeatedTry)(() => {
this.pollItems();
// End the loop if no more items to poll.
return this.itemsToPoll.length === 0;
});
}
}
exports.WebGLContext = WebGLContext;
/***/ }),
/***/ "./lib/onnxjs/execution-plan.ts":
/*!**************************************!*\
!*** ./lib/onnxjs/execution-plan.ts ***!
\**************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.ExecutionPlan = void 0;
const instrument_1 = __webpack_require__(/*! ./instrument */ "./lib/onnxjs/instrument.ts");
class KernelOp {
constructor(op, node) {
this.op = op;
this.node = node;
}
}
class ExecutionPlan {
constructor(graph, ops, profiler) {
this.graph = graph;
this.profiler = profiler;
this.initialize(ops);
}
initialize(ops) {
this.profiler.event('session', 'ExecutionPlan.initialize', () => {
const graphNodes = this.graph.getNodes();
if (graphNodes.length !== ops.length) {
throw new Error('The size of nodes and OPs do not match.');
}
this._ops = ops.map((op, i) => new KernelOp(op, graphNodes[i]));
this.reset();
// look for starter node(s)
this._starter = [];
this._ops.forEach((op, i) => {
let resolved = true;
for (const input of op.node.inputs) {
if (!this._values[input] // not an initialized input
&& this.graph.getInputIndices().indexOf(input) === -1 // not model input
) {
resolved = false;
break;
}
}
if (resolved) {
this._starter.push(i);
}
});
});
}
reset() {
this._values = this.graph.getValues().map(i => i.tensor);
}
async execute(sessionHandler, modelInputs) {
return this.profiler.event('session', 'ExecutionPlan.execute', async () => {
// reset mediem result
this.reset();
// create inference handler
const inferenceHandler = sessionHandler.createInferenceHandler();
// populate inputs value
const graphInputs = this.graph.getInputIndices();
if (modelInputs.length !== graphInputs.length) {
throw new Error(`number of input tensors don't match the number of inputs to the model: actual: ${modelInputs.length} expected: ${graphInputs.length}`);
}
modelInputs.forEach((input, i) => {
const index = graphInputs[i];
this._values[index] = input;
});
// prepare running sequence
const sequence = this._starter.slice(0);
// execution iterations
const graphValues = this.graph.getValues();
const graphNodes = this.graph.getNodes();
let rear = 0;
while (rear < sequence.length) {
const thisOpIndex = sequence[rear++];
const thisOp = this._ops[thisOpIndex];
// check input
const inputList = thisOp.node.inputs.map(i => this._values[i]);
if (inputList.indexOf(undefined) !== -1) {
throw new Error(`unresolved input detected: op: ${thisOp.node}`);
}
// run
const inputTensors = inputList;
instrument_1.Logger.verbose('ExecPlan', `Runing op:${thisOp.node.name} (${inputTensors.map((t, i) => `'${thisOp.node.inputs[i]}': ${t.type}[${t.dims.join(',')}]`).join(', ')})`);
const outputList = await this.profiler.event('node', thisOp.node.name, async () => thisOp.op.impl(inferenceHandler, inputTensors, thisOp.op.context));
// check output
if (outputList.length !== thisOp.node.outputs.length) {
throw new Error('the size of output does not match model definition.');
}
// fill value
outputList.forEach((output, i) => {
const j = thisOp.node.outputs[i];
if (this._values[j]) {
throw new Error(`output [${j}] already has value: op:${thisOp.node.name}`);
}
this._values[j] = output;
});
// resolve downstream nodes
const downstreamNodes = new Set();
outputList.forEach((output, i) => {
const j = thisOp.node.outputs[i];
for (const currentDownstreamNodeIndex of graphValues[j].to) {
const currentDownstreamNode = graphNodes[currentDownstreamNodeIndex];
let resolved = true;
for (const k of currentDownstreamNode.inputs) {
if (!this._values[k]) {
resolved = false;
break;
}
}
if (resolved) {
downstreamNodes.add(currentDownstreamNodeIndex);
}
}
});
sequence.push(...downstreamNodes);
}
const output = [];
for (let i = 0; i < this.graph.getOutputIndices().length; i++) {
const outputIndex = this.graph.getOutputIndices()[i];
const outputTensor = this._values[outputIndex];
if (outputTensor === undefined) {
throw new Error(`required output [${outputIndex}] does not have value`);
}
if (outputIndex === 0) {
await outputTensor.getData();
}
else {
// eslint-disable-next-line no-unused-expressions
outputTensor.data;
}
output.push(outputTensor);
}
instrument_1.Logger.verbose('ExecPlan', 'disposing of inferenceHandler');
inferenceHandler.dispose();
return output;
});
}
}
exports.ExecutionPlan = ExecutionPlan;
/***/ }),
/***/ "./lib/onnxjs/graph.ts":
/*!*****************************!*\
!*** ./lib/onnxjs/graph.ts ***!
\*****************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.Graph = void 0;
const onnx_proto_1 = __webpack_require__(/*! onnx-proto */ "./node_modules/onnx-proto/dist/onnx.js");
const attribute_1 = __webpack_require__(/*! ./attribute */ "./lib/onnxjs/attribute.ts");
const ort_generated_1 = __webpack_require__(/*! ./ort-schema/ort-generated */ "./lib/onnxjs/ort-schema/ort-generated.ts");
const tensor_1 = __webpack_require__(/*! ./tensor */ "./lib/onnxjs/tensor.ts");
const util_1 = __webpack_require__(/*! ./util */ "./lib/onnxjs/util.ts");
var ortFbs = ort_generated_1.onnxruntime.experimental.fbs;
// eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/no-redeclare
exports.Graph = {
/**
* construct a graph from a graph protobuf type
*/
from: (graphProto, initializer) => new GraphImpl(graphProto, initializer),
};
class Value {
constructor(valueInfo) {
this._from = undefined;
this._to = [];
this.tensor = undefined;
this.type = undefined;
if (valueInfo) {
this.type = util_1.ProtoUtil.tensorValueTypeFromProto(valueInfo.type.tensorType);
}
}
get from() {
return this._from;
}
get to() {
return this._to;
}
}
class Node {
constructor(_nodeProto, name) {
if (_nodeProto instanceof onnx_proto_1.onnx.NodeProto) {
this.name = _nodeProto.name;
this.opType = _nodeProto.opType;
this.attributes = new attribute_1.Attribute(_nodeProto.attribute);
}
else if (_nodeProto instanceof ortFbs.Node) {
this.name = name !== null && name !== void 0 ? name : _nodeProto.name();
this.opType = _nodeProto.opType();
this.attributes = new attribute_1.Attribute(util_1.ProtoUtil.tensorAttributesFromORTFormat(_nodeProto));
}
this.inputs = [];
this.outputs = [];
this.executeNode = true;
}
}
class GraphImpl {
constructor(graph, graphInitializer) {
if (!graph) {
throw new TypeError('graph is empty');
}
// build the graph - will throw exceptions if something fatal is detected
this.buildGraph(graph);
// execute any transformation logic for the graph (if applicable)
this.transformGraph(graphInitializer);
// check for cycles and other inconsistencies - will throw exceptions if something fatal is detected
this.checkIsAcyclic();
}
getInputIndices() {
return this._allInputIndices;
}
getInputNames() {
return this._allInputNames;
}
getOutputIndices() {
return this._allOutputIndices;
}
getOutputNames() {
return this._allOutputNames;
}
getValues() {
return this._allData;
}
getNodes() {
return this._nodes;
}
buildGraph(graph) {
// build the graph - will throw exceptions if something fatal is detected
if (graph instanceof onnx_proto_1.onnx.GraphProto) {
this.buildGraphFromOnnxFormat(graph);
}
else if (graph instanceof ortFbs.Graph) {
this.buildGraphFromOrtFormat(graph);
}
else {
throw new TypeError('Graph type is not supported.');
}
}
buildGraphFromOnnxFormat(graph) {
const dataIndices = new Map();
this._allData = [];
this._allInputIndices = [];
this._allInputNames = [];
this._allOutputIndices = [];
this._allOutputNames = [];
this._nodes = [];
const nodesIndices = new Map();
// scan all inputs
if (!graph.input) {
throw new Error('missing information in graph: input');
}
const inputValueNames = [];
for (const i of graph.input) {
if (dataIndices.has(i.name)) {
throw new Error(`duplicated input name: ${i.name}`);
}
const currentIndex = this._allData.push(new Value(i)) - 1;
dataIndices.set(i.name, currentIndex);
inputValueNames.push(i.name);
}
// scan all initializers
if (!graph.initializer) {
throw new Error('missing information in graph: initializer');
}
for (const i of graph.initializer) {
let index = dataIndices.get(i.name);
if (index === undefined) {
const value = new Value();
value.type = {
shape: { dims: util_1.ProtoUtil.tensorDimsFromProto(i.dims) },
tensorType: util_1.ProtoUtil.tensorDataTypeFromProto(i.dataType)
};
index = this._allData.push(value) - 1;
dataIndices.set(i.name, index);
}
this._allData[index]._from = -1;
this._allData[index].tensor = tensor_1.Tensor.fromProto(i);
}
// filter out input indices
for (let i = 0; i < this._allData.length; i++) {
if (!this._allData[i].tensor) {
this._allInputIndices.push(i);
this._allInputNames.push(inputValueNames[i]);
}
}
// scan all outputs
if (!graph.output) {
throw new Error('missing information in graph: output');
}
for (const i of graph.output) {
if (dataIndices.has(i.name)) {
throw new Error(`duplicated output name: ${i.name}`);
}
const currentIndex = this._allData.push(new Value(i)) - 1;
dataIndices.set(i.name, currentIndex);
this._allOutputIndices.push(currentIndex);
this._allOutputNames.push(i.name);
}
// scan all nodes
if (!graph.node) {
throw new Error('missing information in graph: node');
}
for (const nodeProto of graph.node) {
if (!nodeProto.name) {
// assign a name to the node if it doesn't have one
for (let pick = 0;; pick++) {
const name = `unnamed_${nodeProto.opType}_${pick}`;
if (!nodesIndices.has(name)) {
nodeProto.name = name;
break;
}
}
}
if (nodesIndices.has(nodeProto.name)) {
throw new Error(`duplicated node name: ${nodeProto.name}`);
}
const currentIndex = this._nodes.push(new Node(nodeProto)) - 1;
nodesIndices.set(nodeProto.name, currentIndex);
}
// scan node's outputs
for (let i = 0; i < this._nodes.length; i++) {
const node = this._nodes[i];
const nodeProto = graph.node[i];
if (!nodeProto.output) {
throw new Error(`missing output for node: ${nodeProto.name}`);
}
for (const output of nodeProto.output) {
let dataIndex = dataIndices.get(output);
if (typeof dataIndex === 'undefined') {
dataIndex = this._allData.push(new Value()) - 1;
dataIndices.set(output, dataIndex);
}
node.outputs.push(dataIndex);
if (this._allData[dataIndex]._from !== undefined) {
throw new Error(`multiple nodes output to one data value: ${dataIndex}`);
}
this._allData[dataIndex]._from = i;
// for the 'Constant' operator, just create a new edge in the graph corresponding to the 'output' of the
// operator and ignore the node from the graph
if (nodeProto.opType === 'Constant') {
if (!nodeProto.attribute || nodeProto.attribute.length !== 1 || !nodeProto.attribute[0].t) {
throw new Error('missing attributes or missing tensor value in attributes for this Constant operator');
}
if (!nodeProto.output || nodeProto.output.length !== 1) {
throw new Error('missing output or incorrect number of outputs for this Constant operator');
}
node.outputs.pop();
node.executeNode = false;
this._allData[dataIndex]._from = -1;
this._allData[dataIndex].tensor = tensor_1.Tensor.fromProto(nodeProto.attribute[0].t);
}
}
}
// scan node's inputs
for (let i = 0; i < this._nodes.length; i++) {
const node = this._nodes[i];
const nodeProto = graph.node[i];
if (!nodeProto.input) {
throw new Error(`missing input for node: ${nodeProto.name}`);
}
for (const input of nodeProto.input) {
const dataIndex = dataIndices.get(input);
if (typeof dataIndex === 'undefined') {
// handle exception when opset > 9 and roi not given
if (input === '' && nodeProto.input.length === 3 && nodeProto.opType === 'Resize') {
continue;
}
throw new Error(`unrecognized input '${input}' for node: ${nodeProto.name}`);
}
node.inputs.push(dataIndex);
this._allData[dataIndex]._to.push(i);
}
}
return true;
}
buildGraphFromOrtFormat(graph) {
var _a, _b, _c;
const dataIndices = new Map();
this._allData = [];
this._allInputIndices = [];
this._allInputNames = [];
this._allOutputIndices = [];
this._allOutputNames = [];
this._nodes = [];
const nodesIndices = new Map();
// scan all inputs
const inputValueNames = [];
for (let i = 0; i < graph.inputsLength(); i++) {
const inputName = graph.inputs(i);
if (dataIndices.has(inputName)) {
throw new Error(`duplicated input name: ${inputName}`);
}
// Find the input typeInfo from nodeargs
for (let j = 0; j < graph.nodeArgsLength(); j++) {
if (((_a = graph.nodeArgs(j)) === null || _a === void 0 ? void 0 : _a.name()) === inputName) {
const value = new Value();
const valueType = (_c = (_b = graph.nodeArgs(j)) === null || _b === void 0 ? void 0 : _b.type()) === null || _c === void 0 ? void 0 : _c.valueType();
if (valueType !== ortFbs.TypeInfoValue.tensor_type) {
throw new Error('Unexpected value type for the nodeArg.');
}
const valueInfo = graph.nodeArgs(j).type().value(new ortFbs.TensorTypeAndShape());
const type = util_1.ProtoUtil.tensorDataTypeFromProto(valueInfo.elemType());
const shape = valueInfo.shape();
const dims = [];
for (let k = 0; k < shape.dimLength(); k++) {
dims.push(util_1.LongUtil.longToNumber(shape.dim(k).value().dimValue()));
}
value.type = { shape: { dims }, tensorType: type };
const currentIndex = this._allData.push(value) - 1;
dataIndices.set(inputName, currentIndex);
inputValueNames.push(inputName);
}
}
}
// check initializers
for (let i = 0; i < graph.initializersLength(); i++) {
const initializer = graph.initializers(i);
let index = dataIndices.get(initializer.name());
if (index === undefined) {
const value = new Value();
const dims = util_1.ProtoUtil.tensorDimsFromORTFormat(initializer);
const type = util_1.ProtoUtil.tensorDataTypeFromProto(initializer.dataType());
value.type = { shape: { dims }, tensorType: type };
index = this._allData.push(value) - 1;
dataIndices.set(initializer.name(), index);
}
this._allData[index]._from = -1;
this._allData[index].tensor = tensor_1.Tensor.fromOrtTensor(initializer);
}
// filter out input indices
for (let i = 0; i < this._allData.length; i++) {
if (!this._allData[i].tensor) {
this._allInputIndices.push(i);
this._allInputNames.push(inputValueNames[i]);
}
}
// scan all outputs
for (let i = 0; i < graph.outputsLength(); i++) {
const outputName = graph.outputs(i);
if (dataIndices.has(outputName)) {
throw new Error(`duplicated output name: ${outputName}`);
}
const currentIndex = this._allData.push(new Value()) - 1;
dataIndices.set(outputName, currentIndex);
this._allOutputIndices.push(currentIndex);
this._allOutputNames.push(outputName);
}
// scan all nodes
if (!graph.nodes) {
throw new Error('missing information in graph: node');
}
for (let i = 0; i < graph.nodesLength(); i++) {
const nodeProto = graph.nodes(i);
let name = nodeProto.name();
if (!name) {
// assign a name to the node if it doesn't have one
for (let pick = 0;; pick++) {
name = `unnamed_${nodeProto.opType()}_${pick}`;
if (!nodesIndices.has(name)) {
// an unique name is found. break.
break;
}
}
}
if (nodesIndices.has(name)) {
throw new Error(`duplicated node name: ${name}`);
}
const currentIndex = this._nodes.push(new Node(nodeProto, name)) - 1;
nodesIndices.set(name, currentIndex);
}
// scan node's outputs
for (let i = 0; i < this._nodes.length; i++) {
const node = this._nodes[i];
const nodeProto = graph.nodes(i);
if (nodeProto == null) {
throw new Error(`No node exists at index ${i}`);
}
if ((nodeProto === null || nodeProto === void 0 ? void 0 : nodeProto.outputsLength()) === 0) {
throw new Error(`missing output for node: ${nodeProto.name}`);
}
for (let j = 0; j < (nodeProto === null || nodeProto === void 0 ? void 0 : nodeProto.outputsLength()); j++) {
const output = nodeProto === null || nodeProto === void 0 ? void 0 : nodeProto.outputs(j);
let dataIndex = dataIndices.get(output);
if (typeof dataIndex === 'undefined') {
dataIndex = this._allData.push(new Value()) - 1;
dataIndices.set(output, dataIndex);
}
node.outputs.push(dataIndex);
if (this._allData[dataIndex]._from !== undefined) {
throw new Error(`multiple nodes output to one data value: ${dataIndex}`);
}
this._allData[dataIndex]._from = i;
// for the 'Constant' operator, just create a new edge in the graph corresponding to the 'output' of the
// operator and ignore the node from the graph
if (nodeProto.opType() === 'Constant') {
if (nodeProto.attributesLength() !== 1 || !nodeProto.attributes(0).t()) {
throw new Error('missing attributes or missing tensor value in attributes for this Constant operator');
}
if (nodeProto.outputsLength() !== 1) {
throw new Error('missing output or incorrect number of outputs for this Constant operator');
}
node.outputs.pop();
node.executeNode = false;
this._allData[dataIndex]._from = -1;
this._allData[dataIndex].tensor = tensor_1.Tensor.fromOrtTensor(nodeProto.attributes(0).t());
}
}
}
// scan node's inputs
for (let i = 0; i < this._nodes.length; i++) {
const node = this._nodes[i];
const nodeProto = graph.nodes(i);
if (nodeProto.inputsLength() === 0) {
throw new Error(`missing input for node: ${nodeProto.name}`);
}
for (let j = 0; j < nodeProto.inputsLength(); j++) {
const input = nodeProto.inputs(j);
const dataIndex = dataIndices.get(input);
if (typeof dataIndex === 'undefined') {
throw new Error(`unrecognized input '${input}' for node: ${nodeProto.name()}`);
}
node.inputs.push(dataIndex);
this._allData[dataIndex]._to.push(i);
}
}
}
checkIsAcyclic() {
// go through the graph and check for cycles or other fatal inconsistencies
const starters = new Set();
this._allInputIndices.forEach(i => {
const data = this._allData[i];
data._to.forEach(j => {
starters.add(j);
});
});
// Iterative DFS to check for cycles
const nodesStack = Array.from(starters);
const nodesState = new Array(this._nodes.length).fill('white');
while (nodesStack.length > 0) {
const nodeIndex = nodesStack.pop();
// this node has now been processed completely. Mark this node 'black' to denote this.
if (nodesState[nodeIndex] === 'gray') {
nodesState[nodeIndex] = 'black';
}
else {
// this node is under processing stage. mark this node 'gray' to denote this.
nodesStack.push(nodeIndex);
nodesState[nodeIndex] = 'gray';
this._nodes[nodeIndex].outputs.forEach((outgoingEdgeIndex) => {
const data = this._allData[outgoingEdgeIndex];
if (typeof data.tensor !== 'undefined') {
throw new Error('node outputs should not be initialized');
}
if (data._from !== nodeIndex) {
throw new Error('from property of the Value object doesn\'t match index of Node being processed');
}
data._to.forEach((downstreamNodeIndex) => {
// back edge found - cyclic
if (nodesState[downstreamNodeIndex] === 'gray') {
throw new Error('model graph is cyclic');
}
// tree edge found - continue processing by adding it to stack
else if (nodesState[downstreamNodeIndex] === 'white') {
nodesStack.push(downstreamNodeIndex);
}
});
});
}
}
}
transformGraph(graphInitializer) {
// apply common transform
this.removeAllIdentityNodes();
this.removeAllDropoutNodes();
this.fuseConvActivationNodes();
// apply initializer specific transform
if (graphInitializer) {
graphInitializer.transformGraph(this);
}
// finalize graph
this.finalizeGraph();
}
/**
* finalize the graph.
*
* this function should be called after all the transformation completed.
* this function removes all unnecessary nodes and values from the graph
*/
finalizeGraph() {
let offset = 0;
// delete all nodes that are not being executed
for (let i = 0; i < this._nodes.length; i++) {
if (!this._nodes[i].executeNode) {
// delete this node and shift all subsequent nodes up
offset++;
// delete all output values
this._nodes[i].outputs.forEach(ind => {
this._allData[ind]._from = -2;
});
this._nodes.splice(i, 1);
i--;
continue;
}
if (offset > 0) {
// update the value table
this._nodes[i].inputs.forEach(value => {
const ind = this._allData[value]._to.indexOf(i + offset);
if (ind !== -1) {
this._allData[value]._to[ind] = i;
}
});
this._nodes[i].outputs.forEach(value => {
if (this._allData[value]._from && this._allData[value]._from === i + offset) {
this._allData[value]._from = i;
}
});
}
}
offset = 0;
// delete all values that are not being referenced
for (let i = 0; i < this._allData.length; i++) {
// if current value is neither linked to next node, nor an output value, remove it.
if (this._allData[i].from === -2 && this._allOutputIndices.indexOf(i + offset) === -1) {
offset++;
this._allData.splice(i, 1);
i--;
continue;
}
if (offset > 0) {
let ind = -1;
// if current value is neither an input value nor an initializer, find the node it's
// coming from and update the corresponding node output
if (this._allData[i].from !== undefined && this._allData[i].from !== -1) {
ind = this._nodes[this._allData[i].from].outputs.indexOf(i + offset);
if (ind !== -1) {
this._nodes[this._allData[i].from].outputs[ind] = i;
}
}
else {
// if current value is an input value, update its reference in inputIndices
ind = this._allInputIndices.indexOf(i + offset);
if (ind !== -1) {
this._allInputIndices[ind] = i;
}
}
// find the node that the current value is linking to and update its input reference
this._allData[i].to.forEach(node => {
ind = this._nodes[node].inputs.indexOf(i + offset);
if (ind !== -1) {
this._nodes[node].inputs[ind] = i;
}
});
if (this._allData[i].to.length === 0) {
// if current value is a graph output, update its reference in outputIndices
ind = this._allOutputIndices.indexOf(i + offset);
if (ind !== -1) {
this._allOutputIndices[ind] = i;
}
}
}
}
}
/**
* Delete the specifed node. Assume the node has one incoming input and the first output connected to other nodes.
* An input validation must be done before calling this function.
* @param nodeIndex The index of node to be deleted
*/
deleteNode(nodeIndex) {
const node = this._nodes[nodeIndex];
if (node.outputs.length > 1) {
for (let i = 1; i < node.outputs.length; i++) {
if (this._allData[node.outputs[i]].to.length > 0) {
throw new Error('Node deletion with more than one output connected to other nodes is not supported. ');
}
}
}
// this node wil not be executed
node.executeNode = false;
const inputValueIndex = node.inputs[0];
const outputValueIndex = node.outputs[0];
const nodesConsumingOutput = this._allData[outputValueIndex].to;
// remove this node from the to property of the input Value
const delIndex = this._allData[inputValueIndex].to.indexOf(nodeIndex);
// should not happen
if (delIndex === -1) {
throw new Error('The Value object doesn\'t have the current Node in it\'s \'to\' property ');
}
this._allData[inputValueIndex].to.splice(delIndex, 1);
// clear node indices consuming this output Value
this._allData[outputValueIndex]._to = [];
// if the output of this node is a graph output, adjust the index appropriately
const index = this._allOutputIndices.indexOf(outputValueIndex);
if (index !== -1) {
this._allOutputIndices[index] = inputValueIndex;
}
// override the inputs for nodes consuming this node's output with the input to this node
if (nodesConsumingOutput && nodesConsumingOutput.length > 0) {
for (const nodeIndex of nodesConsumingOutput) {
const replaceIndex = this._nodes[nodeIndex].inputs.indexOf(outputValueIndex);
// should not happen
if (replaceIndex === -1) {
throw new Error('The Node object doesn\'t have the output Value in it\'s \'inputs\' property ');
}
this._nodes[nodeIndex].inputs[replaceIndex] = inputValueIndex;
this._allData[inputValueIndex].to.push(nodeIndex);
}
}
}
removeAllDropoutNodes() {
let nodeIndex = 0;
for (const node of this._nodes) {
// weed out 'Dropout' nodes so that no time is wasted in execution
if (node.opType === 'Dropout') {
// the node should have exactly 1 input and 1 or 2 outputs
if (node.inputs.length !== 1) {
throw new Error('Dropout nodes should only contain one input. ');
}
if (node.outputs.length !== 1 && node.outputs.length !== 2) {
throw new Error('Dropout nodes should contain either 1 or 2 output(s)');
}
// the second output should not be referenced by any other node
if (node.outputs.length === 2 && this._allData[node.outputs[1]]._to.length !== 0) {
throw new Error('Dropout nodes\'s second output should not be referenced by other nodes');
}
this.deleteNode(nodeIndex);
}
nodeIndex++;
}
}
removeAllIdentityNodes() {
let nodeIndex = 0;
for (const node of this._nodes) {
// weed out 'Identity' nodes so that no time is wasted in execution
if (node.opType === 'Identity') {
this.deleteNode(nodeIndex);
}
nodeIndex++;
}
}
isActivation(n) {
switch (n.opType) {
// TODO: add other activation methods
case 'Relu':
case 'Sigmoid':
case 'Clip':
return true;
default:
return false;
}
}
fuseConvActivationNodes() {
for (const node of this._nodes) {
if (node.opType === 'Conv') {
const next = this._allData[node.outputs[0]]._to;
if (next.length === 1 && this.isActivation(this._nodes[next[0]])) {
const child = this._nodes[next[0]];
if (child.opType === 'Clip') {
if (child.inputs.length === 1) {
try {
node.attributes.set('activation_params', 'floats', [child.attributes.getFloat('min'), child.attributes.getFloat('max')]);
}
catch (e) {
node.attributes.set('activation_params', 'floats', [util_1.MIN_CLIP, util_1.MAX_CLIP]);
}
}
else if (child.inputs.length >= 3 && this._allData[child.inputs[1]].tensor !== undefined &&
this._allData[child.inputs[2]].tensor !== undefined) {
node.attributes.set('activation_params', 'floats', [
this._allData[child.inputs[1]].tensor.floatData[0], this._allData[child.inputs[2]].tensor.floatData[0]
]);
}
else {
// Skip fusion with clip node since clip min and clip max are not coming from initializer
continue;
}
}
node.attributes.set('activation', 'string', (child.opType));
this.deleteNode(next[0]);
}
}
}
}
}
/***/ }),
/***/ "./lib/onnxjs/instrument.ts":
/*!**********************************!*\
!*** ./lib/onnxjs/instrument.ts ***!
\**********************************/
/***/ ((__unused_webpack_module, exports) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.now = exports.Profiler = exports.Logger = void 0;
class NoOpLoggerProvider {
log(_severity, _content, _category) {
// do nothing
}
}
class ConsoleLoggerProvider {
log(severity, content, category) {
// eslint-disable-next-line no-console
console.log(`${this.color(severity)} ${category ? '\x1b[35m' + category + '\x1b[0m ' : ''}${content}`);
}
color(severity) {
switch (severity) {
case 'verbose':
return '\x1b[34;40mv\x1b[0m';
case 'info':
return '\x1b[32mi\x1b[0m';
case 'warning':
return '\x1b[30;43mw\x1b[0m';
case 'error':
return '\x1b[31;40me\x1b[0m';
case 'fatal':
return '\x1b[101mf\x1b[0m';
default:
throw new Error(`unsupported severity: ${severity}`);
}
}
}
const SEVERITY_VALUE = {
verbose: 1000,
info: 2000,
warning: 4000,
error: 5000,
fatal: 6000
};
const LOGGER_PROVIDER_MAP = {
['none']: new NoOpLoggerProvider(),
['console']: new ConsoleLoggerProvider()
};
const LOGGER_DEFAULT_CONFIG = {
provider: 'console',
minimalSeverity: 'warning',
logDateTime: true,
logSourceLocation: false
};
let LOGGER_CONFIG_MAP = { ['']: LOGGER_DEFAULT_CONFIG };
function log(arg0, arg1, arg2, arg3) {
if (arg1 === undefined) {
// log(category: string): Logger.CategorizedLogger;
return createCategorizedLogger(arg0);
}
else if (arg2 === undefined) {
// log(severity, content);
logInternal(arg0, arg1, 1);
}
else if (typeof arg2 === 'number' && arg3 === undefined) {
// log(severity, content, stack)
logInternal(arg0, arg1, arg2);
}
else if (typeof arg2 === 'string' && arg3 === undefined) {
// log(severity, category, content)
logInternal(arg0, arg2, 1, arg1);
}
else if (typeof arg2 === 'string' && typeof arg3 === 'number') {
// log(severity, category, content, stack)
logInternal(arg0, arg2, arg3, arg1);
}
else {
throw new TypeError('input is valid');
}
}
function createCategorizedLogger(category) {
return {
verbose: log.verbose.bind(null, category),
info: log.info.bind(null, category),
warning: log.warning.bind(null, category),
error: log.error.bind(null, category),
fatal: log.fatal.bind(null, category)
};
}
// NOTE: argument 'category' is put the last parameter beacause typescript
// doesn't allow optional argument put in front of required argument. This
// order is different from a usual logging API.
function logInternal(severity, content, stack, category) {
const config = LOGGER_CONFIG_MAP[category || ''] || LOGGER_CONFIG_MAP[''];
if (SEVERITY_VALUE[severity] < SEVERITY_VALUE[config.minimalSeverity]) {
return;
}
if (config.logDateTime) {
content = `${new Date().toISOString()}|${content}`;
}
if (config.logSourceLocation) {
// TODO: calculate source location from 'stack'
}
LOGGER_PROVIDER_MAP[config.provider].log(severity, content, category);
}
// eslint-disable-next-line @typescript-eslint/no-namespace
(function (log) {
function verbose(arg0, arg1) {
log('verbose', arg0, arg1);
}
log.verbose = verbose;
function info(arg0, arg1) {
log('info', arg0, arg1);
}
log.info = info;
function warning(arg0, arg1) {
log('warning', arg0, arg1);
}
log.warning = warning;
function error(arg0, arg1) {
log('error', arg0, arg1);
}
log.error = error;
function fatal(arg0, arg1) {
log('fatal', arg0, arg1);
}
log.fatal = fatal;
function reset(config) {
LOGGER_CONFIG_MAP = {};
set('', config || {});
}
log.reset = reset;
function set(category, config) {
if (category === '*') {
reset(config);
}
else {
const previousConfig = LOGGER_CONFIG_MAP[category] || LOGGER_DEFAULT_CONFIG;
LOGGER_CONFIG_MAP[category] = {
provider: config.provider || previousConfig.provider,
minimalSeverity: config.minimalSeverity || previousConfig.minimalSeverity,
logDateTime: (config.logDateTime === undefined) ? previousConfig.logDateTime : config.logDateTime,
logSourceLocation: (config.logSourceLocation === undefined) ? previousConfig.logSourceLocation :
config.logSourceLocation
};
}
// TODO: we want to support wildcard or regex?
}
log.set = set;
function setWithEnv(env) {
const config = {};
if (env.logLevel) {
config.minimalSeverity = env.logLevel;
}
set('', config);
}
log.setWithEnv = setWithEnv;
})(log || (log = {}));
// eslint-disable-next-line @typescript-eslint/no-redeclare, @typescript-eslint/naming-convention
exports.Logger = log;
// TODO
// class WebGLEvent implements Profiler.Event {}
class Event {
constructor(category, name, startTime, endCallback, timer, ctx) {
this.category = category;
this.name = name;
this.startTime = startTime;
this.endCallback = endCallback;
this.timer = timer;
this.ctx = ctx;
}
end() {
return this.endCallback(this);
}
async checkTimer() {
if (this.ctx === undefined || this.timer === undefined) {
throw new Error('No webgl timer found');
}
else {
this.ctx.endTimer();
return this.ctx.waitForQueryAndGetTime(this.timer);
}
}
}
class EventRecord {
constructor(category, name, startTime, endTime) {
this.category = category;
this.name = name;
this.startTime = startTime;
this.endTime = endTime;
}
}
class Profiler {
static create(config) {
if (config === undefined) {
return new this();
}
return new this(config.maxNumberEvents, config.flushBatchSize, config.flushIntervalInMilliseconds);
}
constructor(maxNumberEvents, flushBatchSize, flushIntervalInMilliseconds) {
this._started = false;
this._flushPointer = 0;
this._started = false;
this._maxNumberEvents = maxNumberEvents === undefined ? 10000 : maxNumberEvents;
this._flushBatchSize = flushBatchSize === undefined ? 10 : flushBatchSize;
this._flushIntervalInMilliseconds = flushIntervalInMilliseconds === undefined ? 5000 : flushIntervalInMilliseconds;
}
// start profiling
start() {
this._started = true;
this._timingEvents = [];
this._flushTime = (0, exports.now)();
this._flushPointer = 0;
}
// stop profiling
stop() {
this._started = false;
for (; this._flushPointer < this._timingEvents.length; this._flushPointer++) {
this.logOneEvent(this._timingEvents[this._flushPointer]);
}
}
event(category, name, func, ctx) {
const event = this._started ? this.begin(category, name, ctx) : undefined;
let isPromise = false;
const res = func();
// we consider a then-able object is a promise
if (res && typeof res.then === 'function') {
isPromise = true;
return new Promise((resolve, reject) => {
res
.then(async (value) => {
if (event) {
await event.end();
}
resolve(value);
}, async (reason) => {
if (event) {
await event.end();
}
reject(reason);
});
});
}
if (!isPromise && event) {
const eventRes = event.end();
if (eventRes && typeof eventRes.then === 'function') {
return new Promise((resolve, reject) => {
(eventRes).then(() => {
resolve(res);
}, (reason) => {
reject(reason);
});
});
}
}
return res;
}
// begin an event
begin(category, name, ctx) {
if (!this._started) {
throw new Error('profiler is not started yet');
}
if (ctx === undefined) {
const startTime = (0, exports.now)();
this.flush(startTime);
return new Event(category, name, startTime, e => this.endSync(e));
}
else {
const timer = ctx.beginTimer();
return new Event(category, name, 0, async (e) => this.end(e), timer, ctx);
}
}
// end the specific event
async end(event) {
const endTime = await event.checkTimer();
if (this._timingEvents.length < this._maxNumberEvents) {
this._timingEvents.push(new EventRecord(event.category, event.name, event.startTime, endTime));
this.flush(endTime);
}
}
endSync(event) {
const endTime = (0, exports.now)();
if (this._timingEvents.length < this._maxNumberEvents) {
this._timingEvents.push(new EventRecord(event.category, event.name, event.startTime, endTime));
this.flush(endTime);
}
}
logOneEvent(event) {
exports.Logger.verbose(`Profiler.${event.category}`, `${(event.endTime - event.startTime).toFixed(2)}ms on event '${event.name}' at ${event.endTime.toFixed(2)}`);
}
flush(currentTime) {
if (this._timingEvents.length - this._flushPointer >= this._flushBatchSize ||
currentTime - this._flushTime >= this._flushIntervalInMilliseconds) {
// should flush when either batch size accumlated or interval elepsed
for (const previousPointer = this._flushPointer; this._flushPointer < previousPointer + this._flushBatchSize &&
this._flushPointer < this._timingEvents.length; this._flushPointer++) {
this.logOneEvent(this._timingEvents[this._flushPointer]);
}
this._flushTime = (0, exports.now)();
}
}
get started() {
return this._started;
}
}
exports.Profiler = Profiler;
/**
* returns a number to represent the current timestamp in a resolution as high as possible.
*/
exports.now = (typeof performance !== 'undefined' && performance.now) ? () => performance.now() : Date.now;
/***/ }),
/***/ "./lib/onnxjs/model.ts":
/*!*****************************!*\
!*** ./lib/onnxjs/model.ts ***!
\*****************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.Model = void 0;
const flatbuffers_1 = __webpack_require__(/*! flatbuffers */ "./node_modules/flatbuffers/js/flatbuffers.mjs");
const onnx_proto_1 = __webpack_require__(/*! onnx-proto */ "./node_modules/onnx-proto/dist/onnx.js");
const graph_1 = __webpack_require__(/*! ./graph */ "./lib/onnxjs/graph.ts");
const ort_generated_1 = __webpack_require__(/*! ./ort-schema/ort-generated */ "./lib/onnxjs/ort-schema/ort-generated.ts");
const util_1 = __webpack_require__(/*! ./util */ "./lib/onnxjs/util.ts");
var ortFbs = ort_generated_1.onnxruntime.experimental.fbs;
class Model {
// empty model
constructor() { }
load(buf, graphInitializer, isOrtFormat) {
if (!isOrtFormat) {
// isOrtFormat === false || isOrtFormat === undefined
try {
this.loadFromOnnxFormat(buf, graphInitializer);
return;
}
catch (e) {
if (isOrtFormat !== undefined) {
throw e;
}
}
}
this.loadFromOrtFormat(buf, graphInitializer);
}
loadFromOnnxFormat(buf, graphInitializer) {
const modelProto = onnx_proto_1.onnx.ModelProto.decode(buf);
const irVersion = util_1.LongUtil.longToNumber(modelProto.irVersion);
if (irVersion < 3) {
throw new Error('only support ONNX model with IR_VERSION>=3');
}
this._opsets =
modelProto.opsetImport.map(i => ({ domain: i.domain, version: util_1.LongUtil.longToNumber(i.version) }));
this._graph = graph_1.Graph.from(modelProto.graph, graphInitializer);
}
loadFromOrtFormat(buf, graphInitializer) {
const fb = new flatbuffers_1.flatbuffers.ByteBuffer(buf);
const ortModel = ortFbs.InferenceSession.getRootAsInferenceSession(fb).model();
const irVersion = util_1.LongUtil.longToNumber(ortModel.irVersion());
if (irVersion < 3) {
throw new Error('only support ONNX model with IR_VERSION>=3');
}
this._opsets = [];
for (let i = 0; i < ortModel.opsetImportLength(); i++) {
const opsetId = ortModel.opsetImport(i);
this._opsets.push({ domain: opsetId === null || opsetId === void 0 ? void 0 : opsetId.domain(), version: util_1.LongUtil.longToNumber(opsetId.version()) });
}
this._graph = graph_1.Graph.from(ortModel.graph(), graphInitializer);
}
get graph() {
return this._graph;
}
get opsets() {
return this._opsets;
}
}
exports.Model = Model;
/***/ }),
/***/ "./lib/onnxjs/operators.ts":
/*!*********************************!*\
!*** ./lib/onnxjs/operators.ts ***!
\*********************************/
/***/ ((__unused_webpack_module, exports) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.FLOAT_TYPES = exports.INT_TYPES = exports.NUMBER_TYPES = void 0;
exports.NUMBER_TYPES = ['float32', 'float64', 'int32', 'int16', 'int8', 'uint16', 'uint32', 'uint8'];
exports.INT_TYPES = ['int32', 'int16', 'int8', 'uint16', 'uint32', 'uint8'];
exports.FLOAT_TYPES = ['float32', 'float64'];
/***/ }),
/***/ "./lib/onnxjs/opset.ts":
/*!*****************************!*\
!*** ./lib/onnxjs/opset.ts ***!
\*****************************/
/***/ ((__unused_webpack_module, exports) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.resolveOperator = void 0;
function resolveOperator(node, opsets, rules) {
for (const rule of rules) {
const opType = rule[0];
const domain = rule[1];
const versionSelector = rule[2];
const opImpl = rule[3];
const opInit = rule[4];
if (node.opType === opType) { // operator type matches
for (const opset of opsets) {
// opset '' and 'ai.onnx' are considered the same.
if (opset.domain === domain || (opset.domain === 'ai.onnx' && domain === '')) { // opset domain found
if (matchSelector(opset.version, versionSelector)) {
return { opImpl, opInit };
}
}
}
}
}
throw new TypeError(`cannot resolve operator '${node.opType}' with opsets: ${opsets.map(set => `${set.domain || 'ai.onnx'} v${set.version}`).join(', ')}`);
}
exports.resolveOperator = resolveOperator;
function matchSelector(version, selector) {
if (selector.endsWith('+')) {
// minimum version match ('7+' expects version>=7)
const rangeStart = Number.parseInt(selector.substring(0, selector.length - 1), 10);
return !isNaN(rangeStart) && rangeStart <= version;
}
else if (selector.split('-').length === 2) {
// range match ('6-8' expects 6<=version<=8)
const pair = selector.split('-');
const rangeStart = Number.parseInt(pair[0], 10);
const rangeEnd = Number.parseInt(pair[1], 10);
return !isNaN(rangeStart) && !isNaN(rangeEnd) && rangeStart <= version && version <= rangeEnd;
}
else {
// exact match ('7' expects version===7)
return Number.parseInt(selector, 10) === version;
}
}
/***/ }),
/***/ "./lib/onnxjs/ort-schema/ort-generated.ts":
/*!************************************************!*\
!*** ./lib/onnxjs/ort-schema/ort-generated.ts ***!
\************************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// automatically generated by the FlatBuffers compiler, do not modify
/* eslint-disable */
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.onnxruntime = void 0;
const flatbuffers_1 = __webpack_require__(/*! flatbuffers */ "./node_modules/flatbuffers/js/flatbuffers.mjs");
/**
* @enum {number}
*/
var onnxruntime;
(function (onnxruntime) {
var experimental;
(function (experimental) {
var fbs;
(function (fbs) {
let AttributeType;
(function (AttributeType) {
AttributeType[AttributeType["UNDEFINED"] = 0] = "UNDEFINED";
AttributeType[AttributeType["FLOAT"] = 1] = "FLOAT";
AttributeType[AttributeType["INT"] = 2] = "INT";
AttributeType[AttributeType["STRING"] = 3] = "STRING";
AttributeType[AttributeType["TENSOR"] = 4] = "TENSOR";
AttributeType[AttributeType["GRAPH"] = 5] = "GRAPH";
AttributeType[AttributeType["FLOATS"] = 6] = "FLOATS";
AttributeType[AttributeType["INTS"] = 7] = "INTS";
AttributeType[AttributeType["STRINGS"] = 8] = "STRINGS";
AttributeType[AttributeType["TENSORS"] = 9] = "TENSORS";
AttributeType[AttributeType["GRAPHS"] = 10] = "GRAPHS";
AttributeType[AttributeType["SPARSE_TENSOR"] = 11] = "SPARSE_TENSOR";
AttributeType[AttributeType["SPARSE_TENSORS"] = 12] = "SPARSE_TENSORS";
})(AttributeType = fbs.AttributeType || (fbs.AttributeType = {}));
})(fbs = experimental.fbs || (experimental.fbs = {}));
})(experimental = onnxruntime.experimental || (onnxruntime.experimental = {}));
})(onnxruntime = exports.onnxruntime || (exports.onnxruntime = {}));
/**
* @enum {number}
*/
(function (onnxruntime) {
var experimental;
(function (experimental) {
var fbs;
(function (fbs) {
let DimensionValueType;
(function (DimensionValueType) {
DimensionValueType[DimensionValueType["UNKNOWN"] = 0] = "UNKNOWN";
DimensionValueType[DimensionValueType["VALUE"] = 1] = "VALUE";
DimensionValueType[DimensionValueType["PARAM"] = 2] = "PARAM";
})(DimensionValueType = fbs.DimensionValueType || (fbs.DimensionValueType = {}));
})(fbs = experimental.fbs || (experimental.fbs = {}));
})(experimental = onnxruntime.experimental || (onnxruntime.experimental = {}));
})(onnxruntime = exports.onnxruntime || (exports.onnxruntime = {}));
/**
* @enum {number}
*/
(function (onnxruntime) {
var experimental;
(function (experimental) {
var fbs;
(function (fbs) {
let TensorDataType;
(function (TensorDataType) {
TensorDataType[TensorDataType["UNDEFINED"] = 0] = "UNDEFINED";
TensorDataType[TensorDataType["FLOAT"] = 1] = "FLOAT";
TensorDataType[TensorDataType["UINT8"] = 2] = "UINT8";
TensorDataType[TensorDataType["INT8"] = 3] = "INT8";
TensorDataType[TensorDataType["UINT16"] = 4] = "UINT16";
TensorDataType[TensorDataType["INT16"] = 5] = "INT16";
TensorDataType[TensorDataType["INT32"] = 6] = "INT32";
TensorDataType[TensorDataType["INT64"] = 7] = "INT64";
TensorDataType[TensorDataType["STRING"] = 8] = "STRING";
TensorDataType[TensorDataType["BOOL"] = 9] = "BOOL";
TensorDataType[TensorDataType["FLOAT16"] = 10] = "FLOAT16";
TensorDataType[TensorDataType["DOUBLE"] = 11] = "DOUBLE";
TensorDataType[TensorDataType["UINT32"] = 12] = "UINT32";
TensorDataType[TensorDataType["UINT64"] = 13] = "UINT64";
TensorDataType[TensorDataType["COMPLEX64"] = 14] = "COMPLEX64";
TensorDataType[TensorDataType["COMPLEX128"] = 15] = "COMPLEX128";
TensorDataType[TensorDataType["BFLOAT16"] = 16] = "BFLOAT16";
})(TensorDataType = fbs.TensorDataType || (fbs.TensorDataType = {}));
})(fbs = experimental.fbs || (experimental.fbs = {}));
})(experimental = onnxruntime.experimental || (onnxruntime.experimental = {}));
})(onnxruntime = exports.onnxruntime || (exports.onnxruntime = {}));
/**
* @enum {number}
*/
(function (onnxruntime) {
var experimental;
(function (experimental) {
var fbs;
(function (fbs) {
let NodeType;
(function (NodeType) {
NodeType[NodeType["Primitive"] = 0] = "Primitive";
NodeType[NodeType["Fused"] = 1] = "Fused";
})(NodeType = fbs.NodeType || (fbs.NodeType = {}));
})(fbs = experimental.fbs || (experimental.fbs = {}));
})(experimental = onnxruntime.experimental || (onnxruntime.experimental = {}));
})(onnxruntime = exports.onnxruntime || (exports.onnxruntime = {}));
/**
* @enum {number}
*/
(function (onnxruntime) {
var experimental;
(function (experimental) {
var fbs;
(function (fbs) {
let TypeInfoValue;
(function (TypeInfoValue) {
TypeInfoValue[TypeInfoValue["NONE"] = 0] = "NONE";
TypeInfoValue[TypeInfoValue["tensor_type"] = 1] = "tensor_type";
TypeInfoValue[TypeInfoValue["sequence_type"] = 2] = "sequence_type";
TypeInfoValue[TypeInfoValue["map_type"] = 3] = "map_type";
})(TypeInfoValue = fbs.TypeInfoValue || (fbs.TypeInfoValue = {}));
})(fbs = experimental.fbs || (experimental.fbs = {}));
})(experimental = onnxruntime.experimental || (onnxruntime.experimental = {}));
})(onnxruntime = exports.onnxruntime || (exports.onnxruntime = {}));
/**
* @constructor
*/
(function (onnxruntime) {
var experimental;
(function (experimental) {
var fbs;
(function (fbs) {
class Shape {
constructor() {
this.bb = null;
this.bb_pos = 0;
}
/**
* @param number i
* @param flatbuffers.ByteBuffer bb
* @returns Shape
*/
__init(i, bb) {
this.bb_pos = i;
this.bb = bb;
return this;
}
/**
* @param flatbuffers.ByteBuffer bb
* @param Shape= obj
* @returns Shape
*/
static getRootAsShape(bb, obj) {
return (obj || new Shape()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
/**
* @param flatbuffers.ByteBuffer bb
* @param Shape= obj
* @returns Shape
*/
static getSizePrefixedRootAsShape(bb, obj) {
bb.setPosition(bb.position() + flatbuffers_1.flatbuffers.SIZE_PREFIX_LENGTH);
return (obj || new Shape()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
/**
* @param number index
* @param onnxruntime.experimental.fbs.Dimension= obj
* @returns onnxruntime.experimental.fbs.Dimension
*/
dim(index, obj) {
let offset = this.bb.__offset(this.bb_pos, 4);
return offset ? (obj || new onnxruntime.experimental.fbs.Dimension())
.__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) :
null;
}
/**
* @returns number
*/
dimLength() {
let offset = this.bb.__offset(this.bb_pos, 4);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
}
/**
* @param flatbuffers.Builder builder
*/
static startShape(builder) {
builder.startObject(1);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset dimOffset
*/
static addDim(builder, dimOffset) {
builder.addFieldOffset(0, dimOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param Array.<flatbuffers.Offset> data
* @returns flatbuffers.Offset
*/
static createDimVector(builder, data) {
builder.startVector(4, data.length, 4);
for (let i = data.length - 1; i >= 0; i--) {
builder.addOffset(data[i]);
}
return builder.endVector();
}
/**
* @param flatbuffers.Builder builder
* @param number numElems
*/
static startDimVector(builder, numElems) {
builder.startVector(4, numElems, 4);
}
/**
* @param flatbuffers.Builder builder
* @returns flatbuffers.Offset
*/
static endShape(builder) {
let offset = builder.endObject();
return offset;
}
static createShape(builder, dimOffset) {
Shape.startShape(builder);
Shape.addDim(builder, dimOffset);
return Shape.endShape(builder);
}
}
fbs.Shape = Shape;
})(fbs = experimental.fbs || (experimental.fbs = {}));
})(experimental = onnxruntime.experimental || (onnxruntime.experimental = {}));
})(onnxruntime = exports.onnxruntime || (exports.onnxruntime = {}));
/**
* @constructor
*/
(function (onnxruntime) {
var experimental;
(function (experimental) {
var fbs;
(function (fbs) {
class Dimension {
constructor() {
this.bb = null;
this.bb_pos = 0;
}
/**
* @param number i
* @param flatbuffers.ByteBuffer bb
* @returns Dimension
*/
__init(i, bb) {
this.bb_pos = i;
this.bb = bb;
return this;
}
/**
* @param flatbuffers.ByteBuffer bb
* @param Dimension= obj
* @returns Dimension
*/
static getRootAsDimension(bb, obj) {
return (obj || new Dimension()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
/**
* @param flatbuffers.ByteBuffer bb
* @param Dimension= obj
* @returns Dimension
*/
static getSizePrefixedRootAsDimension(bb, obj) {
bb.setPosition(bb.position() + flatbuffers_1.flatbuffers.SIZE_PREFIX_LENGTH);
return (obj || new Dimension()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
/**
* @param onnxruntime.experimental.fbs.DimensionValue= obj
* @returns onnxruntime.experimental.fbs.DimensionValue|null
*/
value(obj) {
let offset = this.bb.__offset(this.bb_pos, 4);
return offset ? (obj || new onnxruntime.experimental.fbs.DimensionValue())
.__init(this.bb.__indirect(this.bb_pos + offset), this.bb) :
null;
}
denotation(optionalEncoding) {
let offset = this.bb.__offset(this.bb_pos, 6);
return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null;
}
/**
* @param flatbuffers.Builder builder
*/
static startDimension(builder) {
builder.startObject(2);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset valueOffset
*/
static addValue(builder, valueOffset) {
builder.addFieldOffset(0, valueOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset denotationOffset
*/
static addDenotation(builder, denotationOffset) {
builder.addFieldOffset(1, denotationOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @returns flatbuffers.Offset
*/
static endDimension(builder) {
let offset = builder.endObject();
return offset;
}
static createDimension(builder, valueOffset, denotationOffset) {
Dimension.startDimension(builder);
Dimension.addValue(builder, valueOffset);
Dimension.addDenotation(builder, denotationOffset);
return Dimension.endDimension(builder);
}
}
fbs.Dimension = Dimension;
})(fbs = experimental.fbs || (experimental.fbs = {}));
})(experimental = onnxruntime.experimental || (onnxruntime.experimental = {}));
})(onnxruntime = exports.onnxruntime || (exports.onnxruntime = {}));
/**
* @constructor
*/
(function (onnxruntime) {
var experimental;
(function (experimental) {
var fbs;
(function (fbs) {
class DimensionValue {
constructor() {
this.bb = null;
this.bb_pos = 0;
}
/**
* @param number i
* @param flatbuffers.ByteBuffer bb
* @returns DimensionValue
*/
__init(i, bb) {
this.bb_pos = i;
this.bb = bb;
return this;
}
/**
* @param flatbuffers.ByteBuffer bb
* @param DimensionValue= obj
* @returns DimensionValue
*/
static getRootAsDimensionValue(bb, obj) {
return (obj || new DimensionValue()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
/**
* @param flatbuffers.ByteBuffer bb
* @param DimensionValue= obj
* @returns DimensionValue
*/
static getSizePrefixedRootAsDimensionValue(bb, obj) {
bb.setPosition(bb.position() + flatbuffers_1.flatbuffers.SIZE_PREFIX_LENGTH);
return (obj || new DimensionValue()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
/**
* @returns onnxruntime.experimental.fbs.DimensionValueType
*/
dimType() {
let offset = this.bb.__offset(this.bb_pos, 4);
return offset ? /** */ (this.bb.readInt8(this.bb_pos + offset)) :
onnxruntime.experimental.fbs.DimensionValueType.UNKNOWN;
}
/**
* @returns flatbuffers.Long
*/
dimValue() {
let offset = this.bb.__offset(this.bb_pos, 6);
return offset ? this.bb.readInt64(this.bb_pos + offset) : this.bb.createLong(0, 0);
}
dimParam(optionalEncoding) {
let offset = this.bb.__offset(this.bb_pos, 8);
return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null;
}
/**
* @param flatbuffers.Builder builder
*/
static startDimensionValue(builder) {
builder.startObject(3);
}
/**
* @param flatbuffers.Builder builder
* @param onnxruntime.experimental.fbs.DimensionValueType dimType
*/
static addDimType(builder, dimType) {
builder.addFieldInt8(0, dimType, onnxruntime.experimental.fbs.DimensionValueType.UNKNOWN);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Long dimValue
*/
static addDimValue(builder, dimValue) {
builder.addFieldInt64(1, dimValue, builder.createLong(0, 0));
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset dimParamOffset
*/
static addDimParam(builder, dimParamOffset) {
builder.addFieldOffset(2, dimParamOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @returns flatbuffers.Offset
*/
static endDimensionValue(builder) {
let offset = builder.endObject();
return offset;
}
static createDimensionValue(builder, dimType, dimValue, dimParamOffset) {
DimensionValue.startDimensionValue(builder);
DimensionValue.addDimType(builder, dimType);
DimensionValue.addDimValue(builder, dimValue);
DimensionValue.addDimParam(builder, dimParamOffset);
return DimensionValue.endDimensionValue(builder);
}
}
fbs.DimensionValue = DimensionValue;
})(fbs = experimental.fbs || (experimental.fbs = {}));
})(experimental = onnxruntime.experimental || (onnxruntime.experimental = {}));
})(onnxruntime = exports.onnxruntime || (exports.onnxruntime = {}));
/**
* @constructor
*/
(function (onnxruntime) {
var experimental;
(function (experimental) {
var fbs;
(function (fbs) {
class TensorTypeAndShape {
constructor() {
this.bb = null;
this.bb_pos = 0;
}
/**
* @param number i
* @param flatbuffers.ByteBuffer bb
* @returns TensorTypeAndShape
*/
__init(i, bb) {
this.bb_pos = i;
this.bb = bb;
return this;
}
/**
* @param flatbuffers.ByteBuffer bb
* @param TensorTypeAndShape= obj
* @returns TensorTypeAndShape
*/
static getRootAsTensorTypeAndShape(bb, obj) {
return (obj || new TensorTypeAndShape()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
/**
* @param flatbuffers.ByteBuffer bb
* @param TensorTypeAndShape= obj
* @returns TensorTypeAndShape
*/
static getSizePrefixedRootAsTensorTypeAndShape(bb, obj) {
bb.setPosition(bb.position() + flatbuffers_1.flatbuffers.SIZE_PREFIX_LENGTH);
return (obj || new TensorTypeAndShape()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
/**
* @returns onnxruntime.experimental.fbs.TensorDataType
*/
elemType() {
let offset = this.bb.__offset(this.bb_pos, 4);
return offset ? /** */ (this.bb.readInt32(this.bb_pos + offset)) :
onnxruntime.experimental.fbs.TensorDataType.UNDEFINED;
}
/**
* @param onnxruntime.experimental.fbs.Shape= obj
* @returns onnxruntime.experimental.fbs.Shape|null
*/
shape(obj) {
let offset = this.bb.__offset(this.bb_pos, 6);
return offset ? (obj || new onnxruntime.experimental.fbs.Shape())
.__init(this.bb.__indirect(this.bb_pos + offset), this.bb) :
null;
}
/**
* @param flatbuffers.Builder builder
*/
static startTensorTypeAndShape(builder) {
builder.startObject(2);
}
/**
* @param flatbuffers.Builder builder
* @param onnxruntime.experimental.fbs.TensorDataType elemType
*/
static addElemType(builder, elemType) {
builder.addFieldInt32(0, elemType, onnxruntime.experimental.fbs.TensorDataType.UNDEFINED);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset shapeOffset
*/
static addShape(builder, shapeOffset) {
builder.addFieldOffset(1, shapeOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @returns flatbuffers.Offset
*/
static endTensorTypeAndShape(builder) {
let offset = builder.endObject();
return offset;
}
static createTensorTypeAndShape(builder, elemType, shapeOffset) {
TensorTypeAndShape.startTensorTypeAndShape(builder);
TensorTypeAndShape.addElemType(builder, elemType);
TensorTypeAndShape.addShape(builder, shapeOffset);
return TensorTypeAndShape.endTensorTypeAndShape(builder);
}
}
fbs.TensorTypeAndShape = TensorTypeAndShape;
})(fbs = experimental.fbs || (experimental.fbs = {}));
})(experimental = onnxruntime.experimental || (onnxruntime.experimental = {}));
})(onnxruntime = exports.onnxruntime || (exports.onnxruntime = {}));
/**
* @constructor
*/
(function (onnxruntime) {
var experimental;
(function (experimental) {
var fbs;
(function (fbs) {
class MapType {
constructor() {
this.bb = null;
this.bb_pos = 0;
}
/**
* @param number i
* @param flatbuffers.ByteBuffer bb
* @returns MapType
*/
__init(i, bb) {
this.bb_pos = i;
this.bb = bb;
return this;
}
/**
* @param flatbuffers.ByteBuffer bb
* @param MapType= obj
* @returns MapType
*/
static getRootAsMapType(bb, obj) {
return (obj || new MapType()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
/**
* @param flatbuffers.ByteBuffer bb
* @param MapType= obj
* @returns MapType
*/
static getSizePrefixedRootAsMapType(bb, obj) {
bb.setPosition(bb.position() + flatbuffers_1.flatbuffers.SIZE_PREFIX_LENGTH);
return (obj || new MapType()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
/**
* @returns onnxruntime.experimental.fbs.TensorDataType
*/
keyType() {
let offset = this.bb.__offset(this.bb_pos, 4);
return offset ? /** */ (this.bb.readInt32(this.bb_pos + offset)) :
onnxruntime.experimental.fbs.TensorDataType.UNDEFINED;
}
/**
* @param onnxruntime.experimental.fbs.TypeInfo= obj
* @returns onnxruntime.experimental.fbs.TypeInfo|null
*/
valueType(obj) {
let offset = this.bb.__offset(this.bb_pos, 6);
return offset ? (obj || new onnxruntime.experimental.fbs.TypeInfo())
.__init(this.bb.__indirect(this.bb_pos + offset), this.bb) :
null;
}
/**
* @param flatbuffers.Builder builder
*/
static startMapType(builder) {
builder.startObject(2);
}
/**
* @param flatbuffers.Builder builder
* @param onnxruntime.experimental.fbs.TensorDataType keyType
*/
static addKeyType(builder, keyType) {
builder.addFieldInt32(0, keyType, onnxruntime.experimental.fbs.TensorDataType.UNDEFINED);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset valueTypeOffset
*/
static addValueType(builder, valueTypeOffset) {
builder.addFieldOffset(1, valueTypeOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @returns flatbuffers.Offset
*/
static endMapType(builder) {
let offset = builder.endObject();
return offset;
}
static createMapType(builder, keyType, valueTypeOffset) {
MapType.startMapType(builder);
MapType.addKeyType(builder, keyType);
MapType.addValueType(builder, valueTypeOffset);
return MapType.endMapType(builder);
}
}
fbs.MapType = MapType;
})(fbs = experimental.fbs || (experimental.fbs = {}));
})(experimental = onnxruntime.experimental || (onnxruntime.experimental = {}));
})(onnxruntime = exports.onnxruntime || (exports.onnxruntime = {}));
/**
* @constructor
*/
(function (onnxruntime) {
var experimental;
(function (experimental) {
var fbs;
(function (fbs) {
class SequenceType {
constructor() {
this.bb = null;
this.bb_pos = 0;
}
/**
* @param number i
* @param flatbuffers.ByteBuffer bb
* @returns SequenceType
*/
__init(i, bb) {
this.bb_pos = i;
this.bb = bb;
return this;
}
/**
* @param flatbuffers.ByteBuffer bb
* @param SequenceType= obj
* @returns SequenceType
*/
static getRootAsSequenceType(bb, obj) {
return (obj || new SequenceType()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
/**
* @param flatbuffers.ByteBuffer bb
* @param SequenceType= obj
* @returns SequenceType
*/
static getSizePrefixedRootAsSequenceType(bb, obj) {
bb.setPosition(bb.position() + flatbuffers_1.flatbuffers.SIZE_PREFIX_LENGTH);
return (obj || new SequenceType()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
/**
* @param onnxruntime.experimental.fbs.TypeInfo= obj
* @returns onnxruntime.experimental.fbs.TypeInfo|null
*/
elemType(obj) {
let offset = this.bb.__offset(this.bb_pos, 4);
return offset ? (obj || new onnxruntime.experimental.fbs.TypeInfo())
.__init(this.bb.__indirect(this.bb_pos + offset), this.bb) :
null;
}
/**
* @param flatbuffers.Builder builder
*/
static startSequenceType(builder) {
builder.startObject(1);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset elemTypeOffset
*/
static addElemType(builder, elemTypeOffset) {
builder.addFieldOffset(0, elemTypeOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @returns flatbuffers.Offset
*/
static endSequenceType(builder) {
let offset = builder.endObject();
return offset;
}
static createSequenceType(builder, elemTypeOffset) {
SequenceType.startSequenceType(builder);
SequenceType.addElemType(builder, elemTypeOffset);
return SequenceType.endSequenceType(builder);
}
}
fbs.SequenceType = SequenceType;
})(fbs = experimental.fbs || (experimental.fbs = {}));
})(experimental = onnxruntime.experimental || (onnxruntime.experimental = {}));
})(onnxruntime = exports.onnxruntime || (exports.onnxruntime = {}));
/**
* @constructor
*/
(function (onnxruntime) {
var experimental;
(function (experimental) {
var fbs;
(function (fbs) {
class EdgeEnd {
constructor() {
this.bb = null;
this.bb_pos = 0;
}
/**
* @param number i
* @param flatbuffers.ByteBuffer bb
* @returns EdgeEnd
*/
__init(i, bb) {
this.bb_pos = i;
this.bb = bb;
return this;
}
/**
* @returns number
*/
nodeIndex() {
return this.bb.readUint32(this.bb_pos);
}
/**
* @returns number
*/
srcArgIndex() {
return this.bb.readInt32(this.bb_pos + 4);
}
/**
* @returns number
*/
dstArgIndex() {
return this.bb.readInt32(this.bb_pos + 8);
}
/**
* @param flatbuffers.Builder builder
* @param number node_index
* @param number src_arg_index
* @param number dst_arg_index
* @returns flatbuffers.Offset
*/
static createEdgeEnd(builder, node_index, src_arg_index, dst_arg_index) {
builder.prep(4, 12);
builder.writeInt32(dst_arg_index);
builder.writeInt32(src_arg_index);
builder.writeInt32(node_index);
return builder.offset();
}
}
fbs.EdgeEnd = EdgeEnd;
})(fbs = experimental.fbs || (experimental.fbs = {}));
})(experimental = onnxruntime.experimental || (onnxruntime.experimental = {}));
})(onnxruntime = exports.onnxruntime || (exports.onnxruntime = {}));
/**
* @constructor
*/
(function (onnxruntime) {
var experimental;
(function (experimental) {
var fbs;
(function (fbs) {
class NodeEdge {
constructor() {
this.bb = null;
this.bb_pos = 0;
}
/**
* @param number i
* @param flatbuffers.ByteBuffer bb
* @returns NodeEdge
*/
__init(i, bb) {
this.bb_pos = i;
this.bb = bb;
return this;
}
/**
* @param flatbuffers.ByteBuffer bb
* @param NodeEdge= obj
* @returns NodeEdge
*/
static getRootAsNodeEdge(bb, obj) {
return (obj || new NodeEdge()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
/**
* @param flatbuffers.ByteBuffer bb
* @param NodeEdge= obj
* @returns NodeEdge
*/
static getSizePrefixedRootAsNodeEdge(bb, obj) {
bb.setPosition(bb.position() + flatbuffers_1.flatbuffers.SIZE_PREFIX_LENGTH);
return (obj || new NodeEdge()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
/**
* @returns number
*/
nodeIndex() {
let offset = this.bb.__offset(this.bb_pos, 4);
return offset ? this.bb.readUint32(this.bb_pos + offset) : 0;
}
/**
* @param number index
* @param onnxruntime.experimental.fbs.EdgeEnd= obj
* @returns onnxruntime.experimental.fbs.EdgeEnd
*/
inputEdges(index, obj) {
let offset = this.bb.__offset(this.bb_pos, 6);
return offset ? (obj || new onnxruntime.experimental.fbs.EdgeEnd())
.__init(this.bb.__vector(this.bb_pos + offset) + index * 12, this.bb) :
null;
}
/**
* @returns number
*/
inputEdgesLength() {
let offset = this.bb.__offset(this.bb_pos, 6);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
}
/**
* @param number index
* @param onnxruntime.experimental.fbs.EdgeEnd= obj
* @returns onnxruntime.experimental.fbs.EdgeEnd
*/
outputEdges(index, obj) {
let offset = this.bb.__offset(this.bb_pos, 8);
return offset ? (obj || new onnxruntime.experimental.fbs.EdgeEnd())
.__init(this.bb.__vector(this.bb_pos + offset) + index * 12, this.bb) :
null;
}
/**
* @returns number
*/
outputEdgesLength() {
let offset = this.bb.__offset(this.bb_pos, 8);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
}
/**
* @param flatbuffers.Builder builder
*/
static startNodeEdge(builder) {
builder.startObject(3);
}
/**
* @param flatbuffers.Builder builder
* @param number nodeIndex
*/
static addNodeIndex(builder, nodeIndex) {
builder.addFieldInt32(0, nodeIndex, 0);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset inputEdgesOffset
*/
static addInputEdges(builder, inputEdgesOffset) {
builder.addFieldOffset(1, inputEdgesOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param number numElems
*/
static startInputEdgesVector(builder, numElems) {
builder.startVector(12, numElems, 4);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset outputEdgesOffset
*/
static addOutputEdges(builder, outputEdgesOffset) {
builder.addFieldOffset(2, outputEdgesOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param number numElems
*/
static startOutputEdgesVector(builder, numElems) {
builder.startVector(12, numElems, 4);
}
/**
* @param flatbuffers.Builder builder
* @returns flatbuffers.Offset
*/
static endNodeEdge(builder) {
let offset = builder.endObject();
return offset;
}
static createNodeEdge(builder, nodeIndex, inputEdgesOffset, outputEdgesOffset) {
NodeEdge.startNodeEdge(builder);
NodeEdge.addNodeIndex(builder, nodeIndex);
NodeEdge.addInputEdges(builder, inputEdgesOffset);
NodeEdge.addOutputEdges(builder, outputEdgesOffset);
return NodeEdge.endNodeEdge(builder);
}
}
fbs.NodeEdge = NodeEdge;
})(fbs = experimental.fbs || (experimental.fbs = {}));
})(experimental = onnxruntime.experimental || (onnxruntime.experimental = {}));
})(onnxruntime = exports.onnxruntime || (exports.onnxruntime = {}));
/**
* @constructor
*/
(function (onnxruntime) {
var experimental;
(function (experimental) {
var fbs;
(function (fbs) {
class Node {
constructor() {
this.bb = null;
this.bb_pos = 0;
}
/**
* @param number i
* @param flatbuffers.ByteBuffer bb
* @returns Node
*/
__init(i, bb) {
this.bb_pos = i;
this.bb = bb;
return this;
}
/**
* @param flatbuffers.ByteBuffer bb
* @param Node= obj
* @returns Node
*/
static getRootAsNode(bb, obj) {
return (obj || new Node()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
/**
* @param flatbuffers.ByteBuffer bb
* @param Node= obj
* @returns Node
*/
static getSizePrefixedRootAsNode(bb, obj) {
bb.setPosition(bb.position() + flatbuffers_1.flatbuffers.SIZE_PREFIX_LENGTH);
return (obj || new Node()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
name(optionalEncoding) {
let offset = this.bb.__offset(this.bb_pos, 4);
return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null;
}
docString(optionalEncoding) {
let offset = this.bb.__offset(this.bb_pos, 6);
return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null;
}
domain(optionalEncoding) {
let offset = this.bb.__offset(this.bb_pos, 8);
return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null;
}
/**
* @returns number
*/
sinceVersion() {
let offset = this.bb.__offset(this.bb_pos, 10);
return offset ? this.bb.readInt32(this.bb_pos + offset) : 0;
}
/**
* @returns number
*/
index() {
let offset = this.bb.__offset(this.bb_pos, 12);
return offset ? this.bb.readUint32(this.bb_pos + offset) : 0;
}
opType(optionalEncoding) {
let offset = this.bb.__offset(this.bb_pos, 14);
return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null;
}
/**
* @returns onnxruntime.experimental.fbs.NodeType
*/
type() {
let offset = this.bb.__offset(this.bb_pos, 16);
return offset ? /** */ (this.bb.readInt32(this.bb_pos + offset)) :
onnxruntime.experimental.fbs.NodeType.Primitive;
}
executionProviderType(optionalEncoding) {
let offset = this.bb.__offset(this.bb_pos, 18);
return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null;
}
inputs(index, optionalEncoding) {
let offset = this.bb.__offset(this.bb_pos, 20);
return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null;
}
/**
* @returns number
*/
inputsLength() {
let offset = this.bb.__offset(this.bb_pos, 20);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
}
outputs(index, optionalEncoding) {
let offset = this.bb.__offset(this.bb_pos, 22);
return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null;
}
/**
* @returns number
*/
outputsLength() {
let offset = this.bb.__offset(this.bb_pos, 22);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
}
/**
* @param number index
* @param onnxruntime.experimental.fbs.Attribute= obj
* @returns onnxruntime.experimental.fbs.Attribute
*/
attributes(index, obj) {
let offset = this.bb.__offset(this.bb_pos, 24);
return offset ? (obj || new onnxruntime.experimental.fbs.Attribute())
.__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) :
null;
}
/**
* @returns number
*/
attributesLength() {
let offset = this.bb.__offset(this.bb_pos, 24);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
}
/**
* @param number index
* @returns number
*/
inputArgCounts(index) {
let offset = this.bb.__offset(this.bb_pos, 26);
return offset ? this.bb.readInt32(this.bb.__vector(this.bb_pos + offset) + index * 4) : 0;
}
/**
* @returns number
*/
inputArgCountsLength() {
let offset = this.bb.__offset(this.bb_pos, 26);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
}
/**
* @returns Int32Array
*/
inputArgCountsArray() {
let offset = this.bb.__offset(this.bb_pos, 26);
return offset ?
new Int32Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) :
null;
}
implicitInputs(index, optionalEncoding) {
let offset = this.bb.__offset(this.bb_pos, 28);
return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null;
}
/**
* @returns number
*/
implicitInputsLength() {
let offset = this.bb.__offset(this.bb_pos, 28);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
}
/**
* @param flatbuffers.Builder builder
*/
static startNode(builder) {
builder.startObject(13);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset nameOffset
*/
static addName(builder, nameOffset) {
builder.addFieldOffset(0, nameOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset docStringOffset
*/
static addDocString(builder, docStringOffset) {
builder.addFieldOffset(1, docStringOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset domainOffset
*/
static addDomain(builder, domainOffset) {
builder.addFieldOffset(2, domainOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param number sinceVersion
*/
static addSinceVersion(builder, sinceVersion) {
builder.addFieldInt32(3, sinceVersion, 0);
}
/**
* @param flatbuffers.Builder builder
* @param number index
*/
static addIndex(builder, index) {
builder.addFieldInt32(4, index, 0);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset opTypeOffset
*/
static addOpType(builder, opTypeOffset) {
builder.addFieldOffset(5, opTypeOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param onnxruntime.experimental.fbs.NodeType type
*/
static addType(builder, type) {
builder.addFieldInt32(6, type, onnxruntime.experimental.fbs.NodeType.Primitive);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset executionProviderTypeOffset
*/
static addExecutionProviderType(builder, executionProviderTypeOffset) {
builder.addFieldOffset(7, executionProviderTypeOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset inputsOffset
*/
static addInputs(builder, inputsOffset) {
builder.addFieldOffset(8, inputsOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param Array.<flatbuffers.Offset> data
* @returns flatbuffers.Offset
*/
static createInputsVector(builder, data) {
builder.startVector(4, data.length, 4);
for (let i = data.length - 1; i >= 0; i--) {
builder.addOffset(data[i]);
}
return builder.endVector();
}
/**
* @param flatbuffers.Builder builder
* @param number numElems
*/
static startInputsVector(builder, numElems) {
builder.startVector(4, numElems, 4);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset outputsOffset
*/
static addOutputs(builder, outputsOffset) {
builder.addFieldOffset(9, outputsOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param Array.<flatbuffers.Offset> data
* @returns flatbuffers.Offset
*/
static createOutputsVector(builder, data) {
builder.startVector(4, data.length, 4);
for (let i = data.length - 1; i >= 0; i--) {
builder.addOffset(data[i]);
}
return builder.endVector();
}
/**
* @param flatbuffers.Builder builder
* @param number numElems
*/
static startOutputsVector(builder, numElems) {
builder.startVector(4, numElems, 4);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset attributesOffset
*/
static addAttributes(builder, attributesOffset) {
builder.addFieldOffset(10, attributesOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param Array.<flatbuffers.Offset> data
* @returns flatbuffers.Offset
*/
static createAttributesVector(builder, data) {
builder.startVector(4, data.length, 4);
for (let i = data.length - 1; i >= 0; i--) {
builder.addOffset(data[i]);
}
return builder.endVector();
}
/**
* @param flatbuffers.Builder builder
* @param number numElems
*/
static startAttributesVector(builder, numElems) {
builder.startVector(4, numElems, 4);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset inputArgCountsOffset
*/
static addInputArgCounts(builder, inputArgCountsOffset) {
builder.addFieldOffset(11, inputArgCountsOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param Array.<number> data
* @returns flatbuffers.Offset
*/
static createInputArgCountsVector(builder, data) {
builder.startVector(4, data.length, 4);
for (let i = data.length - 1; i >= 0; i--) {
builder.addInt32(data[i]);
}
return builder.endVector();
}
/**
* @param flatbuffers.Builder builder
* @param number numElems
*/
static startInputArgCountsVector(builder, numElems) {
builder.startVector(4, numElems, 4);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset implicitInputsOffset
*/
static addImplicitInputs(builder, implicitInputsOffset) {
builder.addFieldOffset(12, implicitInputsOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param Array.<flatbuffers.Offset> data
* @returns flatbuffers.Offset
*/
static createImplicitInputsVector(builder, data) {
builder.startVector(4, data.length, 4);
for (let i = data.length - 1; i >= 0; i--) {
builder.addOffset(data[i]);
}
return builder.endVector();
}
/**
* @param flatbuffers.Builder builder
* @param number numElems
*/
static startImplicitInputsVector(builder, numElems) {
builder.startVector(4, numElems, 4);
}
/**
* @param flatbuffers.Builder builder
* @returns flatbuffers.Offset
*/
static endNode(builder) {
let offset = builder.endObject();
return offset;
}
static createNode(builder, nameOffset, docStringOffset, domainOffset, sinceVersion, index, opTypeOffset, type, executionProviderTypeOffset, inputsOffset, outputsOffset, attributesOffset, inputArgCountsOffset, implicitInputsOffset) {
Node.startNode(builder);
Node.addName(builder, nameOffset);
Node.addDocString(builder, docStringOffset);
Node.addDomain(builder, domainOffset);
Node.addSinceVersion(builder, sinceVersion);
Node.addIndex(builder, index);
Node.addOpType(builder, opTypeOffset);
Node.addType(builder, type);
Node.addExecutionProviderType(builder, executionProviderTypeOffset);
Node.addInputs(builder, inputsOffset);
Node.addOutputs(builder, outputsOffset);
Node.addAttributes(builder, attributesOffset);
Node.addInputArgCounts(builder, inputArgCountsOffset);
Node.addImplicitInputs(builder, implicitInputsOffset);
return Node.endNode(builder);
}
}
fbs.Node = Node;
})(fbs = experimental.fbs || (experimental.fbs = {}));
})(experimental = onnxruntime.experimental || (onnxruntime.experimental = {}));
})(onnxruntime = exports.onnxruntime || (exports.onnxruntime = {}));
/**
* @constructor
*/
(function (onnxruntime) {
var experimental;
(function (experimental) {
var fbs;
(function (fbs) {
class ValueInfo {
constructor() {
this.bb = null;
this.bb_pos = 0;
}
/**
* @param number i
* @param flatbuffers.ByteBuffer bb
* @returns ValueInfo
*/
__init(i, bb) {
this.bb_pos = i;
this.bb = bb;
return this;
}
/**
* @param flatbuffers.ByteBuffer bb
* @param ValueInfo= obj
* @returns ValueInfo
*/
static getRootAsValueInfo(bb, obj) {
return (obj || new ValueInfo()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
/**
* @param flatbuffers.ByteBuffer bb
* @param ValueInfo= obj
* @returns ValueInfo
*/
static getSizePrefixedRootAsValueInfo(bb, obj) {
bb.setPosition(bb.position() + flatbuffers_1.flatbuffers.SIZE_PREFIX_LENGTH);
return (obj || new ValueInfo()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
name(optionalEncoding) {
let offset = this.bb.__offset(this.bb_pos, 4);
return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null;
}
docString(optionalEncoding) {
let offset = this.bb.__offset(this.bb_pos, 6);
return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null;
}
/**
* @param onnxruntime.experimental.fbs.TypeInfo= obj
* @returns onnxruntime.experimental.fbs.TypeInfo|null
*/
type(obj) {
let offset = this.bb.__offset(this.bb_pos, 8);
return offset ? (obj || new onnxruntime.experimental.fbs.TypeInfo())
.__init(this.bb.__indirect(this.bb_pos + offset), this.bb) :
null;
}
/**
* @param flatbuffers.Builder builder
*/
static startValueInfo(builder) {
builder.startObject(3);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset nameOffset
*/
static addName(builder, nameOffset) {
builder.addFieldOffset(0, nameOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset docStringOffset
*/
static addDocString(builder, docStringOffset) {
builder.addFieldOffset(1, docStringOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset typeOffset
*/
static addType(builder, typeOffset) {
builder.addFieldOffset(2, typeOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @returns flatbuffers.Offset
*/
static endValueInfo(builder) {
let offset = builder.endObject();
return offset;
}
static createValueInfo(builder, nameOffset, docStringOffset, typeOffset) {
ValueInfo.startValueInfo(builder);
ValueInfo.addName(builder, nameOffset);
ValueInfo.addDocString(builder, docStringOffset);
ValueInfo.addType(builder, typeOffset);
return ValueInfo.endValueInfo(builder);
}
}
fbs.ValueInfo = ValueInfo;
})(fbs = experimental.fbs || (experimental.fbs = {}));
})(experimental = onnxruntime.experimental || (onnxruntime.experimental = {}));
})(onnxruntime = exports.onnxruntime || (exports.onnxruntime = {}));
/**
* @constructor
*/
(function (onnxruntime) {
var experimental;
(function (experimental) {
var fbs;
(function (fbs) {
class TypeInfo {
constructor() {
this.bb = null;
this.bb_pos = 0;
}
/**
* @param number i
* @param flatbuffers.ByteBuffer bb
* @returns TypeInfo
*/
__init(i, bb) {
this.bb_pos = i;
this.bb = bb;
return this;
}
/**
* @param flatbuffers.ByteBuffer bb
* @param TypeInfo= obj
* @returns TypeInfo
*/
static getRootAsTypeInfo(bb, obj) {
return (obj || new TypeInfo()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
/**
* @param flatbuffers.ByteBuffer bb
* @param TypeInfo= obj
* @returns TypeInfo
*/
static getSizePrefixedRootAsTypeInfo(bb, obj) {
bb.setPosition(bb.position() + flatbuffers_1.flatbuffers.SIZE_PREFIX_LENGTH);
return (obj || new TypeInfo()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
denotation(optionalEncoding) {
let offset = this.bb.__offset(this.bb_pos, 4);
return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null;
}
/**
* @returns onnxruntime.experimental.fbs.TypeInfoValue
*/
valueType() {
let offset = this.bb.__offset(this.bb_pos, 6);
return offset ? /** */ (this.bb.readUint8(this.bb_pos + offset)) :
onnxruntime.experimental.fbs.TypeInfoValue.NONE;
}
/**
* @param flatbuffers.Table obj
* @returns ?flatbuffers.Table
*/
value(obj) {
let offset = this.bb.__offset(this.bb_pos, 8);
return offset ? this.bb.__union(obj, this.bb_pos + offset) : null;
}
/**
* @param flatbuffers.Builder builder
*/
static startTypeInfo(builder) {
builder.startObject(3);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset denotationOffset
*/
static addDenotation(builder, denotationOffset) {
builder.addFieldOffset(0, denotationOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param onnxruntime.experimental.fbs.TypeInfoValue valueType
*/
static addValueType(builder, valueType) {
builder.addFieldInt8(1, valueType, onnxruntime.experimental.fbs.TypeInfoValue.NONE);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset valueOffset
*/
static addValue(builder, valueOffset) {
builder.addFieldOffset(2, valueOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @returns flatbuffers.Offset
*/
static endTypeInfo(builder) {
let offset = builder.endObject();
return offset;
}
static createTypeInfo(builder, denotationOffset, valueType, valueOffset) {
TypeInfo.startTypeInfo(builder);
TypeInfo.addDenotation(builder, denotationOffset);
TypeInfo.addValueType(builder, valueType);
TypeInfo.addValue(builder, valueOffset);
return TypeInfo.endTypeInfo(builder);
}
}
fbs.TypeInfo = TypeInfo;
})(fbs = experimental.fbs || (experimental.fbs = {}));
})(experimental = onnxruntime.experimental || (onnxruntime.experimental = {}));
})(onnxruntime = exports.onnxruntime || (exports.onnxruntime = {}));
/**
* @constructor
*/
(function (onnxruntime) {
var experimental;
(function (experimental) {
var fbs;
(function (fbs) {
class OperatorSetId {
constructor() {
this.bb = null;
this.bb_pos = 0;
}
/**
* @param number i
* @param flatbuffers.ByteBuffer bb
* @returns OperatorSetId
*/
__init(i, bb) {
this.bb_pos = i;
this.bb = bb;
return this;
}
/**
* @param flatbuffers.ByteBuffer bb
* @param OperatorSetId= obj
* @returns OperatorSetId
*/
static getRootAsOperatorSetId(bb, obj) {
return (obj || new OperatorSetId()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
/**
* @param flatbuffers.ByteBuffer bb
* @param OperatorSetId= obj
* @returns OperatorSetId
*/
static getSizePrefixedRootAsOperatorSetId(bb, obj) {
bb.setPosition(bb.position() + flatbuffers_1.flatbuffers.SIZE_PREFIX_LENGTH);
return (obj || new OperatorSetId()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
domain(optionalEncoding) {
let offset = this.bb.__offset(this.bb_pos, 4);
return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null;
}
/**
* @returns flatbuffers.Long
*/
version() {
let offset = this.bb.__offset(this.bb_pos, 6);
return offset ? this.bb.readInt64(this.bb_pos + offset) : this.bb.createLong(0, 0);
}
/**
* @param flatbuffers.Builder builder
*/
static startOperatorSetId(builder) {
builder.startObject(2);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset domainOffset
*/
static addDomain(builder, domainOffset) {
builder.addFieldOffset(0, domainOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Long version
*/
static addVersion(builder, version) {
builder.addFieldInt64(1, version, builder.createLong(0, 0));
}
/**
* @param flatbuffers.Builder builder
* @returns flatbuffers.Offset
*/
static endOperatorSetId(builder) {
let offset = builder.endObject();
return offset;
}
static createOperatorSetId(builder, domainOffset, version) {
OperatorSetId.startOperatorSetId(builder);
OperatorSetId.addDomain(builder, domainOffset);
OperatorSetId.addVersion(builder, version);
return OperatorSetId.endOperatorSetId(builder);
}
}
fbs.OperatorSetId = OperatorSetId;
})(fbs = experimental.fbs || (experimental.fbs = {}));
})(experimental = onnxruntime.experimental || (onnxruntime.experimental = {}));
})(onnxruntime = exports.onnxruntime || (exports.onnxruntime = {}));
/**
* @constructor
*/
(function (onnxruntime) {
var experimental;
(function (experimental) {
var fbs;
(function (fbs) {
class Tensor {
constructor() {
this.bb = null;
this.bb_pos = 0;
}
/**
* @param number i
* @param flatbuffers.ByteBuffer bb
* @returns Tensor
*/
__init(i, bb) {
this.bb_pos = i;
this.bb = bb;
return this;
}
/**
* @param flatbuffers.ByteBuffer bb
* @param Tensor= obj
* @returns Tensor
*/
static getRootAsTensor(bb, obj) {
return (obj || new Tensor()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
/**
* @param flatbuffers.ByteBuffer bb
* @param Tensor= obj
* @returns Tensor
*/
static getSizePrefixedRootAsTensor(bb, obj) {
bb.setPosition(bb.position() + flatbuffers_1.flatbuffers.SIZE_PREFIX_LENGTH);
return (obj || new Tensor()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
name(optionalEncoding) {
let offset = this.bb.__offset(this.bb_pos, 4);
return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null;
}
docString(optionalEncoding) {
let offset = this.bb.__offset(this.bb_pos, 6);
return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null;
}
/**
* @param number index
* @returns flatbuffers.Long
*/
dims(index) {
let offset = this.bb.__offset(this.bb_pos, 8);
return offset ? this.bb.readInt64(this.bb.__vector(this.bb_pos + offset) + index * 8) :
this.bb.createLong(0, 0);
}
/**
* @returns number
*/
dimsLength() {
let offset = this.bb.__offset(this.bb_pos, 8);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
}
/**
* @returns onnxruntime.experimental.fbs.TensorDataType
*/
dataType() {
let offset = this.bb.__offset(this.bb_pos, 10);
return offset ? /** */ (this.bb.readInt32(this.bb_pos + offset)) :
onnxruntime.experimental.fbs.TensorDataType.UNDEFINED;
}
/**
* @param number index
* @returns number
*/
rawData(index) {
let offset = this.bb.__offset(this.bb_pos, 12);
return offset ? this.bb.readUint8(this.bb.__vector(this.bb_pos + offset) + index) : 0;
}
/**
* @returns number
*/
rawDataLength() {
let offset = this.bb.__offset(this.bb_pos, 12);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
}
/**
* @returns Uint8Array
*/
rawDataArray() {
let offset = this.bb.__offset(this.bb_pos, 12);
return offset ?
new Uint8Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) :
null;
}
stringData(index, optionalEncoding) {
let offset = this.bb.__offset(this.bb_pos, 14);
return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null;
}
/**
* @returns number
*/
stringDataLength() {
let offset = this.bb.__offset(this.bb_pos, 14);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
}
/**
* @param flatbuffers.Builder builder
*/
static startTensor(builder) {
builder.startObject(6);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset nameOffset
*/
static addName(builder, nameOffset) {
builder.addFieldOffset(0, nameOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset docStringOffset
*/
static addDocString(builder, docStringOffset) {
builder.addFieldOffset(1, docStringOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset dimsOffset
*/
static addDims(builder, dimsOffset) {
builder.addFieldOffset(2, dimsOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param Array.<flatbuffers.Long> data
* @returns flatbuffers.Offset
*/
static createDimsVector(builder, data) {
builder.startVector(8, data.length, 8);
for (let i = data.length - 1; i >= 0; i--) {
builder.addInt64(data[i]);
}
return builder.endVector();
}
/**
* @param flatbuffers.Builder builder
* @param number numElems
*/
static startDimsVector(builder, numElems) {
builder.startVector(8, numElems, 8);
}
/**
* @param flatbuffers.Builder builder
* @param onnxruntime.experimental.fbs.TensorDataType dataType
*/
static addDataType(builder, dataType) {
builder.addFieldInt32(3, dataType, onnxruntime.experimental.fbs.TensorDataType.UNDEFINED);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset rawDataOffset
*/
static addRawData(builder, rawDataOffset) {
builder.addFieldOffset(4, rawDataOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param Array.<number> data
* @returns flatbuffers.Offset
*/
static createRawDataVector(builder, data) {
builder.startVector(1, data.length, 1);
for (let i = data.length - 1; i >= 0; i--) {
builder.addInt8(data[i]);
}
return builder.endVector();
}
/**
* @param flatbuffers.Builder builder
* @param number numElems
*/
static startRawDataVector(builder, numElems) {
builder.startVector(1, numElems, 1);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset stringDataOffset
*/
static addStringData(builder, stringDataOffset) {
builder.addFieldOffset(5, stringDataOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param Array.<flatbuffers.Offset> data
* @returns flatbuffers.Offset
*/
static createStringDataVector(builder, data) {
builder.startVector(4, data.length, 4);
for (let i = data.length - 1; i >= 0; i--) {
builder.addOffset(data[i]);
}
return builder.endVector();
}
/**
* @param flatbuffers.Builder builder
* @param number numElems
*/
static startStringDataVector(builder, numElems) {
builder.startVector(4, numElems, 4);
}
/**
* @param flatbuffers.Builder builder
* @returns flatbuffers.Offset
*/
static endTensor(builder) {
let offset = builder.endObject();
return offset;
}
static createTensor(builder, nameOffset, docStringOffset, dimsOffset, dataType, rawDataOffset, stringDataOffset) {
Tensor.startTensor(builder);
Tensor.addName(builder, nameOffset);
Tensor.addDocString(builder, docStringOffset);
Tensor.addDims(builder, dimsOffset);
Tensor.addDataType(builder, dataType);
Tensor.addRawData(builder, rawDataOffset);
Tensor.addStringData(builder, stringDataOffset);
return Tensor.endTensor(builder);
}
}
fbs.Tensor = Tensor;
})(fbs = experimental.fbs || (experimental.fbs = {}));
})(experimental = onnxruntime.experimental || (onnxruntime.experimental = {}));
})(onnxruntime = exports.onnxruntime || (exports.onnxruntime = {}));
/**
* @constructor
*/
(function (onnxruntime) {
var experimental;
(function (experimental) {
var fbs;
(function (fbs) {
class SparseTensor {
constructor() {
this.bb = null;
this.bb_pos = 0;
}
/**
* @param number i
* @param flatbuffers.ByteBuffer bb
* @returns SparseTensor
*/
__init(i, bb) {
this.bb_pos = i;
this.bb = bb;
return this;
}
/**
* @param flatbuffers.ByteBuffer bb
* @param SparseTensor= obj
* @returns SparseTensor
*/
static getRootAsSparseTensor(bb, obj) {
return (obj || new SparseTensor()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
/**
* @param flatbuffers.ByteBuffer bb
* @param SparseTensor= obj
* @returns SparseTensor
*/
static getSizePrefixedRootAsSparseTensor(bb, obj) {
bb.setPosition(bb.position() + flatbuffers_1.flatbuffers.SIZE_PREFIX_LENGTH);
return (obj || new SparseTensor()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
/**
* @param onnxruntime.experimental.fbs.Tensor= obj
* @returns onnxruntime.experimental.fbs.Tensor|null
*/
values(obj) {
let offset = this.bb.__offset(this.bb_pos, 4);
return offset ? (obj || new onnxruntime.experimental.fbs.Tensor())
.__init(this.bb.__indirect(this.bb_pos + offset), this.bb) :
null;
}
/**
* @param onnxruntime.experimental.fbs.Tensor= obj
* @returns onnxruntime.experimental.fbs.Tensor|null
*/
indices(obj) {
let offset = this.bb.__offset(this.bb_pos, 6);
return offset ? (obj || new onnxruntime.experimental.fbs.Tensor())
.__init(this.bb.__indirect(this.bb_pos + offset), this.bb) :
null;
}
/**
* @param number index
* @returns flatbuffers.Long
*/
dims(index) {
let offset = this.bb.__offset(this.bb_pos, 8);
return offset ? this.bb.readInt64(this.bb.__vector(this.bb_pos + offset) + index * 8) :
this.bb.createLong(0, 0);
}
/**
* @returns number
*/
dimsLength() {
let offset = this.bb.__offset(this.bb_pos, 8);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
}
/**
* @param flatbuffers.Builder builder
*/
static startSparseTensor(builder) {
builder.startObject(3);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset valuesOffset
*/
static addValues(builder, valuesOffset) {
builder.addFieldOffset(0, valuesOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset indicesOffset
*/
static addIndices(builder, indicesOffset) {
builder.addFieldOffset(1, indicesOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset dimsOffset
*/
static addDims(builder, dimsOffset) {
builder.addFieldOffset(2, dimsOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param Array.<flatbuffers.Long> data
* @returns flatbuffers.Offset
*/
static createDimsVector(builder, data) {
builder.startVector(8, data.length, 8);
for (let i = data.length - 1; i >= 0; i--) {
builder.addInt64(data[i]);
}
return builder.endVector();
}
/**
* @param flatbuffers.Builder builder
* @param number numElems
*/
static startDimsVector(builder, numElems) {
builder.startVector(8, numElems, 8);
}
/**
* @param flatbuffers.Builder builder
* @returns flatbuffers.Offset
*/
static endSparseTensor(builder) {
let offset = builder.endObject();
return offset;
}
static createSparseTensor(builder, valuesOffset, indicesOffset, dimsOffset) {
SparseTensor.startSparseTensor(builder);
SparseTensor.addValues(builder, valuesOffset);
SparseTensor.addIndices(builder, indicesOffset);
SparseTensor.addDims(builder, dimsOffset);
return SparseTensor.endSparseTensor(builder);
}
}
fbs.SparseTensor = SparseTensor;
})(fbs = experimental.fbs || (experimental.fbs = {}));
})(experimental = onnxruntime.experimental || (onnxruntime.experimental = {}));
})(onnxruntime = exports.onnxruntime || (exports.onnxruntime = {}));
/**
* @constructor
*/
(function (onnxruntime) {
var experimental;
(function (experimental) {
var fbs;
(function (fbs) {
class Attribute {
constructor() {
this.bb = null;
this.bb_pos = 0;
}
/**
* @param number i
* @param flatbuffers.ByteBuffer bb
* @returns Attribute
*/
__init(i, bb) {
this.bb_pos = i;
this.bb = bb;
return this;
}
/**
* @param flatbuffers.ByteBuffer bb
* @param Attribute= obj
* @returns Attribute
*/
static getRootAsAttribute(bb, obj) {
return (obj || new Attribute()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
/**
* @param flatbuffers.ByteBuffer bb
* @param Attribute= obj
* @returns Attribute
*/
static getSizePrefixedRootAsAttribute(bb, obj) {
bb.setPosition(bb.position() + flatbuffers_1.flatbuffers.SIZE_PREFIX_LENGTH);
return (obj || new Attribute()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
name(optionalEncoding) {
let offset = this.bb.__offset(this.bb_pos, 4);
return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null;
}
docString(optionalEncoding) {
let offset = this.bb.__offset(this.bb_pos, 6);
return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null;
}
/**
* @returns onnxruntime.experimental.fbs.AttributeType
*/
type() {
let offset = this.bb.__offset(this.bb_pos, 8);
return offset ? /** */ (this.bb.readInt32(this.bb_pos + offset)) :
onnxruntime.experimental.fbs.AttributeType.UNDEFINED;
}
/**
* @returns number
*/
f() {
let offset = this.bb.__offset(this.bb_pos, 10);
return offset ? this.bb.readFloat32(this.bb_pos + offset) : 0.0;
}
/**
* @returns flatbuffers.Long
*/
i() {
let offset = this.bb.__offset(this.bb_pos, 12);
return offset ? this.bb.readInt64(this.bb_pos + offset) : this.bb.createLong(0, 0);
}
s(optionalEncoding) {
let offset = this.bb.__offset(this.bb_pos, 14);
return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null;
}
/**
* @param onnxruntime.experimental.fbs.Tensor= obj
* @returns onnxruntime.experimental.fbs.Tensor|null
*/
t(obj) {
let offset = this.bb.__offset(this.bb_pos, 16);
return offset ? (obj || new onnxruntime.experimental.fbs.Tensor())
.__init(this.bb.__indirect(this.bb_pos + offset), this.bb) :
null;
}
/**
* @param onnxruntime.experimental.fbs.Graph= obj
* @returns onnxruntime.experimental.fbs.Graph|null
*/
g(obj) {
let offset = this.bb.__offset(this.bb_pos, 18);
return offset ? (obj || new onnxruntime.experimental.fbs.Graph())
.__init(this.bb.__indirect(this.bb_pos + offset), this.bb) :
null;
}
/**
* @param number index
* @returns number
*/
floats(index) {
let offset = this.bb.__offset(this.bb_pos, 20);
return offset ? this.bb.readFloat32(this.bb.__vector(this.bb_pos + offset) + index * 4) : 0;
}
/**
* @returns number
*/
floatsLength() {
let offset = this.bb.__offset(this.bb_pos, 20);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
}
/**
* @returns Float32Array
*/
floatsArray() {
let offset = this.bb.__offset(this.bb_pos, 20);
return offset ?
new Float32Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) :
null;
}
/**
* @param number index
* @returns flatbuffers.Long
*/
ints(index) {
let offset = this.bb.__offset(this.bb_pos, 22);
return offset ? this.bb.readInt64(this.bb.__vector(this.bb_pos + offset) + index * 8) :
this.bb.createLong(0, 0);
}
/**
* @returns number
*/
intsLength() {
let offset = this.bb.__offset(this.bb_pos, 22);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
}
strings(index, optionalEncoding) {
let offset = this.bb.__offset(this.bb_pos, 24);
return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null;
}
/**
* @returns number
*/
stringsLength() {
let offset = this.bb.__offset(this.bb_pos, 24);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
}
/**
* @param number index
* @param onnxruntime.experimental.fbs.Tensor= obj
* @returns onnxruntime.experimental.fbs.Tensor
*/
tensors(index, obj) {
let offset = this.bb.__offset(this.bb_pos, 26);
return offset ? (obj || new onnxruntime.experimental.fbs.Tensor())
.__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) :
null;
}
/**
* @returns number
*/
tensorsLength() {
let offset = this.bb.__offset(this.bb_pos, 26);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
}
/**
* @param number index
* @param onnxruntime.experimental.fbs.Graph= obj
* @returns onnxruntime.experimental.fbs.Graph
*/
graphs(index, obj) {
let offset = this.bb.__offset(this.bb_pos, 28);
return offset ? (obj || new onnxruntime.experimental.fbs.Graph())
.__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) :
null;
}
/**
* @returns number
*/
graphsLength() {
let offset = this.bb.__offset(this.bb_pos, 28);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
}
/**
* @param flatbuffers.Builder builder
*/
static startAttribute(builder) {
builder.startObject(13);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset nameOffset
*/
static addName(builder, nameOffset) {
builder.addFieldOffset(0, nameOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset docStringOffset
*/
static addDocString(builder, docStringOffset) {
builder.addFieldOffset(1, docStringOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param onnxruntime.experimental.fbs.AttributeType type
*/
static addType(builder, type) {
builder.addFieldInt32(2, type, onnxruntime.experimental.fbs.AttributeType.UNDEFINED);
}
/**
* @param flatbuffers.Builder builder
* @param number f
*/
static addF(builder, f) {
builder.addFieldFloat32(3, f, 0.0);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Long i
*/
static addI(builder, i) {
builder.addFieldInt64(4, i, builder.createLong(0, 0));
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset sOffset
*/
static addS(builder, sOffset) {
builder.addFieldOffset(5, sOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset tOffset
*/
static addT(builder, tOffset) {
builder.addFieldOffset(6, tOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset gOffset
*/
static addG(builder, gOffset) {
builder.addFieldOffset(7, gOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset floatsOffset
*/
static addFloats(builder, floatsOffset) {
builder.addFieldOffset(8, floatsOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param Array.<number> data
* @returns flatbuffers.Offset
*/
static createFloatsVector(builder, data) {
builder.startVector(4, data.length, 4);
for (let i = data.length - 1; i >= 0; i--) {
builder.addFloat32(data[i]);
}
return builder.endVector();
}
/**
* @param flatbuffers.Builder builder
* @param number numElems
*/
static startFloatsVector(builder, numElems) {
builder.startVector(4, numElems, 4);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset intsOffset
*/
static addInts(builder, intsOffset) {
builder.addFieldOffset(9, intsOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param Array.<flatbuffers.Long> data
* @returns flatbuffers.Offset
*/
static createIntsVector(builder, data) {
builder.startVector(8, data.length, 8);
for (let i = data.length - 1; i >= 0; i--) {
builder.addInt64(data[i]);
}
return builder.endVector();
}
/**
* @param flatbuffers.Builder builder
* @param number numElems
*/
static startIntsVector(builder, numElems) {
builder.startVector(8, numElems, 8);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset stringsOffset
*/
static addStrings(builder, stringsOffset) {
builder.addFieldOffset(10, stringsOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param Array.<flatbuffers.Offset> data
* @returns flatbuffers.Offset
*/
static createStringsVector(builder, data) {
builder.startVector(4, data.length, 4);
for (let i = data.length - 1; i >= 0; i--) {
builder.addOffset(data[i]);
}
return builder.endVector();
}
/**
* @param flatbuffers.Builder builder
* @param number numElems
*/
static startStringsVector(builder, numElems) {
builder.startVector(4, numElems, 4);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset tensorsOffset
*/
static addTensors(builder, tensorsOffset) {
builder.addFieldOffset(11, tensorsOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param Array.<flatbuffers.Offset> data
* @returns flatbuffers.Offset
*/
static createTensorsVector(builder, data) {
builder.startVector(4, data.length, 4);
for (let i = data.length - 1; i >= 0; i--) {
builder.addOffset(data[i]);
}
return builder.endVector();
}
/**
* @param flatbuffers.Builder builder
* @param number numElems
*/
static startTensorsVector(builder, numElems) {
builder.startVector(4, numElems, 4);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset graphsOffset
*/
static addGraphs(builder, graphsOffset) {
builder.addFieldOffset(12, graphsOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param Array.<flatbuffers.Offset> data
* @returns flatbuffers.Offset
*/
static createGraphsVector(builder, data) {
builder.startVector(4, data.length, 4);
for (let i = data.length - 1; i >= 0; i--) {
builder.addOffset(data[i]);
}
return builder.endVector();
}
/**
* @param flatbuffers.Builder builder
* @param number numElems
*/
static startGraphsVector(builder, numElems) {
builder.startVector(4, numElems, 4);
}
/**
* @param flatbuffers.Builder builder
* @returns flatbuffers.Offset
*/
static endAttribute(builder) {
let offset = builder.endObject();
return offset;
}
static createAttribute(builder, nameOffset, docStringOffset, type, f, i, sOffset, tOffset, gOffset, floatsOffset, intsOffset, stringsOffset, tensorsOffset, graphsOffset) {
Attribute.startAttribute(builder);
Attribute.addName(builder, nameOffset);
Attribute.addDocString(builder, docStringOffset);
Attribute.addType(builder, type);
Attribute.addF(builder, f);
Attribute.addI(builder, i);
Attribute.addS(builder, sOffset);
Attribute.addT(builder, tOffset);
Attribute.addG(builder, gOffset);
Attribute.addFloats(builder, floatsOffset);
Attribute.addInts(builder, intsOffset);
Attribute.addStrings(builder, stringsOffset);
Attribute.addTensors(builder, tensorsOffset);
Attribute.addGraphs(builder, graphsOffset);
return Attribute.endAttribute(builder);
}
}
fbs.Attribute = Attribute;
})(fbs = experimental.fbs || (experimental.fbs = {}));
})(experimental = onnxruntime.experimental || (onnxruntime.experimental = {}));
})(onnxruntime = exports.onnxruntime || (exports.onnxruntime = {}));
/**
* @constructor
*/
(function (onnxruntime) {
var experimental;
(function (experimental) {
var fbs;
(function (fbs) {
class Graph {
constructor() {
this.bb = null;
this.bb_pos = 0;
}
/**
* @param number i
* @param flatbuffers.ByteBuffer bb
* @returns Graph
*/
__init(i, bb) {
this.bb_pos = i;
this.bb = bb;
return this;
}
/**
* @param flatbuffers.ByteBuffer bb
* @param Graph= obj
* @returns Graph
*/
static getRootAsGraph(bb, obj) {
return (obj || new Graph()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
/**
* @param flatbuffers.ByteBuffer bb
* @param Graph= obj
* @returns Graph
*/
static getSizePrefixedRootAsGraph(bb, obj) {
bb.setPosition(bb.position() + flatbuffers_1.flatbuffers.SIZE_PREFIX_LENGTH);
return (obj || new Graph()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
/**
* @param number index
* @param onnxruntime.experimental.fbs.Tensor= obj
* @returns onnxruntime.experimental.fbs.Tensor
*/
initializers(index, obj) {
let offset = this.bb.__offset(this.bb_pos, 4);
return offset ? (obj || new onnxruntime.experimental.fbs.Tensor())
.__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) :
null;
}
/**
* @returns number
*/
initializersLength() {
let offset = this.bb.__offset(this.bb_pos, 4);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
}
/**
* @param number index
* @param onnxruntime.experimental.fbs.ValueInfo= obj
* @returns onnxruntime.experimental.fbs.ValueInfo
*/
nodeArgs(index, obj) {
let offset = this.bb.__offset(this.bb_pos, 6);
return offset ? (obj || new onnxruntime.experimental.fbs.ValueInfo())
.__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) :
null;
}
/**
* @returns number
*/
nodeArgsLength() {
let offset = this.bb.__offset(this.bb_pos, 6);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
}
/**
* @param number index
* @param onnxruntime.experimental.fbs.Node= obj
* @returns onnxruntime.experimental.fbs.Node
*/
nodes(index, obj) {
let offset = this.bb.__offset(this.bb_pos, 8);
return offset ? (obj || new onnxruntime.experimental.fbs.Node())
.__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) :
null;
}
/**
* @returns number
*/
nodesLength() {
let offset = this.bb.__offset(this.bb_pos, 8);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
}
/**
* @returns number
*/
maxNodeIndex() {
let offset = this.bb.__offset(this.bb_pos, 10);
return offset ? this.bb.readUint32(this.bb_pos + offset) : 0;
}
/**
* @param number index
* @param onnxruntime.experimental.fbs.NodeEdge= obj
* @returns onnxruntime.experimental.fbs.NodeEdge
*/
nodeEdges(index, obj) {
let offset = this.bb.__offset(this.bb_pos, 12);
return offset ? (obj || new onnxruntime.experimental.fbs.NodeEdge())
.__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) :
null;
}
/**
* @returns number
*/
nodeEdgesLength() {
let offset = this.bb.__offset(this.bb_pos, 12);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
}
inputs(index, optionalEncoding) {
let offset = this.bb.__offset(this.bb_pos, 14);
return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null;
}
/**
* @returns number
*/
inputsLength() {
let offset = this.bb.__offset(this.bb_pos, 14);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
}
outputs(index, optionalEncoding) {
let offset = this.bb.__offset(this.bb_pos, 16);
return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null;
}
/**
* @returns number
*/
outputsLength() {
let offset = this.bb.__offset(this.bb_pos, 16);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
}
/**
* @param number index
* @param onnxruntime.experimental.fbs.SparseTensor= obj
* @returns onnxruntime.experimental.fbs.SparseTensor
*/
sparseInitializers(index, obj) {
let offset = this.bb.__offset(this.bb_pos, 18);
return offset ? (obj || new onnxruntime.experimental.fbs.SparseTensor())
.__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) :
null;
}
/**
* @returns number
*/
sparseInitializersLength() {
let offset = this.bb.__offset(this.bb_pos, 18);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
}
/**
* @param flatbuffers.Builder builder
*/
static startGraph(builder) {
builder.startObject(8);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset initializersOffset
*/
static addInitializers(builder, initializersOffset) {
builder.addFieldOffset(0, initializersOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param Array.<flatbuffers.Offset> data
* @returns flatbuffers.Offset
*/
static createInitializersVector(builder, data) {
builder.startVector(4, data.length, 4);
for (let i = data.length - 1; i >= 0; i--) {
builder.addOffset(data[i]);
}
return builder.endVector();
}
/**
* @param flatbuffers.Builder builder
* @param number numElems
*/
static startInitializersVector(builder, numElems) {
builder.startVector(4, numElems, 4);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset nodeArgsOffset
*/
static addNodeArgs(builder, nodeArgsOffset) {
builder.addFieldOffset(1, nodeArgsOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param Array.<flatbuffers.Offset> data
* @returns flatbuffers.Offset
*/
static createNodeArgsVector(builder, data) {
builder.startVector(4, data.length, 4);
for (let i = data.length - 1; i >= 0; i--) {
builder.addOffset(data[i]);
}
return builder.endVector();
}
/**
* @param flatbuffers.Builder builder
* @param number numElems
*/
static startNodeArgsVector(builder, numElems) {
builder.startVector(4, numElems, 4);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset nodesOffset
*/
static addNodes(builder, nodesOffset) {
builder.addFieldOffset(2, nodesOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param Array.<flatbuffers.Offset> data
* @returns flatbuffers.Offset
*/
static createNodesVector(builder, data) {
builder.startVector(4, data.length, 4);
for (let i = data.length - 1; i >= 0; i--) {
builder.addOffset(data[i]);
}
return builder.endVector();
}
/**
* @param flatbuffers.Builder builder
* @param number numElems
*/
static startNodesVector(builder, numElems) {
builder.startVector(4, numElems, 4);
}
/**
* @param flatbuffers.Builder builder
* @param number maxNodeIndex
*/
static addMaxNodeIndex(builder, maxNodeIndex) {
builder.addFieldInt32(3, maxNodeIndex, 0);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset nodeEdgesOffset
*/
static addNodeEdges(builder, nodeEdgesOffset) {
builder.addFieldOffset(4, nodeEdgesOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param Array.<flatbuffers.Offset> data
* @returns flatbuffers.Offset
*/
static createNodeEdgesVector(builder, data) {
builder.startVector(4, data.length, 4);
for (let i = data.length - 1; i >= 0; i--) {
builder.addOffset(data[i]);
}
return builder.endVector();
}
/**
* @param flatbuffers.Builder builder
* @param number numElems
*/
static startNodeEdgesVector(builder, numElems) {
builder.startVector(4, numElems, 4);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset inputsOffset
*/
static addInputs(builder, inputsOffset) {
builder.addFieldOffset(5, inputsOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param Array.<flatbuffers.Offset> data
* @returns flatbuffers.Offset
*/
static createInputsVector(builder, data) {
builder.startVector(4, data.length, 4);
for (let i = data.length - 1; i >= 0; i--) {
builder.addOffset(data[i]);
}
return builder.endVector();
}
/**
* @param flatbuffers.Builder builder
* @param number numElems
*/
static startInputsVector(builder, numElems) {
builder.startVector(4, numElems, 4);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset outputsOffset
*/
static addOutputs(builder, outputsOffset) {
builder.addFieldOffset(6, outputsOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param Array.<flatbuffers.Offset> data
* @returns flatbuffers.Offset
*/
static createOutputsVector(builder, data) {
builder.startVector(4, data.length, 4);
for (let i = data.length - 1; i >= 0; i--) {
builder.addOffset(data[i]);
}
return builder.endVector();
}
/**
* @param flatbuffers.Builder builder
* @param number numElems
*/
static startOutputsVector(builder, numElems) {
builder.startVector(4, numElems, 4);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset sparseInitializersOffset
*/
static addSparseInitializers(builder, sparseInitializersOffset) {
builder.addFieldOffset(7, sparseInitializersOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param Array.<flatbuffers.Offset> data
* @returns flatbuffers.Offset
*/
static createSparseInitializersVector(builder, data) {
builder.startVector(4, data.length, 4);
for (let i = data.length - 1; i >= 0; i--) {
builder.addOffset(data[i]);
}
return builder.endVector();
}
/**
* @param flatbuffers.Builder builder
* @param number numElems
*/
static startSparseInitializersVector(builder, numElems) {
builder.startVector(4, numElems, 4);
}
/**
* @param flatbuffers.Builder builder
* @returns flatbuffers.Offset
*/
static endGraph(builder) {
let offset = builder.endObject();
return offset;
}
static createGraph(builder, initializersOffset, nodeArgsOffset, nodesOffset, maxNodeIndex, nodeEdgesOffset, inputsOffset, outputsOffset, sparseInitializersOffset) {
Graph.startGraph(builder);
Graph.addInitializers(builder, initializersOffset);
Graph.addNodeArgs(builder, nodeArgsOffset);
Graph.addNodes(builder, nodesOffset);
Graph.addMaxNodeIndex(builder, maxNodeIndex);
Graph.addNodeEdges(builder, nodeEdgesOffset);
Graph.addInputs(builder, inputsOffset);
Graph.addOutputs(builder, outputsOffset);
Graph.addSparseInitializers(builder, sparseInitializersOffset);
return Graph.endGraph(builder);
}
}
fbs.Graph = Graph;
})(fbs = experimental.fbs || (experimental.fbs = {}));
})(experimental = onnxruntime.experimental || (onnxruntime.experimental = {}));
})(onnxruntime = exports.onnxruntime || (exports.onnxruntime = {}));
/**
* @constructor
*/
(function (onnxruntime) {
var experimental;
(function (experimental) {
var fbs;
(function (fbs) {
class Model {
constructor() {
this.bb = null;
this.bb_pos = 0;
}
/**
* @param number i
* @param flatbuffers.ByteBuffer bb
* @returns Model
*/
__init(i, bb) {
this.bb_pos = i;
this.bb = bb;
return this;
}
/**
* @param flatbuffers.ByteBuffer bb
* @param Model= obj
* @returns Model
*/
static getRootAsModel(bb, obj) {
return (obj || new Model()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
/**
* @param flatbuffers.ByteBuffer bb
* @param Model= obj
* @returns Model
*/
static getSizePrefixedRootAsModel(bb, obj) {
bb.setPosition(bb.position() + flatbuffers_1.flatbuffers.SIZE_PREFIX_LENGTH);
return (obj || new Model()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
/**
* @returns flatbuffers.Long
*/
irVersion() {
let offset = this.bb.__offset(this.bb_pos, 4);
return offset ? this.bb.readInt64(this.bb_pos + offset) : this.bb.createLong(0, 0);
}
/**
* @param number index
* @param onnxruntime.experimental.fbs.OperatorSetId= obj
* @returns onnxruntime.experimental.fbs.OperatorSetId
*/
opsetImport(index, obj) {
let offset = this.bb.__offset(this.bb_pos, 6);
return offset ? (obj || new onnxruntime.experimental.fbs.OperatorSetId())
.__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) :
null;
}
/**
* @returns number
*/
opsetImportLength() {
let offset = this.bb.__offset(this.bb_pos, 6);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
}
producerName(optionalEncoding) {
let offset = this.bb.__offset(this.bb_pos, 8);
return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null;
}
producerVersion(optionalEncoding) {
let offset = this.bb.__offset(this.bb_pos, 10);
return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null;
}
domain(optionalEncoding) {
let offset = this.bb.__offset(this.bb_pos, 12);
return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null;
}
/**
* @returns flatbuffers.Long
*/
modelVersion() {
let offset = this.bb.__offset(this.bb_pos, 14);
return offset ? this.bb.readInt64(this.bb_pos + offset) : this.bb.createLong(0, 0);
}
docString(optionalEncoding) {
let offset = this.bb.__offset(this.bb_pos, 16);
return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null;
}
/**
* @param onnxruntime.experimental.fbs.Graph= obj
* @returns onnxruntime.experimental.fbs.Graph|null
*/
graph(obj) {
let offset = this.bb.__offset(this.bb_pos, 18);
return offset ? (obj || new onnxruntime.experimental.fbs.Graph())
.__init(this.bb.__indirect(this.bb_pos + offset), this.bb) :
null;
}
graphDocString(optionalEncoding) {
let offset = this.bb.__offset(this.bb_pos, 20);
return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null;
}
/**
* @param flatbuffers.Builder builder
*/
static startModel(builder) {
builder.startObject(9);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Long irVersion
*/
static addIrVersion(builder, irVersion) {
builder.addFieldInt64(0, irVersion, builder.createLong(0, 0));
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset opsetImportOffset
*/
static addOpsetImport(builder, opsetImportOffset) {
builder.addFieldOffset(1, opsetImportOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param Array.<flatbuffers.Offset> data
* @returns flatbuffers.Offset
*/
static createOpsetImportVector(builder, data) {
builder.startVector(4, data.length, 4);
for (let i = data.length - 1; i >= 0; i--) {
builder.addOffset(data[i]);
}
return builder.endVector();
}
/**
* @param flatbuffers.Builder builder
* @param number numElems
*/
static startOpsetImportVector(builder, numElems) {
builder.startVector(4, numElems, 4);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset producerNameOffset
*/
static addProducerName(builder, producerNameOffset) {
builder.addFieldOffset(2, producerNameOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset producerVersionOffset
*/
static addProducerVersion(builder, producerVersionOffset) {
builder.addFieldOffset(3, producerVersionOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset domainOffset
*/
static addDomain(builder, domainOffset) {
builder.addFieldOffset(4, domainOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Long modelVersion
*/
static addModelVersion(builder, modelVersion) {
builder.addFieldInt64(5, modelVersion, builder.createLong(0, 0));
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset docStringOffset
*/
static addDocString(builder, docStringOffset) {
builder.addFieldOffset(6, docStringOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset graphOffset
*/
static addGraph(builder, graphOffset) {
builder.addFieldOffset(7, graphOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset graphDocStringOffset
*/
static addGraphDocString(builder, graphDocStringOffset) {
builder.addFieldOffset(8, graphDocStringOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @returns flatbuffers.Offset
*/
static endModel(builder) {
let offset = builder.endObject();
return offset;
}
static createModel(builder, irVersion, opsetImportOffset, producerNameOffset, producerVersionOffset, domainOffset, modelVersion, docStringOffset, graphOffset, graphDocStringOffset) {
Model.startModel(builder);
Model.addIrVersion(builder, irVersion);
Model.addOpsetImport(builder, opsetImportOffset);
Model.addProducerName(builder, producerNameOffset);
Model.addProducerVersion(builder, producerVersionOffset);
Model.addDomain(builder, domainOffset);
Model.addModelVersion(builder, modelVersion);
Model.addDocString(builder, docStringOffset);
Model.addGraph(builder, graphOffset);
Model.addGraphDocString(builder, graphDocStringOffset);
return Model.endModel(builder);
}
}
fbs.Model = Model;
})(fbs = experimental.fbs || (experimental.fbs = {}));
})(experimental = onnxruntime.experimental || (onnxruntime.experimental = {}));
})(onnxruntime = exports.onnxruntime || (exports.onnxruntime = {}));
/**
* @constructor
*/
(function (onnxruntime) {
var experimental;
(function (experimental) {
var fbs;
(function (fbs) {
class KernelCreateInfos {
constructor() {
this.bb = null;
this.bb_pos = 0;
}
/**
* @param number i
* @param flatbuffers.ByteBuffer bb
* @returns KernelCreateInfos
*/
__init(i, bb) {
this.bb_pos = i;
this.bb = bb;
return this;
}
/**
* @param flatbuffers.ByteBuffer bb
* @param KernelCreateInfos= obj
* @returns KernelCreateInfos
*/
static getRootAsKernelCreateInfos(bb, obj) {
return (obj || new KernelCreateInfos()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
/**
* @param flatbuffers.ByteBuffer bb
* @param KernelCreateInfos= obj
* @returns KernelCreateInfos
*/
static getSizePrefixedRootAsKernelCreateInfos(bb, obj) {
bb.setPosition(bb.position() + flatbuffers_1.flatbuffers.SIZE_PREFIX_LENGTH);
return (obj || new KernelCreateInfos()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
/**
* @param number index
* @returns number
*/
nodeIndices(index) {
let offset = this.bb.__offset(this.bb_pos, 4);
return offset ? this.bb.readUint32(this.bb.__vector(this.bb_pos + offset) + index * 4) : 0;
}
/**
* @returns number
*/
nodeIndicesLength() {
let offset = this.bb.__offset(this.bb_pos, 4);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
}
/**
* @returns Uint32Array
*/
nodeIndicesArray() {
let offset = this.bb.__offset(this.bb_pos, 4);
return offset ?
new Uint32Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) :
null;
}
/**
* @param number index
* @returns flatbuffers.Long
*/
kernelDefHashes(index) {
let offset = this.bb.__offset(this.bb_pos, 6);
return offset ? this.bb.readUint64(this.bb.__vector(this.bb_pos + offset) + index * 8) :
this.bb.createLong(0, 0);
}
/**
* @returns number
*/
kernelDefHashesLength() {
let offset = this.bb.__offset(this.bb_pos, 6);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
}
/**
* @param flatbuffers.Builder builder
*/
static startKernelCreateInfos(builder) {
builder.startObject(2);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset nodeIndicesOffset
*/
static addNodeIndices(builder, nodeIndicesOffset) {
builder.addFieldOffset(0, nodeIndicesOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param Array.<number> data
* @returns flatbuffers.Offset
*/
static createNodeIndicesVector(builder, data) {
builder.startVector(4, data.length, 4);
for (let i = data.length - 1; i >= 0; i--) {
builder.addInt32(data[i]);
}
return builder.endVector();
}
/**
* @param flatbuffers.Builder builder
* @param number numElems
*/
static startNodeIndicesVector(builder, numElems) {
builder.startVector(4, numElems, 4);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset kernelDefHashesOffset
*/
static addKernelDefHashes(builder, kernelDefHashesOffset) {
builder.addFieldOffset(1, kernelDefHashesOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param Array.<flatbuffers.Long> data
* @returns flatbuffers.Offset
*/
static createKernelDefHashesVector(builder, data) {
builder.startVector(8, data.length, 8);
for (let i = data.length - 1; i >= 0; i--) {
builder.addInt64(data[i]);
}
return builder.endVector();
}
/**
* @param flatbuffers.Builder builder
* @param number numElems
*/
static startKernelDefHashesVector(builder, numElems) {
builder.startVector(8, numElems, 8);
}
/**
* @param flatbuffers.Builder builder
* @returns flatbuffers.Offset
*/
static endKernelCreateInfos(builder) {
let offset = builder.endObject();
return offset;
}
static createKernelCreateInfos(builder, nodeIndicesOffset, kernelDefHashesOffset) {
KernelCreateInfos.startKernelCreateInfos(builder);
KernelCreateInfos.addNodeIndices(builder, nodeIndicesOffset);
KernelCreateInfos.addKernelDefHashes(builder, kernelDefHashesOffset);
return KernelCreateInfos.endKernelCreateInfos(builder);
}
}
fbs.KernelCreateInfos = KernelCreateInfos;
})(fbs = experimental.fbs || (experimental.fbs = {}));
})(experimental = onnxruntime.experimental || (onnxruntime.experimental = {}));
})(onnxruntime = exports.onnxruntime || (exports.onnxruntime = {}));
/**
* @constructor
*/
(function (onnxruntime) {
var experimental;
(function (experimental) {
var fbs;
(function (fbs) {
class SubGraphSessionState {
constructor() {
this.bb = null;
this.bb_pos = 0;
}
/**
* @param number i
* @param flatbuffers.ByteBuffer bb
* @returns SubGraphSessionState
*/
__init(i, bb) {
this.bb_pos = i;
this.bb = bb;
return this;
}
/**
* @param flatbuffers.ByteBuffer bb
* @param SubGraphSessionState= obj
* @returns SubGraphSessionState
*/
static getRootAsSubGraphSessionState(bb, obj) {
return (obj || new SubGraphSessionState()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
/**
* @param flatbuffers.ByteBuffer bb
* @param SubGraphSessionState= obj
* @returns SubGraphSessionState
*/
static getSizePrefixedRootAsSubGraphSessionState(bb, obj) {
bb.setPosition(bb.position() + flatbuffers_1.flatbuffers.SIZE_PREFIX_LENGTH);
return (obj || new SubGraphSessionState()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
graphId(optionalEncoding) {
let offset = this.bb.__offset(this.bb_pos, 4);
return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null;
}
/**
* @param onnxruntime.experimental.fbs.SessionState= obj
* @returns onnxruntime.experimental.fbs.SessionState|null
*/
sessionState(obj) {
let offset = this.bb.__offset(this.bb_pos, 6);
return offset ? (obj || new onnxruntime.experimental.fbs.SessionState())
.__init(this.bb.__indirect(this.bb_pos + offset), this.bb) :
null;
}
/**
* @param flatbuffers.Builder builder
*/
static startSubGraphSessionState(builder) {
builder.startObject(2);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset graphIdOffset
*/
static addGraphId(builder, graphIdOffset) {
builder.addFieldOffset(0, graphIdOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset sessionStateOffset
*/
static addSessionState(builder, sessionStateOffset) {
builder.addFieldOffset(1, sessionStateOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @returns flatbuffers.Offset
*/
static endSubGraphSessionState(builder) {
let offset = builder.endObject();
builder.requiredField(offset, 4); // graph_id
return offset;
}
static createSubGraphSessionState(builder, graphIdOffset, sessionStateOffset) {
SubGraphSessionState.startSubGraphSessionState(builder);
SubGraphSessionState.addGraphId(builder, graphIdOffset);
SubGraphSessionState.addSessionState(builder, sessionStateOffset);
return SubGraphSessionState.endSubGraphSessionState(builder);
}
}
fbs.SubGraphSessionState = SubGraphSessionState;
})(fbs = experimental.fbs || (experimental.fbs = {}));
})(experimental = onnxruntime.experimental || (onnxruntime.experimental = {}));
})(onnxruntime = exports.onnxruntime || (exports.onnxruntime = {}));
/**
* @constructor
*/
(function (onnxruntime) {
var experimental;
(function (experimental) {
var fbs;
(function (fbs) {
class SessionState {
constructor() {
this.bb = null;
this.bb_pos = 0;
}
/**
* @param number i
* @param flatbuffers.ByteBuffer bb
* @returns SessionState
*/
__init(i, bb) {
this.bb_pos = i;
this.bb = bb;
return this;
}
/**
* @param flatbuffers.ByteBuffer bb
* @param SessionState= obj
* @returns SessionState
*/
static getRootAsSessionState(bb, obj) {
return (obj || new SessionState()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
/**
* @param flatbuffers.ByteBuffer bb
* @param SessionState= obj
* @returns SessionState
*/
static getSizePrefixedRootAsSessionState(bb, obj) {
bb.setPosition(bb.position() + flatbuffers_1.flatbuffers.SIZE_PREFIX_LENGTH);
return (obj || new SessionState()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
/**
* @param onnxruntime.experimental.fbs.KernelCreateInfos= obj
* @returns onnxruntime.experimental.fbs.KernelCreateInfos|null
*/
kernels(obj) {
let offset = this.bb.__offset(this.bb_pos, 4);
return offset ? (obj || new onnxruntime.experimental.fbs.KernelCreateInfos())
.__init(this.bb.__indirect(this.bb_pos + offset), this.bb) :
null;
}
/**
* @param number index
* @param onnxruntime.experimental.fbs.SubGraphSessionState= obj
* @returns onnxruntime.experimental.fbs.SubGraphSessionState
*/
subGraphSessionStates(index, obj) {
let offset = this.bb.__offset(this.bb_pos, 6);
return offset ? (obj || new onnxruntime.experimental.fbs.SubGraphSessionState())
.__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) :
null;
}
/**
* @returns number
*/
subGraphSessionStatesLength() {
let offset = this.bb.__offset(this.bb_pos, 6);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
}
/**
* @param flatbuffers.Builder builder
*/
static startSessionState(builder) {
builder.startObject(2);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset kernelsOffset
*/
static addKernels(builder, kernelsOffset) {
builder.addFieldOffset(0, kernelsOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset subGraphSessionStatesOffset
*/
static addSubGraphSessionStates(builder, subGraphSessionStatesOffset) {
builder.addFieldOffset(1, subGraphSessionStatesOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param Array.<flatbuffers.Offset> data
* @returns flatbuffers.Offset
*/
static createSubGraphSessionStatesVector(builder, data) {
builder.startVector(4, data.length, 4);
for (let i = data.length - 1; i >= 0; i--) {
builder.addOffset(data[i]);
}
return builder.endVector();
}
/**
* @param flatbuffers.Builder builder
* @param number numElems
*/
static startSubGraphSessionStatesVector(builder, numElems) {
builder.startVector(4, numElems, 4);
}
/**
* @param flatbuffers.Builder builder
* @returns flatbuffers.Offset
*/
static endSessionState(builder) {
let offset = builder.endObject();
return offset;
}
static createSessionState(builder, kernelsOffset, subGraphSessionStatesOffset) {
SessionState.startSessionState(builder);
SessionState.addKernels(builder, kernelsOffset);
SessionState.addSubGraphSessionStates(builder, subGraphSessionStatesOffset);
return SessionState.endSessionState(builder);
}
}
fbs.SessionState = SessionState;
})(fbs = experimental.fbs || (experimental.fbs = {}));
})(experimental = onnxruntime.experimental || (onnxruntime.experimental = {}));
})(onnxruntime = exports.onnxruntime || (exports.onnxruntime = {}));
/**
* @constructor
*/
(function (onnxruntime) {
var experimental;
(function (experimental) {
var fbs;
(function (fbs) {
class InferenceSession {
constructor() {
this.bb = null;
this.bb_pos = 0;
}
/**
* @param number i
* @param flatbuffers.ByteBuffer bb
* @returns InferenceSession
*/
__init(i, bb) {
this.bb_pos = i;
this.bb = bb;
return this;
}
/**
* @param flatbuffers.ByteBuffer bb
* @param InferenceSession= obj
* @returns InferenceSession
*/
static getRootAsInferenceSession(bb, obj) {
return (obj || new InferenceSession()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
/**
* @param flatbuffers.ByteBuffer bb
* @param InferenceSession= obj
* @returns InferenceSession
*/
static getSizePrefixedRootAsInferenceSession(bb, obj) {
bb.setPosition(bb.position() + flatbuffers_1.flatbuffers.SIZE_PREFIX_LENGTH);
return (obj || new InferenceSession()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}
/**
* @param flatbuffers.ByteBuffer bb
* @returns boolean
*/
static bufferHasIdentifier(bb) {
return bb.__has_identifier('ORTM');
}
ortVersion(optionalEncoding) {
let offset = this.bb.__offset(this.bb_pos, 4);
return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null;
}
/**
* @param onnxruntime.experimental.fbs.Model= obj
* @returns onnxruntime.experimental.fbs.Model|null
*/
model(obj) {
let offset = this.bb.__offset(this.bb_pos, 6);
return offset ? (obj || new onnxruntime.experimental.fbs.Model())
.__init(this.bb.__indirect(this.bb_pos + offset), this.bb) :
null;
}
/**
* @param onnxruntime.experimental.fbs.SessionState= obj
* @returns onnxruntime.experimental.fbs.SessionState|null
*/
sessionState(obj) {
let offset = this.bb.__offset(this.bb_pos, 8);
return offset ? (obj || new onnxruntime.experimental.fbs.SessionState())
.__init(this.bb.__indirect(this.bb_pos + offset), this.bb) :
null;
}
/**
* @param flatbuffers.Builder builder
*/
static startInferenceSession(builder) {
builder.startObject(3);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset ortVersionOffset
*/
static addOrtVersion(builder, ortVersionOffset) {
builder.addFieldOffset(0, ortVersionOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset modelOffset
*/
static addModel(builder, modelOffset) {
builder.addFieldOffset(1, modelOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset sessionStateOffset
*/
static addSessionState(builder, sessionStateOffset) {
builder.addFieldOffset(2, sessionStateOffset, 0);
}
/**
* @param flatbuffers.Builder builder
* @returns flatbuffers.Offset
*/
static endInferenceSession(builder) {
let offset = builder.endObject();
return offset;
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset offset
*/
static finishInferenceSessionBuffer(builder, offset) {
builder.finish(offset, 'ORTM');
}
/**
* @param flatbuffers.Builder builder
* @param flatbuffers.Offset offset
*/
static finishSizePrefixedInferenceSessionBuffer(builder, offset) {
builder.finish(offset, 'ORTM', true);
}
static createInferenceSession(builder, ortVersionOffset, modelOffset, sessionStateOffset) {
InferenceSession.startInferenceSession(builder);
InferenceSession.addOrtVersion(builder, ortVersionOffset);
InferenceSession.addModel(builder, modelOffset);
InferenceSession.addSessionState(builder, sessionStateOffset);
return InferenceSession.endInferenceSession(builder);
}
}
fbs.InferenceSession = InferenceSession;
})(fbs = experimental.fbs || (experimental.fbs = {}));
})(experimental = onnxruntime.experimental || (onnxruntime.experimental = {}));
})(onnxruntime = exports.onnxruntime || (exports.onnxruntime = {}));
/***/ }),
/***/ "./lib/onnxjs/session-handler.ts":
/*!***************************************!*\
!*** ./lib/onnxjs/session-handler.ts ***!
\***************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.OnnxjsSessionHandler = void 0;
const onnxruntime_common_1 = __webpack_require__(/*! onnxruntime-common */ "onnxruntime-common");
const tensor_1 = __webpack_require__(/*! ./tensor */ "./lib/onnxjs/tensor.ts");
class OnnxjsSessionHandler {
constructor(session) {
this.session = session;
this.inputNames = this.session.inputNames;
this.outputNames = this.session.outputNames;
}
async dispose() { }
async run(feeds, _fetches, _options) {
const inputMap = new Map();
for (const name in feeds) {
if (Object.hasOwnProperty.call(feeds, name)) {
const feed = feeds[name];
inputMap.set(name, new tensor_1.Tensor(feed.dims, feed.type, undefined, undefined, feed.data));
}
}
const outputMap = await this.session.run(inputMap);
const output = {};
outputMap.forEach((tensor, name) => {
output[name] = new onnxruntime_common_1.Tensor(tensor.type, tensor.data, tensor.dims);
});
return output;
}
startProfiling() {
this.session.startProfiling();
}
endProfiling() {
this.session.endProfiling();
}
}
exports.OnnxjsSessionHandler = OnnxjsSessionHandler;
/***/ }),
/***/ "./lib/onnxjs/session.ts":
/*!*******************************!*\
!*** ./lib/onnxjs/session.ts ***!
\*******************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.Session = void 0;
const fs_1 = __webpack_require__(/*! fs */ "?6c45");
const util_1 = __webpack_require__(/*! util */ "?b3a2");
const backend_1 = __webpack_require__(/*! ./backend */ "./lib/onnxjs/backend.ts");
const execution_plan_1 = __webpack_require__(/*! ./execution-plan */ "./lib/onnxjs/execution-plan.ts");
const instrument_1 = __webpack_require__(/*! ./instrument */ "./lib/onnxjs/instrument.ts");
const model_1 = __webpack_require__(/*! ./model */ "./lib/onnxjs/model.ts");
class Session {
constructor(config = {}) {
this._initialized = false;
this.backendHint = config.backendHint;
this.profiler = instrument_1.Profiler.create(config.profiler);
this.context = { profiler: this.profiler, graphInputTypes: [], graphInputDims: [] };
}
get inputNames() {
return this._model.graph.getInputNames();
}
get outputNames() {
return this._model.graph.getOutputNames();
}
startProfiling() {
this.profiler.start();
}
endProfiling() {
this.profiler.stop();
}
async loadModel(arg, byteOffset, length) {
await this.profiler.event('session', 'Session.loadModel', async () => {
// resolve backend and session handler
const backend = await (0, backend_1.resolveBackend)(this.backendHint);
this.sessionHandler = backend.createSessionHandler(this.context);
this._model = new model_1.Model();
if (typeof arg === 'string') {
const isOrtFormat = arg.endsWith('.ort');
if (typeof fetch === 'undefined') {
// node
const buf = await (0, util_1.promisify)(fs_1.readFile)(arg);
this.initialize(buf, isOrtFormat);
}
else {
// browser
const response = await fetch(arg);
const buf = await response.arrayBuffer();
this.initialize(new Uint8Array(buf), isOrtFormat);
}
}
else if (!ArrayBuffer.isView(arg)) {
// load model from ArrayBuffer
const arr = new Uint8Array(arg, byteOffset || 0, length || arg.byteLength);
this.initialize(arr);
}
else {
// load model from Uint8array
this.initialize(arg);
}
});
}
initialize(modelProtoBlob, isOrtFormat) {
if (this._initialized) {
throw new Error('already initialized');
}
this.profiler.event('session', 'Session.initialize', () => {
// load graph
const graphInitializer = this.sessionHandler.transformGraph ? this.sessionHandler : undefined;
this._model.load(modelProtoBlob, graphInitializer, isOrtFormat);
// graph is completely initialzied at this stage , let the interested handlers know
if (this.sessionHandler.onGraphInitialized) {
this.sessionHandler.onGraphInitialized(this._model.graph);
}
// initialize each operator in the graph
this.initializeOps(this._model.graph);
// instantiate an ExecutionPlan object to be used by the Session object
this._executionPlan = new execution_plan_1.ExecutionPlan(this._model.graph, this._ops, this.profiler);
});
this._initialized = true;
}
async run(inputs) {
if (!this._initialized) {
throw new Error('session not initialized yet');
}
return this.profiler.event('session', 'Session.run', async () => {
const inputTensors = this.normalizeAndValidateInputs(inputs);
const outputTensors = await this._executionPlan.execute(this.sessionHandler, inputTensors);
return this.createOutput(outputTensors);
});
}
normalizeAndValidateInputs(inputs) {
const modelInputNames = this._model.graph.getInputNames();
// normalize inputs
// inputs: Tensor[]
if (Array.isArray(inputs)) {
if (inputs.length !== modelInputNames.length) {
throw new Error(`incorrect input array length: expected ${modelInputNames.length} but got ${inputs.length}`);
}
}
// convert map to array
// inputs: Map<string, Tensor>
else {
if (inputs.size !== modelInputNames.length) {
throw new Error(`incorrect input map size: expected ${modelInputNames.length} but got ${inputs.size}`);
}
const sortedInputs = new Array(inputs.size);
let sortedInputsIndex = 0;
for (let i = 0; i < modelInputNames.length; ++i) {
const tensor = inputs.get(modelInputNames[i]);
if (!tensor) {
throw new Error(`missing input tensor for: '${name}'`);
}
sortedInputs[sortedInputsIndex++] = tensor;
}
inputs = sortedInputs;
}
// validate dims requirements
// First session run - graph input data is not cached for the session
if (!this.context.graphInputTypes || this.context.graphInputTypes.length === 0 || !this.context.graphInputDims ||
this.context.graphInputDims.length === 0) {
const modelInputIndices = this._model.graph.getInputIndices();
const modelValues = this._model.graph.getValues();
const graphInputDims = new Array(modelInputIndices.length);
for (let i = 0; i < modelInputIndices.length; ++i) {
const graphInput = modelValues[modelInputIndices[i]];
graphInputDims[i] = graphInput.type.shape.dims;
// cached for second and subsequent runs.
// Some parts of the framework works on the assumption that the graph and types and shapes are static
this.context.graphInputTypes.push(graphInput.type.tensorType);
this.context.graphInputDims.push(inputs[i].dims);
}
this.validateInputTensorDims(graphInputDims, inputs, true);
}
// Second and subsequent session runs - graph input data is cached for the session
else {
this.validateInputTensorDims(this.context.graphInputDims, inputs, false);
}
// validate types requirement
this.validateInputTensorTypes(this.context.graphInputTypes, inputs);
return inputs;
}
validateInputTensorTypes(graphInputTypes, givenInputs) {
for (let i = 0; i < givenInputs.length; i++) {
const expectedType = graphInputTypes[i];
const actualType = givenInputs[i].type;
if (expectedType !== actualType) {
throw new Error(`input tensor[${i}] check failed: expected type '${expectedType}' but got ${actualType}`);
}
}
}
validateInputTensorDims(graphInputDims, givenInputs, noneDimSupported) {
for (let i = 0; i < givenInputs.length; i++) {
const expectedDims = graphInputDims[i];
const actualDims = givenInputs[i].dims;
if (!this.compareTensorDims(expectedDims, actualDims, noneDimSupported)) {
throw new Error(`input tensor[${i}] check failed: expected shape '[${expectedDims.join(',')}]' but got [${actualDims.join(',')}]`);
}
}
}
compareTensorDims(expectedDims, actualDims, noneDimSupported) {
if (expectedDims.length !== actualDims.length) {
return false;
}
for (let i = 0; i < expectedDims.length; ++i) {
if (expectedDims[i] !== actualDims[i] && (!noneDimSupported || expectedDims[i] !== 0)) {
// data shape mis-match AND not a 'None' dimension.
return false;
}
}
return true;
}
createOutput(outputTensors) {
const modelOutputNames = this._model.graph.getOutputNames();
if (outputTensors.length !== modelOutputNames.length) {
throw new Error('expected number of outputs do not match number of generated outputs');
}
const output = new Map();
for (let i = 0; i < modelOutputNames.length; ++i) {
output.set(modelOutputNames[i], outputTensors[i]);
}
return output;
}
initializeOps(graph) {
const nodes = graph.getNodes();
this._ops = new Array(nodes.length);
for (let i = 0; i < nodes.length; i++) {
this._ops[i] = this.sessionHandler.resolve(nodes[i], this._model.opsets, graph);
}
}
}
exports.Session = Session;
/***/ }),
/***/ "./lib/onnxjs/tensor.ts":
/*!******************************!*\
!*** ./lib/onnxjs/tensor.ts ***!
\******************************/
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.Tensor = void 0;
const guid_typescript_1 = __webpack_require__(/*! guid-typescript */ "./node_modules/guid-typescript/dist/guid.js");
const long_1 = __importDefault(__webpack_require__(/*! long */ "./node_modules/long/src/long.js"));
const onnx_proto_1 = __webpack_require__(/*! onnx-proto */ "./node_modules/onnx-proto/dist/onnx.js");
const ort_generated_1 = __webpack_require__(/*! ./ort-schema/ort-generated */ "./lib/onnxjs/ort-schema/ort-generated.ts");
const util_1 = __webpack_require__(/*! ./util */ "./lib/onnxjs/util.ts");
var ortFbs = ort_generated_1.onnxruntime.experimental.fbs;
class Tensor {
/**
* get the underlying tensor data
*/
get data() {
if (this.cache === undefined) {
const data = this.dataProvider(this.dataId);
if (data.length !== this.size) {
throw new Error('Length of data provided by the Data Provider is inconsistent with the dims of this Tensor.');
}
this.cache = data;
}
return this.cache;
}
/**
* get the underlying string tensor data. Should only use when type is STRING
*/
get stringData() {
if (this.type !== 'string') {
throw new TypeError('data type is not string');
}
return this.data;
}
/**
* get the underlying integer tensor data. Should only use when type is one of the following: (UINT8, INT8, UINT16,
* INT16, INT32, UINT32, BOOL)
*/
get integerData() {
switch (this.type) {
case 'uint8':
case 'int8':
case 'uint16':
case 'int16':
case 'int32':
case 'uint32':
case 'bool':
return this.data;
default:
throw new TypeError('data type is not integer (uint8, int8, uint16, int16, int32, uint32, bool)');
}
}
/**
* get the underlying float tensor data. Should only use when type is one of the following: (FLOAT, DOUBLE)
*/
get floatData() {
switch (this.type) {
case 'float32':
case 'float64':
return this.data;
default:
throw new TypeError('data type is not float (float32, float64)');
}
}
/**
* get the underlying number tensor data. Should only use when type is one of the following: (UINT8, INT8, UINT16,
* INT16, INT32, UINT32, BOOL, FLOAT, DOUBLE)
*/
get numberData() {
if (this.type !== 'string') {
return this.data;
}
throw new TypeError('type cannot be non-number (string)');
}
/**
* get value of an element at the given indices
*/
get(indices) {
return this.data[util_1.ShapeUtil.indicesToOffset(indices, this.strides)];
}
/**
* set value of an element at the given indices
*/
set(indices, value) {
this.data[util_1.ShapeUtil.indicesToOffset(indices, this.strides)] = value;
}
/**
* get the underlying tensor data asynchronously
*/
async getData() {
if (this.cache === undefined) {
this.cache = await this.asyncDataProvider(this.dataId);
}
return this.cache;
}
/**
* get the strides for each dimension
*/
get strides() {
if (!this._strides) {
this._strides = util_1.ShapeUtil.computeStrides(this.dims);
}
return this._strides;
}
constructor(
/**
* get the dimensions of the tensor
*/
dims,
/**
* get the type of the tensor
*/
type, dataProvider, asyncDataProvider, cache,
/**
* get the data ID that used to map to a tensor data
*/
dataId = guid_typescript_1.Guid.create()) {
this.dims = dims;
this.type = type;
this.dataProvider = dataProvider;
this.asyncDataProvider = asyncDataProvider;
this.cache = cache;
this.dataId = dataId;
this.size = util_1.ShapeUtil.validateDimsAndCalcSize(dims);
const size = this.size;
const empty = (dataProvider === undefined && asyncDataProvider === undefined && cache === undefined);
if (cache !== undefined) {
if (cache.length !== size) {
throw new RangeError('Input dims doesn\'t match data length.');
}
}
if (type === 'string') {
if (cache !== undefined && (!Array.isArray(cache) || !cache.every(i => typeof i === 'string'))) {
throw new TypeError('cache should be a string array');
}
if (empty) {
this.cache = new Array(size);
}
}
else {
if (cache !== undefined) {
const constructor = dataviewConstructor(type);
if (!(cache instanceof constructor)) {
throw new TypeError(`cache should be type ${constructor.name}`);
}
}
if (empty) {
const buf = new ArrayBuffer(size * sizeof(type));
this.cache = createView(buf, type);
}
}
}
/**
* Construct new Tensor from a ONNX Tensor object
* @param tensorProto the ONNX Tensor
*/
static fromProto(tensorProto) {
if (!tensorProto) {
throw new Error('cannot construct Value from an empty tensor');
}
const type = util_1.ProtoUtil.tensorDataTypeFromProto(tensorProto.dataType);
const dims = util_1.ProtoUtil.tensorDimsFromProto(tensorProto.dims);
const value = new Tensor(dims, type);
if (type === 'string') {
// When it's STRING type, the value should always be stored in field
// 'stringData'
tensorProto.stringData.forEach((str, i) => {
value.data[i] = (0, util_1.decodeUtf8String)(str);
});
}
else if (tensorProto.rawData && typeof tensorProto.rawData.byteLength === 'number' &&
tensorProto.rawData.byteLength > 0) {
// NOT considering segment for now (IMPORTANT)
// populate value from rawData
const dataDest = value.data;
const dataSource = new DataView(tensorProto.rawData.buffer, tensorProto.rawData.byteOffset, tensorProto.rawData.byteLength);
const elementSize = sizeofProto(tensorProto.dataType);
const length = tensorProto.rawData.byteLength / elementSize;
if (tensorProto.rawData.byteLength % elementSize !== 0) {
throw new Error('invalid buffer length');
}
if (dataDest.length !== length) {
throw new Error('buffer length mismatch');
}
for (let i = 0; i < length; i++) {
const n = readProto(dataSource, tensorProto.dataType, i * elementSize);
dataDest[i] = n;
}
}
else {
// populate value from array
let array;
switch (tensorProto.dataType) {
case onnx_proto_1.onnx.TensorProto.DataType.FLOAT:
array = tensorProto.floatData;
break;
case onnx_proto_1.onnx.TensorProto.DataType.INT32:
case onnx_proto_1.onnx.TensorProto.DataType.INT16:
case onnx_proto_1.onnx.TensorProto.DataType.UINT16:
case onnx_proto_1.onnx.TensorProto.DataType.INT8:
case onnx_proto_1.onnx.TensorProto.DataType.UINT8:
case onnx_proto_1.onnx.TensorProto.DataType.BOOL:
array = tensorProto.int32Data;
break;
case onnx_proto_1.onnx.TensorProto.DataType.INT64:
array = tensorProto.int64Data;
break;
case onnx_proto_1.onnx.TensorProto.DataType.DOUBLE:
array = tensorProto.doubleData;
break;
case onnx_proto_1.onnx.TensorProto.DataType.UINT32:
case onnx_proto_1.onnx.TensorProto.DataType.UINT64:
array = tensorProto.uint64Data;
break;
default:
// should never run here
throw new Error('unspecific error');
}
if (array === null || array === undefined) {
throw new Error('failed to populate data from a tensorproto value');
}
const data = value.data;
if (data.length !== array.length) {
throw new Error('array length mismatch');
}
for (let i = 0; i < array.length; i++) {
const element = array[i];
if (long_1.default.isLong(element)) {
data[i] = longToNumber(element, tensorProto.dataType);
}
else {
data[i] = element;
}
}
}
return value;
}
/**
* Construct new Tensor from raw data
* @param data the raw data object. Should be a string array for 'string' tensor, and the corresponding typed array
* for other types of tensor.
* @param dims the dimensions of the tensor
* @param type the type of the tensor
*/
static fromData(data, dims, type) {
return new Tensor(dims, type, undefined, undefined, data);
}
static fromOrtTensor(ortTensor) {
if (!ortTensor) {
throw new Error('cannot construct Value from an empty tensor');
}
const dims = util_1.ProtoUtil.tensorDimsFromORTFormat(ortTensor);
const type = util_1.ProtoUtil.tensorDataTypeFromProto(ortTensor.dataType());
const value = new Tensor(dims, type);
if (type === 'string') {
// When it's STRING type, the value should always be stored in field
// 'stringData'
for (let i = 0; i < ortTensor.stringDataLength(); i++) {
value.data[i] = ortTensor.stringData(i);
}
}
else if (ortTensor.rawDataArray() && typeof ortTensor.rawDataLength() === 'number' && ortTensor.rawDataLength() > 0) {
// NOT considering segment for now (IMPORTANT)
// populate value from rawData
const dataDest = value.data;
const dataSource = new DataView(ortTensor.rawDataArray().buffer, ortTensor.rawDataArray().byteOffset, ortTensor.rawDataLength());
const elementSize = sizeofProto(ortTensor.dataType());
const length = ortTensor.rawDataLength() / elementSize;
if (ortTensor.rawDataLength() % elementSize !== 0) {
throw new Error('invalid buffer length');
}
if (dataDest.length !== length) {
throw new Error('buffer length mismatch');
}
for (let i = 0; i < length; i++) {
const n = readProto(dataSource, ortTensor.dataType(), i * elementSize);
dataDest[i] = n;
}
}
return value;
}
}
exports.Tensor = Tensor;
function sizeof(type) {
switch (type) {
case 'bool':
case 'int8':
case 'uint8':
return 1;
case 'int16':
case 'uint16':
return 2;
case 'int32':
case 'uint32':
case 'float32':
return 4;
case 'float64':
return 8;
default:
throw new Error(`cannot calculate sizeof() on type ${type}`);
}
}
function sizeofProto(type) {
switch (type) {
case onnx_proto_1.onnx.TensorProto.DataType.UINT8:
case onnx_proto_1.onnx.TensorProto.DataType.INT8:
case onnx_proto_1.onnx.TensorProto.DataType.BOOL:
return 1;
case onnx_proto_1.onnx.TensorProto.DataType.UINT16:
case onnx_proto_1.onnx.TensorProto.DataType.INT16:
return 2;
case onnx_proto_1.onnx.TensorProto.DataType.FLOAT:
case onnx_proto_1.onnx.TensorProto.DataType.INT32:
case onnx_proto_1.onnx.TensorProto.DataType.UINT32:
return 4;
case onnx_proto_1.onnx.TensorProto.DataType.INT64:
case onnx_proto_1.onnx.TensorProto.DataType.DOUBLE:
case onnx_proto_1.onnx.TensorProto.DataType.UINT64:
return 8;
default:
throw new Error(`cannot calculate sizeof() on type ${onnx_proto_1.onnx.TensorProto.DataType[type]}`);
}
}
function createView(dataBuffer, type) {
return new (dataviewConstructor(type))(dataBuffer);
}
function dataviewConstructor(type) {
switch (type) {
case 'bool':
case 'uint8':
return Uint8Array;
case 'int8':
return Int8Array;
case 'int16':
return Int16Array;
case 'uint16':
return Uint16Array;
case 'int32':
return Int32Array;
case 'uint32':
return Uint32Array;
case 'float32':
return Float32Array;
case 'float64':
return Float64Array;
default:
// should never run to here
throw new Error('unspecified error');
}
}
// convert a long number to a 32-bit integer (cast-down)
function longToNumber(i, type) {
// INT64, UINT32, UINT64
if (type === onnx_proto_1.onnx.TensorProto.DataType.INT64 || type === ortFbs.TensorDataType.INT64) {
if (i.greaterThanOrEqual(2147483648) || i.lessThan(-2147483648)) {
throw new TypeError('int64 is not supported');
}
}
else if (type === onnx_proto_1.onnx.TensorProto.DataType.UINT32 || type === ortFbs.TensorDataType.UINT32 ||
type === onnx_proto_1.onnx.TensorProto.DataType.UINT64 || type === ortFbs.TensorDataType.UINT64) {
if (i.greaterThanOrEqual(4294967296) || i.lessThan(0)) {
throw new TypeError('uint64 is not supported');
}
}
else {
throw new TypeError(`not a LONG type: ${onnx_proto_1.onnx.TensorProto.DataType[type]}`);
}
return i.toNumber();
}
// read one value from TensorProto
function readProto(view, type, byteOffset) {
switch (type) {
case onnx_proto_1.onnx.TensorProto.DataType.BOOL:
case onnx_proto_1.onnx.TensorProto.DataType.UINT8:
return view.getUint8(byteOffset);
case onnx_proto_1.onnx.TensorProto.DataType.INT8:
return view.getInt8(byteOffset);
case onnx_proto_1.onnx.TensorProto.DataType.UINT16:
return view.getUint16(byteOffset, true);
case onnx_proto_1.onnx.TensorProto.DataType.INT16:
return view.getInt16(byteOffset, true);
case onnx_proto_1.onnx.TensorProto.DataType.FLOAT:
return view.getFloat32(byteOffset, true);
case onnx_proto_1.onnx.TensorProto.DataType.INT32:
return view.getInt32(byteOffset, true);
case onnx_proto_1.onnx.TensorProto.DataType.UINT32:
return view.getUint32(byteOffset, true);
case onnx_proto_1.onnx.TensorProto.DataType.INT64:
return longToNumber(long_1.default.fromBits(view.getUint32(byteOffset, true), view.getUint32(byteOffset + 4, true), false), type);
case onnx_proto_1.onnx.TensorProto.DataType.DOUBLE:
return view.getFloat64(byteOffset, true);
case onnx_proto_1.onnx.TensorProto.DataType.UINT64:
return longToNumber(long_1.default.fromBits(view.getUint32(byteOffset, true), view.getUint32(byteOffset + 4, true), true), type);
default:
throw new Error(`cannot read from DataView for type ${onnx_proto_1.onnx.TensorProto.DataType[type]}`);
}
}
/***/ }),
/***/ "./lib/onnxjs/util.ts":
/*!****************************!*\
!*** ./lib/onnxjs/util.ts ***!
\****************************/
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.decodeUtf8String = exports.MAX_CLIP = exports.MIN_CLIP = exports.PoolConvUtil = exports.ReduceUtil = exports.SplitUtil = exports.MathUtil = exports.ShapeUtil = exports.LongUtil = exports.ProtoUtil = exports.GemmUtil = exports.arrayCopyHelper = exports.BroadcastUtil = exports.MatMulUtil = exports.ArrayUtil = exports.assert = exports.checkInputsShape = void 0;
const flatbuffers_1 = __webpack_require__(/*! flatbuffers */ "./node_modules/flatbuffers/js/flatbuffers.mjs");
const long_1 = __importDefault(__webpack_require__(/*! long */ "./node_modules/long/src/long.js"));
const onnx_proto_1 = __webpack_require__(/*! onnx-proto */ "./node_modules/onnx-proto/dist/onnx.js");
const tensor_1 = __webpack_require__(/*! ./tensor */ "./lib/onnxjs/tensor.ts");
// check the inputs shape before running an OP.
// return true when the inputs pass the check
// return false when the inputs do not fit the requirement
// throw exception when fatal error or not implemented
function checkInputsShape(inputs, ...expectedDimensions) {
if (!inputs || inputs.length !== expectedDimensions.length) {
return false;
}
for (let i = 0; i < inputs.length; i++) {
if (!inputs[i].dims || inputs[i].dims.length !== expectedDimensions[i]) {
return false;
}
}
return true;
}
exports.checkInputsShape = checkInputsShape;
// Evaluates the given expression and asserts error message if condition is unmet.
function assert(expr, msg) {
if (!expr) {
throw new Error(typeof msg === 'string' ? msg : msg());
}
}
exports.assert = assert;
class ArrayUtil {
/**
* Verifies if 2 input arrays contain the same elements.
* @param n1 Array 1
* @param n2 Array 2
* @returns Whether these 2 are equal
*/
static arraysEqual(n1, n2) {
if (n1.length !== n2.length) {
return false;
}
for (let i = 0; i < n1.length; i++) {
if (n1[i] !== n2[i]) {
return false;
}
}
return true;
}
}
exports.ArrayUtil = ArrayUtil;
class MatMulUtil {
/**
* Fix the input shapes for MatMul operation if they need fixing
* @param dimsA The shape of tensor A. Should be an array of positive integers
* @param dimsB The shape of tensor B. Should be an array of positive integers
* @returns A tuple containing the preprocessed input shapes as required by ONNX specifications
*/
static preprocessInputShapes(dimsA, dimsB) {
// If the first argument is 1-D, it is promoted to a matrix by prepending
// a 1 to its dimensions. After matrix multiplication the prepended 1 is
// removed.
const a = (dimsA.length === 1) ? [1, dimsA[0]] : dimsA;
// If the second argument is 1-D, it is promoted to a matrix by appending
// a 1 to its dimensions. After matrix multiplication the appended 1 is
// removed.
const b = (dimsB.length === 1) ? [dimsB[0], 1] : dimsB;
return [a, b];
}
/**
* Fix the output shape computed for MatMul operation if it needs fixing
* @param outputShape The computed outputShape. Should be an array (atleast of length 2) of positive integers.
* This will be mutated.
* @param aRank The rank of tensor A.
* @param bRank The rank of tensor B.
*/
static postprocessOutputShape(outputShape, aRank, bRank) {
// Remove prepended dimension if first input is 1d
if (aRank === 1) {
// outputShape = outputShape.slice(0, outputShape.length - 2).concat(outputShape.slice(outputShape.length - 1));
outputShape.splice(outputShape.length - 2, 1);
}
// Remove appended dimension if second input is 1d
if (bRank === 1) {
outputShape.pop();
}
}
/**
* Calculate the expected shape when matrix multiplication
* @param a The shape of tensor A. Should be a tuple of 2 positive integers
* @param b The shape of tensor B. Should be a tuple of 2 positive integers
* @returns The expected shape of the result, or undefined if N/A
*/
static calcMatMulShape(a, b) {
return (a[1] !== b[0]) ? undefined : [a[0], b[1]];
}
}
exports.MatMulUtil = MatMulUtil;
class BroadcastUtil {
/**
* Calculate the expected shape when broadcasting 2 tensors
* @param a The shape of tensor A. Should be an array of positive integers
* @param b The shape of tensor B. Should be an array of positive integers
* @param isMatMul Whether the operation is MatMul
* @returns The expected shape of the result, or undefined if N/A
*/
static calcShape(adims, bdims, isMatMul = false) {
const arank = adims.length;
const brank = bdims.length;
if (arank === 0) {
return bdims;
}
if (brank === 0) {
return adims;
}
const crank = Math.max(adims.length, bdims.length);
const cdims = new Array(crank);
// calculate the last 2 dimension if it is MatMul
if (isMatMul) {
if (arank < 2 || brank < 2) {
return undefined;
}
const cShapeMatMul = MatMulUtil.calcMatMulShape([adims[arank - 2], adims[arank - 1]], [bdims[brank - 2], bdims[brank - 1]]);
if (cShapeMatMul === undefined) {
return undefined;
}
[cdims[crank - 2], cdims[crank - 1]] = cShapeMatMul;
}
for (let i = isMatMul ? 3 : 1; i <= crank; i++) {
const aLen = arank - i < 0 ? 1 : adims[arank - i];
const bLen = brank - i < 0 ? 1 : bdims[brank - i];
if (aLen !== bLen && aLen > 1 && bLen > 1) {
return undefined;
}
cdims[crank - i] = Math.max(aLen, bLen);
}
return cdims;
}
/**
* Given the indices of a broadcasted tensor, calculate the original indices
* @param broadcastedIndices The given indices of the broadcasted tensor.
* @param originalShape The original shape of the tensor before broadcas
* @returns The calculated indices that maps to the original tensor.
*/
static index(broadcastedIndices, originalShape) {
// NOTE 1: we assume the parameter broadcastedIndices is valid. ie. it should have the same
// length as the broadcasted shape, and for each dimension the index should
// not be out of range.
const originalIndices = new Array(originalShape.length);
BroadcastUtil.fillIndex(broadcastedIndices, originalShape, originalIndices);
return originalIndices;
}
/**
* Given the indices of a broadcasted tensor, calculate the original indices
* @param broadcastedIndices The given indices of the broadcasted tensor.
* @param originalShape The original shape of the tensor before broadcast
* @param originalIndices The mapping of broadcastedIndices to the originalIndices (output parameter - will be
* mutated).
*/
static fillIndex(broadcastedIndices, originalShape, originalIndices) {
// NOTE 1: we assume the parameter broadcastedIndices is valid. ie. it should have the same length as the
// broadcasted shape, and for each dimension the index should not be out of range.
// NOTE 2: we assume the parameter originalIndices has the same length as the originalShape
const dimOffset = broadcastedIndices.length - originalShape.length;
for (let i = 0; i < originalShape.length; i++) {
originalIndices[i] = broadcastedIndices[dimOffset + i] % originalShape[i];
}
}
/**
* Perform the broadcasting operation on the specific operator
* @param a The input tensor A
* @param b The input tensor B
* @param op The operator lambda function
* @param inplace Whether to write the result back to A.
* @returns The result tensor, or undefined if input not broadcastable.
*/
static calc(a, b, op, inplace, resultType) {
const outputShape = BroadcastUtil.calcShape(a.dims, b.dims);
if (outputShape) {
if (inplace && !ShapeUtil.areEqual(outputShape, a.dims)) {
// B is not broadcastable to A, failed to calculate inplace.
return undefined;
}
const size = ShapeUtil.size(outputShape);
const c = inplace ? a : new tensor_1.Tensor(outputShape, resultType || a.type);
// both inputs are scalars
if (outputShape.length === 0) {
c.set([], op(a.get([]), b.get([])));
}
// atleast one input is a non-scalar
else {
const outputIndices = new Array(outputShape.length);
const originalIndicesA = new Array(a.dims.length);
const originalIndicesB = new Array(b.dims.length);
let valA = 0;
let valB = 0;
let isAScalar = false;
let isBScalar = false;
if (a.dims.length === 0) {
valA = a.get([]);
isAScalar = true;
}
if (b.dims.length === 0) {
valB = b.get([]);
isBScalar = true;
}
let rest;
for (let i = 0; i < size; i++) {
// traversal indices
rest = i;
for (let j = outputShape.length - 1; j >= 0; j--) {
outputIndices[j] = rest % outputShape[j];
rest = Math.floor(rest / outputShape[j]);
}
if (!isAScalar) {
// map outputIndices (which is actually broadcasted) to the originalIndices
BroadcastUtil.fillIndex(outputIndices, a.dims, originalIndicesA);
valA = a.get(originalIndicesA);
}
if (!isBScalar) {
BroadcastUtil.fillIndex(outputIndices, b.dims, originalIndicesB);
valB = b.get(originalIndicesB);
}
c.set(outputIndices, op(valA, valB));
}
}
return c;
}
return undefined;
}
/**
* Determine if a shape is unidirectional broadcastable to another shape
* @param shape The input shape
* @param finalShape The desired shape after broadcasting
*/
static isValidBroadcast(shape, finalShape) {
// align shape to the right
const inputRank = shape.length;
const finalRank = finalShape.length;
if (inputRank > finalRank) {
return false;
}
for (let i = 1; i <= inputRank; i++) {
if (shape[inputRank - i] !== 1 && shape[inputRank - i] !== finalShape[finalRank - i]) {
return false;
}
}
return true;
}
/**
* Determine the broadcasted dims in input shape based on the given output shape.
* Note that this function only returns the broadcasted dims.
* @param inputShape The input shape
* @param outputShape The output shape
* @returns The broadcasted dims in input shape.
*/
static getBroadcastDims(inputShape, outputShape) {
const inRank = inputShape.length;
const dims = [];
for (let i = 0; i < inRank; i++) {
const dim = inRank - 1 - i;
const a = inputShape[dim] || 1;
const b = outputShape[outputShape.length - 1 - i] || 1;
if (b > 1 && a === 1) {
dims.unshift(dim);
}
}
return dims;
}
}
exports.BroadcastUtil = BroadcastUtil;
// copy array helper
// mimics memcpy as much as possible
function arrayCopyHelper(target, source, targetIndex, sourceIndex, blockSize) {
if (sourceIndex < 0 || sourceIndex >= source.length) {
throw new Error('sourceIndex out of bounds');
}
if (targetIndex < 0 || targetIndex >= target.length) {
throw new Error('targetIndex out of bounds');
}
if (sourceIndex + blockSize > source.length) {
throw new Error('source indices to be copied are outside bounds');
}
if (targetIndex + blockSize > target.length) {
throw new Error('target array is too small to hold result');
}
for (let offset = 0; offset < blockSize; offset++) {
target[targetIndex + offset] = source[sourceIndex + offset];
}
}
exports.arrayCopyHelper = arrayCopyHelper;
class GemmUtil {
// will make sure input shapes are compatible for this op
// and return back the shape of the output in the form of a tuple
// will throw exception if the input shapes are not compatible
static getShapeOfGemmResult(leftShape, transLeft, rightShape, transRight, biasShape) {
if (leftShape.length !== 2 || rightShape.length !== 2) {
throw new Error('shape need to be of size 2');
}
let M;
let K;
let N;
if (transLeft) {
M = leftShape[1];
K = leftShape[0];
}
else {
M = leftShape[0];
K = leftShape[1];
}
let kDim = -1;
if (transRight) {
N = rightShape[0];
kDim = 1;
}
else {
N = rightShape[1];
kDim = 0;
}
if (rightShape[kDim] !== K) {
throw new Error('dimension mismatch');
}
if (M <= 0 || N <= 0 || K <= 0) {
throw new Error('invalid shape specified');
}
if (biasShape && !BroadcastUtil.isValidBroadcast(biasShape, [M, N])) {
throw new Error('gemm: invalid bias shape for broadcast');
}
return [M, N, K];
}
}
exports.GemmUtil = GemmUtil;
class ProtoUtil {
static tensorDataTypeFromProto(typeProto) {
switch (typeProto) {
case onnx_proto_1.onnx.TensorProto.DataType.INT8:
return 'int8';
case onnx_proto_1.onnx.TensorProto.DataType.UINT8:
return 'uint8';
case onnx_proto_1.onnx.TensorProto.DataType.BOOL:
return 'bool';
case onnx_proto_1.onnx.TensorProto.DataType.INT16:
return 'int16';
case onnx_proto_1.onnx.TensorProto.DataType.UINT16:
return 'uint16';
case onnx_proto_1.onnx.TensorProto.DataType.INT32:
return 'int32';
case onnx_proto_1.onnx.TensorProto.DataType.UINT32:
return 'uint32';
case onnx_proto_1.onnx.TensorProto.DataType.FLOAT:
return 'float32';
case onnx_proto_1.onnx.TensorProto.DataType.DOUBLE:
return 'float64';
case onnx_proto_1.onnx.TensorProto.DataType.STRING:
return 'string';
// For INT64/UINT64, reduce their value to 32-bits.
// Should throw exception when overflow
case onnx_proto_1.onnx.TensorProto.DataType.INT64:
return 'int32';
case onnx_proto_1.onnx.TensorProto.DataType.UINT64:
return 'uint32';
default:
throw new Error(`unsupported data type: ${onnx_proto_1.onnx.TensorProto.DataType[typeProto]}`);
}
}
static tensorDataTypeStringToEnum(type) {
switch (type) {
case 'int8':
return onnx_proto_1.onnx.TensorProto.DataType.INT8;
case 'uint8':
return onnx_proto_1.onnx.TensorProto.DataType.UINT8;
case 'bool':
return onnx_proto_1.onnx.TensorProto.DataType.BOOL;
case 'int16':
return onnx_proto_1.onnx.TensorProto.DataType.INT16;
case 'uint16':
return onnx_proto_1.onnx.TensorProto.DataType.UINT16;
case 'int32':
return onnx_proto_1.onnx.TensorProto.DataType.INT32;
case 'uint32':
return onnx_proto_1.onnx.TensorProto.DataType.UINT32;
case 'float32':
return onnx_proto_1.onnx.TensorProto.DataType.FLOAT;
case 'float64':
return onnx_proto_1.onnx.TensorProto.DataType.DOUBLE;
case 'string':
return onnx_proto_1.onnx.TensorProto.DataType.STRING;
case 'int64':
return onnx_proto_1.onnx.TensorProto.DataType.INT64;
case 'uint64':
return onnx_proto_1.onnx.TensorProto.DataType.UINT64;
default:
throw new Error(`unsupported data type: ${type}`);
}
}
static tensorDimsFromProto(dims) {
// get rid of Long type for dims
return dims.map(d => long_1.default.isLong(d) ? d.toNumber() : d);
}
static tensorValueTypeFromProto(valueType) {
return {
tensorType: ProtoUtil.tensorDataTypeFromProto(valueType.elemType),
shape: { dims: ProtoUtil.tensorDimsFromProto(valueType.shape.dim.map(d => d.dimValue)) }
};
}
static tensorDimsFromORTFormat(tensor) {
const dims = [];
for (let i = 0; i < tensor.dimsLength(); i++) {
dims.push(LongUtil.longToNumber(tensor.dims(i)));
}
return dims;
}
static tensorAttributesFromORTFormat(node) {
const attributes = [];
for (let i = 0; i < node.attributesLength(); i++) {
attributes.push(node.attributes(i));
}
return attributes;
}
}
exports.ProtoUtil = ProtoUtil;
class LongUtil {
// This function is called to get a number from long type of data for attribute, dim, and ir version,
// which values are signed integers.
// To make it more generic, add an optional paramter to convert to a unsigned number.
static longToNumber(n, unsigned) {
if (long_1.default.isLong(n)) {
return n.toNumber();
}
else if (n instanceof flatbuffers_1.flatbuffers.Long) {
return long_1.default.fromValue({ low: n.low, high: n.high, unsigned: unsigned !== null && unsigned !== void 0 ? unsigned : false }).toNumber();
}
return n;
}
static isLong(n) {
return long_1.default.isLong(n) || n instanceof flatbuffers_1.flatbuffers.Long;
}
}
exports.LongUtil = LongUtil;
class ShapeUtil {
static size(dims) {
return ShapeUtil.getSizeFromDimensionRange(dims, 0, dims.length);
}
// `axis` inclusive
static sizeFromDimension(dims, axis) {
if (axis < 0 || axis > dims.length) {
throw new Error(`invalid dimension of ${axis} for sizeFromDimension as Tensor has ${dims.length} dimensions.`);
}
return ShapeUtil.getSizeFromDimensionRange(dims, axis, dims.length);
}
// `axis` exclusive
static sizeToDimension(dims, axis) {
if (axis < 0 || axis > dims.length) {
throw new Error(`invalid dimension of ${axis} for sizeToDimension as Tensor has ${dims.length} dimensions.`);
}
return ShapeUtil.getSizeFromDimensionRange(dims, 0, axis);
}
static getSizeFromDimensionRange(dims, start, end) {
let size = 1;
for (let i = start; i < end; i++) {
// safety check as this method is called by multiple other methods requiring size.
// size cannot be 0 or negative.
if (dims[i] <= 0) {
throw new Error(
// eslint-disable-next-line max-len
'cannot get valid size from specified dimension range. Most likely the range contains 0 or negative values in them.');
}
size *= dims[i];
}
return size;
}
static computeStrides(dims) {
const rank = dims.length;
if (rank === 0) {
return [];
}
else if (rank === 1) {
return [1];
}
const strides = new Array(rank);
strides[rank - 1] = 1;
strides[rank - 2] = dims[rank - 1];
for (let i = rank - 3; i >= 0; --i) {
strides[i] = strides[i + 1] * dims[i + 1];
}
return strides;
}
static transpose(dims) {
const copy = dims.slice();
return copy.reverse();
}
static indicesToOffset(indices, strides, axis) {
if (axis === undefined) {
axis = indices.length;
}
let offset = 0;
for (let i = 0; i < axis; ++i) {
offset += strides[i] * indices[i];
}
return offset;
}
static offsetToIndices(offset, strides) {
const rank = strides.length;
if (rank === 0) {
return [];
}
else if (rank === 1) {
return [offset * strides[0]];
}
const indices = new Array(strides.length);
for (let i = 0; i < indices.length - 1; ++i) {
indices[i] = Math.floor(offset / strides[i]);
offset -= indices[i] * strides[i];
}
indices[indices.length - 1] = offset;
return indices;
}
/**
* normailze axis of range [-r, r) into [0, r).
*/
static normalizeAxis(axis, tensorRank) {
if (axis < -tensorRank && axis >= tensorRank) {
throw new Error('unsupported axis for this operation.');
}
return axis < 0 ? axis + tensorRank : axis;
}
static normalizeAxes(axes, tensorRank) {
return axes.map(x => this.normalizeAxis(x, tensorRank));
}
// Increment an index into a tensor (in lexicographic
// ordering), wrapping around the specified upper_bound.
/**
* Increment an index into a tensor (in lexicographic ordering), wrapping around the specified upper_bound.
* @param index Given index to increment (Will be mutated)
* @param dims The dimensions of the tensor for which the given index corresponds to
* @param axisToIncrementOn The 1-indexed axis to increment on. If undefined, axisToIncrementOn == rank
*/
static incrementIndex(index, dims, axisToIncrementOn) {
if (dims.length === 0 || index.length === 0) {
throw new Error('Index incrementing unsupported for scalar Tensor');
}
if (axisToIncrementOn === undefined) {
axisToIncrementOn = dims.length;
}
else {
if (axisToIncrementOn <= 0 || axisToIncrementOn > dims.length) {
throw new Error('Incorrect axis to increment on');
}
}
for (let k = axisToIncrementOn - 1; k >= 0; --k) {
index[k]++;
if (index[k] < dims[k]) {
break;
}
index[k] = 0;
}
}
/**
* Produces a new dimensions array based on the values in the 'originalDimensions' and 'shape' array
* Used in Reshape
* @param originalDims Original Shape array
* @param shapeHints array containing values to compute the new dimensions
* For example:
* originalDims = [2,2] and shapeHints = [0,-1] will return [2,2]
* originalDims = [2,2] and shapeHints = [4] will return [4]
* originalDims = [2,2] and shapeHints = [5] will throw an exception
* https://github.com/onnx/onnx/blob/main/docs/Operators.md#Reshape
*/
static calculateReshapedDims(originalDims, shapeHints) {
// reshape to a Scalar Tensor
if (shapeHints.length === 0) {
if (originalDims.length === 0 || ShapeUtil.size(originalDims) === 1) {
return [];
}
else {
throw new Error('cannot reshape to a scalar Tensor');
}
}
const nDims = shapeHints.length;
const reshapedDims = new Array(nDims);
let unknownDimension = -1;
let newTensorSize = 1;
for (let i = 0; i < nDims; i++) {
if (shapeHints[i] < -1) {
throw new Error('a dimension in shape hints cannot be less than -1');
}
if (shapeHints[i] === -1) {
if (unknownDimension !== -1) {
throw new Error('at most one dimension in shape hints can be -1');
}
unknownDimension = i;
}
else {
if (shapeHints[i] === 0) {
if (i >= originalDims.length) {
throw new Error('the dimension with value zero exceeds the dimension size of the input tensor');
}
reshapedDims[i] = originalDims[i];
}
else {
reshapedDims[i] = shapeHints[i];
}
newTensorSize *= reshapedDims[i];
}
}
const oldTensorSize = ShapeUtil.size(originalDims);
if (unknownDimension !== -1) {
if (oldTensorSize % newTensorSize !== 0) {
throw new Error(`the input tensor cannot be reshaped to the requested shape. Input shape: [${originalDims}] Output shape: [${shapeHints}]`);
}
reshapedDims[unknownDimension] = oldTensorSize / newTensorSize;
}
// validate sizes from originalDims and reshapedDims match
else {
if (newTensorSize !== oldTensorSize) {
throw new Error('reshapedDims and originalDims don\'t have matching sizes');
}
}
return reshapedDims;
}
/**
* Sorts a given array based on the indices in the Perm array
* Used in Transpose
* @param a Array to be sorted such as dims or strides
* @param perm Perm given; if null a will be reversed
*/
static sortBasedOnPerm(a, perm) {
if (perm) {
return perm.map((v) => a[v]);
}
else {
return a.slice().reverse();
}
}
/**
* Pads a given shape according to the padding values
* @param dims shape of the Tensor to be padded
* @param pad pad values
*/
static padShape(dims, pad) {
const rank = dims.length;
return dims.map((v, i) => v + pad[i] + pad[i + rank]);
}
/**
* Determines if the two shapes are identical
* @param shape1
* @param shape2
*/
static areEqual(shape1, shape2) {
if (shape1.length !== shape2.length) {
return false;
}
return shape1.every((v, i) => v === shape2[i]);
}
/**
* Validates if the given `dims` or `shape` is valid in ONNX.js context and returns data size
* @param dims - input `dims` that needs to be checked
*/
static validateDimsAndCalcSize(dims) {
if (dims.length > 6) {
throw new TypeError('Only rank 0 to 6 is supported for tensor shape.');
}
let size = 1;
for (const n of dims) {
if (!Number.isInteger(n)) {
throw new TypeError(`Invalid shape: ${n} is not an integer`);
}
if (n < 0 || n > 2147483647) {
throw new TypeError(`Invalid shape: length ${n} is not allowed`);
}
size *= n;
}
return size;
}
/**
* Determines the shape of output tensor y = flatten(x, axis)
* @param dims - shape of input tensor
* @param axis - flatten axis, in the range [-r, r]
*/
static flattenShape(dims, axis) {
if (axis < 0) {
axis += dims.length;
}
const total = dims.reduce((x, y) => x * y, 1);
const right = dims.slice(axis).reduce((x, y) => x * y, 1);
const outputDims = [total / right, right];
return outputDims;
}
/**
* Determines the shape of output tensor y = squeeze(x, axes)
* @param dims - shape of input tensor
* @param axes - squeeze axes
*/
static squeezeShape(dims, axes) {
const outputDims = new Array();
// sanity check
axes = ShapeUtil.normalizeAxes(axes, dims.length);
for (let i = 0; i < dims.length; i++) {
const inSqueezeList = axes.indexOf(i) >= 0;
if (inSqueezeList && dims[i] !== 1) {
throw new Error('squeeze an axis of size different than 1');
}
if ((axes.length === 0 && dims[i] > 1) || (axes.length > 0 && !inSqueezeList)) {
outputDims.push(dims[i]);
}
}
return outputDims;
}
/**
* Determines the shape of output tensor y = unsqueeze(x, axes)
* @param dims - shape of input tensor
* @param axes - unsqueeze axes
*/
static unsqueezeShape(dims, axes) {
const outputDims = new Array(dims.length + axes.length);
// initialize the array elements to 0
outputDims.fill(0);
// set all axes indices to 1 in outputDims and check for duplicates
for (let i = 0; i < axes.length; i++) {
const axis = ShapeUtil.normalizeAxis(axes[i], outputDims.length);
if (axis >= outputDims.length) {
throw new Error('\'axes\' has an out of range axis');
}
if (outputDims[axis] !== 0) {
throw new Error('\'axes\' has a duplicate axis');
}
outputDims[axis] = 1;
}
// fill in the zero entries of outputDims with the input tensor's shape
let inputDimsIterator = 0;
for (let i = 0; i < outputDims.length; i++) {
if (outputDims[i] === 0) {
outputDims[i] = dims[inputDimsIterator++];
}
}
// sanity check assertion. 'inputDimsIterator'
// should be equal to the length of 'dims'
if (inputDimsIterator !== dims.length) {
throw new Error('the unsqueezed dimension could not be established');
}
return outputDims;
}
}
exports.ShapeUtil = ShapeUtil;
// bunch of helper methods that do a variety of math operations
class MathUtil {
// y = (x*x) + y
static sqr(target, source, targetIndex, sourceIndex, blockSize) {
if (sourceIndex < 0 || sourceIndex >= source.length) {
throw new Error('sourceIndex out of bounds');
}
if (targetIndex < 0 || targetIndex >= target.length) {
throw new Error('targetIndex out of bounds');
}
if (sourceIndex + blockSize > source.length) {
throw new Error('source indices to be copied are outside bounds');
}
if (targetIndex + blockSize > target.length) {
throw new Error('target array is too small to hold result');
}
for (let offset = 0; offset < blockSize; offset++) {
target[targetIndex + offset] += Math.pow(source[sourceIndex + offset], 2);
}
}
// y = ax + y
static axpy(target, source, targetIndex, sourceIndex, blockSize, alpha) {
if (sourceIndex < 0 || sourceIndex >= source.length) {
throw new Error('sourceIndex out of bounds');
}
if (targetIndex < 0 || targetIndex >= target.length) {
throw new Error('targetIndex out of bounds');
}
if (sourceIndex + blockSize > source.length) {
throw new Error('source indices to be copied are outside bounds');
}
if (targetIndex + blockSize > target.length) {
throw new Error('target array is too small to hold result');
}
for (let offset = 0; offset < blockSize; offset++) {
target[targetIndex + offset] += (alpha * source[sourceIndex + offset]);
}
}
// y = pow(x, b)
static powx(target, source, targetIndex, sourceIndex, blockSize, b) {
if (sourceIndex < 0 || sourceIndex >= source.length) {
throw new Error('sourceIndex out of bounds');
}
if (targetIndex < 0 || targetIndex >= target.length) {
throw new Error('targetIndex out of bounds');
}
if (sourceIndex + blockSize > source.length) {
throw new Error('source indices to be copied are outside bounds');
}
if (targetIndex + blockSize > target.length) {
throw new Error('target array is too small to hold result');
}
for (let offset = 0; offset < blockSize; offset++) {
target[targetIndex + offset] = Math.pow(source[sourceIndex + offset], b);
}
}
// y = x * y
static mul(target, source, targetIndex, sourceIndex, blockSize) {
if (sourceIndex < 0 || sourceIndex >= source.length) {
throw new Error('sourceIndex out of bounds');
}
if (targetIndex < 0 || targetIndex >= target.length) {
throw new Error('targetIndex out of bounds');
}
if (sourceIndex + blockSize > source.length) {
throw new Error('source indices to be copied are outside bounds');
}
if (targetIndex + blockSize > target.length) {
throw new Error('target array is too small to hold result');
}
for (let offset = 0; offset < blockSize; offset++) {
target[targetIndex + offset] = (source[sourceIndex + offset] * target[targetIndex + offset]);
}
}
}
exports.MathUtil = MathUtil;
class SplitUtil {
/**
* Calculates new Shapes from existing one and the splits given along the axis provides
* @param dims Shape of the Tensor to be splitted into two or more Shapes
* @param axis The dimension along which the Tensor will be split
* @param splits Offsets for the start of each split
*/
static splitShape(dims, axis, split, numOutputs) {
if (split.length === 0) {
if (!numOutputs) {
throw new Error('need to know number of outputs when the \'split\' attribute is not specified');
}
SplitUtil.determineSplit(dims[axis], numOutputs, split);
}
const shapes = [];
const offsets = [0];
for (let i = 0; i < split.length; ++i) {
if (i !== 0) {
offsets.push(offsets[i - 1] + split[i - 1]);
}
const shape = dims.slice();
shape[axis] = split[i];
shapes.push(shape);
}
return [shapes, offsets];
}
static determineSplit(numElementsAlongAxis, numOutputs, split) {
// If 'split' is not specified by the user, we need to partition the number of elements equally among the outputs
if (numElementsAlongAxis % numOutputs !== 0) {
throw new Error('cannot split tensor to equal sized parts');
}
for (let i = 0; i < numOutputs; ++i) {
split.push(numElementsAlongAxis / numOutputs);
}
}
}
exports.SplitUtil = SplitUtil;
class ReduceUtil {
/**
* Perform reduce operations on the specific operator
* @param a Input tensor data
* @param axes The dimensions along which the Tensor will be reduced
* @param keepdims If set to true, the axes which are reduced are left in the
* result as dimensions with size one.
* @param op1 The operation to be performed on each element in the tensor
* @param op2 The operation to be performed between elements in the tensor
*/
static calcReduce(a, axes, keepdims, op1, op2) {
const dims = a.dims.slice(0);
// if axes is not set, perform reduce on all axes
if (axes.length === 0) {
dims.forEach((d, ind) => axes.push(ind));
}
// get a temporary broadcastable output shape
const outputDims = ReduceUtil.calcReduceShape(dims, axes, true);
// loop through the output and calculate result one by one
const size = ShapeUtil.size(outputDims);
const y = new tensor_1.Tensor(outputDims, a.type);
const strides = ShapeUtil.computeStrides(outputDims);
const inputStrides = ShapeUtil.computeStrides(dims);
const indicesY = new Array(dims.length);
for (let i = 0; i < size; i++) {
const indices = ShapeUtil.offsetToIndices(i, strides);
// map index
BroadcastUtil.fillIndex(indices, dims, indicesY);
y.set(indices, ReduceUtil.calcReduceByAxis(a.numberData, axes, dims, 0, ShapeUtil.indicesToOffset(indicesY, inputStrides), op1, op2));
}
if (keepdims) {
return y;
}
else {
// keepdims == 0, calculate the expected shape
return new tensor_1.Tensor(ReduceUtil.calcReduceShape(dims, axes, keepdims), y.type, undefined, undefined, y.data, y.dataId);
}
}
/**
* Perform reduce operations on the specific operator on specific axes
* @param a Input tensor data
* @param axes The dimensions along which the Tensor will be reduced
* @param dims The input dimension.
* @param curAxisInd Index in axes specifying the current dimension along
* which the tensor will be reduced
* @param pos The current index of element to perform operation
* @param op1 The operation to be performed on each element in the tensor
* @param op2 The operation to be performed between elements in the tensor
*/
static calcReduceByAxis(input, axes, dims, curAxisInd, pos, op1, op2) {
let res = 0;
if (curAxisInd >= axes.length) {
return op1(input[pos]);
}
const axis = axes[curAxisInd];
const step = axis >= dims.length ? 1 : ShapeUtil.size(dims.slice(axis + 1));
for (let i = 0; i < dims[axis]; i++) {
res = i === 0 ? ReduceUtil.calcReduceByAxis(input, axes, dims, curAxisInd + 1, pos, op1, op2) :
op2(res, ReduceUtil.calcReduceByAxis(input, axes, dims, curAxisInd + 1, pos, op1, op2));
pos += step;
}
return res;
}
/**
* Calculate the expected shape of a reduce operation
* @param dims The input tensor dimension
* @param axes The dimensions along which the Tensor will be reduced
* @param keepdims If set to true, the axes which are reduced are left in the
* result as dimensions with size one.
*/
static calcReduceShape(dims, axes, keepDims) {
const outputDims = dims.slice();
for (let i = 0; i < axes.length; i++) {
if (keepDims) {
outputDims[axes[i]] = 1;
}
else {
outputDims[axes[i]] = 0;
}
}
return outputDims.filter(dim => dim !== 0);
}
}
exports.ReduceUtil = ReduceUtil;
class PoolConvUtil {
/**
* Adjust the kernel, strides, pads to correct rank. Set to default value if not present
* @param isGlobalOperator If true, perform global pooling.
* @param inputDims The input tensor dimension.
* @param kernelShape The size of the kernel along each axis.
* @param strides Stride along each axis.
* @param dilations Dilation along each axis.
* @param pads Padding for the beginning and ending along each axis.
*/
static adjustPoolAttributes(isGlobalOperator, inputDims, kernelShape, strides, dilations, pads) {
if (!isGlobalOperator && kernelShape.length !== inputDims.length - 2) {
throw new Error('length of specified kernel shapes should be 2 less than length of input dimensions');
}
if (isGlobalOperator) {
// adjust kernel shape to cover the input dims
for (let dim = 0; dim < inputDims.length - 2; dim++) {
if (dim >= kernelShape.length) {
kernelShape.push(inputDims[dim + 2]);
}
else {
kernelShape[dim] = inputDims[dim + 2];
}
}
}
// adjust strides length to match kernel shape length
for (let dim = 0; dim < kernelShape.length; dim++) {
if (dim < strides.length) {
if (strides[dim] < 0) {
throw new Error('strides should be greater than or equal to 1');
}
}
else {
strides.push(1);
}
}
// adjust dilation value
for (let dim = 0; dim < kernelShape.length; dim++) {
if (dim < dilations.length) {
if (dilations[dim] < 0) {
throw new Error('dilations should be greater than or equal to 1');
}
}
else {
dilations.push(1);
}
}
// adjust pads length to match 2 * kernel shape length
for (let dim = 0; dim < kernelShape.length * 2; dim++) {
if (dim < pads.length) {
if (pads[dim] < 0) {
throw new Error('pad should be greater than or equal to 1');
}
}
else {
pads.push(0);
}
}
// sanity checks for values in kernel shapes and pads
for (let dim = 0; dim < kernelShape.length; dim++) {
if (kernelShape[dim] <= 0) {
throw new Error('kernel shapes need to be greater than 0');
}
if (pads[dim] >= kernelShape[dim] || pads[dim + kernelShape.length] >= kernelShape[dim]) {
throw new Error('pads should be smaller than kernel');
}
}
}
// adjust pad values based on 'autoPad' attribute
static adjustPadsBasedOnAutoPad(inputDims, strides, dilations, kernelShape, pads, autoPad) {
if (!autoPad) {
return;
}
if (pads.length !== 2 * (inputDims.length - 2)) {
throw new Error('length of pads should be twice the length of data dimensions');
}
if (strides.length !== (inputDims.length - 2)) {
throw new Error('length of strides should be the length of data dimensions');
}
if (kernelShape.length !== (inputDims.length - 2)) {
throw new Error('length of kernel shapes should be the length of data dimensions');
}
for (let dim = 0; dim < inputDims.length - 2; dim++) {
PoolConvUtil.adjustPadAndReturnShape(inputDims[dim + 2], strides[dim], dilations[dim], kernelShape[dim], pads, dim, dim + inputDims.length - 2, autoPad);
}
}
/**
* Calculate the output shape for Pool ops based on input attributes. (Should be used only for Pool ops)
* @param isGlobalOperator If true, perform global pooling.
* @param inputDims The input tensor dimension. (inputs[0].dims)
* @param strides Stride along each axis.
* @param dilations Dilation along each axis.
* @param kernelShape The size of the kernel along each axis.
* @param pads Padding for the beginning and ending along each axis.
* @param autoPad DEPRECATED attribute supported for legacy models. Specifies how to implicitly calculate pads in each
* dimension. Can take values NOTSET, SAME_UPPER, SAME_LOWER, or VALID.
*/
static computePoolOutputShape(isGlobalOperator, inputDims, strides, dilations, kernelShape, pads, autoPad) {
if (inputDims.length <= 0) {
throw new Error('input shape must be of size greater than 0');
}
// Add batch size and number of channels of output
const outputDims = [inputDims[0], inputDims[1]];
PoolConvUtil.computeShapeHelper(isGlobalOperator, inputDims, outputDims, strides, dilations, kernelShape, pads, autoPad);
return outputDims;
}
/**
* Calculate the output shape for Conv op based on input attributes. (Should be used only for Conv op)
* @param inputDims The input tensor dimension. (inputs[0].dims)
* @param filterDims The filter tensor dimension. (inputs[1].dims)
* @param strides Stride along each axis.
* @param kernelShape The size of the kernel along each axis.
* @param pads Padding for the beginning and ending along each axis.
* @param autoPad DEPRECATED attribute supported for legacy models. Specifies how to implicitly calculate pads in each
* dimension. Can take values NOTSET, SAME_UPPER, SAME_LOWER, or VALID.
*/
static computeConvOutputShape(inputDims, filterDims, strides, dilations, kernelShape, pads, autoPad) {
if (inputDims.length <= 0 || filterDims.length <= 0) {
throw new Error('invalid input tensor dims or invalid filter tensor dims');
}
// Add batch size and number of channels of output
const outputDims = [inputDims[0], filterDims[0]];
PoolConvUtil.computeShapeHelper(false, inputDims, outputDims, strides, dilations, kernelShape, pads, autoPad);
return outputDims;
}
// will compute output shapes for data dimensions ONLY (i.e.) no batch size and channels
// called by computePoolOutputShape() and computeConvOutputShape()
// adjust pads based on 'autoPad' attribute prior to shape computation
static computeShapeHelper(isGlobalOperator, inputDims, outputDims, strides, dilations, kernelShape, pads, autoPad) {
if (isGlobalOperator) {
for (let dim = 0; dim < inputDims.length - 2; dim++) {
outputDims.push(1);
}
}
else {
for (let dim = 0; dim < inputDims.length - 2; dim++) {
outputDims.push(PoolConvUtil.adjustPadAndReturnShape(inputDims[dim + 2], strides[dim], dilations[dim], kernelShape[dim], pads, dim, dim + inputDims.length - 2, autoPad));
}
}
}
// helper for computeShapeHelper() and adjustPadsBasedOnAutoPad()
// adjusts pad value for given 'autoPad' string and computes output shape along a particular dimension
static adjustPadAndReturnShape(inSize, stride, dilation, kernel, pads, padHeadIndex, padTailIndex, autoPad) {
const dkernel = dilation * (kernel - 1) + 1;
if (autoPad && autoPad !== 'NOTSET') {
switch (autoPad) {
case 'VALID':
pads[padHeadIndex] = 0;
pads[padTailIndex] = 0;
return Math.floor(((inSize - dkernel) / stride) + 1);
case 'SAME_LOWER':
case 'SAME_UPPER':
if (dilation !== 1) {
throw new Error('Dilation not supported for SAME_UPPER or SAME_LOWER');
}
else {
const legacyTargetSize = (inSize + stride - 1) / stride;
const padNeeded = (legacyTargetSize - 1) * stride + kernel - inSize;
pads[padHeadIndex] =
(autoPad === 'SAME_LOWER') ? Math.floor((padNeeded + 1) / 2) : Math.floor(padNeeded / 2);
pads[padTailIndex] = padNeeded - pads[padHeadIndex];
return Math.floor(((inSize + padNeeded - kernel) / stride) + 1);
}
default:
throw new Error('Unsupported AutoPad type');
}
}
else {
return Math.floor(((inSize + pads[padHeadIndex] + pads[padTailIndex] - dkernel) / stride) + 1);
}
}
}
exports.PoolConvUtil = PoolConvUtil;
exports.MIN_CLIP = -3.4028234663852886e+38;
exports.MAX_CLIP = 3.4028234663852886e+38;
function decodeUtf8String(buffer) {
return new TextDecoder().decode(buffer);
}
exports.decodeUtf8String = decodeUtf8String;
/***/ }),
/***/ "./lib/wasm/options-utils.ts":
/*!***********************************!*\
!*** ./lib/wasm/options-utils.ts ***!
\***********************************/
/***/ ((__unused_webpack_module, exports) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.iterateExtraOptions = void 0;
const iterateExtraOptions = (options, prefix, seen, handler) => {
if (typeof options == 'object' && options !== null) {
if (seen.has(options)) {
throw new Error('Circular reference in options');
}
else {
seen.add(options);
}
}
Object.entries(options).forEach(([key, value]) => {
const name = (prefix) ? prefix + key : key;
if (typeof value === 'object') {
(0, exports.iterateExtraOptions)(value, name + '.', seen, handler);
}
else if (typeof value === 'string' || typeof value === 'number') {
handler(name, value.toString());
}
else if (typeof value === 'boolean') {
handler(name, (value) ? '1' : '0');
}
else {
throw new Error(`Can't handle extra config type: ${typeof value}`);
}
});
};
exports.iterateExtraOptions = iterateExtraOptions;
/***/ }),
/***/ "./lib/wasm/proxy-wrapper.ts":
/*!***********************************!*\
!*** ./lib/wasm/proxy-wrapper.ts ***!
\***********************************/
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var _a;
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.endProfiling = exports.run = exports.releaseSession = exports.createSession = exports.createSessionFinalize = exports.createSessionAllocate = exports.initOrt = exports.initWasm = void 0;
const onnxruntime_common_1 = __webpack_require__(/*! onnxruntime-common */ "onnxruntime-common");
const core = __importStar(__webpack_require__(/*! ./wasm-core-impl */ "./lib/wasm/wasm-core-impl.ts"));
const wasm_factory_1 = __webpack_require__(/*! ./wasm-factory */ "./lib/wasm/wasm-factory.ts");
const isProxy = () => !!onnxruntime_common_1.env.wasm.proxy && typeof document !== 'undefined';
let proxyWorker;
let initializing = false;
let initialized = false;
let aborted = false;
let initWasmCallbacks;
let initOrtCallbacks;
const createSessionAllocateCallbacks = [];
const createSessionFinalizeCallbacks = [];
const createSessionCallbacks = [];
const releaseSessionCallbacks = [];
const runCallbacks = [];
const endProfilingCallbacks = [];
const ensureWorker = () => {
if (initializing || !initialized || aborted || !proxyWorker) {
throw new Error('worker not ready');
}
};
const onProxyWorkerMessage = (ev) => {
switch (ev.data.type) {
case 'init-wasm':
initializing = false;
if (ev.data.err) {
aborted = true;
initWasmCallbacks[1](ev.data.err);
}
else {
initialized = true;
initWasmCallbacks[0]();
}
break;
case 'init-ort':
if (ev.data.err) {
initOrtCallbacks[1](ev.data.err);
}
else {
initOrtCallbacks[0]();
}
break;
case 'create_allocate':
if (ev.data.err) {
createSessionAllocateCallbacks.shift()[1](ev.data.err);
}
else {
createSessionAllocateCallbacks.shift()[0](ev.data.out);
}
break;
case 'create_finalize':
if (ev.data.err) {
createSessionFinalizeCallbacks.shift()[1](ev.data.err);
}
else {
createSessionFinalizeCallbacks.shift()[0](ev.data.out);
}
break;
case 'create':
if (ev.data.err) {
createSessionCallbacks.shift()[1](ev.data.err);
}
else {
createSessionCallbacks.shift()[0](ev.data.out);
}
break;
case 'release':
if (ev.data.err) {
releaseSessionCallbacks.shift()[1](ev.data.err);
}
else {
releaseSessionCallbacks.shift()[0]();
}
break;
case 'run':
if (ev.data.err) {
runCallbacks.shift()[1](ev.data.err);
}
else {
runCallbacks.shift()[0](ev.data.out);
}
break;
case 'end-profiling':
if (ev.data.err) {
endProfilingCallbacks.shift()[1](ev.data.err);
}
else {
endProfilingCallbacks.shift()[0]();
}
break;
default:
}
};
const scriptSrc = typeof document !== 'undefined' ? (_a = document === null || document === void 0 ? void 0 : document.currentScript) === null || _a === void 0 ? void 0 : _a.src : undefined;
const initWasm = async () => {
if ( true && isProxy()) {
if (initialized) {
return;
}
if (initializing) {
throw new Error('multiple calls to \'initWasm()\' detected.');
}
if (aborted) {
throw new Error('previous call to \'initWasm()\' failed.');
}
initializing = true;
// overwrite wasm filepaths
if (onnxruntime_common_1.env.wasm.wasmPaths === undefined) {
if (scriptSrc && scriptSrc.indexOf('blob:') !== 0) {
onnxruntime_common_1.env.wasm.wasmPaths = scriptSrc.substr(0, +(scriptSrc).lastIndexOf('/') + 1);
}
}
return new Promise((resolve, reject) => {
proxyWorker === null || proxyWorker === void 0 ? void 0 : proxyWorker.terminate();
// eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports
proxyWorker = (__webpack_require__(/*! worker-loader?inline=no-fallback!./proxy-worker/main */ "./node_modules/worker-loader/dist/cjs.js?inline=no-fallback!./lib/wasm/proxy-worker/main.ts")["default"])();
proxyWorker.onmessage = onProxyWorkerMessage;
initWasmCallbacks = [resolve, reject];
const message = { type: 'init-wasm', in: onnxruntime_common_1.env.wasm };
proxyWorker.postMessage(message);
});
}
else {
return (0, wasm_factory_1.initializeWebAssembly)(onnxruntime_common_1.env.wasm);
}
};
exports.initWasm = initWasm;
const initOrt = async (numThreads, loggingLevel) => {
if ( true && isProxy()) {
ensureWorker();
return new Promise((resolve, reject) => {
initOrtCallbacks = [resolve, reject];
const message = { type: 'init-ort', in: { numThreads, loggingLevel } };
proxyWorker.postMessage(message);
});
}
else {
core.initOrt(numThreads, loggingLevel);
}
};
exports.initOrt = initOrt;
const createSessionAllocate = async (model) => {
if ( true && isProxy()) {
ensureWorker();
return new Promise((resolve, reject) => {
createSessionAllocateCallbacks.push([resolve, reject]);
const message = { type: 'create_allocate', in: { model } };
proxyWorker.postMessage(message, [model.buffer]);
});
}
else {
return core.createSessionAllocate(model);
}
};
exports.createSessionAllocate = createSessionAllocate;
const createSessionFinalize = async (modeldata, options) => {
if ( true && isProxy()) {
ensureWorker();
return new Promise((resolve, reject) => {
createSessionFinalizeCallbacks.push([resolve, reject]);
const message = { type: 'create_finalize', in: { modeldata, options } };
proxyWorker.postMessage(message);
});
}
else {
return core.createSessionFinalize(modeldata, options);
}
};
exports.createSessionFinalize = createSessionFinalize;
const createSession = async (model, options) => {
if ( true && isProxy()) {
ensureWorker();
return new Promise((resolve, reject) => {
createSessionCallbacks.push([resolve, reject]);
const message = { type: 'create', in: { model, options } };
proxyWorker.postMessage(message, [model.buffer]);
});
}
else {
return core.createSession(model, options);
}
};
exports.createSession = createSession;
const releaseSession = async (sessionId) => {
if ( true && isProxy()) {
ensureWorker();
return new Promise((resolve, reject) => {
releaseSessionCallbacks.push([resolve, reject]);
const message = { type: 'release', in: sessionId };
proxyWorker.postMessage(message);
});
}
else {
core.releaseSession(sessionId);
}
};
exports.releaseSession = releaseSession;
const run = async (sessionId, inputIndices, inputs, outputIndices, options) => {
if ( true && isProxy()) {
ensureWorker();
return new Promise((resolve, reject) => {
runCallbacks.push([resolve, reject]);
const message = { type: 'run', in: { sessionId, inputIndices, inputs, outputIndices, options } };
proxyWorker.postMessage(message, core.extractTransferableBuffers(inputs));
});
}
else {
return core.run(sessionId, inputIndices, inputs, outputIndices, options);
}
};
exports.run = run;
const endProfiling = async (sessionId) => {
if ( true && isProxy()) {
ensureWorker();
return new Promise((resolve, reject) => {
endProfilingCallbacks.push([resolve, reject]);
const message = { type: 'end-profiling', in: sessionId };
proxyWorker.postMessage(message);
});
}
else {
core.endProfiling(sessionId);
}
};
exports.endProfiling = endProfiling;
/***/ }),
/***/ "./lib/wasm/run-options.ts":
/*!*********************************!*\
!*** ./lib/wasm/run-options.ts ***!
\*********************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.setRunOptions = void 0;
const options_utils_1 = __webpack_require__(/*! ./options-utils */ "./lib/wasm/options-utils.ts");
const string_utils_1 = __webpack_require__(/*! ./string-utils */ "./lib/wasm/string-utils.ts");
const wasm_factory_1 = __webpack_require__(/*! ./wasm-factory */ "./lib/wasm/wasm-factory.ts");
const setRunOptions = (options) => {
const wasm = (0, wasm_factory_1.getInstance)();
let runOptionsHandle = 0;
const allocs = [];
const runOptions = options || {};
try {
if ((options === null || options === void 0 ? void 0 : options.logSeverityLevel) === undefined) {
runOptions.logSeverityLevel = 2; // Default to warning
}
else if (typeof options.logSeverityLevel !== 'number' || !Number.isInteger(options.logSeverityLevel) ||
options.logSeverityLevel < 0 || options.logSeverityLevel > 4) {
throw new Error(`log serverity level is not valid: ${options.logSeverityLevel}`);
}
if ((options === null || options === void 0 ? void 0 : options.logVerbosityLevel) === undefined) {
runOptions.logVerbosityLevel = 0; // Default to 0
}
else if (typeof options.logVerbosityLevel !== 'number' || !Number.isInteger(options.logVerbosityLevel)) {
throw new Error(`log verbosity level is not valid: ${options.logVerbosityLevel}`);
}
if ((options === null || options === void 0 ? void 0 : options.terminate) === undefined) {
runOptions.terminate = false;
}
let tagDataOffset = 0;
if ((options === null || options === void 0 ? void 0 : options.tag) !== undefined) {
tagDataOffset = (0, string_utils_1.allocWasmString)(options.tag, allocs);
}
runOptionsHandle = wasm._OrtCreateRunOptions(runOptions.logSeverityLevel, runOptions.logVerbosityLevel, !!runOptions.terminate, tagDataOffset);
if (runOptionsHandle === 0) {
throw new Error('Can\'t create run options');
}
if ((options === null || options === void 0 ? void 0 : options.extra) !== undefined) {
(0, options_utils_1.iterateExtraOptions)(options.extra, '', new WeakSet(), (key, value) => {
const keyDataOffset = (0, string_utils_1.allocWasmString)(key, allocs);
const valueDataOffset = (0, string_utils_1.allocWasmString)(value, allocs);
if (wasm._OrtAddRunConfigEntry(runOptionsHandle, keyDataOffset, valueDataOffset) !== 0) {
throw new Error(`Can't set a run config entry: ${key} - ${value}`);
}
});
}
return [runOptionsHandle, allocs];
}
catch (e) {
if (runOptionsHandle !== 0) {
wasm._OrtReleaseRunOptions(runOptionsHandle);
}
allocs.forEach(wasm._free);
throw e;
}
};
exports.setRunOptions = setRunOptions;
/***/ }),
/***/ "./lib/wasm/session-handler.ts":
/*!*************************************!*\
!*** ./lib/wasm/session-handler.ts ***!
\*************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.OnnxruntimeWebAssemblySessionHandler = void 0;
const fs_1 = __webpack_require__(/*! fs */ "?295d");
const onnxruntime_common_1 = __webpack_require__(/*! onnxruntime-common */ "onnxruntime-common");
const util_1 = __webpack_require__(/*! util */ "?cf98");
const proxy_wrapper_1 = __webpack_require__(/*! ./proxy-wrapper */ "./lib/wasm/proxy-wrapper.ts");
let ortInit;
const getLogLevel = (logLevel) => {
switch (logLevel) {
case 'verbose':
return 0;
case 'info':
return 1;
case 'warning':
return 2;
case 'error':
return 3;
case 'fatal':
return 4;
default:
throw new Error(`unsupported logging level: ${logLevel}`);
}
};
class OnnxruntimeWebAssemblySessionHandler {
async createSessionAllocate(path) {
// fetch model from url and move to wasm heap. The arraybufffer that held the http
// response is freed once we return
const response = await fetch(path);
const arrayBuffer = await response.arrayBuffer();
return (0, proxy_wrapper_1.createSessionAllocate)(new Uint8Array(arrayBuffer));
}
async loadModel(pathOrBuffer, options) {
if (!ortInit) {
await (0, proxy_wrapper_1.initOrt)(onnxruntime_common_1.env.wasm.numThreads, getLogLevel(onnxruntime_common_1.env.logLevel));
ortInit = true;
}
if (typeof pathOrBuffer === 'string') {
if (typeof fetch === 'undefined') {
// node
const model = await (0, util_1.promisify)(fs_1.readFile)(pathOrBuffer);
[this.sessionId, this.inputNames, this.outputNames] = await (0, proxy_wrapper_1.createSession)(model, options);
}
else {
// browser
// fetch model and move to wasm heap.
const modelData = await this.createSessionAllocate(pathOrBuffer);
// create the session
[this.sessionId, this.inputNames, this.outputNames] = await (0, proxy_wrapper_1.createSessionFinalize)(modelData, options);
}
}
else {
[this.sessionId, this.inputNames, this.outputNames] = await (0, proxy_wrapper_1.createSession)(pathOrBuffer, options);
}
}
async dispose() {
return (0, proxy_wrapper_1.releaseSession)(this.sessionId);
}
async run(feeds, fetches, options) {
const inputArray = [];
const inputIndices = [];
Object.entries(feeds).forEach(kvp => {
const name = kvp[0];
const tensor = kvp[1];
const index = this.inputNames.indexOf(name);
if (index === -1) {
throw new Error(`invalid input '${name}'`);
}
inputArray.push(tensor);
inputIndices.push(index);
});
const outputIndices = [];
Object.entries(fetches).forEach(kvp => {
const name = kvp[0];
// TODO: support pre-allocated output
const index = this.outputNames.indexOf(name);
if (index === -1) {
throw new Error(`invalid output '${name}'`);
}
outputIndices.push(index);
});
const outputs = await (0, proxy_wrapper_1.run)(this.sessionId, inputIndices, inputArray.map(t => [t.type, t.dims, t.data]), outputIndices, options);
const result = {};
for (let i = 0; i < outputs.length; i++) {
result[this.outputNames[outputIndices[i]]] = new onnxruntime_common_1.Tensor(outputs[i][0], outputs[i][2], outputs[i][1]);
}
return result;
}
startProfiling() {
// TODO: implement profiling
}
endProfiling() {
void (0, proxy_wrapper_1.endProfiling)(this.sessionId);
}
}
exports.OnnxruntimeWebAssemblySessionHandler = OnnxruntimeWebAssemblySessionHandler;
/***/ }),
/***/ "./lib/wasm/session-options.ts":
/*!*************************************!*\
!*** ./lib/wasm/session-options.ts ***!
\*************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.setSessionOptions = void 0;
const options_utils_1 = __webpack_require__(/*! ./options-utils */ "./lib/wasm/options-utils.ts");
const string_utils_1 = __webpack_require__(/*! ./string-utils */ "./lib/wasm/string-utils.ts");
const wasm_factory_1 = __webpack_require__(/*! ./wasm-factory */ "./lib/wasm/wasm-factory.ts");
const getGraphOptimzationLevel = (graphOptimizationLevel) => {
switch (graphOptimizationLevel) {
case 'disabled':
return 0;
case 'basic':
return 1;
case 'extended':
return 2;
case 'all':
return 99;
default:
throw new Error(`unsupported graph optimization level: ${graphOptimizationLevel}`);
}
};
const getExecutionMode = (executionMode) => {
switch (executionMode) {
case 'sequential':
return 0;
case 'parallel':
return 1;
default:
throw new Error(`unsupported execution mode: ${executionMode}`);
}
};
const appendDefaultOptions = (options) => {
if (!options.extra) {
options.extra = {};
}
if (!options.extra.session) {
options.extra.session = {};
}
const session = options.extra.session;
if (!session.use_ort_model_bytes_directly) {
// eslint-disable-next-line camelcase
session.use_ort_model_bytes_directly = '1';
}
};
const setExecutionProviders = (sessionOptionsHandle, executionProviders, allocs) => {
for (const ep of executionProviders) {
let epName = typeof ep === 'string' ? ep : ep.name;
// check EP name
switch (epName) {
case 'xnnpack':
epName = 'XNNPACK';
break;
case 'wasm':
case 'cpu':
continue;
default:
throw new Error(`not supported EP: ${epName}`);
}
const epNameDataOffset = (0, string_utils_1.allocWasmString)(epName, allocs);
if ((0, wasm_factory_1.getInstance)()._OrtAppendExecutionProvider(sessionOptionsHandle, epNameDataOffset) !== 0) {
throw new Error(`Can't append execution provider: ${epName}`);
}
}
};
const setSessionOptions = (options) => {
const wasm = (0, wasm_factory_1.getInstance)();
let sessionOptionsHandle = 0;
const allocs = [];
const sessionOptions = options || {};
appendDefaultOptions(sessionOptions);
try {
if ((options === null || options === void 0 ? void 0 : options.graphOptimizationLevel) === undefined) {
sessionOptions.graphOptimizationLevel = 'all';
}
const graphOptimizationLevel = getGraphOptimzationLevel(sessionOptions.graphOptimizationLevel);
if ((options === null || options === void 0 ? void 0 : options.enableCpuMemArena) === undefined) {
sessionOptions.enableCpuMemArena = true;
}
if ((options === null || options === void 0 ? void 0 : options.enableMemPattern) === undefined) {
sessionOptions.enableMemPattern = true;
}
if ((options === null || options === void 0 ? void 0 : options.executionMode) === undefined) {
sessionOptions.executionMode = 'sequential';
}
const executionMode = getExecutionMode(sessionOptions.executionMode);
let logIdDataOffset = 0;
if ((options === null || options === void 0 ? void 0 : options.logId) !== undefined) {
logIdDataOffset = (0, string_utils_1.allocWasmString)(options.logId, allocs);
}
if ((options === null || options === void 0 ? void 0 : options.logSeverityLevel) === undefined) {
sessionOptions.logSeverityLevel = 2; // Default to warning
}
else if (typeof options.logSeverityLevel !== 'number' || !Number.isInteger(options.logSeverityLevel) ||
options.logSeverityLevel < 0 || options.logSeverityLevel > 4) {
throw new Error(`log serverity level is not valid: ${options.logSeverityLevel}`);
}
if ((options === null || options === void 0 ? void 0 : options.logVerbosityLevel) === undefined) {
sessionOptions.logVerbosityLevel = 0; // Default to 0
}
else if (typeof options.logVerbosityLevel !== 'number' || !Number.isInteger(options.logVerbosityLevel)) {
throw new Error(`log verbosity level is not valid: ${options.logVerbosityLevel}`);
}
if ((options === null || options === void 0 ? void 0 : options.enableProfiling) === undefined) {
sessionOptions.enableProfiling = false;
}
sessionOptionsHandle = wasm._OrtCreateSessionOptions(graphOptimizationLevel, !!sessionOptions.enableCpuMemArena, !!sessionOptions.enableMemPattern, executionMode, !!sessionOptions.enableProfiling, 0, logIdDataOffset, sessionOptions.logSeverityLevel, sessionOptions.logVerbosityLevel);
if (sessionOptionsHandle === 0) {
throw new Error('Can\'t create session options');
}
if (options === null || options === void 0 ? void 0 : options.executionProviders) {
setExecutionProviders(sessionOptionsHandle, options.executionProviders, allocs);
}
if ((options === null || options === void 0 ? void 0 : options.extra) !== undefined) {
(0, options_utils_1.iterateExtraOptions)(options.extra, '', new WeakSet(), (key, value) => {
const keyDataOffset = (0, string_utils_1.allocWasmString)(key, allocs);
const valueDataOffset = (0, string_utils_1.allocWasmString)(value, allocs);
if (wasm._OrtAddSessionConfigEntry(sessionOptionsHandle, keyDataOffset, valueDataOffset) !== 0) {
throw new Error(`Can't set a session config entry: ${key} - ${value}`);
}
});
}
return [sessionOptionsHandle, allocs];
}
catch (e) {
if (sessionOptionsHandle !== 0) {
wasm._OrtReleaseSessionOptions(sessionOptionsHandle);
}
allocs.forEach(wasm._free);
throw e;
}
};
exports.setSessionOptions = setSessionOptions;
/***/ }),
/***/ "./lib/wasm/string-utils.ts":
/*!**********************************!*\
!*** ./lib/wasm/string-utils.ts ***!
\**********************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.allocWasmString = void 0;
const wasm_factory_1 = __webpack_require__(/*! ./wasm-factory */ "./lib/wasm/wasm-factory.ts");
const allocWasmString = (data, allocs) => {
const wasm = (0, wasm_factory_1.getInstance)();
const dataLength = wasm.lengthBytesUTF8(data) + 1;
const dataOffset = wasm._malloc(dataLength);
wasm.stringToUTF8(data, dataOffset, dataLength);
allocs.push(dataOffset);
return dataOffset;
};
exports.allocWasmString = allocWasmString;
/***/ }),
/***/ "./lib/wasm/wasm-core-impl.ts":
/*!************************************!*\
!*** ./lib/wasm/wasm-core-impl.ts ***!
\************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.extractTransferableBuffers = exports.endProfiling = exports.run = exports.releaseSession = exports.createSession = exports.createSessionFinalize = exports.createSessionAllocate = exports.initOrt = void 0;
const run_options_1 = __webpack_require__(/*! ./run-options */ "./lib/wasm/run-options.ts");
const session_options_1 = __webpack_require__(/*! ./session-options */ "./lib/wasm/session-options.ts");
const string_utils_1 = __webpack_require__(/*! ./string-utils */ "./lib/wasm/string-utils.ts");
const wasm_factory_1 = __webpack_require__(/*! ./wasm-factory */ "./lib/wasm/wasm-factory.ts");
/**
* initialize ORT environment.
* @param numThreads SetGlobalIntraOpNumThreads(numThreads)
* @param loggingLevel CreateEnv(static_cast<OrtLoggingLevel>(logging_level))
*/
const initOrt = (numThreads, loggingLevel) => {
const errorCode = (0, wasm_factory_1.getInstance)()._OrtInit(numThreads, loggingLevel);
if (errorCode !== 0) {
throw new Error(`Can't initialize onnxruntime. error code = ${errorCode}`);
}
};
exports.initOrt = initOrt;
const activeSessions = new Map();
/**
* create an instance of InferenceSession.
* @returns the metadata of InferenceSession. 0-value handle for failure.
*/
const createSessionAllocate = (model) => {
const wasm = (0, wasm_factory_1.getInstance)();
const modelDataOffset = wasm._malloc(model.byteLength);
wasm.HEAPU8.set(model, modelDataOffset);
return [modelDataOffset, model.byteLength];
};
exports.createSessionAllocate = createSessionAllocate;
const createSessionFinalize = (modelData, options) => {
const wasm = (0, wasm_factory_1.getInstance)();
let sessionHandle = 0;
let sessionOptionsHandle = 0;
let allocs = [];
try {
[sessionOptionsHandle, allocs] = (0, session_options_1.setSessionOptions)(options);
sessionHandle = wasm._OrtCreateSession(modelData[0], modelData[1], sessionOptionsHandle);
if (sessionHandle === 0) {
throw new Error('Can\'t create a session');
}
}
finally {
wasm._free(modelData[0]);
wasm._OrtReleaseSessionOptions(sessionOptionsHandle);
allocs.forEach(wasm._free);
}
const inputCount = wasm._OrtGetInputCount(sessionHandle);
const outputCount = wasm._OrtGetOutputCount(sessionHandle);
const inputNames = [];
const inputNamesUTF8Encoded = [];
const outputNames = [];
const outputNamesUTF8Encoded = [];
for (let i = 0; i < inputCount; i++) {
const name = wasm._OrtGetInputName(sessionHandle, i);
if (name === 0) {
throw new Error('Can\'t get an input name');
}
inputNamesUTF8Encoded.push(name);
inputNames.push(wasm.UTF8ToString(name));
}
for (let i = 0; i < outputCount; i++) {
const name = wasm._OrtGetOutputName(sessionHandle, i);
if (name === 0) {
throw new Error('Can\'t get an output name');
}
outputNamesUTF8Encoded.push(name);
outputNames.push(wasm.UTF8ToString(name));
}
activeSessions.set(sessionHandle, [sessionHandle, inputNamesUTF8Encoded, outputNamesUTF8Encoded]);
return [sessionHandle, inputNames, outputNames];
};
exports.createSessionFinalize = createSessionFinalize;
/**
* create an instance of InferenceSession.
* @returns the metadata of InferenceSession. 0-value handle for failure.
*/
const createSession = (model, options) => {
const modelData = (0, exports.createSessionAllocate)(model);
return (0, exports.createSessionFinalize)(modelData, options);
};
exports.createSession = createSession;
const releaseSession = (sessionId) => {
const wasm = (0, wasm_factory_1.getInstance)();
const session = activeSessions.get(sessionId);
if (!session) {
throw new Error('invalid session id');
}
const sessionHandle = session[0];
const inputNamesUTF8Encoded = session[1];
const outputNamesUTF8Encoded = session[2];
inputNamesUTF8Encoded.forEach(wasm._OrtFree);
outputNamesUTF8Encoded.forEach(wasm._OrtFree);
wasm._OrtReleaseSession(sessionHandle);
activeSessions.delete(sessionId);
};
exports.releaseSession = releaseSession;
const tensorDataTypeStringToEnum = (type) => {
switch (type) {
case 'int8':
return 3 /* DataType.int8 */;
case 'uint8':
return 2 /* DataType.uint8 */;
case 'bool':
return 9 /* DataType.bool */;
case 'int16':
return 5 /* DataType.int16 */;
case 'uint16':
return 4 /* DataType.uint16 */;
case 'int32':
return 6 /* DataType.int32 */;
case 'uint32':
return 12 /* DataType.uint32 */;
case 'float32':
return 1 /* DataType.float */;
case 'float64':
return 11 /* DataType.double */;
case 'string':
return 8 /* DataType.string */;
case 'int64':
return 7 /* DataType.int64 */;
case 'uint64':
return 13 /* DataType.uint64 */;
default:
throw new Error(`unsupported data type: ${type}`);
}
};
const tensorDataTypeEnumToString = (typeProto) => {
switch (typeProto) {
case 3 /* DataType.int8 */:
return 'int8';
case 2 /* DataType.uint8 */:
return 'uint8';
case 9 /* DataType.bool */:
return 'bool';
case 5 /* DataType.int16 */:
return 'int16';
case 4 /* DataType.uint16 */:
return 'uint16';
case 6 /* DataType.int32 */:
return 'int32';
case 12 /* DataType.uint32 */:
return 'uint32';
case 1 /* DataType.float */:
return 'float32';
case 11 /* DataType.double */:
return 'float64';
case 8 /* DataType.string */:
return 'string';
case 7 /* DataType.int64 */:
return 'int64';
case 13 /* DataType.uint64 */:
return 'uint64';
default:
throw new Error(`unsupported data type: ${typeProto}`);
}
};
const numericTensorTypeToTypedArray = (type) => {
switch (type) {
case 'float32':
return Float32Array;
case 'uint8':
return Uint8Array;
case 'int8':
return Int8Array;
case 'uint16':
return Uint16Array;
case 'int16':
return Int16Array;
case 'int32':
return Int32Array;
case 'bool':
return Uint8Array;
case 'float64':
return Float64Array;
case 'uint32':
return Uint32Array;
case 'int64':
return BigInt64Array;
case 'uint64':
return BigUint64Array;
default:
throw new Error(`unsupported type: ${type}`);
}
};
/**
* perform inference run
*/
const run = (sessionId, inputIndices, inputs, outputIndices, options) => {
const wasm = (0, wasm_factory_1.getInstance)();
const session = activeSessions.get(sessionId);
if (!session) {
throw new Error('invalid session id');
}
const sessionHandle = session[0];
const inputNamesUTF8Encoded = session[1];
const outputNamesUTF8Encoded = session[2];
const inputCount = inputIndices.length;
const outputCount = outputIndices.length;
let runOptionsHandle = 0;
let runOptionsAllocs = [];
const inputValues = [];
const inputAllocs = [];
try {
[runOptionsHandle, runOptionsAllocs] = (0, run_options_1.setRunOptions)(options);
// create input tensors
for (let i = 0; i < inputCount; i++) {
const dataType = inputs[i][0];
const dims = inputs[i][1];
const data = inputs[i][2];
let dataOffset;
let dataByteLength;
if (Array.isArray(data)) {
// string tensor
dataByteLength = 4 * data.length;
dataOffset = wasm._malloc(dataByteLength);
inputAllocs.push(dataOffset);
let dataIndex = dataOffset / 4;
for (let i = 0; i < data.length; i++) {
if (typeof data[i] !== 'string') {
throw new TypeError(`tensor data at index ${i} is not a string`);
}
wasm.HEAPU32[dataIndex++] = (0, string_utils_1.allocWasmString)(data[i], inputAllocs);
}
}
else {
dataByteLength = data.byteLength;
dataOffset = wasm._malloc(dataByteLength);
inputAllocs.push(dataOffset);
wasm.HEAPU8.set(new Uint8Array(data.buffer, data.byteOffset, dataByteLength), dataOffset);
}
const stack = wasm.stackSave();
const dimsOffset = wasm.stackAlloc(4 * dims.length);
try {
let dimIndex = dimsOffset / 4;
dims.forEach(d => wasm.HEAP32[dimIndex++] = d);
const tensor = wasm._OrtCreateTensor(tensorDataTypeStringToEnum(dataType), dataOffset, dataByteLength, dimsOffset, dims.length);
if (tensor === 0) {
throw new Error('Can\'t create a tensor');
}
inputValues.push(tensor);
}
finally {
wasm.stackRestore(stack);
}
}
const beforeRunStack = wasm.stackSave();
const inputValuesOffset = wasm.stackAlloc(inputCount * 4);
const inputNamesOffset = wasm.stackAlloc(inputCount * 4);
const outputValuesOffset = wasm.stackAlloc(outputCount * 4);
const outputNamesOffset = wasm.stackAlloc(outputCount * 4);
try {
let inputValuesIndex = inputValuesOffset / 4;
let inputNamesIndex = inputNamesOffset / 4;
let outputValuesIndex = outputValuesOffset / 4;
let outputNamesIndex = outputNamesOffset / 4;
for (let i = 0; i < inputCount; i++) {
wasm.HEAPU32[inputValuesIndex++] = inputValues[i];
wasm.HEAPU32[inputNamesIndex++] = inputNamesUTF8Encoded[inputIndices[i]];
}
for (let i = 0; i < outputCount; i++) {
wasm.HEAPU32[outputValuesIndex++] = 0;
wasm.HEAPU32[outputNamesIndex++] = outputNamesUTF8Encoded[outputIndices[i]];
}
// support RunOptions
let errorCode = wasm._OrtRun(sessionHandle, inputNamesOffset, inputValuesOffset, inputCount, outputNamesOffset, outputCount, outputValuesOffset, runOptionsHandle);
const output = [];
if (errorCode === 0) {
for (let i = 0; i < outputCount; i++) {
const tensor = wasm.HEAPU32[outputValuesOffset / 4 + i];
const beforeGetTensorDataStack = wasm.stackSave();
// stack allocate 4 pointer value
const tensorDataOffset = wasm.stackAlloc(4 * 4);
let type, dataOffset = 0;
try {
errorCode = wasm._OrtGetTensorData(tensor, tensorDataOffset, tensorDataOffset + 4, tensorDataOffset + 8, tensorDataOffset + 12);
if (errorCode !== 0) {
throw new Error(`Can't access output tensor data. error code = ${errorCode}`);
}
let tensorDataIndex = tensorDataOffset / 4;
const dataType = wasm.HEAPU32[tensorDataIndex++];
dataOffset = wasm.HEAPU32[tensorDataIndex++];
const dimsOffset = wasm.HEAPU32[tensorDataIndex++];
const dimsLength = wasm.HEAPU32[tensorDataIndex++];
const dims = [];
for (let i = 0; i < dimsLength; i++) {
dims.push(wasm.HEAPU32[dimsOffset / 4 + i]);
}
wasm._OrtFree(dimsOffset);
const size = dims.length === 0 ? 1 : dims.reduce((a, b) => a * b);
type = tensorDataTypeEnumToString(dataType);
if (type === 'string') {
const stringData = [];
let dataIndex = dataOffset / 4;
for (let i = 0; i < size; i++) {
const offset = wasm.HEAPU32[dataIndex++];
const maxBytesToRead = i === size - 1 ? undefined : wasm.HEAPU32[dataIndex] - offset;
stringData.push(wasm.UTF8ToString(offset, maxBytesToRead));
}
output.push([type, dims, stringData]);
}
else {
const typedArrayConstructor = numericTensorTypeToTypedArray(type);
const data = new typedArrayConstructor(size);
new Uint8Array(data.buffer, data.byteOffset, data.byteLength)
.set(wasm.HEAPU8.subarray(dataOffset, dataOffset + data.byteLength));
output.push([type, dims, data]);
}
}
finally {
wasm.stackRestore(beforeGetTensorDataStack);
if (type === 'string' && dataOffset) {
wasm._free(dataOffset);
}
wasm._OrtReleaseTensor(tensor);
}
}
}
if (errorCode === 0) {
return output;
}
else {
throw new Error(`failed to call OrtRun(). error code = ${errorCode}.`);
}
}
finally {
wasm.stackRestore(beforeRunStack);
}
}
finally {
inputValues.forEach(wasm._OrtReleaseTensor);
inputAllocs.forEach(wasm._free);
wasm._OrtReleaseRunOptions(runOptionsHandle);
runOptionsAllocs.forEach(wasm._free);
}
};
exports.run = run;
/**
* end profiling
*/
const endProfiling = (sessionId) => {
const wasm = (0, wasm_factory_1.getInstance)();
const session = activeSessions.get(sessionId);
if (!session) {
throw new Error('invalid session id');
}
const sessionHandle = session[0];
// profile file name is not used yet, but it must be freed.
const profileFileName = wasm._OrtEndProfiling(sessionHandle);
if (profileFileName === 0) {
throw new Error('Can\'t get an profile file name');
}
wasm._OrtFree(profileFileName);
};
exports.endProfiling = endProfiling;
const extractTransferableBuffers = (tensors) => {
const buffers = [];
for (const tensor of tensors) {
const data = tensor[2];
if (!Array.isArray(data) && data.buffer) {
buffers.push(data.buffer);
}
}
return buffers;
};
exports.extractTransferableBuffers = extractTransferableBuffers;
/***/ }),
/***/ "./lib/wasm/wasm-factory.ts":
/*!**********************************!*\
!*** ./lib/wasm/wasm-factory.ts ***!
\**********************************/
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
"use strict";
var __dirname = "/";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.dispose = exports.getInstance = exports.initializeWebAssembly = void 0;
const path = __importStar(__webpack_require__(/*! path */ "?7aa5"));
const ort_wasm_js_1 = __importDefault(__webpack_require__(/*! ./binding/ort-wasm.js */ "./lib/wasm/binding/ort-wasm.js"));
const ortWasmFactoryThreaded =
// eslint-disable-next-line @typescript-eslint/no-require-imports
true ? __webpack_require__(/*! ./binding/ort-wasm-threaded.js */ "./lib/wasm/binding/ort-wasm-threaded.js") : 0;
let wasm;
let initialized = false;
let initializing = false;
let aborted = false;
const isMultiThreadSupported = () => {
try {
// If 'SharedArrayBuffer' is not available, WebAssembly threads will not work.
if (typeof SharedArrayBuffer === 'undefined') {
return false;
}
// Test for transferability of SABs (for browsers. needed for Firefox)
// https://groups.google.com/forum/#!msg/mozilla.dev.platform/IHkBZlHETpA/dwsMNchWEQAJ
if (typeof MessageChannel !== 'undefined') {
new MessageChannel().port1.postMessage(new SharedArrayBuffer(1));
}
// Test for WebAssembly threads capability (for both browsers and Node.js)
// This typed array is a WebAssembly program containing threaded instructions.
return WebAssembly.validate(new Uint8Array([
0, 97, 115, 109, 1, 0, 0, 0, 1, 4, 1, 96, 0, 0, 3, 2, 1, 0, 5,
4, 1, 3, 1, 1, 10, 11, 1, 9, 0, 65, 0, 254, 16, 2, 0, 26, 11
]));
}
catch (e) {
return false;
}
};
const isSimdSupported = () => {
try {
// Test for WebAssembly SIMD capability (for both browsers and Node.js)
// This typed array is a WebAssembly program containing SIMD instructions.
// The binary data is generated from the following code by wat2wasm:
//
// (module
// (type $t0 (func))
// (func $f0 (type $t0)
// (drop
// (i32x4.dot_i16x8_s
// (i8x16.splat
// (i32.const 0))
// (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)))))
return WebAssembly.validate(new Uint8Array([
0, 97, 115, 109, 1, 0, 0, 0, 1, 4, 1, 96, 0, 0, 3, 2, 1, 0, 10, 30, 1, 28, 0, 65, 0,
253, 15, 253, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 253, 186, 1, 26, 11
]));
}
catch (e) {
return false;
}
};
const getWasmFileName = (useSimd, useThreads) => {
if (useThreads) {
return useSimd ? 'ort-wasm-simd-threaded.wasm' : 'ort-wasm-threaded.wasm';
}
else {
return useSimd ? 'ort-wasm-simd.wasm' : 'ort-wasm.wasm';
}
};
const initializeWebAssembly = async (flags) => {
if (initialized) {
return Promise.resolve();
}
if (initializing) {
throw new Error('multiple calls to \'initializeWebAssembly()\' detected.');
}
if (aborted) {
throw new Error('previous call to \'initializeWebAssembly()\' failed.');
}
initializing = true;
// wasm flags are already initialized
const timeout = flags.initTimeout;
const numThreads = flags.numThreads;
const simd = flags.simd;
const useThreads = numThreads > 1 && isMultiThreadSupported();
const useSimd = simd && isSimdSupported();
const wasmPrefixOverride = typeof flags.wasmPaths === 'string' ? flags.wasmPaths : undefined;
const wasmFileName = getWasmFileName(false, useThreads);
const wasmOverrideFileName = getWasmFileName(useSimd, useThreads);
const wasmPathOverride = typeof flags.wasmPaths === 'object' ? flags.wasmPaths[wasmOverrideFileName] : undefined;
let isTimeout = false;
const tasks = [];
// promise for timeout
if (timeout > 0) {
tasks.push(new Promise((resolve) => {
setTimeout(() => {
isTimeout = true;
resolve();
}, timeout);
}));
}
// promise for module initialization
tasks.push(new Promise((resolve, reject) => {
const factory = useThreads ? ortWasmFactoryThreaded : ort_wasm_js_1.default;
const config = {
locateFile: (fileName, scriptDirectory) => {
if ( true && useThreads && fileName.endsWith('.worker.js') &&
typeof Blob !== 'undefined') {
return URL.createObjectURL(new Blob([
// This require() function is handled by webpack to load file content of the corresponding .worker.js
// eslint-disable-next-line @typescript-eslint/no-require-imports
__webpack_require__(/*! ./binding/ort-wasm-threaded.worker.js */ "./lib/wasm/binding/ort-wasm-threaded.worker.js")
], { type: 'text/javascript' }));
}
if (fileName === wasmFileName) {
const prefix = wasmPrefixOverride !== null && wasmPrefixOverride !== void 0 ? wasmPrefixOverride : scriptDirectory;
return wasmPathOverride !== null && wasmPathOverride !== void 0 ? wasmPathOverride : prefix + wasmOverrideFileName;
}
return scriptDirectory + fileName;
}
};
if ( true && useThreads) {
if (typeof Blob === 'undefined') {
config.mainScriptUrlOrBlob = path.join(__dirname, 'ort-wasm-threaded.js');
}
else {
const scriptSourceCode = `var ortWasmThreaded=(function(){var _scriptDir;return ${factory.toString()}})();`;
config.mainScriptUrlOrBlob = new Blob([scriptSourceCode], { type: 'text/javascript' });
}
}
factory(config).then(
// wasm module initialized successfully
module => {
initializing = false;
initialized = true;
wasm = module;
resolve();
},
// wasm module failed to initialize
(what) => {
initializing = false;
aborted = true;
reject(what);
});
}));
await Promise.race(tasks);
if (isTimeout) {
throw new Error(`WebAssembly backend initializing failed due to timeout: ${timeout}ms`);
}
};
exports.initializeWebAssembly = initializeWebAssembly;
const getInstance = () => {
if (initialized && wasm) {
return wasm;
}
throw new Error('WebAssembly is not initialized yet.');
};
exports.getInstance = getInstance;
const dispose = () => {
var _a;
if (initialized && !initializing && !aborted) {
initializing = true;
(_a = wasm.PThread) === null || _a === void 0 ? void 0 : _a.terminateAllThreads();
wasm = undefined;
initializing = false;
initialized = false;
aborted = true;
}
};
exports.dispose = dispose;
/***/ }),
/***/ "./node_modules/worker-loader/dist/cjs.js?inline=no-fallback!./lib/wasm/proxy-worker/main.ts":
/*!***************************************************************************************************!*\
!*** ./node_modules/worker-loader/dist/cjs.js?inline=no-fallback!./lib/wasm/proxy-worker/main.ts ***!
\***************************************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (/* binding */ Worker_fn)
/* harmony export */ });
/* harmony import */ var _node_modules_worker_loader_dist_runtime_inline_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! !!../../../node_modules/worker-loader/dist/runtime/inline.js */ "./node_modules/worker-loader/dist/runtime/inline.js");
/* harmony import */ var _node_modules_worker_loader_dist_runtime_inline_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_worker_loader_dist_runtime_inline_js__WEBPACK_IMPORTED_MODULE_0__);
function Worker_fn() {
return _node_modules_worker_loader_dist_runtime_inline_js__WEBPACK_IMPORTED_MODULE_0___default()("/*!\n* ONNX Runtime Web v1.14.0\n* Copyright (c) Microsoft Corporation. All rights reserved.\n* Licensed under the MIT License.\n*/\n/******/ (() => { // webpackBootstrap\n/******/ \tvar __webpack_modules__ = ({\n\n/***/ \"./lib/wasm/binding/ort-wasm-threaded.js\":\n/*!***********************************************!*\\\n !*** ./lib/wasm/binding/ort-wasm-threaded.js ***!\n \\***********************************************/\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\nvar __filename = \"/index.js\";\nvar __dirname = \"/\";\n\r\nvar ortWasmThreaded = (() => {\r\n var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined;\r\n if (true) _scriptDir = _scriptDir || __filename;\r\n return (\r\nfunction(ortWasmThreaded) {\r\n ortWasmThreaded = ortWasmThreaded || {};\r\n\r\n\r\nfunction d(){m.buffer!=n&&p(m.buffer);return aa}function q(){m.buffer!=n&&p(m.buffer);return ba}function r(){m.buffer!=n&&p(m.buffer);return ca}function v(){m.buffer!=n&&p(m.buffer);return da}function ea(){m.buffer!=n&&p(m.buffer);return fa}var x;x||(x=typeof ortWasmThreaded !== 'undefined' ? ortWasmThreaded : {});var ha,ia;x.ready=new Promise(function(a,b){ha=a;ia=b});\r\nvar ja=Object.assign({},x),ka=\"./this.program\",la=(a,b)=>{throw b;},ma=\"object\"==typeof window,y=\"function\"==typeof importScripts,B=\"object\"==typeof process&&\"object\"==typeof process.versions&&\"string\"==typeof process.versions.node,C=x.ENVIRONMENT_IS_PTHREAD||!1,D=\"\";function na(a){return x.locateFile?x.locateFile(a,D):D+a}var oa,pa,qa,fs,ra,sa;\r\nif(B){D=y?(__webpack_require__(/*! path */ \"?75c6\").dirname)(D)+\"/\":__dirname+\"/\";sa=()=>{ra||(fs=__webpack_require__(/*! fs */ \"?63c8\"),ra=__webpack_require__(/*! path */ \"?75c6\"))};oa=function(b,c){sa();b=ra.normalize(b);return fs.readFileSync(b,c?void 0:\"utf8\")};qa=b=>{b=oa(b,!0);b.buffer||(b=new Uint8Array(b));return b};pa=(b,c,e)=>{sa();b=ra.normalize(b);fs.readFile(b,function(f,h){f?e(f):c(h.buffer)})};1<process.argv.length&&(ka=process.argv[1].replace(/\\\\/g,\"/\"));process.argv.slice(2);process.on(\"uncaughtException\",function(b){if(!(b instanceof E))throw b;});process.on(\"unhandledRejection\",\r\nfunction(b){throw b;});la=(b,c)=>{if(F())throw process.exitCode=b,c;c instanceof E||G(\"exiting due to exception: \"+c);process.exit(b)};x.inspect=function(){return\"[Emscripten Module object]\"};let a;try{a=__webpack_require__(/*! worker_threads */ \"?c6f7\")}catch(b){throw console.error('The \"worker_threads\" module is not supported in this node.js build - perhaps a newer version is needed?'),b;}__webpack_require__.g.Worker=a.Worker}else if(ma||y)y?D=self.location.href:\"undefined\"!=typeof document&&document.currentScript&&(D=document.currentScript.src),\r\n_scriptDir&&(D=_scriptDir),0!==D.indexOf(\"blob:\")?D=D.substr(0,D.replace(/[?#].*/,\"\").lastIndexOf(\"/\")+1):D=\"\",B||(oa=a=>{var b=new XMLHttpRequest;b.open(\"GET\",a,!1);b.send(null);return b.responseText},y&&(qa=a=>{var b=new XMLHttpRequest;b.open(\"GET\",a,!1);b.responseType=\"arraybuffer\";b.send(null);return new Uint8Array(b.response)}),pa=(a,b,c)=>{var e=new XMLHttpRequest;e.open(\"GET\",a,!0);e.responseType=\"arraybuffer\";e.onload=()=>{200==e.status||0==e.status&&e.response?b(e.response):c()};e.onerror=\r\nc;e.send(null)});B&&\"undefined\"==typeof performance&&(__webpack_require__.g.performance=(__webpack_require__(/*! perf_hooks */ \"?674f\").performance));var ta=console.log.bind(console),ua=console.warn.bind(console);B&&(sa(),ta=a=>fs.writeSync(1,a+\"\\n\"),ua=a=>fs.writeSync(2,a+\"\\n\"));var va=x.print||ta,G=x.printErr||ua;Object.assign(x,ja);ja=null;x.thisProgram&&(ka=x.thisProgram);x.quit&&(la=x.quit);var H;x.wasmBinary&&(H=x.wasmBinary);var noExitRuntime=x.noExitRuntime||!1;\"object\"!=typeof WebAssembly&&I(\"no native wasm support detected\");\r\nvar m,wa,xa=!1,ya=\"undefined\"!=typeof TextDecoder?new TextDecoder(\"utf8\"):void 0;\r\nfunction za(a,b,c){b>>>=0;var e=b+c;for(c=b;a[c]&&!(c>=e);)++c;if(16<c-b&&a.buffer&&ya)return ya.decode(a.buffer instanceof SharedArrayBuffer?a.slice(b,c):a.subarray(b,c));for(e=\"\";b<c;){var f=a[b++];if(f&128){var h=a[b++]&63;if(192==(f&224))e+=String.fromCharCode((f&31)<<6|h);else{var k=a[b++]&63;f=224==(f&240)?(f&15)<<12|h<<6|k:(f&7)<<18|h<<12|k<<6|a[b++]&63;65536>f?e+=String.fromCharCode(f):(f-=65536,e+=String.fromCharCode(55296|f>>10,56320|f&1023))}}else e+=String.fromCharCode(f)}return e}\r\nfunction Aa(a,b){return(a>>>=0)?za(q(),a,b):\"\"}\r\nfunction Ba(a,b,c,e){c>>>=0;if(!(0<e))return 0;var f=c;e=c+e-1;for(var h=0;h<a.length;++h){var k=a.charCodeAt(h);if(55296<=k&&57343>=k){var l=a.charCodeAt(++h);k=65536+((k&1023)<<10)|l&1023}if(127>=k){if(c>=e)break;b[c++>>>0]=k}else{if(2047>=k){if(c+1>=e)break;b[c++>>>0]=192|k>>6}else{if(65535>=k){if(c+2>=e)break;b[c++>>>0]=224|k>>12}else{if(c+3>=e)break;b[c++>>>0]=240|k>>18;b[c++>>>0]=128|k>>12&63}b[c++>>>0]=128|k>>6&63}b[c++>>>0]=128|k&63}}b[c>>>0]=0;return c-f}\r\nfunction Ca(a){for(var b=0,c=0;c<a.length;++c){var e=a.charCodeAt(c);127>=e?b++:2047>=e?b+=2:55296<=e&&57343>=e?(b+=4,++c):b+=3}return b}var n,aa,ba,ca,da,fa;C&&(n=x.buffer);function p(a){n=a;x.HEAP8=aa=new Int8Array(a);x.HEAP16=new Int16Array(a);x.HEAP32=ca=new Int32Array(a);x.HEAPU8=ba=new Uint8Array(a);x.HEAPU16=new Uint16Array(a);x.HEAPU32=da=new Uint32Array(a);x.HEAPF32=new Float32Array(a);x.HEAPF64=fa=new Float64Array(a)}var Da=x.INITIAL_MEMORY||16777216;\r\nif(C)m=x.wasmMemory,n=x.buffer;else if(x.wasmMemory)m=x.wasmMemory;else if(m=new WebAssembly.Memory({initial:Da/65536,maximum:65536,shared:!0}),!(m.buffer instanceof SharedArrayBuffer))throw G(\"requested a shared WebAssembly.Memory but the returned buffer is not a SharedArrayBuffer, indicating that while the browser has SharedArrayBuffer it does not have WebAssembly threads support - you may need to set a flag\"),B&&console.log(\"(on node you may need: --experimental-wasm-threads --experimental-wasm-bulk-memory and also use a recent version)\"),\r\nError(\"bad memory\");m&&(n=m.buffer);Da=n.byteLength;p(n);var Ea,Fa=[],Ga=[],Ha=[],Ia=[],Ja=0;function F(){return noExitRuntime||0<Ja}function Ka(){var a=x.preRun.shift();Fa.unshift(a)}var L=0,La=null,M=null;function I(a){if(C)postMessage({cmd:\"onAbort\",arg:a});else if(x.onAbort)x.onAbort(a);a=\"Aborted(\"+a+\")\";G(a);xa=!0;a=new WebAssembly.RuntimeError(a+\". Build with -sASSERTIONS for more info.\");ia(a);throw a;}function Ma(){return O.startsWith(\"data:application/octet-stream;base64,\")}var O;O=\"ort-wasm-threaded.wasm\";\r\nMa()||(O=na(O));function Na(){var a=O;try{if(a==O&&H)return new Uint8Array(H);if(qa)return qa(a);throw\"both async and sync fetching of the wasm failed\";}catch(b){I(b)}}\r\nfunction Oa(){if(!H&&(ma||y)){if(\"function\"==typeof fetch&&!O.startsWith(\"file://\"))return fetch(O,{credentials:\"same-origin\"}).then(function(a){if(!a.ok)throw\"failed to load wasm binary file at '\"+O+\"'\";return a.arrayBuffer()}).catch(function(){return Na()});if(pa)return new Promise(function(a,b){pa(O,function(c){a(new Uint8Array(c))},b)})}return Promise.resolve().then(function(){return Na()})}var Pa={};\r\nfunction E(a){this.name=\"ExitStatus\";this.message=\"Program terminated with exit(\"+a+\")\";this.status=a}function Qa(a){(a=P.Vb[a])||I();P.mc(a)}function Ra(a){var b=P.Cc();if(!b)return 6;P.ac.push(b);P.Vb[a.Ub]=b;b.Ub=a.Ub;var c={cmd:\"run\",start_routine:a.Ic,arg:a.zc,pthread_ptr:a.Ub};b.$b=()=>{c.time=performance.now();b.postMessage(c,a.Nc)};b.loaded&&(b.$b(),delete b.$b);return 0}function Sa(a){if(C)return Q(1,1,a);if(!F()){P.oc();if(x.onExit)x.onExit(a);xa=!0}la(a,new E(a))}\r\nfunction Ta(a,b){if(!b&&C)throw Ua(a),\"unwind\";F()||C||(Va(),R(Ha),Wa(0),Xa[1].length&&Ya(1,10),Xa[2].length&&Ya(2,10),P.oc());Sa(a)}\r\nvar P={Yb:[],ac:[],qc:[],Vb:{},fc:function(){C&&P.Ec()},Pc:function(){},Ec:function(){P.receiveObjectTransfer=P.Gc;P.threadInitTLS=P.pc;P.setExitStatus=P.nc;noExitRuntime=!1},nc:function(){},oc:function(){for(var a of Object.values(P.Vb))P.mc(a);for(a of P.Yb)a.terminate();P.Yb=[]},mc:function(a){var b=a.Ub;delete P.Vb[b];P.Yb.push(a);P.ac.splice(P.ac.indexOf(a),1);a.Ub=0;Za(b)},Gc:function(){},pc:function(){P.qc.forEach(a=>a())},Fc:function(a,b){a.onmessage=c=>{c=c.data;var e=c.cmd;a.Ub&&(P.Bc=a.Ub);\r\nif(c.targetThread&&c.targetThread!=$a()){var f=P.Vb[c.Qc];f?f.postMessage(c,c.transferList):G('Internal error! Worker sent a message \"'+e+'\" to target pthread '+c.targetThread+\", but that thread no longer exists!\")}else if(\"processProxyingQueue\"===e)ab(c.queue);else if(\"spawnThread\"===e)Ra(c);else if(\"cleanupThread\"===e)Qa(c.thread);else if(\"killThread\"===e)c=c.thread,e=P.Vb[c],delete P.Vb[c],e.terminate(),Za(c),P.ac.splice(P.ac.indexOf(e),1),e.Ub=0;else if(\"cancelThread\"===e)P.Vb[c.thread].postMessage({cmd:\"cancel\"});\r\nelse if(\"loaded\"===e)a.loaded=!0,b&&b(a),a.$b&&(a.$b(),delete a.$b);else if(\"print\"===e)va(\"Thread \"+c.threadId+\": \"+c.text);else if(\"printErr\"===e)G(\"Thread \"+c.threadId+\": \"+c.text);else if(\"alert\"===e)alert(\"Thread \"+c.threadId+\": \"+c.text);else if(\"setimmediate\"===c.target)a.postMessage(c);else if(\"onAbort\"===e){if(x.onAbort)x.onAbort(c.arg)}else e&&G(\"worker sent an unknown command \"+e);P.Bc=void 0};a.onerror=c=>{G(\"worker sent an error! \"+c.filename+\":\"+c.lineno+\": \"+c.message);throw c;};B&&\r\n(a.on(\"message\",function(c){a.onmessage({data:c})}),a.on(\"error\",function(c){a.onerror(c)}),a.on(\"detachedExit\",function(){}));a.postMessage({cmd:\"load\",urlOrBlob:x.mainScriptUrlOrBlob||_scriptDir,wasmMemory:m,wasmModule:wa})},yc:function(){var a=na(\"ort-wasm-threaded.worker.js\");P.Yb.push(new Worker(a))},Cc:function(){0==P.Yb.length&&(P.yc(),P.Fc(P.Yb[0]));return P.Yb.pop()}};x.PThread=P;function R(a){for(;0<a.length;)a.shift()(x)}function bb(a){var b=S();a=a();U(b);return a}\r\nx.establishStackSpace=function(){var a=$a(),b=r()[a+44>>2>>>0];a=r()[a+48>>2>>>0];cb(b,b-a);U(b)};function Ua(a){if(C)return Q(2,0,a);try{Ta(a)}catch(b){b instanceof E||\"unwind\"==b||la(1,b)}}var db=[];function V(a){var b=db[a];b||(a>=db.length&&(db.length=a+1),db[a]=b=Ea.get(a));return b}x.invokeEntryPoint=function(a,b){a=V(a)(b);F()?P.nc(a):eb(a)};function fb(a,b){d().set(a,b>>>0)}var gb=[],hb=0,W=0;\r\nfunction X(a){this.Zb=a;this.Sb=a-24;this.xc=function(b){v()[this.Sb+4>>2>>>0]=b};this.bc=function(){return v()[this.Sb+4>>2>>>0]};this.wc=function(b){v()[this.Sb+8>>2>>>0]=b};this.Dc=function(){return v()[this.Sb+8>>2>>>0]};this.rc=function(){r()[this.Sb>>2>>>0]=0};this.hc=function(b){b=b?1:0;d()[this.Sb+12>>0>>>0]=b};this.uc=function(){return 0!=d()[this.Sb+12>>0>>>0]};this.ic=function(b){b=b?1:0;d()[this.Sb+13>>0>>>0]=b};this.kc=function(){return 0!=d()[this.Sb+13>>0>>>0]};this.fc=function(b,c){this.cc(0);\r\nthis.xc(b);this.wc(c);this.rc();this.hc(!1);this.ic(!1)};this.sc=function(){Atomics.add(r(),this.Sb>>2,1)};this.Hc=function(){return 1===Atomics.sub(r(),this.Sb>>2,1)};this.cc=function(b){v()[this.Sb+16>>2>>>0]=b};this.tc=function(){return v()[this.Sb+16>>2>>>0]};this.vc=function(){if(ib(this.bc()))return v()[this.Zb>>2>>>0];var b=this.tc();return 0!==b?b:this.Zb}}function jb(a){return kb((new X(a)).Sb)}function lb(a,b,c,e){return C?Q(3,1,a,b,c,e):mb(a,b,c,e)}\r\nfunction mb(a,b,c,e){if(\"undefined\"==typeof SharedArrayBuffer)return G(\"Current environment does not support SharedArrayBuffer, pthreads are not available!\"),6;var f=[];if(C&&0===f.length)return lb(a,b,c,e);a={Ic:c,Ub:a,zc:e,Nc:f};return C?(a.Oc=\"spawnThread\",postMessage(a,f),0):Ra(a)}function nb(a,b,c){return C?Q(4,1,a,b,c):0}function ob(a,b){if(C)return Q(5,1,a,b)}function pb(a,b){if(C)return Q(6,1,a,b)}function qb(a,b,c){if(C)return Q(7,1,a,b,c)}function rb(a,b,c){return C?Q(8,1,a,b,c):0}\r\nfunction sb(a,b){if(C)return Q(9,1,a,b)}function tb(a,b,c){if(C)return Q(10,1,a,b,c)}function ub(a,b,c,e){if(C)return Q(11,1,a,b,c,e)}function vb(a,b,c,e){if(C)return Q(12,1,a,b,c,e)}function wb(a,b,c,e){if(C)return Q(13,1,a,b,c,e)}function xb(a){if(C)return Q(14,1,a)}function yb(a,b){if(C)return Q(15,1,a,b)}function zb(a,b,c){if(C)return Q(16,1,a,b,c)}function ab(a){Atomics.store(r(),a>>2,1);$a()&&Ab(a);Atomics.compareExchange(r(),a>>2,1,0)}x.executeNotifiedProxyingQueue=ab;\r\nfunction Bb(a){return v()[a>>>2]+4294967296*r()[a+4>>>2]}function Cb(a,b,c,e,f,h){return C?Q(17,1,a,b,c,e,f,h):-52}function Db(a,b,c,e,f,h){if(C)return Q(18,1,a,b,c,e,f,h)}function Eb(a){var b=Ca(a)+1,c=Fb(b);c&&Ba(a,d(),c,b);return c}\r\nfunction Gb(a,b,c){function e(t){return(t=t.toTimeString().match(/\\(([A-Za-z ]+)\\)$/))?t[1]:\"GMT\"}if(C)return Q(19,1,a,b,c);var f=(new Date).getFullYear(),h=new Date(f,0,1),k=new Date(f,6,1);f=h.getTimezoneOffset();var l=k.getTimezoneOffset(),u=Math.max(f,l);r()[a>>2>>>0]=60*u;r()[b>>2>>>0]=Number(f!=l);a=e(h);b=e(k);a=Eb(a);b=Eb(b);l<f?(v()[c>>2>>>0]=a,v()[c+4>>2>>>0]=b):(v()[c>>2>>>0]=b,v()[c+4>>2>>>0]=a)}function Hb(a,b,c){Hb.Ac||(Hb.Ac=!0,Gb(a,b,c))}var Ib,Jb;\r\nJb=B?()=>{var a=process.hrtime();return 1E3*a[0]+a[1]/1E6}:C?()=>performance.now()-x.__performance_now_clock_drift:()=>performance.now();function Q(a,b){var c=arguments.length-2,e=arguments;return bb(()=>{for(var f=Kb(8*c),h=f>>3,k=0;k<c;k++){var l=e[2+k];ea()[h+k>>>0]=l}return Lb(a,c,f,b)})}var Mb=[],Nb={};\r\nfunction Ob(){if(!Pb){var a={USER:\"web_user\",LOGNAME:\"web_user\",PATH:\"/\",PWD:\"/\",HOME:\"/home/web_user\",LANG:(\"object\"==typeof navigator&&navigator.languages&&navigator.languages[0]||\"C\").replace(\"-\",\"_\")+\".UTF-8\",_:ka||\"./this.program\"},b;for(b in Nb)void 0===Nb[b]?delete a[b]:a[b]=Nb[b];var c=[];for(b in a)c.push(b+\"=\"+a[b]);Pb=c}return Pb}var Pb;\r\nfunction Qb(a,b){if(C)return Q(20,1,a,b);var c=0;Ob().forEach(function(e,f){var h=b+c;f=v()[a+4*f>>2>>>0]=h;for(h=0;h<e.length;++h)d()[f++>>0>>>0]=e.charCodeAt(h);d()[f>>0>>>0]=0;c+=e.length+1});return 0}function Rb(a,b){if(C)return Q(21,1,a,b);var c=Ob();v()[a>>2>>>0]=c.length;var e=0;c.forEach(function(f){e+=f.length+1});v()[b>>2>>>0]=e;return 0}function Sb(a){return C?Q(22,1,a):52}function Tb(a,b,c,e){return C?Q(23,1,a,b,c,e):52}function Ub(a,b,c,e,f){return C?Q(24,1,a,b,c,e,f):70}\r\nvar Xa=[null,[],[]];function Ya(a,b){var c=Xa[a];0===b||10===b?((1===a?va:G)(za(c,0)),c.length=0):c.push(b)}function Vb(a,b,c,e){if(C)return Q(25,1,a,b,c,e);for(var f=0,h=0;h<c;h++){var k=v()[b>>2>>>0],l=v()[b+4>>2>>>0];b+=8;for(var u=0;u<l;u++)Ya(a,q()[k+u>>>0]);f+=l}v()[e>>2>>>0]=f;return 0}var Y=0;\r\nfunction Wb(){if(\"object\"==typeof crypto&&\"function\"==typeof crypto.getRandomValues){var a=new Uint8Array(1);return()=>{crypto.getRandomValues(a);return a[0]}}if(B)try{var b=__webpack_require__(Object(function webpackMissingModule() { var e = new Error(\"Cannot find module 'crypto'\"); e.code = 'MODULE_NOT_FOUND'; throw e; }()));return()=>b.randomBytes(1)[0]}catch(c){}return()=>I(\"randomDevice\")}function Xb(a,b){Xb.lc||(Xb.lc=Wb());for(var c=0;c<b;c++)d()[a+c>>0>>>0]=Xb.lc();return 0}function Yb(a){return 0===a%4&&(0!==a%100||0===a%400)}var Zb=[31,29,31,30,31,30,31,31,30,31,30,31],$b=[31,28,31,30,31,30,31,31,30,31,30,31];\r\nfunction ac(a){var b=Array(Ca(a)+1);Ba(a,b,0,b.length);return b}\r\nfunction bc(a,b,c,e){function f(g,w,z){for(g=\"number\"==typeof g?g.toString():g||\"\";g.length<w;)g=z[0]+g;return g}function h(g,w){return f(g,w,\"0\")}function k(g,w){function z(T){return 0>T?-1:0<T?1:0}var N;0===(N=z(g.getFullYear()-w.getFullYear()))&&0===(N=z(g.getMonth()-w.getMonth()))&&(N=z(g.getDate()-w.getDate()));return N}function l(g){switch(g.getDay()){case 0:return new Date(g.getFullYear()-1,11,29);case 1:return g;case 2:return new Date(g.getFullYear(),0,3);case 3:return new Date(g.getFullYear(),\r\n0,2);case 4:return new Date(g.getFullYear(),0,1);case 5:return new Date(g.getFullYear()-1,11,31);case 6:return new Date(g.getFullYear()-1,11,30)}}function u(g){var w=g.Wb;for(g=new Date((new Date(g.Xb+1900,0,1)).getTime());0<w;){var z=g.getMonth(),N=(Yb(g.getFullYear())?Zb:$b)[z];if(w>N-g.getDate())w-=N-g.getDate()+1,g.setDate(1),11>z?g.setMonth(z+1):(g.setMonth(0),g.setFullYear(g.getFullYear()+1));else{g.setDate(g.getDate()+w);break}}z=new Date(g.getFullYear()+1,0,4);w=l(new Date(g.getFullYear(),\r\n0,4));z=l(z);return 0>=k(w,g)?0>=k(z,g)?g.getFullYear()+1:g.getFullYear():g.getFullYear()-1}var t=r()[e+40>>2>>>0];e={Lc:r()[e>>2>>>0],Kc:r()[e+4>>2>>>0],dc:r()[e+8>>2>>>0],jc:r()[e+12>>2>>>0],ec:r()[e+16>>2>>>0],Xb:r()[e+20>>2>>>0],Tb:r()[e+24>>2>>>0],Wb:r()[e+28>>2>>>0],Rc:r()[e+32>>2>>>0],Jc:r()[e+36>>2>>>0],Mc:t?Aa(t):\"\"};c=Aa(c);t={\"%c\":\"%a %b %d %H:%M:%S %Y\",\"%D\":\"%m/%d/%y\",\"%F\":\"%Y-%m-%d\",\"%h\":\"%b\",\"%r\":\"%I:%M:%S %p\",\"%R\":\"%H:%M\",\"%T\":\"%H:%M:%S\",\"%x\":\"%m/%d/%y\",\"%X\":\"%H:%M:%S\",\"%Ec\":\"%c\",\"%EC\":\"%C\",\r\n\"%Ex\":\"%m/%d/%y\",\"%EX\":\"%H:%M:%S\",\"%Ey\":\"%y\",\"%EY\":\"%Y\",\"%Od\":\"%d\",\"%Oe\":\"%e\",\"%OH\":\"%H\",\"%OI\":\"%I\",\"%Om\":\"%m\",\"%OM\":\"%M\",\"%OS\":\"%S\",\"%Ou\":\"%u\",\"%OU\":\"%U\",\"%OV\":\"%V\",\"%Ow\":\"%w\",\"%OW\":\"%W\",\"%Oy\":\"%y\"};for(var A in t)c=c.replace(new RegExp(A,\"g\"),t[A]);var K=\"Sunday Monday Tuesday Wednesday Thursday Friday Saturday\".split(\" \"),J=\"January February March April May June July August September October November December\".split(\" \");t={\"%a\":function(g){return K[g.Tb].substring(0,3)},\"%A\":function(g){return K[g.Tb]},\r\n\"%b\":function(g){return J[g.ec].substring(0,3)},\"%B\":function(g){return J[g.ec]},\"%C\":function(g){return h((g.Xb+1900)/100|0,2)},\"%d\":function(g){return h(g.jc,2)},\"%e\":function(g){return f(g.jc,2,\" \")},\"%g\":function(g){return u(g).toString().substring(2)},\"%G\":function(g){return u(g)},\"%H\":function(g){return h(g.dc,2)},\"%I\":function(g){g=g.dc;0==g?g=12:12<g&&(g-=12);return h(g,2)},\"%j\":function(g){for(var w=0,z=0;z<=g.ec-1;w+=(Yb(g.Xb+1900)?Zb:$b)[z++]);return h(g.jc+w,3)},\"%m\":function(g){return h(g.ec+\r\n1,2)},\"%M\":function(g){return h(g.Kc,2)},\"%n\":function(){return\"\\n\"},\"%p\":function(g){return 0<=g.dc&&12>g.dc?\"AM\":\"PM\"},\"%S\":function(g){return h(g.Lc,2)},\"%t\":function(){return\"\\t\"},\"%u\":function(g){return g.Tb||7},\"%U\":function(g){return h(Math.floor((g.Wb+7-g.Tb)/7),2)},\"%V\":function(g){var w=Math.floor((g.Wb+7-(g.Tb+6)%7)/7);2>=(g.Tb+371-g.Wb-2)%7&&w++;if(w)53==w&&(z=(g.Tb+371-g.Wb)%7,4==z||3==z&&Yb(g.Xb)||(w=1));else{w=52;var z=(g.Tb+7-g.Wb-1)%7;(4==z||5==z&&Yb(g.Xb%400-1))&&w++}return h(w,\r\n2)},\"%w\":function(g){return g.Tb},\"%W\":function(g){return h(Math.floor((g.Wb+7-(g.Tb+6)%7)/7),2)},\"%y\":function(g){return(g.Xb+1900).toString().substring(2)},\"%Y\":function(g){return g.Xb+1900},\"%z\":function(g){g=g.Jc;var w=0<=g;g=Math.abs(g)/60;return(w?\"+\":\"-\")+String(\"0000\"+(g/60*100+g%60)).slice(-4)},\"%Z\":function(g){return g.Mc},\"%%\":function(){return\"%\"}};c=c.replace(/%%/g,\"\\x00\\x00\");for(A in t)c.includes(A)&&(c=c.replace(new RegExp(A,\"g\"),t[A](e)));c=c.replace(/\\0\\0/g,\"%\");A=ac(c);if(A.length>\r\nb)return 0;fb(A,a);return A.length-1}P.fc();\r\nvar cc=[null,Sa,Ua,lb,nb,ob,pb,qb,rb,sb,tb,ub,vb,wb,xb,yb,zb,Cb,Db,Gb,Qb,Rb,Sb,Tb,Ub,Vb],Pc={b:function(a){return Fb(a+24)+24},n:function(a){a=new X(a);a.uc()||(a.hc(!0),hb--);a.ic(!1);gb.push(a);a.sc();return a.vc()},ma:function(a){G(\"Unexpected exception thrown, this is not properly supported - aborting\");xa=!0;throw a;},x:function(){Z(0);var a=gb.pop();if(a.Hc()&&!a.kc()){var b=a.Dc();b&&V(b)(a.Zb);jb(a.Zb)}W=0},e:function(){var a=W;if(!a)return Y=0;var b=new X(a);b.cc(a);var c=b.bc();if(!c)return Y=\r\n0,a;for(var e=Array.prototype.slice.call(arguments),f=0;f<e.length;f++){var h=e[f];if(0===h||h===c)break;if(dc(h,c,b.Sb+16))return Y=h,a}Y=c;return a},l:function(){var a=W;if(!a)return Y=0;var b=new X(a);b.cc(a);var c=b.bc();if(!c)return Y=0,a;for(var e=Array.prototype.slice.call(arguments),f=0;f<e.length;f++){var h=e[f];if(0===h||h===c)break;if(dc(h,c,b.Sb+16))return Y=h,a}Y=c;return a},h:function(){var a=W;if(!a)return Y=0;var b=new X(a);b.cc(a);var c=b.bc();if(!c)return Y=0,a;for(var e=Array.prototype.slice.call(arguments),\r\nf=0;f<e.length;f++){var h=e[f];if(0===h||h===c)break;if(dc(h,c,b.Sb+16))return Y=h,a}Y=c;return a},t:jb,M:function(){var a=gb.pop();a||I(\"no exception to throw\");var b=a.Zb;a.kc()||(gb.push(a),a.ic(!0),a.hc(!1),hb++);W=b;throw b;},c:function(a,b,c){(new X(a)).fc(b,c);W=a;hb++;throw a;},pa:function(){return hb},Fa:function(a){ec(a,!y,1,!ma);P.pc()},T:function(a){C?postMessage({cmd:\"cleanupThread\",thread:a}):Qa(a)},xa:mb,j:function(a){W||(W=a);throw a;},H:nb,Ma:ob,ua:pb,wa:qb,oa:rb,Ka:sb,Ca:tb,Ja:ub,\r\nV:vb,va:wb,sa:xb,La:yb,ta:zb,Ta:function(){},X:function(){I(\"To use dlopen, you need enable dynamic linking, see https://github.com/emscripten-core/emscripten/wiki/Linking\")},Ua:function(){I(\"To use dlopen, you need enable dynamic linking, see https://github.com/emscripten-core/emscripten/wiki/Linking\")},W:function(){return Date.now()},ya:function(){return 2097152},Oa:function(){return!0},za:function(a,b,c,e){if(a==b)setTimeout(()=>ab(e));else if(C)postMessage({targetThread:a,cmd:\"processProxyingQueue\",\r\nqueue:e});else{a=P.Vb[a];if(!a)return;a.postMessage({cmd:\"processProxyingQueue\",queue:e})}return 1},Ea:function(){return-1},Pa:function(a,b){a=new Date(1E3*Bb(a));r()[b>>2>>>0]=a.getUTCSeconds();r()[b+4>>2>>>0]=a.getUTCMinutes();r()[b+8>>2>>>0]=a.getUTCHours();r()[b+12>>2>>>0]=a.getUTCDate();r()[b+16>>2>>>0]=a.getUTCMonth();r()[b+20>>2>>>0]=a.getUTCFullYear()-1900;r()[b+24>>2>>>0]=a.getUTCDay();a=(a.getTime()-Date.UTC(a.getUTCFullYear(),0,1,0,0,0,0))/864E5|0;r()[b+28>>2>>>0]=a},Qa:function(a,b){a=\r\nnew Date(1E3*Bb(a));r()[b>>2>>>0]=a.getSeconds();r()[b+4>>2>>>0]=a.getMinutes();r()[b+8>>2>>>0]=a.getHours();r()[b+12>>2>>>0]=a.getDate();r()[b+16>>2>>>0]=a.getMonth();r()[b+20>>2>>>0]=a.getFullYear()-1900;r()[b+24>>2>>>0]=a.getDay();var c=new Date(a.getFullYear(),0,1),e=(a.getTime()-c.getTime())/864E5|0;r()[b+28>>2>>>0]=e;r()[b+36>>2>>>0]=-(60*a.getTimezoneOffset());e=(new Date(a.getFullYear(),6,1)).getTimezoneOffset();c=c.getTimezoneOffset();a=(e!=c&&a.getTimezoneOffset()==Math.min(c,e))|0;r()[b+\r\n32>>2>>>0]=a},Ra:function(a){var b=new Date(r()[a+20>>2>>>0]+1900,r()[a+16>>2>>>0],r()[a+12>>2>>>0],r()[a+8>>2>>>0],r()[a+4>>2>>>0],r()[a>>2>>>0],0),c=r()[a+32>>2>>>0],e=b.getTimezoneOffset(),f=new Date(b.getFullYear(),0,1),h=(new Date(b.getFullYear(),6,1)).getTimezoneOffset(),k=f.getTimezoneOffset(),l=Math.min(k,h);0>c?r()[a+32>>2>>>0]=Number(h!=k&&l==e):0<c!=(l==e)&&(h=Math.max(k,h),b.setTime(b.getTime()+6E4*((0<c?l:h)-e)));r()[a+24>>2>>>0]=b.getDay();c=(b.getTime()-f.getTime())/864E5|0;r()[a+28>>\r\n2>>>0]=c;r()[a>>2>>>0]=b.getSeconds();r()[a+4>>2>>>0]=b.getMinutes();r()[a+8>>2>>>0]=b.getHours();r()[a+12>>2>>>0]=b.getDate();r()[a+16>>2>>>0]=b.getMonth();return b.getTime()/1E3|0},Aa:Cb,Ba:Db,Sa:Hb,y:function(){I(\"\")},U:function(){if(!B&&!y){var a=\"Blocking on the main thread is very dangerous, see https://emscripten.org/docs/porting/pthreads.html#blocking-on-the-main-browser-thread\";Ib||(Ib={});Ib[a]||(Ib[a]=1,B&&(a=\"warning: \"+a),G(a))}},ra:function(){return 4294901760},B:Jb,Ia:function(a,b,\r\nc){q().copyWithin(a>>>0,b>>>0,b+c>>>0)},F:function(){return B?(__webpack_require__(/*! os */ \"?aedb\").cpus)().length:navigator.hardwareConcurrency},Da:function(a,b,c){Mb.length=b;c>>=3;for(var e=0;e<b;e++)Mb[e]=ea()[c+e>>>0];return(0>a?Pa[-a-1]:cc[a]).apply(null,Mb)},qa:function(a){var b=q().length;a>>>=0;if(a<=b||4294901760<a)return!1;for(var c=1;4>=c;c*=2){var e=b*(1+.2/c);e=Math.min(e,a+100663296);var f=Math;e=Math.max(a,e);f=f.min.call(f,4294901760,e+(65536-e%65536)%65536);a:{try{m.grow(f-n.byteLength+65535>>>16);p(m.buffer);\r\nvar h=1;break a}catch(k){}h=void 0}if(h)return!0}return!1},Na:function(){throw\"unwind\";},Ga:Qb,Ha:Rb,J:Ta,I:Sb,S:Tb,ga:Ub,R:Vb,d:function(){return Y},na:Xb,ia:fc,ja:gc,K:hc,f:ic,P:jc,Q:kc,k:lc,p:mc,q:nc,N:oc,s:pc,w:qc,L:rc,E:sc,aa:tc,_:uc,Z:vc,ca:wc,$:xc,ba:yc,Y:zc,g:Ac,r:Bc,i:Cc,ha:Dc,m:Ec,v:Fc,u:Gc,O:Hc,A:Ic,ka:Jc,C:Kc,D:Lc,fa:Mc,da:Nc,ea:Oc,o:function(a){return a},a:m||x.wasmMemory,G:function(a){Y=a},la:bc,z:function(a,b,c,e){return bc(a,b,c,e)}};\r\n(function(){function a(f,h){x.asm=f.exports;P.qc.push(x.asm.sb);Ea=x.asm.ub;Ga.unshift(x.asm.Va);wa=h;C||(L--,x.monitorRunDependencies&&x.monitorRunDependencies(L),0==L&&(null!==La&&(clearInterval(La),La=null),M&&(f=M,M=null,f())))}function b(f){a(f.instance,f.module)}function c(f){return Oa().then(function(h){return WebAssembly.instantiate(h,e)}).then(function(h){return h}).then(f,function(h){G(\"failed to asynchronously prepare wasm: \"+h);I(h)})}var e={a:Pc};C||(L++,x.monitorRunDependencies&&x.monitorRunDependencies(L));\r\nif(x.instantiateWasm)try{return x.instantiateWasm(e,a)}catch(f){return G(\"Module.instantiateWasm callback failed with error: \"+f),!1}(function(){return H||\"function\"!=typeof WebAssembly.instantiateStreaming||Ma()||O.startsWith(\"file://\")||B||\"function\"!=typeof fetch?c(b):fetch(O,{credentials:\"same-origin\"}).then(function(f){return WebAssembly.instantiateStreaming(f,e).then(b,function(h){G(\"wasm streaming compile failed: \"+h);G(\"falling back to ArrayBuffer instantiation\");return c(b)})})})().catch(ia);\r\nreturn{}})();x.___wasm_call_ctors=function(){return(x.___wasm_call_ctors=x.asm.Va).apply(null,arguments)};x._OrtInit=function(){return(x._OrtInit=x.asm.Wa).apply(null,arguments)};x._OrtCreateSessionOptions=function(){return(x._OrtCreateSessionOptions=x.asm.Xa).apply(null,arguments)};x._OrtAppendExecutionProvider=function(){return(x._OrtAppendExecutionProvider=x.asm.Ya).apply(null,arguments)};x._OrtAddSessionConfigEntry=function(){return(x._OrtAddSessionConfigEntry=x.asm.Za).apply(null,arguments)};\r\nx._OrtReleaseSessionOptions=function(){return(x._OrtReleaseSessionOptions=x.asm._a).apply(null,arguments)};x._OrtCreateSession=function(){return(x._OrtCreateSession=x.asm.$a).apply(null,arguments)};x._OrtReleaseSession=function(){return(x._OrtReleaseSession=x.asm.ab).apply(null,arguments)};x._OrtGetInputCount=function(){return(x._OrtGetInputCount=x.asm.bb).apply(null,arguments)};x._OrtGetOutputCount=function(){return(x._OrtGetOutputCount=x.asm.cb).apply(null,arguments)};\r\nx._OrtGetInputName=function(){return(x._OrtGetInputName=x.asm.db).apply(null,arguments)};x._OrtGetOutputName=function(){return(x._OrtGetOutputName=x.asm.eb).apply(null,arguments)};x._OrtFree=function(){return(x._OrtFree=x.asm.fb).apply(null,arguments)};x._OrtCreateTensor=function(){return(x._OrtCreateTensor=x.asm.gb).apply(null,arguments)};x._OrtGetTensorData=function(){return(x._OrtGetTensorData=x.asm.hb).apply(null,arguments)};\r\nx._OrtReleaseTensor=function(){return(x._OrtReleaseTensor=x.asm.ib).apply(null,arguments)};x._OrtCreateRunOptions=function(){return(x._OrtCreateRunOptions=x.asm.jb).apply(null,arguments)};x._OrtAddRunConfigEntry=function(){return(x._OrtAddRunConfigEntry=x.asm.kb).apply(null,arguments)};x._OrtReleaseRunOptions=function(){return(x._OrtReleaseRunOptions=x.asm.lb).apply(null,arguments)};x._OrtRun=function(){return(x._OrtRun=x.asm.mb).apply(null,arguments)};\r\nx._OrtEndProfiling=function(){return(x._OrtEndProfiling=x.asm.nb).apply(null,arguments)};var $a=x._pthread_self=function(){return($a=x._pthread_self=x.asm.ob).apply(null,arguments)},Fb=x._malloc=function(){return(Fb=x._malloc=x.asm.pb).apply(null,arguments)},kb=x._free=function(){return(kb=x._free=x.asm.qb).apply(null,arguments)},Wa=x._fflush=function(){return(Wa=x._fflush=x.asm.rb).apply(null,arguments)};x.__emscripten_tls_init=function(){return(x.__emscripten_tls_init=x.asm.sb).apply(null,arguments)};\r\nvar Va=x.___funcs_on_exit=function(){return(Va=x.___funcs_on_exit=x.asm.tb).apply(null,arguments)},ec=x.__emscripten_thread_init=function(){return(ec=x.__emscripten_thread_init=x.asm.vb).apply(null,arguments)};x.__emscripten_thread_crashed=function(){return(x.__emscripten_thread_crashed=x.asm.wb).apply(null,arguments)};\r\nvar Lb=x._emscripten_run_in_main_runtime_thread_js=function(){return(Lb=x._emscripten_run_in_main_runtime_thread_js=x.asm.xb).apply(null,arguments)},Ab=x.__emscripten_proxy_execute_task_queue=function(){return(Ab=x.__emscripten_proxy_execute_task_queue=x.asm.yb).apply(null,arguments)},Za=x.__emscripten_thread_free_data=function(){return(Za=x.__emscripten_thread_free_data=x.asm.zb).apply(null,arguments)},eb=x.__emscripten_thread_exit=function(){return(eb=x.__emscripten_thread_exit=x.asm.Ab).apply(null,\r\narguments)},Z=x._setThrew=function(){return(Z=x._setThrew=x.asm.Bb).apply(null,arguments)},cb=x._emscripten_stack_set_limits=function(){return(cb=x._emscripten_stack_set_limits=x.asm.Cb).apply(null,arguments)},S=x.stackSave=function(){return(S=x.stackSave=x.asm.Db).apply(null,arguments)},U=x.stackRestore=function(){return(U=x.stackRestore=x.asm.Eb).apply(null,arguments)},Kb=x.stackAlloc=function(){return(Kb=x.stackAlloc=x.asm.Fb).apply(null,arguments)},dc=x.___cxa_can_catch=function(){return(dc=x.___cxa_can_catch=\r\nx.asm.Gb).apply(null,arguments)},ib=x.___cxa_is_pointer_type=function(){return(ib=x.___cxa_is_pointer_type=x.asm.Hb).apply(null,arguments)},Qc=x.dynCall_j=function(){return(Qc=x.dynCall_j=x.asm.Ib).apply(null,arguments)},Rc=x.dynCall_iiiiij=function(){return(Rc=x.dynCall_iiiiij=x.asm.Jb).apply(null,arguments)},Sc=x.dynCall_jii=function(){return(Sc=x.dynCall_jii=x.asm.Kb).apply(null,arguments)},Tc=x.dynCall_viiiiij=function(){return(Tc=x.dynCall_viiiiij=x.asm.Lb).apply(null,arguments)},Uc=x.dynCall_vjji=\r\nfunction(){return(Uc=x.dynCall_vjji=x.asm.Mb).apply(null,arguments)},Vc=x.dynCall_viiijjjii=function(){return(Vc=x.dynCall_viiijjjii=x.asm.Nb).apply(null,arguments)},Wc=x.dynCall_iij=function(){return(Wc=x.dynCall_iij=x.asm.Ob).apply(null,arguments)},Xc=x.dynCall_ji=function(){return(Xc=x.dynCall_ji=x.asm.Pb).apply(null,arguments)},Yc=x.dynCall_iiiiiij=function(){return(Yc=x.dynCall_iiiiiij=x.asm.Qb).apply(null,arguments)},Zc=x.dynCall_iiij=function(){return(Zc=x.dynCall_iiij=x.asm.Rb).apply(null,\r\narguments)};function ic(a,b){var c=S();try{return V(a)(b)}catch(e){U(c);if(e!==e+0)throw e;Z(1,0)}}function Bc(a,b){var c=S();try{V(a)(b)}catch(e){U(c);if(e!==e+0)throw e;Z(1,0)}}function Cc(a,b,c){var e=S();try{V(a)(b,c)}catch(f){U(e);if(f!==f+0)throw f;Z(1,0)}}function lc(a,b,c){var e=S();try{return V(a)(b,c)}catch(f){U(e);if(f!==f+0)throw f;Z(1,0)}}function mc(a,b,c,e){var f=S();try{return V(a)(b,c,e)}catch(h){U(f);if(h!==h+0)throw h;Z(1,0)}}\r\nfunction qc(a,b,c,e,f,h,k){var l=S();try{return V(a)(b,c,e,f,h,k)}catch(u){U(l);if(u!==u+0)throw u;Z(1,0)}}function Ac(a){var b=S();try{V(a)()}catch(c){U(b);if(c!==c+0)throw c;Z(1,0)}}function pc(a,b,c,e,f,h){var k=S();try{return V(a)(b,c,e,f,h)}catch(l){U(k);if(l!==l+0)throw l;Z(1,0)}}function nc(a,b,c,e,f){var h=S();try{return V(a)(b,c,e,f)}catch(k){U(h);if(k!==k+0)throw k;Z(1,0)}}function Ec(a,b,c,e){var f=S();try{V(a)(b,c,e)}catch(h){U(f);if(h!==h+0)throw h;Z(1,0)}}\r\nfunction Gc(a,b,c,e,f,h){var k=S();try{V(a)(b,c,e,f,h)}catch(l){U(k);if(l!==l+0)throw l;Z(1,0)}}function Fc(a,b,c,e,f){var h=S();try{V(a)(b,c,e,f)}catch(k){U(h);if(k!==k+0)throw k;Z(1,0)}}function Ic(a,b,c,e,f,h,k,l){var u=S();try{V(a)(b,c,e,f,h,k,l)}catch(t){U(u);if(t!==t+0)throw t;Z(1,0)}}function kc(a,b,c){var e=S();try{return V(a)(b,c)}catch(f){U(e);if(f!==f+0)throw f;Z(1,0)}}function jc(a,b,c){var e=S();try{return V(a)(b,c)}catch(f){U(e);if(f!==f+0)throw f;Z(1,0)}}\r\nfunction Jc(a,b,c,e,f,h,k,l,u){var t=S();try{V(a)(b,c,e,f,h,k,l,u)}catch(A){U(t);if(A!==A+0)throw A;Z(1,0)}}function Hc(a,b,c,e,f,h,k){var l=S();try{V(a)(b,c,e,f,h,k)}catch(u){U(l);if(u!==u+0)throw u;Z(1,0)}}function oc(a,b,c,e,f,h){var k=S();try{return V(a)(b,c,e,f,h)}catch(l){U(k);if(l!==l+0)throw l;Z(1,0)}}function rc(a,b,c,e,f,h,k,l){var u=S();try{return V(a)(b,c,e,f,h,k,l)}catch(t){U(u);if(t!==t+0)throw t;Z(1,0)}}\r\nfunction sc(a,b,c,e,f,h,k,l,u,t,A,K){var J=S();try{return V(a)(b,c,e,f,h,k,l,u,t,A,K)}catch(g){U(J);if(g!==g+0)throw g;Z(1,0)}}function Kc(a,b,c,e,f,h,k,l,u,t,A){var K=S();try{V(a)(b,c,e,f,h,k,l,u,t,A)}catch(J){U(K);if(J!==J+0)throw J;Z(1,0)}}function Lc(a,b,c,e,f,h,k,l,u,t,A,K,J,g,w,z){var N=S();try{V(a)(b,c,e,f,h,k,l,u,t,A,K,J,g,w,z)}catch(T){U(N);if(T!==T+0)throw T;Z(1,0)}}function hc(a){var b=S();try{return V(a)()}catch(c){U(b);if(c!==c+0)throw c;Z(1,0)}}\r\nfunction gc(a,b,c){var e=S();try{return V(a)(b,c)}catch(f){U(e);if(f!==f+0)throw f;Z(1,0)}}function fc(a,b,c){var e=S();try{return V(a)(b,c)}catch(f){U(e);if(f!==f+0)throw f;Z(1,0)}}function Dc(a,b,c,e){var f=S();try{V(a)(b,c,e)}catch(h){U(f);if(h!==h+0)throw h;Z(1,0)}}function Mc(a,b,c,e,f,h,k,l){var u=S();try{Tc(a,b,c,e,f,h,k,l)}catch(t){U(u);if(t!==t+0)throw t;Z(1,0)}}function Oc(a,b,c,e,f,h){var k=S();try{Uc(a,b,c,e,f,h)}catch(l){U(k);if(l!==l+0)throw l;Z(1,0)}}\r\nfunction Nc(a,b,c,e,f,h,k,l,u,t,A,K){var J=S();try{Vc(a,b,c,e,f,h,k,l,u,t,A,K)}catch(g){U(J);if(g!==g+0)throw g;Z(1,0)}}function wc(a,b,c,e){var f=S();try{return Wc(a,b,c,e)}catch(h){U(f);if(h!==h+0)throw h;Z(1,0)}}function yc(a,b){var c=S();try{return Xc(a,b)}catch(e){U(c);if(e!==e+0)throw e;Z(1,0)}}function tc(a,b,c,e,f,h,k,l){var u=S();try{return Yc(a,b,c,e,f,h,k,l)}catch(t){U(u);if(t!==t+0)throw t;Z(1,0)}}function xc(a){var b=S();try{return Qc(a)}catch(c){U(b);if(c!==c+0)throw c;Z(1,0)}}\r\nfunction uc(a,b,c,e,f,h,k){var l=S();try{return Rc(a,b,c,e,f,h,k)}catch(u){U(l);if(u!==u+0)throw u;Z(1,0)}}function vc(a,b,c,e,f){var h=S();try{return Zc(a,b,c,e,f)}catch(k){U(h);if(k!==k+0)throw k;Z(1,0)}}function zc(a,b,c){var e=S();try{return Sc(a,b,c)}catch(f){U(e);if(f!==f+0)throw f;Z(1,0)}}x.UTF8ToString=Aa;x.stringToUTF8=function(a,b,c){return Ba(a,q(),b,c)};x.lengthBytesUTF8=Ca;x.keepRuntimeAlive=F;x.wasmMemory=m;x.stackSave=S;x.stackRestore=U;x.stackAlloc=Kb;x.ExitStatus=E;x.PThread=P;var $c;\r\nM=function ad(){$c||bd();$c||(M=ad)};\r\nfunction bd(){function a(){if(!$c&&($c=!0,x.calledRun=!0,!xa)){C||R(Ga);ha(x);if(x.onRuntimeInitialized)x.onRuntimeInitialized();if(!C){if(x.postRun)for(\"function\"==typeof x.postRun&&(x.postRun=[x.postRun]);x.postRun.length;){var b=x.postRun.shift();Ia.unshift(b)}R(Ia)}}}if(!(0<L))if(C)ha(x),C||R(Ga),postMessage({cmd:\"loaded\"});else{if(x.preRun)for(\"function\"==typeof x.preRun&&(x.preRun=[x.preRun]);x.preRun.length;)Ka();R(Fa);0<L||(x.setStatus?(x.setStatus(\"Running...\"),setTimeout(function(){setTimeout(function(){x.setStatus(\"\")},\r\n1);a()},1)):a())}}if(x.preInit)for(\"function\"==typeof x.preInit&&(x.preInit=[x.preInit]);0<x.preInit.length;)x.preInit.pop()();bd();\r\n\r\n\r\n return ortWasmThreaded.ready\r\n}\r\n);\r\n})();\r\nif (true)\r\n module.exports = ortWasmThreaded;\r\nelse {}\r\n\n\n/***/ }),\n\n/***/ \"./lib/wasm/binding/ort-wasm.js\":\n/*!**************************************!*\\\n !*** ./lib/wasm/binding/ort-wasm.js ***!\n \\**************************************/\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\nvar __filename = \"/index.js\";\nvar __dirname = \"/\";\n\r\nvar ortWasm = (() => {\r\n var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined;\r\n if (true) _scriptDir = _scriptDir || __filename;\r\n return (\r\nfunction(ortWasm) {\r\n ortWasm = ortWasm || {};\r\n\r\n\r\nvar d;d||(d=typeof ortWasm !== 'undefined' ? ortWasm : {});var aa,ba;d.ready=new Promise(function(a,b){aa=a;ba=b});var ca=Object.assign({},d),da=\"./this.program\",ea=(a,b)=>{throw b;},fa=\"object\"==typeof window,m=\"function\"==typeof importScripts,p=\"object\"==typeof process&&\"object\"==typeof process.versions&&\"string\"==typeof process.versions.node,q=\"\",ha,r,v,fs,y,ia;\r\nif(p)q=m?(__webpack_require__(/*! path */ \"?75c6\").dirname)(q)+\"/\":__dirname+\"/\",ia=()=>{y||(fs=__webpack_require__(/*! fs */ \"?63c8\"),y=__webpack_require__(/*! path */ \"?75c6\"))},ha=function(a,b){ia();a=y.normalize(a);return fs.readFileSync(a,b?void 0:\"utf8\")},v=a=>{a=ha(a,!0);a.buffer||(a=new Uint8Array(a));return a},r=(a,b,c)=>{ia();a=y.normalize(a);fs.readFile(a,function(e,f){e?c(e):b(f.buffer)})},1<process.argv.length&&(da=process.argv[1].replace(/\\\\/g,\"/\")),process.argv.slice(2),process.on(\"uncaughtException\",function(a){if(!(a instanceof ja))throw a;}),process.on(\"unhandledRejection\",\r\nfunction(a){throw a;}),ea=(a,b)=>{if(noExitRuntime||0<ka)throw process.exitCode=a,b;b instanceof ja||z(\"exiting due to exception: \"+b);process.exit(a)},d.inspect=function(){return\"[Emscripten Module object]\"};else if(fa||m)m?q=self.location.href:\"undefined\"!=typeof document&&document.currentScript&&(q=document.currentScript.src),_scriptDir&&(q=_scriptDir),0!==q.indexOf(\"blob:\")?q=q.substr(0,q.replace(/[?#].*/,\"\").lastIndexOf(\"/\")+1):q=\"\",ha=a=>{var b=new XMLHttpRequest;b.open(\"GET\",a,!1);b.send(null);\r\nreturn b.responseText},m&&(v=a=>{var b=new XMLHttpRequest;b.open(\"GET\",a,!1);b.responseType=\"arraybuffer\";b.send(null);return new Uint8Array(b.response)}),r=(a,b,c)=>{var e=new XMLHttpRequest;e.open(\"GET\",a,!0);e.responseType=\"arraybuffer\";e.onload=()=>{200==e.status||0==e.status&&e.response?b(e.response):c()};e.onerror=c;e.send(null)};var la=d.print||console.log.bind(console),z=d.printErr||console.warn.bind(console);Object.assign(d,ca);ca=null;d.thisProgram&&(da=d.thisProgram);d.quit&&(ea=d.quit);\r\nvar A;d.wasmBinary&&(A=d.wasmBinary);var noExitRuntime=d.noExitRuntime||!1;\"object\"!=typeof WebAssembly&&B(\"no native wasm support detected\");var ma,D=!1,na=\"undefined\"!=typeof TextDecoder?new TextDecoder(\"utf8\"):void 0;\r\nfunction oa(a,b,c){b>>>=0;var e=b+c;for(c=b;a[c]&&!(c>=e);)++c;if(16<c-b&&a.buffer&&na)return na.decode(a.subarray(b,c));for(e=\"\";b<c;){var f=a[b++];if(f&128){var h=a[b++]&63;if(192==(f&224))e+=String.fromCharCode((f&31)<<6|h);else{var k=a[b++]&63;f=224==(f&240)?(f&15)<<12|h<<6|k:(f&7)<<18|h<<12|k<<6|a[b++]&63;65536>f?e+=String.fromCharCode(f):(f-=65536,e+=String.fromCharCode(55296|f>>10,56320|f&1023))}}else e+=String.fromCharCode(f)}return e}function pa(a,b){return(a>>>=0)?oa(G,a,b):\"\"}\r\nfunction qa(a,b,c,e){c>>>=0;if(!(0<e))return 0;var f=c;e=c+e-1;for(var h=0;h<a.length;++h){var k=a.charCodeAt(h);if(55296<=k&&57343>=k){var l=a.charCodeAt(++h);k=65536+((k&1023)<<10)|l&1023}if(127>=k){if(c>=e)break;b[c++>>>0]=k}else{if(2047>=k){if(c+1>=e)break;b[c++>>>0]=192|k>>6}else{if(65535>=k){if(c+2>=e)break;b[c++>>>0]=224|k>>12}else{if(c+3>=e)break;b[c++>>>0]=240|k>>18;b[c++>>>0]=128|k>>12&63}b[c++>>>0]=128|k>>6&63}b[c++>>>0]=128|k&63}}b[c>>>0]=0;return c-f}\r\nfunction ra(a){for(var b=0,c=0;c<a.length;++c){var e=a.charCodeAt(c);127>=e?b++:2047>=e?b+=2:55296<=e&&57343>=e?(b+=4,++c):b+=3}return b}var sa,H,G,I,J;function ta(){var a=ma.buffer;sa=a;d.HEAP8=H=new Int8Array(a);d.HEAP16=new Int16Array(a);d.HEAP32=I=new Int32Array(a);d.HEAPU8=G=new Uint8Array(a);d.HEAPU16=new Uint16Array(a);d.HEAPU32=J=new Uint32Array(a);d.HEAPF32=new Float32Array(a);d.HEAPF64=new Float64Array(a)}var ua,va=[],wa=[],xa=[],ya=[],ka=0;\r\nfunction za(){var a=d.preRun.shift();va.unshift(a)}var K=0,Aa=null,L=null;function B(a){if(d.onAbort)d.onAbort(a);a=\"Aborted(\"+a+\")\";z(a);D=!0;a=new WebAssembly.RuntimeError(a+\". Build with -sASSERTIONS for more info.\");ba(a);throw a;}function Ba(){return N.startsWith(\"data:application/octet-stream;base64,\")}var N;N=\"ort-wasm.wasm\";if(!Ba()){var Ca=N;N=d.locateFile?d.locateFile(Ca,q):q+Ca}\r\nfunction Da(){var a=N;try{if(a==N&&A)return new Uint8Array(A);if(v)return v(a);throw\"both async and sync fetching of the wasm failed\";}catch(b){B(b)}}\r\nfunction Ea(){if(!A&&(fa||m)){if(\"function\"==typeof fetch&&!N.startsWith(\"file://\"))return fetch(N,{credentials:\"same-origin\"}).then(function(a){if(!a.ok)throw\"failed to load wasm binary file at '\"+N+\"'\";return a.arrayBuffer()}).catch(function(){return Da()});if(r)return new Promise(function(a,b){r(N,function(c){a(new Uint8Array(c))},b)})}return Promise.resolve().then(function(){return Da()})}function ja(a){this.name=\"ExitStatus\";this.message=\"Program terminated with exit(\"+a+\")\";this.status=a}\r\nfunction O(a){for(;0<a.length;)a.shift()(d)}var P=[],Q=0,R=0;\r\nfunction S(a){this.Db=a;this.zb=a-24;this.Ub=function(b){J[this.zb+4>>2>>>0]=b};this.Eb=function(){return J[this.zb+4>>2>>>0]};this.Sb=function(b){J[this.zb+8>>2>>>0]=b};this.Wb=function(){return J[this.zb+8>>2>>>0]};this.Tb=function(){I[this.zb>>2>>>0]=0};this.Ib=function(b){H[this.zb+12>>0>>>0]=b?1:0};this.Pb=function(){return 0!=H[this.zb+12>>0>>>0]};this.Jb=function(b){H[this.zb+13>>0>>>0]=b?1:0};this.Lb=function(){return 0!=H[this.zb+13>>0>>>0]};this.Rb=function(b,c){this.Fb(0);this.Ub(b);this.Sb(c);\r\nthis.Tb();this.Ib(!1);this.Jb(!1)};this.Nb=function(){I[this.zb>>2>>>0]+=1};this.Xb=function(){var b=I[this.zb>>2>>>0];I[this.zb>>2>>>0]=b-1;return 1===b};this.Fb=function(b){J[this.zb+16>>2>>>0]=b};this.Ob=function(){return J[this.zb+16>>2>>>0]};this.Qb=function(){if(Fa(this.Eb()))return J[this.Db>>2>>>0];var b=this.Ob();return 0!==b?b:this.Db}}function Ga(a){return Ha((new S(a)).zb)}var T=[];function U(a){var b=T[a];b||(a>=T.length&&(T.length=a+1),T[a]=b=ua.get(a));return b}\r\nfunction Ia(a){var b=ra(a)+1,c=Ja(b);c&&qa(a,H,c,b);return c}function Ka(a,b,c){function e(n){return(n=n.toTimeString().match(/\\(([A-Za-z ]+)\\)$/))?n[1]:\"GMT\"}var f=(new Date).getFullYear(),h=new Date(f,0,1),k=new Date(f,6,1);f=h.getTimezoneOffset();var l=k.getTimezoneOffset();I[a>>2>>>0]=60*Math.max(f,l);I[b>>2>>>0]=Number(f!=l);a=e(h);b=e(k);a=Ia(a);b=Ia(b);l<f?(J[c>>2>>>0]=a,J[c+4>>2>>>0]=b):(J[c>>2>>>0]=b,J[c+4>>2>>>0]=a)}function La(a,b,c){La.Vb||(La.Vb=!0,Ka(a,b,c))}var Ma={};\r\nfunction Na(){if(!Oa){var a={USER:\"web_user\",LOGNAME:\"web_user\",PATH:\"/\",PWD:\"/\",HOME:\"/home/web_user\",LANG:(\"object\"==typeof navigator&&navigator.languages&&navigator.languages[0]||\"C\").replace(\"-\",\"_\")+\".UTF-8\",_:da||\"./this.program\"},b;for(b in Ma)void 0===Ma[b]?delete a[b]:a[b]=Ma[b];var c=[];for(b in a)c.push(b+\"=\"+a[b]);Oa=c}return Oa}var Oa,Pa=[null,[],[]];function Qa(a,b){var c=Pa[a];0===b||10===b?((1===a?la:z)(oa(c,0)),c.length=0):c.push(b)}var V=0;\r\nfunction Ra(){if(\"object\"==typeof crypto&&\"function\"==typeof crypto.getRandomValues){var a=new Uint8Array(1);return()=>{crypto.getRandomValues(a);return a[0]}}if(p)try{var b=__webpack_require__(Object(function webpackMissingModule() { var e = new Error(\"Cannot find module 'crypto'\"); e.code = 'MODULE_NOT_FOUND'; throw e; }()));return()=>b.randomBytes(1)[0]}catch(c){}return()=>B(\"randomDevice\")}function W(a,b){W.Mb||(W.Mb=Ra());for(var c=0;c<b;c++)H[a+c>>0>>>0]=W.Mb();return 0}function Sa(a){return 0===a%4&&(0!==a%100||0===a%400)}var Ta=[31,29,31,30,31,30,31,31,30,31,30,31],Ua=[31,28,31,30,31,30,31,31,30,31,30,31];\r\nfunction Va(a){var b=Array(ra(a)+1);qa(a,b,0,b.length);return b}\r\nfunction Wa(a,b,c,e){function f(g,u,w){for(g=\"number\"==typeof g?g.toString():g||\"\";g.length<u;)g=w[0]+g;return g}function h(g,u){return f(g,u,\"0\")}function k(g,u){function w(M){return 0>M?-1:0<M?1:0}var F;0===(F=w(g.getFullYear()-u.getFullYear()))&&0===(F=w(g.getMonth()-u.getMonth()))&&(F=w(g.getDate()-u.getDate()));return F}function l(g){switch(g.getDay()){case 0:return new Date(g.getFullYear()-1,11,29);case 1:return g;case 2:return new Date(g.getFullYear(),0,3);case 3:return new Date(g.getFullYear(),\r\n0,2);case 4:return new Date(g.getFullYear(),0,1);case 5:return new Date(g.getFullYear()-1,11,31);case 6:return new Date(g.getFullYear()-1,11,30)}}function n(g){var u=g.Bb;for(g=new Date((new Date(g.Cb+1900,0,1)).getTime());0<u;){var w=g.getMonth(),F=(Sa(g.getFullYear())?Ta:Ua)[w];if(u>F-g.getDate())u-=F-g.getDate()+1,g.setDate(1),11>w?g.setMonth(w+1):(g.setMonth(0),g.setFullYear(g.getFullYear()+1));else{g.setDate(g.getDate()+u);break}}w=new Date(g.getFullYear()+1,0,4);u=l(new Date(g.getFullYear(),\r\n0,4));w=l(w);return 0>=k(u,g)?0>=k(w,g)?g.getFullYear()+1:g.getFullYear():g.getFullYear()-1}var t=I[e+40>>2>>>0];e={$b:I[e>>2>>>0],Zb:I[e+4>>2>>>0],Gb:I[e+8>>2>>>0],Kb:I[e+12>>2>>>0],Hb:I[e+16>>2>>>0],Cb:I[e+20>>2>>>0],Ab:I[e+24>>2>>>0],Bb:I[e+28>>2>>>0],bc:I[e+32>>2>>>0],Yb:I[e+36>>2>>>0],ac:t?pa(t):\"\"};c=pa(c);t={\"%c\":\"%a %b %d %H:%M:%S %Y\",\"%D\":\"%m/%d/%y\",\"%F\":\"%Y-%m-%d\",\"%h\":\"%b\",\"%r\":\"%I:%M:%S %p\",\"%R\":\"%H:%M\",\"%T\":\"%H:%M:%S\",\"%x\":\"%m/%d/%y\",\"%X\":\"%H:%M:%S\",\"%Ec\":\"%c\",\"%EC\":\"%C\",\"%Ex\":\"%m/%d/%y\",\r\n\"%EX\":\"%H:%M:%S\",\"%Ey\":\"%y\",\"%EY\":\"%Y\",\"%Od\":\"%d\",\"%Oe\":\"%e\",\"%OH\":\"%H\",\"%OI\":\"%I\",\"%Om\":\"%m\",\"%OM\":\"%M\",\"%OS\":\"%S\",\"%Ou\":\"%u\",\"%OU\":\"%U\",\"%OV\":\"%V\",\"%Ow\":\"%w\",\"%OW\":\"%W\",\"%Oy\":\"%y\"};for(var x in t)c=c.replace(new RegExp(x,\"g\"),t[x]);var E=\"Sunday Monday Tuesday Wednesday Thursday Friday Saturday\".split(\" \"),C=\"January February March April May June July August September October November December\".split(\" \");t={\"%a\":function(g){return E[g.Ab].substring(0,3)},\"%A\":function(g){return E[g.Ab]},\"%b\":function(g){return C[g.Hb].substring(0,\r\n3)},\"%B\":function(g){return C[g.Hb]},\"%C\":function(g){return h((g.Cb+1900)/100|0,2)},\"%d\":function(g){return h(g.Kb,2)},\"%e\":function(g){return f(g.Kb,2,\" \")},\"%g\":function(g){return n(g).toString().substring(2)},\"%G\":function(g){return n(g)},\"%H\":function(g){return h(g.Gb,2)},\"%I\":function(g){g=g.Gb;0==g?g=12:12<g&&(g-=12);return h(g,2)},\"%j\":function(g){for(var u=0,w=0;w<=g.Hb-1;u+=(Sa(g.Cb+1900)?Ta:Ua)[w++]);return h(g.Kb+u,3)},\"%m\":function(g){return h(g.Hb+1,2)},\"%M\":function(g){return h(g.Zb,\r\n2)},\"%n\":function(){return\"\\n\"},\"%p\":function(g){return 0<=g.Gb&&12>g.Gb?\"AM\":\"PM\"},\"%S\":function(g){return h(g.$b,2)},\"%t\":function(){return\"\\t\"},\"%u\":function(g){return g.Ab||7},\"%U\":function(g){return h(Math.floor((g.Bb+7-g.Ab)/7),2)},\"%V\":function(g){var u=Math.floor((g.Bb+7-(g.Ab+6)%7)/7);2>=(g.Ab+371-g.Bb-2)%7&&u++;if(u)53==u&&(w=(g.Ab+371-g.Bb)%7,4==w||3==w&&Sa(g.Cb)||(u=1));else{u=52;var w=(g.Ab+7-g.Bb-1)%7;(4==w||5==w&&Sa(g.Cb%400-1))&&u++}return h(u,2)},\"%w\":function(g){return g.Ab},\"%W\":function(g){return h(Math.floor((g.Bb+\r\n7-(g.Ab+6)%7)/7),2)},\"%y\":function(g){return(g.Cb+1900).toString().substring(2)},\"%Y\":function(g){return g.Cb+1900},\"%z\":function(g){g=g.Yb;var u=0<=g;g=Math.abs(g)/60;return(u?\"+\":\"-\")+String(\"0000\"+(g/60*100+g%60)).slice(-4)},\"%Z\":function(g){return g.ac},\"%%\":function(){return\"%\"}};c=c.replace(/%%/g,\"\\x00\\x00\");for(x in t)c.includes(x)&&(c=c.replace(new RegExp(x,\"g\"),t[x](e)));c=c.replace(/\\0\\0/g,\"%\");x=Va(c);if(x.length>b)return 0;H.set(x,a>>>0);return x.length-1}\r\nvar Jb={a:function(a){return Ja(a+24)+24},m:function(a){a=new S(a);a.Pb()||(a.Ib(!0),Q--);a.Jb(!1);P.push(a);a.Nb();return a.Qb()},ia:function(a){z(\"Unexpected exception thrown, this is not properly supported - aborting\");D=!0;throw a;},w:function(){X(0);var a=P.pop();if(a.Xb()&&!a.Lb()){var b=a.Wb();b&&U(b)(a.Db);Ga(a.Db)}R=0},d:function(){var a=R;if(!a)return V=0;var b=new S(a);b.Fb(a);var c=b.Eb();if(!c)return V=0,a;for(var e=Array.prototype.slice.call(arguments),f=0;f<e.length;f++){var h=e[f];\r\nif(0===h||h===c)break;if(Xa(h,c,b.zb+16))return V=h,a}V=c;return a},k:function(){var a=R;if(!a)return V=0;var b=new S(a);b.Fb(a);var c=b.Eb();if(!c)return V=0,a;for(var e=Array.prototype.slice.call(arguments),f=0;f<e.length;f++){var h=e[f];if(0===h||h===c)break;if(Xa(h,c,b.zb+16))return V=h,a}V=c;return a},g:function(){var a=R;if(!a)return V=0;var b=new S(a);b.Fb(a);var c=b.Eb();if(!c)return V=0,a;for(var e=Array.prototype.slice.call(arguments),f=0;f<e.length;f++){var h=e[f];if(0===h||h===c)break;\r\nif(Xa(h,c,b.zb+16))return V=h,a}V=c;return a},s:Ga,L:function(){var a=P.pop();a||B(\"no exception to throw\");var b=a.Db;a.Lb()||(P.push(a),a.Jb(!0),a.Ib(!1),Q++);R=b;throw b;},b:function(a,b,c){(new S(a)).Rb(b,c);R=a;Q++;throw a;},la:function(){return Q},i:function(a){R||(R=a);throw a;},H:function(){return 0},Ba:function(){},pa:function(){},ra:function(){},ka:function(){return 0},za:function(){},ua:function(){},ya:function(){},R:function(){},qa:function(){},na:function(){},Aa:function(){},oa:function(){},\r\nHa:function(){},Ja:function(){B(\"To use dlopen, you need enable dynamic linking, see https://github.com/emscripten-core/emscripten/wiki/Linking\")},Ia:function(){B(\"To use dlopen, you need enable dynamic linking, see https://github.com/emscripten-core/emscripten/wiki/Linking\")},S:function(){return Date.now()},Ca:function(){return!0},Da:function(a,b){a=new Date(1E3*(J[a>>>2]+4294967296*I[a+4>>>2]));I[b>>2>>>0]=a.getUTCSeconds();I[b+4>>2>>>0]=a.getUTCMinutes();I[b+8>>2>>>0]=a.getUTCHours();I[b+12>>2>>>\r\n0]=a.getUTCDate();I[b+16>>2>>>0]=a.getUTCMonth();I[b+20>>2>>>0]=a.getUTCFullYear()-1900;I[b+24>>2>>>0]=a.getUTCDay();I[b+28>>2>>>0]=(a.getTime()-Date.UTC(a.getUTCFullYear(),0,1,0,0,0,0))/864E5|0},Ea:function(a,b){a=new Date(1E3*(J[a>>>2]+4294967296*I[a+4>>>2]));I[b>>2>>>0]=a.getSeconds();I[b+4>>2>>>0]=a.getMinutes();I[b+8>>2>>>0]=a.getHours();I[b+12>>2>>>0]=a.getDate();I[b+16>>2>>>0]=a.getMonth();I[b+20>>2>>>0]=a.getFullYear()-1900;I[b+24>>2>>>0]=a.getDay();var c=new Date(a.getFullYear(),0,1);I[b+\r\n28>>2>>>0]=(a.getTime()-c.getTime())/864E5|0;I[b+36>>2>>>0]=-(60*a.getTimezoneOffset());var e=(new Date(a.getFullYear(),6,1)).getTimezoneOffset();c=c.getTimezoneOffset();I[b+32>>2>>>0]=(e!=c&&a.getTimezoneOffset()==Math.min(c,e))|0},Fa:function(a){var b=new Date(I[a+20>>2>>>0]+1900,I[a+16>>2>>>0],I[a+12>>2>>>0],I[a+8>>2>>>0],I[a+4>>2>>>0],I[a>>2>>>0],0),c=I[a+32>>2>>>0],e=b.getTimezoneOffset(),f=new Date(b.getFullYear(),0,1),h=(new Date(b.getFullYear(),6,1)).getTimezoneOffset(),k=f.getTimezoneOffset(),\r\nl=Math.min(k,h);0>c?I[a+32>>2>>>0]=Number(h!=k&&l==e):0<c!=(l==e)&&(h=Math.max(k,h),b.setTime(b.getTime()+6E4*((0<c?l:h)-e)));I[a+24>>2>>>0]=b.getDay();I[a+28>>2>>>0]=(b.getTime()-f.getTime())/864E5|0;I[a>>2>>>0]=b.getSeconds();I[a+4>>2>>>0]=b.getMinutes();I[a+8>>2>>>0]=b.getHours();I[a+12>>2>>>0]=b.getDate();I[a+16>>2>>>0]=b.getMonth();return b.getTime()/1E3|0},sa:function(){return-52},ta:function(){},Ga:La,B:function(){B(\"\")},ma:function(){return 4294901760},I:p?()=>{var a=process.hrtime();return 1E3*\r\na[0]+a[1]/1E6}:()=>performance.now(),xa:function(a,b,c){G.copyWithin(a>>>0,b>>>0,b+c>>>0)},G:function(a){var b=G.length;a>>>=0;if(4294901760<a)return!1;for(var c=1;4>=c;c*=2){var e=b*(1+.2/c);e=Math.min(e,a+100663296);var f=Math;e=Math.max(a,e);f=f.min.call(f,4294901760,e+(65536-e%65536)%65536);a:{try{ma.grow(f-sa.byteLength+65535>>>16);ta();var h=1;break a}catch(k){}h=void 0}if(h)return!0}return!1},va:function(a,b){var c=0;Na().forEach(function(e,f){var h=b+c;f=J[a+4*f>>2>>>0]=h;for(h=0;h<e.length;++h)H[f++>>\r\n0>>>0]=e.charCodeAt(h);H[f>>0>>>0]=0;c+=e.length+1});return 0},wa:function(a,b){var c=Na();J[a>>2>>>0]=c.length;var e=0;c.forEach(function(f){e+=f.length+1});J[b>>2>>>0]=e;return 0},ba:function(a){noExitRuntime||0<ka||(Ya(),O(xa),Za(0),Pa[1].length&&Qa(1,10),Pa[2].length&&Qa(2,10));if(!(noExitRuntime||0<ka)){if(d.onExit)d.onExit(a);D=!0}ea(a,new ja(a))},E:function(){return 52},Q:function(){return 52},ca:function(){return 70},P:function(a,b,c,e){for(var f=0,h=0;h<c;h++){var k=J[b>>2>>>0],l=J[b+4>>\r\n2>>>0];b+=8;for(var n=0;n<l;n++)Qa(a,G[k+n>>>0]);f+=l}J[e>>2>>>0]=f;return 0},c:function(){return V},ja:W,ea:$a,fa:ab,J:bb,e:cb,N:db,O:eb,j:fb,o:gb,p:hb,M:ib,r:jb,v:kb,K:lb,D:mb,X:nb,V:ob,U:pb,Z:qb,W:rb,Y:sb,T:tb,f:ub,q:vb,h:wb,da:xb,l:yb,t:zb,u:Ab,x:Bb,z:Cb,ga:Db,A:Eb,C:Fb,aa:Gb,_:Hb,$:Ib,n:function(a){return a},F:function(a){V=a},ha:Wa,y:function(a,b,c,e){return Wa(a,b,c,e)}};\r\n(function(){function a(f){d.asm=f.exports;ma=d.asm.Ka;ta();ua=d.asm.ib;wa.unshift(d.asm.La);K--;d.monitorRunDependencies&&d.monitorRunDependencies(K);0==K&&(null!==Aa&&(clearInterval(Aa),Aa=null),L&&(f=L,L=null,f()))}function b(f){a(f.instance)}function c(f){return Ea().then(function(h){return WebAssembly.instantiate(h,e)}).then(function(h){return h}).then(f,function(h){z(\"failed to asynchronously prepare wasm: \"+h);B(h)})}var e={a:Jb};K++;d.monitorRunDependencies&&d.monitorRunDependencies(K);if(d.instantiateWasm)try{return d.instantiateWasm(e,\r\na)}catch(f){return z(\"Module.instantiateWasm callback failed with error: \"+f),!1}(function(){return A||\"function\"!=typeof WebAssembly.instantiateStreaming||Ba()||N.startsWith(\"file://\")||p||\"function\"!=typeof fetch?c(b):fetch(N,{credentials:\"same-origin\"}).then(function(f){return WebAssembly.instantiateStreaming(f,e).then(b,function(h){z(\"wasm streaming compile failed: \"+h);z(\"falling back to ArrayBuffer instantiation\");return c(b)})})})().catch(ba);return{}})();\r\nd.___wasm_call_ctors=function(){return(d.___wasm_call_ctors=d.asm.La).apply(null,arguments)};d._OrtInit=function(){return(d._OrtInit=d.asm.Ma).apply(null,arguments)};d._OrtCreateSessionOptions=function(){return(d._OrtCreateSessionOptions=d.asm.Na).apply(null,arguments)};d._OrtAppendExecutionProvider=function(){return(d._OrtAppendExecutionProvider=d.asm.Oa).apply(null,arguments)};d._OrtAddSessionConfigEntry=function(){return(d._OrtAddSessionConfigEntry=d.asm.Pa).apply(null,arguments)};\r\nd._OrtReleaseSessionOptions=function(){return(d._OrtReleaseSessionOptions=d.asm.Qa).apply(null,arguments)};d._OrtCreateSession=function(){return(d._OrtCreateSession=d.asm.Ra).apply(null,arguments)};d._OrtReleaseSession=function(){return(d._OrtReleaseSession=d.asm.Sa).apply(null,arguments)};d._OrtGetInputCount=function(){return(d._OrtGetInputCount=d.asm.Ta).apply(null,arguments)};d._OrtGetOutputCount=function(){return(d._OrtGetOutputCount=d.asm.Ua).apply(null,arguments)};\r\nd._OrtGetInputName=function(){return(d._OrtGetInputName=d.asm.Va).apply(null,arguments)};d._OrtGetOutputName=function(){return(d._OrtGetOutputName=d.asm.Wa).apply(null,arguments)};d._OrtFree=function(){return(d._OrtFree=d.asm.Xa).apply(null,arguments)};d._OrtCreateTensor=function(){return(d._OrtCreateTensor=d.asm.Ya).apply(null,arguments)};d._OrtGetTensorData=function(){return(d._OrtGetTensorData=d.asm.Za).apply(null,arguments)};\r\nd._OrtReleaseTensor=function(){return(d._OrtReleaseTensor=d.asm._a).apply(null,arguments)};d._OrtCreateRunOptions=function(){return(d._OrtCreateRunOptions=d.asm.$a).apply(null,arguments)};d._OrtAddRunConfigEntry=function(){return(d._OrtAddRunConfigEntry=d.asm.ab).apply(null,arguments)};d._OrtReleaseRunOptions=function(){return(d._OrtReleaseRunOptions=d.asm.bb).apply(null,arguments)};d._OrtRun=function(){return(d._OrtRun=d.asm.cb).apply(null,arguments)};\r\nd._OrtEndProfiling=function(){return(d._OrtEndProfiling=d.asm.db).apply(null,arguments)};\r\nvar Ja=d._malloc=function(){return(Ja=d._malloc=d.asm.eb).apply(null,arguments)},Ha=d._free=function(){return(Ha=d._free=d.asm.fb).apply(null,arguments)},Za=d._fflush=function(){return(Za=d._fflush=d.asm.gb).apply(null,arguments)},Ya=d.___funcs_on_exit=function(){return(Ya=d.___funcs_on_exit=d.asm.hb).apply(null,arguments)},X=d._setThrew=function(){return(X=d._setThrew=d.asm.jb).apply(null,arguments)},Y=d.stackSave=function(){return(Y=d.stackSave=d.asm.kb).apply(null,arguments)},Z=d.stackRestore=\r\nfunction(){return(Z=d.stackRestore=d.asm.lb).apply(null,arguments)},Kb=d.stackAlloc=function(){return(Kb=d.stackAlloc=d.asm.mb).apply(null,arguments)},Xa=d.___cxa_can_catch=function(){return(Xa=d.___cxa_can_catch=d.asm.nb).apply(null,arguments)},Fa=d.___cxa_is_pointer_type=function(){return(Fa=d.___cxa_is_pointer_type=d.asm.ob).apply(null,arguments)},Lb=d.dynCall_j=function(){return(Lb=d.dynCall_j=d.asm.pb).apply(null,arguments)},Mb=d.dynCall_iiiiij=function(){return(Mb=d.dynCall_iiiiij=d.asm.qb).apply(null,\r\narguments)},Nb=d.dynCall_jii=function(){return(Nb=d.dynCall_jii=d.asm.rb).apply(null,arguments)},Ob=d.dynCall_viiiiij=function(){return(Ob=d.dynCall_viiiiij=d.asm.sb).apply(null,arguments)},Pb=d.dynCall_vjji=function(){return(Pb=d.dynCall_vjji=d.asm.tb).apply(null,arguments)},Qb=d.dynCall_viiijjjii=function(){return(Qb=d.dynCall_viiijjjii=d.asm.ub).apply(null,arguments)},Rb=d.dynCall_iij=function(){return(Rb=d.dynCall_iij=d.asm.vb).apply(null,arguments)},Sb=d.dynCall_ji=function(){return(Sb=d.dynCall_ji=\r\nd.asm.wb).apply(null,arguments)},Tb=d.dynCall_iiiiiij=function(){return(Tb=d.dynCall_iiiiiij=d.asm.xb).apply(null,arguments)},Ub=d.dynCall_iiij=function(){return(Ub=d.dynCall_iiij=d.asm.yb).apply(null,arguments)};function cb(a,b){var c=Y();try{return U(a)(b)}catch(e){Z(c);if(e!==e+0)throw e;X(1,0)}}function vb(a,b){var c=Y();try{U(a)(b)}catch(e){Z(c);if(e!==e+0)throw e;X(1,0)}}function wb(a,b,c){var e=Y();try{U(a)(b,c)}catch(f){Z(e);if(f!==f+0)throw f;X(1,0)}}\r\nfunction fb(a,b,c){var e=Y();try{return U(a)(b,c)}catch(f){Z(e);if(f!==f+0)throw f;X(1,0)}}function gb(a,b,c,e){var f=Y();try{return U(a)(b,c,e)}catch(h){Z(f);if(h!==h+0)throw h;X(1,0)}}function kb(a,b,c,e,f,h,k){var l=Y();try{return U(a)(b,c,e,f,h,k)}catch(n){Z(l);if(n!==n+0)throw n;X(1,0)}}function ub(a){var b=Y();try{U(a)()}catch(c){Z(b);if(c!==c+0)throw c;X(1,0)}}function jb(a,b,c,e,f,h){var k=Y();try{return U(a)(b,c,e,f,h)}catch(l){Z(k);if(l!==l+0)throw l;X(1,0)}}\r\nfunction hb(a,b,c,e,f){var h=Y();try{return U(a)(b,c,e,f)}catch(k){Z(h);if(k!==k+0)throw k;X(1,0)}}function yb(a,b,c,e){var f=Y();try{U(a)(b,c,e)}catch(h){Z(f);if(h!==h+0)throw h;X(1,0)}}function Ab(a,b,c,e,f,h){var k=Y();try{U(a)(b,c,e,f,h)}catch(l){Z(k);if(l!==l+0)throw l;X(1,0)}}function zb(a,b,c,e,f){var h=Y();try{U(a)(b,c,e,f)}catch(k){Z(h);if(k!==k+0)throw k;X(1,0)}}function Bb(a,b,c,e,f,h,k){var l=Y();try{U(a)(b,c,e,f,h,k)}catch(n){Z(l);if(n!==n+0)throw n;X(1,0)}}\r\nfunction Cb(a,b,c,e,f,h,k,l){var n=Y();try{U(a)(b,c,e,f,h,k,l)}catch(t){Z(n);if(t!==t+0)throw t;X(1,0)}}function eb(a,b,c){var e=Y();try{return U(a)(b,c)}catch(f){Z(e);if(f!==f+0)throw f;X(1,0)}}function db(a,b,c){var e=Y();try{return U(a)(b,c)}catch(f){Z(e);if(f!==f+0)throw f;X(1,0)}}function Db(a,b,c,e,f,h,k,l,n){var t=Y();try{U(a)(b,c,e,f,h,k,l,n)}catch(x){Z(t);if(x!==x+0)throw x;X(1,0)}}function ib(a,b,c,e,f,h){var k=Y();try{return U(a)(b,c,e,f,h)}catch(l){Z(k);if(l!==l+0)throw l;X(1,0)}}\r\nfunction lb(a,b,c,e,f,h,k,l){var n=Y();try{return U(a)(b,c,e,f,h,k,l)}catch(t){Z(n);if(t!==t+0)throw t;X(1,0)}}function mb(a,b,c,e,f,h,k,l,n,t,x,E){var C=Y();try{return U(a)(b,c,e,f,h,k,l,n,t,x,E)}catch(g){Z(C);if(g!==g+0)throw g;X(1,0)}}function Eb(a,b,c,e,f,h,k,l,n,t,x){var E=Y();try{U(a)(b,c,e,f,h,k,l,n,t,x)}catch(C){Z(E);if(C!==C+0)throw C;X(1,0)}}function Fb(a,b,c,e,f,h,k,l,n,t,x,E,C,g,u,w){var F=Y();try{U(a)(b,c,e,f,h,k,l,n,t,x,E,C,g,u,w)}catch(M){Z(F);if(M!==M+0)throw M;X(1,0)}}\r\nfunction bb(a){var b=Y();try{return U(a)()}catch(c){Z(b);if(c!==c+0)throw c;X(1,0)}}function ab(a,b,c){var e=Y();try{return U(a)(b,c)}catch(f){Z(e);if(f!==f+0)throw f;X(1,0)}}function $a(a,b,c){var e=Y();try{return U(a)(b,c)}catch(f){Z(e);if(f!==f+0)throw f;X(1,0)}}function xb(a,b,c,e){var f=Y();try{U(a)(b,c,e)}catch(h){Z(f);if(h!==h+0)throw h;X(1,0)}}function Gb(a,b,c,e,f,h,k,l){var n=Y();try{Ob(a,b,c,e,f,h,k,l)}catch(t){Z(n);if(t!==t+0)throw t;X(1,0)}}\r\nfunction Ib(a,b,c,e,f,h){var k=Y();try{Pb(a,b,c,e,f,h)}catch(l){Z(k);if(l!==l+0)throw l;X(1,0)}}function Hb(a,b,c,e,f,h,k,l,n,t,x,E){var C=Y();try{Qb(a,b,c,e,f,h,k,l,n,t,x,E)}catch(g){Z(C);if(g!==g+0)throw g;X(1,0)}}function qb(a,b,c,e){var f=Y();try{return Rb(a,b,c,e)}catch(h){Z(f);if(h!==h+0)throw h;X(1,0)}}function sb(a,b){var c=Y();try{return Sb(a,b)}catch(e){Z(c);if(e!==e+0)throw e;X(1,0)}}\r\nfunction nb(a,b,c,e,f,h,k,l){var n=Y();try{return Tb(a,b,c,e,f,h,k,l)}catch(t){Z(n);if(t!==t+0)throw t;X(1,0)}}function rb(a){var b=Y();try{return Lb(a)}catch(c){Z(b);if(c!==c+0)throw c;X(1,0)}}function ob(a,b,c,e,f,h,k){var l=Y();try{return Mb(a,b,c,e,f,h,k)}catch(n){Z(l);if(n!==n+0)throw n;X(1,0)}}function pb(a,b,c,e,f){var h=Y();try{return Ub(a,b,c,e,f)}catch(k){Z(h);if(k!==k+0)throw k;X(1,0)}}function tb(a,b,c){var e=Y();try{return Nb(a,b,c)}catch(f){Z(e);if(f!==f+0)throw f;X(1,0)}}\r\nd.UTF8ToString=pa;d.stringToUTF8=function(a,b,c){return qa(a,G,b,c)};d.lengthBytesUTF8=ra;d.stackSave=Y;d.stackRestore=Z;d.stackAlloc=Kb;var Vb;L=function Wb(){Vb||Xb();Vb||(L=Wb)};\r\nfunction Xb(){function a(){if(!Vb&&(Vb=!0,d.calledRun=!0,!D)){O(wa);aa(d);if(d.onRuntimeInitialized)d.onRuntimeInitialized();if(d.postRun)for(\"function\"==typeof d.postRun&&(d.postRun=[d.postRun]);d.postRun.length;){var b=d.postRun.shift();ya.unshift(b)}O(ya)}}if(!(0<K)){if(d.preRun)for(\"function\"==typeof d.preRun&&(d.preRun=[d.preRun]);d.preRun.length;)za();O(va);0<K||(d.setStatus?(d.setStatus(\"Running...\"),setTimeout(function(){setTimeout(function(){d.setStatus(\"\")},1);a()},1)):a())}}\r\nif(d.preInit)for(\"function\"==typeof d.preInit&&(d.preInit=[d.preInit]);0<d.preInit.length;)d.preInit.pop()();Xb();\r\n\r\n\r\n return ortWasm.ready\r\n}\r\n);\r\n})();\r\nif (true)\r\n module.exports = ortWasm;\r\nelse {}\r\n\n\n/***/ }),\n\n/***/ \"./lib/wasm/options-utils.ts\":\n/*!***********************************!*\\\n !*** ./lib/wasm/options-utils.ts ***!\n \\***********************************/\n/***/ ((__unused_webpack_module, exports) => {\n\n\"use strict\";\n\n// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT License.\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.iterateExtraOptions = void 0;\nconst iterateExtraOptions = (options, prefix, seen, handler) => {\n if (typeof options == 'object' && options !== null) {\n if (seen.has(options)) {\n throw new Error('Circular reference in options');\n }\n else {\n seen.add(options);\n }\n }\n Object.entries(options).forEach(([key, value]) => {\n const name = (prefix) ? prefix + key : key;\n if (typeof value === 'object') {\n (0, exports.iterateExtraOptions)(value, name + '.', seen, handler);\n }\n else if (typeof value === 'string' || typeof value === 'number') {\n handler(name, value.toString());\n }\n else if (typeof value === 'boolean') {\n handler(name, (value) ? '1' : '0');\n }\n else {\n throw new Error(`Can't handle extra config type: ${typeof value}`);\n }\n });\n};\nexports.iterateExtraOptions = iterateExtraOptions;\n\n\n/***/ }),\n\n/***/ \"./lib/wasm/run-options.ts\":\n/*!*********************************!*\\\n !*** ./lib/wasm/run-options.ts ***!\n \\*********************************/\n/***/ ((__unused_webpack_module, exports, __webpack_require__) => {\n\n\"use strict\";\n\n// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT License.\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.setRunOptions = void 0;\nconst options_utils_1 = __webpack_require__(/*! ./options-utils */ \"./lib/wasm/options-utils.ts\");\nconst string_utils_1 = __webpack_require__(/*! ./string-utils */ \"./lib/wasm/string-utils.ts\");\nconst wasm_factory_1 = __webpack_require__(/*! ./wasm-factory */ \"./lib/wasm/wasm-factory.ts\");\nconst setRunOptions = (options) => {\n const wasm = (0, wasm_factory_1.getInstance)();\n let runOptionsHandle = 0;\n const allocs = [];\n const runOptions = options || {};\n try {\n if ((options === null || options === void 0 ? void 0 : options.logSeverityLevel) === undefined) {\n runOptions.logSeverityLevel = 2; // Default to warning\n }\n else if (typeof options.logSeverityLevel !== 'number' || !Number.isInteger(options.logSeverityLevel) ||\n options.logSeverityLevel < 0 || options.logSeverityLevel > 4) {\n throw new Error(`log serverity level is not valid: ${options.logSeverityLevel}`);\n }\n if ((options === null || options === void 0 ? void 0 : options.logVerbosityLevel) === undefined) {\n runOptions.logVerbosityLevel = 0; // Default to 0\n }\n else if (typeof options.logVerbosityLevel !== 'number' || !Number.isInteger(options.logVerbosityLevel)) {\n throw new Error(`log verbosity level is not valid: ${options.logVerbosityLevel}`);\n }\n if ((options === null || options === void 0 ? void 0 : options.terminate) === undefined) {\n runOptions.terminate = false;\n }\n let tagDataOffset = 0;\n if ((options === null || options === void 0 ? void 0 : options.tag) !== undefined) {\n tagDataOffset = (0, string_utils_1.allocWasmString)(options.tag, allocs);\n }\n runOptionsHandle = wasm._OrtCreateRunOptions(runOptions.logSeverityLevel, runOptions.logVerbosityLevel, !!runOptions.terminate, tagDataOffset);\n if (runOptionsHandle === 0) {\n throw new Error('Can\\'t create run options');\n }\n if ((options === null || options === void 0 ? void 0 : options.extra) !== undefined) {\n (0, options_utils_1.iterateExtraOptions)(options.extra, '', new WeakSet(), (key, value) => {\n const keyDataOffset = (0, string_utils_1.allocWasmString)(key, allocs);\n const valueDataOffset = (0, string_utils_1.allocWasmString)(value, allocs);\n if (wasm._OrtAddRunConfigEntry(runOptionsHandle, keyDataOffset, valueDataOffset) !== 0) {\n throw new Error(`Can't set a run config entry: ${key} - ${value}`);\n }\n });\n }\n return [runOptionsHandle, allocs];\n }\n catch (e) {\n if (runOptionsHandle !== 0) {\n wasm._OrtReleaseRunOptions(runOptionsHandle);\n }\n allocs.forEach(wasm._free);\n throw e;\n }\n};\nexports.setRunOptions = setRunOptions;\n\n\n/***/ }),\n\n/***/ \"./lib/wasm/session-options.ts\":\n/*!*************************************!*\\\n !*** ./lib/wasm/session-options.ts ***!\n \\*************************************/\n/***/ ((__unused_webpack_module, exports, __webpack_require__) => {\n\n\"use strict\";\n\n// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT License.\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.setSessionOptions = void 0;\nconst options_utils_1 = __webpack_require__(/*! ./options-utils */ \"./lib/wasm/options-utils.ts\");\nconst string_utils_1 = __webpack_require__(/*! ./string-utils */ \"./lib/wasm/string-utils.ts\");\nconst wasm_factory_1 = __webpack_require__(/*! ./wasm-factory */ \"./lib/wasm/wasm-factory.ts\");\nconst getGraphOptimzationLevel = (graphOptimizationLevel) => {\n switch (graphOptimizationLevel) {\n case 'disabled':\n return 0;\n case 'basic':\n return 1;\n case 'extended':\n return 2;\n case 'all':\n return 99;\n default:\n throw new Error(`unsupported graph optimization level: ${graphOptimizationLevel}`);\n }\n};\nconst getExecutionMode = (executionMode) => {\n switch (executionMode) {\n case 'sequential':\n return 0;\n case 'parallel':\n return 1;\n default:\n throw new Error(`unsupported execution mode: ${executionMode}`);\n }\n};\nconst appendDefaultOptions = (options) => {\n if (!options.extra) {\n options.extra = {};\n }\n if (!options.extra.session) {\n options.extra.session = {};\n }\n const session = options.extra.session;\n if (!session.use_ort_model_bytes_directly) {\n // eslint-disable-next-line camelcase\n session.use_ort_model_bytes_directly = '1';\n }\n};\nconst setExecutionProviders = (sessionOptionsHandle, executionProviders, allocs) => {\n for (const ep of executionProviders) {\n let epName = typeof ep === 'string' ? ep : ep.name;\n // check EP name\n switch (epName) {\n case 'xnnpack':\n epName = 'XNNPACK';\n break;\n case 'wasm':\n case 'cpu':\n continue;\n default:\n throw new Error(`not supported EP: ${epName}`);\n }\n const epNameDataOffset = (0, string_utils_1.allocWasmString)(epName, allocs);\n if ((0, wasm_factory_1.getInstance)()._OrtAppendExecutionProvider(sessionOptionsHandle, epNameDataOffset) !== 0) {\n throw new Error(`Can't append execution provider: ${epName}`);\n }\n }\n};\nconst setSessionOptions = (options) => {\n const wasm = (0, wasm_factory_1.getInstance)();\n let sessionOptionsHandle = 0;\n const allocs = [];\n const sessionOptions = options || {};\n appendDefaultOptions(sessionOptions);\n try {\n if ((options === null || options === void 0 ? void 0 : options.graphOptimizationLevel) === undefined) {\n sessionOptions.graphOptimizationLevel = 'all';\n }\n const graphOptimizationLevel = getGraphOptimzationLevel(sessionOptions.graphOptimizationLevel);\n if ((options === null || options === void 0 ? void 0 : options.enableCpuMemArena) === undefined) {\n sessionOptions.enableCpuMemArena = true;\n }\n if ((options === null || options === void 0 ? void 0 : options.enableMemPattern) === undefined) {\n sessionOptions.enableMemPattern = true;\n }\n if ((options === null || options === void 0 ? void 0 : options.executionMode) === undefined) {\n sessionOptions.executionMode = 'sequential';\n }\n const executionMode = getExecutionMode(sessionOptions.executionMode);\n let logIdDataOffset = 0;\n if ((options === null || options === void 0 ? void 0 : options.logId) !== undefined) {\n logIdDataOffset = (0, string_utils_1.allocWasmString)(options.logId, allocs);\n }\n if ((options === null || options === void 0 ? void 0 : options.logSeverityLevel) === undefined) {\n sessionOptions.logSeverityLevel = 2; // Default to warning\n }\n else if (typeof options.logSeverityLevel !== 'number' || !Number.isInteger(options.logSeverityLevel) ||\n options.logSeverityLevel < 0 || options.logSeverityLevel > 4) {\n throw new Error(`log serverity level is not valid: ${options.logSeverityLevel}`);\n }\n if ((options === null || options === void 0 ? void 0 : options.logVerbosityLevel) === undefined) {\n sessionOptions.logVerbosityLevel = 0; // Default to 0\n }\n else if (typeof options.logVerbosityLevel !== 'number' || !Number.isInteger(options.logVerbosityLevel)) {\n throw new Error(`log verbosity level is not valid: ${options.logVerbosityLevel}`);\n }\n if ((options === null || options === void 0 ? void 0 : options.enableProfiling) === undefined) {\n sessionOptions.enableProfiling = false;\n }\n sessionOptionsHandle = wasm._OrtCreateSessionOptions(graphOptimizationLevel, !!sessionOptions.enableCpuMemArena, !!sessionOptions.enableMemPattern, executionMode, !!sessionOptions.enableProfiling, 0, logIdDataOffset, sessionOptions.logSeverityLevel, sessionOptions.logVerbosityLevel);\n if (sessionOptionsHandle === 0) {\n throw new Error('Can\\'t create session options');\n }\n if (options === null || options === void 0 ? void 0 : options.executionProviders) {\n setExecutionProviders(sessionOptionsHandle, options.executionProviders, allocs);\n }\n if ((options === null || options === void 0 ? void 0 : options.extra) !== undefined) {\n (0, options_utils_1.iterateExtraOptions)(options.extra, '', new WeakSet(), (key, value) => {\n const keyDataOffset = (0, string_utils_1.allocWasmString)(key, allocs);\n const valueDataOffset = (0, string_utils_1.allocWasmString)(value, allocs);\n if (wasm._OrtAddSessionConfigEntry(sessionOptionsHandle, keyDataOffset, valueDataOffset) !== 0) {\n throw new Error(`Can't set a session config entry: ${key} - ${value}`);\n }\n });\n }\n return [sessionOptionsHandle, allocs];\n }\n catch (e) {\n if (sessionOptionsHandle !== 0) {\n wasm._OrtReleaseSessionOptions(sessionOptionsHandle);\n }\n allocs.forEach(wasm._free);\n throw e;\n }\n};\nexports.setSessionOptions = setSessionOptions;\n\n\n/***/ }),\n\n/***/ \"./lib/wasm/string-utils.ts\":\n/*!**********************************!*\\\n !*** ./lib/wasm/string-utils.ts ***!\n \\**********************************/\n/***/ ((__unused_webpack_module, exports, __webpack_require__) => {\n\n\"use strict\";\n\n// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT License.\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.allocWasmString = void 0;\nconst wasm_factory_1 = __webpack_require__(/*! ./wasm-factory */ \"./lib/wasm/wasm-factory.ts\");\nconst allocWasmString = (data, allocs) => {\n const wasm = (0, wasm_factory_1.getInstance)();\n const dataLength = wasm.lengthBytesUTF8(data) + 1;\n const dataOffset = wasm._malloc(dataLength);\n wasm.stringToUTF8(data, dataOffset, dataLength);\n allocs.push(dataOffset);\n return dataOffset;\n};\nexports.allocWasmString = allocWasmString;\n\n\n/***/ }),\n\n/***/ \"./lib/wasm/wasm-core-impl.ts\":\n/*!************************************!*\\\n !*** ./lib/wasm/wasm-core-impl.ts ***!\n \\************************************/\n/***/ ((__unused_webpack_module, exports, __webpack_require__) => {\n\n\"use strict\";\n\n// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT License.\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.extractTransferableBuffers = exports.endProfiling = exports.run = exports.releaseSession = exports.createSession = exports.createSessionFinalize = exports.createSessionAllocate = exports.initOrt = void 0;\nconst run_options_1 = __webpack_require__(/*! ./run-options */ \"./lib/wasm/run-options.ts\");\nconst session_options_1 = __webpack_require__(/*! ./session-options */ \"./lib/wasm/session-options.ts\");\nconst string_utils_1 = __webpack_require__(/*! ./string-utils */ \"./lib/wasm/string-utils.ts\");\nconst wasm_factory_1 = __webpack_require__(/*! ./wasm-factory */ \"./lib/wasm/wasm-factory.ts\");\n/**\n * initialize ORT environment.\n * @param numThreads SetGlobalIntraOpNumThreads(numThreads)\n * @param loggingLevel CreateEnv(static_cast<OrtLoggingLevel>(logging_level))\n */\nconst initOrt = (numThreads, loggingLevel) => {\n const errorCode = (0, wasm_factory_1.getInstance)()._OrtInit(numThreads, loggingLevel);\n if (errorCode !== 0) {\n throw new Error(`Can't initialize onnxruntime. error code = ${errorCode}`);\n }\n};\nexports.initOrt = initOrt;\nconst activeSessions = new Map();\n/**\n * create an instance of InferenceSession.\n * @returns the metadata of InferenceSession. 0-value handle for failure.\n */\nconst createSessionAllocate = (model) => {\n const wasm = (0, wasm_factory_1.getInstance)();\n const modelDataOffset = wasm._malloc(model.byteLength);\n wasm.HEAPU8.set(model, modelDataOffset);\n return [modelDataOffset, model.byteLength];\n};\nexports.createSessionAllocate = createSessionAllocate;\nconst createSessionFinalize = (modelData, options) => {\n const wasm = (0, wasm_factory_1.getInstance)();\n let sessionHandle = 0;\n let sessionOptionsHandle = 0;\n let allocs = [];\n try {\n [sessionOptionsHandle, allocs] = (0, session_options_1.setSessionOptions)(options);\n sessionHandle = wasm._OrtCreateSession(modelData[0], modelData[1], sessionOptionsHandle);\n if (sessionHandle === 0) {\n throw new Error('Can\\'t create a session');\n }\n }\n finally {\n wasm._free(modelData[0]);\n wasm._OrtReleaseSessionOptions(sessionOptionsHandle);\n allocs.forEach(wasm._free);\n }\n const inputCount = wasm._OrtGetInputCount(sessionHandle);\n const outputCount = wasm._OrtGetOutputCount(sessionHandle);\n const inputNames = [];\n const inputNamesUTF8Encoded = [];\n const outputNames = [];\n const outputNamesUTF8Encoded = [];\n for (let i = 0; i < inputCount; i++) {\n const name = wasm._OrtGetInputName(sessionHandle, i);\n if (name === 0) {\n throw new Error('Can\\'t get an input name');\n }\n inputNamesUTF8Encoded.push(name);\n inputNames.push(wasm.UTF8ToString(name));\n }\n for (let i = 0; i < outputCount; i++) {\n const name = wasm._OrtGetOutputName(sessionHandle, i);\n if (name === 0) {\n throw new Error('Can\\'t get an output name');\n }\n outputNamesUTF8Encoded.push(name);\n outputNames.push(wasm.UTF8ToString(name));\n }\n activeSessions.set(sessionHandle, [sessionHandle, inputNamesUTF8Encoded, outputNamesUTF8Encoded]);\n return [sessionHandle, inputNames, outputNames];\n};\nexports.createSessionFinalize = createSessionFinalize;\n/**\n * create an instance of InferenceSession.\n * @returns the metadata of InferenceSession. 0-value handle for failure.\n */\nconst createSession = (model, options) => {\n const modelData = (0, exports.createSessionAllocate)(model);\n return (0, exports.createSessionFinalize)(modelData, options);\n};\nexports.createSession = createSession;\nconst releaseSession = (sessionId) => {\n const wasm = (0, wasm_factory_1.getInstance)();\n const session = activeSessions.get(sessionId);\n if (!session) {\n throw new Error('invalid session id');\n }\n const sessionHandle = session[0];\n const inputNamesUTF8Encoded = session[1];\n const outputNamesUTF8Encoded = session[2];\n inputNamesUTF8Encoded.forEach(wasm._OrtFree);\n outputNamesUTF8Encoded.forEach(wasm._OrtFree);\n wasm._OrtReleaseSession(sessionHandle);\n activeSessions.delete(sessionId);\n};\nexports.releaseSession = releaseSession;\nconst tensorDataTypeStringToEnum = (type) => {\n switch (type) {\n case 'int8':\n return 3 /* DataType.int8 */;\n case 'uint8':\n return 2 /* DataType.uint8 */;\n case 'bool':\n return 9 /* DataType.bool */;\n case 'int16':\n return 5 /* DataType.int16 */;\n case 'uint16':\n return 4 /* DataType.uint16 */;\n case 'int32':\n return 6 /* DataType.int32 */;\n case 'uint32':\n return 12 /* DataType.uint32 */;\n case 'float32':\n return 1 /* DataType.float */;\n case 'float64':\n return 11 /* DataType.double */;\n case 'string':\n return 8 /* DataType.string */;\n case 'int64':\n return 7 /* DataType.int64 */;\n case 'uint64':\n return 13 /* DataType.uint64 */;\n default:\n throw new Error(`unsupported data type: ${type}`);\n }\n};\nconst tensorDataTypeEnumToString = (typeProto) => {\n switch (typeProto) {\n case 3 /* DataType.int8 */:\n return 'int8';\n case 2 /* DataType.uint8 */:\n return 'uint8';\n case 9 /* DataType.bool */:\n return 'bool';\n case 5 /* DataType.int16 */:\n return 'int16';\n case 4 /* DataType.uint16 */:\n return 'uint16';\n case 6 /* DataType.int32 */:\n return 'int32';\n case 12 /* DataType.uint32 */:\n return 'uint32';\n case 1 /* DataType.float */:\n return 'float32';\n case 11 /* DataType.double */:\n return 'float64';\n case 8 /* DataType.string */:\n return 'string';\n case 7 /* DataType.int64 */:\n return 'int64';\n case 13 /* DataType.uint64 */:\n return 'uint64';\n default:\n throw new Error(`unsupported data type: ${typeProto}`);\n }\n};\nconst numericTensorTypeToTypedArray = (type) => {\n switch (type) {\n case 'float32':\n return Float32Array;\n case 'uint8':\n return Uint8Array;\n case 'int8':\n return Int8Array;\n case 'uint16':\n return Uint16Array;\n case 'int16':\n return Int16Array;\n case 'int32':\n return Int32Array;\n case 'bool':\n return Uint8Array;\n case 'float64':\n return Float64Array;\n case 'uint32':\n return Uint32Array;\n case 'int64':\n return BigInt64Array;\n case 'uint64':\n return BigUint64Array;\n default:\n throw new Error(`unsupported type: ${type}`);\n }\n};\n/**\n * perform inference run\n */\nconst run = (sessionId, inputIndices, inputs, outputIndices, options) => {\n const wasm = (0, wasm_factory_1.getInstance)();\n const session = activeSessions.get(sessionId);\n if (!session) {\n throw new Error('invalid session id');\n }\n const sessionHandle = session[0];\n const inputNamesUTF8Encoded = session[1];\n const outputNamesUTF8Encoded = session[2];\n const inputCount = inputIndices.length;\n const outputCount = outputIndices.length;\n let runOptionsHandle = 0;\n let runOptionsAllocs = [];\n const inputValues = [];\n const inputAllocs = [];\n try {\n [runOptionsHandle, runOptionsAllocs] = (0, run_options_1.setRunOptions)(options);\n // create input tensors\n for (let i = 0; i < inputCount; i++) {\n const dataType = inputs[i][0];\n const dims = inputs[i][1];\n const data = inputs[i][2];\n let dataOffset;\n let dataByteLength;\n if (Array.isArray(data)) {\n // string tensor\n dataByteLength = 4 * data.length;\n dataOffset = wasm._malloc(dataByteLength);\n inputAllocs.push(dataOffset);\n let dataIndex = dataOffset / 4;\n for (let i = 0; i < data.length; i++) {\n if (typeof data[i] !== 'string') {\n throw new TypeError(`tensor data at index ${i} is not a string`);\n }\n wasm.HEAPU32[dataIndex++] = (0, string_utils_1.allocWasmString)(data[i], inputAllocs);\n }\n }\n else {\n dataByteLength = data.byteLength;\n dataOffset = wasm._malloc(dataByteLength);\n inputAllocs.push(dataOffset);\n wasm.HEAPU8.set(new Uint8Array(data.buffer, data.byteOffset, dataByteLength), dataOffset);\n }\n const stack = wasm.stackSave();\n const dimsOffset = wasm.stackAlloc(4 * dims.length);\n try {\n let dimIndex = dimsOffset / 4;\n dims.forEach(d => wasm.HEAP32[dimIndex++] = d);\n const tensor = wasm._OrtCreateTensor(tensorDataTypeStringToEnum(dataType), dataOffset, dataByteLength, dimsOffset, dims.length);\n if (tensor === 0) {\n throw new Error('Can\\'t create a tensor');\n }\n inputValues.push(tensor);\n }\n finally {\n wasm.stackRestore(stack);\n }\n }\n const beforeRunStack = wasm.stackSave();\n const inputValuesOffset = wasm.stackAlloc(inputCount * 4);\n const inputNamesOffset = wasm.stackAlloc(inputCount * 4);\n const outputValuesOffset = wasm.stackAlloc(outputCount * 4);\n const outputNamesOffset = wasm.stackAlloc(outputCount * 4);\n try {\n let inputValuesIndex = inputValuesOffset / 4;\n let inputNamesIndex = inputNamesOffset / 4;\n let outputValuesIndex = outputValuesOffset / 4;\n let outputNamesIndex = outputNamesOffset / 4;\n for (let i = 0; i < inputCount; i++) {\n wasm.HEAPU32[inputValuesIndex++] = inputValues[i];\n wasm.HEAPU32[inputNamesIndex++] = inputNamesUTF8Encoded[inputIndices[i]];\n }\n for (let i = 0; i < outputCount; i++) {\n wasm.HEAPU32[outputValuesIndex++] = 0;\n wasm.HEAPU32[outputNamesIndex++] = outputNamesUTF8Encoded[outputIndices[i]];\n }\n // support RunOptions\n let errorCode = wasm._OrtRun(sessionHandle, inputNamesOffset, inputValuesOffset, inputCount, outputNamesOffset, outputCount, outputValuesOffset, runOptionsHandle);\n const output = [];\n if (errorCode === 0) {\n for (let i = 0; i < outputCount; i++) {\n const tensor = wasm.HEAPU32[outputValuesOffset / 4 + i];\n const beforeGetTensorDataStack = wasm.stackSave();\n // stack allocate 4 pointer value\n const tensorDataOffset = wasm.stackAlloc(4 * 4);\n let type, dataOffset = 0;\n try {\n errorCode = wasm._OrtGetTensorData(tensor, tensorDataOffset, tensorDataOffset + 4, tensorDataOffset + 8, tensorDataOffset + 12);\n if (errorCode !== 0) {\n throw new Error(`Can't access output tensor data. error code = ${errorCode}`);\n }\n let tensorDataIndex = tensorDataOffset / 4;\n const dataType = wasm.HEAPU32[tensorDataIndex++];\n dataOffset = wasm.HEAPU32[tensorDataIndex++];\n const dimsOffset = wasm.HEAPU32[tensorDataIndex++];\n const dimsLength = wasm.HEAPU32[tensorDataIndex++];\n const dims = [];\n for (let i = 0; i < dimsLength; i++) {\n dims.push(wasm.HEAPU32[dimsOffset / 4 + i]);\n }\n wasm._OrtFree(dimsOffset);\n const size = dims.length === 0 ? 1 : dims.reduce((a, b) => a * b);\n type = tensorDataTypeEnumToString(dataType);\n if (type === 'string') {\n const stringData = [];\n let dataIndex = dataOffset / 4;\n for (let i = 0; i < size; i++) {\n const offset = wasm.HEAPU32[dataIndex++];\n const maxBytesToRead = i === size - 1 ? undefined : wasm.HEAPU32[dataIndex] - offset;\n stringData.push(wasm.UTF8ToString(offset, maxBytesToRead));\n }\n output.push([type, dims, stringData]);\n }\n else {\n const typedArrayConstructor = numericTensorTypeToTypedArray(type);\n const data = new typedArrayConstructor(size);\n new Uint8Array(data.buffer, data.byteOffset, data.byteLength)\n .set(wasm.HEAPU8.subarray(dataOffset, dataOffset + data.byteLength));\n output.push([type, dims, data]);\n }\n }\n finally {\n wasm.stackRestore(beforeGetTensorDataStack);\n if (type === 'string' && dataOffset) {\n wasm._free(dataOffset);\n }\n wasm._OrtReleaseTensor(tensor);\n }\n }\n }\n if (errorCode === 0) {\n return output;\n }\n else {\n throw new Error(`failed to call OrtRun(). error code = ${errorCode}.`);\n }\n }\n finally {\n wasm.stackRestore(beforeRunStack);\n }\n }\n finally {\n inputValues.forEach(wasm._OrtReleaseTensor);\n inputAllocs.forEach(wasm._free);\n wasm._OrtReleaseRunOptions(runOptionsHandle);\n runOptionsAllocs.forEach(wasm._free);\n }\n};\nexports.run = run;\n/**\n * end profiling\n */\nconst endProfiling = (sessionId) => {\n const wasm = (0, wasm_factory_1.getInstance)();\n const session = activeSessions.get(sessionId);\n if (!session) {\n throw new Error('invalid session id');\n }\n const sessionHandle = session[0];\n // profile file name is not used yet, but it must be freed.\n const profileFileName = wasm._OrtEndProfiling(sessionHandle);\n if (profileFileName === 0) {\n throw new Error('Can\\'t get an profile file name');\n }\n wasm._OrtFree(profileFileName);\n};\nexports.endProfiling = endProfiling;\nconst extractTransferableBuffers = (tensors) => {\n const buffers = [];\n for (const tensor of tensors) {\n const data = tensor[2];\n if (!Array.isArray(data) && data.buffer) {\n buffers.push(data.buffer);\n }\n }\n return buffers;\n};\nexports.extractTransferableBuffers = extractTransferableBuffers;\n\n\n/***/ }),\n\n/***/ \"./lib/wasm/wasm-factory.ts\":\n/*!**********************************!*\\\n !*** ./lib/wasm/wasm-factory.ts ***!\n \\**********************************/\n/***/ (function(__unused_webpack_module, exports, __webpack_require__) {\n\n\"use strict\";\nvar __dirname = \"/\";\n\n// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT License.\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.dispose = exports.getInstance = exports.initializeWebAssembly = void 0;\nconst path = __importStar(__webpack_require__(/*! path */ \"?7aa5\"));\nconst ort_wasm_js_1 = __importDefault(__webpack_require__(/*! ./binding/ort-wasm.js */ \"./lib/wasm/binding/ort-wasm.js\"));\nconst ortWasmFactoryThreaded = \n// eslint-disable-next-line @typescript-eslint/no-require-imports\n true ? __webpack_require__(/*! ./binding/ort-wasm-threaded.js */ \"./lib/wasm/binding/ort-wasm-threaded.js\") : 0;\nlet wasm;\nlet initialized = false;\nlet initializing = false;\nlet aborted = false;\nconst isMultiThreadSupported = () => {\n try {\n // If 'SharedArrayBuffer' is not available, WebAssembly threads will not work.\n if (typeof SharedArrayBuffer === 'undefined') {\n return false;\n }\n // Test for transferability of SABs (for browsers. needed for Firefox)\n // https://groups.google.com/forum/#!msg/mozilla.dev.platform/IHkBZlHETpA/dwsMNchWEQAJ\n if (typeof MessageChannel !== 'undefined') {\n new MessageChannel().port1.postMessage(new SharedArrayBuffer(1));\n }\n // Test for WebAssembly threads capability (for both browsers and Node.js)\n // This typed array is a WebAssembly program containing threaded instructions.\n return WebAssembly.validate(new Uint8Array([\n 0, 97, 115, 109, 1, 0, 0, 0, 1, 4, 1, 96, 0, 0, 3, 2, 1, 0, 5,\n 4, 1, 3, 1, 1, 10, 11, 1, 9, 0, 65, 0, 254, 16, 2, 0, 26, 11\n ]));\n }\n catch (e) {\n return false;\n }\n};\nconst isSimdSupported = () => {\n try {\n // Test for WebAssembly SIMD capability (for both browsers and Node.js)\n // This typed array is a WebAssembly program containing SIMD instructions.\n // The binary data is generated from the following code by wat2wasm:\n //\n // (module\n // (type $t0 (func))\n // (func $f0 (type $t0)\n // (drop\n // (i32x4.dot_i16x8_s\n // (i8x16.splat\n // (i32.const 0))\n // (v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)))))\n return WebAssembly.validate(new Uint8Array([\n 0, 97, 115, 109, 1, 0, 0, 0, 1, 4, 1, 96, 0, 0, 3, 2, 1, 0, 10, 30, 1, 28, 0, 65, 0,\n 253, 15, 253, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 253, 186, 1, 26, 11\n ]));\n }\n catch (e) {\n return false;\n }\n};\nconst getWasmFileName = (useSimd, useThreads) => {\n if (useThreads) {\n return useSimd ? 'ort-wasm-simd-threaded.wasm' : 'ort-wasm-threaded.wasm';\n }\n else {\n return useSimd ? 'ort-wasm-simd.wasm' : 'ort-wasm.wasm';\n }\n};\nconst initializeWebAssembly = async (flags) => {\n if (initialized) {\n return Promise.resolve();\n }\n if (initializing) {\n throw new Error('multiple calls to \\'initializeWebAssembly()\\' detected.');\n }\n if (aborted) {\n throw new Error('previous call to \\'initializeWebAssembly()\\' failed.');\n }\n initializing = true;\n // wasm flags are already initialized\n const timeout = flags.initTimeout;\n const numThreads = flags.numThreads;\n const simd = flags.simd;\n const useThreads = numThreads > 1 && isMultiThreadSupported();\n const useSimd = simd && isSimdSupported();\n const wasmPrefixOverride = typeof flags.wasmPaths === 'string' ? flags.wasmPaths : undefined;\n const wasmFileName = getWasmFileName(false, useThreads);\n const wasmOverrideFileName = getWasmFileName(useSimd, useThreads);\n const wasmPathOverride = typeof flags.wasmPaths === 'object' ? flags.wasmPaths[wasmOverrideFileName] : undefined;\n let isTimeout = false;\n const tasks = [];\n // promise for timeout\n if (timeout > 0) {\n tasks.push(new Promise((resolve) => {\n setTimeout(() => {\n isTimeout = true;\n resolve();\n }, timeout);\n }));\n }\n // promise for module initialization\n tasks.push(new Promise((resolve, reject) => {\n const factory = useThreads ? ortWasmFactoryThreaded : ort_wasm_js_1.default;\n const config = {\n locateFile: (fileName, scriptDirectory) => {\n if ( true && useThreads && fileName.endsWith('.worker.js') &&\n typeof Blob !== 'undefined') {\n return URL.createObjectURL(new Blob([\n // This require() function is handled by webpack to load file content of the corresponding .worker.js\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n __webpack_require__(/*! ./binding/ort-wasm-threaded.worker.js */ \"./lib/wasm/binding/ort-wasm-threaded.worker.js\")\n ], { type: 'text/javascript' }));\n }\n if (fileName === wasmFileName) {\n const prefix = wasmPrefixOverride !== null && wasmPrefixOverride !== void 0 ? wasmPrefixOverride : scriptDirectory;\n return wasmPathOverride !== null && wasmPathOverride !== void 0 ? wasmPathOverride : prefix + wasmOverrideFileName;\n }\n return scriptDirectory + fileName;\n }\n };\n if ( true && useThreads) {\n if (typeof Blob === 'undefined') {\n config.mainScriptUrlOrBlob = path.join(__dirname, 'ort-wasm-threaded.js');\n }\n else {\n const scriptSourceCode = `var ortWasmThreaded=(function(){var _scriptDir;return ${factory.toString()}})();`;\n config.mainScriptUrlOrBlob = new Blob([scriptSourceCode], { type: 'text/javascript' });\n }\n }\n factory(config).then(\n // wasm module initialized successfully\n module => {\n initializing = false;\n initialized = true;\n wasm = module;\n resolve();\n }, \n // wasm module failed to initialize\n (what) => {\n initializing = false;\n aborted = true;\n reject(what);\n });\n }));\n await Promise.race(tasks);\n if (isTimeout) {\n throw new Error(`WebAssembly backend initializing failed due to timeout: ${timeout}ms`);\n }\n};\nexports.initializeWebAssembly = initializeWebAssembly;\nconst getInstance = () => {\n if (initialized && wasm) {\n return wasm;\n }\n throw new Error('WebAssembly is not initialized yet.');\n};\nexports.getInstance = getInstance;\nconst dispose = () => {\n var _a;\n if (initialized && !initializing && !aborted) {\n initializing = true;\n (_a = wasm.PThread) === null || _a === void 0 ? void 0 : _a.terminateAllThreads();\n wasm = undefined;\n initializing = false;\n initialized = false;\n aborted = true;\n }\n};\nexports.dispose = dispose;\n\n\n/***/ }),\n\n/***/ \"./lib/wasm/binding/ort-wasm-threaded.worker.js\":\n/*!******************************************************!*\\\n !*** ./lib/wasm/binding/ort-wasm-threaded.worker.js ***!\n \\******************************************************/\n/***/ ((module) => {\n\n\"use strict\";\nmodule.exports = \"\\\"use strict\\\";var Module={};var ENVIRONMENT_IS_NODE=typeof process==\\\"object\\\"&&typeof process.versions==\\\"object\\\"&&typeof process.versions.node==\\\"string\\\";if(ENVIRONMENT_IS_NODE){var nodeWorkerThreads=require(\\\"worker_threads\\\");var parentPort=nodeWorkerThreads.parentPort;parentPort.on(\\\"message\\\",data=>onmessage({data:data}));var fs=require(\\\"fs\\\");Object.assign(global,{self:global,require:require,Module:Module,location:{href:__filename},Worker:nodeWorkerThreads.Worker,importScripts:function(f){(0,eval)(fs.readFileSync(f,\\\"utf8\\\"))},postMessage:function(msg){parentPort.postMessage(msg)},performance:global.performance||{now:function(){return Date.now()}}})}var initializedJS=false;var pendingNotifiedProxyingQueues=[];function threadPrintErr(){var text=Array.prototype.slice.call(arguments).join(\\\" \\\");if(ENVIRONMENT_IS_NODE){fs.writeSync(2,text+\\\"\\\\n\\\");return}console.error(text)}function threadAlert(){var text=Array.prototype.slice.call(arguments).join(\\\" \\\");postMessage({cmd:\\\"alert\\\",text:text,threadId:Module[\\\"_pthread_self\\\"]()})}var err=threadPrintErr;self.alert=threadAlert;Module[\\\"instantiateWasm\\\"]=(info,receiveInstance)=>{var instance=new WebAssembly.Instance(Module[\\\"wasmModule\\\"],info);receiveInstance(instance);Module[\\\"wasmModule\\\"]=null;return instance.exports};self.onunhandledrejection=e=>{throw e.reason??e};self.onmessage=e=>{try{if(e.data.cmd===\\\"load\\\"){Module[\\\"wasmModule\\\"]=e.data.wasmModule;Module[\\\"wasmMemory\\\"]=e.data.wasmMemory;Module[\\\"buffer\\\"]=Module[\\\"wasmMemory\\\"].buffer;Module[\\\"ENVIRONMENT_IS_PTHREAD\\\"]=true;if(typeof e.data.urlOrBlob==\\\"string\\\"){importScripts(e.data.urlOrBlob)}else{var objectUrl=URL.createObjectURL(e.data.urlOrBlob);importScripts(objectUrl);URL.revokeObjectURL(objectUrl)}ortWasmThreaded(Module).then(function(instance){Module=instance})}else if(e.data.cmd===\\\"run\\\"){Module[\\\"__performance_now_clock_drift\\\"]=performance.now()-e.data.time;Module[\\\"__emscripten_thread_init\\\"](e.data.pthread_ptr,/*isMainBrowserThread=*/0,/*isMainRuntimeThread=*/0,/*canBlock=*/1);Module[\\\"establishStackSpace\\\"]();Module[\\\"PThread\\\"].receiveObjectTransfer(e.data);Module[\\\"PThread\\\"].threadInitTLS();if(!initializedJS){pendingNotifiedProxyingQueues.forEach(queue=>{Module[\\\"executeNotifiedProxyingQueue\\\"](queue)});pendingNotifiedProxyingQueues=[];initializedJS=true}try{Module[\\\"invokeEntryPoint\\\"](e.data.start_routine,e.data.arg)}catch(ex){if(ex!=\\\"unwind\\\"){if(ex instanceof Module[\\\"ExitStatus\\\"]){if(Module[\\\"keepRuntimeAlive\\\"]()){}else{Module[\\\"__emscripten_thread_exit\\\"](ex.status)}}else{throw ex}}}}else if(e.data.cmd===\\\"cancel\\\"){if(Module[\\\"_pthread_self\\\"]()){Module[\\\"__emscripten_thread_exit\\\"](-1)}}else if(e.data.target===\\\"setimmediate\\\"){}else if(e.data.cmd===\\\"processProxyingQueue\\\"){if(initializedJS){Module[\\\"executeNotifiedProxyingQueue\\\"](e.data.queue)}else{pendingNotifiedProxyingQueues.push(e.data.queue)}}else{err(\\\"worker.js received unknown command \\\"+e.data.cmd);err(e.data)}}catch(ex){err(\\\"worker.js onmessage() captured an uncaught exception: \\\"+ex);if(ex&&ex.stack)err(ex.stack);if(Module[\\\"__emscripten_thread_crashed\\\"]){Module[\\\"__emscripten_thread_crashed\\\"]()}throw ex}};\\r\\n\";\n\n/***/ }),\n\n/***/ \"?63c8\":\n/*!********************!*\\\n !*** fs (ignored) ***!\n \\********************/\n/***/ (() => {\n\n/* (ignored) */\n\n/***/ }),\n\n/***/ \"?aedb\":\n/*!********************!*\\\n !*** os (ignored) ***!\n \\********************/\n/***/ (() => {\n\n/* (ignored) */\n\n/***/ }),\n\n/***/ \"?75c6\":\n/*!**********************!*\\\n !*** path (ignored) ***!\n \\**********************/\n/***/ (() => {\n\n/* (ignored) */\n\n/***/ }),\n\n/***/ \"?674f\":\n/*!****************************!*\\\n !*** perf_hooks (ignored) ***!\n \\****************************/\n/***/ (() => {\n\n/* (ignored) */\n\n/***/ }),\n\n/***/ \"?c6f7\":\n/*!********************************!*\\\n !*** worker_threads (ignored) ***!\n \\********************************/\n/***/ (() => {\n\n/* (ignored) */\n\n/***/ }),\n\n/***/ \"?7aa5\":\n/*!**********************!*\\\n !*** path (ignored) ***!\n \\**********************/\n/***/ (() => {\n\n/* (ignored) */\n\n/***/ })\n\n/******/ \t});\n/************************************************************************/\n/******/ \t// The module cache\n/******/ \tvar __webpack_module_cache__ = {};\n/******/ \t\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/ \t\t// Check if module is in cache\n/******/ \t\tvar cachedModule = __webpack_module_cache__[moduleId];\n/******/ \t\tif (cachedModule !== undefined) {\n/******/ \t\t\treturn cachedModule.exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = __webpack_module_cache__[moduleId] = {\n/******/ \t\t\t// no module.id needed\n/******/ \t\t\t// no module.loaded needed\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/ \t\n/******/ \t\t// Execute the module function\n/******/ \t\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/ \t\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/ \t\n/************************************************************************/\n/******/ \t/* webpack/runtime/global */\n/******/ \t(() => {\n/******/ \t\t__webpack_require__.g = (function() {\n/******/ \t\t\tif (typeof globalThis === 'object') return globalThis;\n/******/ \t\t\ttry {\n/******/ \t\t\t\treturn this || new Function('return this')();\n/******/ \t\t\t} catch (e) {\n/******/ \t\t\t\tif (typeof window === 'object') return window;\n/******/ \t\t\t}\n/******/ \t\t})();\n/******/ \t})();\n/******/ \t\n/************************************************************************/\nvar __webpack_exports__ = {};\n// This entry need to be wrapped in an IIFE because it need to be in strict mode.\n(() => {\n\"use strict\";\nvar exports = __webpack_exports__;\n/*!*****************************************************************************************************!*\\\n !*** ./node_modules/ts-loader/index.js??ruleSet[1].rules[0].use[0]!./lib/wasm/proxy-worker/main.ts ***!\n \\*****************************************************************************************************/\n\n// Copyright (c) Microsoft Corporation. All rights reserved.\n// Licensed under the MIT License.\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst wasm_core_impl_1 = __webpack_require__(/*! ../wasm-core-impl */ \"./lib/wasm/wasm-core-impl.ts\");\nconst wasm_factory_1 = __webpack_require__(/*! ../wasm-factory */ \"./lib/wasm/wasm-factory.ts\");\nself.onmessage = (ev) => {\n switch (ev.data.type) {\n case 'init-wasm':\n (0, wasm_factory_1.initializeWebAssembly)(ev.data.in)\n .then(() => postMessage({ type: 'init-wasm' }), err => postMessage({ type: 'init-wasm', err }));\n break;\n case 'init-ort':\n try {\n const { numThreads, loggingLevel } = ev.data.in;\n (0, wasm_core_impl_1.initOrt)(numThreads, loggingLevel);\n postMessage({ type: 'init-ort' });\n }\n catch (err) {\n postMessage({ type: 'init-ort', err });\n }\n break;\n case 'create_allocate':\n try {\n const { model } = ev.data.in;\n const modeldata = (0, wasm_core_impl_1.createSessionAllocate)(model);\n postMessage({ type: 'create_allocate', out: modeldata });\n }\n catch (err) {\n postMessage({ type: 'create_allocate', err });\n }\n break;\n case 'create_finalize':\n try {\n const { modeldata, options } = ev.data.in;\n const sessionMetadata = (0, wasm_core_impl_1.createSessionFinalize)(modeldata, options);\n postMessage({ type: 'create_finalize', out: sessionMetadata });\n }\n catch (err) {\n postMessage({ type: 'create_finalize', err });\n }\n break;\n case 'create':\n try {\n const { model, options } = ev.data.in;\n const sessionMetadata = (0, wasm_core_impl_1.createSession)(model, options);\n postMessage({ type: 'create', out: sessionMetadata });\n }\n catch (err) {\n postMessage({ type: 'create', err });\n }\n break;\n case 'release':\n try {\n const handler = ev.data.in;\n (0, wasm_core_impl_1.releaseSession)(handler);\n postMessage({ type: 'release' });\n }\n catch (err) {\n postMessage({ type: 'release', err });\n }\n break;\n case 'run':\n try {\n const { sessionId, inputIndices, inputs, outputIndices, options } = ev.data.in;\n const outputs = (0, wasm_core_impl_1.run)(sessionId, inputIndices, inputs, outputIndices, options);\n postMessage({ type: 'run', out: outputs }, (0, wasm_core_impl_1.extractTransferableBuffers)(outputs));\n }\n catch (err) {\n postMessage({ type: 'run', err });\n }\n break;\n case 'end-profiling':\n try {\n const handler = ev.data.in;\n (0, wasm_core_impl_1.endProfiling)(handler);\n postMessage({ type: 'end-profiling' });\n }\n catch (err) {\n postMessage({ type: 'end-profiling', err });\n }\n break;\n default:\n }\n};\n\n})();\n\n/******/ })()\n;\n", "Worker", undefined, undefined);
}
/***/ }),
/***/ "./node_modules/worker-loader/dist/runtime/inline.js":
/*!***********************************************************!*\
!*** ./node_modules/worker-loader/dist/runtime/inline.js ***!
\***********************************************************/
/***/ ((module) => {
"use strict";
/* eslint-env browser */
/* eslint-disable no-undef, no-use-before-define, new-cap */
module.exports = function (content, workerConstructor, workerOptions, url) {
var globalScope = self || window;
try {
try {
var blob;
try {
// New API
blob = new globalScope.Blob([content]);
} catch (e) {
// BlobBuilder = Deprecated, but widely implemented
var BlobBuilder = globalScope.BlobBuilder || globalScope.WebKitBlobBuilder || globalScope.MozBlobBuilder || globalScope.MSBlobBuilder;
blob = new BlobBuilder();
blob.append(content);
blob = blob.getBlob();
}
var URL = globalScope.URL || globalScope.webkitURL;
var objectURL = URL.createObjectURL(blob);
var worker = new globalScope[workerConstructor](objectURL, workerOptions);
URL.revokeObjectURL(objectURL);
return worker;
} catch (e) {
return new globalScope[workerConstructor]("data:application/javascript,".concat(encodeURIComponent(content)), workerOptions);
}
} catch (e) {
if (!url) {
throw Error("Inline worker is not supported");
}
return new globalScope[workerConstructor](url, workerOptions);
}
};
/***/ }),
/***/ "./lib/wasm/binding/ort-wasm-threaded.worker.js":
/*!******************************************************!*\
!*** ./lib/wasm/binding/ort-wasm-threaded.worker.js ***!
\******************************************************/
/***/ ((module) => {
"use strict";
module.exports = "\"use strict\";var Module={};var ENVIRONMENT_IS_NODE=typeof process==\"object\"&&typeof process.versions==\"object\"&&typeof process.versions.node==\"string\";if(ENVIRONMENT_IS_NODE){var nodeWorkerThreads=require(\"worker_threads\");var parentPort=nodeWorkerThreads.parentPort;parentPort.on(\"message\",data=>onmessage({data:data}));var fs=require(\"fs\");Object.assign(global,{self:global,require:require,Module:Module,location:{href:__filename},Worker:nodeWorkerThreads.Worker,importScripts:function(f){(0,eval)(fs.readFileSync(f,\"utf8\"))},postMessage:function(msg){parentPort.postMessage(msg)},performance:global.performance||{now:function(){return Date.now()}}})}var initializedJS=false;var pendingNotifiedProxyingQueues=[];function threadPrintErr(){var text=Array.prototype.slice.call(arguments).join(\" \");if(ENVIRONMENT_IS_NODE){fs.writeSync(2,text+\"\\n\");return}console.error(text)}function threadAlert(){var text=Array.prototype.slice.call(arguments).join(\" \");postMessage({cmd:\"alert\",text:text,threadId:Module[\"_pthread_self\"]()})}var err=threadPrintErr;self.alert=threadAlert;Module[\"instantiateWasm\"]=(info,receiveInstance)=>{var instance=new WebAssembly.Instance(Module[\"wasmModule\"],info);receiveInstance(instance);Module[\"wasmModule\"]=null;return instance.exports};self.onunhandledrejection=e=>{throw e.reason??e};self.onmessage=e=>{try{if(e.data.cmd===\"load\"){Module[\"wasmModule\"]=e.data.wasmModule;Module[\"wasmMemory\"]=e.data.wasmMemory;Module[\"buffer\"]=Module[\"wasmMemory\"].buffer;Module[\"ENVIRONMENT_IS_PTHREAD\"]=true;if(typeof e.data.urlOrBlob==\"string\"){importScripts(e.data.urlOrBlob)}else{var objectUrl=URL.createObjectURL(e.data.urlOrBlob);importScripts(objectUrl);URL.revokeObjectURL(objectUrl)}ortWasmThreaded(Module).then(function(instance){Module=instance})}else if(e.data.cmd===\"run\"){Module[\"__performance_now_clock_drift\"]=performance.now()-e.data.time;Module[\"__emscripten_thread_init\"](e.data.pthread_ptr,/*isMainBrowserThread=*/0,/*isMainRuntimeThread=*/0,/*canBlock=*/1);Module[\"establishStackSpace\"]();Module[\"PThread\"].receiveObjectTransfer(e.data);Module[\"PThread\"].threadInitTLS();if(!initializedJS){pendingNotifiedProxyingQueues.forEach(queue=>{Module[\"executeNotifiedProxyingQueue\"](queue)});pendingNotifiedProxyingQueues=[];initializedJS=true}try{Module[\"invokeEntryPoint\"](e.data.start_routine,e.data.arg)}catch(ex){if(ex!=\"unwind\"){if(ex instanceof Module[\"ExitStatus\"]){if(Module[\"keepRuntimeAlive\"]()){}else{Module[\"__emscripten_thread_exit\"](ex.status)}}else{throw ex}}}}else if(e.data.cmd===\"cancel\"){if(Module[\"_pthread_self\"]()){Module[\"__emscripten_thread_exit\"](-1)}}else if(e.data.target===\"setimmediate\"){}else if(e.data.cmd===\"processProxyingQueue\"){if(initializedJS){Module[\"executeNotifiedProxyingQueue\"](e.data.queue)}else{pendingNotifiedProxyingQueues.push(e.data.queue)}}else{err(\"worker.js received unknown command \"+e.data.cmd);err(e.data)}}catch(ex){err(\"worker.js onmessage() captured an uncaught exception: \"+ex);if(ex&&ex.stack)err(ex.stack);if(Module[\"__emscripten_thread_crashed\"]){Module[\"__emscripten_thread_crashed\"]()}throw ex}};\r\n";
/***/ }),
/***/ "onnxruntime-common":
/*!************************************************************************************************!*\
!*** external {"commonjs":"onnxruntime-common","commonjs2":"onnxruntime-common","root":"ort"} ***!
\************************************************************************************************/
/***/ ((module) => {
"use strict";
module.exports = __WEBPACK_EXTERNAL_MODULE_onnxruntime_common__;
/***/ }),
/***/ "?6c45":
/*!********************!*\
!*** fs (ignored) ***!
\********************/
/***/ (() => {
/* (ignored) */
/***/ }),
/***/ "?b3a2":
/*!**********************!*\
!*** util (ignored) ***!
\**********************/
/***/ (() => {
/* (ignored) */
/***/ }),
/***/ "?63c8":
/*!********************!*\
!*** fs (ignored) ***!
\********************/
/***/ (() => {
/* (ignored) */
/***/ }),
/***/ "?aedb":
/*!********************!*\
!*** os (ignored) ***!
\********************/
/***/ (() => {
/* (ignored) */
/***/ }),
/***/ "?75c6":
/*!**********************!*\
!*** path (ignored) ***!
\**********************/
/***/ (() => {
/* (ignored) */
/***/ }),
/***/ "?674f":
/*!****************************!*\
!*** perf_hooks (ignored) ***!
\****************************/
/***/ (() => {
/* (ignored) */
/***/ }),
/***/ "?c6f7":
/*!********************************!*\
!*** worker_threads (ignored) ***!
\********************************/
/***/ (() => {
/* (ignored) */
/***/ }),
/***/ "?295d":
/*!********************!*\
!*** fs (ignored) ***!
\********************/
/***/ (() => {
/* (ignored) */
/***/ }),
/***/ "?7aa5":
/*!**********************!*\
!*** path (ignored) ***!
\**********************/
/***/ (() => {
/* (ignored) */
/***/ }),
/***/ "?cf98":
/*!**********************!*\
!*** util (ignored) ***!
\**********************/
/***/ (() => {
/* (ignored) */
/***/ }),
/***/ "?0757":
/*!********************!*\
!*** os (ignored) ***!
\********************/
/***/ (() => {
/* (ignored) */
/***/ }),
/***/ "./node_modules/flatbuffers/js/flatbuffers.mjs":
/*!*****************************************************!*\
!*** ./node_modules/flatbuffers/js/flatbuffers.mjs ***!
\*****************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "flatbuffers": () => (/* binding */ flatbuffers)
/* harmony export */ });
/// @file
/// @addtogroup flatbuffers_javascript_api
/// @{
/// @cond FLATBUFFERS_INTERNAL
/**
* @fileoverview
*
* Need to suppress 'global this' error so the Node.js export line doesn't cause
* closure compile to error out.
* @suppress {globalThis}
*/
/**
* @const
* @namespace
*/
var flatbuffers = {};
/**
* @typedef {number}
*/
flatbuffers.Offset;
/**
* @typedef {{
* bb: flatbuffers.ByteBuffer,
* bb_pos: number
* }}
*/
flatbuffers.Table;
/**
* @type {number}
* @const
*/
flatbuffers.SIZEOF_SHORT = 2;
/**
* @type {number}
* @const
*/
flatbuffers.SIZEOF_INT = 4;
/**
* @type {number}
* @const
*/
flatbuffers.FILE_IDENTIFIER_LENGTH = 4;
/**
* @type {number}
* @const
*/
flatbuffers.SIZE_PREFIX_LENGTH = 4;
/**
* @enum {number}
*/
flatbuffers.Encoding = {
UTF8_BYTES: 1,
UTF16_STRING: 2
};
/**
* @type {Int32Array}
* @const
*/
flatbuffers.int32 = new Int32Array(2);
/**
* @type {Float32Array}
* @const
*/
flatbuffers.float32 = new Float32Array(flatbuffers.int32.buffer);
/**
* @type {Float64Array}
* @const
*/
flatbuffers.float64 = new Float64Array(flatbuffers.int32.buffer);
/**
* @type {boolean}
* @const
*/
flatbuffers.isLittleEndian = new Uint16Array(new Uint8Array([1, 0]).buffer)[0] === 1;
////////////////////////////////////////////////////////////////////////////////
/**
* @constructor
* @param {number} low
* @param {number} high
*/
flatbuffers.Long = function(low, high) {
/**
* @type {number}
* @const
*/
this.low = low | 0;
/**
* @type {number}
* @const
*/
this.high = high | 0;
};
/**
* @param {number} low
* @param {number} high
* @returns {!flatbuffers.Long}
*/
flatbuffers.Long.create = function(low, high) {
// Special-case zero to avoid GC overhead for default values
return low == 0 && high == 0 ? flatbuffers.Long.ZERO : new flatbuffers.Long(low, high);
};
/**
* @returns {number}
*/
flatbuffers.Long.prototype.toFloat64 = function() {
return (this.low >>> 0) + this.high * 0x100000000;
};
/**
* @param {flatbuffers.Long} other
* @returns {boolean}
*/
flatbuffers.Long.prototype.equals = function(other) {
return this.low == other.low && this.high == other.high;
};
/**
* @type {!flatbuffers.Long}
* @const
*/
flatbuffers.Long.ZERO = new flatbuffers.Long(0, 0);
/// @endcond
////////////////////////////////////////////////////////////////////////////////
/**
* Create a FlatBufferBuilder.
*
* @constructor
* @param {number=} opt_initial_size
*/
flatbuffers.Builder = function(opt_initial_size) {
if (!opt_initial_size) {
var initial_size = 1024;
} else {
var initial_size = opt_initial_size;
}
/**
* @type {flatbuffers.ByteBuffer}
* @private
*/
this.bb = flatbuffers.ByteBuffer.allocate(initial_size);
/**
* Remaining space in the ByteBuffer.
*
* @type {number}
* @private
*/
this.space = initial_size;
/**
* Minimum alignment encountered so far.
*
* @type {number}
* @private
*/
this.minalign = 1;
/**
* The vtable for the current table.
*
* @type {Array.<number>}
* @private
*/
this.vtable = null;
/**
* The amount of fields we're actually using.
*
* @type {number}
* @private
*/
this.vtable_in_use = 0;
/**
* Whether we are currently serializing a table.
*
* @type {boolean}
* @private
*/
this.isNested = false;
/**
* Starting offset of the current struct/table.
*
* @type {number}
* @private
*/
this.object_start = 0;
/**
* List of offsets of all vtables.
*
* @type {Array.<number>}
* @private
*/
this.vtables = [];
/**
* For the current vector being built.
*
* @type {number}
* @private
*/
this.vector_num_elems = 0;
/**
* False omits default values from the serialized data
*
* @type {boolean}
* @private
*/
this.force_defaults = false;
};
flatbuffers.Builder.prototype.clear = function() {
this.bb.clear();
this.space = this.bb.capacity();
this.minalign = 1;
this.vtable = null;
this.vtable_in_use = 0;
this.isNested = false;
this.object_start = 0;
this.vtables = [];
this.vector_num_elems = 0;
this.force_defaults = false;
};
/**
* In order to save space, fields that are set to their default value
* don't get serialized into the buffer. Forcing defaults provides a
* way to manually disable this optimization.
*
* @param {boolean} forceDefaults true always serializes default values
*/
flatbuffers.Builder.prototype.forceDefaults = function(forceDefaults) {
this.force_defaults = forceDefaults;
};
/**
* Get the ByteBuffer representing the FlatBuffer. Only call this after you've
* called finish(). The actual data starts at the ByteBuffer's current position,
* not necessarily at 0.
*
* @returns {flatbuffers.ByteBuffer}
*/
flatbuffers.Builder.prototype.dataBuffer = function() {
return this.bb;
};
/**
* Get the bytes representing the FlatBuffer. Only call this after you've
* called finish().
*
* @returns {!Uint8Array}
*/
flatbuffers.Builder.prototype.asUint8Array = function() {
return this.bb.bytes().subarray(this.bb.position(), this.bb.position() + this.offset());
};
/// @cond FLATBUFFERS_INTERNAL
/**
* Prepare to write an element of `size` after `additional_bytes` have been
* written, e.g. if you write a string, you need to align such the int length
* field is aligned to 4 bytes, and the string data follows it directly. If all
* you need to do is alignment, `additional_bytes` will be 0.
*
* @param {number} size This is the of the new element to write
* @param {number} additional_bytes The padding size
*/
flatbuffers.Builder.prototype.prep = function(size, additional_bytes) {
// Track the biggest thing we've ever aligned to.
if (size > this.minalign) {
this.minalign = size;
}
// Find the amount of alignment needed such that `size` is properly
// aligned after `additional_bytes`
var align_size = ((~(this.bb.capacity() - this.space + additional_bytes)) + 1) & (size - 1);
// Reallocate the buffer if needed.
while (this.space < align_size + size + additional_bytes) {
var old_buf_size = this.bb.capacity();
this.bb = flatbuffers.Builder.growByteBuffer(this.bb);
this.space += this.bb.capacity() - old_buf_size;
}
this.pad(align_size);
};
/**
* @param {number} byte_size
*/
flatbuffers.Builder.prototype.pad = function(byte_size) {
for (var i = 0; i < byte_size; i++) {
this.bb.writeInt8(--this.space, 0);
}
};
/**
* @param {number} value
*/
flatbuffers.Builder.prototype.writeInt8 = function(value) {
this.bb.writeInt8(this.space -= 1, value);
};
/**
* @param {number} value
*/
flatbuffers.Builder.prototype.writeInt16 = function(value) {
this.bb.writeInt16(this.space -= 2, value);
};
/**
* @param {number} value
*/
flatbuffers.Builder.prototype.writeInt32 = function(value) {
this.bb.writeInt32(this.space -= 4, value);
};
/**
* @param {flatbuffers.Long} value
*/
flatbuffers.Builder.prototype.writeInt64 = function(value) {
this.bb.writeInt64(this.space -= 8, value);
};
/**
* @param {number} value
*/
flatbuffers.Builder.prototype.writeFloat32 = function(value) {
this.bb.writeFloat32(this.space -= 4, value);
};
/**
* @param {number} value
*/
flatbuffers.Builder.prototype.writeFloat64 = function(value) {
this.bb.writeFloat64(this.space -= 8, value);
};
/// @endcond
/**
* Add an `int8` to the buffer, properly aligned, and grows the buffer (if necessary).
* @param {number} value The `int8` to add the the buffer.
*/
flatbuffers.Builder.prototype.addInt8 = function(value) {
this.prep(1, 0);
this.writeInt8(value);
};
/**
* Add an `int16` to the buffer, properly aligned, and grows the buffer (if necessary).
* @param {number} value The `int16` to add the the buffer.
*/
flatbuffers.Builder.prototype.addInt16 = function(value) {
this.prep(2, 0);
this.writeInt16(value);
};
/**
* Add an `int32` to the buffer, properly aligned, and grows the buffer (if necessary).
* @param {number} value The `int32` to add the the buffer.
*/
flatbuffers.Builder.prototype.addInt32 = function(value) {
this.prep(4, 0);
this.writeInt32(value);
};
/**
* Add an `int64` to the buffer, properly aligned, and grows the buffer (if necessary).
* @param {flatbuffers.Long} value The `int64` to add the the buffer.
*/
flatbuffers.Builder.prototype.addInt64 = function(value) {
this.prep(8, 0);
this.writeInt64(value);
};
/**
* Add a `float32` to the buffer, properly aligned, and grows the buffer (if necessary).
* @param {number} value The `float32` to add the the buffer.
*/
flatbuffers.Builder.prototype.addFloat32 = function(value) {
this.prep(4, 0);
this.writeFloat32(value);
};
/**
* Add a `float64` to the buffer, properly aligned, and grows the buffer (if necessary).
* @param {number} value The `float64` to add the the buffer.
*/
flatbuffers.Builder.prototype.addFloat64 = function(value) {
this.prep(8, 0);
this.writeFloat64(value);
};
/// @cond FLATBUFFERS_INTERNAL
/**
* @param {number} voffset
* @param {number} value
* @param {number} defaultValue
*/
flatbuffers.Builder.prototype.addFieldInt8 = function(voffset, value, defaultValue) {
if (this.force_defaults || value != defaultValue) {
this.addInt8(value);
this.slot(voffset);
}
};
/**
* @param {number} voffset
* @param {number} value
* @param {number} defaultValue
*/
flatbuffers.Builder.prototype.addFieldInt16 = function(voffset, value, defaultValue) {
if (this.force_defaults || value != defaultValue) {
this.addInt16(value);
this.slot(voffset);
}
};
/**
* @param {number} voffset
* @param {number} value
* @param {number} defaultValue
*/
flatbuffers.Builder.prototype.addFieldInt32 = function(voffset, value, defaultValue) {
if (this.force_defaults || value != defaultValue) {
this.addInt32(value);
this.slot(voffset);
}
};
/**
* @param {number} voffset
* @param {flatbuffers.Long} value
* @param {flatbuffers.Long} defaultValue
*/
flatbuffers.Builder.prototype.addFieldInt64 = function(voffset, value, defaultValue) {
if (this.force_defaults || !value.equals(defaultValue)) {
this.addInt64(value);
this.slot(voffset);
}
};
/**
* @param {number} voffset
* @param {number} value
* @param {number} defaultValue
*/
flatbuffers.Builder.prototype.addFieldFloat32 = function(voffset, value, defaultValue) {
if (this.force_defaults || value != defaultValue) {
this.addFloat32(value);
this.slot(voffset);
}
};
/**
* @param {number} voffset
* @param {number} value
* @param {number} defaultValue
*/
flatbuffers.Builder.prototype.addFieldFloat64 = function(voffset, value, defaultValue) {
if (this.force_defaults || value != defaultValue) {
this.addFloat64(value);
this.slot(voffset);
}
};
/**
* @param {number} voffset
* @param {flatbuffers.Offset} value
* @param {flatbuffers.Offset} defaultValue
*/
flatbuffers.Builder.prototype.addFieldOffset = function(voffset, value, defaultValue) {
if (this.force_defaults || value != defaultValue) {
this.addOffset(value);
this.slot(voffset);
}
};
/**
* Structs are stored inline, so nothing additional is being added. `d` is always 0.
*
* @param {number} voffset
* @param {flatbuffers.Offset} value
* @param {flatbuffers.Offset} defaultValue
*/
flatbuffers.Builder.prototype.addFieldStruct = function(voffset, value, defaultValue) {
if (value != defaultValue) {
this.nested(value);
this.slot(voffset);
}
};
/**
* Structures are always stored inline, they need to be created right
* where they're used. You'll get this assertion failure if you
* created it elsewhere.
*
* @param {flatbuffers.Offset} obj The offset of the created object
*/
flatbuffers.Builder.prototype.nested = function(obj) {
if (obj != this.offset()) {
throw new Error('FlatBuffers: struct must be serialized inline.');
}
};
/**
* Should not be creating any other object, string or vector
* while an object is being constructed
*/
flatbuffers.Builder.prototype.notNested = function() {
if (this.isNested) {
throw new Error('FlatBuffers: object serialization must not be nested.');
}
};
/**
* Set the current vtable at `voffset` to the current location in the buffer.
*
* @param {number} voffset
*/
flatbuffers.Builder.prototype.slot = function(voffset) {
this.vtable[voffset] = this.offset();
};
/**
* @returns {flatbuffers.Offset} Offset relative to the end of the buffer.
*/
flatbuffers.Builder.prototype.offset = function() {
return this.bb.capacity() - this.space;
};
/**
* Doubles the size of the backing ByteBuffer and copies the old data towards
* the end of the new buffer (since we build the buffer backwards).
*
* @param {flatbuffers.ByteBuffer} bb The current buffer with the existing data
* @returns {!flatbuffers.ByteBuffer} A new byte buffer with the old data copied
* to it. The data is located at the end of the buffer.
*
* uint8Array.set() formally takes {Array<number>|ArrayBufferView}, so to pass
* it a uint8Array we need to suppress the type check:
* @suppress {checkTypes}
*/
flatbuffers.Builder.growByteBuffer = function(bb) {
var old_buf_size = bb.capacity();
// Ensure we don't grow beyond what fits in an int.
if (old_buf_size & 0xC0000000) {
throw new Error('FlatBuffers: cannot grow buffer beyond 2 gigabytes.');
}
var new_buf_size = old_buf_size << 1;
var nbb = flatbuffers.ByteBuffer.allocate(new_buf_size);
nbb.setPosition(new_buf_size - old_buf_size);
nbb.bytes().set(bb.bytes(), new_buf_size - old_buf_size);
return nbb;
};
/// @endcond
/**
* Adds on offset, relative to where it will be written.
*
* @param {flatbuffers.Offset} offset The offset to add.
*/
flatbuffers.Builder.prototype.addOffset = function(offset) {
this.prep(flatbuffers.SIZEOF_INT, 0); // Ensure alignment is already done.
this.writeInt32(this.offset() - offset + flatbuffers.SIZEOF_INT);
};
/// @cond FLATBUFFERS_INTERNAL
/**
* Start encoding a new object in the buffer. Users will not usually need to
* call this directly. The FlatBuffers compiler will generate helper methods
* that call this method internally.
*
* @param {number} numfields
*/
flatbuffers.Builder.prototype.startObject = function(numfields) {
this.notNested();
if (this.vtable == null) {
this.vtable = [];
}
this.vtable_in_use = numfields;
for (var i = 0; i < numfields; i++) {
this.vtable[i] = 0; // This will push additional elements as needed
}
this.isNested = true;
this.object_start = this.offset();
};
/**
* Finish off writing the object that is under construction.
*
* @returns {flatbuffers.Offset} The offset to the object inside `dataBuffer`
*/
flatbuffers.Builder.prototype.endObject = function() {
if (this.vtable == null || !this.isNested) {
throw new Error('FlatBuffers: endObject called without startObject');
}
this.addInt32(0);
var vtableloc = this.offset();
// Trim trailing zeroes.
var i = this.vtable_in_use - 1;
for (; i >= 0 && this.vtable[i] == 0; i--) {}
var trimmed_size = i + 1;
// Write out the current vtable.
for (; i >= 0; i--) {
// Offset relative to the start of the table.
this.addInt16(this.vtable[i] != 0 ? vtableloc - this.vtable[i] : 0);
}
var standard_fields = 2; // The fields below:
this.addInt16(vtableloc - this.object_start);
var len = (trimmed_size + standard_fields) * flatbuffers.SIZEOF_SHORT;
this.addInt16(len);
// Search for an existing vtable that matches the current one.
var existing_vtable = 0;
var vt1 = this.space;
outer_loop:
for (i = 0; i < this.vtables.length; i++) {
var vt2 = this.bb.capacity() - this.vtables[i];
if (len == this.bb.readInt16(vt2)) {
for (var j = flatbuffers.SIZEOF_SHORT; j < len; j += flatbuffers.SIZEOF_SHORT) {
if (this.bb.readInt16(vt1 + j) != this.bb.readInt16(vt2 + j)) {
continue outer_loop;
}
}
existing_vtable = this.vtables[i];
break;
}
}
if (existing_vtable) {
// Found a match:
// Remove the current vtable.
this.space = this.bb.capacity() - vtableloc;
// Point table to existing vtable.
this.bb.writeInt32(this.space, existing_vtable - vtableloc);
} else {
// No match:
// Add the location of the current vtable to the list of vtables.
this.vtables.push(this.offset());
// Point table to current vtable.
this.bb.writeInt32(this.bb.capacity() - vtableloc, this.offset() - vtableloc);
}
this.isNested = false;
return vtableloc;
};
/// @endcond
/**
* Finalize a buffer, poiting to the given `root_table`.
*
* @param {flatbuffers.Offset} root_table
* @param {string=} opt_file_identifier
* @param {boolean=} opt_size_prefix
*/
flatbuffers.Builder.prototype.finish = function(root_table, opt_file_identifier, opt_size_prefix) {
var size_prefix = opt_size_prefix ? flatbuffers.SIZE_PREFIX_LENGTH : 0;
if (opt_file_identifier) {
var file_identifier = opt_file_identifier;
this.prep(this.minalign, flatbuffers.SIZEOF_INT +
flatbuffers.FILE_IDENTIFIER_LENGTH + size_prefix);
if (file_identifier.length != flatbuffers.FILE_IDENTIFIER_LENGTH) {
throw new Error('FlatBuffers: file identifier must be length ' +
flatbuffers.FILE_IDENTIFIER_LENGTH);
}
for (var i = flatbuffers.FILE_IDENTIFIER_LENGTH - 1; i >= 0; i--) {
this.writeInt8(file_identifier.charCodeAt(i));
}
}
this.prep(this.minalign, flatbuffers.SIZEOF_INT + size_prefix);
this.addOffset(root_table);
if (size_prefix) {
this.addInt32(this.bb.capacity() - this.space);
}
this.bb.setPosition(this.space);
};
/**
* Finalize a size prefixed buffer, pointing to the given `root_table`.
*
* @param {flatbuffers.Offset} root_table
* @param {string=} opt_file_identifier
*/
flatbuffers.Builder.prototype.finishSizePrefixed = function (root_table, opt_file_identifier) {
this.finish(root_table, opt_file_identifier, true);
};
/// @cond FLATBUFFERS_INTERNAL
/**
* This checks a required field has been set in a given table that has
* just been constructed.
*
* @param {flatbuffers.Offset} table
* @param {number} field
*/
flatbuffers.Builder.prototype.requiredField = function(table, field) {
var table_start = this.bb.capacity() - table;
var vtable_start = table_start - this.bb.readInt32(table_start);
var ok = this.bb.readInt16(vtable_start + field) != 0;
// If this fails, the caller will show what field needs to be set.
if (!ok) {
throw new Error('FlatBuffers: field ' + field + ' must be set');
}
};
/**
* Start a new array/vector of objects. Users usually will not call
* this directly. The FlatBuffers compiler will create a start/end
* method for vector types in generated code.
*
* @param {number} elem_size The size of each element in the array
* @param {number} num_elems The number of elements in the array
* @param {number} alignment The alignment of the array
*/
flatbuffers.Builder.prototype.startVector = function(elem_size, num_elems, alignment) {
this.notNested();
this.vector_num_elems = num_elems;
this.prep(flatbuffers.SIZEOF_INT, elem_size * num_elems);
this.prep(alignment, elem_size * num_elems); // Just in case alignment > int.
};
/**
* Finish off the creation of an array and all its elements. The array must be
* created with `startVector`.
*
* @returns {flatbuffers.Offset} The offset at which the newly created array
* starts.
*/
flatbuffers.Builder.prototype.endVector = function() {
this.writeInt32(this.vector_num_elems);
return this.offset();
};
/// @endcond
/**
* Encode the string `s` in the buffer using UTF-8. If a Uint8Array is passed
* instead of a string, it is assumed to contain valid UTF-8 encoded data.
*
* @param {string|Uint8Array} s The string to encode
* @return {flatbuffers.Offset} The offset in the buffer where the encoded string starts
*/
flatbuffers.Builder.prototype.createString = function(s) {
if (s instanceof Uint8Array) {
var utf8 = s;
} else {
var utf8 = [];
var i = 0;
while (i < s.length) {
var codePoint;
// Decode UTF-16
var a = s.charCodeAt(i++);
if (a < 0xD800 || a >= 0xDC00) {
codePoint = a;
} else {
var b = s.charCodeAt(i++);
codePoint = (a << 10) + b + (0x10000 - (0xD800 << 10) - 0xDC00);
}
// Encode UTF-8
if (codePoint < 0x80) {
utf8.push(codePoint);
} else {
if (codePoint < 0x800) {
utf8.push(((codePoint >> 6) & 0x1F) | 0xC0);
} else {
if (codePoint < 0x10000) {
utf8.push(((codePoint >> 12) & 0x0F) | 0xE0);
} else {
utf8.push(
((codePoint >> 18) & 0x07) | 0xF0,
((codePoint >> 12) & 0x3F) | 0x80);
}
utf8.push(((codePoint >> 6) & 0x3F) | 0x80);
}
utf8.push((codePoint & 0x3F) | 0x80);
}
}
}
this.addInt8(0);
this.startVector(1, utf8.length, 1);
this.bb.setPosition(this.space -= utf8.length);
for (var i = 0, offset = this.space, bytes = this.bb.bytes(); i < utf8.length; i++) {
bytes[offset++] = utf8[i];
}
return this.endVector();
};
/**
* A helper function to avoid generated code depending on this file directly.
*
* @param {number} low
* @param {number} high
* @returns {!flatbuffers.Long}
*/
flatbuffers.Builder.prototype.createLong = function(low, high) {
return flatbuffers.Long.create(low, high);
};
////////////////////////////////////////////////////////////////////////////////
/// @cond FLATBUFFERS_INTERNAL
/**
* Create a new ByteBuffer with a given array of bytes (`Uint8Array`).
*
* @constructor
* @param {Uint8Array} bytes
*/
flatbuffers.ByteBuffer = function(bytes) {
/**
* @type {Uint8Array}
* @private
*/
this.bytes_ = bytes;
/**
* @type {number}
* @private
*/
this.position_ = 0;
};
/**
* Create and allocate a new ByteBuffer with a given size.
*
* @param {number} byte_size
* @returns {!flatbuffers.ByteBuffer}
*/
flatbuffers.ByteBuffer.allocate = function(byte_size) {
return new flatbuffers.ByteBuffer(new Uint8Array(byte_size));
};
flatbuffers.ByteBuffer.prototype.clear = function() {
this.position_ = 0;
};
/**
* Get the underlying `Uint8Array`.
*
* @returns {Uint8Array}
*/
flatbuffers.ByteBuffer.prototype.bytes = function() {
return this.bytes_;
};
/**
* Get the buffer's position.
*
* @returns {number}
*/
flatbuffers.ByteBuffer.prototype.position = function() {
return this.position_;
};
/**
* Set the buffer's position.
*
* @param {number} position
*/
flatbuffers.ByteBuffer.prototype.setPosition = function(position) {
this.position_ = position;
};
/**
* Get the buffer's capacity.
*
* @returns {number}
*/
flatbuffers.ByteBuffer.prototype.capacity = function() {
return this.bytes_.length;
};
/**
* @param {number} offset
* @returns {number}
*/
flatbuffers.ByteBuffer.prototype.readInt8 = function(offset) {
return this.readUint8(offset) << 24 >> 24;
};
/**
* @param {number} offset
* @returns {number}
*/
flatbuffers.ByteBuffer.prototype.readUint8 = function(offset) {
return this.bytes_[offset];
};
/**
* @param {number} offset
* @returns {number}
*/
flatbuffers.ByteBuffer.prototype.readInt16 = function(offset) {
return this.readUint16(offset) << 16 >> 16;
};
/**
* @param {number} offset
* @returns {number}
*/
flatbuffers.ByteBuffer.prototype.readUint16 = function(offset) {
return this.bytes_[offset] | this.bytes_[offset + 1] << 8;
};
/**
* @param {number} offset
* @returns {number}
*/
flatbuffers.ByteBuffer.prototype.readInt32 = function(offset) {
return this.bytes_[offset] | this.bytes_[offset + 1] << 8 | this.bytes_[offset + 2] << 16 | this.bytes_[offset + 3] << 24;
};
/**
* @param {number} offset
* @returns {number}
*/
flatbuffers.ByteBuffer.prototype.readUint32 = function(offset) {
return this.readInt32(offset) >>> 0;
};
/**
* @param {number} offset
* @returns {!flatbuffers.Long}
*/
flatbuffers.ByteBuffer.prototype.readInt64 = function(offset) {
return new flatbuffers.Long(this.readInt32(offset), this.readInt32(offset + 4));
};
/**
* @param {number} offset
* @returns {!flatbuffers.Long}
*/
flatbuffers.ByteBuffer.prototype.readUint64 = function(offset) {
return new flatbuffers.Long(this.readUint32(offset), this.readUint32(offset + 4));
};
/**
* @param {number} offset
* @returns {number}
*/
flatbuffers.ByteBuffer.prototype.readFloat32 = function(offset) {
flatbuffers.int32[0] = this.readInt32(offset);
return flatbuffers.float32[0];
};
/**
* @param {number} offset
* @returns {number}
*/
flatbuffers.ByteBuffer.prototype.readFloat64 = function(offset) {
flatbuffers.int32[flatbuffers.isLittleEndian ? 0 : 1] = this.readInt32(offset);
flatbuffers.int32[flatbuffers.isLittleEndian ? 1 : 0] = this.readInt32(offset + 4);
return flatbuffers.float64[0];
};
/**
* @param {number} offset
* @param {number|boolean} value
*/
flatbuffers.ByteBuffer.prototype.writeInt8 = function(offset, value) {
this.bytes_[offset] = /** @type {number} */(value);
};
/**
* @param {number} offset
* @param {number} value
*/
flatbuffers.ByteBuffer.prototype.writeUint8 = function(offset, value) {
this.bytes_[offset] = value;
};
/**
* @param {number} offset
* @param {number} value
*/
flatbuffers.ByteBuffer.prototype.writeInt16 = function(offset, value) {
this.bytes_[offset] = value;
this.bytes_[offset + 1] = value >> 8;
};
/**
* @param {number} offset
* @param {number} value
*/
flatbuffers.ByteBuffer.prototype.writeUint16 = function(offset, value) {
this.bytes_[offset] = value;
this.bytes_[offset + 1] = value >> 8;
};
/**
* @param {number} offset
* @param {number} value
*/
flatbuffers.ByteBuffer.prototype.writeInt32 = function(offset, value) {
this.bytes_[offset] = value;
this.bytes_[offset + 1] = value >> 8;
this.bytes_[offset + 2] = value >> 16;
this.bytes_[offset + 3] = value >> 24;
};
/**
* @param {number} offset
* @param {number} value
*/
flatbuffers.ByteBuffer.prototype.writeUint32 = function(offset, value) {
this.bytes_[offset] = value;
this.bytes_[offset + 1] = value >> 8;
this.bytes_[offset + 2] = value >> 16;
this.bytes_[offset + 3] = value >> 24;
};
/**
* @param {number} offset
* @param {flatbuffers.Long} value
*/
flatbuffers.ByteBuffer.prototype.writeInt64 = function(offset, value) {
this.writeInt32(offset, value.low);
this.writeInt32(offset + 4, value.high);
};
/**
* @param {number} offset
* @param {flatbuffers.Long} value
*/
flatbuffers.ByteBuffer.prototype.writeUint64 = function(offset, value) {
this.writeUint32(offset, value.low);
this.writeUint32(offset + 4, value.high);
};
/**
* @param {number} offset
* @param {number} value
*/
flatbuffers.ByteBuffer.prototype.writeFloat32 = function(offset, value) {
flatbuffers.float32[0] = value;
this.writeInt32(offset, flatbuffers.int32[0]);
};
/**
* @param {number} offset
* @param {number} value
*/
flatbuffers.ByteBuffer.prototype.writeFloat64 = function(offset, value) {
flatbuffers.float64[0] = value;
this.writeInt32(offset, flatbuffers.int32[flatbuffers.isLittleEndian ? 0 : 1]);
this.writeInt32(offset + 4, flatbuffers.int32[flatbuffers.isLittleEndian ? 1 : 0]);
};
/**
* Return the file identifier. Behavior is undefined for FlatBuffers whose
* schema does not include a file_identifier (likely points at padding or the
* start of a the root vtable).
* @returns {string}
*/
flatbuffers.ByteBuffer.prototype.getBufferIdentifier = function() {
if (this.bytes_.length < this.position_ + flatbuffers.SIZEOF_INT +
flatbuffers.FILE_IDENTIFIER_LENGTH) {
throw new Error(
'FlatBuffers: ByteBuffer is too short to contain an identifier.');
}
var result = "";
for (var i = 0; i < flatbuffers.FILE_IDENTIFIER_LENGTH; i++) {
result += String.fromCharCode(
this.readInt8(this.position_ + flatbuffers.SIZEOF_INT + i));
}
return result;
};
/**
* Look up a field in the vtable, return an offset into the object, or 0 if the
* field is not present.
*
* @param {number} bb_pos
* @param {number} vtable_offset
* @returns {number}
*/
flatbuffers.ByteBuffer.prototype.__offset = function(bb_pos, vtable_offset) {
var vtable = bb_pos - this.readInt32(bb_pos);
return vtable_offset < this.readInt16(vtable) ? this.readInt16(vtable + vtable_offset) : 0;
};
/**
* Initialize any Table-derived type to point to the union at the given offset.
*
* @param {flatbuffers.Table} t
* @param {number} offset
* @returns {flatbuffers.Table}
*/
flatbuffers.ByteBuffer.prototype.__union = function(t, offset) {
t.bb_pos = offset + this.readInt32(offset);
t.bb = this;
return t;
};
/**
* Create a JavaScript string from UTF-8 data stored inside the FlatBuffer.
* This allocates a new string and converts to wide chars upon each access.
*
* To avoid the conversion to UTF-16, pass flatbuffers.Encoding.UTF8_BYTES as
* the "optionalEncoding" argument. This is useful for avoiding conversion to
* and from UTF-16 when the data will just be packaged back up in another
* FlatBuffer later on.
*
* @param {number} offset
* @param {flatbuffers.Encoding=} opt_encoding Defaults to UTF16_STRING
* @returns {string|!Uint8Array}
*/
flatbuffers.ByteBuffer.prototype.__string = function(offset, opt_encoding) {
offset += this.readInt32(offset);
var length = this.readInt32(offset);
var result = '';
var i = 0;
offset += flatbuffers.SIZEOF_INT;
if (opt_encoding === flatbuffers.Encoding.UTF8_BYTES) {
return this.bytes_.subarray(offset, offset + length);
}
while (i < length) {
var codePoint;
// Decode UTF-8
var a = this.readUint8(offset + i++);
if (a < 0xC0) {
codePoint = a;
} else {
var b = this.readUint8(offset + i++);
if (a < 0xE0) {
codePoint =
((a & 0x1F) << 6) |
(b & 0x3F);
} else {
var c = this.readUint8(offset + i++);
if (a < 0xF0) {
codePoint =
((a & 0x0F) << 12) |
((b & 0x3F) << 6) |
(c & 0x3F);
} else {
var d = this.readUint8(offset + i++);
codePoint =
((a & 0x07) << 18) |
((b & 0x3F) << 12) |
((c & 0x3F) << 6) |
(d & 0x3F);
}
}
}
// Encode UTF-16
if (codePoint < 0x10000) {
result += String.fromCharCode(codePoint);
} else {
codePoint -= 0x10000;
result += String.fromCharCode(
(codePoint >> 10) + 0xD800,
(codePoint & ((1 << 10) - 1)) + 0xDC00);
}
}
return result;
};
/**
* Retrieve the relative offset stored at "offset"
* @param {number} offset
* @returns {number}
*/
flatbuffers.ByteBuffer.prototype.__indirect = function(offset) {
return offset + this.readInt32(offset);
};
/**
* Get the start of data of a vector whose offset is stored at "offset" in this object.
*
* @param {number} offset
* @returns {number}
*/
flatbuffers.ByteBuffer.prototype.__vector = function(offset) {
return offset + this.readInt32(offset) + flatbuffers.SIZEOF_INT; // data starts after the length
};
/**
* Get the length of a vector whose offset is stored at "offset" in this object.
*
* @param {number} offset
* @returns {number}
*/
flatbuffers.ByteBuffer.prototype.__vector_len = function(offset) {
return this.readInt32(offset + this.readInt32(offset));
};
/**
* @param {string} ident
* @returns {boolean}
*/
flatbuffers.ByteBuffer.prototype.__has_identifier = function(ident) {
if (ident.length != flatbuffers.FILE_IDENTIFIER_LENGTH) {
throw new Error('FlatBuffers: file identifier must be length ' +
flatbuffers.FILE_IDENTIFIER_LENGTH);
}
for (var i = 0; i < flatbuffers.FILE_IDENTIFIER_LENGTH; i++) {
if (ident.charCodeAt(i) != this.readInt8(this.position_ + flatbuffers.SIZEOF_INT + i)) {
return false;
}
}
return true;
};
/**
* A helper function to avoid generated code depending on this file directly.
*
* @param {number} low
* @param {number} high
* @returns {!flatbuffers.Long}
*/
flatbuffers.ByteBuffer.prototype.createLong = function(low, high) {
return flatbuffers.Long.create(low, high);
};
// Exports for Node.js and RequireJS
/// @endcond
/// @}
/***/ })
/******/ });
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ var cachedModule = __webpack_module_cache__[moduleId];
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ // no module.id needed
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/************************************************************************/
/******/ /* webpack/runtime/compat get default export */
/******/ (() => {
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = (module) => {
/******/ var getter = module && module.__esModule ?
/******/ () => (module['default']) :
/******/ () => (module);
/******/ __webpack_require__.d(getter, { a: getter });
/******/ return getter;
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/define property getters */
/******/ (() => {
/******/ // define getter functions for harmony exports
/******/ __webpack_require__.d = (exports, definition) => {
/******/ for(var key in definition) {
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ }
/******/ }
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/global */
/******/ (() => {
/******/ __webpack_require__.g = (function() {
/******/ if (typeof globalThis === 'object') return globalThis;
/******/ try {
/******/ return this || new Function('return this')();
/******/ } catch (e) {
/******/ if (typeof window === 'object') return window;
/******/ }
/******/ })();
/******/ })();
/******/
/******/ /* webpack/runtime/hasOwnProperty shorthand */
/******/ (() => {
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
/******/ })();
/******/
/******/ /* webpack/runtime/make namespace object */
/******/ (() => {
/******/ // define __esModule on exports
/******/ __webpack_require__.r = (exports) => {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/ })();
/******/
/************************************************************************/
/******/
/******/ // startup
/******/ // Load entry module and return exports
/******/ // This entry module is referenced by other modules so it can't be inlined
/******/ var __webpack_exports__ = __webpack_require__("./lib/index.ts");
/******/
/******/ return __webpack_exports__;
/******/ })()
;
});
//# sourceMappingURL=data:application/json;charset=utf-8;base64,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QSxXQUFXLFFBQVE7QUFDbkIsV0FBVyxZQUFZO0FBQ3ZCLFdBQVcsUUFBUTtBQUNuQixhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxZQUFZO0FBQ3ZCLFdBQVcsUUFBUTtBQUNuQixhQUFhLFFBQVE7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxZQUFZO0FBQ3ZCLFdBQVcsUUFBUTtBQUNuQixhQUFhLFFBQVE7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxRQUFRO0FBQ25CLFdBQVcsWUFBWTtBQUN2QixXQUFXLFFBQVE7QUFDbkIsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsUUFBUTtBQUNuQixXQUFXLFlBQVk7QUFDdkIsV0FBVyxRQUFRO0FBQ25CLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLFlBQVk7QUFDdkIsV0FBVyxRQUFRO0FBQ25CLGFBQWEsUUFBUTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLFlBQVk7QUFDdkIsV0FBVyxRQUFRO0FBQ25CLGFBQWEsUUFBUTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUssS0FBSztBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSyxLQUFLO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0EsY0FBYywwQ0FBMEM7QUFDeEQ7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBLHFEQUFxRDtBQUNyRDtBQUNBO0FBQ0E7QUFDQSxrQkFBa0I7QUFDbEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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ckIsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLHNCQUFzQiwrQ0FBK0M7QUFDaEYsV0FBVyxVQUFVO0FBQ3JCLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxTQUFTO0FBQ3BCLGFBQWE7QUFDYjtBQUNBLFlBQVksWUFBWTtBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWEsUUFBUTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWEsUUFBUTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWEsUUFBUTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWEsUUFBUTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCLFNBQVM7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0VBQWdFLGtCQUFrQjtBQUNsRixhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcscUJBQXFCO0FBQ2hDLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJFQUEyRSxrQkFBa0I7QUFDN0Y7QUFDQSxXQUFXLHFCQUFxQjtBQUNoQyxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcscUJBQXFCO0FBQ2hDLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpRkFBaUYscUJBQXFCO0FBQ3RHO0FBQ0EsV0FBVyxxQkFBcUI7QUFDaEMsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUZBQWlGLHFCQUFxQjtBQUN0RztBQUNBLFdBQVcscUJBQXFCO0FBQ2hDLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxxQkFBcUI7QUFDaEMsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlGQUFpRixvQkFBb0I7QUFDckc7QUFDQSxXQUFXLHFCQUFxQjtBQUNoQyxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcscUJBQXFCO0FBQ2hDLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwRkFBMEYsMkJBQTJCO0FBQ3JIO0FBQ0EsV0FBVyxxQkFBcUI7QUFDaEMsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEZBQTBGLDJCQUEyQjtBQUNySDtBQUNBLFdBQVcscUJBQXFCO0FBQ2hDLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxxQkFBcUI7QUFDaEMsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9GQUFvRix1QkFBdUI7QUFDM0c7QUFDQSxXQUFXLHFCQUFxQjtBQUNoQyxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcscUJBQXFCO0FBQ2hDLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2RkFBNkYsOEJBQThCO0FBQzNIO0FBQ0EsV0FBVyxxQkFBcUI7QUFDaEMsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkZBQTZGLDhCQUE4QjtBQUMzSDtBQUNBLFdBQVcscUJBQXFCO0FBQ2hDLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxxQkFBcUI7QUFDaEMsYUFBYSxRQUFRO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlFQUF5RSxtQkFBbUI7QUFDNUY7QUFDQSxXQUFXLHFCQUFxQjtBQUNoQyxhQUFhLFFBQVE7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSxPQUFPO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtREFBbUQsa0JBQWtCO0FBQ3JFO0FBQ0EsYUFBYSxPQUFPO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLHFCQUFxQjtBQUNoQyxhQUFhLE9BQU87QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLHFCQUFxQjtBQUNoQyxhQUFhLE9BQU87QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtFQUErRSxvQkFBb0I7QUFDbkc7QUFDQSxXQUFXLHFCQUFxQjtBQUNoQyxhQUFhLE9BQU87QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcscUJBQXFCO0FBQ2hDLGFBQWEsT0FBTztBQUNwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEVBQTRFLG9CQUFvQjtBQUNoRztBQUNBLFdBQVcscUJBQXFCO0FBQ2hDLGFBQWEsT0FBTztBQUNwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLHFCQUFxQjtBQUNoQyxhQUFhLE9BQU87QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQztBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdEQUF3RCxtQkFBbUI7QUFDM0U7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0VBQW9FLGtCQUFrQjtBQUN0RjtBQUNBLFdBQVcscUJBQXFCO0FBQ2hDLGFBQWEsT0FBTztBQUNwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxxQkFBcUI7QUFDaEMsYUFBYSxPQUFPO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnRUFBZ0Usa0JBQWtCO0FBQ2xGO0FBQ0EsV0FBVyxxQkFBcUI7QUFDaEMsYUFBYSxPQUFPO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0VBQWdFLGtCQUFrQjtBQUNsRjtBQUNBLFdBQVcscUJBQXFCO0FBQ2hDLGFBQWEsT0FBTztBQUNwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxxQkFBcUI7QUFDaEMsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcscUJBQXFCO0FBQ2hDLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLHFCQUFxQjtBQUNoQyxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxjQUFjO0FBQ3pCLGFBQWEsT0FBTztBQUNwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZGQUE2RixxQkFBcUI7QUFDbEg7QUFDQSxXQUFXLGNBQWM7QUFDekIsYUFBYSxPQUFPO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLGNBQWM7QUFDekIsYUFBYSxPQUFPO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkdBQTZHLHNCQUFzQjtBQUNuSTtBQUNBLFdBQVcsY0FBYztBQUN6QixhQUFhLE9BQU87QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsY0FBYztBQUN6QixhQUFhLE9BQU87QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0dBQXdHLDhCQUE4QjtBQUN0STtBQUNBLFdBQVcsY0FBYztBQUN6QixhQUFhLE9BQU87QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3R0FBd0csOEJBQThCO0FBQ3RJO0FBQ0EsV0FBVyxjQUFjO0FBQ3pCLGFBQWEsT0FBTztBQUNwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSxPQUFPO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWEsT0FBTztBQUNwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLFVBQVU7QUFDckIsYUFBYSxpQkFBaUI7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhLGlCQUFpQjtBQUM5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhLGlCQUFpQjtBQUM5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLGlCQUFpQjtBQUM1QixXQUFXLFVBQVU7QUFDckIsV0FBVyxVQUFVO0FBQ3JCLGFBQWEsTUFBTTtBQUNuQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsaUJBQWlCO0FBQzVCLFdBQVcsVUFBVTtBQUNyQixhQUFhLE1BQU07QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsaUJBQWlCO0FBQzVCLFdBQVcsVUFBVTtBQUNyQixhQUFhLE1BQU07QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7O0FDMXlDQTtBQUNhOztBQUViLGdCQUFnQixtQkFBTyxDQUFDLGdFQUFvQjs7QUFFNUM7QUFDQTs7QUFFQTtBQUNBLDBFQUEwRTs7QUFFMUU7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZCxrQkFBa0IsUUFBUTtBQUMxQixrQkFBa0IsUUFBUTtBQUMxQixrQkFBa0IsUUFBUTtBQUMxQixrQkFBa0IsUUFBUTtBQUMxQixrQkFBa0IsUUFBUTtBQUMxQixrQkFBa0IsUUFBUTtBQUMxQjtBQUNBO0FBQ0EsMkJBQTJCO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNCQUFzQixhQUFhO0FBQ25DLHNCQUFzQixhQUFhO0FBQ25DLHNCQUFzQixhQUFhO0FBQ25DLHNCQUFzQix3Q0FBd0M7QUFDOUQsc0JBQXNCLGFBQWE7QUFDbkMsc0JBQXNCLGtCQUFrQjtBQUN4QyxzQkFBc0IsaUJBQWlCO0FBQ3ZDLHNCQUFzQix3QkFBd0I7QUFDOUMsc0JBQXNCLHVCQUF1QjtBQUM3QyxzQkFBc0IscUJBQXFCO0FBQzNDLHNCQUFzQiwwQkFBMEI7QUFDaEQsc0JBQXNCLHlCQUF5QjtBQUMvQyxzQkFBc0IsZ0NBQWdDO0FBQ3RELHNCQUFzQiwrQkFBK0I7QUFDckQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLHVCQUF1QjtBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0VBQWdFLGlCQUFpQjtBQUNqRjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9CQUFvQixRQUFRO0FBQzVCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQkFBb0IsUUFBUTtBQUM1QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esb0JBQW9CLFFBQVE7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9CQUFvQixtQ0FBbUM7QUFDdkQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9CQUFvQixRQUFRO0FBQzVCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQkFBb0IsYUFBYTtBQUNqQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esb0JBQW9CLFlBQVk7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9CQUFvQixrQ0FBa0M7QUFDdEQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9CQUFvQixpQ0FBaUM7QUFDckQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9CQUFvQixnQkFBZ0I7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9CQUFvQixxQkFBcUI7QUFDekM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9CQUFvQixvQkFBb0I7QUFDeEM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9CQUFvQiwyQkFBMkI7QUFDL0M7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9CQUFvQiwwQkFBMEI7QUFDOUM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQix1QkFBdUI7QUFDMUMscUJBQXFCLHFCQUFxQjtBQUMxQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDhFQUE4RSx5Q0FBeUM7QUFDdkg7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLHNCQUFzQjtBQUN6QyxtQkFBbUIsa0JBQWtCO0FBQ3JDLHFCQUFxQixrQkFBa0I7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLDJCQUEyQjtBQUMzRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLHlCQUF5QjtBQUN6RDtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyw0QkFBNEI7QUFDNUQ7QUFDQTtBQUNBLGdDQUFnQyw0QkFBNEI7QUFDNUQ7QUFDQTtBQUNBLGdDQUFnQywyQkFBMkI7QUFDM0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsZ0dBQWdHLHlDQUF5QztBQUN6STtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsc0JBQXNCO0FBQ3pDLG1CQUFtQixrQkFBa0I7QUFDckMscUJBQXFCLGtCQUFrQjtBQUN2QztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLDZCQUE2QjtBQUNoRCxtQkFBbUIsUUFBUTtBQUMzQixxQkFBcUIscUJBQXFCO0FBQzFDLG9CQUFvQixPQUFPO0FBQzNCLG9CQUFvQiw4QkFBOEI7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNCQUFzQjtBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQiw2QkFBNkI7QUFDaEQscUJBQXFCLHFCQUFxQjtBQUMxQyxvQkFBb0IsT0FBTztBQUMzQixvQkFBb0IsOEJBQThCO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLG1CQUFtQjtBQUN0QyxxQkFBcUIsYUFBYTtBQUNsQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQywyQkFBMkI7QUFDM0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLHlCQUF5QjtBQUN6RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MsNEJBQTRCO0FBQzVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyw0QkFBNEI7QUFDNUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQywyQkFBMkI7QUFDM0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixtQkFBbUI7QUFDdEMscUJBQXFCLHFCQUFxQjtBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MsMEJBQTBCO0FBQzFEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyx3QkFBd0I7QUFDeEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MsMkJBQTJCO0FBQzNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQywyQkFBMkI7QUFDM0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLDBCQUEwQjtBQUMxRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLHFCQUFxQjtBQUN4QyxtQkFBbUIsOEJBQThCO0FBQ2pELHFCQUFxQixtQkFBbUI7QUFDeEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLDJCQUEyQjtBQUMzRDtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyx5QkFBeUI7QUFDekQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MsNEJBQTRCO0FBQzVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLDRCQUE0QjtBQUM1RDtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQywyQkFBMkI7QUFDM0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQixtQkFBbUI7QUFDeEM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCO0FBQ2xCLHNCQUFzQixRQUFRO0FBQzlCLHNCQUFzQixRQUFRO0FBQzlCLHNCQUFzQixRQUFRO0FBQzlCLHNCQUFzQixRQUFRO0FBQzlCLHNCQUFzQixRQUFRO0FBQzlCLHNCQUFzQixRQUFRO0FBQzlCLHNCQUFzQixRQUFRO0FBQzlCLHNCQUFzQixRQUFRO0FBQzlCLHNCQUFzQixRQUFRO0FBQzlCLHNCQUFzQixRQUFRO0FBQzlCLHNCQUFzQixRQUFRO0FBQzlCO0FBQ0E7QUFDQSwrQkFBK0I7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUzs7QUFFVDtBQUNBLEtBQUs7O0FBRUw7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0IsYUFBYTtBQUNuQyxzQkFBc0Isc0JBQXNCO0FBQzVDLHNCQUFzQixhQUFhO0FBQ25DOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQix1QkFBdUI7QUFDMUM7QUFDQTtBQUNBO0FBQ0EsZ0VBQWdFLGlCQUFpQjtBQUNqRjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9CQUFvQixRQUFRO0FBQzVCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQkFBb0IsZ0NBQWdDO0FBQ3BEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQkFBb0IsUUFBUTtBQUM1QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLHVCQUF1QjtBQUMxQyxxQkFBcUIscUJBQXFCO0FBQzFDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsOEVBQThFLHlDQUF5QztBQUN2SDtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsc0JBQXNCO0FBQ3pDLG1CQUFtQixrQkFBa0I7QUFDckMscUJBQXFCLGtCQUFrQjtBQUN2QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxnR0FBZ0cseUNBQXlDO0FBQ3pJO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixzQkFBc0I7QUFDekMsbUJBQW1CLGtCQUFrQjtBQUNyQyxxQkFBcUIsa0JBQWtCO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsNkJBQTZCO0FBQ2hELG1CQUFtQixRQUFRO0FBQzNCLHFCQUFxQixxQkFBcUI7QUFDMUMsb0JBQW9CLE9BQU87QUFDM0Isb0JBQW9CLDhCQUE4QjtBQUNsRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQiw2QkFBNkI7QUFDaEQscUJBQXFCLHFCQUFxQjtBQUMxQyxvQkFBb0IsT0FBTztBQUMzQixvQkFBb0IsOEJBQThCO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLG1CQUFtQjtBQUN0QyxxQkFBcUIsYUFBYTtBQUNsQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsbUJBQW1CO0FBQ3RDLHFCQUFxQixxQkFBcUI7QUFDMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixxQkFBcUI7QUFDeEMsbUJBQW1CLDhCQUE4QjtBQUNqRCxxQkFBcUIsbUJBQW1CO0FBQ3hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCLG1CQUFtQjtBQUN4QztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEtBQUs7O0FBRUw7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0IscUJBQXFCO0FBQzNDLHNCQUFzQixxQkFBcUI7QUFDM0Msc0JBQXNCLGFBQWE7QUFDbkMsc0JBQXNCLGFBQWE7QUFDbkMsc0JBQXNCLGFBQWE7QUFDbkMsc0JBQXNCLG1DQUFtQztBQUN6RCxzQkFBc0IsYUFBYTtBQUNuQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsa0JBQWtCO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdFQUFnRSxpQkFBaUI7QUFDakY7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQkFBb0IsZ0JBQWdCO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQkFBb0IsZ0JBQWdCO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQkFBb0IsUUFBUTtBQUM1QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esb0JBQW9CLFFBQVE7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9CQUFvQixRQUFRO0FBQzVCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQkFBb0IsOEJBQThCO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQkFBb0IsUUFBUTtBQUM1QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLGtCQUFrQjtBQUNyQyxxQkFBcUIsZ0JBQWdCO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EseUVBQXlFLG9DQUFvQztBQUM3RztBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsaUJBQWlCO0FBQ3BDLG1CQUFtQixrQkFBa0I7QUFDckMscUJBQXFCLGtCQUFrQjtBQUN2QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLDBCQUEwQjtBQUMxRDtBQUNBO0FBQ0EsZ0NBQWdDLDJCQUEyQjtBQUMzRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MsOEJBQThCO0FBQzlEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsMkZBQTJGLG9DQUFvQztBQUMvSDtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsaUJBQWlCO0FBQ3BDLG1CQUFtQixrQkFBa0I7QUFDckMscUJBQXFCLGtCQUFrQjtBQUN2QztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLDZCQUE2QjtBQUNoRCxtQkFBbUIsUUFBUTtBQUMzQixxQkFBcUIsZ0JBQWdCO0FBQ3JDLG9CQUFvQixPQUFPO0FBQzNCLG9CQUFvQiw4QkFBOEI7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsNkJBQTZCO0FBQ2hELHFCQUFxQixnQkFBZ0I7QUFDckMsb0JBQW9CLE9BQU87QUFDM0Isb0JBQW9CLDhCQUE4QjtBQUNsRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixtQkFBbUI7QUFDdEMscUJBQXFCLGFBQWE7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MsMEJBQTBCO0FBQzFEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQywyQkFBMkI7QUFDM0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLDhCQUE4QjtBQUM5RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLG1CQUFtQjtBQUN0QyxxQkFBcUIsZ0JBQWdCO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyx5QkFBeUI7QUFDekQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLDBCQUEwQjtBQUMxRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MsNkJBQTZCO0FBQzdEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLGdCQUFnQjtBQUNuQyxtQkFBbUIsOEJBQThCO0FBQ2pELHFCQUFxQixtQkFBbUI7QUFDeEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLDBCQUEwQjtBQUMxRDtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQywyQkFBMkI7QUFDM0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyw4QkFBOEI7QUFDOUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCLG1CQUFtQjtBQUN4QztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEtBQUs7O0FBRUw7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0Isa0JBQWtCO0FBQ3hDLHNCQUFzQix1Q0FBdUM7QUFDN0Qsc0JBQXNCLGFBQWE7QUFDbkMsc0JBQXNCLGFBQWE7QUFDbkMsc0JBQXNCLGFBQWE7QUFDbkMsc0JBQXNCLGtCQUFrQjtBQUN4QyxzQkFBc0IsYUFBYTtBQUNuQyxzQkFBc0IsdUJBQXVCO0FBQzdDLHNCQUFzQiwyQ0FBMkM7QUFDakU7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLG1CQUFtQjtBQUN0QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0VBQWdFLGlCQUFpQjtBQUNqRjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9CQUFvQixhQUFhO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQkFBb0Isa0NBQWtDO0FBQ3REO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQkFBb0IsUUFBUTtBQUM1QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esb0JBQW9CLFFBQVE7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9CQUFvQixRQUFRO0FBQzVCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQkFBb0IsYUFBYTtBQUNqQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esb0JBQW9CLFFBQVE7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9CQUFvQixpQ0FBaUM7QUFDckQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9CQUFvQixzQ0FBc0M7QUFDMUQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixtQkFBbUI7QUFDdEMscUJBQXFCLGlCQUFpQjtBQUN0QztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDBFQUEwRSxxQ0FBcUM7QUFDL0c7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLGtCQUFrQjtBQUNyQyxtQkFBbUIsa0JBQWtCO0FBQ3JDLHFCQUFxQixrQkFBa0I7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MsZ0NBQWdDO0FBQ2hFO0FBQ0E7QUFDQSxnQ0FBZ0Msa0NBQWtDO0FBQ2xFO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDRGQUE0RixxQ0FBcUM7QUFDakk7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLGtCQUFrQjtBQUNyQyxtQkFBbUIsa0JBQWtCO0FBQ3JDLHFCQUFxQixrQkFBa0I7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQiw2QkFBNkI7QUFDaEQsbUJBQW1CLFFBQVE7QUFDM0IscUJBQXFCLGlCQUFpQjtBQUN0QyxvQkFBb0IsT0FBTztBQUMzQixvQkFBb0IsOEJBQThCO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsNkJBQTZCO0FBQ2hELHFCQUFxQixpQkFBaUI7QUFDdEMsb0JBQW9CLE9BQU87QUFDM0Isb0JBQW9CLDhCQUE4QjtBQUNsRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixtQkFBbUI7QUFDdEMscUJBQXFCLGFBQWE7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MsZ0NBQWdDO0FBQ2hFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLGtDQUFrQztBQUNsRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLG1CQUFtQjtBQUN0QyxxQkFBcUIsaUJBQWlCO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQywrQkFBK0I7QUFDL0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MsaUNBQWlDO0FBQ2pFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsaUJBQWlCO0FBQ3BDLG1CQUFtQiw4QkFBOEI7QUFDakQscUJBQXFCLG1CQUFtQjtBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQjtBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQjtBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLGdDQUFnQztBQUNoRTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyxrQ0FBa0M7QUFDbEU7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQixtQkFBbUI7QUFDeEM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLOztBQUVMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCLGFBQWE7QUFDbkMsc0JBQXNCLGFBQWE7QUFDbkM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLCtCQUErQjtBQUNsRDtBQUNBO0FBQ0E7QUFDQSxnRUFBZ0UsaUJBQWlCO0FBQ2pGO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esb0JBQW9CLFFBQVE7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9CQUFvQixRQUFRO0FBQzVCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsK0JBQStCO0FBQ2xELHFCQUFxQiw2QkFBNkI7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxzRkFBc0YsaURBQWlEO0FBQ3ZJO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQiw4QkFBOEI7QUFDakQsbUJBQW1CLGtCQUFrQjtBQUNyQyxxQkFBcUIsa0JBQWtCO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0Esd0dBQXdHLGlEQUFpRDtBQUN6SjtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsOEJBQThCO0FBQ2pELG1CQUFtQixrQkFBa0I7QUFDckMscUJBQXFCLGtCQUFrQjtBQUN2QztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLDZCQUE2QjtBQUNoRCxtQkFBbUIsUUFBUTtBQUMzQixxQkFBcUIsNkJBQTZCO0FBQ2xELG9CQUFvQixPQUFPO0FBQzNCLG9CQUFvQiw4QkFBOEI7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsNkJBQTZCO0FBQ2hELHFCQUFxQiw2QkFBNkI7QUFDbEQsb0JBQW9CLE9BQU87QUFDM0Isb0JBQW9CLDhCQUE4QjtBQUNsRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixtQkFBbUI7QUFDdEMscUJBQXFCLGFBQWE7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsbUJBQW1CO0FBQ3RDLHFCQUFxQiw2QkFBNkI7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLDZCQUE2QjtBQUNoRCxtQkFBbUIsOEJBQThCO0FBQ2pELHFCQUFxQixtQkFBbUI7QUFDeEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUIsbUJBQW1CO0FBQ3hDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsS0FBSzs7QUFFTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNCQUFzQixhQUFhO0FBQ25DLHNCQUFzQiwyQ0FBMkM7QUFDakU7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLHlCQUF5QjtBQUM1QztBQUNBO0FBQ0E7QUFDQTtBQUNBLGdFQUFnRSxpQkFBaUI7QUFDakY7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQkFBb0IsUUFBUTtBQUM1QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esb0JBQW9CLHNDQUFzQztBQUMxRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLHlCQUF5QjtBQUM1QyxxQkFBcUIsdUJBQXVCO0FBQzVDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsZ0ZBQWdGLDJDQUEyQztBQUMzSDtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsd0JBQXdCO0FBQzNDLG1CQUFtQixrQkFBa0I7QUFDckMscUJBQXFCLGtCQUFrQjtBQUN2QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyw4Q0FBOEM7QUFDOUU7QUFDQTtBQUNBOztBQUVBO0FBQ0Esa0dBQWtHLDJDQUEyQztBQUM3STtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsd0JBQXdCO0FBQzNDLG1CQUFtQixrQkFBa0I7QUFDckMscUJBQXFCLGtCQUFrQjtBQUN2QztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLDZCQUE2QjtBQUNoRCxtQkFBbUIsUUFBUTtBQUMzQixxQkFBcUIsdUJBQXVCO0FBQzVDLG9CQUFvQixPQUFPO0FBQzNCLG9CQUFvQiw4QkFBOEI7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLDZCQUE2QjtBQUNoRCxxQkFBcUIsdUJBQXVCO0FBQzVDLG9CQUFvQixPQUFPO0FBQzNCLG9CQUFvQiw4QkFBOEI7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsbUJBQW1CO0FBQ3RDLHFCQUFxQixhQUFhO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLDhDQUE4QztBQUM5RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLG1CQUFtQjtBQUN0QyxxQkFBcUIsdUJBQXVCO0FBQzVDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MsNkNBQTZDO0FBQzdFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsdUJBQXVCO0FBQzFDLG1CQUFtQiw4QkFBOEI7QUFDakQscUJBQXFCLG1CQUFtQjtBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyw4Q0FBOEM7QUFDOUU7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQixtQkFBbUI7QUFDeEM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLOztBQUVMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCLDhCQUE4QjtBQUNwRCxzQkFBc0IsYUFBYTtBQUNuQyxzQkFBc0IsZ0NBQWdDO0FBQ3RELHNCQUFzQixhQUFhO0FBQ25DLHNCQUFzQixtQ0FBbUM7QUFDekQsc0JBQXNCLG1DQUFtQztBQUN6RCxzQkFBc0IsbUNBQW1DO0FBQ3pELHNCQUFzQixxQ0FBcUM7QUFDM0Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLG1CQUFtQjtBQUN0QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnRUFBZ0UsaUJBQWlCO0FBQ2pGO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esb0JBQW9CLHlCQUF5QjtBQUM3QztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esb0JBQW9CLFFBQVE7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9CQUFvQiwyQkFBMkI7QUFDL0M7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9CQUFvQixRQUFRO0FBQzVCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQkFBb0IsOEJBQThCO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQkFBb0IsOEJBQThCO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQkFBb0IsOEJBQThCO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQkFBb0IsZ0NBQWdDO0FBQ3BEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsbUJBQW1CO0FBQ3RDLHFCQUFxQixpQkFBaUI7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwwRUFBMEUscUNBQXFDO0FBQy9HO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixrQkFBa0I7QUFDckMsbUJBQW1CLGtCQUFrQjtBQUNyQyxxQkFBcUIsa0JBQWtCO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MseUJBQXlCO0FBQ3pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLGdDQUFnQztBQUNoRTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQywwQkFBMEI7QUFDMUQ7QUFDQTtBQUNBLGdDQUFnQywyQkFBMkI7QUFDM0Q7QUFDQTtBQUNBLGdDQUFnQyw4QkFBOEI7QUFDOUQ7QUFDQTtBQUNBLGdDQUFnQywyQ0FBMkM7QUFDM0U7QUFDQTtBQUNBOztBQUVBO0FBQ0EsNEZBQTRGLHFDQUFxQztBQUNqSTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsa0JBQWtCO0FBQ3JDLG1CQUFtQixrQkFBa0I7QUFDckMscUJBQXFCLGtCQUFrQjtBQUN2QztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLDZCQUE2QjtBQUNoRCxtQkFBbUIsUUFBUTtBQUMzQixxQkFBcUIsaUJBQWlCO0FBQ3RDLG9CQUFvQixPQUFPO0FBQzNCLG9CQUFvQiw4QkFBOEI7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsNkJBQTZCO0FBQ2hELHFCQUFxQixpQkFBaUI7QUFDdEMsb0JBQW9CLE9BQU87QUFDM0Isb0JBQW9CLDhCQUE4QjtBQUNsRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixtQkFBbUI7QUFDdEMscUJBQXFCLGFBQWE7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MseUJBQXlCO0FBQ3pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MsZ0NBQWdDO0FBQ2hFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MsMEJBQTBCO0FBQzFEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MsMkJBQTJCO0FBQzNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MsOEJBQThCO0FBQzlEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MsMkNBQTJDO0FBQzNFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsbUJBQW1CO0FBQ3RDLHFCQUFxQixpQkFBaUI7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLHdCQUF3QjtBQUN4RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLCtCQUErQjtBQUMvRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLHlCQUF5QjtBQUN6RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MsMEJBQTBCO0FBQzFEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyw2QkFBNkI7QUFDN0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLDBDQUEwQztBQUMxRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLGlCQUFpQjtBQUNwQyxtQkFBbUIsOEJBQThCO0FBQ2pELHFCQUFxQixtQkFBbUI7QUFDeEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MseUJBQXlCO0FBQ3pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyxnQ0FBZ0M7QUFDaEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLDBCQUEwQjtBQUMxRDtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQywyQkFBMkI7QUFDM0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MsOEJBQThCO0FBQzlEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLDJDQUEyQztBQUMzRTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCLG1CQUFtQjtBQUN4QztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEtBQUs7O0FBRUw7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0IsMEJBQTBCO0FBQ2hELHNCQUFzQixhQUFhO0FBQ25DLHNCQUFzQixnQ0FBZ0M7QUFDdEQsc0JBQXNCLHFCQUFxQjtBQUMzQyxzQkFBc0IscUJBQXFCO0FBQzNDLHNCQUFzQix5QkFBeUI7QUFDL0Msc0JBQXNCLDBCQUEwQjtBQUNoRCxzQkFBc0IsYUFBYTtBQUNuQyxzQkFBc0IsYUFBYTtBQUNuQyxzQkFBc0IsaUJBQWlCO0FBQ3ZDLHNCQUFzQiwyQ0FBMkM7QUFDakUsc0JBQXNCLG9DQUFvQztBQUMxRCxzQkFBc0IscUJBQXFCO0FBQzNDLHNCQUFzQiwwQkFBMEI7QUFDaEQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLG9CQUFvQjtBQUN2QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0VBQWdFLGlCQUFpQjtBQUNqRjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9CQUFvQixxQkFBcUI7QUFDekM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9CQUFvQixRQUFRO0FBQzVCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQkFBb0IsMENBQTBDO0FBQzlEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQkFBb0IsZ0JBQWdCO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQkFBb0IsZ0JBQWdCO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQkFBb0Isb0JBQW9CO0FBQ3hDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQkFBb0IscUJBQXFCO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQkFBb0IsUUFBUTtBQUM1QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esb0JBQW9CLFFBQVE7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9CQUFvQixZQUFZO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQkFBb0Isc0NBQXNDO0FBQzFEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQkFBb0IsK0JBQStCO0FBQ25EO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQkFBb0IsZ0JBQWdCO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQkFBb0IscUJBQXFCO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsb0JBQW9CO0FBQ3ZDLHFCQUFxQixrQkFBa0I7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwyRUFBMkUsc0NBQXNDO0FBQ2pIO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixtQkFBbUI7QUFDdEMsbUJBQW1CLGtCQUFrQjtBQUNyQyxxQkFBcUIsa0JBQWtCO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyx5QkFBeUI7QUFDekQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLDhCQUE4QjtBQUM5RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLDhCQUE4QjtBQUM5RDtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQywrQkFBK0I7QUFDL0Q7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLDhCQUE4QjtBQUM5RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MsK0JBQStCO0FBQy9EO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MsK0JBQStCO0FBQy9EO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyxpQ0FBaUM7QUFDakU7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDZGQUE2RixzQ0FBc0M7QUFDbkk7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLG1CQUFtQjtBQUN0QyxtQkFBbUIsa0JBQWtCO0FBQ3JDLHFCQUFxQixrQkFBa0I7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQiw2QkFBNkI7QUFDaEQsbUJBQW1CLFFBQVE7QUFDM0IscUJBQXFCLGtCQUFrQjtBQUN2QyxvQkFBb0IsT0FBTztBQUMzQixvQkFBb0IsOEJBQThCO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNCQUFzQjtBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0I7QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0I7QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNCQUFzQjtBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0I7QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsNkJBQTZCO0FBQ2hELHFCQUFxQixrQkFBa0I7QUFDdkMsb0JBQW9CLE9BQU87QUFDM0Isb0JBQW9CLDhCQUE4QjtBQUNsRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixtQkFBbUI7QUFDdEMscUJBQXFCLGFBQWE7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MseUJBQXlCO0FBQ3pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MsOEJBQThCO0FBQzlEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyw4QkFBOEI7QUFDOUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLCtCQUErQjtBQUMvRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MsOEJBQThCO0FBQzlEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyxpQ0FBaUM7QUFDakU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MsK0JBQStCO0FBQy9EO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQywrQkFBK0I7QUFDL0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLG1CQUFtQjtBQUN0QyxxQkFBcUIsa0JBQWtCO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyx3QkFBd0I7QUFDeEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyw2QkFBNkI7QUFDN0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLDZCQUE2QjtBQUM3RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MsOEJBQThCO0FBQzlEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyw2QkFBNkI7QUFDN0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MsZ0NBQWdDO0FBQ2hFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLDhCQUE4QjtBQUM5RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MsOEJBQThCO0FBQzlEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixrQkFBa0I7QUFDckMsbUJBQW1CLDhCQUE4QjtBQUNqRCxxQkFBcUIsbUJBQW1CO0FBQ3hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLHlCQUF5QjtBQUN6RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLDhCQUE4QjtBQUM5RDtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyw4QkFBOEI7QUFDOUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MsK0JBQStCO0FBQy9EO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLDhCQUE4QjtBQUM5RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLCtCQUErQjtBQUMvRDtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQywrQkFBK0I7QUFDL0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLGlDQUFpQztBQUNqRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQixtQkFBbUI7QUFDeEM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCO0FBQ2xCLHNCQUFzQixRQUFRO0FBQzlCLHNCQUFzQixRQUFRO0FBQzlCLHNCQUFzQixRQUFRO0FBQzlCLHNCQUFzQixRQUFRO0FBQzlCLHNCQUFzQixRQUFRO0FBQzlCLHNCQUFzQixRQUFRO0FBQzlCLHNCQUFzQixRQUFRO0FBQzlCLHNCQUFzQixRQUFRO0FBQzlCLHNCQUFzQixRQUFRO0FBQzlCLHNCQUFzQixRQUFRO0FBQzlCLHNCQUFzQixRQUFRO0FBQzlCLHNCQUFzQixRQUFRO0FBQzlCLHNCQUFzQixRQUFRO0FBQzlCLHNCQUFzQixRQUFRO0FBQzlCLHNCQUFzQixRQUFRO0FBQzlCLHNCQUFzQixRQUFRO0FBQzlCLHNCQUFzQixRQUFRO0FBQzlCO0FBQ0E7QUFDQSwrQkFBK0I7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUzs7QUFFVDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBCQUEwQixrQkFBa0I7QUFDNUMsMEJBQTBCLGtCQUFrQjtBQUM1Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUIsNEJBQTRCO0FBQ25EO0FBQ0E7QUFDQTtBQUNBLG9FQUFvRSxpQkFBaUI7QUFDckY7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSx3QkFBd0IsYUFBYTtBQUNyQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esd0JBQXdCLGFBQWE7QUFDckM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1Qiw0QkFBNEI7QUFDbkQseUJBQXlCLDBCQUEwQjtBQUNuRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDJFQUEyRSw4Q0FBOEM7QUFDekg7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCLDJCQUEyQjtBQUNsRCx1QkFBdUIsa0JBQWtCO0FBQ3pDLHlCQUF5QixrQkFBa0I7QUFDM0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw2RkFBNkYsOENBQThDO0FBQzNJO0FBQ0E7QUFDQTtBQUNBLHVCQUF1QiwyQkFBMkI7QUFDbEQsdUJBQXVCLGtCQUFrQjtBQUN6Qyx5QkFBeUIsa0JBQWtCO0FBQzNDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUIsNkJBQTZCO0FBQ3BELHVCQUF1QixRQUFRO0FBQy9CLHlCQUF5QiwwQkFBMEI7QUFDbkQsd0JBQXdCLE9BQU87QUFDL0Isd0JBQXdCLDhCQUE4QjtBQUN0RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1Qiw2QkFBNkI7QUFDcEQseUJBQXlCLDBCQUEwQjtBQUNuRCx3QkFBd0IsT0FBTztBQUMvQix3QkFBd0IsOEJBQThCO0FBQ3REO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCLG1CQUFtQjtBQUMxQyx5QkFBeUIsYUFBYTtBQUN0QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1QixtQkFBbUI7QUFDMUMseUJBQXlCLDBCQUEwQjtBQUNuRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCLDBCQUEwQjtBQUNqRCx1QkFBdUIsOEJBQThCO0FBQ3JELHlCQUF5QixtQkFBbUI7QUFDNUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QixtQkFBbUI7QUFDNUM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxTQUFTOztBQUVUO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQjtBQUNsQixzQkFBc0IsUUFBUTtBQUM5QixzQkFBc0IsUUFBUTtBQUM5QjtBQUNBO0FBQ0EsK0JBQStCO0FBQy9CO0FBQ0E7QUFDQTtBQUNBLFNBQVM7O0FBRVQ7QUFDQSxLQUFLOztBQUVMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCLCtDQUErQztBQUNyRTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIseUJBQXlCO0FBQzVDO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0VBQWdFLGlCQUFpQjtBQUNqRjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9CQUFvQiwwQ0FBMEM7QUFDOUQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQix5QkFBeUI7QUFDNUMscUJBQXFCLHVCQUF1QjtBQUM1QztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGdGQUFnRiwyQ0FBMkM7QUFDM0g7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLHdCQUF3QjtBQUMzQyxtQkFBbUIsa0JBQWtCO0FBQ3JDLHFCQUFxQixrQkFBa0I7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyx3QkFBd0I7QUFDeEQ7QUFDQTtBQUNBOztBQUVBO0FBQ0Esa0dBQWtHLDJDQUEyQztBQUM3STtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsd0JBQXdCO0FBQzNDLG1CQUFtQixrQkFBa0I7QUFDckMscUJBQXFCLGtCQUFrQjtBQUN2QztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLDZCQUE2QjtBQUNoRCxtQkFBbUIsUUFBUTtBQUMzQixxQkFBcUIsdUJBQXVCO0FBQzVDLG9CQUFvQixPQUFPO0FBQzNCLG9CQUFvQiw4QkFBOEI7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLDZCQUE2QjtBQUNoRCxxQkFBcUIsdUJBQXVCO0FBQzVDLG9CQUFvQixPQUFPO0FBQzNCLG9CQUFvQiw4QkFBOEI7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsbUJBQW1CO0FBQ3RDLHFCQUFxQixhQUFhO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLHdCQUF3QjtBQUN4RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLG1CQUFtQjtBQUN0QyxxQkFBcUIsdUJBQXVCO0FBQzVDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyx1QkFBdUI7QUFDdkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQix1QkFBdUI7QUFDMUMsbUJBQW1CLDhCQUE4QjtBQUNqRCxxQkFBcUIsbUJBQW1CO0FBQ3hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyx3QkFBd0I7QUFDeEQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQixtQkFBbUI7QUFDeEM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQkFBMEIsa0JBQWtCO0FBQzVDLDBCQUEwQixhQUFhO0FBQ3ZDLDBCQUEwQixhQUFhO0FBQ3ZDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1QixtQ0FBbUM7QUFDMUQ7QUFDQTtBQUNBO0FBQ0Esb0VBQW9FLGlCQUFpQjtBQUNyRjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHdCQUF3QixhQUFhO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSx3QkFBd0IsUUFBUTtBQUNoQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esd0JBQXdCLFFBQVE7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esd0JBQXdCLGlDQUFpQztBQUN6RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhOztBQUViO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUIsbUNBQW1DO0FBQzFELHlCQUF5QixpQ0FBaUM7QUFDMUQ7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw2RUFBNkUscURBQXFEO0FBQ2xJO0FBQ0E7QUFDQTtBQUNBLHVCQUF1QixrQ0FBa0M7QUFDekQsdUJBQXVCLGtCQUFrQjtBQUN6Qyx5QkFBeUIsa0JBQWtCO0FBQzNDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLCtGQUErRixxREFBcUQ7QUFDcEo7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCLGtDQUFrQztBQUN6RCx1QkFBdUIsa0JBQWtCO0FBQ3pDLHlCQUF5QixrQkFBa0I7QUFDM0M7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1Qiw2QkFBNkI7QUFDcEQsdUJBQXVCLFFBQVE7QUFDL0IseUJBQXlCLGlDQUFpQztBQUMxRCx3QkFBd0IsT0FBTztBQUMvQix3QkFBd0IsOEJBQThCO0FBQ3REO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCLDZCQUE2QjtBQUNwRCx5QkFBeUIsaUNBQWlDO0FBQzFELHdCQUF3QixPQUFPO0FBQy9CLHdCQUF3Qiw4QkFBOEI7QUFDdEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUIsbUJBQW1CO0FBQzFDLHlCQUF5QixhQUFhO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUIsbUJBQW1CO0FBQzFDLHlCQUF5QixpQ0FBaUM7QUFDMUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCLGlDQUFpQztBQUN4RCx1QkFBdUIsOEJBQThCO0FBQ3JELHlCQUF5QixtQkFBbUI7QUFDNUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUIsbUJBQW1CO0FBQzVDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsU0FBUzs7QUFFVDtBQUNBLEtBQUs7O0FBRUw7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0IsNkJBQTZCO0FBQ25ELHNCQUFzQixhQUFhO0FBQ25DOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixrQkFBa0I7QUFDckM7QUFDQTtBQUNBO0FBQ0EsZ0VBQWdFLGlCQUFpQjtBQUNqRjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9CQUFvQix1Q0FBdUM7QUFDM0Q7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9CQUFvQixRQUFRO0FBQzVCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9CQUFvQix3QkFBd0I7QUFDNUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUzs7QUFFVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLGtCQUFrQjtBQUNyQyxxQkFBcUIsZ0JBQWdCO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EseUVBQXlFLG9DQUFvQztBQUM3RztBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsaUJBQWlCO0FBQ3BDLG1CQUFtQixrQkFBa0I7QUFDckMscUJBQXFCLGtCQUFrQjtBQUN2QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDJGQUEyRixvQ0FBb0M7QUFDL0g7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLGlCQUFpQjtBQUNwQyxtQkFBbUIsa0JBQWtCO0FBQ3JDLHFCQUFxQixrQkFBa0I7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQiw2QkFBNkI7QUFDaEQsbUJBQW1CLFFBQVE7QUFDM0IscUJBQXFCLGdCQUFnQjtBQUNyQyxvQkFBb0IsT0FBTztBQUMzQixvQkFBb0IsOEJBQThCO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLDZCQUE2QjtBQUNoRCxxQkFBcUIsZ0JBQWdCO0FBQ3JDLG9CQUFvQixPQUFPO0FBQzNCLG9CQUFvQiw4QkFBOEI7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsbUJBQW1CO0FBQ3RDLHFCQUFxQixhQUFhO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLG1CQUFtQjtBQUN0QyxxQkFBcUIsZ0JBQWdCO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixnQkFBZ0I7QUFDbkMsbUJBQW1CLDhCQUE4QjtBQUNqRCxxQkFBcUIsbUJBQW1CO0FBQ3hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUIsbUJBQW1CO0FBQ3hDO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEJBQTBCLGFBQWE7QUFDdkMsMEJBQTBCLDZCQUE2QjtBQUN2RDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUIseUJBQXlCO0FBQ2hEO0FBQ0E7QUFDQTtBQUNBLG9FQUFvRSxpQkFBaUI7QUFDckY7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSx3QkFBd0IsUUFBUTtBQUNoQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esd0JBQXdCLHVDQUF1QztBQUMvRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCLHlCQUF5QjtBQUNoRCx5QkFBeUIsdUJBQXVCO0FBQ2hEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsMEVBQTBFLDJDQUEyQztBQUNySDtBQUNBO0FBQ0E7QUFDQSx1QkFBdUIsd0JBQXdCO0FBQy9DLHVCQUF1QixrQkFBa0I7QUFDekMseUJBQXlCLGtCQUFrQjtBQUMzQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDRGQUE0RiwyQ0FBMkM7QUFDdkk7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCLHdCQUF3QjtBQUMvQyx1QkFBdUIsa0JBQWtCO0FBQ3pDLHlCQUF5QixrQkFBa0I7QUFDM0M7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1Qiw2QkFBNkI7QUFDcEQsdUJBQXVCLFFBQVE7QUFDL0IseUJBQXlCLHVCQUF1QjtBQUNoRCx3QkFBd0IsT0FBTztBQUMvQix3QkFBd0IsOEJBQThCO0FBQ3REO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCLDZCQUE2QjtBQUNwRCx5QkFBeUIsdUJBQXVCO0FBQ2hELHdCQUF3QixPQUFPO0FBQy9CLHdCQUF3Qiw4QkFBOEI7QUFDdEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUIsbUJBQW1CO0FBQzFDLHlCQUF5QixhQUFhO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1QixtQkFBbUI7QUFDMUMseUJBQXlCLHVCQUF1QjtBQUNoRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUIsdUJBQXVCO0FBQzlDLHVCQUF1Qiw4QkFBOEI7QUFDckQseUJBQXlCLG1CQUFtQjtBQUM1QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QixtQkFBbUI7QUFDNUM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxTQUFTOztBQUVUO0FBQ0EsS0FBSzs7QUFFTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNCQUFzQixhQUFhO0FBQ25DLHNCQUFzQixrQkFBa0I7QUFDeEM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLDJCQUEyQjtBQUM5QztBQUNBO0FBQ0E7QUFDQSxnRUFBZ0UsaUJBQWlCO0FBQ2pGO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esb0JBQW9CLFFBQVE7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9CQUFvQixhQUFhO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsMkJBQTJCO0FBQzlDLHFCQUFxQix5QkFBeUI7QUFDOUM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxrRkFBa0YsNkNBQTZDO0FBQy9IO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQiwwQkFBMEI7QUFDN0MsbUJBQW1CLGtCQUFrQjtBQUNyQyxxQkFBcUIsa0JBQWtCO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0Esb0dBQW9HLDZDQUE2QztBQUNqSjtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsMEJBQTBCO0FBQzdDLG1CQUFtQixrQkFBa0I7QUFDckMscUJBQXFCLGtCQUFrQjtBQUN2QztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLDZCQUE2QjtBQUNoRCxtQkFBbUIsUUFBUTtBQUMzQixxQkFBcUIseUJBQXlCO0FBQzlDLG9CQUFvQixPQUFPO0FBQzNCLG9CQUFvQiw4QkFBOEI7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsNkJBQTZCO0FBQ2hELHFCQUFxQix5QkFBeUI7QUFDOUMsb0JBQW9CLE9BQU87QUFDM0Isb0JBQW9CLDhCQUE4QjtBQUNsRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixtQkFBbUI7QUFDdEMscUJBQXFCLGFBQWE7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsbUJBQW1CO0FBQ3RDLHFCQUFxQix5QkFBeUI7QUFDOUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIseUJBQXlCO0FBQzVDLG1CQUFtQiw4QkFBOEI7QUFDakQscUJBQXFCLG1CQUFtQjtBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQjtBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUIsbUJBQW1CO0FBQ3hDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBLENBQUM7O0FBRUQ7Ozs7Ozs7Ozs7OztBQ3Z4SkE7O0FBRWE7QUFDYixpSEFBK0M7Ozs7Ozs7Ozs7OztBQ0hsQztBQUNiOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7O0FBRUE7QUFDQSx3QkFBd0IsbUJBQU8sQ0FBQyx5REFBVTtBQUMxQyx3QkFBd0IsbUJBQU8sQ0FBQyx1RUFBaUI7QUFDakQsd0JBQXdCLG1CQUFPLENBQUMseURBQVU7QUFDMUMsd0JBQXdCLG1CQUFPLENBQUMsdUVBQWlCOztBQUVqRDtBQUNBLHdCQUF3QixtQkFBTyxDQUFDLHFFQUFnQjtBQUNoRCx3QkFBd0IsbUJBQU8sQ0FBQyxtREFBTztBQUN2Qyx3QkFBd0IsbUJBQU8sQ0FBQyx1REFBUztBQUN6Qzs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7Ozs7Ozs7Ozs7OztBQ25DYTtBQUNiOztBQUVBLGdCQUFnQixtQkFBTyxDQUFDLHFFQUFnQjs7QUFFeEMsa0JBQWtCOztBQUVsQjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxZQUFZO0FBQ3ZCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBOztBQUVBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLG1CQUFtQjtBQUM5QixhQUFhLHFCQUFxQixHQUFHLG9CQUFvQixzQ0FBc0M7QUFDL0YsWUFBWSxPQUFPO0FBQ25CO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsYUFBYSxRQUFRO0FBQ3JCO0FBQ0E7QUFDQSw0QkFBNEI7QUFDNUI7QUFDQSxrRUFBa0U7QUFDbEUsa0VBQWtFO0FBQ2xFLGtFQUFrRTtBQUNsRSxrRUFBa0U7QUFDbEUsa0VBQWtFOztBQUVsRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBLGFBQWEsUUFBUTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsYUFBYSxRQUFRO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUM7QUFDbkMsZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ04sZUFBZSxPQUFPO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQztBQUNuQyxlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTixlQUFlLE9BQU87QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSxNQUFNO0FBQ25COztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSxNQUFNO0FBQ25COztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSxNQUFNO0FBQ25COztBQUVBO0FBQ0E7QUFDQSxhQUFhLFNBQVM7QUFDdEI7QUFDQTtBQUNBO0FBQ0E7O0FBRUEscUNBQXFDO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGFBQWEsUUFBUTtBQUNyQjtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxhQUFhLFFBQVE7QUFDckI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWEsTUFBTTtBQUNuQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWEsTUFBTTtBQUNuQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxhQUFhLFFBQVE7QUFDckI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsYUFBYSxRQUFRO0FBQ3JCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxhQUFhLFlBQVk7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGFBQWEsUUFBUTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxXQUFXLFFBQVE7QUFDbkIsYUFBYSxRQUFRO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsV0FBVyxRQUFRO0FBQ25CLGFBQWEsUUFBUTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNB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RCxTQUFnQixPQUFPO0lBQ3JCLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQztJQUNwQixNQUFNLElBQUksR0FBRztVQUNMLElBQUk7OztTQUdMLElBQUk7OztHQUdWLENBQUM7SUFDRixPQUFPLEVBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsK0JBQVksQ0FBQyxVQUFVLEVBQUMsQ0FBQztBQUNyRCxDQUFDO0FBWEQsMEJBV0M7QUFDRCxTQUFnQixPQUFPO0lBQ3JCLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQztJQUNwQixNQUFNLElBQUksR0FBRztVQUNMLElBQUk7OztTQUdMLElBQUk7OztHQUdWLENBQUM7SUFDRixPQUFPLEVBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsK0JBQVksQ0FBQyxVQUFVLEVBQUMsQ0FBQztBQUNyRCxDQUFDO0FBWEQsMEJBV0M7QUFDRCxTQUFnQixPQUFPO0lBQ3JCLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQztJQUNwQixNQUFNLElBQUksR0FBRztVQUNMLElBQUk7OztTQUdMLElBQUk7OztHQUdWLENBQUM7SUFDRixPQUFPLEVBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsK0JBQVksQ0FBQyxVQUFVLEVBQUMsQ0FBQztBQUNyRCxDQUFDO0FBWEQsMEJBV0M7QUFDRCxTQUFnQixTQUFTO0lBQ3ZCLE1BQU0sSUFBSSxHQUFHLFFBQVEsQ0FBQztJQUN0QixNQUFNLElBQUksR0FBRztVQUNMLElBQUk7OztTQUdMLElBQUk7OztHQUdWLENBQUM7SUFDRixPQUFPLEVBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsK0JBQVksQ0FBQyxVQUFVLEVBQUMsQ0FBQztBQUNyRCxDQUFDO0FBWEQsOEJBV0M7QUFDRCxTQUFnQixXQUFXO0lBQ3pCLE1BQU0sSUFBSSxHQUFHLFVBQVUsQ0FBQztJQUN4QixNQUFNLElBQUksR0FBRztVQUNMLElBQUk7OztTQUdMLElBQUk7Ozs7OztHQU1WLENBQUM7SUFDRixPQUFPLEVBQUMsSUFB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O0FBQ25CO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsV0FBVyxrQkFBa0I7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxXQUFXLFFBQVE7QUFDbkI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxXQUFXLFFBQVE7QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsV0FBVyxRQUFRO0FBQ25CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFdBQVcsUUFBUTtBQUNuQjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxXQUFXLFFBQVE7QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsV0FBVyxrQkFBa0I7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsV0FBVyxRQUFRO0FBQ25CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFdBQVcsUUFBUTtBQUNuQjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxXQUFXLFFBQVE7QUFDbkIsV0FBVyxRQUFRO0FBQ25CLFdBQVcsUUFBUTtBQUNuQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFdBQVcsUUFBUTtBQUNuQixXQUFXLFFBQVE7QUFDbkIsV0FBVyxRQUFRO0FBQ25CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsV0FBVyxRQUFRO0FBQ25CLFdBQVcsUUFBUTtBQUNuQixXQUFXLFFBQVE7QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxXQUFXLFFBQVE7QUFDbkIsV0FBVyxrQkFBa0I7QUFDN0IsV0FBVyxrQkFBa0I7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxXQUFXLFFBQVE7QUFDbkIsV0FBVyxRQUFRO0FBQ25CLFdBQVcsUUFBUTtBQUNuQjtBQUNBO0FB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QUFDQSxXQUFXLFFBQVE7QUFDbkIsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsUUFBUTtBQUNuQixhQUFhO0FBQ2I7QUFDQTtBQUNBLG1FQUFtRTtBQUNuRTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLFFBQVE7QUFDbkIsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsV0FBVyxRQUFRO0FBQ25CLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0Isd0NBQXdDO0FBQzFEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLFFBQVE7QUFDbkIsV0FBVyxRQUFRO0FBQ25CLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUN1Qjs7QUFFdkI7QUFDQTs7Ozs7OztVQzF1Q0E7VUFDQTs7VUFFQTtVQUNBO1VBQ0E7VUFDQTtVQUNBO1VBQ0E7VUFDQTtVQUNBO1VBQ0E7VUFDQTtVQUNBO1VBQ0E7VUFDQTs7VUFFQTtVQUNBOztVQUVBO1VBQ0E7VUFDQTs7Ozs7V0N0QkE7V0FDQTtXQUNBO1dBQ0E7V0FDQTtXQUNBLGlDQUFpQyxXQUFXO1dBQzVDO1dBQ0E7Ozs7O1dDUEE7V0FDQTtXQUNBO1dBQ0E7V0FDQSx5Q0FBeUMsd0NBQXdDO1dBQ2pGO1dBQ0E7V0FDQTs7Ozs7V0NQQTtXQUNBO1dBQ0E7V0FDQTtXQUNBLEdBQUc7V0FDSDtXQUNBO1dBQ0EsQ0FBQzs7Ozs7V0NQRDs7Ozs7V0NBQTtXQUNBO1dBQ0E7V0FDQSx1REFBdUQsaUJBQWlCO1dBQ3hFO1dBQ0EsZ0RBQWdELGFBQWE7V0FDN0Q7Ozs7O1VFTkE7VUFDQTtVQUNBO1VBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvd2VicGFjay91bml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uIiwid2VicGFjazovL29ubnhydW50aW1lLXdlYi8uL2xpYi93YXNtL2JpbmRpbmcvb3J0LXdhc20tdGhyZWFkZWQuanMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbGliL3dhc20vYmluZGluZy9vcnQtd2FzbS5qcyIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvLi9ub2RlX21vZHVsZXMvQHByb3RvYnVmanMvYXNwcm9taXNlL2luZGV4LmpzIiwid2VicGFjazovL29ubnhydW50aW1lLXdlYi8uL25vZGVfbW9kdWxlcy9AcHJvdG9idWZqcy9iYXNlNjQvaW5kZXguanMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbm9kZV9tb2R1bGVzL0Bwcm90b2J1ZmpzL2V2ZW50ZW1pdHRlci9pbmRleC5qcyIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvLi9ub2RlX21vZHVsZXMvQHByb3RvYnVmanMvZmxvYXQvaW5kZXguanMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbm9kZV9tb2R1bGVzL0Bwcm90b2J1ZmpzL2lucXVpcmUvaW5kZXguanMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbm9kZV9tb2R1bGVzL0Bwcm90b2J1ZmpzL3Bvb2wvaW5kZXguanMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbm9kZV9tb2R1bGVzL0Bwcm90b2J1ZmpzL3V0ZjgvaW5kZXguanMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbm9kZV9tb2R1bGVzL2d1aWQtdHlwZXNjcmlwdC9kaXN0L2d1aWQuanMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbm9kZV9tb2R1bGVzL2xvbmcvc3JjL2xvbmcuanMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbm9kZV9tb2R1bGVzL29ubngtcHJvdG8vZGlzdC9vbm54LmpzIiwid2VicGFjazovL29ubnhydW50aW1lLXdlYi8uL25vZGVfbW9kdWxlcy9wcm90b2J1ZmpzL21pbmltYWwuanMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbm9kZV9tb2R1bGVzL3Byb3RvYnVmanMvc3JjL2luZGV4LW1pbmltYWwuanMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbm9kZV9tb2R1bGVzL3Byb3RvYnVmanMvc3JjL3JlYWRlci5qcyIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvLi9ub2RlX21vZHVsZXMvcHJvdG9idWZqcy9zcmMvcmVhZGVyX2J1ZmZlci5qcyIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvLi9ub2RlX21vZHVsZXMvcHJvdG9idWZqcy9zcmMvcm9vdHMuanMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbm9kZV9tb2R1bGVzL3Byb3RvYnVmanMvc3JjL3JwYy5qcyIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvLi9ub2RlX21vZHVsZXMvcHJvdG9idWZqcy9zcmMvcnBjL3NlcnZpY2UuanMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbm9kZV9tb2R1bGVzL3Byb3RvYnVmanMvc3JjL3V0aWwvbG9uZ2JpdHMuanMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbm9kZV9tb2R1bGVzL3Byb3RvYnVmanMvc3JjL3V0aWwvbWluaW1hbC5qcyIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvLi9ub2RlX21vZHVsZXMvcHJvdG9idWZqcy9zcmMvd3JpdGVyLmpzIiwid2VicGFjazovL29ubnhydW50aW1lLXdlYi8uL25vZGVfbW9kdWxlcy9wcm90b2J1ZmpzL3NyYy93cml0ZXJfYnVmZmVyLmpzIiwid2VicGFjazovL29ubnhydW50aW1lLXdlYi8uL2xpYi9iYWNrZW5kLW9ubnhqcy50cyIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvLi9saWIvYmFja2VuZC13YXNtLnRzIiwid2VicGFjazovL29ubnhydW50aW1lLXdlYi8uL2xpYi9pbmRleC50cyIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvLi9saWIvb25ueGpzL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleS50cyIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvLi9saWIvb25ueGpzL2F0dHJpYnV0ZS50cyIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvLi9saWIvb25ueGpzL2JhY2tlbmQudHMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbGliL29ubnhqcy9iYWNrZW5kcy9iYWNrZW5kLXdlYmdsLnRzIiwid2VicGFjazovL29ubnhydW50aW1lLXdlYi8uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvZ2xzbC1jb29yZGluYXRlLWxpYi50cyIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL2dsc2wtZGVmaW5pdGlvbnMudHMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9nbHNsLWVuY29kaW5nLWxpYi50cyIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL2dsc2wtZnJhZ2NvbG9yLWxpYi50cyIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL2dsc2wtZnVuY3Rpb24taW5saW5lci50cyIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL2dsc2wtcHJlcHJvY2Vzc29yLnRzIiwid2VicGFjazovL29ubnhydW50aW1lLXdlYi8uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvZ2xzbC1yZWdpc3RlcmVkLWxpYnMudHMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9nbHNsLXNoYXBlLXV0aWxzLWxpYi50cyIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL2dsc2wtc291cmNlLnRzIiwid2VicGFjazovL29ubnhydW50aW1lLXdlYi8uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvZ2xzbC12ZWMtbGliLnRzIiwid2VicGFjazovL29ubnhydW50aW1lLXdlYi8uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvaW5mZXJlbmNlLWhhbmRsZXIudHMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcC1yZXNvbHZlLXJ1bGVzLnRzIiwid2VicGFjazovL29ubnhydW50aW1lLXdlYi8uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2JhdGNoLW5vcm1hbGl6YXRpb24udHMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvYmluYXJ5LW9wLnRzIiwid2VicGFjazovL29ubnhydW50aW1lLXdlYi8uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2Nhc3QudHMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvY29uY2F0LXBhY2tlZC50cyIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9jb25jYXQudHMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvY29udi1ncm91cGVkLnRzIiwid2VicGFjazovL29ubnhydW50aW1lLXdlYi8uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2NvbnYtcGFjay50cyIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9jb252LXRyYW5zcG9zZS50cyIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9jb252LnRzIiwid2VicGFjazovL29ubnhydW50aW1lLXdlYi8uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2RlcHRoLXRvLXNwYWNlLnRzIiwid2VicGFjazovL29ubnhydW50aW1lLXdlYi8uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2RvdC1wcm9kdWN0LnRzIiwid2VicGFjazovL29ubnhydW50aW1lLXdlYi8uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2ZsYXR0ZW4udHMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvZnVzZS11dGlscy50cyIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9nYXRoZXIudHMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvZ2VtbS50cyIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9pbTJjb2wtcGFjay50cyIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9pbTJjb2wudHMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvaW1hZ2Utc2NhbGVyLnRzIiwid2VicGFjazovL29ubnhydW50aW1lLXdlYi8uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL2luc3RhbmNlLW5vcm1hbGl6YXRpb24udHMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvbWF0bXVsLXBhY2sudHMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvbWF0bXVsLnRzIiwid2VicGFjazovL29ubnhydW50aW1lLXdlYi8uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3BhY2sudHMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvcGFja2luZy11dGlscy50cyIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9wYWQudHMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvcG9vbC50cyIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9yZWR1Y2UudHMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvcmVzaGFwZS1wYWNrZWQudHMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvcmVzaGFwZS50cyIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9yZXNpemUtcGFja2VkLnRzIiwid2VicGFjazovL29ubnhydW50aW1lLXdlYi8uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3NoYXBlLnRzIiwid2VicGFjazovL29ubnhydW50aW1lLXdlYi8uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3NsaWNlLnRzIiwid2VicGFjazovL29ubnhydW50aW1lLXdlYi8uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3NvZnRtYXgudHMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvc3BsaXQudHMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvc3F1ZWV6ZS50cyIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy9zdW0udHMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvdGlsZS50cyIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy90cmFuc3Bvc2UudHMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvdWludDgtZW5jb2RlLnRzIiwid2VicGFjazovL29ubnhydW50aW1lLXdlYi8uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3VuYXJ5LW9wLnRzIiwid2VicGFjazovL29ubnhydW50aW1lLXdlYi8uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvb3BzL3VucGFjay50cyIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL29wcy91bnNxdWVlemUudHMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9vcHMvdXBzYW1wbGUudHMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9wcm9ncmFtLW1hbmFnZXIudHMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC9zZXNzaW9uLWhhbmRsZXIudHMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC90ZXh0dXJlLWRhdGEtZW5jb2Rlci50cyIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL3RleHR1cmUtbGF5b3V0LXN0cmF0ZWd5LnRzIiwid2VicGFjazovL29ubnhydW50aW1lLXdlYi8uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvdGV4dHVyZS1sYXlvdXQudHMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC90ZXh0dXJlLW1hbmFnZXIudHMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbGliL29ubnhqcy9iYWNrZW5kcy93ZWJnbC90eXBlcy50cyIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvLi9saWIvb25ueGpzL2JhY2tlbmRzL3dlYmdsL3V0aWxzLnRzIiwid2VicGFjazovL29ubnhydW50aW1lLXdlYi8uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvd2ViZ2wtY29udGV4dC1mYWN0b3J5LnRzIiwid2VicGFjazovL29ubnhydW50aW1lLXdlYi8uL2xpYi9vbm54anMvYmFja2VuZHMvd2ViZ2wvd2ViZ2wtY29udGV4dC50cyIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvLi9saWIvb25ueGpzL2V4ZWN1dGlvbi1wbGFuLnRzIiwid2VicGFjazovL29ubnhydW50aW1lLXdlYi8uL2xpYi9vbm54anMvZ3JhcGgudHMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbGliL29ubnhqcy9pbnN0cnVtZW50LnRzIiwid2VicGFjazovL29ubnhydW50aW1lLXdlYi8uL2xpYi9vbm54anMvbW9kZWwudHMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbGliL29ubnhqcy9vcGVyYXRvcnMudHMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbGliL29ubnhqcy9vcHNldC50cyIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvLi9saWIvb25ueGpzL29ydC1zY2hlbWEvb3J0LWdlbmVyYXRlZC50cyIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvLi9saWIvb25ueGpzL3Nlc3Npb24taGFuZGxlci50cyIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvLi9saWIvb25ueGpzL3Nlc3Npb24udHMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbGliL29ubnhqcy90ZW5zb3IudHMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbGliL29ubnhqcy91dGlsLnRzIiwid2VicGFjazovL29ubnhydW50aW1lLXdlYi8uL2xpYi93YXNtL29wdGlvbnMtdXRpbHMudHMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbGliL3dhc20vcHJveHktd3JhcHBlci50cyIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvLi9saWIvd2FzbS9ydW4tb3B0aW9ucy50cyIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvLi9saWIvd2FzbS9zZXNzaW9uLWhhbmRsZXIudHMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbGliL3dhc20vc2Vzc2lvbi1vcHRpb25zLnRzIiwid2VicGFjazovL29ubnhydW50aW1lLXdlYi8uL2xpYi93YXNtL3N0cmluZy11dGlscy50cyIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvLi9saWIvd2FzbS93YXNtLWNvcmUtaW1wbC50cyIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvLi9saWIvd2FzbS93YXNtLWZhY3RvcnkudHMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbGliL3dhc20vcHJveHktd29ya2VyL21haW4udHMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViLy4vbm9kZV9tb2R1bGVzL3dvcmtlci1sb2FkZXIvZGlzdC9ydW50aW1lL2lubGluZS5qcyIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvZXh0ZXJuYWwgdW1kIHtcImNvbW1vbmpzXCI6XCJvbm54cnVudGltZS1jb21tb25cIixcImNvbW1vbmpzMlwiOlwib25ueHJ1bnRpbWUtY29tbW9uXCIsXCJyb290XCI6XCJvcnRcIn0iLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViL2lnbm9yZWR8RDpcXGFcXF93b3JrXFwxXFxzXFxqc1xcd2ViXFxsaWJcXG9ubnhqc3xmcyIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvaWdub3JlZHxEOlxcYVxcX3dvcmtcXDFcXHNcXGpzXFx3ZWJcXGxpYlxcb25ueGpzfHV0aWwiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViL2lnbm9yZWR8RDpcXGFcXF93b3JrXFwxXFxzXFxqc1xcd2ViXFxsaWJcXHdhc21cXGJpbmRpbmd8ZnMiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViL2lnbm9yZWR8RDpcXGFcXF93b3JrXFwxXFxzXFxqc1xcd2ViXFxsaWJcXHdhc21cXGJpbmRpbmd8b3MiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViL2lnbm9yZWR8RDpcXGFcXF93b3JrXFwxXFxzXFxqc1xcd2ViXFxsaWJcXHdhc21cXGJpbmRpbmd8cGF0aCIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvaWdub3JlZHxEOlxcYVxcX3dvcmtcXDFcXHNcXGpzXFx3ZWJcXGxpYlxcd2FzbVxcYmluZGluZ3xwZXJmX2hvb2tzIiwid2VicGFjazovL29ubnhydW50aW1lLXdlYi9pZ25vcmVkfEQ6XFxhXFxfd29ya1xcMVxcc1xcanNcXHdlYlxcbGliXFx3YXNtXFxiaW5kaW5nfHdvcmtlcl90aHJlYWRzIiwid2VicGFjazovL29ubnhydW50aW1lLXdlYi9pZ25vcmVkfEQ6XFxhXFxfd29ya1xcMVxcc1xcanNcXHdlYlxcbGliXFx3YXNtfGZzIiwid2VicGFjazovL29ubnhydW50aW1lLXdlYi9pZ25vcmVkfEQ6XFxhXFxfd29ya1xcMVxcc1xcanNcXHdlYlxcbGliXFx3YXNtfHBhdGgiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViL2lnbm9yZWR8RDpcXGFcXF93b3JrXFwxXFxzXFxqc1xcd2ViXFxsaWJcXHdhc218dXRpbCIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvaWdub3JlZHxEOlxcYVxcX3dvcmtcXDFcXHNcXGpzXFx3ZWJcXGxpYnxvcyIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvLi9ub2RlX21vZHVsZXMvZmxhdGJ1ZmZlcnMvanMvZmxhdGJ1ZmZlcnMubWpzIiwid2VicGFjazovL29ubnhydW50aW1lLXdlYi93ZWJwYWNrL2Jvb3RzdHJhcCIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvd2VicGFjay9ydW50aW1lL2NvbXBhdCBnZXQgZGVmYXVsdCBleHBvcnQiLCJ3ZWJwYWNrOi8vb25ueHJ1bnRpbWUtd2ViL3dlYnBhY2svcnVudGltZS9kZWZpbmUgcHJvcGVydHkgZ2V0dGVycyIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvd2VicGFjay9ydW50aW1lL2dsb2JhbCIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvd2VicGFjay9ydW50aW1lL2hhc093blByb3BlcnR5IHNob3J0aGFuZCIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvd2VicGFjay9ydW50aW1lL21ha2UgbmFtZXNwYWNlIG9iamVjdCIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvd2VicGFjay9iZWZvcmUtc3RhcnR1cCIsIndlYnBhY2s6Ly9vbm54cnVudGltZS13ZWIvd2VicGFjay9zdGFydHVwIiwid2VicGFjazovL29ubnhydW50aW1lLXdlYi93ZWJwYWNrL2FmdGVyLXN0YXJ0dXAiXSwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIHdlYnBhY2tVbml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uKHJvb3QsIGZhY3RvcnkpIHtcblx0aWYodHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnKVxuXHRcdG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShyZXF1aXJlKFwib25ueHJ1bnRpbWUtY29tbW9uXCIpKTtcblx0ZWxzZSBpZih0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpXG5cdFx0ZGVmaW5lKFtdLCBmYWN0b3J5KTtcblx0ZWxzZSB7XG5cdFx0dmFyIGEgPSB0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcgPyBmYWN0b3J5KHJlcXVpcmUoXCJvbm54cnVudGltZS1jb21tb25cIikpIDogZmFjdG9yeShyb290W1wib3J0XCJdKTtcblx0XHRmb3IodmFyIGkgaW4gYSkgKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0JyA/IGV4cG9ydHMgOiByb290KVtpXSA9IGFbaV07XG5cdH1cbn0pKHNlbGYsIChfX1dFQlBBQ0tfRVhURVJOQUxfTU9EVUxFX29ubnhydW50aW1lX2NvbW1vbl9fKSA9PiB7XG5yZXR1cm4gIiwiXHJcbnZhciBvcnRXYXNtVGhyZWFkZWQgPSAoKCkgPT4ge1xyXG4gIHZhciBfc2NyaXB0RGlyID0gdHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJyAmJiBkb2N1bWVudC5jdXJyZW50U2NyaXB0ID8gZG9jdW1lbnQuY3VycmVudFNjcmlwdC5zcmMgOiB1bmRlZmluZWQ7XHJcbiAgaWYgKHR5cGVvZiBfX2ZpbGVuYW1lICE9PSAndW5kZWZpbmVkJykgX3NjcmlwdERpciA9IF9zY3JpcHREaXIgfHwgX19maWxlbmFtZTtcclxuICByZXR1cm4gKFxyXG5mdW5jdGlvbihvcnRXYXNtVGhyZWFkZWQpIHtcclxuICBvcnRXYXNtVGhyZWFkZWQgPSBvcnRXYXNtVGhyZWFkZWQgfHwge307XHJcblxyXG5cclxuZnVuY3Rpb24gZCgpe20uYnVmZmVyIT1uJiZwKG0uYnVmZmVyKTtyZXR1cm4gYWF9ZnVuY3Rpb24gcSgpe20uYnVmZmVyIT1uJiZwKG0uYnVmZmVyKTtyZXR1cm4gYmF9ZnVuY3Rpb24gcigpe20uYnVmZmVyIT1uJiZwKG0uYnVmZmVyKTtyZXR1cm4gY2F9ZnVuY3Rpb24gdigpe20uYnVmZmVyIT1uJiZwKG0uYnVmZmVyKTtyZXR1cm4gZGF9ZnVuY3Rpb24gZWEoKXttLmJ1ZmZlciE9biYmcChtLmJ1ZmZlcik7cmV0dXJuIGZhfXZhciB4O3h8fCh4PXR5cGVvZiBvcnRXYXNtVGhyZWFkZWQgIT09ICd1bmRlZmluZWQnID8gb3J0V2FzbVRocmVhZGVkIDoge30pO3ZhciBoYSxpYTt4LnJlYWR5PW5ldyBQcm9taXNlKGZ1bmN0aW9uKGEsYil7aGE9YTtpYT1ifSk7XHJcbnZhciBqYT1PYmplY3QuYXNzaWduKHt9LHgpLGthPVwiLi90aGlzLnByb2dyYW1cIixsYT0oYSxiKT0+e3Rocm93IGI7fSxtYT1cIm9iamVjdFwiPT10eXBlb2Ygd2luZG93LHk9XCJmdW5jdGlvblwiPT10eXBlb2YgaW1wb3J0U2NyaXB0cyxCPVwib2JqZWN0XCI9PXR5cGVvZiBwcm9jZXNzJiZcIm9iamVjdFwiPT10eXBlb2YgcHJvY2Vzcy52ZXJzaW9ucyYmXCJzdHJpbmdcIj09dHlwZW9mIHByb2Nlc3MudmVyc2lvbnMubm9kZSxDPXguRU5WSVJPTk1FTlRfSVNfUFRIUkVBRHx8ITEsRD1cIlwiO2Z1bmN0aW9uIG5hKGEpe3JldHVybiB4LmxvY2F0ZUZpbGU/eC5sb2NhdGVGaWxlKGEsRCk6RCthfXZhciBvYSxwYSxxYSxmcyxyYSxzYTtcclxuaWYoQil7RD15P3JlcXVpcmUoXCJwYXRoXCIpLmRpcm5hbWUoRCkrXCIvXCI6X19kaXJuYW1lK1wiL1wiO3NhPSgpPT57cmF8fChmcz1yZXF1aXJlKFwiZnNcIikscmE9cmVxdWlyZShcInBhdGhcIikpfTtvYT1mdW5jdGlvbihiLGMpe3NhKCk7Yj1yYS5ub3JtYWxpemUoYik7cmV0dXJuIGZzLnJlYWRGaWxlU3luYyhiLGM/dm9pZCAwOlwidXRmOFwiKX07cWE9Yj0+e2I9b2EoYiwhMCk7Yi5idWZmZXJ8fChiPW5ldyBVaW50OEFycmF5KGIpKTtyZXR1cm4gYn07cGE9KGIsYyxlKT0+e3NhKCk7Yj1yYS5ub3JtYWxpemUoYik7ZnMucmVhZEZpbGUoYixmdW5jdGlvbihmLGgpe2Y/ZShmKTpjKGguYnVmZmVyKX0pfTsxPHByb2Nlc3MuYXJndi5sZW5ndGgmJihrYT1wcm9jZXNzLmFyZ3ZbMV0ucmVwbGFjZSgvXFxcXC9nLFwiL1wiKSk7cHJvY2Vzcy5hcmd2LnNsaWNlKDIpO3Byb2Nlc3Mub24oXCJ1bmNhdWdodEV4Y2VwdGlvblwiLGZ1bmN0aW9uKGIpe2lmKCEoYiBpbnN0YW5jZW9mIEUpKXRocm93IGI7fSk7cHJvY2Vzcy5vbihcInVuaGFuZGxlZFJlamVjdGlvblwiLFxyXG5mdW5jdGlvbihiKXt0aHJvdyBiO30pO2xhPShiLGMpPT57aWYoRigpKXRocm93IHByb2Nlc3MuZXhpdENvZGU9YixjO2MgaW5zdGFuY2VvZiBFfHxHKFwiZXhpdGluZyBkdWUgdG8gZXhjZXB0aW9uOiBcIitjKTtwcm9jZXNzLmV4aXQoYil9O3guaW5zcGVjdD1mdW5jdGlvbigpe3JldHVyblwiW0Vtc2NyaXB0ZW4gTW9kdWxlIG9iamVjdF1cIn07bGV0IGE7dHJ5e2E9cmVxdWlyZShcIndvcmtlcl90aHJlYWRzXCIpfWNhdGNoKGIpe3Rocm93IGNvbnNvbGUuZXJyb3IoJ1RoZSBcIndvcmtlcl90aHJlYWRzXCIgbW9kdWxlIGlzIG5vdCBzdXBwb3J0ZWQgaW4gdGhpcyBub2RlLmpzIGJ1aWxkIC0gcGVyaGFwcyBhIG5ld2VyIHZlcnNpb24gaXMgbmVlZGVkPycpLGI7fWdsb2JhbC5Xb3JrZXI9YS5Xb3JrZXJ9ZWxzZSBpZihtYXx8eSl5P0Q9c2VsZi5sb2NhdGlvbi5ocmVmOlwidW5kZWZpbmVkXCIhPXR5cGVvZiBkb2N1bWVudCYmZG9jdW1lbnQuY3VycmVudFNjcmlwdCYmKEQ9ZG9jdW1lbnQuY3VycmVudFNjcmlwdC5zcmMpLFxyXG5fc2NyaXB0RGlyJiYoRD1fc2NyaXB0RGlyKSwwIT09RC5pbmRleE9mKFwiYmxvYjpcIik/RD1ELnN1YnN0cigwLEQucmVwbGFjZSgvWz8jXS4qLyxcIlwiKS5sYXN0SW5kZXhPZihcIi9cIikrMSk6RD1cIlwiLEJ8fChvYT1hPT57dmFyIGI9bmV3IFhNTEh0dHBSZXF1ZXN0O2Iub3BlbihcIkdFVFwiLGEsITEpO2Iuc2VuZChudWxsKTtyZXR1cm4gYi5yZXNwb25zZVRleHR9LHkmJihxYT1hPT57dmFyIGI9bmV3IFhNTEh0dHBSZXF1ZXN0O2Iub3BlbihcIkdFVFwiLGEsITEpO2IucmVzcG9uc2VUeXBlPVwiYXJyYXlidWZmZXJcIjtiLnNlbmQobnVsbCk7cmV0dXJuIG5ldyBVaW50OEFycmF5KGIucmVzcG9uc2UpfSkscGE9KGEsYixjKT0+e3ZhciBlPW5ldyBYTUxIdHRwUmVxdWVzdDtlLm9wZW4oXCJHRVRcIixhLCEwKTtlLnJlc3BvbnNlVHlwZT1cImFycmF5YnVmZmVyXCI7ZS5vbmxvYWQ9KCk9PnsyMDA9PWUuc3RhdHVzfHwwPT1lLnN0YXR1cyYmZS5yZXNwb25zZT9iKGUucmVzcG9uc2UpOmMoKX07ZS5vbmVycm9yPVxyXG5jO2Uuc2VuZChudWxsKX0pO0ImJlwidW5kZWZpbmVkXCI9PXR5cGVvZiBwZXJmb3JtYW5jZSYmKGdsb2JhbC5wZXJmb3JtYW5jZT1yZXF1aXJlKFwicGVyZl9ob29rc1wiKS5wZXJmb3JtYW5jZSk7dmFyIHRhPWNvbnNvbGUubG9nLmJpbmQoY29uc29sZSksdWE9Y29uc29sZS53YXJuLmJpbmQoY29uc29sZSk7QiYmKHNhKCksdGE9YT0+ZnMud3JpdGVTeW5jKDEsYStcIlxcblwiKSx1YT1hPT5mcy53cml0ZVN5bmMoMixhK1wiXFxuXCIpKTt2YXIgdmE9eC5wcmludHx8dGEsRz14LnByaW50RXJyfHx1YTtPYmplY3QuYXNzaWduKHgsamEpO2phPW51bGw7eC50aGlzUHJvZ3JhbSYmKGthPXgudGhpc1Byb2dyYW0pO3gucXVpdCYmKGxhPXgucXVpdCk7dmFyIEg7eC53YXNtQmluYXJ5JiYoSD14Lndhc21CaW5hcnkpO3ZhciBub0V4aXRSdW50aW1lPXgubm9FeGl0UnVudGltZXx8ITE7XCJvYmplY3RcIiE9dHlwZW9mIFdlYkFzc2VtYmx5JiZJKFwibm8gbmF0aXZlIHdhc20gc3VwcG9ydCBkZXRlY3RlZFwiKTtcclxudmFyIG0sd2EseGE9ITEseWE9XCJ1bmRlZmluZWRcIiE9dHlwZW9mIFRleHREZWNvZGVyP25ldyBUZXh0RGVjb2RlcihcInV0ZjhcIik6dm9pZCAwO1xyXG5mdW5jdGlvbiB6YShhLGIsYyl7Yj4+Pj0wO3ZhciBlPWIrYztmb3IoYz1iO2FbY10mJiEoYz49ZSk7KSsrYztpZigxNjxjLWImJmEuYnVmZmVyJiZ5YSlyZXR1cm4geWEuZGVjb2RlKGEuYnVmZmVyIGluc3RhbmNlb2YgU2hhcmVkQXJyYXlCdWZmZXI/YS5zbGljZShiLGMpOmEuc3ViYXJyYXkoYixjKSk7Zm9yKGU9XCJcIjtiPGM7KXt2YXIgZj1hW2IrK107aWYoZiYxMjgpe3ZhciBoPWFbYisrXSY2MztpZigxOTI9PShmJjIyNCkpZSs9U3RyaW5nLmZyb21DaGFyQ29kZSgoZiYzMSk8PDZ8aCk7ZWxzZXt2YXIgaz1hW2IrK10mNjM7Zj0yMjQ9PShmJjI0MCk/KGYmMTUpPDwxMnxoPDw2fGs6KGYmNyk8PDE4fGg8PDEyfGs8PDZ8YVtiKytdJjYzOzY1NTM2PmY/ZSs9U3RyaW5nLmZyb21DaGFyQ29kZShmKTooZi09NjU1MzYsZSs9U3RyaW5nLmZyb21DaGFyQ29kZSg1NTI5NnxmPj4xMCw1NjMyMHxmJjEwMjMpKX19ZWxzZSBlKz1TdHJpbmcuZnJvbUNoYXJDb2RlKGYpfXJldHVybiBlfVxyXG5mdW5jdGlvbiBBYShhLGIpe3JldHVybihhPj4+PTApP3phKHEoKSxhLGIpOlwiXCJ9XHJcbmZ1bmN0aW9uIEJhKGEsYixjLGUpe2M+Pj49MDtpZighKDA8ZSkpcmV0dXJuIDA7dmFyIGY9YztlPWMrZS0xO2Zvcih2YXIgaD0wO2g8YS5sZW5ndGg7KytoKXt2YXIgaz1hLmNoYXJDb2RlQXQoaCk7aWYoNTUyOTY8PWsmJjU3MzQzPj1rKXt2YXIgbD1hLmNoYXJDb2RlQXQoKytoKTtrPTY1NTM2KygoayYxMDIzKTw8MTApfGwmMTAyM31pZigxMjc+PWspe2lmKGM+PWUpYnJlYWs7YltjKys+Pj4wXT1rfWVsc2V7aWYoMjA0Nz49ayl7aWYoYysxPj1lKWJyZWFrO2JbYysrPj4+MF09MTkyfGs+PjZ9ZWxzZXtpZig2NTUzNT49ayl7aWYoYysyPj1lKWJyZWFrO2JbYysrPj4+MF09MjI0fGs+PjEyfWVsc2V7aWYoYyszPj1lKWJyZWFrO2JbYysrPj4+MF09MjQwfGs+PjE4O2JbYysrPj4+MF09MTI4fGs+PjEyJjYzfWJbYysrPj4+MF09MTI4fGs+PjYmNjN9YltjKys+Pj4wXT0xMjh8ayY2M319YltjPj4+MF09MDtyZXR1cm4gYy1mfVxyXG5mdW5jdGlvbiBDYShhKXtmb3IodmFyIGI9MCxjPTA7YzxhLmxlbmd0aDsrK2Mpe3ZhciBlPWEuY2hhckNvZGVBdChjKTsxMjc+PWU/YisrOjIwNDc+PWU/Yis9Mjo1NTI5Njw9ZSYmNTczNDM+PWU/KGIrPTQsKytjKTpiKz0zfXJldHVybiBifXZhciBuLGFhLGJhLGNhLGRhLGZhO0MmJihuPXguYnVmZmVyKTtmdW5jdGlvbiBwKGEpe249YTt4LkhFQVA4PWFhPW5ldyBJbnQ4QXJyYXkoYSk7eC5IRUFQMTY9bmV3IEludDE2QXJyYXkoYSk7eC5IRUFQMzI9Y2E9bmV3IEludDMyQXJyYXkoYSk7eC5IRUFQVTg9YmE9bmV3IFVpbnQ4QXJyYXkoYSk7eC5IRUFQVTE2PW5ldyBVaW50MTZBcnJheShhKTt4LkhFQVBVMzI9ZGE9bmV3IFVpbnQzMkFycmF5KGEpO3guSEVBUEYzMj1uZXcgRmxvYXQzMkFycmF5KGEpO3guSEVBUEY2ND1mYT1uZXcgRmxvYXQ2NEFycmF5KGEpfXZhciBEYT14LklOSVRJQUxfTUVNT1JZfHwxNjc3NzIxNjtcclxuaWYoQyltPXgud2FzbU1lbW9yeSxuPXguYnVmZmVyO2Vsc2UgaWYoeC53YXNtTWVtb3J5KW09eC53YXNtTWVtb3J5O2Vsc2UgaWYobT1uZXcgV2ViQXNzZW1ibHkuTWVtb3J5KHtpbml0aWFsOkRhLzY1NTM2LG1heGltdW06NjU1MzYsc2hhcmVkOiEwfSksIShtLmJ1ZmZlciBpbnN0YW5jZW9mIFNoYXJlZEFycmF5QnVmZmVyKSl0aHJvdyBHKFwicmVxdWVzdGVkIGEgc2hhcmVkIFdlYkFzc2VtYmx5Lk1lbW9yeSBidXQgdGhlIHJldHVybmVkIGJ1ZmZlciBpcyBub3QgYSBTaGFyZWRBcnJheUJ1ZmZlciwgaW5kaWNhdGluZyB0aGF0IHdoaWxlIHRoZSBicm93c2VyIGhhcyBTaGFyZWRBcnJheUJ1ZmZlciBpdCBkb2VzIG5vdCBoYXZlIFdlYkFzc2VtYmx5IHRocmVhZHMgc3VwcG9ydCAtIHlvdSBtYXkgbmVlZCB0byBzZXQgYSBmbGFnXCIpLEImJmNvbnNvbGUubG9nKFwiKG9uIG5vZGUgeW91IG1heSBuZWVkOiAtLWV4cGVyaW1lbnRhbC13YXNtLXRocmVhZHMgLS1leHBlcmltZW50YWwtd2FzbS1idWxrLW1lbW9yeSBhbmQgYWxzbyB1c2UgYSByZWNlbnQgdmVyc2lvbilcIiksXHJcbkVycm9yKFwiYmFkIG1lbW9yeVwiKTttJiYobj1tLmJ1ZmZlcik7RGE9bi5ieXRlTGVuZ3RoO3Aobik7dmFyIEVhLEZhPVtdLEdhPVtdLEhhPVtdLElhPVtdLEphPTA7ZnVuY3Rpb24gRigpe3JldHVybiBub0V4aXRSdW50aW1lfHwwPEphfWZ1bmN0aW9uIEthKCl7dmFyIGE9eC5wcmVSdW4uc2hpZnQoKTtGYS51bnNoaWZ0KGEpfXZhciBMPTAsTGE9bnVsbCxNPW51bGw7ZnVuY3Rpb24gSShhKXtpZihDKXBvc3RNZXNzYWdlKHtjbWQ6XCJvbkFib3J0XCIsYXJnOmF9KTtlbHNlIGlmKHgub25BYm9ydCl4Lm9uQWJvcnQoYSk7YT1cIkFib3J0ZWQoXCIrYStcIilcIjtHKGEpO3hhPSEwO2E9bmV3IFdlYkFzc2VtYmx5LlJ1bnRpbWVFcnJvcihhK1wiLiBCdWlsZCB3aXRoIC1zQVNTRVJUSU9OUyBmb3IgbW9yZSBpbmZvLlwiKTtpYShhKTt0aHJvdyBhO31mdW5jdGlvbiBNYSgpe3JldHVybiBPLnN0YXJ0c1dpdGgoXCJkYXRhOmFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbTtiYXNlNjQsXCIpfXZhciBPO089XCJvcnQtd2FzbS10aHJlYWRlZC53YXNtXCI7XHJcbk1hKCl8fChPPW5hKE8pKTtmdW5jdGlvbiBOYSgpe3ZhciBhPU87dHJ5e2lmKGE9PU8mJkgpcmV0dXJuIG5ldyBVaW50OEFycmF5KEgpO2lmKHFhKXJldHVybiBxYShhKTt0aHJvd1wiYm90aCBhc3luYyBhbmQgc3luYyBmZXRjaGluZyBvZiB0aGUgd2FzbSBmYWlsZWRcIjt9Y2F0Y2goYil7SShiKX19XHJcbmZ1bmN0aW9uIE9hKCl7aWYoIUgmJihtYXx8eSkpe2lmKFwiZnVuY3Rpb25cIj09dHlwZW9mIGZldGNoJiYhTy5zdGFydHNXaXRoKFwiZmlsZTovL1wiKSlyZXR1cm4gZmV0Y2goTyx7Y3JlZGVudGlhbHM6XCJzYW1lLW9yaWdpblwifSkudGhlbihmdW5jdGlvbihhKXtpZighYS5vayl0aHJvd1wiZmFpbGVkIHRvIGxvYWQgd2FzbSBiaW5hcnkgZmlsZSBhdCAnXCIrTytcIidcIjtyZXR1cm4gYS5hcnJheUJ1ZmZlcigpfSkuY2F0Y2goZnVuY3Rpb24oKXtyZXR1cm4gTmEoKX0pO2lmKHBhKXJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihhLGIpe3BhKE8sZnVuY3Rpb24oYyl7YShuZXcgVWludDhBcnJheShjKSl9LGIpfSl9cmV0dXJuIFByb21pc2UucmVzb2x2ZSgpLnRoZW4oZnVuY3Rpb24oKXtyZXR1cm4gTmEoKX0pfXZhciBQYT17fTtcclxuZnVuY3Rpb24gRShhKXt0aGlzLm5hbWU9XCJFeGl0U3RhdHVzXCI7dGhpcy5tZXNzYWdlPVwiUHJvZ3JhbSB0ZXJtaW5hdGVkIHdpdGggZXhpdChcIithK1wiKVwiO3RoaXMuc3RhdHVzPWF9ZnVuY3Rpb24gUWEoYSl7KGE9UC5WYlthXSl8fEkoKTtQLm1jKGEpfWZ1bmN0aW9uIFJhKGEpe3ZhciBiPVAuQ2MoKTtpZighYilyZXR1cm4gNjtQLmFjLnB1c2goYik7UC5WYlthLlViXT1iO2IuVWI9YS5VYjt2YXIgYz17Y21kOlwicnVuXCIsc3RhcnRfcm91dGluZTphLkljLGFyZzphLnpjLHB0aHJlYWRfcHRyOmEuVWJ9O2IuJGI9KCk9PntjLnRpbWU9cGVyZm9ybWFuY2Uubm93KCk7Yi5wb3N0TWVzc2FnZShjLGEuTmMpfTtiLmxvYWRlZCYmKGIuJGIoKSxkZWxldGUgYi4kYik7cmV0dXJuIDB9ZnVuY3Rpb24gU2EoYSl7aWYoQylyZXR1cm4gUSgxLDEsYSk7aWYoIUYoKSl7UC5vYygpO2lmKHgub25FeGl0KXgub25FeGl0KGEpO3hhPSEwfWxhKGEsbmV3IEUoYSkpfVxyXG5mdW5jdGlvbiBUYShhLGIpe2lmKCFiJiZDKXRocm93IFVhKGEpLFwidW53aW5kXCI7RigpfHxDfHwoVmEoKSxSKEhhKSxXYSgwKSxYYVsxXS5sZW5ndGgmJllhKDEsMTApLFhhWzJdLmxlbmd0aCYmWWEoMiwxMCksUC5vYygpKTtTYShhKX1cclxudmFyIFA9e1liOltdLGFjOltdLHFjOltdLFZiOnt9LGZjOmZ1bmN0aW9uKCl7QyYmUC5FYygpfSxQYzpmdW5jdGlvbigpe30sRWM6ZnVuY3Rpb24oKXtQLnJlY2VpdmVPYmplY3RUcmFuc2Zlcj1QLkdjO1AudGhyZWFkSW5pdFRMUz1QLnBjO1Auc2V0RXhpdFN0YXR1cz1QLm5jO25vRXhpdFJ1bnRpbWU9ITF9LG5jOmZ1bmN0aW9uKCl7fSxvYzpmdW5jdGlvbigpe2Zvcih2YXIgYSBvZiBPYmplY3QudmFsdWVzKFAuVmIpKVAubWMoYSk7Zm9yKGEgb2YgUC5ZYilhLnRlcm1pbmF0ZSgpO1AuWWI9W119LG1jOmZ1bmN0aW9uKGEpe3ZhciBiPWEuVWI7ZGVsZXRlIFAuVmJbYl07UC5ZYi5wdXNoKGEpO1AuYWMuc3BsaWNlKFAuYWMuaW5kZXhPZihhKSwxKTthLlViPTA7WmEoYil9LEdjOmZ1bmN0aW9uKCl7fSxwYzpmdW5jdGlvbigpe1AucWMuZm9yRWFjaChhPT5hKCkpfSxGYzpmdW5jdGlvbihhLGIpe2Eub25tZXNzYWdlPWM9PntjPWMuZGF0YTt2YXIgZT1jLmNtZDthLlViJiYoUC5CYz1hLlViKTtcclxuaWYoYy50YXJnZXRUaHJlYWQmJmMudGFyZ2V0VGhyZWFkIT0kYSgpKXt2YXIgZj1QLlZiW2MuUWNdO2Y/Zi5wb3N0TWVzc2FnZShjLGMudHJhbnNmZXJMaXN0KTpHKCdJbnRlcm5hbCBlcnJvciEgV29ya2VyIHNlbnQgYSBtZXNzYWdlIFwiJytlKydcIiB0byB0YXJnZXQgcHRocmVhZCAnK2MudGFyZ2V0VGhyZWFkK1wiLCBidXQgdGhhdCB0aHJlYWQgbm8gbG9uZ2VyIGV4aXN0cyFcIil9ZWxzZSBpZihcInByb2Nlc3NQcm94eWluZ1F1ZXVlXCI9PT1lKWFiKGMucXVldWUpO2Vsc2UgaWYoXCJzcGF3blRocmVhZFwiPT09ZSlSYShjKTtlbHNlIGlmKFwiY2xlYW51cFRocmVhZFwiPT09ZSlRYShjLnRocmVhZCk7ZWxzZSBpZihcImtpbGxUaHJlYWRcIj09PWUpYz1jLnRocmVhZCxlPVAuVmJbY10sZGVsZXRlIFAuVmJbY10sZS50ZXJtaW5hdGUoKSxaYShjKSxQLmFjLnNwbGljZShQLmFjLmluZGV4T2YoZSksMSksZS5VYj0wO2Vsc2UgaWYoXCJjYW5jZWxUaHJlYWRcIj09PWUpUC5WYltjLnRocmVhZF0ucG9zdE1lc3NhZ2Uoe2NtZDpcImNhbmNlbFwifSk7XHJcbmVsc2UgaWYoXCJsb2FkZWRcIj09PWUpYS5sb2FkZWQ9ITAsYiYmYihhKSxhLiRiJiYoYS4kYigpLGRlbGV0ZSBhLiRiKTtlbHNlIGlmKFwicHJpbnRcIj09PWUpdmEoXCJUaHJlYWQgXCIrYy50aHJlYWRJZCtcIjogXCIrYy50ZXh0KTtlbHNlIGlmKFwicHJpbnRFcnJcIj09PWUpRyhcIlRocmVhZCBcIitjLnRocmVhZElkK1wiOiBcIitjLnRleHQpO2Vsc2UgaWYoXCJhbGVydFwiPT09ZSlhbGVydChcIlRocmVhZCBcIitjLnRocmVhZElkK1wiOiBcIitjLnRleHQpO2Vsc2UgaWYoXCJzZXRpbW1lZGlhdGVcIj09PWMudGFyZ2V0KWEucG9zdE1lc3NhZ2UoYyk7ZWxzZSBpZihcIm9uQWJvcnRcIj09PWUpe2lmKHgub25BYm9ydCl4Lm9uQWJvcnQoYy5hcmcpfWVsc2UgZSYmRyhcIndvcmtlciBzZW50IGFuIHVua25vd24gY29tbWFuZCBcIitlKTtQLkJjPXZvaWQgMH07YS5vbmVycm9yPWM9PntHKFwid29ya2VyIHNlbnQgYW4gZXJyb3IhIFwiK2MuZmlsZW5hbWUrXCI6XCIrYy5saW5lbm8rXCI6IFwiK2MubWVzc2FnZSk7dGhyb3cgYzt9O0ImJlxyXG4oYS5vbihcIm1lc3NhZ2VcIixmdW5jdGlvbihjKXthLm9ubWVzc2FnZSh7ZGF0YTpjfSl9KSxhLm9uKFwiZXJyb3JcIixmdW5jdGlvbihjKXthLm9uZXJyb3IoYyl9KSxhLm9uKFwiZGV0YWNoZWRFeGl0XCIsZnVuY3Rpb24oKXt9KSk7YS5wb3N0TWVzc2FnZSh7Y21kOlwibG9hZFwiLHVybE9yQmxvYjp4Lm1haW5TY3JpcHRVcmxPckJsb2J8fF9zY3JpcHREaXIsd2FzbU1lbW9yeTptLHdhc21Nb2R1bGU6d2F9KX0seWM6ZnVuY3Rpb24oKXt2YXIgYT1uYShcIm9ydC13YXNtLXRocmVhZGVkLndvcmtlci5qc1wiKTtQLlliLnB1c2gobmV3IFdvcmtlcihhKSl9LENjOmZ1bmN0aW9uKCl7MD09UC5ZYi5sZW5ndGgmJihQLnljKCksUC5GYyhQLlliWzBdKSk7cmV0dXJuIFAuWWIucG9wKCl9fTt4LlBUaHJlYWQ9UDtmdW5jdGlvbiBSKGEpe2Zvcig7MDxhLmxlbmd0aDspYS5zaGlmdCgpKHgpfWZ1bmN0aW9uIGJiKGEpe3ZhciBiPVMoKTthPWEoKTtVKGIpO3JldHVybiBhfVxyXG54LmVzdGFibGlzaFN0YWNrU3BhY2U9ZnVuY3Rpb24oKXt2YXIgYT0kYSgpLGI9cigpW2ErNDQ+PjI+Pj4wXTthPXIoKVthKzQ4Pj4yPj4+MF07Y2IoYixiLWEpO1UoYil9O2Z1bmN0aW9uIFVhKGEpe2lmKEMpcmV0dXJuIFEoMiwwLGEpO3RyeXtUYShhKX1jYXRjaChiKXtiIGluc3RhbmNlb2YgRXx8XCJ1bndpbmRcIj09Ynx8bGEoMSxiKX19dmFyIGRiPVtdO2Z1bmN0aW9uIFYoYSl7dmFyIGI9ZGJbYV07Ynx8KGE+PWRiLmxlbmd0aCYmKGRiLmxlbmd0aD1hKzEpLGRiW2FdPWI9RWEuZ2V0KGEpKTtyZXR1cm4gYn14Lmludm9rZUVudHJ5UG9pbnQ9ZnVuY3Rpb24oYSxiKXthPVYoYSkoYik7RigpP1AubmMoYSk6ZWIoYSl9O2Z1bmN0aW9uIGZiKGEsYil7ZCgpLnNldChhLGI+Pj4wKX12YXIgZ2I9W10saGI9MCxXPTA7XHJcbmZ1bmN0aW9uIFgoYSl7dGhpcy5aYj1hO3RoaXMuU2I9YS0yNDt0aGlzLnhjPWZ1bmN0aW9uKGIpe3YoKVt0aGlzLlNiKzQ+PjI+Pj4wXT1ifTt0aGlzLmJjPWZ1bmN0aW9uKCl7cmV0dXJuIHYoKVt0aGlzLlNiKzQ+PjI+Pj4wXX07dGhpcy53Yz1mdW5jdGlvbihiKXt2KClbdGhpcy5TYis4Pj4yPj4+MF09Yn07dGhpcy5EYz1mdW5jdGlvbigpe3JldHVybiB2KClbdGhpcy5TYis4Pj4yPj4+MF19O3RoaXMucmM9ZnVuY3Rpb24oKXtyKClbdGhpcy5TYj4+Mj4+PjBdPTB9O3RoaXMuaGM9ZnVuY3Rpb24oYil7Yj1iPzE6MDtkKClbdGhpcy5TYisxMj4+MD4+PjBdPWJ9O3RoaXMudWM9ZnVuY3Rpb24oKXtyZXR1cm4gMCE9ZCgpW3RoaXMuU2IrMTI+PjA+Pj4wXX07dGhpcy5pYz1mdW5jdGlvbihiKXtiPWI/MTowO2QoKVt0aGlzLlNiKzEzPj4wPj4+MF09Yn07dGhpcy5rYz1mdW5jdGlvbigpe3JldHVybiAwIT1kKClbdGhpcy5TYisxMz4+MD4+PjBdfTt0aGlzLmZjPWZ1bmN0aW9uKGIsYyl7dGhpcy5jYygwKTtcclxudGhpcy54YyhiKTt0aGlzLndjKGMpO3RoaXMucmMoKTt0aGlzLmhjKCExKTt0aGlzLmljKCExKX07dGhpcy5zYz1mdW5jdGlvbigpe0F0b21pY3MuYWRkKHIoKSx0aGlzLlNiPj4yLDEpfTt0aGlzLkhjPWZ1bmN0aW9uKCl7cmV0dXJuIDE9PT1BdG9taWNzLnN1YihyKCksdGhpcy5TYj4+MiwxKX07dGhpcy5jYz1mdW5jdGlvbihiKXt2KClbdGhpcy5TYisxNj4+Mj4+PjBdPWJ9O3RoaXMudGM9ZnVuY3Rpb24oKXtyZXR1cm4gdigpW3RoaXMuU2IrMTY+PjI+Pj4wXX07dGhpcy52Yz1mdW5jdGlvbigpe2lmKGliKHRoaXMuYmMoKSkpcmV0dXJuIHYoKVt0aGlzLlpiPj4yPj4+MF07dmFyIGI9dGhpcy50YygpO3JldHVybiAwIT09Yj9iOnRoaXMuWmJ9fWZ1bmN0aW9uIGpiKGEpe3JldHVybiBrYigobmV3IFgoYSkpLlNiKX1mdW5jdGlvbiBsYihhLGIsYyxlKXtyZXR1cm4gQz9RKDMsMSxhLGIsYyxlKTptYihhLGIsYyxlKX1cclxuZnVuY3Rpb24gbWIoYSxiLGMsZSl7aWYoXCJ1bmRlZmluZWRcIj09dHlwZW9mIFNoYXJlZEFycmF5QnVmZmVyKXJldHVybiBHKFwiQ3VycmVudCBlbnZpcm9ubWVudCBkb2VzIG5vdCBzdXBwb3J0IFNoYXJlZEFycmF5QnVmZmVyLCBwdGhyZWFkcyBhcmUgbm90IGF2YWlsYWJsZSFcIiksNjt2YXIgZj1bXTtpZihDJiYwPT09Zi5sZW5ndGgpcmV0dXJuIGxiKGEsYixjLGUpO2E9e0ljOmMsVWI6YSx6YzplLE5jOmZ9O3JldHVybiBDPyhhLk9jPVwic3Bhd25UaHJlYWRcIixwb3N0TWVzc2FnZShhLGYpLDApOlJhKGEpfWZ1bmN0aW9uIG5iKGEsYixjKXtyZXR1cm4gQz9RKDQsMSxhLGIsYyk6MH1mdW5jdGlvbiBvYihhLGIpe2lmKEMpcmV0dXJuIFEoNSwxLGEsYil9ZnVuY3Rpb24gcGIoYSxiKXtpZihDKXJldHVybiBRKDYsMSxhLGIpfWZ1bmN0aW9uIHFiKGEsYixjKXtpZihDKXJldHVybiBRKDcsMSxhLGIsYyl9ZnVuY3Rpb24gcmIoYSxiLGMpe3JldHVybiBDP1EoOCwxLGEsYixjKTowfVxyXG5mdW5jdGlvbiBzYihhLGIpe2lmKEMpcmV0dXJuIFEoOSwxLGEsYil9ZnVuY3Rpb24gdGIoYSxiLGMpe2lmKEMpcmV0dXJuIFEoMTAsMSxhLGIsYyl9ZnVuY3Rpb24gdWIoYSxiLGMsZSl7aWYoQylyZXR1cm4gUSgxMSwxLGEsYixjLGUpfWZ1bmN0aW9uIHZiKGEsYixjLGUpe2lmKEMpcmV0dXJuIFEoMTIsMSxhLGIsYyxlKX1mdW5jdGlvbiB3YihhLGIsYyxlKXtpZihDKXJldHVybiBRKDEzLDEsYSxiLGMsZSl9ZnVuY3Rpb24geGIoYSl7aWYoQylyZXR1cm4gUSgxNCwxLGEpfWZ1bmN0aW9uIHliKGEsYil7aWYoQylyZXR1cm4gUSgxNSwxLGEsYil9ZnVuY3Rpb24gemIoYSxiLGMpe2lmKEMpcmV0dXJuIFEoMTYsMSxhLGIsYyl9ZnVuY3Rpb24gYWIoYSl7QXRvbWljcy5zdG9yZShyKCksYT4+MiwxKTskYSgpJiZBYihhKTtBdG9taWNzLmNvbXBhcmVFeGNoYW5nZShyKCksYT4+MiwxLDApfXguZXhlY3V0ZU5vdGlmaWVkUHJveHlpbmdRdWV1ZT1hYjtcclxuZnVuY3Rpb24gQmIoYSl7cmV0dXJuIHYoKVthPj4+Ml0rNDI5NDk2NzI5NipyKClbYSs0Pj4+Ml19ZnVuY3Rpb24gQ2IoYSxiLGMsZSxmLGgpe3JldHVybiBDP1EoMTcsMSxhLGIsYyxlLGYsaCk6LTUyfWZ1bmN0aW9uIERiKGEsYixjLGUsZixoKXtpZihDKXJldHVybiBRKDE4LDEsYSxiLGMsZSxmLGgpfWZ1bmN0aW9uIEViKGEpe3ZhciBiPUNhKGEpKzEsYz1GYihiKTtjJiZCYShhLGQoKSxjLGIpO3JldHVybiBjfVxyXG5mdW5jdGlvbiBHYihhLGIsYyl7ZnVuY3Rpb24gZSh0KXtyZXR1cm4odD10LnRvVGltZVN0cmluZygpLm1hdGNoKC9cXCgoW0EtWmEteiBdKylcXCkkLykpP3RbMV06XCJHTVRcIn1pZihDKXJldHVybiBRKDE5LDEsYSxiLGMpO3ZhciBmPShuZXcgRGF0ZSkuZ2V0RnVsbFllYXIoKSxoPW5ldyBEYXRlKGYsMCwxKSxrPW5ldyBEYXRlKGYsNiwxKTtmPWguZ2V0VGltZXpvbmVPZmZzZXQoKTt2YXIgbD1rLmdldFRpbWV6b25lT2Zmc2V0KCksdT1NYXRoLm1heChmLGwpO3IoKVthPj4yPj4+MF09NjAqdTtyKClbYj4+Mj4+PjBdPU51bWJlcihmIT1sKTthPWUoaCk7Yj1lKGspO2E9RWIoYSk7Yj1FYihiKTtsPGY/KHYoKVtjPj4yPj4+MF09YSx2KClbYys0Pj4yPj4+MF09Yik6KHYoKVtjPj4yPj4+MF09Yix2KClbYys0Pj4yPj4+MF09YSl9ZnVuY3Rpb24gSGIoYSxiLGMpe0hiLkFjfHwoSGIuQWM9ITAsR2IoYSxiLGMpKX12YXIgSWIsSmI7XHJcbkpiPUI/KCk9Pnt2YXIgYT1wcm9jZXNzLmhydGltZSgpO3JldHVybiAxRTMqYVswXSthWzFdLzFFNn06Qz8oKT0+cGVyZm9ybWFuY2Uubm93KCkteC5fX3BlcmZvcm1hbmNlX25vd19jbG9ja19kcmlmdDooKT0+cGVyZm9ybWFuY2Uubm93KCk7ZnVuY3Rpb24gUShhLGIpe3ZhciBjPWFyZ3VtZW50cy5sZW5ndGgtMixlPWFyZ3VtZW50cztyZXR1cm4gYmIoKCk9Pntmb3IodmFyIGY9S2IoOCpjKSxoPWY+PjMsaz0wO2s8YztrKyspe3ZhciBsPWVbMitrXTtlYSgpW2graz4+PjBdPWx9cmV0dXJuIExiKGEsYyxmLGIpfSl9dmFyIE1iPVtdLE5iPXt9O1xyXG5mdW5jdGlvbiBPYigpe2lmKCFQYil7dmFyIGE9e1VTRVI6XCJ3ZWJfdXNlclwiLExPR05BTUU6XCJ3ZWJfdXNlclwiLFBBVEg6XCIvXCIsUFdEOlwiL1wiLEhPTUU6XCIvaG9tZS93ZWJfdXNlclwiLExBTkc6KFwib2JqZWN0XCI9PXR5cGVvZiBuYXZpZ2F0b3ImJm5hdmlnYXRvci5sYW5ndWFnZXMmJm5hdmlnYXRvci5sYW5ndWFnZXNbMF18fFwiQ1wiKS5yZXBsYWNlKFwiLVwiLFwiX1wiKStcIi5VVEYtOFwiLF86a2F8fFwiLi90aGlzLnByb2dyYW1cIn0sYjtmb3IoYiBpbiBOYil2b2lkIDA9PT1OYltiXT9kZWxldGUgYVtiXTphW2JdPU5iW2JdO3ZhciBjPVtdO2ZvcihiIGluIGEpYy5wdXNoKGIrXCI9XCIrYVtiXSk7UGI9Y31yZXR1cm4gUGJ9dmFyIFBiO1xyXG5mdW5jdGlvbiBRYihhLGIpe2lmKEMpcmV0dXJuIFEoMjAsMSxhLGIpO3ZhciBjPTA7T2IoKS5mb3JFYWNoKGZ1bmN0aW9uKGUsZil7dmFyIGg9YitjO2Y9digpW2ErNCpmPj4yPj4+MF09aDtmb3IoaD0wO2g8ZS5sZW5ndGg7KytoKWQoKVtmKys+PjA+Pj4wXT1lLmNoYXJDb2RlQXQoaCk7ZCgpW2Y+PjA+Pj4wXT0wO2MrPWUubGVuZ3RoKzF9KTtyZXR1cm4gMH1mdW5jdGlvbiBSYihhLGIpe2lmKEMpcmV0dXJuIFEoMjEsMSxhLGIpO3ZhciBjPU9iKCk7digpW2E+PjI+Pj4wXT1jLmxlbmd0aDt2YXIgZT0wO2MuZm9yRWFjaChmdW5jdGlvbihmKXtlKz1mLmxlbmd0aCsxfSk7digpW2I+PjI+Pj4wXT1lO3JldHVybiAwfWZ1bmN0aW9uIFNiKGEpe3JldHVybiBDP1EoMjIsMSxhKTo1Mn1mdW5jdGlvbiBUYihhLGIsYyxlKXtyZXR1cm4gQz9RKDIzLDEsYSxiLGMsZSk6NTJ9ZnVuY3Rpb24gVWIoYSxiLGMsZSxmKXtyZXR1cm4gQz9RKDI0LDEsYSxiLGMsZSxmKTo3MH1cclxudmFyIFhhPVtudWxsLFtdLFtdXTtmdW5jdGlvbiBZYShhLGIpe3ZhciBjPVhhW2FdOzA9PT1ifHwxMD09PWI/KCgxPT09YT92YTpHKSh6YShjLDApKSxjLmxlbmd0aD0wKTpjLnB1c2goYil9ZnVuY3Rpb24gVmIoYSxiLGMsZSl7aWYoQylyZXR1cm4gUSgyNSwxLGEsYixjLGUpO2Zvcih2YXIgZj0wLGg9MDtoPGM7aCsrKXt2YXIgaz12KClbYj4+Mj4+PjBdLGw9digpW2IrND4+Mj4+PjBdO2IrPTg7Zm9yKHZhciB1PTA7dTxsO3UrKylZYShhLHEoKVtrK3U+Pj4wXSk7Zis9bH12KClbZT4+Mj4+PjBdPWY7cmV0dXJuIDB9dmFyIFk9MDtcclxuZnVuY3Rpb24gV2IoKXtpZihcIm9iamVjdFwiPT10eXBlb2YgY3J5cHRvJiZcImZ1bmN0aW9uXCI9PXR5cGVvZiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKXt2YXIgYT1uZXcgVWludDhBcnJheSgxKTtyZXR1cm4oKT0+e2NyeXB0by5nZXRSYW5kb21WYWx1ZXMoYSk7cmV0dXJuIGFbMF19fWlmKEIpdHJ5e3ZhciBiPXJlcXVpcmUoXCJjcnlwdG9cIik7cmV0dXJuKCk9PmIucmFuZG9tQnl0ZXMoMSlbMF19Y2F0Y2goYyl7fXJldHVybigpPT5JKFwicmFuZG9tRGV2aWNlXCIpfWZ1bmN0aW9uIFhiKGEsYil7WGIubGN8fChYYi5sYz1XYigpKTtmb3IodmFyIGM9MDtjPGI7YysrKWQoKVthK2M+PjA+Pj4wXT1YYi5sYygpO3JldHVybiAwfWZ1bmN0aW9uIFliKGEpe3JldHVybiAwPT09YSU0JiYoMCE9PWElMTAwfHwwPT09YSU0MDApfXZhciBaYj1bMzEsMjksMzEsMzAsMzEsMzAsMzEsMzEsMzAsMzEsMzAsMzFdLCRiPVszMSwyOCwzMSwzMCwzMSwzMCwzMSwzMSwzMCwzMSwzMCwzMV07XHJcbmZ1bmN0aW9uIGFjKGEpe3ZhciBiPUFycmF5KENhKGEpKzEpO0JhKGEsYiwwLGIubGVuZ3RoKTtyZXR1cm4gYn1cclxuZnVuY3Rpb24gYmMoYSxiLGMsZSl7ZnVuY3Rpb24gZihnLHcseil7Zm9yKGc9XCJudW1iZXJcIj09dHlwZW9mIGc/Zy50b1N0cmluZygpOmd8fFwiXCI7Zy5sZW5ndGg8dzspZz16WzBdK2c7cmV0dXJuIGd9ZnVuY3Rpb24gaChnLHcpe3JldHVybiBmKGcsdyxcIjBcIil9ZnVuY3Rpb24gayhnLHcpe2Z1bmN0aW9uIHooVCl7cmV0dXJuIDA+VD8tMTowPFQ/MTowfXZhciBOOzA9PT0oTj16KGcuZ2V0RnVsbFllYXIoKS13LmdldEZ1bGxZZWFyKCkpKSYmMD09PShOPXooZy5nZXRNb250aCgpLXcuZ2V0TW9udGgoKSkpJiYoTj16KGcuZ2V0RGF0ZSgpLXcuZ2V0RGF0ZSgpKSk7cmV0dXJuIE59ZnVuY3Rpb24gbChnKXtzd2l0Y2goZy5nZXREYXkoKSl7Y2FzZSAwOnJldHVybiBuZXcgRGF0ZShnLmdldEZ1bGxZZWFyKCktMSwxMSwyOSk7Y2FzZSAxOnJldHVybiBnO2Nhc2UgMjpyZXR1cm4gbmV3IERhdGUoZy5nZXRGdWxsWWVhcigpLDAsMyk7Y2FzZSAzOnJldHVybiBuZXcgRGF0ZShnLmdldEZ1bGxZZWFyKCksXHJcbjAsMik7Y2FzZSA0OnJldHVybiBuZXcgRGF0ZShnLmdldEZ1bGxZZWFyKCksMCwxKTtjYXNlIDU6cmV0dXJuIG5ldyBEYXRlKGcuZ2V0RnVsbFllYXIoKS0xLDExLDMxKTtjYXNlIDY6cmV0dXJuIG5ldyBEYXRlKGcuZ2V0RnVsbFllYXIoKS0xLDExLDMwKX19ZnVuY3Rpb24gdShnKXt2YXIgdz1nLldiO2ZvcihnPW5ldyBEYXRlKChuZXcgRGF0ZShnLlhiKzE5MDAsMCwxKSkuZ2V0VGltZSgpKTswPHc7KXt2YXIgej1nLmdldE1vbnRoKCksTj0oWWIoZy5nZXRGdWxsWWVhcigpKT9aYjokYilbel07aWYodz5OLWcuZ2V0RGF0ZSgpKXctPU4tZy5nZXREYXRlKCkrMSxnLnNldERhdGUoMSksMTE+ej9nLnNldE1vbnRoKHorMSk6KGcuc2V0TW9udGgoMCksZy5zZXRGdWxsWWVhcihnLmdldEZ1bGxZZWFyKCkrMSkpO2Vsc2V7Zy5zZXREYXRlKGcuZ2V0RGF0ZSgpK3cpO2JyZWFrfX16PW5ldyBEYXRlKGcuZ2V0RnVsbFllYXIoKSsxLDAsNCk7dz1sKG5ldyBEYXRlKGcuZ2V0RnVsbFllYXIoKSxcclxuMCw0KSk7ej1sKHopO3JldHVybiAwPj1rKHcsZyk/MD49ayh6LGcpP2cuZ2V0RnVsbFllYXIoKSsxOmcuZ2V0RnVsbFllYXIoKTpnLmdldEZ1bGxZZWFyKCktMX12YXIgdD1yKClbZSs0MD4+Mj4+PjBdO2U9e0xjOnIoKVtlPj4yPj4+MF0sS2M6cigpW2UrND4+Mj4+PjBdLGRjOnIoKVtlKzg+PjI+Pj4wXSxqYzpyKClbZSsxMj4+Mj4+PjBdLGVjOnIoKVtlKzE2Pj4yPj4+MF0sWGI6cigpW2UrMjA+PjI+Pj4wXSxUYjpyKClbZSsyND4+Mj4+PjBdLFdiOnIoKVtlKzI4Pj4yPj4+MF0sUmM6cigpW2UrMzI+PjI+Pj4wXSxKYzpyKClbZSszNj4+Mj4+PjBdLE1jOnQ/QWEodCk6XCJcIn07Yz1BYShjKTt0PXtcIiVjXCI6XCIlYSAlYiAlZCAlSDolTTolUyAlWVwiLFwiJURcIjpcIiVtLyVkLyV5XCIsXCIlRlwiOlwiJVktJW0tJWRcIixcIiVoXCI6XCIlYlwiLFwiJXJcIjpcIiVJOiVNOiVTICVwXCIsXCIlUlwiOlwiJUg6JU1cIixcIiVUXCI6XCIlSDolTTolU1wiLFwiJXhcIjpcIiVtLyVkLyV5XCIsXCIlWFwiOlwiJUg6JU06JVNcIixcIiVFY1wiOlwiJWNcIixcIiVFQ1wiOlwiJUNcIixcclxuXCIlRXhcIjpcIiVtLyVkLyV5XCIsXCIlRVhcIjpcIiVIOiVNOiVTXCIsXCIlRXlcIjpcIiV5XCIsXCIlRVlcIjpcIiVZXCIsXCIlT2RcIjpcIiVkXCIsXCIlT2VcIjpcIiVlXCIsXCIlT0hcIjpcIiVIXCIsXCIlT0lcIjpcIiVJXCIsXCIlT21cIjpcIiVtXCIsXCIlT01cIjpcIiVNXCIsXCIlT1NcIjpcIiVTXCIsXCIlT3VcIjpcIiV1XCIsXCIlT1VcIjpcIiVVXCIsXCIlT1ZcIjpcIiVWXCIsXCIlT3dcIjpcIiV3XCIsXCIlT1dcIjpcIiVXXCIsXCIlT3lcIjpcIiV5XCJ9O2Zvcih2YXIgQSBpbiB0KWM9Yy5yZXBsYWNlKG5ldyBSZWdFeHAoQSxcImdcIiksdFtBXSk7dmFyIEs9XCJTdW5kYXkgTW9uZGF5IFR1ZXNkYXkgV2VkbmVzZGF5IFRodXJzZGF5IEZyaWRheSBTYXR1cmRheVwiLnNwbGl0KFwiIFwiKSxKPVwiSmFudWFyeSBGZWJydWFyeSBNYXJjaCBBcHJpbCBNYXkgSnVuZSBKdWx5IEF1Z3VzdCBTZXB0ZW1iZXIgT2N0b2JlciBOb3ZlbWJlciBEZWNlbWJlclwiLnNwbGl0KFwiIFwiKTt0PXtcIiVhXCI6ZnVuY3Rpb24oZyl7cmV0dXJuIEtbZy5UYl0uc3Vic3RyaW5nKDAsMyl9LFwiJUFcIjpmdW5jdGlvbihnKXtyZXR1cm4gS1tnLlRiXX0sXHJcblwiJWJcIjpmdW5jdGlvbihnKXtyZXR1cm4gSltnLmVjXS5zdWJzdHJpbmcoMCwzKX0sXCIlQlwiOmZ1bmN0aW9uKGcpe3JldHVybiBKW2cuZWNdfSxcIiVDXCI6ZnVuY3Rpb24oZyl7cmV0dXJuIGgoKGcuWGIrMTkwMCkvMTAwfDAsMil9LFwiJWRcIjpmdW5jdGlvbihnKXtyZXR1cm4gaChnLmpjLDIpfSxcIiVlXCI6ZnVuY3Rpb24oZyl7cmV0dXJuIGYoZy5qYywyLFwiIFwiKX0sXCIlZ1wiOmZ1bmN0aW9uKGcpe3JldHVybiB1KGcpLnRvU3RyaW5nKCkuc3Vic3RyaW5nKDIpfSxcIiVHXCI6ZnVuY3Rpb24oZyl7cmV0dXJuIHUoZyl9LFwiJUhcIjpmdW5jdGlvbihnKXtyZXR1cm4gaChnLmRjLDIpfSxcIiVJXCI6ZnVuY3Rpb24oZyl7Zz1nLmRjOzA9PWc/Zz0xMjoxMjxnJiYoZy09MTIpO3JldHVybiBoKGcsMil9LFwiJWpcIjpmdW5jdGlvbihnKXtmb3IodmFyIHc9MCx6PTA7ejw9Zy5lYy0xO3crPShZYihnLlhiKzE5MDApP1piOiRiKVt6KytdKTtyZXR1cm4gaChnLmpjK3csMyl9LFwiJW1cIjpmdW5jdGlvbihnKXtyZXR1cm4gaChnLmVjK1xyXG4xLDIpfSxcIiVNXCI6ZnVuY3Rpb24oZyl7cmV0dXJuIGgoZy5LYywyKX0sXCIlblwiOmZ1bmN0aW9uKCl7cmV0dXJuXCJcXG5cIn0sXCIlcFwiOmZ1bmN0aW9uKGcpe3JldHVybiAwPD1nLmRjJiYxMj5nLmRjP1wiQU1cIjpcIlBNXCJ9LFwiJVNcIjpmdW5jdGlvbihnKXtyZXR1cm4gaChnLkxjLDIpfSxcIiV0XCI6ZnVuY3Rpb24oKXtyZXR1cm5cIlxcdFwifSxcIiV1XCI6ZnVuY3Rpb24oZyl7cmV0dXJuIGcuVGJ8fDd9LFwiJVVcIjpmdW5jdGlvbihnKXtyZXR1cm4gaChNYXRoLmZsb29yKChnLldiKzctZy5UYikvNyksMil9LFwiJVZcIjpmdW5jdGlvbihnKXt2YXIgdz1NYXRoLmZsb29yKChnLldiKzctKGcuVGIrNiklNykvNyk7Mj49KGcuVGIrMzcxLWcuV2ItMiklNyYmdysrO2lmKHcpNTM9PXcmJih6PShnLlRiKzM3MS1nLldiKSU3LDQ9PXp8fDM9PXomJlliKGcuWGIpfHwodz0xKSk7ZWxzZXt3PTUyO3ZhciB6PShnLlRiKzctZy5XYi0xKSU3Oyg0PT16fHw1PT16JiZZYihnLlhiJTQwMC0xKSkmJncrK31yZXR1cm4gaCh3LFxyXG4yKX0sXCIld1wiOmZ1bmN0aW9uKGcpe3JldHVybiBnLlRifSxcIiVXXCI6ZnVuY3Rpb24oZyl7cmV0dXJuIGgoTWF0aC5mbG9vcigoZy5XYis3LShnLlRiKzYpJTcpLzcpLDIpfSxcIiV5XCI6ZnVuY3Rpb24oZyl7cmV0dXJuKGcuWGIrMTkwMCkudG9TdHJpbmcoKS5zdWJzdHJpbmcoMil9LFwiJVlcIjpmdW5jdGlvbihnKXtyZXR1cm4gZy5YYisxOTAwfSxcIiV6XCI6ZnVuY3Rpb24oZyl7Zz1nLkpjO3ZhciB3PTA8PWc7Zz1NYXRoLmFicyhnKS82MDtyZXR1cm4odz9cIitcIjpcIi1cIikrU3RyaW5nKFwiMDAwMFwiKyhnLzYwKjEwMCtnJTYwKSkuc2xpY2UoLTQpfSxcIiVaXCI6ZnVuY3Rpb24oZyl7cmV0dXJuIGcuTWN9LFwiJSVcIjpmdW5jdGlvbigpe3JldHVyblwiJVwifX07Yz1jLnJlcGxhY2UoLyUlL2csXCJcXHgwMFxceDAwXCIpO2ZvcihBIGluIHQpYy5pbmNsdWRlcyhBKSYmKGM9Yy5yZXBsYWNlKG5ldyBSZWdFeHAoQSxcImdcIiksdFtBXShlKSkpO2M9Yy5yZXBsYWNlKC9cXDBcXDAvZyxcIiVcIik7QT1hYyhjKTtpZihBLmxlbmd0aD5cclxuYilyZXR1cm4gMDtmYihBLGEpO3JldHVybiBBLmxlbmd0aC0xfVAuZmMoKTtcclxudmFyIGNjPVtudWxsLFNhLFVhLGxiLG5iLG9iLHBiLHFiLHJiLHNiLHRiLHViLHZiLHdiLHhiLHliLHpiLENiLERiLEdiLFFiLFJiLFNiLFRiLFViLFZiXSxQYz17YjpmdW5jdGlvbihhKXtyZXR1cm4gRmIoYSsyNCkrMjR9LG46ZnVuY3Rpb24oYSl7YT1uZXcgWChhKTthLnVjKCl8fChhLmhjKCEwKSxoYi0tKTthLmljKCExKTtnYi5wdXNoKGEpO2Euc2MoKTtyZXR1cm4gYS52YygpfSxtYTpmdW5jdGlvbihhKXtHKFwiVW5leHBlY3RlZCBleGNlcHRpb24gdGhyb3duLCB0aGlzIGlzIG5vdCBwcm9wZXJseSBzdXBwb3J0ZWQgLSBhYm9ydGluZ1wiKTt4YT0hMDt0aHJvdyBhO30seDpmdW5jdGlvbigpe1ooMCk7dmFyIGE9Z2IucG9wKCk7aWYoYS5IYygpJiYhYS5rYygpKXt2YXIgYj1hLkRjKCk7YiYmVihiKShhLlpiKTtqYihhLlpiKX1XPTB9LGU6ZnVuY3Rpb24oKXt2YXIgYT1XO2lmKCFhKXJldHVybiBZPTA7dmFyIGI9bmV3IFgoYSk7Yi5jYyhhKTt2YXIgYz1iLmJjKCk7aWYoIWMpcmV0dXJuIFk9XHJcbjAsYTtmb3IodmFyIGU9QXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKSxmPTA7ZjxlLmxlbmd0aDtmKyspe3ZhciBoPWVbZl07aWYoMD09PWh8fGg9PT1jKWJyZWFrO2lmKGRjKGgsYyxiLlNiKzE2KSlyZXR1cm4gWT1oLGF9WT1jO3JldHVybiBhfSxsOmZ1bmN0aW9uKCl7dmFyIGE9VztpZighYSlyZXR1cm4gWT0wO3ZhciBiPW5ldyBYKGEpO2IuY2MoYSk7dmFyIGM9Yi5iYygpO2lmKCFjKXJldHVybiBZPTAsYTtmb3IodmFyIGU9QXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKSxmPTA7ZjxlLmxlbmd0aDtmKyspe3ZhciBoPWVbZl07aWYoMD09PWh8fGg9PT1jKWJyZWFrO2lmKGRjKGgsYyxiLlNiKzE2KSlyZXR1cm4gWT1oLGF9WT1jO3JldHVybiBhfSxoOmZ1bmN0aW9uKCl7dmFyIGE9VztpZighYSlyZXR1cm4gWT0wO3ZhciBiPW5ldyBYKGEpO2IuY2MoYSk7dmFyIGM9Yi5iYygpO2lmKCFjKXJldHVybiBZPTAsYTtmb3IodmFyIGU9QXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKSxcclxuZj0wO2Y8ZS5sZW5ndGg7ZisrKXt2YXIgaD1lW2ZdO2lmKDA9PT1ofHxoPT09YylicmVhaztpZihkYyhoLGMsYi5TYisxNikpcmV0dXJuIFk9aCxhfVk9YztyZXR1cm4gYX0sdDpqYixNOmZ1bmN0aW9uKCl7dmFyIGE9Z2IucG9wKCk7YXx8SShcIm5vIGV4Y2VwdGlvbiB0byB0aHJvd1wiKTt2YXIgYj1hLlpiO2Eua2MoKXx8KGdiLnB1c2goYSksYS5pYyghMCksYS5oYyghMSksaGIrKyk7Vz1iO3Rocm93IGI7fSxjOmZ1bmN0aW9uKGEsYixjKXsobmV3IFgoYSkpLmZjKGIsYyk7Vz1hO2hiKys7dGhyb3cgYTt9LHBhOmZ1bmN0aW9uKCl7cmV0dXJuIGhifSxGYTpmdW5jdGlvbihhKXtlYyhhLCF5LDEsIW1hKTtQLnBjKCl9LFQ6ZnVuY3Rpb24oYSl7Qz9wb3N0TWVzc2FnZSh7Y21kOlwiY2xlYW51cFRocmVhZFwiLHRocmVhZDphfSk6UWEoYSl9LHhhOm1iLGo6ZnVuY3Rpb24oYSl7V3x8KFc9YSk7dGhyb3cgYTt9LEg6bmIsTWE6b2IsdWE6cGIsd2E6cWIsb2E6cmIsS2E6c2IsQ2E6dGIsSmE6dWIsXHJcblY6dmIsdmE6d2Isc2E6eGIsTGE6eWIsdGE6emIsVGE6ZnVuY3Rpb24oKXt9LFg6ZnVuY3Rpb24oKXtJKFwiVG8gdXNlIGRsb3BlbiwgeW91IG5lZWQgZW5hYmxlIGR5bmFtaWMgbGlua2luZywgc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9lbXNjcmlwdGVuLWNvcmUvZW1zY3JpcHRlbi93aWtpL0xpbmtpbmdcIil9LFVhOmZ1bmN0aW9uKCl7SShcIlRvIHVzZSBkbG9wZW4sIHlvdSBuZWVkIGVuYWJsZSBkeW5hbWljIGxpbmtpbmcsIHNlZSBodHRwczovL2dpdGh1Yi5jb20vZW1zY3JpcHRlbi1jb3JlL2Vtc2NyaXB0ZW4vd2lraS9MaW5raW5nXCIpfSxXOmZ1bmN0aW9uKCl7cmV0dXJuIERhdGUubm93KCl9LHlhOmZ1bmN0aW9uKCl7cmV0dXJuIDIwOTcxNTJ9LE9hOmZ1bmN0aW9uKCl7cmV0dXJuITB9LHphOmZ1bmN0aW9uKGEsYixjLGUpe2lmKGE9PWIpc2V0VGltZW91dCgoKT0+YWIoZSkpO2Vsc2UgaWYoQylwb3N0TWVzc2FnZSh7dGFyZ2V0VGhyZWFkOmEsY21kOlwicHJvY2Vzc1Byb3h5aW5nUXVldWVcIixcclxucXVldWU6ZX0pO2Vsc2V7YT1QLlZiW2FdO2lmKCFhKXJldHVybjthLnBvc3RNZXNzYWdlKHtjbWQ6XCJwcm9jZXNzUHJveHlpbmdRdWV1ZVwiLHF1ZXVlOmV9KX1yZXR1cm4gMX0sRWE6ZnVuY3Rpb24oKXtyZXR1cm4tMX0sUGE6ZnVuY3Rpb24oYSxiKXthPW5ldyBEYXRlKDFFMypCYihhKSk7cigpW2I+PjI+Pj4wXT1hLmdldFVUQ1NlY29uZHMoKTtyKClbYis0Pj4yPj4+MF09YS5nZXRVVENNaW51dGVzKCk7cigpW2IrOD4+Mj4+PjBdPWEuZ2V0VVRDSG91cnMoKTtyKClbYisxMj4+Mj4+PjBdPWEuZ2V0VVRDRGF0ZSgpO3IoKVtiKzE2Pj4yPj4+MF09YS5nZXRVVENNb250aCgpO3IoKVtiKzIwPj4yPj4+MF09YS5nZXRVVENGdWxsWWVhcigpLTE5MDA7cigpW2IrMjQ+PjI+Pj4wXT1hLmdldFVUQ0RheSgpO2E9KGEuZ2V0VGltZSgpLURhdGUuVVRDKGEuZ2V0VVRDRnVsbFllYXIoKSwwLDEsMCwwLDAsMCkpLzg2NEU1fDA7cigpW2IrMjg+PjI+Pj4wXT1hfSxRYTpmdW5jdGlvbihhLGIpe2E9XHJcbm5ldyBEYXRlKDFFMypCYihhKSk7cigpW2I+PjI+Pj4wXT1hLmdldFNlY29uZHMoKTtyKClbYis0Pj4yPj4+MF09YS5nZXRNaW51dGVzKCk7cigpW2IrOD4+Mj4+PjBdPWEuZ2V0SG91cnMoKTtyKClbYisxMj4+Mj4+PjBdPWEuZ2V0RGF0ZSgpO3IoKVtiKzE2Pj4yPj4+MF09YS5nZXRNb250aCgpO3IoKVtiKzIwPj4yPj4+MF09YS5nZXRGdWxsWWVhcigpLTE5MDA7cigpW2IrMjQ+PjI+Pj4wXT1hLmdldERheSgpO3ZhciBjPW5ldyBEYXRlKGEuZ2V0RnVsbFllYXIoKSwwLDEpLGU9KGEuZ2V0VGltZSgpLWMuZ2V0VGltZSgpKS84NjRFNXwwO3IoKVtiKzI4Pj4yPj4+MF09ZTtyKClbYiszNj4+Mj4+PjBdPS0oNjAqYS5nZXRUaW1lem9uZU9mZnNldCgpKTtlPShuZXcgRGF0ZShhLmdldEZ1bGxZZWFyKCksNiwxKSkuZ2V0VGltZXpvbmVPZmZzZXQoKTtjPWMuZ2V0VGltZXpvbmVPZmZzZXQoKTthPShlIT1jJiZhLmdldFRpbWV6b25lT2Zmc2V0KCk9PU1hdGgubWluKGMsZSkpfDA7cigpW2IrXHJcbjMyPj4yPj4+MF09YX0sUmE6ZnVuY3Rpb24oYSl7dmFyIGI9bmV3IERhdGUocigpW2ErMjA+PjI+Pj4wXSsxOTAwLHIoKVthKzE2Pj4yPj4+MF0scigpW2ErMTI+PjI+Pj4wXSxyKClbYSs4Pj4yPj4+MF0scigpW2ErND4+Mj4+PjBdLHIoKVthPj4yPj4+MF0sMCksYz1yKClbYSszMj4+Mj4+PjBdLGU9Yi5nZXRUaW1lem9uZU9mZnNldCgpLGY9bmV3IERhdGUoYi5nZXRGdWxsWWVhcigpLDAsMSksaD0obmV3IERhdGUoYi5nZXRGdWxsWWVhcigpLDYsMSkpLmdldFRpbWV6b25lT2Zmc2V0KCksaz1mLmdldFRpbWV6b25lT2Zmc2V0KCksbD1NYXRoLm1pbihrLGgpOzA+Yz9yKClbYSszMj4+Mj4+PjBdPU51bWJlcihoIT1rJiZsPT1lKTowPGMhPShsPT1lKSYmKGg9TWF0aC5tYXgoayxoKSxiLnNldFRpbWUoYi5nZXRUaW1lKCkrNkU0KigoMDxjP2w6aCktZSkpKTtyKClbYSsyND4+Mj4+PjBdPWIuZ2V0RGF5KCk7Yz0oYi5nZXRUaW1lKCktZi5nZXRUaW1lKCkpLzg2NEU1fDA7cigpW2ErMjg+PlxyXG4yPj4+MF09YztyKClbYT4+Mj4+PjBdPWIuZ2V0U2Vjb25kcygpO3IoKVthKzQ+PjI+Pj4wXT1iLmdldE1pbnV0ZXMoKTtyKClbYSs4Pj4yPj4+MF09Yi5nZXRIb3VycygpO3IoKVthKzEyPj4yPj4+MF09Yi5nZXREYXRlKCk7cigpW2ErMTY+PjI+Pj4wXT1iLmdldE1vbnRoKCk7cmV0dXJuIGIuZ2V0VGltZSgpLzFFM3wwfSxBYTpDYixCYTpEYixTYTpIYix5OmZ1bmN0aW9uKCl7SShcIlwiKX0sVTpmdW5jdGlvbigpe2lmKCFCJiYheSl7dmFyIGE9XCJCbG9ja2luZyBvbiB0aGUgbWFpbiB0aHJlYWQgaXMgdmVyeSBkYW5nZXJvdXMsIHNlZSBodHRwczovL2Vtc2NyaXB0ZW4ub3JnL2RvY3MvcG9ydGluZy9wdGhyZWFkcy5odG1sI2Jsb2NraW5nLW9uLXRoZS1tYWluLWJyb3dzZXItdGhyZWFkXCI7SWJ8fChJYj17fSk7SWJbYV18fChJYlthXT0xLEImJihhPVwid2FybmluZzogXCIrYSksRyhhKSl9fSxyYTpmdW5jdGlvbigpe3JldHVybiA0Mjk0OTAxNzYwfSxCOkpiLElhOmZ1bmN0aW9uKGEsYixcclxuYyl7cSgpLmNvcHlXaXRoaW4oYT4+PjAsYj4+PjAsYitjPj4+MCl9LEY6ZnVuY3Rpb24oKXtyZXR1cm4gQj9yZXF1aXJlKFwib3NcIikuY3B1cygpLmxlbmd0aDpuYXZpZ2F0b3IuaGFyZHdhcmVDb25jdXJyZW5jeX0sRGE6ZnVuY3Rpb24oYSxiLGMpe01iLmxlbmd0aD1iO2M+Pj0zO2Zvcih2YXIgZT0wO2U8YjtlKyspTWJbZV09ZWEoKVtjK2U+Pj4wXTtyZXR1cm4oMD5hP1BhWy1hLTFdOmNjW2FdKS5hcHBseShudWxsLE1iKX0scWE6ZnVuY3Rpb24oYSl7dmFyIGI9cSgpLmxlbmd0aDthPj4+PTA7aWYoYTw9Ynx8NDI5NDkwMTc2MDxhKXJldHVybiExO2Zvcih2YXIgYz0xOzQ+PWM7Yyo9Mil7dmFyIGU9YiooMSsuMi9jKTtlPU1hdGgubWluKGUsYSsxMDA2NjMyOTYpO3ZhciBmPU1hdGg7ZT1NYXRoLm1heChhLGUpO2Y9Zi5taW4uY2FsbChmLDQyOTQ5MDE3NjAsZSsoNjU1MzYtZSU2NTUzNiklNjU1MzYpO2E6e3RyeXttLmdyb3coZi1uLmJ5dGVMZW5ndGgrNjU1MzU+Pj4xNik7cChtLmJ1ZmZlcik7XHJcbnZhciBoPTE7YnJlYWsgYX1jYXRjaChrKXt9aD12b2lkIDB9aWYoaClyZXR1cm4hMH1yZXR1cm4hMX0sTmE6ZnVuY3Rpb24oKXt0aHJvd1widW53aW5kXCI7fSxHYTpRYixIYTpSYixKOlRhLEk6U2IsUzpUYixnYTpVYixSOlZiLGQ6ZnVuY3Rpb24oKXtyZXR1cm4gWX0sbmE6WGIsaWE6ZmMsamE6Z2MsSzpoYyxmOmljLFA6amMsUTprYyxrOmxjLHA6bWMscTpuYyxOOm9jLHM6cGMsdzpxYyxMOnJjLEU6c2MsYWE6dGMsXzp1YyxaOnZjLGNhOndjLCQ6eGMsYmE6eWMsWTp6YyxnOkFjLHI6QmMsaTpDYyxoYTpEYyxtOkVjLHY6RmMsdTpHYyxPOkhjLEE6SWMsa2E6SmMsQzpLYyxEOkxjLGZhOk1jLGRhOk5jLGVhOk9jLG86ZnVuY3Rpb24oYSl7cmV0dXJuIGF9LGE6bXx8eC53YXNtTWVtb3J5LEc6ZnVuY3Rpb24oYSl7WT1hfSxsYTpiYyx6OmZ1bmN0aW9uKGEsYixjLGUpe3JldHVybiBiYyhhLGIsYyxlKX19O1xyXG4oZnVuY3Rpb24oKXtmdW5jdGlvbiBhKGYsaCl7eC5hc209Zi5leHBvcnRzO1AucWMucHVzaCh4LmFzbS5zYik7RWE9eC5hc20udWI7R2EudW5zaGlmdCh4LmFzbS5WYSk7d2E9aDtDfHwoTC0tLHgubW9uaXRvclJ1bkRlcGVuZGVuY2llcyYmeC5tb25pdG9yUnVuRGVwZW5kZW5jaWVzKEwpLDA9PUwmJihudWxsIT09TGEmJihjbGVhckludGVydmFsKExhKSxMYT1udWxsKSxNJiYoZj1NLE09bnVsbCxmKCkpKSl9ZnVuY3Rpb24gYihmKXthKGYuaW5zdGFuY2UsZi5tb2R1bGUpfWZ1bmN0aW9uIGMoZil7cmV0dXJuIE9hKCkudGhlbihmdW5jdGlvbihoKXtyZXR1cm4gV2ViQXNzZW1ibHkuaW5zdGFudGlhdGUoaCxlKX0pLnRoZW4oZnVuY3Rpb24oaCl7cmV0dXJuIGh9KS50aGVuKGYsZnVuY3Rpb24oaCl7RyhcImZhaWxlZCB0byBhc3luY2hyb25vdXNseSBwcmVwYXJlIHdhc206IFwiK2gpO0koaCl9KX12YXIgZT17YTpQY307Q3x8KEwrKyx4Lm1vbml0b3JSdW5EZXBlbmRlbmNpZXMmJngubW9uaXRvclJ1bkRlcGVuZGVuY2llcyhMKSk7XHJcbmlmKHguaW5zdGFudGlhdGVXYXNtKXRyeXtyZXR1cm4geC5pbnN0YW50aWF0ZVdhc20oZSxhKX1jYXRjaChmKXtyZXR1cm4gRyhcIk1vZHVsZS5pbnN0YW50aWF0ZVdhc20gY2FsbGJhY2sgZmFpbGVkIHdpdGggZXJyb3I6IFwiK2YpLCExfShmdW5jdGlvbigpe3JldHVybiBIfHxcImZ1bmN0aW9uXCIhPXR5cGVvZiBXZWJBc3NlbWJseS5pbnN0YW50aWF0ZVN0cmVhbWluZ3x8TWEoKXx8Ty5zdGFydHNXaXRoKFwiZmlsZTovL1wiKXx8Qnx8XCJmdW5jdGlvblwiIT10eXBlb2YgZmV0Y2g/YyhiKTpmZXRjaChPLHtjcmVkZW50aWFsczpcInNhbWUtb3JpZ2luXCJ9KS50aGVuKGZ1bmN0aW9uKGYpe3JldHVybiBXZWJBc3NlbWJseS5pbnN0YW50aWF0ZVN0cmVhbWluZyhmLGUpLnRoZW4oYixmdW5jdGlvbihoKXtHKFwid2FzbSBzdHJlYW1pbmcgY29tcGlsZSBmYWlsZWQ6IFwiK2gpO0coXCJmYWxsaW5nIGJhY2sgdG8gQXJyYXlCdWZmZXIgaW5zdGFudGlhdGlvblwiKTtyZXR1cm4gYyhiKX0pfSl9KSgpLmNhdGNoKGlhKTtcclxucmV0dXJue319KSgpO3guX19fd2FzbV9jYWxsX2N0b3JzPWZ1bmN0aW9uKCl7cmV0dXJuKHguX19fd2FzbV9jYWxsX2N0b3JzPXguYXNtLlZhKS5hcHBseShudWxsLGFyZ3VtZW50cyl9O3guX09ydEluaXQ9ZnVuY3Rpb24oKXtyZXR1cm4oeC5fT3J0SW5pdD14LmFzbS5XYSkuYXBwbHkobnVsbCxhcmd1bWVudHMpfTt4Ll9PcnRDcmVhdGVTZXNzaW9uT3B0aW9ucz1mdW5jdGlvbigpe3JldHVybih4Ll9PcnRDcmVhdGVTZXNzaW9uT3B0aW9ucz14LmFzbS5YYSkuYXBwbHkobnVsbCxhcmd1bWVudHMpfTt4Ll9PcnRBcHBlbmRFeGVjdXRpb25Qcm92aWRlcj1mdW5jdGlvbigpe3JldHVybih4Ll9PcnRBcHBlbmRFeGVjdXRpb25Qcm92aWRlcj14LmFzbS5ZYSkuYXBwbHkobnVsbCxhcmd1bWVudHMpfTt4Ll9PcnRBZGRTZXNzaW9uQ29uZmlnRW50cnk9ZnVuY3Rpb24oKXtyZXR1cm4oeC5fT3J0QWRkU2Vzc2lvbkNvbmZpZ0VudHJ5PXguYXNtLlphKS5hcHBseShudWxsLGFyZ3VtZW50cyl9O1xyXG54Ll9PcnRSZWxlYXNlU2Vzc2lvbk9wdGlvbnM9ZnVuY3Rpb24oKXtyZXR1cm4oeC5fT3J0UmVsZWFzZVNlc3Npb25PcHRpb25zPXguYXNtLl9hKS5hcHBseShudWxsLGFyZ3VtZW50cyl9O3guX09ydENyZWF0ZVNlc3Npb249ZnVuY3Rpb24oKXtyZXR1cm4oeC5fT3J0Q3JlYXRlU2Vzc2lvbj14LmFzbS4kYSkuYXBwbHkobnVsbCxhcmd1bWVudHMpfTt4Ll9PcnRSZWxlYXNlU2Vzc2lvbj1mdW5jdGlvbigpe3JldHVybih4Ll9PcnRSZWxlYXNlU2Vzc2lvbj14LmFzbS5hYikuYXBwbHkobnVsbCxhcmd1bWVudHMpfTt4Ll9PcnRHZXRJbnB1dENvdW50PWZ1bmN0aW9uKCl7cmV0dXJuKHguX09ydEdldElucHV0Q291bnQ9eC5hc20uYmIpLmFwcGx5KG51bGwsYXJndW1lbnRzKX07eC5fT3J0R2V0T3V0cHV0Q291bnQ9ZnVuY3Rpb24oKXtyZXR1cm4oeC5fT3J0R2V0T3V0cHV0Q291bnQ9eC5hc20uY2IpLmFwcGx5KG51bGwsYXJndW1lbnRzKX07XHJcbnguX09ydEdldElucHV0TmFtZT1mdW5jdGlvbigpe3JldHVybih4Ll9PcnRHZXRJbnB1dE5hbWU9eC5hc20uZGIpLmFwcGx5KG51bGwsYXJndW1lbnRzKX07eC5fT3J0R2V0T3V0cHV0TmFtZT1mdW5jdGlvbigpe3JldHVybih4Ll9PcnRHZXRPdXRwdXROYW1lPXguYXNtLmViKS5hcHBseShudWxsLGFyZ3VtZW50cyl9O3guX09ydEZyZWU9ZnVuY3Rpb24oKXtyZXR1cm4oeC5fT3J0RnJlZT14LmFzbS5mYikuYXBwbHkobnVsbCxhcmd1bWVudHMpfTt4Ll9PcnRDcmVhdGVUZW5zb3I9ZnVuY3Rpb24oKXtyZXR1cm4oeC5fT3J0Q3JlYXRlVGVuc29yPXguYXNtLmdiKS5hcHBseShudWxsLGFyZ3VtZW50cyl9O3guX09ydEdldFRlbnNvckRhdGE9ZnVuY3Rpb24oKXtyZXR1cm4oeC5fT3J0R2V0VGVuc29yRGF0YT14LmFzbS5oYikuYXBwbHkobnVsbCxhcmd1bWVudHMpfTtcclxueC5fT3J0UmVsZWFzZVRlbnNvcj1mdW5jdGlvbigpe3JldHVybih4Ll9PcnRSZWxlYXNlVGVuc29yPXguYXNtLmliKS5hcHBseShudWxsLGFyZ3VtZW50cyl9O3guX09ydENyZWF0ZVJ1bk9wdGlvbnM9ZnVuY3Rpb24oKXtyZXR1cm4oeC5fT3J0Q3JlYXRlUnVuT3B0aW9ucz14LmFzbS5qYikuYXBwbHkobnVsbCxhcmd1bWVudHMpfTt4Ll9PcnRBZGRSdW5Db25maWdFbnRyeT1mdW5jdGlvbigpe3JldHVybih4Ll9PcnRBZGRSdW5Db25maWdFbnRyeT14LmFzbS5rYikuYXBwbHkobnVsbCxhcmd1bWVudHMpfTt4Ll9PcnRSZWxlYXNlUnVuT3B0aW9ucz1mdW5jdGlvbigpe3JldHVybih4Ll9PcnRSZWxlYXNlUnVuT3B0aW9ucz14LmFzbS5sYikuYXBwbHkobnVsbCxhcmd1bWVudHMpfTt4Ll9PcnRSdW49ZnVuY3Rpb24oKXtyZXR1cm4oeC5fT3J0UnVuPXguYXNtLm1iKS5hcHBseShudWxsLGFyZ3VtZW50cyl9O1xyXG54Ll9PcnRFbmRQcm9maWxpbmc9ZnVuY3Rpb24oKXtyZXR1cm4oeC5fT3J0RW5kUHJvZmlsaW5nPXguYXNtLm5iKS5hcHBseShudWxsLGFyZ3VtZW50cyl9O3ZhciAkYT14Ll9wdGhyZWFkX3NlbGY9ZnVuY3Rpb24oKXtyZXR1cm4oJGE9eC5fcHRocmVhZF9zZWxmPXguYXNtLm9iKS5hcHBseShudWxsLGFyZ3VtZW50cyl9LEZiPXguX21hbGxvYz1mdW5jdGlvbigpe3JldHVybihGYj14Ll9tYWxsb2M9eC5hc20ucGIpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sa2I9eC5fZnJlZT1mdW5jdGlvbigpe3JldHVybihrYj14Ll9mcmVlPXguYXNtLnFiKS5hcHBseShudWxsLGFyZ3VtZW50cyl9LFdhPXguX2ZmbHVzaD1mdW5jdGlvbigpe3JldHVybihXYT14Ll9mZmx1c2g9eC5hc20ucmIpLmFwcGx5KG51bGwsYXJndW1lbnRzKX07eC5fX2Vtc2NyaXB0ZW5fdGxzX2luaXQ9ZnVuY3Rpb24oKXtyZXR1cm4oeC5fX2Vtc2NyaXB0ZW5fdGxzX2luaXQ9eC5hc20uc2IpLmFwcGx5KG51bGwsYXJndW1lbnRzKX07XHJcbnZhciBWYT14Ll9fX2Z1bmNzX29uX2V4aXQ9ZnVuY3Rpb24oKXtyZXR1cm4oVmE9eC5fX19mdW5jc19vbl9leGl0PXguYXNtLnRiKS5hcHBseShudWxsLGFyZ3VtZW50cyl9LGVjPXguX19lbXNjcmlwdGVuX3RocmVhZF9pbml0PWZ1bmN0aW9uKCl7cmV0dXJuKGVjPXguX19lbXNjcmlwdGVuX3RocmVhZF9pbml0PXguYXNtLnZiKS5hcHBseShudWxsLGFyZ3VtZW50cyl9O3guX19lbXNjcmlwdGVuX3RocmVhZF9jcmFzaGVkPWZ1bmN0aW9uKCl7cmV0dXJuKHguX19lbXNjcmlwdGVuX3RocmVhZF9jcmFzaGVkPXguYXNtLndiKS5hcHBseShudWxsLGFyZ3VtZW50cyl9O1xyXG52YXIgTGI9eC5fZW1zY3JpcHRlbl9ydW5faW5fbWFpbl9ydW50aW1lX3RocmVhZF9qcz1mdW5jdGlvbigpe3JldHVybihMYj14Ll9lbXNjcmlwdGVuX3J1bl9pbl9tYWluX3J1bnRpbWVfdGhyZWFkX2pzPXguYXNtLnhiKS5hcHBseShudWxsLGFyZ3VtZW50cyl9LEFiPXguX19lbXNjcmlwdGVuX3Byb3h5X2V4ZWN1dGVfdGFza19xdWV1ZT1mdW5jdGlvbigpe3JldHVybihBYj14Ll9fZW1zY3JpcHRlbl9wcm94eV9leGVjdXRlX3Rhc2tfcXVldWU9eC5hc20ueWIpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sWmE9eC5fX2Vtc2NyaXB0ZW5fdGhyZWFkX2ZyZWVfZGF0YT1mdW5jdGlvbigpe3JldHVybihaYT14Ll9fZW1zY3JpcHRlbl90aHJlYWRfZnJlZV9kYXRhPXguYXNtLnpiKS5hcHBseShudWxsLGFyZ3VtZW50cyl9LGViPXguX19lbXNjcmlwdGVuX3RocmVhZF9leGl0PWZ1bmN0aW9uKCl7cmV0dXJuKGViPXguX19lbXNjcmlwdGVuX3RocmVhZF9leGl0PXguYXNtLkFiKS5hcHBseShudWxsLFxyXG5hcmd1bWVudHMpfSxaPXguX3NldFRocmV3PWZ1bmN0aW9uKCl7cmV0dXJuKFo9eC5fc2V0VGhyZXc9eC5hc20uQmIpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sY2I9eC5fZW1zY3JpcHRlbl9zdGFja19zZXRfbGltaXRzPWZ1bmN0aW9uKCl7cmV0dXJuKGNiPXguX2Vtc2NyaXB0ZW5fc3RhY2tfc2V0X2xpbWl0cz14LmFzbS5DYikuYXBwbHkobnVsbCxhcmd1bWVudHMpfSxTPXguc3RhY2tTYXZlPWZ1bmN0aW9uKCl7cmV0dXJuKFM9eC5zdGFja1NhdmU9eC5hc20uRGIpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sVT14LnN0YWNrUmVzdG9yZT1mdW5jdGlvbigpe3JldHVybihVPXguc3RhY2tSZXN0b3JlPXguYXNtLkViKS5hcHBseShudWxsLGFyZ3VtZW50cyl9LEtiPXguc3RhY2tBbGxvYz1mdW5jdGlvbigpe3JldHVybihLYj14LnN0YWNrQWxsb2M9eC5hc20uRmIpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sZGM9eC5fX19jeGFfY2FuX2NhdGNoPWZ1bmN0aW9uKCl7cmV0dXJuKGRjPXguX19fY3hhX2Nhbl9jYXRjaD1cclxueC5hc20uR2IpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0saWI9eC5fX19jeGFfaXNfcG9pbnRlcl90eXBlPWZ1bmN0aW9uKCl7cmV0dXJuKGliPXguX19fY3hhX2lzX3BvaW50ZXJfdHlwZT14LmFzbS5IYikuYXBwbHkobnVsbCxhcmd1bWVudHMpfSxRYz14LmR5bkNhbGxfaj1mdW5jdGlvbigpe3JldHVybihRYz14LmR5bkNhbGxfaj14LmFzbS5JYikuYXBwbHkobnVsbCxhcmd1bWVudHMpfSxSYz14LmR5bkNhbGxfaWlpaWlqPWZ1bmN0aW9uKCl7cmV0dXJuKFJjPXguZHluQ2FsbF9paWlpaWo9eC5hc20uSmIpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sU2M9eC5keW5DYWxsX2ppaT1mdW5jdGlvbigpe3JldHVybihTYz14LmR5bkNhbGxfamlpPXguYXNtLktiKS5hcHBseShudWxsLGFyZ3VtZW50cyl9LFRjPXguZHluQ2FsbF92aWlpaWlqPWZ1bmN0aW9uKCl7cmV0dXJuKFRjPXguZHluQ2FsbF92aWlpaWlqPXguYXNtLkxiKS5hcHBseShudWxsLGFyZ3VtZW50cyl9LFVjPXguZHluQ2FsbF92amppPVxyXG5mdW5jdGlvbigpe3JldHVybihVYz14LmR5bkNhbGxfdmpqaT14LmFzbS5NYikuYXBwbHkobnVsbCxhcmd1bWVudHMpfSxWYz14LmR5bkNhbGxfdmlpaWpqamlpPWZ1bmN0aW9uKCl7cmV0dXJuKFZjPXguZHluQ2FsbF92aWlpampqaWk9eC5hc20uTmIpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sV2M9eC5keW5DYWxsX2lpaj1mdW5jdGlvbigpe3JldHVybihXYz14LmR5bkNhbGxfaWlqPXguYXNtLk9iKS5hcHBseShudWxsLGFyZ3VtZW50cyl9LFhjPXguZHluQ2FsbF9qaT1mdW5jdGlvbigpe3JldHVybihYYz14LmR5bkNhbGxfamk9eC5hc20uUGIpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sWWM9eC5keW5DYWxsX2lpaWlpaWo9ZnVuY3Rpb24oKXtyZXR1cm4oWWM9eC5keW5DYWxsX2lpaWlpaWo9eC5hc20uUWIpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sWmM9eC5keW5DYWxsX2lpaWo9ZnVuY3Rpb24oKXtyZXR1cm4oWmM9eC5keW5DYWxsX2lpaWo9eC5hc20uUmIpLmFwcGx5KG51bGwsXHJcbmFyZ3VtZW50cyl9O2Z1bmN0aW9uIGljKGEsYil7dmFyIGM9UygpO3RyeXtyZXR1cm4gVihhKShiKX1jYXRjaChlKXtVKGMpO2lmKGUhPT1lKzApdGhyb3cgZTtaKDEsMCl9fWZ1bmN0aW9uIEJjKGEsYil7dmFyIGM9UygpO3RyeXtWKGEpKGIpfWNhdGNoKGUpe1UoYyk7aWYoZSE9PWUrMCl0aHJvdyBlO1ooMSwwKX19ZnVuY3Rpb24gQ2MoYSxiLGMpe3ZhciBlPVMoKTt0cnl7VihhKShiLGMpfWNhdGNoKGYpe1UoZSk7aWYoZiE9PWYrMCl0aHJvdyBmO1ooMSwwKX19ZnVuY3Rpb24gbGMoYSxiLGMpe3ZhciBlPVMoKTt0cnl7cmV0dXJuIFYoYSkoYixjKX1jYXRjaChmKXtVKGUpO2lmKGYhPT1mKzApdGhyb3cgZjtaKDEsMCl9fWZ1bmN0aW9uIG1jKGEsYixjLGUpe3ZhciBmPVMoKTt0cnl7cmV0dXJuIFYoYSkoYixjLGUpfWNhdGNoKGgpe1UoZik7aWYoaCE9PWgrMCl0aHJvdyBoO1ooMSwwKX19XHJcbmZ1bmN0aW9uIHFjKGEsYixjLGUsZixoLGspe3ZhciBsPVMoKTt0cnl7cmV0dXJuIFYoYSkoYixjLGUsZixoLGspfWNhdGNoKHUpe1UobCk7aWYodSE9PXUrMCl0aHJvdyB1O1ooMSwwKX19ZnVuY3Rpb24gQWMoYSl7dmFyIGI9UygpO3RyeXtWKGEpKCl9Y2F0Y2goYyl7VShiKTtpZihjIT09YyswKXRocm93IGM7WigxLDApfX1mdW5jdGlvbiBwYyhhLGIsYyxlLGYsaCl7dmFyIGs9UygpO3RyeXtyZXR1cm4gVihhKShiLGMsZSxmLGgpfWNhdGNoKGwpe1Uoayk7aWYobCE9PWwrMCl0aHJvdyBsO1ooMSwwKX19ZnVuY3Rpb24gbmMoYSxiLGMsZSxmKXt2YXIgaD1TKCk7dHJ5e3JldHVybiBWKGEpKGIsYyxlLGYpfWNhdGNoKGspe1UoaCk7aWYoayE9PWsrMCl0aHJvdyBrO1ooMSwwKX19ZnVuY3Rpb24gRWMoYSxiLGMsZSl7dmFyIGY9UygpO3RyeXtWKGEpKGIsYyxlKX1jYXRjaChoKXtVKGYpO2lmKGghPT1oKzApdGhyb3cgaDtaKDEsMCl9fVxyXG5mdW5jdGlvbiBHYyhhLGIsYyxlLGYsaCl7dmFyIGs9UygpO3RyeXtWKGEpKGIsYyxlLGYsaCl9Y2F0Y2gobCl7VShrKTtpZihsIT09bCswKXRocm93IGw7WigxLDApfX1mdW5jdGlvbiBGYyhhLGIsYyxlLGYpe3ZhciBoPVMoKTt0cnl7VihhKShiLGMsZSxmKX1jYXRjaChrKXtVKGgpO2lmKGshPT1rKzApdGhyb3cgaztaKDEsMCl9fWZ1bmN0aW9uIEljKGEsYixjLGUsZixoLGssbCl7dmFyIHU9UygpO3RyeXtWKGEpKGIsYyxlLGYsaCxrLGwpfWNhdGNoKHQpe1UodSk7aWYodCE9PXQrMCl0aHJvdyB0O1ooMSwwKX19ZnVuY3Rpb24ga2MoYSxiLGMpe3ZhciBlPVMoKTt0cnl7cmV0dXJuIFYoYSkoYixjKX1jYXRjaChmKXtVKGUpO2lmKGYhPT1mKzApdGhyb3cgZjtaKDEsMCl9fWZ1bmN0aW9uIGpjKGEsYixjKXt2YXIgZT1TKCk7dHJ5e3JldHVybiBWKGEpKGIsYyl9Y2F0Y2goZil7VShlKTtpZihmIT09ZiswKXRocm93IGY7WigxLDApfX1cclxuZnVuY3Rpb24gSmMoYSxiLGMsZSxmLGgsayxsLHUpe3ZhciB0PVMoKTt0cnl7VihhKShiLGMsZSxmLGgsayxsLHUpfWNhdGNoKEEpe1UodCk7aWYoQSE9PUErMCl0aHJvdyBBO1ooMSwwKX19ZnVuY3Rpb24gSGMoYSxiLGMsZSxmLGgsayl7dmFyIGw9UygpO3RyeXtWKGEpKGIsYyxlLGYsaCxrKX1jYXRjaCh1KXtVKGwpO2lmKHUhPT11KzApdGhyb3cgdTtaKDEsMCl9fWZ1bmN0aW9uIG9jKGEsYixjLGUsZixoKXt2YXIgaz1TKCk7dHJ5e3JldHVybiBWKGEpKGIsYyxlLGYsaCl9Y2F0Y2gobCl7VShrKTtpZihsIT09bCswKXRocm93IGw7WigxLDApfX1mdW5jdGlvbiByYyhhLGIsYyxlLGYsaCxrLGwpe3ZhciB1PVMoKTt0cnl7cmV0dXJuIFYoYSkoYixjLGUsZixoLGssbCl9Y2F0Y2godCl7VSh1KTtpZih0IT09dCswKXRocm93IHQ7WigxLDApfX1cclxuZnVuY3Rpb24gc2MoYSxiLGMsZSxmLGgsayxsLHUsdCxBLEspe3ZhciBKPVMoKTt0cnl7cmV0dXJuIFYoYSkoYixjLGUsZixoLGssbCx1LHQsQSxLKX1jYXRjaChnKXtVKEopO2lmKGchPT1nKzApdGhyb3cgZztaKDEsMCl9fWZ1bmN0aW9uIEtjKGEsYixjLGUsZixoLGssbCx1LHQsQSl7dmFyIEs9UygpO3RyeXtWKGEpKGIsYyxlLGYsaCxrLGwsdSx0LEEpfWNhdGNoKEope1UoSyk7aWYoSiE9PUorMCl0aHJvdyBKO1ooMSwwKX19ZnVuY3Rpb24gTGMoYSxiLGMsZSxmLGgsayxsLHUsdCxBLEssSixnLHcseil7dmFyIE49UygpO3RyeXtWKGEpKGIsYyxlLGYsaCxrLGwsdSx0LEEsSyxKLGcsdyx6KX1jYXRjaChUKXtVKE4pO2lmKFQhPT1UKzApdGhyb3cgVDtaKDEsMCl9fWZ1bmN0aW9uIGhjKGEpe3ZhciBiPVMoKTt0cnl7cmV0dXJuIFYoYSkoKX1jYXRjaChjKXtVKGIpO2lmKGMhPT1jKzApdGhyb3cgYztaKDEsMCl9fVxyXG5mdW5jdGlvbiBnYyhhLGIsYyl7dmFyIGU9UygpO3RyeXtyZXR1cm4gVihhKShiLGMpfWNhdGNoKGYpe1UoZSk7aWYoZiE9PWYrMCl0aHJvdyBmO1ooMSwwKX19ZnVuY3Rpb24gZmMoYSxiLGMpe3ZhciBlPVMoKTt0cnl7cmV0dXJuIFYoYSkoYixjKX1jYXRjaChmKXtVKGUpO2lmKGYhPT1mKzApdGhyb3cgZjtaKDEsMCl9fWZ1bmN0aW9uIERjKGEsYixjLGUpe3ZhciBmPVMoKTt0cnl7VihhKShiLGMsZSl9Y2F0Y2goaCl7VShmKTtpZihoIT09aCswKXRocm93IGg7WigxLDApfX1mdW5jdGlvbiBNYyhhLGIsYyxlLGYsaCxrLGwpe3ZhciB1PVMoKTt0cnl7VGMoYSxiLGMsZSxmLGgsayxsKX1jYXRjaCh0KXtVKHUpO2lmKHQhPT10KzApdGhyb3cgdDtaKDEsMCl9fWZ1bmN0aW9uIE9jKGEsYixjLGUsZixoKXt2YXIgaz1TKCk7dHJ5e1VjKGEsYixjLGUsZixoKX1jYXRjaChsKXtVKGspO2lmKGwhPT1sKzApdGhyb3cgbDtaKDEsMCl9fVxyXG5mdW5jdGlvbiBOYyhhLGIsYyxlLGYsaCxrLGwsdSx0LEEsSyl7dmFyIEo9UygpO3RyeXtWYyhhLGIsYyxlLGYsaCxrLGwsdSx0LEEsSyl9Y2F0Y2goZyl7VShKKTtpZihnIT09ZyswKXRocm93IGc7WigxLDApfX1mdW5jdGlvbiB3YyhhLGIsYyxlKXt2YXIgZj1TKCk7dHJ5e3JldHVybiBXYyhhLGIsYyxlKX1jYXRjaChoKXtVKGYpO2lmKGghPT1oKzApdGhyb3cgaDtaKDEsMCl9fWZ1bmN0aW9uIHljKGEsYil7dmFyIGM9UygpO3RyeXtyZXR1cm4gWGMoYSxiKX1jYXRjaChlKXtVKGMpO2lmKGUhPT1lKzApdGhyb3cgZTtaKDEsMCl9fWZ1bmN0aW9uIHRjKGEsYixjLGUsZixoLGssbCl7dmFyIHU9UygpO3RyeXtyZXR1cm4gWWMoYSxiLGMsZSxmLGgsayxsKX1jYXRjaCh0KXtVKHUpO2lmKHQhPT10KzApdGhyb3cgdDtaKDEsMCl9fWZ1bmN0aW9uIHhjKGEpe3ZhciBiPVMoKTt0cnl7cmV0dXJuIFFjKGEpfWNhdGNoKGMpe1UoYik7aWYoYyE9PWMrMCl0aHJvdyBjO1ooMSwwKX19XHJcbmZ1bmN0aW9uIHVjKGEsYixjLGUsZixoLGspe3ZhciBsPVMoKTt0cnl7cmV0dXJuIFJjKGEsYixjLGUsZixoLGspfWNhdGNoKHUpe1UobCk7aWYodSE9PXUrMCl0aHJvdyB1O1ooMSwwKX19ZnVuY3Rpb24gdmMoYSxiLGMsZSxmKXt2YXIgaD1TKCk7dHJ5e3JldHVybiBaYyhhLGIsYyxlLGYpfWNhdGNoKGspe1UoaCk7aWYoayE9PWsrMCl0aHJvdyBrO1ooMSwwKX19ZnVuY3Rpb24gemMoYSxiLGMpe3ZhciBlPVMoKTt0cnl7cmV0dXJuIFNjKGEsYixjKX1jYXRjaChmKXtVKGUpO2lmKGYhPT1mKzApdGhyb3cgZjtaKDEsMCl9fXguVVRGOFRvU3RyaW5nPUFhO3guc3RyaW5nVG9VVEY4PWZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gQmEoYSxxKCksYixjKX07eC5sZW5ndGhCeXRlc1VURjg9Q2E7eC5rZWVwUnVudGltZUFsaXZlPUY7eC53YXNtTWVtb3J5PW07eC5zdGFja1NhdmU9Uzt4LnN0YWNrUmVzdG9yZT1VO3guc3RhY2tBbGxvYz1LYjt4LkV4aXRTdGF0dXM9RTt4LlBUaHJlYWQ9UDt2YXIgJGM7XHJcbk09ZnVuY3Rpb24gYWQoKXskY3x8YmQoKTskY3x8KE09YWQpfTtcclxuZnVuY3Rpb24gYmQoKXtmdW5jdGlvbiBhKCl7aWYoISRjJiYoJGM9ITAseC5jYWxsZWRSdW49ITAsIXhhKSl7Q3x8UihHYSk7aGEoeCk7aWYoeC5vblJ1bnRpbWVJbml0aWFsaXplZCl4Lm9uUnVudGltZUluaXRpYWxpemVkKCk7aWYoIUMpe2lmKHgucG9zdFJ1bilmb3IoXCJmdW5jdGlvblwiPT10eXBlb2YgeC5wb3N0UnVuJiYoeC5wb3N0UnVuPVt4LnBvc3RSdW5dKTt4LnBvc3RSdW4ubGVuZ3RoOyl7dmFyIGI9eC5wb3N0UnVuLnNoaWZ0KCk7SWEudW5zaGlmdChiKX1SKElhKX19fWlmKCEoMDxMKSlpZihDKWhhKHgpLEN8fFIoR2EpLHBvc3RNZXNzYWdlKHtjbWQ6XCJsb2FkZWRcIn0pO2Vsc2V7aWYoeC5wcmVSdW4pZm9yKFwiZnVuY3Rpb25cIj09dHlwZW9mIHgucHJlUnVuJiYoeC5wcmVSdW49W3gucHJlUnVuXSk7eC5wcmVSdW4ubGVuZ3RoOylLYSgpO1IoRmEpOzA8THx8KHguc2V0U3RhdHVzPyh4LnNldFN0YXR1cyhcIlJ1bm5pbmcuLi5cIiksc2V0VGltZW91dChmdW5jdGlvbigpe3NldFRpbWVvdXQoZnVuY3Rpb24oKXt4LnNldFN0YXR1cyhcIlwiKX0sXHJcbjEpO2EoKX0sMSkpOmEoKSl9fWlmKHgucHJlSW5pdClmb3IoXCJmdW5jdGlvblwiPT10eXBlb2YgeC5wcmVJbml0JiYoeC5wcmVJbml0PVt4LnByZUluaXRdKTswPHgucHJlSW5pdC5sZW5ndGg7KXgucHJlSW5pdC5wb3AoKSgpO2JkKCk7XHJcblxyXG5cclxuICByZXR1cm4gb3J0V2FzbVRocmVhZGVkLnJlYWR5XHJcbn1cclxuKTtcclxufSkoKTtcclxuaWYgKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0JylcclxuICBtb2R1bGUuZXhwb3J0cyA9IG9ydFdhc21UaHJlYWRlZDtcclxuZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmVbJ2FtZCddKVxyXG4gIGRlZmluZShbXSwgZnVuY3Rpb24oKSB7IHJldHVybiBvcnRXYXNtVGhyZWFkZWQ7IH0pO1xyXG5lbHNlIGlmICh0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcpXHJcbiAgZXhwb3J0c1tcIm9ydFdhc21UaHJlYWRlZFwiXSA9IG9ydFdhc21UaHJlYWRlZDtcclxuIiwiXHJcbnZhciBvcnRXYXNtID0gKCgpID0+IHtcclxuICB2YXIgX3NjcmlwdERpciA9IHR5cGVvZiBkb2N1bWVudCAhPT0gJ3VuZGVmaW5lZCcgJiYgZG9jdW1lbnQuY3VycmVudFNjcmlwdCA/IGRvY3VtZW50LmN1cnJlbnRTY3JpcHQuc3JjIDogdW5kZWZpbmVkO1xyXG4gIGlmICh0eXBlb2YgX19maWxlbmFtZSAhPT0gJ3VuZGVmaW5lZCcpIF9zY3JpcHREaXIgPSBfc2NyaXB0RGlyIHx8IF9fZmlsZW5hbWU7XHJcbiAgcmV0dXJuIChcclxuZnVuY3Rpb24ob3J0V2FzbSkge1xyXG4gIG9ydFdhc20gPSBvcnRXYXNtIHx8IHt9O1xyXG5cclxuXHJcbnZhciBkO2R8fChkPXR5cGVvZiBvcnRXYXNtICE9PSAndW5kZWZpbmVkJyA/IG9ydFdhc20gOiB7fSk7dmFyIGFhLGJhO2QucmVhZHk9bmV3IFByb21pc2UoZnVuY3Rpb24oYSxiKXthYT1hO2JhPWJ9KTt2YXIgY2E9T2JqZWN0LmFzc2lnbih7fSxkKSxkYT1cIi4vdGhpcy5wcm9ncmFtXCIsZWE9KGEsYik9Pnt0aHJvdyBiO30sZmE9XCJvYmplY3RcIj09dHlwZW9mIHdpbmRvdyxtPVwiZnVuY3Rpb25cIj09dHlwZW9mIGltcG9ydFNjcmlwdHMscD1cIm9iamVjdFwiPT10eXBlb2YgcHJvY2VzcyYmXCJvYmplY3RcIj09dHlwZW9mIHByb2Nlc3MudmVyc2lvbnMmJlwic3RyaW5nXCI9PXR5cGVvZiBwcm9jZXNzLnZlcnNpb25zLm5vZGUscT1cIlwiLGhhLHIsdixmcyx5LGlhO1xyXG5pZihwKXE9bT9yZXF1aXJlKFwicGF0aFwiKS5kaXJuYW1lKHEpK1wiL1wiOl9fZGlybmFtZStcIi9cIixpYT0oKT0+e3l8fChmcz1yZXF1aXJlKFwiZnNcIikseT1yZXF1aXJlKFwicGF0aFwiKSl9LGhhPWZ1bmN0aW9uKGEsYil7aWEoKTthPXkubm9ybWFsaXplKGEpO3JldHVybiBmcy5yZWFkRmlsZVN5bmMoYSxiP3ZvaWQgMDpcInV0ZjhcIil9LHY9YT0+e2E9aGEoYSwhMCk7YS5idWZmZXJ8fChhPW5ldyBVaW50OEFycmF5KGEpKTtyZXR1cm4gYX0scj0oYSxiLGMpPT57aWEoKTthPXkubm9ybWFsaXplKGEpO2ZzLnJlYWRGaWxlKGEsZnVuY3Rpb24oZSxmKXtlP2MoZSk6YihmLmJ1ZmZlcil9KX0sMTxwcm9jZXNzLmFyZ3YubGVuZ3RoJiYoZGE9cHJvY2Vzcy5hcmd2WzFdLnJlcGxhY2UoL1xcXFwvZyxcIi9cIikpLHByb2Nlc3MuYXJndi5zbGljZSgyKSxwcm9jZXNzLm9uKFwidW5jYXVnaHRFeGNlcHRpb25cIixmdW5jdGlvbihhKXtpZighKGEgaW5zdGFuY2VvZiBqYSkpdGhyb3cgYTt9KSxwcm9jZXNzLm9uKFwidW5oYW5kbGVkUmVqZWN0aW9uXCIsXHJcbmZ1bmN0aW9uKGEpe3Rocm93IGE7fSksZWE9KGEsYik9PntpZihub0V4aXRSdW50aW1lfHwwPGthKXRocm93IHByb2Nlc3MuZXhpdENvZGU9YSxiO2IgaW5zdGFuY2VvZiBqYXx8eihcImV4aXRpbmcgZHVlIHRvIGV4Y2VwdGlvbjogXCIrYik7cHJvY2Vzcy5leGl0KGEpfSxkLmluc3BlY3Q9ZnVuY3Rpb24oKXtyZXR1cm5cIltFbXNjcmlwdGVuIE1vZHVsZSBvYmplY3RdXCJ9O2Vsc2UgaWYoZmF8fG0pbT9xPXNlbGYubG9jYXRpb24uaHJlZjpcInVuZGVmaW5lZFwiIT10eXBlb2YgZG9jdW1lbnQmJmRvY3VtZW50LmN1cnJlbnRTY3JpcHQmJihxPWRvY3VtZW50LmN1cnJlbnRTY3JpcHQuc3JjKSxfc2NyaXB0RGlyJiYocT1fc2NyaXB0RGlyKSwwIT09cS5pbmRleE9mKFwiYmxvYjpcIik/cT1xLnN1YnN0cigwLHEucmVwbGFjZSgvWz8jXS4qLyxcIlwiKS5sYXN0SW5kZXhPZihcIi9cIikrMSk6cT1cIlwiLGhhPWE9Pnt2YXIgYj1uZXcgWE1MSHR0cFJlcXVlc3Q7Yi5vcGVuKFwiR0VUXCIsYSwhMSk7Yi5zZW5kKG51bGwpO1xyXG5yZXR1cm4gYi5yZXNwb25zZVRleHR9LG0mJih2PWE9Pnt2YXIgYj1uZXcgWE1MSHR0cFJlcXVlc3Q7Yi5vcGVuKFwiR0VUXCIsYSwhMSk7Yi5yZXNwb25zZVR5cGU9XCJhcnJheWJ1ZmZlclwiO2Iuc2VuZChudWxsKTtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoYi5yZXNwb25zZSl9KSxyPShhLGIsYyk9Pnt2YXIgZT1uZXcgWE1MSHR0cFJlcXVlc3Q7ZS5vcGVuKFwiR0VUXCIsYSwhMCk7ZS5yZXNwb25zZVR5cGU9XCJhcnJheWJ1ZmZlclwiO2Uub25sb2FkPSgpPT57MjAwPT1lLnN0YXR1c3x8MD09ZS5zdGF0dXMmJmUucmVzcG9uc2U/YihlLnJlc3BvbnNlKTpjKCl9O2Uub25lcnJvcj1jO2Uuc2VuZChudWxsKX07dmFyIGxhPWQucHJpbnR8fGNvbnNvbGUubG9nLmJpbmQoY29uc29sZSksej1kLnByaW50RXJyfHxjb25zb2xlLndhcm4uYmluZChjb25zb2xlKTtPYmplY3QuYXNzaWduKGQsY2EpO2NhPW51bGw7ZC50aGlzUHJvZ3JhbSYmKGRhPWQudGhpc1Byb2dyYW0pO2QucXVpdCYmKGVhPWQucXVpdCk7XHJcbnZhciBBO2Qud2FzbUJpbmFyeSYmKEE9ZC53YXNtQmluYXJ5KTt2YXIgbm9FeGl0UnVudGltZT1kLm5vRXhpdFJ1bnRpbWV8fCExO1wib2JqZWN0XCIhPXR5cGVvZiBXZWJBc3NlbWJseSYmQihcIm5vIG5hdGl2ZSB3YXNtIHN1cHBvcnQgZGV0ZWN0ZWRcIik7dmFyIG1hLEQ9ITEsbmE9XCJ1bmRlZmluZWRcIiE9dHlwZW9mIFRleHREZWNvZGVyP25ldyBUZXh0RGVjb2RlcihcInV0ZjhcIik6dm9pZCAwO1xyXG5mdW5jdGlvbiBvYShhLGIsYyl7Yj4+Pj0wO3ZhciBlPWIrYztmb3IoYz1iO2FbY10mJiEoYz49ZSk7KSsrYztpZigxNjxjLWImJmEuYnVmZmVyJiZuYSlyZXR1cm4gbmEuZGVjb2RlKGEuc3ViYXJyYXkoYixjKSk7Zm9yKGU9XCJcIjtiPGM7KXt2YXIgZj1hW2IrK107aWYoZiYxMjgpe3ZhciBoPWFbYisrXSY2MztpZigxOTI9PShmJjIyNCkpZSs9U3RyaW5nLmZyb21DaGFyQ29kZSgoZiYzMSk8PDZ8aCk7ZWxzZXt2YXIgaz1hW2IrK10mNjM7Zj0yMjQ9PShmJjI0MCk/KGYmMTUpPDwxMnxoPDw2fGs6KGYmNyk8PDE4fGg8PDEyfGs8PDZ8YVtiKytdJjYzOzY1NTM2PmY/ZSs9U3RyaW5nLmZyb21DaGFyQ29kZShmKTooZi09NjU1MzYsZSs9U3RyaW5nLmZyb21DaGFyQ29kZSg1NTI5NnxmPj4xMCw1NjMyMHxmJjEwMjMpKX19ZWxzZSBlKz1TdHJpbmcuZnJvbUNoYXJDb2RlKGYpfXJldHVybiBlfWZ1bmN0aW9uIHBhKGEsYil7cmV0dXJuKGE+Pj49MCk/b2EoRyxhLGIpOlwiXCJ9XHJcbmZ1bmN0aW9uIHFhKGEsYixjLGUpe2M+Pj49MDtpZighKDA8ZSkpcmV0dXJuIDA7dmFyIGY9YztlPWMrZS0xO2Zvcih2YXIgaD0wO2g8YS5sZW5ndGg7KytoKXt2YXIgaz1hLmNoYXJDb2RlQXQoaCk7aWYoNTUyOTY8PWsmJjU3MzQzPj1rKXt2YXIgbD1hLmNoYXJDb2RlQXQoKytoKTtrPTY1NTM2KygoayYxMDIzKTw8MTApfGwmMTAyM31pZigxMjc+PWspe2lmKGM+PWUpYnJlYWs7YltjKys+Pj4wXT1rfWVsc2V7aWYoMjA0Nz49ayl7aWYoYysxPj1lKWJyZWFrO2JbYysrPj4+MF09MTkyfGs+PjZ9ZWxzZXtpZig2NTUzNT49ayl7aWYoYysyPj1lKWJyZWFrO2JbYysrPj4+MF09MjI0fGs+PjEyfWVsc2V7aWYoYyszPj1lKWJyZWFrO2JbYysrPj4+MF09MjQwfGs+PjE4O2JbYysrPj4+MF09MTI4fGs+PjEyJjYzfWJbYysrPj4+MF09MTI4fGs+PjYmNjN9YltjKys+Pj4wXT0xMjh8ayY2M319YltjPj4+MF09MDtyZXR1cm4gYy1mfVxyXG5mdW5jdGlvbiByYShhKXtmb3IodmFyIGI9MCxjPTA7YzxhLmxlbmd0aDsrK2Mpe3ZhciBlPWEuY2hhckNvZGVBdChjKTsxMjc+PWU/YisrOjIwNDc+PWU/Yis9Mjo1NTI5Njw9ZSYmNTczNDM+PWU/KGIrPTQsKytjKTpiKz0zfXJldHVybiBifXZhciBzYSxILEcsSSxKO2Z1bmN0aW9uIHRhKCl7dmFyIGE9bWEuYnVmZmVyO3NhPWE7ZC5IRUFQOD1IPW5ldyBJbnQ4QXJyYXkoYSk7ZC5IRUFQMTY9bmV3IEludDE2QXJyYXkoYSk7ZC5IRUFQMzI9ST1uZXcgSW50MzJBcnJheShhKTtkLkhFQVBVOD1HPW5ldyBVaW50OEFycmF5KGEpO2QuSEVBUFUxNj1uZXcgVWludDE2QXJyYXkoYSk7ZC5IRUFQVTMyPUo9bmV3IFVpbnQzMkFycmF5KGEpO2QuSEVBUEYzMj1uZXcgRmxvYXQzMkFycmF5KGEpO2QuSEVBUEY2ND1uZXcgRmxvYXQ2NEFycmF5KGEpfXZhciB1YSx2YT1bXSx3YT1bXSx4YT1bXSx5YT1bXSxrYT0wO1xyXG5mdW5jdGlvbiB6YSgpe3ZhciBhPWQucHJlUnVuLnNoaWZ0KCk7dmEudW5zaGlmdChhKX12YXIgSz0wLEFhPW51bGwsTD1udWxsO2Z1bmN0aW9uIEIoYSl7aWYoZC5vbkFib3J0KWQub25BYm9ydChhKTthPVwiQWJvcnRlZChcIithK1wiKVwiO3ooYSk7RD0hMDthPW5ldyBXZWJBc3NlbWJseS5SdW50aW1lRXJyb3IoYStcIi4gQnVpbGQgd2l0aCAtc0FTU0VSVElPTlMgZm9yIG1vcmUgaW5mby5cIik7YmEoYSk7dGhyb3cgYTt9ZnVuY3Rpb24gQmEoKXtyZXR1cm4gTi5zdGFydHNXaXRoKFwiZGF0YTphcHBsaWNhdGlvbi9vY3RldC1zdHJlYW07YmFzZTY0LFwiKX12YXIgTjtOPVwib3J0LXdhc20ud2FzbVwiO2lmKCFCYSgpKXt2YXIgQ2E9TjtOPWQubG9jYXRlRmlsZT9kLmxvY2F0ZUZpbGUoQ2EscSk6cStDYX1cclxuZnVuY3Rpb24gRGEoKXt2YXIgYT1OO3RyeXtpZihhPT1OJiZBKXJldHVybiBuZXcgVWludDhBcnJheShBKTtpZih2KXJldHVybiB2KGEpO3Rocm93XCJib3RoIGFzeW5jIGFuZCBzeW5jIGZldGNoaW5nIG9mIHRoZSB3YXNtIGZhaWxlZFwiO31jYXRjaChiKXtCKGIpfX1cclxuZnVuY3Rpb24gRWEoKXtpZighQSYmKGZhfHxtKSl7aWYoXCJmdW5jdGlvblwiPT10eXBlb2YgZmV0Y2gmJiFOLnN0YXJ0c1dpdGgoXCJmaWxlOi8vXCIpKXJldHVybiBmZXRjaChOLHtjcmVkZW50aWFsczpcInNhbWUtb3JpZ2luXCJ9KS50aGVuKGZ1bmN0aW9uKGEpe2lmKCFhLm9rKXRocm93XCJmYWlsZWQgdG8gbG9hZCB3YXNtIGJpbmFyeSBmaWxlIGF0ICdcIitOK1wiJ1wiO3JldHVybiBhLmFycmF5QnVmZmVyKCl9KS5jYXRjaChmdW5jdGlvbigpe3JldHVybiBEYSgpfSk7aWYocilyZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24oYSxiKXtyKE4sZnVuY3Rpb24oYyl7YShuZXcgVWludDhBcnJheShjKSl9LGIpfSl9cmV0dXJuIFByb21pc2UucmVzb2x2ZSgpLnRoZW4oZnVuY3Rpb24oKXtyZXR1cm4gRGEoKX0pfWZ1bmN0aW9uIGphKGEpe3RoaXMubmFtZT1cIkV4aXRTdGF0dXNcIjt0aGlzLm1lc3NhZ2U9XCJQcm9ncmFtIHRlcm1pbmF0ZWQgd2l0aCBleGl0KFwiK2ErXCIpXCI7dGhpcy5zdGF0dXM9YX1cclxuZnVuY3Rpb24gTyhhKXtmb3IoOzA8YS5sZW5ndGg7KWEuc2hpZnQoKShkKX12YXIgUD1bXSxRPTAsUj0wO1xyXG5mdW5jdGlvbiBTKGEpe3RoaXMuRGI9YTt0aGlzLnpiPWEtMjQ7dGhpcy5VYj1mdW5jdGlvbihiKXtKW3RoaXMuemIrND4+Mj4+PjBdPWJ9O3RoaXMuRWI9ZnVuY3Rpb24oKXtyZXR1cm4gSlt0aGlzLnpiKzQ+PjI+Pj4wXX07dGhpcy5TYj1mdW5jdGlvbihiKXtKW3RoaXMuemIrOD4+Mj4+PjBdPWJ9O3RoaXMuV2I9ZnVuY3Rpb24oKXtyZXR1cm4gSlt0aGlzLnpiKzg+PjI+Pj4wXX07dGhpcy5UYj1mdW5jdGlvbigpe0lbdGhpcy56Yj4+Mj4+PjBdPTB9O3RoaXMuSWI9ZnVuY3Rpb24oYil7SFt0aGlzLnpiKzEyPj4wPj4+MF09Yj8xOjB9O3RoaXMuUGI9ZnVuY3Rpb24oKXtyZXR1cm4gMCE9SFt0aGlzLnpiKzEyPj4wPj4+MF19O3RoaXMuSmI9ZnVuY3Rpb24oYil7SFt0aGlzLnpiKzEzPj4wPj4+MF09Yj8xOjB9O3RoaXMuTGI9ZnVuY3Rpb24oKXtyZXR1cm4gMCE9SFt0aGlzLnpiKzEzPj4wPj4+MF19O3RoaXMuUmI9ZnVuY3Rpb24oYixjKXt0aGlzLkZiKDApO3RoaXMuVWIoYik7dGhpcy5TYihjKTtcclxudGhpcy5UYigpO3RoaXMuSWIoITEpO3RoaXMuSmIoITEpfTt0aGlzLk5iPWZ1bmN0aW9uKCl7SVt0aGlzLnpiPj4yPj4+MF0rPTF9O3RoaXMuWGI9ZnVuY3Rpb24oKXt2YXIgYj1JW3RoaXMuemI+PjI+Pj4wXTtJW3RoaXMuemI+PjI+Pj4wXT1iLTE7cmV0dXJuIDE9PT1ifTt0aGlzLkZiPWZ1bmN0aW9uKGIpe0pbdGhpcy56YisxNj4+Mj4+PjBdPWJ9O3RoaXMuT2I9ZnVuY3Rpb24oKXtyZXR1cm4gSlt0aGlzLnpiKzE2Pj4yPj4+MF19O3RoaXMuUWI9ZnVuY3Rpb24oKXtpZihGYSh0aGlzLkViKCkpKXJldHVybiBKW3RoaXMuRGI+PjI+Pj4wXTt2YXIgYj10aGlzLk9iKCk7cmV0dXJuIDAhPT1iP2I6dGhpcy5EYn19ZnVuY3Rpb24gR2EoYSl7cmV0dXJuIEhhKChuZXcgUyhhKSkuemIpfXZhciBUPVtdO2Z1bmN0aW9uIFUoYSl7dmFyIGI9VFthXTtifHwoYT49VC5sZW5ndGgmJihULmxlbmd0aD1hKzEpLFRbYV09Yj11YS5nZXQoYSkpO3JldHVybiBifVxyXG5mdW5jdGlvbiBJYShhKXt2YXIgYj1yYShhKSsxLGM9SmEoYik7YyYmcWEoYSxILGMsYik7cmV0dXJuIGN9ZnVuY3Rpb24gS2EoYSxiLGMpe2Z1bmN0aW9uIGUobil7cmV0dXJuKG49bi50b1RpbWVTdHJpbmcoKS5tYXRjaCgvXFwoKFtBLVphLXogXSspXFwpJC8pKT9uWzFdOlwiR01UXCJ9dmFyIGY9KG5ldyBEYXRlKS5nZXRGdWxsWWVhcigpLGg9bmV3IERhdGUoZiwwLDEpLGs9bmV3IERhdGUoZiw2LDEpO2Y9aC5nZXRUaW1lem9uZU9mZnNldCgpO3ZhciBsPWsuZ2V0VGltZXpvbmVPZmZzZXQoKTtJW2E+PjI+Pj4wXT02MCpNYXRoLm1heChmLGwpO0lbYj4+Mj4+PjBdPU51bWJlcihmIT1sKTthPWUoaCk7Yj1lKGspO2E9SWEoYSk7Yj1JYShiKTtsPGY/KEpbYz4+Mj4+PjBdPWEsSltjKzQ+PjI+Pj4wXT1iKTooSltjPj4yPj4+MF09YixKW2MrND4+Mj4+PjBdPWEpfWZ1bmN0aW9uIExhKGEsYixjKXtMYS5WYnx8KExhLlZiPSEwLEthKGEsYixjKSl9dmFyIE1hPXt9O1xyXG5mdW5jdGlvbiBOYSgpe2lmKCFPYSl7dmFyIGE9e1VTRVI6XCJ3ZWJfdXNlclwiLExPR05BTUU6XCJ3ZWJfdXNlclwiLFBBVEg6XCIvXCIsUFdEOlwiL1wiLEhPTUU6XCIvaG9tZS93ZWJfdXNlclwiLExBTkc6KFwib2JqZWN0XCI9PXR5cGVvZiBuYXZpZ2F0b3ImJm5hdmlnYXRvci5sYW5ndWFnZXMmJm5hdmlnYXRvci5sYW5ndWFnZXNbMF18fFwiQ1wiKS5yZXBsYWNlKFwiLVwiLFwiX1wiKStcIi5VVEYtOFwiLF86ZGF8fFwiLi90aGlzLnByb2dyYW1cIn0sYjtmb3IoYiBpbiBNYSl2b2lkIDA9PT1NYVtiXT9kZWxldGUgYVtiXTphW2JdPU1hW2JdO3ZhciBjPVtdO2ZvcihiIGluIGEpYy5wdXNoKGIrXCI9XCIrYVtiXSk7T2E9Y31yZXR1cm4gT2F9dmFyIE9hLFBhPVtudWxsLFtdLFtdXTtmdW5jdGlvbiBRYShhLGIpe3ZhciBjPVBhW2FdOzA9PT1ifHwxMD09PWI/KCgxPT09YT9sYTp6KShvYShjLDApKSxjLmxlbmd0aD0wKTpjLnB1c2goYil9dmFyIFY9MDtcclxuZnVuY3Rpb24gUmEoKXtpZihcIm9iamVjdFwiPT10eXBlb2YgY3J5cHRvJiZcImZ1bmN0aW9uXCI9PXR5cGVvZiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKXt2YXIgYT1uZXcgVWludDhBcnJheSgxKTtyZXR1cm4oKT0+e2NyeXB0by5nZXRSYW5kb21WYWx1ZXMoYSk7cmV0dXJuIGFbMF19fWlmKHApdHJ5e3ZhciBiPXJlcXVpcmUoXCJjcnlwdG9cIik7cmV0dXJuKCk9PmIucmFuZG9tQnl0ZXMoMSlbMF19Y2F0Y2goYyl7fXJldHVybigpPT5CKFwicmFuZG9tRGV2aWNlXCIpfWZ1bmN0aW9uIFcoYSxiKXtXLk1ifHwoVy5NYj1SYSgpKTtmb3IodmFyIGM9MDtjPGI7YysrKUhbYStjPj4wPj4+MF09Vy5NYigpO3JldHVybiAwfWZ1bmN0aW9uIFNhKGEpe3JldHVybiAwPT09YSU0JiYoMCE9PWElMTAwfHwwPT09YSU0MDApfXZhciBUYT1bMzEsMjksMzEsMzAsMzEsMzAsMzEsMzEsMzAsMzEsMzAsMzFdLFVhPVszMSwyOCwzMSwzMCwzMSwzMCwzMSwzMSwzMCwzMSwzMCwzMV07XHJcbmZ1bmN0aW9uIFZhKGEpe3ZhciBiPUFycmF5KHJhKGEpKzEpO3FhKGEsYiwwLGIubGVuZ3RoKTtyZXR1cm4gYn1cclxuZnVuY3Rpb24gV2EoYSxiLGMsZSl7ZnVuY3Rpb24gZihnLHUsdyl7Zm9yKGc9XCJudW1iZXJcIj09dHlwZW9mIGc/Zy50b1N0cmluZygpOmd8fFwiXCI7Zy5sZW5ndGg8dTspZz13WzBdK2c7cmV0dXJuIGd9ZnVuY3Rpb24gaChnLHUpe3JldHVybiBmKGcsdSxcIjBcIil9ZnVuY3Rpb24gayhnLHUpe2Z1bmN0aW9uIHcoTSl7cmV0dXJuIDA+TT8tMTowPE0/MTowfXZhciBGOzA9PT0oRj13KGcuZ2V0RnVsbFllYXIoKS11LmdldEZ1bGxZZWFyKCkpKSYmMD09PShGPXcoZy5nZXRNb250aCgpLXUuZ2V0TW9udGgoKSkpJiYoRj13KGcuZ2V0RGF0ZSgpLXUuZ2V0RGF0ZSgpKSk7cmV0dXJuIEZ9ZnVuY3Rpb24gbChnKXtzd2l0Y2goZy5nZXREYXkoKSl7Y2FzZSAwOnJldHVybiBuZXcgRGF0ZShnLmdldEZ1bGxZZWFyKCktMSwxMSwyOSk7Y2FzZSAxOnJldHVybiBnO2Nhc2UgMjpyZXR1cm4gbmV3IERhdGUoZy5nZXRGdWxsWWVhcigpLDAsMyk7Y2FzZSAzOnJldHVybiBuZXcgRGF0ZShnLmdldEZ1bGxZZWFyKCksXHJcbjAsMik7Y2FzZSA0OnJldHVybiBuZXcgRGF0ZShnLmdldEZ1bGxZZWFyKCksMCwxKTtjYXNlIDU6cmV0dXJuIG5ldyBEYXRlKGcuZ2V0RnVsbFllYXIoKS0xLDExLDMxKTtjYXNlIDY6cmV0dXJuIG5ldyBEYXRlKGcuZ2V0RnVsbFllYXIoKS0xLDExLDMwKX19ZnVuY3Rpb24gbihnKXt2YXIgdT1nLkJiO2ZvcihnPW5ldyBEYXRlKChuZXcgRGF0ZShnLkNiKzE5MDAsMCwxKSkuZ2V0VGltZSgpKTswPHU7KXt2YXIgdz1nLmdldE1vbnRoKCksRj0oU2EoZy5nZXRGdWxsWWVhcigpKT9UYTpVYSlbd107aWYodT5GLWcuZ2V0RGF0ZSgpKXUtPUYtZy5nZXREYXRlKCkrMSxnLnNldERhdGUoMSksMTE+dz9nLnNldE1vbnRoKHcrMSk6KGcuc2V0TW9udGgoMCksZy5zZXRGdWxsWWVhcihnLmdldEZ1bGxZZWFyKCkrMSkpO2Vsc2V7Zy5zZXREYXRlKGcuZ2V0RGF0ZSgpK3UpO2JyZWFrfX13PW5ldyBEYXRlKGcuZ2V0RnVsbFllYXIoKSsxLDAsNCk7dT1sKG5ldyBEYXRlKGcuZ2V0RnVsbFllYXIoKSxcclxuMCw0KSk7dz1sKHcpO3JldHVybiAwPj1rKHUsZyk/MD49ayh3LGcpP2cuZ2V0RnVsbFllYXIoKSsxOmcuZ2V0RnVsbFllYXIoKTpnLmdldEZ1bGxZZWFyKCktMX12YXIgdD1JW2UrNDA+PjI+Pj4wXTtlPXskYjpJW2U+PjI+Pj4wXSxaYjpJW2UrND4+Mj4+PjBdLEdiOklbZSs4Pj4yPj4+MF0sS2I6SVtlKzEyPj4yPj4+MF0sSGI6SVtlKzE2Pj4yPj4+MF0sQ2I6SVtlKzIwPj4yPj4+MF0sQWI6SVtlKzI0Pj4yPj4+MF0sQmI6SVtlKzI4Pj4yPj4+MF0sYmM6SVtlKzMyPj4yPj4+MF0sWWI6SVtlKzM2Pj4yPj4+MF0sYWM6dD9wYSh0KTpcIlwifTtjPXBhKGMpO3Q9e1wiJWNcIjpcIiVhICViICVkICVIOiVNOiVTICVZXCIsXCIlRFwiOlwiJW0vJWQvJXlcIixcIiVGXCI6XCIlWS0lbS0lZFwiLFwiJWhcIjpcIiViXCIsXCIlclwiOlwiJUk6JU06JVMgJXBcIixcIiVSXCI6XCIlSDolTVwiLFwiJVRcIjpcIiVIOiVNOiVTXCIsXCIleFwiOlwiJW0vJWQvJXlcIixcIiVYXCI6XCIlSDolTTolU1wiLFwiJUVjXCI6XCIlY1wiLFwiJUVDXCI6XCIlQ1wiLFwiJUV4XCI6XCIlbS8lZC8leVwiLFxyXG5cIiVFWFwiOlwiJUg6JU06JVNcIixcIiVFeVwiOlwiJXlcIixcIiVFWVwiOlwiJVlcIixcIiVPZFwiOlwiJWRcIixcIiVPZVwiOlwiJWVcIixcIiVPSFwiOlwiJUhcIixcIiVPSVwiOlwiJUlcIixcIiVPbVwiOlwiJW1cIixcIiVPTVwiOlwiJU1cIixcIiVPU1wiOlwiJVNcIixcIiVPdVwiOlwiJXVcIixcIiVPVVwiOlwiJVVcIixcIiVPVlwiOlwiJVZcIixcIiVPd1wiOlwiJXdcIixcIiVPV1wiOlwiJVdcIixcIiVPeVwiOlwiJXlcIn07Zm9yKHZhciB4IGluIHQpYz1jLnJlcGxhY2UobmV3IFJlZ0V4cCh4LFwiZ1wiKSx0W3hdKTt2YXIgRT1cIlN1bmRheSBNb25kYXkgVHVlc2RheSBXZWRuZXNkYXkgVGh1cnNkYXkgRnJpZGF5IFNhdHVyZGF5XCIuc3BsaXQoXCIgXCIpLEM9XCJKYW51YXJ5IEZlYnJ1YXJ5IE1hcmNoIEFwcmlsIE1heSBKdW5lIEp1bHkgQXVndXN0IFNlcHRlbWJlciBPY3RvYmVyIE5vdmVtYmVyIERlY2VtYmVyXCIuc3BsaXQoXCIgXCIpO3Q9e1wiJWFcIjpmdW5jdGlvbihnKXtyZXR1cm4gRVtnLkFiXS5zdWJzdHJpbmcoMCwzKX0sXCIlQVwiOmZ1bmN0aW9uKGcpe3JldHVybiBFW2cuQWJdfSxcIiViXCI6ZnVuY3Rpb24oZyl7cmV0dXJuIENbZy5IYl0uc3Vic3RyaW5nKDAsXHJcbjMpfSxcIiVCXCI6ZnVuY3Rpb24oZyl7cmV0dXJuIENbZy5IYl19LFwiJUNcIjpmdW5jdGlvbihnKXtyZXR1cm4gaCgoZy5DYisxOTAwKS8xMDB8MCwyKX0sXCIlZFwiOmZ1bmN0aW9uKGcpe3JldHVybiBoKGcuS2IsMil9LFwiJWVcIjpmdW5jdGlvbihnKXtyZXR1cm4gZihnLktiLDIsXCIgXCIpfSxcIiVnXCI6ZnVuY3Rpb24oZyl7cmV0dXJuIG4oZykudG9TdHJpbmcoKS5zdWJzdHJpbmcoMil9LFwiJUdcIjpmdW5jdGlvbihnKXtyZXR1cm4gbihnKX0sXCIlSFwiOmZ1bmN0aW9uKGcpe3JldHVybiBoKGcuR2IsMil9LFwiJUlcIjpmdW5jdGlvbihnKXtnPWcuR2I7MD09Zz9nPTEyOjEyPGcmJihnLT0xMik7cmV0dXJuIGgoZywyKX0sXCIlalwiOmZ1bmN0aW9uKGcpe2Zvcih2YXIgdT0wLHc9MDt3PD1nLkhiLTE7dSs9KFNhKGcuQ2IrMTkwMCk/VGE6VWEpW3crK10pO3JldHVybiBoKGcuS2IrdSwzKX0sXCIlbVwiOmZ1bmN0aW9uKGcpe3JldHVybiBoKGcuSGIrMSwyKX0sXCIlTVwiOmZ1bmN0aW9uKGcpe3JldHVybiBoKGcuWmIsXHJcbjIpfSxcIiVuXCI6ZnVuY3Rpb24oKXtyZXR1cm5cIlxcblwifSxcIiVwXCI6ZnVuY3Rpb24oZyl7cmV0dXJuIDA8PWcuR2ImJjEyPmcuR2I/XCJBTVwiOlwiUE1cIn0sXCIlU1wiOmZ1bmN0aW9uKGcpe3JldHVybiBoKGcuJGIsMil9LFwiJXRcIjpmdW5jdGlvbigpe3JldHVyblwiXFx0XCJ9LFwiJXVcIjpmdW5jdGlvbihnKXtyZXR1cm4gZy5BYnx8N30sXCIlVVwiOmZ1bmN0aW9uKGcpe3JldHVybiBoKE1hdGguZmxvb3IoKGcuQmIrNy1nLkFiKS83KSwyKX0sXCIlVlwiOmZ1bmN0aW9uKGcpe3ZhciB1PU1hdGguZmxvb3IoKGcuQmIrNy0oZy5BYis2KSU3KS83KTsyPj0oZy5BYiszNzEtZy5CYi0yKSU3JiZ1Kys7aWYodSk1Mz09dSYmKHc9KGcuQWIrMzcxLWcuQmIpJTcsND09d3x8Mz09dyYmU2EoZy5DYil8fCh1PTEpKTtlbHNle3U9NTI7dmFyIHc9KGcuQWIrNy1nLkJiLTEpJTc7KDQ9PXd8fDU9PXcmJlNhKGcuQ2IlNDAwLTEpKSYmdSsrfXJldHVybiBoKHUsMil9LFwiJXdcIjpmdW5jdGlvbihnKXtyZXR1cm4gZy5BYn0sXCIlV1wiOmZ1bmN0aW9uKGcpe3JldHVybiBoKE1hdGguZmxvb3IoKGcuQmIrXHJcbjctKGcuQWIrNiklNykvNyksMil9LFwiJXlcIjpmdW5jdGlvbihnKXtyZXR1cm4oZy5DYisxOTAwKS50b1N0cmluZygpLnN1YnN0cmluZygyKX0sXCIlWVwiOmZ1bmN0aW9uKGcpe3JldHVybiBnLkNiKzE5MDB9LFwiJXpcIjpmdW5jdGlvbihnKXtnPWcuWWI7dmFyIHU9MDw9ZztnPU1hdGguYWJzKGcpLzYwO3JldHVybih1P1wiK1wiOlwiLVwiKStTdHJpbmcoXCIwMDAwXCIrKGcvNjAqMTAwK2clNjApKS5zbGljZSgtNCl9LFwiJVpcIjpmdW5jdGlvbihnKXtyZXR1cm4gZy5hY30sXCIlJVwiOmZ1bmN0aW9uKCl7cmV0dXJuXCIlXCJ9fTtjPWMucmVwbGFjZSgvJSUvZyxcIlxceDAwXFx4MDBcIik7Zm9yKHggaW4gdCljLmluY2x1ZGVzKHgpJiYoYz1jLnJlcGxhY2UobmV3IFJlZ0V4cCh4LFwiZ1wiKSx0W3hdKGUpKSk7Yz1jLnJlcGxhY2UoL1xcMFxcMC9nLFwiJVwiKTt4PVZhKGMpO2lmKHgubGVuZ3RoPmIpcmV0dXJuIDA7SC5zZXQoeCxhPj4+MCk7cmV0dXJuIHgubGVuZ3RoLTF9XHJcbnZhciBKYj17YTpmdW5jdGlvbihhKXtyZXR1cm4gSmEoYSsyNCkrMjR9LG06ZnVuY3Rpb24oYSl7YT1uZXcgUyhhKTthLlBiKCl8fChhLkliKCEwKSxRLS0pO2EuSmIoITEpO1AucHVzaChhKTthLk5iKCk7cmV0dXJuIGEuUWIoKX0saWE6ZnVuY3Rpb24oYSl7eihcIlVuZXhwZWN0ZWQgZXhjZXB0aW9uIHRocm93biwgdGhpcyBpcyBub3QgcHJvcGVybHkgc3VwcG9ydGVkIC0gYWJvcnRpbmdcIik7RD0hMDt0aHJvdyBhO30sdzpmdW5jdGlvbigpe1goMCk7dmFyIGE9UC5wb3AoKTtpZihhLlhiKCkmJiFhLkxiKCkpe3ZhciBiPWEuV2IoKTtiJiZVKGIpKGEuRGIpO0dhKGEuRGIpfVI9MH0sZDpmdW5jdGlvbigpe3ZhciBhPVI7aWYoIWEpcmV0dXJuIFY9MDt2YXIgYj1uZXcgUyhhKTtiLkZiKGEpO3ZhciBjPWIuRWIoKTtpZighYylyZXR1cm4gVj0wLGE7Zm9yKHZhciBlPUFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cyksZj0wO2Y8ZS5sZW5ndGg7ZisrKXt2YXIgaD1lW2ZdO1xyXG5pZigwPT09aHx8aD09PWMpYnJlYWs7aWYoWGEoaCxjLGIuemIrMTYpKXJldHVybiBWPWgsYX1WPWM7cmV0dXJuIGF9LGs6ZnVuY3Rpb24oKXt2YXIgYT1SO2lmKCFhKXJldHVybiBWPTA7dmFyIGI9bmV3IFMoYSk7Yi5GYihhKTt2YXIgYz1iLkViKCk7aWYoIWMpcmV0dXJuIFY9MCxhO2Zvcih2YXIgZT1BcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpLGY9MDtmPGUubGVuZ3RoO2YrKyl7dmFyIGg9ZVtmXTtpZigwPT09aHx8aD09PWMpYnJlYWs7aWYoWGEoaCxjLGIuemIrMTYpKXJldHVybiBWPWgsYX1WPWM7cmV0dXJuIGF9LGc6ZnVuY3Rpb24oKXt2YXIgYT1SO2lmKCFhKXJldHVybiBWPTA7dmFyIGI9bmV3IFMoYSk7Yi5GYihhKTt2YXIgYz1iLkViKCk7aWYoIWMpcmV0dXJuIFY9MCxhO2Zvcih2YXIgZT1BcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpLGY9MDtmPGUubGVuZ3RoO2YrKyl7dmFyIGg9ZVtmXTtpZigwPT09aHx8aD09PWMpYnJlYWs7XHJcbmlmKFhhKGgsYyxiLnpiKzE2KSlyZXR1cm4gVj1oLGF9Vj1jO3JldHVybiBhfSxzOkdhLEw6ZnVuY3Rpb24oKXt2YXIgYT1QLnBvcCgpO2F8fEIoXCJubyBleGNlcHRpb24gdG8gdGhyb3dcIik7dmFyIGI9YS5EYjthLkxiKCl8fChQLnB1c2goYSksYS5KYighMCksYS5JYighMSksUSsrKTtSPWI7dGhyb3cgYjt9LGI6ZnVuY3Rpb24oYSxiLGMpeyhuZXcgUyhhKSkuUmIoYixjKTtSPWE7USsrO3Rocm93IGE7fSxsYTpmdW5jdGlvbigpe3JldHVybiBRfSxpOmZ1bmN0aW9uKGEpe1J8fChSPWEpO3Rocm93IGE7fSxIOmZ1bmN0aW9uKCl7cmV0dXJuIDB9LEJhOmZ1bmN0aW9uKCl7fSxwYTpmdW5jdGlvbigpe30scmE6ZnVuY3Rpb24oKXt9LGthOmZ1bmN0aW9uKCl7cmV0dXJuIDB9LHphOmZ1bmN0aW9uKCl7fSx1YTpmdW5jdGlvbigpe30seWE6ZnVuY3Rpb24oKXt9LFI6ZnVuY3Rpb24oKXt9LHFhOmZ1bmN0aW9uKCl7fSxuYTpmdW5jdGlvbigpe30sQWE6ZnVuY3Rpb24oKXt9LG9hOmZ1bmN0aW9uKCl7fSxcclxuSGE6ZnVuY3Rpb24oKXt9LEphOmZ1bmN0aW9uKCl7QihcIlRvIHVzZSBkbG9wZW4sIHlvdSBuZWVkIGVuYWJsZSBkeW5hbWljIGxpbmtpbmcsIHNlZSBodHRwczovL2dpdGh1Yi5jb20vZW1zY3JpcHRlbi1jb3JlL2Vtc2NyaXB0ZW4vd2lraS9MaW5raW5nXCIpfSxJYTpmdW5jdGlvbigpe0IoXCJUbyB1c2UgZGxvcGVuLCB5b3UgbmVlZCBlbmFibGUgZHluYW1pYyBsaW5raW5nLCBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2Vtc2NyaXB0ZW4tY29yZS9lbXNjcmlwdGVuL3dpa2kvTGlua2luZ1wiKX0sUzpmdW5jdGlvbigpe3JldHVybiBEYXRlLm5vdygpfSxDYTpmdW5jdGlvbigpe3JldHVybiEwfSxEYTpmdW5jdGlvbihhLGIpe2E9bmV3IERhdGUoMUUzKihKW2E+Pj4yXSs0Mjk0OTY3Mjk2KklbYSs0Pj4+Ml0pKTtJW2I+PjI+Pj4wXT1hLmdldFVUQ1NlY29uZHMoKTtJW2IrND4+Mj4+PjBdPWEuZ2V0VVRDTWludXRlcygpO0lbYis4Pj4yPj4+MF09YS5nZXRVVENIb3VycygpO0lbYisxMj4+Mj4+PlxyXG4wXT1hLmdldFVUQ0RhdGUoKTtJW2IrMTY+PjI+Pj4wXT1hLmdldFVUQ01vbnRoKCk7SVtiKzIwPj4yPj4+MF09YS5nZXRVVENGdWxsWWVhcigpLTE5MDA7SVtiKzI0Pj4yPj4+MF09YS5nZXRVVENEYXkoKTtJW2IrMjg+PjI+Pj4wXT0oYS5nZXRUaW1lKCktRGF0ZS5VVEMoYS5nZXRVVENGdWxsWWVhcigpLDAsMSwwLDAsMCwwKSkvODY0RTV8MH0sRWE6ZnVuY3Rpb24oYSxiKXthPW5ldyBEYXRlKDFFMyooSlthPj4+Ml0rNDI5NDk2NzI5NipJW2ErND4+PjJdKSk7SVtiPj4yPj4+MF09YS5nZXRTZWNvbmRzKCk7SVtiKzQ+PjI+Pj4wXT1hLmdldE1pbnV0ZXMoKTtJW2IrOD4+Mj4+PjBdPWEuZ2V0SG91cnMoKTtJW2IrMTI+PjI+Pj4wXT1hLmdldERhdGUoKTtJW2IrMTY+PjI+Pj4wXT1hLmdldE1vbnRoKCk7SVtiKzIwPj4yPj4+MF09YS5nZXRGdWxsWWVhcigpLTE5MDA7SVtiKzI0Pj4yPj4+MF09YS5nZXREYXkoKTt2YXIgYz1uZXcgRGF0ZShhLmdldEZ1bGxZZWFyKCksMCwxKTtJW2IrXHJcbjI4Pj4yPj4+MF09KGEuZ2V0VGltZSgpLWMuZ2V0VGltZSgpKS84NjRFNXwwO0lbYiszNj4+Mj4+PjBdPS0oNjAqYS5nZXRUaW1lem9uZU9mZnNldCgpKTt2YXIgZT0obmV3IERhdGUoYS5nZXRGdWxsWWVhcigpLDYsMSkpLmdldFRpbWV6b25lT2Zmc2V0KCk7Yz1jLmdldFRpbWV6b25lT2Zmc2V0KCk7SVtiKzMyPj4yPj4+MF09KGUhPWMmJmEuZ2V0VGltZXpvbmVPZmZzZXQoKT09TWF0aC5taW4oYyxlKSl8MH0sRmE6ZnVuY3Rpb24oYSl7dmFyIGI9bmV3IERhdGUoSVthKzIwPj4yPj4+MF0rMTkwMCxJW2ErMTY+PjI+Pj4wXSxJW2ErMTI+PjI+Pj4wXSxJW2ErOD4+Mj4+PjBdLElbYSs0Pj4yPj4+MF0sSVthPj4yPj4+MF0sMCksYz1JW2ErMzI+PjI+Pj4wXSxlPWIuZ2V0VGltZXpvbmVPZmZzZXQoKSxmPW5ldyBEYXRlKGIuZ2V0RnVsbFllYXIoKSwwLDEpLGg9KG5ldyBEYXRlKGIuZ2V0RnVsbFllYXIoKSw2LDEpKS5nZXRUaW1lem9uZU9mZnNldCgpLGs9Zi5nZXRUaW1lem9uZU9mZnNldCgpLFxyXG5sPU1hdGgubWluKGssaCk7MD5jP0lbYSszMj4+Mj4+PjBdPU51bWJlcihoIT1rJiZsPT1lKTowPGMhPShsPT1lKSYmKGg9TWF0aC5tYXgoayxoKSxiLnNldFRpbWUoYi5nZXRUaW1lKCkrNkU0KigoMDxjP2w6aCktZSkpKTtJW2ErMjQ+PjI+Pj4wXT1iLmdldERheSgpO0lbYSsyOD4+Mj4+PjBdPShiLmdldFRpbWUoKS1mLmdldFRpbWUoKSkvODY0RTV8MDtJW2E+PjI+Pj4wXT1iLmdldFNlY29uZHMoKTtJW2ErND4+Mj4+PjBdPWIuZ2V0TWludXRlcygpO0lbYSs4Pj4yPj4+MF09Yi5nZXRIb3VycygpO0lbYSsxMj4+Mj4+PjBdPWIuZ2V0RGF0ZSgpO0lbYSsxNj4+Mj4+PjBdPWIuZ2V0TW9udGgoKTtyZXR1cm4gYi5nZXRUaW1lKCkvMUUzfDB9LHNhOmZ1bmN0aW9uKCl7cmV0dXJuLTUyfSx0YTpmdW5jdGlvbigpe30sR2E6TGEsQjpmdW5jdGlvbigpe0IoXCJcIil9LG1hOmZ1bmN0aW9uKCl7cmV0dXJuIDQyOTQ5MDE3NjB9LEk6cD8oKT0+e3ZhciBhPXByb2Nlc3MuaHJ0aW1lKCk7cmV0dXJuIDFFMypcclxuYVswXSthWzFdLzFFNn06KCk9PnBlcmZvcm1hbmNlLm5vdygpLHhhOmZ1bmN0aW9uKGEsYixjKXtHLmNvcHlXaXRoaW4oYT4+PjAsYj4+PjAsYitjPj4+MCl9LEc6ZnVuY3Rpb24oYSl7dmFyIGI9Ry5sZW5ndGg7YT4+Pj0wO2lmKDQyOTQ5MDE3NjA8YSlyZXR1cm4hMTtmb3IodmFyIGM9MTs0Pj1jO2MqPTIpe3ZhciBlPWIqKDErLjIvYyk7ZT1NYXRoLm1pbihlLGErMTAwNjYzMjk2KTt2YXIgZj1NYXRoO2U9TWF0aC5tYXgoYSxlKTtmPWYubWluLmNhbGwoZiw0Mjk0OTAxNzYwLGUrKDY1NTM2LWUlNjU1MzYpJTY1NTM2KTthOnt0cnl7bWEuZ3JvdyhmLXNhLmJ5dGVMZW5ndGgrNjU1MzU+Pj4xNik7dGEoKTt2YXIgaD0xO2JyZWFrIGF9Y2F0Y2goayl7fWg9dm9pZCAwfWlmKGgpcmV0dXJuITB9cmV0dXJuITF9LHZhOmZ1bmN0aW9uKGEsYil7dmFyIGM9MDtOYSgpLmZvckVhY2goZnVuY3Rpb24oZSxmKXt2YXIgaD1iK2M7Zj1KW2ErNCpmPj4yPj4+MF09aDtmb3IoaD0wO2g8ZS5sZW5ndGg7KytoKUhbZisrPj5cclxuMD4+PjBdPWUuY2hhckNvZGVBdChoKTtIW2Y+PjA+Pj4wXT0wO2MrPWUubGVuZ3RoKzF9KTtyZXR1cm4gMH0sd2E6ZnVuY3Rpb24oYSxiKXt2YXIgYz1OYSgpO0pbYT4+Mj4+PjBdPWMubGVuZ3RoO3ZhciBlPTA7Yy5mb3JFYWNoKGZ1bmN0aW9uKGYpe2UrPWYubGVuZ3RoKzF9KTtKW2I+PjI+Pj4wXT1lO3JldHVybiAwfSxiYTpmdW5jdGlvbihhKXtub0V4aXRSdW50aW1lfHwwPGthfHwoWWEoKSxPKHhhKSxaYSgwKSxQYVsxXS5sZW5ndGgmJlFhKDEsMTApLFBhWzJdLmxlbmd0aCYmUWEoMiwxMCkpO2lmKCEobm9FeGl0UnVudGltZXx8MDxrYSkpe2lmKGQub25FeGl0KWQub25FeGl0KGEpO0Q9ITB9ZWEoYSxuZXcgamEoYSkpfSxFOmZ1bmN0aW9uKCl7cmV0dXJuIDUyfSxROmZ1bmN0aW9uKCl7cmV0dXJuIDUyfSxjYTpmdW5jdGlvbigpe3JldHVybiA3MH0sUDpmdW5jdGlvbihhLGIsYyxlKXtmb3IodmFyIGY9MCxoPTA7aDxjO2grKyl7dmFyIGs9SltiPj4yPj4+MF0sbD1KW2IrND4+XHJcbjI+Pj4wXTtiKz04O2Zvcih2YXIgbj0wO248bDtuKyspUWEoYSxHW2srbj4+PjBdKTtmKz1sfUpbZT4+Mj4+PjBdPWY7cmV0dXJuIDB9LGM6ZnVuY3Rpb24oKXtyZXR1cm4gVn0samE6VyxlYTokYSxmYTphYixKOmJiLGU6Y2IsTjpkYixPOmViLGo6ZmIsbzpnYixwOmhiLE06aWIscjpqYix2OmtiLEs6bGIsRDptYixYOm5iLFY6b2IsVTpwYixaOnFiLFc6cmIsWTpzYixUOnRiLGY6dWIscTp2YixoOndiLGRhOnhiLGw6eWIsdDp6Yix1OkFiLHg6QmIsejpDYixnYTpEYixBOkViLEM6RmIsYWE6R2IsXzpIYiwkOkliLG46ZnVuY3Rpb24oYSl7cmV0dXJuIGF9LEY6ZnVuY3Rpb24oYSl7Vj1hfSxoYTpXYSx5OmZ1bmN0aW9uKGEsYixjLGUpe3JldHVybiBXYShhLGIsYyxlKX19O1xyXG4oZnVuY3Rpb24oKXtmdW5jdGlvbiBhKGYpe2QuYXNtPWYuZXhwb3J0czttYT1kLmFzbS5LYTt0YSgpO3VhPWQuYXNtLmliO3dhLnVuc2hpZnQoZC5hc20uTGEpO0stLTtkLm1vbml0b3JSdW5EZXBlbmRlbmNpZXMmJmQubW9uaXRvclJ1bkRlcGVuZGVuY2llcyhLKTswPT1LJiYobnVsbCE9PUFhJiYoY2xlYXJJbnRlcnZhbChBYSksQWE9bnVsbCksTCYmKGY9TCxMPW51bGwsZigpKSl9ZnVuY3Rpb24gYihmKXthKGYuaW5zdGFuY2UpfWZ1bmN0aW9uIGMoZil7cmV0dXJuIEVhKCkudGhlbihmdW5jdGlvbihoKXtyZXR1cm4gV2ViQXNzZW1ibHkuaW5zdGFudGlhdGUoaCxlKX0pLnRoZW4oZnVuY3Rpb24oaCl7cmV0dXJuIGh9KS50aGVuKGYsZnVuY3Rpb24oaCl7eihcImZhaWxlZCB0byBhc3luY2hyb25vdXNseSBwcmVwYXJlIHdhc206IFwiK2gpO0IoaCl9KX12YXIgZT17YTpKYn07SysrO2QubW9uaXRvclJ1bkRlcGVuZGVuY2llcyYmZC5tb25pdG9yUnVuRGVwZW5kZW5jaWVzKEspO2lmKGQuaW5zdGFudGlhdGVXYXNtKXRyeXtyZXR1cm4gZC5pbnN0YW50aWF0ZVdhc20oZSxcclxuYSl9Y2F0Y2goZil7cmV0dXJuIHooXCJNb2R1bGUuaW5zdGFudGlhdGVXYXNtIGNhbGxiYWNrIGZhaWxlZCB3aXRoIGVycm9yOiBcIitmKSwhMX0oZnVuY3Rpb24oKXtyZXR1cm4gQXx8XCJmdW5jdGlvblwiIT10eXBlb2YgV2ViQXNzZW1ibHkuaW5zdGFudGlhdGVTdHJlYW1pbmd8fEJhKCl8fE4uc3RhcnRzV2l0aChcImZpbGU6Ly9cIil8fHB8fFwiZnVuY3Rpb25cIiE9dHlwZW9mIGZldGNoP2MoYik6ZmV0Y2goTix7Y3JlZGVudGlhbHM6XCJzYW1lLW9yaWdpblwifSkudGhlbihmdW5jdGlvbihmKXtyZXR1cm4gV2ViQXNzZW1ibHkuaW5zdGFudGlhdGVTdHJlYW1pbmcoZixlKS50aGVuKGIsZnVuY3Rpb24oaCl7eihcIndhc20gc3RyZWFtaW5nIGNvbXBpbGUgZmFpbGVkOiBcIitoKTt6KFwiZmFsbGluZyBiYWNrIHRvIEFycmF5QnVmZmVyIGluc3RhbnRpYXRpb25cIik7cmV0dXJuIGMoYil9KX0pfSkoKS5jYXRjaChiYSk7cmV0dXJue319KSgpO1xyXG5kLl9fX3dhc21fY2FsbF9jdG9ycz1mdW5jdGlvbigpe3JldHVybihkLl9fX3dhc21fY2FsbF9jdG9ycz1kLmFzbS5MYSkuYXBwbHkobnVsbCxhcmd1bWVudHMpfTtkLl9PcnRJbml0PWZ1bmN0aW9uKCl7cmV0dXJuKGQuX09ydEluaXQ9ZC5hc20uTWEpLmFwcGx5KG51bGwsYXJndW1lbnRzKX07ZC5fT3J0Q3JlYXRlU2Vzc2lvbk9wdGlvbnM9ZnVuY3Rpb24oKXtyZXR1cm4oZC5fT3J0Q3JlYXRlU2Vzc2lvbk9wdGlvbnM9ZC5hc20uTmEpLmFwcGx5KG51bGwsYXJndW1lbnRzKX07ZC5fT3J0QXBwZW5kRXhlY3V0aW9uUHJvdmlkZXI9ZnVuY3Rpb24oKXtyZXR1cm4oZC5fT3J0QXBwZW5kRXhlY3V0aW9uUHJvdmlkZXI9ZC5hc20uT2EpLmFwcGx5KG51bGwsYXJndW1lbnRzKX07ZC5fT3J0QWRkU2Vzc2lvbkNvbmZpZ0VudHJ5PWZ1bmN0aW9uKCl7cmV0dXJuKGQuX09ydEFkZFNlc3Npb25Db25maWdFbnRyeT1kLmFzbS5QYSkuYXBwbHkobnVsbCxhcmd1bWVudHMpfTtcclxuZC5fT3J0UmVsZWFzZVNlc3Npb25PcHRpb25zPWZ1bmN0aW9uKCl7cmV0dXJuKGQuX09ydFJlbGVhc2VTZXNzaW9uT3B0aW9ucz1kLmFzbS5RYSkuYXBwbHkobnVsbCxhcmd1bWVudHMpfTtkLl9PcnRDcmVhdGVTZXNzaW9uPWZ1bmN0aW9uKCl7cmV0dXJuKGQuX09ydENyZWF0ZVNlc3Npb249ZC5hc20uUmEpLmFwcGx5KG51bGwsYXJndW1lbnRzKX07ZC5fT3J0UmVsZWFzZVNlc3Npb249ZnVuY3Rpb24oKXtyZXR1cm4oZC5fT3J0UmVsZWFzZVNlc3Npb249ZC5hc20uU2EpLmFwcGx5KG51bGwsYXJndW1lbnRzKX07ZC5fT3J0R2V0SW5wdXRDb3VudD1mdW5jdGlvbigpe3JldHVybihkLl9PcnRHZXRJbnB1dENvdW50PWQuYXNtLlRhKS5hcHBseShudWxsLGFyZ3VtZW50cyl9O2QuX09ydEdldE91dHB1dENvdW50PWZ1bmN0aW9uKCl7cmV0dXJuKGQuX09ydEdldE91dHB1dENvdW50PWQuYXNtLlVhKS5hcHBseShudWxsLGFyZ3VtZW50cyl9O1xyXG5kLl9PcnRHZXRJbnB1dE5hbWU9ZnVuY3Rpb24oKXtyZXR1cm4oZC5fT3J0R2V0SW5wdXROYW1lPWQuYXNtLlZhKS5hcHBseShudWxsLGFyZ3VtZW50cyl9O2QuX09ydEdldE91dHB1dE5hbWU9ZnVuY3Rpb24oKXtyZXR1cm4oZC5fT3J0R2V0T3V0cHV0TmFtZT1kLmFzbS5XYSkuYXBwbHkobnVsbCxhcmd1bWVudHMpfTtkLl9PcnRGcmVlPWZ1bmN0aW9uKCl7cmV0dXJuKGQuX09ydEZyZWU9ZC5hc20uWGEpLmFwcGx5KG51bGwsYXJndW1lbnRzKX07ZC5fT3J0Q3JlYXRlVGVuc29yPWZ1bmN0aW9uKCl7cmV0dXJuKGQuX09ydENyZWF0ZVRlbnNvcj1kLmFzbS5ZYSkuYXBwbHkobnVsbCxhcmd1bWVudHMpfTtkLl9PcnRHZXRUZW5zb3JEYXRhPWZ1bmN0aW9uKCl7cmV0dXJuKGQuX09ydEdldFRlbnNvckRhdGE9ZC5hc20uWmEpLmFwcGx5KG51bGwsYXJndW1lbnRzKX07XHJcbmQuX09ydFJlbGVhc2VUZW5zb3I9ZnVuY3Rpb24oKXtyZXR1cm4oZC5fT3J0UmVsZWFzZVRlbnNvcj1kLmFzbS5fYSkuYXBwbHkobnVsbCxhcmd1bWVudHMpfTtkLl9PcnRDcmVhdGVSdW5PcHRpb25zPWZ1bmN0aW9uKCl7cmV0dXJuKGQuX09ydENyZWF0ZVJ1bk9wdGlvbnM9ZC5hc20uJGEpLmFwcGx5KG51bGwsYXJndW1lbnRzKX07ZC5fT3J0QWRkUnVuQ29uZmlnRW50cnk9ZnVuY3Rpb24oKXtyZXR1cm4oZC5fT3J0QWRkUnVuQ29uZmlnRW50cnk9ZC5hc20uYWIpLmFwcGx5KG51bGwsYXJndW1lbnRzKX07ZC5fT3J0UmVsZWFzZVJ1bk9wdGlvbnM9ZnVuY3Rpb24oKXtyZXR1cm4oZC5fT3J0UmVsZWFzZVJ1bk9wdGlvbnM9ZC5hc20uYmIpLmFwcGx5KG51bGwsYXJndW1lbnRzKX07ZC5fT3J0UnVuPWZ1bmN0aW9uKCl7cmV0dXJuKGQuX09ydFJ1bj1kLmFzbS5jYikuYXBwbHkobnVsbCxhcmd1bWVudHMpfTtcclxuZC5fT3J0RW5kUHJvZmlsaW5nPWZ1bmN0aW9uKCl7cmV0dXJuKGQuX09ydEVuZFByb2ZpbGluZz1kLmFzbS5kYikuYXBwbHkobnVsbCxhcmd1bWVudHMpfTtcclxudmFyIEphPWQuX21hbGxvYz1mdW5jdGlvbigpe3JldHVybihKYT1kLl9tYWxsb2M9ZC5hc20uZWIpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sSGE9ZC5fZnJlZT1mdW5jdGlvbigpe3JldHVybihIYT1kLl9mcmVlPWQuYXNtLmZiKS5hcHBseShudWxsLGFyZ3VtZW50cyl9LFphPWQuX2ZmbHVzaD1mdW5jdGlvbigpe3JldHVybihaYT1kLl9mZmx1c2g9ZC5hc20uZ2IpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sWWE9ZC5fX19mdW5jc19vbl9leGl0PWZ1bmN0aW9uKCl7cmV0dXJuKFlhPWQuX19fZnVuY3Nfb25fZXhpdD1kLmFzbS5oYikuYXBwbHkobnVsbCxhcmd1bWVudHMpfSxYPWQuX3NldFRocmV3PWZ1bmN0aW9uKCl7cmV0dXJuKFg9ZC5fc2V0VGhyZXc9ZC5hc20uamIpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sWT1kLnN0YWNrU2F2ZT1mdW5jdGlvbigpe3JldHVybihZPWQuc3RhY2tTYXZlPWQuYXNtLmtiKS5hcHBseShudWxsLGFyZ3VtZW50cyl9LFo9ZC5zdGFja1Jlc3RvcmU9XHJcbmZ1bmN0aW9uKCl7cmV0dXJuKFo9ZC5zdGFja1Jlc3RvcmU9ZC5hc20ubGIpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sS2I9ZC5zdGFja0FsbG9jPWZ1bmN0aW9uKCl7cmV0dXJuKEtiPWQuc3RhY2tBbGxvYz1kLmFzbS5tYikuYXBwbHkobnVsbCxhcmd1bWVudHMpfSxYYT1kLl9fX2N4YV9jYW5fY2F0Y2g9ZnVuY3Rpb24oKXtyZXR1cm4oWGE9ZC5fX19jeGFfY2FuX2NhdGNoPWQuYXNtLm5iKS5hcHBseShudWxsLGFyZ3VtZW50cyl9LEZhPWQuX19fY3hhX2lzX3BvaW50ZXJfdHlwZT1mdW5jdGlvbigpe3JldHVybihGYT1kLl9fX2N4YV9pc19wb2ludGVyX3R5cGU9ZC5hc20ub2IpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sTGI9ZC5keW5DYWxsX2o9ZnVuY3Rpb24oKXtyZXR1cm4oTGI9ZC5keW5DYWxsX2o9ZC5hc20ucGIpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sTWI9ZC5keW5DYWxsX2lpaWlpaj1mdW5jdGlvbigpe3JldHVybihNYj1kLmR5bkNhbGxfaWlpaWlqPWQuYXNtLnFiKS5hcHBseShudWxsLFxyXG5hcmd1bWVudHMpfSxOYj1kLmR5bkNhbGxfamlpPWZ1bmN0aW9uKCl7cmV0dXJuKE5iPWQuZHluQ2FsbF9qaWk9ZC5hc20ucmIpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sT2I9ZC5keW5DYWxsX3ZpaWlpaWo9ZnVuY3Rpb24oKXtyZXR1cm4oT2I9ZC5keW5DYWxsX3ZpaWlpaWo9ZC5hc20uc2IpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sUGI9ZC5keW5DYWxsX3Zqamk9ZnVuY3Rpb24oKXtyZXR1cm4oUGI9ZC5keW5DYWxsX3Zqamk9ZC5hc20udGIpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sUWI9ZC5keW5DYWxsX3ZpaWlqamppaT1mdW5jdGlvbigpe3JldHVybihRYj1kLmR5bkNhbGxfdmlpaWpqamlpPWQuYXNtLnViKS5hcHBseShudWxsLGFyZ3VtZW50cyl9LFJiPWQuZHluQ2FsbF9paWo9ZnVuY3Rpb24oKXtyZXR1cm4oUmI9ZC5keW5DYWxsX2lpaj1kLmFzbS52YikuYXBwbHkobnVsbCxhcmd1bWVudHMpfSxTYj1kLmR5bkNhbGxfamk9ZnVuY3Rpb24oKXtyZXR1cm4oU2I9ZC5keW5DYWxsX2ppPVxyXG5kLmFzbS53YikuYXBwbHkobnVsbCxhcmd1bWVudHMpfSxUYj1kLmR5bkNhbGxfaWlpaWlpaj1mdW5jdGlvbigpe3JldHVybihUYj1kLmR5bkNhbGxfaWlpaWlpaj1kLmFzbS54YikuYXBwbHkobnVsbCxhcmd1bWVudHMpfSxVYj1kLmR5bkNhbGxfaWlpaj1mdW5jdGlvbigpe3JldHVybihVYj1kLmR5bkNhbGxfaWlpaj1kLmFzbS55YikuYXBwbHkobnVsbCxhcmd1bWVudHMpfTtmdW5jdGlvbiBjYihhLGIpe3ZhciBjPVkoKTt0cnl7cmV0dXJuIFUoYSkoYil9Y2F0Y2goZSl7WihjKTtpZihlIT09ZSswKXRocm93IGU7WCgxLDApfX1mdW5jdGlvbiB2YihhLGIpe3ZhciBjPVkoKTt0cnl7VShhKShiKX1jYXRjaChlKXtaKGMpO2lmKGUhPT1lKzApdGhyb3cgZTtYKDEsMCl9fWZ1bmN0aW9uIHdiKGEsYixjKXt2YXIgZT1ZKCk7dHJ5e1UoYSkoYixjKX1jYXRjaChmKXtaKGUpO2lmKGYhPT1mKzApdGhyb3cgZjtYKDEsMCl9fVxyXG5mdW5jdGlvbiBmYihhLGIsYyl7dmFyIGU9WSgpO3RyeXtyZXR1cm4gVShhKShiLGMpfWNhdGNoKGYpe1ooZSk7aWYoZiE9PWYrMCl0aHJvdyBmO1goMSwwKX19ZnVuY3Rpb24gZ2IoYSxiLGMsZSl7dmFyIGY9WSgpO3RyeXtyZXR1cm4gVShhKShiLGMsZSl9Y2F0Y2goaCl7WihmKTtpZihoIT09aCswKXRocm93IGg7WCgxLDApfX1mdW5jdGlvbiBrYihhLGIsYyxlLGYsaCxrKXt2YXIgbD1ZKCk7dHJ5e3JldHVybiBVKGEpKGIsYyxlLGYsaCxrKX1jYXRjaChuKXtaKGwpO2lmKG4hPT1uKzApdGhyb3cgbjtYKDEsMCl9fWZ1bmN0aW9uIHViKGEpe3ZhciBiPVkoKTt0cnl7VShhKSgpfWNhdGNoKGMpe1ooYik7aWYoYyE9PWMrMCl0aHJvdyBjO1goMSwwKX19ZnVuY3Rpb24gamIoYSxiLGMsZSxmLGgpe3ZhciBrPVkoKTt0cnl7cmV0dXJuIFUoYSkoYixjLGUsZixoKX1jYXRjaChsKXtaKGspO2lmKGwhPT1sKzApdGhyb3cgbDtYKDEsMCl9fVxyXG5mdW5jdGlvbiBoYihhLGIsYyxlLGYpe3ZhciBoPVkoKTt0cnl7cmV0dXJuIFUoYSkoYixjLGUsZil9Y2F0Y2goayl7WihoKTtpZihrIT09ayswKXRocm93IGs7WCgxLDApfX1mdW5jdGlvbiB5YihhLGIsYyxlKXt2YXIgZj1ZKCk7dHJ5e1UoYSkoYixjLGUpfWNhdGNoKGgpe1ooZik7aWYoaCE9PWgrMCl0aHJvdyBoO1goMSwwKX19ZnVuY3Rpb24gQWIoYSxiLGMsZSxmLGgpe3ZhciBrPVkoKTt0cnl7VShhKShiLGMsZSxmLGgpfWNhdGNoKGwpe1ooayk7aWYobCE9PWwrMCl0aHJvdyBsO1goMSwwKX19ZnVuY3Rpb24gemIoYSxiLGMsZSxmKXt2YXIgaD1ZKCk7dHJ5e1UoYSkoYixjLGUsZil9Y2F0Y2goayl7WihoKTtpZihrIT09ayswKXRocm93IGs7WCgxLDApfX1mdW5jdGlvbiBCYihhLGIsYyxlLGYsaCxrKXt2YXIgbD1ZKCk7dHJ5e1UoYSkoYixjLGUsZixoLGspfWNhdGNoKG4pe1oobCk7aWYobiE9PW4rMCl0aHJvdyBuO1goMSwwKX19XHJcbmZ1bmN0aW9uIENiKGEsYixjLGUsZixoLGssbCl7dmFyIG49WSgpO3RyeXtVKGEpKGIsYyxlLGYsaCxrLGwpfWNhdGNoKHQpe1oobik7aWYodCE9PXQrMCl0aHJvdyB0O1goMSwwKX19ZnVuY3Rpb24gZWIoYSxiLGMpe3ZhciBlPVkoKTt0cnl7cmV0dXJuIFUoYSkoYixjKX1jYXRjaChmKXtaKGUpO2lmKGYhPT1mKzApdGhyb3cgZjtYKDEsMCl9fWZ1bmN0aW9uIGRiKGEsYixjKXt2YXIgZT1ZKCk7dHJ5e3JldHVybiBVKGEpKGIsYyl9Y2F0Y2goZil7WihlKTtpZihmIT09ZiswKXRocm93IGY7WCgxLDApfX1mdW5jdGlvbiBEYihhLGIsYyxlLGYsaCxrLGwsbil7dmFyIHQ9WSgpO3RyeXtVKGEpKGIsYyxlLGYsaCxrLGwsbil9Y2F0Y2goeCl7Wih0KTtpZih4IT09eCswKXRocm93IHg7WCgxLDApfX1mdW5jdGlvbiBpYihhLGIsYyxlLGYsaCl7dmFyIGs9WSgpO3RyeXtyZXR1cm4gVShhKShiLGMsZSxmLGgpfWNhdGNoKGwpe1ooayk7aWYobCE9PWwrMCl0aHJvdyBsO1goMSwwKX19XHJcbmZ1bmN0aW9uIGxiKGEsYixjLGUsZixoLGssbCl7dmFyIG49WSgpO3RyeXtyZXR1cm4gVShhKShiLGMsZSxmLGgsayxsKX1jYXRjaCh0KXtaKG4pO2lmKHQhPT10KzApdGhyb3cgdDtYKDEsMCl9fWZ1bmN0aW9uIG1iKGEsYixjLGUsZixoLGssbCxuLHQseCxFKXt2YXIgQz1ZKCk7dHJ5e3JldHVybiBVKGEpKGIsYyxlLGYsaCxrLGwsbix0LHgsRSl9Y2F0Y2goZyl7WihDKTtpZihnIT09ZyswKXRocm93IGc7WCgxLDApfX1mdW5jdGlvbiBFYihhLGIsYyxlLGYsaCxrLGwsbix0LHgpe3ZhciBFPVkoKTt0cnl7VShhKShiLGMsZSxmLGgsayxsLG4sdCx4KX1jYXRjaChDKXtaKEUpO2lmKEMhPT1DKzApdGhyb3cgQztYKDEsMCl9fWZ1bmN0aW9uIEZiKGEsYixjLGUsZixoLGssbCxuLHQseCxFLEMsZyx1LHcpe3ZhciBGPVkoKTt0cnl7VShhKShiLGMsZSxmLGgsayxsLG4sdCx4LEUsQyxnLHUsdyl9Y2F0Y2goTSl7WihGKTtpZihNIT09TSswKXRocm93IE07WCgxLDApfX1cclxuZnVuY3Rpb24gYmIoYSl7dmFyIGI9WSgpO3RyeXtyZXR1cm4gVShhKSgpfWNhdGNoKGMpe1ooYik7aWYoYyE9PWMrMCl0aHJvdyBjO1goMSwwKX19ZnVuY3Rpb24gYWIoYSxiLGMpe3ZhciBlPVkoKTt0cnl7cmV0dXJuIFUoYSkoYixjKX1jYXRjaChmKXtaKGUpO2lmKGYhPT1mKzApdGhyb3cgZjtYKDEsMCl9fWZ1bmN0aW9uICRhKGEsYixjKXt2YXIgZT1ZKCk7dHJ5e3JldHVybiBVKGEpKGIsYyl9Y2F0Y2goZil7WihlKTtpZihmIT09ZiswKXRocm93IGY7WCgxLDApfX1mdW5jdGlvbiB4YihhLGIsYyxlKXt2YXIgZj1ZKCk7dHJ5e1UoYSkoYixjLGUpfWNhdGNoKGgpe1ooZik7aWYoaCE9PWgrMCl0aHJvdyBoO1goMSwwKX19ZnVuY3Rpb24gR2IoYSxiLGMsZSxmLGgsayxsKXt2YXIgbj1ZKCk7dHJ5e09iKGEsYixjLGUsZixoLGssbCl9Y2F0Y2godCl7WihuKTtpZih0IT09dCswKXRocm93IHQ7WCgxLDApfX1cclxuZnVuY3Rpb24gSWIoYSxiLGMsZSxmLGgpe3ZhciBrPVkoKTt0cnl7UGIoYSxiLGMsZSxmLGgpfWNhdGNoKGwpe1ooayk7aWYobCE9PWwrMCl0aHJvdyBsO1goMSwwKX19ZnVuY3Rpb24gSGIoYSxiLGMsZSxmLGgsayxsLG4sdCx4LEUpe3ZhciBDPVkoKTt0cnl7UWIoYSxiLGMsZSxmLGgsayxsLG4sdCx4LEUpfWNhdGNoKGcpe1ooQyk7aWYoZyE9PWcrMCl0aHJvdyBnO1goMSwwKX19ZnVuY3Rpb24gcWIoYSxiLGMsZSl7dmFyIGY9WSgpO3RyeXtyZXR1cm4gUmIoYSxiLGMsZSl9Y2F0Y2goaCl7WihmKTtpZihoIT09aCswKXRocm93IGg7WCgxLDApfX1mdW5jdGlvbiBzYihhLGIpe3ZhciBjPVkoKTt0cnl7cmV0dXJuIFNiKGEsYil9Y2F0Y2goZSl7WihjKTtpZihlIT09ZSswKXRocm93IGU7WCgxLDApfX1cclxuZnVuY3Rpb24gbmIoYSxiLGMsZSxmLGgsayxsKXt2YXIgbj1ZKCk7dHJ5e3JldHVybiBUYihhLGIsYyxlLGYsaCxrLGwpfWNhdGNoKHQpe1oobik7aWYodCE9PXQrMCl0aHJvdyB0O1goMSwwKX19ZnVuY3Rpb24gcmIoYSl7dmFyIGI9WSgpO3RyeXtyZXR1cm4gTGIoYSl9Y2F0Y2goYyl7WihiKTtpZihjIT09YyswKXRocm93IGM7WCgxLDApfX1mdW5jdGlvbiBvYihhLGIsYyxlLGYsaCxrKXt2YXIgbD1ZKCk7dHJ5e3JldHVybiBNYihhLGIsYyxlLGYsaCxrKX1jYXRjaChuKXtaKGwpO2lmKG4hPT1uKzApdGhyb3cgbjtYKDEsMCl9fWZ1bmN0aW9uIHBiKGEsYixjLGUsZil7dmFyIGg9WSgpO3RyeXtyZXR1cm4gVWIoYSxiLGMsZSxmKX1jYXRjaChrKXtaKGgpO2lmKGshPT1rKzApdGhyb3cgaztYKDEsMCl9fWZ1bmN0aW9uIHRiKGEsYixjKXt2YXIgZT1ZKCk7dHJ5e3JldHVybiBOYihhLGIsYyl9Y2F0Y2goZil7WihlKTtpZihmIT09ZiswKXRocm93IGY7WCgxLDApfX1cclxuZC5VVEY4VG9TdHJpbmc9cGE7ZC5zdHJpbmdUb1VURjg9ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBxYShhLEcsYixjKX07ZC5sZW5ndGhCeXRlc1VURjg9cmE7ZC5zdGFja1NhdmU9WTtkLnN0YWNrUmVzdG9yZT1aO2Quc3RhY2tBbGxvYz1LYjt2YXIgVmI7TD1mdW5jdGlvbiBXYigpe1ZifHxYYigpO1ZifHwoTD1XYil9O1xyXG5mdW5jdGlvbiBYYigpe2Z1bmN0aW9uIGEoKXtpZighVmImJihWYj0hMCxkLmNhbGxlZFJ1bj0hMCwhRCkpe08od2EpO2FhKGQpO2lmKGQub25SdW50aW1lSW5pdGlhbGl6ZWQpZC5vblJ1bnRpbWVJbml0aWFsaXplZCgpO2lmKGQucG9zdFJ1bilmb3IoXCJmdW5jdGlvblwiPT10eXBlb2YgZC5wb3N0UnVuJiYoZC5wb3N0UnVuPVtkLnBvc3RSdW5dKTtkLnBvc3RSdW4ubGVuZ3RoOyl7dmFyIGI9ZC5wb3N0UnVuLnNoaWZ0KCk7eWEudW5zaGlmdChiKX1PKHlhKX19aWYoISgwPEspKXtpZihkLnByZVJ1bilmb3IoXCJmdW5jdGlvblwiPT10eXBlb2YgZC5wcmVSdW4mJihkLnByZVJ1bj1bZC5wcmVSdW5dKTtkLnByZVJ1bi5sZW5ndGg7KXphKCk7Tyh2YSk7MDxLfHwoZC5zZXRTdGF0dXM/KGQuc2V0U3RhdHVzKFwiUnVubmluZy4uLlwiKSxzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7c2V0VGltZW91dChmdW5jdGlvbigpe2Quc2V0U3RhdHVzKFwiXCIpfSwxKTthKCl9LDEpKTphKCkpfX1cclxuaWYoZC5wcmVJbml0KWZvcihcImZ1bmN0aW9uXCI9PXR5cGVvZiBkLnByZUluaXQmJihkLnByZUluaXQ9W2QucHJlSW5pdF0pOzA8ZC5wcmVJbml0Lmxlbmd0aDspZC5wcmVJbml0LnBvcCgpKCk7WGIoKTtcclxuXHJcblxyXG4gIHJldHVybiBvcnRXYXNtLnJlYWR5XHJcbn1cclxuKTtcclxufSkoKTtcclxuaWYgKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0JylcclxuICBtb2R1bGUuZXhwb3J0cyA9IG9ydFdhc207XHJcbmVsc2UgaWYgKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lWydhbWQnXSlcclxuICBkZWZpbmUoW10sIGZ1bmN0aW9uKCkgeyByZXR1cm4gb3J0V2FzbTsgfSk7XHJcbmVsc2UgaWYgKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0JylcclxuICBleHBvcnRzW1wib3J0V2FzbVwiXSA9IG9ydFdhc207XHJcbiIsIlwidXNlIHN0cmljdFwiO1xyXG5tb2R1bGUuZXhwb3J0cyA9IGFzUHJvbWlzZTtcclxuXHJcbi8qKlxyXG4gKiBDYWxsYmFjayBhcyB1c2VkIGJ5IHtAbGluayB1dGlsLmFzUHJvbWlzZX0uXHJcbiAqIEB0eXBlZGVmIGFzUHJvbWlzZUNhbGxiYWNrXHJcbiAqIEB0eXBlIHtmdW5jdGlvbn1cclxuICogQHBhcmFtIHtFcnJvcnxudWxsfSBlcnJvciBFcnJvciwgaWYgYW55XHJcbiAqIEBwYXJhbSB7Li4uKn0gcGFyYW1zIEFkZGl0aW9uYWwgYXJndW1lbnRzXHJcbiAqIEByZXR1cm5zIHt1bmRlZmluZWR9XHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgYSBwcm9taXNlIGZyb20gYSBub2RlLXN0eWxlIGNhbGxiYWNrIGZ1bmN0aW9uLlxyXG4gKiBAbWVtYmVyb2YgdXRpbFxyXG4gKiBAcGFyYW0ge2FzUHJvbWlzZUNhbGxiYWNrfSBmbiBGdW5jdGlvbiB0byBjYWxsXHJcbiAqIEBwYXJhbSB7Kn0gY3R4IEZ1bmN0aW9uIGNvbnRleHRcclxuICogQHBhcmFtIHsuLi4qfSBwYXJhbXMgRnVuY3Rpb24gYXJndW1lbnRzXHJcbiAqIEByZXR1cm5zIHtQcm9taXNlPCo+fSBQcm9taXNpZmllZCBmdW5jdGlvblxyXG4gKi9cclxuZnVuY3Rpb24gYXNQcm9taXNlKGZuLCBjdHgvKiwgdmFyYXJncyAqLykge1xyXG4gICAgdmFyIHBhcmFtcyAgPSBuZXcgQXJyYXkoYXJndW1lbnRzLmxlbmd0aCAtIDEpLFxyXG4gICAgICAgIG9mZnNldCAgPSAwLFxyXG4gICAgICAgIGluZGV4ICAgPSAyLFxyXG4gICAgICAgIHBlbmRpbmcgPSB0cnVlO1xyXG4gICAgd2hpbGUgKGluZGV4IDwgYXJndW1lbnRzLmxlbmd0aClcclxuICAgICAgICBwYXJhbXNbb2Zmc2V0KytdID0gYXJndW1lbnRzW2luZGV4KytdO1xyXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIGV4ZWN1dG9yKHJlc29sdmUsIHJlamVjdCkge1xyXG4gICAgICAgIHBhcmFtc1tvZmZzZXRdID0gZnVuY3Rpb24gY2FsbGJhY2soZXJyLyosIHZhcmFyZ3MgKi8pIHtcclxuICAgICAgICAgICAgaWYgKHBlbmRpbmcpIHtcclxuICAgICAgICAgICAgICAgIHBlbmRpbmcgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIGlmIChlcnIpXHJcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycik7XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcGFyYW1zID0gbmV3IEFycmF5KGFyZ3VtZW50cy5sZW5ndGggLSAxKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ID0gMDtcclxuICAgICAgICAgICAgICAgICAgICB3aGlsZSAob2Zmc2V0IDwgcGFyYW1zLmxlbmd0aClcclxuICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1zW29mZnNldCsrXSA9IGFyZ3VtZW50c1tvZmZzZXRdO1xyXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUuYXBwbHkobnVsbCwgcGFyYW1zKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgZm4uYXBwbHkoY3R4IHx8IG51bGwsIHBhcmFtcyk7XHJcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgICAgIGlmIChwZW5kaW5nKSB7XHJcbiAgICAgICAgICAgICAgICBwZW5kaW5nID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH0pO1xyXG59XHJcbiIsIlwidXNlIHN0cmljdFwiO1xyXG5cclxuLyoqXHJcbiAqIEEgbWluaW1hbCBiYXNlNjQgaW1wbGVtZW50YXRpb24gZm9yIG51bWJlciBhcnJheXMuXHJcbiAqIEBtZW1iZXJvZiB1dGlsXHJcbiAqIEBuYW1lc3BhY2VcclxuICovXHJcbnZhciBiYXNlNjQgPSBleHBvcnRzO1xyXG5cclxuLyoqXHJcbiAqIENhbGN1bGF0ZXMgdGhlIGJ5dGUgbGVuZ3RoIG9mIGEgYmFzZTY0IGVuY29kZWQgc3RyaW5nLlxyXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIEJhc2U2NCBlbmNvZGVkIHN0cmluZ1xyXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBCeXRlIGxlbmd0aFxyXG4gKi9cclxuYmFzZTY0Lmxlbmd0aCA9IGZ1bmN0aW9uIGxlbmd0aChzdHJpbmcpIHtcclxuICAgIHZhciBwID0gc3RyaW5nLmxlbmd0aDtcclxuICAgIGlmICghcClcclxuICAgICAgICByZXR1cm4gMDtcclxuICAgIHZhciBuID0gMDtcclxuICAgIHdoaWxlICgtLXAgJSA0ID4gMSAmJiBzdHJpbmcuY2hhckF0KHApID09PSBcIj1cIilcclxuICAgICAgICArK247XHJcbiAgICByZXR1cm4gTWF0aC5jZWlsKHN0cmluZy5sZW5ndGggKiAzKSAvIDQgLSBuO1xyXG59O1xyXG5cclxuLy8gQmFzZTY0IGVuY29kaW5nIHRhYmxlXHJcbnZhciBiNjQgPSBuZXcgQXJyYXkoNjQpO1xyXG5cclxuLy8gQmFzZTY0IGRlY29kaW5nIHRhYmxlXHJcbnZhciBzNjQgPSBuZXcgQXJyYXkoMTIzKTtcclxuXHJcbi8vIDY1Li45MCwgOTcuLjEyMiwgNDguLjU3LCA0MywgNDdcclxuZm9yICh2YXIgaSA9IDA7IGkgPCA2NDspXHJcbiAgICBzNjRbYjY0W2ldID0gaSA8IDI2ID8gaSArIDY1IDogaSA8IDUyID8gaSArIDcxIDogaSA8IDYyID8gaSAtIDQgOiBpIC0gNTkgfCA0M10gPSBpKys7XHJcblxyXG4vKipcclxuICogRW5jb2RlcyBhIGJ1ZmZlciB0byBhIGJhc2U2NCBlbmNvZGVkIHN0cmluZy5cclxuICogQHBhcmFtIHtVaW50OEFycmF5fSBidWZmZXIgU291cmNlIGJ1ZmZlclxyXG4gKiBAcGFyYW0ge251bWJlcn0gc3RhcnQgU291cmNlIHN0YXJ0XHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgU291cmNlIGVuZFxyXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBCYXNlNjQgZW5jb2RlZCBzdHJpbmdcclxuICovXHJcbmJhc2U2NC5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUoYnVmZmVyLCBzdGFydCwgZW5kKSB7XHJcbiAgICB2YXIgcGFydHMgPSBudWxsLFxyXG4gICAgICAgIGNodW5rID0gW107XHJcbiAgICB2YXIgaSA9IDAsIC8vIG91dHB1dCBpbmRleFxyXG4gICAgICAgIGogPSAwLCAvLyBnb3RvIGluZGV4XHJcbiAgICAgICAgdDsgICAgIC8vIHRlbXBvcmFyeVxyXG4gICAgd2hpbGUgKHN0YXJ0IDwgZW5kKSB7XHJcbiAgICAgICAgdmFyIGIgPSBidWZmZXJbc3RhcnQrK107XHJcbiAgICAgICAgc3dpdGNoIChqKSB7XHJcbiAgICAgICAgICAgIGNhc2UgMDpcclxuICAgICAgICAgICAgICAgIGNodW5rW2krK10gPSBiNjRbYiA+PiAyXTtcclxuICAgICAgICAgICAgICAgIHQgPSAoYiAmIDMpIDw8IDQ7XHJcbiAgICAgICAgICAgICAgICBqID0gMTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBjYXNlIDE6XHJcbiAgICAgICAgICAgICAgICBjaHVua1tpKytdID0gYjY0W3QgfCBiID4+IDRdO1xyXG4gICAgICAgICAgICAgICAgdCA9IChiICYgMTUpIDw8IDI7XHJcbiAgICAgICAgICAgICAgICBqID0gMjtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBjYXNlIDI6XHJcbiAgICAgICAgICAgICAgICBjaHVua1tpKytdID0gYjY0W3QgfCBiID4+IDZdO1xyXG4gICAgICAgICAgICAgICAgY2h1bmtbaSsrXSA9IGI2NFtiICYgNjNdO1xyXG4gICAgICAgICAgICAgICAgaiA9IDA7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGkgPiA4MTkxKSB7XHJcbiAgICAgICAgICAgIChwYXJ0cyB8fCAocGFydHMgPSBbXSkpLnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShTdHJpbmcsIGNodW5rKSk7XHJcbiAgICAgICAgICAgIGkgPSAwO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGlmIChqKSB7XHJcbiAgICAgICAgY2h1bmtbaSsrXSA9IGI2NFt0XTtcclxuICAgICAgICBjaHVua1tpKytdID0gNjE7XHJcbiAgICAgICAgaWYgKGogPT09IDEpXHJcbiAgICAgICAgICAgIGNodW5rW2krK10gPSA2MTtcclxuICAgIH1cclxuICAgIGlmIChwYXJ0cykge1xyXG4gICAgICAgIGlmIChpKVxyXG4gICAgICAgICAgICBwYXJ0cy5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLCBjaHVuay5zbGljZSgwLCBpKSkpO1xyXG4gICAgICAgIHJldHVybiBwYXJ0cy5qb2luKFwiXCIpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLCBjaHVuay5zbGljZSgwLCBpKSk7XHJcbn07XHJcblxyXG52YXIgaW52YWxpZEVuY29kaW5nID0gXCJpbnZhbGlkIGVuY29kaW5nXCI7XHJcblxyXG4vKipcclxuICogRGVjb2RlcyBhIGJhc2U2NCBlbmNvZGVkIHN0cmluZyB0byBhIGJ1ZmZlci5cclxuICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBTb3VyY2Ugc3RyaW5nXHJcbiAqIEBwYXJhbSB7VWludDhBcnJheX0gYnVmZmVyIERlc3RpbmF0aW9uIGJ1ZmZlclxyXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IERlc3RpbmF0aW9uIG9mZnNldFxyXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBOdW1iZXIgb2YgYnl0ZXMgd3JpdHRlblxyXG4gKiBAdGhyb3dzIHtFcnJvcn0gSWYgZW5jb2RpbmcgaXMgaW52YWxpZFxyXG4gKi9cclxuYmFzZTY0LmRlY29kZSA9IGZ1bmN0aW9uIGRlY29kZShzdHJpbmcsIGJ1ZmZlciwgb2Zmc2V0KSB7XHJcbiAgICB2YXIgc3RhcnQgPSBvZmZzZXQ7XHJcbiAgICB2YXIgaiA9IDAsIC8vIGdvdG8gaW5kZXhcclxuICAgICAgICB0OyAgICAgLy8gdGVtcG9yYXJ5XHJcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN0cmluZy5sZW5ndGg7KSB7XHJcbiAgICAgICAgdmFyIGMgPSBzdHJpbmcuY2hhckNvZGVBdChpKyspO1xyXG4gICAgICAgIGlmIChjID09PSA2MSAmJiBqID4gMSlcclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgaWYgKChjID0gczY0W2NdKSA9PT0gdW5kZWZpbmVkKVxyXG4gICAgICAgICAgICB0aHJvdyBFcnJvcihpbnZhbGlkRW5jb2RpbmcpO1xyXG4gICAgICAgIHN3aXRjaCAoaikge1xyXG4gICAgICAgICAgICBjYXNlIDA6XHJcbiAgICAgICAgICAgICAgICB0ID0gYztcclxuICAgICAgICAgICAgICAgIGogPSAxO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGNhc2UgMTpcclxuICAgICAgICAgICAgICAgIGJ1ZmZlcltvZmZzZXQrK10gPSB0IDw8IDIgfCAoYyAmIDQ4KSA+PiA0O1xyXG4gICAgICAgICAgICAgICAgdCA9IGM7XHJcbiAgICAgICAgICAgICAgICBqID0gMjtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBjYXNlIDI6XHJcbiAgICAgICAgICAgICAgICBidWZmZXJbb2Zmc2V0KytdID0gKHQgJiAxNSkgPDwgNCB8IChjICYgNjApID4+IDI7XHJcbiAgICAgICAgICAgICAgICB0ID0gYztcclxuICAgICAgICAgICAgICAgIGogPSAzO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGNhc2UgMzpcclxuICAgICAgICAgICAgICAgIGJ1ZmZlcltvZmZzZXQrK10gPSAodCAmIDMpIDw8IDYgfCBjO1xyXG4gICAgICAgICAgICAgICAgaiA9IDA7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBpZiAoaiA9PT0gMSlcclxuICAgICAgICB0aHJvdyBFcnJvcihpbnZhbGlkRW5jb2RpbmcpO1xyXG4gICAgcmV0dXJuIG9mZnNldCAtIHN0YXJ0O1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFRlc3RzIGlmIHRoZSBzcGVjaWZpZWQgc3RyaW5nIGFwcGVhcnMgdG8gYmUgYmFzZTY0IGVuY29kZWQuXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgU3RyaW5nIHRvIHRlc3RcclxuICogQHJldHVybnMge2Jvb2xlYW59IGB0cnVlYCBpZiBwcm9iYWJseSBiYXNlNjQgZW5jb2RlZCwgb3RoZXJ3aXNlIGZhbHNlXHJcbiAqL1xyXG5iYXNlNjQudGVzdCA9IGZ1bmN0aW9uIHRlc3Qoc3RyaW5nKSB7XHJcbiAgICByZXR1cm4gL14oPzpbQS1aYS16MC05Ky9dezR9KSooPzpbQS1aYS16MC05Ky9dezJ9PT18W0EtWmEtejAtOSsvXXszfT0pPyQvLnRlc3Qoc3RyaW5nKTtcclxufTtcclxuIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbm1vZHVsZS5leHBvcnRzID0gRXZlbnRFbWl0dGVyO1xyXG5cclxuLyoqXHJcbiAqIENvbnN0cnVjdHMgYSBuZXcgZXZlbnQgZW1pdHRlciBpbnN0YW5jZS5cclxuICogQGNsYXNzZGVzYyBBIG1pbmltYWwgZXZlbnQgZW1pdHRlci5cclxuICogQG1lbWJlcm9mIHV0aWxcclxuICogQGNvbnN0cnVjdG9yXHJcbiAqL1xyXG5mdW5jdGlvbiBFdmVudEVtaXR0ZXIoKSB7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZWdpc3RlcmVkIGxpc3RlbmVycy5cclxuICAgICAqIEB0eXBlIHtPYmplY3QuPHN0cmluZywqPn1cclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIHRoaXMuX2xpc3RlbmVycyA9IHt9O1xyXG59XHJcblxyXG4vKipcclxuICogUmVnaXN0ZXJzIGFuIGV2ZW50IGxpc3RlbmVyLlxyXG4gKiBAcGFyYW0ge3N0cmluZ30gZXZ0IEV2ZW50IG5hbWVcclxuICogQHBhcmFtIHtmdW5jdGlvbn0gZm4gTGlzdGVuZXJcclxuICogQHBhcmFtIHsqfSBbY3R4XSBMaXN0ZW5lciBjb250ZXh0XHJcbiAqIEByZXR1cm5zIHt1dGlsLkV2ZW50RW1pdHRlcn0gYHRoaXNgXHJcbiAqL1xyXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uID0gZnVuY3Rpb24gb24oZXZ0LCBmbiwgY3R4KSB7XHJcbiAgICAodGhpcy5fbGlzdGVuZXJzW2V2dF0gfHwgKHRoaXMuX2xpc3RlbmVyc1tldnRdID0gW10pKS5wdXNoKHtcclxuICAgICAgICBmbiAgOiBmbixcclxuICAgICAgICBjdHggOiBjdHggfHwgdGhpc1xyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gdGhpcztcclxufTtcclxuXHJcbi8qKlxyXG4gKiBSZW1vdmVzIGFuIGV2ZW50IGxpc3RlbmVyIG9yIGFueSBtYXRjaGluZyBsaXN0ZW5lcnMgaWYgYXJndW1lbnRzIGFyZSBvbWl0dGVkLlxyXG4gKiBAcGFyYW0ge3N0cmluZ30gW2V2dF0gRXZlbnQgbmFtZS4gUmVtb3ZlcyBhbGwgbGlzdGVuZXJzIGlmIG9taXR0ZWQuXHJcbiAqIEBwYXJhbSB7ZnVuY3Rpb259IFtmbl0gTGlzdGVuZXIgdG8gcmVtb3ZlLiBSZW1vdmVzIGFsbCBsaXN0ZW5lcnMgb2YgYGV2dGAgaWYgb21pdHRlZC5cclxuICogQHJldHVybnMge3V0aWwuRXZlbnRFbWl0dGVyfSBgdGhpc2BcclxuICovXHJcbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub2ZmID0gZnVuY3Rpb24gb2ZmKGV2dCwgZm4pIHtcclxuICAgIGlmIChldnQgPT09IHVuZGVmaW5lZClcclxuICAgICAgICB0aGlzLl9saXN0ZW5lcnMgPSB7fTtcclxuICAgIGVsc2Uge1xyXG4gICAgICAgIGlmIChmbiA9PT0gdW5kZWZpbmVkKVxyXG4gICAgICAgICAgICB0aGlzLl9saXN0ZW5lcnNbZXZ0XSA9IFtdO1xyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB2YXIgbGlzdGVuZXJzID0gdGhpcy5fbGlzdGVuZXJzW2V2dF07XHJcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGlzdGVuZXJzLmxlbmd0aDspXHJcbiAgICAgICAgICAgICAgICBpZiAobGlzdGVuZXJzW2ldLmZuID09PSBmbilcclxuICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcnMuc3BsaWNlKGksIDEpO1xyXG4gICAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICAgICsraTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcztcclxufTtcclxuXHJcbi8qKlxyXG4gKiBFbWl0cyBhbiBldmVudCBieSBjYWxsaW5nIGl0cyBsaXN0ZW5lcnMgd2l0aCB0aGUgc3BlY2lmaWVkIGFyZ3VtZW50cy5cclxuICogQHBhcmFtIHtzdHJpbmd9IGV2dCBFdmVudCBuYW1lXHJcbiAqIEBwYXJhbSB7Li4uKn0gYXJncyBBcmd1bWVudHNcclxuICogQHJldHVybnMge3V0aWwuRXZlbnRFbWl0dGVyfSBgdGhpc2BcclxuICovXHJcbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uIGVtaXQoZXZ0KSB7XHJcbiAgICB2YXIgbGlzdGVuZXJzID0gdGhpcy5fbGlzdGVuZXJzW2V2dF07XHJcbiAgICBpZiAobGlzdGVuZXJzKSB7XHJcbiAgICAgICAgdmFyIGFyZ3MgPSBbXSxcclxuICAgICAgICAgICAgaSA9IDE7XHJcbiAgICAgICAgZm9yICg7IGkgPCBhcmd1bWVudHMubGVuZ3RoOylcclxuICAgICAgICAgICAgYXJncy5wdXNoKGFyZ3VtZW50c1tpKytdKTtcclxuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGlzdGVuZXJzLmxlbmd0aDspXHJcbiAgICAgICAgICAgIGxpc3RlbmVyc1tpXS5mbi5hcHBseShsaXN0ZW5lcnNbaSsrXS5jdHgsIGFyZ3MpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbn07XHJcbiIsIlwidXNlIHN0cmljdFwiO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KGZhY3RvcnkpO1xyXG5cclxuLyoqXHJcbiAqIFJlYWRzIC8gd3JpdGVzIGZsb2F0cyAvIGRvdWJsZXMgZnJvbSAvIHRvIGJ1ZmZlcnMuXHJcbiAqIEBuYW1lIHV0aWwuZmxvYXRcclxuICogQG5hbWVzcGFjZVxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBXcml0ZXMgYSAzMiBiaXQgZmxvYXQgdG8gYSBidWZmZXIgdXNpbmcgbGl0dGxlIGVuZGlhbiBieXRlIG9yZGVyLlxyXG4gKiBAbmFtZSB1dGlsLmZsb2F0LndyaXRlRmxvYXRMRVxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHtudW1iZXJ9IHZhbCBWYWx1ZSB0byB3cml0ZVxyXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGJ1ZiBUYXJnZXQgYnVmZmVyXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBwb3MgVGFyZ2V0IGJ1ZmZlciBvZmZzZXRcclxuICogQHJldHVybnMge3VuZGVmaW5lZH1cclxuICovXHJcblxyXG4vKipcclxuICogV3JpdGVzIGEgMzIgYml0IGZsb2F0IHRvIGEgYnVmZmVyIHVzaW5nIGJpZyBlbmRpYW4gYnl0ZSBvcmRlci5cclxuICogQG5hbWUgdXRpbC5mbG9hdC53cml0ZUZsb2F0QkVcclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWwgVmFsdWUgdG8gd3JpdGVcclxuICogQHBhcmFtIHtVaW50OEFycmF5fSBidWYgVGFyZ2V0IGJ1ZmZlclxyXG4gKiBAcGFyYW0ge251bWJlcn0gcG9zIFRhcmdldCBidWZmZXIgb2Zmc2V0XHJcbiAqIEByZXR1cm5zIHt1bmRlZmluZWR9XHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIFJlYWRzIGEgMzIgYml0IGZsb2F0IGZyb20gYSBidWZmZXIgdXNpbmcgbGl0dGxlIGVuZGlhbiBieXRlIG9yZGVyLlxyXG4gKiBAbmFtZSB1dGlsLmZsb2F0LnJlYWRGbG9hdExFXHJcbiAqIEBmdW5jdGlvblxyXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGJ1ZiBTb3VyY2UgYnVmZmVyXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBwb3MgU291cmNlIGJ1ZmZlciBvZmZzZXRcclxuICogQHJldHVybnMge251bWJlcn0gVmFsdWUgcmVhZFxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBSZWFkcyBhIDMyIGJpdCBmbG9hdCBmcm9tIGEgYnVmZmVyIHVzaW5nIGJpZyBlbmRpYW4gYnl0ZSBvcmRlci5cclxuICogQG5hbWUgdXRpbC5mbG9hdC5yZWFkRmxvYXRCRVxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHtVaW50OEFycmF5fSBidWYgU291cmNlIGJ1ZmZlclxyXG4gKiBAcGFyYW0ge251bWJlcn0gcG9zIFNvdXJjZSBidWZmZXIgb2Zmc2V0XHJcbiAqIEByZXR1cm5zIHtudW1iZXJ9IFZhbHVlIHJlYWRcclxuICovXHJcblxyXG4vKipcclxuICogV3JpdGVzIGEgNjQgYml0IGRvdWJsZSB0byBhIGJ1ZmZlciB1c2luZyBsaXR0bGUgZW5kaWFuIGJ5dGUgb3JkZXIuXHJcbiAqIEBuYW1lIHV0aWwuZmxvYXQud3JpdGVEb3VibGVMRVxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHtudW1iZXJ9IHZhbCBWYWx1ZSB0byB3cml0ZVxyXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGJ1ZiBUYXJnZXQgYnVmZmVyXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBwb3MgVGFyZ2V0IGJ1ZmZlciBvZmZzZXRcclxuICogQHJldHVybnMge3VuZGVmaW5lZH1cclxuICovXHJcblxyXG4vKipcclxuICogV3JpdGVzIGEgNjQgYml0IGRvdWJsZSB0byBhIGJ1ZmZlciB1c2luZyBiaWcgZW5kaWFuIGJ5dGUgb3JkZXIuXHJcbiAqIEBuYW1lIHV0aWwuZmxvYXQud3JpdGVEb3VibGVCRVxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHtudW1iZXJ9IHZhbCBWYWx1ZSB0byB3cml0ZVxyXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGJ1ZiBUYXJnZXQgYnVmZmVyXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBwb3MgVGFyZ2V0IGJ1ZmZlciBvZmZzZXRcclxuICogQHJldHVybnMge3VuZGVmaW5lZH1cclxuICovXHJcblxyXG4vKipcclxuICogUmVhZHMgYSA2NCBiaXQgZG91YmxlIGZyb20gYSBidWZmZXIgdXNpbmcgbGl0dGxlIGVuZGlhbiBieXRlIG9yZGVyLlxyXG4gKiBAbmFtZSB1dGlsLmZsb2F0LnJlYWREb3VibGVMRVxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHtVaW50OEFycmF5fSBidWYgU291cmNlIGJ1ZmZlclxyXG4gKiBAcGFyYW0ge251bWJlcn0gcG9zIFNvdXJjZSBidWZmZXIgb2Zmc2V0XHJcbiAqIEByZXR1cm5zIHtudW1iZXJ9IFZhbHVlIHJlYWRcclxuICovXHJcblxyXG4vKipcclxuICogUmVhZHMgYSA2NCBiaXQgZG91YmxlIGZyb20gYSBidWZmZXIgdXNpbmcgYmlnIGVuZGlhbiBieXRlIG9yZGVyLlxyXG4gKiBAbmFtZSB1dGlsLmZsb2F0LnJlYWREb3VibGVCRVxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHtVaW50OEFycmF5fSBidWYgU291cmNlIGJ1ZmZlclxyXG4gKiBAcGFyYW0ge251bWJlcn0gcG9zIFNvdXJjZSBidWZmZXIgb2Zmc2V0XHJcbiAqIEByZXR1cm5zIHtudW1iZXJ9IFZhbHVlIHJlYWRcclxuICovXHJcblxyXG4vLyBGYWN0b3J5IGZ1bmN0aW9uIGZvciB0aGUgcHVycG9zZSBvZiBub2RlLWJhc2VkIHRlc3RpbmcgaW4gbW9kaWZpZWQgZ2xvYmFsIGVudmlyb25tZW50c1xyXG5mdW5jdGlvbiBmYWN0b3J5KGV4cG9ydHMpIHtcclxuXHJcbiAgICAvLyBmbG9hdDogdHlwZWQgYXJyYXlcclxuICAgIGlmICh0eXBlb2YgRmxvYXQzMkFycmF5ICE9PSBcInVuZGVmaW5lZFwiKSAoZnVuY3Rpb24oKSB7XHJcblxyXG4gICAgICAgIHZhciBmMzIgPSBuZXcgRmxvYXQzMkFycmF5KFsgLTAgXSksXHJcbiAgICAgICAgICAgIGY4YiA9IG5ldyBVaW50OEFycmF5KGYzMi5idWZmZXIpLFxyXG4gICAgICAgICAgICBsZSAgPSBmOGJbM10gPT09IDEyODtcclxuXHJcbiAgICAgICAgZnVuY3Rpb24gd3JpdGVGbG9hdF9mMzJfY3B5KHZhbCwgYnVmLCBwb3MpIHtcclxuICAgICAgICAgICAgZjMyWzBdID0gdmFsO1xyXG4gICAgICAgICAgICBidWZbcG9zICAgIF0gPSBmOGJbMF07XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgKyAxXSA9IGY4YlsxXTtcclxuICAgICAgICAgICAgYnVmW3BvcyArIDJdID0gZjhiWzJdO1xyXG4gICAgICAgICAgICBidWZbcG9zICsgM10gPSBmOGJbM107XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmdW5jdGlvbiB3cml0ZUZsb2F0X2YzMl9yZXYodmFsLCBidWYsIHBvcykge1xyXG4gICAgICAgICAgICBmMzJbMF0gPSB2YWw7XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgICAgXSA9IGY4YlszXTtcclxuICAgICAgICAgICAgYnVmW3BvcyArIDFdID0gZjhiWzJdO1xyXG4gICAgICAgICAgICBidWZbcG9zICsgMl0gPSBmOGJbMV07XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgKyAzXSA9IGY4YlswXTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXHJcbiAgICAgICAgZXhwb3J0cy53cml0ZUZsb2F0TEUgPSBsZSA/IHdyaXRlRmxvYXRfZjMyX2NweSA6IHdyaXRlRmxvYXRfZjMyX3JldjtcclxuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xyXG4gICAgICAgIGV4cG9ydHMud3JpdGVGbG9hdEJFID0gbGUgPyB3cml0ZUZsb2F0X2YzMl9yZXYgOiB3cml0ZUZsb2F0X2YzMl9jcHk7XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIHJlYWRGbG9hdF9mMzJfY3B5KGJ1ZiwgcG9zKSB7XHJcbiAgICAgICAgICAgIGY4YlswXSA9IGJ1Zltwb3MgICAgXTtcclxuICAgICAgICAgICAgZjhiWzFdID0gYnVmW3BvcyArIDFdO1xyXG4gICAgICAgICAgICBmOGJbMl0gPSBidWZbcG9zICsgMl07XHJcbiAgICAgICAgICAgIGY4YlszXSA9IGJ1Zltwb3MgKyAzXTtcclxuICAgICAgICAgICAgcmV0dXJuIGYzMlswXTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIHJlYWRGbG9hdF9mMzJfcmV2KGJ1ZiwgcG9zKSB7XHJcbiAgICAgICAgICAgIGY4YlszXSA9IGJ1Zltwb3MgICAgXTtcclxuICAgICAgICAgICAgZjhiWzJdID0gYnVmW3BvcyArIDFdO1xyXG4gICAgICAgICAgICBmOGJbMV0gPSBidWZbcG9zICsgMl07XHJcbiAgICAgICAgICAgIGY4YlswXSA9IGJ1Zltwb3MgKyAzXTtcclxuICAgICAgICAgICAgcmV0dXJuIGYzMlswXTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXHJcbiAgICAgICAgZXhwb3J0cy5yZWFkRmxvYXRMRSA9IGxlID8gcmVhZEZsb2F0X2YzMl9jcHkgOiByZWFkRmxvYXRfZjMyX3JldjtcclxuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xyXG4gICAgICAgIGV4cG9ydHMucmVhZEZsb2F0QkUgPSBsZSA/IHJlYWRGbG9hdF9mMzJfcmV2IDogcmVhZEZsb2F0X2YzMl9jcHk7XHJcblxyXG4gICAgLy8gZmxvYXQ6IGllZWU3NTRcclxuICAgIH0pKCk7IGVsc2UgKGZ1bmN0aW9uKCkge1xyXG5cclxuICAgICAgICBmdW5jdGlvbiB3cml0ZUZsb2F0X2llZWU3NTQod3JpdGVVaW50LCB2YWwsIGJ1ZiwgcG9zKSB7XHJcbiAgICAgICAgICAgIHZhciBzaWduID0gdmFsIDwgMCA/IDEgOiAwO1xyXG4gICAgICAgICAgICBpZiAoc2lnbilcclxuICAgICAgICAgICAgICAgIHZhbCA9IC12YWw7XHJcbiAgICAgICAgICAgIGlmICh2YWwgPT09IDApXHJcbiAgICAgICAgICAgICAgICB3cml0ZVVpbnQoMSAvIHZhbCA+IDAgPyAvKiBwb3NpdGl2ZSAqLyAwIDogLyogbmVnYXRpdmUgMCAqLyAyMTQ3NDgzNjQ4LCBidWYsIHBvcyk7XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKGlzTmFOKHZhbCkpXHJcbiAgICAgICAgICAgICAgICB3cml0ZVVpbnQoMjE0MzI4OTM0NCwgYnVmLCBwb3MpO1xyXG4gICAgICAgICAgICBlbHNlIGlmICh2YWwgPiAzLjQwMjgyMzQ2NjM4NTI4ODZlKzM4KSAvLyArLUluZmluaXR5XHJcbiAgICAgICAgICAgICAgICB3cml0ZVVpbnQoKHNpZ24gPDwgMzEgfCAyMTM5MDk1MDQwKSA+Pj4gMCwgYnVmLCBwb3MpO1xyXG4gICAgICAgICAgICBlbHNlIGlmICh2YWwgPCAxLjE3NTQ5NDM1MDgyMjI4NzVlLTM4KSAvLyBkZW5vcm1hbFxyXG4gICAgICAgICAgICAgICAgd3JpdGVVaW50KChzaWduIDw8IDMxIHwgTWF0aC5yb3VuZCh2YWwgLyAxLjQwMTI5ODQ2NDMyNDgxN2UtNDUpKSA+Pj4gMCwgYnVmLCBwb3MpO1xyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHZhciBleHBvbmVudCA9IE1hdGguZmxvb3IoTWF0aC5sb2codmFsKSAvIE1hdGguTE4yKSxcclxuICAgICAgICAgICAgICAgICAgICBtYW50aXNzYSA9IE1hdGgucm91bmQodmFsICogTWF0aC5wb3coMiwgLWV4cG9uZW50KSAqIDgzODg2MDgpICYgODM4ODYwNztcclxuICAgICAgICAgICAgICAgIHdyaXRlVWludCgoc2lnbiA8PCAzMSB8IGV4cG9uZW50ICsgMTI3IDw8IDIzIHwgbWFudGlzc2EpID4+PiAwLCBidWYsIHBvcyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGV4cG9ydHMud3JpdGVGbG9hdExFID0gd3JpdGVGbG9hdF9pZWVlNzU0LmJpbmQobnVsbCwgd3JpdGVVaW50TEUpO1xyXG4gICAgICAgIGV4cG9ydHMud3JpdGVGbG9hdEJFID0gd3JpdGVGbG9hdF9pZWVlNzU0LmJpbmQobnVsbCwgd3JpdGVVaW50QkUpO1xyXG5cclxuICAgICAgICBmdW5jdGlvbiByZWFkRmxvYXRfaWVlZTc1NChyZWFkVWludCwgYnVmLCBwb3MpIHtcclxuICAgICAgICAgICAgdmFyIHVpbnQgPSByZWFkVWludChidWYsIHBvcyksXHJcbiAgICAgICAgICAgICAgICBzaWduID0gKHVpbnQgPj4gMzEpICogMiArIDEsXHJcbiAgICAgICAgICAgICAgICBleHBvbmVudCA9IHVpbnQgPj4+IDIzICYgMjU1LFxyXG4gICAgICAgICAgICAgICAgbWFudGlzc2EgPSB1aW50ICYgODM4ODYwNztcclxuICAgICAgICAgICAgcmV0dXJuIGV4cG9uZW50ID09PSAyNTVcclxuICAgICAgICAgICAgICAgID8gbWFudGlzc2FcclxuICAgICAgICAgICAgICAgID8gTmFOXHJcbiAgICAgICAgICAgICAgICA6IHNpZ24gKiBJbmZpbml0eVxyXG4gICAgICAgICAgICAgICAgOiBleHBvbmVudCA9PT0gMCAvLyBkZW5vcm1hbFxyXG4gICAgICAgICAgICAgICAgPyBzaWduICogMS40MDEyOTg0NjQzMjQ4MTdlLTQ1ICogbWFudGlzc2FcclxuICAgICAgICAgICAgICAgIDogc2lnbiAqIE1hdGgucG93KDIsIGV4cG9uZW50IC0gMTUwKSAqIChtYW50aXNzYSArIDgzODg2MDgpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZXhwb3J0cy5yZWFkRmxvYXRMRSA9IHJlYWRGbG9hdF9pZWVlNzU0LmJpbmQobnVsbCwgcmVhZFVpbnRMRSk7XHJcbiAgICAgICAgZXhwb3J0cy5yZWFkRmxvYXRCRSA9IHJlYWRGbG9hdF9pZWVlNzU0LmJpbmQobnVsbCwgcmVhZFVpbnRCRSk7XHJcblxyXG4gICAgfSkoKTtcclxuXHJcbiAgICAvLyBkb3VibGU6IHR5cGVkIGFycmF5XHJcbiAgICBpZiAodHlwZW9mIEZsb2F0NjRBcnJheSAhPT0gXCJ1bmRlZmluZWRcIikgKGZ1bmN0aW9uKCkge1xyXG5cclxuICAgICAgICB2YXIgZjY0ID0gbmV3IEZsb2F0NjRBcnJheShbLTBdKSxcclxuICAgICAgICAgICAgZjhiID0gbmV3IFVpbnQ4QXJyYXkoZjY0LmJ1ZmZlciksXHJcbiAgICAgICAgICAgIGxlICA9IGY4Yls3XSA9PT0gMTI4O1xyXG5cclxuICAgICAgICBmdW5jdGlvbiB3cml0ZURvdWJsZV9mNjRfY3B5KHZhbCwgYnVmLCBwb3MpIHtcclxuICAgICAgICAgICAgZjY0WzBdID0gdmFsO1xyXG4gICAgICAgICAgICBidWZbcG9zICAgIF0gPSBmOGJbMF07XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgKyAxXSA9IGY4YlsxXTtcclxuICAgICAgICAgICAgYnVmW3BvcyArIDJdID0gZjhiWzJdO1xyXG4gICAgICAgICAgICBidWZbcG9zICsgM10gPSBmOGJbM107XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgKyA0XSA9IGY4Yls0XTtcclxuICAgICAgICAgICAgYnVmW3BvcyArIDVdID0gZjhiWzVdO1xyXG4gICAgICAgICAgICBidWZbcG9zICsgNl0gPSBmOGJbNl07XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgKyA3XSA9IGY4Yls3XTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIHdyaXRlRG91YmxlX2Y2NF9yZXYodmFsLCBidWYsIHBvcykge1xyXG4gICAgICAgICAgICBmNjRbMF0gPSB2YWw7XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgICAgXSA9IGY4Yls3XTtcclxuICAgICAgICAgICAgYnVmW3BvcyArIDFdID0gZjhiWzZdO1xyXG4gICAgICAgICAgICBidWZbcG9zICsgMl0gPSBmOGJbNV07XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgKyAzXSA9IGY4Yls0XTtcclxuICAgICAgICAgICAgYnVmW3BvcyArIDRdID0gZjhiWzNdO1xyXG4gICAgICAgICAgICBidWZbcG9zICsgNV0gPSBmOGJbMl07XHJcbiAgICAgICAgICAgIGJ1Zltwb3MgKyA2XSA9IGY4YlsxXTtcclxuICAgICAgICAgICAgYnVmW3BvcyArIDddID0gZjhiWzBdO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cclxuICAgICAgICBleHBvcnRzLndyaXRlRG91YmxlTEUgPSBsZSA/IHdyaXRlRG91YmxlX2Y2NF9jcHkgOiB3cml0ZURvdWJsZV9mNjRfcmV2O1xyXG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXHJcbiAgICAgICAgZXhwb3J0cy53cml0ZURvdWJsZUJFID0gbGUgPyB3cml0ZURvdWJsZV9mNjRfcmV2IDogd3JpdGVEb3VibGVfZjY0X2NweTtcclxuXHJcbiAgICAgICAgZnVuY3Rpb24gcmVhZERvdWJsZV9mNjRfY3B5KGJ1ZiwgcG9zKSB7XHJcbiAgICAgICAgICAgIGY4YlswXSA9IGJ1Zltwb3MgICAgXTtcclxuICAgICAgICAgICAgZjhiWzFdID0gYnVmW3BvcyArIDFdO1xyXG4gICAgICAgICAgICBmOGJbMl0gPSBidWZbcG9zICsgMl07XHJcbiAgICAgICAgICAgIGY4YlszXSA9IGJ1Zltwb3MgKyAzXTtcclxuICAgICAgICAgICAgZjhiWzRdID0gYnVmW3BvcyArIDRdO1xyXG4gICAgICAgICAgICBmOGJbNV0gPSBidWZbcG9zICsgNV07XHJcbiAgICAgICAgICAgIGY4Yls2XSA9IGJ1Zltwb3MgKyA2XTtcclxuICAgICAgICAgICAgZjhiWzddID0gYnVmW3BvcyArIDddO1xyXG4gICAgICAgICAgICByZXR1cm4gZjY0WzBdO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZnVuY3Rpb24gcmVhZERvdWJsZV9mNjRfcmV2KGJ1ZiwgcG9zKSB7XHJcbiAgICAgICAgICAgIGY4Yls3XSA9IGJ1Zltwb3MgICAgXTtcclxuICAgICAgICAgICAgZjhiWzZdID0gYnVmW3BvcyArIDFdO1xyXG4gICAgICAgICAgICBmOGJbNV0gPSBidWZbcG9zICsgMl07XHJcbiAgICAgICAgICAgIGY4Yls0XSA9IGJ1Zltwb3MgKyAzXTtcclxuICAgICAgICAgICAgZjhiWzNdID0gYnVmW3BvcyArIDRdO1xyXG4gICAgICAgICAgICBmOGJbMl0gPSBidWZbcG9zICsgNV07XHJcbiAgICAgICAgICAgIGY4YlsxXSA9IGJ1Zltwb3MgKyA2XTtcclxuICAgICAgICAgICAgZjhiWzBdID0gYnVmW3BvcyArIDddO1xyXG4gICAgICAgICAgICByZXR1cm4gZjY0WzBdO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cclxuICAgICAgICBleHBvcnRzLnJlYWREb3VibGVMRSA9IGxlID8gcmVhZERvdWJsZV9mNjRfY3B5IDogcmVhZERvdWJsZV9mNjRfcmV2O1xyXG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXHJcbiAgICAgICAgZXhwb3J0cy5yZWFkRG91YmxlQkUgPSBsZSA/IHJlYWREb3VibGVfZjY0X3JldiA6IHJlYWREb3VibGVfZjY0X2NweTtcclxuXHJcbiAgICAvLyBkb3VibGU6IGllZWU3NTRcclxuICAgIH0pKCk7IGVsc2UgKGZ1bmN0aW9uKCkge1xyXG5cclxuICAgICAgICBmdW5jdGlvbiB3cml0ZURvdWJsZV9pZWVlNzU0KHdyaXRlVWludCwgb2ZmMCwgb2ZmMSwgdmFsLCBidWYsIHBvcykge1xyXG4gICAgICAgICAgICB2YXIgc2lnbiA9IHZhbCA8IDAgPyAxIDogMDtcclxuICAgICAgICAgICAgaWYgKHNpZ24pXHJcbiAgICAgICAgICAgICAgICB2YWwgPSAtdmFsO1xyXG4gICAgICAgICAgICBpZiAodmFsID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICB3cml0ZVVpbnQoMCwgYnVmLCBwb3MgKyBvZmYwKTtcclxuICAgICAgICAgICAgICAgIHdyaXRlVWludCgxIC8gdmFsID4gMCA/IC8qIHBvc2l0aXZlICovIDAgOiAvKiBuZWdhdGl2ZSAwICovIDIxNDc0ODM2NDgsIGJ1ZiwgcG9zICsgb2ZmMSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNOYU4odmFsKSkge1xyXG4gICAgICAgICAgICAgICAgd3JpdGVVaW50KDAsIGJ1ZiwgcG9zICsgb2ZmMCk7XHJcbiAgICAgICAgICAgICAgICB3cml0ZVVpbnQoMjE0Njk1OTM2MCwgYnVmLCBwb3MgKyBvZmYxKTtcclxuICAgICAgICAgICAgfSBlbHNlIGlmICh2YWwgPiAxLjc5NzY5MzEzNDg2MjMxNTdlKzMwOCkgeyAvLyArLUluZmluaXR5XHJcbiAgICAgICAgICAgICAgICB3cml0ZVVpbnQoMCwgYnVmLCBwb3MgKyBvZmYwKTtcclxuICAgICAgICAgICAgICAgIHdyaXRlVWludCgoc2lnbiA8PCAzMSB8IDIxNDY0MzUwNzIpID4+PiAwLCBidWYsIHBvcyArIG9mZjEpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdmFyIG1hbnRpc3NhO1xyXG4gICAgICAgICAgICAgICAgaWYgKHZhbCA8IDIuMjI1MDczODU4NTA3MjAxNGUtMzA4KSB7IC8vIGRlbm9ybWFsXHJcbiAgICAgICAgICAgICAgICAgICAgbWFudGlzc2EgPSB2YWwgLyA1ZS0zMjQ7XHJcbiAgICAgICAgICAgICAgICAgICAgd3JpdGVVaW50KG1hbnRpc3NhID4+PiAwLCBidWYsIHBvcyArIG9mZjApO1xyXG4gICAgICAgICAgICAgICAgICAgIHdyaXRlVWludCgoc2lnbiA8PCAzMSB8IG1hbnRpc3NhIC8gNDI5NDk2NzI5NikgPj4+IDAsIGJ1ZiwgcG9zICsgb2ZmMSk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBleHBvbmVudCA9IE1hdGguZmxvb3IoTWF0aC5sb2codmFsKSAvIE1hdGguTE4yKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoZXhwb25lbnQgPT09IDEwMjQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4cG9uZW50ID0gMTAyMztcclxuICAgICAgICAgICAgICAgICAgICBtYW50aXNzYSA9IHZhbCAqIE1hdGgucG93KDIsIC1leHBvbmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgd3JpdGVVaW50KG1hbnRpc3NhICogNDUwMzU5OTYyNzM3MDQ5NiA+Pj4gMCwgYnVmLCBwb3MgKyBvZmYwKTtcclxuICAgICAgICAgICAgICAgICAgICB3cml0ZVVpbnQoKHNpZ24gPDwgMzEgfCBleHBvbmVudCArIDEwMjMgPDwgMjAgfCBtYW50aXNzYSAqIDEwNDg1NzYgJiAxMDQ4NTc1KSA+Pj4gMCwgYnVmLCBwb3MgKyBvZmYxKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZXhwb3J0cy53cml0ZURvdWJsZUxFID0gd3JpdGVEb3VibGVfaWVlZTc1NC5iaW5kKG51bGwsIHdyaXRlVWludExFLCAwLCA0KTtcclxuICAgICAgICBleHBvcnRzLndyaXRlRG91YmxlQkUgPSB3cml0ZURvdWJsZV9pZWVlNzU0LmJpbmQobnVsbCwgd3JpdGVVaW50QkUsIDQsIDApO1xyXG5cclxuICAgICAgICBmdW5jdGlvbiByZWFkRG91YmxlX2llZWU3NTQocmVhZFVpbnQsIG9mZjAsIG9mZjEsIGJ1ZiwgcG9zKSB7XHJcbiAgICAgICAgICAgIHZhciBsbyA9IHJlYWRVaW50KGJ1ZiwgcG9zICsgb2ZmMCksXHJcbiAgICAgICAgICAgICAgICBoaSA9IHJlYWRVaW50KGJ1ZiwgcG9zICsgb2ZmMSk7XHJcbiAgICAgICAgICAgIHZhciBzaWduID0gKGhpID4+IDMxKSAqIDIgKyAxLFxyXG4gICAgICAgICAgICAgICAgZXhwb25lbnQgPSBoaSA+Pj4gMjAgJiAyMDQ3LFxyXG4gICAgICAgICAgICAgICAgbWFudGlzc2EgPSA0Mjk0OTY3Mjk2ICogKGhpICYgMTA0ODU3NSkgKyBsbztcclxuICAgICAgICAgICAgcmV0dXJuIGV4cG9uZW50ID09PSAyMDQ3XHJcbiAgICAgICAgICAgICAgICA/IG1hbnRpc3NhXHJcbiAgICAgICAgICAgICAgICA/IE5hTlxyXG4gICAgICAgICAgICAgICAgOiBzaWduICogSW5maW5pdHlcclxuICAgICAgICAgICAgICAgIDogZXhwb25lbnQgPT09IDAgLy8gZGVub3JtYWxcclxuICAgICAgICAgICAgICAgID8gc2lnbiAqIDVlLTMyNCAqIG1hbnRpc3NhXHJcbiAgICAgICAgICAgICAgICA6IHNpZ24gKiBNYXRoLnBvdygyLCBleHBvbmVudCAtIDEwNzUpICogKG1hbnRpc3NhICsgNDUwMzU5OTYyNzM3MDQ5Nik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBleHBvcnRzLnJlYWREb3VibGVMRSA9IHJlYWREb3VibGVfaWVlZTc1NC5iaW5kKG51bGwsIHJlYWRVaW50TEUsIDAsIDQpO1xyXG4gICAgICAgIGV4cG9ydHMucmVhZERvdWJsZUJFID0gcmVhZERvdWJsZV9pZWVlNzU0LmJpbmQobnVsbCwgcmVhZFVpbnRCRSwgNCwgMCk7XHJcblxyXG4gICAgfSkoKTtcclxuXHJcbiAgICByZXR1cm4gZXhwb3J0cztcclxufVxyXG5cclxuLy8gdWludCBoZWxwZXJzXHJcblxyXG5mdW5jdGlvbiB3cml0ZVVpbnRMRSh2YWwsIGJ1ZiwgcG9zKSB7XHJcbiAgICBidWZbcG9zICAgIF0gPSAgdmFsICAgICAgICAmIDI1NTtcclxuICAgIGJ1Zltwb3MgKyAxXSA9ICB2YWwgPj4+IDggICYgMjU1O1xyXG4gICAgYnVmW3BvcyArIDJdID0gIHZhbCA+Pj4gMTYgJiAyNTU7XHJcbiAgICBidWZbcG9zICsgM10gPSAgdmFsID4+PiAyNDtcclxufVxyXG5cclxuZnVuY3Rpb24gd3JpdGVVaW50QkUodmFsLCBidWYsIHBvcykge1xyXG4gICAgYnVmW3BvcyAgICBdID0gIHZhbCA+Pj4gMjQ7XHJcbiAgICBidWZbcG9zICsgMV0gPSAgdmFsID4+PiAxNiAmIDI1NTtcclxuICAgIGJ1Zltwb3MgKyAyXSA9ICB2YWwgPj4+IDggICYgMjU1O1xyXG4gICAgYnVmW3BvcyArIDNdID0gIHZhbCAgICAgICAgJiAyNTU7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHJlYWRVaW50TEUoYnVmLCBwb3MpIHtcclxuICAgIHJldHVybiAoYnVmW3BvcyAgICBdXHJcbiAgICAgICAgICB8IGJ1Zltwb3MgKyAxXSA8PCA4XHJcbiAgICAgICAgICB8IGJ1Zltwb3MgKyAyXSA8PCAxNlxyXG4gICAgICAgICAgfCBidWZbcG9zICsgM10gPDwgMjQpID4+PiAwO1xyXG59XHJcblxyXG5mdW5jdGlvbiByZWFkVWludEJFKGJ1ZiwgcG9zKSB7XHJcbiAgICByZXR1cm4gKGJ1Zltwb3MgICAgXSA8PCAyNFxyXG4gICAgICAgICAgfCBidWZbcG9zICsgMV0gPDwgMTZcclxuICAgICAgICAgIHwgYnVmW3BvcyArIDJdIDw8IDhcclxuICAgICAgICAgIHwgYnVmW3BvcyArIDNdKSA+Pj4gMDtcclxufVxyXG4iLCJcInVzZSBzdHJpY3RcIjtcclxubW9kdWxlLmV4cG9ydHMgPSBpbnF1aXJlO1xyXG5cclxuLyoqXHJcbiAqIFJlcXVpcmVzIGEgbW9kdWxlIG9ubHkgaWYgYXZhaWxhYmxlLlxyXG4gKiBAbWVtYmVyb2YgdXRpbFxyXG4gKiBAcGFyYW0ge3N0cmluZ30gbW9kdWxlTmFtZSBNb2R1bGUgdG8gcmVxdWlyZVxyXG4gKiBAcmV0dXJucyB7P09iamVjdH0gUmVxdWlyZWQgbW9kdWxlIGlmIGF2YWlsYWJsZSBhbmQgbm90IGVtcHR5LCBvdGhlcndpc2UgYG51bGxgXHJcbiAqL1xyXG5mdW5jdGlvbiBpbnF1aXJlKG1vZHVsZU5hbWUpIHtcclxuICAgIHRyeSB7XHJcbiAgICAgICAgdmFyIG1vZCA9IGV2YWwoXCJxdWlyZVwiLnJlcGxhY2UoL14vLFwicmVcIikpKG1vZHVsZU5hbWUpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLWV2YWxcclxuICAgICAgICBpZiAobW9kICYmIChtb2QubGVuZ3RoIHx8IE9iamVjdC5rZXlzKG1vZCkubGVuZ3RoKSlcclxuICAgICAgICAgICAgcmV0dXJuIG1vZDtcclxuICAgIH0gY2F0Y2ggKGUpIHt9IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tZW1wdHlcclxuICAgIHJldHVybiBudWxsO1xyXG59XHJcbiIsIlwidXNlIHN0cmljdFwiO1xyXG5tb2R1bGUuZXhwb3J0cyA9IHBvb2w7XHJcblxyXG4vKipcclxuICogQW4gYWxsb2NhdG9yIGFzIHVzZWQgYnkge0BsaW5rIHV0aWwucG9vbH0uXHJcbiAqIEB0eXBlZGVmIFBvb2xBbGxvY2F0b3JcclxuICogQHR5cGUge2Z1bmN0aW9ufVxyXG4gKiBAcGFyYW0ge251bWJlcn0gc2l6ZSBCdWZmZXIgc2l6ZVxyXG4gKiBAcmV0dXJucyB7VWludDhBcnJheX0gQnVmZmVyXHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIEEgc2xpY2VyIGFzIHVzZWQgYnkge0BsaW5rIHV0aWwucG9vbH0uXHJcbiAqIEB0eXBlZGVmIFBvb2xTbGljZXJcclxuICogQHR5cGUge2Z1bmN0aW9ufVxyXG4gKiBAcGFyYW0ge251bWJlcn0gc3RhcnQgU3RhcnQgb2Zmc2V0XHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgRW5kIG9mZnNldFxyXG4gKiBAcmV0dXJucyB7VWludDhBcnJheX0gQnVmZmVyIHNsaWNlXHJcbiAqIEB0aGlzIHtVaW50OEFycmF5fVxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBBIGdlbmVyYWwgcHVycG9zZSBidWZmZXIgcG9vbC5cclxuICogQG1lbWJlcm9mIHV0aWxcclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7UG9vbEFsbG9jYXRvcn0gYWxsb2MgQWxsb2NhdG9yXHJcbiAqIEBwYXJhbSB7UG9vbFNsaWNlcn0gc2xpY2UgU2xpY2VyXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBbc2l6ZT04MTkyXSBTbGFiIHNpemVcclxuICogQHJldHVybnMge1Bvb2xBbGxvY2F0b3J9IFBvb2xlZCBhbGxvY2F0b3JcclxuICovXHJcbmZ1bmN0aW9uIHBvb2woYWxsb2MsIHNsaWNlLCBzaXplKSB7XHJcbiAgICB2YXIgU0laRSAgID0gc2l6ZSB8fCA4MTkyO1xyXG4gICAgdmFyIE1BWCAgICA9IFNJWkUgPj4+IDE7XHJcbiAgICB2YXIgc2xhYiAgID0gbnVsbDtcclxuICAgIHZhciBvZmZzZXQgPSBTSVpFO1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uIHBvb2xfYWxsb2Moc2l6ZSkge1xyXG4gICAgICAgIGlmIChzaXplIDwgMSB8fCBzaXplID4gTUFYKVxyXG4gICAgICAgICAgICByZXR1cm4gYWxsb2Moc2l6ZSk7XHJcbiAgICAgICAgaWYgKG9mZnNldCArIHNpemUgPiBTSVpFKSB7XHJcbiAgICAgICAgICAgIHNsYWIgPSBhbGxvYyhTSVpFKTtcclxuICAgICAgICAgICAgb2Zmc2V0ID0gMDtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGJ1ZiA9IHNsaWNlLmNhbGwoc2xhYiwgb2Zmc2V0LCBvZmZzZXQgKz0gc2l6ZSk7XHJcbiAgICAgICAgaWYgKG9mZnNldCAmIDcpIC8vIGFsaWduIHRvIDMyIGJpdFxyXG4gICAgICAgICAgICBvZmZzZXQgPSAob2Zmc2V0IHwgNykgKyAxO1xyXG4gICAgICAgIHJldHVybiBidWY7XHJcbiAgICB9O1xyXG59XHJcbiIsIlwidXNlIHN0cmljdFwiO1xyXG5cclxuLyoqXHJcbiAqIEEgbWluaW1hbCBVVEY4IGltcGxlbWVudGF0aW9uIGZvciBudW1iZXIgYXJyYXlzLlxyXG4gKiBAbWVtYmVyb2YgdXRpbFxyXG4gKiBAbmFtZXNwYWNlXHJcbiAqL1xyXG52YXIgdXRmOCA9IGV4cG9ydHM7XHJcblxyXG4vKipcclxuICogQ2FsY3VsYXRlcyB0aGUgVVRGOCBieXRlIGxlbmd0aCBvZiBhIHN0cmluZy5cclxuICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBTdHJpbmdcclxuICogQHJldHVybnMge251bWJlcn0gQnl0ZSBsZW5ndGhcclxuICovXHJcbnV0ZjgubGVuZ3RoID0gZnVuY3Rpb24gdXRmOF9sZW5ndGgoc3RyaW5nKSB7XHJcbiAgICB2YXIgbGVuID0gMCxcclxuICAgICAgICBjID0gMDtcclxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyaW5nLmxlbmd0aDsgKytpKSB7XHJcbiAgICAgICAgYyA9IHN0cmluZy5jaGFyQ29kZUF0KGkpO1xyXG4gICAgICAgIGlmIChjIDwgMTI4KVxyXG4gICAgICAgICAgICBsZW4gKz0gMTtcclxuICAgICAgICBlbHNlIGlmIChjIDwgMjA0OClcclxuICAgICAgICAgICAgbGVuICs9IDI7XHJcbiAgICAgICAgZWxzZSBpZiAoKGMgJiAweEZDMDApID09PSAweEQ4MDAgJiYgKHN0cmluZy5jaGFyQ29kZUF0KGkgKyAxKSAmIDB4RkMwMCkgPT09IDB4REMwMCkge1xyXG4gICAgICAgICAgICArK2k7XHJcbiAgICAgICAgICAgIGxlbiArPSA0O1xyXG4gICAgICAgIH0gZWxzZVxyXG4gICAgICAgICAgICBsZW4gKz0gMztcclxuICAgIH1cclxuICAgIHJldHVybiBsZW47XHJcbn07XHJcblxyXG4vKipcclxuICogUmVhZHMgVVRGOCBieXRlcyBhcyBhIHN0cmluZy5cclxuICogQHBhcmFtIHtVaW50OEFycmF5fSBidWZmZXIgU291cmNlIGJ1ZmZlclxyXG4gKiBAcGFyYW0ge251bWJlcn0gc3RhcnQgU291cmNlIHN0YXJ0XHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBlbmQgU291cmNlIGVuZFxyXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBTdHJpbmcgcmVhZFxyXG4gKi9cclxudXRmOC5yZWFkID0gZnVuY3Rpb24gdXRmOF9yZWFkKGJ1ZmZlciwgc3RhcnQsIGVuZCkge1xyXG4gICAgdmFyIGxlbiA9IGVuZCAtIHN0YXJ0O1xyXG4gICAgaWYgKGxlbiA8IDEpXHJcbiAgICAgICAgcmV0dXJuIFwiXCI7XHJcbiAgICB2YXIgcGFydHMgPSBudWxsLFxyXG4gICAgICAgIGNodW5rID0gW10sXHJcbiAgICAgICAgaSA9IDAsIC8vIGNoYXIgb2Zmc2V0XHJcbiAgICAgICAgdDsgICAgIC8vIHRlbXBvcmFyeVxyXG4gICAgd2hpbGUgKHN0YXJ0IDwgZW5kKSB7XHJcbiAgICAgICAgdCA9IGJ1ZmZlcltzdGFydCsrXTtcclxuICAgICAgICBpZiAodCA8IDEyOClcclxuICAgICAgICAgICAgY2h1bmtbaSsrXSA9IHQ7XHJcbiAgICAgICAgZWxzZSBpZiAodCA+IDE5MSAmJiB0IDwgMjI0KVxyXG4gICAgICAgICAgICBjaHVua1tpKytdID0gKHQgJiAzMSkgPDwgNiB8IGJ1ZmZlcltzdGFydCsrXSAmIDYzO1xyXG4gICAgICAgIGVsc2UgaWYgKHQgPiAyMzkgJiYgdCA8IDM2NSkge1xyXG4gICAgICAgICAgICB0ID0gKCh0ICYgNykgPDwgMTggfCAoYnVmZmVyW3N0YXJ0KytdICYgNjMpIDw8IDEyIHwgKGJ1ZmZlcltzdGFydCsrXSAmIDYzKSA8PCA2IHwgYnVmZmVyW3N0YXJ0KytdICYgNjMpIC0gMHgxMDAwMDtcclxuICAgICAgICAgICAgY2h1bmtbaSsrXSA9IDB4RDgwMCArICh0ID4+IDEwKTtcclxuICAgICAgICAgICAgY2h1bmtbaSsrXSA9IDB4REMwMCArICh0ICYgMTAyMyk7XHJcbiAgICAgICAgfSBlbHNlXHJcbiAgICAgICAgICAgIGNodW5rW2krK10gPSAodCAmIDE1KSA8PCAxMiB8IChidWZmZXJbc3RhcnQrK10gJiA2MykgPDwgNiB8IGJ1ZmZlcltzdGFydCsrXSAmIDYzO1xyXG4gICAgICAgIGlmIChpID4gODE5MSkge1xyXG4gICAgICAgICAgICAocGFydHMgfHwgKHBhcnRzID0gW10pKS5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLCBjaHVuaykpO1xyXG4gICAgICAgICAgICBpID0gMDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBpZiAocGFydHMpIHtcclxuICAgICAgICBpZiAoaSlcclxuICAgICAgICAgICAgcGFydHMucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZywgY2h1bmsuc2xpY2UoMCwgaSkpKTtcclxuICAgICAgICByZXR1cm4gcGFydHMuam9pbihcIlwiKTtcclxuICAgIH1cclxuICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZywgY2h1bmsuc2xpY2UoMCwgaSkpO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFdyaXRlcyBhIHN0cmluZyBhcyBVVEY4IGJ5dGVzLlxyXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFNvdXJjZSBzdHJpbmdcclxuICogQHBhcmFtIHtVaW50OEFycmF5fSBidWZmZXIgRGVzdGluYXRpb24gYnVmZmVyXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgRGVzdGluYXRpb24gb2Zmc2V0XHJcbiAqIEByZXR1cm5zIHtudW1iZXJ9IEJ5dGVzIHdyaXR0ZW5cclxuICovXHJcbnV0Zjgud3JpdGUgPSBmdW5jdGlvbiB1dGY4X3dyaXRlKHN0cmluZywgYnVmZmVyLCBvZmZzZXQpIHtcclxuICAgIHZhciBzdGFydCA9IG9mZnNldCxcclxuICAgICAgICBjMSwgLy8gY2hhcmFjdGVyIDFcclxuICAgICAgICBjMjsgLy8gY2hhcmFjdGVyIDJcclxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyaW5nLmxlbmd0aDsgKytpKSB7XHJcbiAgICAgICAgYzEgPSBzdHJpbmcuY2hhckNvZGVBdChpKTtcclxuICAgICAgICBpZiAoYzEgPCAxMjgpIHtcclxuICAgICAgICAgICAgYnVmZmVyW29mZnNldCsrXSA9IGMxO1xyXG4gICAgICAgIH0gZWxzZSBpZiAoYzEgPCAyMDQ4KSB7XHJcbiAgICAgICAgICAgIGJ1ZmZlcltvZmZzZXQrK10gPSBjMSA+PiA2ICAgICAgIHwgMTkyO1xyXG4gICAgICAgICAgICBidWZmZXJbb2Zmc2V0KytdID0gYzEgICAgICAgJiA2MyB8IDEyODtcclxuICAgICAgICB9IGVsc2UgaWYgKChjMSAmIDB4RkMwMCkgPT09IDB4RDgwMCAmJiAoKGMyID0gc3RyaW5nLmNoYXJDb2RlQXQoaSArIDEpKSAmIDB4RkMwMCkgPT09IDB4REMwMCkge1xyXG4gICAgICAgICAgICBjMSA9IDB4MTAwMDAgKyAoKGMxICYgMHgwM0ZGKSA8PCAxMCkgKyAoYzIgJiAweDAzRkYpO1xyXG4gICAgICAgICAgICArK2k7XHJcbiAgICAgICAgICAgIGJ1ZmZlcltvZmZzZXQrK10gPSBjMSA+PiAxOCAgICAgIHwgMjQwO1xyXG4gICAgICAgICAgICBidWZmZXJbb2Zmc2V0KytdID0gYzEgPj4gMTIgJiA2MyB8IDEyODtcclxuICAgICAgICAgICAgYnVmZmVyW29mZnNldCsrXSA9IGMxID4+IDYgICYgNjMgfCAxMjg7XHJcbiAgICAgICAgICAgIGJ1ZmZlcltvZmZzZXQrK10gPSBjMSAgICAgICAmIDYzIHwgMTI4O1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGJ1ZmZlcltvZmZzZXQrK10gPSBjMSA+PiAxMiAgICAgIHwgMjI0O1xyXG4gICAgICAgICAgICBidWZmZXJbb2Zmc2V0KytdID0gYzEgPj4gNiAgJiA2MyB8IDEyODtcclxuICAgICAgICAgICAgYnVmZmVyW29mZnNldCsrXSA9IGMxICAgICAgICYgNjMgfCAxMjg7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIG9mZnNldCAtIHN0YXJ0O1xyXG59O1xyXG4iLCJcInVzZSBzdHJpY3RcIjtcclxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcclxudmFyIEd1aWQgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XHJcbiAgICBmdW5jdGlvbiBHdWlkKGd1aWQpIHtcclxuICAgICAgICBpZiAoIWd1aWQpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkludmFsaWQgYXJndW1lbnQ7IGB2YWx1ZWAgaGFzIG5vIHZhbHVlLlwiKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy52YWx1ZSA9IEd1aWQuRU1QVFk7XHJcbiAgICAgICAgaWYgKGd1aWQgJiYgR3VpZC5pc0d1aWQoZ3VpZCkpIHtcclxuICAgICAgICAgICAgdGhpcy52YWx1ZSA9IGd1aWQ7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgR3VpZC5pc0d1aWQgPSBmdW5jdGlvbiAoZ3VpZCkge1xyXG4gICAgICAgIHZhciB2YWx1ZSA9IGd1aWQudG9TdHJpbmcoKTtcclxuICAgICAgICByZXR1cm4gZ3VpZCAmJiAoZ3VpZCBpbnN0YW5jZW9mIEd1aWQgfHwgR3VpZC52YWxpZGF0b3IudGVzdCh2YWx1ZSkpO1xyXG4gICAgfTtcclxuICAgIEd1aWQuY3JlYXRlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiBuZXcgR3VpZChbR3VpZC5nZW4oMiksIEd1aWQuZ2VuKDEpLCBHdWlkLmdlbigxKSwgR3VpZC5nZW4oMSksIEd1aWQuZ2VuKDMpXS5qb2luKFwiLVwiKSk7XHJcbiAgICB9O1xyXG4gICAgR3VpZC5jcmVhdGVFbXB0eSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gbmV3IEd1aWQoXCJlbXB0eWd1aWRcIik7XHJcbiAgICB9O1xyXG4gICAgR3VpZC5wYXJzZSA9IGZ1bmN0aW9uIChndWlkKSB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBHdWlkKGd1aWQpO1xyXG4gICAgfTtcclxuICAgIEd1aWQucmF3ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiBbR3VpZC5nZW4oMiksIEd1aWQuZ2VuKDEpLCBHdWlkLmdlbigxKSwgR3VpZC5nZW4oMSksIEd1aWQuZ2VuKDMpXS5qb2luKFwiLVwiKTtcclxuICAgIH07XHJcbiAgICBHdWlkLmdlbiA9IGZ1bmN0aW9uIChjb3VudCkge1xyXG4gICAgICAgIHZhciBvdXQgPSBcIlwiO1xyXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY291bnQ7IGkrKykge1xyXG4gICAgICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tYml0d2lzZVxyXG4gICAgICAgICAgICBvdXQgKz0gKCgoMSArIE1hdGgucmFuZG9tKCkpICogMHgxMDAwMCkgfCAwKS50b1N0cmluZygxNikuc3Vic3RyaW5nKDEpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gb3V0O1xyXG4gICAgfTtcclxuICAgIEd1aWQucHJvdG90eXBlLmVxdWFscyA9IGZ1bmN0aW9uIChvdGhlcikge1xyXG4gICAgICAgIC8vIENvbXBhcmluZyBzdHJpbmcgYHZhbHVlYCBhZ2FpbnN0IHByb3ZpZGVkIGBndWlkYCB3aWxsIGF1dG8tY2FsbFxyXG4gICAgICAgIC8vIHRvU3RyaW5nIG9uIGBndWlkYCBmb3IgY29tcGFyaXNvblxyXG4gICAgICAgIHJldHVybiBHdWlkLmlzR3VpZChvdGhlcikgJiYgdGhpcy52YWx1ZSA9PT0gb3RoZXIudG9TdHJpbmcoKTtcclxuICAgIH07XHJcbiAgICBHdWlkLnByb3RvdHlwZS5pc0VtcHR5ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlID09PSBHdWlkLkVNUFRZO1xyXG4gICAgfTtcclxuICAgIEd1aWQucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlO1xyXG4gICAgfTtcclxuICAgIEd1aWQucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICB2YWx1ZTogdGhpcy52YWx1ZVxyXG4gICAgICAgIH07XHJcbiAgICB9O1xyXG4gICAgR3VpZC52YWxpZGF0b3IgPSBuZXcgUmVnRXhwKFwiXlthLXowLTldezh9LVthLXowLTldezR9LVthLXowLTldezR9LVthLXowLTldezR9LVthLXowLTldezEyfSRcIiwgXCJpXCIpO1xyXG4gICAgR3VpZC5FTVBUWSA9IFwiMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwXCI7XHJcbiAgICByZXR1cm4gR3VpZDtcclxufSgpKTtcclxuZXhwb3J0cy5HdWlkID0gR3VpZDtcclxuIiwibW9kdWxlLmV4cG9ydHMgPSBMb25nO1xyXG5cclxuLyoqXHJcbiAqIHdhc20gb3B0aW1pemF0aW9ucywgdG8gZG8gbmF0aXZlIGk2NCBtdWx0aXBsaWNhdGlvbiBhbmQgZGl2aWRlXHJcbiAqL1xyXG52YXIgd2FzbSA9IG51bGw7XHJcblxyXG50cnkge1xyXG4gIHdhc20gPSBuZXcgV2ViQXNzZW1ibHkuSW5zdGFuY2UobmV3IFdlYkFzc2VtYmx5Lk1vZHVsZShuZXcgVWludDhBcnJheShbXHJcbiAgICAwLCA5NywgMTE1LCAxMDksIDEsIDAsIDAsIDAsIDEsIDEzLCAyLCA5NiwgMCwgMSwgMTI3LCA5NiwgNCwgMTI3LCAxMjcsIDEyNywgMTI3LCAxLCAxMjcsIDMsIDcsIDYsIDAsIDEsIDEsIDEsIDEsIDEsIDYsIDYsIDEsIDEyNywgMSwgNjUsIDAsIDExLCA3LCA1MCwgNiwgMywgMTA5LCAxMTcsIDEwOCwgMCwgMSwgNSwgMTAwLCAxMDUsIDExOCwgOTUsIDExNSwgMCwgMiwgNSwgMTAwLCAxMDUsIDExOCwgOTUsIDExNywgMCwgMywgNSwgMTE0LCAxMDEsIDEwOSwgOTUsIDExNSwgMCwgNCwgNSwgMTE0LCAxMDEsIDEwOSwgOTUsIDExNywgMCwgNSwgOCwgMTAzLCAxMDEsIDExNiwgOTUsIDEwNCwgMTA1LCAxMDMsIDEwNCwgMCwgMCwgMTAsIDE5MSwgMSwgNiwgNCwgMCwgMzUsIDAsIDExLCAzNiwgMSwgMSwgMTI2LCAzMiwgMCwgMTczLCAzMiwgMSwgMTczLCA2NiwgMzIsIDEzNCwgMTMyLCAzMiwgMiwgMTczLCAzMiwgMywgMTczLCA2NiwgMzIsIDEzNCwgMTMyLCAxMjYsIDM0LCA0LCA2NiwgMzIsIDEzNSwgMTY3LCAzNiwgMCwgMzIsIDQsIDE2NywgMTEsIDM2LCAxLCAxLCAxMjYsIDMyLCAwLCAxNzMsIDMyLCAxLCAxNzMsIDY2LCAzMiwgMTM0LCAxMzIsIDMyLCAyLCAxNzMsIDMyLCAzLCAxNzMsIDY2LCAzMiwgMTM0LCAxMzIsIDEyNywgMzQsIDQsIDY2LCAzMiwgMTM1LCAxNjcsIDM2LCAwLCAzMiwgNCwgMTY3LCAxMSwgMzYsIDEsIDEsIDEyNiwgMzIsIDAsIDE3MywgMzIsIDEsIDE3MywgNjYsIDMyLCAxMzQsIDEzMiwgMzIsIDIsIDE3MywgMzIsIDMsIDE3MywgNjYsIDMyLCAxMzQsIDEzMiwgMTI4LCAzNCwgNCwgNjYsIDMyLCAxMzUsIDE2NywgMzYsIDAsIDMyLCA0LCAxNjcsIDExLCAzNiwgMSwgMSwgMTI2LCAzMiwgMCwgMTczLCAzMiwgMSwgMTczLCA2NiwgMzIsIDEzNCwgMTMyLCAzMiwgMiwgMTczLCAzMiwgMywgMTczLCA2NiwgMzIsIDEzNCwgMTMyLCAxMjksIDM0LCA0LCA2NiwgMzIsIDEzNSwgMTY3LCAzNiwgMCwgMzIsIDQsIDE2NywgMTEsIDM2LCAxLCAxLCAxMjYsIDMyLCAwLCAxNzMsIDMyLCAxLCAxNzMsIDY2LCAzMiwgMTM0LCAxMzIsIDMyLCAyLCAxNzMsIDMyLCAzLCAxNzMsIDY2LCAzMiwgMTM0LCAxMzIsIDEzMCwgMzQsIDQsIDY2LCAzMiwgMTM1LCAxNjcsIDM2LCAwLCAzMiwgNCwgMTY3LCAxMVxyXG4gIF0pKSwge30pLmV4cG9ydHM7XHJcbn0gY2F0Y2ggKGUpIHtcclxuICAvLyBubyB3YXNtIHN1cHBvcnQgOihcclxufVxyXG5cclxuLyoqXHJcbiAqIENvbnN0cnVjdHMgYSA2NCBiaXQgdHdvJ3MtY29tcGxlbWVudCBpbnRlZ2VyLCBnaXZlbiBpdHMgbG93IGFuZCBoaWdoIDMyIGJpdCB2YWx1ZXMgYXMgKnNpZ25lZCogaW50ZWdlcnMuXHJcbiAqICBTZWUgdGhlIGZyb20qIGZ1bmN0aW9ucyBiZWxvdyBmb3IgbW9yZSBjb252ZW5pZW50IHdheXMgb2YgY29uc3RydWN0aW5nIExvbmdzLlxyXG4gKiBAZXhwb3J0cyBMb25nXHJcbiAqIEBjbGFzcyBBIExvbmcgY2xhc3MgZm9yIHJlcHJlc2VudGluZyBhIDY0IGJpdCB0d28ncy1jb21wbGVtZW50IGludGVnZXIgdmFsdWUuXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBsb3cgVGhlIGxvdyAoc2lnbmVkKSAzMiBiaXRzIG9mIHRoZSBsb25nXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBoaWdoIFRoZSBoaWdoIChzaWduZWQpIDMyIGJpdHMgb2YgdGhlIGxvbmdcclxuICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIHNpZ25lZFxyXG4gKiBAY29uc3RydWN0b3JcclxuICovXHJcbmZ1bmN0aW9uIExvbmcobG93LCBoaWdoLCB1bnNpZ25lZCkge1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIGxvdyAzMiBiaXRzIGFzIGEgc2lnbmVkIHZhbHVlLlxyXG4gICAgICogQHR5cGUge251bWJlcn1cclxuICAgICAqL1xyXG4gICAgdGhpcy5sb3cgPSBsb3cgfCAwO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIGhpZ2ggMzIgYml0cyBhcyBhIHNpZ25lZCB2YWx1ZS5cclxuICAgICAqIEB0eXBlIHtudW1iZXJ9XHJcbiAgICAgKi9cclxuICAgIHRoaXMuaGlnaCA9IGhpZ2ggfCAwO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogV2hldGhlciB1bnNpZ25lZCBvciBub3QuXHJcbiAgICAgKiBAdHlwZSB7Ym9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgdGhpcy51bnNpZ25lZCA9ICEhdW5zaWduZWQ7XHJcbn1cclxuXHJcbi8vIFRoZSBpbnRlcm5hbCByZXByZXNlbnRhdGlvbiBvZiBhIGxvbmcgaXMgdGhlIHR3byBnaXZlbiBzaWduZWQsIDMyLWJpdCB2YWx1ZXMuXHJcbi8vIFdlIHVzZSAzMi1iaXQgcGllY2VzIGJlY2F1c2UgdGhlc2UgYXJlIHRoZSBzaXplIG9mIGludGVnZXJzIG9uIHdoaWNoXHJcbi8vIEphdmFzY3JpcHQgcGVyZm9ybXMgYml0LW9wZXJhdGlvbnMuICBGb3Igb3BlcmF0aW9ucyBsaWtlIGFkZGl0aW9uIGFuZFxyXG4vLyBtdWx0aXBsaWNhdGlvbiwgd2Ugc3BsaXQgZWFjaCBudW1iZXIgaW50byAxNiBiaXQgcGllY2VzLCB3aGljaCBjYW4gZWFzaWx5IGJlXHJcbi8vIG11bHRpcGxpZWQgd2l0aGluIEphdmFzY3JpcHQncyBmbG9hdGluZy1wb2ludCByZXByZXNlbnRhdGlvbiB3aXRob3V0IG92ZXJmbG93XHJcbi8vIG9yIGNoYW5nZSBpbiBzaWduLlxyXG4vL1xyXG4vLyBJbiB0aGUgYWxnb3JpdGhtcyBiZWxvdywgd2UgZnJlcXVlbnRseSByZWR1Y2UgdGhlIG5lZ2F0aXZlIGNhc2UgdG8gdGhlXHJcbi8vIHBvc2l0aXZlIGNhc2UgYnkgbmVnYXRpbmcgdGhlIGlucHV0KHMpIGFuZCB0aGVuIHBvc3QtcHJvY2Vzc2luZyB0aGUgcmVzdWx0LlxyXG4vLyBOb3RlIHRoYXQgd2UgbXVzdCBBTFdBWVMgY2hlY2sgc3BlY2lhbGx5IHdoZXRoZXIgdGhvc2UgdmFsdWVzIGFyZSBNSU5fVkFMVUVcclxuLy8gKC0yXjYzKSBiZWNhdXNlIC1NSU5fVkFMVUUgPT0gTUlOX1ZBTFVFIChzaW5jZSAyXjYzIGNhbm5vdCBiZSByZXByZXNlbnRlZCBhc1xyXG4vLyBhIHBvc2l0aXZlIG51bWJlciwgaXQgb3ZlcmZsb3dzIGJhY2sgaW50byBhIG5lZ2F0aXZlKS4gIE5vdCBoYW5kbGluZyB0aGlzXHJcbi8vIGNhc2Ugd291bGQgb2Z0ZW4gcmVzdWx0IGluIGluZmluaXRlIHJlY3Vyc2lvbi5cclxuLy9cclxuLy8gQ29tbW9uIGNvbnN0YW50IHZhbHVlcyBaRVJPLCBPTkUsIE5FR19PTkUsIGV0Yy4gYXJlIGRlZmluZWQgYmVsb3cgdGhlIGZyb20qXHJcbi8vIG1ldGhvZHMgb24gd2hpY2ggdGhleSBkZXBlbmQuXHJcblxyXG4vKipcclxuICogQW4gaW5kaWNhdG9yIHVzZWQgdG8gcmVsaWFibHkgZGV0ZXJtaW5lIGlmIGFuIG9iamVjdCBpcyBhIExvbmcgb3Igbm90LlxyXG4gKiBAdHlwZSB7Ym9vbGVhbn1cclxuICogQGNvbnN0XHJcbiAqIEBwcml2YXRlXHJcbiAqL1xyXG5Mb25nLnByb3RvdHlwZS5fX2lzTG9uZ19fO1xyXG5cclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KExvbmcucHJvdG90eXBlLCBcIl9faXNMb25nX19cIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxuXHJcbi8qKlxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHsqfSBvYmogT2JqZWN0XHJcbiAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gKiBAaW5uZXJcclxuICovXHJcbmZ1bmN0aW9uIGlzTG9uZyhvYmopIHtcclxuICAgIHJldHVybiAob2JqICYmIG9ialtcIl9faXNMb25nX19cIl0pID09PSB0cnVlO1xyXG59XHJcblxyXG4vKipcclxuICogVGVzdHMgaWYgdGhlIHNwZWNpZmllZCBvYmplY3QgaXMgYSBMb25nLlxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHsqfSBvYmogT2JqZWN0XHJcbiAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gKi9cclxuTG9uZy5pc0xvbmcgPSBpc0xvbmc7XHJcblxyXG4vKipcclxuICogQSBjYWNoZSBvZiB0aGUgTG9uZyByZXByZXNlbnRhdGlvbnMgb2Ygc21hbGwgaW50ZWdlciB2YWx1ZXMuXHJcbiAqIEB0eXBlIHshT2JqZWN0fVxyXG4gKiBAaW5uZXJcclxuICovXHJcbnZhciBJTlRfQ0FDSEUgPSB7fTtcclxuXHJcbi8qKlxyXG4gKiBBIGNhY2hlIG9mIHRoZSBMb25nIHJlcHJlc2VudGF0aW9ucyBvZiBzbWFsbCB1bnNpZ25lZCBpbnRlZ2VyIHZhbHVlcy5cclxuICogQHR5cGUgeyFPYmplY3R9XHJcbiAqIEBpbm5lclxyXG4gKi9cclxudmFyIFVJTlRfQ0FDSEUgPSB7fTtcclxuXHJcbi8qKlxyXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWVcclxuICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWRcclxuICogQHJldHVybnMgeyFMb25nfVxyXG4gKiBAaW5uZXJcclxuICovXHJcbmZ1bmN0aW9uIGZyb21JbnQodmFsdWUsIHVuc2lnbmVkKSB7XHJcbiAgICB2YXIgb2JqLCBjYWNoZWRPYmosIGNhY2hlO1xyXG4gICAgaWYgKHVuc2lnbmVkKSB7XHJcbiAgICAgICAgdmFsdWUgPj4+PSAwO1xyXG4gICAgICAgIGlmIChjYWNoZSA9ICgwIDw9IHZhbHVlICYmIHZhbHVlIDwgMjU2KSkge1xyXG4gICAgICAgICAgICBjYWNoZWRPYmogPSBVSU5UX0NBQ0hFW3ZhbHVlXTtcclxuICAgICAgICAgICAgaWYgKGNhY2hlZE9iailcclxuICAgICAgICAgICAgICAgIHJldHVybiBjYWNoZWRPYmo7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIG9iaiA9IGZyb21CaXRzKHZhbHVlLCAodmFsdWUgfCAwKSA8IDAgPyAtMSA6IDAsIHRydWUpO1xyXG4gICAgICAgIGlmIChjYWNoZSlcclxuICAgICAgICAgICAgVUlOVF9DQUNIRVt2YWx1ZV0gPSBvYmo7XHJcbiAgICAgICAgcmV0dXJuIG9iajtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdmFsdWUgfD0gMDtcclxuICAgICAgICBpZiAoY2FjaGUgPSAoLTEyOCA8PSB2YWx1ZSAmJiB2YWx1ZSA8IDEyOCkpIHtcclxuICAgICAgICAgICAgY2FjaGVkT2JqID0gSU5UX0NBQ0hFW3ZhbHVlXTtcclxuICAgICAgICAgICAgaWYgKGNhY2hlZE9iailcclxuICAgICAgICAgICAgICAgIHJldHVybiBjYWNoZWRPYmo7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIG9iaiA9IGZyb21CaXRzKHZhbHVlLCB2YWx1ZSA8IDAgPyAtMSA6IDAsIGZhbHNlKTtcclxuICAgICAgICBpZiAoY2FjaGUpXHJcbiAgICAgICAgICAgIElOVF9DQUNIRVt2YWx1ZV0gPSBvYmo7XHJcbiAgICAgICAgcmV0dXJuIG9iajtcclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgYSBMb25nIHJlcHJlc2VudGluZyB0aGUgZ2l2ZW4gMzIgYml0IGludGVnZXIgdmFsdWUuXHJcbiAqIEBmdW5jdGlvblxyXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVGhlIDMyIGJpdCBpbnRlZ2VyIGluIHF1ZXN0aW9uXHJcbiAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkIFdoZXRoZXIgdW5zaWduZWQgb3Igbm90LCBkZWZhdWx0cyB0byBzaWduZWRcclxuICogQHJldHVybnMgeyFMb25nfSBUaGUgY29ycmVzcG9uZGluZyBMb25nIHZhbHVlXHJcbiAqL1xyXG5Mb25nLmZyb21JbnQgPSBmcm9tSW50O1xyXG5cclxuLyoqXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZVxyXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZFxyXG4gKiBAcmV0dXJucyB7IUxvbmd9XHJcbiAqIEBpbm5lclxyXG4gKi9cclxuZnVuY3Rpb24gZnJvbU51bWJlcih2YWx1ZSwgdW5zaWduZWQpIHtcclxuICAgIGlmIChpc05hTih2YWx1ZSkpXHJcbiAgICAgICAgcmV0dXJuIHVuc2lnbmVkID8gVVpFUk8gOiBaRVJPO1xyXG4gICAgaWYgKHVuc2lnbmVkKSB7XHJcbiAgICAgICAgaWYgKHZhbHVlIDwgMClcclxuICAgICAgICAgICAgcmV0dXJuIFVaRVJPO1xyXG4gICAgICAgIGlmICh2YWx1ZSA+PSBUV09fUFdSXzY0X0RCTClcclxuICAgICAgICAgICAgcmV0dXJuIE1BWF9VTlNJR05FRF9WQUxVRTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgICAgaWYgKHZhbHVlIDw9IC1UV09fUFdSXzYzX0RCTClcclxuICAgICAgICAgICAgcmV0dXJuIE1JTl9WQUxVRTtcclxuICAgICAgICBpZiAodmFsdWUgKyAxID49IFRXT19QV1JfNjNfREJMKVxyXG4gICAgICAgICAgICByZXR1cm4gTUFYX1ZBTFVFO1xyXG4gICAgfVxyXG4gICAgaWYgKHZhbHVlIDwgMClcclxuICAgICAgICByZXR1cm4gZnJvbU51bWJlcigtdmFsdWUsIHVuc2lnbmVkKS5uZWcoKTtcclxuICAgIHJldHVybiBmcm9tQml0cygodmFsdWUgJSBUV09fUFdSXzMyX0RCTCkgfCAwLCAodmFsdWUgLyBUV09fUFdSXzMyX0RCTCkgfCAwLCB1bnNpZ25lZCk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIGEgTG9uZyByZXByZXNlbnRpbmcgdGhlIGdpdmVuIHZhbHVlLCBwcm92aWRlZCB0aGF0IGl0IGlzIGEgZmluaXRlIG51bWJlci4gT3RoZXJ3aXNlLCB6ZXJvIGlzIHJldHVybmVkLlxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFRoZSBudW1iZXIgaW4gcXVlc3Rpb25cclxuICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIHNpZ25lZFxyXG4gKiBAcmV0dXJucyB7IUxvbmd9IFRoZSBjb3JyZXNwb25kaW5nIExvbmcgdmFsdWVcclxuICovXHJcbkxvbmcuZnJvbU51bWJlciA9IGZyb21OdW1iZXI7XHJcblxyXG4vKipcclxuICogQHBhcmFtIHtudW1iZXJ9IGxvd0JpdHNcclxuICogQHBhcmFtIHtudW1iZXJ9IGhpZ2hCaXRzXHJcbiAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkXHJcbiAqIEByZXR1cm5zIHshTG9uZ31cclxuICogQGlubmVyXHJcbiAqL1xyXG5mdW5jdGlvbiBmcm9tQml0cyhsb3dCaXRzLCBoaWdoQml0cywgdW5zaWduZWQpIHtcclxuICAgIHJldHVybiBuZXcgTG9uZyhsb3dCaXRzLCBoaWdoQml0cywgdW5zaWduZWQpO1xyXG59XHJcblxyXG4vKipcclxuICogUmV0dXJucyBhIExvbmcgcmVwcmVzZW50aW5nIHRoZSA2NCBiaXQgaW50ZWdlciB0aGF0IGNvbWVzIGJ5IGNvbmNhdGVuYXRpbmcgdGhlIGdpdmVuIGxvdyBhbmQgaGlnaCBiaXRzLiBFYWNoIGlzXHJcbiAqICBhc3N1bWVkIHRvIHVzZSAzMiBiaXRzLlxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHtudW1iZXJ9IGxvd0JpdHMgVGhlIGxvdyAzMiBiaXRzXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBoaWdoQml0cyBUaGUgaGlnaCAzMiBiaXRzXHJcbiAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkIFdoZXRoZXIgdW5zaWduZWQgb3Igbm90LCBkZWZhdWx0cyB0byBzaWduZWRcclxuICogQHJldHVybnMgeyFMb25nfSBUaGUgY29ycmVzcG9uZGluZyBMb25nIHZhbHVlXHJcbiAqL1xyXG5Mb25nLmZyb21CaXRzID0gZnJvbUJpdHM7XHJcblxyXG4vKipcclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBiYXNlXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBleHBvbmVudFxyXG4gKiBAcmV0dXJucyB7bnVtYmVyfVxyXG4gKiBAaW5uZXJcclxuICovXHJcbnZhciBwb3dfZGJsID0gTWF0aC5wb3c7IC8vIFVzZWQgNCB0aW1lcyAoNCo4IHRvIDE1KzQpXHJcblxyXG4vKipcclxuICogQHBhcmFtIHtzdHJpbmd9IHN0clxyXG4gKiBAcGFyYW0geyhib29sZWFufG51bWJlcik9fSB1bnNpZ25lZFxyXG4gKiBAcGFyYW0ge251bWJlcj19IHJhZGl4XHJcbiAqIEByZXR1cm5zIHshTG9uZ31cclxuICogQGlubmVyXHJcbiAqL1xyXG5mdW5jdGlvbiBmcm9tU3RyaW5nKHN0ciwgdW5zaWduZWQsIHJhZGl4KSB7XHJcbiAgICBpZiAoc3RyLmxlbmd0aCA9PT0gMClcclxuICAgICAgICB0aHJvdyBFcnJvcignZW1wdHkgc3RyaW5nJyk7XHJcbiAgICBpZiAoc3RyID09PSBcIk5hTlwiIHx8IHN0ciA9PT0gXCJJbmZpbml0eVwiIHx8IHN0ciA9PT0gXCIrSW5maW5pdHlcIiB8fCBzdHIgPT09IFwiLUluZmluaXR5XCIpXHJcbiAgICAgICAgcmV0dXJuIFpFUk87XHJcbiAgICBpZiAodHlwZW9mIHVuc2lnbmVkID09PSAnbnVtYmVyJykge1xyXG4gICAgICAgIC8vIEZvciBnb29nLm1hdGgubG9uZyBjb21wYXRpYmlsaXR5XHJcbiAgICAgICAgcmFkaXggPSB1bnNpZ25lZCxcclxuICAgICAgICB1bnNpZ25lZCA9IGZhbHNlO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgICB1bnNpZ25lZCA9ICEhIHVuc2lnbmVkO1xyXG4gICAgfVxyXG4gICAgcmFkaXggPSByYWRpeCB8fCAxMDtcclxuICAgIGlmIChyYWRpeCA8IDIgfHwgMzYgPCByYWRpeClcclxuICAgICAgICB0aHJvdyBSYW5nZUVycm9yKCdyYWRpeCcpO1xyXG5cclxuICAgIHZhciBwO1xyXG4gICAgaWYgKChwID0gc3RyLmluZGV4T2YoJy0nKSkgPiAwKVxyXG4gICAgICAgIHRocm93IEVycm9yKCdpbnRlcmlvciBoeXBoZW4nKTtcclxuICAgIGVsc2UgaWYgKHAgPT09IDApIHtcclxuICAgICAgICByZXR1cm4gZnJvbVN0cmluZyhzdHIuc3Vic3RyaW5nKDEpLCB1bnNpZ25lZCwgcmFkaXgpLm5lZygpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIERvIHNldmVyYWwgKDgpIGRpZ2l0cyBlYWNoIHRpbWUgdGhyb3VnaCB0aGUgbG9vcCwgc28gYXMgdG9cclxuICAgIC8vIG1pbmltaXplIHRoZSBjYWxscyB0byB0aGUgdmVyeSBleHBlbnNpdmUgZW11bGF0ZWQgZGl2LlxyXG4gICAgdmFyIHJhZGl4VG9Qb3dlciA9IGZyb21OdW1iZXIocG93X2RibChyYWRpeCwgOCkpO1xyXG5cclxuICAgIHZhciByZXN1bHQgPSBaRVJPO1xyXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyBpICs9IDgpIHtcclxuICAgICAgICB2YXIgc2l6ZSA9IE1hdGgubWluKDgsIHN0ci5sZW5ndGggLSBpKSxcclxuICAgICAgICAgICAgdmFsdWUgPSBwYXJzZUludChzdHIuc3Vic3RyaW5nKGksIGkgKyBzaXplKSwgcmFkaXgpO1xyXG4gICAgICAgIGlmIChzaXplIDwgOCkge1xyXG4gICAgICAgICAgICB2YXIgcG93ZXIgPSBmcm9tTnVtYmVyKHBvd19kYmwocmFkaXgsIHNpemUpKTtcclxuICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0Lm11bChwb3dlcikuYWRkKGZyb21OdW1iZXIodmFsdWUpKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICByZXN1bHQgPSByZXN1bHQubXVsKHJhZGl4VG9Qb3dlcik7XHJcbiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdC5hZGQoZnJvbU51bWJlcih2YWx1ZSkpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJlc3VsdC51bnNpZ25lZCA9IHVuc2lnbmVkO1xyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgYSBMb25nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBnaXZlbiBzdHJpbmcsIHdyaXR0ZW4gdXNpbmcgdGhlIHNwZWNpZmllZCByYWRpeC5cclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgVGhlIHRleHR1YWwgcmVwcmVzZW50YXRpb24gb2YgdGhlIExvbmdcclxuICogQHBhcmFtIHsoYm9vbGVhbnxudW1iZXIpPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIHNpZ25lZFxyXG4gKiBAcGFyYW0ge251bWJlcj19IHJhZGl4IFRoZSByYWRpeCBpbiB3aGljaCB0aGUgdGV4dCBpcyB3cml0dGVuICgyLTM2KSwgZGVmYXVsdHMgdG8gMTBcclxuICogQHJldHVybnMgeyFMb25nfSBUaGUgY29ycmVzcG9uZGluZyBMb25nIHZhbHVlXHJcbiAqL1xyXG5Mb25nLmZyb21TdHJpbmcgPSBmcm9tU3RyaW5nO1xyXG5cclxuLyoqXHJcbiAqIEBmdW5jdGlvblxyXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd8IXtsb3c6IG51bWJlciwgaGlnaDogbnVtYmVyLCB1bnNpZ25lZDogYm9vbGVhbn19IHZhbFxyXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSB1bnNpZ25lZFxyXG4gKiBAcmV0dXJucyB7IUxvbmd9XHJcbiAqIEBpbm5lclxyXG4gKi9cclxuZnVuY3Rpb24gZnJvbVZhbHVlKHZhbCwgdW5zaWduZWQpIHtcclxuICAgIGlmICh0eXBlb2YgdmFsID09PSAnbnVtYmVyJylcclxuICAgICAgICByZXR1cm4gZnJvbU51bWJlcih2YWwsIHVuc2lnbmVkKTtcclxuICAgIGlmICh0eXBlb2YgdmFsID09PSAnc3RyaW5nJylcclxuICAgICAgICByZXR1cm4gZnJvbVN0cmluZyh2YWwsIHVuc2lnbmVkKTtcclxuICAgIC8vIFRocm93cyBmb3Igbm9uLW9iamVjdHMsIGNvbnZlcnRzIG5vbi1pbnN0YW5jZW9mIExvbmc6XHJcbiAgICByZXR1cm4gZnJvbUJpdHModmFsLmxvdywgdmFsLmhpZ2gsIHR5cGVvZiB1bnNpZ25lZCA9PT0gJ2Jvb2xlYW4nID8gdW5zaWduZWQgOiB2YWwudW5zaWduZWQpO1xyXG59XHJcblxyXG4vKipcclxuICogQ29udmVydHMgdGhlIHNwZWNpZmllZCB2YWx1ZSB0byBhIExvbmcgdXNpbmcgdGhlIGFwcHJvcHJpYXRlIGZyb20qIGZ1bmN0aW9uIGZvciBpdHMgdHlwZS5cclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ3whe2xvdzogbnVtYmVyLCBoaWdoOiBudW1iZXIsIHVuc2lnbmVkOiBib29sZWFufX0gdmFsIFZhbHVlXHJcbiAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkIFdoZXRoZXIgdW5zaWduZWQgb3Igbm90LCBkZWZhdWx0cyB0byBzaWduZWRcclxuICogQHJldHVybnMgeyFMb25nfVxyXG4gKi9cclxuTG9uZy5mcm9tVmFsdWUgPSBmcm9tVmFsdWU7XHJcblxyXG4vLyBOT1RFOiB0aGUgY29tcGlsZXIgc2hvdWxkIGlubGluZSB0aGVzZSBjb25zdGFudCB2YWx1ZXMgYmVsb3cgYW5kIHRoZW4gcmVtb3ZlIHRoZXNlIHZhcmlhYmxlcywgc28gdGhlcmUgc2hvdWxkIGJlXHJcbi8vIG5vIHJ1bnRpbWUgcGVuYWx0eSBmb3IgdGhlc2UuXHJcblxyXG4vKipcclxuICogQHR5cGUge251bWJlcn1cclxuICogQGNvbnN0XHJcbiAqIEBpbm5lclxyXG4gKi9cclxudmFyIFRXT19QV1JfMTZfREJMID0gMSA8PCAxNjtcclxuXHJcbi8qKlxyXG4gKiBAdHlwZSB7bnVtYmVyfVxyXG4gKiBAY29uc3RcclxuICogQGlubmVyXHJcbiAqL1xyXG52YXIgVFdPX1BXUl8yNF9EQkwgPSAxIDw8IDI0O1xyXG5cclxuLyoqXHJcbiAqIEB0eXBlIHtudW1iZXJ9XHJcbiAqIEBjb25zdFxyXG4gKiBAaW5uZXJcclxuICovXHJcbnZhciBUV09fUFdSXzMyX0RCTCA9IFRXT19QV1JfMTZfREJMICogVFdPX1BXUl8xNl9EQkw7XHJcblxyXG4vKipcclxuICogQHR5cGUge251bWJlcn1cclxuICogQGNvbnN0XHJcbiAqIEBpbm5lclxyXG4gKi9cclxudmFyIFRXT19QV1JfNjRfREJMID0gVFdPX1BXUl8zMl9EQkwgKiBUV09fUFdSXzMyX0RCTDtcclxuXHJcbi8qKlxyXG4gKiBAdHlwZSB7bnVtYmVyfVxyXG4gKiBAY29uc3RcclxuICogQGlubmVyXHJcbiAqL1xyXG52YXIgVFdPX1BXUl82M19EQkwgPSBUV09fUFdSXzY0X0RCTCAvIDI7XHJcblxyXG4vKipcclxuICogQHR5cGUgeyFMb25nfVxyXG4gKiBAY29uc3RcclxuICogQGlubmVyXHJcbiAqL1xyXG52YXIgVFdPX1BXUl8yNCA9IGZyb21JbnQoVFdPX1BXUl8yNF9EQkwpO1xyXG5cclxuLyoqXHJcbiAqIEB0eXBlIHshTG9uZ31cclxuICogQGlubmVyXHJcbiAqL1xyXG52YXIgWkVSTyA9IGZyb21JbnQoMCk7XHJcblxyXG4vKipcclxuICogU2lnbmVkIHplcm8uXHJcbiAqIEB0eXBlIHshTG9uZ31cclxuICovXHJcbkxvbmcuWkVSTyA9IFpFUk87XHJcblxyXG4vKipcclxuICogQHR5cGUgeyFMb25nfVxyXG4gKiBAaW5uZXJcclxuICovXHJcbnZhciBVWkVSTyA9IGZyb21JbnQoMCwgdHJ1ZSk7XHJcblxyXG4vKipcclxuICogVW5zaWduZWQgemVyby5cclxuICogQHR5cGUgeyFMb25nfVxyXG4gKi9cclxuTG9uZy5VWkVSTyA9IFVaRVJPO1xyXG5cclxuLyoqXHJcbiAqIEB0eXBlIHshTG9uZ31cclxuICogQGlubmVyXHJcbiAqL1xyXG52YXIgT05FID0gZnJvbUludCgxKTtcclxuXHJcbi8qKlxyXG4gKiBTaWduZWQgb25lLlxyXG4gKiBAdHlwZSB7IUxvbmd9XHJcbiAqL1xyXG5Mb25nLk9ORSA9IE9ORTtcclxuXHJcbi8qKlxyXG4gKiBAdHlwZSB7IUxvbmd9XHJcbiAqIEBpbm5lclxyXG4gKi9cclxudmFyIFVPTkUgPSBmcm9tSW50KDEsIHRydWUpO1xyXG5cclxuLyoqXHJcbiAqIFVuc2lnbmVkIG9uZS5cclxuICogQHR5cGUgeyFMb25nfVxyXG4gKi9cclxuTG9uZy5VT05FID0gVU9ORTtcclxuXHJcbi8qKlxyXG4gKiBAdHlwZSB7IUxvbmd9XHJcbiAqIEBpbm5lclxyXG4gKi9cclxudmFyIE5FR19PTkUgPSBmcm9tSW50KC0xKTtcclxuXHJcbi8qKlxyXG4gKiBTaWduZWQgbmVnYXRpdmUgb25lLlxyXG4gKiBAdHlwZSB7IUxvbmd9XHJcbiAqL1xyXG5Mb25nLk5FR19PTkUgPSBORUdfT05FO1xyXG5cclxuLyoqXHJcbiAqIEB0eXBlIHshTG9uZ31cclxuICogQGlubmVyXHJcbiAqL1xyXG52YXIgTUFYX1ZBTFVFID0gZnJvbUJpdHMoMHhGRkZGRkZGRnwwLCAweDdGRkZGRkZGfDAsIGZhbHNlKTtcclxuXHJcbi8qKlxyXG4gKiBNYXhpbXVtIHNpZ25lZCB2YWx1ZS5cclxuICogQHR5cGUgeyFMb25nfVxyXG4gKi9cclxuTG9uZy5NQVhfVkFMVUUgPSBNQVhfVkFMVUU7XHJcblxyXG4vKipcclxuICogQHR5cGUgeyFMb25nfVxyXG4gKiBAaW5uZXJcclxuICovXHJcbnZhciBNQVhfVU5TSUdORURfVkFMVUUgPSBmcm9tQml0cygweEZGRkZGRkZGfDAsIDB4RkZGRkZGRkZ8MCwgdHJ1ZSk7XHJcblxyXG4vKipcclxuICogTWF4aW11bSB1bnNpZ25lZCB2YWx1ZS5cclxuICogQHR5cGUgeyFMb25nfVxyXG4gKi9cclxuTG9uZy5NQVhfVU5TSUdORURfVkFMVUUgPSBNQVhfVU5TSUdORURfVkFMVUU7XHJcblxyXG4vKipcclxuICogQHR5cGUgeyFMb25nfVxyXG4gKiBAaW5uZXJcclxuICovXHJcbnZhciBNSU5fVkFMVUUgPSBmcm9tQml0cygwLCAweDgwMDAwMDAwfDAsIGZhbHNlKTtcclxuXHJcbi8qKlxyXG4gKiBNaW5pbXVtIHNpZ25lZCB2YWx1ZS5cclxuICogQHR5cGUgeyFMb25nfVxyXG4gKi9cclxuTG9uZy5NSU5fVkFMVUUgPSBNSU5fVkFMVUU7XHJcblxyXG4vKipcclxuICogQGFsaWFzIExvbmcucHJvdG90eXBlXHJcbiAqIEBpbm5lclxyXG4gKi9cclxudmFyIExvbmdQcm90b3R5cGUgPSBMb25nLnByb3RvdHlwZTtcclxuXHJcbi8qKlxyXG4gKiBDb252ZXJ0cyB0aGUgTG9uZyB0byBhIDMyIGJpdCBpbnRlZ2VyLCBhc3N1bWluZyBpdCBpcyBhIDMyIGJpdCBpbnRlZ2VyLlxyXG4gKiBAcmV0dXJucyB7bnVtYmVyfVxyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS50b0ludCA9IGZ1bmN0aW9uIHRvSW50KCkge1xyXG4gICAgcmV0dXJuIHRoaXMudW5zaWduZWQgPyB0aGlzLmxvdyA+Pj4gMCA6IHRoaXMubG93O1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIENvbnZlcnRzIHRoZSBMb25nIHRvIGEgdGhlIG5lYXJlc3QgZmxvYXRpbmctcG9pbnQgcmVwcmVzZW50YXRpb24gb2YgdGhpcyB2YWx1ZSAoZG91YmxlLCA1MyBiaXQgbWFudGlzc2EpLlxyXG4gKiBAcmV0dXJucyB7bnVtYmVyfVxyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS50b051bWJlciA9IGZ1bmN0aW9uIHRvTnVtYmVyKCkge1xyXG4gICAgaWYgKHRoaXMudW5zaWduZWQpXHJcbiAgICAgICAgcmV0dXJuICgodGhpcy5oaWdoID4+PiAwKSAqIFRXT19QV1JfMzJfREJMKSArICh0aGlzLmxvdyA+Pj4gMCk7XHJcbiAgICByZXR1cm4gdGhpcy5oaWdoICogVFdPX1BXUl8zMl9EQkwgKyAodGhpcy5sb3cgPj4+IDApO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIENvbnZlcnRzIHRoZSBMb25nIHRvIGEgc3RyaW5nIHdyaXR0ZW4gaW4gdGhlIHNwZWNpZmllZCByYWRpeC5cclxuICogQHBhcmFtIHtudW1iZXI9fSByYWRpeCBSYWRpeCAoMi0zNiksIGRlZmF1bHRzIHRvIDEwXHJcbiAqIEByZXR1cm5zIHtzdHJpbmd9XHJcbiAqIEBvdmVycmlkZVxyXG4gKiBAdGhyb3dzIHtSYW5nZUVycm9yfSBJZiBgcmFkaXhgIGlzIG91dCBvZiByYW5nZVxyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKHJhZGl4KSB7XHJcbiAgICByYWRpeCA9IHJhZGl4IHx8IDEwO1xyXG4gICAgaWYgKHJhZGl4IDwgMiB8fCAzNiA8IHJhZGl4KVxyXG4gICAgICAgIHRocm93IFJhbmdlRXJyb3IoJ3JhZGl4Jyk7XHJcbiAgICBpZiAodGhpcy5pc1plcm8oKSlcclxuICAgICAgICByZXR1cm4gJzAnO1xyXG4gICAgaWYgKHRoaXMuaXNOZWdhdGl2ZSgpKSB7IC8vIFVuc2lnbmVkIExvbmdzIGFyZSBuZXZlciBuZWdhdGl2ZVxyXG4gICAgICAgIGlmICh0aGlzLmVxKE1JTl9WQUxVRSkpIHtcclxuICAgICAgICAgICAgLy8gV2UgbmVlZCB0byBjaGFuZ2UgdGhlIExvbmcgdmFsdWUgYmVmb3JlIGl0IGNhbiBiZSBuZWdhdGVkLCBzbyB3ZSByZW1vdmVcclxuICAgICAgICAgICAgLy8gdGhlIGJvdHRvbS1tb3N0IGRpZ2l0IGluIHRoaXMgYmFzZSBhbmQgdGhlbiByZWN1cnNlIHRvIGRvIHRoZSByZXN0LlxyXG4gICAgICAgICAgICB2YXIgcmFkaXhMb25nID0gZnJvbU51bWJlcihyYWRpeCksXHJcbiAgICAgICAgICAgICAgICBkaXYgPSB0aGlzLmRpdihyYWRpeExvbmcpLFxyXG4gICAgICAgICAgICAgICAgcmVtMSA9IGRpdi5tdWwocmFkaXhMb25nKS5zdWIodGhpcyk7XHJcbiAgICAgICAgICAgIHJldHVybiBkaXYudG9TdHJpbmcocmFkaXgpICsgcmVtMS50b0ludCgpLnRvU3RyaW5nKHJhZGl4KTtcclxuICAgICAgICB9IGVsc2VcclxuICAgICAgICAgICAgcmV0dXJuICctJyArIHRoaXMubmVnKCkudG9TdHJpbmcocmFkaXgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIERvIHNldmVyYWwgKDYpIGRpZ2l0cyBlYWNoIHRpbWUgdGhyb3VnaCB0aGUgbG9vcCwgc28gYXMgdG9cclxuICAgIC8vIG1pbmltaXplIHRoZSBjYWxscyB0byB0aGUgdmVyeSBleHBlbnNpdmUgZW11bGF0ZWQgZGl2LlxyXG4gICAgdmFyIHJhZGl4VG9Qb3dlciA9IGZyb21OdW1iZXIocG93X2RibChyYWRpeCwgNiksIHRoaXMudW5zaWduZWQpLFxyXG4gICAgICAgIHJlbSA9IHRoaXM7XHJcbiAgICB2YXIgcmVzdWx0ID0gJyc7XHJcbiAgICB3aGlsZSAodHJ1ZSkge1xyXG4gICAgICAgIHZhciByZW1EaXYgPSByZW0uZGl2KHJhZGl4VG9Qb3dlciksXHJcbiAgICAgICAgICAgIGludHZhbCA9IHJlbS5zdWIocmVtRGl2Lm11bChyYWRpeFRvUG93ZXIpKS50b0ludCgpID4+PiAwLFxyXG4gICAgICAgICAgICBkaWdpdHMgPSBpbnR2YWwudG9TdHJpbmcocmFkaXgpO1xyXG4gICAgICAgIHJlbSA9IHJlbURpdjtcclxuICAgICAgICBpZiAocmVtLmlzWmVybygpKVxyXG4gICAgICAgICAgICByZXR1cm4gZGlnaXRzICsgcmVzdWx0O1xyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB3aGlsZSAoZGlnaXRzLmxlbmd0aCA8IDYpXHJcbiAgICAgICAgICAgICAgICBkaWdpdHMgPSAnMCcgKyBkaWdpdHM7XHJcbiAgICAgICAgICAgIHJlc3VsdCA9ICcnICsgZGlnaXRzICsgcmVzdWx0O1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufTtcclxuXHJcbi8qKlxyXG4gKiBHZXRzIHRoZSBoaWdoIDMyIGJpdHMgYXMgYSBzaWduZWQgaW50ZWdlci5cclxuICogQHJldHVybnMge251bWJlcn0gU2lnbmVkIGhpZ2ggYml0c1xyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS5nZXRIaWdoQml0cyA9IGZ1bmN0aW9uIGdldEhpZ2hCaXRzKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuaGlnaDtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBHZXRzIHRoZSBoaWdoIDMyIGJpdHMgYXMgYW4gdW5zaWduZWQgaW50ZWdlci5cclxuICogQHJldHVybnMge251bWJlcn0gVW5zaWduZWQgaGlnaCBiaXRzXHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLmdldEhpZ2hCaXRzVW5zaWduZWQgPSBmdW5jdGlvbiBnZXRIaWdoQml0c1Vuc2lnbmVkKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuaGlnaCA+Pj4gMDtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBHZXRzIHRoZSBsb3cgMzIgYml0cyBhcyBhIHNpZ25lZCBpbnRlZ2VyLlxyXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBTaWduZWQgbG93IGJpdHNcclxuICovXHJcbkxvbmdQcm90b3R5cGUuZ2V0TG93Qml0cyA9IGZ1bmN0aW9uIGdldExvd0JpdHMoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5sb3c7XHJcbn07XHJcblxyXG4vKipcclxuICogR2V0cyB0aGUgbG93IDMyIGJpdHMgYXMgYW4gdW5zaWduZWQgaW50ZWdlci5cclxuICogQHJldHVybnMge251bWJlcn0gVW5zaWduZWQgbG93IGJpdHNcclxuICovXHJcbkxvbmdQcm90b3R5cGUuZ2V0TG93Qml0c1Vuc2lnbmVkID0gZnVuY3Rpb24gZ2V0TG93Qml0c1Vuc2lnbmVkKCkge1xyXG4gICAgcmV0dXJuIHRoaXMubG93ID4+PiAwO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIEdldHMgdGhlIG51bWJlciBvZiBiaXRzIG5lZWRlZCB0byByZXByZXNlbnQgdGhlIGFic29sdXRlIHZhbHVlIG9mIHRoaXMgTG9uZy5cclxuICogQHJldHVybnMge251bWJlcn1cclxuICovXHJcbkxvbmdQcm90b3R5cGUuZ2V0TnVtQml0c0FicyA9IGZ1bmN0aW9uIGdldE51bUJpdHNBYnMoKSB7XHJcbiAgICBpZiAodGhpcy5pc05lZ2F0aXZlKCkpIC8vIFVuc2lnbmVkIExvbmdzIGFyZSBuZXZlciBuZWdhdGl2ZVxyXG4gICAgICAgIHJldHVybiB0aGlzLmVxKE1JTl9WQUxVRSkgPyA2NCA6IHRoaXMubmVnKCkuZ2V0TnVtQml0c0FicygpO1xyXG4gICAgdmFyIHZhbCA9IHRoaXMuaGlnaCAhPSAwID8gdGhpcy5oaWdoIDogdGhpcy5sb3c7XHJcbiAgICBmb3IgKHZhciBiaXQgPSAzMTsgYml0ID4gMDsgYml0LS0pXHJcbiAgICAgICAgaWYgKCh2YWwgJiAoMSA8PCBiaXQpKSAhPSAwKVxyXG4gICAgICAgICAgICBicmVhaztcclxuICAgIHJldHVybiB0aGlzLmhpZ2ggIT0gMCA/IGJpdCArIDMzIDogYml0ICsgMTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBlcXVhbHMgemVyby5cclxuICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLmlzWmVybyA9IGZ1bmN0aW9uIGlzWmVybygpIHtcclxuICAgIHJldHVybiB0aGlzLmhpZ2ggPT09IDAgJiYgdGhpcy5sb3cgPT09IDA7XHJcbn07XHJcblxyXG4vKipcclxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgZXF1YWxzIHplcm8uIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjaXNaZXJvfS5cclxuICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLmVxeiA9IExvbmdQcm90b3R5cGUuaXNaZXJvO1xyXG5cclxuLyoqXHJcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIG5lZ2F0aXZlLlxyXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICovXHJcbkxvbmdQcm90b3R5cGUuaXNOZWdhdGl2ZSA9IGZ1bmN0aW9uIGlzTmVnYXRpdmUoKSB7XHJcbiAgICByZXR1cm4gIXRoaXMudW5zaWduZWQgJiYgdGhpcy5oaWdoIDwgMDtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBwb3NpdGl2ZS5cclxuICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLmlzUG9zaXRpdmUgPSBmdW5jdGlvbiBpc1Bvc2l0aXZlKCkge1xyXG4gICAgcmV0dXJuIHRoaXMudW5zaWduZWQgfHwgdGhpcy5oaWdoID49IDA7XHJcbn07XHJcblxyXG4vKipcclxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgb2RkLlxyXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICovXHJcbkxvbmdQcm90b3R5cGUuaXNPZGQgPSBmdW5jdGlvbiBpc09kZCgpIHtcclxuICAgIHJldHVybiAodGhpcy5sb3cgJiAxKSA9PT0gMTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBldmVuLlxyXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICovXHJcbkxvbmdQcm90b3R5cGUuaXNFdmVuID0gZnVuY3Rpb24gaXNFdmVuKCkge1xyXG4gICAgcmV0dXJuICh0aGlzLmxvdyAmIDEpID09PSAwO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGVxdWFscyB0aGUgc3BlY2lmaWVkJ3MuXHJcbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLmVxdWFscyA9IGZ1bmN0aW9uIGVxdWFscyhvdGhlcikge1xyXG4gICAgaWYgKCFpc0xvbmcob3RoZXIpKVxyXG4gICAgICAgIG90aGVyID0gZnJvbVZhbHVlKG90aGVyKTtcclxuICAgIGlmICh0aGlzLnVuc2lnbmVkICE9PSBvdGhlci51bnNpZ25lZCAmJiAodGhpcy5oaWdoID4+PiAzMSkgPT09IDEgJiYgKG90aGVyLmhpZ2ggPj4+IDMxKSA9PT0gMSlcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICByZXR1cm4gdGhpcy5oaWdoID09PSBvdGhlci5oaWdoICYmIHRoaXMubG93ID09PSBvdGhlci5sb3c7XHJcbn07XHJcblxyXG4vKipcclxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgZXF1YWxzIHRoZSBzcGVjaWZpZWQncy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNlcXVhbHN9LlxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxyXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICovXHJcbkxvbmdQcm90b3R5cGUuZXEgPSBMb25nUHJvdG90eXBlLmVxdWFscztcclxuXHJcbi8qKlxyXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBkaWZmZXJzIGZyb20gdGhlIHNwZWNpZmllZCdzLlxyXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXHJcbiAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS5ub3RFcXVhbHMgPSBmdW5jdGlvbiBub3RFcXVhbHMob3RoZXIpIHtcclxuICAgIHJldHVybiAhdGhpcy5lcSgvKiB2YWxpZGF0ZXMgKi8gb3RoZXIpO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGRpZmZlcnMgZnJvbSB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjbm90RXF1YWxzfS5cclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLm5lcSA9IExvbmdQcm90b3R5cGUubm90RXF1YWxzO1xyXG5cclxuLyoqXHJcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGRpZmZlcnMgZnJvbSB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjbm90RXF1YWxzfS5cclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLm5lID0gTG9uZ1Byb3RvdHlwZS5ub3RFcXVhbHM7XHJcblxyXG4vKipcclxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgbGVzcyB0aGFuIHRoZSBzcGVjaWZpZWQncy5cclxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxyXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICovXHJcbkxvbmdQcm90b3R5cGUubGVzc1RoYW4gPSBmdW5jdGlvbiBsZXNzVGhhbihvdGhlcikge1xyXG4gICAgcmV0dXJuIHRoaXMuY29tcCgvKiB2YWxpZGF0ZXMgKi8gb3RoZXIpIDwgMDtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBsZXNzIHRoYW4gdGhlIHNwZWNpZmllZCdzLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI2xlc3NUaGFufS5cclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLmx0ID0gTG9uZ1Byb3RvdHlwZS5sZXNzVGhhbjtcclxuXHJcbi8qKlxyXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdGhlIHNwZWNpZmllZCdzLlxyXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXHJcbiAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS5sZXNzVGhhbk9yRXF1YWwgPSBmdW5jdGlvbiBsZXNzVGhhbk9yRXF1YWwob3RoZXIpIHtcclxuICAgIHJldHVybiB0aGlzLmNvbXAoLyogdmFsaWRhdGVzICovIG90aGVyKSA8PSAwO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjbGVzc1RoYW5PckVxdWFsfS5cclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLmx0ZSA9IExvbmdQcm90b3R5cGUubGVzc1RoYW5PckVxdWFsO1xyXG5cclxuLyoqXHJcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjbGVzc1RoYW5PckVxdWFsfS5cclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLmxlID0gTG9uZ1Byb3RvdHlwZS5sZXNzVGhhbk9yRXF1YWw7XHJcblxyXG4vKipcclxuICogVGVzdHMgaWYgdGhpcyBMb25nJ3MgdmFsdWUgaXMgZ3JlYXRlciB0aGFuIHRoZSBzcGVjaWZpZWQncy5cclxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciB2YWx1ZVxyXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICovXHJcbkxvbmdQcm90b3R5cGUuZ3JlYXRlclRoYW4gPSBmdW5jdGlvbiBncmVhdGVyVGhhbihvdGhlcikge1xyXG4gICAgcmV0dXJuIHRoaXMuY29tcCgvKiB2YWxpZGF0ZXMgKi8gb3RoZXIpID4gMDtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBncmVhdGVyIHRoYW4gdGhlIHNwZWNpZmllZCdzLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI2dyZWF0ZXJUaGFufS5cclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLmd0ID0gTG9uZ1Byb3RvdHlwZS5ncmVhdGVyVGhhbjtcclxuXHJcbi8qKlxyXG4gKiBUZXN0cyBpZiB0aGlzIExvbmcncyB2YWx1ZSBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdGhlIHNwZWNpZmllZCdzLlxyXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXHJcbiAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS5ncmVhdGVyVGhhbk9yRXF1YWwgPSBmdW5jdGlvbiBncmVhdGVyVGhhbk9yRXF1YWwob3RoZXIpIHtcclxuICAgIHJldHVybiB0aGlzLmNvbXAoLyogdmFsaWRhdGVzICovIG90aGVyKSA+PSAwO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjZ3JlYXRlclRoYW5PckVxdWFsfS5cclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLmd0ZSA9IExvbmdQcm90b3R5cGUuZ3JlYXRlclRoYW5PckVxdWFsO1xyXG5cclxuLyoqXHJcbiAqIFRlc3RzIGlmIHRoaXMgTG9uZydzIHZhbHVlIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjZ3JlYXRlclRoYW5PckVxdWFsfS5cclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLmdlID0gTG9uZ1Byb3RvdHlwZS5ncmVhdGVyVGhhbk9yRXF1YWw7XHJcblxyXG4vKipcclxuICogQ29tcGFyZXMgdGhpcyBMb25nJ3MgdmFsdWUgd2l0aCB0aGUgc3BlY2lmaWVkJ3MuXHJcbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgdmFsdWVcclxuICogQHJldHVybnMge251bWJlcn0gMCBpZiB0aGV5IGFyZSB0aGUgc2FtZSwgMSBpZiB0aGUgdGhpcyBpcyBncmVhdGVyIGFuZCAtMVxyXG4gKiAgaWYgdGhlIGdpdmVuIG9uZSBpcyBncmVhdGVyXHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLmNvbXBhcmUgPSBmdW5jdGlvbiBjb21wYXJlKG90aGVyKSB7XHJcbiAgICBpZiAoIWlzTG9uZyhvdGhlcikpXHJcbiAgICAgICAgb3RoZXIgPSBmcm9tVmFsdWUob3RoZXIpO1xyXG4gICAgaWYgKHRoaXMuZXEob3RoZXIpKVxyXG4gICAgICAgIHJldHVybiAwO1xyXG4gICAgdmFyIHRoaXNOZWcgPSB0aGlzLmlzTmVnYXRpdmUoKSxcclxuICAgICAgICBvdGhlck5lZyA9IG90aGVyLmlzTmVnYXRpdmUoKTtcclxuICAgIGlmICh0aGlzTmVnICYmICFvdGhlck5lZylcclxuICAgICAgICByZXR1cm4gLTE7XHJcbiAgICBpZiAoIXRoaXNOZWcgJiYgb3RoZXJOZWcpXHJcbiAgICAgICAgcmV0dXJuIDE7XHJcbiAgICAvLyBBdCB0aGlzIHBvaW50IHRoZSBzaWduIGJpdHMgYXJlIHRoZSBzYW1lXHJcbiAgICBpZiAoIXRoaXMudW5zaWduZWQpXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuc3ViKG90aGVyKS5pc05lZ2F0aXZlKCkgPyAtMSA6IDE7XHJcbiAgICAvLyBCb3RoIGFyZSBwb3NpdGl2ZSBpZiBhdCBsZWFzdCBvbmUgaXMgdW5zaWduZWRcclxuICAgIHJldHVybiAob3RoZXIuaGlnaCA+Pj4gMCkgPiAodGhpcy5oaWdoID4+PiAwKSB8fCAob3RoZXIuaGlnaCA9PT0gdGhpcy5oaWdoICYmIChvdGhlci5sb3cgPj4+IDApID4gKHRoaXMubG93ID4+PiAwKSkgPyAtMSA6IDE7XHJcbn07XHJcblxyXG4vKipcclxuICogQ29tcGFyZXMgdGhpcyBMb25nJ3MgdmFsdWUgd2l0aCB0aGUgc3BlY2lmaWVkJ3MuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjY29tcGFyZX0uXHJcbiAqIEBmdW5jdGlvblxyXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IG90aGVyIE90aGVyIHZhbHVlXHJcbiAqIEByZXR1cm5zIHtudW1iZXJ9IDAgaWYgdGhleSBhcmUgdGhlIHNhbWUsIDEgaWYgdGhlIHRoaXMgaXMgZ3JlYXRlciBhbmQgLTFcclxuICogIGlmIHRoZSBnaXZlbiBvbmUgaXMgZ3JlYXRlclxyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS5jb21wID0gTG9uZ1Byb3RvdHlwZS5jb21wYXJlO1xyXG5cclxuLyoqXHJcbiAqIE5lZ2F0ZXMgdGhpcyBMb25nJ3MgdmFsdWUuXHJcbiAqIEByZXR1cm5zIHshTG9uZ30gTmVnYXRlZCBMb25nXHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLm5lZ2F0ZSA9IGZ1bmN0aW9uIG5lZ2F0ZSgpIHtcclxuICAgIGlmICghdGhpcy51bnNpZ25lZCAmJiB0aGlzLmVxKE1JTl9WQUxVRSkpXHJcbiAgICAgICAgcmV0dXJuIE1JTl9WQUxVRTtcclxuICAgIHJldHVybiB0aGlzLm5vdCgpLmFkZChPTkUpO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIE5lZ2F0ZXMgdGhpcyBMb25nJ3MgdmFsdWUuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjbmVnYXRlfS5cclxuICogQGZ1bmN0aW9uXHJcbiAqIEByZXR1cm5zIHshTG9uZ30gTmVnYXRlZCBMb25nXHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLm5lZyA9IExvbmdQcm90b3R5cGUubmVnYXRlO1xyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgdGhlIHN1bSBvZiB0aGlzIGFuZCB0aGUgc3BlY2lmaWVkIExvbmcuXHJcbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gYWRkZW5kIEFkZGVuZFxyXG4gKiBAcmV0dXJucyB7IUxvbmd9IFN1bVxyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS5hZGQgPSBmdW5jdGlvbiBhZGQoYWRkZW5kKSB7XHJcbiAgICBpZiAoIWlzTG9uZyhhZGRlbmQpKVxyXG4gICAgICAgIGFkZGVuZCA9IGZyb21WYWx1ZShhZGRlbmQpO1xyXG5cclxuICAgIC8vIERpdmlkZSBlYWNoIG51bWJlciBpbnRvIDQgY2h1bmtzIG9mIDE2IGJpdHMsIGFuZCB0aGVuIHN1bSB0aGUgY2h1bmtzLlxyXG5cclxuICAgIHZhciBhNDggPSB0aGlzLmhpZ2ggPj4+IDE2O1xyXG4gICAgdmFyIGEzMiA9IHRoaXMuaGlnaCAmIDB4RkZGRjtcclxuICAgIHZhciBhMTYgPSB0aGlzLmxvdyA+Pj4gMTY7XHJcbiAgICB2YXIgYTAwID0gdGhpcy5sb3cgJiAweEZGRkY7XHJcblxyXG4gICAgdmFyIGI0OCA9IGFkZGVuZC5oaWdoID4+PiAxNjtcclxuICAgIHZhciBiMzIgPSBhZGRlbmQuaGlnaCAmIDB4RkZGRjtcclxuICAgIHZhciBiMTYgPSBhZGRlbmQubG93ID4+PiAxNjtcclxuICAgIHZhciBiMDAgPSBhZGRlbmQubG93ICYgMHhGRkZGO1xyXG5cclxuICAgIHZhciBjNDggPSAwLCBjMzIgPSAwLCBjMTYgPSAwLCBjMDAgPSAwO1xyXG4gICAgYzAwICs9IGEwMCArIGIwMDtcclxuICAgIGMxNiArPSBjMDAgPj4+IDE2O1xyXG4gICAgYzAwICY9IDB4RkZGRjtcclxuICAgIGMxNiArPSBhMTYgKyBiMTY7XHJcbiAgICBjMzIgKz0gYzE2ID4+PiAxNjtcclxuICAgIGMxNiAmPSAweEZGRkY7XHJcbiAgICBjMzIgKz0gYTMyICsgYjMyO1xyXG4gICAgYzQ4ICs9IGMzMiA+Pj4gMTY7XHJcbiAgICBjMzIgJj0gMHhGRkZGO1xyXG4gICAgYzQ4ICs9IGE0OCArIGI0ODtcclxuICAgIGM0OCAmPSAweEZGRkY7XHJcbiAgICByZXR1cm4gZnJvbUJpdHMoKGMxNiA8PCAxNikgfCBjMDAsIChjNDggPDwgMTYpIHwgYzMyLCB0aGlzLnVuc2lnbmVkKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIHRoZSBkaWZmZXJlbmNlIG9mIHRoaXMgYW5kIHRoZSBzcGVjaWZpZWQgTG9uZy5cclxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBzdWJ0cmFoZW5kIFN1YnRyYWhlbmRcclxuICogQHJldHVybnMgeyFMb25nfSBEaWZmZXJlbmNlXHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLnN1YnRyYWN0ID0gZnVuY3Rpb24gc3VidHJhY3Qoc3VidHJhaGVuZCkge1xyXG4gICAgaWYgKCFpc0xvbmcoc3VidHJhaGVuZCkpXHJcbiAgICAgICAgc3VidHJhaGVuZCA9IGZyb21WYWx1ZShzdWJ0cmFoZW5kKTtcclxuICAgIHJldHVybiB0aGlzLmFkZChzdWJ0cmFoZW5kLm5lZygpKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIHRoZSBkaWZmZXJlbmNlIG9mIHRoaXMgYW5kIHRoZSBzcGVjaWZpZWQgTG9uZy4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNzdWJ0cmFjdH0uXHJcbiAqIEBmdW5jdGlvblxyXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IHN1YnRyYWhlbmQgU3VidHJhaGVuZFxyXG4gKiBAcmV0dXJucyB7IUxvbmd9IERpZmZlcmVuY2VcclxuICovXHJcbkxvbmdQcm90b3R5cGUuc3ViID0gTG9uZ1Byb3RvdHlwZS5zdWJ0cmFjdDtcclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIHRoZSBwcm9kdWN0IG9mIHRoaXMgYW5kIHRoZSBzcGVjaWZpZWQgTG9uZy5cclxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBtdWx0aXBsaWVyIE11bHRpcGxpZXJcclxuICogQHJldHVybnMgeyFMb25nfSBQcm9kdWN0XHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLm11bHRpcGx5ID0gZnVuY3Rpb24gbXVsdGlwbHkobXVsdGlwbGllcikge1xyXG4gICAgaWYgKHRoaXMuaXNaZXJvKCkpXHJcbiAgICAgICAgcmV0dXJuIFpFUk87XHJcbiAgICBpZiAoIWlzTG9uZyhtdWx0aXBsaWVyKSlcclxuICAgICAgICBtdWx0aXBsaWVyID0gZnJvbVZhbHVlKG11bHRpcGxpZXIpO1xyXG5cclxuICAgIC8vIHVzZSB3YXNtIHN1cHBvcnQgaWYgcHJlc2VudFxyXG4gICAgaWYgKHdhc20pIHtcclxuICAgICAgICB2YXIgbG93ID0gd2FzbS5tdWwodGhpcy5sb3csXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaGlnaCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgbXVsdGlwbGllci5sb3csXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIG11bHRpcGxpZXIuaGlnaCk7XHJcbiAgICAgICAgcmV0dXJuIGZyb21CaXRzKGxvdywgd2FzbS5nZXRfaGlnaCgpLCB0aGlzLnVuc2lnbmVkKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAobXVsdGlwbGllci5pc1plcm8oKSlcclxuICAgICAgICByZXR1cm4gWkVSTztcclxuICAgIGlmICh0aGlzLmVxKE1JTl9WQUxVRSkpXHJcbiAgICAgICAgcmV0dXJuIG11bHRpcGxpZXIuaXNPZGQoKSA/IE1JTl9WQUxVRSA6IFpFUk87XHJcbiAgICBpZiAobXVsdGlwbGllci5lcShNSU5fVkFMVUUpKVxyXG4gICAgICAgIHJldHVybiB0aGlzLmlzT2RkKCkgPyBNSU5fVkFMVUUgOiBaRVJPO1xyXG5cclxuICAgIGlmICh0aGlzLmlzTmVnYXRpdmUoKSkge1xyXG4gICAgICAgIGlmIChtdWx0aXBsaWVyLmlzTmVnYXRpdmUoKSlcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMubmVnKCkubXVsKG11bHRpcGxpZXIubmVnKCkpO1xyXG4gICAgICAgIGVsc2VcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMubmVnKCkubXVsKG11bHRpcGxpZXIpLm5lZygpO1xyXG4gICAgfSBlbHNlIGlmIChtdWx0aXBsaWVyLmlzTmVnYXRpdmUoKSlcclxuICAgICAgICByZXR1cm4gdGhpcy5tdWwobXVsdGlwbGllci5uZWcoKSkubmVnKCk7XHJcblxyXG4gICAgLy8gSWYgYm90aCBsb25ncyBhcmUgc21hbGwsIHVzZSBmbG9hdCBtdWx0aXBsaWNhdGlvblxyXG4gICAgaWYgKHRoaXMubHQoVFdPX1BXUl8yNCkgJiYgbXVsdGlwbGllci5sdChUV09fUFdSXzI0KSlcclxuICAgICAgICByZXR1cm4gZnJvbU51bWJlcih0aGlzLnRvTnVtYmVyKCkgKiBtdWx0aXBsaWVyLnRvTnVtYmVyKCksIHRoaXMudW5zaWduZWQpO1xyXG5cclxuICAgIC8vIERpdmlkZSBlYWNoIGxvbmcgaW50byA0IGNodW5rcyBvZiAxNiBiaXRzLCBhbmQgdGhlbiBhZGQgdXAgNHg0IHByb2R1Y3RzLlxyXG4gICAgLy8gV2UgY2FuIHNraXAgcHJvZHVjdHMgdGhhdCB3b3VsZCBvdmVyZmxvdy5cclxuXHJcbiAgICB2YXIgYTQ4ID0gdGhpcy5oaWdoID4+PiAxNjtcclxuICAgIHZhciBhMzIgPSB0aGlzLmhpZ2ggJiAweEZGRkY7XHJcbiAgICB2YXIgYTE2ID0gdGhpcy5sb3cgPj4+IDE2O1xyXG4gICAgdmFyIGEwMCA9IHRoaXMubG93ICYgMHhGRkZGO1xyXG5cclxuICAgIHZhciBiNDggPSBtdWx0aXBsaWVyLmhpZ2ggPj4+IDE2O1xyXG4gICAgdmFyIGIzMiA9IG11bHRpcGxpZXIuaGlnaCAmIDB4RkZGRjtcclxuICAgIHZhciBiMTYgPSBtdWx0aXBsaWVyLmxvdyA+Pj4gMTY7XHJcbiAgICB2YXIgYjAwID0gbXVsdGlwbGllci5sb3cgJiAweEZGRkY7XHJcblxyXG4gICAgdmFyIGM0OCA9IDAsIGMzMiA9IDAsIGMxNiA9IDAsIGMwMCA9IDA7XHJcbiAgICBjMDAgKz0gYTAwICogYjAwO1xyXG4gICAgYzE2ICs9IGMwMCA+Pj4gMTY7XHJcbiAgICBjMDAgJj0gMHhGRkZGO1xyXG4gICAgYzE2ICs9IGExNiAqIGIwMDtcclxuICAgIGMzMiArPSBjMTYgPj4+IDE2O1xyXG4gICAgYzE2ICY9IDB4RkZGRjtcclxuICAgIGMxNiArPSBhMDAgKiBiMTY7XHJcbiAgICBjMzIgKz0gYzE2ID4+PiAxNjtcclxuICAgIGMxNiAmPSAweEZGRkY7XHJcbiAgICBjMzIgKz0gYTMyICogYjAwO1xyXG4gICAgYzQ4ICs9IGMzMiA+Pj4gMTY7XHJcbiAgICBjMzIgJj0gMHhGRkZGO1xyXG4gICAgYzMyICs9IGExNiAqIGIxNjtcclxuICAgIGM0OCArPSBjMzIgPj4+IDE2O1xyXG4gICAgYzMyICY9IDB4RkZGRjtcclxuICAgIGMzMiArPSBhMDAgKiBiMzI7XHJcbiAgICBjNDggKz0gYzMyID4+PiAxNjtcclxuICAgIGMzMiAmPSAweEZGRkY7XHJcbiAgICBjNDggKz0gYTQ4ICogYjAwICsgYTMyICogYjE2ICsgYTE2ICogYjMyICsgYTAwICogYjQ4O1xyXG4gICAgYzQ4ICY9IDB4RkZGRjtcclxuICAgIHJldHVybiBmcm9tQml0cygoYzE2IDw8IDE2KSB8IGMwMCwgKGM0OCA8PCAxNikgfCBjMzIsIHRoaXMudW5zaWduZWQpO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgdGhlIHByb2R1Y3Qgb2YgdGhpcyBhbmQgdGhlIHNwZWNpZmllZCBMb25nLiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayBMb25nI211bHRpcGx5fS5cclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gbXVsdGlwbGllciBNdWx0aXBsaWVyXHJcbiAqIEByZXR1cm5zIHshTG9uZ30gUHJvZHVjdFxyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS5tdWwgPSBMb25nUHJvdG90eXBlLm11bHRpcGx5O1xyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgdGhpcyBMb25nIGRpdmlkZWQgYnkgdGhlIHNwZWNpZmllZC4gVGhlIHJlc3VsdCBpcyBzaWduZWQgaWYgdGhpcyBMb25nIGlzIHNpZ25lZCBvclxyXG4gKiAgdW5zaWduZWQgaWYgdGhpcyBMb25nIGlzIHVuc2lnbmVkLlxyXG4gKiBAcGFyYW0geyFMb25nfG51bWJlcnxzdHJpbmd9IGRpdmlzb3IgRGl2aXNvclxyXG4gKiBAcmV0dXJucyB7IUxvbmd9IFF1b3RpZW50XHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLmRpdmlkZSA9IGZ1bmN0aW9uIGRpdmlkZShkaXZpc29yKSB7XHJcbiAgICBpZiAoIWlzTG9uZyhkaXZpc29yKSlcclxuICAgICAgICBkaXZpc29yID0gZnJvbVZhbHVlKGRpdmlzb3IpO1xyXG4gICAgaWYgKGRpdmlzb3IuaXNaZXJvKCkpXHJcbiAgICAgICAgdGhyb3cgRXJyb3IoJ2RpdmlzaW9uIGJ5IHplcm8nKTtcclxuXHJcbiAgICAvLyB1c2Ugd2FzbSBzdXBwb3J0IGlmIHByZXNlbnRcclxuICAgIGlmICh3YXNtKSB7XHJcbiAgICAgICAgLy8gZ3VhcmQgYWdhaW5zdCBzaWduZWQgZGl2aXNpb24gb3ZlcmZsb3c6IHRoZSBsYXJnZXN0XHJcbiAgICAgICAgLy8gbmVnYXRpdmUgbnVtYmVyIC8gLTEgd291bGQgYmUgMSBsYXJnZXIgdGhhbiB0aGUgbGFyZ2VzdFxyXG4gICAgICAgIC8vIHBvc2l0aXZlIG51bWJlciwgZHVlIHRvIHR3bydzIGNvbXBsZW1lbnQuXHJcbiAgICAgICAgaWYgKCF0aGlzLnVuc2lnbmVkICYmXHJcbiAgICAgICAgICAgIHRoaXMuaGlnaCA9PT0gLTB4ODAwMDAwMDAgJiZcclxuICAgICAgICAgICAgZGl2aXNvci5sb3cgPT09IC0xICYmIGRpdmlzb3IuaGlnaCA9PT0gLTEpIHtcclxuICAgICAgICAgICAgLy8gYmUgY29uc2lzdGVudCB3aXRoIG5vbi13YXNtIGNvZGUgcGF0aFxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGxvdyA9ICh0aGlzLnVuc2lnbmVkID8gd2FzbS5kaXZfdSA6IHdhc20uZGl2X3MpKFxyXG4gICAgICAgICAgICB0aGlzLmxvdyxcclxuICAgICAgICAgICAgdGhpcy5oaWdoLFxyXG4gICAgICAgICAgICBkaXZpc29yLmxvdyxcclxuICAgICAgICAgICAgZGl2aXNvci5oaWdoXHJcbiAgICAgICAgKTtcclxuICAgICAgICByZXR1cm4gZnJvbUJpdHMobG93LCB3YXNtLmdldF9oaWdoKCksIHRoaXMudW5zaWduZWQpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLmlzWmVybygpKVxyXG4gICAgICAgIHJldHVybiB0aGlzLnVuc2lnbmVkID8gVVpFUk8gOiBaRVJPO1xyXG4gICAgdmFyIGFwcHJveCwgcmVtLCByZXM7XHJcbiAgICBpZiAoIXRoaXMudW5zaWduZWQpIHtcclxuICAgICAgICAvLyBUaGlzIHNlY3Rpb24gaXMgb25seSByZWxldmFudCBmb3Igc2lnbmVkIGxvbmdzIGFuZCBpcyBkZXJpdmVkIGZyb20gdGhlXHJcbiAgICAgICAgLy8gY2xvc3VyZSBsaWJyYXJ5IGFzIGEgd2hvbGUuXHJcbiAgICAgICAgaWYgKHRoaXMuZXEoTUlOX1ZBTFVFKSkge1xyXG4gICAgICAgICAgICBpZiAoZGl2aXNvci5lcShPTkUpIHx8IGRpdmlzb3IuZXEoTkVHX09ORSkpXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gTUlOX1ZBTFVFOyAgLy8gcmVjYWxsIHRoYXQgLU1JTl9WQUxVRSA9PSBNSU5fVkFMVUVcclxuICAgICAgICAgICAgZWxzZSBpZiAoZGl2aXNvci5lcShNSU5fVkFMVUUpKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIE9ORTtcclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAvLyBBdCB0aGlzIHBvaW50LCB3ZSBoYXZlIHxvdGhlcnwgPj0gMiwgc28gfHRoaXMvb3RoZXJ8IDwgfE1JTl9WQUxVRXwuXHJcbiAgICAgICAgICAgICAgICB2YXIgaGFsZlRoaXMgPSB0aGlzLnNocigxKTtcclxuICAgICAgICAgICAgICAgIGFwcHJveCA9IGhhbGZUaGlzLmRpdihkaXZpc29yKS5zaGwoMSk7XHJcbiAgICAgICAgICAgICAgICBpZiAoYXBwcm94LmVxKFpFUk8pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRpdmlzb3IuaXNOZWdhdGl2ZSgpID8gT05FIDogTkVHX09ORTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVtID0gdGhpcy5zdWIoZGl2aXNvci5tdWwoYXBwcm94KSk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVzID0gYXBwcm94LmFkZChyZW0uZGl2KGRpdmlzb3IpKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIGlmIChkaXZpc29yLmVxKE1JTl9WQUxVRSkpXHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnVuc2lnbmVkID8gVVpFUk8gOiBaRVJPO1xyXG4gICAgICAgIGlmICh0aGlzLmlzTmVnYXRpdmUoKSkge1xyXG4gICAgICAgICAgICBpZiAoZGl2aXNvci5pc05lZ2F0aXZlKCkpXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5uZWcoKS5kaXYoZGl2aXNvci5uZWcoKSk7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm5lZygpLmRpdihkaXZpc29yKS5uZWcoKTtcclxuICAgICAgICB9IGVsc2UgaWYgKGRpdmlzb3IuaXNOZWdhdGl2ZSgpKVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5kaXYoZGl2aXNvci5uZWcoKSkubmVnKCk7XHJcbiAgICAgICAgcmVzID0gWkVSTztcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgICAgLy8gVGhlIGFsZ29yaXRobSBiZWxvdyBoYXMgbm90IGJlZW4gbWFkZSBmb3IgdW5zaWduZWQgbG9uZ3MuIEl0J3MgdGhlcmVmb3JlXHJcbiAgICAgICAgLy8gcmVxdWlyZWQgdG8gdGFrZSBzcGVjaWFsIGNhcmUgb2YgdGhlIE1TQiBwcmlvciB0byBydW5uaW5nIGl0LlxyXG4gICAgICAgIGlmICghZGl2aXNvci51bnNpZ25lZClcclxuICAgICAgICAgICAgZGl2aXNvciA9IGRpdmlzb3IudG9VbnNpZ25lZCgpO1xyXG4gICAgICAgIGlmIChkaXZpc29yLmd0KHRoaXMpKVxyXG4gICAgICAgICAgICByZXR1cm4gVVpFUk87XHJcbiAgICAgICAgaWYgKGRpdmlzb3IuZ3QodGhpcy5zaHJ1KDEpKSkgLy8gMTUgPj4+IDEgPSA3IDsgd2l0aCBkaXZpc29yID0gOCA7IHRydWVcclxuICAgICAgICAgICAgcmV0dXJuIFVPTkU7XHJcbiAgICAgICAgcmVzID0gVVpFUk87XHJcbiAgICB9XHJcblxyXG4gICAgLy8gUmVwZWF0IHRoZSBmb2xsb3dpbmcgdW50aWwgdGhlIHJlbWFpbmRlciBpcyBsZXNzIHRoYW4gb3RoZXI6ICBmaW5kIGFcclxuICAgIC8vIGZsb2F0aW5nLXBvaW50IHRoYXQgYXBwcm94aW1hdGVzIHJlbWFpbmRlciAvIG90aGVyICpmcm9tIGJlbG93KiwgYWRkIHRoaXNcclxuICAgIC8vIGludG8gdGhlIHJlc3VsdCwgYW5kIHN1YnRyYWN0IGl0IGZyb20gdGhlIHJlbWFpbmRlci4gIEl0IGlzIGNyaXRpY2FsIHRoYXRcclxuICAgIC8vIHRoZSBhcHByb3hpbWF0ZSB2YWx1ZSBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gdGhlIHJlYWwgdmFsdWUgc28gdGhhdCB0aGVcclxuICAgIC8vIHJlbWFpbmRlciBuZXZlciBiZWNvbWVzIG5lZ2F0aXZlLlxyXG4gICAgcmVtID0gdGhpcztcclxuICAgIHdoaWxlIChyZW0uZ3RlKGRpdmlzb3IpKSB7XHJcbiAgICAgICAgLy8gQXBwcm94aW1hdGUgdGhlIHJlc3VsdCBvZiBkaXZpc2lvbi4gVGhpcyBtYXkgYmUgYSBsaXR0bGUgZ3JlYXRlciBvclxyXG4gICAgICAgIC8vIHNtYWxsZXIgdGhhbiB0aGUgYWN0dWFsIHZhbHVlLlxyXG4gICAgICAgIGFwcHJveCA9IE1hdGgubWF4KDEsIE1hdGguZmxvb3IocmVtLnRvTnVtYmVyKCkgLyBkaXZpc29yLnRvTnVtYmVyKCkpKTtcclxuXHJcbiAgICAgICAgLy8gV2Ugd2lsbCB0d2VhayB0aGUgYXBwcm94aW1hdGUgcmVzdWx0IGJ5IGNoYW5naW5nIGl0IGluIHRoZSA0OC10aCBkaWdpdCBvclxyXG4gICAgICAgIC8vIHRoZSBzbWFsbGVzdCBub24tZnJhY3Rpb25hbCBkaWdpdCwgd2hpY2hldmVyIGlzIGxhcmdlci5cclxuICAgICAgICB2YXIgbG9nMiA9IE1hdGguY2VpbChNYXRoLmxvZyhhcHByb3gpIC8gTWF0aC5MTjIpLFxyXG4gICAgICAgICAgICBkZWx0YSA9IChsb2cyIDw9IDQ4KSA/IDEgOiBwb3dfZGJsKDIsIGxvZzIgLSA0OCksXHJcblxyXG4gICAgICAgIC8vIERlY3JlYXNlIHRoZSBhcHByb3hpbWF0aW9uIHVudGlsIGl0IGlzIHNtYWxsZXIgdGhhbiB0aGUgcmVtYWluZGVyLiAgTm90ZVxyXG4gICAgICAgIC8vIHRoYXQgaWYgaXQgaXMgdG9vIGxhcmdlLCB0aGUgcHJvZHVjdCBvdmVyZmxvd3MgYW5kIGlzIG5lZ2F0aXZlLlxyXG4gICAgICAgICAgICBhcHByb3hSZXMgPSBmcm9tTnVtYmVyKGFwcHJveCksXHJcbiAgICAgICAgICAgIGFwcHJveFJlbSA9IGFwcHJveFJlcy5tdWwoZGl2aXNvcik7XHJcbiAgICAgICAgd2hpbGUgKGFwcHJveFJlbS5pc05lZ2F0aXZlKCkgfHwgYXBwcm94UmVtLmd0KHJlbSkpIHtcclxuICAgICAgICAgICAgYXBwcm94IC09IGRlbHRhO1xyXG4gICAgICAgICAgICBhcHByb3hSZXMgPSBmcm9tTnVtYmVyKGFwcHJveCwgdGhpcy51bnNpZ25lZCk7XHJcbiAgICAgICAgICAgIGFwcHJveFJlbSA9IGFwcHJveFJlcy5tdWwoZGl2aXNvcik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBXZSBrbm93IHRoZSBhbnN3ZXIgY2FuJ3QgYmUgemVyby4uLiBhbmQgYWN0dWFsbHksIHplcm8gd291bGQgY2F1c2VcclxuICAgICAgICAvLyBpbmZpbml0ZSByZWN1cnNpb24gc2luY2Ugd2Ugd291bGQgbWFrZSBubyBwcm9ncmVzcy5cclxuICAgICAgICBpZiAoYXBwcm94UmVzLmlzWmVybygpKVxyXG4gICAgICAgICAgICBhcHByb3hSZXMgPSBPTkU7XHJcblxyXG4gICAgICAgIHJlcyA9IHJlcy5hZGQoYXBwcm94UmVzKTtcclxuICAgICAgICByZW0gPSByZW0uc3ViKGFwcHJveFJlbSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcmVzO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgdGhpcyBMb25nIGRpdmlkZWQgYnkgdGhlIHNwZWNpZmllZC4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNkaXZpZGV9LlxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBkaXZpc29yIERpdmlzb3JcclxuICogQHJldHVybnMgeyFMb25nfSBRdW90aWVudFxyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS5kaXYgPSBMb25nUHJvdG90eXBlLmRpdmlkZTtcclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyBtb2R1bG8gdGhlIHNwZWNpZmllZC5cclxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBkaXZpc29yIERpdmlzb3JcclxuICogQHJldHVybnMgeyFMb25nfSBSZW1haW5kZXJcclxuICovXHJcbkxvbmdQcm90b3R5cGUubW9kdWxvID0gZnVuY3Rpb24gbW9kdWxvKGRpdmlzb3IpIHtcclxuICAgIGlmICghaXNMb25nKGRpdmlzb3IpKVxyXG4gICAgICAgIGRpdmlzb3IgPSBmcm9tVmFsdWUoZGl2aXNvcik7XHJcblxyXG4gICAgLy8gdXNlIHdhc20gc3VwcG9ydCBpZiBwcmVzZW50XHJcbiAgICBpZiAod2FzbSkge1xyXG4gICAgICAgIHZhciBsb3cgPSAodGhpcy51bnNpZ25lZCA/IHdhc20ucmVtX3UgOiB3YXNtLnJlbV9zKShcclxuICAgICAgICAgICAgdGhpcy5sb3csXHJcbiAgICAgICAgICAgIHRoaXMuaGlnaCxcclxuICAgICAgICAgICAgZGl2aXNvci5sb3csXHJcbiAgICAgICAgICAgIGRpdmlzb3IuaGlnaFxyXG4gICAgICAgICk7XHJcbiAgICAgICAgcmV0dXJuIGZyb21CaXRzKGxvdywgd2FzbS5nZXRfaGlnaCgpLCB0aGlzLnVuc2lnbmVkKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gdGhpcy5zdWIodGhpcy5kaXYoZGl2aXNvcikubXVsKGRpdmlzb3IpKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyBtb2R1bG8gdGhlIHNwZWNpZmllZC4gVGhpcyBpcyBhbiBhbGlhcyBvZiB7QGxpbmsgTG9uZyNtb2R1bG99LlxyXG4gKiBAZnVuY3Rpb25cclxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBkaXZpc29yIERpdmlzb3JcclxuICogQHJldHVybnMgeyFMb25nfSBSZW1haW5kZXJcclxuICovXHJcbkxvbmdQcm90b3R5cGUubW9kID0gTG9uZ1Byb3RvdHlwZS5tb2R1bG87XHJcblxyXG4vKipcclxuICogUmV0dXJucyB0aGlzIExvbmcgbW9kdWxvIHRoZSBzcGVjaWZpZWQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjbW9kdWxvfS5cclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gZGl2aXNvciBEaXZpc29yXHJcbiAqIEByZXR1cm5zIHshTG9uZ30gUmVtYWluZGVyXHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLnJlbSA9IExvbmdQcm90b3R5cGUubW9kdWxvO1xyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgdGhlIGJpdHdpc2UgTk9UIG9mIHRoaXMgTG9uZy5cclxuICogQHJldHVybnMgeyFMb25nfVxyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS5ub3QgPSBmdW5jdGlvbiBub3QoKSB7XHJcbiAgICByZXR1cm4gZnJvbUJpdHMofnRoaXMubG93LCB+dGhpcy5oaWdoLCB0aGlzLnVuc2lnbmVkKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIHRoZSBiaXR3aXNlIEFORCBvZiB0aGlzIExvbmcgYW5kIHRoZSBzcGVjaWZpZWQuXHJcbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgTG9uZ1xyXG4gKiBAcmV0dXJucyB7IUxvbmd9XHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLmFuZCA9IGZ1bmN0aW9uIGFuZChvdGhlcikge1xyXG4gICAgaWYgKCFpc0xvbmcob3RoZXIpKVxyXG4gICAgICAgIG90aGVyID0gZnJvbVZhbHVlKG90aGVyKTtcclxuICAgIHJldHVybiBmcm9tQml0cyh0aGlzLmxvdyAmIG90aGVyLmxvdywgdGhpcy5oaWdoICYgb3RoZXIuaGlnaCwgdGhpcy51bnNpZ25lZCk7XHJcbn07XHJcblxyXG4vKipcclxuICogUmV0dXJucyB0aGUgYml0d2lzZSBPUiBvZiB0aGlzIExvbmcgYW5kIHRoZSBzcGVjaWZpZWQuXHJcbiAqIEBwYXJhbSB7IUxvbmd8bnVtYmVyfHN0cmluZ30gb3RoZXIgT3RoZXIgTG9uZ1xyXG4gKiBAcmV0dXJucyB7IUxvbmd9XHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLm9yID0gZnVuY3Rpb24gb3Iob3RoZXIpIHtcclxuICAgIGlmICghaXNMb25nKG90aGVyKSlcclxuICAgICAgICBvdGhlciA9IGZyb21WYWx1ZShvdGhlcik7XHJcbiAgICByZXR1cm4gZnJvbUJpdHModGhpcy5sb3cgfCBvdGhlci5sb3csIHRoaXMuaGlnaCB8IG90aGVyLmhpZ2gsIHRoaXMudW5zaWduZWQpO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgdGhlIGJpdHdpc2UgWE9SIG9mIHRoaXMgTG9uZyBhbmQgdGhlIGdpdmVuIG9uZS5cclxuICogQHBhcmFtIHshTG9uZ3xudW1iZXJ8c3RyaW5nfSBvdGhlciBPdGhlciBMb25nXHJcbiAqIEByZXR1cm5zIHshTG9uZ31cclxuICovXHJcbkxvbmdQcm90b3R5cGUueG9yID0gZnVuY3Rpb24geG9yKG90aGVyKSB7XHJcbiAgICBpZiAoIWlzTG9uZyhvdGhlcikpXHJcbiAgICAgICAgb3RoZXIgPSBmcm9tVmFsdWUob3RoZXIpO1xyXG4gICAgcmV0dXJuIGZyb21CaXRzKHRoaXMubG93IF4gb3RoZXIubG93LCB0aGlzLmhpZ2ggXiBvdGhlci5oaWdoLCB0aGlzLnVuc2lnbmVkKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyB3aXRoIGJpdHMgc2hpZnRlZCB0byB0aGUgbGVmdCBieSB0aGUgZ2l2ZW4gYW1vdW50LlxyXG4gKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gbnVtQml0cyBOdW1iZXIgb2YgYml0c1xyXG4gKiBAcmV0dXJucyB7IUxvbmd9IFNoaWZ0ZWQgTG9uZ1xyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS5zaGlmdExlZnQgPSBmdW5jdGlvbiBzaGlmdExlZnQobnVtQml0cykge1xyXG4gICAgaWYgKGlzTG9uZyhudW1CaXRzKSlcclxuICAgICAgICBudW1CaXRzID0gbnVtQml0cy50b0ludCgpO1xyXG4gICAgaWYgKChudW1CaXRzICY9IDYzKSA9PT0gMClcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIGVsc2UgaWYgKG51bUJpdHMgPCAzMilcclxuICAgICAgICByZXR1cm4gZnJvbUJpdHModGhpcy5sb3cgPDwgbnVtQml0cywgKHRoaXMuaGlnaCA8PCBudW1CaXRzKSB8ICh0aGlzLmxvdyA+Pj4gKDMyIC0gbnVtQml0cykpLCB0aGlzLnVuc2lnbmVkKTtcclxuICAgIGVsc2VcclxuICAgICAgICByZXR1cm4gZnJvbUJpdHMoMCwgdGhpcy5sb3cgPDwgKG51bUJpdHMgLSAzMiksIHRoaXMudW5zaWduZWQpO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgdGhpcyBMb25nIHdpdGggYml0cyBzaGlmdGVkIHRvIHRoZSBsZWZ0IGJ5IHRoZSBnaXZlbiBhbW91bnQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjc2hpZnRMZWZ0fS5cclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSBudW1CaXRzIE51bWJlciBvZiBiaXRzXHJcbiAqIEByZXR1cm5zIHshTG9uZ30gU2hpZnRlZCBMb25nXHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLnNobCA9IExvbmdQcm90b3R5cGUuc2hpZnRMZWZ0O1xyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgdGhpcyBMb25nIHdpdGggYml0cyBhcml0aG1ldGljYWxseSBzaGlmdGVkIHRvIHRoZSByaWdodCBieSB0aGUgZ2l2ZW4gYW1vdW50LlxyXG4gKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gbnVtQml0cyBOdW1iZXIgb2YgYml0c1xyXG4gKiBAcmV0dXJucyB7IUxvbmd9IFNoaWZ0ZWQgTG9uZ1xyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS5zaGlmdFJpZ2h0ID0gZnVuY3Rpb24gc2hpZnRSaWdodChudW1CaXRzKSB7XHJcbiAgICBpZiAoaXNMb25nKG51bUJpdHMpKVxyXG4gICAgICAgIG51bUJpdHMgPSBudW1CaXRzLnRvSW50KCk7XHJcbiAgICBpZiAoKG51bUJpdHMgJj0gNjMpID09PSAwKVxyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgZWxzZSBpZiAobnVtQml0cyA8IDMyKVxyXG4gICAgICAgIHJldHVybiBmcm9tQml0cygodGhpcy5sb3cgPj4+IG51bUJpdHMpIHwgKHRoaXMuaGlnaCA8PCAoMzIgLSBudW1CaXRzKSksIHRoaXMuaGlnaCA+PiBudW1CaXRzLCB0aGlzLnVuc2lnbmVkKTtcclxuICAgIGVsc2VcclxuICAgICAgICByZXR1cm4gZnJvbUJpdHModGhpcy5oaWdoID4+IChudW1CaXRzIC0gMzIpLCB0aGlzLmhpZ2ggPj0gMCA/IDAgOiAtMSwgdGhpcy51bnNpZ25lZCk7XHJcbn07XHJcblxyXG4vKipcclxuICogUmV0dXJucyB0aGlzIExvbmcgd2l0aCBiaXRzIGFyaXRobWV0aWNhbGx5IHNoaWZ0ZWQgdG8gdGhlIHJpZ2h0IGJ5IHRoZSBnaXZlbiBhbW91bnQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjc2hpZnRSaWdodH0uXHJcbiAqIEBmdW5jdGlvblxyXG4gKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gbnVtQml0cyBOdW1iZXIgb2YgYml0c1xyXG4gKiBAcmV0dXJucyB7IUxvbmd9IFNoaWZ0ZWQgTG9uZ1xyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS5zaHIgPSBMb25nUHJvdG90eXBlLnNoaWZ0UmlnaHQ7XHJcblxyXG4vKipcclxuICogUmV0dXJucyB0aGlzIExvbmcgd2l0aCBiaXRzIGxvZ2ljYWxseSBzaGlmdGVkIHRvIHRoZSByaWdodCBieSB0aGUgZ2l2ZW4gYW1vdW50LlxyXG4gKiBAcGFyYW0ge251bWJlcnwhTG9uZ30gbnVtQml0cyBOdW1iZXIgb2YgYml0c1xyXG4gKiBAcmV0dXJucyB7IUxvbmd9IFNoaWZ0ZWQgTG9uZ1xyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS5zaGlmdFJpZ2h0VW5zaWduZWQgPSBmdW5jdGlvbiBzaGlmdFJpZ2h0VW5zaWduZWQobnVtQml0cykge1xyXG4gICAgaWYgKGlzTG9uZyhudW1CaXRzKSlcclxuICAgICAgICBudW1CaXRzID0gbnVtQml0cy50b0ludCgpO1xyXG4gICAgbnVtQml0cyAmPSA2MztcclxuICAgIGlmIChudW1CaXRzID09PSAwKVxyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgZWxzZSB7XHJcbiAgICAgICAgdmFyIGhpZ2ggPSB0aGlzLmhpZ2g7XHJcbiAgICAgICAgaWYgKG51bUJpdHMgPCAzMikge1xyXG4gICAgICAgICAgICB2YXIgbG93ID0gdGhpcy5sb3c7XHJcbiAgICAgICAgICAgIHJldHVybiBmcm9tQml0cygobG93ID4+PiBudW1CaXRzKSB8IChoaWdoIDw8ICgzMiAtIG51bUJpdHMpKSwgaGlnaCA+Pj4gbnVtQml0cywgdGhpcy51bnNpZ25lZCk7XHJcbiAgICAgICAgfSBlbHNlIGlmIChudW1CaXRzID09PSAzMilcclxuICAgICAgICAgICAgcmV0dXJuIGZyb21CaXRzKGhpZ2gsIDAsIHRoaXMudW5zaWduZWQpO1xyXG4gICAgICAgIGVsc2VcclxuICAgICAgICAgICAgcmV0dXJuIGZyb21CaXRzKGhpZ2ggPj4+IChudW1CaXRzIC0gMzIpLCAwLCB0aGlzLnVuc2lnbmVkKTtcclxuICAgIH1cclxufTtcclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyB3aXRoIGJpdHMgbG9naWNhbGx5IHNoaWZ0ZWQgdG8gdGhlIHJpZ2h0IGJ5IHRoZSBnaXZlbiBhbW91bnQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjc2hpZnRSaWdodFVuc2lnbmVkfS5cclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSBudW1CaXRzIE51bWJlciBvZiBiaXRzXHJcbiAqIEByZXR1cm5zIHshTG9uZ30gU2hpZnRlZCBMb25nXHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLnNocnUgPSBMb25nUHJvdG90eXBlLnNoaWZ0UmlnaHRVbnNpZ25lZDtcclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIHRoaXMgTG9uZyB3aXRoIGJpdHMgbG9naWNhbGx5IHNoaWZ0ZWQgdG8gdGhlIHJpZ2h0IGJ5IHRoZSBnaXZlbiBhbW91bnQuIFRoaXMgaXMgYW4gYWxpYXMgb2Yge0BsaW5rIExvbmcjc2hpZnRSaWdodFVuc2lnbmVkfS5cclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7bnVtYmVyfCFMb25nfSBudW1CaXRzIE51bWJlciBvZiBiaXRzXHJcbiAqIEByZXR1cm5zIHshTG9uZ30gU2hpZnRlZCBMb25nXHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLnNocl91ID0gTG9uZ1Byb3RvdHlwZS5zaGlmdFJpZ2h0VW5zaWduZWQ7XHJcblxyXG4vKipcclxuICogQ29udmVydHMgdGhpcyBMb25nIHRvIHNpZ25lZC5cclxuICogQHJldHVybnMgeyFMb25nfSBTaWduZWQgbG9uZ1xyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS50b1NpZ25lZCA9IGZ1bmN0aW9uIHRvU2lnbmVkKCkge1xyXG4gICAgaWYgKCF0aGlzLnVuc2lnbmVkKVxyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgcmV0dXJuIGZyb21CaXRzKHRoaXMubG93LCB0aGlzLmhpZ2gsIGZhbHNlKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBDb252ZXJ0cyB0aGlzIExvbmcgdG8gdW5zaWduZWQuXHJcbiAqIEByZXR1cm5zIHshTG9uZ30gVW5zaWduZWQgbG9uZ1xyXG4gKi9cclxuTG9uZ1Byb3RvdHlwZS50b1Vuc2lnbmVkID0gZnVuY3Rpb24gdG9VbnNpZ25lZCgpIHtcclxuICAgIGlmICh0aGlzLnVuc2lnbmVkKVxyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgcmV0dXJuIGZyb21CaXRzKHRoaXMubG93LCB0aGlzLmhpZ2gsIHRydWUpO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIENvbnZlcnRzIHRoaXMgTG9uZyB0byBpdHMgYnl0ZSByZXByZXNlbnRhdGlvbi5cclxuICogQHBhcmFtIHtib29sZWFuPX0gbGUgV2hldGhlciBsaXR0bGUgb3IgYmlnIGVuZGlhbiwgZGVmYXVsdHMgdG8gYmlnIGVuZGlhblxyXG4gKiBAcmV0dXJucyB7IUFycmF5LjxudW1iZXI+fSBCeXRlIHJlcHJlc2VudGF0aW9uXHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLnRvQnl0ZXMgPSBmdW5jdGlvbiB0b0J5dGVzKGxlKSB7XHJcbiAgICByZXR1cm4gbGUgPyB0aGlzLnRvQnl0ZXNMRSgpIDogdGhpcy50b0J5dGVzQkUoKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBDb252ZXJ0cyB0aGlzIExvbmcgdG8gaXRzIGxpdHRsZSBlbmRpYW4gYnl0ZSByZXByZXNlbnRhdGlvbi5cclxuICogQHJldHVybnMgeyFBcnJheS48bnVtYmVyPn0gTGl0dGxlIGVuZGlhbiBieXRlIHJlcHJlc2VudGF0aW9uXHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLnRvQnl0ZXNMRSA9IGZ1bmN0aW9uIHRvQnl0ZXNMRSgpIHtcclxuICAgIHZhciBoaSA9IHRoaXMuaGlnaCxcclxuICAgICAgICBsbyA9IHRoaXMubG93O1xyXG4gICAgcmV0dXJuIFtcclxuICAgICAgICBsbyAgICAgICAgJiAweGZmLFxyXG4gICAgICAgIGxvID4+PiAgOCAmIDB4ZmYsXHJcbiAgICAgICAgbG8gPj4+IDE2ICYgMHhmZixcclxuICAgICAgICBsbyA+Pj4gMjQgICAgICAgLFxyXG4gICAgICAgIGhpICAgICAgICAmIDB4ZmYsXHJcbiAgICAgICAgaGkgPj4+ICA4ICYgMHhmZixcclxuICAgICAgICBoaSA+Pj4gMTYgJiAweGZmLFxyXG4gICAgICAgIGhpID4+PiAyNFxyXG4gICAgXTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBDb252ZXJ0cyB0aGlzIExvbmcgdG8gaXRzIGJpZyBlbmRpYW4gYnl0ZSByZXByZXNlbnRhdGlvbi5cclxuICogQHJldHVybnMgeyFBcnJheS48bnVtYmVyPn0gQmlnIGVuZGlhbiBieXRlIHJlcHJlc2VudGF0aW9uXHJcbiAqL1xyXG5Mb25nUHJvdG90eXBlLnRvQnl0ZXNCRSA9IGZ1bmN0aW9uIHRvQnl0ZXNCRSgpIHtcclxuICAgIHZhciBoaSA9IHRoaXMuaGlnaCxcclxuICAgICAgICBsbyA9IHRoaXMubG93O1xyXG4gICAgcmV0dXJuIFtcclxuICAgICAgICBoaSA+Pj4gMjQgICAgICAgLFxyXG4gICAgICAgIGhpID4+PiAxNiAmIDB4ZmYsXHJcbiAgICAgICAgaGkgPj4+ICA4ICYgMHhmZixcclxuICAgICAgICBoaSAgICAgICAgJiAweGZmLFxyXG4gICAgICAgIGxvID4+PiAyNCAgICAgICAsXHJcbiAgICAgICAgbG8gPj4+IDE2ICYgMHhmZixcclxuICAgICAgICBsbyA+Pj4gIDggJiAweGZmLFxyXG4gICAgICAgIGxvICAgICAgICAmIDB4ZmZcclxuICAgIF07XHJcbn07XHJcblxyXG4vKipcclxuICogQ3JlYXRlcyBhIExvbmcgZnJvbSBpdHMgYnl0ZSByZXByZXNlbnRhdGlvbi5cclxuICogQHBhcmFtIHshQXJyYXkuPG51bWJlcj59IGJ5dGVzIEJ5dGUgcmVwcmVzZW50YXRpb25cclxuICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIHNpZ25lZFxyXG4gKiBAcGFyYW0ge2Jvb2xlYW49fSBsZSBXaGV0aGVyIGxpdHRsZSBvciBiaWcgZW5kaWFuLCBkZWZhdWx0cyB0byBiaWcgZW5kaWFuXHJcbiAqIEByZXR1cm5zIHtMb25nfSBUaGUgY29ycmVzcG9uZGluZyBMb25nIHZhbHVlXHJcbiAqL1xyXG5Mb25nLmZyb21CeXRlcyA9IGZ1bmN0aW9uIGZyb21CeXRlcyhieXRlcywgdW5zaWduZWQsIGxlKSB7XHJcbiAgICByZXR1cm4gbGUgPyBMb25nLmZyb21CeXRlc0xFKGJ5dGVzLCB1bnNpZ25lZCkgOiBMb25nLmZyb21CeXRlc0JFKGJ5dGVzLCB1bnNpZ25lZCk7XHJcbn07XHJcblxyXG4vKipcclxuICogQ3JlYXRlcyBhIExvbmcgZnJvbSBpdHMgbGl0dGxlIGVuZGlhbiBieXRlIHJlcHJlc2VudGF0aW9uLlxyXG4gKiBAcGFyYW0geyFBcnJheS48bnVtYmVyPn0gYnl0ZXMgTGl0dGxlIGVuZGlhbiBieXRlIHJlcHJlc2VudGF0aW9uXHJcbiAqIEBwYXJhbSB7Ym9vbGVhbj19IHVuc2lnbmVkIFdoZXRoZXIgdW5zaWduZWQgb3Igbm90LCBkZWZhdWx0cyB0byBzaWduZWRcclxuICogQHJldHVybnMge0xvbmd9IFRoZSBjb3JyZXNwb25kaW5nIExvbmcgdmFsdWVcclxuICovXHJcbkxvbmcuZnJvbUJ5dGVzTEUgPSBmdW5jdGlvbiBmcm9tQnl0ZXNMRShieXRlcywgdW5zaWduZWQpIHtcclxuICAgIHJldHVybiBuZXcgTG9uZyhcclxuICAgICAgICBieXRlc1swXSAgICAgICB8XHJcbiAgICAgICAgYnl0ZXNbMV0gPDwgIDggfFxyXG4gICAgICAgIGJ5dGVzWzJdIDw8IDE2IHxcclxuICAgICAgICBieXRlc1szXSA8PCAyNCxcclxuICAgICAgICBieXRlc1s0XSAgICAgICB8XHJcbiAgICAgICAgYnl0ZXNbNV0gPDwgIDggfFxyXG4gICAgICAgIGJ5dGVzWzZdIDw8IDE2IHxcclxuICAgICAgICBieXRlc1s3XSA8PCAyNCxcclxuICAgICAgICB1bnNpZ25lZFxyXG4gICAgKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBDcmVhdGVzIGEgTG9uZyBmcm9tIGl0cyBiaWcgZW5kaWFuIGJ5dGUgcmVwcmVzZW50YXRpb24uXHJcbiAqIEBwYXJhbSB7IUFycmF5LjxudW1iZXI+fSBieXRlcyBCaWcgZW5kaWFuIGJ5dGUgcmVwcmVzZW50YXRpb25cclxuICogQHBhcmFtIHtib29sZWFuPX0gdW5zaWduZWQgV2hldGhlciB1bnNpZ25lZCBvciBub3QsIGRlZmF1bHRzIHRvIHNpZ25lZFxyXG4gKiBAcmV0dXJucyB7TG9uZ30gVGhlIGNvcnJlc3BvbmRpbmcgTG9uZyB2YWx1ZVxyXG4gKi9cclxuTG9uZy5mcm9tQnl0ZXNCRSA9IGZ1bmN0aW9uIGZyb21CeXRlc0JFKGJ5dGVzLCB1bnNpZ25lZCkge1xyXG4gICAgcmV0dXJuIG5ldyBMb25nKFxyXG4gICAgICAgIGJ5dGVzWzRdIDw8IDI0IHxcclxuICAgICAgICBieXRlc1s1XSA8PCAxNiB8XHJcbiAgICAgICAgYnl0ZXNbNl0gPDwgIDggfFxyXG4gICAgICAgIGJ5dGVzWzddLFxyXG4gICAgICAgIGJ5dGVzWzBdIDw8IDI0IHxcclxuICAgICAgICBieXRlc1sxXSA8PCAxNiB8XHJcbiAgICAgICAgYnl0ZXNbMl0gPDwgIDggfFxyXG4gICAgICAgIGJ5dGVzWzNdLFxyXG4gICAgICAgIHVuc2lnbmVkXHJcbiAgICApO1xyXG59O1xyXG4iLCIvKmVzbGludC1kaXNhYmxlIGJsb2NrLXNjb3BlZC12YXIsIGlkLWxlbmd0aCwgbm8tY29udHJvbC1yZWdleCwgbm8tbWFnaWMtbnVtYmVycywgbm8tcHJvdG90eXBlLWJ1aWx0aW5zLCBuby1yZWRlY2xhcmUsIG5vLXNoYWRvdywgbm8tdmFyLCBzb3J0LXZhcnMqL1xuXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciAkcHJvdG9idWYgPSByZXF1aXJlKFwicHJvdG9idWZqcy9taW5pbWFsXCIpO1xuXG4vLyBDb21tb24gYWxpYXNlc1xudmFyICRSZWFkZXIgPSAkcHJvdG9idWYuUmVhZGVyLCAkV3JpdGVyID0gJHByb3RvYnVmLldyaXRlciwgJHV0aWwgPSAkcHJvdG9idWYudXRpbDtcblxuLy8gRXhwb3J0ZWQgcm9vdCBuYW1lc3BhY2VcbnZhciAkcm9vdCA9ICRwcm90b2J1Zi5yb290c1tcImRlZmF1bHRcIl0gfHwgKCRwcm90b2J1Zi5yb290c1tcImRlZmF1bHRcIl0gPSB7fSk7XG5cbiRyb290Lm9ubnggPSAoZnVuY3Rpb24oKSB7XG5cbiAgICAvKipcbiAgICAgKiBOYW1lc3BhY2Ugb25ueC5cbiAgICAgKiBAZXhwb3J0cyBvbm54XG4gICAgICogQG5hbWVzcGFjZVxuICAgICAqL1xuICAgIHZhciBvbm54ID0ge307XG5cbiAgICAvKipcbiAgICAgKiBWZXJzaW9uIGVudW0uXG4gICAgICogQG5hbWUgb25ueC5WZXJzaW9uXG4gICAgICogQGVudW0ge3N0cmluZ31cbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gX1NUQVJUX1ZFUlNJT049MCBfU1RBUlRfVkVSU0lPTiB2YWx1ZVxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBJUl9WRVJTSU9OXzIwMTdfMTBfMTA9MSBJUl9WRVJTSU9OXzIwMTdfMTBfMTAgdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gSVJfVkVSU0lPTl8yMDE3XzEwXzMwPTIgSVJfVkVSU0lPTl8yMDE3XzEwXzMwIHZhbHVlXG4gICAgICogQHByb3BlcnR5IHtudW1iZXJ9IElSX1ZFUlNJT05fMjAxN18xMV8zPTMgSVJfVkVSU0lPTl8yMDE3XzExXzMgdmFsdWVcbiAgICAgKiBAcHJvcGVydHkge251bWJlcn0gSVJfVkVSU0lPTl8yMDE5XzFfMjI9NCBJUl9WRVJTSU9OXzIwMTlfMV8yMiB2YWx1ZVxuICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBJUl9WRVJTSU9OPTUgSVJfVkVSU0lPTiB2YWx1ZVxuICAgICAqL1xuICAgIG9ubnguVmVyc2lvbiA9IChmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIHZhbHVlc0J5SWQgPSB7fSwgdmFsdWVzID0gT2JqZWN0LmNyZWF0ZSh2YWx1ZXNCeUlkKTtcbiAgICAgICAgdmFsdWVzW3ZhbHVlc0J5SWRbMF0gPSBcIl9TVEFSVF9WRVJTSU9OXCJdID0gMDtcbiAgICAgICAgdmFsdWVzW3ZhbHVlc0J5SWRbMV0gPSBcIklSX1ZFUlNJT05fMjAxN18xMF8xMFwiXSA9IDE7XG4gICAgICAgIHZhbHVlc1t2YWx1ZXNCeUlkWzJdID0gXCJJUl9WRVJTSU9OXzIwMTdfMTBfMzBcIl0gPSAyO1xuICAgICAgICB2YWx1ZXNbdmFsdWVzQnlJZFszXSA9IFwiSVJfVkVSU0lPTl8yMDE3XzExXzNcIl0gPSAzO1xuICAgICAgICB2YWx1ZXNbdmFsdWVzQnlJZFs0XSA9IFwiSVJfVkVSU0lPTl8yMDE5XzFfMjJcIl0gPSA0O1xuICAgICAgICB2YWx1ZXNbdmFsdWVzQnlJZFs1XSA9IFwiSVJfVkVSU0lPTlwiXSA9IDU7XG4gICAgICAgIHJldHVybiB2YWx1ZXM7XG4gICAgfSkoKTtcblxuICAgIG9ubnguQXR0cmlidXRlUHJvdG8gPSAoZnVuY3Rpb24oKSB7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFByb3BlcnRpZXMgb2YgYW4gQXR0cmlidXRlUHJvdG8uXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54XG4gICAgICAgICAqIEBpbnRlcmZhY2UgSUF0dHJpYnV0ZVByb3RvXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtuYW1lXSBBdHRyaWJ1dGVQcm90byBuYW1lXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtyZWZBdHRyTmFtZV0gQXR0cmlidXRlUHJvdG8gcmVmQXR0ck5hbWVcbiAgICAgICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW2RvY1N0cmluZ10gQXR0cmlidXRlUHJvdG8gZG9jU3RyaW5nXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7b25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlfG51bGx9IFt0eXBlXSBBdHRyaWJ1dGVQcm90byB0eXBlXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfG51bGx9IFtmXSBBdHRyaWJ1dGVQcm90byBmXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfExvbmd8bnVsbH0gW2ldIEF0dHJpYnV0ZVByb3RvIGlcbiAgICAgICAgICogQHByb3BlcnR5IHtVaW50OEFycmF5fG51bGx9IFtzXSBBdHRyaWJ1dGVQcm90byBzXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7b25ueC5JVGVuc29yUHJvdG98bnVsbH0gW3RdIEF0dHJpYnV0ZVByb3RvIHRcbiAgICAgICAgICogQHByb3BlcnR5IHtvbm54LklHcmFwaFByb3RvfG51bGx9IFtnXSBBdHRyaWJ1dGVQcm90byBnXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG51bWJlcj58bnVsbH0gW2Zsb2F0c10gQXR0cmlidXRlUHJvdG8gZmxvYXRzXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG51bWJlcnxMb25nPnxudWxsfSBbaW50c10gQXR0cmlidXRlUHJvdG8gaW50c1xuICAgICAgICAgKiBAcHJvcGVydHkge0FycmF5LjxVaW50OEFycmF5PnxudWxsfSBbc3RyaW5nc10gQXR0cmlidXRlUHJvdG8gc3RyaW5nc1xuICAgICAgICAgKiBAcHJvcGVydHkge0FycmF5Ljxvbm54LklUZW5zb3JQcm90bz58bnVsbH0gW3RlbnNvcnNdIEF0dHJpYnV0ZVByb3RvIHRlbnNvcnNcbiAgICAgICAgICogQHByb3BlcnR5IHtBcnJheS48b25ueC5JR3JhcGhQcm90bz58bnVsbH0gW2dyYXBoc10gQXR0cmlidXRlUHJvdG8gZ3JhcGhzXG4gICAgICAgICAqL1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IEF0dHJpYnV0ZVByb3RvLlxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAgICAgKiBAY2xhc3NkZXNjIFJlcHJlc2VudHMgYW4gQXR0cmlidXRlUHJvdG8uXG4gICAgICAgICAqIEBpbXBsZW1lbnRzIElBdHRyaWJ1dGVQcm90b1xuICAgICAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgICAgICogQHBhcmFtIHtvbm54LklBdHRyaWJ1dGVQcm90bz19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAgICAgKi9cbiAgICAgICAgZnVuY3Rpb24gQXR0cmlidXRlUHJvdG8ocHJvcGVydGllcykge1xuICAgICAgICAgICAgdGhpcy5mbG9hdHMgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuaW50cyA9IFtdO1xuICAgICAgICAgICAgdGhpcy5zdHJpbmdzID0gW107XG4gICAgICAgICAgICB0aGlzLnRlbnNvcnMgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuZ3JhcGhzID0gW107XG4gICAgICAgICAgICBpZiAocHJvcGVydGllcylcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBrZXlzID0gT2JqZWN0LmtleXMocHJvcGVydGllcyksIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgaWYgKHByb3BlcnRpZXNba2V5c1tpXV0gIT0gbnVsbClcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNba2V5c1tpXV0gPSBwcm9wZXJ0aWVzW2tleXNbaV1dO1xuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEF0dHJpYnV0ZVByb3RvIG5hbWUuXG4gICAgICAgICAqIEBtZW1iZXIge3N0cmluZ30gbmFtZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIEF0dHJpYnV0ZVByb3RvLnByb3RvdHlwZS5uYW1lID0gXCJcIjtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQXR0cmlidXRlUHJvdG8gcmVmQXR0ck5hbWUuXG4gICAgICAgICAqIEBtZW1iZXIge3N0cmluZ30gcmVmQXR0ck5hbWVcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBBdHRyaWJ1dGVQcm90by5wcm90b3R5cGUucmVmQXR0ck5hbWUgPSBcIlwiO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBdHRyaWJ1dGVQcm90byBkb2NTdHJpbmcuXG4gICAgICAgICAqIEBtZW1iZXIge3N0cmluZ30gZG9jU3RyaW5nXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgQXR0cmlidXRlUHJvdG8ucHJvdG90eXBlLmRvY1N0cmluZyA9IFwiXCI7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEF0dHJpYnV0ZVByb3RvIHR5cGUuXG4gICAgICAgICAqIEBtZW1iZXIge29ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZX0gdHlwZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIEF0dHJpYnV0ZVByb3RvLnByb3RvdHlwZS50eXBlID0gMDtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQXR0cmlidXRlUHJvdG8gZi5cbiAgICAgICAgICogQG1lbWJlciB7bnVtYmVyfSBmXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgQXR0cmlidXRlUHJvdG8ucHJvdG90eXBlLmYgPSAwO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBdHRyaWJ1dGVQcm90byBpLlxuICAgICAgICAgKiBAbWVtYmVyIHtudW1iZXJ8TG9uZ30gaVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIEF0dHJpYnV0ZVByb3RvLnByb3RvdHlwZS5pID0gJHV0aWwuTG9uZyA/ICR1dGlsLkxvbmcuZnJvbUJpdHMoMCwwLGZhbHNlKSA6IDA7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEF0dHJpYnV0ZVByb3RvIHMuXG4gICAgICAgICAqIEBtZW1iZXIge1VpbnQ4QXJyYXl9IHNcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBBdHRyaWJ1dGVQcm90by5wcm90b3R5cGUucyA9ICR1dGlsLm5ld0J1ZmZlcihbXSk7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEF0dHJpYnV0ZVByb3RvIHQuXG4gICAgICAgICAqIEBtZW1iZXIge29ubnguSVRlbnNvclByb3RvfG51bGx8dW5kZWZpbmVkfSB0XG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgQXR0cmlidXRlUHJvdG8ucHJvdG90eXBlLnQgPSBudWxsO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBdHRyaWJ1dGVQcm90byBnLlxuICAgICAgICAgKiBAbWVtYmVyIHtvbm54LklHcmFwaFByb3RvfG51bGx8dW5kZWZpbmVkfSBnXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgQXR0cmlidXRlUHJvdG8ucHJvdG90eXBlLmcgPSBudWxsO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBdHRyaWJ1dGVQcm90byBmbG9hdHMuXG4gICAgICAgICAqIEBtZW1iZXIge0FycmF5LjxudW1iZXI+fSBmbG9hdHNcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBBdHRyaWJ1dGVQcm90by5wcm90b3R5cGUuZmxvYXRzID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQXR0cmlidXRlUHJvdG8gaW50cy5cbiAgICAgICAgICogQG1lbWJlciB7QXJyYXkuPG51bWJlcnxMb25nPn0gaW50c1xuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIEF0dHJpYnV0ZVByb3RvLnByb3RvdHlwZS5pbnRzID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQXR0cmlidXRlUHJvdG8gc3RyaW5ncy5cbiAgICAgICAgICogQG1lbWJlciB7QXJyYXkuPFVpbnQ4QXJyYXk+fSBzdHJpbmdzXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgQXR0cmlidXRlUHJvdG8ucHJvdG90eXBlLnN0cmluZ3MgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBdHRyaWJ1dGVQcm90byB0ZW5zb3JzLlxuICAgICAgICAgKiBAbWVtYmVyIHtBcnJheS48b25ueC5JVGVuc29yUHJvdG8+fSB0ZW5zb3JzXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgQXR0cmlidXRlUHJvdG8ucHJvdG90eXBlLnRlbnNvcnMgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBdHRyaWJ1dGVQcm90byBncmFwaHMuXG4gICAgICAgICAqIEBtZW1iZXIge0FycmF5Ljxvbm54LklHcmFwaFByb3RvPn0gZ3JhcGhzXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgQXR0cmlidXRlUHJvdG8ucHJvdG90eXBlLmdyYXBocyA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENyZWF0ZXMgYSBuZXcgQXR0cmlidXRlUHJvdG8gaW5zdGFuY2UgdXNpbmcgdGhlIHNwZWNpZmllZCBwcm9wZXJ0aWVzLlxuICAgICAgICAgKiBAZnVuY3Rpb24gY3JlYXRlXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtvbm54LklBdHRyaWJ1dGVQcm90bz19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5BdHRyaWJ1dGVQcm90b30gQXR0cmlidXRlUHJvdG8gaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIEF0dHJpYnV0ZVByb3RvLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShwcm9wZXJ0aWVzKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IEF0dHJpYnV0ZVByb3RvKHByb3BlcnRpZXMpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgQXR0cmlidXRlUHJvdG8gbWVzc2FnZS4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5BdHRyaWJ1dGVQcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgICAgICogQGZ1bmN0aW9uIGVuY29kZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7b25ueC5JQXR0cmlidXRlUHJvdG99IG1lc3NhZ2UgQXR0cmlidXRlUHJvdG8gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICAgICAqL1xuICAgICAgICBBdHRyaWJ1dGVQcm90by5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICAgICAgICBpZiAoIXdyaXRlcilcbiAgICAgICAgICAgICAgICB3cml0ZXIgPSAkV3JpdGVyLmNyZWF0ZSgpO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UubmFtZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJuYW1lXCIpKVxuICAgICAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMSwgd2lyZVR5cGUgMiA9Ki8xMCkuc3RyaW5nKG1lc3NhZ2UubmFtZSk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5mICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImZcIikpXG4gICAgICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAyLCB3aXJlVHlwZSA1ID0qLzIxKS5mbG9hdChtZXNzYWdlLmYpO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuaSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJpXCIpKVxuICAgICAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMywgd2lyZVR5cGUgMCA9Ki8yNCkuaW50NjQobWVzc2FnZS5pKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnMgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwic1wiKSlcbiAgICAgICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDQsIHdpcmVUeXBlIDIgPSovMzQpLmJ5dGVzKG1lc3NhZ2Uucyk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS50ICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcInRcIikpXG4gICAgICAgICAgICAgICAgJHJvb3Qub25ueC5UZW5zb3JQcm90by5lbmNvZGUobWVzc2FnZS50LCB3cml0ZXIudWludDMyKC8qIGlkIDUsIHdpcmVUeXBlIDIgPSovNDIpLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5nICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImdcIikpXG4gICAgICAgICAgICAgICAgJHJvb3Qub25ueC5HcmFwaFByb3RvLmVuY29kZShtZXNzYWdlLmcsIHdyaXRlci51aW50MzIoLyogaWQgNiwgd2lyZVR5cGUgMiA9Ki81MCkuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmZsb2F0cyAhPSBudWxsICYmIG1lc3NhZ2UuZmxvYXRzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgNywgd2lyZVR5cGUgMiA9Ki81OCkuZm9yaygpO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5mbG9hdHMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgIHdyaXRlci5mbG9hdChtZXNzYWdlLmZsb2F0c1tpXSk7XG4gICAgICAgICAgICAgICAgd3JpdGVyLmxkZWxpbSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuaW50cyAhPSBudWxsICYmIG1lc3NhZ2UuaW50cy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDgsIHdpcmVUeXBlIDIgPSovNjYpLmZvcmsoKTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuaW50cy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgd3JpdGVyLmludDY0KG1lc3NhZ2UuaW50c1tpXSk7XG4gICAgICAgICAgICAgICAgd3JpdGVyLmxkZWxpbSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2Uuc3RyaW5ncyAhPSBudWxsICYmIG1lc3NhZ2Uuc3RyaW5ncy5sZW5ndGgpXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLnN0cmluZ3MubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgOSwgd2lyZVR5cGUgMiA9Ki83NCkuYnl0ZXMobWVzc2FnZS5zdHJpbmdzW2ldKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnRlbnNvcnMgIT0gbnVsbCAmJiBtZXNzYWdlLnRlbnNvcnMubGVuZ3RoKVxuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS50ZW5zb3JzLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICAkcm9vdC5vbm54LlRlbnNvclByb3RvLmVuY29kZShtZXNzYWdlLnRlbnNvcnNbaV0sIHdyaXRlci51aW50MzIoLyogaWQgMTAsIHdpcmVUeXBlIDIgPSovODIpLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5ncmFwaHMgIT0gbnVsbCAmJiBtZXNzYWdlLmdyYXBocy5sZW5ndGgpXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmdyYXBocy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgJHJvb3Qub25ueC5HcmFwaFByb3RvLmVuY29kZShtZXNzYWdlLmdyYXBoc1tpXSwgd3JpdGVyLnVpbnQzMigvKiBpZCAxMSwgd2lyZVR5cGUgMiA9Ki85MCkuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmRvY1N0cmluZyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJkb2NTdHJpbmdcIikpXG4gICAgICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxMywgd2lyZVR5cGUgMiA9Ki8xMDYpLnN0cmluZyhtZXNzYWdlLmRvY1N0cmluZyk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS50eXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcInR5cGVcIikpXG4gICAgICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAyMCwgd2lyZVR5cGUgMCA9Ki8xNjApLmludDMyKG1lc3NhZ2UudHlwZSk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5yZWZBdHRyTmFtZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJyZWZBdHRyTmFtZVwiKSlcbiAgICAgICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDIxLCB3aXJlVHlwZSAyID0qLzE3MCkuc3RyaW5nKG1lc3NhZ2UucmVmQXR0ck5hbWUpO1xuICAgICAgICAgICAgcmV0dXJuIHdyaXRlcjtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIEF0dHJpYnV0ZVByb3RvIG1lc3NhZ2UsIGxlbmd0aCBkZWxpbWl0ZWQuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguQXR0cmlidXRlUHJvdG8udmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICAgICAqIEBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWRcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge29ubnguSUF0dHJpYnV0ZVByb3RvfSBtZXNzYWdlIEF0dHJpYnV0ZVByb3RvIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAgICAgKi9cbiAgICAgICAgQXR0cmlidXRlUHJvdG8uZW5jb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikubGRlbGltKCk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIERlY29kZXMgYW4gQXR0cmlidXRlUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlci5cbiAgICAgICAgICogQGZ1bmN0aW9uIGRlY29kZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5BdHRyaWJ1dGVQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aF0gTWVzc2FnZSBsZW5ndGggaWYga25vd24gYmVmb3JlaGFuZFxuICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5BdHRyaWJ1dGVQcm90b30gQXR0cmlidXRlUHJvdG9cbiAgICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICAgICAqL1xuICAgICAgICBBdHRyaWJ1dGVQcm90by5kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUocmVhZGVyLCBsZW5ndGgpIHtcbiAgICAgICAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKVxuICAgICAgICAgICAgICAgIHJlYWRlciA9ICRSZWFkZXIuY3JlYXRlKHJlYWRlcik7XG4gICAgICAgICAgICB2YXIgZW5kID0gbGVuZ3RoID09PSB1bmRlZmluZWQgPyByZWFkZXIubGVuIDogcmVhZGVyLnBvcyArIGxlbmd0aCwgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LkF0dHJpYnV0ZVByb3RvKCk7XG4gICAgICAgICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZCkge1xuICAgICAgICAgICAgICAgIHZhciB0YWcgPSByZWFkZXIudWludDMyKCk7XG4gICAgICAgICAgICAgICAgc3dpdGNoICh0YWcgPj4+IDMpIHtcbiAgICAgICAgICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UubmFtZSA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAyMTpcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5yZWZBdHRyTmFtZSA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAxMzpcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5kb2NTdHJpbmcgPSByZWFkZXIuc3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgMjA6XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UudHlwZSA9IHJlYWRlci5pbnQzMigpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZiA9IHJlYWRlci5mbG9hdCgpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuaSA9IHJlYWRlci5pbnQ2NCgpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UucyA9IHJlYWRlci5ieXRlcygpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIDU6XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UudCA9ICRyb290Lm9ubnguVGVuc29yUHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSA2OlxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmcgPSAkcm9vdC5vbm54LkdyYXBoUHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSA3OlxuICAgICAgICAgICAgICAgICAgICBpZiAoIShtZXNzYWdlLmZsb2F0cyAmJiBtZXNzYWdlLmZsb2F0cy5sZW5ndGgpKVxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5mbG9hdHMgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCh0YWcgJiA3KSA9PT0gMikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVuZDIgPSByZWFkZXIudWludDMyKCkgKyByZWFkZXIucG9zO1xuICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQyKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZmxvYXRzLnB1c2gocmVhZGVyLmZsb2F0KCkpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZmxvYXRzLnB1c2gocmVhZGVyLmZsb2F0KCkpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIDg6XG4gICAgICAgICAgICAgICAgICAgIGlmICghKG1lc3NhZ2UuaW50cyAmJiBtZXNzYWdlLmludHMubGVuZ3RoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuaW50cyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICBpZiAoKHRhZyAmIDcpID09PSAyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZW5kMiA9IHJlYWRlci51aW50MzIoKSArIHJlYWRlci5wb3M7XG4gICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZDIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5pbnRzLnB1c2gocmVhZGVyLmludDY0KCkpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuaW50cy5wdXNoKHJlYWRlci5pbnQ2NCgpKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSA5OlxuICAgICAgICAgICAgICAgICAgICBpZiAoIShtZXNzYWdlLnN0cmluZ3MgJiYgbWVzc2FnZS5zdHJpbmdzLmxlbmd0aCkpXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnN0cmluZ3MgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5zdHJpbmdzLnB1c2gocmVhZGVyLmJ5dGVzKCkpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIDEwOlxuICAgICAgICAgICAgICAgICAgICBpZiAoIShtZXNzYWdlLnRlbnNvcnMgJiYgbWVzc2FnZS50ZW5zb3JzLmxlbmd0aCkpXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnRlbnNvcnMgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS50ZW5zb3JzLnB1c2goJHJvb3Qub25ueC5UZW5zb3JQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAxMTpcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5ncmFwaHMgJiYgbWVzc2FnZS5ncmFwaHMubGVuZ3RoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZ3JhcGhzID0gW107XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZ3JhcGhzLnB1c2goJHJvb3Qub25ueC5HcmFwaFByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSkpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICByZWFkZXIuc2tpcFR5cGUodGFnICYgNyk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEZWNvZGVzIGFuIEF0dHJpYnV0ZVByb3RvIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIsIGxlbmd0aCBkZWxpbWl0ZWQuXG4gICAgICAgICAqIEBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWRcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgICAgICogQHJldHVybnMge29ubnguQXR0cmlidXRlUHJvdG99IEF0dHJpYnV0ZVByb3RvXG4gICAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAgICAgKi9cbiAgICAgICAgQXR0cmlidXRlUHJvdG8uZGVjb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkKHJlYWRlcikge1xuICAgICAgICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpXG4gICAgICAgICAgICAgICAgcmVhZGVyID0gbmV3ICRSZWFkZXIocmVhZGVyKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFZlcmlmaWVzIGFuIEF0dHJpYnV0ZVByb3RvIG1lc3NhZ2UuXG4gICAgICAgICAqIEBmdW5jdGlvbiB2ZXJpZnlcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBtZXNzYWdlIFBsYWluIG9iamVjdCB0byB2ZXJpZnlcbiAgICAgICAgICogQHJldHVybnMge3N0cmluZ3xudWxsfSBgbnVsbGAgaWYgdmFsaWQsIG90aGVyd2lzZSB0aGUgcmVhc29uIHdoeSBpdCBpcyBub3RcbiAgICAgICAgICovXG4gICAgICAgIEF0dHJpYnV0ZVByb3RvLnZlcmlmeSA9IGZ1bmN0aW9uIHZlcmlmeShtZXNzYWdlKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UgIT09IFwib2JqZWN0XCIgfHwgbWVzc2FnZSA9PT0gbnVsbClcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJvYmplY3QgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLm5hbWUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwibmFtZVwiKSlcbiAgICAgICAgICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UubmFtZSkpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm5hbWU6IHN0cmluZyBleHBlY3RlZFwiO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UucmVmQXR0ck5hbWUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwicmVmQXR0ck5hbWVcIikpXG4gICAgICAgICAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLnJlZkF0dHJOYW1lKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwicmVmQXR0ck5hbWU6IHN0cmluZyBleHBlY3RlZFwiO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZG9jU3RyaW5nICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImRvY1N0cmluZ1wiKSlcbiAgICAgICAgICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UuZG9jU3RyaW5nKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiZG9jU3RyaW5nOiBzdHJpbmcgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwidHlwZVwiKSlcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKG1lc3NhZ2UudHlwZSkge1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcInR5cGU6IGVudW0gdmFsdWUgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgY2FzZSAxOlxuICAgICAgICAgICAgICAgIGNhc2UgMjpcbiAgICAgICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgICAgY2FzZSA0OlxuICAgICAgICAgICAgICAgIGNhc2UgNTpcbiAgICAgICAgICAgICAgICBjYXNlIDY6XG4gICAgICAgICAgICAgICAgY2FzZSA3OlxuICAgICAgICAgICAgICAgIGNhc2UgODpcbiAgICAgICAgICAgICAgICBjYXNlIDk6XG4gICAgICAgICAgICAgICAgY2FzZSAxMDpcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJmXCIpKVxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZS5mICE9PSBcIm51bWJlclwiKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJmOiBudW1iZXIgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmkgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiaVwiKSlcbiAgICAgICAgICAgICAgICBpZiAoISR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmkpICYmICEobWVzc2FnZS5pICYmICR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmkubG93KSAmJiAkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5pLmhpZ2gpKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiaTogaW50ZWdlcnxMb25nIGV4cGVjdGVkXCI7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5zICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcInNcIikpXG4gICAgICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5zICYmIHR5cGVvZiBtZXNzYWdlLnMubGVuZ3RoID09PSBcIm51bWJlclwiIHx8ICR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UucykpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJzOiBidWZmZXIgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnQgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwidFwiKSkge1xuICAgICAgICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguVGVuc29yUHJvdG8udmVyaWZ5KG1lc3NhZ2UudCk7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJ0LlwiICsgZXJyb3I7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5nICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImdcIikpIHtcbiAgICAgICAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LkdyYXBoUHJvdG8udmVyaWZ5KG1lc3NhZ2UuZyk7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJnLlwiICsgZXJyb3I7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5mbG9hdHMgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiZmxvYXRzXCIpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2UuZmxvYXRzKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiZmxvYXRzOiBhcnJheSBleHBlY3RlZFwiO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5mbG9hdHMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZS5mbG9hdHNbaV0gIT09IFwibnVtYmVyXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJmbG9hdHM6IG51bWJlcltdIGV4cGVjdGVkXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5pbnRzICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImludHNcIikpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5pbnRzKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiaW50czogYXJyYXkgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuaW50cy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5pbnRzW2ldKSAmJiAhKG1lc3NhZ2UuaW50c1tpXSAmJiAkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5pbnRzW2ldLmxvdykgJiYgJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuaW50c1tpXS5oaWdoKSkpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJpbnRzOiBpbnRlZ2VyfExvbmdbXSBleHBlY3RlZFwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2Uuc3RyaW5ncyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJzdHJpbmdzXCIpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2Uuc3RyaW5ncykpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcInN0cmluZ3M6IGFycmF5IGV4cGVjdGVkXCI7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLnN0cmluZ3MubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgIGlmICghKG1lc3NhZ2Uuc3RyaW5nc1tpXSAmJiB0eXBlb2YgbWVzc2FnZS5zdHJpbmdzW2ldLmxlbmd0aCA9PT0gXCJudW1iZXJcIiB8fCAkdXRpbC5pc1N0cmluZyhtZXNzYWdlLnN0cmluZ3NbaV0pKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcInN0cmluZ3M6IGJ1ZmZlcltdIGV4cGVjdGVkXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS50ZW5zb3JzICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcInRlbnNvcnNcIikpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS50ZW5zb3JzKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwidGVuc29yczogYXJyYXkgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UudGVuc29ycy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlRlbnNvclByb3RvLnZlcmlmeShtZXNzYWdlLnRlbnNvcnNbaV0pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJ0ZW5zb3JzLlwiICsgZXJyb3I7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZ3JhcGhzICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImdyYXBoc1wiKSkge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLmdyYXBocykpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcImdyYXBoczogYXJyYXkgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuZ3JhcGhzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguR3JhcGhQcm90by52ZXJpZnkobWVzc2FnZS5ncmFwaHNbaV0pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJncmFwaHMuXCIgKyBlcnJvcjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ3JlYXRlcyBhbiBBdHRyaWJ1dGVQcm90byBtZXNzYWdlIGZyb20gYSBwbGFpbiBvYmplY3QuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIHRoZWlyIHJlc3BlY3RpdmUgaW50ZXJuYWwgdHlwZXMuXG4gICAgICAgICAqIEBmdW5jdGlvbiBmcm9tT2JqZWN0XG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gb2JqZWN0IFBsYWluIG9iamVjdFxuICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5BdHRyaWJ1dGVQcm90b30gQXR0cmlidXRlUHJvdG9cbiAgICAgICAgICovXG4gICAgICAgIEF0dHJpYnV0ZVByb3RvLmZyb21PYmplY3QgPSBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mICRyb290Lm9ubnguQXR0cmlidXRlUHJvdG8pXG4gICAgICAgICAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgICAgICAgIHZhciBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguQXR0cmlidXRlUHJvdG8oKTtcbiAgICAgICAgICAgIGlmIChvYmplY3QubmFtZSAhPSBudWxsKVxuICAgICAgICAgICAgICAgIG1lc3NhZ2UubmFtZSA9IFN0cmluZyhvYmplY3QubmFtZSk7XG4gICAgICAgICAgICBpZiAob2JqZWN0LnJlZkF0dHJOYW1lICE9IG51bGwpXG4gICAgICAgICAgICAgICAgbWVzc2FnZS5yZWZBdHRyTmFtZSA9IFN0cmluZyhvYmplY3QucmVmQXR0ck5hbWUpO1xuICAgICAgICAgICAgaWYgKG9iamVjdC5kb2NTdHJpbmcgIT0gbnVsbClcbiAgICAgICAgICAgICAgICBtZXNzYWdlLmRvY1N0cmluZyA9IFN0cmluZyhvYmplY3QuZG9jU3RyaW5nKTtcbiAgICAgICAgICAgIHN3aXRjaCAob2JqZWN0LnR5cGUpIHtcbiAgICAgICAgICAgIGNhc2UgXCJVTkRFRklORURcIjpcbiAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBtZXNzYWdlLnR5cGUgPSAwO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcIkZMT0FUXCI6XG4gICAgICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgICAgICAgbWVzc2FnZS50eXBlID0gMTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJJTlRcIjpcbiAgICAgICAgICAgIGNhc2UgMjpcbiAgICAgICAgICAgICAgICBtZXNzYWdlLnR5cGUgPSAyO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcIlNUUklOR1wiOlxuICAgICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgICAgIG1lc3NhZ2UudHlwZSA9IDM7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFwiVEVOU09SXCI6XG4gICAgICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgICAgICAgbWVzc2FnZS50eXBlID0gNDtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJHUkFQSFwiOlxuICAgICAgICAgICAgY2FzZSA1OlxuICAgICAgICAgICAgICAgIG1lc3NhZ2UudHlwZSA9IDU7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFwiRkxPQVRTXCI6XG4gICAgICAgICAgICBjYXNlIDY6XG4gICAgICAgICAgICAgICAgbWVzc2FnZS50eXBlID0gNjtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJJTlRTXCI6XG4gICAgICAgICAgICBjYXNlIDc6XG4gICAgICAgICAgICAgICAgbWVzc2FnZS50eXBlID0gNztcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJTVFJJTkdTXCI6XG4gICAgICAgICAgICBjYXNlIDg6XG4gICAgICAgICAgICAgICAgbWVzc2FnZS50eXBlID0gODtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJURU5TT1JTXCI6XG4gICAgICAgICAgICBjYXNlIDk6XG4gICAgICAgICAgICAgICAgbWVzc2FnZS50eXBlID0gOTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJHUkFQSFNcIjpcbiAgICAgICAgICAgIGNhc2UgMTA6XG4gICAgICAgICAgICAgICAgbWVzc2FnZS50eXBlID0gMTA7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob2JqZWN0LmYgIT0gbnVsbClcbiAgICAgICAgICAgICAgICBtZXNzYWdlLmYgPSBOdW1iZXIob2JqZWN0LmYpO1xuICAgICAgICAgICAgaWYgKG9iamVjdC5pICE9IG51bGwpXG4gICAgICAgICAgICAgICAgaWYgKCR1dGlsLkxvbmcpXG4gICAgICAgICAgICAgICAgICAgIChtZXNzYWdlLmkgPSAkdXRpbC5Mb25nLmZyb21WYWx1ZShvYmplY3QuaSkpLnVuc2lnbmVkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5pID09PSBcInN0cmluZ1wiKVxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmkgPSBwYXJzZUludChvYmplY3QuaSwgMTApO1xuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuaSA9PT0gXCJudW1iZXJcIilcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5pID0gb2JqZWN0Lmk7XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5pID09PSBcIm9iamVjdFwiKVxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmkgPSBuZXcgJHV0aWwuTG9uZ0JpdHMob2JqZWN0LmkubG93ID4+PiAwLCBvYmplY3QuaS5oaWdoID4+PiAwKS50b051bWJlcigpO1xuICAgICAgICAgICAgaWYgKG9iamVjdC5zICE9IG51bGwpXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QucyA9PT0gXCJzdHJpbmdcIilcbiAgICAgICAgICAgICAgICAgICAgJHV0aWwuYmFzZTY0LmRlY29kZShvYmplY3QucywgbWVzc2FnZS5zID0gJHV0aWwubmV3QnVmZmVyKCR1dGlsLmJhc2U2NC5sZW5ndGgob2JqZWN0LnMpKSwgMCk7XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAob2JqZWN0LnMubGVuZ3RoKVxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnMgPSBvYmplY3QucztcbiAgICAgICAgICAgIGlmIChvYmplY3QudCAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QudCAhPT0gXCJvYmplY3RcIilcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguQXR0cmlidXRlUHJvdG8udDogb2JqZWN0IGV4cGVjdGVkXCIpO1xuICAgICAgICAgICAgICAgIG1lc3NhZ2UudCA9ICRyb290Lm9ubnguVGVuc29yUHJvdG8uZnJvbU9iamVjdChvYmplY3QudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob2JqZWN0LmcgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LmcgIT09IFwib2JqZWN0XCIpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIi5vbm54LkF0dHJpYnV0ZVByb3RvLmc6IG9iamVjdCBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICBtZXNzYWdlLmcgPSAkcm9vdC5vbm54LkdyYXBoUHJvdG8uZnJvbU9iamVjdChvYmplY3QuZyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob2JqZWN0LmZsb2F0cykge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QuZmxvYXRzKSlcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguQXR0cmlidXRlUHJvdG8uZmxvYXRzOiBhcnJheSBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICBtZXNzYWdlLmZsb2F0cyA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0LmZsb2F0cy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5mbG9hdHNbaV0gPSBOdW1iZXIob2JqZWN0LmZsb2F0c1tpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob2JqZWN0LmludHMpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LmludHMpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5BdHRyaWJ1dGVQcm90by5pbnRzOiBhcnJheSBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICBtZXNzYWdlLmludHMgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5pbnRzLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICBpZiAoJHV0aWwuTG9uZylcbiAgICAgICAgICAgICAgICAgICAgICAgIChtZXNzYWdlLmludHNbaV0gPSAkdXRpbC5Mb25nLmZyb21WYWx1ZShvYmplY3QuaW50c1tpXSkpLnVuc2lnbmVkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuaW50c1tpXSA9PT0gXCJzdHJpbmdcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuaW50c1tpXSA9IHBhcnNlSW50KG9iamVjdC5pbnRzW2ldLCAxMCk7XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuaW50c1tpXSA9PT0gXCJudW1iZXJcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuaW50c1tpXSA9IG9iamVjdC5pbnRzW2ldO1xuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LmludHNbaV0gPT09IFwib2JqZWN0XCIpXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmludHNbaV0gPSBuZXcgJHV0aWwuTG9uZ0JpdHMob2JqZWN0LmludHNbaV0ubG93ID4+PiAwLCBvYmplY3QuaW50c1tpXS5oaWdoID4+PiAwKS50b051bWJlcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG9iamVjdC5zdHJpbmdzKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5zdHJpbmdzKSlcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguQXR0cmlidXRlUHJvdG8uc3RyaW5nczogYXJyYXkgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgbWVzc2FnZS5zdHJpbmdzID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3Quc3RyaW5ncy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3Quc3RyaW5nc1tpXSA9PT0gXCJzdHJpbmdcIilcbiAgICAgICAgICAgICAgICAgICAgICAgICR1dGlsLmJhc2U2NC5kZWNvZGUob2JqZWN0LnN0cmluZ3NbaV0sIG1lc3NhZ2Uuc3RyaW5nc1tpXSA9ICR1dGlsLm5ld0J1ZmZlcigkdXRpbC5iYXNlNjQubGVuZ3RoKG9iamVjdC5zdHJpbmdzW2ldKSksIDApO1xuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChvYmplY3Quc3RyaW5nc1tpXS5sZW5ndGgpXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnN0cmluZ3NbaV0gPSBvYmplY3Quc3RyaW5nc1tpXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChvYmplY3QudGVuc29ycykge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QudGVuc29ycykpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIi5vbm54LkF0dHJpYnV0ZVByb3RvLnRlbnNvcnM6IGFycmF5IGV4cGVjdGVkXCIpO1xuICAgICAgICAgICAgICAgIG1lc3NhZ2UudGVuc29ycyA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0LnRlbnNvcnMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QudGVuc29yc1tpXSAhPT0gXCJvYmplY3RcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIi5vbm54LkF0dHJpYnV0ZVByb3RvLnRlbnNvcnM6IG9iamVjdCBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS50ZW5zb3JzW2ldID0gJHJvb3Qub25ueC5UZW5zb3JQcm90by5mcm9tT2JqZWN0KG9iamVjdC50ZW5zb3JzW2ldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob2JqZWN0LmdyYXBocykge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QuZ3JhcGhzKSlcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguQXR0cmlidXRlUHJvdG8uZ3JhcGhzOiBhcnJheSBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICBtZXNzYWdlLmdyYXBocyA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0LmdyYXBocy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5ncmFwaHNbaV0gIT09IFwib2JqZWN0XCIpXG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5BdHRyaWJ1dGVQcm90by5ncmFwaHM6IG9iamVjdCBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5ncmFwaHNbaV0gPSAkcm9vdC5vbm54LkdyYXBoUHJvdG8uZnJvbU9iamVjdChvYmplY3QuZ3JhcGhzW2ldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ3JlYXRlcyBhIHBsYWluIG9iamVjdCBmcm9tIGFuIEF0dHJpYnV0ZVByb3RvIG1lc3NhZ2UuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIG90aGVyIHR5cGVzIGlmIHNwZWNpZmllZC5cbiAgICAgICAgICogQGZ1bmN0aW9uIHRvT2JqZWN0XG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LkF0dHJpYnV0ZVByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtvbm54LkF0dHJpYnV0ZVByb3RvfSBtZXNzYWdlIEF0dHJpYnV0ZVByb3RvXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLklDb252ZXJzaW9uT3B0aW9uc30gW29wdGlvbnNdIENvbnZlcnNpb24gb3B0aW9uc1xuICAgICAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IFBsYWluIG9iamVjdFxuICAgICAgICAgKi9cbiAgICAgICAgQXR0cmlidXRlUHJvdG8udG9PYmplY3QgPSBmdW5jdGlvbiB0b09iamVjdChtZXNzYWdlLCBvcHRpb25zKSB7XG4gICAgICAgICAgICBpZiAoIW9wdGlvbnMpXG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IHt9O1xuICAgICAgICAgICAgdmFyIG9iamVjdCA9IHt9O1xuICAgICAgICAgICAgaWYgKG9wdGlvbnMuYXJyYXlzIHx8IG9wdGlvbnMuZGVmYXVsdHMpIHtcbiAgICAgICAgICAgICAgICBvYmplY3QuZmxvYXRzID0gW107XG4gICAgICAgICAgICAgICAgb2JqZWN0LmludHMgPSBbXTtcbiAgICAgICAgICAgICAgICBvYmplY3Quc3RyaW5ncyA9IFtdO1xuICAgICAgICAgICAgICAgIG9iamVjdC50ZW5zb3JzID0gW107XG4gICAgICAgICAgICAgICAgb2JqZWN0LmdyYXBocyA9IFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG9wdGlvbnMuZGVmYXVsdHMpIHtcbiAgICAgICAgICAgICAgICBvYmplY3QubmFtZSA9IFwiXCI7XG4gICAgICAgICAgICAgICAgb2JqZWN0LmYgPSAwO1xuICAgICAgICAgICAgICAgIGlmICgkdXRpbC5Mb25nKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBsb25nID0gbmV3ICR1dGlsLkxvbmcoMCwgMCwgZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICBvYmplY3QuaSA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/IGxvbmcudG9TdHJpbmcoKSA6IG9wdGlvbnMubG9uZ3MgPT09IE51bWJlciA/IGxvbmcudG9OdW1iZXIoKSA6IGxvbmc7XG4gICAgICAgICAgICAgICAgfSBlbHNlXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC5pID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gXCIwXCIgOiAwO1xuICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLmJ5dGVzID09PSBTdHJpbmcpXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC5zID0gXCJcIjtcbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LnMgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuYnl0ZXMgIT09IEFycmF5KVxuICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LnMgPSAkdXRpbC5uZXdCdWZmZXIob2JqZWN0LnMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBvYmplY3QudCA9IG51bGw7XG4gICAgICAgICAgICAgICAgb2JqZWN0LmcgPSBudWxsO1xuICAgICAgICAgICAgICAgIG9iamVjdC5kb2NTdHJpbmcgPSBcIlwiO1xuICAgICAgICAgICAgICAgIG9iamVjdC50eXBlID0gb3B0aW9ucy5lbnVtcyA9PT0gU3RyaW5nID8gXCJVTkRFRklORURcIiA6IDA7XG4gICAgICAgICAgICAgICAgb2JqZWN0LnJlZkF0dHJOYW1lID0gXCJcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLm5hbWUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwibmFtZVwiKSlcbiAgICAgICAgICAgICAgICBvYmplY3QubmFtZSA9IG1lc3NhZ2UubmFtZTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmYgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiZlwiKSlcbiAgICAgICAgICAgICAgICBvYmplY3QuZiA9IG9wdGlvbnMuanNvbiAmJiAhaXNGaW5pdGUobWVzc2FnZS5mKSA/IFN0cmluZyhtZXNzYWdlLmYpIDogbWVzc2FnZS5mO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuaSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJpXCIpKVxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZS5pID09PSBcIm51bWJlclwiKVxuICAgICAgICAgICAgICAgICAgICBvYmplY3QuaSA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/IFN0cmluZyhtZXNzYWdlLmkpIDogbWVzc2FnZS5pO1xuICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LmkgPSBvcHRpb25zLmxvbmdzID09PSBTdHJpbmcgPyAkdXRpbC5Mb25nLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG1lc3NhZ2UuaSkgOiBvcHRpb25zLmxvbmdzID09PSBOdW1iZXIgPyBuZXcgJHV0aWwuTG9uZ0JpdHMobWVzc2FnZS5pLmxvdyA+Pj4gMCwgbWVzc2FnZS5pLmhpZ2ggPj4+IDApLnRvTnVtYmVyKCkgOiBtZXNzYWdlLmk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5zICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcInNcIikpXG4gICAgICAgICAgICAgICAgb2JqZWN0LnMgPSBvcHRpb25zLmJ5dGVzID09PSBTdHJpbmcgPyAkdXRpbC5iYXNlNjQuZW5jb2RlKG1lc3NhZ2UucywgMCwgbWVzc2FnZS5zLmxlbmd0aCkgOiBvcHRpb25zLmJ5dGVzID09PSBBcnJheSA/IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKG1lc3NhZ2UucykgOiBtZXNzYWdlLnM7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS50ICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcInRcIikpXG4gICAgICAgICAgICAgICAgb2JqZWN0LnQgPSAkcm9vdC5vbm54LlRlbnNvclByb3RvLnRvT2JqZWN0KG1lc3NhZ2UudCwgb3B0aW9ucyk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5nICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImdcIikpXG4gICAgICAgICAgICAgICAgb2JqZWN0LmcgPSAkcm9vdC5vbm54LkdyYXBoUHJvdG8udG9PYmplY3QobWVzc2FnZS5nLCBvcHRpb25zKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmZsb2F0cyAmJiBtZXNzYWdlLmZsb2F0cy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBvYmplY3QuZmxvYXRzID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLmZsb2F0cy5sZW5ndGg7ICsrailcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LmZsb2F0c1tqXSA9IG9wdGlvbnMuanNvbiAmJiAhaXNGaW5pdGUobWVzc2FnZS5mbG9hdHNbal0pID8gU3RyaW5nKG1lc3NhZ2UuZmxvYXRzW2pdKSA6IG1lc3NhZ2UuZmxvYXRzW2pdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuaW50cyAmJiBtZXNzYWdlLmludHMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgb2JqZWN0LmludHMgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UuaW50cy5sZW5ndGg7ICsrailcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlLmludHNbal0gPT09IFwibnVtYmVyXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QuaW50c1tqXSA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/IFN0cmluZyhtZXNzYWdlLmludHNbal0pIDogbWVzc2FnZS5pbnRzW2pdO1xuICAgICAgICAgICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QuaW50c1tqXSA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/ICR1dGlsLkxvbmcucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobWVzc2FnZS5pbnRzW2pdKSA6IG9wdGlvbnMubG9uZ3MgPT09IE51bWJlciA/IG5ldyAkdXRpbC5Mb25nQml0cyhtZXNzYWdlLmludHNbal0ubG93ID4+PiAwLCBtZXNzYWdlLmludHNbal0uaGlnaCA+Pj4gMCkudG9OdW1iZXIoKSA6IG1lc3NhZ2UuaW50c1tqXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnN0cmluZ3MgJiYgbWVzc2FnZS5zdHJpbmdzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIG9iamVjdC5zdHJpbmdzID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLnN0cmluZ3MubGVuZ3RoOyArK2opXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC5zdHJpbmdzW2pdID0gb3B0aW9ucy5ieXRlcyA9PT0gU3RyaW5nID8gJHV0aWwuYmFzZTY0LmVuY29kZShtZXNzYWdlLnN0cmluZ3Nbal0sIDAsIG1lc3NhZ2Uuc3RyaW5nc1tqXS5sZW5ndGgpIDogb3B0aW9ucy5ieXRlcyA9PT0gQXJyYXkgPyBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChtZXNzYWdlLnN0cmluZ3Nbal0pIDogbWVzc2FnZS5zdHJpbmdzW2pdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UudGVuc29ycyAmJiBtZXNzYWdlLnRlbnNvcnMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgb2JqZWN0LnRlbnNvcnMgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UudGVuc29ycy5sZW5ndGg7ICsrailcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LnRlbnNvcnNbal0gPSAkcm9vdC5vbm54LlRlbnNvclByb3RvLnRvT2JqZWN0KG1lc3NhZ2UudGVuc29yc1tqXSwgb3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5ncmFwaHMgJiYgbWVzc2FnZS5ncmFwaHMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgb2JqZWN0LmdyYXBocyA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5ncmFwaHMubGVuZ3RoOyArK2opXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC5ncmFwaHNbal0gPSAkcm9vdC5vbm54LkdyYXBoUHJvdG8udG9PYmplY3QobWVzc2FnZS5ncmFwaHNbal0sIG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZG9jU3RyaW5nICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImRvY1N0cmluZ1wiKSlcbiAgICAgICAgICAgICAgICBvYmplY3QuZG9jU3RyaW5nID0gbWVzc2FnZS5kb2NTdHJpbmc7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS50eXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcInR5cGVcIikpXG4gICAgICAgICAgICAgICAgb2JqZWN0LnR5cGUgPSBvcHRpb25zLmVudW1zID09PSBTdHJpbmcgPyAkcm9vdC5vbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGVbbWVzc2FnZS50eXBlXSA6IG1lc3NhZ2UudHlwZTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnJlZkF0dHJOYW1lICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcInJlZkF0dHJOYW1lXCIpKVxuICAgICAgICAgICAgICAgIG9iamVjdC5yZWZBdHRyTmFtZSA9IG1lc3NhZ2UucmVmQXR0ck5hbWU7XG4gICAgICAgICAgICByZXR1cm4gb2JqZWN0O1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDb252ZXJ0cyB0aGlzIEF0dHJpYnV0ZVByb3RvIHRvIEpTT04uXG4gICAgICAgICAqIEBmdW5jdGlvbiB0b0pTT05cbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguQXR0cmlidXRlUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gSlNPTiBvYmplY3RcbiAgICAgICAgICovXG4gICAgICAgIEF0dHJpYnV0ZVByb3RvLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04oKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci50b09iamVjdCh0aGlzLCAkcHJvdG9idWYudXRpbC50b0pTT05PcHRpb25zKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQXR0cmlidXRlVHlwZSBlbnVtLlxuICAgICAgICAgKiBAbmFtZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGVcbiAgICAgICAgICogQGVudW0ge3N0cmluZ31cbiAgICAgICAgICogQHByb3BlcnR5IHtudW1iZXJ9IFVOREVGSU5FRD0wIFVOREVGSU5FRCB2YWx1ZVxuICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gRkxPQVQ9MSBGTE9BVCB2YWx1ZVxuICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gSU5UPTIgSU5UIHZhbHVlXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBTVFJJTkc9MyBTVFJJTkcgdmFsdWVcbiAgICAgICAgICogQHByb3BlcnR5IHtudW1iZXJ9IFRFTlNPUj00IFRFTlNPUiB2YWx1ZVxuICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gR1JBUEg9NSBHUkFQSCB2YWx1ZVxuICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gRkxPQVRTPTYgRkxPQVRTIHZhbHVlXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBJTlRTPTcgSU5UUyB2YWx1ZVxuICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gU1RSSU5HUz04IFNUUklOR1MgdmFsdWVcbiAgICAgICAgICogQHByb3BlcnR5IHtudW1iZXJ9IFRFTlNPUlM9OSBURU5TT1JTIHZhbHVlXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBHUkFQSFM9MTAgR1JBUEhTIHZhbHVlXG4gICAgICAgICAqL1xuICAgICAgICBBdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlID0gKGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgdmFyIHZhbHVlc0J5SWQgPSB7fSwgdmFsdWVzID0gT2JqZWN0LmNyZWF0ZSh2YWx1ZXNCeUlkKTtcbiAgICAgICAgICAgIHZhbHVlc1t2YWx1ZXNCeUlkWzBdID0gXCJVTkRFRklORURcIl0gPSAwO1xuICAgICAgICAgICAgdmFsdWVzW3ZhbHVlc0J5SWRbMV0gPSBcIkZMT0FUXCJdID0gMTtcbiAgICAgICAgICAgIHZhbHVlc1t2YWx1ZXNCeUlkWzJdID0gXCJJTlRcIl0gPSAyO1xuICAgICAgICAgICAgdmFsdWVzW3ZhbHVlc0J5SWRbM10gPSBcIlNUUklOR1wiXSA9IDM7XG4gICAgICAgICAgICB2YWx1ZXNbdmFsdWVzQnlJZFs0XSA9IFwiVEVOU09SXCJdID0gNDtcbiAgICAgICAgICAgIHZhbHVlc1t2YWx1ZXNCeUlkWzVdID0gXCJHUkFQSFwiXSA9IDU7XG4gICAgICAgICAgICB2YWx1ZXNbdmFsdWVzQnlJZFs2XSA9IFwiRkxPQVRTXCJdID0gNjtcbiAgICAgICAgICAgIHZhbHVlc1t2YWx1ZXNCeUlkWzddID0gXCJJTlRTXCJdID0gNztcbiAgICAgICAgICAgIHZhbHVlc1t2YWx1ZXNCeUlkWzhdID0gXCJTVFJJTkdTXCJdID0gODtcbiAgICAgICAgICAgIHZhbHVlc1t2YWx1ZXNCeUlkWzldID0gXCJURU5TT1JTXCJdID0gOTtcbiAgICAgICAgICAgIHZhbHVlc1t2YWx1ZXNCeUlkWzEwXSA9IFwiR1JBUEhTXCJdID0gMTA7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWVzO1xuICAgICAgICB9KSgpO1xuXG4gICAgICAgIHJldHVybiBBdHRyaWJ1dGVQcm90bztcbiAgICB9KSgpO1xuXG4gICAgb25ueC5WYWx1ZUluZm9Qcm90byA9IChmdW5jdGlvbigpIHtcblxuICAgICAgICAvKipcbiAgICAgICAgICogUHJvcGVydGllcyBvZiBhIFZhbHVlSW5mb1Byb3RvLlxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAgICAgKiBAaW50ZXJmYWNlIElWYWx1ZUluZm9Qcm90b1xuICAgICAgICAgKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSBbbmFtZV0gVmFsdWVJbmZvUHJvdG8gbmFtZVxuICAgICAgICAgKiBAcHJvcGVydHkge29ubnguSVR5cGVQcm90b3xudWxsfSBbdHlwZV0gVmFsdWVJbmZvUHJvdG8gdHlwZVxuICAgICAgICAgKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSBbZG9jU3RyaW5nXSBWYWx1ZUluZm9Qcm90byBkb2NTdHJpbmdcbiAgICAgICAgICovXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENvbnN0cnVjdHMgYSBuZXcgVmFsdWVJbmZvUHJvdG8uXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54XG4gICAgICAgICAqIEBjbGFzc2Rlc2MgUmVwcmVzZW50cyBhIFZhbHVlSW5mb1Byb3RvLlxuICAgICAgICAgKiBAaW1wbGVtZW50cyBJVmFsdWVJbmZvUHJvdG9cbiAgICAgICAgICogQGNvbnN0cnVjdG9yXG4gICAgICAgICAqIEBwYXJhbSB7b25ueC5JVmFsdWVJbmZvUHJvdG89fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgICAgICovXG4gICAgICAgIGZ1bmN0aW9uIFZhbHVlSW5mb1Byb3RvKHByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzKVxuICAgICAgICAgICAgICAgIGZvciAodmFyIGtleXMgPSBPYmplY3Qua2V5cyhwcm9wZXJ0aWVzKSwgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICBpZiAocHJvcGVydGllc1trZXlzW2ldXSAhPSBudWxsKVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpc1trZXlzW2ldXSA9IHByb3BlcnRpZXNba2V5c1tpXV07XG4gICAgICAgIH1cblxuICAgICAgICAvKipcbiAgICAgICAgICogVmFsdWVJbmZvUHJvdG8gbmFtZS5cbiAgICAgICAgICogQG1lbWJlciB7c3RyaW5nfSBuYW1lXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlZhbHVlSW5mb1Byb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgVmFsdWVJbmZvUHJvdG8ucHJvdG90eXBlLm5hbWUgPSBcIlwiO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBWYWx1ZUluZm9Qcm90byB0eXBlLlxuICAgICAgICAgKiBAbWVtYmVyIHtvbm54LklUeXBlUHJvdG98bnVsbHx1bmRlZmluZWR9IHR5cGVcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVmFsdWVJbmZvUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBWYWx1ZUluZm9Qcm90by5wcm90b3R5cGUudHlwZSA9IG51bGw7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFZhbHVlSW5mb1Byb3RvIGRvY1N0cmluZy5cbiAgICAgICAgICogQG1lbWJlciB7c3RyaW5nfSBkb2NTdHJpbmdcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVmFsdWVJbmZvUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBWYWx1ZUluZm9Qcm90by5wcm90b3R5cGUuZG9jU3RyaW5nID0gXCJcIjtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ3JlYXRlcyBhIG5ldyBWYWx1ZUluZm9Qcm90byBpbnN0YW5jZSB1c2luZyB0aGUgc3BlY2lmaWVkIHByb3BlcnRpZXMuXG4gICAgICAgICAqIEBmdW5jdGlvbiBjcmVhdGVcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVmFsdWVJbmZvUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge29ubnguSVZhbHVlSW5mb1Byb3RvPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICAgICAqIEByZXR1cm5zIHtvbm54LlZhbHVlSW5mb1Byb3RvfSBWYWx1ZUluZm9Qcm90byBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgVmFsdWVJbmZvUHJvdG8uY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKHByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgVmFsdWVJbmZvUHJvdG8ocHJvcGVydGllcyk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBWYWx1ZUluZm9Qcm90byBtZXNzYWdlLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlZhbHVlSW5mb1Byb3RvLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlZhbHVlSW5mb1Byb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtvbm54LklWYWx1ZUluZm9Qcm90b30gbWVzc2FnZSBWYWx1ZUluZm9Qcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgICAgICovXG4gICAgICAgIFZhbHVlSW5mb1Byb3RvLmVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZShtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgICAgICAgIGlmICghd3JpdGVyKVxuICAgICAgICAgICAgICAgIHdyaXRlciA9ICRXcml0ZXIuY3JlYXRlKCk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5uYW1lICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcIm5hbWVcIikpXG4gICAgICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxLCB3aXJlVHlwZSAyID0qLzEwKS5zdHJpbmcobWVzc2FnZS5uYW1lKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwidHlwZVwiKSlcbiAgICAgICAgICAgICAgICAkcm9vdC5vbm54LlR5cGVQcm90by5lbmNvZGUobWVzc2FnZS50eXBlLCB3cml0ZXIudWludDMyKC8qIGlkIDIsIHdpcmVUeXBlIDIgPSovMTgpLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5kb2NTdHJpbmcgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiZG9jU3RyaW5nXCIpKVxuICAgICAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMywgd2lyZVR5cGUgMiA9Ki8yNikuc3RyaW5nKG1lc3NhZ2UuZG9jU3RyaW5nKTtcbiAgICAgICAgICAgIHJldHVybiB3cml0ZXI7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBWYWx1ZUluZm9Qcm90byBtZXNzYWdlLCBsZW5ndGggZGVsaW1pdGVkLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlZhbHVlSW5mb1Byb3RvLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlZhbHVlSW5mb1Byb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtvbm54LklWYWx1ZUluZm9Qcm90b30gbWVzc2FnZSBWYWx1ZUluZm9Qcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgICAgICovXG4gICAgICAgIFZhbHVlSW5mb1Byb3RvLmVuY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZChtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVuY29kZShtZXNzYWdlLCB3cml0ZXIpLmxkZWxpbSgpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEZWNvZGVzIGEgVmFsdWVJbmZvUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlci5cbiAgICAgICAgICogQGZ1bmN0aW9uIGRlY29kZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5WYWx1ZUluZm9Qcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aF0gTWVzc2FnZSBsZW5ndGggaWYga25vd24gYmVmb3JlaGFuZFxuICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5WYWx1ZUluZm9Qcm90b30gVmFsdWVJbmZvUHJvdG9cbiAgICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICAgICAqL1xuICAgICAgICBWYWx1ZUluZm9Qcm90by5kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUocmVhZGVyLCBsZW5ndGgpIHtcbiAgICAgICAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKVxuICAgICAgICAgICAgICAgIHJlYWRlciA9ICRSZWFkZXIuY3JlYXRlKHJlYWRlcik7XG4gICAgICAgICAgICB2YXIgZW5kID0gbGVuZ3RoID09PSB1bmRlZmluZWQgPyByZWFkZXIubGVuIDogcmVhZGVyLnBvcyArIGxlbmd0aCwgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlZhbHVlSW5mb1Byb3RvKCk7XG4gICAgICAgICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZCkge1xuICAgICAgICAgICAgICAgIHZhciB0YWcgPSByZWFkZXIudWludDMyKCk7XG4gICAgICAgICAgICAgICAgc3dpdGNoICh0YWcgPj4+IDMpIHtcbiAgICAgICAgICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UubmFtZSA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAyOlxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnR5cGUgPSAkcm9vdC5vbm54LlR5cGVQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZG9jU3RyaW5nID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICByZWFkZXIuc2tpcFR5cGUodGFnICYgNyk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEZWNvZGVzIGEgVmFsdWVJbmZvUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlciwgbGVuZ3RoIGRlbGltaXRlZC5cbiAgICAgICAgICogQGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZFxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5WYWx1ZUluZm9Qcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5WYWx1ZUluZm9Qcm90b30gVmFsdWVJbmZvUHJvdG9cbiAgICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICAgICAqL1xuICAgICAgICBWYWx1ZUluZm9Qcm90by5kZWNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWQocmVhZGVyKSB7XG4gICAgICAgICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSlcbiAgICAgICAgICAgICAgICByZWFkZXIgPSBuZXcgJFJlYWRlcihyZWFkZXIpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogVmVyaWZpZXMgYSBWYWx1ZUluZm9Qcm90byBtZXNzYWdlLlxuICAgICAgICAgKiBAZnVuY3Rpb24gdmVyaWZ5XG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlZhbHVlSW5mb1Byb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gbWVzc2FnZSBQbGFpbiBvYmplY3QgdG8gdmVyaWZ5XG4gICAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd8bnVsbH0gYG51bGxgIGlmIHZhbGlkLCBvdGhlcndpc2UgdGhlIHJlYXNvbiB3aHkgaXQgaXMgbm90XG4gICAgICAgICAqL1xuICAgICAgICBWYWx1ZUluZm9Qcm90by52ZXJpZnkgPSBmdW5jdGlvbiB2ZXJpZnkobWVzc2FnZSkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlICE9PSBcIm9iamVjdFwiIHx8IG1lc3NhZ2UgPT09IG51bGwpXG4gICAgICAgICAgICAgICAgcmV0dXJuIFwib2JqZWN0IGV4cGVjdGVkXCI7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5uYW1lICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcIm5hbWVcIikpXG4gICAgICAgICAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLm5hbWUpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJuYW1lOiBzdHJpbmcgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwidHlwZVwiKSkge1xuICAgICAgICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguVHlwZVByb3RvLnZlcmlmeShtZXNzYWdlLnR5cGUpO1xuICAgICAgICAgICAgICAgIGlmIChlcnJvcilcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwidHlwZS5cIiArIGVycm9yO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZG9jU3RyaW5nICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImRvY1N0cmluZ1wiKSlcbiAgICAgICAgICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UuZG9jU3RyaW5nKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiZG9jU3RyaW5nOiBzdHJpbmcgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDcmVhdGVzIGEgVmFsdWVJbmZvUHJvdG8gbWVzc2FnZSBmcm9tIGEgcGxhaW4gb2JqZWN0LiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byB0aGVpciByZXNwZWN0aXZlIGludGVybmFsIHR5cGVzLlxuICAgICAgICAgKiBAZnVuY3Rpb24gZnJvbU9iamVjdFxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5WYWx1ZUluZm9Qcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG9iamVjdCBQbGFpbiBvYmplY3RcbiAgICAgICAgICogQHJldHVybnMge29ubnguVmFsdWVJbmZvUHJvdG99IFZhbHVlSW5mb1Byb3RvXG4gICAgICAgICAqL1xuICAgICAgICBWYWx1ZUluZm9Qcm90by5mcm9tT2JqZWN0ID0gZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgICAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiAkcm9vdC5vbm54LlZhbHVlSW5mb1Byb3RvKVxuICAgICAgICAgICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICAgICAgICB2YXIgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlZhbHVlSW5mb1Byb3RvKCk7XG4gICAgICAgICAgICBpZiAob2JqZWN0Lm5hbWUgIT0gbnVsbClcbiAgICAgICAgICAgICAgICBtZXNzYWdlLm5hbWUgPSBTdHJpbmcob2JqZWN0Lm5hbWUpO1xuICAgICAgICAgICAgaWYgKG9iamVjdC50eXBlICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC50eXBlICE9PSBcIm9iamVjdFwiKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5WYWx1ZUluZm9Qcm90by50eXBlOiBvYmplY3QgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgbWVzc2FnZS50eXBlID0gJHJvb3Qub25ueC5UeXBlUHJvdG8uZnJvbU9iamVjdChvYmplY3QudHlwZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob2JqZWN0LmRvY1N0cmluZyAhPSBudWxsKVxuICAgICAgICAgICAgICAgIG1lc3NhZ2UuZG9jU3RyaW5nID0gU3RyaW5nKG9iamVjdC5kb2NTdHJpbmcpO1xuICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENyZWF0ZXMgYSBwbGFpbiBvYmplY3QgZnJvbSBhIFZhbHVlSW5mb1Byb3RvIG1lc3NhZ2UuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIG90aGVyIHR5cGVzIGlmIHNwZWNpZmllZC5cbiAgICAgICAgICogQGZ1bmN0aW9uIHRvT2JqZWN0XG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlZhbHVlSW5mb1Byb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtvbm54LlZhbHVlSW5mb1Byb3RvfSBtZXNzYWdlIFZhbHVlSW5mb1Byb3RvXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLklDb252ZXJzaW9uT3B0aW9uc30gW29wdGlvbnNdIENvbnZlcnNpb24gb3B0aW9uc1xuICAgICAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IFBsYWluIG9iamVjdFxuICAgICAgICAgKi9cbiAgICAgICAgVmFsdWVJbmZvUHJvdG8udG9PYmplY3QgPSBmdW5jdGlvbiB0b09iamVjdChtZXNzYWdlLCBvcHRpb25zKSB7XG4gICAgICAgICAgICBpZiAoIW9wdGlvbnMpXG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IHt9O1xuICAgICAgICAgICAgdmFyIG9iamVjdCA9IHt9O1xuICAgICAgICAgICAgaWYgKG9wdGlvbnMuZGVmYXVsdHMpIHtcbiAgICAgICAgICAgICAgICBvYmplY3QubmFtZSA9IFwiXCI7XG4gICAgICAgICAgICAgICAgb2JqZWN0LnR5cGUgPSBudWxsO1xuICAgICAgICAgICAgICAgIG9iamVjdC5kb2NTdHJpbmcgPSBcIlwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UubmFtZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJuYW1lXCIpKVxuICAgICAgICAgICAgICAgIG9iamVjdC5uYW1lID0gbWVzc2FnZS5uYW1lO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UudHlwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJ0eXBlXCIpKVxuICAgICAgICAgICAgICAgIG9iamVjdC50eXBlID0gJHJvb3Qub25ueC5UeXBlUHJvdG8udG9PYmplY3QobWVzc2FnZS50eXBlLCBvcHRpb25zKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmRvY1N0cmluZyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJkb2NTdHJpbmdcIikpXG4gICAgICAgICAgICAgICAgb2JqZWN0LmRvY1N0cmluZyA9IG1lc3NhZ2UuZG9jU3RyaW5nO1xuICAgICAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ29udmVydHMgdGhpcyBWYWx1ZUluZm9Qcm90byB0byBKU09OLlxuICAgICAgICAgKiBAZnVuY3Rpb24gdG9KU09OXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlZhbHVlSW5mb1Byb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IEpTT04gb2JqZWN0XG4gICAgICAgICAqL1xuICAgICAgICBWYWx1ZUluZm9Qcm90by5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IudG9PYmplY3QodGhpcywgJHByb3RvYnVmLnV0aWwudG9KU09OT3B0aW9ucyk7XG4gICAgICAgIH07XG5cbiAgICAgICAgcmV0dXJuIFZhbHVlSW5mb1Byb3RvO1xuICAgIH0pKCk7XG5cbiAgICBvbm54Lk5vZGVQcm90byA9IChmdW5jdGlvbigpIHtcblxuICAgICAgICAvKipcbiAgICAgICAgICogUHJvcGVydGllcyBvZiBhIE5vZGVQcm90by5cbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgICAgICogQGludGVyZmFjZSBJTm9kZVByb3RvXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPHN0cmluZz58bnVsbH0gW2lucHV0XSBOb2RlUHJvdG8gaW5wdXRcbiAgICAgICAgICogQHByb3BlcnR5IHtBcnJheS48c3RyaW5nPnxudWxsfSBbb3V0cHV0XSBOb2RlUHJvdG8gb3V0cHV0XG4gICAgICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtuYW1lXSBOb2RlUHJvdG8gbmFtZVxuICAgICAgICAgKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSBbb3BUeXBlXSBOb2RlUHJvdG8gb3BUeXBlXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtkb21haW5dIE5vZGVQcm90byBkb21haW5cbiAgICAgICAgICogQHByb3BlcnR5IHtBcnJheS48b25ueC5JQXR0cmlidXRlUHJvdG8+fG51bGx9IFthdHRyaWJ1dGVdIE5vZGVQcm90byBhdHRyaWJ1dGVcbiAgICAgICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW2RvY1N0cmluZ10gTm9kZVByb3RvIGRvY1N0cmluZ1xuICAgICAgICAgKi9cblxuICAgICAgICAvKipcbiAgICAgICAgICogQ29uc3RydWN0cyBhIG5ldyBOb2RlUHJvdG8uXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54XG4gICAgICAgICAqIEBjbGFzc2Rlc2MgUmVwcmVzZW50cyBhIE5vZGVQcm90by5cbiAgICAgICAgICogQGltcGxlbWVudHMgSU5vZGVQcm90b1xuICAgICAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgICAgICogQHBhcmFtIHtvbm54LklOb2RlUHJvdG89fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgICAgICovXG4gICAgICAgIGZ1bmN0aW9uIE5vZGVQcm90byhwcm9wZXJ0aWVzKSB7XG4gICAgICAgICAgICB0aGlzLmlucHV0ID0gW107XG4gICAgICAgICAgICB0aGlzLm91dHB1dCA9IFtdO1xuICAgICAgICAgICAgdGhpcy5hdHRyaWJ1dGUgPSBbXTtcbiAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzKVxuICAgICAgICAgICAgICAgIGZvciAodmFyIGtleXMgPSBPYmplY3Qua2V5cyhwcm9wZXJ0aWVzKSwgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICBpZiAocHJvcGVydGllc1trZXlzW2ldXSAhPSBudWxsKVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpc1trZXlzW2ldXSA9IHByb3BlcnRpZXNba2V5c1tpXV07XG4gICAgICAgIH1cblxuICAgICAgICAvKipcbiAgICAgICAgICogTm9kZVByb3RvIGlucHV0LlxuICAgICAgICAgKiBAbWVtYmVyIHtBcnJheS48c3RyaW5nPn0gaW5wdXRcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguTm9kZVByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgTm9kZVByb3RvLnByb3RvdHlwZS5pbnB1dCA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIE5vZGVQcm90byBvdXRwdXQuXG4gICAgICAgICAqIEBtZW1iZXIge0FycmF5LjxzdHJpbmc+fSBvdXRwdXRcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguTm9kZVByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgTm9kZVByb3RvLnByb3RvdHlwZS5vdXRwdXQgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBOb2RlUHJvdG8gbmFtZS5cbiAgICAgICAgICogQG1lbWJlciB7c3RyaW5nfSBuYW1lXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54Lk5vZGVQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIE5vZGVQcm90by5wcm90b3R5cGUubmFtZSA9IFwiXCI7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIE5vZGVQcm90byBvcFR5cGUuXG4gICAgICAgICAqIEBtZW1iZXIge3N0cmluZ30gb3BUeXBlXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54Lk5vZGVQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIE5vZGVQcm90by5wcm90b3R5cGUub3BUeXBlID0gXCJcIjtcblxuICAgICAgICAvKipcbiAgICAgICAgICogTm9kZVByb3RvIGRvbWFpbi5cbiAgICAgICAgICogQG1lbWJlciB7c3RyaW5nfSBkb21haW5cbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguTm9kZVByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgTm9kZVByb3RvLnByb3RvdHlwZS5kb21haW4gPSBcIlwiO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBOb2RlUHJvdG8gYXR0cmlidXRlLlxuICAgICAgICAgKiBAbWVtYmVyIHtBcnJheS48b25ueC5JQXR0cmlidXRlUHJvdG8+fSBhdHRyaWJ1dGVcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguTm9kZVByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgTm9kZVByb3RvLnByb3RvdHlwZS5hdHRyaWJ1dGUgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBOb2RlUHJvdG8gZG9jU3RyaW5nLlxuICAgICAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IGRvY1N0cmluZ1xuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5Ob2RlUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBOb2RlUHJvdG8ucHJvdG90eXBlLmRvY1N0cmluZyA9IFwiXCI7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENyZWF0ZXMgYSBuZXcgTm9kZVByb3RvIGluc3RhbmNlIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHJvcGVydGllcy5cbiAgICAgICAgICogQGZ1bmN0aW9uIGNyZWF0ZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5Ob2RlUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge29ubnguSU5vZGVQcm90bz19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5Ob2RlUHJvdG99IE5vZGVQcm90byBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgTm9kZVByb3RvLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShwcm9wZXJ0aWVzKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IE5vZGVQcm90byhwcm9wZXJ0aWVzKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIE5vZGVQcm90byBtZXNzYWdlLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54Lk5vZGVQcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgICAgICogQGZ1bmN0aW9uIGVuY29kZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5Ob2RlUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge29ubnguSU5vZGVQcm90b30gbWVzc2FnZSBOb2RlUHJvdG8gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICAgICAqL1xuICAgICAgICBOb2RlUHJvdG8uZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgICAgICAgaWYgKCF3cml0ZXIpXG4gICAgICAgICAgICAgICAgd3JpdGVyID0gJFdyaXRlci5jcmVhdGUoKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmlucHV0ICE9IG51bGwgJiYgbWVzc2FnZS5pbnB1dC5sZW5ndGgpXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmlucHV0Lmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDEsIHdpcmVUeXBlIDIgPSovMTApLnN0cmluZyhtZXNzYWdlLmlucHV0W2ldKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLm91dHB1dCAhPSBudWxsICYmIG1lc3NhZ2Uub3V0cHV0Lmxlbmd0aClcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2Uub3V0cHV0Lmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDIsIHdpcmVUeXBlIDIgPSovMTgpLnN0cmluZyhtZXNzYWdlLm91dHB1dFtpXSk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5uYW1lICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcIm5hbWVcIikpXG4gICAgICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAzLCB3aXJlVHlwZSAyID0qLzI2KS5zdHJpbmcobWVzc2FnZS5uYW1lKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLm9wVHlwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJvcFR5cGVcIikpXG4gICAgICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCA0LCB3aXJlVHlwZSAyID0qLzM0KS5zdHJpbmcobWVzc2FnZS5vcFR5cGUpO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuYXR0cmlidXRlICE9IG51bGwgJiYgbWVzc2FnZS5hdHRyaWJ1dGUubGVuZ3RoKVxuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5hdHRyaWJ1dGUubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgICRyb290Lm9ubnguQXR0cmlidXRlUHJvdG8uZW5jb2RlKG1lc3NhZ2UuYXR0cmlidXRlW2ldLCB3cml0ZXIudWludDMyKC8qIGlkIDUsIHdpcmVUeXBlIDIgPSovNDIpLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5kb2NTdHJpbmcgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiZG9jU3RyaW5nXCIpKVxuICAgICAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgNiwgd2lyZVR5cGUgMiA9Ki81MCkuc3RyaW5nKG1lc3NhZ2UuZG9jU3RyaW5nKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmRvbWFpbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJkb21haW5cIikpXG4gICAgICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCA3LCB3aXJlVHlwZSAyID0qLzU4KS5zdHJpbmcobWVzc2FnZS5kb21haW4pO1xuICAgICAgICAgICAgcmV0dXJuIHdyaXRlcjtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIE5vZGVQcm90byBtZXNzYWdlLCBsZW5ndGggZGVsaW1pdGVkLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54Lk5vZGVQcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgICAgICogQGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZFxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5Ob2RlUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge29ubnguSU5vZGVQcm90b30gbWVzc2FnZSBOb2RlUHJvdG8gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICAgICAqL1xuICAgICAgICBOb2RlUHJvdG8uZW5jb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikubGRlbGltKCk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIERlY29kZXMgYSBOb2RlUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlci5cbiAgICAgICAgICogQGZ1bmN0aW9uIGRlY29kZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5Ob2RlUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGhdIE1lc3NhZ2UgbGVuZ3RoIGlmIGtub3duIGJlZm9yZWhhbmRcbiAgICAgICAgICogQHJldHVybnMge29ubnguTm9kZVByb3RvfSBOb2RlUHJvdG9cbiAgICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICAgICAqL1xuICAgICAgICBOb2RlUHJvdG8uZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKHJlYWRlciwgbGVuZ3RoKSB7XG4gICAgICAgICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSlcbiAgICAgICAgICAgICAgICByZWFkZXIgPSAkUmVhZGVyLmNyZWF0ZShyZWFkZXIpO1xuICAgICAgICAgICAgdmFyIGVuZCA9IGxlbmd0aCA9PT0gdW5kZWZpbmVkID8gcmVhZGVyLmxlbiA6IHJlYWRlci5wb3MgKyBsZW5ndGgsIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5Ob2RlUHJvdG8oKTtcbiAgICAgICAgICAgIHdoaWxlIChyZWFkZXIucG9zIDwgZW5kKSB7XG4gICAgICAgICAgICAgICAgdmFyIHRhZyA9IHJlYWRlci51aW50MzIoKTtcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKHRhZyA+Pj4gMykge1xuICAgICAgICAgICAgICAgIGNhc2UgMTpcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5pbnB1dCAmJiBtZXNzYWdlLmlucHV0Lmxlbmd0aCkpXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmlucHV0ID0gW107XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuaW5wdXQucHVzaChyZWFkZXIuc3RyaW5nKCkpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgICAgICAgICAgIGlmICghKG1lc3NhZ2Uub3V0cHV0ICYmIG1lc3NhZ2Uub3V0cHV0Lmxlbmd0aCkpXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLm91dHB1dCA9IFtdO1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLm91dHB1dC5wdXNoKHJlYWRlci5zdHJpbmcoKSk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5uYW1lID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2Uub3BUeXBlID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIDc6XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZG9tYWluID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIDU6XG4gICAgICAgICAgICAgICAgICAgIGlmICghKG1lc3NhZ2UuYXR0cmlidXRlICYmIG1lc3NhZ2UuYXR0cmlidXRlLmxlbmd0aCkpXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmF0dHJpYnV0ZSA9IFtdO1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmF0dHJpYnV0ZS5wdXNoKCRyb290Lm9ubnguQXR0cmlidXRlUHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKSk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgNjpcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5kb2NTdHJpbmcgPSByZWFkZXIuc3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIHJlYWRlci5za2lwVHlwZSh0YWcgJiA3KTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIERlY29kZXMgYSBOb2RlUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlciwgbGVuZ3RoIGRlbGltaXRlZC5cbiAgICAgICAgICogQGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZFxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5Ob2RlUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgICAgICogQHJldHVybnMge29ubnguTm9kZVByb3RvfSBOb2RlUHJvdG9cbiAgICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICAgICAqL1xuICAgICAgICBOb2RlUHJvdG8uZGVjb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkKHJlYWRlcikge1xuICAgICAgICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpXG4gICAgICAgICAgICAgICAgcmVhZGVyID0gbmV3ICRSZWFkZXIocmVhZGVyKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFZlcmlmaWVzIGEgTm9kZVByb3RvIG1lc3NhZ2UuXG4gICAgICAgICAqIEBmdW5jdGlvbiB2ZXJpZnlcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguTm9kZVByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gbWVzc2FnZSBQbGFpbiBvYmplY3QgdG8gdmVyaWZ5XG4gICAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd8bnVsbH0gYG51bGxgIGlmIHZhbGlkLCBvdGhlcndpc2UgdGhlIHJlYXNvbiB3aHkgaXQgaXMgbm90XG4gICAgICAgICAqL1xuICAgICAgICBOb2RlUHJvdG8udmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1lc3NhZ2UpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSAhPT0gXCJvYmplY3RcIiB8fCBtZXNzYWdlID09PSBudWxsKVxuICAgICAgICAgICAgICAgIHJldHVybiBcIm9iamVjdCBleHBlY3RlZFwiO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuaW5wdXQgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiaW5wdXRcIikpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5pbnB1dCkpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcImlucHV0OiBhcnJheSBleHBlY3RlZFwiO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5pbnB1dC5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLmlucHV0W2ldKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcImlucHV0OiBzdHJpbmdbXSBleHBlY3RlZFwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2Uub3V0cHV0ICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcIm91dHB1dFwiKSkge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLm91dHB1dCkpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm91dHB1dDogYXJyYXkgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2Uub3V0cHV0Lmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2Uub3V0cHV0W2ldKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm91dHB1dDogc3RyaW5nW10gZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLm5hbWUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwibmFtZVwiKSlcbiAgICAgICAgICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UubmFtZSkpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm5hbWU6IHN0cmluZyBleHBlY3RlZFwiO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2Uub3BUeXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcIm9wVHlwZVwiKSlcbiAgICAgICAgICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2Uub3BUeXBlKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwib3BUeXBlOiBzdHJpbmcgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmRvbWFpbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJkb21haW5cIikpXG4gICAgICAgICAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLmRvbWFpbikpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcImRvbWFpbjogc3RyaW5nIGV4cGVjdGVkXCI7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5hdHRyaWJ1dGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiYXR0cmlidXRlXCIpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2UuYXR0cmlidXRlKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiYXR0cmlidXRlOiBhcnJheSBleHBlY3RlZFwiO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5hdHRyaWJ1dGUubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5BdHRyaWJ1dGVQcm90by52ZXJpZnkobWVzc2FnZS5hdHRyaWJ1dGVbaV0pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJhdHRyaWJ1dGUuXCIgKyBlcnJvcjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5kb2NTdHJpbmcgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiZG9jU3RyaW5nXCIpKVxuICAgICAgICAgICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5kb2NTdHJpbmcpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJkb2NTdHJpbmc6IHN0cmluZyBleHBlY3RlZFwiO1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENyZWF0ZXMgYSBOb2RlUHJvdG8gbWVzc2FnZSBmcm9tIGEgcGxhaW4gb2JqZWN0LiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byB0aGVpciByZXNwZWN0aXZlIGludGVybmFsIHR5cGVzLlxuICAgICAgICAgKiBAZnVuY3Rpb24gZnJvbU9iamVjdFxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5Ob2RlUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBvYmplY3QgUGxhaW4gb2JqZWN0XG4gICAgICAgICAqIEByZXR1cm5zIHtvbm54Lk5vZGVQcm90b30gTm9kZVByb3RvXG4gICAgICAgICAqL1xuICAgICAgICBOb2RlUHJvdG8uZnJvbU9iamVjdCA9IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgJHJvb3Qub25ueC5Ob2RlUHJvdG8pXG4gICAgICAgICAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgICAgICAgIHZhciBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguTm9kZVByb3RvKCk7XG4gICAgICAgICAgICBpZiAob2JqZWN0LmlucHV0KSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5pbnB1dCkpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIi5vbm54Lk5vZGVQcm90by5pbnB1dDogYXJyYXkgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgbWVzc2FnZS5pbnB1dCA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0LmlucHV0Lmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmlucHV0W2ldID0gU3RyaW5nKG9iamVjdC5pbnB1dFtpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob2JqZWN0Lm91dHB1dCkge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3Qub3V0cHV0KSlcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguTm9kZVByb3RvLm91dHB1dDogYXJyYXkgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgbWVzc2FnZS5vdXRwdXQgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5vdXRwdXQubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2Uub3V0cHV0W2ldID0gU3RyaW5nKG9iamVjdC5vdXRwdXRbaV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG9iamVjdC5uYW1lICE9IG51bGwpXG4gICAgICAgICAgICAgICAgbWVzc2FnZS5uYW1lID0gU3RyaW5nKG9iamVjdC5uYW1lKTtcbiAgICAgICAgICAgIGlmIChvYmplY3Qub3BUeXBlICE9IG51bGwpXG4gICAgICAgICAgICAgICAgbWVzc2FnZS5vcFR5cGUgPSBTdHJpbmcob2JqZWN0Lm9wVHlwZSk7XG4gICAgICAgICAgICBpZiAob2JqZWN0LmRvbWFpbiAhPSBudWxsKVxuICAgICAgICAgICAgICAgIG1lc3NhZ2UuZG9tYWluID0gU3RyaW5nKG9iamVjdC5kb21haW4pO1xuICAgICAgICAgICAgaWYgKG9iamVjdC5hdHRyaWJ1dGUpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LmF0dHJpYnV0ZSkpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIi5vbm54Lk5vZGVQcm90by5hdHRyaWJ1dGU6IGFycmF5IGV4cGVjdGVkXCIpO1xuICAgICAgICAgICAgICAgIG1lc3NhZ2UuYXR0cmlidXRlID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QuYXR0cmlidXRlLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LmF0dHJpYnV0ZVtpXSAhPT0gXCJvYmplY3RcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIi5vbm54Lk5vZGVQcm90by5hdHRyaWJ1dGU6IG9iamVjdCBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5hdHRyaWJ1dGVbaV0gPSAkcm9vdC5vbm54LkF0dHJpYnV0ZVByb3RvLmZyb21PYmplY3Qob2JqZWN0LmF0dHJpYnV0ZVtpXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG9iamVjdC5kb2NTdHJpbmcgIT0gbnVsbClcbiAgICAgICAgICAgICAgICBtZXNzYWdlLmRvY1N0cmluZyA9IFN0cmluZyhvYmplY3QuZG9jU3RyaW5nKTtcbiAgICAgICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDcmVhdGVzIGEgcGxhaW4gb2JqZWN0IGZyb20gYSBOb2RlUHJvdG8gbWVzc2FnZS4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gb3RoZXIgdHlwZXMgaWYgc3BlY2lmaWVkLlxuICAgICAgICAgKiBAZnVuY3Rpb24gdG9PYmplY3RcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguTm9kZVByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtvbm54Lk5vZGVQcm90b30gbWVzc2FnZSBOb2RlUHJvdG9cbiAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuSUNvbnZlcnNpb25PcHRpb25zfSBbb3B0aW9uc10gQ29udmVyc2lvbiBvcHRpb25zXG4gICAgICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gUGxhaW4gb2JqZWN0XG4gICAgICAgICAqL1xuICAgICAgICBOb2RlUHJvdG8udG9PYmplY3QgPSBmdW5jdGlvbiB0b09iamVjdChtZXNzYWdlLCBvcHRpb25zKSB7XG4gICAgICAgICAgICBpZiAoIW9wdGlvbnMpXG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IHt9O1xuICAgICAgICAgICAgdmFyIG9iamVjdCA9IHt9O1xuICAgICAgICAgICAgaWYgKG9wdGlvbnMuYXJyYXlzIHx8IG9wdGlvbnMuZGVmYXVsdHMpIHtcbiAgICAgICAgICAgICAgICBvYmplY3QuaW5wdXQgPSBbXTtcbiAgICAgICAgICAgICAgICBvYmplY3Qub3V0cHV0ID0gW107XG4gICAgICAgICAgICAgICAgb2JqZWN0LmF0dHJpYnV0ZSA9IFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG9wdGlvbnMuZGVmYXVsdHMpIHtcbiAgICAgICAgICAgICAgICBvYmplY3QubmFtZSA9IFwiXCI7XG4gICAgICAgICAgICAgICAgb2JqZWN0Lm9wVHlwZSA9IFwiXCI7XG4gICAgICAgICAgICAgICAgb2JqZWN0LmRvY1N0cmluZyA9IFwiXCI7XG4gICAgICAgICAgICAgICAgb2JqZWN0LmRvbWFpbiA9IFwiXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5pbnB1dCAmJiBtZXNzYWdlLmlucHV0Lmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIG9iamVjdC5pbnB1dCA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5pbnB1dC5sZW5ndGg7ICsrailcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LmlucHV0W2pdID0gbWVzc2FnZS5pbnB1dFtqXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLm91dHB1dCAmJiBtZXNzYWdlLm91dHB1dC5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBvYmplY3Qub3V0cHV0ID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLm91dHB1dC5sZW5ndGg7ICsrailcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0Lm91dHB1dFtqXSA9IG1lc3NhZ2Uub3V0cHV0W2pdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UubmFtZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJuYW1lXCIpKVxuICAgICAgICAgICAgICAgIG9iamVjdC5uYW1lID0gbWVzc2FnZS5uYW1lO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2Uub3BUeXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcIm9wVHlwZVwiKSlcbiAgICAgICAgICAgICAgICBvYmplY3Qub3BUeXBlID0gbWVzc2FnZS5vcFR5cGU7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5hdHRyaWJ1dGUgJiYgbWVzc2FnZS5hdHRyaWJ1dGUubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgb2JqZWN0LmF0dHJpYnV0ZSA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5hdHRyaWJ1dGUubGVuZ3RoOyArK2opXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC5hdHRyaWJ1dGVbal0gPSAkcm9vdC5vbm54LkF0dHJpYnV0ZVByb3RvLnRvT2JqZWN0KG1lc3NhZ2UuYXR0cmlidXRlW2pdLCBvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmRvY1N0cmluZyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJkb2NTdHJpbmdcIikpXG4gICAgICAgICAgICAgICAgb2JqZWN0LmRvY1N0cmluZyA9IG1lc3NhZ2UuZG9jU3RyaW5nO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZG9tYWluICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImRvbWFpblwiKSlcbiAgICAgICAgICAgICAgICBvYmplY3QuZG9tYWluID0gbWVzc2FnZS5kb21haW47XG4gICAgICAgICAgICByZXR1cm4gb2JqZWN0O1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDb252ZXJ0cyB0aGlzIE5vZGVQcm90byB0byBKU09OLlxuICAgICAgICAgKiBAZnVuY3Rpb24gdG9KU09OXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54Lk5vZGVQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBKU09OIG9iamVjdFxuICAgICAgICAgKi9cbiAgICAgICAgTm9kZVByb3RvLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04oKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci50b09iamVjdCh0aGlzLCAkcHJvdG9idWYudXRpbC50b0pTT05PcHRpb25zKTtcbiAgICAgICAgfTtcblxuICAgICAgICByZXR1cm4gTm9kZVByb3RvO1xuICAgIH0pKCk7XG5cbiAgICBvbm54Lk1vZGVsUHJvdG8gPSAoZnVuY3Rpb24oKSB7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFByb3BlcnRpZXMgb2YgYSBNb2RlbFByb3RvLlxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAgICAgKiBAaW50ZXJmYWNlIElNb2RlbFByb3RvXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfExvbmd8bnVsbH0gW2lyVmVyc2lvbl0gTW9kZWxQcm90byBpclZlcnNpb25cbiAgICAgICAgICogQHByb3BlcnR5IHtBcnJheS48b25ueC5JT3BlcmF0b3JTZXRJZFByb3RvPnxudWxsfSBbb3BzZXRJbXBvcnRdIE1vZGVsUHJvdG8gb3BzZXRJbXBvcnRcbiAgICAgICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW3Byb2R1Y2VyTmFtZV0gTW9kZWxQcm90byBwcm9kdWNlck5hbWVcbiAgICAgICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW3Byb2R1Y2VyVmVyc2lvbl0gTW9kZWxQcm90byBwcm9kdWNlclZlcnNpb25cbiAgICAgICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW2RvbWFpbl0gTW9kZWxQcm90byBkb21haW5cbiAgICAgICAgICogQHByb3BlcnR5IHtudW1iZXJ8TG9uZ3xudWxsfSBbbW9kZWxWZXJzaW9uXSBNb2RlbFByb3RvIG1vZGVsVmVyc2lvblxuICAgICAgICAgKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSBbZG9jU3RyaW5nXSBNb2RlbFByb3RvIGRvY1N0cmluZ1xuICAgICAgICAgKiBAcHJvcGVydHkge29ubnguSUdyYXBoUHJvdG98bnVsbH0gW2dyYXBoXSBNb2RlbFByb3RvIGdyYXBoXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSVN0cmluZ1N0cmluZ0VudHJ5UHJvdG8+fG51bGx9IFttZXRhZGF0YVByb3BzXSBNb2RlbFByb3RvIG1ldGFkYXRhUHJvcHNcbiAgICAgICAgICovXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENvbnN0cnVjdHMgYSBuZXcgTW9kZWxQcm90by5cbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgICAgICogQGNsYXNzZGVzYyBSZXByZXNlbnRzIGEgTW9kZWxQcm90by5cbiAgICAgICAgICogQGltcGxlbWVudHMgSU1vZGVsUHJvdG9cbiAgICAgICAgICogQGNvbnN0cnVjdG9yXG4gICAgICAgICAqIEBwYXJhbSB7b25ueC5JTW9kZWxQcm90bz19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAgICAgKi9cbiAgICAgICAgZnVuY3Rpb24gTW9kZWxQcm90byhwcm9wZXJ0aWVzKSB7XG4gICAgICAgICAgICB0aGlzLm9wc2V0SW1wb3J0ID0gW107XG4gICAgICAgICAgICB0aGlzLm1ldGFkYXRhUHJvcHMgPSBbXTtcbiAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzKVxuICAgICAgICAgICAgICAgIGZvciAodmFyIGtleXMgPSBPYmplY3Qua2V5cyhwcm9wZXJ0aWVzKSwgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICBpZiAocHJvcGVydGllc1trZXlzW2ldXSAhPSBudWxsKVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpc1trZXlzW2ldXSA9IHByb3BlcnRpZXNba2V5c1tpXV07XG4gICAgICAgIH1cblxuICAgICAgICAvKipcbiAgICAgICAgICogTW9kZWxQcm90byBpclZlcnNpb24uXG4gICAgICAgICAqIEBtZW1iZXIge251bWJlcnxMb25nfSBpclZlcnNpb25cbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguTW9kZWxQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIE1vZGVsUHJvdG8ucHJvdG90eXBlLmlyVmVyc2lvbiA9ICR1dGlsLkxvbmcgPyAkdXRpbC5Mb25nLmZyb21CaXRzKDAsMCxmYWxzZSkgOiAwO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBNb2RlbFByb3RvIG9wc2V0SW1wb3J0LlxuICAgICAgICAgKiBAbWVtYmVyIHtBcnJheS48b25ueC5JT3BlcmF0b3JTZXRJZFByb3RvPn0gb3BzZXRJbXBvcnRcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguTW9kZWxQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIE1vZGVsUHJvdG8ucHJvdG90eXBlLm9wc2V0SW1wb3J0ID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogTW9kZWxQcm90byBwcm9kdWNlck5hbWUuXG4gICAgICAgICAqIEBtZW1iZXIge3N0cmluZ30gcHJvZHVjZXJOYW1lXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54Lk1vZGVsUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBNb2RlbFByb3RvLnByb3RvdHlwZS5wcm9kdWNlck5hbWUgPSBcIlwiO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBNb2RlbFByb3RvIHByb2R1Y2VyVmVyc2lvbi5cbiAgICAgICAgICogQG1lbWJlciB7c3RyaW5nfSBwcm9kdWNlclZlcnNpb25cbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguTW9kZWxQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIE1vZGVsUHJvdG8ucHJvdG90eXBlLnByb2R1Y2VyVmVyc2lvbiA9IFwiXCI7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIE1vZGVsUHJvdG8gZG9tYWluLlxuICAgICAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IGRvbWFpblxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5Nb2RlbFByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgTW9kZWxQcm90by5wcm90b3R5cGUuZG9tYWluID0gXCJcIjtcblxuICAgICAgICAvKipcbiAgICAgICAgICogTW9kZWxQcm90byBtb2RlbFZlcnNpb24uXG4gICAgICAgICAqIEBtZW1iZXIge251bWJlcnxMb25nfSBtb2RlbFZlcnNpb25cbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguTW9kZWxQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIE1vZGVsUHJvdG8ucHJvdG90eXBlLm1vZGVsVmVyc2lvbiA9ICR1dGlsLkxvbmcgPyAkdXRpbC5Mb25nLmZyb21CaXRzKDAsMCxmYWxzZSkgOiAwO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBNb2RlbFByb3RvIGRvY1N0cmluZy5cbiAgICAgICAgICogQG1lbWJlciB7c3RyaW5nfSBkb2NTdHJpbmdcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguTW9kZWxQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIE1vZGVsUHJvdG8ucHJvdG90eXBlLmRvY1N0cmluZyA9IFwiXCI7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIE1vZGVsUHJvdG8gZ3JhcGguXG4gICAgICAgICAqIEBtZW1iZXIge29ubnguSUdyYXBoUHJvdG98bnVsbHx1bmRlZmluZWR9IGdyYXBoXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54Lk1vZGVsUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBNb2RlbFByb3RvLnByb3RvdHlwZS5ncmFwaCA9IG51bGw7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIE1vZGVsUHJvdG8gbWV0YWRhdGFQcm9wcy5cbiAgICAgICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguSVN0cmluZ1N0cmluZ0VudHJ5UHJvdG8+fSBtZXRhZGF0YVByb3BzXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54Lk1vZGVsUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBNb2RlbFByb3RvLnByb3RvdHlwZS5tZXRhZGF0YVByb3BzID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ3JlYXRlcyBhIG5ldyBNb2RlbFByb3RvIGluc3RhbmNlIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHJvcGVydGllcy5cbiAgICAgICAgICogQGZ1bmN0aW9uIGNyZWF0ZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5Nb2RlbFByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtvbm54LklNb2RlbFByb3RvPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICAgICAqIEByZXR1cm5zIHtvbm54Lk1vZGVsUHJvdG99IE1vZGVsUHJvdG8gaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIE1vZGVsUHJvdG8uY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKHByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgTW9kZWxQcm90byhwcm9wZXJ0aWVzKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIE1vZGVsUHJvdG8gbWVzc2FnZS4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5Nb2RlbFByb3RvLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54Lk1vZGVsUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge29ubnguSU1vZGVsUHJvdG99IG1lc3NhZ2UgTW9kZWxQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgICAgICovXG4gICAgICAgIE1vZGVsUHJvdG8uZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgICAgICAgaWYgKCF3cml0ZXIpXG4gICAgICAgICAgICAgICAgd3JpdGVyID0gJFdyaXRlci5jcmVhdGUoKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmlyVmVyc2lvbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJpclZlcnNpb25cIikpXG4gICAgICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxLCB3aXJlVHlwZSAwID0qLzgpLmludDY0KG1lc3NhZ2UuaXJWZXJzaW9uKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnByb2R1Y2VyTmFtZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJwcm9kdWNlck5hbWVcIikpXG4gICAgICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAyLCB3aXJlVHlwZSAyID0qLzE4KS5zdHJpbmcobWVzc2FnZS5wcm9kdWNlck5hbWUpO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UucHJvZHVjZXJWZXJzaW9uICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcInByb2R1Y2VyVmVyc2lvblwiKSlcbiAgICAgICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDMsIHdpcmVUeXBlIDIgPSovMjYpLnN0cmluZyhtZXNzYWdlLnByb2R1Y2VyVmVyc2lvbik7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5kb21haW4gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiZG9tYWluXCIpKVxuICAgICAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgNCwgd2lyZVR5cGUgMiA9Ki8zNCkuc3RyaW5nKG1lc3NhZ2UuZG9tYWluKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLm1vZGVsVmVyc2lvbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJtb2RlbFZlcnNpb25cIikpXG4gICAgICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCA1LCB3aXJlVHlwZSAwID0qLzQwKS5pbnQ2NChtZXNzYWdlLm1vZGVsVmVyc2lvbik7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5kb2NTdHJpbmcgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiZG9jU3RyaW5nXCIpKVxuICAgICAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgNiwgd2lyZVR5cGUgMiA9Ki81MCkuc3RyaW5nKG1lc3NhZ2UuZG9jU3RyaW5nKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmdyYXBoICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImdyYXBoXCIpKVxuICAgICAgICAgICAgICAgICRyb290Lm9ubnguR3JhcGhQcm90by5lbmNvZGUobWVzc2FnZS5ncmFwaCwgd3JpdGVyLnVpbnQzMigvKiBpZCA3LCB3aXJlVHlwZSAyID0qLzU4KS5mb3JrKCkpLmxkZWxpbSgpO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2Uub3BzZXRJbXBvcnQgIT0gbnVsbCAmJiBtZXNzYWdlLm9wc2V0SW1wb3J0Lmxlbmd0aClcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2Uub3BzZXRJbXBvcnQubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgICRyb290Lm9ubnguT3BlcmF0b3JTZXRJZFByb3RvLmVuY29kZShtZXNzYWdlLm9wc2V0SW1wb3J0W2ldLCB3cml0ZXIudWludDMyKC8qIGlkIDgsIHdpcmVUeXBlIDIgPSovNjYpLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5tZXRhZGF0YVByb3BzICE9IG51bGwgJiYgbWVzc2FnZS5tZXRhZGF0YVByb3BzLmxlbmd0aClcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UubWV0YWRhdGFQcm9wcy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgJHJvb3Qub25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvLmVuY29kZShtZXNzYWdlLm1ldGFkYXRhUHJvcHNbaV0sIHdyaXRlci51aW50MzIoLyogaWQgMTQsIHdpcmVUeXBlIDIgPSovMTE0KS5mb3JrKCkpLmxkZWxpbSgpO1xuICAgICAgICAgICAgcmV0dXJuIHdyaXRlcjtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIE1vZGVsUHJvdG8gbWVzc2FnZSwgbGVuZ3RoIGRlbGltaXRlZC4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5Nb2RlbFByb3RvLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54Lk1vZGVsUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge29ubnguSU1vZGVsUHJvdG99IG1lc3NhZ2UgTW9kZWxQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgICAgICovXG4gICAgICAgIE1vZGVsUHJvdG8uZW5jb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikubGRlbGltKCk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIERlY29kZXMgYSBNb2RlbFByb3RvIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIuXG4gICAgICAgICAqIEBmdW5jdGlvbiBkZWNvZGVcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguTW9kZWxQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aF0gTWVzc2FnZSBsZW5ndGggaWYga25vd24gYmVmb3JlaGFuZFxuICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5Nb2RlbFByb3RvfSBNb2RlbFByb3RvXG4gICAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAgICAgKi9cbiAgICAgICAgTW9kZWxQcm90by5kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUocmVhZGVyLCBsZW5ndGgpIHtcbiAgICAgICAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKVxuICAgICAgICAgICAgICAgIHJlYWRlciA9ICRSZWFkZXIuY3JlYXRlKHJlYWRlcik7XG4gICAgICAgICAgICB2YXIgZW5kID0gbGVuZ3RoID09PSB1bmRlZmluZWQgPyByZWFkZXIubGVuIDogcmVhZGVyLnBvcyArIGxlbmd0aCwgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54Lk1vZGVsUHJvdG8oKTtcbiAgICAgICAgICAgIHdoaWxlIChyZWFkZXIucG9zIDwgZW5kKSB7XG4gICAgICAgICAgICAgICAgdmFyIHRhZyA9IHJlYWRlci51aW50MzIoKTtcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKHRhZyA+Pj4gMykge1xuICAgICAgICAgICAgICAgIGNhc2UgMTpcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5pclZlcnNpb24gPSByZWFkZXIuaW50NjQoKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSA4OlxuICAgICAgICAgICAgICAgICAgICBpZiAoIShtZXNzYWdlLm9wc2V0SW1wb3J0ICYmIG1lc3NhZ2Uub3BzZXRJbXBvcnQubGVuZ3RoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2Uub3BzZXRJbXBvcnQgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5vcHNldEltcG9ydC5wdXNoKCRyb290Lm9ubnguT3BlcmF0b3JTZXRJZFByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSkpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UucHJvZHVjZXJOYW1lID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UucHJvZHVjZXJWZXJzaW9uID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZG9tYWluID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIDU6XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UubW9kZWxWZXJzaW9uID0gcmVhZGVyLmludDY0KCk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgNjpcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5kb2NTdHJpbmcgPSByZWFkZXIuc3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgNzpcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5ncmFwaCA9ICRyb290Lm9ubnguR3JhcGhQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIDE0OlxuICAgICAgICAgICAgICAgICAgICBpZiAoIShtZXNzYWdlLm1ldGFkYXRhUHJvcHMgJiYgbWVzc2FnZS5tZXRhZGF0YVByb3BzLmxlbmd0aCkpXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLm1ldGFkYXRhUHJvcHMgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5tZXRhZGF0YVByb3BzLnB1c2goJHJvb3Qub25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSkpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICByZWFkZXIuc2tpcFR5cGUodGFnICYgNyk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEZWNvZGVzIGEgTW9kZWxQcm90byBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLCBsZW5ndGggZGVsaW1pdGVkLlxuICAgICAgICAgKiBAZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54Lk1vZGVsUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgICAgICogQHJldHVybnMge29ubnguTW9kZWxQcm90b30gTW9kZWxQcm90b1xuICAgICAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgICAgICovXG4gICAgICAgIE1vZGVsUHJvdG8uZGVjb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkKHJlYWRlcikge1xuICAgICAgICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpXG4gICAgICAgICAgICAgICAgcmVhZGVyID0gbmV3ICRSZWFkZXIocmVhZGVyKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFZlcmlmaWVzIGEgTW9kZWxQcm90byBtZXNzYWdlLlxuICAgICAgICAgKiBAZnVuY3Rpb24gdmVyaWZ5XG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54Lk1vZGVsUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBtZXNzYWdlIFBsYWluIG9iamVjdCB0byB2ZXJpZnlcbiAgICAgICAgICogQHJldHVybnMge3N0cmluZ3xudWxsfSBgbnVsbGAgaWYgdmFsaWQsIG90aGVyd2lzZSB0aGUgcmVhc29uIHdoeSBpdCBpcyBub3RcbiAgICAgICAgICovXG4gICAgICAgIE1vZGVsUHJvdG8udmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1lc3NhZ2UpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSAhPT0gXCJvYmplY3RcIiB8fCBtZXNzYWdlID09PSBudWxsKVxuICAgICAgICAgICAgICAgIHJldHVybiBcIm9iamVjdCBleHBlY3RlZFwiO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuaXJWZXJzaW9uICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImlyVmVyc2lvblwiKSlcbiAgICAgICAgICAgICAgICBpZiAoISR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmlyVmVyc2lvbikgJiYgIShtZXNzYWdlLmlyVmVyc2lvbiAmJiAkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5pclZlcnNpb24ubG93KSAmJiAkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5pclZlcnNpb24uaGlnaCkpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJpclZlcnNpb246IGludGVnZXJ8TG9uZyBleHBlY3RlZFwiO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2Uub3BzZXRJbXBvcnQgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwib3BzZXRJbXBvcnRcIikpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5vcHNldEltcG9ydCkpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm9wc2V0SW1wb3J0OiBhcnJheSBleHBlY3RlZFwiO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5vcHNldEltcG9ydC5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54Lk9wZXJhdG9yU2V0SWRQcm90by52ZXJpZnkobWVzc2FnZS5vcHNldEltcG9ydFtpXSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcilcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm9wc2V0SW1wb3J0LlwiICsgZXJyb3I7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UucHJvZHVjZXJOYW1lICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcInByb2R1Y2VyTmFtZVwiKSlcbiAgICAgICAgICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UucHJvZHVjZXJOYW1lKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwicHJvZHVjZXJOYW1lOiBzdHJpbmcgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnByb2R1Y2VyVmVyc2lvbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJwcm9kdWNlclZlcnNpb25cIikpXG4gICAgICAgICAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLnByb2R1Y2VyVmVyc2lvbikpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcInByb2R1Y2VyVmVyc2lvbjogc3RyaW5nIGV4cGVjdGVkXCI7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5kb21haW4gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiZG9tYWluXCIpKVxuICAgICAgICAgICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5kb21haW4pKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJkb21haW46IHN0cmluZyBleHBlY3RlZFwiO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UubW9kZWxWZXJzaW9uICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcIm1vZGVsVmVyc2lvblwiKSlcbiAgICAgICAgICAgICAgICBpZiAoISR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLm1vZGVsVmVyc2lvbikgJiYgIShtZXNzYWdlLm1vZGVsVmVyc2lvbiAmJiAkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5tb2RlbFZlcnNpb24ubG93KSAmJiAkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5tb2RlbFZlcnNpb24uaGlnaCkpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJtb2RlbFZlcnNpb246IGludGVnZXJ8TG9uZyBleHBlY3RlZFwiO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZG9jU3RyaW5nICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImRvY1N0cmluZ1wiKSlcbiAgICAgICAgICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UuZG9jU3RyaW5nKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiZG9jU3RyaW5nOiBzdHJpbmcgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmdyYXBoICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImdyYXBoXCIpKSB7XG4gICAgICAgICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5HcmFwaFByb3RvLnZlcmlmeShtZXNzYWdlLmdyYXBoKTtcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcImdyYXBoLlwiICsgZXJyb3I7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5tZXRhZGF0YVByb3BzICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcIm1ldGFkYXRhUHJvcHNcIikpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5tZXRhZGF0YVByb3BzKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwibWV0YWRhdGFQcm9wczogYXJyYXkgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UubWV0YWRhdGFQcm9wcy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8udmVyaWZ5KG1lc3NhZ2UubWV0YWRhdGFQcm9wc1tpXSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcilcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm1ldGFkYXRhUHJvcHMuXCIgKyBlcnJvcjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ3JlYXRlcyBhIE1vZGVsUHJvdG8gbWVzc2FnZSBmcm9tIGEgcGxhaW4gb2JqZWN0LiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byB0aGVpciByZXNwZWN0aXZlIGludGVybmFsIHR5cGVzLlxuICAgICAgICAgKiBAZnVuY3Rpb24gZnJvbU9iamVjdFxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5Nb2RlbFByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gb2JqZWN0IFBsYWluIG9iamVjdFxuICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5Nb2RlbFByb3RvfSBNb2RlbFByb3RvXG4gICAgICAgICAqL1xuICAgICAgICBNb2RlbFByb3RvLmZyb21PYmplY3QgPSBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mICRyb290Lm9ubnguTW9kZWxQcm90bylcbiAgICAgICAgICAgICAgICByZXR1cm4gb2JqZWN0O1xuICAgICAgICAgICAgdmFyIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5Nb2RlbFByb3RvKCk7XG4gICAgICAgICAgICBpZiAob2JqZWN0LmlyVmVyc2lvbiAhPSBudWxsKVxuICAgICAgICAgICAgICAgIGlmICgkdXRpbC5Mb25nKVxuICAgICAgICAgICAgICAgICAgICAobWVzc2FnZS5pclZlcnNpb24gPSAkdXRpbC5Mb25nLmZyb21WYWx1ZShvYmplY3QuaXJWZXJzaW9uKSkudW5zaWduZWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LmlyVmVyc2lvbiA9PT0gXCJzdHJpbmdcIilcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5pclZlcnNpb24gPSBwYXJzZUludChvYmplY3QuaXJWZXJzaW9uLCAxMCk7XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5pclZlcnNpb24gPT09IFwibnVtYmVyXCIpXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuaXJWZXJzaW9uID0gb2JqZWN0LmlyVmVyc2lvbjtcbiAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LmlyVmVyc2lvbiA9PT0gXCJvYmplY3RcIilcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5pclZlcnNpb24gPSBuZXcgJHV0aWwuTG9uZ0JpdHMob2JqZWN0LmlyVmVyc2lvbi5sb3cgPj4+IDAsIG9iamVjdC5pclZlcnNpb24uaGlnaCA+Pj4gMCkudG9OdW1iZXIoKTtcbiAgICAgICAgICAgIGlmIChvYmplY3Qub3BzZXRJbXBvcnQpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0Lm9wc2V0SW1wb3J0KSlcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguTW9kZWxQcm90by5vcHNldEltcG9ydDogYXJyYXkgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgbWVzc2FnZS5vcHNldEltcG9ydCA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0Lm9wc2V0SW1wb3J0Lmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0Lm9wc2V0SW1wb3J0W2ldICE9PSBcIm9iamVjdFwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguTW9kZWxQcm90by5vcHNldEltcG9ydDogb2JqZWN0IGV4cGVjdGVkXCIpO1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLm9wc2V0SW1wb3J0W2ldID0gJHJvb3Qub25ueC5PcGVyYXRvclNldElkUHJvdG8uZnJvbU9iamVjdChvYmplY3Qub3BzZXRJbXBvcnRbaV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChvYmplY3QucHJvZHVjZXJOYW1lICE9IG51bGwpXG4gICAgICAgICAgICAgICAgbWVzc2FnZS5wcm9kdWNlck5hbWUgPSBTdHJpbmcob2JqZWN0LnByb2R1Y2VyTmFtZSk7XG4gICAgICAgICAgICBpZiAob2JqZWN0LnByb2R1Y2VyVmVyc2lvbiAhPSBudWxsKVxuICAgICAgICAgICAgICAgIG1lc3NhZ2UucHJvZHVjZXJWZXJzaW9uID0gU3RyaW5nKG9iamVjdC5wcm9kdWNlclZlcnNpb24pO1xuICAgICAgICAgICAgaWYgKG9iamVjdC5kb21haW4gIT0gbnVsbClcbiAgICAgICAgICAgICAgICBtZXNzYWdlLmRvbWFpbiA9IFN0cmluZyhvYmplY3QuZG9tYWluKTtcbiAgICAgICAgICAgIGlmIChvYmplY3QubW9kZWxWZXJzaW9uICE9IG51bGwpXG4gICAgICAgICAgICAgICAgaWYgKCR1dGlsLkxvbmcpXG4gICAgICAgICAgICAgICAgICAgIChtZXNzYWdlLm1vZGVsVmVyc2lvbiA9ICR1dGlsLkxvbmcuZnJvbVZhbHVlKG9iamVjdC5tb2RlbFZlcnNpb24pKS51bnNpZ25lZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QubW9kZWxWZXJzaW9uID09PSBcInN0cmluZ1wiKVxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLm1vZGVsVmVyc2lvbiA9IHBhcnNlSW50KG9iamVjdC5tb2RlbFZlcnNpb24sIDEwKTtcbiAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0Lm1vZGVsVmVyc2lvbiA9PT0gXCJudW1iZXJcIilcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5tb2RlbFZlcnNpb24gPSBvYmplY3QubW9kZWxWZXJzaW9uO1xuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QubW9kZWxWZXJzaW9uID09PSBcIm9iamVjdFwiKVxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLm1vZGVsVmVyc2lvbiA9IG5ldyAkdXRpbC5Mb25nQml0cyhvYmplY3QubW9kZWxWZXJzaW9uLmxvdyA+Pj4gMCwgb2JqZWN0Lm1vZGVsVmVyc2lvbi5oaWdoID4+PiAwKS50b051bWJlcigpO1xuICAgICAgICAgICAgaWYgKG9iamVjdC5kb2NTdHJpbmcgIT0gbnVsbClcbiAgICAgICAgICAgICAgICBtZXNzYWdlLmRvY1N0cmluZyA9IFN0cmluZyhvYmplY3QuZG9jU3RyaW5nKTtcbiAgICAgICAgICAgIGlmIChvYmplY3QuZ3JhcGggIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LmdyYXBoICE9PSBcIm9iamVjdFwiKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5Nb2RlbFByb3RvLmdyYXBoOiBvYmplY3QgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgbWVzc2FnZS5ncmFwaCA9ICRyb290Lm9ubnguR3JhcGhQcm90by5mcm9tT2JqZWN0KG9iamVjdC5ncmFwaCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob2JqZWN0Lm1ldGFkYXRhUHJvcHMpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0Lm1ldGFkYXRhUHJvcHMpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5Nb2RlbFByb3RvLm1ldGFkYXRhUHJvcHM6IGFycmF5IGV4cGVjdGVkXCIpO1xuICAgICAgICAgICAgICAgIG1lc3NhZ2UubWV0YWRhdGFQcm9wcyA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0Lm1ldGFkYXRhUHJvcHMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QubWV0YWRhdGFQcm9wc1tpXSAhPT0gXCJvYmplY3RcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIi5vbm54Lk1vZGVsUHJvdG8ubWV0YWRhdGFQcm9wczogb2JqZWN0IGV4cGVjdGVkXCIpO1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLm1ldGFkYXRhUHJvcHNbaV0gPSAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uZnJvbU9iamVjdChvYmplY3QubWV0YWRhdGFQcm9wc1tpXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENyZWF0ZXMgYSBwbGFpbiBvYmplY3QgZnJvbSBhIE1vZGVsUHJvdG8gbWVzc2FnZS4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gb3RoZXIgdHlwZXMgaWYgc3BlY2lmaWVkLlxuICAgICAgICAgKiBAZnVuY3Rpb24gdG9PYmplY3RcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguTW9kZWxQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7b25ueC5Nb2RlbFByb3RvfSBtZXNzYWdlIE1vZGVsUHJvdG9cbiAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuSUNvbnZlcnNpb25PcHRpb25zfSBbb3B0aW9uc10gQ29udmVyc2lvbiBvcHRpb25zXG4gICAgICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gUGxhaW4gb2JqZWN0XG4gICAgICAgICAqL1xuICAgICAgICBNb2RlbFByb3RvLnRvT2JqZWN0ID0gZnVuY3Rpb24gdG9PYmplY3QobWVzc2FnZSwgb3B0aW9ucykge1xuICAgICAgICAgICAgaWYgKCFvcHRpb25zKVxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICAgICAgICAgIHZhciBvYmplY3QgPSB7fTtcbiAgICAgICAgICAgIGlmIChvcHRpb25zLmFycmF5cyB8fCBvcHRpb25zLmRlZmF1bHRzKSB7XG4gICAgICAgICAgICAgICAgb2JqZWN0Lm9wc2V0SW1wb3J0ID0gW107XG4gICAgICAgICAgICAgICAgb2JqZWN0Lm1ldGFkYXRhUHJvcHMgPSBbXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChvcHRpb25zLmRlZmF1bHRzKSB7XG4gICAgICAgICAgICAgICAgaWYgKCR1dGlsLkxvbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGxvbmcgPSBuZXcgJHV0aWwuTG9uZygwLCAwLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC5pclZlcnNpb24gPSBvcHRpb25zLmxvbmdzID09PSBTdHJpbmcgPyBsb25nLnRvU3RyaW5nKCkgOiBvcHRpb25zLmxvbmdzID09PSBOdW1iZXIgPyBsb25nLnRvTnVtYmVyKCkgOiBsb25nO1xuICAgICAgICAgICAgICAgIH0gZWxzZVxuICAgICAgICAgICAgICAgICAgICBvYmplY3QuaXJWZXJzaW9uID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gXCIwXCIgOiAwO1xuICAgICAgICAgICAgICAgIG9iamVjdC5wcm9kdWNlck5hbWUgPSBcIlwiO1xuICAgICAgICAgICAgICAgIG9iamVjdC5wcm9kdWNlclZlcnNpb24gPSBcIlwiO1xuICAgICAgICAgICAgICAgIG9iamVjdC5kb21haW4gPSBcIlwiO1xuICAgICAgICAgICAgICAgIGlmICgkdXRpbC5Mb25nKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBsb25nID0gbmV3ICR1dGlsLkxvbmcoMCwgMCwgZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICBvYmplY3QubW9kZWxWZXJzaW9uID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gbG9uZy50b1N0cmluZygpIDogb3B0aW9ucy5sb25ncyA9PT0gTnVtYmVyID8gbG9uZy50b051bWJlcigpIDogbG9uZztcbiAgICAgICAgICAgICAgICB9IGVsc2VcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0Lm1vZGVsVmVyc2lvbiA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/IFwiMFwiIDogMDtcbiAgICAgICAgICAgICAgICBvYmplY3QuZG9jU3RyaW5nID0gXCJcIjtcbiAgICAgICAgICAgICAgICBvYmplY3QuZ3JhcGggPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuaXJWZXJzaW9uICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImlyVmVyc2lvblwiKSlcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UuaXJWZXJzaW9uID09PSBcIm51bWJlclwiKVxuICAgICAgICAgICAgICAgICAgICBvYmplY3QuaXJWZXJzaW9uID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gU3RyaW5nKG1lc3NhZ2UuaXJWZXJzaW9uKSA6IG1lc3NhZ2UuaXJWZXJzaW9uO1xuICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LmlyVmVyc2lvbiA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/ICR1dGlsLkxvbmcucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobWVzc2FnZS5pclZlcnNpb24pIDogb3B0aW9ucy5sb25ncyA9PT0gTnVtYmVyID8gbmV3ICR1dGlsLkxvbmdCaXRzKG1lc3NhZ2UuaXJWZXJzaW9uLmxvdyA+Pj4gMCwgbWVzc2FnZS5pclZlcnNpb24uaGlnaCA+Pj4gMCkudG9OdW1iZXIoKSA6IG1lc3NhZ2UuaXJWZXJzaW9uO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UucHJvZHVjZXJOYW1lICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcInByb2R1Y2VyTmFtZVwiKSlcbiAgICAgICAgICAgICAgICBvYmplY3QucHJvZHVjZXJOYW1lID0gbWVzc2FnZS5wcm9kdWNlck5hbWU7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5wcm9kdWNlclZlcnNpb24gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwicHJvZHVjZXJWZXJzaW9uXCIpKVxuICAgICAgICAgICAgICAgIG9iamVjdC5wcm9kdWNlclZlcnNpb24gPSBtZXNzYWdlLnByb2R1Y2VyVmVyc2lvbjtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmRvbWFpbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJkb21haW5cIikpXG4gICAgICAgICAgICAgICAgb2JqZWN0LmRvbWFpbiA9IG1lc3NhZ2UuZG9tYWluO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UubW9kZWxWZXJzaW9uICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcIm1vZGVsVmVyc2lvblwiKSlcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UubW9kZWxWZXJzaW9uID09PSBcIm51bWJlclwiKVxuICAgICAgICAgICAgICAgICAgICBvYmplY3QubW9kZWxWZXJzaW9uID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gU3RyaW5nKG1lc3NhZ2UubW9kZWxWZXJzaW9uKSA6IG1lc3NhZ2UubW9kZWxWZXJzaW9uO1xuICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0Lm1vZGVsVmVyc2lvbiA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/ICR1dGlsLkxvbmcucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobWVzc2FnZS5tb2RlbFZlcnNpb24pIDogb3B0aW9ucy5sb25ncyA9PT0gTnVtYmVyID8gbmV3ICR1dGlsLkxvbmdCaXRzKG1lc3NhZ2UubW9kZWxWZXJzaW9uLmxvdyA+Pj4gMCwgbWVzc2FnZS5tb2RlbFZlcnNpb24uaGlnaCA+Pj4gMCkudG9OdW1iZXIoKSA6IG1lc3NhZ2UubW9kZWxWZXJzaW9uO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZG9jU3RyaW5nICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImRvY1N0cmluZ1wiKSlcbiAgICAgICAgICAgICAgICBvYmplY3QuZG9jU3RyaW5nID0gbWVzc2FnZS5kb2NTdHJpbmc7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5ncmFwaCAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJncmFwaFwiKSlcbiAgICAgICAgICAgICAgICBvYmplY3QuZ3JhcGggPSAkcm9vdC5vbm54LkdyYXBoUHJvdG8udG9PYmplY3QobWVzc2FnZS5ncmFwaCwgb3B0aW9ucyk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5vcHNldEltcG9ydCAmJiBtZXNzYWdlLm9wc2V0SW1wb3J0Lmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIG9iamVjdC5vcHNldEltcG9ydCA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5vcHNldEltcG9ydC5sZW5ndGg7ICsrailcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0Lm9wc2V0SW1wb3J0W2pdID0gJHJvb3Qub25ueC5PcGVyYXRvclNldElkUHJvdG8udG9PYmplY3QobWVzc2FnZS5vcHNldEltcG9ydFtqXSwgb3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5tZXRhZGF0YVByb3BzICYmIG1lc3NhZ2UubWV0YWRhdGFQcm9wcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBvYmplY3QubWV0YWRhdGFQcm9wcyA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5tZXRhZGF0YVByb3BzLmxlbmd0aDsgKytqKVxuICAgICAgICAgICAgICAgICAgICBvYmplY3QubWV0YWRhdGFQcm9wc1tqXSA9ICRyb290Lm9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90by50b09iamVjdChtZXNzYWdlLm1ldGFkYXRhUHJvcHNbal0sIG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ29udmVydHMgdGhpcyBNb2RlbFByb3RvIHRvIEpTT04uXG4gICAgICAgICAqIEBmdW5jdGlvbiB0b0pTT05cbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguTW9kZWxQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBKU09OIG9iamVjdFxuICAgICAgICAgKi9cbiAgICAgICAgTW9kZWxQcm90by5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IudG9PYmplY3QodGhpcywgJHByb3RvYnVmLnV0aWwudG9KU09OT3B0aW9ucyk7XG4gICAgICAgIH07XG5cbiAgICAgICAgcmV0dXJuIE1vZGVsUHJvdG87XG4gICAgfSkoKTtcblxuICAgIG9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90byA9IChmdW5jdGlvbigpIHtcblxuICAgICAgICAvKipcbiAgICAgICAgICogUHJvcGVydGllcyBvZiBhIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54XG4gICAgICAgICAqIEBpbnRlcmZhY2UgSVN0cmluZ1N0cmluZ0VudHJ5UHJvdG9cbiAgICAgICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW2tleV0gU3RyaW5nU3RyaW5nRW50cnlQcm90byBrZXlcbiAgICAgICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW3ZhbHVlXSBTdHJpbmdTdHJpbmdFbnRyeVByb3RvIHZhbHVlXG4gICAgICAgICAqL1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54XG4gICAgICAgICAqIEBjbGFzc2Rlc2MgUmVwcmVzZW50cyBhIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uXG4gICAgICAgICAqIEBpbXBsZW1lbnRzIElTdHJpbmdTdHJpbmdFbnRyeVByb3RvXG4gICAgICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAgICAgKiBAcGFyYW0ge29ubnguSVN0cmluZ1N0cmluZ0VudHJ5UHJvdG89fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgICAgICovXG4gICAgICAgIGZ1bmN0aW9uIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8ocHJvcGVydGllcykge1xuICAgICAgICAgICAgaWYgKHByb3BlcnRpZXMpXG4gICAgICAgICAgICAgICAgZm9yICh2YXIga2V5cyA9IE9iamVjdC5rZXlzKHByb3BlcnRpZXMpLCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzW2tleXNbaV1dICE9IG51bGwpXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzW2tleXNbaV1dID0gcHJvcGVydGllc1trZXlzW2ldXTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBTdHJpbmdTdHJpbmdFbnRyeVByb3RvIGtleS5cbiAgICAgICAgICogQG1lbWJlciB7c3RyaW5nfSBrZXlcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8ucHJvdG90eXBlLmtleSA9IFwiXCI7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8gdmFsdWUuXG4gICAgICAgICAqIEBtZW1iZXIge3N0cmluZ30gdmFsdWVcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8ucHJvdG90eXBlLnZhbHVlID0gXCJcIjtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ3JlYXRlcyBhIG5ldyBTdHJpbmdTdHJpbmdFbnRyeVByb3RvIGluc3RhbmNlIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHJvcGVydGllcy5cbiAgICAgICAgICogQGZ1bmN0aW9uIGNyZWF0ZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtvbm54LklTdHJpbmdTdHJpbmdFbnRyeVByb3RvPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICAgICAqIEByZXR1cm5zIHtvbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG99IFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8gaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKHByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgU3RyaW5nU3RyaW5nRW50cnlQcm90byhwcm9wZXJ0aWVzKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8gbWVzc2FnZS4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge29ubnguSVN0cmluZ1N0cmluZ0VudHJ5UHJvdG99IG1lc3NhZ2UgU3RyaW5nU3RyaW5nRW50cnlQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgICAgICovXG4gICAgICAgIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgICAgICAgaWYgKCF3cml0ZXIpXG4gICAgICAgICAgICAgICAgd3JpdGVyID0gJFdyaXRlci5jcmVhdGUoKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmtleSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJrZXlcIikpXG4gICAgICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxLCB3aXJlVHlwZSAyID0qLzEwKS5zdHJpbmcobWVzc2FnZS5rZXkpO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UudmFsdWUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwidmFsdWVcIikpXG4gICAgICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAyLCB3aXJlVHlwZSAyID0qLzE4KS5zdHJpbmcobWVzc2FnZS52YWx1ZSk7XG4gICAgICAgICAgICByZXR1cm4gd3JpdGVyO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgU3RyaW5nU3RyaW5nRW50cnlQcm90byBtZXNzYWdlLCBsZW5ndGggZGVsaW1pdGVkLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8udmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICAgICAqIEBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWRcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7b25ueC5JU3RyaW5nU3RyaW5nRW50cnlQcm90b30gbWVzc2FnZSBTdHJpbmdTdHJpbmdFbnRyeVByb3RvIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAgICAgKi9cbiAgICAgICAgU3RyaW5nU3RyaW5nRW50cnlQcm90by5lbmNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWQobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5lbmNvZGUobWVzc2FnZSwgd3JpdGVyKS5sZGVsaW0oKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRGVjb2RlcyBhIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlci5cbiAgICAgICAgICogQGZ1bmN0aW9uIGRlY29kZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoXSBNZXNzYWdlIGxlbmd0aCBpZiBrbm93biBiZWZvcmVoYW5kXG4gICAgICAgICAqIEByZXR1cm5zIHtvbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG99IFN0cmluZ1N0cmluZ0VudHJ5UHJvdG9cbiAgICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICAgICAqL1xuICAgICAgICBTdHJpbmdTdHJpbmdFbnRyeVByb3RvLmRlY29kZSA9IGZ1bmN0aW9uIGRlY29kZShyZWFkZXIsIGxlbmd0aCkge1xuICAgICAgICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpXG4gICAgICAgICAgICAgICAgcmVhZGVyID0gJFJlYWRlci5jcmVhdGUocmVhZGVyKTtcbiAgICAgICAgICAgIHZhciBlbmQgPSBsZW5ndGggPT09IHVuZGVmaW5lZCA/IHJlYWRlci5sZW4gOiByZWFkZXIucG9zICsgbGVuZ3RoLCBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90bygpO1xuICAgICAgICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQpIHtcbiAgICAgICAgICAgICAgICB2YXIgdGFnID0gcmVhZGVyLnVpbnQzMigpO1xuICAgICAgICAgICAgICAgIHN3aXRjaCAodGFnID4+PiAzKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAxOlxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmtleSA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAyOlxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnZhbHVlID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICByZWFkZXIuc2tpcFR5cGUodGFnICYgNyk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEZWNvZGVzIGEgU3RyaW5nU3RyaW5nRW50cnlQcm90byBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLCBsZW5ndGggZGVsaW1pdGVkLlxuICAgICAgICAgKiBAZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgICAgICogQHJldHVybnMge29ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90b30gU3RyaW5nU3RyaW5nRW50cnlQcm90b1xuICAgICAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgICAgICovXG4gICAgICAgIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uZGVjb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkKHJlYWRlcikge1xuICAgICAgICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpXG4gICAgICAgICAgICAgICAgcmVhZGVyID0gbmV3ICRSZWFkZXIocmVhZGVyKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFZlcmlmaWVzIGEgU3RyaW5nU3RyaW5nRW50cnlQcm90byBtZXNzYWdlLlxuICAgICAgICAgKiBAZnVuY3Rpb24gdmVyaWZ5XG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBtZXNzYWdlIFBsYWluIG9iamVjdCB0byB2ZXJpZnlcbiAgICAgICAgICogQHJldHVybnMge3N0cmluZ3xudWxsfSBgbnVsbGAgaWYgdmFsaWQsIG90aGVyd2lzZSB0aGUgcmVhc29uIHdoeSBpdCBpcyBub3RcbiAgICAgICAgICovXG4gICAgICAgIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8udmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1lc3NhZ2UpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSAhPT0gXCJvYmplY3RcIiB8fCBtZXNzYWdlID09PSBudWxsKVxuICAgICAgICAgICAgICAgIHJldHVybiBcIm9iamVjdCBleHBlY3RlZFwiO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2Uua2V5ICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImtleVwiKSlcbiAgICAgICAgICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2Uua2V5KSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwia2V5OiBzdHJpbmcgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnZhbHVlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcInZhbHVlXCIpKVxuICAgICAgICAgICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS52YWx1ZSkpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcInZhbHVlOiBzdHJpbmcgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDcmVhdGVzIGEgU3RyaW5nU3RyaW5nRW50cnlQcm90byBtZXNzYWdlIGZyb20gYSBwbGFpbiBvYmplY3QuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIHRoZWlyIHJlc3BlY3RpdmUgaW50ZXJuYWwgdHlwZXMuXG4gICAgICAgICAqIEBmdW5jdGlvbiBmcm9tT2JqZWN0XG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBvYmplY3QgUGxhaW4gb2JqZWN0XG4gICAgICAgICAqIEByZXR1cm5zIHtvbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG99IFN0cmluZ1N0cmluZ0VudHJ5UHJvdG9cbiAgICAgICAgICovXG4gICAgICAgIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uZnJvbU9iamVjdCA9IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgJHJvb3Qub25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvKVxuICAgICAgICAgICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICAgICAgICB2YXIgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8oKTtcbiAgICAgICAgICAgIGlmIChvYmplY3Qua2V5ICE9IG51bGwpXG4gICAgICAgICAgICAgICAgbWVzc2FnZS5rZXkgPSBTdHJpbmcob2JqZWN0LmtleSk7XG4gICAgICAgICAgICBpZiAob2JqZWN0LnZhbHVlICE9IG51bGwpXG4gICAgICAgICAgICAgICAgbWVzc2FnZS52YWx1ZSA9IFN0cmluZyhvYmplY3QudmFsdWUpO1xuICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENyZWF0ZXMgYSBwbGFpbiBvYmplY3QgZnJvbSBhIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8gbWVzc2FnZS4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gb3RoZXIgdHlwZXMgaWYgc3BlY2lmaWVkLlxuICAgICAgICAgKiBAZnVuY3Rpb24gdG9PYmplY3RcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7b25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvfSBtZXNzYWdlIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG9cbiAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuSUNvbnZlcnNpb25PcHRpb25zfSBbb3B0aW9uc10gQ29udmVyc2lvbiBvcHRpb25zXG4gICAgICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gUGxhaW4gb2JqZWN0XG4gICAgICAgICAqL1xuICAgICAgICBTdHJpbmdTdHJpbmdFbnRyeVByb3RvLnRvT2JqZWN0ID0gZnVuY3Rpb24gdG9PYmplY3QobWVzc2FnZSwgb3B0aW9ucykge1xuICAgICAgICAgICAgaWYgKCFvcHRpb25zKVxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICAgICAgICAgIHZhciBvYmplY3QgPSB7fTtcbiAgICAgICAgICAgIGlmIChvcHRpb25zLmRlZmF1bHRzKSB7XG4gICAgICAgICAgICAgICAgb2JqZWN0LmtleSA9IFwiXCI7XG4gICAgICAgICAgICAgICAgb2JqZWN0LnZhbHVlID0gXCJcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmtleSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJrZXlcIikpXG4gICAgICAgICAgICAgICAgb2JqZWN0LmtleSA9IG1lc3NhZ2Uua2V5O1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UudmFsdWUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwidmFsdWVcIikpXG4gICAgICAgICAgICAgICAgb2JqZWN0LnZhbHVlID0gbWVzc2FnZS52YWx1ZTtcbiAgICAgICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENvbnZlcnRzIHRoaXMgU3RyaW5nU3RyaW5nRW50cnlQcm90byB0byBKU09OLlxuICAgICAgICAgKiBAZnVuY3Rpb24gdG9KU09OXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gSlNPTiBvYmplY3RcbiAgICAgICAgICovXG4gICAgICAgIFN0cmluZ1N0cmluZ0VudHJ5UHJvdG8ucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLnRvT2JqZWN0KHRoaXMsICRwcm90b2J1Zi51dGlsLnRvSlNPTk9wdGlvbnMpO1xuICAgICAgICB9O1xuXG4gICAgICAgIHJldHVybiBTdHJpbmdTdHJpbmdFbnRyeVByb3RvO1xuICAgIH0pKCk7XG5cbiAgICBvbm54LlRlbnNvckFubm90YXRpb24gPSAoZnVuY3Rpb24oKSB7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFByb3BlcnRpZXMgb2YgYSBUZW5zb3JBbm5vdGF0aW9uLlxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAgICAgKiBAaW50ZXJmYWNlIElUZW5zb3JBbm5vdGF0aW9uXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFt0ZW5zb3JOYW1lXSBUZW5zb3JBbm5vdGF0aW9uIHRlbnNvck5hbWVcbiAgICAgICAgICogQHByb3BlcnR5IHtBcnJheS48b25ueC5JU3RyaW5nU3RyaW5nRW50cnlQcm90bz58bnVsbH0gW3F1YW50UGFyYW1ldGVyVGVuc29yTmFtZXNdIFRlbnNvckFubm90YXRpb24gcXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lc1xuICAgICAgICAgKi9cblxuICAgICAgICAvKipcbiAgICAgICAgICogQ29uc3RydWN0cyBhIG5ldyBUZW5zb3JBbm5vdGF0aW9uLlxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAgICAgKiBAY2xhc3NkZXNjIFJlcHJlc2VudHMgYSBUZW5zb3JBbm5vdGF0aW9uLlxuICAgICAgICAgKiBAaW1wbGVtZW50cyBJVGVuc29yQW5ub3RhdGlvblxuICAgICAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgICAgICogQHBhcmFtIHtvbm54LklUZW5zb3JBbm5vdGF0aW9uPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICAgICAqL1xuICAgICAgICBmdW5jdGlvbiBUZW5zb3JBbm5vdGF0aW9uKHByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgIHRoaXMucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lcyA9IFtdO1xuICAgICAgICAgICAgaWYgKHByb3BlcnRpZXMpXG4gICAgICAgICAgICAgICAgZm9yICh2YXIga2V5cyA9IE9iamVjdC5rZXlzKHByb3BlcnRpZXMpLCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzW2tleXNbaV1dICE9IG51bGwpXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzW2tleXNbaV1dID0gcHJvcGVydGllc1trZXlzW2ldXTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUZW5zb3JBbm5vdGF0aW9uIHRlbnNvck5hbWUuXG4gICAgICAgICAqIEBtZW1iZXIge3N0cmluZ30gdGVuc29yTmFtZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JBbm5vdGF0aW9uXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgVGVuc29yQW5ub3RhdGlvbi5wcm90b3R5cGUudGVuc29yTmFtZSA9IFwiXCI7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRlbnNvckFubm90YXRpb24gcXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lcy5cbiAgICAgICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguSVN0cmluZ1N0cmluZ0VudHJ5UHJvdG8+fSBxdWFudFBhcmFtZXRlclRlbnNvck5hbWVzXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvckFubm90YXRpb25cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBUZW5zb3JBbm5vdGF0aW9uLnByb3RvdHlwZS5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ3JlYXRlcyBhIG5ldyBUZW5zb3JBbm5vdGF0aW9uIGluc3RhbmNlIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHJvcGVydGllcy5cbiAgICAgICAgICogQGZ1bmN0aW9uIGNyZWF0ZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JBbm5vdGF0aW9uXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtvbm54LklUZW5zb3JBbm5vdGF0aW9uPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICAgICAqIEByZXR1cm5zIHtvbm54LlRlbnNvckFubm90YXRpb259IFRlbnNvckFubm90YXRpb24gaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIFRlbnNvckFubm90YXRpb24uY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKHByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgVGVuc29yQW5ub3RhdGlvbihwcm9wZXJ0aWVzKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIFRlbnNvckFubm90YXRpb24gbWVzc2FnZS4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5UZW5zb3JBbm5vdGF0aW9uLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvckFubm90YXRpb25cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge29ubnguSVRlbnNvckFubm90YXRpb259IG1lc3NhZ2UgVGVuc29yQW5ub3RhdGlvbiBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgICAgICovXG4gICAgICAgIFRlbnNvckFubm90YXRpb24uZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgICAgICAgaWYgKCF3cml0ZXIpXG4gICAgICAgICAgICAgICAgd3JpdGVyID0gJFdyaXRlci5jcmVhdGUoKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnRlbnNvck5hbWUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwidGVuc29yTmFtZVwiKSlcbiAgICAgICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDEsIHdpcmVUeXBlIDIgPSovMTApLnN0cmluZyhtZXNzYWdlLnRlbnNvck5hbWUpO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lcyAhPSBudWxsICYmIG1lc3NhZ2UucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lcy5sZW5ndGgpXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgICRyb290Lm9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90by5lbmNvZGUobWVzc2FnZS5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzW2ldLCB3cml0ZXIudWludDMyKC8qIGlkIDIsIHdpcmVUeXBlIDIgPSovMTgpLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICAgICAgICByZXR1cm4gd3JpdGVyO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgVGVuc29yQW5ub3RhdGlvbiBtZXNzYWdlLCBsZW5ndGggZGVsaW1pdGVkLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlRlbnNvckFubm90YXRpb24udmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICAgICAqIEBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWRcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yQW5ub3RhdGlvblxuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7b25ueC5JVGVuc29yQW5ub3RhdGlvbn0gbWVzc2FnZSBUZW5zb3JBbm5vdGF0aW9uIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAgICAgKi9cbiAgICAgICAgVGVuc29yQW5ub3RhdGlvbi5lbmNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWQobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5lbmNvZGUobWVzc2FnZSwgd3JpdGVyKS5sZGVsaW0oKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRGVjb2RlcyBhIFRlbnNvckFubm90YXRpb24gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlci5cbiAgICAgICAgICogQGZ1bmN0aW9uIGRlY29kZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JBbm5vdGF0aW9uXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoXSBNZXNzYWdlIGxlbmd0aCBpZiBrbm93biBiZWZvcmVoYW5kXG4gICAgICAgICAqIEByZXR1cm5zIHtvbm54LlRlbnNvckFubm90YXRpb259IFRlbnNvckFubm90YXRpb25cbiAgICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICAgICAqL1xuICAgICAgICBUZW5zb3JBbm5vdGF0aW9uLmRlY29kZSA9IGZ1bmN0aW9uIGRlY29kZShyZWFkZXIsIGxlbmd0aCkge1xuICAgICAgICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpXG4gICAgICAgICAgICAgICAgcmVhZGVyID0gJFJlYWRlci5jcmVhdGUocmVhZGVyKTtcbiAgICAgICAgICAgIHZhciBlbmQgPSBsZW5ndGggPT09IHVuZGVmaW5lZCA/IHJlYWRlci5sZW4gOiByZWFkZXIucG9zICsgbGVuZ3RoLCBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVGVuc29yQW5ub3RhdGlvbigpO1xuICAgICAgICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQpIHtcbiAgICAgICAgICAgICAgICB2YXIgdGFnID0gcmVhZGVyLnVpbnQzMigpO1xuICAgICAgICAgICAgICAgIHN3aXRjaCAodGFnID4+PiAzKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAxOlxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnRlbnNvck5hbWUgPSByZWFkZXIuc3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgMjpcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzICYmIG1lc3NhZ2UucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lcy5sZW5ndGgpKVxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzID0gW107XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lcy5wdXNoKCRyb290Lm9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90by5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgcmVhZGVyLnNraXBUeXBlKHRhZyAmIDcpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRGVjb2RlcyBhIFRlbnNvckFubm90YXRpb24gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlciwgbGVuZ3RoIGRlbGltaXRlZC5cbiAgICAgICAgICogQGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZFxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JBbm5vdGF0aW9uXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICAgICAqIEByZXR1cm5zIHtvbm54LlRlbnNvckFubm90YXRpb259IFRlbnNvckFubm90YXRpb25cbiAgICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICAgICAqL1xuICAgICAgICBUZW5zb3JBbm5vdGF0aW9uLmRlY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZChyZWFkZXIpIHtcbiAgICAgICAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKVxuICAgICAgICAgICAgICAgIHJlYWRlciA9IG5ldyAkUmVhZGVyKHJlYWRlcik7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBWZXJpZmllcyBhIFRlbnNvckFubm90YXRpb24gbWVzc2FnZS5cbiAgICAgICAgICogQGZ1bmN0aW9uIHZlcmlmeVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JBbm5vdGF0aW9uXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gbWVzc2FnZSBQbGFpbiBvYmplY3QgdG8gdmVyaWZ5XG4gICAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd8bnVsbH0gYG51bGxgIGlmIHZhbGlkLCBvdGhlcndpc2UgdGhlIHJlYXNvbiB3aHkgaXQgaXMgbm90XG4gICAgICAgICAqL1xuICAgICAgICBUZW5zb3JBbm5vdGF0aW9uLnZlcmlmeSA9IGZ1bmN0aW9uIHZlcmlmeShtZXNzYWdlKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UgIT09IFwib2JqZWN0XCIgfHwgbWVzc2FnZSA9PT0gbnVsbClcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJvYmplY3QgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnRlbnNvck5hbWUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwidGVuc29yTmFtZVwiKSlcbiAgICAgICAgICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UudGVuc29yTmFtZSkpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcInRlbnNvck5hbWU6IHN0cmluZyBleHBlY3RlZFwiO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lcyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJxdWFudFBhcmFtZXRlclRlbnNvck5hbWVzXCIpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2UucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lcykpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcInF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXM6IGFycmF5IGV4cGVjdGVkXCI7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvLnZlcmlmeShtZXNzYWdlLnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXNbaV0pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJxdWFudFBhcmFtZXRlclRlbnNvck5hbWVzLlwiICsgZXJyb3I7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENyZWF0ZXMgYSBUZW5zb3JBbm5vdGF0aW9uIG1lc3NhZ2UgZnJvbSBhIHBsYWluIG9iamVjdC4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gdGhlaXIgcmVzcGVjdGl2ZSBpbnRlcm5hbCB0eXBlcy5cbiAgICAgICAgICogQGZ1bmN0aW9uIGZyb21PYmplY3RcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yQW5ub3RhdGlvblxuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG9iamVjdCBQbGFpbiBvYmplY3RcbiAgICAgICAgICogQHJldHVybnMge29ubnguVGVuc29yQW5ub3RhdGlvbn0gVGVuc29yQW5ub3RhdGlvblxuICAgICAgICAgKi9cbiAgICAgICAgVGVuc29yQW5ub3RhdGlvbi5mcm9tT2JqZWN0ID0gZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgICAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiAkcm9vdC5vbm54LlRlbnNvckFubm90YXRpb24pXG4gICAgICAgICAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgICAgICAgIHZhciBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVGVuc29yQW5ub3RhdGlvbigpO1xuICAgICAgICAgICAgaWYgKG9iamVjdC50ZW5zb3JOYW1lICE9IG51bGwpXG4gICAgICAgICAgICAgICAgbWVzc2FnZS50ZW5zb3JOYW1lID0gU3RyaW5nKG9iamVjdC50ZW5zb3JOYW1lKTtcbiAgICAgICAgICAgIGlmIChvYmplY3QucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lcykge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lcykpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIi5vbm54LlRlbnNvckFubm90YXRpb24ucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lczogYXJyYXkgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgbWVzc2FnZS5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lcy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzW2ldICE9PSBcIm9iamVjdFwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguVGVuc29yQW5ub3RhdGlvbi5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzOiBvYmplY3QgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lc1tpXSA9ICRyb290Lm9ubnguU3RyaW5nU3RyaW5nRW50cnlQcm90by5mcm9tT2JqZWN0KG9iamVjdC5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzW2ldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ3JlYXRlcyBhIHBsYWluIG9iamVjdCBmcm9tIGEgVGVuc29yQW5ub3RhdGlvbiBtZXNzYWdlLiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byBvdGhlciB0eXBlcyBpZiBzcGVjaWZpZWQuXG4gICAgICAgICAqIEBmdW5jdGlvbiB0b09iamVjdFxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JBbm5vdGF0aW9uXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtvbm54LlRlbnNvckFubm90YXRpb259IG1lc3NhZ2UgVGVuc29yQW5ub3RhdGlvblxuICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5JQ29udmVyc2lvbk9wdGlvbnN9IFtvcHRpb25zXSBDb252ZXJzaW9uIG9wdGlvbnNcbiAgICAgICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBQbGFpbiBvYmplY3RcbiAgICAgICAgICovXG4gICAgICAgIFRlbnNvckFubm90YXRpb24udG9PYmplY3QgPSBmdW5jdGlvbiB0b09iamVjdChtZXNzYWdlLCBvcHRpb25zKSB7XG4gICAgICAgICAgICBpZiAoIW9wdGlvbnMpXG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IHt9O1xuICAgICAgICAgICAgdmFyIG9iamVjdCA9IHt9O1xuICAgICAgICAgICAgaWYgKG9wdGlvbnMuYXJyYXlzIHx8IG9wdGlvbnMuZGVmYXVsdHMpXG4gICAgICAgICAgICAgICAgb2JqZWN0LnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXMgPSBbXTtcbiAgICAgICAgICAgIGlmIChvcHRpb25zLmRlZmF1bHRzKVxuICAgICAgICAgICAgICAgIG9iamVjdC50ZW5zb3JOYW1lID0gXCJcIjtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnRlbnNvck5hbWUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwidGVuc29yTmFtZVwiKSlcbiAgICAgICAgICAgICAgICBvYmplY3QudGVuc29yTmFtZSA9IG1lc3NhZ2UudGVuc29yTmFtZTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXMgJiYgbWVzc2FnZS5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIG9iamVjdC5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLnF1YW50UGFyYW1ldGVyVGVuc29yTmFtZXMubGVuZ3RoOyArK2opXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC5xdWFudFBhcmFtZXRlclRlbnNvck5hbWVzW2pdID0gJHJvb3Qub25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvLnRvT2JqZWN0KG1lc3NhZ2UucXVhbnRQYXJhbWV0ZXJUZW5zb3JOYW1lc1tqXSwgb3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gb2JqZWN0O1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDb252ZXJ0cyB0aGlzIFRlbnNvckFubm90YXRpb24gdG8gSlNPTi5cbiAgICAgICAgICogQGZ1bmN0aW9uIHRvSlNPTlxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JBbm5vdGF0aW9uXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IEpTT04gb2JqZWN0XG4gICAgICAgICAqL1xuICAgICAgICBUZW5zb3JBbm5vdGF0aW9uLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04oKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci50b09iamVjdCh0aGlzLCAkcHJvdG9idWYudXRpbC50b0pTT05PcHRpb25zKTtcbiAgICAgICAgfTtcblxuICAgICAgICByZXR1cm4gVGVuc29yQW5ub3RhdGlvbjtcbiAgICB9KSgpO1xuXG4gICAgb25ueC5HcmFwaFByb3RvID0gKGZ1bmN0aW9uKCkge1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBQcm9wZXJ0aWVzIG9mIGEgR3JhcGhQcm90by5cbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgICAgICogQGludGVyZmFjZSBJR3JhcGhQcm90b1xuICAgICAgICAgKiBAcHJvcGVydHkge0FycmF5Ljxvbm54LklOb2RlUHJvdG8+fG51bGx9IFtub2RlXSBHcmFwaFByb3RvIG5vZGVcbiAgICAgICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW25hbWVdIEdyYXBoUHJvdG8gbmFtZVxuICAgICAgICAgKiBAcHJvcGVydHkge0FycmF5Ljxvbm54LklUZW5zb3JQcm90bz58bnVsbH0gW2luaXRpYWxpemVyXSBHcmFwaFByb3RvIGluaXRpYWxpemVyXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtkb2NTdHJpbmddIEdyYXBoUHJvdG8gZG9jU3RyaW5nXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSVZhbHVlSW5mb1Byb3RvPnxudWxsfSBbaW5wdXRdIEdyYXBoUHJvdG8gaW5wdXRcbiAgICAgICAgICogQHByb3BlcnR5IHtBcnJheS48b25ueC5JVmFsdWVJbmZvUHJvdG8+fG51bGx9IFtvdXRwdXRdIEdyYXBoUHJvdG8gb3V0cHV0XG4gICAgICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG9ubnguSVZhbHVlSW5mb1Byb3RvPnxudWxsfSBbdmFsdWVJbmZvXSBHcmFwaFByb3RvIHZhbHVlSW5mb1xuICAgICAgICAgKiBAcHJvcGVydHkge0FycmF5Ljxvbm54LklUZW5zb3JBbm5vdGF0aW9uPnxudWxsfSBbcXVhbnRpemF0aW9uQW5ub3RhdGlvbl0gR3JhcGhQcm90byBxdWFudGl6YXRpb25Bbm5vdGF0aW9uXG4gICAgICAgICAqL1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IEdyYXBoUHJvdG8uXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54XG4gICAgICAgICAqIEBjbGFzc2Rlc2MgUmVwcmVzZW50cyBhIEdyYXBoUHJvdG8uXG4gICAgICAgICAqIEBpbXBsZW1lbnRzIElHcmFwaFByb3RvXG4gICAgICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAgICAgKiBAcGFyYW0ge29ubnguSUdyYXBoUHJvdG89fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgICAgICovXG4gICAgICAgIGZ1bmN0aW9uIEdyYXBoUHJvdG8ocHJvcGVydGllcykge1xuICAgICAgICAgICAgdGhpcy5ub2RlID0gW107XG4gICAgICAgICAgICB0aGlzLmluaXRpYWxpemVyID0gW107XG4gICAgICAgICAgICB0aGlzLmlucHV0ID0gW107XG4gICAgICAgICAgICB0aGlzLm91dHB1dCA9IFtdO1xuICAgICAgICAgICAgdGhpcy52YWx1ZUluZm8gPSBbXTtcbiAgICAgICAgICAgIHRoaXMucXVhbnRpemF0aW9uQW5ub3RhdGlvbiA9IFtdO1xuICAgICAgICAgICAgaWYgKHByb3BlcnRpZXMpXG4gICAgICAgICAgICAgICAgZm9yICh2YXIga2V5cyA9IE9iamVjdC5rZXlzKHByb3BlcnRpZXMpLCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzW2tleXNbaV1dICE9IG51bGwpXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzW2tleXNbaV1dID0gcHJvcGVydGllc1trZXlzW2ldXTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBHcmFwaFByb3RvIG5vZGUuXG4gICAgICAgICAqIEBtZW1iZXIge0FycmF5Ljxvbm54LklOb2RlUHJvdG8+fSBub2RlXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LkdyYXBoUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBHcmFwaFByb3RvLnByb3RvdHlwZS5ub2RlID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogR3JhcGhQcm90byBuYW1lLlxuICAgICAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IG5hbWVcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguR3JhcGhQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIEdyYXBoUHJvdG8ucHJvdG90eXBlLm5hbWUgPSBcIlwiO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBHcmFwaFByb3RvIGluaXRpYWxpemVyLlxuICAgICAgICAgKiBAbWVtYmVyIHtBcnJheS48b25ueC5JVGVuc29yUHJvdG8+fSBpbml0aWFsaXplclxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5HcmFwaFByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgR3JhcGhQcm90by5wcm90b3R5cGUuaW5pdGlhbGl6ZXIgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBHcmFwaFByb3RvIGRvY1N0cmluZy5cbiAgICAgICAgICogQG1lbWJlciB7c3RyaW5nfSBkb2NTdHJpbmdcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguR3JhcGhQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIEdyYXBoUHJvdG8ucHJvdG90eXBlLmRvY1N0cmluZyA9IFwiXCI7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEdyYXBoUHJvdG8gaW5wdXQuXG4gICAgICAgICAqIEBtZW1iZXIge0FycmF5Ljxvbm54LklWYWx1ZUluZm9Qcm90bz59IGlucHV0XG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LkdyYXBoUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBHcmFwaFByb3RvLnByb3RvdHlwZS5pbnB1dCA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEdyYXBoUHJvdG8gb3V0cHV0LlxuICAgICAgICAgKiBAbWVtYmVyIHtBcnJheS48b25ueC5JVmFsdWVJbmZvUHJvdG8+fSBvdXRwdXRcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguR3JhcGhQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIEdyYXBoUHJvdG8ucHJvdG90eXBlLm91dHB1dCA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEdyYXBoUHJvdG8gdmFsdWVJbmZvLlxuICAgICAgICAgKiBAbWVtYmVyIHtBcnJheS48b25ueC5JVmFsdWVJbmZvUHJvdG8+fSB2YWx1ZUluZm9cbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguR3JhcGhQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIEdyYXBoUHJvdG8ucHJvdG90eXBlLnZhbHVlSW5mbyA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEdyYXBoUHJvdG8gcXVhbnRpemF0aW9uQW5ub3RhdGlvbi5cbiAgICAgICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguSVRlbnNvckFubm90YXRpb24+fSBxdWFudGl6YXRpb25Bbm5vdGF0aW9uXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LkdyYXBoUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBHcmFwaFByb3RvLnByb3RvdHlwZS5xdWFudGl6YXRpb25Bbm5vdGF0aW9uID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ3JlYXRlcyBhIG5ldyBHcmFwaFByb3RvIGluc3RhbmNlIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHJvcGVydGllcy5cbiAgICAgICAgICogQGZ1bmN0aW9uIGNyZWF0ZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5HcmFwaFByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtvbm54LklHcmFwaFByb3RvPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICAgICAqIEByZXR1cm5zIHtvbm54LkdyYXBoUHJvdG99IEdyYXBoUHJvdG8gaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIEdyYXBoUHJvdG8uY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKHByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgR3JhcGhQcm90byhwcm9wZXJ0aWVzKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIEdyYXBoUHJvdG8gbWVzc2FnZS4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5HcmFwaFByb3RvLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LkdyYXBoUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge29ubnguSUdyYXBoUHJvdG99IG1lc3NhZ2UgR3JhcGhQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgICAgICovXG4gICAgICAgIEdyYXBoUHJvdG8uZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgICAgICAgaWYgKCF3cml0ZXIpXG4gICAgICAgICAgICAgICAgd3JpdGVyID0gJFdyaXRlci5jcmVhdGUoKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLm5vZGUgIT0gbnVsbCAmJiBtZXNzYWdlLm5vZGUubGVuZ3RoKVxuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5ub2RlLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICAkcm9vdC5vbm54Lk5vZGVQcm90by5lbmNvZGUobWVzc2FnZS5ub2RlW2ldLCB3cml0ZXIudWludDMyKC8qIGlkIDEsIHdpcmVUeXBlIDIgPSovMTApLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5uYW1lICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcIm5hbWVcIikpXG4gICAgICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAyLCB3aXJlVHlwZSAyID0qLzE4KS5zdHJpbmcobWVzc2FnZS5uYW1lKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmluaXRpYWxpemVyICE9IG51bGwgJiYgbWVzc2FnZS5pbml0aWFsaXplci5sZW5ndGgpXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmluaXRpYWxpemVyLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICAkcm9vdC5vbm54LlRlbnNvclByb3RvLmVuY29kZShtZXNzYWdlLmluaXRpYWxpemVyW2ldLCB3cml0ZXIudWludDMyKC8qIGlkIDUsIHdpcmVUeXBlIDIgPSovNDIpLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5kb2NTdHJpbmcgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiZG9jU3RyaW5nXCIpKVxuICAgICAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMTAsIHdpcmVUeXBlIDIgPSovODIpLnN0cmluZyhtZXNzYWdlLmRvY1N0cmluZyk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5pbnB1dCAhPSBudWxsICYmIG1lc3NhZ2UuaW5wdXQubGVuZ3RoKVxuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5pbnB1dC5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgJHJvb3Qub25ueC5WYWx1ZUluZm9Qcm90by5lbmNvZGUobWVzc2FnZS5pbnB1dFtpXSwgd3JpdGVyLnVpbnQzMigvKiBpZCAxMSwgd2lyZVR5cGUgMiA9Ki85MCkuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLm91dHB1dCAhPSBudWxsICYmIG1lc3NhZ2Uub3V0cHV0Lmxlbmd0aClcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2Uub3V0cHV0Lmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICAkcm9vdC5vbm54LlZhbHVlSW5mb1Byb3RvLmVuY29kZShtZXNzYWdlLm91dHB1dFtpXSwgd3JpdGVyLnVpbnQzMigvKiBpZCAxMiwgd2lyZVR5cGUgMiA9Ki85OCkuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnZhbHVlSW5mbyAhPSBudWxsICYmIG1lc3NhZ2UudmFsdWVJbmZvLmxlbmd0aClcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UudmFsdWVJbmZvLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICAkcm9vdC5vbm54LlZhbHVlSW5mb1Byb3RvLmVuY29kZShtZXNzYWdlLnZhbHVlSW5mb1tpXSwgd3JpdGVyLnVpbnQzMigvKiBpZCAxMywgd2lyZVR5cGUgMiA9Ki8xMDYpLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5xdWFudGl6YXRpb25Bbm5vdGF0aW9uICE9IG51bGwgJiYgbWVzc2FnZS5xdWFudGl6YXRpb25Bbm5vdGF0aW9uLmxlbmd0aClcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UucXVhbnRpemF0aW9uQW5ub3RhdGlvbi5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgJHJvb3Qub25ueC5UZW5zb3JBbm5vdGF0aW9uLmVuY29kZShtZXNzYWdlLnF1YW50aXphdGlvbkFubm90YXRpb25baV0sIHdyaXRlci51aW50MzIoLyogaWQgMTQsIHdpcmVUeXBlIDIgPSovMTE0KS5mb3JrKCkpLmxkZWxpbSgpO1xuICAgICAgICAgICAgcmV0dXJuIHdyaXRlcjtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIEdyYXBoUHJvdG8gbWVzc2FnZSwgbGVuZ3RoIGRlbGltaXRlZC4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5HcmFwaFByb3RvLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LkdyYXBoUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge29ubnguSUdyYXBoUHJvdG99IG1lc3NhZ2UgR3JhcGhQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgICAgICovXG4gICAgICAgIEdyYXBoUHJvdG8uZW5jb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikubGRlbGltKCk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIERlY29kZXMgYSBHcmFwaFByb3RvIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIuXG4gICAgICAgICAqIEBmdW5jdGlvbiBkZWNvZGVcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguR3JhcGhQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aF0gTWVzc2FnZSBsZW5ndGggaWYga25vd24gYmVmb3JlaGFuZFxuICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5HcmFwaFByb3RvfSBHcmFwaFByb3RvXG4gICAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAgICAgKi9cbiAgICAgICAgR3JhcGhQcm90by5kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUocmVhZGVyLCBsZW5ndGgpIHtcbiAgICAgICAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKVxuICAgICAgICAgICAgICAgIHJlYWRlciA9ICRSZWFkZXIuY3JlYXRlKHJlYWRlcik7XG4gICAgICAgICAgICB2YXIgZW5kID0gbGVuZ3RoID09PSB1bmRlZmluZWQgPyByZWFkZXIubGVuIDogcmVhZGVyLnBvcyArIGxlbmd0aCwgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LkdyYXBoUHJvdG8oKTtcbiAgICAgICAgICAgIHdoaWxlIChyZWFkZXIucG9zIDwgZW5kKSB7XG4gICAgICAgICAgICAgICAgdmFyIHRhZyA9IHJlYWRlci51aW50MzIoKTtcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKHRhZyA+Pj4gMykge1xuICAgICAgICAgICAgICAgIGNhc2UgMTpcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5ub2RlICYmIG1lc3NhZ2Uubm9kZS5sZW5ndGgpKVxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5ub2RlID0gW107XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2Uubm9kZS5wdXNoKCRyb290Lm9ubnguTm9kZVByb3RvLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSkpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UubmFtZSA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSA1OlxuICAgICAgICAgICAgICAgICAgICBpZiAoIShtZXNzYWdlLmluaXRpYWxpemVyICYmIG1lc3NhZ2UuaW5pdGlhbGl6ZXIubGVuZ3RoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuaW5pdGlhbGl6ZXIgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5pbml0aWFsaXplci5wdXNoKCRyb290Lm9ubnguVGVuc29yUHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKSk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgMTA6XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZG9jU3RyaW5nID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIDExOlxuICAgICAgICAgICAgICAgICAgICBpZiAoIShtZXNzYWdlLmlucHV0ICYmIG1lc3NhZ2UuaW5wdXQubGVuZ3RoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuaW5wdXQgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5pbnB1dC5wdXNoKCRyb290Lm9ubnguVmFsdWVJbmZvUHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKSk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgMTI6XG4gICAgICAgICAgICAgICAgICAgIGlmICghKG1lc3NhZ2Uub3V0cHV0ICYmIG1lc3NhZ2Uub3V0cHV0Lmxlbmd0aCkpXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLm91dHB1dCA9IFtdO1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLm91dHB1dC5wdXNoKCRyb290Lm9ubnguVmFsdWVJbmZvUHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKSk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgMTM6XG4gICAgICAgICAgICAgICAgICAgIGlmICghKG1lc3NhZ2UudmFsdWVJbmZvICYmIG1lc3NhZ2UudmFsdWVJbmZvLmxlbmd0aCkpXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnZhbHVlSW5mbyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnZhbHVlSW5mby5wdXNoKCRyb290Lm9ubnguVmFsdWVJbmZvUHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKSk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgMTQ6XG4gICAgICAgICAgICAgICAgICAgIGlmICghKG1lc3NhZ2UucXVhbnRpemF0aW9uQW5ub3RhdGlvbiAmJiBtZXNzYWdlLnF1YW50aXphdGlvbkFubm90YXRpb24ubGVuZ3RoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UucXVhbnRpemF0aW9uQW5ub3RhdGlvbiA9IFtdO1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnF1YW50aXphdGlvbkFubm90YXRpb24ucHVzaCgkcm9vdC5vbm54LlRlbnNvckFubm90YXRpb24uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKSk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIHJlYWRlci5za2lwVHlwZSh0YWcgJiA3KTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIERlY29kZXMgYSBHcmFwaFByb3RvIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIsIGxlbmd0aCBkZWxpbWl0ZWQuXG4gICAgICAgICAqIEBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWRcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguR3JhcGhQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5HcmFwaFByb3RvfSBHcmFwaFByb3RvXG4gICAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAgICAgKi9cbiAgICAgICAgR3JhcGhQcm90by5kZWNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWQocmVhZGVyKSB7XG4gICAgICAgICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSlcbiAgICAgICAgICAgICAgICByZWFkZXIgPSBuZXcgJFJlYWRlcihyZWFkZXIpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogVmVyaWZpZXMgYSBHcmFwaFByb3RvIG1lc3NhZ2UuXG4gICAgICAgICAqIEBmdW5jdGlvbiB2ZXJpZnlcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguR3JhcGhQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG1lc3NhZ2UgUGxhaW4gb2JqZWN0IHRvIHZlcmlmeVxuICAgICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfG51bGx9IGBudWxsYCBpZiB2YWxpZCwgb3RoZXJ3aXNlIHRoZSByZWFzb24gd2h5IGl0IGlzIG5vdFxuICAgICAgICAgKi9cbiAgICAgICAgR3JhcGhQcm90by52ZXJpZnkgPSBmdW5jdGlvbiB2ZXJpZnkobWVzc2FnZSkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlICE9PSBcIm9iamVjdFwiIHx8IG1lc3NhZ2UgPT09IG51bGwpXG4gICAgICAgICAgICAgICAgcmV0dXJuIFwib2JqZWN0IGV4cGVjdGVkXCI7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5ub2RlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcIm5vZGVcIikpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5ub2RlKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwibm9kZTogYXJyYXkgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2Uubm9kZS5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54Lk5vZGVQcm90by52ZXJpZnkobWVzc2FnZS5ub2RlW2ldKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwibm9kZS5cIiArIGVycm9yO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLm5hbWUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwibmFtZVwiKSlcbiAgICAgICAgICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UubmFtZSkpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm5hbWU6IHN0cmluZyBleHBlY3RlZFwiO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuaW5pdGlhbGl6ZXIgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiaW5pdGlhbGl6ZXJcIikpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5pbml0aWFsaXplcikpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcImluaXRpYWxpemVyOiBhcnJheSBleHBlY3RlZFwiO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5pbml0aWFsaXplci5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlRlbnNvclByb3RvLnZlcmlmeShtZXNzYWdlLmluaXRpYWxpemVyW2ldKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiaW5pdGlhbGl6ZXIuXCIgKyBlcnJvcjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5kb2NTdHJpbmcgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiZG9jU3RyaW5nXCIpKVxuICAgICAgICAgICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5kb2NTdHJpbmcpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJkb2NTdHJpbmc6IHN0cmluZyBleHBlY3RlZFwiO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuaW5wdXQgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiaW5wdXRcIikpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5pbnB1dCkpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcImlucHV0OiBhcnJheSBleHBlY3RlZFwiO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5pbnB1dC5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlZhbHVlSW5mb1Byb3RvLnZlcmlmeShtZXNzYWdlLmlucHV0W2ldKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiaW5wdXQuXCIgKyBlcnJvcjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5vdXRwdXQgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwib3V0cHV0XCIpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2Uub3V0cHV0KSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwib3V0cHV0OiBhcnJheSBleHBlY3RlZFwiO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5vdXRwdXQubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5WYWx1ZUluZm9Qcm90by52ZXJpZnkobWVzc2FnZS5vdXRwdXRbaV0pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJvdXRwdXQuXCIgKyBlcnJvcjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS52YWx1ZUluZm8gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwidmFsdWVJbmZvXCIpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2UudmFsdWVJbmZvKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwidmFsdWVJbmZvOiBhcnJheSBleHBlY3RlZFwiO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS52YWx1ZUluZm8ubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5WYWx1ZUluZm9Qcm90by52ZXJpZnkobWVzc2FnZS52YWx1ZUluZm9baV0pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJ2YWx1ZUluZm8uXCIgKyBlcnJvcjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5xdWFudGl6YXRpb25Bbm5vdGF0aW9uICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcInF1YW50aXphdGlvbkFubm90YXRpb25cIikpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5xdWFudGl6YXRpb25Bbm5vdGF0aW9uKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwicXVhbnRpemF0aW9uQW5ub3RhdGlvbjogYXJyYXkgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UucXVhbnRpemF0aW9uQW5ub3RhdGlvbi5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlRlbnNvckFubm90YXRpb24udmVyaWZ5KG1lc3NhZ2UucXVhbnRpemF0aW9uQW5ub3RhdGlvbltpXSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcilcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcInF1YW50aXphdGlvbkFubm90YXRpb24uXCIgKyBlcnJvcjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ3JlYXRlcyBhIEdyYXBoUHJvdG8gbWVzc2FnZSBmcm9tIGEgcGxhaW4gb2JqZWN0LiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byB0aGVpciByZXNwZWN0aXZlIGludGVybmFsIHR5cGVzLlxuICAgICAgICAgKiBAZnVuY3Rpb24gZnJvbU9iamVjdFxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5HcmFwaFByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gb2JqZWN0IFBsYWluIG9iamVjdFxuICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5HcmFwaFByb3RvfSBHcmFwaFByb3RvXG4gICAgICAgICAqL1xuICAgICAgICBHcmFwaFByb3RvLmZyb21PYmplY3QgPSBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mICRyb290Lm9ubnguR3JhcGhQcm90bylcbiAgICAgICAgICAgICAgICByZXR1cm4gb2JqZWN0O1xuICAgICAgICAgICAgdmFyIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5HcmFwaFByb3RvKCk7XG4gICAgICAgICAgICBpZiAob2JqZWN0Lm5vZGUpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0Lm5vZGUpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5HcmFwaFByb3RvLm5vZGU6IGFycmF5IGV4cGVjdGVkXCIpO1xuICAgICAgICAgICAgICAgIG1lc3NhZ2Uubm9kZSA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0Lm5vZGUubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3Qubm9kZVtpXSAhPT0gXCJvYmplY3RcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIi5vbm54LkdyYXBoUHJvdG8ubm9kZTogb2JqZWN0IGV4cGVjdGVkXCIpO1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLm5vZGVbaV0gPSAkcm9vdC5vbm54Lk5vZGVQcm90by5mcm9tT2JqZWN0KG9iamVjdC5ub2RlW2ldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob2JqZWN0Lm5hbWUgIT0gbnVsbClcbiAgICAgICAgICAgICAgICBtZXNzYWdlLm5hbWUgPSBTdHJpbmcob2JqZWN0Lm5hbWUpO1xuICAgICAgICAgICAgaWYgKG9iamVjdC5pbml0aWFsaXplcikge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QuaW5pdGlhbGl6ZXIpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5HcmFwaFByb3RvLmluaXRpYWxpemVyOiBhcnJheSBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICBtZXNzYWdlLmluaXRpYWxpemVyID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QuaW5pdGlhbGl6ZXIubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QuaW5pdGlhbGl6ZXJbaV0gIT09IFwib2JqZWN0XCIpXG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5HcmFwaFByb3RvLmluaXRpYWxpemVyOiBvYmplY3QgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuaW5pdGlhbGl6ZXJbaV0gPSAkcm9vdC5vbm54LlRlbnNvclByb3RvLmZyb21PYmplY3Qob2JqZWN0LmluaXRpYWxpemVyW2ldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob2JqZWN0LmRvY1N0cmluZyAhPSBudWxsKVxuICAgICAgICAgICAgICAgIG1lc3NhZ2UuZG9jU3RyaW5nID0gU3RyaW5nKG9iamVjdC5kb2NTdHJpbmcpO1xuICAgICAgICAgICAgaWYgKG9iamVjdC5pbnB1dCkge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QuaW5wdXQpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5HcmFwaFByb3RvLmlucHV0OiBhcnJheSBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICBtZXNzYWdlLmlucHV0ID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QuaW5wdXQubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QuaW5wdXRbaV0gIT09IFwib2JqZWN0XCIpXG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5HcmFwaFByb3RvLmlucHV0OiBvYmplY3QgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuaW5wdXRbaV0gPSAkcm9vdC5vbm54LlZhbHVlSW5mb1Byb3RvLmZyb21PYmplY3Qob2JqZWN0LmlucHV0W2ldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob2JqZWN0Lm91dHB1dCkge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3Qub3V0cHV0KSlcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguR3JhcGhQcm90by5vdXRwdXQ6IGFycmF5IGV4cGVjdGVkXCIpO1xuICAgICAgICAgICAgICAgIG1lc3NhZ2Uub3V0cHV0ID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3Qub3V0cHV0Lmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0Lm91dHB1dFtpXSAhPT0gXCJvYmplY3RcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIi5vbm54LkdyYXBoUHJvdG8ub3V0cHV0OiBvYmplY3QgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2Uub3V0cHV0W2ldID0gJHJvb3Qub25ueC5WYWx1ZUluZm9Qcm90by5mcm9tT2JqZWN0KG9iamVjdC5vdXRwdXRbaV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChvYmplY3QudmFsdWVJbmZvKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC52YWx1ZUluZm8pKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5HcmFwaFByb3RvLnZhbHVlSW5mbzogYXJyYXkgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgbWVzc2FnZS52YWx1ZUluZm8gPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC52YWx1ZUluZm8ubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QudmFsdWVJbmZvW2ldICE9PSBcIm9iamVjdFwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguR3JhcGhQcm90by52YWx1ZUluZm86IG9iamVjdCBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS52YWx1ZUluZm9baV0gPSAkcm9vdC5vbm54LlZhbHVlSW5mb1Byb3RvLmZyb21PYmplY3Qob2JqZWN0LnZhbHVlSW5mb1tpXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG9iamVjdC5xdWFudGl6YXRpb25Bbm5vdGF0aW9uKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5xdWFudGl6YXRpb25Bbm5vdGF0aW9uKSlcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguR3JhcGhQcm90by5xdWFudGl6YXRpb25Bbm5vdGF0aW9uOiBhcnJheSBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICBtZXNzYWdlLnF1YW50aXphdGlvbkFubm90YXRpb24gPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5xdWFudGl6YXRpb25Bbm5vdGF0aW9uLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0LnF1YW50aXphdGlvbkFubm90YXRpb25baV0gIT09IFwib2JqZWN0XCIpXG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5HcmFwaFByb3RvLnF1YW50aXphdGlvbkFubm90YXRpb246IG9iamVjdCBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5xdWFudGl6YXRpb25Bbm5vdGF0aW9uW2ldID0gJHJvb3Qub25ueC5UZW5zb3JBbm5vdGF0aW9uLmZyb21PYmplY3Qob2JqZWN0LnF1YW50aXphdGlvbkFubm90YXRpb25baV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDcmVhdGVzIGEgcGxhaW4gb2JqZWN0IGZyb20gYSBHcmFwaFByb3RvIG1lc3NhZ2UuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIG90aGVyIHR5cGVzIGlmIHNwZWNpZmllZC5cbiAgICAgICAgICogQGZ1bmN0aW9uIHRvT2JqZWN0XG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LkdyYXBoUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge29ubnguR3JhcGhQcm90b30gbWVzc2FnZSBHcmFwaFByb3RvXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLklDb252ZXJzaW9uT3B0aW9uc30gW29wdGlvbnNdIENvbnZlcnNpb24gb3B0aW9uc1xuICAgICAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IFBsYWluIG9iamVjdFxuICAgICAgICAgKi9cbiAgICAgICAgR3JhcGhQcm90by50b09iamVjdCA9IGZ1bmN0aW9uIHRvT2JqZWN0KG1lc3NhZ2UsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGlmICghb3B0aW9ucylcbiAgICAgICAgICAgICAgICBvcHRpb25zID0ge307XG4gICAgICAgICAgICB2YXIgb2JqZWN0ID0ge307XG4gICAgICAgICAgICBpZiAob3B0aW9ucy5hcnJheXMgfHwgb3B0aW9ucy5kZWZhdWx0cykge1xuICAgICAgICAgICAgICAgIG9iamVjdC5ub2RlID0gW107XG4gICAgICAgICAgICAgICAgb2JqZWN0LmluaXRpYWxpemVyID0gW107XG4gICAgICAgICAgICAgICAgb2JqZWN0LmlucHV0ID0gW107XG4gICAgICAgICAgICAgICAgb2JqZWN0Lm91dHB1dCA9IFtdO1xuICAgICAgICAgICAgICAgIG9iamVjdC52YWx1ZUluZm8gPSBbXTtcbiAgICAgICAgICAgICAgICBvYmplY3QucXVhbnRpemF0aW9uQW5ub3RhdGlvbiA9IFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG9wdGlvbnMuZGVmYXVsdHMpIHtcbiAgICAgICAgICAgICAgICBvYmplY3QubmFtZSA9IFwiXCI7XG4gICAgICAgICAgICAgICAgb2JqZWN0LmRvY1N0cmluZyA9IFwiXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5ub2RlICYmIG1lc3NhZ2Uubm9kZS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBvYmplY3Qubm9kZSA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5ub2RlLmxlbmd0aDsgKytqKVxuICAgICAgICAgICAgICAgICAgICBvYmplY3Qubm9kZVtqXSA9ICRyb290Lm9ubnguTm9kZVByb3RvLnRvT2JqZWN0KG1lc3NhZ2Uubm9kZVtqXSwgb3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5uYW1lICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcIm5hbWVcIikpXG4gICAgICAgICAgICAgICAgb2JqZWN0Lm5hbWUgPSBtZXNzYWdlLm5hbWU7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5pbml0aWFsaXplciAmJiBtZXNzYWdlLmluaXRpYWxpemVyLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIG9iamVjdC5pbml0aWFsaXplciA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5pbml0aWFsaXplci5sZW5ndGg7ICsrailcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LmluaXRpYWxpemVyW2pdID0gJHJvb3Qub25ueC5UZW5zb3JQcm90by50b09iamVjdChtZXNzYWdlLmluaXRpYWxpemVyW2pdLCBvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmRvY1N0cmluZyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJkb2NTdHJpbmdcIikpXG4gICAgICAgICAgICAgICAgb2JqZWN0LmRvY1N0cmluZyA9IG1lc3NhZ2UuZG9jU3RyaW5nO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuaW5wdXQgJiYgbWVzc2FnZS5pbnB1dC5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBvYmplY3QuaW5wdXQgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UuaW5wdXQubGVuZ3RoOyArK2opXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC5pbnB1dFtqXSA9ICRyb290Lm9ubnguVmFsdWVJbmZvUHJvdG8udG9PYmplY3QobWVzc2FnZS5pbnB1dFtqXSwgb3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5vdXRwdXQgJiYgbWVzc2FnZS5vdXRwdXQubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgb2JqZWN0Lm91dHB1dCA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5vdXRwdXQubGVuZ3RoOyArK2opXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC5vdXRwdXRbal0gPSAkcm9vdC5vbm54LlZhbHVlSW5mb1Byb3RvLnRvT2JqZWN0KG1lc3NhZ2Uub3V0cHV0W2pdLCBvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnZhbHVlSW5mbyAmJiBtZXNzYWdlLnZhbHVlSW5mby5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBvYmplY3QudmFsdWVJbmZvID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLnZhbHVlSW5mby5sZW5ndGg7ICsrailcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LnZhbHVlSW5mb1tqXSA9ICRyb290Lm9ubnguVmFsdWVJbmZvUHJvdG8udG9PYmplY3QobWVzc2FnZS52YWx1ZUluZm9bal0sIG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UucXVhbnRpemF0aW9uQW5ub3RhdGlvbiAmJiBtZXNzYWdlLnF1YW50aXphdGlvbkFubm90YXRpb24ubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgb2JqZWN0LnF1YW50aXphdGlvbkFubm90YXRpb24gPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UucXVhbnRpemF0aW9uQW5ub3RhdGlvbi5sZW5ndGg7ICsrailcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LnF1YW50aXphdGlvbkFubm90YXRpb25bal0gPSAkcm9vdC5vbm54LlRlbnNvckFubm90YXRpb24udG9PYmplY3QobWVzc2FnZS5xdWFudGl6YXRpb25Bbm5vdGF0aW9uW2pdLCBvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENvbnZlcnRzIHRoaXMgR3JhcGhQcm90byB0byBKU09OLlxuICAgICAgICAgKiBAZnVuY3Rpb24gdG9KU09OXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LkdyYXBoUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gSlNPTiBvYmplY3RcbiAgICAgICAgICovXG4gICAgICAgIEdyYXBoUHJvdG8ucHJvdG90eXBlLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLnRvT2JqZWN0KHRoaXMsICRwcm90b2J1Zi51dGlsLnRvSlNPTk9wdGlvbnMpO1xuICAgICAgICB9O1xuXG4gICAgICAgIHJldHVybiBHcmFwaFByb3RvO1xuICAgIH0pKCk7XG5cbiAgICBvbm54LlRlbnNvclByb3RvID0gKGZ1bmN0aW9uKCkge1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBQcm9wZXJ0aWVzIG9mIGEgVGVuc29yUHJvdG8uXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54XG4gICAgICAgICAqIEBpbnRlcmZhY2UgSVRlbnNvclByb3RvXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG51bWJlcnxMb25nPnxudWxsfSBbZGltc10gVGVuc29yUHJvdG8gZGltc1xuICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcnxudWxsfSBbZGF0YVR5cGVdIFRlbnNvclByb3RvIGRhdGFUeXBlXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7b25ueC5UZW5zb3JQcm90by5JU2VnbWVudHxudWxsfSBbc2VnbWVudF0gVGVuc29yUHJvdG8gc2VnbWVudFxuICAgICAgICAgKiBAcHJvcGVydHkge0FycmF5LjxudW1iZXI+fG51bGx9IFtmbG9hdERhdGFdIFRlbnNvclByb3RvIGZsb2F0RGF0YVxuICAgICAgICAgKiBAcHJvcGVydHkge0FycmF5LjxudW1iZXI+fG51bGx9IFtpbnQzMkRhdGFdIFRlbnNvclByb3RvIGludDMyRGF0YVxuICAgICAgICAgKiBAcHJvcGVydHkge0FycmF5LjxVaW50OEFycmF5PnxudWxsfSBbc3RyaW5nRGF0YV0gVGVuc29yUHJvdG8gc3RyaW5nRGF0YVxuICAgICAgICAgKiBAcHJvcGVydHkge0FycmF5LjxudW1iZXJ8TG9uZz58bnVsbH0gW2ludDY0RGF0YV0gVGVuc29yUHJvdG8gaW50NjREYXRhXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtuYW1lXSBUZW5zb3JQcm90byBuYW1lXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtkb2NTdHJpbmddIFRlbnNvclByb3RvIGRvY1N0cmluZ1xuICAgICAgICAgKiBAcHJvcGVydHkge1VpbnQ4QXJyYXl8bnVsbH0gW3Jhd0RhdGFdIFRlbnNvclByb3RvIHJhd0RhdGFcbiAgICAgICAgICogQHByb3BlcnR5IHtBcnJheS48b25ueC5JU3RyaW5nU3RyaW5nRW50cnlQcm90bz58bnVsbH0gW2V4dGVybmFsRGF0YV0gVGVuc29yUHJvdG8gZXh0ZXJuYWxEYXRhXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7b25ueC5UZW5zb3JQcm90by5EYXRhTG9jYXRpb258bnVsbH0gW2RhdGFMb2NhdGlvbl0gVGVuc29yUHJvdG8gZGF0YUxvY2F0aW9uXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7QXJyYXkuPG51bWJlcj58bnVsbH0gW2RvdWJsZURhdGFdIFRlbnNvclByb3RvIGRvdWJsZURhdGFcbiAgICAgICAgICogQHByb3BlcnR5IHtBcnJheS48bnVtYmVyfExvbmc+fG51bGx9IFt1aW50NjREYXRhXSBUZW5zb3JQcm90byB1aW50NjREYXRhXG4gICAgICAgICAqL1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IFRlbnNvclByb3RvLlxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAgICAgKiBAY2xhc3NkZXNjIFJlcHJlc2VudHMgYSBUZW5zb3JQcm90by5cbiAgICAgICAgICogQGltcGxlbWVudHMgSVRlbnNvclByb3RvXG4gICAgICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAgICAgKiBAcGFyYW0ge29ubnguSVRlbnNvclByb3RvPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICAgICAqL1xuICAgICAgICBmdW5jdGlvbiBUZW5zb3JQcm90byhwcm9wZXJ0aWVzKSB7XG4gICAgICAgICAgICB0aGlzLmRpbXMgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuZmxvYXREYXRhID0gW107XG4gICAgICAgICAgICB0aGlzLmludDMyRGF0YSA9IFtdO1xuICAgICAgICAgICAgdGhpcy5zdHJpbmdEYXRhID0gW107XG4gICAgICAgICAgICB0aGlzLmludDY0RGF0YSA9IFtdO1xuICAgICAgICAgICAgdGhpcy5leHRlcm5hbERhdGEgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuZG91YmxlRGF0YSA9IFtdO1xuICAgICAgICAgICAgdGhpcy51aW50NjREYXRhID0gW107XG4gICAgICAgICAgICBpZiAocHJvcGVydGllcylcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBrZXlzID0gT2JqZWN0LmtleXMocHJvcGVydGllcyksIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgaWYgKHByb3BlcnRpZXNba2V5c1tpXV0gIT0gbnVsbClcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNba2V5c1tpXV0gPSBwcm9wZXJ0aWVzW2tleXNbaV1dO1xuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRlbnNvclByb3RvIGRpbXMuXG4gICAgICAgICAqIEBtZW1iZXIge0FycmF5LjxudW1iZXJ8TG9uZz59IGRpbXNcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBUZW5zb3JQcm90by5wcm90b3R5cGUuZGltcyA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRlbnNvclByb3RvIGRhdGFUeXBlLlxuICAgICAgICAgKiBAbWVtYmVyIHtudW1iZXJ9IGRhdGFUeXBlXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgVGVuc29yUHJvdG8ucHJvdG90eXBlLmRhdGFUeXBlID0gMDtcblxuICAgICAgICAvKipcbiAgICAgICAgICogVGVuc29yUHJvdG8gc2VnbWVudC5cbiAgICAgICAgICogQG1lbWJlciB7b25ueC5UZW5zb3JQcm90by5JU2VnbWVudHxudWxsfHVuZGVmaW5lZH0gc2VnbWVudFxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIFRlbnNvclByb3RvLnByb3RvdHlwZS5zZWdtZW50ID0gbnVsbDtcblxuICAgICAgICAvKipcbiAgICAgICAgICogVGVuc29yUHJvdG8gZmxvYXREYXRhLlxuICAgICAgICAgKiBAbWVtYmVyIHtBcnJheS48bnVtYmVyPn0gZmxvYXREYXRhXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgVGVuc29yUHJvdG8ucHJvdG90eXBlLmZsb2F0RGF0YSA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRlbnNvclByb3RvIGludDMyRGF0YS5cbiAgICAgICAgICogQG1lbWJlciB7QXJyYXkuPG51bWJlcj59IGludDMyRGF0YVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIFRlbnNvclByb3RvLnByb3RvdHlwZS5pbnQzMkRhdGEgPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUZW5zb3JQcm90byBzdHJpbmdEYXRhLlxuICAgICAgICAgKiBAbWVtYmVyIHtBcnJheS48VWludDhBcnJheT59IHN0cmluZ0RhdGFcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBUZW5zb3JQcm90by5wcm90b3R5cGUuc3RyaW5nRGF0YSA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRlbnNvclByb3RvIGludDY0RGF0YS5cbiAgICAgICAgICogQG1lbWJlciB7QXJyYXkuPG51bWJlcnxMb25nPn0gaW50NjREYXRhXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgVGVuc29yUHJvdG8ucHJvdG90eXBlLmludDY0RGF0YSA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRlbnNvclByb3RvIG5hbWUuXG4gICAgICAgICAqIEBtZW1iZXIge3N0cmluZ30gbmFtZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIFRlbnNvclByb3RvLnByb3RvdHlwZS5uYW1lID0gXCJcIjtcblxuICAgICAgICAvKipcbiAgICAgICAgICogVGVuc29yUHJvdG8gZG9jU3RyaW5nLlxuICAgICAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IGRvY1N0cmluZ1xuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIFRlbnNvclByb3RvLnByb3RvdHlwZS5kb2NTdHJpbmcgPSBcIlwiO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUZW5zb3JQcm90byByYXdEYXRhLlxuICAgICAgICAgKiBAbWVtYmVyIHtVaW50OEFycmF5fSByYXdEYXRhXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgVGVuc29yUHJvdG8ucHJvdG90eXBlLnJhd0RhdGEgPSAkdXRpbC5uZXdCdWZmZXIoW10pO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUZW5zb3JQcm90byBleHRlcm5hbERhdGEuXG4gICAgICAgICAqIEBtZW1iZXIge0FycmF5Ljxvbm54LklTdHJpbmdTdHJpbmdFbnRyeVByb3RvPn0gZXh0ZXJuYWxEYXRhXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgVGVuc29yUHJvdG8ucHJvdG90eXBlLmV4dGVybmFsRGF0YSA9ICR1dGlsLmVtcHR5QXJyYXk7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRlbnNvclByb3RvIGRhdGFMb2NhdGlvbi5cbiAgICAgICAgICogQG1lbWJlciB7b25ueC5UZW5zb3JQcm90by5EYXRhTG9jYXRpb259IGRhdGFMb2NhdGlvblxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIFRlbnNvclByb3RvLnByb3RvdHlwZS5kYXRhTG9jYXRpb24gPSAwO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUZW5zb3JQcm90byBkb3VibGVEYXRhLlxuICAgICAgICAgKiBAbWVtYmVyIHtBcnJheS48bnVtYmVyPn0gZG91YmxlRGF0YVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIFRlbnNvclByb3RvLnByb3RvdHlwZS5kb3VibGVEYXRhID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogVGVuc29yUHJvdG8gdWludDY0RGF0YS5cbiAgICAgICAgICogQG1lbWJlciB7QXJyYXkuPG51bWJlcnxMb25nPn0gdWludDY0RGF0YVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIFRlbnNvclByb3RvLnByb3RvdHlwZS51aW50NjREYXRhID0gJHV0aWwuZW1wdHlBcnJheTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ3JlYXRlcyBhIG5ldyBUZW5zb3JQcm90byBpbnN0YW5jZSB1c2luZyB0aGUgc3BlY2lmaWVkIHByb3BlcnRpZXMuXG4gICAgICAgICAqIEBmdW5jdGlvbiBjcmVhdGVcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge29ubnguSVRlbnNvclByb3RvPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICAgICAqIEByZXR1cm5zIHtvbm54LlRlbnNvclByb3RvfSBUZW5zb3JQcm90byBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgVGVuc29yUHJvdG8uY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKHByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgVGVuc29yUHJvdG8ocHJvcGVydGllcyk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBUZW5zb3JQcm90byBtZXNzYWdlLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlRlbnNvclByb3RvLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtvbm54LklUZW5zb3JQcm90b30gbWVzc2FnZSBUZW5zb3JQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgICAgICovXG4gICAgICAgIFRlbnNvclByb3RvLmVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZShtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgICAgICAgIGlmICghd3JpdGVyKVxuICAgICAgICAgICAgICAgIHdyaXRlciA9ICRXcml0ZXIuY3JlYXRlKCk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5kaW1zICE9IG51bGwgJiYgbWVzc2FnZS5kaW1zLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMSwgd2lyZVR5cGUgMiA9Ki8xMCkuZm9yaygpO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5kaW1zLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICB3cml0ZXIuaW50NjQobWVzc2FnZS5kaW1zW2ldKTtcbiAgICAgICAgICAgICAgICB3cml0ZXIubGRlbGltKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5kYXRhVHlwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJkYXRhVHlwZVwiKSlcbiAgICAgICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDIsIHdpcmVUeXBlIDAgPSovMTYpLmludDMyKG1lc3NhZ2UuZGF0YVR5cGUpO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2Uuc2VnbWVudCAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJzZWdtZW50XCIpKVxuICAgICAgICAgICAgICAgICRyb290Lm9ubnguVGVuc29yUHJvdG8uU2VnbWVudC5lbmNvZGUobWVzc2FnZS5zZWdtZW50LCB3cml0ZXIudWludDMyKC8qIGlkIDMsIHdpcmVUeXBlIDIgPSovMjYpLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5mbG9hdERhdGEgIT0gbnVsbCAmJiBtZXNzYWdlLmZsb2F0RGF0YS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDQsIHdpcmVUeXBlIDIgPSovMzQpLmZvcmsoKTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuZmxvYXREYXRhLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICB3cml0ZXIuZmxvYXQobWVzc2FnZS5mbG9hdERhdGFbaV0pO1xuICAgICAgICAgICAgICAgIHdyaXRlci5sZGVsaW0oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmludDMyRGF0YSAhPSBudWxsICYmIG1lc3NhZ2UuaW50MzJEYXRhLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgNSwgd2lyZVR5cGUgMiA9Ki80MikuZm9yaygpO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5pbnQzMkRhdGEubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgIHdyaXRlci5pbnQzMihtZXNzYWdlLmludDMyRGF0YVtpXSk7XG4gICAgICAgICAgICAgICAgd3JpdGVyLmxkZWxpbSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2Uuc3RyaW5nRGF0YSAhPSBudWxsICYmIG1lc3NhZ2Uuc3RyaW5nRGF0YS5sZW5ndGgpXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLnN0cmluZ0RhdGEubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgNiwgd2lyZVR5cGUgMiA9Ki81MCkuYnl0ZXMobWVzc2FnZS5zdHJpbmdEYXRhW2ldKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmludDY0RGF0YSAhPSBudWxsICYmIG1lc3NhZ2UuaW50NjREYXRhLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgNywgd2lyZVR5cGUgMiA9Ki81OCkuZm9yaygpO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5pbnQ2NERhdGEubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgIHdyaXRlci5pbnQ2NChtZXNzYWdlLmludDY0RGF0YVtpXSk7XG4gICAgICAgICAgICAgICAgd3JpdGVyLmxkZWxpbSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UubmFtZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJuYW1lXCIpKVxuICAgICAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgOCwgd2lyZVR5cGUgMiA9Ki82Nikuc3RyaW5nKG1lc3NhZ2UubmFtZSk7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5yYXdEYXRhICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcInJhd0RhdGFcIikpXG4gICAgICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCA5LCB3aXJlVHlwZSAyID0qLzc0KS5ieXRlcyhtZXNzYWdlLnJhd0RhdGEpO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZG91YmxlRGF0YSAhPSBudWxsICYmIG1lc3NhZ2UuZG91YmxlRGF0YS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDEwLCB3aXJlVHlwZSAyID0qLzgyKS5mb3JrKCk7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmRvdWJsZURhdGEubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgIHdyaXRlci5kb3VibGUobWVzc2FnZS5kb3VibGVEYXRhW2ldKTtcbiAgICAgICAgICAgICAgICB3cml0ZXIubGRlbGltKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS51aW50NjREYXRhICE9IG51bGwgJiYgbWVzc2FnZS51aW50NjREYXRhLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMTEsIHdpcmVUeXBlIDIgPSovOTApLmZvcmsoKTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UudWludDY0RGF0YS5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgd3JpdGVyLnVpbnQ2NChtZXNzYWdlLnVpbnQ2NERhdGFbaV0pO1xuICAgICAgICAgICAgICAgIHdyaXRlci5sZGVsaW0oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmRvY1N0cmluZyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJkb2NTdHJpbmdcIikpXG4gICAgICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxMiwgd2lyZVR5cGUgMiA9Ki85OCkuc3RyaW5nKG1lc3NhZ2UuZG9jU3RyaW5nKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmV4dGVybmFsRGF0YSAhPSBudWxsICYmIG1lc3NhZ2UuZXh0ZXJuYWxEYXRhLmxlbmd0aClcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuZXh0ZXJuYWxEYXRhLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uZW5jb2RlKG1lc3NhZ2UuZXh0ZXJuYWxEYXRhW2ldLCB3cml0ZXIudWludDMyKC8qIGlkIDEzLCB3aXJlVHlwZSAyID0qLzEwNikuZm9yaygpKS5sZGVsaW0oKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmRhdGFMb2NhdGlvbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJkYXRhTG9jYXRpb25cIikpXG4gICAgICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxNCwgd2lyZVR5cGUgMCA9Ki8xMTIpLmludDMyKG1lc3NhZ2UuZGF0YUxvY2F0aW9uKTtcbiAgICAgICAgICAgIHJldHVybiB3cml0ZXI7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBUZW5zb3JQcm90byBtZXNzYWdlLCBsZW5ndGggZGVsaW1pdGVkLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlRlbnNvclByb3RvLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtvbm54LklUZW5zb3JQcm90b30gbWVzc2FnZSBUZW5zb3JQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgICAgICovXG4gICAgICAgIFRlbnNvclByb3RvLmVuY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZChtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVuY29kZShtZXNzYWdlLCB3cml0ZXIpLmxkZWxpbSgpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEZWNvZGVzIGEgVGVuc29yUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlci5cbiAgICAgICAgICogQGZ1bmN0aW9uIGRlY29kZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aF0gTWVzc2FnZSBsZW5ndGggaWYga25vd24gYmVmb3JlaGFuZFxuICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5UZW5zb3JQcm90b30gVGVuc29yUHJvdG9cbiAgICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICAgICAqL1xuICAgICAgICBUZW5zb3JQcm90by5kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUocmVhZGVyLCBsZW5ndGgpIHtcbiAgICAgICAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKVxuICAgICAgICAgICAgICAgIHJlYWRlciA9ICRSZWFkZXIuY3JlYXRlKHJlYWRlcik7XG4gICAgICAgICAgICB2YXIgZW5kID0gbGVuZ3RoID09PSB1bmRlZmluZWQgPyByZWFkZXIubGVuIDogcmVhZGVyLnBvcyArIGxlbmd0aCwgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlRlbnNvclByb3RvKCk7XG4gICAgICAgICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZCkge1xuICAgICAgICAgICAgICAgIHZhciB0YWcgPSByZWFkZXIudWludDMyKCk7XG4gICAgICAgICAgICAgICAgc3dpdGNoICh0YWcgPj4+IDMpIHtcbiAgICAgICAgICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgICAgICAgICAgIGlmICghKG1lc3NhZ2UuZGltcyAmJiBtZXNzYWdlLmRpbXMubGVuZ3RoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZGltcyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICBpZiAoKHRhZyAmIDcpID09PSAyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZW5kMiA9IHJlYWRlci51aW50MzIoKSArIHJlYWRlci5wb3M7XG4gICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZDIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5kaW1zLnB1c2gocmVhZGVyLmludDY0KCkpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZGltcy5wdXNoKHJlYWRlci5pbnQ2NCgpKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAyOlxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmRhdGFUeXBlID0gcmVhZGVyLmludDMyKCk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5zZWdtZW50ID0gJHJvb3Qub25ueC5UZW5zb3JQcm90by5TZWdtZW50LmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgNDpcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5mbG9hdERhdGEgJiYgbWVzc2FnZS5mbG9hdERhdGEubGVuZ3RoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZmxvYXREYXRhID0gW107XG4gICAgICAgICAgICAgICAgICAgIGlmICgodGFnICYgNykgPT09IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbmQyID0gcmVhZGVyLnVpbnQzMigpICsgcmVhZGVyLnBvcztcbiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChyZWFkZXIucG9zIDwgZW5kMilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmZsb2F0RGF0YS5wdXNoKHJlYWRlci5mbG9hdCgpKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmZsb2F0RGF0YS5wdXNoKHJlYWRlci5mbG9hdCgpKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSA1OlxuICAgICAgICAgICAgICAgICAgICBpZiAoIShtZXNzYWdlLmludDMyRGF0YSAmJiBtZXNzYWdlLmludDMyRGF0YS5sZW5ndGgpKVxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5pbnQzMkRhdGEgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCh0YWcgJiA3KSA9PT0gMikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVuZDIgPSByZWFkZXIudWludDMyKCkgKyByZWFkZXIucG9zO1xuICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQyKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuaW50MzJEYXRhLnB1c2gocmVhZGVyLmludDMyKCkpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuaW50MzJEYXRhLnB1c2gocmVhZGVyLmludDMyKCkpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIDY6XG4gICAgICAgICAgICAgICAgICAgIGlmICghKG1lc3NhZ2Uuc3RyaW5nRGF0YSAmJiBtZXNzYWdlLnN0cmluZ0RhdGEubGVuZ3RoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2Uuc3RyaW5nRGF0YSA9IFtdO1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnN0cmluZ0RhdGEucHVzaChyZWFkZXIuYnl0ZXMoKSk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgNzpcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5pbnQ2NERhdGEgJiYgbWVzc2FnZS5pbnQ2NERhdGEubGVuZ3RoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuaW50NjREYXRhID0gW107XG4gICAgICAgICAgICAgICAgICAgIGlmICgodGFnICYgNykgPT09IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBlbmQyID0gcmVhZGVyLnVpbnQzMigpICsgcmVhZGVyLnBvcztcbiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChyZWFkZXIucG9zIDwgZW5kMilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmludDY0RGF0YS5wdXNoKHJlYWRlci5pbnQ2NCgpKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmludDY0RGF0YS5wdXNoKHJlYWRlci5pbnQ2NCgpKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSA4OlxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLm5hbWUgPSByZWFkZXIuc3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgMTI6XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZG9jU3RyaW5nID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIDk6XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UucmF3RGF0YSA9IHJlYWRlci5ieXRlcygpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIDEzOlxuICAgICAgICAgICAgICAgICAgICBpZiAoIShtZXNzYWdlLmV4dGVybmFsRGF0YSAmJiBtZXNzYWdlLmV4dGVybmFsRGF0YS5sZW5ndGgpKVxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5leHRlcm5hbERhdGEgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5leHRlcm5hbERhdGEucHVzaCgkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKSk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgMTQ6XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZGF0YUxvY2F0aW9uID0gcmVhZGVyLmludDMyKCk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgMTA6XG4gICAgICAgICAgICAgICAgICAgIGlmICghKG1lc3NhZ2UuZG91YmxlRGF0YSAmJiBtZXNzYWdlLmRvdWJsZURhdGEubGVuZ3RoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZG91YmxlRGF0YSA9IFtdO1xuICAgICAgICAgICAgICAgICAgICBpZiAoKHRhZyAmIDcpID09PSAyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZW5kMiA9IHJlYWRlci51aW50MzIoKSArIHJlYWRlci5wb3M7XG4gICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZDIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5kb3VibGVEYXRhLnB1c2gocmVhZGVyLmRvdWJsZSgpKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmRvdWJsZURhdGEucHVzaChyZWFkZXIuZG91YmxlKCkpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIDExOlxuICAgICAgICAgICAgICAgICAgICBpZiAoIShtZXNzYWdlLnVpbnQ2NERhdGEgJiYgbWVzc2FnZS51aW50NjREYXRhLmxlbmd0aCkpXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnVpbnQ2NERhdGEgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCh0YWcgJiA3KSA9PT0gMikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVuZDIgPSByZWFkZXIudWludDMyKCkgKyByZWFkZXIucG9zO1xuICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQyKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UudWludDY0RGF0YS5wdXNoKHJlYWRlci51aW50NjQoKSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS51aW50NjREYXRhLnB1c2gocmVhZGVyLnVpbnQ2NCgpKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgcmVhZGVyLnNraXBUeXBlKHRhZyAmIDcpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRGVjb2RlcyBhIFRlbnNvclByb3RvIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIsIGxlbmd0aCBkZWxpbWl0ZWQuXG4gICAgICAgICAqIEBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWRcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgICAgICogQHJldHVybnMge29ubnguVGVuc29yUHJvdG99IFRlbnNvclByb3RvXG4gICAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAgICAgKi9cbiAgICAgICAgVGVuc29yUHJvdG8uZGVjb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkKHJlYWRlcikge1xuICAgICAgICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpXG4gICAgICAgICAgICAgICAgcmVhZGVyID0gbmV3ICRSZWFkZXIocmVhZGVyKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFZlcmlmaWVzIGEgVGVuc29yUHJvdG8gbWVzc2FnZS5cbiAgICAgICAgICogQGZ1bmN0aW9uIHZlcmlmeVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG1lc3NhZ2UgUGxhaW4gb2JqZWN0IHRvIHZlcmlmeVxuICAgICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfG51bGx9IGBudWxsYCBpZiB2YWxpZCwgb3RoZXJ3aXNlIHRoZSByZWFzb24gd2h5IGl0IGlzIG5vdFxuICAgICAgICAgKi9cbiAgICAgICAgVGVuc29yUHJvdG8udmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1lc3NhZ2UpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSAhPT0gXCJvYmplY3RcIiB8fCBtZXNzYWdlID09PSBudWxsKVxuICAgICAgICAgICAgICAgIHJldHVybiBcIm9iamVjdCBleHBlY3RlZFwiO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZGltcyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJkaW1zXCIpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2UuZGltcykpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcImRpbXM6IGFycmF5IGV4cGVjdGVkXCI7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmRpbXMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgIGlmICghJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuZGltc1tpXSkgJiYgIShtZXNzYWdlLmRpbXNbaV0gJiYgJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuZGltc1tpXS5sb3cpICYmICR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmRpbXNbaV0uaGlnaCkpKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiZGltczogaW50ZWdlcnxMb25nW10gZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmRhdGFUeXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImRhdGFUeXBlXCIpKVxuICAgICAgICAgICAgICAgIGlmICghJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuZGF0YVR5cGUpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJkYXRhVHlwZTogaW50ZWdlciBleHBlY3RlZFwiO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2Uuc2VnbWVudCAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJzZWdtZW50XCIpKSB7XG4gICAgICAgICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5UZW5zb3JQcm90by5TZWdtZW50LnZlcmlmeShtZXNzYWdlLnNlZ21lbnQpO1xuICAgICAgICAgICAgICAgIGlmIChlcnJvcilcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwic2VnbWVudC5cIiArIGVycm9yO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZmxvYXREYXRhICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImZsb2F0RGF0YVwiKSkge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLmZsb2F0RGF0YSkpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcImZsb2F0RGF0YTogYXJyYXkgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuZmxvYXREYXRhLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UuZmxvYXREYXRhW2ldICE9PSBcIm51bWJlclwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiZmxvYXREYXRhOiBudW1iZXJbXSBleHBlY3RlZFwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuaW50MzJEYXRhICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImludDMyRGF0YVwiKSkge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLmludDMyRGF0YSkpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcImludDMyRGF0YTogYXJyYXkgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuaW50MzJEYXRhLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICBpZiAoISR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmludDMyRGF0YVtpXSkpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJpbnQzMkRhdGE6IGludGVnZXJbXSBleHBlY3RlZFwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2Uuc3RyaW5nRGF0YSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJzdHJpbmdEYXRhXCIpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2Uuc3RyaW5nRGF0YSkpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcInN0cmluZ0RhdGE6IGFycmF5IGV4cGVjdGVkXCI7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLnN0cmluZ0RhdGEubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgIGlmICghKG1lc3NhZ2Uuc3RyaW5nRGF0YVtpXSAmJiB0eXBlb2YgbWVzc2FnZS5zdHJpbmdEYXRhW2ldLmxlbmd0aCA9PT0gXCJudW1iZXJcIiB8fCAkdXRpbC5pc1N0cmluZyhtZXNzYWdlLnN0cmluZ0RhdGFbaV0pKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcInN0cmluZ0RhdGE6IGJ1ZmZlcltdIGV4cGVjdGVkXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5pbnQ2NERhdGEgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiaW50NjREYXRhXCIpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2UuaW50NjREYXRhKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiaW50NjREYXRhOiBhcnJheSBleHBlY3RlZFwiO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5pbnQ2NERhdGEubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgIGlmICghJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuaW50NjREYXRhW2ldKSAmJiAhKG1lc3NhZ2UuaW50NjREYXRhW2ldICYmICR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmludDY0RGF0YVtpXS5sb3cpICYmICR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmludDY0RGF0YVtpXS5oaWdoKSkpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJpbnQ2NERhdGE6IGludGVnZXJ8TG9uZ1tdIGV4cGVjdGVkXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5uYW1lICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcIm5hbWVcIikpXG4gICAgICAgICAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLm5hbWUpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJuYW1lOiBzdHJpbmcgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmRvY1N0cmluZyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJkb2NTdHJpbmdcIikpXG4gICAgICAgICAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLmRvY1N0cmluZykpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcImRvY1N0cmluZzogc3RyaW5nIGV4cGVjdGVkXCI7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5yYXdEYXRhICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcInJhd0RhdGFcIikpXG4gICAgICAgICAgICAgICAgaWYgKCEobWVzc2FnZS5yYXdEYXRhICYmIHR5cGVvZiBtZXNzYWdlLnJhd0RhdGEubGVuZ3RoID09PSBcIm51bWJlclwiIHx8ICR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UucmF3RGF0YSkpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJyYXdEYXRhOiBidWZmZXIgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmV4dGVybmFsRGF0YSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJleHRlcm5hbERhdGFcIikpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZS5leHRlcm5hbERhdGEpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJleHRlcm5hbERhdGE6IGFycmF5IGV4cGVjdGVkXCI7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmV4dGVybmFsRGF0YS5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZXJyb3IgPSAkcm9vdC5vbm54LlN0cmluZ1N0cmluZ0VudHJ5UHJvdG8udmVyaWZ5KG1lc3NhZ2UuZXh0ZXJuYWxEYXRhW2ldKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiZXh0ZXJuYWxEYXRhLlwiICsgZXJyb3I7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZGF0YUxvY2F0aW9uICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImRhdGFMb2NhdGlvblwiKSlcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKG1lc3NhZ2UuZGF0YUxvY2F0aW9uKSB7XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiZGF0YUxvY2F0aW9uOiBlbnVtIHZhbHVlIGV4cGVjdGVkXCI7XG4gICAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIGNhc2UgMTpcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZG91YmxlRGF0YSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJkb3VibGVEYXRhXCIpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2UuZG91YmxlRGF0YSkpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcImRvdWJsZURhdGE6IGFycmF5IGV4cGVjdGVkXCI7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtZXNzYWdlLmRvdWJsZURhdGEubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZS5kb3VibGVEYXRhW2ldICE9PSBcIm51bWJlclwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiZG91YmxlRGF0YTogbnVtYmVyW10gZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnVpbnQ2NERhdGEgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwidWludDY0RGF0YVwiKSkge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLnVpbnQ2NERhdGEpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJ1aW50NjREYXRhOiBhcnJheSBleHBlY3RlZFwiO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS51aW50NjREYXRhLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICBpZiAoISR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLnVpbnQ2NERhdGFbaV0pICYmICEobWVzc2FnZS51aW50NjREYXRhW2ldICYmICR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLnVpbnQ2NERhdGFbaV0ubG93KSAmJiAkdXRpbC5pc0ludGVnZXIobWVzc2FnZS51aW50NjREYXRhW2ldLmhpZ2gpKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcInVpbnQ2NERhdGE6IGludGVnZXJ8TG9uZ1tdIGV4cGVjdGVkXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ3JlYXRlcyBhIFRlbnNvclByb3RvIG1lc3NhZ2UgZnJvbSBhIHBsYWluIG9iamVjdC4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gdGhlaXIgcmVzcGVjdGl2ZSBpbnRlcm5hbCB0eXBlcy5cbiAgICAgICAgICogQGZ1bmN0aW9uIGZyb21PYmplY3RcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBvYmplY3QgUGxhaW4gb2JqZWN0XG4gICAgICAgICAqIEByZXR1cm5zIHtvbm54LlRlbnNvclByb3RvfSBUZW5zb3JQcm90b1xuICAgICAgICAgKi9cbiAgICAgICAgVGVuc29yUHJvdG8uZnJvbU9iamVjdCA9IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgJHJvb3Qub25ueC5UZW5zb3JQcm90bylcbiAgICAgICAgICAgICAgICByZXR1cm4gb2JqZWN0O1xuICAgICAgICAgICAgdmFyIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5UZW5zb3JQcm90bygpO1xuICAgICAgICAgICAgaWYgKG9iamVjdC5kaW1zKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5kaW1zKSlcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguVGVuc29yUHJvdG8uZGltczogYXJyYXkgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgbWVzc2FnZS5kaW1zID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QuZGltcy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgaWYgKCR1dGlsLkxvbmcpXG4gICAgICAgICAgICAgICAgICAgICAgICAobWVzc2FnZS5kaW1zW2ldID0gJHV0aWwuTG9uZy5mcm9tVmFsdWUob2JqZWN0LmRpbXNbaV0pKS51bnNpZ25lZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LmRpbXNbaV0gPT09IFwic3RyaW5nXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmRpbXNbaV0gPSBwYXJzZUludChvYmplY3QuZGltc1tpXSwgMTApO1xuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LmRpbXNbaV0gPT09IFwibnVtYmVyXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmRpbXNbaV0gPSBvYmplY3QuZGltc1tpXTtcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5kaW1zW2ldID09PSBcIm9iamVjdFwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5kaW1zW2ldID0gbmV3ICR1dGlsLkxvbmdCaXRzKG9iamVjdC5kaW1zW2ldLmxvdyA+Pj4gMCwgb2JqZWN0LmRpbXNbaV0uaGlnaCA+Pj4gMCkudG9OdW1iZXIoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChvYmplY3QuZGF0YVR5cGUgIT0gbnVsbClcbiAgICAgICAgICAgICAgICBtZXNzYWdlLmRhdGFUeXBlID0gb2JqZWN0LmRhdGFUeXBlIHwgMDtcbiAgICAgICAgICAgIGlmIChvYmplY3Quc2VnbWVudCAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3Quc2VnbWVudCAhPT0gXCJvYmplY3RcIilcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguVGVuc29yUHJvdG8uc2VnbWVudDogb2JqZWN0IGV4cGVjdGVkXCIpO1xuICAgICAgICAgICAgICAgIG1lc3NhZ2Uuc2VnbWVudCA9ICRyb290Lm9ubnguVGVuc29yUHJvdG8uU2VnbWVudC5mcm9tT2JqZWN0KG9iamVjdC5zZWdtZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChvYmplY3QuZmxvYXREYXRhKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5mbG9hdERhdGEpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5UZW5zb3JQcm90by5mbG9hdERhdGE6IGFycmF5IGV4cGVjdGVkXCIpO1xuICAgICAgICAgICAgICAgIG1lc3NhZ2UuZmxvYXREYXRhID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QuZmxvYXREYXRhLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmZsb2F0RGF0YVtpXSA9IE51bWJlcihvYmplY3QuZmxvYXREYXRhW2ldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChvYmplY3QuaW50MzJEYXRhKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5pbnQzMkRhdGEpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5UZW5zb3JQcm90by5pbnQzMkRhdGE6IGFycmF5IGV4cGVjdGVkXCIpO1xuICAgICAgICAgICAgICAgIG1lc3NhZ2UuaW50MzJEYXRhID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QuaW50MzJEYXRhLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmludDMyRGF0YVtpXSA9IG9iamVjdC5pbnQzMkRhdGFbaV0gfCAwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG9iamVjdC5zdHJpbmdEYXRhKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5zdHJpbmdEYXRhKSlcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguVGVuc29yUHJvdG8uc3RyaW5nRGF0YTogYXJyYXkgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgbWVzc2FnZS5zdHJpbmdEYXRhID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3Quc3RyaW5nRGF0YS5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3Quc3RyaW5nRGF0YVtpXSA9PT0gXCJzdHJpbmdcIilcbiAgICAgICAgICAgICAgICAgICAgICAgICR1dGlsLmJhc2U2NC5kZWNvZGUob2JqZWN0LnN0cmluZ0RhdGFbaV0sIG1lc3NhZ2Uuc3RyaW5nRGF0YVtpXSA9ICR1dGlsLm5ld0J1ZmZlcigkdXRpbC5iYXNlNjQubGVuZ3RoKG9iamVjdC5zdHJpbmdEYXRhW2ldKSksIDApO1xuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChvYmplY3Quc3RyaW5nRGF0YVtpXS5sZW5ndGgpXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnN0cmluZ0RhdGFbaV0gPSBvYmplY3Quc3RyaW5nRGF0YVtpXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChvYmplY3QuaW50NjREYXRhKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG9iamVjdC5pbnQ2NERhdGEpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5UZW5zb3JQcm90by5pbnQ2NERhdGE6IGFycmF5IGV4cGVjdGVkXCIpO1xuICAgICAgICAgICAgICAgIG1lc3NhZ2UuaW50NjREYXRhID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmplY3QuaW50NjREYXRhLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICBpZiAoJHV0aWwuTG9uZylcbiAgICAgICAgICAgICAgICAgICAgICAgIChtZXNzYWdlLmludDY0RGF0YVtpXSA9ICR1dGlsLkxvbmcuZnJvbVZhbHVlKG9iamVjdC5pbnQ2NERhdGFbaV0pKS51bnNpZ25lZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LmludDY0RGF0YVtpXSA9PT0gXCJzdHJpbmdcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuaW50NjREYXRhW2ldID0gcGFyc2VJbnQob2JqZWN0LmludDY0RGF0YVtpXSwgMTApO1xuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LmludDY0RGF0YVtpXSA9PT0gXCJudW1iZXJcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuaW50NjREYXRhW2ldID0gb2JqZWN0LmludDY0RGF0YVtpXTtcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5pbnQ2NERhdGFbaV0gPT09IFwib2JqZWN0XCIpXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmludDY0RGF0YVtpXSA9IG5ldyAkdXRpbC5Mb25nQml0cyhvYmplY3QuaW50NjREYXRhW2ldLmxvdyA+Pj4gMCwgb2JqZWN0LmludDY0RGF0YVtpXS5oaWdoID4+PiAwKS50b051bWJlcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG9iamVjdC5uYW1lICE9IG51bGwpXG4gICAgICAgICAgICAgICAgbWVzc2FnZS5uYW1lID0gU3RyaW5nKG9iamVjdC5uYW1lKTtcbiAgICAgICAgICAgIGlmIChvYmplY3QuZG9jU3RyaW5nICE9IG51bGwpXG4gICAgICAgICAgICAgICAgbWVzc2FnZS5kb2NTdHJpbmcgPSBTdHJpbmcob2JqZWN0LmRvY1N0cmluZyk7XG4gICAgICAgICAgICBpZiAob2JqZWN0LnJhd0RhdGEgIT0gbnVsbClcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5yYXdEYXRhID09PSBcInN0cmluZ1wiKVxuICAgICAgICAgICAgICAgICAgICAkdXRpbC5iYXNlNjQuZGVjb2RlKG9iamVjdC5yYXdEYXRhLCBtZXNzYWdlLnJhd0RhdGEgPSAkdXRpbC5uZXdCdWZmZXIoJHV0aWwuYmFzZTY0Lmxlbmd0aChvYmplY3QucmF3RGF0YSkpLCAwKTtcbiAgICAgICAgICAgICAgICBlbHNlIGlmIChvYmplY3QucmF3RGF0YS5sZW5ndGgpXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UucmF3RGF0YSA9IG9iamVjdC5yYXdEYXRhO1xuICAgICAgICAgICAgaWYgKG9iamVjdC5leHRlcm5hbERhdGEpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LmV4dGVybmFsRGF0YSkpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIi5vbm54LlRlbnNvclByb3RvLmV4dGVybmFsRGF0YTogYXJyYXkgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgbWVzc2FnZS5leHRlcm5hbERhdGEgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC5leHRlcm5hbERhdGEubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QuZXh0ZXJuYWxEYXRhW2ldICE9PSBcIm9iamVjdFwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguVGVuc29yUHJvdG8uZXh0ZXJuYWxEYXRhOiBvYmplY3QgZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZXh0ZXJuYWxEYXRhW2ldID0gJHJvb3Qub25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvLmZyb21PYmplY3Qob2JqZWN0LmV4dGVybmFsRGF0YVtpXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc3dpdGNoIChvYmplY3QuZGF0YUxvY2F0aW9uKSB7XG4gICAgICAgICAgICBjYXNlIFwiREVGQVVMVFwiOlxuICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIG1lc3NhZ2UuZGF0YUxvY2F0aW9uID0gMDtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJFWFRFUk5BTFwiOlxuICAgICAgICAgICAgY2FzZSAxOlxuICAgICAgICAgICAgICAgIG1lc3NhZ2UuZGF0YUxvY2F0aW9uID0gMTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChvYmplY3QuZG91YmxlRGF0YSkge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShvYmplY3QuZG91YmxlRGF0YSkpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIi5vbm54LlRlbnNvclByb3RvLmRvdWJsZURhdGE6IGFycmF5IGV4cGVjdGVkXCIpO1xuICAgICAgICAgICAgICAgIG1lc3NhZ2UuZG91YmxlRGF0YSA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0LmRvdWJsZURhdGEubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZG91YmxlRGF0YVtpXSA9IE51bWJlcihvYmplY3QuZG91YmxlRGF0YVtpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob2JqZWN0LnVpbnQ2NERhdGEpIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LnVpbnQ2NERhdGEpKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5UZW5zb3JQcm90by51aW50NjREYXRhOiBhcnJheSBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICBtZXNzYWdlLnVpbnQ2NERhdGEgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iamVjdC51aW50NjREYXRhLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICBpZiAoJHV0aWwuTG9uZylcbiAgICAgICAgICAgICAgICAgICAgICAgIChtZXNzYWdlLnVpbnQ2NERhdGFbaV0gPSAkdXRpbC5Mb25nLmZyb21WYWx1ZShvYmplY3QudWludDY0RGF0YVtpXSkpLnVuc2lnbmVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC51aW50NjREYXRhW2ldID09PSBcInN0cmluZ1wiKVxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS51aW50NjREYXRhW2ldID0gcGFyc2VJbnQob2JqZWN0LnVpbnQ2NERhdGFbaV0sIDEwKTtcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC51aW50NjREYXRhW2ldID09PSBcIm51bWJlclwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS51aW50NjREYXRhW2ldID0gb2JqZWN0LnVpbnQ2NERhdGFbaV07XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QudWludDY0RGF0YVtpXSA9PT0gXCJvYmplY3RcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UudWludDY0RGF0YVtpXSA9IG5ldyAkdXRpbC5Mb25nQml0cyhvYmplY3QudWludDY0RGF0YVtpXS5sb3cgPj4+IDAsIG9iamVjdC51aW50NjREYXRhW2ldLmhpZ2ggPj4+IDApLnRvTnVtYmVyKHRydWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENyZWF0ZXMgYSBwbGFpbiBvYmplY3QgZnJvbSBhIFRlbnNvclByb3RvIG1lc3NhZ2UuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIG90aGVyIHR5cGVzIGlmIHNwZWNpZmllZC5cbiAgICAgICAgICogQGZ1bmN0aW9uIHRvT2JqZWN0XG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtvbm54LlRlbnNvclByb3RvfSBtZXNzYWdlIFRlbnNvclByb3RvXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLklDb252ZXJzaW9uT3B0aW9uc30gW29wdGlvbnNdIENvbnZlcnNpb24gb3B0aW9uc1xuICAgICAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IFBsYWluIG9iamVjdFxuICAgICAgICAgKi9cbiAgICAgICAgVGVuc29yUHJvdG8udG9PYmplY3QgPSBmdW5jdGlvbiB0b09iamVjdChtZXNzYWdlLCBvcHRpb25zKSB7XG4gICAgICAgICAgICBpZiAoIW9wdGlvbnMpXG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IHt9O1xuICAgICAgICAgICAgdmFyIG9iamVjdCA9IHt9O1xuICAgICAgICAgICAgaWYgKG9wdGlvbnMuYXJyYXlzIHx8IG9wdGlvbnMuZGVmYXVsdHMpIHtcbiAgICAgICAgICAgICAgICBvYmplY3QuZGltcyA9IFtdO1xuICAgICAgICAgICAgICAgIG9iamVjdC5mbG9hdERhdGEgPSBbXTtcbiAgICAgICAgICAgICAgICBvYmplY3QuaW50MzJEYXRhID0gW107XG4gICAgICAgICAgICAgICAgb2JqZWN0LnN0cmluZ0RhdGEgPSBbXTtcbiAgICAgICAgICAgICAgICBvYmplY3QuaW50NjREYXRhID0gW107XG4gICAgICAgICAgICAgICAgb2JqZWN0LmRvdWJsZURhdGEgPSBbXTtcbiAgICAgICAgICAgICAgICBvYmplY3QudWludDY0RGF0YSA9IFtdO1xuICAgICAgICAgICAgICAgIG9iamVjdC5leHRlcm5hbERhdGEgPSBbXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChvcHRpb25zLmRlZmF1bHRzKSB7XG4gICAgICAgICAgICAgICAgb2JqZWN0LmRhdGFUeXBlID0gMDtcbiAgICAgICAgICAgICAgICBvYmplY3Quc2VnbWVudCA9IG51bGw7XG4gICAgICAgICAgICAgICAgb2JqZWN0Lm5hbWUgPSBcIlwiO1xuICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLmJ5dGVzID09PSBTdHJpbmcpXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC5yYXdEYXRhID0gXCJcIjtcbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LnJhd0RhdGEgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuYnl0ZXMgIT09IEFycmF5KVxuICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LnJhd0RhdGEgPSAkdXRpbC5uZXdCdWZmZXIob2JqZWN0LnJhd0RhdGEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBvYmplY3QuZG9jU3RyaW5nID0gXCJcIjtcbiAgICAgICAgICAgICAgICBvYmplY3QuZGF0YUxvY2F0aW9uID0gb3B0aW9ucy5lbnVtcyA9PT0gU3RyaW5nID8gXCJERUZBVUxUXCIgOiAwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZGltcyAmJiBtZXNzYWdlLmRpbXMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgb2JqZWN0LmRpbXMgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UuZGltcy5sZW5ndGg7ICsrailcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlLmRpbXNbal0gPT09IFwibnVtYmVyXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QuZGltc1tqXSA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/IFN0cmluZyhtZXNzYWdlLmRpbXNbal0pIDogbWVzc2FnZS5kaW1zW2pdO1xuICAgICAgICAgICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QuZGltc1tqXSA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/ICR1dGlsLkxvbmcucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobWVzc2FnZS5kaW1zW2pdKSA6IG9wdGlvbnMubG9uZ3MgPT09IE51bWJlciA/IG5ldyAkdXRpbC5Mb25nQml0cyhtZXNzYWdlLmRpbXNbal0ubG93ID4+PiAwLCBtZXNzYWdlLmRpbXNbal0uaGlnaCA+Pj4gMCkudG9OdW1iZXIoKSA6IG1lc3NhZ2UuZGltc1tqXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmRhdGFUeXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImRhdGFUeXBlXCIpKVxuICAgICAgICAgICAgICAgIG9iamVjdC5kYXRhVHlwZSA9IG1lc3NhZ2UuZGF0YVR5cGU7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5zZWdtZW50ICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcInNlZ21lbnRcIikpXG4gICAgICAgICAgICAgICAgb2JqZWN0LnNlZ21lbnQgPSAkcm9vdC5vbm54LlRlbnNvclByb3RvLlNlZ21lbnQudG9PYmplY3QobWVzc2FnZS5zZWdtZW50LCBvcHRpb25zKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmZsb2F0RGF0YSAmJiBtZXNzYWdlLmZsb2F0RGF0YS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBvYmplY3QuZmxvYXREYXRhID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLmZsb2F0RGF0YS5sZW5ndGg7ICsrailcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LmZsb2F0RGF0YVtqXSA9IG9wdGlvbnMuanNvbiAmJiAhaXNGaW5pdGUobWVzc2FnZS5mbG9hdERhdGFbal0pID8gU3RyaW5nKG1lc3NhZ2UuZmxvYXREYXRhW2pdKSA6IG1lc3NhZ2UuZmxvYXREYXRhW2pdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuaW50MzJEYXRhICYmIG1lc3NhZ2UuaW50MzJEYXRhLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIG9iamVjdC5pbnQzMkRhdGEgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UuaW50MzJEYXRhLmxlbmd0aDsgKytqKVxuICAgICAgICAgICAgICAgICAgICBvYmplY3QuaW50MzJEYXRhW2pdID0gbWVzc2FnZS5pbnQzMkRhdGFbal07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5zdHJpbmdEYXRhICYmIG1lc3NhZ2Uuc3RyaW5nRGF0YS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBvYmplY3Quc3RyaW5nRGF0YSA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS5zdHJpbmdEYXRhLmxlbmd0aDsgKytqKVxuICAgICAgICAgICAgICAgICAgICBvYmplY3Quc3RyaW5nRGF0YVtqXSA9IG9wdGlvbnMuYnl0ZXMgPT09IFN0cmluZyA/ICR1dGlsLmJhc2U2NC5lbmNvZGUobWVzc2FnZS5zdHJpbmdEYXRhW2pdLCAwLCBtZXNzYWdlLnN0cmluZ0RhdGFbal0ubGVuZ3RoKSA6IG9wdGlvbnMuYnl0ZXMgPT09IEFycmF5ID8gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwobWVzc2FnZS5zdHJpbmdEYXRhW2pdKSA6IG1lc3NhZ2Uuc3RyaW5nRGF0YVtqXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmludDY0RGF0YSAmJiBtZXNzYWdlLmludDY0RGF0YS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBvYmplY3QuaW50NjREYXRhID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLmludDY0RGF0YS5sZW5ndGg7ICsrailcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlLmludDY0RGF0YVtqXSA9PT0gXCJudW1iZXJcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC5pbnQ2NERhdGFbal0gPSBvcHRpb25zLmxvbmdzID09PSBTdHJpbmcgPyBTdHJpbmcobWVzc2FnZS5pbnQ2NERhdGFbal0pIDogbWVzc2FnZS5pbnQ2NERhdGFbal07XG4gICAgICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC5pbnQ2NERhdGFbal0gPSBvcHRpb25zLmxvbmdzID09PSBTdHJpbmcgPyAkdXRpbC5Mb25nLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG1lc3NhZ2UuaW50NjREYXRhW2pdKSA6IG9wdGlvbnMubG9uZ3MgPT09IE51bWJlciA/IG5ldyAkdXRpbC5Mb25nQml0cyhtZXNzYWdlLmludDY0RGF0YVtqXS5sb3cgPj4+IDAsIG1lc3NhZ2UuaW50NjREYXRhW2pdLmhpZ2ggPj4+IDApLnRvTnVtYmVyKCkgOiBtZXNzYWdlLmludDY0RGF0YVtqXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLm5hbWUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwibmFtZVwiKSlcbiAgICAgICAgICAgICAgICBvYmplY3QubmFtZSA9IG1lc3NhZ2UubmFtZTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnJhd0RhdGEgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwicmF3RGF0YVwiKSlcbiAgICAgICAgICAgICAgICBvYmplY3QucmF3RGF0YSA9IG9wdGlvbnMuYnl0ZXMgPT09IFN0cmluZyA/ICR1dGlsLmJhc2U2NC5lbmNvZGUobWVzc2FnZS5yYXdEYXRhLCAwLCBtZXNzYWdlLnJhd0RhdGEubGVuZ3RoKSA6IG9wdGlvbnMuYnl0ZXMgPT09IEFycmF5ID8gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwobWVzc2FnZS5yYXdEYXRhKSA6IG1lc3NhZ2UucmF3RGF0YTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmRvdWJsZURhdGEgJiYgbWVzc2FnZS5kb3VibGVEYXRhLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIG9iamVjdC5kb3VibGVEYXRhID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtZXNzYWdlLmRvdWJsZURhdGEubGVuZ3RoOyArK2opXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC5kb3VibGVEYXRhW2pdID0gb3B0aW9ucy5qc29uICYmICFpc0Zpbml0ZShtZXNzYWdlLmRvdWJsZURhdGFbal0pID8gU3RyaW5nKG1lc3NhZ2UuZG91YmxlRGF0YVtqXSkgOiBtZXNzYWdlLmRvdWJsZURhdGFbal07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS51aW50NjREYXRhICYmIG1lc3NhZ2UudWludDY0RGF0YS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBvYmplY3QudWludDY0RGF0YSA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWVzc2FnZS51aW50NjREYXRhLmxlbmd0aDsgKytqKVxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UudWludDY0RGF0YVtqXSA9PT0gXCJudW1iZXJcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC51aW50NjREYXRhW2pdID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gU3RyaW5nKG1lc3NhZ2UudWludDY0RGF0YVtqXSkgOiBtZXNzYWdlLnVpbnQ2NERhdGFbal07XG4gICAgICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC51aW50NjREYXRhW2pdID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gJHV0aWwuTG9uZy5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChtZXNzYWdlLnVpbnQ2NERhdGFbal0pIDogb3B0aW9ucy5sb25ncyA9PT0gTnVtYmVyID8gbmV3ICR1dGlsLkxvbmdCaXRzKG1lc3NhZ2UudWludDY0RGF0YVtqXS5sb3cgPj4+IDAsIG1lc3NhZ2UudWludDY0RGF0YVtqXS5oaWdoID4+PiAwKS50b051bWJlcih0cnVlKSA6IG1lc3NhZ2UudWludDY0RGF0YVtqXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmRvY1N0cmluZyAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJkb2NTdHJpbmdcIikpXG4gICAgICAgICAgICAgICAgb2JqZWN0LmRvY1N0cmluZyA9IG1lc3NhZ2UuZG9jU3RyaW5nO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZXh0ZXJuYWxEYXRhICYmIG1lc3NhZ2UuZXh0ZXJuYWxEYXRhLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIG9iamVjdC5leHRlcm5hbERhdGEgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UuZXh0ZXJuYWxEYXRhLmxlbmd0aDsgKytqKVxuICAgICAgICAgICAgICAgICAgICBvYmplY3QuZXh0ZXJuYWxEYXRhW2pdID0gJHJvb3Qub25ueC5TdHJpbmdTdHJpbmdFbnRyeVByb3RvLnRvT2JqZWN0KG1lc3NhZ2UuZXh0ZXJuYWxEYXRhW2pdLCBvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmRhdGFMb2NhdGlvbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJkYXRhTG9jYXRpb25cIikpXG4gICAgICAgICAgICAgICAgb2JqZWN0LmRhdGFMb2NhdGlvbiA9IG9wdGlvbnMuZW51bXMgPT09IFN0cmluZyA/ICRyb290Lm9ubnguVGVuc29yUHJvdG8uRGF0YUxvY2F0aW9uW21lc3NhZ2UuZGF0YUxvY2F0aW9uXSA6IG1lc3NhZ2UuZGF0YUxvY2F0aW9uO1xuICAgICAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ29udmVydHMgdGhpcyBUZW5zb3JQcm90byB0byBKU09OLlxuICAgICAgICAgKiBAZnVuY3Rpb24gdG9KU09OXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IEpTT04gb2JqZWN0XG4gICAgICAgICAqL1xuICAgICAgICBUZW5zb3JQcm90by5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IudG9PYmplY3QodGhpcywgJHByb3RvYnVmLnV0aWwudG9KU09OT3B0aW9ucyk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIERhdGFUeXBlIGVudW0uXG4gICAgICAgICAqIEBuYW1lIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGVcbiAgICAgICAgICogQGVudW0ge3N0cmluZ31cbiAgICAgICAgICogQHByb3BlcnR5IHtudW1iZXJ9IFVOREVGSU5FRD0wIFVOREVGSU5FRCB2YWx1ZVxuICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gRkxPQVQ9MSBGTE9BVCB2YWx1ZVxuICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gVUlOVDg9MiBVSU5UOCB2YWx1ZVxuICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gSU5UOD0zIElOVDggdmFsdWVcbiAgICAgICAgICogQHByb3BlcnR5IHtudW1iZXJ9IFVJTlQxNj00IFVJTlQxNiB2YWx1ZVxuICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gSU5UMTY9NSBJTlQxNiB2YWx1ZVxuICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gSU5UMzI9NiBJTlQzMiB2YWx1ZVxuICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gSU5UNjQ9NyBJTlQ2NCB2YWx1ZVxuICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gU1RSSU5HPTggU1RSSU5HIHZhbHVlXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBCT09MPTkgQk9PTCB2YWx1ZVxuICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gRkxPQVQxNj0xMCBGTE9BVDE2IHZhbHVlXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBET1VCTEU9MTEgRE9VQkxFIHZhbHVlXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBVSU5UMzI9MTIgVUlOVDMyIHZhbHVlXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBVSU5UNjQ9MTMgVUlOVDY0IHZhbHVlXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBDT01QTEVYNjQ9MTQgQ09NUExFWDY0IHZhbHVlXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBDT01QTEVYMTI4PTE1IENPTVBMRVgxMjggdmFsdWVcbiAgICAgICAgICogQHByb3BlcnR5IHtudW1iZXJ9IEJGTE9BVDE2PTE2IEJGTE9BVDE2IHZhbHVlXG4gICAgICAgICAqL1xuICAgICAgICBUZW5zb3JQcm90by5EYXRhVHlwZSA9IChmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHZhciB2YWx1ZXNCeUlkID0ge30sIHZhbHVlcyA9IE9iamVjdC5jcmVhdGUodmFsdWVzQnlJZCk7XG4gICAgICAgICAgICB2YWx1ZXNbdmFsdWVzQnlJZFswXSA9IFwiVU5ERUZJTkVEXCJdID0gMDtcbiAgICAgICAgICAgIHZhbHVlc1t2YWx1ZXNCeUlkWzFdID0gXCJGTE9BVFwiXSA9IDE7XG4gICAgICAgICAgICB2YWx1ZXNbdmFsdWVzQnlJZFsyXSA9IFwiVUlOVDhcIl0gPSAyO1xuICAgICAgICAgICAgdmFsdWVzW3ZhbHVlc0J5SWRbM10gPSBcIklOVDhcIl0gPSAzO1xuICAgICAgICAgICAgdmFsdWVzW3ZhbHVlc0J5SWRbNF0gPSBcIlVJTlQxNlwiXSA9IDQ7XG4gICAgICAgICAgICB2YWx1ZXNbdmFsdWVzQnlJZFs1XSA9IFwiSU5UMTZcIl0gPSA1O1xuICAgICAgICAgICAgdmFsdWVzW3ZhbHVlc0J5SWRbNl0gPSBcIklOVDMyXCJdID0gNjtcbiAgICAgICAgICAgIHZhbHVlc1t2YWx1ZXNCeUlkWzddID0gXCJJTlQ2NFwiXSA9IDc7XG4gICAgICAgICAgICB2YWx1ZXNbdmFsdWVzQnlJZFs4XSA9IFwiU1RSSU5HXCJdID0gODtcbiAgICAgICAgICAgIHZhbHVlc1t2YWx1ZXNCeUlkWzldID0gXCJCT09MXCJdID0gOTtcbiAgICAgICAgICAgIHZhbHVlc1t2YWx1ZXNCeUlkWzEwXSA9IFwiRkxPQVQxNlwiXSA9IDEwO1xuICAgICAgICAgICAgdmFsdWVzW3ZhbHVlc0J5SWRbMTFdID0gXCJET1VCTEVcIl0gPSAxMTtcbiAgICAgICAgICAgIHZhbHVlc1t2YWx1ZXNCeUlkWzEyXSA9IFwiVUlOVDMyXCJdID0gMTI7XG4gICAgICAgICAgICB2YWx1ZXNbdmFsdWVzQnlJZFsxM10gPSBcIlVJTlQ2NFwiXSA9IDEzO1xuICAgICAgICAgICAgdmFsdWVzW3ZhbHVlc0J5SWRbMTRdID0gXCJDT01QTEVYNjRcIl0gPSAxNDtcbiAgICAgICAgICAgIHZhbHVlc1t2YWx1ZXNCeUlkWzE1XSA9IFwiQ09NUExFWDEyOFwiXSA9IDE1O1xuICAgICAgICAgICAgdmFsdWVzW3ZhbHVlc0J5SWRbMTZdID0gXCJCRkxPQVQxNlwiXSA9IDE2O1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlcztcbiAgICAgICAgfSkoKTtcblxuICAgICAgICBUZW5zb3JQcm90by5TZWdtZW50ID0gKGZ1bmN0aW9uKCkge1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIFByb3BlcnRpZXMgb2YgYSBTZWdtZW50LlxuICAgICAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG9cbiAgICAgICAgICAgICAqIEBpbnRlcmZhY2UgSVNlZ21lbnRcbiAgICAgICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfExvbmd8bnVsbH0gW2JlZ2luXSBTZWdtZW50IGJlZ2luXG4gICAgICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcnxMb25nfG51bGx9IFtlbmRdIFNlZ21lbnQgZW5kXG4gICAgICAgICAgICAgKi9cblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IFNlZ21lbnQuXG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90b1xuICAgICAgICAgICAgICogQGNsYXNzZGVzYyBSZXByZXNlbnRzIGEgU2VnbWVudC5cbiAgICAgICAgICAgICAqIEBpbXBsZW1lbnRzIElTZWdtZW50XG4gICAgICAgICAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgICAgICAgICAqIEBwYXJhbSB7b25ueC5UZW5zb3JQcm90by5JU2VnbWVudD19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBmdW5jdGlvbiBTZWdtZW50KHByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgICAgICBpZiAocHJvcGVydGllcylcbiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIga2V5cyA9IE9iamVjdC5rZXlzKHByb3BlcnRpZXMpLCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocHJvcGVydGllc1trZXlzW2ldXSAhPSBudWxsKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNba2V5c1tpXV0gPSBwcm9wZXJ0aWVzW2tleXNbaV1dO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIFNlZ21lbnQgYmVnaW4uXG4gICAgICAgICAgICAgKiBAbWVtYmVyIHtudW1iZXJ8TG9uZ30gYmVnaW5cbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvLlNlZ21lbnRcbiAgICAgICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBTZWdtZW50LnByb3RvdHlwZS5iZWdpbiA9ICR1dGlsLkxvbmcgPyAkdXRpbC5Mb25nLmZyb21CaXRzKDAsMCxmYWxzZSkgOiAwO1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIFNlZ21lbnQgZW5kLlxuICAgICAgICAgICAgICogQG1lbWJlciB7bnVtYmVyfExvbmd9IGVuZFxuICAgICAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG8uU2VnbWVudFxuICAgICAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIFNlZ21lbnQucHJvdG90eXBlLmVuZCA9ICR1dGlsLkxvbmcgPyAkdXRpbC5Mb25nLmZyb21CaXRzKDAsMCxmYWxzZSkgOiAwO1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIENyZWF0ZXMgYSBuZXcgU2VnbWVudCBpbnN0YW5jZSB1c2luZyB0aGUgc3BlY2lmaWVkIHByb3BlcnRpZXMuXG4gICAgICAgICAgICAgKiBAZnVuY3Rpb24gY3JlYXRlXG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90by5TZWdtZW50XG4gICAgICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAgICAgKiBAcGFyYW0ge29ubnguVGVuc29yUHJvdG8uSVNlZ21lbnQ9fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgICAgICAgICAqIEByZXR1cm5zIHtvbm54LlRlbnNvclByb3RvLlNlZ21lbnR9IFNlZ21lbnQgaW5zdGFuY2VcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgU2VnbWVudC5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUocHJvcGVydGllcykge1xuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU2VnbWVudChwcm9wZXJ0aWVzKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIFNlZ21lbnQgbWVzc2FnZS4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5UZW5zb3JQcm90by5TZWdtZW50LnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAgICAgICAgICogQGZ1bmN0aW9uIGVuY29kZVxuICAgICAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG8uU2VnbWVudFxuICAgICAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgICAgICogQHBhcmFtIHtvbm54LlRlbnNvclByb3RvLklTZWdtZW50fSBtZXNzYWdlIFNlZ21lbnQgbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgICAgICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgU2VnbWVudC5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICAgICAgICAgICAgaWYgKCF3cml0ZXIpXG4gICAgICAgICAgICAgICAgICAgIHdyaXRlciA9ICRXcml0ZXIuY3JlYXRlKCk7XG4gICAgICAgICAgICAgICAgaWYgKG1lc3NhZ2UuYmVnaW4gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiYmVnaW5cIikpXG4gICAgICAgICAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMSwgd2lyZVR5cGUgMCA9Ki84KS5pbnQ2NChtZXNzYWdlLmJlZ2luKTtcbiAgICAgICAgICAgICAgICBpZiAobWVzc2FnZS5lbmQgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiZW5kXCIpKVxuICAgICAgICAgICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDIsIHdpcmVUeXBlIDAgPSovMTYpLmludDY0KG1lc3NhZ2UuZW5kKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gd3JpdGVyO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgU2VnbWVudCBtZXNzYWdlLCBsZW5ndGggZGVsaW1pdGVkLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlRlbnNvclByb3RvLlNlZ21lbnQudmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICAgICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90by5TZWdtZW50XG4gICAgICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAgICAgKiBAcGFyYW0ge29ubnguVGVuc29yUHJvdG8uSVNlZ21lbnR9IG1lc3NhZ2UgU2VnbWVudCBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAgICAgICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBTZWdtZW50LmVuY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZChtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lbmNvZGUobWVzc2FnZSwgd3JpdGVyKS5sZGVsaW0oKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogRGVjb2RlcyBhIFNlZ21lbnQgbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlci5cbiAgICAgICAgICAgICAqIEBmdW5jdGlvbiBkZWNvZGVcbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvLlNlZ21lbnRcbiAgICAgICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGhdIE1lc3NhZ2UgbGVuZ3RoIGlmIGtub3duIGJlZm9yZWhhbmRcbiAgICAgICAgICAgICAqIEByZXR1cm5zIHtvbm54LlRlbnNvclByb3RvLlNlZ21lbnR9IFNlZ21lbnRcbiAgICAgICAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICAgICAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgU2VnbWVudC5kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUocmVhZGVyLCBsZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSlcbiAgICAgICAgICAgICAgICAgICAgcmVhZGVyID0gJFJlYWRlci5jcmVhdGUocmVhZGVyKTtcbiAgICAgICAgICAgICAgICB2YXIgZW5kID0gbGVuZ3RoID09PSB1bmRlZmluZWQgPyByZWFkZXIubGVuIDogcmVhZGVyLnBvcyArIGxlbmd0aCwgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlRlbnNvclByb3RvLlNlZ21lbnQoKTtcbiAgICAgICAgICAgICAgICB3aGlsZSAocmVhZGVyLnBvcyA8IGVuZCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgdGFnID0gcmVhZGVyLnVpbnQzMigpO1xuICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKHRhZyA+Pj4gMykge1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmJlZ2luID0gcmVhZGVyLmludDY0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAyOlxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5lbmQgPSByZWFkZXIuaW50NjQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICAgICAgcmVhZGVyLnNraXBUeXBlKHRhZyAmIDcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIERlY29kZXMgYSBTZWdtZW50IG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIsIGxlbmd0aCBkZWxpbWl0ZWQuXG4gICAgICAgICAgICAgKiBAZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkXG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90by5TZWdtZW50XG4gICAgICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgICAgICAgICAqIEByZXR1cm5zIHtvbm54LlRlbnNvclByb3RvLlNlZ21lbnR9IFNlZ21lbnRcbiAgICAgICAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICAgICAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgU2VnbWVudC5kZWNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWQocmVhZGVyKSB7XG4gICAgICAgICAgICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpXG4gICAgICAgICAgICAgICAgICAgIHJlYWRlciA9IG5ldyAkUmVhZGVyKHJlYWRlcik7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogVmVyaWZpZXMgYSBTZWdtZW50IG1lc3NhZ2UuXG4gICAgICAgICAgICAgKiBAZnVuY3Rpb24gdmVyaWZ5XG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JQcm90by5TZWdtZW50XG4gICAgICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBtZXNzYWdlIFBsYWluIG9iamVjdCB0byB2ZXJpZnlcbiAgICAgICAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd8bnVsbH0gYG51bGxgIGlmIHZhbGlkLCBvdGhlcndpc2UgdGhlIHJlYXNvbiB3aHkgaXQgaXMgbm90XG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIFNlZ21lbnQudmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1lc3NhZ2UpIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UgIT09IFwib2JqZWN0XCIgfHwgbWVzc2FnZSA9PT0gbnVsbClcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwib2JqZWN0IGV4cGVjdGVkXCI7XG4gICAgICAgICAgICAgICAgaWYgKG1lc3NhZ2UuYmVnaW4gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiYmVnaW5cIikpXG4gICAgICAgICAgICAgICAgICAgIGlmICghJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuYmVnaW4pICYmICEobWVzc2FnZS5iZWdpbiAmJiAkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5iZWdpbi5sb3cpICYmICR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmJlZ2luLmhpZ2gpKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcImJlZ2luOiBpbnRlZ2VyfExvbmcgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgICAgICBpZiAobWVzc2FnZS5lbmQgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiZW5kXCIpKVxuICAgICAgICAgICAgICAgICAgICBpZiAoISR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmVuZCkgJiYgIShtZXNzYWdlLmVuZCAmJiAkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5lbmQubG93KSAmJiAkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5lbmQuaGlnaCkpKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiZW5kOiBpbnRlZ2VyfExvbmcgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogQ3JlYXRlcyBhIFNlZ21lbnQgbWVzc2FnZSBmcm9tIGEgcGxhaW4gb2JqZWN0LiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byB0aGVpciByZXNwZWN0aXZlIGludGVybmFsIHR5cGVzLlxuICAgICAgICAgICAgICogQGZ1bmN0aW9uIGZyb21PYmplY3RcbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvLlNlZ21lbnRcbiAgICAgICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG9iamVjdCBQbGFpbiBvYmplY3RcbiAgICAgICAgICAgICAqIEByZXR1cm5zIHtvbm54LlRlbnNvclByb3RvLlNlZ21lbnR9IFNlZ21lbnRcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgU2VnbWVudC5mcm9tT2JqZWN0ID0gZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgICAgICAgICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgJHJvb3Qub25ueC5UZW5zb3JQcm90by5TZWdtZW50KVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gb2JqZWN0O1xuICAgICAgICAgICAgICAgIHZhciBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVGVuc29yUHJvdG8uU2VnbWVudCgpO1xuICAgICAgICAgICAgICAgIGlmIChvYmplY3QuYmVnaW4gIT0gbnVsbClcbiAgICAgICAgICAgICAgICAgICAgaWYgKCR1dGlsLkxvbmcpXG4gICAgICAgICAgICAgICAgICAgICAgICAobWVzc2FnZS5iZWdpbiA9ICR1dGlsLkxvbmcuZnJvbVZhbHVlKG9iamVjdC5iZWdpbikpLnVuc2lnbmVkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuYmVnaW4gPT09IFwic3RyaW5nXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmJlZ2luID0gcGFyc2VJbnQob2JqZWN0LmJlZ2luLCAxMCk7XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuYmVnaW4gPT09IFwibnVtYmVyXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmJlZ2luID0gb2JqZWN0LmJlZ2luO1xuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LmJlZ2luID09PSBcIm9iamVjdFwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5iZWdpbiA9IG5ldyAkdXRpbC5Mb25nQml0cyhvYmplY3QuYmVnaW4ubG93ID4+PiAwLCBvYmplY3QuYmVnaW4uaGlnaCA+Pj4gMCkudG9OdW1iZXIoKTtcbiAgICAgICAgICAgICAgICBpZiAob2JqZWN0LmVuZCAhPSBudWxsKVxuICAgICAgICAgICAgICAgICAgICBpZiAoJHV0aWwuTG9uZylcbiAgICAgICAgICAgICAgICAgICAgICAgIChtZXNzYWdlLmVuZCA9ICR1dGlsLkxvbmcuZnJvbVZhbHVlKG9iamVjdC5lbmQpKS51bnNpZ25lZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LmVuZCA9PT0gXCJzdHJpbmdcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZW5kID0gcGFyc2VJbnQob2JqZWN0LmVuZCwgMTApO1xuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LmVuZCA9PT0gXCJudW1iZXJcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZW5kID0gb2JqZWN0LmVuZDtcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9iamVjdC5lbmQgPT09IFwib2JqZWN0XCIpXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmVuZCA9IG5ldyAkdXRpbC5Mb25nQml0cyhvYmplY3QuZW5kLmxvdyA+Pj4gMCwgb2JqZWN0LmVuZC5oaWdoID4+PiAwKS50b051bWJlcigpO1xuICAgICAgICAgICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBDcmVhdGVzIGEgcGxhaW4gb2JqZWN0IGZyb20gYSBTZWdtZW50IG1lc3NhZ2UuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIG90aGVyIHR5cGVzIGlmIHNwZWNpZmllZC5cbiAgICAgICAgICAgICAqIEBmdW5jdGlvbiB0b09iamVjdFxuICAgICAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yUHJvdG8uU2VnbWVudFxuICAgICAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgICAgICogQHBhcmFtIHtvbm54LlRlbnNvclByb3RvLlNlZ21lbnR9IG1lc3NhZ2UgU2VnbWVudFxuICAgICAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuSUNvbnZlcnNpb25PcHRpb25zfSBbb3B0aW9uc10gQ29udmVyc2lvbiBvcHRpb25zXG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IFBsYWluIG9iamVjdFxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBTZWdtZW50LnRvT2JqZWN0ID0gZnVuY3Rpb24gdG9PYmplY3QobWVzc2FnZSwgb3B0aW9ucykge1xuICAgICAgICAgICAgICAgIGlmICghb3B0aW9ucylcbiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucyA9IHt9O1xuICAgICAgICAgICAgICAgIHZhciBvYmplY3QgPSB7fTtcbiAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5kZWZhdWx0cykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoJHV0aWwuTG9uZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGxvbmcgPSBuZXcgJHV0aWwuTG9uZygwLCAwLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QuYmVnaW4gPSBvcHRpb25zLmxvbmdzID09PSBTdHJpbmcgPyBsb25nLnRvU3RyaW5nKCkgOiBvcHRpb25zLmxvbmdzID09PSBOdW1iZXIgPyBsb25nLnRvTnVtYmVyKCkgOiBsb25nO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC5iZWdpbiA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/IFwiMFwiIDogMDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCR1dGlsLkxvbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBsb25nID0gbmV3ICR1dGlsLkxvbmcoMCwgMCwgZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LmVuZCA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/IGxvbmcudG9TdHJpbmcoKSA6IG9wdGlvbnMubG9uZ3MgPT09IE51bWJlciA/IGxvbmcudG9OdW1iZXIoKSA6IGxvbmc7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LmVuZCA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/IFwiMFwiIDogMDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKG1lc3NhZ2UuYmVnaW4gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiYmVnaW5cIikpXG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZS5iZWdpbiA9PT0gXCJudW1iZXJcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC5iZWdpbiA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/IFN0cmluZyhtZXNzYWdlLmJlZ2luKSA6IG1lc3NhZ2UuYmVnaW47XG4gICAgICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC5iZWdpbiA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/ICR1dGlsLkxvbmcucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobWVzc2FnZS5iZWdpbikgOiBvcHRpb25zLmxvbmdzID09PSBOdW1iZXIgPyBuZXcgJHV0aWwuTG9uZ0JpdHMobWVzc2FnZS5iZWdpbi5sb3cgPj4+IDAsIG1lc3NhZ2UuYmVnaW4uaGlnaCA+Pj4gMCkudG9OdW1iZXIoKSA6IG1lc3NhZ2UuYmVnaW47XG4gICAgICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZW5kICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImVuZFwiKSlcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlLmVuZCA9PT0gXCJudW1iZXJcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC5lbmQgPSBvcHRpb25zLmxvbmdzID09PSBTdHJpbmcgPyBTdHJpbmcobWVzc2FnZS5lbmQpIDogbWVzc2FnZS5lbmQ7XG4gICAgICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC5lbmQgPSBvcHRpb25zLmxvbmdzID09PSBTdHJpbmcgPyAkdXRpbC5Mb25nLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG1lc3NhZ2UuZW5kKSA6IG9wdGlvbnMubG9uZ3MgPT09IE51bWJlciA/IG5ldyAkdXRpbC5Mb25nQml0cyhtZXNzYWdlLmVuZC5sb3cgPj4+IDAsIG1lc3NhZ2UuZW5kLmhpZ2ggPj4+IDApLnRvTnVtYmVyKCkgOiBtZXNzYWdlLmVuZDtcbiAgICAgICAgICAgICAgICByZXR1cm4gb2JqZWN0O1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBDb252ZXJ0cyB0aGlzIFNlZ21lbnQgdG8gSlNPTi5cbiAgICAgICAgICAgICAqIEBmdW5jdGlvbiB0b0pTT05cbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclByb3RvLlNlZ21lbnRcbiAgICAgICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBKU09OIG9iamVjdFxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBTZWdtZW50LnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04oKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IudG9PYmplY3QodGhpcywgJHByb3RvYnVmLnV0aWwudG9KU09OT3B0aW9ucyk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICByZXR1cm4gU2VnbWVudDtcbiAgICAgICAgfSkoKTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRGF0YUxvY2F0aW9uIGVudW0uXG4gICAgICAgICAqIEBuYW1lIG9ubnguVGVuc29yUHJvdG8uRGF0YUxvY2F0aW9uXG4gICAgICAgICAqIEBlbnVtIHtzdHJpbmd9XG4gICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBERUZBVUxUPTAgREVGQVVMVCB2YWx1ZVxuICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gRVhURVJOQUw9MSBFWFRFUk5BTCB2YWx1ZVxuICAgICAgICAgKi9cbiAgICAgICAgVGVuc29yUHJvdG8uRGF0YUxvY2F0aW9uID0gKGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgdmFyIHZhbHVlc0J5SWQgPSB7fSwgdmFsdWVzID0gT2JqZWN0LmNyZWF0ZSh2YWx1ZXNCeUlkKTtcbiAgICAgICAgICAgIHZhbHVlc1t2YWx1ZXNCeUlkWzBdID0gXCJERUZBVUxUXCJdID0gMDtcbiAgICAgICAgICAgIHZhbHVlc1t2YWx1ZXNCeUlkWzFdID0gXCJFWFRFUk5BTFwiXSA9IDE7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWVzO1xuICAgICAgICB9KSgpO1xuXG4gICAgICAgIHJldHVybiBUZW5zb3JQcm90bztcbiAgICB9KSgpO1xuXG4gICAgb25ueC5UZW5zb3JTaGFwZVByb3RvID0gKGZ1bmN0aW9uKCkge1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBQcm9wZXJ0aWVzIG9mIGEgVGVuc29yU2hhcGVQcm90by5cbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgICAgICogQGludGVyZmFjZSBJVGVuc29yU2hhcGVQcm90b1xuICAgICAgICAgKiBAcHJvcGVydHkge0FycmF5Ljxvbm54LlRlbnNvclNoYXBlUHJvdG8uSURpbWVuc2lvbj58bnVsbH0gW2RpbV0gVGVuc29yU2hhcGVQcm90byBkaW1cbiAgICAgICAgICovXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENvbnN0cnVjdHMgYSBuZXcgVGVuc29yU2hhcGVQcm90by5cbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgICAgICogQGNsYXNzZGVzYyBSZXByZXNlbnRzIGEgVGVuc29yU2hhcGVQcm90by5cbiAgICAgICAgICogQGltcGxlbWVudHMgSVRlbnNvclNoYXBlUHJvdG9cbiAgICAgICAgICogQGNvbnN0cnVjdG9yXG4gICAgICAgICAqIEBwYXJhbSB7b25ueC5JVGVuc29yU2hhcGVQcm90bz19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAgICAgKi9cbiAgICAgICAgZnVuY3Rpb24gVGVuc29yU2hhcGVQcm90byhwcm9wZXJ0aWVzKSB7XG4gICAgICAgICAgICB0aGlzLmRpbSA9IFtdO1xuICAgICAgICAgICAgaWYgKHByb3BlcnRpZXMpXG4gICAgICAgICAgICAgICAgZm9yICh2YXIga2V5cyA9IE9iamVjdC5rZXlzKHByb3BlcnRpZXMpLCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzW2tleXNbaV1dICE9IG51bGwpXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzW2tleXNbaV1dID0gcHJvcGVydGllc1trZXlzW2ldXTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUZW5zb3JTaGFwZVByb3RvIGRpbS5cbiAgICAgICAgICogQG1lbWJlciB7QXJyYXkuPG9ubnguVGVuc29yU2hhcGVQcm90by5JRGltZW5zaW9uPn0gZGltXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclNoYXBlUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqL1xuICAgICAgICBUZW5zb3JTaGFwZVByb3RvLnByb3RvdHlwZS5kaW0gPSAkdXRpbC5lbXB0eUFycmF5O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDcmVhdGVzIGEgbmV3IFRlbnNvclNoYXBlUHJvdG8gaW5zdGFuY2UgdXNpbmcgdGhlIHNwZWNpZmllZCBwcm9wZXJ0aWVzLlxuICAgICAgICAgKiBAZnVuY3Rpb24gY3JlYXRlXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclNoYXBlUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge29ubnguSVRlbnNvclNoYXBlUHJvdG89fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgICAgICogQHJldHVybnMge29ubnguVGVuc29yU2hhcGVQcm90b30gVGVuc29yU2hhcGVQcm90byBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgVGVuc29yU2hhcGVQcm90by5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUocHJvcGVydGllcykge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBUZW5zb3JTaGFwZVByb3RvKHByb3BlcnRpZXMpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgVGVuc29yU2hhcGVQcm90byBtZXNzYWdlLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlRlbnNvclNoYXBlUHJvdG8udmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICAgICAqIEBmdW5jdGlvbiBlbmNvZGVcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7b25ueC5JVGVuc29yU2hhcGVQcm90b30gbWVzc2FnZSBUZW5zb3JTaGFwZVByb3RvIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAgICAgKi9cbiAgICAgICAgVGVuc29yU2hhcGVQcm90by5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICAgICAgICBpZiAoIXdyaXRlcilcbiAgICAgICAgICAgICAgICB3cml0ZXIgPSAkV3JpdGVyLmNyZWF0ZSgpO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZGltICE9IG51bGwgJiYgbWVzc2FnZS5kaW0ubGVuZ3RoKVxuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5kaW0ubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICAgICAgICAgICRyb290Lm9ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb24uZW5jb2RlKG1lc3NhZ2UuZGltW2ldLCB3cml0ZXIudWludDMyKC8qIGlkIDEsIHdpcmVUeXBlIDIgPSovMTApLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICAgICAgICByZXR1cm4gd3JpdGVyO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgVGVuc29yU2hhcGVQcm90byBtZXNzYWdlLCBsZW5ndGggZGVsaW1pdGVkLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlRlbnNvclNoYXBlUHJvdG8udmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICAgICAqIEBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWRcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7b25ueC5JVGVuc29yU2hhcGVQcm90b30gbWVzc2FnZSBUZW5zb3JTaGFwZVByb3RvIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAgICAgKi9cbiAgICAgICAgVGVuc29yU2hhcGVQcm90by5lbmNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWQobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5lbmNvZGUobWVzc2FnZSwgd3JpdGVyKS5sZGVsaW0oKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRGVjb2RlcyBhIFRlbnNvclNoYXBlUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlci5cbiAgICAgICAgICogQGZ1bmN0aW9uIGRlY29kZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoXSBNZXNzYWdlIGxlbmd0aCBpZiBrbm93biBiZWZvcmVoYW5kXG4gICAgICAgICAqIEByZXR1cm5zIHtvbm54LlRlbnNvclNoYXBlUHJvdG99IFRlbnNvclNoYXBlUHJvdG9cbiAgICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICAgICAqL1xuICAgICAgICBUZW5zb3JTaGFwZVByb3RvLmRlY29kZSA9IGZ1bmN0aW9uIGRlY29kZShyZWFkZXIsIGxlbmd0aCkge1xuICAgICAgICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpXG4gICAgICAgICAgICAgICAgcmVhZGVyID0gJFJlYWRlci5jcmVhdGUocmVhZGVyKTtcbiAgICAgICAgICAgIHZhciBlbmQgPSBsZW5ndGggPT09IHVuZGVmaW5lZCA/IHJlYWRlci5sZW4gOiByZWFkZXIucG9zICsgbGVuZ3RoLCBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVGVuc29yU2hhcGVQcm90bygpO1xuICAgICAgICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQpIHtcbiAgICAgICAgICAgICAgICB2YXIgdGFnID0gcmVhZGVyLnVpbnQzMigpO1xuICAgICAgICAgICAgICAgIHN3aXRjaCAodGFnID4+PiAzKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAxOlxuICAgICAgICAgICAgICAgICAgICBpZiAoIShtZXNzYWdlLmRpbSAmJiBtZXNzYWdlLmRpbS5sZW5ndGgpKVxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5kaW0gPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5kaW0ucHVzaCgkcm9vdC5vbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSkpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICByZWFkZXIuc2tpcFR5cGUodGFnICYgNyk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEZWNvZGVzIGEgVGVuc29yU2hhcGVQcm90byBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLCBsZW5ndGggZGVsaW1pdGVkLlxuICAgICAgICAgKiBAZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclNoYXBlUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgICAgICogQHJldHVybnMge29ubnguVGVuc29yU2hhcGVQcm90b30gVGVuc29yU2hhcGVQcm90b1xuICAgICAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgICAgICovXG4gICAgICAgIFRlbnNvclNoYXBlUHJvdG8uZGVjb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkKHJlYWRlcikge1xuICAgICAgICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpXG4gICAgICAgICAgICAgICAgcmVhZGVyID0gbmV3ICRSZWFkZXIocmVhZGVyKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFZlcmlmaWVzIGEgVGVuc29yU2hhcGVQcm90byBtZXNzYWdlLlxuICAgICAgICAgKiBAZnVuY3Rpb24gdmVyaWZ5XG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclNoYXBlUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCo+fSBtZXNzYWdlIFBsYWluIG9iamVjdCB0byB2ZXJpZnlcbiAgICAgICAgICogQHJldHVybnMge3N0cmluZ3xudWxsfSBgbnVsbGAgaWYgdmFsaWQsIG90aGVyd2lzZSB0aGUgcmVhc29uIHdoeSBpdCBpcyBub3RcbiAgICAgICAgICovXG4gICAgICAgIFRlbnNvclNoYXBlUHJvdG8udmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1lc3NhZ2UpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSAhPT0gXCJvYmplY3RcIiB8fCBtZXNzYWdlID09PSBudWxsKVxuICAgICAgICAgICAgICAgIHJldHVybiBcIm9iamVjdCBleHBlY3RlZFwiO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZGltICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImRpbVwiKSkge1xuICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtZXNzYWdlLmRpbSkpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcImRpbTogYXJyYXkgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1lc3NhZ2UuZGltLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBlcnJvciA9ICRyb290Lm9ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb24udmVyaWZ5KG1lc3NhZ2UuZGltW2ldKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiZGltLlwiICsgZXJyb3I7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENyZWF0ZXMgYSBUZW5zb3JTaGFwZVByb3RvIG1lc3NhZ2UgZnJvbSBhIHBsYWluIG9iamVjdC4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gdGhlaXIgcmVzcGVjdGl2ZSBpbnRlcm5hbCB0eXBlcy5cbiAgICAgICAgICogQGZ1bmN0aW9uIGZyb21PYmplY3RcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG9iamVjdCBQbGFpbiBvYmplY3RcbiAgICAgICAgICogQHJldHVybnMge29ubnguVGVuc29yU2hhcGVQcm90b30gVGVuc29yU2hhcGVQcm90b1xuICAgICAgICAgKi9cbiAgICAgICAgVGVuc29yU2hhcGVQcm90by5mcm9tT2JqZWN0ID0gZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgICAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiAkcm9vdC5vbm54LlRlbnNvclNoYXBlUHJvdG8pXG4gICAgICAgICAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgICAgICAgIHZhciBtZXNzYWdlID0gbmV3ICRyb290Lm9ubnguVGVuc29yU2hhcGVQcm90bygpO1xuICAgICAgICAgICAgaWYgKG9iamVjdC5kaW0pIHtcbiAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkob2JqZWN0LmRpbSkpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIi5vbm54LlRlbnNvclNoYXBlUHJvdG8uZGltOiBhcnJheSBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICBtZXNzYWdlLmRpbSA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqZWN0LmRpbS5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5kaW1baV0gIT09IFwib2JqZWN0XCIpXG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCIub25ueC5UZW5zb3JTaGFwZVByb3RvLmRpbTogb2JqZWN0IGV4cGVjdGVkXCIpO1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmRpbVtpXSA9ICRyb290Lm9ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb24uZnJvbU9iamVjdChvYmplY3QuZGltW2ldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ3JlYXRlcyBhIHBsYWluIG9iamVjdCBmcm9tIGEgVGVuc29yU2hhcGVQcm90byBtZXNzYWdlLiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byBvdGhlciB0eXBlcyBpZiBzcGVjaWZpZWQuXG4gICAgICAgICAqIEBmdW5jdGlvbiB0b09iamVjdFxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtvbm54LlRlbnNvclNoYXBlUHJvdG99IG1lc3NhZ2UgVGVuc29yU2hhcGVQcm90b1xuICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5JQ29udmVyc2lvbk9wdGlvbnN9IFtvcHRpb25zXSBDb252ZXJzaW9uIG9wdGlvbnNcbiAgICAgICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBQbGFpbiBvYmplY3RcbiAgICAgICAgICovXG4gICAgICAgIFRlbnNvclNoYXBlUHJvdG8udG9PYmplY3QgPSBmdW5jdGlvbiB0b09iamVjdChtZXNzYWdlLCBvcHRpb25zKSB7XG4gICAgICAgICAgICBpZiAoIW9wdGlvbnMpXG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IHt9O1xuICAgICAgICAgICAgdmFyIG9iamVjdCA9IHt9O1xuICAgICAgICAgICAgaWYgKG9wdGlvbnMuYXJyYXlzIHx8IG9wdGlvbnMuZGVmYXVsdHMpXG4gICAgICAgICAgICAgICAgb2JqZWN0LmRpbSA9IFtdO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZGltICYmIG1lc3NhZ2UuZGltLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIG9iamVjdC5kaW0gPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1lc3NhZ2UuZGltLmxlbmd0aDsgKytqKVxuICAgICAgICAgICAgICAgICAgICBvYmplY3QuZGltW2pdID0gJHJvb3Qub25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvbi50b09iamVjdChtZXNzYWdlLmRpbVtqXSwgb3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gb2JqZWN0O1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDb252ZXJ0cyB0aGlzIFRlbnNvclNoYXBlUHJvdG8gdG8gSlNPTi5cbiAgICAgICAgICogQGZ1bmN0aW9uIHRvSlNPTlxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IEpTT04gb2JqZWN0XG4gICAgICAgICAqL1xuICAgICAgICBUZW5zb3JTaGFwZVByb3RvLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04oKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci50b09iamVjdCh0aGlzLCAkcHJvdG9idWYudXRpbC50b0pTT05PcHRpb25zKTtcbiAgICAgICAgfTtcblxuICAgICAgICBUZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvbiA9IChmdW5jdGlvbigpIHtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBQcm9wZXJ0aWVzIG9mIGEgRGltZW5zaW9uLlxuICAgICAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90b1xuICAgICAgICAgICAgICogQGludGVyZmFjZSBJRGltZW5zaW9uXG4gICAgICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcnxMb25nfG51bGx9IFtkaW1WYWx1ZV0gRGltZW5zaW9uIGRpbVZhbHVlXG4gICAgICAgICAgICAgKiBAcHJvcGVydHkge3N0cmluZ3xudWxsfSBbZGltUGFyYW1dIERpbWVuc2lvbiBkaW1QYXJhbVxuICAgICAgICAgICAgICogQHByb3BlcnR5IHtzdHJpbmd8bnVsbH0gW2Rlbm90YXRpb25dIERpbWVuc2lvbiBkZW5vdGF0aW9uXG4gICAgICAgICAgICAgKi9cblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IERpbWVuc2lvbi5cbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclNoYXBlUHJvdG9cbiAgICAgICAgICAgICAqIEBjbGFzc2Rlc2MgUmVwcmVzZW50cyBhIERpbWVuc2lvbi5cbiAgICAgICAgICAgICAqIEBpbXBsZW1lbnRzIElEaW1lbnNpb25cbiAgICAgICAgICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAgICAgICAgICogQHBhcmFtIHtvbm54LlRlbnNvclNoYXBlUHJvdG8uSURpbWVuc2lvbj19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBmdW5jdGlvbiBEaW1lbnNpb24ocHJvcGVydGllcykge1xuICAgICAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzKVxuICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBrZXlzID0gT2JqZWN0LmtleXMocHJvcGVydGllcyksIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzW2tleXNbaV1dICE9IG51bGwpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpc1trZXlzW2ldXSA9IHByb3BlcnRpZXNba2V5c1tpXV07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogRGltZW5zaW9uIGRpbVZhbHVlLlxuICAgICAgICAgICAgICogQG1lbWJlciB7bnVtYmVyfExvbmd9IGRpbVZhbHVlXG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvblxuICAgICAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIERpbWVuc2lvbi5wcm90b3R5cGUuZGltVmFsdWUgPSAkdXRpbC5Mb25nID8gJHV0aWwuTG9uZy5mcm9tQml0cygwLDAsZmFsc2UpIDogMDtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBEaW1lbnNpb24gZGltUGFyYW0uXG4gICAgICAgICAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IGRpbVBhcmFtXG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvblxuICAgICAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIERpbWVuc2lvbi5wcm90b3R5cGUuZGltUGFyYW0gPSBcIlwiO1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIERpbWVuc2lvbiBkZW5vdGF0aW9uLlxuICAgICAgICAgICAgICogQG1lbWJlciB7c3RyaW5nfSBkZW5vdGF0aW9uXG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvblxuICAgICAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIERpbWVuc2lvbi5wcm90b3R5cGUuZGVub3RhdGlvbiA9IFwiXCI7XG5cbiAgICAgICAgICAgIC8vIE9uZU9mIGZpZWxkIG5hbWVzIGJvdW5kIHRvIHZpcnR1YWwgZ2V0dGVycyBhbmQgc2V0dGVyc1xuICAgICAgICAgICAgdmFyICRvbmVPZkZpZWxkcztcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBEaW1lbnNpb24gdmFsdWUuXG4gICAgICAgICAgICAgKiBAbWVtYmVyIHtcImRpbVZhbHVlXCJ8XCJkaW1QYXJhbVwifHVuZGVmaW5lZH0gdmFsdWVcbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uXG4gICAgICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KERpbWVuc2lvbi5wcm90b3R5cGUsIFwidmFsdWVcIiwge1xuICAgICAgICAgICAgICAgIGdldDogJHV0aWwub25lT2ZHZXR0ZXIoJG9uZU9mRmllbGRzID0gW1wiZGltVmFsdWVcIiwgXCJkaW1QYXJhbVwiXSksXG4gICAgICAgICAgICAgICAgc2V0OiAkdXRpbC5vbmVPZlNldHRlcigkb25lT2ZGaWVsZHMpXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBDcmVhdGVzIGEgbmV3IERpbWVuc2lvbiBpbnN0YW5jZSB1c2luZyB0aGUgc3BlY2lmaWVkIHByb3BlcnRpZXMuXG4gICAgICAgICAgICAgKiBAZnVuY3Rpb24gY3JlYXRlXG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvblxuICAgICAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgICAgICogQHBhcmFtIHtvbm54LlRlbnNvclNoYXBlUHJvdG8uSURpbWVuc2lvbj19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAgICAgICAgICogQHJldHVybnMge29ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb259IERpbWVuc2lvbiBpbnN0YW5jZVxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBEaW1lbnNpb24uY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKHByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IERpbWVuc2lvbihwcm9wZXJ0aWVzKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIERpbWVuc2lvbiBtZXNzYWdlLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAgICAgICAgICogQGZ1bmN0aW9uIGVuY29kZVxuICAgICAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb25cbiAgICAgICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICAgICAqIEBwYXJhbSB7b25ueC5UZW5zb3JTaGFwZVByb3RvLklEaW1lbnNpb259IG1lc3NhZ2UgRGltZW5zaW9uIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIERpbWVuc2lvbi5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICAgICAgICAgICAgaWYgKCF3cml0ZXIpXG4gICAgICAgICAgICAgICAgICAgIHdyaXRlciA9ICRXcml0ZXIuY3JlYXRlKCk7XG4gICAgICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZGltVmFsdWUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiZGltVmFsdWVcIikpXG4gICAgICAgICAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMSwgd2lyZVR5cGUgMCA9Ki84KS5pbnQ2NChtZXNzYWdlLmRpbVZhbHVlKTtcbiAgICAgICAgICAgICAgICBpZiAobWVzc2FnZS5kaW1QYXJhbSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJkaW1QYXJhbVwiKSlcbiAgICAgICAgICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAyLCB3aXJlVHlwZSAyID0qLzE4KS5zdHJpbmcobWVzc2FnZS5kaW1QYXJhbSk7XG4gICAgICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZGVub3RhdGlvbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJkZW5vdGF0aW9uXCIpKVxuICAgICAgICAgICAgICAgICAgICB3cml0ZXIudWludDMyKC8qIGlkIDMsIHdpcmVUeXBlIDIgPSovMjYpLnN0cmluZyhtZXNzYWdlLmRlbm90YXRpb24pO1xuICAgICAgICAgICAgICAgIHJldHVybiB3cml0ZXI7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBEaW1lbnNpb24gbWVzc2FnZSwgbGVuZ3RoIGRlbGltaXRlZC4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvbi52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgICAgICAgICAqIEBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWRcbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uXG4gICAgICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAgICAgKiBAcGFyYW0ge29ubnguVGVuc29yU2hhcGVQcm90by5JRGltZW5zaW9ufSBtZXNzYWdlIERpbWVuc2lvbiBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAgICAgICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBEaW1lbnNpb24uZW5jb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVuY29kZShtZXNzYWdlLCB3cml0ZXIpLmxkZWxpbSgpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBEZWNvZGVzIGEgRGltZW5zaW9uIG1lc3NhZ2UgZnJvbSB0aGUgc3BlY2lmaWVkIHJlYWRlciBvciBidWZmZXIuXG4gICAgICAgICAgICAgKiBAZnVuY3Rpb24gZGVjb2RlXG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvblxuICAgICAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuUmVhZGVyfFVpbnQ4QXJyYXl9IHJlYWRlciBSZWFkZXIgb3IgYnVmZmVyIHRvIGRlY29kZSBmcm9tXG4gICAgICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aF0gTWVzc2FnZSBsZW5ndGggaWYga25vd24gYmVmb3JlaGFuZFxuICAgICAgICAgICAgICogQHJldHVybnMge29ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb259IERpbWVuc2lvblxuICAgICAgICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgICAgICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBEaW1lbnNpb24uZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKHJlYWRlciwgbGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpXG4gICAgICAgICAgICAgICAgICAgIHJlYWRlciA9ICRSZWFkZXIuY3JlYXRlKHJlYWRlcik7XG4gICAgICAgICAgICAgICAgdmFyIGVuZCA9IGxlbmd0aCA9PT0gdW5kZWZpbmVkID8gcmVhZGVyLmxlbiA6IHJlYWRlci5wb3MgKyBsZW5ndGgsIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvbigpO1xuICAgICAgICAgICAgICAgIHdoaWxlIChyZWFkZXIucG9zIDwgZW5kKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciB0YWcgPSByZWFkZXIudWludDMyKCk7XG4gICAgICAgICAgICAgICAgICAgIHN3aXRjaCAodGFnID4+PiAzKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMTpcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZGltVmFsdWUgPSByZWFkZXIuaW50NjQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmRpbVBhcmFtID0gcmVhZGVyLnN0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZGVub3RhdGlvbiA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICAgICAgcmVhZGVyLnNraXBUeXBlKHRhZyAmIDcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIERlY29kZXMgYSBEaW1lbnNpb24gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlciwgbGVuZ3RoIGRlbGltaXRlZC5cbiAgICAgICAgICAgICAqIEBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWRcbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9uXG4gICAgICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgICAgICAgICAqIEByZXR1cm5zIHtvbm54LlRlbnNvclNoYXBlUHJvdG8uRGltZW5zaW9ufSBEaW1lbnNpb25cbiAgICAgICAgICAgICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgcGF5bG9hZCBpcyBub3QgYSByZWFkZXIgb3IgdmFsaWQgYnVmZmVyXG4gICAgICAgICAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgRGltZW5zaW9uLmRlY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZChyZWFkZXIpIHtcbiAgICAgICAgICAgICAgICBpZiAoIShyZWFkZXIgaW5zdGFuY2VvZiAkUmVhZGVyKSlcbiAgICAgICAgICAgICAgICAgICAgcmVhZGVyID0gbmV3ICRSZWFkZXIocmVhZGVyKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5kZWNvZGUocmVhZGVyLCByZWFkZXIudWludDMyKCkpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBWZXJpZmllcyBhIERpbWVuc2lvbiBtZXNzYWdlLlxuICAgICAgICAgICAgICogQGZ1bmN0aW9uIHZlcmlmeVxuICAgICAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb25cbiAgICAgICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG1lc3NhZ2UgUGxhaW4gb2JqZWN0IHRvIHZlcmlmeVxuICAgICAgICAgICAgICogQHJldHVybnMge3N0cmluZ3xudWxsfSBgbnVsbGAgaWYgdmFsaWQsIG90aGVyd2lzZSB0aGUgcmVhc29uIHdoeSBpdCBpcyBub3RcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgRGltZW5zaW9uLnZlcmlmeSA9IGZ1bmN0aW9uIHZlcmlmeShtZXNzYWdlKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlICE9PSBcIm9iamVjdFwiIHx8IG1lc3NhZ2UgPT09IG51bGwpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm9iamVjdCBleHBlY3RlZFwiO1xuICAgICAgICAgICAgICAgIHZhciBwcm9wZXJ0aWVzID0ge307XG4gICAgICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZGltVmFsdWUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiZGltVmFsdWVcIikpIHtcbiAgICAgICAgICAgICAgICAgICAgcHJvcGVydGllcy52YWx1ZSA9IDE7XG4gICAgICAgICAgICAgICAgICAgIGlmICghJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UuZGltVmFsdWUpICYmICEobWVzc2FnZS5kaW1WYWx1ZSAmJiAkdXRpbC5pc0ludGVnZXIobWVzc2FnZS5kaW1WYWx1ZS5sb3cpICYmICR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmRpbVZhbHVlLmhpZ2gpKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcImRpbVZhbHVlOiBpbnRlZ2VyfExvbmcgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZGltUGFyYW0gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiZGltUGFyYW1cIikpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHByb3BlcnRpZXMudmFsdWUgPT09IDEpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJ2YWx1ZTogbXVsdGlwbGUgdmFsdWVzXCI7XG4gICAgICAgICAgICAgICAgICAgIHByb3BlcnRpZXMudmFsdWUgPSAxO1xuICAgICAgICAgICAgICAgICAgICBpZiAoISR1dGlsLmlzU3RyaW5nKG1lc3NhZ2UuZGltUGFyYW0pKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiZGltUGFyYW06IHN0cmluZyBleHBlY3RlZFwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAobWVzc2FnZS5kZW5vdGF0aW9uICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImRlbm90YXRpb25cIikpXG4gICAgICAgICAgICAgICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5kZW5vdGF0aW9uKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcImRlbm90YXRpb246IHN0cmluZyBleHBlY3RlZFwiO1xuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBDcmVhdGVzIGEgRGltZW5zaW9uIG1lc3NhZ2UgZnJvbSBhIHBsYWluIG9iamVjdC4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gdGhlaXIgcmVzcGVjdGl2ZSBpbnRlcm5hbCB0eXBlcy5cbiAgICAgICAgICAgICAqIEBmdW5jdGlvbiBmcm9tT2JqZWN0XG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvblxuICAgICAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gb2JqZWN0IFBsYWluIG9iamVjdFxuICAgICAgICAgICAgICogQHJldHVybnMge29ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb259IERpbWVuc2lvblxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBEaW1lbnNpb24uZnJvbU9iamVjdCA9IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgICAgICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mICRyb290Lm9ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb24pXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICAgICAgICAgICAgdmFyIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvbigpO1xuICAgICAgICAgICAgICAgIGlmIChvYmplY3QuZGltVmFsdWUgIT0gbnVsbClcbiAgICAgICAgICAgICAgICAgICAgaWYgKCR1dGlsLkxvbmcpXG4gICAgICAgICAgICAgICAgICAgICAgICAobWVzc2FnZS5kaW1WYWx1ZSA9ICR1dGlsLkxvbmcuZnJvbVZhbHVlKG9iamVjdC5kaW1WYWx1ZSkpLnVuc2lnbmVkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuZGltVmFsdWUgPT09IFwic3RyaW5nXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmRpbVZhbHVlID0gcGFyc2VJbnQob2JqZWN0LmRpbVZhbHVlLCAxMCk7XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QuZGltVmFsdWUgPT09IFwibnVtYmVyXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmRpbVZhbHVlID0gb2JqZWN0LmRpbVZhbHVlO1xuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LmRpbVZhbHVlID09PSBcIm9iamVjdFwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5kaW1WYWx1ZSA9IG5ldyAkdXRpbC5Mb25nQml0cyhvYmplY3QuZGltVmFsdWUubG93ID4+PiAwLCBvYmplY3QuZGltVmFsdWUuaGlnaCA+Pj4gMCkudG9OdW1iZXIoKTtcbiAgICAgICAgICAgICAgICBpZiAob2JqZWN0LmRpbVBhcmFtICE9IG51bGwpXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZGltUGFyYW0gPSBTdHJpbmcob2JqZWN0LmRpbVBhcmFtKTtcbiAgICAgICAgICAgICAgICBpZiAob2JqZWN0LmRlbm90YXRpb24gIT0gbnVsbClcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5kZW5vdGF0aW9uID0gU3RyaW5nKG9iamVjdC5kZW5vdGF0aW9uKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogQ3JlYXRlcyBhIHBsYWluIG9iamVjdCBmcm9tIGEgRGltZW5zaW9uIG1lc3NhZ2UuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIG90aGVyIHR5cGVzIGlmIHNwZWNpZmllZC5cbiAgICAgICAgICAgICAqIEBmdW5jdGlvbiB0b09iamVjdFxuICAgICAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVGVuc29yU2hhcGVQcm90by5EaW1lbnNpb25cbiAgICAgICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICAgICAqIEBwYXJhbSB7b25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvbn0gbWVzc2FnZSBEaW1lbnNpb25cbiAgICAgICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLklDb252ZXJzaW9uT3B0aW9uc30gW29wdGlvbnNdIENvbnZlcnNpb24gb3B0aW9uc1xuICAgICAgICAgICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBQbGFpbiBvYmplY3RcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgRGltZW5zaW9uLnRvT2JqZWN0ID0gZnVuY3Rpb24gdG9PYmplY3QobWVzc2FnZSwgb3B0aW9ucykge1xuICAgICAgICAgICAgICAgIGlmICghb3B0aW9ucylcbiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucyA9IHt9O1xuICAgICAgICAgICAgICAgIHZhciBvYmplY3QgPSB7fTtcbiAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5kZWZhdWx0cylcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LmRlbm90YXRpb24gPSBcIlwiO1xuICAgICAgICAgICAgICAgIGlmIChtZXNzYWdlLmRpbVZhbHVlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImRpbVZhbHVlXCIpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZS5kaW1WYWx1ZSA9PT0gXCJudW1iZXJcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC5kaW1WYWx1ZSA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/IFN0cmluZyhtZXNzYWdlLmRpbVZhbHVlKSA6IG1lc3NhZ2UuZGltVmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC5kaW1WYWx1ZSA9IG9wdGlvbnMubG9uZ3MgPT09IFN0cmluZyA/ICR1dGlsLkxvbmcucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobWVzc2FnZS5kaW1WYWx1ZSkgOiBvcHRpb25zLmxvbmdzID09PSBOdW1iZXIgPyBuZXcgJHV0aWwuTG9uZ0JpdHMobWVzc2FnZS5kaW1WYWx1ZS5sb3cgPj4+IDAsIG1lc3NhZ2UuZGltVmFsdWUuaGlnaCA+Pj4gMCkudG9OdW1iZXIoKSA6IG1lc3NhZ2UuZGltVmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLm9uZW9mcylcbiAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC52YWx1ZSA9IFwiZGltVmFsdWVcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZGltUGFyYW0gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiZGltUGFyYW1cIikpIHtcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LmRpbVBhcmFtID0gbWVzc2FnZS5kaW1QYXJhbTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMub25lb2ZzKVxuICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LnZhbHVlID0gXCJkaW1QYXJhbVwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAobWVzc2FnZS5kZW5vdGF0aW9uICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImRlbm90YXRpb25cIikpXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC5kZW5vdGF0aW9uID0gbWVzc2FnZS5kZW5vdGF0aW9uO1xuICAgICAgICAgICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIENvbnZlcnRzIHRoaXMgRGltZW5zaW9uIHRvIEpTT04uXG4gICAgICAgICAgICAgKiBAZnVuY3Rpb24gdG9KU09OXG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UZW5zb3JTaGFwZVByb3RvLkRpbWVuc2lvblxuICAgICAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IEpTT04gb2JqZWN0XG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIERpbWVuc2lvbi5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLnRvT2JqZWN0KHRoaXMsICRwcm90b2J1Zi51dGlsLnRvSlNPTk9wdGlvbnMpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgcmV0dXJuIERpbWVuc2lvbjtcbiAgICAgICAgfSkoKTtcblxuICAgICAgICByZXR1cm4gVGVuc29yU2hhcGVQcm90bztcbiAgICB9KSgpO1xuXG4gICAgb25ueC5UeXBlUHJvdG8gPSAoZnVuY3Rpb24oKSB7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFByb3BlcnRpZXMgb2YgYSBUeXBlUHJvdG8uXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54XG4gICAgICAgICAqIEBpbnRlcmZhY2UgSVR5cGVQcm90b1xuICAgICAgICAgKiBAcHJvcGVydHkge29ubnguVHlwZVByb3RvLklUZW5zb3J8bnVsbH0gW3RlbnNvclR5cGVdIFR5cGVQcm90byB0ZW5zb3JUeXBlXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtkZW5vdGF0aW9uXSBUeXBlUHJvdG8gZGVub3RhdGlvblxuICAgICAgICAgKi9cblxuICAgICAgICAvKipcbiAgICAgICAgICogQ29uc3RydWN0cyBhIG5ldyBUeXBlUHJvdG8uXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54XG4gICAgICAgICAqIEBjbGFzc2Rlc2MgUmVwcmVzZW50cyBhIFR5cGVQcm90by5cbiAgICAgICAgICogQGltcGxlbWVudHMgSVR5cGVQcm90b1xuICAgICAgICAgKiBAY29uc3RydWN0b3JcbiAgICAgICAgICogQHBhcmFtIHtvbm54LklUeXBlUHJvdG89fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgICAgICovXG4gICAgICAgIGZ1bmN0aW9uIFR5cGVQcm90byhwcm9wZXJ0aWVzKSB7XG4gICAgICAgICAgICBpZiAocHJvcGVydGllcylcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBrZXlzID0gT2JqZWN0LmtleXMocHJvcGVydGllcyksIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSlcbiAgICAgICAgICAgICAgICAgICAgaWYgKHByb3BlcnRpZXNba2V5c1tpXV0gIT0gbnVsbClcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNba2V5c1tpXV0gPSBwcm9wZXJ0aWVzW2tleXNbaV1dO1xuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFR5cGVQcm90byB0ZW5zb3JUeXBlLlxuICAgICAgICAgKiBAbWVtYmVyIHtvbm54LlR5cGVQcm90by5JVGVuc29yfG51bGx8dW5kZWZpbmVkfSB0ZW5zb3JUeXBlXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIFR5cGVQcm90by5wcm90b3R5cGUudGVuc29yVHlwZSA9IG51bGw7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFR5cGVQcm90byBkZW5vdGF0aW9uLlxuICAgICAgICAgKiBAbWVtYmVyIHtzdHJpbmd9IGRlbm90YXRpb25cbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgVHlwZVByb3RvLnByb3RvdHlwZS5kZW5vdGF0aW9uID0gXCJcIjtcblxuICAgICAgICAvLyBPbmVPZiBmaWVsZCBuYW1lcyBib3VuZCB0byB2aXJ0dWFsIGdldHRlcnMgYW5kIHNldHRlcnNcbiAgICAgICAgdmFyICRvbmVPZkZpZWxkcztcblxuICAgICAgICAvKipcbiAgICAgICAgICogVHlwZVByb3RvIHZhbHVlLlxuICAgICAgICAgKiBAbWVtYmVyIHtcInRlbnNvclR5cGVcInx1bmRlZmluZWR9IHZhbHVlXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICovXG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUeXBlUHJvdG8ucHJvdG90eXBlLCBcInZhbHVlXCIsIHtcbiAgICAgICAgICAgIGdldDogJHV0aWwub25lT2ZHZXR0ZXIoJG9uZU9mRmllbGRzID0gW1widGVuc29yVHlwZVwiXSksXG4gICAgICAgICAgICBzZXQ6ICR1dGlsLm9uZU9mU2V0dGVyKCRvbmVPZkZpZWxkcylcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENyZWF0ZXMgYSBuZXcgVHlwZVByb3RvIGluc3RhbmNlIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHJvcGVydGllcy5cbiAgICAgICAgICogQGZ1bmN0aW9uIGNyZWF0ZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge29ubnguSVR5cGVQcm90bz19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG99IFR5cGVQcm90byBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgVHlwZVByb3RvLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShwcm9wZXJ0aWVzKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFR5cGVQcm90byhwcm9wZXJ0aWVzKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIFR5cGVQcm90byBtZXNzYWdlLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlR5cGVQcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgICAgICogQGZ1bmN0aW9uIGVuY29kZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge29ubnguSVR5cGVQcm90b30gbWVzc2FnZSBUeXBlUHJvdG8gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICAgICAqL1xuICAgICAgICBUeXBlUHJvdG8uZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgICAgICAgaWYgKCF3cml0ZXIpXG4gICAgICAgICAgICAgICAgd3JpdGVyID0gJFdyaXRlci5jcmVhdGUoKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnRlbnNvclR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwidGVuc29yVHlwZVwiKSlcbiAgICAgICAgICAgICAgICAkcm9vdC5vbm54LlR5cGVQcm90by5UZW5zb3IuZW5jb2RlKG1lc3NhZ2UudGVuc29yVHlwZSwgd3JpdGVyLnVpbnQzMigvKiBpZCAxLCB3aXJlVHlwZSAyID0qLzEwKS5mb3JrKCkpLmxkZWxpbSgpO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZGVub3RhdGlvbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJkZW5vdGF0aW9uXCIpKVxuICAgICAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgNiwgd2lyZVR5cGUgMiA9Ki81MCkuc3RyaW5nKG1lc3NhZ2UuZGVub3RhdGlvbik7XG4gICAgICAgICAgICByZXR1cm4gd3JpdGVyO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBFbmNvZGVzIHRoZSBzcGVjaWZpZWQgVHlwZVByb3RvIG1lc3NhZ2UsIGxlbmd0aCBkZWxpbWl0ZWQuIERvZXMgbm90IGltcGxpY2l0bHkge0BsaW5rIG9ubnguVHlwZVByb3RvLnZlcmlmeXx2ZXJpZnl9IG1lc3NhZ2VzLlxuICAgICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7b25ueC5JVHlwZVByb3RvfSBtZXNzYWdlIFR5cGVQcm90byBtZXNzYWdlIG9yIHBsYWluIG9iamVjdCB0byBlbmNvZGVcbiAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgICAqIEByZXR1cm5zIHskcHJvdG9idWYuV3JpdGVyfSBXcml0ZXJcbiAgICAgICAgICovXG4gICAgICAgIFR5cGVQcm90by5lbmNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWQobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5lbmNvZGUobWVzc2FnZSwgd3JpdGVyKS5sZGVsaW0oKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRGVjb2RlcyBhIFR5cGVQcm90byBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLlxuICAgICAgICAgKiBAZnVuY3Rpb24gZGVjb2RlXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aF0gTWVzc2FnZSBsZW5ndGggaWYga25vd24gYmVmb3JlaGFuZFxuICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5UeXBlUHJvdG99IFR5cGVQcm90b1xuICAgICAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgICAgICovXG4gICAgICAgIFR5cGVQcm90by5kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUocmVhZGVyLCBsZW5ndGgpIHtcbiAgICAgICAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKVxuICAgICAgICAgICAgICAgIHJlYWRlciA9ICRSZWFkZXIuY3JlYXRlKHJlYWRlcik7XG4gICAgICAgICAgICB2YXIgZW5kID0gbGVuZ3RoID09PSB1bmRlZmluZWQgPyByZWFkZXIubGVuIDogcmVhZGVyLnBvcyArIGxlbmd0aCwgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlR5cGVQcm90bygpO1xuICAgICAgICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQpIHtcbiAgICAgICAgICAgICAgICB2YXIgdGFnID0gcmVhZGVyLnVpbnQzMigpO1xuICAgICAgICAgICAgICAgIHN3aXRjaCAodGFnID4+PiAzKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAxOlxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnRlbnNvclR5cGUgPSAkcm9vdC5vbm54LlR5cGVQcm90by5UZW5zb3IuZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSA2OlxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmRlbm90YXRpb24gPSByZWFkZXIuc3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIHJlYWRlci5za2lwVHlwZSh0YWcgJiA3KTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIERlY29kZXMgYSBUeXBlUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlciwgbGVuZ3RoIGRlbGltaXRlZC5cbiAgICAgICAgICogQGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZFxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgICAgICogQHJldHVybnMge29ubnguVHlwZVByb3RvfSBUeXBlUHJvdG9cbiAgICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICAgICAqL1xuICAgICAgICBUeXBlUHJvdG8uZGVjb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkKHJlYWRlcikge1xuICAgICAgICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpXG4gICAgICAgICAgICAgICAgcmVhZGVyID0gbmV3ICRSZWFkZXIocmVhZGVyKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFZlcmlmaWVzIGEgVHlwZVByb3RvIG1lc3NhZ2UuXG4gICAgICAgICAqIEBmdW5jdGlvbiB2ZXJpZnlcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguVHlwZVByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gbWVzc2FnZSBQbGFpbiBvYmplY3QgdG8gdmVyaWZ5XG4gICAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd8bnVsbH0gYG51bGxgIGlmIHZhbGlkLCBvdGhlcndpc2UgdGhlIHJlYXNvbiB3aHkgaXQgaXMgbm90XG4gICAgICAgICAqL1xuICAgICAgICBUeXBlUHJvdG8udmVyaWZ5ID0gZnVuY3Rpb24gdmVyaWZ5KG1lc3NhZ2UpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSAhPT0gXCJvYmplY3RcIiB8fCBtZXNzYWdlID09PSBudWxsKVxuICAgICAgICAgICAgICAgIHJldHVybiBcIm9iamVjdCBleHBlY3RlZFwiO1xuICAgICAgICAgICAgdmFyIHByb3BlcnRpZXMgPSB7fTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnRlbnNvclR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwidGVuc29yVHlwZVwiKSkge1xuICAgICAgICAgICAgICAgIHByb3BlcnRpZXMudmFsdWUgPSAxO1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5UeXBlUHJvdG8uVGVuc29yLnZlcmlmeShtZXNzYWdlLnRlbnNvclR5cGUpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gXCJ0ZW5zb3JUeXBlLlwiICsgZXJyb3I7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZGVub3RhdGlvbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJkZW5vdGF0aW9uXCIpKVxuICAgICAgICAgICAgICAgIGlmICghJHV0aWwuaXNTdHJpbmcobWVzc2FnZS5kZW5vdGF0aW9uKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwiZGVub3RhdGlvbjogc3RyaW5nIGV4cGVjdGVkXCI7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ3JlYXRlcyBhIFR5cGVQcm90byBtZXNzYWdlIGZyb20gYSBwbGFpbiBvYmplY3QuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIHRoZWlyIHJlc3BlY3RpdmUgaW50ZXJuYWwgdHlwZXMuXG4gICAgICAgICAqIEBmdW5jdGlvbiBmcm9tT2JqZWN0XG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG9iamVjdCBQbGFpbiBvYmplY3RcbiAgICAgICAgICogQHJldHVybnMge29ubnguVHlwZVByb3RvfSBUeXBlUHJvdG9cbiAgICAgICAgICovXG4gICAgICAgIFR5cGVQcm90by5mcm9tT2JqZWN0ID0gZnVuY3Rpb24gZnJvbU9iamVjdChvYmplY3QpIHtcbiAgICAgICAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiAkcm9vdC5vbm54LlR5cGVQcm90bylcbiAgICAgICAgICAgICAgICByZXR1cm4gb2JqZWN0O1xuICAgICAgICAgICAgdmFyIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5UeXBlUHJvdG8oKTtcbiAgICAgICAgICAgIGlmIChvYmplY3QudGVuc29yVHlwZSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QudGVuc29yVHlwZSAhPT0gXCJvYmplY3RcIilcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwiLm9ubnguVHlwZVByb3RvLnRlbnNvclR5cGU6IG9iamVjdCBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICBtZXNzYWdlLnRlbnNvclR5cGUgPSAkcm9vdC5vbm54LlR5cGVQcm90by5UZW5zb3IuZnJvbU9iamVjdChvYmplY3QudGVuc29yVHlwZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAob2JqZWN0LmRlbm90YXRpb24gIT0gbnVsbClcbiAgICAgICAgICAgICAgICBtZXNzYWdlLmRlbm90YXRpb24gPSBTdHJpbmcob2JqZWN0LmRlbm90YXRpb24pO1xuICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENyZWF0ZXMgYSBwbGFpbiBvYmplY3QgZnJvbSBhIFR5cGVQcm90byBtZXNzYWdlLiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byBvdGhlciB0eXBlcyBpZiBzcGVjaWZpZWQuXG4gICAgICAgICAqIEBmdW5jdGlvbiB0b09iamVjdFxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvfSBtZXNzYWdlIFR5cGVQcm90b1xuICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5JQ29udmVyc2lvbk9wdGlvbnN9IFtvcHRpb25zXSBDb252ZXJzaW9uIG9wdGlvbnNcbiAgICAgICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBQbGFpbiBvYmplY3RcbiAgICAgICAgICovXG4gICAgICAgIFR5cGVQcm90by50b09iamVjdCA9IGZ1bmN0aW9uIHRvT2JqZWN0KG1lc3NhZ2UsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGlmICghb3B0aW9ucylcbiAgICAgICAgICAgICAgICBvcHRpb25zID0ge307XG4gICAgICAgICAgICB2YXIgb2JqZWN0ID0ge307XG4gICAgICAgICAgICBpZiAob3B0aW9ucy5kZWZhdWx0cylcbiAgICAgICAgICAgICAgICBvYmplY3QuZGVub3RhdGlvbiA9IFwiXCI7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS50ZW5zb3JUeXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcInRlbnNvclR5cGVcIikpIHtcbiAgICAgICAgICAgICAgICBvYmplY3QudGVuc29yVHlwZSA9ICRyb290Lm9ubnguVHlwZVByb3RvLlRlbnNvci50b09iamVjdChtZXNzYWdlLnRlbnNvclR5cGUsIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLm9uZW9mcylcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LnZhbHVlID0gXCJ0ZW5zb3JUeXBlXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5kZW5vdGF0aW9uICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImRlbm90YXRpb25cIikpXG4gICAgICAgICAgICAgICAgb2JqZWN0LmRlbm90YXRpb24gPSBtZXNzYWdlLmRlbm90YXRpb247XG4gICAgICAgICAgICByZXR1cm4gb2JqZWN0O1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDb252ZXJ0cyB0aGlzIFR5cGVQcm90byB0byBKU09OLlxuICAgICAgICAgKiBAZnVuY3Rpb24gdG9KU09OXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90b1xuICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBKU09OIG9iamVjdFxuICAgICAgICAgKi9cbiAgICAgICAgVHlwZVByb3RvLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04oKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci50b09iamVjdCh0aGlzLCAkcHJvdG9idWYudXRpbC50b0pTT05PcHRpb25zKTtcbiAgICAgICAgfTtcblxuICAgICAgICBUeXBlUHJvdG8uVGVuc29yID0gKGZ1bmN0aW9uKCkge1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIFByb3BlcnRpZXMgb2YgYSBUZW5zb3IuXG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG9cbiAgICAgICAgICAgICAqIEBpbnRlcmZhY2UgSVRlbnNvclxuICAgICAgICAgICAgICogQHByb3BlcnR5IHtudW1iZXJ8bnVsbH0gW2VsZW1UeXBlXSBUZW5zb3IgZWxlbVR5cGVcbiAgICAgICAgICAgICAqIEBwcm9wZXJ0eSB7b25ueC5JVGVuc29yU2hhcGVQcm90b3xudWxsfSBbc2hhcGVdIFRlbnNvciBzaGFwZVxuICAgICAgICAgICAgICovXG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogQ29uc3RydWN0cyBhIG5ldyBUZW5zb3IuXG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG9cbiAgICAgICAgICAgICAqIEBjbGFzc2Rlc2MgUmVwcmVzZW50cyBhIFRlbnNvci5cbiAgICAgICAgICAgICAqIEBpbXBsZW1lbnRzIElUZW5zb3JcbiAgICAgICAgICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAgICAgICAgICogQHBhcmFtIHtvbm54LlR5cGVQcm90by5JVGVuc29yPX0gW3Byb3BlcnRpZXNdIFByb3BlcnRpZXMgdG8gc2V0XG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGZ1bmN0aW9uIFRlbnNvcihwcm9wZXJ0aWVzKSB7XG4gICAgICAgICAgICAgICAgaWYgKHByb3BlcnRpZXMpXG4gICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGtleXMgPSBPYmplY3Qua2V5cyhwcm9wZXJ0aWVzKSwgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHByb3BlcnRpZXNba2V5c1tpXV0gIT0gbnVsbClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzW2tleXNbaV1dID0gcHJvcGVydGllc1trZXlzW2ldXTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBUZW5zb3IgZWxlbVR5cGUuXG4gICAgICAgICAgICAgKiBAbWVtYmVyIHtudW1iZXJ9IGVsZW1UeXBlXG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uVGVuc29yXG4gICAgICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgVGVuc29yLnByb3RvdHlwZS5lbGVtVHlwZSA9IDA7XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogVGVuc29yIHNoYXBlLlxuICAgICAgICAgICAgICogQG1lbWJlciB7b25ueC5JVGVuc29yU2hhcGVQcm90b3xudWxsfHVuZGVmaW5lZH0gc2hhcGVcbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5UZW5zb3JcbiAgICAgICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBUZW5zb3IucHJvdG90eXBlLnNoYXBlID0gbnVsbDtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBDcmVhdGVzIGEgbmV3IFRlbnNvciBpbnN0YW5jZSB1c2luZyB0aGUgc3BlY2lmaWVkIHByb3BlcnRpZXMuXG4gICAgICAgICAgICAgKiBAZnVuY3Rpb24gY3JlYXRlXG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uVGVuc29yXG4gICAgICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvLklUZW5zb3I9fSBbcHJvcGVydGllc10gUHJvcGVydGllcyB0byBzZXRcbiAgICAgICAgICAgICAqIEByZXR1cm5zIHtvbm54LlR5cGVQcm90by5UZW5zb3J9IFRlbnNvciBpbnN0YW5jZVxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBUZW5zb3IuY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKHByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFRlbnNvcihwcm9wZXJ0aWVzKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIFRlbnNvciBtZXNzYWdlLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlR5cGVQcm90by5UZW5zb3IudmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICAgICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlXG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uVGVuc29yXG4gICAgICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvLklUZW5zb3J9IG1lc3NhZ2UgVGVuc29yIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIFRlbnNvci5lbmNvZGUgPSBmdW5jdGlvbiBlbmNvZGUobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICAgICAgICAgICAgaWYgKCF3cml0ZXIpXG4gICAgICAgICAgICAgICAgICAgIHdyaXRlciA9ICRXcml0ZXIuY3JlYXRlKCk7XG4gICAgICAgICAgICAgICAgaWYgKG1lc3NhZ2UuZWxlbVR5cGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiZWxlbVR5cGVcIikpXG4gICAgICAgICAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMSwgd2lyZVR5cGUgMCA9Ki84KS5pbnQzMihtZXNzYWdlLmVsZW1UeXBlKTtcbiAgICAgICAgICAgICAgICBpZiAobWVzc2FnZS5zaGFwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJzaGFwZVwiKSlcbiAgICAgICAgICAgICAgICAgICAgJHJvb3Qub25ueC5UZW5zb3JTaGFwZVByb3RvLmVuY29kZShtZXNzYWdlLnNoYXBlLCB3cml0ZXIudWludDMyKC8qIGlkIDIsIHdpcmVUeXBlIDIgPSovMTgpLmZvcmsoKSkubGRlbGltKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHdyaXRlcjtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIFRlbnNvciBtZXNzYWdlLCBsZW5ndGggZGVsaW1pdGVkLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54LlR5cGVQcm90by5UZW5zb3IudmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICAgICAgICAgKiBAZnVuY3Rpb24gZW5jb2RlRGVsaW1pdGVkXG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uVGVuc29yXG4gICAgICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvLklUZW5zb3J9IG1lc3NhZ2UgVGVuc29yIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAgICAgICAgICogQHBhcmFtIHskcHJvdG9idWYuV3JpdGVyfSBbd3JpdGVyXSBXcml0ZXIgdG8gZW5jb2RlIHRvXG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIFRlbnNvci5lbmNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWQobWVzc2FnZSwgd3JpdGVyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikubGRlbGltKCk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIERlY29kZXMgYSBUZW5zb3IgbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlci5cbiAgICAgICAgICAgICAqIEBmdW5jdGlvbiBkZWNvZGVcbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5UZW5zb3JcbiAgICAgICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGhdIE1lc3NhZ2UgbGVuZ3RoIGlmIGtub3duIGJlZm9yZWhhbmRcbiAgICAgICAgICAgICAqIEByZXR1cm5zIHtvbm54LlR5cGVQcm90by5UZW5zb3J9IFRlbnNvclxuICAgICAgICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgICAgICAgICAqIEB0aHJvd3MgeyRwcm90b2J1Zi51dGlsLlByb3RvY29sRXJyb3J9IElmIHJlcXVpcmVkIGZpZWxkcyBhcmUgbWlzc2luZ1xuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBUZW5zb3IuZGVjb2RlID0gZnVuY3Rpb24gZGVjb2RlKHJlYWRlciwgbGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpXG4gICAgICAgICAgICAgICAgICAgIHJlYWRlciA9ICRSZWFkZXIuY3JlYXRlKHJlYWRlcik7XG4gICAgICAgICAgICAgICAgdmFyIGVuZCA9IGxlbmd0aCA9PT0gdW5kZWZpbmVkID8gcmVhZGVyLmxlbiA6IHJlYWRlci5wb3MgKyBsZW5ndGgsIG1lc3NhZ2UgPSBuZXcgJHJvb3Qub25ueC5UeXBlUHJvdG8uVGVuc29yKCk7XG4gICAgICAgICAgICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRhZyA9IHJlYWRlci51aW50MzIoKTtcbiAgICAgICAgICAgICAgICAgICAgc3dpdGNoICh0YWcgPj4+IDMpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAxOlxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5lbGVtVHlwZSA9IHJlYWRlci5pbnQzMigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgMjpcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2Uuc2hhcGUgPSAkcm9vdC5vbm54LlRlbnNvclNoYXBlUHJvdG8uZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICAgICAgcmVhZGVyLnNraXBUeXBlKHRhZyAmIDcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIERlY29kZXMgYSBUZW5zb3IgbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlciwgbGVuZ3RoIGRlbGltaXRlZC5cbiAgICAgICAgICAgICAqIEBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWRcbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5UZW5zb3JcbiAgICAgICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICAgICAgICogQHJldHVybnMge29ubnguVHlwZVByb3RvLlRlbnNvcn0gVGVuc29yXG4gICAgICAgICAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAgICAgICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIFRlbnNvci5kZWNvZGVEZWxpbWl0ZWQgPSBmdW5jdGlvbiBkZWNvZGVEZWxpbWl0ZWQocmVhZGVyKSB7XG4gICAgICAgICAgICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpXG4gICAgICAgICAgICAgICAgICAgIHJlYWRlciA9IG5ldyAkUmVhZGVyKHJlYWRlcik7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGVjb2RlKHJlYWRlciwgcmVhZGVyLnVpbnQzMigpKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogVmVyaWZpZXMgYSBUZW5zb3IgbWVzc2FnZS5cbiAgICAgICAgICAgICAqIEBmdW5jdGlvbiB2ZXJpZnlcbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5UZW5zb3JcbiAgICAgICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG1lc3NhZ2UgUGxhaW4gb2JqZWN0IHRvIHZlcmlmeVxuICAgICAgICAgICAgICogQHJldHVybnMge3N0cmluZ3xudWxsfSBgbnVsbGAgaWYgdmFsaWQsIG90aGVyd2lzZSB0aGUgcmVhc29uIHdoeSBpdCBpcyBub3RcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgVGVuc29yLnZlcmlmeSA9IGZ1bmN0aW9uIHZlcmlmeShtZXNzYWdlKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBtZXNzYWdlICE9PSBcIm9iamVjdFwiIHx8IG1lc3NhZ2UgPT09IG51bGwpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm9iamVjdCBleHBlY3RlZFwiO1xuICAgICAgICAgICAgICAgIGlmIChtZXNzYWdlLmVsZW1UeXBlICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcImVsZW1UeXBlXCIpKVxuICAgICAgICAgICAgICAgICAgICBpZiAoISR1dGlsLmlzSW50ZWdlcihtZXNzYWdlLmVsZW1UeXBlKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcImVsZW1UeXBlOiBpbnRlZ2VyIGV4cGVjdGVkXCI7XG4gICAgICAgICAgICAgICAgaWYgKG1lc3NhZ2Uuc2hhcGUgIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwic2hhcGVcIikpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVycm9yID0gJHJvb3Qub25ueC5UZW5zb3JTaGFwZVByb3RvLnZlcmlmeShtZXNzYWdlLnNoYXBlKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFwic2hhcGUuXCIgKyBlcnJvcjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIENyZWF0ZXMgYSBUZW5zb3IgbWVzc2FnZSBmcm9tIGEgcGxhaW4gb2JqZWN0LiBBbHNvIGNvbnZlcnRzIHZhbHVlcyB0byB0aGVpciByZXNwZWN0aXZlIGludGVybmFsIHR5cGVzLlxuICAgICAgICAgICAgICogQGZ1bmN0aW9uIGZyb21PYmplY3RcbiAgICAgICAgICAgICAqIEBtZW1iZXJvZiBvbm54LlR5cGVQcm90by5UZW5zb3JcbiAgICAgICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG9iamVjdCBQbGFpbiBvYmplY3RcbiAgICAgICAgICAgICAqIEByZXR1cm5zIHtvbm54LlR5cGVQcm90by5UZW5zb3J9IFRlbnNvclxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBUZW5zb3IuZnJvbU9iamVjdCA9IGZ1bmN0aW9uIGZyb21PYmplY3Qob2JqZWN0KSB7XG4gICAgICAgICAgICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mICRyb290Lm9ubnguVHlwZVByb3RvLlRlbnNvcilcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgICAgICAgICAgICB2YXIgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54LlR5cGVQcm90by5UZW5zb3IoKTtcbiAgICAgICAgICAgICAgICBpZiAob2JqZWN0LmVsZW1UeXBlICE9IG51bGwpXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UuZWxlbVR5cGUgPSBvYmplY3QuZWxlbVR5cGUgfCAwO1xuICAgICAgICAgICAgICAgIGlmIChvYmplY3Quc2hhcGUgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5zaGFwZSAhPT0gXCJvYmplY3RcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihcIi5vbm54LlR5cGVQcm90by5UZW5zb3Iuc2hhcGU6IG9iamVjdCBleHBlY3RlZFwiKTtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS5zaGFwZSA9ICRyb290Lm9ubnguVGVuc29yU2hhcGVQcm90by5mcm9tT2JqZWN0KG9iamVjdC5zaGFwZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBDcmVhdGVzIGEgcGxhaW4gb2JqZWN0IGZyb20gYSBUZW5zb3IgbWVzc2FnZS4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gb3RoZXIgdHlwZXMgaWYgc3BlY2lmaWVkLlxuICAgICAgICAgICAgICogQGZ1bmN0aW9uIHRvT2JqZWN0XG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uVGVuc29yXG4gICAgICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAgICAgKiBAcGFyYW0ge29ubnguVHlwZVByb3RvLlRlbnNvcn0gbWVzc2FnZSBUZW5zb3JcbiAgICAgICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLklDb252ZXJzaW9uT3B0aW9uc30gW29wdGlvbnNdIENvbnZlcnNpb24gb3B0aW9uc1xuICAgICAgICAgICAgICogQHJldHVybnMge09iamVjdC48c3RyaW5nLCo+fSBQbGFpbiBvYmplY3RcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgVGVuc29yLnRvT2JqZWN0ID0gZnVuY3Rpb24gdG9PYmplY3QobWVzc2FnZSwgb3B0aW9ucykge1xuICAgICAgICAgICAgICAgIGlmICghb3B0aW9ucylcbiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucyA9IHt9O1xuICAgICAgICAgICAgICAgIHZhciBvYmplY3QgPSB7fTtcbiAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5kZWZhdWx0cykge1xuICAgICAgICAgICAgICAgICAgICBvYmplY3QuZWxlbVR5cGUgPSAwO1xuICAgICAgICAgICAgICAgICAgICBvYmplY3Quc2hhcGUgPSBudWxsO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAobWVzc2FnZS5lbGVtVHlwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJlbGVtVHlwZVwiKSlcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LmVsZW1UeXBlID0gbWVzc2FnZS5lbGVtVHlwZTtcbiAgICAgICAgICAgICAgICBpZiAobWVzc2FnZS5zaGFwZSAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJzaGFwZVwiKSlcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LnNoYXBlID0gJHJvb3Qub25ueC5UZW5zb3JTaGFwZVByb3RvLnRvT2JqZWN0KG1lc3NhZ2Uuc2hhcGUsIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIENvbnZlcnRzIHRoaXMgVGVuc29yIHRvIEpTT04uXG4gICAgICAgICAgICAgKiBAZnVuY3Rpb24gdG9KU09OXG4gICAgICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5UeXBlUHJvdG8uVGVuc29yXG4gICAgICAgICAgICAgKiBAaW5zdGFuY2VcbiAgICAgICAgICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gSlNPTiBvYmplY3RcbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgVGVuc29yLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04oKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IudG9PYmplY3QodGhpcywgJHByb3RvYnVmLnV0aWwudG9KU09OT3B0aW9ucyk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICByZXR1cm4gVGVuc29yO1xuICAgICAgICB9KSgpO1xuXG4gICAgICAgIHJldHVybiBUeXBlUHJvdG87XG4gICAgfSkoKTtcblxuICAgIG9ubnguT3BlcmF0b3JTZXRJZFByb3RvID0gKGZ1bmN0aW9uKCkge1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBQcm9wZXJ0aWVzIG9mIGFuIE9wZXJhdG9yU2V0SWRQcm90by5cbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnhcbiAgICAgICAgICogQGludGVyZmFjZSBJT3BlcmF0b3JTZXRJZFByb3RvXG4gICAgICAgICAqIEBwcm9wZXJ0eSB7c3RyaW5nfG51bGx9IFtkb21haW5dIE9wZXJhdG9yU2V0SWRQcm90byBkb21haW5cbiAgICAgICAgICogQHByb3BlcnR5IHtudW1iZXJ8TG9uZ3xudWxsfSBbdmVyc2lvbl0gT3BlcmF0b3JTZXRJZFByb3RvIHZlcnNpb25cbiAgICAgICAgICovXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENvbnN0cnVjdHMgYSBuZXcgT3BlcmF0b3JTZXRJZFByb3RvLlxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueFxuICAgICAgICAgKiBAY2xhc3NkZXNjIFJlcHJlc2VudHMgYW4gT3BlcmF0b3JTZXRJZFByb3RvLlxuICAgICAgICAgKiBAaW1wbGVtZW50cyBJT3BlcmF0b3JTZXRJZFByb3RvXG4gICAgICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAgICAgKiBAcGFyYW0ge29ubnguSU9wZXJhdG9yU2V0SWRQcm90bz19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAgICAgKi9cbiAgICAgICAgZnVuY3Rpb24gT3BlcmF0b3JTZXRJZFByb3RvKHByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgIGlmIChwcm9wZXJ0aWVzKVxuICAgICAgICAgICAgICAgIGZvciAodmFyIGtleXMgPSBPYmplY3Qua2V5cyhwcm9wZXJ0aWVzKSwgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgICAgICAgICBpZiAocHJvcGVydGllc1trZXlzW2ldXSAhPSBudWxsKVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpc1trZXlzW2ldXSA9IHByb3BlcnRpZXNba2V5c1tpXV07XG4gICAgICAgIH1cblxuICAgICAgICAvKipcbiAgICAgICAgICogT3BlcmF0b3JTZXRJZFByb3RvIGRvbWFpbi5cbiAgICAgICAgICogQG1lbWJlciB7c3RyaW5nfSBkb21haW5cbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguT3BlcmF0b3JTZXRJZFByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgT3BlcmF0b3JTZXRJZFByb3RvLnByb3RvdHlwZS5kb21haW4gPSBcIlwiO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBPcGVyYXRvclNldElkUHJvdG8gdmVyc2lvbi5cbiAgICAgICAgICogQG1lbWJlciB7bnVtYmVyfExvbmd9IHZlcnNpb25cbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguT3BlcmF0b3JTZXRJZFByb3RvXG4gICAgICAgICAqIEBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgT3BlcmF0b3JTZXRJZFByb3RvLnByb3RvdHlwZS52ZXJzaW9uID0gJHV0aWwuTG9uZyA/ICR1dGlsLkxvbmcuZnJvbUJpdHMoMCwwLGZhbHNlKSA6IDA7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENyZWF0ZXMgYSBuZXcgT3BlcmF0b3JTZXRJZFByb3RvIGluc3RhbmNlIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHJvcGVydGllcy5cbiAgICAgICAgICogQGZ1bmN0aW9uIGNyZWF0ZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5PcGVyYXRvclNldElkUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge29ubnguSU9wZXJhdG9yU2V0SWRQcm90bz19IFtwcm9wZXJ0aWVzXSBQcm9wZXJ0aWVzIHRvIHNldFxuICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5PcGVyYXRvclNldElkUHJvdG99IE9wZXJhdG9yU2V0SWRQcm90byBpbnN0YW5jZVxuICAgICAgICAgKi9cbiAgICAgICAgT3BlcmF0b3JTZXRJZFByb3RvLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShwcm9wZXJ0aWVzKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IE9wZXJhdG9yU2V0SWRQcm90byhwcm9wZXJ0aWVzKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRW5jb2RlcyB0aGUgc3BlY2lmaWVkIE9wZXJhdG9yU2V0SWRQcm90byBtZXNzYWdlLiBEb2VzIG5vdCBpbXBsaWNpdGx5IHtAbGluayBvbm54Lk9wZXJhdG9yU2V0SWRQcm90by52ZXJpZnl8dmVyaWZ5fSBtZXNzYWdlcy5cbiAgICAgICAgICogQGZ1bmN0aW9uIGVuY29kZVxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5PcGVyYXRvclNldElkUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0ge29ubnguSU9wZXJhdG9yU2V0SWRQcm90b30gbWVzc2FnZSBPcGVyYXRvclNldElkUHJvdG8gbWVzc2FnZSBvciBwbGFpbiBvYmplY3QgdG8gZW5jb2RlXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLldyaXRlcn0gW3dyaXRlcl0gV3JpdGVyIHRvIGVuY29kZSB0b1xuICAgICAgICAgKiBAcmV0dXJucyB7JHByb3RvYnVmLldyaXRlcn0gV3JpdGVyXG4gICAgICAgICAqL1xuICAgICAgICBPcGVyYXRvclNldElkUHJvdG8uZW5jb2RlID0gZnVuY3Rpb24gZW5jb2RlKG1lc3NhZ2UsIHdyaXRlcikge1xuICAgICAgICAgICAgaWYgKCF3cml0ZXIpXG4gICAgICAgICAgICAgICAgd3JpdGVyID0gJFdyaXRlci5jcmVhdGUoKTtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmRvbWFpbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJkb21haW5cIikpXG4gICAgICAgICAgICAgICAgd3JpdGVyLnVpbnQzMigvKiBpZCAxLCB3aXJlVHlwZSAyID0qLzEwKS5zdHJpbmcobWVzc2FnZS5kb21haW4pO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UudmVyc2lvbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJ2ZXJzaW9uXCIpKVxuICAgICAgICAgICAgICAgIHdyaXRlci51aW50MzIoLyogaWQgMiwgd2lyZVR5cGUgMCA9Ki8xNikuaW50NjQobWVzc2FnZS52ZXJzaW9uKTtcbiAgICAgICAgICAgIHJldHVybiB3cml0ZXI7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEVuY29kZXMgdGhlIHNwZWNpZmllZCBPcGVyYXRvclNldElkUHJvdG8gbWVzc2FnZSwgbGVuZ3RoIGRlbGltaXRlZC4gRG9lcyBub3QgaW1wbGljaXRseSB7QGxpbmsgb25ueC5PcGVyYXRvclNldElkUHJvdG8udmVyaWZ5fHZlcmlmeX0gbWVzc2FnZXMuXG4gICAgICAgICAqIEBmdW5jdGlvbiBlbmNvZGVEZWxpbWl0ZWRcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguT3BlcmF0b3JTZXRJZFByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtvbm54LklPcGVyYXRvclNldElkUHJvdG99IG1lc3NhZ2UgT3BlcmF0b3JTZXRJZFByb3RvIG1lc3NhZ2Ugb3IgcGxhaW4gb2JqZWN0IHRvIGVuY29kZVxuICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5Xcml0ZXJ9IFt3cml0ZXJdIFdyaXRlciB0byBlbmNvZGUgdG9cbiAgICAgICAgICogQHJldHVybnMgeyRwcm90b2J1Zi5Xcml0ZXJ9IFdyaXRlclxuICAgICAgICAgKi9cbiAgICAgICAgT3BlcmF0b3JTZXRJZFByb3RvLmVuY29kZURlbGltaXRlZCA9IGZ1bmN0aW9uIGVuY29kZURlbGltaXRlZChtZXNzYWdlLCB3cml0ZXIpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVuY29kZShtZXNzYWdlLCB3cml0ZXIpLmxkZWxpbSgpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEZWNvZGVzIGFuIE9wZXJhdG9yU2V0SWRQcm90byBtZXNzYWdlIGZyb20gdGhlIHNwZWNpZmllZCByZWFkZXIgb3IgYnVmZmVyLlxuICAgICAgICAgKiBAZnVuY3Rpb24gZGVjb2RlXG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54Lk9wZXJhdG9yU2V0SWRQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLlJlYWRlcnxVaW50OEFycmF5fSByZWFkZXIgUmVhZGVyIG9yIGJ1ZmZlciB0byBkZWNvZGUgZnJvbVxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aF0gTWVzc2FnZSBsZW5ndGggaWYga25vd24gYmVmb3JlaGFuZFxuICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5PcGVyYXRvclNldElkUHJvdG99IE9wZXJhdG9yU2V0SWRQcm90b1xuICAgICAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHBheWxvYWQgaXMgbm90IGEgcmVhZGVyIG9yIHZhbGlkIGJ1ZmZlclxuICAgICAgICAgKiBAdGhyb3dzIHskcHJvdG9idWYudXRpbC5Qcm90b2NvbEVycm9yfSBJZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAgICAgICAgICovXG4gICAgICAgIE9wZXJhdG9yU2V0SWRQcm90by5kZWNvZGUgPSBmdW5jdGlvbiBkZWNvZGUocmVhZGVyLCBsZW5ndGgpIHtcbiAgICAgICAgICAgIGlmICghKHJlYWRlciBpbnN0YW5jZW9mICRSZWFkZXIpKVxuICAgICAgICAgICAgICAgIHJlYWRlciA9ICRSZWFkZXIuY3JlYXRlKHJlYWRlcik7XG4gICAgICAgICAgICB2YXIgZW5kID0gbGVuZ3RoID09PSB1bmRlZmluZWQgPyByZWFkZXIubGVuIDogcmVhZGVyLnBvcyArIGxlbmd0aCwgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54Lk9wZXJhdG9yU2V0SWRQcm90bygpO1xuICAgICAgICAgICAgd2hpbGUgKHJlYWRlci5wb3MgPCBlbmQpIHtcbiAgICAgICAgICAgICAgICB2YXIgdGFnID0gcmVhZGVyLnVpbnQzMigpO1xuICAgICAgICAgICAgICAgIHN3aXRjaCAodGFnID4+PiAzKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAxOlxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmRvbWFpbiA9IHJlYWRlci5zdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAyOlxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLnZlcnNpb24gPSByZWFkZXIuaW50NjQoKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgcmVhZGVyLnNraXBUeXBlKHRhZyAmIDcpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRGVjb2RlcyBhbiBPcGVyYXRvclNldElkUHJvdG8gbWVzc2FnZSBmcm9tIHRoZSBzcGVjaWZpZWQgcmVhZGVyIG9yIGJ1ZmZlciwgbGVuZ3RoIGRlbGltaXRlZC5cbiAgICAgICAgICogQGZ1bmN0aW9uIGRlY29kZURlbGltaXRlZFxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5PcGVyYXRvclNldElkUHJvdG9cbiAgICAgICAgICogQHN0YXRpY1xuICAgICAgICAgKiBAcGFyYW0geyRwcm90b2J1Zi5SZWFkZXJ8VWludDhBcnJheX0gcmVhZGVyIFJlYWRlciBvciBidWZmZXIgdG8gZGVjb2RlIGZyb21cbiAgICAgICAgICogQHJldHVybnMge29ubnguT3BlcmF0b3JTZXRJZFByb3RvfSBPcGVyYXRvclNldElkUHJvdG9cbiAgICAgICAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBwYXlsb2FkIGlzIG5vdCBhIHJlYWRlciBvciB2YWxpZCBidWZmZXJcbiAgICAgICAgICogQHRocm93cyB7JHByb3RvYnVmLnV0aWwuUHJvdG9jb2xFcnJvcn0gSWYgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nXG4gICAgICAgICAqL1xuICAgICAgICBPcGVyYXRvclNldElkUHJvdG8uZGVjb2RlRGVsaW1pdGVkID0gZnVuY3Rpb24gZGVjb2RlRGVsaW1pdGVkKHJlYWRlcikge1xuICAgICAgICAgICAgaWYgKCEocmVhZGVyIGluc3RhbmNlb2YgJFJlYWRlcikpXG4gICAgICAgICAgICAgICAgcmVhZGVyID0gbmV3ICRSZWFkZXIocmVhZGVyKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmRlY29kZShyZWFkZXIsIHJlYWRlci51aW50MzIoKSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFZlcmlmaWVzIGFuIE9wZXJhdG9yU2V0SWRQcm90byBtZXNzYWdlLlxuICAgICAgICAgKiBAZnVuY3Rpb24gdmVyaWZ5XG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54Lk9wZXJhdG9yU2V0SWRQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IG1lc3NhZ2UgUGxhaW4gb2JqZWN0IHRvIHZlcmlmeVxuICAgICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfG51bGx9IGBudWxsYCBpZiB2YWxpZCwgb3RoZXJ3aXNlIHRoZSByZWFzb24gd2h5IGl0IGlzIG5vdFxuICAgICAgICAgKi9cbiAgICAgICAgT3BlcmF0b3JTZXRJZFByb3RvLnZlcmlmeSA9IGZ1bmN0aW9uIHZlcmlmeShtZXNzYWdlKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UgIT09IFwib2JqZWN0XCIgfHwgbWVzc2FnZSA9PT0gbnVsbClcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJvYmplY3QgZXhwZWN0ZWRcIjtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmRvbWFpbiAhPSBudWxsICYmIG1lc3NhZ2UuaGFzT3duUHJvcGVydHkoXCJkb21haW5cIikpXG4gICAgICAgICAgICAgICAgaWYgKCEkdXRpbC5pc1N0cmluZyhtZXNzYWdlLmRvbWFpbikpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcImRvbWFpbjogc3RyaW5nIGV4cGVjdGVkXCI7XG4gICAgICAgICAgICBpZiAobWVzc2FnZS52ZXJzaW9uICE9IG51bGwgJiYgbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eShcInZlcnNpb25cIikpXG4gICAgICAgICAgICAgICAgaWYgKCEkdXRpbC5pc0ludGVnZXIobWVzc2FnZS52ZXJzaW9uKSAmJiAhKG1lc3NhZ2UudmVyc2lvbiAmJiAkdXRpbC5pc0ludGVnZXIobWVzc2FnZS52ZXJzaW9uLmxvdykgJiYgJHV0aWwuaXNJbnRlZ2VyKG1lc3NhZ2UudmVyc2lvbi5oaWdoKSkpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcInZlcnNpb246IGludGVnZXJ8TG9uZyBleHBlY3RlZFwiO1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENyZWF0ZXMgYW4gT3BlcmF0b3JTZXRJZFByb3RvIG1lc3NhZ2UgZnJvbSBhIHBsYWluIG9iamVjdC4gQWxzbyBjb252ZXJ0cyB2YWx1ZXMgdG8gdGhlaXIgcmVzcGVjdGl2ZSBpbnRlcm5hbCB0eXBlcy5cbiAgICAgICAgICogQGZ1bmN0aW9uIGZyb21PYmplY3RcbiAgICAgICAgICogQG1lbWJlcm9mIG9ubnguT3BlcmF0b3JTZXRJZFByb3RvXG4gICAgICAgICAqIEBzdGF0aWNcbiAgICAgICAgICogQHBhcmFtIHtPYmplY3QuPHN0cmluZywqPn0gb2JqZWN0IFBsYWluIG9iamVjdFxuICAgICAgICAgKiBAcmV0dXJucyB7b25ueC5PcGVyYXRvclNldElkUHJvdG99IE9wZXJhdG9yU2V0SWRQcm90b1xuICAgICAgICAgKi9cbiAgICAgICAgT3BlcmF0b3JTZXRJZFByb3RvLmZyb21PYmplY3QgPSBmdW5jdGlvbiBmcm9tT2JqZWN0KG9iamVjdCkge1xuICAgICAgICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mICRyb290Lm9ubnguT3BlcmF0b3JTZXRJZFByb3RvKVxuICAgICAgICAgICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICAgICAgICB2YXIgbWVzc2FnZSA9IG5ldyAkcm9vdC5vbm54Lk9wZXJhdG9yU2V0SWRQcm90bygpO1xuICAgICAgICAgICAgaWYgKG9iamVjdC5kb21haW4gIT0gbnVsbClcbiAgICAgICAgICAgICAgICBtZXNzYWdlLmRvbWFpbiA9IFN0cmluZyhvYmplY3QuZG9tYWluKTtcbiAgICAgICAgICAgIGlmIChvYmplY3QudmVyc2lvbiAhPSBudWxsKVxuICAgICAgICAgICAgICAgIGlmICgkdXRpbC5Mb25nKVxuICAgICAgICAgICAgICAgICAgICAobWVzc2FnZS52ZXJzaW9uID0gJHV0aWwuTG9uZy5mcm9tVmFsdWUob2JqZWN0LnZlcnNpb24pKS51bnNpZ25lZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QudmVyc2lvbiA9PT0gXCJzdHJpbmdcIilcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS52ZXJzaW9uID0gcGFyc2VJbnQob2JqZWN0LnZlcnNpb24sIDEwKTtcbiAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb2JqZWN0LnZlcnNpb24gPT09IFwibnVtYmVyXCIpXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UudmVyc2lvbiA9IG9iamVjdC52ZXJzaW9uO1xuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBvYmplY3QudmVyc2lvbiA9PT0gXCJvYmplY3RcIilcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZS52ZXJzaW9uID0gbmV3ICR1dGlsLkxvbmdCaXRzKG9iamVjdC52ZXJzaW9uLmxvdyA+Pj4gMCwgb2JqZWN0LnZlcnNpb24uaGlnaCA+Pj4gMCkudG9OdW1iZXIoKTtcbiAgICAgICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDcmVhdGVzIGEgcGxhaW4gb2JqZWN0IGZyb20gYW4gT3BlcmF0b3JTZXRJZFByb3RvIG1lc3NhZ2UuIEFsc28gY29udmVydHMgdmFsdWVzIHRvIG90aGVyIHR5cGVzIGlmIHNwZWNpZmllZC5cbiAgICAgICAgICogQGZ1bmN0aW9uIHRvT2JqZWN0XG4gICAgICAgICAqIEBtZW1iZXJvZiBvbm54Lk9wZXJhdG9yU2V0SWRQcm90b1xuICAgICAgICAgKiBAc3RhdGljXG4gICAgICAgICAqIEBwYXJhbSB7b25ueC5PcGVyYXRvclNldElkUHJvdG99IG1lc3NhZ2UgT3BlcmF0b3JTZXRJZFByb3RvXG4gICAgICAgICAqIEBwYXJhbSB7JHByb3RvYnVmLklDb252ZXJzaW9uT3B0aW9uc30gW29wdGlvbnNdIENvbnZlcnNpb24gb3B0aW9uc1xuICAgICAgICAgKiBAcmV0dXJucyB7T2JqZWN0LjxzdHJpbmcsKj59IFBsYWluIG9iamVjdFxuICAgICAgICAgKi9cbiAgICAgICAgT3BlcmF0b3JTZXRJZFByb3RvLnRvT2JqZWN0ID0gZnVuY3Rpb24gdG9PYmplY3QobWVzc2FnZSwgb3B0aW9ucykge1xuICAgICAgICAgICAgaWYgKCFvcHRpb25zKVxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICAgICAgICAgIHZhciBvYmplY3QgPSB7fTtcbiAgICAgICAgICAgIGlmIChvcHRpb25zLmRlZmF1bHRzKSB7XG4gICAgICAgICAgICAgICAgb2JqZWN0LmRvbWFpbiA9IFwiXCI7XG4gICAgICAgICAgICAgICAgaWYgKCR1dGlsLkxvbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGxvbmcgPSBuZXcgJHV0aWwuTG9uZygwLCAwLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC52ZXJzaW9uID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gbG9uZy50b1N0cmluZygpIDogb3B0aW9ucy5sb25ncyA9PT0gTnVtYmVyID8gbG9uZy50b051bWJlcigpIDogbG9uZztcbiAgICAgICAgICAgICAgICB9IGVsc2VcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LnZlcnNpb24gPSBvcHRpb25zLmxvbmdzID09PSBTdHJpbmcgPyBcIjBcIiA6IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVzc2FnZS5kb21haW4gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwiZG9tYWluXCIpKVxuICAgICAgICAgICAgICAgIG9iamVjdC5kb21haW4gPSBtZXNzYWdlLmRvbWFpbjtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnZlcnNpb24gIT0gbnVsbCAmJiBtZXNzYWdlLmhhc093blByb3BlcnR5KFwidmVyc2lvblwiKSlcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UudmVyc2lvbiA9PT0gXCJudW1iZXJcIilcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LnZlcnNpb24gPSBvcHRpb25zLmxvbmdzID09PSBTdHJpbmcgPyBTdHJpbmcobWVzc2FnZS52ZXJzaW9uKSA6IG1lc3NhZ2UudmVyc2lvbjtcbiAgICAgICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdC52ZXJzaW9uID0gb3B0aW9ucy5sb25ncyA9PT0gU3RyaW5nID8gJHV0aWwuTG9uZy5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChtZXNzYWdlLnZlcnNpb24pIDogb3B0aW9ucy5sb25ncyA9PT0gTnVtYmVyID8gbmV3ICR1dGlsLkxvbmdCaXRzKG1lc3NhZ2UudmVyc2lvbi5sb3cgPj4+IDAsIG1lc3NhZ2UudmVyc2lvbi5oaWdoID4+PiAwKS50b051bWJlcigpIDogbWVzc2FnZS52ZXJzaW9uO1xuICAgICAgICAgICAgcmV0dXJuIG9iamVjdDtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ29udmVydHMgdGhpcyBPcGVyYXRvclNldElkUHJvdG8gdG8gSlNPTi5cbiAgICAgICAgICogQGZ1bmN0aW9uIHRvSlNPTlxuICAgICAgICAgKiBAbWVtYmVyb2Ygb25ueC5PcGVyYXRvclNldElkUHJvdG9cbiAgICAgICAgICogQGluc3RhbmNlXG4gICAgICAgICAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gSlNPTiBvYmplY3RcbiAgICAgICAgICovXG4gICAgICAgIE9wZXJhdG9yU2V0SWRQcm90by5wcm90b3R5cGUudG9KU09OID0gZnVuY3Rpb24gdG9KU09OKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IudG9PYmplY3QodGhpcywgJHByb3RvYnVmLnV0aWwudG9KU09OT3B0aW9ucyk7XG4gICAgICAgIH07XG5cbiAgICAgICAgcmV0dXJuIE9wZXJhdG9yU2V0SWRQcm90bztcbiAgICB9KSgpO1xuXG4gICAgcmV0dXJuIG9ubng7XG59KSgpO1xuXG5tb2R1bGUuZXhwb3J0cyA9ICRyb290O1xuIiwiLy8gbWluaW1hbCBsaWJyYXJ5IGVudHJ5IHBvaW50LlxuXG5cInVzZSBzdHJpY3RcIjtcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIi4vc3JjL2luZGV4LW1pbmltYWxcIik7XG4iLCJcInVzZSBzdHJpY3RcIjtcbnZhciBwcm90b2J1ZiA9IGV4cG9ydHM7XG5cbi8qKlxuICogQnVpbGQgdHlwZSwgb25lIG9mIGBcImZ1bGxcImAsIGBcImxpZ2h0XCJgIG9yIGBcIm1pbmltYWxcImAuXG4gKiBAbmFtZSBidWlsZFxuICogQHR5cGUge3N0cmluZ31cbiAqIEBjb25zdFxuICovXG5wcm90b2J1Zi5idWlsZCA9IFwibWluaW1hbFwiO1xuXG4vLyBTZXJpYWxpemF0aW9uXG5wcm90b2J1Zi5Xcml0ZXIgICAgICAgPSByZXF1aXJlKFwiLi93cml0ZXJcIik7XG5wcm90b2J1Zi5CdWZmZXJXcml0ZXIgPSByZXF1aXJlKFwiLi93cml0ZXJfYnVmZmVyXCIpO1xucHJvdG9idWYuUmVhZGVyICAgICAgID0gcmVxdWlyZShcIi4vcmVhZGVyXCIpO1xucHJvdG9idWYuQnVmZmVyUmVhZGVyID0gcmVxdWlyZShcIi4vcmVhZGVyX2J1ZmZlclwiKTtcblxuLy8gVXRpbGl0eVxucHJvdG9idWYudXRpbCAgICAgICAgID0gcmVxdWlyZShcIi4vdXRpbC9taW5pbWFsXCIpO1xucHJvdG9idWYucnBjICAgICAgICAgID0gcmVxdWlyZShcIi4vcnBjXCIpO1xucHJvdG9idWYucm9vdHMgICAgICAgID0gcmVxdWlyZShcIi4vcm9vdHNcIik7XG5wcm90b2J1Zi5jb25maWd1cmUgICAgPSBjb25maWd1cmU7XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4vKipcbiAqIFJlY29uZmlndXJlcyB0aGUgbGlicmFyeSBhY2NvcmRpbmcgdG8gdGhlIGVudmlyb25tZW50LlxuICogQHJldHVybnMge3VuZGVmaW5lZH1cbiAqL1xuZnVuY3Rpb24gY29uZmlndXJlKCkge1xuICAgIHByb3RvYnVmLnV0aWwuX2NvbmZpZ3VyZSgpO1xuICAgIHByb3RvYnVmLldyaXRlci5fY29uZmlndXJlKHByb3RvYnVmLkJ1ZmZlcldyaXRlcik7XG4gICAgcHJvdG9idWYuUmVhZGVyLl9jb25maWd1cmUocHJvdG9idWYuQnVmZmVyUmVhZGVyKTtcbn1cblxuLy8gU2V0IHVwIGJ1ZmZlciB1dGlsaXR5IGFjY29yZGluZyB0byB0aGUgZW52aXJvbm1lbnRcbmNvbmZpZ3VyZSgpO1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5tb2R1bGUuZXhwb3J0cyA9IFJlYWRlcjtcblxudmFyIHV0aWwgICAgICA9IHJlcXVpcmUoXCIuL3V0aWwvbWluaW1hbFwiKTtcblxudmFyIEJ1ZmZlclJlYWRlcjsgLy8gY3ljbGljXG5cbnZhciBMb25nQml0cyAgPSB1dGlsLkxvbmdCaXRzLFxuICAgIHV0ZjggICAgICA9IHV0aWwudXRmODtcblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbmZ1bmN0aW9uIGluZGV4T3V0T2ZSYW5nZShyZWFkZXIsIHdyaXRlTGVuZ3RoKSB7XG4gICAgcmV0dXJuIFJhbmdlRXJyb3IoXCJpbmRleCBvdXQgb2YgcmFuZ2U6IFwiICsgcmVhZGVyLnBvcyArIFwiICsgXCIgKyAod3JpdGVMZW5ndGggfHwgMSkgKyBcIiA+IFwiICsgcmVhZGVyLmxlbik7XG59XG5cbi8qKlxuICogQ29uc3RydWN0cyBhIG5ldyByZWFkZXIgaW5zdGFuY2UgdXNpbmcgdGhlIHNwZWNpZmllZCBidWZmZXIuXG4gKiBAY2xhc3NkZXNjIFdpcmUgZm9ybWF0IHJlYWRlciB1c2luZyBgVWludDhBcnJheWAgaWYgYXZhaWxhYmxlLCBvdGhlcndpc2UgYEFycmF5YC5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtVaW50OEFycmF5fSBidWZmZXIgQnVmZmVyIHRvIHJlYWQgZnJvbVxuICovXG5mdW5jdGlvbiBSZWFkZXIoYnVmZmVyKSB7XG5cbiAgICAvKipcbiAgICAgKiBSZWFkIGJ1ZmZlci5cbiAgICAgKiBAdHlwZSB7VWludDhBcnJheX1cbiAgICAgKi9cbiAgICB0aGlzLmJ1ZiA9IGJ1ZmZlcjtcblxuICAgIC8qKlxuICAgICAqIFJlYWQgYnVmZmVyIHBvc2l0aW9uLlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG4gICAgdGhpcy5wb3MgPSAwO1xuXG4gICAgLyoqXG4gICAgICogUmVhZCBidWZmZXIgbGVuZ3RoLlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG4gICAgdGhpcy5sZW4gPSBidWZmZXIubGVuZ3RoO1xufVxuXG52YXIgY3JlYXRlX2FycmF5ID0gdHlwZW9mIFVpbnQ4QXJyYXkgIT09IFwidW5kZWZpbmVkXCJcbiAgICA/IGZ1bmN0aW9uIGNyZWF0ZV90eXBlZF9hcnJheShidWZmZXIpIHtcbiAgICAgICAgaWYgKGJ1ZmZlciBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkgfHwgQXJyYXkuaXNBcnJheShidWZmZXIpKVxuICAgICAgICAgICAgcmV0dXJuIG5ldyBSZWFkZXIoYnVmZmVyKTtcbiAgICAgICAgdGhyb3cgRXJyb3IoXCJpbGxlZ2FsIGJ1ZmZlclwiKTtcbiAgICB9XG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICA6IGZ1bmN0aW9uIGNyZWF0ZV9hcnJheShidWZmZXIpIHtcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoYnVmZmVyKSlcbiAgICAgICAgICAgIHJldHVybiBuZXcgUmVhZGVyKGJ1ZmZlcik7XG4gICAgICAgIHRocm93IEVycm9yKFwiaWxsZWdhbCBidWZmZXJcIik7XG4gICAgfTtcblxudmFyIGNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZSgpIHtcbiAgICByZXR1cm4gdXRpbC5CdWZmZXJcbiAgICAgICAgPyBmdW5jdGlvbiBjcmVhdGVfYnVmZmVyX3NldHVwKGJ1ZmZlcikge1xuICAgICAgICAgICAgcmV0dXJuIChSZWFkZXIuY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlX2J1ZmZlcihidWZmZXIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdXRpbC5CdWZmZXIuaXNCdWZmZXIoYnVmZmVyKVxuICAgICAgICAgICAgICAgICAgICA/IG5ldyBCdWZmZXJSZWFkZXIoYnVmZmVyKVxuICAgICAgICAgICAgICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgICAgICAgICAgICAgICA6IGNyZWF0ZV9hcnJheShidWZmZXIpO1xuICAgICAgICAgICAgfSkoYnVmZmVyKTtcbiAgICAgICAgfVxuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgICA6IGNyZWF0ZV9hcnJheTtcbn07XG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyByZWFkZXIgdXNpbmcgdGhlIHNwZWNpZmllZCBidWZmZXIuXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7VWludDhBcnJheXxCdWZmZXJ9IGJ1ZmZlciBCdWZmZXIgdG8gcmVhZCBmcm9tXG4gKiBAcmV0dXJucyB7UmVhZGVyfEJ1ZmZlclJlYWRlcn0gQSB7QGxpbmsgQnVmZmVyUmVhZGVyfSBpZiBgYnVmZmVyYCBpcyBhIEJ1ZmZlciwgb3RoZXJ3aXNlIGEge0BsaW5rIFJlYWRlcn1cbiAqIEB0aHJvd3Mge0Vycm9yfSBJZiBgYnVmZmVyYCBpcyBub3QgYSB2YWxpZCBidWZmZXJcbiAqL1xuUmVhZGVyLmNyZWF0ZSA9IGNyZWF0ZSgpO1xuXG5SZWFkZXIucHJvdG90eXBlLl9zbGljZSA9IHV0aWwuQXJyYXkucHJvdG90eXBlLnN1YmFycmF5IHx8IC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovIHV0aWwuQXJyYXkucHJvdG90eXBlLnNsaWNlO1xuXG4vKipcbiAqIFJlYWRzIGEgdmFyaW50IGFzIGFuIHVuc2lnbmVkIDMyIGJpdCB2YWx1ZS5cbiAqIEBmdW5jdGlvblxuICogQHJldHVybnMge251bWJlcn0gVmFsdWUgcmVhZFxuICovXG5SZWFkZXIucHJvdG90eXBlLnVpbnQzMiA9IChmdW5jdGlvbiByZWFkX3VpbnQzMl9zZXR1cCgpIHtcbiAgICB2YXIgdmFsdWUgPSA0Mjk0OTY3Mjk1OyAvLyBvcHRpbWl6ZXIgdHlwZS1oaW50LCB0ZW5kcyB0byBkZW9wdCBvdGhlcndpc2UgKD8hKVxuICAgIHJldHVybiBmdW5jdGlvbiByZWFkX3VpbnQzMigpIHtcbiAgICAgICAgdmFsdWUgPSAoICAgICAgICAgdGhpcy5idWZbdGhpcy5wb3NdICYgMTI3ICAgICAgICkgPj4+IDA7IGlmICh0aGlzLmJ1Zlt0aGlzLnBvcysrXSA8IDEyOCkgcmV0dXJuIHZhbHVlO1xuICAgICAgICB2YWx1ZSA9ICh2YWx1ZSB8ICh0aGlzLmJ1Zlt0aGlzLnBvc10gJiAxMjcpIDw8ICA3KSA+Pj4gMDsgaWYgKHRoaXMuYnVmW3RoaXMucG9zKytdIDwgMTI4KSByZXR1cm4gdmFsdWU7XG4gICAgICAgIHZhbHVlID0gKHZhbHVlIHwgKHRoaXMuYnVmW3RoaXMucG9zXSAmIDEyNykgPDwgMTQpID4+PiAwOyBpZiAodGhpcy5idWZbdGhpcy5wb3MrK10gPCAxMjgpIHJldHVybiB2YWx1ZTtcbiAgICAgICAgdmFsdWUgPSAodmFsdWUgfCAodGhpcy5idWZbdGhpcy5wb3NdICYgMTI3KSA8PCAyMSkgPj4+IDA7IGlmICh0aGlzLmJ1Zlt0aGlzLnBvcysrXSA8IDEyOCkgcmV0dXJuIHZhbHVlO1xuICAgICAgICB2YWx1ZSA9ICh2YWx1ZSB8ICh0aGlzLmJ1Zlt0aGlzLnBvc10gJiAgMTUpIDw8IDI4KSA+Pj4gMDsgaWYgKHRoaXMuYnVmW3RoaXMucG9zKytdIDwgMTI4KSByZXR1cm4gdmFsdWU7XG5cbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgICAgIGlmICgodGhpcy5wb3MgKz0gNSkgPiB0aGlzLmxlbikge1xuICAgICAgICAgICAgdGhpcy5wb3MgPSB0aGlzLmxlbjtcbiAgICAgICAgICAgIHRocm93IGluZGV4T3V0T2ZSYW5nZSh0aGlzLCAxMCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH07XG59KSgpO1xuXG4vKipcbiAqIFJlYWRzIGEgdmFyaW50IGFzIGEgc2lnbmVkIDMyIGJpdCB2YWx1ZS5cbiAqIEByZXR1cm5zIHtudW1iZXJ9IFZhbHVlIHJlYWRcbiAqL1xuUmVhZGVyLnByb3RvdHlwZS5pbnQzMiA9IGZ1bmN0aW9uIHJlYWRfaW50MzIoKSB7XG4gICAgcmV0dXJuIHRoaXMudWludDMyKCkgfCAwO1xufTtcblxuLyoqXG4gKiBSZWFkcyBhIHppZy16YWcgZW5jb2RlZCB2YXJpbnQgYXMgYSBzaWduZWQgMzIgYml0IHZhbHVlLlxuICogQHJldHVybnMge251bWJlcn0gVmFsdWUgcmVhZFxuICovXG5SZWFkZXIucHJvdG90eXBlLnNpbnQzMiA9IGZ1bmN0aW9uIHJlYWRfc2ludDMyKCkge1xuICAgIHZhciB2YWx1ZSA9IHRoaXMudWludDMyKCk7XG4gICAgcmV0dXJuIHZhbHVlID4+PiAxIF4gLSh2YWx1ZSAmIDEpIHwgMDtcbn07XG5cbi8qIGVzbGludC1kaXNhYmxlIG5vLWludmFsaWQtdGhpcyAqL1xuXG5mdW5jdGlvbiByZWFkTG9uZ1ZhcmludCgpIHtcbiAgICAvLyB0ZW5kcyB0byBkZW9wdCB3aXRoIGxvY2FsIHZhcnMgZm9yIG9jdGV0IGV0Yy5cbiAgICB2YXIgYml0cyA9IG5ldyBMb25nQml0cygwLCAwKTtcbiAgICB2YXIgaSA9IDA7XG4gICAgaWYgKHRoaXMubGVuIC0gdGhpcy5wb3MgPiA0KSB7IC8vIGZhc3Qgcm91dGUgKGxvKVxuICAgICAgICBmb3IgKDsgaSA8IDQ7ICsraSkge1xuICAgICAgICAgICAgLy8gMXN0Li40dGhcbiAgICAgICAgICAgIGJpdHMubG8gPSAoYml0cy5sbyB8ICh0aGlzLmJ1Zlt0aGlzLnBvc10gJiAxMjcpIDw8IGkgKiA3KSA+Pj4gMDtcbiAgICAgICAgICAgIGlmICh0aGlzLmJ1Zlt0aGlzLnBvcysrXSA8IDEyOClcbiAgICAgICAgICAgICAgICByZXR1cm4gYml0cztcbiAgICAgICAgfVxuICAgICAgICAvLyA1dGhcbiAgICAgICAgYml0cy5sbyA9IChiaXRzLmxvIHwgKHRoaXMuYnVmW3RoaXMucG9zXSAmIDEyNykgPDwgMjgpID4+PiAwO1xuICAgICAgICBiaXRzLmhpID0gKGJpdHMuaGkgfCAodGhpcy5idWZbdGhpcy5wb3NdICYgMTI3KSA+PiAgNCkgPj4+IDA7XG4gICAgICAgIGlmICh0aGlzLmJ1Zlt0aGlzLnBvcysrXSA8IDEyOClcbiAgICAgICAgICAgIHJldHVybiBiaXRzO1xuICAgICAgICBpID0gMDtcbiAgICB9IGVsc2Uge1xuICAgICAgICBmb3IgKDsgaSA8IDM7ICsraSkge1xuICAgICAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgICAgICAgICBpZiAodGhpcy5wb3MgPj0gdGhpcy5sZW4pXG4gICAgICAgICAgICAgICAgdGhyb3cgaW5kZXhPdXRPZlJhbmdlKHRoaXMpO1xuICAgICAgICAgICAgLy8gMXN0Li4zdGhcbiAgICAgICAgICAgIGJpdHMubG8gPSAoYml0cy5sbyB8ICh0aGlzLmJ1Zlt0aGlzLnBvc10gJiAxMjcpIDw8IGkgKiA3KSA+Pj4gMDtcbiAgICAgICAgICAgIGlmICh0aGlzLmJ1Zlt0aGlzLnBvcysrXSA8IDEyOClcbiAgICAgICAgICAgICAgICByZXR1cm4gYml0cztcbiAgICAgICAgfVxuICAgICAgICAvLyA0dGhcbiAgICAgICAgYml0cy5sbyA9IChiaXRzLmxvIHwgKHRoaXMuYnVmW3RoaXMucG9zKytdICYgMTI3KSA8PCBpICogNykgPj4+IDA7XG4gICAgICAgIHJldHVybiBiaXRzO1xuICAgIH1cbiAgICBpZiAodGhpcy5sZW4gLSB0aGlzLnBvcyA+IDQpIHsgLy8gZmFzdCByb3V0ZSAoaGkpXG4gICAgICAgIGZvciAoOyBpIDwgNTsgKytpKSB7XG4gICAgICAgICAgICAvLyA2dGguLjEwdGhcbiAgICAgICAgICAgIGJpdHMuaGkgPSAoYml0cy5oaSB8ICh0aGlzLmJ1Zlt0aGlzLnBvc10gJiAxMjcpIDw8IGkgKiA3ICsgMykgPj4+IDA7XG4gICAgICAgICAgICBpZiAodGhpcy5idWZbdGhpcy5wb3MrK10gPCAxMjgpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGJpdHM7XG4gICAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgICBmb3IgKDsgaSA8IDU7ICsraSkge1xuICAgICAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgICAgICAgICBpZiAodGhpcy5wb3MgPj0gdGhpcy5sZW4pXG4gICAgICAgICAgICAgICAgdGhyb3cgaW5kZXhPdXRPZlJhbmdlKHRoaXMpO1xuICAgICAgICAgICAgLy8gNnRoLi4xMHRoXG4gICAgICAgICAgICBiaXRzLmhpID0gKGJpdHMuaGkgfCAodGhpcy5idWZbdGhpcy5wb3NdICYgMTI3KSA8PCBpICogNyArIDMpID4+PiAwO1xuICAgICAgICAgICAgaWYgKHRoaXMuYnVmW3RoaXMucG9zKytdIDwgMTI4KVxuICAgICAgICAgICAgICAgIHJldHVybiBiaXRzO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgdGhyb3cgRXJyb3IoXCJpbnZhbGlkIHZhcmludCBlbmNvZGluZ1wiKTtcbn1cblxuLyogZXNsaW50LWVuYWJsZSBuby1pbnZhbGlkLXRoaXMgKi9cblxuLyoqXG4gKiBSZWFkcyBhIHZhcmludCBhcyBhIHNpZ25lZCA2NCBiaXQgdmFsdWUuXG4gKiBAbmFtZSBSZWFkZXIjaW50NjRcbiAqIEBmdW5jdGlvblxuICogQHJldHVybnMge0xvbmd9IFZhbHVlIHJlYWRcbiAqL1xuXG4vKipcbiAqIFJlYWRzIGEgdmFyaW50IGFzIGFuIHVuc2lnbmVkIDY0IGJpdCB2YWx1ZS5cbiAqIEBuYW1lIFJlYWRlciN1aW50NjRcbiAqIEBmdW5jdGlvblxuICogQHJldHVybnMge0xvbmd9IFZhbHVlIHJlYWRcbiAqL1xuXG4vKipcbiAqIFJlYWRzIGEgemlnLXphZyBlbmNvZGVkIHZhcmludCBhcyBhIHNpZ25lZCA2NCBiaXQgdmFsdWUuXG4gKiBAbmFtZSBSZWFkZXIjc2ludDY0XG4gKiBAZnVuY3Rpb25cbiAqIEByZXR1cm5zIHtMb25nfSBWYWx1ZSByZWFkXG4gKi9cblxuLyoqXG4gKiBSZWFkcyBhIHZhcmludCBhcyBhIGJvb2xlYW4uXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVmFsdWUgcmVhZFxuICovXG5SZWFkZXIucHJvdG90eXBlLmJvb2wgPSBmdW5jdGlvbiByZWFkX2Jvb2woKSB7XG4gICAgcmV0dXJuIHRoaXMudWludDMyKCkgIT09IDA7XG59O1xuXG5mdW5jdGlvbiByZWFkRml4ZWQzMl9lbmQoYnVmLCBlbmQpIHsgLy8gbm90ZSB0aGF0IHRoaXMgdXNlcyBgZW5kYCwgbm90IGBwb3NgXG4gICAgcmV0dXJuIChidWZbZW5kIC0gNF1cbiAgICAgICAgICB8IGJ1ZltlbmQgLSAzXSA8PCA4XG4gICAgICAgICAgfCBidWZbZW5kIC0gMl0gPDwgMTZcbiAgICAgICAgICB8IGJ1ZltlbmQgLSAxXSA8PCAyNCkgPj4+IDA7XG59XG5cbi8qKlxuICogUmVhZHMgZml4ZWQgMzIgYml0cyBhcyBhbiB1bnNpZ25lZCAzMiBiaXQgaW50ZWdlci5cbiAqIEByZXR1cm5zIHtudW1iZXJ9IFZhbHVlIHJlYWRcbiAqL1xuUmVhZGVyLnByb3RvdHlwZS5maXhlZDMyID0gZnVuY3Rpb24gcmVhZF9maXhlZDMyKCkge1xuXG4gICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgaWYgKHRoaXMucG9zICsgNCA+IHRoaXMubGVuKVxuICAgICAgICB0aHJvdyBpbmRleE91dE9mUmFuZ2UodGhpcywgNCk7XG5cbiAgICByZXR1cm4gcmVhZEZpeGVkMzJfZW5kKHRoaXMuYnVmLCB0aGlzLnBvcyArPSA0KTtcbn07XG5cbi8qKlxuICogUmVhZHMgZml4ZWQgMzIgYml0cyBhcyBhIHNpZ25lZCAzMiBiaXQgaW50ZWdlci5cbiAqIEByZXR1cm5zIHtudW1iZXJ9IFZhbHVlIHJlYWRcbiAqL1xuUmVhZGVyLnByb3RvdHlwZS5zZml4ZWQzMiA9IGZ1bmN0aW9uIHJlYWRfc2ZpeGVkMzIoKSB7XG5cbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICBpZiAodGhpcy5wb3MgKyA0ID4gdGhpcy5sZW4pXG4gICAgICAgIHRocm93IGluZGV4T3V0T2ZSYW5nZSh0aGlzLCA0KTtcblxuICAgIHJldHVybiByZWFkRml4ZWQzMl9lbmQodGhpcy5idWYsIHRoaXMucG9zICs9IDQpIHwgMDtcbn07XG5cbi8qIGVzbGludC1kaXNhYmxlIG5vLWludmFsaWQtdGhpcyAqL1xuXG5mdW5jdGlvbiByZWFkRml4ZWQ2NCgvKiB0aGlzOiBSZWFkZXIgKi8pIHtcblxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgIGlmICh0aGlzLnBvcyArIDggPiB0aGlzLmxlbilcbiAgICAgICAgdGhyb3cgaW5kZXhPdXRPZlJhbmdlKHRoaXMsIDgpO1xuXG4gICAgcmV0dXJuIG5ldyBMb25nQml0cyhyZWFkRml4ZWQzMl9lbmQodGhpcy5idWYsIHRoaXMucG9zICs9IDQpLCByZWFkRml4ZWQzMl9lbmQodGhpcy5idWYsIHRoaXMucG9zICs9IDQpKTtcbn1cblxuLyogZXNsaW50LWVuYWJsZSBuby1pbnZhbGlkLXRoaXMgKi9cblxuLyoqXG4gKiBSZWFkcyBmaXhlZCA2NCBiaXRzLlxuICogQG5hbWUgUmVhZGVyI2ZpeGVkNjRcbiAqIEBmdW5jdGlvblxuICogQHJldHVybnMge0xvbmd9IFZhbHVlIHJlYWRcbiAqL1xuXG4vKipcbiAqIFJlYWRzIHppZy16YWcgZW5jb2RlZCBmaXhlZCA2NCBiaXRzLlxuICogQG5hbWUgUmVhZGVyI3NmaXhlZDY0XG4gKiBAZnVuY3Rpb25cbiAqIEByZXR1cm5zIHtMb25nfSBWYWx1ZSByZWFkXG4gKi9cblxuLyoqXG4gKiBSZWFkcyBhIGZsb2F0ICgzMiBiaXQpIGFzIGEgbnVtYmVyLlxuICogQGZ1bmN0aW9uXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBWYWx1ZSByZWFkXG4gKi9cblJlYWRlci5wcm90b3R5cGUuZmxvYXQgPSBmdW5jdGlvbiByZWFkX2Zsb2F0KCkge1xuXG4gICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgaWYgKHRoaXMucG9zICsgNCA+IHRoaXMubGVuKVxuICAgICAgICB0aHJvdyBpbmRleE91dE9mUmFuZ2UodGhpcywgNCk7XG5cbiAgICB2YXIgdmFsdWUgPSB1dGlsLmZsb2F0LnJlYWRGbG9hdExFKHRoaXMuYnVmLCB0aGlzLnBvcyk7XG4gICAgdGhpcy5wb3MgKz0gNDtcbiAgICByZXR1cm4gdmFsdWU7XG59O1xuXG4vKipcbiAqIFJlYWRzIGEgZG91YmxlICg2NCBiaXQgZmxvYXQpIGFzIGEgbnVtYmVyLlxuICogQGZ1bmN0aW9uXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBWYWx1ZSByZWFkXG4gKi9cblJlYWRlci5wcm90b3R5cGUuZG91YmxlID0gZnVuY3Rpb24gcmVhZF9kb3VibGUoKSB7XG5cbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICBpZiAodGhpcy5wb3MgKyA4ID4gdGhpcy5sZW4pXG4gICAgICAgIHRocm93IGluZGV4T3V0T2ZSYW5nZSh0aGlzLCA0KTtcblxuICAgIHZhciB2YWx1ZSA9IHV0aWwuZmxvYXQucmVhZERvdWJsZUxFKHRoaXMuYnVmLCB0aGlzLnBvcyk7XG4gICAgdGhpcy5wb3MgKz0gODtcbiAgICByZXR1cm4gdmFsdWU7XG59O1xuXG4vKipcbiAqIFJlYWRzIGEgc2VxdWVuY2Ugb2YgYnl0ZXMgcHJlY2VlZGVkIGJ5IGl0cyBsZW5ndGggYXMgYSB2YXJpbnQuXG4gKiBAcmV0dXJucyB7VWludDhBcnJheX0gVmFsdWUgcmVhZFxuICovXG5SZWFkZXIucHJvdG90eXBlLmJ5dGVzID0gZnVuY3Rpb24gcmVhZF9ieXRlcygpIHtcbiAgICB2YXIgbGVuZ3RoID0gdGhpcy51aW50MzIoKSxcbiAgICAgICAgc3RhcnQgID0gdGhpcy5wb3MsXG4gICAgICAgIGVuZCAgICA9IHRoaXMucG9zICsgbGVuZ3RoO1xuXG4gICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgaWYgKGVuZCA+IHRoaXMubGVuKVxuICAgICAgICB0aHJvdyBpbmRleE91dE9mUmFuZ2UodGhpcywgbGVuZ3RoKTtcblxuICAgIHRoaXMucG9zICs9IGxlbmd0aDtcbiAgICBpZiAoQXJyYXkuaXNBcnJheSh0aGlzLmJ1ZikpIC8vIHBsYWluIGFycmF5XG4gICAgICAgIHJldHVybiB0aGlzLmJ1Zi5zbGljZShzdGFydCwgZW5kKTtcbiAgICByZXR1cm4gc3RhcnQgPT09IGVuZCAvLyBmaXggZm9yIElFIDEwL1dpbjggYW5kIG90aGVycycgc3ViYXJyYXkgcmV0dXJuaW5nIGFycmF5IG9mIHNpemUgMVxuICAgICAgICA/IG5ldyB0aGlzLmJ1Zi5jb25zdHJ1Y3RvcigwKVxuICAgICAgICA6IHRoaXMuX3NsaWNlLmNhbGwodGhpcy5idWYsIHN0YXJ0LCBlbmQpO1xufTtcblxuLyoqXG4gKiBSZWFkcyBhIHN0cmluZyBwcmVjZWVkZWQgYnkgaXRzIGJ5dGUgbGVuZ3RoIGFzIGEgdmFyaW50LlxuICogQHJldHVybnMge3N0cmluZ30gVmFsdWUgcmVhZFxuICovXG5SZWFkZXIucHJvdG90eXBlLnN0cmluZyA9IGZ1bmN0aW9uIHJlYWRfc3RyaW5nKCkge1xuICAgIHZhciBieXRlcyA9IHRoaXMuYnl0ZXMoKTtcbiAgICByZXR1cm4gdXRmOC5yZWFkKGJ5dGVzLCAwLCBieXRlcy5sZW5ndGgpO1xufTtcblxuLyoqXG4gKiBTa2lwcyB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiBieXRlcyBpZiBzcGVjaWZpZWQsIG90aGVyd2lzZSBza2lwcyBhIHZhcmludC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoXSBMZW5ndGggaWYga25vd24sIG90aGVyd2lzZSBhIHZhcmludCBpcyBhc3N1bWVkXG4gKiBAcmV0dXJucyB7UmVhZGVyfSBgdGhpc2BcbiAqL1xuUmVhZGVyLnByb3RvdHlwZS5za2lwID0gZnVuY3Rpb24gc2tpcChsZW5ndGgpIHtcbiAgICBpZiAodHlwZW9mIGxlbmd0aCA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICAgICAgaWYgKHRoaXMucG9zICsgbGVuZ3RoID4gdGhpcy5sZW4pXG4gICAgICAgICAgICB0aHJvdyBpbmRleE91dE9mUmFuZ2UodGhpcywgbGVuZ3RoKTtcbiAgICAgICAgdGhpcy5wb3MgKz0gbGVuZ3RoO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGRvIHtcbiAgICAgICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgICAgICAgICAgaWYgKHRoaXMucG9zID49IHRoaXMubGVuKVxuICAgICAgICAgICAgICAgIHRocm93IGluZGV4T3V0T2ZSYW5nZSh0aGlzKTtcbiAgICAgICAgfSB3aGlsZSAodGhpcy5idWZbdGhpcy5wb3MrK10gJiAxMjgpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2tpcHMgdGhlIG5leHQgZWxlbWVudCBvZiB0aGUgc3BlY2lmaWVkIHdpcmUgdHlwZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSB3aXJlVHlwZSBXaXJlIHR5cGUgcmVjZWl2ZWRcbiAqIEByZXR1cm5zIHtSZWFkZXJ9IGB0aGlzYFxuICovXG5SZWFkZXIucHJvdG90eXBlLnNraXBUeXBlID0gZnVuY3Rpb24od2lyZVR5cGUpIHtcbiAgICBzd2l0Y2ggKHdpcmVUeXBlKSB7XG4gICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgIHRoaXMuc2tpcCgpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgMTpcbiAgICAgICAgICAgIHRoaXMuc2tpcCg4KTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgICB0aGlzLnNraXAodGhpcy51aW50MzIoKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgd2hpbGUgKCh3aXJlVHlwZSA9IHRoaXMudWludDMyKCkgJiA3KSAhPT0gNCkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2tpcFR5cGUod2lyZVR5cGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgNTpcbiAgICAgICAgICAgIHRoaXMuc2tpcCg0KTtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICB0aHJvdyBFcnJvcihcImludmFsaWQgd2lyZSB0eXBlIFwiICsgd2lyZVR5cGUgKyBcIiBhdCBvZmZzZXQgXCIgKyB0aGlzLnBvcyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xufTtcblxuUmVhZGVyLl9jb25maWd1cmUgPSBmdW5jdGlvbihCdWZmZXJSZWFkZXJfKSB7XG4gICAgQnVmZmVyUmVhZGVyID0gQnVmZmVyUmVhZGVyXztcbiAgICBSZWFkZXIuY3JlYXRlID0gY3JlYXRlKCk7XG4gICAgQnVmZmVyUmVhZGVyLl9jb25maWd1cmUoKTtcblxuICAgIHZhciBmbiA9IHV0aWwuTG9uZyA/IFwidG9Mb25nXCIgOiAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqLyBcInRvTnVtYmVyXCI7XG4gICAgdXRpbC5tZXJnZShSZWFkZXIucHJvdG90eXBlLCB7XG5cbiAgICAgICAgaW50NjQ6IGZ1bmN0aW9uIHJlYWRfaW50NjQoKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVhZExvbmdWYXJpbnQuY2FsbCh0aGlzKVtmbl0oZmFsc2UpO1xuICAgICAgICB9LFxuXG4gICAgICAgIHVpbnQ2NDogZnVuY3Rpb24gcmVhZF91aW50NjQoKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVhZExvbmdWYXJpbnQuY2FsbCh0aGlzKVtmbl0odHJ1ZSk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgc2ludDY0OiBmdW5jdGlvbiByZWFkX3NpbnQ2NCgpIHtcbiAgICAgICAgICAgIHJldHVybiByZWFkTG9uZ1ZhcmludC5jYWxsKHRoaXMpLnp6RGVjb2RlKClbZm5dKGZhbHNlKTtcbiAgICAgICAgfSxcblxuICAgICAgICBmaXhlZDY0OiBmdW5jdGlvbiByZWFkX2ZpeGVkNjQoKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVhZEZpeGVkNjQuY2FsbCh0aGlzKVtmbl0odHJ1ZSk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgc2ZpeGVkNjQ6IGZ1bmN0aW9uIHJlYWRfc2ZpeGVkNjQoKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVhZEZpeGVkNjQuY2FsbCh0aGlzKVtmbl0oZmFsc2UpO1xuICAgICAgICB9XG5cbiAgICB9KTtcbn07XG4iLCJcInVzZSBzdHJpY3RcIjtcbm1vZHVsZS5leHBvcnRzID0gQnVmZmVyUmVhZGVyO1xuXG4vLyBleHRlbmRzIFJlYWRlclxudmFyIFJlYWRlciA9IHJlcXVpcmUoXCIuL3JlYWRlclwiKTtcbihCdWZmZXJSZWFkZXIucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShSZWFkZXIucHJvdG90eXBlKSkuY29uc3RydWN0b3IgPSBCdWZmZXJSZWFkZXI7XG5cbnZhciB1dGlsID0gcmVxdWlyZShcIi4vdXRpbC9taW5pbWFsXCIpO1xuXG4vKipcbiAqIENvbnN0cnVjdHMgYSBuZXcgYnVmZmVyIHJlYWRlciBpbnN0YW5jZS5cbiAqIEBjbGFzc2Rlc2MgV2lyZSBmb3JtYXQgcmVhZGVyIHVzaW5nIG5vZGUgYnVmZmVycy5cbiAqIEBleHRlbmRzIFJlYWRlclxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge0J1ZmZlcn0gYnVmZmVyIEJ1ZmZlciB0byByZWFkIGZyb21cbiAqL1xuZnVuY3Rpb24gQnVmZmVyUmVhZGVyKGJ1ZmZlcikge1xuICAgIFJlYWRlci5jYWxsKHRoaXMsIGJ1ZmZlcik7XG5cbiAgICAvKipcbiAgICAgKiBSZWFkIGJ1ZmZlci5cbiAgICAgKiBAbmFtZSBCdWZmZXJSZWFkZXIjYnVmXG4gICAgICogQHR5cGUge0J1ZmZlcn1cbiAgICAgKi9cbn1cblxuQnVmZmVyUmVhZGVyLl9jb25maWd1cmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgICBpZiAodXRpbC5CdWZmZXIpXG4gICAgICAgIEJ1ZmZlclJlYWRlci5wcm90b3R5cGUuX3NsaWNlID0gdXRpbC5CdWZmZXIucHJvdG90eXBlLnNsaWNlO1xufTtcblxuXG4vKipcbiAqIEBvdmVycmlkZVxuICovXG5CdWZmZXJSZWFkZXIucHJvdG90eXBlLnN0cmluZyA9IGZ1bmN0aW9uIHJlYWRfc3RyaW5nX2J1ZmZlcigpIHtcbiAgICB2YXIgbGVuID0gdGhpcy51aW50MzIoKTsgLy8gbW9kaWZpZXMgcG9zXG4gICAgcmV0dXJuIHRoaXMuYnVmLnV0ZjhTbGljZVxuICAgICAgICA/IHRoaXMuYnVmLnV0ZjhTbGljZSh0aGlzLnBvcywgdGhpcy5wb3MgPSBNYXRoLm1pbih0aGlzLnBvcyArIGxlbiwgdGhpcy5sZW4pKVxuICAgICAgICA6IHRoaXMuYnVmLnRvU3RyaW5nKFwidXRmLThcIiwgdGhpcy5wb3MsIHRoaXMucG9zID0gTWF0aC5taW4odGhpcy5wb3MgKyBsZW4sIHRoaXMubGVuKSk7XG59O1xuXG4vKipcbiAqIFJlYWRzIGEgc2VxdWVuY2Ugb2YgYnl0ZXMgcHJlY2VlZGVkIGJ5IGl0cyBsZW5ndGggYXMgYSB2YXJpbnQuXG4gKiBAbmFtZSBCdWZmZXJSZWFkZXIjYnl0ZXNcbiAqIEBmdW5jdGlvblxuICogQHJldHVybnMge0J1ZmZlcn0gVmFsdWUgcmVhZFxuICovXG5cbkJ1ZmZlclJlYWRlci5fY29uZmlndXJlKCk7XG4iLCJcInVzZSBzdHJpY3RcIjtcbm1vZHVsZS5leHBvcnRzID0ge307XG5cbi8qKlxuICogTmFtZWQgcm9vdHMuXG4gKiBUaGlzIGlzIHdoZXJlIHBianMgc3RvcmVzIGdlbmVyYXRlZCBzdHJ1Y3R1cmVzICh0aGUgb3B0aW9uIGAtciwgLS1yb290YCBzcGVjaWZpZXMgYSBuYW1lKS5cbiAqIENhbiBhbHNvIGJlIHVzZWQgbWFudWFsbHkgdG8gbWFrZSByb290cyBhdmFpbGFibGUgYWNjcm9zcyBtb2R1bGVzLlxuICogQG5hbWUgcm9vdHNcbiAqIEB0eXBlIHtPYmplY3QuPHN0cmluZyxSb290Pn1cbiAqIEBleGFtcGxlXG4gKiAvLyBwYmpzIC1yIG15cm9vdCAtbyBjb21waWxlZC5qcyAuLi5cbiAqXG4gKiAvLyBpbiBhbm90aGVyIG1vZHVsZTpcbiAqIHJlcXVpcmUoXCIuL2NvbXBpbGVkLmpzXCIpO1xuICpcbiAqIC8vIGluIGFueSBzdWJzZXF1ZW50IG1vZHVsZTpcbiAqIHZhciByb290ID0gcHJvdG9idWYucm9vdHNbXCJteXJvb3RcIl07XG4gKi9cbiIsIlwidXNlIHN0cmljdFwiO1xuXG4vKipcbiAqIFN0cmVhbWluZyBSUEMgaGVscGVycy5cbiAqIEBuYW1lc3BhY2VcbiAqL1xudmFyIHJwYyA9IGV4cG9ydHM7XG5cbi8qKlxuICogUlBDIGltcGxlbWVudGF0aW9uIHBhc3NlZCB0byB7QGxpbmsgU2VydmljZSNjcmVhdGV9IHBlcmZvcm1pbmcgYSBzZXJ2aWNlIHJlcXVlc3Qgb24gbmV0d29yayBsZXZlbCwgaS5lLiBieSB1dGlsaXppbmcgaHR0cCByZXF1ZXN0cyBvciB3ZWJzb2NrZXRzLlxuICogQHR5cGVkZWYgUlBDSW1wbFxuICogQHR5cGUge2Z1bmN0aW9ufVxuICogQHBhcmFtIHtNZXRob2R8cnBjLlNlcnZpY2VNZXRob2Q8TWVzc2FnZTx7fT4sTWVzc2FnZTx7fT4+fSBtZXRob2QgUmVmbGVjdGVkIG9yIHN0YXRpYyBtZXRob2QgYmVpbmcgY2FsbGVkXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IHJlcXVlc3REYXRhIFJlcXVlc3QgZGF0YVxuICogQHBhcmFtIHtSUENJbXBsQ2FsbGJhY2t9IGNhbGxiYWNrIENhbGxiYWNrIGZ1bmN0aW9uXG4gKiBAcmV0dXJucyB7dW5kZWZpbmVkfVxuICogQGV4YW1wbGVcbiAqIGZ1bmN0aW9uIHJwY0ltcGwobWV0aG9kLCByZXF1ZXN0RGF0YSwgY2FsbGJhY2spIHtcbiAqICAgICBpZiAocHJvdG9idWYudXRpbC5sY0ZpcnN0KG1ldGhvZC5uYW1lKSAhPT0gXCJteU1ldGhvZFwiKSAvLyBjb21wYXRpYmxlIHdpdGggc3RhdGljIGNvZGVcbiAqICAgICAgICAgdGhyb3cgRXJyb3IoXCJubyBzdWNoIG1ldGhvZFwiKTtcbiAqICAgICBhc3luY2hyb25vdXNseU9idGFpbkFSZXNwb25zZShyZXF1ZXN0RGF0YSwgZnVuY3Rpb24oZXJyLCByZXNwb25zZURhdGEpIHtcbiAqICAgICAgICAgY2FsbGJhY2soZXJyLCByZXNwb25zZURhdGEpO1xuICogICAgIH0pO1xuICogfVxuICovXG5cbi8qKlxuICogTm9kZS1zdHlsZSBjYWxsYmFjayBhcyB1c2VkIGJ5IHtAbGluayBSUENJbXBsfS5cbiAqIEB0eXBlZGVmIFJQQ0ltcGxDYWxsYmFja1xuICogQHR5cGUge2Z1bmN0aW9ufVxuICogQHBhcmFtIHtFcnJvcnxudWxsfSBlcnJvciBFcnJvciwgaWYgYW55LCBvdGhlcndpc2UgYG51bGxgXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl8bnVsbH0gW3Jlc3BvbnNlXSBSZXNwb25zZSBkYXRhIG9yIGBudWxsYCB0byBzaWduYWwgZW5kIG9mIHN0cmVhbSwgaWYgdGhlcmUgaGFzbid0IGJlZW4gYW4gZXJyb3JcbiAqIEByZXR1cm5zIHt1bmRlZmluZWR9XG4gKi9cblxucnBjLlNlcnZpY2UgPSByZXF1aXJlKFwiLi9ycGMvc2VydmljZVwiKTtcbiIsIlwidXNlIHN0cmljdFwiO1xubW9kdWxlLmV4cG9ydHMgPSBTZXJ2aWNlO1xuXG52YXIgdXRpbCA9IHJlcXVpcmUoXCIuLi91dGlsL21pbmltYWxcIik7XG5cbi8vIEV4dGVuZHMgRXZlbnRFbWl0dGVyXG4oU2VydmljZS5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHV0aWwuRXZlbnRFbWl0dGVyLnByb3RvdHlwZSkpLmNvbnN0cnVjdG9yID0gU2VydmljZTtcblxuLyoqXG4gKiBBIHNlcnZpY2UgbWV0aG9kIGNhbGxiYWNrIGFzIHVzZWQgYnkge0BsaW5rIHJwYy5TZXJ2aWNlTWV0aG9kfFNlcnZpY2VNZXRob2R9LlxuICpcbiAqIERpZmZlcnMgZnJvbSB7QGxpbmsgUlBDSW1wbENhbGxiYWNrfSBpbiB0aGF0IGl0IGlzIGFuIGFjdHVhbCBjYWxsYmFjayBvZiBhIHNlcnZpY2UgbWV0aG9kIHdoaWNoIG1heSBub3QgcmV0dXJuIGByZXNwb25zZSA9IG51bGxgLlxuICogQHR5cGVkZWYgcnBjLlNlcnZpY2VNZXRob2RDYWxsYmFja1xuICogQHRlbXBsYXRlIFRSZXMgZXh0ZW5kcyBNZXNzYWdlPFRSZXM+XG4gKiBAdHlwZSB7ZnVuY3Rpb259XG4gKiBAcGFyYW0ge0Vycm9yfG51bGx9IGVycm9yIEVycm9yLCBpZiBhbnlcbiAqIEBwYXJhbSB7VFJlc30gW3Jlc3BvbnNlXSBSZXNwb25zZSBtZXNzYWdlXG4gKiBAcmV0dXJucyB7dW5kZWZpbmVkfVxuICovXG5cbi8qKlxuICogQSBzZXJ2aWNlIG1ldGhvZCBwYXJ0IG9mIGEge0BsaW5rIHJwYy5TZXJ2aWNlfSBhcyBjcmVhdGVkIGJ5IHtAbGluayBTZXJ2aWNlLmNyZWF0ZX0uXG4gKiBAdHlwZWRlZiBycGMuU2VydmljZU1ldGhvZFxuICogQHRlbXBsYXRlIFRSZXEgZXh0ZW5kcyBNZXNzYWdlPFRSZXE+XG4gKiBAdGVtcGxhdGUgVFJlcyBleHRlbmRzIE1lc3NhZ2U8VFJlcz5cbiAqIEB0eXBlIHtmdW5jdGlvbn1cbiAqIEBwYXJhbSB7VFJlcXxQcm9wZXJ0aWVzPFRSZXE+fSByZXF1ZXN0IFJlcXVlc3QgbWVzc2FnZSBvciBwbGFpbiBvYmplY3RcbiAqIEBwYXJhbSB7cnBjLlNlcnZpY2VNZXRob2RDYWxsYmFjazxUUmVzPn0gW2NhbGxiYWNrXSBOb2RlLXN0eWxlIGNhbGxiYWNrIGNhbGxlZCB3aXRoIHRoZSBlcnJvciwgaWYgYW55LCBhbmQgdGhlIHJlc3BvbnNlIG1lc3NhZ2VcbiAqIEByZXR1cm5zIHtQcm9taXNlPE1lc3NhZ2U8VFJlcz4+fSBQcm9taXNlIGlmIGBjYWxsYmFja2AgaGFzIGJlZW4gb21pdHRlZCwgb3RoZXJ3aXNlIGB1bmRlZmluZWRgXG4gKi9cblxuLyoqXG4gKiBDb25zdHJ1Y3RzIGEgbmV3IFJQQyBzZXJ2aWNlIGluc3RhbmNlLlxuICogQGNsYXNzZGVzYyBBbiBSUEMgc2VydmljZSBhcyByZXR1cm5lZCBieSB7QGxpbmsgU2VydmljZSNjcmVhdGV9LlxuICogQGV4cG9ydHMgcnBjLlNlcnZpY2VcbiAqIEBleHRlbmRzIHV0aWwuRXZlbnRFbWl0dGVyXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7UlBDSW1wbH0gcnBjSW1wbCBSUEMgaW1wbGVtZW50YXRpb25cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW3JlcXVlc3REZWxpbWl0ZWQ9ZmFsc2VdIFdoZXRoZXIgcmVxdWVzdHMgYXJlIGxlbmd0aC1kZWxpbWl0ZWRcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW3Jlc3BvbnNlRGVsaW1pdGVkPWZhbHNlXSBXaGV0aGVyIHJlc3BvbnNlcyBhcmUgbGVuZ3RoLWRlbGltaXRlZFxuICovXG5mdW5jdGlvbiBTZXJ2aWNlKHJwY0ltcGwsIHJlcXVlc3REZWxpbWl0ZWQsIHJlc3BvbnNlRGVsaW1pdGVkKSB7XG5cbiAgICBpZiAodHlwZW9mIHJwY0ltcGwgIT09IFwiZnVuY3Rpb25cIilcbiAgICAgICAgdGhyb3cgVHlwZUVycm9yKFwicnBjSW1wbCBtdXN0IGJlIGEgZnVuY3Rpb25cIik7XG5cbiAgICB1dGlsLkV2ZW50RW1pdHRlci5jYWxsKHRoaXMpO1xuXG4gICAgLyoqXG4gICAgICogUlBDIGltcGxlbWVudGF0aW9uLiBCZWNvbWVzIGBudWxsYCBvbmNlIHRoZSBzZXJ2aWNlIGlzIGVuZGVkLlxuICAgICAqIEB0eXBlIHtSUENJbXBsfG51bGx9XG4gICAgICovXG4gICAgdGhpcy5ycGNJbXBsID0gcnBjSW1wbDtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgcmVxdWVzdHMgYXJlIGxlbmd0aC1kZWxpbWl0ZWQuXG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG4gICAgdGhpcy5yZXF1ZXN0RGVsaW1pdGVkID0gQm9vbGVhbihyZXF1ZXN0RGVsaW1pdGVkKTtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgcmVzcG9uc2VzIGFyZSBsZW5ndGgtZGVsaW1pdGVkLlxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuICAgIHRoaXMucmVzcG9uc2VEZWxpbWl0ZWQgPSBCb29sZWFuKHJlc3BvbnNlRGVsaW1pdGVkKTtcbn1cblxuLyoqXG4gKiBDYWxscyBhIHNlcnZpY2UgbWV0aG9kIHRocm91Z2gge0BsaW5rIHJwYy5TZXJ2aWNlI3JwY0ltcGx8cnBjSW1wbH0uXG4gKiBAcGFyYW0ge01ldGhvZHxycGMuU2VydmljZU1ldGhvZDxUUmVxLFRSZXM+fSBtZXRob2QgUmVmbGVjdGVkIG9yIHN0YXRpYyBtZXRob2RcbiAqIEBwYXJhbSB7Q29uc3RydWN0b3I8VFJlcT59IHJlcXVlc3RDdG9yIFJlcXVlc3QgY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7Q29uc3RydWN0b3I8VFJlcz59IHJlc3BvbnNlQ3RvciBSZXNwb25zZSBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtUUmVxfFByb3BlcnRpZXM8VFJlcT59IHJlcXVlc3QgUmVxdWVzdCBtZXNzYWdlIG9yIHBsYWluIG9iamVjdFxuICogQHBhcmFtIHtycGMuU2VydmljZU1ldGhvZENhbGxiYWNrPFRSZXM+fSBjYWxsYmFjayBTZXJ2aWNlIGNhbGxiYWNrXG4gKiBAcmV0dXJucyB7dW5kZWZpbmVkfVxuICogQHRlbXBsYXRlIFRSZXEgZXh0ZW5kcyBNZXNzYWdlPFRSZXE+XG4gKiBAdGVtcGxhdGUgVFJlcyBleHRlbmRzIE1lc3NhZ2U8VFJlcz5cbiAqL1xuU2VydmljZS5wcm90b3R5cGUucnBjQ2FsbCA9IGZ1bmN0aW9uIHJwY0NhbGwobWV0aG9kLCByZXF1ZXN0Q3RvciwgcmVzcG9uc2VDdG9yLCByZXF1ZXN0LCBjYWxsYmFjaykge1xuXG4gICAgaWYgKCFyZXF1ZXN0KVxuICAgICAgICB0aHJvdyBUeXBlRXJyb3IoXCJyZXF1ZXN0IG11c3QgYmUgc3BlY2lmaWVkXCIpO1xuXG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIGlmICghY2FsbGJhY2spXG4gICAgICAgIHJldHVybiB1dGlsLmFzUHJvbWlzZShycGNDYWxsLCBzZWxmLCBtZXRob2QsIHJlcXVlc3RDdG9yLCByZXNwb25zZUN0b3IsIHJlcXVlc3QpO1xuXG4gICAgaWYgKCFzZWxmLnJwY0ltcGwpIHtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHsgY2FsbGJhY2soRXJyb3IoXCJhbHJlYWR5IGVuZGVkXCIpKTsgfSwgMCk7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIHNlbGYucnBjSW1wbChcbiAgICAgICAgICAgIG1ldGhvZCxcbiAgICAgICAgICAgIHJlcXVlc3RDdG9yW3NlbGYucmVxdWVzdERlbGltaXRlZCA/IFwiZW5jb2RlRGVsaW1pdGVkXCIgOiBcImVuY29kZVwiXShyZXF1ZXN0KS5maW5pc2goKSxcbiAgICAgICAgICAgIGZ1bmN0aW9uIHJwY0NhbGxiYWNrKGVyciwgcmVzcG9uc2UpIHtcblxuICAgICAgICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5lbWl0KFwiZXJyb3JcIiwgZXJyLCBtZXRob2QpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2UgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5lbmQoLyogZW5kZWRCeVJQQyAqLyB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoIShyZXNwb25zZSBpbnN0YW5jZW9mIHJlc3BvbnNlQ3RvcikpIHtcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlID0gcmVzcG9uc2VDdG9yW3NlbGYucmVzcG9uc2VEZWxpbWl0ZWQgPyBcImRlY29kZURlbGltaXRlZFwiIDogXCJkZWNvZGVcIl0ocmVzcG9uc2UpO1xuICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuZW1pdChcImVycm9yXCIsIGVyciwgbWV0aG9kKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgc2VsZi5lbWl0KFwiZGF0YVwiLCByZXNwb25zZSwgbWV0aG9kKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgcmVzcG9uc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICApO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBzZWxmLmVtaXQoXCJlcnJvclwiLCBlcnIsIG1ldGhvZCk7XG4gICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7IGNhbGxiYWNrKGVycik7IH0sIDApO1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbn07XG5cbi8qKlxuICogRW5kcyB0aGlzIHNlcnZpY2UgYW5kIGVtaXRzIHRoZSBgZW5kYCBldmVudC5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2VuZGVkQnlSUEM9ZmFsc2VdIFdoZXRoZXIgdGhlIHNlcnZpY2UgaGFzIGJlZW4gZW5kZWQgYnkgdGhlIFJQQyBpbXBsZW1lbnRhdGlvbi5cbiAqIEByZXR1cm5zIHtycGMuU2VydmljZX0gYHRoaXNgXG4gKi9cblNlcnZpY2UucHJvdG90eXBlLmVuZCA9IGZ1bmN0aW9uIGVuZChlbmRlZEJ5UlBDKSB7XG4gICAgaWYgKHRoaXMucnBjSW1wbCkge1xuICAgICAgICBpZiAoIWVuZGVkQnlSUEMpIC8vIHNpZ25hbCBlbmQgdG8gcnBjSW1wbFxuICAgICAgICAgICAgdGhpcy5ycGNJbXBsKG51bGwsIG51bGwsIG51bGwpO1xuICAgICAgICB0aGlzLnJwY0ltcGwgPSBudWxsO1xuICAgICAgICB0aGlzLmVtaXQoXCJlbmRcIikub2ZmKCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xufTtcbiIsIlwidXNlIHN0cmljdFwiO1xubW9kdWxlLmV4cG9ydHMgPSBMb25nQml0cztcblxudmFyIHV0aWwgPSByZXF1aXJlKFwiLi4vdXRpbC9taW5pbWFsXCIpO1xuXG4vKipcbiAqIENvbnN0cnVjdHMgbmV3IGxvbmcgYml0cy5cbiAqIEBjbGFzc2Rlc2MgSGVscGVyIGNsYXNzIGZvciB3b3JraW5nIHdpdGggdGhlIGxvdyBhbmQgaGlnaCBiaXRzIG9mIGEgNjQgYml0IHZhbHVlLlxuICogQG1lbWJlcm9mIHV0aWxcbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtudW1iZXJ9IGxvIExvdyAzMiBiaXRzLCB1bnNpZ25lZFxuICogQHBhcmFtIHtudW1iZXJ9IGhpIEhpZ2ggMzIgYml0cywgdW5zaWduZWRcbiAqL1xuZnVuY3Rpb24gTG9uZ0JpdHMobG8sIGhpKSB7XG5cbiAgICAvLyBub3RlIHRoYXQgdGhlIGNhc3RzIGJlbG93IGFyZSB0aGVvcmV0aWNhbGx5IHVubmVjZXNzYXJ5IGFzIG9mIHRvZGF5LCBidXQgb2xkZXIgc3RhdGljYWxseVxuICAgIC8vIGdlbmVyYXRlZCBjb252ZXJ0ZXIgY29kZSBtaWdodCBzdGlsbCBjYWxsIHRoZSBjdG9yIHdpdGggc2lnbmVkIDMyYml0cy4ga2VwdCBmb3IgY29tcGF0LlxuXG4gICAgLyoqXG4gICAgICogTG93IGJpdHMuXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICB0aGlzLmxvID0gbG8gPj4+IDA7XG5cbiAgICAvKipcbiAgICAgKiBIaWdoIGJpdHMuXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICB0aGlzLmhpID0gaGkgPj4+IDA7XG59XG5cbi8qKlxuICogWmVybyBiaXRzLlxuICogQG1lbWJlcm9mIHV0aWwuTG9uZ0JpdHNcbiAqIEB0eXBlIHt1dGlsLkxvbmdCaXRzfVxuICovXG52YXIgemVybyA9IExvbmdCaXRzLnplcm8gPSBuZXcgTG9uZ0JpdHMoMCwgMCk7XG5cbnplcm8udG9OdW1iZXIgPSBmdW5jdGlvbigpIHsgcmV0dXJuIDA7IH07XG56ZXJvLnp6RW5jb2RlID0gemVyby56ekRlY29kZSA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gdGhpczsgfTtcbnplcm8ubGVuZ3RoID0gZnVuY3Rpb24oKSB7IHJldHVybiAxOyB9O1xuXG4vKipcbiAqIFplcm8gaGFzaC5cbiAqIEBtZW1iZXJvZiB1dGlsLkxvbmdCaXRzXG4gKiBAdHlwZSB7c3RyaW5nfVxuICovXG52YXIgemVyb0hhc2ggPSBMb25nQml0cy56ZXJvSGFzaCA9IFwiXFwwXFwwXFwwXFwwXFwwXFwwXFwwXFwwXCI7XG5cbi8qKlxuICogQ29uc3RydWN0cyBuZXcgbG9uZyBiaXRzIGZyb20gdGhlIHNwZWNpZmllZCBudW1iZXIuXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVmFsdWVcbiAqIEByZXR1cm5zIHt1dGlsLkxvbmdCaXRzfSBJbnN0YW5jZVxuICovXG5Mb25nQml0cy5mcm9tTnVtYmVyID0gZnVuY3Rpb24gZnJvbU51bWJlcih2YWx1ZSkge1xuICAgIGlmICh2YWx1ZSA9PT0gMClcbiAgICAgICAgcmV0dXJuIHplcm87XG4gICAgdmFyIHNpZ24gPSB2YWx1ZSA8IDA7XG4gICAgaWYgKHNpZ24pXG4gICAgICAgIHZhbHVlID0gLXZhbHVlO1xuICAgIHZhciBsbyA9IHZhbHVlID4+PiAwLFxuICAgICAgICBoaSA9ICh2YWx1ZSAtIGxvKSAvIDQyOTQ5NjcyOTYgPj4+IDA7XG4gICAgaWYgKHNpZ24pIHtcbiAgICAgICAgaGkgPSB+aGkgPj4+IDA7XG4gICAgICAgIGxvID0gfmxvID4+PiAwO1xuICAgICAgICBpZiAoKytsbyA+IDQyOTQ5NjcyOTUpIHtcbiAgICAgICAgICAgIGxvID0gMDtcbiAgICAgICAgICAgIGlmICgrK2hpID4gNDI5NDk2NzI5NSlcbiAgICAgICAgICAgICAgICBoaSA9IDA7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG5ldyBMb25nQml0cyhsbywgaGkpO1xufTtcblxuLyoqXG4gKiBDb25zdHJ1Y3RzIG5ldyBsb25nIGJpdHMgZnJvbSBhIG51bWJlciwgbG9uZyBvciBzdHJpbmcuXG4gKiBAcGFyYW0ge0xvbmd8bnVtYmVyfHN0cmluZ30gdmFsdWUgVmFsdWVcbiAqIEByZXR1cm5zIHt1dGlsLkxvbmdCaXRzfSBJbnN0YW5jZVxuICovXG5Mb25nQml0cy5mcm9tID0gZnVuY3Rpb24gZnJvbSh2YWx1ZSkge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwibnVtYmVyXCIpXG4gICAgICAgIHJldHVybiBMb25nQml0cy5mcm9tTnVtYmVyKHZhbHVlKTtcbiAgICBpZiAodXRpbC5pc1N0cmluZyh2YWx1ZSkpIHtcbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgICAgICAgaWYgKHV0aWwuTG9uZylcbiAgICAgICAgICAgIHZhbHVlID0gdXRpbC5Mb25nLmZyb21TdHJpbmcodmFsdWUpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICByZXR1cm4gTG9uZ0JpdHMuZnJvbU51bWJlcihwYXJzZUludCh2YWx1ZSwgMTApKTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlLmxvdyB8fCB2YWx1ZS5oaWdoID8gbmV3IExvbmdCaXRzKHZhbHVlLmxvdyA+Pj4gMCwgdmFsdWUuaGlnaCA+Pj4gMCkgOiB6ZXJvO1xufTtcblxuLyoqXG4gKiBDb252ZXJ0cyB0aGlzIGxvbmcgYml0cyB0byBhIHBvc3NpYmx5IHVuc2FmZSBKYXZhU2NyaXB0IG51bWJlci5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW3Vuc2lnbmVkPWZhbHNlXSBXaGV0aGVyIHVuc2lnbmVkIG9yIG5vdFxuICogQHJldHVybnMge251bWJlcn0gUG9zc2libHkgdW5zYWZlIG51bWJlclxuICovXG5Mb25nQml0cy5wcm90b3R5cGUudG9OdW1iZXIgPSBmdW5jdGlvbiB0b051bWJlcih1bnNpZ25lZCkge1xuICAgIGlmICghdW5zaWduZWQgJiYgdGhpcy5oaSA+Pj4gMzEpIHtcbiAgICAgICAgdmFyIGxvID0gfnRoaXMubG8gKyAxID4+PiAwLFxuICAgICAgICAgICAgaGkgPSB+dGhpcy5oaSAgICAgPj4+IDA7XG4gICAgICAgIGlmICghbG8pXG4gICAgICAgICAgICBoaSA9IGhpICsgMSA+Pj4gMDtcbiAgICAgICAgcmV0dXJuIC0obG8gKyBoaSAqIDQyOTQ5NjcyOTYpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5sbyArIHRoaXMuaGkgKiA0Mjk0OTY3Mjk2O1xufTtcblxuLyoqXG4gKiBDb252ZXJ0cyB0aGlzIGxvbmcgYml0cyB0byBhIGxvbmcuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFt1bnNpZ25lZD1mYWxzZV0gV2hldGhlciB1bnNpZ25lZCBvciBub3RcbiAqIEByZXR1cm5zIHtMb25nfSBMb25nXG4gKi9cbkxvbmdCaXRzLnByb3RvdHlwZS50b0xvbmcgPSBmdW5jdGlvbiB0b0xvbmcodW5zaWduZWQpIHtcbiAgICByZXR1cm4gdXRpbC5Mb25nXG4gICAgICAgID8gbmV3IHV0aWwuTG9uZyh0aGlzLmxvIHwgMCwgdGhpcy5oaSB8IDAsIEJvb2xlYW4odW5zaWduZWQpKVxuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgICA6IHsgbG93OiB0aGlzLmxvIHwgMCwgaGlnaDogdGhpcy5oaSB8IDAsIHVuc2lnbmVkOiBCb29sZWFuKHVuc2lnbmVkKSB9O1xufTtcblxudmFyIGNoYXJDb2RlQXQgPSBTdHJpbmcucHJvdG90eXBlLmNoYXJDb2RlQXQ7XG5cbi8qKlxuICogQ29uc3RydWN0cyBuZXcgbG9uZyBiaXRzIGZyb20gdGhlIHNwZWNpZmllZCA4IGNoYXJhY3RlcnMgbG9uZyBoYXNoLlxuICogQHBhcmFtIHtzdHJpbmd9IGhhc2ggSGFzaFxuICogQHJldHVybnMge3V0aWwuTG9uZ0JpdHN9IEJpdHNcbiAqL1xuTG9uZ0JpdHMuZnJvbUhhc2ggPSBmdW5jdGlvbiBmcm9tSGFzaChoYXNoKSB7XG4gICAgaWYgKGhhc2ggPT09IHplcm9IYXNoKVxuICAgICAgICByZXR1cm4gemVybztcbiAgICByZXR1cm4gbmV3IExvbmdCaXRzKFxuICAgICAgICAoIGNoYXJDb2RlQXQuY2FsbChoYXNoLCAwKVxuICAgICAgICB8IGNoYXJDb2RlQXQuY2FsbChoYXNoLCAxKSA8PCA4XG4gICAgICAgIHwgY2hhckNvZGVBdC5jYWxsKGhhc2gsIDIpIDw8IDE2XG4gICAgICAgIHwgY2hhckNvZGVBdC5jYWxsKGhhc2gsIDMpIDw8IDI0KSA+Pj4gMFxuICAgICxcbiAgICAgICAgKCBjaGFyQ29kZUF0LmNhbGwoaGFzaCwgNClcbiAgICAgICAgfCBjaGFyQ29kZUF0LmNhbGwoaGFzaCwgNSkgPDwgOFxuICAgICAgICB8IGNoYXJDb2RlQXQuY2FsbChoYXNoLCA2KSA8PCAxNlxuICAgICAgICB8IGNoYXJDb2RlQXQuY2FsbChoYXNoLCA3KSA8PCAyNCkgPj4+IDBcbiAgICApO1xufTtcblxuLyoqXG4gKiBDb252ZXJ0cyB0aGlzIGxvbmcgYml0cyB0byBhIDggY2hhcmFjdGVycyBsb25nIGhhc2guXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBIYXNoXG4gKi9cbkxvbmdCaXRzLnByb3RvdHlwZS50b0hhc2ggPSBmdW5jdGlvbiB0b0hhc2goKSB7XG4gICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUoXG4gICAgICAgIHRoaXMubG8gICAgICAgICYgMjU1LFxuICAgICAgICB0aGlzLmxvID4+PiA4ICAmIDI1NSxcbiAgICAgICAgdGhpcy5sbyA+Pj4gMTYgJiAyNTUsXG4gICAgICAgIHRoaXMubG8gPj4+IDI0ICAgICAgLFxuICAgICAgICB0aGlzLmhpICAgICAgICAmIDI1NSxcbiAgICAgICAgdGhpcy5oaSA+Pj4gOCAgJiAyNTUsXG4gICAgICAgIHRoaXMuaGkgPj4+IDE2ICYgMjU1LFxuICAgICAgICB0aGlzLmhpID4+PiAyNFxuICAgICk7XG59O1xuXG4vKipcbiAqIFppZy16YWcgZW5jb2RlcyB0aGlzIGxvbmcgYml0cy5cbiAqIEByZXR1cm5zIHt1dGlsLkxvbmdCaXRzfSBgdGhpc2BcbiAqL1xuTG9uZ0JpdHMucHJvdG90eXBlLnp6RW5jb2RlID0gZnVuY3Rpb24genpFbmNvZGUoKSB7XG4gICAgdmFyIG1hc2sgPSAgIHRoaXMuaGkgPj4gMzE7XG4gICAgdGhpcy5oaSAgPSAoKHRoaXMuaGkgPDwgMSB8IHRoaXMubG8gPj4+IDMxKSBeIG1hc2spID4+PiAwO1xuICAgIHRoaXMubG8gID0gKCB0aGlzLmxvIDw8IDEgICAgICAgICAgICAgICAgICAgXiBtYXNrKSA+Pj4gMDtcbiAgICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogWmlnLXphZyBkZWNvZGVzIHRoaXMgbG9uZyBiaXRzLlxuICogQHJldHVybnMge3V0aWwuTG9uZ0JpdHN9IGB0aGlzYFxuICovXG5Mb25nQml0cy5wcm90b3R5cGUuenpEZWNvZGUgPSBmdW5jdGlvbiB6ekRlY29kZSgpIHtcbiAgICB2YXIgbWFzayA9IC0odGhpcy5sbyAmIDEpO1xuICAgIHRoaXMubG8gID0gKCh0aGlzLmxvID4+PiAxIHwgdGhpcy5oaSA8PCAzMSkgXiBtYXNrKSA+Pj4gMDtcbiAgICB0aGlzLmhpICA9ICggdGhpcy5oaSA+Pj4gMSAgICAgICAgICAgICAgICAgIF4gbWFzaykgPj4+IDA7XG4gICAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIGxlbmd0aCBvZiB0aGlzIGxvbmdiaXRzIHdoZW4gZW5jb2RlZCBhcyBhIHZhcmludC5cbiAqIEByZXR1cm5zIHtudW1iZXJ9IExlbmd0aFxuICovXG5Mb25nQml0cy5wcm90b3R5cGUubGVuZ3RoID0gZnVuY3Rpb24gbGVuZ3RoKCkge1xuICAgIHZhciBwYXJ0MCA9ICB0aGlzLmxvLFxuICAgICAgICBwYXJ0MSA9ICh0aGlzLmxvID4+PiAyOCB8IHRoaXMuaGkgPDwgNCkgPj4+IDAsXG4gICAgICAgIHBhcnQyID0gIHRoaXMuaGkgPj4+IDI0O1xuICAgIHJldHVybiBwYXJ0MiA9PT0gMFxuICAgICAgICAgPyBwYXJ0MSA9PT0gMFxuICAgICAgICAgICA/IHBhcnQwIDwgMTYzODRcbiAgICAgICAgICAgICA/IHBhcnQwIDwgMTI4ID8gMSA6IDJcbiAgICAgICAgICAgICA6IHBhcnQwIDwgMjA5NzE1MiA/IDMgOiA0XG4gICAgICAgICAgIDogcGFydDEgPCAxNjM4NFxuICAgICAgICAgICAgID8gcGFydDEgPCAxMjggPyA1IDogNlxuICAgICAgICAgICAgIDogcGFydDEgPCAyMDk3MTUyID8gNyA6IDhcbiAgICAgICAgIDogcGFydDIgPCAxMjggPyA5IDogMTA7XG59O1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG52YXIgdXRpbCA9IGV4cG9ydHM7XG5cbi8vIHVzZWQgdG8gcmV0dXJuIGEgUHJvbWlzZSB3aGVyZSBjYWxsYmFjayBpcyBvbWl0dGVkXG51dGlsLmFzUHJvbWlzZSA9IHJlcXVpcmUoXCJAcHJvdG9idWZqcy9hc3Byb21pc2VcIik7XG5cbi8vIGNvbnZlcnRzIHRvIC8gZnJvbSBiYXNlNjQgZW5jb2RlZCBzdHJpbmdzXG51dGlsLmJhc2U2NCA9IHJlcXVpcmUoXCJAcHJvdG9idWZqcy9iYXNlNjRcIik7XG5cbi8vIGJhc2UgY2xhc3Mgb2YgcnBjLlNlcnZpY2VcbnV0aWwuRXZlbnRFbWl0dGVyID0gcmVxdWlyZShcIkBwcm90b2J1ZmpzL2V2ZW50ZW1pdHRlclwiKTtcblxuLy8gZmxvYXQgaGFuZGxpbmcgYWNjcm9zcyBicm93c2Vyc1xudXRpbC5mbG9hdCA9IHJlcXVpcmUoXCJAcHJvdG9idWZqcy9mbG9hdFwiKTtcblxuLy8gcmVxdWlyZXMgbW9kdWxlcyBvcHRpb25hbGx5IGFuZCBoaWRlcyB0aGUgY2FsbCBmcm9tIGJ1bmRsZXJzXG51dGlsLmlucXVpcmUgPSByZXF1aXJlKFwiQHByb3RvYnVmanMvaW5xdWlyZVwiKTtcblxuLy8gY29udmVydHMgdG8gLyBmcm9tIHV0ZjggZW5jb2RlZCBzdHJpbmdzXG51dGlsLnV0ZjggPSByZXF1aXJlKFwiQHByb3RvYnVmanMvdXRmOFwiKTtcblxuLy8gcHJvdmlkZXMgYSBub2RlLWxpa2UgYnVmZmVyIHBvb2wgaW4gdGhlIGJyb3dzZXJcbnV0aWwucG9vbCA9IHJlcXVpcmUoXCJAcHJvdG9idWZqcy9wb29sXCIpO1xuXG4vLyB1dGlsaXR5IHRvIHdvcmsgd2l0aCB0aGUgbG93IGFuZCBoaWdoIGJpdHMgb2YgYSA2NCBiaXQgdmFsdWVcbnV0aWwuTG9uZ0JpdHMgPSByZXF1aXJlKFwiLi9sb25nYml0c1wiKTtcblxuLyoqXG4gKiBXaGV0aGVyIHJ1bm5pbmcgd2l0aGluIG5vZGUgb3Igbm90LlxuICogQG1lbWJlcm9mIHV0aWxcbiAqIEB0eXBlIHtib29sZWFufVxuICovXG51dGlsLmlzTm9kZSA9IEJvb2xlYW4odHlwZW9mIGdsb2JhbCAhPT0gXCJ1bmRlZmluZWRcIlxuICAgICAgICAgICAgICAgICAgICYmIGdsb2JhbFxuICAgICAgICAgICAgICAgICAgICYmIGdsb2JhbC5wcm9jZXNzXG4gICAgICAgICAgICAgICAgICAgJiYgZ2xvYmFsLnByb2Nlc3MudmVyc2lvbnNcbiAgICAgICAgICAgICAgICAgICAmJiBnbG9iYWwucHJvY2Vzcy52ZXJzaW9ucy5ub2RlKTtcblxuLyoqXG4gKiBHbG9iYWwgb2JqZWN0IHJlZmVyZW5jZS5cbiAqIEBtZW1iZXJvZiB1dGlsXG4gKiBAdHlwZSB7T2JqZWN0fVxuICovXG51dGlsLmdsb2JhbCA9IHV0aWwuaXNOb2RlICYmIGdsb2JhbFxuICAgICAgICAgICB8fCB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiICYmIHdpbmRvd1xuICAgICAgICAgICB8fCB0eXBlb2Ygc2VsZiAgICE9PSBcInVuZGVmaW5lZFwiICYmIHNlbGZcbiAgICAgICAgICAgfHwgdGhpczsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1pbnZhbGlkLXRoaXNcblxuLyoqXG4gKiBBbiBpbW11YWJsZSBlbXB0eSBhcnJheS5cbiAqIEBtZW1iZXJvZiB1dGlsXG4gKiBAdHlwZSB7QXJyYXkuPCo+fVxuICogQGNvbnN0XG4gKi9cbnV0aWwuZW1wdHlBcnJheSA9IE9iamVjdC5mcmVlemUgPyBPYmplY3QuZnJlZXplKFtdKSA6IC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovIFtdOyAvLyB1c2VkIG9uIHByb3RvdHlwZXNcblxuLyoqXG4gKiBBbiBpbW11dGFibGUgZW1wdHkgb2JqZWN0LlxuICogQHR5cGUge09iamVjdH1cbiAqIEBjb25zdFxuICovXG51dGlsLmVtcHR5T2JqZWN0ID0gT2JqZWN0LmZyZWV6ZSA/IE9iamVjdC5mcmVlemUoe30pIDogLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi8ge307IC8vIHVzZWQgb24gcHJvdG90eXBlc1xuXG4vKipcbiAqIFRlc3RzIGlmIHRoZSBzcGVjaWZpZWQgdmFsdWUgaXMgYW4gaW50ZWdlci5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHsqfSB2YWx1ZSBWYWx1ZSB0byB0ZXN0XG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gYHRydWVgIGlmIHRoZSB2YWx1ZSBpcyBhbiBpbnRlZ2VyXG4gKi9cbnV0aWwuaXNJbnRlZ2VyID0gTnVtYmVyLmlzSW50ZWdlciB8fCAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqLyBmdW5jdGlvbiBpc0ludGVnZXIodmFsdWUpIHtcbiAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSBcIm51bWJlclwiICYmIGlzRmluaXRlKHZhbHVlKSAmJiBNYXRoLmZsb29yKHZhbHVlKSA9PT0gdmFsdWU7XG59O1xuXG4vKipcbiAqIFRlc3RzIGlmIHRoZSBzcGVjaWZpZWQgdmFsdWUgaXMgYSBzdHJpbmcuXG4gKiBAcGFyYW0geyp9IHZhbHVlIFZhbHVlIHRvIHRlc3RcbiAqIEByZXR1cm5zIHtib29sZWFufSBgdHJ1ZWAgaWYgdGhlIHZhbHVlIGlzIGEgc3RyaW5nXG4gKi9cbnV0aWwuaXNTdHJpbmcgPSBmdW5jdGlvbiBpc1N0cmluZyh2YWx1ZSkge1xuICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIgfHwgdmFsdWUgaW5zdGFuY2VvZiBTdHJpbmc7XG59O1xuXG4vKipcbiAqIFRlc3RzIGlmIHRoZSBzcGVjaWZpZWQgdmFsdWUgaXMgYSBub24tbnVsbCBvYmplY3QuXG4gKiBAcGFyYW0geyp9IHZhbHVlIFZhbHVlIHRvIHRlc3RcbiAqIEByZXR1cm5zIHtib29sZWFufSBgdHJ1ZWAgaWYgdGhlIHZhbHVlIGlzIGEgbm9uLW51bGwgb2JqZWN0XG4gKi9cbnV0aWwuaXNPYmplY3QgPSBmdW5jdGlvbiBpc09iamVjdCh2YWx1ZSkge1xuICAgIHJldHVybiB2YWx1ZSAmJiB0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCI7XG59O1xuXG4vKipcbiAqIENoZWNrcyBpZiBhIHByb3BlcnR5IG9uIGEgbWVzc2FnZSBpcyBjb25zaWRlcmVkIHRvIGJlIHByZXNlbnQuXG4gKiBUaGlzIGlzIGFuIGFsaWFzIG9mIHtAbGluayB1dGlsLmlzU2V0fS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtPYmplY3R9IG9iaiBQbGFpbiBvYmplY3Qgb3IgbWVzc2FnZSBpbnN0YW5jZVxuICogQHBhcmFtIHtzdHJpbmd9IHByb3AgUHJvcGVydHkgbmFtZVxuICogQHJldHVybnMge2Jvb2xlYW59IGB0cnVlYCBpZiBjb25zaWRlcmVkIHRvIGJlIHByZXNlbnQsIG90aGVyd2lzZSBgZmFsc2VgXG4gKi9cbnV0aWwuaXNzZXQgPVxuXG4vKipcbiAqIENoZWNrcyBpZiBhIHByb3BlcnR5IG9uIGEgbWVzc2FnZSBpcyBjb25zaWRlcmVkIHRvIGJlIHByZXNlbnQuXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqIFBsYWluIG9iamVjdCBvciBtZXNzYWdlIGluc3RhbmNlXG4gKiBAcGFyYW0ge3N0cmluZ30gcHJvcCBQcm9wZXJ0eSBuYW1lXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gYHRydWVgIGlmIGNvbnNpZGVyZWQgdG8gYmUgcHJlc2VudCwgb3RoZXJ3aXNlIGBmYWxzZWBcbiAqL1xudXRpbC5pc1NldCA9IGZ1bmN0aW9uIGlzU2V0KG9iaiwgcHJvcCkge1xuICAgIHZhciB2YWx1ZSA9IG9ialtwcm9wXTtcbiAgICBpZiAodmFsdWUgIT0gbnVsbCAmJiBvYmouaGFzT3duUHJvcGVydHkocHJvcCkpIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgZXFlcWVxLCBuby1wcm90b3R5cGUtYnVpbHRpbnNcbiAgICAgICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSAhPT0gXCJvYmplY3RcIiB8fCAoQXJyYXkuaXNBcnJheSh2YWx1ZSkgPyB2YWx1ZS5sZW5ndGggOiBPYmplY3Qua2V5cyh2YWx1ZSkubGVuZ3RoKSA+IDA7XG4gICAgcmV0dXJuIGZhbHNlO1xufTtcblxuLyoqXG4gKiBBbnkgY29tcGF0aWJsZSBCdWZmZXIgaW5zdGFuY2UuXG4gKiBUaGlzIGlzIGEgbWluaW1hbCBzdGFuZC1hbG9uZSBkZWZpbml0aW9uIG9mIGEgQnVmZmVyIGluc3RhbmNlLiBUaGUgYWN0dWFsIHR5cGUgaXMgdGhhdCBleHBvcnRlZCBieSBub2RlJ3MgdHlwaW5ncy5cbiAqIEBpbnRlcmZhY2UgQnVmZmVyXG4gKiBAZXh0ZW5kcyBVaW50OEFycmF5XG4gKi9cblxuLyoqXG4gKiBOb2RlJ3MgQnVmZmVyIGNsYXNzIGlmIGF2YWlsYWJsZS5cbiAqIEB0eXBlIHtDb25zdHJ1Y3RvcjxCdWZmZXI+fVxuICovXG51dGlsLkJ1ZmZlciA9IChmdW5jdGlvbigpIHtcbiAgICB0cnkge1xuICAgICAgICB2YXIgQnVmZmVyID0gdXRpbC5pbnF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcjtcbiAgICAgICAgLy8gcmVmdXNlIHRvIHVzZSBub24tbm9kZSBidWZmZXJzIGlmIG5vdCBleHBsaWNpdGx5IGFzc2lnbmVkIChwZXJmIHJlYXNvbnMpOlxuICAgICAgICByZXR1cm4gQnVmZmVyLnByb3RvdHlwZS51dGY4V3JpdGUgPyBCdWZmZXIgOiAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqLyBudWxsO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxufSkoKTtcblxuLy8gSW50ZXJuYWwgYWxpYXMgb2Ygb3IgcG9seWZ1bGwgZm9yIEJ1ZmZlci5mcm9tLlxudXRpbC5fQnVmZmVyX2Zyb20gPSBudWxsO1xuXG4vLyBJbnRlcm5hbCBhbGlhcyBvZiBvciBwb2x5ZmlsbCBmb3IgQnVmZmVyLmFsbG9jVW5zYWZlLlxudXRpbC5fQnVmZmVyX2FsbG9jVW5zYWZlID0gbnVsbDtcblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IGJ1ZmZlciBvZiB3aGF0ZXZlciB0eXBlIHN1cHBvcnRlZCBieSB0aGUgZW52aXJvbm1lbnQuXG4gKiBAcGFyYW0ge251bWJlcnxudW1iZXJbXX0gW3NpemVPckFycmF5PTBdIEJ1ZmZlciBzaXplIG9yIG51bWJlciBhcnJheVxuICogQHJldHVybnMge1VpbnQ4QXJyYXl8QnVmZmVyfSBCdWZmZXJcbiAqL1xudXRpbC5uZXdCdWZmZXIgPSBmdW5jdGlvbiBuZXdCdWZmZXIoc2l6ZU9yQXJyYXkpIHtcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgIHJldHVybiB0eXBlb2Ygc2l6ZU9yQXJyYXkgPT09IFwibnVtYmVyXCJcbiAgICAgICAgPyB1dGlsLkJ1ZmZlclxuICAgICAgICAgICAgPyB1dGlsLl9CdWZmZXJfYWxsb2NVbnNhZmUoc2l6ZU9yQXJyYXkpXG4gICAgICAgICAgICA6IG5ldyB1dGlsLkFycmF5KHNpemVPckFycmF5KVxuICAgICAgICA6IHV0aWwuQnVmZmVyXG4gICAgICAgICAgICA/IHV0aWwuX0J1ZmZlcl9mcm9tKHNpemVPckFycmF5KVxuICAgICAgICAgICAgOiB0eXBlb2YgVWludDhBcnJheSA9PT0gXCJ1bmRlZmluZWRcIlxuICAgICAgICAgICAgICAgID8gc2l6ZU9yQXJyYXlcbiAgICAgICAgICAgICAgICA6IG5ldyBVaW50OEFycmF5KHNpemVPckFycmF5KTtcbn07XG5cbi8qKlxuICogQXJyYXkgaW1wbGVtZW50YXRpb24gdXNlZCBpbiB0aGUgYnJvd3Nlci4gYFVpbnQ4QXJyYXlgIGlmIHN1cHBvcnRlZCwgb3RoZXJ3aXNlIGBBcnJheWAuXG4gKiBAdHlwZSB7Q29uc3RydWN0b3I8VWludDhBcnJheT59XG4gKi9cbnV0aWwuQXJyYXkgPSB0eXBlb2YgVWludDhBcnJheSAhPT0gXCJ1bmRlZmluZWRcIiA/IFVpbnQ4QXJyYXkgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi8gOiBBcnJheTtcblxuLyoqXG4gKiBBbnkgY29tcGF0aWJsZSBMb25nIGluc3RhbmNlLlxuICogVGhpcyBpcyBhIG1pbmltYWwgc3RhbmQtYWxvbmUgZGVmaW5pdGlvbiBvZiBhIExvbmcgaW5zdGFuY2UuIFRoZSBhY3R1YWwgdHlwZSBpcyB0aGF0IGV4cG9ydGVkIGJ5IGxvbmcuanMuXG4gKiBAaW50ZXJmYWNlIExvbmdcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBsb3cgTG93IGJpdHNcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBoaWdoIEhpZ2ggYml0c1xuICogQHByb3BlcnR5IHtib29sZWFufSB1bnNpZ25lZCBXaGV0aGVyIHVuc2lnbmVkIG9yIG5vdFxuICovXG5cbi8qKlxuICogTG9uZy5qcydzIExvbmcgY2xhc3MgaWYgYXZhaWxhYmxlLlxuICogQHR5cGUge0NvbnN0cnVjdG9yPExvbmc+fVxuICovXG51dGlsLkxvbmcgPSAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqLyB1dGlsLmdsb2JhbC5kY29kZUlPICYmIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovIHV0aWwuZ2xvYmFsLmRjb2RlSU8uTG9uZ1xuICAgICAgICAgfHwgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi8gdXRpbC5nbG9iYWwuTG9uZ1xuICAgICAgICAgfHwgdXRpbC5pbnF1aXJlKFwibG9uZ1wiKTtcblxuLyoqXG4gKiBSZWd1bGFyIGV4cHJlc3Npb24gdXNlZCB0byB2ZXJpZnkgMiBiaXQgKGBib29sYCkgbWFwIGtleXMuXG4gKiBAdHlwZSB7UmVnRXhwfVxuICogQGNvbnN0XG4gKi9cbnV0aWwua2V5MlJlID0gL150cnVlfGZhbHNlfDB8MSQvO1xuXG4vKipcbiAqIFJlZ3VsYXIgZXhwcmVzc2lvbiB1c2VkIHRvIHZlcmlmeSAzMiBiaXQgKGBpbnQzMmAgZXRjLikgbWFwIGtleXMuXG4gKiBAdHlwZSB7UmVnRXhwfVxuICogQGNvbnN0XG4gKi9cbnV0aWwua2V5MzJSZSA9IC9eLT8oPzowfFsxLTldWzAtOV0qKSQvO1xuXG4vKipcbiAqIFJlZ3VsYXIgZXhwcmVzc2lvbiB1c2VkIHRvIHZlcmlmeSA2NCBiaXQgKGBpbnQ2NGAgZXRjLikgbWFwIGtleXMuXG4gKiBAdHlwZSB7UmVnRXhwfVxuICogQGNvbnN0XG4gKi9cbnV0aWwua2V5NjRSZSA9IC9eKD86W1xcXFx4MDAtXFxcXHhmZl17OH18LT8oPzowfFsxLTldWzAtOV0qKSkkLztcblxuLyoqXG4gKiBDb252ZXJ0cyBhIG51bWJlciBvciBsb25nIHRvIGFuIDggY2hhcmFjdGVycyBsb25nIGhhc2ggc3RyaW5nLlxuICogQHBhcmFtIHtMb25nfG51bWJlcn0gdmFsdWUgVmFsdWUgdG8gY29udmVydFxuICogQHJldHVybnMge3N0cmluZ30gSGFzaFxuICovXG51dGlsLmxvbmdUb0hhc2ggPSBmdW5jdGlvbiBsb25nVG9IYXNoKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlXG4gICAgICAgID8gdXRpbC5Mb25nQml0cy5mcm9tKHZhbHVlKS50b0hhc2goKVxuICAgICAgICA6IHV0aWwuTG9uZ0JpdHMuemVyb0hhc2g7XG59O1xuXG4vKipcbiAqIENvbnZlcnRzIGFuIDggY2hhcmFjdGVycyBsb25nIGhhc2ggc3RyaW5nIHRvIGEgbG9uZyBvciBudW1iZXIuXG4gKiBAcGFyYW0ge3N0cmluZ30gaGFzaCBIYXNoXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFt1bnNpZ25lZD1mYWxzZV0gV2hldGhlciB1bnNpZ25lZCBvciBub3RcbiAqIEByZXR1cm5zIHtMb25nfG51bWJlcn0gT3JpZ2luYWwgdmFsdWVcbiAqL1xudXRpbC5sb25nRnJvbUhhc2ggPSBmdW5jdGlvbiBsb25nRnJvbUhhc2goaGFzaCwgdW5zaWduZWQpIHtcbiAgICB2YXIgYml0cyA9IHV0aWwuTG9uZ0JpdHMuZnJvbUhhc2goaGFzaCk7XG4gICAgaWYgKHV0aWwuTG9uZylcbiAgICAgICAgcmV0dXJuIHV0aWwuTG9uZy5mcm9tQml0cyhiaXRzLmxvLCBiaXRzLmhpLCB1bnNpZ25lZCk7XG4gICAgcmV0dXJuIGJpdHMudG9OdW1iZXIoQm9vbGVhbih1bnNpZ25lZCkpO1xufTtcblxuLyoqXG4gKiBNZXJnZXMgdGhlIHByb3BlcnRpZXMgb2YgdGhlIHNvdXJjZSBvYmplY3QgaW50byB0aGUgZGVzdGluYXRpb24gb2JqZWN0LlxuICogQG1lbWJlcm9mIHV0aWxcbiAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IGRzdCBEZXN0aW5hdGlvbiBvYmplY3RcbiAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IHNyYyBTb3VyY2Ugb2JqZWN0XG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtpZk5vdFNldD1mYWxzZV0gTWVyZ2VzIG9ubHkgaWYgdGhlIGtleSBpcyBub3QgYWxyZWFkeSBzZXRcbiAqIEByZXR1cm5zIHtPYmplY3QuPHN0cmluZywqPn0gRGVzdGluYXRpb24gb2JqZWN0XG4gKi9cbmZ1bmN0aW9uIG1lcmdlKGRzdCwgc3JjLCBpZk5vdFNldCkgeyAvLyB1c2VkIGJ5IGNvbnZlcnRlcnNcbiAgICBmb3IgKHZhciBrZXlzID0gT2JqZWN0LmtleXMoc3JjKSwgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKVxuICAgICAgICBpZiAoZHN0W2tleXNbaV1dID09PSB1bmRlZmluZWQgfHwgIWlmTm90U2V0KVxuICAgICAgICAgICAgZHN0W2tleXNbaV1dID0gc3JjW2tleXNbaV1dO1xuICAgIHJldHVybiBkc3Q7XG59XG5cbnV0aWwubWVyZ2UgPSBtZXJnZTtcblxuLyoqXG4gKiBDb252ZXJ0cyB0aGUgZmlyc3QgY2hhcmFjdGVyIG9mIGEgc3RyaW5nIHRvIGxvd2VyIGNhc2UuXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyIFN0cmluZyB0byBjb252ZXJ0XG4gKiBAcmV0dXJucyB7c3RyaW5nfSBDb252ZXJ0ZWQgc3RyaW5nXG4gKi9cbnV0aWwubGNGaXJzdCA9IGZ1bmN0aW9uIGxjRmlyc3Qoc3RyKSB7XG4gICAgcmV0dXJuIHN0ci5jaGFyQXQoMCkudG9Mb3dlckNhc2UoKSArIHN0ci5zdWJzdHJpbmcoMSk7XG59O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBjdXN0b20gZXJyb3IgY29uc3RydWN0b3IuXG4gKiBAbWVtYmVyb2YgdXRpbFxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgRXJyb3IgbmFtZVxuICogQHJldHVybnMge0NvbnN0cnVjdG9yPEVycm9yPn0gQ3VzdG9tIGVycm9yIGNvbnN0cnVjdG9yXG4gKi9cbmZ1bmN0aW9uIG5ld0Vycm9yKG5hbWUpIHtcblxuICAgIGZ1bmN0aW9uIEN1c3RvbUVycm9yKG1lc3NhZ2UsIHByb3BlcnRpZXMpIHtcblxuICAgICAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgQ3VzdG9tRXJyb3IpKVxuICAgICAgICAgICAgcmV0dXJuIG5ldyBDdXN0b21FcnJvcihtZXNzYWdlLCBwcm9wZXJ0aWVzKTtcblxuICAgICAgICAvLyBFcnJvci5jYWxsKHRoaXMsIG1lc3NhZ2UpO1xuICAgICAgICAvLyBeIGp1c3QgcmV0dXJucyBhIG5ldyBlcnJvciBpbnN0YW5jZSBiZWNhdXNlIHRoZSBjdG9yIGNhbiBiZSBjYWxsZWQgYXMgYSBmdW5jdGlvblxuXG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCBcIm1lc3NhZ2VcIiwgeyBnZXQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gbWVzc2FnZTsgfSB9KTtcblxuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgICBpZiAoRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UpIC8vIG5vZGVcbiAgICAgICAgICAgIEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKHRoaXMsIEN1c3RvbUVycm9yKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIFwic3RhY2tcIiwgeyB2YWx1ZTogbmV3IEVycm9yKCkuc3RhY2sgfHwgXCJcIiB9KTtcblxuICAgICAgICBpZiAocHJvcGVydGllcylcbiAgICAgICAgICAgIG1lcmdlKHRoaXMsIHByb3BlcnRpZXMpO1xuICAgIH1cblxuICAgIChDdXN0b21FcnJvci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEVycm9yLnByb3RvdHlwZSkpLmNvbnN0cnVjdG9yID0gQ3VzdG9tRXJyb3I7XG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQ3VzdG9tRXJyb3IucHJvdG90eXBlLCBcIm5hbWVcIiwgeyBnZXQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gbmFtZTsgfSB9KTtcblxuICAgIEN1c3RvbUVycm9yLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5uYW1lICsgXCI6IFwiICsgdGhpcy5tZXNzYWdlO1xuICAgIH07XG5cbiAgICByZXR1cm4gQ3VzdG9tRXJyb3I7XG59XG5cbnV0aWwubmV3RXJyb3IgPSBuZXdFcnJvcjtcblxuLyoqXG4gKiBDb25zdHJ1Y3RzIGEgbmV3IHByb3RvY29sIGVycm9yLlxuICogQGNsYXNzZGVzYyBFcnJvciBzdWJjbGFzcyBpbmRpY2F0aW5nIGEgcHJvdG9jb2wgc3BlY2lmYyBlcnJvci5cbiAqIEBtZW1iZXJvZiB1dGlsXG4gKiBAZXh0ZW5kcyBFcnJvclxuICogQHRlbXBsYXRlIFQgZXh0ZW5kcyBNZXNzYWdlPFQ+XG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIEVycm9yIG1lc3NhZ2VcbiAqIEBwYXJhbSB7T2JqZWN0LjxzdHJpbmcsKj59IFtwcm9wZXJ0aWVzXSBBZGRpdGlvbmFsIHByb3BlcnRpZXNcbiAqIEBleGFtcGxlXG4gKiB0cnkge1xuICogICAgIE15TWVzc2FnZS5kZWNvZGUoc29tZUJ1ZmZlcik7IC8vIHRocm93cyBpZiByZXF1aXJlZCBmaWVsZHMgYXJlIG1pc3NpbmdcbiAqIH0gY2F0Y2ggKGUpIHtcbiAqICAgICBpZiAoZSBpbnN0YW5jZW9mIFByb3RvY29sRXJyb3IgJiYgZS5pbnN0YW5jZSlcbiAqICAgICAgICAgY29uc29sZS5sb2coXCJkZWNvZGVkIHNvIGZhcjogXCIgKyBKU09OLnN0cmluZ2lmeShlLmluc3RhbmNlKSk7XG4gKiB9XG4gKi9cbnV0aWwuUHJvdG9jb2xFcnJvciA9IG5ld0Vycm9yKFwiUHJvdG9jb2xFcnJvclwiKTtcblxuLyoqXG4gKiBTbyBmYXIgZGVjb2RlZCBtZXNzYWdlIGluc3RhbmNlLlxuICogQG5hbWUgdXRpbC5Qcm90b2NvbEVycm9yI2luc3RhbmNlXG4gKiBAdHlwZSB7TWVzc2FnZTxUPn1cbiAqL1xuXG4vKipcbiAqIEEgT25lT2YgZ2V0dGVyIGFzIHJldHVybmVkIGJ5IHtAbGluayB1dGlsLm9uZU9mR2V0dGVyfS5cbiAqIEB0eXBlZGVmIE9uZU9mR2V0dGVyXG4gKiBAdHlwZSB7ZnVuY3Rpb259XG4gKiBAcmV0dXJucyB7c3RyaW5nfHVuZGVmaW5lZH0gU2V0IGZpZWxkIG5hbWUsIGlmIGFueVxuICovXG5cbi8qKlxuICogQnVpbGRzIGEgZ2V0dGVyIGZvciBhIG9uZW9mJ3MgcHJlc2VudCBmaWVsZCBuYW1lLlxuICogQHBhcmFtIHtzdHJpbmdbXX0gZmllbGROYW1lcyBGaWVsZCBuYW1lc1xuICogQHJldHVybnMge09uZU9mR2V0dGVyfSBVbmJvdW5kIGdldHRlclxuICovXG51dGlsLm9uZU9mR2V0dGVyID0gZnVuY3Rpb24gZ2V0T25lT2YoZmllbGROYW1lcykge1xuICAgIHZhciBmaWVsZE1hcCA9IHt9O1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZmllbGROYW1lcy5sZW5ndGg7ICsraSlcbiAgICAgICAgZmllbGRNYXBbZmllbGROYW1lc1tpXV0gPSAxO1xuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMge3N0cmluZ3x1bmRlZmluZWR9IFNldCBmaWVsZCBuYW1lLCBpZiBhbnlcbiAgICAgKiBAdGhpcyBPYmplY3RcbiAgICAgKiBAaWdub3JlXG4gICAgICovXG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGNvbnNpc3RlbnQtcmV0dXJuXG4gICAgICAgIGZvciAodmFyIGtleXMgPSBPYmplY3Qua2V5cyh0aGlzKSwgaSA9IGtleXMubGVuZ3RoIC0gMTsgaSA+IC0xOyAtLWkpXG4gICAgICAgICAgICBpZiAoZmllbGRNYXBba2V5c1tpXV0gPT09IDEgJiYgdGhpc1trZXlzW2ldXSAhPT0gdW5kZWZpbmVkICYmIHRoaXNba2V5c1tpXV0gIT09IG51bGwpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGtleXNbaV07XG4gICAgfTtcbn07XG5cbi8qKlxuICogQSBPbmVPZiBzZXR0ZXIgYXMgcmV0dXJuZWQgYnkge0BsaW5rIHV0aWwub25lT2ZTZXR0ZXJ9LlxuICogQHR5cGVkZWYgT25lT2ZTZXR0ZXJcbiAqIEB0eXBlIHtmdW5jdGlvbn1cbiAqIEBwYXJhbSB7c3RyaW5nfHVuZGVmaW5lZH0gdmFsdWUgRmllbGQgbmFtZVxuICogQHJldHVybnMge3VuZGVmaW5lZH1cbiAqL1xuXG4vKipcbiAqIEJ1aWxkcyBhIHNldHRlciBmb3IgYSBvbmVvZidzIHByZXNlbnQgZmllbGQgbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nW119IGZpZWxkTmFtZXMgRmllbGQgbmFtZXNcbiAqIEByZXR1cm5zIHtPbmVPZlNldHRlcn0gVW5ib3VuZCBzZXR0ZXJcbiAqL1xudXRpbC5vbmVPZlNldHRlciA9IGZ1bmN0aW9uIHNldE9uZU9mKGZpZWxkTmFtZXMpIHtcblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIEZpZWxkIG5hbWVcbiAgICAgKiBAcmV0dXJucyB7dW5kZWZpbmVkfVxuICAgICAqIEB0aGlzIE9iamVjdFxuICAgICAqIEBpZ25vcmVcbiAgICAgKi9cbiAgICByZXR1cm4gZnVuY3Rpb24obmFtZSkge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGZpZWxkTmFtZXMubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICBpZiAoZmllbGROYW1lc1tpXSAhPT0gbmFtZSlcbiAgICAgICAgICAgICAgICBkZWxldGUgdGhpc1tmaWVsZE5hbWVzW2ldXTtcbiAgICB9O1xufTtcblxuLyoqXG4gKiBEZWZhdWx0IGNvbnZlcnNpb24gb3B0aW9ucyB1c2VkIGZvciB7QGxpbmsgTWVzc2FnZSN0b0pTT059IGltcGxlbWVudGF0aW9ucy5cbiAqXG4gKiBUaGVzZSBvcHRpb25zIGFyZSBjbG9zZSB0byBwcm90bzMncyBKU09OIG1hcHBpbmcgd2l0aCB0aGUgZXhjZXB0aW9uIHRoYXQgaW50ZXJuYWwgdHlwZXMgbGlrZSBBbnkgYXJlIGhhbmRsZWQganVzdCBsaWtlIG1lc3NhZ2VzLiBNb3JlIHByZWNpc2VseTpcbiAqXG4gKiAtIExvbmdzIGJlY29tZSBzdHJpbmdzXG4gKiAtIEVudW1zIGJlY29tZSBzdHJpbmcga2V5c1xuICogLSBCeXRlcyBiZWNvbWUgYmFzZTY0IGVuY29kZWQgc3RyaW5nc1xuICogLSAoU3ViLSlNZXNzYWdlcyBiZWNvbWUgcGxhaW4gb2JqZWN0c1xuICogLSBNYXBzIGJlY29tZSBwbGFpbiBvYmplY3RzIHdpdGggYWxsIHN0cmluZyBrZXlzXG4gKiAtIFJlcGVhdGVkIGZpZWxkcyBiZWNvbWUgYXJyYXlzXG4gKiAtIE5hTiBhbmQgSW5maW5pdHkgZm9yIGZsb2F0IGFuZCBkb3VibGUgZmllbGRzIGJlY29tZSBzdHJpbmdzXG4gKlxuICogQHR5cGUge0lDb252ZXJzaW9uT3B0aW9uc31cbiAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy9kb2NzL3Byb3RvMz9obD1lbiNqc29uXG4gKi9cbnV0aWwudG9KU09OT3B0aW9ucyA9IHtcbiAgICBsb25nczogU3RyaW5nLFxuICAgIGVudW1zOiBTdHJpbmcsXG4gICAgYnl0ZXM6IFN0cmluZyxcbiAgICBqc29uOiB0cnVlXG59O1xuXG4vLyBTZXRzIHVwIGJ1ZmZlciB1dGlsaXR5IGFjY29yZGluZyB0byB0aGUgZW52aXJvbm1lbnQgKGNhbGxlZCBpbiBpbmRleC1taW5pbWFsKVxudXRpbC5fY29uZmlndXJlID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIEJ1ZmZlciA9IHV0aWwuQnVmZmVyO1xuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgIGlmICghQnVmZmVyKSB7XG4gICAgICAgIHV0aWwuX0J1ZmZlcl9mcm9tID0gdXRpbC5fQnVmZmVyX2FsbG9jVW5zYWZlID0gbnVsbDtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBiZWNhdXNlIG5vZGUgNC54IGJ1ZmZlcnMgYXJlIGluY29tcGF0aWJsZSAmIGltbXV0YWJsZVxuICAgIC8vIHNlZTogaHR0cHM6Ly9naXRodWIuY29tL2Rjb2RlSU8vcHJvdG9idWYuanMvcHVsbC82NjVcbiAgICB1dGlsLl9CdWZmZXJfZnJvbSA9IEJ1ZmZlci5mcm9tICE9PSBVaW50OEFycmF5LmZyb20gJiYgQnVmZmVyLmZyb20gfHxcbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgICAgZnVuY3Rpb24gQnVmZmVyX2Zyb20odmFsdWUsIGVuY29kaW5nKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IEJ1ZmZlcih2YWx1ZSwgZW5jb2RpbmcpO1xuICAgICAgICB9O1xuICAgIHV0aWwuX0J1ZmZlcl9hbGxvY1Vuc2FmZSA9IEJ1ZmZlci5hbGxvY1Vuc2FmZSB8fFxuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgICBmdW5jdGlvbiBCdWZmZXJfYWxsb2NVbnNhZmUoc2l6ZSkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBCdWZmZXIoc2l6ZSk7XG4gICAgICAgIH07XG59O1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5tb2R1bGUuZXhwb3J0cyA9IFdyaXRlcjtcblxudmFyIHV0aWwgICAgICA9IHJlcXVpcmUoXCIuL3V0aWwvbWluaW1hbFwiKTtcblxudmFyIEJ1ZmZlcldyaXRlcjsgLy8gY3ljbGljXG5cbnZhciBMb25nQml0cyAgPSB1dGlsLkxvbmdCaXRzLFxuICAgIGJhc2U2NCAgICA9IHV0aWwuYmFzZTY0LFxuICAgIHV0ZjggICAgICA9IHV0aWwudXRmODtcblxuLyoqXG4gKiBDb25zdHJ1Y3RzIGEgbmV3IHdyaXRlciBvcGVyYXRpb24gaW5zdGFuY2UuXG4gKiBAY2xhc3NkZXNjIFNjaGVkdWxlZCB3cml0ZXIgb3BlcmF0aW9uLlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKCosIFVpbnQ4QXJyYXksIG51bWJlcil9IGZuIEZ1bmN0aW9uIHRvIGNhbGxcbiAqIEBwYXJhbSB7bnVtYmVyfSBsZW4gVmFsdWUgYnl0ZSBsZW5ndGhcbiAqIEBwYXJhbSB7Kn0gdmFsIFZhbHVlIHRvIHdyaXRlXG4gKiBAaWdub3JlXG4gKi9cbmZ1bmN0aW9uIE9wKGZuLCBsZW4sIHZhbCkge1xuXG4gICAgLyoqXG4gICAgICogRnVuY3Rpb24gdG8gY2FsbC5cbiAgICAgKiBAdHlwZSB7ZnVuY3Rpb24oVWludDhBcnJheSwgbnVtYmVyLCAqKX1cbiAgICAgKi9cbiAgICB0aGlzLmZuID0gZm47XG5cbiAgICAvKipcbiAgICAgKiBWYWx1ZSBieXRlIGxlbmd0aC5cbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIHRoaXMubGVuID0gbGVuO1xuXG4gICAgLyoqXG4gICAgICogTmV4dCBvcGVyYXRpb24uXG4gICAgICogQHR5cGUge1dyaXRlci5PcHx1bmRlZmluZWR9XG4gICAgICovXG4gICAgdGhpcy5uZXh0ID0gdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogVmFsdWUgdG8gd3JpdGUuXG4gICAgICogQHR5cGUgeyp9XG4gICAgICovXG4gICAgdGhpcy52YWwgPSB2YWw7IC8vIHR5cGUgdmFyaWVzXG59XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG5mdW5jdGlvbiBub29wKCkge30gLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1lbXB0eS1mdW5jdGlvblxuXG4vKipcbiAqIENvbnN0cnVjdHMgYSBuZXcgd3JpdGVyIHN0YXRlIGluc3RhbmNlLlxuICogQGNsYXNzZGVzYyBDb3BpZWQgd3JpdGVyIHN0YXRlLlxuICogQG1lbWJlcm9mIFdyaXRlclxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge1dyaXRlcn0gd3JpdGVyIFdyaXRlciB0byBjb3B5IHN0YXRlIGZyb21cbiAqIEBpZ25vcmVcbiAqL1xuZnVuY3Rpb24gU3RhdGUod3JpdGVyKSB7XG5cbiAgICAvKipcbiAgICAgKiBDdXJyZW50IGhlYWQuXG4gICAgICogQHR5cGUge1dyaXRlci5PcH1cbiAgICAgKi9cbiAgICB0aGlzLmhlYWQgPSB3cml0ZXIuaGVhZDtcblxuICAgIC8qKlxuICAgICAqIEN1cnJlbnQgdGFpbC5cbiAgICAgKiBAdHlwZSB7V3JpdGVyLk9wfVxuICAgICAqL1xuICAgIHRoaXMudGFpbCA9IHdyaXRlci50YWlsO1xuXG4gICAgLyoqXG4gICAgICogQ3VycmVudCBidWZmZXIgbGVuZ3RoLlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG4gICAgdGhpcy5sZW4gPSB3cml0ZXIubGVuO1xuXG4gICAgLyoqXG4gICAgICogTmV4dCBzdGF0ZS5cbiAgICAgKiBAdHlwZSB7U3RhdGV8bnVsbH1cbiAgICAgKi9cbiAgICB0aGlzLm5leHQgPSB3cml0ZXIuc3RhdGVzO1xufVxuXG4vKipcbiAqIENvbnN0cnVjdHMgYSBuZXcgd3JpdGVyIGluc3RhbmNlLlxuICogQGNsYXNzZGVzYyBXaXJlIGZvcm1hdCB3cml0ZXIgdXNpbmcgYFVpbnQ4QXJyYXlgIGlmIGF2YWlsYWJsZSwgb3RoZXJ3aXNlIGBBcnJheWAuXG4gKiBAY29uc3RydWN0b3JcbiAqL1xuZnVuY3Rpb24gV3JpdGVyKCkge1xuXG4gICAgLyoqXG4gICAgICogQ3VycmVudCBsZW5ndGguXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICB0aGlzLmxlbiA9IDA7XG5cbiAgICAvKipcbiAgICAgKiBPcGVyYXRpb25zIGhlYWQuXG4gICAgICogQHR5cGUge09iamVjdH1cbiAgICAgKi9cbiAgICB0aGlzLmhlYWQgPSBuZXcgT3Aobm9vcCwgMCwgMCk7XG5cbiAgICAvKipcbiAgICAgKiBPcGVyYXRpb25zIHRhaWxcbiAgICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgICAqL1xuICAgIHRoaXMudGFpbCA9IHRoaXMuaGVhZDtcblxuICAgIC8qKlxuICAgICAqIExpbmtlZCBmb3JrZWQgc3RhdGVzLlxuICAgICAqIEB0eXBlIHtPYmplY3R8bnVsbH1cbiAgICAgKi9cbiAgICB0aGlzLnN0YXRlcyA9IG51bGw7XG5cbiAgICAvLyBXaGVuIGEgdmFsdWUgaXMgd3JpdHRlbiwgdGhlIHdyaXRlciBjYWxjdWxhdGVzIGl0cyBieXRlIGxlbmd0aCBhbmQgcHV0cyBpdCBpbnRvIGEgbGlua2VkXG4gICAgLy8gbGlzdCBvZiBvcGVyYXRpb25zIHRvIHBlcmZvcm0gd2hlbiBmaW5pc2goKSBpcyBjYWxsZWQuIFRoaXMgYm90aCBhbGxvd3MgdXMgdG8gYWxsb2NhdGVcbiAgICAvLyBidWZmZXJzIG9mIHRoZSBleGFjdCByZXF1aXJlZCBzaXplIGFuZCByZWR1Y2VzIHRoZSBhbW91bnQgb2Ygd29yayB3ZSBoYXZlIHRvIGRvIGNvbXBhcmVkXG4gICAgLy8gdG8gZmlyc3QgY2FsY3VsYXRpbmcgb3ZlciBvYmplY3RzIGFuZCB0aGVuIGVuY29kaW5nIG92ZXIgb2JqZWN0cy4gSW4gb3VyIGNhc2UsIHRoZSBlbmNvZGluZ1xuICAgIC8vIHBhcnQgaXMganVzdCBhIGxpbmtlZCBsaXN0IHdhbGsgY2FsbGluZyBvcGVyYXRpb25zIHdpdGggYWxyZWFkeSBwcmVwYXJlZCB2YWx1ZXMuXG59XG5cbnZhciBjcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUoKSB7XG4gICAgcmV0dXJuIHV0aWwuQnVmZmVyXG4gICAgICAgID8gZnVuY3Rpb24gY3JlYXRlX2J1ZmZlcl9zZXR1cCgpIHtcbiAgICAgICAgICAgIHJldHVybiAoV3JpdGVyLmNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZV9idWZmZXIoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBCdWZmZXJXcml0ZXIoKTtcbiAgICAgICAgICAgIH0pKCk7XG4gICAgICAgIH1cbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgICAgOiBmdW5jdGlvbiBjcmVhdGVfYXJyYXkoKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFdyaXRlcigpO1xuICAgICAgICB9O1xufTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IHdyaXRlci5cbiAqIEBmdW5jdGlvblxuICogQHJldHVybnMge0J1ZmZlcldyaXRlcnxXcml0ZXJ9IEEge0BsaW5rIEJ1ZmZlcldyaXRlcn0gd2hlbiBCdWZmZXJzIGFyZSBzdXBwb3J0ZWQsIG90aGVyd2lzZSBhIHtAbGluayBXcml0ZXJ9XG4gKi9cbldyaXRlci5jcmVhdGUgPSBjcmVhdGUoKTtcblxuLyoqXG4gKiBBbGxvY2F0ZXMgYSBidWZmZXIgb2YgdGhlIHNwZWNpZmllZCBzaXplLlxuICogQHBhcmFtIHtudW1iZXJ9IHNpemUgQnVmZmVyIHNpemVcbiAqIEByZXR1cm5zIHtVaW50OEFycmF5fSBCdWZmZXJcbiAqL1xuV3JpdGVyLmFsbG9jID0gZnVuY3Rpb24gYWxsb2Moc2l6ZSkge1xuICAgIHJldHVybiBuZXcgdXRpbC5BcnJheShzaXplKTtcbn07XG5cbi8vIFVzZSBVaW50OEFycmF5IGJ1ZmZlciBwb29sIGluIHRoZSBicm93c2VyLCBqdXN0IGxpa2Ugbm9kZSBkb2VzIHdpdGggYnVmZmVyc1xuLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbmlmICh1dGlsLkFycmF5ICE9PSBBcnJheSlcbiAgICBXcml0ZXIuYWxsb2MgPSB1dGlsLnBvb2woV3JpdGVyLmFsbG9jLCB1dGlsLkFycmF5LnByb3RvdHlwZS5zdWJhcnJheSk7XG5cbi8qKlxuICogUHVzaGVzIGEgbmV3IG9wZXJhdGlvbiB0byB0aGUgcXVldWUuXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKFVpbnQ4QXJyYXksIG51bWJlciwgKil9IGZuIEZ1bmN0aW9uIHRvIGNhbGxcbiAqIEBwYXJhbSB7bnVtYmVyfSBsZW4gVmFsdWUgYnl0ZSBsZW5ndGhcbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWwgVmFsdWUgdG8gd3JpdGVcbiAqIEByZXR1cm5zIHtXcml0ZXJ9IGB0aGlzYFxuICogQHByaXZhdGVcbiAqL1xuV3JpdGVyLnByb3RvdHlwZS5fcHVzaCA9IGZ1bmN0aW9uIHB1c2goZm4sIGxlbiwgdmFsKSB7XG4gICAgdGhpcy50YWlsID0gdGhpcy50YWlsLm5leHQgPSBuZXcgT3AoZm4sIGxlbiwgdmFsKTtcbiAgICB0aGlzLmxlbiArPSBsZW47XG4gICAgcmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiB3cml0ZUJ5dGUodmFsLCBidWYsIHBvcykge1xuICAgIGJ1Zltwb3NdID0gdmFsICYgMjU1O1xufVxuXG5mdW5jdGlvbiB3cml0ZVZhcmludDMyKHZhbCwgYnVmLCBwb3MpIHtcbiAgICB3aGlsZSAodmFsID4gMTI3KSB7XG4gICAgICAgIGJ1Zltwb3MrK10gPSB2YWwgJiAxMjcgfCAxMjg7XG4gICAgICAgIHZhbCA+Pj49IDc7XG4gICAgfVxuICAgIGJ1Zltwb3NdID0gdmFsO1xufVxuXG4vKipcbiAqIENvbnN0cnVjdHMgYSBuZXcgdmFyaW50IHdyaXRlciBvcGVyYXRpb24gaW5zdGFuY2UuXG4gKiBAY2xhc3NkZXNjIFNjaGVkdWxlZCB2YXJpbnQgd3JpdGVyIG9wZXJhdGlvbi5cbiAqIEBleHRlbmRzIE9wXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7bnVtYmVyfSBsZW4gVmFsdWUgYnl0ZSBsZW5ndGhcbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWwgVmFsdWUgdG8gd3JpdGVcbiAqIEBpZ25vcmVcbiAqL1xuZnVuY3Rpb24gVmFyaW50T3AobGVuLCB2YWwpIHtcbiAgICB0aGlzLmxlbiA9IGxlbjtcbiAgICB0aGlzLm5leHQgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy52YWwgPSB2YWw7XG59XG5cblZhcmludE9wLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoT3AucHJvdG90eXBlKTtcblZhcmludE9wLnByb3RvdHlwZS5mbiA9IHdyaXRlVmFyaW50MzI7XG5cbi8qKlxuICogV3JpdGVzIGFuIHVuc2lnbmVkIDMyIGJpdCB2YWx1ZSBhcyBhIHZhcmludC5cbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxuICogQHJldHVybnMge1dyaXRlcn0gYHRoaXNgXG4gKi9cbldyaXRlci5wcm90b3R5cGUudWludDMyID0gZnVuY3Rpb24gd3JpdGVfdWludDMyKHZhbHVlKSB7XG4gICAgLy8gaGVyZSwgdGhlIGNhbGwgdG8gdGhpcy5wdXNoIGhhcyBiZWVuIGlubGluZWQgYW5kIGEgdmFyaW50IHNwZWNpZmljIE9wIHN1YmNsYXNzIGlzIHVzZWQuXG4gICAgLy8gdWludDMyIGlzIGJ5IGZhciB0aGUgbW9zdCBmcmVxdWVudGx5IHVzZWQgb3BlcmF0aW9uIGFuZCBiZW5lZml0cyBzaWduaWZpY2FudGx5IGZyb20gdGhpcy5cbiAgICB0aGlzLmxlbiArPSAodGhpcy50YWlsID0gdGhpcy50YWlsLm5leHQgPSBuZXcgVmFyaW50T3AoXG4gICAgICAgICh2YWx1ZSA9IHZhbHVlID4+PiAwKVxuICAgICAgICAgICAgICAgIDwgMTI4ICAgICAgID8gMVxuICAgICAgICA6IHZhbHVlIDwgMTYzODQgICAgID8gMlxuICAgICAgICA6IHZhbHVlIDwgMjA5NzE1MiAgID8gM1xuICAgICAgICA6IHZhbHVlIDwgMjY4NDM1NDU2ID8gNFxuICAgICAgICA6ICAgICAgICAgICAgICAgICAgICAgNSxcbiAgICB2YWx1ZSkpLmxlbjtcbiAgICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogV3JpdGVzIGEgc2lnbmVkIDMyIGJpdCB2YWx1ZSBhcyBhIHZhcmludC5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXG4gKiBAcmV0dXJucyB7V3JpdGVyfSBgdGhpc2BcbiAqL1xuV3JpdGVyLnByb3RvdHlwZS5pbnQzMiA9IGZ1bmN0aW9uIHdyaXRlX2ludDMyKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlIDwgMFxuICAgICAgICA/IHRoaXMuX3B1c2god3JpdGVWYXJpbnQ2NCwgMTAsIExvbmdCaXRzLmZyb21OdW1iZXIodmFsdWUpKSAvLyAxMCBieXRlcyBwZXIgc3BlY1xuICAgICAgICA6IHRoaXMudWludDMyKHZhbHVlKTtcbn07XG5cbi8qKlxuICogV3JpdGVzIGEgMzIgYml0IHZhbHVlIGFzIGEgdmFyaW50LCB6aWctemFnIGVuY29kZWQuXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVmFsdWUgdG8gd3JpdGVcbiAqIEByZXR1cm5zIHtXcml0ZXJ9IGB0aGlzYFxuICovXG5Xcml0ZXIucHJvdG90eXBlLnNpbnQzMiA9IGZ1bmN0aW9uIHdyaXRlX3NpbnQzMih2YWx1ZSkge1xuICAgIHJldHVybiB0aGlzLnVpbnQzMigodmFsdWUgPDwgMSBeIHZhbHVlID4+IDMxKSA+Pj4gMCk7XG59O1xuXG5mdW5jdGlvbiB3cml0ZVZhcmludDY0KHZhbCwgYnVmLCBwb3MpIHtcbiAgICB3aGlsZSAodmFsLmhpKSB7XG4gICAgICAgIGJ1Zltwb3MrK10gPSB2YWwubG8gJiAxMjcgfCAxMjg7XG4gICAgICAgIHZhbC5sbyA9ICh2YWwubG8gPj4+IDcgfCB2YWwuaGkgPDwgMjUpID4+PiAwO1xuICAgICAgICB2YWwuaGkgPj4+PSA3O1xuICAgIH1cbiAgICB3aGlsZSAodmFsLmxvID4gMTI3KSB7XG4gICAgICAgIGJ1Zltwb3MrK10gPSB2YWwubG8gJiAxMjcgfCAxMjg7XG4gICAgICAgIHZhbC5sbyA9IHZhbC5sbyA+Pj4gNztcbiAgICB9XG4gICAgYnVmW3BvcysrXSA9IHZhbC5sbztcbn1cblxuLyoqXG4gKiBXcml0ZXMgYW4gdW5zaWduZWQgNjQgYml0IHZhbHVlIGFzIGEgdmFyaW50LlxuICogQHBhcmFtIHtMb25nfG51bWJlcnxzdHJpbmd9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXG4gKiBAcmV0dXJucyB7V3JpdGVyfSBgdGhpc2BcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gSWYgYHZhbHVlYCBpcyBhIHN0cmluZyBhbmQgbm8gbG9uZyBsaWJyYXJ5IGlzIHByZXNlbnQuXG4gKi9cbldyaXRlci5wcm90b3R5cGUudWludDY0ID0gZnVuY3Rpb24gd3JpdGVfdWludDY0KHZhbHVlKSB7XG4gICAgdmFyIGJpdHMgPSBMb25nQml0cy5mcm9tKHZhbHVlKTtcbiAgICByZXR1cm4gdGhpcy5fcHVzaCh3cml0ZVZhcmludDY0LCBiaXRzLmxlbmd0aCgpLCBiaXRzKTtcbn07XG5cbi8qKlxuICogV3JpdGVzIGEgc2lnbmVkIDY0IGJpdCB2YWx1ZSBhcyBhIHZhcmludC5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtMb25nfG51bWJlcnxzdHJpbmd9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXG4gKiBAcmV0dXJucyB7V3JpdGVyfSBgdGhpc2BcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gSWYgYHZhbHVlYCBpcyBhIHN0cmluZyBhbmQgbm8gbG9uZyBsaWJyYXJ5IGlzIHByZXNlbnQuXG4gKi9cbldyaXRlci5wcm90b3R5cGUuaW50NjQgPSBXcml0ZXIucHJvdG90eXBlLnVpbnQ2NDtcblxuLyoqXG4gKiBXcml0ZXMgYSBzaWduZWQgNjQgYml0IHZhbHVlIGFzIGEgdmFyaW50LCB6aWctemFnIGVuY29kZWQuXG4gKiBAcGFyYW0ge0xvbmd8bnVtYmVyfHN0cmluZ30gdmFsdWUgVmFsdWUgdG8gd3JpdGVcbiAqIEByZXR1cm5zIHtXcml0ZXJ9IGB0aGlzYFxuICogQHRocm93cyB7VHlwZUVycm9yfSBJZiBgdmFsdWVgIGlzIGEgc3RyaW5nIGFuZCBubyBsb25nIGxpYnJhcnkgaXMgcHJlc2VudC5cbiAqL1xuV3JpdGVyLnByb3RvdHlwZS5zaW50NjQgPSBmdW5jdGlvbiB3cml0ZV9zaW50NjQodmFsdWUpIHtcbiAgICB2YXIgYml0cyA9IExvbmdCaXRzLmZyb20odmFsdWUpLnp6RW5jb2RlKCk7XG4gICAgcmV0dXJuIHRoaXMuX3B1c2god3JpdGVWYXJpbnQ2NCwgYml0cy5sZW5ndGgoKSwgYml0cyk7XG59O1xuXG4vKipcbiAqIFdyaXRlcyBhIGJvb2xpc2ggdmFsdWUgYXMgYSB2YXJpbnQuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IHZhbHVlIFZhbHVlIHRvIHdyaXRlXG4gKiBAcmV0dXJucyB7V3JpdGVyfSBgdGhpc2BcbiAqL1xuV3JpdGVyLnByb3RvdHlwZS5ib29sID0gZnVuY3Rpb24gd3JpdGVfYm9vbCh2YWx1ZSkge1xuICAgIHJldHVybiB0aGlzLl9wdXNoKHdyaXRlQnl0ZSwgMSwgdmFsdWUgPyAxIDogMCk7XG59O1xuXG5mdW5jdGlvbiB3cml0ZUZpeGVkMzIodmFsLCBidWYsIHBvcykge1xuICAgIGJ1Zltwb3MgICAgXSA9ICB2YWwgICAgICAgICAmIDI1NTtcbiAgICBidWZbcG9zICsgMV0gPSAgdmFsID4+PiA4ICAgJiAyNTU7XG4gICAgYnVmW3BvcyArIDJdID0gIHZhbCA+Pj4gMTYgICYgMjU1O1xuICAgIGJ1Zltwb3MgKyAzXSA9ICB2YWwgPj4+IDI0O1xufVxuXG4vKipcbiAqIFdyaXRlcyBhbiB1bnNpZ25lZCAzMiBiaXQgdmFsdWUgYXMgZml4ZWQgMzIgYml0cy5cbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxuICogQHJldHVybnMge1dyaXRlcn0gYHRoaXNgXG4gKi9cbldyaXRlci5wcm90b3R5cGUuZml4ZWQzMiA9IGZ1bmN0aW9uIHdyaXRlX2ZpeGVkMzIodmFsdWUpIHtcbiAgICByZXR1cm4gdGhpcy5fcHVzaCh3cml0ZUZpeGVkMzIsIDQsIHZhbHVlID4+PiAwKTtcbn07XG5cbi8qKlxuICogV3JpdGVzIGEgc2lnbmVkIDMyIGJpdCB2YWx1ZSBhcyBmaXhlZCAzMiBiaXRzLlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWUgVmFsdWUgdG8gd3JpdGVcbiAqIEByZXR1cm5zIHtXcml0ZXJ9IGB0aGlzYFxuICovXG5Xcml0ZXIucHJvdG90eXBlLnNmaXhlZDMyID0gV3JpdGVyLnByb3RvdHlwZS5maXhlZDMyO1xuXG4vKipcbiAqIFdyaXRlcyBhbiB1bnNpZ25lZCA2NCBiaXQgdmFsdWUgYXMgZml4ZWQgNjQgYml0cy5cbiAqIEBwYXJhbSB7TG9uZ3xudW1iZXJ8c3RyaW5nfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxuICogQHJldHVybnMge1dyaXRlcn0gYHRoaXNgXG4gKiBAdGhyb3dzIHtUeXBlRXJyb3J9IElmIGB2YWx1ZWAgaXMgYSBzdHJpbmcgYW5kIG5vIGxvbmcgbGlicmFyeSBpcyBwcmVzZW50LlxuICovXG5Xcml0ZXIucHJvdG90eXBlLmZpeGVkNjQgPSBmdW5jdGlvbiB3cml0ZV9maXhlZDY0KHZhbHVlKSB7XG4gICAgdmFyIGJpdHMgPSBMb25nQml0cy5mcm9tKHZhbHVlKTtcbiAgICByZXR1cm4gdGhpcy5fcHVzaCh3cml0ZUZpeGVkMzIsIDQsIGJpdHMubG8pLl9wdXNoKHdyaXRlRml4ZWQzMiwgNCwgYml0cy5oaSk7XG59O1xuXG4vKipcbiAqIFdyaXRlcyBhIHNpZ25lZCA2NCBiaXQgdmFsdWUgYXMgZml4ZWQgNjQgYml0cy5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtMb25nfG51bWJlcnxzdHJpbmd9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXG4gKiBAcmV0dXJucyB7V3JpdGVyfSBgdGhpc2BcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gSWYgYHZhbHVlYCBpcyBhIHN0cmluZyBhbmQgbm8gbG9uZyBsaWJyYXJ5IGlzIHByZXNlbnQuXG4gKi9cbldyaXRlci5wcm90b3R5cGUuc2ZpeGVkNjQgPSBXcml0ZXIucHJvdG90eXBlLmZpeGVkNjQ7XG5cbi8qKlxuICogV3JpdGVzIGEgZmxvYXQgKDMyIGJpdCkuXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBWYWx1ZSB0byB3cml0ZVxuICogQHJldHVybnMge1dyaXRlcn0gYHRoaXNgXG4gKi9cbldyaXRlci5wcm90b3R5cGUuZmxvYXQgPSBmdW5jdGlvbiB3cml0ZV9mbG9hdCh2YWx1ZSkge1xuICAgIHJldHVybiB0aGlzLl9wdXNoKHV0aWwuZmxvYXQud3JpdGVGbG9hdExFLCA0LCB2YWx1ZSk7XG59O1xuXG4vKipcbiAqIFdyaXRlcyBhIGRvdWJsZSAoNjQgYml0IGZsb2F0KS5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFZhbHVlIHRvIHdyaXRlXG4gKiBAcmV0dXJucyB7V3JpdGVyfSBgdGhpc2BcbiAqL1xuV3JpdGVyLnByb3RvdHlwZS5kb3VibGUgPSBmdW5jdGlvbiB3cml0ZV9kb3VibGUodmFsdWUpIHtcbiAgICByZXR1cm4gdGhpcy5fcHVzaCh1dGlsLmZsb2F0LndyaXRlRG91YmxlTEUsIDgsIHZhbHVlKTtcbn07XG5cbnZhciB3cml0ZUJ5dGVzID0gdXRpbC5BcnJheS5wcm90b3R5cGUuc2V0XG4gICAgPyBmdW5jdGlvbiB3cml0ZUJ5dGVzX3NldCh2YWwsIGJ1ZiwgcG9zKSB7XG4gICAgICAgIGJ1Zi5zZXQodmFsLCBwb3MpOyAvLyBhbHNvIHdvcmtzIGZvciBwbGFpbiBhcnJheSB2YWx1ZXNcbiAgICB9XG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICA6IGZ1bmN0aW9uIHdyaXRlQnl0ZXNfZm9yKHZhbCwgYnVmLCBwb3MpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB2YWwubGVuZ3RoOyArK2kpXG4gICAgICAgICAgICBidWZbcG9zICsgaV0gPSB2YWxbaV07XG4gICAgfTtcblxuLyoqXG4gKiBXcml0ZXMgYSBzZXF1ZW5jZSBvZiBieXRlcy5cbiAqIEBwYXJhbSB7VWludDhBcnJheXxzdHJpbmd9IHZhbHVlIEJ1ZmZlciBvciBiYXNlNjQgZW5jb2RlZCBzdHJpbmcgdG8gd3JpdGVcbiAqIEByZXR1cm5zIHtXcml0ZXJ9IGB0aGlzYFxuICovXG5Xcml0ZXIucHJvdG90eXBlLmJ5dGVzID0gZnVuY3Rpb24gd3JpdGVfYnl0ZXModmFsdWUpIHtcbiAgICB2YXIgbGVuID0gdmFsdWUubGVuZ3RoID4+PiAwO1xuICAgIGlmICghbGVuKVxuICAgICAgICByZXR1cm4gdGhpcy5fcHVzaCh3cml0ZUJ5dGUsIDEsIDApO1xuICAgIGlmICh1dGlsLmlzU3RyaW5nKHZhbHVlKSkge1xuICAgICAgICB2YXIgYnVmID0gV3JpdGVyLmFsbG9jKGxlbiA9IGJhc2U2NC5sZW5ndGgodmFsdWUpKTtcbiAgICAgICAgYmFzZTY0LmRlY29kZSh2YWx1ZSwgYnVmLCAwKTtcbiAgICAgICAgdmFsdWUgPSBidWY7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnVpbnQzMihsZW4pLl9wdXNoKHdyaXRlQnl0ZXMsIGxlbiwgdmFsdWUpO1xufTtcblxuLyoqXG4gKiBXcml0ZXMgYSBzdHJpbmcuXG4gKiBAcGFyYW0ge3N0cmluZ30gdmFsdWUgVmFsdWUgdG8gd3JpdGVcbiAqIEByZXR1cm5zIHtXcml0ZXJ9IGB0aGlzYFxuICovXG5Xcml0ZXIucHJvdG90eXBlLnN0cmluZyA9IGZ1bmN0aW9uIHdyaXRlX3N0cmluZyh2YWx1ZSkge1xuICAgIHZhciBsZW4gPSB1dGY4Lmxlbmd0aCh2YWx1ZSk7XG4gICAgcmV0dXJuIGxlblxuICAgICAgICA/IHRoaXMudWludDMyKGxlbikuX3B1c2godXRmOC53cml0ZSwgbGVuLCB2YWx1ZSlcbiAgICAgICAgOiB0aGlzLl9wdXNoKHdyaXRlQnl0ZSwgMSwgMCk7XG59O1xuXG4vKipcbiAqIEZvcmtzIHRoaXMgd3JpdGVyJ3Mgc3RhdGUgYnkgcHVzaGluZyBpdCB0byBhIHN0YWNrLlxuICogQ2FsbGluZyB7QGxpbmsgV3JpdGVyI3Jlc2V0fHJlc2V0fSBvciB7QGxpbmsgV3JpdGVyI2xkZWxpbXxsZGVsaW19IHJlc2V0cyB0aGUgd3JpdGVyIHRvIHRoZSBwcmV2aW91cyBzdGF0ZS5cbiAqIEByZXR1cm5zIHtXcml0ZXJ9IGB0aGlzYFxuICovXG5Xcml0ZXIucHJvdG90eXBlLmZvcmsgPSBmdW5jdGlvbiBmb3JrKCkge1xuICAgIHRoaXMuc3RhdGVzID0gbmV3IFN0YXRlKHRoaXMpO1xuICAgIHRoaXMuaGVhZCA9IHRoaXMudGFpbCA9IG5ldyBPcChub29wLCAwLCAwKTtcbiAgICB0aGlzLmxlbiA9IDA7XG4gICAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFJlc2V0cyB0aGlzIGluc3RhbmNlIHRvIHRoZSBsYXN0IHN0YXRlLlxuICogQHJldHVybnMge1dyaXRlcn0gYHRoaXNgXG4gKi9cbldyaXRlci5wcm90b3R5cGUucmVzZXQgPSBmdW5jdGlvbiByZXNldCgpIHtcbiAgICBpZiAodGhpcy5zdGF0ZXMpIHtcbiAgICAgICAgdGhpcy5oZWFkICAgPSB0aGlzLnN0YXRlcy5oZWFkO1xuICAgICAgICB0aGlzLnRhaWwgICA9IHRoaXMuc3RhdGVzLnRhaWw7XG4gICAgICAgIHRoaXMubGVuICAgID0gdGhpcy5zdGF0ZXMubGVuO1xuICAgICAgICB0aGlzLnN0YXRlcyA9IHRoaXMuc3RhdGVzLm5leHQ7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5oZWFkID0gdGhpcy50YWlsID0gbmV3IE9wKG5vb3AsIDAsIDApO1xuICAgICAgICB0aGlzLmxlbiAgPSAwO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogUmVzZXRzIHRvIHRoZSBsYXN0IHN0YXRlIGFuZCBhcHBlbmRzIHRoZSBmb3JrIHN0YXRlJ3MgY3VycmVudCB3cml0ZSBsZW5ndGggYXMgYSB2YXJpbnQgZm9sbG93ZWQgYnkgaXRzIG9wZXJhdGlvbnMuXG4gKiBAcmV0dXJucyB7V3JpdGVyfSBgdGhpc2BcbiAqL1xuV3JpdGVyLnByb3RvdHlwZS5sZGVsaW0gPSBmdW5jdGlvbiBsZGVsaW0oKSB7XG4gICAgdmFyIGhlYWQgPSB0aGlzLmhlYWQsXG4gICAgICAgIHRhaWwgPSB0aGlzLnRhaWwsXG4gICAgICAgIGxlbiAgPSB0aGlzLmxlbjtcbiAgICB0aGlzLnJlc2V0KCkudWludDMyKGxlbik7XG4gICAgaWYgKGxlbikge1xuICAgICAgICB0aGlzLnRhaWwubmV4dCA9IGhlYWQubmV4dDsgLy8gc2tpcCBub29wXG4gICAgICAgIHRoaXMudGFpbCA9IHRhaWw7XG4gICAgICAgIHRoaXMubGVuICs9IGxlbjtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIEZpbmlzaGVzIHRoZSB3cml0ZSBvcGVyYXRpb24uXG4gKiBAcmV0dXJucyB7VWludDhBcnJheX0gRmluaXNoZWQgYnVmZmVyXG4gKi9cbldyaXRlci5wcm90b3R5cGUuZmluaXNoID0gZnVuY3Rpb24gZmluaXNoKCkge1xuICAgIHZhciBoZWFkID0gdGhpcy5oZWFkLm5leHQsIC8vIHNraXAgbm9vcFxuICAgICAgICBidWYgID0gdGhpcy5jb25zdHJ1Y3Rvci5hbGxvYyh0aGlzLmxlbiksXG4gICAgICAgIHBvcyAgPSAwO1xuICAgIHdoaWxlIChoZWFkKSB7XG4gICAgICAgIGhlYWQuZm4oaGVhZC52YWwsIGJ1ZiwgcG9zKTtcbiAgICAgICAgcG9zICs9IGhlYWQubGVuO1xuICAgICAgICBoZWFkID0gaGVhZC5uZXh0O1xuICAgIH1cbiAgICAvLyB0aGlzLmhlYWQgPSB0aGlzLnRhaWwgPSBudWxsO1xuICAgIHJldHVybiBidWY7XG59O1xuXG5Xcml0ZXIuX2NvbmZpZ3VyZSA9IGZ1bmN0aW9uKEJ1ZmZlcldyaXRlcl8pIHtcbiAgICBCdWZmZXJXcml0ZXIgPSBCdWZmZXJXcml0ZXJfO1xuICAgIFdyaXRlci5jcmVhdGUgPSBjcmVhdGUoKTtcbiAgICBCdWZmZXJXcml0ZXIuX2NvbmZpZ3VyZSgpO1xufTtcbiIsIlwidXNlIHN0cmljdFwiO1xubW9kdWxlLmV4cG9ydHMgPSBCdWZmZXJXcml0ZXI7XG5cbi8vIGV4dGVuZHMgV3JpdGVyXG52YXIgV3JpdGVyID0gcmVxdWlyZShcIi4vd3JpdGVyXCIpO1xuKEJ1ZmZlcldyaXRlci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKFdyaXRlci5wcm90b3R5cGUpKS5jb25zdHJ1Y3RvciA9IEJ1ZmZlcldyaXRlcjtcblxudmFyIHV0aWwgPSByZXF1aXJlKFwiLi91dGlsL21pbmltYWxcIik7XG5cbi8qKlxuICogQ29uc3RydWN0cyBhIG5ldyBidWZmZXIgd3JpdGVyIGluc3RhbmNlLlxuICogQGNsYXNzZGVzYyBXaXJlIGZvcm1hdCB3cml0ZXIgdXNpbmcgbm9kZSBidWZmZXJzLlxuICogQGV4dGVuZHMgV3JpdGVyXG4gKiBAY29uc3RydWN0b3JcbiAqL1xuZnVuY3Rpb24gQnVmZmVyV3JpdGVyKCkge1xuICAgIFdyaXRlci5jYWxsKHRoaXMpO1xufVxuXG5CdWZmZXJXcml0ZXIuX2NvbmZpZ3VyZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAvKipcbiAgICAgKiBBbGxvY2F0ZXMgYSBidWZmZXIgb2YgdGhlIHNwZWNpZmllZCBzaXplLlxuICAgICAqIEBmdW5jdGlvblxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBzaXplIEJ1ZmZlciBzaXplXG4gICAgICogQHJldHVybnMge0J1ZmZlcn0gQnVmZmVyXG4gICAgICovXG4gICAgQnVmZmVyV3JpdGVyLmFsbG9jID0gdXRpbC5fQnVmZmVyX2FsbG9jVW5zYWZlO1xuXG4gICAgQnVmZmVyV3JpdGVyLndyaXRlQnl0ZXNCdWZmZXIgPSB1dGlsLkJ1ZmZlciAmJiB1dGlsLkJ1ZmZlci5wcm90b3R5cGUgaW5zdGFuY2VvZiBVaW50OEFycmF5ICYmIHV0aWwuQnVmZmVyLnByb3RvdHlwZS5zZXQubmFtZSA9PT0gXCJzZXRcIlxuICAgICAgICA/IGZ1bmN0aW9uIHdyaXRlQnl0ZXNCdWZmZXJfc2V0KHZhbCwgYnVmLCBwb3MpIHtcbiAgICAgICAgICBidWYuc2V0KHZhbCwgcG9zKTsgLy8gZmFzdGVyIHRoYW4gY29weSAocmVxdWlyZXMgbm9kZSA+PSA0IHdoZXJlIEJ1ZmZlcnMgZXh0ZW5kIFVpbnQ4QXJyYXkgYW5kIHNldCBpcyBwcm9wZXJseSBpbmhlcml0ZWQpXG4gICAgICAgICAgLy8gYWxzbyB3b3JrcyBmb3IgcGxhaW4gYXJyYXkgdmFsdWVzXG4gICAgICAgIH1cbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgICAgOiBmdW5jdGlvbiB3cml0ZUJ5dGVzQnVmZmVyX2NvcHkodmFsLCBidWYsIHBvcykge1xuICAgICAgICAgIGlmICh2YWwuY29weSkgLy8gQnVmZmVyIHZhbHVlc1xuICAgICAgICAgICAgdmFsLmNvcHkoYnVmLCBwb3MsIDAsIHZhbC5sZW5ndGgpO1xuICAgICAgICAgIGVsc2UgZm9yICh2YXIgaSA9IDA7IGkgPCB2YWwubGVuZ3RoOykgLy8gcGxhaW4gYXJyYXkgdmFsdWVzXG4gICAgICAgICAgICBidWZbcG9zKytdID0gdmFsW2krK107XG4gICAgICAgIH07XG59O1xuXG5cbi8qKlxuICogQG92ZXJyaWRlXG4gKi9cbkJ1ZmZlcldyaXRlci5wcm90b3R5cGUuYnl0ZXMgPSBmdW5jdGlvbiB3cml0ZV9ieXRlc19idWZmZXIodmFsdWUpIHtcbiAgICBpZiAodXRpbC5pc1N0cmluZyh2YWx1ZSkpXG4gICAgICAgIHZhbHVlID0gdXRpbC5fQnVmZmVyX2Zyb20odmFsdWUsIFwiYmFzZTY0XCIpO1xuICAgIHZhciBsZW4gPSB2YWx1ZS5sZW5ndGggPj4+IDA7XG4gICAgdGhpcy51aW50MzIobGVuKTtcbiAgICBpZiAobGVuKVxuICAgICAgICB0aGlzLl9wdXNoKEJ1ZmZlcldyaXRlci53cml0ZUJ5dGVzQnVmZmVyLCBsZW4sIHZhbHVlKTtcbiAgICByZXR1cm4gdGhpcztcbn07XG5cbmZ1bmN0aW9uIHdyaXRlU3RyaW5nQnVmZmVyKHZhbCwgYnVmLCBwb3MpIHtcbiAgICBpZiAodmFsLmxlbmd0aCA8IDQwKSAvLyBwbGFpbiBqcyBpcyBmYXN0ZXIgZm9yIHNob3J0IHN0cmluZ3MgKHByb2JhYmx5IGR1ZSB0byByZWR1bmRhbnQgYXNzZXJ0aW9ucylcbiAgICAgICAgdXRpbC51dGY4LndyaXRlKHZhbCwgYnVmLCBwb3MpO1xuICAgIGVsc2UgaWYgKGJ1Zi51dGY4V3JpdGUpXG4gICAgICAgIGJ1Zi51dGY4V3JpdGUodmFsLCBwb3MpO1xuICAgIGVsc2VcbiAgICAgICAgYnVmLndyaXRlKHZhbCwgcG9zKTtcbn1cblxuLyoqXG4gKiBAb3ZlcnJpZGVcbiAqL1xuQnVmZmVyV3JpdGVyLnByb3RvdHlwZS5zdHJpbmcgPSBmdW5jdGlvbiB3cml0ZV9zdHJpbmdfYnVmZmVyKHZhbHVlKSB7XG4gICAgdmFyIGxlbiA9IHV0aWwuQnVmZmVyLmJ5dGVMZW5ndGgodmFsdWUpO1xuICAgIHRoaXMudWludDMyKGxlbik7XG4gICAgaWYgKGxlbilcbiAgICAgICAgdGhpcy5fcHVzaCh3cml0ZVN0cmluZ0J1ZmZlciwgbGVuLCB2YWx1ZSk7XG4gICAgcmV0dXJuIHRoaXM7XG59O1xuXG5cbi8qKlxuICogRmluaXNoZXMgdGhlIHdyaXRlIG9wZXJhdGlvbi5cbiAqIEBuYW1lIEJ1ZmZlcldyaXRlciNmaW5pc2hcbiAqIEBmdW5jdGlvblxuICogQHJldHVybnMge0J1ZmZlcn0gRmluaXNoZWQgYnVmZmVyXG4gKi9cblxuQnVmZmVyV3JpdGVyLl9jb25maWd1cmUoKTtcbiIsIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG4vKiBlc2xpbnQtZGlzYWJsZSBpbXBvcnQvbm8taW50ZXJuYWwtbW9kdWxlcyAqL1xuaW1wb3J0IHtCYWNrZW5kLCBJbmZlcmVuY2VTZXNzaW9uLCBTZXNzaW9uSGFuZGxlcn0gZnJvbSAnb25ueHJ1bnRpbWUtY29tbW9uJztcblxuaW1wb3J0IHtTZXNzaW9ufSBmcm9tICcuL29ubnhqcy9zZXNzaW9uJztcbmltcG9ydCB7T25ueGpzU2Vzc2lvbkhhbmRsZXJ9IGZyb20gJy4vb25ueGpzL3Nlc3Npb24taGFuZGxlcic7XG5cbmNsYXNzIE9ubnhqc0JhY2tlbmQgaW1wbGVtZW50cyBCYWNrZW5kIHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1lbXB0eS1mdW5jdGlvblxuICBhc3luYyBpbml0KCk6IFByb21pc2U8dm9pZD4ge31cblxuICBhc3luYyBjcmVhdGVTZXNzaW9uSGFuZGxlcihwYXRoT3JCdWZmZXI6IHN0cmluZ3xVaW50OEFycmF5LCBvcHRpb25zPzogSW5mZXJlbmNlU2Vzc2lvbi5TZXNzaW9uT3B0aW9ucyk6XG4gICAgICBQcm9taXNlPFNlc3Npb25IYW5kbGVyPiB7XG4gICAgLy8gTk9URTogU2Vzc2lvbi5Db25maWcoZnJvbSBvbm54LmpzKSBpcyBub3QgY29tcGF0aWJsZSB3aXRoIEluZmVyZW5jZVNlc3Npb24uU2Vzc2lvbk9wdGlvbnMoZnJvbVxuICAgIC8vIG9ubnhydW50aW1lLWNvbW1vbikuXG4gICAgLy8gICAgICAgSW4gZnV0dXJlIHdlIHNob3VsZCByZW1vdmUgU2Vzc2lvbi5Db25maWcgYW5kIHVzZSBJbmZlcmVuY2VTZXNzaW9uLlNlc3Npb25PcHRpb25zLlxuICAgIC8vICAgICAgIEN1cnJlbnRseSB3ZSBhbGxvdyB0aGlzIHRvIGhhcHBlbiB0byBtYWtlIHRlc3QgcnVubmVyIHdvcmsuXG4gICAgY29uc3Qgc2Vzc2lvbiA9IG5ldyBTZXNzaW9uKG9wdGlvbnMgYXMgdW5rbm93biBhcyBTZXNzaW9uLkNvbmZpZyk7XG5cbiAgICAvLyB0eXBlc2NyaXB0IGNhbm5vdCBtZXJnZSBtZXRob2Qgb3ZlcnJpZGUgY29ycmVjdGx5IChzbyBmYXIgaW4gNC4yLjMpLiBuZWVkIGlmLWVsc2UgdG8gY2FsbCB0aGUgbWV0aG9kLlxuICAgIGlmICh0eXBlb2YgcGF0aE9yQnVmZmVyID09PSAnc3RyaW5nJykge1xuICAgICAgYXdhaXQgc2Vzc2lvbi5sb2FkTW9kZWwocGF0aE9yQnVmZmVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYXdhaXQgc2Vzc2lvbi5sb2FkTW9kZWwocGF0aE9yQnVmZmVyKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IE9ubnhqc1Nlc3Npb25IYW5kbGVyKHNlc3Npb24pO1xuICB9XG59XG5cbmV4cG9ydCBjb25zdCBvbm54anNCYWNrZW5kID0gbmV3IE9ubnhqc0JhY2tlbmQoKTtcbiIsIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge0JhY2tlbmQsIGVudiwgSW5mZXJlbmNlU2Vzc2lvbiwgU2Vzc2lvbkhhbmRsZXJ9IGZyb20gJ29ubnhydW50aW1lLWNvbW1vbic7XG5pbXBvcnQge2NwdXN9IGZyb20gJ29zJztcblxuaW1wb3J0IHtpbml0V2FzbX0gZnJvbSAnLi93YXNtL3Byb3h5LXdyYXBwZXInO1xuaW1wb3J0IHtPbm54cnVudGltZVdlYkFzc2VtYmx5U2Vzc2lvbkhhbmRsZXJ9IGZyb20gJy4vd2FzbS9zZXNzaW9uLWhhbmRsZXInO1xuXG4vKipcbiAqIFRoaXMgZnVuY3Rpb24gaW5pdGlhbGl6ZXMgYWxsIGZsYWdzIGZvciBXZWJBc3NlbWJseS5cbiAqXG4gKiBUaG9zZSBmbGFncyBhcmUgYWNjZXNzaWJsZSBmcm9tIGBvcnQuZW52Lndhc21gLiBVc2VycyBhcmUgYWxsb3cgdG8gc2V0IHRob3NlIGZsYWdzIGJlZm9yZSB0aGUgZmlyc3QgaW5mZXJlbmNlIHNlc3Npb25cbiAqIGJlaW5nIGNyZWF0ZWQsIHRvIG92ZXJyaWRlIGRlZmF1bHQgdmFsdWUuXG4gKi9cbmV4cG9ydCBjb25zdCBpbml0aWFsaXplRmxhZ3MgPSAoKTogdm9pZCA9PiB7XG4gIGlmICh0eXBlb2YgZW52Lndhc20uaW5pdFRpbWVvdXQgIT09ICdudW1iZXInIHx8IGVudi53YXNtLmluaXRUaW1lb3V0IDwgMCkge1xuICAgIGVudi53YXNtLmluaXRUaW1lb3V0ID0gMDtcbiAgfVxuXG4gIGlmICh0eXBlb2YgZW52Lndhc20uc2ltZCAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgZW52Lndhc20uc2ltZCA9IHRydWU7XG4gIH1cblxuICBpZiAodHlwZW9mIGVudi53YXNtLnByb3h5ICE9PSAnYm9vbGVhbicpIHtcbiAgICBlbnYud2FzbS5wcm94eSA9IGZhbHNlO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBlbnYud2FzbS5udW1UaHJlYWRzICE9PSAnbnVtYmVyJyB8fCAhTnVtYmVyLmlzSW50ZWdlcihlbnYud2FzbS5udW1UaHJlYWRzKSB8fCBlbnYud2FzbS5udW1UaHJlYWRzIDw9IDApIHtcbiAgICBjb25zdCBudW1DcHVMb2dpY2FsQ29yZXMgPSB0eXBlb2YgbmF2aWdhdG9yID09PSAndW5kZWZpbmVkJyA/IGNwdXMoKS5sZW5ndGggOiBuYXZpZ2F0b3IuaGFyZHdhcmVDb25jdXJyZW5jeTtcbiAgICBlbnYud2FzbS5udW1UaHJlYWRzID0gTWF0aC5taW4oNCwgTWF0aC5jZWlsKChudW1DcHVMb2dpY2FsQ29yZXMgfHwgMSkgLyAyKSk7XG4gIH1cbn07XG5cbmNsYXNzIE9ubnhydW50aW1lV2ViQXNzZW1ibHlCYWNrZW5kIGltcGxlbWVudHMgQmFja2VuZCB7XG4gIGFzeW5jIGluaXQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gcG9wdWxhdGUgd2FzbSBmbGFnc1xuICAgIGluaXRpYWxpemVGbGFncygpO1xuXG4gICAgLy8gaW5pdCB3YXNtXG4gICAgYXdhaXQgaW5pdFdhc20oKTtcbiAgfVxuICBjcmVhdGVTZXNzaW9uSGFuZGxlcihwYXRoOiBzdHJpbmcsIG9wdGlvbnM/OiBJbmZlcmVuY2VTZXNzaW9uLlNlc3Npb25PcHRpb25zKTogUHJvbWlzZTxTZXNzaW9uSGFuZGxlcj47XG4gIGNyZWF0ZVNlc3Npb25IYW5kbGVyKGJ1ZmZlcjogVWludDhBcnJheSwgb3B0aW9ucz86IEluZmVyZW5jZVNlc3Npb24uU2Vzc2lvbk9wdGlvbnMpOiBQcm9taXNlPFNlc3Npb25IYW5kbGVyPjtcbiAgYXN5bmMgY3JlYXRlU2Vzc2lvbkhhbmRsZXIocGF0aE9yQnVmZmVyOiBzdHJpbmd8VWludDhBcnJheSwgb3B0aW9ucz86IEluZmVyZW5jZVNlc3Npb24uU2Vzc2lvbk9wdGlvbnMpOlxuICAgICAgUHJvbWlzZTxTZXNzaW9uSGFuZGxlcj4ge1xuICAgIGNvbnN0IGhhbmRsZXIgPSBuZXcgT25ueHJ1bnRpbWVXZWJBc3NlbWJseVNlc3Npb25IYW5kbGVyKCk7XG4gICAgYXdhaXQgaGFuZGxlci5sb2FkTW9kZWwocGF0aE9yQnVmZmVyLCBvcHRpb25zKTtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGhhbmRsZXIpO1xuICB9XG59XG5cbmV4cG9ydCBjb25zdCB3YXNtQmFja2VuZCA9IG5ldyBPbm54cnVudGltZVdlYkFzc2VtYmx5QmFja2VuZCgpO1xuIiwiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby12YXItcmVxdWlyZXMsIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZXF1aXJlLWltcG9ydHMgKi9cbi8vIFdlIHVzZSBcInJlcXVpcmVcIiBpbnN0ZWFkIG9mIFwiaW1wb3J0XCIgaGVyZSBiZWNhdXNlIGltcG9ydCBzdGF0ZW1lbnQgbXVzdCBiZSBwdXQgaW4gdG9wIGxldmVsLiBPdXIgY3VycmVudCBjb2RlIGRvZXNcbi8vIG5vdCBhbGxvdyB0ZXJzZXIgdG8gdHJlZS1zaGFraW5nIGNvZGUgYXMgZXhwZWN0ZWQgYmVjYXVzZSBzb21lIGNvZGVzIGFyZSB0cmVhdGVkIGFzIGhhdmluZyBzaWRlIGVmZmVjdHMuXG4vLyBTbyB3ZSBpbXBvcnQgY29kZSBpbnNpZGUgdGhlIGlmLWNsYXVzZSB0byBhbGxvdyB0ZXJzZXIgcmVtb3ZlIHRoZSBjb2RlIHNhZmVseS5cblxuZXhwb3J0ICogZnJvbSAnb25ueHJ1bnRpbWUtY29tbW9uJztcbmltcG9ydCB7cmVnaXN0ZXJCYWNrZW5kfSBmcm9tICdvbm54cnVudGltZS1jb21tb24nO1xuXG5pZiAoIUJVSUxEX0RFRlMuRElTQUJMRV9XRUJHTCkge1xuICBjb25zdCBvbm54anNCYWNrZW5kID0gcmVxdWlyZSgnLi9iYWNrZW5kLW9ubnhqcycpLm9ubnhqc0JhY2tlbmQ7XG4gIHJlZ2lzdGVyQmFja2VuZCgnd2ViZ2wnLCBvbm54anNCYWNrZW5kLCAtMTApO1xufVxuaWYgKCFCVUlMRF9ERUZTLkRJU0FCTEVfV0FTTSkge1xuICBjb25zdCB3YXNtQmFja2VuZCA9IHJlcXVpcmUoJy4vYmFja2VuZC13YXNtJykud2FzbUJhY2tlbmQ7XG4gIHJlZ2lzdGVyQmFja2VuZCgnY3B1Jywgd2FzbUJhY2tlbmQsIDEwKTtcbiAgcmVnaXN0ZXJCYWNrZW5kKCd3YXNtJywgd2FzbUJhY2tlbmQsIDEwKTtcbiAgcmVnaXN0ZXJCYWNrZW5kKCd4bm5wYWNrJywgd2FzbUJhY2tlbmQsIDkpO1xufVxuIiwiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmNsYXNzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleUltcGwge1xuICBjb25zdHJ1Y3RvcihhdHRyaWJ1dGU6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSB7XG4gICAgT2JqZWN0LmFzc2lnbih0aGlzLCBhdHRyaWJ1dGUpO1xuICB9XG5cbiAgcHJpdmF0ZSBfY2FjaGVLZXk6IHN0cmluZztcbiAgcHVibGljIGdldCBjYWNoZUtleSgpOiBzdHJpbmcge1xuICAgIGlmICghdGhpcy5fY2FjaGVLZXkpIHtcbiAgICAgIHRoaXMuX2NhY2hlS2V5ID1cbiAgICAgICAgICBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0aGlzKS5zb3J0KCkubWFwKG5hbWUgPT4gYCR7KHRoaXMgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pW25hbWVdfWApLmpvaW4oJzsnKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2NhY2hlS2V5O1xuICB9XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgY2FjaGVLZXk6IHN0cmluZztcbn1cblxuZXhwb3J0IGNvbnN0IGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSA9IDxUIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4+KGF0dHJpYnV0ZTogVCk6IFQmQXR0cmlidXRlV2l0aENhY2hlS2V5ID0+XG4gICAgbmV3IEF0dHJpYnV0ZVdpdGhDYWNoZUtleUltcGwoYXR0cmlidXRlKSBhcyB1bmtub3duIGFzIFQgJiBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXk7XG4iLCIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IExvbmcgZnJvbSAnbG9uZyc7XG5pbXBvcnQge29ubnh9IGZyb20gJ29ubngtcHJvdG8nO1xuXG5pbXBvcnQge29ubnhydW50aW1lfSBmcm9tICcuL29ydC1zY2hlbWEvb3J0LWdlbmVyYXRlZCc7XG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi90ZW5zb3InO1xuaW1wb3J0IHtkZWNvZGVVdGY4U3RyaW5nLCBMb25nVXRpbH0gZnJvbSAnLi91dGlsJztcblxuaW1wb3J0IG9ydEZicyA9IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnM7XG5cbmV4cG9ydCBkZWNsYXJlIG5hbWVzcGFjZSBBdHRyaWJ1dGUge1xuICBleHBvcnQgaW50ZXJmYWNlIERhdGFUeXBlTWFwIHtcbiAgICBmbG9hdDogbnVtYmVyO1xuICAgIGludDogbnVtYmVyO1xuICAgIHN0cmluZzogc3RyaW5nO1xuICAgIHRlbnNvcjogVGVuc29yO1xuICAgIGZsb2F0czogbnVtYmVyW107XG4gICAgaW50czogbnVtYmVyW107XG4gICAgc3RyaW5nczogc3RyaW5nW107XG4gICAgdGVuc29yczogVGVuc29yW107XG4gIH1cblxuICBleHBvcnQgdHlwZSBEYXRhVHlwZSA9IGtleW9mIERhdGFUeXBlTWFwO1xufVxuXG50eXBlIFZhbHVlVHlwZXMgPSBBdHRyaWJ1dGUuRGF0YVR5cGVNYXBbQXR0cmlidXRlLkRhdGFUeXBlXTtcblxudHlwZSBWYWx1ZSA9IFtWYWx1ZVR5cGVzLCBBdHRyaWJ1dGUuRGF0YVR5cGVdO1xuXG5leHBvcnQgY2xhc3MgQXR0cmlidXRlIHtcbiAgY29uc3RydWN0b3IoYXR0cmlidXRlczogb25ueC5JQXR0cmlidXRlUHJvdG9bXXxvcnRGYnMuQXR0cmlidXRlW118bnVsbHx1bmRlZmluZWQpIHtcbiAgICB0aGlzLl9hdHRyaWJ1dGVzID0gbmV3IE1hcCgpO1xuICAgIGlmIChhdHRyaWJ1dGVzICE9PSBudWxsICYmIGF0dHJpYnV0ZXMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgZm9yIChjb25zdCBhdHRyIG9mIGF0dHJpYnV0ZXMpIHtcbiAgICAgICAgaWYgKGF0dHIgaW5zdGFuY2VvZiBvbm54LkF0dHJpYnV0ZVByb3RvKSB7XG4gICAgICAgICAgdGhpcy5fYXR0cmlidXRlcy5zZXQoYXR0ci5uYW1lLCBbQXR0cmlidXRlLmdldFZhbHVlKGF0dHIpLCBBdHRyaWJ1dGUuZ2V0VHlwZShhdHRyKV0pO1xuICAgICAgICB9IGVsc2UgaWYgKGF0dHIgaW5zdGFuY2VvZiBvcnRGYnMuQXR0cmlidXRlKSB7XG4gICAgICAgICAgdGhpcy5fYXR0cmlidXRlcy5zZXQoYXR0ci5uYW1lKCkhLCBbQXR0cmlidXRlLmdldFZhbHVlKGF0dHIpLCBBdHRyaWJ1dGUuZ2V0VHlwZShhdHRyKV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5fYXR0cmlidXRlcy5zaXplIDwgYXR0cmlidXRlcy5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdkdXBsaWNhdGVkIGF0dHJpYnV0ZSBuYW1lcycpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHNldChrZXk6IHN0cmluZywgdHlwZTogQXR0cmlidXRlLkRhdGFUeXBlLCB2YWx1ZTogVmFsdWVUeXBlcyk6IHZvaWQge1xuICAgIHRoaXMuX2F0dHJpYnV0ZXMuc2V0KGtleSwgW3ZhbHVlLCB0eXBlXSk7XG4gIH1cbiAgZGVsZXRlKGtleTogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5fYXR0cmlidXRlcy5kZWxldGUoa2V5KTtcbiAgfVxuICBnZXRGbG9hdChrZXk6IHN0cmluZywgZGVmYXVsdFZhbHVlPzogQXR0cmlidXRlLkRhdGFUeXBlTWFwWydmbG9hdCddKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KGtleSwgJ2Zsb2F0JywgZGVmYXVsdFZhbHVlKTtcbiAgfVxuXG4gIGdldEludChrZXk6IHN0cmluZywgZGVmYXVsdFZhbHVlPzogQXR0cmlidXRlLkRhdGFUeXBlTWFwWydpbnQnXSkge1xuICAgIHJldHVybiB0aGlzLmdldChrZXksICdpbnQnLCBkZWZhdWx0VmFsdWUpO1xuICB9XG5cbiAgZ2V0U3RyaW5nKGtleTogc3RyaW5nLCBkZWZhdWx0VmFsdWU/OiBBdHRyaWJ1dGUuRGF0YVR5cGVNYXBbJ3N0cmluZyddKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KGtleSwgJ3N0cmluZycsIGRlZmF1bHRWYWx1ZSk7XG4gIH1cblxuICBnZXRUZW5zb3Ioa2V5OiBzdHJpbmcsIGRlZmF1bHRWYWx1ZT86IEF0dHJpYnV0ZS5EYXRhVHlwZU1hcFsndGVuc29yJ10pIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoa2V5LCAndGVuc29yJywgZGVmYXVsdFZhbHVlKTtcbiAgfVxuXG4gIGdldEZsb2F0cyhrZXk6IHN0cmluZywgZGVmYXVsdFZhbHVlPzogQXR0cmlidXRlLkRhdGFUeXBlTWFwWydmbG9hdHMnXSkge1xuICAgIHJldHVybiB0aGlzLmdldChrZXksICdmbG9hdHMnLCBkZWZhdWx0VmFsdWUpO1xuICB9XG5cbiAgZ2V0SW50cyhrZXk6IHN0cmluZywgZGVmYXVsdFZhbHVlPzogQXR0cmlidXRlLkRhdGFUeXBlTWFwWydpbnRzJ10pIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoa2V5LCAnaW50cycsIGRlZmF1bHRWYWx1ZSk7XG4gIH1cblxuICBnZXRTdHJpbmdzKGtleTogc3RyaW5nLCBkZWZhdWx0VmFsdWU/OiBBdHRyaWJ1dGUuRGF0YVR5cGVNYXBbJ3N0cmluZ3MnXSkge1xuICAgIHJldHVybiB0aGlzLmdldChrZXksICdzdHJpbmdzJywgZGVmYXVsdFZhbHVlKTtcbiAgfVxuXG4gIGdldFRlbnNvcnMoa2V5OiBzdHJpbmcsIGRlZmF1bHRWYWx1ZT86IEF0dHJpYnV0ZS5EYXRhVHlwZU1hcFsndGVuc29ycyddKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KGtleSwgJ3RlbnNvcnMnLCBkZWZhdWx0VmFsdWUpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXQ8ViBleHRlbmRzIEF0dHJpYnV0ZS5EYXRhVHlwZU1hcFtBdHRyaWJ1dGUuRGF0YVR5cGVdPihcbiAgICAgIGtleTogc3RyaW5nLCB0eXBlOiBBdHRyaWJ1dGUuRGF0YVR5cGUsIGRlZmF1bHRWYWx1ZT86IFYpOiBWIHtcbiAgICBjb25zdCB2YWx1ZUFuZFR5cGUgPSB0aGlzLl9hdHRyaWJ1dGVzLmdldChrZXkpO1xuICAgIGlmICh2YWx1ZUFuZFR5cGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKGRlZmF1bHRWYWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBkZWZhdWx0VmFsdWU7XG4gICAgICB9XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYHJlcXVpcmVkIGF0dHJpYnV0ZSBub3QgZm91bmQ6ICR7a2V5fWApO1xuICAgIH1cbiAgICBpZiAodmFsdWVBbmRUeXBlWzFdICE9PSB0eXBlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYHR5cGUgbWlzbWF0Y2g6IGV4cGVjdGVkICR7dHlwZX0gYnV0IGdvdCAke3ZhbHVlQW5kVHlwZVsxXX1gKTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlQW5kVHlwZVswXSBhcyBWO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgZ2V0VHlwZShhdHRyOiBvbm54LklBdHRyaWJ1dGVQcm90b3xvcnRGYnMuQXR0cmlidXRlKTogQXR0cmlidXRlLkRhdGFUeXBlIHtcbiAgICBjb25zdCB0eXBlID0gYXR0ciBpbnN0YW5jZW9mIG9ubnguQXR0cmlidXRlUHJvdG8gPyAoYXR0cikudHlwZSA6IChhdHRyIGFzIG9ydEZicy5BdHRyaWJ1dGUpLnR5cGUoKTtcbiAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgIGNhc2Ugb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLkZMT0FUOlxuICAgICAgICByZXR1cm4gJ2Zsb2F0JztcbiAgICAgIGNhc2Ugb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLklOVDpcbiAgICAgICAgcmV0dXJuICdpbnQnO1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuU1RSSU5HOlxuICAgICAgICByZXR1cm4gJ3N0cmluZyc7XG4gICAgICBjYXNlIG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5URU5TT1I6XG4gICAgICAgIHJldHVybiAndGVuc29yJztcbiAgICAgIGNhc2Ugb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLkZMT0FUUzpcbiAgICAgICAgcmV0dXJuICdmbG9hdHMnO1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuSU5UUzpcbiAgICAgICAgcmV0dXJuICdpbnRzJztcbiAgICAgIGNhc2Ugb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLlNUUklOR1M6XG4gICAgICAgIHJldHVybiAnc3RyaW5ncyc7XG4gICAgICBjYXNlIG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5URU5TT1JTOlxuICAgICAgICByZXR1cm4gJ3RlbnNvcnMnO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBhdHRyaWJ1dGUgdHlwZSBpcyBub3Qgc3VwcG9ydGVkIHlldDogJHtvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGVbdHlwZV19YCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgZ2V0VmFsdWUoYXR0cjogb25ueC5JQXR0cmlidXRlUHJvdG98b3J0RmJzLkF0dHJpYnV0ZSkge1xuICAgIGNvbnN0IGF0dHJUeXBlID0gYXR0ciBpbnN0YW5jZW9mIG9ubnguQXR0cmlidXRlUHJvdG8gPyBhdHRyLnR5cGUgOiAoYXR0ciBhcyBvcnRGYnMuQXR0cmlidXRlKS50eXBlKCk7XG4gICAgaWYgKGF0dHJUeXBlID09PSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuR1JBUEggfHwgYXR0clR5cGUgPT09IG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5HUkFQSFMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignZ3JhcGggYXR0cmlidXRlIGlzIG5vdCBzdXBwb3J0ZWQgeWV0Jyk7XG4gICAgfVxuXG4gICAgY29uc3QgdmFsdWUgPSB0aGlzLmdldFZhbHVlTm9DaGVjayhhdHRyKTtcblxuICAgIC8vIGNhc3QgTE9ORyB0byBudW1iZXJcbiAgICBpZiAoYXR0clR5cGUgPT09IG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5JTlQgJiYgTG9uZ1V0aWwuaXNMb25nKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIExvbmdVdGlsLmxvbmdUb051bWJlcih2YWx1ZSBhcyBMb25nIHwgZmxhdGJ1ZmZlcnMuTG9uZyk7XG4gICAgfVxuXG4gICAgLy8gY2FzdCBMT05HW10gdG8gbnVtYmVyW11cbiAgICBpZiAoYXR0clR5cGUgPT09IG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5JTlRTKSB7XG4gICAgICBjb25zdCBhcnIgPSAodmFsdWUgYXMgQXJyYXk8bnVtYmVyfExvbmd8ZmxhdGJ1ZmZlcnMuTG9uZz4pO1xuICAgICAgY29uc3QgbnVtYmVyVmFsdWU6IG51bWJlcltdID0gbmV3IEFycmF5PG51bWJlcj4oYXJyLmxlbmd0aCk7XG5cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IG1heWJlTG9uZyA9IGFycltpXTtcbiAgICAgICAgbnVtYmVyVmFsdWVbaV0gPSBMb25nVXRpbC5sb25nVG9OdW1iZXIobWF5YmVMb25nKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG51bWJlclZhbHVlO1xuICAgIH1cblxuICAgIC8vIGNhc3Qgb25ueC5UZW5zb3JQcm90byB0byBvbm54anMuVGVuc29yXG4gICAgaWYgKGF0dHJUeXBlID09PSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuVEVOU09SKSB7XG4gICAgICByZXR1cm4gYXR0ciBpbnN0YW5jZW9mIG9ubnguQXR0cmlidXRlUHJvdG8gPyBUZW5zb3IuZnJvbVByb3RvKHZhbHVlIGFzIG9ubnguSVRlbnNvclByb3RvKSA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUZW5zb3IuZnJvbU9ydFRlbnNvcih2YWx1ZSBhcyBvcnRGYnMuVGVuc29yKTtcbiAgICB9XG5cbiAgICAvLyBjYXN0IG9ubnguVGVuc29yUHJvdG9bXSB0byBvbm54anMuVGVuc29yW11cbiAgICBpZiAoYXR0clR5cGUgPT09IG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5URU5TT1JTKSB7XG4gICAgICBpZiAoYXR0ciBpbnN0YW5jZW9mIG9ubnguQXR0cmlidXRlUHJvdG8pIHtcbiAgICAgICAgY29uc3QgdGVuc29yUHJvdG9zID0gdmFsdWUgYXMgb25ueC5JVGVuc29yUHJvdG9bXTtcbiAgICAgICAgcmV0dXJuIHRlbnNvclByb3Rvcy5tYXAodmFsdWUgPT4gVGVuc29yLmZyb21Qcm90byh2YWx1ZSkpO1xuICAgICAgfSBlbHNlIGlmIChhdHRyIGluc3RhbmNlb2Ygb3J0RmJzLkF0dHJpYnV0ZSkge1xuICAgICAgICBjb25zdCB0ZW5zb3JQcm90b3MgPSB2YWx1ZSBhcyBvcnRGYnMuVGVuc29yW107XG4gICAgICAgIHJldHVybiB0ZW5zb3JQcm90b3MubWFwKHZhbHVlID0+IFRlbnNvci5mcm9tT3J0VGVuc29yKHZhbHVlKSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gY2FzdCBVaW50OEFycmF5IHRvIHN0cmluZ1xuICAgIGlmIChhdHRyVHlwZSA9PT0gb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLlNUUklORykge1xuICAgICAgLy8gc3RyaW5nIGluIG9ubnggYXR0cmlidXRlIGlzIG9mIHVpbnQ4YXJyYXkgdHlwZSwgc28gd2UgbmVlZCB0byBjb252ZXJ0IGl0IHRvIHN0cmluZyBiZWxvdy4gV2hpbGUgaW4gb3J0IGZvcm1hdCxcbiAgICAgIC8vIHN0cmluZyBhdHRyaWJ1dGVzIGFyZSByZXR1cm5lZCBhcyBzdHJpbmcsIHNvIG5vIGNvbnZlcnNpb24gaXMgbmVlZGVkLlxuICAgICAgaWYgKGF0dHIgaW5zdGFuY2VvZiBvbm54LkF0dHJpYnV0ZVByb3RvKSB7XG4gICAgICAgIGNvbnN0IHV0ZjhTdHJpbmcgPSB2YWx1ZSBhcyBVaW50OEFycmF5O1xuICAgICAgICByZXR1cm4gZGVjb2RlVXRmOFN0cmluZyh1dGY4U3RyaW5nKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBjYXN0IFVpbnQ4QXJyYXlbXSB0byBzdHJpbmdbXVxuICAgIGlmIChhdHRyVHlwZSA9PT0gb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLlNUUklOR1MpIHtcbiAgICAgIC8vIHN0cmluZ3MgaW4gb25ueCBhdHRyaWJ1dGUgaXMgcmV0dXJuZWQgYXMgdWludDhhcnJheVtdLCBzbyB3ZSBuZWVkIHRvIGNvbnZlcnQgaXQgdG8gc3RyaW5nW10gYmVsb3cuIFdoaWxlIGluIG9ydFxuICAgICAgLy8gZm9ybWF0IHN0cmluZ3MgYXR0cmlidXRlcyBhcmUgcmV0dXJuZWQgYXMgc3RyaW5nW10sIHNvIG5vIGNvbnZlcnNpb24gaXMgbmVlZGVkLlxuICAgICAgaWYgKGF0dHIgaW5zdGFuY2VvZiBvbm54LkF0dHJpYnV0ZVByb3RvKSB7XG4gICAgICAgIGNvbnN0IHV0ZjhTdHJpbmdzID0gdmFsdWUgYXMgVWludDhBcnJheVtdO1xuICAgICAgICByZXR1cm4gdXRmOFN0cmluZ3MubWFwKGRlY29kZVV0ZjhTdHJpbmcpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZSBhcyBWYWx1ZVR5cGVzO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgZ2V0VmFsdWVOb0NoZWNrKGF0dHI6IG9ubnguSUF0dHJpYnV0ZVByb3RvfG9ydEZicy5BdHRyaWJ1dGUpIHtcbiAgICByZXR1cm4gYXR0ciBpbnN0YW5jZW9mIChvbm54LkF0dHJpYnV0ZVByb3RvKSA/IHRoaXMuZ2V0VmFsdWVOb0NoZWNrRnJvbU9ubnhGb3JtYXQoYXR0cikgOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5nZXRWYWx1ZU5vQ2hlY2tGcm9tT3J0Rm9ybWF0KGF0dHIgYXMgb3J0RmJzLkF0dHJpYnV0ZSk7XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBnZXRWYWx1ZU5vQ2hlY2tGcm9tT25ueEZvcm1hdChhdHRyOiBvbm54LklBdHRyaWJ1dGVQcm90bykge1xuICAgIHN3aXRjaCAoYXR0ci50eXBlISkge1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuRkxPQVQ6XG4gICAgICAgIHJldHVybiBhdHRyLmY7XG4gICAgICBjYXNlIG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5JTlQ6XG4gICAgICAgIHJldHVybiBhdHRyLmk7XG4gICAgICBjYXNlIG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5TVFJJTkc6XG4gICAgICAgIHJldHVybiBhdHRyLnM7XG4gICAgICBjYXNlIG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5URU5TT1I6XG4gICAgICAgIHJldHVybiBhdHRyLnQ7XG4gICAgICBjYXNlIG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5HUkFQSDpcbiAgICAgICAgcmV0dXJuIGF0dHIuZztcbiAgICAgIGNhc2Ugb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLkZMT0FUUzpcbiAgICAgICAgcmV0dXJuIGF0dHIuZmxvYXRzO1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuSU5UUzpcbiAgICAgICAgcmV0dXJuIGF0dHIuaW50cztcbiAgICAgIGNhc2Ugb25ueC5BdHRyaWJ1dGVQcm90by5BdHRyaWJ1dGVUeXBlLlNUUklOR1M6XG4gICAgICAgIHJldHVybiBhdHRyLnN0cmluZ3M7XG4gICAgICBjYXNlIG9ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZS5URU5TT1JTOlxuICAgICAgICByZXR1cm4gYXR0ci50ZW5zb3JzO1xuICAgICAgY2FzZSBvbm54LkF0dHJpYnV0ZVByb3RvLkF0dHJpYnV0ZVR5cGUuR1JBUEhTOlxuICAgICAgICByZXR1cm4gYXR0ci5ncmFwaHM7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuc3VwcG9ydGVkIGF0dHJpYnV0ZSB0eXBlOiAke29ubnguQXR0cmlidXRlUHJvdG8uQXR0cmlidXRlVHlwZVthdHRyLnR5cGUhXX1gKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBnZXRWYWx1ZU5vQ2hlY2tGcm9tT3J0Rm9ybWF0KGF0dHI6IG9ydEZicy5BdHRyaWJ1dGUpIHtcbiAgICBzd2l0Y2ggKGF0dHIudHlwZSgpKSB7XG4gICAgICBjYXNlIG9ydEZicy5BdHRyaWJ1dGVUeXBlLkZMT0FUOlxuICAgICAgICByZXR1cm4gYXR0ci5mKCk7XG4gICAgICBjYXNlIG9ydEZicy5BdHRyaWJ1dGVUeXBlLklOVDpcbiAgICAgICAgcmV0dXJuIGF0dHIuaSgpO1xuICAgICAgY2FzZSBvcnRGYnMuQXR0cmlidXRlVHlwZS5TVFJJTkc6XG4gICAgICAgIHJldHVybiBhdHRyLnMoKTtcbiAgICAgIGNhc2Ugb3J0RmJzLkF0dHJpYnV0ZVR5cGUuVEVOU09SOlxuICAgICAgICByZXR1cm4gYXR0ci50KCk7XG4gICAgICBjYXNlIG9ydEZicy5BdHRyaWJ1dGVUeXBlLkdSQVBIOlxuICAgICAgICByZXR1cm4gYXR0ci5nKCk7XG4gICAgICBjYXNlIG9ydEZicy5BdHRyaWJ1dGVUeXBlLkZMT0FUUzpcbiAgICAgICAgcmV0dXJuIGF0dHIuZmxvYXRzQXJyYXkoKTtcbiAgICAgIGNhc2Ugb3J0RmJzLkF0dHJpYnV0ZVR5cGUuSU5UUzoge1xuICAgICAgICBjb25zdCBpbnRzID0gW107XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXR0ci5pbnRzTGVuZ3RoKCk7IGkrKykge1xuICAgICAgICAgIGludHMucHVzaChhdHRyLmludHMoaSkhKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaW50cztcbiAgICAgIH1cbiAgICAgIGNhc2Ugb3J0RmJzLkF0dHJpYnV0ZVR5cGUuU1RSSU5HUzoge1xuICAgICAgICBjb25zdCBzdHJpbmdzID0gW107XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXR0ci5zdHJpbmdzTGVuZ3RoKCk7IGkrKykge1xuICAgICAgICAgIHN0cmluZ3MucHVzaChhdHRyLnN0cmluZ3MoaSkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzdHJpbmdzO1xuICAgICAgfVxuICAgICAgY2FzZSBvcnRGYnMuQXR0cmlidXRlVHlwZS5URU5TT1JTOiB7XG4gICAgICAgIGNvbnN0IHRlbnNvcnMgPSBbXTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhdHRyLnRlbnNvcnNMZW5ndGgoKTsgaSsrKSB7XG4gICAgICAgICAgdGVuc29ycy5wdXNoKGF0dHIudGVuc29ycyhpKSEpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0ZW5zb3JzO1xuICAgICAgfVxuICAgICAgLy8gY2FzZSBvcnRGYnMuQXR0cmlidXRlVHlwZS5HUkFQSFM6XG4gICAgICAvLyBUT0RPOiBTdWJncmFwaCBub3Qgc3VwcG9ydGVkIHlldC5cbiAgICAgIC8vIGNvbnN0IGdyYXBocyA9IFtdO1xuICAgICAgLy8gZm9yIChsZXQgaSA9IDA7IGkgPCBhdHRyLmdyYXBoc0xlbmd0aCgpOyBpKyspIHtcbiAgICAgIC8vICAgZ3JhcGhzLnB1c2goYXR0ci5ncmFwaHMoaSkhKTtcbiAgICAgIC8vIH1cbiAgICAgIC8vIHJldHVybiBncmFwaHM7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuc3VwcG9ydGVkIGF0dHJpYnV0ZSB0eXBlOiAke29ydEZicy5BdHRyaWJ1dGVUeXBlW2F0dHIudHlwZSgpXX1gKTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgX2F0dHJpYnV0ZXM6IE1hcDxzdHJpbmcsIFZhbHVlPjtcbn1cbiIsIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge1dlYkdMQmFja2VuZH0gZnJvbSAnLi9iYWNrZW5kcy9iYWNrZW5kLXdlYmdsJztcbmltcG9ydCB7R3JhcGh9IGZyb20gJy4vZ3JhcGgnO1xuaW1wb3J0IHtPcGVyYXRvcn0gZnJvbSAnLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHtPcFNldH0gZnJvbSAnLi9vcHNldCc7XG5pbXBvcnQge1Nlc3Npb259IGZyb20gJy4vc2Vzc2lvbic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW5mZXJlbmNlSGFuZGxlciB7XG4gIC8qKlxuICAgKiBkaXNwb3NlIHRoZSBpbmZlcmVuY2UgaGFuZGxlci4gaXQgd2lsbCBiZSBjYWxsZWQgYXMgdGhlIGxhc3Qgc3RlcCBpbiBTZXNzaW9uLnJ1bigpXG4gICAqL1xuICBkaXNwb3NlKCk6IHZvaWQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2Vzc2lvbkhhbmRsZXIge1xuICAvKipcbiAgICogdHJhbnNmb3JtIHRoZSBncmFwaCBhdCBpbml0aWFsaXphdGlvbiB0aW1lXG4gICAqIEBwYXJhbSBncmFwaFRyYW5zZm9ybWVyIHRoZSBncmFwaCB0cmFuc2Zvcm1lciB0byBtYW5pcHVsYXRlIHRoZSBtb2RlbCBncmFwaFxuICAgKi9cbiAgdHJhbnNmb3JtR3JhcGg/KGdyYXBoVHJhbnNmb3JtZXI6IEdyYXBoLlRyYW5zZm9ybWVyKTogdm9pZDtcblxuICAvKipcbiAgICogY3JlYXRlIGFuIGluc3RhbmNlIG9mIEluZmVyZW5jZUhhbmRsZXIgdG8gdXNlIGluIGEgU2Vzc2lvbi5ydW4oKSBjYWxsXG4gICAqL1xuICBjcmVhdGVJbmZlcmVuY2VIYW5kbGVyKCk6IEluZmVyZW5jZUhhbmRsZXI7XG5cbiAgLyoqXG4gICAqIGRpc3Bvc2UgdGhlIHNlc3Npb24gaGFuZGxlci4gaXQgd2lsbCBiZSBjYWxsZWQgd2hlbiBhIHNlc3Npb24gaXMgYmVpbmcgZGlzcG9zZWQgZXhwbGljaXRseVxuICAgKi9cbiAgZGlzcG9zZSgpOiB2b2lkO1xuXG4gIC8qKlxuICAgKiBSZXNvbHZlcyB0aGUgb3BlcmF0b3IgZnJvbSB0aGUgbmFtZSBhbmQgb3BzZXQgdmVyc2lvbjsgYmFja2VuZCBzcGVjaWZpY1xuICAgKiBAcGFyYW0gbm9kZSB0aGUgbm9kZSB0byByZXNvbHZlXG4gICAqIEBwYXJhbSBvcHNldHMgYSBsaXN0IG9mIG9wc2V0cyB0aGF0IGV4cG9ydGVkIGZyb20gdGhlIG1vZGVsXG4gICAqIEBwYXJhbSBncmFwaCB0aGUgY29tcGxldGVseSBpbml0aWFsaXplZCBncmFwaFxuICAgKi9cbiAgcmVzb2x2ZShub2RlOiBHcmFwaC5Ob2RlLCBvcHNldHM6IHJlYWRvbmx5IE9wU2V0W10sIGdyYXBoOiBHcmFwaCk6IE9wZXJhdG9yO1xuXG4gIC8qKlxuICAgKiBUaGlzIG1ldGhvZCBsZXQncyB0aGUgc2Vzc2lvbkhhbmRsZXIga25vdyB0aGF0IHRoZSBncmFwaCBpbml0aWFsaXphdGlvbiBpcyBjb21wbGV0ZVxuICAgKiBAcGFyYW0gZ3JhcGggdGhlIGNvbXBsZXRlbHkgaW5pdGlhbGl6ZWQgZ3JhcGhcbiAgICovXG4gIG9uR3JhcGhJbml0aWFsaXplZD8oZ3JhcGg6IEdyYXBoKTogdm9pZDtcblxuICAvKipcbiAgICogYSByZWZlcmVuY2UgdG8gdGhlIGNvcnJlc3BvbmRpbmcgYmFja2VuZFxuICAgKi9cbiAgcmVhZG9ubHkgYmFja2VuZDogQmFja2VuZDtcblxuICAvKipcbiAgICogYSByZWZlcmVuY2UgdG8gdGhlIHNlc3Npb24gY29udGV4dFxuICAgKi9cbiAgcmVhZG9ubHkgY29udGV4dDogU2Vzc2lvbi5Db250ZXh0O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEJhY2tlbmQge1xuICAvKipcbiAgICogaW5pdGlhbGl6ZSB0aGUgYmFja2VuZC4gd2lsbCBiZSBjYWxsZWQgb25seSBvbmNlLCB3aGVuIHRoZSBmaXJzdCB0aW1lIHRoZVxuICAgKiBiYWNrZW5kIGl0IHRvIGJlIHVzZWRcbiAgICovXG4gIGluaXRpYWxpemUoKTogYm9vbGVhbnxQcm9taXNlPGJvb2xlYW4+O1xuXG4gIC8qKlxuICAgKiBjcmVhdGUgYW4gaW5zdGFuY2Ugb2YgU2Vzc2lvbkhhbmRsZXIgdG8gdXNlIGluIGEgU2Vzc2lvbiBvYmplY3QncyBsaWZlY3ljbGVcbiAgICovXG4gIGNyZWF0ZVNlc3Npb25IYW5kbGVyKGNvbnRleHQ6IFNlc3Npb24uQ29udGV4dCk6IFNlc3Npb25IYW5kbGVyO1xuXG4gIC8qKlxuICAgKiBkaXNwb3NlIHRoZSBiYWNrZW5kLiBjdXJyZW50bHkgdGhpcyB3aWxsIG5vdCBiZSBjYWxsZWRcbiAgICovXG4gIGRpc3Bvc2UoKTogdm9pZDtcbn1cblxuLy8gY2FjaGVzIGFsbCBpbml0aWFsaXplZCBiYWNrZW5kIGluc3RhbmNlc1xuY29uc3QgYmFja2VuZHNDYWNoZTogTWFwPHN0cmluZywgQmFja2VuZD4gPSBuZXcgTWFwKCk7XG5cbmV4cG9ydCBjb25zdCBiYWNrZW5kOiB7W25hbWU6IHN0cmluZ106IEJhY2tlbmR9ID0ge1xuICB3ZWJnbDogbmV3IFdlYkdMQmFja2VuZCgpLFxufTtcblxuLyoqXG4gKiBSZXNvbHZlIGEgcmVmZXJlbmNlIHRvIHRoZSBiYWNrZW5kLiBJZiBhIGhpbnQgaXMgc3BlY2lmaWVkLCB0aGUgY29ycmVzcG9uZGluZ1xuICogYmFja2VuZCB3aWxsIGJlIHVzZWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZXNvbHZlQmFja2VuZChoaW50Pzogc3RyaW5nfHJlYWRvbmx5IHN0cmluZ1tdKTogUHJvbWlzZTxCYWNrZW5kPiB7XG4gIGlmICghaGludCkge1xuICAgIHJldHVybiByZXNvbHZlQmFja2VuZChbJ3dlYmdsJ10pO1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IGhpbnRzID0gdHlwZW9mIGhpbnQgPT09ICdzdHJpbmcnID8gW2hpbnRdIDogaGludDtcblxuICAgIGZvciAoY29uc3QgYmFja2VuZEhpbnQgb2YgaGludHMpIHtcbiAgICAgIGNvbnN0IGNhY2hlID0gYmFja2VuZHNDYWNoZS5nZXQoYmFja2VuZEhpbnQpO1xuICAgICAgaWYgKGNhY2hlKSB7XG4gICAgICAgIHJldHVybiBjYWNoZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgYmFja2VuZCA9IGF3YWl0IHRyeUxvYWRCYWNrZW5kKGJhY2tlbmRIaW50KTtcbiAgICAgIGlmIChiYWNrZW5kKSB7XG4gICAgICAgIHJldHVybiBiYWNrZW5kO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcignbm8gYXZhaWxhYmxlIGJhY2tlbmQgdG8gdXNlJyk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHRyeUxvYWRCYWNrZW5kKGJhY2tlbmRIaW50OiBzdHJpbmcpOiBQcm9taXNlPEJhY2tlbmR8dW5kZWZpbmVkPiB7XG4gIGNvbnN0IGJhY2tlbmRPYmogPSBiYWNrZW5kO1xuXG4gIGlmICh0eXBlb2YgYmFja2VuZE9ialtiYWNrZW5kSGludF0gIT09ICd1bmRlZmluZWQnICYmIGlzQmFja2VuZChiYWNrZW5kT2JqW2JhY2tlbmRIaW50XSkpIHtcbiAgICBjb25zdCBiYWNrZW5kID0gYmFja2VuZE9ialtiYWNrZW5kSGludF07XG4gICAgbGV0IGluaXQgPSBiYWNrZW5kLmluaXRpYWxpemUoKTtcbiAgICBpZiAodHlwZW9mIGluaXQgPT09ICdvYmplY3QnICYmICd0aGVuJyBpbiBpbml0KSB7XG4gICAgICBpbml0ID0gYXdhaXQgaW5pdDtcbiAgICB9XG4gICAgaWYgKGluaXQpIHtcbiAgICAgIGJhY2tlbmRzQ2FjaGUuc2V0KGJhY2tlbmRIaW50LCBiYWNrZW5kKTtcbiAgICAgIHJldHVybiBiYWNrZW5kO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIGlzQmFja2VuZChvYmo6IHVua25vd24pIHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgY29uc3QgbyA9IG9iaiBhcyBhbnk7XG5cbiAgLy8gY2hlY2sgaWYgYW4gb2JqZWN0IGlzIGEgQmFja2VuZCBpbnN0YW5jZVxuICBpZiAoXG4gICAgICAnaW5pdGlhbGl6ZScgaW4gbyAmJiB0eXBlb2Ygby5pbml0aWFsaXplID09PSAnZnVuY3Rpb24nICYmICAgICAgICAgICAgICAgICAgICAgIC8vIGluaXRpYWxpemUoKVxuICAgICAgJ2NyZWF0ZVNlc3Npb25IYW5kbGVyJyBpbiBvICYmIHR5cGVvZiBvLmNyZWF0ZVNlc3Npb25IYW5kbGVyID09PSAnZnVuY3Rpb24nICYmICAvLyBjcmVhdGVTZXNzaW9uSGFuZGxlcigpXG4gICAgICAnZGlzcG9zZScgaW4gbyAmJiB0eXBlb2Ygby5kaXNwb3NlID09PSAnZnVuY3Rpb24nICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRpc3Bvc2UoKVxuICApIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cblxuZXhwb3J0IHR5cGUgQmFja2VuZFR5cGUgPSBCYWNrZW5kO1xuZXhwb3J0IHR5cGUgU2Vzc2lvbkhhbmRsZXJUeXBlID0gUmV0dXJuVHlwZTxCYWNrZW5kVHlwZVsnY3JlYXRlU2Vzc2lvbkhhbmRsZXInXT47XG5leHBvcnQgdHlwZSBJbmZlcmVuY2VIYW5kbGVyVHlwZSA9IFJldHVyblR5cGU8U2Vzc2lvbkhhbmRsZXJUeXBlWydjcmVhdGVJbmZlcmVuY2VIYW5kbGVyJ10+O1xuIiwiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7ZW52fSBmcm9tICdvbm54cnVudGltZS1jb21tb24nO1xuXG5pbXBvcnQge0JhY2tlbmQsIFNlc3Npb25IYW5kbGVyfSBmcm9tICcuLi9iYWNrZW5kJztcbmltcG9ydCB7TG9nZ2VyfSBmcm9tICcuLi9pbnN0cnVtZW50JztcbmltcG9ydCB7U2Vzc2lvbn0gZnJvbSAnLi4vc2Vzc2lvbic7XG5cbmltcG9ydCB7V2ViR0xTZXNzaW9uSGFuZGxlcn0gZnJvbSAnLi93ZWJnbC9zZXNzaW9uLWhhbmRsZXInO1xuaW1wb3J0IHtXZWJHTENvbnRleHR9IGZyb20gJy4vd2ViZ2wvd2ViZ2wtY29udGV4dCc7XG5pbXBvcnQge2NyZWF0ZVdlYkdMQ29udGV4dH0gZnJvbSAnLi93ZWJnbC93ZWJnbC1jb250ZXh0LWZhY3RvcnknO1xuXG4vKipcbiAqIFdlYkdMQmFja2VuZCBpcyB0aGUgZW50cnkgcG9pbnQgZm9yIGFsbCBXZWJHTCBvcGVhcnRpb25zXG4gKiBXaGVuIGl0IHN0YXJ0cyBpdCBjcmVhdGVkIHRoZSBXZWJHTFJlbmRlcmluZ0NvbnRleHRcbiAqIGFuZCBvdGhlciBtYWluIGZyYW1ld29yayBjb21wb25lbnRzIHN1Y2ggYXMgUHJvZ3JhbSBhbmQgVGV4dHVyZSBNYW5hZ2Vyc1xuICovXG5leHBvcnQgY2xhc3MgV2ViR0xCYWNrZW5kIGltcGxlbWVudHMgQmFja2VuZCB7XG4gIGdsQ29udGV4dDogV2ViR0xDb250ZXh0O1xuXG4gIGdldCBjb250ZXh0SWQoKTogJ3dlYmdsJ3wnd2ViZ2wyJ3x1bmRlZmluZWQge1xuICAgIHJldHVybiBlbnYud2ViZ2wuY29udGV4dElkO1xuICB9XG4gIHNldCBjb250ZXh0SWQodmFsdWU6ICd3ZWJnbCd8J3dlYmdsMid8dW5kZWZpbmVkKSB7XG4gICAgZW52LndlYmdsLmNvbnRleHRJZCA9IHZhbHVlO1xuICB9XG5cbiAgZ2V0IG1hdG11bE1heEJhdGNoU2l6ZSgpOiBudW1iZXJ8dW5kZWZpbmVkIHtcbiAgICByZXR1cm4gZW52LndlYmdsLm1hdG11bE1heEJhdGNoU2l6ZTtcbiAgfVxuICBzZXQgbWF0bXVsTWF4QmF0Y2hTaXplKHZhbHVlOiBudW1iZXJ8dW5kZWZpbmVkKSB7XG4gICAgZW52LndlYmdsLm1hdG11bE1heEJhdGNoU2l6ZSA9IHZhbHVlO1xuICB9XG5cbiAgZ2V0IHRleHR1cmVDYWNoZU1vZGUoKTogJ2luaXRpYWxpemVyT25seSd8J2Z1bGwnfHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIGVudi53ZWJnbC50ZXh0dXJlQ2FjaGVNb2RlO1xuICB9XG4gIHNldCB0ZXh0dXJlQ2FjaGVNb2RlKHZhbHVlOiAnaW5pdGlhbGl6ZXJPbmx5J3wnZnVsbCd8dW5kZWZpbmVkKSB7XG4gICAgZW52LndlYmdsLnRleHR1cmVDYWNoZU1vZGUgPSB2YWx1ZTtcbiAgfVxuXG4gIGdldCBwYWNrKCk6IGJvb2xlYW58dW5kZWZpbmVkIHtcbiAgICByZXR1cm4gZW52LndlYmdsLnBhY2s7XG4gIH1cbiAgc2V0IHBhY2sodmFsdWU6IGJvb2xlYW58dW5kZWZpbmVkKSB7XG4gICAgZW52LndlYmdsLnBhY2sgPSB2YWx1ZTtcbiAgfVxuXG4gIGdldCBhc3luYygpOiBib29sZWFufHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIGVudi53ZWJnbC5hc3luYztcbiAgfVxuICBzZXQgYXN5bmModmFsdWU6IGJvb2xlYW58dW5kZWZpbmVkKSB7XG4gICAgZW52LndlYmdsLmFzeW5jID0gdmFsdWU7XG4gIH1cblxuICBpbml0aWFsaXplKCk6IGJvb2xlYW4ge1xuICAgIHRyeSB7XG4gICAgICB0aGlzLmdsQ29udGV4dCA9IGNyZWF0ZVdlYkdMQ29udGV4dCh0aGlzLmNvbnRleHRJZCk7XG4gICAgICBpZiAodHlwZW9mIHRoaXMubWF0bXVsTWF4QmF0Y2hTaXplICE9PSAnbnVtYmVyJykge1xuICAgICAgICB0aGlzLm1hdG11bE1heEJhdGNoU2l6ZSA9IDE2O1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiB0aGlzLnRleHR1cmVDYWNoZU1vZGUgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHRoaXMudGV4dHVyZUNhY2hlTW9kZSA9ICdmdWxsJztcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgdGhpcy5wYWNrICE9PSAnYm9vbGVhbicpIHtcbiAgICAgICAgdGhpcy5wYWNrID0gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAodHlwZW9mIHRoaXMuYXN5bmMgIT09ICdib29sZWFuJykge1xuICAgICAgICB0aGlzLmFzeW5jID0gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIExvZ2dlci5zZXRXaXRoRW52KGVudik7XG5cbiAgICAgIExvZ2dlci52ZXJib3NlKFxuICAgICAgICAgICdXZWJHTEJhY2tlbmQnLFxuICAgICAgICAgIGBDcmVhdGVkIFdlYkdMQ29udGV4dDogJHt0eXBlb2YgdGhpcy5nbENvbnRleHR9IHdpdGggbWF0bXVsTWF4QmF0Y2hTaXplOiAke1xuICAgICAgICAgICAgICB0aGlzLm1hdG11bE1heEJhdGNoU2l6ZX07IHRleHR1cmVDYWNoZU1vZGU6ICR7dGhpcy50ZXh0dXJlQ2FjaGVNb2RlfTsgcGFjazogJHt0aGlzLnBhY2t9OyBhc3luYzogJHtcbiAgICAgICAgICAgICAgdGhpcy5hc3luY30uYCk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBMb2dnZXIud2FybmluZygnV2ViR0xCYWNrZW5kJywgYFVuYWJsZSB0byBpbml0aWFsaXplIFdlYkdMQmFja2VuZC4gJHtlfWApO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICBjcmVhdGVTZXNzaW9uSGFuZGxlcihjb250ZXh0OiBTZXNzaW9uLkNvbnRleHQpOiBTZXNzaW9uSGFuZGxlciB7XG4gICAgcmV0dXJuIG5ldyBXZWJHTFNlc3Npb25IYW5kbGVyKHRoaXMsIGNvbnRleHQpO1xuICB9XG4gIGRpc3Bvc2UoKTogdm9pZCB7XG4gICAgdGhpcy5nbENvbnRleHQuZGlzcG9zZSgpO1xuICB9XG59XG4iLCIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtBcnJheVV0aWwsIEJyb2FkY2FzdFV0aWwsIFNoYXBlVXRpbH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5cbmltcG9ydCB7R2xzbENvbnRleHQsIEdsc2xMaWIsIEdsc2xMaWJSb3V0aW5lfSBmcm9tICcuL2dsc2wtZGVmaW5pdGlvbnMnO1xuaW1wb3J0IHtnZXRHbHNsfSBmcm9tICcuL2dsc2wtc291cmNlJztcbmltcG9ydCB7c3F1ZWV6ZVNoYXBlfSBmcm9tICcuL3RleHR1cmUtbGF5b3V0LXN0cmF0ZWd5JztcbmltcG9ydCB7VGV4dHVyZUxheW91dH0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQge2dlbmVyYXRlU2hhZGVyRnVuY05hbWVGcm9tSW5wdXRTYW1wbGVyTmFtZSwgZ2VuZXJhdGVTaGFkZXJGdW5jTmFtZUZyb21JbnB1dFNhbXBsZXJOYW1lQXRPdXRDb29yZHMsIGdldENvb3Jkc0RhdGFUeXBlLCBnZXRHbENoYW5uZWxzLCBnZXRTcXVlZXplZFBhcmFtcywgc3F1ZWV6ZUlucHV0U2hhcGV9IGZyb20gJy4vdXRpbHMnO1xuXG4vKipcbiAqIEdMU0wgTGlicmFyeSByZXNwb25zaWJsZSBmb3IgZGF0YSB0eXBlcyBhbmQgcm91dGluZXMgZm9yIG1hbmlwdWxhdGluZ1xuICogY29vcmRpbmF0ZXMgYW5kIG1hcHBpbmcgdG8vZnJvbSB0ZW5zb3IgaW5kaWNlc1xuICovXG5leHBvcnQgY2xhc3MgQ29vcmRzR2xzbExpYiBleHRlbmRzIEdsc2xMaWIge1xuICByZXR1cm5UeXBlOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IoY29udGV4dDogR2xzbENvbnRleHQpIHtcbiAgICBzdXBlcihjb250ZXh0KTtcbiAgfVxuICBnZXRGdW5jdGlvbnMoKToge1tuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZX0ge1xuICAgIHJldHVybiB7XG4gICAgICAuLi50aGlzLm9mZnNldFRvQ29vcmRzKCksXG4gICAgICAuLi50aGlzLmNvb3Jkc1RvT2Zmc2V0KCksXG4gICAgICAuLi50aGlzLnRvVmVjKCksXG4gICAgICAuLi50aGlzLnZhbHVlRnJvbSgpLFxuICAgICAgLy8gVE9ETyByZXR1cm4gdGhlc2Ugb25seSB3aGVuIHBhY2tpbmcgaXMgZW5hYmxlZC5cbiAgICAgIC4uLnRoaXMuZ2V0Q29tbW9uVXRpbEZ1bmNzKCksXG4gICAgICAuLi50aGlzLmdldElucHV0c1NhbXBsaW5nU25pcHBldHMoKSxcbiAgICAgIC4uLnRoaXMuZ2V0T3V0cHV0U2FtcGxpbmdTbmlwcGV0KClcbiAgICB9O1xuICB9XG4gIGdldEN1c3RvbVR5cGVzKCkge1xuICAgIHJldHVybiB7fTtcbiAgfVxuICAvKipcbiAgICogUHJvZHVjZXMgYSBmdW5jdGlvbiB0aGF0IGNhbiBtYXAgZnJvbVxuICAgKiAyRCBub3JtYWx6aWVkIGNvb3JkaW5hdGVzIChzLHQpIHRvIGEgZmxhdCBvZmZzZXRcbiAgICovXG4gIHByb3RlY3RlZCBvZmZzZXRUb0Nvb3JkcygpOiB7W25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lfSB7XG4gICAgY29uc3QgZnVuY05hbWUgPSAnb2Zmc2V0VG9Db29yZHMnO1xuICAgIHJldHVybiB7XG4gICAgICBvZmZzZXRUb0Nvb3JkczogbmV3IEdsc2xMaWJSb3V0aW5lKGBcbiAgICAgIHZlYzIgJHtmdW5jTmFtZX0oaW50IG9mZnNldCwgaW50IHdpZHRoLCBpbnQgaGVpZ2h0KSB7XG4gICAgICAgIGludCB0ID0gb2Zmc2V0IC8gd2lkdGg7XG4gICAgICAgIGludCBzID0gb2Zmc2V0IC0gdCp3aWR0aDtcbiAgICAgICAgdmVjMiBjb29yZHMgPSAodmVjMihzLHQpICsgdmVjMigwLjUsMC41KSkgLyB2ZWMyKHdpZHRoLCBoZWlnaHQpO1xuICAgICAgICByZXR1cm4gY29vcmRzO1xuICAgICAgfVxuICAgICAgYClcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFByb2R1Y2VzIGEgZnVuY3Rpb24gdGhhdCBjYW4gbWFwIGZyb21cbiAgICogMkQgbm9ybWFsemllZCBjb29yZGluYXRlcyAocyx0KSB0byBhIGZsYXQgb2Zmc2V0XG4gICAqL1xuICBwcm90ZWN0ZWQgY29vcmRzVG9PZmZzZXQoKToge1tuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZX0ge1xuICAgIGNvbnN0IGZ1bmNOYW1lID0gJ2Nvb3Jkc1RvT2Zmc2V0JztcbiAgICByZXR1cm4ge1xuICAgICAgY29vcmRzVG9PZmZzZXQ6IG5ldyBHbHNsTGliUm91dGluZShgXG4gICAgICBpbnQgJHtmdW5jTmFtZX0odmVjMiBjb29yZHMsIGludCB3aWR0aCwgaW50IGhlaWdodCkge1xuICAgICAgICBmbG9hdCBzID0gY29vcmRzLnMgKiBmbG9hdCh3aWR0aCk7XG4gICAgICAgIGZsb2F0IHQgPSBjb29yZHMudCAqIGZsb2F0KGhlaWdodCk7XG4gICAgICAgIGludCBvZmZzZXQgPSBpbnQodCkgKiB3aWR0aCArIGludChzKTtcbiAgICAgICAgcmV0dXJuIG9mZnNldDtcbiAgICAgIH1cbiAgICAgIGApXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZXMgY29kZSBmb3Igb3V0cHV0IHNhbXBsZXIuXG4gICAqL1xuXG4gIHByb3RlY3RlZCBnZXRPdXRwdXRTYW1wbGluZ1NuaXBwZXQoKToge1tuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZX0ge1xuICAgIGNvbnN0IG91dHB1dExheW91dCA9IHRoaXMuY29udGV4dC5vdXRwdXRUZXh0dXJlTGF5b3V0O1xuICAgIGlmIChvdXRwdXRMYXlvdXQuaXNQYWNrZWQpIHtcbiAgICAgIHJldHVybiB0aGlzLmdldFBhY2tlZE91dHB1dFNhbXBsaW5nU25pcHBldChvdXRwdXRMYXlvdXQpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRVbnBhY2tlZE91dHB1dFNhbXBsaW5nU25pcHBldChvdXRwdXRMYXlvdXQpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZXMgY29kZSBmb3IgcGFja2VkIG91dHB1dCBzYW1wbGVyLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFBhY2tlZE91dHB1dFNhbXBsaW5nU25pcHBldChvdXRwdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQpOiB7W25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lfSB7XG4gICAgY29uc3Qgb3V0U2hhcGUgPSBvdXRwdXRMYXlvdXQudW5wYWNrZWRTaGFwZTtcbiAgICBjb25zdCBvdXRUZXhTaGFwZSA9IFtvdXRwdXRMYXlvdXQud2lkdGgsIG91dHB1dExheW91dC5oZWlnaHRdO1xuICAgIGNvbnN0IHJlc3VsdDoge1tuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZX0gPSB7fTtcbiAgICBjb25zdCBmdW5jTmFtZSA9ICdnZXRPdXRwdXRDb29yZHMnO1xuICAgIHN3aXRjaCAob3V0U2hhcGUubGVuZ3RoKSB7XG4gICAgICBjYXNlIDA6XG4gICAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSB0aGlzLmdldE91dHB1dFNjYWxhckNvb3JkcygpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IHRoaXMuZ2V0T3V0cHV0UGFja2VkMURDb29yZHMob3V0U2hhcGUgYXMgW251bWJlcl0sIG91dFRleFNoYXBlIGFzIFtudW1iZXIsIG51bWJlcl0pO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMjpcbiAgICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IHRoaXMuZ2V0T3V0cHV0UGFja2VkMkRDb29yZHMob3V0U2hhcGUgYXMgW251bWJlciwgbnVtYmVyXSwgb3V0VGV4U2hhcGUgYXMgW251bWJlciwgbnVtYmVyXSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzOlxuICAgICAgICByZXN1bHRbZnVuY05hbWVdID1cbiAgICAgICAgICAgIHRoaXMuZ2V0T3V0cHV0UGFja2VkM0RDb29yZHMob3V0U2hhcGUgYXMgW251bWJlciwgbnVtYmVyLCBudW1iZXJdLCBvdXRUZXhTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXJdKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXN1bHRbZnVuY05hbWVdID0gdGhpcy5nZXRPdXRwdXRQYWNrZWRORENvb3JkcyhvdXRTaGFwZSwgb3V0VGV4U2hhcGUgYXMgW251bWJlciwgbnVtYmVyXSk7XG4gICAgfVxuICAgIGNvbnN0IGdsc2wgPSBnZXRHbHNsKHRoaXMuY29udGV4dC5nbENvbnRleHQudmVyc2lvbik7XG4gICAgLy8gVE9ETyB3ZSBuZWVkIHRoaXMgdG8gcHJvcGVybHkgcmV0dXJuIGEgcGFja2VkIHZlYzQgZnJvbSBrZXJuZWxzLlxuICAgIC8vIFJlcGxhY2UgYWxsICd7Z2xzbC5vdXRwdXR9ID0gcmVzdWx0JyB3aXRoICdzZXRPdXRwdXQocmVzdWx0KScgaW4gYWxsIGtlcm5lbHMuXG4gICAgY29uc3QgZmxvYXRUZXh0dXJlU2V0UkdCQVNvdXJjZSA9IGBcbiAgICAgIHZvaWQgc2V0T3V0cHV0KHZlYzQgdmFsKSB7XG4gICAgICAgICR7Z2xzbC5vdXRwdXR9ID0gdmFsO1xuICAgICAgfVxuICAgIGA7XG4gICAgY29uc3QgZmxvYXRUZXh0dXJlU2V0UkdCQUZ1bmNOYW1lID0gJ2Zsb2F0VGV4dHVyZVNldFJHQkEnO1xuICAgIHJlc3VsdFtmbG9hdFRleHR1cmVTZXRSR0JBRnVuY05hbWVdID0gbmV3IEdsc2xMaWJSb3V0aW5lKGZsb2F0VGV4dHVyZVNldFJHQkFTb3VyY2UpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogR2VuZXJhdGVzIGNvZGUgZm9yIHVucGFja2VkIG91dHB1dCBzYW1wbGVyLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFVucGFja2VkT3V0cHV0U2FtcGxpbmdTbmlwcGV0KG91dHB1dExheW91dDogVGV4dHVyZUxheW91dCk6IHtbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmV9IHtcbiAgICBjb25zdCBvdXRTaGFwZSA9IG91dHB1dExheW91dC51bnBhY2tlZFNoYXBlO1xuICAgIGNvbnN0IG91dFRleFNoYXBlID0gW291dHB1dExheW91dC53aWR0aCwgb3V0cHV0TGF5b3V0LmhlaWdodF07XG4gICAgY29uc3QgcmVzdWx0OiB7W25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lfSA9IHt9O1xuICAgIGNvbnN0IGZ1bmNOYW1lID0gJ2dldE91dHB1dENvb3Jkcyc7XG4gICAgc3dpdGNoIChvdXRTaGFwZS5sZW5ndGgpIHtcbiAgICAgIGNhc2UgMDpcbiAgICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IHRoaXMuZ2V0T3V0cHV0U2NhbGFyQ29vcmRzKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAxOlxuICAgICAgICByZXN1bHRbZnVuY05hbWVdID0gdGhpcy5nZXRPdXRwdXRVbnBhY2tlZDFEQ29vcmRzKG91dFNoYXBlIGFzIFtudW1iZXJdLCBvdXRUZXhTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXJdKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDI6XG4gICAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPVxuICAgICAgICAgICAgdGhpcy5nZXRPdXRwdXRVbnBhY2tlZDJEQ29vcmRzKG91dFNoYXBlIGFzIFtudW1iZXIsIG51bWJlcl0sIG91dFRleFNoYXBlIGFzIFtudW1iZXIsIG51bWJlcl0pO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzpcbiAgICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9XG4gICAgICAgICAgICB0aGlzLmdldE91dHB1dFVucGFja2VkM0RDb29yZHMob3V0U2hhcGUgYXMgW251bWJlciwgbnVtYmVyLCBudW1iZXJdLCBvdXRUZXhTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXJdKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDQ6XG4gICAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSB0aGlzLmdldE91dHB1dFVucGFja2VkNERDb29yZHMoXG4gICAgICAgICAgICBvdXRTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSwgb3V0VGV4U2hhcGUgYXMgW251bWJlciwgbnVtYmVyXSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA1OlxuICAgICAgICByZXN1bHRbZnVuY05hbWVdID0gdGhpcy5nZXRPdXRwdXRVbnBhY2tlZDVEQ29vcmRzKFxuICAgICAgICAgICAgb3V0U2hhcGUgYXMgW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSwgb3V0VGV4U2hhcGUgYXMgW251bWJlciwgbnVtYmVyXSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA2OlxuICAgICAgICByZXN1bHRbZnVuY05hbWVdID0gdGhpcy5nZXRPdXRwdXRVbnBhY2tlZDZEQ29vcmRzKFxuICAgICAgICAgICAgb3V0U2hhcGUgYXMgW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdLCBvdXRUZXhTaGFwZSBhcyBbbnVtYmVyLCBudW1iZXJdKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuc3VwcG9ydGVkIG91dHB1dCBkaW1lbnNpb25hbGl0eTogJHtvdXRTaGFwZS5sZW5ndGh9YCk7XG4gICAgfVxuICAgIGNvbnN0IGdsc2wgPSBnZXRHbHNsKHRoaXMuY29udGV4dC5nbENvbnRleHQudmVyc2lvbik7XG4gICAgLy8gVE9ETyB3ZSBuZWVkIHRoaXMgdG8gcHJvcGVybHkgcmV0dXJuIGEgcGFja2VkIHZlYzQgZnJvbSBrZXJuZWxzLlxuICAgIC8vIFJlcGxhY2UgYWxsICd7Z2xzbC5vdXRwdXR9ID0gcmVzdWx0JyB3aXRoICdzZXRPdXRwdXQocmVzdWx0KScgaW4gYWxsIGtlcm5lbHMuXG4gICAgY29uc3QgZmxvYXRUZXh0dXJlU2V0UlNvdXJjZSA9IGBcbiAgICAgICAgdm9pZCBzZXRPdXRwdXQoZmxvYXQgdmFsKSB7XG4gICAgICAgICAgJHtnbHNsLm91dHB1dH0gPSB2ZWM0KHZhbCwgMCwgMCwgMCk7XG4gICAgICAgIH1cbiAgICBgO1xuICAgIGNvbnN0IGZsb2F0VGV4dHVyZVNldFJGdW5jTmFtZSA9ICdmbG9hdFRleHR1cmVTZXRSJztcbiAgICByZXN1bHRbZmxvYXRUZXh0dXJlU2V0UkZ1bmNOYW1lXSA9IG5ldyBHbHNsTGliUm91dGluZShmbG9hdFRleHR1cmVTZXRSU291cmNlKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIFNjYWxhciBvdXRwdXQgY29vcmRpbmF0ZXMuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0T3V0cHV0U2NhbGFyQ29vcmRzKCk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKGBcbiAgICAgIGludCBnZXRPdXRwdXRDb29yZHMoKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgICAgfVxuICAgIGApO1xuICB9XG5cbiAgLyoqXG4gICAqIDFEIHBhY2tlZCBvdXRwdXQgY29vcmRpbmF0ZXMuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0T3V0cHV0UGFja2VkMURDb29yZHMoc2hhcGU6IFtudW1iZXJdLCB0ZXhTaGFwZTogW251bWJlciwgbnVtYmVyXSk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBwYWNrZWRUZXhTaGFwZSA9IHRleFNoYXBlO1xuICAgIGxldCBzb3VyY2UgPSAnJztcbiAgICBpZiAocGFja2VkVGV4U2hhcGVbMF0gPT09IDEpIHtcbiAgICAgIHNvdXJjZSA9IGBcbiAgICAgICAgICBpbnQgZ2V0T3V0cHV0Q29vcmRzKCkge1xuICAgICAgICAgICAgcmV0dXJuIDIgKiBpbnQoVGV4Q29vcmRzLnkgKiAke3BhY2tlZFRleFNoYXBlWzFdfS4wKTtcbiAgICAgICAgICB9XG4gICAgICAgIGA7XG4gICAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSk7XG4gICAgfVxuXG4gICAgaWYgKHBhY2tlZFRleFNoYXBlWzFdID09PSAxKSB7XG4gICAgICBzb3VyY2UgPSBgXG4gICAgICAgICAgaW50IGdldE91dHB1dENvb3JkcygpIHtcbiAgICAgICAgICAgIHJldHVybiAyICogaW50KFRleENvb3Jkcy54ICogJHtwYWNrZWRUZXhTaGFwZVswXX0uMCk7XG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UpO1xuICAgIH1cblxuICAgIHNvdXJjZSA9IGBcbiAgICAgICAgaW50IGdldE91dHB1dENvb3JkcygpIHtcbiAgICAgICAgICBpdmVjMiByZXNUZXhSQyA9IGl2ZWMyKFRleENvb3Jkcy54eSAqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKCR7cGFja2VkVGV4U2hhcGVbMF19LCAke3BhY2tlZFRleFNoYXBlWzFdfSkpO1xuICAgICAgICAgIHJldHVybiAyICogKHJlc1RleFJDLnkgKiAke3BhY2tlZFRleFNoYXBlWzBdfSArIHJlc1RleFJDLngpO1xuICAgICAgICB9XG4gICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiAyRCBwYWNrZWQgb3V0cHV0IGNvb3JkaW5hdGVzLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldE91dHB1dFBhY2tlZDJEQ29vcmRzKHNoYXBlOiBbbnVtYmVyLCBudW1iZXJdLCB0ZXhTaGFwZTogW251bWJlciwgbnVtYmVyXSk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBsZXQgc291cmNlID0gJyc7XG4gICAgaWYgKEFycmF5VXRpbC5hcnJheXNFcXVhbChzaGFwZSwgdGV4U2hhcGUpKSB7XG4gICAgICBzb3VyY2UgPSBgXG4gICAgICAgIGl2ZWMyIGdldE91dHB1dENvb3JkcygpIHtcbiAgICAgICAgICByZXR1cm4gMiAqIGl2ZWMyKFRleENvb3Jkcy54eSAqIHZlYzIoJHt0ZXhTaGFwZVswXX0sICR7dGV4U2hhcGVbMV19KSk7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSk7XG4gICAgfVxuXG4gICAgY29uc3QgcGFja2VkVGV4U2hhcGUgPSB0ZXhTaGFwZTtcbiAgICAvLyB0ZXhlbHMgbmVlZGVkIHRvIGFjY29tbW9kYXRlIGEgbG9naWNhbCByb3dcbiAgICBjb25zdCB0ZXhlbHNJbkxvZ2ljYWxSb3cgPSBNYXRoLmNlaWwoc2hhcGVbMV0gLyAyKTtcblxuICAgIC8qKlxuICAgICAqIGdldE91dHB1dENvb3Jkc1xuICAgICAqXG4gICAgICogcmVzVGV4UkM6IFRoZSByb3dzIGFuZCBjb2x1bW5zIG9mIHRoZSB0ZXhlbHMuIElmIHlvdSBtb3ZlIG92ZXIgb25lXG4gICAgICogdGV4ZWwgdG8gdGhlIHJpZ2h0IGluIHRoZSBwYWNrZWQgdGV4dHVyZSwgeW91IGFyZSBtb3Zpbmcgb3ZlciBvbmUgY29sdW1uXG4gICAgICogKG5vdCB0d28pLlxuICAgICAqXG4gICAgICogaW5kZXg6IFRoZSB0ZXhlbCBpbmRleFxuICAgICAqL1xuICAgIHNvdXJjZSA9IGBcbiAgICAgICAgaXZlYzIgZ2V0T3V0cHV0Q29vcmRzKCkge1xuICAgICAgICAgIGl2ZWMyIHJlc1RleFJDID0gaXZlYzIoVGV4Q29vcmRzLnh5ICpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjMigke3BhY2tlZFRleFNoYXBlWzBdfSwgJHtwYWNrZWRUZXhTaGFwZVsxXX0pKTtcblxuICAgICAgICAgIGludCBpbmRleCA9IHJlc1RleFJDLnkgKiAke3BhY2tlZFRleFNoYXBlWzBdfSArIHJlc1RleFJDLng7XG5cbiAgICAgICAgICAvLyByZXZlcnNlIHIgYW5kIGMgb3JkZXIgZm9yIHBhY2tlZCB0ZXh0dXJlXG4gICAgICAgICAgaW50IHIgPSBpbW9kKGluZGV4LCAke3RleGVsc0luTG9naWNhbFJvd30pICogMjtcbiAgICAgICAgICBpbnQgYyA9IDIgKiAoaW5kZXggLyAke3RleGVsc0luTG9naWNhbFJvd30pO1xuXG4gICAgICAgICAgcmV0dXJuIGl2ZWMyKHIsIGMpO1xuICAgICAgICB9XG4gICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiAzRCBwYWNrZWQgb3V0cHV0IGNvb3JkaW5hdGVzLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldE91dHB1dFBhY2tlZDNEQ29vcmRzKHNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sIHRleFNoYXBlOiBbbnVtYmVyLCBudW1iZXJdKTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IHBhY2tlZFRleFNoYXBlID0gW3RleFNoYXBlWzBdLCB0ZXhTaGFwZVsxXV07XG4gICAgY29uc3QgdGV4ZWxzSW5Mb2dpY2FsUm93ID0gTWF0aC5jZWlsKHNoYXBlWzJdIC8gMik7XG4gICAgY29uc3QgdGV4ZWxzSW5CYXRjaCA9IHRleGVsc0luTG9naWNhbFJvdyAqIE1hdGguY2VpbChzaGFwZVsxXSAvIDIpO1xuICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgaXZlYzMgZ2V0T3V0cHV0Q29vcmRzKCkge1xuICAgICAgICAgIGl2ZWMyIHJlc1RleFJDID0gaXZlYzIoVGV4Q29vcmRzLnh5ICpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjMigke3BhY2tlZFRleFNoYXBlWzBdfSwgJHtwYWNrZWRUZXhTaGFwZVsxXX0pKTtcbiAgICAgICAgICBpbnQgaW5kZXggPSByZXNUZXhSQy55ICogJHtwYWNrZWRUZXhTaGFwZVswXX0gKyByZXNUZXhSQy54O1xuXG4gICAgICAgICAgaW50IGIgPSBpbmRleCAvICR7dGV4ZWxzSW5CYXRjaH07XG4gICAgICAgICAgaW5kZXggLT0gYiAqICR7dGV4ZWxzSW5CYXRjaH07XG5cbiAgICAgICAgICAvLyByZXZlcnNlIHIgYW5kIGMgb3JkZXIgZm9yIHBhY2tlZCB0ZXh0dXJlXG4gICAgICAgICAgaW50IHIgPSBpbW9kKGluZGV4LCAke3RleGVsc0luTG9naWNhbFJvd30pICogMjtcbiAgICAgICAgICBpbnQgYyA9IDIgKiAoaW5kZXggLyAke3RleGVsc0luTG9naWNhbFJvd30pO1xuXG4gICAgICAgICAgcmV0dXJuIGl2ZWMzKGIsIHIsIGMpO1xuICAgICAgICB9XG4gICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBORCBwYWNrZWQgb3V0cHV0IGNvb3JkaW5hdGVzLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldE91dHB1dFBhY2tlZE5EQ29vcmRzKHNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgdGV4U2hhcGU6IFtudW1iZXIsIG51bWJlcl0pOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3QgcGFja2VkVGV4U2hhcGUgPSBbdGV4U2hhcGVbMF0sIHRleFNoYXBlWzFdXTtcblxuICAgIGNvbnN0IHRleGVsc0luTG9naWNhbFJvdyA9IE1hdGguY2VpbChzaGFwZVtzaGFwZS5sZW5ndGggLSAxXSAvIDIpO1xuICAgIGNvbnN0IHRleGVsc0luQmF0Y2ggPSB0ZXhlbHNJbkxvZ2ljYWxSb3cgKiBNYXRoLmNlaWwoc2hhcGVbc2hhcGUubGVuZ3RoIC0gMl0gLyAyKTtcbiAgICBsZXQgdGV4ZWxzSW5CYXRjaE4gPSB0ZXhlbHNJbkJhdGNoO1xuICAgIGxldCBiYXRjaGVzID0gJyc7XG4gICAgbGV0IGNvb3JkcyA9ICdiLCByLCBjJztcblxuICAgIGZvciAobGV0IGIgPSAyOyBiIDwgc2hhcGUubGVuZ3RoIC0gMTsgYisrKSB7XG4gICAgICB0ZXhlbHNJbkJhdGNoTiAqPSBzaGFwZVtzaGFwZS5sZW5ndGggLSBiIC0gMV07XG4gICAgICBiYXRjaGVzID0gYFxuICAgICAgaW50IGIke2J9ID0gaW5kZXggLyAke3RleGVsc0luQmF0Y2hOfTtcbiAgICAgIGluZGV4IC09IGIke2J9ICogJHt0ZXhlbHNJbkJhdGNoTn07XG4gICAgYCArIGJhdGNoZXM7XG4gICAgICBjb29yZHMgPSBgYiR7Yn0sIGAgKyBjb29yZHM7XG4gICAgfVxuICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgIGl2ZWMke3NoYXBlLmxlbmd0aH0gZ2V0T3V0cHV0Q29vcmRzKCkge1xuICAgICAgICBpdmVjMiByZXNUZXhSQyA9IGl2ZWMyKFRleENvb3Jkcy54eSAqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKCR7cGFja2VkVGV4U2hhcGVbMF19LCAke3BhY2tlZFRleFNoYXBlWzFdfSkpO1xuICAgICAgICBpbnQgaW5kZXggPSByZXNUZXhSQy55ICogJHtwYWNrZWRUZXhTaGFwZVswXX0gKyByZXNUZXhSQy54O1xuXG4gICAgICAgICR7YmF0Y2hlc31cblxuICAgICAgICBpbnQgYiA9IGluZGV4IC8gJHt0ZXhlbHNJbkJhdGNofTtcbiAgICAgICAgaW5kZXggLT0gYiAqICR7dGV4ZWxzSW5CYXRjaH07XG5cbiAgICAgICAgLy8gcmV2ZXJzZSByIGFuZCBjIG9yZGVyIGZvciBwYWNrZWQgdGV4dHVyZVxuICAgICAgICBpbnQgciA9IGltb2QoaW5kZXgsICR7dGV4ZWxzSW5Mb2dpY2FsUm93fSkgKiAyO1xuICAgICAgICBpbnQgYyA9IDIgKiAoaW5kZXggLyAke3RleGVsc0luTG9naWNhbFJvd30pO1xuXG4gICAgICAgIHJldHVybiBpdmVjJHtzaGFwZS5sZW5ndGh9KCR7Y29vcmRzfSk7XG4gICAgICB9XG4gICAgYDtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSk7XG4gIH1cblxuICAvKipcbiAgICogVW5wYWNrZWQgMUQgb3V0cHV0IGNvb3JkaW5hdGVzLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldE91dHB1dFVucGFja2VkMURDb29yZHMoc2hhcGU6IFtudW1iZXJdLCB0ZXhTaGFwZTogW251bWJlciwgbnVtYmVyXSk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgIGludCBnZXRPdXRwdXRDb29yZHMoKSB7XG4gICAgICAgICAgaXZlYzIgcmVzVGV4UkMgPSBpdmVjMihUZXhDb29yZHMueHkgKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKCR7dGV4U2hhcGVbMF19LCAke3RleFNoYXBlWzFdfSkpO1xuICAgICAgICAgIHJldHVybiByZXNUZXhSQy55ICogJHt0ZXhTaGFwZVswXX0gKyByZXNUZXhSQy54O1xuICAgICAgICB9XG4gICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnBhY2tlZCAyRCBvdXRwdXQgY29vcmRpbmF0ZXMuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0T3V0cHV0VW5wYWNrZWQyRENvb3JkcyhzaGFwZTogW251bWJlciwgbnVtYmVyXSwgdGV4U2hhcGU6IFtudW1iZXIsIG51bWJlcl0pOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICBpdmVjMiBnZXRPdXRwdXRDb29yZHMoKSB7XG4gICAgICAgICAgaXZlYzIgcmVzVGV4UkMgPSBpdmVjMihUZXhDb29yZHMueHkgKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKCR7dGV4U2hhcGVbMF19LCAke3RleFNoYXBlWzFdfSkpO1xuICAgICAgICAgIGludCBpbmRleCA9IHJlc1RleFJDLnkgKiAke3RleFNoYXBlWzBdfSArIHJlc1RleFJDLng7XG4gICAgICAgICAgaW50IHIgPSBpbmRleCAvICR7c2hhcGVbMV19O1xuICAgICAgICAgIGludCBjID0gaW5kZXggLSByICogJHtzaGFwZVsxXX07XG4gICAgICAgICAgcmV0dXJuIGl2ZWMyKHIsIGMpO1xuICAgICAgICB9XG4gICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnBhY2tlZCAzRCBvdXRwdXQgY29vcmRpbmF0ZXMuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0T3V0cHV0VW5wYWNrZWQzRENvb3JkcyhzaGFwZTogW251bWJlciwgbnVtYmVyLCBudW1iZXJdLCB0ZXhTaGFwZTogW251bWJlciwgbnVtYmVyXSk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBsZXQgc291cmNlID0gJyc7XG4gICAgY29uc3QgcmFuayA9IHNoYXBlLmxlbmd0aDtcblxuICAgIGxldCBzdHJpZGVzID0gbnVsbDtcbiAgICBpZiAocmFuayA8IDIpIHtcbiAgICAgIHN0cmlkZXMgPSBbXTtcbiAgICB9XG5cbiAgICBzdHJpZGVzID0gbmV3IEFycmF5KHJhbmsgLSAxKTtcbiAgICBzdHJpZGVzW3JhbmsgLSAyXSA9IHNoYXBlW3JhbmsgLSAxXTtcbiAgICBmb3IgKGxldCBpID0gcmFuayAtIDM7IGkgPj0gMDsgLS1pKSB7XG4gICAgICBzdHJpZGVzW2ldID0gc3RyaWRlc1tpICsgMV0gKiBzaGFwZVtpICsgMV07XG4gICAgfVxuICAgIGNvbnN0IGNvb3Jkc1RvQ29tcHV0ZSA9IFsncicsICdjJywgJ2QnXTtcbiAgICBjb25zdCBjb29yZHNGcm9tSW5kZXhTbmlwcGV0ID1cbiAgICAgICAgc3RyaWRlc1xuICAgICAgICAgICAgLm1hcCgoc3RyaWRlLCBpKSA9PiB7XG4gICAgICAgICAgICAgIGNvbnN0IGxpbmUxID0gYGludCAke2Nvb3Jkc1RvQ29tcHV0ZVtpXX0gPSBpbmRleCAvICR7c3RyaWRlfWA7XG4gICAgICAgICAgICAgIGNvbnN0IGxpbmUyID0gaSA9PT0gc3RyaWRlcy5sZW5ndGggLSAxID9cbiAgICAgICAgICAgICAgICAgIGBpbnQgJHtjb29yZHNUb0NvbXB1dGVbaSArIDFdfSA9IGluZGV4IC0gJHtjb29yZHNUb0NvbXB1dGVbaV19ICogJHtzdHJpZGV9YCA6XG4gICAgICAgICAgICAgICAgICBgaW5kZXggLT0gJHtjb29yZHNUb0NvbXB1dGVbaV19ICogJHtzdHJpZGV9YDtcbiAgICAgICAgICAgICAgcmV0dXJuIGAke2xpbmUxfTsgJHtsaW5lMn07YDtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuam9pbignJyk7XG5cbiAgICBzb3VyY2UgPSBgXG4gICAgICAgIGl2ZWMzIGdldE91dHB1dENvb3JkcygpIHtcbiAgICAgICAgICBpdmVjMiByZXNUZXhSQyA9IGl2ZWMyKFRleENvb3Jkcy54eSAqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlYzIoJHt0ZXhTaGFwZVswXX0sICR7dGV4U2hhcGVbMV19KSk7XG4gICAgICAgICAgaW50IGluZGV4ID0gcmVzVGV4UkMueSAqICR7dGV4U2hhcGVbMF19ICsgcmVzVGV4UkMueDtcbiAgICAgICAgICAke2Nvb3Jkc0Zyb21JbmRleFNuaXBwZXR9XG4gICAgICAgICAgcmV0dXJuIGl2ZWMzKHIsIGMsIGQpO1xuICAgICAgICB9XG4gICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnBhY2tlZCA0RCBvdXRwdXQgY29vcmRpbmF0ZXMuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0T3V0cHV0VW5wYWNrZWQ0RENvb3JkcyhzaGFwZTogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0sIHRleFNoYXBlOiBbbnVtYmVyLCBudW1iZXJdKTpcbiAgICAgIEdsc2xMaWJSb3V0aW5lIHtcbiAgICBsZXQgc291cmNlID0gJyc7XG4gICAgY29uc3QgcmFuayA9IHNoYXBlLmxlbmd0aDtcblxuICAgIGxldCBzdHJpZGVzID0gbnVsbDtcbiAgICBpZiAocmFuayA8IDIpIHtcbiAgICAgIHN0cmlkZXMgPSBbXTtcbiAgICB9XG5cbiAgICBzdHJpZGVzID0gbmV3IEFycmF5KHJhbmsgLSAxKTtcbiAgICBzdHJpZGVzW3JhbmsgLSAyXSA9IHNoYXBlW3JhbmsgLSAxXTtcbiAgICBmb3IgKGxldCBpID0gcmFuayAtIDM7IGkgPj0gMDsgLS1pKSB7XG4gICAgICBzdHJpZGVzW2ldID0gc3RyaWRlc1tpICsgMV0gKiBzaGFwZVtpICsgMV07XG4gICAgfVxuICAgIGNvbnN0IGNvb3Jkc1RvQ29tcHV0ZSA9IFsncicsICdjJywgJ2QnLCAnZDInXTtcbiAgICBjb25zdCBjb29yZHNGcm9tSW5kZXhTbmlwcGV0ID1cbiAgICAgICAgc3RyaWRlc1xuICAgICAgICAgICAgLm1hcCgoc3RyaWRlLCBpKSA9PiB7XG4gICAgICAgICAgICAgIGNvbnN0IGxpbmUxID0gYGludCAke2Nvb3Jkc1RvQ29tcHV0ZVtpXX0gPSBpbmRleCAvICR7c3RyaWRlfWA7XG4gICAgICAgICAgICAgIGNvbnN0IGxpbmUyID0gaSA9PT0gc3RyaWRlcy5sZW5ndGggLSAxID9cbiAgICAgICAgICAgICAgICAgIGBpbnQgJHtjb29yZHNUb0NvbXB1dGVbaSArIDFdfSA9IGluZGV4IC0gJHtjb29yZHNUb0NvbXB1dGVbaV19ICogJHtzdHJpZGV9YCA6XG4gICAgICAgICAgICAgICAgICBgaW5kZXggLT0gJHtjb29yZHNUb0NvbXB1dGVbaV19ICogJHtzdHJpZGV9YDtcbiAgICAgICAgICAgICAgcmV0dXJuIGAke2xpbmUxfTsgJHtsaW5lMn07YDtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuam9pbignJyk7XG5cbiAgICBzb3VyY2UgPSBgXG4gICAgICBpdmVjNCBnZXRPdXRwdXRDb29yZHMoKSB7XG4gICAgICAgICAgaXZlYzIgcmVzVGV4UkMgPSBpdmVjMihUZXhDb29yZHMueHkgKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZWMyKCR7dGV4U2hhcGVbMF19LCAke3RleFNoYXBlWzFdfSkpO1xuICAgICAgICAgIGludCBpbmRleCA9IHJlc1RleFJDLnkgKiAke3RleFNoYXBlWzBdfSArIHJlc1RleFJDLng7XG4gICAgICAgICAgJHtjb29yZHNGcm9tSW5kZXhTbmlwcGV0fVxuICAgICAgICAgIHJldHVybiBpdmVjNChyLCBjLCBkLCBkMik7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVucGFja2VkIDVEIG91dHB1dCBjb29yZGluYXRlcy5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRPdXRwdXRVbnBhY2tlZDVEQ29vcmRzKHNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdLCB0ZXhTaGFwZTogW251bWJlciwgbnVtYmVyXSk6XG4gICAgICBHbHNsTGliUm91dGluZSB7XG4gICAgbGV0IHNvdXJjZSA9ICcnO1xuICAgIGNvbnN0IHJhbmsgPSBzaGFwZS5sZW5ndGg7XG5cbiAgICBsZXQgc3RyaWRlcyA9IG51bGw7XG4gICAgaWYgKHJhbmsgPCAyKSB7XG4gICAgICBzdHJpZGVzID0gW107XG4gICAgfVxuXG4gICAgc3RyaWRlcyA9IG5ldyBBcnJheShyYW5rIC0gMSk7XG4gICAgc3RyaWRlc1tyYW5rIC0gMl0gPSBzaGFwZVtyYW5rIC0gMV07XG4gICAgZm9yIChsZXQgaSA9IHJhbmsgLSAzOyBpID49IDA7IC0taSkge1xuICAgICAgc3RyaWRlc1tpXSA9IHN0cmlkZXNbaSArIDFdICogc2hhcGVbaSArIDFdO1xuICAgIH1cbiAgICBjb25zdCBjb29yZHNUb0NvbXB1dGUgPSBbJ3InLCAnYycsICdkJywgJ2QyJywgJ2QzJ107XG4gICAgY29uc3QgY29vcmRzRnJvbUluZGV4U25pcHBldCA9XG4gICAgICAgIHN0cmlkZXNcbiAgICAgICAgICAgIC5tYXAoKHN0cmlkZSwgaSkgPT4ge1xuICAgICAgICAgICAgICBjb25zdCBsaW5lMSA9IGBpbnQgJHtjb29yZHNUb0NvbXB1dGVbaV19ID0gaW5kZXggLyAke3N0cmlkZX1gO1xuICAgICAgICAgICAgICBjb25zdCBsaW5lMiA9IGkgPT09IHN0cmlkZXMubGVuZ3RoIC0gMSA/XG4gICAgICAgICAgICAgICAgICBgaW50ICR7Y29vcmRzVG9Db21wdXRlW2kgKyAxXX0gPSBpbmRleCAtICR7Y29vcmRzVG9Db21wdXRlW2ldfSAqICR7c3RyaWRlfWAgOlxuICAgICAgICAgICAgICAgICAgYGluZGV4IC09ICR7Y29vcmRzVG9Db21wdXRlW2ldfSAqICR7c3RyaWRlfWA7XG4gICAgICAgICAgICAgIHJldHVybiBgJHtsaW5lMX07ICR7bGluZTJ9O2A7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmpvaW4oJycpO1xuXG4gICAgc291cmNlID0gYFxuICAgICAgaXZlYzUgZ2V0T3V0cHV0Q29vcmRzKCkge1xuICAgICAgICAgIGl2ZWMyIHJlc1RleFJDID0gaXZlYzIoVGV4Q29vcmRzLnh5ICpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVjMigke3RleFNoYXBlWzBdfSwgJHt0ZXhTaGFwZVsxXX0pKTtcbiAgICAgICAgICBpbnQgaW5kZXggPSByZXNUZXhSQy55ICogJHt0ZXhTaGFwZVswXX0gKyByZXNUZXhSQy54O1xuICAgICAgICAgICR7Y29vcmRzRnJvbUluZGV4U25pcHBldH1cbiAgICAgICAgICByZXR1cm4gaXZlYzUociwgYywgZCwgZDIsIGQzKTtcbiAgICAgICAgfVxuICAgICAgYDtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSk7XG4gIH1cblxuICAvKipcbiAgICogVW5wYWNrZWQgNkQgb3V0cHV0IGNvb3JkaW5hdGVzLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldE91dHB1dFVucGFja2VkNkRDb29yZHMoc2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSwgdGV4U2hhcGU6IFtcbiAgICBudW1iZXIsIG51bWJlclxuICBdKTogR2xzbExpYlJvdXRpbmUge1xuICAgIGxldCBzb3VyY2UgPSAnJztcbiAgICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuXG4gICAgbGV0IHN0cmlkZXMgPSBudWxsO1xuICAgIGlmIChyYW5rIDwgMikge1xuICAgICAgc3RyaWRlcyA9IFtdO1xuICAgIH1cblxuICAgIHN0cmlkZXMgPSBuZXcgQXJyYXkocmFuayAtIDEpO1xuICAgIHN0cmlkZXNbcmFuayAtIDJdID0gc2hhcGVbcmFuayAtIDFdO1xuICAgIGZvciAobGV0IGkgPSByYW5rIC0gMzsgaSA+PSAwOyAtLWkpIHtcbiAgICAgIHN0cmlkZXNbaV0gPSBzdHJpZGVzW2kgKyAxXSAqIHNoYXBlW2kgKyAxXTtcbiAgICB9XG4gICAgY29uc3QgY29vcmRzVG9Db21wdXRlID0gWydyJywgJ2MnLCAnZCcsICdkMicsICdkMycsICdkNCddO1xuICAgIGNvbnN0IGNvb3Jkc0Zyb21JbmRleFNuaXBwZXQgPVxuICAgICAgICBzdHJpZGVzXG4gICAgICAgICAgICAubWFwKChzdHJpZGUsIGkpID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgbGluZTEgPSBgaW50ICR7Y29vcmRzVG9Db21wdXRlW2ldfSA9IGluZGV4IC8gJHtzdHJpZGV9YDtcbiAgICAgICAgICAgICAgY29uc3QgbGluZTIgPSBpID09PSBzdHJpZGVzLmxlbmd0aCAtIDEgP1xuICAgICAgICAgICAgICAgICAgYGludCAke2Nvb3Jkc1RvQ29tcHV0ZVtpICsgMV19ID0gaW5kZXggLSAke2Nvb3Jkc1RvQ29tcHV0ZVtpXX0gKiAke3N0cmlkZX1gIDpcbiAgICAgICAgICAgICAgICAgIGBpbmRleCAtPSAke2Nvb3Jkc1RvQ29tcHV0ZVtpXX0gKiAke3N0cmlkZX1gO1xuICAgICAgICAgICAgICByZXR1cm4gYCR7bGluZTF9OyAke2xpbmUyfTtgO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5qb2luKCcnKTtcblxuICAgIHNvdXJjZSA9IGBcbiAgICAgaXZlYzYgZ2V0T3V0cHV0Q29vcmRzKCkge1xuICAgICAgICAgaXZlYzIgcmVzVGV4UkMgPSBpdmVjMihUZXhDb29yZHMueHkgKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlYzIoJHt0ZXhTaGFwZVswXX0sICR7dGV4U2hhcGVbMV19KSk7XG4gICAgICAgICBpbnQgaW5kZXggPSByZXNUZXhSQy55ICogJHt0ZXhTaGFwZVswXX0gKyByZXNUZXhSQy54O1xuICAgICAgICAgJHtjb29yZHNGcm9tSW5kZXhTbmlwcGV0fVxuICAgICAgICAgcmV0dXJuIGl2ZWM2KHIsIGMsIGQsIGQyLCBkMywgZDQpO1xuICAgICAgIH1cbiAgICAgYDtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSk7XG4gIH1cblxuICAvKipcbiAgICogR2VuZXJhdGVzIGNvZGUgZm9yIGNvbW1vbiBVViBjb29yZHMgY29tcHV0YXRpb24gdXRpbGl0eSBmdW5jdGlvbnMuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0Q29tbW9uVXRpbEZ1bmNzKCk6IHtbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmV9IHtcbiAgICBjb25zdCByZXN1bHQ6IHtbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmV9ID0ge307XG4gICAgbGV0IGZ1bmNOYW1lID0gJ3V2RnJvbUZsYXQnO1xuICAgIHJlc3VsdFtmdW5jTmFtZV0gPSBuZXcgR2xzbExpYlJvdXRpbmUoYFxuICAgIHZlYzIgdXZGcm9tRmxhdChpbnQgdGV4TnVtUiwgaW50IHRleE51bUMsIGludCBpbmRleCkge1xuICAgICAgaW50IHRleEMgPSBpbmRleCAvIHRleE51bVI7XG4gICAgICBpbnQgdGV4UiA9IGluZGV4IC0gdGV4QyAqIHRleE51bVI7XG4gICAgICAvLyBUT0RPOiBzd2FwIHRleFIsIHRleEMgb3JkZXIgaW4gZm9sbG93aW5nIGZ1bmN0aW9uIHNvIHJvdyBpcyBjb3JyZXNwb25kaW5nIHRvIHUgYW5kIGNvbHVtbiBpcyBjb3JyZXNwb25kaW5nIHRvXG4gICAgICAvLyAgICAgICB2LlxuICAgICAgcmV0dXJuICh2ZWMyKHRleFIsIHRleEMpICsgaGFsZkNSKSAvIHZlYzIodGV4TnVtUiwgdGV4TnVtQyk7XG4gICAgfVxuICAgIGApO1xuICAgIGZ1bmNOYW1lID0gJ3BhY2tlZFVWZnJvbTFEJztcbiAgICByZXN1bHRbZnVuY05hbWVdID0gbmV3IEdsc2xMaWJSb3V0aW5lKGBcbiAgICAgIHZlYzIgcGFja2VkVVZmcm9tMUQoaW50IHRleE51bVIsIGludCB0ZXhOdW1DLCBpbnQgaW5kZXgpIHtcbiAgICAgICAgaW50IHRleGVsSW5kZXggPSBpbmRleCAvIDI7XG4gICAgICAgIGludCB0ZXhSID0gdGV4ZWxJbmRleCAvIHRleE51bUM7XG4gICAgICAgIGludCB0ZXhDID0gdGV4ZWxJbmRleCAtIHRleFIgKiB0ZXhOdW1DO1xuICAgICAgICByZXR1cm4gKHZlYzIodGV4QywgdGV4UikgKyBoYWxmQ1IpIC8gdmVjMih0ZXhOdW1DLCB0ZXhOdW1SKTtcbiAgICAgIH1cbiAgICAgIGApO1xuICAgIGZ1bmNOYW1lID0gJ3BhY2tlZFVWZnJvbTJEJztcbiAgICByZXN1bHRbZnVuY05hbWVdID0gbmV3IEdsc2xMaWJSb3V0aW5lKGBcbiAgICAgIHZlYzIgcGFja2VkVVZmcm9tMkQoaW50IHRleE51bVIsIGludCB0ZXhOdW1DLCBpbnQgdGV4ZWxzSW5Mb2dpY2FsUm93LCBpbnQgcm93LCBpbnQgY29sKSB7XG4gICAgICAgIGludCB0ZXhlbEluZGV4ID0gKHJvdyAvIDIpICogdGV4ZWxzSW5Mb2dpY2FsUm93ICsgKGNvbCAvIDIpO1xuICAgICAgICBpbnQgdGV4UiA9IHRleGVsSW5kZXggLyB0ZXhOdW1DO1xuICAgICAgICBpbnQgdGV4QyA9IHRleGVsSW5kZXggLSB0ZXhSICogdGV4TnVtQztcbiAgICAgICAgcmV0dXJuICh2ZWMyKHRleEMsIHRleFIpICsgaGFsZkNSKSAvIHZlYzIodGV4TnVtQywgdGV4TnVtUik7XG4gICAgICB9XG4gICAgICBgKTtcbiAgICBmdW5jTmFtZSA9ICdwYWNrZWRVVmZyb20zRCc7XG4gICAgcmVzdWx0W2Z1bmNOYW1lXSA9IG5ldyBHbHNsTGliUm91dGluZShgXG4gICAgICB2ZWMyIHBhY2tlZFVWZnJvbTNEKGludCB0ZXhOdW1SLCBpbnQgdGV4TnVtQyxcbiAgICAgICAgICBpbnQgdGV4ZWxzSW5CYXRjaCwgaW50IHRleGVsc0luTG9naWNhbFJvdywgaW50IGIsXG4gICAgICAgICAgaW50IHJvdywgaW50IGNvbCkge1xuICAgICAgICBpbnQgaW5kZXggPSBiICogdGV4ZWxzSW5CYXRjaCArIChyb3cgLyAyKSAqIHRleGVsc0luTG9naWNhbFJvdyArIChjb2wgLyAyKTtcbiAgICAgICAgaW50IHRleFIgPSBpbmRleCAvIHRleE51bUM7XG4gICAgICAgIGludCB0ZXhDID0gaW5kZXggLSB0ZXhSICogdGV4TnVtQztcbiAgICAgICAgcmV0dXJuICh2ZWMyKHRleEMsIHRleFIpICsgaGFsZkNSKSAvIHZlYzIodGV4TnVtQywgdGV4TnVtUik7XG4gICAgICB9XG4gICAgICBgKTtcbiAgICBmdW5jTmFtZSA9ICdzYW1wbGVUZXh0dXJlJztcbiAgICBjb25zdCBnbHNsID0gZ2V0R2xzbCh0aGlzLmNvbnRleHQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICAgIHJlc3VsdFtmdW5jTmFtZV0gPSBuZXcgR2xzbExpYlJvdXRpbmUoYFxuICAgICAgICBmbG9hdCBzYW1wbGVUZXh0dXJlKHNhbXBsZXIyRCB0ZXh0dXJlU2FtcGxlciwgdmVjMiB1dikge1xuICAgICAgICAgICAgcmV0dXJuICR7Z2xzbC50ZXh0dXJlMkR9KHRleHR1cmVTYW1wbGVyLCB1dikucjtcbiAgICAgICAgfWApO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogQ29uc3RydWN0aW5nIHNuaXBwZXRzIGZvciBpbnB1dHNcbiAgICovXG4gIHByb3RlY3RlZCBnZXRJbnB1dHNTYW1wbGluZ1NuaXBwZXRzKCk6IHtbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmV9IHtcbiAgICBjb25zdCByZXN1bHQ6IHtbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmV9ID0ge307XG4gICAgY29uc3Qgb3V0cHV0TGF5b3V0ID0gdGhpcy5jb250ZXh0Lm91dHB1dFRleHR1cmVMYXlvdXQ7XG4gICAgdGhpcy5jb250ZXh0LnByb2dyYW1JbmZvLmlucHV0TmFtZXMuZm9yRWFjaCgoc2FtcGxlck5hbWUsIGkpID0+IHtcbiAgICAgIGNvbnN0IGlucHV0TGF5b3V0ID0gdGhpcy5jb250ZXh0LmlucHV0VGV4dHVyZUxheW91dHNbaV07XG4gICAgICBjb25zdCBmdW5jTmFtZSA9IGdlbmVyYXRlU2hhZGVyRnVuY05hbWVGcm9tSW5wdXRTYW1wbGVyTmFtZShzYW1wbGVyTmFtZSk7XG4gICAgICBpZiAoaW5wdXRMYXlvdXQuaXNQYWNrZWQpIHtcbiAgICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IHRoaXMuZ2V0UGFja2VkU2FtcGxlckZyb21JbnB1dChmdW5jTmFtZSwgc2FtcGxlck5hbWUsIGlucHV0TGF5b3V0KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSB0aGlzLmdldFVucGFja2VkU2FtcGxlckZyb21JbnB1dChmdW5jTmFtZSwgc2FtcGxlck5hbWUsIGlucHV0TGF5b3V0KTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgb3V0Q29vcmRGdW5jTmFtZSA9IGdlbmVyYXRlU2hhZGVyRnVuY05hbWVGcm9tSW5wdXRTYW1wbGVyTmFtZUF0T3V0Q29vcmRzKHNhbXBsZXJOYW1lKTtcbiAgICAgIGlmIChpbnB1dExheW91dC51bnBhY2tlZFNoYXBlLmxlbmd0aCA8PSBvdXRwdXRMYXlvdXQudW5wYWNrZWRTaGFwZS5sZW5ndGgpIHtcbiAgICAgICAgaWYgKGlucHV0TGF5b3V0LmlzUGFja2VkKSB7XG4gICAgICAgICAgcmVzdWx0W291dENvb3JkRnVuY05hbWVdID1cbiAgICAgICAgICAgICAgdGhpcy5nZXRQYWNrZWRTYW1wbGVyQXRPdXRwdXRDb29yZHMob3V0Q29vcmRGdW5jTmFtZSwgaW5wdXRMYXlvdXQsIG91dHB1dExheW91dCwgc2FtcGxlck5hbWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlc3VsdFtvdXRDb29yZEZ1bmNOYW1lXSA9XG4gICAgICAgICAgICAgIHRoaXMuZ2V0VW5wYWNrZWRTYW1wbGVyQXRPdXRwdXRDb29yZHMob3V0Q29vcmRGdW5jTmFtZSwgaW5wdXRMYXlvdXQsIG91dHB1dExheW91dCwgc2FtcGxlck5hbWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdGluZyBzbmlwcGV0cyBmb3Igb3V0cHV0IGNvb3JkaW5hdGVzIG9mIHNhbXBsZXJzXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0UGFja2VkU2FtcGxlckF0T3V0cHV0Q29vcmRzKFxuICAgICAgZnVuY05hbWU6IHN0cmluZywgaW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQsIG91dHB1dExheW91dDogVGV4dHVyZUxheW91dCwgbmFtZTogc3RyaW5nKTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IGluU2hhcGUgPSBpbnB1dExheW91dC51bnBhY2tlZFNoYXBlO1xuICAgIGNvbnN0IG91dFNoYXBlID0gb3V0cHV0TGF5b3V0LnVucGFja2VkU2hhcGU7XG4gICAgY29uc3QgdGV4TmFtZSA9IG5hbWU7XG4gICAgY29uc3QgdGV4RnVuY1NuaXBwZXQgPSBnZW5lcmF0ZVNoYWRlckZ1bmNOYW1lRnJvbUlucHV0U2FtcGxlck5hbWUodGV4TmFtZSk7XG5cbiAgICBjb25zdCBpblJhbmsgPSBpblNoYXBlLmxlbmd0aDtcbiAgICBjb25zdCBvdXRSYW5rID0gb3V0U2hhcGUubGVuZ3RoO1xuXG4gICAgY29uc3QgYnJvYWRjYXN0RGltcyA9IEJyb2FkY2FzdFV0aWwuZ2V0QnJvYWRjYXN0RGltcyhpblNoYXBlLCBvdXRTaGFwZSk7XG5cbiAgICBjb25zdCB0eXBlID0gZ2V0Q29vcmRzRGF0YVR5cGUob3V0UmFuayk7XG4gICAgY29uc3QgcmFua0RpZmYgPSBvdXRSYW5rIC0gaW5SYW5rO1xuICAgIGxldCBjb29yZHNTbmlwcGV0OiBzdHJpbmc7XG4gICAgY29uc3QgZmllbGRzID0gZ2V0R2xDaGFubmVscygpO1xuXG4gICAgaWYgKGluUmFuayA9PT0gMCkge1xuICAgICAgY29vcmRzU25pcHBldCA9ICcnO1xuICAgIH0gZWxzZSBpZiAob3V0UmFuayA8IDIgJiYgYnJvYWRjYXN0RGltcy5sZW5ndGggPj0gMSkge1xuICAgICAgY29vcmRzU25pcHBldCA9ICdjb29yZHMgPSAwOyc7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvb3Jkc1NuaXBwZXQgPSBicm9hZGNhc3REaW1zLm1hcChkID0+IGBjb29yZHMuJHtmaWVsZHNbZCArIHJhbmtEaWZmXX0gPSAwO2ApLmpvaW4oJ1xcbicpO1xuICAgIH1cbiAgICBsZXQgdW5wYWNrZWRDb29yZHNTbmlwcGV0ID0gJyc7XG4gICAgaWYgKG91dFJhbmsgPCAyICYmIGluUmFuayA+IDApIHtcbiAgICAgIHVucGFja2VkQ29vcmRzU25pcHBldCA9ICdjb29yZHMnO1xuICAgIH0gZWxzZSB7XG4gICAgICB1bnBhY2tlZENvb3Jkc1NuaXBwZXQgPSBpblNoYXBlLm1hcCgocywgaSkgPT4gYGNvb3Jkcy4ke2ZpZWxkc1tpICsgcmFua0RpZmZdfWApLmpvaW4oJywgJyk7XG4gICAgfVxuXG4gICAgbGV0IG91dHB1dCA9ICdyZXR1cm4gb3V0cHV0VmFsdWU7JztcbiAgICBjb25zdCBpblNpemUgPSBTaGFwZVV0aWwuc2l6ZShpblNoYXBlKTtcbiAgICBjb25zdCBpc0lucHV0U2NhbGFyID0gaW5TaXplID09PSAxO1xuICAgIGNvbnN0IG91dFNpemUgPSBTaGFwZVV0aWwuc2l6ZShvdXRTaGFwZSk7XG4gICAgY29uc3QgaXNPdXRwdXRTY2FsYXIgPSBvdXRTaXplID09PSAxO1xuXG4gICAgaWYgKGluUmFuayA9PT0gMSAmJiAhaXNJbnB1dFNjYWxhciAmJiAhaXNPdXRwdXRTY2FsYXIpIHtcbiAgICAgIG91dHB1dCA9IGBcbiAgICAgICAgcmV0dXJuIHZlYzQob3V0cHV0VmFsdWUueHksIG91dHB1dFZhbHVlLnh5KTtcbiAgICAgIGA7XG4gICAgfSBlbHNlIGlmIChpc0lucHV0U2NhbGFyICYmICFpc091dHB1dFNjYWxhcikge1xuICAgICAgaWYgKG91dFJhbmsgPT09IDEpIHtcbiAgICAgICAgb3V0cHV0ID0gYFxuICAgICAgICAgIHJldHVybiB2ZWM0KG91dHB1dFZhbHVlLngsIG91dHB1dFZhbHVlLngsIDAuLCAwLik7XG4gICAgICAgIGA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvdXRwdXQgPSBgXG4gICAgICAgICAgcmV0dXJuIHZlYzQob3V0cHV0VmFsdWUueCk7XG4gICAgICAgIGA7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChicm9hZGNhc3REaW1zLmxlbmd0aCkge1xuICAgICAgY29uc3Qgcm93cyA9IGluUmFuayAtIDI7XG4gICAgICBjb25zdCBjb2xzID0gaW5SYW5rIC0gMTtcblxuICAgICAgaWYgKGJyb2FkY2FzdERpbXMuaW5kZXhPZihyb3dzKSA+IC0xICYmIGJyb2FkY2FzdERpbXMuaW5kZXhPZihjb2xzKSA+IC0xKSB7XG4gICAgICAgIG91dHB1dCA9ICdyZXR1cm4gdmVjNChvdXRwdXRWYWx1ZS54KTsnO1xuICAgICAgfSBlbHNlIGlmIChicm9hZGNhc3REaW1zLmluZGV4T2Yocm93cykgPiAtMSkge1xuICAgICAgICBvdXRwdXQgPSAncmV0dXJuIHZlYzQob3V0cHV0VmFsdWUueCwgb3V0cHV0VmFsdWUueSwgJyArXG4gICAgICAgICAgICAnb3V0cHV0VmFsdWUueCwgb3V0cHV0VmFsdWUueSk7JztcbiAgICAgIH0gZWxzZSBpZiAoYnJvYWRjYXN0RGltcy5pbmRleE9mKGNvbHMpID4gLTEpIHtcbiAgICAgICAgb3V0cHV0ID0gJ3JldHVybiB2ZWM0KG91dHB1dFZhbHVlLnh4LCBvdXRwdXRWYWx1ZS56eik7JztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBzd2FwTGFzdERpbXNTbmlwcGV0ID0gYFxuICAgICAgICBpbnQgbGFzdERpbSA9IGNvb3Jkcy4ke2ZpZWxkc1tvdXRSYW5rIC0gMV19O1xuICAgICAgICBjb29yZHMuJHtmaWVsZHNbb3V0UmFuayAtIDFdfSA9IGNvb3Jkcy4ke2ZpZWxkc1tvdXRSYW5rIC0gMl19O1xuICAgICAgICBjb29yZHMuJHtmaWVsZHNbb3V0UmFuayAtIDJdfSA9IGxhc3REaW07XG4gICAgICBgO1xuICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgIHZlYzQgJHtmdW5jTmFtZX0oKSB7XG4gICAgICAgICR7dHlwZX0gY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7XG4gICAgICAgICR7c3dhcExhc3REaW1zU25pcHBldH1cbiAgICAgICAgJHtjb29yZHNTbmlwcGV0fVxuICAgICAgICB2ZWM0IG91dHB1dFZhbHVlID0gJHt0ZXhGdW5jU25pcHBldH0oJHt1bnBhY2tlZENvb3Jkc1NuaXBwZXR9KTtcbiAgICAgICAgJHtvdXRwdXR9XG4gICAgICB9XG4gICAgYDtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgWydjb29yZGluYXRlcy5nZXRPdXRwdXRDb29yZHMnXSk7XG4gIH1cblxuICAvKipcbiAgICogQ29uc3RydWN0aW5nIHNuaXBwZXRzIGZvciB1bnBhY2tlZCBvdXRwdXQgY29vcmRpbmF0ZXMgb2Ygc2FtcGxlcnNcbiAgICovXG4gIHByb3RlY3RlZCBnZXRVbnBhY2tlZFNhbXBsZXJBdE91dHB1dENvb3JkcyhcbiAgICAgIGZ1bmNOYW1lOiBzdHJpbmcsIGlucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0LCBvdXRwdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQsIG5hbWU6IHN0cmluZyk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBvdXRUZXhTaGFwZSA9IFtvdXRwdXRMYXlvdXQud2lkdGgsIG91dHB1dExheW91dC5oZWlnaHRdO1xuICAgIGNvbnN0IGluVGV4U2hhcGUgPSBbaW5wdXRMYXlvdXQud2lkdGgsIGlucHV0TGF5b3V0LmhlaWdodF07XG4gICAgY29uc3QgaW5SYW5rID0gaW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZS5sZW5ndGg7XG4gICAgY29uc3Qgb3V0UmFuayA9IG91dHB1dExheW91dC51bnBhY2tlZFNoYXBlLmxlbmd0aDtcbiAgICBjb25zdCBpblNoYXBlID0gaW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZTtcbiAgICBjb25zdCBvdXRTaGFwZSA9IG91dHB1dExheW91dC51bnBhY2tlZFNoYXBlO1xuICAgIGNvbnN0IHRleEZ1bmNTbmlwcGV0ID0gZ2VuZXJhdGVTaGFkZXJGdW5jTmFtZUZyb21JbnB1dFNhbXBsZXJOYW1lKG5hbWUpO1xuXG4gICAgaWYgKGluUmFuayA9PT0gb3V0UmFuayAmJiBBcnJheVV0aWwuYXJyYXlzRXF1YWwoaW5UZXhTaGFwZSwgb3V0VGV4U2hhcGUpKSB7XG4gICAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oKSB7XG4gICAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCBUZXhDb29yZHMpO1xuICAgICAgICAgIH1cbiAgICAgICAgYDtcbiAgICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnNhbXBsZVRleHR1cmUnXSk7XG4gICAgfVxuXG4gICAgY29uc3QgdHlwZSA9IGdldENvb3Jkc0RhdGFUeXBlKG91dFJhbmspO1xuICAgIGNvbnN0IGJyb2FkY2FzdERpbXMgPSBCcm9hZGNhc3RVdGlsLmdldEJyb2FkY2FzdERpbXMoaW5TaGFwZSwgb3V0U2hhcGUpO1xuICAgIGNvbnN0IHJhbmtEaWZmID0gb3V0UmFuayAtIGluUmFuaztcbiAgICBsZXQgY29vcmRzU25pcHBldDogc3RyaW5nO1xuICAgIGNvbnN0IGZpZWxkcyA9IGdldEdsQ2hhbm5lbHMoKTtcblxuICAgIGlmIChpblJhbmsgPT09IDApIHtcbiAgICAgIGNvb3Jkc1NuaXBwZXQgPSAnJztcbiAgICB9IGVsc2UgaWYgKG91dFJhbmsgPCAyICYmIGJyb2FkY2FzdERpbXMubGVuZ3RoID49IDEpIHtcbiAgICAgIGNvb3Jkc1NuaXBwZXQgPSAnY29vcmRzID0gMDsnO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb29yZHNTbmlwcGV0ID0gYnJvYWRjYXN0RGltcy5tYXAoZCA9PiBgY29vcmRzLiR7ZmllbGRzW2QgKyByYW5rRGlmZl19ID0gMDtgKS5qb2luKCdcXG4nKTtcbiAgICB9XG4gICAgbGV0IHVucGFja2VkQ29vcmRzU25pcHBldCA9ICcnO1xuICAgIGlmIChvdXRSYW5rIDwgMiAmJiBpblJhbmsgPiAwKSB7XG4gICAgICB1bnBhY2tlZENvb3Jkc1NuaXBwZXQgPSAnY29vcmRzJztcbiAgICB9IGVsc2Uge1xuICAgICAgdW5wYWNrZWRDb29yZHNTbmlwcGV0ID0gaW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZS5tYXAoKHMsIGkpID0+IGBjb29yZHMuJHtmaWVsZHNbaSArIHJhbmtEaWZmXX1gKS5qb2luKCcsICcpO1xuICAgIH1cbiAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KCkge1xuICAgICAgICAgICR7dHlwZX0gY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7XG4gICAgICAgICAgJHtjb29yZHNTbmlwcGV0fVxuICAgICAgICAgIHJldHVybiAke3RleEZ1bmNTbmlwcGV0fSgke3VucGFja2VkQ29vcmRzU25pcHBldH0pO1xuICAgICAgICB9XG4gICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLmdldE91dHB1dENvb3JkcyddKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3Rpbmcgc25pcHBldHMgZm9yIHBhY2tlZCBvcGVyYXRpb25zLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFBhY2tlZFNhbXBsZXJGcm9tSW5wdXQoZnVuY05hbWU6IHN0cmluZywgbmFtZTogc3RyaW5nLCBpbnB1dExheW91dDogVGV4dHVyZUxheW91dCk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBzd2l0Y2ggKGlucHV0TGF5b3V0LnVucGFja2VkU2hhcGUubGVuZ3RoKSB7XG4gICAgICBjYXNlIDA6XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhY2tlZFNhbXBsZXJTY2FsYXIoZnVuY05hbWUsIG5hbWUpO1xuICAgICAgY2FzZSAxOlxuICAgICAgICByZXR1cm4gdGhpcy5nZXRQYWNrZWRTYW1wbGVyMUQoZnVuY05hbWUsIG5hbWUsIGlucHV0TGF5b3V0KTtcbiAgICAgIGNhc2UgMjpcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFja2VkU2FtcGxlcjJEKGZ1bmNOYW1lLCBuYW1lLCBpbnB1dExheW91dCk7XG4gICAgICBjYXNlIDM6XG4gICAgICAgIHJldHVybiB0aGlzLmdldFBhY2tlZFNhbXBsZXIzRChmdW5jTmFtZSwgbmFtZSwgaW5wdXRMYXlvdXQpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGFja2VkU2FtcGxlck5EKGZ1bmNOYW1lLCBuYW1lLCBpbnB1dExheW91dCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdGluZyBzbmlwcGV0cyBmb3IgdW5wYWNrZWQgb3BlcmF0aW9ucy5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRVbnBhY2tlZFNhbXBsZXJGcm9tSW5wdXQoZnVuY05hbWU6IHN0cmluZywgbmFtZTogc3RyaW5nLCBpbnB1dExheW91dDogVGV4dHVyZUxheW91dCk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBzaGFwZSA9IGlucHV0TGF5b3V0LnVucGFja2VkU2hhcGU7XG4gICAgc3dpdGNoIChzaGFwZS5sZW5ndGgpIHtcbiAgICAgIGNhc2UgMDpcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VW5wYWNrZWRTYW1wbGVyU2NhbGFyKGZ1bmNOYW1lLCBuYW1lLCBpbnB1dExheW91dCk7XG4gICAgICBjYXNlIDE6XG4gICAgICAgIHJldHVybiB0aGlzLmdldFVucGFja2VkU2FtcGxlcjFEKGZ1bmNOYW1lLCBuYW1lLCBpbnB1dExheW91dCk7XG4gICAgICBjYXNlIDI6XG4gICAgICAgIHJldHVybiB0aGlzLmdldFVucGFja2VkU2FtcGxlcjJEKGZ1bmNOYW1lLCBuYW1lLCBpbnB1dExheW91dCk7XG4gICAgICBjYXNlIDM6XG4gICAgICAgIHJldHVybiB0aGlzLmdldFVucGFja2VkU2FtcGxlcjNEKGZ1bmNOYW1lLCBuYW1lLCBpbnB1dExheW91dCk7XG4gICAgICBjYXNlIDQ6XG4gICAgICAgIHJldHVybiB0aGlzLmdldFVucGFja2VkU2FtcGxlcjREKGZ1bmNOYW1lLCBuYW1lLCBpbnB1dExheW91dCk7XG4gICAgICBjYXNlIDU6XG4gICAgICAgIHJldHVybiB0aGlzLmdldFVucGFja2VkU2FtcGxlcjVEKGZ1bmNOYW1lLCBuYW1lLCBpbnB1dExheW91dCk7XG4gICAgICBjYXNlIDY6XG4gICAgICAgIHJldHVybiB0aGlzLmdldFVucGFja2VkU2FtcGxlcjZEKGZ1bmNOYW1lLCBuYW1lLCBpbnB1dExheW91dCk7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICAvLyBUT0RPIHN1cHBvcnQgbW9yZSBkaW1lbnNpb25hbGl0aWVzXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgZGltZW5zaW9uICR7c2hhcGUubGVuZ3RofS1EYCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFBhY2tlZCBzY2FsYXIgc25pcHBldC5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRQYWNrZWRTYW1wbGVyU2NhbGFyKGZ1bmNOYW1lOiBzdHJpbmcsIG5hbWU6IHN0cmluZyk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBnbHNsID0gZ2V0R2xzbCh0aGlzLmNvbnRleHQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgICB2ZWM0ICR7ZnVuY05hbWV9KCkge1xuICAgICAgICAgICAgcmV0dXJuICR7Z2xzbC50ZXh0dXJlMkR9KCR7bmFtZX0sIGhhbGZDUik7XG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQYWNrZWQgMUQgc25pcHBldC5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRQYWNrZWRTYW1wbGVyMUQoZnVuY05hbWU6IHN0cmluZywgbmFtZTogc3RyaW5nLCBpbnB1dExheW91dDogVGV4dHVyZUxheW91dCk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCB0ZXhTaGFwZSA9IFtpbnB1dExheW91dC53aWR0aCwgaW5wdXRMYXlvdXQuaGVpZ2h0XTtcbiAgICBjb25zdCBwYWNrZWRUZXhTaGFwZSA9IFt0ZXhTaGFwZVsxXSwgdGV4U2hhcGVbMF1dO1xuICAgIGNvbnN0IGdsc2wgPSBnZXRHbHNsKHRoaXMuY29udGV4dC5nbENvbnRleHQudmVyc2lvbik7XG5cbiAgICBjb25zdCBwYWNrZWRTYW1wbGVyID0gYHZlYzQgJHtmdW5jTmFtZX0oaW50IGluZGV4KSB7XG4gICAgICB2ZWMyIHV2ID0gcGFja2VkVVZmcm9tMUQoXG4gICAgICAke3BhY2tlZFRleFNoYXBlWzBdfSwgJHtwYWNrZWRUZXhTaGFwZVsxXX0sIGluZGV4KTtcbiAgICAgIHJldHVybiAke2dsc2wudGV4dHVyZTJEfSgke25hbWV9LCB1dik7XG4gICAgfWA7XG4gICAgY29uc3Qgc291cmNlID0gcGFja2VkU2FtcGxlcjtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgWydjb29yZGluYXRlcy5wYWNrZWRVVmZyb20xRCddKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQYWNrZWQgMkQgc25pcHBldC5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRQYWNrZWRTYW1wbGVyMkQoZnVuY05hbWU6IHN0cmluZywgbmFtZTogc3RyaW5nLCBpbnB1dExheW91dDogVGV4dHVyZUxheW91dCk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBzaGFwZSA9IGlucHV0TGF5b3V0LnVucGFja2VkU2hhcGU7XG4gICAgY29uc3QgdGV4U2hhcGUgPSBbaW5wdXRMYXlvdXQud2lkdGgsIGlucHV0TGF5b3V0LmhlaWdodF07XG4gICAgY29uc3QgZ2xzbCA9IGdldEdsc2wodGhpcy5jb250ZXh0LmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgICBjb25zdCB0ZXhOdW1SID0gdGV4U2hhcGVbMF07XG4gICAgY29uc3QgdGV4TnVtQyA9IHRleFNoYXBlWzFdO1xuXG4gICAgaWYgKHRleFNoYXBlICE9IG51bGwgJiYgQXJyYXlVdGlsLmFycmF5c0VxdWFsKHNoYXBlLCB0ZXhTaGFwZSkpIHtcbiAgICAgIGNvbnN0IHBhY2tlZFNhbXBsZXIgPSBgdmVjNCAke2Z1bmNOYW1lfShpbnQgcm93LCBpbnQgY29sKSB7XG4gICAgICAgIHZlYzIgdXYgPSAodmVjMihjb2wsIHJvdykgKyBoYWxmQ1IpIC8gdmVjMigke3RleE51bUN9LjAsICR7dGV4TnVtUn0uMCk7XG4gICAgICAgIHJldHVybiAke2dsc2wudGV4dHVyZTJEfSgke25hbWV9LCB1dik7XG4gICAgICB9YDtcblxuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShwYWNrZWRTYW1wbGVyKTtcbiAgICB9XG4gICAgY29uc3QgcGFja2VkVGV4U2hhcGUgPSB0ZXhTaGFwZTtcbiAgICBjb25zdCB2YWx1ZXNQZXJSb3cgPSBNYXRoLmNlaWwoc2hhcGVbMV0gLyAyKTtcbiAgICBjb25zdCBwYWNrZWRTYW1wbGVyID0gYHZlYzQgJHtmdW5jTmFtZX0oaW50IHJvdywgaW50IGNvbCkge1xuICAgICAgdmVjMiB1diA9IHBhY2tlZFVWZnJvbTJEKCR7cGFja2VkVGV4U2hhcGVbMV19LCAke3BhY2tlZFRleFNoYXBlWzBdfSwgJHt2YWx1ZXNQZXJSb3d9LCByb3csIGNvbCk7XG4gICAgICByZXR1cm4gJHtnbHNsLnRleHR1cmUyRH0oJHtuYW1lfSwgdXYpO1xuICAgIH1gO1xuICAgIGNvbnN0IHNvdXJjZSA9IHBhY2tlZFNhbXBsZXI7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMucGFja2VkVVZmcm9tMkQnXSk7XG4gIH1cblxuICAvKipcbiAgICogUGFja2VkIDNEIHNuaXBwZXQuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0UGFja2VkU2FtcGxlcjNEKGZ1bmNOYW1lOiBzdHJpbmcsIG5hbWU6IHN0cmluZywgaW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQpOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3Qgc2hhcGUgPSBpbnB1dExheW91dC51bnBhY2tlZFNoYXBlO1xuICAgIGNvbnN0IHRleFNoYXBlID0gW2lucHV0TGF5b3V0LndpZHRoLCBpbnB1dExheW91dC5oZWlnaHRdO1xuICAgIGNvbnN0IHBhY2tlZFRleFNoYXBlID0gW3RleFNoYXBlWzBdLCB0ZXhTaGFwZVsxXV07XG4gICAgY29uc3QgZ2xzbCA9IGdldEdsc2wodGhpcy5jb250ZXh0LmdsQ29udGV4dC52ZXJzaW9uKTtcblxuICAgIGlmIChzaGFwZVswXSA9PT0gMSkge1xuICAgICAgY29uc3Qgc3F1ZWV6ZWRTaGFwZSA9IHNoYXBlLnNsaWNlKDEpO1xuICAgICAgY29uc3Qga2VwdERpbXMgPSBbMSwgMl07XG4gICAgICBjb25zdCBuZXdJbnB1dFNoYXBlID0gc3F1ZWV6ZUlucHV0U2hhcGUoc2hhcGUsIHNxdWVlemVkU2hhcGUpO1xuICAgICAgY29uc3QgcGFyYW1zID0gWydiJywgJ3JvdycsICdjb2wnXTtcbiAgICAgIC8vIERlZXAgY29weSBvZiBpbnB1dCB0ZXh0dXJlIGxheW91dC5cbiAgICAgIGNvbnN0IG5ld0lucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0ID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShpbnB1dExheW91dCkpO1xuICAgICAgbmV3SW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZSA9IG5ld0lucHV0U2hhcGU7XG4gICAgICBjb25zdCBzYW1wbGVyUm91dGluZSA9IHRoaXMuZ2V0UGFja2VkU2FtcGxlckZyb21JbnB1dChmdW5jTmFtZSwgbmFtZSwgbmV3SW5wdXRMYXlvdXQpO1xuICAgICAgY29uc3QgcGFja2VkU2FtcGxlciA9IGAke3NhbXBsZXJSb3V0aW5lLnJvdXRpbmVCb2R5fVxuICAgICAgdmVjNCAke2Z1bmNOYW1lfShpbnQgYiwgaW50IHJvdywgaW50IGNvbCkge1xuICAgICAgICByZXR1cm4gJHtmdW5jTmFtZX0oJHtnZXRTcXVlZXplZFBhcmFtcyhwYXJhbXMsIGtlcHREaW1zKX0pO1xuICAgICAgfSBgO1xuICAgICAgY29uc3Qgc291cmNlID0gcGFja2VkU2FtcGxlcjtcbiAgICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBzYW1wbGVyUm91dGluZS5kZXBlbmRlbmNpZXMpO1xuICAgIH1cbiAgICBjb25zdCB0ZXhOdW1SID0gcGFja2VkVGV4U2hhcGVbMF07XG4gICAgY29uc3QgdGV4TnVtQyA9IHBhY2tlZFRleFNoYXBlWzFdO1xuXG4gICAgY29uc3QgdmFsdWVzUGVyUm93ID0gTWF0aC5jZWlsKHNoYXBlWzJdIC8gMik7XG4gICAgY29uc3QgdGV4ZWxzSW5CYXRjaCA9IHZhbHVlc1BlclJvdyAqIE1hdGguY2VpbChzaGFwZVsxXSAvIDIpO1xuXG4gICAgY29uc3QgcGFja2VkU2FtcGxlciA9IGB2ZWM0ICR7ZnVuY05hbWV9KGludCBiLCBpbnQgcm93LCBpbnQgY29sKSB7XG4gICAgICB2ZWMyIHV2ID0gcGFja2VkVVZmcm9tM0QoXG4gICAgICAgICR7dGV4TnVtQ30sICR7dGV4TnVtUn0sICR7dGV4ZWxzSW5CYXRjaH0sICR7dmFsdWVzUGVyUm93fSwgYiwgcm93LCBjb2wpO1xuICAgICAgcmV0dXJuICR7Z2xzbC50ZXh0dXJlMkR9KCR7bmFtZX0sIHV2KTt9YDtcbiAgICBjb25zdCBzb3VyY2UgPSBwYWNrZWRTYW1wbGVyO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnBhY2tlZFVWZnJvbTNEJ10pO1xuICB9XG4gIC8qXG4gICAqIFBhY2tlZCBORCBzbmlwcGV0LlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFBhY2tlZFNhbXBsZXJORChmdW5jTmFtZTogc3RyaW5nLCBuYW1lOiBzdHJpbmcsIGlucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0KTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IHNoYXBlID0gaW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZTtcbiAgICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuICAgIGNvbnN0IHRleFNoYXBlID0gW2lucHV0TGF5b3V0LndpZHRoLCBpbnB1dExheW91dC5oZWlnaHRdO1xuICAgIGNvbnN0IGdsc2wgPSBnZXRHbHNsKHRoaXMuY29udGV4dC5nbENvbnRleHQudmVyc2lvbik7XG5cbiAgICBjb25zdCBwYWNrZWRUZXhTaGFwZSA9IFt0ZXhTaGFwZVswXSwgdGV4U2hhcGVbMV1dO1xuICAgIGNvbnN0IHRleE51bVIgPSBwYWNrZWRUZXhTaGFwZVsxXTtcbiAgICBjb25zdCB0ZXhOdW1DID0gcGFja2VkVGV4U2hhcGVbMF07XG4gICAgY29uc3QgdmFsdWVzUGVyUm93ID0gTWF0aC5jZWlsKHNoYXBlW3JhbmsgLSAxXSAvIDIpO1xuICAgIGxldCB0ZXhlbHNJbkJhdGNoID0gdmFsdWVzUGVyUm93ICogTWF0aC5jZWlsKHNoYXBlW3JhbmsgLSAyXSAvIDIpO1xuICAgIGxldCBwYXJhbXMgPSAnaW50IGIsIGludCByb3csIGludCBjb2wnO1xuICAgIGxldCBpbmRleCA9IGBiICogJHt0ZXhlbHNJbkJhdGNofSArIChyb3cgLyAyKSAqICR7dmFsdWVzUGVyUm93fSArIChjb2wgLyAyKWA7XG4gICAgZm9yIChsZXQgYiA9IDI7IGIgPCByYW5rIC0gMTsgYisrKSB7XG4gICAgICBwYXJhbXMgPSBgaW50IGIke2J9LCBgICsgcGFyYW1zO1xuICAgICAgdGV4ZWxzSW5CYXRjaCAqPSBzaGFwZVtyYW5rIC0gYiAtIDFdO1xuICAgICAgaW5kZXggPSBgYiR7Yn0gKiAke3RleGVsc0luQmF0Y2h9ICsgYCArIGluZGV4O1xuICAgIH1cbiAgICBjb25zdCBwYWNrZWRTYW1wbGVyID0gYHZlYzQgJHtmdW5jTmFtZX0oJHtwYXJhbXN9KSB7XG4gICAgICBpbnQgaW5kZXggPSAke2luZGV4fTtcbiAgICAgIGludCB0ZXhSID0gaW5kZXggLyAke3RleE51bUN9O1xuICAgICAgaW50IHRleEMgPSBpbmRleCAtIHRleFIgKiAke3RleE51bUN9O1xuICAgICAgdmVjMiB1diA9ICh2ZWMyKHRleEMsIHRleFIpICsgaGFsZkNSKSAvIHZlYzIoJHt0ZXhOdW1DfSwgJHt0ZXhOdW1SfSk7XG4gICAgICByZXR1cm4gJHtnbHNsLnRleHR1cmUyRH0oJHtuYW1lfSwgdXYpO1xuICAgIH1gO1xuICAgIGNvbnN0IHNvdXJjZSA9IHBhY2tlZFNhbXBsZXI7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVucGFja2VkIHNjYWxhciBzbmlwcGV0LlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFVucGFja2VkU2FtcGxlclNjYWxhcihmdW5jTmFtZTogc3RyaW5nLCBuYW1lOiBzdHJpbmcsIGlucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0KTogR2xzbExpYlJvdXRpbmUge1xuICAgIGNvbnN0IFt0ZXhOdW1SLCB0ZXhOdW1DXSA9IFtpbnB1dExheW91dC53aWR0aCwgaW5wdXRMYXlvdXQuaGVpZ2h0XTtcbiAgICBpZiAodGV4TnVtUiA9PT0gMSAmJiB0ZXhOdW1DID09PSAxKSB7XG4gICAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oKSB7XG4gICAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCBoYWxmQ1IpO1xuICAgICAgICAgIH1cbiAgICAgICAgYDtcbiAgICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnNhbXBsZVRleHR1cmUnXSk7XG4gICAgfVxuXG4gICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfSgpIHtcbiAgICAgICAgICBpbnQgb2Zmc2V0XyR7bmFtZX0gPSBjb29yZHNUb09mZnNldChUZXhDb29yZHMsICR7dGV4TnVtUn0sICR7dGV4TnVtQ30pO1xuICAgICAgICAgIHZlYzIgdXYgPSB1dkZyb21GbGF0KCR7dGV4TnVtUn0sICR7dGV4TnVtQ30sIG9mZnNldF8ke25hbWV9KTtcbiAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCB1dik7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShcbiAgICAgICAgc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnV2RnJvbUZsYXQnLCAnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZScsICdjb29yZGluYXRlcy5jb29yZHNUb09mZnNldCddKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnBhY2tlZCAxRCBzbmlwcGV0LlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFVucGFja2VkU2FtcGxlcjFEKGZ1bmNOYW1lOiBzdHJpbmcsIG5hbWU6IHN0cmluZywgaW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQpOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3QgdE51bVIgPSBpbnB1dExheW91dC53aWR0aDtcbiAgICBjb25zdCB0TnVtQyA9IGlucHV0TGF5b3V0LmhlaWdodDtcblxuICAgIGlmICh0TnVtQyA9PT0gMSAmJiB0TnVtUiA9PT0gMSkge1xuICAgICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfShpbnQgaW5kZXgpIHtcbiAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCBoYWxmQ1IpO1xuICAgICAgICB9XG4gICAgICBgO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZSddKTtcbiAgICB9XG5cbiAgICBpZiAodE51bUMgPT09IDEpIHtcbiAgICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfShpbnQgaW5kZXgpIHtcbiAgICAgICAgICAgIHZlYzIgdXYgPSB2ZWMyKChmbG9hdChpbmRleCkgKyAwLjUpIC8gJHt0TnVtUn0uMCwgMC41KTtcbiAgICAgICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7bmFtZX0sIHV2KTtcbiAgICAgICAgICB9XG4gICAgICAgIGA7XG4gICAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgWydjb29yZGluYXRlcy5zYW1wbGVUZXh0dXJlJ10pO1xuICAgIH1cbiAgICBpZiAodE51bVIgPT09IDEpIHtcbiAgICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfShpbnQgaW5kZXgpIHtcbiAgICAgICAgICAgIHZlYzIgdXYgPSB2ZWMyKDAuNSwgKGZsb2F0KGluZGV4KSArIDAuNSkgLyAke3ROdW1DfS4wKTtcbiAgICAgICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7bmFtZX0sIHV2KTtcbiAgICAgICAgICB9XG4gICAgICAgIGA7XG4gICAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgWydjb29yZGluYXRlcy5zYW1wbGVUZXh0dXJlJ10pO1xuICAgIH1cbiAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCBpbmRleCkge1xuICAgICAgICAgIHZlYzIgdXYgPSB1dkZyb21GbGF0KCR7dE51bVJ9LCAke3ROdW1DfSwgaW5kZXgpO1xuICAgICAgICAgIHJldHVybiBzYW1wbGVUZXh0dXJlKCR7bmFtZX0sIHV2KTtcbiAgICAgICAgfVxuICAgICAgYDtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgWydjb29yZGluYXRlcy51dkZyb21GbGF0JywgJ2Nvb3JkaW5hdGVzLnNhbXBsZVRleHR1cmUnXSk7XG4gIH1cblxuICAvKipcbiAgICogVW5wYWNrZWQgMkQgc25pcHBldC5cbiAgICovXG5cbiAgcHJvdGVjdGVkIGdldFVucGFja2VkU2FtcGxlcjJEKGZ1bmNOYW1lOiBzdHJpbmcsIG5hbWU6IHN0cmluZywgaW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQpOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3Qgc2hhcGUgPSBpbnB1dExheW91dC51bnBhY2tlZFNoYXBlO1xuXG4gICAgLy8gVE9ETzogbW9kaWZ5IHJvdy9jb2wgb3JkZXIgZm9yIG90aGVyIGRpbWVuc2lvbnMuXG4gICAgY29uc3QgdGV4U2hhcGUgPSBbaW5wdXRMYXlvdXQuaGVpZ2h0LCBpbnB1dExheW91dC53aWR0aF07XG5cbiAgICBpZiAodGV4U2hhcGUgIT0gbnVsbCAmJiBBcnJheVV0aWwuYXJyYXlzRXF1YWwoc2hhcGUsIHRleFNoYXBlKSkge1xuICAgICAgY29uc3QgdGV4TnVtUiA9IHRleFNoYXBlWzFdO1xuICAgICAgY29uc3QgdGV4TnVtQyA9IHRleFNoYXBlWzBdO1xuICAgICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCByb3csIGludCBjb2wpIHtcbiAgICAgICAgICAgIHZlYzIgdXYgPSAodmVjMihyb3csIGNvbCkgKyBoYWxmQ1IpIC8gdmVjMigke3RleE51bVJ9LjAsICR7dGV4TnVtQ30uMCk7XG4gICAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCB1dik7XG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZSddKTtcbiAgICB9XG5cbiAgICBjb25zdCB7bmV3U2hhcGUsIGtlcHREaW1zfSA9IHNxdWVlemVTaGFwZShzaGFwZSBhcyBudW1iZXJbXSk7XG4gICAgY29uc3Qgc3F1ZWV6ZWRTaGFwZSA9IG5ld1NoYXBlO1xuICAgIGlmIChzcXVlZXplZFNoYXBlLmxlbmd0aCA8IHNoYXBlLmxlbmd0aCkge1xuICAgICAgY29uc3QgbmV3SW5wdXRTaGFwZSA9IHNxdWVlemVJbnB1dFNoYXBlKHNoYXBlLCBzcXVlZXplZFNoYXBlKTtcbiAgICAgIC8vIERlZXAgY29weSBvZiBpbnB1dCB0ZXh0dXJlIGxheW91dC5cbiAgICAgIGNvbnN0IG5ld0lucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0ID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShpbnB1dExheW91dCkpO1xuICAgICAgbmV3SW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZSA9IG5ld0lucHV0U2hhcGU7XG5cbiAgICAgIGNvbnN0IHBhcmFtcyA9IFsnY29sJywgJ3JvdyddO1xuICAgICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICAgICR7dGhpcy5nZXRVbnBhY2tlZFNhbXBsZXJGcm9tSW5wdXQoZnVuY05hbWUsIG5hbWUsIG5ld0lucHV0TGF5b3V0KS5yb3V0aW5lQm9keX1cbiAgICAgICAgICBmbG9hdCAke2Z1bmNOYW1lfShpbnQgcm93LCBpbnQgY29sKSB7XG4gICAgICAgICAgICByZXR1cm4gJHtmdW5jTmFtZX0oJHtnZXRTcXVlZXplZFBhcmFtcyhwYXJhbXMsIGtlcHREaW1zKX0pO1xuICAgICAgICAgIH1cbiAgICAgICAgYDtcbiAgICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnNhbXBsZVRleHR1cmUnXSk7XG4gICAgfVxuXG4gICAgY29uc3QgdGV4TnVtUiA9IHRleFNoYXBlWzFdO1xuICAgIGNvbnN0IHRleE51bUMgPSB0ZXhTaGFwZVswXTtcbiAgICBpZiAodGV4TnVtQyA9PT0gMSkge1xuICAgICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCByb3csIGludCBjb2wpIHtcbiAgICAgICAgICAgIGludCBvZmZzZXRfJHtuYW1lfSA9IGNvb3Jkc1RvT2Zmc2V0KFRleENvb3JkcywgJHt0ZXhOdW1SfSwgJHt0ZXhOdW1DfSk7XG4gICAgICAgICAgICBmbG9hdCBpbmRleCA9IGRvdCh2ZWMzKHJvdywgY29sLCBvZmZzZXRfJHtuYW1lfSksIHZlYzMoJHtzaGFwZVsxXX0sIDEsIDEpKTtcbiAgICAgICAgICAgIHZlYzIgdXYgPSB2ZWMyKDAuNSwgKGluZGV4ICsgMC41KSAvICR7dGV4TnVtUn0uMCk7XG4gICAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCB1dik7XG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZScsICdjb29yZGluYXRlcy5jb29yZHNUb09mZnNldCddKTtcbiAgICB9XG5cbiAgICBpZiAodGV4TnVtUiA9PT0gMSkge1xuICAgICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCByb3csIGludCBjb2wpIHtcbiAgICAgICAgICAgIGludCBvZmZzZXRfJHtuYW1lfSA9IGNvb3Jkc1RvT2Zmc2V0KFRleENvb3JkcywgJHt0ZXhOdW1SfSwgJHt0ZXhOdW1DfSk7XG4gICAgICAgICAgICBmbG9hdCBpbmRleCA9IGRvdCh2ZWMzKHJvdywgY29sLCBvZmZzZXRfJHtuYW1lfSksIHZlYzMoJHtzaGFwZVsxXX0sIDEsIDEpKTtcbiAgICAgICAgICAgIHZlYzIgdXYgPSB2ZWMyKChpbmRleCArIDAuNSkgLyAke3RleE51bUN9LjAsIDAuNSk7XG4gICAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCB1dik7XG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZScsICdjb29yZGluYXRlcy5jb29yZHNUb09mZnNldCddKTtcbiAgICB9XG5cbiAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCByb3csIGludCBjb2wpIHtcbiAgICAgICAgICBpbnQgaW5kZXggPSBjb2wgKiAke3NoYXBlWzFdfSArIHJvdztcbiAgICAgICAgICB2ZWMyIHV2ID0gdXZGcm9tRmxhdCgke3RleE51bVJ9LCAke3RleE51bUN9LCBpbmRleCk7XG4gICAgICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHtuYW1lfSwgdXYpO1xuICAgICAgICB9XG4gICAgICBgO1xuICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoXG4gICAgICAgIHNvdXJjZSwgWydjb29yZGluYXRlcy51dkZyb21GbGF0JywgJ2Nvb3JkaW5hdGVzLnNhbXBsZVRleHR1cmUnLCAnY29vcmRpbmF0ZXMuY29vcmRzVG9PZmZzZXQnXSk7XG4gIH1cblxuICAvKipcbiAgICogVW5wYWNrZWQgM0Qgc25pcHBldC5cbiAgICovXG5cbiAgcHJvdGVjdGVkIGdldFVucGFja2VkU2FtcGxlcjNEKGZ1bmNOYW1lOiBzdHJpbmcsIG5hbWU6IHN0cmluZywgaW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQpOiBHbHNsTGliUm91dGluZSB7XG4gICAgY29uc3Qgc2hhcGUgPSBpbnB1dExheW91dC51bnBhY2tlZFNoYXBlO1xuICAgIGNvbnN0IHN0cmlkZTAgPSBzaGFwZVsxXSAqIHNoYXBlWzJdO1xuICAgIGNvbnN0IHN0cmlkZTEgPSBzaGFwZVsyXTtcblxuICAgIGNvbnN0IHtuZXdTaGFwZSwga2VwdERpbXN9ID0gc3F1ZWV6ZVNoYXBlKHNoYXBlIGFzIG51bWJlcltdKTtcbiAgICBjb25zdCBzcXVlZXplZFNoYXBlID0gbmV3U2hhcGU7XG4gICAgaWYgKHNxdWVlemVkU2hhcGUubGVuZ3RoIDwgc2hhcGUubGVuZ3RoKSB7XG4gICAgICBjb25zdCBuZXdJbnB1dFNoYXBlID0gc3F1ZWV6ZUlucHV0U2hhcGUoc2hhcGUsIHNxdWVlemVkU2hhcGUpO1xuICAgICAgY29uc3QgcGFyYW1zID0gWydiYXRjaCcsICdjb2wnLCAncm93J107XG4gICAgICAvLyBEZWVwIGNvcHkgb2YgaW5wdXQgdGV4dHVyZSBsYXlvdXQuXG4gICAgICBjb25zdCBuZXdJbnB1dExheW91dDogVGV4dHVyZUxheW91dCA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoaW5wdXRMYXlvdXQpKTtcbiAgICAgIG5ld0lucHV0TGF5b3V0LnVucGFja2VkU2hhcGUgPSBuZXdJbnB1dFNoYXBlO1xuICAgICAgY29uc3Qgcm91dGluZSA9IHRoaXMuZ2V0VW5wYWNrZWRTYW1wbGVyRnJvbUlucHV0KGZ1bmNOYW1lLCBuYW1lLCBuZXdJbnB1dExheW91dCk7XG4gICAgICAvLyBUT0RPOiByZXZpc2l0IHRoZSBsb2dpYyBoZXJlIHRvIG1ha2UgaXQgc2ltcGxlclxuICAgICAgY29uc3QgcmV2RGltcyA9IGtlcHREaW1zLnJldmVyc2UoKTtcbiAgICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgICAke3JvdXRpbmUucm91dGluZUJvZHl9XG4gICAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oaW50IGJhdGNoLCBpbnQgcm93LCBpbnQgY29sKSB7XG4gICAgICAgICAgICByZXR1cm4gJHtmdW5jTmFtZX0oJHtnZXRTcXVlZXplZFBhcmFtcyhwYXJhbXMsIHJldkRpbXMpfSk7XG4gICAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIHJvdXRpbmUuZGVwZW5kZW5jaWVzKTtcbiAgICB9XG5cbiAgICBjb25zdCB0ZXhOdW1SID0gaW5wdXRMYXlvdXQud2lkdGg7XG4gICAgY29uc3QgdGV4TnVtQyA9IGlucHV0TGF5b3V0LmhlaWdodDtcbiAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oaW50IGRlcHRoLCBpbnQgcm93LCBpbnQgY29sKSB7XG4gICAgICAgICAgICAvLyBFeHBsaWNpdGx5IHVzZSBpbnRlZ2VyIG9wZXJhdGlvbnMgYXMgZG90KCkgb25seSB3b3JrcyBvbiBmbG9hdHMuXG4gICAgICAgICAgICBpbnQgaW5kZXggPSBkZXB0aCAqICR7c3RyaWRlMH0gKyBjb2wgKiAke3N0cmlkZTF9ICsgcm93O1xuICAgICAgICAgICAgdmVjMiB1diA9IHV2RnJvbUZsYXQoJHt0ZXhOdW1SfSwgJHt0ZXhOdW1DfSwgaW5kZXgpO1xuICAgICAgICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHtuYW1lfSwgdXYpO1xuICAgICAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShcbiAgICAgICAgc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnV2RnJvbUZsYXQnLCAnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZScsICdjb29yZGluYXRlcy5jb29yZHNUb09mZnNldCddKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnBhY2tlZCA0RCBzbmlwcGV0LlxuICAgKi9cblxuICBwcm90ZWN0ZWQgZ2V0VW5wYWNrZWRTYW1wbGVyNEQoZnVuY05hbWU6IHN0cmluZywgbmFtZTogc3RyaW5nLCBpbnB1dExheW91dDogVGV4dHVyZUxheW91dCk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBzaGFwZSA9IGlucHV0TGF5b3V0LnVucGFja2VkU2hhcGU7XG4gICAgY29uc3Qgc3RyaWRlMiA9IHNoYXBlWzNdO1xuICAgIGNvbnN0IHN0cmlkZTEgPSBzaGFwZVsyXSAqIHN0cmlkZTI7XG4gICAgY29uc3Qgc3RyaWRlMCA9IHNoYXBlWzFdICogc3RyaWRlMTtcblxuICAgIC8vXG4gICAgLy8gVE9ETzogcmUtZW5hYmxlIHRoaXMgc2hvcnRjdXQgb25jZSB0aGUgaW5kZXggY2FsY3VsYXRpb24gYnVnIGlzIGZpeGVkLlxuICAgIC8vXG4gICAgLy8gY29uc3Qge25ld1NoYXBlLCBrZXB0RGltc30gPSBzcXVlZXplU2hhcGUoc2hhcGUgYXMgbnVtYmVyW10pO1xuICAgIC8vIGlmIChuZXdTaGFwZS5sZW5ndGggPCBzaGFwZS5sZW5ndGgpIHtcbiAgICAvLyAgIGNvbnN0IG5ld0lucHV0U2hhcGUgPSBzcXVlZXplSW5wdXRTaGFwZShzaGFwZSwgbmV3U2hhcGUpO1xuICAgIC8vICAgY29uc3QgcGFyYW1zID0gWydyb3cnLCAnY29sJywgJ2RlcHRoJywgJ2RlcHRoMiddO1xuICAgIC8vICAgLy8gRGVlcCBjb3B5IG9mIGlucHV0IHRleHR1cmUgbGF5b3V0LlxuICAgIC8vICAgY29uc3QgbmV3SW5wdXRMYXlvdXQ6IFRleHR1cmVMYXlvdXQgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGlucHV0TGF5b3V0KSk7XG4gICAgLy8gICBuZXdJbnB1dExheW91dC51bnBhY2tlZFNoYXBlID0gbmV3SW5wdXRTaGFwZTtcbiAgICAvLyAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAvLyAgICAgICAke3RoaXMuZ2V0VW5wYWNrZWRTYW1wbGVyRnJvbUlucHV0KGZ1bmNOYW1lLCBuYW1lLCBuZXdJbnB1dExheW91dCkucm91dGluZUJvZHl9XG4gICAgLy8gICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oaW50IHJvdywgaW50IGNvbCwgaW50IGRlcHRoLCBpbnQgZGVwdGgyKSB7XG4gICAgLy8gICAgICAgICByZXR1cm4gJHtmdW5jTmFtZX0oJHtnZXRTcXVlZXplZFBhcmFtcyhwYXJhbXMsIGtlcHREaW1zKX0pO1xuICAgIC8vICAgICAgIH1cbiAgICAvLyAgICAgYDtcbiAgICAvLyAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoXG4gICAgLy8gICAgICAgc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnV2RnJvbUZsYXQnLCAnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZScsICdjb29yZGluYXRlcy5jb29yZHNUb09mZnNldCddKTtcbiAgICAvLyB9XG5cbiAgICBjb25zdCB0ZXhOdW1SID0gaW5wdXRMYXlvdXQud2lkdGg7XG4gICAgY29uc3QgdGV4TnVtQyA9IGlucHV0TGF5b3V0LmhlaWdodDtcbiAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCByb3csIGludCBjb2wsIGludCBkZXB0aCwgaW50IGRlcHRoMikge1xuICAgICAgICAgIGludCBpbmRleCA9IHJvdyAqICR7c3RyaWRlMH0gKyBjb2wgKiAke3N0cmlkZTF9ICtcbiAgICAgICAgICAgICAgZGVwdGgyICogJHtzdHJpZGUyfSArIGRlcHRoO1xuICAgICAgICAgIHZlYzIgdXYgPSB1dkZyb21GbGF0KCR7dGV4TnVtUn0sICR7dGV4TnVtQ30sIGluZGV4KTtcbiAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCB1dik7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMudXZGcm9tRmxhdCcsICdjb29yZGluYXRlcy5zYW1wbGVUZXh0dXJlJ10pO1xuICB9XG5cbiAgLyoqXG4gICAqIFVucGFja2VkIDVEIHNuaXBwZXQuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0VW5wYWNrZWRTYW1wbGVyNUQoZnVuY05hbWU6IHN0cmluZywgbmFtZTogc3RyaW5nLCBpbnB1dExheW91dDogVGV4dHVyZUxheW91dCk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBzaGFwZSA9IGlucHV0TGF5b3V0LnVucGFja2VkU2hhcGU7XG4gICAgY29uc3Qgc3RyaWRlMyA9IHNoYXBlWzRdO1xuICAgIGNvbnN0IHN0cmlkZTIgPSBzaGFwZVszXSAqIHN0cmlkZTM7XG4gICAgY29uc3Qgc3RyaWRlMSA9IHNoYXBlWzJdICogc3RyaWRlMjtcbiAgICBjb25zdCBzdHJpZGUwID0gc2hhcGVbMV0gKiBzdHJpZGUxO1xuXG4gICAgY29uc3Qge25ld1NoYXBlLCBrZXB0RGltc30gPSBzcXVlZXplU2hhcGUoc2hhcGUgYXMgbnVtYmVyW10pO1xuICAgIGlmIChuZXdTaGFwZS5sZW5ndGggPCBzaGFwZS5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IG5ld0lucHV0U2hhcGUgPSBzcXVlZXplSW5wdXRTaGFwZShzaGFwZSwgbmV3U2hhcGUpO1xuICAgICAgY29uc3QgcGFyYW1zID0gWydyb3cnLCAnY29sJywgJ2RlcHRoJywgJ2RlcHRoMicsICdkZXB0aDMnXTtcbiAgICAgIC8vIERlZXAgY29weSBvZiBpbnB1dCB0ZXh0dXJlIGxheW91dC5cbiAgICAgIGNvbnN0IG5ld0lucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0ID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShpbnB1dExheW91dCkpO1xuICAgICAgbmV3SW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZSA9IG5ld0lucHV0U2hhcGU7XG5cbiAgICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgICAke3RoaXMuZ2V0VW5wYWNrZWRTYW1wbGVyRnJvbUlucHV0KGZ1bmNOYW1lLCBuYW1lLCBuZXdJbnB1dExheW91dCkucm91dGluZUJvZHl9XG4gICAgICAgICAgZmxvYXQgJHtmdW5jTmFtZX0oaW50IHJvdywgaW50IGNvbCwgaW50IGRlcHRoLCBpbnQgZGVwdGgyLCBpbnQgZGVwdGgzKSB7XG4gICAgICAgICAgICByZXR1cm4gJHtmdW5jTmFtZX0oJHtnZXRTcXVlZXplZFBhcmFtcyhwYXJhbXMsIGtlcHREaW1zKX0pO1xuICAgICAgICAgIH1cbiAgICAgICAgYDtcbiAgICAgIHJldHVybiBuZXcgR2xzbExpYlJvdXRpbmUoc291cmNlLCBbJ2Nvb3JkaW5hdGVzLnNhbXBsZVRleHR1cmUnLCAnY29vcmRpbmF0ZXMudXZGcm9tRmxhdCddKTtcbiAgICB9XG5cbiAgICBjb25zdCB0ZXhOdW1SID0gaW5wdXRMYXlvdXQud2lkdGg7XG4gICAgY29uc3QgdGV4TnVtQyA9IGlucHV0TGF5b3V0LmhlaWdodDtcbiAgICBjb25zdCBzb3VyY2UgPSBgXG4gICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCByb3csIGludCBjb2wsIGludCBkZXB0aCwgaW50IGRlcHRoMiwgaW50IGRlcHRoMykge1xuICAgICAgICAgIGludCBpbmRleCA9IHJvdyAqICR7c3RyaWRlMH0gKyBjb2wgKiAke3N0cmlkZTF9ICsgZGVwdGggKiAke3N0cmlkZTJ9ICtcbiAgICAgICAgICBkZXB0aDMgKiAke3N0cmlkZTN9ICsgZGVwdGgyO1xuICAgICAgICAgIHZlYzIgdXYgPSB1dkZyb21GbGF0KCR7dGV4TnVtUn0sICR7dGV4TnVtQ30sIGluZGV4KTtcbiAgICAgICAgICByZXR1cm4gc2FtcGxlVGV4dHVyZSgke25hbWV9LCB1dik7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgcmV0dXJuIG5ldyBHbHNsTGliUm91dGluZShzb3VyY2UsIFsnY29vcmRpbmF0ZXMuc2FtcGxlVGV4dHVyZScsICdjb29yZGluYXRlcy51dkZyb21GbGF0J10pO1xuICB9XG5cbiAgLyoqXG4gICAqIFVucGFja2VkIDZEIHNuaXBwZXQuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0VW5wYWNrZWRTYW1wbGVyNkQoZnVuY05hbWU6IHN0cmluZywgbmFtZTogc3RyaW5nLCBpbnB1dExheW91dDogVGV4dHVyZUxheW91dCk6IEdsc2xMaWJSb3V0aW5lIHtcbiAgICBjb25zdCBzaGFwZSA9IGlucHV0TGF5b3V0LnVucGFja2VkU2hhcGU7XG4gICAgY29uc3Qgc3RyaWRlNCA9IHNoYXBlWzVdO1xuICAgIGNvbnN0IHN0cmlkZTMgPSBzaGFwZVs0XSAqIHN0cmlkZTQ7XG4gICAgY29uc3Qgc3RyaWRlMiA9IHNoYXBlWzNdICogc3RyaWRlMztcbiAgICBjb25zdCBzdHJpZGUxID0gc2hhcGVbMl0gKiBzdHJpZGUyO1xuICAgIGNvbnN0IHN0cmlkZTAgPSBzaGFwZVsxXSAqIHN0cmlkZTE7XG5cbiAgICBjb25zdCB7bmV3U2hhcGUsIGtlcHREaW1zfSA9IHNxdWVlemVTaGFwZShzaGFwZSBhcyBudW1iZXJbXSk7XG4gICAgaWYgKG5ld1NoYXBlLmxlbmd0aCA8IHNoYXBlLmxlbmd0aCkge1xuICAgICAgY29uc3QgbmV3SW5wdXRTaGFwZSA9IHNxdWVlemVJbnB1dFNoYXBlKHNoYXBlLCBuZXdTaGFwZSk7XG4gICAgICBjb25zdCBwYXJhbXMgPSBbJ3JvdycsICdjb2wnLCAnZGVwdGgnLCAnZGVwdGgyJywgJ2RlcHRoMycsICdkZXB0aDQnXTtcbiAgICAgIC8vIERlZXAgY29weSBvZiBpbnB1dCB0ZXh0dXJlIGxheW91dC5cbiAgICAgIGNvbnN0IG5ld0lucHV0TGF5b3V0OiBUZXh0dXJlTGF5b3V0ID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShpbnB1dExheW91dCkpO1xuICAgICAgbmV3SW5wdXRMYXlvdXQudW5wYWNrZWRTaGFwZSA9IG5ld0lucHV0U2hhcGU7XG5cbiAgICAgIGNvbnN0IHNvdXJjZSA9IGBcbiAgICAgICAgICAgICR7dGhpcy5nZXRVbnBhY2tlZFNhbXBsZXJGcm9tSW5wdXQoZnVuY05hbWUsIG5hbWUsIG5ld0lucHV0TGF5b3V0KS5yb3V0aW5lQm9keX1cbiAgICAgICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCByb3csIGludCBjb2wsIGludCBkZXB0aCxcbiAgICAgICAgICAgICAgaW50IGRlcHRoMiwgaW50IGRlcHRoMywgaW50IGRlcHRoNCkge1xuICAgICAgICAgICAgICByZXR1cm4gJHtmdW5jTmFtZX0oJHtnZXRTcXVlZXplZFBhcmFtcyhwYXJhbXMsIGtlcHREaW1zKX0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIGA7XG4gICAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKHNvdXJjZSwgWydjb29yZGluYXRlcy5zYW1wbGVUZXh0dXJlJywgJ2Nvb3JkaW5hdGVzLnV2RnJvbUZsYXQnXSk7XG4gICAgfVxuXG4gICAgY29uc3QgdGV4TnVtUiA9IGlucHV0TGF5b3V0LndpZHRoO1xuICAgIGNvbnN0IHRleE51bUMgPSBpbnB1dExheW91dC5oZWlnaHQ7XG4gICAgY29uc3Qgc291cmNlID0gYFxuICAgICAgICAgIGZsb2F0ICR7ZnVuY05hbWV9KGludCByb3csIGludCBjb2wsIGludCBkZXB0aCxcbiAgICAgICAgICAgIGludCBkZXB0aDIsIGludCBkZXB0aDMsIGludCBkZXB0aDQpIHtcbiAgICAgICAgICAgIGludCBpbmRleCA9IHJvdyAqICR7c3RyaWRlMH0gKyBjb2wgKiAke3N0cmlkZTF9ICsgZGVwdGggKiAke3N0cmlkZTJ9ICtcbiAgICAgICAgICAgIGRlcHRoMiAqICR7c3RyaWRlM30gKyBkZXB0aDMgKiAke3N0cmlkZTR9ICsgZGVwdGg0O1xuICAgICAgICAgICAgdmVjMiB1diA9IHV2RnJvbUZsYXQoJHt0ZXhOdW1SfSwgJHt0ZXhOdW1DfSwgaW5kZXgpO1xuICAgICAgICAgICAgcmV0dXJuIHNhbXBsZVRleHR1cmUoJHtuYW1lfSwgdXYpO1xuICAgICAgICAgIH1cbiAgICAgICAgYDtcbiAgICByZXR1cm4gbmV3IEdsc2xMaWJSb3V0aW5lKFxuICAgICAgICBzb3VyY2UsIFsnY29vcmRpbmF0ZXMudXZGcm9tRmxhdCcsICdjb29yZGluYXRlcy5zYW1wbGVUZXh0dXJlJywgJ2Nvb3JkaW5hdGVzLmNvb3Jkc1RvT2Zmc2V0J10pO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoaXMgaXMgdGhlIG1haW4gZnVuY3Rpb24gdG8gbWFwIGZyb20gdGhlIGdpdmVuIHRleHR1cmUgY29vcmRpYW50ZXMgKHMsdClcbiAgICogdG8gbG9naWNhbCBpbmRpY2VzIGZvciB0aGUgb3V0cHV0XG4gICAqIFRoZXJlIHdpbGwgb25seSBiZSBvbmUgc2luZ2xlIHZhcmlhdGlvbiBvZiB0aGlzXG4gICAqIEFsc28gc2VlIGNvb3Jkc1RvT2Zmc2V0IGFuZCBvZmZzZXRUb0luZGljZXMgZm9yIGlucHV0LXNwZWNpZmljIHZlcnNpb25zXG4gICAqL1xuICBwcm90ZWN0ZWQgdG9WZWMoKToge1tuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZX0ge1xuICAgIGNvbnN0IG91dHB1dCA9IHRoaXMuY29udGV4dC5vdXRwdXRUZXh0dXJlTGF5b3V0O1xuICAgIGNvbnN0IHJhbmsgPSBvdXRwdXQuc2hhcGUubGVuZ3RoO1xuICAgIGNvbnN0IHN0cmlkZXMgPSBvdXRwdXQuc3RyaWRlcztcbiAgICBjb25zdCB4U2NhbGUgPSBvdXRwdXQud2lkdGg7XG4gICAgY29uc3QgeVNjYWxlID0gb3V0cHV0LmhlaWdodDtcblxuICAgIGNvbnN0IHN0cmlkZXNCbG9jayA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuayAtIDE7ICsraSkge1xuICAgICAgc3RyaWRlc0Jsb2NrLnB1c2goYFxuICAgICAgICBjWyR7aX1dID0gb2Zmc2V0IC8gJHtzdHJpZGVzW2ldfTtgKTtcbiAgICAgIHN0cmlkZXNCbG9jay5wdXNoKGBcbiAgICAgICAgb2Zmc2V0IC09IGNbJHtpfV0gKiAke3N0cmlkZXNbaV19O2ApO1xuICAgIH1cbiAgICBzdHJpZGVzQmxvY2sucHVzaChgXG4gICAgICAgIGNbJHtyYW5rIC0gMX1dID0gb2Zmc2V0O2ApO1xuICAgIGNvbnN0IGJvZHkgPSBgXG4gICAgICB2b2lkIHRvVmVjKHZlYzIgdGV4Q29vcmRzLCBvdXQgaW50IGNbJHtyYW5rfV0pIHtcbiAgICAgICAgaW50IG9mZnNldCA9IGNvb3Jkc1RvT2Zmc2V0KHRleENvb3JkcywgJHt4U2NhbGV9LCAke3lTY2FsZX0pO1xuICAgICAgICAke3N0cmlkZXNCbG9jay5qb2luKCcnKX1cbiAgICAgIH1cbiAgICAgIHZvaWQgdG9WZWMoaW50IG9mZnNldCwgb3V0IGludCBjWyR7cmFua31dKSB7XG4gICAgICAgICR7c3RyaWRlc0Jsb2NrLmpvaW4oJycpfVxuICAgICAgfVxuICAgIGA7XG4gICAgcmV0dXJuIHt0b1ZlYzogbmV3IEdsc2xMaWJSb3V0aW5lKGJvZHksIFsnY29vcmRpbmF0ZXMuY29vcmRzVG9PZmZzZXQnXSl9O1xuICB9XG4gIC8qKlxuICAgKiBUaGVzZSBhcmUgdmFsdWUgZ2V0dGVyIGZ1bmN0aW9ucyBnZW5lcmF0ZWQgZm9yIGVhY2ggaW5wdXRcbiAgICogRWFjaCBmdW5jdGlvbiBpcyBoYXJkd2lyZWQgdG8gdGhlIG5hbWUgYW5kIGRpbWVuc2lvbnMgb2YgdGhlIGlucHV0XG4gICAqIEFuICdfVCcgdmFyaWF0aW9uIGlzIGFsc28gcHJvZHVjZWQgd2hpY2ggYWNjZXNzZXMgdmFsdWVzIGFzIGlmIHRoZVxuICAgKiBpbnB1dCB3YXMgdHJhbnNwb3NlZFxuICAgKi9cbiAgcHJvdGVjdGVkIHZhbHVlRnJvbSgpOiB7W25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lfSB7XG4gICAgY29uc3QgcmVzdWx0OiB7W25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lfSA9IHt9O1xuICAgIHRoaXMuY29udGV4dC5wcm9ncmFtSW5mby5pbnB1dE5hbWVzLmZvckVhY2goKG5hbWUsIGkpID0+IHtcbiAgICAgIGNvbnN0IGxheW91dCA9IHRoaXMuY29udGV4dC5pbnB1dFRleHR1cmVMYXlvdXRzW2ldO1xuICAgICAgY29uc3Qgc2hhcGUgPSBsYXlvdXQudW5wYWNrZWRTaGFwZS5sZW5ndGggPiAwID8gbGF5b3V0LnVucGFja2VkU2hhcGUgOiBsYXlvdXQuc2hhcGU7XG4gICAgICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuICAgICAgbGV0IGZ1bmNOYW1lID0gYF8ke25hbWV9YDtcbiAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSBuZXcgR2xzbExpYlJvdXRpbmUoXG4gICAgICAgICAgdGhpcy5nZXRWYWx1ZUZyb21TaW5nbGUobmFtZSwgcmFuaywgbGF5b3V0LndpZHRoLCBsYXlvdXQuaGVpZ2h0LCBmYWxzZSksXG4gICAgICAgICAgW2BzaGFwZVV0aWxzLmluZGljZXNUb09mZnNldCR7ZnVuY05hbWV9YCwgJ2Nvb3JkaW5hdGVzLm9mZnNldFRvQ29vcmRzJywgJ2ZyYWdjb2xvci5nZXRDb2xvckFzRmxvYXQnXSk7XG4gICAgICBmdW5jTmFtZSA9IGZ1bmNOYW1lICsgJ19UJztcbiAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSBuZXcgR2xzbExpYlJvdXRpbmUoXG4gICAgICAgICAgdGhpcy5nZXRWYWx1ZUZyb21TaW5nbGUobmFtZSwgcmFuaywgbGF5b3V0LndpZHRoLCBsYXlvdXQuaGVpZ2h0LCB0cnVlKSxcbiAgICAgICAgICBbYHNoYXBlVXRpbHMuaW5kaWNlc1RvT2Zmc2V0JHtmdW5jTmFtZX1gLCAnY29vcmRpbmF0ZXMub2Zmc2V0VG9Db29yZHMnLCAnZnJhZ2NvbG9yLmdldENvbG9yQXNGbG9hdCddKTtcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG4gIC8qKlxuICAgKiBQcm9kdWNlcyBvbmUgdmFsdWUgZ2V0dGVyIGZ1bmN0aW9uIGZvciB0aGUgbmFtZSBhbmQgcmFuayBnaXZlblxuICAgKiBJZiBhIHRyYW5zcG9zZSBpcyBzZXQgcHJvcGVyIG9mZnNldFRvQ29vcmRzIG1hcHBpbmcgd2lsbCBiZSB1c2VkXG4gICAqIEBwYXJhbSBuYW1lIG5hbWUgb2YgdGhlIGZ1bmN0aW9uXG4gICAqIEBwYXJhbSByYW5rIHJhbmsgb2YgdGhlIGlucHV0XG4gICAqIEBwYXJhbSB0cmFuc3Bvc2Ugd2hldGhlciBvciBub3Qgc2hvdWxkIGdlbmVyYXRlIGEgdHJhbnNwb3NlIHZhcmlhdGlvblxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFZhbHVlRnJvbVNpbmdsZSh2YXJOYW1lOiBzdHJpbmcsIHJhbms6IG51bWJlciwgd2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIsIHRyYW5zcG9zZTogYm9vbGVhbik6XG4gICAgICBzdHJpbmcge1xuICAgIGxldCBuYW1lID0gYF8ke3Zhck5hbWV9YDtcbiAgICBpZiAodHJhbnNwb3NlKSB7XG4gICAgICBuYW1lID0gbmFtZSArICdfVCc7XG4gICAgfVxuICAgIGNvbnN0IGdsc2wgPSBnZXRHbHNsKHRoaXMuY29udGV4dC5nbENvbnRleHQudmVyc2lvbik7XG4gICAgcmV0dXJuIGBcbiAgICAgICAgZmxvYXQgJHtuYW1lfShpbnQgbVske3Jhbmt9XSkge1xuICAgICAgICAgIGludCBvZmZzZXQgPSBpbmRpY2VzVG9PZmZzZXQke25hbWV9KG0pO1xuICAgICAgICAgIHZlYzIgY29vcmRzID0gb2Zmc2V0VG9Db29yZHMob2Zmc2V0LCAke3dpZHRofSwgJHtoZWlnaHR9KTtcbiAgICAgICAgICBmbG9hdCB2YWx1ZSA9IGdldENvbG9yQXNGbG9hdCgke2dsc2wudGV4dHVyZTJEfSgke3Zhck5hbWV9LCBjb29yZHMpKTtcbiAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgYDtcbiAgfVxuXG4gIC8qKlxuICAgKiBQcm9kdWNlcyBhIHBhY2tlZCB2YWx1ZSBnZXR0ZXIgZnVuY3Rpb24gZm9yIHRoZSBuYW1lIGFuZCByYW5rIGdpdmVuXG4gICAqIElmIGEgdHJhbnNwb3NlIGlzIHNldCBwcm9wZXIgb2Zmc2V0VG9Db29yZHMgbWFwcGluZyB3aWxsIGJlIHVzZWRcbiAgICogQHBhcmFtIG5hbWUgbmFtZSBvZiB0aGUgZnVuY3Rpb25cbiAgICogQHBhcmFtIHJhbmsgcmFuayBvZiB0aGUgaW5wdXRcbiAgICogQHBhcmFtIHRyYW5zcG9zZSB3aGV0aGVyIG9yIG5vdCBzaG91bGQgZ2VuZXJhdGUgYSB0cmFuc3Bvc2UgdmFyaWF0aW9uXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0UGFja2VkVmFsdWVGcm9tKHZhck5hbWU6IHN0cmluZywgcmFuazogbnVtYmVyLCB3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlciwgdHJhbnNwb3NlOiBib29sZWFuKTpcbiAgICAgIHN0cmluZyB7XG4gICAgbGV0IG5hbWUgPSBgXyR7dmFyTmFtZX1fUGFja2A7XG4gICAgaWYgKHRyYW5zcG9zZSkge1xuICAgICAgbmFtZSA9IG5hbWUgKyAnX1QnO1xuICAgIH1cbiAgICBjb25zdCBnbHNsID0gZ2V0R2xzbCh0aGlzLmNvbnRleHQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICAgIHJldHVybiBgXG4gICAgICAgIHZlYzQgJHtuYW1lfShpbnQgbVske3Jhbmt9XSkge1xuICAgICAgICAgIGludCBvZmZzZXQgPSBpbmRpY2VzVG9PZmZzZXRfJHt2YXJOYW1lfShtKTtcbiAgICAgICAgICB2ZWMyIGNvb3JkcyA9IG9mZnNldFRvQ29vcmRzKG9mZnNldCwgJHt3aWR0aH0sICR7aGVpZ2h0fSk7XG4gICAgICAgICAgcmV0dXJuICR7Z2xzbC50ZXh0dXJlMkR9KCR7dmFyTmFtZX0sIGNvb3Jkcyk7XG4gICAgICAgIH1cbiAgICAgICAgYDtcbiAgfVxufVxuIiwiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7UHJvZ3JhbUluZm8sIFRleHR1cmVMYXlvdXR9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHtXZWJHTENvbnRleHR9IGZyb20gJy4vd2ViZ2wtY29udGV4dCc7XG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvbiAqL1xuZXhwb3J0IGVudW0gRnVuY3Rpb25UeXBlIHtcbiAgVmFsdWVCYXNlZCxcbiAgUG9zaXRpb25hbFxufVxuZXhwb3J0IGludGVyZmFjZSBHbHNsRnVuY3Rpb248VCBleHRlbmRzIEZ1bmN0aW9uVHlwZT4ge1xuICBib2R5OiBzdHJpbmc7XG4gIG5hbWU6IHN0cmluZztcbiAgdHlwZTogVDtcbn1cbmV4cG9ydCB0eXBlIEdsc2xWYWx1ZUZ1bmN0aW9uID0gR2xzbEZ1bmN0aW9uPEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkPjtcbmV4cG9ydCBpbnRlcmZhY2UgR2xzbFBvc2l0aW9uYWxGdW5jdGlvbiBleHRlbmRzIEdsc2xGdW5jdGlvbjxGdW5jdGlvblR5cGUuUG9zaXRpb25hbD4ge1xuICBpbnB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXTtcbiAgb3V0cHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdO1xufVxuXG5leHBvcnQgY2xhc3MgR2xzbENvbnRleHQge1xuICBjb25zdHJ1Y3RvcihcbiAgICAgIHB1YmxpYyBnbENvbnRleHQ6IFdlYkdMQ29udGV4dCwgcHVibGljIHByb2dyYW1JbmZvOiBQcm9ncmFtSW5mbywgcHVibGljIGlucHV0VGV4dHVyZUxheW91dHM6IFRleHR1cmVMYXlvdXRbXSxcbiAgICAgIHB1YmxpYyBvdXRwdXRUZXh0dXJlTGF5b3V0OiBUZXh0dXJlTGF5b3V0KSB7fVxufVxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEdsc2xMaWIge1xuICBjb25zdHJ1Y3RvcihwdWJsaWMgY29udGV4dDogR2xzbENvbnRleHQpIHt9XG4gIGFic3RyYWN0IGdldEZ1bmN0aW9ucygpOiB7W25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lfTtcbiAgYWJzdHJhY3QgZ2V0Q3VzdG9tVHlwZXMoKToge1tuYW1lOiBzdHJpbmddOiBzdHJpbmd9O1xufVxuXG4vLyBhYnN0cmFjdGlvbiB0byByZXByZXNlbnQgYSBHTFNMIGxpYnJhcnkgcm91dGluZSBhbmQgaXQncyBkZXBlbmRlbmNpZXNcbmV4cG9ydCBjbGFzcyBHbHNsTGliUm91dGluZSB7XG4gIGNvbnN0cnVjdG9yKHB1YmxpYyByb3V0aW5lQm9keTogc3RyaW5nLCBwdWJsaWMgZGVwZW5kZW5jaWVzPzogc3RyaW5nW10pIHt9XG59XG5cbi8vIGFic3RyYWN0aW9uIHRvIHJlcHJlc2VudCBhIEdMU0wgbGlicmFyeSByb3V0aW5lIGFuZCBpdCdzIGRlcGVuZGVuY2llcyBBUyBHUkFQSCBOb2Rlc1xuLy8gdGhpcyBsZXZlbCBvZiBhYnN0cmFjdGlvbiBpcyB1c2VkIHRvIHRvcG9sb2dpY2FsbHkgc29ydCByb3V0aW5lcyBiZWZvcmUgZnJhZ21lbnQgc2hhZGUgaW5jbHVzaW9uXG5leHBvcnQgY2xhc3MgR2xzbExpYlJvdXRpbmVOb2RlIHtcbiAgZGVwZW5kZW5jaWVzOiBHbHNsTGliUm91dGluZU5vZGVbXTtcbiAgcm91dGluZUJvZHk6IHN0cmluZztcbiAgY29uc3RydWN0b3IocHVibGljIG5hbWU6IHN0cmluZywgcm91dGluZUJvZHk/OiBzdHJpbmcsIGRlcGVuZGVuY2llcz86IEdsc2xMaWJSb3V0aW5lTm9kZVtdKSB7XG4gICAgaWYgKGRlcGVuZGVuY2llcykge1xuICAgICAgdGhpcy5kZXBlbmRlbmNpZXMgPSBkZXBlbmRlbmNpZXM7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZGVwZW5kZW5jaWVzID0gW107XG4gICAgfVxuXG4gICAgaWYgKHJvdXRpbmVCb2R5KSB7XG4gICAgICB0aGlzLnJvdXRpbmVCb2R5ID0gcm91dGluZUJvZHk7XG4gICAgfVxuICB9XG4gIGFkZERlcGVuZGVuY3kobm9kZTogR2xzbExpYlJvdXRpbmVOb2RlKSB7XG4gICAgaWYgKG5vZGUpIHtcbiAgICAgIHRoaXMuZGVwZW5kZW5jaWVzLnB1c2gobm9kZSk7XG4gICAgfVxuICB9XG59XG5cbi8vIHRvcG9sb2dpY2FsbHkgc29ydCBHTFNMIGxpYnJhcnkgcm91dGluZXMgKGdyYXBoIG5vZGVzIGFic3RyYWN0aW9uKSBiZWZvcmUgc2hhZGVyIHNjcmlwdCBpbmNsdXNpb25cbmV4cG9ydCBjbGFzcyBUb3BvbG9naWNhbFNvcnRHbHNsUm91dGluZXMge1xuICBzdGF0aWMgcmV0dXJuT3JkZXJlZE5vZGVzKG5vZGVzOiBHbHNsTGliUm91dGluZU5vZGVbXSk6IEdsc2xMaWJSb3V0aW5lTm9kZVtdIHtcbiAgICBpZiAoIW5vZGVzIHx8IG5vZGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIGlmIChub2Rlcy5sZW5ndGggPT09IDEpIHtcbiAgICAgIHJldHVybiBub2RlcztcbiAgICB9XG5cbiAgICBjb25zdCBjeWNsZUNoZWNrID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgY29uc3QgYWxyZWFkeVRyYXZlcnNlZCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgIGNvbnN0IHJlc3VsdCA9IG5ldyBBcnJheTxHbHNsTGliUm91dGluZU5vZGU+KCk7XG5cbiAgICB0aGlzLmNyZWF0ZU9yZGVyZWROb2Rlcyhub2RlcywgY3ljbGVDaGVjaywgYWxyZWFkeVRyYXZlcnNlZCwgcmVzdWx0KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgY3JlYXRlT3JkZXJlZE5vZGVzKFxuICAgICAgZ3JhcGhOb2RlczogR2xzbExpYlJvdXRpbmVOb2RlW10sIGN5Y2xlQ2hlY2s6IFNldDxzdHJpbmc+LCBhbHJlYWR5VHJhdmVyc2VkOiBTZXQ8c3RyaW5nPixcbiAgICAgIHJlc3VsdDogR2xzbExpYlJvdXRpbmVOb2RlW10pIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGdyYXBoTm9kZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgIHRoaXMuZGZzVHJhdmVyc2UoZ3JhcGhOb2Rlc1tpXSwgY3ljbGVDaGVjaywgYWxyZWFkeVRyYXZlcnNlZCwgcmVzdWx0KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBkZnNUcmF2ZXJzZShcbiAgICAgIHJvb3Q6IEdsc2xMaWJSb3V0aW5lTm9kZSwgY3ljbGVDaGVjazogU2V0PHN0cmluZz4sIGFscmVhZHlUcmF2ZXJzZWQ6IFNldDxzdHJpbmc+LCByZXN1bHQ6IEdsc2xMaWJSb3V0aW5lTm9kZVtdKSB7XG4gICAgLy8gaWYgdGhpcyByb290IGhhcyBhbHJlYWR5IGJlZW4gdHJhdmVyc2VkIHJldHVyblxuICAgIGlmICghcm9vdCB8fCBhbHJlYWR5VHJhdmVyc2VkLmhhcyhyb290Lm5hbWUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gY3ljbGljIGRlcGVuZGVuY3kgaGFzIGJlZW4gZGV0ZWN0ZWRcbiAgICBpZiAoY3ljbGVDaGVjay5oYXMocm9vdC5uYW1lKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDeWNsaWMgZGVwZW5kZW5jeSBkZXRlY3RlZC4gQ2FuXFwndCB0b3BvbG9naWNhbGx5IHNvcnQgcm91dGluZXMgbmVlZGVkIGZvciBzaGFkZXIuJyk7XG4gICAgfVxuXG4gICAgLy8gaG9sZCB0aGlzIG5vZGUgdG8gZGV0ZWN0IGN5Y2xlcyBpZiBhbnlcbiAgICBjeWNsZUNoZWNrLmFkZChyb290Lm5hbWUpO1xuXG4gICAgLy8gdHJhdmVyc2UgY2hpbGRyZW4gaW4gYSBkZnMgZmFzaGlvblxuICAgIGNvbnN0IGRlcGVuZGVuY2llcyA9IHJvb3QuZGVwZW5kZW5jaWVzO1xuICAgIGlmIChkZXBlbmRlbmNpZXMgJiYgZGVwZW5kZW5jaWVzLmxlbmd0aCA+IDApIHtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGVwZW5kZW5jaWVzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIHRoaXMuZGZzVHJhdmVyc2UoZGVwZW5kZW5jaWVzW2ldLCBjeWNsZUNoZWNrLCBhbHJlYWR5VHJhdmVyc2VkLCByZXN1bHQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGFkZCB0byByZXN1bHQgaG9sZGVyXG4gICAgcmVzdWx0LnB1c2gocm9vdCk7XG5cbiAgICAvLyBtYXJrIHRoaXMgbm9kZSBhcyB0cmF2ZXJzZWQgc28gdGhhdCB3ZSBkb24ndCB0cmF2ZXJzZSBmcm9tIHRoaXMgYWdhaW5cbiAgICBhbHJlYWR5VHJhdmVyc2VkLmFkZChyb290Lm5hbWUpO1xuXG4gICAgLy8gcmVsZWFzZSB0aGUgaG9sZFxuICAgIGN5Y2xlQ2hlY2suZGVsZXRlKHJvb3QubmFtZSk7XG4gIH1cbn1cbiIsIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge0dsc2xDb250ZXh0LCBHbHNsTGliLCBHbHNsTGliUm91dGluZX0gZnJvbSAnLi9nbHNsLWRlZmluaXRpb25zJztcblxuLyoqXG4gKiBUaGlzIEdMU0wgbGlicmFyeSBoYW5kbGVzIHJvdXRpbmVzIGNvbnZlcnRpbmdcbiAqIGZsb2F0MzIgdG8vZnJvbSBVbnNpZ25lZCBieXRlIG9yIGZsb2F0IDE2XG4gKi9cbmV4cG9ydCBjbGFzcyBFbmNvZGluZ0dsc2xMaWIgZXh0ZW5kcyBHbHNsTGliIHtcbiAgY29uc3RydWN0b3IoY29udGV4dDogR2xzbENvbnRleHQpIHtcbiAgICBzdXBlcihjb250ZXh0KTtcbiAgfVxuICBnZXRGdW5jdGlvbnMoKToge1tuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZX0ge1xuICAgIHJldHVybiB7Li4udGhpcy5lbmNvZGVGbG9hdDMyKCksIC4uLnRoaXMuZGVjb2RlRmxvYXQzMigpfTtcbiAgfVxuICBnZXRDdXN0b21UeXBlcygpOiB7W25hbWU6IHN0cmluZ106IHN0cmluZ30ge1xuICAgIHJldHVybiB7fTtcbiAgfVxuICBwcm90ZWN0ZWQgZW5jb2RlRmxvYXQzMigpOiB7W25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lfSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGVuY29kZTogbmV3IEdsc2xMaWJSb3V0aW5lKGBoaWdocCB2ZWM0IGVuY29kZShoaWdocCBmbG9hdCBmKSB7XG4gICAgICAgIHJldHVybiB2ZWM0KGYsIDAuMCwgMC4wLCAwLjApO1xuICAgICAgfVxuICAgICAgICBgKVxuICAgIH07XG4gIH1cbiAgcHJvdGVjdGVkIGRlY29kZUZsb2F0MzIoKToge1tuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZX0ge1xuICAgIHJldHVybiB7XG4gICAgICBkZWNvZGU6IG5ldyBHbHNsTGliUm91dGluZShgaGlnaHAgZmxvYXQgZGVjb2RlKGhpZ2hwIHZlYzQgcmdiYSkge1xuICAgICAgICByZXR1cm4gcmdiYS5yO1xuICAgICAgfVxuICAgICAgICBgKVxuICAgIH07XG4gIH1cbiAgLyoqXG4gICAqIHJldHVybnMgdGhlIHJvdXRpbmUgdG8gZW5jb2RlIGVuY29kZSBhIDMyYml0IGZsb2F0IHRvIGEgdmVjNCAob2YgdW5zaWduZWQgYnl0ZXMpXG4gICAqIEBjcmVkaXQ6IGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzcwNTk5NjIvaG93LWRvLWktY29udmVydC1hLXZlYzQtcmdiYS12YWx1ZS10by1hLWZsb2F0XG4gICAqL1xuICBwcm90ZWN0ZWQgZW5jb2RlVWludDgoKToge1tuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZX0ge1xuICAgIGNvbnN0IGVuZGlhbm5lc3MgPSBFbmNvZGluZ0dsc2xMaWIuaXNMaXR0bGVFbmRpYW4oKSA/ICdyZ2JhLnJnYmE9cmdiYS5hYmdyOycgOiAnJztcbiAgICByZXR1cm4ge1xuICAgICAgZW5jb2RlOiBuZXcgR2xzbExpYlJvdXRpbmUoYFxuICAgICAgaGlnaHAgdmVjNCBlbmNvZGUoaGlnaHAgZmxvYXQgZikge1xuICAgICAgICBoaWdocCBmbG9hdCBGID0gYWJzKGYpO1xuICAgICAgICBoaWdocCBmbG9hdCBTaWduID0gc3RlcCgwLjAsLWYpO1xuICAgICAgICBoaWdocCBmbG9hdCBFeHBvbmVudCA9IGZsb29yKGxvZzIoRikpO1xuICAgICAgICBoaWdocCBmbG9hdCBNYW50aXNzYSA9IChleHAyKC0gRXhwb25lbnQpICogRik7XG4gICAgICAgIEV4cG9uZW50ID0gZmxvb3IobG9nMihGKSArIDEyNy4wKSArIGZsb29yKGxvZzIoTWFudGlzc2EpKTtcbiAgICAgICAgaGlnaHAgdmVjNCByZ2JhO1xuICAgICAgICByZ2JhWzBdID0gMTI4LjAgKiBTaWduICArIGZsb29yKEV4cG9uZW50KmV4cDIoLTEuMCkpO1xuICAgICAgICByZ2JhWzFdID0gMTI4LjAgKiBtb2QoRXhwb25lbnQsMi4wKSArIG1vZChmbG9vcihNYW50aXNzYSoxMjguMCksMTI4LjApO1xuICAgICAgICByZ2JhWzJdID0gZmxvb3IobW9kKGZsb29yKE1hbnRpc3NhKmV4cDIoMjMuMCAtOC4wKSksZXhwMig4LjApKSk7XG4gICAgICAgIHJnYmFbM10gPSBmbG9vcihleHAyKDIzLjApKm1vZChNYW50aXNzYSxleHAyKC0xNS4wKSkpO1xuICAgICAgICAke2VuZGlhbm5lc3N9XG4gICAgICAgIHJnYmEgPSByZ2JhIC8gMjU1LjA7IC8vIHZhbHVlcyBuZWVkIHRvIGJlIG5vcm1hbGl6ZWQgdG8gWzAsMV1cbiAgICAgICAgcmV0dXJuIHJnYmE7XG4gICAgfVxuICAgICAgICBgKVxuICAgIH07XG4gIH1cbiAgLyoqXG4gICAqIHJldHVybnMgdGhlIHJvdXRpbmUgdG8gZW5jb2RlIGEgdmVjNCBvZiB1bnNpZ25lZCBieXRlcyB0byBmbG9hdDMyXG4gICAqIEBjcmVkaXQ6IGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzcwNTk5NjIvaG93LWRvLWktY29udmVydC1hLXZlYzQtcmdiYS12YWx1ZS10by1hLWZsb2F0XG4gICAqL1xuICBwcm90ZWN0ZWQgZGVjb2RlVWludDgoKToge1tuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZX0ge1xuICAgIGNvbnN0IGVuZGlhbm5lc3MgPSBFbmNvZGluZ0dsc2xMaWIuaXNMaXR0bGVFbmRpYW4oKSA/ICdyZ2JhLnJnYmE9cmdiYS5hYmdyOycgOiAnJztcbiAgICByZXR1cm4ge1xuICAgICAgZGVjb2RlOiBuZXcgR2xzbExpYlJvdXRpbmUoYFxuICAgICAgICBoaWdocCBmbG9hdCBkZWNvZGUoaGlnaHAgdmVjNCByZ2JhKSB7XG4gICAgICAgICAgcmdiYSA9IHJnYmEgKiAyNTUuMDsgLy8gdmFsdWVzIG5lZWQgdG8gYmUgZGUtbm9ybWFsaXplZCBmcm9tIFswLDFdIHRvIFswLDI1NV1cbiAgICAgICAgICAke2VuZGlhbm5lc3N9XG4gICAgICAgICAgaGlnaHAgZmxvYXQgU2lnbiA9IDEuMCAtIHN0ZXAoMTI4LjAscmdiYVswXSkqMi4wO1xuICAgICAgICAgIGhpZ2hwIGZsb2F0IEV4cG9uZW50ID0gMi4wICogbW9kKHJnYmFbMF0sMTI4LjApICsgc3RlcCgxMjguMCxyZ2JhWzFdKSAtIDEyNy4wO1xuICAgICAgICAgIGhpZ2hwIGZsb2F0IE1hbnRpc3NhID0gbW9kKHJnYmFbMV0sMTI4LjApKjY1NTM2LjAgKyByZ2JhWzJdKjI1Ni4wICtyZ2JhWzNdICsgZmxvYXQoMHg4MDAwMDApO1xuICAgICAgICAgIGhpZ2hwIGZsb2F0IFJlc3VsdCA9ICBTaWduICogZXhwMihFeHBvbmVudCkgKiAoTWFudGlzc2EgKiBleHAyKC0yMy4wICkpO1xuICAgICAgICAgIHJldHVybiBSZXN1bHQ7XG4gICAgICB9XG4gICAgICAgIGApXG4gICAgfTtcbiAgfVxuICAvKipcbiAgICogRGV0ZXJtaW5lcyBpZiB0aGUgbWFjaGluZSBpcyBsaXR0bGUgZW5kaWFuIG9yIG5vdFxuICAgKiBAY3JlZGl0OiBodHRwczovL2dpc3QuZ2l0aHViLmNvbS9Ub29UYWxsTmF0ZS80NzUwOTUzXG4gICAqL1xuICBzdGF0aWMgaXNMaXR0bGVFbmRpYW4oKTogYm9vbGVhbiB7XG4gICAgY29uc3QgYiA9IG5ldyBBcnJheUJ1ZmZlcig0KTtcbiAgICBjb25zdCBhID0gbmV3IFVpbnQzMkFycmF5KGIpO1xuICAgIGNvbnN0IGMgPSBuZXcgVWludDhBcnJheShiKTtcbiAgICBhWzBdID0gMHhkZWFkYmVlZjtcbiAgICBpZiAoY1swXSA9PT0gMHhlZikge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGlmIChjWzBdID09PSAweGRlKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHRocm93IG5ldyBFcnJvcigndW5rbm93biBlbmRpYW5uZXNzJyk7XG4gIH1cbn1cbiIsIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge0dsc2xDb250ZXh0LCBHbHNsTGliLCBHbHNsTGliUm91dGluZX0gZnJvbSAnLi9nbHNsLWRlZmluaXRpb25zJztcbmltcG9ydCB7Z2V0R2xzbH0gZnJvbSAnLi9nbHNsLXNvdXJjZSc7XG5cbi8qKlxuICogVGhpcyBHTFNMIGxpYnJhcnkgaGFuZGxlcyByb3V0aW5lcyBhcm91bmQgcmVhZGluZyBhIHRleGxldCBhbmQgd3JpdGluZyB0byBpdFxuICogUmVhZGluZyBhbmQgd3JpdGluZyBjb3VsZCBiZSBtb3JlIHRoYW4ganVzdCBkZWFsaW5nIHdpdGggb25lIGNoYW5uZWxcbiAqIEl0IG1heSByZXF1aXJlIGVuY29kaW5nL2RlY29kaW5nIHRvL2Zyb20gNCBjaGFubmVscyBpbnRvIG9uZVxuICovXG5leHBvcnQgY2xhc3MgRnJhZ0NvbG9yR2xzbExpYiBleHRlbmRzIEdsc2xMaWIge1xuICBjb25zdHJ1Y3Rvcihjb250ZXh0OiBHbHNsQ29udGV4dCkge1xuICAgIHN1cGVyKGNvbnRleHQpO1xuICB9XG4gIGdldEZ1bmN0aW9ucygpOiB7W25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lfSB7XG4gICAgcmV0dXJuIHsuLi50aGlzLnNldEZyYWdDb2xvcigpLCAuLi50aGlzLmdldENvbG9yQXNGbG9hdCgpfTtcbiAgfVxuICBnZXRDdXN0b21UeXBlcygpOiB7W25hbWU6IHN0cmluZ106IHN0cmluZ30ge1xuICAgIHJldHVybiB7fTtcbiAgfVxuICBwcm90ZWN0ZWQgc2V0RnJhZ0NvbG9yKCk6IHtbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmV9IHtcbiAgICBjb25zdCBnbHNsID0gZ2V0R2xzbCh0aGlzLmNvbnRleHQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICAgIHJldHVybiB7XG4gICAgICBzZXRGcmFnQ29sb3I6IG5ldyBHbHNsTGliUm91dGluZShcbiAgICAgICAgICBgXG4gICAgICAgIHZvaWQgc2V0RnJhZ0NvbG9yKGZsb2F0IHZhbHVlKSB7XG4gICAgICAgICAgICAke2dsc2wub3V0cHV0fSA9IGVuY29kZSh2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgYCxcbiAgICAgICAgICBbJ2VuY29kaW5nLmVuY29kZSddKVxuICAgIH07XG4gIH1cbiAgcHJvdGVjdGVkIGdldENvbG9yQXNGbG9hdCgpOiB7W25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lfSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGdldENvbG9yQXNGbG9hdDogbmV3IEdsc2xMaWJSb3V0aW5lKFxuICAgICAgICAgIGBcbiAgICAgICAgZmxvYXQgZ2V0Q29sb3JBc0Zsb2F0KHZlYzQgY29sb3IpIHtcbiAgICAgICAgICAgIHJldHVybiBkZWNvZGUoY29sb3IpO1xuICAgICAgICB9XG4gICAgICAgIGAsXG4gICAgICAgICAgWydlbmNvZGluZy5kZWNvZGUnXSlcbiAgICB9O1xuICB9XG59XG4iLCIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuY29uc3QgSU5MSU5FX0ZVTkNfREVGX1JFR0VYID0gL0BpbmxpbmVbXFxzXFxuXFxyXSsoXFx3KylbXFxzXFxuXFxyXSsoWzAtOWEtekEtWl9dKylcXHMqXFwoKFteKV0qKVxcKVxccyp7KChbXn1dfFtcXG5cXHJdKSopfS9nbTtcbmNvbnN0IEZVTkNfQ0FMTF9SRUdFWCA9ICcoXFxcXHcrKT9cXFxccysoW18wLTlhLXpBLVpdKylcXFxccys9XFxcXHMrX19GVU5DX19cXFxcKCguKilcXFxcKVxcXFxzKjsnO1xuLyoqXG4gKiBHTFNMIHByZXByb2Nlc3NvciByZXNwb25zaWJsZSBmb3IgcmVzb2x2aW5nIEBpbmxpbmUgZGlyZWN0aXZlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcmVwbGFjZUlubGluZXMoc2NyaXB0OiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBpbmxpbmVEZWZzOiB7W25hbWU6IHN0cmluZ106IHtwYXJhbXM6IEFycmF5PHt0eXBlOiBzdHJpbmc7IG5hbWU6IHN0cmluZ318bnVsbD47IGJvZHk6IHN0cmluZ319ID0ge307XG4gIGxldCBtYXRjaDtcbiAgd2hpbGUgKChtYXRjaCA9IElOTElORV9GVU5DX0RFRl9SRUdFWC5leGVjKHNjcmlwdCkpICE9PSBudWxsKSB7XG4gICAgY29uc3QgcGFyYW1zID0gbWF0Y2hbM11cbiAgICAgICAgICAgICAgICAgICAgICAgLnNwbGl0KCcsJylcbiAgICAgICAgICAgICAgICAgICAgICAgLm1hcChzID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0b2tlbnMgPSBzLnRyaW0oKS5zcGxpdCgnICcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0b2tlbnMgJiYgdG9rZW5zLmxlbmd0aCA9PT0gMikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHt0eXBlOiB0b2tlbnNbMF0sIG5hbWU6IHRva2Vuc1sxXX07XG4gICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAuZmlsdGVyKHYgPT4gdiAhPT0gbnVsbCk7XG4gICAgaW5saW5lRGVmc1ttYXRjaFsyXV0gPSB7cGFyYW1zLCBib2R5OiBtYXRjaFs0XX07XG4gIH1cbiAgZm9yIChjb25zdCBuYW1lIGluIGlubGluZURlZnMpIHtcbiAgICBjb25zdCByZWdleFN0cmluZyA9IEZVTkNfQ0FMTF9SRUdFWC5yZXBsYWNlKCdfX0ZVTkNfXycsIG5hbWUpO1xuICAgIGNvbnN0IHJlZ2V4ID0gbmV3IFJlZ0V4cChyZWdleFN0cmluZywgJ2dtJyk7XG4gICAgd2hpbGUgKChtYXRjaCA9IHJlZ2V4LmV4ZWMoc2NyaXB0KSkgIT09IG51bGwpIHtcbiAgICAgIGNvbnN0IHR5cGUgPSBtYXRjaFsxXTtcbiAgICAgIGNvbnN0IHZhcmlhYmxlID0gbWF0Y2hbMl07XG4gICAgICBjb25zdCBwYXJhbXMgPSBtYXRjaFszXS5zcGxpdCgnLCcpO1xuICAgICAgY29uc3QgZGVjbExpbmUgPSAodHlwZSkgPyBgJHt0eXBlfSAke3ZhcmlhYmxlfTtgIDogJyc7XG4gICAgICBsZXQgbmV3Qm9keTogc3RyaW5nID0gaW5saW5lRGVmc1tuYW1lXS5ib2R5O1xuICAgICAgbGV0IHBhcmFtUmVkZWNMaW5lID0gJyc7XG4gICAgICBpbmxpbmVEZWZzW25hbWVdLnBhcmFtcy5mb3JFYWNoKCh2LCBpKSA9PiB7XG4gICAgICAgIGlmICh2KSB7XG4gICAgICAgICAgcGFyYW1SZWRlY0xpbmUgKz0gYCR7di50eXBlfSAke3YubmFtZX0gPSAke3BhcmFtc1tpXX07XFxuYDtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBuZXdCb2R5ID0gYCR7cGFyYW1SZWRlY0xpbmV9XFxuICR7bmV3Qm9keX1gO1xuICAgICAgbmV3Qm9keSA9IG5ld0JvZHkucmVwbGFjZSgncmV0dXJuJywgYCR7dmFyaWFibGV9ID0gYCk7XG4gICAgICBjb25zdCByZXBsYWNlbWVudCA9IGBcbiAgICAgICR7ZGVjbExpbmV9XG4gICAgICB7XG4gICAgICAgICR7bmV3Qm9keX1cbiAgICAgIH1cbiAgICAgIGA7XG4gICAgICBzY3JpcHQgPSBzY3JpcHQucmVwbGFjZShtYXRjaFswXSwgcmVwbGFjZW1lbnQpO1xuICAgIH1cbiAgfVxuICBzY3JpcHQgPSBzY3JpcHQucmVwbGFjZShJTkxJTkVfRlVOQ19ERUZfUkVHRVgsICcnKTtcbiAgcmV0dXJuIHNjcmlwdDtcbn1cbiIsIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge0dsc2xDb250ZXh0LCBHbHNsTGliLCBHbHNsTGliUm91dGluZU5vZGUsIFRvcG9sb2dpY2FsU29ydEdsc2xSb3V0aW5lc30gZnJvbSAnLi9nbHNsLWRlZmluaXRpb25zJztcbmltcG9ydCB7cmVwbGFjZUlubGluZXN9IGZyb20gJy4vZ2xzbC1mdW5jdGlvbi1pbmxpbmVyJztcbmltcG9ydCB7Z2xzbFJlZ2lzdHJ5fSBmcm9tICcuL2dsc2wtcmVnaXN0ZXJlZC1saWJzJztcbmltcG9ydCB7Z2V0RGVmYXVsdEZyYWdTaGFkZXJNYWluLCBnZXRGcmFnU2hhZGVyUHJlYW1ibGV9IGZyb20gJy4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHtQcm9ncmFtSW5mbywgVGV4dHVyZUxheW91dCwgVmFyaWFibGVJbmZvfSBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7V2ViR0xDb250ZXh0fSBmcm9tICcuL3dlYmdsLWNvbnRleHQnO1xuXG4vKipcbiAqIFByZXByb2Nlc3NvciBmb3IgdGhlIGFkZGl0aW9ucyB0byB0aGUgR0xTTCBsYW5ndWFnZVxuICogSXQgZGVhbHMgd2l0aDpcbiAqICBAaW5jbHVkZSBkaXJlY3RpdmVzXG4gKiAgQGlubGluZVxuICogIExvb3AgdW5yb2xsaW5nIChub3QgaW1wbGVtZW50ZWQpXG4gKiAgTWFjcm8gcmVzb2x1dGlvbiAobm90IGltcGxlbWVudGVkKVxuICovXG5leHBvcnQgY2xhc3MgR2xzbFByZXByb2Nlc3NvciB7XG4gIHJlYWRvbmx5IGNvbnRleHQ6IEdsc2xDb250ZXh0O1xuICByZWFkb25seSBsaWJzOiB7W25hbWU6IHN0cmluZ106IEdsc2xMaWJ9ID0ge307XG4gIHJlYWRvbmx5IGdsc2xMaWJSb3V0aW5lRGVwZW5kZW5jeUdyYXBoOiB7W3JvdXRpbmVOYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZU5vZGV9ID0ge307XG5cbiAgY29uc3RydWN0b3IoXG4gICAgICBnbENvbnRleHQ6IFdlYkdMQ29udGV4dCwgcHJvZ3JhbUluZm86IFByb2dyYW1JbmZvLCBpbnB1dFRleHR1cmVMYXlvdXRzOiBUZXh0dXJlTGF5b3V0W10sXG4gICAgICBvdXRwdXRUZXh0dXJlTGF5b3V0OiBUZXh0dXJlTGF5b3V0KSB7XG4gICAgdGhpcy5jb250ZXh0ID0gbmV3IEdsc2xDb250ZXh0KGdsQ29udGV4dCwgcHJvZ3JhbUluZm8sIGlucHV0VGV4dHVyZUxheW91dHMsIG91dHB1dFRleHR1cmVMYXlvdXQpO1xuXG4gICAgLy8gY29uc3RydWN0IEdsc2xMaWJzXG4gICAgT2JqZWN0LmtleXMoZ2xzbFJlZ2lzdHJ5KS5mb3JFYWNoKChuYW1lOiBzdHJpbmcpID0+IHtcbiAgICAgIGNvbnN0IGxpYiA9IG5ldyBnbHNsUmVnaXN0cnlbbmFtZV0odGhpcy5jb250ZXh0KTtcbiAgICAgIHRoaXMubGlic1tuYW1lXSA9IGxpYjtcbiAgICB9KTtcblxuICAgIC8vIGNvbnN0cnVjdCBHbHNsUm91dGluZURlcGVuZGVuY3lHcmFwaFxuICAgIGNvbnN0IG1hcCA9IHRoaXMuZ2xzbExpYlJvdXRpbmVEZXBlbmRlbmN5R3JhcGg7XG4gICAgZm9yIChjb25zdCBsaWJOYW1lIGluIHRoaXMubGlicykge1xuICAgICAgY29uc3QgbGliID0gdGhpcy5saWJzW2xpYk5hbWVdO1xuICAgICAgY29uc3Qgcm91dGluZXNJbkxpYiA9IGxpYi5nZXRGdW5jdGlvbnMoKTtcbiAgICAgIGZvciAoY29uc3Qgcm91dGluZSBpbiByb3V0aW5lc0luTGliKSB7XG4gICAgICAgIGNvbnN0IGtleSA9IGxpYk5hbWUgKyAnLicgKyByb3V0aW5lO1xuICAgICAgICBsZXQgY3VycmVudE5vZGU6IEdsc2xMaWJSb3V0aW5lTm9kZTtcbiAgICAgICAgaWYgKG1hcFtrZXldKSB7XG4gICAgICAgICAgY3VycmVudE5vZGUgPSBtYXBba2V5XTtcbiAgICAgICAgICBjdXJyZW50Tm9kZS5yb3V0aW5lQm9keSA9IHJvdXRpbmVzSW5MaWJbcm91dGluZV0ucm91dGluZUJvZHk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY3VycmVudE5vZGUgPSBuZXcgR2xzbExpYlJvdXRpbmVOb2RlKGtleSwgcm91dGluZXNJbkxpYltyb3V0aW5lXS5yb3V0aW5lQm9keSk7XG4gICAgICAgICAgbWFwW2tleV0gPSBjdXJyZW50Tm9kZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBkZXBlbmRlbmNpZXMgPSByb3V0aW5lc0luTGliW3JvdXRpbmVdLmRlcGVuZGVuY2llcztcbiAgICAgICAgaWYgKGRlcGVuZGVuY2llcykge1xuICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGVwZW5kZW5jaWVzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICBpZiAoIW1hcFtkZXBlbmRlbmNpZXNbaV1dKSB7XG4gICAgICAgICAgICAgIGNvbnN0IG5vZGUgPSBuZXcgR2xzbExpYlJvdXRpbmVOb2RlKGRlcGVuZGVuY2llc1tpXSk7XG4gICAgICAgICAgICAgIG1hcFtkZXBlbmRlbmNpZXNbaV1dID0gbm9kZTtcbiAgICAgICAgICAgICAgY3VycmVudE5vZGUuYWRkRGVwZW5kZW5jeShub2RlKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGN1cnJlbnROb2RlLmFkZERlcGVuZGVuY3kobWFwW2RlcGVuZGVuY2llc1tpXV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByZXByb2Nlc3MoKTogc3RyaW5nIHtcbiAgICBjb25zdCBwcm9ncmFtSW5mbyA9IHRoaXMuY29udGV4dC5wcm9ncmFtSW5mbztcbiAgICBsZXQgc291cmNlID0gcHJvZ3JhbUluZm8uc2hhZGVyU291cmNlO1xuXG4gICAgLy8gYXBwZW5kIG1haW4oKSBmdW5jdGlvblxuICAgIGlmICghdGhpcy5jb250ZXh0LnByb2dyYW1JbmZvLmhhc01haW4pIHtcbiAgICAgIHNvdXJjZSA9IGAke3NvdXJjZX1cbiAgICAgICR7Z2V0RGVmYXVsdEZyYWdTaGFkZXJNYWluKHRoaXMuY29udGV4dC5nbENvbnRleHQudmVyc2lvbiwgdGhpcy5jb250ZXh0Lm91dHB1dFRleHR1cmVMYXlvdXQuc2hhcGUubGVuZ3RoKX1gO1xuICAgIH1cbiAgICAvLyByZXBsYWNlIGlubGluZXNcbiAgICBzb3VyY2UgPSByZXBsYWNlSW5saW5lcyhzb3VyY2UpO1xuXG4gICAgLy8gY29uY2F0IGZpbmFsIHNvdXJjZSBzdHJpbmdcbiAgICByZXR1cm4gYCR7Z2V0RnJhZ1NoYWRlclByZWFtYmxlKHRoaXMuY29udGV4dC5nbENvbnRleHQudmVyc2lvbil9XG4gICAgJHt0aGlzLmdldFVuaWZvcm1zKHByb2dyYW1JbmZvLmlucHV0TmFtZXMsIHByb2dyYW1JbmZvLnZhcmlhYmxlcyl9XG4gICAgJHt0aGlzLmdldEltcG9ydHMoc291cmNlKX1cbiAgICAke3NvdXJjZX1gO1xuICB9XG5cbiAgcHJvdGVjdGVkIGdldEltcG9ydHMoc2NyaXB0OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IHJvdXRpbmVzSW5jbHVkZWQgPSB0aGlzLnNlbGVjdEdsc2xMaWJSb3V0aW5lc1RvQmVJbmNsdWRlZChzY3JpcHQpO1xuXG4gICAgaWYgKHJvdXRpbmVzSW5jbHVkZWQubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuXG4gICAgbGV0IHJvdXRpbmVzID0gJyc7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCByb3V0aW5lc0luY2x1ZGVkLmxlbmd0aDsgKytpKSB7XG4gICAgICBpZiAocm91dGluZXNJbmNsdWRlZFtpXS5yb3V0aW5lQm9keSkge1xuICAgICAgICByb3V0aW5lcyArPSByb3V0aW5lc0luY2x1ZGVkW2ldLnJvdXRpbmVCb2R5ICsgJ1xcbic7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE1pc3NpbmcgYm9keSBmb3IgdGhlIEdsc2wgTGlicmFyeSByb3V0aW5lOiAke3JvdXRpbmVzSW5jbHVkZWRbaV0ubmFtZX1gKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcm91dGluZXM7XG4gIH1cbiAgcHJpdmF0ZSBzZWxlY3RHbHNsTGliUm91dGluZXNUb0JlSW5jbHVkZWQoc2NyaXB0OiBzdHJpbmcpOiBHbHNsTGliUm91dGluZU5vZGVbXSB7XG4gICAgY29uc3Qgbm9kZXM6IEdsc2xMaWJSb3V0aW5lTm9kZVtdID0gW107XG5cbiAgICBPYmplY3Qua2V5cyh0aGlzLmdsc2xMaWJSb3V0aW5lRGVwZW5kZW5jeUdyYXBoKS5mb3JFYWNoKGNsYXNzQW5kUm91dGluZSA9PiB7XG4gICAgICBjb25zdCByb3V0aW5lID0gY2xhc3NBbmRSb3V0aW5lLnNwbGl0KCcuJylbMV07XG4gICAgICBpZiAoc2NyaXB0LmluZGV4T2Yocm91dGluZSkgIT09IC0xKSB7XG4gICAgICAgIG5vZGVzLnB1c2godGhpcy5nbHNsTGliUm91dGluZURlcGVuZGVuY3lHcmFwaFtjbGFzc0FuZFJvdXRpbmVdKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiBUb3BvbG9naWNhbFNvcnRHbHNsUm91dGluZXMucmV0dXJuT3JkZXJlZE5vZGVzKG5vZGVzKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXRVbmlmb3JtcyhzYW1wbGVycz86IHN0cmluZ1tdLCB2YXJpYWJsZXM/OiBWYXJpYWJsZUluZm9bXSk6IHN0cmluZyB7XG4gICAgY29uc3QgdW5pZm9ybUxpbmVzOiBzdHJpbmdbXSA9IFtdO1xuICAgIGlmIChzYW1wbGVycykge1xuICAgICAgZm9yIChjb25zdCBzYW1wbGVyIG9mIHNhbXBsZXJzKSB7XG4gICAgICAgIHVuaWZvcm1MaW5lcy5wdXNoKGB1bmlmb3JtIHNhbXBsZXIyRCAke3NhbXBsZXJ9O2ApO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAodmFyaWFibGVzKSB7XG4gICAgICBmb3IgKGNvbnN0IHZhcmlhYmxlIG9mIHZhcmlhYmxlcykge1xuICAgICAgICB1bmlmb3JtTGluZXMucHVzaChcbiAgICAgICAgICAgIGB1bmlmb3JtICR7dmFyaWFibGUudHlwZX0gJHt2YXJpYWJsZS5uYW1lfSR7dmFyaWFibGUuYXJyYXlMZW5ndGggPyBgWyR7dmFyaWFibGUuYXJyYXlMZW5ndGh9XWAgOiAnJ307YCk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB1bmlmb3JtTGluZXMuam9pbignXFxuJyk7XG4gIH1cbn1cbiIsIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge0Nvb3Jkc0dsc2xMaWJ9IGZyb20gJy4vZ2xzbC1jb29yZGluYXRlLWxpYic7XG5pbXBvcnQge0dsc2xDb250ZXh0LCBHbHNsTGlifSBmcm9tICcuL2dsc2wtZGVmaW5pdGlvbnMnO1xuaW1wb3J0IHtFbmNvZGluZ0dsc2xMaWJ9IGZyb20gJy4vZ2xzbC1lbmNvZGluZy1saWInO1xuaW1wb3J0IHtGcmFnQ29sb3JHbHNsTGlifSBmcm9tICcuL2dsc2wtZnJhZ2NvbG9yLWxpYic7XG5pbXBvcnQge1NoYXBlVXRpbHNHbHNsTGlifSBmcm9tICcuL2dsc2wtc2hhcGUtdXRpbHMtbGliJztcbmltcG9ydCB7VmVjR2xzbExpYn0gZnJvbSAnLi9nbHNsLXZlYy1saWInO1xuXG5leHBvcnQgY29uc3QgZ2xzbFJlZ2lzdHJ5OiB7W25hbWU6IHN0cmluZ106IG5ldyAoY29udGV4dDogR2xzbENvbnRleHQpID0+IEdsc2xMaWJ9ID0ge1xuICAnZW5jb2RpbmcnOiBFbmNvZGluZ0dsc2xMaWIsXG4gICdmcmFnY29sb3InOiBGcmFnQ29sb3JHbHNsTGliLFxuICAndmVjJzogVmVjR2xzbExpYixcbiAgJ3NoYXBlVXRpbHMnOiBTaGFwZVV0aWxzR2xzbExpYixcbiAgJ2Nvb3JkaW5hdGVzJzogQ29vcmRzR2xzbExpYixcbiAgLy8gICdhcnJheXMnOiBBcnJheUdsc2xTTGliXG59O1xuIiwiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7R2xzbENvbnRleHQsIEdsc2xMaWIsIEdsc2xMaWJSb3V0aW5lfSBmcm9tICcuL2dsc2wtZGVmaW5pdGlvbnMnO1xuXG4vKipcbiAqIEdMU0wgTGlicmFyeSByZXNwb25zaWJsZSBmb3IgZGF0YSB0eXBlcyBhbmQgcm91dGluZXMgZm9yIG1hbmlwdWxhdGluZ1xuICogY29vcmRpbmF0ZXMgYW5kIG1hcHBpbmcgdG8vZnJvbSB0ZW5zb3IgaW5kaWNlc1xuICovXG5leHBvcnQgY2xhc3MgU2hhcGVVdGlsc0dsc2xMaWIgZXh0ZW5kcyBHbHNsTGliIHtcbiAgY29uc3RydWN0b3IoY29udGV4dDogR2xzbENvbnRleHQpIHtcbiAgICBzdXBlcihjb250ZXh0KTtcbiAgfVxuICBnZXRGdW5jdGlvbnMoKToge1tuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZX0ge1xuICAgIHJldHVybiB7XG4gICAgICAuLi50aGlzLmJjYXN0SW5kZXgoKSxcbiAgICAgIC4uLnRoaXMuYmNhc3RNYXRtdWxJbmRleCgpLFxuICAgICAgLi4udGhpcy5vZmZzZXRUb0luZGljZXMoKSxcbiAgICAgIC4uLnRoaXMuaW5kaWNlc1RvT2Zmc2V0KCksXG4gICAgICAuLi50aGlzLmluY3JlbWVudEluZGljZXMoKVxuICAgIH07XG4gIH1cbiAgZ2V0Q3VzdG9tVHlwZXMoKSB7XG4gICAgcmV0dXJuIHt9O1xuICB9XG4gIHByb3RlY3RlZCBiY2FzdEluZGV4KCk6IHtbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmV9IHtcbiAgICBjb25zdCBvdXRwdXRSYW5rID0gdGhpcy5jb250ZXh0Lm91dHB1dFRleHR1cmVMYXlvdXQuc2hhcGUubGVuZ3RoO1xuICAgIGNvbnN0IHJlc3VsdDoge1tuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZX0gPSB7fTtcbiAgICB0aGlzLmNvbnRleHQucHJvZ3JhbUluZm8uaW5wdXROYW1lcy5mb3JFYWNoKChuYW1lLCBpKSA9PiB7XG4gICAgICBjb25zdCBzaGFwZSA9IHRoaXMuY29udGV4dC5pbnB1dFRleHR1cmVMYXlvdXRzW2ldLnVucGFja2VkU2hhcGU7XG4gICAgICBpZiAoc2hhcGUubGVuZ3RoIDw9IG91dHB1dFJhbmspIHtcbiAgICAgICAgY29uc3QgcmFuayA9IHNoYXBlLmxlbmd0aDtcbiAgICAgICAgY29uc3QgZGltT2Zmc2V0ID0gb3V0cHV0UmFuayAtIHJhbms7XG4gICAgICAgIGNvbnN0IGZ1bmNOYW1lID0gYGJjYXN0SW5kaWNlc18ke25hbWV9YDtcbiAgICAgICAgbGV0IGJsb2NrID0gJyc7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuazsgKytpKSB7XG4gICAgICAgICAgYmxvY2sgKz0gYFxuICAgICAgICAgIHJlYWxJbmRpY2VzWyR7aX1dID0gaW50KCBtb2QoZmxvYXQoYmNhc3RlZEluZGljZXNbJHtkaW1PZmZzZXQgKyBpfV0pLCAke3NoYXBlW2ldfS4wKSApO1xuICAgICAgICAgIGA7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYm9keSA9IGBcbiAgICAgICAgdm9pZCAke2Z1bmNOYW1lfSAoaW50IGJjYXN0ZWRJbmRpY2VzWyR7b3V0cHV0UmFua31dLCBvdXQgaW50IHJlYWxJbmRpY2VzWyR7cmFua31dKSB7XG4gICAgICAgICAgJHtibG9ja31cbiAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgICByZXN1bHRbZnVuY05hbWVdID0gbmV3IEdsc2xMaWJSb3V0aW5lKGJvZHkpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbiAgcHJvdGVjdGVkIGJjYXN0TWF0bXVsSW5kZXgoKToge1tuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZX0ge1xuICAgIGNvbnN0IG91dHB1dFJhbmsgPSB0aGlzLmNvbnRleHQub3V0cHV0VGV4dHVyZUxheW91dC5zaGFwZS5sZW5ndGg7XG4gICAgY29uc3QgcmVzdWx0OiB7W25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lfSA9IHt9O1xuICAgIHRoaXMuY29udGV4dC5wcm9ncmFtSW5mby5pbnB1dE5hbWVzLmZvckVhY2goKG5hbWUsIGkpID0+IHtcbiAgICAgIGNvbnN0IHNoYXBlID0gdGhpcy5jb250ZXh0LmlucHV0VGV4dHVyZUxheW91dHNbaV0uc2hhcGU7XG4gICAgICBpZiAoIShzaGFwZS5sZW5ndGggPCAyIHx8IHNoYXBlLmxlbmd0aCA+IG91dHB1dFJhbmspKSB7XG4gICAgICAgIGNvbnN0IHJhbmsgPSBzaGFwZS5sZW5ndGg7XG4gICAgICAgIGNvbnN0IGRpbU9mZnNldCA9IG91dHB1dFJhbmsgLSByYW5rO1xuICAgICAgICBjb25zdCBmdW5jTmFtZSA9IGBiY2FzdE1hdG11bEluZGljZXNfJHtuYW1lfWA7XG4gICAgICAgIGxldCBibG9jayA9ICcnO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJhbmsgLSAyOyArK2kpIHtcbiAgICAgICAgICBibG9jayArPSBgXG4gICAgICAgICAgcmVhbEluZGljZXNbJHtpfV0gPSBpbnQoIG1vZChmbG9hdChiY2FzdGVkSW5kaWNlc1ske2RpbU9mZnNldCArIGl9XSksICR7c2hhcGVbaV19LjApICk7XG4gICAgICAgICAgYDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBib2R5ID0gYFxuICAgICAgICB2b2lkICR7ZnVuY05hbWV9KGludCBiY2FzdGVkSW5kaWNlc1ske291dHB1dFJhbmt9XSwgb3V0IGludCByZWFsSW5kaWNlc1ske3Jhbmt9XSkge1xuICAgICAgICAgICR7YmxvY2t9XG4gICAgICAgICAgcmVhbEluZGljZXNbJHtyYW5rIC0gMX1dID0gYmNhc3RlZEluZGljZXNbJHtvdXRwdXRSYW5rIC0gMX1dO1xuICAgICAgICAgIHJlYWxJbmRpY2VzWyR7cmFuayAtIDJ9XSA9IGJjYXN0ZWRJbmRpY2VzWyR7b3V0cHV0UmFuayAtIDJ9XTtcbiAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgICByZXN1bHRbZnVuY05hbWVdID0gbmV3IEdsc2xMaWJSb3V0aW5lKGJvZHkpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbiAgcHJvdGVjdGVkIGluZGljZXNUb09mZnNldCgpOiB7W25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lfSB7XG4gICAgY29uc3QgcmVzdWx0OiB7W25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lfSA9IHt9O1xuICAgIHRoaXMuY29udGV4dC5wcm9ncmFtSW5mby5pbnB1dE5hbWVzLmZvckVhY2goKG5hbWUsIGkpID0+IHtcbiAgICAgIGNvbnN0IHNoYXBlID0gdGhpcy5jb250ZXh0LmlucHV0VGV4dHVyZUxheW91dHNbaV0uc2hhcGU7XG4gICAgICBjb25zdCBzdHJpZGVzID0gdGhpcy5jb250ZXh0LmlucHV0VGV4dHVyZUxheW91dHNbaV0uc3RyaWRlcztcbiAgICAgIGNvbnN0IHJhbmsgPSBzaGFwZS5sZW5ndGg7XG4gICAgICBsZXQgZnVuY05hbWUgPSBgaW5kaWNlc1RvT2Zmc2V0XyR7bmFtZX1gO1xuICAgICAgcmVzdWx0W2Z1bmNOYW1lXSA9IG5ldyBHbHNsTGliUm91dGluZShTaGFwZVV0aWxzR2xzbExpYi5pbmRleFRvT2Zmc2V0U2luZ2xlKGZ1bmNOYW1lLCByYW5rLCBzdHJpZGVzKSk7XG4gICAgICBmdW5jTmFtZSA9IGBpbmRpY2VzVG9PZmZzZXRfJHtuYW1lfV9UYDtcbiAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPVxuICAgICAgICAgIG5ldyBHbHNsTGliUm91dGluZShTaGFwZVV0aWxzR2xzbExpYi5pbmRleFRvT2Zmc2V0U2luZ2xlKGZ1bmNOYW1lLCByYW5rLCBzdHJpZGVzLnNsaWNlKCkucmV2ZXJzZSgpKSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuICBzdGF0aWMgaW5kZXhUb09mZnNldFNpbmdsZShuYW1lOiBzdHJpbmcsIHJhbms6IG51bWJlciwgc3RyaWRlczogcmVhZG9ubHkgbnVtYmVyW10pOiBzdHJpbmcge1xuICAgIGxldCBibG9jayA9ICcnO1xuICAgIGZvciAobGV0IGkgPSByYW5rIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgIGJsb2NrICs9IGBcbiAgICAgICAgb2Zmc2V0ICs9IGluZGljZXNbJHtpfV0gKiAke3N0cmlkZXNbaV19O1xuICAgICAgICBgO1xuICAgIH1cbiAgICByZXR1cm4gYFxuICAgICAgaW50ICR7bmFtZX0oaW50IGluZGljZXNbJHtyYW5rfV0pIHtcbiAgICAgICAgaW50IG9mZnNldCA9IDA7XG4gICAgICAgICR7YmxvY2t9XG4gICAgICAgIHJldHVybiBvZmZzZXQ7XG4gICAgICB9XG4gICAgICBgO1xuICB9XG4gIHByb3RlY3RlZCBvZmZzZXRUb0luZGljZXMoKToge1tuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZX0ge1xuICAgIGNvbnN0IHJlc3VsdDoge1tuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZX0gPSB7fTtcbiAgICB0aGlzLmNvbnRleHQucHJvZ3JhbUluZm8uaW5wdXROYW1lcy5mb3JFYWNoKChuYW1lLCBpKSA9PiB7XG4gICAgICBjb25zdCBzaGFwZSA9IHRoaXMuY29udGV4dC5pbnB1dFRleHR1cmVMYXlvdXRzW2ldLnNoYXBlO1xuICAgICAgY29uc3Qgc3RyaWRlcyA9IHRoaXMuY29udGV4dC5pbnB1dFRleHR1cmVMYXlvdXRzW2ldLnN0cmlkZXM7XG4gICAgICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuICAgICAgbGV0IGZ1bmNOYW1lID0gYG9mZnNldFRvSW5kaWNlc18ke25hbWV9YDtcbiAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSBuZXcgR2xzbExpYlJvdXRpbmUoU2hhcGVVdGlsc0dsc2xMaWIub2Zmc2V0VG9JbmRpY2VzU2luZ2xlKGZ1bmNOYW1lLCByYW5rLCBzdHJpZGVzKSk7XG4gICAgICBmdW5jTmFtZSA9IGBvZmZzZXRUb0luZGljZXNfJHtuYW1lfV9UYDtcbiAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPVxuICAgICAgICAgIG5ldyBHbHNsTGliUm91dGluZShTaGFwZVV0aWxzR2xzbExpYi5vZmZzZXRUb0luZGljZXNTaW5nbGUoZnVuY05hbWUsIHJhbmssIHN0cmlkZXMuc2xpY2UoKS5yZXZlcnNlKCkpKTtcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG4gIHN0YXRpYyBvZmZzZXRUb0luZGljZXNTaW5nbGUobmFtZTogc3RyaW5nLCByYW5rOiBudW1iZXIsIHN0cmlkZXM6IHJlYWRvbmx5IG51bWJlcltdKTogc3RyaW5nIHtcbiAgICBjb25zdCBzdHJpZGVzQmxvY2sgPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJhbmsgLSAxOyArK2kpIHtcbiAgICAgIHN0cmlkZXNCbG9jay5wdXNoKGBcbiAgICAgIGluZGljZXNbJHtpfV0gPSBvZmZzZXQgLyAke3N0cmlkZXNbaV19O2ApO1xuICAgICAgc3RyaWRlc0Jsb2NrLnB1c2goYFxuICAgICAgICBvZmZzZXQgLT0gaW5kaWNlc1ske2l9XSAqICR7c3RyaWRlc1tpXX07YCk7XG4gICAgfVxuICAgIHN0cmlkZXNCbG9jay5wdXNoKGBcbiAgICAgIGluZGljZXNbJHtyYW5rIC0gMX1dID0gb2Zmc2V0O2ApO1xuICAgIHJldHVybiBgXG4gICAgICB2b2lkICR7bmFtZX0oaW50IG9mZnNldCwgb3V0IGludCBpbmRpY2VzWyR7cmFua31dKSB7XG4gICAgICAgICR7c3RyaWRlc0Jsb2NrLmpvaW4oJycpfVxuICAgICAgfVxuICAgICAgYDtcbiAgfVxuICBwcm90ZWN0ZWQgaW5jcmVtZW50SW5kaWNlcygpOiB7W25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lfSB7XG4gICAgY29uc3QgcmVzdWx0OiB7W25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lfSA9IHt9O1xuICAgIHRoaXMuY29udGV4dC5wcm9ncmFtSW5mby5pbnB1dE5hbWVzLmZvckVhY2goKG5hbWUsIGkpID0+IHtcbiAgICAgIGNvbnN0IHNoYXBlID0gdGhpcy5jb250ZXh0LmlucHV0VGV4dHVyZUxheW91dHNbaV0uc2hhcGU7XG4gICAgICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuICAgICAgY29uc3QgZnVuY05hbWUgPSBgaW5jcmVtZW50SW5kaWNlc18ke25hbWV9YDtcbiAgICAgIGxldCBzaGFwZUluaXQgPSAnJztcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuazsgKytpKSB7XG4gICAgICAgIHNoYXBlSW5pdCArPSBgXG4gICAgICAgIHNoYXBlWyR7aX1dID0gJHtzaGFwZVtpXX07YDtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGJvZHkgPSBgXG4gICAgICAgIHZvaWQgJHtmdW5jTmFtZX0oaW50IGF4aXMsIG91dCBpbnQgaW5kaWNlc1ske3Jhbmt9XSkge1xuICAgICAgICAgIGludCBzaGFwZVske3Jhbmt9XTtcbiAgICAgICAgICAke3NoYXBlSW5pdH07XG4gICAgICAgICAgZm9yKGludCBpID0gJHtyYW5rfSAtMSA7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgICAgICBpZihpID4gYXhpcykgY29udGludWU7XG4gICAgICAgICAgICBpbmRpY2VzW2ldICs9IDE7XG4gICAgICAgICAgICBpZihpbmRpY2VzW2ldIDwgc2hhcGVbaV0pIHtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpbmRpY2VzW2ldID0gMDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgYDtcbiAgICAgIHJlc3VsdFtmdW5jTmFtZV0gPSBuZXcgR2xzbExpYlJvdXRpbmUoYm9keSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxufVxuIiwiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbi8qKlxuICogcmVwcmVzZW50IGEgdmVyc2lvbiBpcnJlbGV2YW50IGFic3RyYWN0aW9uIG9mIGZvciBHTFNMIHNvdXJjZSBjb2RlXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgR2xzbCB7XG4gIHJlYWRvbmx5IHZlcnNpb246IHN0cmluZztcbiAgcmVhZG9ubHkgYXR0cmlidXRlOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHZhcnlpbmdWZXJ0ZXg6IHN0cmluZztcbiAgcmVhZG9ubHkgdmFyeWluZ0ZyYWc6IHN0cmluZztcbiAgcmVhZG9ubHkgdGV4dHVyZTJEOiBzdHJpbmc7XG4gIHJlYWRvbmx5IG91dHB1dDogc3RyaW5nO1xuICByZWFkb25seSBvdXRwdXREZWNsYXJhdGlvbjogc3RyaW5nO1xufVxuXG5jb25zdCBHTFNMX0VTXzJfMDogR2xzbCA9IHtcbiAgdmVyc2lvbjogJycsXG4gIGF0dHJpYnV0ZTogJ2F0dHJpYnV0ZScsXG4gIHZhcnlpbmdWZXJ0ZXg6ICd2YXJ5aW5nJyxcbiAgdmFyeWluZ0ZyYWc6ICd2YXJ5aW5nJyxcbiAgdGV4dHVyZTJEOiAndGV4dHVyZTJEJyxcbiAgb3V0cHV0OiAnZ2xfRnJhZ0NvbG9yJyxcbiAgb3V0cHV0RGVjbGFyYXRpb246ICcnLFxufTtcbmNvbnN0IEdMU0xfRVNfM18wOiBHbHNsID0ge1xuICB2ZXJzaW9uOiAnI3ZlcnNpb24gMzAwIGVzJyxcbiAgYXR0cmlidXRlOiAnaW4nLFxuICB2YXJ5aW5nVmVydGV4OiAnb3V0JyxcbiAgdmFyeWluZ0ZyYWc6ICdpbicsXG4gIHRleHR1cmUyRDogJ3RleHR1cmUnLFxuICBvdXRwdXQ6ICdvdXRwdXRDb2xvcicsXG4gIG91dHB1dERlY2xhcmF0aW9uOiAnb3V0IHZlYzQgb3V0cHV0Q29sb3I7Jyxcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRHbHNsKHZlcnNpb246IDF8Mikge1xuICByZXR1cm4gdmVyc2lvbiA9PT0gMSA/IEdMU0xfRVNfMl8wIDogR0xTTF9FU18zXzA7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRWZXJ0ZXhTaGFkZXJTb3VyY2UodmVyc2lvbjogMXwyKTogc3RyaW5nIHtcbiAgY29uc3QgZ2xzbCA9IGdldEdsc2wodmVyc2lvbik7XG4gIHJldHVybiBgJHtnbHNsLnZlcnNpb259XG4gICAgICBwcmVjaXNpb24gaGlnaHAgZmxvYXQ7XG4gICAgICAke2dsc2wuYXR0cmlidXRlfSB2ZWMzIHBvc2l0aW9uO1xuICAgICAgJHtnbHNsLmF0dHJpYnV0ZX0gdmVjMiB0ZXh0dXJlQ29vcmQ7XG5cbiAgICAgICR7Z2xzbC52YXJ5aW5nVmVydGV4fSB2ZWMyIFRleENvb3JkcztcblxuICAgICAgdm9pZCBtYWluKClcbiAgICAgIHtcbiAgICAgICAgICBnbF9Qb3NpdGlvbiA9IHZlYzQocG9zaXRpb24sIDEuMCk7XG4gICAgICAgICAgVGV4Q29vcmRzID0gdGV4dHVyZUNvb3JkO1xuICAgICAgfWA7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRGcmFnU2hhZGVyUHJlYW1ibGUodmVyc2lvbjogMXwyKTogc3RyaW5nIHtcbiAgY29uc3QgZ2xzbCA9IGdldEdsc2wodmVyc2lvbik7XG4gIHJldHVybiBgJHtnbHNsLnZlcnNpb259XG4gICAgcHJlY2lzaW9uIGhpZ2hwIGZsb2F0O1xuICAgIHByZWNpc2lvbiBoaWdocCBpbnQ7XG4gICAgcHJlY2lzaW9uIGhpZ2hwIHNhbXBsZXIyRDtcbiAgICAke2dsc2wudmFyeWluZ0ZyYWd9IHZlYzIgVGV4Q29vcmRzO1xuICAgICR7Z2xzbC5vdXRwdXREZWNsYXJhdGlvbn1cbiAgICBjb25zdCB2ZWMyIGhhbGZDUiA9IHZlYzIoMC41LCAwLjUpO1xuXG4gICAgLy8gQ3VzdG9tIHZlY3RvciB0eXBlcyB0byBoYW5kbGUgaGlnaGVyIGRpbWVuYWxpdGllcy5cbiAgICBzdHJ1Y3QgaXZlYzVcbiAgICB7XG4gICAgICBpbnQgeDtcbiAgICAgIGludCB5O1xuICAgICAgaW50IHo7XG4gICAgICBpbnQgdztcbiAgICAgIGludCB1O1xuICAgIH07XG5cbiAgICBzdHJ1Y3QgaXZlYzZcbiAgICB7XG4gICAgICBpbnQgeDtcbiAgICAgIGludCB5O1xuICAgICAgaW50IHo7XG4gICAgICBpbnQgdztcbiAgICAgIGludCB1O1xuICAgICAgaW50IHY7XG4gICAgfTtcblxuICAgIGludCBpbW9kKGludCB4LCBpbnQgeSkge1xuICAgICAgcmV0dXJuIHggLSB5ICogKHggLyB5KTtcbiAgICB9XG5cbiAgICBgO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RGVmYXVsdEZyYWdTaGFkZXJNYWluKHZlcnNpb246IDF8Miwgb3V0cHV0U2hhcGVMZW5ndGg6IG51bWJlcik6IHN0cmluZyB7XG4gIGNvbnN0IGdsc2wgPSBnZXRHbHNsKHZlcnNpb24pO1xuICByZXR1cm4gYFxuICB2b2lkIG1haW4oKSB7XG4gICAgaW50IGluZGljZXNbJHtvdXRwdXRTaGFwZUxlbmd0aH1dO1xuICAgIHRvVmVjKFRleENvb3JkcywgaW5kaWNlcyk7XG4gICAgdmVjNCByZXN1bHQgPSB2ZWM0KHByb2Nlc3MoaW5kaWNlcykpO1xuICAgICR7Z2xzbC5vdXRwdXR9ID0gcmVzdWx0O1xuICB9XG4gIGA7XG59XG4iLCIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtHbHNsQ29udGV4dCwgR2xzbExpYiwgR2xzbExpYlJvdXRpbmV9IGZyb20gJy4vZ2xzbC1kZWZpbml0aW9ucyc7XG5cbi8qKlxuICogR0xTTCBMaWJyYXJ5IHJlc3BvbnNpYmxlIGZvciB2ZWMgcm91dGluZXNcbiAqIFZlYyBpcyBhbiB2YXJpYmxlIGxlbmd0aCBpbnQgYXJyYXkuIFRoZSBsZW5ndGggaXMgZml4ZWQgYXQgdGhlIHRpbWUgb2ZcbiAqIGdlbmVyYXRpbmcgdGhlIGxpYnJhcnkgZnVuY3Rpb25zIGZyb20gdGhlIGRpbWVuc2lvbnMgb2YgdGhlIG91dHB1dC5cbiAqL1xuZXhwb3J0IGNsYXNzIFZlY0dsc2xMaWIgZXh0ZW5kcyBHbHNsTGliIHtcbiAgY29uc3RydWN0b3IoY29udGV4dDogR2xzbENvbnRleHQpIHtcbiAgICBzdXBlcihjb250ZXh0KTtcbiAgfVxuICBnZXRDdXN0b21UeXBlcygpOiB7W25hbWU6IHN0cmluZ106IHN0cmluZ30ge1xuICAgIHJldHVybiB7fTtcbiAgfVxuICBnZXRGdW5jdGlvbnMoKToge1tuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZX0ge1xuICAgIHJldHVybiB7Li4udGhpcy5iaW5hcnlWZWNGdW5jdGlvbnMoKSwgLi4udGhpcy5jb3B5VmVjKCksIC4uLnRoaXMuc2V0VmVjSXRlbSgpLCAuLi50aGlzLmdldFZlY0l0ZW0oKX07XG4gIH1cbiAgcHJvdGVjdGVkIGJpbmFyeVZlY0Z1bmN0aW9ucygpOiB7W25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lfSB7XG4gICAgY29uc3Qgb3V0cHV0TGF5b3V0ID0gdGhpcy5jb250ZXh0Lm91dHB1dFRleHR1cmVMYXlvdXQ7XG4gICAgY29uc3QgcmFuayA9IG91dHB1dExheW91dC5zaGFwZS5sZW5ndGg7XG4gICAgY29uc3QgbmFtZU9wOiB7W25hbWU6IHN0cmluZ106IHN0cmluZ30gPSB7YWRkOiAnKz0nLCBzdWI6ICctPScsIG11bDogJyo9JywgZGl2OiAnLz0nfTtcbiAgICBjb25zdCByZXN1bHQ6IHtbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmV9ID0ge307XG4gICAgZm9yIChjb25zdCBuYW1lIGluIG5hbWVPcCkge1xuICAgICAgY29uc3QgZm5hbWUgPSBgJHtuYW1lfVZlY2A7XG4gICAgICBsZXQgYXNzaWdubWVudEJsb2NrID0gJyc7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJhbms7ICsraSkge1xuICAgICAgICBhc3NpZ25tZW50QmxvY2sgKz0gYFxuICAgICAgICAgIGRlc3RbJHtpfV0gJHtuYW1lT3BbbmFtZV19IHNyY1ske2l9XTtcbiAgICAgICAgICBgO1xuICAgICAgfVxuICAgICAgY29uc3QgYm9keSA9IGBcbiAgICAgICAgdm9pZCAke2ZuYW1lfShpbnQgc3JjWyR7cmFua31dLCBvdXQgaW50IGRlc3RbJHtyYW5rfV0pIHtcbiAgICAgICAgICAke2Fzc2lnbm1lbnRCbG9ja31cbiAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgcmVzdWx0W2ZuYW1lXSA9IG5ldyBHbHNsTGliUm91dGluZShib2R5KTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG4gIHByb3RlY3RlZCBjb3B5VmVjKCk6IHtbbmFtZTogc3RyaW5nXTogR2xzbExpYlJvdXRpbmV9IHtcbiAgICBjb25zdCBvdXRwdXRMYXlvdXQgPSB0aGlzLmNvbnRleHQub3V0cHV0VGV4dHVyZUxheW91dDtcbiAgICBjb25zdCByYW5rID0gb3V0cHV0TGF5b3V0LnNoYXBlLmxlbmd0aDtcbiAgICBsZXQgYXNzaWdubWVudEJsb2NrID0gJyc7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCByYW5rOyArK2kpIHtcbiAgICAgIGFzc2lnbm1lbnRCbG9jayArPSBgXG4gICAgICAgIGRlc3RbJHtpfV0gPSBzcmNbJHtpfV07XG4gICAgICAgIGA7XG4gICAgfVxuICAgIGNvbnN0IGJvZHkgPSBgXG4gICAgICB2b2lkIGNvcHlWZWMoaW50IHNyY1ske3Jhbmt9XSwgb3V0IGludCBkZXN0WyR7cmFua31dKSB7XG4gICAgICAgICR7YXNzaWdubWVudEJsb2NrfVxuICAgICAgfVxuICAgICAgYDtcbiAgICByZXR1cm4ge2NvcHlWZWM6IG5ldyBHbHNsTGliUm91dGluZShib2R5KX07XG4gIH1cblxuICBwcm90ZWN0ZWQgc2V0VmVjSXRlbSgpOiB7W25hbWU6IHN0cmluZ106IEdsc2xMaWJSb3V0aW5lfSB7XG4gICAgY29uc3Qgb3V0cHV0TGF5b3V0ID0gdGhpcy5jb250ZXh0Lm91dHB1dFRleHR1cmVMYXlvdXQ7XG4gICAgY29uc3QgcmFuayA9IG91dHB1dExheW91dC5zaGFwZS5sZW5ndGg7XG4gICAgbGV0IGJsb2NrID0gYFxuICAgICAgICBpZihpbmRleCA8IDApXG4gICAgICAgICAgICBpbmRleCA9JHtyYW5rfSArIGluZGV4O1xuICAgICAgICBpZiAoaW5kZXggPT0gMClcbiAgICAgICAgICAgIG1bMF0gPSB2YWx1ZTtcbiAgICAgICAgYDtcbiAgICBmb3IgKGxldCBpID0gMTsgaSA8IHJhbmsgLSAxOyArK2kpIHtcbiAgICAgIGJsb2NrICs9IGBcbiAgICAgICAgZWxzZSBpZiAoaW5kZXggPT0gJHtpfSlcbiAgICAgICAgICAgIG1bJHtpfV0gPSB2YWx1ZTtcbiAgICAgICAgICAgIGA7XG4gICAgfVxuICAgIGJsb2NrICs9IGBcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgbVske3JhbmsgLSAxfV0gPSB2YWx1ZTtcbiAgICAgICAgYDtcbiAgICBjb25zdCBib2R5ID0gYFxuICAgICAgdm9pZCBzZXRWZWNJdGVtKG91dCBpbnQgbVske3Jhbmt9XSwgaW50IGluZGV4LCBpbnQgdmFsdWUpIHtcbiAgICAgICAgJHtibG9ja31cbiAgICAgIH1cbiAgICAgICAgYDtcbiAgICByZXR1cm4ge3NldFZlY0l0ZW06IG5ldyBHbHNsTGliUm91dGluZShib2R5KX07XG4gIH1cbiAgcHJvdGVjdGVkIGdldFZlY0l0ZW0oKToge1tuYW1lOiBzdHJpbmddOiBHbHNsTGliUm91dGluZX0ge1xuICAgIGNvbnN0IG91dHB1dExheW91dCA9IHRoaXMuY29udGV4dC5vdXRwdXRUZXh0dXJlTGF5b3V0O1xuICAgIGNvbnN0IHJhbmsgPSBvdXRwdXRMYXlvdXQuc2hhcGUubGVuZ3RoO1xuICAgIGxldCBibG9jayA9IGBcbiAgICAgICAgaWYoaW5kZXggPCAwKVxuICAgICAgICAgICAgaW5kZXggPSAke3Jhbmt9ICsgaW5kZXg7XG4gICAgICAgIGlmIChpbmRleCA9PSAwKVxuICAgICAgICAgICAgcmV0dXJuIG1bMF07XG4gICAgICBgO1xuICAgIGZvciAobGV0IGkgPSAxOyBpIDwgcmFuayAtIDE7ICsraSkge1xuICAgICAgYmxvY2sgKz0gYFxuICAgICAgICBlbHNlIGlmIChpbmRleCA9PSAke2l9KVxuICAgICAgICAgICAgcmV0dXJuIG1bJHtpfV07XG4gICAgICBgO1xuICAgIH1cbiAgICBibG9jayArPSBgXG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIHJldHVybiBtWyR7cmFuayAtIDF9XTtcbiAgICAgICAgYDtcbiAgICBjb25zdCBib2R5ID0gYFxuICAgICAgaW50IGdldFZlY0l0ZW0oaW50IG1bJHtyYW5rfV0sIGludCBpbmRleCkge1xuICAgICAgICAke2Jsb2NrfVxuICAgICAgfVxuICAgIGA7XG4gICAgcmV0dXJuIHtnZXRWZWNJdGVtOiBuZXcgR2xzbExpYlJvdXRpbmUoYm9keSl9O1xuICB9XG59XG4iLCIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtJbmZlcmVuY2VIYW5kbGVyfSBmcm9tICcuLi8uLi9iYWNrZW5kJztcbmltcG9ydCB7TG9nZ2VyfSBmcm9tICcuLi8uLi9pbnN0cnVtZW50JztcbmltcG9ydCB7VGVuc29yfSBmcm9tICcuLi8uLi90ZW5zb3InO1xuaW1wb3J0IHtTaGFwZVV0aWx9IGZyb20gJy4uLy4uL3V0aWwnO1xuXG5pbXBvcnQge2NyZWF0ZVBhY2tQcm9ncmFtSW5mb0xvYWRlcn0gZnJvbSAnLi9vcHMvcGFjayc7XG5pbXBvcnQge2NyZWF0ZVBhY2tlZFJlc2hhcGUzRFByb2dyYW1JbmZvTG9hZGVyLCBpc1Jlc2hhcGVDaGVhcCwgcHJvY2Vzc0RpbXMzRH0gZnJvbSAnLi9vcHMvcmVzaGFwZS1wYWNrZWQnO1xuaW1wb3J0IHtlbmNvZGVBc1VpbnQ4fSBmcm9tICcuL29wcy91aW50OC1lbmNvZGUnO1xuaW1wb3J0IHtjcmVhdGVVbnBhY2tQcm9ncmFtSW5mb0xvYWRlcn0gZnJvbSAnLi9vcHMvdW5wYWNrJztcbmltcG9ydCB7V2ViR0xTZXNzaW9uSGFuZGxlcn0gZnJvbSAnLi9zZXNzaW9uLWhhbmRsZXInO1xuaW1wb3J0IHtFbmNvZGVyfSBmcm9tICcuL3RleHR1cmUtZGF0YS1lbmNvZGVyJztcbmltcG9ydCB7Y2FsY3VsYXRlVGV4dHVyZVdpZHRoQW5kSGVpZ2h0LCBjcmVhdGVUZXh0dXJlTGF5b3V0RnJvbVNoYXBlLCBjcmVhdGVUZXh0dXJlTGF5b3V0RnJvbVRleHR1cmVUeXBlfSBmcm9tICcuL3RleHR1cmUtbGF5b3V0JztcbmltcG9ydCB7QXJ0aWZhY3QsIFByb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgVGV4dHVyZURhdGEsIFRleHR1cmVMYXlvdXQsIFRleHR1cmVUeXBlfSBmcm9tICcuL3R5cGVzJztcblxuY29uc3QgZ2V0UHJvZ3JhbUluZm9VbmlxdWVLZXkgPVxuICAgIChwcm9ncmFtSW5mbzogUHJvZ3JhbUluZm98UHJvZ3JhbUluZm9Mb2FkZXIsIGlucHV0VGV4dHVyZURhdGFzOiBUZXh0dXJlRGF0YVtdKTogc3RyaW5nID0+IHtcbiAgICAgIGNvbnN0IGlucHV0cyA9XG4gICAgICAgICAgaW5wdXRUZXh0dXJlRGF0YXMubWFwKHRleHR1cmUgPT4gYCR7dGV4dHVyZS51bnBhY2tlZFNoYXBlLmpvaW4oJywnKX07JHt0ZXh0dXJlLndpZHRofXgke3RleHR1cmUuaGVpZ2h0fWApXG4gICAgICAgICAgICAgIC5qb2luKCdfJyk7XG4gICAgICBsZXQga2V5ID0gcHJvZ3JhbUluZm8ubmFtZTtcbiAgICAgIGlmIChwcm9ncmFtSW5mby5jYWNoZUhpbnQpIHtcbiAgICAgICAga2V5ICs9ICdbJyArIHByb2dyYW1JbmZvLmNhY2hlSGludCArICddJztcbiAgICAgIH1cbiAgICAgIGtleSArPSAnOicgKyBpbnB1dHM7XG4gICAgICByZXR1cm4ga2V5O1xuICAgIH07XG5cbmV4cG9ydCBjbGFzcyBXZWJHTEluZmVyZW5jZUhhbmRsZXIgaW1wbGVtZW50cyBJbmZlcmVuY2VIYW5kbGVyIHtcbiAgcHJpdmF0ZSBwYWNrZWRUZXh0dXJlRGF0YUNhY2hlOiBNYXA8VGVuc29yLklkLCBUZXh0dXJlRGF0YT47XG4gIHByaXZhdGUgdW5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlOiBNYXA8VGVuc29yLklkLCBUZXh0dXJlRGF0YT47XG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBzZXNzaW9uOiBXZWJHTFNlc3Npb25IYW5kbGVyKSB7XG4gICAgdGhpcy5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlID0gbmV3IE1hcCgpO1xuICAgIHRoaXMudW5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlID0gbmV3IE1hcCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIFt3aWR0aCwgaGVpZ2h0XVxuICAgKi9cbiAgY2FsY3VsYXRlVGV4dHVyZVdpZHRoQW5kSGVpZ2h0KHNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlKTogW251bWJlciwgbnVtYmVyXSB7XG4gICAgcmV0dXJuIGNhbGN1bGF0ZVRleHR1cmVXaWR0aEFuZEhlaWdodCh0aGlzLnNlc3Npb24ubGF5b3V0U3RyYXRlZ3ksIHNoYXBlLCB0ZXh0dXJlVHlwZSk7XG4gIH1cblxuICBleGVjdXRlUHJvZ3JhbShwcm9ncmFtOiBQcm9ncmFtSW5mb3xQcm9ncmFtSW5mb0xvYWRlciwgaW5wdXRzOiByZWFkb25seSBUZW5zb3JbXSk6IFRleHR1cmVEYXRhIHtcbiAgICBpZiAoaW5wdXRzLmxlbmd0aCA8IHByb2dyYW0uaW5wdXROYW1lcy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW5wdXQgc2l6ZSBtdXN0bid0IGJlIGxlc3MgdGhhbiAke3Byb2dyYW0uaW5wdXROYW1lcy5sZW5ndGh9LmApO1xuICAgIH1cbiAgICBpZiAocHJvZ3JhbS5pbnB1dE5hbWVzLmxlbmd0aCAhPT0gcHJvZ3JhbS5pbnB1dFR5cGVzLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnB1dCBuYW1lcyBzaXplIGRvZXMgbm90IG1hdGNoIGlucHV0IHR5cGVzJyk7XG4gICAgfVxuXG4gICAgLy8gY3JlYXRlIHRleHR1cmUgaW5mbyBmb3IgaW5wdXRcbiAgICBjb25zdCBpbnB1dFRleHR1cmVEYXRhczogVGV4dHVyZURhdGFbXSA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcHJvZ3JhbS5pbnB1dE5hbWVzLmxlbmd0aDsgKytpKSB7XG4gICAgICBpbnB1dFRleHR1cmVEYXRhc1tpXSA9IHRoaXMuZ2V0T3JDcmVhdGVUZXh0dXJlRGF0YShpbnB1dHNbaV0sIHByb2dyYW0uaW5wdXRUeXBlc1tpXSk7XG4gICAgfVxuXG4gICAgY29uc3Qga2V5ID0gZ2V0UHJvZ3JhbUluZm9VbmlxdWVLZXkocHJvZ3JhbSwgaW5wdXRUZXh0dXJlRGF0YXMpO1xuICAgIGxldCBhcnRpZmFjdCA9IHRoaXMuc2Vzc2lvbi5wcm9ncmFtTWFuYWdlci5nZXRBcnRpZmFjdChrZXkpO1xuICAgIGNvbnN0IHByb2dyYW1JbmZvID0gYXJ0aWZhY3QgP1xuICAgICAgICBhcnRpZmFjdC5wcm9ncmFtSW5mbyA6XG4gICAgICAgICh0eXBlb2YgKHByb2dyYW0gYXMgUHJvZ3JhbUluZm9Mb2FkZXIpLmdldCA9PT0gJ2Z1bmN0aW9uJyA/IChwcm9ncmFtIGFzIFByb2dyYW1JbmZvTG9hZGVyKS5nZXQoKSA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChwcm9ncmFtIGFzIFByb2dyYW1JbmZvKSk7XG5cbiAgICAvLyBjcmVhdGUgdGV4dHVyZSBpbmZvIGZvciBvdXRwdXRcbiAgICBjb25zdCBvdXRwdXRUZXh0dXJlTGF5b3V0ID0gY3JlYXRlVGV4dHVyZUxheW91dEZyb21UZXh0dXJlVHlwZShcbiAgICAgICAgdGhpcy5zZXNzaW9uLmxheW91dFN0cmF0ZWd5LCBwcm9ncmFtSW5mby5vdXRwdXQuZGltcywgcHJvZ3JhbUluZm8ub3V0cHV0LnRleHR1cmVUeXBlKTtcbiAgICBjb25zdCBvdXRwdXRUZXh0dXJlRGF0YSA9IHRoaXMuY3JlYXRlVGV4dHVyZURhdGEob3V0cHV0VGV4dHVyZUxheW91dCwgcHJvZ3JhbUluZm8ub3V0cHV0LnR5cGUpO1xuXG4gICAgaWYgKCFhcnRpZmFjdCkge1xuICAgICAgYXJ0aWZhY3QgPSB0aGlzLnNlc3Npb24ucHJvZ3JhbU1hbmFnZXIuYnVpbGQocHJvZ3JhbUluZm8sIGlucHV0VGV4dHVyZURhdGFzLCBvdXRwdXRUZXh0dXJlRGF0YSk7XG4gICAgICB0aGlzLnNlc3Npb24ucHJvZ3JhbU1hbmFnZXIuc2V0QXJ0aWZhY3Qoa2V5LCBhcnRpZmFjdCk7XG4gICAgfVxuXG4gICAgdGhpcy5ydW5Qcm9ncmFtKGFydGlmYWN0LCBpbnB1dFRleHR1cmVEYXRhcywgb3V0cHV0VGV4dHVyZURhdGEpO1xuICAgIHJldHVybiBvdXRwdXRUZXh0dXJlRGF0YTtcbiAgfVxuXG4gIHJ1bihwcm9ncmFtOiBQcm9ncmFtSW5mb0xvYWRlciwgaW5wdXRzOiByZWFkb25seSBUZW5zb3JbXSk6IFRlbnNvciB7XG4gICAgY29uc3Qgb3V0cHV0VGV4dHVyZURhdGEgPSB0aGlzLmV4ZWN1dGVQcm9ncmFtKHByb2dyYW0sIGlucHV0cyk7XG4gICAgcmV0dXJuIG91dHB1dFRleHR1cmVEYXRhLnRlbnNvcjtcbiAgfVxuXG4gIHByaXZhdGUgcnVuUHJvZ3JhbShhcnRpZmFjdDogQXJ0aWZhY3QsIGlucHV0czogVGV4dHVyZURhdGFbXSwgb3V0cHV0OiBUZXh0dXJlRGF0YSk6IHZvaWQge1xuICAgIC8vIGlucHV0IHNob3VsZCBtYXRjaFxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5wdXRzLmxlbmd0aDsgKytpKSB7XG4gICAgICBpZiAoISFpbnB1dHNbaV0uaXNQYWNrZWQgIT09IChhcnRpZmFjdC5wcm9ncmFtSW5mby5pbnB1dFR5cGVzW2ldID09PSBUZXh0dXJlVHlwZS5wYWNrZWQpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgaW5wdXRbJHtpfV0gcHJvcGVydHkgcGFja2VkIGluY29uc2lzdGVudGApO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIG91dHB1dCBzaG91bGQgbWF0Y2hcbiAgICBpZiAoISFvdXRwdXQuaXNQYWNrZWQgIT09IChhcnRpZmFjdC5wcm9ncmFtSW5mby5vdXRwdXQudGV4dHVyZVR5cGUgPT09IFRleHR1cmVUeXBlLnBhY2tlZCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignb3V0cHV0IHByb3BlcnR5IHBhY2tlZCBpbmNvbnNpc3RlbnQnKTtcbiAgICB9XG5cbiAgICB0aGlzLnNlc3Npb24ucHJvZ3JhbU1hbmFnZXIucnVuKGFydGlmYWN0LCBpbnB1dHMsIG91dHB1dCk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgVGV4dHVyZURhdGEgb2JqZWN0IGZyb20gYSB0ZW5zb3IuXG4gICAqIFVzYWdlID0gRW5jb2Rlci5Vc2FnZS5VcGxvYWRPbmx5LlxuICAgKiBJZiBhIHJlbGF0ZWQgdGV4dHVyZSBkYXRhIGlzIGZvdW5kIGluIGNhY2hlLCByZXR1cm5zIGl0O1xuICAgKiBPdGhlcndpc2U6XG4gICAqICAgQ3JlYXRlcyBhIG5ldyB0ZXh0dXJlIGxheW91dCBpZiBub3QgcHJvdmlkZWQ7XG4gICAqICAgQ3JlYXRlcyBXZWJHTFRleHR1cmUgd2l0aCB0aGUgbGF5b3V0O1xuICAgKiAgIFVwbG9hZCB0ZW5zb3IgZGF0YSB0byB0aGUgdGV4dHVyZTtcbiAgICogICBDcmVhdGVzIGEgdGV4dHVyZSBkYXRhIG9iamVjdCBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIHRlbnNvci5cbiAgICogQHBhcmFtIHRlbnNvciB0aGUgdGVuc29yIHdpdGggZGF0YSB0byB1cGxvYWRcbiAgICovXG4gIHByaXZhdGUgZ2V0T3JDcmVhdGVUZXh0dXJlRGF0YSh0ZW5zb3I6IFRlbnNvciwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlKSB7XG4gICAgbGV0IHRkID0gdGhpcy5nZXRUZXh0dXJlRGF0YSh0ZW5zb3IuZGF0YUlkLCB0ZXh0dXJlVHlwZSA9PT0gVGV4dHVyZVR5cGUucGFja2VkKTtcblxuICAgIGlmICghdGQpIHtcbiAgICAgIC8vIGNoZWNrIGlmIHdlIGhhdmUgdGV4dHVyZSBkYXRhIGluIGRpZmZlcmVudCB0eXBlXG4gICAgICB0ZCA9IHRoaXMuZ2V0VGV4dHVyZURhdGEodGVuc29yLmRhdGFJZCwgdGV4dHVyZVR5cGUgIT09IFRleHR1cmVUeXBlLnBhY2tlZCk7XG4gICAgICBpZiAodGQpIHtcbiAgICAgICAgaWYgKHRleHR1cmVUeXBlID09PSBUZXh0dXJlVHlwZS5wYWNrZWQpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5wYWNrKHRkKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy51bnBhY2sodGQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCF0ZCkge1xuICAgICAgY29uc3QgbGF5b3V0ID0gY3JlYXRlVGV4dHVyZUxheW91dEZyb21UZXh0dXJlVHlwZSh0aGlzLnNlc3Npb24ubGF5b3V0U3RyYXRlZ3ksIHRlbnNvci5kaW1zLCB0ZXh0dXJlVHlwZSk7XG5cbiAgICAgIGlmICh0ZXh0dXJlVHlwZSA9PT0gVGV4dHVyZVR5cGUucGFja2VkTGFzdERpbWVuc2lvbikge1xuICAgICAgICBjb25zdCBncm91cCA9IDE7XG4gICAgICAgIGNvbnN0IGNoYW5uZWxzID0gNDtcbiAgICAgICAgY29uc3Qgc2hhcGUgPSB0ZW5zb3IuZGltcztcbiAgICAgICAgaWYgKHNoYXBlLmxlbmd0aCA9PT0gNCkge1xuICAgICAgICAgIC8vIHByZS1wcm9jZXNzaW5nIGZvciBrZXJuZWwgZGF0YSBvZiBDb252LlxuICAgICAgICAgIC8vXG4gICAgICAgICAgLy8gVE9ETzogY3VycmVudGx5IHRoaXMgaXMgYSBoYWNraW5nIHRvIG92ZXJ3cml0ZSBDb252J3Mgd2VpZ2h0LiBUaGUgY29ycmVjdCB3YXkgdG8gZG8gdGhpcyBzaG91bGQgYmU6XG4gICAgICAgICAgLy8gMS4gaW1wbGVtZW50IHRleHR1cmUgYmFzZWQgY29uc3QtZm9sZGluZ1xuICAgICAgICAgIC8vIDIuIGNyZWF0ZSBhIFdlYkdMIHByb2dyYW0gXCJwcmVwcm9jZXNzQ29udldlaWdodFwiIHRvIGRvIHRoZSBzYW1lIHdvcmsgYXMgYmVsb3dcbiAgICAgICAgICAvLyAzLiBydW4gdGhlIHByb2dyYW0gYmVmb3JlIGRvdFByb2R1Y3QuXG4gICAgICAgICAgLy9cbiAgICAgICAgICBjb25zdCBhZGp1c3RlZEtlcm5lbFNoYXBlID0gW3NoYXBlWzBdLCBNYXRoLmNlaWwoKHNoYXBlWzFdICogc2hhcGVbMl0gKiBzaGFwZVszXSkgLyBjaGFubmVscyldO1xuICAgICAgICAgIGNvbnN0IGFkanVzdGVkTGF5b3V0ID1cbiAgICAgICAgICAgICAgY3JlYXRlVGV4dHVyZUxheW91dEZyb21UZXh0dXJlVHlwZSh0aGlzLnNlc3Npb24ubGF5b3V0U3RyYXRlZ3ksIGFkanVzdGVkS2VybmVsU2hhcGUsIHRleHR1cmVUeXBlKTtcbiAgICAgICAgICBsZXQgYnVmZmVyID0gdGVuc29yLm51bWJlckRhdGE7XG4gICAgICAgICAgaWYgKHNoYXBlWzFdICogc2hhcGVbMl0gKiBzaGFwZVszXSAlIGNoYW5uZWxzICE9PSAwKSB7XG4gICAgICAgICAgICBjb25zdCBudW1GZWF0dXJlTWFwcyA9IHNoYXBlWzBdO1xuICAgICAgICAgICAgY29uc3Qgb2xkUm93U2l6ZSA9IHNoYXBlWzFdICogc2hhcGVbMl0gKiBzaGFwZVszXTtcbiAgICAgICAgICAgIGNvbnN0IG5ld1Jvd1NpemUgPSBNYXRoLmNlaWwob2xkUm93U2l6ZSAqIGdyb3VwIC8gY2hhbm5lbHMpICogY2hhbm5lbHM7XG4gICAgICAgICAgICBjb25zdCBuZXdTaXplID0gbnVtRmVhdHVyZU1hcHMgKiBuZXdSb3dTaXplO1xuICAgICAgICAgICAgYnVmZmVyID0gbmV3IEZsb2F0MzJBcnJheShuZXdTaXplKTtcbiAgICAgICAgICAgIGZvciAobGV0IGYgPSAwOyBmIDwgbnVtRmVhdHVyZU1hcHM7ICsrZikge1xuICAgICAgICAgICAgICBjb25zdCBvbGRPZmZzZXQgPSBmICogb2xkUm93U2l6ZTtcbiAgICAgICAgICAgICAgY29uc3QgbmV3T2Zmc2V0ID0gZiAqIG5ld1Jvd1NpemUgKyBmICUgZ3JvdXAgKiBvbGRSb3dTaXplO1xuICAgICAgICAgICAgICBidWZmZXIuc2V0KHRlbnNvci5udW1iZXJEYXRhLnN1YmFycmF5KG9sZE9mZnNldCwgb2xkT2Zmc2V0ICsgb2xkUm93U2l6ZSksIG5ld09mZnNldCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB0aGlzLmNyZWF0ZVRleHR1cmVEYXRhKGFkanVzdGVkTGF5b3V0LCB0ZW5zb3IudHlwZSwgYnVmZmVyLCB0ZW5zb3IsIEVuY29kZXIuVXNhZ2UuVXBsb2FkT25seSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKHRleHR1cmVUeXBlID09PSBUZXh0dXJlVHlwZS5wYWNrZWQpIHtcbiAgICAgICAgY29uc3QgdW5wYWNrZWRUZXh0dXJlTGF5b3V0ID1cbiAgICAgICAgICAgIGNyZWF0ZVRleHR1cmVMYXlvdXRGcm9tU2hhcGUodGhpcy5zZXNzaW9uLmxheW91dFN0cmF0ZWd5LCB0ZW5zb3IuZGltcywgMSwgW10sIHtyZXZlcnNlV0g6IHRydWV9KTtcbiAgICAgICAgY29uc3QgdW5wYWNrZWRUZXh0dXJlRGF0YSA9IHRoaXMuY3JlYXRlVGV4dHVyZURhdGEoXG4gICAgICAgICAgICB1bnBhY2tlZFRleHR1cmVMYXlvdXQsIHRlbnNvci50eXBlLCB0ZW5zb3IubnVtYmVyRGF0YSwgdGVuc29yLCBFbmNvZGVyLlVzYWdlLlVwbG9hZE9ubHkpO1xuICAgICAgICB0ZCA9IHRoaXMucGFjayh1bnBhY2tlZFRleHR1cmVEYXRhKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRkID0gdGhpcy5jcmVhdGVUZXh0dXJlRGF0YShsYXlvdXQsIHRlbnNvci50eXBlLCB0ZW5zb3IubnVtYmVyRGF0YSwgdGVuc29yLCBFbmNvZGVyLlVzYWdlLlVwbG9hZE9ubHkpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGQ7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgVGV4dHVyZURhdGEgb2JqZWN0IHVzaW5nIHRoZSBnaXZlbiBkYXRhIGFuZCBiaW5kIHRvIHRoZSBnaXZlbiB0ZW5zb3IuXG4gICAqIFVzYWdlID0gRW5jb2Rlci5Vc2FnZS5VcGxvYWRPbmx5LlxuICAgKiBOT1RFOiB0aGlzIGZ1bmN0aW9uIGlzIGEgaGFjayBmb3IgQ29udiBpbXBsZW1lbnRhdGlvbi4gc2hvdWxkIHJlbW92ZSB0aGlzIGZ1bmN0aW9uLCBhZnRlciByZXdyaXRpbmcgQ29udlxuICAgKiBpbXBsZW1lbnRhdGlvbiBieSBHcmFwaC5UcmFuc2Zvcm1lclxuICAgKiBAcGFyYW0gZGF0YVR5cGUgdGhlIHRlbnNvciBkYXRhIHR5cGVcbiAgICogQHBhcmFtIGRhdGEgdGhlIGFjdHVhbCBkYXRhIHRvIHVwbG9hZFxuICAgKiBAcGFyYW0gdGVuc29yIHRoZSB0ZW5zb3IgdG8gYmluZC4gdGVuc29yJ3MgZGF0YSBpcyBpZ25vcmVkLlxuICAgKi9cbiAgY3JlYXRlVGV4dHVyZURhdGFGcm9tTGF5b3V0QmluZFRlbnNvcihcbiAgICAgIGxheW91dDogVGV4dHVyZUxheW91dCwgZGF0YVR5cGU6IFRlbnNvci5EYXRhVHlwZSwgZGF0YTogVGVuc29yLk51bWJlclR5cGUsIHRlbnNvcjogVGVuc29yKTogVGV4dHVyZURhdGEge1xuICAgIHJldHVybiB0aGlzLmNyZWF0ZVRleHR1cmVEYXRhKGxheW91dCwgZGF0YVR5cGUsIGRhdGEsIHRlbnNvciwgRW5jb2Rlci5Vc2FnZS5VcGxvYWRPbmx5KTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlVGV4dHVyZURhdGEoXG4gICAgICBsYXlvdXQ6IFRleHR1cmVMYXlvdXQsIGRhdGFUeXBlOiBUZW5zb3IuRGF0YVR5cGUsIGRhdGE/OiBUZW5zb3IuTnVtYmVyVHlwZSwgdGVuc29yPzogVGVuc29yLFxuICAgICAgdXNhZ2U/OiBFbmNvZGVyLlVzYWdlKTogVGV4dHVyZURhdGEge1xuICAgIExvZ2dlci52ZXJib3NlKCdJbmZlcmVuY2VIYW5kbGVyJywgYENyZWF0aW5nIFRleHR1cmVEYXRhOiBsYXlvdXQ6WyR7SlNPTi5zdHJpbmdpZnkobGF5b3V0KX1dYCk7XG4gICAgY29uc3QgdGV4dHVyZSA9IHRoaXMuc2Vzc2lvbi50ZXh0dXJlTWFuYWdlci5jcmVhdGVUZXh0dXJlRnJvbUxheW91dChkYXRhVHlwZSwgbGF5b3V0LCBkYXRhLCB1c2FnZSk7XG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlVGV4dHVyZURhdGFGcm9tVGV4dHVyZShsYXlvdXQsIGRhdGFUeXBlLCB0ZXh0dXJlLCB0ZW5zb3IpO1xuICB9XG5cbiAgcmVzaGFwZVVucGFja2VkKGlucHV0OiBUZW5zb3IsIHJlc2hhcGVkRGltczogcmVhZG9ubHkgbnVtYmVyW10pOiBUZW5zb3Ige1xuICAgIGNvbnN0IGlucHV0VEQgPSB0aGlzLmdldE9yQ3JlYXRlVGV4dHVyZURhdGEoaW5wdXQsIFRleHR1cmVUeXBlLnVucGFja2VkKTtcbiAgICBjb25zdCBuZXdUZXh0dXJlTGF5b3V0OiBUZXh0dXJlTGF5b3V0ID0ge1xuICAgICAgY2hhbm5lbHM6IGlucHV0VEQuY2hhbm5lbHMsXG4gICAgICBoZWlnaHQ6IGlucHV0VEQuaGVpZ2h0LFxuICAgICAgd2lkdGg6IGlucHV0VEQud2lkdGgsXG4gICAgICAvLyBoYW5kbGUgcmVzaGFwaW5nIGludG8gc2NhbGFyIFRlbnNvcnNcbiAgICAgIHNoYXBlOiByZXNoYXBlZERpbXMubGVuZ3RoICE9PSAwID8gcmVzaGFwZWREaW1zIDogWzFdLFxuICAgICAgc3RyaWRlczogU2hhcGVVdGlsLmNvbXB1dGVTdHJpZGVzKHJlc2hhcGVkRGltcyksXG4gICAgICB1bnBhY2tlZFNoYXBlOiByZXNoYXBlZERpbXMsXG4gICAgfTtcbiAgICBjb25zdCBuZXdUZXh0dXJlRGF0YSA9IHRoaXMuY3JlYXRlVGV4dHVyZURhdGFGcm9tVGV4dHVyZShuZXdUZXh0dXJlTGF5b3V0LCBpbnB1dC50eXBlLCBpbnB1dFRELnRleHR1cmUpO1xuICAgIHJldHVybiBuZXdUZXh0dXJlRGF0YS50ZW5zb3I7XG4gIH1cblxuICByZXNoYXBlUGFja2VkKGlucHV0OiBUZW5zb3IsIHJlc2hhcGVkRGltczogcmVhZG9ubHkgbnVtYmVyW10pOiBUZW5zb3Ige1xuICAgIGNvbnN0IGlucHV0VEQgPSB0aGlzLmdldE9yQ3JlYXRlVGV4dHVyZURhdGEoaW5wdXQsIFRleHR1cmVUeXBlLnBhY2tlZCk7XG5cbiAgICAvLyBjaGVjayBpZiB0aGUgcmVzaGFwZSBpcyAnY2hlYXAnXG4gICAgaWYgKGlzUmVzaGFwZUNoZWFwKGlucHV0LmRpbXMsIHJlc2hhcGVkRGltcykpIHtcbiAgICAgIGNvbnN0IG5ld1RleHR1cmVMYXlvdXQ6IFRleHR1cmVMYXlvdXQgPSB7XG4gICAgICAgIGNoYW5uZWxzOiBpbnB1dFRELmNoYW5uZWxzLFxuICAgICAgICBoZWlnaHQ6IGlucHV0VEQuaGVpZ2h0LFxuICAgICAgICB3aWR0aDogaW5wdXRURC53aWR0aCxcbiAgICAgICAgLy8gaGFuZGxlIHJlc2hhcGluZyBpbnRvIHNjYWxhciBUZW5zb3JzXG4gICAgICAgIHNoYXBlOiByZXNoYXBlZERpbXMubGVuZ3RoICE9PSAwID8gcmVzaGFwZWREaW1zIDogWzFdLFxuICAgICAgICBzdHJpZGVzOiBTaGFwZVV0aWwuY29tcHV0ZVN0cmlkZXMocmVzaGFwZWREaW1zKSxcbiAgICAgICAgdW5wYWNrZWRTaGFwZTogcmVzaGFwZWREaW1zLFxuICAgICAgICBpc1BhY2tlZDogdHJ1ZVxuICAgICAgfTtcbiAgICAgIGNvbnN0IG5ld1RleHR1cmVEYXRhID0gdGhpcy5jcmVhdGVUZXh0dXJlRGF0YUZyb21UZXh0dXJlKG5ld1RleHR1cmVMYXlvdXQsIGlucHV0LnR5cGUsIGlucHV0VEQudGV4dHVyZSk7XG4gICAgICByZXR1cm4gbmV3VGV4dHVyZURhdGEudGVuc29yO1xuICAgIH1cblxuICAgIGNvbnN0IHNxdWVlemVkSW5wdXRTaGFwZSA9IHByb2Nlc3NEaW1zM0QoaW5wdXQuZGltcyk7XG4gICAgY29uc3Qgc3F1ZWV6ZWRPdXRwdXRTaGFwZSA9IHByb2Nlc3NEaW1zM0QocmVzaGFwZWREaW1zKTtcblxuICAgIGNvbnN0IHNxdWVlemVkSW5wdXRUZW5zb3IgPSB0aGlzLnJlc2hhcGVQYWNrZWQoaW5wdXQsIHNxdWVlemVkSW5wdXRTaGFwZSk7XG4gICAgY29uc3Qgc3F1ZWV6ZWRPdXRwdXRUZW5zb3IgPSB0aGlzLnJ1bihcbiAgICAgICAgY3JlYXRlUGFja2VkUmVzaGFwZTNEUHJvZ3JhbUluZm9Mb2FkZXIodGhpcywgc3F1ZWV6ZWRJbnB1dFRlbnNvciwgc3F1ZWV6ZWRPdXRwdXRTaGFwZSksIFtzcXVlZXplZElucHV0VGVuc29yXSk7XG4gICAgY29uc3Qgb3V0cHV0VGVuc29yID0gdGhpcy5yZXNoYXBlUGFja2VkKHNxdWVlemVkT3V0cHV0VGVuc29yLCByZXNoYXBlZERpbXMpO1xuICAgIHJldHVybiBvdXRwdXRUZW5zb3I7XG4gIH1cblxuICBjYXN0KGlucHV0OiBUZW5zb3IsIHR5cGU6IFRlbnNvci5EYXRhVHlwZSk6IFRlbnNvciB7XG4gICAgY29uc3QgaW5wdXRURCA9IHRoaXMuZ2V0T3JDcmVhdGVUZXh0dXJlRGF0YShpbnB1dCwgVGV4dHVyZVR5cGUudW5wYWNrZWQpO1xuICAgIGNvbnN0IG5ld1RleHR1cmVEYXRhID0gdGhpcy5jcmVhdGVUZXh0dXJlRGF0YUZyb21UZXh0dXJlKGlucHV0VEQgYXMgVGV4dHVyZUxheW91dCwgdHlwZSwgaW5wdXRURC50ZXh0dXJlKTtcbiAgICByZXR1cm4gbmV3VGV4dHVyZURhdGEudGVuc29yO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVUZXh0dXJlRGF0YUZyb21UZXh0dXJlKFxuICAgICAgbGF5b3V0OiBUZXh0dXJlTGF5b3V0LCBkYXRhVHlwZTogVGVuc29yLkRhdGFUeXBlLCB0ZXh0dXJlOiBXZWJHTFRleHR1cmUsIHRlbnNvcj86IFRlbnNvciwgdGVuc29ySWQ/OiBUZW5zb3IuSWQpIHtcbiAgICBjb25zdCB0ZXh0dXJlRGF0YTogVGV4dHVyZURhdGEgPSB7XG4gICAgICAuLi5sYXlvdXQsXG4gICAgICB0ZW5zb3I6IHRlbnNvciB8fFxuICAgICAgICAgIG5ldyBUZW5zb3IoXG4gICAgICAgICAgICAgICAgICBsYXlvdXQudW5wYWNrZWRTaGFwZSwgZGF0YVR5cGUsIChfaWQ6IFRlbnNvci5JZCkgPT4gdGhpcy5yZWFkVGV4dHVyZSh0ZXh0dXJlRGF0YSksXG4gICAgICAgICAgICAgICAgICBhc3luYyAoX2lkOiBUZW5zb3IuSWQpID0+IHRoaXMucmVhZFRleHR1cmVBc3luYyh0ZXh0dXJlRGF0YSksIHVuZGVmaW5lZCwgdGVuc29ySWQpLFxuICAgICAgdGV4dHVyZVxuICAgIH07XG4gICAgdGhpcy5zZXRUZXh0dXJlRGF0YSh0ZXh0dXJlRGF0YS50ZW5zb3IuZGF0YUlkLCB0ZXh0dXJlRGF0YSwgbGF5b3V0LmlzUGFja2VkKTtcbiAgICByZXR1cm4gdGV4dHVyZURhdGE7XG4gIH1cblxuICBwcml2YXRlIGdldFRleHR1cmVEYXRhKHRlbnNvcklkOiBUZW5zb3IuSWQsIGlzUGFja2VkID0gZmFsc2UpOiBUZXh0dXJlRGF0YXx1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLnNlc3Npb24uaXNJbml0aWFsaXplcih0ZW5zb3JJZCkgPyB0aGlzLnNlc3Npb24uZ2V0VGV4dHVyZURhdGEodGVuc29ySWQsIGlzUGFja2VkKSA6XG4gICAgICAgIGlzUGFja2VkICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IHRoaXMucGFja2VkVGV4dHVyZURhdGFDYWNoZS5nZXQodGVuc29ySWQpIDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy51bnBhY2tlZFRleHR1cmVEYXRhQ2FjaGUuZ2V0KHRlbnNvcklkKTtcbiAgfVxuICBzZXRUZXh0dXJlRGF0YSh0ZW5zb3JJZDogVGVuc29yLklkLCB0ZDogVGV4dHVyZURhdGEsIGlzUGFja2VkID0gZmFsc2UpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5zZXNzaW9uLmlzSW5pdGlhbGl6ZXIodGVuc29ySWQpKSB7XG4gICAgICB0aGlzLnNlc3Npb24uc2V0VGV4dHVyZURhdGEodGVuc29ySWQsIHRkLCBpc1BhY2tlZCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIChpc1BhY2tlZCA/IHRoaXMucGFja2VkVGV4dHVyZURhdGFDYWNoZSA6IHRoaXMudW5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlKS5zZXQodGVuc29ySWQsIHRkKTtcbiAgICB9XG4gIH1cbiAgaXNUZXh0dXJlTGF5b3V0Q2FjaGVkKHRlbnNvcjogVGVuc29yLCBpc1BhY2tlZCA9IGZhbHNlKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICEhdGhpcy5nZXRUZXh0dXJlRGF0YSh0ZW5zb3IuZGF0YUlkLCBpc1BhY2tlZCk7XG4gIH1cblxuICBkaXNwb3NlKCk6IHZvaWQge1xuICAgIHRoaXMuc2Vzc2lvbi50ZXh0dXJlTWFuYWdlci5jbGVhckFjdGl2ZVRleHR1cmVzKCk7XG4gICAgdGhpcy5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlLmZvckVhY2godGQgPT4gdGhpcy5zZXNzaW9uLnRleHR1cmVNYW5hZ2VyLnJlbGVhc2VUZXh0dXJlKHRkKSk7XG4gICAgdGhpcy5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlID0gbmV3IE1hcCgpO1xuICAgIHRoaXMudW5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlLmZvckVhY2godGQgPT4gdGhpcy5zZXNzaW9uLnRleHR1cmVNYW5hZ2VyLnJlbGVhc2VUZXh0dXJlKHRkKSk7XG4gICAgdGhpcy51bnBhY2tlZFRleHR1cmVEYXRhQ2FjaGUgPSBuZXcgTWFwKCk7XG4gIH1cblxuICByZWFkVGV4dHVyZSh0ZXh0dXJlRGF0YTogVGV4dHVyZURhdGEpOiBUZW5zb3IuTnVtYmVyVHlwZSB7XG4gICAgaWYgKHRleHR1cmVEYXRhLmlzUGFja2VkKSB7XG4gICAgICByZXR1cm4gdGhpcy5yZWFkVGV4dHVyZSh0aGlzLnVucGFjayh0ZXh0dXJlRGF0YSkpO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC5pc0Zsb2F0MzJEb3dubG9hZFN1cHBvcnRlZCkge1xuICAgICAgcmV0dXJuIHRoaXMuc2Vzc2lvbi50ZXh0dXJlTWFuYWdlci5yZWFkVWludDhUZXh0dXJlQXNGbG9hdChlbmNvZGVBc1VpbnQ4KHRoaXMsIHRleHR1cmVEYXRhKSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnNlc3Npb24udGV4dHVyZU1hbmFnZXIucmVhZFRleHR1cmUodGV4dHVyZURhdGEsIHRleHR1cmVEYXRhLnRlbnNvci50eXBlLCB0ZXh0dXJlRGF0YS5jaGFubmVscyk7XG4gIH1cblxuICBhc3luYyByZWFkVGV4dHVyZUFzeW5jKHRleHR1cmVEYXRhOiBUZXh0dXJlRGF0YSk6IFByb21pc2U8VGVuc29yLk51bWJlclR5cGU+IHtcbiAgICBpZiAodGV4dHVyZURhdGEuaXNQYWNrZWQpIHtcbiAgICAgIHJldHVybiB0aGlzLnJlYWRUZXh0dXJlQXN5bmModGhpcy51bnBhY2sodGV4dHVyZURhdGEpKTtcbiAgICB9XG4gICAgaWYgKCF0aGlzLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQuaXNGbG9hdDMyRG93bmxvYWRTdXBwb3J0ZWQpIHtcbiAgICAgIHJldHVybiB0aGlzLnNlc3Npb24udGV4dHVyZU1hbmFnZXIucmVhZFVpbnQ4VGV4dHVyZUFzRmxvYXQoZW5jb2RlQXNVaW50OCh0aGlzLCB0ZXh0dXJlRGF0YSkpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5zZXNzaW9uLnRleHR1cmVNYW5hZ2VyLnJlYWRUZXh0dXJlQXN5bmModGV4dHVyZURhdGEsIHRleHR1cmVEYXRhLnRlbnNvci50eXBlLCB0ZXh0dXJlRGF0YS5jaGFubmVscyk7XG4gIH1cblxuICBwYWNrKGlucHV0OiBUZXh0dXJlRGF0YSk6IFRleHR1cmVEYXRhIHtcbiAgICBjb25zdCBvdXRwdXRUZXh0dXJlRGF0YSA9IHRoaXMuZXhlY3V0ZVByb2dyYW0oY3JlYXRlUGFja1Byb2dyYW1JbmZvTG9hZGVyKHRoaXMsIGlucHV0LnRlbnNvciksIFtpbnB1dC50ZW5zb3JdKTtcbiAgICByZXR1cm4gb3V0cHV0VGV4dHVyZURhdGE7XG4gIH1cblxuICB1bnBhY2soaW5wdXQ6IFRleHR1cmVEYXRhKTogVGV4dHVyZURhdGEge1xuICAgIGNvbnN0IG91dHB1dFRleHR1cmVEYXRhID0gdGhpcy5leGVjdXRlUHJvZ3JhbShjcmVhdGVVbnBhY2tQcm9ncmFtSW5mb0xvYWRlcih0aGlzLCBpbnB1dC50ZW5zb3IpLCBbaW5wdXQudGVuc29yXSk7XG4gICAgcmV0dXJuIG91dHB1dFRleHR1cmVEYXRhO1xuICB9XG59XG4iLCIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtPcFNldH0gZnJvbSAnLi4vLi4vb3BzZXQnO1xuXG5pbXBvcnQge2JhdGNoTm9ybWFsaXphdGlvbiwgcGFyc2VCYXRjaE5vcm1hbGl6YXRpb25BdHRyaWJ1dGVzfSBmcm9tICcuL29wcy9iYXRjaC1ub3JtYWxpemF0aW9uJztcbmltcG9ydCAqIGFzIGJpbmFyeU9wcyBmcm9tICcuL29wcy9iaW5hcnktb3AnO1xuaW1wb3J0IHtjYXN0LCBwYXJzZUNhc3RBdHRyaWJ1dGVzfSBmcm9tICcuL29wcy9jYXN0JztcbmltcG9ydCB7Y29uY2F0LCBwYXJzZUNvbmNhdEF0dHJpYnV0ZXN9IGZyb20gJy4vb3BzL2NvbmNhdCc7XG5pbXBvcnQge2NvbnYsIHBhcnNlQ29udkF0dHJpYnV0ZXN9IGZyb20gJy4vb3BzL2NvbnYnO1xuaW1wb3J0IHtjb252VHJhbnNwb3NlLCBwYXJzZUNvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzfSBmcm9tICcuL29wcy9jb252LXRyYW5zcG9zZSc7XG5pbXBvcnQge2RlcHRoVG9TcGFjZSwgcGFyc2VEZXB0aFRvU3BhY2VBdHRyaWJ1dGVzfSBmcm9tICcuL29wcy9kZXB0aC10by1zcGFjZSc7XG5pbXBvcnQge2ZsYXR0ZW4sIHBhcnNlRmxhdHRlbkF0dHJpYnV0ZXN9IGZyb20gJy4vb3BzL2ZsYXR0ZW4nO1xuaW1wb3J0IHtnYXRoZXIsIHBhcnNlR2F0aGVyQXR0cmlidXRlc30gZnJvbSAnLi9vcHMvZ2F0aGVyJztcbmltcG9ydCB7Z2VtbSwgcGFyc2VHZW1tQXR0cmlidXRlc1YxMSwgcGFyc2VHZW1tQXR0cmlidXRlc1Y3fSBmcm9tICcuL29wcy9nZW1tJztcbmltcG9ydCB7aW1hZ2VTY2FsZXIsIHBhcnNlSW1hZ2VTY2FsZXJBdHRyaWJ1dGVzfSBmcm9tICcuL29wcy9pbWFnZS1zY2FsZXInO1xuaW1wb3J0IHtpbnN0YW5jZU5vcm1hbGl6YXRpb24sIHBhcnNlSW5zdGFuY2VOb3JtYWxpemF0aW9uQXR0cmlidXRlc30gZnJvbSAnLi9vcHMvaW5zdGFuY2Utbm9ybWFsaXphdGlvbic7XG5pbXBvcnQge21hdE11bCwgcGFyc2VNYXRNdWxBdHRyaWJ1dGVzfSBmcm9tICcuL29wcy9tYXRtdWwnO1xuaW1wb3J0IHtwYWRWMTEsIHBhZFYyLCBwYXJzZVBhZEF0dHJpYnV0ZXNWMTEsIHBhcnNlUGFkQXR0cmlidXRlc1YyfSBmcm9tICcuL29wcy9wYWQnO1xuaW1wb3J0IHthdmVyYWdlUG9vbCwgZ2xvYmFsQXZlcmFnZVBvb2wsIGdsb2JhbE1heFBvb2wsIG1heFBvb2wsIHBhcnNlQXZlcmFnZVBvb2xBdHRyaWJ1dGVzLCBwYXJzZUdsb2JhbEF2ZXJhZ2VQb29sQXR0cmlidXRlcywgcGFyc2VNYXhQb29sQXR0cmlidXRlc30gZnJvbSAnLi9vcHMvcG9vbCc7XG5pbXBvcnQge3BhcnNlUmVkdWNlQXR0cmlidXRlcywgcmVkdWNlTG9nU3VtLCByZWR1Y2VMb2dTdW1TcXVhcmUsIHJlZHVjZU1heCwgcmVkdWNlTWVhbiwgcmVkdWNlTWluLCByZWR1Y2VQcm9kLCByZWR1Y2VTdW19IGZyb20gJy4vb3BzL3JlZHVjZSc7XG5pbXBvcnQge3Jlc2hhcGV9IGZyb20gJy4vb3BzL3Jlc2hhcGUnO1xuaW1wb3J0IHtwYXJzZVJlc2l6ZUF0dHJpYnV0ZXNWMTAsIHBhcnNlUmVzaXplQXR0cmlidXRlc1YxMSwgcmVzaXplfSBmcm9tICcuL29wcy9yZXNpemUtcGFja2VkJztcbmltcG9ydCB7c2hhcGV9IGZyb20gJy4vb3BzL3NoYXBlJztcbmltcG9ydCB7cGFyc2VTbGljZUF0dHJpYnV0ZXMsIHNsaWNlLCBzbGljZVYxMH0gZnJvbSAnLi9vcHMvc2xpY2UnO1xuaW1wb3J0IHtwYXJzZVNvZnRtYXhBdHRyaWJ1dGVzLCBwYXJzZVNvZnRtYXhBdHRyaWJ1dGVzVjEzLCBzb2Z0bWF4LCBzb2Z0bWF4VjEzfSBmcm9tICcuL29wcy9zb2Z0bWF4JztcbmltcG9ydCB7cGFyc2VTcGxpdEF0dHJpYnV0ZXMsIHNwbGl0fSBmcm9tICcuL29wcy9zcGxpdCc7XG5pbXBvcnQge3BhcnNlU3F1ZWV6ZUF0dHJpYnV0ZXMsIHNxdWVlemUsIHNxdWVlemVWMTN9IGZyb20gJy4vb3BzL3NxdWVlemUnO1xuaW1wb3J0IHtzdW19IGZyb20gJy4vb3BzL3N1bSc7XG5pbXBvcnQge3RpbGV9IGZyb20gJy4vb3BzL3RpbGUnO1xuaW1wb3J0IHtwYXJzZVRyYW5zcG9zZUF0dHJpYnV0ZXMsIHRyYW5zcG9zZX0gZnJvbSAnLi9vcHMvdHJhbnNwb3NlJztcbmltcG9ydCAqIGFzIHVuYXJ5T3BzIGZyb20gJy4vb3BzL3VuYXJ5LW9wJztcbmltcG9ydCB7cGFyc2VVbnNxdWVlemVBdHRyaWJ1dGVzLCB1bnNxdWVlemUsIHVuc3F1ZWV6ZVYxM30gZnJvbSAnLi9vcHMvdW5zcXVlZXplJztcbmltcG9ydCB7cGFyc2VVcHNhbXBsZUF0dHJpYnV0ZXNWNywgcGFyc2VVcHNhbXBsZUF0dHJpYnV0ZXNWOSwgdXBzYW1wbGV9IGZyb20gJy4vb3BzL3Vwc2FtcGxlJztcblxuZXhwb3J0IGNvbnN0IFdFQkdMX09QX1JFU09MVkVfUlVMRVM6IHJlYWRvbmx5IE9wU2V0LlJlc29sdmVSdWxlW10gPSBbXG4gIFsnQWJzJywgJycsICc2KycsIHVuYXJ5T3BzLmFic10sXG4gIFsnQWNvcycsICcnLCAnNysnLCB1bmFyeU9wcy5hY29zXSxcbiAgWydBZGQnLCAnJywgJzcrJywgYmluYXJ5T3BzLmFkZF0sXG4gIFsnQW5kJywgJycsICc3KycsIGJpbmFyeU9wcy5hbmRdLFxuICBbJ0FzaW4nLCAnJywgJzcrJywgdW5hcnlPcHMuYXNpbl0sXG4gIFsnQXRhbicsICcnLCAnNysnLCB1bmFyeU9wcy5hdGFuXSxcbiAgLy8gVE9ETzogc3VwcG9ydCBuZXcgYXR0cmlidXRlcyBmb3IgQXZlcmFnZVBvb2wtMTBcbiAgWydBdmVyYWdlUG9vbCcsICcnLCAnNysnLCBhdmVyYWdlUG9vbCwgcGFyc2VBdmVyYWdlUG9vbEF0dHJpYnV0ZXNdLFxuICBbJ0JhdGNoTm9ybWFsaXphdGlvbicsICcnLCAnNysnLCBiYXRjaE5vcm1hbGl6YXRpb24sIHBhcnNlQmF0Y2hOb3JtYWxpemF0aW9uQXR0cmlidXRlc10sXG4gIFsnQ2FzdCcsICcnLCAnNisnLCBjYXN0LCBwYXJzZUNhc3RBdHRyaWJ1dGVzXSxcbiAgWydDZWlsJywgJycsICc2KycsIHVuYXJ5T3BzLmNlaWxdLFxuICBbJ0NsaXAnLCAnJywgJzYtMTAnLCB1bmFyeU9wcy5jbGlwLCB1bmFyeU9wcy5wYXJzZUNsaXBBdHRyaWJ1dGVzXSxcbiAgWydDbGlwJywgJycsICcxMSsnLCB1bmFyeU9wcy5jbGlwVjExXSxcbiAgWydDb25jYXQnLCAnJywgJzQrJywgY29uY2F0LCBwYXJzZUNvbmNhdEF0dHJpYnV0ZXNdLFxuICBbJ0NvbnYnLCAnJywgJzErJywgY29udiwgcGFyc2VDb252QXR0cmlidXRlc10sXG4gIFsnQ29udlRyYW5zcG9zZScsICcnLCAnMSsnLCBjb252VHJhbnNwb3NlLCBwYXJzZUNvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzXSxcbiAgWydDb3MnLCAnJywgJzcrJywgdW5hcnlPcHMuY29zXSxcbiAgWydEaXYnLCAnJywgJzcrJywgYmluYXJ5T3BzLmRpdl0sXG4gIFsnRHJvcG91dCcsICcnLCAnNysnLCB1bmFyeU9wcy5pZGVudGl0eV0sXG4gIFsnRGVwdGhUb1NwYWNlJywgJycsICcxKycsIGRlcHRoVG9TcGFjZSwgcGFyc2VEZXB0aFRvU3BhY2VBdHRyaWJ1dGVzXSxcbiAgWydFcXVhbCcsICcnLCAnNysnLCBiaW5hcnlPcHMuZXF1YWxdLFxuICBbJ0VsdScsICcnLCAnNisnLCB1bmFyeU9wcy5lbHUsIHVuYXJ5T3BzLnBhcnNlRWx1QXR0cmlidXRlc10sXG4gIFsnRXhwJywgJycsICc2KycsIHVuYXJ5T3BzLmV4cF0sXG4gIFsnRmxhdHRlbicsICcnLCAnMSsnLCBmbGF0dGVuLCBwYXJzZUZsYXR0ZW5BdHRyaWJ1dGVzXSxcbiAgWydGbG9vcicsICcnLCAnNisnLCB1bmFyeU9wcy5mbG9vcl0sXG4gIFsnRnVzZWRDb252JywgJ2NvbS5taWNyb3NvZnQnLCAnMSsnLCBjb252LCBwYXJzZUNvbnZBdHRyaWJ1dGVzXSxcbiAgWydHYXRoZXInLCAnJywgJzErJywgZ2F0aGVyLCBwYXJzZUdhdGhlckF0dHJpYnV0ZXNdLFxuICBbJ0dlbW0nLCAnJywgJzctMTAnLCBnZW1tLCBwYXJzZUdlbW1BdHRyaWJ1dGVzVjddLFxuICBbJ0dlbW0nLCAnJywgJzExKycsIGdlbW0sIHBhcnNlR2VtbUF0dHJpYnV0ZXNWMTFdLFxuICBbJ0dsb2JhbEF2ZXJhZ2VQb29sJywgJycsICcxKycsIGdsb2JhbEF2ZXJhZ2VQb29sLCBwYXJzZUdsb2JhbEF2ZXJhZ2VQb29sQXR0cmlidXRlc10sXG4gIFsnR2xvYmFsTWF4UG9vbCcsICcnLCAnMSsnLCBnbG9iYWxNYXhQb29sXSxcbiAgWydHcmVhdGVyJywgJycsICc3KycsIGJpbmFyeU9wcy5ncmVhdGVyXSxcbiAgWydJZGVudGl0eScsICcnLCAnMSsnLCB1bmFyeU9wcy5pZGVudGl0eV0sXG4gIFsnSW1hZ2VTY2FsZXInLCAnJywgJzErJywgaW1hZ2VTY2FsZXIsIHBhcnNlSW1hZ2VTY2FsZXJBdHRyaWJ1dGVzXSxcbiAgWydJbnN0YW5jZU5vcm1hbGl6YXRpb24nLCAnJywgJzYrJywgaW5zdGFuY2VOb3JtYWxpemF0aW9uLCBwYXJzZUluc3RhbmNlTm9ybWFsaXphdGlvbkF0dHJpYnV0ZXNdLFxuICBbJ0xlYWt5UmVsdScsICcnLCAnNisnLCB1bmFyeU9wcy5sZWFreVJlbHUsIHVuYXJ5T3BzLnBhcnNlTGVha3lSZWx1QXR0cmlidXRlc10sXG4gIFsnTGVzcycsICcnLCAnNysnLCBiaW5hcnlPcHMubGVzc10sXG4gIFsnTG9nJywgJycsICc2KycsIHVuYXJ5T3BzLmxvZ10sXG4gIFsnTWF0TXVsJywgJycsICcxKycsIG1hdE11bCwgcGFyc2VNYXRNdWxBdHRyaWJ1dGVzXSxcbiAgLy8gVE9ETzogc3VwcG9ydCBuZXcgYXR0cmlidXRlcyBmb3IgTWF4UG9vbC04IGFuZCBNYXhQb29sLTEwXG4gIFsnTWF4UG9vbCcsICcnLCAnMSsnLCBtYXhQb29sLCBwYXJzZU1heFBvb2xBdHRyaWJ1dGVzXSxcbiAgWydNdWwnLCAnJywgJzcrJywgYmluYXJ5T3BzLm11bF0sXG4gIFsnTmVnJywgJycsICc2KycsIHVuYXJ5T3BzLm5lZ10sXG4gIFsnTm90JywgJycsICcxKycsIHVuYXJ5T3BzLm5vdF0sXG4gIFsnT3InLCAnJywgJzcrJywgYmluYXJ5T3BzLm9yXSxcbiAgWydQYWQnLCAnJywgJzItMTAnLCBwYWRWMiwgcGFyc2VQYWRBdHRyaWJ1dGVzVjJdLFxuICBbJ1BhZCcsICcnLCAnMTErJywgcGFkVjExLCBwYXJzZVBhZEF0dHJpYnV0ZXNWMTFdLFxuICBbJ1BvdycsICcnLCAnNysnLCBiaW5hcnlPcHMucG93XSxcbiAgWydQUmVsdScsICcnLCAnNysnLCBiaW5hcnlPcHMucFJlbHVdLFxuICBbJ1JlZHVjZUxvZ1N1bScsICcnLCAnMSsnLCByZWR1Y2VMb2dTdW0sIHBhcnNlUmVkdWNlQXR0cmlidXRlc10sXG4gIFsnUmVkdWNlTWF4JywgJycsICcxKycsIHJlZHVjZU1heCwgcGFyc2VSZWR1Y2VBdHRyaWJ1dGVzXSxcbiAgWydSZWR1Y2VNZWFuJywgJycsICcxKycsIHJlZHVjZU1lYW4sIHBhcnNlUmVkdWNlQXR0cmlidXRlc10sXG4gIFsnUmVkdWNlTWluJywgJycsICcxKycsIHJlZHVjZU1pbiwgcGFyc2VSZWR1Y2VBdHRyaWJ1dGVzXSxcbiAgWydSZWR1Y2VQcm9kJywgJycsICcxKycsIHJlZHVjZVByb2QsIHBhcnNlUmVkdWNlQXR0cmlidXRlc10sXG4gIFsnUmVkdWNlU3VtJywgJycsICcxLTEyJywgcmVkdWNlU3VtLCBwYXJzZVJlZHVjZUF0dHJpYnV0ZXNdLFxuICBbJ1JlZHVjZVN1bVNxdWFyZScsICcnLCAnMSsnLCByZWR1Y2VMb2dTdW1TcXVhcmUsIHBhcnNlUmVkdWNlQXR0cmlidXRlc10sXG4gIFsnUmVsdScsICcnLCAnNisnLCB1bmFyeU9wcy5yZWx1XSxcbiAgWydSZXNoYXBlJywgJycsICc1KycsIHJlc2hhcGVdLFxuICBbJ1Jlc2l6ZScsICcnLCAnMTAnLCByZXNpemUsIHBhcnNlUmVzaXplQXR0cmlidXRlc1YxMF0sXG4gIFsnUmVzaXplJywgJycsICcxMSsnLCByZXNpemUsIHBhcnNlUmVzaXplQXR0cmlidXRlc1YxMV0sXG4gIFsnU2hhcGUnLCAnJywgJzErJywgc2hhcGVdLFxuICBbJ1NpZ21vaWQnLCAnJywgJzYrJywgdW5hcnlPcHMuc2lnbW9pZF0sXG4gIFsnU2luJywgJycsICc3KycsIHVuYXJ5T3BzLnNpbl0sXG4gIFsnU2xpY2UnLCAnJywgJzEwKycsIHNsaWNlVjEwXSwgIC8vIFRPRE86IHN1cHBvcnQgJ3N0ZXBzJyBmb3IgU2xpY2UtMTBcbiAgWydTbGljZScsICcnLCAnMS05Jywgc2xpY2UsIHBhcnNlU2xpY2VBdHRyaWJ1dGVzXSxcbiAgLy8gVGhlIFwic2VtYW50aWNcIiBtZWFuaW5nIG9mIGF4aXMgaGFzIGNoYW5nZWQgaW4gb3BzZXQtMTMuXG4gIFsnU29mdG1heCcsICcnLCAnMS0xMicsIHNvZnRtYXgsIHBhcnNlU29mdG1heEF0dHJpYnV0ZXNdLFxuICBbJ1NvZnRtYXgnLCAnJywgJzEzKycsIHNvZnRtYXhWMTMsIHBhcnNlU29mdG1heEF0dHJpYnV0ZXNWMTNdLFxuICAvLyAnU3BsaXQnIG9wZXJhdG9yIGhhcyBhbiBvcHRpb25hbCBhdHRyaWJ1dGUgJ3NwbGl0J1xuICAvLyB0aGlzIGF0dHJpYnV0ZSBkZXRlcm1pbmVzIGhvdyB0aGUgc3BlY2lmaWVkIGF4aXMgb2YgaW5wdXQgZGF0YSBpcyBzcGxpdC5cbiAgLy8gV2hlbiB0aGUgYXR0cmlidXRlIGlzIG1pc3NpbmcsIHdlIG5lZWQgdGhlIGNvdW50IG9mIG51bWJlciBvZiBvdXRwdXRzXG4gIC8vIHNvIHRoYXQgd2UgY2FuIGRldGVybWluZSB0aGUgJ3NwbGl0JyBhdHRyaWJ1dGUgZnJvbSB0aGUgcnVudGltZSBpbnB1dCB0byB0aGUgT3BlcmF0b3JcbiAgWydTcGxpdCcsICcnLCAnMi0xMicsIHNwbGl0LCBwYXJzZVNwbGl0QXR0cmlidXRlc10sXG4gIFsnU3FydCcsICcnLCAnNisnLCB1bmFyeU9wcy5zcXJ0XSxcbiAgWydTcXVlZXplJywgJycsICcxLTEyJywgc3F1ZWV6ZSwgcGFyc2VTcXVlZXplQXR0cmlidXRlc10sXG4gIFsnU3F1ZWV6ZScsICcnLCAnMTMrJywgc3F1ZWV6ZVYxM10sXG4gIFsnU3ViJywgJycsICc3KycsIGJpbmFyeU9wcy5zdWJdLFxuICBbJ1N1bScsICcnLCAnNisnLCBzdW1dLFxuICBbJ1RhbicsICcnLCAnNysnLCB1bmFyeU9wcy50YW5dLFxuICBbJ1RhbmgnLCAnJywgJzYrJywgdW5hcnlPcHMudGFuaF0sXG4gIFsnVGlsZScsICcnLCAnNisnLCB0aWxlXSxcbiAgWydUcmFuc3Bvc2UnLCAnJywgJzErJywgdHJhbnNwb3NlLCBwYXJzZVRyYW5zcG9zZUF0dHJpYnV0ZXNdLFxuICBbJ1Vwc2FtcGxlJywgJycsICc3LTgnLCB1cHNhbXBsZSwgcGFyc2VVcHNhbXBsZUF0dHJpYnV0ZXNWN10sXG4gIFsnVXBzYW1wbGUnLCAnJywgJzknLCB1cHNhbXBsZSwgcGFyc2VVcHNhbXBsZUF0dHJpYnV0ZXNWOV0sXG4gIFsnVW5zcXVlZXplJywgJycsICcxLTEyJywgdW5zcXVlZXplLCBwYXJzZVVuc3F1ZWV6ZUF0dHJpYnV0ZXNdLFxuICBbJ1Vuc3F1ZWV6ZScsICcnLCAnMTMrJywgdW5zcXVlZXplVjEzXSxcbiAgWydYb3InLCAnJywgJzcrJywgYmluYXJ5T3BzLnhvcl0sXG5dO1xuIiwiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7QXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXl9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQge0dyYXBofSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQge09wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb259IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7Z2V0R2xzbH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHtXZWJHTEluZmVyZW5jZUhhbmRsZXJ9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7UHJvZ3JhbUluZm8sIFRleHR1cmVUeXBlfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQmF0Y2hOb3JtYWxpemF0aW9uQXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIGVwc2lsb246IG51bWJlcjtcbiAgbW9tZW50dW06IG51bWJlcjtcbiAgc3BhdGlhbDogbnVtYmVyO1xufVxuXG5jb25zdCBiYXRjaE5vcm1hbGl6YXRpb25Qcm9ncmFtTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdCYXRjaE5vcm1hbGl6YXRpb24nLFxuICBpbnB1dE5hbWVzOiBbJ0EnLCAnU2NhbGUnLCAnQicsICdNZWFuJywgJ1ZhcmlhbmNlJ10sXG4gIGlucHV0VHlwZXM6XG4gICAgICBbVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnVucGFja2VkXVxufTtcblxuZXhwb3J0IGNvbnN0IGJhdGNoTm9ybWFsaXphdGlvbjogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxCYXRjaE5vcm1hbGl6YXRpb25BdHRyaWJ1dGVzPiA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogQmF0Y2hOb3JtYWxpemF0aW9uQXR0cmlidXRlcyk6IFRlbnNvcltdID0+IHtcbiAgICAgIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG4gICAgICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICAgICAgICB7XG4gICAgICAgICAgICAuLi5iYXRjaE5vcm1hbGl6YXRpb25Qcm9ncmFtTWV0YWRhdGEsXG4gICAgICAgICAgICBjYWNoZUhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXksXG4gICAgICAgICAgICBnZXQ6ICgpID0+IGNyZWF0ZUJhdGNoTm9ybWFsaXphdGlvblByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcylcbiAgICAgICAgICB9LFxuICAgICAgICAgIGlucHV0cyk7XG4gICAgICByZXR1cm4gW291dHB1dF07XG4gICAgfTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlQmF0Y2hOb3JtYWxpemF0aW9uQXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxCYXRjaE5vcm1hbGl6YXRpb25BdHRyaWJ1dGVzPiA9XG4gICAgKG5vZGU6IEdyYXBoLk5vZGUpOiBCYXRjaE5vcm1hbGl6YXRpb25BdHRyaWJ1dGVzID0+IHtcbiAgICAgIGNvbnN0IGVwc2lsb24gPSBub2RlLmF0dHJpYnV0ZXMuZ2V0RmxvYXQoJ2Vwc2lsb24nLCAxZS01KTtcbiAgICAgIGNvbnN0IG1vbWVudHVtID0gbm9kZS5hdHRyaWJ1dGVzLmdldEZsb2F0KCdtb21lbnR1bScsIDAuOSk7XG4gICAgICBjb25zdCBzcGF0aWFsID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludCgnc3BhdGlhbCcsIDEpO1xuICAgICAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7ZXBzaWxvbiwgbW9tZW50dW0sIHNwYXRpYWx9KTtcbiAgICB9O1xuXG5jb25zdCBjcmVhdGVCYXRjaE5vcm1hbGl6YXRpb25Qcm9ncmFtSW5mbyA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogQmF0Y2hOb3JtYWxpemF0aW9uQXR0cmlidXRlcyk6XG4gICAgICAgIFByb2dyYW1JbmZvID0+IHtcbiAgICAgICAgICBjb25zdCBnbHNsID0gZ2V0R2xzbChpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gICAgICAgICAgY29uc3QgcmFuayA9IGlucHV0c1swXS5kaW1zLmxlbmd0aDtcbiAgICAgICAgICBjb25zdCBbc2NhbGVXaWR0aCwgc2NhbGVIZWlnaHRdID1cbiAgICAgICAgICAgICAgaW5mZXJlbmNlSGFuZGxlci5jYWxjdWxhdGVUZXh0dXJlV2lkdGhBbmRIZWlnaHQoaW5wdXRzWzFdLmRpbXMsIFRleHR1cmVUeXBlLnVucGFja2VkKTtcbiAgICAgICAgICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gIGZsb2F0IHByb2Nlc3MoaW50WyR7cmFua31dIGluZGljZXMpIHtcbiAgICB2ZWMyIHBvc2l0aW9uID0gb2Zmc2V0VG9Db29yZHMoaW5kaWNlc1sxXSwgJHtzY2FsZVdpZHRofSwgJHtzY2FsZUhlaWdodH0pO1xuICAgIGZsb2F0IHNjYWxlID0gZ2V0Q29sb3JBc0Zsb2F0KCR7Z2xzbC50ZXh0dXJlMkR9KFNjYWxlLCBwb3NpdGlvbikpO1xuICAgIGZsb2F0IG1lYW4gPSBnZXRDb2xvckFzRmxvYXQoJHtnbHNsLnRleHR1cmUyRH0oTWVhbiwgcG9zaXRpb24pKTtcbiAgICBmbG9hdCB2YXJpYW5jZSA9IGdldENvbG9yQXNGbG9hdCgke2dsc2wudGV4dHVyZTJEfShWYXJpYW5jZSwgcG9zaXRpb24pKTtcbiAgICBmbG9hdCBiID0gZ2V0Q29sb3JBc0Zsb2F0KCR7Z2xzbC50ZXh0dXJlMkR9KEIsIHBvc2l0aW9uKSk7XG5cbiAgICByZXR1cm4gc2NhbGUgKiAoIChfQShpbmRpY2VzKSAtIG1lYW4pIC8gc3FydCh2YXJpYW5jZSArIGZsb2F0KCR7YXR0cmlidXRlcy5lcHNpbG9ufSkpICkgKyBiO1xuICB9YDtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgLi4uYmF0Y2hOb3JtYWxpemF0aW9uUHJvZ3JhbU1ldGFkYXRhLFxuICAgICAgICAgICAgb3V0cHV0OiB7ZGltczogaW5wdXRzWzBdLmRpbXMsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWR9LFxuICAgICAgICAgICAgc2hhZGVyU291cmNlXG4gICAgICAgICAgfTtcbiAgICAgICAgfTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSA1KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdCYXRjaE5vcm1hbGl6YXRpb24gcmVxdWlyZXMgNSBpbnB1dHMuJyk7XG4gIH1cblxuICBjb25zdCBYID0gaW5wdXRzWzBdO1xuICBjb25zdCBzY2FsZSA9IGlucHV0c1sxXTtcbiAgY29uc3QgQiA9IGlucHV0c1syXTtcbiAgY29uc3QgbWVhbiA9IGlucHV0c1szXTtcbiAgY29uc3QgdmFyXyA9IGlucHV0c1s0XTtcblxuICAvLyBpbnB1dCBzaG91bGQgYXRsZWFzdCBoYXZlIHRocmVlIGRpbWVuc2lvbnMgLSBOLEMsZGltMSwuLi4sZGltblxuICAvLyBvdGhlciBpbnB1dHMgY2FuIGhhdmUgb25seSBvbmUgZGltZW5zaW9uc1xuICBpZiAoWC5kaW1zLmxlbmd0aCA8IDMgfHwgc2NhbGUuZGltcy5sZW5ndGggIT09IDEgfHwgQi5kaW1zLmxlbmd0aCAhPT0gMSB8fCBtZWFuLmRpbXMubGVuZ3RoICE9PSAxIHx8XG4gICAgICB2YXJfLmRpbXMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGlucHV0IHNoYXBlLicpO1xuICB9XG4gIGlmIChzY2FsZS5kaW1zWzBdICE9PSBYLmRpbXNbMV0gfHwgQi5kaW1zWzBdICE9PSBYLmRpbXNbMV0gfHwgbWVhbi5kaW1zWzBdICE9PSBYLmRpbXNbMV0gfHxcbiAgICAgIHZhcl8uZGltc1swXSAhPT0gWC5kaW1zWzFdKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGlucHV0IHNoYXBlLicpO1xuICB9XG4gIGlmICgoWC50eXBlICE9PSAnZmxvYXQzMicgJiYgWC50eXBlICE9PSAnZmxvYXQ2NCcpIHx8IChzY2FsZS50eXBlICE9PSAnZmxvYXQzMicgJiYgc2NhbGUudHlwZSAhPT0gJ2Zsb2F0NjQnKSB8fFxuICAgICAgKEIudHlwZSAhPT0gJ2Zsb2F0MzInICYmIEIudHlwZSAhPT0gJ2Zsb2F0NjQnKSB8fCAobWVhbi50eXBlICE9PSAnZmxvYXQzMicgJiYgbWVhbi50eXBlICE9PSAnZmxvYXQ2NCcpIHx8XG4gICAgICAodmFyXy50eXBlICE9PSAnZmxvYXQzMicgJiYgdmFyXy50eXBlICE9PSAnZmxvYXQ2NCcpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGlucHV0IHRlbnNvciB0eXBlcy4nKTtcbiAgfVxufTtcbiIsIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7QnJvYWRjYXN0VXRpbCwgU2hhcGVVdGlsfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7RnVuY3Rpb25UeXBlLCBHbHNsVmFsdWVGdW5jdGlvbn0gZnJvbSAnLi4vZ2xzbC1kZWZpbml0aW9ucyc7XG5pbXBvcnQge2dldEdsc2x9IGZyb20gJy4uL2dsc2wtc291cmNlJztcbmltcG9ydCB7V2ViR0xJbmZlcmVuY2VIYW5kbGVyfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQge1Byb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgVGV4dHVyZVR5cGV9IGZyb20gJy4uL3R5cGVzJztcblxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xBZGQoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ2FkZF8nO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9KGZsb2F0IGEsIGZsb2F0IGIpIHtcbiAgICByZXR1cm4gYSArIGI7XG4gIH1cbiAgdmVjNCAke25hbWV9KHZlYzQgdjEsIHZlYzQgdjIpIHtcbiAgICByZXR1cm4gdjEgKyB2MjtcbiAgfVxuICBgO1xuICByZXR1cm4ge2JvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsRGl2KCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdkaXZfJztcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfShmbG9hdCBhLCBmbG9hdCBiKSB7XG4gICAgcmV0dXJuIGEgLyBiO1xuICB9XG4gIHZlYzQgJHtuYW1lfSh2ZWM0IHYxLCB2ZWM0IHYyKSB7XG4gICAgcmV0dXJuIHYxIC8gdjI7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHtib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbE11bCgpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIGNvbnN0IG5hbWUgPSAnbXVsXyc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX0oZmxvYXQgYSwgZmxvYXQgYikge1xuICAgIHJldHVybiBhICogYjtcbiAgfVxuICB2ZWM0ICR7bmFtZX0odmVjNCB2MSwgdmVjNCB2Mikge1xuICAgIHJldHVybiB2MSAqIHYyO1xuICB9XG4gIGA7XG4gIHJldHVybiB7Ym9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWR9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xTdWIoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ3N1Yl8nO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9KGZsb2F0IGEsIGZsb2F0IGIpIHtcbiAgICByZXR1cm4gYSAtIGI7XG4gIH1cbiAgdmVjNCAke25hbWV9KHZlYzQgdjEsIHZlYzQgdjIpIHtcbiAgICByZXR1cm4gdjEgLSB2MjtcbiAgfVxuICBgO1xuICByZXR1cm4ge2JvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsRXF1YWwoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ2VxdWFsXyc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX0oZmxvYXQgYSwgZmxvYXQgYikge1xuICAgIHJldHVybiBmbG9hdChhID09IGIpO1xuICB9XG4gIHZlYzQgJHtuYW1lfSh2ZWM0IHYxLCB2ZWM0IHYyKSB7XG4gICAgcmV0dXJuIHZlYzQoZXF1YWwodjEsIHYyKSk7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHtib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbEdyZWF0ZXIoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ2dyZWF0ZXJfJztcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfShmbG9hdCBhLCBmbG9hdCBiKSB7XG4gICAgcmV0dXJuIGZsb2F0KGEgPiBiKTtcbiAgfVxuICB2ZWM0ICR7bmFtZX0odmVjNCB2MSwgdmVjNCB2Mikge1xuICAgIHJldHVybiB2ZWM0KCB2MS5yID4gdjIuciAsXG4gICAgICB2MS5nID4gdjIuZyxcbiAgICAgIHYxLmIgPiB2Mi5iLFxuICAgICAgdjEuYSA+IHYyLmEgKTtcbiAgfVxuICBgO1xuICByZXR1cm4ge2JvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsTGVzcygpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIGNvbnN0IG5hbWUgPSAnbGVzc18nO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9KGZsb2F0IGEsIGZsb2F0IGIpIHtcbiAgICByZXR1cm4gZmxvYXQoYSA8IGIpO1xuICB9XG4gIHZlYzQgJHtuYW1lfSh2ZWM0IHYxLCB2ZWM0IHYyKSB7XG4gICAgcmV0dXJuIHZlYzQoIHYxLnIgPCB2Mi5yICxcbiAgICAgICAgICAgICAgICB2MS5nIDwgdjIuZyxcbiAgICAgICAgICAgICAgICB2MS5iIDwgdjIuYixcbiAgICAgICAgICAgICAgICB2MS5hIDwgdjIuYSApO1xuICB9XG4gIGA7XG4gIHJldHVybiB7Ym9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWR9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xBbmQoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ2FuZF8nO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9KGZsb2F0IGEsIGZsb2F0IGIpIHtcbiAgICByZXR1cm4gZmxvYXQoIGJvb2woYSkgJiYgYm9vbChiKSApO1xuICB9XG4gIHZlYzQgJHtuYW1lfSh2ZWM0IHYxLCB2ZWM0IHYyKSB7XG4gICAgYnZlYzQgYjEgPSBidmVjNCh2MSk7XG4gICAgYnZlYzQgYjIgPSBidmVjNCh2Mik7XG4gICAgcmV0dXJuIHZlYzQoIGIxLnIgJiYgYjIuciAsXG4gICAgICAgICAgICAgICAgYjEuZyAmJiBiMi5nLFxuICAgICAgICAgICAgICAgIGIxLmIgJiYgYjIuYixcbiAgICAgICAgICAgICAgICBiMS5hICYmIGIyLmEgKTtcbiAgfVxuICBgO1xuICByZXR1cm4ge2JvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsT3IoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ29yXyc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX0oZmxvYXQgYSwgZmxvYXQgYikge1xuICAgIHJldHVybiBmbG9hdCggYm9vbChhKSB8fCBib29sKGIpICk7XG4gIH1cbiAgdmVjNCAke25hbWV9KHZlYzQgdjEsIHZlYzQgdjIpIHtcbiAgICBidmVjNCBiMSA9IGJ2ZWM0KHYxKTtcbiAgICBidmVjNCBiMiA9IGJ2ZWM0KHYyKTtcbiAgICByZXR1cm4gdmVjNCggYjEuciB8fCBiMi5yICxcbiAgICAgICAgICAgICAgICBiMS5nIHx8IGIyLmcsXG4gICAgICAgICAgICAgICAgYjEuYiB8fCBiMi5iLFxuICAgICAgICAgICAgICAgIGIxLmEgfHwgYjIuYSApO1xuICB9XG4gIGA7XG4gIHJldHVybiB7Ym9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWR9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xYb3IoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ3hvcl8nO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9KGZsb2F0IGEsIGZsb2F0IGIpIHtcbiAgICByZXR1cm4gZmxvYXQoIGJvb2woYSkgXl4gYm9vbChiKSApO1xuICB9XG4gIHZlYzQgJHtuYW1lfSh2ZWM0IHYxLCB2ZWM0IHYyKSB7XG4gICAgYnZlYzQgYjEgPSBidmVjNCh2MSk7XG4gICAgYnZlYzQgYjIgPSBidmVjNCh2Mik7XG4gICAgcmV0dXJuIHZlYzQoIGIxLnIgXl4gYjIuciAsXG4gICAgICAgICAgICAgICAgYjEuZyBeXiBiMi5nLFxuICAgICAgICAgICAgICAgIGIxLmIgXl4gYjIuYixcbiAgICAgICAgICAgICAgICBiMS5hIF5eIGIyLmEgKTtcbiAgfVxuICBgO1xuICByZXR1cm4ge2JvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsUG93KCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgcmV0dXJuIGdsc2xCdWlsdGluQmluYXJ5KCdwb3cnKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsUFJlbHUoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ3ByZWx1Xyc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX0oZmxvYXQgYSwgZmxvYXQgYikge1xuICAgIHJldHVybiBhIDwgMC4wID8gYSAqIGI6IGE7XG4gIH1cbiAgdmVjNCAke25hbWV9KHZlYzQgdjEsIHZlYzQgdjIpIHtcbiAgICByZXR1cm4gdmVjNChcbiAgICAgIHYxLnIgPCAwLjAgPyB2MS5yICogdjIucjogdjEucixcbiAgICAgIHYxLmcgPCAwLjAgPyB2MS5nICogdjIuZzogdjEuZyxcbiAgICAgIHYxLmIgPCAwLjAgPyB2MS5iICogdjIuYjogdjEuYixcbiAgICAgIHYxLmEgPCAwLjAgPyB2MS5hICogdjIuYTogdjEuYVxuICAgICAgKTtcbiAgfVxuICBgO1xuICByZXR1cm4ge2JvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkfTtcbn1cblxuZnVuY3Rpb24gZ2xzbEJ1aWx0aW5CaW5hcnkoZm5hbWU6IHN0cmluZyk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9IGAke2ZuYW1lfV9gO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9KGZsb2F0IGEsIGZsb2F0IGIpIHtcbiAgICByZXR1cm4gJHtmbmFtZX0oYSwgYik7XG4gIH1cbiAgdmVjNCAke25hbWV9KHZlYzQgdjEsIHZlYzQgdjIpIHtcbiAgICByZXR1cm4gJHtmbmFtZX0odjEsIHYyKTtcbiAgfVxuICBgO1xuICByZXR1cm4ge2JvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkfTtcbn1cblxuY29uc3QgY3JlYXRlQmluYXJ5UHJvZ3JhbUluZm9Mb2FkZXIgPVxuICAgIChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIGdsc2xGdW5jOiBHbHNsVmFsdWVGdW5jdGlvbixcbiAgICAgb3V0cHV0VGVuc29yVHlwZTogVGVuc29yLkRhdGFUeXBlID0gaW5wdXRzWzBdLnR5cGUsIGNhY2hlS2V5Pzogc3RyaW5nKTogUHJvZ3JhbUluZm9Mb2FkZXIgPT4ge1xuICAgICAgY29uc3QgdGV4dHVyZVR5cGUgPSBoYW5kbGVyLnNlc3Npb24ucGFjayA/IFRleHR1cmVUeXBlLnBhY2tlZCA6IFRleHR1cmVUeXBlLnVucGFja2VkO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgbmFtZTogZ2xzbEZ1bmMubmFtZSxcbiAgICAgICAgaW5wdXROYW1lczogWydBJywgJ0InXSxcbiAgICAgICAgaW5wdXRUeXBlczogW3RleHR1cmVUeXBlLCB0ZXh0dXJlVHlwZV0sXG4gICAgICAgIGNhY2hlSGludDogY2FjaGVLZXksXG4gICAgICAgIGdldDogKCkgPT4gY3JlYXRlQmluYXJ5UHJvZ3JhbUluZm8oaGFuZGxlciwgaW5wdXRzLCBnbHNsRnVuYywgb3V0cHV0VGVuc29yVHlwZSlcbiAgICAgIH07XG4gICAgfTtcblxuY29uc3QgY3JlYXRlQmluYXJ5UHJvZ3JhbUluZm8gPVxuICAgIChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIGdsc2xGdW5jOiBHbHNsVmFsdWVGdW5jdGlvbixcbiAgICAgb3V0cHV0VGVuc29yVHlwZTogVGVuc29yLkRhdGFUeXBlID0gaW5wdXRzWzBdLnR5cGUpOiBQcm9ncmFtSW5mbyA9PiB7XG4gICAgICBjb25zdCB0ZXh0dXJlVHlwZSA9IGhhbmRsZXIuc2Vzc2lvbi5wYWNrID8gVGV4dHVyZVR5cGUucGFja2VkIDogVGV4dHVyZVR5cGUudW5wYWNrZWQ7XG4gICAgICBjb25zdCBpc0Jyb2FkY2FzdCA9ICFTaGFwZVV0aWwuYXJlRXF1YWwoaW5wdXRzWzBdLmRpbXMsIGlucHV0c1sxXS5kaW1zKTtcbiAgICAgIGxldCBvdXRwdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuXG4gICAgICBjb25zdCB1c2VQYWNrZWRUZXh0dXJlID0gaGFuZGxlci5zZXNzaW9uLnBhY2s7XG5cbiAgICAgIGlmIChpc0Jyb2FkY2FzdCkge1xuICAgICAgICBjb25zdCBjYWxjdWxhdGVkU2hhcGUgPSBCcm9hZGNhc3RVdGlsLmNhbGNTaGFwZShpbnB1dHNbMF0uZGltcywgaW5wdXRzWzFdLmRpbXMsIGZhbHNlKTtcbiAgICAgICAgaWYgKCFjYWxjdWxhdGVkU2hhcGUpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NhblxcJ3QgcGVyZm9ybSBiaW5hcnkgb3Agb24gdGhlIGdpdmVuIHRlbnNvcnMnKTtcbiAgICAgICAgfVxuICAgICAgICBvdXRwdXRTaGFwZSA9IGNhbGN1bGF0ZWRTaGFwZTtcbiAgICAgICAgY29uc3Qgb3V0cHV0UmFuayA9IG91dHB1dFNoYXBlLmxlbmd0aDtcbiAgICAgICAgY29uc3QgYVJhbmsgPSBpbnB1dHNbMF0uZGltcy5sZW5ndGggIT09IDAgPyBpbnB1dHNbMF0uZGltcy5sZW5ndGggOiAxO1xuICAgICAgICBjb25zdCBiUmFuayA9IGlucHV0c1sxXS5kaW1zLmxlbmd0aCAhPT0gMCA/IGlucHV0c1sxXS5kaW1zLmxlbmd0aCA6IDE7XG4gICAgICAgIGNvbnN0IGFCY2FzdCA9IGlucHV0c1swXS5kaW1zLmxlbmd0aCAhPT0gMCA/ICdiY2FzdEluZGljZXNfQShpbmRpY2VzLCBhaW5kaWNlcyk7JyA6ICdhaW5kaWNlc1swXSA9IDA7JztcbiAgICAgICAgY29uc3QgYkJjYXN0ID0gaW5wdXRzWzFdLmRpbXMubGVuZ3RoICE9PSAwID8gJ2JjYXN0SW5kaWNlc19CKGluZGljZXMsIGJpbmRpY2VzKTsnIDogJ2JpbmRpY2VzWzBdID0gMDsnO1xuXG4gICAgICAgIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgICAgICAgY29uc3Qgc2hhZGVyU291cmNlID0gdXNlUGFja2VkVGV4dHVyZSA/IGBcbiAgICAgICR7Z2xzbEZ1bmMuYm9keX1cbiAgICAgIHZvaWQgbWFpbigpIHtcbiAgICAgICAgdmVjNCBhID0gZ2V0QUF0T3V0Q29vcmRzKCk7XG4gICAgICAgIHZlYzQgYiA9IGdldEJBdE91dENvb3JkcygpO1xuICAgICAgICB2ZWM0IHJlc3VsdCA9ICR7Z2xzbEZ1bmMubmFtZX0oYSwgYik7XG4gICAgICAgICR7Z2xzbC5vdXRwdXR9ID0gcmVzdWx0O1xuICAgICAgfWAgOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYFxuICAgICAgJHtnbHNsRnVuYy5ib2R5fVxuICAgICAgZmxvYXQgcHJvY2VzcyhpbnQgaW5kaWNlc1ske291dHB1dFJhbmt9XSkge1xuICAgICAgICBpbnQgYWluZGljZXNbJHthUmFua31dO1xuICAgICAgICBpbnQgYmluZGljZXNbJHtiUmFua31dO1xuICAgICAgICAke2FCY2FzdH1cbiAgICAgICAgJHtiQmNhc3R9XG4gICAgICAgIHJldHVybiAke2dsc2xGdW5jLm5hbWV9KF9BKGFpbmRpY2VzKSwgX0IoYmluZGljZXMpKTtcbiAgICAgIH1gO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgbmFtZTogZ2xzbEZ1bmMubmFtZSxcbiAgICAgICAgICBpbnB1dE5hbWVzOiBbJ0EnLCAnQiddLFxuICAgICAgICAgIGlucHV0VHlwZXM6IFt0ZXh0dXJlVHlwZSwgdGV4dHVyZVR5cGVdLFxuICAgICAgICAgIG91dHB1dDoge2RpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBvdXRwdXRUZW5zb3JUeXBlLCB0ZXh0dXJlVHlwZX0sXG4gICAgICAgICAgc2hhZGVyU291cmNlLFxuICAgICAgICAgIGhhc01haW46IHVzZVBhY2tlZFRleHR1cmVcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgICAgIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAke2dsc2xGdW5jLmJvZHl9XG4gICAgdm9pZCBtYWluKCkge1xuICAgICAgdmVjNCB2MSA9ICR7Z2xzbC50ZXh0dXJlMkR9KEEsIFRleENvb3Jkcyk7XG4gICAgICB2ZWM0IHYyID0gJHtnbHNsLnRleHR1cmUyRH0oQiwgVGV4Q29vcmRzKTtcbiAgICAgIHZlYzQgcmVzdWx0ID0gJHtnbHNsRnVuYy5uYW1lfSh2MSwgdjIpO1xuICAgICAgJHtnbHNsLm91dHB1dH0gPSByZXN1bHQ7XG4gICAgfVxuICAgIGA7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIG5hbWU6IGdsc2xGdW5jLm5hbWUsXG4gICAgICAgIGlucHV0TmFtZXM6IFsnQScsICdCJ10sXG4gICAgICAgIGlucHV0VHlwZXM6IFt0ZXh0dXJlVHlwZSwgdGV4dHVyZVR5cGVdLFxuICAgICAgICBvdXRwdXQ6IHtkaW1zOiBpbnB1dHNbMF0uZGltcywgdHlwZTogb3V0cHV0VGVuc29yVHlwZSwgdGV4dHVyZVR5cGV9LFxuICAgICAgICBzaGFkZXJTb3VyY2UsXG4gICAgICAgIGhhc01haW46IHRydWVcbiAgICAgIH07XG4gICAgfTtcblxuZXhwb3J0IGNvbnN0IGFkZCA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOlxuICAgIFRlbnNvcltdID0+IFtoYW5kbGVyLnJ1bihjcmVhdGVCaW5hcnlQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHMsIGdsc2xBZGQoKSksIGlucHV0cyldO1xuXG5leHBvcnQgY29uc3QgYW5kID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6XG4gICAgVGVuc29yW10gPT4gW2hhbmRsZXIucnVuKGNyZWF0ZUJpbmFyeVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0cywgZ2xzbEFuZCgpLCAnYm9vbCcpLCBpbnB1dHMpXTtcblxuZXhwb3J0IGNvbnN0IGRpdiA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOlxuICAgIFRlbnNvcltdID0+IFtoYW5kbGVyLnJ1bihjcmVhdGVCaW5hcnlQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHMsIGdsc2xEaXYoKSksIGlucHV0cyldO1xuXG5leHBvcnQgY29uc3QgZXF1YWwgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTpcbiAgICBUZW5zb3JbXSA9PiBbaGFuZGxlci5ydW4oY3JlYXRlQmluYXJ5UHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzLCBnbHNsRXF1YWwoKSwgJ2Jvb2wnKSwgaW5wdXRzKV07XG5cbmV4cG9ydCBjb25zdCBncmVhdGVyID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6XG4gICAgVGVuc29yW10gPT4gW2hhbmRsZXIucnVuKGNyZWF0ZUJpbmFyeVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0cywgZ2xzbEdyZWF0ZXIoKSwgJ2Jvb2wnKSwgaW5wdXRzKV07XG5cbmV4cG9ydCBjb25zdCBsZXNzID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6XG4gICAgVGVuc29yW10gPT4gW2hhbmRsZXIucnVuKGNyZWF0ZUJpbmFyeVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0cywgZ2xzbExlc3MoKSwgJ2Jvb2wnKSwgaW5wdXRzKV07XG5cbmV4cG9ydCBjb25zdCBtdWwgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTpcbiAgICBUZW5zb3JbXSA9PiBbaGFuZGxlci5ydW4oY3JlYXRlQmluYXJ5UHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzLCBnbHNsTXVsKCkpLCBpbnB1dHMpXTtcblxuZXhwb3J0IGNvbnN0IG9yID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6XG4gICAgVGVuc29yW10gPT4gW2hhbmRsZXIucnVuKGNyZWF0ZUJpbmFyeVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0cywgZ2xzbE9yKCksICdib29sJyksIGlucHV0cyldO1xuXG5leHBvcnQgY29uc3QgcG93ID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6XG4gICAgVGVuc29yW10gPT4gW2hhbmRsZXIucnVuKGNyZWF0ZUJpbmFyeVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0cywgZ2xzbFBvdygpKSwgaW5wdXRzKV07XG5cbmV4cG9ydCBjb25zdCBwUmVsdSA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOlxuICAgIFRlbnNvcltdID0+IFtoYW5kbGVyLnJ1bihjcmVhdGVCaW5hcnlQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHMsIGdsc2xQUmVsdSgpKSwgaW5wdXRzKV07XG5cbmV4cG9ydCBjb25zdCBzdWIgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTpcbiAgICBUZW5zb3JbXSA9PiBbaGFuZGxlci5ydW4oY3JlYXRlQmluYXJ5UHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzLCBnbHNsU3ViKCkpLCBpbnB1dHMpXTtcblxuZXhwb3J0IGNvbnN0IHhvciA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOlxuICAgIFRlbnNvcltdID0+IFtoYW5kbGVyLnJ1bihjcmVhdGVCaW5hcnlQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHMsIGdsc2xYb3IoKSwgJ2Jvb2wnKSwgaW5wdXRzKV07XG4iLCIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtHcmFwaH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHtPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9ufSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHtUZW5zb3J9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQge1Byb3RvVXRpbH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQge1dlYkdMSW5mZXJlbmNlSGFuZGxlcn0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuXG5leHBvcnQgY29uc3QgY2FzdDogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxUZW5zb3IuRGF0YVR5cGU+ID1cbiAgICAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdLCB0bzogVGVuc29yLkRhdGFUeXBlKTogVGVuc29yW10gPT4ge1xuICAgICAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcbiAgICAgIHJldHVybiBbaGFuZGxlci5jYXN0KGlucHV0c1swXSwgdG8pXTtcbiAgICB9O1xuXG5leHBvcnQgY29uc3QgcGFyc2VDYXN0QXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxUZW5zb3IuRGF0YVR5cGU+ID0gKG5vZGU6IEdyYXBoLk5vZGUpOiBUZW5zb3IuRGF0YVR5cGUgPT5cbiAgICBQcm90b1V0aWwudGVuc29yRGF0YVR5cGVGcm9tUHJvdG8obm9kZS5hdHRyaWJ1dGVzLmdldEludCgndG8nKSk7XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignQ2FzdCByZXF1aXJlcyAxIGlucHV0LicpO1xuICB9XG5cbiAgaWYgKGlucHV0c1swXS50eXBlID09PSAnc3RyaW5nJykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG59OyIsIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7Z2V0R2xzbH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHtXZWJHTEluZmVyZW5jZUhhbmRsZXJ9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7UHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlfSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQge2dldENvb3Jkc0RhdGFUeXBlLCBnZXRHbENoYW5uZWxzfSBmcm9tICcuLi91dGlscyc7XG5cbmltcG9ydCB7Q29uY2F0QXR0cmlidXRlc30gZnJvbSAnLi9jb25jYXQnO1xuaW1wb3J0IHtnZXRDaGFubmVscywgdW5wYWNrRnJvbUNoYW5uZWx9IGZyb20gJy4vcGFja2luZy11dGlscyc7XG5cbmNvbnN0IGNyZWF0ZVBhY2tlZENvbmNhdFByb2dyYW1NZXRhZGF0YSA9IChpbnB1dENvdW50OiBudW1iZXIsIGNhY2hlSGludDogc3RyaW5nKSA9PiAoe1xuICBuYW1lOiAnQ29uY2F0IChwYWNrZWQpJyxcbiAgaW5wdXROYW1lczogQXJyYXkuZnJvbSh7bGVuZ3RoOiBpbnB1dENvdW50fSwgKHYsIGkpID0+IGBYJHtpfWApLFxuICBpbnB1dFR5cGVzOiBBcnJheShpbnB1dENvdW50KS5maWxsKFRleHR1cmVUeXBlLnBhY2tlZCksXG4gIGNhY2hlSGludFxufSk7XG5cbmNvbnN0IGNyZWF0ZVBhY2tlZENvbmNhdFByb2dyYW1JbmZvID1cbiAgICAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBtZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhLCBpbnB1dHM6IFRlbnNvcltdLCBheGlzOiBudW1iZXIpOiBQcm9ncmFtSW5mbyA9PiB7XG4gICAgICBjb25zdCBpbnB1dFNoYXBlID0gaW5wdXRzWzBdLmRpbXMuc2xpY2UoKTtcbiAgICAgIGlmIChheGlzID49IGlucHV0U2hhcGUubGVuZ3RoIHx8IGF4aXMgPCAoLTEgKiBpbnB1dFNoYXBlLmxlbmd0aCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdheGlzIHNwZWNpZmllZCBmb3IgY29uY2F0IGRvZXNuXFwndCBtYXRjaCBpbnB1dCBkaW1lbnNpb25hbGl0eScpO1xuICAgICAgfVxuICAgICAgaWYgKGF4aXMgPCAwKSB7XG4gICAgICAgIGF4aXMgPSBpbnB1dFNoYXBlLmxlbmd0aCArIGF4aXM7XG4gICAgICB9XG4gICAgICAvLyBlbnN1cmUgYWxsIG9mIHRoZSBub24tY29uY2F0ZW5hdGVkIGF4ZXMgbWF0Y2ggZWFjaCBvdGhlclxuICAgICAgLy8gY2FsY3VsYXRlIHRoZSBzaGFwZSBvZiB0aGUgb3V0cHV0IHRlbnNvciB3aGlsZSB3ZSBkbyB0aGF0XG4gICAgICBjb25zdCBvdXRwdXRTaGFwZSA9IGlucHV0U2hhcGUuc2xpY2UoMCk7XG4gICAgICBmb3IgKGxldCBpID0gMTsgaSA8IGlucHV0cy5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBkYXRhTlNoYXBlID0gaW5wdXRzW2ldLmRpbXMuc2xpY2UoKTtcbiAgICAgICAgZm9yIChsZXQgYXhpc0luZGV4ID0gMDsgYXhpc0luZGV4IDwgaW5wdXRTaGFwZS5sZW5ndGg7IGF4aXNJbmRleCsrKSB7XG4gICAgICAgICAgLy8gYWRkIHRvIHRoZSBwbGFjZWhvbGRlciBmb3IgY29tcHV0aW5nIG91dHB1dCBzaGFwZVxuICAgICAgICAgIGlmIChheGlzSW5kZXggPT09IGF4aXMpIHtcbiAgICAgICAgICAgIG91dHB1dFNoYXBlW2F4aXNdICs9IGRhdGFOU2hhcGVbYXhpc0luZGV4XTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gZW5zdXJlIGFsbCBub24tY2FuY2F0ZW5hdGVkIGF4ZXMgbWF0Y2ggZWFjaCBvdGhlclxuICAgICAgICAgIGVsc2UgaWYgKGlucHV0U2hhcGVbYXhpc0luZGV4XSAhPT0gZGF0YU5TaGFwZVtheGlzSW5kZXhdKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ25vbiBjb25jYXQgZGltZW5zaW9ucyBtdXN0IG1hdGNoJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG4gICAgICBjb25zdCBjb29yZHMgPSBnZXRDaGFubmVscygnY29vcmRzJywgcmFuayk7XG4gICAgICBjb25zdCBkdHlwZSA9IGdldENvb3Jkc0RhdGFUeXBlKHJhbmspO1xuICAgICAgY29uc3QgdW5wYWNrQ2hhbm5lbCA9IHVucGFja0Zyb21DaGFubmVsKCk7XG5cbiAgICAgIGNvbnN0IHNoYXBlcyA9IGlucHV0cy5tYXAoaSA9PiBpLmRpbXMpO1xuICAgICAgY29uc3QgY2hhbm5lbHMgPSBnZXRHbENoYW5uZWxzKHJhbmspO1xuICAgICAgY29uc3Qgb2Zmc2V0czogbnVtYmVyW10gPSBuZXcgQXJyYXkoc2hhcGVzLmxlbmd0aCAtIDEpO1xuXG4gICAgICBvZmZzZXRzWzBdID0gc2hhcGVzWzBdW2F4aXNdO1xuICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPCBvZmZzZXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIG9mZnNldHNbaV0gPSBvZmZzZXRzW2kgLSAxXSArIHNoYXBlc1tpXVtheGlzXTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgY2hhbm5lbCA9IGNoYW5uZWxzW2F4aXNdO1xuICAgICAgY29uc3QgbGFzdENoYW5uZWxzID0gY2hhbm5lbHMuc2xpY2UoLTIpO1xuICAgICAgY29uc3QgYWxsQ2hhbm5lbHMgPSBjaGFubmVscy5qb2luKCk7XG5cbiAgICAgIGxldCBnZXRWYWx1ZVNuaXBwZXQgPSBgaWYgKCR7Y2hhbm5lbH0gPCAke29mZnNldHNbMF19KSB7XG4gICAgICAgIHJldHVybiBnZXRDaGFubmVsKFxuICAgICAgICAgICAgZ2V0WDAoJHthbGxDaGFubmVsc30pLCB2ZWMyKCR7bGFzdENoYW5uZWxzLmpvaW4oKX0pKTtcbiAgICAgICAgfWA7XG4gICAgICBmb3IgKGxldCBpID0gMTsgaSA8IG9mZnNldHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3Qgc2hpZnQgPSBvZmZzZXRzW2kgLSAxXTtcbiAgICAgICAgZ2V0VmFsdWVTbmlwcGV0ICs9IGBcbiAgICAgICAgICAgIGlmICgke2NoYW5uZWx9IDwgJHtvZmZzZXRzW2ldfSAgJiYgJHtjaGFubmVsfSA+PSAke29mZnNldHNbaSAtIDFdfSkge1xuICAgICAgICAgICAgICByZXR1cm4gZ2V0Q2hhbm5lbChcbiAgICAgICAgICAgICAgICBnZXRYJHtpfSgke2dldFNoaWZ0ZWRDaGFubmVsc1NuaXBwZXQoY2hhbm5lbHMsIGNoYW5uZWwsIHNoaWZ0KX0pLFxuICAgICAgICAgICAgICAgIHZlYzIoJHtnZXRTaGlmdGVkQ2hhbm5lbHNTbmlwcGV0KGxhc3RDaGFubmVscywgY2hhbm5lbCwgc2hpZnQpfSkpO1xuICAgICAgICAgICAgfWA7XG4gICAgICB9XG4gICAgICBjb25zdCBsYXN0SW5kZXggPSBvZmZzZXRzLmxlbmd0aDtcbiAgICAgIGNvbnN0IHNoaWZ0ID0gb2Zmc2V0c1tvZmZzZXRzLmxlbmd0aCAtIDFdO1xuICAgICAgZ2V0VmFsdWVTbmlwcGV0ICs9IGBcbiAgICAgICAgICAgIHJldHVybiBnZXRDaGFubmVsKFxuICAgICAgICAgICAgICBnZXRYJHtsYXN0SW5kZXh9KCR7Z2V0U2hpZnRlZENoYW5uZWxzU25pcHBldChjaGFubmVscywgY2hhbm5lbCwgc2hpZnQpfSksXG4gICAgICAgICAgICAgIHZlYzIoJHtnZXRTaGlmdGVkQ2hhbm5lbHNTbmlwcGV0KGxhc3RDaGFubmVscywgY2hhbm5lbCwgc2hpZnQpfSkpO2A7XG5cbiAgICAgIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcblxuICAgICAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgICAgICR7dW5wYWNrQ2hhbm5lbH1cbiAgICAgICAgICBmbG9hdCBnZXRWYWx1ZSgke2NoYW5uZWxzLm1hcCh4ID0+ICdpbnQgJyArIHgpfSkge1xuICAgICAgICAgICAgJHtnZXRWYWx1ZVNuaXBwZXR9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdm9pZCBtYWluKCkge1xuICAgICAgICAgICAgJHtkdHlwZX0gY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7XG4gICAgICAgICAgICBpbnQgbGFzdERpbSA9IGNvb3Jkcy4ke2NoYW5uZWxzW3JhbmsgLSAxXX07XG4gICAgICAgICAgICBjb29yZHMuJHtjaGFubmVsc1tyYW5rIC0gMV19ID0gY29vcmRzLiR7Y2hhbm5lbHNbcmFuayAtIDJdfTtcbiAgICAgICAgICAgIGNvb3Jkcy4ke2NoYW5uZWxzW3JhbmsgLSAyXX0gPSBsYXN0RGltO1xuXG4gICAgICAgICAgICB2ZWM0IHJlc3VsdCA9IHZlYzQoZ2V0VmFsdWUoJHtjb29yZHN9KSwgMC4sIDAuLCAwLik7XG5cbiAgICAgICAgICAgICR7Y29vcmRzW3JhbmsgLSAxXX0gPSAke2Nvb3Jkc1tyYW5rIC0gMV19ICsgMTtcbiAgICAgICAgICAgIGlmICgke2Nvb3Jkc1tyYW5rIC0gMV19IDwgJHtvdXRwdXRTaGFwZVtyYW5rIC0gMV19KSB7XG4gICAgICAgICAgICAgIHJlc3VsdC5nID0gZ2V0VmFsdWUoJHtjb29yZHN9KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgJHtjb29yZHNbcmFuayAtIDJdfSA9ICR7Y29vcmRzW3JhbmsgLSAyXX0gKyAxO1xuICAgICAgICAgICAgaWYgKCR7Y29vcmRzW3JhbmsgLSAyXX0gPCAke291dHB1dFNoYXBlW3JhbmsgLSAyXX0pIHtcbiAgICAgICAgICAgICAgcmVzdWx0LmEgPSBnZXRWYWx1ZSgke2Nvb3Jkc30pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAke2Nvb3Jkc1tyYW5rIC0gMV19ID0gJHtjb29yZHNbcmFuayAtIDFdfSAtIDE7XG4gICAgICAgICAgICBpZiAoJHtjb29yZHNbcmFuayAtIDJdfSA8ICR7b3V0cHV0U2hhcGVbcmFuayAtIDJdfSAmJlxuICAgICAgICAgICAgICAgICR7Y29vcmRzW3JhbmsgLSAxXX0gPCAke291dHB1dFNoYXBlW3JhbmsgLSAxXX0pIHtcbiAgICAgICAgICAgICAgcmVzdWx0LmIgPSBnZXRWYWx1ZSgke2Nvb3Jkc30pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgJHtnbHNsLm91dHB1dH0gPSByZXN1bHQ7XG4gICAgICAgICAgfVxuICAgICAgICBgO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5tZXRhZGF0YSxcbiAgICAgICAgb3V0cHV0OiB7ZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUucGFja2VkfSxcbiAgICAgICAgc2hhZGVyU291cmNlLFxuICAgICAgICBoYXNNYWluOiB0cnVlLFxuICAgICAgfTtcbiAgICB9O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlUGFja2VkQ29uY2F0UHJvZ3JhbUluZm9Mb2FkZXIgPVxuICAgIChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IENvbmNhdEF0dHJpYnV0ZXMpOiBQcm9ncmFtSW5mb0xvYWRlciA9PiB7XG4gICAgICBjb25zdCBtZXRhZGF0YSA9IGNyZWF0ZVBhY2tlZENvbmNhdFByb2dyYW1NZXRhZGF0YShpbnB1dHMubGVuZ3RoLCBhdHRyaWJ1dGVzLmNhY2hlS2V5KTtcbiAgICAgIHJldHVybiB7Li4ubWV0YWRhdGEsIGdldDogKCkgPT4gY3JlYXRlUGFja2VkQ29uY2F0UHJvZ3JhbUluZm8oaGFuZGxlciwgbWV0YWRhdGEsIGlucHV0cywgYXR0cmlidXRlcy5heGlzKX07XG4gICAgfTtcblxuY29uc3QgZ2V0U2hpZnRlZENoYW5uZWxzU25pcHBldCA9IChjaGFubmVsczogc3RyaW5nW10sIGNoYW5uZWw6IHN0cmluZywgc2hpZnQ6IG51bWJlcik6IHN0cmluZyA9PiB7XG4gIGNvbnN0IGNoYW5uZWxJZHggPSBjaGFubmVscy5pbmRleE9mKGNoYW5uZWwpO1xuICBjb25zdCByZXMgPSBjaGFubmVscy5tYXAoKGMsIGlkeCkgPT4ge1xuICAgIGlmIChpZHggPT09IGNoYW5uZWxJZHgpIHtcbiAgICAgIHJldHVybiBgJHtjfSAtICR7c2hpZnR9YDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGM7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIHJlcy5qb2luKCk7XG59O1xuIiwiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7QXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXl9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQge0dyYXBofSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQge09wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb259IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7V2ViR0xJbmZlcmVuY2VIYW5kbGVyfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQge1Byb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgUHJvZ3JhbU1ldGFkYXRhLCBUZXh0dXJlVHlwZX0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQge2NyZWF0ZVBhY2tlZENvbmNhdFByb2dyYW1JbmZvTG9hZGVyfSBmcm9tICcuL2NvbmNhdC1wYWNrZWQnO1xuXG5leHBvcnQgaW50ZXJmYWNlIENvbmNhdEF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBheGlzOiBudW1iZXI7XG59XG5cbmV4cG9ydCBjb25zdCBjb25jYXQ6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248Q29uY2F0QXR0cmlidXRlcz4gPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IENvbmNhdEF0dHJpYnV0ZXMpOiBUZW5zb3JbXSA9PiB7XG4gICAgICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuICAgICAgaWYgKGluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5wYWNrICYmIGlucHV0c1swXS5kaW1zLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgY29uc3Qgb3V0cHV0ID1cbiAgICAgICAgICAgIGluZmVyZW5jZUhhbmRsZXIucnVuKGNyZWF0ZVBhY2tlZENvbmNhdFByb2dyYW1JbmZvTG9hZGVyKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcyksIGlucHV0cyk7XG4gICAgICAgIHJldHVybiBbb3V0cHV0XTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IG91dHB1dCA9XG4gICAgICAgICAgICBpbmZlcmVuY2VIYW5kbGVyLnJ1bihjcmVhdGVVbnBhY2tlZENvbmNhdFByb2dyYW1JbmZvTG9hZGVyKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcyksIGlucHV0cyk7XG4gICAgICAgIHJldHVybiBbb3V0cHV0XTtcbiAgICAgIH1cbiAgICB9O1xuXG5jb25zdCBjcmVhdGVVbnBhY2tlZENvbmNhdFByb2dyYW1NZXRhZGF0YSA9IChpbnB1dENvdW50OiBudW1iZXIsIGNhY2hlSGludDogc3RyaW5nKSA9PiAoe1xuICBuYW1lOiAnQ29uY2F0JyxcbiAgaW5wdXROYW1lczogQXJyYXkuZnJvbSh7bGVuZ3RoOiBpbnB1dENvdW50fSwgKHYsIGkpID0+IGBYJHtpfWApLFxuICBpbnB1dFR5cGVzOiBBcnJheShpbnB1dENvdW50KS5maWxsKFRleHR1cmVUeXBlLnVucGFja2VkKSxcbiAgY2FjaGVIaW50XG59KTtcblxuY29uc3QgY3JlYXRlVW5wYWNrZWRDb25jYXRQcm9ncmFtSW5mbyA9XG4gICAgKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgbWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSwgaW5wdXRzOiBUZW5zb3JbXSwgYXhpczogbnVtYmVyKTogUHJvZ3JhbUluZm8gPT4ge1xuICAgICAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zLnNsaWNlKCk7XG4gICAgICBpZiAoYXhpcyA+PSBpbnB1dFNoYXBlLmxlbmd0aCB8fCBheGlzIDwgKC0xICogaW5wdXRTaGFwZS5sZW5ndGgpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignYXhpcyBzcGVjaWZpZWQgZm9yIGNvbmNhdCBkb2VzblxcJ3QgbWF0Y2ggaW5wdXQgZGltZW5zaW9uYWxpdHknKTtcbiAgICAgIH1cbiAgICAgIGlmIChheGlzIDwgMCkge1xuICAgICAgICBheGlzID0gaW5wdXRTaGFwZS5sZW5ndGggKyBheGlzO1xuICAgICAgfVxuICAgICAgLy8gZW5zdXJlIGFsbCBvZiB0aGUgbm9uLWNvbmNhdGVuYXRlZCBheGVzIG1hdGNoIGVhY2ggb3RoZXJcbiAgICAgIC8vIGNhbGN1bGF0ZSB0aGUgc2hhcGUgb2YgdGhlIG91dHB1dCB0ZW5zb3Igd2hpbGUgd2UgZG8gdGhhdFxuICAgICAgY29uc3Qgb3V0cHV0U2hhcGUgPSBpbnB1dFNoYXBlLnNsaWNlKDApO1xuICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPCBpbnB1dHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3QgZGF0YU5TaGFwZSA9IGlucHV0c1tpXS5kaW1zLnNsaWNlKCk7XG4gICAgICAgIGZvciAobGV0IGF4aXNJbmRleCA9IDA7IGF4aXNJbmRleCA8IGlucHV0U2hhcGUubGVuZ3RoOyBheGlzSW5kZXgrKykge1xuICAgICAgICAgIC8vIGFkZCB0byB0aGUgcGxhY2Vob2xkZXIgZm9yIGNvbXB1dGluZyBvdXRwdXQgc2hhcGVcbiAgICAgICAgICBpZiAoYXhpc0luZGV4ID09PSBheGlzKSB7XG4gICAgICAgICAgICBvdXRwdXRTaGFwZVtheGlzXSArPSBkYXRhTlNoYXBlW2F4aXNJbmRleF07XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIGVuc3VyZSBhbGwgbm9uLWNhbmNhdGVuYXRlZCBheGVzIG1hdGNoIGVhY2ggb3RoZXJcbiAgICAgICAgICBlbHNlIGlmIChpbnB1dFNoYXBlW2F4aXNJbmRleF0gIT09IGRhdGFOU2hhcGVbYXhpc0luZGV4XSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdub24gY29uY2F0IGRpbWVuc2lvbnMgbXVzdCBtYXRjaCcpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCByYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuXG4gICAgICBjb25zdCBzaXplSW5Db25jYXRBeGlzID0gbmV3IEFycmF5PG51bWJlcj4oaW5wdXRzLmxlbmd0aCk7XG4gICAgICBsZXQgcHJldmlvdXNTdW0gPSAwO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzaXplSW5Db25jYXRBeGlzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIHByZXZpb3VzU3VtICs9IGlucHV0c1tpXS5kaW1zW2F4aXNdO1xuICAgICAgICBzaXplSW5Db25jYXRBeGlzW2ldID0gcHJldmlvdXNTdW07XG4gICAgICB9XG5cbiAgICAgIGxldCBnZXRUZXh0dXJlSW5kZXhXaGVyZURhdGFSZXNpZGVzTWV0aG9kID0gJyc7XG4gICAgICAvLyBpbiBtb3N0IGNhc2VzIGxpbmVhciBzZWFyY2ggaXMgc3VmZmljaWVudCwgYXMgaW4gbW9zdCBzY2VuYXJpb3MsIG9ubHkgMiB0ZW5zb3JzIGFyZSBjb25jYXRlbmF0ZWRcbiAgICAgIGlmIChpbnB1dHMubGVuZ3RoIDwgNSkge1xuICAgICAgICBnZXRUZXh0dXJlSW5kZXhXaGVyZURhdGFSZXNpZGVzTWV0aG9kID0gZ2V0VGV4dHVyZUluZGV4V2hlcmVEYXRhUmVzaWRlc0xpbmVhclNlYXJjaChzaXplSW5Db25jYXRBeGlzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGdldFRleHR1cmVJbmRleFdoZXJlRGF0YVJlc2lkZXNNZXRob2QgPSBnZXRUZXh0dXJlSW5kZXhXaGVyZURhdGFSZXNpZGVzQmluYXJ5U2VhcmNoKHNpemVJbkNvbmNhdEF4aXMpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBmZXRjaERhdGFGcm9tQ29ycmVjdFRleHR1cmVNZXRob2QgPSBnZXRGZXRjaERhdGFGcm9tQ29ycmVjdFRleHR1cmVNZXRob2QoaW5wdXRzLmxlbmd0aCwgcmFuayk7XG4gICAgICBjb25zdCBnZXRTaXplSW5Db25jYXRBeGlzVmFsdWVGcm9tSW5kZXhNZXRob2QgPSBnZXRHZXRTaXplSW5Db25jYXRBeGlzVmFsdWVGcm9tSW5kZXhNZXRob2Qoc2l6ZUluQ29uY2F0QXhpcyk7XG4gICAgICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICAgICR7ZmV0Y2hEYXRhRnJvbUNvcnJlY3RUZXh0dXJlTWV0aG9kfVxuICAgICAgICAke2dldFNpemVJbkNvbmNhdEF4aXNWYWx1ZUZyb21JbmRleE1ldGhvZH1cbiAgICAgICAgJHtnZXRUZXh0dXJlSW5kZXhXaGVyZURhdGFSZXNpZGVzTWV0aG9kfVxuICAgICAgICBmbG9hdCBwcm9jZXNzKGludCBpbmRpY2VzWyR7cmFua31dKSB7XG4gICAgICAgICAgaW50IHRleHR1cmVJbmRleCA9IGdldFRleHR1cmVXaGVyZURhdGFSZXNpZGVzIChpbmRpY2VzWyR7YXhpc31dKTtcblxuICAgICAgICAgIGlmKHRleHR1cmVJbmRleCAhPSAwKSB7XG4gICAgICAgICAgICBpbmRpY2VzWyR7YXhpc31dID0gaW5kaWNlc1ske2F4aXN9XSAtIGludChnZXRTaXplSW5Db25jYXRBeGlzVmFsdWVGcm9tSW5kZXgodGV4dHVyZUluZGV4LWludCgxKSkpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiBmZXRjaERhdGFGcm9tQ29ycmVjdFRleHR1cmUodGV4dHVyZUluZGV4LCBpbmRpY2VzKTtcbiAgICAgICAgfWA7XG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5tZXRhZGF0YSxcbiAgICAgICAgb3V0cHV0OiB7ZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWR9LFxuICAgICAgICBzaGFkZXJTb3VyY2UsXG4gICAgICB9O1xuICAgIH07XG5cbmNvbnN0IGNyZWF0ZVVucGFja2VkQ29uY2F0UHJvZ3JhbUluZm9Mb2FkZXIgPVxuICAgIChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IENvbmNhdEF0dHJpYnV0ZXMpOiBQcm9ncmFtSW5mb0xvYWRlciA9PiB7XG4gICAgICBjb25zdCBtZXRhZGF0YSA9IGNyZWF0ZVVucGFja2VkQ29uY2F0UHJvZ3JhbU1ldGFkYXRhKGlucHV0cy5sZW5ndGgsIGF0dHJpYnV0ZXMuY2FjaGVLZXkpO1xuICAgICAgcmV0dXJuIHsuLi5tZXRhZGF0YSwgZ2V0OiAoKSA9PiBjcmVhdGVVbnBhY2tlZENvbmNhdFByb2dyYW1JbmZvKGhhbmRsZXIsIG1ldGFkYXRhLCBpbnB1dHMsIGF0dHJpYnV0ZXMuYXhpcyl9O1xuICAgIH07XG5cbmNvbnN0IGdldFRleHR1cmVJbmRleFdoZXJlRGF0YVJlc2lkZXNMaW5lYXJTZWFyY2ggPSAoc2l6ZUluQ29uY2F0QXhpczogbnVtYmVyW10pOiBzdHJpbmcgPT4ge1xuICBjb25zdCBzZWFyY2hBeGlzID0gc2l6ZUluQ29uY2F0QXhpcy5tYXAoKHNpemUsIGkpID0+IGBpZihpbmRleDwke3NpemV9KSB7cmV0dXJuICR7aX07fVxuYCk7XG4gIHJldHVybiBgaW50IGdldFRleHR1cmVXaGVyZURhdGFSZXNpZGVzKGludCBpbmRleCkge1xuICAgICAgJHtzZWFyY2hBeGlzLmpvaW4oJycpfVxuICAgIH1gO1xufTtcblxuLy8gVE9ETzogSW1wbGVtZW50IEJpbmFyeVNlYXJjaCBpbiBHTFNMXG5jb25zdCBnZXRUZXh0dXJlSW5kZXhXaGVyZURhdGFSZXNpZGVzQmluYXJ5U2VhcmNoID0gKHNpemVJbkNvbmNhdEF4aXM6IG51bWJlcltdKTogc3RyaW5nID0+XG4gICAgZ2V0VGV4dHVyZUluZGV4V2hlcmVEYXRhUmVzaWRlc0xpbmVhclNlYXJjaChzaXplSW5Db25jYXRBeGlzKTtcblxuY29uc3QgZ2V0RmV0Y2hEYXRhRnJvbUNvcnJlY3RUZXh0dXJlTWV0aG9kID0gKG51bWJlck9mVGVuc29yczogbnVtYmVyLCB0ZW5zb3JSYW5rOiBudW1iZXIpID0+IHtcbiAgY29uc3QgY29kZUxpbmVzOiBzdHJpbmdbXSA9IFtgZmxvYXQgZmV0Y2hEYXRhRnJvbUNvcnJlY3RUZXh0dXJlKGludCB0ZXh0dXJlSW5kZXgsIGludCBpbmRpY2VzWyR7dGVuc29yUmFua31dKSB7YF07XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtYmVyT2ZUZW5zb3JzOyArK2kpIHtcbiAgICBpZiAoaSA9PT0gMCkge1xuICAgICAgY29kZUxpbmVzLnB1c2goXG4gICAgICAgICAgJ1xcdCcgK1xuICAgICAgICAgIGBpZiAodGV4dHVyZUluZGV4ID09ICR7aX0pIHsgcmV0dXJuIF9YJHtpfShpbmRpY2VzKTsgfWApO1xuICAgIH0gZWxzZSBpZiAoaSA9PT0gbnVtYmVyT2ZUZW5zb3JzIC0gMSkge1xuICAgICAgY29kZUxpbmVzLnB1c2goXG4gICAgICAgICAgJ1xcdCcgK1xuICAgICAgICAgIGBlbHNlIHsgcmV0dXJuIF9YJHtpfShpbmRpY2VzKTsgfWApO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb2RlTGluZXMucHVzaChcbiAgICAgICAgICAnXFx0JyArXG4gICAgICAgICAgYGVsc2UgaWYgKHRleHR1cmVJbmRleCA9PSAke2l9KSB7IHJldHVybiBfWCR7aX0oaW5kaWNlcyk7IH1gKTtcbiAgICB9XG4gIH1cbiAgY29kZUxpbmVzLnB1c2goXG4gICAgICAnXFx0JyArXG4gICAgICAnfScpO1xuICByZXR1cm4gY29kZUxpbmVzLmpvaW4oJ1xcbicpO1xufTtcblxuY29uc3QgZ2V0R2V0U2l6ZUluQ29uY2F0QXhpc1ZhbHVlRnJvbUluZGV4TWV0aG9kID0gKHNpemVJbkNvbmNhdEF4aXM6IG51bWJlcltdKTogc3RyaW5nID0+IHtcbiAgY29uc3QgY29kZUxpbmVzOiBzdHJpbmdbXSA9IFsnaW50IGdldFNpemVJbkNvbmNhdEF4aXNWYWx1ZUZyb21JbmRleChpbnQgaW5kZXgpIHsnXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBzaXplSW5Db25jYXRBeGlzLmxlbmd0aDsgKytpKSB7XG4gICAgaWYgKGkgPT09IDApIHtcbiAgICAgIGNvZGVMaW5lcy5wdXNoKFxuICAgICAgICAgICdcXHQnICtcbiAgICAgICAgICBgaWYgKGluZGV4ID09ICR7aX0pIHsgcmV0dXJuICR7c2l6ZUluQ29uY2F0QXhpc1tpXX07IH1gKTtcbiAgICB9IGVsc2UgaWYgKGkgPT09IHNpemVJbkNvbmNhdEF4aXMubGVuZ3RoIC0gMSkge1xuICAgICAgY29kZUxpbmVzLnB1c2goXG4gICAgICAgICAgJ1xcdCcgK1xuICAgICAgICAgIGBlbHNlIHsgcmV0dXJuICR7c2l6ZUluQ29uY2F0QXhpc1tpXX07IH1gKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29kZUxpbmVzLnB1c2goXG4gICAgICAgICAgJ1xcdCcgK1xuICAgICAgICAgIGBlbHNlIGlmIChpbmRleCA9PSAke2l9KSB7IHJldHVybiAke3NpemVJbkNvbmNhdEF4aXNbaV19OyB9YCk7XG4gICAgfVxuICB9XG4gIGNvZGVMaW5lcy5wdXNoKFxuICAgICAgJ1xcdCcgK1xuICAgICAgJ30nKTtcblxuICByZXR1cm4gY29kZUxpbmVzLmpvaW4oJ1xcbicpO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlQ29uY2F0QXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxDb25jYXRBdHRyaWJ1dGVzPiA9IChub2RlOiBHcmFwaC5Ob2RlKTogQ29uY2F0QXR0cmlidXRlcyA9PlxuICAgIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7YXhpczogbm9kZS5hdHRyaWJ1dGVzLmdldEludCgnYXhpcycpfSk7XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCA8IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3RvbyBmZXcgaW5wdXRzJyk7XG4gIH1cblxuICBjb25zdCBpbnB1dFR5cGUgPSBpbnB1dHNbMF0udHlwZTtcbiAgY29uc3QgaW5wdXREaW1lbnNpb25hbGl0eSA9IGlucHV0c1swXS5kaW1zLmxlbmd0aDtcblxuICAvLyBUT0RPOiBTdXBwb3J0IHN0cmluZyBjb25jYXRcbiAgaWYgKGlucHV0VHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3N0cmluZyB0ZW5zb3IgaXMgbm90IHN1cHBvcnRlZCB5ZXQnKTtcbiAgfVxuXG4gIGZvciAoY29uc3QgaW5wdXQgb2YgaW5wdXRzKSB7XG4gICAgLy8gbWFrZSBzdXJlIHR5cGVzIG9mIGFsbCBpbnB1dHMgbWF0Y2hcbiAgICBpZiAoaW5wdXQudHlwZSAhPT0gaW5wdXRUeXBlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2lucHV0IHRlbnNvcnMgc2hvdWxkIGJlIG9uZSB0eXBlJyk7XG4gICAgfVxuXG4gICAgLy8gbWFrZSBzdXJlIHRoZSBkaW1lbnNpb25hbGl0eSBvZiBhbGwgaW5wdXRzIGFyZSB0aGUgc2FtZVxuICAgIGlmIChpbnB1dC5kaW1zLmxlbmd0aCAhPT0gaW5wdXREaW1lbnNpb25hbGl0eSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnB1dCB0ZW5zb3JzIHNob3VsZCBoYXZlIHRoZSBzYW1lIHNoYXBlJyk7XG4gICAgfVxuICB9XG59O1xuIiwiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7TG9nZ2VyfSBmcm9tICcuLi8uLi8uLi9pbnN0cnVtZW50JztcbmltcG9ydCB7VGVuc29yfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHtnZXRHbHNsfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQge1dlYkdMSW5mZXJlbmNlSGFuZGxlcn0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHtQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGV9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHtjYWxjdWxhdGVPdXRwdXRTaGFwZSwgQ29udkF0dHJpYnV0ZXN9IGZyb20gJy4vY29udic7XG5pbXBvcnQge2dldEFjdGl2YXRpb25TbmlwcGV0fSBmcm9tICcuL2Z1c2UtdXRpbHMnO1xuXG5jb25zdCBjcmVhdGVVbnBhY2tlZEdyb3VwZWRDb252UHJvZ3JhbU1ldGFkYXRhID0gKGhhc0JpYXM6IGJvb2xlYW4sIGNhY2hlSGludDogc3RyaW5nKTogUHJvZ3JhbU1ldGFkYXRhID0+ICh7XG4gIG5hbWU6ICdHcm91cGVkQ29udicsXG4gIGlucHV0TmFtZXM6IGhhc0JpYXMgPyBbJ1gnLCAnVycsICdCaWFzJ10gOiBbJ1gnLCAnVyddLFxuICBpbnB1dFR5cGVzOiBoYXNCaWFzID8gW1RleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUudW5wYWNrZWRdIDpcbiAgICAgICAgICAgICAgICAgICAgICAgIFtUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxuICBjYWNoZUhpbnRcbn0pO1xuXG5jb25zdCBjcmVhdGVVbnBhY2tlZEdyb3VwZWRDb252UHJvZ3JhbUluZm8gPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogcmVhZG9ubHkgVGVuc29yW10sIG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsXG4gICAgIGF0dHJpYnV0ZXM6IENvbnZBdHRyaWJ1dGVzKTogUHJvZ3JhbUluZm8gPT4ge1xuICAgICAgY29uc3QgaGFzQmlhcyA9IGlucHV0cy5sZW5ndGggPiAyO1xuICAgICAgY29uc3QgcHJvY2Vzc0JpYXMgPSBoYXNCaWFzID8gJ3ZhbHVlICs9IGdldEJpYXMob3V0cHV0X2NoYW5uZWwpOycgOiAnJztcbiAgICAgIGNvbnN0IHhTaGFwZSA9IGlucHV0c1swXS5kaW1zLnNsaWNlKCk7XG4gICAgICBjb25zdCB3U2hhcGUgPSBpbnB1dHNbMV0uZGltcy5zbGljZSgpO1xuICAgICAgY29uc3Qgb3V0cHV0Q2hhbm5lbHNQZXJHcm91cCA9IHdTaGFwZVswXSAvIGF0dHJpYnV0ZXMuZ3JvdXA7XG4gICAgICBMb2dnZXIudmVyYm9zZShcbiAgICAgICAgICAnR3JvdXBlZENvbnYnLFxuICAgICAgICAgIGBhdXRwUGFkOiR7YXR0cmlidXRlcy5hdXRvUGFkfSwgZGlsYXRpb25zOiR7YXR0cmlidXRlcy5kaWxhdGlvbnN9LCBncm91cDoke2F0dHJpYnV0ZXMuZ3JvdXB9LCBrZXJuZWxTaGFwZToke1xuICAgICAgICAgICAgICBhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlfSwgcGFkczoke2F0dHJpYnV0ZXMucGFkc30sIHN0cmlkZXM6JHthdHRyaWJ1dGVzLnN0cmlkZXN9YCk7XG4gICAgICBjb25zdCBvdXRwdXRTaGFwZSA9XG4gICAgICAgICAgY2FsY3VsYXRlT3V0cHV0U2hhcGUoeFNoYXBlLCB3U2hhcGUsIGF0dHJpYnV0ZXMuZGlsYXRpb25zLCBhdHRyaWJ1dGVzLnBhZHMsIGF0dHJpYnV0ZXMuc3RyaWRlcyk7XG4gICAgICBjb25zdCBnbHNsID0gZ2V0R2xzbChpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gICAgICBjb25zdCB7YWN0aXZhdGlvbkZ1bmN0aW9uLCBhcHBseUFjdGl2YXRpb259ID0gZ2V0QWN0aXZhdGlvblNuaXBwZXQoYXR0cmlidXRlcyk7XG5cbiAgICAgIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgY29uc3QgaXZlYzIgc3RyaWRlcyA9IGl2ZWMyKCR7YXR0cmlidXRlcy5zdHJpZGVzWzBdfSwgJHthdHRyaWJ1dGVzLnN0cmlkZXNbMV19KTtcbiAgY29uc3QgaXZlYzIgcGFkcyA9IGl2ZWMyKCR7YXR0cmlidXRlcy5wYWRzWzBdfSwgJHthdHRyaWJ1dGVzLnBhZHNbMV19KTtcbiAgJHthY3RpdmF0aW9uRnVuY3Rpb259XG4gIHZvaWQgbWFpbigpIHtcbiAgICBpdmVjNCBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTtcbiAgICBpbnQgYmF0Y2ggPSBjb29yZHMueDtcbiAgICBpbnQgb3V0cHV0X2NoYW5uZWwgPSBjb29yZHMueTtcbiAgICBpdmVjMiB4UkNDb3JuZXIgPSBjb29yZHMuencgKiBzdHJpZGVzIC0gcGFkcztcbiAgICBpbnQgZ3JvdXBfaWQgPSBvdXRwdXRfY2hhbm5lbCAvICR7b3V0cHV0Q2hhbm5lbHNQZXJHcm91cH07XG5cbiAgICBmbG9hdCB2YWx1ZSA9IDAuMDtcbiAgICBmb3IgKGludCB3SW5DaGFubmVsID0gMDsgd0luQ2hhbm5lbCA8ICR7d1NoYXBlWzFdfTsgd0luQ2hhbm5lbCsrKSB7XG4gICAgICBpbnQgaW5wdXRfY2hhbm5lbCA9IGdyb3VwX2lkICogJHt3U2hhcGVbMV19ICsgd0luQ2hhbm5lbDtcbiAgICAgIGZvciAoaW50IHdIZWlnaHQgPSAwOyB3SGVpZ2h0IDwgJHt3U2hhcGVbMl19OyB3SGVpZ2h0KyspIHtcbiAgICAgICAgaW50IHhIZWlnaHQgPSB4UkNDb3JuZXIueCArIHdIZWlnaHQgKiAke2F0dHJpYnV0ZXMuZGlsYXRpb25zWzBdfTtcblxuICAgICAgICBpZiAoeEhlaWdodCA8IDAgfHwgeEhlaWdodCA+PSAke3hTaGFwZVsyXX0pIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoaW50IHdXaWR0aCA9IDA7IHdXaWR0aCA8ICR7d1NoYXBlWzNdfTsgd1dpZHRoKyspIHtcbiAgICAgICAgICBpbnQgeFdpZHRoID0geFJDQ29ybmVyLnkgKyB3V2lkdGggKiAke2F0dHJpYnV0ZXMuZGlsYXRpb25zWzFdfTtcbiAgICAgICAgICBpZiAoeFdpZHRoIDwgMCB8fCB4V2lkdGggPj0gJHt4U2hhcGVbM119KSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBmbG9hdCB4VmFsID0gZ2V0WChiYXRjaCwgaW5wdXRfY2hhbm5lbCwgeFdpZHRoLCB4SGVpZ2h0KTtcbiAgICAgICAgICBmbG9hdCB3VmFsID0gZ2V0VyhvdXRwdXRfY2hhbm5lbCwgd0luQ2hhbm5lbCwgd1dpZHRoLCB3SGVpZ2h0KTtcbiAgICAgICAgICB2YWx1ZSArPSB4VmFsKndWYWw7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgJHtwcm9jZXNzQmlhc31cbiAgICAke2FwcGx5QWN0aXZhdGlvbn1cbiAgICAke2dsc2wub3V0cHV0fSA9IHZlYzQodmFsdWUsIC4wLCAuMCwgLjApO1xuICB9XG5gO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4ubWV0YWRhdGEsXG4gICAgICAgIG91dHB1dDoge2RpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkfSxcbiAgICAgICAgc2hhZGVyU291cmNlLFxuICAgICAgICBoYXNNYWluOiB0cnVlLFxuICAgICAgfTtcbiAgICB9O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlVW5wYWNrZWRHcm91cGVkQ29udlByb2dyYW1JbmZvTG9hZGVyID1cbiAgICAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBDb252QXR0cmlidXRlcyk6XG4gICAgICAgIFByb2dyYW1JbmZvTG9hZGVyID0+IHtcbiAgICAgICAgICBjb25zdCBtZXRhZGF0YSA9IGNyZWF0ZVVucGFja2VkR3JvdXBlZENvbnZQcm9ncmFtTWV0YWRhdGEoaW5wdXRzLmxlbmd0aCA+IDIsIGF0dHJpYnV0ZXMuY2FjaGVLZXkpO1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAuLi5tZXRhZGF0YSxcbiAgICAgICAgICAgIGdldDogKCkgPT4gY3JlYXRlVW5wYWNrZWRHcm91cGVkQ29udlByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgbWV0YWRhdGEsIGF0dHJpYnV0ZXMpXG4gICAgICAgICAgfTtcbiAgICAgICAgfTtcbiIsIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7V2ViR0xJbmZlcmVuY2VIYW5kbGVyfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5cbmltcG9ydCB7Y2FsY3VsYXRlT3V0cHV0U2hhcGUsIENvbnZBdHRyaWJ1dGVzfSBmcm9tICcuL2NvbnYnO1xuaW1wb3J0IHtjcmVhdGVQYWNrZWRJbTJDb2xQcm9ncmFtSW5mb0xvYWRlcn0gZnJvbSAnLi9pbTJjb2wtcGFjayc7XG5pbXBvcnQge2NyZWF0ZVBhY2tlZE1hdG11bFByb2dyYW1JbmZvTG9hZGVyfSBmcm9tICcuL21hdG11bC1wYWNrJztcblxuZXhwb3J0IGNvbnN0IGNvbnYyRFBhY2tlZFBvaW50d2lzZSA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiByZWFkb25seSBUZW5zb3JbXSwgYXR0cmlidXRlczogQ29udkF0dHJpYnV0ZXMpOiBUZW5zb3IgPT4ge1xuICAgICAgY29uc3QgeHNoYXBlID0gaW5wdXRzWzBdLmRpbXM7XG4gICAgICBjb25zdCBrc2hhcGUgPSBpbnB1dHNbMV0uZGltcztcbiAgICAgIGNvbnN0IG91dHB1dFNoYXBlID1cbiAgICAgICAgICBjYWxjdWxhdGVPdXRwdXRTaGFwZSh4c2hhcGUsIGtzaGFwZSwgYXR0cmlidXRlcy5kaWxhdGlvbnMsIGF0dHJpYnV0ZXMucGFkcywgYXR0cmlidXRlcy5zdHJpZGVzKTtcbiAgICAgIGNvbnN0IHJlc2hhcGVkWCA9IGluZmVyZW5jZUhhbmRsZXIucmVzaGFwZVBhY2tlZChpbnB1dHNbMF0sIFt4c2hhcGVbMV0sIHhzaGFwZVsyXSAqIHhzaGFwZVszXV0pO1xuICAgICAgY29uc3QgcmVzaGFwZWRLID0gaW5mZXJlbmNlSGFuZGxlci5yZXNoYXBlUGFja2VkKGlucHV0c1sxXSwgW2tzaGFwZVswXSwga3NoYXBlWzFdXSk7XG5cbiAgICAgIGNvbnN0IG1hdG11bElucHV0cyA9IGlucHV0cy5sZW5ndGggPiAyID8gW3Jlc2hhcGVkSywgcmVzaGFwZWRYLCBpbnB1dHNbMl1dIDogW3Jlc2hhcGVkSywgcmVzaGFwZWRYXTtcbiAgICAgIGNvbnN0IG1hdG11bE91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgICAgICAgIGNyZWF0ZVBhY2tlZE1hdG11bFByb2dyYW1JbmZvTG9hZGVyKGluZmVyZW5jZUhhbmRsZXIsIG1hdG11bElucHV0cywgYXR0cmlidXRlcyksIG1hdG11bElucHV0cyk7XG4gICAgICByZXR1cm4gaW5mZXJlbmNlSGFuZGxlci5yZXNoYXBlUGFja2VkKG1hdG11bE91dHB1dCwgb3V0cHV0U2hhcGUpO1xuICAgIH07XG5cbmV4cG9ydCBjb25zdCBjb252MkRQYWNrZWQgPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogcmVhZG9ubHkgVGVuc29yW10sIGF0dHJpYnV0ZXM6IENvbnZBdHRyaWJ1dGVzKTogVGVuc29yID0+IHtcbiAgICAgIGNvbnN0IHhzaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICAgICAgY29uc3Qga3NoYXBlID0gaW5wdXRzWzFdLmRpbXM7XG4gICAgICBjb25zdCBvdXRwdXRTaGFwZSA9XG4gICAgICAgICAgY2FsY3VsYXRlT3V0cHV0U2hhcGUoeHNoYXBlLCBrc2hhcGUsIGF0dHJpYnV0ZXMuZGlsYXRpb25zLCBhdHRyaWJ1dGVzLnBhZHMsIGF0dHJpYnV0ZXMuc3RyaWRlcyk7XG5cbiAgICAgIC8vIHJ1biBpbTJjb2xcbiAgICAgIGNvbnN0IGltMmNvbE91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgICAgICAgIGNyZWF0ZVBhY2tlZEltMkNvbFByb2dyYW1JbmZvTG9hZGVyKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0c1swXSwgaW5wdXRzWzFdLCBvdXRwdXRTaGFwZSwgYXR0cmlidXRlcyksXG4gICAgICAgICAgW2lucHV0c1swXV0pO1xuXG4gICAgICAvLyByZXNoYXBlIGtlcm5lbFxuICAgICAgY29uc3Qga2VybmVsUmVzaGFwZWQgPSBpbmZlcmVuY2VIYW5kbGVyLnJlc2hhcGVQYWNrZWQoaW5wdXRzWzFdLCBba3NoYXBlWzBdLCBrc2hhcGVbMV0gKiBrc2hhcGVbMl0gKiBrc2hhcGVbM11dKTtcblxuICAgICAgLy8gcnVuIG1hdG11bFxuICAgICAgY29uc3QgbWF0bXVsSW5wdXRzID1cbiAgICAgICAgICAoaW5wdXRzLmxlbmd0aCA9PT0gMykgPyBba2VybmVsUmVzaGFwZWQsIGltMmNvbE91dHB1dCwgaW5wdXRzWzJdXSA6IFtrZXJuZWxSZXNoYXBlZCwgaW0yY29sT3V0cHV0XTtcbiAgICAgIGNvbnN0IG1hdG11bE91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgICAgICAgIGNyZWF0ZVBhY2tlZE1hdG11bFByb2dyYW1JbmZvTG9hZGVyKGluZmVyZW5jZUhhbmRsZXIsIG1hdG11bElucHV0cywgYXR0cmlidXRlcyksIG1hdG11bElucHV0cyk7XG5cbiAgICAgIC8vIHJlc2hhcGUgb3V0cHV0XG4gICAgICBjb25zdCBvdXRwdXRSZXNoYXBlZCA9IGluZmVyZW5jZUhhbmRsZXIucmVzaGFwZVBhY2tlZChtYXRtdWxPdXRwdXQsIG91dHB1dFNoYXBlKTtcbiAgICAgIHJldHVybiBvdXRwdXRSZXNoYXBlZDtcbiAgICB9O1xuIiwiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7Y3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5fSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHtJbmZlcmVuY2VIYW5kbGVyfSBmcm9tICcuLi8uLi8uLi9iYWNrZW5kJztcbmltcG9ydCB7R3JhcGh9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7T3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbn0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7VGVuc29yfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHtnZXRHbHNsfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQge1dlYkdMSW5mZXJlbmNlSGFuZGxlcn0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHtQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGV9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHtDb252QXR0cmlidXRlc30gZnJvbSAnLi9jb252JztcbmltcG9ydCB7Z2V0QWN0aXZhdGlvblNuaXBwZXQsIHBhcnNlSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlc30gZnJvbSAnLi9mdXNlLXV0aWxzJztcblxuY29uc3QgY29tcHV0ZVRvdGFsUGFkID1cbiAgICAoaW5EaW06IG51bWJlciwgc3RyaWRlOiBudW1iZXIsIGFkajogbnVtYmVyLCBrZXJuZWw6IG51bWJlciwgZGlsYXRpb246IG51bWJlciwgb3V0U2l6ZTogbnVtYmVyKSA9PlxuICAgICAgICAoaW5EaW0gLSAxKSAqIHN0cmlkZSArIGFkaiArIChrZXJuZWwgLSAxKSAqIGRpbGF0aW9uICsgMSAtIG91dFNpemU7XG5cbmNvbnN0IGRpc3RyaWJ1dGVQYWRkaW5nID0gKHRvdGFsUGFkOiBudW1iZXIsIGF1dG9QYWQ6IHN0cmluZywgcGFkczogbnVtYmVyW10sIGhlYWQ6IG51bWJlciwgdGFpbDogbnVtYmVyKSA9PiB7XG4gIGNvbnN0IHNtYWxsUGFkID0gTWF0aC5mbG9vcih0b3RhbFBhZCAvIDIpO1xuICBpZiAoYXV0b1BhZCA9PT0gJ1NBTUVfVVBQRVInKSB7XG4gICAgcGFkc1toZWFkXSA9IHNtYWxsUGFkO1xuICAgIHBhZHNbdGFpbF0gPSB0b3RhbFBhZCAtIHNtYWxsUGFkO1xuICB9IGVsc2UgaWYgKGF1dG9QYWQgPT09ICdTQU1FX0xPV0VSJykge1xuICAgIHBhZHNbaGVhZF0gPSB0b3RhbFBhZCAtIHNtYWxsUGFkO1xuICAgIHBhZHNbdGFpbF0gPSBzbWFsbFBhZDtcbiAgfVxufTtcblxuY29uc3QgY2FsY3VsYXRlT3V0cHV0U2hhcGVBbmRQYWRzID1cbiAgICAoaW5wdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIGtlcm5lbFNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgZGlsYXRpb25zOiByZWFkb25seSBudW1iZXJbXSwgYXV0b1BhZDogc3RyaW5nLFxuICAgICBwYWRzOiBudW1iZXJbXSwgc3RyaWRlczogcmVhZG9ubHkgbnVtYmVyW10sIG91dHB1dFBhZGRpbmc6IHJlYWRvbmx5IG51bWJlcltdLCBvdXRwdXRTaGFwZTogbnVtYmVyW10pID0+IHtcbiAgICAgIGNvbnN0IHNwYXRpYWxSYW5rID0gaW5wdXRTaGFwZS5sZW5ndGggLSAyO1xuICAgICAgY29uc3QgdXBkYXRlU2hhcGUgPSBvdXRwdXRTaGFwZS5sZW5ndGggPT09IDA7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNwYXRpYWxSYW5rOyArK2kpIHtcbiAgICAgICAgY29uc3Qgb3V0U2l6ZSA9IHVwZGF0ZVNoYXBlID8gaW5wdXRTaGFwZVtpICsgMl0gKiBzdHJpZGVzW2ldIDogb3V0cHV0U2hhcGVbaV07XG4gICAgICAgIGNvbnN0IHRvdGFsUGFkID0gY29tcHV0ZVRvdGFsUGFkKGlucHV0U2hhcGVbaSArIDJdLCBzdHJpZGVzW2ldLCBwYWRzW2ldLCBrZXJuZWxTaGFwZVtpXSwgZGlsYXRpb25zW2ldLCBvdXRTaXplKTtcbiAgICAgICAgZGlzdHJpYnV0ZVBhZGRpbmcodG90YWxQYWQsIGF1dG9QYWQsIHBhZHMsIGksIGkgKyBzcGF0aWFsUmFuayk7XG4gICAgICAgIGlmICh1cGRhdGVTaGFwZSkge1xuICAgICAgICAgIG91dHB1dFNoYXBlLnB1c2goXG4gICAgICAgICAgICAgIHN0cmlkZXNbaV0gKiAoaW5wdXRTaGFwZVtpICsgMl0gLSAxKSArIG91dHB1dFBhZGRpbmdbaV0gKyAoa2VybmVsU2hhcGVbaV0gLSAxKSAqIGRpbGF0aW9uc1tpXSArIDEgLVxuICAgICAgICAgICAgICBwYWRzW2ldIC0gcGFkc1tpICsgc3BhdGlhbFJhbmtdKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29udlRyYW5zcG9zZUF0dHJpYnV0ZXMgZXh0ZW5kcyBDb252QXR0cmlidXRlcyB7XG4gIHJlYWRvbmx5IG91dHB1dFBhZGRpbmc6IHJlYWRvbmx5IG51bWJlcltdO1xuICByZWFkb25seSBvdXRwdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW107XG59XG5cbmV4cG9ydCBjb25zdCBjb252VHJhbnNwb3NlOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPENvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzPiA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IENvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzKTogVGVuc29yW10gPT4ge1xuICAgICAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzLCBhdHRyaWJ1dGVzKTsgIC8vIGN1cnJlbnRseSB3aWxsIGZhaWwgaWYgbm90IGNvbnZUcmFuc3Bvc2UyRFxuICAgICAgcmV0dXJuIGNvbnZUcmFuc3Bvc2UyZChpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMpO1xuICAgIH07XG5cbmNvbnN0IGNvbnZUcmFuc3Bvc2UyZDogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxDb252VHJhbnNwb3NlQXR0cmlidXRlcz4gPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IENvbnZUcmFuc3Bvc2VBdHRyaWJ1dGVzKTogVGVuc29yW10gPT4ge1xuICAgICAgY29uc3QgYWRqdXN0ZWRBdHRyaWJ1dGVzID0gZ2V0QWRqdXN0ZWRDb252VHJhbnNwb3NlQXR0cmlidXRlcyhhdHRyaWJ1dGVzLCBpbnB1dHMpO1xuICAgICAgcmV0dXJuIFtjb252VHJhbnNwb3NlMkRVbnBhY2tlZChpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGFkanVzdGVkQXR0cmlidXRlcyldO1xuICAgIH07XG5cbmNvbnN0IGNyZWF0ZUNvbnZUcmFuc3Bvc2VQcm9ncmFtTWV0YWRhdGEgPSAoaGFzQmlhczogYm9vbGVhbiwgY2FjaGVIaW50OiBzdHJpbmcpID0+ICh7XG4gIG5hbWU6ICdDb252VHJhbnNwb3NlJyxcbiAgaW5wdXROYW1lczogaGFzQmlhcyA/IFsnWCcsICdXJywgJ0InXSA6IFsnWCcsICdXJ10sXG4gIGlucHV0VHlwZXM6IGhhc0JpYXMgPyBbVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZF0gOlxuICAgICAgICAgICAgICAgICAgICAgICAgW1RleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG4gIGNhY2hlSGludFxufSk7XG5cbmNvbnN0IGNyZWF0ZVVucGFja2VkQ29udlRyYW5zcG9zZVByb2dyYW1JbmZvID1cbiAgICAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvcltdLCBtZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhLFxuICAgICBhdHRyaWJ1dGVzOiBDb252VHJhbnNwb3NlQXR0cmlidXRlcyk6IFByb2dyYW1JbmZvID0+IHtcbiAgICAgIGNvbnN0IGhhc0JpYXMgPSBpbnB1dHMubGVuZ3RoID4gMjtcbiAgICAgIGNvbnN0IHZhbHVlSW5pdCA9IGhhc0JpYXMgPyAnZ2V0QihvdXRwdXRfY2hhbm5lbCknIDogJzAuMCc7XG4gICAgICBjb25zdCB4U2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgICAgIGNvbnN0IHdTaGFwZSA9IGlucHV0c1sxXS5kaW1zO1xuICAgICAgY29uc3Qgb3V0cHV0Q2hhbm5lbHNQZXJHcm91cCA9IHdTaGFwZVsxXTtcbiAgICAgIGNvbnN0IGlucHV0Q2hhbm5lbHNQZXJHcm91cCA9IHdTaGFwZVswXSAvIGF0dHJpYnV0ZXMuZ3JvdXA7XG4gICAgICBjb25zdCBvdXRwdXRTaGFwZSA9IFtpbnB1dHNbMF0uZGltc1swXSwgaW5wdXRzWzFdLmRpbXNbMV0gKiBhdHRyaWJ1dGVzLmdyb3VwLCAuLi5hdHRyaWJ1dGVzLm91dHB1dFNoYXBlXTtcbiAgICAgIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgICAgIGNvbnN0IHthY3RpdmF0aW9uRnVuY3Rpb24sIGFwcGx5QWN0aXZhdGlvbn0gPSBnZXRBY3RpdmF0aW9uU25pcHBldChhdHRyaWJ1dGVzKTtcblxuICAgICAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICBjb25zdCBpdmVjMiBzdHJpZGVzID0gaXZlYzIoJHthdHRyaWJ1dGVzLnN0cmlkZXNbMF19LCAke2F0dHJpYnV0ZXMuc3RyaWRlc1sxXX0pO1xuICBjb25zdCBpdmVjMiBwYWRzID0gaXZlYzIoJHthdHRyaWJ1dGVzLnBhZHNbMF19LCAke2F0dHJpYnV0ZXMucGFkc1sxXX0pO1xuICAke2FjdGl2YXRpb25GdW5jdGlvbn1cbiAgdm9pZCBtYWluKCkge1xuICAgIGl2ZWM0IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpO1xuICAgIGludCBiYXRjaCA9IGNvb3Jkcy54O1xuICAgIGludCBvdXRwdXRfY2hhbm5lbCA9IGNvb3Jkcy55O1xuXG4gICAgaXZlYzIgbG9jID0gY29vcmRzLnp3ICsgcGFkcztcblxuICAgIGludCBncm91cF9pZCA9IG91dHB1dF9jaGFubmVsIC8gJHtvdXRwdXRDaGFubmVsc1Blckdyb3VwfTtcbiAgICBpbnQgd091dENoYW5uZWwgPSBvdXRwdXRfY2hhbm5lbCAtIGdyb3VwX2lkICogJHtvdXRwdXRDaGFubmVsc1Blckdyb3VwfTtcblxuICAgIGZsb2F0IHZhbHVlID0gJHt2YWx1ZUluaXR9O1xuICAgIGZvciAoaW50IGluQ2hhbm5lbE9mZnNldCA9IDA7IGluQ2hhbm5lbE9mZnNldCA8ICR7aW5wdXRDaGFubmVsc1Blckdyb3VwfTsgaW5DaGFubmVsT2Zmc2V0KyspIHtcbiAgICAgIGludCBpbnB1dF9jaGFubmVsID0gZ3JvdXBfaWQgKiAke2lucHV0Q2hhbm5lbHNQZXJHcm91cH0gKyBpbkNoYW5uZWxPZmZzZXQ7XG4gICAgICBmb3IgKGludCB3V09mZiA9IDA7IHdXT2ZmIDwgJHt3U2hhcGVbMl19OyB3V09mZisrKSB7XG4gICAgICAgIGZvciAoaW50IHdIT2ZmID0gMDsgd0hPZmYgPCAke3dTaGFwZVszXX07IHdIT2ZmKyspIHtcbiAgICAgICAgICBpdmVjMiB3T2ZmID0gaXZlYzIod1dPZmYgKiAke2F0dHJpYnV0ZXMuZGlsYXRpb25zWzBdfSwgd0hPZmYgKiAke2F0dHJpYnV0ZXMuZGlsYXRpb25zWzFdfSk7XG4gICAgICAgICAgaXZlYzIgd0xvYyA9IGxvYyAtIHdPZmY7XG4gICAgICAgICAgaXZlYzIgd0xvY0luID0gd0xvYyAvIHN0cmlkZXM7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgd0xvY0luICogc3RyaWRlcyA9PSB3TG9jICYmXG4gICAgICAgICAgICB3TG9jSW4ueCA+PSAwICYmIHdMb2NJbi54IDwgJHt4U2hhcGVbMl19ICYmXG4gICAgICAgICAgICB3TG9jSW4ueSA+PSAwICYmIHdMb2NJbi55IDwgJHt4U2hhcGVbM119XG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBmbG9hdCB4VmFsID0gZ2V0WChiYXRjaCwgaW5wdXRfY2hhbm5lbCwgd0xvY0luLnksIHdMb2NJbi54KTtcbiAgICAgICAgICAgIGZsb2F0IHdWYWwgPSBnZXRXKGlucHV0X2NoYW5uZWwsIHdPdXRDaGFubmVsLCB3SE9mZiwgd1dPZmYpO1xuICAgICAgICAgICAgdmFsdWUgKz0geFZhbCAqIHdWYWw7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgICR7YXBwbHlBY3RpdmF0aW9ufVxuICAgICR7Z2xzbC5vdXRwdXR9ID0gdmVjNCh2YWx1ZSwgLjAsIC4wLCAuMCk7XG4gIH1cbmA7XG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5tZXRhZGF0YSxcbiAgICAgICAgb3V0cHV0OiB7ZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWR9LFxuICAgICAgICBzaGFkZXJTb3VyY2UsXG4gICAgICAgIGhhc01haW46IHRydWUsXG4gICAgICB9O1xuICAgIH07XG5cbmNvbnN0IGNyZWF0ZVVucGFja2VkQ29udlRyYW5zcG9zZVByb2dyYW1JbmZvTG9hZGVyID1cbiAgICAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBDb252VHJhbnNwb3NlQXR0cmlidXRlcyk6XG4gICAgICAgIFByb2dyYW1JbmZvTG9hZGVyID0+IHtcbiAgICAgICAgICBjb25zdCBtZXRhZGF0YSA9IGNyZWF0ZUNvbnZUcmFuc3Bvc2VQcm9ncmFtTWV0YWRhdGEoaW5wdXRzLmxlbmd0aCA+IDIsIGF0dHJpYnV0ZXMuY2FjaGVLZXkpO1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAuLi5tZXRhZGF0YSxcbiAgICAgICAgICAgIGdldDogKCkgPT4gY3JlYXRlVW5wYWNrZWRDb252VHJhbnNwb3NlUHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBtZXRhZGF0YSwgYXR0cmlidXRlcylcbiAgICAgICAgICB9O1xuICAgICAgICB9O1xuXG5cbmNvbnN0IGNvbnZUcmFuc3Bvc2UyRFVucGFja2VkID1cbiAgICAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBDb252VHJhbnNwb3NlQXR0cmlidXRlcyk6XG4gICAgICAgIFRlbnNvciA9PiB7XG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgICAgICAgICAgIGNyZWF0ZVVucGFja2VkQ29udlRyYW5zcG9zZVByb2dyYW1JbmZvTG9hZGVyKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcyksIGlucHV0cyk7XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfTtcblxuY29uc3QgZ2V0QWRqdXN0ZWRDb252VHJhbnNwb3NlQXR0cmlidXRlcyA9IDxUIGV4dGVuZHMgQ29udlRyYW5zcG9zZUF0dHJpYnV0ZXM+KGF0dHJpYnV0ZXM6IFQsIGlucHV0czogVGVuc29yW10pOiBUID0+IHtcbiAgY29uc3Qga2VybmVsU2hhcGUgPSBhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLnNsaWNlKCk7XG4gIC8vIGlmIGtlcm5lbFNoYXBlIGlzIG5vdCBzcGVjaWZpZWQgaW4gdGhlIGF0dHJpYnV0ZXMgb2YgdGhpcyBvcCwgaW5mZXIgaXQgZnJvbSB0aGUgd2VpZ2h0IHRlbnNvciBkaW1zXG4gIGlmIChhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLmxlbmd0aCA9PT0gMCkge1xuICAgIGZvciAobGV0IGkgPSAyOyBpIDwgaW5wdXRzWzFdLmRpbXMubGVuZ3RoOyArK2kpIHtcbiAgICAgIGtlcm5lbFNoYXBlLnB1c2goaW5wdXRzWzFdLmRpbXNbaV0pO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IHBhZHMgPSBhdHRyaWJ1dGVzLnBhZHMuc2xpY2UoKTtcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBhdHRyaWJ1dGVzLm91dHB1dFNoYXBlLnNsaWNlKCk7XG4gIGNvbnN0IGlucHV0U2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgLy8gSWYgb3V0cHV0U2hhcGUgaXMgbm90IHNwZWNpZmllZCBpbiB0aGUgYXR0cmlidXRlcyBvZiB0aGlzIG9wLCBpbmZlciBpdCBmcm9tIHRoZSBwYXJhbWV0ZXJzXG4gIC8vIFNpbWlsYXJseSwgYXV0b21hdGljYWxseSBpbmZlciBwYWRzIGlmIG5vdCBzcGVjaWZpZWRcbiAgY2FsY3VsYXRlT3V0cHV0U2hhcGVBbmRQYWRzKFxuICAgICAgaW5wdXRTaGFwZSwga2VybmVsU2hhcGUsIGF0dHJpYnV0ZXMuZGlsYXRpb25zLCBhdHRyaWJ1dGVzLmF1dG9QYWQsIHBhZHMsIGF0dHJpYnV0ZXMuc3RyaWRlcyxcbiAgICAgIGF0dHJpYnV0ZXMub3V0cHV0UGFkZGluZywgb3V0cHV0U2hhcGUpO1xuXG4gIC8vIGFsd2F5cyByZXR1cm4gYSBuZXcgb2JqZWN0IHNvIGRvZXMgbm90IG1vZGlmeSB0aGUgb3JpZ2luYWwgYXR0cmlidXRlc1xuICBjb25zdCBuZXdBdHRyaWJ1dGVzOiBUID0gT2JqZWN0LmFzc2lnbih7fSwgYXR0cmlidXRlcyk7XG4gIE9iamVjdC5hc3NpZ24obmV3QXR0cmlidXRlcywge2tlcm5lbFNoYXBlLCBwYWRzLCBvdXRwdXRTaGFwZSwgY2FjaGVLZXk6IGF0dHJpYnV0ZXMuY2FjaGVLZXl9KTtcbiAgcmV0dXJuIG5ld0F0dHJpYnV0ZXM7XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VDb252VHJhbnNwb3NlQXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxDb252VHJhbnNwb3NlQXR0cmlidXRlcz4gPVxuICAgIChub2RlOiBHcmFwaC5Ob2RlKTogQ29udlRyYW5zcG9zZUF0dHJpYnV0ZXMgPT4ge1xuICAgICAgY29uc3QgYXR0cmlidXRlcyA9IG5vZGUuYXR0cmlidXRlcztcbiAgICAgIGNvbnN0IGFjdGl2YXRpb25BdHRyaWJ1dGVzID0gcGFyc2VJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzKGF0dHJpYnV0ZXMpO1xuICAgICAgLy8gVE9ETyA6IE1ha2UgdGhpcyBnZW5lcmljIGVub3VnaCB0byBjb21wdXRlIGRlZmF1bHQgYXR0cmlidXRlcyBmb3IgbXVsdGktZGltZW5zaW9uYWwgY29udlxuICAgICAgY29uc3QgYXV0b1BhZCA9IGF0dHJpYnV0ZXMuZ2V0U3RyaW5nKCdhdXRvX3BhZCcsICdOT1RTRVQnKTtcbiAgICAgIGNvbnN0IGRpbGF0aW9ucyA9IGF0dHJpYnV0ZXMuZ2V0SW50cygnZGlsYXRpb25zJywgWzEsIDFdKTtcbiAgICAgIGNvbnN0IGdyb3VwID0gYXR0cmlidXRlcy5nZXRJbnQoJ2dyb3VwJywgMSk7XG4gICAgICBjb25zdCBrZXJuZWxTaGFwZSA9IGF0dHJpYnV0ZXMuZ2V0SW50cygna2VybmVsX3NoYXBlJywgW10pO1xuICAgICAgY29uc3Qgb3V0cHV0UGFkZGluZyA9IGF0dHJpYnV0ZXMuZ2V0SW50cygnb3V0cHV0X3BhZGRpbmcnLCBbMCwgMF0pO1xuICAgICAgY29uc3Qgb3V0cHV0U2hhcGUgPSBhdHRyaWJ1dGVzLmdldEludHMoJ291dHB1dF9zaGFwZScsIFtdKTtcbiAgICAgIGNvbnN0IHBhZHMgPSBhdHRyaWJ1dGVzLmdldEludHMoJ3BhZHMnLCBbMCwgMCwgMCwgMF0pO1xuICAgICAgY29uc3Qgc3RyaWRlcyA9IGF0dHJpYnV0ZXMuZ2V0SW50cygnc3RyaWRlcycsIFsxLCAxXSk7XG5cbiAgICAgIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoXG4gICAgICAgICAge2F1dG9QYWQsIGRpbGF0aW9ucywgZ3JvdXAsIGtlcm5lbFNoYXBlLCBvdXRwdXRQYWRkaW5nLCBvdXRwdXRTaGFwZSwgcGFkcywgc3RyaWRlcywgLi4uYWN0aXZhdGlvbkF0dHJpYnV0ZXN9KTtcbiAgICB9O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBDb252VHJhbnNwb3NlQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICAvLyBSZWZlciB0byB0aGUgYmVsb3cgbGluayBmb3IgYWxsIGlucHV0IGNoZWNrc1xuICAvLyBodHRwczovL2dpdGh1Yi5jb20vb25ueC9vbm54L2Jsb2IvbWFpbi9kb2NzL09wZXJhdG9ycy5tZCNDb252XG4gIGlmICghaW5wdXRzIHx8IChpbnB1dHMubGVuZ3RoICE9PSAyICYmIGlucHV0cy5sZW5ndGggIT09IDMpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDb252IHJlcXVpcmVzIDIgb3IgMyBpbnB1dHMnKTtcbiAgfVxuXG4gIC8vIFRPRE8gOiBOZWVkIHRvIGFkZCBzdXBwb3J0IGZvciBtdWx0aS1kaW1lbnNpb25hbCBjb252XG4gIGlmIChpbnB1dHNbMF0uZGltcy5sZW5ndGggIT09IDQgfHwgaW5wdXRzWzFdLmRpbXMubGVuZ3RoICE9PSA0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdjdXJyZW50bHkgb25seSBzdXBwb3J0IDItZGltZW5zaW9uYWwgY29udicpO1xuICB9XG5cbiAgLy8gRklMVEVSX0lOX0NIQU5ORUwgc2hvdWxkIGJlIGVxdWFsIHRvIERBVEFfQ0hBTk5FTFxuICBjb25zdCBkYXRhQ2hhbm5lbCA9IGlucHV0c1swXS5kaW1zWzFdO1xuICBjb25zdCBmaWx0ZXJJbkNoYW5uZWwgPSBpbnB1dHNbMV0uZGltc1swXTtcbiAgaWYgKGRhdGFDaGFubmVsICE9PSBmaWx0ZXJJbkNoYW5uZWwpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZJTFRFUl9JTl9DSEFOTkVMIHNob3VsZCBiZSBlcXVhbCB0byBEQVRBX0NIQU5ORUwnKTtcbiAgfVxuXG4gIGNvbnN0IGZlYXR1cmVNYXBzID0gaW5wdXRzWzFdLmRpbXNbMV0gKiBhdHRyaWJ1dGVzLmdyb3VwO1xuXG4gIC8vIGlmIGJpYXMgaXMgcHJvdmlkZWQgaXQgc2hvdWxkIGJlIDFEIGFuZCB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIHNob3VsZCBiZSBlcXVhbCB0byB0aGUgbnVtYmVyIG9mIGZlYXR1cmUgbWFwc1xuICBpZiAoaW5wdXRzLmxlbmd0aCA9PT0gMyAmJiAoaW5wdXRzWzJdLmRpbXMubGVuZ3RoICE9PSAxIHx8IGlucHV0c1syXS5kaW1zWzBdICE9PSBmZWF0dXJlTWFwcykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgYmlhcycpO1xuICB9XG5cbiAgY29uc3Qgc3BhdGlhbFJhbmsgPSBpbnB1dHNbMF0uZGltcy5sZW5ndGggLSAyO1xuICAvLyB3cm9uZyBkaWxhdGlvbnMgZGltZW5zaW9uXG4gIGlmIChhdHRyaWJ1dGVzLmRpbGF0aW9ucy5sZW5ndGggIT09IHNwYXRpYWxSYW5rKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBkaWxhdGlvbnMgc2hvdWxkIGJlICR7c3BhdGlhbFJhbmt9RGApO1xuICB9XG5cbiAgLy8gV3Jvbmcgc3RyaWRlcyBkaW1lbnNpb25cbiAgaWYgKGF0dHJpYnV0ZXMuc3RyaWRlcy5sZW5ndGggIT09IHNwYXRpYWxSYW5rKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBzdHJpZGVzIHNob3VsZCBiZSAke3NwYXRpYWxSYW5rfURgKTtcbiAgfVxuXG4gIC8vIFdyb25nIHBhZHMgZGltZW5zaW9uXG4gIGlmIChhdHRyaWJ1dGVzLnBhZHMubGVuZ3RoICE9PSBzcGF0aWFsUmFuayAqIDIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYHBhZHMgc2hvdWxkIGJlICR7c3BhdGlhbFJhbmsgKiAyfURgKTtcbiAgfVxuXG4gIC8vIFdyb25nIG91dHB1dCBwYWRkaW5nIGRpbWVuc2lvblxuICBpZiAoYXR0cmlidXRlcy5vdXRwdXRQYWRkaW5nLmxlbmd0aCAhPT0gc3BhdGlhbFJhbmspIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYG91dHB1dF9wYWRkaW5nIHNob3VsZCBiZSAke3NwYXRpYWxSYW5rfURgKTtcbiAgfVxuXG4gIC8vIGlmIGtlcm5lbFNoYXBlIGlzIHNwZWNpZmllZCwgaXQncyBkYXRhIGxlbmd0aCBtdXN0IGJlIDIgbGVzcyB0aGFuIGRpbXMgbGVuZ3RoIG9mIHRoZSB3ZWlnaHRzIHRlbnNvclxuICAvLyAodGhlIGZpcnN0IDIgZGltcyBhcmUgYmF0Y2hfc2l6ZSBhbmQgY2hhbm5lbHMpXG4gIGlmIChhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLmxlbmd0aCAhPT0gMCAmJiBhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLmxlbmd0aCAhPT0gaW5wdXRzWzFdLmRpbXMubGVuZ3RoIC0gMikge1xuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBrZXJuZWwgc2hhcGUnKTtcbiAgfVxuXG4gIC8vIGFzIHdpdGgga2VybmVsU2hhcGUsIG11c3QgaGF2ZSBzYW1lIG51bWJlciBvZiBzcGF0aWFsIGRpbXMgYXMgaW5wdXRcbiAgaWYgKGF0dHJpYnV0ZXMub3V0cHV0U2hhcGUubGVuZ3RoICE9PSAwICYmIGF0dHJpYnV0ZXMub3V0cHV0U2hhcGUubGVuZ3RoICE9PSBpbnB1dHNbMF0uZGltcy5sZW5ndGggLSAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIG91dHB1dCBzaGFwZScpO1xuICB9XG5cbiAgLy8gVE9ETyA6IE5lZWQgdG8gYWRkIHN1cHBvcnQgZm9yIGZsb2F0NjRcbiAgaWYgKGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQzMicgfHwgaW5wdXRzWzFdLnR5cGUgIT09ICdmbG9hdDMyJykge1xuICAgIHRocm93IG5ldyBFcnJvcignQ29udlRyYW5zcG9zZSBpbnB1dChYLFcpIHNob3VsZCBiZSBmbG9hdCB0ZW5zb3InKTtcbiAgfVxuXG4gIGlmIChpbnB1dHMubGVuZ3RoID09PSAzICYmIGlucHV0c1syXS50eXBlICE9PSAnZmxvYXQzMicpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvbnZUcmFuc3Bvc2UgaW5wdXQoYmlhcykgc2hvdWxkIGJlIGZsb2F0IHRlbnNvcicpO1xuICB9XG59O1xuIiwiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7QXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXl9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQge0luZmVyZW5jZUhhbmRsZXJ9IGZyb20gJy4uLy4uLy4uL2JhY2tlbmQnO1xuaW1wb3J0IHtHcmFwaH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHtPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9ufSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHtUZW5zb3J9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQge1Bvb2xDb252VXRpbH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQge1dlYkdMSW5mZXJlbmNlSGFuZGxlcn0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuXG5pbXBvcnQge2NyZWF0ZVVucGFja2VkR3JvdXBlZENvbnZQcm9ncmFtSW5mb0xvYWRlcn0gZnJvbSAnLi9jb252LWdyb3VwZWQnO1xuaW1wb3J0IHtjb252MkRQYWNrZWR9IGZyb20gJy4vY29udi1wYWNrJztcbmltcG9ydCB7Y3JlYXRlRG90UHJvZHVjdFByb2dyYW1JbmZvTG9hZGVyfSBmcm9tICcuL2RvdC1wcm9kdWN0JztcbmltcG9ydCB7SW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcywgcGFyc2VJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzfSBmcm9tICcuL2Z1c2UtdXRpbHMnO1xuaW1wb3J0IHtjcmVhdGVJbTJDb2xQcm9ncmFtSW5mb0xvYWRlcn0gZnJvbSAnLi9pbTJjb2wnO1xuaW1wb3J0IHtjcmVhdGVNYXRtdWxQcm9ncmFtSW5mb0xvYWRlcn0gZnJvbSAnLi9tYXRtdWwnO1xuXG5cbmV4cG9ydCBjb25zdCBjYWxjdWxhdGVPdXRwdXRTaGFwZSA9XG4gICAgKGlucHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCBrZXJuZWxTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIGRpbGF0aW9uczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgIGFkanVzdFBhZHM6IHJlYWRvbmx5IG51bWJlcltdLCBzdHJpZGVzOiByZWFkb25seSBudW1iZXJbXSk6IG51bWJlcltdID0+IHtcbiAgICAgIGNvbnN0IGJhdGNoU2l6ZSA9IGlucHV0U2hhcGVbMF07XG4gICAgICBjb25zdCBpbnB1dFNwYXRpYWxTaGFwZSA9IGlucHV0U2hhcGUuc2xpY2UoMik7XG4gICAgICBjb25zdCBzcGF0aWFsUmFuayA9IGlucHV0U3BhdGlhbFNoYXBlLmxlbmd0aDtcbiAgICAgIGNvbnN0IG91dENoYW5uZWxzID0ga2VybmVsU2hhcGVbMF07XG4gICAgICBjb25zdCBrZXJuZWxTcGF0aWFsU2hhcGUgPSBrZXJuZWxTaGFwZS5zbGljZSgyKTtcbiAgICAgIGNvbnN0IGRpbGF0ZWRLZXJuZWxTaGFwZSA9IGtlcm5lbFNwYXRpYWxTaGFwZS5tYXAoKHYsIGkpID0+IHYgKyAodiAtIDEpICogKGRpbGF0aW9uc1tpXSAtIDEpKTtcbiAgICAgIGNvbnN0IGlucHV0U3BhdGlhbFNoYXBlV2l0aFBhZCA9IGlucHV0U3BhdGlhbFNoYXBlLm1hcCgodiwgaSkgPT4gdiArIGFkanVzdFBhZHNbaV0gKyBhZGp1c3RQYWRzW2kgKyBzcGF0aWFsUmFua10pO1xuICAgICAgY29uc3Qgb3V0cHV0U3BhdGlhbFNoYXBlID1cbiAgICAgICAgICBpbnB1dFNwYXRpYWxTaGFwZVdpdGhQYWQubWFwKCh2LCBpKSA9PiBNYXRoLmZsb29yKCh2IC0gZGlsYXRlZEtlcm5lbFNoYXBlW2ldICsgc3RyaWRlc1tpXSkgLyBzdHJpZGVzW2ldKSk7XG4gICAgICBjb25zdCBvdXRwdXRTaGFwZSA9IFtiYXRjaFNpemUsIG91dENoYW5uZWxzXS5jb25jYXQoLi4ub3V0cHV0U3BhdGlhbFNoYXBlKTtcbiAgICAgIHJldHVybiBvdXRwdXRTaGFwZTtcbiAgICB9O1xuXG5leHBvcnQgaW50ZXJmYWNlIENvbnZBdHRyaWJ1dGVzIGV4dGVuZHMgSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcywgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgYXV0b1BhZDogc3RyaW5nO1xuICByZWFkb25seSBkaWxhdGlvbnM6IHJlYWRvbmx5IG51bWJlcltdO1xuICByZWFkb25seSBncm91cDogbnVtYmVyO1xuICByZWFkb25seSBrZXJuZWxTaGFwZTogcmVhZG9ubHkgbnVtYmVyW107XG4gIHJlYWRvbmx5IHBhZHM6IHJlYWRvbmx5IG51bWJlcltdO1xuICByZWFkb25seSBzdHJpZGVzOiByZWFkb25seSBudW1iZXJbXTtcbn1cblxuZXhwb3J0IGNvbnN0IGNvbnY6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248Q29udkF0dHJpYnV0ZXM+ID1cbiAgICAoaW5mZXJlbmNlSGFuZGxlcjogSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogQ29udkF0dHJpYnV0ZXMpOiBUZW5zb3JbXSA9PiB7XG4gICAgICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMsIGF0dHJpYnV0ZXMpOyAgLy8gY3VycmVudGx5IHdpbGwgZmFpbCBpZiBub3QgY29udjJEXG4gICAgICByZXR1cm4gY29udjJkKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcyk7XG4gICAgfTtcblxuY29uc3QgY29udjJkOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPENvbnZBdHRyaWJ1dGVzPiA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogQ29udkF0dHJpYnV0ZXMpOiBUZW5zb3JbXSA9PiB7XG4gICAgICBjb25zdCBhZGp1c3RlZEF0dHJpYnV0ZXMgPSBnZXRBZGp1c3RlZENvbnZBdHRyaWJ1dGVzKGF0dHJpYnV0ZXMsIGlucHV0cyk7XG4gICAgICBjb25zdCBwYWNrTW9kZSA9IGluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5wYWNrO1xuICAgICAgY29uc3QgaXNQb2ludHdpc2UgPSBhZGp1c3RlZEF0dHJpYnV0ZXMua2VybmVsU2hhcGVbMF0gPT09IDEgJiYgYWRqdXN0ZWRBdHRyaWJ1dGVzLmtlcm5lbFNoYXBlWzFdID09PSAxO1xuICAgICAgaWYgKGFkanVzdGVkQXR0cmlidXRlcy5ncm91cCA+IDEpIHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgICAgICAgICBjcmVhdGVVbnBhY2tlZEdyb3VwZWRDb252UHJvZ3JhbUluZm9Mb2FkZXIoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhZGp1c3RlZEF0dHJpYnV0ZXMpLCBpbnB1dHMpO1xuICAgICAgICByZXR1cm4gW3Jlc3VsdF07XG4gICAgICB9IGVsc2UgaWYgKGlzUG9pbnR3aXNlICYmIHBhY2tNb2RlKSB7XG4gICAgICAgIHJldHVybiBbY29udjJEVW5wYWNrZWRQb2ludHdpc2UoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhZGp1c3RlZEF0dHJpYnV0ZXMpXTtcbiAgICAgIH0gZWxzZSBpZiAocGFja01vZGUgJiYgaW5wdXRzWzBdLmRpbXMubGVuZ3RoID09PSA0ICYmIGlucHV0c1swXS5kaW1zWzBdID09PSAxICYmICFpc1BvaW50d2lzZSkge1xuICAgICAgICByZXR1cm4gW2NvbnYyRFBhY2tlZChpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGFkanVzdGVkQXR0cmlidXRlcyldO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIFtjb252MkRVbnBhY2tlZChpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGFkanVzdGVkQXR0cmlidXRlcyldO1xuICAgICAgfVxuICAgIH07XG5cbmNvbnN0IGNvbnYyRFVucGFja2VkUG9pbnR3aXNlID1cbiAgICAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IHJlYWRvbmx5IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBDb252QXR0cmlidXRlcyk6IFRlbnNvciA9PiB7XG4gICAgICBjb25zdCB4c2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgICAgIGNvbnN0IGtzaGFwZSA9IGlucHV0c1sxXS5kaW1zO1xuICAgICAgY29uc3Qgb3V0cHV0U2hhcGUgPVxuICAgICAgICAgIGNhbGN1bGF0ZU91dHB1dFNoYXBlKHhzaGFwZSwga3NoYXBlLCBhdHRyaWJ1dGVzLmRpbGF0aW9ucywgYXR0cmlidXRlcy5wYWRzLCBhdHRyaWJ1dGVzLnN0cmlkZXMpO1xuICAgICAgY29uc3QgcmVzaGFwZWRYID0gaW5mZXJlbmNlSGFuZGxlci5yZXNoYXBlVW5wYWNrZWQoaW5wdXRzWzBdLCBbeHNoYXBlWzFdLCB4c2hhcGVbMl0gKiB4c2hhcGVbM11dKTtcbiAgICAgIGNvbnN0IHJlc2hhcGVkSyA9IGluZmVyZW5jZUhhbmRsZXIucmVzaGFwZVVucGFja2VkKGlucHV0c1sxXSwgW2tzaGFwZVswXSwga3NoYXBlWzFdXSk7XG5cbiAgICAgIGNvbnN0IG1hdG11bElucHV0cyA9IGlucHV0cy5sZW5ndGggPiAyID8gW3Jlc2hhcGVkSywgcmVzaGFwZWRYLCBpbnB1dHNbMl1dIDogW3Jlc2hhcGVkSywgcmVzaGFwZWRYXTtcbiAgICAgIGNvbnN0IG1hdG11bE91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKGNyZWF0ZU1hdG11bFByb2dyYW1JbmZvTG9hZGVyKG1hdG11bElucHV0cywgYXR0cmlidXRlcyksIG1hdG11bElucHV0cyk7XG4gICAgICByZXR1cm4gaW5mZXJlbmNlSGFuZGxlci5yZXNoYXBlVW5wYWNrZWQobWF0bXVsT3V0cHV0LCBvdXRwdXRTaGFwZSk7XG4gICAgfTtcblxuY29uc3QgY29udjJEVW5wYWNrZWQgPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogcmVhZG9ubHkgVGVuc29yW10sIGF0dHJpYnV0ZXM6IENvbnZBdHRyaWJ1dGVzKTogVGVuc29yID0+IHtcbiAgICAgIGNvbnN0IHhzaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICAgICAgY29uc3Qga3NoYXBlID0gaW5wdXRzWzFdLmRpbXM7XG4gICAgICBjb25zdCBvdXRwdXRTaGFwZSA9XG4gICAgICAgICAgY2FsY3VsYXRlT3V0cHV0U2hhcGUoeHNoYXBlLCBrc2hhcGUsIGF0dHJpYnV0ZXMuZGlsYXRpb25zLCBhdHRyaWJ1dGVzLnBhZHMsIGF0dHJpYnV0ZXMuc3RyaWRlcyk7XG4gICAgICBjb25zdCB4SW0yQ29sID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgICAgICAgY3JlYXRlSW0yQ29sUHJvZ3JhbUluZm9Mb2FkZXIoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzWzBdLCBpbnB1dHNbMV0sIG91dHB1dFNoYXBlLCBhdHRyaWJ1dGVzKSwgW2lucHV0c1swXV0pO1xuXG4gICAgICBjb25zdCBkb3RQcm9kdWN0SW5wdXRzID0gaW5wdXRzLmxlbmd0aCA9PT0gMyA/IFt4SW0yQ29sLCBpbnB1dHNbMV0sIGlucHV0c1syXV0gOiBbeEltMkNvbCwgaW5wdXRzWzFdXTtcbiAgICAgIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgICAgICAgIGNyZWF0ZURvdFByb2R1Y3RQcm9ncmFtSW5mb0xvYWRlcihpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIG91dHB1dFNoYXBlLCBhdHRyaWJ1dGVzKSwgZG90UHJvZHVjdElucHV0cyk7XG4gICAgICByZXR1cm4gb3V0cHV0O1xuICAgIH07XG5cbmNvbnN0IGdldEFkanVzdGVkQ29udkF0dHJpYnV0ZXMgPSA8VCBleHRlbmRzIENvbnZBdHRyaWJ1dGVzPihhdHRyaWJ1dGVzOiBULCBpbnB1dHM6IFRlbnNvcltdKTogVCA9PiB7XG4gIGNvbnN0IGtlcm5lbFNoYXBlID0gYXR0cmlidXRlcy5rZXJuZWxTaGFwZS5zbGljZSgpO1xuICAvLyBpZiBrZXJuZWxTaGFwZSBpcyBub3Qgc3BlY2lmaWVkIGluIHRoZSBhdHRyaWJ1dGVzIG9mIHRoaXMgb3AsIGluZmVyIGl0IGZyb20gdGhlIHdlaWdodCB0ZW5zb3IgZGltc1xuICBpZiAoYXR0cmlidXRlcy5rZXJuZWxTaGFwZS5sZW5ndGggPT09IDApIHtcbiAgICBmb3IgKGxldCBpID0gMjsgaSA8IGlucHV0c1sxXS5kaW1zLmxlbmd0aDsgKytpKSB7XG4gICAgICBrZXJuZWxTaGFwZS5wdXNoKGlucHV0c1sxXS5kaW1zW2ldKTtcbiAgICB9XG4gIH1cbiAgY29uc3QgcGFkcyA9IGF0dHJpYnV0ZXMucGFkcy5zbGljZSgpO1xuICBQb29sQ29udlV0aWwuYWRqdXN0UGFkc0Jhc2VkT25BdXRvUGFkKFxuICAgICAgaW5wdXRzWzBdLmRpbXMsIGF0dHJpYnV0ZXMuc3RyaWRlcywgYXR0cmlidXRlcy5kaWxhdGlvbnMsIGtlcm5lbFNoYXBlLCBwYWRzLCBhdHRyaWJ1dGVzLmF1dG9QYWQpO1xuXG4gIC8vIGFsd2F5cyByZXR1cm4gYSBuZXcgb2JqZWN0IHNvIGRvZXMgbm90IG1vZGlmeSB0aGUgb3JpZ2luYWwgYXR0cmlidXRlc1xuICBjb25zdCBuZXdBdHRyaWJ1dGVzOiBUID0gT2JqZWN0LmFzc2lnbih7fSwgYXR0cmlidXRlcyk7XG4gIE9iamVjdC5hc3NpZ24obmV3QXR0cmlidXRlcywge2tlcm5lbFNoYXBlLCBwYWRzLCBjYWNoZUtleTogYXR0cmlidXRlcy5jYWNoZUtleX0pO1xuICByZXR1cm4gbmV3QXR0cmlidXRlcztcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZUNvbnZBdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPENvbnZBdHRyaWJ1dGVzPiA9IChub2RlOiBHcmFwaC5Ob2RlKTogQ29udkF0dHJpYnV0ZXMgPT4ge1xuICBjb25zdCBhdHRyaWJ1dGVzID0gbm9kZS5hdHRyaWJ1dGVzO1xuICBjb25zdCBhY3RpdmF0aW9uQXR0cmlidXRlcyA9IHBhcnNlSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyhhdHRyaWJ1dGVzKTtcbiAgLy8gVE9ETyA6IE1ha2UgdGhpcyBnZW5lcmljIGVub3VnaCB0byBjb21wdXRlIGRlZmF1bHQgYXR0cmlidXRlcyBmb3IgbXVsdGktZGltZW5zaW9uYWwgY29udlxuICBjb25zdCBhdXRvUGFkID0gYXR0cmlidXRlcy5nZXRTdHJpbmcoJ2F1dG9fcGFkJywgJ05PVFNFVCcpO1xuICBjb25zdCBkaWxhdGlvbnMgPSBhdHRyaWJ1dGVzLmdldEludHMoJ2RpbGF0aW9ucycsIFsxLCAxXSk7XG4gIGNvbnN0IGdyb3VwID0gYXR0cmlidXRlcy5nZXRJbnQoJ2dyb3VwJywgMSk7XG4gIGNvbnN0IGtlcm5lbFNoYXBlID0gYXR0cmlidXRlcy5nZXRJbnRzKCdrZXJuZWxfc2hhcGUnLCBbXSk7XG4gIGNvbnN0IHBhZHMgPSBhdHRyaWJ1dGVzLmdldEludHMoJ3BhZHMnLCBbMCwgMCwgMCwgMF0pO1xuICBjb25zdCBzdHJpZGVzID0gYXR0cmlidXRlcy5nZXRJbnRzKCdzdHJpZGVzJywgWzEsIDFdKTtcblxuICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHthdXRvUGFkLCBkaWxhdGlvbnMsIGdyb3VwLCBrZXJuZWxTaGFwZSwgcGFkcywgc3RyaWRlcywgLi4uYWN0aXZhdGlvbkF0dHJpYnV0ZXN9KTtcbn07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IENvbnZBdHRyaWJ1dGVzKTogdm9pZCA9PiB7XG4gIC8vIFJlZmVyIHRvIHRoZSBiZWxvdyBsaW5rIGZvciBhbGwgaW5wdXQgY2hlY2tzXG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9vbm54L29ubngvYmxvYi9tYWluL2RvY3MvT3BlcmF0b3JzLm1kI0NvbnZcbiAgaWYgKCFpbnB1dHMgfHwgKGlucHV0cy5sZW5ndGggIT09IDIgJiYgaW5wdXRzLmxlbmd0aCAhPT0gMykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvbnYgcmVxdWlyZXMgMiBvciAzIGlucHV0cycpO1xuICB9XG5cbiAgLy8gVE9ETyA6IE5lZWQgdG8gYWRkIHN1cHBvcnQgZm9yIG11bHRpLWRpbWVuc2lvbmFsIGNvbnZcbiAgaWYgKGlucHV0c1swXS5kaW1zLmxlbmd0aCAhPT0gNCB8fCBpbnB1dHNbMV0uZGltcy5sZW5ndGggIT09IDQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2N1cnJlbnRseSBvbmx5IHN1cHBvcnQgMi1kaW1lbnNpb25hbCBjb252Jyk7XG4gIH1cblxuICAvLyBGSUxURVJfSU5fQ0hBTk5FTCBzaG91bGQgYmUgZXF1YWwgdG8gREFUQV9DSEFOTkVMXG4gIGNvbnN0IGRhdGFDaGFubmVsID0gaW5wdXRzWzBdLmRpbXNbMV07XG4gIGNvbnN0IGZpbHRlckluQ2hhbm5lbCA9IGlucHV0c1sxXS5kaW1zWzFdICogYXR0cmlidXRlcy5ncm91cDtcbiAgaWYgKGRhdGFDaGFubmVsICE9PSBmaWx0ZXJJbkNoYW5uZWwpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZJTFRFUl9JTl9DSEFOTkVMIHNob3VsZCBiZSBlcXVhbCB0byBEQVRBX0NIQU5ORUwnKTtcbiAgfVxuXG4gIC8vIGlmIGJpYXMgaXMgcHJvdmlkZWQgaXQgc2hvdWxkIGJlIDFEIGFuZCB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIHNob3VsZCBiZSBlcXVhbCB0byB0aGUgbnVtYmVyIG9mIGZlYXR1cmUgbWFwc1xuICBpZiAoaW5wdXRzLmxlbmd0aCA9PT0gMyAmJiAoaW5wdXRzWzJdLmRpbXMubGVuZ3RoICE9PSAxIHx8IGlucHV0c1sxXS5kaW1zWzBdICE9PSBpbnB1dHNbMl0uZGltc1swXSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgYmlhcycpO1xuICB9XG5cbiAgY29uc3Qgc3BhdGlhbFJhbmsgPSBpbnB1dHNbMF0uZGltcy5sZW5ndGggLSAyO1xuICAvLyB3cm9uZyBkaWxhdGlvbnMgZGltZW5zaW9uXG4gIGlmIChhdHRyaWJ1dGVzLmRpbGF0aW9ucy5sZW5ndGggIT09IHNwYXRpYWxSYW5rKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBkaWxhdGlvbnMgc2hvdWxkIGJlICR7c3BhdGlhbFJhbmt9RGApO1xuICB9XG5cbiAgLy8gV3Jvbmcgc3RyaWRlcyBkaW1lbnNpb25cbiAgaWYgKGF0dHJpYnV0ZXMuc3RyaWRlcy5sZW5ndGggIT09IHNwYXRpYWxSYW5rKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBzdHJpZGVzIHNob3VsZCBiZSAke3NwYXRpYWxSYW5rfURgKTtcbiAgfVxuXG4gIC8vIFdyb25nIHBhZHMgZGltZW5zaW9uXG4gIGlmIChhdHRyaWJ1dGVzLnBhZHMubGVuZ3RoICE9PSBzcGF0aWFsUmFuayAqIDIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYHBhZHMgc2hvdWxkIGJlICR7c3BhdGlhbFJhbmsgKiAyfURgKTtcbiAgfVxuXG4gIC8vIGlmIGtlcm5lbFNoYXBlIGlzIHNwZWNpZmllZCwgaXQncyBkYXRhIGxlbmd0aCBtdXN0IGJlIDIgbGVzcyB0aGFuIGRpbXMgbGVuZ3RoIG9mIHRoZSB3ZWlnaHRzIHRlbnNvclxuICAvLyAodGhlIGZpcnN0IDIgZGltcyBhcmUgYmF0Y2hfc2l6ZSBhbmQgY2hhbm5lbHMpXG4gIGlmIChhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLmxlbmd0aCAhPT0gMCAmJiBhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLmxlbmd0aCAhPT0gaW5wdXRzWzFdLmRpbXMubGVuZ3RoIC0gMikge1xuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBrZXJuZWwgc2hhcGUnKTtcbiAgfVxuXG4gIC8vIFRPRE8gOiBOZWVkIHRvIGFkZCBzdXBwb3J0IGZvciBmbG9hdDY0XG4gIGlmIChpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0MzInIHx8IGlucHV0c1sxXS50eXBlICE9PSAnZmxvYXQzMicpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvbnYgaW5wdXQoWCxXKSBzaG91bGQgYmUgZmxvYXQgdGVuc29yJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzLmxlbmd0aCA9PT0gMyAmJiBpbnB1dHNbMl0udHlwZSAhPT0gJ2Zsb2F0MzInKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDb252IGlucHV0KGJpYXMpIHNob3VsZCBiZSBmbG9hdCB0ZW5zb3InKTtcbiAgfVxufTtcbiIsIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge0dyYXBofSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQge09wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb259IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7V2ViR0xJbmZlcmVuY2VIYW5kbGVyfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5cbmltcG9ydCB7dHJhbnNwb3NlLCBUcmFuc3Bvc2VBdHRyaWJ1dGVzfSBmcm9tICcuL3RyYW5zcG9zZSc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRGVwdGhUb1NwYWNlQXR0cmlidXRlcyB7XG4gIG1vZGU6ICdEQ1InfCdDUkQnO1xuICBibG9ja3NpemU6IG51bWJlcjtcbn1cblxuZXhwb3J0IGNvbnN0IGRlcHRoVG9TcGFjZTogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxEZXB0aFRvU3BhY2VBdHRyaWJ1dGVzPiA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogRGVwdGhUb1NwYWNlQXR0cmlidXRlcyk6IFRlbnNvcltdID0+IHtcbiAgICAgIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG4gICAgICBjb25zdCBibG9ja3NpemUgPSBhdHRyaWJ1dGVzLmJsb2Nrc2l6ZTtcbiAgICAgIGNvbnN0IGJsb2Nrc2l6ZVNxciA9IGJsb2Nrc2l6ZSAqIGJsb2Nrc2l6ZTtcbiAgICAgIGNvbnN0IHRyYW5zcG9zZVBlcm0gPSBhdHRyaWJ1dGVzLm1vZGUgPT09ICdEQ1InID8gWzAsIDMsIDQsIDEsIDUsIDJdIDogWzAsIDEsIDQsIDIsIDUsIDNdO1xuICAgICAgY29uc3QgZmlyc3RSZXNoYXBlU2hhcGUgPSBhdHRyaWJ1dGVzLm1vZGUgPT09ICdEQ1InID9cbiAgICAgICAgICBbXG4gICAgICAgICAgICBpbnB1dHNbMF0uZGltc1swXSwgYmxvY2tzaXplLCBibG9ja3NpemUsIGlucHV0c1swXS5kaW1zWzFdIC8gYmxvY2tzaXplU3FyLCBpbnB1dHNbMF0uZGltc1syXSxcbiAgICAgICAgICAgIGlucHV0c1swXS5kaW1zWzNdXG4gICAgICAgICAgXSA6XG4gICAgICAgICAgW1xuICAgICAgICAgICAgaW5wdXRzWzBdLmRpbXNbMF0sIGlucHV0c1swXS5kaW1zWzFdIC8gYmxvY2tzaXplU3FyLCBibG9ja3NpemUsIGJsb2Nrc2l6ZSwgaW5wdXRzWzBdLmRpbXNbMl0sXG4gICAgICAgICAgICBpbnB1dHNbMF0uZGltc1szXVxuICAgICAgICAgIF07XG5cbiAgICAgIC8vIGNvbnN0IHRyYW5zcG9zZSA9IG5ldyBXZWJHTFRyYW5zcG9zZSgpO1xuICAgICAgLy8gY29uc3QgYXR0cmlidXRlcyA9IG5ldyBBdHRyaWJ1dGUodW5kZWZpbmVkKTtcbiAgICAgIC8vIGF0dHJpYnV0ZXMuc2V0KCdwZXJtJywgJ2ludHMnLCB0cmFuc3Bvc2VQZXJtKTtcbiAgICAgIC8vIHRyYW5zcG9zZS5pbml0aWFsaXplKGF0dHJpYnV0ZXMpO1xuXG4gICAgICAvLyBGaXJzdCByZXNoYXBlXG4gICAgICBjb25zdCBmaXJzdFJlc2hhcGVkVGVuc29yID0gaW5mZXJlbmNlSGFuZGxlci5yZXNoYXBlVW5wYWNrZWQoaW5wdXRzWzBdLCBmaXJzdFJlc2hhcGVTaGFwZSk7XG5cbiAgICAgIC8vIHRyYW5zcG9zZVxuICAgICAgY29uc3QgdHJhbnNwb3NlQXR0cmlidXRlczogVHJhbnNwb3NlQXR0cmlidXRlcyA9IHtwZXJtOiB0cmFuc3Bvc2VQZXJtLCBjYWNoZUtleTogYCR7dHJhbnNwb3NlUGVybX1gfTtcbiAgICAgIGNvbnN0IFt0cmFuc3Bvc2VPdXRwdXRdID0gdHJhbnNwb3NlKGluZmVyZW5jZUhhbmRsZXIsIFtmaXJzdFJlc2hhcGVkVGVuc29yXSwgdHJhbnNwb3NlQXR0cmlidXRlcyk7XG5cbiAgICAgIC8vIFNlY29uZCByZXNoYXBlXG4gICAgICBjb25zdCBzZWNvbmRSZXNoYXBlU2hhcGUgPSBbXG4gICAgICAgIGlucHV0c1swXS5kaW1zWzBdLCBpbnB1dHNbMF0uZGltc1sxXSAvIGJsb2Nrc2l6ZVNxciwgaW5wdXRzWzBdLmRpbXNbMl0gKiBibG9ja3NpemUsXG4gICAgICAgIGlucHV0c1swXS5kaW1zWzNdICogYmxvY2tzaXplXG4gICAgICBdO1xuICAgICAgY29uc3QgcmVzdWx0ID0gaW5mZXJlbmNlSGFuZGxlci5yZXNoYXBlVW5wYWNrZWQodHJhbnNwb3NlT3V0cHV0LCBzZWNvbmRSZXNoYXBlU2hhcGUpO1xuICAgICAgcmV0dXJuIFtyZXN1bHRdO1xuICAgIH07XG5cbmV4cG9ydCBjb25zdCBwYXJzZURlcHRoVG9TcGFjZUF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248RGVwdGhUb1NwYWNlQXR0cmlidXRlcz4gPVxuICAgIChub2RlOiBHcmFwaC5Ob2RlKTogRGVwdGhUb1NwYWNlQXR0cmlidXRlcyA9PiB7XG4gICAgICAvLyBwcm9jZXNzaW5nIG5vZGUgYXR0cmlidXRlc1xuICAgICAgY29uc3QgYmxvY2tzaXplID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludCgnYmxvY2tzaXplJyk7XG4gICAgICBpZiAoYmxvY2tzaXplIDwgMSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGJsb2Nrc2l6ZSBtdXN0IGJlID49IDEsIGJ1dCBnb3QgOiAke2Jsb2Nrc2l6ZX0gZm9yIERlcHRoVG9TcGFjZWApO1xuICAgICAgfVxuICAgICAgY29uc3QgbW9kZSA9IG5vZGUuYXR0cmlidXRlcy5nZXRTdHJpbmcoJ21vZGUnLCAnRENSJyk7XG4gICAgICBpZiAobW9kZSAhPT0gJ0RDUicgJiYgbW9kZSAhPT0gJ0NSRCcpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bnJlY29nbml6ZWQgbW9kZTogJHttb2RlfSBmb3IgRGVwdGhUb1NwYWNlYCk7XG4gICAgICB9XG4gICAgICByZXR1cm4ge21vZGUsIGJsb2Nrc2l6ZX07XG4gICAgfTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoaW5wdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgRGVwdGhUb1NwYWNlIGV4cGVjdCAxIGlucHV0cywgYnV0IGdvdCAke2lucHV0cy5sZW5ndGh9YCk7XG4gIH1cblxuICAvLyBJbnB1dCBoYXMgdG8gYmUgYSA0LUQgdGVuc29yXG4gIC8vIFRPRE86IFN1cHBvcnQgc3RyaW5nIGRlcHRoLXRvLXNwYWNlLlxuICBpZiAoaW5wdXRzWzBdLnR5cGUgPT09ICdzdHJpbmcnIHx8IGlucHV0c1swXS5kaW1zLmxlbmd0aCAhPT0gNCkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0RlcHRoVG9TcGFjZSBpbnB1dCBzaG91bGQgYmUgYSA0LUQgbnVtZXJpYyB0ZW5zb3InKTtcbiAgfVxufTtcbiIsIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7U2hhcGVVdGlsfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7Z2V0R2xzbH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHtXZWJHTEluZmVyZW5jZUhhbmRsZXJ9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7UHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlfSBmcm9tICcuLi90eXBlcyc7XG5cbmltcG9ydCB7Z2V0QWN0aXZhdGlvblNuaXBwZXQsIEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXN9IGZyb20gJy4vZnVzZS11dGlscyc7XG5pbXBvcnQge2NhbGN1bGF0ZUltMkNvbERpbXN9IGZyb20gJy4vaW0yY29sJztcblxuY29uc3QgY3JlYXRlRG90UHJvZHVjdFByb2dyYW1NZXRhZGF0YSA9IChoYXNCaWFzOiBib29sZWFuLCBhdHRyaWJ1dGVzOiBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzKSA9PiAoe1xuICBuYW1lOiAnQ29udkRvdFByb2R1Y3QnLFxuICBpbnB1dE5hbWVzOiBoYXNCaWFzID8gWydJbTJDb2wnLCAnSycsICdCJ10gOiBbJ0ltMkNvbCcsICdLJ10sXG4gIGlucHV0VHlwZXM6IGhhc0JpYXMgPyBbVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnBhY2tlZExhc3REaW1lbnNpb24sIFRleHR1cmVUeXBlLnVucGFja2VkXSA6XG4gICAgICAgICAgICAgICAgICAgICAgICBbVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnBhY2tlZExhc3REaW1lbnNpb25dLFxuICBjYWNoZUtleTogYXR0cmlidXRlcy5hY3RpdmF0aW9uQ2FjaGVLZXlcbn0pO1xuXG5jb25zdCBjcmVhdGVEb3RQcm9kdWN0UHJvZ3JhbUluZm8gPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsIGlucHV0czogcmVhZG9ubHkgVGVuc29yW10sXG4gICAgIG91dHB1dFNoYXBlOiBudW1iZXJbXSwgYXR0cmlidXRlczogSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyk6IFByb2dyYW1JbmZvID0+IHtcbiAgICAgIGNvbnN0IHhzaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICAgICAgY29uc3Qga3NoYXBlID0gaW5wdXRzWzFdLmRpbXM7XG4gICAgICBjb25zdCBhZGp1c3RlZEtlcm5lbFNoYXBlID0gW2tzaGFwZVswXSwgTWF0aC5jZWlsKCh4c2hhcGVbMV0gKiBrc2hhcGVbMl0gKiBrc2hhcGVbM10pIC8gNCldO1xuICAgICAgY29uc3QgaW0yY29sU2hhcGUgPSBjYWxjdWxhdGVJbTJDb2xEaW1zKHhzaGFwZSwga3NoYXBlLCBvdXRwdXRTaGFwZSk7XG4gICAgICBjb25zdCBba1dpZHRoLCBrSGVpZ2h0XSA9XG4gICAgICAgICAgaW5mZXJlbmNlSGFuZGxlci5jYWxjdWxhdGVUZXh0dXJlV2lkdGhBbmRIZWlnaHQoYWRqdXN0ZWRLZXJuZWxTaGFwZSwgVGV4dHVyZVR5cGUucGFja2VkTGFzdERpbWVuc2lvbik7XG5cbiAgICAgIGNvbnN0IGltMmNvbFN0cmlkZXMgPSBTaGFwZVV0aWwuY29tcHV0ZVN0cmlkZXMoaW0yY29sU2hhcGUpO1xuICAgICAgY29uc3QgW2ltMmNvbFdpZHRoLCBpbTJjb2xIZWlnaHRdID1cbiAgICAgICAgICBpbmZlcmVuY2VIYW5kbGVyLmNhbGN1bGF0ZVRleHR1cmVXaWR0aEFuZEhlaWdodChpbTJjb2xTaGFwZSwgVGV4dHVyZVR5cGUucGFja2VkTGFzdERpbWVuc2lvbik7XG4gICAgICBjb25zdCByYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuXG4gICAgICBjb25zdCBpbml0VmFsdWUgPSAoaW5wdXRzLmxlbmd0aCA8IDMpID8gJzAuMCcgOiAnX0IoYiknO1xuICAgICAgY29uc3Qgc2hhcmVkRGltID0gTWF0aC5jZWlsKHhzaGFwZVsxXSAqIGtzaGFwZVsyXSAqIGtzaGFwZVszXSAvIDQpO1xuICAgICAgY29uc3Qge2FjdGl2YXRpb25GdW5jdGlvbiwgYXBwbHlBY3RpdmF0aW9ufSA9IGdldEFjdGl2YXRpb25TbmlwcGV0KGF0dHJpYnV0ZXMpO1xuICAgICAgY29uc3QgZ2xzbCA9IGdldEdsc2woaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICAgICAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuJHthY3RpdmF0aW9uRnVuY3Rpb259XG5mbG9hdCBwcm9jZXNzKGludCBpbmRpY2VzWyR7cmFua31dKSB7XG4gIGludCBiWzFdO1xuICBiWzBdID0gaW5kaWNlc1sxXTtcbiAgaW50IGltMmNvbFs0XTtcbiAgaW0yY29sWzBdID0gaW5kaWNlc1swXTtcbiAgaW0yY29sWzFdID0gaW5kaWNlc1syXTtcbiAgaW0yY29sWzJdID0gaW5kaWNlc1szXTtcbiAgaW50IGltMmNvbE9mZnNldCA9IGltMmNvbFswXSAqICR7aW0yY29sU3RyaWRlc1swXX0gKyBpbTJjb2xbMV0gKiAke2ltMmNvbFN0cmlkZXNbMV19ICsgaW0yY29sWzJdICogJHtcbiAgICAgICAgICBpbTJjb2xTdHJpZGVzWzJdfTtcbiAgaW50IGtlcm5lbE9mZnNldCA9IGluZGljZXNbMV0gKiAke2FkanVzdGVkS2VybmVsU2hhcGVbMV19O1xuICBmbG9hdCB2YWx1ZSA9ICR7aW5pdFZhbHVlfTtcbiAgZm9yIChpbnQgaSA9IDA7IGkgPCAke3NoYXJlZERpbX07ICsraSkge1xuICAgIHZlYzIgaW0yY29sQ29vcmRzID0gb2Zmc2V0VG9Db29yZHMoaW0yY29sT2Zmc2V0LCAke2ltMmNvbFdpZHRofSwgJHtpbTJjb2xIZWlnaHR9KTtcbiAgICB2ZWMyIGtlcm5lbENvb3JkcyA9IG9mZnNldFRvQ29vcmRzKGtlcm5lbE9mZnNldCwgJHtrV2lkdGh9LCAke2tIZWlnaHR9KTtcbiAgICB2YWx1ZSArPSBkb3QoJHtnbHNsLnRleHR1cmUyRH0oSW0yQ29sLCBpbTJjb2xDb29yZHMpLCAke2dsc2wudGV4dHVyZTJEfShLLCBrZXJuZWxDb29yZHMpKTtcbiAgICArK2ltMmNvbE9mZnNldDtcbiAgICArK2tlcm5lbE9mZnNldDtcbiAgfVxuICAke2FwcGx5QWN0aXZhdGlvbn1cbiAgcmV0dXJuIHZhbHVlO1xufWA7XG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5tZXRhZGF0YSxcbiAgICAgICAgb3V0cHV0OiB7ZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWR9LFxuICAgICAgICBzaGFkZXJTb3VyY2VcbiAgICAgIH07XG4gICAgfTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZURvdFByb2R1Y3RQcm9ncmFtSW5mb0xvYWRlciA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiByZWFkb25seSBUZW5zb3JbXSwgb3V0cHV0U2hhcGU6IG51bWJlcltdLFxuICAgICBhdHRyaWJ1dGVzOiBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzKTogUHJvZ3JhbUluZm9Mb2FkZXIgPT4ge1xuICAgICAgY29uc3QgbWV0YWRhdGEgPSBjcmVhdGVEb3RQcm9kdWN0UHJvZ3JhbU1ldGFkYXRhKGlucHV0cy5sZW5ndGggPiAyLCBhdHRyaWJ1dGVzKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLm1ldGFkYXRhLFxuICAgICAgICBnZXQ6ICgpID0+IGNyZWF0ZURvdFByb2R1Y3RQcm9ncmFtSW5mbyhpbmZlcmVuY2VIYW5kbGVyLCBtZXRhZGF0YSwgaW5wdXRzLCBvdXRwdXRTaGFwZSwgYXR0cmlidXRlcylcbiAgICAgIH07XG4gICAgfTtcbiIsIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge0dyYXBofSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQge09wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb259IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7U2hhcGVVdGlsfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7V2ViR0xJbmZlcmVuY2VIYW5kbGVyfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5cbmV4cG9ydCBjb25zdCBmbGF0dGVuOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPG51bWJlcj4gPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIGF4aXM6IG51bWJlcik6IFRlbnNvcltdID0+IHtcbiAgICAgIHZhbGlkYXRlSW5wdXRzKGlucHV0cywgYXhpcyk7XG5cbiAgICAgIGNvbnN0IG91dHB1dERpbXMgPSBTaGFwZVV0aWwuZmxhdHRlblNoYXBlKGlucHV0c1swXS5kaW1zLCBheGlzKTtcbiAgICAgIHJldHVybiBbaW5mZXJlbmNlSGFuZGxlci5yZXNoYXBlVW5wYWNrZWQoaW5wdXRzWzBdLCBvdXRwdXREaW1zKV07XG4gICAgfTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlRmxhdHRlbkF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248bnVtYmVyPiA9IChub2RlOiBHcmFwaC5Ob2RlKTogbnVtYmVyID0+XG4gICAgbm9kZS5hdHRyaWJ1dGVzLmdldEludCgnYXhpcycsIDEpOyAgLy8gZGVmYXVsdCBheGlzIGlzIDFcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSwgYXhpczogbnVtYmVyKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZsYXR0ZW4gcmVxdWlyZXMgMSBpbnB1dC4nKTtcbiAgfVxuXG4gIGNvbnN0IHIgPSBpbnB1dHNbMF0uZGltcy5sZW5ndGg7XG4gIGlmIChyID09PSAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdzY2FsYXIgdGVuc29yIGlzIG5vdCBzdXBwb3J0ZWQuJyk7XG4gIH1cblxuICBpZiAoYXhpcyA8IC1yIHx8IGF4aXMgPiByKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGF4aXMnKTtcbiAgfVxuXG4gIC8vIFRPRE86IFN1cHBvcnQgc3RyaW5nIHR5cGVcbiAgaWYgKGlucHV0c1swXS50eXBlID09PSAnc3RyaW5nJykge1xuICAgIHRocm93IG5ldyBFcnJvcignc3RyaW5nIHRlbnNvciBpcyBub3Qgc3VwcG9ydGVkLicpO1xuICB9XG59OyIsIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge0F0dHJpYnV0ZX0gZnJvbSAnLi4vLi4vLi4vYXR0cmlidXRlJztcbmltcG9ydCB7TUFYX0NMSVAsIE1JTl9DTElQfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7R2xzbFZhbHVlRnVuY3Rpb259IGZyb20gJy4uL2dsc2wtZGVmaW5pdGlvbnMnO1xuXG5pbXBvcnQge2dsc2xDbGlwLCBnbHNsUmVsdSwgZ2xzbFNpZ21vaWR9IGZyb20gJy4vdW5hcnktb3AnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMge1xuICByZWFkb25seSBhY3RpdmF0aW9uOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGNsaXBNaW4/OiBudW1iZXI7XG4gIHJlYWRvbmx5IGNsaXBNYXg/OiBudW1iZXI7XG4gIHJlYWRvbmx5IGFjdGl2YXRpb25DYWNoZUtleTogc3RyaW5nO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0QWN0aXZhdGlvblNuaXBwZXQoYXR0cmlidXRlczogSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcykge1xuICBsZXQgZnVuYzogR2xzbFZhbHVlRnVuY3Rpb247XG4gIHN3aXRjaCAoYXR0cmlidXRlcy5hY3RpdmF0aW9uKSB7XG4gICAgY2FzZSAnUmVsdSc6XG4gICAgICBmdW5jID0gZ2xzbFJlbHUoKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ1NpZ21vaWQnOlxuICAgICAgZnVuYyA9IGdsc2xTaWdtb2lkKCk7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdDbGlwJzpcbiAgICAgIGZ1bmMgPSBnbHNsQ2xpcChhdHRyaWJ1dGVzLmNsaXBNaW4hLCBhdHRyaWJ1dGVzLmNsaXBNYXghKTtcbiAgICAgIGJyZWFrO1xuICAgIC8vIFRPRE86IGFkZGluZyBvdGhlciBhY3RpdmF0aW9ucyB0aGF0IGNhbiBiZSBmdXNlZC5cbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIHthY3RpdmF0aW9uRnVuY3Rpb246ICcnLCBhcHBseUFjdGl2YXRpb246ICcnfTtcbiAgfVxuXG4gIGNvbnN0IGFjdGl2YXRpb25OYW1lID0gZnVuYy5uYW1lO1xuICBjb25zdCBhY3RpdmF0aW9uRnVuY3Rpb24gPSBmdW5jLmJvZHk7XG4gIGNvbnN0IGFwcGx5QWN0aXZhdGlvbiA9IGB2YWx1ZSA9ICR7YWN0aXZhdGlvbk5hbWV9Xyh2YWx1ZSk7YDtcbiAgcmV0dXJuIHthY3RpdmF0aW9uRnVuY3Rpb24sIGFwcGx5QWN0aXZhdGlvbn07XG59XG5cbmV4cG9ydCBjb25zdCBwYXJzZUludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMgPSAoYXR0cmlidXRlczogQXR0cmlidXRlKTogSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyA9PiB7XG4gIGNvbnN0IGFjdGl2YXRpb24gPSBhdHRyaWJ1dGVzLmdldFN0cmluZygnYWN0aXZhdGlvbicsICcnKTtcblxuICBpZiAoYWN0aXZhdGlvbiA9PT0gJ0NsaXAnKSB7XG4gICAgY29uc3QgW2NsaXBNaW4sIGNsaXBNYXhdID0gYXR0cmlidXRlcy5nZXRGbG9hdHMoJ2FjdGl2YXRpb25fcGFyYW1zJywgW01JTl9DTElQLCBNQVhfQ0xJUF0pO1xuICAgIHJldHVybiB7YWN0aXZhdGlvbiwgY2xpcE1heCwgY2xpcE1pbiwgYWN0aXZhdGlvbkNhY2hlS2V5OiBgJHthY3RpdmF0aW9ufToke2NsaXBNaW59LCR7Y2xpcE1heH1gfTtcbiAgfVxuICByZXR1cm4ge2FjdGl2YXRpb24sIGFjdGl2YXRpb25DYWNoZUtleTogYWN0aXZhdGlvbn07XG59O1xuIiwiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7QXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXl9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQge0dyYXBofSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQge05VTUJFUl9UWVBFUywgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbn0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7VGVuc29yfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHtTaGFwZVV0aWx9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHtXZWJHTEluZmVyZW5jZUhhbmRsZXJ9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7UHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlfSBmcm9tICcuLi90eXBlcyc7XG5cbmludGVyZmFjZSBHYXRoZXJBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgYXhpczogbnVtYmVyO1xufVxuXG5leHBvcnQgY29uc3QgZ2F0aGVyOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPEdhdGhlckF0dHJpYnV0ZXM+ID1cbiAgICAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBHYXRoZXJBdHRyaWJ1dGVzKTogVGVuc29yW10gPT4ge1xuICAgICAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzLCBhdHRyaWJ1dGVzLmF4aXMpO1xuICAgICAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oY3JlYXRlR2F0aGVyUHJvZ3JhbUluZm9Mb2FkZXIoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzKSwgaW5wdXRzKTtcbiAgICAgIHJldHVybiBbb3V0cHV0XTtcbiAgICB9O1xuXG5leHBvcnQgY29uc3QgcGFyc2VHYXRoZXJBdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPEdhdGhlckF0dHJpYnV0ZXM+ID0gKG5vZGU6IEdyYXBoLk5vZGUpOiBHYXRoZXJBdHRyaWJ1dGVzID0+XG4gICAgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHtheGlzOiBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50KCdheGlzJywgMCl9KTtcblxuY29uc3QgZ2F0aGVyUHJvZ3JhbU1ldGFkYXRhID0ge1xuICBuYW1lOiAnR2F0aGVyJyxcbiAgaW5wdXROYW1lczogWydBJywgJ0InXSxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG59O1xuXG5jb25zdCBjcmVhdGVHYXRoZXJQcm9ncmFtSW5mbyA9XG4gICAgKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgbWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSwgaW5wdXRzOiBUZW5zb3JbXSwgYXhpczogbnVtYmVyKTogUHJvZ3JhbUluZm8gPT4ge1xuICAgICAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zLnNsaWNlKCk7XG4gICAgICBjb25zdCBpbmRleERhdGFTaGFwZSA9IGlucHV0c1sxXS5kaW1zLnNsaWNlKCk7XG4gICAgICBjb25zdCBvdXRwdXRTaGFwZSA9IG5ldyBBcnJheShpbnB1dFNoYXBlLmxlbmd0aCArIGluZGV4RGF0YVNoYXBlLmxlbmd0aCAtIDEpO1xuXG4gICAgICBheGlzID0gU2hhcGVVdGlsLm5vcm1hbGl6ZUF4aXMoYXhpcywgaW5wdXRTaGFwZS5sZW5ndGgpO1xuICAgICAgY29uc3QgaW5kZXhDb3B5T3BzOiBzdHJpbmdbXSA9IFtdO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvdXRwdXRTaGFwZS5sZW5ndGg7IGkrKykge1xuICAgICAgICAvLyBvdXRwdXRTaGFwZSBpcyBkaXZpZGVkIGludG8gdGhyZWUgcGFydHM6IEEsIEIsIENcbiAgICAgICAgLy8gfDAgICAgICAgIGF4aXN8ICBheGlzICsgaW5kZXhEYXRhU2hhcGUubGVuZ3RoIHwgICAgICAgICAgZW5kfFxuICAgICAgICAvLyB8ICAgICBBICAgICAgIHwgICAgICAgICAgICAgQiAgICAgICAgICAgICAgICAgfCAgICAgIEMgICAgICB8XG4gICAgICAgIC8vXG4gICAgICAgIC8vIGlucHV0SWR4OiBbQSwgaW5wdXRzWzFdW0JdLCBDXVxuICAgICAgICBpZiAoaSA8IGF4aXMpIHsgIC8vIEFcbiAgICAgICAgICBvdXRwdXRTaGFwZVtpXSA9IGlucHV0U2hhcGVbaV07XG4gICAgICAgICAgaW5kZXhDb3B5T3BzLnB1c2goYGlucHV0SWR4WyR7aX1dID0gb3V0cHV0SWR4WyR7aX1dO2ApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChpIDwgYXhpcyArIGluZGV4RGF0YVNoYXBlLmxlbmd0aCkgeyAgLy8gQlxuICAgICAgICAgICAgb3V0cHV0U2hhcGVbaV0gPSBpbmRleERhdGFTaGFwZVtpIC0gYXhpc107XG4gICAgICAgICAgICBpbmRleENvcHlPcHMucHVzaChgaW5kZXhEYXRhSWR4WyR7aSAtIGF4aXN9XSA9IG91dHB1dElkeFske2l9XTtgKTtcbiAgICAgICAgICB9IGVsc2UgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBDXG4gICAgICAgICAgICBvdXRwdXRTaGFwZVtpXSA9IGlucHV0U2hhcGVbaSAtIGluZGV4RGF0YVNoYXBlLmxlbmd0aCArIDFdOyAgLy8gc2tpcCAxIGZvciBheGlzXG4gICAgICAgICAgICBpbmRleENvcHlPcHMucHVzaChgaW5wdXRJZHhbJHtpIC0gaW5kZXhEYXRhU2hhcGUubGVuZ3RoICsgMX1dID0gb3V0cHV0SWR4WyR7aX1dO2ApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCBvcmFuayA9IG91dHB1dFNoYXBlLmxlbmd0aCB8fCAxO1xuICAgICAgY29uc3QgaXJhbmsgPSBpbnB1dFNoYXBlLmxlbmd0aDtcbiAgICAgIGNvbnN0IGlEcmFuayA9IGluZGV4RGF0YVNoYXBlLmxlbmd0aCB8fCAxO1xuICAgICAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgZmxvYXQgcHJvY2VzcyhpbnQgb3V0cHV0SWR4WyR7b3Jhbmt9XSkge1xuICAgICAgICBpbnQgaW5wdXRJZHhbJHtpcmFua31dO1xuICAgICAgICBpbnQgaW5kZXhEYXRhSWR4WyR7aURyYW5rfV07XG4gICAgICAgIGluZGV4RGF0YUlkeFswXSA9IDA7XG4gICAgICAgICR7aW5kZXhDb3B5T3BzLmpvaW4oJ1xcbiAgICAgICAgJyl9XG4gICAgICAgIGludCBpZHggPSBpbnQoX0IoaW5kZXhEYXRhSWR4KSk7XG4gICAgICAgIGlucHV0SWR4WyR7YXhpc31dID0gaWR4IDwgMCA/IGlkeCArICR7aW5wdXRTaGFwZVtheGlzXX0gOiBpZHg7XG4gICAgICAgIHJldHVybiBfQShpbnB1dElkeCk7XG4gICAgICB9YDtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLm1ldGFkYXRhLFxuICAgICAgICBvdXRwdXQ6IHtkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXRzWzBdLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZH0sXG4gICAgICAgIHNoYWRlclNvdXJjZVxuICAgICAgfTtcbiAgICB9O1xuXG5jb25zdCBjcmVhdGVHYXRoZXJQcm9ncmFtSW5mb0xvYWRlciA9XG4gICAgKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogR2F0aGVyQXR0cmlidXRlcyk6IFByb2dyYW1JbmZvTG9hZGVyID0+IHtcbiAgICAgIGNvbnN0IG1ldGFkYXRhID0gey4uLmdhdGhlclByb2dyYW1NZXRhZGF0YSwgY2FjaGVIaW50OiBhdHRyaWJ1dGVzLmNhY2hlS2V5fTtcbiAgICAgIHJldHVybiB7Li4ubWV0YWRhdGEsIGdldDogKCkgPT4gY3JlYXRlR2F0aGVyUHJvZ3JhbUluZm8oaGFuZGxlciwgbWV0YWRhdGEsIGlucHV0cywgYXR0cmlidXRlcy5heGlzKX07XG4gICAgfTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSwgYXhpczogbnVtYmVyKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0dhdGhlciByZXF1aXJlcyAyIGlucHV0cy4nKTtcbiAgfVxuICBjb25zdCB0ZW5zb3JSYW5rID0gaW5wdXRzWzBdLmRpbXMubGVuZ3RoO1xuICBpZiAodGVuc29yUmFuayA8IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgc2hhcGUuJyk7XG4gIH1cbiAgaWYgKGF4aXMgPCAtdGVuc29yUmFuayB8fCBheGlzID4gdGVuc29yUmFuayAtIDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgYXhpcy4nKTtcbiAgfVxuICBpZiAoTlVNQkVSX1RZUEVTLmluZGV4T2YoaW5wdXRzWzBdLnR5cGUpID09PSAtMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbiAgaWYgKGlucHV0c1sxXS50eXBlICE9PSAnaW50MzInICYmIGlucHV0c1sxXS50eXBlICE9PSAnaW50MTYnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxufTtcbiIsIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge0F0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5fSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHtHcmFwaH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHtPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9ufSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHtUZW5zb3J9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQge0dlbW1VdGlsfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7V2ViR0xJbmZlcmVuY2VIYW5kbGVyfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQge1Byb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgUHJvZ3JhbU1ldGFkYXRhLCBUZXh0dXJlVHlwZX0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEdlbW1BdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgdHJhbnNBOiBib29sZWFuO1xuICB0cmFuc0I6IGJvb2xlYW47XG4gIGFscGhhOiBudW1iZXI7XG4gIGJldGE6IG51bWJlcjtcbiAgaXNPcHRpb25hbEM6IGJvb2xlYW47ICAvLyBpbiBvcHNldCAxMSwgQyBiZWNvbWVzIG9wdGlvbmFsXG59XG5cbmV4cG9ydCBjb25zdCBnZW1tOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPEdlbW1BdHRyaWJ1dGVzPiA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogR2VtbUF0dHJpYnV0ZXMpOiBUZW5zb3JbXSA9PiB7XG4gICAgICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMsIGF0dHJpYnV0ZXMpO1xuICAgICAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oY3JlYXRlR2VtbVByb2dyYW1JbmZvTG9hZGVyKGlucHV0cywgYXR0cmlidXRlcyksIGlucHV0cyk7XG4gICAgICByZXR1cm4gW291dHB1dF07XG4gICAgfTtcblxuY29uc3QgcGFyc2VHZW1tQXR0cmlidXRlcyA9IChub2RlOiBHcmFwaC5Ob2RlLCBpc09wdGlvbmFsQzogYm9vbGVhbik6IEdlbW1BdHRyaWJ1dGVzID0+IHtcbiAgY29uc3QgdHJhbnNBID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludCgndHJhbnNBJywgMCkgIT09IDA7XG4gIGNvbnN0IHRyYW5zQiA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ3RyYW5zQicsIDApICE9PSAwO1xuICBjb25zdCBhbHBoYSA9IG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdCgnYWxwaGEnLCAxLjApO1xuICBjb25zdCBiZXRhID0gbm9kZS5hdHRyaWJ1dGVzLmdldEZsb2F0KCdiZXRhJywgMS4wKTtcbiAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7dHJhbnNBLCB0cmFuc0IsIGFscGhhLCBiZXRhLCBpc09wdGlvbmFsQ30pO1xufTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlR2VtbUF0dHJpYnV0ZXNWNzogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxHZW1tQXR0cmlidXRlcz4gPSAobm9kZTogR3JhcGguTm9kZSk6IEdlbW1BdHRyaWJ1dGVzID0+XG4gICAgcGFyc2VHZW1tQXR0cmlidXRlcyhub2RlLCBmYWxzZSk7XG5cbmV4cG9ydCBjb25zdCBwYXJzZUdlbW1BdHRyaWJ1dGVzVjExOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPEdlbW1BdHRyaWJ1dGVzPiA9IChub2RlOiBHcmFwaC5Ob2RlKTogR2VtbUF0dHJpYnV0ZXMgPT5cbiAgICBwYXJzZUdlbW1BdHRyaWJ1dGVzKG5vZGUsIHRydWUpO1xuXG5jb25zdCBjcmVhdGVHZW1tUHJvZ3JhbUluZm9Mb2FkZXIgPSAoaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogR2VtbUF0dHJpYnV0ZXMpOiBQcm9ncmFtSW5mb0xvYWRlciA9PiB7XG4gIGNvbnN0IG1ldGFkYXRhID0ge1xuICAgIG5hbWU6ICdHZW1tJyxcbiAgICBpbnB1dE5hbWVzOiBpbnB1dHMubGVuZ3RoID09PSAzID8gWydBJywgJ0InLCAnQyddIDogWydBJywgJ0InXSxcbiAgICBpbnB1dFR5cGVzOiBpbnB1dHMubGVuZ3RoID09PSAzID8gW1RleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUudW5wYWNrZWRdIDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW1RleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG4gICAga2V5OiBhdHRyaWJ1dGVzLmNhY2hlS2V5XG4gIH07XG5cbiAgcmV0dXJuIHsuLi5tZXRhZGF0YSwgZ2V0OiAoKSA9PiBjcmVhdGVHZW1tUHJvZ3JhbUluZm8obWV0YWRhdGEsIGlucHV0cywgYXR0cmlidXRlcyl9O1xufTtcblxuY29uc3QgY3JlYXRlR2VtbVByb2dyYW1JbmZvID1cbiAgICAobWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSwgaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogR2VtbUF0dHJpYnV0ZXMpOiBQcm9ncmFtSW5mbyA9PiB7XG4gICAgICBjb25zdCBhU2hhcGUgPSBpbnB1dHNbMF0uZGltcy5zbGljZSgpO1xuICAgICAgY29uc3QgYlNoYXBlID0gaW5wdXRzWzFdLmRpbXMuc2xpY2UoKTtcbiAgICAgIGNvbnN0IFtNLCBOXSA9IEdlbW1VdGlsLmdldFNoYXBlT2ZHZW1tUmVzdWx0KFxuICAgICAgICAgIGFTaGFwZSwgYXR0cmlidXRlcy50cmFuc0EsIGJTaGFwZSwgYXR0cmlidXRlcy50cmFuc0IsIGlucHV0cy5sZW5ndGggPT09IDMgPyBpbnB1dHNbMl0uZGltcyA6IHVuZGVmaW5lZCk7XG4gICAgICBjb25zdCBvdXRwdXRTaGFwZSA9IFtNLCBOXTtcbiAgICAgIGlmICghb3V0cHV0U2hhcGUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW5cXCd0IHVzZSBnZW1tIG9uIHRoZSBnaXZlbiB0ZW5zb3JzJyk7XG4gICAgICB9XG4gICAgICBsZXQgc2hhcmVkRGltID0gYVNoYXBlW2FTaGFwZS5sZW5ndGggLSAxXTtcbiAgICAgIGxldCBsaW5lID0gJyc7XG4gICAgICBpZiAoYXR0cmlidXRlcy50cmFuc0EpIHtcbiAgICAgICAgc2hhcmVkRGltID0gYVNoYXBlWzBdO1xuICAgICAgfVxuICAgICAgaWYgKGF0dHJpYnV0ZXMudHJhbnNBICYmIGF0dHJpYnV0ZXMudHJhbnNCKSB7XG4gICAgICAgIGxpbmUgPSAndmFsdWUgKz0gX0FfVChhKSAqIF9CX1QoYik7JztcbiAgICAgIH0gZWxzZSBpZiAoYXR0cmlidXRlcy50cmFuc0EgJiYgIWF0dHJpYnV0ZXMudHJhbnNCKSB7XG4gICAgICAgIGxpbmUgPSAndmFsdWUgKz0gX0FfVChhKSAqIF9CKGIpOyc7XG4gICAgICB9IGVsc2UgaWYgKCFhdHRyaWJ1dGVzLnRyYW5zQSAmJiBhdHRyaWJ1dGVzLnRyYW5zQikge1xuICAgICAgICBsaW5lID0gJ3ZhbHVlICs9IF9BKGEpICogX0JfVChiKTsnO1xuICAgICAgfSBlbHNlIGlmICghYXR0cmlidXRlcy50cmFuc0EgJiYgIWF0dHJpYnV0ZXMudHJhbnNCKSB7XG4gICAgICAgIGxpbmUgPSAndmFsdWUgKz0gX0EoYSkgKiBfQihiKTsnO1xuICAgICAgfVxuICAgICAgY29uc3QgcmFuayA9IG91dHB1dFNoYXBlLmxlbmd0aDtcbiAgICAgIGNvbnN0IGRlY2xhcmVDID0gaW5wdXRzLmxlbmd0aCA9PT0gMyA/IGBpbnQgY1ske2lucHV0c1syXS5kaW1zLmxlbmd0aH1dO2AgOiAnJztcbiAgICAgIGNvbnN0IGJyb2FkY2FzdEMgPSBpbnB1dHMubGVuZ3RoID09PSAzID8gJ2JjYXN0SW5kaWNlc19DKGluZGljZXMsIGMpOycgOiAnJztcbiAgICAgIGNvbnN0IGNhbGN1bGF0ZUMgPSBpbnB1dHMubGVuZ3RoID09PSAzID8gJ3ZhbHVlICs9IGJldGEgKiBfQyhjKTsnIDogJyc7XG4gICAgICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICBmbG9hdCBwcm9jZXNzKGludCBpbmRpY2VzWyR7cmFua31dKSB7XG4gICAgICAgICAgaW50IGFbJHtyYW5rfV07XG4gICAgICAgICAgaW50IGJbJHtyYW5rfV07XG4gICAgICAgICAgJHtkZWNsYXJlQ31cblxuICAgICAgICAgIGNvcHlWZWMoaW5kaWNlcywgYSk7XG4gICAgICAgICAgY29weVZlYyhpbmRpY2VzLCBiKTtcbiAgICAgICAgICAke2Jyb2FkY2FzdEN9XG5cbiAgICAgICAgICBmbG9hdCB2YWx1ZSA9IDAuMDtcbiAgICAgICAgICBmb3IgKGludCBrPTA7IGs8JHtzaGFyZWREaW19OyArK2spIHtcbiAgICAgICAgICAgICAgYVske3JhbmsgLSAxfV0gPSBrO1xuICAgICAgICAgICAgICBiWyR7cmFuayAtIDJ9XSA9IGs7XG4gICAgICAgICAgICAgICR7bGluZX1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICB2YWx1ZSA9IHZhbHVlICogYWxwaGE7XG4gICAgICAgICAgJHtjYWxjdWxhdGVDfVxuICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIH1gO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4ubWV0YWRhdGEsXG4gICAgICAgIG91dHB1dDoge2RpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkfSxcbiAgICAgICAgdmFyaWFibGVzOiBbXG4gICAgICAgICAge25hbWU6ICdhbHBoYScsIHR5cGU6ICdmbG9hdCcsIGRhdGE6IGF0dHJpYnV0ZXMuYWxwaGF9LCB7bmFtZTogJ2JldGEnLCB0eXBlOiAnZmxvYXQnLCBkYXRhOiBhdHRyaWJ1dGVzLmJldGF9XG4gICAgICAgIF0sXG4gICAgICAgIHNoYWRlclNvdXJjZVxuICAgICAgfTtcbiAgICB9O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBHZW1tQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgaXMgbWlzc2luZycpO1xuICB9XG4gIGlmIChhdHRyaWJ1dGVzLmlzT3B0aW9uYWxDICYmIChpbnB1dHMubGVuZ3RoIDwgMiB8fCBpbnB1dHMubGVuZ3RoID4gMykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFpZCBpbnB1dCBzaGFwZS4nKTtcbiAgfVxuICBpZiAoIWF0dHJpYnV0ZXMuaXNPcHRpb25hbEMgJiYgaW5wdXRzLmxlbmd0aCAhPT0gMykge1xuICAgIHRocm93IG5ldyBFcnJvcignR2VtbSByZXF1aXJlcyAzIGlucHV0cycpO1xuICB9XG5cbiAgLy8gJ0MnIGNhbiBiZSBvZiBkaW1lbnNpb25hbGl0eSAxIG9yIDIgb25seVxuICBpZiAoaW5wdXRzLmxlbmd0aCA9PT0gMyAmJiBpbnB1dHNbMl0uZGltcy5sZW5ndGggIT09IDEgJiYgaW5wdXRzWzJdLmRpbXMubGVuZ3RoICE9PSAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHNoYXBlIG9mIEMnKTtcbiAgfVxuXG4gIGlmICgoaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDMyJyAmJiBpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0NjQnKSB8fFxuICAgICAgKGlucHV0c1sxXS50eXBlICE9PSAnZmxvYXQzMicgJiYgaW5wdXRzWzFdLnR5cGUgIT09ICdmbG9hdDY0JykgfHxcbiAgICAgIChpbnB1dHMubGVuZ3RoID09PSAzICYmIGlucHV0c1syXS50eXBlICE9PSAnZmxvYXQzMicgJiYgaW5wdXRzWzJdLnR5cGUgIT09ICdmbG9hdDY0JykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxuXG4gIGlmICgoaW5wdXRzWzBdLnR5cGUgIT09IGlucHV0c1sxXS50eXBlKSB8fCAoaW5wdXRzLmxlbmd0aCA9PT0gMyAmJiBpbnB1dHNbMF0udHlwZSAhPT0gaW5wdXRzWzJdLnR5cGUpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCB0eXBlcyBhcmUgbWlzbWF0Y2hlZCcpO1xuICB9XG59O1xuIiwiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7VGVuc29yfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHtnZXRHbHNsfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQge1dlYkdMSW5mZXJlbmNlSGFuZGxlcn0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHtQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGV9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHtDb252QXR0cmlidXRlc30gZnJvbSAnLi9jb252JztcbmltcG9ydCB7dW5wYWNrRnJvbUNoYW5uZWx9IGZyb20gJy4vcGFja2luZy11dGlscyc7XG5cbmNvbnN0IGNyZWF0ZVBhY2tlZEltMkNvbFByb2dyYW1NZXRhZGF0YSA9IChjYWNoZUhpbnQ6IHN0cmluZykgPT4gKHtcbiAgbmFtZTogJ0ltMkNvbCAocGFja2VkKScsXG4gIGlucHV0TmFtZXM6IFsnQSddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUucGFja2VkXSxcbiAgY2FjaGVIaW50LFxufSk7XG5cbmNvbnN0IGNyZWF0ZVBhY2tlZEltMkNvbFByb2dyYW1JbmZvID1cbiAgICAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBtZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhLCB4OiBUZW5zb3IsIHc6IFRlbnNvcixcbiAgICAgb3V0cHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCBhdHRyaWJ1dGVzOiBDb252QXR0cmlidXRlcyk6IFByb2dyYW1JbmZvID0+IHtcbiAgICAgIGNvbnN0IHhzaGFwZSA9IHguZGltcztcbiAgICAgIGNvbnN0IHdzaGFwZSA9IHcuZGltcztcbiAgICAgIGNvbnN0IHJvd0RpbSA9IDI7XG4gICAgICBjb25zdCBjb2xEaW0gPSAzO1xuICAgICAgY29uc3QgcmFuayA9IG91dHB1dFNoYXBlLmxlbmd0aDtcbiAgICAgIGNvbnN0IGltMmNvbFNoYXBlID0gW3dzaGFwZVsxXSAqIHdzaGFwZVsyXSAqIHdzaGFwZVszXSwgb3V0cHV0U2hhcGVbMl0gKiBvdXRwdXRTaGFwZVszXV07XG4gICAgICBjb25zdCBrZXJuZWxTaXplID0gd3NoYXBlWzJdICogd3NoYXBlWzNdO1xuICAgICAgY29uc3QgdW5wYWNrQ2hhbm5lbCA9IHVucGFja0Zyb21DaGFubmVsKCk7XG4gICAgICBjb25zdCBnbHNsID0gZ2V0R2xzbChpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gICAgICBsZXQgdW5yb2xsZWQgPSAnJztcblxuICAgICAgZm9yIChsZXQgcm93ID0gMDsgcm93IDw9IDE7IHJvdysrKSB7XG4gICAgICAgIGZvciAobGV0IGNvbCA9IDA7IGNvbCA8PSAxOyBjb2wrKykge1xuICAgICAgICAgIHVucm9sbGVkICs9IGBcbiAgICAgICAgICAgIGJsb2NrSW5kZXggPSByYy54ICsgJHtjb2x9O1xuICAgICAgICAgICAgcG9zID0gcmMueSArICR7cm93fTtcblxuICAgICAgICAgICAgaWYoYmxvY2tJbmRleCA8ICR7aW0yY29sU2hhcGVbMV19ICYmIHBvcyA8ICR7aW0yY29sU2hhcGVbMF19KSB7XG4gICAgICAgICAgICAgIG9mZnNldFkgPSBpbnQoYmxvY2tJbmRleCAvICgke291dHB1dFNoYXBlW3JhbmsgLSAxXX0pKSAqICR7YXR0cmlidXRlcy5zdHJpZGVzWzBdfSAtXG4gICAgICAgICAgICAgICAgJHthdHRyaWJ1dGVzLnBhZHNbMF19O1xuICAgICAgICAgICAgICBkMCA9IG9mZnNldFkgKyAke2F0dHJpYnV0ZXMuZGlsYXRpb25zWzBdfSAqIChpbW9kKHBvcywgJHtrZXJuZWxTaXplfSkgLyAke3dzaGFwZVsyXX0pO1xuXG4gICAgICAgICAgICAgIGlmKGQwIDwgJHt4c2hhcGVbcm93RGltXX0gJiYgZDAgPj0gMCkge1xuICAgICAgICAgICAgICAgIG9mZnNldFggPSBpbW9kKGJsb2NrSW5kZXgsICR7b3V0cHV0U2hhcGVbcmFuayAtIDFdfSkgKiAke2F0dHJpYnV0ZXMuc3RyaWRlc1sxXX0gLVxuICAgICAgICAgICAgICAgICAgJHthdHRyaWJ1dGVzLnBhZHNbMV19O1xuICAgICAgICAgICAgICAgIGQxID0gb2Zmc2V0WCArICR7YXR0cmlidXRlcy5kaWxhdGlvbnNbMV19ICogaW1vZChpbW9kKHBvcywgJHtrZXJuZWxTaXplfSksICR7d3NoYXBlWzJdfSk7XG5cbiAgICAgICAgICAgICAgICBpZihkMSA8ICR7eHNoYXBlW2NvbERpbV19ICYmIGQxID49IDApIHtcblxuICAgICAgICAgICAgICAgICAgY2ggPSBpbnQoZmxvYXQocG9zKS8gJHtrZXJuZWxTaXplfS4pO1xuICAgICAgICAgICAgICAgICAgICBpbm5lckRpbXMgPSB2ZWMyKGQwLCBkMSk7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdFske3JvdyAqIDIgKyBjb2x9XSA9IGdldENoYW5uZWwoXG4gICAgICAgICAgICAgICAgICAgICAgZ2V0QSgwLCBjaCwgaW50KGlubmVyRGltcy54KSxcbiAgICAgICAgICAgICAgICAgICAgICBpbnQoaW5uZXJEaW1zLnkpKSwgaW5uZXJEaW1zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgIGA7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgJHt1bnBhY2tDaGFubmVsfVxuXG4gICAgICB2b2lkIG1haW4oKSB7XG4gICAgICAgIGl2ZWMyIHJjID0gZ2V0T3V0cHV0Q29vcmRzKCk7XG4gICAgICAgICAgdmVjNCByZXN1bHQgPSB2ZWM0KDAuMCk7XG4gICAgICAgICAgaW50IGJsb2NrSW5kZXgsIHBvcywgb2Zmc2V0WSwgZDAsIG9mZnNldFgsIGQxLCBjaDtcbiAgICAgICAgICB2ZWMyIGlubmVyRGltcztcbiAgICAgICAgICAke3Vucm9sbGVkfVxuICAgICAgICAgICR7Z2xzbC5vdXRwdXR9ID0gcmVzdWx0O1xuICAgICAgfVxuICAgICAgICAgICAgYDtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLm1ldGFkYXRhLFxuICAgICAgICBvdXRwdXQ6IHtkaW1zOiBpbTJjb2xTaGFwZSwgdHlwZTogeC50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUucGFja2VkfSxcbiAgICAgICAgc2hhZGVyU291cmNlLFxuICAgICAgICBoYXNNYWluOiB0cnVlXG4gICAgICB9O1xuICAgIH07XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVQYWNrZWRJbTJDb2xQcm9ncmFtSW5mb0xvYWRlciA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgeDogVGVuc29yLCB3OiBUZW5zb3IsIG91dHB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgICAgYXR0cmlidXRlczogQ29udkF0dHJpYnV0ZXMpOiBQcm9ncmFtSW5mb0xvYWRlciA9PiB7XG4gICAgICBjb25zdCBtZXRhZGF0YSA9IGNyZWF0ZVBhY2tlZEltMkNvbFByb2dyYW1NZXRhZGF0YShhdHRyaWJ1dGVzLmNhY2hlS2V5KTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLm1ldGFkYXRhLFxuICAgICAgICBnZXQ6ICgpID0+IGNyZWF0ZVBhY2tlZEltMkNvbFByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIG1ldGFkYXRhLCB4LCB3LCBvdXRwdXRTaGFwZSwgYXR0cmlidXRlcylcbiAgICAgIH07XG4gICAgfTtcbiIsIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7V2ViR0xJbmZlcmVuY2VIYW5kbGVyfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQge1Byb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgUHJvZ3JhbU1ldGFkYXRhLCBUZXh0dXJlVHlwZX0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQge0NvbnZBdHRyaWJ1dGVzfSBmcm9tICcuL2NvbnYnO1xuXG5jb25zdCBjcmVhdGVJbTJDb2xQcm9ncmFtTWV0YWRhdGEgPSAoY2FjaGVIaW50OiBzdHJpbmcpID0+ICh7XG4gIG5hbWU6ICdJbTJDb2wnLFxuICBpbnB1dE5hbWVzOiBbJ1gnXSxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkXSxcbiAgY2FjaGVIaW50LFxufSk7XG5cbmNvbnN0IGNyZWF0ZUltMkNvbFByb2dyYW1JbmZvID1cbiAgICAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBtZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhLCB4OiBUZW5zb3IsIHc6IFRlbnNvcixcbiAgICAgb3V0cHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCBhdHRyaWJ1dGVzOiBDb252QXR0cmlidXRlcyk6IFByb2dyYW1JbmZvID0+IHtcbiAgICAgIGNvbnN0IHhzaGFwZSA9IHguZGltcztcbiAgICAgIGNvbnN0IHdzaGFwZSA9IHcuZGltcztcblxuICAgICAgY29uc3QgcmFuayA9IG91dHB1dFNoYXBlLmxlbmd0aDtcbiAgICAgIGNvbnN0IGltMmNvbERpbXMgPSBjYWxjdWxhdGVJbTJDb2xEaW1zKHhzaGFwZSwgd3NoYXBlLCBvdXRwdXRTaGFwZSwgNCk7XG5cbiAgICAgIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgICAgY29uc3QgaW50IFhDID0gJHt4c2hhcGVbMV19O1xuICAgICAgICBjb25zdCBpbnQgWEggPSAke3hzaGFwZVsyXX07XG4gICAgICAgIGNvbnN0IGludCBYVyA9ICR7eHNoYXBlWzNdfTtcbiAgICAgICAgY29uc3QgaW50IEtIID0gJHthdHRyaWJ1dGVzLmtlcm5lbFNoYXBlWzBdfTtcbiAgICAgICAgY29uc3QgaW50IEtXID0gJHthdHRyaWJ1dGVzLmtlcm5lbFNoYXBlWzFdfTtcbiAgICAgICAgY29uc3QgaW50IGRpbGF0aW9uSCA9ICR7YXR0cmlidXRlcy5kaWxhdGlvbnNbMF19O1xuICAgICAgICBjb25zdCBpbnQgZGlsYXRpb25XID0gJHthdHRyaWJ1dGVzLmRpbGF0aW9uc1sxXX07XG4gICAgICAgIGNvbnN0IGludCBzdHJpZGVIID0gJHthdHRyaWJ1dGVzLnN0cmlkZXNbMF19O1xuICAgICAgICBjb25zdCBpbnQgc3RyaWRlVyA9ICR7YXR0cmlidXRlcy5zdHJpZGVzWzFdfTtcbiAgICAgICAgY29uc3QgaW50IHBhZEggPSAke2F0dHJpYnV0ZXMucGFkc1swXX07XG4gICAgICAgIGNvbnN0IGludCBwYWRXID0gJHthdHRyaWJ1dGVzLnBhZHNbMV19O1xuICAgICAgICBjb25zdCBpbnQgS0hLVyA9IEtIKktXO1xuICAgICAgICBjb25zdCBpbnQgWENLSEtXID0gWEMgKiBLSEtXO1xuICAgICAgICBjb25zdCBpbnQgb3V0cHV0Q2hhbm5lbHMgPSA0O1xuICAgICAgICB2ZWM0IHByb2Nlc3MoaW50IGluZGljZXNbJHtyYW5rfV0pIHtcbiAgICAgICAgICBpbnQgYiAgPSBpbmRpY2VzWzBdOyAvLyBiYXRjaCBzaXplXG4gICAgICAgICAgaW50IG9oID0gaW5kaWNlc1sxXSAqIHN0cmlkZUggLSBwYWRIOyAvL291dHB1dCBoZWlnaHRcbiAgICAgICAgICBpbnQgb3cgPSBpbmRpY2VzWzJdICogc3RyaWRlVyAtIHBhZFc7IC8vb3V0cHV0IHdpZHRoXG4gICAgICAgICAgaW50IHAgPSBpbmRpY2VzWzNdICogb3V0cHV0Q2hhbm5lbHM7IC8vcGF0Y2hcbiAgICAgICAgICB2ZWM0IHZhbHVlID0gdmVjNCgwLjApO1xuICAgICAgICAgIGZvcihpbnQgaT0wOyBpIDwgb3V0cHV0Q2hhbm5lbHM7ICsraSkge1xuICAgICAgICAgICAgaWYocCA8IFhDS0hLVykge1xuICAgICAgICAgICAgICBpbnQgcGF0Y2hDID0gcCAvIEtIS1c7XG4gICAgICAgICAgICAgIGludCBwYXRjaEggPSAocCAtIHBhdGNoQypLSEtXKSAvIEtXO1xuICAgICAgICAgICAgICBpbnQgcGF0Y2hXID0gKHAgLSBwYXRjaEMqS0hLVykgLSBwYXRjaEggKiBLVztcbiAgICAgICAgICAgICAgaW50IHhoMiA9IG9oICsgcGF0Y2hIICogZGlsYXRpb25IO1xuICAgICAgICAgICAgICBpbnQgeHcyID0gb3cgKyBwYXRjaFcgKiBkaWxhdGlvblc7XG4gICAgICAgICAgICAgIGludCB4WyR7eHNoYXBlLmxlbmd0aH1dO1xuICAgICAgICAgICAgICB4WzBdID0gYjtcbiAgICAgICAgICAgICAgeFsxXSA9IHBhdGNoQztcbiAgICAgICAgICAgICAgeFsyXSA9IHhoMjtcbiAgICAgICAgICAgICAgeFszXSA9IHh3MjtcbiAgICAgICAgICAgICAgaWYoeGgyID49IDAgJiZcbiAgICAgICAgICAgICAgICAgIHhoMiA8IFhIICYmXG4gICAgICAgICAgICAgICAgICB4dzIgPj0gMCAmJlxuICAgICAgICAgICAgICAgICAgeHcyIDwgWFcpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZVtpXSA9IF9YKHgpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICArK3A7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4ubWV0YWRhdGEsXG4gICAgICAgIG91dHB1dDoge2RpbXM6IGltMmNvbERpbXMsIHR5cGU6IHgudHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnBhY2tlZExhc3REaW1lbnNpb259LFxuICAgICAgICBzaGFkZXJTb3VyY2VcbiAgICAgIH07XG4gICAgfTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZUltMkNvbFByb2dyYW1JbmZvTG9hZGVyID1cbiAgICAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCB4OiBUZW5zb3IsIHc6IFRlbnNvciwgb3V0cHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLFxuICAgICBhdHRyaWJ1dGVzOiBDb252QXR0cmlidXRlcyk6IFByb2dyYW1JbmZvTG9hZGVyID0+IHtcbiAgICAgIGNvbnN0IG1ldGFkYXRhID0gY3JlYXRlSW0yQ29sUHJvZ3JhbU1ldGFkYXRhKGF0dHJpYnV0ZXMuY2FjaGVLZXkpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4ubWV0YWRhdGEsXG4gICAgICAgIGdldDogKCkgPT4gY3JlYXRlSW0yQ29sUHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgbWV0YWRhdGEsIHgsIHcsIG91dHB1dFNoYXBlLCBhdHRyaWJ1dGVzKVxuICAgICAgfTtcbiAgICB9O1xuXG5cbmV4cG9ydCBjb25zdCBjYWxjdWxhdGVJbTJDb2xEaW1zID1cbiAgICAoaW5wdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIGtlcm5lbFNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgb3V0cHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCBjaGFubmVscyA9IDQpOlxuICAgICAgICBudW1iZXJbXSA9PlxuICAgICAgICAgICAgW291dHB1dFNoYXBlWzBdLCBvdXRwdXRTaGFwZVsyXSwgb3V0cHV0U2hhcGVbM10sXG4gICAgICAgICAgICAgTWF0aC5jZWlsKGlucHV0U2hhcGVbMV0gKiBrZXJuZWxTaGFwZVsyXSAqIGtlcm5lbFNoYXBlWzNdIC8gY2hhbm5lbHMpXTtcbiIsIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge0F0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5fSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHtHcmFwaH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHtPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9ufSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHtUZW5zb3J9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQge1dlYkdMSW5mZXJlbmNlSGFuZGxlcn0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHtQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGV9IGZyb20gJy4uL3R5cGVzJztcblxuZXhwb3J0IGludGVyZmFjZSBJbWFnZVNjYWxlckF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICBzY2FsZTogbnVtYmVyO1xuICBiaWFzOiBudW1iZXJbXTtcbn1cblxuZXhwb3J0IGNvbnN0IGltYWdlU2NhbGVyOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPEltYWdlU2NhbGVyQXR0cmlidXRlcz4gPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IEltYWdlU2NhbGVyQXR0cmlidXRlcyk6IFRlbnNvcltdID0+IHtcbiAgICAgIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG4gICAgICBjb25zdCBvdXRwdXQgPVxuICAgICAgICAgIGluZmVyZW5jZUhhbmRsZXIucnVuKGNyZWF0ZUltYWdlU2NhbGVyUHJvZ3JhbUluZm9Mb2FkZXIoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzKSwgaW5wdXRzKTtcbiAgICAgIHJldHVybiBbb3V0cHV0XTtcbiAgICB9O1xuXG5leHBvcnQgY29uc3QgcGFyc2VJbWFnZVNjYWxlckF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248SW1hZ2VTY2FsZXJBdHRyaWJ1dGVzPiA9XG4gICAgKG5vZGU6IEdyYXBoLk5vZGUpOiBJbWFnZVNjYWxlckF0dHJpYnV0ZXMgPT4ge1xuICAgICAgY29uc3Qgc2NhbGUgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0RmxvYXQoJ3NjYWxlJyk7XG4gICAgICBjb25zdCBiaWFzID0gbm9kZS5hdHRyaWJ1dGVzLmdldEZsb2F0cygnYmlhcycpO1xuICAgICAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7c2NhbGUsIGJpYXN9KTtcbiAgICB9O1xuXG5jb25zdCBpbWFnZVNjYWxlclByb2dyYW1NZXRhZGF0YSA9IHtcbiAgbmFtZTogJ0ltYWdlU2NhbGVyJyxcbiAgaW5wdXROYW1lczogWydYJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG59O1xuXG5jb25zdCBjcmVhdGVJbWFnZVNjYWxlclByb2dyYW1JbmZvID1cbiAgICAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBtZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhLCBpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBJbWFnZVNjYWxlckF0dHJpYnV0ZXMpOlxuICAgICAgICBQcm9ncmFtSW5mbyA9PiB7XG4gICAgICAgICAgY29uc3Qgb3V0cHV0U2hhcGUgPSBpbnB1dHNbMF0uZGltcy5zbGljZSgpO1xuICAgICAgICAgIGNvbnN0IHJhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG4gICAgICAgICAgY29uc3QgZ2V0Qmlhc01ldGhvZCA9IGNyZWF0ZUdldEJpYXNNZXRob2QoYXR0cmlidXRlcy5iaWFzLmxlbmd0aCk7XG4gICAgICAgICAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgJHtnZXRCaWFzTWV0aG9kfVxuICAgICAgZmxvYXQgcHJvY2VzcyhpbnQgaW5kaWNlc1ske3Jhbmt9XSkge1xuICAgICAgICByZXR1cm4gX1goaW5kaWNlcykgKiBzY2FsZSArIGdldEJpYXMoYmlhcywgaW5kaWNlc1sxXSk7XG4gICAgICB9YDtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgLi4ubWV0YWRhdGEsXG4gICAgICAgICAgICBvdXRwdXQ6IHtkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXRzWzBdLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZH0sXG4gICAgICAgICAgICB2YXJpYWJsZXM6IFtcbiAgICAgICAgICAgICAge25hbWU6ICdiaWFzJywgdHlwZTogJ2Zsb2F0JywgYXJyYXlMZW5ndGg6IGF0dHJpYnV0ZXMuYmlhcy5sZW5ndGgsIGRhdGE6IGF0dHJpYnV0ZXMuYmlhc30sXG4gICAgICAgICAgICAgIHtuYW1lOiAnc2NhbGUnLCB0eXBlOiAnZmxvYXQnLCBkYXRhOiBhdHRyaWJ1dGVzLnNjYWxlfVxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIHNoYWRlclNvdXJjZVxuICAgICAgICAgIH07XG4gICAgICAgIH07XG5cbmNvbnN0IGNyZWF0ZUltYWdlU2NhbGVyUHJvZ3JhbUluZm9Mb2FkZXIgPVxuICAgIChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IEltYWdlU2NhbGVyQXR0cmlidXRlcyk6IFByb2dyYW1JbmZvTG9hZGVyID0+IHtcbiAgICAgIGNvbnN0IG1ldGFkYXRhID0gey4uLmltYWdlU2NhbGVyUHJvZ3JhbU1ldGFkYXRhLCBjYWNoZUhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXl9O1xuICAgICAgcmV0dXJuIHsuLi5tZXRhZGF0YSwgZ2V0OiAoKSA9PiBjcmVhdGVJbWFnZVNjYWxlclByb2dyYW1JbmZvKGhhbmRsZXIsIG1ldGFkYXRhLCBpbnB1dHMsIGF0dHJpYnV0ZXMpfTtcbiAgICB9O1xuXG5jb25zdCBjcmVhdGVHZXRCaWFzTWV0aG9kID0gKG51bUNoYW5uZWxzOiBudW1iZXIpOiBzdHJpbmcgPT4ge1xuICBjb25zdCBjb2RlTGluZXM6IHN0cmluZ1tdID0gW2BmbG9hdCBnZXRCaWFzKGZsb2F0IGJpYXNbJHtudW1DaGFubmVsc31dLCBpbnQgY2hhbm5lbCkge2BdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IG51bUNoYW5uZWxzOyArK2kpIHtcbiAgICBpZiAoaSA9PT0gMCkge1xuICAgICAgY29kZUxpbmVzLnB1c2goXG4gICAgICAgICAgJ1xcdCcgK1xuICAgICAgICAgIGBpZiAoY2hhbm5lbCA9PSAke2l9KSB7IHJldHVybiBiaWFzWyR7aX1dOyB9YCk7XG4gICAgfSBlbHNlIGlmIChpID09PSBudW1DaGFubmVscyAtIDEpIHtcbiAgICAgIGNvZGVMaW5lcy5wdXNoKFxuICAgICAgICAgICdcXHQnICtcbiAgICAgICAgICBgZWxzZSB7IHJldHVybiBiaWFzWyR7aX1dOyB9YCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvZGVMaW5lcy5wdXNoKFxuICAgICAgICAgICdcXHQnICtcbiAgICAgICAgICBgZWxzZSBpZiAoY2hhbm5lbCA9PSAke2l9KSB7IHJldHVybiBiaWFzWyR7aX1dOyB9YCk7XG4gICAgfVxuICB9XG4gIGNvZGVMaW5lcy5wdXNoKFxuICAgICAgJ1xcdCcgK1xuICAgICAgJ30nKTtcbiAgcmV0dXJuIGNvZGVMaW5lcy5qb2luKCdcXG4nKTtcbn07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW1hZ2VTY2FsZXIgcmVxdWlyZXMgMSBpbnB1dC4nKTtcbiAgfVxuICBpZiAoaW5wdXRzWzBdLmRpbXMubGVuZ3RoICE9PSA0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHNoYXBlLicpO1xuICB9XG4gIGlmIChpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0MzInICYmIGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQ2NCcpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxufTtcbiIsIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge0dyYXBofSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQge09wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb259IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7Z2V0R2xzbH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHtXZWJHTEluZmVyZW5jZUhhbmRsZXJ9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7UHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBjb25zdCBpbnN0YW5jZU5vcm1hbGl6YXRpb246IE9wZXJhdG9ySW1wbGVtZW50YXRpb248bnVtYmVyPiA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgZXBzaWxvbjogbnVtYmVyKTogVGVuc29yW10gPT4ge1xuICAgICAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcblxuICAgICAgY29uc3QgbWVhbkFuZFZhcmlhbmNlID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oY3JlYXRlTWVhbkFuZFZhcmlhbmNlUHJvZ3JhbUluZm9Mb2FkZXIoaW5wdXRzWzBdKSwgaW5wdXRzKTtcbiAgICAgIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgICAgICAgIGNyZWF0ZUNvbXB1dGVPdXRwdXRQcm9ncmFtSW5mb0xvYWRlcihpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHNbMF0sIGVwc2lsb24sIG1lYW5BbmRWYXJpYW5jZS5kaW1zKSxcbiAgICAgICAgICBbaW5wdXRzWzBdLCBtZWFuQW5kVmFyaWFuY2UsIGlucHV0c1sxXSwgaW5wdXRzWzJdXSk7XG4gICAgICByZXR1cm4gW291dHB1dF07XG4gICAgfTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlSW5zdGFuY2VOb3JtYWxpemF0aW9uQXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxudW1iZXI+ID0gKG5vZGU6IEdyYXBoLk5vZGUpOiBudW1iZXIgPT5cbiAgICBub2RlLmF0dHJpYnV0ZXMuZ2V0RmxvYXQoJ2Vwc2lsb24nLCAxZS01KTtcblxuY29uc3QgbWVhbkFuZFZhcmlhbmNlUHJvZ3JhbU1ldGFkYXRhID0ge1xuICBuYW1lOiAnSW5zdGFuY2VOb3JtYWxpemF0aW9uX01lYW5BbmRWYXJpYW5jZScsXG4gIGlucHV0TmFtZXM6IFsnWCddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxufTtcblxuY29uc3QgY3JlYXRlTWVhbkFuZFZhcmlhbmNlUHJvZ3JhbUluZm8gPSAobWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSwgaW5wdXQ6IFRlbnNvcik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgeERpbXMgPSBpbnB1dC5kaW1zLnNsaWNlKCk7XG4gIGNvbnN0IGNoYW5uZWwgPSB4RGltc1sxXTtcbiAgY29uc3QgY2hhbm5lbFNpemUgPSB4RGltc1syXSAqIHhEaW1zWzNdO1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IFt4RGltc1swXSwgY2hhbm5lbF07XG5cbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgdmVjNCBwcm9jZXNzKGludFsyXSBpbmRpY2VzKSB7XG4gICAgICAgIHZlYzQgdiA9IHZlYzQoMC4wKTtcbiAgICAgICAgaW50IGFbNF07XG4gICAgICAgIGFbMF0gPSBpbmRpY2VzWzBdO1xuICAgICAgICBhWzFdID0gaW5kaWNlc1sxXTtcbiAgICAgICAgZmxvYXQgdGVtcCA9IDAuMDtcbiAgICAgICAgZm9yKGludCBhMj0wOyBhMjwke3hEaW1zWzJdfTsgYTIrKykge1xuICAgICAgICAgIGFbMl0gPSBhMjtcbiAgICAgICAgICBmb3IoaW50IGEzPTA7IGEzPCR7eERpbXNbM119OyBhMysrKSB7XG4gICAgICAgICAgICBhWzNdID0gYTM7XG4gICAgICAgICAgICBmbG9hdCB4ID0gX1goYSk7XG4gICAgICAgICAgICB0ZW1wICs9IHg7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGZsb2F0IG1lYW4gPSB0ZW1wIC8gZmxvYXQoJHtjaGFubmVsU2l6ZX0pO1xuICAgICAgICB0ZW1wID0gMC4wO1xuICAgICAgICBmb3IoaW50IGEyPTA7IGEyPCR7eERpbXNbMl19OyBhMisrKSB7XG4gICAgICAgICAgYVsyXSA9IGEyO1xuICAgICAgICAgIGZvcihpbnQgYTM9MDsgYTM8JHt4RGltc1szXX07IGEzKyspIHtcbiAgICAgICAgICAgIGFbM10gPSBhMztcbiAgICAgICAgICAgIGZsb2F0IHggPSBfWChhKTtcbiAgICAgICAgICAgIHRlbXAgKz0gKHggLSBtZWFuKSAqICh4IC0gbWVhbik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHYuciA9IG1lYW47XG4gICAgICAgIHYuZyA9IHRlbXAgLyBmbG9hdCgke2NoYW5uZWxTaXplfSk7XG5cbiAgICAgICAgcmV0dXJuIHY7XG4gICAgICB9YDtcbiAgcmV0dXJuIHtcbiAgICAuLi5tZXRhZGF0YSxcbiAgICBvdXRwdXQ6IHtkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXQudHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnBhY2tlZExhc3REaW1lbnNpb259LFxuICAgIHNoYWRlclNvdXJjZVxuICB9O1xufTtcblxuY29uc3QgY3JlYXRlTWVhbkFuZFZhcmlhbmNlUHJvZ3JhbUluZm9Mb2FkZXIgPSAoaW5wdXQ6IFRlbnNvcik6IFByb2dyYW1JbmZvTG9hZGVyID0+ICh7XG4gIC4uLm1lYW5BbmRWYXJpYW5jZVByb2dyYW1NZXRhZGF0YSxcbiAgZ2V0OiAoKSA9PiBjcmVhdGVNZWFuQW5kVmFyaWFuY2VQcm9ncmFtSW5mbyhtZWFuQW5kVmFyaWFuY2VQcm9ncmFtTWV0YWRhdGEsIGlucHV0KVxufSk7XG5cbmNvbnN0IGNvbXB1dGVPdXRwdXRQcm9ncmFtTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdJbnN0YW5jZU5vcm1hbGl6YXRpb25fQ29tcHV0ZU91dHB1dCcsXG4gIGlucHV0TmFtZXM6IFsnWCcsICdNZWFuQW5kVmFyaWFuY2UnLCAnU2NhbGUnLCAnQiddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnBhY2tlZExhc3REaW1lbnNpb24sIFRleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG59O1xuXG5jb25zdCBjcmVhdGVDb21wdXRlT3V0cHV0UHJvZ3JhbUluZm8gPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsIGlucHV0OiBUZW5zb3IsIGVwc2lsb246IG51bWJlcixcbiAgICAgbWVhbkFuZFZhcmlhbmNlU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdKTogUHJvZ3JhbUluZm8gPT4ge1xuICAgICAgY29uc3QgZ2xzbCA9IGdldEdsc2woaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICAgICAgY29uc3QgW3RleHR1cmVXaWR0aCwgdGV4dHVyZUhlaWdodF0gPVxuICAgICAgICAgIGluZmVyZW5jZUhhbmRsZXIuY2FsY3VsYXRlVGV4dHVyZVdpZHRoQW5kSGVpZ2h0KG1lYW5BbmRWYXJpYW5jZVNoYXBlLCBUZXh0dXJlVHlwZS5wYWNrZWRMYXN0RGltZW5zaW9uKTtcbiAgICAgIGNvbnN0IFttZWFuQW5kVmFyaWFuY2VXaWR0aCwgbWVhbkFuZFZhcmlhbmNlSGVpZ2h0XSA9IFt0ZXh0dXJlV2lkdGggLyA0LCB0ZXh0dXJlSGVpZ2h0XTtcbiAgICAgIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgIHZlYzQgZ2V0X01lYW5BbmRWYXJpYW5jZShpbnRbMl0gbXYpIHtcbiAgICAgICAgaW50IG9mZnNldCA9IGluZGljZXNUb09mZnNldF9NZWFuQW5kVmFyaWFuY2UobXYpO1xuICAgICAgICB2ZWMyIGNvb3JkcyA9IG9mZnNldFRvQ29vcmRzKG9mZnNldCwgJHttZWFuQW5kVmFyaWFuY2VXaWR0aH0sICR7bWVhbkFuZFZhcmlhbmNlSGVpZ2h0fSk7XG4gICAgICAgIHJldHVybiAke2dsc2wudGV4dHVyZTJEfShNZWFuQW5kVmFyaWFuY2UsIGNvb3Jkcyk7XG4gICAgICB9XG5cbiAgICAgIGZsb2F0IHByb2Nlc3MoaW50WzRdIGluZGljZXMpIHtcbiAgICAgICAgaW50IG12WzJdO1xuICAgICAgICBtdlswXSA9IGluZGljZXNbMF07XG4gICAgICAgIG12WzFdID0gaW5kaWNlc1sxXTtcbiAgICAgICAgdmVjNCBtZWFuX2FuZF92YXJpYW5jZSA9IGdldF9NZWFuQW5kVmFyaWFuY2UobXYpO1xuICAgICAgICBmbG9hdCBtZWFuID0gbWVhbl9hbmRfdmFyaWFuY2UucjtcbiAgICAgICAgZmxvYXQgdmFyaWFuY2UgPSBtZWFuX2FuZF92YXJpYW5jZS5nO1xuXG4gICAgICAgIGludCBzYlsxXTtcbiAgICAgICAgc2JbMF0gPSBpbmRpY2VzWzFdO1xuICAgICAgICBmbG9hdCBzY2FsZSA9IF9TY2FsZShzYik7XG4gICAgICAgIGZsb2F0IGIgPSBfQihzYik7XG5cbiAgICAgICAgcmV0dXJuIHNjYWxlICogKF9YKGluZGljZXMpIC0gbWVhbikgLyBzcXJ0KHZhcmlhbmNlICsgZXBzaWxvbikgKyBiO1xuICAgICAgfWA7XG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5tZXRhZGF0YSxcbiAgICAgICAgb3V0cHV0OiB7ZGltczogaW5wdXQuZGltcywgdHlwZTogaW5wdXQudHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkfSxcbiAgICAgICAgdmFyaWFibGVzOiBbe25hbWU6ICdlcHNpbG9uJywgdHlwZTogJ2Zsb2F0JywgZGF0YTogZXBzaWxvbn1dLFxuICAgICAgICBzaGFkZXJTb3VyY2VcbiAgICAgIH07XG4gICAgfTtcblxuY29uc3QgY3JlYXRlQ29tcHV0ZU91dHB1dFByb2dyYW1JbmZvTG9hZGVyID1cbiAgICAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dDogVGVuc29yLCBlcHNpbG9uOiBudW1iZXIsIG1lYW5BbmRWYXJpYW5jZVNoYXBlOiByZWFkb25seSBudW1iZXJbXSk6XG4gICAgICAgIFByb2dyYW1JbmZvTG9hZGVyID0+IHtcbiAgICAgICAgICBjb25zdCBtZXRhZGF0YSA9IHsuLi5jb21wdXRlT3V0cHV0UHJvZ3JhbU1ldGFkYXRhLCBjYWNoZUhpbnQ6IGAke2Vwc2lsb259YH07XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC4uLm1ldGFkYXRhLFxuICAgICAgICAgICAgZ2V0OiAoKSA9PiBjcmVhdGVDb21wdXRlT3V0cHV0UHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgbWV0YWRhdGEsIGlucHV0LCBlcHNpbG9uLCBtZWFuQW5kVmFyaWFuY2VTaGFwZSlcbiAgICAgICAgICB9O1xuICAgICAgICB9O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0luc3RhbmNlTm9ybWFsaXphdGlvbiByZXF1aXJlcyAzIGlucHV0cy4nKTtcbiAgfVxuXG4gIGNvbnN0IFggPSBpbnB1dHNbMF07XG4gIGNvbnN0IHNjYWxlID0gaW5wdXRzWzFdO1xuICBjb25zdCBCID0gaW5wdXRzWzJdO1xuXG4gIC8vIGlucHV0IHNob3VsZCBhdCBsZWFzdCBoYXZlIHRocmVlIGRpbWVuc2lvbnMgLSBOLEMsZGltMSwuLi4sZGltblxuICAvLyBvdGhlciBpbnB1dHMgY2FuIGhhdmUgb25seSBvbmUgZGltZW5zaW9uc1xuICBpZiAoWC5kaW1zLmxlbmd0aCA8IDMgfHwgc2NhbGUuZGltcy5sZW5ndGggIT09IDEgfHwgQi5kaW1zLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCBzaGFwZS4nKTtcbiAgfVxuICBpZiAoc2NhbGUuZGltc1swXSAhPT0gWC5kaW1zWzFdIHx8IEIuZGltc1swXSAhPT0gWC5kaW1zWzFdKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBzaGFwZXMgYXJlIG1pc21hdGNoZWQuJyk7XG4gIH1cbiAgaWYgKChYLnR5cGUgIT09ICdmbG9hdDMyJyAmJiBYLnR5cGUgIT09ICdmbG9hdDY0JykgfHwgKHNjYWxlLnR5cGUgIT09ICdmbG9hdDMyJyAmJiBzY2FsZS50eXBlICE9PSAnZmxvYXQ2NCcpIHx8XG4gICAgICAoQi50eXBlICE9PSAnZmxvYXQzMicgJiYgQi50eXBlICE9PSAnZmxvYXQ2NCcpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbiAgaWYgKGlucHV0c1swXS5kaW1zLmxlbmd0aCAhPT0gNCkge1xuICAgIHRocm93IG5ldyBFcnJvcignT25seSBzdXBwb3J0IDQtRCBpbnB1dCBzaGFwZS4nKTtcbiAgfVxufTtcbiIsIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7QnJvYWRjYXN0VXRpbCwgU2hhcGVVdGlsfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7Z2V0R2xzbH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHtXZWJHTEluZmVyZW5jZUhhbmRsZXJ9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7UHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlfSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQge2dldENvb3Jkc0RhdGFUeXBlLCBnZXRHbENoYW5uZWxzfSBmcm9tICcuLi91dGlscyc7XG5cbmltcG9ydCB7Z2V0QWN0aXZhdGlvblNuaXBwZXQsIEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXN9IGZyb20gJy4vZnVzZS11dGlscyc7XG5pbXBvcnQge2dldEJpYXNGb3JNYXRtdWx9IGZyb20gJy4vbWF0bXVsJztcblxuY29uc3QgY3JlYXRlUGFja2VkTWF0bXVsUHJvZ3JhbU1ldGFkYXRhID0gKGhhc0JpYXM6IGJvb2xlYW4sIGNhY2hlSGludDogc3RyaW5nKSA9PiAoe1xuICBuYW1lOiAnTWF0TXVsIChwYWNrZWQpJyxcbiAgaW5wdXROYW1lczogaGFzQmlhcyA/IFsnQScsICdCJywgJ0JpYXMnXSA6IFsnQScsICdCJ10sXG4gIGlucHV0VHlwZXM6IGhhc0JpYXMgPyBbVGV4dHVyZVR5cGUucGFja2VkLCBUZXh0dXJlVHlwZS5wYWNrZWQsIFRleHR1cmVUeXBlLnBhY2tlZF0gOlxuICAgICAgICAgICAgICAgICAgICAgICAgW1RleHR1cmVUeXBlLnBhY2tlZCwgVGV4dHVyZVR5cGUucGFja2VkXSxcbiAgY2FjaGVIaW50XG59KTtcblxuY29uc3QgY3JlYXRlUGFja2VkTWF0bXVsUHJvZ3JhbUluZm8gPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsIGlucHV0czogVGVuc29yW10sXG4gICAgIGFjdGl2YXRpb25BdHRyaWJ1dGVzOiBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzKTogUHJvZ3JhbUluZm8gPT4ge1xuICAgICAgY29uc3QgaGFzQmlhcyA9IGlucHV0cy5sZW5ndGggPiAyO1xuICAgICAgY29uc3QgcHJvY2Vzc0JpYXMgPSBoYXNCaWFzID8gJ3ZhbHVlICs9IGdldEJpYXNGb3JNYXRtdWwoKTsnIDogJyc7XG4gICAgICBjb25zdCBhU2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgICAgIGNvbnN0IGJTaGFwZSA9IGlucHV0c1sxXS5kaW1zO1xuICAgICAgY29uc3Qgb3V0cHV0U2hhcGUgPSBCcm9hZGNhc3RVdGlsLmNhbGNTaGFwZShhU2hhcGUsIGJTaGFwZSwgdHJ1ZSk7XG4gICAgICBjb25zdCBpc0Jyb2FkY2FzdCA9ICFTaGFwZVV0aWwuYXJlRXF1YWwoaW5wdXRzWzBdLmRpbXMsIGlucHV0c1sxXS5kaW1zKTtcblxuICAgICAgaWYgKCFvdXRwdXRTaGFwZSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NhblxcJ3QgdXNlIG1hdG11bCBvbiB0aGUgZ2l2ZW4gdGVuc29ycycpO1xuICAgICAgfVxuICAgICAgY29uc3Qgc2hhcmVkRGltID0gYVNoYXBlW2FTaGFwZS5sZW5ndGggLSAxXTtcbiAgICAgIGNvbnN0IHNoYXJlZERpbUluZGV4ID0gTWF0aC5jZWlsKHNoYXJlZERpbSAvIDIpO1xuICAgICAgY29uc3QgYVJhbmsgPSBhU2hhcGUubGVuZ3RoO1xuICAgICAgY29uc3QgYlJhbmsgPSBiU2hhcGUubGVuZ3RoO1xuXG4gICAgICBjb25zdCBnbHNsID0gZ2V0R2xzbChpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gICAgICBjb25zdCBjb29yZHNEYXRhVHlwZSA9IGdldENvb3Jkc0RhdGFUeXBlKG91dHB1dFNoYXBlLmxlbmd0aCk7XG4gICAgICBjb25zdCBvdXRSYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuICAgICAgY29uc3QgYWxsR2xDaGFubmVscyA9IGdldEdsQ2hhbm5lbHMoKTtcbiAgICAgIGNvbnN0IHthY3RpdmF0aW9uRnVuY3Rpb24sIGFwcGx5QWN0aXZhdGlvbn0gPSBnZXRBY3RpdmF0aW9uU25pcHBldChhY3RpdmF0aW9uQXR0cmlidXRlcyk7XG5cbiAgICAgIGNvbnN0IGdldEJpYXNGb3JNYXRtdWxTbmlwcGV0ID1cbiAgICAgICAgICBoYXNCaWFzID8gYCR7Z2V0Qmlhc0Zvck1hdG11bChjb29yZHNEYXRhVHlwZSwgYWxsR2xDaGFubmVscywgaW5wdXRzWzJdLmRpbXMsIG91dHB1dFNoYXBlLCB0cnVlKX1gIDogJyc7XG5cbiAgICAgIGNvbnN0IGdldEJjYXN0ZWRTYW1wbGVyRm9yTWF0bXVsU25pcHBldCA9XG4gICAgICAgICAgaXNCcm9hZGNhc3QgPyBgJHtnZXRCY2FzdFNhbXBsZXJGb3JNYXRtdWwoY29vcmRzRGF0YVR5cGUsIGFsbEdsQ2hhbm5lbHMsIGlucHV0cywgb3V0cHV0U2hhcGUpfWAgOiAnJztcblxuICAgICAgY29uc3QgZ2V0U2FtcGxlckFJbkxvb3BTbmlwcGV0ID0gaXNCcm9hZGNhc3QgPyAnZ2V0QUF0T3V0Q29vcmRzTWF0bXVsKGkpJyA6IGBnZXRBKCR7Z2V0QShhbGxHbENoYW5uZWxzLCBhUmFuayl9KWA7XG4gICAgICBjb25zdCBnZXRTYW1wbGVyQkluTG9vcFNuaXBwZXQgPSBpc0Jyb2FkY2FzdCA/ICdnZXRCQXRPdXRDb29yZHNNYXRtdWwoaSknIDogYGdldEIoJHtnZXRCKGFsbEdsQ2hhbm5lbHMsIGJSYW5rKX0pYDtcbiAgICAgIGNvbnN0IGdldE91dHB1dENvb3Jkc1NuaXBwZXQgPSBpc0Jyb2FkY2FzdCA/ICcnIDogYCR7Y29vcmRzRGF0YVR5cGV9IHJjID1cbiAgICAgICAgICBnZXRPdXRwdXRDb29yZHMoKTsgaW50IGxhc3REaW0gPSByYy4ke2FsbEdsQ2hhbm5lbHNbb3V0UmFuayAtIDFdfTsgcmMuJHthbGxHbENoYW5uZWxzW291dFJhbmsgLSAxXX0gPVxuICAgICAgICAgIHJjLiR7YWxsR2xDaGFubmVsc1tvdXRSYW5rIC0gMl19OyByYy4ke2FsbEdsQ2hhbm5lbHNbb3V0UmFuayAtIDJdfSA9IGxhc3REaW07XG4gICAgICBgO1xuICAgICAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgICAgICAgJHtnZXRCY2FzdGVkU2FtcGxlckZvck1hdG11bFNuaXBwZXR9XG4gICAgICAgICAgICAke2dldEJpYXNGb3JNYXRtdWxTbmlwcGV0fVxuICAgICAgICAgICAgJHthY3RpdmF0aW9uRnVuY3Rpb259XG4gICAgICAgICAgICB2b2lkIG1haW4oKSB7XG4gICAgICAgICAgICAgICR7Z2V0T3V0cHV0Q29vcmRzU25pcHBldH1cblxuICAgICAgICAgICAgICB2ZWM0IHZhbHVlID0gdmVjNCgwKTtcbiAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAke3NoYXJlZERpbUluZGV4fTsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdmVjNCBhID0gJHtnZXRTYW1wbGVyQUluTG9vcFNuaXBwZXR9O1xuICAgICAgICAgICAgICAgIHZlYzQgYiA9ICR7Z2V0U2FtcGxlckJJbkxvb3BTbmlwcGV0fTtcblxuICAgICAgICAgICAgICAgIHZhbHVlICs9IChhLnJyYmIgKiBiLnJncmcpO1xuICAgICAgICAgICAgICAgIHZhbHVlICs9IChhLmdnYWEgKiBiLmJhYmEpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICR7cHJvY2Vzc0JpYXN9XG4gICAgICAgICAgICAgICR7YXBwbHlBY3RpdmF0aW9ufVxuICAgICAgICAgICAgICAke2dsc2wub3V0cHV0fSA9IHZhbHVlO1xuICAgICAgICAgICAgfWA7XG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5tZXRhZGF0YSxcbiAgICAgICAgb3V0cHV0OiB7ZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUucGFja2VkfSxcbiAgICAgICAgc2hhZGVyU291cmNlLFxuICAgICAgICBoYXNNYWluOiB0cnVlXG4gICAgICB9O1xuICAgIH07XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVQYWNrZWRNYXRtdWxQcm9ncmFtSW5mb0xvYWRlciA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSxcbiAgICAgYWN0aXZhdGlvbkF0dHJpYnV0ZXM6IEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMpOiBQcm9ncmFtSW5mb0xvYWRlciA9PiB7XG4gICAgICBjb25zdCBtZXRhZGF0YSA9IGNyZWF0ZVBhY2tlZE1hdG11bFByb2dyYW1NZXRhZGF0YShpbnB1dHMubGVuZ3RoID4gMiwgYWN0aXZhdGlvbkF0dHJpYnV0ZXMuYWN0aXZhdGlvbkNhY2hlS2V5KTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLm1ldGFkYXRhLFxuICAgICAgICBnZXQ6ICgpID0+IGNyZWF0ZVBhY2tlZE1hdG11bFByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIG1ldGFkYXRhLCBpbnB1dHMsIGFjdGl2YXRpb25BdHRyaWJ1dGVzKVxuICAgICAgfTtcbiAgICB9O1xuXG5mdW5jdGlvbiBnZXRCY2FzdFNhbXBsZXJGb3JNYXRtdWwoXG4gICAgY29vcmRzRGF0YVR5cGU6IHN0cmluZywgYWxsR2xDaGFubmVsczogcmVhZG9ubHkgc3RyaW5nW10sIGlucHV0czogVGVuc29yW10sIG91dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSk6IHN0cmluZyB7XG4gIGxldCB1bnBhY2tlZEFDb29yZHNTbmlwcGV0ID0gW107XG4gIGxldCB1bnBhY2tlZEJDb29yZHNTbmlwcGV0ID0gW107XG5cbiAgY29uc3QgaW5BU2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgY29uc3QgaW5CU2hhcGUgPSBpbnB1dHNbMV0uZGltcztcblxuICBjb25zdCBpbkFSYW5rID0gaW5BU2hhcGUubGVuZ3RoO1xuICBjb25zdCBpbkJSYW5rID0gaW5CU2hhcGUubGVuZ3RoO1xuXG4gIGNvbnN0IG91dFJhbmsgPSBvdXRTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IHJhbmtBRGlmZiA9IG91dFJhbmsgLSBpbkFSYW5rO1xuICBjb25zdCByYW5rQkRpZmYgPSBvdXRSYW5rIC0gaW5CUmFuaztcblxuICB1bnBhY2tlZEFDb29yZHNTbmlwcGV0ID0gaW5BU2hhcGUubWFwKChzLCBpKSA9PiBgY29vcmRzLiR7YWxsR2xDaGFubmVsc1tpICsgcmFua0FEaWZmXX1gKTtcbiAgdW5wYWNrZWRBQ29vcmRzU25pcHBldFtpbkFSYW5rIC0gMV0gPSAnaSoyJztcbiAgdW5wYWNrZWRBQ29vcmRzU25pcHBldC5qb2luKCcsICcpO1xuICB1bnBhY2tlZEJDb29yZHNTbmlwcGV0ID0gaW5CU2hhcGUubWFwKChzLCBpKSA9PiBgY29vcmRzLiR7YWxsR2xDaGFubmVsc1tpICsgcmFua0JEaWZmXX1gKTtcbiAgdW5wYWNrZWRCQ29vcmRzU25pcHBldFtpbkJSYW5rIC0gMl0gPSAnaSoyJztcbiAgdW5wYWNrZWRCQ29vcmRzU25pcHBldC5qb2luKCcsICcpO1xuXG4gIGNvbnN0IGJyb2FkY2FzdEFEaW1zID0gQnJvYWRjYXN0VXRpbC5nZXRCcm9hZGNhc3REaW1zKGluQVNoYXBlLCBvdXRTaGFwZSk7XG4gIGNvbnN0IGJyb2FkY2FzdEJEaW1zID0gQnJvYWRjYXN0VXRpbC5nZXRCcm9hZGNhc3REaW1zKGluQlNoYXBlLCBvdXRTaGFwZSk7XG5cbiAgY29uc3QgY29vcmRzQVNuaXBwZXQgPSBicm9hZGNhc3RBRGltcy5tYXAoZCA9PiBgY29vcmRzLiR7YWxsR2xDaGFubmVsc1tkICsgcmFua0FEaWZmXX0gPSAwO2ApLmpvaW4oJ1xcbicpO1xuICBjb25zdCBjb29yZHNCU25pcHBldCA9IGJyb2FkY2FzdEJEaW1zLm1hcChkID0+IGBjb29yZHMuJHthbGxHbENoYW5uZWxzW2QgKyByYW5rQkRpZmZdfSA9IDA7YCkuam9pbignXFxuJyk7XG4gIGNvbnN0IHN3YXBEaW1TbmlwcGV0ID0gYGludCBsYXN0RGltID0gY29vcmRzLiR7YWxsR2xDaGFubmVsc1tvdXRSYW5rIC0gMV19O1xuICBjb29yZHMuJHthbGxHbENoYW5uZWxzW291dFJhbmsgLSAxXX0gPSBjb29yZHMuJHthbGxHbENoYW5uZWxzW291dFJhbmsgLSAyXX07XG4gIGNvb3Jkcy4ke2FsbEdsQ2hhbm5lbHNbb3V0UmFuayAtIDJdfSA9IGxhc3REaW07YDtcblxuICBjb25zdCBnZXRCY2FzdFNhbXBsZXJNYXRtdWxTb3VyY2UgPSBgXG52ZWM0IGdldEFBdE91dENvb3Jkc01hdG11bChpbnQgaSkge1xuICAke2Nvb3Jkc0RhdGFUeXBlfSBjb29yZHMgPSBnZXRPdXRwdXRDb29yZHMoKTtcbiAgJHtzd2FwRGltU25pcHBldH1cbiAgJHtjb29yZHNBU25pcHBldH1cbiAgdmVjNCBvdXRwdXRWYWx1ZSA9IGdldEEoJHt1bnBhY2tlZEFDb29yZHNTbmlwcGV0fSk7XG4gIHJldHVybiBvdXRwdXRWYWx1ZTtcbn1cblxudmVjNCBnZXRCQXRPdXRDb29yZHNNYXRtdWwoaW50IGkpIHtcbiAgJHtjb29yZHNEYXRhVHlwZX0gY29vcmRzID0gZ2V0T3V0cHV0Q29vcmRzKCk7XG4gICR7c3dhcERpbVNuaXBwZXR9XG4gICR7Y29vcmRzQlNuaXBwZXR9XG4gIHZlYzQgb3V0cHV0VmFsdWUgPSBnZXRCKCR7dW5wYWNrZWRCQ29vcmRzU25pcHBldH0pO1xuICByZXR1cm4gb3V0cHV0VmFsdWU7XG59YDtcblxuICByZXR1cm4gZ2V0QmNhc3RTYW1wbGVyTWF0bXVsU291cmNlO1xufVxuXG5mdW5jdGlvbiBnZXRBKGFsbEdsQ2hhbm5lbHM6IHN0cmluZ1tdLCByYW5rOiBudW1iZXIpOiBzdHJpbmcge1xuICBsZXQgcmVzID0gJyc7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuayAtIDI7IGkrKykge1xuICAgIHJlcyArPSBgcmMuJHthbGxHbENoYW5uZWxzW2ldfSwgYDtcbiAgfVxuICByZXMgKz0gYHJjLiR7YWxsR2xDaGFubmVsc1tyYW5rIC0gMl19LCBgICtcbiAgICAgICdpKjInO1xuICByZXR1cm4gcmVzO1xufVxuXG5mdW5jdGlvbiBnZXRCKGFsbEdsQ2hhbm5lbHM6IHN0cmluZ1tdLCByYW5rOiBudW1iZXIpOiBzdHJpbmcge1xuICBsZXQgcmVzID0gJyc7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuayAtIDI7IGkrKykge1xuICAgIHJlcyArPSBgcmMuJHthbGxHbENoYW5uZWxzW2ldfSwgYDtcbiAgfVxuICByZXMgKz0gJ2kqMiwgJyArXG4gICAgICBgcmMuJHthbGxHbENoYW5uZWxzW3JhbmsgLSAxXX1gO1xuICByZXR1cm4gcmVzO1xufVxuIiwiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7R3JhcGh9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7T3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbn0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7VGVuc29yfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHtCcm9hZGNhc3RVdGlsLCBTaGFwZVV0aWx9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHtXZWJHTEluZmVyZW5jZUhhbmRsZXJ9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7UHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlfSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQge2dldENvb3Jkc0RhdGFUeXBlLCBnZXRHbENoYW5uZWxzfSBmcm9tICcuLi91dGlscyc7XG5cbmltcG9ydCB7Z2V0QWN0aXZhdGlvblNuaXBwZXQsIEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMsIHBhcnNlSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlc30gZnJvbSAnLi9mdXNlLXV0aWxzJztcbmltcG9ydCB7Y3JlYXRlUGFja2VkTWF0bXVsUHJvZ3JhbUluZm9Mb2FkZXJ9IGZyb20gJy4vbWF0bXVsLXBhY2snO1xuXG5leHBvcnQgY29uc3QgbWF0TXVsOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXM+ID1cbiAgICAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzKTogVGVuc29yW10gPT4ge1xuICAgICAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcblxuICAgICAgaWYgKGluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5wYWNrKSB7XG4gICAgICAgIHJldHVybiBbaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgICAgICAgICBjcmVhdGVQYWNrZWRNYXRtdWxQcm9ncmFtSW5mb0xvYWRlcihpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMpLCBpbnB1dHMpXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBbaW5mZXJlbmNlSGFuZGxlci5ydW4oY3JlYXRlTWF0bXVsUHJvZ3JhbUluZm9Mb2FkZXIoaW5wdXRzLCBhdHRyaWJ1dGVzKSwgaW5wdXRzKV07XG4gICAgICB9XG4gICAgfTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlTWF0TXVsQXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzPiA9XG4gICAgKG5vZGU6IEdyYXBoLk5vZGUpOiBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzID0+IHBhcnNlSW50ZXJuYWxBY3RpdmF0aW9uQXR0cmlidXRlcyhub2RlLmF0dHJpYnV0ZXMpO1xuXG5jb25zdCBjcmVhdGVNYXRtdWxQcm9ncmFtTWV0YWRhdGEgPSAoaGFzQmlhczogYm9vbGVhbiwgY2FjaGVIaW50OiBzdHJpbmcpID0+ICh7XG4gIG5hbWU6ICdNYXRNdWwnLFxuICBpbnB1dE5hbWVzOiBoYXNCaWFzID8gWydBJywgJ0InLCAnQmlhcyddIDogWydBJywgJ0InXSxcbiAgaW5wdXRUeXBlczogaGFzQmlhcyA/IFtUZXh0dXJlVHlwZS51bnBhY2tlZCwgVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnVucGFja2VkXSA6XG4gICAgICAgICAgICAgICAgICAgICAgICBbVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnVucGFja2VkXSxcbiAgY2FjaGVIaW50XG59KTtcblxuZnVuY3Rpb24gY3JlYXRlTWF0bXVsUHJvZ3JhbUluZm8oXG4gICAgbWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSwgaW5wdXRzOiBUZW5zb3JbXSwgYWN0aXZhdGlvbkF0dHJpYnV0ZXM6IEludGVybmFsQWN0aXZhdGlvbkF0dHJpYnV0ZXMpOiBQcm9ncmFtSW5mbyB7XG4gIGNvbnN0IGFTaGFwZSA9IGlucHV0c1swXS5kaW1zO1xuICBjb25zdCBiU2hhcGUgPSBpbnB1dHNbMV0uZGltcztcbiAgY29uc3Qgb3V0cHV0U2hhcGUgPSBCcm9hZGNhc3RVdGlsLmNhbGNTaGFwZShhU2hhcGUsIGJTaGFwZSwgdHJ1ZSk7XG4gIGlmICghb3V0cHV0U2hhcGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NhblxcJ3QgdXNlIG1hdG11bCBvbiB0aGUgZ2l2ZW4gdGVuc29ycycpO1xuICB9XG4gIGNvbnN0IGNvb3Jkc0RhdGFUeXBlID0gZ2V0Q29vcmRzRGF0YVR5cGUob3V0cHV0U2hhcGUubGVuZ3RoKTtcbiAgY29uc3QgYWxsR2xDaGFubmVscyA9IGdldEdsQ2hhbm5lbHMoKTtcbiAgY29uc3Qge2FjdGl2YXRpb25GdW5jdGlvbiwgYXBwbHlBY3RpdmF0aW9ufSA9IGdldEFjdGl2YXRpb25TbmlwcGV0KGFjdGl2YXRpb25BdHRyaWJ1dGVzKTtcblxuICBjb25zdCBoYXNCaWFzID0gaW5wdXRzLmxlbmd0aCA+IDI7XG4gIGNvbnN0IHByb2Nlc3NCaWFzID0gaGFzQmlhcyA/ICd2YWx1ZSArPSBnZXRCaWFzRm9yTWF0bXVsKCk7JyA6ICcnO1xuICBjb25zdCBnZXRCaWFzRm9yTWF0bXVsU25pcHBldCA9XG4gICAgICBoYXNCaWFzID8gYCR7Z2V0Qmlhc0Zvck1hdG11bChjb29yZHNEYXRhVHlwZSwgYWxsR2xDaGFubmVscywgaW5wdXRzWzJdLmRpbXMsIG91dHB1dFNoYXBlLCBmYWxzZSl9YCA6ICcnO1xuXG4gIGNvbnN0IHJhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG4gIGNvbnN0IGFyYW5rID0gYVNoYXBlLmxlbmd0aDtcbiAgY29uc3QgYnJhbmsgPSBiU2hhcGUubGVuZ3RoO1xuICBjb25zdCBzaGFyZWREaW0gPSBhU2hhcGVbYVNoYXBlLmxlbmd0aCAtIDFdO1xuICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgJHthY3RpdmF0aW9uRnVuY3Rpb259XG4gICAgJHtnZXRCaWFzRm9yTWF0bXVsU25pcHBldH1cbiAgICBmbG9hdCBwcm9jZXNzKGludCBpbmRpY2VzWyR7cmFua31dKSB7XG4gICAgICAgIGludCBhWyR7YXJhbmt9XTtcbiAgICAgICAgaW50IGJbJHticmFua31dO1xuICAgICAgICBiY2FzdE1hdG11bEluZGljZXNfQShpbmRpY2VzLCBhKTtcbiAgICAgICAgYmNhc3RNYXRtdWxJbmRpY2VzX0IoaW5kaWNlcywgYik7XG5cbiAgICAgICAgZmxvYXQgdmFsdWU7XG4gICAgICAgIGZvciAoaW50IGs9MDsgazwke3NoYXJlZERpbX07ICsraykge1xuICAgICAgICAgICAgYVske2FyYW5rIC0gMX1dID0gaztcbiAgICAgICAgICAgIGJbJHticmFuayAtIDJ9XSA9IGs7XG4gICAgICAgICAgICB2YWx1ZSArPSBfQShhKSAqIF9CKGIpO1xuICAgICAgICB9XG4gICAgICAgICR7cHJvY2Vzc0JpYXN9XG4gICAgICAgICR7YXBwbHlBY3RpdmF0aW9ufVxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfWA7XG4gIHJldHVybiB7XG4gICAgLi4ubWV0YWRhdGEsXG4gICAgb3V0cHV0OiB7ZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWR9LFxuICAgIHNoYWRlclNvdXJjZSxcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZU1hdG11bFByb2dyYW1JbmZvTG9hZGVyKFxuICAgIGlucHV0czogVGVuc29yW10sIGFjdGl2YXRpb25BdHRyaWJ1dGVzOiBJbnRlcm5hbEFjdGl2YXRpb25BdHRyaWJ1dGVzKTogUHJvZ3JhbUluZm9Mb2FkZXIge1xuICBjb25zdCBtZXRhZGF0YSA9IGNyZWF0ZU1hdG11bFByb2dyYW1NZXRhZGF0YShpbnB1dHMubGVuZ3RoID4gMiwgYWN0aXZhdGlvbkF0dHJpYnV0ZXMuYWN0aXZhdGlvbkNhY2hlS2V5KTtcbiAgcmV0dXJuIHsuLi5tZXRhZGF0YSwgZ2V0OiAoKSA9PiBjcmVhdGVNYXRtdWxQcm9ncmFtSW5mbyhtZXRhZGF0YSwgaW5wdXRzLCBhY3RpdmF0aW9uQXR0cmlidXRlcyl9O1xufVxuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ01hdE11bCByZXF1aXJlcyAyIGlucHV0cy4nKTtcbiAgfVxuXG4gIGlmIChpbnB1dHNbMF0uZGltc1tpbnB1dHNbMF0uZGltcy5sZW5ndGggLSAxXSAhPT0gaW5wdXRzWzFdLmRpbXNbaW5wdXRzWzFdLmRpbXMubGVuZ3RoIC0gMl0pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3NoYXJlZCBkaW1lbnNpb24gZG9lcyBub3QgbWF0Y2guJyk7XG4gIH1cblxuICBpZiAoKGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQzMicgJiYgaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDY0JykgfHxcbiAgICAgIChpbnB1dHNbMV0udHlwZSAhPT0gJ2Zsb2F0MzInICYmIGlucHV0c1sxXS50eXBlICE9PSAnZmxvYXQ2NCcpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnB1dHMgc2hvdWxkIGJlIGZsb2F0IHR5cGUnKTtcbiAgfVxuXG4gIGlmIChpbnB1dHNbMF0udHlwZSAhPT0gaW5wdXRzWzFdLnR5cGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2lucHV0cyB0eXBlcyBzaG91bGQgbWF0Y2gnKTtcbiAgfVxufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldEJpYXNGb3JNYXRtdWwoXG4gICAgY29vcmRzRGF0YVR5cGU6IHN0cmluZywgYWxsR2xDaGFubmVsczogcmVhZG9ubHkgc3RyaW5nW10sIGluU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCBvdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgaXNQYWNrZWQ6IGJvb2xlYW4pOiBzdHJpbmcge1xuICBsZXQgdW5wYWNrZWRDb29yZHNTbmlwcGV0ID0gJyc7XG4gIGNvbnN0IGluUmFuayA9IGluU2hhcGUubGVuZ3RoO1xuICBjb25zdCBvdXRSYW5rID0gb3V0U2hhcGUubGVuZ3RoO1xuICBjb25zdCByYW5rRGlmZiA9IG91dFJhbmsgLSBpblJhbms7XG4gIGlmIChvdXRSYW5rIDwgMiAmJiBpblJhbmsgPiAwKSB7XG4gICAgdW5wYWNrZWRDb29yZHNTbmlwcGV0ID0gJ2Nvb3Jkcyc7XG4gIH0gZWxzZSB7XG4gICAgdW5wYWNrZWRDb29yZHNTbmlwcGV0ID0gaW5TaGFwZS5tYXAoKHMsIGkpID0+IGBjb29yZHMuJHthbGxHbENoYW5uZWxzW2kgKyByYW5rRGlmZl19YCkuam9pbignLCAnKTtcbiAgfVxuICBjb25zdCBicm9hZGNhc3REaW1zID0gQnJvYWRjYXN0VXRpbC5nZXRCcm9hZGNhc3REaW1zKGluU2hhcGUsIG91dFNoYXBlKTtcbiAgY29uc3QgY29vcmRzU25pcHBldCA9IGJyb2FkY2FzdERpbXMubWFwKGQgPT4gYGNvb3Jkcy4ke2FsbEdsQ2hhbm5lbHNbZCArIHJhbmtEaWZmXX0gPSAwO2ApLmpvaW4oJ1xcbicpO1xuICBjb25zdCBpblNpemUgPSBTaGFwZVV0aWwuc2l6ZShpblNoYXBlKTtcbiAgY29uc3QgaXNJbnB1dFNjYWxhciA9IGluU2l6ZSA9PT0gMTtcbiAgbGV0IG91dHB1dCA9ICd2ZWM0KG91dHB1dFZhbHVlLnh4LCBvdXRwdXRWYWx1ZS55eSknO1xuICBpZiAoaXNJbnB1dFNjYWxhcikge1xuICAgIG91dHB1dCA9ICd2ZWM0KG91dHB1dFZhbHVlLngpJztcbiAgfVxuICBjb25zdCBnZXRCaWFzRm9yTWF0bXVsU291cmNlID0gaXNQYWNrZWQgPyBgXG52ZWM0IGdldEJpYXNGb3JNYXRtdWwoKSB7XG4gICR7Y29vcmRzRGF0YVR5cGV9IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpO1xuICAke2Nvb3Jkc1NuaXBwZXR9XG4gIHZlYzQgb3V0cHV0VmFsdWUgPSBnZXRCaWFzKCR7dW5wYWNrZWRDb29yZHNTbmlwcGV0fSk7XG4gIHJldHVybiAke291dHB1dH07XG59YCA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBcbmZsb2F0IGdldEJpYXNGb3JNYXRtdWwoKSB7XG4gICR7Y29vcmRzRGF0YVR5cGV9IGNvb3JkcyA9IGdldE91dHB1dENvb3JkcygpO1xuICAke2Nvb3Jkc1NuaXBwZXR9XG4gIHJldHVybiBnZXRCaWFzKGNvb3Jkcy54KTtcbn1gO1xuXG4gIHJldHVybiBnZXRCaWFzRm9yTWF0bXVsU291cmNlO1xufVxuIiwiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7VGVuc29yfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHtnZXRHbHNsfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQge1dlYkdMSW5mZXJlbmNlSGFuZGxlcn0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHtQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFRleHR1cmVUeXBlfSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQge2dldENvb3Jkc0RhdGFUeXBlfSBmcm9tICcuLi91dGlscyc7XG5cbmltcG9ydCB7Z2V0Q2hhbm5lbHN9IGZyb20gJy4vcGFja2luZy11dGlscyc7XG5cbmNvbnN0IHBhY2tQcm9ncmFtTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdwYWNrJyxcbiAgaW5wdXROYW1lczogWydBJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZFJldmVyc2VkXVxufTtcblxuY29uc3QgY3JlYXRlUGFja1Byb2dyYW1JbmZvID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXQ6IFRlbnNvcik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgZ2xzbCA9IGdldEdsc2woaGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICBjb25zdCBpbnB1dFNoYXBlID0gaW5wdXQuZGltcztcblxuICBjb25zdCBpbnB1dFJhbmsgPSBpbnB1dFNoYXBlLmxlbmd0aDtcbiAgLy8gY3JlYXRlVGV4dHVyZUxheW91dEZyb21TaGFwZSB3b24ndCBjaGFuZ2Ugb3V0cHV0IHJhbmsuIE5lZWQgdG8gdmVyaWZ5IGJ5IHJ1bm5pbmcgdGVzdHNcbiAgY29uc3Qgb3V0cHV0UmFuayA9IGlucHV0LmRpbXMubGVuZ3RoO1xuXG4gIGNvbnN0IGNvb3Jkc0RhdGFUeXBlID0gZ2V0Q29vcmRzRGF0YVR5cGUob3V0cHV0UmFuayk7XG4gIGNvbnN0IGNoYW5uZWxzID0gZ2V0Q2hhbm5lbHMoJ3JjJywgb3V0cHV0UmFuayk7XG4gIGNvbnN0IHNldHVwID0gZ2V0U2V0dXAob3V0cHV0UmFuaywgY2hhbm5lbHMsIGlucHV0U2hhcGVbaW5wdXRTaGFwZS5sZW5ndGggLSAyXSwgaW5wdXRTaGFwZVtpbnB1dFNoYXBlLmxlbmd0aCAtIDFdKTtcblxuICBsZXQgcmV2ZXJzZWRJbnB1dFdIO1xuICBpZiAoaW5wdXRSYW5rID09PSAwKSB7XG4gICAgcmV2ZXJzZWRJbnB1dFdIID0gWzEsIDFdO1xuICB9IGVsc2UgaWYgKGlucHV0UmFuayA9PT0gMSkge1xuICAgIHJldmVyc2VkSW5wdXRXSCA9IFtpbnB1dFNoYXBlWzBdLCAxXTtcbiAgfSBlbHNlIHtcbiAgICByZXZlcnNlZElucHV0V0ggPSBbaW5wdXRTaGFwZVtvdXRwdXRSYW5rIC0gMV0sIGlucHV0U2hhcGVbb3V0cHV0UmFuayAtIDJdXTtcbiAgfVxuICBjb25zdCBvdXRPZkJvdW5kc0NvbmRpdGlvbiA9IGdldE91dE9mQm91bmRzQ29uZGl0aW9uKG91dHB1dFJhbmssIHJldmVyc2VkSW5wdXRXSCwgY2hhbm5lbHMpO1xuICBjb25zdCBvdXRwdXQgPSBnZXRPdXRwdXQoaW5wdXRTaGFwZSwgY2hhbm5lbHMpO1xuXG4gIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgICAgdm9pZCBtYWluKCkge1xuICAgICAgICAgICR7Y29vcmRzRGF0YVR5cGV9IHJjID0gZ2V0T3V0cHV0Q29vcmRzKCk7XG5cbiAgICAgICAgICBpZigke291dE9mQm91bmRzQ29uZGl0aW9ufSkge1xuICAgICAgICAgICAgJHtnbHNsLm91dHB1dH0gPSB2ZWM0KDApO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAke3NldHVwfVxuXG4gICAgICAgICAgICAke2dsc2wub3V0cHV0fSA9IHZlYzQoJHtvdXRwdXR9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIGA7XG4gIHJldHVybiB7XG4gICAgLi4ucGFja1Byb2dyYW1NZXRhZGF0YSxcbiAgICBoYXNNYWluOiB0cnVlLFxuICAgIG91dHB1dDoge2RpbXM6IGlucHV0LmRpbXMsIHR5cGU6IGlucHV0LnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS5wYWNrZWR9LFxuICAgIHNoYWRlclNvdXJjZVxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZVBhY2tQcm9ncmFtSW5mb0xvYWRlciA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0OiBUZW5zb3IpOiBQcm9ncmFtSW5mb0xvYWRlciA9PlxuICAgICh7Li4ucGFja1Byb2dyYW1NZXRhZGF0YSwgZ2V0OiAoKSA9PiBjcmVhdGVQYWNrUHJvZ3JhbUluZm8oaGFuZGxlciwgaW5wdXQpfSk7XG5cbi8qKlxuICogY2hlY2sgb3V0cHV0IGNvb3JkaW5hdGUgbG9jYXRpb24gYW5kIHJldHVybiBmYWxzZSBpZiBpdCBpcyBvdXRzaWRlIGlucHV0J3Mgd2lkdGgvaGVpZ2h0IGJvdW5kYXJ5XG4gKi9cbmZ1bmN0aW9uIGdldE91dE9mQm91bmRzQ29uZGl0aW9uKHJhbms6IG51bWJlciwgc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCBkaW1zOiBzdHJpbmdbXSk6IHN0cmluZyB7XG4gIGlmIChyYW5rID09PSAwKSB7XG4gICAgcmV0dXJuICdmYWxzZSc7XG4gIH1cbiAgaWYgKHJhbmsgPT09IDEpIHtcbiAgICByZXR1cm4gYHJjID4gJHtzaGFwZVswXX1gO1xuICB9XG5cbiAgbGV0IGNvbmQgPSAnJztcbiAgZm9yIChsZXQgaSA9IHJhbmsgLSAyOyBpIDwgcmFuazsgaSsrKSB7XG4gICAgY29uZCArPSBgJHtkaW1zW2ldfSA+PSAke3NoYXBlW2kgLSByYW5rICsgMl19YDtcbiAgICBpZiAoaSA8IHJhbmsgLSAxKSB7XG4gICAgICBjb25kICs9ICd8fCc7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGNvbmQ7XG59XG5cbi8qKlxuICogY29kZSBzbmlwcGV0IHRvIHNhbXBsZSBpbnB1dCB0ZXh0dXJlIHdpdGggb3V0cHV0IGNvb3JkaWFudGVzXG4gKi9cbmZ1bmN0aW9uIGdldE91dHB1dChzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIGRpbXM6IHN0cmluZ1tdKTogc3RyaW5nIHtcbiAgY29uc3QgcmFuayA9IHNoYXBlLmxlbmd0aDtcblxuICBpZiAocmFuayA9PT0gMCkge1xuICAgIHJldHVybiAnZ2V0QSgpLCAwLCAwLCAwJztcbiAgfVxuXG4gIGlmIChyYW5rID09PSAxKSB7XG4gICAgcmV0dXJuIGBnZXRBKHJjKSxcbiAgICAgICAgICAgIHJjICsgMSA+PSAke3NoYXBlWzBdfSA/IDAuIDogZ2V0QShyYyArIDEpLFxuICAgICAgICAgICAgMCwgMGA7XG4gIH1cblxuICBjb25zdCBjb29yZDAwID0gJ3IsIGMnO1xuICBjb25zdCBjb29yZDAxID0gJ3IsIGNwMSc7XG4gIGNvbnN0IGNvb3JkMTAgPSAncnAxLCBjJztcbiAgY29uc3QgY29vcmQxMSA9ICdycDEsIGNwMSc7XG4gIGxldCBEID0gJyc7XG4gIGlmIChyYW5rID4gMikge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuayAtIDI7ICsraSkge1xuICAgICAgRCA9IEQgKyBgJHtkaW1zW2ldfSxgO1xuICAgIH1cbiAgfVxuICByZXR1cm4gYGdldEEoJHtEfSR7Y29vcmQwMH0pLFxuICAgICAgICAgIHJFZGdlID8gMC4gOiBnZXRBKCR7RH0ke2Nvb3JkMTB9KSxcbiAgICAgICAgICBjRWRnZSA/IDAuIDogZ2V0QSgke0R9JHtjb29yZDAxfSksXG4gICAgICAgICAgckVkZ2UgfHwgY0VkZ2UgPyAwLiA6IGdldEEoJHtEfSR7Y29vcmQxMX0pYDtcbn1cblxuLyoqXG4gKiBjb2RlIHNuaXBwZXQgdG8gc2V0dXAgNCBjb29yZGluYXRlcyBhbmQgZWRnZSBjb25kaXRpb25zXG4gKi9cbmZ1bmN0aW9uIGdldFNldHVwKHJhbms6IG51bWJlciwgZGltczogc3RyaW5nW10sIHJvd3M6IG51bWJlciwgY29sczogbnVtYmVyKTogc3RyaW5nIHtcbiAgaWYgKHJhbmsgPT09IDAgfHwgcmFuayA9PT0gMSkge1xuICAgIHJldHVybiAnJztcbiAgfVxuICAvLyByYW5rID49IDIgZm9yIHdpZHRoK2hlaWdodCBwYWNrLlxuICBlbHNlIHtcbiAgICBjb25zdCBzZXR1cCA9IGBcbiAgICBpbnQgciA9ICR7ZGltc1tyYW5rIC0gMl19O1xuICAgIGludCBjID0gJHtkaW1zW3JhbmsgLSAxXX07XG4gICAgaW50IHJwMSA9ICR7ZGltc1tyYW5rIC0gMl19ICsgMTtcbiAgICBpbnQgY3AxID0gJHtkaW1zW3JhbmsgLSAxXX0gKyAxO1xuICAgIGJvb2wgckVkZ2UgPSBycDEgPj0gJHtjb2xzfTtcbiAgICBib29sIGNFZGdlID0gY3AxID49ICR7cm93c307XG4gICAgYDtcbiAgICByZXR1cm4gc2V0dXA7XG4gIH1cbn1cbiIsIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge2dldEdsQ2hhbm5lbHN9IGZyb20gJy4uL3V0aWxzJztcblxuZXhwb3J0IGZ1bmN0aW9uIGdldFZlY0NoYW5uZWxzKG5hbWU6IHN0cmluZywgcmFuazogbnVtYmVyKTogc3RyaW5nW10ge1xuICByZXR1cm4gZ2V0R2xDaGFubmVscyhyYW5rKS5tYXAoZCA9PiBgJHtuYW1lfS4ke2R9YCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDaGFubmVscyhuYW1lOiBzdHJpbmcsIHJhbms6IG51bWJlcik6IHN0cmluZ1tdIHtcbiAgaWYgKHJhbmsgPT09IDEpIHtcbiAgICByZXR1cm4gW25hbWVdO1xuICB9XG4gIHJldHVybiBnZXRWZWNDaGFubmVscyhuYW1lLCByYW5rKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHVucGFja0Zyb21DaGFubmVsKCk6IHN0cmluZyB7XG4gIHJldHVybiBgXG4gICAgZmxvYXQgZ2V0Q2hhbm5lbCh2ZWM0IGZyYWcsIGludCBkaW0pIHtcbiAgICAgIGludCBtb2RDb29yZCA9IGltb2QoZGltLCAyKTtcbiAgICAgIHJldHVybiBtb2RDb29yZCA9PSAwID8gZnJhZy5yIDogZnJhZy5nO1xuICAgIH1cblxuICAgIGZsb2F0IGdldENoYW5uZWwodmVjNCBmcmFnLCB2ZWMyIGlubmVyRGltcykge1xuICAgICAgdmVjMiBtb2RDb29yZCA9IG1vZChpbm5lckRpbXMsIDIuKTtcbiAgICAgIHJldHVybiBtb2RDb29yZC54ID09IDAuID9cbiAgICAgICAgKG1vZENvb3JkLnkgPT0gMC4gPyBmcmFnLnIgOiBmcmFnLmcpIDpcbiAgICAgICAgKG1vZENvb3JkLnkgPT0gMC4gPyBmcmFnLmIgOiBmcmFnLmEpO1xuICAgIH1cbiAgYDtcbn1cbiIsIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge0F0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5fSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHtHcmFwaH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHtPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9ufSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHtUZW5zb3J9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQge1NoYXBlVXRpbH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQge2dldEdsc2wsIEdsc2x9IGZyb20gJy4uL2dsc2wtc291cmNlJztcbmltcG9ydCB7V2ViR0xJbmZlcmVuY2VIYW5kbGVyfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQge1Byb2dyYW1JbmZvLCBUZXh0dXJlVHlwZX0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFBhZEF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBtb2RlOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHBhZHM6IG51bWJlcltdO1xuICByZWFkb25seSB2YWx1ZTogbnVtYmVyO1xufVxuXG5jb25zdCBwYWRQcm9ncmFtTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdQYWQnLFxuICBpbnB1dE5hbWVzOiBbJ0EnXSxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkXSxcbn07XG5cbmV4cG9ydCBjb25zdCBwYWRWMjogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxQYWRBdHRyaWJ1dGVzPiA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogUGFkQXR0cmlidXRlcyk6IFRlbnNvcltdID0+IHtcbiAgICAgIHZhbGlkYXRlSW5wdXRzVjIoaW5wdXRzKTtcbiAgICAgIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIC4uLnBhZFByb2dyYW1NZXRhZGF0YSxcbiAgICAgICAgICAgIGNhY2hlSGludDogYXR0cmlidXRlcy5jYWNoZUtleSxcbiAgICAgICAgICAgIGdldDogKCkgPT4gY3JlYXRlUGFkUHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzWzBdLCBhdHRyaWJ1dGVzKVxuICAgICAgICAgIH0sXG4gICAgICAgICAgaW5wdXRzKTtcbiAgICAgIHJldHVybiBbb3V0cHV0XTtcbiAgICB9O1xuXG5leHBvcnQgY29uc3QgcGFyc2VQYWRBdHRyaWJ1dGVzVjI6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248UGFkQXR0cmlidXRlcz4gPSAobm9kZTogR3JhcGguTm9kZSk6IFBhZEF0dHJpYnV0ZXMgPT4ge1xuICBjb25zdCBtb2RlID0gbm9kZS5hdHRyaWJ1dGVzLmdldFN0cmluZygnbW9kZScsICdjb25zdGFudCcpO1xuICBjb25zdCB2YWx1ZSA9IG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdCgndmFsdWUnLCAwLjApO1xuICBjb25zdCBwYWRzID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludHMoJ3BhZHMnKTtcbiAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7bW9kZSwgdmFsdWUsIHBhZHN9KTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYWRWMTE6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248c3RyaW5nPiA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgbW9kZTogc3RyaW5nKTogVGVuc29yW10gPT4ge1xuICAgICAgdmFsaWRhdGVJbnB1dHNWMTEoaW5wdXRzKTtcbiAgICAgIGNvbnN0IGF0dHJ1YnV0ZXMgPSBnZW5lcmF0ZVBhZEF0dHJpYnV0ZXNGcm9tSW5wdXRzKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgbW9kZSk7XG4gICAgICByZXR1cm4gcGFkVjIoaW5mZXJlbmNlSGFuZGxlciwgW2lucHV0c1swXV0sIGF0dHJ1YnV0ZXMpO1xuICAgIH07XG5cbmV4cG9ydCBjb25zdCBwYXJzZVBhZEF0dHJpYnV0ZXNWMTE6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248c3RyaW5nPiA9IChub2RlOiBHcmFwaC5Ob2RlKTogc3RyaW5nID0+XG4gICAgbm9kZS5hdHRyaWJ1dGVzLmdldFN0cmluZygnbW9kZScsICdjb25zdGFudCcpO1xuXG5jb25zdCBnZW5lcmF0ZVBhZEF0dHJpYnV0ZXNGcm9tSW5wdXRzID1cbiAgICAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdLCBtb2RlOiBzdHJpbmcpOiBQYWRBdHRyaWJ1dGVzID0+IHtcbiAgICAgIGlmICghaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmlzSW5pdGlhbGl6ZXIoaW5wdXRzWzFdLmRhdGFJZCkgfHxcbiAgICAgICAgICAoaW5wdXRzLmxlbmd0aCA+PSAzICYmICFpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uaXNJbml0aWFsaXplcihpbnB1dHNbMl0uZGF0YUlkKSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdkeW5hbWljIHBhZCBhdHRyaWJ1dGVzIGFyZSBub3QgYWxsb3dlZCcpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBwYWRzID0gQXJyYXkuZnJvbShpbnB1dHNbMV0uaW50ZWdlckRhdGEpO1xuICAgICAgY29uc3QgdmFsdWUgPSAoaW5wdXRzLmxlbmd0aCA+PSAzKSA/IGlucHV0c1syXS5mbG9hdERhdGFbMF0gOiAwLjA7XG5cbiAgICAgIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoe21vZGUsIHBhZHMsIHZhbHVlfSk7XG4gICAgfTtcblxuY29uc3QgY3JlYXRlUGFkUHJvZ3JhbUluZm8gPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0OiBUZW5zb3IsIGF0dHJpYnV0ZXM6IFBhZEF0dHJpYnV0ZXMpOiBQcm9ncmFtSW5mbyA9PiB7XG4gICAgICBjb25zdCBvdXRwdXRTaGFwZSA9IFNoYXBlVXRpbC5wYWRTaGFwZShpbnB1dC5kaW1zLnNsaWNlKCksIGF0dHJpYnV0ZXMucGFkcyk7XG4gICAgICBjb25zdCByYW5rID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuICAgICAgY29uc3QgcGFkRnVuY3Rpb24gPSBnZXRQYWRGdW5jdGlvbihpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dCwgYXR0cmlidXRlcyk7XG4gICAgICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICAke3BhZEZ1bmN0aW9ufVxuICAgICAgZmxvYXQgcHJvY2VzcyhpbnRbJHtyYW5rfV0gaW5kaWNlcykge1xuICAgICAgICAgIHJldHVybiBwYWRBKGluZGljZXMpO1xuICAgICAgfWA7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBuYW1lOiAnUGFkJyxcbiAgICAgICAgaW5wdXROYW1lczogWydBJ10sXG4gICAgICAgIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG4gICAgICAgIG91dHB1dDoge2RpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dC50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWR9LFxuICAgICAgICBzaGFkZXJTb3VyY2VcbiAgICAgIH07XG4gICAgfTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHNWMiA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1BhZCByZXF1aXJlcyAxIGlucHV0Jyk7XG4gIH1cbiAgaWYgKGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQzMicgJiYgaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDY0Jykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG59O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0c1YxMSA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IChpbnB1dHMubGVuZ3RoICE9PSAyICYmIGlucHV0cy5sZW5ndGggIT09IDMpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdQYWQgcmVxdWlyZXMgMiBvciAzIGlucHV0cycpO1xuICB9XG4gIGlmIChpbnB1dHNbMV0udHlwZSAhPT0gJ2ludDMyJykge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG4gIGlmIChpbnB1dHMubGVuZ3RoID49IDMgJiYgaW5wdXRzWzJdLnR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbn07XG5cbmNvbnN0IGdldFBhZEZ1bmN0aW9uID0gKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXQ6IFRlbnNvciwgYXR0cmlidXRlczogUGFkQXR0cmlidXRlcyk6IHN0cmluZyA9PiB7XG4gIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgY29uc3QgW3dpZHRoLCBoZWlnaHRdID0gaW5mZXJlbmNlSGFuZGxlci5jYWxjdWxhdGVUZXh0dXJlV2lkdGhBbmRIZWlnaHQoaW5wdXQuZGltcywgVGV4dHVyZVR5cGUudW5wYWNrZWQpO1xuICBjb25zdCBzdHJpZGVzID0gU2hhcGVVdGlsLmNvbXB1dGVTdHJpZGVzKGlucHV0LmRpbXMpO1xuXG4gIHN3aXRjaCAoYXR0cmlidXRlcy5tb2RlKSB7XG4gICAgY2FzZSAnY29uc3RhbnQnOlxuICAgICAgcmV0dXJuIGdldFBhZENvbnN0YW50KGdsc2wsIGlucHV0LmRpbXMsIHN0cmlkZXMsIHdpZHRoLCBoZWlnaHQsIGF0dHJpYnV0ZXMucGFkcywgYXR0cmlidXRlcy52YWx1ZSk7XG4gICAgY2FzZSAncmVmbGVjdCc6XG4gICAgICByZXR1cm4gZ2V0UGFkUmVmbGVjdChnbHNsLCBpbnB1dC5kaW1zLCBzdHJpZGVzLCB3aWR0aCwgaGVpZ2h0LCBhdHRyaWJ1dGVzLnBhZHMpO1xuICAgIGNhc2UgJ2VkZ2UnOlxuICAgICAgcmV0dXJuIGdldFBhZEVkZ2UoZ2xzbCwgaW5wdXQuZGltcywgc3RyaWRlcywgd2lkdGgsIGhlaWdodCwgYXR0cmlidXRlcy5wYWRzKTtcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIG1vZGUnKTtcbiAgfVxufTtcblxuY29uc3QgZ2V0UGFkQ29uc3RhbnQgPVxuICAgIChnbHNsOiBHbHNsLCBzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIHN0cmlkZXM6IHJlYWRvbmx5IG51bWJlcltdLCB3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlciwgcGFkczogbnVtYmVyW10sXG4gICAgIHZhbHVlOiBudW1iZXIpOiBzdHJpbmcgPT4ge1xuICAgICAgY29uc3QgcmFuayA9IHNoYXBlLmxlbmd0aDtcbiAgICAgIGxldCBibG9jayA9ICcnO1xuICAgICAgZm9yIChsZXQgaSA9IHJhbmsgLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgICBibG9jayArPSBgXG4gICAgICAgIGsgPSBtWyR7aX1dIC0gJHtwYWRzW2ldfTtcbiAgICAgICAgaWYgKGsgPCAwKSAgcmV0dXJuIGNvbnN0YW50O1xuICAgICAgICBpZiAoayA+PSAke3NoYXBlW2ldfSkgcmV0dXJuIGNvbnN0YW50O1xuICAgICAgICBvZmZzZXQgKz0gayAqICR7c3RyaWRlc1tpXX07XG4gICAgICAgIGA7XG4gICAgICB9XG4gICAgICByZXR1cm4gYFxuICAgICAgZmxvYXQgcGFkQShpbnQgbVske3Jhbmt9XSkge1xuICAgICAgICBjb25zdCBmbG9hdCBjb25zdGFudCA9IGZsb2F0KCR7dmFsdWV9KTtcbiAgICAgICAgaW50IG9mZnNldCA9IDA7XG4gICAgICAgIGludCBrID0gMDtcbiAgICAgICAgJHtibG9ja31cbiAgICAgICAgdmVjMiBjb29yZHMgPSBvZmZzZXRUb0Nvb3JkcyhvZmZzZXQsICR7d2lkdGh9LCAke2hlaWdodH0pO1xuICAgICAgICBmbG9hdCB2YWx1ZSA9IGdldENvbG9yQXNGbG9hdCgke2dsc2wudGV4dHVyZTJEfShBLCBjb29yZHMpKTtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgfVxuICAgICAgYDtcbiAgICB9O1xuXG5jb25zdCBnZXRQYWRSZWZsZWN0ID1cbiAgICAoZ2xzbDogR2xzbCwgc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCBzdHJpZGVzOiByZWFkb25seSBudW1iZXJbXSwgd2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIsIHBhZHM6IG51bWJlcltdKTpcbiAgICAgICAgc3RyaW5nID0+IHtcbiAgICAgICAgICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuXG4gICAgICAgICAgbGV0IGJsb2NrID0gJyc7XG4gICAgICAgICAgZm9yIChsZXQgaSA9IHJhbmsgLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgICAgICAgYmxvY2sgKz0gYFxuICAgICAgICBrID0gbVske2l9XSAtICR7cGFkc1tpXX07XG4gICAgICAgIGlmIChrIDwgMCkgeyBrID0gLWs7IH1cbiAgICAgICAge1xuICAgICAgICAgIGNvbnN0IGludCBfMm5fMSA9ICR7MiAqIChzaGFwZVtpXSAtIDEpfTtcbiAgICAgICAgICBrID0gaW50KCBtb2QoIGZsb2F0KGspLCBmbG9hdChfMm5fMSkgKSApIDtcbiAgICAgICAgICBpZihrID49ICR7c2hhcGVbaV19KSB7IGsgPSBfMm5fMSAtIGs7IH1cbiAgICAgICAgfVxuICAgICAgICBvZmZzZXQgKz0gayAqICR7c3RyaWRlc1tpXX07XG4gICAgICAgIGA7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBgXG4gICAgICBmbG9hdCBwYWRBKGludCBtWyR7cmFua31dKSB7XG4gICAgICAgIGludCBvZmZzZXQgPSAwO1xuICAgICAgICBpbnQgayA9IDA7XG4gICAgICAgICR7YmxvY2t9XG4gICAgICAgIHZlYzIgY29vcmRzID0gb2Zmc2V0VG9Db29yZHMob2Zmc2V0LCAke3dpZHRofSwgJHtoZWlnaHR9KTtcbiAgICAgICAgZmxvYXQgdmFsdWUgPSBnZXRDb2xvckFzRmxvYXQoJHtnbHNsLnRleHR1cmUyRH0oQSwgY29vcmRzKSk7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIGA7XG4gICAgICAgIH07XG5cbmNvbnN0IGdldFBhZEVkZ2UgPVxuICAgIChnbHNsOiBHbHNsLCBzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIHN0cmlkZXM6IHJlYWRvbmx5IG51bWJlcltdLCB3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlciwgcGFkczogbnVtYmVyW10pOlxuICAgICAgICBzdHJpbmcgPT4ge1xuICAgICAgICAgIGNvbnN0IHJhbmsgPSBzaGFwZS5sZW5ndGg7XG5cbiAgICAgICAgICBsZXQgYmxvY2sgPSAnJztcbiAgICAgICAgICBmb3IgKGxldCBpID0gcmFuayAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgICAgICBibG9jayArPSBgXG4gICAgICAgIGsgPSBtWyR7aX1dIC0gJHtwYWRzW2ldfTtcbiAgICAgICAgaWYgKGsgPCAwKSAgayA9IDA7XG4gICAgICAgIGlmIChrID49ICR7c2hhcGVbaV19KSBrID0gJHtzaGFwZVtpXSAtIDF9O1xuICAgICAgICBvZmZzZXQgKz0gayAqICR7c3RyaWRlc1tpXX07XG4gICAgICBgO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gYFxuICAgICAgZmxvYXQgcGFkQShpbnQgbVske3Jhbmt9XSkge1xuICAgICAgICBpbnQgb2Zmc2V0ID0gMDtcbiAgICAgICAgaW50IGsgPSAwO1xuICAgICAgICAke2Jsb2NrfVxuICAgICAgICB2ZWMyIGNvb3JkcyA9IG9mZnNldFRvQ29vcmRzKG9mZnNldCwgJHt3aWR0aH0sICR7aGVpZ2h0fSk7XG4gICAgICAgIGZsb2F0IHZhbHVlID0gZ2V0Q29sb3JBc0Zsb2F0KCR7Z2xzbC50ZXh0dXJlMkR9KEEsIGNvb3JkcykpO1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9XG4gICAgICBgO1xuICAgICAgICB9O1xuIiwiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7QXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXl9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQge0dyYXBofSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQge09wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb259IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7UG9vbENvbnZVdGlsLCBTaGFwZVV0aWx9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHtXZWJHTEluZmVyZW5jZUhhbmRsZXJ9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7UHJvZ3JhbUluZm8sIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGV9IGZyb20gJy4uL3R5cGVzJztcblxuZXhwb3J0IGludGVyZmFjZSBBdmVyYWdlUG9vbEF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBhdXRvUGFkOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGNlaWxNb2RlOiBudW1iZXI7XG4gIHJlYWRvbmx5IGNvdW50SW5jbHVkZVBhZDogYm9vbGVhbjtcbiAgcmVhZG9ubHkga2VybmVsU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdO1xuICByZWFkb25seSBzdHJpZGVzOiByZWFkb25seSBudW1iZXJbXTtcbiAgcmVhZG9ubHkgcGFkczogcmVhZG9ubHkgbnVtYmVyW107XG59XG5cbmV4cG9ydCBjb25zdCBhdmVyYWdlUG9vbDogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxBdmVyYWdlUG9vbEF0dHJpYnV0ZXM+ID1cbiAgICAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBBdmVyYWdlUG9vbEF0dHJpYnV0ZXMpOiBUZW5zb3JbXSA9PiB7XG4gICAgICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuICAgICAgY29uc3QgbWV0YWRhdGEgPVxuICAgICAgICAgIHtuYW1lOiAnQXZlcmFnZVBvb2wnLCBpbnB1dE5hbWVzOiBbJ1gnXSwgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkXSwgY2FjaGVIaW50OiBhdHRyaWJ1dGVzLmNhY2hlS2V5fTtcbiAgICAgIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgICAgICAgIHsuLi5tZXRhZGF0YSwgZ2V0OiAoKSA9PiBjcmVhdGVBdmVyYWdlUG9vbFByb2dyYW1JbmZvKGlucHV0cywgbWV0YWRhdGEsIGZhbHNlLCBhdHRyaWJ1dGVzKX0sIGlucHV0cyk7XG4gICAgICByZXR1cm4gW291dHB1dF07XG4gICAgfTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlQXZlcmFnZVBvb2xBdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPEF2ZXJhZ2VQb29sQXR0cmlidXRlcz4gPVxuICAgIChub2RlOiBHcmFwaC5Ob2RlKTogQXZlcmFnZVBvb2xBdHRyaWJ1dGVzID0+IHtcbiAgICAgIGNvbnN0IGF1dG9QYWQgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0U3RyaW5nKCdhdXRvX3BhZCcsICdOT1RTRVQnKTtcbiAgICAgIGNvbnN0IGNlaWxNb2RlID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludCgnY2VpbF9tb2RlJywgMCk7XG4gICAgICBjb25zdCBjb3VudEluY2x1ZGVQYWQgPSAobm9kZS5hdHRyaWJ1dGVzLmdldEludCgnY291bnRfaW5jbHVkZV9wYWQnLCAwKSA9PT0gMCA/IGZhbHNlIDogdHJ1ZSk7XG4gICAgICBjb25zdCBrZXJuZWxTaGFwZSA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnRzKCdrZXJuZWxfc2hhcGUnKTtcbiAgICAgIGNvbnN0IHN0cmlkZXMgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50cygnc3RyaWRlcycsIFtdKTtcbiAgICAgIGNvbnN0IHBhZHMgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50cygncGFkcycsIFtdKTtcblxuICAgICAgLy8gVE9ETzogc3VwcG9ydCBhdHRyaWJ1dGUgJ2NlaWxfbW9kZSdcbiAgICAgIGlmIChjZWlsTW9kZSAhPT0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3VzaW5nIGNlaWwoKSBpbiBzaGFwZSBjb21wdXRhdGlvbiBpcyBub3QgeWV0IHN1cHBvcnRlZCBmb3IgQXZlcmFnZVBvb2wnKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7YXV0b1BhZCwgY2VpbE1vZGUsIGNvdW50SW5jbHVkZVBhZCwga2VybmVsU2hhcGUsIHN0cmlkZXMsIHBhZHN9KTtcbiAgICB9O1xuXG5jb25zdCBjcmVhdGVBdmVyYWdlUG9vbFByb2dyYW1JbmZvID1cbiAgICAoaW5wdXRzOiBUZW5zb3JbXSwgbWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSwgaXNHbG9iYWxPcGVyYXRvcjogYm9vbGVhbiwgYXR0cmlidXRlczogQXZlcmFnZVBvb2xBdHRyaWJ1dGVzKTpcbiAgICAgICAgUHJvZ3JhbUluZm8gPT4ge1xuICAgICAgICAgIGNvbnN0IFthZGp1c3RlZEF0dHJpYnV0ZXMsIG91dHB1dFNoYXBlXSA9XG4gICAgICAgICAgICAgIGdldEFkanVzdGVkUG9vbEF0dHJpYnV0ZXNBbmRPdXRwdXRTaGFwZShpbnB1dHMsIGF0dHJpYnV0ZXMsIGlzR2xvYmFsT3BlcmF0b3IpO1xuICAgICAgICAgIGNvbnN0IGtlcm5lbFNpemUgPSBTaGFwZVV0aWwuc2l6ZShhZGp1c3RlZEF0dHJpYnV0ZXMua2VybmVsU2hhcGUpO1xuICAgICAgICAgIGNvbnN0IG9wMSA9ICd2YWx1ZSArPSBfWCh4KTsnO1xuICAgICAgICAgIGxldCBvcDIgPSAnJztcbiAgICAgICAgICBpZiAoYWRqdXN0ZWRBdHRyaWJ1dGVzLmNvdW50SW5jbHVkZVBhZCkge1xuICAgICAgICAgICAgb3AyICs9IGB2YWx1ZSAvPSBmbG9hdCgke2tlcm5lbFNpemV9KTtgO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBvcDIgKz0gYHZhbHVlIC89IGZsb2F0KCR7a2VybmVsU2l6ZX0gLSBwYWQpO2A7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IHBvb2xpbmdDb2RlID0gZ2VuZXJhdGVQb29saW5nQ29kZShpbnB1dHNbMF0uZGltcywgYWRqdXN0ZWRBdHRyaWJ1dGVzLCBvcDEsIG9wMiwgJzAuMCcpO1xuICAgICAgICAgIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgICAgJHtwb29saW5nQ29kZX1cbiAgICAgIGA7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC4uLm1ldGFkYXRhLFxuICAgICAgICAgICAgb3V0cHV0OiB7ZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWR9LFxuICAgICAgICAgICAgc2hhZGVyU291cmNlXG4gICAgICAgICAgfTtcbiAgICAgICAgfTtcblxuZXhwb3J0IGNvbnN0IGdsb2JhbEF2ZXJhZ2VQb29sOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPEF2ZXJhZ2VQb29sQXR0cmlidXRlcz4gPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IEF2ZXJhZ2VQb29sQXR0cmlidXRlcyk6IFRlbnNvcltdID0+IHtcbiAgICAgIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG4gICAgICBjb25zdCBtZXRhZGF0YSA9IHtcbiAgICAgICAgbmFtZTogJ0dsb2JhbEF2ZXJhZ2VQb29sJyxcbiAgICAgICAgaW5wdXROYW1lczogWydYJ10sXG4gICAgICAgIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG4gICAgICAgIGNhY2hlSGludDogYCR7YXR0cmlidXRlcy5jb3VudEluY2x1ZGVQYWR9YFxuICAgICAgfTtcbiAgICAgIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgICAgICAgIHsuLi5tZXRhZGF0YSwgZ2V0OiAoKSA9PiBjcmVhdGVBdmVyYWdlUG9vbFByb2dyYW1JbmZvKGlucHV0cywgbWV0YWRhdGEsIHRydWUsIGF0dHJpYnV0ZXMpfSwgaW5wdXRzKTtcbiAgICAgIHJldHVybiBbb3V0cHV0XTtcbiAgICB9O1xuXG5leHBvcnQgY29uc3QgcGFyc2VHbG9iYWxBdmVyYWdlUG9vbEF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248QXZlcmFnZVBvb2xBdHRyaWJ1dGVzPiA9XG4gICAgKG5vZGU6IEdyYXBoLk5vZGUpOiBBdmVyYWdlUG9vbEF0dHJpYnV0ZXMgPT4ge1xuICAgICAgY29uc3QgY291bnRJbmNsdWRlUGFkID0gKG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ2NvdW50X2luY2x1ZGVfcGFkJywgMCkgPT09IDAgPyBmYWxzZSA6IHRydWUpO1xuICAgICAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleShcbiAgICAgICAgICB7YXV0b1BhZDogJycsIGNlaWxNb2RlOiAwLCBjb3VudEluY2x1ZGVQYWQsIGtlcm5lbFNoYXBlOiBbXSwgc3RyaWRlczogW10sIHBhZHM6IFtdfSk7XG4gICAgfTtcblxuZXhwb3J0IGludGVyZmFjZSBNYXhQb29sQXR0cmlidXRlcyBleHRlbmRzIEF2ZXJhZ2VQb29sQXR0cmlidXRlcyB7XG4gIHJlYWRvbmx5IHN0b3JhZ2VPcmRlcjogbnVtYmVyO1xuICByZWFkb25seSBkaWxhdGlvbnM6IG51bWJlcltdO1xufVxuXG5leHBvcnQgY29uc3QgbWF4UG9vbDogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxNYXhQb29sQXR0cmlidXRlcz4gPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IE1heFBvb2xBdHRyaWJ1dGVzKTogVGVuc29yW10gPT4ge1xuICAgICAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcbiAgICAgIGNvbnN0IG1ldGFkYXRhID1cbiAgICAgICAgICB7bmFtZTogJ01heFBvb2wnLCBpbnB1dE5hbWVzOiBbJ1gnXSwgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkXSwgY2FjaGVIaW50OiBhdHRyaWJ1dGVzLmNhY2hlS2V5fTtcbiAgICAgIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgICAgICAgIHsuLi5tZXRhZGF0YSwgZ2V0OiAoKSA9PiBjcmVhdGVNYXhQb29sUHJvZ3JhbUluZm8oaW5wdXRzLCBtZXRhZGF0YSwgZmFsc2UsIGF0dHJpYnV0ZXMpfSwgaW5wdXRzKTtcbiAgICAgIHJldHVybiBbb3V0cHV0XTtcbiAgICB9O1xuXG5leHBvcnQgY29uc3QgcGFyc2VNYXhQb29sQXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxNYXhQb29sQXR0cmlidXRlcz4gPVxuICAgIChub2RlOiBHcmFwaC5Ob2RlKTogTWF4UG9vbEF0dHJpYnV0ZXMgPT4ge1xuICAgICAgY29uc3QgYXV0b1BhZCA9IG5vZGUuYXR0cmlidXRlcy5nZXRTdHJpbmcoJ2F1dG9fcGFkJywgJ05PVFNFVCcpO1xuICAgICAgY29uc3QgY2VpbE1vZGUgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50KCdjZWlsX21vZGUnLCAwKTtcbiAgICAgIGNvbnN0IGtlcm5lbFNoYXBlID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludHMoJ2tlcm5lbF9zaGFwZScpO1xuICAgICAgY29uc3Qgc3RyaWRlcyA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnRzKCdzdHJpZGVzJywgW10pO1xuICAgICAgY29uc3QgcGFkcyA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnRzKCdwYWRzJywgW10pO1xuICAgICAgY29uc3Qgc3RvcmFnZU9yZGVyID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludCgnc3RvcmFnZV9vcmRlcicsIDApO1xuICAgICAgY29uc3QgZGlsYXRpb25zID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludHMoJ2RpbGF0aW9ucycsIFtdKTtcblxuICAgICAgLy8gVE9ETzogc3VwcG9ydCBhdHRyaWJ1dGUgJ2NlaWxfbW9kZScgYW5kICdzdG9yYWdlX29yZGVyJ1xuICAgICAgaWYgKHN0b3JhZ2VPcmRlciAhPT0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2NvbHVtbiBtYWpvciBzdG9yYWdlIG9yZGVyIGlzIG5vdCB5ZXQgc3VwcG9ydGVkIGZvciBNYXhQb29sJyk7XG4gICAgICB9XG4gICAgICBpZiAoY2VpbE1vZGUgIT09IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd1c2luZyBjZWlsKCkgaW4gc2hhcGUgY29tcHV0YXRpb24gaXMgbm90IHlldCBzdXBwb3J0ZWQgZm9yIE1heFBvb2wnKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleShcbiAgICAgICAgICB7YXV0b1BhZCwgY2VpbE1vZGUsIGNvdW50SW5jbHVkZVBhZDogZmFsc2UsIGtlcm5lbFNoYXBlLCBzdHJpZGVzLCBwYWRzLCBzdG9yYWdlT3JkZXIsIGRpbGF0aW9uc30pO1xuICAgIH07XG5cbmNvbnN0IGNyZWF0ZU1heFBvb2xQcm9ncmFtSW5mbyA9XG4gICAgKGlucHV0czogVGVuc29yW10sIG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsIGlzR2xvYmFsT3BlcmF0b3I6IGJvb2xlYW4sIGF0dHJpYnV0ZXM6IE1heFBvb2xBdHRyaWJ1dGVzKTpcbiAgICAgICAgUHJvZ3JhbUluZm8gPT4ge1xuICAgICAgICAgIGNvbnN0IFthZGp1c3RlZEF0dHJpYnV0ZXMsIG91dHB1dFNoYXBlXSA9XG4gICAgICAgICAgICAgIGdldEFkanVzdGVkUG9vbEF0dHJpYnV0ZXNBbmRPdXRwdXRTaGFwZShpbnB1dHMsIGF0dHJpYnV0ZXMsIGlzR2xvYmFsT3BlcmF0b3IpO1xuICAgICAgICAgIGNvbnN0IG9wMSA9IGBcbiAgICAgIHZhbHVlID0gbWF4KF9YKHgpLCB2YWx1ZSk7XG4gICAgYDtcbiAgICAgICAgICBjb25zdCBvcDIgPSAnJztcbiAgICAgICAgICBjb25zdCBwb29saW5nQ29kZSA9IGdlbmVyYXRlUG9vbGluZ0NvZGUoaW5wdXRzWzBdLmRpbXMsIGFkanVzdGVkQXR0cmlidXRlcywgb3AxLCBvcDIsICctMWU1Jyk7XG4gICAgICAgICAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgJHtwb29saW5nQ29kZX1cbiAgICBgO1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAuLi5tZXRhZGF0YSxcbiAgICAgICAgICAgIG91dHB1dDoge2RpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkfSxcbiAgICAgICAgICAgIHNoYWRlclNvdXJjZVxuICAgICAgICAgIH07XG4gICAgICAgIH07XG5cbmNvbnN0IGdldEFkanVzdGVkUG9vbEF0dHJpYnV0ZXNBbmRPdXRwdXRTaGFwZSA9XG4gICAgKGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IEF2ZXJhZ2VQb29sQXR0cmlidXRlc3xNYXhQb29sQXR0cmlidXRlcywgaXNHbG9iYWxPcGVyYXRvcjogYm9vbGVhbik6XG4gICAgICAgIFtBdmVyYWdlUG9vbEF0dHJpYnV0ZXN8TWF4UG9vbEF0dHJpYnV0ZXMsIG51bWJlcltdXSA9PiB7XG4gICAgICAgICAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zLnNsaWNlKCk7XG4gICAgICAgICAgY29uc3QgaGFzRGlsYXRpb25zID0gT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwoYXR0cmlidXRlcywgJ2RpbGF0aW9ucycpO1xuICAgICAgICAgIGNvbnN0IGtlcm5lbFNoYXBlID0gYXR0cmlidXRlcy5rZXJuZWxTaGFwZS5zbGljZSgpO1xuICAgICAgICAgIGNvbnN0IHN0cmlkZXMgPSBhdHRyaWJ1dGVzLnN0cmlkZXMuc2xpY2UoKTtcbiAgICAgICAgICBjb25zdCBkaWxhdGlvbnM6IG51bWJlcltdID0gaGFzRGlsYXRpb25zID8gKGF0dHJpYnV0ZXMgYXMgTWF4UG9vbEF0dHJpYnV0ZXMpLmRpbGF0aW9ucy5zbGljZSgpIDogW107XG4gICAgICAgICAgY29uc3QgcGFkcyA9IGF0dHJpYnV0ZXMucGFkcy5zbGljZSgpO1xuICAgICAgICAgIFBvb2xDb252VXRpbC5hZGp1c3RQb29sQXR0cmlidXRlcyhpc0dsb2JhbE9wZXJhdG9yLCBpbnB1dFNoYXBlLCBrZXJuZWxTaGFwZSwgc3RyaWRlcywgZGlsYXRpb25zLCBwYWRzKTtcblxuICAgICAgICAgIGNvbnN0IG91dHB1dFNoYXBlID0gUG9vbENvbnZVdGlsLmNvbXB1dGVQb29sT3V0cHV0U2hhcGUoXG4gICAgICAgICAgICAgIGlzR2xvYmFsT3BlcmF0b3IsIGlucHV0U2hhcGUsIHN0cmlkZXMsIGRpbGF0aW9ucywga2VybmVsU2hhcGUsIHBhZHMsIGF0dHJpYnV0ZXMuYXV0b1BhZCk7XG5cbiAgICAgICAgICBjb25zdCBuZXdBdHRyaWJ1dGVzID0gT2JqZWN0LmFzc2lnbih7fSwgYXR0cmlidXRlcyk7XG4gICAgICAgICAgaWYgKGhhc0RpbGF0aW9ucykge1xuICAgICAgICAgICAgT2JqZWN0LmFzc2lnbihuZXdBdHRyaWJ1dGVzLCB7a2VybmVsU2hhcGUsIHN0cmlkZXMsIHBhZHMsIGRpbGF0aW9ucywgY2FjaGVLZXk6IGF0dHJpYnV0ZXMuY2FjaGVLZXl9KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgT2JqZWN0LmFzc2lnbihuZXdBdHRyaWJ1dGVzLCB7a2VybmVsU2hhcGUsIHN0cmlkZXMsIHBhZHMsIGNhY2hlS2V5OiBhdHRyaWJ1dGVzLmNhY2hlS2V5fSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBbbmV3QXR0cmlidXRlcywgb3V0cHV0U2hhcGVdO1xuICAgICAgICB9O1xuXG5jb25zdCBnbG9iYWxNYXhQb29sQXR0cmlidXRlcyA9IHtcbiAgYXV0b1BhZDogJycsXG4gIGNlaWxNb2RlOiAwLFxuICBjb3VudEluY2x1ZGVQYWQ6IGZhbHNlLFxuICBrZXJuZWxTaGFwZTogW10sXG4gIHN0cmlkZXM6IFtdLFxuICBwYWRzOiBbXSxcbiAgc3RvcmFnZU9yZGVyOiAwLFxuICBkaWxhdGlvbnM6IFtdLFxuICBjYWNoZUtleTogJydcbn07XG5cbmNvbnN0IGdsb2JhbE1heFBvb2xNZXRhZGF0YSA9IHtcbiAgbmFtZTogJ0dsb2JhbE1heFBvb2wnLFxuICBpbnB1dE5hbWVzOiBbJ1gnXSxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkXVxufTtcblxuZXhwb3J0IGNvbnN0IGdsb2JhbE1heFBvb2wgPSAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICAgIHtcbiAgICAgICAgLi4uZ2xvYmFsTWF4UG9vbE1ldGFkYXRhLFxuICAgICAgICBnZXQ6ICgpID0+IGNyZWF0ZU1heFBvb2xQcm9ncmFtSW5mbyhpbnB1dHMsIGdsb2JhbE1heFBvb2xNZXRhZGF0YSwgdHJ1ZSwgZ2xvYmFsTWF4UG9vbEF0dHJpYnV0ZXMpXG4gICAgICB9LFxuICAgICAgaW5wdXRzKTtcbiAgcmV0dXJuIFtvdXRwdXRdO1xufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdQb29sIG9wcyByZXF1aXJlcyAxIGlucHV0LicpO1xuICB9XG4gIGlmIChpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0MzInICYmIGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQ2NCcpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxufTtcblxuY29uc3QgZ2VuZXJhdGVQb29saW5nQ29kZSA9XG4gICAgKGlucHV0RGltczogcmVhZG9ubHkgbnVtYmVyW10sIGF0dHJpYnV0ZXM6IEF2ZXJhZ2VQb29sQXR0cmlidXRlcywgb3AxOiBzdHJpbmcsIG9wMjogc3RyaW5nLCBzdGFydDogc3RyaW5nKTpcbiAgICAgICAgc3RyaW5nID0+IHtcbiAgICAgICAgICBjb25zdCByYW5rID0gaW5wdXREaW1zLmxlbmd0aDtcbiAgICAgICAgICBpZiAoYXR0cmlidXRlcy5rZXJuZWxTaGFwZS5sZW5ndGggPD0gMikge1xuICAgICAgICAgICAgY29uc3Qga3cgPSBhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlW2F0dHJpYnV0ZXMua2VybmVsU2hhcGUubGVuZ3RoIC0gMV07XG4gICAgICAgICAgICBjb25zdCBzdyA9IGF0dHJpYnV0ZXMuc3RyaWRlc1thdHRyaWJ1dGVzLnN0cmlkZXMubGVuZ3RoIC0gMV07XG4gICAgICAgICAgICBjb25zdCBwd1N0YXJ0ID0gYXR0cmlidXRlcy5wYWRzW2F0dHJpYnV0ZXMucGFkcy5sZW5ndGggLyAyIC0gMV07XG4gICAgICAgICAgICBjb25zdCBwd0VuZCA9IGF0dHJpYnV0ZXMucGFkc1thdHRyaWJ1dGVzLnBhZHMubGVuZ3RoIC0gMV07XG4gICAgICAgICAgICBjb25zdCBkaW1XID0gaW5wdXREaW1zW3JhbmsgLSAxXTtcbiAgICAgICAgICAgIGxldCBjb2RlVyA9ICcnO1xuICAgICAgICAgICAgbGV0IGNvZGVIID0gJyc7XG4gICAgICAgICAgICBsZXQgY29kZUhFbmQgPSAnJztcbiAgICAgICAgICAgIGlmIChwd1N0YXJ0ICsgcHdFbmQgIT09IDApIHtcbiAgICAgICAgICAgICAgY29kZVcgPSBgXG4gICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCAke2t3fTsgaSsrKSB7XG4gICAgICAgICAgICB4WyR7cmFua30gLSAxXSA9IGluZGljZXNbJHtyYW5rfSAtIDFdICogJHtzd30gLSAke3B3U3RhcnR9ICsgaTtcbiAgICAgICAgICAgIGlmICh4WyR7cmFua30gLSAxXSA8IDAgfHwgeFske3Jhbmt9IC0gMV0gPj0gJHtkaW1XfSkge1xuICAgICAgICAgICAgICBwYWQrKztcbiAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAke29wMX1cbiAgICAgICAgICB9YDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGNvZGVXID0gYFxuICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgJHtrd307IGkrKykge1xuICAgICAgICAgICAgeFske3Jhbmt9IC0gMV0gPSBpbmRpY2VzWyR7cmFua30gLSAxXSAqICR7c3d9IC0gJHtwd1N0YXJ0fSArIGk7XG4gICAgICAgICAgICAke29wMX1cbiAgICAgICAgICB9YDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGF0dHJpYnV0ZXMua2VybmVsU2hhcGUubGVuZ3RoID09PSAyKSB7XG4gICAgICAgICAgICAgIGNvbnN0IGtoID0gYXR0cmlidXRlcy5rZXJuZWxTaGFwZVthdHRyaWJ1dGVzLmtlcm5lbFNoYXBlLmxlbmd0aCAtIDJdO1xuICAgICAgICAgICAgICBjb25zdCBzaCA9IGF0dHJpYnV0ZXMuc3RyaWRlc1thdHRyaWJ1dGVzLnN0cmlkZXMubGVuZ3RoIC0gMl07XG4gICAgICAgICAgICAgIGNvbnN0IHBoU3RhcnQgPSBhdHRyaWJ1dGVzLnBhZHNbYXR0cmlidXRlcy5wYWRzLmxlbmd0aCAvIDIgLSAyXTtcbiAgICAgICAgICAgICAgY29uc3QgcGhFbmQgPSBhdHRyaWJ1dGVzLnBhZHNbYXR0cmlidXRlcy5wYWRzLmxlbmd0aCAtIDJdO1xuICAgICAgICAgICAgICBjb25zdCBkaW1IID0gaW5wdXREaW1zW3JhbmsgLSAyXTtcbiAgICAgICAgICAgICAgaWYgKHBoU3RhcnQgKyBwaEVuZCAhPT0gMCkge1xuICAgICAgICAgICAgICAgIGNvZGVIID0gYFxuICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCAke2tofTsgaisrKSB7XG4gICAgICAgICAgICAgIHhbJHtyYW5rfSAtIDJdID0gaW5kaWNlc1ske3Jhbmt9IC0gMl0gKiAke3NofSAtICR7cGhTdGFydH0gKyBqO1xuICAgICAgICAgICAgICBpZiAoeFske3Jhbmt9IC0gMl0gPCAwIHx8IHhbJHtyYW5rfSAtIDJdID49ICR7ZGltSH0pIHtcbiAgICAgICAgICAgICAgICBwYWQrPSAke2t3fTtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgIGA7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29kZUggPSBgXG4gICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8ICR7a2h9OyBqKyspIHtcbiAgICAgICAgICAgICAgeFske3Jhbmt9IC0gMl0gPSBpbmRpY2VzWyR7cmFua30gLSAyXSAqICR7c2h9IC0gJHtwaFN0YXJ0fSArIGo7XG4gICAgICAgICAgICBgO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGNvZGVIRW5kID0gYFxuICAgICAgICAgIH1cbiAgICAgICAgYDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgcG9vbGluZ0NvZGUgPSBgXG4gICAgICAgIGZsb2F0IHByb2Nlc3MoaW50IGluZGljZXNbJHtyYW5rfV0pIHtcbiAgICAgICAgICBpbnQgeFske3Jhbmt9XTtcbiAgICAgICAgICBjb3B5VmVjKGluZGljZXMsIHgpO1xuXG4gICAgICAgICAgZmxvYXQgdmFsdWUgPSAke3N0YXJ0fTtcbiAgICAgICAgICBpbnQgcGFkID0gMDtcbiAgICAgICAgICAke2NvZGVIfVxuICAgICAgICAgICR7Y29kZVd9XG4gICAgICAgICAgJHtjb2RlSEVuZH1cbiAgICAgICAgICAke29wMn1cbiAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgICAgICAgICByZXR1cm4gcG9vbGluZ0NvZGU7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGtlcm5lbFNpemUgPSBTaGFwZVV0aWwuc2l6ZShhdHRyaWJ1dGVzLmtlcm5lbFNoYXBlKTtcbiAgICAgICAgICAgIGNvbnN0IGtlcm5lbFN0cmlkZXMgPSBTaGFwZVV0aWwuY29tcHV0ZVN0cmlkZXMoYXR0cmlidXRlcy5rZXJuZWxTaGFwZSk7XG4gICAgICAgICAgICBjb25zdCBzdHJpZGVzUmFuayA9IGtlcm5lbFN0cmlkZXMubGVuZ3RoO1xuICAgICAgICAgICAgY29uc3QgcGFkc1JhbmsgPSBhdHRyaWJ1dGVzLnBhZHMubGVuZ3RoO1xuICAgICAgICAgICAgY29uc3Qgb2Zmc2V0VG9JbmRpY2VzRnVuY3Rpb24gPSBvZmZzZXRUb0luZGljZXMoc3RyaWRlc1JhbmspO1xuICAgICAgICAgICAgY29uc3QgY29weUlucHV0RGltcyA9IGNvcHlBcnJheShpbnB1dERpbXMsICdpbnB1dERpbXMnKTtcbiAgICAgICAgICAgIGNvbnN0IGNvcHlQYWRzID0gY29weUFycmF5KGF0dHJpYnV0ZXMucGFkcywgJ3BhZHMnKTtcbiAgICAgICAgICAgIGNvbnN0IGNvcHlLZXJuZWxTdHJpZGVzID0gY29weUFycmF5KGtlcm5lbFN0cmlkZXMsICdrZXJuZWxTdHJpZGVzJyk7XG4gICAgICAgICAgICBjb25zdCBjb3B5U3RyaWRlcyA9IGNvcHlBcnJheShhdHRyaWJ1dGVzLnN0cmlkZXMsICdzdHJpZGVzJyk7XG4gICAgICAgICAgICBjb25zdCBoYXNQYWRzID0gYXR0cmlidXRlcy5wYWRzLnJlZHVjZSgoc3VtLCBjdXIpID0+IHN1bSArIGN1cik7XG4gICAgICAgICAgICBsZXQgcGFkQ29kZSA9ICcnO1xuICAgICAgICAgICAgaWYgKGhhc1BhZHMpIHtcbiAgICAgICAgICAgICAgcGFkQ29kZSA9IGBcbiAgICAgICAgICAgIGlmICh4W2pdID49IGlucHV0RGltc1tqXSB8fCB4W2pdIDwgMCkge1xuICAgICAgICAgICAgICBwYWQrKztcbiAgICAgICAgICAgICAgaXNQYWQgPSB0cnVlO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCFpc1BhZCkge1xuICAgICAgICAgICAgJHtvcDF9XG4gICAgICAgICAgfWA7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBwYWRDb2RlID0gYFxuICAgICAgICAgIH1cbiAgICAgICAgICAke29wMX1cbiAgICAgICAgYDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHBvb2xpbmdDb2RlID0gYFxuICAgICAgICAke29mZnNldFRvSW5kaWNlc0Z1bmN0aW9ufVxuICAgICAgICBmbG9hdCBwcm9jZXNzKGludCBpbmRpY2VzWyR7cmFua31dKSB7XG4gICAgICAgICAgaW50IHhbJHtyYW5rfV07XG4gICAgICAgICAgY29weVZlYyhpbmRpY2VzLCB4KTtcbiAgICAgICAgICBpbnQgb2Zmc2V0WyR7c3RyaWRlc1Jhbmt9XTtcbiAgICAgICAgICBpbnQgcGFkc1ske3BhZHNSYW5rfV07XG4gICAgICAgICAgaW50IGlucHV0RGltc1ske3Jhbmt9XTtcbiAgICAgICAgICBpbnQga2VybmVsU3RyaWRlc1ske3N0cmlkZXNSYW5rfV07XG4gICAgICAgICAgaW50IHN0cmlkZXNbJHtzdHJpZGVzUmFua31dO1xuICAgICAgICAgICR7Y29weVBhZHN9XG4gICAgICAgICAgJHtjb3B5SW5wdXREaW1zfVxuICAgICAgICAgICR7Y29weVN0cmlkZXN9XG4gICAgICAgICAgJHtjb3B5S2VybmVsU3RyaWRlc31cblxuICAgICAgICAgIGZsb2F0IHZhbHVlID0gJHtzdGFydH07XG4gICAgICAgICAgaW50IHBhZCA9IDA7XG4gICAgICAgICAgYm9vbCBpc1BhZCA9IGZhbHNlO1xuICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgJHtrZXJuZWxTaXplfTsgaSsrKSB7XG4gICAgICAgICAgICBvZmZzZXRUb0luZGljZXMoaSwga2VybmVsU3RyaWRlcywgb2Zmc2V0KTtcbiAgICAgICAgICAgIGlzUGFkID0gZmFsc2U7XG4gICAgICAgICAgICBmb3IgKGludCBqID0gJHtyYW5rfSAtICR7c3RyaWRlc1Jhbmt9OyBqIDwgJHtyYW5rfTsgaisrKSB7XG4gICAgICAgICAgICAgIHhbal0gPSBpbmRpY2VzW2pdICogc3RyaWRlc1tqIC0gJHtyYW5rfSArICR7c3RyaWRlc1Jhbmt9XVxuICAgICAgICAgICAgICAgICsgb2Zmc2V0W2ogLSAke3Jhbmt9ICsgJHtzdHJpZGVzUmFua31dIC0gcGFkc1tqIC0gMl07XG4gICAgICAgICAgICAgICR7cGFkQ29kZX1cbiAgICAgICAgICB9XG4gICAgICAgICAgJHtvcDJ9XG5cbiAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgIGA7XG4gICAgICAgICAgICByZXR1cm4gcG9vbGluZ0NvZGU7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuXG5jb25zdCBjb3B5QXJyYXkgPSAoYXJyYXk6IHJlYWRvbmx5IG51bWJlcltdLCBhcnJheU5hbWU6IHN0cmluZyk6IHN0cmluZyA9PiB7XG4gIGxldCBibG9jayA9ICcnO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgYmxvY2sgKz0gYFxuICAgICAgJHthcnJheU5hbWV9WyR7aX1dID0gJHthcnJheVtpXX07XG4gICAgYDtcbiAgfVxuICByZXR1cm4gYmxvY2s7XG59O1xuXG5jb25zdCBvZmZzZXRUb0luZGljZXMgPSAocmFuazogbnVtYmVyKTogc3RyaW5nID0+IGBcbiAgdm9pZCBvZmZzZXRUb0luZGljZXMoaW50IG9mZnNldCwgaW50WyR7cmFua31dIHN0cmlkZXMsIG91dCBpbnRbJHtyYW5rfV0gaW5kaWNlcykge1xuICAgIGlmICgke3Jhbmt9ID09IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZm9yIChpbnQgaSA9IDA7IGkgPCAke3Jhbmt9IC0gMTsgKytpKSB7XG4gICAgICBpbmRpY2VzW2ldID0gb2Zmc2V0IC8gc3RyaWRlc1tpXTtcbiAgICAgIG9mZnNldCAtPSBpbmRpY2VzW2ldICogc3RyaWRlc1tpXTtcbiAgICB9XG4gICAgaW5kaWNlc1ske3Jhbmt9IC0gMV0gPSBvZmZzZXQ7XG4gIH1gO1xuIiwiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7QXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXl9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQge0dyYXBofSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQge05VTUJFUl9UWVBFUywgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbn0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7VGVuc29yfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHtTaGFwZVV0aWx9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHtXZWJHTEluZmVyZW5jZUhhbmRsZXJ9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7UHJvZ3JhbUluZm8sIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGV9IGZyb20gJy4uL3R5cGVzJztcblxuZXhwb3J0IGludGVyZmFjZSBSZWR1Y2VBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgYXhlczogbnVtYmVyW107XG4gIHJlYWRvbmx5IGtlZXBEaW1zOiBib29sZWFuO1xufVxuXG4vLyByZXR1cm4gW2luaXQgb3BzLCByZWR1Y2Ugb3BzLCBmaW5hbCBvcHNdXG50eXBlIFJlZHVjZU9wID0gKGlucHV0czogVGVuc29yW10sIGF4ZXM6IG51bWJlcltdKSA9PiBzdHJpbmdbXTtcblxuY29uc3QgcmVkdWNlID1cbiAgICAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzLCBuYW1lOiBzdHJpbmcsXG4gICAgIHJlZHVjZU9wOiBSZWR1Y2VPcCk6IFRlbnNvcltdID0+IHtcbiAgICAgIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG5cbiAgICAgIGNvbnN0IHJlZHVjZVByb2dyYW1NZXRhZGF0YSA9IHtcbiAgICAgICAgbmFtZSxcbiAgICAgICAgaW5wdXROYW1lczogWydBJ10sXG4gICAgICAgIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICAgICAgICB7XG4gICAgICAgICAgICAuLi5yZWR1Y2VQcm9ncmFtTWV0YWRhdGEsXG4gICAgICAgICAgICBjYWNoZUhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXksXG4gICAgICAgICAgICBnZXQ6ICgpID0+XG4gICAgICAgICAgICAgICAgY3JlYXRlUmVkdWNlUHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzLCBuYW1lLCByZWR1Y2VPcCwgcmVkdWNlUHJvZ3JhbU1ldGFkYXRhKVxuICAgICAgICAgIH0sXG4gICAgICAgICAgaW5wdXRzKTtcbiAgICAgIHJldHVybiBbb3V0cHV0XTtcbiAgICB9O1xuXG5leHBvcnQgY29uc3QgcGFyc2VSZWR1Y2VBdHRyaWJ1dGVzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPFJlZHVjZUF0dHJpYnV0ZXM+ID0gKG5vZGU6IEdyYXBoLk5vZGUpOiBSZWR1Y2VBdHRyaWJ1dGVzID0+IHtcbiAgY29uc3QgYXhlcyA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnRzKCdheGVzJywgW10pO1xuICBjb25zdCBrZWVwRGltcyA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ2tlZXBkaW1zJywgMSkgPT09IDE7XG4gIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoe2F4ZXMsIGtlZXBEaW1zfSk7XG59O1xuXG5jb25zdCBjcmVhdGVSZWR1Y2VQcm9ncmFtSW5mbyA9XG4gICAgKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogUmVkdWNlQXR0cmlidXRlcywgbmFtZTogc3RyaW5nLCByZWR1Y2VPcDogUmVkdWNlT3AsXG4gICAgIHJlZHVjZVByb2dyYW1NZXRhZGF0YTogUHJvZ3JhbU1ldGFkYXRhKTogUHJvZ3JhbUluZm8gPT4ge1xuICAgICAgY29uc3Qgb3V0cHV0U2hhcGU6IG51bWJlcltdID0gW107XG4gICAgICBjb25zdCBpUmFuayA9IGlucHV0c1swXS5kaW1zLmxlbmd0aCB8fCAxO1xuXG4gICAgICBjb25zdCBpZHhDb3B5ID0gW107ICAvLyBjb3B5IG91dHB1dCBpbmRleGVzIHRvIGlucHV0IGluZGV4ZXNcblxuICAgICAgY29uc3QgYXhlcyA9IFNoYXBlVXRpbC5ub3JtYWxpemVBeGVzKGF0dHJpYnV0ZXMuYXhlcywgaW5wdXRzWzBdLmRpbXMubGVuZ3RoKTtcbiAgICAgIGNvbnN0IG9wcyA9IHJlZHVjZU9wKGlucHV0cywgYXhlcyk7XG4gICAgICBsZXQgcmVkdWNlT3BzID0gb3BzWzFdO1xuXG4gICAgICBmb3IgKGxldCBrID0gMDsgayA8IGlucHV0c1swXS5kaW1zLmxlbmd0aDsgaysrKSB7XG4gICAgICAgIC8vIGlmIHRoaXMgYXhpcyBpcyByZWR1Y2VkXG4gICAgICAgIGlmIChheGVzLmluZGV4T2YoaykgPj0gMCB8fCBheGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIGlmIChhdHRyaWJ1dGVzLmtlZXBEaW1zKSB7XG4gICAgICAgICAgICBvdXRwdXRTaGFwZS5wdXNoKDEpO1xuICAgICAgICAgIH0gIC8vIGVsc2UgeyByZW1vdmUgdGhlIGF4aXMgZnJvbSBvdXRwdXRTaGFwZTsgfVxuXG4gICAgICAgICAgLy8gbG9vcCBvdmVyIHRoZSBkLXRoIGF4aXNcbiAgICAgICAgICByZWR1Y2VPcHMgPSBgXG4gICAgICAgICAgZm9yKGludCBqJHtrfSA9IDA7IGoke2t9IDwgJHtpbnB1dHNbMF0uZGltc1trXX07IGoke2t9KyspIHtcbiAgICAgICAgICAgIGlucHV0SWR4WyR7a31dID0gaiR7a307XG4gICAgICAgICAgICAke3JlZHVjZU9wc31cbiAgICAgICAgICB9YDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZHhDb3B5LnB1c2goYGlucHV0SWR4WyR7a31dID0gb3V0cHV0SWR4WyR7b3V0cHV0U2hhcGUubGVuZ3RofV07YCk7XG5cbiAgICAgICAgICBvdXRwdXRTaGFwZS5wdXNoKGlucHV0c1swXS5kaW1zW2tdKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCBvUmFuayA9IG91dHB1dFNoYXBlLmxlbmd0aCB8fCAxO1xuXG4gICAgICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICBmbG9hdCBwcm9jZXNzKGludCBvdXRwdXRJZHhbJHtvUmFua31dKSB7XG4gICAgICAgIGZsb2F0IHZhbHVlOyAgICAgICAgICAgICAgICAgLy8gZmluYWwgcmVzdWx0XG4gICAgICAgIGludCBpbnB1dElkeFske2lSYW5rfV07ICAgICAgLy8gYWRkcmVzc2luZyBpbnB1dCBkYXRhXG4gICAgICAgICR7aWR4Q29weS5qb2luKCdcXG4nKX1cbiAgICAgICAgJHtvcHNbMF19ICAgICAgIC8vIGluaXQgb3BzIGZvciByZWR1Y2UgbWF4L21pblxuICAgICAgICAke3JlZHVjZU9wc31cbiAgICAgICAgJHtvcHNbMl19ICAgICAgIC8vIGZpbmFsIGNvbXB1dGF0aW9uIGZvciByZWR1Y2UgbWVhblxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9YDtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4ucmVkdWNlUHJvZ3JhbU1ldGFkYXRhLFxuICAgICAgICBvdXRwdXQ6IHtkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXRzWzBdLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZH0sXG4gICAgICAgIHNoYWRlclNvdXJjZVxuICAgICAgfTtcbiAgICB9O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1JlZHVjZSBvcCByZXF1aXJlcyAxIGlucHV0LicpO1xuICB9XG5cbiAgaWYgKE5VTUJFUl9UWVBFUy5pbmRleE9mKGlucHV0c1swXS50eXBlKSA9PT0gLTEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IHJlZHVjZVN1bTogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxSZWR1Y2VBdHRyaWJ1dGVzPiA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogUmVkdWNlQXR0cmlidXRlcyk6IFRlbnNvcltdID0+IHtcbiAgICAgIGNvbnN0IHJlZHVjZU9wOiBSZWR1Y2VPcCA9ICgpOiBzdHJpbmdbXSA9PiBbJ3ZhbHVlID0gMC4wOycsICd2YWx1ZSArPSBfQShpbnB1dElkeCk7JywgJyddO1xuICAgICAgcmV0dXJuIHJlZHVjZShpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMsICdSZWR1Y2VTdW0nLCByZWR1Y2VPcCk7XG4gICAgfTtcblxuZXhwb3J0IGNvbnN0IHJlZHVjZU1lYW46IE9wZXJhdG9ySW1wbGVtZW50YXRpb248UmVkdWNlQXR0cmlidXRlcz4gPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMpOiBUZW5zb3JbXSA9PiB7XG4gICAgICBjb25zdCByZWR1Y2VPcDogUmVkdWNlT3AgPSAoaW5wdXRzOiBUZW5zb3JbXSwgYXhlczogbnVtYmVyW10pOiBzdHJpbmdbXSA9PiB7XG4gICAgICAgIGxldCBzaXplID0gMS4wO1xuICAgICAgICBmb3IgKGxldCBrID0gMDsgayA8IGlucHV0c1swXS5kaW1zLmxlbmd0aDsgaysrKSB7XG4gICAgICAgICAgaWYgKGF4ZXMuaW5kZXhPZihrKSA+PSAwIHx8IGF4ZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICBzaXplICo9IGlucHV0c1swXS5kaW1zW2tdO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBbJ3ZhbHVlID0gMC4wOycsICd2YWx1ZSArPSBfQShpbnB1dElkeCk7JywgYHZhbHVlIC89ICR7c2l6ZX0uO2BdOyAgLy8gZW5zdXJlIHJlYWwgbnVtYmVyIHdpdGggYC5gXG4gICAgICB9O1xuICAgICAgcmV0dXJuIHJlZHVjZShpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMsICdSZWR1Y2VNZWFuJywgcmVkdWNlT3ApO1xuICAgIH07XG5cbmV4cG9ydCBjb25zdCByZWR1Y2VNYXg6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248UmVkdWNlQXR0cmlidXRlcz4gPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMpOiBUZW5zb3JbXSA9PiB7XG4gICAgICBjb25zdCByZWR1Y2VPcDogUmVkdWNlT3AgPSAoaW5wdXRzOiBUZW5zb3JbXSwgYXhlczogbnVtYmVyW10pOiBzdHJpbmdbXSA9PiB7XG4gICAgICAgIGNvbnN0IGlkeFplcm8gPSBbXTtcbiAgICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCBpbnB1dHNbMF0uZGltcy5sZW5ndGg7IGsrKykge1xuICAgICAgICAgIGlmIChheGVzLmluZGV4T2YoaykgPj0gMCB8fCBheGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgaWR4WmVyby5wdXNoKGBpbnB1dElkeFske2t9XSA9IDA7YCk7ICAvLyBmaXJzdCBlbGVtZW50XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIFtgJHtpZHhaZXJvLmpvaW4oJ1xcbicpfVxcbnZhbHVlID0gX0EoaW5wdXRJZHgpO2AsICd2YWx1ZSA9IG1heCh2YWx1ZSwgX0EoaW5wdXRJZHgpKTsnLCAnJ107XG4gICAgICB9O1xuICAgICAgcmV0dXJuIHJlZHVjZShpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMsICdSZWR1Y2VNYXgnLCByZWR1Y2VPcCk7XG4gICAgfTtcblxuZXhwb3J0IGNvbnN0IHJlZHVjZU1pbjogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxSZWR1Y2VBdHRyaWJ1dGVzPiA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogUmVkdWNlQXR0cmlidXRlcyk6IFRlbnNvcltdID0+IHtcbiAgICAgIGNvbnN0IHJlZHVjZU9wOiBSZWR1Y2VPcCA9IChpbnB1dHM6IFRlbnNvcltdLCBheGVzOiBudW1iZXJbXSk6IHN0cmluZ1tdID0+IHtcbiAgICAgICAgY29uc3QgaWR4WmVybyA9IFtdO1xuICAgICAgICBmb3IgKGxldCBrID0gMDsgayA8IGlucHV0c1swXS5kaW1zLmxlbmd0aDsgaysrKSB7XG4gICAgICAgICAgaWYgKGF4ZXMuaW5kZXhPZihrKSA+PSAwIHx8IGF4ZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICBpZHhaZXJvLnB1c2goYGlucHV0SWR4WyR7a31dID0gMDtgKTsgIC8vIGZpcnN0IGVsZW1lbnRcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gW2Ake2lkeFplcm8uam9pbignXFxuJyl9XFxudmFsdWUgPSBfQShpbnB1dElkeCk7YCwgJ3ZhbHVlID0gbWluKHZhbHVlLCBfQShpbnB1dElkeCkpOycsICcnXTtcbiAgICAgIH07XG4gICAgICByZXR1cm4gcmVkdWNlKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcywgJ1JlZHVjZU1pbicsIHJlZHVjZU9wKTtcbiAgICB9O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlUHJvZDogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxSZWR1Y2VBdHRyaWJ1dGVzPiA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogUmVkdWNlQXR0cmlidXRlcyk6IFRlbnNvcltdID0+IHtcbiAgICAgIGNvbnN0IHJlZHVjZU9wOiBSZWR1Y2VPcCA9ICgpOiBzdHJpbmdbXSA9PiBbJ3ZhbHVlID0gMS4wOycsICd2YWx1ZSAqPSBfQShpbnB1dElkeCk7JywgJyddO1xuICAgICAgcmV0dXJuIHJlZHVjZShpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMsICdSZWR1Y2VQcm9kJywgcmVkdWNlT3ApO1xuICAgIH07XG5cbmV4cG9ydCBjb25zdCByZWR1Y2VMb2dTdW06IE9wZXJhdG9ySW1wbGVtZW50YXRpb248UmVkdWNlQXR0cmlidXRlcz4gPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IFJlZHVjZUF0dHJpYnV0ZXMpOiBUZW5zb3JbXSA9PiB7XG4gICAgICBjb25zdCByZWR1Y2VPcDogUmVkdWNlT3AgPSAoKTogc3RyaW5nW10gPT4gWyd2YWx1ZSA9IDAuMDsnLCAndmFsdWUgKz0gX0EoaW5wdXRJZHgpOycsICd2YWx1ZSA9IGxvZyh2YWx1ZSk7J107XG4gICAgICByZXR1cm4gcmVkdWNlKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgYXR0cmlidXRlcywgJ1JlZHVjZUxvZ1N1bScsIHJlZHVjZU9wKTtcbiAgICB9O1xuXG5leHBvcnQgY29uc3QgcmVkdWNlTG9nU3VtU3F1YXJlOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPFJlZHVjZUF0dHJpYnV0ZXM+ID1cbiAgICAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBSZWR1Y2VBdHRyaWJ1dGVzKTogVGVuc29yW10gPT4ge1xuICAgICAgY29uc3QgcmVkdWNlT3A6IFJlZHVjZU9wID0gKCk6IHN0cmluZ1tdID0+IFsnZmxvYXQgdDsgdmFsdWUgPSAwLjA7JywgJ3QgPSBfQShpbnB1dElkeCk7IHZhbHVlICs9IHQgKiB0OycsICcnXTtcbiAgICAgIHJldHVybiByZWR1Y2UoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzLCAnUmVkdWNlTG9nU3VtU3F1YXJlJywgcmVkdWNlT3ApO1xuICAgIH07IiwiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7VGVuc29yfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHtTaGFwZVV0aWx9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHtnZXRHbHNsfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQge1dlYkdMSW5mZXJlbmNlSGFuZGxlcn0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHtQcm9ncmFtSW5mbywgUHJvZ3JhbUluZm9Mb2FkZXIsIFByb2dyYW1NZXRhZGF0YSwgVGV4dHVyZVR5cGV9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHt1bnBhY2tGcm9tQ2hhbm5lbH0gZnJvbSAnLi9wYWNraW5nLXV0aWxzJztcblxuY29uc3QgY3JlYXRlUGFja2VkUmVzaGFwZTNEUHJvZ3JhbU1ldGFkYXRhID0gKG91dHB1dFNoYXBlM0Q6IHJlYWRvbmx5IG51bWJlcltdKSA9PlxuICAgICh7bmFtZTogJ1Jlc2hhcGUgKHBhY2tlZCknLCBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUucGFja2VkXSwgaW5wdXROYW1lczogWydBJ10sIGNhY2hlSGludDogYCR7b3V0cHV0U2hhcGUzRH1gfSk7XG5cbmNvbnN0IGNyZWF0ZVBhY2tlZFJlc2hhcGUzRFByb2dyYW1JbmZvID1cbiAgICAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dDNEOiBUZW5zb3IsIG1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEsIG91dHB1dFNoYXBlM0Q6IHJlYWRvbmx5IG51bWJlcltdKTpcbiAgICAgICAgUHJvZ3JhbUluZm8gPT4ge1xuICAgICAgICAgIGNvbnN0IGlucHV0U2hhcGUzRCA9IGlucHV0M0QuZGltcyBhcyBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl07XG4gICAgICAgICAgY29uc3Qgc3F1ZWV6ZWRPdXRwdXRTaGFwZSA9IG91dHB1dFNoYXBlM0QgYXMgW251bWJlciwgbnVtYmVyLCBudW1iZXJdO1xuXG4gICAgICAgICAgbGV0IG1haW5Mb29wID0gJyc7XG4gICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCA0OyBpKyspIHtcbiAgICAgICAgICAgIGxldCBvdXRwdXRDb29yZHMgPSAnJztcbiAgICAgICAgICAgIHN3aXRjaCAoaSkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3V0cHV0Q29vcmRzID0gJ291dHB1dENvb3JkcyA9IHJjOyc7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIGNhc2UgMTpcbiAgICAgICAgICAgICAgICBvdXRwdXRDb29yZHMgPSAnb3V0cHV0Q29vcmRzID0gaXZlYzMocmMueCwgcmMueSsxLCByYy56KTsnO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgICAgICAgb3V0cHV0Q29vcmRzID0gJ291dHB1dENvb3JkcyA9IGl2ZWMzKHJjLngsIHJjLnksIHJjLnorMSk7JztcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgICAgIG91dHB1dENvb3JkcyA9ICdvdXRwdXRDb29yZHMgPSBpdmVjMyhyYy54LCByYy55KzEsIHJjLnorMSk7JztcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbWFpbkxvb3AgKz0gYFxuICAgICAgICAke291dHB1dENvb3Jkc31cbiAgICAgICAgJHtpID4gMCA/ICdpZihvdXRwdXRDb29yZHMueSA8IHJvd3MgJiYgb3V0cHV0Q29vcmRzLnogPCBjb2xzKXsnIDogJyd9XG4gICAgICAgICAgaW50IGZsYXR0ZW5lZEluZGV4ID0gZ2V0RmxhdHRlbmVkSW5kZXgob3V0cHV0Q29vcmRzKTtcblxuICAgICAgICAgIGl2ZWMzIGlucHV0UkMgPSBpbnB1dENvb3Jkc0Zyb21SZXNoYXBlZE91dENvb3JkcyhmbGF0dGVuZWRJbmRleCk7XG4gICAgICAgICAgdmVjMiBpbm5lckRpbXMgPSB2ZWMyKGZsb2F0KGlucHV0UkMueSksZmxvYXQoaW5wdXRSQy56KSk7XG5cbiAgICAgICAgICByZXN1bHRbJHtpfV0gPSBnZXRDaGFubmVsKGdldEEoaW5wdXRSQy54LCBpbnB1dFJDLnksIGlucHV0UkMueiksIGlubmVyRGltcyk7XG5cbiAgICAgICAgJHtpID4gMCA/ICd9JyA6ICcnfVxuICAgICAgYDtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgZ2xzbCA9IGdldEdsc2woaGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuXG4gICAgICAgICAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgJHtnZXRSZXNoYXBlZElucHV0Q29vcmRzKGlucHV0U2hhcGUzRCl9XG4gICAgICAke2dldEZsYXR0ZW5lZEluZGV4RnJvbTNEKHNxdWVlemVkT3V0cHV0U2hhcGUpfVxuICAgICAgJHt1bnBhY2tGcm9tQ2hhbm5lbCgpfVxuXG4gICAgICB2b2lkIG1haW4oKSB7XG4gICAgICAgIGl2ZWMzIHJjID0gZ2V0T3V0cHV0Q29vcmRzKCk7XG5cbiAgICAgICAgdmVjNCByZXN1bHQgPSB2ZWM0KDAuMCk7XG5cbiAgICAgICAgaXZlYzMgb3V0cHV0Q29vcmRzO1xuICAgICAgICBpbnQgcm93cyA9ICR7c3F1ZWV6ZWRPdXRwdXRTaGFwZVsyXX07XG4gICAgICAgIGludCBjb2xzID0gJHtzcXVlZXplZE91dHB1dFNoYXBlWzFdfTtcblxuICAgICAgICAke21haW5Mb29wfVxuICAgICAgICAke2dsc2wub3V0cHV0fSA9IHJlc3VsdDtcbiAgICAgIH1cbiAgICBgO1xuXG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC4uLm1ldGFkYXRhLFxuICAgICAgICAgICAgb3V0cHV0OiB7ZGltczogc3F1ZWV6ZWRPdXRwdXRTaGFwZSwgdHlwZTogaW5wdXQzRC50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUucGFja2VkfSxcbiAgICAgICAgICAgIHNoYWRlclNvdXJjZSxcbiAgICAgICAgICAgIGhhc01haW46IHRydWVcbiAgICAgICAgICB9O1xuICAgICAgICB9O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlUGFja2VkUmVzaGFwZTNEUHJvZ3JhbUluZm9Mb2FkZXIgPVxuICAgIChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0M0Q6IFRlbnNvciwgb3V0cHV0U2hhcGUzRDogcmVhZG9ubHkgbnVtYmVyW10pOiBQcm9ncmFtSW5mb0xvYWRlciA9PiB7XG4gICAgICBjb25zdCBtZXRhZGF0YSA9IGNyZWF0ZVBhY2tlZFJlc2hhcGUzRFByb2dyYW1NZXRhZGF0YShvdXRwdXRTaGFwZTNEKTtcbiAgICAgIHJldHVybiB7Li4ubWV0YWRhdGEsIGdldDogKCkgPT4gY3JlYXRlUGFja2VkUmVzaGFwZTNEUHJvZ3JhbUluZm8oaGFuZGxlciwgaW5wdXQzRCwgbWV0YWRhdGEsIG91dHB1dFNoYXBlM0QpfTtcbiAgICB9O1xuXG5leHBvcnQgZnVuY3Rpb24gcHJvY2Vzc0RpbXMzRChzaGFwZTogQXJyYXlMaWtlPG51bWJlcj4pOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0ge1xuICBpZiAoc2hhcGUubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIFsxLCAxLCAxXTtcbiAgfVxuICAvLyBUT0RPOiBzcXVlZXplIG90aGVyIHNoYXBlcyB0byAyRCBjYXNlXG4gIGxldCBiYXRjaCA9IDE7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgc2hhcGUubGVuZ3RoIC0gMjsgKytpKSB7XG4gICAgYmF0Y2ggKj0gc2hhcGVbaV07XG4gIH1cbiAgcmV0dXJuIFtiYXRjaCwgc2hhcGUubGVuZ3RoID4gMSA/IHNoYXBlW3NoYXBlLmxlbmd0aCAtIDJdIDogMSwgc2hhcGVbc2hhcGUubGVuZ3RoIC0gMV1dO1xufVxuXG4vLyBGb3IgcGFja2VkIHJlc2hhcGUsIHdlIG5lZWQgdG8gcmUtYXJyYW5nZSB0ZXhlbCBkYXRhIGZvciBvdXRwdXQgc2hhcGUuXG4vLyBPdXIgcGFjayBpcyBkZXNpZ25lZCB0byBwYWNrIGEgMngyIHRpbGUgaW4gbGFzdCBoIGFuZCB3IGRpbWVuc2lvbiwgc29cbi8vIGZvciB0aGUgcmVzaGFwZWQgbmV3IHRlbnNvciwgd2UganVzdCBuZWVkIHRvIHJlLWFycmFuZ2UgdGhlIGxhc3QgaCBhbmRcbi8vIHcgZGltZW5zaW9uLiBGb3IgYW55IHNoYXBlIHRoYXQgaXMgbm90IGluIDNELCBpLmUuIFtiYXRjaCwgVywgSF0sIHdlXG4vLyBmaXJzdCBjb252ZXJ0IGl0IHRvIDNEIGJ5IGNvbGxhcHNpbmcgb3RoZXIgZGltZW5zaW9uIHRvIGJhdGNoIGRpbSwgdGhlblxuLy8gcHJvY2VzcyB3aXRoIHRoZSBsYXN0IHR3byBkaW1lbnNpb25zLlxuLy8gTm90ZTogd2Ugb25seSBuZWVkIHRoZSBzaGFwZSB0ZW5zb3IgdG8gY2FsY3VsYXRlIG91dHB1dCBzaGFwZSwgc28gdGhlXG4vLyBjb250ZW50IGluIHNoYXBlIHRlbnNvciBpcyBuZXZlciB1cGxvYWRlZCB0byBHUFUuIEl0IGlzIGFsd2F5cyBrZXB0IGluIENQVS5cbi8vIFRPRE86IG9wdGltaXplIHRoZSBhbGdvcml0aG0gLS0gaW4gc29tZSBjYXNlcywgaWYgdGhlIGxhc3QgdHdvIGRpbXMgYXJlXG4vLyB0aGUgc2FtZSBiZXR3ZWVuIGlucHV0IHNoYXBlIGFuZCBvdXRwdXQgc2hhcGUsIHRoZSBwYWNrZWQgcmVzaGFwZSBjYW4gYmVcbi8vIHRyZWF0ZWQgYXMgbm8tb3AuXG5leHBvcnQgZnVuY3Rpb24gaXNSZXNoYXBlQ2hlYXAoZGltczogcmVhZG9ubHkgbnVtYmVyW10sIHJlc2hhcGVkRGltczogcmVhZG9ubHkgbnVtYmVyW10pIHtcbiAgbGV0IGlzQ2hlYXBSZXNoYXBlID0gZmFsc2U7XG4gIGlmIChkaW1zLmxlbmd0aCA9PT0gMCB8fCByZXNoYXBlZERpbXMubGVuZ3RoID09PSAwKSB7ICAvLyBzY2FsYXJcbiAgICBpc0NoZWFwUmVzaGFwZSA9IHRydWU7XG4gIH0gZWxzZSBpZiAoZGltcy5sZW5ndGggPCAyIHx8IHJlc2hhcGVkRGltcy5sZW5ndGggPCAyKSB7ICAvLyAxRFxuICAgIGlzQ2hlYXBSZXNoYXBlID0gZGltc1tkaW1zLmxlbmd0aCAtIDFdID09PSByZXNoYXBlZERpbXNbcmVzaGFwZWREaW1zLmxlbmd0aCAtIDFdO1xuICB9IGVsc2UgeyAgLy8gMkQgK1xuICAgIGlzQ2hlYXBSZXNoYXBlID0gZGltc1tkaW1zLmxlbmd0aCAtIDFdID09PSByZXNoYXBlZERpbXNbcmVzaGFwZWREaW1zLmxlbmd0aCAtIDFdICYmXG4gICAgICAgIGRpbXNbZGltcy5sZW5ndGggLSAyXSA9PT0gcmVzaGFwZWREaW1zW3Jlc2hhcGVkRGltcy5sZW5ndGggLSAyXTtcbiAgfVxuXG4gIHJldHVybiBpc0NoZWFwUmVzaGFwZTtcbn1cblxuZnVuY3Rpb24gZ2V0UmVzaGFwZWRJbnB1dENvb3JkcyhzaGFwZTogW251bWJlciwgbnVtYmVyLCBudW1iZXJdKTogc3RyaW5nIHtcbiAgY29uc3Qgc3RyaWRlcyA9IFNoYXBlVXRpbC5jb21wdXRlU3RyaWRlcyhzaGFwZSk7XG4gIGNvbnN0IGNvb3JkcyA9IFsnYicsICdyJywgJ2MnXTtcbiAgY29uc3QgaW5kZXggPSAnaW5kZXgnO1xuICBjb25zdCBjb29yZHNGcm9tSW5kZXhTbmlwcGV0ID0gc3RyaWRlc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5tYXAoKHN0cmlkZSwgaSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbGluZTEgPSBgaW50ICR7Y29vcmRzW2ldfSA9ICR7aW5kZXh9IC8gJHtzdHJpZGV9YDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGxpbmUyID0gaSA9PT0gc3RyaWRlcy5sZW5ndGggLSAxID9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgaW50ICR7Y29vcmRzW2kgKyAxXX0gPSAke2luZGV4fSAtICR7Y29vcmRzW2ldfSAqICR7c3RyaWRlfWAgOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBpbmRleCAtPSAke2Nvb3Jkc1tpXX0gKiAke3N0cmlkZX1gO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGAke2xpbmUxfTsgJHtsaW5lMn07YDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5qb2luKCcnKTtcblxuICByZXR1cm4gYFxuICAgIGl2ZWMzIGlucHV0Q29vcmRzRnJvbVJlc2hhcGVkT3V0Q29vcmRzKGludCBpbmRleCkge1xuICAgICAgJHtjb29yZHNGcm9tSW5kZXhTbmlwcGV0fVxuICAgICAgcmV0dXJuIGl2ZWMzKGIsIHIsIGMpO1xuICAgIH1cbiAgYDtcbn1cblxuZnVuY3Rpb24gZ2V0RmxhdHRlbmVkSW5kZXhGcm9tM0Qoc2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSk6IHN0cmluZyB7XG4gIGNvbnN0IHN0cmlkZXMgPSBTaGFwZVV0aWwuY29tcHV0ZVN0cmlkZXMoc2hhcGUpO1xuXG4gIHJldHVybiBgXG4gIGludCBnZXRGbGF0dGVuZWRJbmRleChpdmVjMyBjb29yZHMpIHtcbiAgICAvLyByZXZlcnNlIHksIHogb3JkZXJcbiAgICByZXR1cm4gY29vcmRzLnggKiAke3N0cmlkZXNbMF19ICsgY29vcmRzLnogKiAke3N0cmlkZXNbMV19ICsgY29vcmRzLnk7XG4gIH1cbmA7XG59XG4iLCIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtUZW5zb3J9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQge1NoYXBlVXRpbH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQge1dlYkdMSW5mZXJlbmNlSGFuZGxlcn0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuXG5leHBvcnQgY29uc3QgcmVzaGFwZSA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiB7XG4gIGNvbnN0IHJlc2hhcGVkRGltcyA9IFNoYXBlVXRpbC5jYWxjdWxhdGVSZXNoYXBlZERpbXMoaW5wdXRzWzBdLmRpbXMsIGlucHV0c1sxXS5pbnRlZ2VyRGF0YSk7XG4gIGlmIChoYW5kbGVyLnNlc3Npb24ucGFjaykge1xuICAgIHJldHVybiBbaGFuZGxlci5yZXNoYXBlUGFja2VkKGlucHV0c1swXSwgcmVzaGFwZWREaW1zKV07XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIFtoYW5kbGVyLnJlc2hhcGVVbnBhY2tlZChpbnB1dHNbMF0sIHJlc2hhcGVkRGltcyldO1xuICB9XG59O1xuIiwiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7R3JhcGh9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7T3BlcmF0b3JJbXBsZW1lbnRhdGlvbiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbn0gZnJvbSAnLi4vLi4vLi4vb3BlcmF0b3JzJztcbmltcG9ydCB7VGVuc29yfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHtnZXRHbHNsfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQge1dlYkdMSW5mZXJlbmNlSGFuZGxlcn0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHtQcm9ncmFtSW5mbywgVGV4dHVyZVR5cGV9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB7Z2V0Q29vcmRzRGF0YVR5cGV9IGZyb20gJy4uL3V0aWxzJztcblxuaW1wb3J0IHt1bnBhY2tGcm9tQ2hhbm5lbH0gZnJvbSAnLi9wYWNraW5nLXV0aWxzJztcbmltcG9ydCB7cGFyc2VVcHNhbXBsZUF0dHJpYnV0ZXMsIHNjYWxlc1ZhbGlkYXRpb24sIFVwc2FtcGxlQXR0cmlidXRlcywgdmFsaWRhdGVJbnB1dHN9IGZyb20gJy4vdXBzYW1wbGUnO1xuXG5jb25zdCByZXNpemVQcm9ncmFtTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdSZXNpemUnLFxuICBpbnB1dE5hbWVzOiBbJ0EnXSxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnBhY2tlZF1cbn07XG5cbmV4cG9ydCBjb25zdCByZXNpemU6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248VXBzYW1wbGVBdHRyaWJ1dGVzPiA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogVXBzYW1wbGVBdHRyaWJ1dGVzKTogVGVuc29yW10gPT4ge1xuICAgICAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzLCBhdHRyaWJ1dGVzKTtcbiAgICAgIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIC4uLnJlc2l6ZVByb2dyYW1NZXRhZGF0YSxcbiAgICAgICAgICAgIGNhY2hlSGludDogYXR0cmlidXRlcy5jYWNoZUtleSxcbiAgICAgICAgICAgIGdldDogKCkgPT4gY3JlYXRlUGFja2VkUmVzaXplUHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzLCBhdHRyaWJ1dGVzKVxuICAgICAgICAgIH0sXG4gICAgICAgICAgaW5wdXRzKTtcbiAgICAgIHJldHVybiBbb3V0cHV0XTtcbiAgICB9O1xuXG5leHBvcnQgY29uc3QgcGFyc2VSZXNpemVBdHRyaWJ1dGVzVjEwOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPFVwc2FtcGxlQXR0cmlidXRlcz4gPVxuICAgIChub2RlOiBHcmFwaC5Ob2RlKTogVXBzYW1wbGVBdHRyaWJ1dGVzID0+IHBhcnNlVXBzYW1wbGVBdHRyaWJ1dGVzKG5vZGUsIDEwKTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlUmVzaXplQXR0cmlidXRlc1YxMTogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxVcHNhbXBsZUF0dHJpYnV0ZXM+ID1cbiAgICAobm9kZTogR3JhcGguTm9kZSk6IFVwc2FtcGxlQXR0cmlidXRlcyA9PiBwYXJzZVVwc2FtcGxlQXR0cmlidXRlcyhub2RlLCAxMSk7XG5cbmNvbnN0IGNyZWF0ZVBhY2tlZFJlc2l6ZVByb2dyYW1JbmZvID1cbiAgICAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBVcHNhbXBsZUF0dHJpYnV0ZXMpOiBQcm9ncmFtSW5mbyA9PiB7XG4gICAgICBjb25zdCBnbHNsID0gZ2V0R2xzbChpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gICAgICBjb25zdCBbc2NhbGVzLCBvdXRwdXRTaGFwZV0gPSBwcmVwYXJlSW5wdXRzKGlucHV0cywgYXR0cmlidXRlcyk7XG5cbiAgICAgIGNvbnN0IGlzU2FtZSA9XG4gICAgICAgICAgc2NhbGVzLmV2ZXJ5KChzOiBudW1iZXIpID0+IHMgPT09IDEpICYmIGF0dHJpYnV0ZXMuY29vcmRpbmF0ZVRyYW5zZm9ybU1vZGUgIT09ICd0Zl9jcm9wX2FuZF9yZXNpemUnO1xuICAgICAgaWYgKGlzU2FtZSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIC4uLnJlc2l6ZVByb2dyYW1NZXRhZGF0YSxcbiAgICAgICAgICBvdXRwdXQ6IHtkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXRzWzBdLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS5wYWNrZWR9LFxuICAgICAgICAgIGhhc01haW46IHRydWUsXG4gICAgICAgICAgc2hhZGVyU291cmNlOiBgdm9pZCBtYWluKCkge1xuICAgICAgICAgICAgICAgICAgICB2ZWM0IHYgPSAke2dsc2wudGV4dHVyZTJEfShYLCBUZXhDb29yZHMpO1xuICAgICAgICAgICAgICAgICAgICAke2dsc2wub3V0cHV0fSA9IHY7XG4gICAgICAgICAgICAgICAgfWBcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZGltID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuICAgICAgaWYgKGRpbSA8IDIpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBvdXRwdXQgZGltZW5zaW9uIHNob3VsZCBiZSBhdCBsZWFzdCAyLCBidXQgZ290ICR7ZGltfWApO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBvdXRwdXRIZWlnaHQgPSBvdXRwdXRTaGFwZVtkaW0gLSAyXTtcbiAgICAgIGNvbnN0IG91dHB1dFdpZHRoID0gb3V0cHV0U2hhcGVbZGltIC0gMV07XG5cbiAgICAgIGNvbnN0IGlucHV0U2hhcGUgPSBpbnB1dHNbMF0uZGltcztcbiAgICAgIGlmIChkaW0gIT09IGlucHV0U2hhcGUubGVuZ3RoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgb3V0cHV0IGRpbWVuc2lvbiBzaG91bGQgbWF0Y2ggaW5wdXQgJHtpbnB1dFNoYXBlLmxlbmd0aH0sIGJ1dCBnb3QgJHtkaW19YCk7XG4gICAgICB9XG4gICAgICBjb25zdCBpbnB1dEhlaWdodCA9IGlucHV0U2hhcGVbZGltIC0gMl07XG4gICAgICBjb25zdCBpbnB1dFdpZHRoID0gaW5wdXRTaGFwZVtkaW0gLSAxXTtcblxuICAgICAgY29uc3Qgc2NhbGVzSGVpZ2h0ID0gc2NhbGVzW2RpbSAtIDJdO1xuICAgICAgY29uc3Qgc2NhbGVzV2lkdGggPSBzY2FsZXNbZGltIC0gMV07XG5cbiAgICAgIGxldCBnZXRTb3VyY2VGcmFjSW5kZXggPSAnJztcblxuICAgICAgaWYgKGF0dHJpYnV0ZXMubW9kZSAhPT0gJ2xpbmVhcicpIHtcbiAgICAgICAgLy8gVE9ETzogc3VwcG9ydCBvdGhlciBtb2Rlc1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHJlc2l6ZSAocGFja2VkKSBkb2VzIG5vdCBzdXBwb3J0IG1vZGU6ICcke2F0dHJpYnV0ZXMubW9kZX0nYCk7XG4gICAgICB9XG4gICAgICBzd2l0Y2ggKGF0dHJpYnV0ZXMuY29vcmRpbmF0ZVRyYW5zZm9ybU1vZGUpIHtcbiAgICAgICAgY2FzZSAnYXN5bW1ldHJpYyc6XG4gICAgICAgICAgZ2V0U291cmNlRnJhY0luZGV4ID0gYFxuICAgICAgICAgICAgICAgICAgICB2ZWM0IGdldFNvdXJjZUZyYWNJbmRleChpdmVjNCBjb29yZHMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB2ZWM0KGNvb3JkcykgLyBzY2FsZVdIV0g7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBgO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdoYWxmX3BpeGVsJzpcbiAgICAgICAgICBnZXRTb3VyY2VGcmFjSW5kZXggPSBgXG4gICAgICAgICAgICAgICAgICAgIHZlYzQgZ2V0U291cmNlRnJhY0luZGV4KGl2ZWM0IGNvb3Jkcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICh2ZWM0KGNvb3JkcykgKyAwLjUpIC8gc2NhbGVXSFdIIC0gMC41O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAncHl0b3JjaF9oYWxmX3BpeGVsJzpcbiAgICAgICAgICBnZXRTb3VyY2VGcmFjSW5kZXggPSBgXG4gICAgICAgICAgICAgICAgICAgIHZlYzQgZ2V0U291cmNlRnJhY0luZGV4KGl2ZWM0IGNvb3Jkcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmVjNCBmY29vcmRzID0gdmVjNChjb29yZHMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZlYzQoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJHtvdXRwdXRXaWR0aH0uMCA+IDEuMCA/IChmY29vcmRzLnggKyAwLjUpIC8gc2NhbGVXSFdILnggLSAwLjUgOiAwLjAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJHtvdXRwdXRIZWlnaHR9LjAgPiAxLjAgPyAoZmNvb3Jkcy55ICsgMC41KSAvIHNjYWxlV0hXSC55IC0gMC41IDogMC4wLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICR7b3V0cHV0V2lkdGh9LjAgPiAxLjAgPyAoZmNvb3Jkcy56ICsgMC41KSAvIHNjYWxlV0hXSC56IC0gMC41IDogMC4wLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICR7b3V0cHV0SGVpZ2h0fS4wID4gMS4wID8gKGZjb29yZHMudyArIDAuNSkgLyBzY2FsZVdIV0gudyAtIDAuNSA6IDAuMFxuICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnYWxpZ25fY29ybmVycyc6XG4gICAgICAgICAgZ2V0U291cmNlRnJhY0luZGV4ID0gYFxuICAgICAgICAgICAgICAgICAgICB2ZWM0IGdldFNvdXJjZUZyYWNJbmRleChpdmVjNCBjb29yZHMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZlYzQgcmVzaXplZCA9IHZlYzQoJHtvdXRwdXRXaWR0aH0uMCAtIDEuMCwgJHtvdXRwdXRIZWlnaHR9LjAgLSAxLjAsICR7b3V0cHV0V2lkdGh9LjAgLSAxLjAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJHtvdXRwdXRIZWlnaHR9LjAgLSAxLjApO1xuICAgICAgICAgICAgICAgICAgICAgICAgdmVjNCBvcmlnaW5hbCA9IHZlYzQoJHtpbnB1dFdpZHRofS4wIC0gMS4wLCAke2lucHV0SGVpZ2h0fS4wIC0gMS4wLCAke2lucHV0V2lkdGh9LjAgLSAxLjAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJHtpbnB1dEhlaWdodH0uMCAtIDEuMCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB2ZWM0IG5ld19zY2FsZSA9IG9yaWdpbmFsIC8gcmVzaXplZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB2ZWM0KGNvb3JkcykgKiBuZXdfc2NhbGU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBgO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIC8vIFRPRE86c3VwcG9ydGluZyBvdGhlciBjb29yZGluYXRlVHJhbnNmb3JtTW9kZXNcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHJlc2l6ZSAocGFja2VkKSBkb2VzIG5vdCBzdXBwb3J0IGNvb3JkaW5hdGVUcmFuc2Zvcm1Nb2RlOiBcXFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnJHthdHRyaWJ1dGVzLmNvb3JkaW5hdGVUcmFuc2Zvcm1Nb2RlfSdgKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgY29vcmRzRGF0YVR5cGUgPSBnZXRDb29yZHNEYXRhVHlwZShkaW0pO1xuICAgICAgY29uc3QgdW5wYWNrQ2hhbm5lbCA9IHVucGFja0Zyb21DaGFubmVsKCk7XG4gICAgICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICAgICAgICBjb25zdCB2ZWMyIGlucHV0V0ggPSB2ZWMyKCR7aW5wdXRIZWlnaHR9LjAsICR7aW5wdXRXaWR0aH0uMCk7XG4gICAgICAgICAgICBjb25zdCB2ZWM0IHNjYWxlV0hXSCA9IHZlYzQoZmxvYXQoJHtzY2FsZXNIZWlnaHR9KSwgZmxvYXQoJHtzY2FsZXNXaWR0aH0pLCBmbG9hdCgke3NjYWxlc0hlaWdodH0pLCBmbG9hdCgke1xuICAgICAgICAgIHNjYWxlc1dpZHRofSkpO1xuICAgICAgICAgICAgJHt1bnBhY2tDaGFubmVsfVxuICAgICAgICAgICAgJHtnZXRTb3VyY2VGcmFjSW5kZXh9XG4gICAgICAgICAgICBmbG9hdCBnZXRBVmFsdWUoaW50IHgxMCwgaW50IHIsIGludCBjLCBpbnQgZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBnZXRDaGFubmVsKGdldEEoeDEwLCByLCBjLCBkKSwgdmVjMihjLCBkKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2b2lkIG1haW4oKSB7XG4gICAgICAgICAgICAgICAgJHtjb29yZHNEYXRhVHlwZX0gcmMgPSBnZXRPdXRwdXRDb29yZHMoKTtcblxuICAgICAgICAgICAgICAgIGludCBiYXRjaCA9IHJjWzBdO1xuICAgICAgICAgICAgICAgIGludCBkZXB0aCA9IHJjWzFdO1xuXG4gICAgICAgICAgICAgICAgLy8gcmV0cmlldmUgdGhlIDQgY29vcmRpbmF0ZXMgdGhhdCBpcyB1c2VkIGluIHRoZSA0IHBhY2tlZCBvdXRwdXQgdmFsdWVzLlxuICAgICAgICAgICAgICAgIGl2ZWM0IGNvb3JkcyA9IGl2ZWM0KHJjLnd6LCByYy53ICsgMSwgcmMueiArIDEpO1xuXG4gICAgICAgICAgICAgICAgLy8gY2FsY3VsYXRlIHRoZSBzb3VyY2UgaW5kZXggaW4gZnJhY3Rpb25cbiAgICAgICAgICAgICAgICB2ZWM0IHNvdXJjZUZyYWMgPSBnZXRTb3VyY2VGcmFjSW5kZXgoY29vcmRzKTtcblxuICAgICAgICAgICAgICAgIC8vIGdldCB0aGUgbG93ZXIgYW5kIHVwcGVyIGJvdW5kIG9mIHRoZSA0IHZhbHVlcyB0aGF0IHdpbGwgYmUgcGFja2VkIGludG8gb25lIHRleGVsLlxuICAgICAgICAgICAgICAgIGl2ZWM0IHgwMCA9IGl2ZWM0KG1heChzb3VyY2VGcmFjLnh5LCB2ZWMyKDAuMCkpLCBtaW4oaW5wdXRXSCAtIDEuMCwgY2VpbChzb3VyY2VGcmFjLnh5KSkpO1xuICAgICAgICAgICAgICAgIGl2ZWM0IHgwMSA9IGl2ZWM0KG1heChzb3VyY2VGcmFjLnh3LCB2ZWMyKDAuMCkpLCBtaW4oaW5wdXRXSCAtIDEuMCwgY2VpbChzb3VyY2VGcmFjLnh3KSkpO1xuICAgICAgICAgICAgICAgIGl2ZWM0IHgxMCA9IGl2ZWM0KG1heChzb3VyY2VGcmFjLnp5LCB2ZWMyKDAuMCkpLCBtaW4oaW5wdXRXSCAtIDEuMCwgY2VpbChzb3VyY2VGcmFjLnp5KSkpO1xuICAgICAgICAgICAgICAgIGl2ZWM0IHgxMSA9IGl2ZWM0KG1heChzb3VyY2VGcmFjLnp3LCB2ZWMyKDAuMCkpLCBtaW4oaW5wdXRXSCAtIDEuMCwgY2VpbChzb3VyY2VGcmFjLnp3KSkpO1xuXG4gICAgICAgICAgICAgICAgYm9vbCBoYXNOZXh0Um93ID0gcmMudyA8ICR7b3V0cHV0SGVpZ2h0IC0gMX07XG4gICAgICAgICAgICAgICAgYm9vbCBoYXNOZXh0Q29sID0gcmMueiA8ICR7b3V0cHV0V2lkdGggLSAxfTtcblxuICAgICAgICAgICAgICAgIC8vIHBhY2sgeDAwLCB4MDEsIHgxMCwgeDExJ3MgdG9wLWxlZnQgY29ybmVyIGludG8gb25lIHZlYzQgc3RydWN0dXJlXG4gICAgICAgICAgICAgICAgdmVjNCB0b3BMZWZ0ID0gdmVjNChcbiAgICAgICAgICAgICAgICAgICAgZ2V0QVZhbHVlKGJhdGNoLCBkZXB0aCwgeDAwLngsIHgwMC55KSxcbiAgICAgICAgICAgICAgICAgICAgaGFzTmV4dENvbCA/IGdldEFWYWx1ZShiYXRjaCwgZGVwdGgsIHgwMS54LCB4MDEueSkgOiAwLjAsXG4gICAgICAgICAgICAgICAgICAgIGhhc05leHRSb3cgPyBnZXRBVmFsdWUoYmF0Y2gsIGRlcHRoLCB4MTAueCwgeDEwLnkpIDogMC4wLFxuICAgICAgICAgICAgICAgICAgICAoaGFzTmV4dFJvdyAmJiBoYXNOZXh0Q29sKSA/IGdldEFWYWx1ZShiYXRjaCwgZGVwdGgsIHgxMS54LCB4MTEueSkgOiAwLjApO1xuXG4gICAgICAgICAgICAgICAgLy8gcGFjayB4MDAsIHgwMSwgeDEwLCB4MTEncyB0b3AtcmlnaHQgY29ybmVyIGludG8gb25lIHZlYzQgc3RydWN0dXJlXG4gICAgICAgICAgICAgICAgdmVjNCB0b3BSaWdodCA9IHZlYzQoXG4gICAgICAgICAgICAgICAgICAgIGdldEFWYWx1ZShiYXRjaCwgZGVwdGgsIHgwMC54LCB4MDAudyksXG4gICAgICAgICAgICAgICAgICAgIGhhc05leHRDb2wgPyBnZXRBVmFsdWUoYmF0Y2gsIGRlcHRoLCB4MDEueCwgeDAxLncpIDogMC4wLFxuICAgICAgICAgICAgICAgICAgICBoYXNOZXh0Um93ID8gZ2V0QVZhbHVlKGJhdGNoLCBkZXB0aCwgeDEwLngsIHgxMC53KSA6IDAuMCxcbiAgICAgICAgICAgICAgICAgICAgKGhhc05leHRSb3cgJiYgaGFzTmV4dENvbCkgPyBnZXRBVmFsdWUoYmF0Y2gsIGRlcHRoLCB4MTEueCwgeDExLncpIDogMC4wKTtcblxuICAgICAgICAgICAgICAgIC8vIHBhY2sgeDAwLCB4MDEsIHgxMCwgeDExJ3MgYm90dG9tLWxlZnQgY29ybmVyIGludG8gb25lIHZlYzQgc3RydWN0dXJlXG4gICAgICAgICAgICAgICAgdmVjNCBib3R0b21MZWZ0ID0gdmVjNChcbiAgICAgICAgICAgICAgICAgICAgZ2V0QVZhbHVlKGJhdGNoLCBkZXB0aCwgeDAwLnosIHgwMC55KSxcbiAgICAgICAgICAgICAgICAgICAgaGFzTmV4dENvbCA/IGdldEFWYWx1ZShiYXRjaCwgZGVwdGgsIHgwMS56LCB4MDEueSkgOiAwLjAsXG4gICAgICAgICAgICAgICAgICAgIGhhc05leHRSb3cgPyBnZXRBVmFsdWUoYmF0Y2gsIGRlcHRoLCB4MTAueiwgeDEwLnkpIDogMC4wLFxuICAgICAgICAgICAgICAgICAgICAoaGFzTmV4dFJvdyAmJiBoYXNOZXh0Q29sKSA/IGdldEFWYWx1ZShiYXRjaCwgZGVwdGgsIHgxMS56LCB4MTEueSkgOiAwLjApO1xuXG4gICAgICAgICAgICAgICAgLy8gcGFjayB4MDAsIHgwMSwgeDEwLCB4MTEncyBib3R0b20tcmlnaHQgY29ybmVyIGludG8gb25lIHZlYzQgc3RydWN0dXJlXG4gICAgICAgICAgICAgICAgdmVjNCBib3R0b21SaWdodCA9IHZlYzQoXG4gICAgICAgICAgICAgICAgICAgIGdldEFWYWx1ZShiYXRjaCwgZGVwdGgsIHgwMC56LCB4MDAudyksXG4gICAgICAgICAgICAgICAgICAgIGhhc05leHRDb2wgPyBnZXRBVmFsdWUoYmF0Y2gsIGRlcHRoLCB4MDEueiwgeDAxLncpIDogMC4wLFxuICAgICAgICAgICAgICAgICAgICBoYXNOZXh0Um93ID8gZ2V0QVZhbHVlKGJhdGNoLCBkZXB0aCwgeDEwLnosIHgxMC53KSA6IDAuMCxcbiAgICAgICAgICAgICAgICAgICAgKGhhc05leHRSb3cgJiYgaGFzTmV4dENvbCkgPyBnZXRBVmFsdWUoYmF0Y2gsIGRlcHRoLCB4MTEueiwgeDExLncpIDogMC4wKTtcblxuICAgICAgICAgICAgICAgIC8vIGNhbGN1bGF0ZSB0aGUgaW50ZXJwb2xhdGlvbiBmcmFjdGlvbiBvbiB1IGFuZCB2IGRpcmVjdGlvblxuICAgICAgICAgICAgICAgIHZlYzQgZnJhYyA9IHZlYzQoc291cmNlRnJhYykgLSBmbG9vcihzb3VyY2VGcmFjKTtcbiAgICAgICAgICAgICAgICB2ZWM0IGNsYW1wRnJhYyA9IGNsYW1wKGZyYWMsIHZlYzQoMC4wKSwgdmVjNCgxLjApKTtcblxuICAgICAgICAgICAgICAgIHZlYzQgdG9wID0gbWl4KHRvcExlZnQsIHRvcFJpZ2h0LCBjbGFtcEZyYWMueXd5dyk7XG4gICAgICAgICAgICAgICAgdmVjNCBib3R0b20gPSBtaXgoYm90dG9tTGVmdCwgYm90dG9tUmlnaHQsIGNsYW1wRnJhYy55d3l3KTtcbiAgICAgICAgICAgICAgICB2ZWM0IG5ld1ZhbHVlID0gbWl4KHRvcCwgYm90dG9tLCBjbGFtcEZyYWMueHh6eik7XG5cbiAgICAgICAgICAgICAgICAke2dsc2wub3V0cHV0fSA9IHZlYzQobmV3VmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICBgO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4ucmVzaXplUHJvZ3JhbU1ldGFkYXRhLFxuICAgICAgICBvdXRwdXQ6IHtkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXRzWzBdLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS5wYWNrZWR9LFxuICAgICAgICBoYXNNYWluOiB0cnVlLFxuICAgICAgICBzaGFkZXJTb3VyY2VcbiAgICAgIH07XG4gICAgfTtcblxuXG5jb25zdCBwcmVwYXJlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IFVwc2FtcGxlQXR0cmlidXRlcyk6IFtyZWFkb25seSBudW1iZXJbXSwgcmVhZG9ubHkgbnVtYmVyW11dID0+IHtcbiAgY29uc3QgeCA9IGlucHV0c1swXTtcbiAgY29uc3QgeERpbXMgPSB4LmRpbXM7XG5cbiAgbGV0IHNjYWxlcyA9IGF0dHJpYnV0ZXMuc2NhbGVzO1xuICBsZXQgb3V0cHV0U2l6ZXM6IG51bWJlcltdfHVuZGVmaW5lZDtcbiAgaWYgKHNjYWxlcy5sZW5ndGggPT09IDApIHtcbiAgICBjb25zdCBzY2FsZXNUZW5zb3IgPSBpbnB1dHNbYXR0cmlidXRlcy5zY2FsZXNJbnB1dElkeF07XG4gICAgaWYgKHNjYWxlc1RlbnNvciAmJiBzY2FsZXNUZW5zb3Iuc2l6ZSAhPT0gMCkge1xuICAgICAgaWYgKGlucHV0c1thdHRyaWJ1dGVzLnNpemVzSW5wdXRJZHhdKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignT25seSBvbmUgb2Ygc2NhbGVzIG9yIHNpemVzIG11c3QgYmUgcHJvdmlkZWQgYXMgaW5wdXQuJyk7XG4gICAgICB9XG4gICAgICBzY2FsZXMgPSBwYXJzZVNjYWxlc0RhdGEoc2NhbGVzVGVuc29yLCBhdHRyaWJ1dGVzLm1vZGUsIGF0dHJpYnV0ZXMuaXNSZXNpemUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBzaXplc1RlbnNvciA9IGlucHV0c1thdHRyaWJ1dGVzLnNpemVzSW5wdXRJZHhdO1xuICAgICAgaWYgKCFzaXplc1RlbnNvciB8fCBzaXplc1RlbnNvci5zaXplID09PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignRWl0aGVyIHNjYWxlcyBvciBzaXplcyBNVVNUIGJlIHByb3ZpZGVkIGFzIGlucHV0LicpO1xuICAgICAgfVxuXG4gICAgICBvdXRwdXRTaXplcyA9IEFycmF5LmZyb20oc2l6ZXNUZW5zb3IuaW50ZWdlckRhdGEpO1xuICAgICAgc2NhbGVzID0gcGFyc2VTY2FsZXNEYXRhRnJvbU91dHB1dFNpemUob3V0cHV0U2l6ZXMsIHhEaW1zLCBhdHRyaWJ1dGVzLm1vZGUsIGF0dHJpYnV0ZXMuaXNSZXNpemUpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpZiAoaW5wdXRzW2F0dHJpYnV0ZXMuc2l6ZXNJbnB1dElkeF0pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignT25seSBvbmUgb2Ygc2NhbGVzIG9yIHNpemVzIG11c3QgYmUgcHJvdmlkZWQgYXMgaW5wdXQuJyk7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgeURpbXMgPSBvdXRwdXRTaXplcyB8fCAoeERpbXMubWFwKChkaW0sIGkpID0+IE1hdGguZmxvb3IoZGltICogc2NhbGVzW2ldKSkpO1xuXG4gIHJldHVybiBbc2NhbGVzLCB5RGltc107XG59O1xuXG5jb25zdCBwYXJzZVNjYWxlc0RhdGEgPSAoc2NhbGU6IFRlbnNvciwgbW9kZTogc3RyaW5nLCBpc1Jlc2l6ZTogYm9vbGVhbik6IG51bWJlcltdID0+IHtcbiAgY29uc3Qgc2NhbGVzID0gQXJyYXkuZnJvbShzY2FsZS5mbG9hdERhdGEpO1xuICBzY2FsZXNWYWxpZGF0aW9uKHNjYWxlcywgbW9kZSwgaXNSZXNpemUpO1xuICByZXR1cm4gc2NhbGVzO1xufTtcblxuY29uc3QgcGFyc2VTY2FsZXNEYXRhRnJvbU91dHB1dFNpemUgPVxuICAgICh5RGltczogcmVhZG9ubHkgbnVtYmVyW10sIHhEaW1zOiByZWFkb25seSBudW1iZXJbXSwgbW9kZTogc3RyaW5nLCBpc1Jlc2l6ZTogYm9vbGVhbik6IG51bWJlcltdID0+IHtcbiAgICAgIGNvbnN0IGxlbmd0aCA9IHhEaW1zLmxlbmd0aDtcbiAgICAgIGNvbnN0IHNjYWxlcyA9IG5ldyBBcnJheTxudW1iZXI+KGxlbmd0aCk7XG5cbiAgICAgIGZvciAobGV0IGkgPSAwLCBlbmQgPSBsZW5ndGg7IGkgPCBlbmQ7IGkrKykge1xuICAgICAgICBpZiAoeERpbXNbaV0gPT09IDApIHtcbiAgICAgICAgICBpZiAoeURpbXNbaV0gIT09IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgZGltIGlzIHplcm8gYnV0IHJlcXVpcmVkIG91dHB1dCBkaW0gaXMgbm9uLXplcm8uJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHNjYWxlc1tpXSA9IDE7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc2NhbGVzW2ldID0geURpbXNbaV0gLyB4RGltc1tpXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgc2NhbGVzVmFsaWRhdGlvbihzY2FsZXMsIG1vZGUsIGlzUmVzaXplKTtcbiAgICAgIHJldHVybiBzY2FsZXM7XG4gICAgfTtcblxuLy8gcm9pIGRhdGEgaXMgbm90IHVzZWQgeWV0LiBidXQgbGVhdmUgaGVyZSBmb3IgZnV0dXJlIHVzYWdlLlxuLy8gY29uc3QgZ2V0Um9pID0gKGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IFVwc2FtcGxlQXR0cmlidXRlcykgOiBudW1iZXJbXSA9PiB7XG4vLyAgICAgbGV0IHJvaTogbnVtYmVyW10gPSBbXTtcbi8vICAgICBpZiAoYXR0cmlidXRlcy5uZWVkUm9pSW5wdXQpIHtcbi8vICAgICAgICAgaWYgKGF0dHJpYnV0ZXMucm9pSW5wdXRJZHggPD0gMCkge1xuLy8gICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHJvaSBpbnB1dCBpbmRleC4nKTtcbi8vICAgICAgICAgfVxuLy8gICAgICAgICBjb25zdCByb2lUZW5zb3IgPSBpbnB1dHNbYXR0cmlidXRlcy5yb2lJbnB1dElkeF07XG4vLyAgICAgICAgIHJvaSA9IHJvaVRlbnNvci5zaXplID4gMCA/IEFycmF5LmZyb20ocm9pVGVuc29yLmZsb2F0RGF0YSkgOiBbXTtcbi8vICAgICB9IGVsc2Uge1xuLy8gICAgICAgICByb2kgPSBuZXcgQXJyYXkoaW5wdXRzWzBdLmRpbXMubGVuZ3RoICogMikuZmlsbCgwKTtcbi8vICAgICB9XG4vLyAgICAgcmV0dXJuIHJvaTtcbi8vIH07XG4iLCIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtUZW5zb3J9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQge1dlYkdMSW5mZXJlbmNlSGFuZGxlcn0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuXG5leHBvcnQgY29uc3Qgc2hhcGUgPSAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4ge1xuICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuICByZXR1cm4gW25ldyBUZW5zb3IoW2lucHV0c1swXS5kaW1zLmxlbmd0aF0sICdpbnQzMicsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCBuZXcgSW50MzJBcnJheShpbnB1dHNbMF0uZGltcykpXTtcbn07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignU2hhcGUgcmVxdWlyZXMgMSBpbnB1dC4nKTtcbiAgfVxufTsiLCIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleX0gZnJvbSAnLi4vLi4vLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7R3JhcGh9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7TlVNQkVSX1RZUEVTLCBPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9ufSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHtUZW5zb3J9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQge1NoYXBlVXRpbH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQge1dlYkdMSW5mZXJlbmNlSGFuZGxlcn0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHtQcm9ncmFtSW5mbywgVGV4dHVyZVR5cGV9IGZyb20gJy4uL3R5cGVzJztcblxuZXhwb3J0IGludGVyZmFjZSBTbGljZUF0dHJpYnV0ZXMgZXh0ZW5kcyBBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkge1xuICByZWFkb25seSBheGVzOiBudW1iZXJbXTtcbiAgcmVhZG9ubHkgZW5kczogbnVtYmVyW107XG4gIHJlYWRvbmx5IHN0YXJ0czogbnVtYmVyW107XG59XG5cbmNvbnN0IHNsaWNlUHJvZ3JhbU1ldGFkYXRhID0ge1xuICBuYW1lOiAnU2xpY2UnLFxuICBpbnB1dE5hbWVzOiBbJ0EnXSxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkXVxufTtcblxuZXhwb3J0IGNvbnN0IHNsaWNlOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPFNsaWNlQXR0cmlidXRlcz4gPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IFNsaWNlQXR0cmlidXRlcyk6IFRlbnNvcltdID0+IHtcbiAgICAgIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG4gICAgICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICAgICAgICB7XG4gICAgICAgICAgICAuLi5zbGljZVByb2dyYW1NZXRhZGF0YSxcbiAgICAgICAgICAgIGNhY2hlSGludDogYXR0cmlidXRlcy5jYWNoZUtleSxcbiAgICAgICAgICAgIGdldDogKCkgPT4gY3JlYXRlU2xpY2VQcm9ncmFtSW5mbyhpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHNbMF0sIGF0dHJpYnV0ZXMpXG4gICAgICAgICAgfSxcbiAgICAgICAgICBpbnB1dHMpO1xuICAgICAgcmV0dXJuIFtvdXRwdXRdO1xuICAgIH07XG5cbmV4cG9ydCBjb25zdCBwYXJzZVNsaWNlQXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxTbGljZUF0dHJpYnV0ZXM+ID0gKG5vZGU6IEdyYXBoLk5vZGUpOiBTbGljZUF0dHJpYnV0ZXMgPT4ge1xuICBjb25zdCBzdGFydHMgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50cygnc3RhcnRzJyk7XG4gIGNvbnN0IGVuZHMgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50cygnZW5kcycpO1xuICBjb25zdCBheGVzID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludHMoJ2F4ZXMnLCBbXSk7XG4gIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoe3N0YXJ0cywgZW5kcywgYXhlc30pO1xufTtcblxuY29uc3QgY3JlYXRlU2xpY2VQcm9ncmFtSW5mbyA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXQ6IFRlbnNvciwgYXR0cmlidXRlczogU2xpY2VBdHRyaWJ1dGVzKTogUHJvZ3JhbUluZm8gPT4ge1xuICAgICAgY29uc3QgYXhlcyA9IChhdHRyaWJ1dGVzLmF4ZXMubGVuZ3RoID09PSAwKSA/IGlucHV0LmRpbXMuc2xpY2UoMCkubWFwKCh2YWwsIGkpID0+IGkpIDogYXR0cmlidXRlcy5heGVzO1xuICAgICAgY29uc3Qgbm9ybWFsaXplZEF4ZXMgPSBTaGFwZVV0aWwubm9ybWFsaXplQXhlcyhheGVzLCBpbnB1dC5kaW1zLmxlbmd0aCk7XG4gICAgICBjb25zdCBzdGFydHMgPSBhdHRyaWJ1dGVzLnN0YXJ0cy5tYXAoKHN0YXJ0LCBpKSA9PiB7XG4gICAgICAgIGlmIChzdGFydCA+IGlucHV0LmRpbXNbbm9ybWFsaXplZEF4ZXNbaV1dIC0gMSkge1xuICAgICAgICAgIHJldHVybiBpbnB1dC5kaW1zW25vcm1hbGl6ZWRBeGVzW2ldXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gU2hhcGVVdGlsLm5vcm1hbGl6ZUF4aXMoc3RhcnQsIGlucHV0LmRpbXNbbm9ybWFsaXplZEF4ZXNbaV1dKTtcbiAgICAgIH0pO1xuICAgICAgY29uc3QgZW5kcyA9IGF0dHJpYnV0ZXMuZW5kcy5tYXAoKGVuZCwgaSkgPT4ge1xuICAgICAgICBpZiAoZW5kID4gaW5wdXQuZGltc1tub3JtYWxpemVkQXhlc1tpXV0gLSAxKSB7XG4gICAgICAgICAgcmV0dXJuIGlucHV0LmRpbXNbbm9ybWFsaXplZEF4ZXNbaV1dO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBTaGFwZVV0aWwubm9ybWFsaXplQXhpcyhlbmQsIGlucHV0LmRpbXNbbm9ybWFsaXplZEF4ZXNbaV1dKTtcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBvdXRwdXRTaGFwZSA9IGlucHV0LmRpbXMuc2xpY2UoKTtcblxuICAgICAgY29uc3Qgc2xpY2VPcHM6IHN0cmluZ1tdID0gW107XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5vcm1hbGl6ZWRBeGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIG91dHB1dFNoYXBlW25vcm1hbGl6ZWRBeGVzW2ldXSA9IGVuZHNbaV0gLSBzdGFydHNbaV07XG4gICAgICAgIGlmIChzdGFydHNbaV0gPiAwKSB7XG4gICAgICAgICAgc2xpY2VPcHMucHVzaChgb3V0cHV0SWR4WyR7bm9ybWFsaXplZEF4ZXNbaV19XSArPSAke3N0YXJ0c1tpXX07YCk7XG4gICAgICAgIH0gIC8vIGVsc2UgeyBzbGljZU9wcy5wdXNoKGBvdXRwdXRJZHhbJHtub3JtYWxpemVkQXhlc1tpXX1dICs9IDA7YCk7IH1cbiAgICAgIH1cblxuICAgICAgY29uc3QgcmFuayA9IG91dHB1dFNoYXBlLmxlbmd0aDtcbiAgICAgIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgIGZsb2F0IHByb2Nlc3MoaW50IG91dHB1dElkeFske3Jhbmt9XSkge1xuICAgICAgICAke3NsaWNlT3BzLmpvaW4oJ1xcbiAgICAgICcpfVxuICAgICAgICByZXR1cm4gX0Eob3V0cHV0SWR4KTtcbiAgICAgIH1gO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4uc2xpY2VQcm9ncmFtTWV0YWRhdGEsXG4gICAgICAgIG91dHB1dDoge2RpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dC50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWR9LFxuICAgICAgICBzaGFkZXJTb3VyY2VcbiAgICAgIH07XG4gICAgfTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTbGljZSByZXF1aXJlcyAxIGlucHV0LicpO1xuICB9XG4gIGlmIChOVU1CRVJfVFlQRVMuaW5kZXhPZihpbnB1dHNbMF0udHlwZSkgPT09IC0xKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBzbGljZVYxMCA9IChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBUZW5zb3JbXSA9PiB7XG4gIHZhbGlkYXRlSW5wdXRzVjEwKGlucHV0cyk7XG4gIGNvbnN0IGF0dHJpYnV0ZXMgPSBnZW5lcmF0ZVNsaWNlQXR0cmlidXRlc0Zyb21JbnB1dHMoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzKTtcbiAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgICB7XG4gICAgICAgIC4uLnNsaWNlUHJvZ3JhbU1ldGFkYXRhLFxuICAgICAgICBjYWNoZUhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXksXG4gICAgICAgIGdldDogKCkgPT4gY3JlYXRlU2xpY2VQcm9ncmFtSW5mbyhpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHNbMF0sIGF0dHJpYnV0ZXMpXG4gICAgICB9LFxuICAgICAgW2lucHV0c1swXV0pO1xuICByZXR1cm4gW291dHB1dF07XG59O1xuXG5jb25zdCBnZW5lcmF0ZVNsaWNlQXR0cmlidXRlc0Zyb21JbnB1dHMgPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOiBTbGljZUF0dHJpYnV0ZXMgPT4ge1xuICAgICAgaWYgKCFpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uaXNJbml0aWFsaXplcihpbnB1dHNbMV0uZGF0YUlkKSB8fFxuICAgICAgICAgICFpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uaXNJbml0aWFsaXplcihpbnB1dHNbMl0uZGF0YUlkKSB8fFxuICAgICAgICAgIChpbnB1dHMubGVuZ3RoID49IDQgJiYgIWluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5pc0luaXRpYWxpemVyKGlucHV0c1szXS5kYXRhSWQpKSB8fFxuICAgICAgICAgIChpbnB1dHMubGVuZ3RoID49IDUgJiYgIWluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5pc0luaXRpYWxpemVyKGlucHV0c1s0XS5kYXRhSWQpKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2R5bmFtaWMgc2xpY2UgYXR0cmlidXRlcyBhcmUgbm90IGFsbG93ZWQnKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGlucHV0cy5sZW5ndGggPj0gNSAmJiBpbnB1dHNbNF0uaW50ZWdlckRhdGEuc29tZSgoaTogbnVtYmVyKSA9PiBpICE9PSAxKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2N1cnJlbnRseSBub24tMSBzdGVwcyBpcyBub3Qgc3VwcG9ydGVkIGZvciBTbGljZScpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBzdGFydHMgPSBBcnJheS5mcm9tKGlucHV0c1sxXS5pbnRlZ2VyRGF0YSk7XG4gICAgICBjb25zdCBlbmRzID0gQXJyYXkuZnJvbShpbnB1dHNbMl0uaW50ZWdlckRhdGEpO1xuICAgICAgY29uc3QgYXhlcyA9IGlucHV0cy5sZW5ndGggPj0gNCA/IEFycmF5LmZyb20oaW5wdXRzWzNdLmludGVnZXJEYXRhKSA6IFtdO1xuICAgICAgY29uc3QgY2FjaGVLZXkgPSBgJHtheGVzfTske3N0YXJ0c307JHtlbmRzfWA7XG4gICAgICByZXR1cm4ge3N0YXJ0cywgZW5kcywgYXhlcywgY2FjaGVLZXl9O1xuICAgIH07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzVjEwID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCA8IDMgfHwgaW5wdXRzLmxlbmd0aCA+IDUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgbnVtYmVyLicpO1xuICB9XG4gIGlmIChpbnB1dHNbMV0udHlwZSAhPT0gJ2ludDMyJyB8fCBpbnB1dHNbMV0uZGltcy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxuICBpZiAoaW5wdXRzWzJdLnR5cGUgIT09ICdpbnQzMicgfHwgaW5wdXRzWzJdLmRpbXMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbiAgaWYgKGlucHV0cy5sZW5ndGggPj0gNCAmJiAoaW5wdXRzWzNdLnR5cGUgIT09ICdpbnQzMicgfHwgaW5wdXRzWzNdLmRpbXMubGVuZ3RoICE9PSAxKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBpbnB1dCB0eXBlLicpO1xuICB9XG4gIGlmIChpbnB1dHMubGVuZ3RoID49IDUgJiYgKGlucHV0c1s0XS50eXBlICE9PSAnaW50MzInIHx8IGlucHV0c1s0XS5kaW1zLmxlbmd0aCAhPT0gMSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxufTtcbiIsIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge0F0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5fSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHtHcmFwaH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHtPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9ufSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHtUZW5zb3J9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQge1NoYXBlVXRpbH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQge2dldEdsc2x9IGZyb20gJy4uL2dsc2wtc291cmNlJztcbmltcG9ydCB7V2ViR0xJbmZlcmVuY2VIYW5kbGVyfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQge1Byb2dyYW1JbmZvLCBUZXh0dXJlVHlwZX0gZnJvbSAnLi4vdHlwZXMnO1xuXG5pbXBvcnQge3RyYW5zcG9zZSwgVHJhbnNwb3NlQXR0cmlidXRlc30gZnJvbSAnLi90cmFuc3Bvc2UnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFNvZnRtYXhBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgYXhpczogbnVtYmVyO1xufVxuXG5jb25zdCBzb2Z0bWF4Q29tcHV0ZU1heFByb2dyYW1NZXRhZGF0YSA9IHtcbiAgbmFtZTogJ1NvZnRtYXhDb21wdXRlTWF4JyxcbiAgaW5wdXROYW1lczogWydBJ10sXG4gIGlucHV0VHlwZXM6IFtUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG59O1xuXG5jb25zdCBzb2Z0bWF4Q29tcHV0ZVNjYWxlUHJvZ3JhbU1ldGFkYXRhID0ge1xuICBuYW1lOiAnU29mdG1heENvbXB1dGVTY2FsZScsXG4gIGlucHV0TmFtZXM6IFsnQScsICdNYXgnXSxcbiAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG59O1xuXG5jb25zdCBzb2Z0bWF4UHJvZ3JhbU1ldGFkYXRhID0ge1xuICBuYW1lOiAnU29mdE1heCcsXG4gIGlucHV0TmFtZXM6IFsnQScsICdNYXgnLCAnTm9ybSddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWQsIFRleHR1cmVUeXBlLnVucGFja2VkLCBUZXh0dXJlVHlwZS51bnBhY2tlZF0sXG59O1xuXG5leHBvcnQgY29uc3Qgc29mdG1heDogT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjxTb2Z0bWF4QXR0cmlidXRlcz4gPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IFNvZnRtYXhBdHRyaWJ1dGVzKTogVGVuc29yW10gPT4ge1xuICAgICAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcblxuICAgICAgY29uc3QgaW5wdXRTaGFwZSA9IGlucHV0c1swXS5kaW1zLnNsaWNlKCk7XG4gICAgICBjb25zdCBheGlzID0gU2hhcGVVdGlsLm5vcm1hbGl6ZUF4aXMoYXR0cmlidXRlcy5heGlzLCBpbnB1dFNoYXBlLmxlbmd0aCk7XG4gICAgICBjb25zdCBsb2dpY2FsUm93Q291bnQgPSBTaGFwZVV0aWwuc2l6ZVRvRGltZW5zaW9uKGlucHV0U2hhcGUsIGF4aXMpO1xuICAgICAgY29uc3QgZmVhdHVyZUNvdW50ID0gU2hhcGVVdGlsLnNpemVGcm9tRGltZW5zaW9uKGlucHV0U2hhcGUsIGF4aXMpO1xuXG4gICAgICBjb25zdCBvdXRwdXQgPSBjb21wdXRlU29mdG1heChpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMsIGxvZ2ljYWxSb3dDb3VudCwgZmVhdHVyZUNvdW50KTtcbiAgICAgIHJldHVybiBvdXRwdXQ7XG4gICAgfTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlU29mdG1heEF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248U29mdG1heEF0dHJpYnV0ZXM+ID1cbiAgICAobm9kZTogR3JhcGguTm9kZSk6IFNvZnRtYXhBdHRyaWJ1dGVzID0+IGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7YXhpczogbm9kZS5hdHRyaWJ1dGVzLmdldEludCgnYXhpcycsIDEpfSk7XG5cbmV4cG9ydCBjb25zdCBwYXJzZVNvZnRtYXhBdHRyaWJ1dGVzVjEzOiBPcGVyYXRvckluaXRpYWxpemF0aW9uPFNvZnRtYXhBdHRyaWJ1dGVzPiA9XG4gICAgKG5vZGU6IEdyYXBoLk5vZGUpOiBTb2Z0bWF4QXR0cmlidXRlcyA9PiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoe2F4aXM6IG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ2F4aXMnLCAtMSl9KTtcblxuLy8gVGhlIFwic2VtYW50aWNcIiBtZWFuaW5nIG9mIGF4aXMgaGFzIGNoYW5nZWQgaW4gb3BzZXQtMTMuXG4vLyBQbGVhc2UgY29tcGFyZTogaHR0cHM6Ly9naXRodWIuY29tL29ubngvb25ueC9ibG9iL21haW4vZG9jcy9PcGVyYXRvcnMubWQjU29mdG1heFxuLy8gd2l0aCBodHRwczovL2dpdGh1Yi5jb20vb25ueC9vbm54L2Jsb2IvbWFpbi9kb2NzL0NoYW5nZWxvZy5tZCNTb2Z0bWF4LTExIGZvciBkZXRhaWxlZCBleHBsYW5hdGlvbnNcbi8vIFRvIGFjY291bnQgZm9yIHRoZSBvcHNldC0xMyBiZWhhdmlvciwgb3VyIHBsYW4gd2lsbCBiZSB0byB0cmFuc3Bvc2UgdGhlIFwiYXhpc1wiIGRpbSB0byB0aGUgaW5uZXJtb3N0IGRpbVxuLy8gYW5kIHBlcmZvcm0gc29mdG1heCBhbmQgdGhlbiByZXZlcnNlIHRoZSB0cmFuc3Bvc2UuIFdlIGNhbiBza2lwIHRoZSB0cmFuc3Bvc2luZyBhc3BlY3QgaWYgdGhlIGF4aXMgaXMgYWxyZWFkeVxuLy8gdGhlIGlubmVybW9zdCBkaW1cbmV4cG9ydCBjb25zdCBzb2Z0bWF4VjEzOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPFNvZnRtYXhBdHRyaWJ1dGVzPiA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogU29mdG1heEF0dHJpYnV0ZXMpOiBUZW5zb3JbXSA9PiB7XG4gICAgICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuXG4gICAgICBjb25zdCBpbnB1dFNoYXBlID0gaW5wdXRzWzBdLmRpbXMuc2xpY2UoKTtcbiAgICAgIGNvbnN0IGF4aXMgPSBTaGFwZVV0aWwubm9ybWFsaXplQXhpcyhhdHRyaWJ1dGVzLmF4aXMsIGlucHV0U2hhcGUubGVuZ3RoKTtcbiAgICAgIGNvbnN0IHJhbmsgPSBpbnB1dFNoYXBlLmxlbmd0aDtcblxuICAgICAgY29uc3QgaXNUcmFuc3Bvc2VSZXF1aXJlZCA9IChheGlzICE9PSByYW5rIC0gMSkgPyB0cnVlIDogZmFsc2U7XG4gICAgICBjb25zdCB0cmFuc3Bvc2VkSW5wdXRTaGFwZTogbnVtYmVyW10gPSBbXTtcbiAgICAgIGxldCBwZXJtOiBudW1iZXJbXSA9IFtdO1xuICAgICAgbGV0IHRyYW5zcG9zZWRJbnB1dHM6IFRlbnNvcltdID0gW107XG4gICAgICBsZXQgdHJhbnNwb3NlQXR0cmlidXRlOiBUcmFuc3Bvc2VBdHRyaWJ1dGVzO1xuXG4gICAgICBpZiAoaXNUcmFuc3Bvc2VSZXF1aXJlZCkge1xuICAgICAgICBwZXJtID0gQXJyYXkuZnJvbSh7bGVuZ3RoOiByYW5rfSkubWFwKChfLCBpKSA9PiBpKTtcblxuICAgICAgICAvLyBzd2FwIHRoZSBpbm5lcm1vc3QgZGltIHdpdGggdGhlIGRpbSBjb3JyZXNwb25kaW5nIHRvIGF4aXNcbiAgICAgICAgcGVybVtheGlzXSA9IHJhbmsgLSAxO1xuICAgICAgICBwZXJtW3JhbmsgLSAxXSA9IGF4aXM7XG5cbiAgICAgICAgcGVybS5tYXAocCA9PiB0cmFuc3Bvc2VkSW5wdXRTaGFwZS5wdXNoKGlucHV0U2hhcGVbcF0pKTtcblxuICAgICAgICB0cmFuc3Bvc2VBdHRyaWJ1dGUgPSBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoe3Blcm19KTtcbiAgICAgICAgdHJhbnNwb3NlZElucHV0cyA9IHRyYW5zcG9zZShpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIHRyYW5zcG9zZUF0dHJpYnV0ZSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGxvZ2ljYWxSb3dDb3VudCA9IGlzVHJhbnNwb3NlUmVxdWlyZWQgPyBTaGFwZVV0aWwuc2l6ZVRvRGltZW5zaW9uKHRyYW5zcG9zZWRJbnB1dFNoYXBlLCByYW5rIC0gMSkgOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNoYXBlVXRpbC5zaXplVG9EaW1lbnNpb24oaW5wdXRTaGFwZSwgcmFuayAtIDEpO1xuICAgICAgY29uc3QgZmVhdHVyZUNvdW50ID0gaXNUcmFuc3Bvc2VSZXF1aXJlZCA/IFNoYXBlVXRpbC5zaXplRnJvbURpbWVuc2lvbih0cmFuc3Bvc2VkSW5wdXRTaGFwZSwgcmFuayAtIDEpIDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTaGFwZVV0aWwuc2l6ZUZyb21EaW1lbnNpb24oaW5wdXRTaGFwZSwgcmFuayAtIDEpO1xuXG4gICAgICBjb25zdCBvdXRwdXQgPSBjb21wdXRlU29mdG1heChcbiAgICAgICAgICBpbmZlcmVuY2VIYW5kbGVyLCBpc1RyYW5zcG9zZVJlcXVpcmVkID8gdHJhbnNwb3NlZElucHV0cyA6IGlucHV0cywgYXR0cmlidXRlcywgbG9naWNhbFJvd0NvdW50LCBmZWF0dXJlQ291bnQpO1xuXG4gICAgICBpZiAoaXNUcmFuc3Bvc2VSZXF1aXJlZCkge1xuICAgICAgICBjb25zdCByZXZlcnNlZE91dHB1dCA9IHRyYW5zcG9zZShpbmZlcmVuY2VIYW5kbGVyLCBvdXRwdXQsIHRyYW5zcG9zZUF0dHJpYnV0ZSEpO1xuICAgICAgICByZXR1cm4gcmV2ZXJzZWRPdXRwdXQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gb3V0cHV0O1xuICAgICAgfVxuICAgIH07XG5cbmNvbnN0IGNvbXB1dGVTb2Z0bWF4ID1cbiAgICAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBTb2Z0bWF4QXR0cmlidXRlcywgbG9naWNhbFJvd0NvdW50OiBudW1iZXIsXG4gICAgIGZlYXR1cmVDb3VudDogbnVtYmVyKTogVGVuc29yW10gPT4ge1xuICAgICAgY29uc3QgY29tcHV0ZU1heFByb2dyYW1JbmZvID1cbiAgICAgICAgICBjcmVhdGVDb21wdXRlTWF4UHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzWzBdLCBsb2dpY2FsUm93Q291bnQsIGZlYXR1cmVDb3VudCwgW2xvZ2ljYWxSb3dDb3VudF0pO1xuICAgICAgY29uc3QgbWF4ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgICAgICAgey4uLnNvZnRtYXhDb21wdXRlTWF4UHJvZ3JhbU1ldGFkYXRhLCBjYWNoZUhpbnQ6IGF0dHJpYnV0ZXMuY2FjaGVLZXksIGdldDogKCkgPT4gY29tcHV0ZU1heFByb2dyYW1JbmZvfSxcbiAgICAgICAgICBpbnB1dHMpO1xuXG4gICAgICBjb25zdCBjb21wdXRlU2NhbGVQcm9ncmFtSW5mbyA9IGNyZWF0ZUNvbXB1dFNjYWxlUHJvZ3JhbUluZm8oXG4gICAgICAgICAgaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzWzBdLCBsb2dpY2FsUm93Q291bnQsIGZlYXR1cmVDb3VudCwgY29tcHV0ZU1heFByb2dyYW1JbmZvLm91dHB1dC5kaW1zLFxuICAgICAgICAgIFtsb2dpY2FsUm93Q291bnRdKTtcbiAgICAgIGNvbnN0IHNjYWxlID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgICAgICAgey4uLnNvZnRtYXhDb21wdXRlU2NhbGVQcm9ncmFtTWV0YWRhdGEsIGNhY2hlSGludDogYXR0cmlidXRlcy5jYWNoZUtleSwgZ2V0OiAoKSA9PiBjb21wdXRlU2NhbGVQcm9ncmFtSW5mb30sXG4gICAgICAgICAgW2lucHV0c1swXSwgbWF4XSk7XG5cbiAgICAgIGNvbnN0IHNvZnRNYXhQcm9ncmFtSW5mbyA9IGNyZWF0ZVNvZnRNYXhQcm9ncmFtSW5mbyhcbiAgICAgICAgICBpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHNbMF0sIGxvZ2ljYWxSb3dDb3VudCwgZmVhdHVyZUNvdW50LCBjb21wdXRlTWF4UHJvZ3JhbUluZm8ub3V0cHV0LmRpbXMsXG4gICAgICAgICAgY29tcHV0ZVNjYWxlUHJvZ3JhbUluZm8ub3V0cHV0LmRpbXMpO1xuICAgICAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgICAgICAgey4uLnNvZnRtYXhQcm9ncmFtTWV0YWRhdGEsIGNhY2hlSGludDogYXR0cmlidXRlcy5jYWNoZUtleSwgZ2V0OiAoKSA9PiBzb2Z0TWF4UHJvZ3JhbUluZm99LFxuICAgICAgICAgIFtpbnB1dHNbMF0sIG1heCwgc2NhbGVdKTtcbiAgICAgIHJldHVybiBbb3V0cHV0XTtcbiAgICB9O1xuXG4vKipcbiAqIENyZWF0ZSBhIHRleHR1cmUgdGhhdCBjb250YWlucyB0aGUgbWF4aW11bSB2YWx1ZSBvZiBlYWNoIG9mIHRoZSAnTicgcm93c1xuICovXG5jb25zdCBjcmVhdGVDb21wdXRlTWF4UHJvZ3JhbUluZm8gPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0OiBUZW5zb3IsIGxvZ2ljYWxSb3dDb3VudDogbnVtYmVyLCBmZWF0dXJlQ291bnQ6IG51bWJlcixcbiAgICAgb3V0cHV0U2hhcGU6IG51bWJlcltdKTogUHJvZ3JhbUluZm8gPT4ge1xuICAgICAgY29uc3QgW3RleHR1cmVXaWR0aCwgdGV4dHVyZUhlaWdodF0gPVxuICAgICAgICAgIGluZmVyZW5jZUhhbmRsZXIuY2FsY3VsYXRlVGV4dHVyZVdpZHRoQW5kSGVpZ2h0KGlucHV0LmRpbXMsIFRleHR1cmVUeXBlLnVucGFja2VkKTtcbiAgICAgIGNvbnN0IHJhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG5cbiAgICAgIGlmIChsb2dpY2FsUm93Q291bnQgPCAxIHx8IGZlYXR1cmVDb3VudCA8IDEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdMb2dpY2FsIHJvdyBjb3VudCBOIGFuZCBmZWF0dXJlIGNvdW50IEQgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gMScpO1xuICAgICAgfVxuXG4gICAgICBpZiAob3V0cHV0U2hhcGUubGVuZ3RoICE9PSAxKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignRGltZW5zaW9uYWxpdHkgb2YgdGhlIG91dHB1dCBzaG91bGQgYmUgMScpO1xuICAgICAgfVxuXG4gICAgICBpZiAob3V0cHV0U2hhcGVbMF0gIT09IGxvZ2ljYWxSb3dDb3VudCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NoYXBlIG9mIHRoZSBvdXRwdXQgc2hvdWxkIGJlIGVxdWFsIHRvIGxvZ2ljYWwgcm93IGNvdW50Jyk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgICAgIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgIGZsb2F0IHByb2Nlc3MoaW50WyR7cmFua31dIGluZGljZXMpIHtcbiAgICAgICAgaW50IGxvZ2ljYWxfcm93X3N0YXJ0X29mZnNldCA9IGluZGljZXNbMF0gKiAke2ZlYXR1cmVDb3VudH07XG5cbiAgICAgICAgZmxvYXQgbWF4ID0gZ2V0Q29sb3JBc0Zsb2F0KCR7Z2xzbC50ZXh0dXJlMkR9KEEsIG9mZnNldFRvQ29vcmRzKGxvZ2ljYWxfcm93X3N0YXJ0X29mZnNldCwgJHt0ZXh0dXJlV2lkdGh9LFxuICAgICAgICAke3RleHR1cmVIZWlnaHR9ICkpKTtcbiAgICAgICAgZm9yKGludCBpPTE7IGk8JHtmZWF0dXJlQ291bnR9OyArK2kpXG4gICAgICAgIHtcbiAgICAgICAgICBmbG9hdCBjdXJyZW50ID0gZ2V0Q29sb3JBc0Zsb2F0KCR7Z2xzbC50ZXh0dXJlMkR9KEEsIG9mZnNldFRvQ29vcmRzKGxvZ2ljYWxfcm93X3N0YXJ0X29mZnNldCArIGksXG4gICAgICAgICAgICAke3RleHR1cmVXaWR0aH0sICR7dGV4dHVyZUhlaWdodH0pKSk7XG4gICAgICAgICAgaWYoY3VycmVudCA+IG1heClcbiAgICAgICAgICBtYXggPSBjdXJyZW50O1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG1heDtcbiAgICAgIH1gO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4uc29mdG1heENvbXB1dGVNYXhQcm9ncmFtTWV0YWRhdGEsXG4gICAgICAgIG91dHB1dDoge2RpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dC50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWR9LFxuICAgICAgICBzaGFkZXJTb3VyY2VcbiAgICAgIH07XG4gICAgfTtcblxuLyoqXG4gKiBDcmVhdGUgYSB0ZXh0dXJlIHRoYXQgY29udGFpbnMgdGhlIG5vcm1hbGl6YXRpb24gZmFjdG9yIGZvciBlYWNoIG9mIHRoZSAnTicgcm93c1xuICovXG5jb25zdCBjcmVhdGVDb21wdXRTY2FsZVByb2dyYW1JbmZvID1cbiAgICAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dDogVGVuc29yLCBsb2dpY2FsUm93Q291bnQ6IG51bWJlciwgZmVhdHVyZUNvdW50OiBudW1iZXIsXG4gICAgIG1heEVsZW1lbnRQZXJMb2dpY2FsUm93OiByZWFkb25seSBudW1iZXJbXSwgb3V0cHV0U2hhcGU6IG51bWJlcltdKTogUHJvZ3JhbUluZm8gPT4ge1xuICAgICAgY29uc3QgW3RleHR1cmVXaWR0aCwgdGV4dHVyZUhlaWdodF0gPVxuICAgICAgICAgIGluZmVyZW5jZUhhbmRsZXIuY2FsY3VsYXRlVGV4dHVyZVdpZHRoQW5kSGVpZ2h0KGlucHV0LmRpbXMsIFRleHR1cmVUeXBlLnVucGFja2VkKTtcbiAgICAgIGNvbnN0IHJhbmsgPSBvdXRwdXRTaGFwZS5sZW5ndGg7XG5cbiAgICAgIGlmIChsb2dpY2FsUm93Q291bnQgPCAxIHx8IGZlYXR1cmVDb3VudCA8IDEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdMb2dpY2FsIHJvdyBjb3VudCBOIGFuZCBmZWF0dXJlIGNvdW50IEQgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gMScpO1xuICAgICAgfVxuXG4gICAgICBpZiAob3V0cHV0U2hhcGUubGVuZ3RoICE9PSAxKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignRGltZW5zaW9uYWxpdHkgb2YgdGhlIG91dHB1dCBzaG91bGQgYmUgMScpO1xuICAgICAgfVxuXG4gICAgICBpZiAob3V0cHV0U2hhcGVbMF0gIT09IGxvZ2ljYWxSb3dDb3VudCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NoYXBlIG9mIHRoZSBvdXRwdXQgc2hvdWxkIGJlIGVxdWFsIHRvIGxvZ2ljYWwgcm93IGNvdW50Jyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChtYXhFbGVtZW50UGVyTG9naWNhbFJvdy5sZW5ndGggIT09IDEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdEaW1lbnNpb25hbGl0eSBvZiB0aGUgaW50ZXJtZWRpYXRlIHJlc3VsdHMgc2hvdWxkIGJlIDEnKTtcbiAgICAgIH1cblxuICAgICAgaWYgKG1heEVsZW1lbnRQZXJMb2dpY2FsUm93WzBdICE9PSBsb2dpY2FsUm93Q291bnQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdTaGFwZSBvZiB0aGUgaW50ZXJtZWRpYXRlIHJlc3VsdHMgc2hvdWxkIGJlIGVxdWFsIHRvIGxvZ2ljYWwgcm93IGNvdW50Jyk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgICAgIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgIGZsb2F0IHByb2Nlc3MoaW50WyR7cmFua31dIGluZGljZXMpIHtcbiAgICAgICAgaW50IGxvZ2ljYWxfcm93X3N0YXJ0X29mZnNldCA9IGluZGljZXNbMF0gKiAke2ZlYXR1cmVDb3VudH07XG5cbiAgICAgICAgZmxvYXQgbm9ybV9mYWN0b3IgPSAwLjA7XG4gICAgICAgIGZsb2F0IG1heCA9IF9NYXgoaW5kaWNlcyk7XG4gICAgICAgIGZvcihpbnQgaT0wOyBpPCR7ZmVhdHVyZUNvdW50fTsgKytpKVxuICAgICAgICB7XG4gICAgICAgICAgbm9ybV9mYWN0b3IgKz0gZXhwKGdldENvbG9yQXNGbG9hdCgke2dsc2wudGV4dHVyZTJEfShBLCBvZmZzZXRUb0Nvb3Jkcyhsb2dpY2FsX3Jvd19zdGFydF9vZmZzZXQgKyBpLFxuICAgICAgICAgICAgJHt0ZXh0dXJlV2lkdGh9LCAke3RleHR1cmVIZWlnaHR9KSkpIC0gbWF4KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBub3JtX2ZhY3RvcjtcbiAgICAgIH1gO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4uc29mdG1heENvbXB1dGVTY2FsZVByb2dyYW1NZXRhZGF0YSxcbiAgICAgICAgb3V0cHV0OiB7ZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0LnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZH0sXG4gICAgICAgIHNoYWRlclNvdXJjZVxuICAgICAgfTtcbiAgICB9O1xuXG5jb25zdCBjcmVhdGVTb2Z0TWF4UHJvZ3JhbUluZm8gPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0OiBUZW5zb3IsIGxvZ2ljYWxSb3dDb3VudDogbnVtYmVyLCBmZWF0dXJlQ291bnQ6IG51bWJlcixcbiAgICAgbWF4RWxlbWVudFBlckxvZ2ljYWxSb3c6IHJlYWRvbmx5IG51bWJlcltdLCBub3JtYWxpemF0aW9uUGVyTG9naWNhbFJvdzogcmVhZG9ubHkgbnVtYmVyW10pOiBQcm9ncmFtSW5mbyA9PiB7XG4gICAgICBjb25zdCBbdGV4dHVyZVdpZHRoLCB0ZXh0dXJlSGVpZ2h0XSA9XG4gICAgICAgICAgaW5mZXJlbmNlSGFuZGxlci5jYWxjdWxhdGVUZXh0dXJlV2lkdGhBbmRIZWlnaHQoaW5wdXQuZGltcywgVGV4dHVyZVR5cGUudW5wYWNrZWQpO1xuICAgICAgY29uc3QgcmFuayA9IGlucHV0LmRpbXMubGVuZ3RoO1xuXG4gICAgICBpZiAobG9naWNhbFJvd0NvdW50IDwgMSB8fCBmZWF0dXJlQ291bnQgPCAxKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTG9naWNhbCByb3cgY291bnQgTiBhbmQgZmVhdHVyZSBjb3VudCBEIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDEnKTtcbiAgICAgIH1cblxuICAgICAgaWYgKG1heEVsZW1lbnRQZXJMb2dpY2FsUm93Lmxlbmd0aCAhPT0gMSB8fCBub3JtYWxpemF0aW9uUGVyTG9naWNhbFJvdy5sZW5ndGggIT09IDEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdEaW1lbnNpb25hbGl0eSBvZiB0aGUgaW50ZXJtZWRpYXRlIHJlc3VsdHMgc2hvdWxkIGJlIDEnKTtcbiAgICAgIH1cblxuICAgICAgaWYgKG1heEVsZW1lbnRQZXJMb2dpY2FsUm93WzBdICE9PSBsb2dpY2FsUm93Q291bnQgfHwgbm9ybWFsaXphdGlvblBlckxvZ2ljYWxSb3dbMF0gIT09IGxvZ2ljYWxSb3dDb3VudCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NoYXBlIG9mIHRoZSBpbnRlcm1lZGlhdGUgcmVzdWx0cyBzaG91bGQgYmUgZXF1YWwgdG8gbG9naWNhbCByb3cgY291bnQnKTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgZmxvYXQgcHJvY2VzcyhpbnRbJHtyYW5rfV0gaW5kaWNlcykge1xuXG4gICAgICAvLyBnZXQgb2Zmc2V0IG9mIGN1cnJlbnQgbG9naWNhbCB0ZW5zb3IgaW5kZXggZnJvbSB0aGUgMi1EIHRleHR1cmUgY29vcmRpbmF0ZXMgKFRleENvb3JkcylcbiAgICAgIGludCBvZmZzZXQgPSBjb29yZHNUb09mZnNldChUZXhDb29yZHMsICR7dGV4dHVyZVdpZHRofSwgJHt0ZXh0dXJlSGVpZ2h0fSk7XG5cbiAgICAgIC8vZGV0ZXJtaW5lIHRoZSBsb2dpY2FsIHJvdyBmb3IgdGhpcyBpbmRleFxuICAgICAgaW50IGxvZ2ljYWxfcm93X2luZGV4WzFdO1xuICAgICAgbG9naWNhbF9yb3dfaW5kZXhbMF0gPSBvZmZzZXQgLyAke2ZlYXR1cmVDb3VudH07XG5cbiAgICAgIGZsb2F0IG5vcm1fZmFjdG9yID0gX05vcm0obG9naWNhbF9yb3dfaW5kZXgpO1xuXG4gICAgICAvLyBhdm9pZCBwb3NzaWJsZSBkaXZpc2lvbiBieSAwXG4gICAgICAvLyBpZiBub3JtX2ZhY29yIGlzIDAsIGFsbCBlbGVtZW50cyBhcmUgemVyb1xuICAgICAgLy8gaWYgc28sIHJldHVybiAwXG4gICAgICBpZihub3JtX2ZhY3RvciA9PSAwLjApXG4gICAgICAgIHJldHVybiAwLjA7XG5cbiAgICAgIHJldHVybiBleHAoX0EoaW5kaWNlcykgLSBfTWF4KGxvZ2ljYWxfcm93X2luZGV4KSkgLyBub3JtX2ZhY3RvcjtcbiAgICB9YDtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLnNvZnRtYXhQcm9ncmFtTWV0YWRhdGEsXG4gICAgICAgIG91dHB1dDoge2RpbXM6IGlucHV0LmRpbXMsIHR5cGU6IGlucHV0LnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS51bnBhY2tlZH0sXG4gICAgICAgIHNoYWRlclNvdXJjZVxuICAgICAgfTtcbiAgICB9O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1NvZnRtYXggcmVxdWlyZXMgMSBpbnB1dC4nKTtcbiAgfVxuXG4gIGlmIChpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0MzInICYmIGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQ2NCcpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZScpO1xuICB9XG59O1xuIiwiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7QXR0cmlidXRlV2l0aENhY2hlS2V5LCBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXl9IGZyb20gJy4uLy4uLy4uL2F0dHJpYnV0ZS13aXRoLWNhY2hlLWtleSc7XG5pbXBvcnQge0dyYXBofSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQge09wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb259IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7U2hhcGVVdGlsLCBTcGxpdFV0aWx9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHtXZWJHTEluZmVyZW5jZUhhbmRsZXJ9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7UHJvZ3JhbUluZm8sIFRleHR1cmVUeXBlfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3BsaXRBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgYXhpczogbnVtYmVyO1xuICByZWFkb25seSBzcGxpdDogbnVtYmVyW107XG4gIHJlYWRvbmx5IG51bU91dHB1dHM6IG51bWJlcjtcbn1cblxuY29uc3Qgc3BsaXRQcm9ncmFtTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdTcGxpdCcsXG4gIGlucHV0TmFtZXM6IFsnQSddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxufTtcblxuZXhwb3J0IGNvbnN0IHNwbGl0OiBPcGVyYXRvckltcGxlbWVudGF0aW9uPFNwbGl0QXR0cmlidXRlcz4gPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IFNwbGl0QXR0cmlidXRlcyk6IFRlbnNvcltdID0+IHtcbiAgICAgIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG5cbiAgICAgIGNvbnN0IGF4aXMgPSBTaGFwZVV0aWwubm9ybWFsaXplQXhpcyhhdHRyaWJ1dGVzLmF4aXMsIGlucHV0c1swXS5kaW1zLmxlbmd0aCk7XG4gICAgICBjb25zdCBjb3VudCA9IGdldFByb2dyYW1Db3VudChpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF4aXMsIGF0dHJpYnV0ZXMpO1xuICAgICAgY29uc3Qgb3V0cHV0OiBUZW5zb3JbXSA9IFtdO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb3VudDsgKytpKSB7XG4gICAgICAgIG91dHB1dC5wdXNoKGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAuLi5zcGxpdFByb2dyYW1NZXRhZGF0YSxcbiAgICAgICAgICAgICAgY2FjaGVIaW50OiBgJHthdHRyaWJ1dGVzLmNhY2hlS2V5fTske2l9YCxcbiAgICAgICAgICAgICAgZ2V0OiAoKSA9PiBjcmVhdGVTcGxpdFByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0c1swXSwgYXR0cmlidXRlcywgYXhpcywgaSlcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBpbnB1dHMpKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG91dHB1dDtcbiAgICB9O1xuXG5leHBvcnQgY29uc3QgcGFyc2VTcGxpdEF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248U3BsaXRBdHRyaWJ1dGVzPiA9IChub2RlOiBHcmFwaC5Ob2RlKTogU3BsaXRBdHRyaWJ1dGVzID0+IHtcbiAgY29uc3QgYXhpcyA9IG5vZGUuYXR0cmlidXRlcy5nZXRJbnQoJ2F4aXMnLCAwKTtcbiAgY29uc3Qgc3BsaXQgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0SW50cygnc3BsaXQnLCBbXSk7XG4gIGNvbnN0IG51bU91dHB1dHMgPSBub2RlLm91dHB1dHMubGVuZ3RoO1xuICByZXR1cm4gY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5KHtheGlzLCBzcGxpdCwgbnVtT3V0cHV0c30pO1xufTtcblxuY29uc3QgZ2V0UHJvZ3JhbUNvdW50ID1cbiAgICAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdLCBheGlzOiBudW1iZXIsIGF0dHJpYnV0ZXM6IFNwbGl0QXR0cmlidXRlcyk6IG51bWJlciA9PiB7XG4gICAgICBjb25zdCBbLCBvZmZzZXRzXSA9IFNwbGl0VXRpbC5zcGxpdFNoYXBlKGlucHV0c1swXS5kaW1zLCBheGlzLCBhdHRyaWJ1dGVzLnNwbGl0LCBhdHRyaWJ1dGVzLm51bU91dHB1dHMpO1xuICAgICAgcmV0dXJuIG9mZnNldHMubGVuZ3RoO1xuICAgIH07XG5cbmNvbnN0IGNyZWF0ZVNwbGl0UHJvZ3JhbUluZm8gPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0OiBUZW5zb3IsIGF0dHJpYnV0ZXM6IFNwbGl0QXR0cmlidXRlcywgYXhpczogbnVtYmVyLCBpbmRleDogbnVtYmVyKTpcbiAgICAgICAgUHJvZ3JhbUluZm8gPT4ge1xuICAgICAgICAgIGNvbnN0IFtzaGFwZXMsIG9mZnNldHNdID0gU3BsaXRVdGlsLnNwbGl0U2hhcGUoaW5wdXQuZGltcywgYXhpcywgYXR0cmlidXRlcy5zcGxpdCwgYXR0cmlidXRlcy5udW1PdXRwdXRzKTtcbiAgICAgICAgICBjb25zdCBvZmZzZXQgPSBvZmZzZXRzW2luZGV4XTtcbiAgICAgICAgICBjb25zdCBvdXRwdXRTaGFwZSA9IHNoYXBlc1tpbmRleF07XG4gICAgICAgICAgY29uc3QgcmFuayA9IG91dHB1dFNoYXBlLmxlbmd0aDtcbiAgICAgICAgICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICBmbG9hdCBwcm9jZXNzKGludCBpbmRpY2VzWyR7cmFua31dKSB7XG4gICAgICAgIGluZGljZXNbJHtheGlzfV0gKz0gJHtvZmZzZXR9O1xuICAgICAgICByZXR1cm4gX0EoaW5kaWNlcyk7XG4gICAgICB9XG4gICAgYDtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgLi4uc3BsaXRQcm9ncmFtTWV0YWRhdGEsXG4gICAgICAgICAgICBjYWNoZUhpbnQ6IGAke2F0dHJpYnV0ZXMuY2FjaGVLZXl9OiR7aW5kZXh9YCxcbiAgICAgICAgICAgIG91dHB1dDoge2RpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dC50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWR9LFxuICAgICAgICAgICAgc2hhZGVyU291cmNlXG4gICAgICAgICAgfTtcbiAgICAgICAgfTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTcGxpdCByZXF1aXJlcyBvbmUgaW5wdXQuJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzWzBdLnR5cGUgIT09ICdpbnQ4JyAmJiBpbnB1dHNbMF0udHlwZSAhPT0gJ3VpbnQ4JyAmJiBpbnB1dHNbMF0udHlwZSAhPT0gJ2ludDE2JyAmJlxuICAgICAgaW5wdXRzWzBdLnR5cGUgIT09ICd1aW50MTYnICYmIGlucHV0c1swXS50eXBlICE9PSAnaW50MzInICYmIGlucHV0c1swXS50eXBlICE9PSAndWludDMyJyAmJlxuICAgICAgaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDMyJyAmJiBpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0NjQnICYmIGlucHV0c1swXS50eXBlICE9PSAnYm9vbCcpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxufTtcbiIsIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge0dyYXBofSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQge09wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb259IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7U2hhcGVVdGlsfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7V2ViR0xJbmZlcmVuY2VIYW5kbGVyfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5cbmV4cG9ydCBjb25zdCBzcXVlZXplOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPG51bWJlcltdPiA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgYXhlczogbnVtYmVyW10pOiBUZW5zb3JbXSA9PiB7XG4gICAgICB2YWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuICAgICAgY29uc3Qgb3V0cHV0U2hhcGUgPSBTaGFwZVV0aWwuc3F1ZWV6ZVNoYXBlKGlucHV0c1swXS5kaW1zLCBheGVzKTtcbiAgICAgIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucmVzaGFwZVVucGFja2VkKGlucHV0c1swXSwgb3V0cHV0U2hhcGUpO1xuICAgICAgcmV0dXJuIFtvdXRwdXRdO1xuICAgIH07XG5cbmV4cG9ydCBjb25zdCBzcXVlZXplVjEzID0gKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHNWMTMoaW5wdXRzKTtcbiAgcmV0dXJuIHNxdWVlemUoaW5mZXJlbmNlSGFuZGxlciwgW2lucHV0c1swXV0sIEFycmF5LmZyb20oaW5wdXRzWzFdLmludGVnZXJEYXRhKSk7XG59O1xuXG5leHBvcnQgY29uc3QgcGFyc2VTcXVlZXplQXR0cmlidXRlczogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxudW1iZXJbXT4gPSAobm9kZTogR3JhcGguTm9kZSk6IG51bWJlcltdID0+XG4gICAgbm9kZS5hdHRyaWJ1dGVzLmdldEludHMoJ2F4ZXMnKTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTcXVlZXplIHJlcXVpcmVzIDEgaW5wdXQuJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzWzBdLnR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGlucHV0IHRlbnNvciB0eXBlcy4nKTtcbiAgfVxufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHNWMTMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTcXVlZXplIHJlcXVpcmVzIDIgaW5wdXRzLicpO1xuICB9XG5cbiAgaWYgKGlucHV0c1sxXS50eXBlICE9PSAnaW50MzInKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbn07IiwiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7VGVuc29yfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHtnZXRHbHNsfSBmcm9tICcuLi9nbHNsLXNvdXJjZSc7XG5pbXBvcnQge1dlYkdMSW5mZXJlbmNlSGFuZGxlcn0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHtQcm9ncmFtSW5mbywgUHJvZ3JhbU1ldGFkYXRhLCBUZXh0dXJlVHlwZX0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgY29uc3Qgc3VtID0gKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcblxuICBjb25zdCBzdW1Qcm9ncmFtTWV0YWRhdGEgPSB7XG4gICAgbmFtZTogJ1N1bScsXG4gICAgaW5wdXROYW1lczogaW5wdXRzLm1hcCgodiwgaSkgPT4gYFgke2l9YCksXG4gICAgaW5wdXRUeXBlczogbmV3IEFycmF5KGlucHV0cy5sZW5ndGgpLmZpbGwoVGV4dHVyZVR5cGUudW5wYWNrZWQpXG4gIH07XG5cbiAgY29uc3Qgb3V0cHV0ID0gaW5mZXJlbmNlSGFuZGxlci5ydW4oXG4gICAgICB7Li4uc3VtUHJvZ3JhbU1ldGFkYXRhLCBnZXQ6ICgpID0+IGNyZWF0ZVN1bVByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgc3VtUHJvZ3JhbU1ldGFkYXRhKX0sIGlucHV0cyk7XG4gIHJldHVybiBbb3V0cHV0XTtcbn07XG5cbmNvbnN0IGNyZWF0ZVN1bVByb2dyYW1JbmZvID1cbiAgICAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdLCBzdW1Qcm9ncmFtTWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSk6IFByb2dyYW1JbmZvID0+IHtcbiAgICAgIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGluZmVyZW5jZUhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgICAgIGNvbnN0IG91dHB1dFNoYXBlID0gaW5wdXRzWzBdLmRpbXMuc2xpY2UoKTtcbiAgICAgIGNvbnN0IHN1bUxpbmUgPSBpbnB1dHMubWFwKCh2LCBpKSA9PiBgJHtnbHNsLnRleHR1cmUyRH0oWCR7aX0sVGV4Q29vcmRzKWApLmpvaW4oJyArICcpO1xuICAgICAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICAgdm9pZCBtYWluKCkge1xuICAgICAgICB2ZWM0IHJlc3VsdCA9ICR7c3VtTGluZX07XG4gICAgICAgICR7Z2xzbC5vdXRwdXR9ID0gcmVzdWx0O1xuICAgICAgfVxuICAgIGA7XG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5zdW1Qcm9ncmFtTWV0YWRhdGEsXG4gICAgICAgIG91dHB1dDoge2RpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkfSxcbiAgICAgICAgaGFzTWFpbjogdHJ1ZSxcbiAgICAgICAgc2hhZGVyU291cmNlXG4gICAgICB9O1xuICAgIH07XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCA9PT0gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcignU3VtIHJlcXVpcmVzIGlucHV0cy4nKTtcbiAgfVxuXG4gIGNvbnN0IGxlbmd0aCA9IGlucHV0c1swXS5kaW1zLmxlbmd0aDtcbiAgZm9yIChsZXQgaSA9IDE7IGkgPCBpbnB1dHMubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAobGVuZ3RoICE9PSBpbnB1dHNbaV0uZGltcy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgc2hhcGVzIGFyZSBtaXNtYXRjaGVkLicpO1xuICAgIH1cblxuICAgIGZvciAobGV0IGogPSAwOyBqIDwgbGVuZ3RoOyBqKyspIHtcbiAgICAgIGlmIChpbnB1dHNbMF0uZGltc1tqXSAhPT0gaW5wdXRzW2ldLmRpbXNbal0pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBzaGFwZXMgYXJlIG5vdCBtYXRjaGVkLicpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlmIChpbnB1dHNbMF0udHlwZSAhPT0gJ2Zsb2F0MzInICYmIGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQ2NCcpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxuICBmb3IgKGxldCBpID0gMTsgaSA8IGlucHV0cy5sZW5ndGg7IGkrKykge1xuICAgIGlmIChpbnB1dHNbMF0udHlwZSAhPT0gaW5wdXRzW2ldLnR5cGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW5wdXQgdHlwZXMgYXJlIG5vdCBtYXRjaGVkLicpO1xuICAgIH1cbiAgfVxufTsiLCIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtOVU1CRVJfVFlQRVN9IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7V2ViR0xJbmZlcmVuY2VIYW5kbGVyfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQge1Byb2dyYW1JbmZvLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBjb25zdCB0aWxlID0gKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcblxuICBjb25zdCB0aWxlUHJvZ3JhbU1ldGFkYXRhID0ge1xuICAgIG5hbWU6ICdUaWxlJyxcbiAgICBpbnB1dE5hbWVzOiBbJ0EnXSxcbiAgICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxuICB9O1xuXG4gIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgICAgey4uLnRpbGVQcm9ncmFtTWV0YWRhdGEsIGdldDogKCkgPT4gY3JlYXRlVGlsZVByb2dyYW1JbmZvKGluZmVyZW5jZUhhbmRsZXIsIGlucHV0cywgdGlsZVByb2dyYW1NZXRhZGF0YSl9LFxuICAgICAgaW5wdXRzKTtcbiAgcmV0dXJuIFtvdXRwdXRdO1xufTtcblxuY29uc3QgY3JlYXRlVGlsZVByb2dyYW1JbmZvID1cbiAgICAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdLCB0aWxlUHJvZ3JhbU1ldGFkYXRhOiBQcm9ncmFtTWV0YWRhdGEpOiBQcm9ncmFtSW5mbyA9PiB7XG4gICAgICBjb25zdCBpbnB1dFNoYXBlID0gaW5wdXRzWzBdLmRpbXMuc2xpY2UoKTtcbiAgICAgIGNvbnN0IG91dHB1dFNoYXBlID0gbmV3IEFycmF5KGlucHV0U2hhcGUubGVuZ3RoKTtcblxuICAgICAgY29uc3QgdGlsZU9wczogc3RyaW5nW10gPSBbXTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5wdXRTaGFwZS5sZW5ndGg7IGkrKykge1xuICAgICAgICBvdXRwdXRTaGFwZVtpXSA9IGlucHV0U2hhcGVbaV0gKiBpbnB1dHNbMV0ubnVtYmVyRGF0YVtpXTtcbiAgICAgICAgdGlsZU9wcy5wdXNoKGBpbnB1dElkeFske2l9XSA9IGludChtb2QoZmxvYXQob3V0cHV0SWR4WyR7aX1dKSwgJHtpbnB1dFNoYXBlW2ldfS4pKTtgKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcmFuayA9IG91dHB1dFNoYXBlLmxlbmd0aDtcbiAgICAgIGNvbnN0IHNoYWRlclNvdXJjZSA9IGBcbiAgICAgIGZsb2F0IHByb2Nlc3MoaW50IG91dHB1dElkeFske3Jhbmt9XSkge1xuICAgICAgICBpbnQgaW5wdXRJZHhbJHtyYW5rfV07XG4gICAgICAgICR7dGlsZU9wcy5qb2luKCdcXG4nKX1cbiAgICAgICAgcmV0dXJuIF9BKGlucHV0SWR4KTtcbiAgICAgIH1cbiAgICBgO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4udGlsZVByb2dyYW1NZXRhZGF0YSxcbiAgICAgICAgb3V0cHV0OiB7ZGltczogb3V0cHV0U2hhcGUsIHR5cGU6IGlucHV0c1swXS50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWR9LFxuICAgICAgICBzaGFkZXJTb3VyY2VcbiAgICAgIH07XG4gICAgfTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdUaWxlIHJlcXVpcmVzIDIgaW5wdXQuJyk7XG4gIH1cbiAgaWYgKGlucHV0c1sxXS5kaW1zLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignVGhlIHNlY29uZCBpbnB1dCBzaGFwZSBtdXN0IDEgZGltZW5zaW9uLicpO1xuICB9XG4gIGlmIChpbnB1dHNbMV0uZGltc1swXSAhPT0gaW5wdXRzWzBdLmRpbXMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHNoYXBlLicpO1xuICB9XG4gIGlmIChOVU1CRVJfVFlQRVMuaW5kZXhPZihpbnB1dHNbMF0udHlwZSkgPT09IC0xKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHR5cGUuJyk7XG4gIH1cbiAgaWYgKGlucHV0c1sxXS50eXBlICE9PSAnaW50MzInICYmIGlucHV0c1sxXS50eXBlICE9PSAnaW50MTYnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHJlcGVhdCB0eXBlLicpO1xuICB9XG59OyIsIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge0F0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5fSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHtHcmFwaH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHtPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9ufSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHtUZW5zb3J9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQge1NoYXBlVXRpbH0gZnJvbSAnLi4vLi4vLi4vdXRpbCc7XG5pbXBvcnQge1dlYkdMSW5mZXJlbmNlSGFuZGxlcn0gZnJvbSAnLi4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHtQcm9ncmFtSW5mbywgVGV4dHVyZVR5cGV9IGZyb20gJy4uL3R5cGVzJztcblxuZXhwb3J0IGludGVyZmFjZSBUcmFuc3Bvc2VBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgcGVybTogbnVtYmVyW107XG59XG5cbmNvbnN0IHRyYW5zcG9zZVByb2dyYW1NZXRhZGF0YSA9IHtcbiAgbmFtZTogJ1RyYW5zcG9zZScsXG4gIGlucHV0TmFtZXM6IFsnQSddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdXG59O1xuXG5leHBvcnQgY29uc3QgdHJhbnNwb3NlOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPFRyYW5zcG9zZUF0dHJpYnV0ZXM+ID1cbiAgICAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGVzOiBUcmFuc3Bvc2VBdHRyaWJ1dGVzKTogVGVuc29yW10gPT4ge1xuICAgICAgdmFsaWRhdGVJbnB1dHMoaW5wdXRzKTtcbiAgICAgIGNvbnN0IG91dHB1dCA9IGluZmVyZW5jZUhhbmRsZXIucnVuKFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIC4uLnRyYW5zcG9zZVByb2dyYW1NZXRhZGF0YSxcbiAgICAgICAgICAgIGNhY2hlSGludDogYXR0cmlidXRlcy5jYWNoZUtleSxcbiAgICAgICAgICAgIGdldDogKCkgPT4gY3JlYXRlVHJhbnNwb3NlUHJvZ3JhbUluZm8oaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzWzBdLCBhdHRyaWJ1dGVzLnBlcm0pXG4gICAgICAgICAgfSxcbiAgICAgICAgICBpbnB1dHMpO1xuICAgICAgcmV0dXJuIFtvdXRwdXRdO1xuICAgIH07XG5cbmV4cG9ydCBjb25zdCBwYXJzZVRyYW5zcG9zZUF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248VHJhbnNwb3NlQXR0cmlidXRlcz4gPVxuICAgIChub2RlOiBHcmFwaC5Ob2RlKTogVHJhbnNwb3NlQXR0cmlidXRlcyA9PiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoe3Blcm06IG5vZGUuYXR0cmlidXRlcy5nZXRJbnRzKCdwZXJtJywgW10pfSk7XG5cbmNvbnN0IGNyZWF0ZVRyYW5zcG9zZVByb2dyYW1JbmZvID1cbiAgICAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dDogVGVuc29yLCBwZXJtOiBudW1iZXJbXSk6IFByb2dyYW1JbmZvID0+IHtcbiAgICAgIGNvbnN0IGlucHV0U2hhcGUgPSBpbnB1dC5kaW1zO1xuICAgICAgcGVybSA9IGdldEFkanVzdGVkUGVybShpbnB1dFNoYXBlLCBwZXJtKTtcbiAgICAgIGNvbnN0IHVucGFja2VkT3V0cHV0U2hhcGUgPSBnZXRPdXRwdXRTaGFwZShpbnB1dFNoYXBlLCBwZXJtKTtcbiAgICAgIGNvbnN0IHJhbmsgPSBpbnB1dFNoYXBlLmxlbmd0aDtcbiAgICAgIC8vIEEgZGltcz1bJHtpbnB1dHNbMF0uZGltcy50b1N0cmluZygpfV1cbiAgICAgIC8vIG91dCBEaW1zPVske3VucGFja2VkT3V0cHV0U2hhcGUudG9TdHJpbmcoKX1dXG4gICAgICAvLyBiYXNlZCBvbiBwZXJtPVske3Blcm0udG9TdHJpbmcoKX1dXG4gICAgICBjb25zdCBzaGFkZXJTb3VyY2UgPSBgXG4gICAgICAke2dldFBlcm1GdW5jdGlvbkJvZHkoJ3Blcm0nLCBwZXJtLCByYW5rKX1cbiAgICAgIGZsb2F0IHByb2Nlc3MoaW50IGluZGljZXNbJHtyYW5rfV0pIHtcbiAgICAgICAgaW50IGFbJHtyYW5rfV07XG4gICAgICAgIHBlcm0oYSwgaW5kaWNlcyk7XG4gICAgICAgIHJldHVybiBfQShhKTtcbiAgICAgIH1gO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4udHJhbnNwb3NlUHJvZ3JhbU1ldGFkYXRhLFxuICAgICAgICBvdXRwdXQ6IHtkaW1zOiB1bnBhY2tlZE91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dC50eXBlLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUudW5wYWNrZWR9LFxuICAgICAgICBzaGFkZXJTb3VyY2VcbiAgICAgIH07XG4gICAgfTtcblxuY29uc3QgZ2V0QWRqdXN0ZWRQZXJtID0gKGlucHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCBwZXJtOiBudW1iZXJbXSk6IG51bWJlcltdID0+IHtcbiAgaWYgKHBlcm0gJiYgcGVybS5sZW5ndGggIT09IGlucHV0U2hhcGUubGVuZ3RoKSB7XG4gICAgcGVybSA9IFsuLi4oaW5wdXRTaGFwZS5rZXlzKCkpXS5yZXZlcnNlKCk7XG4gIH1cbiAgcmV0dXJuIHBlcm07XG59O1xuXG5jb25zdCBnZXRPdXRwdXRTaGFwZSA9IChpbnB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgcGVybTogbnVtYmVyW10pOiByZWFkb25seSBudW1iZXJbXSA9PiB7XG4gIHBlcm0gPSBnZXRBZGp1c3RlZFBlcm0oaW5wdXRTaGFwZSwgcGVybSk7XG4gIHJldHVybiBTaGFwZVV0aWwuc29ydEJhc2VkT25QZXJtKGlucHV0U2hhcGUsIHBlcm0pO1xufTtcblxuY29uc3QgZ2V0UGVybUZ1bmN0aW9uQm9keSA9IChuYW1lOiBzdHJpbmcsIHBlcm06IG51bWJlcltdLCByYW5rOiBudW1iZXIpOiBzdHJpbmcgPT4ge1xuICBjb25zdCByZXZlcnNlRnVuYyA9IFtdO1xuICByZXZlcnNlRnVuYy5wdXNoKGB2b2lkICR7bmFtZX0ob3V0IGludCBhWyR7cmFua31dLCBpbnQgc3JjWyR7cmFua31dKSB7YCk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuazsgKytpKSB7XG4gICAgcmV2ZXJzZUZ1bmMucHVzaChgXFx0YVske3Blcm1baV19XT1zcmNbJHtpfV07YCk7XG4gIH1cbiAgcmV2ZXJzZUZ1bmMucHVzaCgnXFx0fScpO1xuICByZXR1cm4gcmV2ZXJzZUZ1bmMuam9pbignXFxuJyk7XG59O1xuXG5jb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdKTogdm9pZCA9PiB7XG4gIGlmICghaW5wdXRzIHx8IGlucHV0cy5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1RyYW5zcG9zZSByZXF1aXJlcyAxIGlucHV0LicpO1xuICB9XG5cbiAgaWYgKGlucHV0c1swXS50eXBlICE9PSAnZmxvYXQzMicgJiYgaW5wdXRzWzBdLnR5cGUgIT09ICdmbG9hdDY0Jykge1xuICAgIHRocm93IG5ldyBFcnJvcignaW5wdXQgc2hvdWxkIGJlIGZsb2F0IHRlbnNvcicpO1xuICB9XG59O1xuIiwiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7Z2V0R2xzbH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHtXZWJHTEluZmVyZW5jZUhhbmRsZXJ9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7VGV4dHVyZURhdGEsIFRleHR1cmVUeXBlfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBjb25zdCBlbmNvZGVBc1VpbnQ4ID0gKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXQ6IFRleHR1cmVEYXRhKTogVGV4dHVyZURhdGEgPT4ge1xuICBjb25zdCBvdXRwdXRTaGFwZSA9IGlucHV0LnNoYXBlO1xuICBjb25zdCBnbHNsID0gZ2V0R2xzbChpbmZlcmVuY2VIYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gIC8qKlxuICAgKiBodHRwczovL2dpdGh1Yi5jb20vdGVuc29yZmxvdy90ZmpzLWNvcmUvYmxvYi9tYXN0ZXIvc3JjL2tlcm5lbHMvd2ViZ2wvZW5jb2RlX2Zsb2F0X2dwdS50c1xuICAgKi9cbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgIGNvbnN0IGZsb2F0IEZMT0FUX01BWCA9IDEuNzAxNDExODRlMzg7XG4gICAgY29uc3QgZmxvYXQgRkxPQVRfTUlOID0gMS4xNzU0OTQzNWUtMzg7XG5cbiAgICBib29sIGlzTmFOKGZsb2F0IHZhbCkge1xuICAgICAgcmV0dXJuICh2YWwgPCAxLjAgfHwgMC4wIDwgdmFsIHx8IHZhbCA9PSAwLjApID8gZmFsc2UgOiB0cnVlO1xuICAgIH1cblxuICAgIGhpZ2hwIHZlYzQgZW5jb2RlQXNVaW50OChoaWdocCBmbG9hdCB2KSB7XG4gICAgICBpZiAoaXNOYU4odikpIHtcbiAgICAgICAgcmV0dXJuIHZlYzQoMjU1LCAyNTUsIDI1NSwgMjU1KTtcbiAgICAgIH1cblxuICAgICAgaGlnaHAgZmxvYXQgYXYgPSBhYnModik7XG5cbiAgICAgIGlmKGF2IDwgRkxPQVRfTUlOKSB7XG4gICAgICAgIHJldHVybiB2ZWM0KDAuMCwgMC4wLCAwLjAsIDAuMCk7XG4gICAgICB9IGVsc2UgaWYodiA+IEZMT0FUX01BWCkge1xuICAgICAgICByZXR1cm4gdmVjNCgwLjAsIDAuMCwgMTI4LjAsIDEyNy4wKSAvIDI1NS4wO1xuICAgICAgfSBlbHNlIGlmKHYgPCAtRkxPQVRfTUFYKSB7XG4gICAgICAgIHJldHVybiB2ZWM0KDAuMCwgMC4wLCAgMTI4LjAsIDI1NS4wKSAvIDI1NS4wO1xuICAgICAgfVxuXG4gICAgICBoaWdocCB2ZWM0IGMgPSB2ZWM0KDAsMCwwLDApO1xuXG4gICAgICBoaWdocCBmbG9hdCBlID0gZmxvb3IobG9nMihhdikpO1xuICAgICAgaGlnaHAgZmxvYXQgbSA9IGV4cDIoZnJhY3QobG9nMihhdikpKSAtIDEuMDtcblxuICAgICAgY1syXSA9IGZsb29yKDEyOC4wICogbSk7XG4gICAgICBtIC09IGNbMl0gLyAxMjguMDtcbiAgICAgIGNbMV0gPSBmbG9vcigzMjc2OC4wICogbSk7XG4gICAgICBtIC09IGNbMV0gLyAzMjc2OC4wO1xuICAgICAgY1swXSA9IGZsb29yKDgzODg2MDguMCAqIG0pO1xuXG4gICAgICBoaWdocCBmbG9hdCBlYmlhcyA9IGUgKyAxMjcuMDtcbiAgICAgIGNbM10gPSBmbG9vcihlYmlhcyAvIDIuMCk7XG4gICAgICBlYmlhcyAtPSBjWzNdICogMi4wO1xuICAgICAgY1syXSArPSBmbG9vcihlYmlhcykgKiAxMjguMDtcblxuICAgICAgY1szXSArPSAxMjguMCAqIHN0ZXAoMC4wLCAtdik7XG5cbiAgICAgIHJldHVybiBjIC8gMjU1LjA7XG4gICAgfVxuXG4gICAgdm9pZCBtYWluKCkge1xuICAgICAgZmxvYXQgdmFsdWUgPSAke2dsc2wudGV4dHVyZTJEfShYLFRleENvb3JkcykucjtcbiAgICAgICR7Z2xzbC5vdXRwdXR9ID0gZW5jb2RlQXNVaW50OCh2YWx1ZSk7XG4gICAgfWA7XG4gIGNvbnN0IHByb2dyYW1JbmZvID0ge1xuICAgIG5hbWU6ICdVaW50OEVuY29kZScsXG4gICAgaW5wdXRUeXBlczogW1RleHR1cmVUeXBlLnVucGFja2VkXSxcbiAgICBpbnB1dE5hbWVzOiBbJ1gnXSxcbiAgICBvdXRwdXQ6IHtkaW1zOiBvdXRwdXRTaGFwZSwgdHlwZTogaW5wdXQudGVuc29yLnR5cGUsIHRleHR1cmVUeXBlOiBUZXh0dXJlVHlwZS5kb3dubG9hZFVpbnQ4QXNGbG9hdH0sXG4gICAgc2hhZGVyU291cmNlLFxuICAgIGhhc01haW46IHRydWVcbiAgfTtcbiAgcmV0dXJuIGluZmVyZW5jZUhhbmRsZXIuZXhlY3V0ZVByb2dyYW0ocHJvZ3JhbUluZm8sIFtpbnB1dC50ZW5zb3JdKTtcbn07XG4iLCIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtBdHRyaWJ1dGVXaXRoQ2FjaGVLZXksIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleX0gZnJvbSAnLi4vLi4vLi4vYXR0cmlidXRlLXdpdGgtY2FjaGUta2V5JztcbmltcG9ydCB7R3JhcGh9IGZyb20gJy4uLy4uLy4uL2dyYXBoJztcbmltcG9ydCB7VGVuc29yfSBmcm9tICcuLi8uLi8uLi90ZW5zb3InO1xuaW1wb3J0IHtNQVhfQ0xJUCwgTUlOX0NMSVB9IGZyb20gJy4uLy4uLy4uL3V0aWwnO1xuaW1wb3J0IHtGdW5jdGlvblR5cGUsIEdsc2xWYWx1ZUZ1bmN0aW9ufSBmcm9tICcuLi9nbHNsLWRlZmluaXRpb25zJztcbmltcG9ydCB7Z2V0R2xzbH0gZnJvbSAnLi4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHtXZWJHTEluZmVyZW5jZUhhbmRsZXJ9IGZyb20gJy4uL2luZmVyZW5jZS1oYW5kbGVyJztcbmltcG9ydCB7UHJvZ3JhbUluZm8sIFByb2dyYW1JbmZvTG9hZGVyLCBQcm9ncmFtTWV0YWRhdGEsIFRleHR1cmVUeXBlfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBnbHNsQWJzKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgcmV0dXJuIGdsc2xCdWlsdGluVW5hcnkoJ2FicycpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xBY29zKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgcmV0dXJuIGdsc2xCdWlsdGluVW5hcnkoJ2Fjb3MnKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsQXNpbigpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIHJldHVybiBnbHNsQnVpbHRpblVuYXJ5KCdhc2luJyk7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbEF0YW4oKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICByZXR1cm4gZ2xzbEJ1aWx0aW5VbmFyeSgnYXRhbicpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xDZWlsKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgcmV0dXJuIGdsc2xCdWlsdGluVW5hcnkoJ2NlaWwnKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsQ29zKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgcmV0dXJuIGdsc2xCdWlsdGluVW5hcnkoJ2NvcycpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xFbHUoYWxwaGE6IG51bWJlcik6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdlbHUnO1xuICBjb25zdCBib2R5ID0gYFxuICBjb25zdCBmbG9hdCBhbHBoYSA9IGZsb2F0KCR7YWxwaGF9KTtcblxuICBmbG9hdCAke25hbWV9XyhmbG9hdCBhKSB7XG4gICAgcmV0dXJuIGEgPj0gMC4wID8gYTogKGV4cChhKSAtIDEuMCkgKiBhbHBoYTtcbiAgfVxuICB2ZWM0ICR7bmFtZX1fKHZlYzQgdikge1xuICAgIHJldHVybiB2ZWM0KCR7bmFtZX1fKHYueCksICR7bmFtZX1fKHYueSksICR7bmFtZX1fKHYueiksICR7bmFtZX1fKHYudykpO1xuICB9XG4gIGA7XG4gIHJldHVybiB7Ym9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWR9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xFeHAoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICByZXR1cm4gZ2xzbEJ1aWx0aW5VbmFyeSgnZXhwJyk7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbEZsb29yKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgcmV0dXJuIGdsc2xCdWlsdGluVW5hcnkoJ2Zsb29yJyk7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbENsaXAobWluOiBudW1iZXIsIG1heDogbnVtYmVyKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ2NsaXAnO1xuICBjb25zdCBib2R5ID0gYFxuICBjb25zdCBmbG9hdCBtaW4gPSBmbG9hdCgke21pbn0pO1xuICBjb25zdCBmbG9hdCBtYXggPSBmbG9hdCgke21heH0pO1xuXG4gIGZsb2F0ICR7bmFtZX1fKGZsb2F0IGEpIHtcbiAgICByZXR1cm4gY2xhbXAoYSwgbWluLCBtYXgpO1xuICB9XG4gIHZlYzQgJHtuYW1lfV8odmVjNCB2KSB7XG4gICAgcmV0dXJuIGNsYW1wKHYsIG1pbiwgbWF4KTtcbiAgfVxuICBgO1xuICByZXR1cm4ge2JvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsSWRlbnRpdHkoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ2luZGVudGl0eSc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX1fKGZsb2F0IGEpIHtcbiAgICByZXR1cm4gYTtcbiAgfVxuICB2ZWM0ICR7bmFtZX1fKHZlYzQgdikge1xuICAgIHJldHVybiB2O1xuICB9XG4gIGA7XG4gIHJldHVybiB7Ym9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWR9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xMZWFreVJlbHUoYWxwaGE6IG51bWJlcik6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdsZWFreVJlbHUnO1xuICBjb25zdCBib2R5ID0gYFxuICBjb25zdCBmbG9hdCBhbHBoYSA9IGZsb2F0KCR7YWxwaGF9KTtcblxuICBmbG9hdCAke25hbWV9XyhmbG9hdCBhKSB7XG4gICAgcmV0dXJuIGEgPCAwLjAgPyBhICogYWxwaGEgOiBhO1xuICB9XG4gIHZlYzQgJHtuYW1lfV8odmVjNCB2KSB7XG4gICAgcmV0dXJuIHZlYzQoJHtuYW1lfV8odi54KSwgJHtuYW1lfV8odi55KSwgJHtuYW1lfV8odi56KSwgJHtuYW1lfV8odi53KSk7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHtib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbExvZygpOiBHbHNsVmFsdWVGdW5jdGlvbiB7XG4gIHJldHVybiBnbHNsQnVpbHRpblVuYXJ5KCdsb2cnKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsTmVnKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICduZWcnO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9XyhmbG9hdCBhKSB7XG4gICAgcmV0dXJuIC1hO1xuICB9XG4gIHZlYzQgJHtuYW1lfV8odmVjNCB2KSB7XG4gICAgcmV0dXJuIC12O1xuICB9XG4gIGA7XG4gIHJldHVybiB7Ym9keSwgbmFtZSwgdHlwZTogRnVuY3Rpb25UeXBlLlZhbHVlQmFzZWR9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xOb3QoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ25vdCc7XG4gIGNvbnN0IGJvZHkgPSBgXG4gIGZsb2F0ICR7bmFtZX1fKGZsb2F0IGEpIHtcbiAgICByZXR1cm4gZmxvYXQoICEgYm9vbChhKSApO1xuICB9XG4gIGJvb2wgJHtuYW1lfV8oYm9vbCBhKSB7XG4gICAgcmV0dXJuICFhO1xuICB9XG4gIHZlYzQgJHtuYW1lfV8odmVjNCB2KSB7XG4gICAgcmV0dXJuIHZlYzQoIWJvb2wodi54KSwgIWJvb2wodi55KSwgIWJvb2wodi56KSwgIWJvb2wodi53KSk7XG4gIH1cbiAgYnZlYzQgJHtuYW1lfV8oYnZlYzQgdikge1xuICAgIHJldHVybiBidmVjNCghdi54LCAhdi55LCAhdi56LCAhdi53KTtcbiAgfVxuICBgO1xuICByZXR1cm4ge2JvZHksIG5hbWUsIHR5cGU6IEZ1bmN0aW9uVHlwZS5WYWx1ZUJhc2VkfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnbHNsU2luKCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgcmV0dXJuIGdsc2xCdWlsdGluVW5hcnkoJ3NpbicpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xSZWx1KCk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgbmFtZSA9ICdyZWx1JztcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfV8oZmxvYXQgYSkge1xuICAgIHJldHVybiBtYXgoIGEsIDAuMCApO1xuICB9XG4gIHZlYzQgJHtuYW1lfV8odmVjNCB2KSB7XG4gICAgcmV0dXJuIG1heCggdiwgMC4wICk7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHtib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbFNpZ21vaWQoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ3NpZ21vaWQnO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9XyhmbG9hdCBhKSB7XG4gICAgcmV0dXJuIDEuMCAvICgxLjAgKyBleHAoLWEpKTtcbiAgfVxuICB2ZWM0ICR7bmFtZX1fKHZlYzQgdikge1xuICAgIHJldHVybiAxLjAgLyAoMS4wICsgZXhwKC12KSk7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHtib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZH07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbFNxcnQoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICByZXR1cm4gZ2xzbEJ1aWx0aW5VbmFyeSgnc3FydCcpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdsc2xUYW4oKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICByZXR1cm4gZ2xzbEJ1aWx0aW5VbmFyeSgndGFuJyk7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2xzbFRhbmgoKTogR2xzbFZhbHVlRnVuY3Rpb24ge1xuICBjb25zdCBuYW1lID0gJ3RhbmgnO1xuICBjb25zdCBib2R5ID0gYFxuICBmbG9hdCAke25hbWV9XyhmbG9hdCBhKSB7XG4gICAgYSA9IGNsYW1wKGEsIC0xMC4sIDEwLik7XG4gICAgYSA9IGV4cCgyLiphKTtcbiAgICByZXR1cm4gKGEgLSAxLikgLyAoYSArIDEuKTtcbiAgfVxuICB2ZWM0ICR7bmFtZX1fKHZlYzQgdikge1xuICAgIHYgPSBjbGFtcCh2LCAtMTAuLCAxMC4pO1xuICAgIHYgPSBleHAoMi4qdik7XG4gICAgcmV0dXJuICh2IC0gMS4pIC8gKHYgKyAxLik7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHtib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZH07XG59XG5mdW5jdGlvbiBnbHNsQnVpbHRpblVuYXJ5KG5hbWU6IHN0cmluZyk6IEdsc2xWYWx1ZUZ1bmN0aW9uIHtcbiAgY29uc3QgYm9keSA9IGBcbiAgZmxvYXQgJHtuYW1lfV8oZmxvYXQgYSkge1xuICAgIHJldHVybiAke25hbWV9KGEpO1xuICB9XG4gIHZlYzQgJHtuYW1lfV8odmVjNCB2KSB7XG4gICAgcmV0dXJuICR7bmFtZX0odik7XG4gIH1cbiAgYDtcbiAgcmV0dXJuIHtib2R5LCBuYW1lLCB0eXBlOiBGdW5jdGlvblR5cGUuVmFsdWVCYXNlZH07XG59XG5cbi8vLy8vXG4vLy8vL1xuLy8vLy9cblxuY29uc3QgY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mbyA9XG4gICAgKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgbWV0YWRhdGE6IFByb2dyYW1NZXRhZGF0YSwgaW5wdXQ6IFRlbnNvciwgZ2xzbEZ1bmM6IEdsc2xWYWx1ZUZ1bmN0aW9uKTpcbiAgICAgICAgUHJvZ3JhbUluZm8gPT4ge1xuICAgICAgICAgIGNvbnN0IHRleHR1cmVUeXBlID0gaGFuZGxlci5zZXNzaW9uLnBhY2sgPyBUZXh0dXJlVHlwZS5wYWNrZWQgOiBUZXh0dXJlVHlwZS51bnBhY2tlZDtcbiAgICAgICAgICBjb25zdCBnbHNsID0gZ2V0R2xzbChoYW5kbGVyLnNlc3Npb24uYmFja2VuZC5nbENvbnRleHQudmVyc2lvbik7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC4uLm1ldGFkYXRhLFxuICAgICAgICAgICAgb3V0cHV0OiB7ZGltczogaW5wdXQuZGltcywgdHlwZTogaW5wdXQudHlwZSwgdGV4dHVyZVR5cGV9LFxuICAgICAgICAgICAgc2hhZGVyU291cmNlOiBgXG4gICAgICR7Z2xzbEZ1bmMuYm9keX1cbiAgICAgdm9pZCBtYWluKCkge1xuICAgICAgIHZlYzQgdiA9ICR7Z2xzbC50ZXh0dXJlMkR9KEEsIFRleENvb3Jkcyk7XG4gICAgICAgdiA9ICR7Z2xzbEZ1bmMubmFtZX1fKHYpO1xuICAgICAgICR7Z2xzbC5vdXRwdXR9ID0gdjtcbiAgICAgfVxuICAgICBgLFxuICAgICAgICAgICAgaGFzTWFpbjogdHJ1ZVxuICAgICAgICAgIH07XG4gICAgICAgIH07XG5cbmNvbnN0IGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIgPVxuICAgIChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0OiBUZW5zb3IsIGdsc2xGdW5jOiBHbHNsVmFsdWVGdW5jdGlvbiwgY2FjaGVLZXk/OiBzdHJpbmcpOlxuICAgICAgICBQcm9ncmFtSW5mb0xvYWRlciA9PiB7XG4gICAgICAgICAgY29uc3QgdGV4dHVyZVR5cGUgPSBoYW5kbGVyLnNlc3Npb24ucGFjayA/IFRleHR1cmVUeXBlLnBhY2tlZCA6IFRleHR1cmVUeXBlLnVucGFja2VkO1xuICAgICAgICAgIGNvbnN0IG1ldGFkYXRhID0ge25hbWU6IGdsc2xGdW5jLm5hbWUsIGlucHV0VHlwZXM6IFt0ZXh0dXJlVHlwZV0sIGlucHV0TmFtZXM6IFsnQSddLCBjYWNoZUhpbnQ6IGNhY2hlS2V5fTtcbiAgICAgICAgICByZXR1cm4gey4uLm1ldGFkYXRhLCBnZXQ6ICgpID0+IGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm8oaGFuZGxlciwgbWV0YWRhdGEsIGlucHV0LCBnbHNsRnVuYyl9O1xuICAgICAgICB9O1xuXG5leHBvcnQgY29uc3QgYWJzID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6XG4gICAgVGVuc29yW10gPT4gW2hhbmRsZXIucnVuKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsQWJzKCkpLCBpbnB1dHMpXTtcblxuZXhwb3J0IGNvbnN0IGFjb3MgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTpcbiAgICBUZW5zb3JbXSA9PiBbaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xBY29zKCkpLCBpbnB1dHMpXTtcblxuZXhwb3J0IGNvbnN0IGFzaW4gPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTpcbiAgICBUZW5zb3JbXSA9PiBbaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xBc2luKCkpLCBpbnB1dHMpXTtcblxuZXhwb3J0IGNvbnN0IGF0YW4gPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTpcbiAgICBUZW5zb3JbXSA9PiBbaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xBdGFuKCkpLCBpbnB1dHMpXTtcblxuZXhwb3J0IGludGVyZmFjZSBDbGlwQXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHJlYWRvbmx5IG1pbjogbnVtYmVyO1xuICByZWFkb25seSBtYXg6IG51bWJlcjtcbn1cblxuZXhwb3J0IGNvbnN0IGNsaXAgPVxuICAgIChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IENsaXBBdHRyaWJ1dGVzKTogVGVuc29yW10gPT4gW2hhbmRsZXIucnVuKFxuICAgICAgICBjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKFxuICAgICAgICAgICAgaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsQ2xpcChhdHRyaWJ1dGVzLm1pbiwgYXR0cmlidXRlcy5tYXgpLCBhdHRyaWJ1dGVzLmNhY2hlS2V5KSxcbiAgICAgICAgaW5wdXRzKV07XG5cbmV4cG9ydCBjb25zdCBwYXJzZUNsaXBBdHRyaWJ1dGVzID0gKG5vZGU6IEdyYXBoLk5vZGUpOiBDbGlwQXR0cmlidXRlcyA9PiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoXG4gICAge21pbjogbm9kZS5hdHRyaWJ1dGVzLmdldEZsb2F0KCdtaW4nLCBNSU5fQ0xJUCksIG1heDogbm9kZS5hdHRyaWJ1dGVzLmdldEZsb2F0KCdtYXgnLCBNQVhfQ0xJUCl9KTtcblxuZXhwb3J0IGNvbnN0IGNsaXBWMTEgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogVGVuc29yW10gPT4ge1xuICBjb25zdCBhdHRyaWJ1dGVzID0gZ2VuZXJhdGVDbGlwQXR0cmlidXRlc0Zyb21JbnB1dHMoaGFuZGxlciwgaW5wdXRzKTtcbiAgcmV0dXJuIGNsaXAoaGFuZGxlciwgW2lucHV0c1swXV0sIGF0dHJpYnV0ZXMpO1xufTtcblxuY29uc3QgZ2VuZXJhdGVDbGlwQXR0cmlidXRlc0Zyb21JbnB1dHMgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTogQ2xpcEF0dHJpYnV0ZXMgPT4ge1xuICBpZiAoaW5wdXRzLmxlbmd0aCA+PSAzICYmXG4gICAgICAoIWhhbmRsZXIuc2Vzc2lvbi5pc0luaXRpYWxpemVyKGlucHV0c1sxXS5kYXRhSWQpIHx8ICFoYW5kbGVyLnNlc3Npb24uaXNJbml0aWFsaXplcihpbnB1dHNbMl0uZGF0YUlkKSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2R5bmFtaWMgY2xpcCBhdHRyaWJ1dGVzIGFyZSBub3QgYWxsb3dlZCcpO1xuICB9XG5cbiAgY29uc3QgbWluID0gKGlucHV0cy5sZW5ndGggPj0gMykgPyBpbnB1dHNbMV0ubnVtYmVyRGF0YVswXSA6IE1JTl9DTElQO1xuICBjb25zdCBtYXggPSAoaW5wdXRzLmxlbmd0aCA+PSAzKSA/IGlucHV0c1syXS5udW1iZXJEYXRhWzBdIDogTUFYX0NMSVA7XG4gIHJldHVybiBjcmVhdGVBdHRyaWJ1dGVXaXRoQ2FjaGVLZXkoe21pbiwgbWF4fSk7XG59O1xuXG5leHBvcnQgY29uc3QgY2VpbCA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOlxuICAgIFRlbnNvcltdID0+IFtoYW5kbGVyLnJ1bihjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbENlaWwoKSksIGlucHV0cyldO1xuXG5leHBvcnQgY29uc3QgY29zID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6XG4gICAgVGVuc29yW10gPT4gW2hhbmRsZXIucnVuKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsQ29zKCkpLCBpbnB1dHMpXTtcblxuZXhwb3J0IGludGVyZmFjZSBFbHVBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgYWxwaGE6IG51bWJlcjtcbn1cblxuZXhwb3J0IGNvbnN0IGVsdSA9XG4gICAgKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogRWx1QXR0cmlidXRlcyk6IFRlbnNvcltdID0+IFtoYW5kbGVyLnJ1bihcbiAgICAgICAgY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xFbHUoYXR0cmlidXRlcy5hbHBoYSksIGF0dHJpYnV0ZXMuY2FjaGVLZXkpLFxuICAgICAgICBpbnB1dHMpXTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlRWx1QXR0cmlidXRlcyA9IChub2RlOiBHcmFwaC5Ob2RlKTogRWx1QXR0cmlidXRlcyA9PlxuICAgIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7YWxwaGE6IG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdCgnYWxwaGEnLCAxLjApfSk7XG5cbmV4cG9ydCBjb25zdCBleHAgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTpcbiAgICBUZW5zb3JbXSA9PiBbaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xFeHAoKSksIGlucHV0cyldO1xuXG5leHBvcnQgY29uc3QgZmxvb3IgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTpcbiAgICBUZW5zb3JbXSA9PiBbaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xGbG9vcigpKSwgaW5wdXRzKV07XG5cbmV4cG9ydCBjb25zdCBpZGVudGl0eSA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOlxuICAgIFRlbnNvcltdID0+IFtoYW5kbGVyLnJ1bihjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbElkZW50aXR5KCkpLCBpbnB1dHMpXTtcblxuZXhwb3J0IGludGVyZmFjZSBMZWFreVJlbHVBdHRyaWJ1dGVzIGV4dGVuZHMgQXR0cmlidXRlV2l0aENhY2hlS2V5IHtcbiAgcmVhZG9ubHkgYWxwaGE6IG51bWJlcjtcbn1cblxuZXhwb3J0IGNvbnN0IGxlYWt5UmVsdSA9XG4gICAgKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogTGVha3lSZWx1QXR0cmlidXRlcyk6IFRlbnNvcltdID0+IFtoYW5kbGVyLnJ1bihcbiAgICAgICAgY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xMZWFreVJlbHUoYXR0cmlidXRlcy5hbHBoYSksIGF0dHJpYnV0ZXMuY2FjaGVLZXkpLFxuICAgICAgICBpbnB1dHMpXTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlTGVha3lSZWx1QXR0cmlidXRlcyA9IChub2RlOiBHcmFwaC5Ob2RlKTogTGVha3lSZWx1QXR0cmlidXRlcyA9PlxuICAgIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7YWxwaGE6IG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdCgnYWxwaGEnLCAwLjAxKX0pO1xuXG5leHBvcnQgY29uc3QgbG9nID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6XG4gICAgVGVuc29yW10gPT4gW2hhbmRsZXIucnVuKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsTG9nKCkpLCBpbnB1dHMpXTtcblxuZXhwb3J0IGNvbnN0IG5lZyA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOlxuICAgIFRlbnNvcltdID0+IFtoYW5kbGVyLnJ1bihjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbE5lZygpKSwgaW5wdXRzKV07XG5cbmV4cG9ydCBjb25zdCBub3QgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTpcbiAgICBUZW5zb3JbXSA9PiBbaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xOb3QoKSksIGlucHV0cyldO1xuXG5leHBvcnQgY29uc3QgcmVsdSA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOlxuICAgIFRlbnNvcltdID0+IFtoYW5kbGVyLnJ1bihjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbFJlbHUoKSksIGlucHV0cyldO1xuXG5leHBvcnQgY29uc3Qgc2lnbW9pZCA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOlxuICAgIFRlbnNvcltdID0+IFtoYW5kbGVyLnJ1bihjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbFNpZ21vaWQoKSksIGlucHV0cyldO1xuXG5leHBvcnQgY29uc3Qgc2luID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6XG4gICAgVGVuc29yW10gPT4gW2hhbmRsZXIucnVuKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsU2luKCkpLCBpbnB1dHMpXTtcblxuZXhwb3J0IGNvbnN0IHNxcnQgPSAoaGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdKTpcbiAgICBUZW5zb3JbXSA9PiBbaGFuZGxlci5ydW4oY3JlYXRlRWxlbWVudHdpc2VQcm9ncmFtSW5mb0xvYWRlcihoYW5kbGVyLCBpbnB1dHNbMF0sIGdsc2xTcXJ0KCkpLCBpbnB1dHMpXTtcblxuZXhwb3J0IGNvbnN0IHRhbiA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10pOlxuICAgIFRlbnNvcltdID0+IFtoYW5kbGVyLnJ1bihjcmVhdGVFbGVtZW50d2lzZVByb2dyYW1JbmZvTG9hZGVyKGhhbmRsZXIsIGlucHV0c1swXSwgZ2xzbFRhbigpKSwgaW5wdXRzKV07XG5cbmV4cG9ydCBjb25zdCB0YW5oID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6XG4gICAgVGVuc29yW10gPT4gW2hhbmRsZXIucnVuKGNyZWF0ZUVsZW1lbnR3aXNlUHJvZ3JhbUluZm9Mb2FkZXIoaGFuZGxlciwgaW5wdXRzWzBdLCBnbHNsVGFuaCgpKSwgaW5wdXRzKV07XG4iLCIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtUZW5zb3J9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQge2dldEdsc2x9IGZyb20gJy4uL2dsc2wtc291cmNlJztcbmltcG9ydCB7V2ViR0xJbmZlcmVuY2VIYW5kbGVyfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQge1Byb2dyYW1JbmZvLCBQcm9ncmFtSW5mb0xvYWRlciwgVGV4dHVyZVR5cGV9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB7Z2V0Q29vcmRzRGF0YVR5cGV9IGZyb20gJy4uL3V0aWxzJztcblxuaW1wb3J0IHtnZXRDaGFubmVscywgdW5wYWNrRnJvbUNoYW5uZWx9IGZyb20gJy4vcGFja2luZy11dGlscyc7XG5cbmNvbnN0IHVucGFja1Byb2dyYW1NZXRhZGF0YSA9IHtcbiAgbmFtZTogJ3VucGFjaycsXG4gIGlucHV0TmFtZXM6IFsnQSddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUucGFja2VkXVxufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZVVucGFja1Byb2dyYW1JbmZvID0gKGhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXQ6IFRlbnNvcik6IFByb2dyYW1JbmZvID0+IHtcbiAgY29uc3QgcmFuayA9IGlucHV0LmRpbXMubGVuZ3RoO1xuXG4gIGNvbnN0IGNoYW5uZWxzID0gZ2V0Q2hhbm5lbHMoJ3JjJywgcmFuayk7XG4gIGNvbnN0IGlubmVyRGltcyA9IGNoYW5uZWxzLnNsaWNlKC0yKTtcbiAgY29uc3QgY29vcmRzRGF0YVR5cGUgPSBnZXRDb29yZHNEYXRhVHlwZShyYW5rKTtcbiAgY29uc3QgdW5wYWNrQ2hhbm5lbCA9IHVucGFja0Zyb21DaGFubmVsKCk7XG4gIGNvbnN0IGlzU2NhbGFyID0gKGlucHV0LmRpbXMubGVuZ3RoID09PSAwKTtcbiAgY29uc3Qgc291cmNlQ29vcmRzID0gaXNTY2FsYXIgPyAnJyA6IGdldFNvdXJjZUNvb3JkcyhyYW5rLCBjaGFubmVscyk7XG4gIGNvbnN0IGNvb3JkcyA9IHJhbmsgPD0gMSA/ICdyYycgOiBgdmVjMigke2lubmVyRGltcy5qb2luKCcsJyl9KWA7XG4gIGNvbnN0IGdsc2wgPSBnZXRHbHNsKGhhbmRsZXIuc2Vzc2lvbi5iYWNrZW5kLmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgY29uc3Qgc2hhZGVyU291cmNlID0gYFxuICAgICR7dW5wYWNrQ2hhbm5lbH1cbiAgICB2b2lkIG1haW4oKSB7XG4gICAgICAke2Nvb3Jkc0RhdGFUeXBlfSByYyA9IGdldE91dHB1dENvb3JkcygpO1xuXG4gICAgICAgLy8gU2FtcGxlIHRoZSB0ZXh0dXJlIHdpdGggdGhlIGNvb3JkcyB0byBnZXQgdGhlIHJnYmEgY2hhbm5lbCB2YWx1ZS5cbiAgICAgICB2ZWM0IHBhY2tlZElucHV0ID0gZ2V0QSgke3NvdXJjZUNvb3Jkc30pO1xuXG4gICAgICAgJHtnbHNsLm91dHB1dH0gPSB2ZWM0KGdldENoYW5uZWwocGFja2VkSW5wdXQsICR7Y29vcmRzfSksIDAsIDAsIDApO1xuICAgICB9XG4gICBgO1xuXG4gIHJldHVybiB7XG4gICAgLi4udW5wYWNrUHJvZ3JhbU1ldGFkYXRhLFxuICAgIGhhc01haW46IHRydWUsXG4gICAgb3V0cHV0OiB7ZGltczogaW5wdXQuZGltcywgdHlwZTogaW5wdXQudHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkfSxcbiAgICBzaGFkZXJTb3VyY2VcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVVbnBhY2tQcm9ncmFtSW5mb0xvYWRlciA9IChoYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0OiBUZW5zb3IpOiBQcm9ncmFtSW5mb0xvYWRlciA9PlxuICAgICh7Li4udW5wYWNrUHJvZ3JhbU1ldGFkYXRhLCBnZXQ6ICgpID0+IGNyZWF0ZVVucGFja1Byb2dyYW1JbmZvKGhhbmRsZXIsIGlucHV0KX0pO1xuXG5mdW5jdGlvbiBnZXRTb3VyY2VDb29yZHMocmFuazogbnVtYmVyLCBkaW1zOiBzdHJpbmdbXSk6IHN0cmluZyB7XG4gIGlmIChyYW5rID09PSAxKSB7XG4gICAgcmV0dXJuICdyYyc7XG4gIH1cblxuICBsZXQgY29vcmRzID0gJyc7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuazsgaSsrKSB7XG4gICAgY29vcmRzICs9IGRpbXNbaV07XG4gICAgaWYgKGkgPCByYW5rIC0gMSkge1xuICAgICAgY29vcmRzICs9ICcsJztcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGNvb3Jkcztcbn1cbiIsIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge0dyYXBofSBmcm9tICcuLi8uLi8uLi9ncmFwaCc7XG5pbXBvcnQge09wZXJhdG9ySW1wbGVtZW50YXRpb24sIE9wZXJhdG9ySW5pdGlhbGl6YXRpb259IGZyb20gJy4uLy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi4vLi4vLi4vdGVuc29yJztcbmltcG9ydCB7U2hhcGVVdGlsfSBmcm9tICcuLi8uLi8uLi91dGlsJztcbmltcG9ydCB7V2ViR0xJbmZlcmVuY2VIYW5kbGVyfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5cbmV4cG9ydCBjb25zdCB1bnNxdWVlemU6IE9wZXJhdG9ySW1wbGVtZW50YXRpb248bnVtYmVyW10+ID1cbiAgICAoaW5mZXJlbmNlSGFuZGxlcjogV2ViR0xJbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHM6IFRlbnNvcltdLCBheGVzOiBudW1iZXJbXSk6IFRlbnNvcltdID0+IHtcbiAgICAgIHZhbGlkYXRlSW5wdXRzKGlucHV0cyk7XG4gICAgICBjb25zdCBvdXRwdXRTaGFwZSA9IFNoYXBlVXRpbC51bnNxdWVlemVTaGFwZShpbnB1dHNbMF0uZGltcywgYXhlcyk7XG4gICAgICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJlc2hhcGVVbnBhY2tlZChpbnB1dHNbMF0sIG91dHB1dFNoYXBlKTtcbiAgICAgIHJldHVybiBbb3V0cHV0XTtcbiAgICB9O1xuXG5leHBvcnQgY29uc3QgdW5zcXVlZXplVjEzID0gKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSk6IFRlbnNvcltdID0+IHtcbiAgdmFsaWRhdGVJbnB1dHNWMTMoaW5wdXRzKTtcbiAgcmV0dXJuIHVuc3F1ZWV6ZShpbmZlcmVuY2VIYW5kbGVyLCBbaW5wdXRzWzBdXSwgQXJyYXkuZnJvbShpbnB1dHNbMV0uaW50ZWdlckRhdGEpKTtcbn07XG5cbmV4cG9ydCBjb25zdCBwYXJzZVVuc3F1ZWV6ZUF0dHJpYnV0ZXM6IE9wZXJhdG9ySW5pdGlhbGl6YXRpb248bnVtYmVyW10+ID0gKG5vZGU6IEdyYXBoLk5vZGUpOiBudW1iZXJbXSA9PlxuICAgIG5vZGUuYXR0cmlidXRlcy5nZXRJbnRzKCdheGVzJyk7XG5cbmNvbnN0IHZhbGlkYXRlSW5wdXRzID0gKGlucHV0czogVGVuc29yW10pOiB2b2lkID0+IHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignVW5zcXVlZXplIHJlcXVpcmVzIDEgaW5wdXQuJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzWzBdLnR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGlucHV0IHRlbnNvciB0eXBlcy4nKTtcbiAgfVxufTtcblxuY29uc3QgdmFsaWRhdGVJbnB1dHNWMTMgPSAoaW5wdXRzOiBUZW5zb3JbXSk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCBpbnB1dHMubGVuZ3RoICE9PSAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdVbnNxdWVlemUgcmVxdWlyZXMgMiBpbnB1dHMuJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzWzFdLnR5cGUgIT09ICdpbnQzMicpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgdHlwZS4nKTtcbiAgfVxufTtcbiIsIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge0F0dHJpYnV0ZVdpdGhDYWNoZUtleSwgY3JlYXRlQXR0cmlidXRlV2l0aENhY2hlS2V5fSBmcm9tICcuLi8uLi8uLi9hdHRyaWJ1dGUtd2l0aC1jYWNoZS1rZXknO1xuaW1wb3J0IHtHcmFwaH0gZnJvbSAnLi4vLi4vLi4vZ3JhcGgnO1xuaW1wb3J0IHtPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9ufSBmcm9tICcuLi8uLi8uLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHtUZW5zb3J9IGZyb20gJy4uLy4uLy4uL3RlbnNvcic7XG5pbXBvcnQge2dldEdsc2x9IGZyb20gJy4uL2dsc2wtc291cmNlJztcbmltcG9ydCB7V2ViR0xJbmZlcmVuY2VIYW5kbGVyfSBmcm9tICcuLi9pbmZlcmVuY2UtaGFuZGxlcic7XG5pbXBvcnQge1Byb2dyYW1JbmZvLCBUZXh0dXJlVHlwZX0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFVwc2FtcGxlQXR0cmlidXRlcyBleHRlbmRzIEF0dHJpYnV0ZVdpdGhDYWNoZUtleSB7XG4gIHJlYWRvbmx5IG9wc2V0OiBudW1iZXI7XG4gIHJlYWRvbmx5IGlzUmVzaXplOiBib29sZWFuO1xuICByZWFkb25seSBtb2RlOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHNjYWxlczogbnVtYmVyW107XG4gIHJlYWRvbmx5IGV4dHJhcG9sYXRpb25WYWx1ZTogbnVtYmVyO1xuICByZWFkb25seSBjb29yZGluYXRlVHJhbnNmb3JtTW9kZTogc3RyaW5nO1xuICByZWFkb25seSB1c2VFeHRyYXBvbGF0aW9uOiBib29sZWFuO1xuICByZWFkb25seSBuZWVkUm9pSW5wdXQ6IGJvb2xlYW47XG4gIHJlYWRvbmx5IG5lYXJlc3RNb2RlOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGN1YmljQ29lZmZpY2llbnRBOiBudW1iZXI7XG4gIHJlYWRvbmx5IGV4Y2x1ZGVPdXRzaWRlOiBib29sZWFuO1xuICByZWFkb25seSB1c2VOZWFyZXN0MnhPcHRpbWl6YXRpb246IGJvb2xlYW47XG4gIHJlYWRvbmx5IHJvaUlucHV0SWR4OiBudW1iZXI7XG4gIHJlYWRvbmx5IHNjYWxlc0lucHV0SWR4OiBudW1iZXI7XG4gIHJlYWRvbmx5IHNpemVzSW5wdXRJZHg6IG51bWJlcjtcbn1cblxuY29uc3QgdXBzYW1wbGVQcm9ncmFtTWV0YWRhdGEgPSB7XG4gIG5hbWU6ICdVcHNhbXBsZScsXG4gIGlucHV0TmFtZXM6IFsnWCddLFxuICBpbnB1dFR5cGVzOiBbVGV4dHVyZVR5cGUudW5wYWNrZWRdLFxufTtcblxuZXhwb3J0IGNvbnN0IHVwc2FtcGxlOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPFVwc2FtcGxlQXR0cmlidXRlcz4gPVxuICAgIChpbmZlcmVuY2VIYW5kbGVyOiBXZWJHTEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIGF0dHJpYnV0ZXM6IFVwc2FtcGxlQXR0cmlidXRlcyk6IFRlbnNvcltdID0+IHtcbiAgICAgIHZhbGlkYXRlSW5wdXRzKGlucHV0cywgYXR0cmlidXRlcyk7XG4gICAgICBjb25zdCBvdXRwdXQgPSBpbmZlcmVuY2VIYW5kbGVyLnJ1bihcbiAgICAgICAgICB7XG4gICAgICAgICAgICAuLi51cHNhbXBsZVByb2dyYW1NZXRhZGF0YSxcbiAgICAgICAgICAgIGNhY2hlSGludDogYXR0cmlidXRlcy5jYWNoZUtleSxcbiAgICAgICAgICAgIGdldDogKCkgPT4gY3JlYXRlVXBzYW1wbGVQcm9ncmFtSW5mbyhpbmZlcmVuY2VIYW5kbGVyLCBpbnB1dHMsIGF0dHJpYnV0ZXMpXG4gICAgICAgICAgfSxcbiAgICAgICAgICBpbnB1dHMpO1xuICAgICAgcmV0dXJuIFtvdXRwdXRdO1xuICAgIH07XG5cbmV4cG9ydCBjb25zdCBwYXJzZVVwc2FtcGxlQXR0cmlidXRlc1Y3OiBPcGVyYXRvckluaXRpYWxpemF0aW9uPFVwc2FtcGxlQXR0cmlidXRlcz4gPVxuICAgIChub2RlOiBHcmFwaC5Ob2RlKTogVXBzYW1wbGVBdHRyaWJ1dGVzID0+IHBhcnNlVXBzYW1wbGVBdHRyaWJ1dGVzKG5vZGUsIDcpO1xuXG5leHBvcnQgY29uc3QgcGFyc2VVcHNhbXBsZUF0dHJpYnV0ZXNWOTogT3BlcmF0b3JJbml0aWFsaXphdGlvbjxVcHNhbXBsZUF0dHJpYnV0ZXM+ID1cbiAgICAobm9kZTogR3JhcGguTm9kZSk6IFVwc2FtcGxlQXR0cmlidXRlcyA9PiBwYXJzZVVwc2FtcGxlQXR0cmlidXRlcyhub2RlLCA5KTtcblxuZXhwb3J0IGNvbnN0IHBhcnNlVXBzYW1wbGVBdHRyaWJ1dGVzID0gKG5vZGU6IEdyYXBoLk5vZGUsIG9wc2V0OiBudW1iZXIpOiBVcHNhbXBsZUF0dHJpYnV0ZXMgPT4ge1xuICBjb25zdCBpc1Jlc2l6ZSA9IChvcHNldCA+PSAxMCk7XG5cbiAgLy8gcHJvY2Vzc2luZyBub2RlIGF0dHJpYnV0ZXNcbiAgY29uc3QgbW9kZSA9IG5vZGUuYXR0cmlidXRlcy5nZXRTdHJpbmcoJ21vZGUnLCAnbmVhcmVzdCcpO1xuICBpZiAobW9kZSAhPT0gJ25lYXJlc3QnICYmIG1vZGUgIT09ICdsaW5lYXInICYmIChvcHNldCA8IDExIHx8IG1vZGUgIT09ICdjdWJpYycpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGB1bnJlY29nbml6ZWQgbW9kZTogJHttb2RlfWApO1xuICB9XG5cbiAgbGV0IHNjYWxlczogbnVtYmVyW10gPSBbXTtcbiAgaWYgKG9wc2V0IDwgOSkge1xuICAgIHNjYWxlcyA9IG5vZGUuYXR0cmlidXRlcy5nZXRGbG9hdHMoJ3NjYWxlcycpO1xuICAgIHNjYWxlc1ZhbGlkYXRpb24oc2NhbGVzLCBtb2RlLCBpc1Jlc2l6ZSk7XG4gIH1cblxuICBjb25zdCBleHRyYXBvbGF0aW9uVmFsdWUgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0RmxvYXQoJ2V4dHJhcG9sYXRpb25fdmFsdWUnLCAwLjApO1xuXG4gIGNvbnN0IGNvb3JkaW5hdGVUcmFuc2Zvcm1Nb2RlID1cbiAgICAgIG9wc2V0ID4gMTAgPyBub2RlLmF0dHJpYnV0ZXMuZ2V0U3RyaW5nKCdjb29yZGluYXRlX3RyYW5zZm9ybWF0aW9uX21vZGUnLCAnaGFsZl9waXhlbCcpIDogJ2FzeW1tZXRyaWMnO1xuICBpZiAoW1xuICAgICAgICAnYXN5bW1ldHJpYycsICdweXRvcmNoX2hhbGZfcGl4ZWwnLCAndGZfaGFsZl9waXhlbF9mb3Jfbm4nLCAnYWxpZ25fY29ybmVycycsICd0Zl9jcm9wX2FuZF9yZXNpemUnLCAnaGFsZl9waXhlbCdcbiAgICAgIF0uaW5kZXhPZihjb29yZGluYXRlVHJhbnNmb3JtTW9kZSkgPT09IC0xKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBjb29yZGluYXRlX3RyYW5zZm9ybV9tb2RlICcke2Nvb3JkaW5hdGVUcmFuc2Zvcm1Nb2RlfScgaXMgbm90IHN1cHBvcnRlZGApO1xuICB9XG4gIGNvbnN0IG5lZWRSb2lJbnB1dCA9IChjb29yZGluYXRlVHJhbnNmb3JtTW9kZSA9PT0gJ3RmX2Nyb3BfYW5kX3Jlc2l6ZScpO1xuICBjb25zdCB1c2VFeHRyYXBvbGF0aW9uID0gbmVlZFJvaUlucHV0O1xuXG4gIGNvbnN0IG5lYXJlc3RNb2RlID1cbiAgICAgIChtb2RlID09PSAnbmVhcmVzdCcgJiYgb3BzZXQgPj0gMTEpID8gbm9kZS5hdHRyaWJ1dGVzLmdldFN0cmluZygnbmVhcmVzdF9tb2RlJywgJ3JvdW5kX3ByZWZlcl9mbG9vcicpIDogJyc7XG4gIGlmIChbJ3JvdW5kX3ByZWZlcl9mbG9vcicsICdyb3VuZF9wcmVmZXJfY2VpbCcsICdmbG9vcicsICdjZWlsJywgJyddLmluZGV4T2YobmVhcmVzdE1vZGUpID09PSAtMSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgbmVhcmVzdF9tb2RlICcke25lYXJlc3RNb2RlfScgaXMgbm90IHN1cHBvcnRlZGApO1xuICB9XG5cbiAgY29uc3QgY3ViaWNDb2VmZmljaWVudEEgPSBub2RlLmF0dHJpYnV0ZXMuZ2V0RmxvYXQoJ2N1YmljX2NvZWZmX2EnLCAtMC43NSk7XG4gIGNvbnN0IGV4Y2x1ZGVPdXRzaWRlID0gbm9kZS5hdHRyaWJ1dGVzLmdldEludCgnZXhjbHVkZV9vdXRzaWRlJywgMCkgIT09IDA7XG4gIGlmIChleGNsdWRlT3V0c2lkZSAmJiBtb2RlICE9PSAnY3ViaWMnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdleGNsdWRlX291dHNpZGUgY2FuIGJlIHNldCB0byAxIG9ubHkgd2hlbiBtb2RlIGlzIENVQklDLicpO1xuICB9XG5cbiAgY29uc3QgdXNlTmVhcmVzdDJ4T3B0aW1pemF0aW9uID1cbiAgICAgIChvcHNldCA8IDExKSA/IHRydWUgOiAobW9kZSA9PT0gJ25lYXJlc3QnICYmIGNvb3JkaW5hdGVUcmFuc2Zvcm1Nb2RlID09PSAnYXN5bW1ldHJpYycgJiYgbmVhcmVzdE1vZGUgPT09ICdmbG9vcicpO1xuXG4gIGxldCByb2lJbnB1dElkeCA9IDA7XG4gIGxldCBzY2FsZXNJbnB1dElkeCA9IDA7XG4gIGxldCBzaXplc0lucHV0SWR4ID0gMDtcblxuICBpZiAob3BzZXQgPiAxMCkge1xuICAgIC8vIGhhbmRsZSB3aGVuIHJvaUlucHV0IGlzIG5vdCBnaXZlblxuICAgIGlmIChub2RlLmlucHV0cy5sZW5ndGggPiAyKSB7XG4gICAgICByb2lJbnB1dElkeCA9IDE7XG4gICAgICBzY2FsZXNJbnB1dElkeCA9IDI7XG4gICAgICBzaXplc0lucHV0SWR4ID0gMztcbiAgICB9IGVsc2Uge1xuICAgICAgc2NhbGVzSW5wdXRJZHggPSAxO1xuICAgICAgc2l6ZXNJbnB1dElkeCA9IDI7XG4gICAgfVxuICB9IGVsc2UgaWYgKG9wc2V0ID09PSA5KSB7XG4gICAgc2NhbGVzSW5wdXRJZHggPSAxO1xuICB9XG5cbiAgcmV0dXJuIGNyZWF0ZUF0dHJpYnV0ZVdpdGhDYWNoZUtleSh7XG4gICAgb3BzZXQsXG4gICAgaXNSZXNpemUsXG4gICAgbW9kZSxcbiAgICBzY2FsZXMsXG4gICAgZXh0cmFwb2xhdGlvblZhbHVlLFxuICAgIGNvb3JkaW5hdGVUcmFuc2Zvcm1Nb2RlLFxuICAgIHVzZUV4dHJhcG9sYXRpb24sXG4gICAgbmVlZFJvaUlucHV0LFxuICAgIG5lYXJlc3RNb2RlLFxuICAgIGN1YmljQ29lZmZpY2llbnRBLFxuICAgIGV4Y2x1ZGVPdXRzaWRlLFxuICAgIHVzZU5lYXJlc3QyeE9wdGltaXphdGlvbixcbiAgICByb2lJbnB1dElkeCxcbiAgICBzY2FsZXNJbnB1dElkeCxcbiAgICBzaXplc0lucHV0SWR4XG4gIH0pO1xufTtcblxuY29uc3QgY3JlYXRlVXBzYW1wbGVQcm9ncmFtSW5mbyA9XG4gICAgKGluZmVyZW5jZUhhbmRsZXI6IFdlYkdMSW5mZXJlbmNlSGFuZGxlciwgaW5wdXRzOiBUZW5zb3JbXSwgYXR0cmlidXRlczogVXBzYW1wbGVBdHRyaWJ1dGVzKTogUHJvZ3JhbUluZm8gPT4ge1xuICAgICAgY29uc3QgZ2xzbCA9IGdldEdsc2woaW5mZXJlbmNlSGFuZGxlci5zZXNzaW9uLmJhY2tlbmQuZ2xDb250ZXh0LnZlcnNpb24pO1xuICAgICAgY29uc3QgW2lucHV0V2lkdGgsIGlucHV0SGVpZ2h0XSA9XG4gICAgICAgICAgaW5mZXJlbmNlSGFuZGxlci5jYWxjdWxhdGVUZXh0dXJlV2lkdGhBbmRIZWlnaHQoaW5wdXRzWzBdLmRpbXMsIFRleHR1cmVUeXBlLnVucGFja2VkKTtcblxuICAgICAgY29uc3Qgb3V0cHV0U2hhcGUgPSBpbnB1dHNbMF0uZGltcy5tYXAoKGRpbSwgaSkgPT4gTWF0aC5mbG9vcihkaW0gKiBhdHRyaWJ1dGVzLnNjYWxlc1tpXSkpO1xuICAgICAgY29uc3QgW291dHB1dFdpZHRoLCBvdXRwdXRIZWlnaHRdID1cbiAgICAgICAgICBpbmZlcmVuY2VIYW5kbGVyLmNhbGN1bGF0ZVRleHR1cmVXaWR0aEFuZEhlaWdodChvdXRwdXRTaGFwZSwgVGV4dHVyZVR5cGUudW5wYWNrZWQpO1xuICAgICAgY29uc3QgZGltID0gb3V0cHV0U2hhcGUubGVuZ3RoO1xuXG4gICAgICBjb25zdCBvdXRwdXRQaXRjaGVzID0gbmV3IEFycmF5PG51bWJlcj4oZGltKTtcbiAgICAgIGNvbnN0IGlucHV0UGl0Y2hlcyA9IG5ldyBBcnJheTxudW1iZXI+KGRpbSk7XG4gICAgICBsZXQgcHJlY2FsY3VsYXRlZFBpdGNoZXMgPSBgXG4gICAgICBpbnQgb3V0cHV0X3BpdGNoZXNbJHtkaW19XTtcbiAgICAgIGludCBpbnB1dF9waXRjaGVzWyR7ZGltfV07XG4gICAgICBgO1xuICAgICAgZm9yIChsZXQgZCA9IGRpbSAtIDE7IGQgPj0gMDsgZC0tKSB7XG4gICAgICAgIG91dHB1dFBpdGNoZXNbZF0gPSAoZCA9PT0gZGltIC0gMSkgPyAxIDogb3V0cHV0UGl0Y2hlc1tkICsgMV0gKiBvdXRwdXRTaGFwZVtkICsgMV07XG4gICAgICAgIGlucHV0UGl0Y2hlc1tkXSA9IChkID09PSBkaW0gLSAxKSA/IDEgOiBpbnB1dFBpdGNoZXNbZCArIDFdICogaW5wdXRzWzBdLmRpbXNbZCArIDFdO1xuXG4gICAgICAgIHByZWNhbGN1bGF0ZWRQaXRjaGVzICs9IGBcbiAgICAgICAgb3V0cHV0X3BpdGNoZXNbJHtkfV0gPSAke291dHB1dFBpdGNoZXNbZF19O1xuICAgICAgICBpbnB1dF9waXRjaGVzWyR7ZH1dID0gJHtpbnB1dFBpdGNoZXNbZF19O1xuICAgICAgICBgO1xuICAgICAgfVxuICAgICAgY29uc3QgZ2V0SW5wdXRGbG9hdEZ1bmN0aW9uID0gYFxuICAgICAgZmxvYXQgZ2V0SW5wdXRGbG9hdChpbnQgaW5kZXgpIHtcbiAgICAgICAgdmVjMiBjb29yZHMgPSBvZmZzZXRUb0Nvb3JkcyhpbmRleCwgJHtpbnB1dFdpZHRofSwgJHtpbnB1dEhlaWdodH0pO1xuICAgICAgICBmbG9hdCB2YWx1ZSA9IGdldENvbG9yQXNGbG9hdCgke2dsc2wudGV4dHVyZTJEfShYLCBjb29yZHMpKTtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgfVxuICAgICAgYDtcblxuICAgICAgY29uc3Qgc2hhZGVyU291cmNlID0gYXR0cmlidXRlcy5tb2RlID09PSAnbmVhcmVzdCcgP1xuICAgICAgICAgIC8vIG5lYXJlc3RcbiAgICAgICAgICBgXG4gICAgJHtnZXRJbnB1dEZsb2F0RnVuY3Rpb259XG4gICAgZmxvYXQgcHJvY2VzcyhpbnQgaW5kaWNlc1ske2RpbX1dKSB7XG4gICAgICBpbnQgaW5wdXRfaW5kZXggPSAwO1xuICAgICAgaW50IG91dHB1dF9pbmRleCA9IGNvb3Jkc1RvT2Zmc2V0KFRleENvb3JkcywgJHtvdXRwdXRXaWR0aH0sICR7b3V0cHV0SGVpZ2h0fSk7XG5cbiAgICAgICR7cHJlY2FsY3VsYXRlZFBpdGNoZXN9XG5cbiAgICAgIGludCBkLCBtO1xuICAgICAgZm9yIChpbnQgZGltID0gMDsgZGltIDwgJHtkaW19OyArK2RpbSkge1xuICAgICAgICBkID0gb3V0cHV0X2luZGV4IC8gb3V0cHV0X3BpdGNoZXNbZGltXTtcbiAgICAgICAgbSA9IG91dHB1dF9pbmRleCAtIGQgKiBvdXRwdXRfcGl0Y2hlc1tkaW1dO1xuICAgICAgICBvdXRwdXRfaW5kZXggPSBtO1xuXG4gICAgICAgIGlmIChzY2FsZXNbZGltXSAhPSAxICYmIGQgPiAwKSB7XG4gICAgICAgICAgaW50IGQyID0gZCAvIHNjYWxlc1tkaW1dO1xuICAgICAgICAgIG0gPSBkIC0gZDIgKiBzY2FsZXNbZGltXTtcbiAgICAgICAgICBkID0gZDI7XG4gICAgICAgIH1cbiAgICAgICAgaW5wdXRfaW5kZXggKz0gaW5wdXRfcGl0Y2hlc1tkaW1dICogZDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGdldElucHV0RmxvYXQoaW5wdXRfaW5kZXgpO1xuICAgIH1gIDpcbiAgICAgICAgICBkaW0gPT09IDQgP1xuICAgICAgICAgIC8vIGJpbGluZWFyIDREXG4gICAgICAgICAgICAgIGBcbiAgICAke2dldElucHV0RmxvYXRGdW5jdGlvbn1cbiAgICBmbG9hdCBwcm9jZXNzKGludCBpbmRpY2VzWzRdKSB7XG4gICAgICBpbnQgaW5wdXRfaW5kZXggPSAwO1xuICAgICAgaW50IG91dHB1dF9pbmRleCA9IGNvb3Jkc1RvT2Zmc2V0KFRleENvb3JkcywgJHtvdXRwdXRXaWR0aH0sICR7b3V0cHV0SGVpZ2h0fSk7XG5cbiAgICAgICR7cHJlY2FsY3VsYXRlZFBpdGNoZXN9XG5cbiAgICAgIGludCBtO1xuICAgICAgaW50IGluZGV4X29mX2RpbTAsIGluZGV4X29mX2RpbTEsIGluZGV4X29mX2RpbTIsIGluZGV4X29mX2RpbTM7XG4gICAgICBpbmRleF9vZl9kaW0wID0gb3V0cHV0X2luZGV4IC8gb3V0cHV0X3BpdGNoZXNbMF07XG4gICAgICBtID0gb3V0cHV0X2luZGV4IC0gaW5kZXhfb2ZfZGltMCAqIG91dHB1dF9waXRjaGVzWzBdO1xuICAgICAgaW5kZXhfb2ZfZGltMSA9IG0gLyBvdXRwdXRfcGl0Y2hlc1sxXTtcbiAgICAgIG0gPSBtIC0gaW5kZXhfb2ZfZGltMSAqIG91dHB1dF9waXRjaGVzWzFdO1xuICAgICAgaW5kZXhfb2ZfZGltMiA9IG0gLyBvdXRwdXRfcGl0Y2hlc1syXTtcbiAgICAgIG0gPSBtIC0gaW5kZXhfb2ZfZGltMiAqIG91dHB1dF9waXRjaGVzWzJdO1xuICAgICAgaW5kZXhfb2ZfZGltMyA9IG07XG5cbiAgICAgIGludCBpbmRleF9vZl9pbnB1dF9kaW0yLCBpbmRleF9vZl9pbnB1dF9kaW0zLCB4X29mZnNldCwgeV9vZmZzZXQ7XG4gICAgICBpbmRleF9vZl9pbnB1dF9kaW0yID0gaW5kZXhfb2ZfZGltMiAvIHNjYWxlc1syXTtcbiAgICAgIHlfb2Zmc2V0ID0gaW5kZXhfb2ZfZGltMiAtIGluZGV4X29mX2lucHV0X2RpbTIgKiBzY2FsZXNbMl07XG4gICAgICBpbmRleF9vZl9pbnB1dF9kaW0zID0gaW5kZXhfb2ZfZGltMyAvIHNjYWxlc1szXTtcbiAgICAgIHhfb2Zmc2V0ID0gaW5kZXhfb2ZfZGltMyAtIGluZGV4X29mX2lucHV0X2RpbTMgKiBzY2FsZXNbM107XG5cbiAgICAgIGlucHV0X2luZGV4ID0gaW5kZXhfb2ZfZGltMCAqIGlucHV0X3BpdGNoZXNbMF0gK1xuICAgICAgICAgICAgaW5kZXhfb2ZfZGltMSAqIGlucHV0X3BpdGNoZXNbMV0gK1xuICAgICAgICAgICAgaW5kZXhfb2ZfaW5wdXRfZGltMiAqIGlucHV0X3BpdGNoZXNbMl0gK1xuICAgICAgICAgICAgaW5kZXhfb2ZfaW5wdXRfZGltMztcblxuICAgICAgZmxvYXQgeDAwID0gZ2V0SW5wdXRGbG9hdChpbnB1dF9pbmRleCk7XG4gICAgICBmbG9hdCB4MTAsIHgwMSwgeDExO1xuXG4gICAgICBib29sIGVuZF9vZl9kaW0yID0gZmFsc2U7XG4gICAgICBpZiAoaW5kZXhfb2ZfaW5wdXRfZGltMiA9PSAoJHtpbnB1dHNbMF0uZGltc1syXX0gLSAxKSkge1xuICAgICAgICAvLyBJdCdzIHRoZSBlbmQgaW4gZGltZW5zaW9uIDJcbiAgICAgICAgeDAxID0geDAwO1xuICAgICAgICBlbmRfb2ZfZGltMiA9IHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB4MDEgPSBnZXRJbnB1dEZsb2F0KGlucHV0X2luZGV4ICsgaW5wdXRfcGl0Y2hlc1syXSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChpbmRleF9vZl9pbnB1dF9kaW0zID09IChpbnB1dF9waXRjaGVzWzJdIC0gMSkpIHtcbiAgICAgICAgLy8gSXQncyB0aGUgZW5kIGluIGRpbWVuc2lvbiAzXG4gICAgICAgIHgxMCA9IHgwMDtcbiAgICAgICAgeDExID0geDAxO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIHgxMCA9IGdldElucHV0RmxvYXQoaW5wdXRfaW5kZXggKyAxKTtcbiAgICAgICAgeDExID0gZW5kX29mX2RpbTIgPyB4MTAgOiBnZXRJbnB1dEZsb2F0KGlucHV0X2luZGV4ICsgaW5wdXRfcGl0Y2hlc1syXSArIDEpO1xuICAgICAgfVxuXG4gICAgICBmbG9hdCB5MCA9IHgwMCArIGZsb2F0KHlfb2Zmc2V0KSAqICh4MDEgLSB4MDApIC8gZmxvYXQoc2NhbGVzWzJdKTtcbiAgICAgIGZsb2F0IHkxID0geDEwICsgZmxvYXQoeV9vZmZzZXQpICogKHgxMSAtIHgxMCkgLyBmbG9hdChzY2FsZXNbMl0pO1xuICAgICAgcmV0dXJuIHkwICsgZmxvYXQoeF9vZmZzZXQpICogKHkxIC0geTApIC8gZmxvYXQoc2NhbGVzWzNdKTtcbiAgICB9YCA6XG4gICAgICAgICAgICAgIC8vIGJpbGluZWFyIDJEXG4gICAgICAgICAgICAgIGBcbiAgICAke2dldElucHV0RmxvYXRGdW5jdGlvbn1cbiAgICBmbG9hdCBwcm9jZXNzKGludCBpbmRpY2VzWzJdKSB7XG4gICAgICBpbnQgaW5wdXRfaW5kZXggPSAwO1xuICAgICAgaW50IG91dHB1dF9pbmRleCA9IGNvb3Jkc1RvT2Zmc2V0KFRleENvb3JkcywgJHtvdXRwdXRXaWR0aH0sICR7b3V0cHV0SGVpZ2h0fSk7XG5cbiAgICAgICR7cHJlY2FsY3VsYXRlZFBpdGNoZXN9XG5cbiAgICAgIGludCBtO1xuICAgICAgaW50IGluZGV4X29mX2RpbTAsIGluZGV4X29mX2RpbTE7XG4gICAgICBpbmRleF9vZl9kaW0wID0gb3V0cHV0X2luZGV4IC8gb3V0cHV0X3BpdGNoZXNbMF07XG4gICAgICBtID0gb3V0cHV0X2luZGV4IC0gaW5kZXhfb2ZfZGltMCAqIG91dHB1dF9waXRjaGVzWzBdO1xuICAgICAgaW5kZXhfb2ZfZGltMSA9IG07XG5cbiAgICAgIGludCBpbmRleF9vZl9pbnB1dF9kaW0wLCBpbmRleF9vZl9pbnB1dF9kaW0xLCB4X29mZnNldCwgeV9vZmZzZXQ7XG4gICAgICBpbmRleF9vZl9pbnB1dF9kaW0wID0gaW5kZXhfb2ZfZGltMCAvIHNjYWxlc1swXTtcbiAgICAgIHlfb2Zmc2V0ID0gaW5kZXhfb2ZfZGltMCAtIGluZGV4X29mX2lucHV0X2RpbTAgKiBzY2FsZXNbMF07XG4gICAgICBpbmRleF9vZl9pbnB1dF9kaW0xID0gaW5kZXhfb2ZfZGltMSAvIHNjYWxlc1sxXTtcbiAgICAgIHhfb2Zmc2V0ID0gaW5kZXhfb2ZfZGltMSAtIGluZGV4X29mX2lucHV0X2RpbTEgKiBzY2FsZXNbMV07XG5cbiAgICAgIGlucHV0X2luZGV4ID0gaW5kZXhfb2ZfaW5wdXRfZGltMCAqIGlucHV0X3BpdGNoZXNbMF0gKyBpbmRleF9vZl9pbnB1dF9kaW0xO1xuXG4gICAgICBmbG9hdCB4MDAgPSBnZXRJbnB1dEZsb2F0KGlucHV0X2luZGV4KTtcbiAgICAgIGZsb2F0IHgxMCwgeDAxLCB4MTE7XG5cbiAgICAgIGJvb2wgZW5kX29mX2RpbTAgPSBmYWxzZTtcbiAgICAgIGlmIChpbmRleF9vZl9pbnB1dF9kaW0wID09ICgke2lucHV0c1swXS5kaW1zWzBdfSAtIDEpKSB7XG4gICAgICAgIC8vIEl0J3MgdGhlIGVuZCBpbiBkaW1lbnNpb24gMFxuICAgICAgICB4MDEgPSB4MDA7XG4gICAgICAgIGVuZF9vZl9kaW0wID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHgwMSA9IGdldElucHV0RmxvYXQoaW5wdXRfaW5kZXggKyBpbnB1dF9waXRjaGVzWzBdKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGluZGV4X29mX2lucHV0X2RpbTEgPT0gKGlucHV0X3BpdGNoZXNbMF0gLSAxKSkge1xuICAgICAgICAvLyBJdCdzIHRoZSBlbmQgaW4gZGltZW5zaW9uIDFcbiAgICAgICAgeDEwID0geDAwO1xuICAgICAgICB4MTEgPSB4MDE7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgeDEwID0gZ2V0SW5wdXRGbG9hdChpbnB1dF9pbmRleCArIDEpO1xuICAgICAgICB4MTEgPSBlbmRfb2ZfZGltMCA/IHgxMCA6IGdldElucHV0RmxvYXQoaW5wdXRfaW5kZXggKyBpbnB1dF9waXRjaGVzWzBdICsgMSk7XG4gICAgICB9XG5cbiAgICAgIGZsb2F0IHkwID0geDAwICsgZmxvYXQoeV9vZmZzZXQpICogKHgwMSAtIHgwMCkgLyBmbG9hdChzY2FsZXNbMF0pO1xuICAgICAgZmxvYXQgeTEgPSB4MTAgKyBmbG9hdCh5X29mZnNldCkgKiAoeDExIC0geDEwKSAvIGZsb2F0KHNjYWxlc1swXSk7XG4gICAgICByZXR1cm4geTAgKyBmbG9hdCh4X29mZnNldCkgKiAoeTEgLSB5MCkgLyBmbG9hdChzY2FsZXNbMV0pO1xuICAgIH1gO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4udXBzYW1wbGVQcm9ncmFtTWV0YWRhdGEsXG4gICAgICAgIG91dHB1dDoge2RpbXM6IG91dHB1dFNoYXBlLCB0eXBlOiBpbnB1dHNbMF0udHlwZSwgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlLnVucGFja2VkfSxcbiAgICAgICAgc2hhZGVyU291cmNlLFxuICAgICAgICB2YXJpYWJsZXM6IFt7XG4gICAgICAgICAgbmFtZTogJ3NjYWxlcycsXG4gICAgICAgICAgdHlwZTogJ2ludCcsXG4gICAgICAgICAgYXJyYXlMZW5ndGg6IGF0dHJpYnV0ZXMuc2NhbGVzLmxlbmd0aCxcbiAgICAgICAgICBkYXRhOiBhdHRyaWJ1dGVzLnNjYWxlcy5tYXAoeCA9PiBNYXRoLmNlaWwoeCkpXG4gICAgICAgIH1dXG4gICAgICB9O1xuICAgIH07XG5cbmV4cG9ydCBjb25zdCB2YWxpZGF0ZUlucHV0cyA9IChpbnB1dHM6IFRlbnNvcltdLCBhdHRyaWJ1dGU6IFVwc2FtcGxlQXR0cmlidXRlcyk6IHZvaWQgPT4ge1xuICBpZiAoIWlucHV0cyB8fCAoYXR0cmlidXRlLm9wc2V0IDwgOSAmJiBpbnB1dHMubGVuZ3RoICE9PSAxKSB8fFxuICAgICAgKGF0dHJpYnV0ZS5vcHNldCA+PSA5ICYmIGF0dHJpYnV0ZS5vcHNldCA8IDExICYmIGlucHV0cy5sZW5ndGggIT09IDIpIHx8XG4gICAgICAoYXR0cmlidXRlLm9wc2V0ID49IDExICYmIGlucHV0cy5sZW5ndGggPCAyKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBpbnB1dHMuJyk7XG4gIH1cblxuICBpZiAoYXR0cmlidXRlLnNjYWxlcy5sZW5ndGggPiAwICYmIGlucHV0c1swXS5kaW1zLmxlbmd0aCAhPT0gYXR0cmlidXRlLnNjYWxlcy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW5wdXQgc2hhcGUuJyk7XG4gIH1cblxuICBpZiAoaW5wdXRzWzBdLnR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGlucHV0IHRlbnNvciB0eXBlcy4nKTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IHNjYWxlc1ZhbGlkYXRpb24gPSAoc2NhbGVzOiBudW1iZXJbXSwgbW9kZTogc3RyaW5nLCBpc1Jlc2l6ZTogYm9vbGVhbik6IHZvaWQgPT4ge1xuICBpZiAoIWlzUmVzaXplKSB7XG4gICAgZm9yIChjb25zdCBzY2FsZSBvZiBzY2FsZXMpIHtcbiAgICAgIGlmIChzY2FsZSA8IDEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdTY2FsZSB2YWx1ZSBzaG91bGQgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDEuJyk7XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGZvciAoY29uc3Qgc2NhbGUgb2Ygc2NhbGVzKSB7XG4gICAgICBpZiAoc2NhbGUgPD0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NjYWxlIHZhbHVlIHNob3VsZCBiZSBncmVhdGVyIHRoYW4gMC4nKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgaWYgKG1vZGUgPT09ICdsaW5lYXInIHx8IG1vZGUgPT09ICdjdWJpYycpIHtcbiAgICBpZiAoc2NhbGVzLmxlbmd0aCAhPT0gMiAmJiAoc2NhbGVzLmxlbmd0aCAhPT0gNCB8fCBzY2FsZXNbMF0gIT09IDEgfHwgc2NhbGVzWzFdICE9PSAxKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGAnTGluZWFyJyBtb2RlIGFuZCAnQ3ViaWMnIG1vZGUgb25seSBzdXBwb3J0IDItRCBpbnB1dHMgKCdCaWxpbmVhcicsICdCaWN1YmljJykgXFxcbiAgICAgICAgb3IgNC1EIGlucHV0cyB3aXRoIHRoZSBjb3JyZXNwb25kaW5nIG91dGVybW9zdCAyIHNjYWxlIHZhbHVlcyBiZWluZyAxIFxcXG4gICAgICAgIGluIHRoZSAke2lzUmVzaXplID8gJ1Jlc2l6ZScgOiAnVXBzYW1wbGUnfSBvcGVhcnRvci5gKTtcbiAgICB9XG4gIH1cbn07IiwiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7ZW52fSBmcm9tICdvbm54cnVudGltZS1jb21tb24nO1xuXG5pbXBvcnQge0xvZ2dlciwgUHJvZmlsZXJ9IGZyb20gJy4uLy4uL2luc3RydW1lbnQnO1xuXG5pbXBvcnQge0dsc2xQcmVwcm9jZXNzb3J9IGZyb20gJy4vZ2xzbC1wcmVwcm9jZXNzb3InO1xuaW1wb3J0IHtnZXRWZXJ0ZXhTaGFkZXJTb3VyY2V9IGZyb20gJy4vZ2xzbC1zb3VyY2UnO1xuaW1wb3J0IHtUZXh0dXJlTGF5b3V0U3RyYXRlZ3l9IGZyb20gJy4vdGV4dHVyZS1sYXlvdXQtc3RyYXRlZ3knO1xuaW1wb3J0IHtBcnRpZmFjdCwgUHJvZ3JhbUluZm8sIFByb2dyYW1WYXJpYWJsZSwgVGV4dHVyZURhdGEsIFRleHR1cmVMYXlvdXQsIFZhcmlhYmxlSW5mb30gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQge1dlYkdMQ29udGV4dH0gZnJvbSAnLi93ZWJnbC1jb250ZXh0JztcblxuLyoqXG4gKiBQcm9ncmFtTWFuYWdlciBpcyB0aGUgbWFpbiBjbGFzcyBiZWhpbmQgcnVubmluZyBjb21wdXRhdGlvbnNcbiAqIEl0IGJ1aWxkcyBQcm9ncmFtSW5mbydzIGludG8gQXJ0aWZhY3RzXG4gKiBJdCBjb21waWxlcyBnaXZlbiBQcm9ncmFtSW5mbydzIGludG8gV2ViR0wgUHJvcmFtcyAoY2FjaGVkIGFzIEFydGlmYWN0cylcbiAqIFVzZXMgdGhlIGFydGlmYWN0IHRvIHJ1biB0aGUgY29tcHV0YXRpb24gYnkgY2FsbGluZyBEcmF3IG9uXG4gKiB0aGUgV2ViR0wgZHJhd2luZyBidWZmZXJcbiAqIFByb2dyYW1NYW5hZ2VyIGF1dG9tYXRpY2FsbHkgbWFwcyAoYmluZHMpIGlucHV0IHZhcmlhYmxlcyB0byB0aGVpclxuICogY29ycmVzcG9uZGluZyBMb2NhdGlvbidzIGluIHRoZSBiaW5hcnkgcHJvZ3JhbVxuICovXG5leHBvcnQgY2xhc3MgUHJvZ3JhbU1hbmFnZXIge1xuICByZXBvOiBNYXA8dW5rbm93biwgQXJ0aWZhY3Q+OyAgLy8gdGhpcyBzaG91bGQgYmUgcGVyLXNlc3Npb24gb2JqZWN0XG4gIHZlcnRleFNoYWRlcjogV2ViR0xTaGFkZXI7XG4gIGF0dHJpYnV0ZXNCb3VuZDogYm9vbGVhbjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICAgIHB1YmxpYyBwcm9maWxlcjogUmVhZG9ubHk8UHJvZmlsZXI+LCBwdWJsaWMgZ2xDb250ZXh0OiBXZWJHTENvbnRleHQsXG4gICAgICBwdWJsaWMgdGV4dHVyZUxheW91dFN0cmF0ZWd5OiBUZXh0dXJlTGF5b3V0U3RyYXRlZ3kpIHtcbiAgICB0aGlzLnJlcG8gPSBuZXcgTWFwKCk7XG4gICAgdGhpcy5hdHRyaWJ1dGVzQm91bmQgPSBmYWxzZTtcbiAgfVxuICBnZXRBcnRpZmFjdChrZXk6IHVua25vd24pOiBBcnRpZmFjdHx1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLnJlcG8uZ2V0KGtleSk7XG4gIH1cbiAgc2V0QXJ0aWZhY3Qoa2V5OiB1bmtub3duLCBhcnRpZmFjdDogQXJ0aWZhY3QpOiB2b2lkIHtcbiAgICB0aGlzLnJlcG8uc2V0KGtleSwgYXJ0aWZhY3QpO1xuICB9XG4gIHJ1bihidWlsZEFydGlmYWN0OiBBcnRpZmFjdCwgaW5wdXRzOiBUZXh0dXJlRGF0YVtdLCBvdXRwdXQ6IFRleHR1cmVEYXRhKTogdm9pZCB7XG4gICAgdGhpcy5wcm9maWxlci5ldmVudCgnb3AnLCBgUHJvZ3JhbU1hbmFnZXIucnVuICR7YnVpbGRBcnRpZmFjdC5wcm9ncmFtSW5mby5uYW1lID8/ICd1bmtub3duIGtlcm5lbCd9YCwgKCkgPT4ge1xuICAgICAgY29uc3QgZ2wgPSB0aGlzLmdsQ29udGV4dC5nbDtcbiAgICAgIGNvbnN0IHByb2dyYW0gPSBidWlsZEFydGlmYWN0LnByb2dyYW07XG4gICAgICBnbC51c2VQcm9ncmFtKHByb2dyYW0pO1xuICAgICAgdHJ5IHtcbiAgICAgICAgdGhpcy5iaW5kT3V0cHV0KG91dHB1dCk7XG4gICAgICAgIGlmICghdGhpcy5hdHRyaWJ1dGVzQm91bmQpIHtcbiAgICAgICAgICB0aGlzLmJpbmRBdHRyaWJ1dGVzKGJ1aWxkQXJ0aWZhY3QuYXR0cmliTG9jYXRpb25zKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmJpbmRVbmlmb3JtcyhidWlsZEFydGlmYWN0LnVuaWZvcm1Mb2NhdGlvbnMsIGJ1aWxkQXJ0aWZhY3QucHJvZ3JhbUluZm8udmFyaWFibGVzID8/IFtdLCBpbnB1dHMpO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIExvZ2dlci5lcnJvcignUHJvZ3JhbU1hbmFnZXInLCBidWlsZEFydGlmYWN0LnByb2dyYW1JbmZvLnNoYWRlclNvdXJjZSk7XG4gICAgICAgIHRocm93IGVycjtcbiAgICAgIH1cbiAgICAgIHRoaXMucHJvZmlsZXIuZXZlbnQoJ2JhY2tlbmQnLCAnR2xDb250ZXh0LmRyYXcoKScsICgpID0+IHtcbiAgICAgICAgdGhpcy5nbENvbnRleHQuZHJhdygpO1xuICAgICAgfSk7XG4gICAgfSwgdGhpcy5nbENvbnRleHQpO1xuICB9XG4gIGRpc3Bvc2UoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMudmVydGV4U2hhZGVyKSB7XG4gICAgICB0aGlzLmdsQ29udGV4dC5kZWxldGVTaGFkZXIodGhpcy52ZXJ0ZXhTaGFkZXIpO1xuICAgIH1cbiAgICB0aGlzLnJlcG8uZm9yRWFjaChhID0+IHRoaXMuZ2xDb250ZXh0LmRlbGV0ZVByb2dyYW0oYS5wcm9ncmFtKSk7XG4gIH1cbiAgYnVpbGQocHJvZ3JhbUluZm86IFByb2dyYW1JbmZvLCBpbnB1dFRleHR1cmVMYXlvdXRzOiBUZXh0dXJlTGF5b3V0W10sIG91dHB1dFRleHR1cmVMYXlvdXQ6IFRleHR1cmVMYXlvdXQpOiBBcnRpZmFjdCB7XG4gICAgcmV0dXJuIHRoaXMucHJvZmlsZXIuZXZlbnQoJ2JhY2tlbmQnLCAnUHJvZ3JhbU1hbmFnZXIuYnVpbGQnLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcmVwcm9jZXNzb3IgPSBuZXcgR2xzbFByZXByb2Nlc3Nvcih0aGlzLmdsQ29udGV4dCwgcHJvZ3JhbUluZm8sIGlucHV0VGV4dHVyZUxheW91dHMsIG91dHB1dFRleHR1cmVMYXlvdXQpO1xuICAgICAgY29uc3QgZnJhZ1NjcmlwdCA9IHByZXByb2Nlc3Nvci5wcmVwcm9jZXNzKCk7XG4gICAgICBjb25zdCBwcm9ncmFtID0gdGhpcy5jb21waWxlKGZyYWdTY3JpcHQpO1xuICAgICAgY29uc3QgYXJ0aWZhY3QgPSB7XG4gICAgICAgIHByb2dyYW1JbmZvLFxuICAgICAgICBwcm9ncmFtLFxuICAgICAgICB1bmlmb3JtTG9jYXRpb25zOiB0aGlzLmdldFVuaWZvcm1Mb2NhdGlvbnMoXG4gICAgICAgICAgICBwcm9ncmFtLCBwcmVwcm9jZXNzb3IuY29udGV4dC5wcm9ncmFtSW5mby5pbnB1dE5hbWVzLCBwcmVwcm9jZXNzb3IuY29udGV4dC5wcm9ncmFtSW5mby52YXJpYWJsZXMpLFxuICAgICAgICBhdHRyaWJMb2NhdGlvbnM6IHRoaXMuZ2V0QXR0cmliTG9jYXRpb25zKHByb2dyYW0pXG4gICAgICB9O1xuICAgICAgcmV0dXJuIGFydGlmYWN0O1xuICAgIH0pO1xuICB9XG4gIHByb3RlY3RlZCBjb21waWxlKGZyYWdTaGFkZXJTY3JpcHQ6IHN0cmluZyk6IFdlYkdMUHJvZ3JhbSB7XG4gICAgaWYgKCF0aGlzLnZlcnRleFNoYWRlcikge1xuICAgICAgTG9nZ2VyLnZlcmJvc2UoJ1Byb3JncmFtTWFuYWdlcicsICdDb21waWxpbmcgYW5kIGNhY2hpbmcgVmVydGV4IHNoYWRlciBmb3IgdGhlIGZpcnN0IHRpbWUnKTtcbiAgICAgIGNvbnN0IHZlcnRleFNoYWRlclNjcmlwdCA9IGdldFZlcnRleFNoYWRlclNvdXJjZSh0aGlzLmdsQ29udGV4dC52ZXJzaW9uKTtcbiAgICAgIHRoaXMudmVydGV4U2hhZGVyID0gdGhpcy5nbENvbnRleHQuY29tcGlsZVNoYWRlcih2ZXJ0ZXhTaGFkZXJTY3JpcHQsIHRoaXMuZ2xDb250ZXh0LmdsLlZFUlRFWF9TSEFERVIpO1xuICAgIH1cbiAgICBpZiAoZW52LmRlYnVnKSB7XG4gICAgICBMb2dnZXIudmVyYm9zZSgnUHJvcmdyYW1NYW5hZ2VyJywgYEZyYWdTaGFkZXI6XG4ke2ZyYWdTaGFkZXJTY3JpcHR9XG5gKTtcbiAgICB9XG4gICAgY29uc3QgZnJhZ1NoYWRlciA9IHRoaXMuZ2xDb250ZXh0LmNvbXBpbGVTaGFkZXIoZnJhZ1NoYWRlclNjcmlwdCwgdGhpcy5nbENvbnRleHQuZ2wuRlJBR01FTlRfU0hBREVSKTtcbiAgICBjb25zdCBwcm9ncmFtID0gdGhpcy5nbENvbnRleHQuY3JlYXRlUHJvZ3JhbSh0aGlzLnZlcnRleFNoYWRlciwgZnJhZ1NoYWRlcik7XG4gICAgdGhpcy5nbENvbnRleHQuZGVsZXRlU2hhZGVyKGZyYWdTaGFkZXIpO1xuICAgIHJldHVybiBwcm9ncmFtO1xuICB9XG4gIGJpbmRPdXRwdXQodGQ6IFRleHR1cmVEYXRhKTogdm9pZCB7XG4gICAgY29uc3Qgd2lkdGggPSB0ZC53aWR0aDtcbiAgICBjb25zdCBoZWlnaHQgPSB0ZC5oZWlnaHQ7XG4gICAgTG9nZ2VyLnZlcmJvc2UoXG4gICAgICAgICdQcm9yZ3JhbU1hbmFnZXInLFxuICAgICAgICBgQmluZGluZyBvdXRwdXQgdGV4dHVyZSB0byBGcmFtZWJ1ZmZlcjogdy9oPSR7d2lkdGh9LyR7aGVpZ2h0fSwgc2hhcGU9JHt0ZC5zaGFwZX0sIHR5cGU9JHt0ZC50ZW5zb3IudHlwZX1gKTtcbiAgICB0aGlzLmdsQ29udGV4dC5hdHRhY2hGcmFtZWJ1ZmZlcih0ZC50ZXh0dXJlLCB3aWR0aCwgaGVpZ2h0KTtcbiAgfVxuICBiaW5kQXR0cmlidXRlcyhhdHRyaWJMb2NhdGlvbnM6IEFydGlmYWN0LkF0dHJpYkxvY2F0aW9ucyk6IHZvaWQge1xuICAgIGNvbnN0IHBvc2l0aW9uSGFuZGxlID0gYXR0cmliTG9jYXRpb25zLnBvc2l0aW9uO1xuICAgIGNvbnN0IHRleHR1cmVDb29yZEhhbmRsZSA9IGF0dHJpYkxvY2F0aW9ucy50ZXh0dXJlQ29vcmQ7XG4gICAgdGhpcy5nbENvbnRleHQuc2V0VmVydGV4QXR0cmlidXRlcyhwb3NpdGlvbkhhbmRsZSwgdGV4dHVyZUNvb3JkSGFuZGxlKTtcbiAgICB0aGlzLmF0dHJpYnV0ZXNCb3VuZCA9IHRydWU7XG4gIH1cbiAgYmluZFVuaWZvcm1zKHVuaWZvcm1Mb2NhdGlvbnM6IEFydGlmYWN0LlVuaWZvcm1Mb2NhdGlvbnMsIHZhcmlhYmxlczogUHJvZ3JhbVZhcmlhYmxlW10sIHRleHR1cmVzOiBUZXh0dXJlRGF0YVtdKTpcbiAgICAgIHZvaWQge1xuICAgIGNvbnN0IGdsID0gdGhpcy5nbENvbnRleHQuZ2w7XG4gICAgbGV0IHRleHR1cmVQb3NpdGlvbiA9IDA7XG4gICAgZm9yIChjb25zdCB7bmFtZSwgdHlwZSwgbG9jYXRpb24sIGFycmF5TGVuZ3RofSBvZiB1bmlmb3JtTG9jYXRpb25zKSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IHZhcmlhYmxlcy5maW5kKHYgPT4gdi5uYW1lID09PSBuYW1lKT8uZGF0YTtcbiAgICAgIGlmICh0eXBlICE9PSAnc2FtcGxlcjJEJyAmJiAhdmFsdWUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB2YXJpYWJsZSAnJHtuYW1lfScgZG9lcyBub3QgaGF2ZSBkYXRhIGRlZmluZWQgaW4gcHJvZ3JhbSBpbmZvYCk7XG4gICAgICB9XG4gICAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgICAgY2FzZSAnc2FtcGxlcjJEJzpcbiAgICAgICAgICB0aGlzLmJpbmRUZXh0dXJlKHRleHR1cmVzW3RleHR1cmVQb3NpdGlvbl0sIGxvY2F0aW9uLCB0ZXh0dXJlUG9zaXRpb24pO1xuICAgICAgICAgIHRleHR1cmVQb3NpdGlvbisrO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdmbG9hdCc6XG4gICAgICAgICAgaWYgKGFycmF5TGVuZ3RoKSB7XG4gICAgICAgICAgICBnbC51bmlmb3JtMWZ2KGxvY2F0aW9uLCB2YWx1ZSBhcyBudW1iZXJbXSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGdsLnVuaWZvcm0xZihsb2NhdGlvbiwgdmFsdWUgYXMgbnVtYmVyKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ2ludCc6XG4gICAgICAgICAgaWYgKGFycmF5TGVuZ3RoKSB7XG4gICAgICAgICAgICBnbC51bmlmb3JtMWl2KGxvY2F0aW9uLCB2YWx1ZSBhcyBudW1iZXJbXSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGdsLnVuaWZvcm0xaShsb2NhdGlvbiwgdmFsdWUgYXMgbnVtYmVyKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmlmb3JtIG5vdCBpbXBsZW1lbnRlZDogJHt0eXBlfWApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBiaW5kVGV4dHVyZSh0ZDogVGV4dHVyZURhdGEsIHVuaWZvcm1IYW5kbGU6IFdlYkdMVW5pZm9ybUxvY2F0aW9uLCBwb3NpdGlvbjogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5nbENvbnRleHQuYmluZFRleHR1cmVUb1VuaWZvcm0odGQudGV4dHVyZSwgcG9zaXRpb24sIHVuaWZvcm1IYW5kbGUpO1xuICB9XG4gIGdldEF0dHJpYkxvY2F0aW9ucyhwcm9ncmFtOiBXZWJHTFByb2dyYW0pOiBBcnRpZmFjdC5BdHRyaWJMb2NhdGlvbnMge1xuICAgIHJldHVybiB7XG4gICAgICBwb3NpdGlvbjogdGhpcy5nZXRBdHRyaWJMb2NhdGlvbihwcm9ncmFtLCAncG9zaXRpb24nKSxcbiAgICAgIHRleHR1cmVDb29yZDogdGhpcy5nZXRBdHRyaWJMb2NhdGlvbihwcm9ncmFtLCAndGV4dHVyZUNvb3JkJylcbiAgICB9O1xuICB9XG4gIGdldFVuaWZvcm1Mb2NhdGlvbnMocHJvZ3JhbTogV2ViR0xQcm9ncmFtLCBzYW1wbGVycz86IHN0cmluZ1tdLCB2YXJpYWJsZXM/OiBWYXJpYWJsZUluZm9bXSk6XG4gICAgICBBcnRpZmFjdC5Vbmlmb3JtTG9jYXRpb25zIHtcbiAgICBjb25zdCB1bmlmb3JtTG9jYXRpb25zOiBBcnRpZmFjdC5Vbmlmb3JtTG9jYXRpb25zID0gW107XG4gICAgaWYgKHNhbXBsZXJzKSB7XG4gICAgICBmb3IgKGNvbnN0IHNhbXBsZXIgb2Ygc2FtcGxlcnMpIHtcbiAgICAgICAgdW5pZm9ybUxvY2F0aW9ucy5wdXNoKHtuYW1lOiBzYW1wbGVyLCB0eXBlOiAnc2FtcGxlcjJEJywgbG9jYXRpb246IHRoaXMuZ2V0VW5pZm9ybUxvY2F0aW9uKHByb2dyYW0sIHNhbXBsZXIpfSk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICh2YXJpYWJsZXMpIHtcbiAgICAgIGZvciAoY29uc3QgdmFyaWFibGUgb2YgdmFyaWFibGVzKSB7XG4gICAgICAgIHVuaWZvcm1Mb2NhdGlvbnMucHVzaCh7Li4udmFyaWFibGUsIGxvY2F0aW9uOiB0aGlzLmdldFVuaWZvcm1Mb2NhdGlvbihwcm9ncmFtLCB2YXJpYWJsZS5uYW1lKX0pO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdW5pZm9ybUxvY2F0aW9ucztcbiAgfVxuICBnZXRVbmlmb3JtTG9jYXRpb24ocHJvZ3JhbTogV2ViR0xQcm9ncmFtLCBuYW1lOiBzdHJpbmcpOiBXZWJHTFVuaWZvcm1Mb2NhdGlvbiB7XG4gICAgY29uc3QgZ2wgPSB0aGlzLmdsQ29udGV4dC5nbDtcbiAgICBjb25zdCByZWZlcmVuY2UgPSBnbC5nZXRVbmlmb3JtTG9jYXRpb24ocHJvZ3JhbSwgbmFtZSk7XG4gICAgaWYgKHJlZmVyZW5jZSA9PT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmlmb3JtICR7bmFtZX0gbm90IGZvdW5kLmApO1xuICAgIH1cbiAgICByZXR1cm4gcmVmZXJlbmNlO1xuICB9XG4gIGdldEF0dHJpYkxvY2F0aW9uKHByb2dyYW06IFdlYkdMUHJvZ3JhbSwgbmFtZTogc3RyaW5nKTogbnVtYmVyIHtcbiAgICBjb25zdCBnbCA9IHRoaXMuZ2xDb250ZXh0LmdsO1xuICAgIGNvbnN0IGF0dHJpYnV0ZUxvY2F0aW9uOiBudW1iZXIgPSBnbC5nZXRBdHRyaWJMb2NhdGlvbihwcm9ncmFtLCBuYW1lKTtcbiAgICByZXR1cm4gYXR0cmlidXRlTG9jYXRpb247XG4gIH1cbn1cbiIsIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge1Nlc3Npb25IYW5kbGVyfSBmcm9tICcuLi8uLi9iYWNrZW5kJztcbmltcG9ydCB7R3JhcGh9IGZyb20gJy4uLy4uL2dyYXBoJztcbmltcG9ydCB7TG9nZ2VyfSBmcm9tICcuLi8uLi9pbnN0cnVtZW50JztcbmltcG9ydCB7T3BlcmF0b3J9IGZyb20gJy4uLy4uL29wZXJhdG9ycyc7XG5pbXBvcnQge09wU2V0LCByZXNvbHZlT3BlcmF0b3J9IGZyb20gJy4uLy4uL29wc2V0JztcbmltcG9ydCB7U2Vzc2lvbn0gZnJvbSAnLi4vLi4vc2Vzc2lvbic7XG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi4vLi4vdGVuc29yJztcbmltcG9ydCB7V2ViR0xCYWNrZW5kfSBmcm9tICcuLi9iYWNrZW5kLXdlYmdsJztcblxuaW1wb3J0IHtXZWJHTEluZmVyZW5jZUhhbmRsZXJ9IGZyb20gJy4vaW5mZXJlbmNlLWhhbmRsZXInO1xuaW1wb3J0IHtXRUJHTF9PUF9SRVNPTFZFX1JVTEVTfSBmcm9tICcuL29wLXJlc29sdmUtcnVsZXMnO1xuaW1wb3J0IHtQcm9ncmFtTWFuYWdlcn0gZnJvbSAnLi9wcm9ncmFtLW1hbmFnZXInO1xuaW1wb3J0IHtQcmVmZXJMb2dpY2FsU3RyYXRlZ3ksIFRleHR1cmVMYXlvdXRTdHJhdGVneX0gZnJvbSAnLi90ZXh0dXJlLWxheW91dC1zdHJhdGVneSc7XG5pbXBvcnQge1RleHR1cmVNYW5hZ2VyfSBmcm9tICcuL3RleHR1cmUtbWFuYWdlcic7XG5pbXBvcnQge1RleHR1cmVEYXRhfSBmcm9tICcuL3R5cGVzJztcblxuZXhwb3J0IGNsYXNzIFdlYkdMU2Vzc2lvbkhhbmRsZXIgaW1wbGVtZW50cyBTZXNzaW9uSGFuZGxlciB7XG4gIHByb2dyYW1NYW5hZ2VyOiBQcm9ncmFtTWFuYWdlcjtcbiAgdGV4dHVyZU1hbmFnZXI6IFRleHR1cmVNYW5hZ2VyO1xuICBsYXlvdXRTdHJhdGVneTogVGV4dHVyZUxheW91dFN0cmF0ZWd5O1xuICBwYWNrZWRUZXh0dXJlRGF0YUNhY2hlOiBNYXA8VGVuc29yLklkLCBUZXh0dXJlRGF0YT47XG4gIHVucGFja2VkVGV4dHVyZURhdGFDYWNoZTogTWFwPFRlbnNvci5JZCwgVGV4dHVyZURhdGE+O1xuICBwYWNrMnVucGFja01hcDogTWFwPFRlbnNvci5JZCwgVGVuc29yLklkPjtcbiAgdW5wYWNrMnBhY2tNYXA6IE1hcDxUZW5zb3IuSWQsIFRlbnNvci5JZD47XG4gIGluaXRpYWxpemVyczogU2V0PFRlbnNvci5JZD47XG4gIHBhY2s/OiBib29sZWFuO1xuXG4gIGNvbnN0cnVjdG9yKHB1YmxpYyByZWFkb25seSBiYWNrZW5kOiBXZWJHTEJhY2tlbmQsIHB1YmxpYyByZWFkb25seSBjb250ZXh0OiBTZXNzaW9uLkNvbnRleHQpIHtcbiAgICB0aGlzLmxheW91dFN0cmF0ZWd5ID0gbmV3IFByZWZlckxvZ2ljYWxTdHJhdGVneShiYWNrZW5kLmdsQ29udGV4dC5tYXhUZXh0dXJlU2l6ZSk7XG4gICAgdGhpcy5wcm9ncmFtTWFuYWdlciA9IG5ldyBQcm9ncmFtTWFuYWdlcih0aGlzLmNvbnRleHQucHJvZmlsZXIsIGJhY2tlbmQuZ2xDb250ZXh0LCB0aGlzLmxheW91dFN0cmF0ZWd5KTtcbiAgICB0aGlzLnRleHR1cmVNYW5hZ2VyID0gbmV3IFRleHR1cmVNYW5hZ2VyKFxuICAgICAgICBiYWNrZW5kLmdsQ29udGV4dCwgdGhpcy5sYXlvdXRTdHJhdGVneSwgdGhpcy5jb250ZXh0LnByb2ZpbGVyLFxuICAgICAgICB7cmV1c2VUZXh0dXJlczogYmFja2VuZC50ZXh0dXJlQ2FjaGVNb2RlID09PSAnZnVsbCd9KTtcbiAgICB0aGlzLnBhY2tlZFRleHR1cmVEYXRhQ2FjaGUgPSBuZXcgTWFwKCk7XG4gICAgdGhpcy51bnBhY2tlZFRleHR1cmVEYXRhQ2FjaGUgPSBuZXcgTWFwKCk7XG4gICAgdGhpcy5wYWNrID0gYmFja2VuZC5wYWNrO1xuICAgIHRoaXMucGFjazJ1bnBhY2tNYXAgPSBuZXcgTWFwKCk7XG4gICAgdGhpcy51bnBhY2sycGFja01hcCA9IG5ldyBNYXAoKTtcbiAgfVxuXG4gIGNyZWF0ZUluZmVyZW5jZUhhbmRsZXIoKSB7XG4gICAgcmV0dXJuIG5ldyBXZWJHTEluZmVyZW5jZUhhbmRsZXIodGhpcyk7XG4gIH1cbiAgb25HcmFwaEluaXRpYWxpemVkKGdyYXBoOiBHcmFwaCk6IHZvaWQge1xuICAgIGNvbnN0IGluaXRpYWxpemVycyA9IGdyYXBoLmdldFZhbHVlcygpLmZpbHRlcih2ID0+IHYuZnJvbSA9PT0gLTEgJiYgdi50ZW5zb3IpLm1hcCh2ID0+IHYudGVuc29yIS5kYXRhSWQpO1xuICAgIHRoaXMuaW5pdGlhbGl6ZXJzID0gbmV3IFNldChpbml0aWFsaXplcnMpO1xuICB9XG4gIGlzSW5pdGlhbGl6ZXIodGVuc29ySWQ6IFRlbnNvci5JZCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmluaXRpYWxpemVycyA/IHRoaXMuaW5pdGlhbGl6ZXJzLmhhcyh0ZW5zb3JJZCkgOiBmYWxzZTtcbiAgfVxuICBhZGRJbml0aWFsaXplcih0ZW5zb3JJZDogVGVuc29yLklkKTogdm9pZCB7XG4gICAgdGhpcy5pbml0aWFsaXplcnMuYWRkKHRlbnNvcklkKTtcbiAgfVxuICBnZXRUZXh0dXJlRGF0YSh0ZW5zb3JJZDogVGVuc29yLklkLCBpc1BhY2tlZDogYm9vbGVhbik6IFRleHR1cmVEYXRhfHVuZGVmaW5lZCB7XG4gICAgaWYgKGlzUGFja2VkKSB7XG4gICAgICByZXR1cm4gdGhpcy5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlLmdldCh0ZW5zb3JJZCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0aGlzLnVucGFja2VkVGV4dHVyZURhdGFDYWNoZS5nZXQodGVuc29ySWQpO1xuICAgIH1cbiAgfVxuICBzZXRUZXh0dXJlRGF0YSh0ZW5zb3JJZDogVGVuc29yLklkLCB0ZXh0dXJlRGF0YTogVGV4dHVyZURhdGEsIGlzUGFja2VkID0gZmFsc2UpOiB2b2lkIHtcbiAgICBMb2dnZXIudmVyYm9zZSgnV2ViR0xTZXNzaW9uSGFuZGxlcicsICdTdG9yaW5nIFRleHR1cmUgZGF0YSBpbiBjYWNoZScpO1xuICAgIGlmIChpc1BhY2tlZCkge1xuICAgICAgdGhpcy5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlLnNldCh0ZW5zb3JJZCwgdGV4dHVyZURhdGEpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnVucGFja2VkVGV4dHVyZURhdGFDYWNoZS5zZXQodGVuc29ySWQsIHRleHR1cmVEYXRhKTtcbiAgICB9XG4gIH1cbiAgZGlzcG9zZSgpOiB2b2lkIHtcbiAgICB0aGlzLnByb2dyYW1NYW5hZ2VyLmRpc3Bvc2UoKTtcbiAgICB0aGlzLnRleHR1cmVNYW5hZ2VyLmNsZWFyQWN0aXZlVGV4dHVyZXMoKTtcbiAgICB0aGlzLnBhY2tlZFRleHR1cmVEYXRhQ2FjaGUuZm9yRWFjaCh0ZCA9PiB0aGlzLnRleHR1cmVNYW5hZ2VyLnJlbGVhc2VUZXh0dXJlKHRkLCB0cnVlKSk7XG4gICAgdGhpcy5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlID0gbmV3IE1hcCgpO1xuICAgIHRoaXMudW5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlLmZvckVhY2godGQgPT4gdGhpcy50ZXh0dXJlTWFuYWdlci5yZWxlYXNlVGV4dHVyZSh0ZCwgdHJ1ZSkpO1xuICAgIHRoaXMudW5wYWNrZWRUZXh0dXJlRGF0YUNhY2hlID0gbmV3IE1hcCgpO1xuICB9XG4gIHJlc29sdmUobm9kZTogR3JhcGguTm9kZSwgb3BzZXRzOiByZWFkb25seSBPcFNldFtdLCBncmFwaDogR3JhcGgpOiBPcGVyYXRvciB7XG4gICAgY29uc3Qgb3AgPSByZXNvbHZlT3BlcmF0b3Iobm9kZSwgb3BzZXRzLCBXRUJHTF9PUF9SRVNPTFZFX1JVTEVTKTtcbiAgICByZXR1cm4ge2ltcGw6IG9wLm9wSW1wbCwgY29udGV4dDogb3Aub3BJbml0ID8gb3Aub3BJbml0KG5vZGUsIGdyYXBoKSA6IG5vZGV9O1xuICB9XG59XG4iLCIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtMb2dnZXJ9IGZyb20gJy4uLy4uL2luc3RydW1lbnQnO1xuXG5leHBvcnQgZGVjbGFyZSBuYW1lc3BhY2UgRW5jb2RlciB7XG4gIGV4cG9ydCBpbnRlcmZhY2UgRGF0YVR5cGVNYXAge1xuICAgIGZsb2F0OiBGbG9hdDMyQXJyYXk7XG4gICAgYnl0ZTogVWludDhBcnJheTtcbiAgICBpbnQ6IFVpbnQzMkFycmF5O1xuICB9XG4gIGV4cG9ydCB0eXBlIERhdGFUeXBlID0ga2V5b2YgRGF0YVR5cGVNYXA7XG4gIHR5cGUgRGF0YUFycmF5VHlwZSA9IERhdGFUeXBlTWFwW0RhdGFUeXBlXTtcblxuICAvKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb24gKi9cbiAgZXhwb3J0IGNvbnN0IGVudW0gVXNhZ2Uge1xuICAgIERlZmF1bHQgPSAwLFxuICAgIFVwbG9hZE9ubHksXG4gICAgRG93bmxvYWQ0Qnl0ZXNBc0Zsb2F0MzIsXG4gIH1cbn1cblxuLyoqXG4gKiBBYnN0cmFjdGlvbiBmb3IgbWFwcGluZyBkYXRhIHR5cGVzIHRvIHRleHR1cmUgdGV4bGV0c1xuICogRW5jb2RpbmcgbWVhbnMgaG93IGEgRmxvYXQzMiBpcyBtYXBwZWQgdG8gMSBvciA0IGNoYW5uZWxzIGZvciBlYWNoIHRleGxldFxuICogRGVjb2RpbmcgbWVhbnMgaG93IGEgdGV4bGV0J3MgY2hhbm5lbHMgYXJlIG1hcHBlZCB0byBhIHJlc3VsdGluZyBGbG9hdDMyXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRGF0YUVuY29kZXIge1xuICBpbnRlcm5hbEZvcm1hdDogbnVtYmVyO1xuICBmb3JtYXQ6IG51bWJlcjtcbiAgdGV4dHVyZVR5cGU6IG51bWJlcjtcbiAgY2hhbm5lbFNpemU6IG51bWJlcjtcbiAgZW5jb2RlKHNyYzogRW5jb2Rlci5EYXRhQXJyYXlUeXBlLCB0ZXh0dXJlU2l6ZTogbnVtYmVyKTogRW5jb2Rlci5EYXRhQXJyYXlUeXBlO1xuICBhbGxvY2F0ZShzaXplOiBudW1iZXIpOiBFbmNvZGVyLkRhdGFBcnJheVR5cGU7XG4gIGRlY29kZShidWZmZXI6IEVuY29kZXIuRGF0YUFycmF5VHlwZSwgZGF0YVNpemU6IG51bWJlcik6IEVuY29kZXIuRGF0YUFycmF5VHlwZTtcbn1cbi8qKlxuICogV2ViR0wyIGRhdGEgZW5jb2RlclxuICogVXNlcyBSMzJGIGFzIHRoZSBmb3JtYXQgZm9yIHRleGxldFxuICovXG5leHBvcnQgY2xhc3MgUmVkRmxvYXQzMkRhdGFFbmNvZGVyIGltcGxlbWVudHMgRGF0YUVuY29kZXIge1xuICBpbnRlcm5hbEZvcm1hdDogbnVtYmVyO1xuICBmb3JtYXQ6IG51bWJlcjtcbiAgdGV4dHVyZVR5cGU6IG51bWJlcjtcbiAgY2hhbm5lbFNpemU6IG51bWJlcjtcbiAgY29uc3RydWN0b3IoZ2w6IFdlYkdMMlJlbmRlcmluZ0NvbnRleHQsIGNoYW5uZWxzID0gMSkge1xuICAgIGlmIChjaGFubmVscyA9PT0gMSkge1xuICAgICAgdGhpcy5pbnRlcm5hbEZvcm1hdCA9IGdsLlIzMkY7XG4gICAgICB0aGlzLmZvcm1hdCA9IGdsLlJFRDtcbiAgICAgIHRoaXMudGV4dHVyZVR5cGUgPSBnbC5GTE9BVDtcbiAgICAgIHRoaXMuY2hhbm5lbFNpemUgPSBjaGFubmVscztcbiAgICB9IGVsc2UgaWYgKGNoYW5uZWxzID09PSA0KSB7XG4gICAgICB0aGlzLmludGVybmFsRm9ybWF0ID0gZ2wuUkdCQTMyRjtcbiAgICAgIHRoaXMuZm9ybWF0ID0gZ2wuUkdCQTtcbiAgICAgIHRoaXMudGV4dHVyZVR5cGUgPSBnbC5GTE9BVDtcbiAgICAgIHRoaXMuY2hhbm5lbFNpemUgPSBjaGFubmVscztcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIG51bWJlciBvZiBjaGFubmVsczogJHtjaGFubmVsc31gKTtcbiAgICB9XG4gIH1cbiAgZW5jb2RlKHNyYzogRW5jb2Rlci5EYXRhQXJyYXlUeXBlLCB0ZXh0dXJlU2l6ZTogbnVtYmVyKTogRW5jb2Rlci5EYXRhQXJyYXlUeXBlIHtcbiAgICBsZXQgcmVzdWx0OiBGbG9hdDMyQXJyYXk7XG4gICAgbGV0IHNvdXJjZTogRmxvYXQzMkFycmF5O1xuICAgIGlmIChzcmMuY29uc3RydWN0b3IgIT09IEZsb2F0MzJBcnJheSkge1xuICAgICAgTG9nZ2VyLndhcm5pbmcoJ0VuY29kZXInLCAnZGF0YSB3YXMgbm90IG9mIHR5cGUgRmxvYXQzMjsgY3JlYXRpbmcgbmV3IEZsb2F0MzJBcnJheScpO1xuICAgICAgc291cmNlID0gbmV3IEZsb2F0MzJBcnJheShzcmMpO1xuICAgIH1cbiAgICBpZiAodGV4dHVyZVNpemUgKiB0aGlzLmNoYW5uZWxTaXplID4gc3JjLmxlbmd0aCkge1xuICAgICAgTG9nZ2VyLndhcm5pbmcoJ0VuY29kZXInLCAnU291cmNlIGRhdGEgdG9vIHNtYWxsLiBBbGxvY2F0aW5nIGxhcmdlciBhcnJheScpO1xuICAgICAgc291cmNlID0gc3JjIGFzIEZsb2F0MzJBcnJheTtcbiAgICAgIHJlc3VsdCA9IHRoaXMuYWxsb2NhdGUodGV4dHVyZVNpemUgKiB0aGlzLmNoYW5uZWxTaXplKSBhcyBGbG9hdDMyQXJyYXk7XG4gICAgICBzb3VyY2UuZm9yRWFjaCgodiwgaSkgPT4gcmVzdWx0W2ldID0gdik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNvdXJjZSA9IHNyYyBhcyBGbG9hdDMyQXJyYXk7XG4gICAgICByZXN1bHQgPSBzb3VyY2U7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbiAgYWxsb2NhdGUoc2l6ZTogbnVtYmVyKTogRW5jb2Rlci5EYXRhQXJyYXlUeXBlIHtcbiAgICByZXR1cm4gbmV3IEZsb2F0MzJBcnJheShzaXplICogNCk7XG4gIH1cbiAgZGVjb2RlKGJ1ZmZlcjogRW5jb2Rlci5EYXRhQXJyYXlUeXBlLCBkYXRhU2l6ZTogbnVtYmVyKTogRmxvYXQzMkFycmF5IHtcbiAgICBpZiAodGhpcy5jaGFubmVsU2l6ZSA9PT0gMSkge1xuICAgICAgY29uc3QgZmlsdGVyZWREYXRhID0gKGJ1ZmZlciBhcyBGbG9hdDMyQXJyYXkpLmZpbHRlcigodmFsdWUsIGluZGV4KSA9PiBpbmRleCAlIDQgPT09IDApLnN1YmFycmF5KDAsIGRhdGFTaXplKTtcbiAgICAgIHJldHVybiBmaWx0ZXJlZERhdGE7XG4gICAgfVxuICAgIHJldHVybiBidWZmZXIuc3ViYXJyYXkoMCwgZGF0YVNpemUpIGFzIEZsb2F0MzJBcnJheTtcbiAgfVxufVxuLyoqXG4gKiBEYXRhIGVuY29kZXIgZm9yIFdlYkdMIDEgd2l0aCBzdXBwb3J0IGZvciBmbG9hdGluZyBwb2ludCB0ZXh0dXJlXG4gKi9cbmV4cG9ydCBjbGFzcyBSR0JBRmxvYXREYXRhRW5jb2RlciBpbXBsZW1lbnRzIERhdGFFbmNvZGVyIHtcbiAgaW50ZXJuYWxGb3JtYXQ6IG51bWJlcjtcbiAgZm9ybWF0OiBudW1iZXI7XG4gIHRleHR1cmVUeXBlOiBudW1iZXI7XG4gIGNoYW5uZWxTaXplOiBudW1iZXI7XG4gIGNvbnN0cnVjdG9yKGdsOiBXZWJHTFJlbmRlcmluZ0NvbnRleHQsIGNoYW5uZWxzID0gMSwgdGV4dHVyZVR5cGU/OiBudW1iZXIpIHtcbiAgICBpZiAoY2hhbm5lbHMgIT09IDEgJiYgY2hhbm5lbHMgIT09IDQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBudW1iZXIgb2YgY2hhbm5lbHM6ICR7Y2hhbm5lbHN9YCk7XG4gICAgfVxuICAgIHRoaXMuaW50ZXJuYWxGb3JtYXQgPSBnbC5SR0JBO1xuICAgIHRoaXMuZm9ybWF0ID0gZ2wuUkdCQTtcbiAgICB0aGlzLmNoYW5uZWxTaXplID0gY2hhbm5lbHM7XG4gICAgdGhpcy50ZXh0dXJlVHlwZSA9IHRleHR1cmVUeXBlIHx8IGdsLkZMT0FUO1xuICB9XG4gIGVuY29kZShzcmM6IEZsb2F0MzJBcnJheSwgdGV4dHVyZVNpemU6IG51bWJlcik6IEVuY29kZXIuRGF0YUFycmF5VHlwZSB7XG4gICAgbGV0IGRlc3QgPSBzcmM7XG4gICAgaWYgKHRoaXMuY2hhbm5lbFNpemUgPT09IDEpIHtcbiAgICAgIExvZ2dlci52ZXJib3NlKCdFbmNvZGVyJywgJ0V4cGxvZGluZyBpbnRvIGEgbGFyZ2VyIGFycmF5Jyk7XG4gICAgICBkZXN0ID0gdGhpcy5hbGxvY2F0ZSh0ZXh0dXJlU2l6ZSkgYXMgRmxvYXQzMkFycmF5O1xuICAgICAgc3JjLmZvckVhY2goKHYsIGkpID0+IGRlc3RbaSAqIDRdID0gdik7XG4gICAgfVxuICAgIHJldHVybiBkZXN0O1xuICB9XG4gIGFsbG9jYXRlKHNpemU6IG51bWJlcik6IEVuY29kZXIuRGF0YUFycmF5VHlwZSB7XG4gICAgcmV0dXJuIG5ldyBGbG9hdDMyQXJyYXkoc2l6ZSAqIDQpO1xuICB9XG4gIGRlY29kZShidWZmZXI6IEVuY29kZXIuRGF0YUFycmF5VHlwZSwgZGF0YVNpemU6IG51bWJlcik6IEZsb2F0MzJBcnJheSB7XG4gICAgaWYgKHRoaXMuY2hhbm5lbFNpemUgPT09IDEpIHtcbiAgICAgIGNvbnN0IGZpbHRlcmVkRGF0YSA9IChidWZmZXIgYXMgRmxvYXQzMkFycmF5KS5maWx0ZXIoKHZhbHVlLCBpbmRleCkgPT4gaW5kZXggJSA0ID09PSAwKS5zdWJhcnJheSgwLCBkYXRhU2l6ZSk7XG4gICAgICByZXR1cm4gZmlsdGVyZWREYXRhO1xuICAgIH1cbiAgICByZXR1cm4gYnVmZmVyLnN1YmFycmF5KDAsIGRhdGFTaXplKSBhcyBGbG9hdDMyQXJyYXk7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFVpbnQ4RGF0YUVuY29kZXIgaW1wbGVtZW50cyBEYXRhRW5jb2RlciB7XG4gIGludGVybmFsRm9ybWF0OiBudW1iZXI7XG4gIGZvcm1hdDogbnVtYmVyO1xuICB0ZXh0dXJlVHlwZTogbnVtYmVyO1xuICBjaGFubmVsU2l6ZSA9IDQ7XG4gIGNvbnN0cnVjdG9yKGdsOiBXZWJHTFJlbmRlcmluZ0NvbnRleHQsIGNoYW5uZWxzID0gMSkge1xuICAgIGlmIChjaGFubmVscyA9PT0gMSkge1xuICAgICAgdGhpcy5pbnRlcm5hbEZvcm1hdCA9IGdsLkFMUEhBO1xuICAgICAgdGhpcy5mb3JtYXQgPSBnbC5BTFBIQTsgIC8vIG5vdCB0ZXN0ZWRcbiAgICAgIHRoaXMudGV4dHVyZVR5cGUgPSBnbC5VTlNJR05FRF9CWVRFO1xuICAgICAgdGhpcy5jaGFubmVsU2l6ZSA9IGNoYW5uZWxzO1xuICAgIH0gZWxzZSBpZiAoY2hhbm5lbHMgPT09IDQpIHtcbiAgICAgIHRoaXMuaW50ZXJuYWxGb3JtYXQgPSBnbC5SR0JBO1xuICAgICAgdGhpcy5mb3JtYXQgPSBnbC5SR0JBO1xuICAgICAgdGhpcy50ZXh0dXJlVHlwZSA9IGdsLlVOU0lHTkVEX0JZVEU7XG4gICAgICB0aGlzLmNoYW5uZWxTaXplID0gY2hhbm5lbHM7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBudW1iZXIgb2YgY2hhbm5lbHM6ICR7Y2hhbm5lbHN9YCk7XG4gICAgfVxuICB9XG4gIGVuY29kZShzcmM6IFVpbnQ4QXJyYXksIF90ZXh0dXJlU2l6ZTogbnVtYmVyKTogRW5jb2Rlci5EYXRhQXJyYXlUeXBlIHtcbiAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoc3JjLmJ1ZmZlciwgc3JjLmJ5dGVPZmZzZXQsIHNyYy5ieXRlTGVuZ3RoKTtcbiAgfVxuICBhbGxvY2F0ZShzaXplOiBudW1iZXIpOiBFbmNvZGVyLkRhdGFBcnJheVR5cGUge1xuICAgIHJldHVybiBuZXcgVWludDhBcnJheShzaXplICogdGhpcy5jaGFubmVsU2l6ZSk7XG4gIH1cbiAgZGVjb2RlKGJ1ZmZlcjogRW5jb2Rlci5EYXRhQXJyYXlUeXBlLCBkYXRhU2l6ZTogbnVtYmVyKTogVWludDhBcnJheSB7XG4gICAgaWYgKGJ1ZmZlciBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHtcbiAgICAgIHJldHVybiBidWZmZXIuc3ViYXJyYXkoMCwgZGF0YVNpemUpO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgYXJyYXkgdHlwZTogJHtidWZmZXIuY29uc3RydWN0b3J9YCk7XG4gIH1cbn1cbiIsIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge0xvZ2dlcn0gZnJvbSAnLi4vLi4vaW5zdHJ1bWVudCc7XG5pbXBvcnQge2Fzc2VydH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5cbi8qKiBMYXlvdXQgcHJlZmVyZW5jZXMgKi9cbmV4cG9ydCBpbnRlcmZhY2UgV2lkdGhIZWlnaHRQcmVmcyB7XG4gIGJyZWFrQXhpcz86IG51bWJlcjtcbiAgaXNQYWNrZWQ/OiBib29sZWFuO1xuICByZXZlcnNlV0g/OiBib29sZWFuO1xufVxuLyoqXG4gKiBUZXh0dXJlTGF5b3V0U3RyYXRlZ3kgaXMgYW4gYWJzdHJhY3Rpb24gZm9yIGRpZmZlcmVudCBwbGFuc1xuICogZm9yIG1hcHBpbmcgbi1kaW1lbnNpb25hbCBhcnJheXMgdG8gMkQgdGV4dHVyZXMgKGFuZCBiYWNrKVxuICovXG5leHBvcnQgaW50ZXJmYWNlIFRleHR1cmVMYXlvdXRTdHJhdGVneSB7XG4gIGNvbXB1dGVUZXh0dXJlV0goc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCBwcmVmcz86IFdpZHRoSGVpZ2h0UHJlZnMpOiBbbnVtYmVyLCBudW1iZXJdO1xufVxuXG4vKipcbiAqIFRoaXMgc3RyYXRlZ3kgdHJ5IHRvIGZpbmQgdGhlIG1pbmltYWwgbWF4KFcsSCkgdGhhdCBmdWxmaWxscyAoVyAqIEggPT0gdG90YWxTaXplKVxuICovXG5leHBvcnQgY2xhc3MgQWx3YXlzS2VlcE9yaWdpbmFsU2l6ZVN0cmF0ZWd5IGltcGxlbWVudHMgVGV4dHVyZUxheW91dFN0cmF0ZWd5IHtcbiAgY29uc3RydWN0b3IocHVibGljIG1heFRleHR1cmVTaXplOiBudW1iZXIpIHt9XG4gIGNvbXB1dGVUZXh0dXJlV0goc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCBwcmVmcz86IFdpZHRoSGVpZ2h0UHJlZnMpOiBbbnVtYmVyLCBudW1iZXJdIHtcbiAgICAvLyBzY2FsYXIgdGVuc29yXG4gICAgaWYgKHNoYXBlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIFsxLCAxXTtcbiAgICB9XG4gICAgY29uc3QgbWF4VGV4dHVyZVNpemUgPSB0aGlzLm1heFRleHR1cmVTaXplO1xuICAgIGlmIChwcmVmcyAmJiBwcmVmcy5icmVha0F4aXMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgLy8gY2hlY2sgdG8gc2VlIGlmIGRpbXMgZml0XG4gICAgICBjb25zdCB3c2l6ZSA9IHByZWZzLmJyZWFrQXhpcyA+PSBzaGFwZS5sZW5ndGggPyAxIDogc2hhcGUuc2xpY2UocHJlZnMuYnJlYWtBeGlzKS5yZWR1Y2UoKGEsIGIpID0+IGEgKiBiKTtcbiAgICAgIGNvbnN0IGhzaXplID0gcHJlZnMuYnJlYWtBeGlzIDw9IDAgPyAxIDogc2hhcGUuc2xpY2UoMCwgcHJlZnMuYnJlYWtBeGlzKS5yZWR1Y2UoKGEsIGIpID0+IGEgKiBiKTtcbiAgICAgIGlmICh3c2l6ZSA+IG1heFRleHR1cmVTaXplIHx8IGhzaXplID4gbWF4VGV4dHVyZVNpemUpIHtcbiAgICAgICAgLy8gaWdub3JlIHByZWZlcmVuY2VzXG4gICAgICAgIC8vIGNvbnRpbnVlIHdpdGggZGVmYXVsdCBsYXlvdXRcbiAgICAgICAgTG9nZ2VyLnZlcmJvc2UoXG4gICAgICAgICAgICAnVGV4dHVyZUxheW91dCcsXG4gICAgICAgICAgICBgR2l2ZW4gd2lkdGgvaGVpZ2h0IHByZWZlcmVuY2VzIHdlcmUgdW5hdHRhaW5hYmxlOiBzaGFwZToke3NoYXBlfSwgYnJlYWtBeGlzOiR7cHJlZnMuYnJlYWtBeGlzfWApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIFt3c2l6ZSwgaHNpemVdO1xuICAgICAgfVxuICAgIH1cbiAgICBjb25zdCB0b3RhbFNpemUgPSBzaGFwZS5yZWR1Y2UoKGEsIGIpID0+IGEgKiBiKTtcblxuICAgIGxldCB3aWR0aCA9IE1hdGguZmxvb3IoTWF0aC5zcXJ0KHRvdGFsU2l6ZSkpO1xuXG4gICAgZm9yICg7IHdpZHRoIDwgbWF4VGV4dHVyZVNpemUgJiYgd2lkdGggPCB0b3RhbFNpemU7IHdpZHRoKyspIHtcbiAgICAgIGlmICh0b3RhbFNpemUgJSB3aWR0aCA9PT0gMCkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAod2lkdGggPj0gbWF4VGV4dHVyZVNpemUgfHwgdG90YWxTaXplICUgd2lkdGggIT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVGhlIGdpdmVuIGRpbWVuc2lvbnMgYXJlIG91dHNpZGUgdGhpcyBHUFUncyBib3VuZGFyaWVzOiAke3NoYXBlfWApO1xuICAgIH1cbiAgICByZXR1cm4gW3dpZHRoLCB0b3RhbFNpemUgLyB3aWR0aF07XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFByZWZlckxvZ2ljYWxTdHJhdGVneSBpbXBsZW1lbnRzIFRleHR1cmVMYXlvdXRTdHJhdGVneSB7XG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBtYXhUZXh0dXJlU2l6ZTogbnVtYmVyKSB7fVxuICBjb21wdXRlVGV4dHVyZVdIKHNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgcHJlZnM/OiBXaWR0aEhlaWdodFByZWZzKTogW251bWJlciwgbnVtYmVyXSB7XG4gICAgY29uc3Qgd2ggPSB0aGlzLmNvbXB1dGVUZXh0dXJlKHNoYXBlLCBwcmVmcyk7XG4gICAgaWYgKHByZWZzICYmIHByZWZzLmlzUGFja2VkKSB7XG4gICAgICB3aFswXSAvPSAyO1xuICAgICAgd2hbMV0gLz0gMjtcbiAgICB9XG4gICAgaWYgKHByZWZzICYmIHByZWZzLnJldmVyc2VXSCkge1xuICAgICAgcmV0dXJuIFt3aFsxXSwgd2hbMF1dO1xuICAgIH1cbiAgICByZXR1cm4gd2g7XG4gIH1cblxuICBjb21wdXRlVGV4dHVyZShzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIHByZWZzPzogV2lkdGhIZWlnaHRQcmVmcyk6IFtudW1iZXIsIG51bWJlcl0ge1xuICAgIGNvbnN0IGlzUGFja2VkID0gcHJlZnMgJiYgcHJlZnMuaXNQYWNrZWQ7XG4gICAgLy8gc2NhbGFyIHRlbnNvclxuICAgIGlmIChzaGFwZS5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBpc1BhY2tlZCA/IFsyLCAyXSA6IFsxLCAxXTtcbiAgICB9XG4gICAgbGV0IG1heFRleHR1cmVTaXplID0gdGhpcy5tYXhUZXh0dXJlU2l6ZTtcbiAgICBpZiAocHJlZnMgJiYgcHJlZnMuYnJlYWtBeGlzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIC8vIGNoZWNrIHRvIHNlZSBpZiBkaW1zIGZpdFxuICAgICAgY29uc3Qgd3NpemUgPSBwcmVmcy5icmVha0F4aXMgPj0gc2hhcGUubGVuZ3RoID8gMSA6IHNoYXBlLnNsaWNlKHByZWZzLmJyZWFrQXhpcykucmVkdWNlKChhLCBiKSA9PiBhICogYik7XG4gICAgICBjb25zdCBoc2l6ZSA9IHByZWZzLmJyZWFrQXhpcyA8PSAwID8gMSA6IHNoYXBlLnNsaWNlKDAsIHByZWZzLmJyZWFrQXhpcykucmVkdWNlKChhLCBiKSA9PiBhICogYik7XG4gICAgICBpZiAod3NpemUgPiBtYXhUZXh0dXJlU2l6ZSB8fCBoc2l6ZSA+IG1heFRleHR1cmVTaXplKSB7XG4gICAgICAgIC8vIGlnbm9yZSBwcmVmZXJlbmNlc1xuICAgICAgICAvLyBjb250aW51ZSB3aXRoIGRlZmF1bHQgbGF5b3V0XG4gICAgICAgIExvZ2dlci52ZXJib3NlKFxuICAgICAgICAgICAgJ1RleHR1cmVMYXlvdXQnLFxuICAgICAgICAgICAgYEdpdmVuIHdpZHRoL2hlaWdodCBwcmVmZXJlbmNlcyB3ZXJlIHVuYXR0YWluYWJsZTogc2hhcGU6JHtzaGFwZX0sIGJyZWFrQXhpczoke3ByZWZzLmJyZWFrQXhpc31gKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBbd3NpemUsIGhzaXplXTtcbiAgICAgIH1cbiAgICB9XG4gICAgbGV0IGxvZ1NoYXBlID0gc2hhcGUuc2xpY2UoMCk7XG4gICAgaWYgKGlzUGFja2VkKSB7XG4gICAgICBtYXhUZXh0dXJlU2l6ZSA9IG1heFRleHR1cmVTaXplICogMjtcblxuICAgICAgLy8gVGhpcyBsb2dpYyBlbnN1cmVzIHdlIGFjY3VyYXRlbHkgY291bnQgdGhlIG51bWJlciBvZiBwYWNrZWQgdGV4ZWxzIG5lZWRlZFxuICAgICAgLy8gdG8gYWNjb21tb2RhdGUgdGhlIHRlbnNvci4gV2UgY2FuIG9ubHkgcGFjayB2YWx1ZXMgaW4gdGhlIHNhbWUgdGV4ZWwgaWZcbiAgICAgIC8vIHRoZXkgYXJlIGZyb20gYWRqYWNlbnQgcGFpcnMgb2Ygcm93cy9jb2xzIHdpdGhpbiB0aGUgc2FtZSBiYXRjaC4gU28gaWYgYVxuICAgICAgLy8gdGVuc29yIGhhcyAzIHJvd3MsIHdlIHByZXRlbmQgaXQgaGFzIDQgcm93cyBpbiBvcmRlciB0byBhY2NvdW50IGZvciB0aGVcbiAgICAgIC8vIGZhY3QgdGhhdCB0aGUgdGV4ZWxzIGNvbnRhaW5pbmcgdGhlIHRoaXJkIHJvdyBhcmUgaGFsZiBlbXB0eS5cbiAgICAgIGxvZ1NoYXBlID0gbG9nU2hhcGUubWFwKFxuICAgICAgICAgIChkLCBpKSA9PiBpID49IGxvZ1NoYXBlLmxlbmd0aCAtIDIgPyAobG9nU2hhcGVbaV0gJSAyID09PSAwID8gbG9nU2hhcGVbaV0gOiBsb2dTaGFwZVtpXSArIDEpIDogbG9nU2hhcGVbaV0pO1xuXG4gICAgICAvLyBQYWNrZWQgdGV4dHVyZSBoZWlnaHQgaXMgYXQgbGVhc3QgMiAodGhlIGNoYW5uZWwgaGVpZ2h0IG9mIGEgc2luZ2xlXG4gICAgICAvLyB0ZXhlbCkuXG4gICAgICBpZiAobG9nU2hhcGUubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIGxvZ1NoYXBlID0gWzIsIGxvZ1NoYXBlWzBdXTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBJZiBsb2dpY2FsIHNoYXBlIGlzIDIsIHdlIGRvbid0IHNxdWVlemUsIHNpbmNlIHdlIHdhbnQgdG8gbWF0Y2ggcGh5c2ljYWwuXG4gICAgaWYgKGxvZ1NoYXBlLmxlbmd0aCAhPT0gMikge1xuICAgICAgY29uc3Qgc3F1ZWV6ZVJlc3VsdCA9IHNxdWVlemVTaGFwZShsb2dTaGFwZSk7XG4gICAgICBsb2dTaGFwZSA9IHNxdWVlemVSZXN1bHQubmV3U2hhcGU7XG4gICAgfVxuXG4gICAgY29uc3Qgc2l6ZSA9IHNpemVGcm9tU2hhcGUobG9nU2hhcGUpO1xuICAgIGlmIChsb2dTaGFwZS5sZW5ndGggPD0gMSAmJiBzaXplIDw9IG1heFRleHR1cmVTaXplKSB7XG4gICAgICByZXR1cm4gWzEsIHNpemVdO1xuICAgIH0gZWxzZSBpZiAobG9nU2hhcGUubGVuZ3RoID09PSAyICYmIGxvZ1NoYXBlWzBdIDw9IG1heFRleHR1cmVTaXplICYmIGxvZ1NoYXBlWzFdIDw9IG1heFRleHR1cmVTaXplKSB7XG4gICAgICByZXR1cm4gbG9nU2hhcGUgYXMgW251bWJlciwgbnVtYmVyXTtcbiAgICB9IGVsc2UgaWYgKGxvZ1NoYXBlLmxlbmd0aCA9PT0gMyAmJiBsb2dTaGFwZVswXSAqIGxvZ1NoYXBlWzFdIDw9IG1heFRleHR1cmVTaXplICYmIGxvZ1NoYXBlWzJdIDw9IG1heFRleHR1cmVTaXplKSB7XG4gICAgICByZXR1cm4gW2xvZ1NoYXBlWzBdICogbG9nU2hhcGVbMV0sIGxvZ1NoYXBlWzJdXTtcbiAgICB9IGVsc2UgaWYgKGxvZ1NoYXBlLmxlbmd0aCA9PT0gMyAmJiBsb2dTaGFwZVswXSA8PSBtYXhUZXh0dXJlU2l6ZSAmJiBsb2dTaGFwZVsxXSAqIGxvZ1NoYXBlWzJdIDw9IG1heFRleHR1cmVTaXplKSB7XG4gICAgICByZXR1cm4gW2xvZ1NoYXBlWzBdLCBsb2dTaGFwZVsxXSAqIGxvZ1NoYXBlWzJdXTtcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgICBsb2dTaGFwZS5sZW5ndGggPT09IDQgJiYgbG9nU2hhcGVbMF0gKiBsb2dTaGFwZVsxXSAqIGxvZ1NoYXBlWzJdIDw9IG1heFRleHR1cmVTaXplICYmXG4gICAgICAgIGxvZ1NoYXBlWzNdIDw9IG1heFRleHR1cmVTaXplKSB7XG4gICAgICByZXR1cm4gW2xvZ1NoYXBlWzBdICogbG9nU2hhcGVbMV0gKiBsb2dTaGFwZVsyXSwgbG9nU2hhcGVbM11dO1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICAgIGxvZ1NoYXBlLmxlbmd0aCA9PT0gNCAmJiBsb2dTaGFwZVswXSA8PSBtYXhUZXh0dXJlU2l6ZSAmJlxuICAgICAgICBsb2dTaGFwZVsxXSAqIGxvZ1NoYXBlWzJdICogbG9nU2hhcGVbM10gPD0gbWF4VGV4dHVyZVNpemUpIHtcbiAgICAgIHJldHVybiBbbG9nU2hhcGVbMF0sIGxvZ1NoYXBlWzFdICogbG9nU2hhcGVbMl0gKiBsb2dTaGFwZVszXV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChpc1BhY2tlZCkge1xuICAgICAgICAvLyBGb3IgcGFja2VkIHRleHR1cmVzIHNpemUgZXF1YWxzIHRoZSBudW1iZXIgb2YgY2hhbm5lbHMgcmVxdWlyZWQgdG9cbiAgICAgICAgLy8gYWNjb21tb2RhdGUgdGhlIHRleHR1cmUgZGF0YS4gSG93ZXZlciBpbiBvcmRlciB0byBzcXVhcmlmeSBzdWNoIHRoYXRcbiAgICAgICAgLy8gaW5uZXIgZGltZW5zaW9ucyBzdGF5IGV2ZW4sIHdlIHJld3JpdGUgc2l6ZSB0byBlcXVhbCB0aGUgbnVtYmVyIG9mXG4gICAgICAgIC8vIHRleGVscy4gVGhlbiBpbiB0aGUgcmV0dXJuIHN0YXRlbWVudCB3ZSByZWh5ZHJhdGUgdGhlIHNxdWFyaWZpZWRcbiAgICAgICAgLy8gZGltZW5zaW9ucyB0byBjaGFubmVsIHVuaXRzLlxuICAgICAgICByZXR1cm4gc2l6ZVRvU3F1YXJpc2hTaGFwZShzaXplIC8gNCkubWFwKGQgPT4gZCAqIDIpIGFzIFtudW1iZXIsIG51bWJlcl07XG4gICAgICB9XG4gICAgICByZXR1cm4gc2l6ZVRvU3F1YXJpc2hTaGFwZShzaXplKTtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNxdWVlemVTaGFwZShzaGFwZTogbnVtYmVyW10sIGF4aXM/OiBudW1iZXJbXSk6IHtuZXdTaGFwZTogbnVtYmVyW107IGtlcHREaW1zOiBudW1iZXJbXX0ge1xuICBjb25zdCBuZXdTaGFwZTogbnVtYmVyW10gPSBbXTtcbiAgY29uc3Qga2VwdERpbXM6IG51bWJlcltdID0gW107XG4gIGNvbnN0IGlzRW1wdHlBcnJheSA9IGF4aXMgIT0gbnVsbCAmJiBBcnJheS5pc0FycmF5KGF4aXMpICYmIGF4aXMubGVuZ3RoID09PSAwO1xuICBjb25zdCBheGVzID0gKGF4aXMgPT0gbnVsbCB8fCBpc0VtcHR5QXJyYXkpID8gbnVsbCA6IHBhcnNlQXhpc1BhcmFtKGF4aXMsIHNoYXBlKS5zb3J0KCk7XG4gIGxldCBqID0gMDtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBzaGFwZS5sZW5ndGg7ICsraSkge1xuICAgIGlmIChheGVzICE9IG51bGwpIHtcbiAgICAgIGlmIChheGVzW2pdID09PSBpICYmIHNoYXBlW2ldICE9PSAxKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2FuJ3Qgc3F1ZWV6ZSBheGlzICR7aX0gc2luY2UgaXRzIGRpbSAnJHtzaGFwZVtpXX0nIGlzIG5vdCAxYCk7XG4gICAgICB9XG4gICAgICBpZiAoKGF4ZXNbal0gPT0gbnVsbCB8fCBheGVzW2pdID4gaSkgJiYgc2hhcGVbaV0gPT09IDEpIHtcbiAgICAgICAgbmV3U2hhcGUucHVzaChzaGFwZVtpXSk7XG4gICAgICAgIGtlcHREaW1zLnB1c2goaSk7XG4gICAgICB9XG4gICAgICBpZiAoYXhlc1tqXSA8PSBpKSB7XG4gICAgICAgIGorKztcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHNoYXBlW2ldICE9PSAxKSB7XG4gICAgICBuZXdTaGFwZS5wdXNoKHNoYXBlW2ldKTtcbiAgICAgIGtlcHREaW1zLnB1c2goaSk7XG4gICAgfVxuICB9XG4gIHJldHVybiB7bmV3U2hhcGUsIGtlcHREaW1zfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlQXhpc1BhcmFtKGF4aXM6IG51bWJlcnxudW1iZXJbXSwgc2hhcGU6IG51bWJlcltdKTogbnVtYmVyW10ge1xuICBjb25zdCByYW5rID0gc2hhcGUubGVuZ3RoO1xuXG4gIC8vIE5vcm1hbGl6ZSBpbnB1dFxuICBheGlzID0gYXhpcyA9PSBudWxsID8gc2hhcGUubWFwKChzLCBpKSA9PiBpKSA6IChbXSBhcyBudW1iZXJbXSkuY29uY2F0KGF4aXMpO1xuXG4gIC8vIENoZWNrIGZvciB2YWxpZCByYW5nZVxuICBhc3NlcnQoXG4gICAgICBheGlzLmV2ZXJ5KGF4ID0+IGF4ID49IC1yYW5rICYmIGF4IDwgcmFuayksXG4gICAgICAoKSA9PiBgQWxsIHZhbHVlcyBpbiBheGlzIHBhcmFtIG11c3QgYmUgaW4gcmFuZ2UgWy0ke3Jhbmt9LCAke3Jhbmt9KSBidXQgYCArXG4gICAgICAgICAgYGdvdCBheGlzICR7YXhpc31gKTtcblxuICAvLyBDaGVjayBmb3Igb25seSBpbnRlZ2Vyc1xuICBhc3NlcnQoXG4gICAgICBheGlzLmV2ZXJ5KGlzSW50KSxcbiAgICAgICgpID0+ICdBbGwgdmFsdWVzIGluIGF4aXMgcGFyYW0gbXVzdCBiZSBpbnRlZ2VycyBidXQgJyArXG4gICAgICAgICAgYGdvdCBheGlzICR7YXhpc31gKTtcblxuICAvLyBIYW5kbGUgbmVnYXRpdmUgYXhpcy5cbiAgcmV0dXJuIGF4aXMubWFwKGEgPT4gYSA8IDAgPyByYW5rICsgYSA6IGEpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGlzSW50KGE6IG51bWJlcik6IGJvb2xlYW4ge1xuICByZXR1cm4gYSAlIDEgPT09IDA7XG59XG5leHBvcnQgZnVuY3Rpb24gc2l6ZUZyb21TaGFwZShzaGFwZTogbnVtYmVyW10pOiBudW1iZXIge1xuICBpZiAoc2hhcGUubGVuZ3RoID09PSAwKSB7XG4gICAgLy8gU2NhbGFyLlxuICAgIHJldHVybiAxO1xuICB9XG4gIGxldCBzaXplID0gc2hhcGVbMF07XG4gIGZvciAobGV0IGkgPSAxOyBpIDwgc2hhcGUubGVuZ3RoOyBpKyspIHtcbiAgICBzaXplICo9IHNoYXBlW2ldO1xuICB9XG4gIHJldHVybiBzaXplO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdldFJvd3NDb2xzKHNoYXBlOiBudW1iZXJbXSk6IFtudW1iZXIsIG51bWJlcl0ge1xuICBpZiAoc2hhcGUubGVuZ3RoID09PSAwKSB7XG4gICAgdGhyb3cgRXJyb3IoJ0Nhbm5vdCBnZXQgcm93cyBhbmQgY29sdW1ucyBvZiBhbiBlbXB0eSBzaGFwZSBhcnJheS4nKTtcbiAgfVxuXG4gIHJldHVybiBbc2hhcGUubGVuZ3RoID4gMSA/IHNoYXBlW3NoYXBlLmxlbmd0aCAtIDJdIDogMSwgc2hhcGVbc2hhcGUubGVuZ3RoIC0gMV1dO1xufVxuZXhwb3J0IGZ1bmN0aW9uIHNpemVUb1NxdWFyaXNoU2hhcGUoc2l6ZTogbnVtYmVyKTogW251bWJlciwgbnVtYmVyXSB7XG4gIGNvbnN0IHdpZHRoID0gTWF0aC5jZWlsKE1hdGguc3FydChzaXplKSk7XG4gIHJldHVybiBbd2lkdGgsIE1hdGguY2VpbChzaXplIC8gd2lkdGgpXTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnZXRCYXRjaERpbShzaGFwZTogbnVtYmVyW10sIGRpbXNUb1NraXAgPSAyKTogbnVtYmVyIHtcbiAgcmV0dXJuIHNpemVGcm9tU2hhcGUoc2hhcGUuc2xpY2UoMCwgc2hhcGUubGVuZ3RoIC0gZGltc1RvU2tpcCkpO1xufVxuIiwiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7U2hhcGVVdGlsfSBmcm9tICcuLi8uLi91dGlsJztcblxuaW1wb3J0IHtUZXh0dXJlTGF5b3V0U3RyYXRlZ3ksIFdpZHRoSGVpZ2h0UHJlZnN9IGZyb20gJy4vdGV4dHVyZS1sYXlvdXQtc3RyYXRlZ3knO1xuaW1wb3J0IHtUZXh0dXJlTGF5b3V0LCBUZXh0dXJlVHlwZX0gZnJvbSAnLi90eXBlcyc7XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVUZXh0dXJlTGF5b3V0RnJvbVRleHR1cmVUeXBlID1cbiAgICAodGV4dHVyZUxheW91dFN0cmF0ZWd5OiBUZXh0dXJlTGF5b3V0U3RyYXRlZ3ksIHNoYXBlOiByZWFkb25seSBudW1iZXJbXSxcbiAgICAgdGV4dHVyZVR5cGU6IFRleHR1cmVUeXBlKTogVGV4dHVyZUxheW91dCA9PiB7XG4gICAgICBjb25zdCBjaGFubmVsID0gKHRleHR1cmVUeXBlID09PSBUZXh0dXJlVHlwZS51bnBhY2tlZCB8fCB0ZXh0dXJlVHlwZSA9PT0gVGV4dHVyZVR5cGUudW5wYWNrZWRSZXZlcnNlZCkgPyAxIDogNDtcbiAgICAgIGNvbnN0IGlzUGFja2VkID0gdGV4dHVyZVR5cGUgPT09IFRleHR1cmVUeXBlLnBhY2tlZDtcbiAgICAgIGNvbnN0IHJldmVyc2VXSCA9ICh0ZXh0dXJlVHlwZSA9PT0gVGV4dHVyZVR5cGUudW5wYWNrZWRSZXZlcnNlZCB8fCB0ZXh0dXJlVHlwZSA9PT0gVGV4dHVyZVR5cGUucGFja2VkKTtcbiAgICAgIGNvbnN0IGJyZWFrQXhpcyA9IHRleHR1cmVUeXBlID09PSBUZXh0dXJlVHlwZS5wYWNrZWRMYXN0RGltZW5zaW9uID8gc2hhcGUubGVuZ3RoIC0gMSA6IHVuZGVmaW5lZDtcbiAgICAgIGNvbnN0IHVucGFja2VkU2hhcGUgPSB0ZXh0dXJlVHlwZSA9PT0gVGV4dHVyZVR5cGUucGFja2VkTGFzdERpbWVuc2lvbiA/XG4gICAgICAgICAgc2hhcGUubWFwKChkLCBpKSA9PiBpID09PSBzaGFwZS5sZW5ndGggLSAxID8gZCAqIDQgOiBkKSA6XG4gICAgICAgICAgdW5kZWZpbmVkO1xuICAgICAgcmV0dXJuIGNyZWF0ZVRleHR1cmVMYXlvdXRGcm9tU2hhcGUoXG4gICAgICAgICAgdGV4dHVyZUxheW91dFN0cmF0ZWd5LCBzaGFwZSwgY2hhbm5lbCwgdW5wYWNrZWRTaGFwZSwge2lzUGFja2VkLCByZXZlcnNlV0gsIGJyZWFrQXhpc30pO1xuICAgIH07XG5cbmV4cG9ydCBjb25zdCBjYWxjdWxhdGVUZXh0dXJlV2lkdGhBbmRIZWlnaHQgPVxuICAgICh0ZXh0dXJlTGF5b3V0U3RyYXRlZ3k6IFRleHR1cmVMYXlvdXRTdHJhdGVneSwgc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGUpOlxuICAgICAgICBbbnVtYmVyLCBudW1iZXJdID0+IHtcbiAgICAgICAgICBjb25zdCBsYXlvdXQgPSBjcmVhdGVUZXh0dXJlTGF5b3V0RnJvbVRleHR1cmVUeXBlKHRleHR1cmVMYXlvdXRTdHJhdGVneSwgc2hhcGUsIHRleHR1cmVUeXBlKTtcbiAgICAgICAgICByZXR1cm4gW2xheW91dC53aWR0aCwgbGF5b3V0LmhlaWdodF07XG4gICAgICAgIH07XG5cbi8qKlxuICogQ3JlYXRlIGEgVGV4dHVyZUxheW91dCBvYmplY3QgZnJvbSBzaGFwZS5cbiAqL1xuZXhwb3J0IGNvbnN0IGNyZWF0ZVRleHR1cmVMYXlvdXRGcm9tU2hhcGUgPVxuICAgICh0ZXh0dXJlTGF5b3V0U3RyYXRlZ3k6IFRleHR1cmVMYXlvdXRTdHJhdGVneSwgc2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCBjaGFubmVsczogMXw0ID0gMSxcbiAgICAgdW5wYWNrZWRTaGFwZT86IHJlYWRvbmx5IG51bWJlcltdLCBwcmVmcz86IFdpZHRoSGVpZ2h0UHJlZnMpOiBUZXh0dXJlTGF5b3V0ID0+IHtcbiAgICAgIGNvbnN0IGlzUGFja2VkID0gISEocHJlZnMgJiYgcHJlZnMuaXNQYWNrZWQpO1xuICAgICAgY29uc3QgW3dpZHRoLCBoZWlnaHRdID0gdGV4dHVyZUxheW91dFN0cmF0ZWd5LmNvbXB1dGVUZXh0dXJlV0goaXNQYWNrZWQgPyB1bnBhY2tlZFNoYXBlIHx8IHNoYXBlIDogc2hhcGUsIHByZWZzKTtcbiAgICAgIGNvbnN0IHJhbmsgPSBzaGFwZS5sZW5ndGg7XG4gICAgICBsZXQgaW5mZXJyZWREaW1zID0gc2hhcGUuc2xpY2UoMCk7XG4gICAgICBpZiAocmFuayA9PT0gMCkge1xuICAgICAgICBpbmZlcnJlZERpbXMgPSBbMV07XG4gICAgICB9XG4gICAgICBpZiAoY2hhbm5lbHMgPT09IDEpIHtcbiAgICAgICAgLy8gdW5wYWNrZWRTaGFwZSB3aWxsIHRha2UgYHNoYXBlYCBhbmQgbm90IGBpbmZlcnJlZERpbXNgIHNvIGFzIHRvIGNyZWF0ZSBhIHNjYWxhciBUZW5zb3IgaWYgbmVlZCBiZVxuICAgICAgICB1bnBhY2tlZFNoYXBlID0gc2hhcGU7XG4gICAgICB9IGVsc2UgaWYgKGlzUGFja2VkKSB7XG4gICAgICAgIGlmIChjaGFubmVscyAhPT0gNCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignYSBwYWNrZWQgdGV4dHVyZSBtdXN0IGJlIDQtY2hhbm5lbCcpO1xuICAgICAgICB9XG4gICAgICAgIHVucGFja2VkU2hhcGUgPSBzaGFwZTtcbiAgICAgICAgaWYgKHJhbmsgPiAwKSB7XG4gICAgICAgICAgaW5mZXJyZWREaW1zW3JhbmsgLSAxXSA9IE1hdGguY2VpbChpbmZlcnJlZERpbXNbcmFuayAtIDFdIC8gMik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJhbmsgPiAxKSB7XG4gICAgICAgICAgaW5mZXJyZWREaW1zW3JhbmsgLSAyXSA9IE1hdGguY2VpbChpbmZlcnJlZERpbXNbcmFuayAtIDJdIC8gMik7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoIXVucGFja2VkU2hhcGUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbnBhY2tlZCBzaGFwZSBpcyBuZWVkZWQgd2hlbiB1c2luZyBjaGFubmVscyA+IDEnKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHdpZHRoLFxuICAgICAgICBoZWlnaHQsXG4gICAgICAgIGNoYW5uZWxzLFxuICAgICAgICBpc1BhY2tlZCxcbiAgICAgICAgc2hhcGU6IGluZmVycmVkRGltcyxcbiAgICAgICAgc3RyaWRlczogU2hhcGVVdGlsLmNvbXB1dGVTdHJpZGVzKGluZmVycmVkRGltcyksXG4gICAgICAgIHVucGFja2VkU2hhcGUsXG4gICAgICAgIHJldmVyc2VkV0g6IChwcmVmcyAmJiBwcmVmcy5yZXZlcnNlV0gpXG4gICAgICB9O1xuICAgIH07XG4iLCIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtMb2dnZXIsIFByb2ZpbGVyfSBmcm9tICcuLi8uLi9pbnN0cnVtZW50JztcbmltcG9ydCB7VGVuc29yfSBmcm9tICcuLi8uLi90ZW5zb3InO1xuXG5pbXBvcnQge0VuY29kZXJ9IGZyb20gJy4vdGV4dHVyZS1kYXRhLWVuY29kZXInO1xuaW1wb3J0IHtUZXh0dXJlTGF5b3V0U3RyYXRlZ3l9IGZyb20gJy4vdGV4dHVyZS1sYXlvdXQtc3RyYXRlZ3knO1xuaW1wb3J0IHtUZXh0dXJlRGF0YSwgVGV4dHVyZUxheW91dH0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQge1dlYkdMQ29udGV4dH0gZnJvbSAnLi93ZWJnbC1jb250ZXh0JztcblxuZXhwb3J0IGludGVyZmFjZSBUZXh0dXJlTWFuYWdlckNvbmZpZyB7XG4gIHJldXNlVGV4dHVyZXM/OiBib29sZWFuO1xufVxuXG4vKipcbiAqIFRleHR1cmVNYW5hZ2VyIGlzIHRoZSBtYWlubHkgcmVzcG9uc2libGUgZm9yIGNhY2hpbmcgVGV4dHVyZXNcbiAqIFRleHR1cmVzIGFyZSBjYWNoZWQgaW4gMiBsZXZlbHM6XG4gKiAgIDEuIHRoZSB0ZXh1cmVzIHdoaWNoIGFyZSBhc3NvY2lhdGVkIHdpdGggYSBkYXRhSWQgKGZyb20gVGVuc29yKVxuICogICAgQ2FjaGluZyB0aGVzZSBpcyBjcnVjaWFsIHRvIHBlcmZvcm1hbmNlLiBUaGVzZSBhcmUgSW4tdXNlIFRleHR1cmVzXG4gKiAgIDIuIHRleHR1cmVzIHdoaWNoIGFyZSBub3QgaW4gdXNlIGJ5IGFueSBjdXJyZW50IFByb2dyYW1JbmZvL1RlbnNvclxuICogICAgIFRoZXNlIGFyZSBjYWxsZWQgRnJlZSBUZXh0dXJlc1xuICogVGV4dHVyZU1hbmFnZXIgaXMgYWxzbyB1c2VkIHRvIGhlbHAgY3JlYXRpbmcgdGV4dHVyZXMuIEZvciB0aGlzIGl0XG4gKiB1c2VzIFdlYkdMQ29udGV4dCBhbmQgVGV4dHVyZUxheW91dFN0cmF0ZWd5XG4gKi9cbmV4cG9ydCBjbGFzcyBUZXh0dXJlTWFuYWdlciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgaW5Vc2VUZXh0dXJlczogTWFwPHN0cmluZywgV2ViR0xUZXh0dXJlW10+O1xuICBwcml2YXRlIHJlYWRvbmx5IGlkbGVUZXh0dXJlczogTWFwPHN0cmluZywgV2ViR0xUZXh0dXJlW10+O1xuICBwcml2YXRlIHJlYWRvbmx5IHRleHR1cmVMb29rdXA6IE1hcDxXZWJHTFRleHR1cmUsIHN0cmluZz47XG4gIHByaXZhdGUgcmVhZG9ubHkgcGVuZGluZ1JlYWQ6IE1hcDxUZW5zb3IuSWQsIEFycmF5PChhcnI6IFRlbnNvci5OdW1iZXJUeXBlKSA9PiB2b2lkPj4gPSBuZXcgTWFwKCk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgICBwdWJsaWMgZ2xDb250ZXh0OiBXZWJHTENvbnRleHQsIHB1YmxpYyBsYXlvdXRTdHJhdGVneTogVGV4dHVyZUxheW91dFN0cmF0ZWd5LCBwdWJsaWMgcHJvZmlsZXI6IFJlYWRvbmx5PFByb2ZpbGVyPixcbiAgICAgIHByaXZhdGUgY29uZmlnOiBUZXh0dXJlTWFuYWdlckNvbmZpZykge1xuICAgIGlmIChjb25maWcucmV1c2VUZXh0dXJlcykge1xuICAgICAgdGhpcy5pblVzZVRleHR1cmVzID0gbmV3IE1hcCgpO1xuICAgICAgdGhpcy5pZGxlVGV4dHVyZXMgPSBuZXcgTWFwKCk7XG4gICAgICB0aGlzLnRleHR1cmVMb29rdXAgPSBuZXcgTWFwKCk7XG4gICAgfVxuICB9XG4gIGNyZWF0ZVRleHR1cmVGcm9tTGF5b3V0KFxuICAgICAgZGF0YVR5cGU6IFRlbnNvci5EYXRhVHlwZSwgbGF5b3V0OiBUZXh0dXJlTGF5b3V0LCBkYXRhPzogVGVuc29yLk51bWJlclR5cGUsIHVzYWdlPzogRW5jb2Rlci5Vc2FnZSkge1xuICAgIGNvbnN0IHRleHR1cmVEYXRhVHlwZSA9IHRoaXMudG9FbmNvZGVyVHlwZShkYXRhVHlwZSk7XG5cbiAgICBjb25zdCBlbmNvZGVyID0gdGhpcy5nbENvbnRleHQuZ2V0RW5jb2Rlcih0ZXh0dXJlRGF0YVR5cGUsIGxheW91dC5jaGFubmVscyB8fCAxLCB1c2FnZSk7XG4gICAgaWYgKGxheW91dC5pc1BhY2tlZCAmJiB1c2FnZSA9PT0gRW5jb2Rlci5Vc2FnZS5VcGxvYWRPbmx5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ25vdCBpbXBsZW1lbnRlZCcpO1xuICAgIH1cbiAgICBjb25zdCB3aWR0aCA9IGxheW91dC53aWR0aDtcbiAgICBjb25zdCBoZWlnaHQgPSBsYXlvdXQuaGVpZ2h0O1xuXG4gICAgbGV0IGtleTogc3RyaW5nfHVuZGVmaW5lZDtcbiAgICBsZXQgaW5Vc2VUZXh0dXJlczogV2ViR0xUZXh0dXJlW118dW5kZWZpbmVkO1xuICAgIGlmICh0aGlzLmNvbmZpZy5yZXVzZVRleHR1cmVzKSB7XG4gICAgICBrZXkgPSBgJHt3aWR0aH14JHtoZWlnaHR9XyR7ZW5jb2Rlci5mb3JtYXR9XyR7ZW5jb2Rlci5pbnRlcm5hbEZvcm1hdH1fJHtlbmNvZGVyLnRleHR1cmVUeXBlfWA7XG4gICAgICBpblVzZVRleHR1cmVzID0gdGhpcy5pblVzZVRleHR1cmVzLmdldChrZXkpO1xuICAgICAgaWYgKCFpblVzZVRleHR1cmVzKSB7XG4gICAgICAgIGluVXNlVGV4dHVyZXMgPSBbXTtcbiAgICAgICAgdGhpcy5pblVzZVRleHR1cmVzLnNldChrZXksIGluVXNlVGV4dHVyZXMpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBpZGxlVGV4dHVyZXMgPSB0aGlzLmlkbGVUZXh0dXJlcy5nZXQoa2V5KTtcbiAgICAgIGlmIChpZGxlVGV4dHVyZXMgJiYgaWRsZVRleHR1cmVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgY29uc3QgdGV4dHVyZSA9IGlkbGVUZXh0dXJlcy5wb3AoKSE7XG4gICAgICAgIGluVXNlVGV4dHVyZXMucHVzaCh0ZXh0dXJlKTtcbiAgICAgICAgaWYgKHVzYWdlID09PSBFbmNvZGVyLlVzYWdlLlVwbG9hZE9ubHkpIHtcbiAgICAgICAgICB0aGlzLmdsQ29udGV4dC51cGRhdGVUZXh0dXJlKHRleHR1cmUsIHdpZHRoLCBoZWlnaHQsIGVuY29kZXIsIHRoaXMudG9UZXh0dXJlRGF0YShkYXRhVHlwZSwgZGF0YSkhKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGV4dHVyZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBMb2dnZXIudmVyYm9zZSgnVGV4dHVyZU1hbmFnZXInLCBgQ3JlYXRpbmcgbmV3IHRleHR1cmUgb2Ygc2l6ZSAke2xheW91dC53aWR0aH14JHtsYXlvdXQuaGVpZ2h0fWApO1xuICAgIGNvbnN0IHRleHR1cmUgPSB0aGlzLmdsQ29udGV4dC5hbGxvY2F0ZVRleHR1cmUod2lkdGgsIGhlaWdodCwgZW5jb2RlciwgdGhpcy50b1RleHR1cmVEYXRhKGRhdGFUeXBlLCBkYXRhKSk7XG5cbiAgICBpZiAodGhpcy5jb25maWcucmV1c2VUZXh0dXJlcykge1xuICAgICAgaW5Vc2VUZXh0dXJlcyEucHVzaCh0ZXh0dXJlKTtcbiAgICAgIHRoaXMudGV4dHVyZUxvb2t1cC5zZXQodGV4dHVyZSwga2V5ISk7XG4gICAgfVxuICAgIHJldHVybiB0ZXh0dXJlO1xuICB9XG4gIHJlYWRUZXh0dXJlKHRkOiBUZXh0dXJlRGF0YSwgZGF0YVR5cGU6IFRlbnNvci5EYXRhVHlwZSwgY2hhbm5lbHM/OiBudW1iZXIpOiBUZW5zb3IuTnVtYmVyVHlwZSB7XG4gICAgaWYgKCFjaGFubmVscykge1xuICAgICAgY2hhbm5lbHMgPSAxO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5wcm9maWxlci5ldmVudCgnYmFja2VuZCcsICdUZXh0dXJlTWFuYWdlci5yZWFkVGV4dHVyZScsICgpID0+IHtcbiAgICAgIGNvbnN0IGRhdGFTaXplID0gdGQuc2hhcGUucmVkdWNlKChhLCBiKSA9PiBhICogYikgKiBjaGFubmVscyE7XG4gICAgICBjb25zdCBkYXRhID0gdGhpcy5nbENvbnRleHQucmVhZFRleHR1cmUoXG4gICAgICAgICAgdGQudGV4dHVyZSwgdGQud2lkdGgsIHRkLmhlaWdodCwgZGF0YVNpemUsIHRoaXMudG9FbmNvZGVyVHlwZShkYXRhVHlwZSksIGNoYW5uZWxzISk7XG4gICAgICByZXR1cm4gdGhpcy50b1RlbnNvckRhdGEoZGF0YVR5cGUsIGRhdGEpO1xuICAgIH0pO1xuICB9XG4gIGFzeW5jIHJlYWRUZXh0dXJlQXN5bmModGQ6IFRleHR1cmVEYXRhLCBkYXRhVHlwZTogVGVuc29yLkRhdGFUeXBlLCBjaGFubmVscz86IG51bWJlcik6IFByb21pc2U8VGVuc29yLk51bWJlclR5cGU+IHtcbiAgICBjb25zdCBkYXRhSWQgPSB0ZC50ZW5zb3IuZGF0YUlkO1xuICAgIGlmICghY2hhbm5lbHMpIHtcbiAgICAgIGNoYW5uZWxzID0gMTtcbiAgICB9XG4gICAgaWYgKHRoaXMucGVuZGluZ1JlYWQuaGFzKGRhdGFJZCkpIHtcbiAgICAgIGNvbnN0IHN1YnNjcmliZXJzID0gdGhpcy5wZW5kaW5nUmVhZC5nZXQoZGF0YUlkKTtcbiAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxUZW5zb3IuTnVtYmVyVHlwZT4ocmVzb2x2ZSA9PiBzdWJzY3JpYmVycz8ucHVzaChyZXNvbHZlKSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnByb2ZpbGVyLmV2ZW50KCdiYWNrZW5kJywgJ1RleHR1cmVNYW5hZ2VyLnJlYWRUZXh0dXJlQXN5bmMnLCBhc3luYyAoKSA9PiB7XG4gICAgICB0aGlzLnBlbmRpbmdSZWFkLnNldChkYXRhSWQsIFtdKTtcbiAgICAgIGNvbnN0IGRhdGFTaXplID0gdGQuc2hhcGUucmVkdWNlKChhLCBiKSA9PiBhICogYikgKiBjaGFubmVscyE7XG4gICAgICAvLyBhZGQgYSBmZW5jZSB3YWl0aW5nIGZvciB0aGUgZGF0YSB0byBiZSByZWFkeVxuICAgICAgYXdhaXQgdGhpcy5nbENvbnRleHQuY3JlYXRlQW5kV2FpdEZvckZlbmNlKCk7XG4gICAgICBjb25zdCBkYXRhID0gdGhpcy5nbENvbnRleHQucmVhZFRleHR1cmUoXG4gICAgICAgICAgdGQudGV4dHVyZSwgdGQud2lkdGgsIHRkLmhlaWdodCwgZGF0YVNpemUsIHRoaXMudG9FbmNvZGVyVHlwZShkYXRhVHlwZSksIGNoYW5uZWxzISk7XG4gICAgICBjb25zdCB0ZW5zb3JEYXRhID0gdGhpcy50b1RlbnNvckRhdGEoZGF0YVR5cGUsIGRhdGEpO1xuICAgICAgY29uc3Qgc3Vic2NyaWJlcnMgPSB0aGlzLnBlbmRpbmdSZWFkLmdldChkYXRhSWQpO1xuICAgICAgdGhpcy5wZW5kaW5nUmVhZC5kZWxldGUoZGF0YUlkKTtcbiAgICAgIHN1YnNjcmliZXJzPy5mb3JFYWNoKHJlc29sdmUgPT4gcmVzb2x2ZSh0ZW5zb3JEYXRhKSk7XG4gICAgICByZXR1cm4gdGVuc29yRGF0YTtcbiAgICB9KTtcbiAgfVxuICByZWFkVWludDhUZXh0dXJlQXNGbG9hdCh0ZDogVGV4dHVyZURhdGEpOiBGbG9hdDMyQXJyYXkge1xuICAgIHJldHVybiB0aGlzLnByb2ZpbGVyLmV2ZW50KCdiYWNrZW5kJywgJ1RleHR1cmVNYW5hZ2VyLnJlYWRVaW50OFRleHR1cmVBc0Zsb2F0JywgKCkgPT4ge1xuICAgICAgY29uc3QgZGF0YVNpemUgPSB0ZC5zaGFwZS5yZWR1Y2UoKGEsIGIpID0+IGEgKiBiKTtcbiAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLmdsQ29udGV4dC5yZWFkVGV4dHVyZSh0ZC50ZXh0dXJlLCB0ZC53aWR0aCwgdGQuaGVpZ2h0LCBkYXRhU2l6ZSAqIDQsICdieXRlJywgNCk7XG4gICAgICByZXR1cm4gbmV3IEZsb2F0MzJBcnJheShkYXRhLmJ1ZmZlciwgZGF0YS5ieXRlT2Zmc2V0LCBkYXRhU2l6ZSk7XG4gICAgfSk7XG4gIH1cbiAgcmVsZWFzZVRleHR1cmUodGV4dHVyZURhdGE6IFRleHR1cmVEYXRhLCBkZWxldGVUZXh0dXJlPzogYm9vbGVhbik6IHZvaWQge1xuICAgIGxldCBrZXk6IHN0cmluZ3x1bmRlZmluZWQ7XG4gICAgaWYgKHRoaXMuY29uZmlnLnJldXNlVGV4dHVyZXMpIHtcbiAgICAgIGtleSA9IHRoaXMudGV4dHVyZUxvb2t1cC5nZXQodGV4dHVyZURhdGEudGV4dHVyZSk7XG4gICAgICBpZiAoa2V5KSB7XG4gICAgICAgIGlmIChkZWxldGVUZXh0dXJlKSB7XG4gICAgICAgICAgdGhpcy50ZXh0dXJlTG9va3VwLmRlbGV0ZShrZXkpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGluVXNlVGV4dHVyZXMgPSB0aGlzLmluVXNlVGV4dHVyZXMuZ2V0KGtleSk7XG4gICAgICAgIGlmIChpblVzZVRleHR1cmVzKSB7XG4gICAgICAgICAgY29uc3QgaW5kZXggPSBpblVzZVRleHR1cmVzLmluZGV4T2YodGV4dHVyZURhdGEudGV4dHVyZSk7XG4gICAgICAgICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgICAgICAgaW5Vc2VUZXh0dXJlcy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICAgICAgbGV0IGlkbGVUZXh0dXJlcyA9IHRoaXMuaWRsZVRleHR1cmVzLmdldChrZXkpO1xuICAgICAgICAgICAgaWYgKCFpZGxlVGV4dHVyZXMpIHtcbiAgICAgICAgICAgICAgaWRsZVRleHR1cmVzID0gW107XG4gICAgICAgICAgICAgIHRoaXMuaWRsZVRleHR1cmVzLnNldChrZXksIGlkbGVUZXh0dXJlcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZGxlVGV4dHVyZXMucHVzaCh0ZXh0dXJlRGF0YS50ZXh0dXJlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIWtleSB8fCBkZWxldGVUZXh0dXJlKSB7XG4gICAgICBMb2dnZXIudmVyYm9zZSgnVGV4dHVyZU1hbmFnZXInLCBgRGVsZXRpbmcgdGV4dHVyZSBvZiBzaXplICR7dGV4dHVyZURhdGEud2lkdGh9eCR7dGV4dHVyZURhdGEuaGVpZ2h0fWApO1xuICAgICAgdGhpcy5nbENvbnRleHQuZGVsZXRlVGV4dHVyZSh0ZXh0dXJlRGF0YS50ZXh0dXJlKTtcbiAgICB9XG4gIH1cbiAgdG9UZW5zb3JEYXRhKGRhdGFUeXBlOiBUZW5zb3IuRGF0YVR5cGUsIGRhdGE6IEVuY29kZXIuRGF0YUFycmF5VHlwZSk6IFRlbnNvci5OdW1iZXJUeXBlIHtcbiAgICBzd2l0Y2ggKGRhdGFUeXBlKSB7XG4gICAgICBjYXNlICdpbnQxNic6XG4gICAgICAgIHJldHVybiBkYXRhIGluc3RhbmNlb2YgSW50MTZBcnJheSA/IGRhdGEgOiBJbnQxNkFycmF5LmZyb20oZGF0YSk7XG4gICAgICBjYXNlICdpbnQzMic6XG4gICAgICAgIHJldHVybiBkYXRhIGluc3RhbmNlb2YgSW50MzJBcnJheSA/IGRhdGEgOiBJbnQzMkFycmF5LmZyb20oZGF0YSk7XG4gICAgICBjYXNlICdpbnQ4JzpcbiAgICAgICAgcmV0dXJuIGRhdGEgaW5zdGFuY2VvZiBJbnQ4QXJyYXkgPyBkYXRhIDogSW50OEFycmF5LmZyb20oZGF0YSk7XG4gICAgICBjYXNlICd1aW50MTYnOlxuICAgICAgICByZXR1cm4gZGF0YSBpbnN0YW5jZW9mIFVpbnQxNkFycmF5ID8gZGF0YSA6IFVpbnQxNkFycmF5LmZyb20oZGF0YSk7XG4gICAgICBjYXNlICd1aW50MzInOlxuICAgICAgICByZXR1cm4gZGF0YSBpbnN0YW5jZW9mIFVpbnQzMkFycmF5ID8gZGF0YSA6IFVpbnQzMkFycmF5LmZyb20oZGF0YSk7XG4gICAgICBjYXNlICd1aW50OCc6XG4gICAgICBjYXNlICdib29sJzpcbiAgICAgICAgcmV0dXJuIGRhdGEgaW5zdGFuY2VvZiBVaW50OEFycmF5ID8gZGF0YSA6IFVpbnQ4QXJyYXkuZnJvbShkYXRhKTtcbiAgICAgIGNhc2UgJ2Zsb2F0MzInOlxuICAgICAgICByZXR1cm4gZGF0YSBpbnN0YW5jZW9mIEZsb2F0MzJBcnJheSA/IGRhdGEgOiBGbG9hdDMyQXJyYXkuZnJvbShkYXRhKTtcbiAgICAgIGNhc2UgJ2Zsb2F0NjQnOlxuICAgICAgICByZXR1cm4gZGF0YSBpbnN0YW5jZW9mIEZsb2F0NjRBcnJheSA/IGRhdGEgOiBGbG9hdDY0QXJyYXkuZnJvbShkYXRhKTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVGVuc29yRGF0YSB0eXBlICR7ZGF0YVR5cGV9IGlzIG5vdCBzdXBwb3J0ZWRgKTtcbiAgICB9XG4gIH1cbiAgdG9UZXh0dXJlRGF0YShkYXRhVHlwZTogVGVuc29yLkRhdGFUeXBlLCBkYXRhOiBUZW5zb3IuTnVtYmVyVHlwZXx1bmRlZmluZWQpOiBFbmNvZGVyLkRhdGFBcnJheVR5cGV8dW5kZWZpbmVkIHtcbiAgICBpZiAoIWRhdGEpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHJldHVybiAoZGF0YSBpbnN0YW5jZW9mIEZsb2F0MzJBcnJheSkgPyBkYXRhIDogbmV3IEZsb2F0MzJBcnJheShkYXRhKTtcbiAgICAvKlxuICAgIHN3aXRjaCAoZGF0YVR5cGUpIHtcbiAgICAgIGNhc2UgJ2ludDE2JzpcbiAgICAgIGNhc2UgJ2ludDMyJzpcbiAgICAgIGNhc2UgJ3VpbnQxNic6XG4gICAgICBjYXNlICd1aW50MzInOlxuICAgICAgICByZXR1cm4gKGRhdGEuY29uc3RydWN0b3IgPT09IFVpbnQzMkFycmF5KSA/IGRhdGEgYXMgVWludDMyQXJyYXkgOiBuZXcgVWludDMyQXJyYXkoZGF0YSk7XG4gICAgICBjYXNlICdpbnQ4JzpcbiAgICAgIGNhc2UgJ3VpbnQ4JzpcbiAgICAgIGNhc2UgJ2Jvb2wnOlxuICAgICAgICByZXR1cm4gKGRhdGEuY29uc3RydWN0b3IgPT09IFVpbnQ4QXJyYXkpID8gZGF0YSBhcyBVaW50OEFycmF5IDogbmV3IFVpbnQ4QXJyYXkoZGF0YSk7XG4gICAgICBjYXNlICdmbG9hdDMyJzpcbiAgICAgIGNhc2UgJ2Zsb2F0NjQnOlxuICAgICAgICByZXR1cm4gKGRhdGEuY29uc3RydWN0b3IgPT09IEZsb2F0MzJBcnJheSkgPyBkYXRhIGFzIEZsb2F0MzJBcnJheSA6IG5ldyBGbG9hdDMyQXJyYXkoZGF0YSk7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFRlbnNvckRhdGEgdHlwZSAke2RhdGFUeXBlfSBpcyBub3Qgc3VwcG9ydGVkYCk7XG4gICAgfVxuICAgICovXG4gIH1cbiAgdG9FbmNvZGVyVHlwZShfZGF0YVR5cGU6IFRlbnNvci5EYXRhVHlwZSk6IEVuY29kZXIuRGF0YVR5cGUge1xuICAgIHJldHVybiAnZmxvYXQnO1xuICAgIC8vIHN3aXRjaCAoZGF0YVR5cGUpIHtcbiAgICAvLyAgIGNhc2UgJ2ludDE2JzpcbiAgICAvLyAgIGNhc2UgJ2ludDMyJzpcbiAgICAvLyAgIGNhc2UgJ3VpbnQxNic6XG4gICAgLy8gICBjYXNlICd1aW50MzInOlxuICAgIC8vICAgICByZXR1cm4gJ2ludCc7XG4gICAgLy8gICBjYXNlICd1aW50OCc6XG4gICAgLy8gICBjYXNlICdib29sJzpcbiAgICAvLyAgICAgcmV0dXJuICdieXRlJztcbiAgICAvLyAgIGNhc2UgJ2Zsb2F0MzInOlxuICAgIC8vICAgY2FzZSAnZmxvYXQ2NCc6XG4gICAgLy8gICAgIHJldHVybiAnZmxvYXQnO1xuICAgIC8vICAgZGVmYXVsdDpcbiAgICAvLyAgICAgdGhyb3cgbmV3IEVycm9yKGBUZW5zb3JEYXRhIHR5cGUgJHtkYXRhVHlwZX0gaXMgbm90IHN1cHBvcnRlZGApO1xuICAgIC8vIH1cbiAgfVxuICBjbGVhckFjdGl2ZVRleHR1cmVzKCk6IHZvaWQge1xuICAgIHRoaXMuZ2xDb250ZXh0LmNsZWFyQWN0aXZlVGV4dHVyZXMoKTtcbiAgfVxufVxuIiwiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7VGVuc29yfSBmcm9tICcuLi8uLi90ZW5zb3InO1xuXG4vKipcbiAqIExheW91dCBpbmZvIGlzIHVzZWQgZm9yIG1hcHBpbmcgbi1kaW1lbnNpb25hbCBhcnJheSB0byAyRCB0ZXh0dXJlc1xuICogVGhlIGxheW91dCBpcyBjcmVhdGVkIGJ5IHRoZSBUZXh0dXJlTGF5b3V0U3RyYXRlZ3kgYmFzZWQgb25cbiAqIHRoZSBUZW5zb3IncyBkaW1lbnNpb25zIGFuZCBzdHJpZGVzXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVGV4dHVyZUxheW91dCB7XG4gIHdpZHRoOiBudW1iZXI7XG4gIGhlaWdodDogbnVtYmVyO1xuICAvKipcbiAgICogc3BlY2lmeSB0aGUgbnVtYmVyIG9mIHZhbHVlIHRoYXQgZW5jb2RlZCBpbiBhIHNpbmdsZSBwaXhlbFxuICAgKi9cbiAgY2hhbm5lbHM6IDF8MnwzfDQ7XG4gIC8qKlxuICAgKiB3aGV0aGVyIGluIHBhY2tlZCBtb2RlIG9yIG5vdFxuICAgKi9cbiAgaXNQYWNrZWQ/OiBib29sZWFuO1xuICAvKipcbiAgICogdGhlIG5vcm1hbGl6ZWQgc2hhcGVcbiAgICovXG4gIHNoYXBlOiByZWFkb25seSBudW1iZXJbXTtcbiAgLyoqXG4gICAqIHRoZSBzdHJpZGUgb2YgZWFjaCBkaW1lbnNpb25zLCBjYWxjdWxhdGVkIGFjY29yZGluZyB0byBzaGFwZVxuICAgKi9cbiAgc3RyaWRlczogcmVhZG9ubHkgbnVtYmVyW107XG4gIC8qKlxuICAgKiB0aGUgb3JpZ2luYWwgc2hhcGUoZGltcykgb2YgdGhlIGNvcnJlc3BvbmRpbmcgdGVuc29yXG4gICAqL1xuICB1bnBhY2tlZFNoYXBlOiByZWFkb25seSBudW1iZXJbXTtcblxuICByZXZlcnNlZFdIPzogYm9vbGVhbjtcbn1cbmV4cG9ydCBpbnRlcmZhY2UgVGV4dHVyZURhdGEgZXh0ZW5kcyBUZXh0dXJlTGF5b3V0IHtcbiAgdGVuc29yOiBUZW5zb3I7XG4gIHRleHR1cmU6IFdlYkdMVGV4dHVyZTtcbn1cblxuZXhwb3J0IGVudW0gVGV4dHVyZVR5cGUge1xuICB1bnBhY2tlZCwgICAgICAgICAgICAgIC8vIDwtLSBub3JtYWwgdW5wYWNrZWQgdGV4dHVyZVxuICB1bnBhY2tlZFJldmVyc2VkLCAgICAgIC8vIDwtLSB1bnBhY2tlZCB0ZXh0dXJlIHVzZWQgaW4gb2xkIE9OTlguanMgaW1wbGVtZW50YXRpb24gKGRlcHJlY2F0ZWQpXG4gIHBhY2tlZCwgICAgICAgICAgICAgICAgLy8gPC0tIG5vcm1hbCBwYWNrZWQgdGV4dHVyZVxuICBkb3dubG9hZFVpbnQ4QXNGbG9hdCwgIC8vIDwtLSBPTkxZIHVzZWQgaW4gdGV4dHVyZSBkb3dubG9hZGluZyBmb3IgaU9TIGRldmljZXNcbiAgcGFja2VkTGFzdERpbWVuc2lvbiAgICAvLyA8LS0gT05MWSB1c2VkIGluIG9sZCBPTk5YLmpzIENvbnYgaW1wbGVtZW50YXRpb24gZm9yIGlucHV0IFcgKGRlcHJlY2F0ZWQpXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGVuc29ySW5mbyB7XG4gIGlkPzogVGVuc29yLklkO1xuICBkaW1zOiByZWFkb25seSBudW1iZXJbXTtcbiAgdHlwZTogVGVuc29yLkRhdGFUeXBlO1xuICB0ZXh0dXJlVHlwZTogVGV4dHVyZVR5cGU7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUHJvZ3JhbVZhcmlhYmxlIHtcbiAgdHlwZTogJ2Zsb2F0J3wnaW50JztcbiAgbmFtZTogc3RyaW5nO1xuICBhcnJheUxlbmd0aD86IG51bWJlcjtcbiAgZGF0YTogbnVtYmVyfG51bWJlcltdO1xufVxuXG4vKipcbiAqIEEgc2V0IG9mIG1ldGFkYXRhIG9mIGEgc2hhZGVyIHByb2dyYW0uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUHJvZ3JhbU1ldGFkYXRhIHtcbiAgLyoqXG4gICAqIHRoZSBuYW1lIG9mIHRoZSBwcm9ncmFtLiB1c2VkIGZvciBkZWJ1Z2dpbmcgYW5kIHByb2ZpbGluZ1xuICAgKi9cbiAgbmFtZTogc3RyaW5nO1xuICAvKipcbiAgICogdGV4dHVyZSB0eXBlcyBmb3IgZWFjaCBpbnB1dFxuICAgKi9cbiAgaW5wdXRUeXBlczogVGV4dHVyZVR5cGVbXTtcbiAgLyoqXG4gICAqIG5hbWVzIG9mIGVhY2ggaW5wdXRcbiAgICovXG4gIGlucHV0TmFtZXM6IHN0cmluZ1tdO1xuICAvKipcbiAgICogYW4gb3B0aW9uYWwgc3RyaW5nIGFzIGEgY2FjaGUgaGludCBpbiB0aGUgYXJ0aWZhY3QgY2FjaGVcbiAgICovXG4gIGNhY2hlSGludD86IHN0cmluZztcbn1cblxuLyoqXG4gKiBBIFByb2dyYW1JbmZvTG9hZGVyIGFsbG93c1xuICovXG5leHBvcnQgaW50ZXJmYWNlIFByb2dyYW1JbmZvTG9hZGVyIGV4dGVuZHMgUHJvZ3JhbU1ldGFkYXRhIHtcbiAgLyoqXG4gICAqIGEgZnVuY3Rpb24gdG8gZ2V0IHRoZSBwcm9ncmFtIGluZm9cbiAgICovXG4gIGdldCgpOiBQcm9ncmFtSW5mbztcbn1cblxuLyoqXG4gKiBBIHNldCBvZiBkYXRhIHRoYXQgcmVwcmVzZW50IGEgc2hhZGVyIHByb2dyYW1cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQcm9ncmFtSW5mbyBleHRlbmRzIFByb2dyYW1NZXRhZGF0YSB7XG4gIC8qKlxuICAgKiBpbmZvcm1hdGlvbiBvZiB1bmlmb3JtIHZhcmlhYmxlc1xuICAgKi9cbiAgdmFyaWFibGVzPzogUHJvZ3JhbVZhcmlhYmxlW107XG4gIC8qKlxuICAgKiB0ZW5zb3IgaW5mbyBmb3Igb3V0cHV0XG4gICAqL1xuICBvdXRwdXQ6IFRlbnNvckluZm87XG4gIC8qKlxuICAgKiB0aGUgc2hhZGVyJ3MgcHJvY2Vzc2luZyBzb3VyY2UgY29kZVxuICAgKi9cbiAgc2hhZGVyU291cmNlOiBzdHJpbmc7XG4gIC8qKlxuICAgKiB3aGV0aGVyIHRoZSBzaGFkZXIgc291cmNlIGNvbnRhaW5zIGEgY3VzdG9taXplZCBtYWluIGZ1bmN0aW9uIGltcGxlbWVudGF0aW9uXG4gICAqL1xuICBoYXNNYWluPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBWYXJpYWJsZUluZm8ge1xuICB0eXBlOiAnZmxvYXQnfCdpbnQnO1xuICBuYW1lOiBzdHJpbmc7XG4gIGFycmF5TGVuZ3RoPzogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFByb2dyYW1WYXJpYWJsZSB7XG4gIHR5cGU6ICdmbG9hdCd8J2ludCc7XG4gIG5hbWU6IHN0cmluZztcbiAgYXJyYXlMZW5ndGg/OiBudW1iZXI7XG4gIGRhdGE6IG51bWJlcnxudW1iZXJbXTtcbn1cblxuLyoqXG4gKiBJbmZvcm1hdGlvbiBvZiB1bmlmb3JtcyB0aGF0IHNoYWRlciB1c2VzXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVW5pZm9ybUluZm8ge1xuICB0eXBlOiAnc2FtcGxlcjJEJ3xWYXJpYWJsZUluZm9bJ3R5cGUnXTtcbiAgbmFtZTogc3RyaW5nO1xuICBhcnJheUxlbmd0aD86IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBVbmlmb3JtTG9jYXRpb24gZXh0ZW5kcyBVbmlmb3JtSW5mbyB7XG4gIGxvY2F0aW9uOiBXZWJHTFVuaWZvcm1Mb2NhdGlvbjtcbn1cblxuLyoqXG4gKiBBcnRpZmFjdCBpcyB0aGUgcmVzdWx0IG9mIGNvbXBpbGF0aW9uXG4gKiBJdCBkb2VzIG5vdCBjb250YWluIGlucHV0IG9mIG91dHB1dCBkYXRhXG4gKiBIb3dldmVyIGFueXRoaW5nIHRoYXQgY291bGQgYmUgcnVuIGFzIGEgXCJwcm9ncmFtXCJcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBcnRpZmFjdCB7XG4gIHByb2dyYW1JbmZvOiBQcm9ncmFtSW5mbztcbiAgcHJvZ3JhbTogV2ViR0xQcm9ncmFtO1xuICB1bmlmb3JtTG9jYXRpb25zOiBVbmlmb3JtTG9jYXRpb25bXTtcbiAgYXR0cmliTG9jYXRpb25zOiB7cG9zaXRpb246IG51bWJlcjsgdGV4dHVyZUNvb3JkOiBudW1iZXJ9O1xufVxuZXhwb3J0IGRlY2xhcmUgbmFtZXNwYWNlIEFydGlmYWN0IHtcbiAgdHlwZSBVbmlmb3JtTG9jYXRpb25zID0gQXJ0aWZhY3RbJ3VuaWZvcm1Mb2NhdGlvbnMnXTtcbiAgdHlwZSBBdHRyaWJMb2NhdGlvbnMgPSBBcnRpZmFjdFsnYXR0cmliTG9jYXRpb25zJ107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVW5pZm9ybURhdGEge1xuICBbbmFtZTogc3RyaW5nXTogbnVtYmVyfG51bWJlcltdO1xufVxuIiwiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7YXNzZXJ0fSBmcm9tICcuLi8uLi91dGlsJztcbi8qKlxuICogR2l2ZW4gYSBub24gUkdCQSBzaGFwZSBjYWxjdWxhdGUgdGhlIFIgdmVyc2lvblxuICogSXQgaXMgYXNzdW1lZCB0aGF0IHRoZSBkaW1lbnNpb25zIGFyZSBtdWx0aXBsZXMgb2YgZ2l2ZW4gY2hhbm5lbHNcbiAqIE5PVEU6IGl0IGlzIGFsd2F5cyB0aGUgbGFzdCBkaW0gdGhhdCBnZXRzIHBhY2tlZC5cbiAqIEBwYXJhbSB1bnBhY2tlZFNoYXBlIG9yaWdpbmFsIHNoYXBlIHRvIGNyZWF0ZSBhIHBhY2tlZCB2ZXJzaW9uIGZyb21cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFBhY2tlZFNoYXBlKHVucGFja2VkU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICBjb25zdCBsZW4gPSB1bnBhY2tlZFNoYXBlLmxlbmd0aDtcbiAgcmV0dXJuIHVucGFja2VkU2hhcGUuc2xpY2UoMCwgbGVuIC0gMSkuY29uY2F0KHVucGFja2VkU2hhcGVbbGVuIC0gMV0gLyA0KTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlcGVhdGVkVHJ5KFxuICAgIGNoZWNrRm46ICgpID0+IGJvb2xlYW4sIGRlbGF5Rm4gPSAoX2NvdW50ZXI6IG51bWJlcikgPT4gMCwgbWF4Q291bnRlcj86IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICByZXR1cm4gbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGxldCB0cnlDb3VudCA9IDA7XG5cbiAgICBjb25zdCB0cnlGbiA9ICgpID0+IHtcbiAgICAgIGlmIChjaGVja0ZuKCkpIHtcbiAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHRyeUNvdW50Kys7XG5cbiAgICAgIGNvbnN0IG5leHRCYWNrb2ZmID0gZGVsYXlGbih0cnlDb3VudCk7XG5cbiAgICAgIGlmIChtYXhDb3VudGVyICE9IG51bGwgJiYgdHJ5Q291bnQgPj0gbWF4Q291bnRlcikge1xuICAgICAgICByZWplY3QoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgc2V0VGltZW91dCh0cnlGbiwgbmV4dEJhY2tvZmYpO1xuICAgIH07XG5cbiAgICB0cnlGbigpO1xuICB9KTtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZXMgdGhlIGZ1bmN0aW9uIG5hbWUgZnJvbSBhbiBpbnB1dCBzYW1wbGVyIG5hbWUuXG4gKiBAcGFyYW0gc2FtcGxlck5hbWUgTmFtZSBvZiB0aGUgc2FtcGxlci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlU2hhZGVyRnVuY05hbWVGcm9tSW5wdXRTYW1wbGVyTmFtZShzYW1wbGVyTmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgYXNzZXJ0KHR5cGVvZiBzYW1wbGVyTmFtZSAhPT0gJ3VuZGVmaW5lZCcgJiYgc2FtcGxlck5hbWUubGVuZ3RoICE9PSAwLCAoKSA9PiAnZW1wdHkgc3RyaW5nIGZvdW5kIGZvciBzYW1wbGVyIG5hbWUnKTtcbiAgcmV0dXJuICdnZXQnICsgc2FtcGxlck5hbWUuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBzYW1wbGVyTmFtZS5zbGljZSgxKTtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZXMgdGhlIGZ1bmN0aW9uIG5hbWUgZnJvbSBhbiBpbnB1dCBzYW1wbGVyIG5hbWUgYXQgb3V0cHV0IGNvb3JkaW5hdGVzLlxuICogQHBhcmFtIHNhbXBsZXJOYW1lIE5hbWUgb2YgdGhlIHNhbXBsZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZVNoYWRlckZ1bmNOYW1lRnJvbUlucHV0U2FtcGxlck5hbWVBdE91dENvb3JkcyhzYW1wbGVyTmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgYXNzZXJ0KHR5cGVvZiBzYW1wbGVyTmFtZSAhPT0gJ3VuZGVmaW5lZCcgJiYgc2FtcGxlck5hbWUubGVuZ3RoICE9PSAwLCAoKSA9PiAnZW1wdHkgc3RyaW5nIGZvdW5kIGZvciBzYW1wbGVyIG5hbWUnKTtcbiAgcmV0dXJuICdnZXQnICsgc2FtcGxlck5hbWUuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBzYW1wbGVyTmFtZS5zbGljZSgxKSArICdBdE91dENvb3Jkcyc7XG59XG5cbi8qKiBSZXR1cm5zIGEgbmV3IGlucHV0IHNoYXBlIChhIGNvcHkpIHRoYXQgaGFzIGEgc3F1ZWV6ZWQgbG9naWNhbCBzaGFwZS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzcXVlZXplSW5wdXRTaGFwZShpbnB1dFNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgc3F1ZWV6ZWRTaGFwZTogbnVtYmVyW10pOiBudW1iZXJbXSB7XG4gIC8vIERlZXAgY29weS5cbiAgbGV0IG5ld0lucHV0U2hhcGU6IG51bWJlcltdID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShpbnB1dFNoYXBlKSk7XG4gIG5ld0lucHV0U2hhcGUgPSBzcXVlZXplZFNoYXBlO1xuICByZXR1cm4gbmV3SW5wdXRTaGFwZTtcbn1cblxuLyoqIFJldHVybnMgYSBsaXN0IG9mIHNxdWVlemVkIHBhcmFtZXRlcnMgZm9yIHNoYWRlciBmdW5jdGlvbnMgKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRTcXVlZXplZFBhcmFtcyhwYXJhbXM6IHN0cmluZ1tdLCBrZXB0RGltczogbnVtYmVyW10pOiBzdHJpbmcge1xuICByZXR1cm4ga2VwdERpbXMubWFwKGQgPT4gcGFyYW1zW2RdKS5qb2luKCcsICcpO1xufVxuXG4vKiogUmV0dXJucyB0aGUgZGF0YSB0eXBlIGZvciBkaWZmZXJlbnQgcmFua3MuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q29vcmRzRGF0YVR5cGUocmFuazogbnVtYmVyKTogc3RyaW5nIHtcbiAgaWYgKHJhbmsgPD0gMSkge1xuICAgIHJldHVybiAnaW50JztcbiAgfSBlbHNlIGlmIChyYW5rID09PSAyKSB7XG4gICAgcmV0dXJuICdpdmVjMic7XG4gIH0gZWxzZSBpZiAocmFuayA9PT0gMykge1xuICAgIHJldHVybiAnaXZlYzMnO1xuICB9IGVsc2UgaWYgKHJhbmsgPT09IDQpIHtcbiAgICByZXR1cm4gJ2l2ZWM0JztcbiAgfSBlbHNlIGlmIChyYW5rID09PSA1KSB7XG4gICAgcmV0dXJuICdpdmVjNSc7XG4gIH0gZWxzZSBpZiAocmFuayA9PT0gNikge1xuICAgIHJldHVybiAnaXZlYzYnO1xuICB9IGVsc2Uge1xuICAgIHRocm93IEVycm9yKGBHUFUgZm9yIHJhbmsgJHtyYW5rfSBpcyBub3QgeWV0IHN1cHBvcnRlZGApO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRHbENoYW5uZWxzKHJhbmsgPSA2KTogc3RyaW5nW10ge1xuICByZXR1cm4gWyd4JywgJ3knLCAneicsICd3JywgJ3UnLCAndiddLnNsaWNlKDAsIHJhbmspO1xufVxuIiwiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7TG9nZ2VyfSBmcm9tICcuLi8uLi9pbnN0cnVtZW50JztcblxuaW1wb3J0IHtXZWJHTENvbnRleHR9IGZyb20gJy4vd2ViZ2wtY29udGV4dCc7XG5cbmNvbnN0IGNhY2hlOiB7W2NvbnRleHRJZDogc3RyaW5nXTogV2ViR0xDb250ZXh0fSA9IHt9O1xuXG4vKipcbiAqIFRoaXMgZmFjdG9yeSBmdW5jdGlvbiBjcmVhdGVzIHByb3BlciBXZWJHTFJlbmRlcmluZ0NvbnRleHQgYmFzZWQgb25cbiAqIHRoZSBjdXJyZW50IGJyb3dzZXJzIGNhcGFiaWxpdGllc1xuICogVGhlIG9yZGVyIGlzIGZyb20gaGlnaGVyL21vc3QgcmVjZW50IHZlcnNpb25zIHRvIG1vc3QgYmFzaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVdlYkdMQ29udGV4dChjb250ZXh0SWQ/OiAnd2ViZ2wnfCd3ZWJnbDInKTogV2ViR0xDb250ZXh0IHtcbiAgbGV0IGNvbnRleHQ6IFdlYkdMQ29udGV4dHx1bmRlZmluZWQ7XG4gIGlmICgoIWNvbnRleHRJZCB8fCBjb250ZXh0SWQgPT09ICd3ZWJnbDInKSAmJiAnd2ViZ2wyJyBpbiBjYWNoZSkge1xuICAgIGNvbnRleHQgPSBjYWNoZS53ZWJnbDI7XG4gIH0gZWxzZSBpZiAoKCFjb250ZXh0SWQgfHwgY29udGV4dElkID09PSAnd2ViZ2wnKSAmJiAnd2ViZ2wnIGluIGNhY2hlKSB7XG4gICAgY29udGV4dCA9IGNhY2hlLndlYmdsO1xuICB9XG5cbiAgY29udGV4dCA9IGNvbnRleHQgfHwgY3JlYXRlTmV3V2ViR0xDb250ZXh0KGNvbnRleHRJZCk7XG4gIGNvbnRleHRJZCA9IGNvbnRleHRJZCB8fCBjb250ZXh0LnZlcnNpb24gPT09IDEgPyAnd2ViZ2wnIDogJ3dlYmdsMic7XG4gIGNvbnN0IGdsID0gY29udGV4dC5nbDtcblxuICBjYWNoZVtjb250ZXh0SWRdID0gY29udGV4dDtcblxuICBpZiAoZ2wuaXNDb250ZXh0TG9zdCgpKSB7XG4gICAgZGVsZXRlIGNhY2hlW2NvbnRleHRJZF07XG4gICAgcmV0dXJuIGNyZWF0ZVdlYkdMQ29udGV4dChjb250ZXh0SWQpO1xuICB9XG5cbiAgZ2wuZGlzYWJsZShnbC5ERVBUSF9URVNUKTtcbiAgZ2wuZGlzYWJsZShnbC5TVEVOQ0lMX1RFU1QpO1xuICBnbC5kaXNhYmxlKGdsLkJMRU5EKTtcbiAgZ2wuZGlzYWJsZShnbC5ESVRIRVIpO1xuICBnbC5kaXNhYmxlKGdsLlBPTFlHT05fT0ZGU0VUX0ZJTEwpO1xuICBnbC5kaXNhYmxlKGdsLlNBTVBMRV9DT1ZFUkFHRSk7XG4gIGdsLmVuYWJsZShnbC5TQ0lTU09SX1RFU1QpO1xuICBnbC5lbmFibGUoZ2wuQ1VMTF9GQUNFKTtcbiAgZ2wuY3VsbEZhY2UoZ2wuQkFDSyk7XG5cbiAgcmV0dXJuIGNvbnRleHQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVOZXdXZWJHTENvbnRleHQoY29udGV4dElkPzogJ3dlYmdsJ3wnd2ViZ2wyJyk6IFdlYkdMQ29udGV4dCB7XG4gIGNvbnN0IGNhbnZhcyA9IGNyZWF0ZUNhbnZhcygpO1xuICBjb25zdCBjb250ZXh0QXR0cmlidXRlczogV2ViR0xDb250ZXh0QXR0cmlidXRlcyA9IHtcbiAgICBhbHBoYTogZmFsc2UsXG4gICAgZGVwdGg6IGZhbHNlLFxuICAgIGFudGlhbGlhczogZmFsc2UsXG4gICAgc3RlbmNpbDogZmFsc2UsXG4gICAgcHJlc2VydmVEcmF3aW5nQnVmZmVyOiBmYWxzZSxcbiAgICBwcmVtdWx0aXBsaWVkQWxwaGE6IGZhbHNlLFxuICAgIGZhaWxJZk1ham9yUGVyZm9ybWFuY2VDYXZlYXQ6IGZhbHNlXG4gIH07XG4gIGxldCBnbDogV2ViR0xSZW5kZXJpbmdDb250ZXh0fG51bGw7XG4gIGNvbnN0IGNhID0gY29udGV4dEF0dHJpYnV0ZXM7XG4gIGlmICghY29udGV4dElkIHx8IGNvbnRleHRJZCA9PT0gJ3dlYmdsMicpIHtcbiAgICBnbCA9IGNhbnZhcy5nZXRDb250ZXh0KCd3ZWJnbDInLCBjYSk7XG4gICAgaWYgKGdsKSB7XG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gbmV3IFdlYkdMQ29udGV4dChnbCwgMik7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgTG9nZ2VyLndhcm5pbmcoJ0dsQ29udGV4dEZhY3RvcnknLCBgZmFpbGVkIHRvIGNyZWF0ZSBXZWJHTENvbnRleHQgdXNpbmcgY29udGV4dElkICd3ZWJnbDInLiBFcnJvcjogJHtlcnJ9YCk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGlmICghY29udGV4dElkIHx8IGNvbnRleHRJZCA9PT0gJ3dlYmdsJykge1xuICAgIGdsID0gY2FudmFzLmdldENvbnRleHQoJ3dlYmdsJywgY2EpIHx8IGNhbnZhcy5nZXRDb250ZXh0KCdleHBlcmltZW50YWwtd2ViZ2wnLCBjYSkgYXMgV2ViR0xSZW5kZXJpbmdDb250ZXh0O1xuICAgIGlmIChnbCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIG5ldyBXZWJHTENvbnRleHQoZ2wsIDEpO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIExvZ2dlci53YXJuaW5nKFxuICAgICAgICAgICAgJ0dsQ29udGV4dEZhY3RvcnknLFxuICAgICAgICAgICAgYGZhaWxlZCB0byBjcmVhdGUgV2ViR0xDb250ZXh0IHVzaW5nIGNvbnRleHRJZCAnd2ViZ2wnIG9yICdleHBlcmltZW50YWwtd2ViZ2wnLiBFcnJvcjogJHtlcnJ9YCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdGhyb3cgbmV3IEVycm9yKCdXZWJHTCBpcyBub3Qgc3VwcG9ydGVkJyk7XG59XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cbmRlY2xhcmUgbGV0IE9mZnNjcmVlbkNhbnZhczoge25ldyAod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpOiBIVE1MQ2FudmFzRWxlbWVudH07XG5cbmZ1bmN0aW9uIGNyZWF0ZUNhbnZhcygpOiBIVE1MQ2FudmFzRWxlbWVudCB7XG4gIGlmICh0eXBlb2YgZG9jdW1lbnQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgaWYgKHR5cGVvZiBPZmZzY3JlZW5DYW52YXMgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdmYWlsZWQgdG8gY3JlYXRlIGNhbnZhczogT2Zmc2NyZWVuQ2FudmFzIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBPZmZzY3JlZW5DYW52YXMoMSwgMSk7XG4gIH1cbiAgY29uc3QgY2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICBjYW52YXMud2lkdGggPSAxO1xuICBjYW52YXMuaGVpZ2h0ID0gMTtcbiAgcmV0dXJuIGNhbnZhcztcbn1cbiIsIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge2Vudn0gZnJvbSAnb25ueHJ1bnRpbWUtY29tbW9uJztcblxuaW1wb3J0ICogYXMgRGF0YUVuY29kZXJzIGZyb20gJy4vdGV4dHVyZS1kYXRhLWVuY29kZXInO1xuaW1wb3J0IHtEYXRhRW5jb2RlciwgRW5jb2Rlcn0gZnJvbSAnLi90ZXh0dXJlLWRhdGEtZW5jb2Rlcic7XG5pbXBvcnQge3JlcGVhdGVkVHJ5fSBmcm9tICcuL3V0aWxzJztcblxuZXhwb3J0IGludGVyZmFjZSBGZW5jZUNvbnRleHQge1xuICBxdWVyeTogV2ViR0xTeW5jfG51bGw7XG4gIGlzRmVuY2VQYXNzZWQoKTogYm9vbGVhbjtcbn1cblxudHlwZSBQb2xsSXRlbSA9IHtcbiAgaXNEb25lRm46ICgpID0+IGJvb2xlYW47IHJlc29sdmVGbjogKCkgPT4gdm9pZDtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBsaW5lYXJTZWFyY2hMYXN0VHJ1ZShhcnI6IEFycmF5PCgpID0+IGJvb2xlYW4+KTogbnVtYmVyIHtcbiAgbGV0IGkgPSAwO1xuICBmb3IgKDsgaSA8IGFyci5sZW5ndGg7ICsraSkge1xuICAgIGNvbnN0IGlzRG9uZSA9IGFycltpXSgpO1xuICAgIGlmICghaXNEb25lKSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGkgLSAxO1xufVxuXG4vKipcbiAqIEFic3RyYWN0aW9uIGFuZCB3cmFwcGVyIGFyb3VuZCBXZWJHTFJlbmRlcmluZ0NvbnRleHQgYW5kIGl0cyBvcGVyYXRpb25zXG4gKi9cbmV4cG9ydCBjbGFzcyBXZWJHTENvbnRleHQge1xuICBnbDogV2ViR0xSZW5kZXJpbmdDb250ZXh0O1xuICB2ZXJzaW9uOiAxfDI7XG5cbiAgcHJpdmF0ZSB2ZXJ0ZXhidWZmZXI6IFdlYkdMQnVmZmVyO1xuICBwcml2YXRlIGZyYW1lYnVmZmVyOiBXZWJHTEZyYW1lYnVmZmVyO1xuXG4gIC8vIFdlYkdMIGZsYWdzIGFuZCB2aXRhbCBwYXJhbWV0ZXJzXG4gIHByaXZhdGUgaXNGbG9hdFRleHR1cmVBdHRhY2hhYmxlVG9GcmFtZUJ1ZmZlcjogYm9vbGVhbjtcbiAgaXNGbG9hdDMyRG93bmxvYWRTdXBwb3J0ZWQ6IGJvb2xlYW47XG4gIGlzUmVuZGVyRmxvYXQzMlN1cHBvcnRlZDogYm9vbGVhbjtcbiAgaXNCbGVuZFN1cHBvcnRlZDogYm9vbGVhbjtcbiAgbWF4VGV4dHVyZVNpemU6IG51bWJlcjtcbiAgLy8gcHJpdmF0ZSBtYXhDb21iaW5lZFRleHR1cmVJbWFnZVVuaXRzOiBudW1iZXI7XG4gIHByaXZhdGUgbWF4VGV4dHVyZUltYWdlVW5pdHM6IG51bWJlcjtcbiAgLy8gcHJpdmF0ZSBtYXhDdWJlTWFwVGV4dHVyZVNpemU6IG51bWJlcjtcbiAgLy8gcHJpdmF0ZSBzaGFkaW5nTGFuZ3VhZ2VWZXJzaW9uOiBzdHJpbmc7XG4gIC8vIHByaXZhdGUgd2ViZ2xWZW5kb3I6IHN0cmluZztcbiAgLy8gcHJpdmF0ZSB3ZWJnbFZlcnNpb246IHN0cmluZztcblxuICAvLyBXZWJHTDIgZmxhZ3MgYW5kIHZpdGFsIHBhcmFtZXRlcnNcbiAgLy8gcHJpdmF0ZSBtYXgzRFRleHR1cmVTaXplOiBudW1iZXI7XG4gIC8vIHByaXZhdGUgbWF4QXJyYXlUZXh0dXJlTGF5ZXJzOiBudW1iZXI7XG4gIC8vIHByaXZhdGUgbWF4Q29sb3JBdHRhY2htZW50czogbnVtYmVyO1xuICAvLyBwcml2YXRlIG1heERyYXdCdWZmZXJzOiBudW1iZXI7XG5cbiAgLy8gV2ViR0wgZXh0ZW5zaW9uc1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY2FtZWxjYXNlXG4gIHRleHR1cmVGbG9hdEV4dGVuc2lvbjogT0VTX3RleHR1cmVfZmxvYXR8bnVsbDtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNhbWVsY2FzZVxuICB0ZXh0dXJlSGFsZkZsb2F0RXh0ZW5zaW9uOiBPRVNfdGV4dHVyZV9oYWxmX2Zsb2F0fG51bGw7XG5cbiAgLy8gV2ViR0wyIGV4dGVuc2lvbnNcbiAgY29sb3JCdWZmZXJGbG9hdEV4dGVuc2lvbjogdW5rbm93bnxudWxsO1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXG4gIGRpc2pvaW50VGltZXJRdWVyeVdlYmdsMkV4dGVuc2lvbjoge1RJTUVfRUxBUFNFRF9FWFQ6IEdMZW51bTsgR1BVX0RJU0pPSU5UX0VYVDogR0xlbnVtfXxudWxsO1xuXG4gIHByaXZhdGUgZGlzcG9zZWQ6IGJvb2xlYW47XG4gIHByaXZhdGUgZnJhbWVCdWZmZXJCb3VuZCA9IGZhbHNlO1xuXG4gIGNvbnN0cnVjdG9yKGdsOiBXZWJHTFJlbmRlcmluZ0NvbnRleHQsIHZlcnNpb246IDF8Mikge1xuICAgIHRoaXMuZ2wgPSBnbDtcbiAgICB0aGlzLnZlcnNpb24gPSB2ZXJzaW9uO1xuXG4gICAgdGhpcy5nZXRFeHRlbnNpb25zKCk7XG4gICAgdGhpcy52ZXJ0ZXhidWZmZXIgPSB0aGlzLmNyZWF0ZVZlcnRleGJ1ZmZlcigpO1xuICAgIHRoaXMuZnJhbWVidWZmZXIgPSB0aGlzLmNyZWF0ZUZyYW1lYnVmZmVyKCk7XG4gICAgdGhpcy5xdWVyeVZpdGFsUGFyYW1ldGVycygpO1xuICB9XG5cbiAgYWxsb2NhdGVUZXh0dXJlKHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyLCBlbmNvZGVyOiBEYXRhRW5jb2RlciwgZGF0YT86IEVuY29kZXIuRGF0YUFycmF5VHlwZSk6IFdlYkdMVGV4dHVyZSB7XG4gICAgY29uc3QgZ2wgPSB0aGlzLmdsO1xuICAgIC8vIGNyZWF0ZSB0aGUgdGV4dHVyZVxuICAgIGNvbnN0IHRleHR1cmUgPSBnbC5jcmVhdGVUZXh0dXJlKCk7XG4gICAgLy8gYmluZCB0aGUgdGV4dHVyZSBzbyB0aGUgZm9sbG93aW5nIG1ldGhvZHMgZWZmZWN0IHRoaXMgdGV4dHVyZS5cbiAgICBnbC5iaW5kVGV4dHVyZShnbC5URVhUVVJFXzJELCB0ZXh0dXJlKTtcbiAgICBnbC50ZXhQYXJhbWV0ZXJpKGdsLlRFWFRVUkVfMkQsIGdsLlRFWFRVUkVfTUlOX0ZJTFRFUiwgZ2wuTkVBUkVTVCk7XG4gICAgZ2wudGV4UGFyYW1ldGVyaShnbC5URVhUVVJFXzJELCBnbC5URVhUVVJFX01BR19GSUxURVIsIGdsLk5FQVJFU1QpO1xuICAgIGdsLnRleFBhcmFtZXRlcmkoZ2wuVEVYVFVSRV8yRCwgZ2wuVEVYVFVSRV9XUkFQX1MsIGdsLkNMQU1QX1RPX0VER0UpO1xuICAgIGdsLnRleFBhcmFtZXRlcmkoZ2wuVEVYVFVSRV8yRCwgZ2wuVEVYVFVSRV9XUkFQX1QsIGdsLkNMQU1QX1RPX0VER0UpO1xuICAgIGNvbnN0IGJ1ZmZlciA9IGRhdGEgPyBlbmNvZGVyLmVuY29kZShkYXRhLCB3aWR0aCAqIGhlaWdodCkgOiBudWxsO1xuICAgIGdsLnRleEltYWdlMkQoXG4gICAgICAgIGdsLlRFWFRVUkVfMkQsXG4gICAgICAgIDAsICAvLyBMZXZlbCBvZiBkZXRhaWwuXG4gICAgICAgIGVuY29kZXIuaW50ZXJuYWxGb3JtYXQsIHdpZHRoLCBoZWlnaHQsXG4gICAgICAgIDAsICAvLyBBbHdheXMgMCBpbiBPcGVuR0wgRVMuXG4gICAgICAgIGVuY29kZXIuZm9ybWF0LCBlbmNvZGVyLnRleHR1cmVUeXBlLCBidWZmZXIpO1xuICAgIHRoaXMuY2hlY2tFcnJvcigpO1xuICAgIHJldHVybiB0ZXh0dXJlIGFzIFdlYkdMVGV4dHVyZTtcbiAgfVxuICB1cGRhdGVUZXh0dXJlKFxuICAgICAgdGV4dHVyZTogV2ViR0xUZXh0dXJlLCB3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlciwgZW5jb2RlcjogRGF0YUVuY29kZXIsIGRhdGE6IEVuY29kZXIuRGF0YUFycmF5VHlwZSk6IHZvaWQge1xuICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcbiAgICBnbC5iaW5kVGV4dHVyZShnbC5URVhUVVJFXzJELCB0ZXh0dXJlKTtcbiAgICBjb25zdCBidWZmZXIgPSBlbmNvZGVyLmVuY29kZShkYXRhLCB3aWR0aCAqIGhlaWdodCk7XG4gICAgZ2wudGV4U3ViSW1hZ2UyRChcbiAgICAgICAgZ2wuVEVYVFVSRV8yRCxcbiAgICAgICAgMCwgIC8vIGxldmVsXG4gICAgICAgIDAsICAvLyB4b2Zmc2V0XG4gICAgICAgIDAsICAvLyB5b2Zmc2V0XG4gICAgICAgIHdpZHRoLCBoZWlnaHQsIGVuY29kZXIuZm9ybWF0LCBlbmNvZGVyLnRleHR1cmVUeXBlLCBidWZmZXIpO1xuICAgIHRoaXMuY2hlY2tFcnJvcigpO1xuICB9XG4gIGF0dGFjaEZyYW1lYnVmZmVyKHRleHR1cmU6IFdlYkdMVGV4dHVyZSwgd2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG4gICAgLy8gTWFrZSBpdCB0aGUgdGFyZ2V0IGZvciBmcmFtZWJ1ZmZlciBvcGVyYXRpb25zIC0gaW5jbHVkaW5nIHJlbmRlcmluZy5cbiAgICBnbC5iaW5kVGV4dHVyZShnbC5URVhUVVJFXzJELCB0ZXh0dXJlKTtcbiAgICBnbC5iaW5kRnJhbWVidWZmZXIoZ2wuRlJBTUVCVUZGRVIsIHRoaXMuZnJhbWVidWZmZXIpO1xuICAgIGdsLmZyYW1lYnVmZmVyVGV4dHVyZTJEKFxuICAgICAgICBnbC5GUkFNRUJVRkZFUiwgZ2wuQ09MT1JfQVRUQUNITUVOVDAsIGdsLlRFWFRVUkVfMkQsIHRleHR1cmUsXG4gICAgICAgIDApOyAgLy8gMCwgd2UgYXJlbid0IHVzaW5nIE1JUE1BUHNcbiAgICB0aGlzLmNoZWNrRXJyb3IoKTtcbiAgICBnbC52aWV3cG9ydCgwLCAwLCB3aWR0aCwgaGVpZ2h0KTtcbiAgICBnbC5zY2lzc29yKDAsIDAsIHdpZHRoLCBoZWlnaHQpO1xuICB9XG4gIHJlYWRUZXh0dXJlKFxuICAgICAgdGV4dHVyZTogV2ViR0xUZXh0dXJlLCB3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlciwgZGF0YVNpemU6IG51bWJlciwgZGF0YVR5cGU6IEVuY29kZXIuRGF0YVR5cGUsXG4gICAgICBjaGFubmVsczogbnVtYmVyKTogRW5jb2Rlci5EYXRhQXJyYXlUeXBlIHtcbiAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG4gICAgaWYgKCFjaGFubmVscykge1xuICAgICAgY2hhbm5lbHMgPSAxO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuZnJhbWVCdWZmZXJCb3VuZCkge1xuICAgICAgdGhpcy5hdHRhY2hGcmFtZWJ1ZmZlcih0ZXh0dXJlLCB3aWR0aCwgaGVpZ2h0KTtcbiAgICB9XG4gICAgY29uc3QgZW5jb2RlciA9IHRoaXMuZ2V0RW5jb2RlcihkYXRhVHlwZSwgY2hhbm5lbHMpO1xuICAgIGNvbnN0IGJ1ZmZlciA9IGVuY29kZXIuYWxsb2NhdGUod2lkdGggKiBoZWlnaHQpO1xuICAgIC8vIGJpbmQgdGV4dHVyZSB0byBmcmFtZWJ1ZmZlclxuICAgIGdsLmJpbmRUZXh0dXJlKGdsLlRFWFRVUkVfMkQsIHRleHR1cmUpO1xuICAgIGdsLmZyYW1lYnVmZmVyVGV4dHVyZTJEKFxuICAgICAgICBnbC5GUkFNRUJVRkZFUiwgZ2wuQ09MT1JfQVRUQUNITUVOVDAsIGdsLlRFWFRVUkVfMkQsIHRleHR1cmUsXG4gICAgICAgIDApOyAgLy8gMCwgd2UgYXJlbid0IHVzaW5nIE1JUE1BUHNcbiAgICAvLyBUT0RPOiBDaGVjayBpZiBmcmFtZWJ1ZmZlciBpcyByZWFkeVxuICAgIGdsLnJlYWRQaXhlbHMoMCwgMCwgd2lkdGgsIGhlaWdodCwgZ2wuUkdCQSwgZW5jb2Rlci50ZXh0dXJlVHlwZSwgYnVmZmVyKTtcbiAgICB0aGlzLmNoZWNrRXJyb3IoKTtcbiAgICAvLyB1bmJpbmQgRkJcbiAgICByZXR1cm4gZW5jb2Rlci5kZWNvZGUoYnVmZmVyLCBkYXRhU2l6ZSk7XG4gIH1cblxuICBpc0ZyYW1lYnVmZmVyUmVhZHkoKTogYm9vbGVhbiB7XG4gICAgLy8gVE9ETzogSW1wbGVtZW50IGxvZ2ljIHRvIGNoZWNrIGlmIHRoZSBmcmFtZWJ1ZmZlciBpcyByZWFkeVxuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIGdldEFjdGl2ZVRleHR1cmUoKTogc3RyaW5nIHtcbiAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG4gICAgY29uc3QgbiA9IGdsLmdldFBhcmFtZXRlcih0aGlzLmdsLkFDVElWRV9URVhUVVJFKTtcbiAgICByZXR1cm4gYFRFWFRVUkUkeyhuIC0gZ2wuVEVYVFVSRTApfWA7XG4gIH1cbiAgZ2V0VGV4dHVyZUJpbmRpbmcoKTogV2ViR0xUZXh0dXJlIHtcbiAgICByZXR1cm4gdGhpcy5nbC5nZXRQYXJhbWV0ZXIodGhpcy5nbC5URVhUVVJFX0JJTkRJTkdfMkQpO1xuICB9XG4gIGdldEZyYW1lYnVmZmVyQmluZGluZygpOiBXZWJHTEZyYW1lYnVmZmVyIHtcbiAgICByZXR1cm4gdGhpcy5nbC5nZXRQYXJhbWV0ZXIodGhpcy5nbC5GUkFNRUJVRkZFUl9CSU5ESU5HKTtcbiAgfVxuICBzZXRWZXJ0ZXhBdHRyaWJ1dGVzKHBvc2l0aW9uSGFuZGxlOiBudW1iZXIsIHRleHR1cmVDb29yZEhhbmRsZTogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgZ2wgPSB0aGlzLmdsO1xuICAgIGdsLnZlcnRleEF0dHJpYlBvaW50ZXIocG9zaXRpb25IYW5kbGUsIDMsIGdsLkZMT0FULCBmYWxzZSwgMjAsIDApO1xuICAgIGdsLmVuYWJsZVZlcnRleEF0dHJpYkFycmF5KHBvc2l0aW9uSGFuZGxlKTtcbiAgICBpZiAodGV4dHVyZUNvb3JkSGFuZGxlICE9PSAtMSkge1xuICAgICAgZ2wudmVydGV4QXR0cmliUG9pbnRlcih0ZXh0dXJlQ29vcmRIYW5kbGUsIDIsIGdsLkZMT0FULCBmYWxzZSwgMjAsIDEyKTtcbiAgICAgIGdsLmVuYWJsZVZlcnRleEF0dHJpYkFycmF5KHRleHR1cmVDb29yZEhhbmRsZSk7XG4gICAgfVxuICAgIHRoaXMuY2hlY2tFcnJvcigpO1xuICB9XG4gIGNyZWF0ZVByb2dyYW0oXG4gICAgICB2ZXJ0ZXhTaGFkZXI6IFdlYkdMU2hhZGVyLFxuICAgICAgZnJhZ1NoYWRlcjogV2ViR0xTaGFkZXIsXG4gICAgICApOiBXZWJHTFByb2dyYW0ge1xuICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcbiAgICBjb25zdCBwcm9ncmFtID0gZ2wuY3JlYXRlUHJvZ3JhbSgpITtcblxuICAgIC8vIHRoZSBwcm9ncmFtIGNvbnNpc3RzIG9mIG91ciBzaGFkZXJzXG4gICAgZ2wuYXR0YWNoU2hhZGVyKHByb2dyYW0sIHZlcnRleFNoYWRlcik7XG4gICAgZ2wuYXR0YWNoU2hhZGVyKHByb2dyYW0sIGZyYWdTaGFkZXIpO1xuICAgIGdsLmxpbmtQcm9ncmFtKHByb2dyYW0pO1xuICAgIHJldHVybiBwcm9ncmFtO1xuICB9XG4gIGNvbXBpbGVTaGFkZXIoc2hhZGVyU291cmNlOiBzdHJpbmcsIHNoYWRlclR5cGU6IG51bWJlcik6IFdlYkdMU2hhZGVyIHtcbiAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG4gICAgY29uc3Qgc2hhZGVyID0gZ2wuY3JlYXRlU2hhZGVyKHNoYWRlclR5cGUpO1xuICAgIGlmICghc2hhZGVyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGNyZWF0ZVNoYWRlcigpIHJldHVybmVkIG51bGwgd2l0aCB0eXBlICR7c2hhZGVyVHlwZX1gKTtcbiAgICB9XG5cbiAgICBnbC5zaGFkZXJTb3VyY2Uoc2hhZGVyLCBzaGFkZXJTb3VyY2UpO1xuICAgIGdsLmNvbXBpbGVTaGFkZXIoc2hhZGVyKTtcbiAgICBpZiAoZ2wuZ2V0U2hhZGVyUGFyYW1ldGVyKHNoYWRlciwgZ2wuQ09NUElMRV9TVEFUVVMpID09PSBmYWxzZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gY29tcGlsZSBzaGFkZXI6ICR7Z2wuZ2V0U2hhZGVySW5mb0xvZyhzaGFkZXIpfVxuU2hhZGVyIHNvdXJjZTpcbiR7c2hhZGVyU291cmNlfWApO1xuICAgIH1cbiAgICByZXR1cm4gc2hhZGVyO1xuICB9XG4gIGRlbGV0ZVNoYWRlcihzaGFkZXI6IFdlYkdMU2hhZGVyKTogdm9pZCB7XG4gICAgdGhpcy5nbC5kZWxldGVTaGFkZXIoc2hhZGVyKTtcbiAgfVxuICBiaW5kVGV4dHVyZVRvVW5pZm9ybSh0ZXh0dXJlOiBXZWJHTFRleHR1cmUsIHBvc2l0aW9uOiBudW1iZXIsIHVuaWZvcm1IYW5kbGU6IFdlYkdMVW5pZm9ybUxvY2F0aW9uKTogdm9pZCB7XG4gICAgY29uc3QgZ2wgPSB0aGlzLmdsO1xuICAgIGdsLmFjdGl2ZVRleHR1cmUoZ2wuVEVYVFVSRTAgKyBwb3NpdGlvbik7XG4gICAgdGhpcy5jaGVja0Vycm9yKCk7XG4gICAgZ2wuYmluZFRleHR1cmUoZ2wuVEVYVFVSRV8yRCwgdGV4dHVyZSk7XG4gICAgdGhpcy5jaGVja0Vycm9yKCk7XG4gICAgZ2wudW5pZm9ybTFpKHVuaWZvcm1IYW5kbGUsIHBvc2l0aW9uKTtcbiAgICB0aGlzLmNoZWNrRXJyb3IoKTtcbiAgfVxuICBkcmF3KCk6IHZvaWQge1xuICAgIHRoaXMuZ2wuZHJhd0FycmF5cyh0aGlzLmdsLlRSSUFOR0xFX1NUUklQLCAwLCA0KTtcbiAgICB0aGlzLmNoZWNrRXJyb3IoKTtcbiAgfVxuICBjaGVja0Vycm9yKCk6IHZvaWQge1xuICAgIGlmIChlbnYuZGVidWcpIHtcbiAgICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcbiAgICAgIGNvbnN0IGVycm9yID0gZ2wuZ2V0RXJyb3IoKTtcbiAgICAgIGxldCBsYWJlbCA9ICcnO1xuICAgICAgc3dpdGNoIChlcnJvcikge1xuICAgICAgICBjYXNlIChnbC5OT19FUlJPUik6XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICBjYXNlIChnbC5JTlZBTElEX0VOVU0pOlxuICAgICAgICAgIGxhYmVsID0gJ0lOVkFMSURfRU5VTSc7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgKGdsLklOVkFMSURfVkFMVUUpOlxuICAgICAgICAgIGxhYmVsID0gJ0lOVkFMSURfVkFMVUUnO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIChnbC5JTlZBTElEX09QRVJBVElPTik6XG4gICAgICAgICAgbGFiZWwgPSAnSU5WQUxJRF9PUEVSQVRJT04nO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIChnbC5JTlZBTElEX0ZSQU1FQlVGRkVSX09QRVJBVElPTik6XG4gICAgICAgICAgbGFiZWwgPSAnSU5WQUxJRF9GUkFNRUJVRkZFUl9PUEVSQVRJT04nO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIChnbC5PVVRfT0ZfTUVNT1JZKTpcbiAgICAgICAgICBsYWJlbCA9ICdPVVRfT0ZfTUVNT1JZJztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAoZ2wuQ09OVEVYVF9MT1NUX1dFQkdMKTpcbiAgICAgICAgICBsYWJlbCA9ICdDT05URVhUX0xPU1RfV0VCR0wnO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIGxhYmVsID0gYFVua25vd24gV2ViR0wgRXJyb3I6ICR7ZXJyb3IudG9TdHJpbmcoMTYpfWA7XG4gICAgICB9XG4gICAgICB0aHJvdyBuZXcgRXJyb3IobGFiZWwpO1xuICAgIH1cbiAgfVxuICBkZWxldGVUZXh0dXJlKHRleHR1cmU6IFdlYkdMVGV4dHVyZSk6IHZvaWQge1xuICAgIHRoaXMuZ2wuZGVsZXRlVGV4dHVyZSh0ZXh0dXJlKTtcbiAgfVxuICBkZWxldGVQcm9ncmFtKHByb2dyYW06IFdlYkdMUHJvZ3JhbSk6IHZvaWQge1xuICAgIHRoaXMuZ2wuZGVsZXRlUHJvZ3JhbShwcm9ncmFtKTtcbiAgfVxuICBnZXRFbmNvZGVyKGRhdGFUeXBlOiBFbmNvZGVyLkRhdGFUeXBlLCBjaGFubmVsczogbnVtYmVyLCB1c2FnZTogRW5jb2Rlci5Vc2FnZSA9IEVuY29kZXIuVXNhZ2UuRGVmYXVsdCk6IERhdGFFbmNvZGVyIHtcbiAgICBpZiAodGhpcy52ZXJzaW9uID09PSAyKSB7XG4gICAgICByZXR1cm4gbmV3IERhdGFFbmNvZGVycy5SZWRGbG9hdDMyRGF0YUVuY29kZXIodGhpcy5nbCBhcyBXZWJHTDJSZW5kZXJpbmdDb250ZXh0LCBjaGFubmVscyk7XG4gICAgfVxuXG4gICAgc3dpdGNoIChkYXRhVHlwZSkge1xuICAgICAgY2FzZSAnZmxvYXQnOlxuICAgICAgICBpZiAodXNhZ2UgPT09IEVuY29kZXIuVXNhZ2UuVXBsb2FkT25seSB8fCB0aGlzLmlzUmVuZGVyRmxvYXQzMlN1cHBvcnRlZCkge1xuICAgICAgICAgIHJldHVybiBuZXcgRGF0YUVuY29kZXJzLlJHQkFGbG9hdERhdGFFbmNvZGVyKHRoaXMuZ2wsIGNoYW5uZWxzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gbmV3IERhdGFFbmNvZGVycy5SR0JBRmxvYXREYXRhRW5jb2RlcihcbiAgICAgICAgICAgICAgdGhpcy5nbCwgY2hhbm5lbHMsIHRoaXMudGV4dHVyZUhhbGZGbG9hdEV4dGVuc2lvbiEuSEFMRl9GTE9BVF9PRVMpO1xuICAgICAgICB9XG4gICAgICBjYXNlICdpbnQnOlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ25vdCBpbXBsZW1lbnRlZCcpO1xuICAgICAgY2FzZSAnYnl0ZSc6XG4gICAgICAgIHJldHVybiBuZXcgRGF0YUVuY29kZXJzLlVpbnQ4RGF0YUVuY29kZXIodGhpcy5nbCwgY2hhbm5lbHMpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGRhdGFUeXBlOiAke2RhdGFUeXBlfWApO1xuICAgIH1cbiAgfVxuICBjbGVhckFjdGl2ZVRleHR1cmVzKCk6IHZvaWQge1xuICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcbiAgICBmb3IgKGxldCB1bml0ID0gMDsgdW5pdCA8IHRoaXMubWF4VGV4dHVyZUltYWdlVW5pdHM7ICsrdW5pdCkge1xuICAgICAgZ2wuYWN0aXZlVGV4dHVyZShnbC5URVhUVVJFMCArIHVuaXQpO1xuICAgICAgZ2wuYmluZFRleHR1cmUoZ2wuVEVYVFVSRV8yRCwgbnVsbCk7XG4gICAgfVxuICB9XG4gIGRpc3Bvc2UoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZGlzcG9zZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgZ2wgPSB0aGlzLmdsO1xuICAgIGdsLmJpbmRGcmFtZWJ1ZmZlcihnbC5GUkFNRUJVRkZFUiwgbnVsbCk7XG4gICAgZ2wuZGVsZXRlRnJhbWVidWZmZXIodGhpcy5mcmFtZWJ1ZmZlcik7XG4gICAgZ2wuYmluZEJ1ZmZlcihnbC5BUlJBWV9CVUZGRVIsIG51bGwpO1xuICAgIGdsLmRlbGV0ZUJ1ZmZlcih0aGlzLnZlcnRleGJ1ZmZlcik7XG4gICAgZ2wuYmluZEJ1ZmZlcihnbC5FTEVNRU5UX0FSUkFZX0JVRkZFUiwgbnVsbCk7XG4gICAgZ2wuZmluaXNoKCk7XG4gICAgdGhpcy5kaXNwb3NlZCA9IHRydWU7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZURlZmF1bHRHZW9tZXRyeSgpOiBGbG9hdDMyQXJyYXkge1xuICAgIC8vIFNldHMgb2YgeCx5LHooPTApLHMsdCBjb29yZGluYXRlcy5cbiAgICByZXR1cm4gbmV3IEZsb2F0MzJBcnJheShbXG4gICAgICAtMS4wLCAxLjAsICAwLjAsIDAuMCwgMS4wLCAgLy8gdXBwZXIgbGVmdFxuICAgICAgLTEuMCwgLTEuMCwgMC4wLCAwLjAsIDAuMCwgIC8vIGxvd2VyIGxlZnRcbiAgICAgIDEuMCwgIDEuMCwgIDAuMCwgMS4wLCAxLjAsICAvLyB1cHBlciByaWdodFxuICAgICAgMS4wLCAgLTEuMCwgMC4wLCAxLjAsIDAuMCAgIC8vIGxvd2VyIHJpZ2h0XG4gICAgXSk7XG4gIH1cbiAgcHJpdmF0ZSBjcmVhdGVWZXJ0ZXhidWZmZXIoKTogV2ViR0xCdWZmZXIge1xuICAgIGNvbnN0IGdsID0gdGhpcy5nbDtcbiAgICBjb25zdCBidWZmZXIgPSBnbC5jcmVhdGVCdWZmZXIoKTtcbiAgICBpZiAoIWJ1ZmZlcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdjcmVhdGVCdWZmZXIoKSByZXR1cm5lZCBudWxsJyk7XG4gICAgfVxuICAgIGNvbnN0IGdlb21ldHJ5ID0gdGhpcy5jcmVhdGVEZWZhdWx0R2VvbWV0cnkoKTtcbiAgICBnbC5iaW5kQnVmZmVyKGdsLkFSUkFZX0JVRkZFUiwgYnVmZmVyKTtcbiAgICBnbC5idWZmZXJEYXRhKGdsLkFSUkFZX0JVRkZFUiwgZ2VvbWV0cnksIGdsLlNUQVRJQ19EUkFXKTtcbiAgICB0aGlzLmNoZWNrRXJyb3IoKTtcbiAgICByZXR1cm4gYnVmZmVyO1xuICB9XG4gIHByaXZhdGUgY3JlYXRlRnJhbWVidWZmZXIoKTogV2ViR0xGcmFtZWJ1ZmZlciB7XG4gICAgY29uc3QgZmIgPSB0aGlzLmdsLmNyZWF0ZUZyYW1lYnVmZmVyKCk7XG4gICAgaWYgKCFmYikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdjcmVhdGVGcmFtZWJ1ZmZlciByZXR1cm5lZCBudWxsJyk7XG4gICAgfVxuICAgIHJldHVybiBmYjtcbiAgfVxuXG4gIHByaXZhdGUgcXVlcnlWaXRhbFBhcmFtZXRlcnMoKTogdm9pZCB7XG4gICAgY29uc3QgZ2wgPSB0aGlzLmdsO1xuXG4gICAgdGhpcy5pc0Zsb2F0VGV4dHVyZUF0dGFjaGFibGVUb0ZyYW1lQnVmZmVyID0gdGhpcy5jaGVja0Zsb2F0VGV4dHVyZUF0dGFjaGFibGVUb0ZyYW1lQnVmZmVyKCk7XG4gICAgdGhpcy5pc1JlbmRlckZsb2F0MzJTdXBwb3J0ZWQgPSB0aGlzLmNoZWNrUmVuZGVyRmxvYXQzMigpO1xuICAgIHRoaXMuaXNGbG9hdDMyRG93bmxvYWRTdXBwb3J0ZWQgPSB0aGlzLmNoZWNrRmxvYXQzMkRvd25sb2FkKCk7XG5cbiAgICBpZiAodGhpcy52ZXJzaW9uID09PSAxICYmICF0aGlzLnRleHR1cmVIYWxmRmxvYXRFeHRlbnNpb24gJiYgIXRoaXMuaXNSZW5kZXJGbG9hdDMyU3VwcG9ydGVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2JvdGggZmxvYXQzMiBhbmQgZmxvYXQxNiBUZXh0dXJlVHlwZSBhcmUgbm90IHN1cHBvcnRlZCcpO1xuICAgIH1cblxuICAgIHRoaXMuaXNCbGVuZFN1cHBvcnRlZCA9ICF0aGlzLmlzUmVuZGVyRmxvYXQzMlN1cHBvcnRlZCB8fCB0aGlzLmNoZWNrRmxvYXQzMkJsZW5kKCk7XG5cbiAgICAvLyB0aGlzLm1heENvbWJpbmVkVGV4dHVyZUltYWdlVW5pdHMgPSBnbC5nZXRQYXJhbWV0ZXIoZ2wuTUFYX0NPTUJJTkVEX1RFWFRVUkVfSU1BR0VfVU5JVFMpO1xuICAgIHRoaXMubWF4VGV4dHVyZVNpemUgPSBnbC5nZXRQYXJhbWV0ZXIoZ2wuTUFYX1RFWFRVUkVfU0laRSk7XG4gICAgdGhpcy5tYXhUZXh0dXJlSW1hZ2VVbml0cyA9IGdsLmdldFBhcmFtZXRlcihnbC5NQVhfVEVYVFVSRV9JTUFHRV9VTklUUyk7XG4gICAgLy8gdGhpcy5tYXhDdWJlTWFwVGV4dHVyZVNpemUgPSBnbC5nZXRQYXJhbWV0ZXIoZ2wuTUFYX0NVQkVfTUFQX1RFWFRVUkVfU0laRSk7XG4gICAgLy8gdGhpcy5zaGFkaW5nTGFuZ3VhZ2VWZXJzaW9uID0gZ2wuZ2V0UGFyYW1ldGVyKGdsLlNIQURJTkdfTEFOR1VBR0VfVkVSU0lPTik7XG4gICAgLy8gdGhpcy53ZWJnbFZlbmRvciA9IGdsLmdldFBhcmFtZXRlcihnbC5WRU5ET1IpO1xuICAgIC8vIHRoaXMud2ViZ2xWZXJzaW9uID0gZ2wuZ2V0UGFyYW1ldGVyKGdsLlZFUlNJT04pO1xuXG4gICAgaWYgKHRoaXMudmVyc2lvbiA9PT0gMikge1xuICAgICAgLy8gdGhpcy5tYXgzRFRleHR1cmVTaXplID0gZ2wuZ2V0UGFyYW1ldGVyKFdlYkdMMlJlbmRlcmluZ0NvbnRleHQuTUFYXzNEX1RFWFRVUkVfU0laRSk7XG4gICAgICAvLyB0aGlzLm1heEFycmF5VGV4dHVyZUxheWVycyA9IGdsLmdldFBhcmFtZXRlcihXZWJHTDJSZW5kZXJpbmdDb250ZXh0Lk1BWF9BUlJBWV9URVhUVVJFX0xBWUVSUyk7XG4gICAgICAvLyB0aGlzLm1heENvbG9yQXR0YWNobWVudHMgPSBnbC5nZXRQYXJhbWV0ZXIoV2ViR0wyUmVuZGVyaW5nQ29udGV4dC5NQVhfQ09MT1JfQVRUQUNITUVOVFMpO1xuICAgICAgLy8gdGhpcy5tYXhEcmF3QnVmZmVycyA9IGdsLmdldFBhcmFtZXRlcihXZWJHTDJSZW5kZXJpbmdDb250ZXh0Lk1BWF9EUkFXX0JVRkZFUlMpO1xuICAgIH1cbiAgfVxuICBwcml2YXRlIGdldEV4dGVuc2lvbnMoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMudmVyc2lvbiA9PT0gMikge1xuICAgICAgdGhpcy5jb2xvckJ1ZmZlckZsb2F0RXh0ZW5zaW9uID0gdGhpcy5nbC5nZXRFeHRlbnNpb24oJ0VYVF9jb2xvcl9idWZmZXJfZmxvYXQnKTtcbiAgICAgIHRoaXMuZGlzam9pbnRUaW1lclF1ZXJ5V2ViZ2wyRXh0ZW5zaW9uID0gdGhpcy5nbC5nZXRFeHRlbnNpb24oJ0VYVF9kaXNqb2ludF90aW1lcl9xdWVyeV93ZWJnbDInKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy50ZXh0dXJlRmxvYXRFeHRlbnNpb24gPSB0aGlzLmdsLmdldEV4dGVuc2lvbignT0VTX3RleHR1cmVfZmxvYXQnKTtcbiAgICAgIHRoaXMudGV4dHVyZUhhbGZGbG9hdEV4dGVuc2lvbiA9IHRoaXMuZ2wuZ2V0RXh0ZW5zaW9uKCdPRVNfdGV4dHVyZV9oYWxmX2Zsb2F0Jyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBjaGVja0Zsb2F0VGV4dHVyZUF0dGFjaGFibGVUb0ZyYW1lQnVmZmVyKCk6IGJvb2xlYW4ge1xuICAgIC8vIHRlc3Qgd2hldGhlciBGbG9hdDMyIHRleHR1cmUgaXMgc3VwcG9ydGVkOlxuICAgIC8vIFNURVAuMSBjcmVhdGUgYSBmbG9hdCB0ZXh0dXJlXG4gICAgY29uc3QgZ2wgPSB0aGlzLmdsO1xuICAgIGNvbnN0IHRleHR1cmUgPSBnbC5jcmVhdGVUZXh0dXJlKCk7XG4gICAgZ2wuYmluZFRleHR1cmUoZ2wuVEVYVFVSRV8yRCwgdGV4dHVyZSk7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxuICAgIGNvbnN0IGludGVybmFsRm9ybWF0ID0gdGhpcy52ZXJzaW9uID09PSAyID8gKGdsIGFzIHVua25vd24gYXMge1JHQkEzMkY6IG51bWJlcn0pLlJHQkEzMkYgOiBnbC5SR0JBO1xuICAgIGdsLnRleEltYWdlMkQoZ2wuVEVYVFVSRV8yRCwgMCwgaW50ZXJuYWxGb3JtYXQsIDEsIDEsIDAsIGdsLlJHQkEsIGdsLkZMT0FULCBudWxsKTtcbiAgICAvLyBTVEVQLjIgYmluZCBhIGZyYW1lIGJ1ZmZlclxuICAgIGNvbnN0IGZyYW1lQnVmZmVyID0gZ2wuY3JlYXRlRnJhbWVidWZmZXIoKTtcbiAgICBnbC5iaW5kRnJhbWVidWZmZXIoZ2wuRlJBTUVCVUZGRVIsIGZyYW1lQnVmZmVyKTtcbiAgICAvLyBTVEVQLjMgYXR0YWNoIHRleHR1cmUgdG8gZnJhbWVidWZmZXJcbiAgICBnbC5mcmFtZWJ1ZmZlclRleHR1cmUyRChnbC5GUkFNRUJVRkZFUiwgZ2wuQ09MT1JfQVRUQUNITUVOVDAsIGdsLlRFWFRVUkVfMkQsIHRleHR1cmUsIDApO1xuICAgIC8vIFNURVAuNCB0ZXN0IHdoZXRoZXIgZnJhbWVidWZmZXIgaXMgY29tcGxldGVcbiAgICBjb25zdCBpc0NvbXBsZXRlID0gZ2wuY2hlY2tGcmFtZWJ1ZmZlclN0YXR1cyhnbC5GUkFNRUJVRkZFUikgPT09IGdsLkZSQU1FQlVGRkVSX0NPTVBMRVRFO1xuICAgIGdsLmJpbmRUZXh0dXJlKGdsLlRFWFRVUkVfMkQsIG51bGwpO1xuICAgIGdsLmJpbmRGcmFtZWJ1ZmZlcihnbC5GUkFNRUJVRkZFUiwgbnVsbCk7XG4gICAgZ2wuZGVsZXRlVGV4dHVyZSh0ZXh0dXJlKTtcbiAgICBnbC5kZWxldGVGcmFtZWJ1ZmZlcihmcmFtZUJ1ZmZlcik7XG4gICAgcmV0dXJuIGlzQ29tcGxldGU7XG4gIH1cblxuICBwcml2YXRlIGNoZWNrUmVuZGVyRmxvYXQzMigpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy52ZXJzaW9uID09PSAyKSB7XG4gICAgICBpZiAoIXRoaXMuY29sb3JCdWZmZXJGbG9hdEV4dGVuc2lvbikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICghdGhpcy50ZXh0dXJlRmxvYXRFeHRlbnNpb24pIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5pc0Zsb2F0VGV4dHVyZUF0dGFjaGFibGVUb0ZyYW1lQnVmZmVyO1xuICB9XG5cbiAgcHJpdmF0ZSBjaGVja0Zsb2F0MzJEb3dubG9hZCgpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy52ZXJzaW9uID09PSAyKSB7XG4gICAgICBpZiAoIXRoaXMuY29sb3JCdWZmZXJGbG9hdEV4dGVuc2lvbikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICghdGhpcy50ZXh0dXJlRmxvYXRFeHRlbnNpb24pIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgaWYgKCF0aGlzLmdsLmdldEV4dGVuc2lvbignV0VCR0xfY29sb3JfYnVmZmVyX2Zsb2F0JykpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5pc0Zsb2F0VGV4dHVyZUF0dGFjaGFibGVUb0ZyYW1lQnVmZmVyO1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIHdoZXRoZXIgR0xfQkxFTkQgaXMgc3VwcG9ydGVkXG4gICAqL1xuICBwcml2YXRlIGNoZWNrRmxvYXQzMkJsZW5kKCk6IGJvb2xlYW4ge1xuICAgIC8vIGl0IGxvb2tzIGxpa2UgY3VycmVudGx5ICgyMDE5LTA1LTA4KSB0aGVyZSBpcyBubyBlYXN5IHdheSB0byBkZXRlY3Qgd2hldGhlciBCTEVORCBpcyBzdXBwb3J0ZWRcbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vbWljcm9zb2Z0L29ubnhqcy9pc3N1ZXMvMTQ1XG5cbiAgICBjb25zdCBnbCA9IHRoaXMuZ2w7XG5cbiAgICBsZXQgdGV4dHVyZTogV2ViR0xUZXh0dXJlfG51bGx8dW5kZWZpbmVkO1xuICAgIGxldCBmcmFtZUJ1ZmZlcjogV2ViR0xGcmFtZWJ1ZmZlcnxudWxsfHVuZGVmaW5lZDtcbiAgICBsZXQgdmVydGV4U2hhZGVyOiBXZWJHTFNoYWRlcnxudWxsfHVuZGVmaW5lZDtcbiAgICBsZXQgZnJhZ21lbnRTaGFkZXI6IFdlYkdMU2hhZGVyfG51bGx8dW5kZWZpbmVkO1xuICAgIGxldCBwcm9ncmFtOiBXZWJHTFByb2dyYW18bnVsbHx1bmRlZmluZWQ7XG5cbiAgICB0cnkge1xuICAgICAgdGV4dHVyZSA9IGdsLmNyZWF0ZVRleHR1cmUoKTtcbiAgICAgIGZyYW1lQnVmZmVyID0gZ2wuY3JlYXRlRnJhbWVidWZmZXIoKTtcbiAgICAgIGdsLmJpbmRUZXh0dXJlKGdsLlRFWFRVUkVfMkQsIHRleHR1cmUpO1xuXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXG4gICAgICBjb25zdCBpbnRlcm5hbEZvcm1hdCA9IHRoaXMudmVyc2lvbiA9PT0gMiA/IChnbCBhcyB1bmtub3duIGFzIHtSR0JBMzJGOiBudW1iZXJ9KS5SR0JBMzJGIDogZ2wuUkdCQTtcbiAgICAgIGdsLnRleEltYWdlMkQoZ2wuVEVYVFVSRV8yRCwgMCwgaW50ZXJuYWxGb3JtYXQsIDEsIDEsIDAsIGdsLlJHQkEsIGdsLkZMT0FULCBudWxsKTtcblxuICAgICAgZ2wuYmluZEZyYW1lYnVmZmVyKGdsLkZSQU1FQlVGRkVSLCBmcmFtZUJ1ZmZlcik7XG4gICAgICBnbC5mcmFtZWJ1ZmZlclRleHR1cmUyRChnbC5GUkFNRUJVRkZFUiwgZ2wuQ09MT1JfQVRUQUNITUVOVDAsIGdsLlRFWFRVUkVfMkQsIHRleHR1cmUsIDApO1xuXG4gICAgICBnbC5lbmFibGUoZ2wuQkxFTkQpO1xuXG4gICAgICB2ZXJ0ZXhTaGFkZXIgPSBnbC5jcmVhdGVTaGFkZXIoZ2wuVkVSVEVYX1NIQURFUik7XG4gICAgICBpZiAoIXZlcnRleFNoYWRlcikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBnbC5zaGFkZXJTb3VyY2UodmVydGV4U2hhZGVyLCAndm9pZCBtYWluKCl7fScpO1xuICAgICAgZ2wuY29tcGlsZVNoYWRlcih2ZXJ0ZXhTaGFkZXIpO1xuXG4gICAgICBmcmFnbWVudFNoYWRlciA9IGdsLmNyZWF0ZVNoYWRlcihnbC5GUkFHTUVOVF9TSEFERVIpO1xuICAgICAgaWYgKCFmcmFnbWVudFNoYWRlcikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBnbC5zaGFkZXJTb3VyY2UoZnJhZ21lbnRTaGFkZXIsICdwcmVjaXNpb24gaGlnaHAgZmxvYXQ7dm9pZCBtYWluKCl7Z2xfRnJhZ0NvbG9yPXZlYzQoMC41KTt9Jyk7XG4gICAgICBnbC5jb21waWxlU2hhZGVyKGZyYWdtZW50U2hhZGVyKTtcblxuICAgICAgcHJvZ3JhbSA9IGdsLmNyZWF0ZVByb2dyYW0oKTtcbiAgICAgIGlmICghcHJvZ3JhbSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBnbC5hdHRhY2hTaGFkZXIocHJvZ3JhbSwgdmVydGV4U2hhZGVyKTtcbiAgICAgIGdsLmF0dGFjaFNoYWRlcihwcm9ncmFtLCBmcmFnbWVudFNoYWRlcik7XG4gICAgICBnbC5saW5rUHJvZ3JhbShwcm9ncmFtKTtcbiAgICAgIGdsLnVzZVByb2dyYW0ocHJvZ3JhbSk7XG5cbiAgICAgIGdsLmRyYXdBcnJheXMoZ2wuUE9JTlRTLCAwLCAxKTtcbiAgICAgIHJldHVybiBnbC5nZXRFcnJvcigpID09PSBnbC5OT19FUlJPUjtcblxuICAgIH0gZmluYWxseSB7XG4gICAgICBnbC5kaXNhYmxlKGdsLkJMRU5EKTtcblxuICAgICAgaWYgKHByb2dyYW0pIHtcbiAgICAgICAgZ2wuZGVsZXRlUHJvZ3JhbShwcm9ncmFtKTtcbiAgICAgIH1cbiAgICAgIGlmICh2ZXJ0ZXhTaGFkZXIpIHtcbiAgICAgICAgZ2wuZGVsZXRlU2hhZGVyKHZlcnRleFNoYWRlcik7XG4gICAgICB9XG4gICAgICBpZiAoZnJhZ21lbnRTaGFkZXIpIHtcbiAgICAgICAgZ2wuZGVsZXRlU2hhZGVyKGZyYWdtZW50U2hhZGVyKTtcbiAgICAgIH1cbiAgICAgIGlmIChmcmFtZUJ1ZmZlcikge1xuICAgICAgICBnbC5iaW5kRnJhbWVidWZmZXIoZ2wuRlJBTUVCVUZGRVIsIG51bGwpO1xuICAgICAgICBnbC5kZWxldGVGcmFtZWJ1ZmZlcihmcmFtZUJ1ZmZlcik7XG4gICAgICB9XG4gICAgICBpZiAodGV4dHVyZSkge1xuICAgICAgICBnbC5iaW5kVGV4dHVyZShnbC5URVhUVVJFXzJELCBudWxsKTtcbiAgICAgICAgZ2wuZGVsZXRlVGV4dHVyZSh0ZXh0dXJlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBiZWdpblRpbWVyKCk6IFdlYkdMUXVlcnkge1xuICAgIGlmICh0aGlzLnZlcnNpb24gPT09IDIgJiYgdGhpcy5kaXNqb2ludFRpbWVyUXVlcnlXZWJnbDJFeHRlbnNpb24pIHtcbiAgICAgIGNvbnN0IGdsMiA9IHRoaXMuZ2wgYXMgV2ViR0wyUmVuZGVyaW5nQ29udGV4dDtcbiAgICAgIGNvbnN0IGV4dCA9IHRoaXMuZGlzam9pbnRUaW1lclF1ZXJ5V2ViZ2wyRXh0ZW5zaW9uO1xuXG4gICAgICBjb25zdCBxdWVyeSA9IGdsMi5jcmVhdGVRdWVyeSgpIGFzIFdlYkdMUXVlcnk7XG4gICAgICBnbDIuYmVnaW5RdWVyeShleHQuVElNRV9FTEFQU0VEX0VYVCwgcXVlcnkpO1xuICAgICAgcmV0dXJuIHF1ZXJ5O1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBUT0RPOiBhZGQgd2ViZ2wgMSBoYW5kbGluZy5cbiAgICAgIHRocm93IG5ldyBFcnJvcignV2ViR0wxIHByb2ZpbGluZyBjdXJyZW50bHkgbm90IHN1cHBvcnRlZC4nKTtcbiAgICB9XG4gIH1cblxuICBlbmRUaW1lcigpIHtcbiAgICBpZiAodGhpcy52ZXJzaW9uID09PSAyICYmIHRoaXMuZGlzam9pbnRUaW1lclF1ZXJ5V2ViZ2wyRXh0ZW5zaW9uKSB7XG4gICAgICBjb25zdCBnbDIgPSB0aGlzLmdsIGFzIFdlYkdMMlJlbmRlcmluZ0NvbnRleHQ7XG4gICAgICBjb25zdCBleHQgPSB0aGlzLmRpc2pvaW50VGltZXJRdWVyeVdlYmdsMkV4dGVuc2lvbjtcbiAgICAgIGdsMi5lbmRRdWVyeShleHQuVElNRV9FTEFQU0VEX0VYVCk7XG4gICAgICByZXR1cm47XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFRPRE86IGFkZCB3ZWJnbCAxIGhhbmRsaW5nLlxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdXZWJHTDEgcHJvZmlsaW5nIGN1cnJlbnRseSBub3Qgc3VwcG9ydGVkJyk7XG4gICAgfVxuICB9XG5cbiAgaXNUaW1lclJlc3VsdEF2YWlsYWJsZShxdWVyeTogV2ViR0xRdWVyeSk6IGJvb2xlYW4ge1xuICAgIGxldCBhdmFpbGFibGUgPSBmYWxzZSwgZGlzam9pbnQgPSBmYWxzZTtcbiAgICBpZiAodGhpcy52ZXJzaW9uID09PSAyICYmIHRoaXMuZGlzam9pbnRUaW1lclF1ZXJ5V2ViZ2wyRXh0ZW5zaW9uKSB7XG4gICAgICBjb25zdCBnbDIgPSB0aGlzLmdsIGFzIFdlYkdMMlJlbmRlcmluZ0NvbnRleHQ7XG4gICAgICBjb25zdCBleHQgPSB0aGlzLmRpc2pvaW50VGltZXJRdWVyeVdlYmdsMkV4dGVuc2lvbjtcblxuICAgICAgYXZhaWxhYmxlID0gZ2wyLmdldFF1ZXJ5UGFyYW1ldGVyKHF1ZXJ5LCBnbDIuUVVFUllfUkVTVUxUX0FWQUlMQUJMRSk7XG4gICAgICBkaXNqb2ludCA9IGdsMi5nZXRQYXJhbWV0ZXIoZXh0LkdQVV9ESVNKT0lOVF9FWFQpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBUT0RPOiBhZGQgd2ViZ2wgMSBoYW5kbGluZy5cbiAgICAgIHRocm93IG5ldyBFcnJvcignV2ViR0wxIHByb2ZpbGluZyBjdXJyZW50bHkgbm90IHN1cHBvcnRlZCcpO1xuICAgIH1cblxuICAgIHJldHVybiBhdmFpbGFibGUgJiYgIWRpc2pvaW50O1xuICB9XG5cbiAgZ2V0VGltZXJSZXN1bHQocXVlcnk6IFdlYkdMUXVlcnkpOiBudW1iZXIge1xuICAgIGxldCB0aW1lRWxhcHNlZCA9IDA7XG4gICAgaWYgKHRoaXMudmVyc2lvbiA9PT0gMikge1xuICAgICAgY29uc3QgZ2wyID0gdGhpcy5nbCBhcyBXZWJHTDJSZW5kZXJpbmdDb250ZXh0O1xuICAgICAgdGltZUVsYXBzZWQgPSBnbDIuZ2V0UXVlcnlQYXJhbWV0ZXIocXVlcnksIGdsMi5RVUVSWV9SRVNVTFQpO1xuICAgICAgZ2wyLmRlbGV0ZVF1ZXJ5KHF1ZXJ5KTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gVE9ETzogYWRkIHdlYmdsIDEgaGFuZGxpbmcuXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1dlYkdMMSBwcm9maWxpbmcgY3VycmVudGx5IG5vdCBzdXBwb3J0ZWQnKTtcbiAgICB9XG4gICAgLy8gcmV0dXJuIG1pbGlzZWNvbmRzXG4gICAgcmV0dXJuIHRpbWVFbGFwc2VkIC8gMTAwMDAwMDtcbiAgfVxuXG4gIGFzeW5jIHdhaXRGb3JRdWVyeUFuZEdldFRpbWUocXVlcnk6IFdlYkdMUXVlcnkpOiBQcm9taXNlPG51bWJlcj4ge1xuICAgIGF3YWl0IHJlcGVhdGVkVHJ5KCgpID0+IHRoaXMuaXNUaW1lclJlc3VsdEF2YWlsYWJsZShxdWVyeSkpO1xuICAgIHJldHVybiB0aGlzLmdldFRpbWVyUmVzdWx0KHF1ZXJ5KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBjcmVhdGVBbmRXYWl0Rm9yRmVuY2UoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgZmVuY2VDb250ZXh0ID0gdGhpcy5jcmVhdGVGZW5jZSh0aGlzLmdsKTtcbiAgICByZXR1cm4gdGhpcy5wb2xsRmVuY2UoZmVuY2VDb250ZXh0KTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlRmVuY2UoZ2w6IFdlYkdMUmVuZGVyaW5nQ29udGV4dCk6IEZlbmNlQ29udGV4dCB7XG4gICAgbGV0IGlzRmVuY2VQYXNzZWQ6ICgpID0+IGJvb2xlYW47XG4gICAgY29uc3QgZ2wyID0gZ2wgYXMgV2ViR0wyUmVuZGVyaW5nQ29udGV4dDtcbiAgICBjb25zdCBxdWVyeSA9IGdsMi5mZW5jZVN5bmMoZ2wyLlNZTkNfR1BVX0NPTU1BTkRTX0NPTVBMRVRFLCAwKTtcbiAgICBnbC5mbHVzaCgpO1xuICAgIGlmIChxdWVyeSA9PT0gbnVsbCkge1xuICAgICAgaXNGZW5jZVBhc3NlZCA9ICgpID0+IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlzRmVuY2VQYXNzZWQgPSAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHN0YXR1cyA9IGdsMi5jbGllbnRXYWl0U3luYyhxdWVyeSwgMCwgMCk7XG4gICAgICAgIHJldHVybiBzdGF0dXMgPT09IGdsMi5BTFJFQURZX1NJR05BTEVEIHx8IHN0YXR1cyA9PT0gZ2wyLkNPTkRJVElPTl9TQVRJU0ZJRUQ7XG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4ge3F1ZXJ5LCBpc0ZlbmNlUGFzc2VkfTtcbiAgfVxuXG4gIGFzeW5jIHBvbGxGZW5jZShmZW5jZUNvbnRleHQ6IEZlbmNlQ29udGV4dCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTx2b2lkPihyZXNvbHZlID0+IHtcbiAgICAgIHZvaWQgdGhpcy5hZGRJdGVtVG9Qb2xsKCgpID0+IGZlbmNlQ29udGV4dC5pc0ZlbmNlUGFzc2VkKCksICgpID0+IHJlc29sdmUoKSk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGl0ZW1zVG9Qb2xsOiBQb2xsSXRlbVtdID0gW107XG5cbiAgcG9sbEl0ZW1zKCk6IHZvaWQge1xuICAgIC8vIEZpbmQgdGhlIGxhc3QgcXVlcnkgdGhhdCBoYXMgZmluaXNoZWQuXG4gICAgY29uc3QgaW5kZXggPSBsaW5lYXJTZWFyY2hMYXN0VHJ1ZSh0aGlzLml0ZW1zVG9Qb2xsLm1hcCh4ID0+IHguaXNEb25lRm4pKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8PSBpbmRleDsgKytpKSB7XG4gICAgICBjb25zdCB7cmVzb2x2ZUZufSA9IHRoaXMuaXRlbXNUb1BvbGxbaV07XG4gICAgICByZXNvbHZlRm4oKTtcbiAgICB9XG4gICAgdGhpcy5pdGVtc1RvUG9sbCA9IHRoaXMuaXRlbXNUb1BvbGwuc2xpY2UoaW5kZXggKyAxKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgYWRkSXRlbVRvUG9sbChpc0RvbmVGbjogKCkgPT4gYm9vbGVhbiwgcmVzb2x2ZUZuOiAoKSA9PiB2b2lkKSB7XG4gICAgdGhpcy5pdGVtc1RvUG9sbC5wdXNoKHtpc0RvbmVGbiwgcmVzb2x2ZUZufSk7XG4gICAgaWYgKHRoaXMuaXRlbXNUb1BvbGwubGVuZ3RoID4gMSkge1xuICAgICAgLy8gV2UgYWxyZWFkeSBoYXZlIGEgcnVubmluZyBsb29wIHRoYXQgcG9sbHMuXG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIFN0YXJ0IGEgbmV3IGxvb3AgdGhhdCBwb2xscy5cbiAgICBhd2FpdCByZXBlYXRlZFRyeSgoKSA9PiB7XG4gICAgICB0aGlzLnBvbGxJdGVtcygpO1xuICAgICAgLy8gRW5kIHRoZSBsb29wIGlmIG5vIG1vcmUgaXRlbXMgdG8gcG9sbC5cbiAgICAgIHJldHVybiB0aGlzLml0ZW1zVG9Qb2xsLmxlbmd0aCA9PT0gMDtcbiAgICB9KTtcbiAgfVxufVxuIiwiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7U2Vzc2lvbkhhbmRsZXJ9IGZyb20gJy4vYmFja2VuZCc7XG5pbXBvcnQge0dyYXBofSBmcm9tICcuL2dyYXBoJztcbmltcG9ydCB7TG9nZ2VyLCBQcm9maWxlcn0gZnJvbSAnLi9pbnN0cnVtZW50JztcbmltcG9ydCB7T3BlcmF0b3J9IGZyb20gJy4vb3BlcmF0b3JzJztcbmltcG9ydCB7VGVuc29yfSBmcm9tICcuL3RlbnNvcic7XG5cbmNsYXNzIEtlcm5lbE9wIHtcbiAgY29uc3RydWN0b3IocHVibGljIG9wOiBPcGVyYXRvciwgcHVibGljIG5vZGU6IEdyYXBoLk5vZGUpIHt9XG59XG5cbmV4cG9ydCBjbGFzcyBFeGVjdXRpb25QbGFuIHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBncmFwaDogR3JhcGgsIG9wczogT3BlcmF0b3JbXSwgcHJpdmF0ZSBwcm9maWxlcjogUmVhZG9ubHk8UHJvZmlsZXI+KSB7XG4gICAgdGhpcy5pbml0aWFsaXplKG9wcyk7XG4gIH1cblxuICBpbml0aWFsaXplKG9wczogT3BlcmF0b3JbXSkge1xuICAgIHRoaXMucHJvZmlsZXIuZXZlbnQoJ3Nlc3Npb24nLCAnRXhlY3V0aW9uUGxhbi5pbml0aWFsaXplJywgKCkgPT4ge1xuICAgICAgY29uc3QgZ3JhcGhOb2RlcyA9IHRoaXMuZ3JhcGguZ2V0Tm9kZXMoKTtcbiAgICAgIGlmIChncmFwaE5vZGVzLmxlbmd0aCAhPT0gb3BzLmxlbmd0aCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBzaXplIG9mIG5vZGVzIGFuZCBPUHMgZG8gbm90IG1hdGNoLicpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl9vcHMgPSBvcHMubWFwKChvcCwgaSkgPT4gbmV3IEtlcm5lbE9wKG9wLCBncmFwaE5vZGVzW2ldKSk7XG4gICAgICB0aGlzLnJlc2V0KCk7XG5cbiAgICAgIC8vIGxvb2sgZm9yIHN0YXJ0ZXIgbm9kZShzKVxuICAgICAgdGhpcy5fc3RhcnRlciA9IFtdO1xuICAgICAgdGhpcy5fb3BzLmZvckVhY2goKG9wLCBpKSA9PiB7XG4gICAgICAgIGxldCByZXNvbHZlZCA9IHRydWU7XG4gICAgICAgIGZvciAoY29uc3QgaW5wdXQgb2Ygb3Aubm9kZS5pbnB1dHMpIHtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICF0aGlzLl92YWx1ZXNbaW5wdXRdICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBub3QgYW4gaW5pdGlhbGl6ZWQgaW5wdXRcbiAgICAgICAgICAgICAgJiYgdGhpcy5ncmFwaC5nZXRJbnB1dEluZGljZXMoKS5pbmRleE9mKGlucHV0KSA9PT0gLTEgIC8vIG5vdCBtb2RlbCBpbnB1dFxuICAgICAgICAgICkge1xuICAgICAgICAgICAgcmVzb2x2ZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAocmVzb2x2ZWQpIHtcbiAgICAgICAgICB0aGlzLl9zdGFydGVyLnB1c2goaSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgcmVzZXQoKSB7XG4gICAgdGhpcy5fdmFsdWVzID0gdGhpcy5ncmFwaC5nZXRWYWx1ZXMoKS5tYXAoaSA9PiBpLnRlbnNvcik7XG4gIH1cblxuICBhc3luYyBleGVjdXRlKHNlc3Npb25IYW5kbGVyOiBTZXNzaW9uSGFuZGxlciwgbW9kZWxJbnB1dHM6IFRlbnNvcltdKTogUHJvbWlzZTxUZW5zb3JbXT4ge1xuICAgIHJldHVybiB0aGlzLnByb2ZpbGVyLmV2ZW50KCdzZXNzaW9uJywgJ0V4ZWN1dGlvblBsYW4uZXhlY3V0ZScsIGFzeW5jICgpID0+IHtcbiAgICAgIC8vIHJlc2V0IG1lZGllbSByZXN1bHRcbiAgICAgIHRoaXMucmVzZXQoKTtcblxuICAgICAgLy8gY3JlYXRlIGluZmVyZW5jZSBoYW5kbGVyXG4gICAgICBjb25zdCBpbmZlcmVuY2VIYW5kbGVyID0gc2Vzc2lvbkhhbmRsZXIuY3JlYXRlSW5mZXJlbmNlSGFuZGxlcigpO1xuXG4gICAgICAvLyBwb3B1bGF0ZSBpbnB1dHMgdmFsdWVcbiAgICAgIGNvbnN0IGdyYXBoSW5wdXRzID0gdGhpcy5ncmFwaC5nZXRJbnB1dEluZGljZXMoKTtcbiAgICAgIGlmIChtb2RlbElucHV0cy5sZW5ndGggIT09IGdyYXBoSW5wdXRzLmxlbmd0aCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYG51bWJlciBvZiBpbnB1dCB0ZW5zb3JzIGRvbid0IG1hdGNoIHRoZSBudW1iZXIgb2YgaW5wdXRzIHRvIHRoZSBtb2RlbDogYWN0dWFsOiAke1xuICAgICAgICAgICAgbW9kZWxJbnB1dHMubGVuZ3RofSBleHBlY3RlZDogJHtncmFwaElucHV0cy5sZW5ndGh9YCk7XG4gICAgICB9XG5cbiAgICAgIG1vZGVsSW5wdXRzLmZvckVhY2goKGlucHV0LCBpKSA9PiB7XG4gICAgICAgIGNvbnN0IGluZGV4ID0gZ3JhcGhJbnB1dHNbaV07XG4gICAgICAgIHRoaXMuX3ZhbHVlc1tpbmRleF0gPSBpbnB1dDtcbiAgICAgIH0pO1xuXG4gICAgICAvLyBwcmVwYXJlIHJ1bm5pbmcgc2VxdWVuY2VcbiAgICAgIGNvbnN0IHNlcXVlbmNlOiBudW1iZXJbXSA9IHRoaXMuX3N0YXJ0ZXIuc2xpY2UoMCk7XG5cbiAgICAgIC8vIGV4ZWN1dGlvbiBpdGVyYXRpb25zXG4gICAgICBjb25zdCBncmFwaFZhbHVlcyA9IHRoaXMuZ3JhcGguZ2V0VmFsdWVzKCk7XG4gICAgICBjb25zdCBncmFwaE5vZGVzID0gdGhpcy5ncmFwaC5nZXROb2RlcygpO1xuXG4gICAgICBsZXQgcmVhciA9IDA7XG4gICAgICB3aGlsZSAocmVhciA8IHNlcXVlbmNlLmxlbmd0aCkge1xuICAgICAgICBjb25zdCB0aGlzT3BJbmRleCA9IHNlcXVlbmNlW3JlYXIrK107XG4gICAgICAgIGNvbnN0IHRoaXNPcCA9IHRoaXMuX29wc1t0aGlzT3BJbmRleF07XG5cbiAgICAgICAgLy8gY2hlY2sgaW5wdXRcbiAgICAgICAgY29uc3QgaW5wdXRMaXN0ID0gdGhpc09wLm5vZGUuaW5wdXRzLm1hcChpID0+IHRoaXMuX3ZhbHVlc1tpXSk7XG4gICAgICAgIGlmIChpbnB1dExpc3QuaW5kZXhPZih1bmRlZmluZWQpICE9PSAtMSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgdW5yZXNvbHZlZCBpbnB1dCBkZXRlY3RlZDogb3A6ICR7dGhpc09wLm5vZGV9YCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBydW5cbiAgICAgICAgY29uc3QgaW5wdXRUZW5zb3JzID0gaW5wdXRMaXN0IGFzIFRlbnNvcltdO1xuICAgICAgICBMb2dnZXIudmVyYm9zZShcbiAgICAgICAgICAgICdFeGVjUGxhbicsXG4gICAgICAgICAgICBgUnVuaW5nIG9wOiR7dGhpc09wLm5vZGUubmFtZX0gKCR7XG4gICAgICAgICAgICAgICAgaW5wdXRUZW5zb3JzLm1hcCgodCwgaSkgPT4gYCcke3RoaXNPcC5ub2RlLmlucHV0c1tpXX0nOiAke3QudHlwZX1bJHt0LmRpbXMuam9pbignLCcpfV1gKS5qb2luKCcsICcpfSlgKTtcblxuICAgICAgICBjb25zdCBvdXRwdXRMaXN0ID0gYXdhaXQgdGhpcy5wcm9maWxlci5ldmVudChcbiAgICAgICAgICAgICdub2RlJywgdGhpc09wLm5vZGUubmFtZSwgYXN5bmMgKCkgPT4gdGhpc09wLm9wLmltcGwoaW5mZXJlbmNlSGFuZGxlciwgaW5wdXRUZW5zb3JzLCB0aGlzT3Aub3AuY29udGV4dCkpO1xuXG4gICAgICAgIC8vIGNoZWNrIG91dHB1dFxuICAgICAgICBpZiAob3V0cHV0TGlzdC5sZW5ndGggIT09IHRoaXNPcC5ub2RlLm91dHB1dHMubGVuZ3RoKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd0aGUgc2l6ZSBvZiBvdXRwdXQgZG9lcyBub3QgbWF0Y2ggbW9kZWwgZGVmaW5pdGlvbi4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGZpbGwgdmFsdWVcbiAgICAgICAgb3V0cHV0TGlzdC5mb3JFYWNoKChvdXRwdXQsIGkpID0+IHtcbiAgICAgICAgICBjb25zdCBqID0gdGhpc09wLm5vZGUub3V0cHV0c1tpXTtcbiAgICAgICAgICBpZiAodGhpcy5fdmFsdWVzW2pdKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYG91dHB1dCBbJHtqfV0gYWxyZWFkeSBoYXMgdmFsdWU6IG9wOiR7dGhpc09wLm5vZGUubmFtZX1gKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5fdmFsdWVzW2pdID0gb3V0cHV0O1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyByZXNvbHZlIGRvd25zdHJlYW0gbm9kZXNcbiAgICAgICAgY29uc3QgZG93bnN0cmVhbU5vZGVzID0gbmV3IFNldDxudW1iZXI+KCk7XG4gICAgICAgIG91dHB1dExpc3QuZm9yRWFjaCgob3V0cHV0LCBpKSA9PiB7XG4gICAgICAgICAgY29uc3QgaiA9IHRoaXNPcC5ub2RlLm91dHB1dHNbaV07XG4gICAgICAgICAgZm9yIChjb25zdCBjdXJyZW50RG93bnN0cmVhbU5vZGVJbmRleCBvZiBncmFwaFZhbHVlc1tqXS50bykge1xuICAgICAgICAgICAgY29uc3QgY3VycmVudERvd25zdHJlYW1Ob2RlID0gZ3JhcGhOb2Rlc1tjdXJyZW50RG93bnN0cmVhbU5vZGVJbmRleF07XG4gICAgICAgICAgICBsZXQgcmVzb2x2ZWQgPSB0cnVlO1xuICAgICAgICAgICAgZm9yIChjb25zdCBrIG9mIGN1cnJlbnREb3duc3RyZWFtTm9kZS5pbnB1dHMpIHtcbiAgICAgICAgICAgICAgaWYgKCF0aGlzLl92YWx1ZXNba10pIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAocmVzb2x2ZWQpIHtcbiAgICAgICAgICAgICAgZG93bnN0cmVhbU5vZGVzLmFkZChjdXJyZW50RG93bnN0cmVhbU5vZGVJbmRleCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgc2VxdWVuY2UucHVzaCguLi5kb3duc3RyZWFtTm9kZXMpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBvdXRwdXQ6IFRlbnNvcltdID0gW107XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuZ3JhcGguZ2V0T3V0cHV0SW5kaWNlcygpLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IG91dHB1dEluZGV4ID0gdGhpcy5ncmFwaC5nZXRPdXRwdXRJbmRpY2VzKClbaV07XG4gICAgICAgIGNvbnN0IG91dHB1dFRlbnNvciA9IHRoaXMuX3ZhbHVlc1tvdXRwdXRJbmRleF07XG4gICAgICAgIGlmIChvdXRwdXRUZW5zb3IgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgcmVxdWlyZWQgb3V0cHV0IFske291dHB1dEluZGV4fV0gZG9lcyBub3QgaGF2ZSB2YWx1ZWApO1xuICAgICAgICB9XG4gICAgICAgIGlmIChvdXRwdXRJbmRleCA9PT0gMCkge1xuICAgICAgICAgIGF3YWl0IG91dHB1dFRlbnNvci5nZXREYXRhKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVudXNlZC1leHByZXNzaW9uc1xuICAgICAgICAgIG91dHB1dFRlbnNvci5kYXRhO1xuICAgICAgICB9XG4gICAgICAgIG91dHB1dC5wdXNoKG91dHB1dFRlbnNvcik7XG4gICAgICB9XG4gICAgICBMb2dnZXIudmVyYm9zZSgnRXhlY1BsYW4nLCAnZGlzcG9zaW5nIG9mIGluZmVyZW5jZUhhbmRsZXInKTtcbiAgICAgIGluZmVyZW5jZUhhbmRsZXIuZGlzcG9zZSgpO1xuICAgICAgcmV0dXJuIG91dHB1dDtcbiAgICB9KTtcbiAgfVxuXG4gIF92YWx1ZXM6IEFycmF5PFRlbnNvcnx1bmRlZmluZWQ+O1xuICBfb3BzOiBLZXJuZWxPcFtdO1xuICBfc3RhcnRlcjogbnVtYmVyW107XG59XG4iLCIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtvbm54fSBmcm9tICdvbm54LXByb3RvJztcblxuaW1wb3J0IHtBdHRyaWJ1dGV9IGZyb20gJy4vYXR0cmlidXRlJztcbmltcG9ydCB7b25ueHJ1bnRpbWV9IGZyb20gJy4vb3J0LXNjaGVtYS9vcnQtZ2VuZXJhdGVkJztcbmltcG9ydCB7VGVuc29yfSBmcm9tICcuL3RlbnNvcic7XG5pbXBvcnQge0xvbmdVdGlsLCBNQVhfQ0xJUCwgTUlOX0NMSVAsIFByb3RvVXRpbH0gZnJvbSAnLi91dGlsJztcblxuaW1wb3J0IG9ydEZicyA9IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnM7XG5cbmV4cG9ydCBkZWNsYXJlIG5hbWVzcGFjZSBHcmFwaCB7XG4gIGV4cG9ydCBpbnRlcmZhY2UgU2hhcGUge1xuICAgIHJlYWRvbmx5IGRpbXM6IHJlYWRvbmx5IG51bWJlcltdO1xuICB9XG4gIGV4cG9ydCBpbnRlcmZhY2UgVmFsdWVUeXBlIHtcbiAgICByZWFkb25seSB0ZW5zb3JUeXBlOiBUZW5zb3IuRGF0YVR5cGU7XG4gICAgcmVhZG9ubHkgc2hhcGU6IFNoYXBlO1xuICB9XG4gIGV4cG9ydCBpbnRlcmZhY2UgVmFsdWUge1xuICAgIC8vIHRoZSB0ZW5zb3IgZGF0YS4gZW1wdHkgZm9yIG5vbi1pbml0aWFsaXplZCBpbnB1dHNcbiAgICByZWFkb25seSB0ZW5zb3I/OiBUZW5zb3I7XG5cbiAgICAvLyBpbmRleCB0byB0aGUgTm9kZSB3aGVyZSB0aGUgdmFsdWUgY29tZXMgZnJvbS4gLTEgZm9yIGluaXRpYWxpemVyLlxuICAgIHJlYWRvbmx5IGZyb206IG51bWJlcjtcblxuICAgIC8vIGluZGljZXMgdG8gdGhlIE5vZGVzIHdoZXJlIHRoZSB2YWx1ZXMgZ28gdG8uXG4gICAgcmVhZG9ubHkgdG86IHJlYWRvbmx5IG51bWJlcltdO1xuXG4gICAgLy8gdmFsdWUgdHlwZSBzcGVjaWZpY2F0aW9uLiBlbXB0eSBmb3Igbm9uLWlucHV0IHZhbHVlcy5cbiAgICByZWFkb25seSB0eXBlPzogVmFsdWVUeXBlO1xuICB9XG4gIGV4cG9ydCBpbnRlcmZhY2UgTm9kZSB7XG4gICAgLy8gbmFtZSBvZiB0aGUgbm9kZVxuICAgIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcblxuICAgIC8vIHRoZSBvcGVyYXRvciB0eXBlXG4gICAgcmVhZG9ubHkgb3BUeXBlOiBzdHJpbmc7XG5cbiAgICAvLyBpbmRpY2VzIHRvIHRoZSBWYWx1ZXMgd2hlcmUgdGhlIGlucHV0cyBjb21lIGZyb20uXG4gICAgcmVhZG9ubHkgaW5wdXRzOiByZWFkb25seSBudW1iZXJbXTtcblxuICAgIC8vIGluZGljZXMgdG8gdGhlIFZhbHVlcyB3aGVyZSB0aGUgb3V0cHVzIGdvIHRvLlxuICAgIHJlYWRvbmx5IG91dHB1dHM6IHJlYWRvbmx5IG51bWJlcltdO1xuXG4gICAgLy8gdGhlIGF0dHJpYnV0ZXMgdGhhdCB1c2VkIGJ5IHRoZSBvcGVyYXRvclxuICAgIHJlYWRvbmx5IGF0dHJpYnV0ZXM6IEF0dHJpYnV0ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBhIFRyYW5zZm9ybWVyIGlzIGFuIGluc3RhbmNlIHRoYXQgYWxsb3dzIGFsbCBwb3NzaWJsZSB0cmFuc2Zvcm1hdGlvbiBvcGVyYXRpb25zIHRoYXQgYXBwbGllZCB0byBhIGdyYXBoXG4gICAqL1xuICBleHBvcnQgaW50ZXJmYWNlIFRyYW5zZm9ybWVyIHtcbiAgICByZW1vdmVBbGxJZGVudGl0eU5vZGVzKCk6IHZvaWQ7XG4gICAgcmVtb3ZlQWxsRHJvcG91dE5vZGVzKCk6IHZvaWQ7XG4gICAgZnVzZUNvbnZBY3RpdmF0aW9uTm9kZXMoKTogdm9pZDtcbiAgICAvLyBUT0RPOiBhZGQgZ2VuZXJpYyBmdW5jdGlvbnMgdG8gbWFuaXB1bGF0ZSB0aGUgZ3JhcGhcbiAgfVxuXG4gIC8vIGFuIGluaXRpYWxpemVyIGNhbiB1c2UgdHJhbnNmb3JtZXIgdG8gdHJhbnNmb3JtIHRoZSBncmFwaFxuICBleHBvcnQgaW50ZXJmYWNlIEluaXRpYWxpemVyIHtcbiAgICB0cmFuc2Zvcm1HcmFwaCh0cmFuc2Zvcm1lcjogVHJhbnNmb3JtZXIpOiB2b2lkO1xuICB9XG59XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVkZWNsYXJlXG5leHBvcnQgaW50ZXJmYWNlIEdyYXBoIHtcbiAgZ2V0SW5wdXRJbmRpY2VzKCk6IHJlYWRvbmx5IG51bWJlcltdO1xuICBnZXRJbnB1dE5hbWVzKCk6IHJlYWRvbmx5IHN0cmluZ1tdO1xuICBnZXRPdXRwdXRJbmRpY2VzKCk6IHJlYWRvbmx5IG51bWJlcltdO1xuICBnZXRPdXRwdXROYW1lcygpOiByZWFkb25seSBzdHJpbmdbXTtcbiAgZ2V0VmFsdWVzKCk6IHJlYWRvbmx5IEdyYXBoLlZhbHVlW107XG4gIGdldE5vZGVzKCk6IHJlYWRvbmx5IEdyYXBoLk5vZGVbXTtcbn1cblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvbiwgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlZGVjbGFyZVxuZXhwb3J0IGNvbnN0IEdyYXBoID0ge1xuICAvKipcbiAgICogY29uc3RydWN0IGEgZ3JhcGggZnJvbSBhIGdyYXBoIHByb3RvYnVmIHR5cGVcbiAgICovXG4gIGZyb206IChncmFwaFByb3RvOiBvbm54LklHcmFwaFByb3RvfG9ydEZicy5HcmFwaCwgaW5pdGlhbGl6ZXI/OiBHcmFwaC5Jbml0aWFsaXplcikgPT5cbiAgICAgIG5ldyBHcmFwaEltcGwoZ3JhcGhQcm90bywgaW5pdGlhbGl6ZXIpLFxufTtcblxuY2xhc3MgVmFsdWUgaW1wbGVtZW50cyBHcmFwaC5WYWx1ZSB7XG4gIGNvbnN0cnVjdG9yKHZhbHVlSW5mbz86IG9ubnguSVZhbHVlSW5mb1Byb3RvKSB7XG4gICAgdGhpcy5fZnJvbSA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl90byA9IFtdO1xuICAgIHRoaXMudGVuc29yID0gdW5kZWZpbmVkO1xuICAgIHRoaXMudHlwZSA9IHVuZGVmaW5lZDtcblxuICAgIGlmICh2YWx1ZUluZm8pIHtcbiAgICAgIHRoaXMudHlwZSA9IFByb3RvVXRpbC50ZW5zb3JWYWx1ZVR5cGVGcm9tUHJvdG8odmFsdWVJbmZvLnR5cGUhLnRlbnNvclR5cGUhKTtcbiAgICB9XG4gIH1cblxuICBfZnJvbT86IG51bWJlcjsgIC8vIC0xIHJlcHJlc2VudCBmcm9tIGluaXRpYWxpemVyXG4gIGdldCBmcm9tKCkge1xuICAgIHJldHVybiB0aGlzLl9mcm9tITtcbiAgfVxuICBfdG86IG51bWJlcltdO1xuICBnZXQgdG8oKSB7XG4gICAgcmV0dXJuIHRoaXMuX3RvO1xuICB9XG4gIHR5cGU/OiBHcmFwaC5WYWx1ZVR5cGU7XG4gIHRlbnNvcj86IFRlbnNvcjtcbn1cblxuY2xhc3MgTm9kZSBpbXBsZW1lbnRzIEdyYXBoLk5vZGUge1xuICBjb25zdHJ1Y3Rvcihfbm9kZVByb3RvOiBvbm54LklOb2RlUHJvdG98b3J0RmJzLk5vZGUsIG5hbWU/OiBzdHJpbmcpIHtcbiAgICBpZiAoX25vZGVQcm90byBpbnN0YW5jZW9mIG9ubnguTm9kZVByb3RvKSB7XG4gICAgICB0aGlzLm5hbWUgPSBfbm9kZVByb3RvLm5hbWU7XG4gICAgICB0aGlzLm9wVHlwZSA9IF9ub2RlUHJvdG8ub3BUeXBlO1xuICAgICAgdGhpcy5hdHRyaWJ1dGVzID0gbmV3IEF0dHJpYnV0ZShfbm9kZVByb3RvLmF0dHJpYnV0ZSk7XG4gICAgfSBlbHNlIGlmIChfbm9kZVByb3RvIGluc3RhbmNlb2Ygb3J0RmJzLk5vZGUpIHtcbiAgICAgIHRoaXMubmFtZSA9IG5hbWUgPz8gX25vZGVQcm90by5uYW1lKCkhO1xuICAgICAgdGhpcy5vcFR5cGUgPSBfbm9kZVByb3RvLm9wVHlwZSgpITtcbiAgICAgIHRoaXMuYXR0cmlidXRlcyA9IG5ldyBBdHRyaWJ1dGUoUHJvdG9VdGlsLnRlbnNvckF0dHJpYnV0ZXNGcm9tT1JURm9ybWF0KF9ub2RlUHJvdG8pKTtcbiAgICB9XG5cbiAgICB0aGlzLmlucHV0cyA9IFtdO1xuICAgIHRoaXMub3V0cHV0cyA9IFtdO1xuICAgIHRoaXMuZXhlY3V0ZU5vZGUgPSB0cnVlO1xuICB9XG5cbiAgbmFtZTogc3RyaW5nO1xuICBvcFR5cGU6IHN0cmluZztcbiAgaW5wdXRzOiBudW1iZXJbXTtcbiAgb3V0cHV0czogbnVtYmVyW107XG4gIGF0dHJpYnV0ZXM6IEF0dHJpYnV0ZTtcbiAgZXhlY3V0ZU5vZGU6IGJvb2xlYW47XG59XG5cbmNsYXNzIEdyYXBoSW1wbCBpbXBsZW1lbnRzIEdyYXBoLCBHcmFwaC5UcmFuc2Zvcm1lciB7XG4gIHByaXZhdGUgX2FsbERhdGE6IFZhbHVlW107XG5cbiAgcHJpdmF0ZSBfYWxsSW5wdXRJbmRpY2VzOiBudW1iZXJbXTtcbiAgcHJpdmF0ZSBfYWxsSW5wdXROYW1lczogc3RyaW5nW107XG5cbiAgcHJpdmF0ZSBfYWxsT3V0cHV0SW5kaWNlczogbnVtYmVyW107XG4gIHByaXZhdGUgX2FsbE91dHB1dE5hbWVzOiBzdHJpbmdbXTtcblxuICBwcml2YXRlIF9ub2RlczogTm9kZVtdO1xuXG4gIGNvbnN0cnVjdG9yKGdyYXBoOiBvbm54LklHcmFwaFByb3RvfG9ydEZicy5HcmFwaCwgZ3JhcGhJbml0aWFsaXplcj86IEdyYXBoLkluaXRpYWxpemVyKSB7XG4gICAgaWYgKCFncmFwaCkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignZ3JhcGggaXMgZW1wdHknKTtcbiAgICB9XG5cbiAgICAvLyBidWlsZCB0aGUgZ3JhcGggLSB3aWxsIHRocm93IGV4Y2VwdGlvbnMgaWYgc29tZXRoaW5nIGZhdGFsIGlzIGRldGVjdGVkXG4gICAgdGhpcy5idWlsZEdyYXBoKGdyYXBoKTtcblxuICAgIC8vIGV4ZWN1dGUgYW55IHRyYW5zZm9ybWF0aW9uIGxvZ2ljIGZvciB0aGUgZ3JhcGggKGlmIGFwcGxpY2FibGUpXG4gICAgdGhpcy50cmFuc2Zvcm1HcmFwaChncmFwaEluaXRpYWxpemVyKTtcblxuICAgIC8vIGNoZWNrIGZvciBjeWNsZXMgYW5kIG90aGVyIGluY29uc2lzdGVuY2llcyAtIHdpbGwgdGhyb3cgZXhjZXB0aW9ucyBpZiBzb21ldGhpbmcgZmF0YWwgaXMgZGV0ZWN0ZWRcbiAgICB0aGlzLmNoZWNrSXNBY3ljbGljKCk7XG4gIH1cblxuICBnZXRJbnB1dEluZGljZXMoKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIHJldHVybiB0aGlzLl9hbGxJbnB1dEluZGljZXM7XG4gIH1cblxuICBnZXRJbnB1dE5hbWVzKCk6IHJlYWRvbmx5IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5fYWxsSW5wdXROYW1lcztcbiAgfVxuXG4gIGdldE91dHB1dEluZGljZXMoKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIHJldHVybiB0aGlzLl9hbGxPdXRwdXRJbmRpY2VzO1xuICB9XG5cbiAgZ2V0T3V0cHV0TmFtZXMoKTogcmVhZG9ubHkgc3RyaW5nW10ge1xuICAgIHJldHVybiB0aGlzLl9hbGxPdXRwdXROYW1lcztcbiAgfVxuXG4gIGdldFZhbHVlcygpOiByZWFkb25seSBHcmFwaC5WYWx1ZVtdIHtcbiAgICByZXR1cm4gdGhpcy5fYWxsRGF0YTtcbiAgfVxuXG4gIGdldE5vZGVzKCk6IHJlYWRvbmx5IEdyYXBoLk5vZGVbXSB7XG4gICAgcmV0dXJuIHRoaXMuX25vZGVzO1xuICB9XG5cbiAgcHJpdmF0ZSBidWlsZEdyYXBoKGdyYXBoOiBvbm54LklHcmFwaFByb3RvfG9ydEZicy5HcmFwaCkge1xuICAgIC8vIGJ1aWxkIHRoZSBncmFwaCAtIHdpbGwgdGhyb3cgZXhjZXB0aW9ucyBpZiBzb21ldGhpbmcgZmF0YWwgaXMgZGV0ZWN0ZWRcbiAgICBpZiAoZ3JhcGggaW5zdGFuY2VvZiBvbm54LkdyYXBoUHJvdG8pIHtcbiAgICAgIHRoaXMuYnVpbGRHcmFwaEZyb21Pbm54Rm9ybWF0KGdyYXBoKTtcbiAgICB9IGVsc2UgaWYgKGdyYXBoIGluc3RhbmNlb2Ygb3J0RmJzLkdyYXBoKSB7XG4gICAgICB0aGlzLmJ1aWxkR3JhcGhGcm9tT3J0Rm9ybWF0KGdyYXBoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignR3JhcGggdHlwZSBpcyBub3Qgc3VwcG9ydGVkLicpO1xuICAgIH1cbiAgfVxuICBwcml2YXRlIGJ1aWxkR3JhcGhGcm9tT25ueEZvcm1hdChncmFwaDogb25ueC5JR3JhcGhQcm90bykge1xuICAgIGNvbnN0IGRhdGFJbmRpY2VzID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcbiAgICB0aGlzLl9hbGxEYXRhID0gW107XG5cbiAgICB0aGlzLl9hbGxJbnB1dEluZGljZXMgPSBbXTtcbiAgICB0aGlzLl9hbGxJbnB1dE5hbWVzID0gW107XG5cbiAgICB0aGlzLl9hbGxPdXRwdXRJbmRpY2VzID0gW107XG4gICAgdGhpcy5fYWxsT3V0cHV0TmFtZXMgPSBbXTtcblxuICAgIHRoaXMuX25vZGVzID0gW107XG5cbiAgICBjb25zdCBub2Rlc0luZGljZXMgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xuXG4gICAgLy8gc2NhbiBhbGwgaW5wdXRzXG4gICAgaWYgKCFncmFwaC5pbnB1dCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIGluZm9ybWF0aW9uIGluIGdyYXBoOiBpbnB1dCcpO1xuICAgIH1cbiAgICBjb25zdCBpbnB1dFZhbHVlTmFtZXMgPSBbXTtcbiAgICBmb3IgKGNvbnN0IGkgb2YgZ3JhcGguaW5wdXQpIHtcbiAgICAgIGlmIChkYXRhSW5kaWNlcy5oYXMoaS5uYW1lISkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBkdXBsaWNhdGVkIGlucHV0IG5hbWU6ICR7aS5uYW1lfWApO1xuICAgICAgfVxuICAgICAgY29uc3QgY3VycmVudEluZGV4ID0gdGhpcy5fYWxsRGF0YS5wdXNoKG5ldyBWYWx1ZShpKSkgLSAxO1xuICAgICAgZGF0YUluZGljZXMuc2V0KGkubmFtZSEsIGN1cnJlbnRJbmRleCk7XG4gICAgICBpbnB1dFZhbHVlTmFtZXMucHVzaChpLm5hbWUhKTtcbiAgICB9XG5cbiAgICAvLyBzY2FuIGFsbCBpbml0aWFsaXplcnNcbiAgICBpZiAoIWdyYXBoLmluaXRpYWxpemVyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgaW5mb3JtYXRpb24gaW4gZ3JhcGg6IGluaXRpYWxpemVyJyk7XG4gICAgfVxuICAgIGZvciAoY29uc3QgaSBvZiBncmFwaC5pbml0aWFsaXplcikge1xuICAgICAgbGV0IGluZGV4ID0gZGF0YUluZGljZXMuZ2V0KGkubmFtZSEpO1xuICAgICAgaWYgKGluZGV4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29uc3QgdmFsdWUgPSBuZXcgVmFsdWUoKTtcbiAgICAgICAgdmFsdWUudHlwZSA9IHtcbiAgICAgICAgICBzaGFwZToge2RpbXM6IFByb3RvVXRpbC50ZW5zb3JEaW1zRnJvbVByb3RvKGkuZGltcyEpfSxcbiAgICAgICAgICB0ZW5zb3JUeXBlOiBQcm90b1V0aWwudGVuc29yRGF0YVR5cGVGcm9tUHJvdG8oaS5kYXRhVHlwZSEpXG4gICAgICAgIH07XG4gICAgICAgIGluZGV4ID0gdGhpcy5fYWxsRGF0YS5wdXNoKHZhbHVlKSAtIDE7XG4gICAgICAgIGRhdGFJbmRpY2VzLnNldChpLm5hbWUhLCBpbmRleCk7XG4gICAgICB9XG4gICAgICB0aGlzLl9hbGxEYXRhW2luZGV4XS5fZnJvbSA9IC0xO1xuICAgICAgdGhpcy5fYWxsRGF0YVtpbmRleF0udGVuc29yID0gVGVuc29yLmZyb21Qcm90byhpKTtcbiAgICB9XG5cbiAgICAvLyBmaWx0ZXIgb3V0IGlucHV0IGluZGljZXNcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2FsbERhdGEubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmICghdGhpcy5fYWxsRGF0YVtpXS50ZW5zb3IpIHtcbiAgICAgICAgdGhpcy5fYWxsSW5wdXRJbmRpY2VzLnB1c2goaSk7XG4gICAgICAgIHRoaXMuX2FsbElucHV0TmFtZXMucHVzaChpbnB1dFZhbHVlTmFtZXNbaV0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHNjYW4gYWxsIG91dHB1dHNcbiAgICBpZiAoIWdyYXBoLm91dHB1dCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIGluZm9ybWF0aW9uIGluIGdyYXBoOiBvdXRwdXQnKTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBpIG9mIGdyYXBoLm91dHB1dCkge1xuICAgICAgaWYgKGRhdGFJbmRpY2VzLmhhcyhpLm5hbWUhKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGR1cGxpY2F0ZWQgb3V0cHV0IG5hbWU6ICR7aS5uYW1lfWApO1xuICAgICAgfVxuICAgICAgY29uc3QgY3VycmVudEluZGV4ID0gdGhpcy5fYWxsRGF0YS5wdXNoKG5ldyBWYWx1ZShpKSkgLSAxO1xuICAgICAgZGF0YUluZGljZXMuc2V0KGkubmFtZSEsIGN1cnJlbnRJbmRleCk7XG4gICAgICB0aGlzLl9hbGxPdXRwdXRJbmRpY2VzLnB1c2goY3VycmVudEluZGV4KTtcbiAgICAgIHRoaXMuX2FsbE91dHB1dE5hbWVzLnB1c2goaS5uYW1lISk7XG4gICAgfVxuXG4gICAgLy8gc2NhbiBhbGwgbm9kZXNcbiAgICBpZiAoIWdyYXBoLm5vZGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyBpbmZvcm1hdGlvbiBpbiBncmFwaDogbm9kZScpO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IG5vZGVQcm90byBvZiBncmFwaC5ub2RlKSB7XG4gICAgICBpZiAoIW5vZGVQcm90by5uYW1lKSB7XG4gICAgICAgIC8vIGFzc2lnbiBhIG5hbWUgdG8gdGhlIG5vZGUgaWYgaXQgZG9lc24ndCBoYXZlIG9uZVxuICAgICAgICBmb3IgKGxldCBwaWNrID0gMDs7IHBpY2srKykge1xuICAgICAgICAgIGNvbnN0IG5hbWUgPSBgdW5uYW1lZF8ke25vZGVQcm90by5vcFR5cGV9XyR7cGlja31gO1xuICAgICAgICAgIGlmICghbm9kZXNJbmRpY2VzLmhhcyhuYW1lKSkge1xuICAgICAgICAgICAgbm9kZVByb3RvLm5hbWUgPSBuYW1lO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChub2Rlc0luZGljZXMuaGFzKG5vZGVQcm90by5uYW1lKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGR1cGxpY2F0ZWQgbm9kZSBuYW1lOiAke25vZGVQcm90by5uYW1lfWApO1xuICAgICAgfVxuICAgICAgY29uc3QgY3VycmVudEluZGV4ID0gdGhpcy5fbm9kZXMucHVzaChuZXcgTm9kZShub2RlUHJvdG8pKSAtIDE7XG4gICAgICBub2Rlc0luZGljZXMuc2V0KG5vZGVQcm90by5uYW1lLCBjdXJyZW50SW5kZXgpO1xuICAgIH1cblxuICAgIC8vIHNjYW4gbm9kZSdzIG91dHB1dHNcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX25vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBub2RlID0gdGhpcy5fbm9kZXNbaV07XG4gICAgICBjb25zdCBub2RlUHJvdG8gPSBncmFwaC5ub2RlW2ldO1xuICAgICAgaWYgKCFub2RlUHJvdG8ub3V0cHV0KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgbWlzc2luZyBvdXRwdXQgZm9yIG5vZGU6ICR7bm9kZVByb3RvLm5hbWV9YCk7XG4gICAgICB9XG4gICAgICBmb3IgKGNvbnN0IG91dHB1dCBvZiBub2RlUHJvdG8ub3V0cHV0KSB7XG4gICAgICAgIGxldCBkYXRhSW5kZXggPSBkYXRhSW5kaWNlcy5nZXQob3V0cHV0KTtcbiAgICAgICAgaWYgKHR5cGVvZiBkYXRhSW5kZXggPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgZGF0YUluZGV4ID0gdGhpcy5fYWxsRGF0YS5wdXNoKG5ldyBWYWx1ZSgpKSAtIDE7XG4gICAgICAgICAgZGF0YUluZGljZXMuc2V0KG91dHB1dCwgZGF0YUluZGV4KTtcbiAgICAgICAgfVxuICAgICAgICBub2RlLm91dHB1dHMucHVzaChkYXRhSW5kZXgpO1xuXG4gICAgICAgIGlmICh0aGlzLl9hbGxEYXRhW2RhdGFJbmRleF0uX2Zyb20gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgbXVsdGlwbGUgbm9kZXMgb3V0cHV0IHRvIG9uZSBkYXRhIHZhbHVlOiAke2RhdGFJbmRleH1gKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9hbGxEYXRhW2RhdGFJbmRleF0uX2Zyb20gPSBpO1xuXG4gICAgICAgIC8vIGZvciB0aGUgJ0NvbnN0YW50JyBvcGVyYXRvciwganVzdCBjcmVhdGUgYSBuZXcgZWRnZSBpbiB0aGUgZ3JhcGggY29ycmVzcG9uZGluZyB0byB0aGUgJ291dHB1dCcgb2YgdGhlXG4gICAgICAgIC8vIG9wZXJhdG9yIGFuZCBpZ25vcmUgdGhlIG5vZGUgZnJvbSB0aGUgZ3JhcGhcbiAgICAgICAgaWYgKG5vZGVQcm90by5vcFR5cGUgPT09ICdDb25zdGFudCcpIHtcbiAgICAgICAgICBpZiAoIW5vZGVQcm90by5hdHRyaWJ1dGUgfHwgbm9kZVByb3RvLmF0dHJpYnV0ZS5sZW5ndGggIT09IDEgfHwgIW5vZGVQcm90by5hdHRyaWJ1dGVbMF0udCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdtaXNzaW5nIGF0dHJpYnV0ZXMgb3IgbWlzc2luZyB0ZW5zb3IgdmFsdWUgaW4gYXR0cmlidXRlcyBmb3IgdGhpcyBDb25zdGFudCBvcGVyYXRvcicpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIW5vZGVQcm90by5vdXRwdXQgfHwgbm9kZVByb3RvLm91dHB1dC5sZW5ndGggIT09IDEpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyBvdXRwdXQgb3IgaW5jb3JyZWN0IG51bWJlciBvZiBvdXRwdXRzIGZvciB0aGlzIENvbnN0YW50IG9wZXJhdG9yJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIG5vZGUub3V0cHV0cy5wb3AoKTtcbiAgICAgICAgICBub2RlLmV4ZWN1dGVOb2RlID0gZmFsc2U7XG5cbiAgICAgICAgICB0aGlzLl9hbGxEYXRhW2RhdGFJbmRleF0uX2Zyb20gPSAtMTtcbiAgICAgICAgICB0aGlzLl9hbGxEYXRhW2RhdGFJbmRleF0udGVuc29yID0gVGVuc29yLmZyb21Qcm90byhub2RlUHJvdG8uYXR0cmlidXRlWzBdLnQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gc2NhbiBub2RlJ3MgaW5wdXRzXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9ub2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3Qgbm9kZSA9IHRoaXMuX25vZGVzW2ldO1xuICAgICAgY29uc3Qgbm9kZVByb3RvID0gZ3JhcGgubm9kZVtpXTtcblxuICAgICAgaWYgKCFub2RlUHJvdG8uaW5wdXQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBtaXNzaW5nIGlucHV0IGZvciBub2RlOiAke25vZGVQcm90by5uYW1lfWApO1xuICAgICAgfVxuICAgICAgZm9yIChjb25zdCBpbnB1dCBvZiBub2RlUHJvdG8uaW5wdXQpIHtcbiAgICAgICAgY29uc3QgZGF0YUluZGV4ID0gZGF0YUluZGljZXMuZ2V0KGlucHV0KTtcbiAgICAgICAgaWYgKHR5cGVvZiBkYXRhSW5kZXggPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgLy8gaGFuZGxlIGV4Y2VwdGlvbiB3aGVuIG9wc2V0ID4gOSBhbmQgcm9pIG5vdCBnaXZlblxuICAgICAgICAgIGlmIChpbnB1dCA9PT0gJycgJiYgbm9kZVByb3RvLmlucHV0Lmxlbmd0aCA9PT0gMyAmJiBub2RlUHJvdG8ub3BUeXBlID09PSAnUmVzaXplJykge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgdW5yZWNvZ25pemVkIGlucHV0ICcke2lucHV0fScgZm9yIG5vZGU6ICR7bm9kZVByb3RvLm5hbWV9YCk7XG4gICAgICAgIH1cbiAgICAgICAgbm9kZS5pbnB1dHMucHVzaChkYXRhSW5kZXgpO1xuXG4gICAgICAgIHRoaXMuX2FsbERhdGFbZGF0YUluZGV4XS5fdG8ucHVzaChpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHByaXZhdGUgYnVpbGRHcmFwaEZyb21PcnRGb3JtYXQoZ3JhcGg6IG9ydEZicy5HcmFwaCkge1xuICAgIGNvbnN0IGRhdGFJbmRpY2VzID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcbiAgICB0aGlzLl9hbGxEYXRhID0gW107XG5cbiAgICB0aGlzLl9hbGxJbnB1dEluZGljZXMgPSBbXTtcbiAgICB0aGlzLl9hbGxJbnB1dE5hbWVzID0gW107XG5cbiAgICB0aGlzLl9hbGxPdXRwdXRJbmRpY2VzID0gW107XG4gICAgdGhpcy5fYWxsT3V0cHV0TmFtZXMgPSBbXTtcblxuICAgIHRoaXMuX25vZGVzID0gW107XG5cbiAgICBjb25zdCBub2Rlc0luZGljZXMgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xuXG4gICAgLy8gc2NhbiBhbGwgaW5wdXRzXG4gICAgY29uc3QgaW5wdXRWYWx1ZU5hbWVzID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBncmFwaC5pbnB1dHNMZW5ndGgoKTsgaSsrKSB7XG4gICAgICBjb25zdCBpbnB1dE5hbWUgPSBncmFwaC5pbnB1dHMoaSk7XG4gICAgICBpZiAoZGF0YUluZGljZXMuaGFzKGlucHV0TmFtZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBkdXBsaWNhdGVkIGlucHV0IG5hbWU6ICR7aW5wdXROYW1lfWApO1xuICAgICAgfVxuICAgICAgLy8gRmluZCB0aGUgaW5wdXQgdHlwZUluZm8gZnJvbSBub2RlYXJnc1xuICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBncmFwaC5ub2RlQXJnc0xlbmd0aCgpOyBqKyspIHtcbiAgICAgICAgaWYgKGdyYXBoLm5vZGVBcmdzKGopPy5uYW1lKCkgPT09IGlucHV0TmFtZSkge1xuICAgICAgICAgIGNvbnN0IHZhbHVlID0gbmV3IFZhbHVlKCk7XG4gICAgICAgICAgY29uc3QgdmFsdWVUeXBlID0gZ3JhcGgubm9kZUFyZ3Moaik/LnR5cGUoKT8udmFsdWVUeXBlKCk7XG4gICAgICAgICAgaWYgKHZhbHVlVHlwZSAhPT0gb3J0RmJzLlR5cGVJbmZvVmFsdWUudGVuc29yX3R5cGUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVW5leHBlY3RlZCB2YWx1ZSB0eXBlIGZvciB0aGUgbm9kZUFyZy4nKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgdmFsdWVJbmZvID0gZ3JhcGgubm9kZUFyZ3MoaikhLnR5cGUoKSEudmFsdWUobmV3IG9ydEZicy5UZW5zb3JUeXBlQW5kU2hhcGUoKSkhO1xuICAgICAgICAgIGNvbnN0IHR5cGUgPSBQcm90b1V0aWwudGVuc29yRGF0YVR5cGVGcm9tUHJvdG8odmFsdWVJbmZvLmVsZW1UeXBlKCkpO1xuICAgICAgICAgIGNvbnN0IHNoYXBlID0gdmFsdWVJbmZvLnNoYXBlKCkhO1xuICAgICAgICAgIGNvbnN0IGRpbXMgPSBbXTtcbiAgICAgICAgICBmb3IgKGxldCBrID0gMDsgayA8IHNoYXBlLmRpbUxlbmd0aCgpITsgaysrKSB7XG4gICAgICAgICAgICBkaW1zLnB1c2goTG9uZ1V0aWwubG9uZ1RvTnVtYmVyKHNoYXBlLmRpbShrKSEudmFsdWUoKSEuZGltVmFsdWUoKSEpKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdmFsdWUudHlwZSA9IHtzaGFwZToge2RpbXN9LCB0ZW5zb3JUeXBlOiB0eXBlfTtcbiAgICAgICAgICBjb25zdCBjdXJyZW50SW5kZXggPSB0aGlzLl9hbGxEYXRhLnB1c2godmFsdWUpIC0gMTtcbiAgICAgICAgICBkYXRhSW5kaWNlcy5zZXQoaW5wdXROYW1lLCBjdXJyZW50SW5kZXgpO1xuICAgICAgICAgIGlucHV0VmFsdWVOYW1lcy5wdXNoKGlucHV0TmFtZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgLy8gY2hlY2sgaW5pdGlhbGl6ZXJzXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBncmFwaC5pbml0aWFsaXplcnNMZW5ndGgoKTsgaSsrKSB7XG4gICAgICBjb25zdCBpbml0aWFsaXplciA9IGdyYXBoLmluaXRpYWxpemVycyhpKSE7XG4gICAgICBsZXQgaW5kZXggPSBkYXRhSW5kaWNlcy5nZXQoaW5pdGlhbGl6ZXIubmFtZSgpISk7XG4gICAgICBpZiAoaW5kZXggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IG5ldyBWYWx1ZSgpO1xuICAgICAgICBjb25zdCBkaW1zID0gUHJvdG9VdGlsLnRlbnNvckRpbXNGcm9tT1JURm9ybWF0KGluaXRpYWxpemVyKTtcbiAgICAgICAgY29uc3QgdHlwZSA9IFByb3RvVXRpbC50ZW5zb3JEYXRhVHlwZUZyb21Qcm90byhpbml0aWFsaXplci5kYXRhVHlwZSgpKTtcbiAgICAgICAgdmFsdWUudHlwZSA9IHtzaGFwZToge2RpbXN9LCB0ZW5zb3JUeXBlOiB0eXBlfTtcbiAgICAgICAgaW5kZXggPSB0aGlzLl9hbGxEYXRhLnB1c2godmFsdWUpIC0gMTtcbiAgICAgICAgZGF0YUluZGljZXMuc2V0KGluaXRpYWxpemVyLm5hbWUoKSEsIGluZGV4KTtcbiAgICAgIH1cbiAgICAgIHRoaXMuX2FsbERhdGFbaW5kZXhdLl9mcm9tID0gLTE7XG4gICAgICB0aGlzLl9hbGxEYXRhW2luZGV4XS50ZW5zb3IgPSBUZW5zb3IuZnJvbU9ydFRlbnNvcihpbml0aWFsaXplcik7XG4gICAgfVxuXG4gICAgLy8gZmlsdGVyIG91dCBpbnB1dCBpbmRpY2VzXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9hbGxEYXRhLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoIXRoaXMuX2FsbERhdGFbaV0udGVuc29yKSB7XG4gICAgICAgIHRoaXMuX2FsbElucHV0SW5kaWNlcy5wdXNoKGkpO1xuICAgICAgICB0aGlzLl9hbGxJbnB1dE5hbWVzLnB1c2goaW5wdXRWYWx1ZU5hbWVzW2ldKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBzY2FuIGFsbCBvdXRwdXRzXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBncmFwaC5vdXRwdXRzTGVuZ3RoKCk7IGkrKykge1xuICAgICAgY29uc3Qgb3V0cHV0TmFtZSA9IGdyYXBoLm91dHB1dHMoaSk7XG4gICAgICBpZiAoZGF0YUluZGljZXMuaGFzKG91dHB1dE5hbWUpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgZHVwbGljYXRlZCBvdXRwdXQgbmFtZTogJHtvdXRwdXROYW1lfWApO1xuICAgICAgfVxuICAgICAgY29uc3QgY3VycmVudEluZGV4ID0gdGhpcy5fYWxsRGF0YS5wdXNoKG5ldyBWYWx1ZSgpKSAtIDE7XG4gICAgICBkYXRhSW5kaWNlcy5zZXQob3V0cHV0TmFtZSwgY3VycmVudEluZGV4KTtcbiAgICAgIHRoaXMuX2FsbE91dHB1dEluZGljZXMucHVzaChjdXJyZW50SW5kZXgpO1xuICAgICAgdGhpcy5fYWxsT3V0cHV0TmFtZXMucHVzaChvdXRwdXROYW1lKTtcbiAgICB9XG5cbiAgICAvLyBzY2FuIGFsbCBub2Rlc1xuICAgIGlmICghZ3JhcGgubm9kZXMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbWlzc2luZyBpbmZvcm1hdGlvbiBpbiBncmFwaDogbm9kZScpO1xuICAgIH1cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGdyYXBoLm5vZGVzTGVuZ3RoKCk7IGkrKykge1xuICAgICAgY29uc3Qgbm9kZVByb3RvID0gZ3JhcGgubm9kZXMoaSk7XG4gICAgICBsZXQgbmFtZSA9IG5vZGVQcm90byEubmFtZSgpO1xuICAgICAgaWYgKCFuYW1lKSB7XG4gICAgICAgIC8vIGFzc2lnbiBhIG5hbWUgdG8gdGhlIG5vZGUgaWYgaXQgZG9lc24ndCBoYXZlIG9uZVxuICAgICAgICBmb3IgKGxldCBwaWNrID0gMDs7IHBpY2srKykge1xuICAgICAgICAgIG5hbWUgPSBgdW5uYW1lZF8ke25vZGVQcm90byEub3BUeXBlKCl9XyR7cGlja31gO1xuICAgICAgICAgIGlmICghbm9kZXNJbmRpY2VzLmhhcyhuYW1lKSkge1xuICAgICAgICAgICAgLy8gYW4gdW5pcXVlIG5hbWUgaXMgZm91bmQuIGJyZWFrLlxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChub2Rlc0luZGljZXMuaGFzKG5hbWUpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgZHVwbGljYXRlZCBub2RlIG5hbWU6ICR7bmFtZX1gKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGN1cnJlbnRJbmRleCA9IHRoaXMuX25vZGVzLnB1c2gobmV3IE5vZGUobm9kZVByb3RvISwgbmFtZSkpIC0gMTtcbiAgICAgIG5vZGVzSW5kaWNlcy5zZXQobmFtZSwgY3VycmVudEluZGV4KTtcbiAgICB9XG5cbiAgICAvLyBzY2FuIG5vZGUncyBvdXRwdXRzXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9ub2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3Qgbm9kZSA9IHRoaXMuX25vZGVzW2ldO1xuICAgICAgY29uc3Qgbm9kZVByb3RvID0gZ3JhcGgubm9kZXMoaSk7XG4gICAgICBpZiAobm9kZVByb3RvID09IG51bGwpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBObyBub2RlIGV4aXN0cyBhdCBpbmRleCAke2l9YCk7XG4gICAgICB9XG4gICAgICBpZiAobm9kZVByb3RvPy5vdXRwdXRzTGVuZ3RoKCkgPT09IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBtaXNzaW5nIG91dHB1dCBmb3Igbm9kZTogJHtub2RlUHJvdG8ubmFtZX1gKTtcbiAgICAgIH1cbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgbm9kZVByb3RvPy5vdXRwdXRzTGVuZ3RoKCk7IGorKykge1xuICAgICAgICBjb25zdCBvdXRwdXQgPSBub2RlUHJvdG8/Lm91dHB1dHMoaik7XG4gICAgICAgIGxldCBkYXRhSW5kZXggPSBkYXRhSW5kaWNlcy5nZXQob3V0cHV0KTtcbiAgICAgICAgaWYgKHR5cGVvZiBkYXRhSW5kZXggPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgZGF0YUluZGV4ID0gdGhpcy5fYWxsRGF0YS5wdXNoKG5ldyBWYWx1ZSgpKSAtIDE7XG4gICAgICAgICAgZGF0YUluZGljZXMuc2V0KG91dHB1dCwgZGF0YUluZGV4KTtcbiAgICAgICAgfVxuICAgICAgICBub2RlLm91dHB1dHMucHVzaChkYXRhSW5kZXgpO1xuXG4gICAgICAgIGlmICh0aGlzLl9hbGxEYXRhW2RhdGFJbmRleF0uX2Zyb20gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgbXVsdGlwbGUgbm9kZXMgb3V0cHV0IHRvIG9uZSBkYXRhIHZhbHVlOiAke2RhdGFJbmRleH1gKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9hbGxEYXRhW2RhdGFJbmRleF0uX2Zyb20gPSBpO1xuXG4gICAgICAgIC8vIGZvciB0aGUgJ0NvbnN0YW50JyBvcGVyYXRvciwganVzdCBjcmVhdGUgYSBuZXcgZWRnZSBpbiB0aGUgZ3JhcGggY29ycmVzcG9uZGluZyB0byB0aGUgJ291dHB1dCcgb2YgdGhlXG4gICAgICAgIC8vIG9wZXJhdG9yIGFuZCBpZ25vcmUgdGhlIG5vZGUgZnJvbSB0aGUgZ3JhcGhcbiAgICAgICAgaWYgKG5vZGVQcm90by5vcFR5cGUoKSA9PT0gJ0NvbnN0YW50Jykge1xuICAgICAgICAgIGlmIChub2RlUHJvdG8uYXR0cmlidXRlc0xlbmd0aCgpICE9PSAxIHx8ICFub2RlUHJvdG8uYXR0cmlidXRlcygwKSEudCgpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgYXR0cmlidXRlcyBvciBtaXNzaW5nIHRlbnNvciB2YWx1ZSBpbiBhdHRyaWJ1dGVzIGZvciB0aGlzIENvbnN0YW50IG9wZXJhdG9yJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChub2RlUHJvdG8ub3V0cHV0c0xlbmd0aCgpICE9PSAxKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ21pc3Npbmcgb3V0cHV0IG9yIGluY29ycmVjdCBudW1iZXIgb2Ygb3V0cHV0cyBmb3IgdGhpcyBDb25zdGFudCBvcGVyYXRvcicpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBub2RlLm91dHB1dHMucG9wKCk7XG4gICAgICAgICAgbm9kZS5leGVjdXRlTm9kZSA9IGZhbHNlO1xuXG4gICAgICAgICAgdGhpcy5fYWxsRGF0YVtkYXRhSW5kZXhdLl9mcm9tID0gLTE7XG4gICAgICAgICAgdGhpcy5fYWxsRGF0YVtkYXRhSW5kZXhdLnRlbnNvciA9IFRlbnNvci5mcm9tT3J0VGVuc29yKG5vZGVQcm90by5hdHRyaWJ1dGVzKDApIS50KCkhKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHNjYW4gbm9kZSdzIGlucHV0c1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fbm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IG5vZGUgPSB0aGlzLl9ub2Rlc1tpXTtcbiAgICAgIGNvbnN0IG5vZGVQcm90byA9IGdyYXBoLm5vZGVzKGkpITtcblxuICAgICAgaWYgKG5vZGVQcm90by5pbnB1dHNMZW5ndGgoKSA9PT0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYG1pc3NpbmcgaW5wdXQgZm9yIG5vZGU6ICR7bm9kZVByb3RvLm5hbWV9YCk7XG4gICAgICB9XG4gICAgICBmb3IgKGxldCBqID0gMDsgaiA8IG5vZGVQcm90by5pbnB1dHNMZW5ndGgoKSE7IGorKykge1xuICAgICAgICBjb25zdCBpbnB1dCA9IG5vZGVQcm90by5pbnB1dHMoaikhO1xuICAgICAgICBjb25zdCBkYXRhSW5kZXggPSBkYXRhSW5kaWNlcy5nZXQoaW5wdXQpO1xuICAgICAgICBpZiAodHlwZW9mIGRhdGFJbmRleCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVucmVjb2duaXplZCBpbnB1dCAnJHtpbnB1dH0nIGZvciBub2RlOiAke25vZGVQcm90byEubmFtZSgpfWApO1xuICAgICAgICB9XG4gICAgICAgIG5vZGUuaW5wdXRzLnB1c2goZGF0YUluZGV4KTtcblxuICAgICAgICB0aGlzLl9hbGxEYXRhW2RhdGFJbmRleF0uX3RvLnB1c2goaSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBjaGVja0lzQWN5Y2xpYygpIHtcbiAgICAvLyBnbyB0aHJvdWdoIHRoZSBncmFwaCBhbmQgY2hlY2sgZm9yIGN5Y2xlcyBvciBvdGhlciBmYXRhbCBpbmNvbnNpc3RlbmNpZXNcbiAgICBjb25zdCBzdGFydGVyczogU2V0PG51bWJlcj4gPSBuZXcgU2V0PG51bWJlcj4oKTtcbiAgICB0aGlzLl9hbGxJbnB1dEluZGljZXMuZm9yRWFjaChpID0+IHtcbiAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLl9hbGxEYXRhW2ldO1xuICAgICAgZGF0YS5fdG8uZm9yRWFjaChqID0+IHtcbiAgICAgICAgc3RhcnRlcnMuYWRkKGopO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICAvLyBJdGVyYXRpdmUgREZTIHRvIGNoZWNrIGZvciBjeWNsZXNcbiAgICBjb25zdCBub2Rlc1N0YWNrID0gQXJyYXkuZnJvbShzdGFydGVycyk7XG4gICAgY29uc3Qgbm9kZXNTdGF0ZSA9IG5ldyBBcnJheTxzdHJpbmc+KHRoaXMuX25vZGVzLmxlbmd0aCkuZmlsbCgnd2hpdGUnKTtcblxuICAgIHdoaWxlIChub2Rlc1N0YWNrLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IG5vZGVJbmRleCA9IG5vZGVzU3RhY2sucG9wKCkhO1xuICAgICAgLy8gdGhpcyBub2RlIGhhcyBub3cgYmVlbiBwcm9jZXNzZWQgY29tcGxldGVseS4gTWFyayB0aGlzIG5vZGUgJ2JsYWNrJyB0byBkZW5vdGUgdGhpcy5cbiAgICAgIGlmIChub2Rlc1N0YXRlW25vZGVJbmRleF0gPT09ICdncmF5Jykge1xuICAgICAgICBub2Rlc1N0YXRlW25vZGVJbmRleF0gPSAnYmxhY2snO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gdGhpcyBub2RlIGlzIHVuZGVyIHByb2Nlc3Npbmcgc3RhZ2UuIG1hcmsgdGhpcyBub2RlICdncmF5JyB0byBkZW5vdGUgdGhpcy5cbiAgICAgICAgbm9kZXNTdGFjay5wdXNoKG5vZGVJbmRleCk7XG4gICAgICAgIG5vZGVzU3RhdGVbbm9kZUluZGV4XSA9ICdncmF5JztcblxuICAgICAgICB0aGlzLl9ub2Rlc1tub2RlSW5kZXhdLm91dHB1dHMuZm9yRWFjaCgob3V0Z29pbmdFZGdlSW5kZXgpID0+IHtcbiAgICAgICAgICBjb25zdCBkYXRhID0gdGhpcy5fYWxsRGF0YVtvdXRnb2luZ0VkZ2VJbmRleF07XG4gICAgICAgICAgaWYgKHR5cGVvZiBkYXRhLnRlbnNvciAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignbm9kZSBvdXRwdXRzIHNob3VsZCBub3QgYmUgaW5pdGlhbGl6ZWQnKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGRhdGEuX2Zyb20gIT09IG5vZGVJbmRleCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdmcm9tIHByb3BlcnR5IG9mIHRoZSBWYWx1ZSBvYmplY3QgZG9lc25cXCd0IG1hdGNoIGluZGV4IG9mIE5vZGUgYmVpbmcgcHJvY2Vzc2VkJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGRhdGEuX3RvLmZvckVhY2goKGRvd25zdHJlYW1Ob2RlSW5kZXgpID0+IHtcbiAgICAgICAgICAgIC8vIGJhY2sgZWRnZSBmb3VuZCAtIGN5Y2xpY1xuICAgICAgICAgICAgaWYgKG5vZGVzU3RhdGVbZG93bnN0cmVhbU5vZGVJbmRleF0gPT09ICdncmF5Jykge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ21vZGVsIGdyYXBoIGlzIGN5Y2xpYycpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gdHJlZSBlZGdlIGZvdW5kIC0gY29udGludWUgcHJvY2Vzc2luZyBieSBhZGRpbmcgaXQgdG8gc3RhY2tcbiAgICAgICAgICAgIGVsc2UgaWYgKG5vZGVzU3RhdGVbZG93bnN0cmVhbU5vZGVJbmRleF0gPT09ICd3aGl0ZScpIHtcbiAgICAgICAgICAgICAgbm9kZXNTdGFjay5wdXNoKGRvd25zdHJlYW1Ob2RlSW5kZXgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHRyYW5zZm9ybUdyYXBoKGdyYXBoSW5pdGlhbGl6ZXI/OiBHcmFwaC5Jbml0aWFsaXplcik6IHZvaWQge1xuICAgIC8vIGFwcGx5IGNvbW1vbiB0cmFuc2Zvcm1cbiAgICB0aGlzLnJlbW92ZUFsbElkZW50aXR5Tm9kZXMoKTtcbiAgICB0aGlzLnJlbW92ZUFsbERyb3BvdXROb2RlcygpO1xuICAgIHRoaXMuZnVzZUNvbnZBY3RpdmF0aW9uTm9kZXMoKTtcbiAgICAvLyBhcHBseSBpbml0aWFsaXplciBzcGVjaWZpYyB0cmFuc2Zvcm1cbiAgICBpZiAoZ3JhcGhJbml0aWFsaXplcikge1xuICAgICAgZ3JhcGhJbml0aWFsaXplci50cmFuc2Zvcm1HcmFwaCh0aGlzKTtcbiAgICB9XG5cbiAgICAvLyBmaW5hbGl6ZSBncmFwaFxuICAgIHRoaXMuZmluYWxpemVHcmFwaCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIGZpbmFsaXplIHRoZSBncmFwaC5cbiAgICpcbiAgICogdGhpcyBmdW5jdGlvbiBzaG91bGQgYmUgY2FsbGVkIGFmdGVyIGFsbCB0aGUgdHJhbnNmb3JtYXRpb24gY29tcGxldGVkLlxuICAgKiB0aGlzIGZ1bmN0aW9uIHJlbW92ZXMgYWxsIHVubmVjZXNzYXJ5IG5vZGVzIGFuZCB2YWx1ZXMgZnJvbSB0aGUgZ3JhcGhcbiAgICovXG4gIGZpbmFsaXplR3JhcGgoKSB7XG4gICAgbGV0IG9mZnNldCA9IDA7XG4gICAgLy8gZGVsZXRlIGFsbCBub2RlcyB0aGF0IGFyZSBub3QgYmVpbmcgZXhlY3V0ZWRcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX25vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoIXRoaXMuX25vZGVzW2ldLmV4ZWN1dGVOb2RlKSB7XG4gICAgICAgIC8vIGRlbGV0ZSB0aGlzIG5vZGUgYW5kIHNoaWZ0IGFsbCBzdWJzZXF1ZW50IG5vZGVzIHVwXG4gICAgICAgIG9mZnNldCsrO1xuICAgICAgICAvLyBkZWxldGUgYWxsIG91dHB1dCB2YWx1ZXNcbiAgICAgICAgdGhpcy5fbm9kZXNbaV0ub3V0cHV0cy5mb3JFYWNoKGluZCA9PiB7XG4gICAgICAgICAgdGhpcy5fYWxsRGF0YVtpbmRdLl9mcm9tID0gLTI7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9ub2Rlcy5zcGxpY2UoaSwgMSk7XG4gICAgICAgIGktLTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAob2Zmc2V0ID4gMCkge1xuICAgICAgICAvLyB1cGRhdGUgdGhlIHZhbHVlIHRhYmxlXG4gICAgICAgIHRoaXMuX25vZGVzW2ldLmlucHV0cy5mb3JFYWNoKHZhbHVlID0+IHtcbiAgICAgICAgICBjb25zdCBpbmQgPSB0aGlzLl9hbGxEYXRhW3ZhbHVlXS5fdG8uaW5kZXhPZihpICsgb2Zmc2V0KTtcbiAgICAgICAgICBpZiAoaW5kICE9PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5fYWxsRGF0YVt2YWx1ZV0uX3RvW2luZF0gPSBpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX25vZGVzW2ldLm91dHB1dHMuZm9yRWFjaCh2YWx1ZSA9PiB7XG4gICAgICAgICAgaWYgKHRoaXMuX2FsbERhdGFbdmFsdWVdLl9mcm9tICYmIHRoaXMuX2FsbERhdGFbdmFsdWVdLl9mcm9tISA9PT0gaSArIG9mZnNldCkge1xuICAgICAgICAgICAgdGhpcy5fYWxsRGF0YVt2YWx1ZV0uX2Zyb20hID0gaTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgICBvZmZzZXQgPSAwO1xuICAgIC8vIGRlbGV0ZSBhbGwgdmFsdWVzIHRoYXQgYXJlIG5vdCBiZWluZyByZWZlcmVuY2VkXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9hbGxEYXRhLmxlbmd0aDsgaSsrKSB7XG4gICAgICAvLyBpZiBjdXJyZW50IHZhbHVlIGlzIG5laXRoZXIgbGlua2VkIHRvIG5leHQgbm9kZSwgbm9yIGFuIG91dHB1dCB2YWx1ZSwgcmVtb3ZlIGl0LlxuICAgICAgaWYgKHRoaXMuX2FsbERhdGFbaV0uZnJvbSA9PT0gLTIgJiYgdGhpcy5fYWxsT3V0cHV0SW5kaWNlcy5pbmRleE9mKGkgKyBvZmZzZXQpID09PSAtMSkge1xuICAgICAgICBvZmZzZXQrKztcbiAgICAgICAgdGhpcy5fYWxsRGF0YS5zcGxpY2UoaSwgMSk7XG4gICAgICAgIGktLTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAob2Zmc2V0ID4gMCkge1xuICAgICAgICBsZXQgaW5kID0gLTE7XG4gICAgICAgIC8vIGlmIGN1cnJlbnQgdmFsdWUgaXMgbmVpdGhlciBhbiBpbnB1dCB2YWx1ZSBub3IgYW4gaW5pdGlhbGl6ZXIsIGZpbmQgdGhlIG5vZGUgaXQnc1xuICAgICAgICAvLyBjb21pbmcgZnJvbSBhbmQgdXBkYXRlIHRoZSBjb3JyZXNwb25kaW5nIG5vZGUgb3V0cHV0XG4gICAgICAgIGlmICh0aGlzLl9hbGxEYXRhW2ldLmZyb20gIT09IHVuZGVmaW5lZCAmJiB0aGlzLl9hbGxEYXRhW2ldLmZyb20gIT09IC0xKSB7XG4gICAgICAgICAgaW5kID0gdGhpcy5fbm9kZXNbdGhpcy5fYWxsRGF0YVtpXS5mcm9tXS5vdXRwdXRzLmluZGV4T2YoaSArIG9mZnNldCk7XG4gICAgICAgICAgaWYgKGluZCAhPT0gLTEpIHtcbiAgICAgICAgICAgIHRoaXMuX25vZGVzW3RoaXMuX2FsbERhdGFbaV0uZnJvbV0ub3V0cHV0c1tpbmRdID0gaTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gaWYgY3VycmVudCB2YWx1ZSBpcyBhbiBpbnB1dCB2YWx1ZSwgdXBkYXRlIGl0cyByZWZlcmVuY2UgaW4gaW5wdXRJbmRpY2VzXG4gICAgICAgICAgaW5kID0gdGhpcy5fYWxsSW5wdXRJbmRpY2VzLmluZGV4T2YoaSArIG9mZnNldCk7XG4gICAgICAgICAgaWYgKGluZCAhPT0gLTEpIHtcbiAgICAgICAgICAgIHRoaXMuX2FsbElucHV0SW5kaWNlc1tpbmRdID0gaTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBmaW5kIHRoZSBub2RlIHRoYXQgdGhlIGN1cnJlbnQgdmFsdWUgaXMgbGlua2luZyB0byBhbmQgdXBkYXRlIGl0cyBpbnB1dCByZWZlcmVuY2VcbiAgICAgICAgdGhpcy5fYWxsRGF0YVtpXS50by5mb3JFYWNoKG5vZGUgPT4ge1xuICAgICAgICAgIGluZCA9IHRoaXMuX25vZGVzW25vZGVdLmlucHV0cy5pbmRleE9mKGkgKyBvZmZzZXQpO1xuICAgICAgICAgIGlmIChpbmQgIT09IC0xKSB7XG4gICAgICAgICAgICB0aGlzLl9ub2Rlc1tub2RlXS5pbnB1dHNbaW5kXSA9IGk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHRoaXMuX2FsbERhdGFbaV0udG8ubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgLy8gaWYgY3VycmVudCB2YWx1ZSBpcyBhIGdyYXBoIG91dHB1dCwgdXBkYXRlIGl0cyByZWZlcmVuY2UgaW4gb3V0cHV0SW5kaWNlc1xuICAgICAgICAgIGluZCA9IHRoaXMuX2FsbE91dHB1dEluZGljZXMuaW5kZXhPZihpICsgb2Zmc2V0KTtcbiAgICAgICAgICBpZiAoaW5kICE9PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5fYWxsT3V0cHV0SW5kaWNlc1tpbmRdID0gaTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRGVsZXRlIHRoZSBzcGVjaWZlZCBub2RlLiBBc3N1bWUgdGhlIG5vZGUgaGFzIG9uZSBpbmNvbWluZyBpbnB1dCBhbmQgdGhlIGZpcnN0IG91dHB1dCBjb25uZWN0ZWQgdG8gb3RoZXIgbm9kZXMuXG4gICAqIEFuIGlucHV0IHZhbGlkYXRpb24gbXVzdCBiZSBkb25lIGJlZm9yZSBjYWxsaW5nIHRoaXMgZnVuY3Rpb24uXG4gICAqIEBwYXJhbSBub2RlSW5kZXggVGhlIGluZGV4IG9mIG5vZGUgdG8gYmUgZGVsZXRlZFxuICAgKi9cbiAgcHJpdmF0ZSBkZWxldGVOb2RlKG5vZGVJbmRleDogbnVtYmVyKSB7XG4gICAgY29uc3Qgbm9kZSA9IHRoaXMuX25vZGVzW25vZGVJbmRleF07XG4gICAgaWYgKG5vZGUub3V0cHV0cy5sZW5ndGggPiAxKSB7XG4gICAgICBmb3IgKGxldCBpID0gMTsgaSA8IG5vZGUub3V0cHV0cy5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAodGhpcy5fYWxsRGF0YVtub2RlLm91dHB1dHNbaV1dLnRvLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vZGUgZGVsZXRpb24gd2l0aCBtb3JlIHRoYW4gb25lIG91dHB1dCBjb25uZWN0ZWQgdG8gb3RoZXIgbm9kZXMgaXMgbm90IHN1cHBvcnRlZC4gJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyB0aGlzIG5vZGUgd2lsIG5vdCBiZSBleGVjdXRlZFxuICAgIG5vZGUuZXhlY3V0ZU5vZGUgPSBmYWxzZTtcbiAgICBjb25zdCBpbnB1dFZhbHVlSW5kZXggPSBub2RlLmlucHV0c1swXTtcbiAgICBjb25zdCBvdXRwdXRWYWx1ZUluZGV4ID0gbm9kZS5vdXRwdXRzWzBdO1xuICAgIGNvbnN0IG5vZGVzQ29uc3VtaW5nT3V0cHV0ID0gdGhpcy5fYWxsRGF0YVtvdXRwdXRWYWx1ZUluZGV4XS50bztcblxuICAgIC8vIHJlbW92ZSB0aGlzIG5vZGUgZnJvbSB0aGUgdG8gcHJvcGVydHkgb2YgdGhlIGlucHV0IFZhbHVlXG4gICAgY29uc3QgZGVsSW5kZXggPSB0aGlzLl9hbGxEYXRhW2lucHV0VmFsdWVJbmRleF0udG8uaW5kZXhPZihub2RlSW5kZXgpO1xuICAgIC8vIHNob3VsZCBub3QgaGFwcGVuXG4gICAgaWYgKGRlbEluZGV4ID09PSAtMSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgVmFsdWUgb2JqZWN0IGRvZXNuXFwndCBoYXZlIHRoZSBjdXJyZW50IE5vZGUgaW4gaXRcXCdzIFxcJ3RvXFwnIHByb3BlcnR5ICcpO1xuICAgIH1cbiAgICB0aGlzLl9hbGxEYXRhW2lucHV0VmFsdWVJbmRleF0udG8uc3BsaWNlKGRlbEluZGV4LCAxKTtcblxuICAgIC8vIGNsZWFyIG5vZGUgaW5kaWNlcyBjb25zdW1pbmcgdGhpcyBvdXRwdXQgVmFsdWVcbiAgICB0aGlzLl9hbGxEYXRhW291dHB1dFZhbHVlSW5kZXhdLl90byA9IFtdO1xuXG4gICAgLy8gaWYgdGhlIG91dHB1dCBvZiB0aGlzIG5vZGUgaXMgYSBncmFwaCBvdXRwdXQsIGFkanVzdCB0aGUgaW5kZXggYXBwcm9wcmlhdGVseVxuICAgIGNvbnN0IGluZGV4ID0gdGhpcy5fYWxsT3V0cHV0SW5kaWNlcy5pbmRleE9mKG91dHB1dFZhbHVlSW5kZXgpO1xuICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgIHRoaXMuX2FsbE91dHB1dEluZGljZXNbaW5kZXhdID0gaW5wdXRWYWx1ZUluZGV4O1xuICAgIH1cblxuICAgIC8vIG92ZXJyaWRlIHRoZSBpbnB1dHMgZm9yIG5vZGVzIGNvbnN1bWluZyB0aGlzIG5vZGUncyBvdXRwdXQgd2l0aCB0aGUgaW5wdXQgdG8gdGhpcyBub2RlXG4gICAgaWYgKG5vZGVzQ29uc3VtaW5nT3V0cHV0ICYmIG5vZGVzQ29uc3VtaW5nT3V0cHV0Lmxlbmd0aCA+IDApIHtcbiAgICAgIGZvciAoY29uc3Qgbm9kZUluZGV4IG9mIG5vZGVzQ29uc3VtaW5nT3V0cHV0KSB7XG4gICAgICAgIGNvbnN0IHJlcGxhY2VJbmRleCA9IHRoaXMuX25vZGVzW25vZGVJbmRleF0uaW5wdXRzLmluZGV4T2Yob3V0cHV0VmFsdWVJbmRleCk7XG4gICAgICAgIC8vIHNob3VsZCBub3QgaGFwcGVuXG4gICAgICAgIGlmIChyZXBsYWNlSW5kZXggPT09IC0xKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgTm9kZSBvYmplY3QgZG9lc25cXCd0IGhhdmUgdGhlIG91dHB1dCBWYWx1ZSBpbiBpdFxcJ3MgXFwnaW5wdXRzXFwnIHByb3BlcnR5ICcpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX25vZGVzW25vZGVJbmRleF0uaW5wdXRzW3JlcGxhY2VJbmRleF0gPSBpbnB1dFZhbHVlSW5kZXg7XG4gICAgICAgIHRoaXMuX2FsbERhdGFbaW5wdXRWYWx1ZUluZGV4XS50by5wdXNoKG5vZGVJbmRleCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmVtb3ZlQWxsRHJvcG91dE5vZGVzKCkge1xuICAgIGxldCBub2RlSW5kZXggPSAwO1xuICAgIGZvciAoY29uc3Qgbm9kZSBvZiB0aGlzLl9ub2Rlcykge1xuICAgICAgLy8gd2VlZCBvdXQgJ0Ryb3BvdXQnIG5vZGVzIHNvIHRoYXQgbm8gdGltZSBpcyB3YXN0ZWQgaW4gZXhlY3V0aW9uXG4gICAgICBpZiAobm9kZS5vcFR5cGUgPT09ICdEcm9wb3V0Jykge1xuICAgICAgICAvLyB0aGUgbm9kZSBzaG91bGQgaGF2ZSBleGFjdGx5IDEgaW5wdXQgYW5kIDEgb3IgMiBvdXRwdXRzXG4gICAgICAgIGlmIChub2RlLmlucHV0cy5sZW5ndGggIT09IDEpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Ryb3BvdXQgbm9kZXMgc2hvdWxkIG9ubHkgY29udGFpbiBvbmUgaW5wdXQuICcpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChub2RlLm91dHB1dHMubGVuZ3RoICE9PSAxICYmIG5vZGUub3V0cHV0cy5sZW5ndGggIT09IDIpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Ryb3BvdXQgbm9kZXMgc2hvdWxkIGNvbnRhaW4gZWl0aGVyIDEgb3IgMiBvdXRwdXQocyknKTtcbiAgICAgICAgfVxuICAgICAgICAvLyB0aGUgc2Vjb25kIG91dHB1dCBzaG91bGQgbm90IGJlIHJlZmVyZW5jZWQgYnkgYW55IG90aGVyIG5vZGVcbiAgICAgICAgaWYgKG5vZGUub3V0cHV0cy5sZW5ndGggPT09IDIgJiYgdGhpcy5fYWxsRGF0YVtub2RlLm91dHB1dHNbMV1dLl90by5sZW5ndGggIT09IDApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Ryb3BvdXQgbm9kZXNcXCdzIHNlY29uZCBvdXRwdXQgc2hvdWxkIG5vdCBiZSByZWZlcmVuY2VkIGJ5IG90aGVyIG5vZGVzJyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5kZWxldGVOb2RlKG5vZGVJbmRleCk7XG4gICAgICB9XG4gICAgICBub2RlSW5kZXgrKztcbiAgICB9XG4gIH1cblxuICByZW1vdmVBbGxJZGVudGl0eU5vZGVzKCkge1xuICAgIGxldCBub2RlSW5kZXggPSAwO1xuICAgIGZvciAoY29uc3Qgbm9kZSBvZiB0aGlzLl9ub2Rlcykge1xuICAgICAgLy8gd2VlZCBvdXQgJ0lkZW50aXR5JyBub2RlcyBzbyB0aGF0IG5vIHRpbWUgaXMgd2FzdGVkIGluIGV4ZWN1dGlvblxuICAgICAgaWYgKG5vZGUub3BUeXBlID09PSAnSWRlbnRpdHknKSB7XG4gICAgICAgIHRoaXMuZGVsZXRlTm9kZShub2RlSW5kZXgpO1xuICAgICAgfVxuICAgICAgbm9kZUluZGV4Kys7XG4gICAgfVxuICB9XG5cbiAgaXNBY3RpdmF0aW9uKG46IE5vZGUpOiBib29sZWFuIHtcbiAgICBzd2l0Y2ggKG4ub3BUeXBlKSB7XG4gICAgICAvLyBUT0RPOiBhZGQgb3RoZXIgYWN0aXZhdGlvbiBtZXRob2RzXG4gICAgICBjYXNlICdSZWx1JzpcbiAgICAgIGNhc2UgJ1NpZ21vaWQnOlxuICAgICAgY2FzZSAnQ2xpcCc6XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIGZ1c2VDb252QWN0aXZhdGlvbk5vZGVzKCkge1xuICAgIGZvciAoY29uc3Qgbm9kZSBvZiB0aGlzLl9ub2Rlcykge1xuICAgICAgaWYgKG5vZGUub3BUeXBlID09PSAnQ29udicpIHtcbiAgICAgICAgY29uc3QgbmV4dCA9IHRoaXMuX2FsbERhdGFbbm9kZS5vdXRwdXRzWzBdXS5fdG87XG4gICAgICAgIGlmIChuZXh0Lmxlbmd0aCA9PT0gMSAmJiB0aGlzLmlzQWN0aXZhdGlvbih0aGlzLl9ub2Rlc1tuZXh0WzBdXSkpIHtcbiAgICAgICAgICBjb25zdCBjaGlsZCA9IHRoaXMuX25vZGVzW25leHRbMF1dO1xuICAgICAgICAgIGlmIChjaGlsZC5vcFR5cGUgPT09ICdDbGlwJykge1xuICAgICAgICAgICAgaWYgKGNoaWxkLmlucHV0cy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBub2RlLmF0dHJpYnV0ZXMuc2V0KFxuICAgICAgICAgICAgICAgICAgICAnYWN0aXZhdGlvbl9wYXJhbXMnLCAnZmxvYXRzJyxcbiAgICAgICAgICAgICAgICAgICAgW2NoaWxkLmF0dHJpYnV0ZXMuZ2V0RmxvYXQoJ21pbicpLCBjaGlsZC5hdHRyaWJ1dGVzLmdldEZsb2F0KCdtYXgnKV0pO1xuICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgbm9kZS5hdHRyaWJ1dGVzLnNldCgnYWN0aXZhdGlvbl9wYXJhbXMnLCAnZmxvYXRzJywgW01JTl9DTElQLCBNQVhfQ0xJUF0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgICAgICAgIGNoaWxkLmlucHV0cy5sZW5ndGggPj0gMyAmJiB0aGlzLl9hbGxEYXRhW2NoaWxkLmlucHV0c1sxXV0udGVuc29yICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgICAgICAgICB0aGlzLl9hbGxEYXRhW2NoaWxkLmlucHV0c1syXV0udGVuc29yICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgbm9kZS5hdHRyaWJ1dGVzLnNldCgnYWN0aXZhdGlvbl9wYXJhbXMnLCAnZmxvYXRzJywgW1xuICAgICAgICAgICAgICAgIHRoaXMuX2FsbERhdGFbY2hpbGQuaW5wdXRzWzFdXS50ZW5zb3IhLmZsb2F0RGF0YVswXSwgdGhpcy5fYWxsRGF0YVtjaGlsZC5pbnB1dHNbMl1dLnRlbnNvciEuZmxvYXREYXRhWzBdXG4gICAgICAgICAgICAgIF0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgLy8gU2tpcCBmdXNpb24gd2l0aCBjbGlwIG5vZGUgc2luY2UgY2xpcCBtaW4gYW5kIGNsaXAgbWF4IGFyZSBub3QgY29taW5nIGZyb20gaW5pdGlhbGl6ZXJcbiAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIG5vZGUuYXR0cmlidXRlcy5zZXQoJ2FjdGl2YXRpb24nLCAnc3RyaW5nJywgKGNoaWxkLm9wVHlwZSkpO1xuICAgICAgICAgIHRoaXMuZGVsZXRlTm9kZShuZXh0WzBdKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuIiwiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7RW52fSBmcm9tICdvbm54cnVudGltZS1jb21tb24nO1xuXG5pbXBvcnQge1dlYkdMQ29udGV4dH0gZnJvbSAnLi9iYWNrZW5kcy93ZWJnbC93ZWJnbC1jb250ZXh0JztcblxuZXhwb3J0IGRlY2xhcmUgbmFtZXNwYWNlIExvZ2dlciB7XG4gIGV4cG9ydCBpbnRlcmZhY2UgU2V2ZXJpdHlUeXBlTWFwIHtcbiAgICB2ZXJib3NlOiAndic7XG4gICAgaW5mbzogJ2knO1xuICAgIHdhcm5pbmc6ICd3JztcbiAgICBlcnJvcjogJ2UnO1xuICAgIGZhdGFsOiAnZic7XG4gIH1cblxuICBleHBvcnQgdHlwZSBTZXZlcml0eSA9IGtleW9mIFNldmVyaXR5VHlwZU1hcDtcblxuICBleHBvcnQgdHlwZSBQcm92aWRlciA9ICdub25lJ3wnY29uc29sZSc7XG5cbiAgLyoqXG4gICAqIExvZ2dpbmcgY29uZmlnIHRoYXQgdXNlZCB0byBjb250cm9sIHRoZSBiZWhhdmlvciBvZiBsb2dnZXJcbiAgICovXG4gIGV4cG9ydCBpbnRlcmZhY2UgQ29uZmlnIHtcbiAgICAvKipcbiAgICAgKiBTcGVjaWZ5IHRoZSBsb2dnaW5nIHByb3ZpZGVyLiAnY29uc29sZScgYnkgZGVmYXVsdFxuICAgICAqL1xuICAgIHByb3ZpZGVyPzogUHJvdmlkZXI7XG4gICAgLyoqXG4gICAgICogU3BlY2lmeSB0aGUgbWluaW1hbCBsb2dnZXIgc2VydmVyaXR5LiAnd2FybmluZycgYnkgZGVmYXVsdFxuICAgICAqL1xuICAgIG1pbmltYWxTZXZlcml0eT86IExvZ2dlci5TZXZlcml0eTtcbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRvIG91dHB1dCBkYXRlIHRpbWUgaW4gbG9nLiB0cnVlIGJ5IGRlZmF1bHRcbiAgICAgKi9cbiAgICBsb2dEYXRlVGltZT86IGJvb2xlYW47XG4gICAgLyoqXG4gICAgICogV2hldGhlciB0byBvdXRwdXQgc291cmNlIGluZm9ybWF0aW9uIChOb3QgeWV0IHN1cHBvcnRlZCkuIGZhbHNlIGJ5IGRlZmF1bHRcbiAgICAgKi9cbiAgICBsb2dTb3VyY2VMb2NhdGlvbj86IGJvb2xlYW47XG4gIH1cblxuICBleHBvcnQgaW50ZXJmYWNlIENhdGVnb3JpemVkTG9nZ2VyIHtcbiAgICB2ZXJib3NlKGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gICAgaW5mbyhjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICAgIHdhcm5pbmcoY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgICBlcnJvcihjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICAgIGZhdGFsKGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIH1cbn1cblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZWRlY2xhcmVcbmV4cG9ydCBpbnRlcmZhY2UgTG9nZ2VyIHtcbiAgKGNhdGVnb3J5OiBzdHJpbmcpOiBMb2dnZXIuQ2F0ZWdvcml6ZWRMb2dnZXI7XG5cbiAgdmVyYm9zZShjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICB2ZXJib3NlKGNhdGVnb3J5OiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGluZm8oY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgaW5mbyhjYXRlZ29yeTogc3RyaW5nLCBjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICB3YXJuaW5nKGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIHdhcm5pbmcoY2F0ZWdvcnk6IHN0cmluZywgY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgZXJyb3IoY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgZXJyb3IoY2F0ZWdvcnk6IHN0cmluZywgY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgZmF0YWwoY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgZmF0YWwoY2F0ZWdvcnk6IHN0cmluZywgY29udGVudDogc3RyaW5nKTogdm9pZDtcblxuICAvKipcbiAgICogUmVzZXQgdGhlIGxvZ2dlciBjb25maWd1cmF0aW9uLlxuICAgKiBAcGFyYW0gY29uZmlnIHNwZWNpZnkgYW4gb3B0aW9uYWwgZGVmYXVsdCBjb25maWdcbiAgICovXG4gIHJlc2V0KGNvbmZpZz86IExvZ2dlci5Db25maWcpOiB2b2lkO1xuICAvKipcbiAgICogU2V0IHRoZSBsb2dnZXIncyBiZWhhdmlvciBvbiB0aGUgZ2l2ZW4gY2F0ZWdvcnlcbiAgICogQHBhcmFtIGNhdGVnb3J5IHNwZWNpZnkgYSBjYXRlZ29yeSBzdHJpbmcuIElmICcqJyBpcyBzcGVjaWZpZWQsIGFsbCBwcmV2aW91cyBjb25maWd1cmF0aW9uIHdpbGwgYmUgb3ZlcndyaXR0ZW4uIElmXG4gICAqICcnIGlzIHNwZWNpZmllZCwgdGhlIGRlZmF1bHQgYmVoYXZpb3Igd2lsbCBiZSB1cGRhdGVkLlxuICAgKiBAcGFyYW0gY29uZmlnIHRoZSBjb25maWcgb2JqZWN0IHRvIGluZGljYXRlIHRoZSBsb2dnZXIncyBiZWhhdmlvclxuICAgKi9cbiAgc2V0KGNhdGVnb3J5OiBzdHJpbmcsIGNvbmZpZzogTG9nZ2VyLkNvbmZpZyk6IHZvaWQ7XG5cbiAgLyoqXG4gICAqIFNldCB0aGUgbG9nZ2VyJ3MgYmVoYXZpb3IgZnJvbSBvcnQtY29tbW9uIGVudlxuICAgKiBAcGFyYW0gZW52IHRoZSBlbnYgdXNlZCB0byBzZXQgbG9nZ2VyLiBDdXJyZW50bHkgb25seSBzZXR0aW5nIGxvZ2xldmVsIGlzIHN1cHBvcnRlZCB0aHJvdWdoIEVudi5cbiAgICovXG4gIHNldFdpdGhFbnYoZW52OiBFbnYpOiB2b2lkO1xufVxuXG5pbnRlcmZhY2UgTG9nZ2VyUHJvdmlkZXIge1xuICBsb2coc2V2ZXJpdHk6IExvZ2dlci5TZXZlcml0eSwgY29udGVudDogc3RyaW5nLCBjYXRlZ29yeT86IHN0cmluZyk6IHZvaWQ7XG59XG5jbGFzcyBOb09wTG9nZ2VyUHJvdmlkZXIgaW1wbGVtZW50cyBMb2dnZXJQcm92aWRlciB7XG4gIGxvZyhfc2V2ZXJpdHk6IExvZ2dlci5TZXZlcml0eSwgX2NvbnRlbnQ6IHN0cmluZywgX2NhdGVnb3J5Pzogc3RyaW5nKSB7XG4gICAgLy8gZG8gbm90aGluZ1xuICB9XG59XG5jbGFzcyBDb25zb2xlTG9nZ2VyUHJvdmlkZXIgaW1wbGVtZW50cyBMb2dnZXJQcm92aWRlciB7XG4gIGxvZyhzZXZlcml0eTogTG9nZ2VyLlNldmVyaXR5LCBjb250ZW50OiBzdHJpbmcsIGNhdGVnb3J5Pzogc3RyaW5nKSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICBjb25zb2xlLmxvZyhgJHt0aGlzLmNvbG9yKHNldmVyaXR5KX0gJHtjYXRlZ29yeSA/ICdcXHgxYlszNW0nICsgY2F0ZWdvcnkgKyAnXFx4MWJbMG0gJyA6ICcnfSR7Y29udGVudH1gKTtcbiAgfVxuXG4gIHByaXZhdGUgY29sb3Ioc2V2ZXJpdHk6IExvZ2dlci5TZXZlcml0eSkge1xuICAgIHN3aXRjaCAoc2V2ZXJpdHkpIHtcbiAgICAgIGNhc2UgJ3ZlcmJvc2UnOlxuICAgICAgICByZXR1cm4gJ1xceDFiWzM0OzQwbXZcXHgxYlswbSc7XG4gICAgICBjYXNlICdpbmZvJzpcbiAgICAgICAgcmV0dXJuICdcXHgxYlszMm1pXFx4MWJbMG0nO1xuICAgICAgY2FzZSAnd2FybmluZyc6XG4gICAgICAgIHJldHVybiAnXFx4MWJbMzA7NDNtd1xceDFiWzBtJztcbiAgICAgIGNhc2UgJ2Vycm9yJzpcbiAgICAgICAgcmV0dXJuICdcXHgxYlszMTs0MG1lXFx4MWJbMG0nO1xuICAgICAgY2FzZSAnZmF0YWwnOlxuICAgICAgICByZXR1cm4gJ1xceDFiWzEwMW1mXFx4MWJbMG0nO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bnN1cHBvcnRlZCBzZXZlcml0eTogJHtzZXZlcml0eX1gKTtcbiAgICB9XG4gIH1cbn1cblxuY29uc3QgU0VWRVJJVFlfVkFMVUUgPSB7XG4gIHZlcmJvc2U6IDEwMDAsXG4gIGluZm86IDIwMDAsXG4gIHdhcm5pbmc6IDQwMDAsXG4gIGVycm9yOiA1MDAwLFxuICBmYXRhbDogNjAwMFxufTtcblxuY29uc3QgTE9HR0VSX1BST1ZJREVSX01BUDoge3JlYWRvbmx5IFtwcm92aWRlcjogc3RyaW5nXTogUmVhZG9ubHk8TG9nZ2VyUHJvdmlkZXI+fSA9IHtcbiAgWydub25lJ106IG5ldyBOb09wTG9nZ2VyUHJvdmlkZXIoKSxcbiAgWydjb25zb2xlJ106IG5ldyBDb25zb2xlTG9nZ2VyUHJvdmlkZXIoKVxufTtcbmNvbnN0IExPR0dFUl9ERUZBVUxUX0NPTkZJRyA9IHtcbiAgcHJvdmlkZXI6ICdjb25zb2xlJyxcbiAgbWluaW1hbFNldmVyaXR5OiAnd2FybmluZycsXG4gIGxvZ0RhdGVUaW1lOiB0cnVlLFxuICBsb2dTb3VyY2VMb2NhdGlvbjogZmFsc2Vcbn07XG5sZXQgTE9HR0VSX0NPTkZJR19NQVA6XG4gICAge1tjYXRlZ29yeTogc3RyaW5nXTogUmVhZG9ubHk8UmVxdWlyZWQ8TG9nZ2VyLkNvbmZpZz4+fSA9IHtbJyddOiBMT0dHRVJfREVGQVVMVF9DT05GSUcgYXMgUmVxdWlyZWQ8TG9nZ2VyLkNvbmZpZz59O1xuXG5mdW5jdGlvbiBsb2coY2F0ZWdvcnk6IHN0cmluZyk6IExvZ2dlci5DYXRlZ29yaXplZExvZ2dlcjtcbmZ1bmN0aW9uIGxvZyhzZXZlcml0eTogTG9nZ2VyLlNldmVyaXR5LCBjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuZnVuY3Rpb24gbG9nKHNldmVyaXR5OiBMb2dnZXIuU2V2ZXJpdHksIGNhdGVnb3J5OiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG5mdW5jdGlvbiBsb2coc2V2ZXJpdHk6IExvZ2dlci5TZXZlcml0eSwgYXJnMTogc3RyaW5nLCBhcmcyPzogc3RyaW5nKTogdm9pZDtcbmZ1bmN0aW9uIGxvZyhcbiAgICBhcmcwOiBzdHJpbmd8TG9nZ2VyLlNldmVyaXR5LCBhcmcxPzogc3RyaW5nLCBhcmcyPzogc3RyaW5nfG51bWJlciwgYXJnMz86IG51bWJlcik6IExvZ2dlci5DYXRlZ29yaXplZExvZ2dlcnx2b2lkIHtcbiAgaWYgKGFyZzEgPT09IHVuZGVmaW5lZCkge1xuICAgIC8vIGxvZyhjYXRlZ29yeTogc3RyaW5nKTogTG9nZ2VyLkNhdGVnb3JpemVkTG9nZ2VyO1xuICAgIHJldHVybiBjcmVhdGVDYXRlZ29yaXplZExvZ2dlcihhcmcwKTtcbiAgfSBlbHNlIGlmIChhcmcyID09PSB1bmRlZmluZWQpIHtcbiAgICAvLyBsb2coc2V2ZXJpdHksIGNvbnRlbnQpO1xuICAgIGxvZ0ludGVybmFsKGFyZzAgYXMgTG9nZ2VyLlNldmVyaXR5LCBhcmcxLCAxKTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgYXJnMiA9PT0gJ251bWJlcicgJiYgYXJnMyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgLy8gbG9nKHNldmVyaXR5LCBjb250ZW50LCBzdGFjaylcbiAgICBsb2dJbnRlcm5hbChhcmcwIGFzIExvZ2dlci5TZXZlcml0eSwgYXJnMSwgYXJnMik7XG4gIH0gZWxzZSBpZiAodHlwZW9mIGFyZzIgPT09ICdzdHJpbmcnICYmIGFyZzMgPT09IHVuZGVmaW5lZCkge1xuICAgIC8vIGxvZyhzZXZlcml0eSwgY2F0ZWdvcnksIGNvbnRlbnQpXG4gICAgbG9nSW50ZXJuYWwoYXJnMCBhcyBMb2dnZXIuU2V2ZXJpdHksIGFyZzIsIDEsIGFyZzEpO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBhcmcyID09PSAnc3RyaW5nJyAmJiB0eXBlb2YgYXJnMyA9PT0gJ251bWJlcicpIHtcbiAgICAvLyBsb2coc2V2ZXJpdHksIGNhdGVnb3J5LCBjb250ZW50LCBzdGFjaylcbiAgICBsb2dJbnRlcm5hbChhcmcwIGFzIExvZ2dlci5TZXZlcml0eSwgYXJnMiwgYXJnMywgYXJnMSk7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignaW5wdXQgaXMgdmFsaWQnKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBjcmVhdGVDYXRlZ29yaXplZExvZ2dlcihjYXRlZ29yeTogc3RyaW5nKTogTG9nZ2VyLkNhdGVnb3JpemVkTG9nZ2VyIHtcbiAgcmV0dXJuIHtcbiAgICB2ZXJib3NlOiBsb2cudmVyYm9zZS5iaW5kKG51bGwsIGNhdGVnb3J5KSxcbiAgICBpbmZvOiBsb2cuaW5mby5iaW5kKG51bGwsIGNhdGVnb3J5KSxcbiAgICB3YXJuaW5nOiBsb2cud2FybmluZy5iaW5kKG51bGwsIGNhdGVnb3J5KSxcbiAgICBlcnJvcjogbG9nLmVycm9yLmJpbmQobnVsbCwgY2F0ZWdvcnkpLFxuICAgIGZhdGFsOiBsb2cuZmF0YWwuYmluZChudWxsLCBjYXRlZ29yeSlcbiAgfTtcbn1cblxuLy8gTk9URTogYXJndW1lbnQgJ2NhdGVnb3J5JyBpcyBwdXQgdGhlIGxhc3QgcGFyYW1ldGVyIGJlYWNhdXNlIHR5cGVzY3JpcHRcbi8vIGRvZXNuJ3QgYWxsb3cgb3B0aW9uYWwgYXJndW1lbnQgcHV0IGluIGZyb250IG9mIHJlcXVpcmVkIGFyZ3VtZW50LiBUaGlzXG4vLyBvcmRlciBpcyBkaWZmZXJlbnQgZnJvbSBhIHVzdWFsIGxvZ2dpbmcgQVBJLlxuZnVuY3Rpb24gbG9nSW50ZXJuYWwoc2V2ZXJpdHk6IExvZ2dlci5TZXZlcml0eSwgY29udGVudDogc3RyaW5nLCBzdGFjazogbnVtYmVyLCBjYXRlZ29yeT86IHN0cmluZykge1xuICBjb25zdCBjb25maWcgPSBMT0dHRVJfQ09ORklHX01BUFtjYXRlZ29yeSB8fCAnJ10gfHwgTE9HR0VSX0NPTkZJR19NQVBbJyddO1xuICBpZiAoU0VWRVJJVFlfVkFMVUVbc2V2ZXJpdHldIDwgU0VWRVJJVFlfVkFMVUVbY29uZmlnLm1pbmltYWxTZXZlcml0eV0pIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAoY29uZmlnLmxvZ0RhdGVUaW1lKSB7XG4gICAgY29udGVudCA9IGAke25ldyBEYXRlKCkudG9JU09TdHJpbmcoKX18JHtjb250ZW50fWA7XG4gIH1cblxuICBpZiAoY29uZmlnLmxvZ1NvdXJjZUxvY2F0aW9uKSB7XG4gICAgLy8gVE9ETzogY2FsY3VsYXRlIHNvdXJjZSBsb2NhdGlvbiBmcm9tICdzdGFjaydcbiAgfVxuXG4gIExPR0dFUl9QUk9WSURFUl9NQVBbY29uZmlnLnByb3ZpZGVyXS5sb2coc2V2ZXJpdHksIGNvbnRlbnQsIGNhdGVnb3J5KTtcbn1cblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1uYW1lc3BhY2Vcbm5hbWVzcGFjZSBsb2cge1xuICBleHBvcnQgZnVuY3Rpb24gdmVyYm9zZShjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICBleHBvcnQgZnVuY3Rpb24gdmVyYm9zZShjYXRlZ29yeTogc3RyaW5nLCBjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICBleHBvcnQgZnVuY3Rpb24gdmVyYm9zZShhcmcwOiBzdHJpbmcsIGFyZzE/OiBzdHJpbmcpIHtcbiAgICBsb2coJ3ZlcmJvc2UnLCBhcmcwLCBhcmcxKTtcbiAgfVxuICBleHBvcnQgZnVuY3Rpb24gaW5mbyhjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICBleHBvcnQgZnVuY3Rpb24gaW5mbyhjYXRlZ29yeTogc3RyaW5nLCBjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICBleHBvcnQgZnVuY3Rpb24gaW5mbyhhcmcwOiBzdHJpbmcsIGFyZzE/OiBzdHJpbmcpIHtcbiAgICBsb2coJ2luZm8nLCBhcmcwLCBhcmcxKTtcbiAgfVxuICBleHBvcnQgZnVuY3Rpb24gd2FybmluZyhjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICBleHBvcnQgZnVuY3Rpb24gd2FybmluZyhjYXRlZ29yeTogc3RyaW5nLCBjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICBleHBvcnQgZnVuY3Rpb24gd2FybmluZyhhcmcwOiBzdHJpbmcsIGFyZzE/OiBzdHJpbmcpIHtcbiAgICBsb2coJ3dhcm5pbmcnLCBhcmcwLCBhcmcxKTtcbiAgfVxuICBleHBvcnQgZnVuY3Rpb24gZXJyb3IoY29udGVudDogc3RyaW5nKTogdm9pZDtcbiAgZXhwb3J0IGZ1bmN0aW9uIGVycm9yKGNhdGVnb3J5OiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGV4cG9ydCBmdW5jdGlvbiBlcnJvcihhcmcwOiBzdHJpbmcsIGFyZzE/OiBzdHJpbmcpIHtcbiAgICBsb2coJ2Vycm9yJywgYXJnMCwgYXJnMSk7XG4gIH1cbiAgZXhwb3J0IGZ1bmN0aW9uIGZhdGFsKGNvbnRlbnQ6IHN0cmluZyk6IHZvaWQ7XG4gIGV4cG9ydCBmdW5jdGlvbiBmYXRhbChjYXRlZ29yeTogc3RyaW5nLCBjb250ZW50OiBzdHJpbmcpOiB2b2lkO1xuICBleHBvcnQgZnVuY3Rpb24gZmF0YWwoYXJnMDogc3RyaW5nLCBhcmcxPzogc3RyaW5nKSB7XG4gICAgbG9nKCdmYXRhbCcsIGFyZzAsIGFyZzEpO1xuICB9XG5cbiAgZXhwb3J0IGZ1bmN0aW9uIHJlc2V0KGNvbmZpZz86IExvZ2dlci5Db25maWcpOiB2b2lkIHtcbiAgICBMT0dHRVJfQ09ORklHX01BUCA9IHt9O1xuICAgIHNldCgnJywgY29uZmlnIHx8IHt9KTtcbiAgfVxuICBleHBvcnQgZnVuY3Rpb24gc2V0KGNhdGVnb3J5OiBzdHJpbmcsIGNvbmZpZzogTG9nZ2VyLkNvbmZpZyk6IHZvaWQge1xuICAgIGlmIChjYXRlZ29yeSA9PT0gJyonKSB7XG4gICAgICByZXNldChjb25maWcpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBwcmV2aW91c0NvbmZpZyA9IExPR0dFUl9DT05GSUdfTUFQW2NhdGVnb3J5XSB8fCBMT0dHRVJfREVGQVVMVF9DT05GSUc7XG4gICAgICBMT0dHRVJfQ09ORklHX01BUFtjYXRlZ29yeV0gPSB7XG4gICAgICAgIHByb3ZpZGVyOiBjb25maWcucHJvdmlkZXIgfHwgcHJldmlvdXNDb25maWcucHJvdmlkZXIsXG4gICAgICAgIG1pbmltYWxTZXZlcml0eTogY29uZmlnLm1pbmltYWxTZXZlcml0eSB8fCBwcmV2aW91c0NvbmZpZy5taW5pbWFsU2V2ZXJpdHksXG4gICAgICAgIGxvZ0RhdGVUaW1lOiAoY29uZmlnLmxvZ0RhdGVUaW1lID09PSB1bmRlZmluZWQpID8gcHJldmlvdXNDb25maWcubG9nRGF0ZVRpbWUgOiBjb25maWcubG9nRGF0ZVRpbWUsXG4gICAgICAgIGxvZ1NvdXJjZUxvY2F0aW9uOiAoY29uZmlnLmxvZ1NvdXJjZUxvY2F0aW9uID09PSB1bmRlZmluZWQpID8gcHJldmlvdXNDb25maWcubG9nU291cmNlTG9jYXRpb24gOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZy5sb2dTb3VyY2VMb2NhdGlvblxuICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyBUT0RPOiB3ZSB3YW50IHRvIHN1cHBvcnQgd2lsZGNhcmQgb3IgcmVnZXg/XG4gIH1cblxuICBleHBvcnQgZnVuY3Rpb24gc2V0V2l0aEVudihlbnY6IEVudik6IHZvaWQge1xuICAgIGNvbnN0IGNvbmZpZzogTG9nZ2VyLkNvbmZpZyA9IHt9O1xuICAgIGlmIChlbnYubG9nTGV2ZWwpIHtcbiAgICAgIGNvbmZpZy5taW5pbWFsU2V2ZXJpdHkgPSBlbnYubG9nTGV2ZWwgYXMgTG9nZ2VyLlNldmVyaXR5O1xuICAgIH1cbiAgICBzZXQoJycsIGNvbmZpZyk7XG4gIH1cbn1cblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZWRlY2xhcmUsIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxuZXhwb3J0IGNvbnN0IExvZ2dlcjogTG9nZ2VyID0gbG9nO1xuXG5leHBvcnQgZGVjbGFyZSBuYW1lc3BhY2UgUHJvZmlsZXIge1xuICBleHBvcnQgaW50ZXJmYWNlIENvbmZpZyB7XG4gICAgbWF4TnVtYmVyRXZlbnRzPzogbnVtYmVyO1xuICAgIGZsdXNoQmF0Y2hTaXplPzogbnVtYmVyO1xuICAgIGZsdXNoSW50ZXJ2YWxJbk1pbGxpc2Vjb25kcz86IG51bWJlcjtcbiAgfVxuXG4gIGV4cG9ydCB0eXBlIEV2ZW50Q2F0ZWdvcnkgPSAnc2Vzc2lvbid8J25vZGUnfCdvcCd8J2JhY2tlbmQnO1xuXG4gIGV4cG9ydCBpbnRlcmZhY2UgRXZlbnQge1xuICAgIGVuZCgpOiB2b2lkfFByb21pc2U8dm9pZD47XG4gIH1cbn1cbi8vIFRPRE9cbi8vIGNsYXNzIFdlYkdMRXZlbnQgaW1wbGVtZW50cyBQcm9maWxlci5FdmVudCB7fVxuXG5jbGFzcyBFdmVudCBpbXBsZW1lbnRzIFByb2ZpbGVyLkV2ZW50IHtcbiAgY29uc3RydWN0b3IoXG4gICAgICBwdWJsaWMgY2F0ZWdvcnk6IFByb2ZpbGVyLkV2ZW50Q2F0ZWdvcnksIHB1YmxpYyBuYW1lOiBzdHJpbmcsIHB1YmxpYyBzdGFydFRpbWU6IG51bWJlcixcbiAgICAgIHByaXZhdGUgZW5kQ2FsbGJhY2s6IChlOiBFdmVudCkgPT4gdm9pZHxQcm9taXNlPHZvaWQ+LCBwdWJsaWMgdGltZXI/OiBXZWJHTFF1ZXJ5LCBwdWJsaWMgY3R4PzogV2ViR0xDb250ZXh0KSB7fVxuXG4gIGVuZCgpIHtcbiAgICByZXR1cm4gdGhpcy5lbmRDYWxsYmFjayh0aGlzKTtcbiAgfVxuXG4gIGFzeW5jIGNoZWNrVGltZXIoKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICBpZiAodGhpcy5jdHggPT09IHVuZGVmaW5lZCB8fCB0aGlzLnRpbWVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTm8gd2ViZ2wgdGltZXIgZm91bmQnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5jdHguZW5kVGltZXIoKTtcbiAgICAgIHJldHVybiB0aGlzLmN0eC53YWl0Rm9yUXVlcnlBbmRHZXRUaW1lKHRoaXMudGltZXIpO1xuICAgIH1cbiAgfVxufVxuXG5jbGFzcyBFdmVudFJlY29yZCB7XG4gIGNvbnN0cnVjdG9yKFxuICAgICAgcHVibGljIGNhdGVnb3J5OiBQcm9maWxlci5FdmVudENhdGVnb3J5LCBwdWJsaWMgbmFtZTogc3RyaW5nLCBwdWJsaWMgc3RhcnRUaW1lOiBudW1iZXIsIHB1YmxpYyBlbmRUaW1lOiBudW1iZXIpIHt9XG59XG5cbmV4cG9ydCBjbGFzcyBQcm9maWxlciB7XG4gIHN0YXRpYyBjcmVhdGUoY29uZmlnPzogUHJvZmlsZXIuQ29uZmlnKTogUHJvZmlsZXIge1xuICAgIGlmIChjb25maWcgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIG5ldyB0aGlzKCk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgdGhpcyhjb25maWcubWF4TnVtYmVyRXZlbnRzLCBjb25maWcuZmx1c2hCYXRjaFNpemUsIGNvbmZpZy5mbHVzaEludGVydmFsSW5NaWxsaXNlY29uZHMpO1xuICB9XG5cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcihtYXhOdW1iZXJFdmVudHM/OiBudW1iZXIsIGZsdXNoQmF0Y2hTaXplPzogbnVtYmVyLCBmbHVzaEludGVydmFsSW5NaWxsaXNlY29uZHM/OiBudW1iZXIpIHtcbiAgICB0aGlzLl9zdGFydGVkID0gZmFsc2U7XG4gICAgdGhpcy5fbWF4TnVtYmVyRXZlbnRzID0gbWF4TnVtYmVyRXZlbnRzID09PSB1bmRlZmluZWQgPyAxMDAwMCA6IG1heE51bWJlckV2ZW50cztcbiAgICB0aGlzLl9mbHVzaEJhdGNoU2l6ZSA9IGZsdXNoQmF0Y2hTaXplID09PSB1bmRlZmluZWQgPyAxMCA6IGZsdXNoQmF0Y2hTaXplO1xuICAgIHRoaXMuX2ZsdXNoSW50ZXJ2YWxJbk1pbGxpc2Vjb25kcyA9IGZsdXNoSW50ZXJ2YWxJbk1pbGxpc2Vjb25kcyA9PT0gdW5kZWZpbmVkID8gNTAwMCA6IGZsdXNoSW50ZXJ2YWxJbk1pbGxpc2Vjb25kcztcbiAgfVxuXG4gIC8vIHN0YXJ0IHByb2ZpbGluZ1xuICBzdGFydCgpIHtcbiAgICB0aGlzLl9zdGFydGVkID0gdHJ1ZTtcbiAgICB0aGlzLl90aW1pbmdFdmVudHMgPSBbXTtcbiAgICB0aGlzLl9mbHVzaFRpbWUgPSBub3coKTtcbiAgICB0aGlzLl9mbHVzaFBvaW50ZXIgPSAwO1xuICB9XG5cbiAgLy8gc3RvcCBwcm9maWxpbmdcbiAgc3RvcCgpIHtcbiAgICB0aGlzLl9zdGFydGVkID0gZmFsc2U7XG4gICAgZm9yICg7IHRoaXMuX2ZsdXNoUG9pbnRlciA8IHRoaXMuX3RpbWluZ0V2ZW50cy5sZW5ndGg7IHRoaXMuX2ZsdXNoUG9pbnRlcisrKSB7XG4gICAgICB0aGlzLmxvZ09uZUV2ZW50KHRoaXMuX3RpbWluZ0V2ZW50c1t0aGlzLl9mbHVzaFBvaW50ZXJdKTtcbiAgICB9XG4gIH1cblxuICAvLyBjcmVhdGUgYW4gZXZlbnQgc2NvcGUgZm9yIHRoZSBzcGVjaWZpYyBmdW5jdGlvblxuICBldmVudDxUPihjYXRlZ29yeTogUHJvZmlsZXIuRXZlbnRDYXRlZ29yeSwgbmFtZTogc3RyaW5nLCBmdW5jOiAoKSA9PiBULCBjdHg/OiBXZWJHTENvbnRleHQpOiBUO1xuICBldmVudDxUPihjYXRlZ29yeTogUHJvZmlsZXIuRXZlbnRDYXRlZ29yeSwgbmFtZTogc3RyaW5nLCBmdW5jOiAoKSA9PiBQcm9taXNlPFQ+LCBjdHg/OiBXZWJHTENvbnRleHQpOiBQcm9taXNlPFQ+O1xuXG4gIGV2ZW50PFQ+KGNhdGVnb3J5OiBQcm9maWxlci5FdmVudENhdGVnb3J5LCBuYW1lOiBzdHJpbmcsIGZ1bmM6ICgpID0+IFQgfCBQcm9taXNlPFQ+LCBjdHg/OiBXZWJHTENvbnRleHQpOiBUXG4gICAgICB8UHJvbWlzZTxUPiB7XG4gICAgY29uc3QgZXZlbnQgPSB0aGlzLl9zdGFydGVkID8gdGhpcy5iZWdpbihjYXRlZ29yeSwgbmFtZSwgY3R4KSA6IHVuZGVmaW5lZDtcbiAgICBsZXQgaXNQcm9taXNlID0gZmFsc2U7XG5cbiAgICBjb25zdCByZXMgPSBmdW5jKCk7XG5cbiAgICAvLyB3ZSBjb25zaWRlciBhIHRoZW4tYWJsZSBvYmplY3QgaXMgYSBwcm9taXNlXG4gICAgaWYgKHJlcyAmJiB0eXBlb2YgKHJlcyBhcyBQcm9taXNlPFQ+KS50aGVuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBpc1Byb21pc2UgPSB0cnVlO1xuICAgICAgcmV0dXJuIG5ldyBQcm9taXNlPFQ+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgKHJlcyBhcyBQcm9taXNlPFQ+KVxuICAgICAgICAgICAgLnRoZW4oXG4gICAgICAgICAgICAgICAgYXN5bmMgdmFsdWUgPT4geyAgLy8gZnVsZmlsbGVkXG4gICAgICAgICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgZXZlbnQuZW5kKCk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICByZXNvbHZlKHZhbHVlKTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGFzeW5jIHJlYXNvbiA9PiB7ICAvLyByZWplY3RlZFxuICAgICAgICAgICAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IGV2ZW50LmVuZCgpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgcmVqZWN0KHJlYXNvbik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgaWYgKCFpc1Byb21pc2UgJiYgZXZlbnQpIHtcbiAgICAgIGNvbnN0IGV2ZW50UmVzID0gZXZlbnQuZW5kKCk7XG4gICAgICBpZiAoZXZlbnRSZXMgJiYgdHlwZW9mIGV2ZW50UmVzLnRoZW4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlPFQ+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAoZXZlbnRSZXMpLnRoZW4oXG4gICAgICAgICAgICAgICgpID0+IHsgIC8vIGZ1bGZpbGxlZFxuICAgICAgICAgICAgICAgIHJlc29sdmUocmVzKTtcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgKHJlYXNvbikgPT4geyAgLy8gcmVqZWN0ZWRcbiAgICAgICAgICAgICAgICByZWplY3QocmVhc29uKTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzO1xuICB9XG5cbiAgLy8gYmVnaW4gYW4gZXZlbnRcbiAgYmVnaW4oY2F0ZWdvcnk6IFByb2ZpbGVyLkV2ZW50Q2F0ZWdvcnksIG5hbWU6IHN0cmluZywgY3R4PzogV2ViR0xDb250ZXh0KTogRXZlbnQge1xuICAgIGlmICghdGhpcy5fc3RhcnRlZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdwcm9maWxlciBpcyBub3Qgc3RhcnRlZCB5ZXQnKTtcbiAgICB9XG4gICAgaWYgKGN0eCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb25zdCBzdGFydFRpbWUgPSBub3coKTtcbiAgICAgIHRoaXMuZmx1c2goc3RhcnRUaW1lKTtcbiAgICAgIHJldHVybiBuZXcgRXZlbnQoY2F0ZWdvcnksIG5hbWUsIHN0YXJ0VGltZSwgZSA9PiB0aGlzLmVuZFN5bmMoZSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCB0aW1lcjogV2ViR0xRdWVyeSA9IGN0eC5iZWdpblRpbWVyKCk7XG4gICAgICByZXR1cm4gbmV3IEV2ZW50KGNhdGVnb3J5LCBuYW1lLCAwLCBhc3luYyBlID0+IHRoaXMuZW5kKGUpLCB0aW1lciwgY3R4KTtcbiAgICB9XG4gIH1cblxuICAvLyBlbmQgdGhlIHNwZWNpZmljIGV2ZW50XG4gIHByaXZhdGUgYXN5bmMgZW5kKGV2ZW50OiBFdmVudCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGVuZFRpbWU6IG51bWJlciA9IGF3YWl0IGV2ZW50LmNoZWNrVGltZXIoKTtcbiAgICBpZiAodGhpcy5fdGltaW5nRXZlbnRzLmxlbmd0aCA8IHRoaXMuX21heE51bWJlckV2ZW50cykge1xuICAgICAgdGhpcy5fdGltaW5nRXZlbnRzLnB1c2gobmV3IEV2ZW50UmVjb3JkKGV2ZW50LmNhdGVnb3J5LCBldmVudC5uYW1lLCBldmVudC5zdGFydFRpbWUsIGVuZFRpbWUpKTtcbiAgICAgIHRoaXMuZmx1c2goZW5kVGltZSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBlbmRTeW5jKGV2ZW50OiBFdmVudCk6IHZvaWQge1xuICAgIGNvbnN0IGVuZFRpbWU6IG51bWJlciA9IG5vdygpO1xuICAgIGlmICh0aGlzLl90aW1pbmdFdmVudHMubGVuZ3RoIDwgdGhpcy5fbWF4TnVtYmVyRXZlbnRzKSB7XG4gICAgICB0aGlzLl90aW1pbmdFdmVudHMucHVzaChuZXcgRXZlbnRSZWNvcmQoZXZlbnQuY2F0ZWdvcnksIGV2ZW50Lm5hbWUsIGV2ZW50LnN0YXJ0VGltZSwgZW5kVGltZSkpO1xuICAgICAgdGhpcy5mbHVzaChlbmRUaW1lKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGxvZ09uZUV2ZW50KGV2ZW50OiBFdmVudFJlY29yZCkge1xuICAgIExvZ2dlci52ZXJib3NlKFxuICAgICAgICBgUHJvZmlsZXIuJHtldmVudC5jYXRlZ29yeX1gLFxuICAgICAgICBgJHsoZXZlbnQuZW5kVGltZSAtIGV2ZW50LnN0YXJ0VGltZSkudG9GaXhlZCgyKX1tcyBvbiBldmVudCAnJHtldmVudC5uYW1lfScgYXQgJHtldmVudC5lbmRUaW1lLnRvRml4ZWQoMil9YCk7XG4gIH1cblxuICBwcml2YXRlIGZsdXNoKGN1cnJlbnRUaW1lOiBudW1iZXIpIHtcbiAgICBpZiAodGhpcy5fdGltaW5nRXZlbnRzLmxlbmd0aCAtIHRoaXMuX2ZsdXNoUG9pbnRlciA+PSB0aGlzLl9mbHVzaEJhdGNoU2l6ZSB8fFxuICAgICAgICBjdXJyZW50VGltZSAtIHRoaXMuX2ZsdXNoVGltZSA+PSB0aGlzLl9mbHVzaEludGVydmFsSW5NaWxsaXNlY29uZHMpIHtcbiAgICAgIC8vIHNob3VsZCBmbHVzaCB3aGVuIGVpdGhlciBiYXRjaCBzaXplIGFjY3VtbGF0ZWQgb3IgaW50ZXJ2YWwgZWxlcHNlZFxuXG4gICAgICBmb3IgKGNvbnN0IHByZXZpb3VzUG9pbnRlciA9IHRoaXMuX2ZsdXNoUG9pbnRlcjsgdGhpcy5fZmx1c2hQb2ludGVyIDwgcHJldmlvdXNQb2ludGVyICsgdGhpcy5fZmx1c2hCYXRjaFNpemUgJiZcbiAgICAgICAgICAgdGhpcy5fZmx1c2hQb2ludGVyIDwgdGhpcy5fdGltaW5nRXZlbnRzLmxlbmd0aDtcbiAgICAgICAgICAgdGhpcy5fZmx1c2hQb2ludGVyKyspIHtcbiAgICAgICAgdGhpcy5sb2dPbmVFdmVudCh0aGlzLl90aW1pbmdFdmVudHNbdGhpcy5fZmx1c2hQb2ludGVyXSk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuX2ZsdXNoVGltZSA9IG5vdygpO1xuICAgIH1cbiAgfVxuXG4gIGdldCBzdGFydGVkKCkge1xuICAgIHJldHVybiB0aGlzLl9zdGFydGVkO1xuICB9XG4gIHByaXZhdGUgX3N0YXJ0ZWQgPSBmYWxzZTtcbiAgcHJpdmF0ZSBfdGltaW5nRXZlbnRzOiBFdmVudFJlY29yZFtdO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgX21heE51bWJlckV2ZW50czogbnVtYmVyO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgX2ZsdXNoQmF0Y2hTaXplOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2ZsdXNoSW50ZXJ2YWxJbk1pbGxpc2Vjb25kczogbnVtYmVyO1xuXG4gIHByaXZhdGUgX2ZsdXNoVGltZTogbnVtYmVyO1xuICBwcml2YXRlIF9mbHVzaFBvaW50ZXIgPSAwO1xufVxuXG4vKipcbiAqIHJldHVybnMgYSBudW1iZXIgdG8gcmVwcmVzZW50IHRoZSBjdXJyZW50IHRpbWVzdGFtcCBpbiBhIHJlc29sdXRpb24gYXMgaGlnaCBhcyBwb3NzaWJsZS5cbiAqL1xuZXhwb3J0IGNvbnN0IG5vdyA9ICh0eXBlb2YgcGVyZm9ybWFuY2UgIT09ICd1bmRlZmluZWQnICYmIHBlcmZvcm1hbmNlLm5vdykgPyAoKSA9PiBwZXJmb3JtYW5jZS5ub3coKSA6IERhdGUubm93O1xuIiwiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7ZmxhdGJ1ZmZlcnN9IGZyb20gJ2ZsYXRidWZmZXJzJztcbmltcG9ydCB7b25ueH0gZnJvbSAnb25ueC1wcm90byc7XG5cbmltcG9ydCB7R3JhcGh9IGZyb20gJy4vZ3JhcGgnO1xuaW1wb3J0IHtPcFNldH0gZnJvbSAnLi9vcHNldCc7XG5pbXBvcnQge29ubnhydW50aW1lfSBmcm9tICcuL29ydC1zY2hlbWEvb3J0LWdlbmVyYXRlZCc7XG5pbXBvcnQge0xvbmdVdGlsfSBmcm9tICcuL3V0aWwnO1xuXG5pbXBvcnQgb3J0RmJzID0gb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicztcblxuZXhwb3J0IGNsYXNzIE1vZGVsIHtcbiAgLy8gZW1wdHkgbW9kZWxcbiAgY29uc3RydWN0b3IoKSB7fVxuXG4gIGxvYWQoYnVmOiBVaW50OEFycmF5LCBncmFwaEluaXRpYWxpemVyPzogR3JhcGguSW5pdGlhbGl6ZXIsIGlzT3J0Rm9ybWF0PzogYm9vbGVhbik6IHZvaWQge1xuICAgIGlmICghaXNPcnRGb3JtYXQpIHtcbiAgICAgIC8vIGlzT3J0Rm9ybWF0ID09PSBmYWxzZSB8fCBpc09ydEZvcm1hdCA9PT0gdW5kZWZpbmVkXG4gICAgICB0cnkge1xuICAgICAgICB0aGlzLmxvYWRGcm9tT25ueEZvcm1hdChidWYsIGdyYXBoSW5pdGlhbGl6ZXIpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGlmIChpc09ydEZvcm1hdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMubG9hZEZyb21PcnRGb3JtYXQoYnVmLCBncmFwaEluaXRpYWxpemVyKTtcbiAgfVxuXG4gIHByaXZhdGUgbG9hZEZyb21Pbm54Rm9ybWF0KGJ1ZjogVWludDhBcnJheSwgZ3JhcGhJbml0aWFsaXplcj86IEdyYXBoLkluaXRpYWxpemVyKTogdm9pZCB7XG4gICAgY29uc3QgbW9kZWxQcm90byA9IG9ubnguTW9kZWxQcm90by5kZWNvZGUoYnVmKTtcbiAgICBjb25zdCBpclZlcnNpb24gPSBMb25nVXRpbC5sb25nVG9OdW1iZXIobW9kZWxQcm90by5pclZlcnNpb24pO1xuICAgIGlmIChpclZlcnNpb24gPCAzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ29ubHkgc3VwcG9ydCBPTk5YIG1vZGVsIHdpdGggSVJfVkVSU0lPTj49MycpO1xuICAgIH1cblxuICAgIHRoaXMuX29wc2V0cyA9XG4gICAgICAgIG1vZGVsUHJvdG8ub3BzZXRJbXBvcnQubWFwKGkgPT4gKHtkb21haW46IGkuZG9tYWluIGFzIHN0cmluZywgdmVyc2lvbjogTG9uZ1V0aWwubG9uZ1RvTnVtYmVyKGkudmVyc2lvbiEpfSkpO1xuXG4gICAgdGhpcy5fZ3JhcGggPSBHcmFwaC5mcm9tKG1vZGVsUHJvdG8uZ3JhcGghLCBncmFwaEluaXRpYWxpemVyKTtcbiAgfVxuXG4gIHByaXZhdGUgbG9hZEZyb21PcnRGb3JtYXQoYnVmOiBVaW50OEFycmF5LCBncmFwaEluaXRpYWxpemVyPzogR3JhcGguSW5pdGlhbGl6ZXIpOiB2b2lkIHtcbiAgICBjb25zdCBmYiA9IG5ldyBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKGJ1Zik7XG4gICAgY29uc3Qgb3J0TW9kZWwgPSBvcnRGYnMuSW5mZXJlbmNlU2Vzc2lvbi5nZXRSb290QXNJbmZlcmVuY2VTZXNzaW9uKGZiKS5tb2RlbCgpITtcbiAgICBjb25zdCBpclZlcnNpb24gPSBMb25nVXRpbC5sb25nVG9OdW1iZXIob3J0TW9kZWwuaXJWZXJzaW9uKCkpO1xuICAgIGlmIChpclZlcnNpb24gPCAzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ29ubHkgc3VwcG9ydCBPTk5YIG1vZGVsIHdpdGggSVJfVkVSU0lPTj49MycpO1xuICAgIH1cbiAgICB0aGlzLl9vcHNldHMgPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG9ydE1vZGVsLm9wc2V0SW1wb3J0TGVuZ3RoKCk7IGkrKykge1xuICAgICAgY29uc3Qgb3BzZXRJZCA9IG9ydE1vZGVsLm9wc2V0SW1wb3J0KGkpITtcbiAgICAgIHRoaXMuX29wc2V0cy5wdXNoKHtkb21haW46IG9wc2V0SWQ/LmRvbWFpbigpIGFzIHN0cmluZywgdmVyc2lvbjogTG9uZ1V0aWwubG9uZ1RvTnVtYmVyKG9wc2V0SWQudmVyc2lvbigpISl9KTtcbiAgICB9XG5cbiAgICB0aGlzLl9ncmFwaCA9IEdyYXBoLmZyb20ob3J0TW9kZWwuZ3JhcGgoKSEsIGdyYXBoSW5pdGlhbGl6ZXIpO1xuICB9XG5cbiAgcHJpdmF0ZSBfZ3JhcGg6IEdyYXBoO1xuICBnZXQgZ3JhcGgoKTogR3JhcGgge1xuICAgIHJldHVybiB0aGlzLl9ncmFwaDtcbiAgfVxuXG4gIHByaXZhdGUgX29wc2V0czogT3BTZXRbXTtcbiAgZ2V0IG9wc2V0cygpOiByZWFkb25seSBPcFNldFtdIHtcbiAgICByZXR1cm4gdGhpcy5fb3BzZXRzO1xuICB9XG59XG4iLCIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtJbmZlcmVuY2VIYW5kbGVyfSBmcm9tICcuL2JhY2tlbmQnO1xuaW1wb3J0IHtHcmFwaH0gZnJvbSAnLi9ncmFwaCc7XG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi90ZW5zb3InO1xuXG5leHBvcnQgdHlwZSBPcGVyYXRvckltcGxlbWVudGF0aW9uPFQ+ID0gKGluZmVyZW5jZUhhbmRsZXI6IEluZmVyZW5jZUhhbmRsZXIsIGlucHV0czogVGVuc29yW10sIGNvbnRleHQ6IFQpID0+IFRlbnNvcltdO1xuZXhwb3J0IHR5cGUgT3BlcmF0b3JJbml0aWFsaXphdGlvbjxUPiA9IChub2RlOiBHcmFwaC5Ob2RlLCBncmFwaDogR3JhcGgpID0+IFQ7XG5cbmV4cG9ydCBpbnRlcmZhY2UgT3BlcmF0b3Ige1xuICByZWFkb25seSBpbXBsOiBPcGVyYXRvckltcGxlbWVudGF0aW9uPHVua25vd24+O1xuICByZWFkb25seSBjb250ZXh0OiBHcmFwaC5Ob2RlfHVua25vd247XG59XG5cbmV4cG9ydCBjb25zdCBOVU1CRVJfVFlQRVM6IHJlYWRvbmx5IFRlbnNvci5EYXRhVHlwZVtdID1cbiAgICBbJ2Zsb2F0MzInLCAnZmxvYXQ2NCcsICdpbnQzMicsICdpbnQxNicsICdpbnQ4JywgJ3VpbnQxNicsICd1aW50MzInLCAndWludDgnXTtcbmV4cG9ydCBjb25zdCBJTlRfVFlQRVM6IHJlYWRvbmx5IFRlbnNvci5EYXRhVHlwZVtdID0gWydpbnQzMicsICdpbnQxNicsICdpbnQ4JywgJ3VpbnQxNicsICd1aW50MzInLCAndWludDgnXTtcbmV4cG9ydCBjb25zdCBGTE9BVF9UWVBFUzogcmVhZG9ubHkgVGVuc29yLkRhdGFUeXBlW10gPSBbJ2Zsb2F0MzInLCAnZmxvYXQ2NCddO1xuIiwiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7R3JhcGh9IGZyb20gJy4vZ3JhcGgnO1xuaW1wb3J0IHtPcGVyYXRvckltcGxlbWVudGF0aW9uLCBPcGVyYXRvckluaXRpYWxpemF0aW9ufSBmcm9tICcuL29wZXJhdG9ycyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgT3BTZXQge1xuICBkb21haW46IHN0cmluZztcbiAgdmVyc2lvbjogbnVtYmVyO1xufVxuXG5leHBvcnQgZGVjbGFyZSBuYW1lc3BhY2UgT3BTZXQge1xuICAvKipcbiAgICogRG9tYWluIG9mIGFuIG9wc2V0LCBpdCBjYW4gYmUgYW4gZW1wdHkgc3RyaW5nKGRlZmF1bHQgdmFsdWUsIHJlcHJlc2VudCBmb3IgYWkub25ueCksIG9yICdhaS5vbm54Lm1sJ1xuICAgKi9cbiAgdHlwZSBEb21haW4gPSAnJ3wnYWkub25ueC5tbCd8J2NvbS5taWNyb3NvZnQnO1xuXG4gIC8qKlxuICAgKiBBIHJlc29sdmUgcnVsZSBjb25zaXN0cyBvZiA0IG9yIDUgaXRlbXM6IG9wVHlwZSwgb3BTZXREb21haW4sIHZlcnNpb25TZWxlY3Rvciwgb3BlcmF0b3JJbXBsZW1lbnRhdGlvbiBhbmRcbiAgICogb3BlcmF0b3JJbml0aWFsaXphdGlvbiAob3B0aW9uYWwpXG4gICAqL1xuICB0eXBlIFJlc29sdmVSdWxlID0gW1xuICAgIHN0cmluZywgRG9tYWluLCBzdHJpbmcsIE9wZXJhdG9ySW1wbGVtZW50YXRpb248R3JhcGguTm9kZT5cbiAgXXxbc3RyaW5nLCBEb21haW4sIHN0cmluZywgT3BlcmF0b3JJbXBsZW1lbnRhdGlvbjx1bmtub3duPiwgT3BlcmF0b3JJbml0aWFsaXphdGlvbjx1bmtub3duPl07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlT3BlcmF0b3Iobm9kZTogR3JhcGguTm9kZSwgb3BzZXRzOiByZWFkb25seSBPcFNldFtdLCBydWxlczogcmVhZG9ubHkgT3BTZXQuUmVzb2x2ZVJ1bGVbXSkge1xuICBmb3IgKGNvbnN0IHJ1bGUgb2YgcnVsZXMpIHtcbiAgICBjb25zdCBvcFR5cGUgPSBydWxlWzBdO1xuICAgIGNvbnN0IGRvbWFpbiA9IHJ1bGVbMV07XG4gICAgY29uc3QgdmVyc2lvblNlbGVjdG9yID0gcnVsZVsyXTtcbiAgICBjb25zdCBvcEltcGwgPSBydWxlWzNdO1xuICAgIGNvbnN0IG9wSW5pdCA9IHJ1bGVbNF07XG5cbiAgICBpZiAobm9kZS5vcFR5cGUgPT09IG9wVHlwZSkgeyAgLy8gb3BlcmF0b3IgdHlwZSBtYXRjaGVzXG4gICAgICBmb3IgKGNvbnN0IG9wc2V0IG9mIG9wc2V0cykge1xuICAgICAgICAvLyBvcHNldCAnJyBhbmQgJ2FpLm9ubngnIGFyZSBjb25zaWRlcmVkIHRoZSBzYW1lLlxuICAgICAgICBpZiAob3BzZXQuZG9tYWluID09PSBkb21haW4gfHwgKG9wc2V0LmRvbWFpbiA9PT0gJ2FpLm9ubngnICYmIGRvbWFpbiA9PT0gJycpKSB7ICAvLyBvcHNldCBkb21haW4gZm91bmRcbiAgICAgICAgICBpZiAobWF0Y2hTZWxlY3RvcihvcHNldC52ZXJzaW9uLCB2ZXJzaW9uU2VsZWN0b3IpKSB7XG4gICAgICAgICAgICByZXR1cm4ge29wSW1wbCwgb3BJbml0fTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZUVycm9yKGBjYW5ub3QgcmVzb2x2ZSBvcGVyYXRvciAnJHtub2RlLm9wVHlwZX0nIHdpdGggb3BzZXRzOiAke1xuICAgICAgb3BzZXRzLm1hcChzZXQgPT4gYCR7c2V0LmRvbWFpbiB8fCAnYWkub25ueCd9IHYke3NldC52ZXJzaW9ufWApLmpvaW4oJywgJyl9YCk7XG59XG5cbmZ1bmN0aW9uIG1hdGNoU2VsZWN0b3IodmVyc2lvbjogbnVtYmVyLCBzZWxlY3Rvcjogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGlmIChzZWxlY3Rvci5lbmRzV2l0aCgnKycpKSB7XG4gICAgLy8gbWluaW11bSB2ZXJzaW9uIG1hdGNoICgnNysnIGV4cGVjdHMgdmVyc2lvbj49NylcbiAgICBjb25zdCByYW5nZVN0YXJ0ID0gTnVtYmVyLnBhcnNlSW50KHNlbGVjdG9yLnN1YnN0cmluZygwLCBzZWxlY3Rvci5sZW5ndGggLSAxKSwgMTApO1xuICAgIHJldHVybiAhaXNOYU4ocmFuZ2VTdGFydCkgJiYgcmFuZ2VTdGFydCA8PSB2ZXJzaW9uO1xuICB9IGVsc2UgaWYgKHNlbGVjdG9yLnNwbGl0KCctJykubGVuZ3RoID09PSAyKSB7XG4gICAgLy8gcmFuZ2UgbWF0Y2ggKCc2LTgnIGV4cGVjdHMgNjw9dmVyc2lvbjw9OClcbiAgICBjb25zdCBwYWlyID0gc2VsZWN0b3Iuc3BsaXQoJy0nKTtcbiAgICBjb25zdCByYW5nZVN0YXJ0ID0gTnVtYmVyLnBhcnNlSW50KHBhaXJbMF0sIDEwKTtcbiAgICBjb25zdCByYW5nZUVuZCA9IE51bWJlci5wYXJzZUludChwYWlyWzFdLCAxMCk7XG4gICAgcmV0dXJuICFpc05hTihyYW5nZVN0YXJ0KSAmJiAhaXNOYU4ocmFuZ2VFbmQpICYmIHJhbmdlU3RhcnQgPD0gdmVyc2lvbiAmJiB2ZXJzaW9uIDw9IHJhbmdlRW5kO1xuICB9IGVsc2Uge1xuICAgIC8vIGV4YWN0IG1hdGNoICgnNycgZXhwZWN0cyB2ZXJzaW9uPT09NylcbiAgICByZXR1cm4gTnVtYmVyLnBhcnNlSW50KHNlbGVjdG9yLCAxMCkgPT09IHZlcnNpb247XG4gIH1cbn1cbiIsIi8vIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IHRoZSBGbGF0QnVmZmVycyBjb21waWxlciwgZG8gbm90IG1vZGlmeVxuLyogZXNsaW50LWRpc2FibGUgKi9cblxuaW1wb3J0IHtmbGF0YnVmZmVyc30gZnJvbSAnZmxhdGJ1ZmZlcnMnO1xuXG4vKipcbiAqIEBlbnVtIHtudW1iZXJ9XG4gKi9cbmV4cG9ydCBuYW1lc3BhY2Ugb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicyB7XG4gIGV4cG9ydCBlbnVtIEF0dHJpYnV0ZVR5cGUge1xuICAgIFVOREVGSU5FRCA9IDAsXG4gICAgRkxPQVQgPSAxLFxuICAgIElOVCA9IDIsXG4gICAgU1RSSU5HID0gMyxcbiAgICBURU5TT1IgPSA0LFxuICAgIEdSQVBIID0gNSxcbiAgICBGTE9BVFMgPSA2LFxuICAgIElOVFMgPSA3LFxuICAgIFNUUklOR1MgPSA4LFxuICAgIFRFTlNPUlMgPSA5LFxuICAgIEdSQVBIUyA9IDEwLFxuICAgIFNQQVJTRV9URU5TT1IgPSAxMSxcbiAgICBTUEFSU0VfVEVOU09SUyA9IDEyXG4gIH1cbn1cblxuLyoqXG4gKiBAZW51bSB7bnVtYmVyfVxuICovXG5leHBvcnQgbmFtZXNwYWNlIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMge1xuICBleHBvcnQgZW51bSBEaW1lbnNpb25WYWx1ZVR5cGUge1VOS05PV04gPSAwLCBWQUxVRSA9IDEsIFBBUkFNID0gMn1cbn1cblxuLyoqXG4gKiBAZW51bSB7bnVtYmVyfVxuICovXG5leHBvcnQgbmFtZXNwYWNlIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMge1xuICBleHBvcnQgZW51bSBUZW5zb3JEYXRhVHlwZSB7XG4gICAgVU5ERUZJTkVEID0gMCxcbiAgICBGTE9BVCA9IDEsXG4gICAgVUlOVDggPSAyLFxuICAgIElOVDggPSAzLFxuICAgIFVJTlQxNiA9IDQsXG4gICAgSU5UMTYgPSA1LFxuICAgIElOVDMyID0gNixcbiAgICBJTlQ2NCA9IDcsXG4gICAgU1RSSU5HID0gOCxcbiAgICBCT09MID0gOSxcbiAgICBGTE9BVDE2ID0gMTAsXG4gICAgRE9VQkxFID0gMTEsXG4gICAgVUlOVDMyID0gMTIsXG4gICAgVUlOVDY0ID0gMTMsXG4gICAgQ09NUExFWDY0ID0gMTQsXG4gICAgQ09NUExFWDEyOCA9IDE1LFxuICAgIEJGTE9BVDE2ID0gMTZcbiAgfVxufVxuXG4vKipcbiAqIEBlbnVtIHtudW1iZXJ9XG4gKi9cbmV4cG9ydCBuYW1lc3BhY2Ugb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicyB7XG4gIGV4cG9ydCBlbnVtIE5vZGVUeXBlIHtQcmltaXRpdmUgPSAwLCBGdXNlZCA9IDF9XG59XG5cbi8qKlxuICogQGVudW0ge251bWJlcn1cbiAqL1xuZXhwb3J0IG5hbWVzcGFjZSBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzIHtcbiAgZXhwb3J0IGVudW0gVHlwZUluZm9WYWx1ZSB7Tk9ORSA9IDAsIHRlbnNvcl90eXBlID0gMSwgc2VxdWVuY2VfdHlwZSA9IDIsIG1hcF90eXBlID0gM31cbn1cblxuLyoqXG4gKiBAY29uc3RydWN0b3JcbiAqL1xuZXhwb3J0IG5hbWVzcGFjZSBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzIHtcbiAgZXhwb3J0IGNsYXNzIFNoYXBlIHtcbiAgICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcnxudWxsID0gbnVsbDtcblxuICAgIGJiX3BvcyA9IDA7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIG51bWJlciBpXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcmV0dXJucyBTaGFwZVxuICAgICAqL1xuICAgIF9faW5pdChpOiBudW1iZXIsIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKTogU2hhcGUge1xuICAgICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgICAgdGhpcy5iYiA9IGJiO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcGFyYW0gU2hhcGU9IG9ialxuICAgICAqIEByZXR1cm5zIFNoYXBlXG4gICAgICovXG4gICAgc3RhdGljIGdldFJvb3RBc1NoYXBlKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBTaGFwZSk6IFNoYXBlIHtcbiAgICAgIHJldHVybiAob2JqIHx8IG5ldyBTaGFwZSgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIGJiXG4gICAgICogQHBhcmFtIFNoYXBlPSBvYmpcbiAgICAgKiBAcmV0dXJucyBTaGFwZVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRTaXplUHJlZml4ZWRSb290QXNTaGFwZShiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogU2hhcGUpOiBTaGFwZSB7XG4gICAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICAgIHJldHVybiAob2JqIHx8IG5ldyBTaGFwZSgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBudW1iZXIgaW5kZXhcbiAgICAgKiBAcGFyYW0gb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5EaW1lbnNpb249IG9ialxuICAgICAqIEByZXR1cm5zIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuRGltZW5zaW9uXG4gICAgICovXG4gICAgZGltKGluZGV4OiBudW1iZXIsIG9iaj86IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuRGltZW5zaW9uKTogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5EaW1lbnNpb258bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IChvYmogfHwgbmV3IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuRGltZW5zaW9uKCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQpLCB0aGlzLmJiISkgOlxuICAgICAgICAgICAgICAgICAgICAgIG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgbnVtYmVyXG4gICAgICovXG4gICAgZGltTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKi9cbiAgICBzdGF0aWMgc3RhcnRTaGFwZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgICBidWlsZGVyLnN0YXJ0T2JqZWN0KDEpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IGRpbU9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGREaW0oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGltT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMCwgZGltT2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIEFycmF5LjxmbGF0YnVmZmVycy5PZmZzZXQ+IGRhdGFcbiAgICAgKiBAcmV0dXJucyBmbGF0YnVmZmVycy5PZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgY3JlYXRlRGltVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLk9mZnNldFtdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgZGF0YS5sZW5ndGgsIDQpO1xuICAgICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgYnVpbGRlci5hZGRPZmZzZXQoZGF0YVtpXSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIG51bWJlciBudW1FbGVtc1xuICAgICAqL1xuICAgIHN0YXRpYyBzdGFydERpbVZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGVuZFNoYXBlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgICAgbGV0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgICByZXR1cm4gb2Zmc2V0O1xuICAgIH1cblxuICAgIHN0YXRpYyBjcmVhdGVTaGFwZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkaW1PZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBTaGFwZS5zdGFydFNoYXBlKGJ1aWxkZXIpO1xuICAgICAgU2hhcGUuYWRkRGltKGJ1aWxkZXIsIGRpbU9mZnNldCk7XG4gICAgICByZXR1cm4gU2hhcGUuZW5kU2hhcGUoYnVpbGRlcik7XG4gICAgfVxuICB9XG59XG4vKipcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5leHBvcnQgbmFtZXNwYWNlIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMge1xuICBleHBvcnQgY2xhc3MgRGltZW5zaW9uIHtcbiAgICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcnxudWxsID0gbnVsbDtcblxuICAgIGJiX3BvcyA9IDA7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIG51bWJlciBpXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcmV0dXJucyBEaW1lbnNpb25cbiAgICAgKi9cbiAgICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IERpbWVuc2lvbiB7XG4gICAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgICB0aGlzLmJiID0gYmI7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciBiYlxuICAgICAqIEBwYXJhbSBEaW1lbnNpb249IG9ialxuICAgICAqIEByZXR1cm5zIERpbWVuc2lvblxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRSb290QXNEaW1lbnNpb24oYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IERpbWVuc2lvbik6IERpbWVuc2lvbiB7XG4gICAgICByZXR1cm4gKG9iaiB8fCBuZXcgRGltZW5zaW9uKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcGFyYW0gRGltZW5zaW9uPSBvYmpcbiAgICAgKiBAcmV0dXJucyBEaW1lbnNpb25cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0U2l6ZVByZWZpeGVkUm9vdEFzRGltZW5zaW9uKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBEaW1lbnNpb24pOiBEaW1lbnNpb24ge1xuICAgICAgYmIuc2V0UG9zaXRpb24oYmIucG9zaXRpb24oKSArIGZsYXRidWZmZXJzLlNJWkVfUFJFRklYX0xFTkdUSCk7XG4gICAgICByZXR1cm4gKG9iaiB8fCBuZXcgRGltZW5zaW9uKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuRGltZW5zaW9uVmFsdWU9IG9ialxuICAgICAqIEByZXR1cm5zIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuRGltZW5zaW9uVmFsdWV8bnVsbFxuICAgICAqL1xuICAgIHZhbHVlKG9iaj86IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuRGltZW5zaW9uVmFsdWUpOiBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLkRpbWVuc2lvblZhbHVlfG51bGwge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyAob2JqIHx8IG5ldyBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLkRpbWVuc2lvblZhbHVlKCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiX3BvcyArIG9mZnNldCksIHRoaXMuYmIhKSA6XG4gICAgICAgICAgICAgICAgICAgICAgbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuRW5jb2Rpbmc9IG9wdGlvbmFsRW5jb2RpbmdcbiAgICAgKiBAcmV0dXJucyBzdHJpbmd8VWludDhBcnJheXxudWxsXG4gICAgICovXG4gICAgZGVub3RhdGlvbigpOiBzdHJpbmd8bnVsbDtcbiAgICBkZW5vdGF0aW9uKG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbDtcbiAgICBkZW5vdGF0aW9uKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmd8VWludDhBcnJheXxudWxsIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICovXG4gICAgc3RhdGljIHN0YXJ0RGltZW5zaW9uKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpIHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoMik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5PZmZzZXQgdmFsdWVPZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkVmFsdWUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgdmFsdWVPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgwLCB2YWx1ZU9mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5PZmZzZXQgZGVub3RhdGlvbk9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGREZW5vdGF0aW9uKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRlbm90YXRpb25PZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxLCBkZW5vdGF0aW9uT2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGVuZERpbWVuc2lvbihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICAgIGxldCBvZmZzZXQgPSBidWlsZGVyLmVuZE9iamVjdCgpO1xuICAgICAgcmV0dXJuIG9mZnNldDtcbiAgICB9XG5cbiAgICBzdGF0aWMgY3JlYXRlRGltZW5zaW9uKFxuICAgICAgICBidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCB2YWx1ZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgICAgICBkZW5vdGF0aW9uT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgICAgRGltZW5zaW9uLnN0YXJ0RGltZW5zaW9uKGJ1aWxkZXIpO1xuICAgICAgRGltZW5zaW9uLmFkZFZhbHVlKGJ1aWxkZXIsIHZhbHVlT2Zmc2V0KTtcbiAgICAgIERpbWVuc2lvbi5hZGREZW5vdGF0aW9uKGJ1aWxkZXIsIGRlbm90YXRpb25PZmZzZXQpO1xuICAgICAgcmV0dXJuIERpbWVuc2lvbi5lbmREaW1lbnNpb24oYnVpbGRlcik7XG4gICAgfVxuICB9XG59XG4vKipcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5leHBvcnQgbmFtZXNwYWNlIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMge1xuICBleHBvcnQgY2xhc3MgRGltZW5zaW9uVmFsdWUge1xuICAgIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyfG51bGwgPSBudWxsO1xuXG4gICAgYmJfcG9zID0gMDtcbiAgICAvKipcbiAgICAgKiBAcGFyYW0gbnVtYmVyIGlcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciBiYlxuICAgICAqIEByZXR1cm5zIERpbWVuc2lvblZhbHVlXG4gICAgICovXG4gICAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBEaW1lbnNpb25WYWx1ZSB7XG4gICAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgICB0aGlzLmJiID0gYmI7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciBiYlxuICAgICAqIEBwYXJhbSBEaW1lbnNpb25WYWx1ZT0gb2JqXG4gICAgICogQHJldHVybnMgRGltZW5zaW9uVmFsdWVcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0Um9vdEFzRGltZW5zaW9uVmFsdWUoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IERpbWVuc2lvblZhbHVlKTogRGltZW5zaW9uVmFsdWUge1xuICAgICAgcmV0dXJuIChvYmogfHwgbmV3IERpbWVuc2lvblZhbHVlKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcGFyYW0gRGltZW5zaW9uVmFsdWU9IG9ialxuICAgICAqIEByZXR1cm5zIERpbWVuc2lvblZhbHVlXG4gICAgICovXG4gICAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc0RpbWVuc2lvblZhbHVlKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBEaW1lbnNpb25WYWx1ZSk6IERpbWVuc2lvblZhbHVlIHtcbiAgICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgICAgcmV0dXJuIChvYmogfHwgbmV3IERpbWVuc2lvblZhbHVlKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5EaW1lbnNpb25WYWx1ZVR5cGVcbiAgICAgKi9cbiAgICBkaW1UeXBlKCk6IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuRGltZW5zaW9uVmFsdWVUeXBlIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gLyoqICAqLyAodGhpcy5iYiEucmVhZEludDgodGhpcy5iYl9wb3MgKyBvZmZzZXQpKSA6XG4gICAgICAgICAgICAgICAgICAgICAgb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5EaW1lbnNpb25WYWx1ZVR5cGUuVU5LTk9XTjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBmbGF0YnVmZmVycy5Mb25nXG4gICAgICovXG4gICAgZGltVmFsdWUoKTogZmxhdGJ1ZmZlcnMuTG9uZyB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRJbnQ2NCh0aGlzLmJiX3BvcyArIG9mZnNldCkgOiB0aGlzLmJiIS5jcmVhdGVMb25nKDAsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5FbmNvZGluZz0gb3B0aW9uYWxFbmNvZGluZ1xuICAgICAqIEByZXR1cm5zIHN0cmluZ3xVaW50OEFycmF5fG51bGxcbiAgICAgKi9cbiAgICBkaW1QYXJhbSgpOiBzdHJpbmd8bnVsbDtcbiAgICBkaW1QYXJhbShvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZ3xVaW50OEFycmF5fG51bGw7XG4gICAgZGltUGFyYW0ob3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZ3xVaW50OEFycmF5fG51bGwge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA4KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiX3BvcyArIG9mZnNldCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKi9cbiAgICBzdGF0aWMgc3RhcnREaW1lbnNpb25WYWx1ZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgICBidWlsZGVyLnN0YXJ0T2JqZWN0KDMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5EaW1lbnNpb25WYWx1ZVR5cGUgZGltVHlwZVxuICAgICAqL1xuICAgIHN0YXRpYyBhZGREaW1UeXBlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRpbVR5cGU6IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuRGltZW5zaW9uVmFsdWVUeXBlKSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkSW50OCgwLCBkaW1UeXBlLCBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLkRpbWVuc2lvblZhbHVlVHlwZS5VTktOT1dOKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkxvbmcgZGltVmFsdWVcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkRGltVmFsdWUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGltVmFsdWU6IGZsYXRidWZmZXJzLkxvbmcpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRJbnQ2NCgxLCBkaW1WYWx1ZSwgYnVpbGRlci5jcmVhdGVMb25nKDAsIDApKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCBkaW1QYXJhbU9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGREaW1QYXJhbShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkaW1QYXJhbU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDIsIGRpbVBhcmFtT2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGVuZERpbWVuc2lvblZhbHVlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgICAgbGV0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgICByZXR1cm4gb2Zmc2V0O1xuICAgIH1cblxuICAgIHN0YXRpYyBjcmVhdGVEaW1lbnNpb25WYWx1ZShcbiAgICAgICAgYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGltVHlwZTogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5EaW1lbnNpb25WYWx1ZVR5cGUsXG4gICAgICAgIGRpbVZhbHVlOiBmbGF0YnVmZmVycy5Mb25nLCBkaW1QYXJhbU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICAgIERpbWVuc2lvblZhbHVlLnN0YXJ0RGltZW5zaW9uVmFsdWUoYnVpbGRlcik7XG4gICAgICBEaW1lbnNpb25WYWx1ZS5hZGREaW1UeXBlKGJ1aWxkZXIsIGRpbVR5cGUpO1xuICAgICAgRGltZW5zaW9uVmFsdWUuYWRkRGltVmFsdWUoYnVpbGRlciwgZGltVmFsdWUpO1xuICAgICAgRGltZW5zaW9uVmFsdWUuYWRkRGltUGFyYW0oYnVpbGRlciwgZGltUGFyYW1PZmZzZXQpO1xuICAgICAgcmV0dXJuIERpbWVuc2lvblZhbHVlLmVuZERpbWVuc2lvblZhbHVlKGJ1aWxkZXIpO1xuICAgIH1cbiAgfVxufVxuLyoqXG4gKiBAY29uc3RydWN0b3JcbiAqL1xuZXhwb3J0IG5hbWVzcGFjZSBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzIHtcbiAgZXhwb3J0IGNsYXNzIFRlbnNvclR5cGVBbmRTaGFwZSB7XG4gICAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXJ8bnVsbCA9IG51bGw7XG5cbiAgICBiYl9wb3MgPSAwO1xuICAgIC8qKlxuICAgICAqIEBwYXJhbSBudW1iZXIgaVxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIGJiXG4gICAgICogQHJldHVybnMgVGVuc29yVHlwZUFuZFNoYXBlXG4gICAgICovXG4gICAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBUZW5zb3JUeXBlQW5kU2hhcGUge1xuICAgICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgICAgdGhpcy5iYiA9IGJiO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcGFyYW0gVGVuc29yVHlwZUFuZFNoYXBlPSBvYmpcbiAgICAgKiBAcmV0dXJucyBUZW5zb3JUeXBlQW5kU2hhcGVcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0Um9vdEFzVGVuc29yVHlwZUFuZFNoYXBlKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBUZW5zb3JUeXBlQW5kU2hhcGUpOiBUZW5zb3JUeXBlQW5kU2hhcGUge1xuICAgICAgcmV0dXJuIChvYmogfHwgbmV3IFRlbnNvclR5cGVBbmRTaGFwZSgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIGJiXG4gICAgICogQHBhcmFtIFRlbnNvclR5cGVBbmRTaGFwZT0gb2JqXG4gICAgICogQHJldHVybnMgVGVuc29yVHlwZUFuZFNoYXBlXG4gICAgICovXG4gICAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc1RlbnNvclR5cGVBbmRTaGFwZShiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogVGVuc29yVHlwZUFuZFNoYXBlKTpcbiAgICAgICAgVGVuc29yVHlwZUFuZFNoYXBlIHtcbiAgICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgICAgcmV0dXJuIChvYmogfHwgbmV3IFRlbnNvclR5cGVBbmRTaGFwZSgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVGVuc29yRGF0YVR5cGVcbiAgICAgKi9cbiAgICBlbGVtVHlwZSgpOiBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlRlbnNvckRhdGFUeXBlIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gLyoqICAqLyAodGhpcy5iYiEucmVhZEludDMyKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSkgOlxuICAgICAgICAgICAgICAgICAgICAgIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVGVuc29yRGF0YVR5cGUuVU5ERUZJTkVEO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlNoYXBlPSBvYmpcbiAgICAgKiBAcmV0dXJucyBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlNoYXBlfG51bGxcbiAgICAgKi9cbiAgICBzaGFwZShvYmo/OiBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlNoYXBlKTogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5TaGFwZXxudWxsIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gKG9iaiB8fCBuZXcgb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5TaGFwZSgpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAuX19pbml0KHRoaXMuYmIhLl9faW5kaXJlY3QodGhpcy5iYl9wb3MgKyBvZmZzZXQpLCB0aGlzLmJiISkgOlxuICAgICAgICAgICAgICAgICAgICAgIG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqL1xuICAgIHN0YXRpYyBzdGFydFRlbnNvclR5cGVBbmRTaGFwZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgICBidWlsZGVyLnN0YXJ0T2JqZWN0KDIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UZW5zb3JEYXRhVHlwZSBlbGVtVHlwZVxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRFbGVtVHlwZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBlbGVtVHlwZTogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UZW5zb3JEYXRhVHlwZSkge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZEludDMyKDAsIGVsZW1UeXBlLCBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlRlbnNvckRhdGFUeXBlLlVOREVGSU5FRCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5PZmZzZXQgc2hhcGVPZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkU2hhcGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgc2hhcGVPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxLCBzaGFwZU9mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEByZXR1cm5zIGZsYXRidWZmZXJzLk9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBlbmRUZW5zb3JUeXBlQW5kU2hhcGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICAgIHJldHVybiBvZmZzZXQ7XG4gICAgfVxuXG4gICAgc3RhdGljIGNyZWF0ZVRlbnNvclR5cGVBbmRTaGFwZShcbiAgICAgICAgYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZWxlbVR5cGU6IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVGVuc29yRGF0YVR5cGUsXG4gICAgICAgIHNoYXBlT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgICAgVGVuc29yVHlwZUFuZFNoYXBlLnN0YXJ0VGVuc29yVHlwZUFuZFNoYXBlKGJ1aWxkZXIpO1xuICAgICAgVGVuc29yVHlwZUFuZFNoYXBlLmFkZEVsZW1UeXBlKGJ1aWxkZXIsIGVsZW1UeXBlKTtcbiAgICAgIFRlbnNvclR5cGVBbmRTaGFwZS5hZGRTaGFwZShidWlsZGVyLCBzaGFwZU9mZnNldCk7XG4gICAgICByZXR1cm4gVGVuc29yVHlwZUFuZFNoYXBlLmVuZFRlbnNvclR5cGVBbmRTaGFwZShidWlsZGVyKTtcbiAgICB9XG4gIH1cbn1cbi8qKlxuICogQGNvbnN0cnVjdG9yXG4gKi9cbmV4cG9ydCBuYW1lc3BhY2Ugb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicyB7XG4gIGV4cG9ydCBjbGFzcyBNYXBUeXBlIHtcbiAgICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcnxudWxsID0gbnVsbDtcblxuICAgIGJiX3BvcyA9IDA7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIG51bWJlciBpXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcmV0dXJucyBNYXBUeXBlXG4gICAgICovXG4gICAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBNYXBUeXBlIHtcbiAgICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICAgIHRoaXMuYmIgPSBiYjtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIGJiXG4gICAgICogQHBhcmFtIE1hcFR5cGU9IG9ialxuICAgICAqIEByZXR1cm5zIE1hcFR5cGVcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0Um9vdEFzTWFwVHlwZShiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogTWFwVHlwZSk6IE1hcFR5cGUge1xuICAgICAgcmV0dXJuIChvYmogfHwgbmV3IE1hcFR5cGUoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciBiYlxuICAgICAqIEBwYXJhbSBNYXBUeXBlPSBvYmpcbiAgICAgKiBAcmV0dXJucyBNYXBUeXBlXG4gICAgICovXG4gICAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc01hcFR5cGUoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IE1hcFR5cGUpOiBNYXBUeXBlIHtcbiAgICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgICAgcmV0dXJuIChvYmogfHwgbmV3IE1hcFR5cGUoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlRlbnNvckRhdGFUeXBlXG4gICAgICovXG4gICAga2V5VHlwZSgpOiBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlRlbnNvckRhdGFUeXBlIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gLyoqICAqLyAodGhpcy5iYiEucmVhZEludDMyKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSkgOlxuICAgICAgICAgICAgICAgICAgICAgIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVGVuc29yRGF0YVR5cGUuVU5ERUZJTkVEO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlR5cGVJbmZvPSBvYmpcbiAgICAgKiBAcmV0dXJucyBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlR5cGVJbmZvfG51bGxcbiAgICAgKi9cbiAgICB2YWx1ZVR5cGUob2JqPzogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UeXBlSW5mbyk6IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVHlwZUluZm98bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IChvYmogfHwgbmV3IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVHlwZUluZm8oKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLl9faW5pdCh0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmJfcG9zICsgb2Zmc2V0KSwgdGhpcy5iYiEpIDpcbiAgICAgICAgICAgICAgICAgICAgICBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKi9cbiAgICBzdGF0aWMgc3RhcnRNYXBUeXBlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpIHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoMik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlRlbnNvckRhdGFUeXBlIGtleVR5cGVcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkS2V5VHlwZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBrZXlUeXBlOiBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlRlbnNvckRhdGFUeXBlKSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkSW50MzIoMCwga2V5VHlwZSwgb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UZW5zb3JEYXRhVHlwZS5VTkRFRklORUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IHZhbHVlVHlwZU9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRWYWx1ZVR5cGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgdmFsdWVUeXBlT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMSwgdmFsdWVUeXBlT2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGVuZE1hcFR5cGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICAgIHJldHVybiBvZmZzZXQ7XG4gICAgfVxuXG4gICAgc3RhdGljIGNyZWF0ZU1hcFR5cGUoXG4gICAgICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGtleVR5cGU6IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVGVuc29yRGF0YVR5cGUsXG4gICAgICAgIHZhbHVlVHlwZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICAgIE1hcFR5cGUuc3RhcnRNYXBUeXBlKGJ1aWxkZXIpO1xuICAgICAgTWFwVHlwZS5hZGRLZXlUeXBlKGJ1aWxkZXIsIGtleVR5cGUpO1xuICAgICAgTWFwVHlwZS5hZGRWYWx1ZVR5cGUoYnVpbGRlciwgdmFsdWVUeXBlT2Zmc2V0KTtcbiAgICAgIHJldHVybiBNYXBUeXBlLmVuZE1hcFR5cGUoYnVpbGRlcik7XG4gICAgfVxuICB9XG59XG4vKipcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5leHBvcnQgbmFtZXNwYWNlIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMge1xuICBleHBvcnQgY2xhc3MgU2VxdWVuY2VUeXBlIHtcbiAgICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcnxudWxsID0gbnVsbDtcblxuICAgIGJiX3BvcyA9IDA7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIG51bWJlciBpXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcmV0dXJucyBTZXF1ZW5jZVR5cGVcbiAgICAgKi9cbiAgICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IFNlcXVlbmNlVHlwZSB7XG4gICAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgICB0aGlzLmJiID0gYmI7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciBiYlxuICAgICAqIEBwYXJhbSBTZXF1ZW5jZVR5cGU9IG9ialxuICAgICAqIEByZXR1cm5zIFNlcXVlbmNlVHlwZVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRSb290QXNTZXF1ZW5jZVR5cGUoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IFNlcXVlbmNlVHlwZSk6IFNlcXVlbmNlVHlwZSB7XG4gICAgICByZXR1cm4gKG9iaiB8fCBuZXcgU2VxdWVuY2VUeXBlKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcGFyYW0gU2VxdWVuY2VUeXBlPSBvYmpcbiAgICAgKiBAcmV0dXJucyBTZXF1ZW5jZVR5cGVcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0U2l6ZVByZWZpeGVkUm9vdEFzU2VxdWVuY2VUeXBlKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBTZXF1ZW5jZVR5cGUpOiBTZXF1ZW5jZVR5cGUge1xuICAgICAgYmIuc2V0UG9zaXRpb24oYmIucG9zaXRpb24oKSArIGZsYXRidWZmZXJzLlNJWkVfUFJFRklYX0xFTkdUSCk7XG4gICAgICByZXR1cm4gKG9iaiB8fCBuZXcgU2VxdWVuY2VUeXBlKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVHlwZUluZm89IG9ialxuICAgICAqIEByZXR1cm5zIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVHlwZUluZm98bnVsbFxuICAgICAqL1xuICAgIGVsZW1UeXBlKG9iaj86IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVHlwZUluZm8pOiBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlR5cGVJbmZvfG51bGwge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyAob2JqIHx8IG5ldyBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlR5cGVJbmZvKCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiX3BvcyArIG9mZnNldCksIHRoaXMuYmIhKSA6XG4gICAgICAgICAgICAgICAgICAgICAgbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICovXG4gICAgc3RhdGljIHN0YXJ0U2VxdWVuY2VUeXBlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpIHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoMSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5PZmZzZXQgZWxlbVR5cGVPZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkRWxlbVR5cGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZWxlbVR5cGVPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgwLCBlbGVtVHlwZU9mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEByZXR1cm5zIGZsYXRidWZmZXJzLk9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBlbmRTZXF1ZW5jZVR5cGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICAgIHJldHVybiBvZmZzZXQ7XG4gICAgfVxuXG4gICAgc3RhdGljIGNyZWF0ZVNlcXVlbmNlVHlwZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBlbGVtVHlwZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICAgIFNlcXVlbmNlVHlwZS5zdGFydFNlcXVlbmNlVHlwZShidWlsZGVyKTtcbiAgICAgIFNlcXVlbmNlVHlwZS5hZGRFbGVtVHlwZShidWlsZGVyLCBlbGVtVHlwZU9mZnNldCk7XG4gICAgICByZXR1cm4gU2VxdWVuY2VUeXBlLmVuZFNlcXVlbmNlVHlwZShidWlsZGVyKTtcbiAgICB9XG4gIH1cbn1cbi8qKlxuICogQGNvbnN0cnVjdG9yXG4gKi9cbmV4cG9ydCBuYW1lc3BhY2Ugb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicyB7XG4gIGV4cG9ydCBjbGFzcyBFZGdlRW5kIHtcbiAgICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcnxudWxsID0gbnVsbDtcblxuICAgIGJiX3BvcyA9IDA7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIG51bWJlciBpXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcmV0dXJucyBFZGdlRW5kXG4gICAgICovXG4gICAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBFZGdlRW5kIHtcbiAgICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICAgIHRoaXMuYmIgPSBiYjtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIG51bWJlclxuICAgICAqL1xuICAgIG5vZGVJbmRleCgpOiBudW1iZXIge1xuICAgICAgcmV0dXJuIHRoaXMuYmIhLnJlYWRVaW50MzIodGhpcy5iYl9wb3MpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIG51bWJlclxuICAgICAqL1xuICAgIHNyY0FyZ0luZGV4KCk6IG51bWJlciB7XG4gICAgICByZXR1cm4gdGhpcy5iYiEucmVhZEludDMyKHRoaXMuYmJfcG9zICsgNCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgbnVtYmVyXG4gICAgICovXG4gICAgZHN0QXJnSW5kZXgoKTogbnVtYmVyIHtcbiAgICAgIHJldHVybiB0aGlzLmJiIS5yZWFkSW50MzIodGhpcy5iYl9wb3MgKyA4KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIG51bWJlciBub2RlX2luZGV4XG4gICAgICogQHBhcmFtIG51bWJlciBzcmNfYXJnX2luZGV4XG4gICAgICogQHBhcmFtIG51bWJlciBkc3RfYXJnX2luZGV4XG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGNyZWF0ZUVkZ2VFbmQoXG4gICAgICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG5vZGVfaW5kZXg6IG51bWJlciwgc3JjX2FyZ19pbmRleDogbnVtYmVyLFxuICAgICAgICBkc3RfYXJnX2luZGV4OiBudW1iZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgICAgYnVpbGRlci5wcmVwKDQsIDEyKTtcbiAgICAgIGJ1aWxkZXIud3JpdGVJbnQzMihkc3RfYXJnX2luZGV4KTtcbiAgICAgIGJ1aWxkZXIud3JpdGVJbnQzMihzcmNfYXJnX2luZGV4KTtcbiAgICAgIGJ1aWxkZXIud3JpdGVJbnQzMihub2RlX2luZGV4KTtcbiAgICAgIHJldHVybiBidWlsZGVyLm9mZnNldCgpO1xuICAgIH1cbiAgfVxufVxuLyoqXG4gKiBAY29uc3RydWN0b3JcbiAqL1xuZXhwb3J0IG5hbWVzcGFjZSBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzIHtcbiAgZXhwb3J0IGNsYXNzIE5vZGVFZGdlIHtcbiAgICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcnxudWxsID0gbnVsbDtcblxuICAgIGJiX3BvcyA9IDA7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIG51bWJlciBpXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcmV0dXJucyBOb2RlRWRnZVxuICAgICAqL1xuICAgIF9faW5pdChpOiBudW1iZXIsIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKTogTm9kZUVkZ2Uge1xuICAgICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgICAgdGhpcy5iYiA9IGJiO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcGFyYW0gTm9kZUVkZ2U9IG9ialxuICAgICAqIEByZXR1cm5zIE5vZGVFZGdlXG4gICAgICovXG4gICAgc3RhdGljIGdldFJvb3RBc05vZGVFZGdlKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBOb2RlRWRnZSk6IE5vZGVFZGdlIHtcbiAgICAgIHJldHVybiAob2JqIHx8IG5ldyBOb2RlRWRnZSgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIGJiXG4gICAgICogQHBhcmFtIE5vZGVFZGdlPSBvYmpcbiAgICAgKiBAcmV0dXJucyBOb2RlRWRnZVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRTaXplUHJlZml4ZWRSb290QXNOb2RlRWRnZShiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogTm9kZUVkZ2UpOiBOb2RlRWRnZSB7XG4gICAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICAgIHJldHVybiAob2JqIHx8IG5ldyBOb2RlRWRnZSgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIG51bWJlclxuICAgICAqL1xuICAgIG5vZGVJbmRleCgpOiBudW1iZXIge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkVWludDMyKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIG51bWJlciBpbmRleFxuICAgICAqIEBwYXJhbSBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLkVkZ2VFbmQ9IG9ialxuICAgICAqIEByZXR1cm5zIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuRWRnZUVuZFxuICAgICAqL1xuICAgIGlucHV0RWRnZXMoaW5kZXg6IG51bWJlciwgb2JqPzogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5FZGdlRW5kKTogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5FZGdlRW5kfG51bGwge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA2KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyAob2JqIHx8IG5ldyBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLkVkZ2VFbmQoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLl9faW5pdCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDEyLCB0aGlzLmJiISkgOlxuICAgICAgICAgICAgICAgICAgICAgIG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgbnVtYmVyXG4gICAgICovXG4gICAgaW5wdXRFZGdlc0xlbmd0aCgpOiBudW1iZXIge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA2KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gbnVtYmVyIGluZGV4XG4gICAgICogQHBhcmFtIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuRWRnZUVuZD0gb2JqXG4gICAgICogQHJldHVybnMgb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5FZGdlRW5kXG4gICAgICovXG4gICAgb3V0cHV0RWRnZXMoaW5kZXg6IG51bWJlciwgb2JqPzogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5FZGdlRW5kKTogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5FZGdlRW5kfG51bGwge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA4KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyAob2JqIHx8IG5ldyBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLkVkZ2VFbmQoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLl9faW5pdCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDEyLCB0aGlzLmJiISkgOlxuICAgICAgICAgICAgICAgICAgICAgIG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgbnVtYmVyXG4gICAgICovXG4gICAgb3V0cHV0RWRnZXNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgOCk7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqL1xuICAgIHN0YXRpYyBzdGFydE5vZGVFZGdlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpIHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoMyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBudW1iZXIgbm9kZUluZGV4XG4gICAgICovXG4gICAgc3RhdGljIGFkZE5vZGVJbmRleChidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBub2RlSW5kZXg6IG51bWJlcikge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZEludDMyKDAsIG5vZGVJbmRleCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5PZmZzZXQgaW5wdXRFZGdlc09mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRJbnB1dEVkZ2VzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGlucHV0RWRnZXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxLCBpbnB1dEVkZ2VzT2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIG51bWJlciBudW1FbGVtc1xuICAgICAqL1xuICAgIHN0YXRpYyBzdGFydElucHV0RWRnZXNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgICAgYnVpbGRlci5zdGFydFZlY3RvcigxMiwgbnVtRWxlbXMsIDQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IG91dHB1dEVkZ2VzT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZE91dHB1dEVkZ2VzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG91dHB1dEVkZ2VzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMiwgb3V0cHV0RWRnZXNPZmZzZXQsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gbnVtYmVyIG51bUVsZW1zXG4gICAgICovXG4gICAgc3RhdGljIHN0YXJ0T3V0cHV0RWRnZXNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgICAgYnVpbGRlci5zdGFydFZlY3RvcigxMiwgbnVtRWxlbXMsIDQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcmV0dXJucyBmbGF0YnVmZmVycy5PZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgZW5kTm9kZUVkZ2UoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICAgIHJldHVybiBvZmZzZXQ7XG4gICAgfVxuXG4gICAgc3RhdGljIGNyZWF0ZU5vZGVFZGdlKFxuICAgICAgICBidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBub2RlSW5kZXg6IG51bWJlciwgaW5wdXRFZGdlc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgICAgICBvdXRwdXRFZGdlc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICAgIE5vZGVFZGdlLnN0YXJ0Tm9kZUVkZ2UoYnVpbGRlcik7XG4gICAgICBOb2RlRWRnZS5hZGROb2RlSW5kZXgoYnVpbGRlciwgbm9kZUluZGV4KTtcbiAgICAgIE5vZGVFZGdlLmFkZElucHV0RWRnZXMoYnVpbGRlciwgaW5wdXRFZGdlc09mZnNldCk7XG4gICAgICBOb2RlRWRnZS5hZGRPdXRwdXRFZGdlcyhidWlsZGVyLCBvdXRwdXRFZGdlc09mZnNldCk7XG4gICAgICByZXR1cm4gTm9kZUVkZ2UuZW5kTm9kZUVkZ2UoYnVpbGRlcik7XG4gICAgfVxuICB9XG59XG4vKipcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5leHBvcnQgbmFtZXNwYWNlIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMge1xuICBleHBvcnQgY2xhc3MgTm9kZSB7XG4gICAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXJ8bnVsbCA9IG51bGw7XG5cbiAgICBiYl9wb3MgPSAwO1xuICAgIC8qKlxuICAgICAqIEBwYXJhbSBudW1iZXIgaVxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIGJiXG4gICAgICogQHJldHVybnMgTm9kZVxuICAgICAqL1xuICAgIF9faW5pdChpOiBudW1iZXIsIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKTogTm9kZSB7XG4gICAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgICB0aGlzLmJiID0gYmI7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciBiYlxuICAgICAqIEBwYXJhbSBOb2RlPSBvYmpcbiAgICAgKiBAcmV0dXJucyBOb2RlXG4gICAgICovXG4gICAgc3RhdGljIGdldFJvb3RBc05vZGUoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IE5vZGUpOiBOb2RlIHtcbiAgICAgIHJldHVybiAob2JqIHx8IG5ldyBOb2RlKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcGFyYW0gTm9kZT0gb2JqXG4gICAgICogQHJldHVybnMgTm9kZVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRTaXplUHJlZml4ZWRSb290QXNOb2RlKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBOb2RlKTogTm9kZSB7XG4gICAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICAgIHJldHVybiAob2JqIHx8IG5ldyBOb2RlKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkVuY29kaW5nPSBvcHRpb25hbEVuY29kaW5nXG4gICAgICogQHJldHVybnMgc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbFxuICAgICAqL1xuICAgIG5hbWUoKTogc3RyaW5nfG51bGw7XG4gICAgbmFtZShvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZ3xVaW50OEFycmF5fG51bGw7XG4gICAgbmFtZShvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkVuY29kaW5nPSBvcHRpb25hbEVuY29kaW5nXG4gICAgICogQHJldHVybnMgc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbFxuICAgICAqL1xuICAgIGRvY1N0cmluZygpOiBzdHJpbmd8bnVsbDtcbiAgICBkb2NTdHJpbmcob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmd8VWludDhBcnJheXxudWxsO1xuICAgIGRvY1N0cmluZyhvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkVuY29kaW5nPSBvcHRpb25hbEVuY29kaW5nXG4gICAgICogQHJldHVybnMgc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbFxuICAgICAqL1xuICAgIGRvbWFpbigpOiBzdHJpbmd8bnVsbDtcbiAgICBkb21haW4ob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmd8VWludDhBcnJheXxudWxsO1xuICAgIGRvbWFpbihvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDgpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgbnVtYmVyXG4gICAgICovXG4gICAgc2luY2VWZXJzaW9uKCk6IG51bWJlciB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDEwKTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkSW50MzIodGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBudW1iZXJcbiAgICAgKi9cbiAgICBpbmRleCgpOiBudW1iZXIge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAxMik7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEucmVhZFVpbnQzMih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5FbmNvZGluZz0gb3B0aW9uYWxFbmNvZGluZ1xuICAgICAqIEByZXR1cm5zIHN0cmluZ3xVaW50OEFycmF5fG51bGxcbiAgICAgKi9cbiAgICBvcFR5cGUoKTogc3RyaW5nfG51bGw7XG4gICAgb3BUeXBlKG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbDtcbiAgICBvcFR5cGUob3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZ3xVaW50OEFycmF5fG51bGwge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAxNCk7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLk5vZGVUeXBlXG4gICAgICovXG4gICAgdHlwZSgpOiBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLk5vZGVUeXBlIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTYpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IC8qKiAgKi8gKHRoaXMuYmIhLnJlYWRJbnQzMih0aGlzLmJiX3BvcyArIG9mZnNldCkpIDpcbiAgICAgICAgICAgICAgICAgICAgICBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLk5vZGVUeXBlLlByaW1pdGl2ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuRW5jb2Rpbmc9IG9wdGlvbmFsRW5jb2RpbmdcbiAgICAgKiBAcmV0dXJucyBzdHJpbmd8VWludDhBcnJheXxudWxsXG4gICAgICovXG4gICAgZXhlY3V0aW9uUHJvdmlkZXJUeXBlKCk6IHN0cmluZ3xudWxsO1xuICAgIGV4ZWN1dGlvblByb3ZpZGVyVHlwZShvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZ3xVaW50OEFycmF5fG51bGw7XG4gICAgZXhlY3V0aW9uUHJvdmlkZXJUeXBlKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmd8VWludDhBcnJheXxudWxsIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTgpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIG51bWJlciBpbmRleFxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5FbmNvZGluZz0gb3B0aW9uYWxFbmNvZGluZ1xuICAgICAqIEByZXR1cm5zIHN0cmluZ3xVaW50OEFycmF5XG4gICAgICovXG4gICAgaW5wdXRzKGluZGV4OiBudW1iZXIpOiBzdHJpbmc7XG4gICAgaW5wdXRzKGluZGV4OiBudW1iZXIsIG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nfFVpbnQ4QXJyYXk7XG4gICAgaW5wdXRzKGluZGV4OiBudW1iZXIsIG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmd8VWludDhBcnJheXxudWxsIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjApO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIG51bWJlclxuICAgICAqL1xuICAgIGlucHV0c0xlbmd0aCgpOiBudW1iZXIge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyMCk7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIG51bWJlciBpbmRleFxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5FbmNvZGluZz0gb3B0aW9uYWxFbmNvZGluZ1xuICAgICAqIEByZXR1cm5zIHN0cmluZ3xVaW50OEFycmF5XG4gICAgICovXG4gICAgb3V0cHV0cyhpbmRleDogbnVtYmVyKTogc3RyaW5nO1xuICAgIG91dHB1dHMoaW5kZXg6IG51bWJlciwgb3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmd8VWludDhBcnJheTtcbiAgICBvdXRwdXRzKGluZGV4OiBudW1iZXIsIG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmd8VWludDhBcnJheXxudWxsIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjIpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIG51bWJlclxuICAgICAqL1xuICAgIG91dHB1dHNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjIpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBudW1iZXIgaW5kZXhcbiAgICAgKiBAcGFyYW0gb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5BdHRyaWJ1dGU9IG9ialxuICAgICAqIEByZXR1cm5zIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuQXR0cmlidXRlXG4gICAgICovXG4gICAgYXR0cmlidXRlcyhpbmRleDogbnVtYmVyLCBvYmo/OiBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLkF0dHJpYnV0ZSk6IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuQXR0cmlidXRlXG4gICAgICAgIHxudWxsIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjQpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IChvYmogfHwgbmV3IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuQXR0cmlidXRlKCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQpLCB0aGlzLmJiISkgOlxuICAgICAgICAgICAgICAgICAgICAgIG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgbnVtYmVyXG4gICAgICovXG4gICAgYXR0cmlidXRlc0xlbmd0aCgpOiBudW1iZXIge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyNCk7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIG51bWJlciBpbmRleFxuICAgICAqIEByZXR1cm5zIG51bWJlclxuICAgICAqL1xuICAgIGlucHV0QXJnQ291bnRzKGluZGV4OiBudW1iZXIpOiBudW1iZXJ8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDI2KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkSW50MzIodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA0KSA6IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgbnVtYmVyXG4gICAgICovXG4gICAgaW5wdXRBcmdDb3VudHNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjYpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIEludDMyQXJyYXlcbiAgICAgKi9cbiAgICBpbnB1dEFyZ0NvdW50c0FycmF5KCk6IEludDMyQXJyYXl8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDI2KTtcbiAgICAgIHJldHVybiBvZmZzZXQgP1xuICAgICAgICAgIG5ldyBJbnQzMkFycmF5KFxuICAgICAgICAgICAgICB0aGlzLmJiIS5ieXRlcygpLmJ1ZmZlciwgdGhpcy5iYiEuYnl0ZXMoKS5ieXRlT2Zmc2V0ICsgdGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpLFxuICAgICAgICAgICAgICB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpKSA6XG4gICAgICAgICAgbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gbnVtYmVyIGluZGV4XG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkVuY29kaW5nPSBvcHRpb25hbEVuY29kaW5nXG4gICAgICogQHJldHVybnMgc3RyaW5nfFVpbnQ4QXJyYXlcbiAgICAgKi9cbiAgICBpbXBsaWNpdElucHV0cyhpbmRleDogbnVtYmVyKTogc3RyaW5nO1xuICAgIGltcGxpY2l0SW5wdXRzKGluZGV4OiBudW1iZXIsIG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nfFVpbnQ4QXJyYXk7XG4gICAgaW1wbGljaXRJbnB1dHMoaW5kZXg6IG51bWJlciwgb3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZ3xVaW50OEFycmF5fG51bGwge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyOCk7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgbnVtYmVyXG4gICAgICovXG4gICAgaW1wbGljaXRJbnB1dHNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjgpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKi9cbiAgICBzdGF0aWMgc3RhcnROb2RlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpIHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoMTMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IG5hbWVPZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkTmFtZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBuYW1lT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMCwgbmFtZU9mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5PZmZzZXQgZG9jU3RyaW5nT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZERvY1N0cmluZyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkb2NTdHJpbmdPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxLCBkb2NTdHJpbmdPZmZzZXQsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IGRvbWFpbk9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGREb21haW4oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZG9tYWluT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMiwgZG9tYWluT2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIG51bWJlciBzaW5jZVZlcnNpb25cbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkU2luY2VWZXJzaW9uKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIHNpbmNlVmVyc2lvbjogbnVtYmVyKSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkSW50MzIoMywgc2luY2VWZXJzaW9uLCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIG51bWJlciBpbmRleFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRJbmRleChidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBpbmRleDogbnVtYmVyKSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkSW50MzIoNCwgaW5kZXgsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IG9wVHlwZU9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRPcFR5cGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgb3BUeXBlT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoNSwgb3BUeXBlT2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuTm9kZVR5cGUgdHlwZVxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRUeXBlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIHR5cGU6IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuTm9kZVR5cGUpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRJbnQzMig2LCB0eXBlLCBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLk5vZGVUeXBlLlByaW1pdGl2ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5PZmZzZXQgZXhlY3V0aW9uUHJvdmlkZXJUeXBlT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZEV4ZWN1dGlvblByb3ZpZGVyVHlwZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBleGVjdXRpb25Qcm92aWRlclR5cGVPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCg3LCBleGVjdXRpb25Qcm92aWRlclR5cGVPZmZzZXQsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IGlucHV0c09mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRJbnB1dHMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgaW5wdXRzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoOCwgaW5wdXRzT2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIEFycmF5LjxmbGF0YnVmZmVycy5PZmZzZXQ+IGRhdGFcbiAgICAgKiBAcmV0dXJucyBmbGF0YnVmZmVycy5PZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgY3JlYXRlSW5wdXRzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLk9mZnNldFtdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgZGF0YS5sZW5ndGgsIDQpO1xuICAgICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgYnVpbGRlci5hZGRPZmZzZXQoZGF0YVtpXSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIG51bWJlciBudW1FbGVtc1xuICAgICAqL1xuICAgIHN0YXRpYyBzdGFydElucHV0c1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCBvdXRwdXRzT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZE91dHB1dHMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgb3V0cHV0c09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDksIG91dHB1dHNPZmZzZXQsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gQXJyYXkuPGZsYXRidWZmZXJzLk9mZnNldD4gZGF0YVxuICAgICAqIEByZXR1cm5zIGZsYXRidWZmZXJzLk9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBjcmVhdGVPdXRwdXRzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLk9mZnNldFtdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgZGF0YS5sZW5ndGgsIDQpO1xuICAgICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgYnVpbGRlci5hZGRPZmZzZXQoZGF0YVtpXSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIG51bWJlciBudW1FbGVtc1xuICAgICAqL1xuICAgIHN0YXRpYyBzdGFydE91dHB1dHNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBudW1FbGVtcywgNCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5PZmZzZXQgYXR0cmlidXRlc09mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRBdHRyaWJ1dGVzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGF0dHJpYnV0ZXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxMCwgYXR0cmlidXRlc09mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBBcnJheS48ZmxhdGJ1ZmZlcnMuT2Zmc2V0PiBkYXRhXG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGNyZWF0ZUF0dHJpYnV0ZXNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogZmxhdGJ1ZmZlcnMuT2Zmc2V0W10pOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICBidWlsZGVyLmFkZE9mZnNldChkYXRhW2ldKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gbnVtYmVyIG51bUVsZW1zXG4gICAgICovXG4gICAgc3RhdGljIHN0YXJ0QXR0cmlidXRlc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCBpbnB1dEFyZ0NvdW50c09mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRJbnB1dEFyZ0NvdW50cyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBpbnB1dEFyZ0NvdW50c09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDExLCBpbnB1dEFyZ0NvdW50c09mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBBcnJheS48bnVtYmVyPiBkYXRhXG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGNyZWF0ZUlucHV0QXJnQ291bnRzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IG51bWJlcltdfFVpbnQ4QXJyYXkpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICBidWlsZGVyLmFkZEludDMyKGRhdGFbaV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBudW1iZXIgbnVtRWxlbXNcbiAgICAgKi9cbiAgICBzdGF0aWMgc3RhcnRJbnB1dEFyZ0NvdW50c1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCBpbXBsaWNpdElucHV0c09mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRJbXBsaWNpdElucHV0cyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBpbXBsaWNpdElucHV0c09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDEyLCBpbXBsaWNpdElucHV0c09mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBBcnJheS48ZmxhdGJ1ZmZlcnMuT2Zmc2V0PiBkYXRhXG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGNyZWF0ZUltcGxpY2l0SW5wdXRzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLk9mZnNldFtdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgZGF0YS5sZW5ndGgsIDQpO1xuICAgICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgYnVpbGRlci5hZGRPZmZzZXQoZGF0YVtpXSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIG51bWJlciBudW1FbGVtc1xuICAgICAqL1xuICAgIHN0YXRpYyBzdGFydEltcGxpY2l0SW5wdXRzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcmV0dXJucyBmbGF0YnVmZmVycy5PZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgZW5kTm9kZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICAgIGxldCBvZmZzZXQgPSBidWlsZGVyLmVuZE9iamVjdCgpO1xuICAgICAgcmV0dXJuIG9mZnNldDtcbiAgICB9XG5cbiAgICBzdGF0aWMgY3JlYXRlTm9kZShcbiAgICAgICAgYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbmFtZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LCBkb2NTdHJpbmdPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgICAgICAgZG9tYWluT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsIHNpbmNlVmVyc2lvbjogbnVtYmVyLCBpbmRleDogbnVtYmVyLCBvcFR5cGVPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgICAgICAgdHlwZTogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5Ob2RlVHlwZSwgZXhlY3V0aW9uUHJvdmlkZXJUeXBlT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICAgICAgIGlucHV0c09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LCBvdXRwdXRzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsIGF0dHJpYnV0ZXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgICAgICAgaW5wdXRBcmdDb3VudHNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCwgaW1wbGljaXRJbnB1dHNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBOb2RlLnN0YXJ0Tm9kZShidWlsZGVyKTtcbiAgICAgIE5vZGUuYWRkTmFtZShidWlsZGVyLCBuYW1lT2Zmc2V0KTtcbiAgICAgIE5vZGUuYWRkRG9jU3RyaW5nKGJ1aWxkZXIsIGRvY1N0cmluZ09mZnNldCk7XG4gICAgICBOb2RlLmFkZERvbWFpbihidWlsZGVyLCBkb21haW5PZmZzZXQpO1xuICAgICAgTm9kZS5hZGRTaW5jZVZlcnNpb24oYnVpbGRlciwgc2luY2VWZXJzaW9uKTtcbiAgICAgIE5vZGUuYWRkSW5kZXgoYnVpbGRlciwgaW5kZXgpO1xuICAgICAgTm9kZS5hZGRPcFR5cGUoYnVpbGRlciwgb3BUeXBlT2Zmc2V0KTtcbiAgICAgIE5vZGUuYWRkVHlwZShidWlsZGVyLCB0eXBlKTtcbiAgICAgIE5vZGUuYWRkRXhlY3V0aW9uUHJvdmlkZXJUeXBlKGJ1aWxkZXIsIGV4ZWN1dGlvblByb3ZpZGVyVHlwZU9mZnNldCk7XG4gICAgICBOb2RlLmFkZElucHV0cyhidWlsZGVyLCBpbnB1dHNPZmZzZXQpO1xuICAgICAgTm9kZS5hZGRPdXRwdXRzKGJ1aWxkZXIsIG91dHB1dHNPZmZzZXQpO1xuICAgICAgTm9kZS5hZGRBdHRyaWJ1dGVzKGJ1aWxkZXIsIGF0dHJpYnV0ZXNPZmZzZXQpO1xuICAgICAgTm9kZS5hZGRJbnB1dEFyZ0NvdW50cyhidWlsZGVyLCBpbnB1dEFyZ0NvdW50c09mZnNldCk7XG4gICAgICBOb2RlLmFkZEltcGxpY2l0SW5wdXRzKGJ1aWxkZXIsIGltcGxpY2l0SW5wdXRzT2Zmc2V0KTtcbiAgICAgIHJldHVybiBOb2RlLmVuZE5vZGUoYnVpbGRlcik7XG4gICAgfVxuICB9XG59XG4vKipcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5leHBvcnQgbmFtZXNwYWNlIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMge1xuICBleHBvcnQgY2xhc3MgVmFsdWVJbmZvIHtcbiAgICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcnxudWxsID0gbnVsbDtcblxuICAgIGJiX3BvcyA9IDA7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIG51bWJlciBpXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcmV0dXJucyBWYWx1ZUluZm9cbiAgICAgKi9cbiAgICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IFZhbHVlSW5mbyB7XG4gICAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgICB0aGlzLmJiID0gYmI7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciBiYlxuICAgICAqIEBwYXJhbSBWYWx1ZUluZm89IG9ialxuICAgICAqIEByZXR1cm5zIFZhbHVlSW5mb1xuICAgICAqL1xuICAgIHN0YXRpYyBnZXRSb290QXNWYWx1ZUluZm8oYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IFZhbHVlSW5mbyk6IFZhbHVlSW5mbyB7XG4gICAgICByZXR1cm4gKG9iaiB8fCBuZXcgVmFsdWVJbmZvKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcGFyYW0gVmFsdWVJbmZvPSBvYmpcbiAgICAgKiBAcmV0dXJucyBWYWx1ZUluZm9cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0U2l6ZVByZWZpeGVkUm9vdEFzVmFsdWVJbmZvKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBWYWx1ZUluZm8pOiBWYWx1ZUluZm8ge1xuICAgICAgYmIuc2V0UG9zaXRpb24oYmIucG9zaXRpb24oKSArIGZsYXRidWZmZXJzLlNJWkVfUFJFRklYX0xFTkdUSCk7XG4gICAgICByZXR1cm4gKG9iaiB8fCBuZXcgVmFsdWVJbmZvKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkVuY29kaW5nPSBvcHRpb25hbEVuY29kaW5nXG4gICAgICogQHJldHVybnMgc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbFxuICAgICAqL1xuICAgIG5hbWUoKTogc3RyaW5nfG51bGw7XG4gICAgbmFtZShvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZ3xVaW50OEFycmF5fG51bGw7XG4gICAgbmFtZShvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkVuY29kaW5nPSBvcHRpb25hbEVuY29kaW5nXG4gICAgICogQHJldHVybnMgc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbFxuICAgICAqL1xuICAgIGRvY1N0cmluZygpOiBzdHJpbmd8bnVsbDtcbiAgICBkb2NTdHJpbmcob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmd8VWludDhBcnJheXxudWxsO1xuICAgIGRvY1N0cmluZyhvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVHlwZUluZm89IG9ialxuICAgICAqIEByZXR1cm5zIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVHlwZUluZm98bnVsbFxuICAgICAqL1xuICAgIHR5cGUob2JqPzogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UeXBlSW5mbyk6IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVHlwZUluZm98bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDgpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IChvYmogfHwgbmV3IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVHlwZUluZm8oKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLl9faW5pdCh0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmJfcG9zICsgb2Zmc2V0KSwgdGhpcy5iYiEpIDpcbiAgICAgICAgICAgICAgICAgICAgICBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKi9cbiAgICBzdGF0aWMgc3RhcnRWYWx1ZUluZm8oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgICAgYnVpbGRlci5zdGFydE9iamVjdCgzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCBuYW1lT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZE5hbWUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbmFtZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDAsIG5hbWVPZmZzZXQsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IGRvY1N0cmluZ09mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGREb2NTdHJpbmcoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZG9jU3RyaW5nT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMSwgZG9jU3RyaW5nT2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCB0eXBlT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZFR5cGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgdHlwZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDIsIHR5cGVPZmZzZXQsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcmV0dXJucyBmbGF0YnVmZmVycy5PZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgZW5kVmFsdWVJbmZvKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgICAgbGV0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgICByZXR1cm4gb2Zmc2V0O1xuICAgIH1cblxuICAgIHN0YXRpYyBjcmVhdGVWYWx1ZUluZm8oXG4gICAgICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG5hbWVPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCwgZG9jU3RyaW5nT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICAgICAgIHR5cGVPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBWYWx1ZUluZm8uc3RhcnRWYWx1ZUluZm8oYnVpbGRlcik7XG4gICAgICBWYWx1ZUluZm8uYWRkTmFtZShidWlsZGVyLCBuYW1lT2Zmc2V0KTtcbiAgICAgIFZhbHVlSW5mby5hZGREb2NTdHJpbmcoYnVpbGRlciwgZG9jU3RyaW5nT2Zmc2V0KTtcbiAgICAgIFZhbHVlSW5mby5hZGRUeXBlKGJ1aWxkZXIsIHR5cGVPZmZzZXQpO1xuICAgICAgcmV0dXJuIFZhbHVlSW5mby5lbmRWYWx1ZUluZm8oYnVpbGRlcik7XG4gICAgfVxuICB9XG59XG4vKipcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5leHBvcnQgbmFtZXNwYWNlIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMge1xuICBleHBvcnQgY2xhc3MgVHlwZUluZm8ge1xuICAgIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyfG51bGwgPSBudWxsO1xuXG4gICAgYmJfcG9zID0gMDtcbiAgICAvKipcbiAgICAgKiBAcGFyYW0gbnVtYmVyIGlcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciBiYlxuICAgICAqIEByZXR1cm5zIFR5cGVJbmZvXG4gICAgICovXG4gICAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBUeXBlSW5mbyB7XG4gICAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgICB0aGlzLmJiID0gYmI7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciBiYlxuICAgICAqIEBwYXJhbSBUeXBlSW5mbz0gb2JqXG4gICAgICogQHJldHVybnMgVHlwZUluZm9cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0Um9vdEFzVHlwZUluZm8oYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IFR5cGVJbmZvKTogVHlwZUluZm8ge1xuICAgICAgcmV0dXJuIChvYmogfHwgbmV3IFR5cGVJbmZvKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcGFyYW0gVHlwZUluZm89IG9ialxuICAgICAqIEByZXR1cm5zIFR5cGVJbmZvXG4gICAgICovXG4gICAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc1R5cGVJbmZvKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBUeXBlSW5mbyk6IFR5cGVJbmZvIHtcbiAgICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgICAgcmV0dXJuIChvYmogfHwgbmV3IFR5cGVJbmZvKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkVuY29kaW5nPSBvcHRpb25hbEVuY29kaW5nXG4gICAgICogQHJldHVybnMgc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbFxuICAgICAqL1xuICAgIGRlbm90YXRpb24oKTogc3RyaW5nfG51bGw7XG4gICAgZGVub3RhdGlvbihvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZ3xVaW50OEFycmF5fG51bGw7XG4gICAgZGVub3RhdGlvbihvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UeXBlSW5mb1ZhbHVlXG4gICAgICovXG4gICAgdmFsdWVUeXBlKCk6IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVHlwZUluZm9WYWx1ZSB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IC8qKiAgKi8gKHRoaXMuYmIhLnJlYWRVaW50OCh0aGlzLmJiX3BvcyArIG9mZnNldCkpIDpcbiAgICAgICAgICAgICAgICAgICAgICBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlR5cGVJbmZvVmFsdWUuTk9ORTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuVGFibGUgb2JqXG4gICAgICogQHJldHVybnMgP2ZsYXRidWZmZXJzLlRhYmxlXG4gICAgICovXG4gICAgdmFsdWU8VCBleHRlbmRzIGZsYXRidWZmZXJzLlRhYmxlPihvYmo6IFQpOiBUfG51bGwge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA4KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3VuaW9uKG9iaiwgdGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICovXG4gICAgc3RhdGljIHN0YXJ0VHlwZUluZm8oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgICAgYnVpbGRlci5zdGFydE9iamVjdCgzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCBkZW5vdGF0aW9uT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZERlbm90YXRpb24oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGVub3RhdGlvbk9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDAsIGRlbm90YXRpb25PZmZzZXQsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UeXBlSW5mb1ZhbHVlIHZhbHVlVHlwZVxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRWYWx1ZVR5cGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgdmFsdWVUeXBlOiBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlR5cGVJbmZvVmFsdWUpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRJbnQ4KDEsIHZhbHVlVHlwZSwgb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UeXBlSW5mb1ZhbHVlLk5PTkUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IHZhbHVlT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZFZhbHVlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIHZhbHVlT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMiwgdmFsdWVPZmZzZXQsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcmV0dXJucyBmbGF0YnVmZmVycy5PZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgZW5kVHlwZUluZm8oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICAgIHJldHVybiBvZmZzZXQ7XG4gICAgfVxuXG4gICAgc3RhdGljIGNyZWF0ZVR5cGVJbmZvKFxuICAgICAgICBidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkZW5vdGF0aW9uT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICAgICAgIHZhbHVlVHlwZTogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UeXBlSW5mb1ZhbHVlLCB2YWx1ZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICAgIFR5cGVJbmZvLnN0YXJ0VHlwZUluZm8oYnVpbGRlcik7XG4gICAgICBUeXBlSW5mby5hZGREZW5vdGF0aW9uKGJ1aWxkZXIsIGRlbm90YXRpb25PZmZzZXQpO1xuICAgICAgVHlwZUluZm8uYWRkVmFsdWVUeXBlKGJ1aWxkZXIsIHZhbHVlVHlwZSk7XG4gICAgICBUeXBlSW5mby5hZGRWYWx1ZShidWlsZGVyLCB2YWx1ZU9mZnNldCk7XG4gICAgICByZXR1cm4gVHlwZUluZm8uZW5kVHlwZUluZm8oYnVpbGRlcik7XG4gICAgfVxuICB9XG59XG4vKipcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5leHBvcnQgbmFtZXNwYWNlIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMge1xuICBleHBvcnQgY2xhc3MgT3BlcmF0b3JTZXRJZCB7XG4gICAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXJ8bnVsbCA9IG51bGw7XG5cbiAgICBiYl9wb3MgPSAwO1xuICAgIC8qKlxuICAgICAqIEBwYXJhbSBudW1iZXIgaVxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIGJiXG4gICAgICogQHJldHVybnMgT3BlcmF0b3JTZXRJZFxuICAgICAqL1xuICAgIF9faW5pdChpOiBudW1iZXIsIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKTogT3BlcmF0b3JTZXRJZCB7XG4gICAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgICB0aGlzLmJiID0gYmI7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciBiYlxuICAgICAqIEBwYXJhbSBPcGVyYXRvclNldElkPSBvYmpcbiAgICAgKiBAcmV0dXJucyBPcGVyYXRvclNldElkXG4gICAgICovXG4gICAgc3RhdGljIGdldFJvb3RBc09wZXJhdG9yU2V0SWQoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IE9wZXJhdG9yU2V0SWQpOiBPcGVyYXRvclNldElkIHtcbiAgICAgIHJldHVybiAob2JqIHx8IG5ldyBPcGVyYXRvclNldElkKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcGFyYW0gT3BlcmF0b3JTZXRJZD0gb2JqXG4gICAgICogQHJldHVybnMgT3BlcmF0b3JTZXRJZFxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRTaXplUHJlZml4ZWRSb290QXNPcGVyYXRvclNldElkKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBPcGVyYXRvclNldElkKTogT3BlcmF0b3JTZXRJZCB7XG4gICAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICAgIHJldHVybiAob2JqIHx8IG5ldyBPcGVyYXRvclNldElkKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkVuY29kaW5nPSBvcHRpb25hbEVuY29kaW5nXG4gICAgICogQHJldHVybnMgc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbFxuICAgICAqL1xuICAgIGRvbWFpbigpOiBzdHJpbmd8bnVsbDtcbiAgICBkb21haW4ob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmd8VWludDhBcnJheXxudWxsO1xuICAgIGRvbWFpbihvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuTG9uZ1xuICAgICAqL1xuICAgIHZlcnNpb24oKTogZmxhdGJ1ZmZlcnMuTG9uZyB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRJbnQ2NCh0aGlzLmJiX3BvcyArIG9mZnNldCkgOiB0aGlzLmJiIS5jcmVhdGVMb25nKDAsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKi9cbiAgICBzdGF0aWMgc3RhcnRPcGVyYXRvclNldElkKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpIHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoMik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5PZmZzZXQgZG9tYWluT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZERvbWFpbihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkb21haW5PZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgwLCBkb21haW5PZmZzZXQsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuTG9uZyB2ZXJzaW9uXG4gICAgICovXG4gICAgc3RhdGljIGFkZFZlcnNpb24oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgdmVyc2lvbjogZmxhdGJ1ZmZlcnMuTG9uZykge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZEludDY0KDEsIHZlcnNpb24sIGJ1aWxkZXIuY3JlYXRlTG9uZygwLCAwKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEByZXR1cm5zIGZsYXRidWZmZXJzLk9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBlbmRPcGVyYXRvclNldElkKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgICAgbGV0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgICByZXR1cm4gb2Zmc2V0O1xuICAgIH1cblxuICAgIHN0YXRpYyBjcmVhdGVPcGVyYXRvclNldElkKFxuICAgICAgICBidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkb21haW5PZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCwgdmVyc2lvbjogZmxhdGJ1ZmZlcnMuTG9uZyk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBPcGVyYXRvclNldElkLnN0YXJ0T3BlcmF0b3JTZXRJZChidWlsZGVyKTtcbiAgICAgIE9wZXJhdG9yU2V0SWQuYWRkRG9tYWluKGJ1aWxkZXIsIGRvbWFpbk9mZnNldCk7XG4gICAgICBPcGVyYXRvclNldElkLmFkZFZlcnNpb24oYnVpbGRlciwgdmVyc2lvbik7XG4gICAgICByZXR1cm4gT3BlcmF0b3JTZXRJZC5lbmRPcGVyYXRvclNldElkKGJ1aWxkZXIpO1xuICAgIH1cbiAgfVxufVxuLyoqXG4gKiBAY29uc3RydWN0b3JcbiAqL1xuZXhwb3J0IG5hbWVzcGFjZSBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzIHtcbiAgZXhwb3J0IGNsYXNzIFRlbnNvciB7XG4gICAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXJ8bnVsbCA9IG51bGw7XG5cbiAgICBiYl9wb3MgPSAwO1xuICAgIC8qKlxuICAgICAqIEBwYXJhbSBudW1iZXIgaVxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIGJiXG4gICAgICogQHJldHVybnMgVGVuc29yXG4gICAgICovXG4gICAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBUZW5zb3Ige1xuICAgICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgICAgdGhpcy5iYiA9IGJiO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcGFyYW0gVGVuc29yPSBvYmpcbiAgICAgKiBAcmV0dXJucyBUZW5zb3JcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0Um9vdEFzVGVuc29yKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBUZW5zb3IpOiBUZW5zb3Ige1xuICAgICAgcmV0dXJuIChvYmogfHwgbmV3IFRlbnNvcigpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIGJiXG4gICAgICogQHBhcmFtIFRlbnNvcj0gb2JqXG4gICAgICogQHJldHVybnMgVGVuc29yXG4gICAgICovXG4gICAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc1RlbnNvcihiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogVGVuc29yKTogVGVuc29yIHtcbiAgICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgICAgcmV0dXJuIChvYmogfHwgbmV3IFRlbnNvcigpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5FbmNvZGluZz0gb3B0aW9uYWxFbmNvZGluZ1xuICAgICAqIEByZXR1cm5zIHN0cmluZ3xVaW50OEFycmF5fG51bGxcbiAgICAgKi9cbiAgICBuYW1lKCk6IHN0cmluZ3xudWxsO1xuICAgIG5hbWUob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmd8VWludDhBcnJheXxudWxsO1xuICAgIG5hbWUob3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZ3xVaW50OEFycmF5fG51bGwge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiX3BvcyArIG9mZnNldCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5FbmNvZGluZz0gb3B0aW9uYWxFbmNvZGluZ1xuICAgICAqIEByZXR1cm5zIHN0cmluZ3xVaW50OEFycmF5fG51bGxcbiAgICAgKi9cbiAgICBkb2NTdHJpbmcoKTogc3RyaW5nfG51bGw7XG4gICAgZG9jU3RyaW5nKG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbDtcbiAgICBkb2NTdHJpbmcob3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZ3xVaW50OEFycmF5fG51bGwge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA2KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiX3BvcyArIG9mZnNldCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBudW1iZXIgaW5kZXhcbiAgICAgKiBAcmV0dXJucyBmbGF0YnVmZmVycy5Mb25nXG4gICAgICovXG4gICAgZGltcyhpbmRleDogbnVtYmVyKTogZmxhdGJ1ZmZlcnMuTG9uZ3xudWxsIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgOCk7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEucmVhZEludDY0KHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogOCkgOlxuICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYmIhLmNyZWF0ZUxvbmcoMCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgbnVtYmVyXG4gICAgICovXG4gICAgZGltc0xlbmd0aCgpOiBudW1iZXIge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA4KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlRlbnNvckRhdGFUeXBlXG4gICAgICovXG4gICAgZGF0YVR5cGUoKTogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UZW5zb3JEYXRhVHlwZSB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDEwKTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyAvKiogICovICh0aGlzLmJiIS5yZWFkSW50MzIodGhpcy5iYl9wb3MgKyBvZmZzZXQpKSA6XG4gICAgICAgICAgICAgICAgICAgICAgb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UZW5zb3JEYXRhVHlwZS5VTkRFRklORUQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIG51bWJlciBpbmRleFxuICAgICAqIEByZXR1cm5zIG51bWJlclxuICAgICAqL1xuICAgIHJhd0RhdGEoaW5kZXg6IG51bWJlcik6IG51bWJlcnxudWxsIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTIpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRVaW50OCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCkgOiAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIG51bWJlclxuICAgICAqL1xuICAgIHJhd0RhdGFMZW5ndGgoKTogbnVtYmVyIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTIpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIFVpbnQ4QXJyYXlcbiAgICAgKi9cbiAgICByYXdEYXRhQXJyYXkoKTogVWludDhBcnJheXxudWxsIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTIpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/XG4gICAgICAgICAgbmV3IFVpbnQ4QXJyYXkoXG4gICAgICAgICAgICAgIHRoaXMuYmIhLmJ5dGVzKCkuYnVmZmVyLCB0aGlzLmJiIS5ieXRlcygpLmJ5dGVPZmZzZXQgKyB0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCksXG4gICAgICAgICAgICAgIHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkpIDpcbiAgICAgICAgICBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBudW1iZXIgaW5kZXhcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuRW5jb2Rpbmc9IG9wdGlvbmFsRW5jb2RpbmdcbiAgICAgKiBAcmV0dXJucyBzdHJpbmd8VWludDhBcnJheVxuICAgICAqL1xuICAgIHN0cmluZ0RhdGEoaW5kZXg6IG51bWJlcik6IHN0cmluZztcbiAgICBzdHJpbmdEYXRhKGluZGV4OiBudW1iZXIsIG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nfFVpbnQ4QXJyYXk7XG4gICAgc3RyaW5nRGF0YShpbmRleDogbnVtYmVyLCBvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDE0KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBudW1iZXJcbiAgICAgKi9cbiAgICBzdHJpbmdEYXRhTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDE0KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICovXG4gICAgc3RhdGljIHN0YXJ0VGVuc29yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpIHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoNik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5PZmZzZXQgbmFtZU9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGROYW1lKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG5hbWVPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgwLCBuYW1lT2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCBkb2NTdHJpbmdPZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkRG9jU3RyaW5nKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRvY1N0cmluZ09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDEsIGRvY1N0cmluZ09mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5PZmZzZXQgZGltc09mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGREaW1zKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRpbXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgyLCBkaW1zT2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIEFycmF5LjxmbGF0YnVmZmVycy5Mb25nPiBkYXRhXG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGNyZWF0ZURpbXNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogZmxhdGJ1ZmZlcnMuTG9uZ1tdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoOCwgZGF0YS5sZW5ndGgsIDgpO1xuICAgICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgYnVpbGRlci5hZGRJbnQ2NChkYXRhW2ldKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gbnVtYmVyIG51bUVsZW1zXG4gICAgICovXG4gICAgc3RhdGljIHN0YXJ0RGltc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDgsIG51bUVsZW1zLCA4KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVGVuc29yRGF0YVR5cGUgZGF0YVR5cGVcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkRGF0YVR5cGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YVR5cGU6IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVGVuc29yRGF0YVR5cGUpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRJbnQzMigzLCBkYXRhVHlwZSwgb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UZW5zb3JEYXRhVHlwZS5VTkRFRklORUQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IHJhd0RhdGFPZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkUmF3RGF0YShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCByYXdEYXRhT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoNCwgcmF3RGF0YU9mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBBcnJheS48bnVtYmVyPiBkYXRhXG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGNyZWF0ZVJhd0RhdGFWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogbnVtYmVyW118VWludDhBcnJheSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDEsIGRhdGEubGVuZ3RoLCAxKTtcbiAgICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIGJ1aWxkZXIuYWRkSW50OChkYXRhW2ldKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gbnVtYmVyIG51bUVsZW1zXG4gICAgICovXG4gICAgc3RhdGljIHN0YXJ0UmF3RGF0YVZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDEsIG51bUVsZW1zLCAxKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCBzdHJpbmdEYXRhT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZFN0cmluZ0RhdGEoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgc3RyaW5nRGF0YU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDUsIHN0cmluZ0RhdGFPZmZzZXQsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gQXJyYXkuPGZsYXRidWZmZXJzLk9mZnNldD4gZGF0YVxuICAgICAqIEByZXR1cm5zIGZsYXRidWZmZXJzLk9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBjcmVhdGVTdHJpbmdEYXRhVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLk9mZnNldFtdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgZGF0YS5sZW5ndGgsIDQpO1xuICAgICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgYnVpbGRlci5hZGRPZmZzZXQoZGF0YVtpXSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIG51bWJlciBudW1FbGVtc1xuICAgICAqL1xuICAgIHN0YXRpYyBzdGFydFN0cmluZ0RhdGFWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBudW1FbGVtcywgNCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEByZXR1cm5zIGZsYXRidWZmZXJzLk9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBlbmRUZW5zb3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICAgIHJldHVybiBvZmZzZXQ7XG4gICAgfVxuXG4gICAgc3RhdGljIGNyZWF0ZVRlbnNvcihcbiAgICAgICAgYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbmFtZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LCBkb2NTdHJpbmdPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgICAgICAgZGltc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LCBkYXRhVHlwZTogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UZW5zb3JEYXRhVHlwZSxcbiAgICAgICAgcmF3RGF0YU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LCBzdHJpbmdEYXRhT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgICAgVGVuc29yLnN0YXJ0VGVuc29yKGJ1aWxkZXIpO1xuICAgICAgVGVuc29yLmFkZE5hbWUoYnVpbGRlciwgbmFtZU9mZnNldCk7XG4gICAgICBUZW5zb3IuYWRkRG9jU3RyaW5nKGJ1aWxkZXIsIGRvY1N0cmluZ09mZnNldCk7XG4gICAgICBUZW5zb3IuYWRkRGltcyhidWlsZGVyLCBkaW1zT2Zmc2V0KTtcbiAgICAgIFRlbnNvci5hZGREYXRhVHlwZShidWlsZGVyLCBkYXRhVHlwZSk7XG4gICAgICBUZW5zb3IuYWRkUmF3RGF0YShidWlsZGVyLCByYXdEYXRhT2Zmc2V0KTtcbiAgICAgIFRlbnNvci5hZGRTdHJpbmdEYXRhKGJ1aWxkZXIsIHN0cmluZ0RhdGFPZmZzZXQpO1xuICAgICAgcmV0dXJuIFRlbnNvci5lbmRUZW5zb3IoYnVpbGRlcik7XG4gICAgfVxuICB9XG59XG4vKipcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5leHBvcnQgbmFtZXNwYWNlIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMge1xuICBleHBvcnQgY2xhc3MgU3BhcnNlVGVuc29yIHtcbiAgICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcnxudWxsID0gbnVsbDtcblxuICAgIGJiX3BvcyA9IDA7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIG51bWJlciBpXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcmV0dXJucyBTcGFyc2VUZW5zb3JcbiAgICAgKi9cbiAgICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IFNwYXJzZVRlbnNvciB7XG4gICAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgICB0aGlzLmJiID0gYmI7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciBiYlxuICAgICAqIEBwYXJhbSBTcGFyc2VUZW5zb3I9IG9ialxuICAgICAqIEByZXR1cm5zIFNwYXJzZVRlbnNvclxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRSb290QXNTcGFyc2VUZW5zb3IoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IFNwYXJzZVRlbnNvcik6IFNwYXJzZVRlbnNvciB7XG4gICAgICByZXR1cm4gKG9iaiB8fCBuZXcgU3BhcnNlVGVuc29yKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcGFyYW0gU3BhcnNlVGVuc29yPSBvYmpcbiAgICAgKiBAcmV0dXJucyBTcGFyc2VUZW5zb3JcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0U2l6ZVByZWZpeGVkUm9vdEFzU3BhcnNlVGVuc29yKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBTcGFyc2VUZW5zb3IpOiBTcGFyc2VUZW5zb3Ige1xuICAgICAgYmIuc2V0UG9zaXRpb24oYmIucG9zaXRpb24oKSArIGZsYXRidWZmZXJzLlNJWkVfUFJFRklYX0xFTkdUSCk7XG4gICAgICByZXR1cm4gKG9iaiB8fCBuZXcgU3BhcnNlVGVuc29yKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVGVuc29yPSBvYmpcbiAgICAgKiBAcmV0dXJucyBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlRlbnNvcnxudWxsXG4gICAgICovXG4gICAgdmFsdWVzKG9iaj86IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVGVuc29yKTogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UZW5zb3J8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IChvYmogfHwgbmV3IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVGVuc29yKCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiX3BvcyArIG9mZnNldCksIHRoaXMuYmIhKSA6XG4gICAgICAgICAgICAgICAgICAgICAgbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UZW5zb3I9IG9ialxuICAgICAqIEByZXR1cm5zIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVGVuc29yfG51bGxcbiAgICAgKi9cbiAgICBpbmRpY2VzKG9iaj86IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVGVuc29yKTogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UZW5zb3J8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IChvYmogfHwgbmV3IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVGVuc29yKCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiX3BvcyArIG9mZnNldCksIHRoaXMuYmIhKSA6XG4gICAgICAgICAgICAgICAgICAgICAgbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gbnVtYmVyIGluZGV4XG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuTG9uZ1xuICAgICAqL1xuICAgIGRpbXMoaW5kZXg6IG51bWJlcik6IGZsYXRidWZmZXJzLkxvbmd8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDgpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRJbnQ2NCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDgpIDpcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLmJiIS5jcmVhdGVMb25nKDAsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIG51bWJlclxuICAgICAqL1xuICAgIGRpbXNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgOCk7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqL1xuICAgIHN0YXRpYyBzdGFydFNwYXJzZVRlbnNvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgICBidWlsZGVyLnN0YXJ0T2JqZWN0KDMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IHZhbHVlc09mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRWYWx1ZXMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgdmFsdWVzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMCwgdmFsdWVzT2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCBpbmRpY2VzT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZEluZGljZXMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgaW5kaWNlc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDEsIGluZGljZXNPZmZzZXQsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IGRpbXNPZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkRGltcyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkaW1zT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMiwgZGltc09mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBBcnJheS48ZmxhdGJ1ZmZlcnMuTG9uZz4gZGF0YVxuICAgICAqIEByZXR1cm5zIGZsYXRidWZmZXJzLk9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBjcmVhdGVEaW1zVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLkxvbmdbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDgsIGRhdGEubGVuZ3RoLCA4KTtcbiAgICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIGJ1aWxkZXIuYWRkSW50NjQoZGF0YVtpXSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIG51bWJlciBudW1FbGVtc1xuICAgICAqL1xuICAgIHN0YXRpYyBzdGFydERpbXNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgICAgYnVpbGRlci5zdGFydFZlY3Rvcig4LCBudW1FbGVtcywgOCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEByZXR1cm5zIGZsYXRidWZmZXJzLk9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBlbmRTcGFyc2VUZW5zb3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICAgIHJldHVybiBvZmZzZXQ7XG4gICAgfVxuXG4gICAgc3RhdGljIGNyZWF0ZVNwYXJzZVRlbnNvcihcbiAgICAgICAgYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgdmFsdWVzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsIGluZGljZXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgICAgICAgZGltc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICAgIFNwYXJzZVRlbnNvci5zdGFydFNwYXJzZVRlbnNvcihidWlsZGVyKTtcbiAgICAgIFNwYXJzZVRlbnNvci5hZGRWYWx1ZXMoYnVpbGRlciwgdmFsdWVzT2Zmc2V0KTtcbiAgICAgIFNwYXJzZVRlbnNvci5hZGRJbmRpY2VzKGJ1aWxkZXIsIGluZGljZXNPZmZzZXQpO1xuICAgICAgU3BhcnNlVGVuc29yLmFkZERpbXMoYnVpbGRlciwgZGltc09mZnNldCk7XG4gICAgICByZXR1cm4gU3BhcnNlVGVuc29yLmVuZFNwYXJzZVRlbnNvcihidWlsZGVyKTtcbiAgICB9XG4gIH1cbn1cbi8qKlxuICogQGNvbnN0cnVjdG9yXG4gKi9cbmV4cG9ydCBuYW1lc3BhY2Ugb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicyB7XG4gIGV4cG9ydCBjbGFzcyBBdHRyaWJ1dGUge1xuICAgIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyfG51bGwgPSBudWxsO1xuXG4gICAgYmJfcG9zID0gMDtcbiAgICAvKipcbiAgICAgKiBAcGFyYW0gbnVtYmVyIGlcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciBiYlxuICAgICAqIEByZXR1cm5zIEF0dHJpYnV0ZVxuICAgICAqL1xuICAgIF9faW5pdChpOiBudW1iZXIsIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKTogQXR0cmlidXRlIHtcbiAgICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICAgIHRoaXMuYmIgPSBiYjtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIGJiXG4gICAgICogQHBhcmFtIEF0dHJpYnV0ZT0gb2JqXG4gICAgICogQHJldHVybnMgQXR0cmlidXRlXG4gICAgICovXG4gICAgc3RhdGljIGdldFJvb3RBc0F0dHJpYnV0ZShiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogQXR0cmlidXRlKTogQXR0cmlidXRlIHtcbiAgICAgIHJldHVybiAob2JqIHx8IG5ldyBBdHRyaWJ1dGUoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciBiYlxuICAgICAqIEBwYXJhbSBBdHRyaWJ1dGU9IG9ialxuICAgICAqIEByZXR1cm5zIEF0dHJpYnV0ZVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRTaXplUHJlZml4ZWRSb290QXNBdHRyaWJ1dGUoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IEF0dHJpYnV0ZSk6IEF0dHJpYnV0ZSB7XG4gICAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICAgIHJldHVybiAob2JqIHx8IG5ldyBBdHRyaWJ1dGUoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuRW5jb2Rpbmc9IG9wdGlvbmFsRW5jb2RpbmdcbiAgICAgKiBAcmV0dXJucyBzdHJpbmd8VWludDhBcnJheXxudWxsXG4gICAgICovXG4gICAgbmFtZSgpOiBzdHJpbmd8bnVsbDtcbiAgICBuYW1lKG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbDtcbiAgICBuYW1lKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmd8VWludDhBcnJheXxudWxsIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuRW5jb2Rpbmc9IG9wdGlvbmFsRW5jb2RpbmdcbiAgICAgKiBAcmV0dXJucyBzdHJpbmd8VWludDhBcnJheXxudWxsXG4gICAgICovXG4gICAgZG9jU3RyaW5nKCk6IHN0cmluZ3xudWxsO1xuICAgIGRvY1N0cmluZyhvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZ3xVaW50OEFycmF5fG51bGw7XG4gICAgZG9jU3RyaW5nKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmd8VWludDhBcnJheXxudWxsIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLkF0dHJpYnV0ZVR5cGVcbiAgICAgKi9cbiAgICB0eXBlKCk6IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuQXR0cmlidXRlVHlwZSB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDgpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IC8qKiAgKi8gKHRoaXMuYmIhLnJlYWRJbnQzMih0aGlzLmJiX3BvcyArIG9mZnNldCkpIDpcbiAgICAgICAgICAgICAgICAgICAgICBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLkF0dHJpYnV0ZVR5cGUuVU5ERUZJTkVEO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIG51bWJlclxuICAgICAqL1xuICAgIGYoKTogbnVtYmVyIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTApO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRGbG9hdDMyKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDAuMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBmbGF0YnVmZmVycy5Mb25nXG4gICAgICovXG4gICAgaSgpOiBmbGF0YnVmZmVycy5Mb25nIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTIpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRJbnQ2NCh0aGlzLmJiX3BvcyArIG9mZnNldCkgOiB0aGlzLmJiIS5jcmVhdGVMb25nKDAsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5FbmNvZGluZz0gb3B0aW9uYWxFbmNvZGluZ1xuICAgICAqIEByZXR1cm5zIHN0cmluZ3xVaW50OEFycmF5fG51bGxcbiAgICAgKi9cbiAgICBzKCk6IHN0cmluZ3xudWxsO1xuICAgIHMob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmd8VWludDhBcnJheXxudWxsO1xuICAgIHMob3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZ3xVaW50OEFycmF5fG51bGwge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAxNCk7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UZW5zb3I9IG9ialxuICAgICAqIEByZXR1cm5zIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVGVuc29yfG51bGxcbiAgICAgKi9cbiAgICB0KG9iaj86IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVGVuc29yKTogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UZW5zb3J8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDE2KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyAob2JqIHx8IG5ldyBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlRlbnNvcigpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAuX19pbml0KHRoaXMuYmIhLl9faW5kaXJlY3QodGhpcy5iYl9wb3MgKyBvZmZzZXQpLCB0aGlzLmJiISkgOlxuICAgICAgICAgICAgICAgICAgICAgIG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuR3JhcGg9IG9ialxuICAgICAqIEByZXR1cm5zIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuR3JhcGh8bnVsbFxuICAgICAqL1xuICAgIGcob2JqPzogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5HcmFwaCk6IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuR3JhcGh8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDE4KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyAob2JqIHx8IG5ldyBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLkdyYXBoKCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiX3BvcyArIG9mZnNldCksIHRoaXMuYmIhKSA6XG4gICAgICAgICAgICAgICAgICAgICAgbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gbnVtYmVyIGluZGV4XG4gICAgICogQHJldHVybnMgbnVtYmVyXG4gICAgICovXG4gICAgZmxvYXRzKGluZGV4OiBudW1iZXIpOiBudW1iZXJ8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDIwKTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkRmxvYXQzMih0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQpIDogMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBudW1iZXJcbiAgICAgKi9cbiAgICBmbG9hdHNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjApO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIEZsb2F0MzJBcnJheVxuICAgICAqL1xuICAgIGZsb2F0c0FycmF5KCk6IEZsb2F0MzJBcnJheXxudWxsIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjApO1xuICAgICAgcmV0dXJuIG9mZnNldCA/XG4gICAgICAgICAgbmV3IEZsb2F0MzJBcnJheShcbiAgICAgICAgICAgICAgdGhpcy5iYiEuYnl0ZXMoKS5idWZmZXIsIHRoaXMuYmIhLmJ5dGVzKCkuYnl0ZU9mZnNldCArIHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSxcbiAgICAgICAgICAgICAgdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSkgOlxuICAgICAgICAgIG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIG51bWJlciBpbmRleFxuICAgICAqIEByZXR1cm5zIGZsYXRidWZmZXJzLkxvbmdcbiAgICAgKi9cbiAgICBpbnRzKGluZGV4OiBudW1iZXIpOiBmbGF0YnVmZmVycy5Mb25nfG51bGwge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyMik7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEucmVhZEludDY0KHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogOCkgOlxuICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYmIhLmNyZWF0ZUxvbmcoMCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgbnVtYmVyXG4gICAgICovXG4gICAgaW50c0xlbmd0aCgpOiBudW1iZXIge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyMik7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIG51bWJlciBpbmRleFxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5FbmNvZGluZz0gb3B0aW9uYWxFbmNvZGluZ1xuICAgICAqIEByZXR1cm5zIHN0cmluZ3xVaW50OEFycmF5XG4gICAgICovXG4gICAgc3RyaW5ncyhpbmRleDogbnVtYmVyKTogc3RyaW5nO1xuICAgIHN0cmluZ3MoaW5kZXg6IG51bWJlciwgb3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmd8VWludDhBcnJheTtcbiAgICBzdHJpbmdzKGluZGV4OiBudW1iZXIsIG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmd8VWludDhBcnJheXxudWxsIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjQpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIG51bWJlclxuICAgICAqL1xuICAgIHN0cmluZ3NMZW5ndGgoKTogbnVtYmVyIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMjQpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBudW1iZXIgaW5kZXhcbiAgICAgKiBAcGFyYW0gb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UZW5zb3I9IG9ialxuICAgICAqIEByZXR1cm5zIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVGVuc29yXG4gICAgICovXG4gICAgdGVuc29ycyhpbmRleDogbnVtYmVyLCBvYmo/OiBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlRlbnNvcik6IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVGVuc29yfG51bGwge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAyNik7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gKG9iaiB8fCBuZXcgb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UZW5zb3IoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLl9faW5pdCh0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCksIHRoaXMuYmIhKSA6XG4gICAgICAgICAgICAgICAgICAgICAgbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBudW1iZXJcbiAgICAgKi9cbiAgICB0ZW5zb3JzTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDI2KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gbnVtYmVyIGluZGV4XG4gICAgICogQHBhcmFtIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuR3JhcGg9IG9ialxuICAgICAqIEByZXR1cm5zIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuR3JhcGhcbiAgICAgKi9cbiAgICBncmFwaHMoaW5kZXg6IG51bWJlciwgb2JqPzogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5HcmFwaCk6IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuR3JhcGh8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDI4KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyAob2JqIHx8IG5ldyBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLkdyYXBoKCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQpLCB0aGlzLmJiISkgOlxuICAgICAgICAgICAgICAgICAgICAgIG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgbnVtYmVyXG4gICAgICovXG4gICAgZ3JhcGhzTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDI4KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICovXG4gICAgc3RhdGljIHN0YXJ0QXR0cmlidXRlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpIHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoMTMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IG5hbWVPZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkTmFtZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBuYW1lT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMCwgbmFtZU9mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5PZmZzZXQgZG9jU3RyaW5nT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZERvY1N0cmluZyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkb2NTdHJpbmdPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxLCBkb2NTdHJpbmdPZmZzZXQsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5BdHRyaWJ1dGVUeXBlIHR5cGVcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkVHlwZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCB0eXBlOiBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLkF0dHJpYnV0ZVR5cGUpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRJbnQzMigyLCB0eXBlLCBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLkF0dHJpYnV0ZVR5cGUuVU5ERUZJTkVEKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIG51bWJlciBmXG4gICAgICovXG4gICAgc3RhdGljIGFkZEYoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZjogbnVtYmVyKSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkRmxvYXQzMigzLCBmLCAwLjApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuTG9uZyBpXG4gICAgICovXG4gICAgc3RhdGljIGFkZEkoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgaTogZmxhdGJ1ZmZlcnMuTG9uZykge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZEludDY0KDQsIGksIGJ1aWxkZXIuY3JlYXRlTG9uZygwLCAwKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5PZmZzZXQgc09mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRTKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIHNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCg1LCBzT2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCB0T2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZFQoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgdE9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDYsIHRPZmZzZXQsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IGdPZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkRyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBnT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoNywgZ09mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5PZmZzZXQgZmxvYXRzT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZEZsb2F0cyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBmbG9hdHNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCg4LCBmbG9hdHNPZmZzZXQsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gQXJyYXkuPG51bWJlcj4gZGF0YVxuICAgICAqIEByZXR1cm5zIGZsYXRidWZmZXJzLk9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBjcmVhdGVGbG9hdHNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogbnVtYmVyW118VWludDhBcnJheSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIGJ1aWxkZXIuYWRkRmxvYXQzMihkYXRhW2ldKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gbnVtYmVyIG51bUVsZW1zXG4gICAgICovXG4gICAgc3RhdGljIHN0YXJ0RmxvYXRzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IGludHNPZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkSW50cyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBpbnRzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoOSwgaW50c09mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBBcnJheS48ZmxhdGJ1ZmZlcnMuTG9uZz4gZGF0YVxuICAgICAqIEByZXR1cm5zIGZsYXRidWZmZXJzLk9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBjcmVhdGVJbnRzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLkxvbmdbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDgsIGRhdGEubGVuZ3RoLCA4KTtcbiAgICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIGJ1aWxkZXIuYWRkSW50NjQoZGF0YVtpXSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIG51bWJlciBudW1FbGVtc1xuICAgICAqL1xuICAgIHN0YXRpYyBzdGFydEludHNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgICAgYnVpbGRlci5zdGFydFZlY3Rvcig4LCBudW1FbGVtcywgOCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5PZmZzZXQgc3RyaW5nc09mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRTdHJpbmdzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIHN0cmluZ3NPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxMCwgc3RyaW5nc09mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBBcnJheS48ZmxhdGJ1ZmZlcnMuT2Zmc2V0PiBkYXRhXG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGNyZWF0ZVN0cmluZ3NWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogZmxhdGJ1ZmZlcnMuT2Zmc2V0W10pOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICBidWlsZGVyLmFkZE9mZnNldChkYXRhW2ldKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gbnVtYmVyIG51bUVsZW1zXG4gICAgICovXG4gICAgc3RhdGljIHN0YXJ0U3RyaW5nc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCB0ZW5zb3JzT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZFRlbnNvcnMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgdGVuc29yc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDExLCB0ZW5zb3JzT2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIEFycmF5LjxmbGF0YnVmZmVycy5PZmZzZXQ+IGRhdGFcbiAgICAgKiBAcmV0dXJucyBmbGF0YnVmZmVycy5PZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgY3JlYXRlVGVuc29yc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBmbGF0YnVmZmVycy5PZmZzZXRbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIGJ1aWxkZXIuYWRkT2Zmc2V0KGRhdGFbaV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBudW1iZXIgbnVtRWxlbXNcbiAgICAgKi9cbiAgICBzdGF0aWMgc3RhcnRUZW5zb3JzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IGdyYXBoc09mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRHcmFwaHMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZ3JhcGhzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMTIsIGdyYXBoc09mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBBcnJheS48ZmxhdGJ1ZmZlcnMuT2Zmc2V0PiBkYXRhXG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGNyZWF0ZUdyYXBoc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBmbGF0YnVmZmVycy5PZmZzZXRbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIGJ1aWxkZXIuYWRkT2Zmc2V0KGRhdGFbaV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBudW1iZXIgbnVtRWxlbXNcbiAgICAgKi9cbiAgICBzdGF0aWMgc3RhcnRHcmFwaHNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBudW1FbGVtcywgNCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEByZXR1cm5zIGZsYXRidWZmZXJzLk9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBlbmRBdHRyaWJ1dGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICAgIHJldHVybiBvZmZzZXQ7XG4gICAgfVxuXG4gICAgc3RhdGljIGNyZWF0ZUF0dHJpYnV0ZShcbiAgICAgICAgYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbmFtZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LCBkb2NTdHJpbmdPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgICAgICAgdHlwZTogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5BdHRyaWJ1dGVUeXBlLCBmOiBudW1iZXIsIGk6IGZsYXRidWZmZXJzLkxvbmcsIHNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgICAgICAgdE9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LCBnT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsIGZsb2F0c09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgICAgICBpbnRzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsIHN0cmluZ3NPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCwgdGVuc29yc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgICAgICBncmFwaHNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBBdHRyaWJ1dGUuc3RhcnRBdHRyaWJ1dGUoYnVpbGRlcik7XG4gICAgICBBdHRyaWJ1dGUuYWRkTmFtZShidWlsZGVyLCBuYW1lT2Zmc2V0KTtcbiAgICAgIEF0dHJpYnV0ZS5hZGREb2NTdHJpbmcoYnVpbGRlciwgZG9jU3RyaW5nT2Zmc2V0KTtcbiAgICAgIEF0dHJpYnV0ZS5hZGRUeXBlKGJ1aWxkZXIsIHR5cGUpO1xuICAgICAgQXR0cmlidXRlLmFkZEYoYnVpbGRlciwgZik7XG4gICAgICBBdHRyaWJ1dGUuYWRkSShidWlsZGVyLCBpKTtcbiAgICAgIEF0dHJpYnV0ZS5hZGRTKGJ1aWxkZXIsIHNPZmZzZXQpO1xuICAgICAgQXR0cmlidXRlLmFkZFQoYnVpbGRlciwgdE9mZnNldCk7XG4gICAgICBBdHRyaWJ1dGUuYWRkRyhidWlsZGVyLCBnT2Zmc2V0KTtcbiAgICAgIEF0dHJpYnV0ZS5hZGRGbG9hdHMoYnVpbGRlciwgZmxvYXRzT2Zmc2V0KTtcbiAgICAgIEF0dHJpYnV0ZS5hZGRJbnRzKGJ1aWxkZXIsIGludHNPZmZzZXQpO1xuICAgICAgQXR0cmlidXRlLmFkZFN0cmluZ3MoYnVpbGRlciwgc3RyaW5nc09mZnNldCk7XG4gICAgICBBdHRyaWJ1dGUuYWRkVGVuc29ycyhidWlsZGVyLCB0ZW5zb3JzT2Zmc2V0KTtcbiAgICAgIEF0dHJpYnV0ZS5hZGRHcmFwaHMoYnVpbGRlciwgZ3JhcGhzT2Zmc2V0KTtcbiAgICAgIHJldHVybiBBdHRyaWJ1dGUuZW5kQXR0cmlidXRlKGJ1aWxkZXIpO1xuICAgIH1cbiAgfVxufVxuLyoqXG4gKiBAY29uc3RydWN0b3JcbiAqL1xuZXhwb3J0IG5hbWVzcGFjZSBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzIHtcbiAgZXhwb3J0IGNsYXNzIEdyYXBoIHtcbiAgICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcnxudWxsID0gbnVsbDtcblxuICAgIGJiX3BvcyA9IDA7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIG51bWJlciBpXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcmV0dXJucyBHcmFwaFxuICAgICAqL1xuICAgIF9faW5pdChpOiBudW1iZXIsIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKTogR3JhcGgge1xuICAgICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgICAgdGhpcy5iYiA9IGJiO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcGFyYW0gR3JhcGg9IG9ialxuICAgICAqIEByZXR1cm5zIEdyYXBoXG4gICAgICovXG4gICAgc3RhdGljIGdldFJvb3RBc0dyYXBoKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBHcmFwaCk6IEdyYXBoIHtcbiAgICAgIHJldHVybiAob2JqIHx8IG5ldyBHcmFwaCgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIGJiXG4gICAgICogQHBhcmFtIEdyYXBoPSBvYmpcbiAgICAgKiBAcmV0dXJucyBHcmFwaFxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRTaXplUHJlZml4ZWRSb290QXNHcmFwaChiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogR3JhcGgpOiBHcmFwaCB7XG4gICAgICBiYi5zZXRQb3NpdGlvbihiYi5wb3NpdGlvbigpICsgZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIKTtcbiAgICAgIHJldHVybiAob2JqIHx8IG5ldyBHcmFwaCgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBudW1iZXIgaW5kZXhcbiAgICAgKiBAcGFyYW0gb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UZW5zb3I9IG9ialxuICAgICAqIEByZXR1cm5zIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVGVuc29yXG4gICAgICovXG4gICAgaW5pdGlhbGl6ZXJzKGluZGV4OiBudW1iZXIsIG9iaj86IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVGVuc29yKTogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UZW5zb3J8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IChvYmogfHwgbmV3IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVGVuc29yKCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQpLCB0aGlzLmJiISkgOlxuICAgICAgICAgICAgICAgICAgICAgIG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgbnVtYmVyXG4gICAgICovXG4gICAgaW5pdGlhbGl6ZXJzTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fdmVjdG9yX2xlbih0aGlzLmJiX3BvcyArIG9mZnNldCkgOiAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBudW1iZXIgaW5kZXhcbiAgICAgKiBAcGFyYW0gb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5WYWx1ZUluZm89IG9ialxuICAgICAqIEByZXR1cm5zIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuVmFsdWVJbmZvXG4gICAgICovXG4gICAgbm9kZUFyZ3MoaW5kZXg6IG51bWJlciwgb2JqPzogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5WYWx1ZUluZm8pOiBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlZhbHVlSW5mb3xudWxsIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gKG9iaiB8fCBuZXcgb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5WYWx1ZUluZm8oKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLl9faW5pdCh0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCksIHRoaXMuYmIhKSA6XG4gICAgICAgICAgICAgICAgICAgICAgbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBudW1iZXJcbiAgICAgKi9cbiAgICBub2RlQXJnc0xlbmd0aCgpOiBudW1iZXIge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA2KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gbnVtYmVyIGluZGV4XG4gICAgICogQHBhcmFtIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuTm9kZT0gb2JqXG4gICAgICogQHJldHVybnMgb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5Ob2RlXG4gICAgICovXG4gICAgbm9kZXMoaW5kZXg6IG51bWJlciwgb2JqPzogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5Ob2RlKTogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5Ob2RlfG51bGwge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA4KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyAob2JqIHx8IG5ldyBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLk5vZGUoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLl9faW5pdCh0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCksIHRoaXMuYmIhKSA6XG4gICAgICAgICAgICAgICAgICAgICAgbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBudW1iZXJcbiAgICAgKi9cbiAgICBub2Rlc0xlbmd0aCgpOiBudW1iZXIge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA4KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBudW1iZXJcbiAgICAgKi9cbiAgICBtYXhOb2RlSW5kZXgoKTogbnVtYmVyIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTApO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRVaW50MzIodGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gbnVtYmVyIGluZGV4XG4gICAgICogQHBhcmFtIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuTm9kZUVkZ2U9IG9ialxuICAgICAqIEByZXR1cm5zIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuTm9kZUVkZ2VcbiAgICAgKi9cbiAgICBub2RlRWRnZXMoaW5kZXg6IG51bWJlciwgb2JqPzogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5Ob2RlRWRnZSk6IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuTm9kZUVkZ2V8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDEyKTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyAob2JqIHx8IG5ldyBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLk5vZGVFZGdlKCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQpLCB0aGlzLmJiISkgOlxuICAgICAgICAgICAgICAgICAgICAgIG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgbnVtYmVyXG4gICAgICovXG4gICAgbm9kZUVkZ2VzTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDEyKTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gbnVtYmVyIGluZGV4XG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkVuY29kaW5nPSBvcHRpb25hbEVuY29kaW5nXG4gICAgICogQHJldHVybnMgc3RyaW5nfFVpbnQ4QXJyYXlcbiAgICAgKi9cbiAgICBpbnB1dHMoaW5kZXg6IG51bWJlcik6IHN0cmluZztcbiAgICBpbnB1dHMoaW5kZXg6IG51bWJlciwgb3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmd8VWludDhBcnJheTtcbiAgICBpbnB1dHMoaW5kZXg6IG51bWJlciwgb3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZ3xVaW50OEFycmF5fG51bGwge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAxNCk7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgbnVtYmVyXG4gICAgICovXG4gICAgaW5wdXRzTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDE0KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gbnVtYmVyIGluZGV4XG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkVuY29kaW5nPSBvcHRpb25hbEVuY29kaW5nXG4gICAgICogQHJldHVybnMgc3RyaW5nfFVpbnQ4QXJyYXlcbiAgICAgKi9cbiAgICBvdXRwdXRzKGluZGV4OiBudW1iZXIpOiBzdHJpbmc7XG4gICAgb3V0cHV0cyhpbmRleDogbnVtYmVyLCBvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZ3xVaW50OEFycmF5O1xuICAgIG91dHB1dHMoaW5kZXg6IG51bWJlciwgb3B0aW9uYWxFbmNvZGluZz86IGFueSk6IHN0cmluZ3xVaW50OEFycmF5fG51bGwge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAxNik7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgbnVtYmVyXG4gICAgICovXG4gICAgb3V0cHV0c0xlbmd0aCgpOiBudW1iZXIge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAxNik7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIG51bWJlciBpbmRleFxuICAgICAqIEBwYXJhbSBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlNwYXJzZVRlbnNvcj0gb2JqXG4gICAgICogQHJldHVybnMgb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5TcGFyc2VUZW5zb3JcbiAgICAgKi9cbiAgICBzcGFyc2VJbml0aWFsaXplcnMoaW5kZXg6IG51bWJlciwgb2JqPzogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5TcGFyc2VUZW5zb3IpOlxuICAgICAgICBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlNwYXJzZVRlbnNvcnxudWxsIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTgpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IChvYmogfHwgbmV3IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuU3BhcnNlVGVuc29yKCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiIS5fX3ZlY3Rvcih0aGlzLmJiX3BvcyArIG9mZnNldCkgKyBpbmRleCAqIDQpLCB0aGlzLmJiISkgOlxuICAgICAgICAgICAgICAgICAgICAgIG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgbnVtYmVyXG4gICAgICovXG4gICAgc3BhcnNlSW5pdGlhbGl6ZXJzTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDE4KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICovXG4gICAgc3RhdGljIHN0YXJ0R3JhcGgoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgICAgYnVpbGRlci5zdGFydE9iamVjdCg4KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCBpbml0aWFsaXplcnNPZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkSW5pdGlhbGl6ZXJzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGluaXRpYWxpemVyc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDAsIGluaXRpYWxpemVyc09mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBBcnJheS48ZmxhdGJ1ZmZlcnMuT2Zmc2V0PiBkYXRhXG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGNyZWF0ZUluaXRpYWxpemVyc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBmbGF0YnVmZmVycy5PZmZzZXRbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIGJ1aWxkZXIuYWRkT2Zmc2V0KGRhdGFbaV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBudW1iZXIgbnVtRWxlbXNcbiAgICAgKi9cbiAgICBzdGF0aWMgc3RhcnRJbml0aWFsaXplcnNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBudW1FbGVtcywgNCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5PZmZzZXQgbm9kZUFyZ3NPZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkTm9kZUFyZ3MoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbm9kZUFyZ3NPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxLCBub2RlQXJnc09mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBBcnJheS48ZmxhdGJ1ZmZlcnMuT2Zmc2V0PiBkYXRhXG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGNyZWF0ZU5vZGVBcmdzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IGZsYXRidWZmZXJzLk9mZnNldFtdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgZGF0YS5sZW5ndGgsIDQpO1xuICAgICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgYnVpbGRlci5hZGRPZmZzZXQoZGF0YVtpXSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYnVpbGRlci5lbmRWZWN0b3IoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIG51bWJlciBudW1FbGVtc1xuICAgICAqL1xuICAgIHN0YXRpYyBzdGFydE5vZGVBcmdzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IG5vZGVzT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZE5vZGVzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG5vZGVzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMiwgbm9kZXNPZmZzZXQsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gQXJyYXkuPGZsYXRidWZmZXJzLk9mZnNldD4gZGF0YVxuICAgICAqIEByZXR1cm5zIGZsYXRidWZmZXJzLk9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBjcmVhdGVOb2Rlc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBmbGF0YnVmZmVycy5PZmZzZXRbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIGJ1aWxkZXIuYWRkT2Zmc2V0KGRhdGFbaV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBudW1iZXIgbnVtRWxlbXNcbiAgICAgKi9cbiAgICBzdGF0aWMgc3RhcnROb2Rlc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIG51bWJlciBtYXhOb2RlSW5kZXhcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkTWF4Tm9kZUluZGV4KGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG1heE5vZGVJbmRleDogbnVtYmVyKSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkSW50MzIoMywgbWF4Tm9kZUluZGV4LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCBub2RlRWRnZXNPZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkTm9kZUVkZ2VzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG5vZGVFZGdlc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDQsIG5vZGVFZGdlc09mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBBcnJheS48ZmxhdGJ1ZmZlcnMuT2Zmc2V0PiBkYXRhXG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGNyZWF0ZU5vZGVFZGdlc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBmbGF0YnVmZmVycy5PZmZzZXRbXSk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIGJ1aWxkZXIuYWRkT2Zmc2V0KGRhdGFbaV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBudW1iZXIgbnVtRWxlbXNcbiAgICAgKi9cbiAgICBzdGF0aWMgc3RhcnROb2RlRWRnZXNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBudW1FbGVtcywgNCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5PZmZzZXQgaW5wdXRzT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZElucHV0cyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBpbnB1dHNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCg1LCBpbnB1dHNPZmZzZXQsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gQXJyYXkuPGZsYXRidWZmZXJzLk9mZnNldD4gZGF0YVxuICAgICAqIEByZXR1cm5zIGZsYXRidWZmZXJzLk9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBjcmVhdGVJbnB1dHNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogZmxhdGJ1ZmZlcnMuT2Zmc2V0W10pOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICBidWlsZGVyLmFkZE9mZnNldChkYXRhW2ldKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gbnVtYmVyIG51bUVsZW1zXG4gICAgICovXG4gICAgc3RhdGljIHN0YXJ0SW5wdXRzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IG91dHB1dHNPZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkT3V0cHV0cyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBvdXRwdXRzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoNiwgb3V0cHV0c09mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBBcnJheS48ZmxhdGJ1ZmZlcnMuT2Zmc2V0PiBkYXRhXG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGNyZWF0ZU91dHB1dHNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogZmxhdGJ1ZmZlcnMuT2Zmc2V0W10pOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICBidWlsZGVyLmFkZE9mZnNldChkYXRhW2ldKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gbnVtYmVyIG51bUVsZW1zXG4gICAgICovXG4gICAgc3RhdGljIHN0YXJ0T3V0cHV0c1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCBzcGFyc2VJbml0aWFsaXplcnNPZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkU3BhcnNlSW5pdGlhbGl6ZXJzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIHNwYXJzZUluaXRpYWxpemVyc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDcsIHNwYXJzZUluaXRpYWxpemVyc09mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBBcnJheS48ZmxhdGJ1ZmZlcnMuT2Zmc2V0PiBkYXRhXG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGNyZWF0ZVNwYXJzZUluaXRpYWxpemVyc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBkYXRhOiBmbGF0YnVmZmVycy5PZmZzZXRbXSk6XG4gICAgICAgIGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIGRhdGEubGVuZ3RoLCA0KTtcbiAgICAgIGZvciAobGV0IGkgPSBkYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIGJ1aWxkZXIuYWRkT2Zmc2V0KGRhdGFbaV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBudW1iZXIgbnVtRWxlbXNcbiAgICAgKi9cbiAgICBzdGF0aWMgc3RhcnRTcGFyc2VJbml0aWFsaXplcnNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBudW1FbGVtcywgNCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEByZXR1cm5zIGZsYXRidWZmZXJzLk9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBlbmRHcmFwaChidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICAgIGxldCBvZmZzZXQgPSBidWlsZGVyLmVuZE9iamVjdCgpO1xuICAgICAgcmV0dXJuIG9mZnNldDtcbiAgICB9XG5cbiAgICBzdGF0aWMgY3JlYXRlR3JhcGgoXG4gICAgICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGluaXRpYWxpemVyc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LCBub2RlQXJnc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgICAgICBub2Rlc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LCBtYXhOb2RlSW5kZXg6IG51bWJlciwgbm9kZUVkZ2VzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICAgICAgIGlucHV0c09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LCBvdXRwdXRzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICAgICAgIHNwYXJzZUluaXRpYWxpemVyc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICAgIEdyYXBoLnN0YXJ0R3JhcGgoYnVpbGRlcik7XG4gICAgICBHcmFwaC5hZGRJbml0aWFsaXplcnMoYnVpbGRlciwgaW5pdGlhbGl6ZXJzT2Zmc2V0KTtcbiAgICAgIEdyYXBoLmFkZE5vZGVBcmdzKGJ1aWxkZXIsIG5vZGVBcmdzT2Zmc2V0KTtcbiAgICAgIEdyYXBoLmFkZE5vZGVzKGJ1aWxkZXIsIG5vZGVzT2Zmc2V0KTtcbiAgICAgIEdyYXBoLmFkZE1heE5vZGVJbmRleChidWlsZGVyLCBtYXhOb2RlSW5kZXgpO1xuICAgICAgR3JhcGguYWRkTm9kZUVkZ2VzKGJ1aWxkZXIsIG5vZGVFZGdlc09mZnNldCk7XG4gICAgICBHcmFwaC5hZGRJbnB1dHMoYnVpbGRlciwgaW5wdXRzT2Zmc2V0KTtcbiAgICAgIEdyYXBoLmFkZE91dHB1dHMoYnVpbGRlciwgb3V0cHV0c09mZnNldCk7XG4gICAgICBHcmFwaC5hZGRTcGFyc2VJbml0aWFsaXplcnMoYnVpbGRlciwgc3BhcnNlSW5pdGlhbGl6ZXJzT2Zmc2V0KTtcbiAgICAgIHJldHVybiBHcmFwaC5lbmRHcmFwaChidWlsZGVyKTtcbiAgICB9XG4gIH1cbn1cbi8qKlxuICogQGNvbnN0cnVjdG9yXG4gKi9cbmV4cG9ydCBuYW1lc3BhY2Ugb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicyB7XG4gIGV4cG9ydCBjbGFzcyBNb2RlbCB7XG4gICAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXJ8bnVsbCA9IG51bGw7XG5cbiAgICBiYl9wb3MgPSAwO1xuICAgIC8qKlxuICAgICAqIEBwYXJhbSBudW1iZXIgaVxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIGJiXG4gICAgICogQHJldHVybnMgTW9kZWxcbiAgICAgKi9cbiAgICBfX2luaXQoaTogbnVtYmVyLCBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IE1vZGVsIHtcbiAgICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICAgIHRoaXMuYmIgPSBiYjtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIGJiXG4gICAgICogQHBhcmFtIE1vZGVsPSBvYmpcbiAgICAgKiBAcmV0dXJucyBNb2RlbFxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRSb290QXNNb2RlbChiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogTW9kZWwpOiBNb2RlbCB7XG4gICAgICByZXR1cm4gKG9iaiB8fCBuZXcgTW9kZWwoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciBiYlxuICAgICAqIEBwYXJhbSBNb2RlbD0gb2JqXG4gICAgICogQHJldHVybnMgTW9kZWxcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0U2l6ZVByZWZpeGVkUm9vdEFzTW9kZWwoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IE1vZGVsKTogTW9kZWwge1xuICAgICAgYmIuc2V0UG9zaXRpb24oYmIucG9zaXRpb24oKSArIGZsYXRidWZmZXJzLlNJWkVfUFJFRklYX0xFTkdUSCk7XG4gICAgICByZXR1cm4gKG9iaiB8fCBuZXcgTW9kZWwoKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBmbGF0YnVmZmVycy5Mb25nXG4gICAgICovXG4gICAgaXJWZXJzaW9uKCk6IGZsYXRidWZmZXJzLkxvbmcge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkSW50NjQodGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogdGhpcy5iYiEuY3JlYXRlTG9uZygwLCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gbnVtYmVyIGluZGV4XG4gICAgICogQHBhcmFtIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuT3BlcmF0b3JTZXRJZD0gb2JqXG4gICAgICogQHJldHVybnMgb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5PcGVyYXRvclNldElkXG4gICAgICovXG4gICAgb3BzZXRJbXBvcnQoaW5kZXg6IG51bWJlciwgb2JqPzogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5PcGVyYXRvclNldElkKTpcbiAgICAgICAgb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5PcGVyYXRvclNldElkfG51bGwge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA2KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyAob2JqIHx8IG5ldyBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLk9wZXJhdG9yU2V0SWQoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLl9faW5pdCh0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCksIHRoaXMuYmIhKSA6XG4gICAgICAgICAgICAgICAgICAgICAgbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBudW1iZXJcbiAgICAgKi9cbiAgICBvcHNldEltcG9ydExlbmd0aCgpOiBudW1iZXIge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA2KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3ZlY3Rvcl9sZW4odGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuRW5jb2Rpbmc9IG9wdGlvbmFsRW5jb2RpbmdcbiAgICAgKiBAcmV0dXJucyBzdHJpbmd8VWludDhBcnJheXxudWxsXG4gICAgICovXG4gICAgcHJvZHVjZXJOYW1lKCk6IHN0cmluZ3xudWxsO1xuICAgIHByb2R1Y2VyTmFtZShvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZ3xVaW50OEFycmF5fG51bGw7XG4gICAgcHJvZHVjZXJOYW1lKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmd8VWludDhBcnJheXxudWxsIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgOCk7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuRW5jb2Rpbmc9IG9wdGlvbmFsRW5jb2RpbmdcbiAgICAgKiBAcmV0dXJucyBzdHJpbmd8VWludDhBcnJheXxudWxsXG4gICAgICovXG4gICAgcHJvZHVjZXJWZXJzaW9uKCk6IHN0cmluZ3xudWxsO1xuICAgIHByb2R1Y2VyVmVyc2lvbihvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZ3xVaW50OEFycmF5fG51bGw7XG4gICAgcHJvZHVjZXJWZXJzaW9uKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmd8VWludDhBcnJheXxudWxsIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTApO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkVuY29kaW5nPSBvcHRpb25hbEVuY29kaW5nXG4gICAgICogQHJldHVybnMgc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbFxuICAgICAqL1xuICAgIGRvbWFpbigpOiBzdHJpbmd8bnVsbDtcbiAgICBkb21haW4ob3B0aW9uYWxFbmNvZGluZzogZmxhdGJ1ZmZlcnMuRW5jb2RpbmcpOiBzdHJpbmd8VWludDhBcnJheXxudWxsO1xuICAgIGRvbWFpbihvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDEyKTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiX3BvcyArIG9mZnNldCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIGZsYXRidWZmZXJzLkxvbmdcbiAgICAgKi9cbiAgICBtb2RlbFZlcnNpb24oKTogZmxhdGJ1ZmZlcnMuTG9uZyB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDE0KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5yZWFkSW50NjQodGhpcy5iYl9wb3MgKyBvZmZzZXQpIDogdGhpcy5iYiEuY3JlYXRlTG9uZygwLCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuRW5jb2Rpbmc9IG9wdGlvbmFsRW5jb2RpbmdcbiAgICAgKiBAcmV0dXJucyBzdHJpbmd8VWludDhBcnJheXxudWxsXG4gICAgICovXG4gICAgZG9jU3RyaW5nKCk6IHN0cmluZ3xudWxsO1xuICAgIGRvY1N0cmluZyhvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZ3xVaW50OEFycmF5fG51bGw7XG4gICAgZG9jU3RyaW5nKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmd8VWludDhBcnJheXxudWxsIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgMTYpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuR3JhcGg9IG9ialxuICAgICAqIEByZXR1cm5zIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuR3JhcGh8bnVsbFxuICAgICAqL1xuICAgIGdyYXBoKG9iaj86IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuR3JhcGgpOiBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLkdyYXBofG51bGwge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCAxOCk7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gKG9iaiB8fCBuZXcgb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5HcmFwaCgpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAuX19pbml0KHRoaXMuYmIhLl9faW5kaXJlY3QodGhpcy5iYl9wb3MgKyBvZmZzZXQpLCB0aGlzLmJiISkgOlxuICAgICAgICAgICAgICAgICAgICAgIG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkVuY29kaW5nPSBvcHRpb25hbEVuY29kaW5nXG4gICAgICogQHJldHVybnMgc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbFxuICAgICAqL1xuICAgIGdyYXBoRG9jU3RyaW5nKCk6IHN0cmluZ3xudWxsO1xuICAgIGdyYXBoRG9jU3RyaW5nKG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbDtcbiAgICBncmFwaERvY1N0cmluZyhvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDIwKTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyB0aGlzLmJiIS5fX3N0cmluZyh0aGlzLmJiX3BvcyArIG9mZnNldCwgb3B0aW9uYWxFbmNvZGluZykgOiBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKi9cbiAgICBzdGF0aWMgc3RhcnRNb2RlbChidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgICBidWlsZGVyLnN0YXJ0T2JqZWN0KDkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuTG9uZyBpclZlcnNpb25cbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkSXJWZXJzaW9uKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGlyVmVyc2lvbjogZmxhdGJ1ZmZlcnMuTG9uZykge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZEludDY0KDAsIGlyVmVyc2lvbiwgYnVpbGRlci5jcmVhdGVMb25nKDAsIDApKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCBvcHNldEltcG9ydE9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRPcHNldEltcG9ydChidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBvcHNldEltcG9ydE9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDEsIG9wc2V0SW1wb3J0T2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIEFycmF5LjxmbGF0YnVmZmVycy5PZmZzZXQ+IGRhdGFcbiAgICAgKiBAcmV0dXJucyBmbGF0YnVmZmVycy5PZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgY3JlYXRlT3BzZXRJbXBvcnRWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogZmxhdGJ1ZmZlcnMuT2Zmc2V0W10pOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICBidWlsZGVyLmFkZE9mZnNldChkYXRhW2ldKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gbnVtYmVyIG51bUVsZW1zXG4gICAgICovXG4gICAgc3RhdGljIHN0YXJ0T3BzZXRJbXBvcnRWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbnVtRWxlbXM6IG51bWJlcikge1xuICAgICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBudW1FbGVtcywgNCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5PZmZzZXQgcHJvZHVjZXJOYW1lT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZFByb2R1Y2VyTmFtZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBwcm9kdWNlck5hbWVPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgyLCBwcm9kdWNlck5hbWVPZmZzZXQsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IHByb2R1Y2VyVmVyc2lvbk9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRQcm9kdWNlclZlcnNpb24oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgcHJvZHVjZXJWZXJzaW9uT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMywgcHJvZHVjZXJWZXJzaW9uT2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCBkb21haW5PZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkRG9tYWluKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRvbWFpbk9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDQsIGRvbWFpbk9mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5Mb25nIG1vZGVsVmVyc2lvblxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRNb2RlbFZlcnNpb24oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbW9kZWxWZXJzaW9uOiBmbGF0YnVmZmVycy5Mb25nKSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkSW50NjQoNSwgbW9kZWxWZXJzaW9uLCBidWlsZGVyLmNyZWF0ZUxvbmcoMCwgMCkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IGRvY1N0cmluZ09mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGREb2NTdHJpbmcoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZG9jU3RyaW5nT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoNiwgZG9jU3RyaW5nT2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCBncmFwaE9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRHcmFwaChidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBncmFwaE9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDcsIGdyYXBoT2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCBncmFwaERvY1N0cmluZ09mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRHcmFwaERvY1N0cmluZyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBncmFwaERvY1N0cmluZ09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDgsIGdyYXBoRG9jU3RyaW5nT2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGVuZE1vZGVsKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgICAgbGV0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgICByZXR1cm4gb2Zmc2V0O1xuICAgIH1cblxuICAgIHN0YXRpYyBjcmVhdGVNb2RlbChcbiAgICAgICAgYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgaXJWZXJzaW9uOiBmbGF0YnVmZmVycy5Mb25nLCBvcHNldEltcG9ydE9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgICAgICBwcm9kdWNlck5hbWVPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCwgcHJvZHVjZXJWZXJzaW9uT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICAgICAgIGRvbWFpbk9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LCBtb2RlbFZlcnNpb246IGZsYXRidWZmZXJzLkxvbmcsIGRvY1N0cmluZ09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgICAgICBncmFwaE9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LCBncmFwaERvY1N0cmluZ09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICAgIE1vZGVsLnN0YXJ0TW9kZWwoYnVpbGRlcik7XG4gICAgICBNb2RlbC5hZGRJclZlcnNpb24oYnVpbGRlciwgaXJWZXJzaW9uKTtcbiAgICAgIE1vZGVsLmFkZE9wc2V0SW1wb3J0KGJ1aWxkZXIsIG9wc2V0SW1wb3J0T2Zmc2V0KTtcbiAgICAgIE1vZGVsLmFkZFByb2R1Y2VyTmFtZShidWlsZGVyLCBwcm9kdWNlck5hbWVPZmZzZXQpO1xuICAgICAgTW9kZWwuYWRkUHJvZHVjZXJWZXJzaW9uKGJ1aWxkZXIsIHByb2R1Y2VyVmVyc2lvbk9mZnNldCk7XG4gICAgICBNb2RlbC5hZGREb21haW4oYnVpbGRlciwgZG9tYWluT2Zmc2V0KTtcbiAgICAgIE1vZGVsLmFkZE1vZGVsVmVyc2lvbihidWlsZGVyLCBtb2RlbFZlcnNpb24pO1xuICAgICAgTW9kZWwuYWRkRG9jU3RyaW5nKGJ1aWxkZXIsIGRvY1N0cmluZ09mZnNldCk7XG4gICAgICBNb2RlbC5hZGRHcmFwaChidWlsZGVyLCBncmFwaE9mZnNldCk7XG4gICAgICBNb2RlbC5hZGRHcmFwaERvY1N0cmluZyhidWlsZGVyLCBncmFwaERvY1N0cmluZ09mZnNldCk7XG4gICAgICByZXR1cm4gTW9kZWwuZW5kTW9kZWwoYnVpbGRlcik7XG4gICAgfVxuICB9XG59XG4vKipcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5leHBvcnQgbmFtZXNwYWNlIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMge1xuICBleHBvcnQgY2xhc3MgS2VybmVsQ3JlYXRlSW5mb3Mge1xuICAgIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyfG51bGwgPSBudWxsO1xuXG4gICAgYmJfcG9zID0gMDtcbiAgICAvKipcbiAgICAgKiBAcGFyYW0gbnVtYmVyIGlcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciBiYlxuICAgICAqIEByZXR1cm5zIEtlcm5lbENyZWF0ZUluZm9zXG4gICAgICovXG4gICAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBLZXJuZWxDcmVhdGVJbmZvcyB7XG4gICAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgICB0aGlzLmJiID0gYmI7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciBiYlxuICAgICAqIEBwYXJhbSBLZXJuZWxDcmVhdGVJbmZvcz0gb2JqXG4gICAgICogQHJldHVybnMgS2VybmVsQ3JlYXRlSW5mb3NcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0Um9vdEFzS2VybmVsQ3JlYXRlSW5mb3MoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IEtlcm5lbENyZWF0ZUluZm9zKTogS2VybmVsQ3JlYXRlSW5mb3Mge1xuICAgICAgcmV0dXJuIChvYmogfHwgbmV3IEtlcm5lbENyZWF0ZUluZm9zKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcGFyYW0gS2VybmVsQ3JlYXRlSW5mb3M9IG9ialxuICAgICAqIEByZXR1cm5zIEtlcm5lbENyZWF0ZUluZm9zXG4gICAgICovXG4gICAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc0tlcm5lbENyZWF0ZUluZm9zKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBLZXJuZWxDcmVhdGVJbmZvcyk6XG4gICAgICAgIEtlcm5lbENyZWF0ZUluZm9zIHtcbiAgICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgICAgcmV0dXJuIChvYmogfHwgbmV3IEtlcm5lbENyZWF0ZUluZm9zKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIG51bWJlciBpbmRleFxuICAgICAqIEByZXR1cm5zIG51bWJlclxuICAgICAqL1xuICAgIG5vZGVJbmRpY2VzKGluZGV4OiBudW1iZXIpOiBudW1iZXJ8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRVaW50MzIodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA0KSA6IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgbnVtYmVyXG4gICAgICovXG4gICAgbm9kZUluZGljZXNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHJldHVybnMgVWludDMyQXJyYXlcbiAgICAgKi9cbiAgICBub2RlSW5kaWNlc0FycmF5KCk6IFVpbnQzMkFycmF5fG51bGwge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICAgIHJldHVybiBvZmZzZXQgP1xuICAgICAgICAgIG5ldyBVaW50MzJBcnJheShcbiAgICAgICAgICAgICAgdGhpcy5iYiEuYnl0ZXMoKS5idWZmZXIsIHRoaXMuYmIhLmJ5dGVzKCkuYnl0ZU9mZnNldCArIHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSxcbiAgICAgICAgICAgICAgdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSkgOlxuICAgICAgICAgIG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIG51bWJlciBpbmRleFxuICAgICAqIEByZXR1cm5zIGZsYXRidWZmZXJzLkxvbmdcbiAgICAgKi9cbiAgICBrZXJuZWxEZWZIYXNoZXMoaW5kZXg6IG51bWJlcik6IGZsYXRidWZmZXJzLkxvbmd8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLnJlYWRVaW50NjQodGhpcy5iYiEuX192ZWN0b3IodGhpcy5iYl9wb3MgKyBvZmZzZXQpICsgaW5kZXggKiA4KSA6XG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5iYiEuY3JlYXRlTG9uZygwLCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBudW1iZXJcbiAgICAgKi9cbiAgICBrZXJuZWxEZWZIYXNoZXNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqL1xuICAgIHN0YXRpYyBzdGFydEtlcm5lbENyZWF0ZUluZm9zKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpIHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRPYmplY3QoMik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5PZmZzZXQgbm9kZUluZGljZXNPZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkTm9kZUluZGljZXMoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgbm9kZUluZGljZXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgwLCBub2RlSW5kaWNlc09mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBBcnJheS48bnVtYmVyPiBkYXRhXG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGNyZWF0ZU5vZGVJbmRpY2VzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGRhdGE6IG51bWJlcltdfFVpbnQ4QXJyYXkpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICBidWlsZGVyLmFkZEludDMyKGRhdGFbaV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJ1aWxkZXIuZW5kVmVjdG9yKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBudW1iZXIgbnVtRWxlbXNcbiAgICAgKi9cbiAgICBzdGF0aWMgc3RhcnROb2RlSW5kaWNlc1ZlY3RvcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBudW1FbGVtczogbnVtYmVyKSB7XG4gICAgICBidWlsZGVyLnN0YXJ0VmVjdG9yKDQsIG51bUVsZW1zLCA0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCBrZXJuZWxEZWZIYXNoZXNPZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkS2VybmVsRGVmSGFzaGVzKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGtlcm5lbERlZkhhc2hlc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDEsIGtlcm5lbERlZkhhc2hlc09mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBBcnJheS48ZmxhdGJ1ZmZlcnMuTG9uZz4gZGF0YVxuICAgICAqIEByZXR1cm5zIGZsYXRidWZmZXJzLk9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBjcmVhdGVLZXJuZWxEZWZIYXNoZXNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogZmxhdGJ1ZmZlcnMuTG9uZ1tdKTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoOCwgZGF0YS5sZW5ndGgsIDgpO1xuICAgICAgZm9yIChsZXQgaSA9IGRhdGEubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgYnVpbGRlci5hZGRJbnQ2NChkYXRhW2ldKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gbnVtYmVyIG51bUVsZW1zXG4gICAgICovXG4gICAgc3RhdGljIHN0YXJ0S2VybmVsRGVmSGFzaGVzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoOCwgbnVtRWxlbXMsIDgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcmV0dXJucyBmbGF0YnVmZmVycy5PZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgZW5kS2VybmVsQ3JlYXRlSW5mb3MoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICAgIHJldHVybiBvZmZzZXQ7XG4gICAgfVxuXG4gICAgc3RhdGljIGNyZWF0ZUtlcm5lbENyZWF0ZUluZm9zKFxuICAgICAgICBidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBub2RlSW5kaWNlc09mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgICAgICBrZXJuZWxEZWZIYXNoZXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBLZXJuZWxDcmVhdGVJbmZvcy5zdGFydEtlcm5lbENyZWF0ZUluZm9zKGJ1aWxkZXIpO1xuICAgICAgS2VybmVsQ3JlYXRlSW5mb3MuYWRkTm9kZUluZGljZXMoYnVpbGRlciwgbm9kZUluZGljZXNPZmZzZXQpO1xuICAgICAgS2VybmVsQ3JlYXRlSW5mb3MuYWRkS2VybmVsRGVmSGFzaGVzKGJ1aWxkZXIsIGtlcm5lbERlZkhhc2hlc09mZnNldCk7XG4gICAgICByZXR1cm4gS2VybmVsQ3JlYXRlSW5mb3MuZW5kS2VybmVsQ3JlYXRlSW5mb3MoYnVpbGRlcik7XG4gICAgfVxuICB9XG59XG4vKipcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5leHBvcnQgbmFtZXNwYWNlIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMge1xuICBleHBvcnQgY2xhc3MgU3ViR3JhcGhTZXNzaW9uU3RhdGUge1xuICAgIGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyfG51bGwgPSBudWxsO1xuXG4gICAgYmJfcG9zID0gMDtcbiAgICAvKipcbiAgICAgKiBAcGFyYW0gbnVtYmVyIGlcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciBiYlxuICAgICAqIEByZXR1cm5zIFN1YkdyYXBoU2Vzc2lvblN0YXRlXG4gICAgICovXG4gICAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBTdWJHcmFwaFNlc3Npb25TdGF0ZSB7XG4gICAgICB0aGlzLmJiX3BvcyA9IGk7XG4gICAgICB0aGlzLmJiID0gYmI7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciBiYlxuICAgICAqIEBwYXJhbSBTdWJHcmFwaFNlc3Npb25TdGF0ZT0gb2JqXG4gICAgICogQHJldHVybnMgU3ViR3JhcGhTZXNzaW9uU3RhdGVcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0Um9vdEFzU3ViR3JhcGhTZXNzaW9uU3RhdGUoYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IFN1YkdyYXBoU2Vzc2lvblN0YXRlKTogU3ViR3JhcGhTZXNzaW9uU3RhdGUge1xuICAgICAgcmV0dXJuIChvYmogfHwgbmV3IFN1YkdyYXBoU2Vzc2lvblN0YXRlKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcGFyYW0gU3ViR3JhcGhTZXNzaW9uU3RhdGU9IG9ialxuICAgICAqIEByZXR1cm5zIFN1YkdyYXBoU2Vzc2lvblN0YXRlXG4gICAgICovXG4gICAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc1N1YkdyYXBoU2Vzc2lvblN0YXRlKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBTdWJHcmFwaFNlc3Npb25TdGF0ZSk6XG4gICAgICAgIFN1YkdyYXBoU2Vzc2lvblN0YXRlIHtcbiAgICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgICAgcmV0dXJuIChvYmogfHwgbmV3IFN1YkdyYXBoU2Vzc2lvblN0YXRlKCkpLl9faW5pdChiYi5yZWFkSW50MzIoYmIucG9zaXRpb24oKSkgKyBiYi5wb3NpdGlvbigpLCBiYik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkVuY29kaW5nPSBvcHRpb25hbEVuY29kaW5nXG4gICAgICogQHJldHVybnMgc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbFxuICAgICAqL1xuICAgIGdyYXBoSWQoKTogc3RyaW5nfG51bGw7XG4gICAgZ3JhcGhJZChvcHRpb25hbEVuY29kaW5nOiBmbGF0YnVmZmVycy5FbmNvZGluZyk6IHN0cmluZ3xVaW50OEFycmF5fG51bGw7XG4gICAgZ3JhcGhJZChvcHRpb25hbEVuY29kaW5nPzogYW55KTogc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDQpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IHRoaXMuYmIhLl9fc3RyaW5nKHRoaXMuYmJfcG9zICsgb2Zmc2V0LCBvcHRpb25hbEVuY29kaW5nKSA6IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuU2Vzc2lvblN0YXRlPSBvYmpcbiAgICAgKiBAcmV0dXJucyBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlNlc3Npb25TdGF0ZXxudWxsXG4gICAgICovXG4gICAgc2Vzc2lvblN0YXRlKG9iaj86IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuU2Vzc2lvblN0YXRlKTogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5TZXNzaW9uU3RhdGV8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IChvYmogfHwgbmV3IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuU2Vzc2lvblN0YXRlKCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiX3BvcyArIG9mZnNldCksIHRoaXMuYmIhKSA6XG4gICAgICAgICAgICAgICAgICAgICAgbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICovXG4gICAgc3RhdGljIHN0YXJ0U3ViR3JhcGhTZXNzaW9uU3RhdGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgICAgYnVpbGRlci5zdGFydE9iamVjdCgyKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCBncmFwaElkT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZEdyYXBoSWQoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZ3JhcGhJZE9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDAsIGdyYXBoSWRPZmZzZXQsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IHNlc3Npb25TdGF0ZU9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRTZXNzaW9uU3RhdGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgc2Vzc2lvblN0YXRlT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMSwgc2Vzc2lvblN0YXRlT2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGVuZFN1YkdyYXBoU2Vzc2lvblN0YXRlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgICAgbGV0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgICBidWlsZGVyLnJlcXVpcmVkRmllbGQob2Zmc2V0LCA0KTsgIC8vIGdyYXBoX2lkXG4gICAgICByZXR1cm4gb2Zmc2V0O1xuICAgIH1cblxuICAgIHN0YXRpYyBjcmVhdGVTdWJHcmFwaFNlc3Npb25TdGF0ZShcbiAgICAgICAgYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZ3JhcGhJZE9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0LFxuICAgICAgICBzZXNzaW9uU3RhdGVPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCk6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBTdWJHcmFwaFNlc3Npb25TdGF0ZS5zdGFydFN1YkdyYXBoU2Vzc2lvblN0YXRlKGJ1aWxkZXIpO1xuICAgICAgU3ViR3JhcGhTZXNzaW9uU3RhdGUuYWRkR3JhcGhJZChidWlsZGVyLCBncmFwaElkT2Zmc2V0KTtcbiAgICAgIFN1YkdyYXBoU2Vzc2lvblN0YXRlLmFkZFNlc3Npb25TdGF0ZShidWlsZGVyLCBzZXNzaW9uU3RhdGVPZmZzZXQpO1xuICAgICAgcmV0dXJuIFN1YkdyYXBoU2Vzc2lvblN0YXRlLmVuZFN1YkdyYXBoU2Vzc2lvblN0YXRlKGJ1aWxkZXIpO1xuICAgIH1cbiAgfVxufVxuLyoqXG4gKiBAY29uc3RydWN0b3JcbiAqL1xuZXhwb3J0IG5hbWVzcGFjZSBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzIHtcbiAgZXhwb3J0IGNsYXNzIFNlc3Npb25TdGF0ZSB7XG4gICAgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXJ8bnVsbCA9IG51bGw7XG5cbiAgICBiYl9wb3MgPSAwO1xuICAgIC8qKlxuICAgICAqIEBwYXJhbSBudW1iZXIgaVxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIGJiXG4gICAgICogQHJldHVybnMgU2Vzc2lvblN0YXRlXG4gICAgICovXG4gICAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBTZXNzaW9uU3RhdGUge1xuICAgICAgdGhpcy5iYl9wb3MgPSBpO1xuICAgICAgdGhpcy5iYiA9IGJiO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcGFyYW0gU2Vzc2lvblN0YXRlPSBvYmpcbiAgICAgKiBAcmV0dXJucyBTZXNzaW9uU3RhdGVcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0Um9vdEFzU2Vzc2lvblN0YXRlKGJiOiBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLCBvYmo/OiBTZXNzaW9uU3RhdGUpOiBTZXNzaW9uU3RhdGUge1xuICAgICAgcmV0dXJuIChvYmogfHwgbmV3IFNlc3Npb25TdGF0ZSgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIGJiXG4gICAgICogQHBhcmFtIFNlc3Npb25TdGF0ZT0gb2JqXG4gICAgICogQHJldHVybnMgU2Vzc2lvblN0YXRlXG4gICAgICovXG4gICAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc1Nlc3Npb25TdGF0ZShiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogU2Vzc2lvblN0YXRlKTogU2Vzc2lvblN0YXRlIHtcbiAgICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgICAgcmV0dXJuIChvYmogfHwgbmV3IFNlc3Npb25TdGF0ZSgpKS5fX2luaXQoYmIucmVhZEludDMyKGJiLnBvc2l0aW9uKCkpICsgYmIucG9zaXRpb24oKSwgYmIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLktlcm5lbENyZWF0ZUluZm9zPSBvYmpcbiAgICAgKiBAcmV0dXJucyBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLktlcm5lbENyZWF0ZUluZm9zfG51bGxcbiAgICAgKi9cbiAgICBrZXJuZWxzKG9iaj86IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuS2VybmVsQ3JlYXRlSW5mb3MpOiBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLktlcm5lbENyZWF0ZUluZm9zfG51bGwge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA0KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyAob2JqIHx8IG5ldyBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLktlcm5lbENyZWF0ZUluZm9zKCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC5fX2luaXQodGhpcy5iYiEuX19pbmRpcmVjdCh0aGlzLmJiX3BvcyArIG9mZnNldCksIHRoaXMuYmIhKSA6XG4gICAgICAgICAgICAgICAgICAgICAgbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gbnVtYmVyIGluZGV4XG4gICAgICogQHBhcmFtIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuU3ViR3JhcGhTZXNzaW9uU3RhdGU9IG9ialxuICAgICAqIEByZXR1cm5zIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuU3ViR3JhcGhTZXNzaW9uU3RhdGVcbiAgICAgKi9cbiAgICBzdWJHcmFwaFNlc3Npb25TdGF0ZXMoaW5kZXg6IG51bWJlciwgb2JqPzogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5TdWJHcmFwaFNlc3Npb25TdGF0ZSk6XG4gICAgICAgIG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuU3ViR3JhcGhTZXNzaW9uU3RhdGV8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IChvYmogfHwgbmV3IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuU3ViR3JhcGhTZXNzaW9uU3RhdGUoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLl9faW5pdCh0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmIhLl9fdmVjdG9yKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSArIGluZGV4ICogNCksIHRoaXMuYmIhKSA6XG4gICAgICAgICAgICAgICAgICAgICAgbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyBudW1iZXJcbiAgICAgKi9cbiAgICBzdWJHcmFwaFNlc3Npb25TdGF0ZXNMZW5ndGgoKTogbnVtYmVyIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNik7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX192ZWN0b3JfbGVuKHRoaXMuYmJfcG9zICsgb2Zmc2V0KSA6IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqL1xuICAgIHN0YXRpYyBzdGFydFNlc3Npb25TdGF0ZShidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyKSB7XG4gICAgICBidWlsZGVyLnN0YXJ0T2JqZWN0KDIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IGtlcm5lbHNPZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgYWRkS2VybmVscyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBrZXJuZWxzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMCwga2VybmVsc09mZnNldCwgMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5PZmZzZXQgc3ViR3JhcGhTZXNzaW9uU3RhdGVzT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZFN1YkdyYXBoU2Vzc2lvblN0YXRlcyhidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBzdWJHcmFwaFNlc3Npb25TdGF0ZXNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgICAgYnVpbGRlci5hZGRGaWVsZE9mZnNldCgxLCBzdWJHcmFwaFNlc3Npb25TdGF0ZXNPZmZzZXQsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gQXJyYXkuPGZsYXRidWZmZXJzLk9mZnNldD4gZGF0YVxuICAgICAqIEByZXR1cm5zIGZsYXRidWZmZXJzLk9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBjcmVhdGVTdWJHcmFwaFNlc3Npb25TdGF0ZXNWZWN0b3IoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgZGF0YTogZmxhdGJ1ZmZlcnMuT2Zmc2V0W10pOlxuICAgICAgICBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgICAgYnVpbGRlci5zdGFydFZlY3Rvcig0LCBkYXRhLmxlbmd0aCwgNCk7XG4gICAgICBmb3IgKGxldCBpID0gZGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICBidWlsZGVyLmFkZE9mZnNldChkYXRhW2ldKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBidWlsZGVyLmVuZFZlY3RvcigpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gbnVtYmVyIG51bUVsZW1zXG4gICAgICovXG4gICAgc3RhdGljIHN0YXJ0U3ViR3JhcGhTZXNzaW9uU3RhdGVzVmVjdG9yKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG51bUVsZW1zOiBudW1iZXIpIHtcbiAgICAgIGJ1aWxkZXIuc3RhcnRWZWN0b3IoNCwgbnVtRWxlbXMsIDQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcmV0dXJucyBmbGF0YnVmZmVycy5PZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgZW5kU2Vzc2lvblN0YXRlKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgICAgbGV0IG9mZnNldCA9IGJ1aWxkZXIuZW5kT2JqZWN0KCk7XG4gICAgICByZXR1cm4gb2Zmc2V0O1xuICAgIH1cblxuICAgIHN0YXRpYyBjcmVhdGVTZXNzaW9uU3RhdGUoXG4gICAgICAgIGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIGtlcm5lbHNPZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCxcbiAgICAgICAgc3ViR3JhcGhTZXNzaW9uU3RhdGVzT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpOiBmbGF0YnVmZmVycy5PZmZzZXQge1xuICAgICAgU2Vzc2lvblN0YXRlLnN0YXJ0U2Vzc2lvblN0YXRlKGJ1aWxkZXIpO1xuICAgICAgU2Vzc2lvblN0YXRlLmFkZEtlcm5lbHMoYnVpbGRlciwga2VybmVsc09mZnNldCk7XG4gICAgICBTZXNzaW9uU3RhdGUuYWRkU3ViR3JhcGhTZXNzaW9uU3RhdGVzKGJ1aWxkZXIsIHN1YkdyYXBoU2Vzc2lvblN0YXRlc09mZnNldCk7XG4gICAgICByZXR1cm4gU2Vzc2lvblN0YXRlLmVuZFNlc3Npb25TdGF0ZShidWlsZGVyKTtcbiAgICB9XG4gIH1cbn1cbi8qKlxuICogQGNvbnN0cnVjdG9yXG4gKi9cbmV4cG9ydCBuYW1lc3BhY2Ugb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicyB7XG4gIGV4cG9ydCBjbGFzcyBJbmZlcmVuY2VTZXNzaW9uIHtcbiAgICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcnxudWxsID0gbnVsbDtcblxuICAgIGJiX3BvcyA9IDA7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIG51bWJlciBpXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIgYmJcbiAgICAgKiBAcmV0dXJucyBJbmZlcmVuY2VTZXNzaW9uXG4gICAgICovXG4gICAgX19pbml0KGk6IG51bWJlciwgYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIpOiBJbmZlcmVuY2VTZXNzaW9uIHtcbiAgICAgIHRoaXMuYmJfcG9zID0gaTtcbiAgICAgIHRoaXMuYmIgPSBiYjtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CeXRlQnVmZmVyIGJiXG4gICAgICogQHBhcmFtIEluZmVyZW5jZVNlc3Npb249IG9ialxuICAgICAqIEByZXR1cm5zIEluZmVyZW5jZVNlc3Npb25cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0Um9vdEFzSW5mZXJlbmNlU2Vzc2lvbihiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciwgb2JqPzogSW5mZXJlbmNlU2Vzc2lvbik6IEluZmVyZW5jZVNlc3Npb24ge1xuICAgICAgcmV0dXJuIChvYmogfHwgbmV3IEluZmVyZW5jZVNlc3Npb24oKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciBiYlxuICAgICAqIEBwYXJhbSBJbmZlcmVuY2VTZXNzaW9uPSBvYmpcbiAgICAgKiBAcmV0dXJucyBJbmZlcmVuY2VTZXNzaW9uXG4gICAgICovXG4gICAgc3RhdGljIGdldFNpemVQcmVmaXhlZFJvb3RBc0luZmVyZW5jZVNlc3Npb24oYmI6IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIsIG9iaj86IEluZmVyZW5jZVNlc3Npb24pOiBJbmZlcmVuY2VTZXNzaW9uIHtcbiAgICAgIGJiLnNldFBvc2l0aW9uKGJiLnBvc2l0aW9uKCkgKyBmbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEgpO1xuICAgICAgcmV0dXJuIChvYmogfHwgbmV3IEluZmVyZW5jZVNlc3Npb24oKSkuX19pbml0KGJiLnJlYWRJbnQzMihiYi5wb3NpdGlvbigpKSArIGJiLnBvc2l0aW9uKCksIGJiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciBiYlxuICAgICAqIEByZXR1cm5zIGJvb2xlYW5cbiAgICAgKi9cbiAgICBzdGF0aWMgYnVmZmVySGFzSWRlbnRpZmllcihiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcik6IGJvb2xlYW4ge1xuICAgICAgcmV0dXJuIGJiLl9faGFzX2lkZW50aWZpZXIoJ09SVE0nKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuRW5jb2Rpbmc9IG9wdGlvbmFsRW5jb2RpbmdcbiAgICAgKiBAcmV0dXJucyBzdHJpbmd8VWludDhBcnJheXxudWxsXG4gICAgICovXG4gICAgb3J0VmVyc2lvbigpOiBzdHJpbmd8bnVsbDtcbiAgICBvcnRWZXJzaW9uKG9wdGlvbmFsRW5jb2Rpbmc6IGZsYXRidWZmZXJzLkVuY29kaW5nKTogc3RyaW5nfFVpbnQ4QXJyYXl8bnVsbDtcbiAgICBvcnRWZXJzaW9uKG9wdGlvbmFsRW5jb2Rpbmc/OiBhbnkpOiBzdHJpbmd8VWludDhBcnJheXxudWxsIHtcbiAgICAgIGxldCBvZmZzZXQgPSB0aGlzLmJiIS5fX29mZnNldCh0aGlzLmJiX3BvcywgNCk7XG4gICAgICByZXR1cm4gb2Zmc2V0ID8gdGhpcy5iYiEuX19zdHJpbmcodGhpcy5iYl9wb3MgKyBvZmZzZXQsIG9wdGlvbmFsRW5jb2RpbmcpIDogbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5Nb2RlbD0gb2JqXG4gICAgICogQHJldHVybnMgb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5Nb2RlbHxudWxsXG4gICAgICovXG4gICAgbW9kZWwob2JqPzogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5Nb2RlbCk6IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuTW9kZWx8bnVsbCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gdGhpcy5iYiEuX19vZmZzZXQodGhpcy5iYl9wb3MsIDYpO1xuICAgICAgcmV0dXJuIG9mZnNldCA/IChvYmogfHwgbmV3IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuTW9kZWwoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLl9faW5pdCh0aGlzLmJiIS5fX2luZGlyZWN0KHRoaXMuYmJfcG9zICsgb2Zmc2V0KSwgdGhpcy5iYiEpIDpcbiAgICAgICAgICAgICAgICAgICAgICBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlNlc3Npb25TdGF0ZT0gb2JqXG4gICAgICogQHJldHVybnMgb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5TZXNzaW9uU3RhdGV8bnVsbFxuICAgICAqL1xuICAgIHNlc3Npb25TdGF0ZShvYmo/OiBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlNlc3Npb25TdGF0ZSk6IG9ubnhydW50aW1lLmV4cGVyaW1lbnRhbC5mYnMuU2Vzc2lvblN0YXRlfG51bGwge1xuICAgICAgbGV0IG9mZnNldCA9IHRoaXMuYmIhLl9fb2Zmc2V0KHRoaXMuYmJfcG9zLCA4KTtcbiAgICAgIHJldHVybiBvZmZzZXQgPyAob2JqIHx8IG5ldyBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlNlc3Npb25TdGF0ZSgpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAuX19pbml0KHRoaXMuYmIhLl9faW5kaXJlY3QodGhpcy5iYl9wb3MgKyBvZmZzZXQpLCB0aGlzLmJiISkgOlxuICAgICAgICAgICAgICAgICAgICAgIG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqL1xuICAgIHN0YXRpYyBzdGFydEluZmVyZW5jZVNlc3Npb24oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcikge1xuICAgICAgYnVpbGRlci5zdGFydE9iamVjdCgzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCBvcnRWZXJzaW9uT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZE9ydFZlcnNpb24oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgb3J0VmVyc2lvbk9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KSB7XG4gICAgICBidWlsZGVyLmFkZEZpZWxkT2Zmc2V0KDAsIG9ydFZlcnNpb25PZmZzZXQsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IG1vZGVsT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGFkZE1vZGVsKGJ1aWxkZXI6IGZsYXRidWZmZXJzLkJ1aWxkZXIsIG1vZGVsT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMSwgbW9kZWxPZmZzZXQsIDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5CdWlsZGVyIGJ1aWxkZXJcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuT2Zmc2V0IHNlc3Npb25TdGF0ZU9mZnNldFxuICAgICAqL1xuICAgIHN0YXRpYyBhZGRTZXNzaW9uU3RhdGUoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgc2Vzc2lvblN0YXRlT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuYWRkRmllbGRPZmZzZXQoMiwgc2Vzc2lvblN0YXRlT2Zmc2V0LCAwKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHJldHVybnMgZmxhdGJ1ZmZlcnMuT2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGVuZEluZmVyZW5jZVNlc3Npb24oYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlcik6IGZsYXRidWZmZXJzLk9mZnNldCB7XG4gICAgICBsZXQgb2Zmc2V0ID0gYnVpbGRlci5lbmRPYmplY3QoKTtcbiAgICAgIHJldHVybiBvZmZzZXQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLkJ1aWxkZXIgYnVpbGRlclxuICAgICAqIEBwYXJhbSBmbGF0YnVmZmVycy5PZmZzZXQgb2Zmc2V0XG4gICAgICovXG4gICAgc3RhdGljIGZpbmlzaEluZmVyZW5jZVNlc3Npb25CdWZmZXIoYnVpbGRlcjogZmxhdGJ1ZmZlcnMuQnVpbGRlciwgb2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQpIHtcbiAgICAgIGJ1aWxkZXIuZmluaXNoKG9mZnNldCwgJ09SVE0nKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gZmxhdGJ1ZmZlcnMuQnVpbGRlciBidWlsZGVyXG4gICAgICogQHBhcmFtIGZsYXRidWZmZXJzLk9mZnNldCBvZmZzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgZmluaXNoU2l6ZVByZWZpeGVkSW5mZXJlbmNlU2Vzc2lvbkJ1ZmZlcihidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBvZmZzZXQ6IGZsYXRidWZmZXJzLk9mZnNldCkge1xuICAgICAgYnVpbGRlci5maW5pc2gob2Zmc2V0LCAnT1JUTScsIHRydWUpO1xuICAgIH1cblxuICAgIHN0YXRpYyBjcmVhdGVJbmZlcmVuY2VTZXNzaW9uKFxuICAgICAgICBidWlsZGVyOiBmbGF0YnVmZmVycy5CdWlsZGVyLCBvcnRWZXJzaW9uT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsIG1vZGVsT2Zmc2V0OiBmbGF0YnVmZmVycy5PZmZzZXQsXG4gICAgICAgIHNlc3Npb25TdGF0ZU9mZnNldDogZmxhdGJ1ZmZlcnMuT2Zmc2V0KTogZmxhdGJ1ZmZlcnMuT2Zmc2V0IHtcbiAgICAgIEluZmVyZW5jZVNlc3Npb24uc3RhcnRJbmZlcmVuY2VTZXNzaW9uKGJ1aWxkZXIpO1xuICAgICAgSW5mZXJlbmNlU2Vzc2lvbi5hZGRPcnRWZXJzaW9uKGJ1aWxkZXIsIG9ydFZlcnNpb25PZmZzZXQpO1xuICAgICAgSW5mZXJlbmNlU2Vzc2lvbi5hZGRNb2RlbChidWlsZGVyLCBtb2RlbE9mZnNldCk7XG4gICAgICBJbmZlcmVuY2VTZXNzaW9uLmFkZFNlc3Npb25TdGF0ZShidWlsZGVyLCBzZXNzaW9uU3RhdGVPZmZzZXQpO1xuICAgICAgcmV0dXJuIEluZmVyZW5jZVNlc3Npb24uZW5kSW5mZXJlbmNlU2Vzc2lvbihidWlsZGVyKTtcbiAgICB9XG4gIH1cbn1cbiIsIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge0luZmVyZW5jZVNlc3Npb24sIFNlc3Npb25IYW5kbGVyLCBUZW5zb3J9IGZyb20gJ29ubnhydW50aW1lLWNvbW1vbic7XG5cbmltcG9ydCB7U2Vzc2lvbn0gZnJvbSAnLi9zZXNzaW9uJztcbmltcG9ydCB7VGVuc29yIGFzIE9ubnhqc1RlbnNvcn0gZnJvbSAnLi90ZW5zb3InO1xuXG5leHBvcnQgY2xhc3MgT25ueGpzU2Vzc2lvbkhhbmRsZXIgaW1wbGVtZW50cyBTZXNzaW9uSGFuZGxlciB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgc2Vzc2lvbjogU2Vzc2lvbikge1xuICAgIHRoaXMuaW5wdXROYW1lcyA9IHRoaXMuc2Vzc2lvbi5pbnB1dE5hbWVzO1xuICAgIHRoaXMub3V0cHV0TmFtZXMgPSB0aGlzLnNlc3Npb24ub3V0cHV0TmFtZXM7XG4gIH1cblxuICBhc3luYyBkaXNwb3NlKCk6IFByb21pc2U8dm9pZD4ge31cbiAgaW5wdXROYW1lczogcmVhZG9ubHkgc3RyaW5nW107XG4gIG91dHB1dE5hbWVzOiByZWFkb25seSBzdHJpbmdbXTtcbiAgYXN5bmMgcnVuKFxuICAgICAgZmVlZHM6IFNlc3Npb25IYW5kbGVyLkZlZWRzVHlwZSwgX2ZldGNoZXM6IFNlc3Npb25IYW5kbGVyLkZldGNoZXNUeXBlLFxuICAgICAgX29wdGlvbnM6IEluZmVyZW5jZVNlc3Npb24uUnVuT3B0aW9ucyk6IFByb21pc2U8U2Vzc2lvbkhhbmRsZXIuUmV0dXJuVHlwZT4ge1xuICAgIGNvbnN0IGlucHV0TWFwID0gbmV3IE1hcDxzdHJpbmcsIE9ubnhqc1RlbnNvcj4oKTtcbiAgICBmb3IgKGNvbnN0IG5hbWUgaW4gZmVlZHMpIHtcbiAgICAgIGlmIChPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChmZWVkcywgbmFtZSkpIHtcbiAgICAgICAgY29uc3QgZmVlZCA9IGZlZWRzW25hbWVdO1xuICAgICAgICBpbnB1dE1hcC5zZXQoXG4gICAgICAgICAgICBuYW1lLFxuICAgICAgICAgICAgbmV3IE9ubnhqc1RlbnNvcihcbiAgICAgICAgICAgICAgICBmZWVkLmRpbXMsIGZlZWQudHlwZSBhcyBPbm54anNUZW5zb3IuRGF0YVR5cGUsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgIGZlZWQuZGF0YSBhcyBPbm54anNUZW5zb3IuTnVtYmVyVHlwZSkpO1xuICAgICAgfVxuICAgIH1cbiAgICBjb25zdCBvdXRwdXRNYXAgPSBhd2FpdCB0aGlzLnNlc3Npb24ucnVuKGlucHV0TWFwKTtcbiAgICBjb25zdCBvdXRwdXQ6IFNlc3Npb25IYW5kbGVyLlJldHVyblR5cGUgPSB7fTtcbiAgICBvdXRwdXRNYXAuZm9yRWFjaCgodGVuc29yLCBuYW1lKSA9PiB7XG4gICAgICBvdXRwdXRbbmFtZV0gPSBuZXcgVGVuc29yKHRlbnNvci50eXBlLCB0ZW5zb3IuZGF0YSwgdGVuc29yLmRpbXMpO1xuICAgIH0pO1xuICAgIHJldHVybiBvdXRwdXQ7XG4gIH1cbiAgc3RhcnRQcm9maWxpbmcoKTogdm9pZCB7XG4gICAgdGhpcy5zZXNzaW9uLnN0YXJ0UHJvZmlsaW5nKCk7XG4gIH1cbiAgZW5kUHJvZmlsaW5nKCk6IHZvaWQge1xuICAgIHRoaXMuc2Vzc2lvbi5lbmRQcm9maWxpbmcoKTtcbiAgfVxufVxuIiwiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7cmVhZEZpbGV9IGZyb20gJ2ZzJztcbmltcG9ydCB7cHJvbWlzaWZ5fSBmcm9tICd1dGlsJztcblxuaW1wb3J0IHtyZXNvbHZlQmFja2VuZCwgU2Vzc2lvbkhhbmRsZXJUeXBlfSBmcm9tICcuL2JhY2tlbmQnO1xuaW1wb3J0IHtFeGVjdXRpb25QbGFufSBmcm9tICcuL2V4ZWN1dGlvbi1wbGFuJztcbmltcG9ydCB7R3JhcGh9IGZyb20gJy4vZ3JhcGgnO1xuaW1wb3J0IHtQcm9maWxlcn0gZnJvbSAnLi9pbnN0cnVtZW50JztcbmltcG9ydCB7TW9kZWx9IGZyb20gJy4vbW9kZWwnO1xuaW1wb3J0IHtPcGVyYXRvcn0gZnJvbSAnLi9vcGVyYXRvcnMnO1xuaW1wb3J0IHtUZW5zb3J9IGZyb20gJy4vdGVuc29yJztcblxuZXhwb3J0IGRlY2xhcmUgbmFtZXNwYWNlIFNlc3Npb24ge1xuICBleHBvcnQgaW50ZXJmYWNlIENvbmZpZyB7XG4gICAgYmFja2VuZEhpbnQ/OiBzdHJpbmc7XG4gICAgcHJvZmlsZXI/OiBQcm9maWxlci5Db25maWc7XG4gIH1cblxuICBleHBvcnQgaW50ZXJmYWNlIENvbnRleHQge1xuICAgIHByb2ZpbGVyOiBSZWFkb25seTxQcm9maWxlcj47XG4gICAgZ3JhcGhJbnB1dFR5cGVzPzogVGVuc29yLkRhdGFUeXBlW107XG4gICAgZ3JhcGhJbnB1dERpbXM/OiBBcnJheTxyZWFkb25seSBudW1iZXJbXT47XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFNlc3Npb24ge1xuICBjb25zdHJ1Y3Rvcihjb25maWc6IFNlc3Npb24uQ29uZmlnID0ge30pIHtcbiAgICB0aGlzLl9pbml0aWFsaXplZCA9IGZhbHNlO1xuICAgIHRoaXMuYmFja2VuZEhpbnQgPSBjb25maWcuYmFja2VuZEhpbnQ7XG4gICAgdGhpcy5wcm9maWxlciA9IFByb2ZpbGVyLmNyZWF0ZShjb25maWcucHJvZmlsZXIpO1xuICAgIHRoaXMuY29udGV4dCA9IHtwcm9maWxlcjogdGhpcy5wcm9maWxlciwgZ3JhcGhJbnB1dFR5cGVzOiBbXSwgZ3JhcGhJbnB1dERpbXM6IFtdfTtcbiAgfVxuXG4gIGdldCBpbnB1dE5hbWVzKCk6IHJlYWRvbmx5IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5fbW9kZWwuZ3JhcGguZ2V0SW5wdXROYW1lcygpO1xuICB9XG4gIGdldCBvdXRwdXROYW1lcygpOiByZWFkb25seSBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIHRoaXMuX21vZGVsLmdyYXBoLmdldE91dHB1dE5hbWVzKCk7XG4gIH1cblxuICBzdGFydFByb2ZpbGluZygpIHtcbiAgICB0aGlzLnByb2ZpbGVyLnN0YXJ0KCk7XG4gIH1cblxuICBlbmRQcm9maWxpbmcoKSB7XG4gICAgdGhpcy5wcm9maWxlci5zdG9wKCk7XG4gIH1cblxuICBhc3luYyBsb2FkTW9kZWwodXJpOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+O1xuICBhc3luYyBsb2FkTW9kZWwoYnVmZmVyOiBBcnJheUJ1ZmZlciwgYnl0ZU9mZnNldD86IG51bWJlciwgbGVuZ3RoPzogbnVtYmVyKTogUHJvbWlzZTx2b2lkPjtcbiAgYXN5bmMgbG9hZE1vZGVsKGJ1ZmZlcjogVWludDhBcnJheSk6IFByb21pc2U8dm9pZD47XG4gIGFzeW5jIGxvYWRNb2RlbChhcmc6IHN0cmluZ3xBcnJheUJ1ZmZlcnxVaW50OEFycmF5LCBieXRlT2Zmc2V0PzogbnVtYmVyLCBsZW5ndGg/OiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLnByb2ZpbGVyLmV2ZW50KCdzZXNzaW9uJywgJ1Nlc3Npb24ubG9hZE1vZGVsJywgYXN5bmMgKCkgPT4ge1xuICAgICAgLy8gcmVzb2x2ZSBiYWNrZW5kIGFuZCBzZXNzaW9uIGhhbmRsZXJcbiAgICAgIGNvbnN0IGJhY2tlbmQgPSBhd2FpdCByZXNvbHZlQmFja2VuZCh0aGlzLmJhY2tlbmRIaW50KTtcbiAgICAgIHRoaXMuc2Vzc2lvbkhhbmRsZXIgPSBiYWNrZW5kLmNyZWF0ZVNlc3Npb25IYW5kbGVyKHRoaXMuY29udGV4dCk7XG5cbiAgICAgIHRoaXMuX21vZGVsID0gbmV3IE1vZGVsKCk7XG4gICAgICBpZiAodHlwZW9mIGFyZyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgY29uc3QgaXNPcnRGb3JtYXQgPSBhcmcuZW5kc1dpdGgoJy5vcnQnKTtcbiAgICAgICAgaWYgKHR5cGVvZiBmZXRjaCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAvLyBub2RlXG4gICAgICAgICAgY29uc3QgYnVmID0gYXdhaXQgcHJvbWlzaWZ5KHJlYWRGaWxlKShhcmcpO1xuICAgICAgICAgIHRoaXMuaW5pdGlhbGl6ZShidWYsIGlzT3J0Rm9ybWF0KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBicm93c2VyXG4gICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChhcmcpO1xuICAgICAgICAgIGNvbnN0IGJ1ZiA9IGF3YWl0IHJlc3BvbnNlLmFycmF5QnVmZmVyKCk7XG4gICAgICAgICAgdGhpcy5pbml0aWFsaXplKG5ldyBVaW50OEFycmF5KGJ1ZiksIGlzT3J0Rm9ybWF0KTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICghQXJyYXlCdWZmZXIuaXNWaWV3KGFyZykpIHtcbiAgICAgICAgLy8gbG9hZCBtb2RlbCBmcm9tIEFycmF5QnVmZmVyXG4gICAgICAgIGNvbnN0IGFyciA9IG5ldyBVaW50OEFycmF5KGFyZywgYnl0ZU9mZnNldCB8fCAwLCBsZW5ndGggfHwgYXJnLmJ5dGVMZW5ndGgpO1xuICAgICAgICB0aGlzLmluaXRpYWxpemUoYXJyKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIGxvYWQgbW9kZWwgZnJvbSBVaW50OGFycmF5XG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZShhcmcpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBpbml0aWFsaXplKG1vZGVsUHJvdG9CbG9iOiBVaW50OEFycmF5LCBpc09ydEZvcm1hdD86IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBpZiAodGhpcy5faW5pdGlhbGl6ZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignYWxyZWFkeSBpbml0aWFsaXplZCcpO1xuICAgIH1cblxuICAgIHRoaXMucHJvZmlsZXIuZXZlbnQoJ3Nlc3Npb24nLCAnU2Vzc2lvbi5pbml0aWFsaXplJywgKCkgPT4ge1xuICAgICAgLy8gbG9hZCBncmFwaFxuICAgICAgY29uc3QgZ3JhcGhJbml0aWFsaXplciA9XG4gICAgICAgICAgdGhpcy5zZXNzaW9uSGFuZGxlci50cmFuc2Zvcm1HcmFwaCA/IHRoaXMuc2Vzc2lvbkhhbmRsZXIgYXMgR3JhcGguSW5pdGlhbGl6ZXIgOiB1bmRlZmluZWQ7XG4gICAgICB0aGlzLl9tb2RlbC5sb2FkKG1vZGVsUHJvdG9CbG9iLCBncmFwaEluaXRpYWxpemVyLCBpc09ydEZvcm1hdCk7XG5cbiAgICAgIC8vIGdyYXBoIGlzIGNvbXBsZXRlbHkgaW5pdGlhbHppZWQgYXQgdGhpcyBzdGFnZSAsIGxldCB0aGUgaW50ZXJlc3RlZCBoYW5kbGVycyBrbm93XG4gICAgICBpZiAodGhpcy5zZXNzaW9uSGFuZGxlci5vbkdyYXBoSW5pdGlhbGl6ZWQpIHtcbiAgICAgICAgdGhpcy5zZXNzaW9uSGFuZGxlci5vbkdyYXBoSW5pdGlhbGl6ZWQodGhpcy5fbW9kZWwuZ3JhcGgpO1xuICAgICAgfVxuICAgICAgLy8gaW5pdGlhbGl6ZSBlYWNoIG9wZXJhdG9yIGluIHRoZSBncmFwaFxuICAgICAgdGhpcy5pbml0aWFsaXplT3BzKHRoaXMuX21vZGVsLmdyYXBoKTtcblxuICAgICAgLy8gaW5zdGFudGlhdGUgYW4gRXhlY3V0aW9uUGxhbiBvYmplY3QgdG8gYmUgdXNlZCBieSB0aGUgU2Vzc2lvbiBvYmplY3RcbiAgICAgIHRoaXMuX2V4ZWN1dGlvblBsYW4gPSBuZXcgRXhlY3V0aW9uUGxhbih0aGlzLl9tb2RlbC5ncmFwaCwgdGhpcy5fb3BzLCB0aGlzLnByb2ZpbGVyKTtcbiAgICB9KTtcblxuICAgIHRoaXMuX2luaXRpYWxpemVkID0gdHJ1ZTtcbiAgfVxuXG4gIGFzeW5jIHJ1bihpbnB1dHM6IE1hcDxzdHJpbmcsIFRlbnNvcj58VGVuc29yW10pOiBQcm9taXNlPE1hcDxzdHJpbmcsIFRlbnNvcj4+IHtcbiAgICBpZiAoIXRoaXMuX2luaXRpYWxpemVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Nlc3Npb24gbm90IGluaXRpYWxpemVkIHlldCcpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnByb2ZpbGVyLmV2ZW50KCdzZXNzaW9uJywgJ1Nlc3Npb24ucnVuJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgaW5wdXRUZW5zb3JzID0gdGhpcy5ub3JtYWxpemVBbmRWYWxpZGF0ZUlucHV0cyhpbnB1dHMpO1xuXG4gICAgICBjb25zdCBvdXRwdXRUZW5zb3JzID0gYXdhaXQgdGhpcy5fZXhlY3V0aW9uUGxhbi5leGVjdXRlKHRoaXMuc2Vzc2lvbkhhbmRsZXIsIGlucHV0VGVuc29ycyk7XG5cbiAgICAgIHJldHVybiB0aGlzLmNyZWF0ZU91dHB1dChvdXRwdXRUZW5zb3JzKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgbm9ybWFsaXplQW5kVmFsaWRhdGVJbnB1dHMoaW5wdXRzOiBNYXA8c3RyaW5nLCBUZW5zb3I+fFRlbnNvcltdKTogVGVuc29yW10ge1xuICAgIGNvbnN0IG1vZGVsSW5wdXROYW1lcyA9IHRoaXMuX21vZGVsLmdyYXBoLmdldElucHV0TmFtZXMoKTtcblxuICAgIC8vIG5vcm1hbGl6ZSBpbnB1dHNcbiAgICAvLyBpbnB1dHM6IFRlbnNvcltdXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoaW5wdXRzKSkge1xuICAgICAgaWYgKGlucHV0cy5sZW5ndGggIT09IG1vZGVsSW5wdXROYW1lcy5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbmNvcnJlY3QgaW5wdXQgYXJyYXkgbGVuZ3RoOiBleHBlY3RlZCAke21vZGVsSW5wdXROYW1lcy5sZW5ndGh9IGJ1dCBnb3QgJHtpbnB1dHMubGVuZ3RofWApO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBjb252ZXJ0IG1hcCB0byBhcnJheVxuICAgIC8vIGlucHV0czogTWFwPHN0cmluZywgVGVuc29yPlxuICAgIGVsc2Uge1xuICAgICAgaWYgKGlucHV0cy5zaXplICE9PSBtb2RlbElucHV0TmFtZXMubGVuZ3RoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgaW5jb3JyZWN0IGlucHV0IG1hcCBzaXplOiBleHBlY3RlZCAke21vZGVsSW5wdXROYW1lcy5sZW5ndGh9IGJ1dCBnb3QgJHtpbnB1dHMuc2l6ZX1gKTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgc29ydGVkSW5wdXRzID0gbmV3IEFycmF5PFRlbnNvcj4oaW5wdXRzLnNpemUpO1xuICAgICAgbGV0IHNvcnRlZElucHV0c0luZGV4ID0gMDtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbW9kZWxJbnB1dE5hbWVzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIGNvbnN0IHRlbnNvciA9IGlucHV0cy5nZXQobW9kZWxJbnB1dE5hbWVzW2ldKTtcbiAgICAgICAgaWYgKCF0ZW5zb3IpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYG1pc3NpbmcgaW5wdXQgdGVuc29yIGZvcjogJyR7bmFtZX0nYCk7XG4gICAgICAgIH1cbiAgICAgICAgc29ydGVkSW5wdXRzW3NvcnRlZElucHV0c0luZGV4KytdID0gdGVuc29yO1xuICAgICAgfVxuXG4gICAgICBpbnB1dHMgPSBzb3J0ZWRJbnB1dHM7XG4gICAgfVxuXG4gICAgLy8gdmFsaWRhdGUgZGltcyByZXF1aXJlbWVudHNcbiAgICAvLyBGaXJzdCBzZXNzaW9uIHJ1biAtIGdyYXBoIGlucHV0IGRhdGEgaXMgbm90IGNhY2hlZCBmb3IgdGhlIHNlc3Npb25cbiAgICBpZiAoIXRoaXMuY29udGV4dC5ncmFwaElucHV0VHlwZXMgfHwgdGhpcy5jb250ZXh0LmdyYXBoSW5wdXRUeXBlcy5sZW5ndGggPT09IDAgfHwgIXRoaXMuY29udGV4dC5ncmFwaElucHV0RGltcyB8fFxuICAgICAgICB0aGlzLmNvbnRleHQuZ3JhcGhJbnB1dERpbXMubGVuZ3RoID09PSAwKSB7XG4gICAgICBjb25zdCBtb2RlbElucHV0SW5kaWNlcyA9IHRoaXMuX21vZGVsLmdyYXBoLmdldElucHV0SW5kaWNlcygpO1xuICAgICAgY29uc3QgbW9kZWxWYWx1ZXMgPSB0aGlzLl9tb2RlbC5ncmFwaC5nZXRWYWx1ZXMoKTtcblxuICAgICAgY29uc3QgZ3JhcGhJbnB1dERpbXMgPSBuZXcgQXJyYXk8cmVhZG9ubHkgbnVtYmVyW10+KG1vZGVsSW5wdXRJbmRpY2VzLmxlbmd0aCk7XG5cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbW9kZWxJbnB1dEluZGljZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgY29uc3QgZ3JhcGhJbnB1dCA9IG1vZGVsVmFsdWVzW21vZGVsSW5wdXRJbmRpY2VzW2ldXTtcbiAgICAgICAgZ3JhcGhJbnB1dERpbXNbaV0gPSBncmFwaElucHV0LnR5cGUhLnNoYXBlLmRpbXM7XG5cbiAgICAgICAgLy8gY2FjaGVkIGZvciBzZWNvbmQgYW5kIHN1YnNlcXVlbnQgcnVucy5cbiAgICAgICAgLy8gU29tZSBwYXJ0cyBvZiB0aGUgZnJhbWV3b3JrIHdvcmtzIG9uIHRoZSBhc3N1bXB0aW9uIHRoYXQgdGhlIGdyYXBoIGFuZCB0eXBlcyBhbmQgc2hhcGVzIGFyZSBzdGF0aWNcbiAgICAgICAgdGhpcy5jb250ZXh0LmdyYXBoSW5wdXRUeXBlcyEucHVzaChncmFwaElucHV0LnR5cGUhLnRlbnNvclR5cGUpO1xuICAgICAgICB0aGlzLmNvbnRleHQuZ3JhcGhJbnB1dERpbXMhLnB1c2goaW5wdXRzW2ldLmRpbXMpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnZhbGlkYXRlSW5wdXRUZW5zb3JEaW1zKGdyYXBoSW5wdXREaW1zLCBpbnB1dHMsIHRydWUpO1xuICAgIH1cblxuICAgIC8vIFNlY29uZCBhbmQgc3Vic2VxdWVudCBzZXNzaW9uIHJ1bnMgLSBncmFwaCBpbnB1dCBkYXRhIGlzIGNhY2hlZCBmb3IgdGhlIHNlc3Npb25cbiAgICBlbHNlIHtcbiAgICAgIHRoaXMudmFsaWRhdGVJbnB1dFRlbnNvckRpbXModGhpcy5jb250ZXh0LmdyYXBoSW5wdXREaW1zLCBpbnB1dHMsIGZhbHNlKTtcbiAgICB9XG5cbiAgICAvLyB2YWxpZGF0ZSB0eXBlcyByZXF1aXJlbWVudFxuICAgIHRoaXMudmFsaWRhdGVJbnB1dFRlbnNvclR5cGVzKHRoaXMuY29udGV4dC5ncmFwaElucHV0VHlwZXMhLCBpbnB1dHMpO1xuXG4gICAgcmV0dXJuIGlucHV0cztcbiAgfVxuXG4gIHByaXZhdGUgdmFsaWRhdGVJbnB1dFRlbnNvclR5cGVzKGdyYXBoSW5wdXRUeXBlczogVGVuc29yLkRhdGFUeXBlW10sIGdpdmVuSW5wdXRzOiBUZW5zb3JbXSkge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZ2l2ZW5JbnB1dHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGV4cGVjdGVkVHlwZSA9IGdyYXBoSW5wdXRUeXBlc1tpXTtcbiAgICAgIGNvbnN0IGFjdHVhbFR5cGUgPSBnaXZlbklucHV0c1tpXS50eXBlO1xuICAgICAgaWYgKGV4cGVjdGVkVHlwZSAhPT0gYWN0dWFsVHlwZSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGlucHV0IHRlbnNvclske2l9XSBjaGVjayBmYWlsZWQ6IGV4cGVjdGVkIHR5cGUgJyR7ZXhwZWN0ZWRUeXBlfScgYnV0IGdvdCAke2FjdHVhbFR5cGV9YCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSB2YWxpZGF0ZUlucHV0VGVuc29yRGltcyhcbiAgICAgIGdyYXBoSW5wdXREaW1zOiBBcnJheTxyZWFkb25seSBudW1iZXJbXT4sIGdpdmVuSW5wdXRzOiBUZW5zb3JbXSwgbm9uZURpbVN1cHBvcnRlZDogYm9vbGVhbikge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZ2l2ZW5JbnB1dHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGV4cGVjdGVkRGltcyA9IGdyYXBoSW5wdXREaW1zW2ldO1xuICAgICAgY29uc3QgYWN0dWFsRGltcyA9IGdpdmVuSW5wdXRzW2ldLmRpbXM7XG4gICAgICBpZiAoIXRoaXMuY29tcGFyZVRlbnNvckRpbXMoZXhwZWN0ZWREaW1zLCBhY3R1YWxEaW1zLCBub25lRGltU3VwcG9ydGVkKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGlucHV0IHRlbnNvclske2l9XSBjaGVjayBmYWlsZWQ6IGV4cGVjdGVkIHNoYXBlICdbJHtleHBlY3RlZERpbXMuam9pbignLCcpfV0nIGJ1dCBnb3QgWyR7XG4gICAgICAgICAgICBhY3R1YWxEaW1zLmpvaW4oJywnKX1dYCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBjb21wYXJlVGVuc29yRGltcyhleHBlY3RlZERpbXM6IHJlYWRvbmx5IG51bWJlcltdLCBhY3R1YWxEaW1zOiByZWFkb25seSBudW1iZXJbXSwgbm9uZURpbVN1cHBvcnRlZDogYm9vbGVhbik6XG4gICAgICBib29sZWFuIHtcbiAgICBpZiAoZXhwZWN0ZWREaW1zLmxlbmd0aCAhPT0gYWN0dWFsRGltcy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGV4cGVjdGVkRGltcy5sZW5ndGg7ICsraSkge1xuICAgICAgaWYgKGV4cGVjdGVkRGltc1tpXSAhPT0gYWN0dWFsRGltc1tpXSAmJiAoIW5vbmVEaW1TdXBwb3J0ZWQgfHwgZXhwZWN0ZWREaW1zW2ldICE9PSAwKSkge1xuICAgICAgICAvLyBkYXRhIHNoYXBlIG1pcy1tYXRjaCBBTkQgbm90IGEgJ05vbmUnIGRpbWVuc2lvbi5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVPdXRwdXQob3V0cHV0VGVuc29yczogVGVuc29yW10pOiBNYXA8c3RyaW5nLCBUZW5zb3I+IHtcbiAgICBjb25zdCBtb2RlbE91dHB1dE5hbWVzID0gdGhpcy5fbW9kZWwuZ3JhcGguZ2V0T3V0cHV0TmFtZXMoKTtcbiAgICBpZiAob3V0cHV0VGVuc29ycy5sZW5ndGggIT09IG1vZGVsT3V0cHV0TmFtZXMubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2V4cGVjdGVkIG51bWJlciBvZiBvdXRwdXRzIGRvIG5vdCBtYXRjaCBudW1iZXIgb2YgZ2VuZXJhdGVkIG91dHB1dHMnKTtcbiAgICB9XG5cbiAgICBjb25zdCBvdXRwdXQgPSBuZXcgTWFwPHN0cmluZywgVGVuc29yPigpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbW9kZWxPdXRwdXROYW1lcy5sZW5ndGg7ICsraSkge1xuICAgICAgb3V0cHV0LnNldChtb2RlbE91dHB1dE5hbWVzW2ldLCBvdXRwdXRUZW5zb3JzW2ldKTtcbiAgICB9XG5cbiAgICByZXR1cm4gb3V0cHV0O1xuICB9XG5cbiAgcHJpdmF0ZSBpbml0aWFsaXplT3BzKGdyYXBoOiBHcmFwaCk6IHZvaWQge1xuICAgIGNvbnN0IG5vZGVzID0gZ3JhcGguZ2V0Tm9kZXMoKTtcbiAgICB0aGlzLl9vcHMgPSBuZXcgQXJyYXkobm9kZXMubGVuZ3RoKTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHRoaXMuX29wc1tpXSA9IHRoaXMuc2Vzc2lvbkhhbmRsZXIucmVzb2x2ZShub2Rlc1tpXSwgdGhpcy5fbW9kZWwub3BzZXRzLCBncmFwaCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfbW9kZWw6IE1vZGVsO1xuICBwcml2YXRlIF9pbml0aWFsaXplZDogYm9vbGVhbjtcblxuICBwcml2YXRlIF9vcHM6IE9wZXJhdG9yW107XG4gIHByaXZhdGUgX2V4ZWN1dGlvblBsYW46IEV4ZWN1dGlvblBsYW47XG5cbiAgcHJpdmF0ZSBiYWNrZW5kSGludD86IHN0cmluZztcblxuICBwcml2YXRlIHNlc3Npb25IYW5kbGVyOiBTZXNzaW9uSGFuZGxlclR5cGU7XG4gIHByaXZhdGUgY29udGV4dDogU2Vzc2lvbi5Db250ZXh0O1xuICBwcml2YXRlIHByb2ZpbGVyOiBSZWFkb25seTxQcm9maWxlcj47XG59XG4iLCIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtHdWlkfSBmcm9tICdndWlkLXR5cGVzY3JpcHQnO1xuaW1wb3J0IExvbmcgZnJvbSAnbG9uZyc7XG5pbXBvcnQge29ubnh9IGZyb20gJ29ubngtcHJvdG8nO1xuXG5pbXBvcnQge29ubnhydW50aW1lfSBmcm9tICcuL29ydC1zY2hlbWEvb3J0LWdlbmVyYXRlZCc7XG5pbXBvcnQge2RlY29kZVV0ZjhTdHJpbmcsIFByb3RvVXRpbCwgU2hhcGVVdGlsfSBmcm9tICcuL3V0aWwnO1xuXG5pbXBvcnQgb3J0RmJzID0gb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicztcblxuZXhwb3J0IGRlY2xhcmUgbmFtZXNwYWNlIFRlbnNvciB7XG4gIGV4cG9ydCBpbnRlcmZhY2UgRGF0YVR5cGVNYXAge1xuICAgIGJvb2w6IFVpbnQ4QXJyYXk7XG4gICAgZmxvYXQzMjogRmxvYXQzMkFycmF5O1xuICAgIGZsb2F0NjQ6IEZsb2F0NjRBcnJheTtcbiAgICBzdHJpbmc6IHN0cmluZ1tdO1xuICAgIGludDg6IEludDhBcnJheTtcbiAgICB1aW50ODogVWludDhBcnJheTtcbiAgICBpbnQxNjogSW50MTZBcnJheTtcbiAgICB1aW50MTY6IFVpbnQxNkFycmF5O1xuICAgIGludDMyOiBJbnQzMkFycmF5O1xuICAgIHVpbnQzMjogVWludDMyQXJyYXk7XG4gIH1cblxuICBleHBvcnQgdHlwZSBEYXRhVHlwZSA9IGtleW9mIERhdGFUeXBlTWFwO1xuXG4gIGV4cG9ydCB0eXBlIFN0cmluZ1R5cGUgPSBUZW5zb3IuRGF0YVR5cGVNYXBbJ3N0cmluZyddO1xuICBleHBvcnQgdHlwZSBCb29sZWFuVHlwZSA9IFRlbnNvci5EYXRhVHlwZU1hcFsnYm9vbCddO1xuICBleHBvcnQgdHlwZSBJbnRlZ2VyVHlwZSA9IFRlbnNvci5EYXRhVHlwZU1hcFsnaW50OCddfFRlbnNvci5EYXRhVHlwZU1hcFsndWludDgnXXxUZW5zb3IuRGF0YVR5cGVNYXBbJ2ludDE2J118XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgVGVuc29yLkRhdGFUeXBlTWFwWyd1aW50MTYnXXxUZW5zb3IuRGF0YVR5cGVNYXBbJ2ludDMyJ118VGVuc29yLkRhdGFUeXBlTWFwWyd1aW50MzInXTtcbiAgZXhwb3J0IHR5cGUgRmxvYXRUeXBlID0gVGVuc29yLkRhdGFUeXBlTWFwWydmbG9hdDMyJ118VGVuc29yLkRhdGFUeXBlTWFwWydmbG9hdDY0J107XG4gIGV4cG9ydCB0eXBlIE51bWJlclR5cGUgPSBCb29sZWFuVHlwZXxJbnRlZ2VyVHlwZXxGbG9hdFR5cGU7XG5cbiAgZXhwb3J0IHR5cGUgSWQgPSBHdWlkO1xufVxuXG50eXBlIFRlbnNvckRhdGEgPSBUZW5zb3IuRGF0YVR5cGVNYXBbVGVuc29yLkRhdGFUeXBlXTtcblxudHlwZSBEYXRhUHJvdmlkZXIgPSAoaWQ6IFRlbnNvci5JZCkgPT4gVGVuc29yRGF0YTtcbnR5cGUgQXN5bmNEYXRhUHJvdmlkZXIgPSAoaWQ6IFRlbnNvci5JZCkgPT4gUHJvbWlzZTxUZW5zb3JEYXRhPjtcblxuZXhwb3J0IGNsYXNzIFRlbnNvciB7XG4gIC8qKlxuICAgKiBnZXQgdGhlIHVuZGVybHlpbmcgdGVuc29yIGRhdGFcbiAgICovXG4gIGdldCBkYXRhKCk6IFRlbnNvckRhdGEge1xuICAgIGlmICh0aGlzLmNhY2hlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLmRhdGFQcm92aWRlciEodGhpcy5kYXRhSWQpO1xuICAgICAgaWYgKGRhdGEubGVuZ3RoICE9PSB0aGlzLnNpemUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdMZW5ndGggb2YgZGF0YSBwcm92aWRlZCBieSB0aGUgRGF0YSBQcm92aWRlciBpcyBpbmNvbnNpc3RlbnQgd2l0aCB0aGUgZGltcyBvZiB0aGlzIFRlbnNvci4nKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuY2FjaGUgPSBkYXRhO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jYWNoZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBnZXQgdGhlIHVuZGVybHlpbmcgc3RyaW5nIHRlbnNvciBkYXRhLiBTaG91bGQgb25seSB1c2Ugd2hlbiB0eXBlIGlzIFNUUklOR1xuICAgKi9cbiAgZ2V0IHN0cmluZ0RhdGEoKSB7XG4gICAgaWYgKHRoaXMudHlwZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2RhdGEgdHlwZSBpcyBub3Qgc3RyaW5nJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuZGF0YSBhcyBUZW5zb3IuU3RyaW5nVHlwZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBnZXQgdGhlIHVuZGVybHlpbmcgaW50ZWdlciB0ZW5zb3IgZGF0YS4gU2hvdWxkIG9ubHkgdXNlIHdoZW4gdHlwZSBpcyBvbmUgb2YgdGhlIGZvbGxvd2luZzogKFVJTlQ4LCBJTlQ4LCBVSU5UMTYsXG4gICAqIElOVDE2LCBJTlQzMiwgVUlOVDMyLCBCT09MKVxuICAgKi9cbiAgZ2V0IGludGVnZXJEYXRhKCkge1xuICAgIHN3aXRjaCAodGhpcy50eXBlKSB7XG4gICAgICBjYXNlICd1aW50OCc6XG4gICAgICBjYXNlICdpbnQ4JzpcbiAgICAgIGNhc2UgJ3VpbnQxNic6XG4gICAgICBjYXNlICdpbnQxNic6XG4gICAgICBjYXNlICdpbnQzMic6XG4gICAgICBjYXNlICd1aW50MzInOlxuICAgICAgY2FzZSAnYm9vbCc6XG4gICAgICAgIHJldHVybiB0aGlzLmRhdGEgYXMgVGVuc29yLkludGVnZXJUeXBlO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdkYXRhIHR5cGUgaXMgbm90IGludGVnZXIgKHVpbnQ4LCBpbnQ4LCB1aW50MTYsIGludDE2LCBpbnQzMiwgdWludDMyLCBib29sKScpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBnZXQgdGhlIHVuZGVybHlpbmcgZmxvYXQgdGVuc29yIGRhdGEuIFNob3VsZCBvbmx5IHVzZSB3aGVuIHR5cGUgaXMgb25lIG9mIHRoZSBmb2xsb3dpbmc6IChGTE9BVCwgRE9VQkxFKVxuICAgKi9cbiAgZ2V0IGZsb2F0RGF0YSgpIHtcbiAgICBzd2l0Y2ggKHRoaXMudHlwZSkge1xuICAgICAgY2FzZSAnZmxvYXQzMic6XG4gICAgICBjYXNlICdmbG9hdDY0JzpcbiAgICAgICAgcmV0dXJuIHRoaXMuZGF0YSBhcyBUZW5zb3IuRmxvYXRUeXBlO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdkYXRhIHR5cGUgaXMgbm90IGZsb2F0IChmbG9hdDMyLCBmbG9hdDY0KScpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBnZXQgdGhlIHVuZGVybHlpbmcgbnVtYmVyIHRlbnNvciBkYXRhLiBTaG91bGQgb25seSB1c2Ugd2hlbiB0eXBlIGlzIG9uZSBvZiB0aGUgZm9sbG93aW5nOiAoVUlOVDgsIElOVDgsIFVJTlQxNixcbiAgICogSU5UMTYsIElOVDMyLCBVSU5UMzIsIEJPT0wsIEZMT0FULCBET1VCTEUpXG4gICAqL1xuICBnZXQgbnVtYmVyRGF0YSgpIHtcbiAgICBpZiAodGhpcy50eXBlICE9PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIHRoaXMuZGF0YSBhcyBUZW5zb3IuTnVtYmVyVHlwZTtcbiAgICB9XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcigndHlwZSBjYW5ub3QgYmUgbm9uLW51bWJlciAoc3RyaW5nKScpO1xuICB9XG5cbiAgLyoqXG4gICAqIGdldCB2YWx1ZSBvZiBhbiBlbGVtZW50IGF0IHRoZSBnaXZlbiBpbmRpY2VzXG4gICAqL1xuICBnZXQoaW5kaWNlczogcmVhZG9ubHkgbnVtYmVyW10pOiBUZW5zb3IuRGF0YVR5cGVNYXBbVGVuc29yLkRhdGFUeXBlXVtudW1iZXJdIHtcbiAgICByZXR1cm4gdGhpcy5kYXRhW1NoYXBlVXRpbC5pbmRpY2VzVG9PZmZzZXQoaW5kaWNlcywgdGhpcy5zdHJpZGVzKV07XG4gIH1cblxuICAvKipcbiAgICogc2V0IHZhbHVlIG9mIGFuIGVsZW1lbnQgYXQgdGhlIGdpdmVuIGluZGljZXNcbiAgICovXG4gIHNldChpbmRpY2VzOiByZWFkb25seSBudW1iZXJbXSwgdmFsdWU6IFRlbnNvci5EYXRhVHlwZU1hcFtUZW5zb3IuRGF0YVR5cGVdW251bWJlcl0pIHtcbiAgICB0aGlzLmRhdGFbU2hhcGVVdGlsLmluZGljZXNUb09mZnNldChpbmRpY2VzLCB0aGlzLnN0cmlkZXMpXSA9IHZhbHVlO1xuICB9XG5cbiAgLyoqXG4gICAqIGdldCB0aGUgdW5kZXJseWluZyB0ZW5zb3IgZGF0YSBhc3luY2hyb25vdXNseVxuICAgKi9cbiAgYXN5bmMgZ2V0RGF0YSgpOiBQcm9taXNlPFRlbnNvckRhdGE+IHtcbiAgICBpZiAodGhpcy5jYWNoZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLmNhY2hlID0gYXdhaXQgdGhpcy5hc3luY0RhdGFQcm92aWRlciEodGhpcy5kYXRhSWQpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jYWNoZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBnZXQgdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGUgdGVuc29yXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgc2l6ZTogbnVtYmVyO1xuXG4gIHByaXZhdGUgX3N0cmlkZXM6IHJlYWRvbmx5IG51bWJlcltdO1xuICAvKipcbiAgICogZ2V0IHRoZSBzdHJpZGVzIGZvciBlYWNoIGRpbWVuc2lvblxuICAgKi9cbiAgZ2V0IHN0cmlkZXMoKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIGlmICghdGhpcy5fc3RyaWRlcykge1xuICAgICAgdGhpcy5fc3RyaWRlcyA9IFNoYXBlVXRpbC5jb21wdXRlU3RyaWRlcyh0aGlzLmRpbXMpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fc3RyaWRlcztcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKFxuICAgICAgLyoqXG4gICAgICAgKiBnZXQgdGhlIGRpbWVuc2lvbnMgb2YgdGhlIHRlbnNvclxuICAgICAgICovXG4gICAgICBwdWJsaWMgcmVhZG9ubHkgZGltczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgICAvKipcbiAgICAgICAqIGdldCB0aGUgdHlwZSBvZiB0aGUgdGVuc29yXG4gICAgICAgKi9cbiAgICAgIHB1YmxpYyByZWFkb25seSB0eXBlOiBUZW5zb3IuRGF0YVR5cGUsIHByaXZhdGUgZGF0YVByb3ZpZGVyPzogRGF0YVByb3ZpZGVyLFxuICAgICAgcHJpdmF0ZSBhc3luY0RhdGFQcm92aWRlcj86IEFzeW5jRGF0YVByb3ZpZGVyLCBwcml2YXRlIGNhY2hlPzogVGVuc29yRGF0YSxcbiAgICAgIC8qKlxuICAgICAgICogZ2V0IHRoZSBkYXRhIElEIHRoYXQgdXNlZCB0byBtYXAgdG8gYSB0ZW5zb3IgZGF0YVxuICAgICAgICovXG4gICAgICBwdWJsaWMgcmVhZG9ubHkgZGF0YUlkOiBHdWlkID0gR3VpZC5jcmVhdGUoKSkge1xuICAgIHRoaXMuc2l6ZSA9IFNoYXBlVXRpbC52YWxpZGF0ZURpbXNBbmRDYWxjU2l6ZShkaW1zKTtcbiAgICBjb25zdCBzaXplID0gdGhpcy5zaXplO1xuICAgIGNvbnN0IGVtcHR5ID0gKGRhdGFQcm92aWRlciA9PT0gdW5kZWZpbmVkICYmIGFzeW5jRGF0YVByb3ZpZGVyID09PSB1bmRlZmluZWQgJiYgY2FjaGUgPT09IHVuZGVmaW5lZCk7XG5cbiAgICBpZiAoY2FjaGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKGNhY2hlLmxlbmd0aCAhPT0gc2l6ZSkge1xuICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignSW5wdXQgZGltcyBkb2VzblxcJ3QgbWF0Y2ggZGF0YSBsZW5ndGguJyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICBpZiAoY2FjaGUgIT09IHVuZGVmaW5lZCAmJiAoIUFycmF5LmlzQXJyYXkoY2FjaGUpIHx8ICFjYWNoZS5ldmVyeShpID0+IHR5cGVvZiBpID09PSAnc3RyaW5nJykpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2NhY2hlIHNob3VsZCBiZSBhIHN0cmluZyBhcnJheScpO1xuICAgICAgfVxuXG4gICAgICBpZiAoZW1wdHkpIHtcbiAgICAgICAgdGhpcy5jYWNoZSA9IG5ldyBBcnJheTxzdHJpbmc+KHNpemUpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoY2FjaGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjb25zdCBjb25zdHJ1Y3RvciA9IGRhdGF2aWV3Q29uc3RydWN0b3IodHlwZSk7XG4gICAgICAgIGlmICghKGNhY2hlIGluc3RhbmNlb2YgY29uc3RydWN0b3IpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgY2FjaGUgc2hvdWxkIGJlIHR5cGUgJHtjb25zdHJ1Y3Rvci5uYW1lfWApO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChlbXB0eSkge1xuICAgICAgICBjb25zdCBidWYgPSBuZXcgQXJyYXlCdWZmZXIoc2l6ZSAqIHNpemVvZih0eXBlKSk7XG4gICAgICAgIHRoaXMuY2FjaGUgPSBjcmVhdGVWaWV3KGJ1ZiwgdHlwZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBuZXcgVGVuc29yIGZyb20gYSBPTk5YIFRlbnNvciBvYmplY3RcbiAgICogQHBhcmFtIHRlbnNvclByb3RvIHRoZSBPTk5YIFRlbnNvclxuICAgKi9cbiAgc3RhdGljIGZyb21Qcm90byh0ZW5zb3JQcm90bzogb25ueC5JVGVuc29yUHJvdG8pOiBUZW5zb3Ige1xuICAgIGlmICghdGVuc29yUHJvdG8pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignY2Fubm90IGNvbnN0cnVjdCBWYWx1ZSBmcm9tIGFuIGVtcHR5IHRlbnNvcicpO1xuICAgIH1cbiAgICBjb25zdCB0eXBlID0gUHJvdG9VdGlsLnRlbnNvckRhdGFUeXBlRnJvbVByb3RvKHRlbnNvclByb3RvLmRhdGFUeXBlISk7XG4gICAgY29uc3QgZGltcyA9IFByb3RvVXRpbC50ZW5zb3JEaW1zRnJvbVByb3RvKHRlbnNvclByb3RvLmRpbXMhKTtcblxuICAgIGNvbnN0IHZhbHVlID0gbmV3IFRlbnNvcihkaW1zLCB0eXBlKTtcblxuICAgIGlmICh0eXBlID09PSAnc3RyaW5nJykge1xuICAgICAgLy8gV2hlbiBpdCdzIFNUUklORyB0eXBlLCB0aGUgdmFsdWUgc2hvdWxkIGFsd2F5cyBiZSBzdG9yZWQgaW4gZmllbGRcbiAgICAgIC8vICdzdHJpbmdEYXRhJ1xuICAgICAgdGVuc29yUHJvdG8uc3RyaW5nRGF0YSEuZm9yRWFjaCgoc3RyLCBpKSA9PiB7XG4gICAgICAgIHZhbHVlLmRhdGFbaV0gPSBkZWNvZGVVdGY4U3RyaW5nKHN0cik7XG4gICAgICB9KTtcblxuICAgIH0gZWxzZSBpZiAoXG4gICAgICAgIHRlbnNvclByb3RvLnJhd0RhdGEgJiYgdHlwZW9mIHRlbnNvclByb3RvLnJhd0RhdGEuYnl0ZUxlbmd0aCA9PT0gJ251bWJlcicgJiZcbiAgICAgICAgdGVuc29yUHJvdG8ucmF3RGF0YS5ieXRlTGVuZ3RoID4gMCkge1xuICAgICAgLy8gTk9UIGNvbnNpZGVyaW5nIHNlZ21lbnQgZm9yIG5vdyAoSU1QT1JUQU5UKVxuXG4gICAgICAvLyBwb3B1bGF0ZSB2YWx1ZSBmcm9tIHJhd0RhdGFcbiAgICAgIGNvbnN0IGRhdGFEZXN0ID0gdmFsdWUuZGF0YTtcbiAgICAgIGNvbnN0IGRhdGFTb3VyY2UgPVxuICAgICAgICAgIG5ldyBEYXRhVmlldyh0ZW5zb3JQcm90by5yYXdEYXRhLmJ1ZmZlciwgdGVuc29yUHJvdG8ucmF3RGF0YS5ieXRlT2Zmc2V0LCB0ZW5zb3JQcm90by5yYXdEYXRhLmJ5dGVMZW5ndGgpO1xuICAgICAgY29uc3QgZWxlbWVudFNpemUgPSBzaXplb2ZQcm90byh0ZW5zb3JQcm90by5kYXRhVHlwZSEpO1xuICAgICAgY29uc3QgbGVuZ3RoID0gdGVuc29yUHJvdG8ucmF3RGF0YS5ieXRlTGVuZ3RoIC8gZWxlbWVudFNpemU7XG5cbiAgICAgIGlmICh0ZW5zb3JQcm90by5yYXdEYXRhLmJ5dGVMZW5ndGggJSBlbGVtZW50U2l6ZSAhPT0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgYnVmZmVyIGxlbmd0aCcpO1xuICAgICAgfVxuICAgICAgaWYgKGRhdGFEZXN0Lmxlbmd0aCAhPT0gbGVuZ3RoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignYnVmZmVyIGxlbmd0aCBtaXNtYXRjaCcpO1xuICAgICAgfVxuXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IG4gPSByZWFkUHJvdG8oZGF0YVNvdXJjZSwgdGVuc29yUHJvdG8uZGF0YVR5cGUhLCBpICogZWxlbWVudFNpemUpO1xuICAgICAgICBkYXRhRGVzdFtpXSA9IG47XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIHBvcHVsYXRlIHZhbHVlIGZyb20gYXJyYXlcbiAgICAgIGxldCBhcnJheTogQXJyYXk8bnVtYmVyfExvbmc+O1xuICAgICAgc3dpdGNoICh0ZW5zb3JQcm90by5kYXRhVHlwZSkge1xuICAgICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuRkxPQVQ6XG4gICAgICAgICAgYXJyYXkgPSB0ZW5zb3JQcm90by5mbG9hdERhdGEhO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UMzI6XG4gICAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQxNjpcbiAgICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQxNjpcbiAgICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDg6XG4gICAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UODpcbiAgICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLkJPT0w6XG4gICAgICAgICAgYXJyYXkgPSB0ZW5zb3JQcm90by5pbnQzMkRhdGEhO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UNjQ6XG4gICAgICAgICAgYXJyYXkgPSB0ZW5zb3JQcm90by5pbnQ2NERhdGEhO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuRE9VQkxFOlxuICAgICAgICAgIGFycmF5ID0gdGVuc29yUHJvdG8uZG91YmxlRGF0YSE7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UMzI6XG4gICAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UNjQ6XG4gICAgICAgICAgYXJyYXkgPSB0ZW5zb3JQcm90by51aW50NjREYXRhITtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAvLyBzaG91bGQgbmV2ZXIgcnVuIGhlcmVcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Vuc3BlY2lmaWMgZXJyb3InKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGFycmF5ID09PSBudWxsIHx8IGFycmF5ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdmYWlsZWQgdG8gcG9wdWxhdGUgZGF0YSBmcm9tIGEgdGVuc29ycHJvdG8gdmFsdWUnKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZGF0YSA9IHZhbHVlLmRhdGE7XG4gICAgICBpZiAoZGF0YS5sZW5ndGggIT09IGFycmF5Lmxlbmd0aCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2FycmF5IGxlbmd0aCBtaXNtYXRjaCcpO1xuICAgICAgfVxuXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGVsZW1lbnQgPSBhcnJheVtpXTtcbiAgICAgICAgaWYgKExvbmcuaXNMb25nKGVsZW1lbnQpKSB7XG4gICAgICAgICAgZGF0YVtpXSA9IGxvbmdUb051bWJlcihlbGVtZW50LCB0ZW5zb3JQcm90by5kYXRhVHlwZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZGF0YVtpXSA9IGVsZW1lbnQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICAvKipcbiAgICogQ29uc3RydWN0IG5ldyBUZW5zb3IgZnJvbSByYXcgZGF0YVxuICAgKiBAcGFyYW0gZGF0YSB0aGUgcmF3IGRhdGEgb2JqZWN0LiBTaG91bGQgYmUgYSBzdHJpbmcgYXJyYXkgZm9yICdzdHJpbmcnIHRlbnNvciwgYW5kIHRoZSBjb3JyZXNwb25kaW5nIHR5cGVkIGFycmF5XG4gICAqIGZvciBvdGhlciB0eXBlcyBvZiB0ZW5zb3IuXG4gICAqIEBwYXJhbSBkaW1zIHRoZSBkaW1lbnNpb25zIG9mIHRoZSB0ZW5zb3JcbiAgICogQHBhcmFtIHR5cGUgdGhlIHR5cGUgb2YgdGhlIHRlbnNvclxuICAgKi9cbiAgc3RhdGljIGZyb21EYXRhKGRhdGE6IFRlbnNvci5EYXRhVHlwZU1hcFtUZW5zb3IuRGF0YVR5cGVdLCBkaW1zOiByZWFkb25seSBudW1iZXJbXSwgdHlwZTogVGVuc29yLkRhdGFUeXBlKSB7XG4gICAgcmV0dXJuIG5ldyBUZW5zb3IoZGltcywgdHlwZSwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIGRhdGEpO1xuICB9XG5cbiAgc3RhdGljIGZyb21PcnRUZW5zb3Iob3J0VGVuc29yOiBvcnRGYnMuVGVuc29yKSB7XG4gICAgaWYgKCFvcnRUZW5zb3IpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignY2Fubm90IGNvbnN0cnVjdCBWYWx1ZSBmcm9tIGFuIGVtcHR5IHRlbnNvcicpO1xuICAgIH1cbiAgICBjb25zdCBkaW1zID0gUHJvdG9VdGlsLnRlbnNvckRpbXNGcm9tT1JURm9ybWF0KG9ydFRlbnNvcik7XG4gICAgY29uc3QgdHlwZSA9IFByb3RvVXRpbC50ZW5zb3JEYXRhVHlwZUZyb21Qcm90byhvcnRUZW5zb3IuZGF0YVR5cGUoKSk7XG5cbiAgICBjb25zdCB2YWx1ZSA9IG5ldyBUZW5zb3IoZGltcywgdHlwZSk7XG5cbiAgICBpZiAodHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIC8vIFdoZW4gaXQncyBTVFJJTkcgdHlwZSwgdGhlIHZhbHVlIHNob3VsZCBhbHdheXMgYmUgc3RvcmVkIGluIGZpZWxkXG4gICAgICAvLyAnc3RyaW5nRGF0YSdcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3J0VGVuc29yLnN0cmluZ0RhdGFMZW5ndGgoKTsgaSsrKSB7XG4gICAgICAgIHZhbHVlLmRhdGFbaV0gPSBvcnRUZW5zb3Iuc3RyaW5nRGF0YShpKTtcbiAgICAgIH1cblxuICAgIH0gZWxzZSBpZiAoXG4gICAgICAgIG9ydFRlbnNvci5yYXdEYXRhQXJyYXkoKSAmJiB0eXBlb2Ygb3J0VGVuc29yLnJhd0RhdGFMZW5ndGgoKSA9PT0gJ251bWJlcicgJiYgb3J0VGVuc29yLnJhd0RhdGFMZW5ndGgoKSA+IDApIHtcbiAgICAgIC8vIE5PVCBjb25zaWRlcmluZyBzZWdtZW50IGZvciBub3cgKElNUE9SVEFOVClcblxuICAgICAgLy8gcG9wdWxhdGUgdmFsdWUgZnJvbSByYXdEYXRhXG4gICAgICBjb25zdCBkYXRhRGVzdCA9IHZhbHVlLmRhdGE7XG4gICAgICBjb25zdCBkYXRhU291cmNlID0gbmV3IERhdGFWaWV3KFxuICAgICAgICAgIG9ydFRlbnNvci5yYXdEYXRhQXJyYXkoKSEuYnVmZmVyLCBvcnRUZW5zb3IucmF3RGF0YUFycmF5KCkhLmJ5dGVPZmZzZXQsIG9ydFRlbnNvci5yYXdEYXRhTGVuZ3RoKCkpO1xuICAgICAgY29uc3QgZWxlbWVudFNpemUgPSBzaXplb2ZQcm90byhvcnRUZW5zb3IuZGF0YVR5cGUoKSk7XG4gICAgICBjb25zdCBsZW5ndGggPSBvcnRUZW5zb3IucmF3RGF0YUxlbmd0aCgpIC8gZWxlbWVudFNpemU7XG5cbiAgICAgIGlmIChvcnRUZW5zb3IucmF3RGF0YUxlbmd0aCgpICUgZWxlbWVudFNpemUgIT09IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGJ1ZmZlciBsZW5ndGgnKTtcbiAgICAgIH1cbiAgICAgIGlmIChkYXRhRGVzdC5sZW5ndGggIT09IGxlbmd0aCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2J1ZmZlciBsZW5ndGggbWlzbWF0Y2gnKTtcbiAgICAgIH1cblxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBuID0gcmVhZFByb3RvKGRhdGFTb3VyY2UsIG9ydFRlbnNvci5kYXRhVHlwZSgpLCBpICogZWxlbWVudFNpemUpO1xuICAgICAgICBkYXRhRGVzdFtpXSA9IG47XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxufVxuXG5mdW5jdGlvbiBzaXplb2YodHlwZTogVGVuc29yLkRhdGFUeXBlKTogbnVtYmVyIHtcbiAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSAnYm9vbCc6XG4gICAgY2FzZSAnaW50OCc6XG4gICAgY2FzZSAndWludDgnOlxuICAgICAgcmV0dXJuIDE7XG4gICAgY2FzZSAnaW50MTYnOlxuICAgIGNhc2UgJ3VpbnQxNic6XG4gICAgICByZXR1cm4gMjtcbiAgICBjYXNlICdpbnQzMic6XG4gICAgY2FzZSAndWludDMyJzpcbiAgICBjYXNlICdmbG9hdDMyJzpcbiAgICAgIHJldHVybiA0O1xuICAgIGNhc2UgJ2Zsb2F0NjQnOlxuICAgICAgcmV0dXJuIDg7XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcihgY2Fubm90IGNhbGN1bGF0ZSBzaXplb2YoKSBvbiB0eXBlICR7dHlwZX1gKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBzaXplb2ZQcm90byh0eXBlOiBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlfG9ydEZicy5UZW5zb3JEYXRhVHlwZSk6IG51bWJlciB7XG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UODpcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UODpcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuQk9PTDpcbiAgICAgIHJldHVybiAxO1xuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UMTY6XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDE2OlxuICAgICAgcmV0dXJuIDI7XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLkZMT0FUOlxuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQzMjpcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDMyOlxuICAgICAgcmV0dXJuIDQ7XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDY0OlxuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5ET1VCTEU6XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQ2NDpcbiAgICAgIHJldHVybiA4O1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGNhbm5vdCBjYWxjdWxhdGUgc2l6ZW9mKCkgb24gdHlwZSAke29ubnguVGVuc29yUHJvdG8uRGF0YVR5cGVbdHlwZV19YCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlVmlldyhkYXRhQnVmZmVyOiBBcnJheUJ1ZmZlciwgdHlwZTogVGVuc29yLkRhdGFUeXBlKSB7XG4gIHJldHVybiBuZXcgKGRhdGF2aWV3Q29uc3RydWN0b3IodHlwZSkpKGRhdGFCdWZmZXIpO1xufVxuXG5mdW5jdGlvbiBkYXRhdmlld0NvbnN0cnVjdG9yKHR5cGU6IFRlbnNvci5EYXRhVHlwZSkge1xuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlICdib29sJzpcbiAgICBjYXNlICd1aW50OCc6XG4gICAgICByZXR1cm4gVWludDhBcnJheTtcbiAgICBjYXNlICdpbnQ4JzpcbiAgICAgIHJldHVybiBJbnQ4QXJyYXk7XG4gICAgY2FzZSAnaW50MTYnOlxuICAgICAgcmV0dXJuIEludDE2QXJyYXk7XG4gICAgY2FzZSAndWludDE2JzpcbiAgICAgIHJldHVybiBVaW50MTZBcnJheTtcbiAgICBjYXNlICdpbnQzMic6XG4gICAgICByZXR1cm4gSW50MzJBcnJheTtcbiAgICBjYXNlICd1aW50MzInOlxuICAgICAgcmV0dXJuIFVpbnQzMkFycmF5O1xuICAgIGNhc2UgJ2Zsb2F0MzInOlxuICAgICAgcmV0dXJuIEZsb2F0MzJBcnJheTtcbiAgICBjYXNlICdmbG9hdDY0JzpcbiAgICAgIHJldHVybiBGbG9hdDY0QXJyYXk7XG4gICAgZGVmYXVsdDpcbiAgICAgIC8vIHNob3VsZCBuZXZlciBydW4gdG8gaGVyZVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCd1bnNwZWNpZmllZCBlcnJvcicpO1xuICB9XG59XG5cbi8vIGNvbnZlcnQgYSBsb25nIG51bWJlciB0byBhIDMyLWJpdCBpbnRlZ2VyIChjYXN0LWRvd24pXG5mdW5jdGlvbiBsb25nVG9OdW1iZXIoaTogTG9uZywgdHlwZTogb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZXxvcnRGYnMuVGVuc29yRGF0YVR5cGUpOiBudW1iZXIge1xuICAvLyBJTlQ2NCwgVUlOVDMyLCBVSU5UNjRcbiAgaWYgKHR5cGUgPT09IG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UNjQgfHwgdHlwZSA9PT0gb3J0RmJzLlRlbnNvckRhdGFUeXBlLklOVDY0KSB7XG4gICAgaWYgKGkuZ3JlYXRlclRoYW5PckVxdWFsKDIxNDc0ODM2NDgpIHx8IGkubGVzc1RoYW4oLTIxNDc0ODM2NDgpKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnQ2NCBpcyBub3Qgc3VwcG9ydGVkJyk7XG4gICAgfVxuICB9IGVsc2UgaWYgKFxuICAgICAgdHlwZSA9PT0gb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UMzIgfHwgdHlwZSA9PT0gb3J0RmJzLlRlbnNvckRhdGFUeXBlLlVJTlQzMiB8fFxuICAgICAgdHlwZSA9PT0gb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UNjQgfHwgdHlwZSA9PT0gb3J0RmJzLlRlbnNvckRhdGFUeXBlLlVJTlQ2NCkge1xuICAgIGlmIChpLmdyZWF0ZXJUaGFuT3JFcXVhbCg0Mjk0OTY3Mjk2KSB8fCBpLmxlc3NUaGFuKDApKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCd1aW50NjQgaXMgbm90IHN1cHBvcnRlZCcpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBub3QgYSBMT05HIHR5cGU6ICR7b25ueC5UZW5zb3JQcm90by5EYXRhVHlwZVt0eXBlXX1gKTtcbiAgfVxuXG4gIHJldHVybiBpLnRvTnVtYmVyKCk7XG59XG5cbi8vIHJlYWQgb25lIHZhbHVlIGZyb20gVGVuc29yUHJvdG9cbmZ1bmN0aW9uIHJlYWRQcm90byh2aWV3OiBEYXRhVmlldywgdHlwZTogb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZXxvcnRGYnMuVGVuc29yRGF0YVR5cGUsIGJ5dGVPZmZzZXQ6IG51bWJlcik6IG51bWJlciB7XG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5CT09MOlxuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UODpcbiAgICAgIHJldHVybiB2aWV3LmdldFVpbnQ4KGJ5dGVPZmZzZXQpO1xuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQ4OlxuICAgICAgcmV0dXJuIHZpZXcuZ2V0SW50OChieXRlT2Zmc2V0KTtcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDE2OlxuICAgICAgcmV0dXJuIHZpZXcuZ2V0VWludDE2KGJ5dGVPZmZzZXQsIHRydWUpO1xuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQxNjpcbiAgICAgIHJldHVybiB2aWV3LmdldEludDE2KGJ5dGVPZmZzZXQsIHRydWUpO1xuICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5GTE9BVDpcbiAgICAgIHJldHVybiB2aWV3LmdldEZsb2F0MzIoYnl0ZU9mZnNldCwgdHJ1ZSk7XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDMyOlxuICAgICAgcmV0dXJuIHZpZXcuZ2V0SW50MzIoYnl0ZU9mZnNldCwgdHJ1ZSk7XG4gICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQzMjpcbiAgICAgIHJldHVybiB2aWV3LmdldFVpbnQzMihieXRlT2Zmc2V0LCB0cnVlKTtcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UNjQ6XG4gICAgICByZXR1cm4gbG9uZ1RvTnVtYmVyKFxuICAgICAgICAgIExvbmcuZnJvbUJpdHModmlldy5nZXRVaW50MzIoYnl0ZU9mZnNldCwgdHJ1ZSksIHZpZXcuZ2V0VWludDMyKGJ5dGVPZmZzZXQgKyA0LCB0cnVlKSwgZmFsc2UpLCB0eXBlKTtcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuRE9VQkxFOlxuICAgICAgcmV0dXJuIHZpZXcuZ2V0RmxvYXQ2NChieXRlT2Zmc2V0LCB0cnVlKTtcbiAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDY0OlxuICAgICAgcmV0dXJuIGxvbmdUb051bWJlcihcbiAgICAgICAgICBMb25nLmZyb21CaXRzKHZpZXcuZ2V0VWludDMyKGJ5dGVPZmZzZXQsIHRydWUpLCB2aWV3LmdldFVpbnQzMihieXRlT2Zmc2V0ICsgNCwgdHJ1ZSksIHRydWUpLCB0eXBlKTtcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBjYW5ub3QgcmVhZCBmcm9tIERhdGFWaWV3IGZvciB0eXBlICR7b25ueC5UZW5zb3JQcm90by5EYXRhVHlwZVt0eXBlXX1gKTtcbiAgfVxufVxuIiwiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7ZmxhdGJ1ZmZlcnN9IGZyb20gJ2ZsYXRidWZmZXJzJztcbmltcG9ydCBMb25nIGZyb20gJ2xvbmcnO1xuaW1wb3J0IHtvbm54fSBmcm9tICdvbm54LXByb3RvJztcblxuaW1wb3J0IHtHcmFwaH0gZnJvbSAnLi9ncmFwaCc7XG5pbXBvcnQge29ubnhydW50aW1lfSBmcm9tICcuL29ydC1zY2hlbWEvb3J0LWdlbmVyYXRlZCc7XG5pbXBvcnQge1RlbnNvcn0gZnJvbSAnLi90ZW5zb3InO1xuXG4vLyBjaGVjayB0aGUgaW5wdXRzIHNoYXBlIGJlZm9yZSBydW5uaW5nIGFuIE9QLlxuLy8gcmV0dXJuIHRydWUgd2hlbiB0aGUgaW5wdXRzIHBhc3MgdGhlIGNoZWNrXG4vLyByZXR1cm4gZmFsc2Ugd2hlbiB0aGUgaW5wdXRzIGRvIG5vdCBmaXQgdGhlIHJlcXVpcmVtZW50XG4vLyB0aHJvdyBleGNlcHRpb24gd2hlbiBmYXRhbCBlcnJvciBvciBub3QgaW1wbGVtZW50ZWRcbmV4cG9ydCBmdW5jdGlvbiBjaGVja0lucHV0c1NoYXBlKGlucHV0czogVGVuc29yW10sIC4uLmV4cGVjdGVkRGltZW5zaW9uczogbnVtYmVyW10pOiBib29sZWFuIHtcbiAgaWYgKCFpbnB1dHMgfHwgaW5wdXRzLmxlbmd0aCAhPT0gZXhwZWN0ZWREaW1lbnNpb25zLmxlbmd0aCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBmb3IgKGxldCBpID0gMDsgaSA8IGlucHV0cy5sZW5ndGg7IGkrKykge1xuICAgIGlmICghaW5wdXRzW2ldLmRpbXMgfHwgaW5wdXRzW2ldLmRpbXMubGVuZ3RoICE9PSBleHBlY3RlZERpbWVuc2lvbnNbaV0pIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbi8vIEV2YWx1YXRlcyB0aGUgZ2l2ZW4gZXhwcmVzc2lvbiBhbmQgYXNzZXJ0cyBlcnJvciBtZXNzYWdlIGlmIGNvbmRpdGlvbiBpcyB1bm1ldC5cbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnQoZXhwcjogYm9vbGVhbiwgbXNnOiAoKSA9PiBzdHJpbmcpIHtcbiAgaWYgKCFleHByKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKHR5cGVvZiBtc2cgPT09ICdzdHJpbmcnID8gbXNnIDogbXNnKCkpO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBBcnJheVV0aWwge1xuICAvKipcbiAgICogVmVyaWZpZXMgaWYgMiBpbnB1dCBhcnJheXMgY29udGFpbiB0aGUgc2FtZSBlbGVtZW50cy5cbiAgICogQHBhcmFtIG4xIEFycmF5IDFcbiAgICogQHBhcmFtIG4yIEFycmF5IDJcbiAgICogQHJldHVybnMgV2hldGhlciB0aGVzZSAyIGFyZSBlcXVhbFxuICAgKi9cbiAgc3RhdGljIGFycmF5c0VxdWFsKFxuICAgICAgbjE6IHJlYWRvbmx5IG51bWJlcltdfEludDhBcnJheXxVaW50OEFycmF5fEludDE2QXJyYXl8VWludDE2QXJyYXl8SW50MzJBcnJheXxVaW50MzJBcnJheXxVaW50OENsYW1wZWRBcnJheXxcbiAgICAgIEZsb2F0MzJBcnJheXxGbG9hdDY0QXJyYXksXG4gICAgICBuMjogcmVhZG9ubHkgbnVtYmVyW118SW50OEFycmF5fFVpbnQ4QXJyYXl8SW50MTZBcnJheXxVaW50MTZBcnJheXxJbnQzMkFycmF5fFVpbnQzMkFycmF5fFVpbnQ4Q2xhbXBlZEFycmF5fFxuICAgICAgRmxvYXQzMkFycmF5fEZsb2F0NjRBcnJheSkge1xuICAgIGlmIChuMS5sZW5ndGggIT09IG4yLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG4xLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAobjFbaV0gIT09IG4yW2ldKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIE1hdE11bFV0aWwge1xuICAvKipcbiAgICogRml4IHRoZSBpbnB1dCBzaGFwZXMgZm9yIE1hdE11bCBvcGVyYXRpb24gaWYgdGhleSBuZWVkIGZpeGluZ1xuICAgKiBAcGFyYW0gZGltc0EgVGhlIHNoYXBlIG9mIHRlbnNvciBBLiBTaG91bGQgYmUgYW4gYXJyYXkgb2YgcG9zaXRpdmUgaW50ZWdlcnNcbiAgICogQHBhcmFtIGRpbXNCIFRoZSBzaGFwZSBvZiB0ZW5zb3IgQi4gU2hvdWxkIGJlIGFuIGFycmF5IG9mIHBvc2l0aXZlIGludGVnZXJzXG4gICAqIEByZXR1cm5zIEEgdHVwbGUgY29udGFpbmluZyB0aGUgcHJlcHJvY2Vzc2VkIGlucHV0IHNoYXBlcyBhcyByZXF1aXJlZCBieSBPTk5YIHNwZWNpZmljYXRpb25zXG4gICAqL1xuICBzdGF0aWMgcHJlcHJvY2Vzc0lucHV0U2hhcGVzKGRpbXNBOiByZWFkb25seSBudW1iZXJbXSwgZGltc0I6IHJlYWRvbmx5IG51bWJlcltdKTpcbiAgICAgIFtyZWFkb25seSBudW1iZXJbXSwgcmVhZG9ubHkgbnVtYmVyW11dIHtcbiAgICAvLyBJZiB0aGUgZmlyc3QgYXJndW1lbnQgaXMgMS1ELCBpdCBpcyBwcm9tb3RlZCB0byBhIG1hdHJpeCBieSBwcmVwZW5kaW5nXG4gICAgLy8gYSAxIHRvIGl0cyBkaW1lbnNpb25zLiBBZnRlciBtYXRyaXggbXVsdGlwbGljYXRpb24gdGhlIHByZXBlbmRlZCAxIGlzXG4gICAgLy8gcmVtb3ZlZC5cbiAgICBjb25zdCBhID0gKGRpbXNBLmxlbmd0aCA9PT0gMSkgPyBbMSwgZGltc0FbMF1dIDogZGltc0E7XG5cbiAgICAvLyBJZiB0aGUgc2Vjb25kIGFyZ3VtZW50IGlzIDEtRCwgaXQgaXMgcHJvbW90ZWQgdG8gYSBtYXRyaXggYnkgYXBwZW5kaW5nXG4gICAgLy8gYSAxIHRvIGl0cyBkaW1lbnNpb25zLiBBZnRlciBtYXRyaXggbXVsdGlwbGljYXRpb24gdGhlIGFwcGVuZGVkIDEgaXNcbiAgICAvLyByZW1vdmVkLlxuICAgIGNvbnN0IGIgPSAoZGltc0IubGVuZ3RoID09PSAxKSA/IFtkaW1zQlswXSwgMV0gOiBkaW1zQjtcblxuICAgIHJldHVybiBbYSwgYl07XG4gIH1cblxuICAvKipcbiAgICogRml4IHRoZSBvdXRwdXQgc2hhcGUgY29tcHV0ZWQgZm9yIE1hdE11bCBvcGVyYXRpb24gaWYgaXQgbmVlZHMgZml4aW5nXG4gICAqIEBwYXJhbSBvdXRwdXRTaGFwZSBUaGUgY29tcHV0ZWQgb3V0cHV0U2hhcGUuIFNob3VsZCBiZSBhbiBhcnJheSAoYXRsZWFzdCBvZiBsZW5ndGggMikgb2YgcG9zaXRpdmUgaW50ZWdlcnMuXG4gICAqIFRoaXMgd2lsbCBiZSBtdXRhdGVkLlxuICAgKiBAcGFyYW0gYVJhbmsgVGhlIHJhbmsgb2YgdGVuc29yIEEuXG4gICAqIEBwYXJhbSBiUmFuayBUaGUgcmFuayBvZiB0ZW5zb3IgQi5cbiAgICovXG4gIHN0YXRpYyBwb3N0cHJvY2Vzc091dHB1dFNoYXBlKG91dHB1dFNoYXBlOiBudW1iZXJbXSwgYVJhbms6IG51bWJlciwgYlJhbms6IG51bWJlcikge1xuICAgIC8vIFJlbW92ZSBwcmVwZW5kZWQgZGltZW5zaW9uIGlmIGZpcnN0IGlucHV0IGlzIDFkXG4gICAgaWYgKGFSYW5rID09PSAxKSB7XG4gICAgICAvLyBvdXRwdXRTaGFwZSA9IG91dHB1dFNoYXBlLnNsaWNlKDAsIG91dHB1dFNoYXBlLmxlbmd0aCAtIDIpLmNvbmNhdChvdXRwdXRTaGFwZS5zbGljZShvdXRwdXRTaGFwZS5sZW5ndGggLSAxKSk7XG4gICAgICBvdXRwdXRTaGFwZS5zcGxpY2Uob3V0cHV0U2hhcGUubGVuZ3RoIC0gMiwgMSk7XG4gICAgfVxuICAgIC8vIFJlbW92ZSBhcHBlbmRlZCBkaW1lbnNpb24gaWYgc2Vjb25kIGlucHV0IGlzIDFkXG4gICAgaWYgKGJSYW5rID09PSAxKSB7XG4gICAgICBvdXRwdXRTaGFwZS5wb3AoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2FsY3VsYXRlIHRoZSBleHBlY3RlZCBzaGFwZSB3aGVuIG1hdHJpeCBtdWx0aXBsaWNhdGlvblxuICAgKiBAcGFyYW0gYSBUaGUgc2hhcGUgb2YgdGVuc29yIEEuIFNob3VsZCBiZSBhIHR1cGxlIG9mIDIgcG9zaXRpdmUgaW50ZWdlcnNcbiAgICogQHBhcmFtIGIgVGhlIHNoYXBlIG9mIHRlbnNvciBCLiBTaG91bGQgYmUgYSB0dXBsZSBvZiAyIHBvc2l0aXZlIGludGVnZXJzXG4gICAqIEByZXR1cm5zIFRoZSBleHBlY3RlZCBzaGFwZSBvZiB0aGUgcmVzdWx0LCBvciB1bmRlZmluZWQgaWYgTi9BXG4gICAqL1xuICBzdGF0aWMgY2FsY01hdE11bFNoYXBlKGE6IFtudW1iZXIsIG51bWJlcl0sIGI6IFtudW1iZXIsIG51bWJlcl0pOiBbbnVtYmVyLCBudW1iZXJdfHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIChhWzFdICE9PSBiWzBdKSA/IHVuZGVmaW5lZCA6IFthWzBdLCBiWzFdXTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgQnJvYWRjYXN0VXRpbCB7XG4gIC8qKlxuICAgKiBDYWxjdWxhdGUgdGhlIGV4cGVjdGVkIHNoYXBlIHdoZW4gYnJvYWRjYXN0aW5nIDIgdGVuc29yc1xuICAgKiBAcGFyYW0gYSBUaGUgc2hhcGUgb2YgdGVuc29yIEEuIFNob3VsZCBiZSBhbiBhcnJheSBvZiBwb3NpdGl2ZSBpbnRlZ2Vyc1xuICAgKiBAcGFyYW0gYiBUaGUgc2hhcGUgb2YgdGVuc29yIEIuIFNob3VsZCBiZSBhbiBhcnJheSBvZiBwb3NpdGl2ZSBpbnRlZ2Vyc1xuICAgKiBAcGFyYW0gaXNNYXRNdWwgV2hldGhlciB0aGUgb3BlcmF0aW9uIGlzIE1hdE11bFxuICAgKiBAcmV0dXJucyBUaGUgZXhwZWN0ZWQgc2hhcGUgb2YgdGhlIHJlc3VsdCwgb3IgdW5kZWZpbmVkIGlmIE4vQVxuICAgKi9cbiAgc3RhdGljIGNhbGNTaGFwZShhZGltczogcmVhZG9ubHkgbnVtYmVyW10sIGJkaW1zOiByZWFkb25seSBudW1iZXJbXSwgaXNNYXRNdWwgPSBmYWxzZSk6IHJlYWRvbmx5IG51bWJlcltdfHVuZGVmaW5lZCB7XG4gICAgY29uc3QgYXJhbmsgPSBhZGltcy5sZW5ndGg7XG4gICAgY29uc3QgYnJhbmsgPSBiZGltcy5sZW5ndGg7XG4gICAgaWYgKGFyYW5rID09PSAwKSB7XG4gICAgICByZXR1cm4gYmRpbXM7XG4gICAgfVxuICAgIGlmIChicmFuayA9PT0gMCkge1xuICAgICAgcmV0dXJuIGFkaW1zO1xuICAgIH1cbiAgICBjb25zdCBjcmFuayA9IE1hdGgubWF4KGFkaW1zLmxlbmd0aCwgYmRpbXMubGVuZ3RoKTtcbiAgICBjb25zdCBjZGltcyA9IG5ldyBBcnJheTxudW1iZXI+KGNyYW5rKTtcblxuICAgIC8vIGNhbGN1bGF0ZSB0aGUgbGFzdCAyIGRpbWVuc2lvbiBpZiBpdCBpcyBNYXRNdWxcbiAgICBpZiAoaXNNYXRNdWwpIHtcbiAgICAgIGlmIChhcmFuayA8IDIgfHwgYnJhbmsgPCAyKSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICBjb25zdCBjU2hhcGVNYXRNdWwgPVxuICAgICAgICAgIE1hdE11bFV0aWwuY2FsY01hdE11bFNoYXBlKFthZGltc1thcmFuayAtIDJdLCBhZGltc1thcmFuayAtIDFdXSwgW2JkaW1zW2JyYW5rIC0gMl0sIGJkaW1zW2JyYW5rIC0gMV1dKTtcbiAgICAgIGlmIChjU2hhcGVNYXRNdWwgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgW2NkaW1zW2NyYW5rIC0gMl0sIGNkaW1zW2NyYW5rIC0gMV1dID0gY1NoYXBlTWF0TXVsO1xuICAgIH1cblxuICAgIGZvciAobGV0IGkgPSBpc01hdE11bCA/IDMgOiAxOyBpIDw9IGNyYW5rOyBpKyspIHtcbiAgICAgIGNvbnN0IGFMZW4gPSBhcmFuayAtIGkgPCAwID8gMSA6IGFkaW1zW2FyYW5rIC0gaV07XG4gICAgICBjb25zdCBiTGVuID0gYnJhbmsgLSBpIDwgMCA/IDEgOiBiZGltc1ticmFuayAtIGldO1xuXG4gICAgICBpZiAoYUxlbiAhPT0gYkxlbiAmJiBhTGVuID4gMSAmJiBiTGVuID4gMSkge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgY2RpbXNbY3JhbmsgLSBpXSA9IE1hdGgubWF4KGFMZW4sIGJMZW4pO1xuICAgIH1cblxuICAgIHJldHVybiBjZGltcztcbiAgfVxuXG4gIC8qKlxuICAgKiBHaXZlbiB0aGUgaW5kaWNlcyBvZiBhIGJyb2FkY2FzdGVkIHRlbnNvciwgY2FsY3VsYXRlIHRoZSBvcmlnaW5hbCBpbmRpY2VzXG4gICAqIEBwYXJhbSBicm9hZGNhc3RlZEluZGljZXMgVGhlIGdpdmVuIGluZGljZXMgb2YgdGhlIGJyb2FkY2FzdGVkIHRlbnNvci5cbiAgICogQHBhcmFtIG9yaWdpbmFsU2hhcGUgVGhlIG9yaWdpbmFsIHNoYXBlIG9mIHRoZSB0ZW5zb3IgYmVmb3JlIGJyb2FkY2FzXG4gICAqIEByZXR1cm5zIFRoZSBjYWxjdWxhdGVkIGluZGljZXMgdGhhdCBtYXBzIHRvIHRoZSBvcmlnaW5hbCB0ZW5zb3IuXG4gICAqL1xuICBzdGF0aWMgaW5kZXgoYnJvYWRjYXN0ZWRJbmRpY2VzOiByZWFkb25seSBudW1iZXJbXSwgb3JpZ2luYWxTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10pOiBudW1iZXJbXSB7XG4gICAgLy8gTk9URSAxOiB3ZSBhc3N1bWUgdGhlIHBhcmFtZXRlciBicm9hZGNhc3RlZEluZGljZXMgaXMgdmFsaWQuIGllLiBpdCBzaG91bGQgaGF2ZSB0aGUgc2FtZVxuICAgIC8vIGxlbmd0aCBhcyB0aGUgYnJvYWRjYXN0ZWQgc2hhcGUsIGFuZCBmb3IgZWFjaCBkaW1lbnNpb24gdGhlIGluZGV4IHNob3VsZFxuICAgIC8vIG5vdCBiZSBvdXQgb2YgcmFuZ2UuXG4gICAgY29uc3Qgb3JpZ2luYWxJbmRpY2VzID0gbmV3IEFycmF5KG9yaWdpbmFsU2hhcGUubGVuZ3RoKTtcbiAgICBCcm9hZGNhc3RVdGlsLmZpbGxJbmRleChicm9hZGNhc3RlZEluZGljZXMsIG9yaWdpbmFsU2hhcGUsIG9yaWdpbmFsSW5kaWNlcyk7XG4gICAgcmV0dXJuIG9yaWdpbmFsSW5kaWNlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBHaXZlbiB0aGUgaW5kaWNlcyBvZiBhIGJyb2FkY2FzdGVkIHRlbnNvciwgY2FsY3VsYXRlIHRoZSBvcmlnaW5hbCBpbmRpY2VzXG4gICAqIEBwYXJhbSBicm9hZGNhc3RlZEluZGljZXMgVGhlIGdpdmVuIGluZGljZXMgb2YgdGhlIGJyb2FkY2FzdGVkIHRlbnNvci5cbiAgICogQHBhcmFtIG9yaWdpbmFsU2hhcGUgVGhlIG9yaWdpbmFsIHNoYXBlIG9mIHRoZSB0ZW5zb3IgYmVmb3JlIGJyb2FkY2FzdFxuICAgKiBAcGFyYW0gb3JpZ2luYWxJbmRpY2VzIFRoZSBtYXBwaW5nIG9mIGJyb2FkY2FzdGVkSW5kaWNlcyB0byB0aGUgb3JpZ2luYWxJbmRpY2VzIChvdXRwdXQgcGFyYW1ldGVyIC0gd2lsbCBiZVxuICAgKiAgICAgbXV0YXRlZCkuXG4gICAqL1xuICBzdGF0aWMgZmlsbEluZGV4KGJyb2FkY2FzdGVkSW5kaWNlczogcmVhZG9ubHkgbnVtYmVyW10sIG9yaWdpbmFsU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCBvcmlnaW5hbEluZGljZXM6IG51bWJlcltdKSB7XG4gICAgLy8gTk9URSAxOiB3ZSBhc3N1bWUgdGhlIHBhcmFtZXRlciBicm9hZGNhc3RlZEluZGljZXMgaXMgdmFsaWQuIGllLiBpdCBzaG91bGQgaGF2ZSB0aGUgc2FtZSBsZW5ndGggYXMgdGhlXG4gICAgLy8gYnJvYWRjYXN0ZWQgc2hhcGUsIGFuZCBmb3IgZWFjaCBkaW1lbnNpb24gdGhlIGluZGV4IHNob3VsZCBub3QgYmUgb3V0IG9mIHJhbmdlLlxuICAgIC8vIE5PVEUgMjogd2UgYXNzdW1lIHRoZSBwYXJhbWV0ZXIgb3JpZ2luYWxJbmRpY2VzIGhhcyB0aGUgc2FtZSBsZW5ndGggYXMgdGhlIG9yaWdpbmFsU2hhcGVcbiAgICBjb25zdCBkaW1PZmZzZXQgPSBicm9hZGNhc3RlZEluZGljZXMubGVuZ3RoIC0gb3JpZ2luYWxTaGFwZS5sZW5ndGg7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvcmlnaW5hbFNoYXBlLmxlbmd0aDsgaSsrKSB7XG4gICAgICBvcmlnaW5hbEluZGljZXNbaV0gPSBicm9hZGNhc3RlZEluZGljZXNbZGltT2Zmc2V0ICsgaV0gJSBvcmlnaW5hbFNoYXBlW2ldO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQZXJmb3JtIHRoZSBicm9hZGNhc3Rpbmcgb3BlcmF0aW9uIG9uIHRoZSBzcGVjaWZpYyBvcGVyYXRvclxuICAgKiBAcGFyYW0gYSBUaGUgaW5wdXQgdGVuc29yIEFcbiAgICogQHBhcmFtIGIgVGhlIGlucHV0IHRlbnNvciBCXG4gICAqIEBwYXJhbSBvcCBUaGUgb3BlcmF0b3IgbGFtYmRhIGZ1bmN0aW9uXG4gICAqIEBwYXJhbSBpbnBsYWNlIFdoZXRoZXIgdG8gd3JpdGUgdGhlIHJlc3VsdCBiYWNrIHRvIEEuXG4gICAqIEByZXR1cm5zIFRoZSByZXN1bHQgdGVuc29yLCBvciB1bmRlZmluZWQgaWYgaW5wdXQgbm90IGJyb2FkY2FzdGFibGUuXG4gICAqL1xuICBzdGF0aWMgY2FsYyhcbiAgICAgIGE6IFRlbnNvciwgYjogVGVuc29yLCBvcDogKGE6IHN0cmluZ3xudW1iZXIsIGI6IHN0cmluZ3xudW1iZXIpID0+IChzdHJpbmcgfCBudW1iZXIpLCBpbnBsYWNlOiBib29sZWFuLFxuICAgICAgcmVzdWx0VHlwZT86IFRlbnNvci5EYXRhVHlwZSk6IFRlbnNvcnx1bmRlZmluZWQge1xuICAgIGNvbnN0IG91dHB1dFNoYXBlID0gQnJvYWRjYXN0VXRpbC5jYWxjU2hhcGUoYS5kaW1zLCBiLmRpbXMpO1xuXG4gICAgaWYgKG91dHB1dFNoYXBlKSB7XG4gICAgICBpZiAoaW5wbGFjZSAmJiAhU2hhcGVVdGlsLmFyZUVxdWFsKG91dHB1dFNoYXBlLCBhLmRpbXMpKSB7XG4gICAgICAgIC8vIEIgaXMgbm90IGJyb2FkY2FzdGFibGUgdG8gQSwgZmFpbGVkIHRvIGNhbGN1bGF0ZSBpbnBsYWNlLlxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBzaXplID0gU2hhcGVVdGlsLnNpemUob3V0cHV0U2hhcGUpO1xuICAgICAgY29uc3QgYyA9IGlucGxhY2UgPyBhIDogbmV3IFRlbnNvcihvdXRwdXRTaGFwZSwgcmVzdWx0VHlwZSB8fCBhLnR5cGUpO1xuXG4gICAgICAvLyBib3RoIGlucHV0cyBhcmUgc2NhbGFyc1xuICAgICAgaWYgKG91dHB1dFNoYXBlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBjLnNldChbXSwgb3AoYS5nZXQoW10pLCBiLmdldChbXSkpKTtcbiAgICAgIH1cblxuICAgICAgLy8gYXRsZWFzdCBvbmUgaW5wdXQgaXMgYSBub24tc2NhbGFyXG4gICAgICBlbHNlIHtcbiAgICAgICAgY29uc3Qgb3V0cHV0SW5kaWNlcyA9IG5ldyBBcnJheTxudW1iZXI+KG91dHB1dFNoYXBlLmxlbmd0aCk7XG4gICAgICAgIGNvbnN0IG9yaWdpbmFsSW5kaWNlc0EgPSBuZXcgQXJyYXkoYS5kaW1zLmxlbmd0aCk7XG4gICAgICAgIGNvbnN0IG9yaWdpbmFsSW5kaWNlc0IgPSBuZXcgQXJyYXkoYi5kaW1zLmxlbmd0aCk7XG4gICAgICAgIGxldCB2YWxBOiBzdHJpbmd8bnVtYmVyID0gMDtcbiAgICAgICAgbGV0IHZhbEI6IHN0cmluZ3xudW1iZXIgPSAwO1xuICAgICAgICBsZXQgaXNBU2NhbGFyID0gZmFsc2U7XG4gICAgICAgIGxldCBpc0JTY2FsYXIgPSBmYWxzZTtcbiAgICAgICAgaWYgKGEuZGltcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICB2YWxBID0gYS5nZXQoW10pO1xuICAgICAgICAgIGlzQVNjYWxhciA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGIuZGltcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICB2YWxCID0gYi5nZXQoW10pO1xuICAgICAgICAgIGlzQlNjYWxhciA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHJlc3Q6IG51bWJlcjtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHtcbiAgICAgICAgICAvLyB0cmF2ZXJzYWwgaW5kaWNlc1xuICAgICAgICAgIHJlc3QgPSBpO1xuICAgICAgICAgIGZvciAobGV0IGogPSBvdXRwdXRTaGFwZS5sZW5ndGggLSAxOyBqID49IDA7IGotLSkge1xuICAgICAgICAgICAgb3V0cHV0SW5kaWNlc1tqXSA9IHJlc3QgJSBvdXRwdXRTaGFwZVtqXTtcbiAgICAgICAgICAgIHJlc3QgPSBNYXRoLmZsb29yKHJlc3QgLyBvdXRwdXRTaGFwZVtqXSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKCFpc0FTY2FsYXIpIHtcbiAgICAgICAgICAgIC8vIG1hcCBvdXRwdXRJbmRpY2VzICh3aGljaCBpcyBhY3R1YWxseSBicm9hZGNhc3RlZCkgdG8gdGhlIG9yaWdpbmFsSW5kaWNlc1xuICAgICAgICAgICAgQnJvYWRjYXN0VXRpbC5maWxsSW5kZXgob3V0cHV0SW5kaWNlcywgYS5kaW1zLCBvcmlnaW5hbEluZGljZXNBKTtcbiAgICAgICAgICAgIHZhbEEgPSBhLmdldChvcmlnaW5hbEluZGljZXNBKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCFpc0JTY2FsYXIpIHtcbiAgICAgICAgICAgIEJyb2FkY2FzdFV0aWwuZmlsbEluZGV4KG91dHB1dEluZGljZXMsIGIuZGltcywgb3JpZ2luYWxJbmRpY2VzQik7XG4gICAgICAgICAgICB2YWxCID0gYi5nZXQob3JpZ2luYWxJbmRpY2VzQik7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYy5zZXQob3V0cHV0SW5kaWNlcywgb3AodmFsQSwgdmFsQikpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBjO1xuICAgIH1cblxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICAvKipcbiAgICogRGV0ZXJtaW5lIGlmIGEgc2hhcGUgaXMgdW5pZGlyZWN0aW9uYWwgYnJvYWRjYXN0YWJsZSB0byBhbm90aGVyIHNoYXBlXG4gICAqIEBwYXJhbSBzaGFwZSBUaGUgaW5wdXQgc2hhcGVcbiAgICogQHBhcmFtIGZpbmFsU2hhcGUgVGhlIGRlc2lyZWQgc2hhcGUgYWZ0ZXIgYnJvYWRjYXN0aW5nXG4gICAqL1xuICBzdGF0aWMgaXNWYWxpZEJyb2FkY2FzdChzaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIGZpbmFsU2hhcGU6IHJlYWRvbmx5IG51bWJlcltdKTogYm9vbGVhbiB7XG4gICAgLy8gYWxpZ24gc2hhcGUgdG8gdGhlIHJpZ2h0XG4gICAgY29uc3QgaW5wdXRSYW5rID0gc2hhcGUubGVuZ3RoO1xuICAgIGNvbnN0IGZpbmFsUmFuayA9IGZpbmFsU2hhcGUubGVuZ3RoO1xuICAgIGlmIChpbnB1dFJhbmsgPiBmaW5hbFJhbmspIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgZm9yIChsZXQgaSA9IDE7IGkgPD0gaW5wdXRSYW5rOyBpKyspIHtcbiAgICAgIGlmIChzaGFwZVtpbnB1dFJhbmsgLSBpXSAhPT0gMSAmJiBzaGFwZVtpbnB1dFJhbmsgLSBpXSAhPT0gZmluYWxTaGFwZVtmaW5hbFJhbmsgLSBpXSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqXG4gICAqIERldGVybWluZSB0aGUgYnJvYWRjYXN0ZWQgZGltcyBpbiBpbnB1dCBzaGFwZSBiYXNlZCBvbiB0aGUgZ2l2ZW4gb3V0cHV0IHNoYXBlLlxuICAgKiBOb3RlIHRoYXQgdGhpcyBmdW5jdGlvbiBvbmx5IHJldHVybnMgdGhlIGJyb2FkY2FzdGVkIGRpbXMuXG4gICAqIEBwYXJhbSBpbnB1dFNoYXBlIFRoZSBpbnB1dCBzaGFwZVxuICAgKiBAcGFyYW0gb3V0cHV0U2hhcGUgVGhlIG91dHB1dCBzaGFwZVxuICAgKiBAcmV0dXJucyBUaGUgYnJvYWRjYXN0ZWQgZGltcyBpbiBpbnB1dCBzaGFwZS5cbiAgICovXG4gIHN0YXRpYyBnZXRCcm9hZGNhc3REaW1zKGlucHV0U2hhcGU6IHJlYWRvbmx5IG51bWJlcltdLCBvdXRwdXRTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10pOiBudW1iZXJbXSB7XG4gICAgY29uc3QgaW5SYW5rID0gaW5wdXRTaGFwZS5sZW5ndGg7XG4gICAgY29uc3QgZGltczogbnVtYmVyW10gPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGluUmFuazsgaSsrKSB7XG4gICAgICBjb25zdCBkaW0gPSBpblJhbmsgLSAxIC0gaTtcbiAgICAgIGNvbnN0IGEgPSBpbnB1dFNoYXBlW2RpbV0gfHwgMTtcbiAgICAgIGNvbnN0IGIgPSBvdXRwdXRTaGFwZVtvdXRwdXRTaGFwZS5sZW5ndGggLSAxIC0gaV0gfHwgMTtcbiAgICAgIGlmIChiID4gMSAmJiBhID09PSAxKSB7XG4gICAgICAgIGRpbXMudW5zaGlmdChkaW0pO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZGltcztcbiAgfVxufVxuXG4vLyBjb3B5IGFycmF5IGhlbHBlclxuLy8gbWltaWNzIG1lbWNweSBhcyBtdWNoIGFzIHBvc3NpYmxlXG5leHBvcnQgZnVuY3Rpb24gYXJyYXlDb3B5SGVscGVyKFxuICAgIHRhcmdldDogbnVtYmVyW118VGVuc29yLk51bWJlclR5cGUsIHNvdXJjZTogbnVtYmVyW118VGVuc29yLk51bWJlclR5cGUsIHRhcmdldEluZGV4OiBudW1iZXIsIHNvdXJjZUluZGV4OiBudW1iZXIsXG4gICAgYmxvY2tTaXplOiBudW1iZXIpIHtcbiAgaWYgKHNvdXJjZUluZGV4IDwgMCB8fCBzb3VyY2VJbmRleCA+PSBzb3VyY2UubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdzb3VyY2VJbmRleCBvdXQgb2YgYm91bmRzJyk7XG4gIH1cbiAgaWYgKHRhcmdldEluZGV4IDwgMCB8fCB0YXJnZXRJbmRleCA+PSB0YXJnZXQubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd0YXJnZXRJbmRleCBvdXQgb2YgYm91bmRzJyk7XG4gIH1cbiAgaWYgKHNvdXJjZUluZGV4ICsgYmxvY2tTaXplID4gc291cmNlLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBFcnJvcignc291cmNlIGluZGljZXMgdG8gYmUgY29waWVkIGFyZSBvdXRzaWRlIGJvdW5kcycpO1xuICB9XG4gIGlmICh0YXJnZXRJbmRleCArIGJsb2NrU2l6ZSA+IHRhcmdldC5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3RhcmdldCBhcnJheSBpcyB0b28gc21hbGwgdG8gaG9sZCByZXN1bHQnKTtcbiAgfVxuXG4gIGZvciAobGV0IG9mZnNldCA9IDA7IG9mZnNldCA8IGJsb2NrU2l6ZTsgb2Zmc2V0KyspIHtcbiAgICB0YXJnZXRbdGFyZ2V0SW5kZXggKyBvZmZzZXRdID0gc291cmNlW3NvdXJjZUluZGV4ICsgb2Zmc2V0XTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgR2VtbVV0aWwge1xuICAvLyB3aWxsIG1ha2Ugc3VyZSBpbnB1dCBzaGFwZXMgYXJlIGNvbXBhdGlibGUgZm9yIHRoaXMgb3BcbiAgLy8gYW5kIHJldHVybiBiYWNrIHRoZSBzaGFwZSBvZiB0aGUgb3V0cHV0IGluIHRoZSBmb3JtIG9mIGEgdHVwbGVcbiAgLy8gd2lsbCB0aHJvdyBleGNlcHRpb24gaWYgdGhlIGlucHV0IHNoYXBlcyBhcmUgbm90IGNvbXBhdGlibGVcbiAgc3RhdGljIGdldFNoYXBlT2ZHZW1tUmVzdWx0KFxuICAgICAgbGVmdFNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgdHJhbnNMZWZ0OiBib29sZWFuLCByaWdodFNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgdHJhbnNSaWdodDogYm9vbGVhbixcbiAgICAgIGJpYXNTaGFwZT86IHJlYWRvbmx5IG51bWJlcltdKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIGlmIChsZWZ0U2hhcGUubGVuZ3RoICE9PSAyIHx8IHJpZ2h0U2hhcGUubGVuZ3RoICE9PSAyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NoYXBlIG5lZWQgdG8gYmUgb2Ygc2l6ZSAyJyk7XG4gICAgfVxuXG4gICAgbGV0IE06IG51bWJlcjtcbiAgICBsZXQgSzogbnVtYmVyO1xuICAgIGxldCBOOiBudW1iZXI7XG5cbiAgICBpZiAodHJhbnNMZWZ0KSB7XG4gICAgICBNID0gbGVmdFNoYXBlWzFdO1xuICAgICAgSyA9IGxlZnRTaGFwZVswXTtcbiAgICB9IGVsc2Uge1xuICAgICAgTSA9IGxlZnRTaGFwZVswXTtcbiAgICAgIEsgPSBsZWZ0U2hhcGVbMV07XG4gICAgfVxuXG4gICAgbGV0IGtEaW0gPSAtMTtcblxuICAgIGlmICh0cmFuc1JpZ2h0KSB7XG4gICAgICBOID0gcmlnaHRTaGFwZVswXTtcbiAgICAgIGtEaW0gPSAxO1xuICAgIH0gZWxzZSB7XG4gICAgICBOID0gcmlnaHRTaGFwZVsxXTtcbiAgICAgIGtEaW0gPSAwO1xuICAgIH1cblxuICAgIGlmIChyaWdodFNoYXBlW2tEaW1dICE9PSBLKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2RpbWVuc2lvbiBtaXNtYXRjaCcpO1xuICAgIH1cblxuICAgIGlmIChNIDw9IDAgfHwgTiA8PSAwIHx8IEsgPD0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIHNoYXBlIHNwZWNpZmllZCcpO1xuICAgIH1cblxuICAgIGlmIChiaWFzU2hhcGUgJiYgIUJyb2FkY2FzdFV0aWwuaXNWYWxpZEJyb2FkY2FzdChiaWFzU2hhcGUsIFtNLCBOXSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignZ2VtbTogaW52YWxpZCBiaWFzIHNoYXBlIGZvciBicm9hZGNhc3QnKTtcbiAgICB9XG5cbiAgICByZXR1cm4gW00sIE4sIEtdO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBQcm90b1V0aWwge1xuICBzdGF0aWMgdGVuc29yRGF0YVR5cGVGcm9tUHJvdG8odHlwZVByb3RvOiBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlfFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5UZW5zb3JEYXRhVHlwZSk6IFRlbnNvci5EYXRhVHlwZSB7XG4gICAgc3dpdGNoICh0eXBlUHJvdG8pIHtcbiAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQ4OlxuICAgICAgICByZXR1cm4gJ2ludDgnO1xuICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQ4OlxuICAgICAgICByZXR1cm4gJ3VpbnQ4JztcbiAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5CT09MOlxuICAgICAgICByZXR1cm4gJ2Jvb2wnO1xuICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDE2OlxuICAgICAgICByZXR1cm4gJ2ludDE2JztcbiAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UMTY6XG4gICAgICAgIHJldHVybiAndWludDE2JztcbiAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQzMjpcbiAgICAgICAgcmV0dXJuICdpbnQzMic7XG4gICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuVUlOVDMyOlxuICAgICAgICByZXR1cm4gJ3VpbnQzMic7XG4gICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuRkxPQVQ6XG4gICAgICAgIHJldHVybiAnZmxvYXQzMic7XG4gICAgICBjYXNlIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuRE9VQkxFOlxuICAgICAgICByZXR1cm4gJ2Zsb2F0NjQnO1xuICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlNUUklORzpcbiAgICAgICAgcmV0dXJuICdzdHJpbmcnO1xuXG4gICAgICAvLyBGb3IgSU5UNjQvVUlOVDY0LCByZWR1Y2UgdGhlaXIgdmFsdWUgdG8gMzItYml0cy5cbiAgICAgIC8vIFNob3VsZCB0aHJvdyBleGNlcHRpb24gd2hlbiBvdmVyZmxvd1xuICAgICAgY2FzZSBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLklOVDY0OlxuICAgICAgICByZXR1cm4gJ2ludDMyJztcbiAgICAgIGNhc2Ugb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UNjQ6XG4gICAgICAgIHJldHVybiAndWludDMyJztcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bnN1cHBvcnRlZCBkYXRhIHR5cGU6ICR7b25ueC5UZW5zb3JQcm90by5EYXRhVHlwZVt0eXBlUHJvdG9dfWApO1xuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyB0ZW5zb3JEYXRhVHlwZVN0cmluZ1RvRW51bSh0eXBlOiBzdHJpbmcpOiBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlIHtcbiAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgIGNhc2UgJ2ludDgnOlxuICAgICAgICByZXR1cm4gb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQ4O1xuICAgICAgY2FzZSAndWludDgnOlxuICAgICAgICByZXR1cm4gb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UODtcbiAgICAgIGNhc2UgJ2Jvb2wnOlxuICAgICAgICByZXR1cm4gb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5CT09MO1xuICAgICAgY2FzZSAnaW50MTYnOlxuICAgICAgICByZXR1cm4gb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQxNjtcbiAgICAgIGNhc2UgJ3VpbnQxNic6XG4gICAgICAgIHJldHVybiBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQxNjtcbiAgICAgIGNhc2UgJ2ludDMyJzpcbiAgICAgICAgcmV0dXJuIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuSU5UMzI7XG4gICAgICBjYXNlICd1aW50MzInOlxuICAgICAgICByZXR1cm4gb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5VSU5UMzI7XG4gICAgICBjYXNlICdmbG9hdDMyJzpcbiAgICAgICAgcmV0dXJuIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuRkxPQVQ7XG4gICAgICBjYXNlICdmbG9hdDY0JzpcbiAgICAgICAgcmV0dXJuIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuRE9VQkxFO1xuICAgICAgY2FzZSAnc3RyaW5nJzpcbiAgICAgICAgcmV0dXJuIG9ubnguVGVuc29yUHJvdG8uRGF0YVR5cGUuU1RSSU5HO1xuICAgICAgY2FzZSAnaW50NjQnOlxuICAgICAgICByZXR1cm4gb25ueC5UZW5zb3JQcm90by5EYXRhVHlwZS5JTlQ2NDtcbiAgICAgIGNhc2UgJ3VpbnQ2NCc6XG4gICAgICAgIHJldHVybiBvbm54LlRlbnNvclByb3RvLkRhdGFUeXBlLlVJTlQ2NDtcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bnN1cHBvcnRlZCBkYXRhIHR5cGU6ICR7dHlwZX1gKTtcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgdGVuc29yRGltc0Zyb21Qcm90byhkaW1zOiBBcnJheTxudW1iZXJ8TG9uZz4pOiBudW1iZXJbXSB7XG4gICAgLy8gZ2V0IHJpZCBvZiBMb25nIHR5cGUgZm9yIGRpbXNcbiAgICByZXR1cm4gZGltcy5tYXAoZCA9PiBMb25nLmlzTG9uZyhkKSA/IGQudG9OdW1iZXIoKSA6IGQpO1xuICB9XG5cbiAgc3RhdGljIHRlbnNvclZhbHVlVHlwZUZyb21Qcm90byh2YWx1ZVR5cGU6IG9ubnguVHlwZVByb3RvLklUZW5zb3IpOiBHcmFwaC5WYWx1ZVR5cGUge1xuICAgIHJldHVybiB7XG4gICAgICB0ZW5zb3JUeXBlOiBQcm90b1V0aWwudGVuc29yRGF0YVR5cGVGcm9tUHJvdG8odmFsdWVUeXBlLmVsZW1UeXBlISksXG4gICAgICBzaGFwZToge2RpbXM6IFByb3RvVXRpbC50ZW5zb3JEaW1zRnJvbVByb3RvKHZhbHVlVHlwZS5zaGFwZSEuZGltIS5tYXAoZCA9PiBkLmRpbVZhbHVlISkpfVxuICAgIH07XG4gIH1cblxuICBzdGF0aWMgdGVuc29yRGltc0Zyb21PUlRGb3JtYXQodGVuc29yOiBvbm54cnVudGltZS5leHBlcmltZW50YWwuZmJzLlRlbnNvcikge1xuICAgIGNvbnN0IGRpbXMgPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRlbnNvci5kaW1zTGVuZ3RoKCk7IGkrKykge1xuICAgICAgZGltcy5wdXNoKExvbmdVdGlsLmxvbmdUb051bWJlcih0ZW5zb3IuZGltcyhpKSEpKTtcbiAgICB9XG4gICAgcmV0dXJuIGRpbXM7XG4gIH1cblxuICBzdGF0aWMgdGVuc29yQXR0cmlidXRlc0Zyb21PUlRGb3JtYXQobm9kZTogb25ueHJ1bnRpbWUuZXhwZXJpbWVudGFsLmZicy5Ob2RlKSB7XG4gICAgY29uc3QgYXR0cmlidXRlcyA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbm9kZS5hdHRyaWJ1dGVzTGVuZ3RoKCk7IGkrKykge1xuICAgICAgYXR0cmlidXRlcy5wdXNoKG5vZGUuYXR0cmlidXRlcyhpKSEpO1xuICAgIH1cbiAgICByZXR1cm4gYXR0cmlidXRlcztcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgTG9uZ1V0aWwge1xuICAvLyBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCB0byBnZXQgYSBudW1iZXIgZnJvbSBsb25nIHR5cGUgb2YgZGF0YSBmb3IgYXR0cmlidXRlLCBkaW0sIGFuZCBpciB2ZXJzaW9uLFxuICAvLyB3aGljaCB2YWx1ZXMgYXJlIHNpZ25lZCBpbnRlZ2Vycy5cbiAgLy8gVG8gbWFrZSBpdCBtb3JlIGdlbmVyaWMsIGFkZCBhbiBvcHRpb25hbCBwYXJhbXRlciB0byBjb252ZXJ0IHRvIGEgdW5zaWduZWQgbnVtYmVyLlxuICBzdGF0aWMgbG9uZ1RvTnVtYmVyKG46IExvbmd8ZmxhdGJ1ZmZlcnMuTG9uZ3xudW1iZXIsIHVuc2lnbmVkPzogYm9vbGVhbikge1xuICAgIGlmIChMb25nLmlzTG9uZyhuKSkge1xuICAgICAgcmV0dXJuIG4udG9OdW1iZXIoKTtcbiAgICB9IGVsc2UgaWYgKG4gaW5zdGFuY2VvZiBmbGF0YnVmZmVycy5Mb25nKSB7XG4gICAgICByZXR1cm4gTG9uZy5mcm9tVmFsdWUoe2xvdzogbi5sb3csIGhpZ2g6IG4uaGlnaCwgdW5zaWduZWQ6IHVuc2lnbmVkID8/IGZhbHNlfSkudG9OdW1iZXIoKTtcbiAgICB9XG4gICAgcmV0dXJuIG47XG4gIH1cbiAgc3RhdGljIGlzTG9uZyhuOiB1bmtub3duKSB7XG4gICAgcmV0dXJuIExvbmcuaXNMb25nKG4pIHx8IG4gaW5zdGFuY2VvZiBmbGF0YnVmZmVycy5Mb25nO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBTaGFwZVV0aWwge1xuICBzdGF0aWMgc2l6ZShkaW1zOiByZWFkb25seSBudW1iZXJbXSk6IG51bWJlciB7XG4gICAgcmV0dXJuIFNoYXBlVXRpbC5nZXRTaXplRnJvbURpbWVuc2lvblJhbmdlKGRpbXMsIDAsIGRpbXMubGVuZ3RoKTtcbiAgfVxuXG4gIC8vIGBheGlzYCBpbmNsdXNpdmVcbiAgc3RhdGljIHNpemVGcm9tRGltZW5zaW9uKGRpbXM6IHJlYWRvbmx5IG51bWJlcltdLCBheGlzOiBudW1iZXIpOiBudW1iZXIge1xuICAgIGlmIChheGlzIDwgMCB8fCBheGlzID4gZGltcy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgaW52YWxpZCBkaW1lbnNpb24gb2YgJHtheGlzfSBmb3Igc2l6ZUZyb21EaW1lbnNpb24gYXMgVGVuc29yIGhhcyAke2RpbXMubGVuZ3RofSBkaW1lbnNpb25zLmApO1xuICAgIH1cbiAgICByZXR1cm4gU2hhcGVVdGlsLmdldFNpemVGcm9tRGltZW5zaW9uUmFuZ2UoZGltcywgYXhpcywgZGltcy5sZW5ndGgpO1xuICB9XG5cbiAgLy8gYGF4aXNgIGV4Y2x1c2l2ZVxuICBzdGF0aWMgc2l6ZVRvRGltZW5zaW9uKGRpbXM6IHJlYWRvbmx5IG51bWJlcltdLCBheGlzOiBudW1iZXIpOiBudW1iZXIge1xuICAgIGlmIChheGlzIDwgMCB8fCBheGlzID4gZGltcy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgaW52YWxpZCBkaW1lbnNpb24gb2YgJHtheGlzfSBmb3Igc2l6ZVRvRGltZW5zaW9uIGFzIFRlbnNvciBoYXMgJHtkaW1zLmxlbmd0aH0gZGltZW5zaW9ucy5gKTtcbiAgICB9XG4gICAgcmV0dXJuIFNoYXBlVXRpbC5nZXRTaXplRnJvbURpbWVuc2lvblJhbmdlKGRpbXMsIDAsIGF4aXMpO1xuICB9XG5cbiAgc3RhdGljIGdldFNpemVGcm9tRGltZW5zaW9uUmFuZ2UoZGltczogcmVhZG9ubHkgbnVtYmVyW10sIHN0YXJ0OiBudW1iZXIsIGVuZDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBsZXQgc2l6ZSA9IDE7XG4gICAgZm9yIChsZXQgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHtcbiAgICAgIC8vIHNhZmV0eSBjaGVjayBhcyB0aGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgbXVsdGlwbGUgb3RoZXIgbWV0aG9kcyByZXF1aXJpbmcgc2l6ZS5cbiAgICAgIC8vIHNpemUgY2Fubm90IGJlIDAgb3IgbmVnYXRpdmUuXG4gICAgICBpZiAoZGltc1tpXSA8PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBtYXgtbGVuXG4gICAgICAgICAgICAnY2Fubm90IGdldCB2YWxpZCBzaXplIGZyb20gc3BlY2lmaWVkIGRpbWVuc2lvbiByYW5nZS4gTW9zdCBsaWtlbHkgdGhlIHJhbmdlIGNvbnRhaW5zIDAgb3IgbmVnYXRpdmUgdmFsdWVzIGluIHRoZW0uJyk7XG4gICAgICB9XG4gICAgICBzaXplICo9IGRpbXNbaV07XG4gICAgfVxuICAgIHJldHVybiBzaXplO1xuICB9XG5cbiAgc3RhdGljIGNvbXB1dGVTdHJpZGVzKGRpbXM6IHJlYWRvbmx5IG51bWJlcltdKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIGNvbnN0IHJhbmsgPSBkaW1zLmxlbmd0aDtcbiAgICBpZiAocmFuayA9PT0gMCkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH0gZWxzZSBpZiAocmFuayA9PT0gMSkge1xuICAgICAgcmV0dXJuIFsxXTtcbiAgICB9XG4gICAgY29uc3Qgc3RyaWRlcyA9IG5ldyBBcnJheShyYW5rKTtcbiAgICBzdHJpZGVzW3JhbmsgLSAxXSA9IDE7XG4gICAgc3RyaWRlc1tyYW5rIC0gMl0gPSBkaW1zW3JhbmsgLSAxXTtcbiAgICBmb3IgKGxldCBpID0gcmFuayAtIDM7IGkgPj0gMDsgLS1pKSB7XG4gICAgICBzdHJpZGVzW2ldID0gc3RyaWRlc1tpICsgMV0gKiBkaW1zW2kgKyAxXTtcbiAgICB9XG4gICAgcmV0dXJuIHN0cmlkZXM7XG4gIH1cblxuICBzdGF0aWMgdHJhbnNwb3NlKGRpbXM6IHJlYWRvbmx5IG51bWJlcltdKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIGNvbnN0IGNvcHkgPSBkaW1zLnNsaWNlKCk7XG4gICAgcmV0dXJuIGNvcHkucmV2ZXJzZSgpO1xuICB9XG5cbiAgc3RhdGljIGluZGljZXNUb09mZnNldChpbmRpY2VzOiByZWFkb25seSBudW1iZXJbXSwgc3RyaWRlczogcmVhZG9ubHkgbnVtYmVyW10sIGF4aXM/OiBudW1iZXIpOiBudW1iZXIge1xuICAgIGlmIChheGlzID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGF4aXMgPSBpbmRpY2VzLmxlbmd0aDtcbiAgICB9XG4gICAgbGV0IG9mZnNldCA9IDA7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBheGlzOyArK2kpIHtcbiAgICAgIG9mZnNldCArPSBzdHJpZGVzW2ldICogaW5kaWNlc1tpXTtcbiAgICB9XG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxuXG4gIHN0YXRpYyBvZmZzZXRUb0luZGljZXMob2Zmc2V0OiBudW1iZXIsIHN0cmlkZXM6IHJlYWRvbmx5IG51bWJlcltdKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIGNvbnN0IHJhbmsgPSBzdHJpZGVzLmxlbmd0aDtcbiAgICBpZiAocmFuayA9PT0gMCkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH0gZWxzZSBpZiAocmFuayA9PT0gMSkge1xuICAgICAgcmV0dXJuIFtvZmZzZXQgKiBzdHJpZGVzWzBdXTtcbiAgICB9XG4gICAgY29uc3QgaW5kaWNlczogbnVtYmVyW10gPSBuZXcgQXJyYXkoc3RyaWRlcy5sZW5ndGgpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5kaWNlcy5sZW5ndGggLSAxOyArK2kpIHtcbiAgICAgIGluZGljZXNbaV0gPSBNYXRoLmZsb29yKG9mZnNldCAvIHN0cmlkZXNbaV0pO1xuICAgICAgb2Zmc2V0IC09IGluZGljZXNbaV0gKiBzdHJpZGVzW2ldO1xuICAgIH1cbiAgICBpbmRpY2VzW2luZGljZXMubGVuZ3RoIC0gMV0gPSBvZmZzZXQ7XG4gICAgcmV0dXJuIGluZGljZXM7XG4gIH1cblxuICAvKipcbiAgICogbm9ybWFpbHplIGF4aXMgb2YgcmFuZ2UgWy1yLCByKSBpbnRvIFswLCByKS5cbiAgICovXG4gIHN0YXRpYyBub3JtYWxpemVBeGlzKGF4aXM6IG51bWJlciwgdGVuc29yUmFuazogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBpZiAoYXhpcyA8IC10ZW5zb3JSYW5rICYmIGF4aXMgPj0gdGVuc29yUmFuaykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd1bnN1cHBvcnRlZCBheGlzIGZvciB0aGlzIG9wZXJhdGlvbi4nKTtcbiAgICB9XG4gICAgcmV0dXJuIGF4aXMgPCAwID8gYXhpcyArIHRlbnNvclJhbmsgOiBheGlzO1xuICB9XG5cbiAgc3RhdGljIG5vcm1hbGl6ZUF4ZXMoYXhlczogcmVhZG9ubHkgbnVtYmVyW10sIHRlbnNvclJhbms6IG51bWJlcik6IG51bWJlcltdIHtcbiAgICByZXR1cm4gYXhlcy5tYXAoeCA9PiB0aGlzLm5vcm1hbGl6ZUF4aXMoeCwgdGVuc29yUmFuaykpO1xuICB9XG5cbiAgLy8gSW5jcmVtZW50IGFuIGluZGV4IGludG8gYSB0ZW5zb3IgKGluIGxleGljb2dyYXBoaWNcbiAgLy8gb3JkZXJpbmcpLCB3cmFwcGluZyBhcm91bmQgdGhlIHNwZWNpZmllZCB1cHBlcl9ib3VuZC5cbiAgLyoqXG4gICAqIEluY3JlbWVudCBhbiBpbmRleCBpbnRvIGEgdGVuc29yIChpbiBsZXhpY29ncmFwaGljIG9yZGVyaW5nKSwgd3JhcHBpbmcgYXJvdW5kIHRoZSBzcGVjaWZpZWQgdXBwZXJfYm91bmQuXG4gICAqIEBwYXJhbSBpbmRleCBHaXZlbiBpbmRleCB0byBpbmNyZW1lbnQgKFdpbGwgYmUgbXV0YXRlZClcbiAgICogQHBhcmFtIGRpbXMgVGhlIGRpbWVuc2lvbnMgb2YgdGhlIHRlbnNvciBmb3Igd2hpY2ggdGhlIGdpdmVuIGluZGV4IGNvcnJlc3BvbmRzIHRvXG4gICAqIEBwYXJhbSBheGlzVG9JbmNyZW1lbnRPbiBUaGUgMS1pbmRleGVkIGF4aXMgdG8gaW5jcmVtZW50IG9uLiBJZiB1bmRlZmluZWQsIGF4aXNUb0luY3JlbWVudE9uID09IHJhbmtcbiAgICovXG4gIHN0YXRpYyBpbmNyZW1lbnRJbmRleChpbmRleDogbnVtYmVyW10sIGRpbXM6IHJlYWRvbmx5IG51bWJlcltdLCBheGlzVG9JbmNyZW1lbnRPbj86IG51bWJlcikge1xuICAgIGlmIChkaW1zLmxlbmd0aCA9PT0gMCB8fCBpbmRleC5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW5kZXggaW5jcmVtZW50aW5nIHVuc3VwcG9ydGVkIGZvciBzY2FsYXIgVGVuc29yJyk7XG4gICAgfVxuICAgIGlmIChheGlzVG9JbmNyZW1lbnRPbiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBheGlzVG9JbmNyZW1lbnRPbiA9IGRpbXMubGVuZ3RoO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoYXhpc1RvSW5jcmVtZW50T24gPD0gMCB8fCBheGlzVG9JbmNyZW1lbnRPbiA+IGRpbXMubGVuZ3RoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW5jb3JyZWN0IGF4aXMgdG8gaW5jcmVtZW50IG9uJyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChsZXQgayA9IGF4aXNUb0luY3JlbWVudE9uIC0gMTsgayA+PSAwOyAtLWspIHtcbiAgICAgIGluZGV4W2tdKys7XG4gICAgICBpZiAoaW5kZXhba10gPCBkaW1zW2tdKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgaW5kZXhba10gPSAwO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQcm9kdWNlcyBhIG5ldyBkaW1lbnNpb25zIGFycmF5IGJhc2VkIG9uIHRoZSB2YWx1ZXMgaW4gdGhlICdvcmlnaW5hbERpbWVuc2lvbnMnIGFuZCAnc2hhcGUnIGFycmF5XG4gICAqIFVzZWQgaW4gUmVzaGFwZVxuICAgKiBAcGFyYW0gb3JpZ2luYWxEaW1zIE9yaWdpbmFsIFNoYXBlIGFycmF5XG4gICAqIEBwYXJhbSBzaGFwZUhpbnRzIGFycmF5IGNvbnRhaW5pbmcgdmFsdWVzIHRvIGNvbXB1dGUgdGhlIG5ldyBkaW1lbnNpb25zXG4gICAqIEZvciBleGFtcGxlOlxuICAgKiBvcmlnaW5hbERpbXMgPSBbMiwyXSBhbmQgc2hhcGVIaW50cyA9IFswLC0xXSB3aWxsIHJldHVybiBbMiwyXVxuICAgKiBvcmlnaW5hbERpbXMgPSBbMiwyXSBhbmQgc2hhcGVIaW50cyA9IFs0XSB3aWxsIHJldHVybiBbNF1cbiAgICogb3JpZ2luYWxEaW1zID0gWzIsMl0gYW5kIHNoYXBlSGludHMgPSBbNV0gd2lsbCB0aHJvdyBhbiBleGNlcHRpb25cbiAgICogaHR0cHM6Ly9naXRodWIuY29tL29ubngvb25ueC9ibG9iL21haW4vZG9jcy9PcGVyYXRvcnMubWQjUmVzaGFwZVxuICAgKi9cblxuICBzdGF0aWMgY2FsY3VsYXRlUmVzaGFwZWREaW1zKG9yaWdpbmFsRGltczogcmVhZG9ubHkgbnVtYmVyW10sIHNoYXBlSGludHM6IEFycmF5TGlrZTxudW1iZXI+KTogbnVtYmVyW10ge1xuICAgIC8vIHJlc2hhcGUgdG8gYSBTY2FsYXIgVGVuc29yXG4gICAgaWYgKHNoYXBlSGludHMubGVuZ3RoID09PSAwKSB7XG4gICAgICBpZiAob3JpZ2luYWxEaW1zLmxlbmd0aCA9PT0gMCB8fCBTaGFwZVV0aWwuc2l6ZShvcmlnaW5hbERpbXMpID09PSAxKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignY2Fubm90IHJlc2hhcGUgdG8gYSBzY2FsYXIgVGVuc29yJyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgbkRpbXMgPSBzaGFwZUhpbnRzLmxlbmd0aDtcbiAgICBjb25zdCByZXNoYXBlZERpbXMgPSBuZXcgQXJyYXk8bnVtYmVyPihuRGltcyk7XG4gICAgbGV0IHVua25vd25EaW1lbnNpb24gPSAtMTtcbiAgICBsZXQgbmV3VGVuc29yU2l6ZSA9IDE7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuRGltczsgaSsrKSB7XG4gICAgICBpZiAoc2hhcGVIaW50c1tpXSA8IC0xKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignYSBkaW1lbnNpb24gaW4gc2hhcGUgaGludHMgY2Fubm90IGJlIGxlc3MgdGhhbiAtMScpO1xuICAgICAgfVxuICAgICAgaWYgKHNoYXBlSGludHNbaV0gPT09IC0xKSB7XG4gICAgICAgIGlmICh1bmtub3duRGltZW5zaW9uICE9PSAtMSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignYXQgbW9zdCBvbmUgZGltZW5zaW9uIGluIHNoYXBlIGhpbnRzIGNhbiBiZSAtMScpO1xuICAgICAgICB9XG4gICAgICAgIHVua25vd25EaW1lbnNpb24gPSBpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHNoYXBlSGludHNbaV0gPT09IDApIHtcbiAgICAgICAgICBpZiAoaSA+PSBvcmlnaW5hbERpbXMubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3RoZSBkaW1lbnNpb24gd2l0aCB2YWx1ZSB6ZXJvIGV4Y2VlZHMgdGhlIGRpbWVuc2lvbiBzaXplIG9mIHRoZSBpbnB1dCB0ZW5zb3InKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmVzaGFwZWREaW1zW2ldID0gb3JpZ2luYWxEaW1zW2ldO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlc2hhcGVkRGltc1tpXSA9IHNoYXBlSGludHNbaV07XG4gICAgICAgIH1cbiAgICAgICAgbmV3VGVuc29yU2l6ZSAqPSByZXNoYXBlZERpbXNbaV07XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3Qgb2xkVGVuc29yU2l6ZSA9IFNoYXBlVXRpbC5zaXplKG9yaWdpbmFsRGltcyk7XG4gICAgaWYgKHVua25vd25EaW1lbnNpb24gIT09IC0xKSB7XG4gICAgICBpZiAob2xkVGVuc29yU2l6ZSAlIG5ld1RlbnNvclNpemUgIT09IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB0aGUgaW5wdXQgdGVuc29yIGNhbm5vdCBiZSByZXNoYXBlZCB0byB0aGUgcmVxdWVzdGVkIHNoYXBlLiBJbnB1dCBzaGFwZTogWyR7XG4gICAgICAgICAgICBvcmlnaW5hbERpbXN9XSBPdXRwdXQgc2hhcGU6IFske3NoYXBlSGludHN9XWApO1xuICAgICAgfVxuICAgICAgcmVzaGFwZWREaW1zW3Vua25vd25EaW1lbnNpb25dID0gb2xkVGVuc29yU2l6ZSAvIG5ld1RlbnNvclNpemU7XG4gICAgfVxuICAgIC8vIHZhbGlkYXRlIHNpemVzIGZyb20gb3JpZ2luYWxEaW1zIGFuZCByZXNoYXBlZERpbXMgbWF0Y2hcbiAgICBlbHNlIHtcbiAgICAgIGlmIChuZXdUZW5zb3JTaXplICE9PSBvbGRUZW5zb3JTaXplKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcigncmVzaGFwZWREaW1zIGFuZCBvcmlnaW5hbERpbXMgZG9uXFwndCBoYXZlIG1hdGNoaW5nIHNpemVzJyk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXNoYXBlZERpbXM7XG4gIH1cblxuICAvKipcbiAgICogU29ydHMgYSBnaXZlbiBhcnJheSBiYXNlZCBvbiB0aGUgaW5kaWNlcyBpbiB0aGUgUGVybSBhcnJheVxuICAgKiBVc2VkIGluIFRyYW5zcG9zZVxuICAgKiBAcGFyYW0gYSBBcnJheSB0byBiZSBzb3J0ZWQgc3VjaCBhcyBkaW1zIG9yIHN0cmlkZXNcbiAgICogQHBhcmFtIHBlcm0gUGVybSBnaXZlbjsgaWYgbnVsbCBhIHdpbGwgYmUgcmV2ZXJzZWRcbiAgICovXG4gIHN0YXRpYyBzb3J0QmFzZWRPblBlcm0oYTogcmVhZG9ubHkgbnVtYmVyW10sIHBlcm0/OiByZWFkb25seSBudW1iZXJbXSk6IHJlYWRvbmx5IG51bWJlcltdIHtcbiAgICBpZiAocGVybSkge1xuICAgICAgcmV0dXJuIHBlcm0ubWFwKCh2KSA9PiBhW3ZdKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGEuc2xpY2UoKS5yZXZlcnNlKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFBhZHMgYSBnaXZlbiBzaGFwZSBhY2NvcmRpbmcgdG8gdGhlIHBhZGRpbmcgdmFsdWVzXG4gICAqIEBwYXJhbSBkaW1zIHNoYXBlIG9mIHRoZSBUZW5zb3IgdG8gYmUgcGFkZGVkXG4gICAqIEBwYXJhbSBwYWQgcGFkIHZhbHVlc1xuICAgKi9cbiAgc3RhdGljIHBhZFNoYXBlKGRpbXM6IHJlYWRvbmx5IG51bWJlcltdLCBwYWQ6IHJlYWRvbmx5IG51bWJlcltdKTogcmVhZG9ubHkgbnVtYmVyW10ge1xuICAgIGNvbnN0IHJhbmsgPSBkaW1zLmxlbmd0aDtcbiAgICByZXR1cm4gZGltcy5tYXAoKHYsIGkpID0+IHYgKyBwYWRbaV0gKyBwYWRbaSArIHJhbmtdKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXRlcm1pbmVzIGlmIHRoZSB0d28gc2hhcGVzIGFyZSBpZGVudGljYWxcbiAgICogQHBhcmFtIHNoYXBlMVxuICAgKiBAcGFyYW0gc2hhcGUyXG4gICAqL1xuICBzdGF0aWMgYXJlRXF1YWwoc2hhcGUxOiByZWFkb25seSBudW1iZXJbXSwgc2hhcGUyOiByZWFkb25seSBudW1iZXJbXSk6IGJvb2xlYW4ge1xuICAgIGlmIChzaGFwZTEubGVuZ3RoICE9PSBzaGFwZTIubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiBzaGFwZTEuZXZlcnkoKHYsIGkpID0+IHYgPT09IHNoYXBlMltpXSk7XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGVzIGlmIHRoZSBnaXZlbiBgZGltc2Agb3IgYHNoYXBlYCBpcyB2YWxpZCBpbiBPTk5YLmpzIGNvbnRleHQgYW5kIHJldHVybnMgZGF0YSBzaXplXG4gICAqIEBwYXJhbSBkaW1zIC0gaW5wdXQgYGRpbXNgIHRoYXQgbmVlZHMgdG8gYmUgY2hlY2tlZFxuICAgKi9cbiAgc3RhdGljIHZhbGlkYXRlRGltc0FuZENhbGNTaXplKGRpbXM6IHJlYWRvbmx5IG51bWJlcltdKTogbnVtYmVyIHtcbiAgICBpZiAoZGltcy5sZW5ndGggPiA2KSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdPbmx5IHJhbmsgMCB0byA2IGlzIHN1cHBvcnRlZCBmb3IgdGVuc29yIHNoYXBlLicpO1xuICAgIH1cbiAgICBsZXQgc2l6ZSA9IDE7XG4gICAgZm9yIChjb25zdCBuIG9mIGRpbXMpIHtcbiAgICAgIGlmICghTnVtYmVyLmlzSW50ZWdlcihuKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBJbnZhbGlkIHNoYXBlOiAke259IGlzIG5vdCBhbiBpbnRlZ2VyYCk7XG4gICAgICB9XG4gICAgICBpZiAobiA8IDAgfHwgbiA+IDIxNDc0ODM2NDcpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgSW52YWxpZCBzaGFwZTogbGVuZ3RoICR7bn0gaXMgbm90IGFsbG93ZWRgKTtcbiAgICAgIH1cbiAgICAgIHNpemUgKj0gbjtcbiAgICB9XG4gICAgcmV0dXJuIHNpemU7XG4gIH1cblxuICAvKipcbiAgICogRGV0ZXJtaW5lcyB0aGUgc2hhcGUgb2Ygb3V0cHV0IHRlbnNvciB5ID0gZmxhdHRlbih4LCBheGlzKVxuICAgKiBAcGFyYW0gZGltcyAtIHNoYXBlIG9mIGlucHV0IHRlbnNvclxuICAgKiBAcGFyYW0gYXhpcyAtIGZsYXR0ZW4gYXhpcywgaW4gdGhlIHJhbmdlIFstciwgcl1cbiAgICovXG4gIHN0YXRpYyBmbGF0dGVuU2hhcGUoZGltczogcmVhZG9ubHkgbnVtYmVyW10sIGF4aXM6IG51bWJlcik6IHJlYWRvbmx5IG51bWJlcltdIHtcbiAgICBpZiAoYXhpcyA8IDApIHtcbiAgICAgIGF4aXMgKz0gZGltcy5sZW5ndGg7XG4gICAgfVxuICAgIGNvbnN0IHRvdGFsID0gZGltcy5yZWR1Y2UoKHgsIHkpID0+IHggKiB5LCAxKTtcbiAgICBjb25zdCByaWdodCA9IGRpbXMuc2xpY2UoYXhpcykucmVkdWNlKCh4LCB5KSA9PiB4ICogeSwgMSk7XG4gICAgY29uc3Qgb3V0cHV0RGltcyA9IFt0b3RhbCAvIHJpZ2h0LCByaWdodF07XG5cbiAgICByZXR1cm4gb3V0cHV0RGltcztcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXRlcm1pbmVzIHRoZSBzaGFwZSBvZiBvdXRwdXQgdGVuc29yIHkgPSBzcXVlZXplKHgsIGF4ZXMpXG4gICAqIEBwYXJhbSBkaW1zIC0gc2hhcGUgb2YgaW5wdXQgdGVuc29yXG4gICAqIEBwYXJhbSBheGVzIC0gc3F1ZWV6ZSBheGVzXG4gICAqL1xuICBzdGF0aWMgc3F1ZWV6ZVNoYXBlKGRpbXM6IHJlYWRvbmx5IG51bWJlcltdLCBheGVzOiByZWFkb25seSBudW1iZXJbXSk6IHJlYWRvbmx5IG51bWJlcltdIHtcbiAgICBjb25zdCBvdXRwdXREaW1zID0gbmV3IEFycmF5PG51bWJlcj4oKTtcblxuICAgIC8vIHNhbml0eSBjaGVja1xuICAgIGF4ZXMgPSBTaGFwZVV0aWwubm9ybWFsaXplQXhlcyhheGVzLCBkaW1zLmxlbmd0aCk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRpbXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGluU3F1ZWV6ZUxpc3QgPSBheGVzLmluZGV4T2YoaSkgPj0gMDtcbiAgICAgIGlmIChpblNxdWVlemVMaXN0ICYmIGRpbXNbaV0gIT09IDEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdzcXVlZXplIGFuIGF4aXMgb2Ygc2l6ZSBkaWZmZXJlbnQgdGhhbiAxJyk7XG4gICAgICB9XG5cbiAgICAgIGlmICgoYXhlcy5sZW5ndGggPT09IDAgJiYgZGltc1tpXSA+IDEpIHx8IChheGVzLmxlbmd0aCA+IDAgJiYgIWluU3F1ZWV6ZUxpc3QpKSB7XG4gICAgICAgIG91dHB1dERpbXMucHVzaChkaW1zW2ldKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gb3V0cHV0RGltcztcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXRlcm1pbmVzIHRoZSBzaGFwZSBvZiBvdXRwdXQgdGVuc29yIHkgPSB1bnNxdWVlemUoeCwgYXhlcylcbiAgICogQHBhcmFtIGRpbXMgLSBzaGFwZSBvZiBpbnB1dCB0ZW5zb3JcbiAgICogQHBhcmFtIGF4ZXMgLSB1bnNxdWVlemUgYXhlc1xuICAgKi9cbiAgc3RhdGljIHVuc3F1ZWV6ZVNoYXBlKGRpbXM6IHJlYWRvbmx5IG51bWJlcltdLCBheGVzOiByZWFkb25seSBudW1iZXJbXSk6IHJlYWRvbmx5IG51bWJlcltdIHtcbiAgICBjb25zdCBvdXRwdXREaW1zID0gbmV3IEFycmF5PG51bWJlcj4oZGltcy5sZW5ndGggKyBheGVzLmxlbmd0aCk7XG5cbiAgICAvLyBpbml0aWFsaXplIHRoZSBhcnJheSBlbGVtZW50cyB0byAwXG4gICAgb3V0cHV0RGltcy5maWxsKDApO1xuXG4gICAgLy8gc2V0IGFsbCBheGVzIGluZGljZXMgdG8gMSBpbiBvdXRwdXREaW1zIGFuZCBjaGVjayBmb3IgZHVwbGljYXRlc1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXhlcy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgYXhpcyA9IFNoYXBlVXRpbC5ub3JtYWxpemVBeGlzKGF4ZXNbaV0sIG91dHB1dERpbXMubGVuZ3RoKTtcbiAgICAgIGlmIChheGlzID49IG91dHB1dERpbXMubGVuZ3RoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignXFwnYXhlc1xcJyBoYXMgYW4gb3V0IG9mIHJhbmdlIGF4aXMnKTtcbiAgICAgIH1cbiAgICAgIGlmIChvdXRwdXREaW1zW2F4aXNdICE9PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignXFwnYXhlc1xcJyBoYXMgYSBkdXBsaWNhdGUgYXhpcycpO1xuICAgICAgfVxuXG4gICAgICBvdXRwdXREaW1zW2F4aXNdID0gMTtcbiAgICB9XG5cbiAgICAvLyBmaWxsIGluIHRoZSB6ZXJvIGVudHJpZXMgb2Ygb3V0cHV0RGltcyB3aXRoIHRoZSBpbnB1dCB0ZW5zb3IncyBzaGFwZVxuICAgIGxldCBpbnB1dERpbXNJdGVyYXRvciA9IDA7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvdXRwdXREaW1zLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAob3V0cHV0RGltc1tpXSA9PT0gMCkge1xuICAgICAgICBvdXRwdXREaW1zW2ldID0gZGltc1tpbnB1dERpbXNJdGVyYXRvcisrXTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBzYW5pdHkgY2hlY2sgYXNzZXJ0aW9uLiAnaW5wdXREaW1zSXRlcmF0b3InXG4gICAgLy8gc2hvdWxkIGJlIGVxdWFsIHRvIHRoZSBsZW5ndGggb2YgJ2RpbXMnXG4gICAgaWYgKGlucHV0RGltc0l0ZXJhdG9yICE9PSBkaW1zLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd0aGUgdW5zcXVlZXplZCBkaW1lbnNpb24gY291bGQgbm90IGJlIGVzdGFibGlzaGVkJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG91dHB1dERpbXM7XG4gIH1cbn1cblxuLy8gYnVuY2ggb2YgaGVscGVyIG1ldGhvZHMgdGhhdCBkbyBhIHZhcmlldHkgb2YgbWF0aCBvcGVyYXRpb25zXG5leHBvcnQgY2xhc3MgTWF0aFV0aWwge1xuICAvLyB5ID0gKHgqeCkgKyB5XG4gIHN0YXRpYyBzcXIoXG4gICAgICB0YXJnZXQ6IG51bWJlcltdfFRlbnNvci5OdW1iZXJUeXBlLCBzb3VyY2U6IG51bWJlcltdfFRlbnNvci5OdW1iZXJUeXBlLCB0YXJnZXRJbmRleDogbnVtYmVyLCBzb3VyY2VJbmRleDogbnVtYmVyLFxuICAgICAgYmxvY2tTaXplOiBudW1iZXIpIHtcbiAgICBpZiAoc291cmNlSW5kZXggPCAwIHx8IHNvdXJjZUluZGV4ID49IHNvdXJjZS5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignc291cmNlSW5kZXggb3V0IG9mIGJvdW5kcycpO1xuICAgIH1cbiAgICBpZiAodGFyZ2V0SW5kZXggPCAwIHx8IHRhcmdldEluZGV4ID49IHRhcmdldC5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndGFyZ2V0SW5kZXggb3V0IG9mIGJvdW5kcycpO1xuICAgIH1cbiAgICBpZiAoc291cmNlSW5kZXggKyBibG9ja1NpemUgPiBzb3VyY2UubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NvdXJjZSBpbmRpY2VzIHRvIGJlIGNvcGllZCBhcmUgb3V0c2lkZSBib3VuZHMnKTtcbiAgICB9XG4gICAgaWYgKHRhcmdldEluZGV4ICsgYmxvY2tTaXplID4gdGFyZ2V0Lmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd0YXJnZXQgYXJyYXkgaXMgdG9vIHNtYWxsIHRvIGhvbGQgcmVzdWx0Jyk7XG4gICAgfVxuXG4gICAgZm9yIChsZXQgb2Zmc2V0ID0gMDsgb2Zmc2V0IDwgYmxvY2tTaXplOyBvZmZzZXQrKykge1xuICAgICAgdGFyZ2V0W3RhcmdldEluZGV4ICsgb2Zmc2V0XSArPSBNYXRoLnBvdyhzb3VyY2Vbc291cmNlSW5kZXggKyBvZmZzZXRdLCAyKTtcbiAgICB9XG4gIH1cblxuICAvLyB5ID0gYXggKyB5XG4gIHN0YXRpYyBheHB5KFxuICAgICAgdGFyZ2V0OiBudW1iZXJbXXxUZW5zb3IuTnVtYmVyVHlwZSwgc291cmNlOiBudW1iZXJbXXxUZW5zb3IuTnVtYmVyVHlwZSwgdGFyZ2V0SW5kZXg6IG51bWJlciwgc291cmNlSW5kZXg6IG51bWJlcixcbiAgICAgIGJsb2NrU2l6ZTogbnVtYmVyLCBhbHBoYTogbnVtYmVyKSB7XG4gICAgaWYgKHNvdXJjZUluZGV4IDwgMCB8fCBzb3VyY2VJbmRleCA+PSBzb3VyY2UubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NvdXJjZUluZGV4IG91dCBvZiBib3VuZHMnKTtcbiAgICB9XG4gICAgaWYgKHRhcmdldEluZGV4IDwgMCB8fCB0YXJnZXRJbmRleCA+PSB0YXJnZXQubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3RhcmdldEluZGV4IG91dCBvZiBib3VuZHMnKTtcbiAgICB9XG4gICAgaWYgKHNvdXJjZUluZGV4ICsgYmxvY2tTaXplID4gc291cmNlLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdzb3VyY2UgaW5kaWNlcyB0byBiZSBjb3BpZWQgYXJlIG91dHNpZGUgYm91bmRzJyk7XG4gICAgfVxuICAgIGlmICh0YXJnZXRJbmRleCArIGJsb2NrU2l6ZSA+IHRhcmdldC5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndGFyZ2V0IGFycmF5IGlzIHRvbyBzbWFsbCB0byBob2xkIHJlc3VsdCcpO1xuICAgIH1cblxuICAgIGZvciAobGV0IG9mZnNldCA9IDA7IG9mZnNldCA8IGJsb2NrU2l6ZTsgb2Zmc2V0KyspIHtcbiAgICAgIHRhcmdldFt0YXJnZXRJbmRleCArIG9mZnNldF0gKz0gKGFscGhhICogc291cmNlW3NvdXJjZUluZGV4ICsgb2Zmc2V0XSk7XG4gICAgfVxuICB9XG5cbiAgLy8geSA9IHBvdyh4LCBiKVxuICBzdGF0aWMgcG93eChcbiAgICAgIHRhcmdldDogbnVtYmVyW118VGVuc29yLk51bWJlclR5cGUsIHNvdXJjZTogbnVtYmVyW118VGVuc29yLk51bWJlclR5cGUsIHRhcmdldEluZGV4OiBudW1iZXIsIHNvdXJjZUluZGV4OiBudW1iZXIsXG4gICAgICBibG9ja1NpemU6IG51bWJlciwgYjogbnVtYmVyKSB7XG4gICAgaWYgKHNvdXJjZUluZGV4IDwgMCB8fCBzb3VyY2VJbmRleCA+PSBzb3VyY2UubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NvdXJjZUluZGV4IG91dCBvZiBib3VuZHMnKTtcbiAgICB9XG4gICAgaWYgKHRhcmdldEluZGV4IDwgMCB8fCB0YXJnZXRJbmRleCA+PSB0YXJnZXQubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3RhcmdldEluZGV4IG91dCBvZiBib3VuZHMnKTtcbiAgICB9XG4gICAgaWYgKHNvdXJjZUluZGV4ICsgYmxvY2tTaXplID4gc291cmNlLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdzb3VyY2UgaW5kaWNlcyB0byBiZSBjb3BpZWQgYXJlIG91dHNpZGUgYm91bmRzJyk7XG4gICAgfVxuICAgIGlmICh0YXJnZXRJbmRleCArIGJsb2NrU2l6ZSA+IHRhcmdldC5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndGFyZ2V0IGFycmF5IGlzIHRvbyBzbWFsbCB0byBob2xkIHJlc3VsdCcpO1xuICAgIH1cblxuICAgIGZvciAobGV0IG9mZnNldCA9IDA7IG9mZnNldCA8IGJsb2NrU2l6ZTsgb2Zmc2V0KyspIHtcbiAgICAgIHRhcmdldFt0YXJnZXRJbmRleCArIG9mZnNldF0gPSBNYXRoLnBvdyhzb3VyY2Vbc291cmNlSW5kZXggKyBvZmZzZXRdLCBiKTtcbiAgICB9XG4gIH1cblxuICAvLyB5ID0geCAqIHlcbiAgc3RhdGljIG11bChcbiAgICAgIHRhcmdldDogbnVtYmVyW118VGVuc29yLk51bWJlclR5cGUsIHNvdXJjZTogbnVtYmVyW118VGVuc29yLk51bWJlclR5cGUsIHRhcmdldEluZGV4OiBudW1iZXIsIHNvdXJjZUluZGV4OiBudW1iZXIsXG4gICAgICBibG9ja1NpemU6IG51bWJlcikge1xuICAgIGlmIChzb3VyY2VJbmRleCA8IDAgfHwgc291cmNlSW5kZXggPj0gc291cmNlLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdzb3VyY2VJbmRleCBvdXQgb2YgYm91bmRzJyk7XG4gICAgfVxuICAgIGlmICh0YXJnZXRJbmRleCA8IDAgfHwgdGFyZ2V0SW5kZXggPj0gdGFyZ2V0Lmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd0YXJnZXRJbmRleCBvdXQgb2YgYm91bmRzJyk7XG4gICAgfVxuICAgIGlmIChzb3VyY2VJbmRleCArIGJsb2NrU2l6ZSA+IHNvdXJjZS5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignc291cmNlIGluZGljZXMgdG8gYmUgY29waWVkIGFyZSBvdXRzaWRlIGJvdW5kcycpO1xuICAgIH1cbiAgICBpZiAodGFyZ2V0SW5kZXggKyBibG9ja1NpemUgPiB0YXJnZXQubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3RhcmdldCBhcnJheSBpcyB0b28gc21hbGwgdG8gaG9sZCByZXN1bHQnKTtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBvZmZzZXQgPSAwOyBvZmZzZXQgPCBibG9ja1NpemU7IG9mZnNldCsrKSB7XG4gICAgICB0YXJnZXRbdGFyZ2V0SW5kZXggKyBvZmZzZXRdID0gKHNvdXJjZVtzb3VyY2VJbmRleCArIG9mZnNldF0gKiB0YXJnZXRbdGFyZ2V0SW5kZXggKyBvZmZzZXRdKTtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFNwbGl0VXRpbCB7XG4gIC8qKlxuICAgKiBDYWxjdWxhdGVzIG5ldyBTaGFwZXMgZnJvbSBleGlzdGluZyBvbmUgYW5kIHRoZSBzcGxpdHMgZ2l2ZW4gYWxvbmcgdGhlIGF4aXMgcHJvdmlkZXNcbiAgICogQHBhcmFtIGRpbXMgU2hhcGUgb2YgdGhlIFRlbnNvciB0byBiZSBzcGxpdHRlZCBpbnRvIHR3byBvciBtb3JlIFNoYXBlc1xuICAgKiBAcGFyYW0gYXhpcyBUaGUgZGltZW5zaW9uIGFsb25nIHdoaWNoIHRoZSBUZW5zb3Igd2lsbCBiZSBzcGxpdFxuICAgKiBAcGFyYW0gc3BsaXRzIE9mZnNldHMgZm9yIHRoZSBzdGFydCBvZiBlYWNoIHNwbGl0XG4gICAqL1xuICBzdGF0aWMgc3BsaXRTaGFwZShkaW1zOiByZWFkb25seSBudW1iZXJbXSwgYXhpczogbnVtYmVyLCBzcGxpdDogbnVtYmVyW10sIG51bU91dHB1dHM/OiBudW1iZXIpOlxuICAgICAgW251bWJlcltdW10sIG51bWJlcltdXSB7XG4gICAgaWYgKHNwbGl0Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgaWYgKCFudW1PdXRwdXRzKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignbmVlZCB0byBrbm93IG51bWJlciBvZiBvdXRwdXRzIHdoZW4gdGhlIFxcJ3NwbGl0XFwnIGF0dHJpYnV0ZSBpcyBub3Qgc3BlY2lmaWVkJyk7XG4gICAgICB9XG4gICAgICBTcGxpdFV0aWwuZGV0ZXJtaW5lU3BsaXQoZGltc1theGlzXSwgbnVtT3V0cHV0cywgc3BsaXQpO1xuICAgIH1cblxuICAgIGNvbnN0IHNoYXBlczogbnVtYmVyW11bXSA9IFtdO1xuICAgIGNvbnN0IG9mZnNldHMgPSBbMF07XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzcGxpdC5sZW5ndGg7ICsraSkge1xuICAgICAgaWYgKGkgIT09IDApIHtcbiAgICAgICAgb2Zmc2V0cy5wdXNoKG9mZnNldHNbaSAtIDFdICsgc3BsaXRbaSAtIDFdKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHNoYXBlID0gZGltcy5zbGljZSgpO1xuICAgICAgc2hhcGVbYXhpc10gPSBzcGxpdFtpXTtcbiAgICAgIHNoYXBlcy5wdXNoKHNoYXBlKTtcbiAgICB9XG4gICAgcmV0dXJuIFtzaGFwZXMsIG9mZnNldHNdO1xuICB9XG5cbiAgc3RhdGljIGRldGVybWluZVNwbGl0KG51bUVsZW1lbnRzQWxvbmdBeGlzOiBudW1iZXIsIG51bU91dHB1dHM6IG51bWJlciwgc3BsaXQ6IG51bWJlcltdKSB7XG4gICAgLy8gSWYgJ3NwbGl0JyBpcyBub3Qgc3BlY2lmaWVkIGJ5IHRoZSB1c2VyLCB3ZSBuZWVkIHRvIHBhcnRpdGlvbiB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIGVxdWFsbHkgYW1vbmcgdGhlIG91dHB1dHNcbiAgICBpZiAobnVtRWxlbWVudHNBbG9uZ0F4aXMgJSBudW1PdXRwdXRzICE9PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2Nhbm5vdCBzcGxpdCB0ZW5zb3IgdG8gZXF1YWwgc2l6ZWQgcGFydHMnKTtcbiAgICB9XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBudW1PdXRwdXRzOyArK2kpIHtcbiAgICAgIHNwbGl0LnB1c2gobnVtRWxlbWVudHNBbG9uZ0F4aXMgLyBudW1PdXRwdXRzKTtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFJlZHVjZVV0aWwge1xuICAvKipcbiAgICogUGVyZm9ybSByZWR1Y2Ugb3BlcmF0aW9ucyBvbiB0aGUgc3BlY2lmaWMgb3BlcmF0b3JcbiAgICogQHBhcmFtIGEgSW5wdXQgdGVuc29yIGRhdGFcbiAgICogQHBhcmFtIGF4ZXMgVGhlIGRpbWVuc2lvbnMgYWxvbmcgd2hpY2ggdGhlIFRlbnNvciB3aWxsIGJlIHJlZHVjZWRcbiAgICogQHBhcmFtIGtlZXBkaW1zIElmIHNldCB0byB0cnVlLCB0aGUgYXhlcyB3aGljaCBhcmUgcmVkdWNlZCBhcmUgbGVmdCBpbiB0aGVcbiAgICogICAgcmVzdWx0IGFzIGRpbWVuc2lvbnMgd2l0aCBzaXplIG9uZS5cbiAgICogQHBhcmFtIG9wMSBUaGUgb3BlcmF0aW9uIHRvIGJlIHBlcmZvcm1lZCBvbiBlYWNoIGVsZW1lbnQgaW4gdGhlIHRlbnNvclxuICAgKiBAcGFyYW0gb3AyIFRoZSBvcGVyYXRpb24gdG8gYmUgcGVyZm9ybWVkIGJldHdlZW4gZWxlbWVudHMgaW4gdGhlIHRlbnNvclxuICAgKi9cbiAgc3RhdGljIGNhbGNSZWR1Y2UoXG4gICAgICBhOiBUZW5zb3IsIGF4ZXM6IG51bWJlcltdLCBrZWVwZGltczogYm9vbGVhbiwgb3AxOiAoYjogbnVtYmVyKSA9PiBudW1iZXIsXG4gICAgICBvcDI6IChhOiBudW1iZXIsIGI6IG51bWJlcikgPT4gbnVtYmVyKTogVGVuc29yIHtcbiAgICBjb25zdCBkaW1zID0gYS5kaW1zLnNsaWNlKDApO1xuICAgIC8vIGlmIGF4ZXMgaXMgbm90IHNldCwgcGVyZm9ybSByZWR1Y2Ugb24gYWxsIGF4ZXNcbiAgICBpZiAoYXhlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIGRpbXMuZm9yRWFjaCgoZCwgaW5kKSA9PiBheGVzLnB1c2goaW5kKSk7XG4gICAgfVxuICAgIC8vIGdldCBhIHRlbXBvcmFyeSBicm9hZGNhc3RhYmxlIG91dHB1dCBzaGFwZVxuICAgIGNvbnN0IG91dHB1dERpbXMgPSBSZWR1Y2VVdGlsLmNhbGNSZWR1Y2VTaGFwZShkaW1zLCBheGVzLCB0cnVlKTtcblxuICAgIC8vIGxvb3AgdGhyb3VnaCB0aGUgb3V0cHV0IGFuZCBjYWxjdWxhdGUgcmVzdWx0IG9uZSBieSBvbmVcbiAgICBjb25zdCBzaXplID0gU2hhcGVVdGlsLnNpemUob3V0cHV0RGltcyk7XG4gICAgY29uc3QgeSA9IG5ldyBUZW5zb3Iob3V0cHV0RGltcywgYS50eXBlKTtcbiAgICBjb25zdCBzdHJpZGVzID0gU2hhcGVVdGlsLmNvbXB1dGVTdHJpZGVzKG91dHB1dERpbXMpO1xuICAgIGNvbnN0IGlucHV0U3RyaWRlcyA9IFNoYXBlVXRpbC5jb21wdXRlU3RyaWRlcyhkaW1zKTtcbiAgICBjb25zdCBpbmRpY2VzWSA9IG5ldyBBcnJheShkaW1zLmxlbmd0aCk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHtcbiAgICAgIGNvbnN0IGluZGljZXMgPSBTaGFwZVV0aWwub2Zmc2V0VG9JbmRpY2VzKGksIHN0cmlkZXMpO1xuICAgICAgLy8gbWFwIGluZGV4XG4gICAgICBCcm9hZGNhc3RVdGlsLmZpbGxJbmRleChpbmRpY2VzLCBkaW1zLCBpbmRpY2VzWSk7XG4gICAgICB5LnNldChcbiAgICAgICAgICBpbmRpY2VzLFxuICAgICAgICAgIFJlZHVjZVV0aWwuY2FsY1JlZHVjZUJ5QXhpcyhcbiAgICAgICAgICAgICAgYS5udW1iZXJEYXRhLCBheGVzLCBkaW1zLCAwLCBTaGFwZVV0aWwuaW5kaWNlc1RvT2Zmc2V0KGluZGljZXNZLCBpbnB1dFN0cmlkZXMpLCBvcDEsIG9wMikpO1xuICAgIH1cblxuICAgIGlmIChrZWVwZGltcykge1xuICAgICAgcmV0dXJuIHk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGtlZXBkaW1zID09IDAsIGNhbGN1bGF0ZSB0aGUgZXhwZWN0ZWQgc2hhcGVcbiAgICAgIHJldHVybiBuZXcgVGVuc29yKFxuICAgICAgICAgIFJlZHVjZVV0aWwuY2FsY1JlZHVjZVNoYXBlKGRpbXMsIGF4ZXMsIGtlZXBkaW1zKSwgeS50eXBlLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgeS5kYXRhLCB5LmRhdGFJZCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFBlcmZvcm0gcmVkdWNlIG9wZXJhdGlvbnMgb24gdGhlIHNwZWNpZmljIG9wZXJhdG9yIG9uIHNwZWNpZmljIGF4ZXNcbiAgICogQHBhcmFtIGEgSW5wdXQgdGVuc29yIGRhdGFcbiAgICogQHBhcmFtIGF4ZXMgVGhlIGRpbWVuc2lvbnMgYWxvbmcgd2hpY2ggdGhlIFRlbnNvciB3aWxsIGJlIHJlZHVjZWRcbiAgICogQHBhcmFtIGRpbXMgVGhlIGlucHV0IGRpbWVuc2lvbi5cbiAgICogQHBhcmFtIGN1ckF4aXNJbmQgSW5kZXggaW4gYXhlcyBzcGVjaWZ5aW5nIHRoZSBjdXJyZW50IGRpbWVuc2lvbiBhbG9uZ1xuICAgKiAgICAgIHdoaWNoIHRoZSB0ZW5zb3Igd2lsbCBiZSByZWR1Y2VkXG4gICAqIEBwYXJhbSBwb3MgVGhlIGN1cnJlbnQgaW5kZXggb2YgZWxlbWVudCB0byBwZXJmb3JtIG9wZXJhdGlvblxuICAgKiBAcGFyYW0gb3AxIFRoZSBvcGVyYXRpb24gdG8gYmUgcGVyZm9ybWVkIG9uIGVhY2ggZWxlbWVudCBpbiB0aGUgdGVuc29yXG4gICAqIEBwYXJhbSBvcDIgVGhlIG9wZXJhdGlvbiB0byBiZSBwZXJmb3JtZWQgYmV0d2VlbiBlbGVtZW50cyBpbiB0aGUgdGVuc29yXG4gICAqL1xuICBzdGF0aWMgY2FsY1JlZHVjZUJ5QXhpcyhcbiAgICAgIGlucHV0OiBUZW5zb3IuTnVtYmVyVHlwZSwgYXhlczogbnVtYmVyW10sIGRpbXM6IG51bWJlcltdLCBjdXJBeGlzSW5kOiBudW1iZXIsIHBvczogbnVtYmVyLFxuICAgICAgb3AxOiAoYjogbnVtYmVyKSA9PiBudW1iZXIsIG9wMjogKGE6IG51bWJlciwgYjogbnVtYmVyKSA9PiBudW1iZXIpOiBudW1iZXIge1xuICAgIGxldCByZXMgPSAwO1xuICAgIGlmIChjdXJBeGlzSW5kID49IGF4ZXMubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gb3AxKGlucHV0W3Bvc10pO1xuICAgIH1cbiAgICBjb25zdCBheGlzID0gYXhlc1tjdXJBeGlzSW5kXTtcbiAgICBjb25zdCBzdGVwID0gYXhpcyA+PSBkaW1zLmxlbmd0aCA/IDEgOiBTaGFwZVV0aWwuc2l6ZShkaW1zLnNsaWNlKGF4aXMgKyAxKSk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkaW1zW2F4aXNdOyBpKyspIHtcbiAgICAgIHJlcyA9IGkgPT09IDAgPyBSZWR1Y2VVdGlsLmNhbGNSZWR1Y2VCeUF4aXMoaW5wdXQsIGF4ZXMsIGRpbXMsIGN1ckF4aXNJbmQgKyAxLCBwb3MsIG9wMSwgb3AyKSA6XG4gICAgICAgICAgICAgICAgICAgICAgb3AyKHJlcywgUmVkdWNlVXRpbC5jYWxjUmVkdWNlQnlBeGlzKGlucHV0LCBheGVzLCBkaW1zLCBjdXJBeGlzSW5kICsgMSwgcG9zLCBvcDEsIG9wMikpO1xuICAgICAgcG9zICs9IHN0ZXA7XG4gICAgfVxuICAgIHJldHVybiByZXM7XG4gIH1cblxuICAvKipcbiAgICogQ2FsY3VsYXRlIHRoZSBleHBlY3RlZCBzaGFwZSBvZiBhIHJlZHVjZSBvcGVyYXRpb25cbiAgICogQHBhcmFtIGRpbXMgVGhlIGlucHV0IHRlbnNvciBkaW1lbnNpb25cbiAgICogQHBhcmFtIGF4ZXMgVGhlIGRpbWVuc2lvbnMgYWxvbmcgd2hpY2ggdGhlIFRlbnNvciB3aWxsIGJlIHJlZHVjZWRcbiAgICogQHBhcmFtIGtlZXBkaW1zIElmIHNldCB0byB0cnVlLCB0aGUgYXhlcyB3aGljaCBhcmUgcmVkdWNlZCBhcmUgbGVmdCBpbiB0aGVcbiAgICogICAgcmVzdWx0IGFzIGRpbWVuc2lvbnMgd2l0aCBzaXplIG9uZS5cbiAgICovXG4gIHN0YXRpYyBjYWxjUmVkdWNlU2hhcGUoZGltczogcmVhZG9ubHkgbnVtYmVyW10sIGF4ZXM6IHJlYWRvbmx5IG51bWJlcltdLCBrZWVwRGltczogYm9vbGVhbik6IG51bWJlcltdIHtcbiAgICBjb25zdCBvdXRwdXREaW1zID0gZGltcy5zbGljZSgpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXhlcy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKGtlZXBEaW1zKSB7XG4gICAgICAgIG91dHB1dERpbXNbYXhlc1tpXV0gPSAxO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb3V0cHV0RGltc1theGVzW2ldXSA9IDA7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBvdXRwdXREaW1zLmZpbHRlcihkaW0gPT4gZGltICE9PSAwKTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgUG9vbENvbnZVdGlsIHtcbiAgLyoqXG4gICAqIEFkanVzdCB0aGUga2VybmVsLCBzdHJpZGVzLCBwYWRzIHRvIGNvcnJlY3QgcmFuay4gU2V0IHRvIGRlZmF1bHQgdmFsdWUgaWYgbm90IHByZXNlbnRcbiAgICogQHBhcmFtIGlzR2xvYmFsT3BlcmF0b3IgSWYgdHJ1ZSwgcGVyZm9ybSBnbG9iYWwgcG9vbGluZy5cbiAgICogQHBhcmFtIGlucHV0RGltcyBUaGUgaW5wdXQgdGVuc29yIGRpbWVuc2lvbi5cbiAgICogQHBhcmFtIGtlcm5lbFNoYXBlIFRoZSBzaXplIG9mIHRoZSBrZXJuZWwgYWxvbmcgZWFjaCBheGlzLlxuICAgKiBAcGFyYW0gc3RyaWRlcyBTdHJpZGUgYWxvbmcgZWFjaCBheGlzLlxuICAgKiBAcGFyYW0gZGlsYXRpb25zIERpbGF0aW9uIGFsb25nIGVhY2ggYXhpcy5cbiAgICogQHBhcmFtIHBhZHMgUGFkZGluZyBmb3IgdGhlIGJlZ2lubmluZyBhbmQgZW5kaW5nIGFsb25nIGVhY2ggYXhpcy5cbiAgICovXG4gIHN0YXRpYyBhZGp1c3RQb29sQXR0cmlidXRlcyhcbiAgICAgIGlzR2xvYmFsT3BlcmF0b3I6IGJvb2xlYW4sIGlucHV0RGltczogcmVhZG9ubHkgbnVtYmVyW10sIGtlcm5lbFNoYXBlOiBudW1iZXJbXSwgc3RyaWRlczogbnVtYmVyW10sXG4gICAgICBkaWxhdGlvbnM6IG51bWJlcltdLCBwYWRzOiBudW1iZXJbXSkge1xuICAgIGlmICghaXNHbG9iYWxPcGVyYXRvciAmJiBrZXJuZWxTaGFwZS5sZW5ndGggIT09IGlucHV0RGltcy5sZW5ndGggLSAyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2xlbmd0aCBvZiBzcGVjaWZpZWQga2VybmVsIHNoYXBlcyBzaG91bGQgYmUgMiBsZXNzIHRoYW4gbGVuZ3RoIG9mIGlucHV0IGRpbWVuc2lvbnMnKTtcbiAgICB9XG5cbiAgICBpZiAoaXNHbG9iYWxPcGVyYXRvcikge1xuICAgICAgLy8gYWRqdXN0IGtlcm5lbCBzaGFwZSB0byBjb3ZlciB0aGUgaW5wdXQgZGltc1xuICAgICAgZm9yIChsZXQgZGltID0gMDsgZGltIDwgaW5wdXREaW1zLmxlbmd0aCAtIDI7IGRpbSsrKSB7XG4gICAgICAgIGlmIChkaW0gPj0ga2VybmVsU2hhcGUubGVuZ3RoKSB7XG4gICAgICAgICAga2VybmVsU2hhcGUucHVzaChpbnB1dERpbXNbZGltICsgMl0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGtlcm5lbFNoYXBlW2RpbV0gPSBpbnB1dERpbXNbZGltICsgMl07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBhZGp1c3Qgc3RyaWRlcyBsZW5ndGggdG8gbWF0Y2gga2VybmVsIHNoYXBlIGxlbmd0aFxuICAgIGZvciAobGV0IGRpbSA9IDA7IGRpbSA8IGtlcm5lbFNoYXBlLmxlbmd0aDsgZGltKyspIHtcbiAgICAgIGlmIChkaW0gPCBzdHJpZGVzLmxlbmd0aCkge1xuICAgICAgICBpZiAoc3RyaWRlc1tkaW1dIDwgMCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignc3RyaWRlcyBzaG91bGQgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDEnKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RyaWRlcy5wdXNoKDEpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGFkanVzdCBkaWxhdGlvbiB2YWx1ZVxuICAgIGZvciAobGV0IGRpbSA9IDA7IGRpbSA8IGtlcm5lbFNoYXBlLmxlbmd0aDsgZGltKyspIHtcbiAgICAgIGlmIChkaW0gPCBkaWxhdGlvbnMubGVuZ3RoKSB7XG4gICAgICAgIGlmIChkaWxhdGlvbnNbZGltXSA8IDApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2RpbGF0aW9ucyBzaG91bGQgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDEnKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGlsYXRpb25zLnB1c2goMSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gYWRqdXN0IHBhZHMgbGVuZ3RoIHRvIG1hdGNoIDIgKiBrZXJuZWwgc2hhcGUgbGVuZ3RoXG4gICAgZm9yIChsZXQgZGltID0gMDsgZGltIDwga2VybmVsU2hhcGUubGVuZ3RoICogMjsgZGltKyspIHtcbiAgICAgIGlmIChkaW0gPCBwYWRzLmxlbmd0aCkge1xuICAgICAgICBpZiAocGFkc1tkaW1dIDwgMCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcigncGFkIHNob3VsZCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gMScpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwYWRzLnB1c2goMCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gc2FuaXR5IGNoZWNrcyBmb3IgdmFsdWVzIGluIGtlcm5lbCBzaGFwZXMgYW5kIHBhZHNcbiAgICBmb3IgKGxldCBkaW0gPSAwOyBkaW0gPCBrZXJuZWxTaGFwZS5sZW5ndGg7IGRpbSsrKSB7XG4gICAgICBpZiAoa2VybmVsU2hhcGVbZGltXSA8PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcigna2VybmVsIHNoYXBlcyBuZWVkIHRvIGJlIGdyZWF0ZXIgdGhhbiAwJyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChwYWRzW2RpbV0gPj0ga2VybmVsU2hhcGVbZGltXSB8fCBwYWRzW2RpbSArIGtlcm5lbFNoYXBlLmxlbmd0aF0gPj0ga2VybmVsU2hhcGVbZGltXSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3BhZHMgc2hvdWxkIGJlIHNtYWxsZXIgdGhhbiBrZXJuZWwnKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBhZGp1c3QgcGFkIHZhbHVlcyBiYXNlZCBvbiAnYXV0b1BhZCcgYXR0cmlidXRlXG4gIHN0YXRpYyBhZGp1c3RQYWRzQmFzZWRPbkF1dG9QYWQoXG4gICAgICBpbnB1dERpbXM6IHJlYWRvbmx5IG51bWJlcltdLCBzdHJpZGVzOiByZWFkb25seSBudW1iZXJbXSwgZGlsYXRpb25zOiByZWFkb25seSBudW1iZXJbXSxcbiAgICAgIGtlcm5lbFNoYXBlOiByZWFkb25seSBudW1iZXJbXSwgcGFkczogbnVtYmVyW10sIGF1dG9QYWQ/OiBzdHJpbmcpIHtcbiAgICBpZiAoIWF1dG9QYWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAocGFkcy5sZW5ndGggIT09IDIgKiAoaW5wdXREaW1zLmxlbmd0aCAtIDIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2xlbmd0aCBvZiBwYWRzIHNob3VsZCBiZSB0d2ljZSB0aGUgbGVuZ3RoIG9mIGRhdGEgZGltZW5zaW9ucycpO1xuICAgIH1cblxuICAgIGlmIChzdHJpZGVzLmxlbmd0aCAhPT0gKGlucHV0RGltcy5sZW5ndGggLSAyKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdsZW5ndGggb2Ygc3RyaWRlcyBzaG91bGQgYmUgdGhlIGxlbmd0aCBvZiBkYXRhIGRpbWVuc2lvbnMnKTtcbiAgICB9XG5cbiAgICBpZiAoa2VybmVsU2hhcGUubGVuZ3RoICE9PSAoaW5wdXREaW1zLmxlbmd0aCAtIDIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2xlbmd0aCBvZiBrZXJuZWwgc2hhcGVzIHNob3VsZCBiZSB0aGUgbGVuZ3RoIG9mIGRhdGEgZGltZW5zaW9ucycpO1xuICAgIH1cblxuICAgIGZvciAobGV0IGRpbSA9IDA7IGRpbSA8IGlucHV0RGltcy5sZW5ndGggLSAyOyBkaW0rKykge1xuICAgICAgUG9vbENvbnZVdGlsLmFkanVzdFBhZEFuZFJldHVyblNoYXBlKFxuICAgICAgICAgIGlucHV0RGltc1tkaW0gKyAyXSwgc3RyaWRlc1tkaW1dLCBkaWxhdGlvbnNbZGltXSwga2VybmVsU2hhcGVbZGltXSwgcGFkcywgZGltLCBkaW0gKyBpbnB1dERpbXMubGVuZ3RoIC0gMixcbiAgICAgICAgICBhdXRvUGFkKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2FsY3VsYXRlIHRoZSBvdXRwdXQgc2hhcGUgZm9yIFBvb2wgb3BzIGJhc2VkIG9uIGlucHV0IGF0dHJpYnV0ZXMuIChTaG91bGQgYmUgdXNlZCBvbmx5IGZvciBQb29sIG9wcylcbiAgICogQHBhcmFtIGlzR2xvYmFsT3BlcmF0b3IgSWYgdHJ1ZSwgcGVyZm9ybSBnbG9iYWwgcG9vbGluZy5cbiAgICogQHBhcmFtIGlucHV0RGltcyBUaGUgaW5wdXQgdGVuc29yIGRpbWVuc2lvbi4gKGlucHV0c1swXS5kaW1zKVxuICAgKiBAcGFyYW0gc3RyaWRlcyBTdHJpZGUgYWxvbmcgZWFjaCBheGlzLlxuICAgKiBAcGFyYW0gZGlsYXRpb25zIERpbGF0aW9uIGFsb25nIGVhY2ggYXhpcy5cbiAgICogQHBhcmFtIGtlcm5lbFNoYXBlIFRoZSBzaXplIG9mIHRoZSBrZXJuZWwgYWxvbmcgZWFjaCBheGlzLlxuICAgKiBAcGFyYW0gcGFkcyBQYWRkaW5nIGZvciB0aGUgYmVnaW5uaW5nIGFuZCBlbmRpbmcgYWxvbmcgZWFjaCBheGlzLlxuICAgKiBAcGFyYW0gYXV0b1BhZCBERVBSRUNBVEVEIGF0dHJpYnV0ZSBzdXBwb3J0ZWQgZm9yIGxlZ2FjeSBtb2RlbHMuIFNwZWNpZmllcyBob3cgdG8gaW1wbGljaXRseSBjYWxjdWxhdGUgcGFkcyBpbiBlYWNoXG4gICAqICAgICBkaW1lbnNpb24uIENhbiB0YWtlIHZhbHVlcyBOT1RTRVQsIFNBTUVfVVBQRVIsIFNBTUVfTE9XRVIsIG9yIFZBTElELlxuICAgKi9cbiAgc3RhdGljIGNvbXB1dGVQb29sT3V0cHV0U2hhcGUoXG4gICAgICBpc0dsb2JhbE9wZXJhdG9yOiBib29sZWFuLCBpbnB1dERpbXM6IHJlYWRvbmx5IG51bWJlcltdLCBzdHJpZGVzOiBudW1iZXJbXSwgZGlsYXRpb25zOiBudW1iZXJbXSxcbiAgICAgIGtlcm5lbFNoYXBlOiBudW1iZXJbXSwgcGFkczogbnVtYmVyW10sIGF1dG9QYWQ/OiBzdHJpbmcpOiBudW1iZXJbXSB7XG4gICAgaWYgKGlucHV0RGltcy5sZW5ndGggPD0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnB1dCBzaGFwZSBtdXN0IGJlIG9mIHNpemUgZ3JlYXRlciB0aGFuIDAnKTtcbiAgICB9XG5cbiAgICAvLyBBZGQgYmF0Y2ggc2l6ZSBhbmQgbnVtYmVyIG9mIGNoYW5uZWxzIG9mIG91dHB1dFxuICAgIGNvbnN0IG91dHB1dERpbXMgPSBbaW5wdXREaW1zWzBdLCBpbnB1dERpbXNbMV1dO1xuXG4gICAgUG9vbENvbnZVdGlsLmNvbXB1dGVTaGFwZUhlbHBlcihcbiAgICAgICAgaXNHbG9iYWxPcGVyYXRvciwgaW5wdXREaW1zLCBvdXRwdXREaW1zLCBzdHJpZGVzLCBkaWxhdGlvbnMsIGtlcm5lbFNoYXBlLCBwYWRzLCBhdXRvUGFkKTtcbiAgICByZXR1cm4gb3V0cHV0RGltcztcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxjdWxhdGUgdGhlIG91dHB1dCBzaGFwZSBmb3IgQ29udiBvcCBiYXNlZCBvbiBpbnB1dCBhdHRyaWJ1dGVzLiAoU2hvdWxkIGJlIHVzZWQgb25seSBmb3IgQ29udiBvcClcbiAgICogQHBhcmFtIGlucHV0RGltcyBUaGUgaW5wdXQgdGVuc29yIGRpbWVuc2lvbi4gKGlucHV0c1swXS5kaW1zKVxuICAgKiBAcGFyYW0gZmlsdGVyRGltcyBUaGUgZmlsdGVyIHRlbnNvciBkaW1lbnNpb24uIChpbnB1dHNbMV0uZGltcylcbiAgICogQHBhcmFtIHN0cmlkZXMgU3RyaWRlIGFsb25nIGVhY2ggYXhpcy5cbiAgICogQHBhcmFtIGtlcm5lbFNoYXBlIFRoZSBzaXplIG9mIHRoZSBrZXJuZWwgYWxvbmcgZWFjaCBheGlzLlxuICAgKiBAcGFyYW0gcGFkcyBQYWRkaW5nIGZvciB0aGUgYmVnaW5uaW5nIGFuZCBlbmRpbmcgYWxvbmcgZWFjaCBheGlzLlxuICAgKiBAcGFyYW0gYXV0b1BhZCBERVBSRUNBVEVEIGF0dHJpYnV0ZSBzdXBwb3J0ZWQgZm9yIGxlZ2FjeSBtb2RlbHMuIFNwZWNpZmllcyBob3cgdG8gaW1wbGljaXRseSBjYWxjdWxhdGUgcGFkcyBpbiBlYWNoXG4gICAqICAgICBkaW1lbnNpb24uIENhbiB0YWtlIHZhbHVlcyBOT1RTRVQsIFNBTUVfVVBQRVIsIFNBTUVfTE9XRVIsIG9yIFZBTElELlxuICAgKi9cbiAgc3RhdGljIGNvbXB1dGVDb252T3V0cHV0U2hhcGUoXG4gICAgICBpbnB1dERpbXM6IHJlYWRvbmx5IG51bWJlcltdLCBmaWx0ZXJEaW1zOiByZWFkb25seSBudW1iZXJbXSwgc3RyaWRlczogbnVtYmVyW10sIGRpbGF0aW9uczogbnVtYmVyW10sXG4gICAgICBrZXJuZWxTaGFwZTogbnVtYmVyW10sIHBhZHM6IG51bWJlcltdLCBhdXRvUGFkPzogc3RyaW5nKTogbnVtYmVyW10ge1xuICAgIGlmIChpbnB1dERpbXMubGVuZ3RoIDw9IDAgfHwgZmlsdGVyRGltcy5sZW5ndGggPD0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGlucHV0IHRlbnNvciBkaW1zIG9yIGludmFsaWQgZmlsdGVyIHRlbnNvciBkaW1zJyk7XG4gICAgfVxuXG4gICAgLy8gQWRkIGJhdGNoIHNpemUgYW5kIG51bWJlciBvZiBjaGFubmVscyBvZiBvdXRwdXRcbiAgICBjb25zdCBvdXRwdXREaW1zID0gW2lucHV0RGltc1swXSwgZmlsdGVyRGltc1swXV07XG5cbiAgICBQb29sQ29udlV0aWwuY29tcHV0ZVNoYXBlSGVscGVyKGZhbHNlLCBpbnB1dERpbXMsIG91dHB1dERpbXMsIHN0cmlkZXMsIGRpbGF0aW9ucywga2VybmVsU2hhcGUsIHBhZHMsIGF1dG9QYWQpO1xuICAgIHJldHVybiBvdXRwdXREaW1zO1xuICB9XG5cbiAgLy8gd2lsbCBjb21wdXRlIG91dHB1dCBzaGFwZXMgZm9yIGRhdGEgZGltZW5zaW9ucyBPTkxZIChpLmUuKSBubyBiYXRjaCBzaXplIGFuZCBjaGFubmVsc1xuICAvLyBjYWxsZWQgYnkgY29tcHV0ZVBvb2xPdXRwdXRTaGFwZSgpIGFuZCBjb21wdXRlQ29udk91dHB1dFNoYXBlKClcbiAgLy8gYWRqdXN0IHBhZHMgYmFzZWQgb24gJ2F1dG9QYWQnIGF0dHJpYnV0ZSBwcmlvciB0byBzaGFwZSBjb21wdXRhdGlvblxuICBwcml2YXRlIHN0YXRpYyBjb21wdXRlU2hhcGVIZWxwZXIoXG4gICAgICBpc0dsb2JhbE9wZXJhdG9yOiBib29sZWFuLCBpbnB1dERpbXM6IHJlYWRvbmx5IG51bWJlcltdLCBvdXRwdXREaW1zOiBudW1iZXJbXSwgc3RyaWRlczogcmVhZG9ubHkgbnVtYmVyW10sXG4gICAgICBkaWxhdGlvbnM6IHJlYWRvbmx5IG51bWJlcltdLCBrZXJuZWxTaGFwZTogcmVhZG9ubHkgbnVtYmVyW10sIHBhZHM6IG51bWJlcltdLCBhdXRvUGFkPzogc3RyaW5nKSB7XG4gICAgaWYgKGlzR2xvYmFsT3BlcmF0b3IpIHtcbiAgICAgIGZvciAobGV0IGRpbSA9IDA7IGRpbSA8IGlucHV0RGltcy5sZW5ndGggLSAyOyBkaW0rKykge1xuICAgICAgICBvdXRwdXREaW1zLnB1c2goMSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGZvciAobGV0IGRpbSA9IDA7IGRpbSA8IGlucHV0RGltcy5sZW5ndGggLSAyOyBkaW0rKykge1xuICAgICAgICBvdXRwdXREaW1zLnB1c2goUG9vbENvbnZVdGlsLmFkanVzdFBhZEFuZFJldHVyblNoYXBlKFxuICAgICAgICAgICAgaW5wdXREaW1zW2RpbSArIDJdLCBzdHJpZGVzW2RpbV0sIGRpbGF0aW9uc1tkaW1dLCBrZXJuZWxTaGFwZVtkaW1dLCBwYWRzLCBkaW0sIGRpbSArIGlucHV0RGltcy5sZW5ndGggLSAyLFxuICAgICAgICAgICAgYXV0b1BhZCkpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIGhlbHBlciBmb3IgY29tcHV0ZVNoYXBlSGVscGVyKCkgYW5kIGFkanVzdFBhZHNCYXNlZE9uQXV0b1BhZCgpXG4gIC8vIGFkanVzdHMgcGFkIHZhbHVlIGZvciBnaXZlbiAnYXV0b1BhZCcgc3RyaW5nIGFuZCBjb21wdXRlcyBvdXRwdXQgc2hhcGUgYWxvbmcgYSBwYXJ0aWN1bGFyIGRpbWVuc2lvblxuICBwcml2YXRlIHN0YXRpYyBhZGp1c3RQYWRBbmRSZXR1cm5TaGFwZShcbiAgICAgIGluU2l6ZTogbnVtYmVyLCBzdHJpZGU6IG51bWJlciwgZGlsYXRpb246IG51bWJlciwga2VybmVsOiBudW1iZXIsIHBhZHM6IG51bWJlcltdLCBwYWRIZWFkSW5kZXg6IG51bWJlcixcbiAgICAgIHBhZFRhaWxJbmRleDogbnVtYmVyLCBhdXRvUGFkPzogc3RyaW5nKTogbnVtYmVyIHtcbiAgICBjb25zdCBka2VybmVsID0gZGlsYXRpb24gKiAoa2VybmVsIC0gMSkgKyAxO1xuICAgIGlmIChhdXRvUGFkICYmIGF1dG9QYWQgIT09ICdOT1RTRVQnKSB7XG4gICAgICBzd2l0Y2ggKGF1dG9QYWQpIHtcbiAgICAgICAgY2FzZSAnVkFMSUQnOlxuICAgICAgICAgIHBhZHNbcGFkSGVhZEluZGV4XSA9IDA7XG4gICAgICAgICAgcGFkc1twYWRUYWlsSW5kZXhdID0gMDtcbiAgICAgICAgICByZXR1cm4gTWF0aC5mbG9vcigoKGluU2l6ZSAtIGRrZXJuZWwpIC8gc3RyaWRlKSArIDEpO1xuICAgICAgICBjYXNlICdTQU1FX0xPV0VSJzpcbiAgICAgICAgY2FzZSAnU0FNRV9VUFBFUic6XG4gICAgICAgICAgaWYgKGRpbGF0aW9uICE9PSAxKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0RpbGF0aW9uIG5vdCBzdXBwb3J0ZWQgZm9yIFNBTUVfVVBQRVIgb3IgU0FNRV9MT1dFUicpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBsZWdhY3lUYXJnZXRTaXplID0gKGluU2l6ZSArIHN0cmlkZSAtIDEpIC8gc3RyaWRlO1xuICAgICAgICAgICAgY29uc3QgcGFkTmVlZGVkID0gKGxlZ2FjeVRhcmdldFNpemUgLSAxKSAqIHN0cmlkZSArIGtlcm5lbCAtIGluU2l6ZTtcbiAgICAgICAgICAgIHBhZHNbcGFkSGVhZEluZGV4XSA9XG4gICAgICAgICAgICAgICAgKGF1dG9QYWQgPT09ICdTQU1FX0xPV0VSJykgPyBNYXRoLmZsb29yKChwYWROZWVkZWQgKyAxKSAvIDIpIDogTWF0aC5mbG9vcihwYWROZWVkZWQgLyAyKTtcbiAgICAgICAgICAgIHBhZHNbcGFkVGFpbEluZGV4XSA9IHBhZE5lZWRlZCAtIHBhZHNbcGFkSGVhZEluZGV4XTtcbiAgICAgICAgICAgIHJldHVybiBNYXRoLmZsb29yKCgoaW5TaXplICsgcGFkTmVlZGVkIC0ga2VybmVsKSAvIHN0cmlkZSkgKyAxKTtcbiAgICAgICAgICB9XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBBdXRvUGFkIHR5cGUnKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIE1hdGguZmxvb3IoKChpblNpemUgKyBwYWRzW3BhZEhlYWRJbmRleF0gKyBwYWRzW3BhZFRhaWxJbmRleF0gLSBka2VybmVsKSAvIHN0cmlkZSkgKyAxKTtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IE1JTl9DTElQID0gLTMuNDAyODIzNDY2Mzg1Mjg4NmUrMzg7XG5leHBvcnQgY29uc3QgTUFYX0NMSVAgPSAzLjQwMjgyMzQ2NjM4NTI4ODZlKzM4O1xuXG5leHBvcnQgZnVuY3Rpb24gZGVjb2RlVXRmOFN0cmluZyhidWZmZXI6IFVpbnQ4QXJyYXkpOiBzdHJpbmcge1xuICByZXR1cm4gbmV3IFRleHREZWNvZGVyKCkuZGVjb2RlKGJ1ZmZlcik7XG59XG4iLCIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW50ZXJmYWNlIEV4dHJhT3B0aW9uc0hhbmRsZXIge1xuICAobmFtZTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nKTogdm9pZDtcbn1cblxuZXhwb3J0IGNvbnN0IGl0ZXJhdGVFeHRyYU9wdGlvbnMgPVxuICAgIChvcHRpb25zOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiwgcHJlZml4OiBzdHJpbmcsIHNlZW46IFdlYWtTZXQ8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+LFxuICAgICBoYW5kbGVyOiBFeHRyYU9wdGlvbnNIYW5kbGVyKTogdm9pZCA9PiB7XG4gICAgICBpZiAodHlwZW9mIG9wdGlvbnMgPT0gJ29iamVjdCcgJiYgb3B0aW9ucyAhPT0gbnVsbCkge1xuICAgICAgICBpZiAoc2Vlbi5oYXMob3B0aW9ucykpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NpcmN1bGFyIHJlZmVyZW5jZSBpbiBvcHRpb25zJyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc2Vlbi5hZGQob3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgT2JqZWN0LmVudHJpZXMob3B0aW9ucykuZm9yRWFjaCgoW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICAgIGNvbnN0IG5hbWUgPSAocHJlZml4KSA/IHByZWZpeCArIGtleSA6IGtleTtcbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICBpdGVyYXRlRXh0cmFPcHRpb25zKHZhbHVlIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+LCBuYW1lICsgJy4nLCBzZWVuLCBoYW5kbGVyKTtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnIHx8IHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICBoYW5kbGVyKG5hbWUsIHZhbHVlLnRvU3RyaW5nKCkpO1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgICAgaGFuZGxlcihuYW1lLCAodmFsdWUpID8gJzEnIDogJzAnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENhbid0IGhhbmRsZSBleHRyYSBjb25maWcgdHlwZTogJHt0eXBlb2YgdmFsdWV9YCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH07XG4iLCIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtlbnYsIEluZmVyZW5jZVNlc3Npb259IGZyb20gJ29ubnhydW50aW1lLWNvbW1vbic7XG5cbmltcG9ydCB7T3J0V2FzbU1lc3NhZ2UsIFNlcmlhbGl6YWJsZU1vZGVsZGF0YSwgU2VyaWFsaXphYmxlU2Vzc2lvbk1ldGFkYXRhLCBTZXJpYWxpemFibGVUZW5zb3J9IGZyb20gJy4vcHJveHktbWVzc2FnZXMnO1xuaW1wb3J0ICogYXMgY29yZSBmcm9tICcuL3dhc20tY29yZS1pbXBsJztcbmltcG9ydCB7aW5pdGlhbGl6ZVdlYkFzc2VtYmx5fSBmcm9tICcuL3dhc20tZmFjdG9yeSc7XG5cbmNvbnN0IGlzUHJveHkgPSAoKTogYm9vbGVhbiA9PiAhIWVudi53YXNtLnByb3h5ICYmIHR5cGVvZiBkb2N1bWVudCAhPT0gJ3VuZGVmaW5lZCc7XG5sZXQgcHJveHlXb3JrZXI6IFdvcmtlcnx1bmRlZmluZWQ7XG5sZXQgaW5pdGlhbGl6aW5nID0gZmFsc2U7XG5sZXQgaW5pdGlhbGl6ZWQgPSBmYWxzZTtcbmxldCBhYm9ydGVkID0gZmFsc2U7XG5cbi8vIHJlc29sdmU7IHJlamVjdFxudHlwZSBQcm9taXNlQ2FsbGJhY2tzPFQgPSB2b2lkPiA9IFsocmVzdWx0OiBUKSA9PiB2b2lkLCAocmVhc29uOiB1bmtub3duKSA9PiB2b2lkXTtcblxubGV0IGluaXRXYXNtQ2FsbGJhY2tzOiBQcm9taXNlQ2FsbGJhY2tzO1xubGV0IGluaXRPcnRDYWxsYmFja3M6IFByb21pc2VDYWxsYmFja3M7XG5jb25zdCBjcmVhdGVTZXNzaW9uQWxsb2NhdGVDYWxsYmFja3M6IEFycmF5PFByb21pc2VDYWxsYmFja3M8U2VyaWFsaXphYmxlTW9kZWxkYXRhPj4gPSBbXTtcbmNvbnN0IGNyZWF0ZVNlc3Npb25GaW5hbGl6ZUNhbGxiYWNrczogQXJyYXk8UHJvbWlzZUNhbGxiYWNrczxTZXJpYWxpemFibGVTZXNzaW9uTWV0YWRhdGE+PiA9IFtdO1xuY29uc3QgY3JlYXRlU2Vzc2lvbkNhbGxiYWNrczogQXJyYXk8UHJvbWlzZUNhbGxiYWNrczxTZXJpYWxpemFibGVTZXNzaW9uTWV0YWRhdGE+PiA9IFtdO1xuY29uc3QgcmVsZWFzZVNlc3Npb25DYWxsYmFja3M6IEFycmF5PFByb21pc2VDYWxsYmFja3M8dm9pZD4+ID0gW107XG5jb25zdCBydW5DYWxsYmFja3M6IEFycmF5PFByb21pc2VDYWxsYmFja3M8U2VyaWFsaXphYmxlVGVuc29yW10+PiA9IFtdO1xuY29uc3QgZW5kUHJvZmlsaW5nQ2FsbGJhY2tzOiBBcnJheTxQcm9taXNlQ2FsbGJhY2tzPHZvaWQ+PiA9IFtdO1xuXG5jb25zdCBlbnN1cmVXb3JrZXIgPSAoKTogdm9pZCA9PiB7XG4gIGlmIChpbml0aWFsaXppbmcgfHwgIWluaXRpYWxpemVkIHx8IGFib3J0ZWQgfHwgIXByb3h5V29ya2VyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd3b3JrZXIgbm90IHJlYWR5Jyk7XG4gIH1cbn07XG5cbmNvbnN0IG9uUHJveHlXb3JrZXJNZXNzYWdlID0gKGV2OiBNZXNzYWdlRXZlbnQ8T3J0V2FzbU1lc3NhZ2U+KTogdm9pZCA9PiB7XG4gIHN3aXRjaCAoZXYuZGF0YS50eXBlKSB7XG4gICAgY2FzZSAnaW5pdC13YXNtJzpcbiAgICAgIGluaXRpYWxpemluZyA9IGZhbHNlO1xuICAgICAgaWYgKGV2LmRhdGEuZXJyKSB7XG4gICAgICAgIGFib3J0ZWQgPSB0cnVlO1xuICAgICAgICBpbml0V2FzbUNhbGxiYWNrc1sxXShldi5kYXRhLmVycik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpbml0aWFsaXplZCA9IHRydWU7XG4gICAgICAgIGluaXRXYXNtQ2FsbGJhY2tzWzBdKCk7XG4gICAgICB9XG4gICAgICBicmVhaztcbiAgICBjYXNlICdpbml0LW9ydCc6XG4gICAgICBpZiAoZXYuZGF0YS5lcnIpIHtcbiAgICAgICAgaW5pdE9ydENhbGxiYWNrc1sxXShldi5kYXRhLmVycik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpbml0T3J0Q2FsbGJhY2tzWzBdKCk7XG4gICAgICB9XG4gICAgICBicmVhaztcbiAgICBjYXNlICdjcmVhdGVfYWxsb2NhdGUnOlxuICAgICAgaWYgKGV2LmRhdGEuZXJyKSB7XG4gICAgICAgIGNyZWF0ZVNlc3Npb25BbGxvY2F0ZUNhbGxiYWNrcy5zaGlmdCgpIVsxXShldi5kYXRhLmVycik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjcmVhdGVTZXNzaW9uQWxsb2NhdGVDYWxsYmFja3Muc2hpZnQoKSFbMF0oZXYuZGF0YS5vdXQhKTtcbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2NyZWF0ZV9maW5hbGl6ZSc6XG4gICAgICBpZiAoZXYuZGF0YS5lcnIpIHtcbiAgICAgICAgY3JlYXRlU2Vzc2lvbkZpbmFsaXplQ2FsbGJhY2tzLnNoaWZ0KCkhWzFdKGV2LmRhdGEuZXJyKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNyZWF0ZVNlc3Npb25GaW5hbGl6ZUNhbGxiYWNrcy5zaGlmdCgpIVswXShldi5kYXRhLm91dCEpO1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnY3JlYXRlJzpcbiAgICAgIGlmIChldi5kYXRhLmVycikge1xuICAgICAgICBjcmVhdGVTZXNzaW9uQ2FsbGJhY2tzLnNoaWZ0KCkhWzFdKGV2LmRhdGEuZXJyKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNyZWF0ZVNlc3Npb25DYWxsYmFja3Muc2hpZnQoKSFbMF0oZXYuZGF0YS5vdXQhKTtcbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ3JlbGVhc2UnOlxuICAgICAgaWYgKGV2LmRhdGEuZXJyKSB7XG4gICAgICAgIHJlbGVhc2VTZXNzaW9uQ2FsbGJhY2tzLnNoaWZ0KCkhWzFdKGV2LmRhdGEuZXJyKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlbGVhc2VTZXNzaW9uQ2FsbGJhY2tzLnNoaWZ0KCkhWzBdKCk7XG4gICAgICB9XG4gICAgICBicmVhaztcbiAgICBjYXNlICdydW4nOlxuICAgICAgaWYgKGV2LmRhdGEuZXJyKSB7XG4gICAgICAgIHJ1bkNhbGxiYWNrcy5zaGlmdCgpIVsxXShldi5kYXRhLmVycik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBydW5DYWxsYmFja3Muc2hpZnQoKSFbMF0oZXYuZGF0YS5vdXQhKTtcbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2VuZC1wcm9maWxpbmcnOlxuICAgICAgaWYgKGV2LmRhdGEuZXJyKSB7XG4gICAgICAgIGVuZFByb2ZpbGluZ0NhbGxiYWNrcy5zaGlmdCgpIVsxXShldi5kYXRhLmVycik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlbmRQcm9maWxpbmdDYWxsYmFja3Muc2hpZnQoKSFbMF0oKTtcbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuICAgIGRlZmF1bHQ6XG4gIH1cbn07XG5cbmNvbnN0IHNjcmlwdFNyYyA9IHR5cGVvZiBkb2N1bWVudCAhPT0gJ3VuZGVmaW5lZCcgPyAoZG9jdW1lbnQ/LmN1cnJlbnRTY3JpcHQgYXMgSFRNTFNjcmlwdEVsZW1lbnQpPy5zcmMgOiB1bmRlZmluZWQ7XG5cbmV4cG9ydCBjb25zdCBpbml0V2FzbSA9IGFzeW5jKCk6IFByb21pc2U8dm9pZD4gPT4ge1xuICBpZiAoIUJVSUxEX0RFRlMuRElTQUJMRV9XQVNNX1BST1hZICYmIGlzUHJveHkoKSkge1xuICAgIGlmIChpbml0aWFsaXplZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoaW5pdGlhbGl6aW5nKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ211bHRpcGxlIGNhbGxzIHRvIFxcJ2luaXRXYXNtKClcXCcgZGV0ZWN0ZWQuJyk7XG4gICAgfVxuICAgIGlmIChhYm9ydGVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3ByZXZpb3VzIGNhbGwgdG8gXFwnaW5pdFdhc20oKVxcJyBmYWlsZWQuJyk7XG4gICAgfVxuXG4gICAgaW5pdGlhbGl6aW5nID0gdHJ1ZTtcblxuICAgIC8vIG92ZXJ3cml0ZSB3YXNtIGZpbGVwYXRoc1xuICAgIGlmIChlbnYud2FzbS53YXNtUGF0aHMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKHNjcmlwdFNyYyAmJiBzY3JpcHRTcmMuaW5kZXhPZignYmxvYjonKSAhPT0gMCkge1xuICAgICAgICBlbnYud2FzbS53YXNtUGF0aHMgPSBzY3JpcHRTcmMuc3Vic3RyKDAsICsoc2NyaXB0U3JjKS5sYXN0SW5kZXhPZignLycpICsgMSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHByb3h5V29ya2VyPy50ZXJtaW5hdGUoKTtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdmFyLXJlcXVpcmVzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVxdWlyZS1pbXBvcnRzXG4gICAgICBwcm94eVdvcmtlciA9IHJlcXVpcmUoJ3dvcmtlci1sb2FkZXI/aW5saW5lPW5vLWZhbGxiYWNrIS4vcHJveHktd29ya2VyL21haW4nKS5kZWZhdWx0KCkgYXMgV29ya2VyO1xuICAgICAgcHJveHlXb3JrZXIub25tZXNzYWdlID0gb25Qcm94eVdvcmtlck1lc3NhZ2U7XG4gICAgICBpbml0V2FzbUNhbGxiYWNrcyA9IFtyZXNvbHZlLCByZWplY3RdO1xuICAgICAgY29uc3QgbWVzc2FnZTogT3J0V2FzbU1lc3NhZ2UgPSB7dHlwZTogJ2luaXQtd2FzbScsIGluIDogZW52Lndhc219O1xuICAgICAgcHJveHlXb3JrZXIucG9zdE1lc3NhZ2UobWVzc2FnZSk7XG4gICAgfSk7XG5cbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gaW5pdGlhbGl6ZVdlYkFzc2VtYmx5KGVudi53YXNtKTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IGluaXRPcnQgPSBhc3luYyhudW1UaHJlYWRzOiBudW1iZXIsIGxvZ2dpbmdMZXZlbDogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gIGlmICghQlVJTERfREVGUy5ESVNBQkxFX1dBU01fUFJPWFkgJiYgaXNQcm94eSgpKSB7XG4gICAgZW5zdXJlV29ya2VyKCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGluaXRPcnRDYWxsYmFja3MgPSBbcmVzb2x2ZSwgcmVqZWN0XTtcbiAgICAgIGNvbnN0IG1lc3NhZ2U6IE9ydFdhc21NZXNzYWdlID0ge3R5cGU6ICdpbml0LW9ydCcsIGluIDoge251bVRocmVhZHMsIGxvZ2dpbmdMZXZlbH19O1xuICAgICAgcHJveHlXb3JrZXIhLnBvc3RNZXNzYWdlKG1lc3NhZ2UpO1xuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIGNvcmUuaW5pdE9ydChudW1UaHJlYWRzLCBsb2dnaW5nTGV2ZWwpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlU2Vzc2lvbkFsbG9jYXRlID0gYXN5bmMobW9kZWw6IFVpbnQ4QXJyYXkpOiBQcm9taXNlPFNlcmlhbGl6YWJsZU1vZGVsZGF0YT4gPT4ge1xuICBpZiAoIUJVSUxEX0RFRlMuRElTQUJMRV9XQVNNX1BST1hZICYmIGlzUHJveHkoKSkge1xuICAgIGVuc3VyZVdvcmtlcigpO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTxTZXJpYWxpemFibGVNb2RlbGRhdGE+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGNyZWF0ZVNlc3Npb25BbGxvY2F0ZUNhbGxiYWNrcy5wdXNoKFtyZXNvbHZlLCByZWplY3RdKTtcbiAgICAgIGNvbnN0IG1lc3NhZ2U6IE9ydFdhc21NZXNzYWdlID0ge3R5cGU6ICdjcmVhdGVfYWxsb2NhdGUnLCBpbiA6IHttb2RlbH19O1xuICAgICAgcHJveHlXb3JrZXIhLnBvc3RNZXNzYWdlKG1lc3NhZ2UsIFttb2RlbC5idWZmZXJdKTtcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gY29yZS5jcmVhdGVTZXNzaW9uQWxsb2NhdGUobW9kZWwpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlU2Vzc2lvbkZpbmFsaXplID0gYXN5bmMobW9kZWxkYXRhOiBTZXJpYWxpemFibGVNb2RlbGRhdGEsIG9wdGlvbnM/OiBJbmZlcmVuY2VTZXNzaW9uLlNlc3Npb25PcHRpb25zKTpcbiAgICBQcm9taXNlPFNlcmlhbGl6YWJsZVNlc3Npb25NZXRhZGF0YT4gPT4ge1xuICAgICAgaWYgKCFCVUlMRF9ERUZTLkRJU0FCTEVfV0FTTV9QUk9YWSAmJiBpc1Byb3h5KCkpIHtcbiAgICAgICAgZW5zdXJlV29ya2VyKCk7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxTZXJpYWxpemFibGVTZXNzaW9uTWV0YWRhdGE+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICBjcmVhdGVTZXNzaW9uRmluYWxpemVDYWxsYmFja3MucHVzaChbcmVzb2x2ZSwgcmVqZWN0XSk7XG4gICAgICAgICAgY29uc3QgbWVzc2FnZTogT3J0V2FzbU1lc3NhZ2UgPSB7dHlwZTogJ2NyZWF0ZV9maW5hbGl6ZScsIGluIDoge21vZGVsZGF0YSwgb3B0aW9uc319O1xuICAgICAgICAgIHByb3h5V29ya2VyIS5wb3N0TWVzc2FnZShtZXNzYWdlKTtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gY29yZS5jcmVhdGVTZXNzaW9uRmluYWxpemUobW9kZWxkYXRhLCBvcHRpb25zKTtcbiAgICAgIH1cbiAgICB9O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlU2Vzc2lvbiA9XG4gICAgYXN5bmMobW9kZWw6IFVpbnQ4QXJyYXksIG9wdGlvbnM/OiBJbmZlcmVuY2VTZXNzaW9uLlNlc3Npb25PcHRpb25zKTogUHJvbWlzZTxTZXJpYWxpemFibGVTZXNzaW9uTWV0YWRhdGE+ID0+IHtcbiAgaWYgKCFCVUlMRF9ERUZTLkRJU0FCTEVfV0FTTV9QUk9YWSAmJiBpc1Byb3h5KCkpIHtcbiAgICBlbnN1cmVXb3JrZXIoKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8U2VyaWFsaXphYmxlU2Vzc2lvbk1ldGFkYXRhPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBjcmVhdGVTZXNzaW9uQ2FsbGJhY2tzLnB1c2goW3Jlc29sdmUsIHJlamVjdF0pO1xuICAgICAgY29uc3QgbWVzc2FnZTogT3J0V2FzbU1lc3NhZ2UgPSB7dHlwZTogJ2NyZWF0ZScsIGluIDoge21vZGVsLCBvcHRpb25zfX07XG4gICAgICBwcm94eVdvcmtlciEucG9zdE1lc3NhZ2UobWVzc2FnZSwgW21vZGVsLmJ1ZmZlcl0pO1xuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBjb3JlLmNyZWF0ZVNlc3Npb24obW9kZWwsIG9wdGlvbnMpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgcmVsZWFzZVNlc3Npb24gPSBhc3luYyhzZXNzaW9uSWQ6IG51bWJlcik6IFByb21pc2U8dm9pZD4gPT4ge1xuICBpZiAoIUJVSUxEX0RFRlMuRElTQUJMRV9XQVNNX1BST1hZICYmIGlzUHJveHkoKSkge1xuICAgIGVuc3VyZVdvcmtlcigpO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICByZWxlYXNlU2Vzc2lvbkNhbGxiYWNrcy5wdXNoKFtyZXNvbHZlLCByZWplY3RdKTtcbiAgICAgIGNvbnN0IG1lc3NhZ2U6IE9ydFdhc21NZXNzYWdlID0ge3R5cGU6ICdyZWxlYXNlJywgaW4gOiBzZXNzaW9uSWR9O1xuICAgICAgcHJveHlXb3JrZXIhLnBvc3RNZXNzYWdlKG1lc3NhZ2UpO1xuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIGNvcmUucmVsZWFzZVNlc3Npb24oc2Vzc2lvbklkKTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IHJ1biA9IGFzeW5jKFxuICAgIHNlc3Npb25JZDogbnVtYmVyLCBpbnB1dEluZGljZXM6IG51bWJlcltdLCBpbnB1dHM6IFNlcmlhbGl6YWJsZVRlbnNvcltdLCBvdXRwdXRJbmRpY2VzOiBudW1iZXJbXSxcbiAgICBvcHRpb25zOiBJbmZlcmVuY2VTZXNzaW9uLlJ1bk9wdGlvbnMpOiBQcm9taXNlPFNlcmlhbGl6YWJsZVRlbnNvcltdPiA9PiB7XG4gIGlmICghQlVJTERfREVGUy5ESVNBQkxFX1dBU01fUFJPWFkgJiYgaXNQcm94eSgpKSB7XG4gICAgZW5zdXJlV29ya2VyKCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPFNlcmlhbGl6YWJsZVRlbnNvcltdPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBydW5DYWxsYmFja3MucHVzaChbcmVzb2x2ZSwgcmVqZWN0XSk7XG4gICAgICBjb25zdCBtZXNzYWdlOiBPcnRXYXNtTWVzc2FnZSA9IHt0eXBlOiAncnVuJywgaW4gOiB7c2Vzc2lvbklkLCBpbnB1dEluZGljZXMsIGlucHV0cywgb3V0cHV0SW5kaWNlcywgb3B0aW9uc319O1xuICAgICAgcHJveHlXb3JrZXIhLnBvc3RNZXNzYWdlKG1lc3NhZ2UsIGNvcmUuZXh0cmFjdFRyYW5zZmVyYWJsZUJ1ZmZlcnMoaW5wdXRzKSk7XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGNvcmUucnVuKHNlc3Npb25JZCwgaW5wdXRJbmRpY2VzLCBpbnB1dHMsIG91dHB1dEluZGljZXMsIG9wdGlvbnMpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgZW5kUHJvZmlsaW5nID0gYXN5bmMoc2Vzc2lvbklkOiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgaWYgKCFCVUlMRF9ERUZTLkRJU0FCTEVfV0FTTV9QUk9YWSAmJiBpc1Byb3h5KCkpIHtcbiAgICBlbnN1cmVXb3JrZXIoKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgZW5kUHJvZmlsaW5nQ2FsbGJhY2tzLnB1c2goW3Jlc29sdmUsIHJlamVjdF0pO1xuICAgICAgY29uc3QgbWVzc2FnZTogT3J0V2FzbU1lc3NhZ2UgPSB7dHlwZTogJ2VuZC1wcm9maWxpbmcnLCBpbiA6IHNlc3Npb25JZH07XG4gICAgICBwcm94eVdvcmtlciEucG9zdE1lc3NhZ2UobWVzc2FnZSk7XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgY29yZS5lbmRQcm9maWxpbmcoc2Vzc2lvbklkKTtcbiAgfVxufTtcbiIsIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge0luZmVyZW5jZVNlc3Npb259IGZyb20gJ29ubnhydW50aW1lLWNvbW1vbic7XG5cbmltcG9ydCB7aXRlcmF0ZUV4dHJhT3B0aW9uc30gZnJvbSAnLi9vcHRpb25zLXV0aWxzJztcbmltcG9ydCB7YWxsb2NXYXNtU3RyaW5nfSBmcm9tICcuL3N0cmluZy11dGlscyc7XG5pbXBvcnQge2dldEluc3RhbmNlfSBmcm9tICcuL3dhc20tZmFjdG9yeSc7XG5cbmV4cG9ydCBjb25zdCBzZXRSdW5PcHRpb25zID0gKG9wdGlvbnM6IEluZmVyZW5jZVNlc3Npb24uUnVuT3B0aW9ucyk6IFtudW1iZXIsIG51bWJlcltdXSA9PiB7XG4gIGNvbnN0IHdhc20gPSBnZXRJbnN0YW5jZSgpO1xuICBsZXQgcnVuT3B0aW9uc0hhbmRsZSA9IDA7XG4gIGNvbnN0IGFsbG9jczogbnVtYmVyW10gPSBbXTtcblxuICBjb25zdCBydW5PcHRpb25zOiBJbmZlcmVuY2VTZXNzaW9uLlJ1bk9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIHRyeSB7XG4gICAgaWYgKG9wdGlvbnM/LmxvZ1NldmVyaXR5TGV2ZWwgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcnVuT3B0aW9ucy5sb2dTZXZlcml0eUxldmVsID0gMjsgIC8vIERlZmF1bHQgdG8gd2FybmluZ1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICAgIHR5cGVvZiBvcHRpb25zLmxvZ1NldmVyaXR5TGV2ZWwgIT09ICdudW1iZXInIHx8ICFOdW1iZXIuaXNJbnRlZ2VyKG9wdGlvbnMubG9nU2V2ZXJpdHlMZXZlbCkgfHxcbiAgICAgICAgb3B0aW9ucy5sb2dTZXZlcml0eUxldmVsIDwgMCB8fCBvcHRpb25zLmxvZ1NldmVyaXR5TGV2ZWwgPiA0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGxvZyBzZXJ2ZXJpdHkgbGV2ZWwgaXMgbm90IHZhbGlkOiAke29wdGlvbnMubG9nU2V2ZXJpdHlMZXZlbH1gKTtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucz8ubG9nVmVyYm9zaXR5TGV2ZWwgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcnVuT3B0aW9ucy5sb2dWZXJib3NpdHlMZXZlbCA9IDA7ICAvLyBEZWZhdWx0IHRvIDBcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBvcHRpb25zLmxvZ1ZlcmJvc2l0eUxldmVsICE9PSAnbnVtYmVyJyB8fCAhTnVtYmVyLmlzSW50ZWdlcihvcHRpb25zLmxvZ1ZlcmJvc2l0eUxldmVsKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBsb2cgdmVyYm9zaXR5IGxldmVsIGlzIG5vdCB2YWxpZDogJHtvcHRpb25zLmxvZ1ZlcmJvc2l0eUxldmVsfWApO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zPy50ZXJtaW5hdGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcnVuT3B0aW9ucy50ZXJtaW5hdGUgPSBmYWxzZTtcbiAgICB9XG5cbiAgICBsZXQgdGFnRGF0YU9mZnNldCA9IDA7XG4gICAgaWYgKG9wdGlvbnM/LnRhZyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0YWdEYXRhT2Zmc2V0ID0gYWxsb2NXYXNtU3RyaW5nKG9wdGlvbnMudGFnLCBhbGxvY3MpO1xuICAgIH1cblxuICAgIHJ1bk9wdGlvbnNIYW5kbGUgPSB3YXNtLl9PcnRDcmVhdGVSdW5PcHRpb25zKFxuICAgICAgICBydW5PcHRpb25zLmxvZ1NldmVyaXR5TGV2ZWwhLCBydW5PcHRpb25zLmxvZ1ZlcmJvc2l0eUxldmVsISwgISFydW5PcHRpb25zLnRlcm1pbmF0ZSEsIHRhZ0RhdGFPZmZzZXQpO1xuICAgIGlmIChydW5PcHRpb25zSGFuZGxlID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NhblxcJ3QgY3JlYXRlIHJ1biBvcHRpb25zJyk7XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnM/LmV4dHJhICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGl0ZXJhdGVFeHRyYU9wdGlvbnMob3B0aW9ucy5leHRyYSwgJycsIG5ldyBXZWFrU2V0PFJlY29yZDxzdHJpbmcsIHVua25vd24+PigpLCAoa2V5LCB2YWx1ZSkgPT4ge1xuICAgICAgICBjb25zdCBrZXlEYXRhT2Zmc2V0ID0gYWxsb2NXYXNtU3RyaW5nKGtleSwgYWxsb2NzKTtcbiAgICAgICAgY29uc3QgdmFsdWVEYXRhT2Zmc2V0ID0gYWxsb2NXYXNtU3RyaW5nKHZhbHVlLCBhbGxvY3MpO1xuXG4gICAgICAgIGlmICh3YXNtLl9PcnRBZGRSdW5Db25maWdFbnRyeShydW5PcHRpb25zSGFuZGxlLCBrZXlEYXRhT2Zmc2V0LCB2YWx1ZURhdGFPZmZzZXQpICE9PSAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW4ndCBzZXQgYSBydW4gY29uZmlnIGVudHJ5OiAke2tleX0gLSAke3ZhbHVlfWApO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gW3J1bk9wdGlvbnNIYW5kbGUsIGFsbG9jc107XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBpZiAocnVuT3B0aW9uc0hhbmRsZSAhPT0gMCkge1xuICAgICAgd2FzbS5fT3J0UmVsZWFzZVJ1bk9wdGlvbnMocnVuT3B0aW9uc0hhbmRsZSk7XG4gICAgfVxuICAgIGFsbG9jcy5mb3JFYWNoKHdhc20uX2ZyZWUpO1xuICAgIHRocm93IGU7XG4gIH1cbn07XG4iLCIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtyZWFkRmlsZX0gZnJvbSAnZnMnO1xuaW1wb3J0IHtlbnYsIEluZmVyZW5jZVNlc3Npb24sIFNlc3Npb25IYW5kbGVyLCBUZW5zb3J9IGZyb20gJ29ubnhydW50aW1lLWNvbW1vbic7XG5pbXBvcnQge3Byb21pc2lmeX0gZnJvbSAndXRpbCc7XG5cbmltcG9ydCB7U2VyaWFsaXphYmxlTW9kZWxkYXRhfSBmcm9tICcuL3Byb3h5LW1lc3NhZ2VzJztcbmltcG9ydCB7Y3JlYXRlU2Vzc2lvbiwgY3JlYXRlU2Vzc2lvbkFsbG9jYXRlLCBjcmVhdGVTZXNzaW9uRmluYWxpemUsIGVuZFByb2ZpbGluZywgaW5pdE9ydCwgcmVsZWFzZVNlc3Npb24sIHJ1bn0gZnJvbSAnLi9wcm94eS13cmFwcGVyJztcblxubGV0IG9ydEluaXQ6IGJvb2xlYW47XG5cblxuY29uc3QgZ2V0TG9nTGV2ZWwgPSAobG9nTGV2ZWw6ICd2ZXJib3NlJ3wnaW5mbyd8J3dhcm5pbmcnfCdlcnJvcid8J2ZhdGFsJyk6IG51bWJlciA9PiB7XG4gIHN3aXRjaCAobG9nTGV2ZWwpIHtcbiAgICBjYXNlICd2ZXJib3NlJzpcbiAgICAgIHJldHVybiAwO1xuICAgIGNhc2UgJ2luZm8nOlxuICAgICAgcmV0dXJuIDE7XG4gICAgY2FzZSAnd2FybmluZyc6XG4gICAgICByZXR1cm4gMjtcbiAgICBjYXNlICdlcnJvcic6XG4gICAgICByZXR1cm4gMztcbiAgICBjYXNlICdmYXRhbCc6XG4gICAgICByZXR1cm4gNDtcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bnN1cHBvcnRlZCBsb2dnaW5nIGxldmVsOiAke2xvZ0xldmVsfWApO1xuICB9XG59O1xuXG5cbmV4cG9ydCBjbGFzcyBPbm54cnVudGltZVdlYkFzc2VtYmx5U2Vzc2lvbkhhbmRsZXIgaW1wbGVtZW50cyBTZXNzaW9uSGFuZGxlciB7XG4gIHByaXZhdGUgc2Vzc2lvbklkOiBudW1iZXI7XG5cbiAgaW5wdXROYW1lczogc3RyaW5nW107XG4gIG91dHB1dE5hbWVzOiBzdHJpbmdbXTtcblxuICBhc3luYyBjcmVhdGVTZXNzaW9uQWxsb2NhdGUocGF0aDogc3RyaW5nKTogUHJvbWlzZTxTZXJpYWxpemFibGVNb2RlbGRhdGE+IHtcbiAgICAvLyBmZXRjaCBtb2RlbCBmcm9tIHVybCBhbmQgbW92ZSB0byB3YXNtIGhlYXAuIFRoZSBhcnJheWJ1ZmZmZXIgdGhhdCBoZWxkIHRoZSBodHRwXG4gICAgLy8gcmVzcG9uc2UgaXMgZnJlZWQgb25jZSB3ZSByZXR1cm5cbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHBhdGgpO1xuICAgIGNvbnN0IGFycmF5QnVmZmVyID0gYXdhaXQgcmVzcG9uc2UuYXJyYXlCdWZmZXIoKTtcbiAgICByZXR1cm4gY3JlYXRlU2Vzc2lvbkFsbG9jYXRlKG5ldyBVaW50OEFycmF5KGFycmF5QnVmZmVyKSk7XG4gIH1cblxuICBhc3luYyBsb2FkTW9kZWwocGF0aE9yQnVmZmVyOiBzdHJpbmd8VWludDhBcnJheSwgb3B0aW9ucz86IEluZmVyZW5jZVNlc3Npb24uU2Vzc2lvbk9wdGlvbnMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIW9ydEluaXQpIHtcbiAgICAgIGF3YWl0IGluaXRPcnQoZW52Lndhc20ubnVtVGhyZWFkcyEsIGdldExvZ0xldmVsKGVudi5sb2dMZXZlbCEpKTtcbiAgICAgIG9ydEluaXQgPSB0cnVlO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgcGF0aE9yQnVmZmVyID09PSAnc3RyaW5nJykge1xuICAgICAgaWYgKHR5cGVvZiBmZXRjaCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgLy8gbm9kZVxuICAgICAgICBjb25zdCBtb2RlbCA9IGF3YWl0IHByb21pc2lmeShyZWFkRmlsZSkocGF0aE9yQnVmZmVyKTtcbiAgICAgICAgW3RoaXMuc2Vzc2lvbklkLCB0aGlzLmlucHV0TmFtZXMsIHRoaXMub3V0cHV0TmFtZXNdID0gYXdhaXQgY3JlYXRlU2Vzc2lvbihtb2RlbCwgb3B0aW9ucyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBicm93c2VyXG4gICAgICAgIC8vIGZldGNoIG1vZGVsIGFuZCBtb3ZlIHRvIHdhc20gaGVhcC5cbiAgICAgICAgY29uc3QgbW9kZWxEYXRhOiBTZXJpYWxpemFibGVNb2RlbGRhdGEgPSBhd2FpdCB0aGlzLmNyZWF0ZVNlc3Npb25BbGxvY2F0ZShwYXRoT3JCdWZmZXIpO1xuICAgICAgICAvLyBjcmVhdGUgdGhlIHNlc3Npb25cbiAgICAgICAgW3RoaXMuc2Vzc2lvbklkLCB0aGlzLmlucHV0TmFtZXMsIHRoaXMub3V0cHV0TmFtZXNdID0gYXdhaXQgY3JlYXRlU2Vzc2lvbkZpbmFsaXplKG1vZGVsRGF0YSwgb3B0aW9ucyk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIFt0aGlzLnNlc3Npb25JZCwgdGhpcy5pbnB1dE5hbWVzLCB0aGlzLm91dHB1dE5hbWVzXSA9IGF3YWl0IGNyZWF0ZVNlc3Npb24ocGF0aE9yQnVmZmVyLCBvcHRpb25zKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBkaXNwb3NlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiByZWxlYXNlU2Vzc2lvbih0aGlzLnNlc3Npb25JZCk7XG4gIH1cblxuICBhc3luYyBydW4oZmVlZHM6IFNlc3Npb25IYW5kbGVyLkZlZWRzVHlwZSwgZmV0Y2hlczogU2Vzc2lvbkhhbmRsZXIuRmV0Y2hlc1R5cGUsIG9wdGlvbnM6IEluZmVyZW5jZVNlc3Npb24uUnVuT3B0aW9ucyk6XG4gICAgICBQcm9taXNlPFNlc3Npb25IYW5kbGVyLlJldHVyblR5cGU+IHtcbiAgICBjb25zdCBpbnB1dEFycmF5OiBUZW5zb3JbXSA9IFtdO1xuICAgIGNvbnN0IGlucHV0SW5kaWNlczogbnVtYmVyW10gPSBbXTtcbiAgICBPYmplY3QuZW50cmllcyhmZWVkcykuZm9yRWFjaChrdnAgPT4ge1xuICAgICAgY29uc3QgbmFtZSA9IGt2cFswXTtcbiAgICAgIGNvbnN0IHRlbnNvciA9IGt2cFsxXTtcbiAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5pbnB1dE5hbWVzLmluZGV4T2YobmFtZSk7XG4gICAgICBpZiAoaW5kZXggPT09IC0xKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgaW52YWxpZCBpbnB1dCAnJHtuYW1lfSdgKTtcbiAgICAgIH1cbiAgICAgIGlucHV0QXJyYXkucHVzaCh0ZW5zb3IpO1xuICAgICAgaW5wdXRJbmRpY2VzLnB1c2goaW5kZXgpO1xuICAgIH0pO1xuXG4gICAgY29uc3Qgb3V0cHV0SW5kaWNlczogbnVtYmVyW10gPSBbXTtcbiAgICBPYmplY3QuZW50cmllcyhmZXRjaGVzKS5mb3JFYWNoKGt2cCA9PiB7XG4gICAgICBjb25zdCBuYW1lID0ga3ZwWzBdO1xuICAgICAgLy8gVE9ETzogc3VwcG9ydCBwcmUtYWxsb2NhdGVkIG91dHB1dFxuICAgICAgY29uc3QgaW5kZXggPSB0aGlzLm91dHB1dE5hbWVzLmluZGV4T2YobmFtZSk7XG4gICAgICBpZiAoaW5kZXggPT09IC0xKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgaW52YWxpZCBvdXRwdXQgJyR7bmFtZX0nYCk7XG4gICAgICB9XG4gICAgICBvdXRwdXRJbmRpY2VzLnB1c2goaW5kZXgpO1xuICAgIH0pO1xuXG4gICAgY29uc3Qgb3V0cHV0cyA9XG4gICAgICAgIGF3YWl0IHJ1bih0aGlzLnNlc3Npb25JZCwgaW5wdXRJbmRpY2VzLCBpbnB1dEFycmF5Lm1hcCh0ID0+IFt0LnR5cGUsIHQuZGltcywgdC5kYXRhXSksIG91dHB1dEluZGljZXMsIG9wdGlvbnMpO1xuXG4gICAgY29uc3QgcmVzdWx0OiBTZXNzaW9uSGFuZGxlci5SZXR1cm5UeXBlID0ge307XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvdXRwdXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICByZXN1bHRbdGhpcy5vdXRwdXROYW1lc1tvdXRwdXRJbmRpY2VzW2ldXV0gPSBuZXcgVGVuc29yKG91dHB1dHNbaV1bMF0sIG91dHB1dHNbaV1bMl0sIG91dHB1dHNbaV1bMV0pO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgc3RhcnRQcm9maWxpbmcoKTogdm9pZCB7XG4gICAgLy8gVE9ETzogaW1wbGVtZW50IHByb2ZpbGluZ1xuICB9XG5cbiAgZW5kUHJvZmlsaW5nKCk6IHZvaWQge1xuICAgIHZvaWQgZW5kUHJvZmlsaW5nKHRoaXMuc2Vzc2lvbklkKTtcbiAgfVxufVxuIiwiLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4vLyBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG5cbmltcG9ydCB7SW5mZXJlbmNlU2Vzc2lvbn0gZnJvbSAnb25ueHJ1bnRpbWUtY29tbW9uJztcblxuaW1wb3J0IHtpdGVyYXRlRXh0cmFPcHRpb25zfSBmcm9tICcuL29wdGlvbnMtdXRpbHMnO1xuaW1wb3J0IHthbGxvY1dhc21TdHJpbmd9IGZyb20gJy4vc3RyaW5nLXV0aWxzJztcbmltcG9ydCB7Z2V0SW5zdGFuY2V9IGZyb20gJy4vd2FzbS1mYWN0b3J5JztcblxuY29uc3QgZ2V0R3JhcGhPcHRpbXphdGlvbkxldmVsID0gKGdyYXBoT3B0aW1pemF0aW9uTGV2ZWw6IHN0cmluZ3x1bmtub3duKTogbnVtYmVyID0+IHtcbiAgc3dpdGNoIChncmFwaE9wdGltaXphdGlvbkxldmVsKSB7XG4gICAgY2FzZSAnZGlzYWJsZWQnOlxuICAgICAgcmV0dXJuIDA7XG4gICAgY2FzZSAnYmFzaWMnOlxuICAgICAgcmV0dXJuIDE7XG4gICAgY2FzZSAnZXh0ZW5kZWQnOlxuICAgICAgcmV0dXJuIDI7XG4gICAgY2FzZSAnYWxsJzpcbiAgICAgIHJldHVybiA5OTtcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bnN1cHBvcnRlZCBncmFwaCBvcHRpbWl6YXRpb24gbGV2ZWw6ICR7Z3JhcGhPcHRpbWl6YXRpb25MZXZlbH1gKTtcbiAgfVxufTtcblxuY29uc3QgZ2V0RXhlY3V0aW9uTW9kZSA9IChleGVjdXRpb25Nb2RlOiAnc2VxdWVudGlhbCd8J3BhcmFsbGVsJyk6IG51bWJlciA9PiB7XG4gIHN3aXRjaCAoZXhlY3V0aW9uTW9kZSkge1xuICAgIGNhc2UgJ3NlcXVlbnRpYWwnOlxuICAgICAgcmV0dXJuIDA7XG4gICAgY2FzZSAncGFyYWxsZWwnOlxuICAgICAgcmV0dXJuIDE7XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcihgdW5zdXBwb3J0ZWQgZXhlY3V0aW9uIG1vZGU6ICR7ZXhlY3V0aW9uTW9kZX1gKTtcbiAgfVxufTtcblxuY29uc3QgYXBwZW5kRGVmYXVsdE9wdGlvbnMgPSAob3B0aW9uczogSW5mZXJlbmNlU2Vzc2lvbi5TZXNzaW9uT3B0aW9ucyk6IHZvaWQgPT4ge1xuICBpZiAoIW9wdGlvbnMuZXh0cmEpIHtcbiAgICBvcHRpb25zLmV4dHJhID0ge307XG4gIH1cbiAgaWYgKCFvcHRpb25zLmV4dHJhLnNlc3Npb24pIHtcbiAgICBvcHRpb25zLmV4dHJhLnNlc3Npb24gPSB7fTtcbiAgfVxuICBjb25zdCBzZXNzaW9uID0gb3B0aW9ucy5leHRyYS5zZXNzaW9uIGFzIFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gIGlmICghc2Vzc2lvbi51c2Vfb3J0X21vZGVsX2J5dGVzX2RpcmVjdGx5KSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNhbWVsY2FzZVxuICAgIHNlc3Npb24udXNlX29ydF9tb2RlbF9ieXRlc19kaXJlY3RseSA9ICcxJztcbiAgfVxufTtcblxuY29uc3Qgc2V0RXhlY3V0aW9uUHJvdmlkZXJzID1cbiAgICAoc2Vzc2lvbk9wdGlvbnNIYW5kbGU6IG51bWJlciwgZXhlY3V0aW9uUHJvdmlkZXJzOiByZWFkb25seSBJbmZlcmVuY2VTZXNzaW9uLkV4ZWN1dGlvblByb3ZpZGVyQ29uZmlnW10sXG4gICAgIGFsbG9jczogbnVtYmVyW10pOiB2b2lkID0+IHtcbiAgICAgIGZvciAoY29uc3QgZXAgb2YgZXhlY3V0aW9uUHJvdmlkZXJzKSB7XG4gICAgICAgIGxldCBlcE5hbWUgPSB0eXBlb2YgZXAgPT09ICdzdHJpbmcnID8gZXAgOiBlcC5uYW1lO1xuXG4gICAgICAgIC8vIGNoZWNrIEVQIG5hbWVcbiAgICAgICAgc3dpdGNoIChlcE5hbWUpIHtcbiAgICAgICAgICBjYXNlICd4bm5wYWNrJzpcbiAgICAgICAgICAgIGVwTmFtZSA9ICdYTk5QQUNLJztcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ3dhc20nOlxuICAgICAgICAgIGNhc2UgJ2NwdSc6XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBub3Qgc3VwcG9ydGVkIEVQOiAke2VwTmFtZX1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGVwTmFtZURhdGFPZmZzZXQgPSBhbGxvY1dhc21TdHJpbmcoZXBOYW1lLCBhbGxvY3MpO1xuICAgICAgICBpZiAoZ2V0SW5zdGFuY2UoKS5fT3J0QXBwZW5kRXhlY3V0aW9uUHJvdmlkZXIoc2Vzc2lvbk9wdGlvbnNIYW5kbGUsIGVwTmFtZURhdGFPZmZzZXQpICE9PSAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW4ndCBhcHBlbmQgZXhlY3V0aW9uIHByb3ZpZGVyOiAke2VwTmFtZX1gKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbmV4cG9ydCBjb25zdCBzZXRTZXNzaW9uT3B0aW9ucyA9IChvcHRpb25zPzogSW5mZXJlbmNlU2Vzc2lvbi5TZXNzaW9uT3B0aW9ucyk6IFtudW1iZXIsIG51bWJlcltdXSA9PiB7XG4gIGNvbnN0IHdhc20gPSBnZXRJbnN0YW5jZSgpO1xuICBsZXQgc2Vzc2lvbk9wdGlvbnNIYW5kbGUgPSAwO1xuICBjb25zdCBhbGxvY3M6IG51bWJlcltdID0gW107XG5cbiAgY29uc3Qgc2Vzc2lvbk9wdGlvbnM6IEluZmVyZW5jZVNlc3Npb24uU2Vzc2lvbk9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICBhcHBlbmREZWZhdWx0T3B0aW9ucyhzZXNzaW9uT3B0aW9ucyk7XG5cbiAgdHJ5IHtcbiAgICBpZiAob3B0aW9ucz8uZ3JhcGhPcHRpbWl6YXRpb25MZXZlbCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBzZXNzaW9uT3B0aW9ucy5ncmFwaE9wdGltaXphdGlvbkxldmVsID0gJ2FsbCc7XG4gICAgfVxuICAgIGNvbnN0IGdyYXBoT3B0aW1pemF0aW9uTGV2ZWwgPSBnZXRHcmFwaE9wdGltemF0aW9uTGV2ZWwoc2Vzc2lvbk9wdGlvbnMuZ3JhcGhPcHRpbWl6YXRpb25MZXZlbCEpO1xuXG4gICAgaWYgKG9wdGlvbnM/LmVuYWJsZUNwdU1lbUFyZW5hID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHNlc3Npb25PcHRpb25zLmVuYWJsZUNwdU1lbUFyZW5hID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucz8uZW5hYmxlTWVtUGF0dGVybiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBzZXNzaW9uT3B0aW9ucy5lbmFibGVNZW1QYXR0ZXJuID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucz8uZXhlY3V0aW9uTW9kZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBzZXNzaW9uT3B0aW9ucy5leGVjdXRpb25Nb2RlID0gJ3NlcXVlbnRpYWwnO1xuICAgIH1cbiAgICBjb25zdCBleGVjdXRpb25Nb2RlID0gZ2V0RXhlY3V0aW9uTW9kZShzZXNzaW9uT3B0aW9ucy5leGVjdXRpb25Nb2RlISk7XG5cbiAgICBsZXQgbG9nSWREYXRhT2Zmc2V0ID0gMDtcbiAgICBpZiAob3B0aW9ucz8ubG9nSWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgbG9nSWREYXRhT2Zmc2V0ID0gYWxsb2NXYXNtU3RyaW5nKG9wdGlvbnMubG9nSWQsIGFsbG9jcyk7XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnM/LmxvZ1NldmVyaXR5TGV2ZWwgPT09IHVuZGVmaW5lZCkge1xuICAgICAgc2Vzc2lvbk9wdGlvbnMubG9nU2V2ZXJpdHlMZXZlbCA9IDI7ICAvLyBEZWZhdWx0IHRvIHdhcm5pbmdcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgICB0eXBlb2Ygb3B0aW9ucy5sb2dTZXZlcml0eUxldmVsICE9PSAnbnVtYmVyJyB8fCAhTnVtYmVyLmlzSW50ZWdlcihvcHRpb25zLmxvZ1NldmVyaXR5TGV2ZWwpIHx8XG4gICAgICAgIG9wdGlvbnMubG9nU2V2ZXJpdHlMZXZlbCA8IDAgfHwgb3B0aW9ucy5sb2dTZXZlcml0eUxldmVsID4gNCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBsb2cgc2VydmVyaXR5IGxldmVsIGlzIG5vdCB2YWxpZDogJHtvcHRpb25zLmxvZ1NldmVyaXR5TGV2ZWx9YCk7XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnM/LmxvZ1ZlcmJvc2l0eUxldmVsID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHNlc3Npb25PcHRpb25zLmxvZ1ZlcmJvc2l0eUxldmVsID0gMDsgIC8vIERlZmF1bHQgdG8gMFxuICAgIH0gZWxzZSBpZiAodHlwZW9mIG9wdGlvbnMubG9nVmVyYm9zaXR5TGV2ZWwgIT09ICdudW1iZXInIHx8ICFOdW1iZXIuaXNJbnRlZ2VyKG9wdGlvbnMubG9nVmVyYm9zaXR5TGV2ZWwpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGxvZyB2ZXJib3NpdHkgbGV2ZWwgaXMgbm90IHZhbGlkOiAke29wdGlvbnMubG9nVmVyYm9zaXR5TGV2ZWx9YCk7XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnM/LmVuYWJsZVByb2ZpbGluZyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBzZXNzaW9uT3B0aW9ucy5lbmFibGVQcm9maWxpbmcgPSBmYWxzZTtcbiAgICB9XG5cbiAgICBzZXNzaW9uT3B0aW9uc0hhbmRsZSA9IHdhc20uX09ydENyZWF0ZVNlc3Npb25PcHRpb25zKFxuICAgICAgICBncmFwaE9wdGltaXphdGlvbkxldmVsLCAhIXNlc3Npb25PcHRpb25zLmVuYWJsZUNwdU1lbUFyZW5hISwgISFzZXNzaW9uT3B0aW9ucy5lbmFibGVNZW1QYXR0ZXJuISwgZXhlY3V0aW9uTW9kZSxcbiAgICAgICAgISFzZXNzaW9uT3B0aW9ucy5lbmFibGVQcm9maWxpbmchLCAwLCBsb2dJZERhdGFPZmZzZXQsIHNlc3Npb25PcHRpb25zLmxvZ1NldmVyaXR5TGV2ZWwhLFxuICAgICAgICBzZXNzaW9uT3B0aW9ucy5sb2dWZXJib3NpdHlMZXZlbCEpO1xuICAgIGlmIChzZXNzaW9uT3B0aW9uc0hhbmRsZSA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW5cXCd0IGNyZWF0ZSBzZXNzaW9uIG9wdGlvbnMnKTtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucz8uZXhlY3V0aW9uUHJvdmlkZXJzKSB7XG4gICAgICBzZXRFeGVjdXRpb25Qcm92aWRlcnMoc2Vzc2lvbk9wdGlvbnNIYW5kbGUsIG9wdGlvbnMuZXhlY3V0aW9uUHJvdmlkZXJzLCBhbGxvY3MpO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zPy5leHRyYSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpdGVyYXRlRXh0cmFPcHRpb25zKG9wdGlvbnMuZXh0cmEsICcnLCBuZXcgV2Vha1NldDxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4oKSwgKGtleSwgdmFsdWUpID0+IHtcbiAgICAgICAgY29uc3Qga2V5RGF0YU9mZnNldCA9IGFsbG9jV2FzbVN0cmluZyhrZXksIGFsbG9jcyk7XG4gICAgICAgIGNvbnN0IHZhbHVlRGF0YU9mZnNldCA9IGFsbG9jV2FzbVN0cmluZyh2YWx1ZSwgYWxsb2NzKTtcblxuICAgICAgICBpZiAod2FzbS5fT3J0QWRkU2Vzc2lvbkNvbmZpZ0VudHJ5KHNlc3Npb25PcHRpb25zSGFuZGxlLCBrZXlEYXRhT2Zmc2V0LCB2YWx1ZURhdGFPZmZzZXQpICE9PSAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW4ndCBzZXQgYSBzZXNzaW9uIGNvbmZpZyBlbnRyeTogJHtrZXl9IC0gJHt2YWx1ZX1gKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIFtzZXNzaW9uT3B0aW9uc0hhbmRsZSwgYWxsb2NzXTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGlmIChzZXNzaW9uT3B0aW9uc0hhbmRsZSAhPT0gMCkge1xuICAgICAgd2FzbS5fT3J0UmVsZWFzZVNlc3Npb25PcHRpb25zKHNlc3Npb25PcHRpb25zSGFuZGxlKTtcbiAgICB9XG4gICAgYWxsb2NzLmZvckVhY2god2FzbS5fZnJlZSk7XG4gICAgdGhyb3cgZTtcbiAgfVxufTtcbiIsIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge2dldEluc3RhbmNlfSBmcm9tICcuL3dhc20tZmFjdG9yeSc7XG5cbmV4cG9ydCBjb25zdCBhbGxvY1dhc21TdHJpbmcgPSAoZGF0YTogc3RyaW5nLCBhbGxvY3M6IG51bWJlcltdKTogbnVtYmVyID0+IHtcbiAgY29uc3Qgd2FzbSA9IGdldEluc3RhbmNlKCk7XG5cbiAgY29uc3QgZGF0YUxlbmd0aCA9IHdhc20ubGVuZ3RoQnl0ZXNVVEY4KGRhdGEpICsgMTtcbiAgY29uc3QgZGF0YU9mZnNldCA9IHdhc20uX21hbGxvYyhkYXRhTGVuZ3RoKTtcbiAgd2FzbS5zdHJpbmdUb1VURjgoZGF0YSwgZGF0YU9mZnNldCwgZGF0YUxlbmd0aCk7XG4gIGFsbG9jcy5wdXNoKGRhdGFPZmZzZXQpO1xuXG4gIHJldHVybiBkYXRhT2Zmc2V0O1xufTtcbiIsIi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxuXG5pbXBvcnQge0luZmVyZW5jZVNlc3Npb24sIFRlbnNvcn0gZnJvbSAnb25ueHJ1bnRpbWUtY29tbW9uJztcblxuaW1wb3J0IHtTZXJpYWxpemFibGVNb2RlbGRhdGEsIFNlcmlhbGl6YWJsZVNlc3Npb25NZXRhZGF0YSwgU2VyaWFsaXphYmxlVGVuc29yfSBmcm9tICcuL3Byb3h5LW1lc3NhZ2VzJztcbmltcG9ydCB7c2V0UnVuT3B0aW9uc30gZnJvbSAnLi9ydW4tb3B0aW9ucyc7XG5pbXBvcnQge3NldFNlc3Npb25PcHRpb25zfSBmcm9tICcuL3Nlc3Npb24tb3B0aW9ucyc7XG5pbXBvcnQge2FsbG9jV2FzbVN0cmluZ30gZnJvbSAnLi9zdHJpbmctdXRpbHMnO1xuaW1wb3J0IHtnZXRJbnN0YW5jZX0gZnJvbSAnLi93YXNtLWZhY3RvcnknO1xuXG4vKipcbiAqIGluaXRpYWxpemUgT1JUIGVudmlyb25tZW50LlxuICogQHBhcmFtIG51bVRocmVhZHMgU2V0R2xvYmFsSW50cmFPcE51bVRocmVhZHMobnVtVGhyZWFkcylcbiAqIEBwYXJhbSBsb2dnaW5nTGV2ZWwgQ3JlYXRlRW52KHN0YXRpY19jYXN0PE9ydExvZ2dpbmdMZXZlbD4obG9nZ2luZ19sZXZlbCkpXG4gKi9cbmV4cG9ydCBjb25zdCBpbml0T3J0ID0gKG51bVRocmVhZHM6IG51bWJlciwgbG9nZ2luZ0xldmVsOiBudW1iZXIpOiB2b2lkID0+IHtcbiAgY29uc3QgZXJyb3JDb2RlID0gZ2V0SW5zdGFuY2UoKS5fT3J0SW5pdChudW1UaHJlYWRzLCBsb2dnaW5nTGV2ZWwpO1xuICBpZiAoZXJyb3JDb2RlICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBDYW4ndCBpbml0aWFsaXplIG9ubnhydW50aW1lLiBlcnJvciBjb2RlID0gJHtlcnJvckNvZGV9YCk7XG4gIH1cbn07XG5cbi8qKlxuICogIHR1cGxlIGVsZW1lbnRzIGFyZTogSW5mZXJlbmNlU2Vzc2lvbiBJRDsgaW5wdXROYW1lc1VURjhFbmNvZGVkOyBvdXRwdXROYW1lc1VURjhFbmNvZGVkXG4gKi9cbnR5cGUgU2Vzc2lvbk1ldGFkYXRhID0gW251bWJlciwgbnVtYmVyW10sIG51bWJlcltdXTtcblxuY29uc3QgYWN0aXZlU2Vzc2lvbnMgPSBuZXcgTWFwPG51bWJlciwgU2Vzc2lvbk1ldGFkYXRhPigpO1xuXG4vKipcbiAqIGNyZWF0ZSBhbiBpbnN0YW5jZSBvZiBJbmZlcmVuY2VTZXNzaW9uLlxuICogQHJldHVybnMgdGhlIG1ldGFkYXRhIG9mIEluZmVyZW5jZVNlc3Npb24uIDAtdmFsdWUgaGFuZGxlIGZvciBmYWlsdXJlLlxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlU2Vzc2lvbkFsbG9jYXRlID0gKG1vZGVsOiBVaW50OEFycmF5KTogW251bWJlciwgbnVtYmVyXSA9PiB7XG4gIGNvbnN0IHdhc20gPSBnZXRJbnN0YW5jZSgpO1xuICBjb25zdCBtb2RlbERhdGFPZmZzZXQgPSB3YXNtLl9tYWxsb2MobW9kZWwuYnl0ZUxlbmd0aCk7XG4gIHdhc20uSEVBUFU4LnNldChtb2RlbCwgbW9kZWxEYXRhT2Zmc2V0KTtcbiAgcmV0dXJuIFttb2RlbERhdGFPZmZzZXQsIG1vZGVsLmJ5dGVMZW5ndGhdO1xufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZVNlc3Npb25GaW5hbGl6ZSA9XG4gICAgKG1vZGVsRGF0YTogU2VyaWFsaXphYmxlTW9kZWxkYXRhLCBvcHRpb25zPzogSW5mZXJlbmNlU2Vzc2lvbi5TZXNzaW9uT3B0aW9ucyk6IFNlcmlhbGl6YWJsZVNlc3Npb25NZXRhZGF0YSA9PiB7XG4gICAgICBjb25zdCB3YXNtID0gZ2V0SW5zdGFuY2UoKTtcblxuICAgICAgbGV0IHNlc3Npb25IYW5kbGUgPSAwO1xuICAgICAgbGV0IHNlc3Npb25PcHRpb25zSGFuZGxlID0gMDtcbiAgICAgIGxldCBhbGxvY3M6IG51bWJlcltdID0gW107XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIFtzZXNzaW9uT3B0aW9uc0hhbmRsZSwgYWxsb2NzXSA9IHNldFNlc3Npb25PcHRpb25zKG9wdGlvbnMpO1xuXG4gICAgICAgIHNlc3Npb25IYW5kbGUgPSB3YXNtLl9PcnRDcmVhdGVTZXNzaW9uKG1vZGVsRGF0YVswXSwgbW9kZWxEYXRhWzFdLCBzZXNzaW9uT3B0aW9uc0hhbmRsZSk7XG4gICAgICAgIGlmIChzZXNzaW9uSGFuZGxlID09PSAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW5cXCd0IGNyZWF0ZSBhIHNlc3Npb24nKTtcbiAgICAgICAgfVxuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgd2FzbS5fZnJlZShtb2RlbERhdGFbMF0pO1xuICAgICAgICB3YXNtLl9PcnRSZWxlYXNlU2Vzc2lvbk9wdGlvbnMoc2Vzc2lvbk9wdGlvbnNIYW5kbGUpO1xuICAgICAgICBhbGxvY3MuZm9yRWFjaCh3YXNtLl9mcmVlKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgaW5wdXRDb3VudCA9IHdhc20uX09ydEdldElucHV0Q291bnQoc2Vzc2lvbkhhbmRsZSk7XG4gICAgICBjb25zdCBvdXRwdXRDb3VudCA9IHdhc20uX09ydEdldE91dHB1dENvdW50KHNlc3Npb25IYW5kbGUpO1xuXG4gICAgICBjb25zdCBpbnB1dE5hbWVzID0gW107XG4gICAgICBjb25zdCBpbnB1dE5hbWVzVVRGOEVuY29kZWQgPSBbXTtcbiAgICAgIGNvbnN0IG91dHB1dE5hbWVzID0gW107XG4gICAgICBjb25zdCBvdXRwdXROYW1lc1VURjhFbmNvZGVkID0gW107XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGlucHV0Q291bnQ7IGkrKykge1xuICAgICAgICBjb25zdCBuYW1lID0gd2FzbS5fT3J0R2V0SW5wdXROYW1lKHNlc3Npb25IYW5kbGUsIGkpO1xuICAgICAgICBpZiAobmFtZSA9PT0gMCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQ2FuXFwndCBnZXQgYW4gaW5wdXQgbmFtZScpO1xuICAgICAgICB9XG4gICAgICAgIGlucHV0TmFtZXNVVEY4RW5jb2RlZC5wdXNoKG5hbWUpO1xuICAgICAgICBpbnB1dE5hbWVzLnB1c2god2FzbS5VVEY4VG9TdHJpbmcobmFtZSkpO1xuICAgICAgfVxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvdXRwdXRDb3VudDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IG5hbWUgPSB3YXNtLl9PcnRHZXRPdXRwdXROYW1lKHNlc3Npb25IYW5kbGUsIGkpO1xuICAgICAgICBpZiAobmFtZSA9PT0gMCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQ2FuXFwndCBnZXQgYW4gb3V0cHV0IG5hbWUnKTtcbiAgICAgICAgfVxuICAgICAgICBvdXRwdXROYW1lc1VURjhFbmNvZGVkLnB1c2gobmFtZSk7XG4gICAgICAgIG91dHB1dE5hbWVzLnB1c2god2FzbS5VVEY4VG9TdHJpbmcobmFtZSkpO1xuICAgICAgfVxuXG4gICAgICBhY3RpdmVTZXNzaW9ucy5zZXQoc2Vzc2lvbkhhbmRsZSwgW3Nlc3Npb25IYW5kbGUsIGlucHV0TmFtZXNVVEY4RW5jb2RlZCwgb3V0cHV0TmFtZXNVVEY4RW5jb2RlZF0pO1xuICAgICAgcmV0dXJuIFtzZXNzaW9uSGFuZGxlLCBpbnB1dE5hbWVzLCBvdXRwdXROYW1lc107XG4gICAgfTtcblxuXG4vKipcbiAqIGNyZWF0ZSBhbiBpbnN0YW5jZSBvZiBJbmZlcmVuY2VTZXNzaW9uLlxuICogQHJldHVybnMgdGhlIG1ldGFkYXRhIG9mIEluZmVyZW5jZVNlc3Npb24uIDAtdmFsdWUgaGFuZGxlIGZvciBmYWlsdXJlLlxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlU2Vzc2lvbiA9XG4gICAgKG1vZGVsOiBVaW50OEFycmF5LCBvcHRpb25zPzogSW5mZXJlbmNlU2Vzc2lvbi5TZXNzaW9uT3B0aW9ucyk6IFNlcmlhbGl6YWJsZVNlc3Npb25NZXRhZGF0YSA9PiB7XG4gICAgICBjb25zdCBtb2RlbERhdGE6IFNlcmlhbGl6YWJsZU1vZGVsZGF0YSA9IGNyZWF0ZVNlc3Npb25BbGxvY2F0ZShtb2RlbCk7XG4gICAgICByZXR1cm4gY3JlYXRlU2Vzc2lvbkZpbmFsaXplKG1vZGVsRGF0YSwgb3B0aW9ucyk7XG4gICAgfTtcblxuZXhwb3J0IGNvbnN0IHJlbGVhc2VTZXNzaW9uID0gKHNlc3Npb25JZDogbnVtYmVyKTogdm9pZCA9PiB7XG4gIGNvbnN0IHdhc20gPSBnZXRJbnN0YW5jZSgpO1xuICBjb25zdCBzZXNzaW9uID0gYWN0aXZlU2Vzc2lvbnMuZ2V0KHNlc3Npb25JZCk7XG4gIGlmICghc2Vzc2lvbikge1xuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBzZXNzaW9uIGlkJyk7XG4gIH1cbiAgY29uc3Qgc2Vzc2lvbkhhbmRsZSA9IHNlc3Npb25bMF07XG4gIGNvbnN0IGlucHV0TmFtZXNVVEY4RW5jb2RlZCA9IHNlc3Npb25bMV07XG4gIGNvbnN0IG91dHB1dE5hbWVzVVRGOEVuY29kZWQgPSBzZXNzaW9uWzJdO1xuXG4gIGlucHV0TmFtZXNVVEY4RW5jb2RlZC5mb3JFYWNoKHdhc20uX09ydEZyZWUpO1xuICBvdXRwdXROYW1lc1VURjhFbmNvZGVkLmZvckVhY2god2FzbS5fT3J0RnJlZSk7XG4gIHdhc20uX09ydFJlbGVhc2VTZXNzaW9uKHNlc3Npb25IYW5kbGUpO1xuICBhY3RpdmVTZXNzaW9ucy5kZWxldGUoc2Vzc2lvbklkKTtcbn07XG5cbi8qKlxuICogQ29waWVkIGZyb20gT05OWCBkZWZpbml0aW9uLiBVc2UgdGhpcyB0byBkcm9wIGRlcGVuZGVuY3kgJ29ubnhfcHJvdG8nIHRvIGRlY3JlYXNlIGNvbXBpbGVkIC5qcyBmaWxlIHNpemUuXG4gKi9cbmNvbnN0IGVudW0gRGF0YVR5cGUge1xuICB1bmRlZmluZWQgPSAwLFxuICBmbG9hdCA9IDEsXG4gIHVpbnQ4ID0gMixcbiAgaW50OCA9IDMsXG4gIHVpbnQxNiA9IDQsXG4gIGludDE2ID0gNSxcbiAgaW50MzIgPSA2LFxuICBpbnQ2NCA9IDcsXG4gIHN0cmluZyA9IDgsXG4gIGJvb2wgPSA5LFxuICBmbG9hdDE2ID0gMTAsXG4gIGRvdWJsZSA9IDExLFxuICB1aW50MzIgPSAxMixcbiAgdWludDY0ID0gMTMsXG4gIGNvbXBsZXg2NCA9IDE0LFxuICBjb21wbGV4MTI4ID0gMTUsXG4gIGJmbG9hdDE2ID0gMTZcbn1cblxuXG5jb25zdCB0ZW5zb3JEYXRhVHlwZVN0cmluZ1RvRW51bSA9ICh0eXBlOiBzdHJpbmcpOiBEYXRhVHlwZSA9PiB7XG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2UgJ2ludDgnOlxuICAgICAgcmV0dXJuIERhdGFUeXBlLmludDg7XG4gICAgY2FzZSAndWludDgnOlxuICAgICAgcmV0dXJuIERhdGFUeXBlLnVpbnQ4O1xuICAgIGNhc2UgJ2Jvb2wnOlxuICAgICAgcmV0dXJuIERhdGFUeXBlLmJvb2w7XG4gICAgY2FzZSAnaW50MTYnOlxuICAgICAgcmV0dXJuIERhdGFUeXBlLmludDE2O1xuICAgIGNhc2UgJ3VpbnQxNic6XG4gICAgICByZXR1cm4gRGF0YVR5cGUudWludDE2O1xuICAgIGNhc2UgJ2ludDMyJzpcbiAgICAgIHJldHVybiBEYXRhVHlwZS5pbnQzMjtcbiAgICBjYXNlICd1aW50MzInOlxuICAgICAgcmV0dXJuIERhdGFUeXBlLnVpbnQzMjtcbiAgICBjYXNlICdmbG9hdDMyJzpcbiAgICAgIHJldHVybiBEYXRhVHlwZS5mbG9hdDtcbiAgICBjYXNlICdmbG9hdDY0JzpcbiAgICAgIHJldHVybiBEYXRhVHlwZS5kb3VibGU7XG4gICAgY2FzZSAnc3RyaW5nJzpcbiAgICAgIHJldHVybiBEYXRhVHlwZS5zdHJpbmc7XG4gICAgY2FzZSAnaW50NjQnOlxuICAgICAgcmV0dXJuIERhdGFUeXBlLmludDY0O1xuICAgIGNhc2UgJ3VpbnQ2NCc6XG4gICAgICByZXR1cm4gRGF0YVR5cGUudWludDY0O1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcihgdW5zdXBwb3J0ZWQgZGF0YSB0eXBlOiAke3R5cGV9YCk7XG4gIH1cbn07XG5cbmNvbnN0IHRlbnNvckRhdGFUeXBlRW51bVRvU3RyaW5nID0gKHR5cGVQcm90bzogRGF0YVR5cGUpOiBUZW5zb3IuVHlwZSA9PiB7XG4gIHN3aXRjaCAodHlwZVByb3RvKSB7XG4gICAgY2FzZSBEYXRhVHlwZS5pbnQ4OlxuICAgICAgcmV0dXJuICdpbnQ4JztcbiAgICBjYXNlIERhdGFUeXBlLnVpbnQ4OlxuICAgICAgcmV0dXJuICd1aW50OCc7XG4gICAgY2FzZSBEYXRhVHlwZS5ib29sOlxuICAgICAgcmV0dXJuICdib29sJztcbiAgICBjYXNlIERhdGFUeXBlLmludDE2OlxuICAgICAgcmV0dXJuICdpbnQxNic7XG4gICAgY2FzZSBEYXRhVHlwZS51aW50MTY6XG4gICAgICByZXR1cm4gJ3VpbnQxNic7XG4gICAgY2FzZSBEYXRhVHlwZS5pbnQzMjpcbiAgICAgIHJldHVybiAnaW50MzInO1xuICAgIGNhc2UgRGF0YVR5cGUudWludDMyOlxuICAgICAgcmV0dXJuICd1aW50MzInO1xuICAgIGNhc2UgRGF0YVR5cGUuZmxvYXQ6XG4gICAgICByZXR1cm4gJ2Zsb2F0MzInO1xuICAgIGNhc2UgRGF0YVR5cGUuZG91YmxlOlxuICAgICAgcmV0dXJuICdmbG9hdDY0JztcbiAgICBjYXNlIERhdGFUeXBlLnN0cmluZzpcbiAgICAgIHJldHVybiAnc3RyaW5nJztcbiAgICBjYXNlIERhdGFUeXBlLmludDY0OlxuICAgICAgcmV0dXJuICdpbnQ2NCc7XG4gICAgY2FzZSBEYXRhVHlwZS51aW50NjQ6XG4gICAgICByZXR1cm4gJ3VpbnQ2NCc7XG5cbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bnN1cHBvcnRlZCBkYXRhIHR5cGU6ICR7dHlwZVByb3RvfWApO1xuICB9XG59O1xuXG5jb25zdCBudW1lcmljVGVuc29yVHlwZVRvVHlwZWRBcnJheSA9ICh0eXBlOiBUZW5zb3IuVHlwZSk6IEZsb2F0MzJBcnJheUNvbnN0cnVjdG9yfFVpbnQ4QXJyYXlDb25zdHJ1Y3RvcnxcbiAgICBJbnQ4QXJyYXlDb25zdHJ1Y3RvcnxVaW50MTZBcnJheUNvbnN0cnVjdG9yfEludDE2QXJyYXlDb25zdHJ1Y3RvcnxJbnQzMkFycmF5Q29uc3RydWN0b3J8QmlnSW50NjRBcnJheUNvbnN0cnVjdG9yfFxuICAgIFVpbnQ4QXJyYXlDb25zdHJ1Y3RvcnxGbG9hdDY0QXJyYXlDb25zdHJ1Y3RvcnxVaW50MzJBcnJheUNvbnN0cnVjdG9yfEJpZ1VpbnQ2NEFycmF5Q29uc3RydWN0b3IgPT4ge1xuICAgICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICAgIGNhc2UgJ2Zsb2F0MzInOlxuICAgICAgICAgIHJldHVybiBGbG9hdDMyQXJyYXk7XG4gICAgICAgIGNhc2UgJ3VpbnQ4JzpcbiAgICAgICAgICByZXR1cm4gVWludDhBcnJheTtcbiAgICAgICAgY2FzZSAnaW50OCc6XG4gICAgICAgICAgcmV0dXJuIEludDhBcnJheTtcbiAgICAgICAgY2FzZSAndWludDE2JzpcbiAgICAgICAgICByZXR1cm4gVWludDE2QXJyYXk7XG4gICAgICAgIGNhc2UgJ2ludDE2JzpcbiAgICAgICAgICByZXR1cm4gSW50MTZBcnJheTtcbiAgICAgICAgY2FzZSAnaW50MzInOlxuICAgICAgICAgIHJldHVybiBJbnQzMkFycmF5O1xuICAgICAgICBjYXNlICdib29sJzpcbiAgICAgICAgICByZXR1cm4gVWludDhBcnJheTtcbiAgICAgICAgY2FzZSAnZmxvYXQ2NCc6XG4gICAgICAgICAgcmV0dXJuIEZsb2F0NjRBcnJheTtcbiAgICAgICAgY2FzZSAndWludDMyJzpcbiAgICAgICAgICByZXR1cm4gVWludDMyQXJyYXk7XG4gICAgICAgIGNhc2UgJ2ludDY0JzpcbiAgICAgICAgICByZXR1cm4gQmlnSW50NjRBcnJheTtcbiAgICAgICAgY2FzZSAndWludDY0JzpcbiAgICAgICAgICByZXR1cm4gQmlnVWludDY0QXJyYXk7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bnN1cHBvcnRlZCB0eXBlOiAke3R5cGV9YCk7XG4gICAgICB9XG4gICAgfTtcblxuLyoqXG4gKiBwZXJmb3JtIGluZmVyZW5jZSBydW5cbiAqL1xuZXhwb3J0IGNvbnN0IHJ1biA9XG4gICAgKHNlc3Npb25JZDogbnVtYmVyLCBpbnB1dEluZGljZXM6IG51bWJlcltdLCBpbnB1dHM6IFNlcmlhbGl6YWJsZVRlbnNvcltdLCBvdXRwdXRJbmRpY2VzOiBudW1iZXJbXSxcbiAgICAgb3B0aW9uczogSW5mZXJlbmNlU2Vzc2lvbi5SdW5PcHRpb25zKTogU2VyaWFsaXphYmxlVGVuc29yW10gPT4ge1xuICAgICAgY29uc3Qgd2FzbSA9IGdldEluc3RhbmNlKCk7XG4gICAgICBjb25zdCBzZXNzaW9uID0gYWN0aXZlU2Vzc2lvbnMuZ2V0KHNlc3Npb25JZCk7XG4gICAgICBpZiAoIXNlc3Npb24pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIHNlc3Npb24gaWQnKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHNlc3Npb25IYW5kbGUgPSBzZXNzaW9uWzBdO1xuICAgICAgY29uc3QgaW5wdXROYW1lc1VURjhFbmNvZGVkID0gc2Vzc2lvblsxXTtcbiAgICAgIGNvbnN0IG91dHB1dE5hbWVzVVRGOEVuY29kZWQgPSBzZXNzaW9uWzJdO1xuXG4gICAgICBjb25zdCBpbnB1dENvdW50ID0gaW5wdXRJbmRpY2VzLmxlbmd0aDtcbiAgICAgIGNvbnN0IG91dHB1dENvdW50ID0gb3V0cHV0SW5kaWNlcy5sZW5ndGg7XG5cbiAgICAgIGxldCBydW5PcHRpb25zSGFuZGxlID0gMDtcbiAgICAgIGxldCBydW5PcHRpb25zQWxsb2NzOiBudW1iZXJbXSA9IFtdO1xuXG4gICAgICBjb25zdCBpbnB1dFZhbHVlczogbnVtYmVyW10gPSBbXTtcbiAgICAgIGNvbnN0IGlucHV0QWxsb2NzOiBudW1iZXJbXSA9IFtdO1xuXG4gICAgICB0cnkge1xuICAgICAgICBbcnVuT3B0aW9uc0hhbmRsZSwgcnVuT3B0aW9uc0FsbG9jc10gPSBzZXRSdW5PcHRpb25zKG9wdGlvbnMpO1xuXG4gICAgICAgIC8vIGNyZWF0ZSBpbnB1dCB0ZW5zb3JzXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5wdXRDb3VudDsgaSsrKSB7XG4gICAgICAgICAgY29uc3QgZGF0YVR5cGUgPSBpbnB1dHNbaV1bMF07XG4gICAgICAgICAgY29uc3QgZGltcyA9IGlucHV0c1tpXVsxXTtcbiAgICAgICAgICBjb25zdCBkYXRhID0gaW5wdXRzW2ldWzJdO1xuXG4gICAgICAgICAgbGV0IGRhdGFPZmZzZXQ6IG51bWJlcjtcbiAgICAgICAgICBsZXQgZGF0YUJ5dGVMZW5ndGg6IG51bWJlcjtcblxuICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAvLyBzdHJpbmcgdGVuc29yXG4gICAgICAgICAgICBkYXRhQnl0ZUxlbmd0aCA9IDQgKiBkYXRhLmxlbmd0aDtcbiAgICAgICAgICAgIGRhdGFPZmZzZXQgPSB3YXNtLl9tYWxsb2MoZGF0YUJ5dGVMZW5ndGgpO1xuICAgICAgICAgICAgaW5wdXRBbGxvY3MucHVzaChkYXRhT2Zmc2V0KTtcbiAgICAgICAgICAgIGxldCBkYXRhSW5kZXggPSBkYXRhT2Zmc2V0IC8gNDtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICBpZiAodHlwZW9mIGRhdGFbaV0gIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgdGVuc29yIGRhdGEgYXQgaW5kZXggJHtpfSBpcyBub3QgYSBzdHJpbmdgKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB3YXNtLkhFQVBVMzJbZGF0YUluZGV4KytdID0gYWxsb2NXYXNtU3RyaW5nKGRhdGFbaV0sIGlucHV0QWxsb2NzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZGF0YUJ5dGVMZW5ndGggPSBkYXRhLmJ5dGVMZW5ndGg7XG4gICAgICAgICAgICBkYXRhT2Zmc2V0ID0gd2FzbS5fbWFsbG9jKGRhdGFCeXRlTGVuZ3RoKTtcbiAgICAgICAgICAgIGlucHV0QWxsb2NzLnB1c2goZGF0YU9mZnNldCk7XG4gICAgICAgICAgICB3YXNtLkhFQVBVOC5zZXQobmV3IFVpbnQ4QXJyYXkoZGF0YS5idWZmZXIsIGRhdGEuYnl0ZU9mZnNldCwgZGF0YUJ5dGVMZW5ndGgpLCBkYXRhT2Zmc2V0KTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBzdGFjayA9IHdhc20uc3RhY2tTYXZlKCk7XG4gICAgICAgICAgY29uc3QgZGltc09mZnNldCA9IHdhc20uc3RhY2tBbGxvYyg0ICogZGltcy5sZW5ndGgpO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBsZXQgZGltSW5kZXggPSBkaW1zT2Zmc2V0IC8gNDtcbiAgICAgICAgICAgIGRpbXMuZm9yRWFjaChkID0+IHdhc20uSEVBUDMyW2RpbUluZGV4KytdID0gZCk7XG4gICAgICAgICAgICBjb25zdCB0ZW5zb3IgPSB3YXNtLl9PcnRDcmVhdGVUZW5zb3IoXG4gICAgICAgICAgICAgICAgdGVuc29yRGF0YVR5cGVTdHJpbmdUb0VudW0oZGF0YVR5cGUpLCBkYXRhT2Zmc2V0LCBkYXRhQnl0ZUxlbmd0aCwgZGltc09mZnNldCwgZGltcy5sZW5ndGgpO1xuICAgICAgICAgICAgaWYgKHRlbnNvciA9PT0gMCkge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NhblxcJ3QgY3JlYXRlIGEgdGVuc29yJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpbnB1dFZhbHVlcy5wdXNoKHRlbnNvcik7XG4gICAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgIHdhc20uc3RhY2tSZXN0b3JlKHN0YWNrKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBiZWZvcmVSdW5TdGFjayA9IHdhc20uc3RhY2tTYXZlKCk7XG4gICAgICAgIGNvbnN0IGlucHV0VmFsdWVzT2Zmc2V0ID0gd2FzbS5zdGFja0FsbG9jKGlucHV0Q291bnQgKiA0KTtcbiAgICAgICAgY29uc3QgaW5wdXROYW1lc09mZnNldCA9IHdhc20uc3RhY2tBbGxvYyhpbnB1dENvdW50ICogNCk7XG4gICAgICAgIGNvbnN0IG91dHB1dFZhbHVlc09mZnNldCA9IHdhc20uc3RhY2tBbGxvYyhvdXRwdXRDb3VudCAqIDQpO1xuICAgICAgICBjb25zdCBvdXRwdXROYW1lc09mZnNldCA9IHdhc20uc3RhY2tBbGxvYyhvdXRwdXRDb3VudCAqIDQpO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgbGV0IGlucHV0VmFsdWVzSW5kZXggPSBpbnB1dFZhbHVlc09mZnNldCAvIDQ7XG4gICAgICAgICAgbGV0IGlucHV0TmFtZXNJbmRleCA9IGlucHV0TmFtZXNPZmZzZXQgLyA0O1xuICAgICAgICAgIGxldCBvdXRwdXRWYWx1ZXNJbmRleCA9IG91dHB1dFZhbHVlc09mZnNldCAvIDQ7XG4gICAgICAgICAgbGV0IG91dHB1dE5hbWVzSW5kZXggPSBvdXRwdXROYW1lc09mZnNldCAvIDQ7XG4gICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbnB1dENvdW50OyBpKyspIHtcbiAgICAgICAgICAgIHdhc20uSEVBUFUzMltpbnB1dFZhbHVlc0luZGV4KytdID0gaW5wdXRWYWx1ZXNbaV07XG4gICAgICAgICAgICB3YXNtLkhFQVBVMzJbaW5wdXROYW1lc0luZGV4KytdID0gaW5wdXROYW1lc1VURjhFbmNvZGVkW2lucHV0SW5kaWNlc1tpXV07XG4gICAgICAgICAgfVxuICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3V0cHV0Q291bnQ7IGkrKykge1xuICAgICAgICAgICAgd2FzbS5IRUFQVTMyW291dHB1dFZhbHVlc0luZGV4KytdID0gMDtcbiAgICAgICAgICAgIHdhc20uSEVBUFUzMltvdXRwdXROYW1lc0luZGV4KytdID0gb3V0cHV0TmFtZXNVVEY4RW5jb2RlZFtvdXRwdXRJbmRpY2VzW2ldXTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBzdXBwb3J0IFJ1bk9wdGlvbnNcbiAgICAgICAgICBsZXQgZXJyb3JDb2RlID0gd2FzbS5fT3J0UnVuKFxuICAgICAgICAgICAgICBzZXNzaW9uSGFuZGxlLCBpbnB1dE5hbWVzT2Zmc2V0LCBpbnB1dFZhbHVlc09mZnNldCwgaW5wdXRDb3VudCwgb3V0cHV0TmFtZXNPZmZzZXQsIG91dHB1dENvdW50LFxuICAgICAgICAgICAgICBvdXRwdXRWYWx1ZXNPZmZzZXQsIHJ1bk9wdGlvbnNIYW5kbGUpO1xuXG4gICAgICAgICAgY29uc3Qgb3V0cHV0OiBTZXJpYWxpemFibGVUZW5zb3JbXSA9IFtdO1xuXG4gICAgICAgICAgaWYgKGVycm9yQ29kZSA9PT0gMCkge1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvdXRwdXRDb3VudDsgaSsrKSB7XG4gICAgICAgICAgICAgIGNvbnN0IHRlbnNvciA9IHdhc20uSEVBUFUzMltvdXRwdXRWYWx1ZXNPZmZzZXQgLyA0ICsgaV07XG5cbiAgICAgICAgICAgICAgY29uc3QgYmVmb3JlR2V0VGVuc29yRGF0YVN0YWNrID0gd2FzbS5zdGFja1NhdmUoKTtcbiAgICAgICAgICAgICAgLy8gc3RhY2sgYWxsb2NhdGUgNCBwb2ludGVyIHZhbHVlXG4gICAgICAgICAgICAgIGNvbnN0IHRlbnNvckRhdGFPZmZzZXQgPSB3YXNtLnN0YWNrQWxsb2MoNCAqIDQpO1xuXG4gICAgICAgICAgICAgIGxldCB0eXBlOiBUZW5zb3IuVHlwZXx1bmRlZmluZWQsIGRhdGFPZmZzZXQgPSAwO1xuICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGVycm9yQ29kZSA9IHdhc20uX09ydEdldFRlbnNvckRhdGEoXG4gICAgICAgICAgICAgICAgICAgIHRlbnNvciwgdGVuc29yRGF0YU9mZnNldCwgdGVuc29yRGF0YU9mZnNldCArIDQsIHRlbnNvckRhdGFPZmZzZXQgKyA4LCB0ZW5zb3JEYXRhT2Zmc2V0ICsgMTIpO1xuICAgICAgICAgICAgICAgIGlmIChlcnJvckNvZGUgIT09IDApIHtcbiAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2FuJ3QgYWNjZXNzIG91dHB1dCB0ZW5zb3IgZGF0YS4gZXJyb3IgY29kZSA9ICR7ZXJyb3JDb2RlfWApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsZXQgdGVuc29yRGF0YUluZGV4ID0gdGVuc29yRGF0YU9mZnNldCAvIDQ7XG4gICAgICAgICAgICAgICAgY29uc3QgZGF0YVR5cGUgPSB3YXNtLkhFQVBVMzJbdGVuc29yRGF0YUluZGV4KytdO1xuICAgICAgICAgICAgICAgIGRhdGFPZmZzZXQgPSB3YXNtLkhFQVBVMzJbdGVuc29yRGF0YUluZGV4KytdO1xuICAgICAgICAgICAgICAgIGNvbnN0IGRpbXNPZmZzZXQgPSB3YXNtLkhFQVBVMzJbdGVuc29yRGF0YUluZGV4KytdO1xuICAgICAgICAgICAgICAgIGNvbnN0IGRpbXNMZW5ndGggPSB3YXNtLkhFQVBVMzJbdGVuc29yRGF0YUluZGV4KytdO1xuICAgICAgICAgICAgICAgIGNvbnN0IGRpbXMgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRpbXNMZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgZGltcy5wdXNoKHdhc20uSEVBUFUzMltkaW1zT2Zmc2V0IC8gNCArIGldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgd2FzbS5fT3J0RnJlZShkaW1zT2Zmc2V0KTtcblxuICAgICAgICAgICAgICAgIGNvbnN0IHNpemUgPSBkaW1zLmxlbmd0aCA9PT0gMCA/IDEgOiBkaW1zLnJlZHVjZSgoYSwgYikgPT4gYSAqIGIpO1xuICAgICAgICAgICAgICAgIHR5cGUgPSB0ZW5zb3JEYXRhVHlwZUVudW1Ub1N0cmluZyhkYXRhVHlwZSk7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmdEYXRhOiBzdHJpbmdbXSA9IFtdO1xuICAgICAgICAgICAgICAgICAgbGV0IGRhdGFJbmRleCA9IGRhdGFPZmZzZXQgLyA0O1xuICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2Zmc2V0ID0gd2FzbS5IRUFQVTMyW2RhdGFJbmRleCsrXTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbWF4Qnl0ZXNUb1JlYWQgPSBpID09PSBzaXplIC0gMSA/IHVuZGVmaW5lZCA6IHdhc20uSEVBUFUzMltkYXRhSW5kZXhdIC0gb2Zmc2V0O1xuICAgICAgICAgICAgICAgICAgICBzdHJpbmdEYXRhLnB1c2god2FzbS5VVEY4VG9TdHJpbmcob2Zmc2V0LCBtYXhCeXRlc1RvUmVhZCkpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgb3V0cHV0LnB1c2goW3R5cGUsIGRpbXMsIHN0cmluZ0RhdGFdKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgY29uc3QgdHlwZWRBcnJheUNvbnN0cnVjdG9yID0gbnVtZXJpY1RlbnNvclR5cGVUb1R5cGVkQXJyYXkodHlwZSk7XG4gICAgICAgICAgICAgICAgICBjb25zdCBkYXRhID0gbmV3IHR5cGVkQXJyYXlDb25zdHJ1Y3RvcihzaXplKTtcbiAgICAgICAgICAgICAgICAgIG5ldyBVaW50OEFycmF5KGRhdGEuYnVmZmVyLCBkYXRhLmJ5dGVPZmZzZXQsIGRhdGEuYnl0ZUxlbmd0aClcbiAgICAgICAgICAgICAgICAgICAgICAuc2V0KHdhc20uSEVBUFU4LnN1YmFycmF5KGRhdGFPZmZzZXQsIGRhdGFPZmZzZXQgKyBkYXRhLmJ5dGVMZW5ndGgpKTtcbiAgICAgICAgICAgICAgICAgIG91dHB1dC5wdXNoKFt0eXBlLCBkaW1zLCBkYXRhXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgICAgIHdhc20uc3RhY2tSZXN0b3JlKGJlZm9yZUdldFRlbnNvckRhdGFTdGFjayk7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJpbmcnICYmIGRhdGFPZmZzZXQpIHtcbiAgICAgICAgICAgICAgICAgIHdhc20uX2ZyZWUoZGF0YU9mZnNldCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHdhc20uX09ydFJlbGVhc2VUZW5zb3IodGVuc29yKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChlcnJvckNvZGUgPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiBvdXRwdXQ7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgZmFpbGVkIHRvIGNhbGwgT3J0UnVuKCkuIGVycm9yIGNvZGUgPSAke2Vycm9yQ29kZX0uYCk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIHdhc20uc3RhY2tSZXN0b3JlKGJlZm9yZVJ1blN0YWNrKTtcbiAgICAgICAgfVxuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgaW5wdXRWYWx1ZXMuZm9yRWFjaCh3YXNtLl9PcnRSZWxlYXNlVGVuc29yKTtcbiAgICAgICAgaW5wdXRBbGxvY3MuZm9yRWFjaCh3YXNtLl9mcmVlKTtcblxuICAgICAgICB3YXNtLl9PcnRSZWxlYXNlUnVuT3B0aW9ucyhydW5PcHRpb25zSGFuZGxlKTtcbiAgICAgICAgcnVuT3B0aW9uc0FsbG9jcy5mb3JFYWNoKHdhc20uX2ZyZWUpO1xuICAgICAgfVxuICAgIH07XG5cbi8qKlxuICogZW5kIHByb2ZpbGluZ1xuICovXG5leHBvcnQgY29uc3QgZW5kUHJvZmlsaW5nID0gKHNlc3Npb25JZDogbnVtYmVyKTogdm9pZCA9PiB7XG4gIGNvbnN0IHdhc20gPSBnZXRJbnN0YW5jZSgpO1xuICBjb25zdCBzZXNzaW9uID0gYWN0aXZlU2Vzc2lvbnMuZ2V0KHNlc3Npb25JZCk7XG4gIGlmICghc2Vzc2lvbikge1xuICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZCBzZXNzaW9uIGlkJyk7XG4gIH1cbiAgY29uc3Qgc2Vzc2lvbkhhbmRsZSA9IHNlc3Npb25bMF07XG5cbiAgLy8gcHJvZmlsZSBmaWxlIG5hbWUgaXMgbm90IHVzZWQgeWV0LCBidXQgaXQgbXVzdCBiZSBmcmVlZC5cbiAgY29uc3QgcHJvZmlsZUZpbGVOYW1lID0gd2FzbS5fT3J0RW5kUHJvZmlsaW5nKHNlc3Npb25IYW5kbGUpO1xuICBpZiAocHJvZmlsZUZpbGVOYW1lID09PSAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDYW5cXCd0IGdldCBhbiBwcm9maWxlIGZpbGUgbmFtZScpO1xuICB9XG4gIHdhc20uX09ydEZyZWUocHJvZmlsZUZpbGVOYW1lKTtcbn07XG5cbmV4cG9ydCBjb25zdCBleHRyYWN0VHJhbnNmZXJhYmxlQnVmZmVycyA9ICh0ZW5zb3JzOiByZWFkb25seSBTZXJpYWxpemFibGVUZW5zb3JbXSk6IEFycmF5QnVmZmVyTGlrZVtdID0+IHtcbiAgY29uc3QgYnVmZmVyczogQXJyYXlCdWZmZXJMaWtlW10gPSBbXTtcbiAgZm9yIChjb25zdCB0ZW5zb3Igb2YgdGVuc29ycykge1xuICAgIGNvbnN0IGRhdGEgPSB0ZW5zb3JbMl07XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KGRhdGEpICYmIGRhdGEuYnVmZmVyKSB7XG4gICAgICBidWZmZXJzLnB1c2goZGF0YS5idWZmZXIpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gYnVmZmVycztcbn07XG4iLCIvLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cblxuaW1wb3J0IHtFbnZ9IGZyb20gJ29ubnhydW50aW1lLWNvbW1vbic7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuXG5pbXBvcnQge09ydFdhc21Nb2R1bGV9IGZyb20gJy4vYmluZGluZy9vcnQtd2FzbSc7XG5pbXBvcnQge09ydFdhc21UaHJlYWRlZE1vZHVsZX0gZnJvbSAnLi9iaW5kaW5nL29ydC13YXNtLXRocmVhZGVkJztcbmltcG9ydCBvcnRXYXNtRmFjdG9yeSBmcm9tICcuL2JpbmRpbmcvb3J0LXdhc20uanMnO1xuXG5jb25zdCBvcnRXYXNtRmFjdG9yeVRocmVhZGVkOiBFbXNjcmlwdGVuTW9kdWxlRmFjdG9yeTxPcnRXYXNtTW9kdWxlPiA9XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZXF1aXJlLWltcG9ydHNcbiAgICAhQlVJTERfREVGUy5ESVNBQkxFX1dBU01fVEhSRUFEID8gcmVxdWlyZSgnLi9iaW5kaW5nL29ydC13YXNtLXRocmVhZGVkLmpzJykgOiBvcnRXYXNtRmFjdG9yeTtcblxubGV0IHdhc206IE9ydFdhc21Nb2R1bGV8dW5kZWZpbmVkO1xubGV0IGluaXRpYWxpemVkID0gZmFsc2U7XG5sZXQgaW5pdGlhbGl6aW5nID0gZmFsc2U7XG5sZXQgYWJvcnRlZCA9IGZhbHNlO1xuXG5jb25zdCBpc011bHRpVGhyZWFkU3VwcG9ydGVkID0gKCk6IGJvb2xlYW4gPT4ge1xuICB0cnkge1xuICAgIC8vIElmICdTaGFyZWRBcnJheUJ1ZmZlcicgaXMgbm90IGF2YWlsYWJsZSwgV2ViQXNzZW1ibHkgdGhyZWFkcyB3aWxsIG5vdCB3b3JrLlxuICAgIGlmICh0eXBlb2YgU2hhcmVkQXJyYXlCdWZmZXIgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gVGVzdCBmb3IgdHJhbnNmZXJhYmlsaXR5IG9mIFNBQnMgKGZvciBicm93c2Vycy4gbmVlZGVkIGZvciBGaXJlZm94KVxuICAgIC8vIGh0dHBzOi8vZ3JvdXBzLmdvb2dsZS5jb20vZm9ydW0vIyFtc2cvbW96aWxsYS5kZXYucGxhdGZvcm0vSUhrQlpsSEVUcEEvZHdzTU5jaFdFUUFKXG4gICAgaWYgKHR5cGVvZiBNZXNzYWdlQ2hhbm5lbCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIG5ldyBNZXNzYWdlQ2hhbm5lbCgpLnBvcnQxLnBvc3RNZXNzYWdlKG5ldyBTaGFyZWRBcnJheUJ1ZmZlcigxKSk7XG4gICAgfVxuXG4gICAgLy8gVGVzdCBmb3IgV2ViQXNzZW1ibHkgdGhyZWFkcyBjYXBhYmlsaXR5IChmb3IgYm90aCBicm93c2VycyBhbmQgTm9kZS5qcylcbiAgICAvLyBUaGlzIHR5cGVkIGFycmF5IGlzIGEgV2ViQXNzZW1ibHkgcHJvZ3JhbSBjb250YWluaW5nIHRocmVhZGVkIGluc3RydWN0aW9ucy5cbiAgICByZXR1cm4gV2ViQXNzZW1ibHkudmFsaWRhdGUobmV3IFVpbnQ4QXJyYXkoW1xuICAgICAgMCwgOTcsIDExNSwgMTA5LCAxLCAwLCAgMCwgIDAsIDEsIDQsIDEsICA5NiwgMCwgICAwLCAgMywgMiwgMSwgIDAsIDUsXG4gICAgICA0LCAxLCAgMywgICAxLCAgIDEsIDEwLCAxMSwgMSwgOSwgMCwgNjUsIDAsICAyNTQsIDE2LCAyLCAwLCAyNiwgMTFcbiAgICBdKSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn07XG5cbmNvbnN0IGlzU2ltZFN1cHBvcnRlZCA9ICgpOiBib29sZWFuID0+IHtcbiAgdHJ5IHtcbiAgICAvLyBUZXN0IGZvciBXZWJBc3NlbWJseSBTSU1EIGNhcGFiaWxpdHkgKGZvciBib3RoIGJyb3dzZXJzIGFuZCBOb2RlLmpzKVxuICAgIC8vIFRoaXMgdHlwZWQgYXJyYXkgaXMgYSBXZWJBc3NlbWJseSBwcm9ncmFtIGNvbnRhaW5pbmcgU0lNRCBpbnN0cnVjdGlvbnMuXG5cbiAgICAvLyBUaGUgYmluYXJ5IGRhdGEgaXMgZ2VuZXJhdGVkIGZyb20gdGhlIGZvbGxvd2luZyBjb2RlIGJ5IHdhdDJ3YXNtOlxuICAgIC8vXG4gICAgLy8gKG1vZHVsZVxuICAgIC8vICAgKHR5cGUgJHQwIChmdW5jKSlcbiAgICAvLyAgIChmdW5jICRmMCAodHlwZSAkdDApXG4gICAgLy8gICAgIChkcm9wXG4gICAgLy8gICAgICAgKGkzMng0LmRvdF9pMTZ4OF9zXG4gICAgLy8gICAgICAgICAoaTh4MTYuc3BsYXRcbiAgICAvLyAgICAgICAgICAgKGkzMi5jb25zdCAwKSlcbiAgICAvLyAgICAgICAgICh2MTI4LmNvbnN0IGkzMng0IDB4MDAwMDAwMDAgMHgwMDAwMDAwMCAweDAwMDAwMDAwIDB4MDAwMDAwMDApKSkpKVxuXG4gICAgcmV0dXJuIFdlYkFzc2VtYmx5LnZhbGlkYXRlKG5ldyBVaW50OEFycmF5KFtcbiAgICAgIDAsICAgOTcsIDExNSwgMTA5LCAxLCAwLCAwLCAwLCAxLCA0LCAxLCA5NiwgMCwgMCwgMywgMiwgMSwgMCwgMTAsIDMwLCAxLCAgIDI4LCAgMCwgNjUsIDAsXG4gICAgICAyNTMsIDE1LCAyNTMsIDEyLCAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgIDAsIDAsIDAsIDAsIDAsIDAsIDAsICAwLCAgMjUzLCAxODYsIDEsIDI2LCAxMVxuICAgIF0pKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufTtcblxuY29uc3QgZ2V0V2FzbUZpbGVOYW1lID0gKHVzZVNpbWQ6IGJvb2xlYW4sIHVzZVRocmVhZHM6IGJvb2xlYW4pID0+IHtcbiAgaWYgKHVzZVRocmVhZHMpIHtcbiAgICByZXR1cm4gdXNlU2ltZCA/ICdvcnQtd2FzbS1zaW1kLXRocmVhZGVkLndhc20nIDogJ29ydC13YXNtLXRocmVhZGVkLndhc20nO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiB1c2VTaW1kID8gJ29ydC13YXNtLXNpbWQud2FzbScgOiAnb3J0LXdhc20ud2FzbSc7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBpbml0aWFsaXplV2ViQXNzZW1ibHkgPSBhc3luYyhmbGFnczogRW52LldlYkFzc2VtYmx5RmxhZ3MpOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgaWYgKGluaXRpYWxpemVkKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG4gIGlmIChpbml0aWFsaXppbmcpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ211bHRpcGxlIGNhbGxzIHRvIFxcJ2luaXRpYWxpemVXZWJBc3NlbWJseSgpXFwnIGRldGVjdGVkLicpO1xuICB9XG4gIGlmIChhYm9ydGVkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcmV2aW91cyBjYWxsIHRvIFxcJ2luaXRpYWxpemVXZWJBc3NlbWJseSgpXFwnIGZhaWxlZC4nKTtcbiAgfVxuXG4gIGluaXRpYWxpemluZyA9IHRydWU7XG5cbiAgLy8gd2FzbSBmbGFncyBhcmUgYWxyZWFkeSBpbml0aWFsaXplZFxuICBjb25zdCB0aW1lb3V0ID0gZmxhZ3MuaW5pdFRpbWVvdXQhO1xuICBjb25zdCBudW1UaHJlYWRzID0gZmxhZ3MubnVtVGhyZWFkcyE7XG4gIGNvbnN0IHNpbWQgPSBmbGFncy5zaW1kITtcblxuICBjb25zdCB1c2VUaHJlYWRzID0gbnVtVGhyZWFkcyA+IDEgJiYgaXNNdWx0aVRocmVhZFN1cHBvcnRlZCgpO1xuICBjb25zdCB1c2VTaW1kID0gc2ltZCAmJiBpc1NpbWRTdXBwb3J0ZWQoKTtcblxuICBjb25zdCB3YXNtUHJlZml4T3ZlcnJpZGUgPSB0eXBlb2YgZmxhZ3Mud2FzbVBhdGhzID09PSAnc3RyaW5nJyA/IGZsYWdzLndhc21QYXRocyA6IHVuZGVmaW5lZDtcbiAgY29uc3Qgd2FzbUZpbGVOYW1lID0gZ2V0V2FzbUZpbGVOYW1lKGZhbHNlLCB1c2VUaHJlYWRzKTtcbiAgY29uc3Qgd2FzbU92ZXJyaWRlRmlsZU5hbWUgPSBnZXRXYXNtRmlsZU5hbWUodXNlU2ltZCwgdXNlVGhyZWFkcyk7XG4gIGNvbnN0IHdhc21QYXRoT3ZlcnJpZGUgPSB0eXBlb2YgZmxhZ3Mud2FzbVBhdGhzID09PSAnb2JqZWN0JyA/IGZsYWdzLndhc21QYXRoc1t3YXNtT3ZlcnJpZGVGaWxlTmFtZV0gOiB1bmRlZmluZWQ7XG5cbiAgbGV0IGlzVGltZW91dCA9IGZhbHNlO1xuXG4gIGNvbnN0IHRhc2tzOiBBcnJheTxQcm9taXNlPHZvaWQ+PiA9IFtdO1xuXG4gIC8vIHByb21pc2UgZm9yIHRpbWVvdXRcbiAgaWYgKHRpbWVvdXQgPiAwKSB7XG4gICAgdGFza3MucHVzaChuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIGlzVGltZW91dCA9IHRydWU7XG4gICAgICAgIHJlc29sdmUoKTtcbiAgICAgIH0sIHRpbWVvdXQpO1xuICAgIH0pKTtcbiAgfVxuXG4gIC8vIHByb21pc2UgZm9yIG1vZHVsZSBpbml0aWFsaXphdGlvblxuICB0YXNrcy5wdXNoKG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjb25zdCBmYWN0b3J5ID0gdXNlVGhyZWFkcyA/IG9ydFdhc21GYWN0b3J5VGhyZWFkZWQgOiBvcnRXYXNtRmFjdG9yeTtcbiAgICBjb25zdCBjb25maWc6IFBhcnRpYWw8T3J0V2FzbU1vZHVsZT4gPSB7XG4gICAgICBsb2NhdGVGaWxlOiAoZmlsZU5hbWU6IHN0cmluZywgc2NyaXB0RGlyZWN0b3J5OiBzdHJpbmcpID0+IHtcbiAgICAgICAgaWYgKCFCVUlMRF9ERUZTLkRJU0FCTEVfV0FTTV9USFJFQUQgJiYgdXNlVGhyZWFkcyAmJiBmaWxlTmFtZS5lbmRzV2l0aCgnLndvcmtlci5qcycpICYmXG4gICAgICAgICAgICB0eXBlb2YgQmxvYiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICByZXR1cm4gVVJMLmNyZWF0ZU9iamVjdFVSTChuZXcgQmxvYihcbiAgICAgICAgICAgICAgW1xuICAgICAgICAgICAgICAgIC8vIFRoaXMgcmVxdWlyZSgpIGZ1bmN0aW9uIGlzIGhhbmRsZWQgYnkgd2VicGFjayB0byBsb2FkIGZpbGUgY29udGVudCBvZiB0aGUgY29ycmVzcG9uZGluZyAud29ya2VyLmpzXG4gICAgICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZXF1aXJlLWltcG9ydHNcbiAgICAgICAgICAgICAgICByZXF1aXJlKCcuL2JpbmRpbmcvb3J0LXdhc20tdGhyZWFkZWQud29ya2VyLmpzJylcbiAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAge3R5cGU6ICd0ZXh0L2phdmFzY3JpcHQnfSkpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGZpbGVOYW1lID09PSB3YXNtRmlsZU5hbWUpIHtcbiAgICAgICAgICBjb25zdCBwcmVmaXg6IHN0cmluZyA9IHdhc21QcmVmaXhPdmVycmlkZSA/PyBzY3JpcHREaXJlY3Rvcnk7XG4gICAgICAgICAgcmV0dXJuIHdhc21QYXRoT3ZlcnJpZGUgPz8gcHJlZml4ICsgd2FzbU92ZXJyaWRlRmlsZU5hbWU7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gc2NyaXB0RGlyZWN0b3J5ICsgZmlsZU5hbWU7XG4gICAgICB9XG4gICAgfTtcblxuICAgIGlmICghQlVJTERfREVGUy5ESVNBQkxFX1dBU01fVEhSRUFEICYmIHVzZVRocmVhZHMpIHtcbiAgICAgIGlmICh0eXBlb2YgQmxvYiA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgY29uZmlnLm1haW5TY3JpcHRVcmxPckJsb2IgPSBwYXRoLmpvaW4oX19kaXJuYW1lLCAnb3J0LXdhc20tdGhyZWFkZWQuanMnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IHNjcmlwdFNvdXJjZUNvZGUgPSBgdmFyIG9ydFdhc21UaHJlYWRlZD0oZnVuY3Rpb24oKXt2YXIgX3NjcmlwdERpcjtyZXR1cm4gJHtmYWN0b3J5LnRvU3RyaW5nKCl9fSkoKTtgO1xuICAgICAgICBjb25maWcubWFpblNjcmlwdFVybE9yQmxvYiA9IG5ldyBCbG9iKFtzY3JpcHRTb3VyY2VDb2RlXSwge3R5cGU6ICd0ZXh0L2phdmFzY3JpcHQnfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZmFjdG9yeShjb25maWcpLnRoZW4oXG4gICAgICAgIC8vIHdhc20gbW9kdWxlIGluaXRpYWxpemVkIHN1Y2Nlc3NmdWxseVxuICAgICAgICBtb2R1bGUgPT4ge1xuICAgICAgICAgIGluaXRpYWxpemluZyA9IGZhbHNlO1xuICAgICAgICAgIGluaXRpYWxpemVkID0gdHJ1ZTtcbiAgICAgICAgICB3YXNtID0gbW9kdWxlO1xuICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgfSxcbiAgICAgICAgLy8gd2FzbSBtb2R1bGUgZmFpbGVkIHRvIGluaXRpYWxpemVcbiAgICAgICAgKHdoYXQpID0+IHtcbiAgICAgICAgICBpbml0aWFsaXppbmcgPSBmYWxzZTtcbiAgICAgICAgICBhYm9ydGVkID0gdHJ1ZTtcbiAgICAgICAgICByZWplY3Qod2hhdCk7XG4gICAgICAgIH0pO1xuICB9KSk7XG5cbiAgYXdhaXQgUHJvbWlzZS5yYWNlKHRhc2tzKTtcblxuICBpZiAoaXNUaW1lb3V0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBXZWJBc3NlbWJseSBiYWNrZW5kIGluaXRpYWxpemluZyBmYWlsZWQgZHVlIHRvIHRpbWVvdXQ6ICR7dGltZW91dH1tc2ApO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0SW5zdGFuY2UgPSAoKTogT3J0V2FzbU1vZHVsZSA9PiB7XG4gIGlmIChpbml0aWFsaXplZCAmJiB3YXNtKSB7XG4gICAgcmV0dXJuIHdhc207XG4gIH1cblxuICB0aHJvdyBuZXcgRXJyb3IoJ1dlYkFzc2VtYmx5IGlzIG5vdCBpbml0aWFsaXplZCB5ZXQuJyk7XG59O1xuXG5leHBvcnQgY29uc3QgZGlzcG9zZSA9ICgpOiB2b2lkID0+IHtcbiAgaWYgKGluaXRpYWxpemVkICYmICFpbml0aWFsaXppbmcgJiYgIWFib3J0ZWQpIHtcbiAgICBpbml0aWFsaXppbmcgPSB0cnVlO1xuXG4gICAgKHdhc20gYXMgT3J0V2FzbVRocmVhZGVkTW9kdWxlKS5QVGhyZWFkPy50ZXJtaW5hdGVBbGxUaHJlYWRzKCk7XG4gICAgd2FzbSA9IHVuZGVmaW5lZDtcblxuICAgIGluaXRpYWxpemluZyA9IGZhbHNlO1xuICAgIGluaXRpYWxpemVkID0gZmFsc2U7XG4gICAgYWJvcnRlZCA9IHRydWU7XG4gIH1cbn07XG4iLCJcbmltcG9ydCB3b3JrZXIgZnJvbSBcIiEhLi4vLi4vLi4vbm9kZV9tb2R1bGVzL3dvcmtlci1sb2FkZXIvZGlzdC9ydW50aW1lL2lubGluZS5qc1wiO1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBXb3JrZXJfZm4oKSB7XG4gIHJldHVybiB3b3JrZXIoXCIvKiFcXG4qIE9OTlggUnVudGltZSBXZWIgdjEuMTQuMFxcbiogQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXFxuKiBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXFxuKi9cXG4vKioqKioqLyAoKCkgPT4geyAvLyB3ZWJwYWNrQm9vdHN0cmFwXFxuLyoqKioqKi8gXFx0dmFyIF9fd2VicGFja19tb2R1bGVzX18gPSAoe1xcblxcbi8qKiovIFxcXCIuL2xpYi93YXNtL2JpbmRpbmcvb3J0LXdhc20tdGhyZWFkZWQuanNcXFwiOlxcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxcXFxuICAhKioqIC4vbGliL3dhc20vYmluZGluZy9vcnQtd2FzbS10aHJlYWRlZC5qcyAqKiohXFxuICBcXFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXFxuLyoqKi8gKChtb2R1bGUsIF9fdW51c2VkX3dlYnBhY2tfZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykgPT4ge1xcblxcbnZhciBfX2ZpbGVuYW1lID0gXFxcIi9pbmRleC5qc1xcXCI7XFxudmFyIF9fZGlybmFtZSA9IFxcXCIvXFxcIjtcXG5cXHJcXG52YXIgb3J0V2FzbVRocmVhZGVkID0gKCgpID0+IHtcXHJcXG4gIHZhciBfc2NyaXB0RGlyID0gdHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJyAmJiBkb2N1bWVudC5jdXJyZW50U2NyaXB0ID8gZG9jdW1lbnQuY3VycmVudFNjcmlwdC5zcmMgOiB1bmRlZmluZWQ7XFxyXFxuICBpZiAodHJ1ZSkgX3NjcmlwdERpciA9IF9zY3JpcHREaXIgfHwgX19maWxlbmFtZTtcXHJcXG4gIHJldHVybiAoXFxyXFxuZnVuY3Rpb24ob3J0V2FzbVRocmVhZGVkKSB7XFxyXFxuICBvcnRXYXNtVGhyZWFkZWQgPSBvcnRXYXNtVGhyZWFkZWQgfHwge307XFxyXFxuXFxyXFxuXFxyXFxuZnVuY3Rpb24gZCgpe20uYnVmZmVyIT1uJiZwKG0uYnVmZmVyKTtyZXR1cm4gYWF9ZnVuY3Rpb24gcSgpe20uYnVmZmVyIT1uJiZwKG0uYnVmZmVyKTtyZXR1cm4gYmF9ZnVuY3Rpb24gcigpe20uYnVmZmVyIT1uJiZwKG0uYnVmZmVyKTtyZXR1cm4gY2F9ZnVuY3Rpb24gdigpe20uYnVmZmVyIT1uJiZwKG0uYnVmZmVyKTtyZXR1cm4gZGF9ZnVuY3Rpb24gZWEoKXttLmJ1ZmZlciE9biYmcChtLmJ1ZmZlcik7cmV0dXJuIGZhfXZhciB4O3h8fCh4PXR5cGVvZiBvcnRXYXNtVGhyZWFkZWQgIT09ICd1bmRlZmluZWQnID8gb3J0V2FzbVRocmVhZGVkIDoge30pO3ZhciBoYSxpYTt4LnJlYWR5PW5ldyBQcm9taXNlKGZ1bmN0aW9uKGEsYil7aGE9YTtpYT1ifSk7XFxyXFxudmFyIGphPU9iamVjdC5hc3NpZ24oe30seCksa2E9XFxcIi4vdGhpcy5wcm9ncmFtXFxcIixsYT0oYSxiKT0+e3Rocm93IGI7fSxtYT1cXFwib2JqZWN0XFxcIj09dHlwZW9mIHdpbmRvdyx5PVxcXCJmdW5jdGlvblxcXCI9PXR5cGVvZiBpbXBvcnRTY3JpcHRzLEI9XFxcIm9iamVjdFxcXCI9PXR5cGVvZiBwcm9jZXNzJiZcXFwib2JqZWN0XFxcIj09dHlwZW9mIHByb2Nlc3MudmVyc2lvbnMmJlxcXCJzdHJpbmdcXFwiPT10eXBlb2YgcHJvY2Vzcy52ZXJzaW9ucy5ub2RlLEM9eC5FTlZJUk9OTUVOVF9JU19QVEhSRUFEfHwhMSxEPVxcXCJcXFwiO2Z1bmN0aW9uIG5hKGEpe3JldHVybiB4LmxvY2F0ZUZpbGU/eC5sb2NhdGVGaWxlKGEsRCk6RCthfXZhciBvYSxwYSxxYSxmcyxyYSxzYTtcXHJcXG5pZihCKXtEPXk/KF9fd2VicGFja19yZXF1aXJlX18oLyohIHBhdGggKi8gXFxcIj83NWM2XFxcIikuZGlybmFtZSkoRCkrXFxcIi9cXFwiOl9fZGlybmFtZStcXFwiL1xcXCI7c2E9KCk9PntyYXx8KGZzPV9fd2VicGFja19yZXF1aXJlX18oLyohIGZzICovIFxcXCI/NjNjOFxcXCIpLHJhPV9fd2VicGFja19yZXF1aXJlX18oLyohIHBhdGggKi8gXFxcIj83NWM2XFxcIikpfTtvYT1mdW5jdGlvbihiLGMpe3NhKCk7Yj1yYS5ub3JtYWxpemUoYik7cmV0dXJuIGZzLnJlYWRGaWxlU3luYyhiLGM/dm9pZCAwOlxcXCJ1dGY4XFxcIil9O3FhPWI9PntiPW9hKGIsITApO2IuYnVmZmVyfHwoYj1uZXcgVWludDhBcnJheShiKSk7cmV0dXJuIGJ9O3BhPShiLGMsZSk9PntzYSgpO2I9cmEubm9ybWFsaXplKGIpO2ZzLnJlYWRGaWxlKGIsZnVuY3Rpb24oZixoKXtmP2UoZik6YyhoLmJ1ZmZlcil9KX07MTxwcm9jZXNzLmFyZ3YubGVuZ3RoJiYoa2E9cHJvY2Vzcy5hcmd2WzFdLnJlcGxhY2UoL1xcXFxcXFxcL2csXFxcIi9cXFwiKSk7cHJvY2Vzcy5hcmd2LnNsaWNlKDIpO3Byb2Nlc3Mub24oXFxcInVuY2F1Z2h0RXhjZXB0aW9uXFxcIixmdW5jdGlvbihiKXtpZighKGIgaW5zdGFuY2VvZiBFKSl0aHJvdyBiO30pO3Byb2Nlc3Mub24oXFxcInVuaGFuZGxlZFJlamVjdGlvblxcXCIsXFxyXFxuZnVuY3Rpb24oYil7dGhyb3cgYjt9KTtsYT0oYixjKT0+e2lmKEYoKSl0aHJvdyBwcm9jZXNzLmV4aXRDb2RlPWIsYztjIGluc3RhbmNlb2YgRXx8RyhcXFwiZXhpdGluZyBkdWUgdG8gZXhjZXB0aW9uOiBcXFwiK2MpO3Byb2Nlc3MuZXhpdChiKX07eC5pbnNwZWN0PWZ1bmN0aW9uKCl7cmV0dXJuXFxcIltFbXNjcmlwdGVuIE1vZHVsZSBvYmplY3RdXFxcIn07bGV0IGE7dHJ5e2E9X193ZWJwYWNrX3JlcXVpcmVfXygvKiEgd29ya2VyX3RocmVhZHMgKi8gXFxcIj9jNmY3XFxcIil9Y2F0Y2goYil7dGhyb3cgY29uc29sZS5lcnJvcignVGhlIFxcXCJ3b3JrZXJfdGhyZWFkc1xcXCIgbW9kdWxlIGlzIG5vdCBzdXBwb3J0ZWQgaW4gdGhpcyBub2RlLmpzIGJ1aWxkIC0gcGVyaGFwcyBhIG5ld2VyIHZlcnNpb24gaXMgbmVlZGVkPycpLGI7fV9fd2VicGFja19yZXF1aXJlX18uZy5Xb3JrZXI9YS5Xb3JrZXJ9ZWxzZSBpZihtYXx8eSl5P0Q9c2VsZi5sb2NhdGlvbi5ocmVmOlxcXCJ1bmRlZmluZWRcXFwiIT10eXBlb2YgZG9jdW1lbnQmJmRvY3VtZW50LmN1cnJlbnRTY3JpcHQmJihEPWRvY3VtZW50LmN1cnJlbnRTY3JpcHQuc3JjKSxcXHJcXG5fc2NyaXB0RGlyJiYoRD1fc2NyaXB0RGlyKSwwIT09RC5pbmRleE9mKFxcXCJibG9iOlxcXCIpP0Q9RC5zdWJzdHIoMCxELnJlcGxhY2UoL1s/I10uKi8sXFxcIlxcXCIpLmxhc3RJbmRleE9mKFxcXCIvXFxcIikrMSk6RD1cXFwiXFxcIixCfHwob2E9YT0+e3ZhciBiPW5ldyBYTUxIdHRwUmVxdWVzdDtiLm9wZW4oXFxcIkdFVFxcXCIsYSwhMSk7Yi5zZW5kKG51bGwpO3JldHVybiBiLnJlc3BvbnNlVGV4dH0seSYmKHFhPWE9Pnt2YXIgYj1uZXcgWE1MSHR0cFJlcXVlc3Q7Yi5vcGVuKFxcXCJHRVRcXFwiLGEsITEpO2IucmVzcG9uc2VUeXBlPVxcXCJhcnJheWJ1ZmZlclxcXCI7Yi5zZW5kKG51bGwpO3JldHVybiBuZXcgVWludDhBcnJheShiLnJlc3BvbnNlKX0pLHBhPShhLGIsYyk9Pnt2YXIgZT1uZXcgWE1MSHR0cFJlcXVlc3Q7ZS5vcGVuKFxcXCJHRVRcXFwiLGEsITApO2UucmVzcG9uc2VUeXBlPVxcXCJhcnJheWJ1ZmZlclxcXCI7ZS5vbmxvYWQ9KCk9PnsyMDA9PWUuc3RhdHVzfHwwPT1lLnN0YXR1cyYmZS5yZXNwb25zZT9iKGUucmVzcG9uc2UpOmMoKX07ZS5vbmVycm9yPVxcclxcbmM7ZS5zZW5kKG51bGwpfSk7QiYmXFxcInVuZGVmaW5lZFxcXCI9PXR5cGVvZiBwZXJmb3JtYW5jZSYmKF9fd2VicGFja19yZXF1aXJlX18uZy5wZXJmb3JtYW5jZT0oX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgcGVyZl9ob29rcyAqLyBcXFwiPzY3NGZcXFwiKS5wZXJmb3JtYW5jZSkpO3ZhciB0YT1jb25zb2xlLmxvZy5iaW5kKGNvbnNvbGUpLHVhPWNvbnNvbGUud2Fybi5iaW5kKGNvbnNvbGUpO0ImJihzYSgpLHRhPWE9PmZzLndyaXRlU3luYygxLGErXFxcIlxcXFxuXFxcIiksdWE9YT0+ZnMud3JpdGVTeW5jKDIsYStcXFwiXFxcXG5cXFwiKSk7dmFyIHZhPXgucHJpbnR8fHRhLEc9eC5wcmludEVycnx8dWE7T2JqZWN0LmFzc2lnbih4LGphKTtqYT1udWxsO3gudGhpc1Byb2dyYW0mJihrYT14LnRoaXNQcm9ncmFtKTt4LnF1aXQmJihsYT14LnF1aXQpO3ZhciBIO3gud2FzbUJpbmFyeSYmKEg9eC53YXNtQmluYXJ5KTt2YXIgbm9FeGl0UnVudGltZT14Lm5vRXhpdFJ1bnRpbWV8fCExO1xcXCJvYmplY3RcXFwiIT10eXBlb2YgV2ViQXNzZW1ibHkmJkkoXFxcIm5vIG5hdGl2ZSB3YXNtIHN1cHBvcnQgZGV0ZWN0ZWRcXFwiKTtcXHJcXG52YXIgbSx3YSx4YT0hMSx5YT1cXFwidW5kZWZpbmVkXFxcIiE9dHlwZW9mIFRleHREZWNvZGVyP25ldyBUZXh0RGVjb2RlcihcXFwidXRmOFxcXCIpOnZvaWQgMDtcXHJcXG5mdW5jdGlvbiB6YShhLGIsYyl7Yj4+Pj0wO3ZhciBlPWIrYztmb3IoYz1iO2FbY10mJiEoYz49ZSk7KSsrYztpZigxNjxjLWImJmEuYnVmZmVyJiZ5YSlyZXR1cm4geWEuZGVjb2RlKGEuYnVmZmVyIGluc3RhbmNlb2YgU2hhcmVkQXJyYXlCdWZmZXI/YS5zbGljZShiLGMpOmEuc3ViYXJyYXkoYixjKSk7Zm9yKGU9XFxcIlxcXCI7YjxjOyl7dmFyIGY9YVtiKytdO2lmKGYmMTI4KXt2YXIgaD1hW2IrK10mNjM7aWYoMTkyPT0oZiYyMjQpKWUrPVN0cmluZy5mcm9tQ2hhckNvZGUoKGYmMzEpPDw2fGgpO2Vsc2V7dmFyIGs9YVtiKytdJjYzO2Y9MjI0PT0oZiYyNDApPyhmJjE1KTw8MTJ8aDw8NnxrOihmJjcpPDwxOHxoPDwxMnxrPDw2fGFbYisrXSY2Mzs2NTUzNj5mP2UrPVN0cmluZy5mcm9tQ2hhckNvZGUoZik6KGYtPTY1NTM2LGUrPVN0cmluZy5mcm9tQ2hhckNvZGUoNTUyOTZ8Zj4+MTAsNTYzMjB8ZiYxMDIzKSl9fWVsc2UgZSs9U3RyaW5nLmZyb21DaGFyQ29kZShmKX1yZXR1cm4gZX1cXHJcXG5mdW5jdGlvbiBBYShhLGIpe3JldHVybihhPj4+PTApP3phKHEoKSxhLGIpOlxcXCJcXFwifVxcclxcbmZ1bmN0aW9uIEJhKGEsYixjLGUpe2M+Pj49MDtpZighKDA8ZSkpcmV0dXJuIDA7dmFyIGY9YztlPWMrZS0xO2Zvcih2YXIgaD0wO2g8YS5sZW5ndGg7KytoKXt2YXIgaz1hLmNoYXJDb2RlQXQoaCk7aWYoNTUyOTY8PWsmJjU3MzQzPj1rKXt2YXIgbD1hLmNoYXJDb2RlQXQoKytoKTtrPTY1NTM2KygoayYxMDIzKTw8MTApfGwmMTAyM31pZigxMjc+PWspe2lmKGM+PWUpYnJlYWs7YltjKys+Pj4wXT1rfWVsc2V7aWYoMjA0Nz49ayl7aWYoYysxPj1lKWJyZWFrO2JbYysrPj4+MF09MTkyfGs+PjZ9ZWxzZXtpZig2NTUzNT49ayl7aWYoYysyPj1lKWJyZWFrO2JbYysrPj4+MF09MjI0fGs+PjEyfWVsc2V7aWYoYyszPj1lKWJyZWFrO2JbYysrPj4+MF09MjQwfGs+PjE4O2JbYysrPj4+MF09MTI4fGs+PjEyJjYzfWJbYysrPj4+MF09MTI4fGs+PjYmNjN9YltjKys+Pj4wXT0xMjh8ayY2M319YltjPj4+MF09MDtyZXR1cm4gYy1mfVxcclxcbmZ1bmN0aW9uIENhKGEpe2Zvcih2YXIgYj0wLGM9MDtjPGEubGVuZ3RoOysrYyl7dmFyIGU9YS5jaGFyQ29kZUF0KGMpOzEyNz49ZT9iKys6MjA0Nz49ZT9iKz0yOjU1Mjk2PD1lJiY1NzM0Mz49ZT8oYis9NCwrK2MpOmIrPTN9cmV0dXJuIGJ9dmFyIG4sYWEsYmEsY2EsZGEsZmE7QyYmKG49eC5idWZmZXIpO2Z1bmN0aW9uIHAoYSl7bj1hO3guSEVBUDg9YWE9bmV3IEludDhBcnJheShhKTt4LkhFQVAxNj1uZXcgSW50MTZBcnJheShhKTt4LkhFQVAzMj1jYT1uZXcgSW50MzJBcnJheShhKTt4LkhFQVBVOD1iYT1uZXcgVWludDhBcnJheShhKTt4LkhFQVBVMTY9bmV3IFVpbnQxNkFycmF5KGEpO3guSEVBUFUzMj1kYT1uZXcgVWludDMyQXJyYXkoYSk7eC5IRUFQRjMyPW5ldyBGbG9hdDMyQXJyYXkoYSk7eC5IRUFQRjY0PWZhPW5ldyBGbG9hdDY0QXJyYXkoYSl9dmFyIERhPXguSU5JVElBTF9NRU1PUll8fDE2Nzc3MjE2O1xcclxcbmlmKEMpbT14Lndhc21NZW1vcnksbj14LmJ1ZmZlcjtlbHNlIGlmKHgud2FzbU1lbW9yeSltPXgud2FzbU1lbW9yeTtlbHNlIGlmKG09bmV3IFdlYkFzc2VtYmx5Lk1lbW9yeSh7aW5pdGlhbDpEYS82NTUzNixtYXhpbXVtOjY1NTM2LHNoYXJlZDohMH0pLCEobS5idWZmZXIgaW5zdGFuY2VvZiBTaGFyZWRBcnJheUJ1ZmZlcikpdGhyb3cgRyhcXFwicmVxdWVzdGVkIGEgc2hhcmVkIFdlYkFzc2VtYmx5Lk1lbW9yeSBidXQgdGhlIHJldHVybmVkIGJ1ZmZlciBpcyBub3QgYSBTaGFyZWRBcnJheUJ1ZmZlciwgaW5kaWNhdGluZyB0aGF0IHdoaWxlIHRoZSBicm93c2VyIGhhcyBTaGFyZWRBcnJheUJ1ZmZlciBpdCBkb2VzIG5vdCBoYXZlIFdlYkFzc2VtYmx5IHRocmVhZHMgc3VwcG9ydCAtIHlvdSBtYXkgbmVlZCB0byBzZXQgYSBmbGFnXFxcIiksQiYmY29uc29sZS5sb2coXFxcIihvbiBub2RlIHlvdSBtYXkgbmVlZDogLS1leHBlcmltZW50YWwtd2FzbS10aHJlYWRzIC0tZXhwZXJpbWVudGFsLXdhc20tYnVsay1tZW1vcnkgYW5kIGFsc28gdXNlIGEgcmVjZW50IHZlcnNpb24pXFxcIiksXFxyXFxuRXJyb3IoXFxcImJhZCBtZW1vcnlcXFwiKTttJiYobj1tLmJ1ZmZlcik7RGE9bi5ieXRlTGVuZ3RoO3Aobik7dmFyIEVhLEZhPVtdLEdhPVtdLEhhPVtdLElhPVtdLEphPTA7ZnVuY3Rpb24gRigpe3JldHVybiBub0V4aXRSdW50aW1lfHwwPEphfWZ1bmN0aW9uIEthKCl7dmFyIGE9eC5wcmVSdW4uc2hpZnQoKTtGYS51bnNoaWZ0KGEpfXZhciBMPTAsTGE9bnVsbCxNPW51bGw7ZnVuY3Rpb24gSShhKXtpZihDKXBvc3RNZXNzYWdlKHtjbWQ6XFxcIm9uQWJvcnRcXFwiLGFyZzphfSk7ZWxzZSBpZih4Lm9uQWJvcnQpeC5vbkFib3J0KGEpO2E9XFxcIkFib3J0ZWQoXFxcIithK1xcXCIpXFxcIjtHKGEpO3hhPSEwO2E9bmV3IFdlYkFzc2VtYmx5LlJ1bnRpbWVFcnJvcihhK1xcXCIuIEJ1aWxkIHdpdGggLXNBU1NFUlRJT05TIGZvciBtb3JlIGluZm8uXFxcIik7aWEoYSk7dGhyb3cgYTt9ZnVuY3Rpb24gTWEoKXtyZXR1cm4gTy5zdGFydHNXaXRoKFxcXCJkYXRhOmFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbTtiYXNlNjQsXFxcIil9dmFyIE87Tz1cXFwib3J0LXdhc20tdGhyZWFkZWQud2FzbVxcXCI7XFxyXFxuTWEoKXx8KE89bmEoTykpO2Z1bmN0aW9uIE5hKCl7dmFyIGE9Tzt0cnl7aWYoYT09TyYmSClyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoSCk7aWYocWEpcmV0dXJuIHFhKGEpO3Rocm93XFxcImJvdGggYXN5bmMgYW5kIHN5bmMgZmV0Y2hpbmcgb2YgdGhlIHdhc20gZmFpbGVkXFxcIjt9Y2F0Y2goYil7SShiKX19XFxyXFxuZnVuY3Rpb24gT2EoKXtpZighSCYmKG1hfHx5KSl7aWYoXFxcImZ1bmN0aW9uXFxcIj09dHlwZW9mIGZldGNoJiYhTy5zdGFydHNXaXRoKFxcXCJmaWxlOi8vXFxcIikpcmV0dXJuIGZldGNoKE8se2NyZWRlbnRpYWxzOlxcXCJzYW1lLW9yaWdpblxcXCJ9KS50aGVuKGZ1bmN0aW9uKGEpe2lmKCFhLm9rKXRocm93XFxcImZhaWxlZCB0byBsb2FkIHdhc20gYmluYXJ5IGZpbGUgYXQgJ1xcXCIrTytcXFwiJ1xcXCI7cmV0dXJuIGEuYXJyYXlCdWZmZXIoKX0pLmNhdGNoKGZ1bmN0aW9uKCl7cmV0dXJuIE5hKCl9KTtpZihwYSlyZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24oYSxiKXtwYShPLGZ1bmN0aW9uKGMpe2EobmV3IFVpbnQ4QXJyYXkoYykpfSxiKX0pfXJldHVybiBQcm9taXNlLnJlc29sdmUoKS50aGVuKGZ1bmN0aW9uKCl7cmV0dXJuIE5hKCl9KX12YXIgUGE9e307XFxyXFxuZnVuY3Rpb24gRShhKXt0aGlzLm5hbWU9XFxcIkV4aXRTdGF0dXNcXFwiO3RoaXMubWVzc2FnZT1cXFwiUHJvZ3JhbSB0ZXJtaW5hdGVkIHdpdGggZXhpdChcXFwiK2ErXFxcIilcXFwiO3RoaXMuc3RhdHVzPWF9ZnVuY3Rpb24gUWEoYSl7KGE9UC5WYlthXSl8fEkoKTtQLm1jKGEpfWZ1bmN0aW9uIFJhKGEpe3ZhciBiPVAuQ2MoKTtpZighYilyZXR1cm4gNjtQLmFjLnB1c2goYik7UC5WYlthLlViXT1iO2IuVWI9YS5VYjt2YXIgYz17Y21kOlxcXCJydW5cXFwiLHN0YXJ0X3JvdXRpbmU6YS5JYyxhcmc6YS56YyxwdGhyZWFkX3B0cjphLlVifTtiLiRiPSgpPT57Yy50aW1lPXBlcmZvcm1hbmNlLm5vdygpO2IucG9zdE1lc3NhZ2UoYyxhLk5jKX07Yi5sb2FkZWQmJihiLiRiKCksZGVsZXRlIGIuJGIpO3JldHVybiAwfWZ1bmN0aW9uIFNhKGEpe2lmKEMpcmV0dXJuIFEoMSwxLGEpO2lmKCFGKCkpe1Aub2MoKTtpZih4Lm9uRXhpdCl4Lm9uRXhpdChhKTt4YT0hMH1sYShhLG5ldyBFKGEpKX1cXHJcXG5mdW5jdGlvbiBUYShhLGIpe2lmKCFiJiZDKXRocm93IFVhKGEpLFxcXCJ1bndpbmRcXFwiO0YoKXx8Q3x8KFZhKCksUihIYSksV2EoMCksWGFbMV0ubGVuZ3RoJiZZYSgxLDEwKSxYYVsyXS5sZW5ndGgmJllhKDIsMTApLFAub2MoKSk7U2EoYSl9XFxyXFxudmFyIFA9e1liOltdLGFjOltdLHFjOltdLFZiOnt9LGZjOmZ1bmN0aW9uKCl7QyYmUC5FYygpfSxQYzpmdW5jdGlvbigpe30sRWM6ZnVuY3Rpb24oKXtQLnJlY2VpdmVPYmplY3RUcmFuc2Zlcj1QLkdjO1AudGhyZWFkSW5pdFRMUz1QLnBjO1Auc2V0RXhpdFN0YXR1cz1QLm5jO25vRXhpdFJ1bnRpbWU9ITF9LG5jOmZ1bmN0aW9uKCl7fSxvYzpmdW5jdGlvbigpe2Zvcih2YXIgYSBvZiBPYmplY3QudmFsdWVzKFAuVmIpKVAubWMoYSk7Zm9yKGEgb2YgUC5ZYilhLnRlcm1pbmF0ZSgpO1AuWWI9W119LG1jOmZ1bmN0aW9uKGEpe3ZhciBiPWEuVWI7ZGVsZXRlIFAuVmJbYl07UC5ZYi5wdXNoKGEpO1AuYWMuc3BsaWNlKFAuYWMuaW5kZXhPZihhKSwxKTthLlViPTA7WmEoYil9LEdjOmZ1bmN0aW9uKCl7fSxwYzpmdW5jdGlvbigpe1AucWMuZm9yRWFjaChhPT5hKCkpfSxGYzpmdW5jdGlvbihhLGIpe2Eub25tZXNzYWdlPWM9PntjPWMuZGF0YTt2YXIgZT1jLmNtZDthLlViJiYoUC5CYz1hLlViKTtcXHJcXG5pZihjLnRhcmdldFRocmVhZCYmYy50YXJnZXRUaHJlYWQhPSRhKCkpe3ZhciBmPVAuVmJbYy5RY107Zj9mLnBvc3RNZXNzYWdlKGMsYy50cmFuc2Zlckxpc3QpOkcoJ0ludGVybmFsIGVycm9yISBXb3JrZXIgc2VudCBhIG1lc3NhZ2UgXFxcIicrZSsnXFxcIiB0byB0YXJnZXQgcHRocmVhZCAnK2MudGFyZ2V0VGhyZWFkK1xcXCIsIGJ1dCB0aGF0IHRocmVhZCBubyBsb25nZXIgZXhpc3RzIVxcXCIpfWVsc2UgaWYoXFxcInByb2Nlc3NQcm94eWluZ1F1ZXVlXFxcIj09PWUpYWIoYy5xdWV1ZSk7ZWxzZSBpZihcXFwic3Bhd25UaHJlYWRcXFwiPT09ZSlSYShjKTtlbHNlIGlmKFxcXCJjbGVhbnVwVGhyZWFkXFxcIj09PWUpUWEoYy50aHJlYWQpO2Vsc2UgaWYoXFxcImtpbGxUaHJlYWRcXFwiPT09ZSljPWMudGhyZWFkLGU9UC5WYltjXSxkZWxldGUgUC5WYltjXSxlLnRlcm1pbmF0ZSgpLFphKGMpLFAuYWMuc3BsaWNlKFAuYWMuaW5kZXhPZihlKSwxKSxlLlViPTA7ZWxzZSBpZihcXFwiY2FuY2VsVGhyZWFkXFxcIj09PWUpUC5WYltjLnRocmVhZF0ucG9zdE1lc3NhZ2Uoe2NtZDpcXFwiY2FuY2VsXFxcIn0pO1xcclxcbmVsc2UgaWYoXFxcImxvYWRlZFxcXCI9PT1lKWEubG9hZGVkPSEwLGImJmIoYSksYS4kYiYmKGEuJGIoKSxkZWxldGUgYS4kYik7ZWxzZSBpZihcXFwicHJpbnRcXFwiPT09ZSl2YShcXFwiVGhyZWFkIFxcXCIrYy50aHJlYWRJZCtcXFwiOiBcXFwiK2MudGV4dCk7ZWxzZSBpZihcXFwicHJpbnRFcnJcXFwiPT09ZSlHKFxcXCJUaHJlYWQgXFxcIitjLnRocmVhZElkK1xcXCI6IFxcXCIrYy50ZXh0KTtlbHNlIGlmKFxcXCJhbGVydFxcXCI9PT1lKWFsZXJ0KFxcXCJUaHJlYWQgXFxcIitjLnRocmVhZElkK1xcXCI6IFxcXCIrYy50ZXh0KTtlbHNlIGlmKFxcXCJzZXRpbW1lZGlhdGVcXFwiPT09Yy50YXJnZXQpYS5wb3N0TWVzc2FnZShjKTtlbHNlIGlmKFxcXCJvbkFib3J0XFxcIj09PWUpe2lmKHgub25BYm9ydCl4Lm9uQWJvcnQoYy5hcmcpfWVsc2UgZSYmRyhcXFwid29ya2VyIHNlbnQgYW4gdW5rbm93biBjb21tYW5kIFxcXCIrZSk7UC5CYz12b2lkIDB9O2Eub25lcnJvcj1jPT57RyhcXFwid29ya2VyIHNlbnQgYW4gZXJyb3IhIFxcXCIrYy5maWxlbmFtZStcXFwiOlxcXCIrYy5saW5lbm8rXFxcIjogXFxcIitjLm1lc3NhZ2UpO3Rocm93IGM7fTtCJiZcXHJcXG4oYS5vbihcXFwibWVzc2FnZVxcXCIsZnVuY3Rpb24oYyl7YS5vbm1lc3NhZ2Uoe2RhdGE6Y30pfSksYS5vbihcXFwiZXJyb3JcXFwiLGZ1bmN0aW9uKGMpe2Eub25lcnJvcihjKX0pLGEub24oXFxcImRldGFjaGVkRXhpdFxcXCIsZnVuY3Rpb24oKXt9KSk7YS5wb3N0TWVzc2FnZSh7Y21kOlxcXCJsb2FkXFxcIix1cmxPckJsb2I6eC5tYWluU2NyaXB0VXJsT3JCbG9ifHxfc2NyaXB0RGlyLHdhc21NZW1vcnk6bSx3YXNtTW9kdWxlOndhfSl9LHljOmZ1bmN0aW9uKCl7dmFyIGE9bmEoXFxcIm9ydC13YXNtLXRocmVhZGVkLndvcmtlci5qc1xcXCIpO1AuWWIucHVzaChuZXcgV29ya2VyKGEpKX0sQ2M6ZnVuY3Rpb24oKXswPT1QLlliLmxlbmd0aCYmKFAueWMoKSxQLkZjKFAuWWJbMF0pKTtyZXR1cm4gUC5ZYi5wb3AoKX19O3guUFRocmVhZD1QO2Z1bmN0aW9uIFIoYSl7Zm9yKDswPGEubGVuZ3RoOylhLnNoaWZ0KCkoeCl9ZnVuY3Rpb24gYmIoYSl7dmFyIGI9UygpO2E9YSgpO1UoYik7cmV0dXJuIGF9XFxyXFxueC5lc3RhYmxpc2hTdGFja1NwYWNlPWZ1bmN0aW9uKCl7dmFyIGE9JGEoKSxiPXIoKVthKzQ0Pj4yPj4+MF07YT1yKClbYSs0OD4+Mj4+PjBdO2NiKGIsYi1hKTtVKGIpfTtmdW5jdGlvbiBVYShhKXtpZihDKXJldHVybiBRKDIsMCxhKTt0cnl7VGEoYSl9Y2F0Y2goYil7YiBpbnN0YW5jZW9mIEV8fFxcXCJ1bndpbmRcXFwiPT1ifHxsYSgxLGIpfX12YXIgZGI9W107ZnVuY3Rpb24gVihhKXt2YXIgYj1kYlthXTtifHwoYT49ZGIubGVuZ3RoJiYoZGIubGVuZ3RoPWErMSksZGJbYV09Yj1FYS5nZXQoYSkpO3JldHVybiBifXguaW52b2tlRW50cnlQb2ludD1mdW5jdGlvbihhLGIpe2E9VihhKShiKTtGKCk/UC5uYyhhKTplYihhKX07ZnVuY3Rpb24gZmIoYSxiKXtkKCkuc2V0KGEsYj4+PjApfXZhciBnYj1bXSxoYj0wLFc9MDtcXHJcXG5mdW5jdGlvbiBYKGEpe3RoaXMuWmI9YTt0aGlzLlNiPWEtMjQ7dGhpcy54Yz1mdW5jdGlvbihiKXt2KClbdGhpcy5TYis0Pj4yPj4+MF09Yn07dGhpcy5iYz1mdW5jdGlvbigpe3JldHVybiB2KClbdGhpcy5TYis0Pj4yPj4+MF19O3RoaXMud2M9ZnVuY3Rpb24oYil7digpW3RoaXMuU2IrOD4+Mj4+PjBdPWJ9O3RoaXMuRGM9ZnVuY3Rpb24oKXtyZXR1cm4gdigpW3RoaXMuU2IrOD4+Mj4+PjBdfTt0aGlzLnJjPWZ1bmN0aW9uKCl7cigpW3RoaXMuU2I+PjI+Pj4wXT0wfTt0aGlzLmhjPWZ1bmN0aW9uKGIpe2I9Yj8xOjA7ZCgpW3RoaXMuU2IrMTI+PjA+Pj4wXT1ifTt0aGlzLnVjPWZ1bmN0aW9uKCl7cmV0dXJuIDAhPWQoKVt0aGlzLlNiKzEyPj4wPj4+MF19O3RoaXMuaWM9ZnVuY3Rpb24oYil7Yj1iPzE6MDtkKClbdGhpcy5TYisxMz4+MD4+PjBdPWJ9O3RoaXMua2M9ZnVuY3Rpb24oKXtyZXR1cm4gMCE9ZCgpW3RoaXMuU2IrMTM+PjA+Pj4wXX07dGhpcy5mYz1mdW5jdGlvbihiLGMpe3RoaXMuY2MoMCk7XFxyXFxudGhpcy54YyhiKTt0aGlzLndjKGMpO3RoaXMucmMoKTt0aGlzLmhjKCExKTt0aGlzLmljKCExKX07dGhpcy5zYz1mdW5jdGlvbigpe0F0b21pY3MuYWRkKHIoKSx0aGlzLlNiPj4yLDEpfTt0aGlzLkhjPWZ1bmN0aW9uKCl7cmV0dXJuIDE9PT1BdG9taWNzLnN1YihyKCksdGhpcy5TYj4+MiwxKX07dGhpcy5jYz1mdW5jdGlvbihiKXt2KClbdGhpcy5TYisxNj4+Mj4+PjBdPWJ9O3RoaXMudGM9ZnVuY3Rpb24oKXtyZXR1cm4gdigpW3RoaXMuU2IrMTY+PjI+Pj4wXX07dGhpcy52Yz1mdW5jdGlvbigpe2lmKGliKHRoaXMuYmMoKSkpcmV0dXJuIHYoKVt0aGlzLlpiPj4yPj4+MF07dmFyIGI9dGhpcy50YygpO3JldHVybiAwIT09Yj9iOnRoaXMuWmJ9fWZ1bmN0aW9uIGpiKGEpe3JldHVybiBrYigobmV3IFgoYSkpLlNiKX1mdW5jdGlvbiBsYihhLGIsYyxlKXtyZXR1cm4gQz9RKDMsMSxhLGIsYyxlKTptYihhLGIsYyxlKX1cXHJcXG5mdW5jdGlvbiBtYihhLGIsYyxlKXtpZihcXFwidW5kZWZpbmVkXFxcIj09dHlwZW9mIFNoYXJlZEFycmF5QnVmZmVyKXJldHVybiBHKFxcXCJDdXJyZW50IGVudmlyb25tZW50IGRvZXMgbm90IHN1cHBvcnQgU2hhcmVkQXJyYXlCdWZmZXIsIHB0aHJlYWRzIGFyZSBub3QgYXZhaWxhYmxlIVxcXCIpLDY7dmFyIGY9W107aWYoQyYmMD09PWYubGVuZ3RoKXJldHVybiBsYihhLGIsYyxlKTthPXtJYzpjLFViOmEsemM6ZSxOYzpmfTtyZXR1cm4gQz8oYS5PYz1cXFwic3Bhd25UaHJlYWRcXFwiLHBvc3RNZXNzYWdlKGEsZiksMCk6UmEoYSl9ZnVuY3Rpb24gbmIoYSxiLGMpe3JldHVybiBDP1EoNCwxLGEsYixjKTowfWZ1bmN0aW9uIG9iKGEsYil7aWYoQylyZXR1cm4gUSg1LDEsYSxiKX1mdW5jdGlvbiBwYihhLGIpe2lmKEMpcmV0dXJuIFEoNiwxLGEsYil9ZnVuY3Rpb24gcWIoYSxiLGMpe2lmKEMpcmV0dXJuIFEoNywxLGEsYixjKX1mdW5jdGlvbiByYihhLGIsYyl7cmV0dXJuIEM/USg4LDEsYSxiLGMpOjB9XFxyXFxuZnVuY3Rpb24gc2IoYSxiKXtpZihDKXJldHVybiBRKDksMSxhLGIpfWZ1bmN0aW9uIHRiKGEsYixjKXtpZihDKXJldHVybiBRKDEwLDEsYSxiLGMpfWZ1bmN0aW9uIHViKGEsYixjLGUpe2lmKEMpcmV0dXJuIFEoMTEsMSxhLGIsYyxlKX1mdW5jdGlvbiB2YihhLGIsYyxlKXtpZihDKXJldHVybiBRKDEyLDEsYSxiLGMsZSl9ZnVuY3Rpb24gd2IoYSxiLGMsZSl7aWYoQylyZXR1cm4gUSgxMywxLGEsYixjLGUpfWZ1bmN0aW9uIHhiKGEpe2lmKEMpcmV0dXJuIFEoMTQsMSxhKX1mdW5jdGlvbiB5YihhLGIpe2lmKEMpcmV0dXJuIFEoMTUsMSxhLGIpfWZ1bmN0aW9uIHpiKGEsYixjKXtpZihDKXJldHVybiBRKDE2LDEsYSxiLGMpfWZ1bmN0aW9uIGFiKGEpe0F0b21pY3Muc3RvcmUocigpLGE+PjIsMSk7JGEoKSYmQWIoYSk7QXRvbWljcy5jb21wYXJlRXhjaGFuZ2UocigpLGE+PjIsMSwwKX14LmV4ZWN1dGVOb3RpZmllZFByb3h5aW5nUXVldWU9YWI7XFxyXFxuZnVuY3Rpb24gQmIoYSl7cmV0dXJuIHYoKVthPj4+Ml0rNDI5NDk2NzI5NipyKClbYSs0Pj4+Ml19ZnVuY3Rpb24gQ2IoYSxiLGMsZSxmLGgpe3JldHVybiBDP1EoMTcsMSxhLGIsYyxlLGYsaCk6LTUyfWZ1bmN0aW9uIERiKGEsYixjLGUsZixoKXtpZihDKXJldHVybiBRKDE4LDEsYSxiLGMsZSxmLGgpfWZ1bmN0aW9uIEViKGEpe3ZhciBiPUNhKGEpKzEsYz1GYihiKTtjJiZCYShhLGQoKSxjLGIpO3JldHVybiBjfVxcclxcbmZ1bmN0aW9uIEdiKGEsYixjKXtmdW5jdGlvbiBlKHQpe3JldHVybih0PXQudG9UaW1lU3RyaW5nKCkubWF0Y2goL1xcXFwoKFtBLVphLXogXSspXFxcXCkkLykpP3RbMV06XFxcIkdNVFxcXCJ9aWYoQylyZXR1cm4gUSgxOSwxLGEsYixjKTt2YXIgZj0obmV3IERhdGUpLmdldEZ1bGxZZWFyKCksaD1uZXcgRGF0ZShmLDAsMSksaz1uZXcgRGF0ZShmLDYsMSk7Zj1oLmdldFRpbWV6b25lT2Zmc2V0KCk7dmFyIGw9ay5nZXRUaW1lem9uZU9mZnNldCgpLHU9TWF0aC5tYXgoZixsKTtyKClbYT4+Mj4+PjBdPTYwKnU7cigpW2I+PjI+Pj4wXT1OdW1iZXIoZiE9bCk7YT1lKGgpO2I9ZShrKTthPUViKGEpO2I9RWIoYik7bDxmPyh2KClbYz4+Mj4+PjBdPWEsdigpW2MrND4+Mj4+PjBdPWIpOih2KClbYz4+Mj4+PjBdPWIsdigpW2MrND4+Mj4+PjBdPWEpfWZ1bmN0aW9uIEhiKGEsYixjKXtIYi5BY3x8KEhiLkFjPSEwLEdiKGEsYixjKSl9dmFyIEliLEpiO1xcclxcbkpiPUI/KCk9Pnt2YXIgYT1wcm9jZXNzLmhydGltZSgpO3JldHVybiAxRTMqYVswXSthWzFdLzFFNn06Qz8oKT0+cGVyZm9ybWFuY2Uubm93KCkteC5fX3BlcmZvcm1hbmNlX25vd19jbG9ja19kcmlmdDooKT0+cGVyZm9ybWFuY2Uubm93KCk7ZnVuY3Rpb24gUShhLGIpe3ZhciBjPWFyZ3VtZW50cy5sZW5ndGgtMixlPWFyZ3VtZW50cztyZXR1cm4gYmIoKCk9Pntmb3IodmFyIGY9S2IoOCpjKSxoPWY+PjMsaz0wO2s8YztrKyspe3ZhciBsPWVbMitrXTtlYSgpW2graz4+PjBdPWx9cmV0dXJuIExiKGEsYyxmLGIpfSl9dmFyIE1iPVtdLE5iPXt9O1xcclxcbmZ1bmN0aW9uIE9iKCl7aWYoIVBiKXt2YXIgYT17VVNFUjpcXFwid2ViX3VzZXJcXFwiLExPR05BTUU6XFxcIndlYl91c2VyXFxcIixQQVRIOlxcXCIvXFxcIixQV0Q6XFxcIi9cXFwiLEhPTUU6XFxcIi9ob21lL3dlYl91c2VyXFxcIixMQU5HOihcXFwib2JqZWN0XFxcIj09dHlwZW9mIG5hdmlnYXRvciYmbmF2aWdhdG9yLmxhbmd1YWdlcyYmbmF2aWdhdG9yLmxhbmd1YWdlc1swXXx8XFxcIkNcXFwiKS5yZXBsYWNlKFxcXCItXFxcIixcXFwiX1xcXCIpK1xcXCIuVVRGLThcXFwiLF86a2F8fFxcXCIuL3RoaXMucHJvZ3JhbVxcXCJ9LGI7Zm9yKGIgaW4gTmIpdm9pZCAwPT09TmJbYl0/ZGVsZXRlIGFbYl06YVtiXT1OYltiXTt2YXIgYz1bXTtmb3IoYiBpbiBhKWMucHVzaChiK1xcXCI9XFxcIithW2JdKTtQYj1jfXJldHVybiBQYn12YXIgUGI7XFxyXFxuZnVuY3Rpb24gUWIoYSxiKXtpZihDKXJldHVybiBRKDIwLDEsYSxiKTt2YXIgYz0wO09iKCkuZm9yRWFjaChmdW5jdGlvbihlLGYpe3ZhciBoPWIrYztmPXYoKVthKzQqZj4+Mj4+PjBdPWg7Zm9yKGg9MDtoPGUubGVuZ3RoOysraClkKClbZisrPj4wPj4+MF09ZS5jaGFyQ29kZUF0KGgpO2QoKVtmPj4wPj4+MF09MDtjKz1lLmxlbmd0aCsxfSk7cmV0dXJuIDB9ZnVuY3Rpb24gUmIoYSxiKXtpZihDKXJldHVybiBRKDIxLDEsYSxiKTt2YXIgYz1PYigpO3YoKVthPj4yPj4+MF09Yy5sZW5ndGg7dmFyIGU9MDtjLmZvckVhY2goZnVuY3Rpb24oZil7ZSs9Zi5sZW5ndGgrMX0pO3YoKVtiPj4yPj4+MF09ZTtyZXR1cm4gMH1mdW5jdGlvbiBTYihhKXtyZXR1cm4gQz9RKDIyLDEsYSk6NTJ9ZnVuY3Rpb24gVGIoYSxiLGMsZSl7cmV0dXJuIEM/USgyMywxLGEsYixjLGUpOjUyfWZ1bmN0aW9uIFViKGEsYixjLGUsZil7cmV0dXJuIEM/USgyNCwxLGEsYixjLGUsZik6NzB9XFxyXFxudmFyIFhhPVtudWxsLFtdLFtdXTtmdW5jdGlvbiBZYShhLGIpe3ZhciBjPVhhW2FdOzA9PT1ifHwxMD09PWI/KCgxPT09YT92YTpHKSh6YShjLDApKSxjLmxlbmd0aD0wKTpjLnB1c2goYil9ZnVuY3Rpb24gVmIoYSxiLGMsZSl7aWYoQylyZXR1cm4gUSgyNSwxLGEsYixjLGUpO2Zvcih2YXIgZj0wLGg9MDtoPGM7aCsrKXt2YXIgaz12KClbYj4+Mj4+PjBdLGw9digpW2IrND4+Mj4+PjBdO2IrPTg7Zm9yKHZhciB1PTA7dTxsO3UrKylZYShhLHEoKVtrK3U+Pj4wXSk7Zis9bH12KClbZT4+Mj4+PjBdPWY7cmV0dXJuIDB9dmFyIFk9MDtcXHJcXG5mdW5jdGlvbiBXYigpe2lmKFxcXCJvYmplY3RcXFwiPT10eXBlb2YgY3J5cHRvJiZcXFwiZnVuY3Rpb25cXFwiPT10eXBlb2YgY3J5cHRvLmdldFJhbmRvbVZhbHVlcyl7dmFyIGE9bmV3IFVpbnQ4QXJyYXkoMSk7cmV0dXJuKCk9PntjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKGEpO3JldHVybiBhWzBdfX1pZihCKXRyeXt2YXIgYj1fX3dlYnBhY2tfcmVxdWlyZV9fKE9iamVjdChmdW5jdGlvbiB3ZWJwYWNrTWlzc2luZ01vZHVsZSgpIHsgdmFyIGUgPSBuZXcgRXJyb3IoXFxcIkNhbm5vdCBmaW5kIG1vZHVsZSAnY3J5cHRvJ1xcXCIpOyBlLmNvZGUgPSAnTU9EVUxFX05PVF9GT1VORCc7IHRocm93IGU7IH0oKSkpO3JldHVybigpPT5iLnJhbmRvbUJ5dGVzKDEpWzBdfWNhdGNoKGMpe31yZXR1cm4oKT0+SShcXFwicmFuZG9tRGV2aWNlXFxcIil9ZnVuY3Rpb24gWGIoYSxiKXtYYi5sY3x8KFhiLmxjPVdiKCkpO2Zvcih2YXIgYz0wO2M8YjtjKyspZCgpW2ErYz4+MD4+PjBdPVhiLmxjKCk7cmV0dXJuIDB9ZnVuY3Rpb24gWWIoYSl7cmV0dXJuIDA9PT1hJTQmJigwIT09YSUxMDB8fDA9PT1hJTQwMCl9dmFyIFpiPVszMSwyOSwzMSwzMCwzMSwzMCwzMSwzMSwzMCwzMSwzMCwzMV0sJGI9WzMxLDI4LDMxLDMwLDMxLDMwLDMxLDMxLDMwLDMxLDMwLDMxXTtcXHJcXG5mdW5jdGlvbiBhYyhhKXt2YXIgYj1BcnJheShDYShhKSsxKTtCYShhLGIsMCxiLmxlbmd0aCk7cmV0dXJuIGJ9XFxyXFxuZnVuY3Rpb24gYmMoYSxiLGMsZSl7ZnVuY3Rpb24gZihnLHcseil7Zm9yKGc9XFxcIm51bWJlclxcXCI9PXR5cGVvZiBnP2cudG9TdHJpbmcoKTpnfHxcXFwiXFxcIjtnLmxlbmd0aDx3OylnPXpbMF0rZztyZXR1cm4gZ31mdW5jdGlvbiBoKGcsdyl7cmV0dXJuIGYoZyx3LFxcXCIwXFxcIil9ZnVuY3Rpb24gayhnLHcpe2Z1bmN0aW9uIHooVCl7cmV0dXJuIDA+VD8tMTowPFQ/MTowfXZhciBOOzA9PT0oTj16KGcuZ2V0RnVsbFllYXIoKS13LmdldEZ1bGxZZWFyKCkpKSYmMD09PShOPXooZy5nZXRNb250aCgpLXcuZ2V0TW9udGgoKSkpJiYoTj16KGcuZ2V0RGF0ZSgpLXcuZ2V0RGF0ZSgpKSk7cmV0dXJuIE59ZnVuY3Rpb24gbChnKXtzd2l0Y2goZy5nZXREYXkoKSl7Y2FzZSAwOnJldHVybiBuZXcgRGF0ZShnLmdldEZ1bGxZZWFyKCktMSwxMSwyOSk7Y2FzZSAxOnJldHVybiBnO2Nhc2UgMjpyZXR1cm4gbmV3IERhdGUoZy5nZXRGdWxsWWVhcigpLDAsMyk7Y2FzZSAzOnJldHVybiBuZXcgRGF0ZShnLmdldEZ1bGxZZWFyKCksXFxyXFxuMCwyKTtjYXNlIDQ6cmV0dXJuIG5ldyBEYXRlKGcuZ2V0RnVsbFllYXIoKSwwLDEpO2Nhc2UgNTpyZXR1cm4gbmV3IERhdGUoZy5nZXRGdWxsWWVhcigpLTEsMTEsMzEpO2Nhc2UgNjpyZXR1cm4gbmV3IERhdGUoZy5nZXRGdWxsWWVhcigpLTEsMTEsMzApfX1mdW5jdGlvbiB1KGcpe3ZhciB3PWcuV2I7Zm9yKGc9bmV3IERhdGUoKG5ldyBEYXRlKGcuWGIrMTkwMCwwLDEpKS5nZXRUaW1lKCkpOzA8dzspe3ZhciB6PWcuZ2V0TW9udGgoKSxOPShZYihnLmdldEZ1bGxZZWFyKCkpP1piOiRiKVt6XTtpZih3Pk4tZy5nZXREYXRlKCkpdy09Ti1nLmdldERhdGUoKSsxLGcuc2V0RGF0ZSgxKSwxMT56P2cuc2V0TW9udGgoeisxKTooZy5zZXRNb250aCgwKSxnLnNldEZ1bGxZZWFyKGcuZ2V0RnVsbFllYXIoKSsxKSk7ZWxzZXtnLnNldERhdGUoZy5nZXREYXRlKCkrdyk7YnJlYWt9fXo9bmV3IERhdGUoZy5nZXRGdWxsWWVhcigpKzEsMCw0KTt3PWwobmV3IERhdGUoZy5nZXRGdWxsWWVhcigpLFxcclxcbjAsNCkpO3o9bCh6KTtyZXR1cm4gMD49ayh3LGcpPzA+PWsoeixnKT9nLmdldEZ1bGxZZWFyKCkrMTpnLmdldEZ1bGxZZWFyKCk6Zy5nZXRGdWxsWWVhcigpLTF9dmFyIHQ9cigpW2UrNDA+PjI+Pj4wXTtlPXtMYzpyKClbZT4+Mj4+PjBdLEtjOnIoKVtlKzQ+PjI+Pj4wXSxkYzpyKClbZSs4Pj4yPj4+MF0samM6cigpW2UrMTI+PjI+Pj4wXSxlYzpyKClbZSsxNj4+Mj4+PjBdLFhiOnIoKVtlKzIwPj4yPj4+MF0sVGI6cigpW2UrMjQ+PjI+Pj4wXSxXYjpyKClbZSsyOD4+Mj4+PjBdLFJjOnIoKVtlKzMyPj4yPj4+MF0sSmM6cigpW2UrMzY+PjI+Pj4wXSxNYzp0P0FhKHQpOlxcXCJcXFwifTtjPUFhKGMpO3Q9e1xcXCIlY1xcXCI6XFxcIiVhICViICVkICVIOiVNOiVTICVZXFxcIixcXFwiJURcXFwiOlxcXCIlbS8lZC8leVxcXCIsXFxcIiVGXFxcIjpcXFwiJVktJW0tJWRcXFwiLFxcXCIlaFxcXCI6XFxcIiViXFxcIixcXFwiJXJcXFwiOlxcXCIlSTolTTolUyAlcFxcXCIsXFxcIiVSXFxcIjpcXFwiJUg6JU1cXFwiLFxcXCIlVFxcXCI6XFxcIiVIOiVNOiVTXFxcIixcXFwiJXhcXFwiOlxcXCIlbS8lZC8leVxcXCIsXFxcIiVYXFxcIjpcXFwiJUg6JU06JVNcXFwiLFxcXCIlRWNcXFwiOlxcXCIlY1xcXCIsXFxcIiVFQ1xcXCI6XFxcIiVDXFxcIixcXHJcXG5cXFwiJUV4XFxcIjpcXFwiJW0vJWQvJXlcXFwiLFxcXCIlRVhcXFwiOlxcXCIlSDolTTolU1xcXCIsXFxcIiVFeVxcXCI6XFxcIiV5XFxcIixcXFwiJUVZXFxcIjpcXFwiJVlcXFwiLFxcXCIlT2RcXFwiOlxcXCIlZFxcXCIsXFxcIiVPZVxcXCI6XFxcIiVlXFxcIixcXFwiJU9IXFxcIjpcXFwiJUhcXFwiLFxcXCIlT0lcXFwiOlxcXCIlSVxcXCIsXFxcIiVPbVxcXCI6XFxcIiVtXFxcIixcXFwiJU9NXFxcIjpcXFwiJU1cXFwiLFxcXCIlT1NcXFwiOlxcXCIlU1xcXCIsXFxcIiVPdVxcXCI6XFxcIiV1XFxcIixcXFwiJU9VXFxcIjpcXFwiJVVcXFwiLFxcXCIlT1ZcXFwiOlxcXCIlVlxcXCIsXFxcIiVPd1xcXCI6XFxcIiV3XFxcIixcXFwiJU9XXFxcIjpcXFwiJVdcXFwiLFxcXCIlT3lcXFwiOlxcXCIleVxcXCJ9O2Zvcih2YXIgQSBpbiB0KWM9Yy5yZXBsYWNlKG5ldyBSZWdFeHAoQSxcXFwiZ1xcXCIpLHRbQV0pO3ZhciBLPVxcXCJTdW5kYXkgTW9uZGF5IFR1ZXNkYXkgV2VkbmVzZGF5IFRodXJzZGF5IEZyaWRheSBTYXR1cmRheVxcXCIuc3BsaXQoXFxcIiBcXFwiKSxKPVxcXCJKYW51YXJ5IEZlYnJ1YXJ5IE1hcmNoIEFwcmlsIE1heSBKdW5lIEp1bHkgQXVndXN0IFNlcHRlbWJlciBPY3RvYmVyIE5vdmVtYmVyIERlY2VtYmVyXFxcIi5zcGxpdChcXFwiIFxcXCIpO3Q9e1xcXCIlYVxcXCI6ZnVuY3Rpb24oZyl7cmV0dXJuIEtbZy5UYl0uc3Vic3RyaW5nKDAsMyl9LFxcXCIlQVxcXCI6ZnVuY3Rpb24oZyl7cmV0dXJuIEtbZy5UYl19LFxcclxcblxcXCIlYlxcXCI6ZnVuY3Rpb24oZyl7cmV0dXJuIEpbZy5lY10uc3Vic3RyaW5nKDAsMyl9LFxcXCIlQlxcXCI6ZnVuY3Rpb24oZyl7cmV0dXJuIEpbZy5lY119LFxcXCIlQ1xcXCI6ZnVuY3Rpb24oZyl7cmV0dXJuIGgoKGcuWGIrMTkwMCkvMTAwfDAsMil9LFxcXCIlZFxcXCI6ZnVuY3Rpb24oZyl7cmV0dXJuIGgoZy5qYywyKX0sXFxcIiVlXFxcIjpmdW5jdGlvbihnKXtyZXR1cm4gZihnLmpjLDIsXFxcIiBcXFwiKX0sXFxcIiVnXFxcIjpmdW5jdGlvbihnKXtyZXR1cm4gdShnKS50b1N0cmluZygpLnN1YnN0cmluZygyKX0sXFxcIiVHXFxcIjpmdW5jdGlvbihnKXtyZXR1cm4gdShnKX0sXFxcIiVIXFxcIjpmdW5jdGlvbihnKXtyZXR1cm4gaChnLmRjLDIpfSxcXFwiJUlcXFwiOmZ1bmN0aW9uKGcpe2c9Zy5kYzswPT1nP2c9MTI6MTI8ZyYmKGctPTEyKTtyZXR1cm4gaChnLDIpfSxcXFwiJWpcXFwiOmZ1bmN0aW9uKGcpe2Zvcih2YXIgdz0wLHo9MDt6PD1nLmVjLTE7dys9KFliKGcuWGIrMTkwMCk/WmI6JGIpW3orK10pO3JldHVybiBoKGcuamMrdywzKX0sXFxcIiVtXFxcIjpmdW5jdGlvbihnKXtyZXR1cm4gaChnLmVjK1xcclxcbjEsMil9LFxcXCIlTVxcXCI6ZnVuY3Rpb24oZyl7cmV0dXJuIGgoZy5LYywyKX0sXFxcIiVuXFxcIjpmdW5jdGlvbigpe3JldHVyblxcXCJcXFxcblxcXCJ9LFxcXCIlcFxcXCI6ZnVuY3Rpb24oZyl7cmV0dXJuIDA8PWcuZGMmJjEyPmcuZGM/XFxcIkFNXFxcIjpcXFwiUE1cXFwifSxcXFwiJVNcXFwiOmZ1bmN0aW9uKGcpe3JldHVybiBoKGcuTGMsMil9LFxcXCIldFxcXCI6ZnVuY3Rpb24oKXtyZXR1cm5cXFwiXFxcXHRcXFwifSxcXFwiJXVcXFwiOmZ1bmN0aW9uKGcpe3JldHVybiBnLlRifHw3fSxcXFwiJVVcXFwiOmZ1bmN0aW9uKGcpe3JldHVybiBoKE1hdGguZmxvb3IoKGcuV2IrNy1nLlRiKS83KSwyKX0sXFxcIiVWXFxcIjpmdW5jdGlvbihnKXt2YXIgdz1NYXRoLmZsb29yKChnLldiKzctKGcuVGIrNiklNykvNyk7Mj49KGcuVGIrMzcxLWcuV2ItMiklNyYmdysrO2lmKHcpNTM9PXcmJih6PShnLlRiKzM3MS1nLldiKSU3LDQ9PXp8fDM9PXomJlliKGcuWGIpfHwodz0xKSk7ZWxzZXt3PTUyO3ZhciB6PShnLlRiKzctZy5XYi0xKSU3Oyg0PT16fHw1PT16JiZZYihnLlhiJTQwMC0xKSkmJncrK31yZXR1cm4gaCh3LFxcclxcbjIpfSxcXFwiJXdcXFwiOmZ1bmN0aW9uKGcpe3JldHVybiBnLlRifSxcXFwiJVdcXFwiOmZ1bmN0aW9uKGcpe3JldHVybiBoKE1hdGguZmxvb3IoKGcuV2IrNy0oZy5UYis2KSU3KS83KSwyKX0sXFxcIiV5XFxcIjpmdW5jdGlvbihnKXtyZXR1cm4oZy5YYisxOTAwKS50b1N0cmluZygpLnN1YnN0cmluZygyKX0sXFxcIiVZXFxcIjpmdW5jdGlvbihnKXtyZXR1cm4gZy5YYisxOTAwfSxcXFwiJXpcXFwiOmZ1bmN0aW9uKGcpe2c9Zy5KYzt2YXIgdz0wPD1nO2c9TWF0aC5hYnMoZykvNjA7cmV0dXJuKHc/XFxcIitcXFwiOlxcXCItXFxcIikrU3RyaW5nKFxcXCIwMDAwXFxcIisoZy82MCoxMDArZyU2MCkpLnNsaWNlKC00KX0sXFxcIiVaXFxcIjpmdW5jdGlvbihnKXtyZXR1cm4gZy5NY30sXFxcIiUlXFxcIjpmdW5jdGlvbigpe3JldHVyblxcXCIlXFxcIn19O2M9Yy5yZXBsYWNlKC8lJS9nLFxcXCJcXFxceDAwXFxcXHgwMFxcXCIpO2ZvcihBIGluIHQpYy5pbmNsdWRlcyhBKSYmKGM9Yy5yZXBsYWNlKG5ldyBSZWdFeHAoQSxcXFwiZ1xcXCIpLHRbQV0oZSkpKTtjPWMucmVwbGFjZSgvXFxcXDBcXFxcMC9nLFxcXCIlXFxcIik7QT1hYyhjKTtpZihBLmxlbmd0aD5cXHJcXG5iKXJldHVybiAwO2ZiKEEsYSk7cmV0dXJuIEEubGVuZ3RoLTF9UC5mYygpO1xcclxcbnZhciBjYz1bbnVsbCxTYSxVYSxsYixuYixvYixwYixxYixyYixzYix0Yix1Yix2Yix3Yix4Yix5Yix6YixDYixEYixHYixRYixSYixTYixUYixVYixWYl0sUGM9e2I6ZnVuY3Rpb24oYSl7cmV0dXJuIEZiKGErMjQpKzI0fSxuOmZ1bmN0aW9uKGEpe2E9bmV3IFgoYSk7YS51YygpfHwoYS5oYyghMCksaGItLSk7YS5pYyghMSk7Z2IucHVzaChhKTthLnNjKCk7cmV0dXJuIGEudmMoKX0sbWE6ZnVuY3Rpb24oYSl7RyhcXFwiVW5leHBlY3RlZCBleGNlcHRpb24gdGhyb3duLCB0aGlzIGlzIG5vdCBwcm9wZXJseSBzdXBwb3J0ZWQgLSBhYm9ydGluZ1xcXCIpO3hhPSEwO3Rocm93IGE7fSx4OmZ1bmN0aW9uKCl7WigwKTt2YXIgYT1nYi5wb3AoKTtpZihhLkhjKCkmJiFhLmtjKCkpe3ZhciBiPWEuRGMoKTtiJiZWKGIpKGEuWmIpO2piKGEuWmIpfVc9MH0sZTpmdW5jdGlvbigpe3ZhciBhPVc7aWYoIWEpcmV0dXJuIFk9MDt2YXIgYj1uZXcgWChhKTtiLmNjKGEpO3ZhciBjPWIuYmMoKTtpZighYylyZXR1cm4gWT1cXHJcXG4wLGE7Zm9yKHZhciBlPUFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cyksZj0wO2Y8ZS5sZW5ndGg7ZisrKXt2YXIgaD1lW2ZdO2lmKDA9PT1ofHxoPT09YylicmVhaztpZihkYyhoLGMsYi5TYisxNikpcmV0dXJuIFk9aCxhfVk9YztyZXR1cm4gYX0sbDpmdW5jdGlvbigpe3ZhciBhPVc7aWYoIWEpcmV0dXJuIFk9MDt2YXIgYj1uZXcgWChhKTtiLmNjKGEpO3ZhciBjPWIuYmMoKTtpZighYylyZXR1cm4gWT0wLGE7Zm9yKHZhciBlPUFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cyksZj0wO2Y8ZS5sZW5ndGg7ZisrKXt2YXIgaD1lW2ZdO2lmKDA9PT1ofHxoPT09YylicmVhaztpZihkYyhoLGMsYi5TYisxNikpcmV0dXJuIFk9aCxhfVk9YztyZXR1cm4gYX0saDpmdW5jdGlvbigpe3ZhciBhPVc7aWYoIWEpcmV0dXJuIFk9MDt2YXIgYj1uZXcgWChhKTtiLmNjKGEpO3ZhciBjPWIuYmMoKTtpZighYylyZXR1cm4gWT0wLGE7Zm9yKHZhciBlPUFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cyksXFxyXFxuZj0wO2Y8ZS5sZW5ndGg7ZisrKXt2YXIgaD1lW2ZdO2lmKDA9PT1ofHxoPT09YylicmVhaztpZihkYyhoLGMsYi5TYisxNikpcmV0dXJuIFk9aCxhfVk9YztyZXR1cm4gYX0sdDpqYixNOmZ1bmN0aW9uKCl7dmFyIGE9Z2IucG9wKCk7YXx8SShcXFwibm8gZXhjZXB0aW9uIHRvIHRocm93XFxcIik7dmFyIGI9YS5aYjthLmtjKCl8fChnYi5wdXNoKGEpLGEuaWMoITApLGEuaGMoITEpLGhiKyspO1c9Yjt0aHJvdyBiO30sYzpmdW5jdGlvbihhLGIsYyl7KG5ldyBYKGEpKS5mYyhiLGMpO1c9YTtoYisrO3Rocm93IGE7fSxwYTpmdW5jdGlvbigpe3JldHVybiBoYn0sRmE6ZnVuY3Rpb24oYSl7ZWMoYSwheSwxLCFtYSk7UC5wYygpfSxUOmZ1bmN0aW9uKGEpe0M/cG9zdE1lc3NhZ2Uoe2NtZDpcXFwiY2xlYW51cFRocmVhZFxcXCIsdGhyZWFkOmF9KTpRYShhKX0seGE6bWIsajpmdW5jdGlvbihhKXtXfHwoVz1hKTt0aHJvdyBhO30sSDpuYixNYTpvYix1YTpwYix3YTpxYixvYTpyYixLYTpzYixDYTp0YixKYTp1YixcXHJcXG5WOnZiLHZhOndiLHNhOnhiLExhOnliLHRhOnpiLFRhOmZ1bmN0aW9uKCl7fSxYOmZ1bmN0aW9uKCl7SShcXFwiVG8gdXNlIGRsb3BlbiwgeW91IG5lZWQgZW5hYmxlIGR5bmFtaWMgbGlua2luZywgc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9lbXNjcmlwdGVuLWNvcmUvZW1zY3JpcHRlbi93aWtpL0xpbmtpbmdcXFwiKX0sVWE6ZnVuY3Rpb24oKXtJKFxcXCJUbyB1c2UgZGxvcGVuLCB5b3UgbmVlZCBlbmFibGUgZHluYW1pYyBsaW5raW5nLCBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2Vtc2NyaXB0ZW4tY29yZS9lbXNjcmlwdGVuL3dpa2kvTGlua2luZ1xcXCIpfSxXOmZ1bmN0aW9uKCl7cmV0dXJuIERhdGUubm93KCl9LHlhOmZ1bmN0aW9uKCl7cmV0dXJuIDIwOTcxNTJ9LE9hOmZ1bmN0aW9uKCl7cmV0dXJuITB9LHphOmZ1bmN0aW9uKGEsYixjLGUpe2lmKGE9PWIpc2V0VGltZW91dCgoKT0+YWIoZSkpO2Vsc2UgaWYoQylwb3N0TWVzc2FnZSh7dGFyZ2V0VGhyZWFkOmEsY21kOlxcXCJwcm9jZXNzUHJveHlpbmdRdWV1ZVxcXCIsXFxyXFxucXVldWU6ZX0pO2Vsc2V7YT1QLlZiW2FdO2lmKCFhKXJldHVybjthLnBvc3RNZXNzYWdlKHtjbWQ6XFxcInByb2Nlc3NQcm94eWluZ1F1ZXVlXFxcIixxdWV1ZTplfSl9cmV0dXJuIDF9LEVhOmZ1bmN0aW9uKCl7cmV0dXJuLTF9LFBhOmZ1bmN0aW9uKGEsYil7YT1uZXcgRGF0ZSgxRTMqQmIoYSkpO3IoKVtiPj4yPj4+MF09YS5nZXRVVENTZWNvbmRzKCk7cigpW2IrND4+Mj4+PjBdPWEuZ2V0VVRDTWludXRlcygpO3IoKVtiKzg+PjI+Pj4wXT1hLmdldFVUQ0hvdXJzKCk7cigpW2IrMTI+PjI+Pj4wXT1hLmdldFVUQ0RhdGUoKTtyKClbYisxNj4+Mj4+PjBdPWEuZ2V0VVRDTW9udGgoKTtyKClbYisyMD4+Mj4+PjBdPWEuZ2V0VVRDRnVsbFllYXIoKS0xOTAwO3IoKVtiKzI0Pj4yPj4+MF09YS5nZXRVVENEYXkoKTthPShhLmdldFRpbWUoKS1EYXRlLlVUQyhhLmdldFVUQ0Z1bGxZZWFyKCksMCwxLDAsMCwwLDApKS84NjRFNXwwO3IoKVtiKzI4Pj4yPj4+MF09YX0sUWE6ZnVuY3Rpb24oYSxiKXthPVxcclxcbm5ldyBEYXRlKDFFMypCYihhKSk7cigpW2I+PjI+Pj4wXT1hLmdldFNlY29uZHMoKTtyKClbYis0Pj4yPj4+MF09YS5nZXRNaW51dGVzKCk7cigpW2IrOD4+Mj4+PjBdPWEuZ2V0SG91cnMoKTtyKClbYisxMj4+Mj4+PjBdPWEuZ2V0RGF0ZSgpO3IoKVtiKzE2Pj4yPj4+MF09YS5nZXRNb250aCgpO3IoKVtiKzIwPj4yPj4+MF09YS5nZXRGdWxsWWVhcigpLTE5MDA7cigpW2IrMjQ+PjI+Pj4wXT1hLmdldERheSgpO3ZhciBjPW5ldyBEYXRlKGEuZ2V0RnVsbFllYXIoKSwwLDEpLGU9KGEuZ2V0VGltZSgpLWMuZ2V0VGltZSgpKS84NjRFNXwwO3IoKVtiKzI4Pj4yPj4+MF09ZTtyKClbYiszNj4+Mj4+PjBdPS0oNjAqYS5nZXRUaW1lem9uZU9mZnNldCgpKTtlPShuZXcgRGF0ZShhLmdldEZ1bGxZZWFyKCksNiwxKSkuZ2V0VGltZXpvbmVPZmZzZXQoKTtjPWMuZ2V0VGltZXpvbmVPZmZzZXQoKTthPShlIT1jJiZhLmdldFRpbWV6b25lT2Zmc2V0KCk9PU1hdGgubWluKGMsZSkpfDA7cigpW2IrXFxyXFxuMzI+PjI+Pj4wXT1hfSxSYTpmdW5jdGlvbihhKXt2YXIgYj1uZXcgRGF0ZShyKClbYSsyMD4+Mj4+PjBdKzE5MDAscigpW2ErMTY+PjI+Pj4wXSxyKClbYSsxMj4+Mj4+PjBdLHIoKVthKzg+PjI+Pj4wXSxyKClbYSs0Pj4yPj4+MF0scigpW2E+PjI+Pj4wXSwwKSxjPXIoKVthKzMyPj4yPj4+MF0sZT1iLmdldFRpbWV6b25lT2Zmc2V0KCksZj1uZXcgRGF0ZShiLmdldEZ1bGxZZWFyKCksMCwxKSxoPShuZXcgRGF0ZShiLmdldEZ1bGxZZWFyKCksNiwxKSkuZ2V0VGltZXpvbmVPZmZzZXQoKSxrPWYuZ2V0VGltZXpvbmVPZmZzZXQoKSxsPU1hdGgubWluKGssaCk7MD5jP3IoKVthKzMyPj4yPj4+MF09TnVtYmVyKGghPWsmJmw9PWUpOjA8YyE9KGw9PWUpJiYoaD1NYXRoLm1heChrLGgpLGIuc2V0VGltZShiLmdldFRpbWUoKSs2RTQqKCgwPGM/bDpoKS1lKSkpO3IoKVthKzI0Pj4yPj4+MF09Yi5nZXREYXkoKTtjPShiLmdldFRpbWUoKS1mLmdldFRpbWUoKSkvODY0RTV8MDtyKClbYSsyOD4+XFxyXFxuMj4+PjBdPWM7cigpW2E+PjI+Pj4wXT1iLmdldFNlY29uZHMoKTtyKClbYSs0Pj4yPj4+MF09Yi5nZXRNaW51dGVzKCk7cigpW2ErOD4+Mj4+PjBdPWIuZ2V0SG91cnMoKTtyKClbYSsxMj4+Mj4+PjBdPWIuZ2V0RGF0ZSgpO3IoKVthKzE2Pj4yPj4+MF09Yi5nZXRNb250aCgpO3JldHVybiBiLmdldFRpbWUoKS8xRTN8MH0sQWE6Q2IsQmE6RGIsU2E6SGIseTpmdW5jdGlvbigpe0koXFxcIlxcXCIpfSxVOmZ1bmN0aW9uKCl7aWYoIUImJiF5KXt2YXIgYT1cXFwiQmxvY2tpbmcgb24gdGhlIG1haW4gdGhyZWFkIGlzIHZlcnkgZGFuZ2Vyb3VzLCBzZWUgaHR0cHM6Ly9lbXNjcmlwdGVuLm9yZy9kb2NzL3BvcnRpbmcvcHRocmVhZHMuaHRtbCNibG9ja2luZy1vbi10aGUtbWFpbi1icm93c2VyLXRocmVhZFxcXCI7SWJ8fChJYj17fSk7SWJbYV18fChJYlthXT0xLEImJihhPVxcXCJ3YXJuaW5nOiBcXFwiK2EpLEcoYSkpfX0scmE6ZnVuY3Rpb24oKXtyZXR1cm4gNDI5NDkwMTc2MH0sQjpKYixJYTpmdW5jdGlvbihhLGIsXFxyXFxuYyl7cSgpLmNvcHlXaXRoaW4oYT4+PjAsYj4+PjAsYitjPj4+MCl9LEY6ZnVuY3Rpb24oKXtyZXR1cm4gQj8oX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgb3MgKi8gXFxcIj9hZWRiXFxcIikuY3B1cykoKS5sZW5ndGg6bmF2aWdhdG9yLmhhcmR3YXJlQ29uY3VycmVuY3l9LERhOmZ1bmN0aW9uKGEsYixjKXtNYi5sZW5ndGg9YjtjPj49Mztmb3IodmFyIGU9MDtlPGI7ZSsrKU1iW2VdPWVhKClbYytlPj4+MF07cmV0dXJuKDA+YT9QYVstYS0xXTpjY1thXSkuYXBwbHkobnVsbCxNYil9LHFhOmZ1bmN0aW9uKGEpe3ZhciBiPXEoKS5sZW5ndGg7YT4+Pj0wO2lmKGE8PWJ8fDQyOTQ5MDE3NjA8YSlyZXR1cm4hMTtmb3IodmFyIGM9MTs0Pj1jO2MqPTIpe3ZhciBlPWIqKDErLjIvYyk7ZT1NYXRoLm1pbihlLGErMTAwNjYzMjk2KTt2YXIgZj1NYXRoO2U9TWF0aC5tYXgoYSxlKTtmPWYubWluLmNhbGwoZiw0Mjk0OTAxNzYwLGUrKDY1NTM2LWUlNjU1MzYpJTY1NTM2KTthOnt0cnl7bS5ncm93KGYtbi5ieXRlTGVuZ3RoKzY1NTM1Pj4+MTYpO3AobS5idWZmZXIpO1xcclxcbnZhciBoPTE7YnJlYWsgYX1jYXRjaChrKXt9aD12b2lkIDB9aWYoaClyZXR1cm4hMH1yZXR1cm4hMX0sTmE6ZnVuY3Rpb24oKXt0aHJvd1xcXCJ1bndpbmRcXFwiO30sR2E6UWIsSGE6UmIsSjpUYSxJOlNiLFM6VGIsZ2E6VWIsUjpWYixkOmZ1bmN0aW9uKCl7cmV0dXJuIFl9LG5hOlhiLGlhOmZjLGphOmdjLEs6aGMsZjppYyxQOmpjLFE6a2MsazpsYyxwOm1jLHE6bmMsTjpvYyxzOnBjLHc6cWMsTDpyYyxFOnNjLGFhOnRjLF86dWMsWjp2YyxjYTp3YywkOnhjLGJhOnljLFk6emMsZzpBYyxyOkJjLGk6Q2MsaGE6RGMsbTpFYyx2OkZjLHU6R2MsTzpIYyxBOkljLGthOkpjLEM6S2MsRDpMYyxmYTpNYyxkYTpOYyxlYTpPYyxvOmZ1bmN0aW9uKGEpe3JldHVybiBhfSxhOm18fHgud2FzbU1lbW9yeSxHOmZ1bmN0aW9uKGEpe1k9YX0sbGE6YmMsejpmdW5jdGlvbihhLGIsYyxlKXtyZXR1cm4gYmMoYSxiLGMsZSl9fTtcXHJcXG4oZnVuY3Rpb24oKXtmdW5jdGlvbiBhKGYsaCl7eC5hc209Zi5leHBvcnRzO1AucWMucHVzaCh4LmFzbS5zYik7RWE9eC5hc20udWI7R2EudW5zaGlmdCh4LmFzbS5WYSk7d2E9aDtDfHwoTC0tLHgubW9uaXRvclJ1bkRlcGVuZGVuY2llcyYmeC5tb25pdG9yUnVuRGVwZW5kZW5jaWVzKEwpLDA9PUwmJihudWxsIT09TGEmJihjbGVhckludGVydmFsKExhKSxMYT1udWxsKSxNJiYoZj1NLE09bnVsbCxmKCkpKSl9ZnVuY3Rpb24gYihmKXthKGYuaW5zdGFuY2UsZi5tb2R1bGUpfWZ1bmN0aW9uIGMoZil7cmV0dXJuIE9hKCkudGhlbihmdW5jdGlvbihoKXtyZXR1cm4gV2ViQXNzZW1ibHkuaW5zdGFudGlhdGUoaCxlKX0pLnRoZW4oZnVuY3Rpb24oaCl7cmV0dXJuIGh9KS50aGVuKGYsZnVuY3Rpb24oaCl7RyhcXFwiZmFpbGVkIHRvIGFzeW5jaHJvbm91c2x5IHByZXBhcmUgd2FzbTogXFxcIitoKTtJKGgpfSl9dmFyIGU9e2E6UGN9O0N8fChMKysseC5tb25pdG9yUnVuRGVwZW5kZW5jaWVzJiZ4Lm1vbml0b3JSdW5EZXBlbmRlbmNpZXMoTCkpO1xcclxcbmlmKHguaW5zdGFudGlhdGVXYXNtKXRyeXtyZXR1cm4geC5pbnN0YW50aWF0ZVdhc20oZSxhKX1jYXRjaChmKXtyZXR1cm4gRyhcXFwiTW9kdWxlLmluc3RhbnRpYXRlV2FzbSBjYWxsYmFjayBmYWlsZWQgd2l0aCBlcnJvcjogXFxcIitmKSwhMX0oZnVuY3Rpb24oKXtyZXR1cm4gSHx8XFxcImZ1bmN0aW9uXFxcIiE9dHlwZW9mIFdlYkFzc2VtYmx5Lmluc3RhbnRpYXRlU3RyZWFtaW5nfHxNYSgpfHxPLnN0YXJ0c1dpdGgoXFxcImZpbGU6Ly9cXFwiKXx8Qnx8XFxcImZ1bmN0aW9uXFxcIiE9dHlwZW9mIGZldGNoP2MoYik6ZmV0Y2goTyx7Y3JlZGVudGlhbHM6XFxcInNhbWUtb3JpZ2luXFxcIn0pLnRoZW4oZnVuY3Rpb24oZil7cmV0dXJuIFdlYkFzc2VtYmx5Lmluc3RhbnRpYXRlU3RyZWFtaW5nKGYsZSkudGhlbihiLGZ1bmN0aW9uKGgpe0coXFxcIndhc20gc3RyZWFtaW5nIGNvbXBpbGUgZmFpbGVkOiBcXFwiK2gpO0coXFxcImZhbGxpbmcgYmFjayB0byBBcnJheUJ1ZmZlciBpbnN0YW50aWF0aW9uXFxcIik7cmV0dXJuIGMoYil9KX0pfSkoKS5jYXRjaChpYSk7XFxyXFxucmV0dXJue319KSgpO3guX19fd2FzbV9jYWxsX2N0b3JzPWZ1bmN0aW9uKCl7cmV0dXJuKHguX19fd2FzbV9jYWxsX2N0b3JzPXguYXNtLlZhKS5hcHBseShudWxsLGFyZ3VtZW50cyl9O3guX09ydEluaXQ9ZnVuY3Rpb24oKXtyZXR1cm4oeC5fT3J0SW5pdD14LmFzbS5XYSkuYXBwbHkobnVsbCxhcmd1bWVudHMpfTt4Ll9PcnRDcmVhdGVTZXNzaW9uT3B0aW9ucz1mdW5jdGlvbigpe3JldHVybih4Ll9PcnRDcmVhdGVTZXNzaW9uT3B0aW9ucz14LmFzbS5YYSkuYXBwbHkobnVsbCxhcmd1bWVudHMpfTt4Ll9PcnRBcHBlbmRFeGVjdXRpb25Qcm92aWRlcj1mdW5jdGlvbigpe3JldHVybih4Ll9PcnRBcHBlbmRFeGVjdXRpb25Qcm92aWRlcj14LmFzbS5ZYSkuYXBwbHkobnVsbCxhcmd1bWVudHMpfTt4Ll9PcnRBZGRTZXNzaW9uQ29uZmlnRW50cnk9ZnVuY3Rpb24oKXtyZXR1cm4oeC5fT3J0QWRkU2Vzc2lvbkNvbmZpZ0VudHJ5PXguYXNtLlphKS5hcHBseShudWxsLGFyZ3VtZW50cyl9O1xcclxcbnguX09ydFJlbGVhc2VTZXNzaW9uT3B0aW9ucz1mdW5jdGlvbigpe3JldHVybih4Ll9PcnRSZWxlYXNlU2Vzc2lvbk9wdGlvbnM9eC5hc20uX2EpLmFwcGx5KG51bGwsYXJndW1lbnRzKX07eC5fT3J0Q3JlYXRlU2Vzc2lvbj1mdW5jdGlvbigpe3JldHVybih4Ll9PcnRDcmVhdGVTZXNzaW9uPXguYXNtLiRhKS5hcHBseShudWxsLGFyZ3VtZW50cyl9O3guX09ydFJlbGVhc2VTZXNzaW9uPWZ1bmN0aW9uKCl7cmV0dXJuKHguX09ydFJlbGVhc2VTZXNzaW9uPXguYXNtLmFiKS5hcHBseShudWxsLGFyZ3VtZW50cyl9O3guX09ydEdldElucHV0Q291bnQ9ZnVuY3Rpb24oKXtyZXR1cm4oeC5fT3J0R2V0SW5wdXRDb3VudD14LmFzbS5iYikuYXBwbHkobnVsbCxhcmd1bWVudHMpfTt4Ll9PcnRHZXRPdXRwdXRDb3VudD1mdW5jdGlvbigpe3JldHVybih4Ll9PcnRHZXRPdXRwdXRDb3VudD14LmFzbS5jYikuYXBwbHkobnVsbCxhcmd1bWVudHMpfTtcXHJcXG54Ll9PcnRHZXRJbnB1dE5hbWU9ZnVuY3Rpb24oKXtyZXR1cm4oeC5fT3J0R2V0SW5wdXROYW1lPXguYXNtLmRiKS5hcHBseShudWxsLGFyZ3VtZW50cyl9O3guX09ydEdldE91dHB1dE5hbWU9ZnVuY3Rpb24oKXtyZXR1cm4oeC5fT3J0R2V0T3V0cHV0TmFtZT14LmFzbS5lYikuYXBwbHkobnVsbCxhcmd1bWVudHMpfTt4Ll9PcnRGcmVlPWZ1bmN0aW9uKCl7cmV0dXJuKHguX09ydEZyZWU9eC5hc20uZmIpLmFwcGx5KG51bGwsYXJndW1lbnRzKX07eC5fT3J0Q3JlYXRlVGVuc29yPWZ1bmN0aW9uKCl7cmV0dXJuKHguX09ydENyZWF0ZVRlbnNvcj14LmFzbS5nYikuYXBwbHkobnVsbCxhcmd1bWVudHMpfTt4Ll9PcnRHZXRUZW5zb3JEYXRhPWZ1bmN0aW9uKCl7cmV0dXJuKHguX09ydEdldFRlbnNvckRhdGE9eC5hc20uaGIpLmFwcGx5KG51bGwsYXJndW1lbnRzKX07XFxyXFxueC5fT3J0UmVsZWFzZVRlbnNvcj1mdW5jdGlvbigpe3JldHVybih4Ll9PcnRSZWxlYXNlVGVuc29yPXguYXNtLmliKS5hcHBseShudWxsLGFyZ3VtZW50cyl9O3guX09ydENyZWF0ZVJ1bk9wdGlvbnM9ZnVuY3Rpb24oKXtyZXR1cm4oeC5fT3J0Q3JlYXRlUnVuT3B0aW9ucz14LmFzbS5qYikuYXBwbHkobnVsbCxhcmd1bWVudHMpfTt4Ll9PcnRBZGRSdW5Db25maWdFbnRyeT1mdW5jdGlvbigpe3JldHVybih4Ll9PcnRBZGRSdW5Db25maWdFbnRyeT14LmFzbS5rYikuYXBwbHkobnVsbCxhcmd1bWVudHMpfTt4Ll9PcnRSZWxlYXNlUnVuT3B0aW9ucz1mdW5jdGlvbigpe3JldHVybih4Ll9PcnRSZWxlYXNlUnVuT3B0aW9ucz14LmFzbS5sYikuYXBwbHkobnVsbCxhcmd1bWVudHMpfTt4Ll9PcnRSdW49ZnVuY3Rpb24oKXtyZXR1cm4oeC5fT3J0UnVuPXguYXNtLm1iKS5hcHBseShudWxsLGFyZ3VtZW50cyl9O1xcclxcbnguX09ydEVuZFByb2ZpbGluZz1mdW5jdGlvbigpe3JldHVybih4Ll9PcnRFbmRQcm9maWxpbmc9eC5hc20ubmIpLmFwcGx5KG51bGwsYXJndW1lbnRzKX07dmFyICRhPXguX3B0aHJlYWRfc2VsZj1mdW5jdGlvbigpe3JldHVybigkYT14Ll9wdGhyZWFkX3NlbGY9eC5hc20ub2IpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sRmI9eC5fbWFsbG9jPWZ1bmN0aW9uKCl7cmV0dXJuKEZiPXguX21hbGxvYz14LmFzbS5wYikuYXBwbHkobnVsbCxhcmd1bWVudHMpfSxrYj14Ll9mcmVlPWZ1bmN0aW9uKCl7cmV0dXJuKGtiPXguX2ZyZWU9eC5hc20ucWIpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sV2E9eC5fZmZsdXNoPWZ1bmN0aW9uKCl7cmV0dXJuKFdhPXguX2ZmbHVzaD14LmFzbS5yYikuYXBwbHkobnVsbCxhcmd1bWVudHMpfTt4Ll9fZW1zY3JpcHRlbl90bHNfaW5pdD1mdW5jdGlvbigpe3JldHVybih4Ll9fZW1zY3JpcHRlbl90bHNfaW5pdD14LmFzbS5zYikuYXBwbHkobnVsbCxhcmd1bWVudHMpfTtcXHJcXG52YXIgVmE9eC5fX19mdW5jc19vbl9leGl0PWZ1bmN0aW9uKCl7cmV0dXJuKFZhPXguX19fZnVuY3Nfb25fZXhpdD14LmFzbS50YikuYXBwbHkobnVsbCxhcmd1bWVudHMpfSxlYz14Ll9fZW1zY3JpcHRlbl90aHJlYWRfaW5pdD1mdW5jdGlvbigpe3JldHVybihlYz14Ll9fZW1zY3JpcHRlbl90aHJlYWRfaW5pdD14LmFzbS52YikuYXBwbHkobnVsbCxhcmd1bWVudHMpfTt4Ll9fZW1zY3JpcHRlbl90aHJlYWRfY3Jhc2hlZD1mdW5jdGlvbigpe3JldHVybih4Ll9fZW1zY3JpcHRlbl90aHJlYWRfY3Jhc2hlZD14LmFzbS53YikuYXBwbHkobnVsbCxhcmd1bWVudHMpfTtcXHJcXG52YXIgTGI9eC5fZW1zY3JpcHRlbl9ydW5faW5fbWFpbl9ydW50aW1lX3RocmVhZF9qcz1mdW5jdGlvbigpe3JldHVybihMYj14Ll9lbXNjcmlwdGVuX3J1bl9pbl9tYWluX3J1bnRpbWVfdGhyZWFkX2pzPXguYXNtLnhiKS5hcHBseShudWxsLGFyZ3VtZW50cyl9LEFiPXguX19lbXNjcmlwdGVuX3Byb3h5X2V4ZWN1dGVfdGFza19xdWV1ZT1mdW5jdGlvbigpe3JldHVybihBYj14Ll9fZW1zY3JpcHRlbl9wcm94eV9leGVjdXRlX3Rhc2tfcXVldWU9eC5hc20ueWIpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sWmE9eC5fX2Vtc2NyaXB0ZW5fdGhyZWFkX2ZyZWVfZGF0YT1mdW5jdGlvbigpe3JldHVybihaYT14Ll9fZW1zY3JpcHRlbl90aHJlYWRfZnJlZV9kYXRhPXguYXNtLnpiKS5hcHBseShudWxsLGFyZ3VtZW50cyl9LGViPXguX19lbXNjcmlwdGVuX3RocmVhZF9leGl0PWZ1bmN0aW9uKCl7cmV0dXJuKGViPXguX19lbXNjcmlwdGVuX3RocmVhZF9leGl0PXguYXNtLkFiKS5hcHBseShudWxsLFxcclxcbmFyZ3VtZW50cyl9LFo9eC5fc2V0VGhyZXc9ZnVuY3Rpb24oKXtyZXR1cm4oWj14Ll9zZXRUaHJldz14LmFzbS5CYikuYXBwbHkobnVsbCxhcmd1bWVudHMpfSxjYj14Ll9lbXNjcmlwdGVuX3N0YWNrX3NldF9saW1pdHM9ZnVuY3Rpb24oKXtyZXR1cm4oY2I9eC5fZW1zY3JpcHRlbl9zdGFja19zZXRfbGltaXRzPXguYXNtLkNiKS5hcHBseShudWxsLGFyZ3VtZW50cyl9LFM9eC5zdGFja1NhdmU9ZnVuY3Rpb24oKXtyZXR1cm4oUz14LnN0YWNrU2F2ZT14LmFzbS5EYikuYXBwbHkobnVsbCxhcmd1bWVudHMpfSxVPXguc3RhY2tSZXN0b3JlPWZ1bmN0aW9uKCl7cmV0dXJuKFU9eC5zdGFja1Jlc3RvcmU9eC5hc20uRWIpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sS2I9eC5zdGFja0FsbG9jPWZ1bmN0aW9uKCl7cmV0dXJuKEtiPXguc3RhY2tBbGxvYz14LmFzbS5GYikuYXBwbHkobnVsbCxhcmd1bWVudHMpfSxkYz14Ll9fX2N4YV9jYW5fY2F0Y2g9ZnVuY3Rpb24oKXtyZXR1cm4oZGM9eC5fX19jeGFfY2FuX2NhdGNoPVxcclxcbnguYXNtLkdiKS5hcHBseShudWxsLGFyZ3VtZW50cyl9LGliPXguX19fY3hhX2lzX3BvaW50ZXJfdHlwZT1mdW5jdGlvbigpe3JldHVybihpYj14Ll9fX2N4YV9pc19wb2ludGVyX3R5cGU9eC5hc20uSGIpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sUWM9eC5keW5DYWxsX2o9ZnVuY3Rpb24oKXtyZXR1cm4oUWM9eC5keW5DYWxsX2o9eC5hc20uSWIpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sUmM9eC5keW5DYWxsX2lpaWlpaj1mdW5jdGlvbigpe3JldHVybihSYz14LmR5bkNhbGxfaWlpaWlqPXguYXNtLkpiKS5hcHBseShudWxsLGFyZ3VtZW50cyl9LFNjPXguZHluQ2FsbF9qaWk9ZnVuY3Rpb24oKXtyZXR1cm4oU2M9eC5keW5DYWxsX2ppaT14LmFzbS5LYikuYXBwbHkobnVsbCxhcmd1bWVudHMpfSxUYz14LmR5bkNhbGxfdmlpaWlpaj1mdW5jdGlvbigpe3JldHVybihUYz14LmR5bkNhbGxfdmlpaWlpaj14LmFzbS5MYikuYXBwbHkobnVsbCxhcmd1bWVudHMpfSxVYz14LmR5bkNhbGxfdmpqaT1cXHJcXG5mdW5jdGlvbigpe3JldHVybihVYz14LmR5bkNhbGxfdmpqaT14LmFzbS5NYikuYXBwbHkobnVsbCxhcmd1bWVudHMpfSxWYz14LmR5bkNhbGxfdmlpaWpqamlpPWZ1bmN0aW9uKCl7cmV0dXJuKFZjPXguZHluQ2FsbF92aWlpampqaWk9eC5hc20uTmIpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sV2M9eC5keW5DYWxsX2lpaj1mdW5jdGlvbigpe3JldHVybihXYz14LmR5bkNhbGxfaWlqPXguYXNtLk9iKS5hcHBseShudWxsLGFyZ3VtZW50cyl9LFhjPXguZHluQ2FsbF9qaT1mdW5jdGlvbigpe3JldHVybihYYz14LmR5bkNhbGxfamk9eC5hc20uUGIpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sWWM9eC5keW5DYWxsX2lpaWlpaWo9ZnVuY3Rpb24oKXtyZXR1cm4oWWM9eC5keW5DYWxsX2lpaWlpaWo9eC5hc20uUWIpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sWmM9eC5keW5DYWxsX2lpaWo9ZnVuY3Rpb24oKXtyZXR1cm4oWmM9eC5keW5DYWxsX2lpaWo9eC5hc20uUmIpLmFwcGx5KG51bGwsXFxyXFxuYXJndW1lbnRzKX07ZnVuY3Rpb24gaWMoYSxiKXt2YXIgYz1TKCk7dHJ5e3JldHVybiBWKGEpKGIpfWNhdGNoKGUpe1UoYyk7aWYoZSE9PWUrMCl0aHJvdyBlO1ooMSwwKX19ZnVuY3Rpb24gQmMoYSxiKXt2YXIgYz1TKCk7dHJ5e1YoYSkoYil9Y2F0Y2goZSl7VShjKTtpZihlIT09ZSswKXRocm93IGU7WigxLDApfX1mdW5jdGlvbiBDYyhhLGIsYyl7dmFyIGU9UygpO3RyeXtWKGEpKGIsYyl9Y2F0Y2goZil7VShlKTtpZihmIT09ZiswKXRocm93IGY7WigxLDApfX1mdW5jdGlvbiBsYyhhLGIsYyl7dmFyIGU9UygpO3RyeXtyZXR1cm4gVihhKShiLGMpfWNhdGNoKGYpe1UoZSk7aWYoZiE9PWYrMCl0aHJvdyBmO1ooMSwwKX19ZnVuY3Rpb24gbWMoYSxiLGMsZSl7dmFyIGY9UygpO3RyeXtyZXR1cm4gVihhKShiLGMsZSl9Y2F0Y2goaCl7VShmKTtpZihoIT09aCswKXRocm93IGg7WigxLDApfX1cXHJcXG5mdW5jdGlvbiBxYyhhLGIsYyxlLGYsaCxrKXt2YXIgbD1TKCk7dHJ5e3JldHVybiBWKGEpKGIsYyxlLGYsaCxrKX1jYXRjaCh1KXtVKGwpO2lmKHUhPT11KzApdGhyb3cgdTtaKDEsMCl9fWZ1bmN0aW9uIEFjKGEpe3ZhciBiPVMoKTt0cnl7VihhKSgpfWNhdGNoKGMpe1UoYik7aWYoYyE9PWMrMCl0aHJvdyBjO1ooMSwwKX19ZnVuY3Rpb24gcGMoYSxiLGMsZSxmLGgpe3ZhciBrPVMoKTt0cnl7cmV0dXJuIFYoYSkoYixjLGUsZixoKX1jYXRjaChsKXtVKGspO2lmKGwhPT1sKzApdGhyb3cgbDtaKDEsMCl9fWZ1bmN0aW9uIG5jKGEsYixjLGUsZil7dmFyIGg9UygpO3RyeXtyZXR1cm4gVihhKShiLGMsZSxmKX1jYXRjaChrKXtVKGgpO2lmKGshPT1rKzApdGhyb3cgaztaKDEsMCl9fWZ1bmN0aW9uIEVjKGEsYixjLGUpe3ZhciBmPVMoKTt0cnl7VihhKShiLGMsZSl9Y2F0Y2goaCl7VShmKTtpZihoIT09aCswKXRocm93IGg7WigxLDApfX1cXHJcXG5mdW5jdGlvbiBHYyhhLGIsYyxlLGYsaCl7dmFyIGs9UygpO3RyeXtWKGEpKGIsYyxlLGYsaCl9Y2F0Y2gobCl7VShrKTtpZihsIT09bCswKXRocm93IGw7WigxLDApfX1mdW5jdGlvbiBGYyhhLGIsYyxlLGYpe3ZhciBoPVMoKTt0cnl7VihhKShiLGMsZSxmKX1jYXRjaChrKXtVKGgpO2lmKGshPT1rKzApdGhyb3cgaztaKDEsMCl9fWZ1bmN0aW9uIEljKGEsYixjLGUsZixoLGssbCl7dmFyIHU9UygpO3RyeXtWKGEpKGIsYyxlLGYsaCxrLGwpfWNhdGNoKHQpe1UodSk7aWYodCE9PXQrMCl0aHJvdyB0O1ooMSwwKX19ZnVuY3Rpb24ga2MoYSxiLGMpe3ZhciBlPVMoKTt0cnl7cmV0dXJuIFYoYSkoYixjKX1jYXRjaChmKXtVKGUpO2lmKGYhPT1mKzApdGhyb3cgZjtaKDEsMCl9fWZ1bmN0aW9uIGpjKGEsYixjKXt2YXIgZT1TKCk7dHJ5e3JldHVybiBWKGEpKGIsYyl9Y2F0Y2goZil7VShlKTtpZihmIT09ZiswKXRocm93IGY7WigxLDApfX1cXHJcXG5mdW5jdGlvbiBKYyhhLGIsYyxlLGYsaCxrLGwsdSl7dmFyIHQ9UygpO3RyeXtWKGEpKGIsYyxlLGYsaCxrLGwsdSl9Y2F0Y2goQSl7VSh0KTtpZihBIT09QSswKXRocm93IEE7WigxLDApfX1mdW5jdGlvbiBIYyhhLGIsYyxlLGYsaCxrKXt2YXIgbD1TKCk7dHJ5e1YoYSkoYixjLGUsZixoLGspfWNhdGNoKHUpe1UobCk7aWYodSE9PXUrMCl0aHJvdyB1O1ooMSwwKX19ZnVuY3Rpb24gb2MoYSxiLGMsZSxmLGgpe3ZhciBrPVMoKTt0cnl7cmV0dXJuIFYoYSkoYixjLGUsZixoKX1jYXRjaChsKXtVKGspO2lmKGwhPT1sKzApdGhyb3cgbDtaKDEsMCl9fWZ1bmN0aW9uIHJjKGEsYixjLGUsZixoLGssbCl7dmFyIHU9UygpO3RyeXtyZXR1cm4gVihhKShiLGMsZSxmLGgsayxsKX1jYXRjaCh0KXtVKHUpO2lmKHQhPT10KzApdGhyb3cgdDtaKDEsMCl9fVxcclxcbmZ1bmN0aW9uIHNjKGEsYixjLGUsZixoLGssbCx1LHQsQSxLKXt2YXIgSj1TKCk7dHJ5e3JldHVybiBWKGEpKGIsYyxlLGYsaCxrLGwsdSx0LEEsSyl9Y2F0Y2goZyl7VShKKTtpZihnIT09ZyswKXRocm93IGc7WigxLDApfX1mdW5jdGlvbiBLYyhhLGIsYyxlLGYsaCxrLGwsdSx0LEEpe3ZhciBLPVMoKTt0cnl7VihhKShiLGMsZSxmLGgsayxsLHUsdCxBKX1jYXRjaChKKXtVKEspO2lmKEohPT1KKzApdGhyb3cgSjtaKDEsMCl9fWZ1bmN0aW9uIExjKGEsYixjLGUsZixoLGssbCx1LHQsQSxLLEosZyx3LHope3ZhciBOPVMoKTt0cnl7VihhKShiLGMsZSxmLGgsayxsLHUsdCxBLEssSixnLHcseil9Y2F0Y2goVCl7VShOKTtpZihUIT09VCswKXRocm93IFQ7WigxLDApfX1mdW5jdGlvbiBoYyhhKXt2YXIgYj1TKCk7dHJ5e3JldHVybiBWKGEpKCl9Y2F0Y2goYyl7VShiKTtpZihjIT09YyswKXRocm93IGM7WigxLDApfX1cXHJcXG5mdW5jdGlvbiBnYyhhLGIsYyl7dmFyIGU9UygpO3RyeXtyZXR1cm4gVihhKShiLGMpfWNhdGNoKGYpe1UoZSk7aWYoZiE9PWYrMCl0aHJvdyBmO1ooMSwwKX19ZnVuY3Rpb24gZmMoYSxiLGMpe3ZhciBlPVMoKTt0cnl7cmV0dXJuIFYoYSkoYixjKX1jYXRjaChmKXtVKGUpO2lmKGYhPT1mKzApdGhyb3cgZjtaKDEsMCl9fWZ1bmN0aW9uIERjKGEsYixjLGUpe3ZhciBmPVMoKTt0cnl7VihhKShiLGMsZSl9Y2F0Y2goaCl7VShmKTtpZihoIT09aCswKXRocm93IGg7WigxLDApfX1mdW5jdGlvbiBNYyhhLGIsYyxlLGYsaCxrLGwpe3ZhciB1PVMoKTt0cnl7VGMoYSxiLGMsZSxmLGgsayxsKX1jYXRjaCh0KXtVKHUpO2lmKHQhPT10KzApdGhyb3cgdDtaKDEsMCl9fWZ1bmN0aW9uIE9jKGEsYixjLGUsZixoKXt2YXIgaz1TKCk7dHJ5e1VjKGEsYixjLGUsZixoKX1jYXRjaChsKXtVKGspO2lmKGwhPT1sKzApdGhyb3cgbDtaKDEsMCl9fVxcclxcbmZ1bmN0aW9uIE5jKGEsYixjLGUsZixoLGssbCx1LHQsQSxLKXt2YXIgSj1TKCk7dHJ5e1ZjKGEsYixjLGUsZixoLGssbCx1LHQsQSxLKX1jYXRjaChnKXtVKEopO2lmKGchPT1nKzApdGhyb3cgZztaKDEsMCl9fWZ1bmN0aW9uIHdjKGEsYixjLGUpe3ZhciBmPVMoKTt0cnl7cmV0dXJuIFdjKGEsYixjLGUpfWNhdGNoKGgpe1UoZik7aWYoaCE9PWgrMCl0aHJvdyBoO1ooMSwwKX19ZnVuY3Rpb24geWMoYSxiKXt2YXIgYz1TKCk7dHJ5e3JldHVybiBYYyhhLGIpfWNhdGNoKGUpe1UoYyk7aWYoZSE9PWUrMCl0aHJvdyBlO1ooMSwwKX19ZnVuY3Rpb24gdGMoYSxiLGMsZSxmLGgsayxsKXt2YXIgdT1TKCk7dHJ5e3JldHVybiBZYyhhLGIsYyxlLGYsaCxrLGwpfWNhdGNoKHQpe1UodSk7aWYodCE9PXQrMCl0aHJvdyB0O1ooMSwwKX19ZnVuY3Rpb24geGMoYSl7dmFyIGI9UygpO3RyeXtyZXR1cm4gUWMoYSl9Y2F0Y2goYyl7VShiKTtpZihjIT09YyswKXRocm93IGM7WigxLDApfX1cXHJcXG5mdW5jdGlvbiB1YyhhLGIsYyxlLGYsaCxrKXt2YXIgbD1TKCk7dHJ5e3JldHVybiBSYyhhLGIsYyxlLGYsaCxrKX1jYXRjaCh1KXtVKGwpO2lmKHUhPT11KzApdGhyb3cgdTtaKDEsMCl9fWZ1bmN0aW9uIHZjKGEsYixjLGUsZil7dmFyIGg9UygpO3RyeXtyZXR1cm4gWmMoYSxiLGMsZSxmKX1jYXRjaChrKXtVKGgpO2lmKGshPT1rKzApdGhyb3cgaztaKDEsMCl9fWZ1bmN0aW9uIHpjKGEsYixjKXt2YXIgZT1TKCk7dHJ5e3JldHVybiBTYyhhLGIsYyl9Y2F0Y2goZil7VShlKTtpZihmIT09ZiswKXRocm93IGY7WigxLDApfX14LlVURjhUb1N0cmluZz1BYTt4LnN0cmluZ1RvVVRGOD1mdW5jdGlvbihhLGIsYyl7cmV0dXJuIEJhKGEscSgpLGIsYyl9O3gubGVuZ3RoQnl0ZXNVVEY4PUNhO3gua2VlcFJ1bnRpbWVBbGl2ZT1GO3gud2FzbU1lbW9yeT1tO3guc3RhY2tTYXZlPVM7eC5zdGFja1Jlc3RvcmU9VTt4LnN0YWNrQWxsb2M9S2I7eC5FeGl0U3RhdHVzPUU7eC5QVGhyZWFkPVA7dmFyICRjO1xcclxcbk09ZnVuY3Rpb24gYWQoKXskY3x8YmQoKTskY3x8KE09YWQpfTtcXHJcXG5mdW5jdGlvbiBiZCgpe2Z1bmN0aW9uIGEoKXtpZighJGMmJigkYz0hMCx4LmNhbGxlZFJ1bj0hMCwheGEpKXtDfHxSKEdhKTtoYSh4KTtpZih4Lm9uUnVudGltZUluaXRpYWxpemVkKXgub25SdW50aW1lSW5pdGlhbGl6ZWQoKTtpZighQyl7aWYoeC5wb3N0UnVuKWZvcihcXFwiZnVuY3Rpb25cXFwiPT10eXBlb2YgeC5wb3N0UnVuJiYoeC5wb3N0UnVuPVt4LnBvc3RSdW5dKTt4LnBvc3RSdW4ubGVuZ3RoOyl7dmFyIGI9eC5wb3N0UnVuLnNoaWZ0KCk7SWEudW5zaGlmdChiKX1SKElhKX19fWlmKCEoMDxMKSlpZihDKWhhKHgpLEN8fFIoR2EpLHBvc3RNZXNzYWdlKHtjbWQ6XFxcImxvYWRlZFxcXCJ9KTtlbHNle2lmKHgucHJlUnVuKWZvcihcXFwiZnVuY3Rpb25cXFwiPT10eXBlb2YgeC5wcmVSdW4mJih4LnByZVJ1bj1beC5wcmVSdW5dKTt4LnByZVJ1bi5sZW5ndGg7KUthKCk7UihGYSk7MDxMfHwoeC5zZXRTdGF0dXM/KHguc2V0U3RhdHVzKFxcXCJSdW5uaW5nLi4uXFxcIiksc2V0VGltZW91dChmdW5jdGlvbigpe3NldFRpbWVvdXQoZnVuY3Rpb24oKXt4LnNldFN0YXR1cyhcXFwiXFxcIil9LFxcclxcbjEpO2EoKX0sMSkpOmEoKSl9fWlmKHgucHJlSW5pdClmb3IoXFxcImZ1bmN0aW9uXFxcIj09dHlwZW9mIHgucHJlSW5pdCYmKHgucHJlSW5pdD1beC5wcmVJbml0XSk7MDx4LnByZUluaXQubGVuZ3RoOyl4LnByZUluaXQucG9wKCkoKTtiZCgpO1xcclxcblxcclxcblxcclxcbiAgcmV0dXJuIG9ydFdhc21UaHJlYWRlZC5yZWFkeVxcclxcbn1cXHJcXG4pO1xcclxcbn0pKCk7XFxyXFxuaWYgKHRydWUpXFxyXFxuICBtb2R1bGUuZXhwb3J0cyA9IG9ydFdhc21UaHJlYWRlZDtcXHJcXG5lbHNlIHt9XFxyXFxuXFxuXFxuLyoqKi8gfSksXFxuXFxuLyoqKi8gXFxcIi4vbGliL3dhc20vYmluZGluZy9vcnQtd2FzbS5qc1xcXCI6XFxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXFxcXG4gICEqKiogLi9saWIvd2FzbS9iaW5kaW5nL29ydC13YXNtLmpzICoqKiFcXG4gIFxcXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cXG4vKioqLyAoKG1vZHVsZSwgX191bnVzZWRfd2VicGFja19leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKSA9PiB7XFxuXFxudmFyIF9fZmlsZW5hbWUgPSBcXFwiL2luZGV4LmpzXFxcIjtcXG52YXIgX19kaXJuYW1lID0gXFxcIi9cXFwiO1xcblxcclxcbnZhciBvcnRXYXNtID0gKCgpID0+IHtcXHJcXG4gIHZhciBfc2NyaXB0RGlyID0gdHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJyAmJiBkb2N1bWVudC5jdXJyZW50U2NyaXB0ID8gZG9jdW1lbnQuY3VycmVudFNjcmlwdC5zcmMgOiB1bmRlZmluZWQ7XFxyXFxuICBpZiAodHJ1ZSkgX3NjcmlwdERpciA9IF9zY3JpcHREaXIgfHwgX19maWxlbmFtZTtcXHJcXG4gIHJldHVybiAoXFxyXFxuZnVuY3Rpb24ob3J0V2FzbSkge1xcclxcbiAgb3J0V2FzbSA9IG9ydFdhc20gfHwge307XFxyXFxuXFxyXFxuXFxyXFxudmFyIGQ7ZHx8KGQ9dHlwZW9mIG9ydFdhc20gIT09ICd1bmRlZmluZWQnID8gb3J0V2FzbSA6IHt9KTt2YXIgYWEsYmE7ZC5yZWFkeT1uZXcgUHJvbWlzZShmdW5jdGlvbihhLGIpe2FhPWE7YmE9Yn0pO3ZhciBjYT1PYmplY3QuYXNzaWduKHt9LGQpLGRhPVxcXCIuL3RoaXMucHJvZ3JhbVxcXCIsZWE9KGEsYik9Pnt0aHJvdyBiO30sZmE9XFxcIm9iamVjdFxcXCI9PXR5cGVvZiB3aW5kb3csbT1cXFwiZnVuY3Rpb25cXFwiPT10eXBlb2YgaW1wb3J0U2NyaXB0cyxwPVxcXCJvYmplY3RcXFwiPT10eXBlb2YgcHJvY2VzcyYmXFxcIm9iamVjdFxcXCI9PXR5cGVvZiBwcm9jZXNzLnZlcnNpb25zJiZcXFwic3RyaW5nXFxcIj09dHlwZW9mIHByb2Nlc3MudmVyc2lvbnMubm9kZSxxPVxcXCJcXFwiLGhhLHIsdixmcyx5LGlhO1xcclxcbmlmKHApcT1tPyhfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISBwYXRoICovIFxcXCI/NzVjNlxcXCIpLmRpcm5hbWUpKHEpK1xcXCIvXFxcIjpfX2Rpcm5hbWUrXFxcIi9cXFwiLGlhPSgpPT57eXx8KGZzPV9fd2VicGFja19yZXF1aXJlX18oLyohIGZzICovIFxcXCI/NjNjOFxcXCIpLHk9X193ZWJwYWNrX3JlcXVpcmVfXygvKiEgcGF0aCAqLyBcXFwiPzc1YzZcXFwiKSl9LGhhPWZ1bmN0aW9uKGEsYil7aWEoKTthPXkubm9ybWFsaXplKGEpO3JldHVybiBmcy5yZWFkRmlsZVN5bmMoYSxiP3ZvaWQgMDpcXFwidXRmOFxcXCIpfSx2PWE9PnthPWhhKGEsITApO2EuYnVmZmVyfHwoYT1uZXcgVWludDhBcnJheShhKSk7cmV0dXJuIGF9LHI9KGEsYixjKT0+e2lhKCk7YT15Lm5vcm1hbGl6ZShhKTtmcy5yZWFkRmlsZShhLGZ1bmN0aW9uKGUsZil7ZT9jKGUpOmIoZi5idWZmZXIpfSl9LDE8cHJvY2Vzcy5hcmd2Lmxlbmd0aCYmKGRhPXByb2Nlc3MuYXJndlsxXS5yZXBsYWNlKC9cXFxcXFxcXC9nLFxcXCIvXFxcIikpLHByb2Nlc3MuYXJndi5zbGljZSgyKSxwcm9jZXNzLm9uKFxcXCJ1bmNhdWdodEV4Y2VwdGlvblxcXCIsZnVuY3Rpb24oYSl7aWYoIShhIGluc3RhbmNlb2YgamEpKXRocm93IGE7fSkscHJvY2Vzcy5vbihcXFwidW5oYW5kbGVkUmVqZWN0aW9uXFxcIixcXHJcXG5mdW5jdGlvbihhKXt0aHJvdyBhO30pLGVhPShhLGIpPT57aWYobm9FeGl0UnVudGltZXx8MDxrYSl0aHJvdyBwcm9jZXNzLmV4aXRDb2RlPWEsYjtiIGluc3RhbmNlb2YgamF8fHooXFxcImV4aXRpbmcgZHVlIHRvIGV4Y2VwdGlvbjogXFxcIitiKTtwcm9jZXNzLmV4aXQoYSl9LGQuaW5zcGVjdD1mdW5jdGlvbigpe3JldHVyblxcXCJbRW1zY3JpcHRlbiBNb2R1bGUgb2JqZWN0XVxcXCJ9O2Vsc2UgaWYoZmF8fG0pbT9xPXNlbGYubG9jYXRpb24uaHJlZjpcXFwidW5kZWZpbmVkXFxcIiE9dHlwZW9mIGRvY3VtZW50JiZkb2N1bWVudC5jdXJyZW50U2NyaXB0JiYocT1kb2N1bWVudC5jdXJyZW50U2NyaXB0LnNyYyksX3NjcmlwdERpciYmKHE9X3NjcmlwdERpciksMCE9PXEuaW5kZXhPZihcXFwiYmxvYjpcXFwiKT9xPXEuc3Vic3RyKDAscS5yZXBsYWNlKC9bPyNdLiovLFxcXCJcXFwiKS5sYXN0SW5kZXhPZihcXFwiL1xcXCIpKzEpOnE9XFxcIlxcXCIsaGE9YT0+e3ZhciBiPW5ldyBYTUxIdHRwUmVxdWVzdDtiLm9wZW4oXFxcIkdFVFxcXCIsYSwhMSk7Yi5zZW5kKG51bGwpO1xcclxcbnJldHVybiBiLnJlc3BvbnNlVGV4dH0sbSYmKHY9YT0+e3ZhciBiPW5ldyBYTUxIdHRwUmVxdWVzdDtiLm9wZW4oXFxcIkdFVFxcXCIsYSwhMSk7Yi5yZXNwb25zZVR5cGU9XFxcImFycmF5YnVmZmVyXFxcIjtiLnNlbmQobnVsbCk7cmV0dXJuIG5ldyBVaW50OEFycmF5KGIucmVzcG9uc2UpfSkscj0oYSxiLGMpPT57dmFyIGU9bmV3IFhNTEh0dHBSZXF1ZXN0O2Uub3BlbihcXFwiR0VUXFxcIixhLCEwKTtlLnJlc3BvbnNlVHlwZT1cXFwiYXJyYXlidWZmZXJcXFwiO2Uub25sb2FkPSgpPT57MjAwPT1lLnN0YXR1c3x8MD09ZS5zdGF0dXMmJmUucmVzcG9uc2U/YihlLnJlc3BvbnNlKTpjKCl9O2Uub25lcnJvcj1jO2Uuc2VuZChudWxsKX07dmFyIGxhPWQucHJpbnR8fGNvbnNvbGUubG9nLmJpbmQoY29uc29sZSksej1kLnByaW50RXJyfHxjb25zb2xlLndhcm4uYmluZChjb25zb2xlKTtPYmplY3QuYXNzaWduKGQsY2EpO2NhPW51bGw7ZC50aGlzUHJvZ3JhbSYmKGRhPWQudGhpc1Byb2dyYW0pO2QucXVpdCYmKGVhPWQucXVpdCk7XFxyXFxudmFyIEE7ZC53YXNtQmluYXJ5JiYoQT1kLndhc21CaW5hcnkpO3ZhciBub0V4aXRSdW50aW1lPWQubm9FeGl0UnVudGltZXx8ITE7XFxcIm9iamVjdFxcXCIhPXR5cGVvZiBXZWJBc3NlbWJseSYmQihcXFwibm8gbmF0aXZlIHdhc20gc3VwcG9ydCBkZXRlY3RlZFxcXCIpO3ZhciBtYSxEPSExLG5hPVxcXCJ1bmRlZmluZWRcXFwiIT10eXBlb2YgVGV4dERlY29kZXI/bmV3IFRleHREZWNvZGVyKFxcXCJ1dGY4XFxcIik6dm9pZCAwO1xcclxcbmZ1bmN0aW9uIG9hKGEsYixjKXtiPj4+PTA7dmFyIGU9YitjO2ZvcihjPWI7YVtjXSYmIShjPj1lKTspKytjO2lmKDE2PGMtYiYmYS5idWZmZXImJm5hKXJldHVybiBuYS5kZWNvZGUoYS5zdWJhcnJheShiLGMpKTtmb3IoZT1cXFwiXFxcIjtiPGM7KXt2YXIgZj1hW2IrK107aWYoZiYxMjgpe3ZhciBoPWFbYisrXSY2MztpZigxOTI9PShmJjIyNCkpZSs9U3RyaW5nLmZyb21DaGFyQ29kZSgoZiYzMSk8PDZ8aCk7ZWxzZXt2YXIgaz1hW2IrK10mNjM7Zj0yMjQ9PShmJjI0MCk/KGYmMTUpPDwxMnxoPDw2fGs6KGYmNyk8PDE4fGg8PDEyfGs8PDZ8YVtiKytdJjYzOzY1NTM2PmY/ZSs9U3RyaW5nLmZyb21DaGFyQ29kZShmKTooZi09NjU1MzYsZSs9U3RyaW5nLmZyb21DaGFyQ29kZSg1NTI5NnxmPj4xMCw1NjMyMHxmJjEwMjMpKX19ZWxzZSBlKz1TdHJpbmcuZnJvbUNoYXJDb2RlKGYpfXJldHVybiBlfWZ1bmN0aW9uIHBhKGEsYil7cmV0dXJuKGE+Pj49MCk/b2EoRyxhLGIpOlxcXCJcXFwifVxcclxcbmZ1bmN0aW9uIHFhKGEsYixjLGUpe2M+Pj49MDtpZighKDA8ZSkpcmV0dXJuIDA7dmFyIGY9YztlPWMrZS0xO2Zvcih2YXIgaD0wO2g8YS5sZW5ndGg7KytoKXt2YXIgaz1hLmNoYXJDb2RlQXQoaCk7aWYoNTUyOTY8PWsmJjU3MzQzPj1rKXt2YXIgbD1hLmNoYXJDb2RlQXQoKytoKTtrPTY1NTM2KygoayYxMDIzKTw8MTApfGwmMTAyM31pZigxMjc+PWspe2lmKGM+PWUpYnJlYWs7YltjKys+Pj4wXT1rfWVsc2V7aWYoMjA0Nz49ayl7aWYoYysxPj1lKWJyZWFrO2JbYysrPj4+MF09MTkyfGs+PjZ9ZWxzZXtpZig2NTUzNT49ayl7aWYoYysyPj1lKWJyZWFrO2JbYysrPj4+MF09MjI0fGs+PjEyfWVsc2V7aWYoYyszPj1lKWJyZWFrO2JbYysrPj4+MF09MjQwfGs+PjE4O2JbYysrPj4+MF09MTI4fGs+PjEyJjYzfWJbYysrPj4+MF09MTI4fGs+PjYmNjN9YltjKys+Pj4wXT0xMjh8ayY2M319YltjPj4+MF09MDtyZXR1cm4gYy1mfVxcclxcbmZ1bmN0aW9uIHJhKGEpe2Zvcih2YXIgYj0wLGM9MDtjPGEubGVuZ3RoOysrYyl7dmFyIGU9YS5jaGFyQ29kZUF0KGMpOzEyNz49ZT9iKys6MjA0Nz49ZT9iKz0yOjU1Mjk2PD1lJiY1NzM0Mz49ZT8oYis9NCwrK2MpOmIrPTN9cmV0dXJuIGJ9dmFyIHNhLEgsRyxJLEo7ZnVuY3Rpb24gdGEoKXt2YXIgYT1tYS5idWZmZXI7c2E9YTtkLkhFQVA4PUg9bmV3IEludDhBcnJheShhKTtkLkhFQVAxNj1uZXcgSW50MTZBcnJheShhKTtkLkhFQVAzMj1JPW5ldyBJbnQzMkFycmF5KGEpO2QuSEVBUFU4PUc9bmV3IFVpbnQ4QXJyYXkoYSk7ZC5IRUFQVTE2PW5ldyBVaW50MTZBcnJheShhKTtkLkhFQVBVMzI9Sj1uZXcgVWludDMyQXJyYXkoYSk7ZC5IRUFQRjMyPW5ldyBGbG9hdDMyQXJyYXkoYSk7ZC5IRUFQRjY0PW5ldyBGbG9hdDY0QXJyYXkoYSl9dmFyIHVhLHZhPVtdLHdhPVtdLHhhPVtdLHlhPVtdLGthPTA7XFxyXFxuZnVuY3Rpb24gemEoKXt2YXIgYT1kLnByZVJ1bi5zaGlmdCgpO3ZhLnVuc2hpZnQoYSl9dmFyIEs9MCxBYT1udWxsLEw9bnVsbDtmdW5jdGlvbiBCKGEpe2lmKGQub25BYm9ydClkLm9uQWJvcnQoYSk7YT1cXFwiQWJvcnRlZChcXFwiK2ErXFxcIilcXFwiO3ooYSk7RD0hMDthPW5ldyBXZWJBc3NlbWJseS5SdW50aW1lRXJyb3IoYStcXFwiLiBCdWlsZCB3aXRoIC1zQVNTRVJUSU9OUyBmb3IgbW9yZSBpbmZvLlxcXCIpO2JhKGEpO3Rocm93IGE7fWZ1bmN0aW9uIEJhKCl7cmV0dXJuIE4uc3RhcnRzV2l0aChcXFwiZGF0YTphcHBsaWNhdGlvbi9vY3RldC1zdHJlYW07YmFzZTY0LFxcXCIpfXZhciBOO049XFxcIm9ydC13YXNtLndhc21cXFwiO2lmKCFCYSgpKXt2YXIgQ2E9TjtOPWQubG9jYXRlRmlsZT9kLmxvY2F0ZUZpbGUoQ2EscSk6cStDYX1cXHJcXG5mdW5jdGlvbiBEYSgpe3ZhciBhPU47dHJ5e2lmKGE9PU4mJkEpcmV0dXJuIG5ldyBVaW50OEFycmF5KEEpO2lmKHYpcmV0dXJuIHYoYSk7dGhyb3dcXFwiYm90aCBhc3luYyBhbmQgc3luYyBmZXRjaGluZyBvZiB0aGUgd2FzbSBmYWlsZWRcXFwiO31jYXRjaChiKXtCKGIpfX1cXHJcXG5mdW5jdGlvbiBFYSgpe2lmKCFBJiYoZmF8fG0pKXtpZihcXFwiZnVuY3Rpb25cXFwiPT10eXBlb2YgZmV0Y2gmJiFOLnN0YXJ0c1dpdGgoXFxcImZpbGU6Ly9cXFwiKSlyZXR1cm4gZmV0Y2goTix7Y3JlZGVudGlhbHM6XFxcInNhbWUtb3JpZ2luXFxcIn0pLnRoZW4oZnVuY3Rpb24oYSl7aWYoIWEub2spdGhyb3dcXFwiZmFpbGVkIHRvIGxvYWQgd2FzbSBiaW5hcnkgZmlsZSBhdCAnXFxcIitOK1xcXCInXFxcIjtyZXR1cm4gYS5hcnJheUJ1ZmZlcigpfSkuY2F0Y2goZnVuY3Rpb24oKXtyZXR1cm4gRGEoKX0pO2lmKHIpcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKGEsYil7cihOLGZ1bmN0aW9uKGMpe2EobmV3IFVpbnQ4QXJyYXkoYykpfSxiKX0pfXJldHVybiBQcm9taXNlLnJlc29sdmUoKS50aGVuKGZ1bmN0aW9uKCl7cmV0dXJuIERhKCl9KX1mdW5jdGlvbiBqYShhKXt0aGlzLm5hbWU9XFxcIkV4aXRTdGF0dXNcXFwiO3RoaXMubWVzc2FnZT1cXFwiUHJvZ3JhbSB0ZXJtaW5hdGVkIHdpdGggZXhpdChcXFwiK2ErXFxcIilcXFwiO3RoaXMuc3RhdHVzPWF9XFxyXFxuZnVuY3Rpb24gTyhhKXtmb3IoOzA8YS5sZW5ndGg7KWEuc2hpZnQoKShkKX12YXIgUD1bXSxRPTAsUj0wO1xcclxcbmZ1bmN0aW9uIFMoYSl7dGhpcy5EYj1hO3RoaXMuemI9YS0yNDt0aGlzLlViPWZ1bmN0aW9uKGIpe0pbdGhpcy56Yis0Pj4yPj4+MF09Yn07dGhpcy5FYj1mdW5jdGlvbigpe3JldHVybiBKW3RoaXMuemIrND4+Mj4+PjBdfTt0aGlzLlNiPWZ1bmN0aW9uKGIpe0pbdGhpcy56Yis4Pj4yPj4+MF09Yn07dGhpcy5XYj1mdW5jdGlvbigpe3JldHVybiBKW3RoaXMuemIrOD4+Mj4+PjBdfTt0aGlzLlRiPWZ1bmN0aW9uKCl7SVt0aGlzLnpiPj4yPj4+MF09MH07dGhpcy5JYj1mdW5jdGlvbihiKXtIW3RoaXMuemIrMTI+PjA+Pj4wXT1iPzE6MH07dGhpcy5QYj1mdW5jdGlvbigpe3JldHVybiAwIT1IW3RoaXMuemIrMTI+PjA+Pj4wXX07dGhpcy5KYj1mdW5jdGlvbihiKXtIW3RoaXMuemIrMTM+PjA+Pj4wXT1iPzE6MH07dGhpcy5MYj1mdW5jdGlvbigpe3JldHVybiAwIT1IW3RoaXMuemIrMTM+PjA+Pj4wXX07dGhpcy5SYj1mdW5jdGlvbihiLGMpe3RoaXMuRmIoMCk7dGhpcy5VYihiKTt0aGlzLlNiKGMpO1xcclxcbnRoaXMuVGIoKTt0aGlzLkliKCExKTt0aGlzLkpiKCExKX07dGhpcy5OYj1mdW5jdGlvbigpe0lbdGhpcy56Yj4+Mj4+PjBdKz0xfTt0aGlzLlhiPWZ1bmN0aW9uKCl7dmFyIGI9SVt0aGlzLnpiPj4yPj4+MF07SVt0aGlzLnpiPj4yPj4+MF09Yi0xO3JldHVybiAxPT09Yn07dGhpcy5GYj1mdW5jdGlvbihiKXtKW3RoaXMuemIrMTY+PjI+Pj4wXT1ifTt0aGlzLk9iPWZ1bmN0aW9uKCl7cmV0dXJuIEpbdGhpcy56YisxNj4+Mj4+PjBdfTt0aGlzLlFiPWZ1bmN0aW9uKCl7aWYoRmEodGhpcy5FYigpKSlyZXR1cm4gSlt0aGlzLkRiPj4yPj4+MF07dmFyIGI9dGhpcy5PYigpO3JldHVybiAwIT09Yj9iOnRoaXMuRGJ9fWZ1bmN0aW9uIEdhKGEpe3JldHVybiBIYSgobmV3IFMoYSkpLnpiKX12YXIgVD1bXTtmdW5jdGlvbiBVKGEpe3ZhciBiPVRbYV07Ynx8KGE+PVQubGVuZ3RoJiYoVC5sZW5ndGg9YSsxKSxUW2FdPWI9dWEuZ2V0KGEpKTtyZXR1cm4gYn1cXHJcXG5mdW5jdGlvbiBJYShhKXt2YXIgYj1yYShhKSsxLGM9SmEoYik7YyYmcWEoYSxILGMsYik7cmV0dXJuIGN9ZnVuY3Rpb24gS2EoYSxiLGMpe2Z1bmN0aW9uIGUobil7cmV0dXJuKG49bi50b1RpbWVTdHJpbmcoKS5tYXRjaCgvXFxcXCgoW0EtWmEteiBdKylcXFxcKSQvKSk/blsxXTpcXFwiR01UXFxcIn12YXIgZj0obmV3IERhdGUpLmdldEZ1bGxZZWFyKCksaD1uZXcgRGF0ZShmLDAsMSksaz1uZXcgRGF0ZShmLDYsMSk7Zj1oLmdldFRpbWV6b25lT2Zmc2V0KCk7dmFyIGw9ay5nZXRUaW1lem9uZU9mZnNldCgpO0lbYT4+Mj4+PjBdPTYwKk1hdGgubWF4KGYsbCk7SVtiPj4yPj4+MF09TnVtYmVyKGYhPWwpO2E9ZShoKTtiPWUoayk7YT1JYShhKTtiPUlhKGIpO2w8Zj8oSltjPj4yPj4+MF09YSxKW2MrND4+Mj4+PjBdPWIpOihKW2M+PjI+Pj4wXT1iLEpbYys0Pj4yPj4+MF09YSl9ZnVuY3Rpb24gTGEoYSxiLGMpe0xhLlZifHwoTGEuVmI9ITAsS2EoYSxiLGMpKX12YXIgTWE9e307XFxyXFxuZnVuY3Rpb24gTmEoKXtpZighT2Epe3ZhciBhPXtVU0VSOlxcXCJ3ZWJfdXNlclxcXCIsTE9HTkFNRTpcXFwid2ViX3VzZXJcXFwiLFBBVEg6XFxcIi9cXFwiLFBXRDpcXFwiL1xcXCIsSE9NRTpcXFwiL2hvbWUvd2ViX3VzZXJcXFwiLExBTkc6KFxcXCJvYmplY3RcXFwiPT10eXBlb2YgbmF2aWdhdG9yJiZuYXZpZ2F0b3IubGFuZ3VhZ2VzJiZuYXZpZ2F0b3IubGFuZ3VhZ2VzWzBdfHxcXFwiQ1xcXCIpLnJlcGxhY2UoXFxcIi1cXFwiLFxcXCJfXFxcIikrXFxcIi5VVEYtOFxcXCIsXzpkYXx8XFxcIi4vdGhpcy5wcm9ncmFtXFxcIn0sYjtmb3IoYiBpbiBNYSl2b2lkIDA9PT1NYVtiXT9kZWxldGUgYVtiXTphW2JdPU1hW2JdO3ZhciBjPVtdO2ZvcihiIGluIGEpYy5wdXNoKGIrXFxcIj1cXFwiK2FbYl0pO09hPWN9cmV0dXJuIE9hfXZhciBPYSxQYT1bbnVsbCxbXSxbXV07ZnVuY3Rpb24gUWEoYSxiKXt2YXIgYz1QYVthXTswPT09Ynx8MTA9PT1iPygoMT09PWE/bGE6eikob2EoYywwKSksYy5sZW5ndGg9MCk6Yy5wdXNoKGIpfXZhciBWPTA7XFxyXFxuZnVuY3Rpb24gUmEoKXtpZihcXFwib2JqZWN0XFxcIj09dHlwZW9mIGNyeXB0byYmXFxcImZ1bmN0aW9uXFxcIj09dHlwZW9mIGNyeXB0by5nZXRSYW5kb21WYWx1ZXMpe3ZhciBhPW5ldyBVaW50OEFycmF5KDEpO3JldHVybigpPT57Y3J5cHRvLmdldFJhbmRvbVZhbHVlcyhhKTtyZXR1cm4gYVswXX19aWYocCl0cnl7dmFyIGI9X193ZWJwYWNrX3JlcXVpcmVfXyhPYmplY3QoZnVuY3Rpb24gd2VicGFja01pc3NpbmdNb2R1bGUoKSB7IHZhciBlID0gbmV3IEVycm9yKFxcXCJDYW5ub3QgZmluZCBtb2R1bGUgJ2NyeXB0bydcXFwiKTsgZS5jb2RlID0gJ01PRFVMRV9OT1RfRk9VTkQnOyB0aHJvdyBlOyB9KCkpKTtyZXR1cm4oKT0+Yi5yYW5kb21CeXRlcygxKVswXX1jYXRjaChjKXt9cmV0dXJuKCk9PkIoXFxcInJhbmRvbURldmljZVxcXCIpfWZ1bmN0aW9uIFcoYSxiKXtXLk1ifHwoVy5NYj1SYSgpKTtmb3IodmFyIGM9MDtjPGI7YysrKUhbYStjPj4wPj4+MF09Vy5NYigpO3JldHVybiAwfWZ1bmN0aW9uIFNhKGEpe3JldHVybiAwPT09YSU0JiYoMCE9PWElMTAwfHwwPT09YSU0MDApfXZhciBUYT1bMzEsMjksMzEsMzAsMzEsMzAsMzEsMzEsMzAsMzEsMzAsMzFdLFVhPVszMSwyOCwzMSwzMCwzMSwzMCwzMSwzMSwzMCwzMSwzMCwzMV07XFxyXFxuZnVuY3Rpb24gVmEoYSl7dmFyIGI9QXJyYXkocmEoYSkrMSk7cWEoYSxiLDAsYi5sZW5ndGgpO3JldHVybiBifVxcclxcbmZ1bmN0aW9uIFdhKGEsYixjLGUpe2Z1bmN0aW9uIGYoZyx1LHcpe2ZvcihnPVxcXCJudW1iZXJcXFwiPT10eXBlb2YgZz9nLnRvU3RyaW5nKCk6Z3x8XFxcIlxcXCI7Zy5sZW5ndGg8dTspZz13WzBdK2c7cmV0dXJuIGd9ZnVuY3Rpb24gaChnLHUpe3JldHVybiBmKGcsdSxcXFwiMFxcXCIpfWZ1bmN0aW9uIGsoZyx1KXtmdW5jdGlvbiB3KE0pe3JldHVybiAwPk0/LTE6MDxNPzE6MH12YXIgRjswPT09KEY9dyhnLmdldEZ1bGxZZWFyKCktdS5nZXRGdWxsWWVhcigpKSkmJjA9PT0oRj13KGcuZ2V0TW9udGgoKS11LmdldE1vbnRoKCkpKSYmKEY9dyhnLmdldERhdGUoKS11LmdldERhdGUoKSkpO3JldHVybiBGfWZ1bmN0aW9uIGwoZyl7c3dpdGNoKGcuZ2V0RGF5KCkpe2Nhc2UgMDpyZXR1cm4gbmV3IERhdGUoZy5nZXRGdWxsWWVhcigpLTEsMTEsMjkpO2Nhc2UgMTpyZXR1cm4gZztjYXNlIDI6cmV0dXJuIG5ldyBEYXRlKGcuZ2V0RnVsbFllYXIoKSwwLDMpO2Nhc2UgMzpyZXR1cm4gbmV3IERhdGUoZy5nZXRGdWxsWWVhcigpLFxcclxcbjAsMik7Y2FzZSA0OnJldHVybiBuZXcgRGF0ZShnLmdldEZ1bGxZZWFyKCksMCwxKTtjYXNlIDU6cmV0dXJuIG5ldyBEYXRlKGcuZ2V0RnVsbFllYXIoKS0xLDExLDMxKTtjYXNlIDY6cmV0dXJuIG5ldyBEYXRlKGcuZ2V0RnVsbFllYXIoKS0xLDExLDMwKX19ZnVuY3Rpb24gbihnKXt2YXIgdT1nLkJiO2ZvcihnPW5ldyBEYXRlKChuZXcgRGF0ZShnLkNiKzE5MDAsMCwxKSkuZ2V0VGltZSgpKTswPHU7KXt2YXIgdz1nLmdldE1vbnRoKCksRj0oU2EoZy5nZXRGdWxsWWVhcigpKT9UYTpVYSlbd107aWYodT5GLWcuZ2V0RGF0ZSgpKXUtPUYtZy5nZXREYXRlKCkrMSxnLnNldERhdGUoMSksMTE+dz9nLnNldE1vbnRoKHcrMSk6KGcuc2V0TW9udGgoMCksZy5zZXRGdWxsWWVhcihnLmdldEZ1bGxZZWFyKCkrMSkpO2Vsc2V7Zy5zZXREYXRlKGcuZ2V0RGF0ZSgpK3UpO2JyZWFrfX13PW5ldyBEYXRlKGcuZ2V0RnVsbFllYXIoKSsxLDAsNCk7dT1sKG5ldyBEYXRlKGcuZ2V0RnVsbFllYXIoKSxcXHJcXG4wLDQpKTt3PWwodyk7cmV0dXJuIDA+PWsodSxnKT8wPj1rKHcsZyk/Zy5nZXRGdWxsWWVhcigpKzE6Zy5nZXRGdWxsWWVhcigpOmcuZ2V0RnVsbFllYXIoKS0xfXZhciB0PUlbZSs0MD4+Mj4+PjBdO2U9eyRiOklbZT4+Mj4+PjBdLFpiOklbZSs0Pj4yPj4+MF0sR2I6SVtlKzg+PjI+Pj4wXSxLYjpJW2UrMTI+PjI+Pj4wXSxIYjpJW2UrMTY+PjI+Pj4wXSxDYjpJW2UrMjA+PjI+Pj4wXSxBYjpJW2UrMjQ+PjI+Pj4wXSxCYjpJW2UrMjg+PjI+Pj4wXSxiYzpJW2UrMzI+PjI+Pj4wXSxZYjpJW2UrMzY+PjI+Pj4wXSxhYzp0P3BhKHQpOlxcXCJcXFwifTtjPXBhKGMpO3Q9e1xcXCIlY1xcXCI6XFxcIiVhICViICVkICVIOiVNOiVTICVZXFxcIixcXFwiJURcXFwiOlxcXCIlbS8lZC8leVxcXCIsXFxcIiVGXFxcIjpcXFwiJVktJW0tJWRcXFwiLFxcXCIlaFxcXCI6XFxcIiViXFxcIixcXFwiJXJcXFwiOlxcXCIlSTolTTolUyAlcFxcXCIsXFxcIiVSXFxcIjpcXFwiJUg6JU1cXFwiLFxcXCIlVFxcXCI6XFxcIiVIOiVNOiVTXFxcIixcXFwiJXhcXFwiOlxcXCIlbS8lZC8leVxcXCIsXFxcIiVYXFxcIjpcXFwiJUg6JU06JVNcXFwiLFxcXCIlRWNcXFwiOlxcXCIlY1xcXCIsXFxcIiVFQ1xcXCI6XFxcIiVDXFxcIixcXFwiJUV4XFxcIjpcXFwiJW0vJWQvJXlcXFwiLFxcclxcblxcXCIlRVhcXFwiOlxcXCIlSDolTTolU1xcXCIsXFxcIiVFeVxcXCI6XFxcIiV5XFxcIixcXFwiJUVZXFxcIjpcXFwiJVlcXFwiLFxcXCIlT2RcXFwiOlxcXCIlZFxcXCIsXFxcIiVPZVxcXCI6XFxcIiVlXFxcIixcXFwiJU9IXFxcIjpcXFwiJUhcXFwiLFxcXCIlT0lcXFwiOlxcXCIlSVxcXCIsXFxcIiVPbVxcXCI6XFxcIiVtXFxcIixcXFwiJU9NXFxcIjpcXFwiJU1cXFwiLFxcXCIlT1NcXFwiOlxcXCIlU1xcXCIsXFxcIiVPdVxcXCI6XFxcIiV1XFxcIixcXFwiJU9VXFxcIjpcXFwiJVVcXFwiLFxcXCIlT1ZcXFwiOlxcXCIlVlxcXCIsXFxcIiVPd1xcXCI6XFxcIiV3XFxcIixcXFwiJU9XXFxcIjpcXFwiJVdcXFwiLFxcXCIlT3lcXFwiOlxcXCIleVxcXCJ9O2Zvcih2YXIgeCBpbiB0KWM9Yy5yZXBsYWNlKG5ldyBSZWdFeHAoeCxcXFwiZ1xcXCIpLHRbeF0pO3ZhciBFPVxcXCJTdW5kYXkgTW9uZGF5IFR1ZXNkYXkgV2VkbmVzZGF5IFRodXJzZGF5IEZyaWRheSBTYXR1cmRheVxcXCIuc3BsaXQoXFxcIiBcXFwiKSxDPVxcXCJKYW51YXJ5IEZlYnJ1YXJ5IE1hcmNoIEFwcmlsIE1heSBKdW5lIEp1bHkgQXVndXN0IFNlcHRlbWJlciBPY3RvYmVyIE5vdmVtYmVyIERlY2VtYmVyXFxcIi5zcGxpdChcXFwiIFxcXCIpO3Q9e1xcXCIlYVxcXCI6ZnVuY3Rpb24oZyl7cmV0dXJuIEVbZy5BYl0uc3Vic3RyaW5nKDAsMyl9LFxcXCIlQVxcXCI6ZnVuY3Rpb24oZyl7cmV0dXJuIEVbZy5BYl19LFxcXCIlYlxcXCI6ZnVuY3Rpb24oZyl7cmV0dXJuIENbZy5IYl0uc3Vic3RyaW5nKDAsXFxyXFxuMyl9LFxcXCIlQlxcXCI6ZnVuY3Rpb24oZyl7cmV0dXJuIENbZy5IYl19LFxcXCIlQ1xcXCI6ZnVuY3Rpb24oZyl7cmV0dXJuIGgoKGcuQ2IrMTkwMCkvMTAwfDAsMil9LFxcXCIlZFxcXCI6ZnVuY3Rpb24oZyl7cmV0dXJuIGgoZy5LYiwyKX0sXFxcIiVlXFxcIjpmdW5jdGlvbihnKXtyZXR1cm4gZihnLktiLDIsXFxcIiBcXFwiKX0sXFxcIiVnXFxcIjpmdW5jdGlvbihnKXtyZXR1cm4gbihnKS50b1N0cmluZygpLnN1YnN0cmluZygyKX0sXFxcIiVHXFxcIjpmdW5jdGlvbihnKXtyZXR1cm4gbihnKX0sXFxcIiVIXFxcIjpmdW5jdGlvbihnKXtyZXR1cm4gaChnLkdiLDIpfSxcXFwiJUlcXFwiOmZ1bmN0aW9uKGcpe2c9Zy5HYjswPT1nP2c9MTI6MTI8ZyYmKGctPTEyKTtyZXR1cm4gaChnLDIpfSxcXFwiJWpcXFwiOmZ1bmN0aW9uKGcpe2Zvcih2YXIgdT0wLHc9MDt3PD1nLkhiLTE7dSs9KFNhKGcuQ2IrMTkwMCk/VGE6VWEpW3crK10pO3JldHVybiBoKGcuS2IrdSwzKX0sXFxcIiVtXFxcIjpmdW5jdGlvbihnKXtyZXR1cm4gaChnLkhiKzEsMil9LFxcXCIlTVxcXCI6ZnVuY3Rpb24oZyl7cmV0dXJuIGgoZy5aYixcXHJcXG4yKX0sXFxcIiVuXFxcIjpmdW5jdGlvbigpe3JldHVyblxcXCJcXFxcblxcXCJ9LFxcXCIlcFxcXCI6ZnVuY3Rpb24oZyl7cmV0dXJuIDA8PWcuR2ImJjEyPmcuR2I/XFxcIkFNXFxcIjpcXFwiUE1cXFwifSxcXFwiJVNcXFwiOmZ1bmN0aW9uKGcpe3JldHVybiBoKGcuJGIsMil9LFxcXCIldFxcXCI6ZnVuY3Rpb24oKXtyZXR1cm5cXFwiXFxcXHRcXFwifSxcXFwiJXVcXFwiOmZ1bmN0aW9uKGcpe3JldHVybiBnLkFifHw3fSxcXFwiJVVcXFwiOmZ1bmN0aW9uKGcpe3JldHVybiBoKE1hdGguZmxvb3IoKGcuQmIrNy1nLkFiKS83KSwyKX0sXFxcIiVWXFxcIjpmdW5jdGlvbihnKXt2YXIgdT1NYXRoLmZsb29yKChnLkJiKzctKGcuQWIrNiklNykvNyk7Mj49KGcuQWIrMzcxLWcuQmItMiklNyYmdSsrO2lmKHUpNTM9PXUmJih3PShnLkFiKzM3MS1nLkJiKSU3LDQ9PXd8fDM9PXcmJlNhKGcuQ2IpfHwodT0xKSk7ZWxzZXt1PTUyO3ZhciB3PShnLkFiKzctZy5CYi0xKSU3Oyg0PT13fHw1PT13JiZTYShnLkNiJTQwMC0xKSkmJnUrK31yZXR1cm4gaCh1LDIpfSxcXFwiJXdcXFwiOmZ1bmN0aW9uKGcpe3JldHVybiBnLkFifSxcXFwiJVdcXFwiOmZ1bmN0aW9uKGcpe3JldHVybiBoKE1hdGguZmxvb3IoKGcuQmIrXFxyXFxuNy0oZy5BYis2KSU3KS83KSwyKX0sXFxcIiV5XFxcIjpmdW5jdGlvbihnKXtyZXR1cm4oZy5DYisxOTAwKS50b1N0cmluZygpLnN1YnN0cmluZygyKX0sXFxcIiVZXFxcIjpmdW5jdGlvbihnKXtyZXR1cm4gZy5DYisxOTAwfSxcXFwiJXpcXFwiOmZ1bmN0aW9uKGcpe2c9Zy5ZYjt2YXIgdT0wPD1nO2c9TWF0aC5hYnMoZykvNjA7cmV0dXJuKHU/XFxcIitcXFwiOlxcXCItXFxcIikrU3RyaW5nKFxcXCIwMDAwXFxcIisoZy82MCoxMDArZyU2MCkpLnNsaWNlKC00KX0sXFxcIiVaXFxcIjpmdW5jdGlvbihnKXtyZXR1cm4gZy5hY30sXFxcIiUlXFxcIjpmdW5jdGlvbigpe3JldHVyblxcXCIlXFxcIn19O2M9Yy5yZXBsYWNlKC8lJS9nLFxcXCJcXFxceDAwXFxcXHgwMFxcXCIpO2Zvcih4IGluIHQpYy5pbmNsdWRlcyh4KSYmKGM9Yy5yZXBsYWNlKG5ldyBSZWdFeHAoeCxcXFwiZ1xcXCIpLHRbeF0oZSkpKTtjPWMucmVwbGFjZSgvXFxcXDBcXFxcMC9nLFxcXCIlXFxcIik7eD1WYShjKTtpZih4Lmxlbmd0aD5iKXJldHVybiAwO0guc2V0KHgsYT4+PjApO3JldHVybiB4Lmxlbmd0aC0xfVxcclxcbnZhciBKYj17YTpmdW5jdGlvbihhKXtyZXR1cm4gSmEoYSsyNCkrMjR9LG06ZnVuY3Rpb24oYSl7YT1uZXcgUyhhKTthLlBiKCl8fChhLkliKCEwKSxRLS0pO2EuSmIoITEpO1AucHVzaChhKTthLk5iKCk7cmV0dXJuIGEuUWIoKX0saWE6ZnVuY3Rpb24oYSl7eihcXFwiVW5leHBlY3RlZCBleGNlcHRpb24gdGhyb3duLCB0aGlzIGlzIG5vdCBwcm9wZXJseSBzdXBwb3J0ZWQgLSBhYm9ydGluZ1xcXCIpO0Q9ITA7dGhyb3cgYTt9LHc6ZnVuY3Rpb24oKXtYKDApO3ZhciBhPVAucG9wKCk7aWYoYS5YYigpJiYhYS5MYigpKXt2YXIgYj1hLldiKCk7YiYmVShiKShhLkRiKTtHYShhLkRiKX1SPTB9LGQ6ZnVuY3Rpb24oKXt2YXIgYT1SO2lmKCFhKXJldHVybiBWPTA7dmFyIGI9bmV3IFMoYSk7Yi5GYihhKTt2YXIgYz1iLkViKCk7aWYoIWMpcmV0dXJuIFY9MCxhO2Zvcih2YXIgZT1BcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpLGY9MDtmPGUubGVuZ3RoO2YrKyl7dmFyIGg9ZVtmXTtcXHJcXG5pZigwPT09aHx8aD09PWMpYnJlYWs7aWYoWGEoaCxjLGIuemIrMTYpKXJldHVybiBWPWgsYX1WPWM7cmV0dXJuIGF9LGs6ZnVuY3Rpb24oKXt2YXIgYT1SO2lmKCFhKXJldHVybiBWPTA7dmFyIGI9bmV3IFMoYSk7Yi5GYihhKTt2YXIgYz1iLkViKCk7aWYoIWMpcmV0dXJuIFY9MCxhO2Zvcih2YXIgZT1BcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpLGY9MDtmPGUubGVuZ3RoO2YrKyl7dmFyIGg9ZVtmXTtpZigwPT09aHx8aD09PWMpYnJlYWs7aWYoWGEoaCxjLGIuemIrMTYpKXJldHVybiBWPWgsYX1WPWM7cmV0dXJuIGF9LGc6ZnVuY3Rpb24oKXt2YXIgYT1SO2lmKCFhKXJldHVybiBWPTA7dmFyIGI9bmV3IFMoYSk7Yi5GYihhKTt2YXIgYz1iLkViKCk7aWYoIWMpcmV0dXJuIFY9MCxhO2Zvcih2YXIgZT1BcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpLGY9MDtmPGUubGVuZ3RoO2YrKyl7dmFyIGg9ZVtmXTtpZigwPT09aHx8aD09PWMpYnJlYWs7XFxyXFxuaWYoWGEoaCxjLGIuemIrMTYpKXJldHVybiBWPWgsYX1WPWM7cmV0dXJuIGF9LHM6R2EsTDpmdW5jdGlvbigpe3ZhciBhPVAucG9wKCk7YXx8QihcXFwibm8gZXhjZXB0aW9uIHRvIHRocm93XFxcIik7dmFyIGI9YS5EYjthLkxiKCl8fChQLnB1c2goYSksYS5KYighMCksYS5JYighMSksUSsrKTtSPWI7dGhyb3cgYjt9LGI6ZnVuY3Rpb24oYSxiLGMpeyhuZXcgUyhhKSkuUmIoYixjKTtSPWE7USsrO3Rocm93IGE7fSxsYTpmdW5jdGlvbigpe3JldHVybiBRfSxpOmZ1bmN0aW9uKGEpe1J8fChSPWEpO3Rocm93IGE7fSxIOmZ1bmN0aW9uKCl7cmV0dXJuIDB9LEJhOmZ1bmN0aW9uKCl7fSxwYTpmdW5jdGlvbigpe30scmE6ZnVuY3Rpb24oKXt9LGthOmZ1bmN0aW9uKCl7cmV0dXJuIDB9LHphOmZ1bmN0aW9uKCl7fSx1YTpmdW5jdGlvbigpe30seWE6ZnVuY3Rpb24oKXt9LFI6ZnVuY3Rpb24oKXt9LHFhOmZ1bmN0aW9uKCl7fSxuYTpmdW5jdGlvbigpe30sQWE6ZnVuY3Rpb24oKXt9LG9hOmZ1bmN0aW9uKCl7fSxcXHJcXG5IYTpmdW5jdGlvbigpe30sSmE6ZnVuY3Rpb24oKXtCKFxcXCJUbyB1c2UgZGxvcGVuLCB5b3UgbmVlZCBlbmFibGUgZHluYW1pYyBsaW5raW5nLCBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2Vtc2NyaXB0ZW4tY29yZS9lbXNjcmlwdGVuL3dpa2kvTGlua2luZ1xcXCIpfSxJYTpmdW5jdGlvbigpe0IoXFxcIlRvIHVzZSBkbG9wZW4sIHlvdSBuZWVkIGVuYWJsZSBkeW5hbWljIGxpbmtpbmcsIHNlZSBodHRwczovL2dpdGh1Yi5jb20vZW1zY3JpcHRlbi1jb3JlL2Vtc2NyaXB0ZW4vd2lraS9MaW5raW5nXFxcIil9LFM6ZnVuY3Rpb24oKXtyZXR1cm4gRGF0ZS5ub3coKX0sQ2E6ZnVuY3Rpb24oKXtyZXR1cm4hMH0sRGE6ZnVuY3Rpb24oYSxiKXthPW5ldyBEYXRlKDFFMyooSlthPj4+Ml0rNDI5NDk2NzI5NipJW2ErND4+PjJdKSk7SVtiPj4yPj4+MF09YS5nZXRVVENTZWNvbmRzKCk7SVtiKzQ+PjI+Pj4wXT1hLmdldFVUQ01pbnV0ZXMoKTtJW2IrOD4+Mj4+PjBdPWEuZ2V0VVRDSG91cnMoKTtJW2IrMTI+PjI+Pj5cXHJcXG4wXT1hLmdldFVUQ0RhdGUoKTtJW2IrMTY+PjI+Pj4wXT1hLmdldFVUQ01vbnRoKCk7SVtiKzIwPj4yPj4+MF09YS5nZXRVVENGdWxsWWVhcigpLTE5MDA7SVtiKzI0Pj4yPj4+MF09YS5nZXRVVENEYXkoKTtJW2IrMjg+PjI+Pj4wXT0oYS5nZXRUaW1lKCktRGF0ZS5VVEMoYS5nZXRVVENGdWxsWWVhcigpLDAsMSwwLDAsMCwwKSkvODY0RTV8MH0sRWE6ZnVuY3Rpb24oYSxiKXthPW5ldyBEYXRlKDFFMyooSlthPj4+Ml0rNDI5NDk2NzI5NipJW2ErND4+PjJdKSk7SVtiPj4yPj4+MF09YS5nZXRTZWNvbmRzKCk7SVtiKzQ+PjI+Pj4wXT1hLmdldE1pbnV0ZXMoKTtJW2IrOD4+Mj4+PjBdPWEuZ2V0SG91cnMoKTtJW2IrMTI+PjI+Pj4wXT1hLmdldERhdGUoKTtJW2IrMTY+PjI+Pj4wXT1hLmdldE1vbnRoKCk7SVtiKzIwPj4yPj4+MF09YS5nZXRGdWxsWWVhcigpLTE5MDA7SVtiKzI0Pj4yPj4+MF09YS5nZXREYXkoKTt2YXIgYz1uZXcgRGF0ZShhLmdldEZ1bGxZZWFyKCksMCwxKTtJW2IrXFxyXFxuMjg+PjI+Pj4wXT0oYS5nZXRUaW1lKCktYy5nZXRUaW1lKCkpLzg2NEU1fDA7SVtiKzM2Pj4yPj4+MF09LSg2MCphLmdldFRpbWV6b25lT2Zmc2V0KCkpO3ZhciBlPShuZXcgRGF0ZShhLmdldEZ1bGxZZWFyKCksNiwxKSkuZ2V0VGltZXpvbmVPZmZzZXQoKTtjPWMuZ2V0VGltZXpvbmVPZmZzZXQoKTtJW2IrMzI+PjI+Pj4wXT0oZSE9YyYmYS5nZXRUaW1lem9uZU9mZnNldCgpPT1NYXRoLm1pbihjLGUpKXwwfSxGYTpmdW5jdGlvbihhKXt2YXIgYj1uZXcgRGF0ZShJW2ErMjA+PjI+Pj4wXSsxOTAwLElbYSsxNj4+Mj4+PjBdLElbYSsxMj4+Mj4+PjBdLElbYSs4Pj4yPj4+MF0sSVthKzQ+PjI+Pj4wXSxJW2E+PjI+Pj4wXSwwKSxjPUlbYSszMj4+Mj4+PjBdLGU9Yi5nZXRUaW1lem9uZU9mZnNldCgpLGY9bmV3IERhdGUoYi5nZXRGdWxsWWVhcigpLDAsMSksaD0obmV3IERhdGUoYi5nZXRGdWxsWWVhcigpLDYsMSkpLmdldFRpbWV6b25lT2Zmc2V0KCksaz1mLmdldFRpbWV6b25lT2Zmc2V0KCksXFxyXFxubD1NYXRoLm1pbihrLGgpOzA+Yz9JW2ErMzI+PjI+Pj4wXT1OdW1iZXIoaCE9ayYmbD09ZSk6MDxjIT0obD09ZSkmJihoPU1hdGgubWF4KGssaCksYi5zZXRUaW1lKGIuZ2V0VGltZSgpKzZFNCooKDA8Yz9sOmgpLWUpKSk7SVthKzI0Pj4yPj4+MF09Yi5nZXREYXkoKTtJW2ErMjg+PjI+Pj4wXT0oYi5nZXRUaW1lKCktZi5nZXRUaW1lKCkpLzg2NEU1fDA7SVthPj4yPj4+MF09Yi5nZXRTZWNvbmRzKCk7SVthKzQ+PjI+Pj4wXT1iLmdldE1pbnV0ZXMoKTtJW2ErOD4+Mj4+PjBdPWIuZ2V0SG91cnMoKTtJW2ErMTI+PjI+Pj4wXT1iLmdldERhdGUoKTtJW2ErMTY+PjI+Pj4wXT1iLmdldE1vbnRoKCk7cmV0dXJuIGIuZ2V0VGltZSgpLzFFM3wwfSxzYTpmdW5jdGlvbigpe3JldHVybi01Mn0sdGE6ZnVuY3Rpb24oKXt9LEdhOkxhLEI6ZnVuY3Rpb24oKXtCKFxcXCJcXFwiKX0sbWE6ZnVuY3Rpb24oKXtyZXR1cm4gNDI5NDkwMTc2MH0sSTpwPygpPT57dmFyIGE9cHJvY2Vzcy5ocnRpbWUoKTtyZXR1cm4gMUUzKlxcclxcbmFbMF0rYVsxXS8xRTZ9OigpPT5wZXJmb3JtYW5jZS5ub3coKSx4YTpmdW5jdGlvbihhLGIsYyl7Ry5jb3B5V2l0aGluKGE+Pj4wLGI+Pj4wLGIrYz4+PjApfSxHOmZ1bmN0aW9uKGEpe3ZhciBiPUcubGVuZ3RoO2E+Pj49MDtpZig0Mjk0OTAxNzYwPGEpcmV0dXJuITE7Zm9yKHZhciBjPTE7ND49YztjKj0yKXt2YXIgZT1iKigxKy4yL2MpO2U9TWF0aC5taW4oZSxhKzEwMDY2MzI5Nik7dmFyIGY9TWF0aDtlPU1hdGgubWF4KGEsZSk7Zj1mLm1pbi5jYWxsKGYsNDI5NDkwMTc2MCxlKyg2NTUzNi1lJTY1NTM2KSU2NTUzNik7YTp7dHJ5e21hLmdyb3coZi1zYS5ieXRlTGVuZ3RoKzY1NTM1Pj4+MTYpO3RhKCk7dmFyIGg9MTticmVhayBhfWNhdGNoKGspe31oPXZvaWQgMH1pZihoKXJldHVybiEwfXJldHVybiExfSx2YTpmdW5jdGlvbihhLGIpe3ZhciBjPTA7TmEoKS5mb3JFYWNoKGZ1bmN0aW9uKGUsZil7dmFyIGg9YitjO2Y9SlthKzQqZj4+Mj4+PjBdPWg7Zm9yKGg9MDtoPGUubGVuZ3RoOysraClIW2YrKz4+XFxyXFxuMD4+PjBdPWUuY2hhckNvZGVBdChoKTtIW2Y+PjA+Pj4wXT0wO2MrPWUubGVuZ3RoKzF9KTtyZXR1cm4gMH0sd2E6ZnVuY3Rpb24oYSxiKXt2YXIgYz1OYSgpO0pbYT4+Mj4+PjBdPWMubGVuZ3RoO3ZhciBlPTA7Yy5mb3JFYWNoKGZ1bmN0aW9uKGYpe2UrPWYubGVuZ3RoKzF9KTtKW2I+PjI+Pj4wXT1lO3JldHVybiAwfSxiYTpmdW5jdGlvbihhKXtub0V4aXRSdW50aW1lfHwwPGthfHwoWWEoKSxPKHhhKSxaYSgwKSxQYVsxXS5sZW5ndGgmJlFhKDEsMTApLFBhWzJdLmxlbmd0aCYmUWEoMiwxMCkpO2lmKCEobm9FeGl0UnVudGltZXx8MDxrYSkpe2lmKGQub25FeGl0KWQub25FeGl0KGEpO0Q9ITB9ZWEoYSxuZXcgamEoYSkpfSxFOmZ1bmN0aW9uKCl7cmV0dXJuIDUyfSxROmZ1bmN0aW9uKCl7cmV0dXJuIDUyfSxjYTpmdW5jdGlvbigpe3JldHVybiA3MH0sUDpmdW5jdGlvbihhLGIsYyxlKXtmb3IodmFyIGY9MCxoPTA7aDxjO2grKyl7dmFyIGs9SltiPj4yPj4+MF0sbD1KW2IrND4+XFxyXFxuMj4+PjBdO2IrPTg7Zm9yKHZhciBuPTA7bjxsO24rKylRYShhLEdbaytuPj4+MF0pO2YrPWx9SltlPj4yPj4+MF09ZjtyZXR1cm4gMH0sYzpmdW5jdGlvbigpe3JldHVybiBWfSxqYTpXLGVhOiRhLGZhOmFiLEo6YmIsZTpjYixOOmRiLE86ZWIsajpmYixvOmdiLHA6aGIsTTppYixyOmpiLHY6a2IsSzpsYixEOm1iLFg6bmIsVjpvYixVOnBiLFo6cWIsVzpyYixZOnNiLFQ6dGIsZjp1YixxOnZiLGg6d2IsZGE6eGIsbDp5Yix0OnpiLHU6QWIseDpCYix6OkNiLGdhOkRiLEE6RWIsQzpGYixhYTpHYixfOkhiLCQ6SWIsbjpmdW5jdGlvbihhKXtyZXR1cm4gYX0sRjpmdW5jdGlvbihhKXtWPWF9LGhhOldhLHk6ZnVuY3Rpb24oYSxiLGMsZSl7cmV0dXJuIFdhKGEsYixjLGUpfX07XFxyXFxuKGZ1bmN0aW9uKCl7ZnVuY3Rpb24gYShmKXtkLmFzbT1mLmV4cG9ydHM7bWE9ZC5hc20uS2E7dGEoKTt1YT1kLmFzbS5pYjt3YS51bnNoaWZ0KGQuYXNtLkxhKTtLLS07ZC5tb25pdG9yUnVuRGVwZW5kZW5jaWVzJiZkLm1vbml0b3JSdW5EZXBlbmRlbmNpZXMoSyk7MD09SyYmKG51bGwhPT1BYSYmKGNsZWFySW50ZXJ2YWwoQWEpLEFhPW51bGwpLEwmJihmPUwsTD1udWxsLGYoKSkpfWZ1bmN0aW9uIGIoZil7YShmLmluc3RhbmNlKX1mdW5jdGlvbiBjKGYpe3JldHVybiBFYSgpLnRoZW4oZnVuY3Rpb24oaCl7cmV0dXJuIFdlYkFzc2VtYmx5Lmluc3RhbnRpYXRlKGgsZSl9KS50aGVuKGZ1bmN0aW9uKGgpe3JldHVybiBofSkudGhlbihmLGZ1bmN0aW9uKGgpe3ooXFxcImZhaWxlZCB0byBhc3luY2hyb25vdXNseSBwcmVwYXJlIHdhc206IFxcXCIraCk7QihoKX0pfXZhciBlPXthOkpifTtLKys7ZC5tb25pdG9yUnVuRGVwZW5kZW5jaWVzJiZkLm1vbml0b3JSdW5EZXBlbmRlbmNpZXMoSyk7aWYoZC5pbnN0YW50aWF0ZVdhc20pdHJ5e3JldHVybiBkLmluc3RhbnRpYXRlV2FzbShlLFxcclxcbmEpfWNhdGNoKGYpe3JldHVybiB6KFxcXCJNb2R1bGUuaW5zdGFudGlhdGVXYXNtIGNhbGxiYWNrIGZhaWxlZCB3aXRoIGVycm9yOiBcXFwiK2YpLCExfShmdW5jdGlvbigpe3JldHVybiBBfHxcXFwiZnVuY3Rpb25cXFwiIT10eXBlb2YgV2ViQXNzZW1ibHkuaW5zdGFudGlhdGVTdHJlYW1pbmd8fEJhKCl8fE4uc3RhcnRzV2l0aChcXFwiZmlsZTovL1xcXCIpfHxwfHxcXFwiZnVuY3Rpb25cXFwiIT10eXBlb2YgZmV0Y2g/YyhiKTpmZXRjaChOLHtjcmVkZW50aWFsczpcXFwic2FtZS1vcmlnaW5cXFwifSkudGhlbihmdW5jdGlvbihmKXtyZXR1cm4gV2ViQXNzZW1ibHkuaW5zdGFudGlhdGVTdHJlYW1pbmcoZixlKS50aGVuKGIsZnVuY3Rpb24oaCl7eihcXFwid2FzbSBzdHJlYW1pbmcgY29tcGlsZSBmYWlsZWQ6IFxcXCIraCk7eihcXFwiZmFsbGluZyBiYWNrIHRvIEFycmF5QnVmZmVyIGluc3RhbnRpYXRpb25cXFwiKTtyZXR1cm4gYyhiKX0pfSl9KSgpLmNhdGNoKGJhKTtyZXR1cm57fX0pKCk7XFxyXFxuZC5fX193YXNtX2NhbGxfY3RvcnM9ZnVuY3Rpb24oKXtyZXR1cm4oZC5fX193YXNtX2NhbGxfY3RvcnM9ZC5hc20uTGEpLmFwcGx5KG51bGwsYXJndW1lbnRzKX07ZC5fT3J0SW5pdD1mdW5jdGlvbigpe3JldHVybihkLl9PcnRJbml0PWQuYXNtLk1hKS5hcHBseShudWxsLGFyZ3VtZW50cyl9O2QuX09ydENyZWF0ZVNlc3Npb25PcHRpb25zPWZ1bmN0aW9uKCl7cmV0dXJuKGQuX09ydENyZWF0ZVNlc3Npb25PcHRpb25zPWQuYXNtLk5hKS5hcHBseShudWxsLGFyZ3VtZW50cyl9O2QuX09ydEFwcGVuZEV4ZWN1dGlvblByb3ZpZGVyPWZ1bmN0aW9uKCl7cmV0dXJuKGQuX09ydEFwcGVuZEV4ZWN1dGlvblByb3ZpZGVyPWQuYXNtLk9hKS5hcHBseShudWxsLGFyZ3VtZW50cyl9O2QuX09ydEFkZFNlc3Npb25Db25maWdFbnRyeT1mdW5jdGlvbigpe3JldHVybihkLl9PcnRBZGRTZXNzaW9uQ29uZmlnRW50cnk9ZC5hc20uUGEpLmFwcGx5KG51bGwsYXJndW1lbnRzKX07XFxyXFxuZC5fT3J0UmVsZWFzZVNlc3Npb25PcHRpb25zPWZ1bmN0aW9uKCl7cmV0dXJuKGQuX09ydFJlbGVhc2VTZXNzaW9uT3B0aW9ucz1kLmFzbS5RYSkuYXBwbHkobnVsbCxhcmd1bWVudHMpfTtkLl9PcnRDcmVhdGVTZXNzaW9uPWZ1bmN0aW9uKCl7cmV0dXJuKGQuX09ydENyZWF0ZVNlc3Npb249ZC5hc20uUmEpLmFwcGx5KG51bGwsYXJndW1lbnRzKX07ZC5fT3J0UmVsZWFzZVNlc3Npb249ZnVuY3Rpb24oKXtyZXR1cm4oZC5fT3J0UmVsZWFzZVNlc3Npb249ZC5hc20uU2EpLmFwcGx5KG51bGwsYXJndW1lbnRzKX07ZC5fT3J0R2V0SW5wdXRDb3VudD1mdW5jdGlvbigpe3JldHVybihkLl9PcnRHZXRJbnB1dENvdW50PWQuYXNtLlRhKS5hcHBseShudWxsLGFyZ3VtZW50cyl9O2QuX09ydEdldE91dHB1dENvdW50PWZ1bmN0aW9uKCl7cmV0dXJuKGQuX09ydEdldE91dHB1dENvdW50PWQuYXNtLlVhKS5hcHBseShudWxsLGFyZ3VtZW50cyl9O1xcclxcbmQuX09ydEdldElucHV0TmFtZT1mdW5jdGlvbigpe3JldHVybihkLl9PcnRHZXRJbnB1dE5hbWU9ZC5hc20uVmEpLmFwcGx5KG51bGwsYXJndW1lbnRzKX07ZC5fT3J0R2V0T3V0cHV0TmFtZT1mdW5jdGlvbigpe3JldHVybihkLl9PcnRHZXRPdXRwdXROYW1lPWQuYXNtLldhKS5hcHBseShudWxsLGFyZ3VtZW50cyl9O2QuX09ydEZyZWU9ZnVuY3Rpb24oKXtyZXR1cm4oZC5fT3J0RnJlZT1kLmFzbS5YYSkuYXBwbHkobnVsbCxhcmd1bWVudHMpfTtkLl9PcnRDcmVhdGVUZW5zb3I9ZnVuY3Rpb24oKXtyZXR1cm4oZC5fT3J0Q3JlYXRlVGVuc29yPWQuYXNtLllhKS5hcHBseShudWxsLGFyZ3VtZW50cyl9O2QuX09ydEdldFRlbnNvckRhdGE9ZnVuY3Rpb24oKXtyZXR1cm4oZC5fT3J0R2V0VGVuc29yRGF0YT1kLmFzbS5aYSkuYXBwbHkobnVsbCxhcmd1bWVudHMpfTtcXHJcXG5kLl9PcnRSZWxlYXNlVGVuc29yPWZ1bmN0aW9uKCl7cmV0dXJuKGQuX09ydFJlbGVhc2VUZW5zb3I9ZC5hc20uX2EpLmFwcGx5KG51bGwsYXJndW1lbnRzKX07ZC5fT3J0Q3JlYXRlUnVuT3B0aW9ucz1mdW5jdGlvbigpe3JldHVybihkLl9PcnRDcmVhdGVSdW5PcHRpb25zPWQuYXNtLiRhKS5hcHBseShudWxsLGFyZ3VtZW50cyl9O2QuX09ydEFkZFJ1bkNvbmZpZ0VudHJ5PWZ1bmN0aW9uKCl7cmV0dXJuKGQuX09ydEFkZFJ1bkNvbmZpZ0VudHJ5PWQuYXNtLmFiKS5hcHBseShudWxsLGFyZ3VtZW50cyl9O2QuX09ydFJlbGVhc2VSdW5PcHRpb25zPWZ1bmN0aW9uKCl7cmV0dXJuKGQuX09ydFJlbGVhc2VSdW5PcHRpb25zPWQuYXNtLmJiKS5hcHBseShudWxsLGFyZ3VtZW50cyl9O2QuX09ydFJ1bj1mdW5jdGlvbigpe3JldHVybihkLl9PcnRSdW49ZC5hc20uY2IpLmFwcGx5KG51bGwsYXJndW1lbnRzKX07XFxyXFxuZC5fT3J0RW5kUHJvZmlsaW5nPWZ1bmN0aW9uKCl7cmV0dXJuKGQuX09ydEVuZFByb2ZpbGluZz1kLmFzbS5kYikuYXBwbHkobnVsbCxhcmd1bWVudHMpfTtcXHJcXG52YXIgSmE9ZC5fbWFsbG9jPWZ1bmN0aW9uKCl7cmV0dXJuKEphPWQuX21hbGxvYz1kLmFzbS5lYikuYXBwbHkobnVsbCxhcmd1bWVudHMpfSxIYT1kLl9mcmVlPWZ1bmN0aW9uKCl7cmV0dXJuKEhhPWQuX2ZyZWU9ZC5hc20uZmIpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sWmE9ZC5fZmZsdXNoPWZ1bmN0aW9uKCl7cmV0dXJuKFphPWQuX2ZmbHVzaD1kLmFzbS5nYikuYXBwbHkobnVsbCxhcmd1bWVudHMpfSxZYT1kLl9fX2Z1bmNzX29uX2V4aXQ9ZnVuY3Rpb24oKXtyZXR1cm4oWWE9ZC5fX19mdW5jc19vbl9leGl0PWQuYXNtLmhiKS5hcHBseShudWxsLGFyZ3VtZW50cyl9LFg9ZC5fc2V0VGhyZXc9ZnVuY3Rpb24oKXtyZXR1cm4oWD1kLl9zZXRUaHJldz1kLmFzbS5qYikuYXBwbHkobnVsbCxhcmd1bWVudHMpfSxZPWQuc3RhY2tTYXZlPWZ1bmN0aW9uKCl7cmV0dXJuKFk9ZC5zdGFja1NhdmU9ZC5hc20ua2IpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sWj1kLnN0YWNrUmVzdG9yZT1cXHJcXG5mdW5jdGlvbigpe3JldHVybihaPWQuc3RhY2tSZXN0b3JlPWQuYXNtLmxiKS5hcHBseShudWxsLGFyZ3VtZW50cyl9LEtiPWQuc3RhY2tBbGxvYz1mdW5jdGlvbigpe3JldHVybihLYj1kLnN0YWNrQWxsb2M9ZC5hc20ubWIpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sWGE9ZC5fX19jeGFfY2FuX2NhdGNoPWZ1bmN0aW9uKCl7cmV0dXJuKFhhPWQuX19fY3hhX2Nhbl9jYXRjaD1kLmFzbS5uYikuYXBwbHkobnVsbCxhcmd1bWVudHMpfSxGYT1kLl9fX2N4YV9pc19wb2ludGVyX3R5cGU9ZnVuY3Rpb24oKXtyZXR1cm4oRmE9ZC5fX19jeGFfaXNfcG9pbnRlcl90eXBlPWQuYXNtLm9iKS5hcHBseShudWxsLGFyZ3VtZW50cyl9LExiPWQuZHluQ2FsbF9qPWZ1bmN0aW9uKCl7cmV0dXJuKExiPWQuZHluQ2FsbF9qPWQuYXNtLnBiKS5hcHBseShudWxsLGFyZ3VtZW50cyl9LE1iPWQuZHluQ2FsbF9paWlpaWo9ZnVuY3Rpb24oKXtyZXR1cm4oTWI9ZC5keW5DYWxsX2lpaWlpaj1kLmFzbS5xYikuYXBwbHkobnVsbCxcXHJcXG5hcmd1bWVudHMpfSxOYj1kLmR5bkNhbGxfamlpPWZ1bmN0aW9uKCl7cmV0dXJuKE5iPWQuZHluQ2FsbF9qaWk9ZC5hc20ucmIpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sT2I9ZC5keW5DYWxsX3ZpaWlpaWo9ZnVuY3Rpb24oKXtyZXR1cm4oT2I9ZC5keW5DYWxsX3ZpaWlpaWo9ZC5hc20uc2IpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sUGI9ZC5keW5DYWxsX3Zqamk9ZnVuY3Rpb24oKXtyZXR1cm4oUGI9ZC5keW5DYWxsX3Zqamk9ZC5hc20udGIpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sUWI9ZC5keW5DYWxsX3ZpaWlqamppaT1mdW5jdGlvbigpe3JldHVybihRYj1kLmR5bkNhbGxfdmlpaWpqamlpPWQuYXNtLnViKS5hcHBseShudWxsLGFyZ3VtZW50cyl9LFJiPWQuZHluQ2FsbF9paWo9ZnVuY3Rpb24oKXtyZXR1cm4oUmI9ZC5keW5DYWxsX2lpaj1kLmFzbS52YikuYXBwbHkobnVsbCxhcmd1bWVudHMpfSxTYj1kLmR5bkNhbGxfamk9ZnVuY3Rpb24oKXtyZXR1cm4oU2I9ZC5keW5DYWxsX2ppPVxcclxcbmQuYXNtLndiKS5hcHBseShudWxsLGFyZ3VtZW50cyl9LFRiPWQuZHluQ2FsbF9paWlpaWlqPWZ1bmN0aW9uKCl7cmV0dXJuKFRiPWQuZHluQ2FsbF9paWlpaWlqPWQuYXNtLnhiKS5hcHBseShudWxsLGFyZ3VtZW50cyl9LFViPWQuZHluQ2FsbF9paWlqPWZ1bmN0aW9uKCl7cmV0dXJuKFViPWQuZHluQ2FsbF9paWlqPWQuYXNtLnliKS5hcHBseShudWxsLGFyZ3VtZW50cyl9O2Z1bmN0aW9uIGNiKGEsYil7dmFyIGM9WSgpO3RyeXtyZXR1cm4gVShhKShiKX1jYXRjaChlKXtaKGMpO2lmKGUhPT1lKzApdGhyb3cgZTtYKDEsMCl9fWZ1bmN0aW9uIHZiKGEsYil7dmFyIGM9WSgpO3RyeXtVKGEpKGIpfWNhdGNoKGUpe1ooYyk7aWYoZSE9PWUrMCl0aHJvdyBlO1goMSwwKX19ZnVuY3Rpb24gd2IoYSxiLGMpe3ZhciBlPVkoKTt0cnl7VShhKShiLGMpfWNhdGNoKGYpe1ooZSk7aWYoZiE9PWYrMCl0aHJvdyBmO1goMSwwKX19XFxyXFxuZnVuY3Rpb24gZmIoYSxiLGMpe3ZhciBlPVkoKTt0cnl7cmV0dXJuIFUoYSkoYixjKX1jYXRjaChmKXtaKGUpO2lmKGYhPT1mKzApdGhyb3cgZjtYKDEsMCl9fWZ1bmN0aW9uIGdiKGEsYixjLGUpe3ZhciBmPVkoKTt0cnl7cmV0dXJuIFUoYSkoYixjLGUpfWNhdGNoKGgpe1ooZik7aWYoaCE9PWgrMCl0aHJvdyBoO1goMSwwKX19ZnVuY3Rpb24ga2IoYSxiLGMsZSxmLGgsayl7dmFyIGw9WSgpO3RyeXtyZXR1cm4gVShhKShiLGMsZSxmLGgsayl9Y2F0Y2gobil7WihsKTtpZihuIT09biswKXRocm93IG47WCgxLDApfX1mdW5jdGlvbiB1YihhKXt2YXIgYj1ZKCk7dHJ5e1UoYSkoKX1jYXRjaChjKXtaKGIpO2lmKGMhPT1jKzApdGhyb3cgYztYKDEsMCl9fWZ1bmN0aW9uIGpiKGEsYixjLGUsZixoKXt2YXIgaz1ZKCk7dHJ5e3JldHVybiBVKGEpKGIsYyxlLGYsaCl9Y2F0Y2gobCl7WihrKTtpZihsIT09bCswKXRocm93IGw7WCgxLDApfX1cXHJcXG5mdW5jdGlvbiBoYihhLGIsYyxlLGYpe3ZhciBoPVkoKTt0cnl7cmV0dXJuIFUoYSkoYixjLGUsZil9Y2F0Y2goayl7WihoKTtpZihrIT09ayswKXRocm93IGs7WCgxLDApfX1mdW5jdGlvbiB5YihhLGIsYyxlKXt2YXIgZj1ZKCk7dHJ5e1UoYSkoYixjLGUpfWNhdGNoKGgpe1ooZik7aWYoaCE9PWgrMCl0aHJvdyBoO1goMSwwKX19ZnVuY3Rpb24gQWIoYSxiLGMsZSxmLGgpe3ZhciBrPVkoKTt0cnl7VShhKShiLGMsZSxmLGgpfWNhdGNoKGwpe1ooayk7aWYobCE9PWwrMCl0aHJvdyBsO1goMSwwKX19ZnVuY3Rpb24gemIoYSxiLGMsZSxmKXt2YXIgaD1ZKCk7dHJ5e1UoYSkoYixjLGUsZil9Y2F0Y2goayl7WihoKTtpZihrIT09ayswKXRocm93IGs7WCgxLDApfX1mdW5jdGlvbiBCYihhLGIsYyxlLGYsaCxrKXt2YXIgbD1ZKCk7dHJ5e1UoYSkoYixjLGUsZixoLGspfWNhdGNoKG4pe1oobCk7aWYobiE9PW4rMCl0aHJvdyBuO1goMSwwKX19XFxyXFxuZnVuY3Rpb24gQ2IoYSxiLGMsZSxmLGgsayxsKXt2YXIgbj1ZKCk7dHJ5e1UoYSkoYixjLGUsZixoLGssbCl9Y2F0Y2godCl7WihuKTtpZih0IT09dCswKXRocm93IHQ7WCgxLDApfX1mdW5jdGlvbiBlYihhLGIsYyl7dmFyIGU9WSgpO3RyeXtyZXR1cm4gVShhKShiLGMpfWNhdGNoKGYpe1ooZSk7aWYoZiE9PWYrMCl0aHJvdyBmO1goMSwwKX19ZnVuY3Rpb24gZGIoYSxiLGMpe3ZhciBlPVkoKTt0cnl7cmV0dXJuIFUoYSkoYixjKX1jYXRjaChmKXtaKGUpO2lmKGYhPT1mKzApdGhyb3cgZjtYKDEsMCl9fWZ1bmN0aW9uIERiKGEsYixjLGUsZixoLGssbCxuKXt2YXIgdD1ZKCk7dHJ5e1UoYSkoYixjLGUsZixoLGssbCxuKX1jYXRjaCh4KXtaKHQpO2lmKHghPT14KzApdGhyb3cgeDtYKDEsMCl9fWZ1bmN0aW9uIGliKGEsYixjLGUsZixoKXt2YXIgaz1ZKCk7dHJ5e3JldHVybiBVKGEpKGIsYyxlLGYsaCl9Y2F0Y2gobCl7WihrKTtpZihsIT09bCswKXRocm93IGw7WCgxLDApfX1cXHJcXG5mdW5jdGlvbiBsYihhLGIsYyxlLGYsaCxrLGwpe3ZhciBuPVkoKTt0cnl7cmV0dXJuIFUoYSkoYixjLGUsZixoLGssbCl9Y2F0Y2godCl7WihuKTtpZih0IT09dCswKXRocm93IHQ7WCgxLDApfX1mdW5jdGlvbiBtYihhLGIsYyxlLGYsaCxrLGwsbix0LHgsRSl7dmFyIEM9WSgpO3RyeXtyZXR1cm4gVShhKShiLGMsZSxmLGgsayxsLG4sdCx4LEUpfWNhdGNoKGcpe1ooQyk7aWYoZyE9PWcrMCl0aHJvdyBnO1goMSwwKX19ZnVuY3Rpb24gRWIoYSxiLGMsZSxmLGgsayxsLG4sdCx4KXt2YXIgRT1ZKCk7dHJ5e1UoYSkoYixjLGUsZixoLGssbCxuLHQseCl9Y2F0Y2goQyl7WihFKTtpZihDIT09QyswKXRocm93IEM7WCgxLDApfX1mdW5jdGlvbiBGYihhLGIsYyxlLGYsaCxrLGwsbix0LHgsRSxDLGcsdSx3KXt2YXIgRj1ZKCk7dHJ5e1UoYSkoYixjLGUsZixoLGssbCxuLHQseCxFLEMsZyx1LHcpfWNhdGNoKE0pe1ooRik7aWYoTSE9PU0rMCl0aHJvdyBNO1goMSwwKX19XFxyXFxuZnVuY3Rpb24gYmIoYSl7dmFyIGI9WSgpO3RyeXtyZXR1cm4gVShhKSgpfWNhdGNoKGMpe1ooYik7aWYoYyE9PWMrMCl0aHJvdyBjO1goMSwwKX19ZnVuY3Rpb24gYWIoYSxiLGMpe3ZhciBlPVkoKTt0cnl7cmV0dXJuIFUoYSkoYixjKX1jYXRjaChmKXtaKGUpO2lmKGYhPT1mKzApdGhyb3cgZjtYKDEsMCl9fWZ1bmN0aW9uICRhKGEsYixjKXt2YXIgZT1ZKCk7dHJ5e3JldHVybiBVKGEpKGIsYyl9Y2F0Y2goZil7WihlKTtpZihmIT09ZiswKXRocm93IGY7WCgxLDApfX1mdW5jdGlvbiB4YihhLGIsYyxlKXt2YXIgZj1ZKCk7dHJ5e1UoYSkoYixjLGUpfWNhdGNoKGgpe1ooZik7aWYoaCE9PWgrMCl0aHJvdyBoO1goMSwwKX19ZnVuY3Rpb24gR2IoYSxiLGMsZSxmLGgsayxsKXt2YXIgbj1ZKCk7dHJ5e09iKGEsYixjLGUsZixoLGssbCl9Y2F0Y2godCl7WihuKTtpZih0IT09dCswKXRocm93IHQ7WCgxLDApfX1cXHJcXG5mdW5jdGlvbiBJYihhLGIsYyxlLGYsaCl7dmFyIGs9WSgpO3RyeXtQYihhLGIsYyxlLGYsaCl9Y2F0Y2gobCl7WihrKTtpZihsIT09bCswKXRocm93IGw7WCgxLDApfX1mdW5jdGlvbiBIYihhLGIsYyxlLGYsaCxrLGwsbix0LHgsRSl7dmFyIEM9WSgpO3RyeXtRYihhLGIsYyxlLGYsaCxrLGwsbix0LHgsRSl9Y2F0Y2goZyl7WihDKTtpZihnIT09ZyswKXRocm93IGc7WCgxLDApfX1mdW5jdGlvbiBxYihhLGIsYyxlKXt2YXIgZj1ZKCk7dHJ5e3JldHVybiBSYihhLGIsYyxlKX1jYXRjaChoKXtaKGYpO2lmKGghPT1oKzApdGhyb3cgaDtYKDEsMCl9fWZ1bmN0aW9uIHNiKGEsYil7dmFyIGM9WSgpO3RyeXtyZXR1cm4gU2IoYSxiKX1jYXRjaChlKXtaKGMpO2lmKGUhPT1lKzApdGhyb3cgZTtYKDEsMCl9fVxcclxcbmZ1bmN0aW9uIG5iKGEsYixjLGUsZixoLGssbCl7dmFyIG49WSgpO3RyeXtyZXR1cm4gVGIoYSxiLGMsZSxmLGgsayxsKX1jYXRjaCh0KXtaKG4pO2lmKHQhPT10KzApdGhyb3cgdDtYKDEsMCl9fWZ1bmN0aW9uIHJiKGEpe3ZhciBiPVkoKTt0cnl7cmV0dXJuIExiKGEpfWNhdGNoKGMpe1ooYik7aWYoYyE9PWMrMCl0aHJvdyBjO1goMSwwKX19ZnVuY3Rpb24gb2IoYSxiLGMsZSxmLGgsayl7dmFyIGw9WSgpO3RyeXtyZXR1cm4gTWIoYSxiLGMsZSxmLGgsayl9Y2F0Y2gobil7WihsKTtpZihuIT09biswKXRocm93IG47WCgxLDApfX1mdW5jdGlvbiBwYihhLGIsYyxlLGYpe3ZhciBoPVkoKTt0cnl7cmV0dXJuIFViKGEsYixjLGUsZil9Y2F0Y2goayl7WihoKTtpZihrIT09ayswKXRocm93IGs7WCgxLDApfX1mdW5jdGlvbiB0YihhLGIsYyl7dmFyIGU9WSgpO3RyeXtyZXR1cm4gTmIoYSxiLGMpfWNhdGNoKGYpe1ooZSk7aWYoZiE9PWYrMCl0aHJvdyBmO1goMSwwKX19XFxyXFxuZC5VVEY4VG9TdHJpbmc9cGE7ZC5zdHJpbmdUb1VURjg9ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBxYShhLEcsYixjKX07ZC5sZW5ndGhCeXRlc1VURjg9cmE7ZC5zdGFja1NhdmU9WTtkLnN0YWNrUmVzdG9yZT1aO2Quc3RhY2tBbGxvYz1LYjt2YXIgVmI7TD1mdW5jdGlvbiBXYigpe1ZifHxYYigpO1ZifHwoTD1XYil9O1xcclxcbmZ1bmN0aW9uIFhiKCl7ZnVuY3Rpb24gYSgpe2lmKCFWYiYmKFZiPSEwLGQuY2FsbGVkUnVuPSEwLCFEKSl7Tyh3YSk7YWEoZCk7aWYoZC5vblJ1bnRpbWVJbml0aWFsaXplZClkLm9uUnVudGltZUluaXRpYWxpemVkKCk7aWYoZC5wb3N0UnVuKWZvcihcXFwiZnVuY3Rpb25cXFwiPT10eXBlb2YgZC5wb3N0UnVuJiYoZC5wb3N0UnVuPVtkLnBvc3RSdW5dKTtkLnBvc3RSdW4ubGVuZ3RoOyl7dmFyIGI9ZC5wb3N0UnVuLnNoaWZ0KCk7eWEudW5zaGlmdChiKX1PKHlhKX19aWYoISgwPEspKXtpZihkLnByZVJ1bilmb3IoXFxcImZ1bmN0aW9uXFxcIj09dHlwZW9mIGQucHJlUnVuJiYoZC5wcmVSdW49W2QucHJlUnVuXSk7ZC5wcmVSdW4ubGVuZ3RoOyl6YSgpO08odmEpOzA8S3x8KGQuc2V0U3RhdHVzPyhkLnNldFN0YXR1cyhcXFwiUnVubmluZy4uLlxcXCIpLHNldFRpbWVvdXQoZnVuY3Rpb24oKXtzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7ZC5zZXRTdGF0dXMoXFxcIlxcXCIpfSwxKTthKCl9LDEpKTphKCkpfX1cXHJcXG5pZihkLnByZUluaXQpZm9yKFxcXCJmdW5jdGlvblxcXCI9PXR5cGVvZiBkLnByZUluaXQmJihkLnByZUluaXQ9W2QucHJlSW5pdF0pOzA8ZC5wcmVJbml0Lmxlbmd0aDspZC5wcmVJbml0LnBvcCgpKCk7WGIoKTtcXHJcXG5cXHJcXG5cXHJcXG4gIHJldHVybiBvcnRXYXNtLnJlYWR5XFxyXFxufVxcclxcbik7XFxyXFxufSkoKTtcXHJcXG5pZiAodHJ1ZSlcXHJcXG4gIG1vZHVsZS5leHBvcnRzID0gb3J0V2FzbTtcXHJcXG5lbHNlIHt9XFxyXFxuXFxuXFxuLyoqKi8gfSksXFxuXFxuLyoqKi8gXFxcIi4vbGliL3dhc20vb3B0aW9ucy11dGlscy50c1xcXCI6XFxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXFxcXG4gICEqKiogLi9saWIvd2FzbS9vcHRpb25zLXV0aWxzLnRzICoqKiFcXG4gIFxcXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cXG4vKioqLyAoKF9fdW51c2VkX3dlYnBhY2tfbW9kdWxlLCBleHBvcnRzKSA9PiB7XFxuXFxuXFxcInVzZSBzdHJpY3RcXFwiO1xcblxcbi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXFxcIl9fZXNNb2R1bGVcXFwiLCAoeyB2YWx1ZTogdHJ1ZSB9KSk7XFxuZXhwb3J0cy5pdGVyYXRlRXh0cmFPcHRpb25zID0gdm9pZCAwO1xcbmNvbnN0IGl0ZXJhdGVFeHRyYU9wdGlvbnMgPSAob3B0aW9ucywgcHJlZml4LCBzZWVuLCBoYW5kbGVyKSA9PiB7XFxuICAgIGlmICh0eXBlb2Ygb3B0aW9ucyA9PSAnb2JqZWN0JyAmJiBvcHRpb25zICE9PSBudWxsKSB7XFxuICAgICAgICBpZiAoc2Vlbi5oYXMob3B0aW9ucykpIHtcXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NpcmN1bGFyIHJlZmVyZW5jZSBpbiBvcHRpb25zJyk7XFxuICAgICAgICB9XFxuICAgICAgICBlbHNlIHtcXG4gICAgICAgICAgICBzZWVuLmFkZChvcHRpb25zKTtcXG4gICAgICAgIH1cXG4gICAgfVxcbiAgICBPYmplY3QuZW50cmllcyhvcHRpb25zKS5mb3JFYWNoKChba2V5LCB2YWx1ZV0pID0+IHtcXG4gICAgICAgIGNvbnN0IG5hbWUgPSAocHJlZml4KSA/IHByZWZpeCArIGtleSA6IGtleTtcXG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnKSB7XFxuICAgICAgICAgICAgKDAsIGV4cG9ydHMuaXRlcmF0ZUV4dHJhT3B0aW9ucykodmFsdWUsIG5hbWUgKyAnLicsIHNlZW4sIGhhbmRsZXIpO1xcbiAgICAgICAgfVxcbiAgICAgICAgZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyB8fCB0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKSB7XFxuICAgICAgICAgICAgaGFuZGxlcihuYW1lLCB2YWx1ZS50b1N0cmluZygpKTtcXG4gICAgICAgIH1cXG4gICAgICAgIGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Jvb2xlYW4nKSB7XFxuICAgICAgICAgICAgaGFuZGxlcihuYW1lLCAodmFsdWUpID8gJzEnIDogJzAnKTtcXG4gICAgICAgIH1cXG4gICAgICAgIGVsc2Uge1xcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2FuJ3QgaGFuZGxlIGV4dHJhIGNvbmZpZyB0eXBlOiAke3R5cGVvZiB2YWx1ZX1gKTtcXG4gICAgICAgIH1cXG4gICAgfSk7XFxufTtcXG5leHBvcnRzLml0ZXJhdGVFeHRyYU9wdGlvbnMgPSBpdGVyYXRlRXh0cmFPcHRpb25zO1xcblxcblxcbi8qKiovIH0pLFxcblxcbi8qKiovIFxcXCIuL2xpYi93YXNtL3J1bi1vcHRpb25zLnRzXFxcIjpcXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXFxcXG4gICEqKiogLi9saWIvd2FzbS9ydW4tb3B0aW9ucy50cyAqKiohXFxuICBcXFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xcbi8qKiovICgoX191bnVzZWRfd2VicGFja19tb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pID0+IHtcXG5cXG5cXFwidXNlIHN0cmljdFxcXCI7XFxuXFxuLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXFxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcXFwiX19lc01vZHVsZVxcXCIsICh7IHZhbHVlOiB0cnVlIH0pKTtcXG5leHBvcnRzLnNldFJ1bk9wdGlvbnMgPSB2b2lkIDA7XFxuY29uc3Qgb3B0aW9uc191dGlsc18xID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi9vcHRpb25zLXV0aWxzICovIFxcXCIuL2xpYi93YXNtL29wdGlvbnMtdXRpbHMudHNcXFwiKTtcXG5jb25zdCBzdHJpbmdfdXRpbHNfMSA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vc3RyaW5nLXV0aWxzICovIFxcXCIuL2xpYi93YXNtL3N0cmluZy11dGlscy50c1xcXCIpO1xcbmNvbnN0IHdhc21fZmFjdG9yeV8xID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi93YXNtLWZhY3RvcnkgKi8gXFxcIi4vbGliL3dhc20vd2FzbS1mYWN0b3J5LnRzXFxcIik7XFxuY29uc3Qgc2V0UnVuT3B0aW9ucyA9IChvcHRpb25zKSA9PiB7XFxuICAgIGNvbnN0IHdhc20gPSAoMCwgd2FzbV9mYWN0b3J5XzEuZ2V0SW5zdGFuY2UpKCk7XFxuICAgIGxldCBydW5PcHRpb25zSGFuZGxlID0gMDtcXG4gICAgY29uc3QgYWxsb2NzID0gW107XFxuICAgIGNvbnN0IHJ1bk9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xcbiAgICB0cnkge1xcbiAgICAgICAgaWYgKChvcHRpb25zID09PSBudWxsIHx8IG9wdGlvbnMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9wdGlvbnMubG9nU2V2ZXJpdHlMZXZlbCkgPT09IHVuZGVmaW5lZCkge1xcbiAgICAgICAgICAgIHJ1bk9wdGlvbnMubG9nU2V2ZXJpdHlMZXZlbCA9IDI7IC8vIERlZmF1bHQgdG8gd2FybmluZ1xcbiAgICAgICAgfVxcbiAgICAgICAgZWxzZSBpZiAodHlwZW9mIG9wdGlvbnMubG9nU2V2ZXJpdHlMZXZlbCAhPT0gJ251bWJlcicgfHwgIU51bWJlci5pc0ludGVnZXIob3B0aW9ucy5sb2dTZXZlcml0eUxldmVsKSB8fFxcbiAgICAgICAgICAgIG9wdGlvbnMubG9nU2V2ZXJpdHlMZXZlbCA8IDAgfHwgb3B0aW9ucy5sb2dTZXZlcml0eUxldmVsID4gNCkge1xcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgbG9nIHNlcnZlcml0eSBsZXZlbCBpcyBub3QgdmFsaWQ6ICR7b3B0aW9ucy5sb2dTZXZlcml0eUxldmVsfWApO1xcbiAgICAgICAgfVxcbiAgICAgICAgaWYgKChvcHRpb25zID09PSBudWxsIHx8IG9wdGlvbnMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9wdGlvbnMubG9nVmVyYm9zaXR5TGV2ZWwpID09PSB1bmRlZmluZWQpIHtcXG4gICAgICAgICAgICBydW5PcHRpb25zLmxvZ1ZlcmJvc2l0eUxldmVsID0gMDsgLy8gRGVmYXVsdCB0byAwXFxuICAgICAgICB9XFxuICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb3B0aW9ucy5sb2dWZXJib3NpdHlMZXZlbCAhPT0gJ251bWJlcicgfHwgIU51bWJlci5pc0ludGVnZXIob3B0aW9ucy5sb2dWZXJib3NpdHlMZXZlbCkpIHtcXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGxvZyB2ZXJib3NpdHkgbGV2ZWwgaXMgbm90IHZhbGlkOiAke29wdGlvbnMubG9nVmVyYm9zaXR5TGV2ZWx9YCk7XFxuICAgICAgICB9XFxuICAgICAgICBpZiAoKG9wdGlvbnMgPT09IG51bGwgfHwgb3B0aW9ucyA9PT0gdm9pZCAwID8gdm9pZCAwIDogb3B0aW9ucy50ZXJtaW5hdGUpID09PSB1bmRlZmluZWQpIHtcXG4gICAgICAgICAgICBydW5PcHRpb25zLnRlcm1pbmF0ZSA9IGZhbHNlO1xcbiAgICAgICAgfVxcbiAgICAgICAgbGV0IHRhZ0RhdGFPZmZzZXQgPSAwO1xcbiAgICAgICAgaWYgKChvcHRpb25zID09PSBudWxsIHx8IG9wdGlvbnMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9wdGlvbnMudGFnKSAhPT0gdW5kZWZpbmVkKSB7XFxuICAgICAgICAgICAgdGFnRGF0YU9mZnNldCA9ICgwLCBzdHJpbmdfdXRpbHNfMS5hbGxvY1dhc21TdHJpbmcpKG9wdGlvbnMudGFnLCBhbGxvY3MpO1xcbiAgICAgICAgfVxcbiAgICAgICAgcnVuT3B0aW9uc0hhbmRsZSA9IHdhc20uX09ydENyZWF0ZVJ1bk9wdGlvbnMocnVuT3B0aW9ucy5sb2dTZXZlcml0eUxldmVsLCBydW5PcHRpb25zLmxvZ1ZlcmJvc2l0eUxldmVsLCAhIXJ1bk9wdGlvbnMudGVybWluYXRlLCB0YWdEYXRhT2Zmc2V0KTtcXG4gICAgICAgIGlmIChydW5PcHRpb25zSGFuZGxlID09PSAwKSB7XFxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW5cXFxcJ3QgY3JlYXRlIHJ1biBvcHRpb25zJyk7XFxuICAgICAgICB9XFxuICAgICAgICBpZiAoKG9wdGlvbnMgPT09IG51bGwgfHwgb3B0aW9ucyA9PT0gdm9pZCAwID8gdm9pZCAwIDogb3B0aW9ucy5leHRyYSkgIT09IHVuZGVmaW5lZCkge1xcbiAgICAgICAgICAgICgwLCBvcHRpb25zX3V0aWxzXzEuaXRlcmF0ZUV4dHJhT3B0aW9ucykob3B0aW9ucy5leHRyYSwgJycsIG5ldyBXZWFrU2V0KCksIChrZXksIHZhbHVlKSA9PiB7XFxuICAgICAgICAgICAgICAgIGNvbnN0IGtleURhdGFPZmZzZXQgPSAoMCwgc3RyaW5nX3V0aWxzXzEuYWxsb2NXYXNtU3RyaW5nKShrZXksIGFsbG9jcyk7XFxuICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlRGF0YU9mZnNldCA9ICgwLCBzdHJpbmdfdXRpbHNfMS5hbGxvY1dhc21TdHJpbmcpKHZhbHVlLCBhbGxvY3MpO1xcbiAgICAgICAgICAgICAgICBpZiAod2FzbS5fT3J0QWRkUnVuQ29uZmlnRW50cnkocnVuT3B0aW9uc0hhbmRsZSwga2V5RGF0YU9mZnNldCwgdmFsdWVEYXRhT2Zmc2V0KSAhPT0gMCkge1xcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW4ndCBzZXQgYSBydW4gY29uZmlnIGVudHJ5OiAke2tleX0gLSAke3ZhbHVlfWApO1xcbiAgICAgICAgICAgICAgICB9XFxuICAgICAgICAgICAgfSk7XFxuICAgICAgICB9XFxuICAgICAgICByZXR1cm4gW3J1bk9wdGlvbnNIYW5kbGUsIGFsbG9jc107XFxuICAgIH1cXG4gICAgY2F0Y2ggKGUpIHtcXG4gICAgICAgIGlmIChydW5PcHRpb25zSGFuZGxlICE9PSAwKSB7XFxuICAgICAgICAgICAgd2FzbS5fT3J0UmVsZWFzZVJ1bk9wdGlvbnMocnVuT3B0aW9uc0hhbmRsZSk7XFxuICAgICAgICB9XFxuICAgICAgICBhbGxvY3MuZm9yRWFjaCh3YXNtLl9mcmVlKTtcXG4gICAgICAgIHRocm93IGU7XFxuICAgIH1cXG59O1xcbmV4cG9ydHMuc2V0UnVuT3B0aW9ucyA9IHNldFJ1bk9wdGlvbnM7XFxuXFxuXFxuLyoqKi8gfSksXFxuXFxuLyoqKi8gXFxcIi4vbGliL3dhc20vc2Vzc2lvbi1vcHRpb25zLnRzXFxcIjpcXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxcXFxuICAhKioqIC4vbGliL3dhc20vc2Vzc2lvbi1vcHRpb25zLnRzICoqKiFcXG4gIFxcXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xcbi8qKiovICgoX191bnVzZWRfd2VicGFja19tb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pID0+IHtcXG5cXG5cXFwidXNlIHN0cmljdFxcXCI7XFxuXFxuLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXFxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcXFwiX19lc01vZHVsZVxcXCIsICh7IHZhbHVlOiB0cnVlIH0pKTtcXG5leHBvcnRzLnNldFNlc3Npb25PcHRpb25zID0gdm9pZCAwO1xcbmNvbnN0IG9wdGlvbnNfdXRpbHNfMSA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vb3B0aW9ucy11dGlscyAqLyBcXFwiLi9saWIvd2FzbS9vcHRpb25zLXV0aWxzLnRzXFxcIik7XFxuY29uc3Qgc3RyaW5nX3V0aWxzXzEgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL3N0cmluZy11dGlscyAqLyBcXFwiLi9saWIvd2FzbS9zdHJpbmctdXRpbHMudHNcXFwiKTtcXG5jb25zdCB3YXNtX2ZhY3RvcnlfMSA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vd2FzbS1mYWN0b3J5ICovIFxcXCIuL2xpYi93YXNtL3dhc20tZmFjdG9yeS50c1xcXCIpO1xcbmNvbnN0IGdldEdyYXBoT3B0aW16YXRpb25MZXZlbCA9IChncmFwaE9wdGltaXphdGlvbkxldmVsKSA9PiB7XFxuICAgIHN3aXRjaCAoZ3JhcGhPcHRpbWl6YXRpb25MZXZlbCkge1xcbiAgICAgICAgY2FzZSAnZGlzYWJsZWQnOlxcbiAgICAgICAgICAgIHJldHVybiAwO1xcbiAgICAgICAgY2FzZSAnYmFzaWMnOlxcbiAgICAgICAgICAgIHJldHVybiAxO1xcbiAgICAgICAgY2FzZSAnZXh0ZW5kZWQnOlxcbiAgICAgICAgICAgIHJldHVybiAyO1xcbiAgICAgICAgY2FzZSAnYWxsJzpcXG4gICAgICAgICAgICByZXR1cm4gOTk7XFxuICAgICAgICBkZWZhdWx0OlxcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgdW5zdXBwb3J0ZWQgZ3JhcGggb3B0aW1pemF0aW9uIGxldmVsOiAke2dyYXBoT3B0aW1pemF0aW9uTGV2ZWx9YCk7XFxuICAgIH1cXG59O1xcbmNvbnN0IGdldEV4ZWN1dGlvbk1vZGUgPSAoZXhlY3V0aW9uTW9kZSkgPT4ge1xcbiAgICBzd2l0Y2ggKGV4ZWN1dGlvbk1vZGUpIHtcXG4gICAgICAgIGNhc2UgJ3NlcXVlbnRpYWwnOlxcbiAgICAgICAgICAgIHJldHVybiAwO1xcbiAgICAgICAgY2FzZSAncGFyYWxsZWwnOlxcbiAgICAgICAgICAgIHJldHVybiAxO1xcbiAgICAgICAgZGVmYXVsdDpcXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuc3VwcG9ydGVkIGV4ZWN1dGlvbiBtb2RlOiAke2V4ZWN1dGlvbk1vZGV9YCk7XFxuICAgIH1cXG59O1xcbmNvbnN0IGFwcGVuZERlZmF1bHRPcHRpb25zID0gKG9wdGlvbnMpID0+IHtcXG4gICAgaWYgKCFvcHRpb25zLmV4dHJhKSB7XFxuICAgICAgICBvcHRpb25zLmV4dHJhID0ge307XFxuICAgIH1cXG4gICAgaWYgKCFvcHRpb25zLmV4dHJhLnNlc3Npb24pIHtcXG4gICAgICAgIG9wdGlvbnMuZXh0cmEuc2Vzc2lvbiA9IHt9O1xcbiAgICB9XFxuICAgIGNvbnN0IHNlc3Npb24gPSBvcHRpb25zLmV4dHJhLnNlc3Npb247XFxuICAgIGlmICghc2Vzc2lvbi51c2Vfb3J0X21vZGVsX2J5dGVzX2RpcmVjdGx5KSB7XFxuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY2FtZWxjYXNlXFxuICAgICAgICBzZXNzaW9uLnVzZV9vcnRfbW9kZWxfYnl0ZXNfZGlyZWN0bHkgPSAnMSc7XFxuICAgIH1cXG59O1xcbmNvbnN0IHNldEV4ZWN1dGlvblByb3ZpZGVycyA9IChzZXNzaW9uT3B0aW9uc0hhbmRsZSwgZXhlY3V0aW9uUHJvdmlkZXJzLCBhbGxvY3MpID0+IHtcXG4gICAgZm9yIChjb25zdCBlcCBvZiBleGVjdXRpb25Qcm92aWRlcnMpIHtcXG4gICAgICAgIGxldCBlcE5hbWUgPSB0eXBlb2YgZXAgPT09ICdzdHJpbmcnID8gZXAgOiBlcC5uYW1lO1xcbiAgICAgICAgLy8gY2hlY2sgRVAgbmFtZVxcbiAgICAgICAgc3dpdGNoIChlcE5hbWUpIHtcXG4gICAgICAgICAgICBjYXNlICd4bm5wYWNrJzpcXG4gICAgICAgICAgICAgICAgZXBOYW1lID0gJ1hOTlBBQ0snO1xcbiAgICAgICAgICAgICAgICBicmVhaztcXG4gICAgICAgICAgICBjYXNlICd3YXNtJzpcXG4gICAgICAgICAgICBjYXNlICdjcHUnOlxcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcXG4gICAgICAgICAgICBkZWZhdWx0OlxcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYG5vdCBzdXBwb3J0ZWQgRVA6ICR7ZXBOYW1lfWApO1xcbiAgICAgICAgfVxcbiAgICAgICAgY29uc3QgZXBOYW1lRGF0YU9mZnNldCA9ICgwLCBzdHJpbmdfdXRpbHNfMS5hbGxvY1dhc21TdHJpbmcpKGVwTmFtZSwgYWxsb2NzKTtcXG4gICAgICAgIGlmICgoMCwgd2FzbV9mYWN0b3J5XzEuZ2V0SW5zdGFuY2UpKCkuX09ydEFwcGVuZEV4ZWN1dGlvblByb3ZpZGVyKHNlc3Npb25PcHRpb25zSGFuZGxlLCBlcE5hbWVEYXRhT2Zmc2V0KSAhPT0gMCkge1xcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2FuJ3QgYXBwZW5kIGV4ZWN1dGlvbiBwcm92aWRlcjogJHtlcE5hbWV9YCk7XFxuICAgICAgICB9XFxuICAgIH1cXG59O1xcbmNvbnN0IHNldFNlc3Npb25PcHRpb25zID0gKG9wdGlvbnMpID0+IHtcXG4gICAgY29uc3Qgd2FzbSA9ICgwLCB3YXNtX2ZhY3RvcnlfMS5nZXRJbnN0YW5jZSkoKTtcXG4gICAgbGV0IHNlc3Npb25PcHRpb25zSGFuZGxlID0gMDtcXG4gICAgY29uc3QgYWxsb2NzID0gW107XFxuICAgIGNvbnN0IHNlc3Npb25PcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcXG4gICAgYXBwZW5kRGVmYXVsdE9wdGlvbnMoc2Vzc2lvbk9wdGlvbnMpO1xcbiAgICB0cnkge1xcbiAgICAgICAgaWYgKChvcHRpb25zID09PSBudWxsIHx8IG9wdGlvbnMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9wdGlvbnMuZ3JhcGhPcHRpbWl6YXRpb25MZXZlbCkgPT09IHVuZGVmaW5lZCkge1xcbiAgICAgICAgICAgIHNlc3Npb25PcHRpb25zLmdyYXBoT3B0aW1pemF0aW9uTGV2ZWwgPSAnYWxsJztcXG4gICAgICAgIH1cXG4gICAgICAgIGNvbnN0IGdyYXBoT3B0aW1pemF0aW9uTGV2ZWwgPSBnZXRHcmFwaE9wdGltemF0aW9uTGV2ZWwoc2Vzc2lvbk9wdGlvbnMuZ3JhcGhPcHRpbWl6YXRpb25MZXZlbCk7XFxuICAgICAgICBpZiAoKG9wdGlvbnMgPT09IG51bGwgfHwgb3B0aW9ucyA9PT0gdm9pZCAwID8gdm9pZCAwIDogb3B0aW9ucy5lbmFibGVDcHVNZW1BcmVuYSkgPT09IHVuZGVmaW5lZCkge1xcbiAgICAgICAgICAgIHNlc3Npb25PcHRpb25zLmVuYWJsZUNwdU1lbUFyZW5hID0gdHJ1ZTtcXG4gICAgICAgIH1cXG4gICAgICAgIGlmICgob3B0aW9ucyA9PT0gbnVsbCB8fCBvcHRpb25zID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcHRpb25zLmVuYWJsZU1lbVBhdHRlcm4pID09PSB1bmRlZmluZWQpIHtcXG4gICAgICAgICAgICBzZXNzaW9uT3B0aW9ucy5lbmFibGVNZW1QYXR0ZXJuID0gdHJ1ZTtcXG4gICAgICAgIH1cXG4gICAgICAgIGlmICgob3B0aW9ucyA9PT0gbnVsbCB8fCBvcHRpb25zID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcHRpb25zLmV4ZWN1dGlvbk1vZGUpID09PSB1bmRlZmluZWQpIHtcXG4gICAgICAgICAgICBzZXNzaW9uT3B0aW9ucy5leGVjdXRpb25Nb2RlID0gJ3NlcXVlbnRpYWwnO1xcbiAgICAgICAgfVxcbiAgICAgICAgY29uc3QgZXhlY3V0aW9uTW9kZSA9IGdldEV4ZWN1dGlvbk1vZGUoc2Vzc2lvbk9wdGlvbnMuZXhlY3V0aW9uTW9kZSk7XFxuICAgICAgICBsZXQgbG9nSWREYXRhT2Zmc2V0ID0gMDtcXG4gICAgICAgIGlmICgob3B0aW9ucyA9PT0gbnVsbCB8fCBvcHRpb25zID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcHRpb25zLmxvZ0lkKSAhPT0gdW5kZWZpbmVkKSB7XFxuICAgICAgICAgICAgbG9nSWREYXRhT2Zmc2V0ID0gKDAsIHN0cmluZ191dGlsc18xLmFsbG9jV2FzbVN0cmluZykob3B0aW9ucy5sb2dJZCwgYWxsb2NzKTtcXG4gICAgICAgIH1cXG4gICAgICAgIGlmICgob3B0aW9ucyA9PT0gbnVsbCB8fCBvcHRpb25zID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcHRpb25zLmxvZ1NldmVyaXR5TGV2ZWwpID09PSB1bmRlZmluZWQpIHtcXG4gICAgICAgICAgICBzZXNzaW9uT3B0aW9ucy5sb2dTZXZlcml0eUxldmVsID0gMjsgLy8gRGVmYXVsdCB0byB3YXJuaW5nXFxuICAgICAgICB9XFxuICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb3B0aW9ucy5sb2dTZXZlcml0eUxldmVsICE9PSAnbnVtYmVyJyB8fCAhTnVtYmVyLmlzSW50ZWdlcihvcHRpb25zLmxvZ1NldmVyaXR5TGV2ZWwpIHx8XFxuICAgICAgICAgICAgb3B0aW9ucy5sb2dTZXZlcml0eUxldmVsIDwgMCB8fCBvcHRpb25zLmxvZ1NldmVyaXR5TGV2ZWwgPiA0KSB7XFxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBsb2cgc2VydmVyaXR5IGxldmVsIGlzIG5vdCB2YWxpZDogJHtvcHRpb25zLmxvZ1NldmVyaXR5TGV2ZWx9YCk7XFxuICAgICAgICB9XFxuICAgICAgICBpZiAoKG9wdGlvbnMgPT09IG51bGwgfHwgb3B0aW9ucyA9PT0gdm9pZCAwID8gdm9pZCAwIDogb3B0aW9ucy5sb2dWZXJib3NpdHlMZXZlbCkgPT09IHVuZGVmaW5lZCkge1xcbiAgICAgICAgICAgIHNlc3Npb25PcHRpb25zLmxvZ1ZlcmJvc2l0eUxldmVsID0gMDsgLy8gRGVmYXVsdCB0byAwXFxuICAgICAgICB9XFxuICAgICAgICBlbHNlIGlmICh0eXBlb2Ygb3B0aW9ucy5sb2dWZXJib3NpdHlMZXZlbCAhPT0gJ251bWJlcicgfHwgIU51bWJlci5pc0ludGVnZXIob3B0aW9ucy5sb2dWZXJib3NpdHlMZXZlbCkpIHtcXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGxvZyB2ZXJib3NpdHkgbGV2ZWwgaXMgbm90IHZhbGlkOiAke29wdGlvbnMubG9nVmVyYm9zaXR5TGV2ZWx9YCk7XFxuICAgICAgICB9XFxuICAgICAgICBpZiAoKG9wdGlvbnMgPT09IG51bGwgfHwgb3B0aW9ucyA9PT0gdm9pZCAwID8gdm9pZCAwIDogb3B0aW9ucy5lbmFibGVQcm9maWxpbmcpID09PSB1bmRlZmluZWQpIHtcXG4gICAgICAgICAgICBzZXNzaW9uT3B0aW9ucy5lbmFibGVQcm9maWxpbmcgPSBmYWxzZTtcXG4gICAgICAgIH1cXG4gICAgICAgIHNlc3Npb25PcHRpb25zSGFuZGxlID0gd2FzbS5fT3J0Q3JlYXRlU2Vzc2lvbk9wdGlvbnMoZ3JhcGhPcHRpbWl6YXRpb25MZXZlbCwgISFzZXNzaW9uT3B0aW9ucy5lbmFibGVDcHVNZW1BcmVuYSwgISFzZXNzaW9uT3B0aW9ucy5lbmFibGVNZW1QYXR0ZXJuLCBleGVjdXRpb25Nb2RlLCAhIXNlc3Npb25PcHRpb25zLmVuYWJsZVByb2ZpbGluZywgMCwgbG9nSWREYXRhT2Zmc2V0LCBzZXNzaW9uT3B0aW9ucy5sb2dTZXZlcml0eUxldmVsLCBzZXNzaW9uT3B0aW9ucy5sb2dWZXJib3NpdHlMZXZlbCk7XFxuICAgICAgICBpZiAoc2Vzc2lvbk9wdGlvbnNIYW5kbGUgPT09IDApIHtcXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NhblxcXFwndCBjcmVhdGUgc2Vzc2lvbiBvcHRpb25zJyk7XFxuICAgICAgICB9XFxuICAgICAgICBpZiAob3B0aW9ucyA9PT0gbnVsbCB8fCBvcHRpb25zID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcHRpb25zLmV4ZWN1dGlvblByb3ZpZGVycykge1xcbiAgICAgICAgICAgIHNldEV4ZWN1dGlvblByb3ZpZGVycyhzZXNzaW9uT3B0aW9uc0hhbmRsZSwgb3B0aW9ucy5leGVjdXRpb25Qcm92aWRlcnMsIGFsbG9jcyk7XFxuICAgICAgICB9XFxuICAgICAgICBpZiAoKG9wdGlvbnMgPT09IG51bGwgfHwgb3B0aW9ucyA9PT0gdm9pZCAwID8gdm9pZCAwIDogb3B0aW9ucy5leHRyYSkgIT09IHVuZGVmaW5lZCkge1xcbiAgICAgICAgICAgICgwLCBvcHRpb25zX3V0aWxzXzEuaXRlcmF0ZUV4dHJhT3B0aW9ucykob3B0aW9ucy5leHRyYSwgJycsIG5ldyBXZWFrU2V0KCksIChrZXksIHZhbHVlKSA9PiB7XFxuICAgICAgICAgICAgICAgIGNvbnN0IGtleURhdGFPZmZzZXQgPSAoMCwgc3RyaW5nX3V0aWxzXzEuYWxsb2NXYXNtU3RyaW5nKShrZXksIGFsbG9jcyk7XFxuICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlRGF0YU9mZnNldCA9ICgwLCBzdHJpbmdfdXRpbHNfMS5hbGxvY1dhc21TdHJpbmcpKHZhbHVlLCBhbGxvY3MpO1xcbiAgICAgICAgICAgICAgICBpZiAod2FzbS5fT3J0QWRkU2Vzc2lvbkNvbmZpZ0VudHJ5KHNlc3Npb25PcHRpb25zSGFuZGxlLCBrZXlEYXRhT2Zmc2V0LCB2YWx1ZURhdGFPZmZzZXQpICE9PSAwKSB7XFxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENhbid0IHNldCBhIHNlc3Npb24gY29uZmlnIGVudHJ5OiAke2tleX0gLSAke3ZhbHVlfWApO1xcbiAgICAgICAgICAgICAgICB9XFxuICAgICAgICAgICAgfSk7XFxuICAgICAgICB9XFxuICAgICAgICByZXR1cm4gW3Nlc3Npb25PcHRpb25zSGFuZGxlLCBhbGxvY3NdO1xcbiAgICB9XFxuICAgIGNhdGNoIChlKSB7XFxuICAgICAgICBpZiAoc2Vzc2lvbk9wdGlvbnNIYW5kbGUgIT09IDApIHtcXG4gICAgICAgICAgICB3YXNtLl9PcnRSZWxlYXNlU2Vzc2lvbk9wdGlvbnMoc2Vzc2lvbk9wdGlvbnNIYW5kbGUpO1xcbiAgICAgICAgfVxcbiAgICAgICAgYWxsb2NzLmZvckVhY2god2FzbS5fZnJlZSk7XFxuICAgICAgICB0aHJvdyBlO1xcbiAgICB9XFxufTtcXG5leHBvcnRzLnNldFNlc3Npb25PcHRpb25zID0gc2V0U2Vzc2lvbk9wdGlvbnM7XFxuXFxuXFxuLyoqKi8gfSksXFxuXFxuLyoqKi8gXFxcIi4vbGliL3dhc20vc3RyaW5nLXV0aWxzLnRzXFxcIjpcXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxcXFxuICAhKioqIC4vbGliL3dhc20vc3RyaW5nLXV0aWxzLnRzICoqKiFcXG4gIFxcXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xcbi8qKiovICgoX191bnVzZWRfd2VicGFja19tb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pID0+IHtcXG5cXG5cXFwidXNlIHN0cmljdFxcXCI7XFxuXFxuLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXFxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcXFwiX19lc01vZHVsZVxcXCIsICh7IHZhbHVlOiB0cnVlIH0pKTtcXG5leHBvcnRzLmFsbG9jV2FzbVN0cmluZyA9IHZvaWQgMDtcXG5jb25zdCB3YXNtX2ZhY3RvcnlfMSA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vd2FzbS1mYWN0b3J5ICovIFxcXCIuL2xpYi93YXNtL3dhc20tZmFjdG9yeS50c1xcXCIpO1xcbmNvbnN0IGFsbG9jV2FzbVN0cmluZyA9IChkYXRhLCBhbGxvY3MpID0+IHtcXG4gICAgY29uc3Qgd2FzbSA9ICgwLCB3YXNtX2ZhY3RvcnlfMS5nZXRJbnN0YW5jZSkoKTtcXG4gICAgY29uc3QgZGF0YUxlbmd0aCA9IHdhc20ubGVuZ3RoQnl0ZXNVVEY4KGRhdGEpICsgMTtcXG4gICAgY29uc3QgZGF0YU9mZnNldCA9IHdhc20uX21hbGxvYyhkYXRhTGVuZ3RoKTtcXG4gICAgd2FzbS5zdHJpbmdUb1VURjgoZGF0YSwgZGF0YU9mZnNldCwgZGF0YUxlbmd0aCk7XFxuICAgIGFsbG9jcy5wdXNoKGRhdGFPZmZzZXQpO1xcbiAgICByZXR1cm4gZGF0YU9mZnNldDtcXG59O1xcbmV4cG9ydHMuYWxsb2NXYXNtU3RyaW5nID0gYWxsb2NXYXNtU3RyaW5nO1xcblxcblxcbi8qKiovIH0pLFxcblxcbi8qKiovIFxcXCIuL2xpYi93YXNtL3dhc20tY29yZS1pbXBsLnRzXFxcIjpcXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXFxcXG4gICEqKiogLi9saWIvd2FzbS93YXNtLWNvcmUtaW1wbC50cyAqKiohXFxuICBcXFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xcbi8qKiovICgoX191bnVzZWRfd2VicGFja19tb2R1bGUsIGV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pID0+IHtcXG5cXG5cXFwidXNlIHN0cmljdFxcXCI7XFxuXFxuLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXFxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcXFwiX19lc01vZHVsZVxcXCIsICh7IHZhbHVlOiB0cnVlIH0pKTtcXG5leHBvcnRzLmV4dHJhY3RUcmFuc2ZlcmFibGVCdWZmZXJzID0gZXhwb3J0cy5lbmRQcm9maWxpbmcgPSBleHBvcnRzLnJ1biA9IGV4cG9ydHMucmVsZWFzZVNlc3Npb24gPSBleHBvcnRzLmNyZWF0ZVNlc3Npb24gPSBleHBvcnRzLmNyZWF0ZVNlc3Npb25GaW5hbGl6ZSA9IGV4cG9ydHMuY3JlYXRlU2Vzc2lvbkFsbG9jYXRlID0gZXhwb3J0cy5pbml0T3J0ID0gdm9pZCAwO1xcbmNvbnN0IHJ1bl9vcHRpb25zXzEgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL3J1bi1vcHRpb25zICovIFxcXCIuL2xpYi93YXNtL3J1bi1vcHRpb25zLnRzXFxcIik7XFxuY29uc3Qgc2Vzc2lvbl9vcHRpb25zXzEgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL3Nlc3Npb24tb3B0aW9ucyAqLyBcXFwiLi9saWIvd2FzbS9zZXNzaW9uLW9wdGlvbnMudHNcXFwiKTtcXG5jb25zdCBzdHJpbmdfdXRpbHNfMSA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vc3RyaW5nLXV0aWxzICovIFxcXCIuL2xpYi93YXNtL3N0cmluZy11dGlscy50c1xcXCIpO1xcbmNvbnN0IHdhc21fZmFjdG9yeV8xID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi93YXNtLWZhY3RvcnkgKi8gXFxcIi4vbGliL3dhc20vd2FzbS1mYWN0b3J5LnRzXFxcIik7XFxuLyoqXFxuICogaW5pdGlhbGl6ZSBPUlQgZW52aXJvbm1lbnQuXFxuICogQHBhcmFtIG51bVRocmVhZHMgU2V0R2xvYmFsSW50cmFPcE51bVRocmVhZHMobnVtVGhyZWFkcylcXG4gKiBAcGFyYW0gbG9nZ2luZ0xldmVsIENyZWF0ZUVudihzdGF0aWNfY2FzdDxPcnRMb2dnaW5nTGV2ZWw+KGxvZ2dpbmdfbGV2ZWwpKVxcbiAqL1xcbmNvbnN0IGluaXRPcnQgPSAobnVtVGhyZWFkcywgbG9nZ2luZ0xldmVsKSA9PiB7XFxuICAgIGNvbnN0IGVycm9yQ29kZSA9ICgwLCB3YXNtX2ZhY3RvcnlfMS5nZXRJbnN0YW5jZSkoKS5fT3J0SW5pdChudW1UaHJlYWRzLCBsb2dnaW5nTGV2ZWwpO1xcbiAgICBpZiAoZXJyb3JDb2RlICE9PSAwKSB7XFxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENhbid0IGluaXRpYWxpemUgb25ueHJ1bnRpbWUuIGVycm9yIGNvZGUgPSAke2Vycm9yQ29kZX1gKTtcXG4gICAgfVxcbn07XFxuZXhwb3J0cy5pbml0T3J0ID0gaW5pdE9ydDtcXG5jb25zdCBhY3RpdmVTZXNzaW9ucyA9IG5ldyBNYXAoKTtcXG4vKipcXG4gKiBjcmVhdGUgYW4gaW5zdGFuY2Ugb2YgSW5mZXJlbmNlU2Vzc2lvbi5cXG4gKiBAcmV0dXJucyB0aGUgbWV0YWRhdGEgb2YgSW5mZXJlbmNlU2Vzc2lvbi4gMC12YWx1ZSBoYW5kbGUgZm9yIGZhaWx1cmUuXFxuICovXFxuY29uc3QgY3JlYXRlU2Vzc2lvbkFsbG9jYXRlID0gKG1vZGVsKSA9PiB7XFxuICAgIGNvbnN0IHdhc20gPSAoMCwgd2FzbV9mYWN0b3J5XzEuZ2V0SW5zdGFuY2UpKCk7XFxuICAgIGNvbnN0IG1vZGVsRGF0YU9mZnNldCA9IHdhc20uX21hbGxvYyhtb2RlbC5ieXRlTGVuZ3RoKTtcXG4gICAgd2FzbS5IRUFQVTguc2V0KG1vZGVsLCBtb2RlbERhdGFPZmZzZXQpO1xcbiAgICByZXR1cm4gW21vZGVsRGF0YU9mZnNldCwgbW9kZWwuYnl0ZUxlbmd0aF07XFxufTtcXG5leHBvcnRzLmNyZWF0ZVNlc3Npb25BbGxvY2F0ZSA9IGNyZWF0ZVNlc3Npb25BbGxvY2F0ZTtcXG5jb25zdCBjcmVhdGVTZXNzaW9uRmluYWxpemUgPSAobW9kZWxEYXRhLCBvcHRpb25zKSA9PiB7XFxuICAgIGNvbnN0IHdhc20gPSAoMCwgd2FzbV9mYWN0b3J5XzEuZ2V0SW5zdGFuY2UpKCk7XFxuICAgIGxldCBzZXNzaW9uSGFuZGxlID0gMDtcXG4gICAgbGV0IHNlc3Npb25PcHRpb25zSGFuZGxlID0gMDtcXG4gICAgbGV0IGFsbG9jcyA9IFtdO1xcbiAgICB0cnkge1xcbiAgICAgICAgW3Nlc3Npb25PcHRpb25zSGFuZGxlLCBhbGxvY3NdID0gKDAsIHNlc3Npb25fb3B0aW9uc18xLnNldFNlc3Npb25PcHRpb25zKShvcHRpb25zKTtcXG4gICAgICAgIHNlc3Npb25IYW5kbGUgPSB3YXNtLl9PcnRDcmVhdGVTZXNzaW9uKG1vZGVsRGF0YVswXSwgbW9kZWxEYXRhWzFdLCBzZXNzaW9uT3B0aW9uc0hhbmRsZSk7XFxuICAgICAgICBpZiAoc2Vzc2lvbkhhbmRsZSA9PT0gMCkge1xcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQ2FuXFxcXCd0IGNyZWF0ZSBhIHNlc3Npb24nKTtcXG4gICAgICAgIH1cXG4gICAgfVxcbiAgICBmaW5hbGx5IHtcXG4gICAgICAgIHdhc20uX2ZyZWUobW9kZWxEYXRhWzBdKTtcXG4gICAgICAgIHdhc20uX09ydFJlbGVhc2VTZXNzaW9uT3B0aW9ucyhzZXNzaW9uT3B0aW9uc0hhbmRsZSk7XFxuICAgICAgICBhbGxvY3MuZm9yRWFjaCh3YXNtLl9mcmVlKTtcXG4gICAgfVxcbiAgICBjb25zdCBpbnB1dENvdW50ID0gd2FzbS5fT3J0R2V0SW5wdXRDb3VudChzZXNzaW9uSGFuZGxlKTtcXG4gICAgY29uc3Qgb3V0cHV0Q291bnQgPSB3YXNtLl9PcnRHZXRPdXRwdXRDb3VudChzZXNzaW9uSGFuZGxlKTtcXG4gICAgY29uc3QgaW5wdXROYW1lcyA9IFtdO1xcbiAgICBjb25zdCBpbnB1dE5hbWVzVVRGOEVuY29kZWQgPSBbXTtcXG4gICAgY29uc3Qgb3V0cHV0TmFtZXMgPSBbXTtcXG4gICAgY29uc3Qgb3V0cHV0TmFtZXNVVEY4RW5jb2RlZCA9IFtdO1xcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGlucHV0Q291bnQ7IGkrKykge1xcbiAgICAgICAgY29uc3QgbmFtZSA9IHdhc20uX09ydEdldElucHV0TmFtZShzZXNzaW9uSGFuZGxlLCBpKTtcXG4gICAgICAgIGlmIChuYW1lID09PSAwKSB7XFxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW5cXFxcJ3QgZ2V0IGFuIGlucHV0IG5hbWUnKTtcXG4gICAgICAgIH1cXG4gICAgICAgIGlucHV0TmFtZXNVVEY4RW5jb2RlZC5wdXNoKG5hbWUpO1xcbiAgICAgICAgaW5wdXROYW1lcy5wdXNoKHdhc20uVVRGOFRvU3RyaW5nKG5hbWUpKTtcXG4gICAgfVxcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG91dHB1dENvdW50OyBpKyspIHtcXG4gICAgICAgIGNvbnN0IG5hbWUgPSB3YXNtLl9PcnRHZXRPdXRwdXROYW1lKHNlc3Npb25IYW5kbGUsIGkpO1xcbiAgICAgICAgaWYgKG5hbWUgPT09IDApIHtcXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NhblxcXFwndCBnZXQgYW4gb3V0cHV0IG5hbWUnKTtcXG4gICAgICAgIH1cXG4gICAgICAgIG91dHB1dE5hbWVzVVRGOEVuY29kZWQucHVzaChuYW1lKTtcXG4gICAgICAgIG91dHB1dE5hbWVzLnB1c2god2FzbS5VVEY4VG9TdHJpbmcobmFtZSkpO1xcbiAgICB9XFxuICAgIGFjdGl2ZVNlc3Npb25zLnNldChzZXNzaW9uSGFuZGxlLCBbc2Vzc2lvbkhhbmRsZSwgaW5wdXROYW1lc1VURjhFbmNvZGVkLCBvdXRwdXROYW1lc1VURjhFbmNvZGVkXSk7XFxuICAgIHJldHVybiBbc2Vzc2lvbkhhbmRsZSwgaW5wdXROYW1lcywgb3V0cHV0TmFtZXNdO1xcbn07XFxuZXhwb3J0cy5jcmVhdGVTZXNzaW9uRmluYWxpemUgPSBjcmVhdGVTZXNzaW9uRmluYWxpemU7XFxuLyoqXFxuICogY3JlYXRlIGFuIGluc3RhbmNlIG9mIEluZmVyZW5jZVNlc3Npb24uXFxuICogQHJldHVybnMgdGhlIG1ldGFkYXRhIG9mIEluZmVyZW5jZVNlc3Npb24uIDAtdmFsdWUgaGFuZGxlIGZvciBmYWlsdXJlLlxcbiAqL1xcbmNvbnN0IGNyZWF0ZVNlc3Npb24gPSAobW9kZWwsIG9wdGlvbnMpID0+IHtcXG4gICAgY29uc3QgbW9kZWxEYXRhID0gKDAsIGV4cG9ydHMuY3JlYXRlU2Vzc2lvbkFsbG9jYXRlKShtb2RlbCk7XFxuICAgIHJldHVybiAoMCwgZXhwb3J0cy5jcmVhdGVTZXNzaW9uRmluYWxpemUpKG1vZGVsRGF0YSwgb3B0aW9ucyk7XFxufTtcXG5leHBvcnRzLmNyZWF0ZVNlc3Npb24gPSBjcmVhdGVTZXNzaW9uO1xcbmNvbnN0IHJlbGVhc2VTZXNzaW9uID0gKHNlc3Npb25JZCkgPT4ge1xcbiAgICBjb25zdCB3YXNtID0gKDAsIHdhc21fZmFjdG9yeV8xLmdldEluc3RhbmNlKSgpO1xcbiAgICBjb25zdCBzZXNzaW9uID0gYWN0aXZlU2Vzc2lvbnMuZ2V0KHNlc3Npb25JZCk7XFxuICAgIGlmICghc2Vzc2lvbikge1xcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIHNlc3Npb24gaWQnKTtcXG4gICAgfVxcbiAgICBjb25zdCBzZXNzaW9uSGFuZGxlID0gc2Vzc2lvblswXTtcXG4gICAgY29uc3QgaW5wdXROYW1lc1VURjhFbmNvZGVkID0gc2Vzc2lvblsxXTtcXG4gICAgY29uc3Qgb3V0cHV0TmFtZXNVVEY4RW5jb2RlZCA9IHNlc3Npb25bMl07XFxuICAgIGlucHV0TmFtZXNVVEY4RW5jb2RlZC5mb3JFYWNoKHdhc20uX09ydEZyZWUpO1xcbiAgICBvdXRwdXROYW1lc1VURjhFbmNvZGVkLmZvckVhY2god2FzbS5fT3J0RnJlZSk7XFxuICAgIHdhc20uX09ydFJlbGVhc2VTZXNzaW9uKHNlc3Npb25IYW5kbGUpO1xcbiAgICBhY3RpdmVTZXNzaW9ucy5kZWxldGUoc2Vzc2lvbklkKTtcXG59O1xcbmV4cG9ydHMucmVsZWFzZVNlc3Npb24gPSByZWxlYXNlU2Vzc2lvbjtcXG5jb25zdCB0ZW5zb3JEYXRhVHlwZVN0cmluZ1RvRW51bSA9ICh0eXBlKSA9PiB7XFxuICAgIHN3aXRjaCAodHlwZSkge1xcbiAgICAgICAgY2FzZSAnaW50OCc6XFxuICAgICAgICAgICAgcmV0dXJuIDMgLyogRGF0YVR5cGUuaW50OCAqLztcXG4gICAgICAgIGNhc2UgJ3VpbnQ4JzpcXG4gICAgICAgICAgICByZXR1cm4gMiAvKiBEYXRhVHlwZS51aW50OCAqLztcXG4gICAgICAgIGNhc2UgJ2Jvb2wnOlxcbiAgICAgICAgICAgIHJldHVybiA5IC8qIERhdGFUeXBlLmJvb2wgKi87XFxuICAgICAgICBjYXNlICdpbnQxNic6XFxuICAgICAgICAgICAgcmV0dXJuIDUgLyogRGF0YVR5cGUuaW50MTYgKi87XFxuICAgICAgICBjYXNlICd1aW50MTYnOlxcbiAgICAgICAgICAgIHJldHVybiA0IC8qIERhdGFUeXBlLnVpbnQxNiAqLztcXG4gICAgICAgIGNhc2UgJ2ludDMyJzpcXG4gICAgICAgICAgICByZXR1cm4gNiAvKiBEYXRhVHlwZS5pbnQzMiAqLztcXG4gICAgICAgIGNhc2UgJ3VpbnQzMic6XFxuICAgICAgICAgICAgcmV0dXJuIDEyIC8qIERhdGFUeXBlLnVpbnQzMiAqLztcXG4gICAgICAgIGNhc2UgJ2Zsb2F0MzInOlxcbiAgICAgICAgICAgIHJldHVybiAxIC8qIERhdGFUeXBlLmZsb2F0ICovO1xcbiAgICAgICAgY2FzZSAnZmxvYXQ2NCc6XFxuICAgICAgICAgICAgcmV0dXJuIDExIC8qIERhdGFUeXBlLmRvdWJsZSAqLztcXG4gICAgICAgIGNhc2UgJ3N0cmluZyc6XFxuICAgICAgICAgICAgcmV0dXJuIDggLyogRGF0YVR5cGUuc3RyaW5nICovO1xcbiAgICAgICAgY2FzZSAnaW50NjQnOlxcbiAgICAgICAgICAgIHJldHVybiA3IC8qIERhdGFUeXBlLmludDY0ICovO1xcbiAgICAgICAgY2FzZSAndWludDY0JzpcXG4gICAgICAgICAgICByZXR1cm4gMTMgLyogRGF0YVR5cGUudWludDY0ICovO1xcbiAgICAgICAgZGVmYXVsdDpcXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuc3VwcG9ydGVkIGRhdGEgdHlwZTogJHt0eXBlfWApO1xcbiAgICB9XFxufTtcXG5jb25zdCB0ZW5zb3JEYXRhVHlwZUVudW1Ub1N0cmluZyA9ICh0eXBlUHJvdG8pID0+IHtcXG4gICAgc3dpdGNoICh0eXBlUHJvdG8pIHtcXG4gICAgICAgIGNhc2UgMyAvKiBEYXRhVHlwZS5pbnQ4ICovOlxcbiAgICAgICAgICAgIHJldHVybiAnaW50OCc7XFxuICAgICAgICBjYXNlIDIgLyogRGF0YVR5cGUudWludDggKi86XFxuICAgICAgICAgICAgcmV0dXJuICd1aW50OCc7XFxuICAgICAgICBjYXNlIDkgLyogRGF0YVR5cGUuYm9vbCAqLzpcXG4gICAgICAgICAgICByZXR1cm4gJ2Jvb2wnO1xcbiAgICAgICAgY2FzZSA1IC8qIERhdGFUeXBlLmludDE2ICovOlxcbiAgICAgICAgICAgIHJldHVybiAnaW50MTYnO1xcbiAgICAgICAgY2FzZSA0IC8qIERhdGFUeXBlLnVpbnQxNiAqLzpcXG4gICAgICAgICAgICByZXR1cm4gJ3VpbnQxNic7XFxuICAgICAgICBjYXNlIDYgLyogRGF0YVR5cGUuaW50MzIgKi86XFxuICAgICAgICAgICAgcmV0dXJuICdpbnQzMic7XFxuICAgICAgICBjYXNlIDEyIC8qIERhdGFUeXBlLnVpbnQzMiAqLzpcXG4gICAgICAgICAgICByZXR1cm4gJ3VpbnQzMic7XFxuICAgICAgICBjYXNlIDEgLyogRGF0YVR5cGUuZmxvYXQgKi86XFxuICAgICAgICAgICAgcmV0dXJuICdmbG9hdDMyJztcXG4gICAgICAgIGNhc2UgMTEgLyogRGF0YVR5cGUuZG91YmxlICovOlxcbiAgICAgICAgICAgIHJldHVybiAnZmxvYXQ2NCc7XFxuICAgICAgICBjYXNlIDggLyogRGF0YVR5cGUuc3RyaW5nICovOlxcbiAgICAgICAgICAgIHJldHVybiAnc3RyaW5nJztcXG4gICAgICAgIGNhc2UgNyAvKiBEYXRhVHlwZS5pbnQ2NCAqLzpcXG4gICAgICAgICAgICByZXR1cm4gJ2ludDY0JztcXG4gICAgICAgIGNhc2UgMTMgLyogRGF0YVR5cGUudWludDY0ICovOlxcbiAgICAgICAgICAgIHJldHVybiAndWludDY0JztcXG4gICAgICAgIGRlZmF1bHQ6XFxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bnN1cHBvcnRlZCBkYXRhIHR5cGU6ICR7dHlwZVByb3RvfWApO1xcbiAgICB9XFxufTtcXG5jb25zdCBudW1lcmljVGVuc29yVHlwZVRvVHlwZWRBcnJheSA9ICh0eXBlKSA9PiB7XFxuICAgIHN3aXRjaCAodHlwZSkge1xcbiAgICAgICAgY2FzZSAnZmxvYXQzMic6XFxuICAgICAgICAgICAgcmV0dXJuIEZsb2F0MzJBcnJheTtcXG4gICAgICAgIGNhc2UgJ3VpbnQ4JzpcXG4gICAgICAgICAgICByZXR1cm4gVWludDhBcnJheTtcXG4gICAgICAgIGNhc2UgJ2ludDgnOlxcbiAgICAgICAgICAgIHJldHVybiBJbnQ4QXJyYXk7XFxuICAgICAgICBjYXNlICd1aW50MTYnOlxcbiAgICAgICAgICAgIHJldHVybiBVaW50MTZBcnJheTtcXG4gICAgICAgIGNhc2UgJ2ludDE2JzpcXG4gICAgICAgICAgICByZXR1cm4gSW50MTZBcnJheTtcXG4gICAgICAgIGNhc2UgJ2ludDMyJzpcXG4gICAgICAgICAgICByZXR1cm4gSW50MzJBcnJheTtcXG4gICAgICAgIGNhc2UgJ2Jvb2wnOlxcbiAgICAgICAgICAgIHJldHVybiBVaW50OEFycmF5O1xcbiAgICAgICAgY2FzZSAnZmxvYXQ2NCc6XFxuICAgICAgICAgICAgcmV0dXJuIEZsb2F0NjRBcnJheTtcXG4gICAgICAgIGNhc2UgJ3VpbnQzMic6XFxuICAgICAgICAgICAgcmV0dXJuIFVpbnQzMkFycmF5O1xcbiAgICAgICAgY2FzZSAnaW50NjQnOlxcbiAgICAgICAgICAgIHJldHVybiBCaWdJbnQ2NEFycmF5O1xcbiAgICAgICAgY2FzZSAndWludDY0JzpcXG4gICAgICAgICAgICByZXR1cm4gQmlnVWludDY0QXJyYXk7XFxuICAgICAgICBkZWZhdWx0OlxcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgdW5zdXBwb3J0ZWQgdHlwZTogJHt0eXBlfWApO1xcbiAgICB9XFxufTtcXG4vKipcXG4gKiBwZXJmb3JtIGluZmVyZW5jZSBydW5cXG4gKi9cXG5jb25zdCBydW4gPSAoc2Vzc2lvbklkLCBpbnB1dEluZGljZXMsIGlucHV0cywgb3V0cHV0SW5kaWNlcywgb3B0aW9ucykgPT4ge1xcbiAgICBjb25zdCB3YXNtID0gKDAsIHdhc21fZmFjdG9yeV8xLmdldEluc3RhbmNlKSgpO1xcbiAgICBjb25zdCBzZXNzaW9uID0gYWN0aXZlU2Vzc2lvbnMuZ2V0KHNlc3Npb25JZCk7XFxuICAgIGlmICghc2Vzc2lvbikge1xcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIHNlc3Npb24gaWQnKTtcXG4gICAgfVxcbiAgICBjb25zdCBzZXNzaW9uSGFuZGxlID0gc2Vzc2lvblswXTtcXG4gICAgY29uc3QgaW5wdXROYW1lc1VURjhFbmNvZGVkID0gc2Vzc2lvblsxXTtcXG4gICAgY29uc3Qgb3V0cHV0TmFtZXNVVEY4RW5jb2RlZCA9IHNlc3Npb25bMl07XFxuICAgIGNvbnN0IGlucHV0Q291bnQgPSBpbnB1dEluZGljZXMubGVuZ3RoO1xcbiAgICBjb25zdCBvdXRwdXRDb3VudCA9IG91dHB1dEluZGljZXMubGVuZ3RoO1xcbiAgICBsZXQgcnVuT3B0aW9uc0hhbmRsZSA9IDA7XFxuICAgIGxldCBydW5PcHRpb25zQWxsb2NzID0gW107XFxuICAgIGNvbnN0IGlucHV0VmFsdWVzID0gW107XFxuICAgIGNvbnN0IGlucHV0QWxsb2NzID0gW107XFxuICAgIHRyeSB7XFxuICAgICAgICBbcnVuT3B0aW9uc0hhbmRsZSwgcnVuT3B0aW9uc0FsbG9jc10gPSAoMCwgcnVuX29wdGlvbnNfMS5zZXRSdW5PcHRpb25zKShvcHRpb25zKTtcXG4gICAgICAgIC8vIGNyZWF0ZSBpbnB1dCB0ZW5zb3JzXFxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGlucHV0Q291bnQ7IGkrKykge1xcbiAgICAgICAgICAgIGNvbnN0IGRhdGFUeXBlID0gaW5wdXRzW2ldWzBdO1xcbiAgICAgICAgICAgIGNvbnN0IGRpbXMgPSBpbnB1dHNbaV1bMV07XFxuICAgICAgICAgICAgY29uc3QgZGF0YSA9IGlucHV0c1tpXVsyXTtcXG4gICAgICAgICAgICBsZXQgZGF0YU9mZnNldDtcXG4gICAgICAgICAgICBsZXQgZGF0YUJ5dGVMZW5ndGg7XFxuICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZGF0YSkpIHtcXG4gICAgICAgICAgICAgICAgLy8gc3RyaW5nIHRlbnNvclxcbiAgICAgICAgICAgICAgICBkYXRhQnl0ZUxlbmd0aCA9IDQgKiBkYXRhLmxlbmd0aDtcXG4gICAgICAgICAgICAgICAgZGF0YU9mZnNldCA9IHdhc20uX21hbGxvYyhkYXRhQnl0ZUxlbmd0aCk7XFxuICAgICAgICAgICAgICAgIGlucHV0QWxsb2NzLnB1c2goZGF0YU9mZnNldCk7XFxuICAgICAgICAgICAgICAgIGxldCBkYXRhSW5kZXggPSBkYXRhT2Zmc2V0IC8gNDtcXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkYXRhLmxlbmd0aDsgaSsrKSB7XFxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGRhdGFbaV0gIT09ICdzdHJpbmcnKSB7XFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgdGVuc29yIGRhdGEgYXQgaW5kZXggJHtpfSBpcyBub3QgYSBzdHJpbmdgKTtcXG4gICAgICAgICAgICAgICAgICAgIH1cXG4gICAgICAgICAgICAgICAgICAgIHdhc20uSEVBUFUzMltkYXRhSW5kZXgrK10gPSAoMCwgc3RyaW5nX3V0aWxzXzEuYWxsb2NXYXNtU3RyaW5nKShkYXRhW2ldLCBpbnB1dEFsbG9jcyk7XFxuICAgICAgICAgICAgICAgIH1cXG4gICAgICAgICAgICB9XFxuICAgICAgICAgICAgZWxzZSB7XFxuICAgICAgICAgICAgICAgIGRhdGFCeXRlTGVuZ3RoID0gZGF0YS5ieXRlTGVuZ3RoO1xcbiAgICAgICAgICAgICAgICBkYXRhT2Zmc2V0ID0gd2FzbS5fbWFsbG9jKGRhdGFCeXRlTGVuZ3RoKTtcXG4gICAgICAgICAgICAgICAgaW5wdXRBbGxvY3MucHVzaChkYXRhT2Zmc2V0KTtcXG4gICAgICAgICAgICAgICAgd2FzbS5IRUFQVTguc2V0KG5ldyBVaW50OEFycmF5KGRhdGEuYnVmZmVyLCBkYXRhLmJ5dGVPZmZzZXQsIGRhdGFCeXRlTGVuZ3RoKSwgZGF0YU9mZnNldCk7XFxuICAgICAgICAgICAgfVxcbiAgICAgICAgICAgIGNvbnN0IHN0YWNrID0gd2FzbS5zdGFja1NhdmUoKTtcXG4gICAgICAgICAgICBjb25zdCBkaW1zT2Zmc2V0ID0gd2FzbS5zdGFja0FsbG9jKDQgKiBkaW1zLmxlbmd0aCk7XFxuICAgICAgICAgICAgdHJ5IHtcXG4gICAgICAgICAgICAgICAgbGV0IGRpbUluZGV4ID0gZGltc09mZnNldCAvIDQ7XFxuICAgICAgICAgICAgICAgIGRpbXMuZm9yRWFjaChkID0+IHdhc20uSEVBUDMyW2RpbUluZGV4KytdID0gZCk7XFxuICAgICAgICAgICAgICAgIGNvbnN0IHRlbnNvciA9IHdhc20uX09ydENyZWF0ZVRlbnNvcih0ZW5zb3JEYXRhVHlwZVN0cmluZ1RvRW51bShkYXRhVHlwZSksIGRhdGFPZmZzZXQsIGRhdGFCeXRlTGVuZ3RoLCBkaW1zT2Zmc2V0LCBkaW1zLmxlbmd0aCk7XFxuICAgICAgICAgICAgICAgIGlmICh0ZW5zb3IgPT09IDApIHtcXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQ2FuXFxcXCd0IGNyZWF0ZSBhIHRlbnNvcicpO1xcbiAgICAgICAgICAgICAgICB9XFxuICAgICAgICAgICAgICAgIGlucHV0VmFsdWVzLnB1c2godGVuc29yKTtcXG4gICAgICAgICAgICB9XFxuICAgICAgICAgICAgZmluYWxseSB7XFxuICAgICAgICAgICAgICAgIHdhc20uc3RhY2tSZXN0b3JlKHN0YWNrKTtcXG4gICAgICAgICAgICB9XFxuICAgICAgICB9XFxuICAgICAgICBjb25zdCBiZWZvcmVSdW5TdGFjayA9IHdhc20uc3RhY2tTYXZlKCk7XFxuICAgICAgICBjb25zdCBpbnB1dFZhbHVlc09mZnNldCA9IHdhc20uc3RhY2tBbGxvYyhpbnB1dENvdW50ICogNCk7XFxuICAgICAgICBjb25zdCBpbnB1dE5hbWVzT2Zmc2V0ID0gd2FzbS5zdGFja0FsbG9jKGlucHV0Q291bnQgKiA0KTtcXG4gICAgICAgIGNvbnN0IG91dHB1dFZhbHVlc09mZnNldCA9IHdhc20uc3RhY2tBbGxvYyhvdXRwdXRDb3VudCAqIDQpO1xcbiAgICAgICAgY29uc3Qgb3V0cHV0TmFtZXNPZmZzZXQgPSB3YXNtLnN0YWNrQWxsb2Mob3V0cHV0Q291bnQgKiA0KTtcXG4gICAgICAgIHRyeSB7XFxuICAgICAgICAgICAgbGV0IGlucHV0VmFsdWVzSW5kZXggPSBpbnB1dFZhbHVlc09mZnNldCAvIDQ7XFxuICAgICAgICAgICAgbGV0IGlucHV0TmFtZXNJbmRleCA9IGlucHV0TmFtZXNPZmZzZXQgLyA0O1xcbiAgICAgICAgICAgIGxldCBvdXRwdXRWYWx1ZXNJbmRleCA9IG91dHB1dFZhbHVlc09mZnNldCAvIDQ7XFxuICAgICAgICAgICAgbGV0IG91dHB1dE5hbWVzSW5kZXggPSBvdXRwdXROYW1lc09mZnNldCAvIDQ7XFxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbnB1dENvdW50OyBpKyspIHtcXG4gICAgICAgICAgICAgICAgd2FzbS5IRUFQVTMyW2lucHV0VmFsdWVzSW5kZXgrK10gPSBpbnB1dFZhbHVlc1tpXTtcXG4gICAgICAgICAgICAgICAgd2FzbS5IRUFQVTMyW2lucHV0TmFtZXNJbmRleCsrXSA9IGlucHV0TmFtZXNVVEY4RW5jb2RlZFtpbnB1dEluZGljZXNbaV1dO1xcbiAgICAgICAgICAgIH1cXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG91dHB1dENvdW50OyBpKyspIHtcXG4gICAgICAgICAgICAgICAgd2FzbS5IRUFQVTMyW291dHB1dFZhbHVlc0luZGV4KytdID0gMDtcXG4gICAgICAgICAgICAgICAgd2FzbS5IRUFQVTMyW291dHB1dE5hbWVzSW5kZXgrK10gPSBvdXRwdXROYW1lc1VURjhFbmNvZGVkW291dHB1dEluZGljZXNbaV1dO1xcbiAgICAgICAgICAgIH1cXG4gICAgICAgICAgICAvLyBzdXBwb3J0IFJ1bk9wdGlvbnNcXG4gICAgICAgICAgICBsZXQgZXJyb3JDb2RlID0gd2FzbS5fT3J0UnVuKHNlc3Npb25IYW5kbGUsIGlucHV0TmFtZXNPZmZzZXQsIGlucHV0VmFsdWVzT2Zmc2V0LCBpbnB1dENvdW50LCBvdXRwdXROYW1lc09mZnNldCwgb3V0cHV0Q291bnQsIG91dHB1dFZhbHVlc09mZnNldCwgcnVuT3B0aW9uc0hhbmRsZSk7XFxuICAgICAgICAgICAgY29uc3Qgb3V0cHV0ID0gW107XFxuICAgICAgICAgICAgaWYgKGVycm9yQ29kZSA9PT0gMCkge1xcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG91dHB1dENvdW50OyBpKyspIHtcXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHRlbnNvciA9IHdhc20uSEVBUFUzMltvdXRwdXRWYWx1ZXNPZmZzZXQgLyA0ICsgaV07XFxuICAgICAgICAgICAgICAgICAgICBjb25zdCBiZWZvcmVHZXRUZW5zb3JEYXRhU3RhY2sgPSB3YXNtLnN0YWNrU2F2ZSgpO1xcbiAgICAgICAgICAgICAgICAgICAgLy8gc3RhY2sgYWxsb2NhdGUgNCBwb2ludGVyIHZhbHVlXFxuICAgICAgICAgICAgICAgICAgICBjb25zdCB0ZW5zb3JEYXRhT2Zmc2V0ID0gd2FzbS5zdGFja0FsbG9jKDQgKiA0KTtcXG4gICAgICAgICAgICAgICAgICAgIGxldCB0eXBlLCBkYXRhT2Zmc2V0ID0gMDtcXG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XFxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDb2RlID0gd2FzbS5fT3J0R2V0VGVuc29yRGF0YSh0ZW5zb3IsIHRlbnNvckRhdGFPZmZzZXQsIHRlbnNvckRhdGFPZmZzZXQgKyA0LCB0ZW5zb3JEYXRhT2Zmc2V0ICsgOCwgdGVuc29yRGF0YU9mZnNldCArIDEyKTtcXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3JDb2RlICE9PSAwKSB7XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2FuJ3QgYWNjZXNzIG91dHB1dCB0ZW5zb3IgZGF0YS4gZXJyb3IgY29kZSA9ICR7ZXJyb3JDb2RlfWApO1xcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgdGVuc29yRGF0YUluZGV4ID0gdGVuc29yRGF0YU9mZnNldCAvIDQ7XFxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZGF0YVR5cGUgPSB3YXNtLkhFQVBVMzJbdGVuc29yRGF0YUluZGV4KytdO1xcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFPZmZzZXQgPSB3YXNtLkhFQVBVMzJbdGVuc29yRGF0YUluZGV4KytdO1xcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGRpbXNPZmZzZXQgPSB3YXNtLkhFQVBVMzJbdGVuc29yRGF0YUluZGV4KytdO1xcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGRpbXNMZW5ndGggPSB3YXNtLkhFQVBVMzJbdGVuc29yRGF0YUluZGV4KytdO1xcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGRpbXMgPSBbXTtcXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRpbXNMZW5ndGg7IGkrKykge1xcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaW1zLnB1c2god2FzbS5IRUFQVTMyW2RpbXNPZmZzZXQgLyA0ICsgaV0pO1xcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cXG4gICAgICAgICAgICAgICAgICAgICAgICB3YXNtLl9PcnRGcmVlKGRpbXNPZmZzZXQpO1xcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHNpemUgPSBkaW1zLmxlbmd0aCA9PT0gMCA/IDEgOiBkaW1zLnJlZHVjZSgoYSwgYikgPT4gYSAqIGIpO1xcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUgPSB0ZW5zb3JEYXRhVHlwZUVudW1Ub1N0cmluZyhkYXRhVHlwZSk7XFxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJpbmcnKSB7XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmluZ0RhdGEgPSBbXTtcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGRhdGFJbmRleCA9IGRhdGFPZmZzZXQgLyA0O1xcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNpemU7IGkrKykge1xcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2Zmc2V0ID0gd2FzbS5IRUFQVTMyW2RhdGFJbmRleCsrXTtcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1heEJ5dGVzVG9SZWFkID0gaSA9PT0gc2l6ZSAtIDEgPyB1bmRlZmluZWQgOiB3YXNtLkhFQVBVMzJbZGF0YUluZGV4XSAtIG9mZnNldDtcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZ0RhdGEucHVzaCh3YXNtLlVURjhUb1N0cmluZyhvZmZzZXQsIG1heEJ5dGVzVG9SZWFkKSk7XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0LnB1c2goW3R5cGUsIGRpbXMsIHN0cmluZ0RhdGFdKTtcXG4gICAgICAgICAgICAgICAgICAgICAgICB9XFxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHR5cGVkQXJyYXlDb25zdHJ1Y3RvciA9IG51bWVyaWNUZW5zb3JUeXBlVG9UeXBlZEFycmF5KHR5cGUpO1xcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBkYXRhID0gbmV3IHR5cGVkQXJyYXlDb25zdHJ1Y3RvcihzaXplKTtcXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFVpbnQ4QXJyYXkoZGF0YS5idWZmZXIsIGRhdGEuYnl0ZU9mZnNldCwgZGF0YS5ieXRlTGVuZ3RoKVxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnNldCh3YXNtLkhFQVBVOC5zdWJhcnJheShkYXRhT2Zmc2V0LCBkYXRhT2Zmc2V0ICsgZGF0YS5ieXRlTGVuZ3RoKSk7XFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dC5wdXNoKFt0eXBlLCBkaW1zLCBkYXRhXSk7XFxuICAgICAgICAgICAgICAgICAgICAgICAgfVxcbiAgICAgICAgICAgICAgICAgICAgfVxcbiAgICAgICAgICAgICAgICAgICAgZmluYWxseSB7XFxuICAgICAgICAgICAgICAgICAgICAgICAgd2FzbS5zdGFja1Jlc3RvcmUoYmVmb3JlR2V0VGVuc29yRGF0YVN0YWNrKTtcXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZSA9PT0gJ3N0cmluZycgJiYgZGF0YU9mZnNldCkge1xcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3YXNtLl9mcmVlKGRhdGFPZmZzZXQpO1xcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cXG4gICAgICAgICAgICAgICAgICAgICAgICB3YXNtLl9PcnRSZWxlYXNlVGVuc29yKHRlbnNvcik7XFxuICAgICAgICAgICAgICAgICAgICB9XFxuICAgICAgICAgICAgICAgIH1cXG4gICAgICAgICAgICB9XFxuICAgICAgICAgICAgaWYgKGVycm9yQ29kZSA9PT0gMCkge1xcbiAgICAgICAgICAgICAgICByZXR1cm4gb3V0cHV0O1xcbiAgICAgICAgICAgIH1cXG4gICAgICAgICAgICBlbHNlIHtcXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBmYWlsZWQgdG8gY2FsbCBPcnRSdW4oKS4gZXJyb3IgY29kZSA9ICR7ZXJyb3JDb2RlfS5gKTtcXG4gICAgICAgICAgICB9XFxuICAgICAgICB9XFxuICAgICAgICBmaW5hbGx5IHtcXG4gICAgICAgICAgICB3YXNtLnN0YWNrUmVzdG9yZShiZWZvcmVSdW5TdGFjayk7XFxuICAgICAgICB9XFxuICAgIH1cXG4gICAgZmluYWxseSB7XFxuICAgICAgICBpbnB1dFZhbHVlcy5mb3JFYWNoKHdhc20uX09ydFJlbGVhc2VUZW5zb3IpO1xcbiAgICAgICAgaW5wdXRBbGxvY3MuZm9yRWFjaCh3YXNtLl9mcmVlKTtcXG4gICAgICAgIHdhc20uX09ydFJlbGVhc2VSdW5PcHRpb25zKHJ1bk9wdGlvbnNIYW5kbGUpO1xcbiAgICAgICAgcnVuT3B0aW9uc0FsbG9jcy5mb3JFYWNoKHdhc20uX2ZyZWUpO1xcbiAgICB9XFxufTtcXG5leHBvcnRzLnJ1biA9IHJ1bjtcXG4vKipcXG4gKiBlbmQgcHJvZmlsaW5nXFxuICovXFxuY29uc3QgZW5kUHJvZmlsaW5nID0gKHNlc3Npb25JZCkgPT4ge1xcbiAgICBjb25zdCB3YXNtID0gKDAsIHdhc21fZmFjdG9yeV8xLmdldEluc3RhbmNlKSgpO1xcbiAgICBjb25zdCBzZXNzaW9uID0gYWN0aXZlU2Vzc2lvbnMuZ2V0KHNlc3Npb25JZCk7XFxuICAgIGlmICghc2Vzc2lvbikge1xcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIHNlc3Npb24gaWQnKTtcXG4gICAgfVxcbiAgICBjb25zdCBzZXNzaW9uSGFuZGxlID0gc2Vzc2lvblswXTtcXG4gICAgLy8gcHJvZmlsZSBmaWxlIG5hbWUgaXMgbm90IHVzZWQgeWV0LCBidXQgaXQgbXVzdCBiZSBmcmVlZC5cXG4gICAgY29uc3QgcHJvZmlsZUZpbGVOYW1lID0gd2FzbS5fT3J0RW5kUHJvZmlsaW5nKHNlc3Npb25IYW5kbGUpO1xcbiAgICBpZiAocHJvZmlsZUZpbGVOYW1lID09PSAwKSB7XFxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NhblxcXFwndCBnZXQgYW4gcHJvZmlsZSBmaWxlIG5hbWUnKTtcXG4gICAgfVxcbiAgICB3YXNtLl9PcnRGcmVlKHByb2ZpbGVGaWxlTmFtZSk7XFxufTtcXG5leHBvcnRzLmVuZFByb2ZpbGluZyA9IGVuZFByb2ZpbGluZztcXG5jb25zdCBleHRyYWN0VHJhbnNmZXJhYmxlQnVmZmVycyA9ICh0ZW5zb3JzKSA9PiB7XFxuICAgIGNvbnN0IGJ1ZmZlcnMgPSBbXTtcXG4gICAgZm9yIChjb25zdCB0ZW5zb3Igb2YgdGVuc29ycykge1xcbiAgICAgICAgY29uc3QgZGF0YSA9IHRlbnNvclsyXTtcXG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShkYXRhKSAmJiBkYXRhLmJ1ZmZlcikge1xcbiAgICAgICAgICAgIGJ1ZmZlcnMucHVzaChkYXRhLmJ1ZmZlcik7XFxuICAgICAgICB9XFxuICAgIH1cXG4gICAgcmV0dXJuIGJ1ZmZlcnM7XFxufTtcXG5leHBvcnRzLmV4dHJhY3RUcmFuc2ZlcmFibGVCdWZmZXJzID0gZXh0cmFjdFRyYW5zZmVyYWJsZUJ1ZmZlcnM7XFxuXFxuXFxuLyoqKi8gfSksXFxuXFxuLyoqKi8gXFxcIi4vbGliL3dhc20vd2FzbS1mYWN0b3J5LnRzXFxcIjpcXG4vKiEqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxcXFxuICAhKioqIC4vbGliL3dhc20vd2FzbS1mYWN0b3J5LnRzICoqKiFcXG4gIFxcXFwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xcbi8qKiovIChmdW5jdGlvbihfX3VudXNlZF93ZWJwYWNrX21vZHVsZSwgZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXykge1xcblxcblxcXCJ1c2Ugc3RyaWN0XFxcIjtcXG52YXIgX19kaXJuYW1lID0gXFxcIi9cXFwiO1xcblxcbi8vIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxcbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS5cXG52YXIgX19jcmVhdGVCaW5kaW5nID0gKHRoaXMgJiYgdGhpcy5fX2NyZWF0ZUJpbmRpbmcpIHx8IChPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XFxuICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XFxuICAgIHZhciBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihtLCBrKTtcXG4gICAgaWYgKCFkZXNjIHx8IChcXFwiZ2V0XFxcIiBpbiBkZXNjID8gIW0uX19lc01vZHVsZSA6IGRlc2Mud3JpdGFibGUgfHwgZGVzYy5jb25maWd1cmFibGUpKSB7XFxuICAgICAgZGVzYyA9IHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ba107IH0gfTtcXG4gICAgfVxcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobywgazIsIGRlc2MpO1xcbn0pIDogKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XFxuICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XFxuICAgIG9bazJdID0gbVtrXTtcXG59KSk7XFxudmFyIF9fc2V0TW9kdWxlRGVmYXVsdCA9ICh0aGlzICYmIHRoaXMuX19zZXRNb2R1bGVEZWZhdWx0KSB8fCAoT2JqZWN0LmNyZWF0ZSA/IChmdW5jdGlvbihvLCB2KSB7XFxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBcXFwiZGVmYXVsdFxcXCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgdmFsdWU6IHYgfSk7XFxufSkgOiBmdW5jdGlvbihvLCB2KSB7XFxuICAgIG9bXFxcImRlZmF1bHRcXFwiXSA9IHY7XFxufSk7XFxudmFyIF9faW1wb3J0U3RhciA9ICh0aGlzICYmIHRoaXMuX19pbXBvcnRTdGFyKSB8fCBmdW5jdGlvbiAobW9kKSB7XFxuICAgIGlmIChtb2QgJiYgbW9kLl9fZXNNb2R1bGUpIHJldHVybiBtb2Q7XFxuICAgIHZhciByZXN1bHQgPSB7fTtcXG4gICAgaWYgKG1vZCAhPSBudWxsKSBmb3IgKHZhciBrIGluIG1vZCkgaWYgKGsgIT09IFxcXCJkZWZhdWx0XFxcIiAmJiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobW9kLCBrKSkgX19jcmVhdGVCaW5kaW5nKHJlc3VsdCwgbW9kLCBrKTtcXG4gICAgX19zZXRNb2R1bGVEZWZhdWx0KHJlc3VsdCwgbW9kKTtcXG4gICAgcmV0dXJuIHJlc3VsdDtcXG59O1xcbnZhciBfX2ltcG9ydERlZmF1bHQgPSAodGhpcyAmJiB0aGlzLl9faW1wb3J0RGVmYXVsdCkgfHwgZnVuY3Rpb24gKG1vZCkge1xcbiAgICByZXR1cm4gKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgPyBtb2QgOiB7IFxcXCJkZWZhdWx0XFxcIjogbW9kIH07XFxufTtcXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXFxcIl9fZXNNb2R1bGVcXFwiLCAoeyB2YWx1ZTogdHJ1ZSB9KSk7XFxuZXhwb3J0cy5kaXNwb3NlID0gZXhwb3J0cy5nZXRJbnN0YW5jZSA9IGV4cG9ydHMuaW5pdGlhbGl6ZVdlYkFzc2VtYmx5ID0gdm9pZCAwO1xcbmNvbnN0IHBhdGggPSBfX2ltcG9ydFN0YXIoX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgcGF0aCAqLyBcXFwiPzdhYTVcXFwiKSk7XFxuY29uc3Qgb3J0X3dhc21fanNfMSA9IF9faW1wb3J0RGVmYXVsdChfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL2JpbmRpbmcvb3J0LXdhc20uanMgKi8gXFxcIi4vbGliL3dhc20vYmluZGluZy9vcnQtd2FzbS5qc1xcXCIpKTtcXG5jb25zdCBvcnRXYXNtRmFjdG9yeVRocmVhZGVkID0gXFxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZXF1aXJlLWltcG9ydHNcXG4gdHJ1ZSA/IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4vYmluZGluZy9vcnQtd2FzbS10aHJlYWRlZC5qcyAqLyBcXFwiLi9saWIvd2FzbS9iaW5kaW5nL29ydC13YXNtLXRocmVhZGVkLmpzXFxcIikgOiAwO1xcbmxldCB3YXNtO1xcbmxldCBpbml0aWFsaXplZCA9IGZhbHNlO1xcbmxldCBpbml0aWFsaXppbmcgPSBmYWxzZTtcXG5sZXQgYWJvcnRlZCA9IGZhbHNlO1xcbmNvbnN0IGlzTXVsdGlUaHJlYWRTdXBwb3J0ZWQgPSAoKSA9PiB7XFxuICAgIHRyeSB7XFxuICAgICAgICAvLyBJZiAnU2hhcmVkQXJyYXlCdWZmZXInIGlzIG5vdCBhdmFpbGFibGUsIFdlYkFzc2VtYmx5IHRocmVhZHMgd2lsbCBub3Qgd29yay5cXG4gICAgICAgIGlmICh0eXBlb2YgU2hhcmVkQXJyYXlCdWZmZXIgPT09ICd1bmRlZmluZWQnKSB7XFxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xcbiAgICAgICAgfVxcbiAgICAgICAgLy8gVGVzdCBmb3IgdHJhbnNmZXJhYmlsaXR5IG9mIFNBQnMgKGZvciBicm93c2Vycy4gbmVlZGVkIGZvciBGaXJlZm94KVxcbiAgICAgICAgLy8gaHR0cHM6Ly9ncm91cHMuZ29vZ2xlLmNvbS9mb3J1bS8jIW1zZy9tb3ppbGxhLmRldi5wbGF0Zm9ybS9JSGtCWmxIRVRwQS9kd3NNTmNoV0VRQUpcXG4gICAgICAgIGlmICh0eXBlb2YgTWVzc2FnZUNoYW5uZWwgIT09ICd1bmRlZmluZWQnKSB7XFxuICAgICAgICAgICAgbmV3IE1lc3NhZ2VDaGFubmVsKCkucG9ydDEucG9zdE1lc3NhZ2UobmV3IFNoYXJlZEFycmF5QnVmZmVyKDEpKTtcXG4gICAgICAgIH1cXG4gICAgICAgIC8vIFRlc3QgZm9yIFdlYkFzc2VtYmx5IHRocmVhZHMgY2FwYWJpbGl0eSAoZm9yIGJvdGggYnJvd3NlcnMgYW5kIE5vZGUuanMpXFxuICAgICAgICAvLyBUaGlzIHR5cGVkIGFycmF5IGlzIGEgV2ViQXNzZW1ibHkgcHJvZ3JhbSBjb250YWluaW5nIHRocmVhZGVkIGluc3RydWN0aW9ucy5cXG4gICAgICAgIHJldHVybiBXZWJBc3NlbWJseS52YWxpZGF0ZShuZXcgVWludDhBcnJheShbXFxuICAgICAgICAgICAgMCwgOTcsIDExNSwgMTA5LCAxLCAwLCAwLCAwLCAxLCA0LCAxLCA5NiwgMCwgMCwgMywgMiwgMSwgMCwgNSxcXG4gICAgICAgICAgICA0LCAxLCAzLCAxLCAxLCAxMCwgMTEsIDEsIDksIDAsIDY1LCAwLCAyNTQsIDE2LCAyLCAwLCAyNiwgMTFcXG4gICAgICAgIF0pKTtcXG4gICAgfVxcbiAgICBjYXRjaCAoZSkge1xcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xcbiAgICB9XFxufTtcXG5jb25zdCBpc1NpbWRTdXBwb3J0ZWQgPSAoKSA9PiB7XFxuICAgIHRyeSB7XFxuICAgICAgICAvLyBUZXN0IGZvciBXZWJBc3NlbWJseSBTSU1EIGNhcGFiaWxpdHkgKGZvciBib3RoIGJyb3dzZXJzIGFuZCBOb2RlLmpzKVxcbiAgICAgICAgLy8gVGhpcyB0eXBlZCBhcnJheSBpcyBhIFdlYkFzc2VtYmx5IHByb2dyYW0gY29udGFpbmluZyBTSU1EIGluc3RydWN0aW9ucy5cXG4gICAgICAgIC8vIFRoZSBiaW5hcnkgZGF0YSBpcyBnZW5lcmF0ZWQgZnJvbSB0aGUgZm9sbG93aW5nIGNvZGUgYnkgd2F0Mndhc206XFxuICAgICAgICAvL1xcbiAgICAgICAgLy8gKG1vZHVsZVxcbiAgICAgICAgLy8gICAodHlwZSAkdDAgKGZ1bmMpKVxcbiAgICAgICAgLy8gICAoZnVuYyAkZjAgKHR5cGUgJHQwKVxcbiAgICAgICAgLy8gICAgIChkcm9wXFxuICAgICAgICAvLyAgICAgICAoaTMyeDQuZG90X2kxNng4X3NcXG4gICAgICAgIC8vICAgICAgICAgKGk4eDE2LnNwbGF0XFxuICAgICAgICAvLyAgICAgICAgICAgKGkzMi5jb25zdCAwKSlcXG4gICAgICAgIC8vICAgICAgICAgKHYxMjguY29uc3QgaTMyeDQgMHgwMDAwMDAwMCAweDAwMDAwMDAwIDB4MDAwMDAwMDAgMHgwMDAwMDAwMCkpKSkpXFxuICAgICAgICByZXR1cm4gV2ViQXNzZW1ibHkudmFsaWRhdGUobmV3IFVpbnQ4QXJyYXkoW1xcbiAgICAgICAgICAgIDAsIDk3LCAxMTUsIDEwOSwgMSwgMCwgMCwgMCwgMSwgNCwgMSwgOTYsIDAsIDAsIDMsIDIsIDEsIDAsIDEwLCAzMCwgMSwgMjgsIDAsIDY1LCAwLFxcbiAgICAgICAgICAgIDI1MywgMTUsIDI1MywgMTIsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDI1MywgMTg2LCAxLCAyNiwgMTFcXG4gICAgICAgIF0pKTtcXG4gICAgfVxcbiAgICBjYXRjaCAoZSkge1xcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xcbiAgICB9XFxufTtcXG5jb25zdCBnZXRXYXNtRmlsZU5hbWUgPSAodXNlU2ltZCwgdXNlVGhyZWFkcykgPT4ge1xcbiAgICBpZiAodXNlVGhyZWFkcykge1xcbiAgICAgICAgcmV0dXJuIHVzZVNpbWQgPyAnb3J0LXdhc20tc2ltZC10aHJlYWRlZC53YXNtJyA6ICdvcnQtd2FzbS10aHJlYWRlZC53YXNtJztcXG4gICAgfVxcbiAgICBlbHNlIHtcXG4gICAgICAgIHJldHVybiB1c2VTaW1kID8gJ29ydC13YXNtLXNpbWQud2FzbScgOiAnb3J0LXdhc20ud2FzbSc7XFxuICAgIH1cXG59O1xcbmNvbnN0IGluaXRpYWxpemVXZWJBc3NlbWJseSA9IGFzeW5jIChmbGFncykgPT4ge1xcbiAgICBpZiAoaW5pdGlhbGl6ZWQpIHtcXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcXG4gICAgfVxcbiAgICBpZiAoaW5pdGlhbGl6aW5nKSB7XFxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ211bHRpcGxlIGNhbGxzIHRvIFxcXFwnaW5pdGlhbGl6ZVdlYkFzc2VtYmx5KClcXFxcJyBkZXRlY3RlZC4nKTtcXG4gICAgfVxcbiAgICBpZiAoYWJvcnRlZCkge1xcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdwcmV2aW91cyBjYWxsIHRvIFxcXFwnaW5pdGlhbGl6ZVdlYkFzc2VtYmx5KClcXFxcJyBmYWlsZWQuJyk7XFxuICAgIH1cXG4gICAgaW5pdGlhbGl6aW5nID0gdHJ1ZTtcXG4gICAgLy8gd2FzbSBmbGFncyBhcmUgYWxyZWFkeSBpbml0aWFsaXplZFxcbiAgICBjb25zdCB0aW1lb3V0ID0gZmxhZ3MuaW5pdFRpbWVvdXQ7XFxuICAgIGNvbnN0IG51bVRocmVhZHMgPSBmbGFncy5udW1UaHJlYWRzO1xcbiAgICBjb25zdCBzaW1kID0gZmxhZ3Muc2ltZDtcXG4gICAgY29uc3QgdXNlVGhyZWFkcyA9IG51bVRocmVhZHMgPiAxICYmIGlzTXVsdGlUaHJlYWRTdXBwb3J0ZWQoKTtcXG4gICAgY29uc3QgdXNlU2ltZCA9IHNpbWQgJiYgaXNTaW1kU3VwcG9ydGVkKCk7XFxuICAgIGNvbnN0IHdhc21QcmVmaXhPdmVycmlkZSA9IHR5cGVvZiBmbGFncy53YXNtUGF0aHMgPT09ICdzdHJpbmcnID8gZmxhZ3Mud2FzbVBhdGhzIDogdW5kZWZpbmVkO1xcbiAgICBjb25zdCB3YXNtRmlsZU5hbWUgPSBnZXRXYXNtRmlsZU5hbWUoZmFsc2UsIHVzZVRocmVhZHMpO1xcbiAgICBjb25zdCB3YXNtT3ZlcnJpZGVGaWxlTmFtZSA9IGdldFdhc21GaWxlTmFtZSh1c2VTaW1kLCB1c2VUaHJlYWRzKTtcXG4gICAgY29uc3Qgd2FzbVBhdGhPdmVycmlkZSA9IHR5cGVvZiBmbGFncy53YXNtUGF0aHMgPT09ICdvYmplY3QnID8gZmxhZ3Mud2FzbVBhdGhzW3dhc21PdmVycmlkZUZpbGVOYW1lXSA6IHVuZGVmaW5lZDtcXG4gICAgbGV0IGlzVGltZW91dCA9IGZhbHNlO1xcbiAgICBjb25zdCB0YXNrcyA9IFtdO1xcbiAgICAvLyBwcm9taXNlIGZvciB0aW1lb3V0XFxuICAgIGlmICh0aW1lb3V0ID4gMCkge1xcbiAgICAgICAgdGFza3MucHVzaChuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xcbiAgICAgICAgICAgICAgICBpc1RpbWVvdXQgPSB0cnVlO1xcbiAgICAgICAgICAgICAgICByZXNvbHZlKCk7XFxuICAgICAgICAgICAgfSwgdGltZW91dCk7XFxuICAgICAgICB9KSk7XFxuICAgIH1cXG4gICAgLy8gcHJvbWlzZSBmb3IgbW9kdWxlIGluaXRpYWxpemF0aW9uXFxuICAgIHRhc2tzLnB1c2gobmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xcbiAgICAgICAgY29uc3QgZmFjdG9yeSA9IHVzZVRocmVhZHMgPyBvcnRXYXNtRmFjdG9yeVRocmVhZGVkIDogb3J0X3dhc21fanNfMS5kZWZhdWx0O1xcbiAgICAgICAgY29uc3QgY29uZmlnID0ge1xcbiAgICAgICAgICAgIGxvY2F0ZUZpbGU6IChmaWxlTmFtZSwgc2NyaXB0RGlyZWN0b3J5KSA9PiB7XFxuICAgICAgICAgICAgICAgIGlmICggdHJ1ZSAmJiB1c2VUaHJlYWRzICYmIGZpbGVOYW1lLmVuZHNXaXRoKCcud29ya2VyLmpzJykgJiZcXG4gICAgICAgICAgICAgICAgICAgIHR5cGVvZiBCbG9iICE9PSAndW5kZWZpbmVkJykge1xcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFVSTC5jcmVhdGVPYmplY3RVUkwobmV3IEJsb2IoW1xcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgcmVxdWlyZSgpIGZ1bmN0aW9uIGlzIGhhbmRsZWQgYnkgd2VicGFjayB0byBsb2FkIGZpbGUgY29udGVudCBvZiB0aGUgY29ycmVzcG9uZGluZyAud29ya2VyLmpzXFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZXF1aXJlLWltcG9ydHNcXG4gICAgICAgICAgICAgICAgICAgICAgICBfX3dlYnBhY2tfcmVxdWlyZV9fKC8qISAuL2JpbmRpbmcvb3J0LXdhc20tdGhyZWFkZWQud29ya2VyLmpzICovIFxcXCIuL2xpYi93YXNtL2JpbmRpbmcvb3J0LXdhc20tdGhyZWFkZWQud29ya2VyLmpzXFxcIilcXG4gICAgICAgICAgICAgICAgICAgIF0sIHsgdHlwZTogJ3RleHQvamF2YXNjcmlwdCcgfSkpO1xcbiAgICAgICAgICAgICAgICB9XFxuICAgICAgICAgICAgICAgIGlmIChmaWxlTmFtZSA9PT0gd2FzbUZpbGVOYW1lKSB7XFxuICAgICAgICAgICAgICAgICAgICBjb25zdCBwcmVmaXggPSB3YXNtUHJlZml4T3ZlcnJpZGUgIT09IG51bGwgJiYgd2FzbVByZWZpeE92ZXJyaWRlICE9PSB2b2lkIDAgPyB3YXNtUHJlZml4T3ZlcnJpZGUgOiBzY3JpcHREaXJlY3Rvcnk7XFxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gd2FzbVBhdGhPdmVycmlkZSAhPT0gbnVsbCAmJiB3YXNtUGF0aE92ZXJyaWRlICE9PSB2b2lkIDAgPyB3YXNtUGF0aE92ZXJyaWRlIDogcHJlZml4ICsgd2FzbU92ZXJyaWRlRmlsZU5hbWU7XFxuICAgICAgICAgICAgICAgIH1cXG4gICAgICAgICAgICAgICAgcmV0dXJuIHNjcmlwdERpcmVjdG9yeSArIGZpbGVOYW1lO1xcbiAgICAgICAgICAgIH1cXG4gICAgICAgIH07XFxuICAgICAgICBpZiAoIHRydWUgJiYgdXNlVGhyZWFkcykge1xcbiAgICAgICAgICAgIGlmICh0eXBlb2YgQmxvYiA9PT0gJ3VuZGVmaW5lZCcpIHtcXG4gICAgICAgICAgICAgICAgY29uZmlnLm1haW5TY3JpcHRVcmxPckJsb2IgPSBwYXRoLmpvaW4oX19kaXJuYW1lLCAnb3J0LXdhc20tdGhyZWFkZWQuanMnKTtcXG4gICAgICAgICAgICB9XFxuICAgICAgICAgICAgZWxzZSB7XFxuICAgICAgICAgICAgICAgIGNvbnN0IHNjcmlwdFNvdXJjZUNvZGUgPSBgdmFyIG9ydFdhc21UaHJlYWRlZD0oZnVuY3Rpb24oKXt2YXIgX3NjcmlwdERpcjtyZXR1cm4gJHtmYWN0b3J5LnRvU3RyaW5nKCl9fSkoKTtgO1xcbiAgICAgICAgICAgICAgICBjb25maWcubWFpblNjcmlwdFVybE9yQmxvYiA9IG5ldyBCbG9iKFtzY3JpcHRTb3VyY2VDb2RlXSwgeyB0eXBlOiAndGV4dC9qYXZhc2NyaXB0JyB9KTtcXG4gICAgICAgICAgICB9XFxuICAgICAgICB9XFxuICAgICAgICBmYWN0b3J5KGNvbmZpZykudGhlbihcXG4gICAgICAgIC8vIHdhc20gbW9kdWxlIGluaXRpYWxpemVkIHN1Y2Nlc3NmdWxseVxcbiAgICAgICAgbW9kdWxlID0+IHtcXG4gICAgICAgICAgICBpbml0aWFsaXppbmcgPSBmYWxzZTtcXG4gICAgICAgICAgICBpbml0aWFsaXplZCA9IHRydWU7XFxuICAgICAgICAgICAgd2FzbSA9IG1vZHVsZTtcXG4gICAgICAgICAgICByZXNvbHZlKCk7XFxuICAgICAgICB9LCBcXG4gICAgICAgIC8vIHdhc20gbW9kdWxlIGZhaWxlZCB0byBpbml0aWFsaXplXFxuICAgICAgICAod2hhdCkgPT4ge1xcbiAgICAgICAgICAgIGluaXRpYWxpemluZyA9IGZhbHNlO1xcbiAgICAgICAgICAgIGFib3J0ZWQgPSB0cnVlO1xcbiAgICAgICAgICAgIHJlamVjdCh3aGF0KTtcXG4gICAgICAgIH0pO1xcbiAgICB9KSk7XFxuICAgIGF3YWl0IFByb21pc2UucmFjZSh0YXNrcyk7XFxuICAgIGlmIChpc1RpbWVvdXQpIHtcXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgV2ViQXNzZW1ibHkgYmFja2VuZCBpbml0aWFsaXppbmcgZmFpbGVkIGR1ZSB0byB0aW1lb3V0OiAke3RpbWVvdXR9bXNgKTtcXG4gICAgfVxcbn07XFxuZXhwb3J0cy5pbml0aWFsaXplV2ViQXNzZW1ibHkgPSBpbml0aWFsaXplV2ViQXNzZW1ibHk7XFxuY29uc3QgZ2V0SW5zdGFuY2UgPSAoKSA9PiB7XFxuICAgIGlmIChpbml0aWFsaXplZCAmJiB3YXNtKSB7XFxuICAgICAgICByZXR1cm4gd2FzbTtcXG4gICAgfVxcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1dlYkFzc2VtYmx5IGlzIG5vdCBpbml0aWFsaXplZCB5ZXQuJyk7XFxufTtcXG5leHBvcnRzLmdldEluc3RhbmNlID0gZ2V0SW5zdGFuY2U7XFxuY29uc3QgZGlzcG9zZSA9ICgpID0+IHtcXG4gICAgdmFyIF9hO1xcbiAgICBpZiAoaW5pdGlhbGl6ZWQgJiYgIWluaXRpYWxpemluZyAmJiAhYWJvcnRlZCkge1xcbiAgICAgICAgaW5pdGlhbGl6aW5nID0gdHJ1ZTtcXG4gICAgICAgIChfYSA9IHdhc20uUFRocmVhZCkgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLnRlcm1pbmF0ZUFsbFRocmVhZHMoKTtcXG4gICAgICAgIHdhc20gPSB1bmRlZmluZWQ7XFxuICAgICAgICBpbml0aWFsaXppbmcgPSBmYWxzZTtcXG4gICAgICAgIGluaXRpYWxpemVkID0gZmFsc2U7XFxuICAgICAgICBhYm9ydGVkID0gdHJ1ZTtcXG4gICAgfVxcbn07XFxuZXhwb3J0cy5kaXNwb3NlID0gZGlzcG9zZTtcXG5cXG5cXG4vKioqLyB9KSxcXG5cXG4vKioqLyBcXFwiLi9saWIvd2FzbS9iaW5kaW5nL29ydC13YXNtLXRocmVhZGVkLndvcmtlci5qc1xcXCI6XFxuLyohKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxcXFxuICAhKioqIC4vbGliL3dhc20vYmluZGluZy9vcnQtd2FzbS10aHJlYWRlZC53b3JrZXIuanMgKioqIVxcbiAgXFxcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cXG4vKioqLyAoKG1vZHVsZSkgPT4ge1xcblxcblxcXCJ1c2Ugc3RyaWN0XFxcIjtcXG5tb2R1bGUuZXhwb3J0cyA9IFxcXCJcXFxcXFxcInVzZSBzdHJpY3RcXFxcXFxcIjt2YXIgTW9kdWxlPXt9O3ZhciBFTlZJUk9OTUVOVF9JU19OT0RFPXR5cGVvZiBwcm9jZXNzPT1cXFxcXFxcIm9iamVjdFxcXFxcXFwiJiZ0eXBlb2YgcHJvY2Vzcy52ZXJzaW9ucz09XFxcXFxcXCJvYmplY3RcXFxcXFxcIiYmdHlwZW9mIHByb2Nlc3MudmVyc2lvbnMubm9kZT09XFxcXFxcXCJzdHJpbmdcXFxcXFxcIjtpZihFTlZJUk9OTUVOVF9JU19OT0RFKXt2YXIgbm9kZVdvcmtlclRocmVhZHM9cmVxdWlyZShcXFxcXFxcIndvcmtlcl90aHJlYWRzXFxcXFxcXCIpO3ZhciBwYXJlbnRQb3J0PW5vZGVXb3JrZXJUaHJlYWRzLnBhcmVudFBvcnQ7cGFyZW50UG9ydC5vbihcXFxcXFxcIm1lc3NhZ2VcXFxcXFxcIixkYXRhPT5vbm1lc3NhZ2Uoe2RhdGE6ZGF0YX0pKTt2YXIgZnM9cmVxdWlyZShcXFxcXFxcImZzXFxcXFxcXCIpO09iamVjdC5hc3NpZ24oZ2xvYmFsLHtzZWxmOmdsb2JhbCxyZXF1aXJlOnJlcXVpcmUsTW9kdWxlOk1vZHVsZSxsb2NhdGlvbjp7aHJlZjpfX2ZpbGVuYW1lfSxXb3JrZXI6bm9kZVdvcmtlclRocmVhZHMuV29ya2VyLGltcG9ydFNjcmlwdHM6ZnVuY3Rpb24oZil7KDAsZXZhbCkoZnMucmVhZEZpbGVTeW5jKGYsXFxcXFxcXCJ1dGY4XFxcXFxcXCIpKX0scG9zdE1lc3NhZ2U6ZnVuY3Rpb24obXNnKXtwYXJlbnRQb3J0LnBvc3RNZXNzYWdlKG1zZyl9LHBlcmZvcm1hbmNlOmdsb2JhbC5wZXJmb3JtYW5jZXx8e25vdzpmdW5jdGlvbigpe3JldHVybiBEYXRlLm5vdygpfX19KX12YXIgaW5pdGlhbGl6ZWRKUz1mYWxzZTt2YXIgcGVuZGluZ05vdGlmaWVkUHJveHlpbmdRdWV1ZXM9W107ZnVuY3Rpb24gdGhyZWFkUHJpbnRFcnIoKXt2YXIgdGV4dD1BcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpLmpvaW4oXFxcXFxcXCIgXFxcXFxcXCIpO2lmKEVOVklST05NRU5UX0lTX05PREUpe2ZzLndyaXRlU3luYygyLHRleHQrXFxcXFxcXCJcXFxcXFxcXG5cXFxcXFxcIik7cmV0dXJufWNvbnNvbGUuZXJyb3IodGV4dCl9ZnVuY3Rpb24gdGhyZWFkQWxlcnQoKXt2YXIgdGV4dD1BcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpLmpvaW4oXFxcXFxcXCIgXFxcXFxcXCIpO3Bvc3RNZXNzYWdlKHtjbWQ6XFxcXFxcXCJhbGVydFxcXFxcXFwiLHRleHQ6dGV4dCx0aHJlYWRJZDpNb2R1bGVbXFxcXFxcXCJfcHRocmVhZF9zZWxmXFxcXFxcXCJdKCl9KX12YXIgZXJyPXRocmVhZFByaW50RXJyO3NlbGYuYWxlcnQ9dGhyZWFkQWxlcnQ7TW9kdWxlW1xcXFxcXFwiaW5zdGFudGlhdGVXYXNtXFxcXFxcXCJdPShpbmZvLHJlY2VpdmVJbnN0YW5jZSk9Pnt2YXIgaW5zdGFuY2U9bmV3IFdlYkFzc2VtYmx5Lkluc3RhbmNlKE1vZHVsZVtcXFxcXFxcIndhc21Nb2R1bGVcXFxcXFxcIl0saW5mbyk7cmVjZWl2ZUluc3RhbmNlKGluc3RhbmNlKTtNb2R1bGVbXFxcXFxcXCJ3YXNtTW9kdWxlXFxcXFxcXCJdPW51bGw7cmV0dXJuIGluc3RhbmNlLmV4cG9ydHN9O3NlbGYub251bmhhbmRsZWRyZWplY3Rpb249ZT0+e3Rocm93IGUucmVhc29uPz9lfTtzZWxmLm9ubWVzc2FnZT1lPT57dHJ5e2lmKGUuZGF0YS5jbWQ9PT1cXFxcXFxcImxvYWRcXFxcXFxcIil7TW9kdWxlW1xcXFxcXFwid2FzbU1vZHVsZVxcXFxcXFwiXT1lLmRhdGEud2FzbU1vZHVsZTtNb2R1bGVbXFxcXFxcXCJ3YXNtTWVtb3J5XFxcXFxcXCJdPWUuZGF0YS53YXNtTWVtb3J5O01vZHVsZVtcXFxcXFxcImJ1ZmZlclxcXFxcXFwiXT1Nb2R1bGVbXFxcXFxcXCJ3YXNtTWVtb3J5XFxcXFxcXCJdLmJ1ZmZlcjtNb2R1bGVbXFxcXFxcXCJFTlZJUk9OTUVOVF9JU19QVEhSRUFEXFxcXFxcXCJdPXRydWU7aWYodHlwZW9mIGUuZGF0YS51cmxPckJsb2I9PVxcXFxcXFwic3RyaW5nXFxcXFxcXCIpe2ltcG9ydFNjcmlwdHMoZS5kYXRhLnVybE9yQmxvYil9ZWxzZXt2YXIgb2JqZWN0VXJsPVVSTC5jcmVhdGVPYmplY3RVUkwoZS5kYXRhLnVybE9yQmxvYik7aW1wb3J0U2NyaXB0cyhvYmplY3RVcmwpO1VSTC5yZXZva2VPYmplY3RVUkwob2JqZWN0VXJsKX1vcnRXYXNtVGhyZWFkZWQoTW9kdWxlKS50aGVuKGZ1bmN0aW9uKGluc3RhbmNlKXtNb2R1bGU9aW5zdGFuY2V9KX1lbHNlIGlmKGUuZGF0YS5jbWQ9PT1cXFxcXFxcInJ1blxcXFxcXFwiKXtNb2R1bGVbXFxcXFxcXCJfX3BlcmZvcm1hbmNlX25vd19jbG9ja19kcmlmdFxcXFxcXFwiXT1wZXJmb3JtYW5jZS5ub3coKS1lLmRhdGEudGltZTtNb2R1bGVbXFxcXFxcXCJfX2Vtc2NyaXB0ZW5fdGhyZWFkX2luaXRcXFxcXFxcIl0oZS5kYXRhLnB0aHJlYWRfcHRyLC8qaXNNYWluQnJvd3NlclRocmVhZD0qLzAsLyppc01haW5SdW50aW1lVGhyZWFkPSovMCwvKmNhbkJsb2NrPSovMSk7TW9kdWxlW1xcXFxcXFwiZXN0YWJsaXNoU3RhY2tTcGFjZVxcXFxcXFwiXSgpO01vZHVsZVtcXFxcXFxcIlBUaHJlYWRcXFxcXFxcIl0ucmVjZWl2ZU9iamVjdFRyYW5zZmVyKGUuZGF0YSk7TW9kdWxlW1xcXFxcXFwiUFRocmVhZFxcXFxcXFwiXS50aHJlYWRJbml0VExTKCk7aWYoIWluaXRpYWxpemVkSlMpe3BlbmRpbmdOb3RpZmllZFByb3h5aW5nUXVldWVzLmZvckVhY2gocXVldWU9PntNb2R1bGVbXFxcXFxcXCJleGVjdXRlTm90aWZpZWRQcm94eWluZ1F1ZXVlXFxcXFxcXCJdKHF1ZXVlKX0pO3BlbmRpbmdOb3RpZmllZFByb3h5aW5nUXVldWVzPVtdO2luaXRpYWxpemVkSlM9dHJ1ZX10cnl7TW9kdWxlW1xcXFxcXFwiaW52b2tlRW50cnlQb2ludFxcXFxcXFwiXShlLmRhdGEuc3RhcnRfcm91dGluZSxlLmRhdGEuYXJnKX1jYXRjaChleCl7aWYoZXghPVxcXFxcXFwidW53aW5kXFxcXFxcXCIpe2lmKGV4IGluc3RhbmNlb2YgTW9kdWxlW1xcXFxcXFwiRXhpdFN0YXR1c1xcXFxcXFwiXSl7aWYoTW9kdWxlW1xcXFxcXFwia2VlcFJ1bnRpbWVBbGl2ZVxcXFxcXFwiXSgpKXt9ZWxzZXtNb2R1bGVbXFxcXFxcXCJfX2Vtc2NyaXB0ZW5fdGhyZWFkX2V4aXRcXFxcXFxcIl0oZXguc3RhdHVzKX19ZWxzZXt0aHJvdyBleH19fX1lbHNlIGlmKGUuZGF0YS5jbWQ9PT1cXFxcXFxcImNhbmNlbFxcXFxcXFwiKXtpZihNb2R1bGVbXFxcXFxcXCJfcHRocmVhZF9zZWxmXFxcXFxcXCJdKCkpe01vZHVsZVtcXFxcXFxcIl9fZW1zY3JpcHRlbl90aHJlYWRfZXhpdFxcXFxcXFwiXSgtMSl9fWVsc2UgaWYoZS5kYXRhLnRhcmdldD09PVxcXFxcXFwic2V0aW1tZWRpYXRlXFxcXFxcXCIpe31lbHNlIGlmKGUuZGF0YS5jbWQ9PT1cXFxcXFxcInByb2Nlc3NQcm94eWluZ1F1ZXVlXFxcXFxcXCIpe2lmKGluaXRpYWxpemVkSlMpe01vZHVsZVtcXFxcXFxcImV4ZWN1dGVOb3RpZmllZFByb3h5aW5nUXVldWVcXFxcXFxcIl0oZS5kYXRhLnF1ZXVlKX1lbHNle3BlbmRpbmdOb3RpZmllZFByb3h5aW5nUXVldWVzLnB1c2goZS5kYXRhLnF1ZXVlKX19ZWxzZXtlcnIoXFxcXFxcXCJ3b3JrZXIuanMgcmVjZWl2ZWQgdW5rbm93biBjb21tYW5kIFxcXFxcXFwiK2UuZGF0YS5jbWQpO2VycihlLmRhdGEpfX1jYXRjaChleCl7ZXJyKFxcXFxcXFwid29ya2VyLmpzIG9ubWVzc2FnZSgpIGNhcHR1cmVkIGFuIHVuY2F1Z2h0IGV4Y2VwdGlvbjogXFxcXFxcXCIrZXgpO2lmKGV4JiZleC5zdGFjayllcnIoZXguc3RhY2spO2lmKE1vZHVsZVtcXFxcXFxcIl9fZW1zY3JpcHRlbl90aHJlYWRfY3Jhc2hlZFxcXFxcXFwiXSl7TW9kdWxlW1xcXFxcXFwiX19lbXNjcmlwdGVuX3RocmVhZF9jcmFzaGVkXFxcXFxcXCJdKCl9dGhyb3cgZXh9fTtcXFxcclxcXFxuXFxcIjtcXG5cXG4vKioqLyB9KSxcXG5cXG4vKioqLyBcXFwiPzYzYzhcXFwiOlxcbi8qISoqKioqKioqKioqKioqKioqKioqISpcXFxcXFxuICAhKioqIGZzIChpZ25vcmVkKSAqKiohXFxuICBcXFxcKioqKioqKioqKioqKioqKioqKiovXFxuLyoqKi8gKCgpID0+IHtcXG5cXG4vKiAoaWdub3JlZCkgKi9cXG5cXG4vKioqLyB9KSxcXG5cXG4vKioqLyBcXFwiP2FlZGJcXFwiOlxcbi8qISoqKioqKioqKioqKioqKioqKioqISpcXFxcXFxuICAhKioqIG9zIChpZ25vcmVkKSAqKiohXFxuICBcXFxcKioqKioqKioqKioqKioqKioqKiovXFxuLyoqKi8gKCgpID0+IHtcXG5cXG4vKiAoaWdub3JlZCkgKi9cXG5cXG4vKioqLyB9KSxcXG5cXG4vKioqLyBcXFwiPzc1YzZcXFwiOlxcbi8qISoqKioqKioqKioqKioqKioqKioqKiohKlxcXFxcXG4gICEqKiogcGF0aCAoaWdub3JlZCkgKioqIVxcbiAgXFxcXCoqKioqKioqKioqKioqKioqKioqKiovXFxuLyoqKi8gKCgpID0+IHtcXG5cXG4vKiAoaWdub3JlZCkgKi9cXG5cXG4vKioqLyB9KSxcXG5cXG4vKioqLyBcXFwiPzY3NGZcXFwiOlxcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKiohKlxcXFxcXG4gICEqKiogcGVyZl9ob29rcyAoaWdub3JlZCkgKioqIVxcbiAgXFxcXCoqKioqKioqKioqKioqKioqKioqKioqKioqKiovXFxuLyoqKi8gKCgpID0+IHtcXG5cXG4vKiAoaWdub3JlZCkgKi9cXG5cXG4vKioqLyB9KSxcXG5cXG4vKioqLyBcXFwiP2M2ZjdcXFwiOlxcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxcXFxuICAhKioqIHdvcmtlcl90aHJlYWRzIChpZ25vcmVkKSAqKiohXFxuICBcXFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXFxuLyoqKi8gKCgpID0+IHtcXG5cXG4vKiAoaWdub3JlZCkgKi9cXG5cXG4vKioqLyB9KSxcXG5cXG4vKioqLyBcXFwiPzdhYTVcXFwiOlxcbi8qISoqKioqKioqKioqKioqKioqKioqKiohKlxcXFxcXG4gICEqKiogcGF0aCAoaWdub3JlZCkgKioqIVxcbiAgXFxcXCoqKioqKioqKioqKioqKioqKioqKiovXFxuLyoqKi8gKCgpID0+IHtcXG5cXG4vKiAoaWdub3JlZCkgKi9cXG5cXG4vKioqLyB9KVxcblxcbi8qKioqKiovIFxcdH0pO1xcbi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXFxuLyoqKioqKi8gXFx0Ly8gVGhlIG1vZHVsZSBjYWNoZVxcbi8qKioqKiovIFxcdHZhciBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX18gPSB7fTtcXG4vKioqKioqLyBcXHRcXG4vKioqKioqLyBcXHQvLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxcbi8qKioqKiovIFxcdGZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHtcXG4vKioqKioqLyBcXHRcXHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcXG4vKioqKioqLyBcXHRcXHR2YXIgY2FjaGVkTW9kdWxlID0gX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fW21vZHVsZUlkXTtcXG4vKioqKioqLyBcXHRcXHRpZiAoY2FjaGVkTW9kdWxlICE9PSB1bmRlZmluZWQpIHtcXG4vKioqKioqLyBcXHRcXHRcXHRyZXR1cm4gY2FjaGVkTW9kdWxlLmV4cG9ydHM7XFxuLyoqKioqKi8gXFx0XFx0fVxcbi8qKioqKiovIFxcdFxcdC8vIENyZWF0ZSBhIG5ldyBtb2R1bGUgKGFuZCBwdXQgaXQgaW50byB0aGUgY2FjaGUpXFxuLyoqKioqKi8gXFx0XFx0dmFyIG1vZHVsZSA9IF9fd2VicGFja19tb2R1bGVfY2FjaGVfX1ttb2R1bGVJZF0gPSB7XFxuLyoqKioqKi8gXFx0XFx0XFx0Ly8gbm8gbW9kdWxlLmlkIG5lZWRlZFxcbi8qKioqKiovIFxcdFxcdFxcdC8vIG5vIG1vZHVsZS5sb2FkZWQgbmVlZGVkXFxuLyoqKioqKi8gXFx0XFx0XFx0ZXhwb3J0czoge31cXG4vKioqKioqLyBcXHRcXHR9O1xcbi8qKioqKiovIFxcdFxcbi8qKioqKiovIFxcdFxcdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxcbi8qKioqKiovIFxcdFxcdF9fd2VicGFja19tb2R1bGVzX19bbW9kdWxlSWRdLmNhbGwobW9kdWxlLmV4cG9ydHMsIG1vZHVsZSwgbW9kdWxlLmV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pO1xcbi8qKioqKiovIFxcdFxcbi8qKioqKiovIFxcdFxcdC8vIFJldHVybiB0aGUgZXhwb3J0cyBvZiB0aGUgbW9kdWxlXFxuLyoqKioqKi8gXFx0XFx0cmV0dXJuIG1vZHVsZS5leHBvcnRzO1xcbi8qKioqKiovIFxcdH1cXG4vKioqKioqLyBcXHRcXG4vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xcbi8qKioqKiovIFxcdC8qIHdlYnBhY2svcnVudGltZS9nbG9iYWwgKi9cXG4vKioqKioqLyBcXHQoKCkgPT4ge1xcbi8qKioqKiovIFxcdFxcdF9fd2VicGFja19yZXF1aXJlX18uZyA9IChmdW5jdGlvbigpIHtcXG4vKioqKioqLyBcXHRcXHRcXHRpZiAodHlwZW9mIGdsb2JhbFRoaXMgPT09ICdvYmplY3QnKSByZXR1cm4gZ2xvYmFsVGhpcztcXG4vKioqKioqLyBcXHRcXHRcXHR0cnkge1xcbi8qKioqKiovIFxcdFxcdFxcdFxcdHJldHVybiB0aGlzIHx8IG5ldyBGdW5jdGlvbigncmV0dXJuIHRoaXMnKSgpO1xcbi8qKioqKiovIFxcdFxcdFxcdH0gY2F0Y2ggKGUpIHtcXG4vKioqKioqLyBcXHRcXHRcXHRcXHRpZiAodHlwZW9mIHdpbmRvdyA9PT0gJ29iamVjdCcpIHJldHVybiB3aW5kb3c7XFxuLyoqKioqKi8gXFx0XFx0XFx0fVxcbi8qKioqKiovIFxcdFxcdH0pKCk7XFxuLyoqKioqKi8gXFx0fSkoKTtcXG4vKioqKioqLyBcXHRcXG4vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xcbnZhciBfX3dlYnBhY2tfZXhwb3J0c19fID0ge307XFxuLy8gVGhpcyBlbnRyeSBuZWVkIHRvIGJlIHdyYXBwZWQgaW4gYW4gSUlGRSBiZWNhdXNlIGl0IG5lZWQgdG8gYmUgaW4gc3RyaWN0IG1vZGUuXFxuKCgpID0+IHtcXG5cXFwidXNlIHN0cmljdFxcXCI7XFxudmFyIGV4cG9ydHMgPSBfX3dlYnBhY2tfZXhwb3J0c19fO1xcbi8qISoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqISpcXFxcXFxuICAhKioqIC4vbm9kZV9tb2R1bGVzL3RzLWxvYWRlci9pbmRleC5qcz8/cnVsZVNldFsxXS5ydWxlc1swXS51c2VbMF0hLi9saWIvd2FzbS9wcm94eS13b3JrZXIvbWFpbi50cyAqKiohXFxuICBcXFxcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXFxuXFxuLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXFxuLy8gTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcXFwiX19lc01vZHVsZVxcXCIsICh7IHZhbHVlOiB0cnVlIH0pKTtcXG5jb25zdCB3YXNtX2NvcmVfaW1wbF8xID0gX193ZWJwYWNrX3JlcXVpcmVfXygvKiEgLi4vd2FzbS1jb3JlLWltcGwgKi8gXFxcIi4vbGliL3dhc20vd2FzbS1jb3JlLWltcGwudHNcXFwiKTtcXG5jb25zdCB3YXNtX2ZhY3RvcnlfMSA9IF9fd2VicGFja19yZXF1aXJlX18oLyohIC4uL3dhc20tZmFjdG9yeSAqLyBcXFwiLi9saWIvd2FzbS93YXNtLWZhY3RvcnkudHNcXFwiKTtcXG5zZWxmLm9ubWVzc2FnZSA9IChldikgPT4ge1xcbiAgICBzd2l0Y2ggKGV2LmRhdGEudHlwZSkge1xcbiAgICAgICAgY2FzZSAnaW5pdC13YXNtJzpcXG4gICAgICAgICAgICAoMCwgd2FzbV9mYWN0b3J5XzEuaW5pdGlhbGl6ZVdlYkFzc2VtYmx5KShldi5kYXRhLmluKVxcbiAgICAgICAgICAgICAgICAudGhlbigoKSA9PiBwb3N0TWVzc2FnZSh7IHR5cGU6ICdpbml0LXdhc20nIH0pLCBlcnIgPT4gcG9zdE1lc3NhZ2UoeyB0eXBlOiAnaW5pdC13YXNtJywgZXJyIH0pKTtcXG4gICAgICAgICAgICBicmVhaztcXG4gICAgICAgIGNhc2UgJ2luaXQtb3J0JzpcXG4gICAgICAgICAgICB0cnkge1xcbiAgICAgICAgICAgICAgICBjb25zdCB7IG51bVRocmVhZHMsIGxvZ2dpbmdMZXZlbCB9ID0gZXYuZGF0YS5pbjtcXG4gICAgICAgICAgICAgICAgKDAsIHdhc21fY29yZV9pbXBsXzEuaW5pdE9ydCkobnVtVGhyZWFkcywgbG9nZ2luZ0xldmVsKTtcXG4gICAgICAgICAgICAgICAgcG9zdE1lc3NhZ2UoeyB0eXBlOiAnaW5pdC1vcnQnIH0pO1xcbiAgICAgICAgICAgIH1cXG4gICAgICAgICAgICBjYXRjaCAoZXJyKSB7XFxuICAgICAgICAgICAgICAgIHBvc3RNZXNzYWdlKHsgdHlwZTogJ2luaXQtb3J0JywgZXJyIH0pO1xcbiAgICAgICAgICAgIH1cXG4gICAgICAgICAgICBicmVhaztcXG4gICAgICAgIGNhc2UgJ2NyZWF0ZV9hbGxvY2F0ZSc6XFxuICAgICAgICAgICAgdHJ5IHtcXG4gICAgICAgICAgICAgICAgY29uc3QgeyBtb2RlbCB9ID0gZXYuZGF0YS5pbjtcXG4gICAgICAgICAgICAgICAgY29uc3QgbW9kZWxkYXRhID0gKDAsIHdhc21fY29yZV9pbXBsXzEuY3JlYXRlU2Vzc2lvbkFsbG9jYXRlKShtb2RlbCk7XFxuICAgICAgICAgICAgICAgIHBvc3RNZXNzYWdlKHsgdHlwZTogJ2NyZWF0ZV9hbGxvY2F0ZScsIG91dDogbW9kZWxkYXRhIH0pO1xcbiAgICAgICAgICAgIH1cXG4gICAgICAgICAgICBjYXRjaCAoZXJyKSB7XFxuICAgICAgICAgICAgICAgIHBvc3RNZXNzYWdlKHsgdHlwZTogJ2NyZWF0ZV9hbGxvY2F0ZScsIGVyciB9KTtcXG4gICAgICAgICAgICB9XFxuICAgICAgICAgICAgYnJlYWs7XFxuICAgICAgICBjYXNlICdjcmVhdGVfZmluYWxpemUnOlxcbiAgICAgICAgICAgIHRyeSB7XFxuICAgICAgICAgICAgICAgIGNvbnN0IHsgbW9kZWxkYXRhLCBvcHRpb25zIH0gPSBldi5kYXRhLmluO1xcbiAgICAgICAgICAgICAgICBjb25zdCBzZXNzaW9uTWV0YWRhdGEgPSAoMCwgd2FzbV9jb3JlX2ltcGxfMS5jcmVhdGVTZXNzaW9uRmluYWxpemUpKG1vZGVsZGF0YSwgb3B0aW9ucyk7XFxuICAgICAgICAgICAgICAgIHBvc3RNZXNzYWdlKHsgdHlwZTogJ2NyZWF0ZV9maW5hbGl6ZScsIG91dDogc2Vzc2lvbk1ldGFkYXRhIH0pO1xcbiAgICAgICAgICAgIH1cXG4gICAgICAgICAgICBjYXRjaCAoZXJyKSB7XFxuICAgICAgICAgICAgICAgIHBvc3RNZXNzYWdlKHsgdHlwZTogJ2NyZWF0ZV9maW5hbGl6ZScsIGVyciB9KTtcXG4gICAgICAgICAgICB9XFxuICAgICAgICAgICAgYnJlYWs7XFxuICAgICAgICBjYXNlICdjcmVhdGUnOlxcbiAgICAgICAgICAgIHRyeSB7XFxuICAgICAgICAgICAgICAgIGNvbnN0IHsgbW9kZWwsIG9wdGlvbnMgfSA9IGV2LmRhdGEuaW47XFxuICAgICAgICAgICAgICAgIGNvbnN0IHNlc3Npb25NZXRhZGF0YSA9ICgwLCB3YXNtX2NvcmVfaW1wbF8xLmNyZWF0ZVNlc3Npb24pKG1vZGVsLCBvcHRpb25zKTtcXG4gICAgICAgICAgICAgICAgcG9zdE1lc3NhZ2UoeyB0eXBlOiAnY3JlYXRlJywgb3V0OiBzZXNzaW9uTWV0YWRhdGEgfSk7XFxuICAgICAgICAgICAgfVxcbiAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcXG4gICAgICAgICAgICAgICAgcG9zdE1lc3NhZ2UoeyB0eXBlOiAnY3JlYXRlJywgZXJyIH0pO1xcbiAgICAgICAgICAgIH1cXG4gICAgICAgICAgICBicmVhaztcXG4gICAgICAgIGNhc2UgJ3JlbGVhc2UnOlxcbiAgICAgICAgICAgIHRyeSB7XFxuICAgICAgICAgICAgICAgIGNvbnN0IGhhbmRsZXIgPSBldi5kYXRhLmluO1xcbiAgICAgICAgICAgICAgICAoMCwgd2FzbV9jb3JlX2ltcGxfMS5yZWxlYXNlU2Vzc2lvbikoaGFuZGxlcik7XFxuICAgICAgICAgICAgICAgIHBvc3RNZXNzYWdlKHsgdHlwZTogJ3JlbGVhc2UnIH0pO1xcbiAgICAgICAgICAgIH1cXG4gICAgICAgICAgICBjYXRjaCAoZXJyKSB7XFxuICAgICAgICAgICAgICAgIHBvc3RNZXNzYWdlKHsgdHlwZTogJ3JlbGVhc2UnLCBlcnIgfSk7XFxuICAgICAgICAgICAgfVxcbiAgICAgICAgICAgIGJyZWFrO1xcbiAgICAgICAgY2FzZSAncnVuJzpcXG4gICAgICAgICAgICB0cnkge1xcbiAgICAgICAgICAgICAgICBjb25zdCB7IHNlc3Npb25JZCwgaW5wdXRJbmRpY2VzLCBpbnB1dHMsIG91dHB1dEluZGljZXMsIG9wdGlvbnMgfSA9IGV2LmRhdGEuaW47XFxuICAgICAgICAgICAgICAgIGNvbnN0IG91dHB1dHMgPSAoMCwgd2FzbV9jb3JlX2ltcGxfMS5ydW4pKHNlc3Npb25JZCwgaW5wdXRJbmRpY2VzLCBpbnB1dHMsIG91dHB1dEluZGljZXMsIG9wdGlvbnMpO1xcbiAgICAgICAgICAgICAgICBwb3N0TWVzc2FnZSh7IHR5cGU6ICdydW4nLCBvdXQ6IG91dHB1dHMgfSwgKDAsIHdhc21fY29yZV9pbXBsXzEuZXh0cmFjdFRyYW5zZmVyYWJsZUJ1ZmZlcnMpKG91dHB1dHMpKTtcXG4gICAgICAgICAgICB9XFxuICAgICAgICAgICAgY2F0Y2ggKGVycikge1xcbiAgICAgICAgICAgICAgICBwb3N0TWVzc2FnZSh7IHR5cGU6ICdydW4nLCBlcnIgfSk7XFxuICAgICAgICAgICAgfVxcbiAgICAgICAgICAgIGJyZWFrO1xcbiAgICAgICAgY2FzZSAnZW5kLXByb2ZpbGluZyc6XFxuICAgICAgICAgICAgdHJ5IHtcXG4gICAgICAgICAgICAgICAgY29uc3QgaGFuZGxlciA9IGV2LmRhdGEuaW47XFxuICAgICAgICAgICAgICAgICgwLCB3YXNtX2NvcmVfaW1wbF8xLmVuZFByb2ZpbGluZykoaGFuZGxlcik7XFxuICAgICAgICAgICAgICAgIHBvc3RNZXNzYWdlKHsgdHlwZTogJ2VuZC1wcm9maWxpbmcnIH0pO1xcbiAgICAgICAgICAgIH1cXG4gICAgICAgICAgICBjYXRjaCAoZXJyKSB7XFxuICAgICAgICAgICAgICAgIHBvc3RNZXNzYWdlKHsgdHlwZTogJ2VuZC1wcm9maWxpbmcnLCBlcnIgfSk7XFxuICAgICAgICAgICAgfVxcbiAgICAgICAgICAgIGJyZWFrO1xcbiAgICAgICAgZGVmYXVsdDpcXG4gICAgfVxcbn07XFxuXFxufSkoKTtcXG5cXG4vKioqKioqLyB9KSgpXFxuO1xcblwiLCBcIldvcmtlclwiLCB1bmRlZmluZWQsIHVuZGVmaW5lZCk7XG59XG4iLCJcInVzZSBzdHJpY3RcIjtcblxuLyogZXNsaW50LWVudiBicm93c2VyICovXG5cbi8qIGVzbGludC1kaXNhYmxlIG5vLXVuZGVmLCBuby11c2UtYmVmb3JlLWRlZmluZSwgbmV3LWNhcCAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoY29udGVudCwgd29ya2VyQ29uc3RydWN0b3IsIHdvcmtlck9wdGlvbnMsIHVybCkge1xuICB2YXIgZ2xvYmFsU2NvcGUgPSBzZWxmIHx8IHdpbmRvdztcblxuICB0cnkge1xuICAgIHRyeSB7XG4gICAgICB2YXIgYmxvYjtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gTmV3IEFQSVxuICAgICAgICBibG9iID0gbmV3IGdsb2JhbFNjb3BlLkJsb2IoW2NvbnRlbnRdKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgLy8gQmxvYkJ1aWxkZXIgPSBEZXByZWNhdGVkLCBidXQgd2lkZWx5IGltcGxlbWVudGVkXG4gICAgICAgIHZhciBCbG9iQnVpbGRlciA9IGdsb2JhbFNjb3BlLkJsb2JCdWlsZGVyIHx8IGdsb2JhbFNjb3BlLldlYktpdEJsb2JCdWlsZGVyIHx8IGdsb2JhbFNjb3BlLk1vekJsb2JCdWlsZGVyIHx8IGdsb2JhbFNjb3BlLk1TQmxvYkJ1aWxkZXI7XG4gICAgICAgIGJsb2IgPSBuZXcgQmxvYkJ1aWxkZXIoKTtcbiAgICAgICAgYmxvYi5hcHBlbmQoY29udGVudCk7XG4gICAgICAgIGJsb2IgPSBibG9iLmdldEJsb2IoKTtcbiAgICAgIH1cblxuICAgICAgdmFyIFVSTCA9IGdsb2JhbFNjb3BlLlVSTCB8fCBnbG9iYWxTY29wZS53ZWJraXRVUkw7XG4gICAgICB2YXIgb2JqZWN0VVJMID0gVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKTtcbiAgICAgIHZhciB3b3JrZXIgPSBuZXcgZ2xvYmFsU2NvcGVbd29ya2VyQ29uc3RydWN0b3JdKG9iamVjdFVSTCwgd29ya2VyT3B0aW9ucyk7XG4gICAgICBVUkwucmV2b2tlT2JqZWN0VVJMKG9iamVjdFVSTCk7XG4gICAgICByZXR1cm4gd29ya2VyO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJldHVybiBuZXcgZ2xvYmFsU2NvcGVbd29ya2VyQ29uc3RydWN0b3JdKFwiZGF0YTphcHBsaWNhdGlvbi9qYXZhc2NyaXB0LFwiLmNvbmNhdChlbmNvZGVVUklDb21wb25lbnQoY29udGVudCkpLCB3b3JrZXJPcHRpb25zKTtcbiAgICB9XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBpZiAoIXVybCkge1xuICAgICAgdGhyb3cgRXJyb3IoXCJJbmxpbmUgd29ya2VyIGlzIG5vdCBzdXBwb3J0ZWRcIik7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBnbG9iYWxTY29wZVt3b3JrZXJDb25zdHJ1Y3Rvcl0odXJsLCB3b3JrZXJPcHRpb25zKTtcbiAgfVxufTsiLCJtb2R1bGUuZXhwb3J0cyA9IF9fV0VCUEFDS19FWFRFUk5BTF9NT0RVTEVfb25ueHJ1bnRpbWVfY29tbW9uX187IiwiLyogKGlnbm9yZWQpICovIiwiLyogKGlnbm9yZWQpICovIiwiLyogKGlnbm9yZWQpICovIiwiLyogKGlnbm9yZWQpICovIiwiLyogKGlnbm9yZWQpICovIiwiLyogKGlnbm9yZWQpICovIiwiLyogKGlnbm9yZWQpICovIiwiLyogKGlnbm9yZWQpICovIiwiLyogKGlnbm9yZWQpICovIiwiLyogKGlnbm9yZWQpICovIiwiLyogKGlnbm9yZWQpICovIiwiLy8vIEBmaWxlXG4vLy8gQGFkZHRvZ3JvdXAgZmxhdGJ1ZmZlcnNfamF2YXNjcmlwdF9hcGlcbi8vLyBAe1xuLy8vIEBjb25kIEZMQVRCVUZGRVJTX0lOVEVSTkFMXG5cbi8qKlxuICogQGZpbGVvdmVydmlld1xuICpcbiAqIE5lZWQgdG8gc3VwcHJlc3MgJ2dsb2JhbCB0aGlzJyBlcnJvciBzbyB0aGUgTm9kZS5qcyBleHBvcnQgbGluZSBkb2Vzbid0IGNhdXNlXG4gKiBjbG9zdXJlIGNvbXBpbGUgdG8gZXJyb3Igb3V0LlxuICogQHN1cHByZXNzIHtnbG9iYWxUaGlzfVxuICovXG5cbi8qKlxuICogQGNvbnN0XG4gKiBAbmFtZXNwYWNlXG4gKi9cbnZhciBmbGF0YnVmZmVycyA9IHt9O1xuXG4vKipcbiAqIEB0eXBlZGVmIHtudW1iZXJ9XG4gKi9cbmZsYXRidWZmZXJzLk9mZnNldDtcblxuLyoqXG4gKiBAdHlwZWRlZiB7e1xuICogICBiYjogZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcixcbiAqICAgYmJfcG9zOiBudW1iZXJcbiAqIH19XG4gKi9cbmZsYXRidWZmZXJzLlRhYmxlO1xuXG4vKipcbiAqIEB0eXBlIHtudW1iZXJ9XG4gKiBAY29uc3RcbiAqL1xuZmxhdGJ1ZmZlcnMuU0laRU9GX1NIT1JUID0gMjtcblxuLyoqXG4gKiBAdHlwZSB7bnVtYmVyfVxuICogQGNvbnN0XG4gKi9cbmZsYXRidWZmZXJzLlNJWkVPRl9JTlQgPSA0O1xuXG4vKipcbiAqIEB0eXBlIHtudW1iZXJ9XG4gKiBAY29uc3RcbiAqL1xuZmxhdGJ1ZmZlcnMuRklMRV9JREVOVElGSUVSX0xFTkdUSCA9IDQ7XG5cbi8qKlxuICogQHR5cGUge251bWJlcn1cbiAqIEBjb25zdFxuICovXG5mbGF0YnVmZmVycy5TSVpFX1BSRUZJWF9MRU5HVEggPSA0O1xuXG4vKipcbiAqIEBlbnVtIHtudW1iZXJ9XG4gKi9cbmZsYXRidWZmZXJzLkVuY29kaW5nID0ge1xuICBVVEY4X0JZVEVTOiAxLFxuICBVVEYxNl9TVFJJTkc6IDJcbn07XG5cbi8qKlxuICogQHR5cGUge0ludDMyQXJyYXl9XG4gKiBAY29uc3RcbiAqL1xuZmxhdGJ1ZmZlcnMuaW50MzIgPSBuZXcgSW50MzJBcnJheSgyKTtcblxuLyoqXG4gKiBAdHlwZSB7RmxvYXQzMkFycmF5fVxuICogQGNvbnN0XG4gKi9cbmZsYXRidWZmZXJzLmZsb2F0MzIgPSBuZXcgRmxvYXQzMkFycmF5KGZsYXRidWZmZXJzLmludDMyLmJ1ZmZlcik7XG5cbi8qKlxuICogQHR5cGUge0Zsb2F0NjRBcnJheX1cbiAqIEBjb25zdFxuICovXG5mbGF0YnVmZmVycy5mbG9hdDY0ID0gbmV3IEZsb2F0NjRBcnJheShmbGF0YnVmZmVycy5pbnQzMi5idWZmZXIpO1xuXG4vKipcbiAqIEB0eXBlIHtib29sZWFufVxuICogQGNvbnN0XG4gKi9cbmZsYXRidWZmZXJzLmlzTGl0dGxlRW5kaWFuID0gbmV3IFVpbnQxNkFycmF5KG5ldyBVaW50OEFycmF5KFsxLCAwXSkuYnVmZmVyKVswXSA9PT0gMTtcblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuLyoqXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7bnVtYmVyfSBsb3dcbiAqIEBwYXJhbSB7bnVtYmVyfSBoaWdoXG4gKi9cbmZsYXRidWZmZXJzLkxvbmcgPSBmdW5jdGlvbihsb3csIGhpZ2gpIHtcbiAgLyoqXG4gICAqIEB0eXBlIHtudW1iZXJ9XG4gICAqIEBjb25zdFxuICAgKi9cbiAgdGhpcy5sb3cgPSBsb3cgfCAwO1xuXG4gIC8qKlxuICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgKiBAY29uc3RcbiAgICovXG4gIHRoaXMuaGlnaCA9IGhpZ2ggfCAwO1xufTtcblxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gbG93XG4gKiBAcGFyYW0ge251bWJlcn0gaGlnaFxuICogQHJldHVybnMgeyFmbGF0YnVmZmVycy5Mb25nfVxuICovXG5mbGF0YnVmZmVycy5Mb25nLmNyZWF0ZSA9IGZ1bmN0aW9uKGxvdywgaGlnaCkge1xuICAvLyBTcGVjaWFsLWNhc2UgemVybyB0byBhdm9pZCBHQyBvdmVyaGVhZCBmb3IgZGVmYXVsdCB2YWx1ZXNcbiAgcmV0dXJuIGxvdyA9PSAwICYmIGhpZ2ggPT0gMCA/IGZsYXRidWZmZXJzLkxvbmcuWkVSTyA6IG5ldyBmbGF0YnVmZmVycy5Mb25nKGxvdywgaGlnaCk7XG59O1xuXG4vKipcbiAqIEByZXR1cm5zIHtudW1iZXJ9XG4gKi9cbmZsYXRidWZmZXJzLkxvbmcucHJvdG90eXBlLnRvRmxvYXQ2NCA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gKHRoaXMubG93ID4+PiAwKSArIHRoaXMuaGlnaCAqIDB4MTAwMDAwMDAwO1xufTtcblxuLyoqXG4gKiBAcGFyYW0ge2ZsYXRidWZmZXJzLkxvbmd9IG90aGVyXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuZmxhdGJ1ZmZlcnMuTG9uZy5wcm90b3R5cGUuZXF1YWxzID0gZnVuY3Rpb24ob3RoZXIpIHtcbiAgcmV0dXJuIHRoaXMubG93ID09IG90aGVyLmxvdyAmJiB0aGlzLmhpZ2ggPT0gb3RoZXIuaGlnaDtcbn07XG5cbi8qKlxuICogQHR5cGUgeyFmbGF0YnVmZmVycy5Mb25nfVxuICogQGNvbnN0XG4gKi9cbmZsYXRidWZmZXJzLkxvbmcuWkVSTyA9IG5ldyBmbGF0YnVmZmVycy5Mb25nKDAsIDApO1xuXG4vLy8gQGVuZGNvbmRcbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4vKipcbiAqIENyZWF0ZSBhIEZsYXRCdWZmZXJCdWlsZGVyLlxuICpcbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtudW1iZXI9fSBvcHRfaW5pdGlhbF9zaXplXG4gKi9cbmZsYXRidWZmZXJzLkJ1aWxkZXIgPSBmdW5jdGlvbihvcHRfaW5pdGlhbF9zaXplKSB7XG4gIGlmICghb3B0X2luaXRpYWxfc2l6ZSkge1xuICAgIHZhciBpbml0aWFsX3NpemUgPSAxMDI0O1xuICB9IGVsc2Uge1xuICAgIHZhciBpbml0aWFsX3NpemUgPSBvcHRfaW5pdGlhbF9zaXplO1xuICB9XG5cbiAgLyoqXG4gICAqIEB0eXBlIHtmbGF0YnVmZmVycy5CeXRlQnVmZmVyfVxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgdGhpcy5iYiA9IGZsYXRidWZmZXJzLkJ5dGVCdWZmZXIuYWxsb2NhdGUoaW5pdGlhbF9zaXplKTtcblxuICAvKipcbiAgICogUmVtYWluaW5nIHNwYWNlIGluIHRoZSBCeXRlQnVmZmVyLlxuICAgKlxuICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgdGhpcy5zcGFjZSA9IGluaXRpYWxfc2l6ZTtcblxuICAvKipcbiAgICogTWluaW11bSBhbGlnbm1lbnQgZW5jb3VudGVyZWQgc28gZmFyLlxuICAgKlxuICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgdGhpcy5taW5hbGlnbiA9IDE7XG5cbiAgLyoqXG4gICAqIFRoZSB2dGFibGUgZm9yIHRoZSBjdXJyZW50IHRhYmxlLlxuICAgKlxuICAgKiBAdHlwZSB7QXJyYXkuPG51bWJlcj59XG4gICAqIEBwcml2YXRlXG4gICAqL1xuICB0aGlzLnZ0YWJsZSA9IG51bGw7XG5cbiAgLyoqXG4gICAqIFRoZSBhbW91bnQgb2YgZmllbGRzIHdlJ3JlIGFjdHVhbGx5IHVzaW5nLlxuICAgKlxuICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgdGhpcy52dGFibGVfaW5fdXNlID0gMDtcblxuICAvKipcbiAgICogV2hldGhlciB3ZSBhcmUgY3VycmVudGx5IHNlcmlhbGl6aW5nIGEgdGFibGUuXG4gICAqXG4gICAqIEB0eXBlIHtib29sZWFufVxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgdGhpcy5pc05lc3RlZCA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBTdGFydGluZyBvZmZzZXQgb2YgdGhlIGN1cnJlbnQgc3RydWN0L3RhYmxlLlxuICAgKlxuICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgdGhpcy5vYmplY3Rfc3RhcnQgPSAwO1xuXG4gIC8qKlxuICAgKiBMaXN0IG9mIG9mZnNldHMgb2YgYWxsIHZ0YWJsZXMuXG4gICAqXG4gICAqIEB0eXBlIHtBcnJheS48bnVtYmVyPn1cbiAgICogQHByaXZhdGVcbiAgICovXG4gIHRoaXMudnRhYmxlcyA9IFtdO1xuXG4gIC8qKlxuICAgKiBGb3IgdGhlIGN1cnJlbnQgdmVjdG9yIGJlaW5nIGJ1aWx0LlxuICAgKlxuICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgdGhpcy52ZWN0b3JfbnVtX2VsZW1zID0gMDtcblxuICAvKipcbiAgICogRmFsc2Ugb21pdHMgZGVmYXVsdCB2YWx1ZXMgZnJvbSB0aGUgc2VyaWFsaXplZCBkYXRhXG4gICAqXG4gICAqIEB0eXBlIHtib29sZWFufVxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgdGhpcy5mb3JjZV9kZWZhdWx0cyA9IGZhbHNlO1xufTtcblxuZmxhdGJ1ZmZlcnMuQnVpbGRlci5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5iYi5jbGVhcigpO1xuICB0aGlzLnNwYWNlID0gdGhpcy5iYi5jYXBhY2l0eSgpO1xuICB0aGlzLm1pbmFsaWduID0gMTtcbiAgdGhpcy52dGFibGUgPSBudWxsO1xuICB0aGlzLnZ0YWJsZV9pbl91c2UgPSAwO1xuICB0aGlzLmlzTmVzdGVkID0gZmFsc2U7XG4gIHRoaXMub2JqZWN0X3N0YXJ0ID0gMDtcbiAgdGhpcy52dGFibGVzID0gW107XG4gIHRoaXMudmVjdG9yX251bV9lbGVtcyA9IDA7XG4gIHRoaXMuZm9yY2VfZGVmYXVsdHMgPSBmYWxzZTtcbn07XG5cbi8qKlxuICogSW4gb3JkZXIgdG8gc2F2ZSBzcGFjZSwgZmllbGRzIHRoYXQgYXJlIHNldCB0byB0aGVpciBkZWZhdWx0IHZhbHVlXG4gKiBkb24ndCBnZXQgc2VyaWFsaXplZCBpbnRvIHRoZSBidWZmZXIuIEZvcmNpbmcgZGVmYXVsdHMgcHJvdmlkZXMgYVxuICogd2F5IHRvIG1hbnVhbGx5IGRpc2FibGUgdGhpcyBvcHRpbWl6YXRpb24uXG4gKlxuICogQHBhcmFtIHtib29sZWFufSBmb3JjZURlZmF1bHRzIHRydWUgYWx3YXlzIHNlcmlhbGl6ZXMgZGVmYXVsdCB2YWx1ZXNcbiAqL1xuZmxhdGJ1ZmZlcnMuQnVpbGRlci5wcm90b3R5cGUuZm9yY2VEZWZhdWx0cyA9IGZ1bmN0aW9uKGZvcmNlRGVmYXVsdHMpIHtcbiAgdGhpcy5mb3JjZV9kZWZhdWx0cyA9IGZvcmNlRGVmYXVsdHM7XG59O1xuXG4vKipcbiAqIEdldCB0aGUgQnl0ZUJ1ZmZlciByZXByZXNlbnRpbmcgdGhlIEZsYXRCdWZmZXIuIE9ubHkgY2FsbCB0aGlzIGFmdGVyIHlvdSd2ZVxuICogY2FsbGVkIGZpbmlzaCgpLiBUaGUgYWN0dWFsIGRhdGEgc3RhcnRzIGF0IHRoZSBCeXRlQnVmZmVyJ3MgY3VycmVudCBwb3NpdGlvbixcbiAqIG5vdCBuZWNlc3NhcmlseSBhdCAwLlxuICpcbiAqIEByZXR1cm5zIHtmbGF0YnVmZmVycy5CeXRlQnVmZmVyfVxuICovXG5mbGF0YnVmZmVycy5CdWlsZGVyLnByb3RvdHlwZS5kYXRhQnVmZmVyID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLmJiO1xufTtcblxuLyoqXG4gKiBHZXQgdGhlIGJ5dGVzIHJlcHJlc2VudGluZyB0aGUgRmxhdEJ1ZmZlci4gT25seSBjYWxsIHRoaXMgYWZ0ZXIgeW91J3ZlXG4gKiBjYWxsZWQgZmluaXNoKCkuXG4gKlxuICogQHJldHVybnMgeyFVaW50OEFycmF5fVxuICovXG5mbGF0YnVmZmVycy5CdWlsZGVyLnByb3RvdHlwZS5hc1VpbnQ4QXJyYXkgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMuYmIuYnl0ZXMoKS5zdWJhcnJheSh0aGlzLmJiLnBvc2l0aW9uKCksIHRoaXMuYmIucG9zaXRpb24oKSArIHRoaXMub2Zmc2V0KCkpO1xufTtcblxuLy8vIEBjb25kIEZMQVRCVUZGRVJTX0lOVEVSTkFMXG4vKipcbiAqIFByZXBhcmUgdG8gd3JpdGUgYW4gZWxlbWVudCBvZiBgc2l6ZWAgYWZ0ZXIgYGFkZGl0aW9uYWxfYnl0ZXNgIGhhdmUgYmVlblxuICogd3JpdHRlbiwgZS5nLiBpZiB5b3Ugd3JpdGUgYSBzdHJpbmcsIHlvdSBuZWVkIHRvIGFsaWduIHN1Y2ggdGhlIGludCBsZW5ndGhcbiAqIGZpZWxkIGlzIGFsaWduZWQgdG8gNCBieXRlcywgYW5kIHRoZSBzdHJpbmcgZGF0YSBmb2xsb3dzIGl0IGRpcmVjdGx5LiBJZiBhbGxcbiAqIHlvdSBuZWVkIHRvIGRvIGlzIGFsaWdubWVudCwgYGFkZGl0aW9uYWxfYnl0ZXNgIHdpbGwgYmUgMC5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gc2l6ZSBUaGlzIGlzIHRoZSBvZiB0aGUgbmV3IGVsZW1lbnQgdG8gd3JpdGVcbiAqIEBwYXJhbSB7bnVtYmVyfSBhZGRpdGlvbmFsX2J5dGVzIFRoZSBwYWRkaW5nIHNpemVcbiAqL1xuZmxhdGJ1ZmZlcnMuQnVpbGRlci5wcm90b3R5cGUucHJlcCA9IGZ1bmN0aW9uKHNpemUsIGFkZGl0aW9uYWxfYnl0ZXMpIHtcbiAgLy8gVHJhY2sgdGhlIGJpZ2dlc3QgdGhpbmcgd2UndmUgZXZlciBhbGlnbmVkIHRvLlxuICBpZiAoc2l6ZSA+IHRoaXMubWluYWxpZ24pIHtcbiAgICB0aGlzLm1pbmFsaWduID0gc2l6ZTtcbiAgfVxuXG4gIC8vIEZpbmQgdGhlIGFtb3VudCBvZiBhbGlnbm1lbnQgbmVlZGVkIHN1Y2ggdGhhdCBgc2l6ZWAgaXMgcHJvcGVybHlcbiAgLy8gYWxpZ25lZCBhZnRlciBgYWRkaXRpb25hbF9ieXRlc2BcbiAgdmFyIGFsaWduX3NpemUgPSAoKH4odGhpcy5iYi5jYXBhY2l0eSgpIC0gdGhpcy5zcGFjZSArIGFkZGl0aW9uYWxfYnl0ZXMpKSArIDEpICYgKHNpemUgLSAxKTtcblxuICAvLyBSZWFsbG9jYXRlIHRoZSBidWZmZXIgaWYgbmVlZGVkLlxuICB3aGlsZSAodGhpcy5zcGFjZSA8IGFsaWduX3NpemUgKyBzaXplICsgYWRkaXRpb25hbF9ieXRlcykge1xuICAgIHZhciBvbGRfYnVmX3NpemUgPSB0aGlzLmJiLmNhcGFjaXR5KCk7XG4gICAgdGhpcy5iYiA9IGZsYXRidWZmZXJzLkJ1aWxkZXIuZ3Jvd0J5dGVCdWZmZXIodGhpcy5iYik7XG4gICAgdGhpcy5zcGFjZSArPSB0aGlzLmJiLmNhcGFjaXR5KCkgLSBvbGRfYnVmX3NpemU7XG4gIH1cblxuICB0aGlzLnBhZChhbGlnbl9zaXplKTtcbn07XG5cbi8qKlxuICogQHBhcmFtIHtudW1iZXJ9IGJ5dGVfc2l6ZVxuICovXG5mbGF0YnVmZmVycy5CdWlsZGVyLnByb3RvdHlwZS5wYWQgPSBmdW5jdGlvbihieXRlX3NpemUpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBieXRlX3NpemU7IGkrKykge1xuICAgIHRoaXMuYmIud3JpdGVJbnQ4KC0tdGhpcy5zcGFjZSwgMCk7XG4gIH1cbn07XG5cbi8qKlxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlXG4gKi9cbmZsYXRidWZmZXJzLkJ1aWxkZXIucHJvdG90eXBlLndyaXRlSW50OCA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gIHRoaXMuYmIud3JpdGVJbnQ4KHRoaXMuc3BhY2UgLT0gMSwgdmFsdWUpO1xufTtcblxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWVcbiAqL1xuZmxhdGJ1ZmZlcnMuQnVpbGRlci5wcm90b3R5cGUud3JpdGVJbnQxNiA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gIHRoaXMuYmIud3JpdGVJbnQxNih0aGlzLnNwYWNlIC09IDIsIHZhbHVlKTtcbn07XG5cbi8qKlxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlXG4gKi9cbmZsYXRidWZmZXJzLkJ1aWxkZXIucHJvdG90eXBlLndyaXRlSW50MzIgPSBmdW5jdGlvbih2YWx1ZSkge1xuICB0aGlzLmJiLndyaXRlSW50MzIodGhpcy5zcGFjZSAtPSA0LCB2YWx1ZSk7XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7ZmxhdGJ1ZmZlcnMuTG9uZ30gdmFsdWVcbiAqL1xuZmxhdGJ1ZmZlcnMuQnVpbGRlci5wcm90b3R5cGUud3JpdGVJbnQ2NCA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gIHRoaXMuYmIud3JpdGVJbnQ2NCh0aGlzLnNwYWNlIC09IDgsIHZhbHVlKTtcbn07XG5cbi8qKlxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlXG4gKi9cbmZsYXRidWZmZXJzLkJ1aWxkZXIucHJvdG90eXBlLndyaXRlRmxvYXQzMiA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gIHRoaXMuYmIud3JpdGVGbG9hdDMyKHRoaXMuc3BhY2UgLT0gNCwgdmFsdWUpO1xufTtcblxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWVcbiAqL1xuZmxhdGJ1ZmZlcnMuQnVpbGRlci5wcm90b3R5cGUud3JpdGVGbG9hdDY0ID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgdGhpcy5iYi53cml0ZUZsb2F0NjQodGhpcy5zcGFjZSAtPSA4LCB2YWx1ZSk7XG59O1xuLy8vIEBlbmRjb25kXG5cbi8qKlxuICogQWRkIGFuIGBpbnQ4YCB0byB0aGUgYnVmZmVyLCBwcm9wZXJseSBhbGlnbmVkLCBhbmQgZ3Jvd3MgdGhlIGJ1ZmZlciAoaWYgbmVjZXNzYXJ5KS5cbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBUaGUgYGludDhgIHRvIGFkZCB0aGUgdGhlIGJ1ZmZlci5cbiAqL1xuZmxhdGJ1ZmZlcnMuQnVpbGRlci5wcm90b3R5cGUuYWRkSW50OCA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gIHRoaXMucHJlcCgxLCAwKTtcbiAgdGhpcy53cml0ZUludDgodmFsdWUpO1xufTtcblxuLyoqXG4gKiBBZGQgYW4gYGludDE2YCB0byB0aGUgYnVmZmVyLCBwcm9wZXJseSBhbGlnbmVkLCBhbmQgZ3Jvd3MgdGhlIGJ1ZmZlciAoaWYgbmVjZXNzYXJ5KS5cbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBUaGUgYGludDE2YCB0byBhZGQgdGhlIHRoZSBidWZmZXIuXG4gKi9cbmZsYXRidWZmZXJzLkJ1aWxkZXIucHJvdG90eXBlLmFkZEludDE2ID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgdGhpcy5wcmVwKDIsIDApO1xuICB0aGlzLndyaXRlSW50MTYodmFsdWUpO1xufTtcblxuLyoqXG4gKiBBZGQgYW4gYGludDMyYCB0byB0aGUgYnVmZmVyLCBwcm9wZXJseSBhbGlnbmVkLCBhbmQgZ3Jvd3MgdGhlIGJ1ZmZlciAoaWYgbmVjZXNzYXJ5KS5cbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBUaGUgYGludDMyYCB0byBhZGQgdGhlIHRoZSBidWZmZXIuXG4gKi9cbmZsYXRidWZmZXJzLkJ1aWxkZXIucHJvdG90eXBlLmFkZEludDMyID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgdGhpcy5wcmVwKDQsIDApO1xuICB0aGlzLndyaXRlSW50MzIodmFsdWUpO1xufTtcblxuLyoqXG4gKiBBZGQgYW4gYGludDY0YCB0byB0aGUgYnVmZmVyLCBwcm9wZXJseSBhbGlnbmVkLCBhbmQgZ3Jvd3MgdGhlIGJ1ZmZlciAoaWYgbmVjZXNzYXJ5KS5cbiAqIEBwYXJhbSB7ZmxhdGJ1ZmZlcnMuTG9uZ30gdmFsdWUgVGhlIGBpbnQ2NGAgdG8gYWRkIHRoZSB0aGUgYnVmZmVyLlxuICovXG5mbGF0YnVmZmVycy5CdWlsZGVyLnByb3RvdHlwZS5hZGRJbnQ2NCA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gIHRoaXMucHJlcCg4LCAwKTtcbiAgdGhpcy53cml0ZUludDY0KHZhbHVlKTtcbn07XG5cbi8qKlxuICogQWRkIGEgYGZsb2F0MzJgIHRvIHRoZSBidWZmZXIsIHByb3Blcmx5IGFsaWduZWQsIGFuZCBncm93cyB0aGUgYnVmZmVyIChpZiBuZWNlc3NhcnkpLlxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIFRoZSBgZmxvYXQzMmAgdG8gYWRkIHRoZSB0aGUgYnVmZmVyLlxuICovXG5mbGF0YnVmZmVycy5CdWlsZGVyLnByb3RvdHlwZS5hZGRGbG9hdDMyID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgdGhpcy5wcmVwKDQsIDApO1xuICB0aGlzLndyaXRlRmxvYXQzMih2YWx1ZSk7XG59O1xuXG4vKipcbiAqIEFkZCBhIGBmbG9hdDY0YCB0byB0aGUgYnVmZmVyLCBwcm9wZXJseSBhbGlnbmVkLCBhbmQgZ3Jvd3MgdGhlIGJ1ZmZlciAoaWYgbmVjZXNzYXJ5KS5cbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZSBUaGUgYGZsb2F0NjRgIHRvIGFkZCB0aGUgdGhlIGJ1ZmZlci5cbiAqL1xuZmxhdGJ1ZmZlcnMuQnVpbGRlci5wcm90b3R5cGUuYWRkRmxvYXQ2NCA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gIHRoaXMucHJlcCg4LCAwKTtcbiAgdGhpcy53cml0ZUZsb2F0NjQodmFsdWUpO1xufTtcblxuLy8vIEBjb25kIEZMQVRCVUZGRVJTX0lOVEVSTkFMXG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSB2b2Zmc2V0XG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWVcbiAqIEBwYXJhbSB7bnVtYmVyfSBkZWZhdWx0VmFsdWVcbiAqL1xuZmxhdGJ1ZmZlcnMuQnVpbGRlci5wcm90b3R5cGUuYWRkRmllbGRJbnQ4ID0gZnVuY3Rpb24odm9mZnNldCwgdmFsdWUsIGRlZmF1bHRWYWx1ZSkge1xuICBpZiAodGhpcy5mb3JjZV9kZWZhdWx0cyB8fCB2YWx1ZSAhPSBkZWZhdWx0VmFsdWUpIHtcbiAgICB0aGlzLmFkZEludDgodmFsdWUpO1xuICAgIHRoaXMuc2xvdCh2b2Zmc2V0KTtcbiAgfVxufTtcblxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gdm9mZnNldFxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlXG4gKiBAcGFyYW0ge251bWJlcn0gZGVmYXVsdFZhbHVlXG4gKi9cbmZsYXRidWZmZXJzLkJ1aWxkZXIucHJvdG90eXBlLmFkZEZpZWxkSW50MTYgPSBmdW5jdGlvbih2b2Zmc2V0LCB2YWx1ZSwgZGVmYXVsdFZhbHVlKSB7XG4gIGlmICh0aGlzLmZvcmNlX2RlZmF1bHRzIHx8IHZhbHVlICE9IGRlZmF1bHRWYWx1ZSkge1xuICAgIHRoaXMuYWRkSW50MTYodmFsdWUpO1xuICAgIHRoaXMuc2xvdCh2b2Zmc2V0KTtcbiAgfVxufTtcblxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gdm9mZnNldFxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlXG4gKiBAcGFyYW0ge251bWJlcn0gZGVmYXVsdFZhbHVlXG4gKi9cbmZsYXRidWZmZXJzLkJ1aWxkZXIucHJvdG90eXBlLmFkZEZpZWxkSW50MzIgPSBmdW5jdGlvbih2b2Zmc2V0LCB2YWx1ZSwgZGVmYXVsdFZhbHVlKSB7XG4gIGlmICh0aGlzLmZvcmNlX2RlZmF1bHRzIHx8IHZhbHVlICE9IGRlZmF1bHRWYWx1ZSkge1xuICAgIHRoaXMuYWRkSW50MzIodmFsdWUpO1xuICAgIHRoaXMuc2xvdCh2b2Zmc2V0KTtcbiAgfVxufTtcblxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gdm9mZnNldFxuICogQHBhcmFtIHtmbGF0YnVmZmVycy5Mb25nfSB2YWx1ZVxuICogQHBhcmFtIHtmbGF0YnVmZmVycy5Mb25nfSBkZWZhdWx0VmFsdWVcbiAqL1xuZmxhdGJ1ZmZlcnMuQnVpbGRlci5wcm90b3R5cGUuYWRkRmllbGRJbnQ2NCA9IGZ1bmN0aW9uKHZvZmZzZXQsIHZhbHVlLCBkZWZhdWx0VmFsdWUpIHtcbiAgaWYgKHRoaXMuZm9yY2VfZGVmYXVsdHMgfHwgIXZhbHVlLmVxdWFscyhkZWZhdWx0VmFsdWUpKSB7XG4gICAgdGhpcy5hZGRJbnQ2NCh2YWx1ZSk7XG4gICAgdGhpcy5zbG90KHZvZmZzZXQpO1xuICB9XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSB2b2Zmc2V0XG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWVcbiAqIEBwYXJhbSB7bnVtYmVyfSBkZWZhdWx0VmFsdWVcbiAqL1xuZmxhdGJ1ZmZlcnMuQnVpbGRlci5wcm90b3R5cGUuYWRkRmllbGRGbG9hdDMyID0gZnVuY3Rpb24odm9mZnNldCwgdmFsdWUsIGRlZmF1bHRWYWx1ZSkge1xuICBpZiAodGhpcy5mb3JjZV9kZWZhdWx0cyB8fCB2YWx1ZSAhPSBkZWZhdWx0VmFsdWUpIHtcbiAgICB0aGlzLmFkZEZsb2F0MzIodmFsdWUpO1xuICAgIHRoaXMuc2xvdCh2b2Zmc2V0KTtcbiAgfVxufTtcblxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gdm9mZnNldFxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlXG4gKiBAcGFyYW0ge251bWJlcn0gZGVmYXVsdFZhbHVlXG4gKi9cbmZsYXRidWZmZXJzLkJ1aWxkZXIucHJvdG90eXBlLmFkZEZpZWxkRmxvYXQ2NCA9IGZ1bmN0aW9uKHZvZmZzZXQsIHZhbHVlLCBkZWZhdWx0VmFsdWUpIHtcbiAgaWYgKHRoaXMuZm9yY2VfZGVmYXVsdHMgfHwgdmFsdWUgIT0gZGVmYXVsdFZhbHVlKSB7XG4gICAgdGhpcy5hZGRGbG9hdDY0KHZhbHVlKTtcbiAgICB0aGlzLnNsb3Qodm9mZnNldCk7XG4gIH1cbn07XG5cbi8qKlxuICogQHBhcmFtIHtudW1iZXJ9IHZvZmZzZXRcbiAqIEBwYXJhbSB7ZmxhdGJ1ZmZlcnMuT2Zmc2V0fSB2YWx1ZVxuICogQHBhcmFtIHtmbGF0YnVmZmVycy5PZmZzZXR9IGRlZmF1bHRWYWx1ZVxuICovXG5mbGF0YnVmZmVycy5CdWlsZGVyLnByb3RvdHlwZS5hZGRGaWVsZE9mZnNldCA9IGZ1bmN0aW9uKHZvZmZzZXQsIHZhbHVlLCBkZWZhdWx0VmFsdWUpIHtcbiAgaWYgKHRoaXMuZm9yY2VfZGVmYXVsdHMgfHwgdmFsdWUgIT0gZGVmYXVsdFZhbHVlKSB7XG4gICAgdGhpcy5hZGRPZmZzZXQodmFsdWUpO1xuICAgIHRoaXMuc2xvdCh2b2Zmc2V0KTtcbiAgfVxufTtcblxuLyoqXG4gKiBTdHJ1Y3RzIGFyZSBzdG9yZWQgaW5saW5lLCBzbyBub3RoaW5nIGFkZGl0aW9uYWwgaXMgYmVpbmcgYWRkZWQuIGBkYCBpcyBhbHdheXMgMC5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gdm9mZnNldFxuICogQHBhcmFtIHtmbGF0YnVmZmVycy5PZmZzZXR9IHZhbHVlXG4gKiBAcGFyYW0ge2ZsYXRidWZmZXJzLk9mZnNldH0gZGVmYXVsdFZhbHVlXG4gKi9cbmZsYXRidWZmZXJzLkJ1aWxkZXIucHJvdG90eXBlLmFkZEZpZWxkU3RydWN0ID0gZnVuY3Rpb24odm9mZnNldCwgdmFsdWUsIGRlZmF1bHRWYWx1ZSkge1xuICBpZiAodmFsdWUgIT0gZGVmYXVsdFZhbHVlKSB7XG4gICAgdGhpcy5uZXN0ZWQodmFsdWUpO1xuICAgIHRoaXMuc2xvdCh2b2Zmc2V0KTtcbiAgfVxufTtcblxuLyoqXG4gKiBTdHJ1Y3R1cmVzIGFyZSBhbHdheXMgc3RvcmVkIGlubGluZSwgdGhleSBuZWVkIHRvIGJlIGNyZWF0ZWQgcmlnaHRcbiAqIHdoZXJlIHRoZXkncmUgdXNlZC4gIFlvdSdsbCBnZXQgdGhpcyBhc3NlcnRpb24gZmFpbHVyZSBpZiB5b3VcbiAqIGNyZWF0ZWQgaXQgZWxzZXdoZXJlLlxuICpcbiAqIEBwYXJhbSB7ZmxhdGJ1ZmZlcnMuT2Zmc2V0fSBvYmogVGhlIG9mZnNldCBvZiB0aGUgY3JlYXRlZCBvYmplY3RcbiAqL1xuZmxhdGJ1ZmZlcnMuQnVpbGRlci5wcm90b3R5cGUubmVzdGVkID0gZnVuY3Rpb24ob2JqKSB7XG4gIGlmIChvYmogIT0gdGhpcy5vZmZzZXQoKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignRmxhdEJ1ZmZlcnM6IHN0cnVjdCBtdXN0IGJlIHNlcmlhbGl6ZWQgaW5saW5lLicpO1xuICB9XG59O1xuXG4vKipcbiAqIFNob3VsZCBub3QgYmUgY3JlYXRpbmcgYW55IG90aGVyIG9iamVjdCwgc3RyaW5nIG9yIHZlY3RvclxuICogd2hpbGUgYW4gb2JqZWN0IGlzIGJlaW5nIGNvbnN0cnVjdGVkXG4gKi9cbmZsYXRidWZmZXJzLkJ1aWxkZXIucHJvdG90eXBlLm5vdE5lc3RlZCA9IGZ1bmN0aW9uKCkge1xuICBpZiAodGhpcy5pc05lc3RlZCkge1xuICAgIHRocm93IG5ldyBFcnJvcignRmxhdEJ1ZmZlcnM6IG9iamVjdCBzZXJpYWxpemF0aW9uIG11c3Qgbm90IGJlIG5lc3RlZC4nKTtcbiAgfVxufTtcblxuLyoqXG4gKiBTZXQgdGhlIGN1cnJlbnQgdnRhYmxlIGF0IGB2b2Zmc2V0YCB0byB0aGUgY3VycmVudCBsb2NhdGlvbiBpbiB0aGUgYnVmZmVyLlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSB2b2Zmc2V0XG4gKi9cbmZsYXRidWZmZXJzLkJ1aWxkZXIucHJvdG90eXBlLnNsb3QgPSBmdW5jdGlvbih2b2Zmc2V0KSB7XG4gIHRoaXMudnRhYmxlW3ZvZmZzZXRdID0gdGhpcy5vZmZzZXQoKTtcbn07XG5cbi8qKlxuICogQHJldHVybnMge2ZsYXRidWZmZXJzLk9mZnNldH0gT2Zmc2V0IHJlbGF0aXZlIHRvIHRoZSBlbmQgb2YgdGhlIGJ1ZmZlci5cbiAqL1xuZmxhdGJ1ZmZlcnMuQnVpbGRlci5wcm90b3R5cGUub2Zmc2V0ID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLmJiLmNhcGFjaXR5KCkgLSB0aGlzLnNwYWNlO1xufTtcblxuLyoqXG4gKiBEb3VibGVzIHRoZSBzaXplIG9mIHRoZSBiYWNraW5nIEJ5dGVCdWZmZXIgYW5kIGNvcGllcyB0aGUgb2xkIGRhdGEgdG93YXJkc1xuICogdGhlIGVuZCBvZiB0aGUgbmV3IGJ1ZmZlciAoc2luY2Ugd2UgYnVpbGQgdGhlIGJ1ZmZlciBiYWNrd2FyZHMpLlxuICpcbiAqIEBwYXJhbSB7ZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcn0gYmIgVGhlIGN1cnJlbnQgYnVmZmVyIHdpdGggdGhlIGV4aXN0aW5nIGRhdGFcbiAqIEByZXR1cm5zIHshZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlcn0gQSBuZXcgYnl0ZSBidWZmZXIgd2l0aCB0aGUgb2xkIGRhdGEgY29waWVkXG4gKiB0byBpdC4gVGhlIGRhdGEgaXMgbG9jYXRlZCBhdCB0aGUgZW5kIG9mIHRoZSBidWZmZXIuXG4gKlxuICogdWludDhBcnJheS5zZXQoKSBmb3JtYWxseSB0YWtlcyB7QXJyYXk8bnVtYmVyPnxBcnJheUJ1ZmZlclZpZXd9LCBzbyB0byBwYXNzXG4gKiBpdCBhIHVpbnQ4QXJyYXkgd2UgbmVlZCB0byBzdXBwcmVzcyB0aGUgdHlwZSBjaGVjazpcbiAqIEBzdXBwcmVzcyB7Y2hlY2tUeXBlc31cbiAqL1xuZmxhdGJ1ZmZlcnMuQnVpbGRlci5ncm93Qnl0ZUJ1ZmZlciA9IGZ1bmN0aW9uKGJiKSB7XG4gIHZhciBvbGRfYnVmX3NpemUgPSBiYi5jYXBhY2l0eSgpO1xuXG4gIC8vIEVuc3VyZSB3ZSBkb24ndCBncm93IGJleW9uZCB3aGF0IGZpdHMgaW4gYW4gaW50LlxuICBpZiAob2xkX2J1Zl9zaXplICYgMHhDMDAwMDAwMCkge1xuICAgIHRocm93IG5ldyBFcnJvcignRmxhdEJ1ZmZlcnM6IGNhbm5vdCBncm93IGJ1ZmZlciBiZXlvbmQgMiBnaWdhYnl0ZXMuJyk7XG4gIH1cblxuICB2YXIgbmV3X2J1Zl9zaXplID0gb2xkX2J1Zl9zaXplIDw8IDE7XG4gIHZhciBuYmIgPSBmbGF0YnVmZmVycy5CeXRlQnVmZmVyLmFsbG9jYXRlKG5ld19idWZfc2l6ZSk7XG4gIG5iYi5zZXRQb3NpdGlvbihuZXdfYnVmX3NpemUgLSBvbGRfYnVmX3NpemUpO1xuICBuYmIuYnl0ZXMoKS5zZXQoYmIuYnl0ZXMoKSwgbmV3X2J1Zl9zaXplIC0gb2xkX2J1Zl9zaXplKTtcbiAgcmV0dXJuIG5iYjtcbn07XG4vLy8gQGVuZGNvbmRcblxuLyoqXG4gKiBBZGRzIG9uIG9mZnNldCwgcmVsYXRpdmUgdG8gd2hlcmUgaXQgd2lsbCBiZSB3cml0dGVuLlxuICpcbiAqIEBwYXJhbSB7ZmxhdGJ1ZmZlcnMuT2Zmc2V0fSBvZmZzZXQgVGhlIG9mZnNldCB0byBhZGQuXG4gKi9cbmZsYXRidWZmZXJzLkJ1aWxkZXIucHJvdG90eXBlLmFkZE9mZnNldCA9IGZ1bmN0aW9uKG9mZnNldCkge1xuICB0aGlzLnByZXAoZmxhdGJ1ZmZlcnMuU0laRU9GX0lOVCwgMCk7IC8vIEVuc3VyZSBhbGlnbm1lbnQgaXMgYWxyZWFkeSBkb25lLlxuICB0aGlzLndyaXRlSW50MzIodGhpcy5vZmZzZXQoKSAtIG9mZnNldCArIGZsYXRidWZmZXJzLlNJWkVPRl9JTlQpO1xufTtcblxuLy8vIEBjb25kIEZMQVRCVUZGRVJTX0lOVEVSTkFMXG4vKipcbiAqIFN0YXJ0IGVuY29kaW5nIGEgbmV3IG9iamVjdCBpbiB0aGUgYnVmZmVyLiAgVXNlcnMgd2lsbCBub3QgdXN1YWxseSBuZWVkIHRvXG4gKiBjYWxsIHRoaXMgZGlyZWN0bHkuIFRoZSBGbGF0QnVmZmVycyBjb21waWxlciB3aWxsIGdlbmVyYXRlIGhlbHBlciBtZXRob2RzXG4gKiB0aGF0IGNhbGwgdGhpcyBtZXRob2QgaW50ZXJuYWxseS5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gbnVtZmllbGRzXG4gKi9cbmZsYXRidWZmZXJzLkJ1aWxkZXIucHJvdG90eXBlLnN0YXJ0T2JqZWN0ID0gZnVuY3Rpb24obnVtZmllbGRzKSB7XG4gIHRoaXMubm90TmVzdGVkKCk7XG4gIGlmICh0aGlzLnZ0YWJsZSA9PSBudWxsKSB7XG4gICAgdGhpcy52dGFibGUgPSBbXTtcbiAgfVxuICB0aGlzLnZ0YWJsZV9pbl91c2UgPSBudW1maWVsZHM7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbnVtZmllbGRzOyBpKyspIHtcbiAgICB0aGlzLnZ0YWJsZVtpXSA9IDA7IC8vIFRoaXMgd2lsbCBwdXNoIGFkZGl0aW9uYWwgZWxlbWVudHMgYXMgbmVlZGVkXG4gIH1cbiAgdGhpcy5pc05lc3RlZCA9IHRydWU7XG4gIHRoaXMub2JqZWN0X3N0YXJ0ID0gdGhpcy5vZmZzZXQoKTtcbn07XG5cbi8qKlxuICogRmluaXNoIG9mZiB3cml0aW5nIHRoZSBvYmplY3QgdGhhdCBpcyB1bmRlciBjb25zdHJ1Y3Rpb24uXG4gKlxuICogQHJldHVybnMge2ZsYXRidWZmZXJzLk9mZnNldH0gVGhlIG9mZnNldCB0byB0aGUgb2JqZWN0IGluc2lkZSBgZGF0YUJ1ZmZlcmBcbiAqL1xuZmxhdGJ1ZmZlcnMuQnVpbGRlci5wcm90b3R5cGUuZW5kT2JqZWN0ID0gZnVuY3Rpb24oKSB7XG4gIGlmICh0aGlzLnZ0YWJsZSA9PSBudWxsIHx8ICF0aGlzLmlzTmVzdGVkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdGbGF0QnVmZmVyczogZW5kT2JqZWN0IGNhbGxlZCB3aXRob3V0IHN0YXJ0T2JqZWN0Jyk7XG4gIH1cblxuICB0aGlzLmFkZEludDMyKDApO1xuICB2YXIgdnRhYmxlbG9jID0gdGhpcy5vZmZzZXQoKTtcblxuICAvLyBUcmltIHRyYWlsaW5nIHplcm9lcy5cbiAgdmFyIGkgPSB0aGlzLnZ0YWJsZV9pbl91c2UgLSAxO1xuICBmb3IgKDsgaSA+PSAwICYmIHRoaXMudnRhYmxlW2ldID09IDA7IGktLSkge31cbiAgdmFyIHRyaW1tZWRfc2l6ZSA9IGkgKyAxO1xuXG4gIC8vIFdyaXRlIG91dCB0aGUgY3VycmVudCB2dGFibGUuXG4gIGZvciAoOyBpID49IDA7IGktLSkge1xuICAgIC8vIE9mZnNldCByZWxhdGl2ZSB0byB0aGUgc3RhcnQgb2YgdGhlIHRhYmxlLlxuICAgIHRoaXMuYWRkSW50MTYodGhpcy52dGFibGVbaV0gIT0gMCA/IHZ0YWJsZWxvYyAtIHRoaXMudnRhYmxlW2ldIDogMCk7XG4gIH1cblxuICB2YXIgc3RhbmRhcmRfZmllbGRzID0gMjsgLy8gVGhlIGZpZWxkcyBiZWxvdzpcbiAgdGhpcy5hZGRJbnQxNih2dGFibGVsb2MgLSB0aGlzLm9iamVjdF9zdGFydCk7XG4gIHZhciBsZW4gPSAodHJpbW1lZF9zaXplICsgc3RhbmRhcmRfZmllbGRzKSAqIGZsYXRidWZmZXJzLlNJWkVPRl9TSE9SVDtcbiAgdGhpcy5hZGRJbnQxNihsZW4pO1xuXG4gIC8vIFNlYXJjaCBmb3IgYW4gZXhpc3RpbmcgdnRhYmxlIHRoYXQgbWF0Y2hlcyB0aGUgY3VycmVudCBvbmUuXG4gIHZhciBleGlzdGluZ192dGFibGUgPSAwO1xuICB2YXIgdnQxID0gdGhpcy5zcGFjZTtcbm91dGVyX2xvb3A6XG4gIGZvciAoaSA9IDA7IGkgPCB0aGlzLnZ0YWJsZXMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgdnQyID0gdGhpcy5iYi5jYXBhY2l0eSgpIC0gdGhpcy52dGFibGVzW2ldO1xuICAgIGlmIChsZW4gPT0gdGhpcy5iYi5yZWFkSW50MTYodnQyKSkge1xuICAgICAgZm9yICh2YXIgaiA9IGZsYXRidWZmZXJzLlNJWkVPRl9TSE9SVDsgaiA8IGxlbjsgaiArPSBmbGF0YnVmZmVycy5TSVpFT0ZfU0hPUlQpIHtcbiAgICAgICAgaWYgKHRoaXMuYmIucmVhZEludDE2KHZ0MSArIGopICE9IHRoaXMuYmIucmVhZEludDE2KHZ0MiArIGopKSB7XG4gICAgICAgICAgY29udGludWUgb3V0ZXJfbG9vcDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgZXhpc3RpbmdfdnRhYmxlID0gdGhpcy52dGFibGVzW2ldO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgaWYgKGV4aXN0aW5nX3Z0YWJsZSkge1xuICAgIC8vIEZvdW5kIGEgbWF0Y2g6XG4gICAgLy8gUmVtb3ZlIHRoZSBjdXJyZW50IHZ0YWJsZS5cbiAgICB0aGlzLnNwYWNlID0gdGhpcy5iYi5jYXBhY2l0eSgpIC0gdnRhYmxlbG9jO1xuXG4gICAgLy8gUG9pbnQgdGFibGUgdG8gZXhpc3RpbmcgdnRhYmxlLlxuICAgIHRoaXMuYmIud3JpdGVJbnQzMih0aGlzLnNwYWNlLCBleGlzdGluZ192dGFibGUgLSB2dGFibGVsb2MpO1xuICB9IGVsc2Uge1xuICAgIC8vIE5vIG1hdGNoOlxuICAgIC8vIEFkZCB0aGUgbG9jYXRpb24gb2YgdGhlIGN1cnJlbnQgdnRhYmxlIHRvIHRoZSBsaXN0IG9mIHZ0YWJsZXMuXG4gICAgdGhpcy52dGFibGVzLnB1c2godGhpcy5vZmZzZXQoKSk7XG5cbiAgICAvLyBQb2ludCB0YWJsZSB0byBjdXJyZW50IHZ0YWJsZS5cbiAgICB0aGlzLmJiLndyaXRlSW50MzIodGhpcy5iYi5jYXBhY2l0eSgpIC0gdnRhYmxlbG9jLCB0aGlzLm9mZnNldCgpIC0gdnRhYmxlbG9jKTtcbiAgfVxuXG4gIHRoaXMuaXNOZXN0ZWQgPSBmYWxzZTtcbiAgcmV0dXJuIHZ0YWJsZWxvYztcbn07XG4vLy8gQGVuZGNvbmRcblxuLyoqXG4gKiBGaW5hbGl6ZSBhIGJ1ZmZlciwgcG9pdGluZyB0byB0aGUgZ2l2ZW4gYHJvb3RfdGFibGVgLlxuICpcbiAqIEBwYXJhbSB7ZmxhdGJ1ZmZlcnMuT2Zmc2V0fSByb290X3RhYmxlXG4gKiBAcGFyYW0ge3N0cmluZz19IG9wdF9maWxlX2lkZW50aWZpZXJcbiAqIEBwYXJhbSB7Ym9vbGVhbj19IG9wdF9zaXplX3ByZWZpeFxuICovXG5mbGF0YnVmZmVycy5CdWlsZGVyLnByb3RvdHlwZS5maW5pc2ggPSBmdW5jdGlvbihyb290X3RhYmxlLCBvcHRfZmlsZV9pZGVudGlmaWVyLCBvcHRfc2l6ZV9wcmVmaXgpIHtcbiAgdmFyIHNpemVfcHJlZml4ID0gb3B0X3NpemVfcHJlZml4ID8gZmxhdGJ1ZmZlcnMuU0laRV9QUkVGSVhfTEVOR1RIIDogMDtcbiAgaWYgKG9wdF9maWxlX2lkZW50aWZpZXIpIHtcbiAgICB2YXIgZmlsZV9pZGVudGlmaWVyID0gb3B0X2ZpbGVfaWRlbnRpZmllcjtcbiAgICB0aGlzLnByZXAodGhpcy5taW5hbGlnbiwgZmxhdGJ1ZmZlcnMuU0laRU9GX0lOVCArXG4gICAgICBmbGF0YnVmZmVycy5GSUxFX0lERU5USUZJRVJfTEVOR1RIICsgc2l6ZV9wcmVmaXgpO1xuICAgIGlmIChmaWxlX2lkZW50aWZpZXIubGVuZ3RoICE9IGZsYXRidWZmZXJzLkZJTEVfSURFTlRJRklFUl9MRU5HVEgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRmxhdEJ1ZmZlcnM6IGZpbGUgaWRlbnRpZmllciBtdXN0IGJlIGxlbmd0aCAnICtcbiAgICAgICAgZmxhdGJ1ZmZlcnMuRklMRV9JREVOVElGSUVSX0xFTkdUSCk7XG4gICAgfVxuICAgIGZvciAodmFyIGkgPSBmbGF0YnVmZmVycy5GSUxFX0lERU5USUZJRVJfTEVOR1RIIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIHRoaXMud3JpdGVJbnQ4KGZpbGVfaWRlbnRpZmllci5jaGFyQ29kZUF0KGkpKTtcbiAgICB9XG4gIH1cbiAgdGhpcy5wcmVwKHRoaXMubWluYWxpZ24sIGZsYXRidWZmZXJzLlNJWkVPRl9JTlQgKyBzaXplX3ByZWZpeCk7XG4gIHRoaXMuYWRkT2Zmc2V0KHJvb3RfdGFibGUpO1xuICBpZiAoc2l6ZV9wcmVmaXgpIHtcbiAgICB0aGlzLmFkZEludDMyKHRoaXMuYmIuY2FwYWNpdHkoKSAtIHRoaXMuc3BhY2UpO1xuICB9XG4gIHRoaXMuYmIuc2V0UG9zaXRpb24odGhpcy5zcGFjZSk7XG59O1xuXG4vKipcbiAqIEZpbmFsaXplIGEgc2l6ZSBwcmVmaXhlZCBidWZmZXIsIHBvaW50aW5nIHRvIHRoZSBnaXZlbiBgcm9vdF90YWJsZWAuXG4gKlxuICogQHBhcmFtIHtmbGF0YnVmZmVycy5PZmZzZXR9IHJvb3RfdGFibGVcbiAqIEBwYXJhbSB7c3RyaW5nPX0gb3B0X2ZpbGVfaWRlbnRpZmllclxuICovXG5mbGF0YnVmZmVycy5CdWlsZGVyLnByb3RvdHlwZS5maW5pc2hTaXplUHJlZml4ZWQgPSBmdW5jdGlvbiAocm9vdF90YWJsZSwgb3B0X2ZpbGVfaWRlbnRpZmllcikge1xuICB0aGlzLmZpbmlzaChyb290X3RhYmxlLCBvcHRfZmlsZV9pZGVudGlmaWVyLCB0cnVlKTtcbn07XG5cbi8vLyBAY29uZCBGTEFUQlVGRkVSU19JTlRFUk5BTFxuLyoqXG4gKiBUaGlzIGNoZWNrcyBhIHJlcXVpcmVkIGZpZWxkIGhhcyBiZWVuIHNldCBpbiBhIGdpdmVuIHRhYmxlIHRoYXQgaGFzXG4gKiBqdXN0IGJlZW4gY29uc3RydWN0ZWQuXG4gKlxuICogQHBhcmFtIHtmbGF0YnVmZmVycy5PZmZzZXR9IHRhYmxlXG4gKiBAcGFyYW0ge251bWJlcn0gZmllbGRcbiAqL1xuZmxhdGJ1ZmZlcnMuQnVpbGRlci5wcm90b3R5cGUucmVxdWlyZWRGaWVsZCA9IGZ1bmN0aW9uKHRhYmxlLCBmaWVsZCkge1xuICB2YXIgdGFibGVfc3RhcnQgPSB0aGlzLmJiLmNhcGFjaXR5KCkgLSB0YWJsZTtcbiAgdmFyIHZ0YWJsZV9zdGFydCA9IHRhYmxlX3N0YXJ0IC0gdGhpcy5iYi5yZWFkSW50MzIodGFibGVfc3RhcnQpO1xuICB2YXIgb2sgPSB0aGlzLmJiLnJlYWRJbnQxNih2dGFibGVfc3RhcnQgKyBmaWVsZCkgIT0gMDtcblxuICAvLyBJZiB0aGlzIGZhaWxzLCB0aGUgY2FsbGVyIHdpbGwgc2hvdyB3aGF0IGZpZWxkIG5lZWRzIHRvIGJlIHNldC5cbiAgaWYgKCFvaykge1xuICAgIHRocm93IG5ldyBFcnJvcignRmxhdEJ1ZmZlcnM6IGZpZWxkICcgKyBmaWVsZCArICcgbXVzdCBiZSBzZXQnKTtcbiAgfVxufTtcblxuLyoqXG4gKiBTdGFydCBhIG5ldyBhcnJheS92ZWN0b3Igb2Ygb2JqZWN0cy4gIFVzZXJzIHVzdWFsbHkgd2lsbCBub3QgY2FsbFxuICogdGhpcyBkaXJlY3RseS4gVGhlIEZsYXRCdWZmZXJzIGNvbXBpbGVyIHdpbGwgY3JlYXRlIGEgc3RhcnQvZW5kXG4gKiBtZXRob2QgZm9yIHZlY3RvciB0eXBlcyBpbiBnZW5lcmF0ZWQgY29kZS5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gZWxlbV9zaXplIFRoZSBzaXplIG9mIGVhY2ggZWxlbWVudCBpbiB0aGUgYXJyYXlcbiAqIEBwYXJhbSB7bnVtYmVyfSBudW1fZWxlbXMgVGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGUgYXJyYXlcbiAqIEBwYXJhbSB7bnVtYmVyfSBhbGlnbm1lbnQgVGhlIGFsaWdubWVudCBvZiB0aGUgYXJyYXlcbiAqL1xuZmxhdGJ1ZmZlcnMuQnVpbGRlci5wcm90b3R5cGUuc3RhcnRWZWN0b3IgPSBmdW5jdGlvbihlbGVtX3NpemUsIG51bV9lbGVtcywgYWxpZ25tZW50KSB7XG4gIHRoaXMubm90TmVzdGVkKCk7XG4gIHRoaXMudmVjdG9yX251bV9lbGVtcyA9IG51bV9lbGVtcztcbiAgdGhpcy5wcmVwKGZsYXRidWZmZXJzLlNJWkVPRl9JTlQsIGVsZW1fc2l6ZSAqIG51bV9lbGVtcyk7XG4gIHRoaXMucHJlcChhbGlnbm1lbnQsIGVsZW1fc2l6ZSAqIG51bV9lbGVtcyk7IC8vIEp1c3QgaW4gY2FzZSBhbGlnbm1lbnQgPiBpbnQuXG59O1xuXG4vKipcbiAqIEZpbmlzaCBvZmYgdGhlIGNyZWF0aW9uIG9mIGFuIGFycmF5IGFuZCBhbGwgaXRzIGVsZW1lbnRzLiBUaGUgYXJyYXkgbXVzdCBiZVxuICogY3JlYXRlZCB3aXRoIGBzdGFydFZlY3RvcmAuXG4gKlxuICogQHJldHVybnMge2ZsYXRidWZmZXJzLk9mZnNldH0gVGhlIG9mZnNldCBhdCB3aGljaCB0aGUgbmV3bHkgY3JlYXRlZCBhcnJheVxuICogc3RhcnRzLlxuICovXG5mbGF0YnVmZmVycy5CdWlsZGVyLnByb3RvdHlwZS5lbmRWZWN0b3IgPSBmdW5jdGlvbigpIHtcbiAgdGhpcy53cml0ZUludDMyKHRoaXMudmVjdG9yX251bV9lbGVtcyk7XG4gIHJldHVybiB0aGlzLm9mZnNldCgpO1xufTtcbi8vLyBAZW5kY29uZFxuXG4vKipcbiAqIEVuY29kZSB0aGUgc3RyaW5nIGBzYCBpbiB0aGUgYnVmZmVyIHVzaW5nIFVURi04LiBJZiBhIFVpbnQ4QXJyYXkgaXMgcGFzc2VkXG4gKiBpbnN0ZWFkIG9mIGEgc3RyaW5nLCBpdCBpcyBhc3N1bWVkIHRvIGNvbnRhaW4gdmFsaWQgVVRGLTggZW5jb2RlZCBkYXRhLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfFVpbnQ4QXJyYXl9IHMgVGhlIHN0cmluZyB0byBlbmNvZGVcbiAqIEByZXR1cm4ge2ZsYXRidWZmZXJzLk9mZnNldH0gVGhlIG9mZnNldCBpbiB0aGUgYnVmZmVyIHdoZXJlIHRoZSBlbmNvZGVkIHN0cmluZyBzdGFydHNcbiAqL1xuZmxhdGJ1ZmZlcnMuQnVpbGRlci5wcm90b3R5cGUuY3JlYXRlU3RyaW5nID0gZnVuY3Rpb24ocykge1xuICBpZiAocyBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHtcbiAgICB2YXIgdXRmOCA9IHM7XG4gIH0gZWxzZSB7XG4gICAgdmFyIHV0ZjggPSBbXTtcbiAgICB2YXIgaSA9IDA7XG5cbiAgICB3aGlsZSAoaSA8IHMubGVuZ3RoKSB7XG4gICAgICB2YXIgY29kZVBvaW50O1xuXG4gICAgICAvLyBEZWNvZGUgVVRGLTE2XG4gICAgICB2YXIgYSA9IHMuY2hhckNvZGVBdChpKyspO1xuICAgICAgaWYgKGEgPCAweEQ4MDAgfHwgYSA+PSAweERDMDApIHtcbiAgICAgICAgY29kZVBvaW50ID0gYTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciBiID0gcy5jaGFyQ29kZUF0KGkrKyk7XG4gICAgICAgIGNvZGVQb2ludCA9IChhIDw8IDEwKSArIGIgKyAoMHgxMDAwMCAtICgweEQ4MDAgPDwgMTApIC0gMHhEQzAwKTtcbiAgICAgIH1cblxuICAgICAgLy8gRW5jb2RlIFVURi04XG4gICAgICBpZiAoY29kZVBvaW50IDwgMHg4MCkge1xuICAgICAgICB1dGY4LnB1c2goY29kZVBvaW50KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChjb2RlUG9pbnQgPCAweDgwMCkge1xuICAgICAgICAgIHV0ZjgucHVzaCgoKGNvZGVQb2ludCA+PiA2KSAmIDB4MUYpIHwgMHhDMCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKGNvZGVQb2ludCA8IDB4MTAwMDApIHtcbiAgICAgICAgICAgIHV0ZjgucHVzaCgoKGNvZGVQb2ludCA+PiAxMikgJiAweDBGKSB8IDB4RTApO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB1dGY4LnB1c2goXG4gICAgICAgICAgICAgICgoY29kZVBvaW50ID4+IDE4KSAmIDB4MDcpIHwgMHhGMCxcbiAgICAgICAgICAgICAgKChjb2RlUG9pbnQgPj4gMTIpICYgMHgzRikgfCAweDgwKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdXRmOC5wdXNoKCgoY29kZVBvaW50ID4+IDYpICYgMHgzRikgfCAweDgwKTtcbiAgICAgICAgfVxuICAgICAgICB1dGY4LnB1c2goKGNvZGVQb2ludCAmIDB4M0YpIHwgMHg4MCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdGhpcy5hZGRJbnQ4KDApO1xuICB0aGlzLnN0YXJ0VmVjdG9yKDEsIHV0ZjgubGVuZ3RoLCAxKTtcbiAgdGhpcy5iYi5zZXRQb3NpdGlvbih0aGlzLnNwYWNlIC09IHV0ZjgubGVuZ3RoKTtcbiAgZm9yICh2YXIgaSA9IDAsIG9mZnNldCA9IHRoaXMuc3BhY2UsIGJ5dGVzID0gdGhpcy5iYi5ieXRlcygpOyBpIDwgdXRmOC5sZW5ndGg7IGkrKykge1xuICAgIGJ5dGVzW29mZnNldCsrXSA9IHV0ZjhbaV07XG4gIH1cbiAgcmV0dXJuIHRoaXMuZW5kVmVjdG9yKCk7XG59O1xuXG4vKipcbiAqIEEgaGVscGVyIGZ1bmN0aW9uIHRvIGF2b2lkIGdlbmVyYXRlZCBjb2RlIGRlcGVuZGluZyBvbiB0aGlzIGZpbGUgZGlyZWN0bHkuXG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IGxvd1xuICogQHBhcmFtIHtudW1iZXJ9IGhpZ2hcbiAqIEByZXR1cm5zIHshZmxhdGJ1ZmZlcnMuTG9uZ31cbiAqL1xuZmxhdGJ1ZmZlcnMuQnVpbGRlci5wcm90b3R5cGUuY3JlYXRlTG9uZyA9IGZ1bmN0aW9uKGxvdywgaGlnaCkge1xuICByZXR1cm4gZmxhdGJ1ZmZlcnMuTG9uZy5jcmVhdGUobG93LCBoaWdoKTtcbn07XG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuLy8vIEBjb25kIEZMQVRCVUZGRVJTX0lOVEVSTkFMXG4vKipcbiAqIENyZWF0ZSBhIG5ldyBCeXRlQnVmZmVyIHdpdGggYSBnaXZlbiBhcnJheSBvZiBieXRlcyAoYFVpbnQ4QXJyYXlgKS5cbiAqXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7VWludDhBcnJheX0gYnl0ZXNcbiAqL1xuZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlciA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gIC8qKlxuICAgKiBAdHlwZSB7VWludDhBcnJheX1cbiAgICogQHByaXZhdGVcbiAgICovXG4gIHRoaXMuYnl0ZXNfID0gYnl0ZXM7XG5cbiAgLyoqXG4gICAqIEB0eXBlIHtudW1iZXJ9XG4gICAqIEBwcml2YXRlXG4gICAqL1xuICB0aGlzLnBvc2l0aW9uXyA9IDA7XG59O1xuXG4vKipcbiAqIENyZWF0ZSBhbmQgYWxsb2NhdGUgYSBuZXcgQnl0ZUJ1ZmZlciB3aXRoIGEgZ2l2ZW4gc2l6ZS5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gYnl0ZV9zaXplXG4gKiBAcmV0dXJucyB7IWZsYXRidWZmZXJzLkJ5dGVCdWZmZXJ9XG4gKi9cbmZsYXRidWZmZXJzLkJ5dGVCdWZmZXIuYWxsb2NhdGUgPSBmdW5jdGlvbihieXRlX3NpemUpIHtcbiAgcmV0dXJuIG5ldyBmbGF0YnVmZmVycy5CeXRlQnVmZmVyKG5ldyBVaW50OEFycmF5KGJ5dGVfc2l6ZSkpO1xufTtcblxuZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlci5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5wb3NpdGlvbl8gPSAwO1xufTtcblxuLyoqXG4gKiBHZXQgdGhlIHVuZGVybHlpbmcgYFVpbnQ4QXJyYXlgLlxuICpcbiAqIEByZXR1cm5zIHtVaW50OEFycmF5fVxuICovXG5mbGF0YnVmZmVycy5CeXRlQnVmZmVyLnByb3RvdHlwZS5ieXRlcyA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gdGhpcy5ieXRlc187XG59O1xuXG4vKipcbiAqIEdldCB0aGUgYnVmZmVyJ3MgcG9zaXRpb24uXG4gKlxuICogQHJldHVybnMge251bWJlcn1cbiAqL1xuZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlci5wcm90b3R5cGUucG9zaXRpb24gPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMucG9zaXRpb25fO1xufTtcblxuLyoqXG4gKiBTZXQgdGhlIGJ1ZmZlcidzIHBvc2l0aW9uLlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBwb3NpdGlvblxuICovXG5mbGF0YnVmZmVycy5CeXRlQnVmZmVyLnByb3RvdHlwZS5zZXRQb3NpdGlvbiA9IGZ1bmN0aW9uKHBvc2l0aW9uKSB7XG4gIHRoaXMucG9zaXRpb25fID0gcG9zaXRpb247XG59O1xuXG4vKipcbiAqIEdldCB0aGUgYnVmZmVyJ3MgY2FwYWNpdHkuXG4gKlxuICogQHJldHVybnMge251bWJlcn1cbiAqL1xuZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlci5wcm90b3R5cGUuY2FwYWNpdHkgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMuYnl0ZXNfLmxlbmd0aDtcbn07XG5cbi8qKlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldFxuICogQHJldHVybnMge251bWJlcn1cbiAqL1xuZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlci5wcm90b3R5cGUucmVhZEludDggPSBmdW5jdGlvbihvZmZzZXQpIHtcbiAgcmV0dXJuIHRoaXMucmVhZFVpbnQ4KG9mZnNldCkgPDwgMjQgPj4gMjQ7XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXRcbiAqIEByZXR1cm5zIHtudW1iZXJ9XG4gKi9cbmZsYXRidWZmZXJzLkJ5dGVCdWZmZXIucHJvdG90eXBlLnJlYWRVaW50OCA9IGZ1bmN0aW9uKG9mZnNldCkge1xuICByZXR1cm4gdGhpcy5ieXRlc19bb2Zmc2V0XTtcbn07XG5cbi8qKlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldFxuICogQHJldHVybnMge251bWJlcn1cbiAqL1xuZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlci5wcm90b3R5cGUucmVhZEludDE2ID0gZnVuY3Rpb24ob2Zmc2V0KSB7XG4gIHJldHVybiB0aGlzLnJlYWRVaW50MTYob2Zmc2V0KSA8PCAxNiA+PiAxNjtcbn07XG5cbi8qKlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldFxuICogQHJldHVybnMge251bWJlcn1cbiAqL1xuZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlci5wcm90b3R5cGUucmVhZFVpbnQxNiA9IGZ1bmN0aW9uKG9mZnNldCkge1xuICByZXR1cm4gdGhpcy5ieXRlc19bb2Zmc2V0XSB8IHRoaXMuYnl0ZXNfW29mZnNldCArIDFdIDw8IDg7XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXRcbiAqIEByZXR1cm5zIHtudW1iZXJ9XG4gKi9cbmZsYXRidWZmZXJzLkJ5dGVCdWZmZXIucHJvdG90eXBlLnJlYWRJbnQzMiA9IGZ1bmN0aW9uKG9mZnNldCkge1xuICByZXR1cm4gdGhpcy5ieXRlc19bb2Zmc2V0XSB8IHRoaXMuYnl0ZXNfW29mZnNldCArIDFdIDw8IDggfCB0aGlzLmJ5dGVzX1tvZmZzZXQgKyAyXSA8PCAxNiB8IHRoaXMuYnl0ZXNfW29mZnNldCArIDNdIDw8IDI0O1xufTtcblxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0XG4gKiBAcmV0dXJucyB7bnVtYmVyfVxuICovXG5mbGF0YnVmZmVycy5CeXRlQnVmZmVyLnByb3RvdHlwZS5yZWFkVWludDMyID0gZnVuY3Rpb24ob2Zmc2V0KSB7XG4gIHJldHVybiB0aGlzLnJlYWRJbnQzMihvZmZzZXQpID4+PiAwO1xufTtcblxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0XG4gKiBAcmV0dXJucyB7IWZsYXRidWZmZXJzLkxvbmd9XG4gKi9cbmZsYXRidWZmZXJzLkJ5dGVCdWZmZXIucHJvdG90eXBlLnJlYWRJbnQ2NCA9IGZ1bmN0aW9uKG9mZnNldCkge1xuICByZXR1cm4gbmV3IGZsYXRidWZmZXJzLkxvbmcodGhpcy5yZWFkSW50MzIob2Zmc2V0KSwgdGhpcy5yZWFkSW50MzIob2Zmc2V0ICsgNCkpO1xufTtcblxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0XG4gKiBAcmV0dXJucyB7IWZsYXRidWZmZXJzLkxvbmd9XG4gKi9cbmZsYXRidWZmZXJzLkJ5dGVCdWZmZXIucHJvdG90eXBlLnJlYWRVaW50NjQgPSBmdW5jdGlvbihvZmZzZXQpIHtcbiAgcmV0dXJuIG5ldyBmbGF0YnVmZmVycy5Mb25nKHRoaXMucmVhZFVpbnQzMihvZmZzZXQpLCB0aGlzLnJlYWRVaW50MzIob2Zmc2V0ICsgNCkpO1xufTtcblxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0XG4gKiBAcmV0dXJucyB7bnVtYmVyfVxuICovXG5mbGF0YnVmZmVycy5CeXRlQnVmZmVyLnByb3RvdHlwZS5yZWFkRmxvYXQzMiA9IGZ1bmN0aW9uKG9mZnNldCkge1xuICBmbGF0YnVmZmVycy5pbnQzMlswXSA9IHRoaXMucmVhZEludDMyKG9mZnNldCk7XG4gIHJldHVybiBmbGF0YnVmZmVycy5mbG9hdDMyWzBdO1xufTtcblxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0XG4gKiBAcmV0dXJucyB7bnVtYmVyfVxuICovXG5mbGF0YnVmZmVycy5CeXRlQnVmZmVyLnByb3RvdHlwZS5yZWFkRmxvYXQ2NCA9IGZ1bmN0aW9uKG9mZnNldCkge1xuICBmbGF0YnVmZmVycy5pbnQzMltmbGF0YnVmZmVycy5pc0xpdHRsZUVuZGlhbiA/IDAgOiAxXSA9IHRoaXMucmVhZEludDMyKG9mZnNldCk7XG4gIGZsYXRidWZmZXJzLmludDMyW2ZsYXRidWZmZXJzLmlzTGl0dGxlRW5kaWFuID8gMSA6IDBdID0gdGhpcy5yZWFkSW50MzIob2Zmc2V0ICsgNCk7XG4gIHJldHVybiBmbGF0YnVmZmVycy5mbG9hdDY0WzBdO1xufTtcblxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0XG4gKiBAcGFyYW0ge251bWJlcnxib29sZWFufSB2YWx1ZVxuICovXG5mbGF0YnVmZmVycy5CeXRlQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDggPSBmdW5jdGlvbihvZmZzZXQsIHZhbHVlKSB7XG4gIHRoaXMuYnl0ZXNfW29mZnNldF0gPSAvKiogQHR5cGUge251bWJlcn0gKi8odmFsdWUpO1xufTtcblxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0XG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWVcbiAqL1xuZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlci5wcm90b3R5cGUud3JpdGVVaW50OCA9IGZ1bmN0aW9uKG9mZnNldCwgdmFsdWUpIHtcbiAgdGhpcy5ieXRlc19bb2Zmc2V0XSA9IHZhbHVlO1xufTtcblxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0XG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWVcbiAqL1xuZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQxNiA9IGZ1bmN0aW9uKG9mZnNldCwgdmFsdWUpIHtcbiAgdGhpcy5ieXRlc19bb2Zmc2V0XSA9IHZhbHVlO1xuICB0aGlzLmJ5dGVzX1tvZmZzZXQgKyAxXSA9IHZhbHVlID4+IDg7XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXRcbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZVxuICovXG5mbGF0YnVmZmVycy5CeXRlQnVmZmVyLnByb3RvdHlwZS53cml0ZVVpbnQxNiA9IGZ1bmN0aW9uKG9mZnNldCwgdmFsdWUpIHtcbiAgICB0aGlzLmJ5dGVzX1tvZmZzZXRdID0gdmFsdWU7XG4gICAgdGhpcy5ieXRlc19bb2Zmc2V0ICsgMV0gPSB2YWx1ZSA+PiA4O1xufTtcblxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0XG4gKiBAcGFyYW0ge251bWJlcn0gdmFsdWVcbiAqL1xuZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQzMiA9IGZ1bmN0aW9uKG9mZnNldCwgdmFsdWUpIHtcbiAgdGhpcy5ieXRlc19bb2Zmc2V0XSA9IHZhbHVlO1xuICB0aGlzLmJ5dGVzX1tvZmZzZXQgKyAxXSA9IHZhbHVlID4+IDg7XG4gIHRoaXMuYnl0ZXNfW29mZnNldCArIDJdID0gdmFsdWUgPj4gMTY7XG4gIHRoaXMuYnl0ZXNfW29mZnNldCArIDNdID0gdmFsdWUgPj4gMjQ7XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXRcbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZVxuICovXG5mbGF0YnVmZmVycy5CeXRlQnVmZmVyLnByb3RvdHlwZS53cml0ZVVpbnQzMiA9IGZ1bmN0aW9uKG9mZnNldCwgdmFsdWUpIHtcbiAgICB0aGlzLmJ5dGVzX1tvZmZzZXRdID0gdmFsdWU7XG4gICAgdGhpcy5ieXRlc19bb2Zmc2V0ICsgMV0gPSB2YWx1ZSA+PiA4O1xuICAgIHRoaXMuYnl0ZXNfW29mZnNldCArIDJdID0gdmFsdWUgPj4gMTY7XG4gICAgdGhpcy5ieXRlc19bb2Zmc2V0ICsgM10gPSB2YWx1ZSA+PiAyNDtcbn07XG5cbi8qKlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldFxuICogQHBhcmFtIHtmbGF0YnVmZmVycy5Mb25nfSB2YWx1ZVxuICovXG5mbGF0YnVmZmVycy5CeXRlQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDY0ID0gZnVuY3Rpb24ob2Zmc2V0LCB2YWx1ZSkge1xuICB0aGlzLndyaXRlSW50MzIob2Zmc2V0LCB2YWx1ZS5sb3cpO1xuICB0aGlzLndyaXRlSW50MzIob2Zmc2V0ICsgNCwgdmFsdWUuaGlnaCk7XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXRcbiAqIEBwYXJhbSB7ZmxhdGJ1ZmZlcnMuTG9uZ30gdmFsdWVcbiAqL1xuZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlci5wcm90b3R5cGUud3JpdGVVaW50NjQgPSBmdW5jdGlvbihvZmZzZXQsIHZhbHVlKSB7XG4gICAgdGhpcy53cml0ZVVpbnQzMihvZmZzZXQsIHZhbHVlLmxvdyk7XG4gICAgdGhpcy53cml0ZVVpbnQzMihvZmZzZXQgKyA0LCB2YWx1ZS5oaWdoKTtcbn07XG5cbi8qKlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldFxuICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlXG4gKi9cbmZsYXRidWZmZXJzLkJ5dGVCdWZmZXIucHJvdG90eXBlLndyaXRlRmxvYXQzMiA9IGZ1bmN0aW9uKG9mZnNldCwgdmFsdWUpIHtcbiAgZmxhdGJ1ZmZlcnMuZmxvYXQzMlswXSA9IHZhbHVlO1xuICB0aGlzLndyaXRlSW50MzIob2Zmc2V0LCBmbGF0YnVmZmVycy5pbnQzMlswXSk7XG59O1xuXG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXRcbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZVxuICovXG5mbGF0YnVmZmVycy5CeXRlQnVmZmVyLnByb3RvdHlwZS53cml0ZUZsb2F0NjQgPSBmdW5jdGlvbihvZmZzZXQsIHZhbHVlKSB7XG4gIGZsYXRidWZmZXJzLmZsb2F0NjRbMF0gPSB2YWx1ZTtcbiAgdGhpcy53cml0ZUludDMyKG9mZnNldCwgZmxhdGJ1ZmZlcnMuaW50MzJbZmxhdGJ1ZmZlcnMuaXNMaXR0bGVFbmRpYW4gPyAwIDogMV0pO1xuICB0aGlzLndyaXRlSW50MzIob2Zmc2V0ICsgNCwgZmxhdGJ1ZmZlcnMuaW50MzJbZmxhdGJ1ZmZlcnMuaXNMaXR0bGVFbmRpYW4gPyAxIDogMF0pO1xufTtcblxuLyoqXG4gKiBSZXR1cm4gdGhlIGZpbGUgaWRlbnRpZmllci4gICBCZWhhdmlvciBpcyB1bmRlZmluZWQgZm9yIEZsYXRCdWZmZXJzIHdob3NlXG4gKiBzY2hlbWEgZG9lcyBub3QgaW5jbHVkZSBhIGZpbGVfaWRlbnRpZmllciAobGlrZWx5IHBvaW50cyBhdCBwYWRkaW5nIG9yIHRoZVxuICogc3RhcnQgb2YgYSB0aGUgcm9vdCB2dGFibGUpLlxuICogQHJldHVybnMge3N0cmluZ31cbiAqL1xuZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlci5wcm90b3R5cGUuZ2V0QnVmZmVySWRlbnRpZmllciA9IGZ1bmN0aW9uKCkge1xuICBpZiAodGhpcy5ieXRlc18ubGVuZ3RoIDwgdGhpcy5wb3NpdGlvbl8gKyBmbGF0YnVmZmVycy5TSVpFT0ZfSU5UICtcbiAgICAgIGZsYXRidWZmZXJzLkZJTEVfSURFTlRJRklFUl9MRU5HVEgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICdGbGF0QnVmZmVyczogQnl0ZUJ1ZmZlciBpcyB0b28gc2hvcnQgdG8gY29udGFpbiBhbiBpZGVudGlmaWVyLicpO1xuICB9XG4gIHZhciByZXN1bHQgPSBcIlwiO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGZsYXRidWZmZXJzLkZJTEVfSURFTlRJRklFUl9MRU5HVEg7IGkrKykge1xuICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKFxuICAgICAgICB0aGlzLnJlYWRJbnQ4KHRoaXMucG9zaXRpb25fICsgZmxhdGJ1ZmZlcnMuU0laRU9GX0lOVCArIGkpKTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufTtcblxuLyoqXG4gKiBMb29rIHVwIGEgZmllbGQgaW4gdGhlIHZ0YWJsZSwgcmV0dXJuIGFuIG9mZnNldCBpbnRvIHRoZSBvYmplY3QsIG9yIDAgaWYgdGhlXG4gKiBmaWVsZCBpcyBub3QgcHJlc2VudC5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gYmJfcG9zXG4gKiBAcGFyYW0ge251bWJlcn0gdnRhYmxlX29mZnNldFxuICogQHJldHVybnMge251bWJlcn1cbiAqL1xuZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlci5wcm90b3R5cGUuX19vZmZzZXQgPSBmdW5jdGlvbihiYl9wb3MsIHZ0YWJsZV9vZmZzZXQpIHtcbiAgdmFyIHZ0YWJsZSA9IGJiX3BvcyAtIHRoaXMucmVhZEludDMyKGJiX3Bvcyk7XG4gIHJldHVybiB2dGFibGVfb2Zmc2V0IDwgdGhpcy5yZWFkSW50MTYodnRhYmxlKSA/IHRoaXMucmVhZEludDE2KHZ0YWJsZSArIHZ0YWJsZV9vZmZzZXQpIDogMDtcbn07XG5cbi8qKlxuICogSW5pdGlhbGl6ZSBhbnkgVGFibGUtZGVyaXZlZCB0eXBlIHRvIHBvaW50IHRvIHRoZSB1bmlvbiBhdCB0aGUgZ2l2ZW4gb2Zmc2V0LlxuICpcbiAqIEBwYXJhbSB7ZmxhdGJ1ZmZlcnMuVGFibGV9IHRcbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXRcbiAqIEByZXR1cm5zIHtmbGF0YnVmZmVycy5UYWJsZX1cbiAqL1xuZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlci5wcm90b3R5cGUuX191bmlvbiA9IGZ1bmN0aW9uKHQsIG9mZnNldCkge1xuICB0LmJiX3BvcyA9IG9mZnNldCArIHRoaXMucmVhZEludDMyKG9mZnNldCk7XG4gIHQuYmIgPSB0aGlzO1xuICByZXR1cm4gdDtcbn07XG5cbi8qKlxuICogQ3JlYXRlIGEgSmF2YVNjcmlwdCBzdHJpbmcgZnJvbSBVVEYtOCBkYXRhIHN0b3JlZCBpbnNpZGUgdGhlIEZsYXRCdWZmZXIuXG4gKiBUaGlzIGFsbG9jYXRlcyBhIG5ldyBzdHJpbmcgYW5kIGNvbnZlcnRzIHRvIHdpZGUgY2hhcnMgdXBvbiBlYWNoIGFjY2Vzcy5cbiAqXG4gKiBUbyBhdm9pZCB0aGUgY29udmVyc2lvbiB0byBVVEYtMTYsIHBhc3MgZmxhdGJ1ZmZlcnMuRW5jb2RpbmcuVVRGOF9CWVRFUyBhc1xuICogdGhlIFwib3B0aW9uYWxFbmNvZGluZ1wiIGFyZ3VtZW50LiBUaGlzIGlzIHVzZWZ1bCBmb3IgYXZvaWRpbmcgY29udmVyc2lvbiB0b1xuICogYW5kIGZyb20gVVRGLTE2IHdoZW4gdGhlIGRhdGEgd2lsbCBqdXN0IGJlIHBhY2thZ2VkIGJhY2sgdXAgaW4gYW5vdGhlclxuICogRmxhdEJ1ZmZlciBsYXRlciBvbi5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0XG4gKiBAcGFyYW0ge2ZsYXRidWZmZXJzLkVuY29kaW5nPX0gb3B0X2VuY29kaW5nIERlZmF1bHRzIHRvIFVURjE2X1NUUklOR1xuICogQHJldHVybnMge3N0cmluZ3whVWludDhBcnJheX1cbiAqL1xuZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlci5wcm90b3R5cGUuX19zdHJpbmcgPSBmdW5jdGlvbihvZmZzZXQsIG9wdF9lbmNvZGluZykge1xuICBvZmZzZXQgKz0gdGhpcy5yZWFkSW50MzIob2Zmc2V0KTtcblxuICB2YXIgbGVuZ3RoID0gdGhpcy5yZWFkSW50MzIob2Zmc2V0KTtcbiAgdmFyIHJlc3VsdCA9ICcnO1xuICB2YXIgaSA9IDA7XG5cbiAgb2Zmc2V0ICs9IGZsYXRidWZmZXJzLlNJWkVPRl9JTlQ7XG5cbiAgaWYgKG9wdF9lbmNvZGluZyA9PT0gZmxhdGJ1ZmZlcnMuRW5jb2RpbmcuVVRGOF9CWVRFUykge1xuICAgIHJldHVybiB0aGlzLmJ5dGVzXy5zdWJhcnJheShvZmZzZXQsIG9mZnNldCArIGxlbmd0aCk7XG4gIH1cblxuICB3aGlsZSAoaSA8IGxlbmd0aCkge1xuICAgIHZhciBjb2RlUG9pbnQ7XG5cbiAgICAvLyBEZWNvZGUgVVRGLThcbiAgICB2YXIgYSA9IHRoaXMucmVhZFVpbnQ4KG9mZnNldCArIGkrKyk7XG4gICAgaWYgKGEgPCAweEMwKSB7XG4gICAgICBjb2RlUG9pbnQgPSBhO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgYiA9IHRoaXMucmVhZFVpbnQ4KG9mZnNldCArIGkrKyk7XG4gICAgICBpZiAoYSA8IDB4RTApIHtcbiAgICAgICAgY29kZVBvaW50ID1cbiAgICAgICAgICAoKGEgJiAweDFGKSA8PCA2KSB8XG4gICAgICAgICAgKGIgJiAweDNGKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciBjID0gdGhpcy5yZWFkVWludDgob2Zmc2V0ICsgaSsrKTtcbiAgICAgICAgaWYgKGEgPCAweEYwKSB7XG4gICAgICAgICAgY29kZVBvaW50ID1cbiAgICAgICAgICAgICgoYSAmIDB4MEYpIDw8IDEyKSB8XG4gICAgICAgICAgICAoKGIgJiAweDNGKSA8PCA2KSB8XG4gICAgICAgICAgICAoYyAmIDB4M0YpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhciBkID0gdGhpcy5yZWFkVWludDgob2Zmc2V0ICsgaSsrKTtcbiAgICAgICAgICBjb2RlUG9pbnQgPVxuICAgICAgICAgICAgKChhICYgMHgwNykgPDwgMTgpIHxcbiAgICAgICAgICAgICgoYiAmIDB4M0YpIDw8IDEyKSB8XG4gICAgICAgICAgICAoKGMgJiAweDNGKSA8PCA2KSB8XG4gICAgICAgICAgICAoZCAmIDB4M0YpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gRW5jb2RlIFVURi0xNlxuICAgIGlmIChjb2RlUG9pbnQgPCAweDEwMDAwKSB7XG4gICAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShjb2RlUG9pbnQpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb2RlUG9pbnQgLT0gMHgxMDAwMDtcbiAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKFxuICAgICAgICAoY29kZVBvaW50ID4+IDEwKSArIDB4RDgwMCxcbiAgICAgICAgKGNvZGVQb2ludCAmICgoMSA8PCAxMCkgLSAxKSkgKyAweERDMDApO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG4vKipcbiAqIFJldHJpZXZlIHRoZSByZWxhdGl2ZSBvZmZzZXQgc3RvcmVkIGF0IFwib2Zmc2V0XCJcbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXRcbiAqIEByZXR1cm5zIHtudW1iZXJ9XG4gKi9cbmZsYXRidWZmZXJzLkJ5dGVCdWZmZXIucHJvdG90eXBlLl9faW5kaXJlY3QgPSBmdW5jdGlvbihvZmZzZXQpIHtcbiAgcmV0dXJuIG9mZnNldCArIHRoaXMucmVhZEludDMyKG9mZnNldCk7XG59O1xuXG4vKipcbiAqIEdldCB0aGUgc3RhcnQgb2YgZGF0YSBvZiBhIHZlY3RvciB3aG9zZSBvZmZzZXQgaXMgc3RvcmVkIGF0IFwib2Zmc2V0XCIgaW4gdGhpcyBvYmplY3QuXG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldFxuICogQHJldHVybnMge251bWJlcn1cbiAqL1xuZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlci5wcm90b3R5cGUuX192ZWN0b3IgPSBmdW5jdGlvbihvZmZzZXQpIHtcbiAgcmV0dXJuIG9mZnNldCArIHRoaXMucmVhZEludDMyKG9mZnNldCkgKyBmbGF0YnVmZmVycy5TSVpFT0ZfSU5UOyAvLyBkYXRhIHN0YXJ0cyBhZnRlciB0aGUgbGVuZ3RoXG59O1xuXG4vKipcbiAqIEdldCB0aGUgbGVuZ3RoIG9mIGEgdmVjdG9yIHdob3NlIG9mZnNldCBpcyBzdG9yZWQgYXQgXCJvZmZzZXRcIiBpbiB0aGlzIG9iamVjdC5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0XG4gKiBAcmV0dXJucyB7bnVtYmVyfVxuICovXG5mbGF0YnVmZmVycy5CeXRlQnVmZmVyLnByb3RvdHlwZS5fX3ZlY3Rvcl9sZW4gPSBmdW5jdGlvbihvZmZzZXQpIHtcbiAgcmV0dXJuIHRoaXMucmVhZEludDMyKG9mZnNldCArIHRoaXMucmVhZEludDMyKG9mZnNldCkpO1xufTtcblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gaWRlbnRcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5mbGF0YnVmZmVycy5CeXRlQnVmZmVyLnByb3RvdHlwZS5fX2hhc19pZGVudGlmaWVyID0gZnVuY3Rpb24oaWRlbnQpIHtcbiAgaWYgKGlkZW50Lmxlbmd0aCAhPSBmbGF0YnVmZmVycy5GSUxFX0lERU5USUZJRVJfTEVOR1RIKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdGbGF0QnVmZmVyczogZmlsZSBpZGVudGlmaWVyIG11c3QgYmUgbGVuZ3RoICcgK1xuICAgICAgICAgICAgICAgICAgICBmbGF0YnVmZmVycy5GSUxFX0lERU5USUZJRVJfTEVOR1RIKTtcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGZsYXRidWZmZXJzLkZJTEVfSURFTlRJRklFUl9MRU5HVEg7IGkrKykge1xuICAgIGlmIChpZGVudC5jaGFyQ29kZUF0KGkpICE9IHRoaXMucmVhZEludDgodGhpcy5wb3NpdGlvbl8gKyBmbGF0YnVmZmVycy5TSVpFT0ZfSU5UICsgaSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59O1xuXG4vKipcbiAqIEEgaGVscGVyIGZ1bmN0aW9uIHRvIGF2b2lkIGdlbmVyYXRlZCBjb2RlIGRlcGVuZGluZyBvbiB0aGlzIGZpbGUgZGlyZWN0bHkuXG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IGxvd1xuICogQHBhcmFtIHtudW1iZXJ9IGhpZ2hcbiAqIEByZXR1cm5zIHshZmxhdGJ1ZmZlcnMuTG9uZ31cbiAqL1xuZmxhdGJ1ZmZlcnMuQnl0ZUJ1ZmZlci5wcm90b3R5cGUuY3JlYXRlTG9uZyA9IGZ1bmN0aW9uKGxvdywgaGlnaCkge1xuICByZXR1cm4gZmxhdGJ1ZmZlcnMuTG9uZy5jcmVhdGUobG93LCBoaWdoKTtcbn07XG5cbi8vIEV4cG9ydHMgZm9yIE5vZGUuanMgYW5kIFJlcXVpcmVKU1xuZXhwb3J0IHsgZmxhdGJ1ZmZlcnMgfTtcblxuLy8vIEBlbmRjb25kXG4vLy8gQH1cbiIsIi8vIFRoZSBtb2R1bGUgY2FjaGVcbnZhciBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX18gPSB7fTtcblxuLy8gVGhlIHJlcXVpcmUgZnVuY3Rpb25cbmZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHtcblx0Ly8gQ2hlY2sgaWYgbW9kdWxlIGlzIGluIGNhY2hlXG5cdHZhciBjYWNoZWRNb2R1bGUgPSBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX19bbW9kdWxlSWRdO1xuXHRpZiAoY2FjaGVkTW9kdWxlICE9PSB1bmRlZmluZWQpIHtcblx0XHRyZXR1cm4gY2FjaGVkTW9kdWxlLmV4cG9ydHM7XG5cdH1cblx0Ly8gQ3JlYXRlIGEgbmV3IG1vZHVsZSAoYW5kIHB1dCBpdCBpbnRvIHRoZSBjYWNoZSlcblx0dmFyIG1vZHVsZSA9IF9fd2VicGFja19tb2R1bGVfY2FjaGVfX1ttb2R1bGVJZF0gPSB7XG5cdFx0Ly8gbm8gbW9kdWxlLmlkIG5lZWRlZFxuXHRcdC8vIG5vIG1vZHVsZS5sb2FkZWQgbmVlZGVkXG5cdFx0ZXhwb3J0czoge31cblx0fTtcblxuXHQvLyBFeGVjdXRlIHRoZSBtb2R1bGUgZnVuY3Rpb25cblx0X193ZWJwYWNrX21vZHVsZXNfX1ttb2R1bGVJZF0uY2FsbChtb2R1bGUuZXhwb3J0cywgbW9kdWxlLCBtb2R1bGUuZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyk7XG5cblx0Ly8gUmV0dXJuIHRoZSBleHBvcnRzIG9mIHRoZSBtb2R1bGVcblx0cmV0dXJuIG1vZHVsZS5leHBvcnRzO1xufVxuXG4iLCIvLyBnZXREZWZhdWx0RXhwb3J0IGZ1bmN0aW9uIGZvciBjb21wYXRpYmlsaXR5IHdpdGggbm9uLWhhcm1vbnkgbW9kdWxlc1xuX193ZWJwYWNrX3JlcXVpcmVfXy5uID0gKG1vZHVsZSkgPT4ge1xuXHR2YXIgZ2V0dGVyID0gbW9kdWxlICYmIG1vZHVsZS5fX2VzTW9kdWxlID9cblx0XHQoKSA9PiAobW9kdWxlWydkZWZhdWx0J10pIDpcblx0XHQoKSA9PiAobW9kdWxlKTtcblx0X193ZWJwYWNrX3JlcXVpcmVfXy5kKGdldHRlciwgeyBhOiBnZXR0ZXIgfSk7XG5cdHJldHVybiBnZXR0ZXI7XG59OyIsIi8vIGRlZmluZSBnZXR0ZXIgZnVuY3Rpb25zIGZvciBoYXJtb255IGV4cG9ydHNcbl9fd2VicGFja19yZXF1aXJlX18uZCA9IChleHBvcnRzLCBkZWZpbml0aW9uKSA9PiB7XG5cdGZvcih2YXIga2V5IGluIGRlZmluaXRpb24pIHtcblx0XHRpZihfX3dlYnBhY2tfcmVxdWlyZV9fLm8oZGVmaW5pdGlvbiwga2V5KSAmJiAhX193ZWJwYWNrX3JlcXVpcmVfXy5vKGV4cG9ydHMsIGtleSkpIHtcblx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBrZXksIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBkZWZpbml0aW9uW2tleV0gfSk7XG5cdFx0fVxuXHR9XG59OyIsIl9fd2VicGFja19yZXF1aXJlX18uZyA9IChmdW5jdGlvbigpIHtcblx0aWYgKHR5cGVvZiBnbG9iYWxUaGlzID09PSAnb2JqZWN0JykgcmV0dXJuIGdsb2JhbFRoaXM7XG5cdHRyeSB7XG5cdFx0cmV0dXJuIHRoaXMgfHwgbmV3IEZ1bmN0aW9uKCdyZXR1cm4gdGhpcycpKCk7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHRpZiAodHlwZW9mIHdpbmRvdyA9PT0gJ29iamVjdCcpIHJldHVybiB3aW5kb3c7XG5cdH1cbn0pKCk7IiwiX193ZWJwYWNrX3JlcXVpcmVfXy5vID0gKG9iaiwgcHJvcCkgPT4gKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIHByb3ApKSIsIi8vIGRlZmluZSBfX2VzTW9kdWxlIG9uIGV4cG9ydHNcbl9fd2VicGFja19yZXF1aXJlX18uciA9IChleHBvcnRzKSA9PiB7XG5cdGlmKHR5cGVvZiBTeW1ib2wgIT09ICd1bmRlZmluZWQnICYmIFN5bWJvbC50b1N0cmluZ1RhZykge1xuXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBTeW1ib2wudG9TdHJpbmdUYWcsIHsgdmFsdWU6ICdNb2R1bGUnIH0pO1xuXHR9XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHsgdmFsdWU6IHRydWUgfSk7XG59OyIsIiIsIi8vIHN0YXJ0dXBcbi8vIExvYWQgZW50cnkgbW9kdWxlIGFuZCByZXR1cm4gZXhwb3J0c1xuLy8gVGhpcyBlbnRyeSBtb2R1bGUgaXMgcmVmZXJlbmNlZCBieSBvdGhlciBtb2R1bGVzIHNvIGl0IGNhbid0IGJlIGlubGluZWRcbnZhciBfX3dlYnBhY2tfZXhwb3J0c19fID0gX193ZWJwYWNrX3JlcXVpcmVfXyhcIi4vbGliL2luZGV4LnRzXCIpO1xuIiwiIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9