UNPKG

@randomorg/core

Version:

The official library to access the RANDOM.ORG JSON-RPC API

2 lines 239 kB
function e(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var t={};t.RandomOrgBadHTTPResponseError=class extends Error{constructor(e){super(e)}},t.RandomOrgInsufficientBitsError=class extends Error{#e=-1;constructor(e,t){super(e),this.#e=t}getBitsLeft(){return this.#e}},t.RandomOrgInsufficientRequestsError=class extends Error{constructor(e){super(e)}},t.RandomOrgJSONRPCError=class extends Error{constructor(e){super(e)}},t.RandomOrgKeyNotRunningError=class extends Error{constructor(e){super(e)}},t.RandomOrgRANDOMORGError=class extends Error{#t=-1;constructor(e,t=-1){super(e),this.#t=t}getCode(){return this.#t}},t.RandomOrgSendTimeoutError=class extends Error{constructor(e){super(e)}},t.RandomOrgCacheEmptyError=class extends Error{#s=!1;constructor(e,t=!1){super(e),this.#s=t}wasPaused(){return this.#s}};const{RandomOrgInsufficientBitsError:s,RandomOrgCacheEmptyError:r}=t;var a=class{#r=null;#a=null;#i=0;#n=0;#u=-1;#c=[];#l=10;#s=!1;#o=0;#h=0;#d=!1;#E=null;constructor(e,t,s,r,a,i){this.#r=e,this.#a=t,this.#l=s,this.#i=r,this.#n=a,this.#u=i,this.#g()}#g=async()=>{if(!this.#d&&!this.#s){this.#d=!0;let e=null;for(;null==this.#E;)if(this.#i>0){if(!(this.#c.length<=this.#l-this.#i))break;try{e=await this.#r(this.#a),this.#R(e,!0)}catch(t){if(t instanceof s){let s=t.getBitsLeft();if(s>this.#u){let t=Math.floor(s/this.#u);this.#a.params.n=t*this.#n,e=await this.#r(this.#a),this.#R(e,!0),this.#a.params.n=this.#i*this.#n}else this.#E=t}else this.#E=t}}else{if(!(this.#c.length<this.#l))break;try{e=await this.#r(this.#a),this.#R(e,!1)}catch(e){this.#E=e}}this.#d=!1}};stop(){this.#s=!0}resume(){this.#s=!1,this.#T()}isPaused(){return this.#s}get(){if(null!=this.#E)throw this.#E;if(this.#c&&0==this.#c.length)throw this.#s?new r("The RandomOrgCache stack is empty and the cache is paused. Please call resume() to restart populating the cache.",!0):new r("The RandomOrgCache stack is empty, please wait for it to repopulate itself.");{let e=this.#c.pop();return this.#T(),e}}async getOrWait(){try{return this.get()}catch(e){if(e instanceof r){if(this.#s)throw e;return 0==await this.#g()&&await new Promise((e=>setTimeout(e,50))),this.getOrWait()}}}getCachedValues(){return this.#c.length}getBitsUsed(){return this.#o}getRequestsUsed(){return this.#h}#T=()=>{(this.#i>0&&this.#c.length<=this.#l-this.#i||this.#i<=0&&this.#c.length<this.#l)&&this.#g()};#R=(e,t)=>{if(this.#h++,this.#o+=e.result.bitsUsed,t){let t=e.result.random.data;for(let e=0;e<t.length;e+=this.#n)this.#c.push(t.slice(e,e+this.#n))}else this.#c.push(e.result.random.data)}},i=e(a);const{RandomOrgBadHTTPResponseError:n,RandomOrgInsufficientBitsError:u,RandomOrgInsufficientRequestsError:c,RandomOrgJSONRPCError:l,RandomOrgKeyNotRunningError:o,RandomOrgRANDOMORGError:h,RandomOrgSendTimeoutError:d}=t,E=a;var g=class e{static#m="generateIntegers";static#p="generateIntegerSequences";static#D="generateDecimalFractions";static#_="generateGaussians";static#O="generateStrings";static#S="generateUUIDs";static#q="generateBlobs";static#f="getUsage";static#I="generateSignedIntegers";static#y="generateSignedIntegerSequences";static#b="generateSignedDecimalFractions";static#A="generateSignedGaussians";static#M="generateSignedStrings";static#U="generateSignedUUIDs";static#x="generateSignedBlobs";static#N="getResult";static#L="createTickets";static#H="listTickets";static#k="revealTickets";static#w="getTicket";static#C="verifySignature";static BLOB_FORMAT_BASE64="base64";static BLOB_FORMAT_HEX="hex";static DEFAULT_REPLACEMENT=!0;static DEFAULT_BASE=10;static DEFAULT_USER_DATA=null;static DEFAULT_TICKET_ID=null;static DEFAULT_PREGENERATED_RANDOMIZATION=null;static DEFAULT_LICENSE_DATA=null;static UUID_SIZE=122;static DEFAULT_BLOCKING_TIMEOUT=864e5;static DEFAULT_HTTP_TIMEOUT=12e4;static MAX_URL_LENGTH=2046;static#G=1e3;static#B=36e5;#F=-1;#K=-1;#P=-1;#v="";#z="";#V=e.DEFAULT_BLOCKING_TIMEOUT;#j=e.DEFAULT_HTTP_TIMEOUT;#J=0;#Y=0;static#Z={};static#W=[100,101,200,201,202,203,204,300,301,302,303,304,305,306,307,400,401,402,403,404,405,420,421,422,423,424,425,426,500,32e3];constructor(t,s={}){if(e.#Z&&e.#Z[t])return e.#Z[t];this.#z=t,this.#V=s.blockingTimeout||864e5,this.#j=s.httpTimeout||12e4,e.#Z[t]=this}async generateIntegers(e,t,s,r={}){let a=this.#X(e,t,s,r);return this.#Q(this.#$(a))}async generateIntegerSequences(e,t,s,r,a={}){let i=this.#ee(e,t,s,r,a);return this.#Q(this.#$(i))}async generateDecimalFractions(e,t,s={}){let r=this.#te(e,t,s);return this.#Q(this.#$(r))}async generateGaussians(e,t,s,r,a={}){let i=this.#se(e,t,s,r,a);return this.#Q(this.#$(i))}async generateStrings(e,t,s,r={}){let a=this.#re(e,t,s,r);return this.#Q(this.#$(a))}async generateUUIDs(e,t={}){let s=this.#ae(e,t);return this.#Q(this.#$(s))}async generateBlobs(e,t,s={}){let r=this.#ie(e,t,s);return this.#Q(this.#$(r))}async generateSignedIntegers(e,t,s,r={}){let a=this.#X(e,t,s,r,!0);return this.#ne(this.#$(a))}async generateSignedIntegerSequences(e,t,s,r,a={}){let i=this.#ee(e,t,s,r,a,!0);return this.#ne(this.#$(i))}async generateSignedDecimalFractions(e,t,s={}){let r=this.#te(e,t,s,!0);return this.#ne(this.#$(r))}async generateSignedGaussians(e,t,s,r,a={}){let i=this.#se(e,t,s,r,a,!0);return this.#ne(this.#$(i))}async generateSignedStrings(e,t,s,r={}){let a=this.#re(e,t,s,r,!0);return this.#ne(this.#$(a))}async generateSignedUUIDs(e,t={}){let s=this.#ae(e,t,!0);return this.#ne(this.#$(s))}async generateSignedBlobs(e,t,s={}){let r=this.#ie(e,t,s,!0);return this.#ne(this.#$(r))}async verifySignature(t,s){let r={random:t,signature:s},a=this.#ue(e.#C,r);return this.#ce(this.#$(a))}async getBitsLeft(){let t=Date.now()>this.#Y+e.#B;return(this.#F<0||t)&&await this.#le(),this.#F}async getRequestsLeft(){let t=Date.now()>this.#Y+e.#B;return(this.#K<0||t)&&await this.#le(),this.#K}async getResult(t){let s={serialNumber:t},r=this.#oe(e.#N,s);return this.#ne(this.#$(r))}async createTickets(t,s){let r={n:t,showResult:s},a=this.#oe(e.#L,r);return this.#he(this.#$(a))}async revealTickets(t){let s={ticketId:t},r=this.#oe(e.#k,s);return this.#he(this.#$(r))}async listTickets(t){let s={ticketType:t},r=this.#oe(e.#H,s);return this.#he(this.#$(r))}async getTicket(t){let s={ticketId:t},r=this.#ue(e.#w,s);return this.#he(this.#$(r))}createUrl(t,s){let r="https://api.random.org/signatures/form?format=json";if(r+="&random="+this.#de(JSON.stringify(t)),r+="&signature="+this.#de(s),r.length>e.MAX_URL_LENGTH)throw new h("Error: URL exceeds maximum length("+e.MAX_URL_LENGTH+" characters).");return r}createHtml(e,t){let s="<form action='https://api.random.org/signatures/form' method='post'>\n";return s+=" "+this.#Ee("hidden","format","json")+"\n",s+=" "+this.#Ee("hidden","random",JSON.stringify(e))+"\n",s+=" "+this.#Ee("hidden","signature",t)+"\n",s+=" <input type='submit' value='Validate' />\n</form>",s}createIntegerCache(e,t,s,r={}){let a=r.cacheSize||20;a<2&&(a=2);let i=this.#X(e,t,s,r),n=Math.ceil(Math.log(s-t+1)/Math.log(2)*e),u=0;return"replacement"in r&&!0!==r.replacement||(u=a/2,i.params.n=e*u),new E(this.#$.bind(this),i,a,u,e,n)}createIntegerSequenceCache(e,t,s,r,a={}){let i=a.cacheSize||20;i<2&&(i=2);let n,u=Math.ceil(Math.log(this.#ge(r)-this.#Re(s),1)/Math.log(2)*e*this.#ge(t)),c=0;n=a.replacement&&Array.isArray(a.replacement)?a.replacement.every((e=>!0===e)):a.replacement||!0,n&&(c=i/2,Array.isArray(t)&&(t=this.#Te(t,c)),Array.isArray(s)&&(s=this.#Te(s,c)),Array.isArray(r)&&(r=this.#Te(r,c)),a.replacement&&Array.isArray(a.replacement)&&(a.replacement=this.#Te(a.replacement,c)),a.base&&Array.isArray(a.base)&&(a.base=this.#Te(a.base,c)));let l=this.#ee(e,t,s,r,a);return n&&(l.params.n=c*e),new E(this.#$.bind(this),l,i,c,e,u)}createDecimalFractionCache(e,t,s={}){let r=s.cacheSize||20;r<2&&(r=2);let a=this.#te(e,t,s),i=0;"replacement"in s&&!0!==s.replacement||(i=r/2,a.params.n=e*i);let n=Math.ceil(Math.log(10)/Math.log(2)*t*e);return new E(this.#$.bind(this),a,r,i,e,n)}createGaussianCache(e,t,s,r,a={}){let i=a.cacheSize||20;i<2&&(i=2);let n=Math.ceil(Math.log(Math.pow(10,r))/Math.log(2)*e),u=i/2,c=this.#se(e*u,t,s,r);return new E(this.#$.bind(this),c,i,u,e,n)}createStringCache(e,t,s,r={}){let a=r.cacheSize||20;a<2&&(a=2);let i=this.#re(e,t,s,r),n=Math.ceil(Math.log(s.length)/Math.log(2)*t*e),u=0;return"replacement"in r&&!0!==r.replacement||(u=a/2,i.params.n=e*u),new E(this.#$.bind(this),i,a,u,e,n)}createUUIDCache(t,s={}){let r=s.cacheSize||10;r<2&&(r=2);let a=t*e.UUID_SIZE,i=r/2,n=this.#ae(t*i);return new E(this.#$.bind(this),n,r,i,t,a)}createBlobCache(e,t,s={}){let r=s.cacheSize||10;r<2&&(r=2);let a=e*t,i=r/2,n=this.#ie(e*i,t,s);return new E(this.#$.bind(this),n,r,i,e,a)}#$=async function(t){if(-1!=this.#P){if(Date.now()<this.#P)throw new c(this.#v);this.#P=-1,this.#v=null}let s=this.#J-(Date.now()-this.#Y);if(-1!=this.#V&&s>this.#V)throw new d("The server advisory delay of "+s+"millis is greater than the defined maximum allowed blocking time of "+this.#V+"millis.");s>0&&await new Promise((e=>setTimeout(e,s)));let r=this.#j;return new Promise((function(e){let s=new XMLHttpRequest;s.open("POST","https://api.random.org/json-rpc/4/invoke"),s.setRequestHeader("Content-Type","application/json"),s.ontimeout=function(){throw new d("The maximum allowed blocking time of "+r+"millis has been exceeded while waiting for the server to respond.")},s.onload=function(){if(!(this.status>=200&&this.status<300))throw new n("Error: "+s.status);e(s.responseText)},s.onerror=function(e){throw e instanceof Error?e:(console.info("** An error occurred during the transaction."),new Error(s.responseText))},s.timeout=r,s.send(JSON.stringify(t))})).then((s=>{if((s=JSON.parse(s)).error){let t=s.error.code,r=s.error.message,a=s.error.data;if(401==t)throw new o("Error "+t+": "+r);if(402==t){let e=(new Date).setUTCHours(0,0,0,0);throw this.#P=+e,this.#v="Error "+t+": "+r,this.#K=a[1],new c(this.#v)}throw 403==t?(this.#F=a[1],new u("Error"+t+": "+r,this.#F)):e.#W.includes(t)?new h("Error "+t+": "+r,t):new l("Error "+t+": "+r)}return[e.#C,e.#N,e.#L,e.#H,e.#w].includes(t.method)?this.#J=e.#G:(this.#K=s.result.requestsLeft,this.#F=s.result.bitsLeft,s.result.advisoryDelay?this.#J=s.result.advisoryDelay:this.#J=e.#G),this.#Y=Date.now(),s}))};#le=async()=>{let t=this.#oe(e.#f,{});return this.#he(this.#$(t))};#ue=(e,t)=>({jsonrpc:"2.0",method:e,params:t,id:this.#me()});#oe=(e,t)=>(t.apiKey=this.#z,this.#ue(e,t));#Q=async e=>e.then((e=>e.result.random.data));#ne=async e=>e.then((e=>({data:e.result.random.data,random:e.result.random,signature:e.result.signature})));#ce=async e=>e.then((e=>e.result.authenticity));#he=async e=>e.then((e=>e.result));#X=(t,s,r,{replacement:a=!0,base:i=10,pregeneratedRandomization:n=null,licenseData:u=null,userData:c=null,ticketId:l=null}={},o=!1)=>{let h={n:t,min:s,max:r,replacement:a,base:i};h=this.#pe(h,n,u,c,l,o);let d=o?e.#I:e.#m;return this.#oe(d,h)};#ee=(t,s,r,a,{replacement:i=!0,base:n=10,pregeneratedRandomization:u=null,licenseData:c=null,userData:l=null,ticketId:o=null}={},h=!1)=>{let d={n:t,length:s,min:r,max:a,replacement:i,base:n};d=this.#pe(d,u,c,l,o,h);let E=h?e.#y:e.#p;return this.#oe(E,d)};#te=(t,s,{replacement:r=!0,pregeneratedRandomization:a=null,licenseData:i=null,userData:n=null,ticketId:u=null}={},c=!1)=>{let l={n:t,decimalPlaces:s,replacement:r};l=this.#pe(l,a,i,n,u,c);let o=c?e.#b:e.#D;return this.#oe(o,l)};#se=(t,s,r,a,{pregeneratedRandomization:i=null,licenseData:n=null,userData:u=null,ticketId:c=null}={},l=!1)=>{let o={n:t,mean:s,standardDeviation:r,significantDigits:a};o=this.#pe(o,i,n,u,c,l);let h=l?e.#A:e.#_;return this.#oe(h,o)};#re=(t,s,r,{replacement:a=!0,pregeneratedRandomization:i=null,licenseData:n=null,userData:u=null,ticketId:c=null}={},l=!1)=>{let o={n:t,length:s,characters:r,replacement:a};o=this.#pe(o,i,n,u,c,l);let h=l?e.#M:e.#O;return this.#oe(h,o)};#ae=(t,{pregeneratedRandomization:s=null,licenseData:r=null,userData:a=null,ticketId:i=null}={},n=!1)=>{let u={n:t};u=this.#pe(u,s,r,a,i,n);let c=n?e.#U:e.#S;return this.#oe(c,u)};#ie=(t,s,{format:r=this.BASE64,pregeneratedRandomization:a=null,licenseData:i=null,userData:n=null,ticketId:u=null},c=!1)=>{let l={n:t,size:s,format:r};l=this.#pe(l,a,i,n,u,c);let o=c?e.#x:e.#q;return this.#oe(o,l)};#pe=(e,t,s,r,a,i=!1)=>(e.pregeneratedRandomization=t,i&&(e.licenseData=s,e.userData=r,e.ticketId=a),e);#Te=(e,t)=>Array.from({length:t},(()=>e)).flat();#ge=e=>Array.isArray(e)?e.reduce((function(e,t){return Math.max(e,t)})):e;#Re=e=>Array.isArray(e)?e.reduce((function(e,t){return Math.min(e,t)})):e;#de=e=>{if(!/^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/.test(e))try{window&&(e=btoa(e))}catch(t){t instanceof ReferenceError&&(e=Buffer.from(e).toString("base64"))}return e=(e=(e=e.replace(/=/g,"%3D")).replace(/\+/g,"%2B")).replace(/\//g,"%2F")};#Ee=(e,t,s)=>"<input type='"+e+"' name='"+t+"' value='"+s+"' />";#me=()=>"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,(function(e){var t=16*Math.random()|0;return("x"==e?t:3&t|8).toString(16)}))},R=e(g);let T=t.RandomOrgRANDOMORGError,m=t.RandomOrgBadHTTPResponseError,p=t.RandomOrgInsufficientBitsError,D=t.RandomOrgInsufficientRequestsError,_=t.RandomOrgJSONRPCError,O=t.RandomOrgKeyNotRunningError,S=t.RandomOrgSendTimeoutError,q=t.RandomOrgCacheEmptyError;export{m as RandomOrgBadHTTPResponseError,i as RandomOrgCache,q as RandomOrgCacheEmptyError,R as RandomOrgClient,p as RandomOrgInsufficientBitsError,D as RandomOrgInsufficientRequestsError,_ as RandomOrgJSONRPCError,O as RandomOrgKeyNotRunningError,T as RandomOrgRANDOMORGError,S as RandomOrgSendTimeoutError,R as default}; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmRvY29yZS5lcy5taW4uanMiLCJzb3VyY2VzIjpbIi4uL1JhbmRvbU9yZ0Vycm9ycy5qcyIsIi4uL1JhbmRvbU9yZ0NhY2hlLmpzIiwiLi4vUmFuZG9tT3JnQ2xpZW50LmpzIiwiLi4vZXNtL2luZGV4LmpzIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcclxuXHJcbi8qKlxyXG4gKiBFcnJvciB0aHJvd24gYnkgdGhlIFJhbmRvbU9yZ0NsaWVudCBjbGFzcyB3aGVuIHRoZSBjb25uZWN0aW9uIGRvZXNuJ3QgcmV0dXJuXHJcbiAqIGEgSFRUUCAyMDAgT0sgcmVzcG9uc2UuXHJcbiAqL1xyXG5leHBvcnRzLlJhbmRvbU9yZ0JhZEhUVFBSZXNwb25zZUVycm9yID0gY2xhc3MgUmFuZG9tT3JnQmFkSFRUUFJlc3BvbnNlRXJyb3IgZXh0ZW5kcyBFcnJvclxyXG57XHJcbiAgICAvKipcclxuICAgICAqIENvbnN0cnVjdHMgYSBuZXcgZXhjZXB0aW9uIHdpdGggdGhlIHNwZWNpZmllZCBkZXRhaWwgbWVzc2FnZS5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIFRoZSBkZXRhaWwgbWVzc2FnZS5cclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IobWVzc2FnZSkge1xyXG4gICAgICAgIHN1cGVyKG1lc3NhZ2UpO1xyXG4gICAgfVxyXG59XHJcblxyXG4vKipcclxuICogRXJyb3IgdGhyb3duIGJ5IHRoZSBSYW5kb21PcmdDbGllbnQgY2xhc3Mgd2hlbiBpdHMgQVBJIGtleSdzIHJlcXVlc3QgaGFzXHJcbiAqIGV4Y2VlZGVkIGl0cyByZW1haW5pbmcgc2VydmVyIGJpdHMgYWxsb3dhbmNlLlxyXG4gKiBcclxuICogSWYgdGhlIGNsaWVudCBpcyBjdXJyZW50bHkgaXNzdWluZyBsYXJnZSByZXF1ZXN0cyBpdCBtYXkgYmUgcG9zc2libGUgc3VjY2VlZFxyXG4gKiB3aXRoIHNtYWxsZXIgcmVxdWVzdHMuIFVzZSB0aGUgZ2V0Qml0c0xlZnQoKSBjYWxsIGluIHRoaXMgY2xhc3MgdG8gaGVscFxyXG4gKiBkZXRlcm1pbmUgaWYgYW4gYWx0ZXJuYXRpdmUgcmVxdWVzdCBzaXplIGlzIGFwcHJvcHJpYXRlLlxyXG4gKi9cclxuIGV4cG9ydHMuUmFuZG9tT3JnSW5zdWZmaWNpZW50Qml0c0Vycm9yID0gY2xhc3MgUmFuZG9tT3JnSW5zdWZmaWNpZW50Qml0c0Vycm9yIGV4dGVuZHMgRXJyb3Jcclxue1xyXG4gICAgLy8gU3RvcmVzIHRoZSBudW1iZXIgb2YgYml0cyByZW1haW5pbmdcclxuICAgICNiaXRzID0gLTE7XHJcbiAgICBcclxuICAgIC8qKlxyXG4gICAgICogQ29uc3RydWN0cyBhIG5ldyBleGNlcHRpb24gd2l0aCB0aGUgc3BlY2lmaWVkIGRldGFpbCBtZXNzYWdlLlxyXG4gICAgICogQGNvbnN0cnVjdG9yXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSBUaGUgZGV0YWlsIG1lc3NhZ2UuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gYml0cyBCaXRzIHJlbWFpbmluZyBqdXN0IGJlZm9yZSB0aGUgZXJyb3Igd2FzIHRocm93bi5cclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IobWVzc2FnZSwgYml0cykge1xyXG4gICAgICAgIHN1cGVyKG1lc3NhZ2UpO1xyXG4gICAgICAgIHRoaXMuI2JpdHMgPSBiaXRzO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgbnVtYmVyIG9mIGJpdHMgcmVtYWluaW5nLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gVGhlIG51bWJlciBvZiBiaXRzIGxlZnQuXHJcbiAgICAgKi9cclxuICAgIGdldEJpdHNMZWZ0KCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLiNiaXRzO1xyXG4gICAgfVxyXG59XHJcblxyXG4vKipcclxuICogRXJyb3IgdGhyb3duIGJ5IHRoZSBSYW5kb21PcmdDbGllbnQgY2xhc3Mgd2hlbiBpdHMgQVBJIGtleSdzIHNlcnZlciByZXF1ZXN0c1xyXG4gKiBhbGxvd2FuY2UgaGFzIGJlZW4gZXhjZWVkZWQuXHJcbiAqIFxyXG4gKiBUaGlzIGluZGljYXRlcyB0aGF0IGEgYmFjay1vZmYgdW50aWwgbWlkbmlnaHQgVVRDIGlzIGluIGVmZmVjdCwgYmVmb3JlIHdoaWNoXHJcbiAqIG5vIHJlcXVlc3RzIHdpbGwgYmUgc2VudCBieSB0aGUgY2xpZW50IGFzIG5vIG1lYW5pbmdmdWwgc2VydmVyIHJlc3BvbnNlcyB3aWxsXHJcbiAqIGJlIHJldHVybmVkLlxyXG4gKi9cclxuZXhwb3J0cy5SYW5kb21PcmdJbnN1ZmZpY2llbnRSZXF1ZXN0c0Vycm9yID0gY2xhc3MgUmFuZG9tT3JnSW5zdWZmaWNpZW50UmVxdWVzdHNFcnJvciBleHRlbmRzIEVycm9yXHJcbntcclxuICAgIC8qKlxyXG4gICAgICogQ29uc3RydWN0cyBhIG5ldyBleGNlcHRpb24gd2l0aCB0aGUgc3BlY2lmaWVkIGRldGFpbCBtZXNzYWdlLlxyXG4gICAgICogQGNvbnN0cnVjdG9yXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSBUaGUgZGV0YWlsIG1lc3NhZ2UuXHJcbiAgICAgKi9cclxuICAgIGNvbnN0cnVjdG9yKG1lc3NhZ2UpIHtcclxuICAgICAgICBzdXBlcihtZXNzYWdlKTtcclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIEVycm9yIHRocm93biBieSB0aGUgUmFuZG9tT3JnQ2xpZW50IGNsYXNzIHdoZW4gdGhlIHNlcnZlciByZXR1cm5zIGEgSlNPTi1SUENcclxuICogRXJyb3IuIFNlZSBodHRwczovL2FwaS5yYW5kb20ub3JnL2pzb24tcnBjLzQvZXJyb3ItY29kZXNcclxuICovXHJcbmV4cG9ydHMuUmFuZG9tT3JnSlNPTlJQQ0Vycm9yID0gY2xhc3MgUmFuZG9tT3JnSlNPTlJQQ0Vycm9yIGV4dGVuZHMgRXJyb3Jcclxue1xyXG4gICAgLyoqXHJcbiAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGV4Y2VwdGlvbiB3aXRoIHRoZSBzcGVjaWZpZWQgZGV0YWlsIG1lc3NhZ2UuXHJcbiAgICAgKiBAY29uc3RydWN0b3JcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIFRoZSBkZXRhaWwgbWVzc2FnZS5cclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IobWVzc2FnZSkge1xyXG4gICAgICAgIHN1cGVyKG1lc3NhZ2UpO1xyXG4gICAgfVxyXG59XHJcblxyXG4vKipcclxuICogRXJyb3IgdGhyb3duIGJ5IHRoZSBSYW5kb21PcmdDbGllbnQgY2xhc3Mgd2hlbiBpdHMgQVBJIGtleSBoYXMgYmVlbiBzdG9wcGVkLlxyXG4gKiBSZXF1ZXN0cyB3aWxsIG5vdCBjb21wbGV0ZSB3aGlsZSBBUEkga2V5IGlzIGluIHRoZSBzdG9wcGVkIHN0YXRlLlxyXG4gKi9cclxuZXhwb3J0cy5SYW5kb21PcmdLZXlOb3RSdW5uaW5nRXJyb3IgPSBjbGFzcyBSYW5kb21PcmdLZXlOb3RSdW5uaW5nRXJyb3IgZXh0ZW5kcyBFcnJvclxyXG57XHJcbiAgICAvKipcclxuICAgICAqIEVycm9yIHRocm93biBieSB0aGUgUmFuZG9tT3JnQ2xpZW50IGNsYXNzIHdoZW4gaXRzIEFQSSBrZXkgaGFzIGJlZW4gc3RvcHBlZC5cclxuICAgICAqIFJlcXVlc3RzIHdpbGwgbm90IGNvbXBsZXRlIHdoaWxlIEFQSSBrZXkgaXMgaW4gdGhlIHN0b3BwZWQgc3RhdGUuXHJcbiAgICAgKiBAY29uc3RydWN0b3JcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIFRoZSBkZXRhaWwgbWVzc2FnZS5cclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IobWVzc2FnZSkge1xyXG4gICAgICAgIHN1cGVyKG1lc3NhZ2UpO1xyXG4gICAgfVxyXG59XHJcblxyXG4vKipcclxuICogRXJyb3IgdGhyb3duIGJ5IHRoZSBSYW5kb21PcmdDbGllbnQgY2xhc3Mgd2hlbiB0aGUgc2VydmVyIHJldHVybnMgYVxyXG4gKiBSQU5ET00uT1JHIEVycm9yLiBTZWUgaHR0cHM6Ly9hcGkucmFuZG9tLm9yZy9qc29uLXJwYy80L2Vycm9yLWNvZGVzXHJcbiAqL1xyXG5leHBvcnRzLlJhbmRvbU9yZ1JBTkRPTU9SR0Vycm9yID0gY2xhc3MgUmFuZG9tT3JnUkFORE9NT1JHRXJyb3IgZXh0ZW5kcyBFcnJvclxyXG57XHJcbiAgICAvLyBTdG9yZXMgdGhlIGNvZGUgb2YgdGhlIFJBTkRPTS5PUkcgZXJyb3JcclxuICAgICNjb2RlID0gLTE7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBFcnJvciB0aHJvd24gYnkgdGhlIFJhbmRvbU9yZ0NsaWVudCBjbGFzcyB3aGVuIHRoZSBzZXJ2ZXIgcmV0dXJucyBhXHJcbiAgICAgKiBSQU5ET00uT1JHIEVycm9yLiBTZWUgaHR0cHM6Ly9hcGkucmFuZG9tLm9yZy9qc29uLXJwYy80L2Vycm9yLWNvZGVzXHJcbiAgICAgKiBAY29uc3RydWN0b3JcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIFRoZSBkZXRhaWwgbWVzc2FnZS5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gW2NvZGU9LTFdIFRoZSBlcnJvciBjb2RlLlxyXG4gICAgICovXHJcbiAgICBjb25zdHJ1Y3RvcihtZXNzYWdlLCBjb2RlID0gLTEpIHtcclxuICAgICAgICBzdXBlcihtZXNzYWdlKTsgICAgXHJcbiAgICAgICAgdGhpcy4jY29kZSA9IGNvZGU7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSBSQU5ET00uT1JHIGVycm9yIGNvZGUsIHNlZVxyXG4gICAgICogaHR0cHM6Ly9hcGkucmFuZG9tLm9yZy9qc29uLXJwYy80L2Vycm9yLWNvZGVzXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBUaGUgZXJyb3IgY29kZS5cclxuICAgICAqL1xyXG4gICAgZ2V0Q29kZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy4jY29kZTtcclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIEVycm9yIHRocm93biBieSB0aGUgUmFuZG9tT3JnQ2xpZW50IGNsYXNzIHdoZW4gaXRzIHNldCBibG9ja2luZyB0aW1lb3V0IGlzXHJcbiAqIGV4Y2VlZGVkIGJlZm9yZSB0aGUgcmVxdWVzdCBjYW4gYmUgc2VudC5cclxuICovXHJcbmV4cG9ydHMuUmFuZG9tT3JnU2VuZFRpbWVvdXRFcnJvciA9IGNsYXNzIFJhbmRvbU9yZ1NlbmRUaW1lb3V0RXJyb3IgZXh0ZW5kcyBFcnJvclxyXG57XHJcbiAgICAvKipcclxuICAgICAqIEVycm9yIHRocm93biBieSB0aGUgUmFuZG9tT3JnQ2xpZW50IGNsYXNzIHdoZW4gaXRzIHNldCBibG9ja2luZyB0aW1lb3V0IGlzXHJcbiAgICAgKiBleGNlZWRlZCBiZWZvcmUgdGhlIHJlcXVlc3QgY2FuIGJlIHNlbnQuXHJcbiAgICAgKiBAY29uc3RydWN0b3JcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIFRoZSBkZXRhaWwgbWVzc2FnZS5cclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IobWVzc2FnZSkge1xyXG4gICAgICAgIHN1cGVyKG1lc3NhZ2UpO1xyXG4gICAgfVxyXG59XHJcblxyXG4vKipcclxuICogRXJyb3IgdGhyb3duIHdoZW4gZGF0YSByZXRyaWV2YWwgZnJvbSBhbiBlbXRweSBSYW5kb21PcmdDYWNoZSBpcyBhdHRlbXB0ZWQuXHJcbiAqL1xyXG5leHBvcnRzLlJhbmRvbU9yZ0NhY2hlRW1wdHlFcnJvciA9IGNsYXNzIFJhbmRvbU9yZ0NhY2hlRW1wdHlFcnJvciBleHRlbmRzIEVycm9yXHJcbntcclxuICAgICNwYXVzZWQgPSBmYWxzZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEVycm9yIHRocm93biB3aGVuIGRhdGEgcmV0cmlldmFsIGZyb20gYW4gZW10cHkgUmFuZG9tT3JnQ2FjaGUgaXMgYXR0ZW1wdGVkLlxyXG4gICAgICogQGNvbnN0cnVjdG9yXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSBUaGUgZGV0YWlsIG1lc3NhZ2UuXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IHBhdXNlZCBSZWZsZWN0cyB3aGV0aGVyIHRoZSBSYW5kb21PcmdDYWNoZSBpbnN0YW5jZSB3YXNcclxuICAgICAqICAgICBwYXVzZWQgd2hlbiB0aGlzIGVycm9yIHdhcyB0aHJvd24uXHJcbiAgICAgKi9cclxuICAgIGNvbnN0cnVjdG9yKG1lc3NhZ2UsIHBhdXNlZCA9IGZhbHNlKSB7XHJcbiAgICAgICAgc3VwZXIobWVzc2FnZSk7XHJcbiAgICAgICAgdGhpcy4jcGF1c2VkID0gcGF1c2VkO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBjYWNoZSB3YXMgcGF1c2VkIGF0IHRoZSB0aW1lIHdoZW4gdGhlXHJcbiAgICAgKiBlcnJvciB3YXMgdGhyb3duLlxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgcGF1c2VkLCBmYWxzZSBvdGhlcndpc2UuXHJcbiAgICAgKi9cclxuICAgIHdhc1BhdXNlZCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy4jcGF1c2VkO1xyXG4gICAgfVxyXG59IiwiJ3VzZSBzdHJpY3QnO1xyXG5jb25zdCB7XHJcbiAgICBSYW5kb21PcmdJbnN1ZmZpY2llbnRCaXRzRXJyb3IsXHJcbiAgICBSYW5kb21PcmdDYWNoZUVtcHR5RXJyb3JcclxufSA9IHJlcXVpcmUoJy4vUmFuZG9tT3JnRXJyb3JzLmpzJyk7XHJcbi8qKlxyXG4gKiBQcmVjYWNoZSBjbGFzcyBmb3IgZnJlcXVlbnRseSB1c2VkIHJlcXVlc3RzLlxyXG4gKi9cclxubW9kdWxlLmV4cG9ydHMgPSBjbGFzcyBSYW5kb21PcmdDYWNoZSB7XHJcbiAgICAvLyBmdW5jdGlvbiB1c2VkIHRvIHNlbmQgYSByZXF1ZXN0XHJcbiAgICAjcmVxdWVzdEZ1bmN0aW9uID0gbnVsbDtcclxuXHJcbiAgICAvLyByZXF1ZXN0IHRvIGJlIHNlbnRcclxuICAgICNyZXF1ZXN0ID0gbnVsbDtcclxuXHJcbiAgICAvLyBuIGZvciBidWxrIHJlcXVlc3RzXHJcbiAgICAjYnVsa1JlcXVlc3ROdW1iZXIgPSAwO1xyXG4gICAgLy8gbiBmb3IgYSBzaW5nbGUgcmVxdWVzdFxyXG4gICAgI3JlcXVlc3ROdW1iZXIgPSAwO1xyXG4gICAgLy8gc2l6ZSBvZiBhIHNpbmdsZSByZXF1ZXN0IGluIGJpdHNcclxuICAgICNyZXF1ZXN0U2l6ZSA9IC0xO1xyXG5cclxuICAgIC8vIHN0b3JlcyBjYWNoZWQgYXJyYXlzIG9mIHZhbHVlc1xyXG4gICAgI3N0YWNrID0gW107XHJcbiAgICAvLyBudW1iZXIgb2YgYXJyYXlzIHRvIHRyeSB0byBtYWludGFpbiBpbiAjc3RhY2tcclxuICAgICNjYWNoZVNpemUgPSAxMDtcclxuXHJcbiAgICAvLyBzdGF0dXMgb2YgdGhlIGNhY2hlXHJcbiAgICAjcGF1c2VkID0gZmFsc2U7XHJcbiAgICAvLyBiaXRzIHVzZWQgYnkgdGhpcyBjYWNoZVxyXG4gICAgI2JpdHNVc2VkID0gMDtcclxuICAgIC8vIHJlcXVlc3RzIHVzZWQgYnkgdGhpcyBjYWNoZVxyXG4gICAgI3JlcXVlc3RzVXNlZCA9IDA7XHJcbiAgICAvLyBlbnN1cmVzICNwb3B1bGF0ZSgpIGRvZXMgbm90IGlzc3VlIHBhcmFsbGVsIHJlcXVlc3RzXHJcbiAgICAjY3VycmVudGx5UG9wdWxhdGluZyA9IGZhbHNlO1xyXG5cclxuICAgIC8vIGFuIGVycm9yIHdoaWNoIHdpbGwgYmUgdGhyb3duIG9uIHRoZSBuZXh0IGNhbGwgdG8gZ2V0KCkgb3IgZ2V0T3JXYWl0KClcclxuICAgICNlcnJvciA9IG51bGw7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJbml0aWFsaXplIGNsYXNzIGFuZCBzdGFydCBzdGFjayBwb3B1bGF0aW9uXHJcbiAgICAgKiBcclxuICAgICAqICoqIFdBUk5JTkcqKiBTaG91bGQgb25seSBiZSBjYWxsZWQgYnkgUmFuZG9tT3JnQ2xpZW50J3MgY3JlYXRlQ2FjaGUoKVxyXG4gICAgICogbWV0aG9kcy5cclxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb24oT2JqZWN0KSA6IE9iamVjdH0gcmVxdWVzdEZ1bmN0aW9uIEZ1bmN0aW9uIHVzZWQgdG8gc2VuZFxyXG4gICAgICogICAgIHN1cHBsaWVkIHJlcXVlc3QgdG8gc2VydmVyLlxyXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHJlcXVlc3QgUmVxdWVzdCB0byBzZW5kIHRvIHNlcnZlciB2aWEgcmVxdWVzdEZ1bmN0aW9uLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGNhY2hlU2l6ZSBOdW1iZXIgb2YgcmVxdWVzdCByZXNwb25zZXMgdG8gdHJ5IG1haW50YWluLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGJ1bGtSZXF1ZXN0TnVtYmVyIElmIHJlcXVlc3QgaXMgc2V0IHRvIGJlIGlzc3VlZCBpbiBidWxrLFxyXG4gICAgICogICAgIG51bWJlciBvZiByZXN1bHQgc2V0cyBpbiBhIGJ1bGsgcmVxdWVzdCwgZWxzZSAwLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHJlcXVlc3ROdW1iZXIgSWYgcmVxdWVzdCBpcyBzZXQgdG8gYmUgaXNzdWVkIGluIGJ1bGssXHJcbiAgICAgKiAgICAgbnVtYmVyIG9mIHJlc3VsdHMgaW4gYSBzaW5nbGUgcmVxdWVzdCwgZWxzZSAwLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHNpbmdsZVJlcXVlc3RTaXplIFNpemUgb2YgYSBzaW5nbGUgcmVxdWVzdCBpbiBiaXRzIGZvclxyXG4gICAgICogICAgIGFkanVzdGluZyBidWxrIHJlcXVlc3RzIGlmIGJpdHMgYXJlIGluIHNob3J0IHN1cHBseSBvbiB0aGUgc2VydmVyLlxyXG4gICAgICovXHJcbiAgICBjb25zdHJ1Y3RvcihyZXF1ZXN0RnVuY3Rpb24sIHJlcXVlc3QsIGNhY2hlU2l6ZSwgYnVsa1JlcXVlc3ROdW1iZXIsIHJlcXVlc3ROdW1iZXIsIHNpbmdsZVJlcXVlc3RTaXplKSB7XHJcbiAgICAgICAgdGhpcy4jcmVxdWVzdEZ1bmN0aW9uID0gcmVxdWVzdEZ1bmN0aW9uO1xyXG5cclxuICAgICAgICB0aGlzLiNyZXF1ZXN0ID0gcmVxdWVzdDtcclxuICAgICAgICBcclxuICAgICAgICB0aGlzLiNjYWNoZVNpemUgPSBjYWNoZVNpemU7XHJcblxyXG4gICAgICAgIHRoaXMuI2J1bGtSZXF1ZXN0TnVtYmVyID0gYnVsa1JlcXVlc3ROdW1iZXI7XHJcbiAgICAgICAgdGhpcy4jcmVxdWVzdE51bWJlciA9IHJlcXVlc3ROdW1iZXI7XHJcbiAgICAgICAgdGhpcy4jcmVxdWVzdFNpemUgPSBzaW5nbGVSZXF1ZXN0U2l6ZTtcclxuXHJcbiAgICAgICAgdGhpcy4jcG9wdWxhdGUoKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEZ1bmN0aW9uIHRvIGNvbnRpbnVlIGlzc3VpbmcgcmVxdWVzdHMgdW50aWwgdGhlIHN0YWNrIGlzIGZ1bGwuXHJcbiAgICAgKiBcclxuICAgICAqIEtlZXAgaXNzdWluZyByZXF1ZXN0cyB0byBzZXJ2ZXIgdW50aWwgc3RhY2sgaXMgZnVsbC4gV2hlbiBzdGFjayBpcyBmdWxsXHJcbiAgICAgKiBpZiByZXF1ZXN0cyBhcmUgYmVpbmcgaXNzdWVkIGluIGJ1bGssIHdhaXQgdW50aWwgc3RhY2sgaGFzIGVub3VnaCBzcGFjZVxyXG4gICAgICogdG8gYWNjb21tb2RhdGUgYWxsIG9mIGEgYnVsayByZXF1ZXN0IGJlZm9yZSBpc3N1aW5nIGEgbmV3IHJlcXVlc3QsIG90aGVyd2lzZVxyXG4gICAgICogaXNzdWUgYSBuZXcgcmVxdWVzdCBldmVyeSB0aW1lIGFuIGl0ZW0gaW4gdGhlIHN0YWNrIGhhcyBiZWVuIGNvbnN1bWVkLiBOb3RlXHJcbiAgICAgKiB0aGF0IHJlcXVlc3RzIGFyZSBibG9ja2luZyAoJ2F3YWl0JyBpcyB1c2VkIHdoZW4gY2FsbGluZyB0aGUgcmVxdWVzdEZ1bmN0aW9uKSxcclxuICAgICAqIGkuZS4sIG9ubHkgb25lIHJlcXVlc3Qgd2lsbCBiZSBpc3N1ZWQgYnkgdGhlIGNhY2hlIGF0IGFueSBnaXZlbiB0aW1lLlxyXG4gICAgICovXHJcbiAgICAjcG9wdWxhdGUgPSBhc3luYyAoKSA9PiB7XHJcbiAgICAgICAgaWYgKCF0aGlzLiNjdXJyZW50bHlQb3B1bGF0aW5nICYmICF0aGlzLiNwYXVzZWQpIHtcclxuICAgICAgICAgICAgdGhpcy4jY3VycmVudGx5UG9wdWxhdGluZyA9IHRydWU7XHJcblxyXG4gICAgICAgICAgICBsZXQgcmVzcG9uc2UgPSBudWxsO1xyXG5cclxuICAgICAgICAgICAgd2hpbGUgKHRydWUpIHtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLiNlcnJvciAhPSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy4jYnVsa1JlcXVlc3ROdW1iZXIgPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gSXMgdGhlcmUgc3BhY2UgZm9yIGEgYnVsayByZXNwb25zZSBpbiB0aGUgc3RhY2s/XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuI3N0YWNrLmxlbmd0aCA8PSAodGhpcy4jY2FjaGVTaXplIC0gdGhpcy4jYnVsa1JlcXVlc3ROdW1iZXIpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZSA9IGF3YWl0IHRoaXMuI3JlcXVlc3RGdW5jdGlvbih0aGlzLiNyZXF1ZXN0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuI2FkZFJlc3BvbnNlKHJlc3BvbnNlLCB0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbm90IGVub3VnaCBiaXRzIHJlbWFpbmluZyBmb3IgYSBidWxrIHJlcXVlc3RcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlIGluc3RhbmNlb2YgUmFuZG9tT3JnSW5zdWZmaWNpZW50Qml0c0Vycm9yKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGJpdHNMZWZ0ID0gZS5nZXRCaXRzTGVmdCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChiaXRzTGVmdCA+IHRoaXMuI3JlcXVlc3RTaXplKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlmIHBvc3NpYmxlLCBhZGp1c3QgcmVxdWVzdCBmb3IgdGhlIGxhcmdlc3QgcG9zc2libGUgc2l6ZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgYWRqdXN0ZWRCdWxrID0gTWF0aC5mbG9vcihiaXRzTGVmdC90aGlzLiNyZXF1ZXN0U2l6ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuI3JlcXVlc3QucGFyYW1zLm4gPSBhZGp1c3RlZEJ1bGsgKiB0aGlzLiNyZXF1ZXN0TnVtYmVyO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLiNyZXF1ZXN0RnVuY3Rpb24odGhpcy4jcmVxdWVzdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuI2FkZFJlc3BvbnNlKHJlc3BvbnNlLCB0cnVlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlc2V0IHRvIG9yaWdpbmFsIGJ1bGsgcmVxdWVzdCBzaXplXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuI3JlcXVlc3QucGFyYW1zLm4gPSB0aGlzLiNidWxrUmVxdWVzdE51bWJlciAqIHRoaXMuI3JlcXVlc3ROdW1iZXI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmVxdWVzdCBzaXplIGNhbm5vdCBiZSBhZGp1c3RlZFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiNlcnJvciA9IGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFueSBvdGhlciBlcnJvciB0aHJvd24gZHVyaW5nIGluIHRoZSByZXF1ZXN0IGZ1bmN0aW9uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4jZXJyb3IgPSBlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gbm8gc3BhY2UgZm9yIGEgYnVsayByZXF1ZXN0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy4jc3RhY2subGVuZ3RoIDwgdGhpcy4jY2FjaGVTaXplKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gaW5kaXZpZHVhbCByZXF1ZXN0c1xyXG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlID0gYXdhaXQgdGhpcy4jcmVxdWVzdEZ1bmN0aW9uKHRoaXMuI3JlcXVlc3QpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiNhZGRSZXNwb25zZShyZXNwb25zZSwgZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2goZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiNlcnJvciA9IGU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyB0aGUgc3RhY2sgaXMgZnVsbFxyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9ICAgICAgICAgICAgICAgXHJcblxyXG4gICAgICAgICAgICB0aGlzLiNjdXJyZW50bHlQb3B1bGF0aW5nID0gZmFsc2U7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIGNhY2hlIHdpbGwgbm8gbG9uZ2VyIGNvbnRpbnVlIHRvIHBvcHVsYXRlIGl0c2VsZi5cclxuICAgICAqL1xyXG4gICAgc3RvcCgpIHtcclxuICAgICAgICB0aGlzLiNwYXVzZWQgPSB0cnVlO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIGNhY2hlIHdpbGwgcmVzdW1lIHBvcHVsYXRpbmcgaXRzZWxmIGlmIHN0b3BwZWQuXHJcbiAgICAgKi9cclxuICAgIHJlc3VtZSgpIHtcclxuICAgICAgICB0aGlzLiNwYXVzZWQgPSBmYWxzZTtcclxuXHJcbiAgICAgICAgLy8gY2hlY2sgaWYgaXQgbmVlZHMgdG8gYmUgcmVwb3B1bGF0ZWRcclxuICAgICAgICB0aGlzLiNyZWZyZXNoKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDaGVja3MgaWYgdGhlIGNhY2hlIGlzIGN1cnJlbnRseSBub3QgcmUtcG9wdWxhdGluZyBpdHNlbGYuXHJcbiAgICAgKiBcclxuICAgICAqIFZhbHVlcyBjdXJyZW50bHkgY2FjaGVkIG1heSBzdGlsbCBiZSByZXRyaWV2ZWQgd2l0aCBnZXQoKSBidXQgbm8gbmV3XHJcbiAgICAgKiB2YWx1ZXMgYXJlIGJlaW5nIGZldGNoZWQgZnJvbSB0aGUgc2VydmVyLiBUaGlzIHN0YXRlIGNhbiBiZSBjaGFuZ2VkIHdpdGhcclxuICAgICAqIHN0b3AoKSBhbmQgcmVzdW1lKCkuXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiBjYWNoZSBpcyBjdXJyZW50bHkgbm90IHJlLXBvcHVsYXRpbmcgaXRzZWxmLFxyXG4gICAgICogICAgIGZhbHNlIG90aGVyd2lzZS5cclxuICAgICAqL1xyXG4gICAgaXNQYXVzZWQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuI3BhdXNlZDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHMgdGhlIG5leHQgcmVzcG9uc2UuXHJcbiAgICAgKiBOb3RlIHRoYXQgaWYgdGhlIGNhY2hlIGlzIGVtcHR5LCBpZiB3YXMgY29uc3RydWN0ZWQgd2l0aCB1bnN1aXRhYmxlIHBhcmFtZXRlclxyXG4gICAgICogdmFsdWVzIG9yIGlmIHRoZSBkYWlseSBhbGxvd2FuY2Ugb2YgYml0cy9yZXF1ZXN0cyBoYXMgYmVlbiByZWFjaGVkLCB0aGUgYXBwcm9wcmlhdGVcclxuICAgICAqIGVycm9yIHdpbGwgYmUgdGhyb3duLlxyXG4gICAgICogQHJldHVybnMge2FueVtdfSBUaGUgbmV4dCBhcHByb3ByaWF0ZSByZXNwb25zZSBmb3IgdGhlIHJlcXVlc3QgdGhpcyBSYW5kb21PcmdDYWNoZVxyXG4gICAgICogICAgIHJlcHJlc2VudHMgb3IsIGlmIHN0YWNrIGlzIGVtcHR5IHRocm93cyBhbiBlcnJvci5cclxuICAgICAqIEB0aHJvd3MgUmFuZG9tT3JnQ2FjaGVFbXB0eUVycm9yIGlmIHRoZSBjYWNoZSBpcyBlbXB0eS5cclxuICAgICAqL1xyXG4gICAgZ2V0KCkge1xyXG4gICAgICAgIGlmICh0aGlzLiNlcnJvciAhPSBudWxsKSB7XHJcbiAgICAgICAgICAgIHRocm93IHRoaXMuI2Vycm9yO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodGhpcy4jc3RhY2sgJiYgdGhpcy4jc3RhY2subGVuZ3RoID09IDApIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuI3BhdXNlZCkge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmRvbU9yZ0NhY2hlRW1wdHlFcnJvcignVGhlIFJhbmRvbU9yZ0NhY2hlIHN0YWNrICdcclxuICAgICAgICAgICAgICAgICAgICArICdpcyBlbXB0eSBhbmQgdGhlIGNhY2hlIGlzIHBhdXNlZC4gUGxlYXNlIGNhbGwgcmVzdW1lKCkgdG8gJ1xyXG4gICAgICAgICAgICAgICAgICAgICsgJ3Jlc3RhcnQgcG9wdWxhdGluZyB0aGUgY2FjaGUuJywgdHJ1ZSk7ICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmFuZG9tT3JnQ2FjaGVFbXB0eUVycm9yKCdUaGUgUmFuZG9tT3JnQ2FjaGUgc3RhY2sgJ1xyXG4gICAgICAgICAgICAgICAgICAgICsgJ2lzIGVtcHR5LCBwbGVhc2Ugd2FpdCBmb3IgaXQgdG8gcmVwb3B1bGF0ZSBpdHNlbGYuJyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBsZXQgZGF0YSA9IHRoaXMuI3N0YWNrLnBvcCgpO1xyXG5cclxuICAgICAgICAgICAgLy8gY2hlY2sgaWYgaXQgbmVlZHMgdG8gYmUgcmVwb3B1bGF0ZWRcclxuICAgICAgICAgICAgdGhpcy4jcmVmcmVzaCgpO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIGRhdGE7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0IG5leHQgcmVzcG9uc2Ugb3Igd2FpdCB1bnRpbCB0aGUgbmV4dCB2YWx1ZSBpcyBhdmFpbGFibGUuIFRoaXMgbWV0aG9kXHJcbiAgICAgKiB3aWxsIGJsb2NrIHVudGlsIGEgdmFsdWUgaXMgYXZhaWxhYmxlLiBOb3RlOiB0aGlzIG1ldGhvZCB3aWxsIHRocm93IGFuIGVycm9yXHJcbiAgICAgKiBpZiB0aGUgY2FjaGUgaXMgZW1wdHkgYW5kIGhhcyBiZWVuIHBhdXNlZCwgaS5lLiBpcyBub3QgYmVpbmcgcG9wdWxhdGVkLiBJZlxyXG4gICAgICogdGhlIGNhY2hlIHdhcyBjb25zdHJ1Y3RlZCB3aXRoIHVuc3VpdGFibGUgcGFyYW1ldGVyIHZhbHVlcyBvciB0aGUgZGFpbHkgYWxsb3dhbmNlXHJcbiAgICAgKiBvZiBiaXRzL3JlcXVlc3RzIGhhcyBiZWVuIHJlYWNoZWQsIHRoZSBhcHByb3ByaWF0ZSBlcnJvciB3aWxsIGFsc28gYmUgdGhyb3duLlxyXG4gICAgICogQHJldHVybnMge1Byb21pc2U8YW55W10+fSBUaGUgbmV4dCBhcHByb3ByaWF0ZSByZXNwb25zZSBmb3IgdGhlIHJlcXVlc3QgdGhpc1xyXG4gICAgICogUmFuZG9tT3JnQ2FjaGUgcmVwcmVzZW50cy5cclxuICAgICAqIEB0aHJvd3MgUmFuZG9tT3JnQ2FjaGVFbXB0eUVycm9yIGlmIHRoZSBjYWNoZSBpcyBlbXB0eSBhbmQgaXMgcGF1c2VkLlxyXG4gICAgICovXHJcbiAgICBhc3luYyBnZXRPcldhaXQoKSB7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgbGV0IHZhbHVlcyA9IHRoaXMuZ2V0KCk7XHJcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZXM7XHJcbiAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICBpZiAoZSBpbnN0YW5jZW9mIFJhbmRvbU9yZ0NhY2hlRW1wdHlFcnJvcikge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuI3BhdXNlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIFRoZSBjYWNoZSBpcyBwYXVzZWQgYW5kIHdpbGwgbm90IHJldHVybiBhbnkgdmFsdWVzXHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGxldCBjYWNoZWRWYWx1ZXMgPSBhd2FpdCB0aGlzLiNwb3B1bGF0ZSgpO1xyXG4gICAgICAgICAgICAgICAgaWYgKGNhY2hlZFZhbHVlcyA9PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gVGhlIGNhY2hlIGhhcyBub3QgeWV0IHJlcG9wdWxhdGVkLlxyXG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKHIgPT4gc2V0VGltZW91dChyLCA1MCkpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T3JXYWl0KCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSBudW1iZXIgb2YgcmVzdWx0IHNldHMgcmVtYWluaW5nIGluIHRoZSBjYWNoZS5cclxuICAgICAqIFxyXG4gICAgICogVGhpcyBlc3NlbnRpYWxseSByZXR1cm5zIGhvdyBvZnRlbiBnZXQoKSBtYXkgYmUgY2FsbGVkIHdpdGhvdXRcclxuICAgICAqIGEgY2FjaGUgcmVmaWxsLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gQ3VycmVudCBudW1iZXIgb2YgY2FjaGVkIHJlc3VsdHMuXHJcbiAgICAgKi9cclxuICAgIGdldENhY2hlZFZhbHVlcygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy4jc3RhY2subGVuZ3RoO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgbnVtYmVyIG9mIGJpdHMgdXNlZCBieSB0aGlzIGNhY2hlLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gTnVtYmVyIG9mIGJpdHMgdXNlZC5cclxuICAgICAqL1xyXG4gICAgZ2V0Qml0c1VzZWQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuI2JpdHNVc2VkO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyBudW1iZXIgb2YgcmVxdWVzdHMgdXNlZCBieSB0aGlzIGNhY2hlLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gTnVtYmVyIG9mIHJlcXVlc3RzIHVzZWQuXHJcbiAgICAgKi9cclxuICAgIGdldFJlcXVlc3RzVXNlZCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy4jcmVxdWVzdHNVc2VkO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogSGVscGVyIGZ1bmN0aW9uIHRvIGNoZWNrIGlmIHRoZSBjYWNoZSBuZWVkcyB0byBiZSByZXBvcHVsYXRlZC5cclxuICAgICAqL1xyXG4gICAgI3JlZnJlc2ggPSAoKSA9PiB7XHJcbiAgICAgICAgaWYgKHRoaXMuI2J1bGtSZXF1ZXN0TnVtYmVyID4gMCAmJiB0aGlzLiNzdGFjay5sZW5ndGggPD0gKHRoaXMuI2NhY2hlU2l6ZSAtIHRoaXMuI2J1bGtSZXF1ZXN0TnVtYmVyKSkge1xyXG4gICAgICAgICAgICAvLyBidWxrIHJlcXVlc3RzXHJcbiAgICAgICAgICAgIHRoaXMuI3BvcHVsYXRlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKHRoaXMuI2J1bGtSZXF1ZXN0TnVtYmVyIDw9IDAgJiYgdGhpcy4jc3RhY2subGVuZ3RoIDwgdGhpcy4jY2FjaGVTaXplKSB7XHJcbiAgICAgICAgICAgIC8vIGluZGl2aWR1YWwgcmVxdWVzdHNcclxuICAgICAgICAgICAgdGhpcy4jcG9wdWxhdGUoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBIZWxwZXIgZnVuY3Rpb24gdG8gYWRkIGEgcmVzcG9uc2UgdG8gdGhlIHN0YWNrLlxyXG4gICAgICogQHBhcmFtIHthbnlbXX0gcmVzcG9uc2UgVGhlIHJlc3BvbnNlIHJlY2VpdmVkIGZyb20gdGhlIHNlcnZlci5cclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gYnVsayBUcnVlIGlmIHRoZSBjYWNoZSBpc3N1ZXMgYnVsayByZXF1ZXN0cywgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gICAgICovXHJcbiAgICAjYWRkUmVzcG9uc2UgPSAocmVzcG9uc2UsIGJ1bGspID0+IHtcclxuICAgICAgICB0aGlzLiNyZXF1ZXN0c1VzZWQrKztcclxuICAgICAgICB0aGlzLiNiaXRzVXNlZCArPSByZXNwb25zZS5yZXN1bHQuYml0c1VzZWQ7XHJcblxyXG4gICAgICAgIGlmIChidWxrKSB7XHJcbiAgICAgICAgICAgIGxldCBkYXRhID0gcmVzcG9uc2UucmVzdWx0LnJhbmRvbS5kYXRhO1xyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyBpICs9IHRoaXMuI3JlcXVlc3ROdW1iZXIpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuI3N0YWNrLnB1c2goZGF0YS5zbGljZShpLCBpICsgdGhpcy4jcmVxdWVzdE51bWJlcikpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy4jc3RhY2sucHVzaChyZXNwb25zZS5yZXN1bHQucmFuZG9tLmRhdGEpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufSIsIid1c2Ugc3RyaWN0JztcclxuXHJcbmNvbnN0IHtcclxuICAgIFJhbmRvbU9yZ0JhZEhUVFBSZXNwb25zZUVycm9yLFxyXG4gICAgUmFuZG9tT3JnSW5zdWZmaWNpZW50Qml0c0Vycm9yLFxyXG4gICAgUmFuZG9tT3JnSW5zdWZmaWNpZW50UmVxdWVzdHNFcnJvcixcclxuICAgIFJhbmRvbU9yZ0pTT05SUENFcnJvcixcclxuICAgIFJhbmRvbU9yZ0tleU5vdFJ1bm5pbmdFcnJvcixcclxuICAgIFJhbmRvbU9yZ1JBTkRPTU9SR0Vycm9yLFxyXG4gICAgUmFuZG9tT3JnU2VuZFRpbWVvdXRFcnJvclxyXG59ID0gcmVxdWlyZSgnLi9SYW5kb21PcmdFcnJvcnMuanMnKTtcclxuY29uc3QgUmFuZG9tT3JnQ2FjaGUgPSByZXF1aXJlKCcuL1JhbmRvbU9yZ0NhY2hlLmpzJyk7XHJcbi8qIG5vZGUtaW1wb3J0ICovXHJcbmNvbnN0IFhNTEh0dHBSZXF1ZXN0ID0gcmVxdWlyZSgneG1saHR0cHJlcXVlc3QnKS5YTUxIdHRwUmVxdWVzdDtcclxuLyogZW5kLW5vZGUtaW1wb3J0ICovXHJcblxyXG4vKipcclxuICogUmFuZG9tT3JnQ2xpZW50IG1haW4gY2xhc3MgdGhyb3VnaCB3aGljaCBBUEkgZnVuY3Rpb25zIGFyZSBhY2Nlc3NlZC5cclxuICogXHJcbiAqIFRoaXMgY2xhc3MgcHJvdmlkZXMgYWNjZXNzIHRvIGJvdGggdGhlIHNpZ25lZCBhbmQgdW5zaWduZWQgbWV0aG9kcyBvZiB0aGVcclxuICogUkFORE9NLk9SRyBBUEkuXHJcbiAqIFxyXG4gKiBUaGUgY2xhc3MgYWxzbyBwcm92aWRlcyBhY2Nlc3MgdG8gdGhlIGNyZWF0aW9uIG9mIGEgY29udmVuaWVuY2UgY2xhc3MsIFJhbmRvbU9yZ0NhY2hlLFxyXG4gKiBmb3IgcHJlY2FjaGluZyBBUEkgcmVzcG9uc2VzIHdoZW4gdGhlIHJlcXVlc3QgaXMga25vd24gaW4gYWR2YW5jZS5cclxuICogXHJcbiAqIFRoaXMgY2xhc3Mgd2lsbCBvbmx5IGFsbG93IHRoZSBjcmVhdGlvbiBvZiBvbmUgaW5zdGFuY2UgcGVyIEFQSSBrZXkuIElmIGFuXHJcbiAqIGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgYWxyZWFkeSBleGlzdHMgZm9yIGEgZ2l2ZW4ga2V5LCB0aGF0IGluc3RhbmNlIHdpbGwgYmVcclxuICogcmV0dXJuZWQgaW5zdGVhZCBvZiBhIG5ldyBpbnN0YW5jZS5cclxuICogXHJcbiAqIFRoaXMgY2xhc3Mgb2JleXMgbW9zdCBvZiB0aGUgZ3VpZGVsaW5lcyBzZXQgZm9ydGggaW4gaHR0cHM6Ly9hcGkucmFuZG9tLm9yZy9qc29uLXJwYy80XHJcbiAqIEFsbCByZXF1ZXN0cyByZXNwZWN0IHRoZSBzZXJ2ZXIncyBhZHZpc29yeURlbGF5IHJldHVybmVkIGluIGFueSByZXNwb25zZXMsIG9yIHVzZVxyXG4gKiBERUZBVUxUX0RFTEFZIGlmIG5vIGFkdmlzb3J5RGVsYXkgaXMgcmV0dXJuZWQuIElmIHRoZSBzdXBwbGllZCBBUEkga2V5IGlzIHBhdXNlZCwgaS5lLixcclxuICogaGFzIGV4Y2VlZGVkIGl0cyBkYWlseSBiaXQvcmVxdWVzdCBhbGxvd2FuY2UsIHRoaXMgaW1wbGVtZW50YXRpb24gd2lsbCBiYWNrIG9mZiB1bnRpbFxyXG4gKiBtaWRuaWdodCBVVEMuXHJcbiAqL1xyXG5tb2R1bGUuZXhwb3J0cyA9IGNsYXNzIFJhbmRvbU9yZ0NsaWVudCB7XHJcbiAgICAvLyBCYXNpYyBBUElcclxuICAgIHN0YXRpYyAjSU5URUdFUl9NRVRIT0QgPSAnZ2VuZXJhdGVJbnRlZ2Vycyc7XHJcbiAgICBzdGF0aWMgI0lOVEVHRVJfU0VRVUVOQ0VfTUVUSE9EID0gJ2dlbmVyYXRlSW50ZWdlclNlcXVlbmNlcyc7XHJcbiAgICBzdGF0aWMgI0RFQ0lNQUxfRlJBQ1RJT05fTUVUSE9EID0gJ2dlbmVyYXRlRGVjaW1hbEZyYWN0aW9ucyc7XHJcbiAgICBzdGF0aWMgI0dBVVNTSUFOX01FVEhPRCA9ICdnZW5lcmF0ZUdhdXNzaWFucyc7XHJcbiAgICBzdGF0aWMgI1NUUklOR19NRVRIT0QgPSAnZ2VuZXJhdGVTdHJpbmdzJztcclxuICAgIHN0YXRpYyAjVVVJRF9NRVRIT0QgPSAnZ2VuZXJhdGVVVUlEcyc7XHJcbiAgICBzdGF0aWMgI0JMT0JfTUVUSE9EID0gJ2dlbmVyYXRlQmxvYnMnO1xyXG4gICAgc3RhdGljICNHRVRfVVNBR0VfTUVUSE9EID0gJ2dldFVzYWdlJztcclxuXHJcbiAgICAvLyBTaWduZWQgQVBJXHJcbiAgICBzdGF0aWMgI1NJR05FRF9JTlRFR0VSX01FVEhPRCA9ICdnZW5lcmF0ZVNpZ25lZEludGVnZXJzJztcclxuICAgIHN0YXRpYyAjU0lHTkVEX0lOVEVHRVJfU0VRVUVOQ0VfTUVUSE9EID0gJ2dlbmVyYXRlU2lnbmVkSW50ZWdlclNlcXVlbmNlcyc7XHJcbiAgICBzdGF0aWMgI1NJR05FRF9ERUNJTUFMX0ZSQUNUSU9OX01FVEhPRCA9ICdnZW5lcmF0ZVNpZ25lZERlY2ltYWxGcmFjdGlvbnMnO1xyXG4gICAgc3RhdGljICNTSUdORURfR0FVU1NJQU5fTUVUSE9EID0gJ2dlbmVyYXRlU2lnbmVkR2F1c3NpYW5zJztcclxuICAgIHN0YXRpYyAjU0lHTkVEX1NUUklOR19NRVRIT0QgPSAnZ2VuZXJhdGVTaWduZWRTdHJpbmdzJztcclxuICAgIHN0YXRpYyAjU0lHTkVEX1VVSURfTUVUSE9EID0gJ2dlbmVyYXRlU2lnbmVkVVVJRHMnO1xyXG4gICAgc3RhdGljICNTSUdORURfQkxPQl9NRVRIT0QgPSAnZ2VuZXJhdGVTaWduZWRCbG9icyc7XHJcbiAgICBzdGF0aWMgI0dFVF9SRVNVTFRfTUVUSE9EID0gJ2dldFJlc3VsdCc7XHJcbiAgICBzdGF0aWMgI0NSRUFURV9USUNLRVRfTUVUSE9EID0gJ2NyZWF0ZVRpY2tldHMnO1xyXG4gICAgc3RhdGljICNMSVNUX1RJQ0tFVF9NRVRIT0QgPSAnbGlzdFRpY2tldHMnO1xyXG4gICAgc3RhdGljICNSRVZFQUxfVElDS0VUX01FVEhPRCA9ICdyZXZlYWxUaWNrZXRzJztcclxuICAgIHN0YXRpYyAjR0VUX1RJQ0tFVF9NRVRIT0QgPSAnZ2V0VGlja2V0JztcclxuICAgIHN0YXRpYyAjVkVSSUZZX1NJR05BVFVSRV9NRVRIT0QgPSAndmVyaWZ5U2lnbmF0dXJlJztcclxuXHJcbiAgICAvLyBCbG9iIGZvcm1hdCBsaXRlcmFsc1xyXG4gICAgLyoqIEJsb2IgZm9ybWF0IGxpdGVyYWwsIGJhc2U2NCBlbmNvZGluZyAoZGVmYXVsdCkuICovXHJcbiAgICBzdGF0aWMgQkxPQl9GT1JNQVRfQkFTRTY0ID0gJ2Jhc2U2NCc7XHJcbiAgICAvKiogQmxvYiBmb3JtYXQgbGl0ZXJhbCwgaGV4IGVuY29kaW5nLiAqL1xyXG4gICAgc3RhdGljIEJMT0JfRk9STUFUX0hFWCA9ICdoZXgnO1xyXG5cclxuICAgIC8vIERlZmF1bHQgdmFsdWVzXHJcbiAgICAvKiogRGVmYXVsdCB2YWx1ZSBmb3IgdGhlIHJlcGxhY2VtZW50IHBhcmFtZXRlciAodHJ1ZSkuICovXHJcbiAgICBzdGF0aWMgREVGQVVMVF9SRVBMQUNFTUVOVCA9IHRydWU7XHJcbiAgICAvKiogRGVmYXVsdCB2YWx1ZSBmb3IgdGhlIGJhc2UgcGFyYW1ldGVyICgxMCkuICovXHJcbiAgICBzdGF0aWMgREVGQVVMVF9CQVNFID0gMTA7XHJcbiAgICAvKiogRGVmYXVsdCB2YWx1ZSBmb3IgdGhlIHVzZXJEYXRhIHBhcmFtZXRlciAobnVsbCkuICovXHJcbiAgICBzdGF0aWMgREVGQVVMVF9VU0VSX0RBVEEgPSBudWxsO1xyXG4gICAgLyoqIERlZmF1bHQgdmFsdWUgZm9yIHRoZSB0aWNrZXRJZCBwYXJhbWV0ZXIgKG51bGwpLiAqL1xyXG4gICAgc3RhdGljIERFRkFVTFRfVElDS0VUX0lEID0gbnVsbDtcclxuICAgIC8qKiBEZWZhdWx0IHZhbHVlIGZvciB0aGUgcHJlZ2VuZXJhdGVkUmFuZG9taXphdGlvbiBwYXJhbWV0ZXIgKG51bGwpLiAqL1xyXG4gICAgc3RhdGljIERFRkFVTFRfUFJFR0VORVJBVEVEX1JBTkRPTUlaQVRJT04gPSBudWxsO1xyXG4gICAgLyoqIERlZmF1bHQgdmFsdWUgZm9yIHRoZSBsaWNlbnNlRGF0YSBwYXJhbWV0ZXIgKG51bGwpLiAqL1xyXG4gICAgc3RhdGljIERFRkFVTFRfTElDRU5TRV9EQVRBID0gbnVsbDtcclxuXHJcbiAgICAvKiogU2l6ZSBvZiBhIHNpbmdsZSBVVUlEIGluIGJpdHMuICovXHJcbiAgICBzdGF0aWMgVVVJRF9TSVpFID0gMTIyO1xyXG4gICAgLyoqIERlZmF1bHQgdmFsdWUgZm9yIHRoZSBibG9ja2luZ1RpbWVvdXQgcGFyYW1ldGVyICgxIGRheSkuICovXHJcbiAgICBzdGF0aWMgREVGQVVMVF9CTE9DS0lOR19USU1FT1VUID0gMjQgKiA2MCAqIDYwICogMTAwMDtcclxuICAgIC8qKiBEZWZhdWx0IHZhbHVlIGZvciB0aGUgaHR0cFRpbWVvdXQgcGFyYW1ldGVyICgyIG1pbnV0ZXMpLiAqL1xyXG4gICAgc3RhdGljIERFRkFVTFRfSFRUUF9USU1FT1VUID0gMTIwICogMTAwMDtcclxuICAgIC8qKiBNYXhpbXVtIG51bWJlciBvZiBjaGFyYWN0ZXJzIGFsbG93ZWQgaW4gYSBzaWduYXR1cmUgdmVyZmljaWF0aW9uIFVSTC4gKi9cclxuICAgIHN0YXRpYyBNQVhfVVJMX0xFTkdUSCA9IDIwNDY7XHJcblxyXG4gICAgLy8gRGVmYXVsdCBiYWNrLW9mZiB0byB1c2UgaWYgbm8gYWR2aXNvcnlEZWxheSBiYWNrLW9mZiBzdXBwbGllZCBieSBzZXJ2ZXIgKDEgc2Vjb25kKVxyXG4gICAgc3RhdGljICNERUZBVUxUX0RFTEFZID0gMSoxMDAwO1xyXG5cclxuICAgIC8vIE9uIHJlcXVlc3QgZmV0Y2ggZnJlc2ggYWxsb3dhbmNlIHN0YXRlIGlmIGN1cnJlbnQgc3RhdGUgZGF0YSBpcyBvbGRlciB0aGFuXHJcbiAgICAvLyB0aGlzIHZhbHVlICgxIGhvdXIpLlxyXG4gICAgc3RhdGljICNBTExPV0FOQ0VfU1RBVEVfUkVGUkVTSF9TRUNPTkRTID0gMzYwMCAqIDEwMDA7XHJcblxyXG4gICAgLy8gTWFpbnRhaW5zIHVzYWdlIHN0YXRpc3RpY3MgZnJvbSBzZXJ2ZXIuXHJcbiAgICAjYml0c0xlZnQgPSAtMTtcclxuICAgICNyZXF1ZXN0c0xlZnQgPSAtMTtcclxuXHJcbiAgICAvLyBCYWNrLW9mZiBpbmZvIGZvciB3aGVuIHRoZSBBUEkga2V5IGlzIGRldGVjdGVkIGFzIG5vdCBydW5uaW5nLCBwcm9iYWJseVxyXG4gICAgLy8gYmVjYXVzZSB0aGUga2V5IGhhcyBleGNlZWRlZCBpdHMgZGFpbHkgdXNhZ2UgbGltaXQuIEJhY2stb2ZmIHJ1bnMgdW50aWxcclxuICAgIC8vIG1pZG5pZ2h0IFVUQy5cclxuICAgICNiYWNrb2ZmID0gLTE7XHJcbiAgICAjYmFja29mZkVycm9yID0gJyc7XHJcblxyXG4gICAgI2FwaUtleSA9ICcnO1xyXG4gICAgI2Jsb2NraW5nVGltZW91dCA9IFJhbmRvbU9yZ0NsaWVudC5ERUZBVUxUX0JMT0NLSU5HX1RJTUVPVVQ7XHJcbiAgICAjaHR0cFRpbWVvdXQgPSBSYW5kb21PcmdDbGllbnQuREVGQVVMVF9IVFRQX1RJTUVPVVQ7XHJcblxyXG4gICAgLy8gTWFpbnRhaW4gaW5mbyB0byBvYmV5IHNlcnZlciBhZHZpc29yeSBkZWxheVxyXG4gICAgI2Fkdmlzb3J5RGVsYXkgPSAwO1xyXG4gICAgI2xhc3RSZXNwb25zZVJlY2VpdmVkVGltZSA9IDA7XHJcblxyXG4gICAgLy8gTWFpbnRhaW5zIGEgZGljdGlvbmFyeSBvZiBBUEkga2V5cyBhbmQgdGhlaXIgaW5zdGFuY2VzLlxyXG4gICAgc3RhdGljICNrZXlJbmRleGVkSW5zdGFuY2VzID0ge307XHJcblxyXG4gICAgc3RhdGljICNFUlJPUl9DT0RFUyA9IFsgMTAwLCAxMDEsIDIwMCwgMjAxLCAyMDIsIDIwMywgMjA0LCAzMDAsXHJcbiAgICAgICAgMzAxLCAzMDIsIDMwMywgMzA0LCAzMDUsIDMwNiwgMzA3LCA0MDAsIDQwMSwgNDAyLCA0MDMsIDQwNCxcclxuICAgICAgICA0MDUsIDQyMCwgNDIxLCA0MjIsIDQyMywgNDI0LCA0MjUsIDQyNiwgNTAwLCAzMjAwMCBdO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29uc3RydWN0b3IuIEVuc3VyZXMgb25seSBvbmUgaW5zdGFuY2Ugb2YgUmFuZG9tT3JnQ2xpZW50IGV4aXN0cyBwZXIgQVBJXHJcbiAgICAgKiBrZXkuIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2UgaWYgdGhlIHN1cHBsaWVkIGtleSBpc24ndCBhbHJlYWR5IGtub3duLFxyXG4gICAgICogb3RoZXJ3aXNlIHJldHVybnMgdGhlIHByZXZpb3VzbHkgaW5zdGFudGlhdGVkIG9uZS5cclxuICAgICAqIEBjb25zdHJ1Y3RvclxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGFwaUtleSBBUEkga2V5IG9mIGluc3RhbmNlIHRvIGNyZWF0ZS9maW5kLCBvYnRhaW5lZCBmcm9tXHJcbiAgICAgKiAgICAgUkFORE9NLk9SRywgc2VlIGh0dHBzOi8vYXBpLnJhbmRvbS5vcmcvYXBpLWtleXNcclxuICAgICAqIEBwYXJhbSB7e2Jsb2NraW5nVGltZW91dD86IG51bWJlciwgaHR0cFRpbWVvdXQ/OiBudW1iZXJ9fSBvcHRpb25zIEFuIG9iamVjdFxyXG4gICAgICogICAgIHdoaWNoIG1heSBjb250YWlucyBhbnkgb2YgdGhlIGZvbGxvd2luZyBvcHRpb25hbCBwYXJhbWV0ZXJzOlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRpb25zLmJsb2NraW5nVGltZW91dCA9IDI0ICogNjAgKiA2MCAqIDEwMDBdIE1heGltdW1cclxuICAgICAqICAgICB0aW1lIGluIG1pbGxpc2Vjb25kcyB0byB3YWl0IGJlZm9yZSBiZWluZyBhbGxvd2VkIHRvIHNlbmQgYSByZXF1ZXN0LlxyXG4gICAgICogICAgIE5vdGUgdGhpcyBpcyBhIGhpbnQgbm90IGEgZ3VhcmFudGVlLiBUaGUgYWR2aXNvcnkgZGVsYXkgZnJvbSBzZXJ2ZXJcclxuICAgICAqICAgICBtdXN0IGFsd2F5cyBiZSBvYmV5ZWQuIFN1cHBseSBhIHZhbHVlIG9mIC0xIHRvIGFsbG93IGJsb2NraW5nIGZvcmV2ZXJcclxuICAgICAqICAgICAoZGVmYXVsdCAyNCAqIDYwICogNjAgKiAxMDAwLCBpLmUuLCAxIGRheSkuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdGlvbnMuaHR0cFRpbWVvdXQgPSAxMjAgKiAxMDAwXSBNYXhpbXVtIHRpbWUgaW5cclxuICAgICAqICAgICBtaWxsaXNlY29uZHMgdG8gd2FpdCBmb3IgdGhlIHNlcnZlciByZXNwb25zZSB0byBhIHJlcXVlc3QgKGRlZmF1bHRcclxuICAgICAqICAgICAxMjAqMTAwMCkuXHJcbiAgICAgKi9cclxuICAgIGNvbnN0cnVjdG9yKGFwaUtleSwgb3B0aW9ucyA9IHt9KSB7XHJcbiAgICAgICAgaWYgKFJhbmRvbU9yZ0NsaWVudC4ja2V5SW5kZXhlZEluc3RhbmNlcyAmJiBSYW5kb21PcmdDbGllbnQuI2tleUluZGV4ZWRJbnN0YW5jZXNbYXBpS2V5XSkge1xyXG4gICAgICAgICAgICByZXR1cm4gUmFuZG9tT3JnQ2xpZW50LiNrZXlJbmRleGVkSW5zdGFuY2VzW2FwaUtleV07XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy4jYXBpS2V5ID0gYXBpS2V5O1xyXG4gICAgICAgICAgICB0aGlzLiNibG9ja2luZ1RpbWVvdXQgPSBvcHRpb25zLmJsb2NraW5nVGltZW91dCB8fCAyNCAqIDYwICogNjAgKiAxMDAwO1xyXG4gICAgICAgICAgICB0aGlzLiNodHRwVGltZW91dCA9IG9wdGlvbnMuaHR0cFRpbWVvdXQgfHwgMTIwICogMTAwMDtcclxuXHJcbiAgICAgICAgICAgIFJhbmRvbU9yZ0NsaWVudC4ja2V5SW5kZXhlZEluc3RhbmNlc1thcGlLZXldID0gdGhpcztcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQmFzaWMgQVBJXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXF1ZXN0cyBhbmQgcmV0dXJucyBhbiBhcnJheSBvZiB0cnVlIHJhbmRvbSBpbnRlZ2VycyB3aXRoaW4gYSB1c2VyLWRlZmluZWRcclxuICAgICAqIHJhbmdlIGZyb20gdGhlIHNlcnZlci5cclxuICAgICAqIFxyXG4gICAgICogU2VlOiBodHRwczovL2FwaS5yYW5kb20ub3JnL2pzb24tcnBjLzQvYmFzaWMjZ2VuZXJhdGVJbnRlZ2Vyc1xyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG4gVGhlIG51bWJlciBvZiByYW5kb20gaW50ZWdlcnMgeW91IG5lZWQuIE11c3QgYmUgd2l0aGluXHJcbiAgICAgKiAgICAgdGhlIFsxLDFlNF0gcmFuZ2UuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbWluIFRoZSBsb3dlciBib3VuZGFyeSBmb3IgdGhlIHJhbmdlIGZyb20gd2hpY2ggdGhlIHJhbmRvbVxyXG4gICAgICogICAgIG51bWJlcnMgd2lsbCBiZSBwaWNrZWQuIE11c3QgYmUgd2l0aGluIHRoZSBbLTFlOSwxZTldIHJhbmdlLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG1heCBUaGUgdXBwZXIgYm91bmRhcnkgZm9yIHRoZSByYW5nZSBmcm9tIHdoaWNoIHRoZSByYW5kb21cclxuICAgICAqICAgICBudW1iZXJzIHdpbGwgYmUgcGlja2VkLiBNdXN0IGJlIHdpdGhpbiB0aGUgWy0xZTksMWU5XSByYW5nZS5cclxuICAgICAqIEBwYXJhbSB7e3JlcGxhY2VtZW50PzogYm9vbGVhbiwgYmFzZT86IG51bWJlciwgcHJlZ2VuZXJhdGVkUmFuZG9taXphdGlvbj86XHJcbiAgICAgKiAgICAgT2JqZWN0fX0gb3B0aW9ucyBBbiBvYmplY3Qgd2hpY2ggbWF5IGNvbnRhaW5zIGFueSBvZiB0aGUgZm9sbG93aW5nXHJcbiAgICAgKiAgICAgb3B0aW9uYWwgcGFyYW1ldGVyczpcclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMucmVwbGFjZW1lbnQ9dHJ1ZV0gU3BlY2lmaWVzIHdoZXRoZXIgdGhlIHJhbmRvbVxyXG4gICAgICogICAgIG51bWJlcnMgc2hvdWxkIGJlIHBpY2tlZCB3aXRoIHJlcGxhY2VtZW50LiBJZiB0cnVlLCB0aGUgcmVzdWx0aW5nIG51bWJlcnNcclxuICAgICAqICAgICBtYXkgY29udGFpbiBkdXBsaWNhdGUgdmFsdWVzLCBvdGhlcndpc2UgdGhlIG51bWJlcnMgd2lsbCBhbGwgYmUgdW5pcXVlXHJcbiAgICAgKiAgICAgKGRlZmF1bHQgdHJ1ZSkuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdGlvbnMuYmFzZT0xMF0gVGhlIGJhc2UgdGhhdCB3aWxsIGJlIHVzZWQgdG8gZGlzcGxheVxyXG4gICAgICogICAgIHRoZSBudW1iZXJzLiBWYWx1ZXMgYWxsb3dlZCBhcmUgMiwgOCwgMTAgYW5kIDE2IChkZWZhdWx0IDEwKS5cclxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucy5wcmVnZW5lcmF0ZWRSYW5kb21pemF0aW9uPW51bGxdIEEgZGljdGlvbmFyeSBvYmplY3RcclxuICAgICAqICAgICB3aGljaCBhbGxvd3MgdGhlIGNsaWVudCB0byBzcGVjaWZ5IHRoYXQgdGhlIHJhbmRvbSB2YWx1ZXMgc2hvdWxkIGJlXHJcbiAgICAgKiAgICAgZ2VuZXJhdGVkIGZyb20gYSBwcmVnZW5lcmF0ZWQsIGhpc3RvcmljYWwgcmFuZG9taXphdGlvbiBpbnN0ZWFkIG9mIGFcclxuICAgICAqICAgICBvbmUtdGltZSBvbi10aGUtZmx5IHJhbmRvbWl6YXRpb24uIFRoZXJlIGFyZSB0aHJlZSBwb3NzaWJsZSBjYXNlczpcclxuICAgICAqICogKipudWxsKio6IFRoZSBzdGFuZGFyZCB3YXkgb2YgY2FsbGluZyBmb3IgcmFuZG9tIHZhbHVlcywgaS5lLnRydWVcclxuICAgICAqICAgICAgIHJhbmRvbW5lc3MgaXMgZ2VuZXJhdGVkIGFuZCBkaXNjYXJkZWQgYWZ0ZXJ3YXJkcy5cclxuICAgICAqICogKipkYXRlKio6IFJBTkRPTS5PUkcgdXNlcyBoaXN0b3JpY2FsIHRydWUgcmFuZG9tbmVzcyBnZW5lcmF0ZWQgb24gdGhlXHJcbiAgICAgKiAgICAgICBjb3JyZXNwb25kaW5nIGRhdGUgKHBhc3Qgb3IgcHJlc2VudCwgZm9ybWF0OiB7ICdkYXRlJywgJ1lZWVktTU0tREQnIH0pLlxyXG4gICAgICogKiAqKmlkKio6IFJBTkRPTS5PUkcgdXNlcyBoaXN0b3JpY2FsIHRydWUgcmFuZG9tbmVzcyBkZXJpdmVkIGZyb20gdGhlXHJcbiAgICAgKiAgICAgICBjb3JyZXNwb25kaW5nIGlkZW50aWZpZXIgaW4gYSBkZXRlcm1pbmlzdGljIG1hbm5lci4gRm9ybWF0OiB7ICdpZCcsXHJcbiAgICAgKiAgICAgICAnUEVSU0lTVEVOVC1JREVOVElGSUVSJyB9IHdoZXJlICdQRVJTSVNURU5ULUlERU5USUZJRVInIGlzIGEgc3RyaW5nXHJcbiAgICAgKiAgICAgICB3aXRoIGxlbmd0aCBpbiB0aGUgWzEsIDY0XSByYW5nZS5cclxuICAgICAqIEByZXR1cm5zIHsoUHJvbWlzZTxudW1iZXJbXT58UHJvbWlzZTxzdHJpbmdbXT4pfSBBIFByb21pc2Ugd2hpY2gsIGlmXHJcbiAgICAgKiAgICAgcmVzb2x2ZWQgc3VjY2Vzc2Z1bGx5LCByZXByZXNlbnRzIGFuIGFycmF5IG9mIHRydWUgcmFuZG9tIGludGVnZXJzLlxyXG4gICAgICogQHRocm93cyB7UmFuZG9tT3JnU2VuZFRpbWVvdXRFcnJvcn0gVGhyb3duIHdoZW4gYmxvY2tpbmcgdGltZW91dCBpcyBleGNlZWRlZFxyXG4gICAgICogICAgIGJlZm9yZSB0aGUgcmVxdWVzdCBjYW4gYmUgc2VudC5cclxuICAgICAqIEB0aHJvd3Mge1JhbmRvbU9yZ0tleU5vdFJ1bm5pbmdFcnJvcn0gVGhyb3duIHdoZW4gdGhlIEFQSSBrZXk