UNPKG

@randomorg/core

Version:

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

2 lines 236 kB
var e={};e.RandomOrgBadHTTPResponseError=class extends Error{constructor(e){super(e)}},e.RandomOrgInsufficientBitsError=class extends Error{#bits=-1;constructor(e,t){super(e),this.#bits=t}getBitsLeft(){return this.#bits}},e.RandomOrgInsufficientRequestsError=class extends Error{constructor(e){super(e)}},e.RandomOrgJSONRPCError=class extends Error{constructor(e){super(e)}},e.RandomOrgKeyNotRunningError=class extends Error{constructor(e){super(e)}},e.RandomOrgRANDOMORGError=class extends Error{#code=-1;constructor(e,t=-1){super(e),this.#code=t}getCode(){return this.#code}},e.RandomOrgSendTimeoutError=class extends Error{constructor(e){super(e)}},e.RandomOrgCacheEmptyError=class extends Error{#paused=!1;constructor(e,t=!1){super(e),this.#paused=t}wasPaused(){return this.#paused}};const{RandomOrgInsufficientBitsError:t,RandomOrgCacheEmptyError:s}=e;var r=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(s){if(s instanceof t){let t=s.getBitsLeft();if(t>this.#requestSize){let s=Math.floor(t/this.#requestSize);this.#request.params.n=s*this.#requestNumber,e=await this.#requestFunction(this.#request),this.#addResponse(e,!0),this.#request.params.n=this.#bulkRequestNumber*this.#requestNumber}else this.#error=s}else this.#error=s}}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 s("The RandomOrgCache stack is empty and the cache is paused. Please call resume() to restart populating the cache.",!0):new s("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 s){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:a,RandomOrgInsufficientBitsError:i,RandomOrgInsufficientRequestsError:n,RandomOrgJSONRPCError:u,RandomOrgKeyNotRunningError:c,RandomOrgRANDOMORGError:o,RandomOrgSendTimeoutError:l}=e,h=r;var d=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 o("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 h(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 h(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 h(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 h(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 h(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 h(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 h(this.#sendRequest.bind(this),n,r,i,e,a)}#sendRequest=async function(t){if(-1!=this.#backoff){if(Date.now()<this.#backoff)throw new n(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 l("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 l("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 a("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 c("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 n(this.#backoffError)}throw 403==t?(this.#bitsLeft=a[1],new i("Error"+t+": "+r,this.#bitsLeft)):e.#ERROR_CODES.includes(t)?new o("Error "+t+": "+r,t):new u("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 E=e.RandomOrgRANDOMORGError,g=e.RandomOrgBadHTTPResponseError,R=e.RandomOrgInsufficientBitsError,m=e.RandomOrgInsufficientRequestsError,T=e.RandomOrgJSONRPCError,p=e.RandomOrgKeyNotRunningError,D=e.RandomOrgSendTimeoutError,S=e.RandomOrgCacheEmptyError;export{g as RandomOrgBadHTTPResponseError,r as RandomOrgCache,S as RandomOrgCacheEmptyError,d as RandomOrgClient,R as RandomOrgInsufficientBitsError,m as RandomOrgInsufficientRequestsError,T as RandomOrgJSONRPCError,p as RandomOrgKeyNotRunningError,E as RandomOrgRANDOMORGError,D as RandomOrgSendTimeoutError,d as default}; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmRvY29yZS5lcy5taW4uanMiLCJzb3VyY2VzIjpbIi4uL1JhbmRvbU9yZ0Vycm9ycy5qcyIsIi4uL1JhbmRvbU9yZ0NhY2hlLmpzIiwiLi4vUmFuZG9tT3JnQ2xpZW50LmpzIiwiLi4vZXNtL2luZGV4LmpzIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcclxuXHJcbi8qKlxyXG4gKiBFcnJvciB0aHJvd24gYnkgdGhlIFJhbmRvbU9yZ0NsaWVudCBjbGFzcyB3aGVuIHRoZSBjb25uZWN0aW9uIGRvZXNuJ3QgcmV0dXJuXHJcbiAqIGEgSFRUUCAyMDAgT0sgcmVzcG9uc2UuXHJcbiAqL1xyXG5leHBvcnRzLlJhbmRvbU9yZ0JhZEhUVFBSZXNwb25zZUVycm9yID0gY2xhc3MgUmFuZG9tT3JnQmFkSFRUUFJlc3BvbnNlRXJyb3IgZXh0ZW5kcyBFcnJvclxyXG57XHJcbiAgICAvKipcclxuICAgICAqIENvbnN0cnVjdHMgYSBuZXcgZXhjZXB0aW9uIHdpdGggdGhlIHNwZWNpZmllZCBkZXRhaWwgbWVzc2FnZS5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIFRoZSBkZXRhaWwgbWVzc2FnZS5cclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IobWVzc2FnZSkge1xyXG4gICAgICAgIHN1cGVyKG1lc3NhZ2UpO1xyXG4gICAgfVxyXG59XHJcblxyXG4vKipcclxuICogRXJyb3IgdGhyb3duIGJ5IHRoZSBSYW5kb21PcmdDbGllbnQgY2xhc3Mgd2hlbiBpdHMgQVBJIGtleSdzIHJlcXVlc3QgaGFzXHJcbiAqIGV4Y2VlZGVkIGl0cyByZW1haW5pbmcgc2VydmVyIGJpdHMgYWxsb3dhbmNlLlxyXG4gKiBcclxuICogSWYgdGhlIGNsaWVudCBpcyBjdXJyZW50bHkgaXNzdWluZyBsYXJnZSByZXF1ZXN0cyBpdCBtYXkgYmUgcG9zc2libGUgc3VjY2VlZFxyXG4gKiB3aXRoIHNtYWxsZXIgcmVxdWVzdHMuIFVzZSB0aGUgZ2V0Qml0c0xlZnQoKSBjYWxsIGluIHRoaXMgY2xhc3MgdG8gaGVscFxyXG4gKiBkZXRlcm1pbmUgaWYgYW4gYWx0ZXJuYXRpdmUgcmVxdWVzdCBzaXplIGlzIGFwcHJvcHJpYXRlLlxyXG4gKi9cclxuIGV4cG9ydHMuUmFuZG9tT3JnSW5zdWZmaWNpZW50Qml0c0Vycm9yID0gY2xhc3MgUmFuZG9tT3JnSW5zdWZmaWNpZW50Qml0c0Vycm9yIGV4dGVuZHMgRXJyb3Jcclxue1xyXG4gICAgLy8gU3RvcmVzIHRoZSBudW1iZXIgb2YgYml0cyByZW1haW5pbmdcclxuICAgICNiaXRzID0gLTE7XHJcbiAgICBcclxuICAgIC8qKlxyXG4gICAgICogQ29uc3RydWN0cyBhIG5ldyBleGNlcHRpb24gd2l0aCB0aGUgc3BlY2lmaWVkIGRldGFpbCBtZXNzYWdlLlxyXG4gICAgICogQGNvbnN0cnVjdG9yXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSBUaGUgZGV0YWlsIG1lc3NhZ2UuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gYml0cyBCaXRzIHJlbWFpbmluZyBqdXN0IGJlZm9yZSB0aGUgZXJyb3Igd2FzIHRocm93bi5cclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IobWVzc2FnZSwgYml0cykge1xyXG4gICAgICAgIHN1cGVyKG1lc3NhZ2UpO1xyXG4gICAgICAgIHRoaXMuI2JpdHMgPSBiaXRzO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgbnVtYmVyIG9mIGJpdHMgcmVtYWluaW5nLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gVGhlIG51bWJlciBvZiBiaXRzIGxlZnQuXHJcbiAgICAgKi9cclxuICAgIGdldEJpdHNMZWZ0KCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLiNiaXRzO1xyXG4gICAgfVxyXG59XHJcblxyXG4vKipcclxuICogRXJyb3IgdGhyb3duIGJ5IHRoZSBSYW5kb21PcmdDbGllbnQgY2xhc3Mgd2hlbiBpdHMgQVBJIGtleSdzIHNlcnZlciByZXF1ZXN0c1xyXG4gKiBhbGxvd2FuY2UgaGFzIGJlZW4gZXhjZWVkZWQuXHJcbiAqIFxyXG4gKiBUaGlzIGluZGljYXRlcyB0aGF0IGEgYmFjay1vZmYgdW50aWwgbWlkbmlnaHQgVVRDIGlzIGluIGVmZmVjdCwgYmVmb3JlIHdoaWNoXHJcbiAqIG5vIHJlcXVlc3RzIHdpbGwgYmUgc2VudCBieSB0aGUgY2xpZW50IGFzIG5vIG1lYW5pbmdmdWwgc2VydmVyIHJlc3BvbnNlcyB3aWxsXHJcbiAqIGJlIHJldHVybmVkLlxyXG4gKi9cclxuZXhwb3J0cy5SYW5kb21PcmdJbnN1ZmZpY2llbnRSZXF1ZXN0c0Vycm9yID0gY2xhc3MgUmFuZG9tT3JnSW5zdWZmaWNpZW50UmVxdWVzdHNFcnJvciBleHRlbmRzIEVycm9yXHJcbntcclxuICAgIC8qKlxyXG4gICAgICogQ29uc3RydWN0cyBhIG5ldyBleGNlcHRpb24gd2l0aCB0aGUgc3BlY2lmaWVkIGRldGFpbCBtZXNzYWdlLlxyXG4gICAgICogQGNvbnN0cnVjdG9yXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSBUaGUgZGV0YWlsIG1lc3NhZ2UuXHJcbiAgICAgKi9cclxuICAgIGNvbnN0cnVjdG9yKG1lc3NhZ2UpIHtcclxuICAgICAgICBzdXBlcihtZXNzYWdlKTtcclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIEVycm9yIHRocm93biBieSB0aGUgUmFuZG9tT3JnQ2xpZW50IGNsYXNzIHdoZW4gdGhlIHNlcnZlciByZXR1cm5zIGEgSlNPTi1SUENcclxuICogRXJyb3IuIFNlZSBodHRwczovL2FwaS5yYW5kb20ub3JnL2pzb24tcnBjLzQvZXJyb3ItY29kZXNcclxuICovXHJcbmV4cG9ydHMuUmFuZG9tT3JnSlNPTlJQQ0Vycm9yID0gY2xhc3MgUmFuZG9tT3JnSlNPTlJQQ0Vycm9yIGV4dGVuZHMgRXJyb3Jcclxue1xyXG4gICAgLyoqXHJcbiAgICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGV4Y2VwdGlvbiB3aXRoIHRoZSBzcGVjaWZpZWQgZGV0YWlsIG1lc3NhZ2UuXHJcbiAgICAgKiBAY29uc3RydWN0b3JcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIFRoZSBkZXRhaWwgbWVzc2FnZS5cclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IobWVzc2FnZSkge1xyXG4gICAgICAgIHN1cGVyKG1lc3NhZ2UpO1xyXG4gICAgfVxyXG59XHJcblxyXG4vKipcclxuICogRXJyb3IgdGhyb3duIGJ5IHRoZSBSYW5kb21PcmdDbGllbnQgY2xhc3Mgd2hlbiBpdHMgQVBJIGtleSBoYXMgYmVlbiBzdG9wcGVkLlxyXG4gKiBSZXF1ZXN0cyB3aWxsIG5vdCBjb21wbGV0ZSB3aGlsZSBBUEkga2V5IGlzIGluIHRoZSBzdG9wcGVkIHN0YXRlLlxyXG4gKi9cclxuZXhwb3J0cy5SYW5kb21PcmdLZXlOb3RSdW5uaW5nRXJyb3IgPSBjbGFzcyBSYW5kb21PcmdLZXlOb3RSdW5uaW5nRXJyb3IgZXh0ZW5kcyBFcnJvclxyXG57XHJcbiAgICAvKipcclxuICAgICAqIEVycm9yIHRocm93biBieSB0aGUgUmFuZG9tT3JnQ2xpZW50IGNsYXNzIHdoZW4gaXRzIEFQSSBrZXkgaGFzIGJlZW4gc3RvcHBlZC5cclxuICAgICAqIFJlcXVlc3RzIHdpbGwgbm90IGNvbXBsZXRlIHdoaWxlIEFQSSBrZXkgaXMgaW4gdGhlIHN0b3BwZWQgc3RhdGUuXHJcbiAgICAgKiBAY29uc3RydWN0b3JcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIFRoZSBkZXRhaWwgbWVzc2FnZS5cclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IobWVzc2FnZSkge1xyXG4gICAgICAgIHN1cGVyKG1lc3NhZ2UpO1xyXG4gICAgfVxyXG59XHJcblxyXG4vKipcclxuICogRXJyb3IgdGhyb3duIGJ5IHRoZSBSYW5kb21PcmdDbGllbnQgY2xhc3Mgd2hlbiB0aGUgc2VydmVyIHJldHVybnMgYVxyXG4gKiBSQU5ET00uT1JHIEVycm9yLiBTZWUgaHR0cHM6Ly9hcGkucmFuZG9tLm9yZy9qc29uLXJwYy80L2Vycm9yLWNvZGVzXHJcbiAqL1xyXG5leHBvcnRzLlJhbmRvbU9yZ1JBTkRPTU9SR0Vycm9yID0gY2xhc3MgUmFuZG9tT3JnUkFORE9NT1JHRXJyb3IgZXh0ZW5kcyBFcnJvclxyXG57XHJcbiAgICAvLyBTdG9yZXMgdGhlIGNvZGUgb2YgdGhlIFJBTkRPTS5PUkcgZXJyb3JcclxuICAgICNjb2RlID0gLTE7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBFcnJvciB0aHJvd24gYnkgdGhlIFJhbmRvbU9yZ0NsaWVudCBjbGFzcyB3aGVuIHRoZSBzZXJ2ZXIgcmV0dXJucyBhXHJcbiAgICAgKiBSQU5ET00uT1JHIEVycm9yLiBTZWUgaHR0cHM6Ly9hcGkucmFuZG9tLm9yZy9qc29uLXJwYy80L2Vycm9yLWNvZGVzXHJcbiAgICAgKiBAY29uc3RydWN0b3JcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIFRoZSBkZXRhaWwgbWVzc2FnZS5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyPX0gW2NvZGU9LTFdIFRoZSBlcnJvciBjb2RlLlxyXG4gICAgICovXHJcbiAgICBjb25zdHJ1Y3RvcihtZXNzYWdlLCBjb2RlID0gLTEpIHtcclxuICAgICAgICBzdXBlcihtZXNzYWdlKTsgICAgXHJcbiAgICAgICAgdGhpcy4jY29kZSA9IGNvZGU7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSBSQU5ET00uT1JHIGVycm9yIGNvZGUsIHNlZVxyXG4gICAgICogaHR0cHM6Ly9hcGkucmFuZG9tLm9yZy9qc29uLXJwYy80L2Vycm9yLWNvZGVzXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBUaGUgZXJyb3IgY29kZS5cclxuICAgICAqL1xyXG4gICAgZ2V0Q29kZSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy4jY29kZTtcclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIEVycm9yIHRocm93biBieSB0aGUgUmFuZG9tT3JnQ2xpZW50IGNsYXNzIHdoZW4gaXRzIHNldCBibG9ja2luZyB0aW1lb3V0IGlzXHJcbiAqIGV4Y2VlZGVkIGJlZm9yZSB0aGUgcmVxdWVzdCBjYW4gYmUgc2VudC5cclxuICovXHJcbmV4cG9ydHMuUmFuZG9tT3JnU2VuZFRpbWVvdXRFcnJvciA9IGNsYXNzIFJhbmRvbU9yZ1NlbmRUaW1lb3V0RXJyb3IgZXh0ZW5kcyBFcnJvclxyXG57XHJcbiAgICAvKipcclxuICAgICAqIEVycm9yIHRocm93biBieSB0aGUgUmFuZG9tT3JnQ2xpZW50IGNsYXNzIHdoZW4gaXRzIHNldCBibG9ja2luZyB0aW1lb3V0IGlzXHJcbiAgICAgKiBleGNlZWRlZCBiZWZvcmUgdGhlIHJlcXVlc3QgY2FuIGJlIHNlbnQuXHJcbiAgICAgKiBAY29uc3RydWN0b3JcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIFRoZSBkZXRhaWwgbWVzc2FnZS5cclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IobWVzc2FnZSkge1xyXG4gICAgICAgIHN1cGVyKG1lc3NhZ2UpO1xyXG4gICAgfVxyXG59XHJcblxyXG4vKipcclxuICogRXJyb3IgdGhyb3duIHdoZW4gZGF0YSByZXRyaWV2YWwgZnJvbSBhbiBlbXRweSBSYW5kb21PcmdDYWNoZSBpcyBhdHRlbXB0ZWQuXHJcbiAqL1xyXG5leHBvcnRzLlJhbmRvbU9yZ0NhY2hlRW1wdHlFcnJvciA9IGNsYXNzIFJhbmRvbU9yZ0NhY2hlRW1wdHlFcnJvciBleHRlbmRzIEVycm9yXHJcbntcclxuICAgICNwYXVzZWQgPSBmYWxzZTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEVycm9yIHRocm93biB3aGVuIGRhdGEgcmV0cmlldmFsIGZyb20gYW4gZW10cHkgUmFuZG9tT3JnQ2FjaGUgaXMgYXR0ZW1wdGVkLlxyXG4gICAgICogQGNvbnN0cnVjdG9yXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSBUaGUgZGV0YWlsIG1lc3NhZ2UuXHJcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IHBhdXNlZCBSZWZsZWN0cyB3aGV0aGVyIHRoZSBSYW5kb21PcmdDYWNoZSBpbnN0YW5jZSB3YXNcclxuICAgICAqICAgICBwYXVzZWQgd2hlbiB0aGlzIGVycm9yIHdhcyB0aHJvd24uXHJcbiAgICAgKi9cclxuICAgIGNvbnN0cnVjdG9yKG1lc3NhZ2UsIHBhdXNlZCA9IGZhbHNlKSB7XHJcbiAgICAgICAgc3VwZXIobWVzc2FnZSk7XHJcbiAgICAgICAgdGhpcy4jcGF1c2VkID0gcGF1c2VkO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBjYWNoZSB3YXMgcGF1c2VkIGF0IHRoZSB0aW1lIHdoZW4gdGhlXHJcbiAgICAgKiBlcnJvciB3YXMgdGhyb3duLlxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgcGF1c2VkLCBmYWxzZSBvdGhlcndpc2UuXHJcbiAgICAgKi9cclxuICAgIHdhc1BhdXNlZCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy4jcGF1c2VkO1xyXG4gICAgfVxyXG59IiwiJ3VzZSBzdHJpY3QnO1xyXG5jb25zdCB7XHJcbiAgICBSYW5kb21PcmdJbnN1ZmZpY2llbnRCaXRzRXJyb3IsXHJcbiAgICBSYW5kb21PcmdDYWNoZUVtcHR5RXJyb3JcclxufSA9IHJlcXVpcmUoJy4vUmFuZG9tT3JnRXJyb3JzLmpzJyk7XHJcbi8qKlxyXG4gKiBQcmVjYWNoZSBjbGFzcyBmb3IgZnJlcXVlbnRseSB1c2VkIHJlcXVlc3RzLlxyXG4gKi9cclxubW9kdWxlLmV4cG9ydHMgPSBjbGFzcyBSYW5kb21PcmdDYWNoZSB7XHJcbiAgICAvLyBmdW5jdGlvbiB1c2VkIHRvIHNlbmQgYSByZXF1ZXN0XHJcbiAgICAjcmVxdWVzdEZ1bmN0aW9uID0gbnVsbDtcclxuXHJcbiAgICAvLyByZXF1ZXN0IHRvIGJlIHNlbnRcclxuICAgICNyZXF1ZXN0ID0gbnVsbDtcclxuXHJcbiAgICAvLyBuIGZvciBidWxrIHJlcXVlc3RzXHJcbiAgICAjYnVsa1JlcXVlc3ROdW1iZXIgPSAwO1xyXG4gICAgLy8gbiBmb3IgYSBzaW5nbGUgcmVxdWVzdFxyXG4gICAgI3JlcXVlc3ROdW1iZXIgPSAwO1xyXG4gICAgLy8gc2l6ZSBvZiBhIHNpbmdsZSByZXF1ZXN0IGluIGJpdHNcclxuICAgICNyZXF1ZXN0U2l6ZSA9IC0xO1xyXG5cclxuICAgIC8vIHN0b3JlcyBjYWNoZWQgYXJyYXlzIG9mIHZhbHVlc1xyXG4gICAgI3N0YWNrID0gW107XHJcbiAgICAvLyBudW1iZXIgb2YgYXJyYXlzIHRvIHRyeSB0byBtYWludGFpbiBpbiAjc3RhY2tcclxuICAgICNjYWNoZVNpemUgPSAxMDtcclxuXHJcbiAgICAvLyBzdGF0dXMgb2YgdGhlIGNhY2hlXHJcbiAgICAjcGF1c2VkID0gZmFsc2U7XHJcbiAgICAvLyBiaXRzIHVzZWQgYnkgdGhpcyBjYWNoZVxyXG4gICAgI2JpdHNVc2VkID0gMDtcclxuICAgIC8vIHJlcXVlc3RzIHVzZWQgYnkgdGhpcyBjYWNoZVxyXG4gICAgI3JlcXVlc3RzVXNlZCA9IDA7XHJcbiAgICAvLyBlbnN1cmVzICNwb3B1bGF0ZSgpIGRvZXMgbm90IGlzc3VlIHBhcmFsbGVsIHJlcXVlc3RzXHJcbiAgICAjY3VycmVudGx5UG9wdWxhdGluZyA9IGZhbHNlO1xyXG5cclxuICAgIC8vIGFuIGVycm9yIHdoaWNoIHdpbGwgYmUgdGhyb3duIG9uIHRoZSBuZXh0IGNhbGwgdG8gZ2V0KCkgb3IgZ2V0T3JXYWl0KClcclxuICAgICNlcnJvciA9IG51bGw7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJbml0aWFsaXplIGNsYXNzIGFuZCBzdGFydCBzdGFjayBwb3B1bGF0aW9uXHJcbiAgICAgKiBcclxuICAgICAqICoqIFdBUk5JTkcqKiBTaG91bGQgb25seSBiZSBjYWxsZWQgYnkgUmFuZG9tT3JnQ2xpZW50J3MgY3JlYXRlQ2FjaGUoKVxyXG4gICAgICogbWV0aG9kcy5cclxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb24oT2JqZWN0KSA6IE9iamVjdH0gcmVxdWVzdEZ1bmN0aW9uIEZ1bmN0aW9uIHVzZWQgdG8gc2VuZFxyXG4gICAgICogICAgIHN1cHBsaWVkIHJlcXVlc3QgdG8gc2VydmVyLlxyXG4gICAgICogQHBhcmFtIHtPYmplY3R9IHJlcXVlc3QgUmVxdWVzdCB0byBzZW5kIHRvIHNlcnZlciB2aWEgcmVxdWVzdEZ1bmN0aW9uLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGNhY2hlU2l6ZSBOdW1iZXIgb2YgcmVxdWVzdCByZXNwb25zZXMgdG8gdHJ5IG1haW50YWluLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGJ1bGtSZXF1ZXN0TnVtYmVyIElmIHJlcXVlc3QgaXMgc2V0IHRvIGJlIGlzc3VlZCBpbiBidWxrLFxyXG4gICAgICogICAgIG51bWJlciBvZiByZXN1bHQgc2V0cyBpbiBhIGJ1bGsgcmVxdWVzdCwgZWxzZSAwLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHJlcXVlc3ROdW1iZXIgSWYgcmVxdWVzdCBpcyBzZXQgdG8gYmUgaXNzdWVkIGluIGJ1bGssXHJcbiAgICAgKiAgICAgbnVtYmVyIG9mIHJlc3VsdHMgaW4gYSBzaW5nbGUgcmVxdWVzdCwgZWxzZSAwLlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHNpbmdsZVJlcXVlc3RTaXplIFNpemUgb2YgYSBzaW5nbGUgcmVxdWVzdCBpbiBiaXRzIGZvclxyXG4gICAgICogICAgIGFkanVzdGluZyBidWxrIHJlcXVlc3RzIGlmIGJpdHMgYXJlIGluIHNob3J0IHN1cHBseSBvbiB0aGUgc2VydmVyLlxyXG4gICAgICovXHJcbiAgICBjb25zdHJ1Y3RvcihyZXF1ZXN0RnVuY3Rpb24sIHJlcXVlc3QsIGNhY2hlU2l6ZSwgYnVsa1JlcXVlc3ROdW1iZXIsIHJlcXVlc3ROdW1iZXIsIHNpbmdsZVJlcXVlc3RTaXplKSB7XHJcbiAgICAgICAgdGhpcy4jcmVxdWVzdEZ1bmN0aW9uID0gcmVxdWVzdEZ1bmN0aW9uO1xyXG5cclxuICAgICAgICB0aGlzLiNyZXF1ZXN0ID0gcmVxdWVzdDtcclxuICAgICAgICBcclxuICAgICAgICB0aGlzLiNjYWNoZVNpemUgPSBjYWNoZVNpemU7XHJcblxyXG4gICAgICAgIHRoaXMuI2J1bGtSZXF1ZXN0TnVtYmVyID0gYnVsa1JlcXVlc3ROdW1iZXI7XHJcbiAgICAgICAgdGhpcy4jcmVxdWVzdE51bWJlciA9IHJlcXVlc3ROdW1iZXI7XHJcbiAgICAgICAgdGhpcy4jcmVxdWVzdFNpemUgPSBzaW5nbGVSZXF1ZXN0U2l6ZTtcclxuXHJcbiAgICAgICAgdGhpcy4jcG9wdWxhdGUoKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEZ1bmN0aW9uIHRvIGNvbnRpbnVlIGlzc3VpbmcgcmVxdWVzdHMgdW50aWwgdGhlIHN0YWNrIGlzIGZ1bGwuXHJcbiAgICAgKiBcclxuICAgICAqIEtlZXAgaXNzdWluZyByZXF1ZXN0cyB0byBzZXJ2ZXIgdW50aWwgc3RhY2sgaXMgZnVsbC4gV2hlbiBzdGFjayBpcyBmdWxsXHJcbiAgICAgKiBpZiByZXF1ZXN0cyBhcmUgYmVpbmcgaXNzdWVkIGluIGJ1bGssIHdhaXQgdW50aWwgc3RhY2sgaGFzIGVub3VnaCBzcGFjZVxyXG4gICAgICogdG8gYWNjb21tb2RhdGUgYWxsIG9mIGEgYnVsayByZXF1ZXN0IGJlZm9yZSBpc3N1aW5nIGEgbmV3IHJlcXVlc3QsIG90aGVyd2lzZVxyXG4gICAgICogaXNzdWUgYSBuZXcgcmVxdWVzdCBldmVyeSB0aW1lIGFuIGl0ZW0gaW4gdGhlIHN0YWNrIGhhcyBiZWVuIGNvbnN1bWVkLiBOb3RlXHJcbiAgICAgKiB0aGF0IHJlcXVlc3RzIGFyZSBibG9ja2luZyAoJ2F3YWl0JyBpcyB1c2VkIHdoZW4gY2FsbGluZyB0aGUgcmVxdWVzdEZ1bmN0aW9uKSxcclxuICAgICAqIGkuZS4sIG9ubHkgb25lIHJlcXVlc3Qgd2lsbCBiZSBpc3N1ZWQgYnkgdGhlIGNhY2hlIGF0IGFueSBnaXZlbiB0aW1lLlxyXG4gICAgICovXHJcbiAgICAjcG9wdWxhdGUgPSBhc3luYyAoKSA9PiB7XHJcbiAgICAgICAgaWYgKCF0aGlzLiNjdXJyZW50bHlQb3B1bGF0aW5nICYmICF0aGlzLiNwYXVzZWQpIHtcclxuICAgICAgICAgICAgdGhpcy4jY3VycmVudGx5UG9wdWxhdGluZyA9IHRydWU7XHJcblxyXG4gICAgICAgICAgICBsZXQgcmVzcG9uc2UgPSBudWxsO1xyXG5cclxuICAgICAgICAgICAgd2hpbGUgKHRydWUpIHtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLiNlcnJvciAhPSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy4jYnVsa1JlcXVlc3ROdW1iZXIgPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gSXMgdGhlcmUgc3BhY2UgZm9yIGEgYnVsayByZXNwb25zZSBpbiB0aGUgc3RhY2s/XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuI3N0YWNrLmxlbmd0aCA8PSAodGhpcy4jY2FjaGVTaXplIC0gdGhpcy4jYnVsa1JlcXVlc3ROdW1iZXIpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZSA9IGF3YWl0IHRoaXMuI3JlcXVlc3RGdW5jdGlvbih0aGlzLiNyZXF1ZXN0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuI2FkZFJlc3BvbnNlKHJlc3BvbnNlLCB0cnVlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbm90IGVub3VnaCBiaXRzIHJlbWFpbmluZyBmb3IgYSBidWxrIHJlcXVlc3RcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlIGluc3RhbmNlb2YgUmFuZG9tT3JnSW5zdWZmaWNpZW50Qml0c0Vycm9yKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGJpdHNMZWZ0ID0gZS5nZXRCaXRzTGVmdCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChiaXRzTGVmdCA+IHRoaXMuI3JlcXVlc3RTaXplKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlmIHBvc3NpYmxlLCBhZGp1c3QgcmVxdWVzdCBmb3IgdGhlIGxhcmdlc3QgcG9zc2libGUgc2l6ZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgYWRqdXN0ZWRCdWxrID0gTWF0aC5mbG9vcihiaXRzTGVmdC90aGlzLiNyZXF1ZXN0U2l6ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuI3JlcXVlc3QucGFyYW1zLm4gPSBhZGp1c3RlZEJ1bGsgKiB0aGlzLiNyZXF1ZXN0TnVtYmVyO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLiNyZXF1ZXN0RnVuY3Rpb24odGhpcy4jcmVxdWVzdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuI2FkZFJlc3BvbnNlKHJlc3BvbnNlLCB0cnVlKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlc2V0IHRvIG9yaWdpbmFsIGJ1bGsgcmVxdWVzdCBzaXplXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuI3JlcXVlc3QucGFyYW1zLm4gPSB0aGlzLiNidWxrUmVxdWVzdE51bWJlciAqIHRoaXMuI3JlcXVlc3ROdW1iZXI7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmVxdWVzdCBzaXplIGNhbm5vdCBiZSBhZGp1c3RlZFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiNlcnJvciA9IGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFueSBvdGhlciBlcnJvciB0aHJvd24gZHVyaW5nIGluIHRoZSByZXF1ZXN0IGZ1bmN0aW9uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy4jZXJyb3IgPSBlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gbm8gc3BhY2UgZm9yIGEgYnVsayByZXF1ZXN0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy4jc3RhY2subGVuZ3RoIDwgdGhpcy4jY2FjaGVTaXplKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gaW5kaXZpZHVhbCByZXF1ZXN0c1xyXG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlID0gYXdhaXQgdGhpcy4jcmVxdWVzdEZ1bmN0aW9uKHRoaXMuI3JlcXVlc3QpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiNhZGRSZXNwb25zZShyZXNwb25zZSwgZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2goZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLiNlcnJvciA9IGU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyB0aGUgc3RhY2sgaXMgZnVsbFxyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9ICAgICAgICAgICAgICAgXHJcblxyXG4gICAgICAgICAgICB0aGlzLiNjdXJyZW50bHlQb3B1bGF0aW5nID0gZmFsc2U7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIGNhY2hlIHdpbGwgbm8gbG9uZ2VyIGNvbnRpbnVlIHRvIHBvcHVsYXRlIGl0c2VsZi5cclxuICAgICAqL1xyXG4gICAgc3RvcCgpIHtcclxuICAgICAgICB0aGlzLiNwYXVzZWQgPSB0cnVlO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogVGhlIGNhY2hlIHdpbGwgcmVzdW1lIHBvcHVsYXRpbmcgaXRzZWxmIGlmIHN0b3BwZWQuXHJcbiAgICAgKi9cclxuICAgIHJlc3VtZSgpIHtcclxuICAgICAgICB0aGlzLiNwYXVzZWQgPSBmYWxzZTtcclxuXHJcbiAgICAgICAgLy8gY2hlY2sgaWYgaXQgbmVlZHMgdG8gYmUgcmVwb3B1bGF0ZWRcclxuICAgICAgICB0aGlzLiNyZWZyZXNoKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDaGVja3MgaWYgdGhlIGNhY2hlIGlzIGN1cnJlbnRseSBub3QgcmUtcG9wdWxhdGluZyBpdHNlbGYuXHJcbiAgICAgKiBcclxuICAgICAqIFZhbHVlcyBjdXJyZW50bHkgY2FjaGVkIG1heSBzdGlsbCBiZSByZXRyaWV2ZWQgd2l0aCBnZXQoKSBidXQgbm8gbmV3XHJcbiAgICAgKiB2YWx1ZXMgYXJlIGJlaW5nIGZldGNoZWQgZnJvbSB0aGUgc2VydmVyLiBUaGlzIHN0YXRlIGNhbiBiZSBjaGFuZ2VkIHdpdGhcclxuICAgICAqIHN0b3AoKSBhbmQgcmVzdW1lKCkuXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiBjYWNoZSBpcyBjdXJyZW50bHkgbm90IHJlLXBvcHVsYXRpbmcgaXRzZWxmLFxyXG4gICAgICogICAgIGZhbHNlIG90aGVyd2lzZS5cclxuICAgICAqL1xyXG4gICAgaXNQYXVzZWQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuI3BhdXNlZDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEdldHMgdGhlIG5leHQgcmVzcG9uc2UuXHJcbiAgICAgKiBOb3RlIHRoYXQgaWYgdGhlIGNhY2hlIGlzIGVtcHR5LCBpZiB3YXMgY29uc3RydWN0ZWQgd2l0aCB1bnN1aXRhYmxlIHBhcmFtZXRlclxyXG4gICAgICogdmFsdWVzIG9yIGlmIHRoZSBkYWlseSBhbGxvd2FuY2Ugb2YgYml0cy9yZXF1ZXN0cyBoYXMgYmVlbiByZWFjaGVkLCB0aGUgYXBwcm9wcmlhdGVcclxuICAgICAqIGVycm9yIHdpbGwgYmUgdGhyb3duLlxyXG4gICAgICogQHJldHVybnMge2FueVtdfSBUaGUgbmV4dCBhcHByb3ByaWF0ZSByZXNwb25zZSBmb3IgdGhlIHJlcXVlc3QgdGhpcyBSYW5kb21PcmdDYWNoZVxyXG4gICAgICogICAgIHJlcHJlc2VudHMgb3IsIGlmIHN0YWNrIGlzIGVtcHR5IHRocm93cyBhbiBlcnJvci5cclxuICAgICAqIEB0aHJvd3MgUmFuZG9tT3JnQ2FjaGVFbXB0eUVycm9yIGlmIHRoZSBjYWNoZSBpcyBlbXB0eS5cclxuICAgICAqL1xyXG4gICAgZ2V0KCkge1xyXG4gICAgICAgIGlmICh0aGlzLiNlcnJvciAhPSBudWxsKSB7XHJcbiAgICAgICAgICAgIHRocm93IHRoaXMuI2Vycm9yO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodGhpcy4jc3RhY2sgJiYgdGhpcy4jc3RhY2subGVuZ3RoID09IDApIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuI3BhdXNlZCkge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmRvbU9yZ0NhY2hlRW1wdHlFcnJvcignVGhlIFJhbmRvbU9yZ0NhY2hlIHN0YWNrICdcclxuICAgICAgICAgICAgICAgICAgICArICdpcyBlbXB0eSBhbmQgdGhlIGNhY2hlIGlzIHBhdXNlZC4gUGxlYXNlIGNhbGwgcmVzdW1lKCkgdG8gJ1xyXG4gICAgICAgICAgICAgICAgICAgICsgJ3Jlc3RhcnQgcG9wdWxhdGluZyB0aGUgY2FjaGUuJywgdHJ1ZSk7ICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmFuZG9tT3JnQ2FjaGVFbXB0eUVycm9yKCdUaGUgUmFuZG9tT3JnQ2FjaGUgc3RhY2sgJ1xyXG4gICAgICAgICAgICAgICAgICAgICsgJ2lzIGVtcHR5LCBwbGVhc2Ugd2FpdCBmb3IgaXQgdG8gcmVwb3B1bGF0ZSBpdHNlbGYuJyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBsZXQgZGF0YSA9IHRoaXMuI3N0YWNrLnBvcCgpO1xyXG5cclxuICAgICAgICAgICAgLy8gY2hlY2sgaWYgaXQgbmVlZHMgdG8gYmUgcmVwb3B1bGF0ZWRcclxuICAgICAgICAgICAgdGhpcy4jcmVmcmVzaCgpO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIGRhdGE7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0IG5leHQgcmVzcG9uc2Ugb3Igd2FpdCB1bnRpbCB0aGUgbmV4dCB2YWx1ZSBpcyBhdmFpbGFibGUuIFRoaXMgbWV0aG9kXHJcbiAgICAgKiB3aWxsIGJsb2NrIHVudGlsIGEgdmFsdWUgaXMgYXZhaWxhYmxlLiBOb3RlOiB0aGlzIG1ldGhvZCB3aWxsIHRocm93IGFuIGVycm9yXHJcbiAgICAgKiBpZiB0aGUgY2FjaGUgaXMgZW1wdHkgYW5kIGhhcyBiZWVuIHBhdXNlZCwgaS5lLiBpcyBub3QgYmVpbmcgcG9wdWxhdGVkLiBJZlxyXG4gICAgICogdGhlIGNhY2hlIHdhcyBjb25zdHJ1Y3RlZCB3aXRoIHVuc3VpdGFibGUgcGFyYW1ldGVyIHZhbHVlcyBvciB0aGUgZGFpbHkgYWxsb3dhbmNlXHJcbiAgICAgKiBvZiBiaXRzL3JlcXVlc3RzIGhhcyBiZWVuIHJlYWNoZWQsIHRoZSBhcHByb3ByaWF0ZSBlcnJvciB3aWxsIGFsc28gYmUgdGhyb3duLlxyXG4gICAgICogQHJldHVybnMge1Byb21pc2U8YW55W10+fSBUaGUgbmV4dCBhcHByb3ByaWF0ZSByZXNwb25zZSBmb3IgdGhlIHJlcXVlc3QgdGhpc1xyXG4gICAgICogUmFuZG9tT3JnQ2FjaGUgcmVwcmVzZW50cy5cclxuICAgICAqIEB0aHJvd3MgUmFuZG9tT3JnQ2FjaGVFbXB0eUVycm9yIGlmIHRoZSBjYWNoZSBpcyBlbXB0eSBhbmQgaXMgcGF1c2VkLlxyXG4gICAgICovXHJcbiAgICBhc3luYyBnZXRPcldhaXQoKSB7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgbGV0IHZhbHVlcyA9IHRoaXMuZ2V0KCk7XHJcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZXM7XHJcbiAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICBpZiAoZSBpbnN0YW5jZW9mIFJhbmRvbU9yZ0NhY2hlRW1wdHlFcnJvcikge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuI3BhdXNlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIFRoZSBjYWNoZSBpcyBwYXVzZWQgYW5kIHdpbGwgbm90IHJldHVybiBhbnkgdmFsdWVzXHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGxldCBjYWNoZWRWYWx1ZXMgPSBhd2FpdCB0aGlzLiNwb3B1bGF0ZSgpO1xyXG4gICAgICAgICAgICAgICAgaWYgKGNhY2hlZFZhbHVlcyA9PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gVGhlIGNhY2hlIGhhcyBub3QgeWV0IHJlcG9wdWxhdGVkLlxyXG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKHIgPT4gc2V0VGltZW91dChyLCA1MCkpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0T3JXYWl0KCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSBudW1iZXIgb2YgcmVzdWx0IHNldHMgcmVtYWluaW5nIGluIHRoZSBjYWNoZS5cclxuICAgICAqIFxyXG4gICAgICogVGhpcyBlc3NlbnRpYWxseSByZXR1cm5zIGhvdyBvZnRlbiBnZXQoKSBtYXkgYmUgY2FsbGVkIHdpdGhvdXRcclxuICAgICAqIGEgY2FjaGUgcmVmaWxsLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gQ3VycmVudCBudW1iZXIgb2YgY2FjaGVkIHJlc3VsdHMuXHJcbiAgICAgKi9cclxuICAgIGdldENhY2hlZFZhbHVlcygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy4jc3RhY2subGVuZ3RoO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgbnVtYmVyIG9mIGJpdHMgdXNlZCBieSB0aGlzIGNhY2hlLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gTnVtYmVyIG9mIGJpdHMgdXNlZC5cclxuICAgICAqL1xyXG4gICAgZ2V0Qml0c1VzZWQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuI2JpdHNVc2VkO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogR2V0cyBudW1iZXIgb2YgcmVxdWVzdHMgdXNlZCBieSB0aGlzIGNhY2hlLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gTnVtYmVyIG9mIHJlcXVlc3RzIHVzZWQuXHJcbiAgICAgKi9cclxuICAgIGdldFJlcXVlc3RzVXNlZCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy4jcmVxdWVzdHNVc2VkO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogSGVscGVyIGZ1bmN0aW9uIHRvIGNoZWNrIGlmIHRoZSBjYWNoZSBuZWVkcyB0byBiZSByZXBvcHVsYXRlZC5cclxuICAgICAqL1xyXG4gICAgI3JlZnJlc2ggPSAoKSA9PiB7XHJcbiAgICAgICAgaWYgKHRoaXMuI2J1bGtSZXF1ZXN0TnVtYmVyID4gMCAmJiB0aGlzLiNzdGFjay5sZW5ndGggPD0gKHRoaXMuI2NhY2hlU2l6ZSAtIHRoaXMuI2J1bGtSZXF1ZXN0TnVtYmVyKSkge1xyXG4gICAgICAgICAgICAvLyBidWxrIHJlcXVlc3RzXHJcbiAgICAgICAgICAgIHRoaXMuI3BvcHVsYXRlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKHRoaXMuI2J1bGtSZXF1ZXN0TnVtYmVyIDw9IDAgJiYgdGhpcy4jc3RhY2subGVuZ3RoIDwgdGhpcy4jY2FjaGVTaXplKSB7XHJcbiAgICAgICAgICAgIC8vIGluZGl2aWR1YWwgcmVxdWVzdHNcclxuICAgICAgICAgICAgdGhpcy4jcG9wdWxhdGUoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBIZWxwZXIgZnVuY3Rpb24gdG8gYWRkIGEgcmVzcG9uc2UgdG8gdGhlIHN0YWNrLlxyXG4gICAgICogQHBhcmFtIHthbnlbXX0gcmVzcG9uc2UgVGhlIHJlc3BvbnNlIHJlY2VpdmVkIGZyb20gdGhlIHNlcnZlci5cclxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gYnVsayBUcnVlIGlmIHRoZSBjYWNoZSBpc3N1ZXMgYnVsayByZXF1ZXN0cywgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gICAgICovXHJcbiAgICAjYWRkUmVzcG9uc2UgPSAocmVzcG9uc2UsIGJ1bGspID0+IHtcclxuICAgICAgICB0aGlzLiNyZXF1ZXN0c1VzZWQrKztcclxuICAgICAgICB0aGlzLiNiaXRzVXNlZCArPSByZXNwb25zZS5yZXN1bHQuYml0c1VzZWQ7XHJcblxyXG4gICAgICAgIGlmIChidWxrKSB7XHJcbiAgICAgICAgICAgIGxldCBkYXRhID0gcmVzcG9uc2UucmVzdWx0LnJhbmRvbS5kYXRhO1xyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyBpICs9IHRoaXMuI3JlcXVlc3ROdW1iZXIpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuI3N0YWNrLnB1c2goZGF0YS5zbGljZShpLCBpICsgdGhpcy4jcmVxdWVzdE51bWJlcikpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy4jc3RhY2sucHVzaChyZXNwb25zZS5yZXN1bHQucmFuZG9tLmRhdGEpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufSIsIid1c2Ugc3RyaWN0JztcclxuXHJcbmNvbnN0IHtcclxuICAgIFJhbmRvbU9yZ0JhZEhUVFBSZXNwb25zZUVycm9yLFxyXG4gICAgUmFuZG9tT3JnSW5zdWZmaWNpZW50Qml0c0Vycm9yLFxyXG4gICAgUmFuZG9tT3JnSW5zdWZmaWNpZW50UmVxdWVzdHNFcnJvcixcclxuICAgIFJhbmRvbU9yZ0pTT05SUENFcnJvcixcclxuICAgIFJhbmRvbU9yZ0tleU5vdFJ1bm5pbmdFcnJvcixcclxuICAgIFJhbmRvbU9yZ1JBTkRPTU9SR0Vycm9yLFxyXG4gICAgUmFuZG9tT3JnU2VuZFRpbWVvdXRFcnJvclxyXG59ID0gcmVxdWlyZSgnLi9SYW5kb21PcmdFcnJvcnMuanMnKTtcclxuY29uc3QgUmFuZG9tT3JnQ2FjaGUgPSByZXF1aXJlKCcuL1JhbmRvbU9yZ0NhY2hlLmpzJyk7XHJcbi8qIG5vZGUtaW1wb3J0ICovXHJcbmNvbnN0IFhNTEh0dHBSZXF1ZXN0ID0gcmVxdWlyZSgneG1saHR0cHJlcXVlc3QnKS5YTUxIdHRwUmVxdWVzdDtcclxuLyogZW5kLW5vZGUtaW1wb3J0ICovXHJcblxyXG4vKipcclxuICogUmFuZG9tT3JnQ2xpZW50IG1haW4gY2xhc3MgdGhyb3VnaCB3aGljaCBBUEkgZnVuY3Rpb25zIGFyZSBhY2Nlc3NlZC5cclxuICogXHJcbiAqIFRoaXMgY2xhc3MgcHJvdmlkZXMgYWNjZXNzIHRvIGJvdGggdGhlIHNpZ25lZCBhbmQgdW5zaWduZWQgbWV0aG9kcyBvZiB0aGVcclxuICogUkFORE9NLk9SRyBBUEkuXHJcbiAqIFxyXG4gKiBUaGUgY2xhc3MgYWxzbyBwcm92aWRlcyBhY2Nlc3MgdG8gdGhlIGNyZWF0aW9uIG9mIGEgY29udmVuaWVuY2UgY2xhc3MsIFJhbmRvbU9yZ0NhY2hlLFxyXG4gKiBmb3IgcHJlY2FjaGluZyBBUEkgcmVzcG9uc2VzIHdoZW4gdGhlIHJlcXVlc3QgaXMga25vd24gaW4gYWR2YW5jZS5cclxuICogXHJcbiAqIFRoaXMgY2xhc3Mgd2lsbCBvbmx5IGFsbG93IHRoZSBjcmVhdGlvbiBvZiBvbmUgaW5zdGFuY2UgcGVyIEFQSSBrZXkuIElmIGFuXHJcbiAqIGluc3RhbmNlIG9mIHRoaXMgY2xhc3MgYWxyZWFkeSBleGlzdHMgZm9yIGEgZ2l2ZW4ga2V5LCB0aGF0IGluc3RhbmNlIHdpbGwgYmVcclxuICogcmV0dXJuZWQgaW5zdGVhZCBvZiBhIG5ldyBpbnN0YW5jZS5cclxuICogXHJcbiAqIFRoaXMgY2xhc3Mgb2JleXMgbW9zdCBvZiB0aGUgZ3VpZGVsaW5lcyBzZXQgZm9ydGggaW4gaHR0cHM6Ly9hcGkucmFuZG9tLm9yZy9qc29uLXJwYy80XHJcbiAqIEFsbCByZXF1ZXN0cyByZXNwZWN0IHRoZSBzZXJ2ZXIncyBhZHZpc29yeURlbGF5IHJldHVybmVkIGluIGFueSByZXNwb25zZXMsIG9yIHVzZVxyXG4gKiBERUZBVUxUX0RFTEFZIGlmIG5vIGFkdmlzb3J5RGVsYXkgaXMgcmV0dXJuZWQuIElmIHRoZSBzdXBwbGllZCBBUEkga2V5IGlzIHBhdXNlZCwgaS5lLixcclxuICogaGFzIGV4Y2VlZGVkIGl0cyBkYWlseSBiaXQvcmVxdWVzdCBhbGxvd2FuY2UsIHRoaXMgaW1wbGVtZW50YXRpb24gd2lsbCBiYWNrIG9mZiB1bnRpbFxyXG4gKiBtaWRuaWdodCBVVEMuXHJcbiAqL1xyXG5tb2R1bGUuZXhwb3J0cyA9IGNsYXNzIFJhbmRvbU9yZ0NsaWVudCB7XHJcbiAgICAvLyBCYXNpYyBBUElcclxuICAgIHN0YXRpYyAjSU5URUdFUl9NRVRIT0QgPSAnZ2VuZXJhdGVJbnRlZ2Vycyc7XHJcbiAgICBzdGF0aWMgI0lOVEVHRVJfU0VRVUVOQ0VfTUVUSE9EID0gJ2dlbmVyYXRlSW50ZWdlclNlcXVlbmNlcyc7XHJcbiAgICBzdGF0aWMgI0RFQ0lNQUxfRlJBQ1RJT05fTUVUSE9EID0gJ2dlbmVyYXRlRGVjaW1hbEZyYWN0aW9ucyc7XHJcbiAgICBzdGF0aWMgI0dBVVNTSUFOX01FVEhPRCA9ICdnZW5lcmF0ZUdhdXNzaWFucyc7XHJcbiAgICBzdGF0aWMgI1NUUklOR19NRVRIT0QgPSAnZ2VuZXJhdGVTdHJpbmdzJztcclxuICAgIHN0YXRpYyAjVVVJRF9NRVRIT0QgPSAnZ2VuZXJhdGVVVUlEcyc7XHJcbiAgICBzdGF0aWMgI0JMT0JfTUVUSE9EID0gJ2dlbmVyYXRlQmxvYnMnO1xyXG4gICAgc3RhdGljICNHRVRfVVNBR0VfTUVUSE9EID0gJ2dldFVzYWdlJztcclxuXHJcbiAgICAvLyBTaWduZWQgQVBJXHJcbiAgICBzdGF0aWMgI1NJR05FRF9JTlRFR0VSX01FVEhPRCA9ICdnZW5lcmF0ZVNpZ25lZEludGVnZXJzJztcclxuICAgIHN0YXRpYyAjU0lHTkVEX0lOVEVHRVJfU0VRVUVOQ0VfTUVUSE9EID0gJ2dlbmVyYXRlU2lnbmVkSW50ZWdlclNlcXVlbmNlcyc7XHJcbiAgICBzdGF0aWMgI1NJR05FRF9ERUNJTUFMX0ZSQUNUSU9OX01FVEhPRCA9ICdnZW5lcmF0ZVNpZ25lZERlY2ltYWxGcmFjdGlvbnMnO1xyXG4gICAgc3RhdGljICNTSUdORURfR0FVU1NJQU5fTUVUSE9EID0gJ2dlbmVyYXRlU2lnbmVkR2F1c3NpYW5zJztcclxuICAgIHN0YXRpYyAjU0lHTkVEX1NUUklOR19NRVRIT0QgPSAnZ2VuZXJhdGVTaWduZWRTdHJpbmdzJztcclxuICAgIHN0YXRpYyAjU0lHTkVEX1VVSURfTUVUSE9EID0gJ2dlbmVyYXRlU2lnbmVkVVVJRHMnO1xyXG4gICAgc3RhdGljICNTSUdORURfQkxPQl9NRVRIT0QgPSAnZ2VuZXJhdGVTaWduZWRCbG9icyc7XHJcbiAgICBzdGF0aWMgI0dFVF9SRVNVTFRfTUVUSE9EID0gJ2dldFJlc3VsdCc7XHJcbiAgICBzdGF0aWMgI0NSRUFURV9USUNLRVRfTUVUSE9EID0gJ2NyZWF0ZVRpY2tldHMnO1xyXG4gICAgc3RhdGljICNMSVNUX1RJQ0tFVF9NRVRIT0QgPSAnbGlzdFRpY2tldHMnO1xyXG4gICAgc3RhdGljICNHRVRfVElDS0VUX01FVEhPRCA9ICdnZXRUaWNrZXQnO1xyXG4gICAgc3RhdGljICNWRVJJRllfU0lHTkFUVVJFX01FVEhPRCA9ICd2ZXJpZnlTaWduYXR1cmUnO1xyXG5cclxuICAgIC8vIEJsb2IgZm9ybWF0IGxpdGVyYWxzXHJcbiAgICAvKiogQmxvYiBmb3JtYXQgbGl0ZXJhbCwgYmFzZTY0IGVuY29kaW5nIChkZWZhdWx0KS4gKi9cclxuICAgIHN0YXRpYyBCTE9CX0ZPUk1BVF9CQVNFNjQgPSAnYmFzZTY0JztcclxuICAgIC8qKiBCbG9iIGZvcm1hdCBsaXRlcmFsLCBoZXggZW5jb2RpbmcuICovXHJcbiAgICBzdGF0aWMgQkxPQl9GT1JNQVRfSEVYID0gJ2hleCc7XHJcblxyXG4gICAgLy8gRGVmYXVsdCB2YWx1ZXNcclxuICAgIC8qKiBEZWZhdWx0IHZhbHVlIGZvciB0aGUgcmVwbGFjZW1lbnQgcGFyYW1ldGVyICh0cnVlKS4gKi9cclxuICAgIHN0YXRpYyBERUZBVUxUX1JFUExBQ0VNRU5UID0gdHJ1ZTtcclxuICAgIC8qKiBEZWZhdWx0IHZhbHVlIGZvciB0aGUgYmFzZSBwYXJhbWV0ZXIgKDEwKS4gKi9cclxuICAgIHN0YXRpYyBERUZBVUxUX0JBU0UgPSAxMDtcclxuICAgIC8qKiBEZWZhdWx0IHZhbHVlIGZvciB0aGUgdXNlckRhdGEgcGFyYW1ldGVyIChudWxsKS4gKi9cclxuICAgIHN0YXRpYyBERUZBVUxUX1VTRVJfREFUQSA9IG51bGw7XHJcbiAgICAvKiogRGVmYXVsdCB2YWx1ZSBmb3IgdGhlIHRpY2tldElkIHBhcmFtZXRlciAobnVsbCkuICovXHJcbiAgICBzdGF0aWMgREVGQVVMVF9USUNLRVRfSUQgPSBudWxsO1xyXG4gICAgLyoqIERlZmF1bHQgdmFsdWUgZm9yIHRoZSBwcmVnZW5lcmF0ZWRSYW5kb21pemF0aW9uIHBhcmFtZXRlciAobnVsbCkuICovXHJcbiAgICBzdGF0aWMgREVGQVVMVF9QUkVHRU5FUkFURURfUkFORE9NSVpBVElPTiA9IG51bGw7XHJcbiAgICAvKiogRGVmYXVsdCB2YWx1ZSBmb3IgdGhlIGxpY2Vuc2VEYXRhIHBhcmFtZXRlciAobnVsbCkuICovXHJcbiAgICBzdGF0aWMgREVGQVVMVF9MSUNFTlNFX0RBVEEgPSBudWxsO1xyXG5cclxuICAgIC8qKiBTaXplIG9mIGEgc2luZ2xlIFVVSUQgaW4gYml0cy4gKi9cclxuICAgIHN0YXRpYyBVVUlEX1NJWkUgPSAxMjI7XHJcbiAgICAvKiogRGVmYXVsdCB2YWx1ZSBmb3IgdGhlIGJsb2NraW5nVGltZW91dCBwYXJhbWV0ZXIgKDEgZGF5KS4gKi9cclxuICAgIHN0YXRpYyBERUZBVUxUX0JMT0NLSU5HX1RJTUVPVVQgPSAyNCAqIDYwICogNjAgKiAxMDAwO1xyXG4gICAgLyoqIERlZmF1bHQgdmFsdWUgZm9yIHRoZSBodHRwVGltZW91dCBwYXJhbWV0ZXIgKDIgbWludXRlcykuICovXHJcbiAgICBzdGF0aWMgREVGQVVMVF9IVFRQX1RJTUVPVVQgPSAxMjAgKiAxMDAwO1xyXG4gICAgLyoqIE1heGltdW0gbnVtYmVyIG9mIGNoYXJhY3RlcnMgYWxsb3dlZCBpbiBhIHNpZ25hdHVyZSB2ZXJmaWNpYXRpb24gVVJMLiAqL1xyXG4gICAgc3RhdGljIE1BWF9VUkxfTEVOR1RIID0gMjA0NjtcclxuXHJcbiAgICAvLyBEZWZhdWx0IGJhY2stb2ZmIHRvIHVzZSBpZiBubyBhZHZpc29yeURlbGF5IGJhY2stb2ZmIHN1cHBsaWVkIGJ5IHNlcnZlciAoMSBzZWNvbmQpXHJcbiAgICBzdGF0aWMgI0RFRkFVTFRfREVMQVkgPSAxKjEwMDA7XHJcblxyXG4gICAgLy8gT24gcmVxdWVzdCBmZXRjaCBmcmVzaCBhbGxvd2FuY2Ugc3RhdGUgaWYgY3VycmVudCBzdGF0ZSBkYXRhIGlzIG9sZGVyIHRoYW5cclxuICAgIC8vIHRoaXMgdmFsdWUgKDEgaG91cikuXHJcbiAgICBzdGF0aWMgI0FMTE9XQU5DRV9TVEFURV9SRUZSRVNIX1NFQ09ORFMgPSAzNjAwICogMTAwMDtcclxuXHJcbiAgICAvLyBNYWludGFpbnMgdXNhZ2Ugc3RhdGlzdGljcyBmcm9tIHNlcnZlci5cclxuICAgICNiaXRzTGVmdCA9IC0xO1xyXG4gICAgI3JlcXVlc3RzTGVmdCA9IC0xO1xyXG5cclxuICAgIC8vIEJhY2stb2ZmIGluZm8gZm9yIHdoZW4gdGhlIEFQSSBrZXkgaXMgZGV0ZWN0ZWQgYXMgbm90IHJ1bm5pbmcsIHByb2JhYmx5XHJcbiAgICAvLyBiZWNhdXNlIHRoZSBrZXkgaGFzIGV4Y2VlZGVkIGl0cyBkYWlseSB1c2FnZSBsaW1pdC4gQmFjay1vZmYgcnVucyB1bnRpbFxyXG4gICAgLy8gbWlkbmlnaHQgVVRDLlxyXG4gICAgI2JhY2tvZmYgPSAtMTtcclxuICAgICNiYWNrb2ZmRXJyb3IgPSAnJztcclxuXHJcbiAgICAjYXBpS2V5ID0gJyc7XHJcbiAgICAjYmxvY2tpbmdUaW1lb3V0ID0gUmFuZG9tT3JnQ2xpZW50LkRFRkFVTFRfQkxPQ0tJTkdfVElNRU9VVDtcclxuICAgICNodHRwVGltZW91dCA9IFJhbmRvbU9yZ0NsaWVudC5ERUZBVUxUX0hUVFBfVElNRU9VVDtcclxuXHJcbiAgICAvLyBNYWludGFpbiBpbmZvIHRvIG9iZXkgc2VydmVyIGFkdmlzb3J5IGRlbGF5XHJcbiAgICAjYWR2aXNvcnlEZWxheSA9IDA7XHJcbiAgICAjbGFzdFJlc3BvbnNlUmVjZWl2ZWRUaW1lID0gMDtcclxuXHJcbiAgICAvLyBNYWludGFpbnMgYSBkaWN0aW9uYXJ5IG9mIEFQSSBrZXlzIGFuZCB0aGVpciBpbnN0YW5jZXMuXHJcbiAgICBzdGF0aWMgI2tleUluZGV4ZWRJbnN0YW5jZXMgPSB7fTtcclxuXHJcbiAgICBzdGF0aWMgI0VSUk9SX0NPREVTID0gWyAxMDAsIDEwMSwgMjAwLCAyMDEsIDIwMiwgMjAzLCAyMDQsIDMwMCxcclxuICAgICAgICAzMDEsIDMwMiwgMzAzLCAzMDQsIDMwNSwgMzA2LCAzMDcsIDQwMCwgNDAxLCA0MDIsIDQwMywgNDA0LFxyXG4gICAgICAgIDQwNSwgNDIwLCA0MjEsIDQyMiwgNDIzLCA0MjQsIDQyNSwgNTAwLCAzMjAwMCBdO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29uc3RydWN0b3IuIEVuc3VyZXMgb25seSBvbmUgaW5zdGFuY2Ugb2YgUmFuZG9tT3JnQ2xpZW50IGV4aXN0cyBwZXIgQVBJXHJcbiAgICAgKiBrZXkuIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2UgaWYgdGhlIHN1cHBsaWVkIGtleSBpc24ndCBhbHJlYWR5IGtub3duLFxyXG4gICAgICogb3RoZXJ3aXNlIHJldHVybnMgdGhlIHByZXZpb3VzbHkgaW5zdGFudGlhdGVkIG9uZS5cclxuICAgICAqIEBjb25zdHJ1Y3RvclxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGFwaUtleSBBUEkga2V5IG9mIGluc3RhbmNlIHRvIGNyZWF0ZS9maW5kLCBvYnRhaW5lZCBmcm9tXHJcbiAgICAgKiAgICAgUkFORE9NLk9SRywgc2VlIGh0dHBzOi8vYXBpLnJhbmRvbS5vcmcvYXBpLWtleXNcclxuICAgICAqIEBwYXJhbSB7e2Jsb2NraW5nVGltZW91dD86IG51bWJlciwgaHR0cFRpbWVvdXQ/OiBudW1iZXJ9fSBvcHRpb25zIEFuIG9iamVjdFxyXG4gICAgICogICAgIHdoaWNoIG1heSBjb250YWlucyBhbnkgb2YgdGhlIGZvbGxvd2luZyBvcHRpb25hbCBwYXJhbWV0ZXJzOlxyXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRpb25zLmJsb2NraW5nVGltZW91dCA9IDI0ICogNjAgKiA2MCAqIDEwMDBdIE1heGltdW1cclxuICAgICAqICAgICB0aW1lIGluIG1pbGxpc2Vjb25kcyB0byB3YWl0IGJlZm9yZSBiZWluZyBhbGxvd2VkIHRvIHNlbmQgYSByZXF1ZXN0LlxyXG4gICAgICogICAgIE5vdGUgdGhpcyBpcyBhIGhpbnQgbm90IGEgZ3VhcmFudGVlLiBUaGUgYWR2aXNvcnkgZGVsYXkgZnJvbSBzZXJ2ZXJcclxuICAgICAqICAgICBtdXN0IGFsd2F5cyBiZSBvYmV5ZWQuIFN1cHBseSBhIHZhbHVlIG9mIC0xIHRvIGFsbG93IGJsb2NraW5nIGZvcmV2ZXJcclxuICAgICAqICAgICAoZGVmYXVsdCAyNCAqIDYwICogNjAgKiAxMDAwLCBpLmUuLCAxIGRheSkuXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW29wdGlvbnMuaHR0cFRpbWVvdXQgPSAxMjAgKiAxMDAwXSBNYXhpbXVtIHRpbWUgaW5cclxuICAgICAqICAgICBtaWxsaXNlY29uZHMgdG8gd2FpdCBmb3IgdGhlIHNlcnZlciByZXNwb25zZSB0byBhIHJlcXVlc3QgKGRlZmF1bHRcclxuICAgICAqICAgICAxMjAqMTAwMCkuXHJcbiAgICAgKi9cclxuICAgIGNvbnN0cnVjdG9yKGFwaUtleSwgb3B0aW9ucyA9IHt9KSB7XHJcbiAgICAgICAgaWYgKFJhbmRvbU9yZ0NsaWVudC4ja2V5SW5kZXhlZEluc3RhbmNlcyAmJiBSYW5kb21PcmdDbGllbnQuI2tleUluZGV4ZWRJbnN0YW5jZXNbYXBpS2V5XSkge1xyXG4gICAgICAgICAgICByZXR1cm4gUmFuZG9tT3JnQ2xpZW50LiNrZXlJbmRleGVkSW5zdGFuY2VzW2FwaUtleV07XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy4jYXBpS2V5ID0gYXBpS2V5O1xyXG4gICAgICAgICAgICB0aGlzLiNibG9ja2luZ1RpbWVvdXQgPSBvcHRpb25zLmJsb2NraW5nVGltZW91dCB8fCAyNCAqIDYwICogNjAgKiAxMDAwO1xyXG4gICAgICAgICAgICB0aGlzLiNodHRwVGltZW91dCA9IG9wdGlvbnMuaHR0cFRpbWVvdXQgfHwgMTIwICogMTAwMDtcclxuXHJcbiAgICAgICAgICAgIFJhbmRvbU9yZ0NsaWVudC4ja2V5SW5kZXhlZEluc3RhbmNlc1thcGlLZXldID0gdGhpcztcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQmFzaWMgQVBJXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXF1ZXN0cyBhbmQgcmV0dXJucyBhbiBh