UNPKG

@randomorg/core

Version:

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

2 lines 236 kB
var RandomOrgCore=function(e){"use strict";var t={};t.RandomOrgBadHTTPResponseError=class extends Error{constructor(e){super(e)}},t.RandomOrgInsufficientBitsError=class extends Error{#bits=-1;constructor(e,t){super(e),this.#bits=t}getBitsLeft(){return this.#bits}},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{#code=-1;constructor(e,t=-1){super(e),this.#code=t}getCode(){return this.#code}},t.RandomOrgSendTimeoutError=class extends Error{constructor(e){super(e)}},t.RandomOrgCacheEmptyError=class extends Error{#paused=!1;constructor(e,t=!1){super(e),this.#paused=t}wasPaused(){return this.#paused}};const{RandomOrgInsufficientBitsError:s,RandomOrgCacheEmptyError:r}=t;var a=class{#requestFunction=null;#request=null;#bulkRequestNumber=0;#requestNumber=0;#requestSize=-1;#stack=[];#cacheSize=10;#paused=!1;#bitsUsed=0;#requestsUsed=0;#currentlyPopulating=!1;#error=null;constructor(e,t,s,r,a,i){this.#requestFunction=e,this.#request=t,this.#cacheSize=s,this.#bulkRequestNumber=r,this.#requestNumber=a,this.#requestSize=i,this.#populate()}#populate=async()=>{if(!this.#currentlyPopulating&&!this.#paused){this.#currentlyPopulating=!0;let e=null;for(;null==this.#error;)if(this.#bulkRequestNumber>0){if(!(this.#stack.length<=this.#cacheSize-this.#bulkRequestNumber))break;try{e=await this.#requestFunction(this.#request),this.#addResponse(e,!0)}catch(t){if(t instanceof s){let s=t.getBitsLeft();if(s>this.#requestSize){let t=Math.floor(s/this.#requestSize);this.#request.params.n=t*this.#requestNumber,e=await this.#requestFunction(this.#request),this.#addResponse(e,!0),this.#request.params.n=this.#bulkRequestNumber*this.#requestNumber}else this.#error=t}else this.#error=t}}else{if(!(this.#stack.length<this.#cacheSize))break;try{e=await this.#requestFunction(this.#request),this.#addResponse(e,!1)}catch(e){this.#error=e}}this.#currentlyPopulating=!1}};stop(){this.#paused=!0}resume(){this.#paused=!1,this.#refresh()}isPaused(){return this.#paused}get(){if(null!=this.#error)throw this.#error;if(this.#stack&&0==this.#stack.length)throw this.#paused?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.#stack.pop();return this.#refresh(),e}}async getOrWait(){try{return this.get()}catch(e){if(e instanceof r){if(this.#paused)throw e;return 0==await this.#populate()&&await new Promise((e=>setTimeout(e,50))),this.getOrWait()}}}getCachedValues(){return this.#stack.length}getBitsUsed(){return this.#bitsUsed}getRequestsUsed(){return this.#requestsUsed}#refresh=()=>{(this.#bulkRequestNumber>0&&this.#stack.length<=this.#cacheSize-this.#bulkRequestNumber||this.#bulkRequestNumber<=0&&this.#stack.length<this.#cacheSize)&&this.#populate()};#addResponse=(e,t)=>{if(this.#requestsUsed++,this.#bitsUsed+=e.result.bitsUsed,t){let t=e.result.random.data;for(let e=0;e<t.length;e+=this.#requestNumber)this.#stack.push(t.slice(e,e+this.#requestNumber))}else this.#stack.push(e.result.random.data)}};const{RandomOrgBadHTTPResponseError:i,RandomOrgInsufficientBitsError:n,RandomOrgInsufficientRequestsError:u,RandomOrgJSONRPCError:c,RandomOrgKeyNotRunningError:o,RandomOrgRANDOMORGError:l,RandomOrgSendTimeoutError:h}=t,d=a;var E=class e{static#INTEGER_METHOD="generateIntegers";static#INTEGER_SEQUENCE_METHOD="generateIntegerSequences";static#DECIMAL_FRACTION_METHOD="generateDecimalFractions";static#GAUSSIAN_METHOD="generateGaussians";static#STRING_METHOD="generateStrings";static#UUID_METHOD="generateUUIDs";static#BLOB_METHOD="generateBlobs";static#GET_USAGE_METHOD="getUsage";static#SIGNED_INTEGER_METHOD="generateSignedIntegers";static#SIGNED_INTEGER_SEQUENCE_METHOD="generateSignedIntegerSequences";static#SIGNED_DECIMAL_FRACTION_METHOD="generateSignedDecimalFractions";static#SIGNED_GAUSSIAN_METHOD="generateSignedGaussians";static#SIGNED_STRING_METHOD="generateSignedStrings";static#SIGNED_UUID_METHOD="generateSignedUUIDs";static#SIGNED_BLOB_METHOD="generateSignedBlobs";static#GET_RESULT_METHOD="getResult";static#CREATE_TICKET_METHOD="createTickets";static#LIST_TICKET_METHOD="listTickets";static#GET_TICKET_METHOD="getTicket";static#VERIFY_SIGNATURE_METHOD="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#DEFAULT_DELAY=1e3;static#ALLOWANCE_STATE_REFRESH_SECONDS=36e5;#bitsLeft=-1;#requestsLeft=-1;#backoff=-1;#backoffError="";#apiKey="";#blockingTimeout=e.DEFAULT_BLOCKING_TIMEOUT;#httpTimeout=e.DEFAULT_HTTP_TIMEOUT;#advisoryDelay=0;#lastResponseReceivedTime=0;static#keyIndexedInstances={};static#ERROR_CODES=[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,500,32e3];constructor(t,s={}){if(e.#keyIndexedInstances&&e.#keyIndexedInstances[t])return e.#keyIndexedInstances[t];this.#apiKey=t,this.#blockingTimeout=s.blockingTimeout||864e5,this.#httpTimeout=s.httpTimeout||12e4,e.#keyIndexedInstances[t]=this}async generateIntegers(e,t,s,r={}){let a=this.#integerRequest(e,t,s,r);return this.#extractBasic(this.#sendRequest(a))}async generateIntegerSequences(e,t,s,r,a={}){let i=this.#integerSequenceRequest(e,t,s,r,a);return this.#extractBasic(this.#sendRequest(i))}async generateDecimalFractions(e,t,s={}){let r=this.#decimalFractionRequest(e,t,s);return this.#extractBasic(this.#sendRequest(r))}async generateGaussians(e,t,s,r,a={}){let i=this.#gaussianRequest(e,t,s,r,a);return this.#extractBasic(this.#sendRequest(i))}async generateStrings(e,t,s,r={}){let a=this.#stringRequest(e,t,s,r);return this.#extractBasic(this.#sendRequest(a))}async generateUUIDs(e,t={}){let s=this.#UUIDRequest(e,t);return this.#extractBasic(this.#sendRequest(s))}async generateBlobs(e,t,s={}){let r=this.#blobRequest(e,t,s);return this.#extractBasic(this.#sendRequest(r))}async generateSignedIntegers(e,t,s,r={}){let a=this.#integerRequest(e,t,s,r,!0);return this.#extractSigned(this.#sendRequest(a))}async generateSignedIntegerSequences(e,t,s,r,a={}){let i=this.#integerSequenceRequest(e,t,s,r,a,!0);return this.#extractSigned(this.#sendRequest(i))}async generateSignedDecimalFractions(e,t,s={}){let r=this.#decimalFractionRequest(e,t,s,!0);return this.#extractSigned(this.#sendRequest(r))}async generateSignedGaussians(e,t,s,r,a={}){let i=this.#gaussianRequest(e,t,s,r,a,!0);return this.#extractSigned(this.#sendRequest(i))}async generateSignedStrings(e,t,s,r={}){let a=this.#stringRequest(e,t,s,r,!0);return this.#extractSigned(this.#sendRequest(a))}async generateSignedUUIDs(e,t={}){let s=this.#UUIDRequest(e,t,!0);return this.#extractSigned(this.#sendRequest(s))}async generateSignedBlobs(e,t,s={}){let r=this.#blobRequest(e,t,s,!0);return this.#extractSigned(this.#sendRequest(r))}async verifySignature(t,s){let r={random:t,signature:s},a=this.#generateRequest(e.#VERIFY_SIGNATURE_METHOD,r);return this.#extractVerification(this.#sendRequest(a))}async getBitsLeft(){let t=Date.now()>this.#lastResponseReceivedTime+e.#ALLOWANCE_STATE_REFRESH_SECONDS;return(this.#bitsLeft<0||t)&&await this.#getUsage(),this.#bitsLeft}async getRequestsLeft(){let t=Date.now()>this.#lastResponseReceivedTime+e.#ALLOWANCE_STATE_REFRESH_SECONDS;return(this.#requestsLeft<0||t)&&await this.#getUsage(),this.#requestsLeft}async getResult(t){let s={serialNumber:t},r=this.#generateKeyedRequest(e.#GET_RESULT_METHOD,s);return this.#extractSigned(this.#sendRequest(r))}async createTickets(t,s){let r={n:t,showResult:s},a=this.#generateKeyedRequest(e.#CREATE_TICKET_METHOD,r);return this.#extractResult(this.#sendRequest(a))}async listTickets(t){let s={ticketType:t},r=this.#generateKeyedRequest(e.#LIST_TICKET_METHOD,s);return this.#extractResult(this.#sendRequest(r))}async getTicket(t){let s={ticketId:t},r=this.#generateRequest(e.#GET_TICKET_METHOD,s);return this.#extractResult(this.#sendRequest(r))}createUrl(t,s){let r="https://api.random.org/signatures/form?format=json";if(r+="&random="+this.#formatUrl(JSON.stringify(t)),r+="&signature="+this.#formatUrl(s),r.length>e.MAX_URL_LENGTH)throw new l("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.#inputHTML("hidden","format","json")+"\n",s+=" "+this.#inputHTML("hidden","random",JSON.stringify(e))+"\n",s+=" "+this.#inputHTML("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.#integerRequest(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 d(this.#sendRequest.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.#maxValue(r)-this.#minValue(s),1)/Math.log(2)*e*this.#maxValue(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.#adjust(t,c)),Array.isArray(s)&&(s=this.#adjust(s,c)),Array.isArray(r)&&(r=this.#adjust(r,c)),a.replacement&&Array.isArray(a.replacement)&&(a.replacement=this.#adjust(a.replacement,c)),a.base&&Array.isArray(a.base)&&(a.base=this.#adjust(a.base,c)));let o=this.#integerSequenceRequest(e,t,s,r,a);return n&&(o.params.n=c*e),new d(this.#sendRequest.bind(this),o,i,c,e,u)}createDecimalFractionCache(e,t,s={}){let r=s.cacheSize||20;r<2&&(r=2);let a=this.#decimalFractionRequest(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 d(this.#sendRequest.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.#gaussianRequest(e*u,t,s,r);return new d(this.#sendRequest.bind(this),c,i,u,e,n)}createStringCache(e,t,s,r={}){let a=r.cacheSize||20;a<2&&(a=2);let i=this.#stringRequest(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 d(this.#sendRequest.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.#UUIDRequest(t*i);return new d(this.#sendRequest.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.#blobRequest(e*i,t,s);return new d(this.#sendRequest.bind(this),n,r,i,e,a)}#sendRequest=async function(t){if(-1!=this.#backoff){if(Date.now()<this.#backoff)throw new u(this.#backoffError);this.#backoff=-1,this.#backoffError=null}let s=this.#advisoryDelay-(Date.now()-this.#lastResponseReceivedTime);if(-1!=this.#blockingTimeout&&s>this.#blockingTimeout)throw new h("The server advisory delay of "+s+"millis is greater than the defined maximum allowed blocking time of "+this.#blockingTimeout+"millis.");s>0&&await new Promise((e=>setTimeout(e,s)));let r=this.#httpTimeout;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 h("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 i("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.#backoff=+e,this.#backoffError="Error "+t+": "+r,this.#requestsLeft=a[1],new u(this.#backoffError)}throw 403==t?(this.#bitsLeft=a[1],new n("Error"+t+": "+r,this.#bitsLeft)):e.#ERROR_CODES.includes(t)?new l("Error "+t+": "+r,t):new c("Error "+t+": "+r)}return[e.#VERIFY_SIGNATURE_METHOD,e.#GET_RESULT_METHOD,e.#CREATE_TICKET_METHOD,e.#LIST_TICKET_METHOD,e.#GET_TICKET_METHOD].includes(t.method)?this.#advisoryDelay=e.#DEFAULT_DELAY:(this.#requestsLeft=s.result.requestsLeft,this.#bitsLeft=s.result.bitsLeft,s.result.advisoryDelay?this.#advisoryDelay=s.result.advisoryDelay:this.#advisoryDelay=e.#DEFAULT_DELAY),this.#lastResponseReceivedTime=Date.now(),s}))};#getUsage=async()=>{let t=this.#generateKeyedRequest(e.#GET_USAGE_METHOD,{});return this.#extractResult(this.#sendRequest(t))};#generateRequest=(e,t)=>({jsonrpc:"2.0",method:e,params:t,id:this.#uuidv4()});#generateKeyedRequest=(e,t)=>(t.apiKey=this.#apiKey,this.#generateRequest(e,t));#extractBasic=async e=>e.then((e=>e.result.random.data));#extractSigned=async e=>e.then((e=>({data:e.result.random.data,random:e.result.random,signature:e.result.signature})));#extractVerification=async e=>e.then((e=>e.result.authenticity));#extractResult=async e=>e.then((e=>e.result));#integerRequest=(t,s,r,{replacement:a=!0,base:i=10,pregeneratedRandomization:n=null,licenseData:u=null,userData:c=null,ticketId:o=null}={},l=!1)=>{let h={n:t,min:s,max:r,replacement:a,base:i};h=this.#addOptionalParams(h,n,u,c,o,l);let d=l?e.#SIGNED_INTEGER_METHOD:e.#INTEGER_METHOD;return this.#generateKeyedRequest(d,h)};#integerSequenceRequest=(t,s,r,a,{replacement:i=!0,base:n=10,pregeneratedRandomization:u=null,licenseData:c=null,userData:o=null,ticketId:l=null}={},h=!1)=>{let d={n:t,length:s,min:r,max:a,replacement:i,base:n};d=this.#addOptionalParams(d,u,c,o,l,h);let E=h?e.#SIGNED_INTEGER_SEQUENCE_METHOD:e.#INTEGER_SEQUENCE_METHOD;return this.#generateKeyedRequest(E,d)};#decimalFractionRequest=(t,s,{replacement:r=!0,pregeneratedRandomization:a=null,licenseData:i=null,userData:n=null,ticketId:u=null}={},c=!1)=>{let o={n:t,decimalPlaces:s,replacement:r};o=this.#addOptionalParams(o,a,i,n,u,c);let l=c?e.#SIGNED_DECIMAL_FRACTION_METHOD:e.#DECIMAL_FRACTION_METHOD;return this.#generateKeyedRequest(l,o)};#gaussianRequest=(t,s,r,a,{pregeneratedRandomization:i=null,licenseData:n=null,userData:u=null,ticketId:c=null}={},o=!1)=>{let l={n:t,mean:s,standardDeviation:r,significantDigits:a};l=this.#addOptionalParams(l,i,n,u,c,o);let h=o?e.#SIGNED_GAUSSIAN_METHOD:e.#GAUSSIAN_METHOD;return this.#generateKeyedRequest(h,l)};#stringRequest=(t,s,r,{replacement:a=!0,pregeneratedRandomization:i=null,licenseData:n=null,userData:u=null,ticketId:c=null}={},o=!1)=>{let l={n:t,length:s,characters:r,replacement:a};l=this.#addOptionalParams(l,i,n,u,c,o);let h=o?e.#SIGNED_STRING_METHOD:e.#STRING_METHOD;return this.#generateKeyedRequest(h,l)};#UUIDRequest=(t,{pregeneratedRandomization:s=null,licenseData:r=null,userData:a=null,ticketId:i=null}={},n=!1)=>{let u={n:t};u=this.#addOptionalParams(u,s,r,a,i,n);let c=n?e.#SIGNED_UUID_METHOD:e.#UUID_METHOD;return this.#generateKeyedRequest(c,u)};#blobRequest=(t,s,{format:r=this.BASE64,pregeneratedRandomization:a=null,licenseData:i=null,userData:n=null,ticketId:u=null},c=!1)=>{let o={n:t,size:s,format:r};o=this.#addOptionalParams(o,a,i,n,u,c);let l=c?e.#SIGNED_BLOB_METHOD:e.#BLOB_METHOD;return this.#generateKeyedRequest(l,o)};#addOptionalParams=(e,t,s,r,a,i=!1)=>(e.pregeneratedRandomization=t,i&&(e.licenseData=s,e.userData=r,e.ticketId=a),e);#adjust=(e,t)=>Array.from({length:t},(()=>e)).flat();#maxValue=e=>Array.isArray(e)?e.reduce((function(e,t){return Math.max(e,t)})):e;#minValue=e=>Array.isArray(e)?e.reduce((function(e,t){return Math.min(e,t)})):e;#formatUrl=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")};#inputHTML=(e,t,s)=>"<input type='"+e+"' name='"+t+"' value='"+s+"' />";#uuidv4=()=>"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)}))};let g=t.RandomOrgRANDOMORGError,R=t.RandomOrgBadHTTPResponseError,m=t.RandomOrgInsufficientBitsError,T=t.RandomOrgInsufficientRequestsError,p=t.RandomOrgJSONRPCError,D=t.RandomOrgKeyNotRunningError,O=t.RandomOrgSendTimeoutError,S=t.RandomOrgCacheEmptyError;return e.RandomOrgBadHTTPResponseError=R,e.RandomOrgCache=a,e.RandomOrgCacheEmptyError=S,e.RandomOrgClient=E,e.RandomOrgInsufficientBitsError=m,e.RandomOrgInsufficientRequestsError=T,e.RandomOrgJSONRPCError=p,e.RandomOrgKeyNotRunningError=D,e.RandomOrgRANDOMORGError=g,e.RandomOrgSendTimeoutError=O,e.default=E,Object.defineProperty(e,"__esModule",{value:!0}),e}({}); //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmRvY29yZS5paWZlLm1pbi5qcyIsInNvdXJjZXMiOlsiLi4vUmFuZG9tT3JnRXJyb3JzLmpzIiwiLi4vUmFuZG9tT3JnQ2FjaGUuanMiLCIuLi9SYW5kb21PcmdDbGllbnQuanMiLCIuLi9lc20vaW5kZXguanMiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xyXG5cclxuLyoqXHJcbiAqIEVycm9yIHRocm93biBieSB0aGUgUmFuZG9tT3JnQ2xpZW50IGNsYXNzIHdoZW4gdGhlIGNvbm5lY3Rpb24gZG9lc24ndCByZXR1cm5cclxuICogYSBIVFRQIDIwMCBPSyByZXNwb25zZS5cclxuICovXHJcbmV4cG9ydHMuUmFuZG9tT3JnQmFkSFRUUFJlc3BvbnNlRXJyb3IgPSBjbGFzcyBSYW5kb21PcmdCYWRIVFRQUmVzcG9uc2VFcnJvciBleHRlbmRzIEVycm9yXHJcbntcclxuICAgIC8qKlxyXG4gICAgICogQ29uc3RydWN0cyBhIG5ldyBleGNlcHRpb24gd2l0aCB0aGUgc3BlY2lmaWVkIGRldGFpbCBtZXNzYWdlLlxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2UgVGhlIGRldGFpbCBtZXNzYWdlLlxyXG4gICAgICovXHJcbiAgICBjb25zdHJ1Y3RvcihtZXNzYWdlKSB7XHJcbiAgICAgICAgc3VwZXIobWVzc2FnZSk7XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBFcnJvciB0aHJvd24gYnkgdGhlIFJhbmRvbU9yZ0NsaWVudCBjbGFzcyB3aGVuIGl0cyBBUEkga2V5J3MgcmVxdWVzdCBoYXNcclxuICogZXhjZWVkZWQgaXRzIHJlbWFpbmluZyBzZXJ2ZXIgYml0cyBhbGxvd2FuY2UuXHJcbiAqIFxyXG4gKiBJZiB0aGUgY2xpZW50IGlzIGN1cnJlbnRseSBpc3N1aW5nIGxhcmdlIHJlcXVlc3RzIGl0IG1heSBiZSBwb3NzaWJsZSBzdWNjZWVkXHJcbiAqIHdpdGggc21hbGxlciByZXF1ZXN0cy4gVXNlIHRoZSBnZXRCaXRzTGVmdCgpIGNhbGwgaW4gdGhpcyBjbGFzcyB0byBoZWxwXHJcbiAqIGRldGVybWluZSBpZiBhbiBhbHRlcm5hdGl2ZSByZXF1ZXN0IHNpemUgaXMgYXBwcm9wcmlhdGUuXHJcbiAqL1xyXG4gZXhwb3J0cy5SYW5kb21PcmdJbnN1ZmZpY2llbnRCaXRzRXJyb3IgPSBjbGFzcyBSYW5kb21PcmdJbnN1ZmZpY2llbnRCaXRzRXJyb3IgZXh0ZW5kcyBFcnJvclxyXG57XHJcbiAgICAvLyBTdG9yZXMgdGhlIG51bWJlciBvZiBiaXRzIHJlbWFpbmluZ1xyXG4gICAgI2JpdHMgPSAtMTtcclxuICAgIFxyXG4gICAgLyoqXHJcbiAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGV4Y2VwdGlvbiB3aXRoIHRoZSBzcGVjaWZpZWQgZGV0YWlsIG1lc3NhZ2UuXHJcbiAgICAgKiBAY29uc3RydWN0b3JcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIFRoZSBkZXRhaWwgbWVzc2FnZS5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBiaXRzIEJpdHMgcmVtYWluaW5nIGp1c3QgYmVmb3JlIHRoZSBlcnJvciB3YXMgdGhyb3duLlxyXG4gICAgICovXHJcbiAgICBjb25zdHJ1Y3RvcihtZXNzYWdlLCBiaXRzKSB7XHJcbiAgICAgICAgc3VwZXIobWVzc2FnZSk7XHJcbiAgICAgICAgdGhpcy4jYml0cyA9IGJpdHM7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSBudW1iZXIgb2YgYml0cyByZW1haW5pbmcuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBUaGUgbnVtYmVyIG9mIGJpdHMgbGVmdC5cclxuICAgICAqL1xyXG4gICAgZ2V0Qml0c0xlZnQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuI2JpdHM7XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBFcnJvciB0aHJvd24gYnkgdGhlIFJhbmRvbU9yZ0NsaWVudCBjbGFzcyB3aGVuIGl0cyBBUEkga2V5J3Mgc2VydmVyIHJlcXVlc3RzXHJcbiAqIGFsbG93YW5jZSBoYXMgYmVlbiBleGNlZWRlZC5cclxuICogXHJcbiAqIFRoaXMgaW5kaWNhdGVzIHRoYXQgYSBiYWNrLW9mZiB1bnRpbCBtaWRuaWdodCBVVEMgaXMgaW4gZWZmZWN0LCBiZWZvcmUgd2hpY2hcclxuICogbm8gcmVxdWVzdHMgd2lsbCBiZSBzZW50IGJ5IHRoZSBjbGllbnQgYXMgbm8gbWVhbmluZ2Z1bCBzZXJ2ZXIgcmVzcG9uc2VzIHdpbGxcclxuICogYmUgcmV0dXJuZWQuXHJcbiAqL1xyXG5leHBvcnRzLlJhbmRvbU9yZ0luc3VmZmljaWVudFJlcXVlc3RzRXJyb3IgPSBjbGFzcyBSYW5kb21PcmdJbnN1ZmZpY2llbnRSZXF1ZXN0c0Vycm9yIGV4dGVuZHMgRXJyb3Jcclxue1xyXG4gICAgLyoqXHJcbiAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGV4Y2VwdGlvbiB3aXRoIHRoZSBzcGVjaWZpZWQgZGV0YWlsIG1lc3NhZ2UuXHJcbiAgICAgKiBAY29uc3RydWN0b3JcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIFRoZSBkZXRhaWwgbWVzc2FnZS5cclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IobWVzc2FnZSkge1xyXG4gICAgICAgIHN1cGVyKG1lc3NhZ2UpO1xyXG4gICAgfVxyXG59XHJcblxyXG4vKipcclxuICogRXJyb3IgdGhyb3duIGJ5IHRoZSBSYW5kb21PcmdDbGllbnQgY2xhc3Mgd2hlbiB0aGUgc2VydmVyIHJldHVybnMgYSBKU09OLVJQQ1xyXG4gKiBFcnJvci4gU2VlIGh0dHBzOi8vYXBpLnJhbmRvbS5vcmcvanNvbi1ycGMvNC9lcnJvci1jb2Rlc1xyXG4gKi9cclxuZXhwb3J0cy5SYW5kb21PcmdKU09OUlBDRXJyb3IgPSBjbGFzcyBSYW5kb21PcmdKU09OUlBDRXJyb3IgZXh0ZW5kcyBFcnJvclxyXG57XHJcbiAgICAvKipcclxuICAgICAqIENvbnN0cnVjdHMgYSBuZXcgZXhjZXB0aW9uIHdpdGggdGhlIHNwZWNpZmllZCBkZXRhaWwgbWVzc2FnZS5cclxuICAgICAqIEBjb25zdHJ1Y3RvclxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2UgVGhlIGRldGFpbCBtZXNzYWdlLlxyXG4gICAgICovXHJcbiAgICBjb25zdHJ1Y3RvcihtZXNzYWdlKSB7XHJcbiAgICAgICAgc3VwZXIobWVzc2FnZSk7XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBFcnJvciB0aHJvd24gYnkgdGhlIFJhbmRvbU9yZ0NsaWVudCBjbGFzcyB3aGVuIGl0cyBBUEkga2V5IGhhcyBiZWVuIHN0b3BwZWQuXHJcbiAqIFJlcXVlc3RzIHdpbGwgbm90IGNvbXBsZXRlIHdoaWxlIEFQSSBrZXkgaXMgaW4gdGhlIHN0b3BwZWQgc3RhdGUuXHJcbiAqL1xyXG5leHBvcnRzLlJhbmRvbU9yZ0tleU5vdFJ1bm5pbmdFcnJvciA9IGNsYXNzIFJhbmRvbU9yZ0tleU5vdFJ1bm5pbmdFcnJvciBleHRlbmRzIEVycm9yXHJcbntcclxuICAgIC8qKlxyXG4gICAgICogRXJyb3IgdGhyb3duIGJ5IHRoZSBSYW5kb21PcmdDbGllbnQgY2xhc3Mgd2hlbiBpdHMgQVBJIGtleSBoYXMgYmVlbiBzdG9wcGVkLlxyXG4gICAgICogUmVxdWVzdHMgd2lsbCBub3QgY29tcGxldGUgd2hpbGUgQVBJIGtleSBpcyBpbiB0aGUgc3RvcHBlZCBzdGF0ZS5cclxuICAgICAqIEBjb25zdHJ1Y3RvclxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2UgVGhlIGRldGFpbCBtZXNzYWdlLlxyXG4gICAgICovXHJcbiAgICBjb25zdHJ1Y3RvcihtZXNzYWdlKSB7XHJcbiAgICAgICAgc3VwZXIobWVzc2FnZSk7XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBFcnJvciB0aHJvd24gYnkgdGhlIFJhbmRvbU9yZ0NsaWVudCBjbGFzcyB3aGVuIHRoZSBzZXJ2ZXIgcmV0dXJucyBhXHJcbiAqIFJBTkRPTS5PUkcgRXJyb3IuIFNlZSBodHRwczovL2FwaS5yYW5kb20ub3JnL2pzb24tcnBjLzQvZXJyb3ItY29kZXNcclxuICovXHJcbmV4cG9ydHMuUmFuZG9tT3JnUkFORE9NT1JHRXJyb3IgPSBjbGFzcyBSYW5kb21PcmdSQU5ET01PUkdFcnJvciBleHRlbmRzIEVycm9yXHJcbntcclxuICAgIC8vIFN0b3JlcyB0aGUgY29kZSBvZiB0aGUgUkFORE9NLk9SRyBlcnJvclxyXG4gICAgI2NvZGUgPSAtMTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEVycm9yIHRocm93biBieSB0aGUgUmFuZG9tT3JnQ2xpZW50IGNsYXNzIHdoZW4gdGhlIHNlcnZlciByZXR1cm5zIGFcclxuICAgICAqIFJBTkRPTS5PUkcgRXJyb3IuIFNlZSBodHRwczovL2FwaS5yYW5kb20ub3JnL2pzb24tcnBjLzQvZXJyb3ItY29kZXNcclxuICAgICAqIEBjb25zdHJ1Y3RvclxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2UgVGhlIGRldGFpbCBtZXNzYWdlLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXI9fSBbY29kZT0tMV0gVGhlIGVycm9yIGNvZGUuXHJcbiAgICAgKi9cclxuICAgIGNvbnN0cnVjdG9yKG1lc3NhZ2UsIGNvZGUgPSAtMSkge1xyXG4gICAgICAgIHN1cGVyKG1lc3NhZ2UpOyAgICBcclxuICAgICAgICB0aGlzLiNjb2RlID0gY29kZTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHMgdGhlIFJBTkRPTS5PUkcgZXJyb3IgY29kZSwgc2VlXHJcbiAgICAgKiBodHRwczovL2FwaS5yYW5kb20ub3JnL2pzb24tcnBjLzQvZXJyb3ItY29kZXNcclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IFRoZSBlcnJvciBjb2RlLlxyXG4gICAgICovXHJcbiAgICBnZXRDb2RlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLiNjb2RlO1xyXG4gICAgfVxyXG59XHJcblxyXG4vKipcclxuICogRXJyb3IgdGhyb3duIGJ5IHRoZSBSYW5kb21PcmdDbGllbnQgY2xhc3Mgd2hlbiBpdHMgc2V0IGJsb2NraW5nIHRpbWVvdXQgaXNcclxuICogZXhjZWVkZWQgYmVmb3JlIHRoZSByZXF1ZXN0IGNhbiBiZSBzZW50LlxyXG4gKi9cclxuZXhwb3J0cy5SYW5kb21PcmdTZW5kVGltZW91dEVycm9yID0gY2xhc3MgUmFuZG9tT3JnU2VuZFRpbWVvdXRFcnJvciBleHRlbmRzIEVycm9yXHJcbntcclxuICAgIC8qKlxyXG4gICAgICogRXJyb3IgdGhyb3duIGJ5IHRoZSBSYW5kb21PcmdDbGllbnQgY2xhc3Mgd2hlbiBpdHMgc2V0IGJsb2NraW5nIHRpbWVvdXQgaXNcclxuICAgICAqIGV4Y2VlZGVkIGJlZm9yZSB0aGUgcmVxdWVzdCBjYW4gYmUgc2VudC5cclxuICAgICAqIEBjb25zdHJ1Y3RvclxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2UgVGhlIGRldGFpbCBtZXNzYWdlLlxyXG4gICAgICovXHJcbiAgICBjb25zdHJ1Y3RvcihtZXNzYWdlKSB7XHJcbiAgICAgICAgc3VwZXIobWVzc2FnZSk7XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBFcnJvciB0aHJvd24gd2hlbiBkYXRhIHJldHJpZXZhbCBmcm9tIGFuIGVtdHB5IFJhbmRvbU9yZ0NhY2hlIGlzIGF0dGVtcHRlZC5cclxuICovXHJcbmV4cG9ydHMuUmFuZG9tT3JnQ2FjaGVFbXB0eUVycm9yID0gY2xhc3MgUmFuZG9tT3JnQ2FjaGVFbXB0eUVycm9yIGV4dGVuZHMgRXJyb3Jcclxue1xyXG4gICAgI3BhdXNlZCA9IGZhbHNlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRXJyb3IgdGhyb3duIHdoZW4gZGF0YSByZXRyaWV2YWwgZnJvbSBhbiBlbXRweSBSYW5kb21PcmdDYWNoZSBpcyBhdHRlbXB0ZWQuXHJcbiAgICAgKiBAY29uc3RydWN0b3JcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIFRoZSBkZXRhaWwgbWVzc2FnZS5cclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gcGF1c2VkIFJlZmxlY3RzIHdoZXRoZXIgdGhlIFJhbmRvbU9yZ0NhY2hlIGluc3RhbmNlIHdhc1xyXG4gICAgICogICAgIHBhdXNlZCB3aGVuIHRoaXMgZXJyb3Igd2FzIHRocm93bi5cclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IobWVzc2FnZSwgcGF1c2VkID0gZmFsc2UpIHtcclxuICAgICAgICBzdXBlcihtZXNzYWdlKTtcclxuICAgICAgICB0aGlzLiNwYXVzZWQgPSBwYXVzZWQ7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHdoZXRoZXIgdGhlIGNhY2hlIHdhcyBwYXVzZWQgYXQgdGhlIHRpbWUgd2hlbiB0aGVcclxuICAgICAqIGVycm9yIHdhcyB0aHJvd24uXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiBwYXVzZWQsIGZhbHNlIG90aGVyd2lzZS5cclxuICAgICAqL1xyXG4gICAgd2FzUGF1c2VkKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLiNwYXVzZWQ7XHJcbiAgICB9XHJcbn0iLCIndXNlIHN0cmljdCc7XHJcbmNvbnN0IHtcclxuICAgIFJhbmRvbU9yZ0luc3VmZmljaWVudEJpdHNFcnJvcixcclxuICAgIFJhbmRvbU9yZ0NhY2hlRW1wdHlFcnJvclxyXG59ID0gcmVxdWlyZSgnLi9SYW5kb21PcmdFcnJvcnMuanMnKTtcclxuLyoqXHJcbiAqIFByZWNhY2hlIGNsYXNzIGZvciBmcmVxdWVudGx5IHVzZWQgcmVxdWVzdHMuXHJcbiAqL1xyXG5tb2R1bGUuZXhwb3J0cyA9IGNsYXNzIFJhbmRvbU9yZ0NhY2hlIHtcclxuICAgIC8vIGZ1bmN0aW9uIHVzZWQgdG8gc2VuZCBhIHJlcXVlc3RcclxuICAgICNyZXF1ZXN0RnVuY3Rpb24gPSBudWxsO1xyXG5cclxuICAgIC8vIHJlcXVlc3QgdG8gYmUgc2VudFxyXG4gICAgI3JlcXVlc3QgPSBudWxsO1xyXG5cclxuICAgIC8vIG4gZm9yIGJ1bGsgcmVxdWVzdHNcclxuICAgICNidWxrUmVxdWVzdE51bWJlciA9IDA7XHJcbiAgICAvLyBuIGZvciBhIHNpbmdsZSByZXF1ZXN0XHJcbiAgICAjcmVxdWVzdE51bWJlciA9IDA7XHJcbiAgICAvLyBzaXplIG9mIGEgc2luZ2xlIHJlcXVlc3QgaW4gYml0c1xyXG4gICAgI3JlcXVlc3RTaXplID0gLTE7XHJcblxyXG4gICAgLy8gc3RvcmVzIGNhY2hlZCBhcnJheXMgb2YgdmFsdWVzXHJcbiAgICAjc3RhY2sgPSBbXTtcclxuICAgIC8vIG51bWJlciBvZiBhcnJheXMgdG8gdHJ5IHRvIG1haW50YWluIGluICNzdGFja1xyXG4gICAgI2NhY2hlU2l6ZSA9IDEwO1xyXG5cclxuICAgIC8vIHN0YXR1cyBvZiB0aGUgY2FjaGVcclxuICAgICNwYXVzZWQgPSBmYWxzZTtcclxuICAgIC8vIGJpdHMgdXNlZCBieSB0aGlzIGNhY2hlXHJcbiAgICAjYml0c1VzZWQgPSAwO1xyXG4gICAgLy8gcmVxdWVzdHMgdXNlZCBieSB0aGlzIGNhY2hlXHJcbiAgICAjcmVxdWVzdHNVc2VkID0gMDtcclxuICAgIC8vIGVuc3VyZXMgI3BvcHVsYXRlKCkgZG9lcyBub3QgaXNzdWUgcGFyYWxsZWwgcmVxdWVzdHNcclxuICAgICNjdXJyZW50bHlQb3B1bGF0aW5nID0gZmFsc2U7XHJcblxyXG4gICAgLy8gYW4gZXJyb3Igd2hpY2ggd2lsbCBiZSB0aHJvd24gb24gdGhlIG5leHQgY2FsbCB0byBnZXQoKSBvciBnZXRPcldhaXQoKVxyXG4gICAgI2Vycm9yID0gbnVsbDtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEluaXRpYWxpemUgY2xhc3MgYW5kIHN0YXJ0IHN0YWNrIHBvcHVsYXRpb25cclxuICAgICAqIFxyXG4gICAgICogKiogV0FSTklORyoqIFNob3VsZCBvbmx5IGJlIGNhbGxlZCBieSBSYW5kb21PcmdDbGllbnQncyBjcmVhdGVDYWNoZSgpXHJcbiAgICAgKiBtZXRob2RzLlxyXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbihPYmplY3QpIDogT2JqZWN0fSByZXF1ZXN0RnVuY3Rpb24gRnVuY3Rpb24gdXNlZCB0byBzZW5kXHJcbiAgICAgKiAgICAgc3VwcGxpZWQgcmVxdWVzdCB0byBzZXJ2ZXIuXHJcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gcmVxdWVzdCBSZXF1ZXN0IHRvIHNlbmQgdG8gc2VydmVyIHZpYSByZXF1ZXN0RnVuY3Rpb24uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gY2FjaGVTaXplIE51bWJlciBvZiByZXF1ZXN0IHJlc3BvbnNlcyB0byB0cnkgbWFpbnRhaW4uXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gYnVsa1JlcXVlc3ROdW1iZXIgSWYgcmVxdWVzdCBpcyBzZXQgdG8gYmUgaXNzdWVkIGluIGJ1bGssXHJcbiAgICAgKiAgICAgbnVtYmVyIG9mIHJlc3VsdCBzZXRzIGluIGEgYnVsayByZXF1ZXN0LCBlbHNlIDAuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gcmVxdWVzdE51bWJlciBJZiByZXF1ZXN0IGlzIHNldCB0byBiZSBpc3N1ZWQgaW4gYnVsayxcclxuICAgICAqICAgICBudW1iZXIgb2YgcmVzdWx0cyBpbiBhIHNpbmdsZSByZXF1ZXN0LCBlbHNlIDAuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gc2luZ2xlUmVxdWVzdFNpemUgU2l6ZSBvZiBhIHNpbmdsZSByZXF1ZXN0IGluIGJpdHMgZm9yXHJcbiAgICAgKiAgICAgYWRqdXN0aW5nIGJ1bGsgcmVxdWVzdHMgaWYgYml0cyBhcmUgaW4gc2hvcnQgc3VwcGx5IG9uIHRoZSBzZXJ2ZXIuXHJcbiAgICAgKi9cclxuICAgIGNvbnN0cnVjdG9yKHJlcXVlc3RGdW5jdGlvbiwgcmVxdWVzdCwgY2FjaGVTaXplLCBidWxrUmVxdWVzdE51bWJlciwgcmVxdWVzdE51bWJlciwgc2luZ2xlUmVxdWVzdFNpemUpIHtcclxuICAgICAgICB0aGlzLiNyZXF1ZXN0RnVuY3Rpb24gPSByZXF1ZXN0RnVuY3Rpb247XHJcblxyXG4gICAgICAgIHRoaXMuI3JlcXVlc3QgPSByZXF1ZXN0O1xyXG4gICAgICAgIFxyXG4gICAgICAgIHRoaXMuI2NhY2hlU2l6ZSA9IGNhY2hlU2l6ZTtcclxuXHJcbiAgICAgICAgdGhpcy4jYnVsa1JlcXVlc3ROdW1iZXIgPSBidWxrUmVxdWVzdE51bWJlcjtcclxuICAgICAgICB0aGlzLiNyZXF1ZXN0TnVtYmVyID0gcmVxdWVzdE51bWJlcjtcclxuICAgICAgICB0aGlzLiNyZXF1ZXN0U2l6ZSA9IHNpbmdsZVJlcXVlc3RTaXplO1xyXG5cclxuICAgICAgICB0aGlzLiNwb3B1bGF0ZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRnVuY3Rpb24gdG8gY29udGludWUgaXNzdWluZyByZXF1ZXN0cyB1bnRpbCB0aGUgc3RhY2sgaXMgZnVsbC5cclxuICAgICAqIFxyXG4gICAgICogS2VlcCBpc3N1aW5nIHJlcXVlc3RzIHRvIHNlcnZlciB1bnRpbCBzdGFjayBpcyBmdWxsLiBXaGVuIHN0YWNrIGlzIGZ1bGxcclxuICAgICAqIGlmIHJlcXVlc3RzIGFyZSBiZWluZyBpc3N1ZWQgaW4gYnVsaywgd2FpdCB1bnRpbCBzdGFjayBoYXMgZW5vdWdoIHNwYWNlXHJcbiAgICAgKiB0byBhY2NvbW1vZGF0ZSBhbGwgb2YgYSBidWxrIHJlcXVlc3QgYmVmb3JlIGlzc3VpbmcgYSBuZXcgcmVxdWVzdCwgb3RoZXJ3aXNlXHJcbiAgICAgKiBpc3N1ZSBhIG5ldyByZXF1ZXN0IGV2ZXJ5IHRpbWUgYW4gaXRlbSBpbiB0aGUgc3RhY2sgaGFzIGJlZW4gY29uc3VtZWQuIE5vdGVcclxuICAgICAqIHRoYXQgcmVxdWVzdHMgYXJlIGJsb2NraW5nICgnYXdhaXQnIGlzIHVzZWQgd2hlbiBjYWxsaW5nIHRoZSByZXF1ZXN0RnVuY3Rpb24pLFxyXG4gICAgICogaS5lLiwgb25seSBvbmUgcmVxdWVzdCB3aWxsIGJlIGlzc3VlZCBieSB0aGUgY2FjaGUgYXQgYW55IGdpdmVuIHRpbWUuXHJcbiAgICAgKi9cclxuICAgICNwb3B1bGF0ZSA9IGFzeW5jICgpID0+IHtcclxuICAgICAgICBpZiAoIXRoaXMuI2N1cnJlbnRseVBvcHVsYXRpbmcgJiYgIXRoaXMuI3BhdXNlZCkge1xyXG4gICAgICAgICAgICB0aGlzLiNjdXJyZW50bHlQb3B1bGF0aW5nID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgIGxldCByZXNwb25zZSA9IG51bGw7XHJcblxyXG4gICAgICAgICAgICB3aGlsZSAodHJ1ZSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuI2Vycm9yICE9IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLiNidWxrUmVxdWVzdE51bWJlciA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBJcyB0aGVyZSBzcGFjZSBmb3IgYSBidWxrIHJlc3BvbnNlIGluIHRoZSBzdGFjaz9cclxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy4jc3RhY2subGVuZ3RoIDw9ICh0aGlzLiNjYWNoZVNpemUgLSB0aGlzLiNidWxrUmVxdWVzdE51bWJlcikpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlID0gYXdhaXQgdGhpcy4jcmVxdWVzdEZ1bmN0aW9uKHRoaXMuI3JlcXVlc3QpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4jYWRkUmVzcG9uc2UocmVzcG9uc2UsIHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBub3QgZW5vdWdoIGJpdHMgcmVtYWluaW5nIGZvciBhIGJ1bGsgcmVxdWVzdFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGUgaW5zdGFuY2VvZiBSYW5kb21PcmdJbnN1ZmZpY2llbnRCaXRzRXJyb3IpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgYml0c0xlZnQgPSBlLmdldEJpdHNMZWZ0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJpdHNMZWZ0ID4gdGhpcy4jcmVxdWVzdFNpemUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgcG9zc2libGUsIGFkanVzdCByZXF1ZXN0IGZvciB0aGUgbGFyZ2VzdCBwb3NzaWJsZSBzaXplXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBhZGp1c3RlZEJ1bGsgPSBNYXRoLmZsb29yKGJpdHNMZWZ0L3RoaXMuI3JlcXVlc3RTaXplKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4jcmVxdWVzdC5wYXJhbXMubiA9IGFkanVzdGVkQnVsayAqIHRoaXMuI3JlcXVlc3ROdW1iZXI7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZSA9IGF3YWl0IHRoaXMuI3JlcXVlc3RGdW5jdGlvbih0aGlzLiNyZXF1ZXN0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4jYWRkUmVzcG9uc2UocmVzcG9uc2UsIHRydWUpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmVzZXQgdG8gb3JpZ2luYWwgYnVsayByZXF1ZXN0IHNpemVcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4jcmVxdWVzdC5wYXJhbXMubiA9IHRoaXMuI2J1bGtSZXF1ZXN0TnVtYmVyICogdGhpcy4jcmVxdWVzdE51bWJlcjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyByZXF1ZXN0IHNpemUgY2Fubm90IGJlIGFkanVzdGVkXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuI2Vycm9yID0gZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQW55IG90aGVyIGVycm9yIHRocm93biBkdXJpbmcgaW4gdGhlIHJlcXVlc3QgZnVuY3Rpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiNlcnJvciA9IGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBubyBzcGFjZSBmb3IgYSBidWxrIHJlcXVlc3RcclxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLiNzdGFjay5sZW5ndGggPCB0aGlzLiNjYWNoZVNpemUpIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBpbmRpdmlkdWFsIHJlcXVlc3RzXHJcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLiNyZXF1ZXN0RnVuY3Rpb24odGhpcy4jcmVxdWVzdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuI2FkZFJlc3BvbnNlKHJlc3BvbnNlLCBmYWxzZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaChlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuI2Vycm9yID0gZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIHRoZSBzdGFjayBpcyBmdWxsXHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0gICAgICAgICAgICAgICBcclxuXHJcbiAgICAgICAgICAgIHRoaXMuI2N1cnJlbnRseVBvcHVsYXRpbmcgPSBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgY2FjaGUgd2lsbCBubyBsb25nZXIgY29udGludWUgdG8gcG9wdWxhdGUgaXRzZWxmLlxyXG4gICAgICovXHJcbiAgICBzdG9wKCkge1xyXG4gICAgICAgIHRoaXMuI3BhdXNlZCA9IHRydWU7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgY2FjaGUgd2lsbCByZXN1bWUgcG9wdWxhdGluZyBpdHNlbGYgaWYgc3RvcHBlZC5cclxuICAgICAqL1xyXG4gICAgcmVzdW1lKCkge1xyXG4gICAgICAgIHRoaXMuI3BhdXNlZCA9IGZhbHNlO1xyXG5cclxuICAgICAgICAvLyBjaGVjayBpZiBpdCBuZWVkcyB0byBiZSByZXBvcHVsYXRlZFxyXG4gICAgICAgIHRoaXMuI3JlZnJlc2goKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENoZWNrcyBpZiB0aGUgY2FjaGUgaXMgY3VycmVudGx5IG5vdCByZS1wb3B1bGF0aW5nIGl0c2VsZi5cclxuICAgICAqIFxyXG4gICAgICogVmFsdWVzIGN1cnJlbnRseSBjYWNoZWQgbWF5IHN0aWxsIGJlIHJldHJpZXZlZCB3aXRoIGdldCgpIGJ1dCBubyBuZXdcclxuICAgICAqIHZhbHVlcyBhcmUgYmVpbmcgZmV0Y2hlZCBmcm9tIHRoZSBzZXJ2ZXIuIFRoaXMgc3RhdGUgY2FuIGJlIGNoYW5nZWQgd2l0aFxyXG4gICAgICogc3RvcCgpIGFuZCByZXN1bWUoKS5cclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIGNhY2hlIGlzIGN1cnJlbnRseSBub3QgcmUtcG9wdWxhdGluZyBpdHNlbGYsXHJcbiAgICAgKiAgICAgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gICAgICovXHJcbiAgICBpc1BhdXNlZCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy4jcGF1c2VkO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgbmV4dCByZXNwb25zZS5cclxuICAgICAqIE5vdGUgdGhhdCBpZiB0aGUgY2FjaGUgaXMgZW1wdHksIGlmIHdhcyBjb25zdHJ1Y3RlZCB3aXRoIHVuc3VpdGFibGUgcGFyYW1ldGVyXHJcbiAgICAgKiB2YWx1ZXMgb3IgaWYgdGhlIGRhaWx5IGFsbG93YW5jZSBvZiBiaXRzL3JlcXVlc3RzIGhhcyBiZWVuIHJlYWNoZWQsIHRoZSBhcHByb3ByaWF0ZVxyXG4gICAgICogZXJyb3Igd2lsbCBiZSB0aHJvd24uXHJcbiAgICAgKiBAcmV0dXJucyB7YW55W119IFRoZSBuZXh0IGFwcHJvcHJpYXRlIHJlc3BvbnNlIGZvciB0aGUgcmVxdWVzdCB0aGlzIFJhbmRvbU9yZ0NhY2hlXHJcbiAgICAgKiAgICAgcmVwcmVzZW50cyBvciwgaWYgc3RhY2sgaXMgZW1wdHkgdGhyb3dzIGFuIGVycm9yLlxyXG4gICAgICogQHRocm93cyBSYW5kb21PcmdDYWNoZUVtcHR5RXJyb3IgaWYgdGhlIGNhY2hlIGlzIGVtcHR5LlxyXG4gICAgICovXHJcbiAgICBnZXQoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuI2Vycm9yICE9IG51bGwpIHtcclxuICAgICAgICAgICAgdGhyb3cgdGhpcy4jZXJyb3I7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLiNzdGFjayAmJiB0aGlzLiNzdGFjay5sZW5ndGggPT0gMCkge1xyXG4gICAgICAgICAgICBpZiAodGhpcy4jcGF1c2VkKSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmFuZG9tT3JnQ2FjaGVFbXB0eUVycm9yKCdUaGUgUmFuZG9tT3JnQ2FjaGUgc3RhY2sgJ1xyXG4gICAgICAgICAgICAgICAgICAgICsgJ2lzIGVtcHR5IGFuZCB0aGUgY2FjaGUgaXMgcGF1c2VkLiBQbGVhc2UgY2FsbCByZXN1bWUoKSB0byAnXHJcbiAgICAgICAgICAgICAgICAgICAgKyAncmVzdGFydCBwb3B1bGF0aW5nIHRoZSBjYWNoZS4nLCB0cnVlKTsgICAgICAgICAgICBcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBSYW5kb21PcmdDYWNoZUVtcHR5RXJyb3IoJ1RoZSBSYW5kb21PcmdDYWNoZSBzdGFjayAnXHJcbiAgICAgICAgICAgICAgICAgICAgKyAnaXMgZW1wdHksIHBsZWFzZSB3YWl0IGZvciBpdCB0byByZXBvcHVsYXRlIGl0c2VsZi4nKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGxldCBkYXRhID0gdGhpcy4jc3RhY2sucG9wKCk7XHJcblxyXG4gICAgICAgICAgICAvLyBjaGVjayBpZiBpdCBuZWVkcyB0byBiZSByZXBvcHVsYXRlZFxyXG4gICAgICAgICAgICB0aGlzLiNyZWZyZXNoKCk7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gZGF0YTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXQgbmV4dCByZXNwb25zZSBvciB3YWl0IHVudGlsIHRoZSBuZXh0IHZhbHVlIGlzIGF2YWlsYWJsZS4gVGhpcyBtZXRob2RcclxuICAgICAqIHdpbGwgYmxvY2sgdW50aWwgYSB2YWx1ZSBpcyBhdmFpbGFibGUuIE5vdGU6IHRoaXMgbWV0aG9kIHdpbGwgdGhyb3cgYW4gZXJyb3JcclxuICAgICAqIGlmIHRoZSBjYWNoZSBpcyBlbXB0eSBhbmQgaGFzIGJlZW4gcGF1c2VkLCBpLmUuIGlzIG5vdCBiZWluZyBwb3B1bGF0ZWQuIElmXHJcbiAgICAgKiB0aGUgY2FjaGUgd2FzIGNvbnN0cnVjdGVkIHdpdGggdW5zdWl0YWJsZSBwYXJhbWV0ZXIgdmFsdWVzIG9yIHRoZSBkYWlseSBhbGxvd2FuY2VcclxuICAgICAqIG9mIGJpdHMvcmVxdWVzdHMgaGFzIGJlZW4gcmVhY2hlZCwgdGhlIGFwcHJvcHJpYXRlIGVycm9yIHdpbGwgYWxzbyBiZSB0aHJvd24uXHJcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTxhbnlbXT59IFRoZSBuZXh0IGFwcHJvcHJpYXRlIHJlc3BvbnNlIGZvciB0aGUgcmVxdWVzdCB0aGlzXHJcbiAgICAgKiBSYW5kb21PcmdDYWNoZSByZXByZXNlbnRzLlxyXG4gICAgICogQHRocm93cyBSYW5kb21PcmdDYWNoZUVtcHR5RXJyb3IgaWYgdGhlIGNhY2hlIGlzIGVtcHR5IGFuZCBpcyBwYXVzZWQuXHJcbiAgICAgKi9cclxuICAgIGFzeW5jIGdldE9yV2FpdCgpIHtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBsZXQgdmFsdWVzID0gdGhpcy5nZXQoKTtcclxuICAgICAgICAgICAgcmV0dXJuIHZhbHVlcztcclxuICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgIGlmIChlIGluc3RhbmNlb2YgUmFuZG9tT3JnQ2FjaGVFbXB0eUVycm9yKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy4jcGF1c2VkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gVGhlIGNhY2hlIGlzIHBhdXNlZCBhbmQgd2lsbCBub3QgcmV0dXJuIGFueSB2YWx1ZXNcclxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgbGV0IGNhY2hlZFZhbHVlcyA9IGF3YWl0IHRoaXMuI3BvcHVsYXRlKCk7XHJcbiAgICAgICAgICAgICAgICBpZiAoY2FjaGVkVmFsdWVzID09IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBUaGUgY2FjaGUgaGFzIG5vdCB5ZXQgcmVwb3B1bGF0ZWQuXHJcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgbmV3IFByb21pc2UociA9PiBzZXRUaW1lb3V0KHIsIDUwKSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRPcldhaXQoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHMgdGhlIG51bWJlciBvZiByZXN1bHQgc2V0cyByZW1haW5pbmcgaW4gdGhlIGNhY2hlLlxyXG4gICAgICogXHJcbiAgICAgKiBUaGlzIGVzc2VudGlhbGx5IHJldHVybnMgaG93IG9mdGVuIGdldCgpIG1heSBiZSBjYWxsZWQgd2l0aG91dFxyXG4gICAgICogYSBjYWNoZSByZWZpbGwuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBDdXJyZW50IG51bWJlciBvZiBjYWNoZWQgcmVzdWx0cy5cclxuICAgICAqL1xyXG4gICAgZ2V0Q2FjaGVkVmFsdWVzKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLiNzdGFjay5sZW5ndGg7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSBudW1iZXIgb2YgYml0cyB1c2VkIGJ5IHRoaXMgY2FjaGUuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBOdW1iZXIgb2YgYml0cyB1c2VkLlxyXG4gICAgICovXHJcbiAgICBnZXRCaXRzVXNlZCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy4jYml0c1VzZWQ7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIG51bWJlciBvZiByZXF1ZXN0cyB1c2VkIGJ5IHRoaXMgY2FjaGUuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBOdW1iZXIgb2YgcmVxdWVzdHMgdXNlZC5cclxuICAgICAqL1xyXG4gICAgZ2V0UmVxdWVzdHNVc2VkKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLiNyZXF1ZXN0c1VzZWQ7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBIZWxwZXIgZnVuY3Rpb24gdG8gY2hlY2sgaWYgdGhlIGNhY2hlIG5lZWRzIHRvIGJlIHJlcG9wdWxhdGVkLlxyXG4gICAgICovXHJcbiAgICAjcmVmcmVzaCA9ICgpID0+IHtcclxuICAgICAgICBpZiAodGhpcy4jYnVsa1JlcXVlc3ROdW1iZXIgPiAwICYmIHRoaXMuI3N0YWNrLmxlbmd0aCA8PSAodGhpcy4jY2FjaGVTaXplIC0gdGhpcy4jYnVsa1JlcXVlc3ROdW1iZXIpKSB7XHJcbiAgICAgICAgICAgIC8vIGJ1bGsgcmVxdWVzdHNcclxuICAgICAgICAgICAgdGhpcy4jcG9wdWxhdGUoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAodGhpcy4jYnVsa1JlcXVlc3ROdW1iZXIgPD0gMCAmJiB0aGlzLiNzdGFjay5sZW5ndGggPCB0aGlzLiNjYWNoZVNpemUpIHtcclxuICAgICAgICAgICAgLy8gaW5kaXZpZHVhbCByZXF1ZXN0c1xyXG4gICAgICAgICAgICB0aGlzLiNwb3B1bGF0ZSgpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEhlbHBlciBmdW5jdGlvbiB0byBhZGQgYSByZXNwb25zZSB0byB0aGUgc3RhY2suXHJcbiAgICAgKiBAcGFyYW0ge2FueVtdfSByZXNwb25zZSBUaGUgcmVzcG9uc2UgcmVjZWl2ZWQgZnJvbSB0aGUgc2VydmVyLlxyXG4gICAgICogQHBhcmFtIHtib29sZWFufSBidWxrIFRydWUgaWYgdGhlIGNhY2hlIGlzc3VlcyBidWxrIHJlcXVlc3RzLCBmYWxzZSBvdGhlcndpc2UuXHJcbiAgICAgKi9cclxuICAgICNhZGRSZXNwb25zZSA9IChyZXNwb25zZSwgYnVsaykgPT4ge1xyXG4gICAgICAgIHRoaXMuI3JlcXVlc3RzVXNlZCsrO1xyXG4gICAgICAgIHRoaXMuI2JpdHNVc2VkICs9IHJlc3BvbnNlLnJlc3VsdC5iaXRzVXNlZDtcclxuXHJcbiAgICAgICAgaWYgKGJ1bGspIHtcclxuICAgICAgICAgICAgbGV0IGRhdGEgPSByZXNwb25zZS5yZXN1bHQucmFuZG9tLmRhdGE7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7IGkgKz0gdGhpcy4jcmVxdWVzdE51bWJlcikge1xyXG4gICAgICAgICAgICAgICAgdGhpcy4jc3RhY2sucHVzaChkYXRhLnNsaWNlKGksIGkgKyB0aGlzLiNyZXF1ZXN0TnVtYmVyKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLiNzdGFjay5wdXNoKHJlc3BvbnNlLnJlc3VsdC5yYW5kb20uZGF0YSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59IiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxuY29uc3Qge1xyXG4gICAgUmFuZG9tT3JnQmFkSFRUUFJlc3BvbnNlRXJyb3IsXHJcbiAgICBSYW5kb21PcmdJbnN1ZmZpY2llbnRCaXRzRXJyb3IsXHJcbiAgICBSYW5kb21PcmdJbnN1ZmZpY2llbnRSZXF1ZXN0c0Vycm9yLFxyXG4gICAgUmFuZG9tT3JnSlNPTlJQQ0Vycm9yLFxyXG4gICAgUmFuZG9tT3JnS2V5Tm90UnVubmluZ0Vycm9yLFxyXG4gICAgUmFuZG9tT3JnUkFORE9NT1JHRXJyb3IsXHJcbiAgICBSYW5kb21PcmdTZW5kVGltZW91dEVycm9yXHJcbn0gPSByZXF1aXJlKCcuL1JhbmRvbU9yZ0Vycm9ycy5qcycpO1xyXG5jb25zdCBSYW5kb21PcmdDYWNoZSA9IHJlcXVpcmUoJy4vUmFuZG9tT3JnQ2FjaGUuanMnKTtcclxuLyogbm9kZS1pbXBvcnQgKi9cclxuY29uc3QgWE1MSHR0cFJlcXVlc3QgPSByZXF1aXJlKCd4bWxodHRwcmVxdWVzdCcpLlhNTEh0dHBSZXF1ZXN0O1xyXG4vKiBlbmQtbm9kZS1pbXBvcnQgKi9cclxuXHJcbi8qKlxyXG4gKiBSYW5kb21PcmdDbGllbnQgbWFpbiBjbGFzcyB0aHJvdWdoIHdoaWNoIEFQSSBmdW5jdGlvbnMgYXJlIGFjY2Vzc2VkLlxyXG4gKiBcclxuICogVGhpcyBjbGFzcyBwcm92aWRlcyBhY2Nlc3MgdG8gYm90aCB0aGUgc2lnbmVkIGFuZCB1bnNpZ25lZCBtZXRob2RzIG9mIHRoZVxyXG4gKiBSQU5ET00uT1JHIEFQSS5cclxuICogXHJcbiAqIFRoZSBjbGFzcyBhbHNvIHByb3ZpZGVzIGFjY2VzcyB0byB0aGUgY3JlYXRpb24gb2YgYSBjb252ZW5pZW5jZSBjbGFzcywgUmFuZG9tT3JnQ2FjaGUsXHJcbiAqIGZvciBwcmVjYWNoaW5nIEFQSSByZXNwb25zZXMgd2hlbiB0aGUgcmVxdWVzdCBpcyBrbm93biBpbiBhZHZhbmNlLlxyXG4gKiBcclxuICogVGhpcyBjbGFzcyB3aWxsIG9ubHkgYWxsb3cgdGhlIGNyZWF0aW9uIG9mIG9uZSBpbnN0YW5jZSBwZXIgQVBJIGtleS4gSWYgYW5cclxuICogaW5zdGFuY2Ugb2YgdGhpcyBjbGFzcyBhbHJlYWR5IGV4aXN0cyBmb3IgYSBnaXZlbiBrZXksIHRoYXQgaW5zdGFuY2Ugd2lsbCBiZVxyXG4gKiByZXR1cm5lZCBpbnN0ZWFkIG9mIGEgbmV3IGluc3RhbmNlLlxyXG4gKiBcclxuICogVGhpcyBjbGFzcyBvYmV5cyBtb3N0IG9mIHRoZSBndWlkZWxpbmVzIHNldCBmb3J0aCBpbiBodHRwczovL2FwaS5yYW5kb20ub3JnL2pzb24tcnBjLzRcclxuICogQWxsIHJlcXVlc3RzIHJlc3BlY3QgdGhlIHNlcnZlcidzIGFkdmlzb3J5RGVsYXkgcmV0dXJuZWQgaW4gYW55IHJlc3BvbnNlcywgb3IgdXNlXHJcbiAqIERFRkFVTFRfREVMQVkgaWYgbm8gYWR2aXNvcnlEZWxheSBpcyByZXR1cm5lZC4gSWYgdGhlIHN1cHBsaWVkIEFQSSBrZXkgaXMgcGF1c2VkLCBpLmUuLFxyXG4gKiBoYXMgZXhjZWVkZWQgaXRzIGRhaWx5IGJpdC9yZXF1ZXN0IGFsbG93YW5jZSwgdGhpcyBpbXBsZW1lbnRhdGlvbiB3aWxsIGJhY2sgb2ZmIHVudGlsXHJcbiAqIG1pZG5pZ2h0IFVUQy5cclxuICovXHJcbm1vZHVsZS5leHBvcnRzID0gY2xhc3MgUmFuZG9tT3JnQ2xpZW50IHtcclxuICAgIC8vIEJhc2ljIEFQSVxyXG4gICAgc3RhdGljICNJTlRFR0VSX01FVEhPRCA9ICdnZW5lcmF0ZUludGVnZXJzJztcclxuICAgIHN0YXRpYyAjSU5URUdFUl9TRVFVRU5DRV9NRVRIT0QgPSAnZ2VuZXJhdGVJbnRlZ2VyU2VxdWVuY2VzJztcclxuICAgIHN0YXRpYyAjREVDSU1BTF9GUkFDVElPTl9NRVRIT0QgPSAnZ2VuZXJhdGVEZWNpbWFsRnJhY3Rpb25zJztcclxuICAgIHN0YXRpYyAjR0FVU1NJQU5fTUVUSE9EID0gJ2dlbmVyYXRlR2F1c3NpYW5zJztcclxuICAgIHN0YXRpYyAjU1RSSU5HX01FVEhPRCA9ICdnZW5lcmF0ZVN0cmluZ3MnO1xyXG4gICAgc3RhdGljICNVVUlEX01FVEhPRCA9ICdnZW5lcmF0ZVVVSURzJztcclxuICAgIHN0YXRpYyAjQkxPQl9NRVRIT0QgPSAnZ2VuZXJhdGVCbG9icyc7XHJcbiAgICBzdGF0aWMgI0dFVF9VU0FHRV9NRVRIT0QgPSAnZ2V0VXNhZ2UnO1xyXG5cclxuICAgIC8vIFNpZ25lZCBBUElcclxuICAgIHN0YXRpYyAjU0lHTkVEX0lOVEVHRVJfTUVUSE9EID0gJ2dlbmVyYXRlU2lnbmVkSW50ZWdlcnMnO1xyXG4gICAgc3RhdGljICNTSUdORURfSU5URUdFUl9TRVFVRU5DRV9NRVRIT0QgPSAnZ2VuZXJhdGVTaWduZWRJbnRlZ2VyU2VxdWVuY2VzJztcclxuICAgIHN0YXRpYyAjU0lHTkVEX0RFQ0lNQUxfRlJBQ1RJT05fTUVUSE9EID0gJ2dlbmVyYXRlU2lnbmVkRGVjaW1hbEZyYWN0aW9ucyc7XHJcbiAgICBzdGF0aWMgI1NJR05FRF9HQVVTU0lBTl9NRVRIT0QgPSAnZ2VuZXJhdGVTaWduZWRHYXVzc2lhbnMnO1xyXG4gICAgc3RhdGljICNTSUdORURfU1RSSU5HX01FVEhPRCA9ICdnZW5lcmF0ZVNpZ25lZFN0cmluZ3MnO1xyXG4gICAgc3RhdGljICNTSUdORURfVVVJRF9NRVRIT0QgPSAnZ2VuZXJhdGVTaWduZWRVVUlEcyc7XHJcbiAgICBzdGF0aWMgI1NJR05FRF9CTE9CX01FVEhPRCA9ICdnZW5lcmF0ZVNpZ25lZEJsb2JzJztcclxuICAgIHN0YXRpYyAjR0VUX1JFU1VMVF9NRVRIT0QgPSAnZ2V0UmVzdWx0JztcclxuICAgIHN0YXRpYyAjQ1JFQVRFX1RJQ0tFVF9NRVRIT0QgPSAnY3JlYXRlVGlja2V0cyc7XHJcbiAgICBzdGF0aWMgI0xJU1RfVElDS0VUX01FVEhPRCA9ICdsaXN0VGlja2V0cyc7XHJcbiAgICBzdGF0aWMgI0dFVF9USUNLRVRfTUVUSE9EID0gJ2dldFRpY2tldCc7XHJcbiAgICBzdGF0aWMgI1ZFUklGWV9TSUdOQVRVUkVfTUVUSE9EID0gJ3ZlcmlmeVNpZ25hdHVyZSc7XHJcblxyXG4gICAgLy8gQmxvYiBmb3JtYXQgbGl0ZXJhbHNcclxuICAgIC8qKiBCbG9iIGZvcm1hdCBsaXRlcmFsLCBiYXNlNjQgZW5jb2RpbmcgKGRlZmF1bHQpLiAqL1xyXG4gICAgc3RhdGljIEJMT0JfRk9STUFUX0JBU0U2NCA9ICdiYXNlNjQnO1xyXG4gICAgLyoqIEJsb2IgZm9ybWF0IGxpdGVyYWwsIGhleCBlbmNvZGluZy4gKi9cclxuICAgIHN0YXRpYyBCTE9CX0ZPUk1BVF9IRVggPSAnaGV4JztcclxuXHJcbiAgICAvLyBEZWZhdWx0IHZhbHVlc1xyXG4gICAgLyoqIERlZmF1bHQgdmFsdWUgZm9yIHRoZSByZXBsYWNlbWVudCBwYXJhbWV0ZXIgKHRydWUpLiAqL1xyXG4gICAgc3RhdGljIERFRkFVTFRfUkVQTEFDRU1FTlQgPSB0cnVlO1xyXG4gICAgLyoqIERlZmF1bHQgdmFsdWUgZm9yIHRoZSBiYXNlIHBhcmFtZXRlciAoMTApLiAqL1xyXG4gICAgc3RhdGljIERFRkFVTFRfQkFTRSA9IDEwO1xyXG4gICAgLyoqIERlZmF1bHQgdmFsdWUgZm9yIHRoZSB1c2VyRGF0YSBwYXJhbWV0ZXIgKG51bGwpLiAqL1xyXG4gICAgc3RhdGljIERFRkFVTFRfVVNFUl9EQVRBID0gbnVsbDtcclxuICAgIC8qKiBEZWZhdWx0IHZhbHVlIGZvciB0aGUgdGlja2V0SWQgcGFyYW1ldGVyIChudWxsKS4gKi9cclxuICAgIHN0YXRpYyBERUZBVUxUX1RJQ0tFVF9JRCA9IG51bGw7XHJcbiAgICAvKiogRGVmYXVsdCB2YWx1ZSBmb3IgdGhlIHByZWdlbmVyYXRlZFJhbmRvbWl6YXRpb24gcGFyYW1ldGVyIChudWxsKS4gKi9cclxuICAgIHN0YXRpYyBERUZBVUxUX1BSRUdFTkVSQVRFRF9SQU5ET01JWkFUSU9OID0gbnVsbDtcclxuICAgIC8qKiBEZWZhdWx0IHZhbHVlIGZvciB0aGUgbGljZW5zZURhdGEgcGFyYW1ldGVyIChudWxsKS4gKi9cclxuICAgIHN0YXRpYyBERUZBVUxUX0xJQ0VOU0VfREFUQSA9IG51bGw7XHJcblxyXG4gICAgLyoqIFNpemUgb2YgYSBzaW5nbGUgVVVJRCBpbiBiaXRzLiAqL1xyXG4gICAgc3RhdGljIFVVSURfU0laRSA9IDEyMjtcclxuICAgIC8qKiBEZWZhdWx0IHZhbHVlIGZvciB0aGUgYmxvY2tpbmdUaW1lb3V0IHBhcmFtZXRlciAoMSBkYXkpLiAqL1xyXG4gICAgc3RhdGljIERFRkFVTFRfQkxPQ0tJTkdfVElNRU9VVCA9IDI0ICogNjAgKiA2MCAqIDEwMDA7XHJcbiAgICAvKiogRGVmYXVsdCB2YWx1ZSBmb3IgdGhlIGh0dHBUaW1lb3V0IHBhcmFtZXRlciAoMiBtaW51dGVzKS4gKi9cclxuICAgIHN0YXRpYyBERUZBVUxUX0hUVFBfVElNRU9VVCA9IDEyMCAqIDEwMDA7XHJcbiAgICAvKiogTWF4aW11bSBudW1iZXIgb2YgY2hhcmFjdGVycyBhbGxvd2VkIGluIGEgc2lnbmF0dXJlIHZlcmZpY2lhdGlvbiBVUkwuICovXHJcbiAgICBzdGF0aWMgTUFYX1VSTF9MRU5HVEggPSAyMDQ2O1xyXG5cclxuICAgIC8vIERlZmF1bHQgYmFjay1vZmYgdG8gdXNlIGlmIG5vIGFkdmlzb3J5RGVsYXkgYmFjay1vZmYgc3VwcGxpZWQgYnkgc2VydmVyICgxIHNlY29uZClcclxuICAgIHN0YXRpYyAjREVGQVVMVF9ERUxBWSA9IDEqMTAwMDtcclxuXHJcbiAgICAvLyBPbiByZXF1ZXN0IGZldGNoIGZyZXNoIGFsbG93YW5jZSBzdGF0ZSBpZiBjdXJyZW50IHN0YXRlIGRhdGEgaXMgb2xkZXIgdGhhblxyXG4gICAgLy8gdGhpcyB2YWx1ZSAoMSBob3VyKS5cclxuICAgIHN0YXRpYyAjQUxMT1dBTkNFX1NUQVRFX1JFRlJFU0hfU0VDT05EUyA9IDM2MDAgKiAxMDAwO1xyXG5cclxuICAgIC8vIE1haW50YWlucyB1c2FnZSBzdGF0aXN0aWNzIGZyb20gc2VydmVyLlxyXG4gICAgI2JpdHNMZWZ0ID0gLTE7XHJcbiAgICAjcmVxdWVzdHNMZWZ0ID0gLTE7XHJcblxyXG4gICAgLy8gQmFjay1vZmYgaW5mbyBmb3Igd2hlbiB0aGUgQVBJIGtleSBpcyBkZXRlY3RlZCBhcyBub3QgcnVubmluZywgcHJvYmFibHlcclxuICAgIC8vIGJlY2F1c2UgdGhlIGtleSBoYXMgZXhjZWVkZWQgaXRzIGRhaWx5IHVzYWdlIGxpbWl0LiBCYWNrLW9mZiBydW5zIHVudGlsXHJcbiAgICAvLyBtaWRuaWdodCBVVEMuXHJcbiAgICAjYmFja29mZiA9IC0xO1xyXG4gICAgI2JhY2tvZmZFcnJvciA9ICcnO1xyXG5cclxuICAgICNhcGlLZXkgPSAnJztcclxuICAgICNibG9ja2luZ1RpbWVvdXQgPSBSYW5kb21PcmdDbGllbnQuREVGQVVMVF9CTE9DS0lOR19USU1FT1VUO1xyXG4gICAgI2h0dHBUaW1lb3V0ID0gUmFuZG9tT3JnQ2xpZW50LkRFRkFVTFRfSFRUUF9USU1FT1VUO1xyXG5cclxuICAgIC8vIE1haW50YWluIGluZm8gdG8gb2JleSBzZXJ2ZXIgYWR2aXNvcnkgZGVsYXlcclxuICAgICNhZHZpc29yeURlbGF5ID0gMDtcclxuICAgICNsYXN0UmVzcG9uc2VSZWNlaXZlZFRpbWUgPSAwO1xyXG5cclxuICAgIC8vIE1haW50YWlucyBhIGRpY3Rpb25hcnkgb2YgQVBJIGtleXMgYW5kIHRoZWlyIGluc3RhbmNlcy5cclxuICAgIHN0YXRpYyAja2V5SW5kZXhlZEluc3RhbmNlcyA9IHt9O1xyXG5cclxuICAgIHN0YXRpYyAjRVJST1JfQ09ERVMgPSBbIDEwMCwgMTAxLCAyMDAsIDIwMSwgMjAyLCAyMDMsIDIwNCwgMzAwLFxyXG4gICAgICAgIDMwMSwgMzAyLCAzMDMsIDMwNCwgMzA1LCAzMDYsIDMwNywgNDAwLCA0MDEsIDQwMiwgNDAzLCA0MDQsXHJcbiAgICAgICAgNDA1LCA0MjAsIDQyMSwgNDIyLCA0MjMsIDQyNCwgNDI1LCA1MDAsIDMyMDAwIF07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDb25zdHJ1Y3Rvci4gRW5zdXJlcyBvbmx5IG9uZSBpbnN0YW5jZSBvZiBSYW5kb21PcmdDbGllbnQgZXhpc3RzIHBlciBBUElcclxuICAgICAqIGtleS4gQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBpZiB0aGUgc3VwcGxpZWQga2V5IGlzbid0IGFscmVhZHkga25vd24sXHJcbiAgICAgKiBvdGhlcndpc2UgcmV0dXJucyB0aGUgcHJldmlvdXNseSBpbnN0YW50aWF0ZWQgb25lLlxyXG4gICAgICogQGNvbnN0cnVjdG9yXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gYXBpS2V5IEFQSSBrZXkgb2YgaW5zdGFuY2UgdG8gY3JlYXRlL2ZpbmQsIG9idGFpbmVkIGZyb21cclxuICAgICAqICAgICBSQU5ET00uT1JHLCBzZWUgaHR0cHM6Ly9hcGkucmFuZG9tLm9yZy9hcGkta2V5c1xyXG4gICAgICogQHBhcmFtIHt7YmxvY2tpbmdUaW1lb3V0PzogbnVtYmVyLCBodHRwVGltZW91dD86IG51bWJlcn19IG9wdGlvbnMgQW4gb2JqZWN0XHJcbiAgICAgKiAgICAgd2hpY2ggbWF5IGNvbnRhaW5zIGFueSBvZiB0aGUgZm9sbG93aW5nIG9wdGlvbmFsIHBhcmFtZXRlcnM6XHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdGlvbnMuYmxvY2tpbmdUaW1lb3V0ID0gMjQgKiA2MCAqIDYwICogMTAwMF0gTWF4aW11bVxyXG4gICAgICogICAgIHRpbWUgaW4gbWlsbGlzZWNvbmRzIHRvIHdhaXQgYmVmb3JlIGJlaW5nIGFsbG93ZWQgdG8gc2VuZCBhIHJlcXVlc3QuXHJcbiAgICAgKiAgICAgTm90ZSB0aGlzIGlzIGEgaGludCBub3QgYSBndWFyYW50ZWUuIFRoZSBhZHZpc29yeSBkZWxheSBmcm9tIHNlcnZlclxyXG4gICAgICogICAgIG11c3QgYWx3YXlzIGJlIG9iZXllZC4gU3VwcGx5IGEgdmFsdWUgb2YgLTEgdG8gYWxsb3cgYmxvY2tpbmcgZm9yZXZlclxyXG4gICAgICogICAgIChkZWZhdWx0IDI0ICogNjAgKiA2MCAqIDEwMDAsIGkuZS4sIDEgZGF5KS5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbb3B0aW9ucy5odHRwVGltZW91dCA9IDEyMCAqIDEwMDBdIE1heGltdW0gdGltZSBpblxyXG4gICAgICogICAgIG1pbGxpc2Vjb25kcyB0byB3YWl0IGZvciB0aGUgc2VydmVyIHJlc3BvbnNlIHRvIGEgcmVxdWVzdCAoZGVmYXVsdFxyXG4gICAgICogICAgIDEyMCoxMDAwKS5cclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IoYXBpS2V5LCBvcHRpb25zID0ge30pIHtcclxuICAgICAgICBpZiAoUmFuZG9tT3JnQ2xpZW50LiNrZXlJbmRleGVkSW5zdGFuY2VzICYmIFJhbmRvbU9yZ0NsaWVudC4ja2V5SW5kZXhlZEluc3RhbmNlc1thcGlLZXldKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBSYW5kb21PcmdDbGllbnQuI2tleUluZGV4ZWRJbnN0YW5jZXNbYXBpS2V5XTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLiNhcGlLZXkgPSBhcGlLZXk7XHJcbiAgICAgICAgICAgIHRoaXMuI2Jsb2NraW5nVGltZW91dCA9IG9wdGlvbnMuYmxvY2tpbmdUaW1lb3V0IHx8IDI0ICogNjAgKiA2MCAqIDEwMDA7XHJcbiAgICAgICAgICAgIHRoaXMuI2h0dHBUaW1lb3V0ID0gb3B0aW9ucy5odHRwVGltZW91dCB8fCAxMjAgKiAxMDAwO1xyXG5cclxuICAgICAgICAgICAgUmFuZG9tT3JnQ2xpZW50LiNrZXlJbmRleGVkSW5zdGFuY2VzW2FwaUtleV0gPSB0aGlzO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcb