@vonage/ml-transformers 4.3.5 → 4.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -119,7 +119,7 @@
|
|
|
119
119
|
}`,1),K=R.createProgram();if(R.attachShader(K,F),R.attachShader(K,N),R.linkProgram(K),!R.getProgramParameter(K,R.LINK_STATUS))throw Error(`Could not compile WebGL program.
|
|
120
120
|
|
|
121
121
|
`+R.getProgramInfoLog(K));F=s.m=K,R.useProgram(F),N=R.getUniformLocation(F,"sampler0"),s.j={I:R.getAttribLocation(F,"aVertex"),H:R.getAttribLocation(F,"aTex"),da:N},s.s=R.createBuffer(),R.bindBuffer(R.ARRAY_BUFFER,s.s),R.enableVertexAttribArray(s.j.I),R.vertexAttribPointer(s.j.I,2,R.FLOAT,!1,0,0),R.bufferData(R.ARRAY_BUFFER,new Float32Array([-1,-1,-1,1,1,1,1,-1]),R.STATIC_DRAW),R.bindBuffer(R.ARRAY_BUFFER,null),s.o=R.createBuffer(),R.bindBuffer(R.ARRAY_BUFFER,s.o),R.enableVertexAttribArray(s.j.H),R.vertexAttribPointer(s.j.H,2,R.FLOAT,!1,0,0),R.bufferData(R.ARRAY_BUFFER,new Float32Array([0,1,0,0,1,0,1,1]),R.STATIC_DRAW),R.bindBuffer(R.ARRAY_BUFFER,null),R.uniform1i(N,0)}F=s.j,R.useProgram(s.m),R.canvas.width=X.width,R.canvas.height=X.height,R.viewport(0,0,X.width,X.height),R.activeTexture(R.TEXTURE0),s.h.bindTexture2d(X.glName),R.enableVertexAttribArray(F.I),R.bindBuffer(R.ARRAY_BUFFER,s.s),R.vertexAttribPointer(F.I,2,R.FLOAT,!1,0,0),R.enableVertexAttribArray(F.H),R.bindBuffer(R.ARRAY_BUFFER,s.o),R.vertexAttribPointer(F.H,2,R.FLOAT,!1,0,0),R.bindFramebuffer(R.DRAW_FRAMEBUFFER?R.DRAW_FRAMEBUFFER:R.FRAMEBUFFER,null),R.clearColor(0,0,0,0),R.clear(R.COLOR_BUFFER_BIT),R.colorMask(!0,!0,!0,!0),R.drawArrays(R.TRIANGLE_FAN,0,4),R.disableVertexAttribArray(F.I),R.disableVertexAttribArray(F.H),R.bindBuffer(R.ARRAY_BUFFER,null),s.h.bindTexture2d(0)}function Tt(s){this.g=s}var kt=new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,10,9,1,7,0,65,0,253,15,26,11]);function Qt(s,X){return X+s}function ue(s,X){window[s]=X}function pe(s){var X=document.createElement("script");return X.setAttribute("src",s),X.setAttribute("crossorigin","anonymous"),new Promise(function(R){X.addEventListener("load",function(){R()},!1),X.addEventListener("error",function(){R()},!1),document.body.appendChild(X)})}function ge(){return gt(function(s){switch(s.g){case 1:return s.m=2,P(s,WebAssembly.instantiate(kt),4);case 4:s.g=3,s.m=0;break;case 2:return s.m=0,s.j=null,s.return(!1);case 3:return s.return(!0)}})}function Je(s){if(this.g=s,this.listeners={},this.j={},this.F={},this.m={},this.s={},this.G=this.o=this.R=!0,this.C=Promise.resolve(),this.P="",this.B={},this.locateFile=s&&s.locateFile||Qt,typeof window=="object")var X=window.location.pathname.toString().substring(0,window.location.pathname.toString().lastIndexOf("/"))+"/";else if(typeof location<"u")X=location.pathname.toString().substring(0,location.pathname.toString().lastIndexOf("/"))+"/";else throw Error("solutions can only be loaded on a web page or in a web worker");if(this.S=X,s.options){X=w(Object.keys(s.options));for(var R=X.next();!R.done;R=X.next()){R=R.value;var F=s.options[R].default;F!==void 0&&(this.j[R]=typeof F=="function"?F():F)}}}i=Je.prototype,i.close=function(){return this.i&&this.i.delete(),Promise.resolve()};function h(s){var X,R,F,N,K,B,nt,$,yt,Gt,Bt;return gt(function(xt){switch(xt.g){case 1:return s.R?(X=s.g.files===void 0?[]:typeof s.g.files=="function"?s.g.files(s.j):s.g.files,P(xt,ge(),2)):xt.return();case 2:if(R=xt.h,typeof window=="object")return ue("createMediapipeSolutionsWasm",{locateFile:s.locateFile}),ue("createMediapipeSolutionsPackedAssets",{locateFile:s.locateFile}),B=X.filter(function(ht){return ht.data!==void 0}),nt=X.filter(function(ht){return ht.data===void 0}),$=Promise.all(B.map(function(ht){var Xt=C(s,ht.url);if(ht.path!==void 0){var It=ht.path;Xt=Xt.then(function(wt){return s.overrideFile(It,wt),Promise.resolve(wt)})}return Xt})),yt=Promise.all(nt.map(function(ht){return ht.simd===void 0||ht.simd&&R||!ht.simd&&!R?pe(s.locateFile(ht.url,s.S)):Promise.resolve()})).then(function(){var ht,Xt,It;return gt(function(wt){if(wt.g==1)return ht=window.createMediapipeSolutionsWasm,Xt=window.createMediapipeSolutionsPackedAssets,It=s,P(wt,ht(Xt),2);It.h=wt.h,wt.g=0})}),Gt=function(){return gt(function(ht){return s.g.graph&&s.g.graph.url?ht=P(ht,C(s,s.g.graph.url),0):(ht.g=0,ht=void 0),ht})}(),P(xt,Promise.all([yt,$,Gt]),7);if(typeof importScripts!="function")throw Error("solutions can only be loaded on a web page or in a web worker");return F=X.filter(function(ht){return ht.simd===void 0||ht.simd&&R||!ht.simd&&!R}).map(function(ht){return s.locateFile(ht.url,s.S)}),importScripts.apply(null,E(F)),N=s,P(xt,createMediapipeSolutionsWasm(Module),6);case 6:N.h=xt.h,s.l=new OffscreenCanvas(1,1),s.h.canvas=s.l,K=s.h.GL.createContext(s.l,{antialias:!1,alpha:!1,ba:typeof WebGL2RenderingContext<"u"?2:1}),s.h.GL.makeContextCurrent(K),xt.g=4;break;case 7:if(s.l=document.createElement("canvas"),Bt=s.l.getContext("webgl2",{}),!Bt&&(Bt=s.l.getContext("webgl",{}),!Bt))return alert("Failed to create WebGL canvas context when passing video frame."),xt.return();s.D=Bt,s.h.canvas=s.l,s.h.createContext(s.l,!0,!0,{});case 4:s.i=new s.h.SolutionWasm,s.R=!1,xt.g=0}})}function y(s){var X,R,F,N,K,B,nt,$;return gt(function(yt){if(yt.g==1){if(s.g.graph&&s.g.graph.url&&s.P===s.g.graph.url)return yt.return();if(s.o=!0,!s.g.graph||!s.g.graph.url){yt.g=2;return}return s.P=s.g.graph.url,P(yt,C(s,s.g.graph.url),3)}for(yt.g!=2&&(X=yt.h,s.i.loadGraph(X)),R=w(Object.keys(s.B)),F=R.next();!F.done;F=R.next())N=F.value,s.i.overrideFile(N,s.B[N]);if(s.B={},s.g.listeners)for(K=w(s.g.listeners),B=K.next();!B.done;B=K.next())nt=B.value,M(s,nt);$=s.j,s.j={},s.setOptions($),yt.g=0})}i.reset=function(){var s=this;return gt(function(X){s.i&&(s.i.reset(),s.m={},s.s={}),X.g=0})},i.setOptions=function(s,X){var R=this;if(X=X||this.g.options){for(var F=[],N=[],K={},B=w(Object.keys(s)),nt=B.next();!nt.done;K={K:K.K,L:K.L},nt=B.next()){var $=nt.value;$ in this.j&&this.j[$]===s[$]||(this.j[$]=s[$],nt=X[$],nt!==void 0&&(nt.onChange&&(K.K=nt.onChange,K.L=s[$],F.push(function(yt){return function(){var Gt;return gt(function(Bt){if(Bt.g==1)return P(Bt,yt.K(yt.L),2);Gt=Bt.h,Gt===!0&&(R.o=!0),Bt.g=0})}}(K))),nt.graphOptionXref&&($={valueNumber:nt.type===1?s[$]:0,valueBoolean:nt.type===0?s[$]:!1,valueString:nt.type===2?s[$]:""},nt=Object.assign(Object.assign(Object.assign({},{calculatorName:"",calculatorIndex:0}),nt.graphOptionXref),$),N.push(nt))))}(F.length!==0||N.length!==0)&&(this.o=!0,this.A=(this.A===void 0?[]:this.A).concat(N),this.v=(this.v===void 0?[]:this.v).concat(F))}};function v(s){var X,R,F,N,K,B,nt;return gt(function($){switch($.g){case 1:if(!s.o)return $.return();if(!s.v){$.g=2;break}X=w(s.v),R=X.next();case 3:if(R.done){$.g=5;break}return F=R.value,P($,F(),4);case 4:R=X.next(),$.g=3;break;case 5:s.v=void 0;case 2:if(s.A){for(N=new s.h.GraphOptionChangeRequestList,K=w(s.A),B=K.next();!B.done;B=K.next())nt=B.value,N.push_back(nt);s.i.changeOptions(N),N.delete(),s.A=void 0}s.o=!1,$.g=0}})}i.initialize=function(){var s=this;return gt(function(X){return X.g==1?P(X,h(s),2):X.g!=3?P(X,y(s),3):P(X,v(s),0)})};function C(s,X){var R,F;return gt(function(N){return X in s.F?N.return(s.F[X]):(R=s.locateFile(X,""),F=fetch(R).then(function(K){return K.arrayBuffer()}),s.F[X]=F,N.return(F))})}i.overrideFile=function(s,X){this.i?this.i.overrideFile(s,X):this.B[s]=X},i.clearOverriddenFiles=function(){this.B={},this.i&&this.i.clearOverriddenFiles()},i.send=function(s,X){var R=this,F,N,K,B,nt,$,yt,Gt,Bt;return gt(function(xt){switch(xt.g){case 1:return R.g.inputs?(F=1e3*(X==null?performance.now():X),P(xt,R.C,2)):xt.return();case 2:return P(xt,R.initialize(),3);case 3:for(N=new R.h.PacketDataList,K=w(Object.keys(s)),B=K.next();!B.done;B=K.next())if(nt=B.value,$=R.g.inputs[nt]){t:{var ht=s[nt];switch($.type){case"video":var Xt=R.m[$.stream];if(Xt||(Xt=new Nt(R.h,R.D),R.m[$.stream]=Xt),Xt.l===0&&(Xt.l=Xt.h.createTexture()),typeof HTMLVideoElement<"u"&&ht instanceof HTMLVideoElement)var It=ht.videoWidth,wt=ht.videoHeight;else typeof HTMLImageElement<"u"&&ht instanceof HTMLImageElement?(It=ht.naturalWidth,wt=ht.naturalHeight):(It=ht.width,wt=ht.height);wt={glName:Xt.l,width:It,height:wt},It=Xt.g,It.canvas.width=wt.width,It.canvas.height=wt.height,It.activeTexture(It.TEXTURE0),Xt.h.bindTexture2d(Xt.l),It.texImage2D(It.TEXTURE_2D,0,It.RGBA,It.RGBA,It.UNSIGNED_BYTE,ht),Xt.h.bindTexture2d(0),Xt=wt;break t;case"detections":for(Xt=R.m[$.stream],Xt||(Xt=new Tt(R.h),R.m[$.stream]=Xt),Xt.data||(Xt.data=new Xt.g.DetectionListData),Xt.data.reset(ht.length),wt=0;wt<ht.length;++wt){It=ht[wt];var Yt=Xt.data,l=Yt.setBoundingBox,Z=wt,x=It.T,T=new k;if(ut(T,1,x.Y),ut(T,2,x.Z),ut(T,3,x.height),ut(T,4,x.width),ut(T,5,x.rotation),ut(T,6,x.W),x=fn(T,ot),l.call(Yt,Z,x),It.O)for(Yt=0;Yt<It.O.length;++Yt){T=It.O[Yt];var J=!!T.visibility;l=Xt.data,Z=l.addNormalizedLandmark,x=wt,T=Object.assign(Object.assign({},T),{visibility:J?T.visibility:0}),J=new wn,ut(J,1,T.x),ut(J,2,T.y),ut(J,3,T.z),T.visibility&&ut(J,4,T.visibility),T=fn(J,Qn),Z.call(l,x,T)}if(It.M)for(Yt=0;Yt<It.M.length;++Yt)l=Xt.data,Z=l.addClassification,x=wt,T=It.M[Yt],J=new Sn,ut(J,2,T.X),T.index&&ut(J,1,T.index),T.label&&ut(J,3,T.label),T.displayName&&ut(J,4,T.displayName),T=fn(J,kn),Z.call(l,x,T)}Xt=Xt.data;break t;default:Xt={}}}switch(yt=Xt,Gt=$.stream,$.type){case"video":N.pushTexture2d(Object.assign(Object.assign({},yt),{stream:Gt,timestamp:F}));break;case"detections":Bt=yt,Bt.stream=Gt,Bt.timestamp=F,N.pushDetectionList(Bt);break;default:throw Error("Unknown input config type: '"+$.type+"'")}}return R.i.send(N),P(xt,R.C,4);case 4:N.delete(),xt.g=0}})};function A(s,X,R){var F,N,K,B,nt,$,yt,Gt,Bt,xt,ht,Xt,It,wt;return gt(function(Yt){switch(Yt.g){case 1:if(!R)return Yt.return(X);for(F={},N=0,K=w(Object.keys(R)),B=K.next();!B.done;B=K.next())nt=B.value,$=R[nt],typeof $!="string"&&$.type==="texture"&&X[$.stream]!==void 0&&++N;1<N&&(s.G=!1),yt=w(Object.keys(R)),B=yt.next();case 2:if(B.done){Yt.g=4;break}if(Gt=B.value,Bt=R[Gt],typeof Bt=="string")return It=F,wt=Gt,P(Yt,_(s,Gt,X[Bt]),14);if(xt=X[Bt.stream],Bt.type==="detection_list"){if(xt){for(var l=xt.getRectList(),Z=xt.getLandmarksList(),x=xt.getClassificationsList(),T=[],J=0;J<l.size();++J){var o=yn(l.get(J),k,O);o={T:{Y:it(o,1),Z:it(o,2),height:it(o,3),width:it(o,4),rotation:it(o,5,0),W:St(o,6)},O:Ut(Z.get(J)),M:bt(yn(x.get(J),vn,An))},T.push(o)}l=T}else l=[];F[Gt]=l,Yt.g=7;break}if(Bt.type==="proto_list"){if(xt){for(l=Array(xt.size()),Z=0;Z<xt.size();Z++)l[Z]=xt.get(Z);xt.delete()}else l=[];F[Gt]=l,Yt.g=7;break}if(xt===void 0){Yt.g=3;break}if(Bt.type==="float_list"){F[Gt]=xt,Yt.g=7;break}if(Bt.type==="proto"){F[Gt]=xt,Yt.g=7;break}if(Bt.type!=="texture")throw Error("Unknown output config type: '"+Bt.type+"'");return ht=s.s[Gt],ht||(ht=new Nt(s.h,s.D),s.s[Gt]=ht),P(Yt,$t(ht,xt,s.G),13);case 13:Xt=Yt.h,F[Gt]=Xt;case 7:Bt.transform&&F[Gt]&&(F[Gt]=Bt.transform(F[Gt])),Yt.g=3;break;case 14:It[wt]=Yt.h;case 3:B=yt.next(),Yt.g=2;break;case 4:return Yt.return(F)}})}function _(s,X,R){var F;return gt(function(N){return typeof R=="number"||R instanceof Uint8Array||R instanceof s.h.Uint8BlobList?N.return(R):R instanceof s.h.Texture2dDataOut?(F=s.s[X],F||(F=new Nt(s.h,s.D),s.s[X]=F),N.return($t(F,R,s.G))):N.return(void 0)})}function M(s,X){for(var R=X.name||"$",F=[].concat(E(X.wants)),N=new s.h.StringList,K=w(X.wants),B=K.next();!B.done;B=K.next())N.push_back(B.value);K=s.h.PacketListener.implement({onResults:function(nt){for(var $={},yt=0;yt<X.wants.length;++yt)$[F[yt]]=nt.get(yt);var Gt=s.listeners[R];Gt&&(s.C=A(s,$,X.outs).then(function(Bt){Bt=Gt(Bt);for(var xt=0;xt<X.wants.length;++xt){var ht=$[F[xt]];typeof ht=="object"&&ht.hasOwnProperty&&ht.hasOwnProperty("delete")&&ht.delete()}Bt&&(s.C=Bt)}))}}),s.i.attachMultiListener(N,K),N.delete()}i.onResults=function(s,X){this.listeners[X||"$"]=s},Ht("Solution",Je),Ht("OptionType",{BOOL:0,NUMBER:1,$:2,0:"BOOL",1:"NUMBER",2:"STRING"});function q(s){switch(s===void 0&&(s=0),s){case 1:return"pose_landmark_full.tflite";case 2:return"pose_landmark_heavy.tflite";default:return"pose_landmark_lite.tflite"}}function lt(s){var X=this;s=s||{},this.g=new Je({locateFile:s.locateFile,files:function(R){return[{url:"pose_solution_packed_assets_loader.js"},{simd:!1,url:"pose_solution_wasm_bin.js"},{simd:!0,url:"pose_solution_simd_wasm_bin.js"},{data:!0,url:q(R.modelComplexity)}]},graph:{url:"pose_web.binarypb"},listeners:[{wants:["pose_landmarks","world_landmarks","segmentation_mask","image_transformed"],outs:{image:{type:"texture",stream:"image_transformed"},poseLandmarks:{type:"proto",stream:"pose_landmarks",transform:Ut},poseWorldLandmarks:{type:"proto",stream:"world_landmarks",transform:Ut},segmentationMask:{type:"texture",stream:"segmentation_mask"}}}],inputs:{image:{type:"video",stream:"input_frames_gpu"}},options:{useCpuInference:{type:0,graphOptionXref:{calculatorType:"InferenceCalculator",fieldName:"use_cpu_inference"},default:"iPad Simulator;iPhone Simulator;iPod Simulator;iPad;iPhone;iPod".split(";").includes(navigator.platform)||navigator.userAgent.includes("Mac")&&"ontouchend"in document},selfieMode:{type:0,graphOptionXref:{calculatorType:"GlScalerCalculator",calculatorIndex:1,fieldName:"flip_horizontal"}},modelComplexity:{type:1,graphOptionXref:{calculatorType:"ConstantSidePacketCalculator",calculatorName:"ConstantSidePacketCalculatorModelComplexity",fieldName:"int_value"},onChange:function(R){var F,N,K;return gt(function(B){return B.g==1?(F=q(R),N="third_party/mediapipe/modules/pose_landmark/"+F,P(B,C(X.g,F),2)):(K=B.h,X.g.overrideFile(N,K),B.return(!0))})}},smoothLandmarks:{type:0,graphOptionXref:{calculatorType:"ConstantSidePacketCalculator",calculatorName:"ConstantSidePacketCalculatorSmoothLandmarks",fieldName:"bool_value"}},enableSegmentation:{type:0,graphOptionXref:{calculatorType:"ConstantSidePacketCalculator",calculatorName:"ConstantSidePacketCalculatorEnableSegmentation",fieldName:"bool_value"}},smoothSegmentation:{type:0,graphOptionXref:{calculatorType:"ConstantSidePacketCalculator",calculatorName:"ConstantSidePacketCalculatorSmoothSegmentation",fieldName:"bool_value"}},minDetectionConfidence:{type:1,graphOptionXref:{calculatorType:"TensorsToDetectionsCalculator",calculatorName:"poselandmarkgpu__posedetectiongpu__TensorsToDetectionsCalculator",fieldName:"min_score_thresh"}},minTrackingConfidence:{type:1,graphOptionXref:{calculatorType:"ThresholdingCalculator",calculatorName:"poselandmarkgpu__poselandmarkbyroigpu__tensorstoposelandmarksandsegmentation__ThresholdingCalculator",fieldName:"threshold"}}}})}i=lt.prototype,i.reset=function(){this.g.reset()},i.close=function(){return this.g.close(),Promise.resolve()},i.onResults=function(s){this.g.onResults(s)},i.initialize=function(){var s=this;return gt(function(X){return P(X,s.g.initialize(),0)})},i.send=function(s,X){var R=this;return gt(function(F){return P(F,R.g.send(s,X),0)})},i.setOptions=function(s){this.g.setOptions(s)},Ht("Pose",lt),Ht("POSE_CONNECTIONS",[[0,1],[1,2],[2,3],[3,7],[0,4],[4,5],[5,6],[6,8],[9,10],[11,12],[11,13],[13,15],[15,17],[15,19],[15,21],[17,19],[12,14],[14,16],[16,18],[16,20],[16,22],[18,20],[11,23],[12,24],[23,24],[23,25],[24,26],[25,27],[26,28],[27,29],[28,30],[29,31],[30,32],[27,31],[28,32]]),Ht("POSE_LANDMARKS",{NOSE:0,LEFT_EYE_INNER:1,LEFT_EYE:2,LEFT_EYE_OUTER:3,RIGHT_EYE_INNER:4,RIGHT_EYE:5,RIGHT_EYE_OUTER:6,LEFT_EAR:7,RIGHT_EAR:8,LEFT_RIGHT:9,RIGHT_LEFT:10,LEFT_SHOULDER:11,RIGHT_SHOULDER:12,LEFT_ELBOW:13,RIGHT_ELBOW:14,LEFT_WRIST:15,RIGHT_WRIST:16,LEFT_PINKY:17,RIGHT_PINKY:18,LEFT_INDEX:19,RIGHT_INDEX:20,LEFT_THUMB:21,RIGHT_THUMB:22,LEFT_HIP:23,RIGHT_HIP:24,LEFT_KNEE:25,RIGHT_KNEE:26,LEFT_ANKLE:27,RIGHT_ANKLE:28,LEFT_HEEL:29,RIGHT_HEEL:30,LEFT_FOOT_INDEX:31,RIGHT_FOOT_INDEX:32}),Ht("POSE_LANDMARKS_LEFT",{LEFT_EYE_INNER:1,LEFT_EYE:2,LEFT_EYE_OUTER:3,LEFT_EAR:7,LEFT_RIGHT:9,LEFT_SHOULDER:11,LEFT_ELBOW:13,LEFT_WRIST:15,LEFT_PINKY:17,LEFT_INDEX:19,LEFT_THUMB:21,LEFT_HIP:23,LEFT_KNEE:25,LEFT_ANKLE:27,LEFT_HEEL:29,LEFT_FOOT_INDEX:31}),Ht("POSE_LANDMARKS_RIGHT",{RIGHT_EYE_INNER:4,RIGHT_EYE:5,RIGHT_EYE_OUTER:6,RIGHT_EAR:8,RIGHT_LEFT:10,RIGHT_SHOULDER:12,RIGHT_ELBOW:14,RIGHT_WRIST:16,RIGHT_PINKY:18,RIGHT_INDEX:20,RIGHT_THUMB:22,RIGHT_HIP:24,RIGHT_KNEE:26,RIGHT_ANKLE:28,RIGHT_HEEL:30,RIGHT_FOOT_INDEX:32}),Ht("POSE_LANDMARKS_NEUTRAL",{NOSE:0}),Ht("VERSION","0.5.1635988162")}).call(bi);const ir=class{constructor(){Wt(this,"mediapipeMap_",new Map)}getVersion(n){switch(n){case"face_detection":return fi.VERSION;case"face_mesh":return mi.VERSION;case"hands":return di.VERSION;case"holistic":return hi.VERSION;case"objectron":return pi.VERSION;case"selfie_segmentation":return ai.VERSION;case"pose":return bi.VERSION;default:return""}}initialize(n){return new Promise(async(r,p)=>{if(n.mediaPipeModelConfigArray.length==0){p("no model was selected");return}for(let G=0;G<n.mediaPipeModelConfigArray.length;G++){const S=n.mediaPipeModelConfigArray[G];if(this.mediapipeMap_.has(S.modelType)){p("setting same type is not supported");return}if(typeof S.listener!="function"){p(`[${S.modelType}] ResultsListener must be provided`);return}let H;switch(S.modelType){case"face_mesh":H=new mi.FaceMesh({locateFile:(w,E)=>(S.assetsUri||ir.defaultAssetsBaseUrl+"face_mesh/"+this.getVersion("face_mesh"))+"/"+w});break;case"face_detection":H=new fi.FaceDetection({locateFile:(w,E)=>(S.assetsUri||ir.defaultAssetsBaseUrl+"face_detection/"+this.getVersion("face_detection"))+"/"+w});break;case"hands":H=new di.Hands({locateFile:(w,E)=>(S.assetsUri||ir.defaultAssetsBaseUrl+"hands/"+this.getVersion("hands"))+"/"+w});break;case"holistic":H=new hi.Holistic({locateFile:(w,E)=>(S.assetsUri||ir.defaultAssetsBaseUrl+"holistic/"+this.getVersion("holistic"))+"/"+w});break;case"objectron":H=new pi.Objectron({locateFile:(w,E)=>(S.assetsUri||ir.defaultAssetsBaseUrl+"objectron/"+this.getVersion("objectron"))+"/"+w});break;case"selfie_segmentation":H=new ai.SelfieSegmentation({locateFile:(w,E)=>(S.assetsUri||ir.defaultAssetsBaseUrl+"selfie_segmentation/"+this.getVersion("selfie_segmentation"))+"/"+w});break;case"pose":H=new bi.Pose({locateFile:(w,E)=>(S.assetsUri||ir.defaultAssetsBaseUrl+"pose/"+this.getVersion("pose"))+"/"+w});break;default:p("unknown model type");return}H.onResults(S.listener),S.options&&H.setOptions(S.options);try{await H.initialize(),this.mediapipeMap_.set(S.modelType,H)}catch(w){p(w);return}}r()})}close(n){return new Promise((r,p)=>{let G=[];if(n){let S=this.mediapipeMap_.get(n);if(S)this.mediapipeMap_.delete(n),G.push(S.close());else{p("model not exit");return}}else{for(const[S,H]of this.mediapipeMap_.entries())G.push(H.close());this.mediapipeMap_.clear()}Promise.all(G).then(()=>{r()}).catch(S=>{p(S)})})}send(n,r){return new Promise((p,G)=>{let S=[];if(r){let H=this.mediapipeMap_.get(r);if(H)S.push(H.send({image:n}));else{G("model not exit");return}}else for(const[H,w]of this.mediapipeMap_.entries())S.push(w.send({image:n}));Promise.all(S).then(()=>{p()}).catch(H=>{G(H)})})}reset(n){if(n){let r=this.mediapipeMap_.get(n);r&&typeof r.reset=="function"&&r.reset()}else for(const[r,p]of this.mediapipeMap_.entries())p&&typeof p.reset=="function"&&p.reset()}};let yi=ir;Wt(yi,"defaultAssetsBaseUrl","https://d3opqjmqzxf057.cloudfront.net/ml/mediapipe/");const lr=new WeakMap,vr=new WeakMap,rr=new WeakMap,gi=Symbol("anyProducer"),ds=Promise.resolve(),Zi=Symbol("listenerAdded"),vi=Symbol("listenerRemoved");let Gi=!1,io=!1;function wr(i){if(typeof i!="string"&&typeof i!="symbol"&&typeof i!="number")throw new TypeError("`eventName` must be a string, symbol, or number")}function Xi(i){if(typeof i!="function")throw new TypeError("listener must be a function")}function Fr(i,n){const r=vr.get(i);if(!!r.has(n))return r.get(n)}function Mr(i,n){const r=typeof n=="string"||typeof n=="symbol"||typeof n=="number"?n:gi,p=rr.get(i);if(!!p.has(r))return p.get(r)}function H2(i,n,r){const p=rr.get(i);if(p.has(n))for(const G of p.get(n))G.enqueue(r);if(p.has(gi)){const G=Promise.all([n,r]);for(const S of p.get(gi))S.enqueue(G)}}function hs(i,n){n=Array.isArray(n)?n:[n];let r=!1,p=()=>{},G=[];const S={enqueue(H){G.push(H),p()},finish(){r=!0,p()}};for(const H of n){let w=Mr(i,H);w||(w=new Set,rr.get(i).set(H,w)),w.add(S)}return{async next(){return G?G.length===0?r?(G=void 0,this.next()):(await new Promise(H=>{p=H}),this.next()):{done:!1,value:await G.shift()}:{done:!0}},async return(H){G=void 0;for(const w of n){const E=Mr(i,w);E&&(E.delete(S),E.size===0&&rr.get(i).delete(w))}return p(),arguments.length>0?{done:!0,value:await H}:{done:!0}},[Symbol.asyncIterator](){return this}}}function fs(i){if(i===void 0)return ms;if(!Array.isArray(i))throw new TypeError("`methodNames` must be an array of strings");for(const n of i)if(!ms.includes(n))throw typeof n!="string"?new TypeError("`methodNames` element must be a string"):new Error(`${n} is not Emittery method`);return i}const Yr=i=>i===Zi||i===vi;function Wi(i,n,r){if(Yr(n))try{Gi=!0,i.emit(n,r)}finally{Gi=!1}}class cr{static mixin(n,r){return r=fs(r),p=>{if(typeof p!="function")throw new TypeError("`target` must be function");for(const H of r)if(p.prototype[H]!==void 0)throw new Error(`The property \`${H}\` already exists on \`target\``);function G(){return Object.defineProperty(this,n,{enumerable:!1,value:new cr}),this[n]}Object.defineProperty(p.prototype,n,{enumerable:!1,get:G});const S=H=>function(...w){return this[n][H](...w)};for(const H of r)Object.defineProperty(p.prototype,H,{enumerable:!1,value:S(H)});return p}}static get isDebugEnabled(){var r,p;if(typeof((r=globalThis.process)==null?void 0:r.env)!="object")return io;const{env:n}=(p=globalThis.process)!=null?p:{env:{}};return n.DEBUG==="emittery"||n.DEBUG==="*"||io}static set isDebugEnabled(n){io=n}constructor(n={}){var r;lr.set(this,new Set),vr.set(this,new Map),rr.set(this,new Map),rr.get(this).set(gi,new Set),this.debug=(r=n.debug)!=null?r:{},this.debug.enabled===void 0&&(this.debug.enabled=!1),this.debug.logger||(this.debug.logger=(p,G,S,H)=>{try{H=JSON.stringify(H)}catch{H=`Object with the following keys failed to stringify: ${Object.keys(H).join(",")}`}(typeof S=="symbol"||typeof S=="number")&&(S=S.toString());const w=new Date,E=`${w.getHours()}:${w.getMinutes()}:${w.getSeconds()}.${w.getMilliseconds()}`;console.log(`[${E}][emittery:${p}][${G}] Event Name: ${S}
|
|
122
|
-
data: ${H}`)})}logIfDebugEnabled(n,r,p){(cr.isDebugEnabled||this.debug.enabled)&&this.debug.logger(n,this.debug.name,r,p)}on(n,r){Xi(r),n=Array.isArray(n)?n:[n];for(const p of n){wr(p);let G=Fr(this,p);G||(G=new Set,vr.get(this).set(p,G)),G.add(r),this.logIfDebugEnabled("subscribe",p,void 0),Yr(p)||Wi(this,Zi,{eventName:p,listener:r})}return this.off.bind(this,n,r)}off(n,r){Xi(r),n=Array.isArray(n)?n:[n];for(const p of n){wr(p);const G=Fr(this,p);G&&(G.delete(r),G.size===0&&vr.get(this).delete(p)),this.logIfDebugEnabled("unsubscribe",p,void 0),Yr(p)||Wi(this,vi,{eventName:p,listener:r})}}once(n){let r;const p=new Promise(G=>{r=this.on(n,S=>{r(),G(S)})});return p.off=r,p}events(n){n=Array.isArray(n)?n:[n];for(const r of n)wr(r);return hs(this,n)}async emit(n,r){var w;if(wr(n),Yr(n)&&!Gi)throw new TypeError("`eventName` cannot be meta event `listenerAdded` or `listenerRemoved`");this.logIfDebugEnabled("emit",n,r),H2(this,n,r);const p=(w=Fr(this,n))!=null?w:new Set,G=lr.get(this),S=[...p],H=Yr(n)?[]:[...G];await ds,await Promise.all([...S.map(async E=>{if(p.has(E))return E(r)}),...H.map(async E=>{if(G.has(E))return E(n,r)})])}async emitSerial(n,r){var w;if(wr(n),Yr(n)&&!Gi)throw new TypeError("`eventName` cannot be meta event `listenerAdded` or `listenerRemoved`");this.logIfDebugEnabled("emitSerial",n,r);const p=(w=Fr(this,n))!=null?w:new Set,G=lr.get(this),S=[...p],H=[...G];await ds;for(const E of S)p.has(E)&&await E(r);for(const E of H)G.has(E)&&await E(n,r)}onAny(n){return Xi(n),this.logIfDebugEnabled("subscribeAny",void 0,void 0),lr.get(this).add(n),Wi(this,Zi,{listener:n}),this.offAny.bind(this,n)}anyEvent(){return hs(this)}offAny(n){Xi(n),this.logIfDebugEnabled("unsubscribeAny",void 0,void 0),Wi(this,vi,{listener:n}),lr.get(this).delete(n)}clearListeners(n){n=Array.isArray(n)?n:[n];for(const r of n)if(this.logIfDebugEnabled("clear",r,void 0),typeof r=="string"||typeof r=="symbol"||typeof r=="number"){const p=Fr(this,r);p&&p.clear();const G=Mr(this,r);if(G){for(const S of G)S.finish();G.clear()}}else{lr.get(this).clear();for(const[p,G]of vr.get(this).entries())G.clear(),vr.get(this).delete(p);for(const[p,G]of rr.get(this).entries()){for(const S of G)S.finish();G.clear(),rr.get(this).delete(p)}}}listenerCount(n){var p,G,S,H,w,E;n=Array.isArray(n)?n:[n];let r=0;for(const et of n){if(typeof et=="string"){r+=lr.get(this).size+((G=(p=Fr(this,et))==null?void 0:p.size)!=null?G:0)+((H=(S=Mr(this,et))==null?void 0:S.size)!=null?H:0)+((E=(w=Mr(this))==null?void 0:w.size)!=null?E:0);continue}typeof et<"u"&&wr(et),r+=lr.get(this).size;for(const ct of vr.get(this).values())r+=ct.size;for(const ct of rr.get(this).values())r+=ct.size}return r}bindMethods(n,r){if(typeof n!="object"||n===null)throw new TypeError("`target` must be an object");r=fs(r);for(const p of r){if(n[p]!==void 0)throw new Error(`The property \`${p}\` already exists on \`target\``);Object.defineProperty(n,p,{enumerable:!1,value:this[p].bind(this)})}}}const ms=Object.getOwnPropertyNames(cr.prototype).filter(i=>i!=="constructor");Object.defineProperty(cr,"listenerAdded",{value:Zi,writable:!1,enumerable:!0,configurable:!1}),Object.defineProperty(cr,"listenerRemoved",{value:vi,writable:!1,enumerable:!0,configurable:!1});function oo(i,n){return globalThis[i]||(globalThis[i]=n),globalThis[i]}const Lr=oo("globals",{});var $n=(i=>(i.INIT="INIT",i.FORWARD="FORWARD",i.TERMINATE="TERMINATE",i.GLOBALS_SYNC="GLOBALS_SYNC",i))($n||{});function ps(i){return[ImageBitmap,ReadableStream,WritableStream].some(n=>i instanceof n)}let N2=0;function Vi(i,n,r,p,G){const S=N2++;return i.postMessage({id:S,type:n,functionName:r,args:p},p.filter(H=>ps(H))),new Promise(H=>{G==null||G.set(S,H)})}function Kr(i,n){const{id:r,type:p}=i,G=Array.isArray(n)?n:[n];postMessage({id:r,type:p,result:n},G.filter(S=>ps(S)))}const Ri=oo("workerized",{});function so(){return typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope}async function J2(){if(so())Kr({type:$n.GLOBALS_SYNC},Lr);else{const i=[];for(const n in Ri){const{worker:r,resolvers:p}=Ri[n].workerContext;r&&i.push(Vi(r,$n.GLOBALS_SYNC,"",[Lr],p))}await Promise.all(i)}}function jr(i,n){if(Array.isArray(n))n.splice(0,n.length);else if(typeof n=="object")for(const r in n)delete n[r];for(const r in i)Array.isArray(i[r])?(n[r]=[],jr(i[r],n[r])):typeof i[r]=="object"?(n[r]={},jr(i[r],n[r])):n[r]=i[r]}async function E2(i,n,r){const p=new n;if(p.addEventListener("message",async({data:G})=>{var S,H,w,E,et,ct,dt;switch(G.type){case $n.GLOBALS_SYNC:G.id?((H=r.get((S=G.id)!=null?S:-1))==null||H(G.result),r.delete((w=G.id)!=null?w:-1)):(jr((E=G.result)!=null?E:{},Lr),await J2());break;default:(ct=r.get((et=G.id)!=null?et:-1))==null||ct(G.result),r.delete((dt=G.id)!=null?dt:-1)}}),!await Vi(p,$n.INIT,"",[i.workerId,Lr],r))throw"Failed to instantiate workerized class";return p}let k2=0;async function U2(i,n,r){const p={},G=k2++;return Object.getOwnPropertyNames(i.prototype).forEach(S=>{p[S]=(...H)=>Vi(n,$n.FORWARD,S,H,r)}),p.terminate=async(...S)=>{const H=await Vi(n,$n.TERMINATE,"",S,r);return delete Ri[G],n.terminate(),p.workerContext.worker=void 0,H},p.workerContext={id:G,worker:n,resolvers:r},Ri[G]=p,p}async function B2(i,n){const r=new Map,p=await E2(i,n,r);return U2(i,p,r)}async function A2(i,n){const{functionName:r,args:p}=i;if(!n.instance)throw"instance not initialized";if(!r)throw"missing function name to call";if(!n.instance[r])throw`undefined function [${r}] in class ${n.instance.constructor.workerId}`;Kr(i,await n.instance[r](...p!=null?p:[]))}const bs=oo("registeredWorkers",{});function M2(i,n){n.workerId=i,so()&&(bs[n.workerId]=n)}function K2(i,n){if(!i.args)throw"Missing className while initializing worker";const[r,p]=i.args,G=bs[r];if(G)n.instance=new G(i.args.slice(1));else throw`unknown worker class ${r}`;jr(p,Lr),Kr(i,typeof n.instance!==void 0)}async function j2(i,n){const{args:r}=i;if(!n.instance)throw"instance not initialized";let p;n.instance.terminate&&(p=await n.instance.terminate(...r!=null?r:[])),Kr(i,p)}function O2(i){if(!i.args)throw"Missing globals while syncing";jr(i.args[0],Lr),Kr(i,{})}function z2(){const i={};onmessage=async n=>{const r=n.data;switch(r.type){case $n.INIT:K2(r,i);break;case $n.FORWARD:A2(r,i);break;case $n.TERMINATE:j2(r,i);break;case $n.GLOBALS_SYNC:O2(r);break}}}so()&&z2();class ys{static async createVideoReadable(n){return new Promise((r,p)=>{const G=document.createElement("video");let S=new AbortController,H=new AbortController;G.addEventListener("canplay",()=>{S.abort(),G.muted=!0,G.loop=!0,G.play().then(()=>{try{const w=G.captureStream(),E=new MediaStreamTrackProcessor(w.getVideoTracks()[0]);r(E.readable)}catch(w){p(w)}})},{once:!0,signal:H.signal}),G.addEventListener("error",w=>{H.abort(),p("loading error:"+w)},{once:!0,signal:S.signal}),G.crossOrigin="anonymous",G.src=n})}static async createImageCanvas(n){const p=await(await fetch(n)).blob();return await createImageBitmap(p)}}var P2=Object.defineProperty,_2=(i,n,r)=>n in i?P2(i,n,{enumerable:!0,configurable:!0,writable:!0,value:r}):i[n]=r,Q2=(i,n,r)=>(_2(i,typeof n!="symbol"?n+"":n,r),r);const D2="hlg.tokbox.com/prod/logging/vcp_webrtc",$2="https://",q2=1e4;let xi;const t1=new Uint8Array(16);function e1(){if(!xi&&(xi=typeof crypto<"u"&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto),!xi))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return xi(t1)}const Bn=[];for(let i=0;i<256;++i)Bn.push((i+256).toString(16).slice(1));function n1(i,n=0){return(Bn[i[n+0]]+Bn[i[n+1]]+Bn[i[n+2]]+Bn[i[n+3]]+"-"+Bn[i[n+4]]+Bn[i[n+5]]+"-"+Bn[i[n+6]]+Bn[i[n+7]]+"-"+Bn[i[n+8]]+Bn[i[n+9]]+"-"+Bn[i[n+10]]+Bn[i[n+11]]+Bn[i[n+12]]+Bn[i[n+13]]+Bn[i[n+14]]+Bn[i[n+15]]).toLowerCase()}const r1=typeof crypto<"u"&&crypto.randomUUID&&crypto.randomUUID.bind(crypto),gs={randomUUID:r1};function i1(i,n,r){if(gs.randomUUID&&!n&&!i)return gs.randomUUID();i=i||{};const p=i.random||(i.rng||e1)();if(p[6]=p[6]&15|64,p[8]=p[8]&63|128,n){r=r||0;for(let G=0;G<16;++G)n[r+G]=p[G];return n}return n1(p)}function lo(i,n){return globalThis[i]||(globalThis[i]=n),globalThis[i]}const ur=lo("globals",{});var Gr=(i=>(i.INIT="INIT",i.FORWARD="FORWARD",i.TERMINATE="TERMINATE",i.GLOBALS_SYNC="GLOBALS_SYNC",i))(Gr||{});function Zs(i){return[ImageBitmap,ReadableStream,WritableStream].some(n=>i instanceof n)}let o1=0;function s1(i,n,r,p,G){const S=o1++;return i.postMessage({id:S,type:n,functionName:r,args:p},p.filter(H=>Zs(H))),new Promise(H=>{G==null||G.set(S,H)})}function Or(i,n){const{id:r,type:p}=i,G=Array.isArray(n)?n:[n];postMessage({id:r,type:p,result:n},G.filter(S=>Zs(S)))}const vs=lo("workerized",{});function Gs(){return typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope}async function l1(){if(Gs())Or({type:Gr.GLOBALS_SYNC},ur);else{const i=[];for(const n in vs){const{worker:r,resolvers:p}=vs[n].workerContext;r&&i.push(s1(r,Gr.GLOBALS_SYNC,"",[ur],p))}await Promise.all(i)}}function Ii(i,n){if(Array.isArray(n))n.splice(0,n.length);else if(typeof n=="object")for(const r in n)delete n[r];for(const r in i)Array.isArray(i[r])?(n[r]=[],Ii(i[r],n[r])):typeof i[r]=="object"?(n[r]={},Ii(i[r],n[r])):n[r]=i[r]}async function c1(i,n){const{functionName:r,args:p}=i;if(!n.instance)throw"instance not initialized";if(!r)throw"missing function name to call";if(!n.instance[r])throw`undefined function [${r}] in class ${n.instance.constructor.workerId}`;Or(i,await n.instance[r](...p!=null?p:[]))}const u1=lo("registeredWorkers",{});function a1(i,n){if(!i.args)throw"Missing className while initializing worker";const[r,p]=i.args,G=u1[r];if(G)n.instance=new G(i.args.slice(1));else throw`unknown worker class ${r}`;Ii(p,ur),Or(i,typeof n.instance!==void 0)}async function d1(i,n){const{args:r}=i;if(!n.instance)throw"instance not initialized";let p;n.instance.terminate&&(p=await n.instance.terminate(...r!=null?r:[])),Or(i,p)}function h1(i){if(!i.args)throw"Missing globals while syncing";Ii(i.args[0],ur),Or(i,{})}function f1(){const i={};onmessage=async n=>{const r=n.data;switch(r.type){case Gr.INIT:a1(r,i);break;case Gr.FORWARD:c1(r,i);break;case Gr.TERMINATE:d1(r,i);break;case Gr.GLOBALS_SYNC:h1(r);break}}}Gs()&&f1();function m1(i,n){return ur[i]||(ur[i]=n),[()=>ur[i],async r=>{ur[i]=r,await l1()}]}function p1(i,n){return m1(i,n)}const[b1,m3]=p1("metadata");function co(){return b1()}class y1{constructor(n){Q2(this,"uuid",i1()),this.config=n}async send(n){var r,p,G;const{appId:S,sourceType:H}=(r=co())!=null?r:{};if(!S||!H)return"metadata missing";const w=new AbortController,E=setTimeout(()=>w.abort(),q2);return await((G=(p=this.config)==null?void 0:p.fetch)!=null?G:fetch)(this.getUrl(),{method:"POST",headers:this.getHeaders(),body:JSON.stringify(this.buildReport(n)),signal:w.signal}),clearTimeout(E),"success"}getUrl(){var n;let r=(n=co().proxyUrl)!=null?n:$2;return r+=(r.at(-1)==="/"?"":"/")+D2,r}getHeaders(){return{"Content-Type":"application/json"}}buildReport(n){const r=co();return{guid:this.uuid,...n,applicationId:r.appId,timestamp:Date.now(),proxyUrl:r.proxyUrl,source:r.sourceType}}}const g1="4.3.5";async function Xs(i){return new Promise(n=>{setTimeout(()=>{n()},i)})}var Ws=(i=>(i.PUSH="PUSH",i.POP="POP",i))(Ws||{});class Z1{constructor(n){Wt(this,"context");Wt(this,"extension");Wt(this,"queries",[]);Wt(this,"activeQuery");this.context=n,this.extension=n.getExtension("EXT_disjoint_timer_query_webgl2")}start(){}stop(){this.activeQuery&&this.context.endQuery(this.extension.TIME_ELAPSED_EXT)}pushContext(n){this.createQuery("PUSH",n)}popContext(n){this.createQuery("POP",n)}createQuery(n,r){this.activeQuery&&this.context.endQuery(this.extension.TIME_ELAPSED_EXT),this.activeQuery=this.context.createQuery(),this.context.beginQuery(this.extension.TIME_ELAPSED_EXT,this.activeQuery),this.queries.push({name:r,action:n,query:this.activeQuery})}async getResolvedQueries(){const n=(await Promise.all([...this.queries].map(r=>this.resolveQuery(r)))).filter(r=>r);for(let r=1;r<n.length;++r)n[r].timestamp+=n[r-1].duration+n[r-1].timestamp;return n}async resolveQuery(n){if(!await this.awaitQueryAvailable(n)){console.log("Unawaitable query",n);return}if(this.context.getParameter(this.extension.GPU_DISJOINT_EXT)){console.log("Disjointed query",n);return}return{...n,duration:this.context.getQueryParameter(n.query,this.context.QUERY_RESULT),timestamp:0}}async awaitQueryAvailable(n){for(let r=0;r<10;++r){if(this.context.getQueryParameter(n.query,this.context.QUERY_RESULT_AVAILABLE))return n;await Xs(200)}}}/* @license twgl.js 5.3.0 Copyright (c) 2015, Gregg Tavares All Rights Reserved.
|
|
122
|
+
data: ${H}`)})}logIfDebugEnabled(n,r,p){(cr.isDebugEnabled||this.debug.enabled)&&this.debug.logger(n,this.debug.name,r,p)}on(n,r){Xi(r),n=Array.isArray(n)?n:[n];for(const p of n){wr(p);let G=Fr(this,p);G||(G=new Set,vr.get(this).set(p,G)),G.add(r),this.logIfDebugEnabled("subscribe",p,void 0),Yr(p)||Wi(this,Zi,{eventName:p,listener:r})}return this.off.bind(this,n,r)}off(n,r){Xi(r),n=Array.isArray(n)?n:[n];for(const p of n){wr(p);const G=Fr(this,p);G&&(G.delete(r),G.size===0&&vr.get(this).delete(p)),this.logIfDebugEnabled("unsubscribe",p,void 0),Yr(p)||Wi(this,vi,{eventName:p,listener:r})}}once(n){let r;const p=new Promise(G=>{r=this.on(n,S=>{r(),G(S)})});return p.off=r,p}events(n){n=Array.isArray(n)?n:[n];for(const r of n)wr(r);return hs(this,n)}async emit(n,r){var w;if(wr(n),Yr(n)&&!Gi)throw new TypeError("`eventName` cannot be meta event `listenerAdded` or `listenerRemoved`");this.logIfDebugEnabled("emit",n,r),H2(this,n,r);const p=(w=Fr(this,n))!=null?w:new Set,G=lr.get(this),S=[...p],H=Yr(n)?[]:[...G];await ds,await Promise.all([...S.map(async E=>{if(p.has(E))return E(r)}),...H.map(async E=>{if(G.has(E))return E(n,r)})])}async emitSerial(n,r){var w;if(wr(n),Yr(n)&&!Gi)throw new TypeError("`eventName` cannot be meta event `listenerAdded` or `listenerRemoved`");this.logIfDebugEnabled("emitSerial",n,r);const p=(w=Fr(this,n))!=null?w:new Set,G=lr.get(this),S=[...p],H=[...G];await ds;for(const E of S)p.has(E)&&await E(r);for(const E of H)G.has(E)&&await E(n,r)}onAny(n){return Xi(n),this.logIfDebugEnabled("subscribeAny",void 0,void 0),lr.get(this).add(n),Wi(this,Zi,{listener:n}),this.offAny.bind(this,n)}anyEvent(){return hs(this)}offAny(n){Xi(n),this.logIfDebugEnabled("unsubscribeAny",void 0,void 0),Wi(this,vi,{listener:n}),lr.get(this).delete(n)}clearListeners(n){n=Array.isArray(n)?n:[n];for(const r of n)if(this.logIfDebugEnabled("clear",r,void 0),typeof r=="string"||typeof r=="symbol"||typeof r=="number"){const p=Fr(this,r);p&&p.clear();const G=Mr(this,r);if(G){for(const S of G)S.finish();G.clear()}}else{lr.get(this).clear();for(const[p,G]of vr.get(this).entries())G.clear(),vr.get(this).delete(p);for(const[p,G]of rr.get(this).entries()){for(const S of G)S.finish();G.clear(),rr.get(this).delete(p)}}}listenerCount(n){var p,G,S,H,w,E;n=Array.isArray(n)?n:[n];let r=0;for(const et of n){if(typeof et=="string"){r+=lr.get(this).size+((G=(p=Fr(this,et))==null?void 0:p.size)!=null?G:0)+((H=(S=Mr(this,et))==null?void 0:S.size)!=null?H:0)+((E=(w=Mr(this))==null?void 0:w.size)!=null?E:0);continue}typeof et<"u"&&wr(et),r+=lr.get(this).size;for(const ct of vr.get(this).values())r+=ct.size;for(const ct of rr.get(this).values())r+=ct.size}return r}bindMethods(n,r){if(typeof n!="object"||n===null)throw new TypeError("`target` must be an object");r=fs(r);for(const p of r){if(n[p]!==void 0)throw new Error(`The property \`${p}\` already exists on \`target\``);Object.defineProperty(n,p,{enumerable:!1,value:this[p].bind(this)})}}}const ms=Object.getOwnPropertyNames(cr.prototype).filter(i=>i!=="constructor");Object.defineProperty(cr,"listenerAdded",{value:Zi,writable:!1,enumerable:!0,configurable:!1}),Object.defineProperty(cr,"listenerRemoved",{value:vi,writable:!1,enumerable:!0,configurable:!1});function oo(i,n){return globalThis[i]||(globalThis[i]=n),globalThis[i]}const Lr=oo("globals",{});var $n=(i=>(i.INIT="INIT",i.FORWARD="FORWARD",i.TERMINATE="TERMINATE",i.GLOBALS_SYNC="GLOBALS_SYNC",i))($n||{});function ps(i){return[ImageBitmap,ReadableStream,WritableStream].some(n=>i instanceof n)}let N2=0;function Vi(i,n,r,p,G){const S=N2++;return i.postMessage({id:S,type:n,functionName:r,args:p},p.filter(H=>ps(H))),new Promise(H=>{G==null||G.set(S,H)})}function Kr(i,n){const{id:r,type:p}=i,G=Array.isArray(n)?n:[n];postMessage({id:r,type:p,result:n},G.filter(S=>ps(S)))}const Ri=oo("workerized",{});function so(){return typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope}async function J2(){if(so())Kr({type:$n.GLOBALS_SYNC},Lr);else{const i=[];for(const n in Ri){const{worker:r,resolvers:p}=Ri[n].workerContext;r&&i.push(Vi(r,$n.GLOBALS_SYNC,"",[Lr],p))}await Promise.all(i)}}function jr(i,n){if(Array.isArray(n))n.splice(0,n.length);else if(typeof n=="object")for(const r in n)delete n[r];for(const r in i)Array.isArray(i[r])?(n[r]=[],jr(i[r],n[r])):typeof i[r]=="object"?(n[r]={},jr(i[r],n[r])):n[r]=i[r]}async function E2(i,n,r){const p=new n;if(p.addEventListener("message",async({data:G})=>{var S,H,w,E,et,ct,dt;switch(G.type){case $n.GLOBALS_SYNC:G.id?((H=r.get((S=G.id)!=null?S:-1))==null||H(G.result),r.delete((w=G.id)!=null?w:-1)):(jr((E=G.result)!=null?E:{},Lr),await J2());break;default:(ct=r.get((et=G.id)!=null?et:-1))==null||ct(G.result),r.delete((dt=G.id)!=null?dt:-1)}}),!await Vi(p,$n.INIT,"",[i.workerId,Lr],r))throw"Failed to instantiate workerized class";return p}let k2=0;async function U2(i,n,r){const p={},G=k2++;return Object.getOwnPropertyNames(i.prototype).forEach(S=>{p[S]=(...H)=>Vi(n,$n.FORWARD,S,H,r)}),p.terminate=async(...S)=>{const H=await Vi(n,$n.TERMINATE,"",S,r);return delete Ri[G],n.terminate(),p.workerContext.worker=void 0,H},p.workerContext={id:G,worker:n,resolvers:r},Ri[G]=p,p}async function B2(i,n){const r=new Map,p=await E2(i,n,r);return U2(i,p,r)}async function A2(i,n){const{functionName:r,args:p}=i;if(!n.instance)throw"instance not initialized";if(!r)throw"missing function name to call";if(!n.instance[r])throw`undefined function [${r}] in class ${n.instance.constructor.workerId}`;Kr(i,await n.instance[r](...p!=null?p:[]))}const bs=oo("registeredWorkers",{});function M2(i,n){n.workerId=i,so()&&(bs[n.workerId]=n)}function K2(i,n){if(!i.args)throw"Missing className while initializing worker";const[r,p]=i.args,G=bs[r];if(G)n.instance=new G(i.args.slice(1));else throw`unknown worker class ${r}`;jr(p,Lr),Kr(i,typeof n.instance!==void 0)}async function j2(i,n){const{args:r}=i;if(!n.instance)throw"instance not initialized";let p;n.instance.terminate&&(p=await n.instance.terminate(...r!=null?r:[])),Kr(i,p)}function O2(i){if(!i.args)throw"Missing globals while syncing";jr(i.args[0],Lr),Kr(i,{})}function z2(){const i={};onmessage=async n=>{const r=n.data;switch(r.type){case $n.INIT:K2(r,i);break;case $n.FORWARD:A2(r,i);break;case $n.TERMINATE:j2(r,i);break;case $n.GLOBALS_SYNC:O2(r);break}}}so()&&z2();class ys{static async createVideoReadable(n){return new Promise((r,p)=>{const G=document.createElement("video");let S=new AbortController,H=new AbortController;G.addEventListener("canplay",()=>{S.abort(),G.muted=!0,G.loop=!0,G.play().then(()=>{try{const w=G.captureStream(),E=new MediaStreamTrackProcessor(w.getVideoTracks()[0]);r(E.readable)}catch(w){p(w)}})},{once:!0,signal:H.signal}),G.addEventListener("error",w=>{H.abort(),p("loading error:"+w)},{once:!0,signal:S.signal}),G.crossOrigin="anonymous",G.src=n})}static async createImageCanvas(n){const p=await(await fetch(n)).blob();return await createImageBitmap(p)}}var P2=Object.defineProperty,_2=(i,n,r)=>n in i?P2(i,n,{enumerable:!0,configurable:!0,writable:!0,value:r}):i[n]=r,Q2=(i,n,r)=>(_2(i,typeof n!="symbol"?n+"":n,r),r);const D2="hlg.tokbox.com/prod/logging/vcp_webrtc",$2="https://",q2=1e4;let xi;const t1=new Uint8Array(16);function e1(){if(!xi&&(xi=typeof crypto<"u"&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto),!xi))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return xi(t1)}const Bn=[];for(let i=0;i<256;++i)Bn.push((i+256).toString(16).slice(1));function n1(i,n=0){return(Bn[i[n+0]]+Bn[i[n+1]]+Bn[i[n+2]]+Bn[i[n+3]]+"-"+Bn[i[n+4]]+Bn[i[n+5]]+"-"+Bn[i[n+6]]+Bn[i[n+7]]+"-"+Bn[i[n+8]]+Bn[i[n+9]]+"-"+Bn[i[n+10]]+Bn[i[n+11]]+Bn[i[n+12]]+Bn[i[n+13]]+Bn[i[n+14]]+Bn[i[n+15]]).toLowerCase()}const r1=typeof crypto<"u"&&crypto.randomUUID&&crypto.randomUUID.bind(crypto),gs={randomUUID:r1};function i1(i,n,r){if(gs.randomUUID&&!n&&!i)return gs.randomUUID();i=i||{};const p=i.random||(i.rng||e1)();if(p[6]=p[6]&15|64,p[8]=p[8]&63|128,n){r=r||0;for(let G=0;G<16;++G)n[r+G]=p[G];return n}return n1(p)}function lo(i,n){return globalThis[i]||(globalThis[i]=n),globalThis[i]}const ur=lo("globals",{});var Gr=(i=>(i.INIT="INIT",i.FORWARD="FORWARD",i.TERMINATE="TERMINATE",i.GLOBALS_SYNC="GLOBALS_SYNC",i))(Gr||{});function Zs(i){return[ImageBitmap,ReadableStream,WritableStream].some(n=>i instanceof n)}let o1=0;function s1(i,n,r,p,G){const S=o1++;return i.postMessage({id:S,type:n,functionName:r,args:p},p.filter(H=>Zs(H))),new Promise(H=>{G==null||G.set(S,H)})}function Or(i,n){const{id:r,type:p}=i,G=Array.isArray(n)?n:[n];postMessage({id:r,type:p,result:n},G.filter(S=>Zs(S)))}const vs=lo("workerized",{});function Gs(){return typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope}async function l1(){if(Gs())Or({type:Gr.GLOBALS_SYNC},ur);else{const i=[];for(const n in vs){const{worker:r,resolvers:p}=vs[n].workerContext;r&&i.push(s1(r,Gr.GLOBALS_SYNC,"",[ur],p))}await Promise.all(i)}}function Ii(i,n){if(Array.isArray(n))n.splice(0,n.length);else if(typeof n=="object")for(const r in n)delete n[r];for(const r in i)Array.isArray(i[r])?(n[r]=[],Ii(i[r],n[r])):typeof i[r]=="object"?(n[r]={},Ii(i[r],n[r])):n[r]=i[r]}async function c1(i,n){const{functionName:r,args:p}=i;if(!n.instance)throw"instance not initialized";if(!r)throw"missing function name to call";if(!n.instance[r])throw`undefined function [${r}] in class ${n.instance.constructor.workerId}`;Or(i,await n.instance[r](...p!=null?p:[]))}const u1=lo("registeredWorkers",{});function a1(i,n){if(!i.args)throw"Missing className while initializing worker";const[r,p]=i.args,G=u1[r];if(G)n.instance=new G(i.args.slice(1));else throw`unknown worker class ${r}`;Ii(p,ur),Or(i,typeof n.instance!==void 0)}async function d1(i,n){const{args:r}=i;if(!n.instance)throw"instance not initialized";let p;n.instance.terminate&&(p=await n.instance.terminate(...r!=null?r:[])),Or(i,p)}function h1(i){if(!i.args)throw"Missing globals while syncing";Ii(i.args[0],ur),Or(i,{})}function f1(){const i={};onmessage=async n=>{const r=n.data;switch(r.type){case Gr.INIT:a1(r,i);break;case Gr.FORWARD:c1(r,i);break;case Gr.TERMINATE:d1(r,i);break;case Gr.GLOBALS_SYNC:h1(r);break}}}Gs()&&f1();function m1(i,n){return ur[i]||(ur[i]=n),[()=>ur[i],async r=>{ur[i]=r,await l1()}]}function p1(i,n){return m1(i,n)}const[b1,m3]=p1("metadata");function co(){return b1()}class y1{constructor(n){Q2(this,"uuid",i1()),this.config=n}async send(n){var r,p,G;const{appId:S,sourceType:H}=(r=co())!=null?r:{};if(!S||!H)return"metadata missing";const w=new AbortController,E=setTimeout(()=>w.abort(),q2);return await((G=(p=this.config)==null?void 0:p.fetch)!=null?G:fetch)(this.getUrl(),{method:"POST",headers:this.getHeaders(),body:JSON.stringify(this.buildReport(n)),signal:w.signal}),clearTimeout(E),"success"}getUrl(){var n;let r=(n=co().proxyUrl)!=null?n:$2;return r+=(r.at(-1)==="/"?"":"/")+D2,r}getHeaders(){return{"Content-Type":"application/json"}}buildReport(n){const r=co();return{guid:this.uuid,...n,applicationId:r.appId,timestamp:Date.now(),proxyUrl:r.proxyUrl,source:r.sourceType}}}const g1="4.3.6";async function Xs(i){return new Promise(n=>{setTimeout(()=>{n()},i)})}var Ws=(i=>(i.PUSH="PUSH",i.POP="POP",i))(Ws||{});class Z1{constructor(n){Wt(this,"context");Wt(this,"extension");Wt(this,"queries",[]);Wt(this,"activeQuery");this.context=n,this.extension=n.getExtension("EXT_disjoint_timer_query_webgl2")}start(){}stop(){this.activeQuery&&this.context.endQuery(this.extension.TIME_ELAPSED_EXT)}pushContext(n){this.createQuery("PUSH",n)}popContext(n){this.createQuery("POP",n)}createQuery(n,r){this.activeQuery&&this.context.endQuery(this.extension.TIME_ELAPSED_EXT),this.activeQuery=this.context.createQuery(),this.context.beginQuery(this.extension.TIME_ELAPSED_EXT,this.activeQuery),this.queries.push({name:r,action:n,query:this.activeQuery})}async getResolvedQueries(){const n=(await Promise.all([...this.queries].map(r=>this.resolveQuery(r)))).filter(r=>r);for(let r=1;r<n.length;++r)n[r].timestamp+=n[r-1].duration+n[r-1].timestamp;return n}async resolveQuery(n){if(!await this.awaitQueryAvailable(n)){console.log("Unawaitable query",n);return}if(this.context.getParameter(this.extension.GPU_DISJOINT_EXT)){console.log("Disjointed query",n);return}return{...n,duration:this.context.getQueryParameter(n.query,this.context.QUERY_RESULT),timestamp:0}}async awaitQueryAvailable(n){for(let r=0;r<10;++r){if(this.context.getQueryParameter(n.query,this.context.QUERY_RESULT_AVAILABLE))return n;await Xs(200)}}}/* @license twgl.js 5.3.0 Copyright (c) 2015, Gregg Tavares All Rights Reserved.
|
|
123
123
|
Available via the MIT license.
|
|
124
124
|
see: http://github.com/greggman/twgl.js for details */const uo=5120,zr=5121,ao=5122,ho=5123,fo=5124,mo=5125,po=5126,v1=32819,G1=32820,X1=33635,W1=5131,V1=33640,R1=35899,x1=35902,I1=36269,S1=34042,Vs={};{const i=Vs;i[uo]=Int8Array,i[zr]=Uint8Array,i[ao]=Int16Array,i[ho]=Uint16Array,i[fo]=Int32Array,i[mo]=Uint32Array,i[po]=Float32Array,i[v1]=Uint16Array,i[G1]=Uint16Array,i[X1]=Uint16Array,i[W1]=Uint16Array,i[V1]=Uint32Array,i[R1]=Uint32Array,i[x1]=Uint32Array,i[I1]=Uint32Array,i[S1]=Uint32Array}function bo(i){if(i instanceof Int8Array)return uo;if(i instanceof Uint8Array||i instanceof Uint8ClampedArray)return zr;if(i instanceof Int16Array)return ao;if(i instanceof Uint16Array)return ho;if(i instanceof Int32Array)return fo;if(i instanceof Uint32Array)return mo;if(i instanceof Float32Array)return po;throw new Error("unsupported typed array type")}function Rs(i){if(i===Int8Array)return uo;if(i===Uint8Array||i===Uint8ClampedArray)return zr;if(i===Int16Array)return ao;if(i===Uint16Array)return ho;if(i===Int32Array)return fo;if(i===Uint32Array)return mo;if(i===Float32Array)return po;throw new Error("unsupported typed array type")}function xs(i){const n=Vs[i];if(!n)throw new Error("unknown gl type");return n}const Si=typeof SharedArrayBuffer<"u"?function(n){return n&&n.buffer&&(n.buffer instanceof ArrayBuffer||n.buffer instanceof SharedArrayBuffer)}:function(n){return n&&n.buffer&&n.buffer instanceof ArrayBuffer};function Is(...i){console.error(...i)}const Ss=new Map;function Ti(i,n){if(!i||typeof i!="object")return!1;let r=Ss.get(n);r||(r=new WeakMap,Ss.set(n,r));let p=r.get(i);if(p===void 0){const G=Object.prototype.toString.call(i);p=G.substring(8,G.length-1)===n,r.set(i,p)}return p}function T1(i,n){return typeof WebGLBuffer<"u"&&Ti(n,"WebGLBuffer")}function w1(i,n){return typeof WebGLRenderbuffer<"u"&&Ti(n,"WebGLRenderbuffer")}function yo(i,n){return typeof WebGLTexture<"u"&&Ti(n,"WebGLTexture")}function F1(i,n){return typeof WebGLSampler<"u"&&Ti(n,"WebGLSampler")}const Ts=35044,Xr=34962,Y1=34963,L1=34660,C1=5120,H1=5121,N1=5122,J1=5123,E1=5124,k1=5125,ws=5126,Fs={attribPrefix:""};function U1(i,n,r,p,G){i.bindBuffer(n,r),i.bufferData(n,p,G||Ts)}function Ys(i,n,r,p){if(T1(i,n))return n;r=r||Xr;const G=i.createBuffer();return U1(i,r,G,n,p),G}function Ls(i){return i==="indices"}function B1(i){return i===Int8Array||i===Uint8Array}function A1(i){return i.length?i:i.data}const M1=/coord|texture/i,K1=/color|colour/i;function j1(i,n){let r;if(M1.test(i)?r=2:K1.test(i)?r=4:r=3,n%r>0)throw new Error(`Can not guess numComponents for attribute '${i}'. Tried ${r} but ${n} values is not evenly divisible by ${r}. You should specify it.`);return r}function O1(i,n,r){return i.numComponents||i.size||j1(n,r||A1(i).length)}function Cs(i,n){if(Si(i))return i;if(Si(i.data))return i.data;Array.isArray(i)&&(i={data:i});let r=i.type?go(i.type):void 0;return r||(Ls(n)?r=Uint16Array:r=Float32Array),new r(i.data)}function z1(i){return typeof i=="number"?i:i?Rs(i):ws}function go(i){return typeof i=="number"?xs(i):i||Float32Array}function P1(i,n){return{buffer:n.buffer,numValues:2*3*4,type:z1(n.type),arrayType:go(n.type)}}function _1(i,n){const r=n.data||n,p=go(n.type),G=r*p.BYTES_PER_ELEMENT,S=i.createBuffer();return i.bindBuffer(Xr,S),i.bufferData(Xr,G,n.drawType||Ts),{buffer:S,numValues:r,type:Rs(p),arrayType:p}}function Q1(i,n,r){const p=Cs(n,r);return{arrayType:p.constructor,buffer:Ys(i,p,void 0,n.drawType),type:bo(p),numValues:0}}function D1(i,n){const r={};return Object.keys(n).forEach(function(p){if(!Ls(p)){const G=n[p],S=G.attrib||G.name||G.attribName||Fs.attribPrefix+p;if(G.value){if(!Array.isArray(G.value)&&!Si(G.value))throw new Error("array.value is not array or typedarray");r[S]={value:G.value}}else{let H;G.buffer&&G.buffer instanceof WebGLBuffer?H=P1:typeof G=="number"||typeof G.data=="number"?H=_1:H=Q1;const{buffer:w,type:E,numValues:et,arrayType:ct}=H(i,G,p),dt=G.normalize!==void 0?G.normalize:B1(ct),Ft=O1(G,p,et);r[S]={buffer:w,numComponents:Ft,type:E,normalize:dt,stride:G.stride||0,offset:G.offset||0,divisor:G.divisor===void 0?void 0:G.divisor,drawType:G.drawType}}}}),i.bindBuffer(Xr,null),r}function $1(i,n){return n===C1||n===H1?1:n===N1||n===J1?2:n===E1||n===k1||n===ws?4:0}const Zo=["position","positions","a_position"];function q1(i,n){let r,p;for(p=0;p<Zo.length&&(r=Zo[p],!(r in n||(r=Fs.attribPrefix+r,r in n)));++p);p===Zo.length&&(r=Object.keys(n)[0]);const G=n[r];if(!G.buffer)return 1;i.bindBuffer(Xr,G.buffer);const S=i.getBufferParameter(Xr,L1);i.bindBuffer(Xr,null);const H=$1(i,G.type),w=S/H,E=G.numComponents||G.size,et=w/E;if(et%1!==0)throw new Error(`numComponents ${E} not correct for length ${length}`);return et}function tc(i,n,r){const p=D1(i,n),G=Object.assign({},r||{});G.attribs=Object.assign({},r?r.attribs:{},p);const S=n.indices;if(S){const H=Cs(S,"indices");G.indices=Ys(i,H,Y1),G.numElements=H.length,G.elementType=bo(H)}else G.numElements||(G.numElements=q1(i,G.attribs));return G}function Pr(i){return!!i.texStorage2D}const Hs=function(){const i={},n={};function r(p){const G=p.constructor.name;if(!i[G]){for(const S in p)if(typeof p[S]=="number"){const H=n[p[S]];n[p[S]]=H?`${H} | ${S}`:S}i[G]=!0}}return function(G,S){return r(G),n[S]||(typeof S=="number"?`0x${S.toString(16)}`:S)}}(),ar={textureColor:new Uint8Array([128,192,255,255]),textureOptions:{},crossOrigin:void 0},_r=Si,Ns=function(){let i;return function(){return i=i||(typeof document<"u"&&document.createElement?document.createElement("canvas").getContext("2d"):null),i}}(),Js=6406,er=6407,Gn=6408,Es=6409,ks=6410,Qr=6402,Us=34041,wi=33071,ec=9728,nc=9729,dr=3553,hr=34067,Wr=32879,Vr=35866,vo=34069,rc=34070,ic=34071,oc=34072,sc=34073,lc=34074,Go=10241,Xo=10240,Fi=10242,Yi=10243,Bs=32882,cc=33082,uc=33083,ac=33084,dc=33085,Wo=3317,As=3314,Ms=32878,Ks=3316,js=3315,Os=32877,hc=37443,fc=37441,mc=37440,pc=33321,bc=36756,yc=33325,gc=33326,Zc=33330,vc=33329,Gc=33338,Xc=33337,Wc=33340,Vc=33339,Rc=33323,xc=36757,Ic=33327,Sc=33328,Tc=33336,wc=33335,Fc=33332,Yc=33331,Lc=33334,Cc=33333,Hc=32849,Nc=35905,Jc=36194,Ec=36758,kc=35898,Uc=35901,Bc=34843,Ac=34837,Mc=36221,Kc=36239,jc=36215,Oc=36233,zc=36209,Pc=36227,_c=32856,Qc=35907,Dc=36759,$c=32855,qc=32854,tu=32857,eu=34842,nu=34836,ru=36220,iu=36238,ou=36975,su=36214,lu=36232,cu=36226,uu=36208,au=33189,du=33190,hu=36012,fu=36013,mu=35056,fr=5120,gn=5121,Li=5122,Cr=5123,Ci=5124,Rr=5125,Mn=5126,zs=32819,Ps=32820,_s=33635,qn=5131,Dr=36193,Vo=33640,pu=35899,bu=35902,yu=36269,gu=34042,Hi=33319,Hr=33320,Ni=6403,Nr=36244,Jr=36248,xr=36249;let Ro;function Ji(i){if(!Ro){const n={};n[Js]={textureFormat:Js,colorRenderable:!0,textureFilterable:!0,bytesPerElement:[1,2,2,4],type:[gn,qn,Dr,Mn]},n[Es]={textureFormat:Es,colorRenderable:!0,textureFilterable:!0,bytesPerElement:[1,2,2,4],type:[gn,qn,Dr,Mn]},n[ks]={textureFormat:ks,colorRenderable:!0,textureFilterable:!0,bytesPerElement:[2,4,4,8],type:[gn,qn,Dr,Mn]},n[er]={textureFormat:er,colorRenderable:!0,textureFilterable:!0,bytesPerElement:[3,6,6,12,2],type:[gn,qn,Dr,Mn,_s]},n[Gn]={textureFormat:Gn,colorRenderable:!0,textureFilterable:!0,bytesPerElement:[4,8,8,16,2,2],type:[gn,qn,Dr,Mn,zs,Ps]},n[Qr]={textureFormat:Qr,colorRenderable:!0,textureFilterable:!1,bytesPerElement:[2,4],type:[Rr,Cr]},n[pc]={textureFormat:Ni,colorRenderable:!0,textureFilterable:!0,bytesPerElement:[1],type:[gn]},n[bc]={textureFormat:Ni,colorRenderable:!1,textureFilterable:!0,bytesPerElement:[1],type:[fr]},n[yc]={textureFormat:Ni,colorRenderable:!1,textureFilterable:!0,bytesPerElement:[4,2],type:[Mn,qn]},n[gc]={textureFormat:Ni,colorRenderable:!1,textureFilterable:!1,bytesPerElement:[4],type:[Mn]},n[Zc]={textureFormat:Nr,colorRenderable:!0,textureFilterable:!1,bytesPerElement:[1],type:[gn]},n[vc]={textureFormat:Nr,colorRenderable:!0,textureFilterable:!1,bytesPerElement:[1],type:[fr]},n[Fc]={textureFormat:Nr,colorRenderable:!0,textureFilterable:!1,bytesPerElement:[2],type:[Cr]},n[Yc]={textureFormat:Nr,colorRenderable:!0,textureFilterable:!1,bytesPerElement:[2],type:[Li]},n[Lc]={textureFormat:Nr,colorRenderable:!0,textureFilterable:!1,bytesPerElement:[4],type:[Rr]},n[Cc]={textureFormat:Nr,colorRenderable:!0,textureFilterable:!1,bytesPerElement:[4],type:[Ci]},n[Rc]={textureFormat:Hi,colorRenderable:!0,textureFilterable:!0,bytesPerElement:[2],type:[gn]},n[xc]={textureFormat:Hi,colorRenderable:!1,textureFilterable:!0,bytesPerElement:[2],type:[fr]},n[Ic]={textureFormat:Hi,colorRenderable:!1,textureFilterable:!0,bytesPerElement:[8,4],type:[Mn,qn]},n[Sc]={textureFormat:Hi,colorRenderable:!1,textureFilterable:!1,bytesPerElement:[8],type:[Mn]},n[Tc]={textureFormat:Hr,colorRenderable:!0,textureFilterable:!1,bytesPerElement:[2],type:[gn]},n[wc]={textureFormat:Hr,colorRenderable:!0,textureFilterable:!1,bytesPerElement:[2],type:[fr]},n[Gc]={textureFormat:Hr,colorRenderable:!0,textureFilterable:!1,bytesPerElement:[4],type:[Cr]},n[Xc]={textureFormat:Hr,colorRenderable:!0,textureFilterable:!1,bytesPerElement:[4],type:[Li]},n[Wc]={textureFormat:Hr,colorRenderable:!0,textureFilterable:!1,bytesPerElement:[8],type:[Rr]},n[Vc]={textureFormat:Hr,colorRenderable:!0,textureFilterable:!1,bytesPerElement:[8],type:[Ci]},n[Hc]={textureFormat:er,colorRenderable:!0,textureFilterable:!0,bytesPerElement:[3],type:[gn]},n[Nc]={textureFormat:er,colorRenderable:!1,textureFilterable:!0,bytesPerElement:[3],type:[gn]},n[Jc]={textureFormat:er,colorRenderable:!0,textureFilterable:!0,bytesPerElement:[3,2],type:[gn,_s]},n[Ec]={textureFormat:er,colorRenderable:!1,textureFilterable:!0,bytesPerElement:[3],type:[fr]},n[kc]={textureFormat:er,colorRenderable:!1,textureFilterable:!0,bytesPerElement:[12,6,4],type:[Mn,qn,pu]},n[Uc]={textureFormat:er,colorRenderable:!1,textureFilterable:!0,bytesPerElement:[12,6,4],type:[Mn,qn,bu]},n[Bc]={textureFormat:er,colorRenderable:!1,textureFilterable:!0,bytesPerElement:[12,6],type:[Mn,qn]},n[Ac]={textureFormat:er,colorRenderable:!1,textureFilterable:!1,bytesPerElement:[12],type:[Mn]},n[Mc]={textureFormat:Jr,colorRenderable:!1,textureFilterable:!1,bytesPerElement:[3],type:[gn]},n[Kc]={textureFormat:Jr,colorRenderable:!1,textureFilterable:!1,bytesPerElement:[3],type:[fr]},n[jc]={textureFormat:Jr,colorRenderable:!1,textureFilterable:!1,bytesPerElement:[6],type:[Cr]},n[Oc]={textureFormat:Jr,colorRenderable:!1,textureFilterable:!1,bytesPerElement:[6],type:[Li]},n[zc]={textureFormat:Jr,colorRenderable:!1,textureFilterable:!1,bytesPerElement:[12],type:[Rr]},n[Pc]={textureFormat:Jr,colorRenderable:!1,textureFilterable:!1,bytesPerElement:[12],type:[Ci]},n[_c]={textureFormat:Gn,colorRenderable:!0,textureFilterable:!0,bytesPerElement:[4],type:[gn]},n[Qc]={textureFormat:Gn,colorRenderable:!0,textureFilterable:!0,bytesPerElement:[4],type:[gn]},n[Dc]={textureFormat:Gn,colorRenderable:!1,textureFilterable:!0,bytesPerElement:[4],type:[fr]},n[$c]={textureFormat:Gn,colorRenderable:!0,textureFilterable:!0,bytesPerElement:[4,2,4],type:[gn,Ps,Vo]},n[qc]={textureFormat:Gn,colorRenderable:!0,textureFilterable:!0,bytesPerElement:[4,2],type:[gn,zs]},n[tu]={textureFormat:Gn,colorRenderable:!0,textureFilterable:!0,bytesPerElement:[4],type:[Vo]},n[eu]={textureFormat:Gn,colorRenderable:!1,textureFilterable:!0,bytesPerElement:[16,8],type:[Mn,qn]},n[nu]={textureFormat:Gn,colorRenderable:!1,textureFilterable:!1,bytesPerElement:[16],type:[Mn]},n[ru]={textureFormat:xr,colorRenderable:!0,textureFilterable:!1,bytesPerElement:[4],type:[gn]},n[iu]={textureFormat:xr,colorRenderable:!0,textureFilterable:!1,bytesPerElement:[4],type:[fr]},n[ou]={textureFormat:xr,colorRenderable:!0,textureFilterable:!1,bytesPerElement:[4],type:[Vo]},n[su]={textureFormat:xr,colorRenderable:!0,textureFilterable:!1,bytesPerElement:[8],type:[Cr]},n[lu]={textureFormat:xr,colorRenderable:!0,textureFilterable:!1,bytesPerElement:[8],type:[Li]},n[cu]={textureFormat:xr,colorRenderable:!0,textureFilterable:!1,bytesPerElement:[16],type:[Ci]},n[uu]={textureFormat:xr,colorRenderable:!0,textureFilterable:!1,bytesPerElement:[16],type:[Rr]},n[au]={textureFormat:Qr,colorRenderable:!0,textureFilterable:!1,bytesPerElement:[2,4],type:[Cr,Rr]},n[du]={textureFormat:Qr,colorRenderable:!0,textureFilterable:!1,bytesPerElement:[4],type:[Rr]},n[hu]={textureFormat:Qr,colorRenderable:!0,textureFilterable:!1,bytesPerElement:[4],type:[Mn]},n[mu]={textureFormat:Us,colorRenderable:!0,textureFilterable:!1,bytesPerElement:[4],type:[gu]},n[fu]={textureFormat:Us,colorRenderable:!0,textureFilterable:!1,bytesPerElement:[4],type:[yu]},Object.keys(n).forEach(function(r){const p=n[r];p.bytesPerElementMap={},p.bytesPerElement.forEach(function(G,S){const H=p.type[S];p.bytesPerElementMap[H]=G})}),Ro=n}return Ro[i]}function Zu(i,n){const r=Ji(i);if(!r)throw"unknown internal format";const p=r.bytesPerElementMap[n];if(p===void 0)throw"unknown internal format";return p}function $r(i){const n=Ji(i);if(!n)throw"unknown internal format";return{format:n.textureFormat,type:n.type[0]}}function Qs(i){return(i&i-1)===0}function vu(i,n,r,p){if(!Pr(i))return Qs(n)&&Qs(r);const G=Ji(p);if(!G)throw"unknown internal format";return G.colorRenderable&&G.textureFilterable}function Gu(i){const n=Ji(i);if(!n)throw"unknown internal format";return n.textureFilterable}function Xu(i,n,r){return _r(n)?bo(n):r||gn}function Ei(i,n,r,p,G){if(G%1!==0)throw"can't guess dimensions";if(!r&&!p){const S=Math.sqrt(G/(n===hr?6:1));S%1===0?(r=S,p=S):(r=G,p=1)}else if(p){if(!r&&(r=G/p,r%1))throw"can't guess dimensions"}else if(p=G/r,p%1)throw"can't guess dimensions";return{width:r,height:p}}function Er(i,n){n.colorspaceConversion!==void 0&&i.pixelStorei(hc,n.colorspaceConversion),n.premultiplyAlpha!==void 0&&i.pixelStorei(fc,n.premultiplyAlpha),n.flipY!==void 0&&i.pixelStorei(mc,n.flipY)}function Ds(i){i.pixelStorei(Wo,4),Pr(i)&&(i.pixelStorei(As,0),i.pixelStorei(Ms,0),i.pixelStorei(Ks,0),i.pixelStorei(js,0),i.pixelStorei(Os,0))}function Wu(i,n,r,p){p.minMag&&(r.call(i,n,Go,p.minMag),r.call(i,n,Xo,p.minMag)),p.min&&r.call(i,n,Go,p.min),p.mag&&r.call(i,n,Xo,p.mag),p.wrap&&(r.call(i,n,Fi,p.wrap),r.call(i,n,Yi,p.wrap),(n===Wr||F1(i,n))&&r.call(i,n,Bs,p.wrap)),p.wrapR&&r.call(i,n,Bs,p.wrapR),p.wrapS&&r.call(i,n,Fi,p.wrapS),p.wrapT&&r.call(i,n,Yi,p.wrapT),p.minLod&&r.call(i,n,cc,p.minLod),p.maxLod&&r.call(i,n,uc,p.maxLod),p.baseLevel&&r.call(i,n,ac,p.baseLevel),p.maxLevel&&r.call(i,n,dc,p.maxLevel)}function $s(i,n,r){const p=r.target||dr;i.bindTexture(p,n),Wu(i,p,i.texParameteri,r)}function Vu(i){return i=i||ar.textureColor,_r(i)?i:new Uint8Array([i[0]*255,i[1]*255,i[2]*255,i[3]*255])}function xo(i,n,r,p,G,S){r=r||ar.textureOptions,S=S||Gn;const H=r.target||dr;if(p=p||r.width,G=G||r.height,i.bindTexture(H,n),vu(i,p,G,S))i.generateMipmap(H);else{const w=Gu(S)?nc:ec;i.texParameteri(H,Go,w),i.texParameteri(H,Xo,w),i.texParameteri(H,Fi,wi),i.texParameteri(H,Yi,wi)}}function qr(i){return i.auto===!0||i.auto===void 0&&i.level===void 0}function Io(i,n){return n=n||{},n.cubeFaceOrder||[vo,rc,ic,oc,sc,lc]}function So(i,n){const p=Io(i,n).map(function(G,S){return{face:G,ndx:S}});return p.sort(function(G,S){return G.face-S.face}),p}function qs(i,n,r,p){p=p||ar.textureOptions;const G=p.target||dr,S=p.level||0;let H=r.width,w=r.height;const E=p.internalFormat||p.format||Gn,et=$r(E),ct=p.format||et.format,dt=p.type||et.type;if(Er(i,p),i.bindTexture(G,n),G===hr){const Ft=r.width,Lt=r.height;let at,pt;if(Ft/6===Lt)at=Lt,pt=[0,0,1,0,2,0,3,0,4,0,5,0];else if(Lt/6===Ft)at=Ft,pt=[0,0,0,1,0,2,0,3,0,4,0,5];else if(Ft/3===Lt/2)at=Ft/3,pt=[0,0,1,0,2,0,0,1,1,1,2,1];else if(Ft/2===Lt/3)at=Ft/2,pt=[0,0,1,0,0,1,1,1,0,2,1,2];else throw"can't figure out cube map from element: "+(r.src?r.src:r.nodeName);const Mt=Ns();Mt?(Mt.canvas.width=at,Mt.canvas.height=at,H=at,w=at,So(i,p).forEach(function(Jt){const qt=pt[Jt.ndx*2+0]*at,P=pt[Jt.ndx*2+1]*at;Mt.drawImage(r,qt,P,at,at,0,0,at,at),i.texImage2D(Jt.face,S,E,ct,dt,Mt.canvas)}),Mt.canvas.width=1,Mt.canvas.height=1):typeof createImageBitmap<"u"&&(H=at,w=at,So(i,p).forEach(function(Jt){const qt=pt[Jt.ndx*2+0]*at,P=pt[Jt.ndx*2+1]*at;i.texImage2D(Jt.face,S,E,at,at,0,ct,dt,null),createImageBitmap(r,qt,P,at,at,{premultiplyAlpha:"none",colorSpaceConversion:"none"}).then(function(De){Er(i,p),i.bindTexture(G,n),i.texImage2D(Jt.face,S,E,ct,dt,De),qr(p)&&xo(i,n,p,H,w,E)})}))}else if(G===Wr||G===Vr){const Ft=Math.min(r.width,r.height),Lt=Math.max(r.width,r.height),at=Lt/Ft;if(at%1!==0)throw"can not compute 3D dimensions of element";const pt=r.width===Lt?1:0,Mt=r.height===Lt?1:0;i.pixelStorei(Wo,1),i.pixelStorei(As,r.width),i.pixelStorei(Ms,0),i.pixelStorei(Os,0),i.texImage3D(G,S,E,Ft,Ft,Ft,0,ct,dt,null);for(let Jt=0;Jt<at;++Jt){const qt=Jt*Ft*pt,P=Jt*Ft*Mt;i.pixelStorei(Ks,qt),i.pixelStorei(js,P),i.texSubImage3D(G,S,0,0,Jt,Ft,Ft,1,ct,dt,r)}Ds(i)}else i.texImage2D(G,S,E,ct,dt,r);qr(p)&&xo(i,n,p,H,w,E),$s(i,n,p)}function ti(){}function Ru(i){if(typeof document<"u"){const n=document.createElement("a");return n.href=i,n.hostname===location.hostname&&n.port===location.port&&n.protocol===location.protocol}else{const n=new URL(location.href).origin;return new URL(i,location.href).origin===n}}function xu(i,n){return n===void 0&&!Ru(i)?"anonymous":n}function Iu(i,n,r){r=r||ti;let p;if(n=n!==void 0?n:ar.crossOrigin,n=xu(i,n),typeof Image<"u"){p=new Image,n!==void 0&&(p.crossOrigin=n);const G=function(){p.removeEventListener("error",S),p.removeEventListener("load",H),p=null},S=function(){const E="couldn't load image: "+i;Is(E),r(E,p),G()},H=function(){r(null,p),G()};return p.addEventListener("error",S),p.addEventListener("load",H),p.src=i,p}else if(typeof ImageBitmap<"u"){let G,S;const H=function(){r(G,S)},w={};n&&(w.mode="cors"),fetch(i,w).then(function(E){if(!E.ok)throw E;return E.blob()}).then(function(E){return createImageBitmap(E,{premultiplyAlpha:"none",colorSpaceConversion:"none"})}).then(function(E){S=E,setTimeout(H)}).catch(function(E){G=E,setTimeout(H)}),p=null}return p}function tl(i){return typeof ImageBitmap<"u"&&i instanceof ImageBitmap||typeof ImageData<"u"&&i instanceof ImageData||typeof HTMLElement<"u"&&i instanceof HTMLElement}function To(i,n,r){return tl(i)?(setTimeout(function(){r(null,i)}),i):Iu(i,n,r)}function wo(i,n,r){r=r||ar.textureOptions;const p=r.target||dr;if(i.bindTexture(p,n),r.color===!1)return;const G=Vu(r.color);if(p===hr)for(let S=0;S<6;++S)i.texImage2D(vo+S,0,Gn,1,1,0,Gn,gn,G);else p===Wr||p===Vr?i.texImage3D(p,0,Gn,1,1,1,0,Gn,gn,G):i.texImage2D(p,0,Gn,1,1,0,Gn,gn,G)}function Su(i,n,r,p){return p=p||ti,r=r||ar.textureOptions,wo(i,n,r),r=Object.assign({},r),To(r.src,r.crossOrigin,function(S,H){S?p(S,n,H):(qs(i,n,H,r),p(null,n,H))})}function Tu(i,n,r,p){p=p||ti;const G=r.src;if(G.length!==6)throw"there must be 6 urls for a cubemap";const S=r.level||0,H=r.internalFormat||r.format||Gn,w=$r(H),E=r.format||w.format,et=r.type||gn,ct=r.target||dr;if(ct!==hr)throw"target must be TEXTURE_CUBE_MAP";wo(i,n,r),r=Object.assign({},r);let dt=6;const Ft=[],Lt=Io(i,r);let at;function pt(Mt){return function(Jt,qt){--dt,Jt?Ft.push(Jt):qt.width!==qt.height?Ft.push("cubemap face img is not a square: "+qt.src):(Er(i,r),i.bindTexture(ct,n),dt===5?Io().forEach(function(P){i.texImage2D(P,S,H,E,et,qt)}):i.texImage2D(Mt,S,H,E,et,qt),qr(r)&&i.generateMipmap(ct)),dt===0&&p(Ft.length?Ft:void 0,n,at)}}at=G.map(function(Mt,Jt){return To(Mt,r.crossOrigin,pt(Lt[Jt]))})}function wu(i,n,r,p){p=p||ti;const G=r.src,S=r.internalFormat||r.format||Gn,H=$r(S),w=r.format||H.format,E=r.type||gn,et=r.target||Vr;if(et!==Wr&&et!==Vr)throw"target must be TEXTURE_3D or TEXTURE_2D_ARRAY";wo(i,n,r),r=Object.assign({},r);let ct=G.length;const dt=[];let Ft;const Lt=r.level||0;let at=r.width,pt=r.height;const Mt=G.length;let Jt=!0;function qt(P){return function(De,an){if(--ct,De)dt.push(De);else{if(Er(i,r),i.bindTexture(et,n),Jt){Jt=!1,at=r.width||an.width,pt=r.height||an.height,i.texImage3D(et,Lt,S,at,pt,Mt,0,w,E,null);for(let Ve=0;Ve<Mt;++Ve)i.texSubImage3D(et,Lt,0,0,Ve,at,pt,1,w,E,an)}else{let Ve=an,Dt;(an.width!==at||an.height!==pt)&&(Dt=Ns(),Ve=Dt.canvas,Dt.canvas.width=at,Dt.canvas.height=pt,Dt.drawImage(an,0,0,at,pt)),i.texSubImage3D(et,Lt,0,0,P,at,pt,1,w,E,Ve),Dt&&Ve===Dt.canvas&&(Dt.canvas.width=0,Dt.canvas.height=0)}qr(r)&&i.generateMipmap(et)}ct===0&&p(dt.length?dt:void 0,n,Ft)}}Ft=G.map(function(P,De){return To(P,r.crossOrigin,qt(De))})}function Fu(i,n,r,p){p=p||ar.textureOptions;const G=p.target||dr;i.bindTexture(G,n);let S=p.width,H=p.height,w=p.depth;const E=p.level||0,et=p.internalFormat||p.format||Gn,ct=$r(et),dt=p.format||ct.format,Ft=p.type||Xu(i,r,ct.type);if(_r(r))r instanceof Uint8ClampedArray&&(r=new Uint8Array(r.buffer));else{const Mt=xs(Ft);r=new Mt(r)}const Lt=Zu(et,Ft),at=r.byteLength/Lt;if(at%1)throw"length wrong size for format: "+Hs(i,dt);let pt;if(G===Wr||G===Vr)if(!S&&!H&&!w){const Mt=Math.cbrt(at);if(Mt%1!==0)throw"can't guess cube size of array of numElements: "+at;S=Mt,H=Mt,w=Mt}else S&&(!H||!w)?(pt=Ei(i,G,H,w,at/S),H=pt.width,w=pt.height):H&&(!S||!w)?(pt=Ei(i,G,S,w,at/H),S=pt.width,w=pt.height):(pt=Ei(i,G,S,H,at/w),S=pt.width,H=pt.height);else pt=Ei(i,G,S,H,at),S=pt.width,H=pt.height;if(Ds(i),i.pixelStorei(Wo,p.unpackAlignment||1),Er(i,p),G===hr){const Mt=Lt/r.BYTES_PER_ELEMENT,Jt=at/6*Mt;So(i,p).forEach(qt=>{const P=Jt*qt.ndx,De=r.subarray(P,P+Jt);i.texImage2D(qt.face,E,et,S,H,0,dt,Ft,De)})}else G===Wr||G===Vr?i.texImage3D(G,E,et,S,H,w,0,dt,Ft,r):i.texImage2D(G,E,et,S,H,0,dt,Ft,r);return{width:S,height:H,depth:w,type:Ft}}function Yu(i,n,r){const p=r.target||dr;i.bindTexture(p,n);const G=r.level||0,S=r.internalFormat||r.format||Gn,H=$r(S),w=r.format||H.format,E=r.type||H.type;if(Er(i,r),p===hr)for(let et=0;et<6;++et)i.texImage2D(vo+et,G,S,r.width,r.height,0,w,E,null);else p===Wr||p===Vr?i.texImage3D(p,G,S,r.width,r.height,r.depth,0,w,E,null):i.texImage2D(p,G,S,r.width,r.height,0,w,E,null)}function el(i,n,r){r=r||ti,n=n||ar.textureOptions;const p=i.createTexture(),G=n.target||dr;let S=n.width||1,H=n.height||1;const w=n.internalFormat||Gn;i.bindTexture(G,p),G===hr&&(i.texParameteri(G,Fi,wi),i.texParameteri(G,Yi,wi));let E=n.src;if(E)if(typeof E=="function"&&(E=E(i,n)),typeof E=="string")Su(i,p,n,r);else if(_r(E)||Array.isArray(E)&&(typeof E[0]=="number"||Array.isArray(E[0])||_r(E[0]))){const et=Fu(i,p,E,n);S=et.width,H=et.height}else Array.isArray(E)&&(typeof E[0]=="string"||tl(E[0]))?G===hr?Tu(i,p,n,r):wu(i,p,n,r):(qs(i,p,E,n),S=E.width,H=E.height);else Yu(i,p,n);return qr(n)&&xo(i,p,n,S,H,w),$s(i,p,n),p}const Fo=Is;function nl(i){return typeof document<"u"&&document.getElementById?document.getElementById(i):null}const ki=33984,Ui=34962,Lu=34963,Cu=35713,Hu=35714,Nu=35632,Ju=35633,Eu=35981,rl=35718,ku=35721,Uu=35971,Bu=35382,Au=35396,Mu=35398,Ku=35392,ju=35395,Bi=5126,il=35664,ol=35665,sl=35666,Yo=5124,ll=35667,cl=35668,ul=35669,al=35670,dl=35671,hl=35672,fl=35673,ml=35674,pl=35675,bl=35676,Ou=35678,zu=35680,Pu=35679,_u=35682,Qu=35685,Du=35686,$u=35687,qu=35688,ta=35689,ea=35690,na=36289,ra=36292,ia=36293,Lo=5125,yl=36294,gl=36295,Zl=36296,oa=36298,sa=36299,la=36300,ca=36303,ua=36306,aa=36307,da=36308,ha=36311,Ai=3553,Mi=34067,Co=32879,Ki=35866,be={};function vl(i,n){return be[n].bindPoint}function fa(i,n){return function(r){i.uniform1f(n,r)}}function ma(i,n){return function(r){i.uniform1fv(n,r)}}function pa(i,n){return function(r){i.uniform2fv(n,r)}}function ba(i,n){return function(r){i.uniform3fv(n,r)}}function ya(i,n){return function(r){i.uniform4fv(n,r)}}function Gl(i,n){return function(r){i.uniform1i(n,r)}}function Xl(i,n){return function(r){i.uniform1iv(n,r)}}function Wl(i,n){return function(r){i.uniform2iv(n,r)}}function Vl(i,n){return function(r){i.uniform3iv(n,r)}}function Rl(i,n){return function(r){i.uniform4iv(n,r)}}function ga(i,n){return function(r){i.uniform1ui(n,r)}}function Za(i,n){return function(r){i.uniform1uiv(n,r)}}function va(i,n){return function(r){i.uniform2uiv(n,r)}}function Ga(i,n){return function(r){i.uniform3uiv(n,r)}}function Xa(i,n){return function(r){i.uniform4uiv(n,r)}}function Wa(i,n){return function(r){i.uniformMatrix2fv(n,!1,r)}}function Va(i,n){return function(r){i.uniformMatrix3fv(n,!1,r)}}function Ra(i,n){return function(r){i.uniformMatrix4fv(n,!1,r)}}function xa(i,n){return function(r){i.uniformMatrix2x3fv(n,!1,r)}}function Ia(i,n){return function(r){i.uniformMatrix3x2fv(n,!1,r)}}function Sa(i,n){return function(r){i.uniformMatrix2x4fv(n,!1,r)}}function Ta(i,n){return function(r){i.uniformMatrix4x2fv(n,!1,r)}}function wa(i,n){return function(r){i.uniformMatrix3x4fv(n,!1,r)}}function Fa(i,n){return function(r){i.uniformMatrix4x3fv(n,!1,r)}}function zn(i,n,r,p){const G=vl(i,n);return Pr(i)?function(S){let H,w;!S||yo(i,S)?(H=S,w=null):(H=S.texture,w=S.sampler),i.uniform1i(p,r),i.activeTexture(ki+r),i.bindTexture(G,H),i.bindSampler(r,w)}:function(S){i.uniform1i(p,r),i.activeTexture(ki+r),i.bindTexture(G,S)}}function Pn(i,n,r,p,G){const S=vl(i,n),H=new Int32Array(G);for(let w=0;w<G;++w)H[w]=r+w;return Pr(i)?function(w){i.uniform1iv(p,H),w.forEach(function(E,et){i.activeTexture(ki+H[et]);let ct,dt;yo(i,E)?(ct=E,dt=null):(ct=E.texture,dt=E.sampler),i.bindSampler(r,dt),i.bindTexture(S,ct)})}:function(w){i.uniform1iv(p,H),w.forEach(function(E,et){i.activeTexture(ki+H[et]),i.bindTexture(S,E)})}}be[Bi]={Type:Float32Array,size:4,setter:fa,arraySetter:ma},be[il]={Type:Float32Array,size:8,setter:pa,cols:2},be[ol]={Type:Float32Array,size:12,setter:ba,cols:3},be[sl]={Type:Float32Array,size:16,setter:ya,cols:4},be[Yo]={Type:Int32Array,size:4,setter:Gl,arraySetter:Xl},be[ll]={Type:Int32Array,size:8,setter:Wl,cols:2},be[cl]={Type:Int32Array,size:12,setter:Vl,cols:3},be[ul]={Type:Int32Array,size:16,setter:Rl,cols:4},be[Lo]={Type:Uint32Array,size:4,setter:ga,arraySetter:Za},be[yl]={Type:Uint32Array,size:8,setter:va,cols:2},be[gl]={Type:Uint32Array,size:12,setter:Ga,cols:3},be[Zl]={Type:Uint32Array,size:16,setter:Xa,cols:4},be[al]={Type:Uint32Array,size:4,setter:Gl,arraySetter:Xl},be[dl]={Type:Uint32Array,size:8,setter:Wl,cols:2},be[hl]={Type:Uint32Array,size:12,setter:Vl,cols:3},be[fl]={Type:Uint32Array,size:16,setter:Rl,cols:4},be[ml]={Type:Float32Array,size:32,setter:Wa,rows:2,cols:2},be[pl]={Type:Float32Array,size:48,setter:Va,rows:3,cols:3},be[bl]={Type:Float32Array,size:64,setter:Ra,rows:4,cols:4},be[Qu]={Type:Float32Array,size:32,setter:xa,rows:2,cols:3},be[Du]={Type:Float32Array,size:32,setter:Sa,rows:2,cols:4},be[$u]={Type:Float32Array,size:48,setter:Ia,rows:3,cols:2},be[qu]={Type:Float32Array,size:48,setter:wa,rows:3,cols:4},be[ta]={Type:Float32Array,size:64,setter:Ta,rows:4,cols:2},be[ea]={Type:Float32Array,size:64,setter:Fa,rows:4,cols:3},be[Ou]={Type:null,size:0,setter:zn,arraySetter:Pn,bindPoint:Ai},be[zu]={Type:null,size:0,setter:zn,arraySetter:Pn,bindPoint:Mi},be[Pu]={Type:null,size:0,setter:zn,arraySetter:Pn,bindPoint:Co},be[_u]={Type:null,size:0,setter:zn,arraySetter:Pn,bindPoint:Ai},be[na]={Type:null,size:0,setter:zn,arraySetter:Pn,bindPoint:Ki},be[ra]={Type:null,size:0,setter:zn,arraySetter:Pn,bindPoint:Ki},be[ia]={Type:null,size:0,setter:zn,arraySetter:Pn,bindPoint:Mi},be[oa]={Type:null,size:0,setter:zn,arraySetter:Pn,bindPoint:Ai},be[sa]={Type:null,size:0,setter:zn,arraySetter:Pn,bindPoint:Co},be[la]={Type:null,size:0,setter:zn,arraySetter:Pn,bindPoint:Mi},be[ca]={Type:null,size:0,setter:zn,arraySetter:Pn,bindPoint:Ki},be[ua]={Type:null,size:0,setter:zn,arraySetter:Pn,bindPoint:Ai},be[aa]={Type:null,size:0,setter:zn,arraySetter:Pn,bindPoint:Co},be[da]={Type:null,size:0,setter:zn,arraySetter:Pn,bindPoint:Mi},be[ha]={Type:null,size:0,setter:zn,arraySetter:Pn,bindPoint:Ki};function ji(i,n){return function(r){if(r.value)switch(i.disableVertexAttribArray(n),r.value.length){case 4:i.vertexAttrib4fv(n,r.value);break;case 3:i.vertexAttrib3fv(n,r.value);break;case 2:i.vertexAttrib2fv(n,r.value);break;case 1:i.vertexAttrib1fv(n,r.value);break;default:throw new Error("the length of a float constant value must be between 1 and 4!")}else i.bindBuffer(Ui,r.buffer),i.enableVertexAttribArray(n),i.vertexAttribPointer(n,r.numComponents||r.size,r.type||Bi,r.normalize||!1,r.stride||0,r.offset||0),i.vertexAttribDivisor&&i.vertexAttribDivisor(n,r.divisor||0)}}function mr(i,n){return function(r){if(r.value)if(i.disableVertexAttribArray(n),r.value.length===4)i.vertexAttrib4iv(n,r.value);else throw new Error("The length of an integer constant value must be 4!");else i.bindBuffer(Ui,r.buffer),i.enableVertexAttribArray(n),i.vertexAttribIPointer(n,r.numComponents||r.size,r.type||Yo,r.stride||0,r.offset||0),i.vertexAttribDivisor&&i.vertexAttribDivisor(n,r.divisor||0)}}function Oi(i,n){return function(r){if(r.value)if(i.disableVertexAttribArray(n),r.value.length===4)i.vertexAttrib4uiv(n,r.value);else throw new Error("The length of an unsigned integer constant value must be 4!");else i.bindBuffer(Ui,r.buffer),i.enableVertexAttribArray(n),i.vertexAttribIPointer(n,r.numComponents||r.size,r.type||Lo,r.stride||0,r.offset||0),i.vertexAttribDivisor&&i.vertexAttribDivisor(n,r.divisor||0)}}function Ho(i,n,r){const p=r.size,G=r.count;return function(S){i.bindBuffer(Ui,S.buffer);const H=S.size||S.numComponents||p,w=H/G,E=S.type||Bi,ct=be[E].size*H,dt=S.normalize||!1,Ft=S.offset||0,Lt=ct/G;for(let at=0;at<G;++at)i.enableVertexAttribArray(n+at),i.vertexAttribPointer(n+at,w,E,dt,ct,Ft+Lt*at),i.vertexAttribDivisor&&i.vertexAttribDivisor(n+at,S.divisor||0)}}const Yn={};Yn[Bi]={size:4,setter:ji},Yn[il]={size:8,setter:ji},Yn[ol]={size:12,setter:ji},Yn[sl]={size:16,setter:ji},Yn[Yo]={size:4,setter:mr},Yn[ll]={size:8,setter:mr},Yn[cl]={size:12,setter:mr},Yn[ul]={size:16,setter:mr},Yn[Lo]={size:4,setter:Oi},Yn[yl]={size:8,setter:Oi},Yn[gl]={size:12,setter:Oi},Yn[Zl]={size:16,setter:Oi},Yn[al]={size:4,setter:mr},Yn[dl]={size:8,setter:mr},Yn[hl]={size:12,setter:mr},Yn[fl]={size:16,setter:mr},Yn[ml]={size:4,setter:Ho,count:2},Yn[pl]={size:9,setter:Ho,count:3},Yn[bl]={size:16,setter:Ho,count:4};const Ya=/ERROR:\s*\d+:(\d+)/gi;function La(i,n="",r=0){const p=[...n.matchAll(Ya)],G=new Map(p.map((S,H)=>{const w=parseInt(S[1]),E=p[H+1],et=E?E.index:n.length,ct=n.substring(S.index,et);return[w-1,ct]}));return i.split(`
|
|
125
125
|
`).map((S,H)=>{const w=G.get(H);return`${H+1+r}: ${S}${w?`
|
|
@@ -454,4 +454,4 @@ void main() {
|
|
|
454
454
|
_texture_coord.y = 1. - texture_coord.y;
|
|
455
455
|
}
|
|
456
456
|
}
|
|
457
|
-
`;class $0 extends Ir{getFragmentShader(){return Q0}getVertexShader(){return D0}}class q0 extends Mo{constructor(r,p,G){super();Wt(this,"inputImage");this.context=r;const S={context:r,height:G,width:p};this.addStep({program:new $0({...S,disableFramebuffer:!0}),getUniforms:()=>({texture:mn(r,this.inputImage),invert_y:!0})})}setData(r){this.inputImage=r}}class t3{constructor(n){Wt(this,"resize");Wt(this,"canvas");Wt(this,"context");this.canvas=new OffscreenCanvas(0,0),this.context=this.canvas.getContext("webgl2"),this.canvas.width=n.width,this.canvas.height=n.height,this.resize=new q0(this.context,n.width,n.height)}resizeForeground(n,r){this.canvas.width=n,this.canvas.height=r,this.resize.resizeOutput(n,r)}async process(n){var r,p;return this.canvas.width=this.canvas.width,(r=this.resize)==null||r.setData(n),(p=this.resize)==null||p.run(),this.canvas}}class e3{constructor(n,r){Wt(this,"improveMaskSegmentation");Wt(this,"backgroundResizer");Wt(this,"backgroundImage");Wt(this,"backgroundVideo");Wt(this,"profiler");Wt(this,"activePipeline");Wt(this,"canvas");Wt(this,"options");Wt(this,"context");Wt(this,"virtualBGImage");this.id=n,this.canvas=new OffscreenCanvas(0,0),this.context=this.canvas.getContext("webgl2"),this.canvas.width=r.foregroundWidth,this.canvas.height=r.foregroundHeight,this.improveMaskSegmentation=new _0(this.context,r.maskWidth,r.maskHeight),this.backgroundImage=new kl(this.context),this.backgroundVideo=new w0(this.context),this.backgroundResizer=new t3({width:r.foregroundWidth,height:r.foregroundHeight})}setBackgroundOptions(n){switch(n.transformerType){case"BackgroundBlur":this.activePipeline=new T0(this.context,this.getBlurSize(n.radius));break;case"SilhouetteBlur":this.activePipeline=new L0(this.context,this.getBlurSize(n.radius));break;case"VideoBackground":this.activePipeline=this.backgroundVideo;break;case"VirtualBackground":this.activePipeline=this.backgroundImage;break}this.options=n}setFlickeringOptions(n){var r;(r=this.improveMaskSegmentation)==null||r.setOptions(n)}setVideoBGReadable(n){this.backgroundVideo.inputVideo=n}async setVirtualBGImage(n){this.virtualBGImage=n,this.backgroundImage.inputBackgroundImage=await this.backgroundResizer.process(n)}async process(n,r){var p,G,S,H,w,E,et;if(this.activePipeline&&n.width&&(r==null?void 0:r.width)){const ct=`[${this.id}] background-filter`;(p=this.profiler)==null||p.pushContext(ct);let dt=r;(((G=this.options)==null?void 0:G.selfieSegmentationType)&&((S=this.options)==null?void 0:S.selfieSegmentationType)==="PRECISE"||!((H=this.options)!=null&&H.selfieSegmentationType)&&this.activePipeline.preciseMaskEnabled)&&(this.improveMaskSegmentation.setId(this.id),this.improveMaskSegmentation.setProfiler(this.profiler),this.improveMaskSegmentation.setData(n,r),this.improveMaskSegmentation.run(),dt=this.improveMaskSegmentation.output),this.activePipeline.setId(this.id),this.activePipeline.setProfiler(this.profiler),(w=this.activePipeline)==null||w.setData(n,dt),(E=this.activePipeline)==null||E.run(),(et=this.profiler)==null||et.popContext(ct)}}async resizeForeground(n,r){var p;this.canvas.width=n,this.canvas.height=r,this.backgroundImage.resizeOutput(n,r),this.backgroundVideo.resizeOutput(n,r),this.backgroundResizer.resizeForeground(n,r),(p=this.activePipeline)==null||p.resizeOutput(n,r),this.virtualBGImage&&(this.backgroundImage.inputBackgroundImage=await this.backgroundResizer.process(this.virtualBGImage))}async profile(n){const r=new Z1(this.context);return this.profiler=r,r.start(),await Xs(n),this.profiler=void 0,r.stop(),r.getResolvedQueries()}getBlurSize(n=Ar.Low){switch(n){case Ar.Low:return 5;case Ar.High:return 12}return n}}class Bl{constructor(){Wt(this,"selfieSegmentation",new us);Wt(this,"backgroundFilter");Wt(this,"reporter",new y1);Wt(this,"previousDimensions",{width:0,height:0});Wt(this,"backgroundOptions")}async init(n,r){await this.selfieSegmentation.init(r.wasmAssetUriPath,r.tfliteAssetUriPath);const{width:p,height:G}=this.selfieSegmentation.getOutputDimensions();this.backgroundFilter=new e3(n,{foregroundWidth:1,foregroundHeight:1,maskWidth:p,maskHeight:G}),this.report({variation:"Create"})}async transform(n,r){var H,w,E,et;const p=(H=n.timestamp)!=null?H:0,G=await createImageBitmap(n),S=await this.selfieSegmentation.process(G);S?((G.width!==this.previousDimensions.width||G.height!==this.previousDimensions.height)&&(this.previousDimensions.width=G.width,this.previousDimensions.height=G.height,await((w=this.backgroundFilter)==null?void 0:w.resizeForeground(G.width,G.height))),await((E=this.backgroundFilter)==null?void 0:E.process(G,S)),n.close(),r.enqueue(new VideoFrame((et=this.backgroundFilter)==null?void 0:et.canvas,{timestamp:p,alpha:"discard"}))):r.enqueue(n)}async setBackgroundOptions(n){var r;this.backgroundOptions=n,await((r=this.backgroundFilter)==null?void 0:r.setBackgroundOptions(n)),this.report({variation:"Update"})}async setVideoBGReadable(n){var r;await((r=this.backgroundFilter)==null?void 0:r.setVideoBGReadable(n))}async setVirtualBGImage(n){var r;await((r=this.backgroundFilter)==null?void 0:r.setVirtualBGImage(n))}setFlickeringOptions(n){var r;(r=this.backgroundFilter)==null||r.setFlickeringOptions(n),this.report({variation:"Update"})}async profile(n){var r,p;return(p=(r=this.backgroundFilter)==null?void 0:r.profile(n))!=null?p:[]}getTransformerType(){var n,r;return(r=(n=this.backgroundOptions)==null?void 0:n.transformerType)!=null?r:"Undefined"}report(n){var r;this.reporter.send({version:g1,action:"MlTransformers",transformerType:(r=this.backgroundOptions)==null?void 0:r.transformerType,config:JSON.stringify(this.backgroundOptions),...n})}}const _o=class{constructor(){Wt(this,"backgroundTransformer",new Bl);Wt(this,"mediaProcessor",new V2);Wt(this,"rate",30);Wt(this,"resolveOnMediaProcessor");Wt(this,"eventsQueue",[])}async init(n,r){await this.backgroundTransformer.init(n,r),await this.mediaProcessor.setTransformers([this.backgroundTransformer]),this.mediaProcessor.setTrackExpectedRate(this.rate),this.mediaProcessor.onAny((p,G)=>{this.resolveOnMediaProcessor?(this.resolveOnMediaProcessor({name:p,data:G}),this.resolveOnMediaProcessor=void 0):this.eventsQueue.push({name:p,data:G})})}async onMediaProcessorEvent(){return await new Promise(n=>{this.eventsQueue.length>0?n(this.eventsQueue.shift()):this.resolveOnMediaProcessor=n})}async setTrackExpectedRate(n){this.rate=n,this.mediaProcessor.setTrackExpectedRate(n)}async transform(n,r){this.mediaProcessor.transform(n,r)}async setBackgroundOptions(n){var r;await((r=this.backgroundTransformer)==null?void 0:r.setBackgroundOptions(n))}setVideoBGReadable(n){this.backgroundTransformer.setVideoBGReadable(n)}async setVirtualBGImage(n){await this.backgroundTransformer.setVirtualBGImage(n)}async terminate(){await this.mediaProcessor.destroy()}setFlickeringOptions(n){this.backgroundTransformer.setFlickeringOptions(n)}setVonageMetadata(n){g2(n)}async profile(n){return JSON.stringify(await this.backgroundTransformer.profile(n))}};let zo=_o;(()=>{M2("ProcessorWorker",_o)})();const Al="dmFyIGlsPU9iamVjdC5kZWZpbmVQcm9wZXJ0eTt2YXIgb2w9KHEsWCx6KT0+WCBpbiBxP2lsKHEsWCx7ZW51bWVyYWJsZTohMCxjb25maWd1cmFibGU6ITAsd3JpdGFibGU6ITAsdmFsdWU6en0pOnFbWF09ejt2YXIgcD0ocSxYLHopPT4ob2wocSx0eXBlb2YgWCE9InN5bWJvbCI/WCsiIjpYLHopLHopOyhmdW5jdGlvbigpeyJ1c2Ugc3RyaWN0IjtmdW5jdGlvbiBxKHIsZSl7cmV0dXJuIGdsb2JhbFRoaXNbcl18fChnbG9iYWxUaGlzW3JdPWUpLGdsb2JhbFRoaXNbcl19Y29uc3QgWD1xKCJnbG9iYWxzIix7fSk7dmFyIHo9KHI9PihyLklOSVQ9IklOSVQiLHIuRk9SV0FSRD0iRk9SV0FSRCIsci5URVJNSU5BVEU9IlRFUk1JTkFURSIsci5HTE9CQUxTX1NZTkM9IkdMT0JBTFNfU1lOQyIscikpKHp8fHt9KTtmdW5jdGlvbiBwaShyKXtyZXR1cm5bSW1hZ2VCaXRtYXAsUmVhZGFibGVTdHJlYW0sV3JpdGFibGVTdHJlYW1dLnNvbWUoZT0+ciBpbnN0YW5jZW9mIGUpfWZ1bmN0aW9uIHplKHIsZSl7Y29uc3R7aWQ6dCx0eXBlOm59PXIsaT1BcnJheS5pc0FycmF5KGUpP2U6W2VdO3Bvc3RNZXNzYWdlKHtpZDp0LHR5cGU6bixyZXN1bHQ6ZX0saS5maWx0ZXIobz0+cGkobykpKX1xKCJ3b3JrZXJpemVkIix7fSk7ZnVuY3Rpb24gU3IoKXtyZXR1cm4gdHlwZW9mIFdvcmtlckdsb2JhbFNjb3BlPCJ1IiYmc2VsZiBpbnN0YW5jZW9mIFdvcmtlckdsb2JhbFNjb3BlfWZ1bmN0aW9uIFdlKHIsZSl7aWYoQXJyYXkuaXNBcnJheShlKSllLnNwbGljZSgwLGUubGVuZ3RoKTtlbHNlIGlmKHR5cGVvZiBlPT0ib2JqZWN0Iilmb3IoY29uc3QgdCBpbiBlKWRlbGV0ZSBlW3RdO2Zvcihjb25zdCB0IGluIHIpQXJyYXkuaXNBcnJheShyW3RdKT8oZVt0XT1bXSxXZShyW3RdLGVbdF0pKTp0eXBlb2Ygclt0XT09Im9iamVjdCI/KGVbdF09e30sV2Uoclt0XSxlW3RdKSk6ZVt0XT1yW3RdfWFzeW5jIGZ1bmN0aW9uIHlpKHIsZSl7Y29uc3R7ZnVuY3Rpb25OYW1lOnQsYXJnczpufT1yO2lmKCFlLmluc3RhbmNlKXRocm93Imluc3RhbmNlIG5vdCBpbml0aWFsaXplZCI7aWYoIXQpdGhyb3cibWlzc2luZyBmdW5jdGlvbiBuYW1lIHRvIGNhbGwiO2lmKCFlLmluc3RhbmNlW3RdKXRocm93YHVuZGVmaW5lZCBmdW5jdGlvbiBbJHt0fV0gaW4gY2xhc3MgJHtlLmluc3RhbmNlLmNvbnN0cnVjdG9yLndvcmtlcklkfWA7emUocixhd2FpdCBlLmluc3RhbmNlW3RdKC4uLm4hPW51bGw/bjpbXSkpfWNvbnN0IFJyPXEoInJlZ2lzdGVyZWRXb3JrZXJzIix7fSk7ZnVuY3Rpb24gX2kocixlKXtlLndvcmtlcklkPXIsU3IoKSYmKFJyW2Uud29ya2VySWRdPWUpfWZ1bmN0aW9uIHhpKHIsZSl7aWYoIXIuYXJncyl0aHJvdyJNaXNzaW5nIGNsYXNzTmFtZSB3aGlsZSBpbml0aWFsaXppbmcgd29ya2VyIjtjb25zdFt0LG5dPXIuYXJncyxpPVJyW3RdO2lmKGkpZS5pbnN0YW5jZT1uZXcgaShyLmFyZ3Muc2xpY2UoMSkpO2Vsc2UgdGhyb3dgdW5rbm93biB3b3JrZXIgY2xhc3MgJHt0fWA7V2UobixYKSx6ZShyLHR5cGVvZiBlLmluc3RhbmNlIT09dm9pZCAwKX1hc3luYyBmdW5jdGlvbiBnaShyLGUpe2NvbnN0e2FyZ3M6dH09cjtpZighZS5pbnN0YW5jZSl0aHJvdyJpbnN0YW5jZSBub3QgaW5pdGlhbGl6ZWQiO2xldCBuO2UuaW5zdGFuY2UudGVybWluYXRlJiYobj1hd2FpdCBlLmluc3RhbmNlLnRlcm1pbmF0ZSguLi50IT1udWxsP3Q6W10pKSx6ZShyLG4pfWZ1bmN0aW9uIGJpKHIpe2lmKCFyLmFyZ3MpdGhyb3ciTWlzc2luZyBnbG9iYWxzIHdoaWxlIHN5bmNpbmciO1dlKHIuYXJnc1swXSxYKSx6ZShyLHt9KX1mdW5jdGlvbiB2aSgpe2NvbnN0IHI9e307b25tZXNzYWdlPWFzeW5jIGU9Pntjb25zdCB0PWUuZGF0YTtzd2l0Y2godC50eXBlKXtjYXNlIHouSU5JVDp4aSh0LHIpO2JyZWFrO2Nhc2Ugei5GT1JXQVJEOnlpKHQscik7YnJlYWs7Y2FzZSB6LlRFUk1JTkFURTpnaSh0LHIpO2JyZWFrO2Nhc2Ugei5HTE9CQUxTX1NZTkM6YmkodCk7YnJlYWt9fX1TcigpJiZ2aSgpO3ZhciBFaT1PYmplY3QuZGVmaW5lUHJvcGVydHksVGk9KHIsZSx0KT0+ZSBpbiByP0VpKHIsZSx7ZW51bWVyYWJsZTohMCxjb25maWd1cmFibGU6ITAsd3JpdGFibGU6ITAsdmFsdWU6dH0pOnJbZV09dCxBPShyLGUsdCk9PihUaShyLHR5cGVvZiBlIT0ic3ltYm9sIj9lKyIiOmUsdCksdCk7Y2xhc3MgSnt9QShKLCJ1cGRhdGVzIix7dHJhbnNmb3JtZXJfbmV3OiJOZXcgdHJhbnNmb3JtZXIiLHRyYW5zZm9ybWVyX251bGw6Ik51bGwgdHJhbnNmb3JtZXIifSksQShKLCJlcnJvcnMiLHt0cmFuc2Zvcm1lcl9ub25lOiJObyB0cmFuc2Zvcm1lcnMgcHJvdmlkZWQiLHRyYW5zZm9ybWVyX3N0YXJ0OiJDYW5ub3Qgc3RhcnQgdHJhbnNmb3JtZXIiLHRyYW5zZm9ybWVyX3RyYW5zZm9ybToiQ2Fubm90IHRyYW5zZm9ybSBmcmFtZSIsdHJhbnNmb3JtZXJfZmx1c2g6IkNhbm5vdCBmbHVzaCB0cmFuc2Zvcm1lciIscmVhZGFibGVfbnVsbDoiUmVhZGFibGUgaXMgbnVsbCIsd3JpdGFibGVfbnVsbDoiV3JpdGFibGUgaXMgbnVsbCJ9KTtjb25zdCBlZT1uZXcgV2Vha01hcCxWZT1uZXcgV2Vha01hcCxSZT1uZXcgV2Vha01hcCxSdD1TeW1ib2woImFueVByb2R1Y2VyIiksSXI9UHJvbWlzZS5yZXNvbHZlKCksSGU9U3ltYm9sKCJsaXN0ZW5lckFkZGVkIiksWWU9U3ltYm9sKCJsaXN0ZW5lclJlbW92ZWQiKTtsZXQgSXQ9ITE7ZnVuY3Rpb24gYmUocil7aWYodHlwZW9mIHIhPSJzdHJpbmciJiZ0eXBlb2YgciE9InN5bWJvbCIpdGhyb3cgbmV3IFR5cGVFcnJvcigiZXZlbnROYW1lIG11c3QgYmUgYSBzdHJpbmcgb3IgYSBzeW1ib2wiKX1mdW5jdGlvbiBqZShyKXtpZih0eXBlb2YgciE9ImZ1bmN0aW9uIil0aHJvdyBuZXcgVHlwZUVycm9yKCJsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb24iKX1mdW5jdGlvbiB2ZShyLGUpe2NvbnN0IHQ9VmUuZ2V0KHIpO3JldHVybiB0LmhhcyhlKXx8dC5zZXQoZSxuZXcgU2V0KSx0LmdldChlKX1mdW5jdGlvbiBJZShyLGUpe2NvbnN0IHQ9dHlwZW9mIGU9PSJzdHJpbmcifHx0eXBlb2YgZT09InN5bWJvbCI/ZTpSdCxuPVJlLmdldChyKTtyZXR1cm4gbi5oYXModCl8fG4uc2V0KHQsbmV3IFNldCksbi5nZXQodCl9ZnVuY3Rpb24gQWkocixlLHQpe2NvbnN0IG49UmUuZ2V0KHIpO2lmKG4uaGFzKGUpKWZvcihjb25zdCBpIG9mIG4uZ2V0KGUpKWkuZW5xdWV1ZSh0KTtpZihuLmhhcyhSdCkpe2NvbnN0IGk9UHJvbWlzZS5hbGwoW2UsdF0pO2Zvcihjb25zdCBvIG9mIG4uZ2V0KFJ0KSlvLmVucXVldWUoaSl9fWZ1bmN0aW9uIEZyKHIsZSl7ZT1BcnJheS5pc0FycmF5KGUpP2U6W2VdO2xldCB0PSExLG49KCk9Pnt9LGk9W107Y29uc3Qgbz17ZW5xdWV1ZShzKXtpLnB1c2gocyksbigpfSxmaW5pc2goKXt0PSEwLG4oKX19O2Zvcihjb25zdCBzIG9mIGUpSWUocixzKS5hZGQobyk7cmV0dXJue2FzeW5jIG5leHQoKXtyZXR1cm4gaT9pLmxlbmd0aD09PTA/dD8oaT12b2lkIDAsdGhpcy5uZXh0KCkpOihhd2FpdCBuZXcgUHJvbWlzZShzPT57bj1zfSksdGhpcy5uZXh0KCkpOntkb25lOiExLHZhbHVlOmF3YWl0IGkuc2hpZnQoKX06e2RvbmU6ITB9fSxhc3luYyByZXR1cm4ocyl7aT12b2lkIDA7Zm9yKGNvbnN0IGEgb2YgZSlJZShyLGEpLmRlbGV0ZShvKTtyZXR1cm4gbigpLGFyZ3VtZW50cy5sZW5ndGg+MD97ZG9uZTohMCx2YWx1ZTphd2FpdCBzfTp7ZG9uZTohMH19LFtTeW1ib2wuYXN5bmNJdGVyYXRvcl0oKXtyZXR1cm4gdGhpc319fWZ1bmN0aW9uIFByKHIpe2lmKHI9PT12b2lkIDApcmV0dXJuIERyO2lmKCFBcnJheS5pc0FycmF5KHIpKXRocm93IG5ldyBUeXBlRXJyb3IoImBtZXRob2ROYW1lc2AgbXVzdCBiZSBhbiBhcnJheSBvZiBzdHJpbmdzIik7Zm9yKGNvbnN0IGUgb2YgcilpZighRHIuaW5jbHVkZXMoZSkpdGhyb3cgdHlwZW9mIGUhPSJzdHJpbmciP25ldyBUeXBlRXJyb3IoImBtZXRob2ROYW1lc2AgZWxlbWVudCBtdXN0IGJlIGEgc3RyaW5nIik6bmV3IEVycm9yKGAke2V9IGlzIG5vdCBFbWl0dGVyeSBtZXRob2RgKTtyZXR1cm4gcn1jb25zdCBGdD1yPT5yPT09SGV8fHI9PT1ZZTtjbGFzcyBmZXtzdGF0aWMgbWl4aW4oZSx0KXtyZXR1cm4gdD1Qcih0KSxuPT57aWYodHlwZW9mIG4hPSJmdW5jdGlvbiIpdGhyb3cgbmV3IFR5cGVFcnJvcigiYHRhcmdldGAgbXVzdCBiZSBmdW5jdGlvbiIpO2Zvcihjb25zdCBzIG9mIHQpaWYobi5wcm90b3R5cGVbc10hPT12b2lkIDApdGhyb3cgbmV3IEVycm9yKGBUaGUgcHJvcGVydHkgXGAke3N9XGAgYWxyZWFkeSBleGlzdHMgb24gXGB0YXJnZXRcYGApO2Z1bmN0aW9uIGkoKXtyZXR1cm4gT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsZSx7ZW51bWVyYWJsZTohMSx2YWx1ZTpuZXcgZmV9KSx0aGlzW2VdfU9iamVjdC5kZWZpbmVQcm9wZXJ0eShuLnByb3RvdHlwZSxlLHtlbnVtZXJhYmxlOiExLGdldDppfSk7Y29uc3Qgbz1zPT5mdW5jdGlvbiguLi5hKXtyZXR1cm4gdGhpc1tlXVtzXSguLi5hKX07Zm9yKGNvbnN0IHMgb2YgdClPYmplY3QuZGVmaW5lUHJvcGVydHkobi5wcm90b3R5cGUscyx7ZW51bWVyYWJsZTohMSx2YWx1ZTpvKHMpfSk7cmV0dXJuIG59fXN0YXRpYyBnZXQgaXNEZWJ1Z0VuYWJsZWQoKXtpZih0eXBlb2YgcHJvY2VzcyE9Im9iamVjdCIpcmV0dXJuIEl0O2NvbnN0e2VudjplfT1wcm9jZXNzfHx7ZW52Ont9fTtyZXR1cm4gZS5ERUJVRz09PSJlbWl0dGVyeSJ8fGUuREVCVUc9PT0iKiJ8fEl0fXN0YXRpYyBzZXQgaXNEZWJ1Z0VuYWJsZWQoZSl7SXQ9ZX1jb25zdHJ1Y3RvcihlPXt9KXtlZS5zZXQodGhpcyxuZXcgU2V0KSxWZS5zZXQodGhpcyxuZXcgTWFwKSxSZS5zZXQodGhpcyxuZXcgTWFwKSx0aGlzLmRlYnVnPWUuZGVidWd8fHt9LHRoaXMuZGVidWcuZW5hYmxlZD09PXZvaWQgMCYmKHRoaXMuZGVidWcuZW5hYmxlZD0hMSksdGhpcy5kZWJ1Zy5sb2dnZXJ8fCh0aGlzLmRlYnVnLmxvZ2dlcj0odCxuLGksbyk9Pnt0cnl7bz1KU09OLnN0cmluZ2lmeShvKX1jYXRjaHtvPWBPYmplY3Qgd2l0aCB0aGUgZm9sbG93aW5nIGtleXMgZmFpbGVkIHRvIHN0cmluZ2lmeTogJHtPYmplY3Qua2V5cyhvKS5qb2luKCIsIil9YH10eXBlb2YgaT09InN5bWJvbCImJihpPWkudG9TdHJpbmcoKSk7Y29uc3Qgcz1uZXcgRGF0ZSxhPWAke3MuZ2V0SG91cnMoKX06JHtzLmdldE1pbnV0ZXMoKX06JHtzLmdldFNlY29uZHMoKX0uJHtzLmdldE1pbGxpc2Vjb25kcygpfWA7Y29uc29sZS5sb2coYFske2F9XVtlbWl0dGVyeToke3R9XVske259XSBFdmVudCBOYW1lOiAke2l9CglkYXRhOiAke299YCl9KX1sb2dJZkRlYnVnRW5hYmxlZChlLHQsbil7KGZlLmlzRGVidWdFbmFibGVkfHx0aGlzLmRlYnVnLmVuYWJsZWQpJiZ0aGlzLmRlYnVnLmxvZ2dlcihlLHRoaXMuZGVidWcubmFtZSx0LG4pfW9uKGUsdCl7amUodCksZT1BcnJheS5pc0FycmF5KGUpP2U6W2VdO2Zvcihjb25zdCBuIG9mIGUpYmUobiksdmUodGhpcyxuKS5hZGQodCksdGhpcy5sb2dJZkRlYnVnRW5hYmxlZCgic3Vic2NyaWJlIixuLHZvaWQgMCksRnQobil8fHRoaXMuZW1pdChIZSx7ZXZlbnROYW1lOm4sbGlzdGVuZXI6dH0pO3JldHVybiB0aGlzLm9mZi5iaW5kKHRoaXMsZSx0KX1vZmYoZSx0KXtqZSh0KSxlPUFycmF5LmlzQXJyYXkoZSk/ZTpbZV07Zm9yKGNvbnN0IG4gb2YgZSliZShuKSx2ZSh0aGlzLG4pLmRlbGV0ZSh0KSx0aGlzLmxvZ0lmRGVidWdFbmFibGVkKCJ1bnN1YnNjcmliZSIsbix2b2lkIDApLEZ0KG4pfHx0aGlzLmVtaXQoWWUse2V2ZW50TmFtZTpuLGxpc3RlbmVyOnR9KX1vbmNlKGUpe3JldHVybiBuZXcgUHJvbWlzZSh0PT57Y29uc3Qgbj10aGlzLm9uKGUsaT0+e24oKSx0KGkpfSl9KX1ldmVudHMoZSl7ZT1BcnJheS5pc0FycmF5KGUpP2U6W2VdO2Zvcihjb25zdCB0IG9mIGUpYmUodCk7cmV0dXJuIEZyKHRoaXMsZSl9YXN5bmMgZW1pdChlLHQpe2JlKGUpLHRoaXMubG9nSWZEZWJ1Z0VuYWJsZWQoImVtaXQiLGUsdCksQWkodGhpcyxlLHQpO2NvbnN0IG49dmUodGhpcyxlKSxpPWVlLmdldCh0aGlzKSxvPVsuLi5uXSxzPUZ0KGUpP1tdOlsuLi5pXTthd2FpdCBJcixhd2FpdCBQcm9taXNlLmFsbChbLi4uby5tYXAoYXN5bmMgYT0+e2lmKG4uaGFzKGEpKXJldHVybiBhKHQpfSksLi4ucy5tYXAoYXN5bmMgYT0+e2lmKGkuaGFzKGEpKXJldHVybiBhKGUsdCl9KV0pfWFzeW5jIGVtaXRTZXJpYWwoZSx0KXtiZShlKSx0aGlzLmxvZ0lmRGVidWdFbmFibGVkKCJlbWl0U2VyaWFsIixlLHQpO2NvbnN0IG49dmUodGhpcyxlKSxpPWVlLmdldCh0aGlzKSxvPVsuLi5uXSxzPVsuLi5pXTthd2FpdCBJcjtmb3IoY29uc3QgYSBvZiBvKW4uaGFzKGEpJiZhd2FpdCBhKHQpO2Zvcihjb25zdCBhIG9mIHMpaS5oYXMoYSkmJmF3YWl0IGEoZSx0KX1vbkFueShlKXtyZXR1cm4gamUoZSksdGhpcy5sb2dJZkRlYnVnRW5hYmxlZCgic3Vic2NyaWJlQW55Iix2b2lkIDAsdm9pZCAwKSxlZS5nZXQodGhpcykuYWRkKGUpLHRoaXMuZW1pdChIZSx7bGlzdGVuZXI6ZX0pLHRoaXMub2ZmQW55LmJpbmQodGhpcyxlKX1hbnlFdmVudCgpe3JldHVybiBGcih0aGlzKX1vZmZBbnkoZSl7amUoZSksdGhpcy5sb2dJZkRlYnVnRW5hYmxlZCgidW5zdWJzY3JpYmVBbnkiLHZvaWQgMCx2b2lkIDApLHRoaXMuZW1pdChZZSx7bGlzdGVuZXI6ZX0pLGVlLmdldCh0aGlzKS5kZWxldGUoZSl9Y2xlYXJMaXN0ZW5lcnMoZSl7ZT1BcnJheS5pc0FycmF5KGUpP2U6W2VdO2Zvcihjb25zdCB0IG9mIGUpaWYodGhpcy5sb2dJZkRlYnVnRW5hYmxlZCgiY2xlYXIiLHQsdm9pZCAwKSx0eXBlb2YgdD09InN0cmluZyJ8fHR5cGVvZiB0PT0ic3ltYm9sIil7dmUodGhpcyx0KS5jbGVhcigpO2NvbnN0IG49SWUodGhpcyx0KTtmb3IoY29uc3QgaSBvZiBuKWkuZmluaXNoKCk7bi5jbGVhcigpfWVsc2V7ZWUuZ2V0KHRoaXMpLmNsZWFyKCk7Zm9yKGNvbnN0IG4gb2YgVmUuZ2V0KHRoaXMpLnZhbHVlcygpKW4uY2xlYXIoKTtmb3IoY29uc3QgbiBvZiBSZS5nZXQodGhpcykudmFsdWVzKCkpe2Zvcihjb25zdCBpIG9mIG4paS5maW5pc2goKTtuLmNsZWFyKCl9fX1saXN0ZW5lckNvdW50KGUpe2U9QXJyYXkuaXNBcnJheShlKT9lOltlXTtsZXQgdD0wO2Zvcihjb25zdCBuIG9mIGUpe2lmKHR5cGVvZiBuPT0ic3RyaW5nIil7dCs9ZWUuZ2V0KHRoaXMpLnNpemUrdmUodGhpcyxuKS5zaXplK0llKHRoaXMsbikuc2l6ZStJZSh0aGlzKS5zaXplO2NvbnRpbnVlfXR5cGVvZiBuPCJ1IiYmYmUobiksdCs9ZWUuZ2V0KHRoaXMpLnNpemU7Zm9yKGNvbnN0IGkgb2YgVmUuZ2V0KHRoaXMpLnZhbHVlcygpKXQrPWkuc2l6ZTtmb3IoY29uc3QgaSBvZiBSZS5nZXQodGhpcykudmFsdWVzKCkpdCs9aS5zaXplfXJldHVybiB0fWJpbmRNZXRob2RzKGUsdCl7aWYodHlwZW9mIGUhPSJvYmplY3QifHxlPT09bnVsbCl0aHJvdyBuZXcgVHlwZUVycm9yKCJgdGFyZ2V0YCBtdXN0IGJlIGFuIG9iamVjdCIpO3Q9UHIodCk7Zm9yKGNvbnN0IG4gb2YgdCl7aWYoZVtuXSE9PXZvaWQgMCl0aHJvdyBuZXcgRXJyb3IoYFRoZSBwcm9wZXJ0eSBcYCR7bn1cYCBhbHJlYWR5IGV4aXN0cyBvbiBcYHRhcmdldFxgYCk7T2JqZWN0LmRlZmluZVByb3BlcnR5KGUsbix7ZW51bWVyYWJsZTohMSx2YWx1ZTp0aGlzW25dLmJpbmQodGhpcyl9KX19fWNvbnN0IERyPU9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKGZlLnByb3RvdHlwZSkuZmlsdGVyKHI9PnIhPT0iY29uc3RydWN0b3IiKTtPYmplY3QuZGVmaW5lUHJvcGVydHkoZmUsImxpc3RlbmVyQWRkZWQiLHt2YWx1ZTpIZSx3cml0YWJsZTohMSxlbnVtZXJhYmxlOiEwLGNvbmZpZ3VyYWJsZTohMX0pLE9iamVjdC5kZWZpbmVQcm9wZXJ0eShmZSwibGlzdGVuZXJSZW1vdmVkIix7dmFsdWU6WWUsd3JpdGFibGU6ITEsZW51bWVyYWJsZTohMCxjb25maWd1cmFibGU6ITF9KTt2YXIgUHQ9ZmU7ZnVuY3Rpb24gd2kocil7cmV0dXJuIHR5cGVvZiByPT0ib2JqZWN0IiYmciE9PW51bGwmJiJtZXNzYWdlImluIHImJnR5cGVvZiByLm1lc3NhZ2U9PSJzdHJpbmcifWZ1bmN0aW9uIFNpKHIpe2lmKHdpKHIpKXJldHVybiByO3RyeXtyZXR1cm4gbmV3IEVycm9yKEpTT04uc3RyaW5naWZ5KHIpKX1jYXRjaHtyZXR1cm4gbmV3IEVycm9yKFN0cmluZyhyKSl9fWZ1bmN0aW9uIER0KHIpe3JldHVybiBTaShyKS5tZXNzYWdlfXZhciBSaT1PYmplY3QuZGVmaW5lUHJvcGVydHksSWk9KHIsZSx0KT0+ZSBpbiByP1JpKHIsZSx7ZW51bWVyYWJsZTohMCxjb25maWd1cmFibGU6ITAsd3JpdGFibGU6ITAsdmFsdWU6dH0pOnJbZV09dCxGaT0ocixlLHQpPT4oSWkocix0eXBlb2YgZSE9InN5bWJvbCI/ZSsiIjplLHQpLHQpO2NvbnN0IFBpPSJobGcudG9rYm94LmNvbS9wcm9kL2xvZ2dpbmcvdmNwX3dlYnJ0YyIsRGk9Imh0dHBzOi8vIixOaT0xZTQ7bGV0IFhlO2NvbnN0IE1pPW5ldyBVaW50OEFycmF5KDE2KTtmdW5jdGlvbiBVaSgpe2lmKCFYZSYmKFhlPXR5cGVvZiBjcnlwdG88InUiJiZjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzJiZjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzLmJpbmQoY3J5cHRvKSwhWGUpKXRocm93IG5ldyBFcnJvcigiY3J5cHRvLmdldFJhbmRvbVZhbHVlcygpIG5vdCBzdXBwb3J0ZWQuIFNlZSBodHRwczovL2dpdGh1Yi5jb20vdXVpZGpzL3V1aWQjZ2V0cmFuZG9tdmFsdWVzLW5vdC1zdXBwb3J0ZWQiKTtyZXR1cm4gWGUoTWkpfWNvbnN0IE09W107Zm9yKGxldCByPTA7cjwyNTY7KytyKU0ucHVzaCgocisyNTYpLnRvU3RyaW5nKDE2KS5zbGljZSgxKSk7ZnVuY3Rpb24ga2kocixlPTApe3JldHVybihNW3JbZSswXV0rTVtyW2UrMV1dK01bcltlKzJdXStNW3JbZSszXV0rIi0iK01bcltlKzRdXStNW3JbZSs1XV0rIi0iK01bcltlKzZdXStNW3JbZSs3XV0rIi0iK01bcltlKzhdXStNW3JbZSs5XV0rIi0iK01bcltlKzEwXV0rTVtyW2UrMTFdXStNW3JbZSsxMl1dK01bcltlKzEzXV0rTVtyW2UrMTRdXStNW3JbZSsxNV1dKS50b0xvd2VyQ2FzZSgpfWNvbnN0IENpPXR5cGVvZiBjcnlwdG88InUiJiZjcnlwdG8ucmFuZG9tVVVJRCYmY3J5cHRvLnJhbmRvbVVVSUQuYmluZChjcnlwdG8pLE5yPXtyYW5kb21VVUlEOkNpfTtmdW5jdGlvbiBPaShyLGUsdCl7aWYoTnIucmFuZG9tVVVJRCYmIWUmJiFyKXJldHVybiBOci5yYW5kb21VVUlEKCk7cj1yfHx7fTtjb25zdCBuPXIucmFuZG9tfHwoci5ybmd8fFVpKSgpO2lmKG5bNl09bls2XSYxNXw2NCxuWzhdPW5bOF0mNjN8MTI4LGUpe3Q9dHx8MDtmb3IobGV0IGk9MDtpPDE2OysraSllW3QraV09bltpXTtyZXR1cm4gZX1yZXR1cm4ga2kobil9ZnVuY3Rpb24gTnQocixlKXtyZXR1cm4gZ2xvYmFsVGhpc1tyXXx8KGdsb2JhbFRoaXNbcl09ZSksZ2xvYmFsVGhpc1tyXX1jb25zdCB0ZT1OdCgiZ2xvYmFscyIse30pO3ZhciBsZT0ocj0+KHIuSU5JVD0iSU5JVCIsci5GT1JXQVJEPSJGT1JXQVJEIixyLlRFUk1JTkFURT0iVEVSTUlOQVRFIixyLkdMT0JBTFNfU1lOQz0iR0xPQkFMU19TWU5DIixyKSkobGV8fHt9KTtmdW5jdGlvbiBNcihyKXtyZXR1cm5bSW1hZ2VCaXRtYXAsUmVhZGFibGVTdHJlYW0sV3JpdGFibGVTdHJlYW1dLnNvbWUoZT0+ciBpbnN0YW5jZW9mIGUpfWxldCBCaT0wO2Z1bmN0aW9uIExpKHIsZSx0LG4saSl7Y29uc3Qgbz1CaSsrO3JldHVybiByLnBvc3RNZXNzYWdlKHtpZDpvLHR5cGU6ZSxmdW5jdGlvbk5hbWU6dCxhcmdzOm59LG4uZmlsdGVyKHM9Pk1yKHMpKSksbmV3IFByb21pc2Uocz0+e2k9PW51bGx8fGkuc2V0KG8scyl9KX1mdW5jdGlvbiBGZShyLGUpe2NvbnN0e2lkOnQsdHlwZTpufT1yLGk9QXJyYXkuaXNBcnJheShlKT9lOltlXTtwb3N0TWVzc2FnZSh7aWQ6dCx0eXBlOm4scmVzdWx0OmV9LGkuZmlsdGVyKG89Pk1yKG8pKSl9Y29uc3QgVXI9TnQoIndvcmtlcml6ZWQiLHt9KTtmdW5jdGlvbiBrcigpe3JldHVybiB0eXBlb2YgV29ya2VyR2xvYmFsU2NvcGU8InUiJiZzZWxmIGluc3RhbmNlb2YgV29ya2VyR2xvYmFsU2NvcGV9YXN5bmMgZnVuY3Rpb24gR2koKXtpZihrcigpKUZlKHt0eXBlOmxlLkdMT0JBTFNfU1lOQ30sdGUpO2Vsc2V7Y29uc3Qgcj1bXTtmb3IoY29uc3QgZSBpbiBVcil7Y29uc3R7d29ya2VyOnQscmVzb2x2ZXJzOm59PVVyW2VdLndvcmtlckNvbnRleHQ7dCYmci5wdXNoKExpKHQsbGUuR0xPQkFMU19TWU5DLCIiLFt0ZV0sbikpfWF3YWl0IFByb21pc2UuYWxsKHIpfX1mdW5jdGlvbiBRZShyLGUpe2lmKEFycmF5LmlzQXJyYXkoZSkpZS5zcGxpY2UoMCxlLmxlbmd0aCk7ZWxzZSBpZih0eXBlb2YgZT09Im9iamVjdCIpZm9yKGNvbnN0IHQgaW4gZSlkZWxldGUgZVt0XTtmb3IoY29uc3QgdCBpbiByKUFycmF5LmlzQXJyYXkoclt0XSk/KGVbdF09W10sUWUoclt0XSxlW3RdKSk6dHlwZW9mIHJbdF09PSJvYmplY3QiPyhlW3RdPXt9LFFlKHJbdF0sZVt0XSkpOmVbdF09clt0XX1hc3luYyBmdW5jdGlvbiAkaShyLGUpe2NvbnN0e2Z1bmN0aW9uTmFtZTp0LGFyZ3M6bn09cjtpZighZS5pbnN0YW5jZSl0aHJvdyJpbnN0YW5jZSBub3QgaW5pdGlhbGl6ZWQiO2lmKCF0KXRocm93Im1pc3NpbmcgZnVuY3Rpb24gbmFtZSB0byBjYWxsIjtpZighZS5pbnN0YW5jZVt0XSl0aHJvd2B1bmRlZmluZWQgZnVuY3Rpb24gWyR7dH1dIGluIGNsYXNzICR7ZS5pbnN0YW5jZS5jb25zdHJ1Y3Rvci53b3JrZXJJZH1gO0ZlKHIsYXdhaXQgZS5pbnN0YW5jZVt0XSguLi5uIT1udWxsP246W10pKX1jb25zdCB6aT1OdCgicmVnaXN0ZXJlZFdvcmtlcnMiLHt9KTtmdW5jdGlvbiBXaShyLGUpe2lmKCFyLmFyZ3MpdGhyb3ciTWlzc2luZyBjbGFzc05hbWUgd2hpbGUgaW5pdGlhbGl6aW5nIHdvcmtlciI7Y29uc3RbdCxuXT1yLmFyZ3MsaT16aVt0XTtpZihpKWUuaW5zdGFuY2U9bmV3IGkoci5hcmdzLnNsaWNlKDEpKTtlbHNlIHRocm93YHVua25vd24gd29ya2VyIGNsYXNzICR7dH1gO1FlKG4sdGUpLEZlKHIsdHlwZW9mIGUuaW5zdGFuY2UhPT12b2lkIDApfWFzeW5jIGZ1bmN0aW9uIFZpKHIsZSl7Y29uc3R7YXJnczp0fT1yO2lmKCFlLmluc3RhbmNlKXRocm93Imluc3RhbmNlIG5vdCBpbml0aWFsaXplZCI7bGV0IG47ZS5pbnN0YW5jZS50ZXJtaW5hdGUmJihuPWF3YWl0IGUuaW5zdGFuY2UudGVybWluYXRlKC4uLnQhPW51bGw/dDpbXSkpLEZlKHIsbil9ZnVuY3Rpb24gSGkocil7aWYoIXIuYXJncyl0aHJvdyJNaXNzaW5nIGdsb2JhbHMgd2hpbGUgc3luY2luZyI7UWUoci5hcmdzWzBdLHRlKSxGZShyLHt9KX1mdW5jdGlvbiBZaSgpe2NvbnN0IHI9e307b25tZXNzYWdlPWFzeW5jIGU9Pntjb25zdCB0PWUuZGF0YTtzd2l0Y2godC50eXBlKXtjYXNlIGxlLklOSVQ6V2kodCxyKTticmVhaztjYXNlIGxlLkZPUldBUkQ6JGkodCxyKTticmVhaztjYXNlIGxlLlRFUk1JTkFURTpWaSh0LHIpO2JyZWFrO2Nhc2UgbGUuR0xPQkFMU19TWU5DOkhpKHQpO2JyZWFrfX19a3IoKSYmWWkoKTtmdW5jdGlvbiBqaShyLGUpe3JldHVybiB0ZVtyXXx8KHRlW3JdPWUpLFsoKT0+dGVbcl0sYXN5bmMgdD0+e3RlW3JdPXQsYXdhaXQgR2koKX1dfWZ1bmN0aW9uIFhpKHIsZSl7cmV0dXJuIGppKHIsZSl9Y29uc3RbUWksS2ldPVhpKCJtZXRhZGF0YSIpO2Z1bmN0aW9uIHFpKHIpe0tpKHIpfWZ1bmN0aW9uIE10KCl7cmV0dXJuIFFpKCl9Y2xhc3MgVXR7Y29uc3RydWN0b3IoZSl7RmkodGhpcywidXVpZCIsT2koKSksdGhpcy5jb25maWc9ZX1hc3luYyBzZW5kKGUpe3ZhciB0LG4saTtjb25zdHthcHBJZDpvLHNvdXJjZVR5cGU6c309KHQ9TXQoKSkhPW51bGw/dDp7fTtpZighb3x8IXMpcmV0dXJuIm1ldGFkYXRhIG1pc3NpbmciO2NvbnN0IGE9bmV3IEFib3J0Q29udHJvbGxlcix1PXNldFRpbWVvdXQoKCk9PmEuYWJvcnQoKSxOaSk7cmV0dXJuIGF3YWl0KChpPShuPXRoaXMuY29uZmlnKT09bnVsbD92b2lkIDA6bi5mZXRjaCkhPW51bGw/aTpmZXRjaCkodGhpcy5nZXRVcmwoKSx7bWV0aG9kOiJQT1NUIixoZWFkZXJzOnRoaXMuZ2V0SGVhZGVycygpLGJvZHk6SlNPTi5zdHJpbmdpZnkodGhpcy5idWlsZFJlcG9ydChlKSksc2lnbmFsOmEuc2lnbmFsfSksY2xlYXJUaW1lb3V0KHUpLCJzdWNjZXNzIn1nZXRVcmwoKXt2YXIgZTtsZXQgdD0oZT1NdCgpLnByb3h5VXJsKSE9bnVsbD9lOkRpO3JldHVybiB0Kz0odC5hdCgtMSk9PT0iLyI/IiI6Ii8iKStQaSx0fWdldEhlYWRlcnMoKXtyZXR1cm57IkNvbnRlbnQtVHlwZSI6ImFwcGxpY2F0aW9uL2pzb24ifX1idWlsZFJlcG9ydChlKXtjb25zdCB0PU10KCk7cmV0dXJue2d1aWQ6dGhpcy51dWlkLC4uLmUsYXBwbGljYXRpb25JZDp0LmFwcElkLHRpbWVzdGFtcDpEYXRlLm5vdygpLHByb3h5VXJsOnQucHJveHlVcmwsc291cmNlOnQuc291cmNlVHlwZX19fWNvbnN0IEtlPSIyLjAuMiI7Y2xhc3MgSml7Y29uc3RydWN0b3IoZSl7QSh0aGlzLCJmcmFtZVRyYW5zZm9ybWVkQ291bnQiLDApLEEodGhpcywiZnJhbWVGcm9tU291cmNlQ291bnQiLDApLEEodGhpcywic3RhcnRBdCIsMCksQSh0aGlzLCJyZXBvcnRlciIpLHRoaXMuY29uZmlnPWUsdGhpcy5yZXBvcnRlcj1uZXcgVXQoZSl9YXN5bmMgb25GcmFtZUZyb21Tb3VyY2UoKXt0aGlzLmZyYW1lRnJvbVNvdXJjZUNvdW50Kyt9Z2V0IGZwcygpe2NvbnN0e3N0YXJ0QXQ6ZSxmcmFtZUZyb21Tb3VyY2VDb3VudDp0fT10aGlzLG49KERhdGUubm93KCktZSkvMWUzO3JldHVybiB0L259YXN5bmMgb25GcmFtZVRyYW5zZm9ybWVkKGU9e30sdD0hMSl7dGhpcy5zdGFydEF0PT09MCYmKHRoaXMuc3RhcnRBdD1EYXRlLm5vdygpKSx0aGlzLmZyYW1lVHJhbnNmb3JtZWRDb3VudCsrO2NvbnN0e3N0YXJ0QXQ6bixmcmFtZVRyYW5zZm9ybWVkQ291bnQ6aSxmcmFtZUZyb21Tb3VyY2VDb3VudDpvfT10aGlzLHM9RGF0ZS5ub3coKSxhPShzLW4pLzFlMyx1PWkvYSxmPW8vYTtyZXR1cm4gdHx8dGhpcy5mcmFtZVRyYW5zZm9ybWVkQ291bnQ+PXRoaXMuY29uZmlnLmxvZ2dpbmdJbnRlcnZhbEZyYW1lQ291bnQ/KHRoaXMuZnJhbWVGcm9tU291cmNlQ291bnQ9MCx0aGlzLmZyYW1lVHJhbnNmb3JtZWRDb3VudD0wLHRoaXMuc3RhcnRBdD1zLHRoaXMucmVwb3J0ZXIuY29uZmlnPXRoaXMuY29uZmlnLHRoaXMucmVwb3J0ZXIuc2VuZCh7Li4udGhpcy5jb25maWcucmVwb3J0LHZhcmlhdGlvbjoiUW9TIixmcHM6Zix0cmFuc2Zvcm1lZEZwczp1LGZyYW1lc1RyYW5zZm9ybWVkOmksLi4uZX0pKToic3VjY2VzcyJ9fXZhciBrdD0ocj0+KHIucGlwZWxpbmVfZW5kZWQ9InBpcGVsaW5lX2VuZGVkIixyLnBpcGVsaW5lX2VuZGVkX3dpdGhfZXJyb3I9InBpcGVsaW5lX2VuZGVkX3dpdGhfZXJyb3IiLHIucGlwZWxpbmVfc3RhcnRlZD0icGlwZWxpbmVfc3RhcnRlZCIsci5waXBlbGluZV9zdGFydGVkX3dpdGhfZXJyb3I9InBpcGVsaW5lX3N0YXJ0ZWRfd2l0aF9lcnJvciIsci5waXBlbGluZV9yZXN0YXJ0ZWQ9InBpcGVsaW5lX3Jlc3RhcnRlZCIsci5waXBlbGluZV9yZXN0YXJ0ZWRfd2l0aF9lcnJvcj0icGlwZWxpbmVfcmVzdGFydGVkX3dpdGhfZXJyb3IiLHIpKShrdHx8e30pO2NvbnN0IFppPTUwMCxlbz0uODtjbGFzcyB0byBleHRlbmRzIFB0e2NvbnN0cnVjdG9yKGUsdCl7c3VwZXIoKSxBKHRoaXMsInJlcG9ydGVyXyIsbmV3IFV0KSxBKHRoaXMsInJlcG9ydGVyUW9zXyIsbmV3IEppKHtsb2dnaW5nSW50ZXJ2YWxGcmFtZUNvdW50OlppLHJlcG9ydDp7dmVyc2lvbjpLZX19KSksQSh0aGlzLCJ0cmFuc2Zvcm1lclR5cGVfIiksQSh0aGlzLCJ0cmFuc2Zvcm1lcl8iKSxBKHRoaXMsInNob3VsZFN0b3BfIiksQSh0aGlzLCJpc0ZsYXNoZWRfIiksQSh0aGlzLCJtZWRpYVRyYW5zZm9ybWVyUW9zUmVwb3J0U3RhcnRUaW1lc3RhbXBfIiksQSh0aGlzLCJ2aWRlb0hlaWdodF8iKSxBKHRoaXMsInZpZGVvV2lkdGhfIiksQSh0aGlzLCJ0cmFja0V4cGVjdGVkUmF0ZV8iKSxBKHRoaXMsImluZGV4XyIpLEEodGhpcywiY29udHJvbGxlcl8iKSx0aGlzLmluZGV4Xz10LHRoaXMudHJhbnNmb3JtZXJfPWUsdGhpcy5zaG91bGRTdG9wXz0hMSx0aGlzLmlzRmxhc2hlZF89ITEsdGhpcy5tZWRpYVRyYW5zZm9ybWVyUW9zUmVwb3J0U3RhcnRUaW1lc3RhbXBfPTAsdGhpcy52aWRlb0hlaWdodF89MCx0aGlzLnZpZGVvV2lkdGhfPTAsdGhpcy50cmFja0V4cGVjdGVkUmF0ZV89LTEsdGhpcy50cmFuc2Zvcm1lclR5cGVfPSJDdXN0b20iLCJnZXRUcmFuc2Zvcm1lclR5cGUiaW4gZSYmKHRoaXMudHJhbnNmb3JtZXJUeXBlXz1lLmdldFRyYW5zZm9ybWVyVHlwZSgpKSx0aGlzLnJlcG9ydCh7dmFyaWF0aW9uOiJDcmVhdGUifSl9c2V0VHJhY2tFeHBlY3RlZFJhdGUoZSl7dGhpcy50cmFja0V4cGVjdGVkUmF0ZV89ZX1hc3luYyBzdGFydChlKXtpZih0aGlzLmNvbnRyb2xsZXJfPWUsdGhpcy50cmFuc2Zvcm1lcl8mJnR5cGVvZiB0aGlzLnRyYW5zZm9ybWVyXy5zdGFydD09ImZ1bmN0aW9uIil0cnl7YXdhaXQgdGhpcy50cmFuc2Zvcm1lcl8uc3RhcnQoZSl9Y2F0Y2godCl7dGhpcy5yZXBvcnQoe21lc3NhZ2U6Si5lcnJvcnMudHJhbnNmb3JtZXJfc3RhcnQsdmFyaWF0aW9uOiJFcnJvciIsZXJyb3I6RHQodCl9KTtjb25zdCBuPXtldmVudE1ldGFEYXRhOnt0cmFuc2Zvcm1lckluZGV4OnRoaXMuaW5kZXhffSxlcnJvcjp0LGZ1bmN0aW9uOiJzdGFydCJ9O3RoaXMuZW1pdCgiZXJyb3IiLG4pfX1hc3luYyB0cmFuc2Zvcm0oZSx0KXt2YXIgbixpLG8scztpZih0aGlzLm1lZGlhVHJhbnNmb3JtZXJRb3NSZXBvcnRTdGFydFRpbWVzdGFtcF89PT0wJiYodGhpcy5tZWRpYVRyYW5zZm9ybWVyUW9zUmVwb3J0U3RhcnRUaW1lc3RhbXBfPURhdGUubm93KCkpLGUgaW5zdGFuY2VvZiBWaWRlb0ZyYW1lJiYodGhpcy52aWRlb0hlaWdodF89KG49ZT09bnVsbD92b2lkIDA6ZS5kaXNwbGF5SGVpZ2h0KSE9bnVsbD9uOjAsdGhpcy52aWRlb1dpZHRoXz0oaT1lPT1udWxsP3ZvaWQgMDplLmRpc3BsYXlXaWR0aCkhPW51bGw/aTowKSx0aGlzLnJlcG9ydGVyUW9zXy5vbkZyYW1lRnJvbVNvdXJjZSgpLHRoaXMudHJhbnNmb3JtZXJfKWlmKHRoaXMuc2hvdWxkU3RvcF8pY29uc29sZS53YXJuKCJbUGlwZWxpbmVdIGZsdXNoIGZyb20gdHJhbnNmb3JtIiksZS5jbG9zZSgpLHRoaXMuZmx1c2godCksdC50ZXJtaW5hdGUoKTtlbHNle3RyeXthd2FpdCgocz0obz10aGlzLnRyYW5zZm9ybWVyXykudHJhbnNmb3JtKT09bnVsbD92b2lkIDA6cy5jYWxsKG8sZSx0KSksdGhpcy5yZXBvcnRRb3MoKX1jYXRjaChhKXt0aGlzLnJlcG9ydCh7bWVzc2FnZTpKLmVycm9ycy50cmFuc2Zvcm1lcl90cmFuc2Zvcm0sdmFyaWF0aW9uOiJFcnJvciIsZXJyb3I6RHQoYSl9KTtjb25zdCB1PXtldmVudE1ldGFEYXRhOnt0cmFuc2Zvcm1lckluZGV4OnRoaXMuaW5kZXhffSxlcnJvcjphLGZ1bmN0aW9uOiJ0cmFuc2Zvcm0ifTt0aGlzLmVtaXQoImVycm9yIix1KX1pZih0aGlzLnRyYWNrRXhwZWN0ZWRSYXRlXyE9LTEmJnRoaXMudHJhY2tFeHBlY3RlZFJhdGVfKmVvPnRoaXMucmVwb3J0ZXJRb3NfLmZwcyl7Y29uc3QgYT17ZXZlbnRNZXRhRGF0YTp7dHJhbnNmb3JtZXJJbmRleDp0aGlzLmluZGV4X30sd2FybmluZ1R5cGU6ImZwc19kcm9wIixkcm9wSW5mbzp7cmVxdWVzdGVkOnRoaXMudHJhY2tFeHBlY3RlZFJhdGVfLGN1cnJlbnQ6dGhpcy5yZXBvcnRlclFvc18uZnBzfX07dGhpcy5lbWl0KCJ3YXJuIixhKX19fWFzeW5jIGZsdXNoKGUpe2lmKHRoaXMudHJhbnNmb3JtZXJfJiZ0eXBlb2YgdGhpcy50cmFuc2Zvcm1lcl8uZmx1c2g9PSJmdW5jdGlvbiImJiF0aGlzLmlzRmxhc2hlZF8pe3RoaXMuaXNGbGFzaGVkXz0hMDt0cnl7YXdhaXQgdGhpcy50cmFuc2Zvcm1lcl8uZmx1c2goZSl9Y2F0Y2godCl7dGhpcy5yZXBvcnQoe21lc3NhZ2U6Si5lcnJvcnMudHJhbnNmb3JtZXJfZmx1c2gsdmFyaWF0aW9uOiJFcnJvciIsZXJyb3I6RHQodCl9KTtjb25zdCBuPXtldmVudE1ldGFEYXRhOnt0cmFuc2Zvcm1lckluZGV4OnRoaXMuaW5kZXhffSxlcnJvcjp0LGZ1bmN0aW9uOiJmbHVzaCJ9O3RoaXMuZW1pdCgiZXJyb3IiLG4pfX10aGlzLnJlcG9ydFFvcyghMCksdGhpcy5yZXBvcnQoe3ZhcmlhdGlvbjoiRGVsZXRlIn0pfXN0b3AoKXtjb25zb2xlLmxvZygiW1BpcGVsaW5lXSBTdG9wIHN0cmVhbS4iKSx0aGlzLmNvbnRyb2xsZXJfJiYodGhpcy5mbHVzaCh0aGlzLmNvbnRyb2xsZXJfKSx0aGlzLmNvbnRyb2xsZXJfLnRlcm1pbmF0ZSgpKSx0aGlzLnNob3VsZFN0b3BfPSEwfXJlcG9ydChlKXt0aGlzLnJlcG9ydGVyXy5zZW5kKHt2ZXJzaW9uOktlLGFjdGlvbjoiTWVkaWFUcmFuc2Zvcm1lciIsdHJhbnNmb3JtZXJUeXBlOnRoaXMudHJhbnNmb3JtZXJUeXBlXywuLi5lfSl9cmVwb3J0UW9zKGU9ITEpe3RoaXMucmVwb3J0ZXJRb3NfLmNvbmZpZz17Li4udGhpcy5yZXBvcnRlclFvc18uY29uZmlnfSx0aGlzLnJlcG9ydGVyUW9zXy5vbkZyYW1lVHJhbnNmb3JtZWQoe3ZlcnNpb246S2UsYWN0aW9uOiJNZWRpYVRyYW5zZm9ybWVyIix0cmFuc2Zvcm1lclR5cGU6dGhpcy50cmFuc2Zvcm1lclR5cGVfLHZpZGVvV2lkdGg6dGhpcy52aWRlb1dpZHRoXyx2aWRlb0hlaWdodDp0aGlzLnZpZGVvSGVpZ2h0X30sZSl9fWNsYXNzIHJvIGV4dGVuZHMgUHR7Y29uc3RydWN0b3IoZSl7c3VwZXIoKSxBKHRoaXMsInRyYW5zZm9ybWVyc18iKSxBKHRoaXMsInRyYWNrRXhwZWN0ZWRSYXRlXyIpLHRoaXMudHJhbnNmb3JtZXJzXz1bXSx0aGlzLnRyYWNrRXhwZWN0ZWRSYXRlXz0tMTtmb3IobGV0IHQ9MDt0PGUubGVuZ3RoO3QrKyl7bGV0IG49bmV3IHRvKGVbdF0sdCk7bi5vbigiZXJyb3IiLGk9Pnt0aGlzLmVtaXQoImVycm9yIixpKX0pLG4ub24oIndhcm4iLGk9Pnt0aGlzLmVtaXQoIndhcm4iLGkpfSksdGhpcy50cmFuc2Zvcm1lcnNfLnB1c2gobil9fXNldFRyYWNrRXhwZWN0ZWRSYXRlKGUpe3RoaXMudHJhY2tFeHBlY3RlZFJhdGVfPWU7Zm9yKGxldCB0IG9mIHRoaXMudHJhbnNmb3JtZXJzXyl0LnNldFRyYWNrRXhwZWN0ZWRSYXRlKHRoaXMudHJhY2tFeHBlY3RlZFJhdGVfKX1hc3luYyBzdGFydChlLHQpe2lmKCF0aGlzLnRyYW5zZm9ybWVyc198fHRoaXMudHJhbnNmb3JtZXJzXy5sZW5ndGg9PT0wKXtjb25zb2xlLmxvZygiW1BpcGVsaW5lXSBObyB0cmFuc2Zvcm1lcnMuIik7cmV0dXJufXRyeXtsZXQgbj1lO2ZvcihsZXQgaSBvZiB0aGlzLnRyYW5zZm9ybWVyc18pZT1lLnBpcGVUaHJvdWdoKG5ldyBUcmFuc2Zvcm1TdHJlYW0oaSkpO2UucGlwZVRvKHQpLnRoZW4oYXN5bmMoKT0+e2NvbnNvbGUubG9nKCJbUGlwZWxpbmVdIFNldHVwLiIpLGF3YWl0IHQuYWJvcnQoKSxhd2FpdCBuLmNhbmNlbCgpLHRoaXMuZW1pdCgicGlwZWxpbmVJbmZvIiwicGlwZWxpbmVfZW5kZWQiKX0pLmNhdGNoKGFzeW5jIGk9PntlLmNhbmNlbCgpLnRoZW4oKCk9Pntjb25zb2xlLmxvZygiW1BpcGVsaW5lXSBTaHV0dGluZyBkb3duIHN0cmVhbXMgYWZ0ZXIgYWJvcnQuIil9KS5jYXRjaChvPT57Y29uc29sZS5lcnJvcigiW1BpcGVsaW5lXSBFcnJvciBmcm9tIHN0cmVhbSB0cmFuc2Zvcm06IixvKX0pLGF3YWl0IHQuYWJvcnQoaSksYXdhaXQgbi5jYW5jZWwoaSksdGhpcy5lbWl0KCJwaXBlbGluZUluZm8iLCJwaXBlbGluZV9lbmRlZF93aXRoX2Vycm9yIil9KX1jYXRjaHt0aGlzLmVtaXQoInBpcGVsaW5lSW5mbyIsInBpcGVsaW5lX3N0YXJ0ZWRfd2l0aF9lcnJvciIpLHRoaXMuZGVzdHJveSgpO3JldHVybn10aGlzLmVtaXQoInBpcGVsaW5lSW5mbyIsInBpcGVsaW5lX3N0YXJ0ZWQiKSxjb25zb2xlLmxvZygiW1BpcGVsaW5lXSBQaXBlbGluZSBzdGFydGVkLiIpfWFzeW5jIGRlc3Ryb3koKXtjb25zb2xlLmxvZygiW1BpcGVsaW5lXSBEZXN0cm95aW5nIFBpcGVsaW5lLiIpO2ZvcihsZXQgZSBvZiB0aGlzLnRyYW5zZm9ybWVyc18pZS5zdG9wKCl9fWNsYXNzIG5vIGV4dGVuZHMgUHR7Y29uc3RydWN0b3IoKXtzdXBlcigpLEEodGhpcywicmVwb3J0ZXJfIiksQSh0aGlzLCJwaXBlbGluZV8iKSxBKHRoaXMsInRyYW5zZm9ybWVyc18iKSxBKHRoaXMsInJlYWRhYmxlXyIpLEEodGhpcywid3JpdGFibGVfIiksQSh0aGlzLCJ0cmFja0V4cGVjdGVkUmF0ZV8iKSx0aGlzLnJlcG9ydGVyXz1uZXcgVXQsdGhpcy50cmFja0V4cGVjdGVkUmF0ZV89LTEsdGhpcy5yZXBvcnQoe3ZhcmlhdGlvbjoiQ3JlYXRlIn0pfXNldFRyYWNrRXhwZWN0ZWRSYXRlKGUpe3RoaXMudHJhY2tFeHBlY3RlZFJhdGVfPWUsdGhpcy5waXBlbGluZV8mJnRoaXMucGlwZWxpbmVfLnNldFRyYWNrRXhwZWN0ZWRSYXRlKHRoaXMudHJhY2tFeHBlY3RlZFJhdGVfKX10cmFuc2Zvcm0oZSx0KXtyZXR1cm4gdGhpcy5yZWFkYWJsZV89ZSx0aGlzLndyaXRhYmxlXz10LHRoaXMudHJhbnNmb3JtSW50ZXJuYWwoKX10cmFuc2Zvcm1JbnRlcm5hbCgpe3JldHVybiBuZXcgUHJvbWlzZShhc3luYyhlLHQpPT57aWYoIXRoaXMudHJhbnNmb3JtZXJzX3x8dGhpcy50cmFuc2Zvcm1lcnNfLmxlbmd0aD09PTApe3RoaXMucmVwb3J0KHttZXNzYWdlOkouZXJyb3JzLnRyYW5zZm9ybWVyX25vbmUsdmFyaWF0aW9uOiJFcnJvciJ9KSx0KCJbTWVkaWFQcm9jZXNzb3JdIE5lZWQgdG8gc2V0IHRyYW5zZm9ybWVycy4iKTtyZXR1cm59aWYoIXRoaXMucmVhZGFibGVfKXt0aGlzLnJlcG9ydCh7dmFyaWF0aW9uOiJFcnJvciIsbWVzc2FnZTpKLmVycm9ycy5yZWFkYWJsZV9udWxsfSksdCgiW01lZGlhUHJvY2Vzc29yXSBSZWFkYWJsZSBpcyBudWxsLiIpO3JldHVybn1pZighdGhpcy53cml0YWJsZV8pe3RoaXMucmVwb3J0KHt2YXJpYXRpb246IkVycm9yIixtZXNzYWdlOkouZXJyb3JzLndyaXRhYmxlX251bGx9KSx0KCJbTWVkaWFQcm9jZXNzb3JdIFdyaXRhYmxlIGlzIG51bGwuIik7cmV0dXJufWxldCBuPSExO3RoaXMucGlwZWxpbmVfJiYobj0hMCx0aGlzLnBpcGVsaW5lXy5jbGVhckxpc3RlbmVycygpLHRoaXMucGlwZWxpbmVfLmRlc3Ryb3koKSksdGhpcy5waXBlbGluZV89bmV3IHJvKHRoaXMudHJhbnNmb3JtZXJzXyksdGhpcy5waXBlbGluZV8ub24oIndhcm4iLGk9Pnt0aGlzLmVtaXQoIndhcm4iLGkpfSksdGhpcy5waXBlbGluZV8ub24oImVycm9yIixpPT57dGhpcy5lbWl0KCJlcnJvciIsaSl9KSx0aGlzLnBpcGVsaW5lXy5vbigicGlwZWxpbmVJbmZvIixpPT57biYmKGk9PT0icGlwZWxpbmVfc3RhcnRlZCI/aT1rdC5waXBlbGluZV9yZXN0YXJ0ZWQ6aT09PSJwaXBlbGluZV9zdGFydGVkX3dpdGhfZXJyb3IiJiYoaT1rdC5waXBlbGluZV9yZXN0YXJ0ZWRfd2l0aF9lcnJvcikpLHRoaXMuZW1pdCgicGlwZWxpbmVJbmZvIixpKX0pLHRoaXMudHJhY2tFeHBlY3RlZFJhdGVfIT0tMSYmdGhpcy5waXBlbGluZV8uc2V0VHJhY2tFeHBlY3RlZFJhdGUodGhpcy50cmFja0V4cGVjdGVkUmF0ZV8pLHRoaXMucGlwZWxpbmVfLnN0YXJ0KHRoaXMucmVhZGFibGVfLHRoaXMud3JpdGFibGVfKS50aGVuKCgpPT57ZSgpfSkuY2F0Y2goaT0+e3QoaSl9KX0pfXNldFRyYW5zZm9ybWVycyhlKXtyZXR1cm4gdGhpcy5yZXBvcnQoe3ZhcmlhdGlvbjoiVXBkYXRlIixtZXNzYWdlOkoudXBkYXRlcy50cmFuc2Zvcm1lcl9uZXd9KSx0aGlzLnRyYW5zZm9ybWVyc189ZSx0aGlzLnJlYWRhYmxlXyYmdGhpcy53cml0YWJsZV8/dGhpcy50cmFuc2Zvcm1JbnRlcm5hbCgpOlByb21pc2UucmVzb2x2ZSgpfWRlc3Ryb3koKXtyZXR1cm4gbmV3IFByb21pc2UoYXN5bmMgZT0+e3RoaXMucGlwZWxpbmVfJiZ0aGlzLnBpcGVsaW5lXy5kZXN0cm95KCksdGhpcy5yZXBvcnQoe3ZhcmlhdGlvbjoiRGVsZXRlIn0pLGUoKX0pfXJlcG9ydChlKXt0aGlzLnJlcG9ydGVyXy5zZW5kKHt2ZXJzaW9uOktlLGFjdGlvbjoiTWVkaWFQcm9jZXNzb3IiLC4uLmV9KX19dmFyIGlvPU9iamVjdC5kZWZpbmVQcm9wZXJ0eSxvbz0ocixlLHQpPT5lIGluIHI/aW8ocixlLHtlbnVtZXJhYmxlOiEwLGNvbmZpZ3VyYWJsZTohMCx3cml0YWJsZTohMCx2YWx1ZTp0fSk6cltlXT10LHNvPShyLGUsdCk9PihvbyhyLHR5cGVvZiBlIT0ic3ltYm9sIj9lKyIiOmUsdCksdCk7Y29uc3QgYW89ImhsZy50b2tib3guY29tL3Byb2QvbG9nZ2luZy92Y3Bfd2VicnRjIix1bz0iaHR0cHM6Ly8iLGNvPTFlNDtsZXQgcWU7Y29uc3QgZm89bmV3IFVpbnQ4QXJyYXkoMTYpO2Z1bmN0aW9uIGxvKCl7aWYoIXFlJiYocWU9dHlwZW9mIGNyeXB0bzwidSImJmNyeXB0by5nZXRSYW5kb21WYWx1ZXMmJmNyeXB0by5nZXRSYW5kb21WYWx1ZXMuYmluZChjcnlwdG8pLCFxZSkpdGhyb3cgbmV3IEVycm9yKCJjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKCkgbm90IHN1cHBvcnRlZC4gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS91dWlkanMvdXVpZCNnZXRyYW5kb212YWx1ZXMtbm90LXN1cHBvcnRlZCIpO3JldHVybiBxZShmbyl9Y29uc3QgVT1bXTtmb3IobGV0IHI9MDtyPDI1NjsrK3IpVS5wdXNoKChyKzI1NikudG9TdHJpbmcoMTYpLnNsaWNlKDEpKTtmdW5jdGlvbiBtbyhyLGU9MCl7cmV0dXJuKFVbcltlKzBdXStVW3JbZSsxXV0rVVtyW2UrMl1dK1VbcltlKzNdXSsiLSIrVVtyW2UrNF1dK1VbcltlKzVdXSsiLSIrVVtyW2UrNl1dK1VbcltlKzddXSsiLSIrVVtyW2UrOF1dK1VbcltlKzldXSsiLSIrVVtyW2UrMTBdXStVW3JbZSsxMV1dK1VbcltlKzEyXV0rVVtyW2UrMTNdXStVW3JbZSsxNF1dK1VbcltlKzE1XV0pLnRvTG93ZXJDYXNlKCl9Y29uc3QgaG89dHlwZW9mIGNyeXB0bzwidSImJmNyeXB0by5yYW5kb21VVUlEJiZjcnlwdG8ucmFuZG9tVVVJRC5iaW5kKGNyeXB0byksQ3I9e3JhbmRvbVVVSUQ6aG99O2Z1bmN0aW9uIHBvKHIsZSx0KXtpZihDci5yYW5kb21VVUlEJiYhZSYmIXIpcmV0dXJuIENyLnJhbmRvbVVVSUQoKTtyPXJ8fHt9O2NvbnN0IG49ci5yYW5kb218fChyLnJuZ3x8bG8pKCk7aWYobls2XT1uWzZdJjE1fDY0LG5bOF09bls4XSY2M3wxMjgsZSl7dD10fHwwO2ZvcihsZXQgaT0wO2k8MTY7KytpKWVbdCtpXT1uW2ldO3JldHVybiBlfXJldHVybiBtbyhuKX1mdW5jdGlvbiBDdChyLGUpe3JldHVybiBnbG9iYWxUaGlzW3JdfHwoZ2xvYmFsVGhpc1tyXT1lKSxnbG9iYWxUaGlzW3JdfWNvbnN0IHJlPUN0KCJnbG9iYWxzIix7fSk7dmFyIGRlPShyPT4oci5JTklUPSJJTklUIixyLkZPUldBUkQ9IkZPUldBUkQiLHIuVEVSTUlOQVRFPSJURVJNSU5BVEUiLHIuR0xPQkFMU19TWU5DPSJHTE9CQUxTX1NZTkMiLHIpKShkZXx8e30pO2Z1bmN0aW9uIE9yKHIpe3JldHVybltJbWFnZUJpdG1hcCxSZWFkYWJsZVN0cmVhbSxXcml0YWJsZVN0cmVhbV0uc29tZShlPT5yIGluc3RhbmNlb2YgZSl9bGV0IHlvPTA7ZnVuY3Rpb24gX28ocixlLHQsbixpKXtjb25zdCBvPXlvKys7cmV0dXJuIHIucG9zdE1lc3NhZ2Uoe2lkOm8sdHlwZTplLGZ1bmN0aW9uTmFtZTp0LGFyZ3M6bn0sbi5maWx0ZXIocz0+T3IocykpKSxuZXcgUHJvbWlzZShzPT57aT09bnVsbHx8aS5zZXQobyxzKX0pfWZ1bmN0aW9uIFBlKHIsZSl7Y29uc3R7aWQ6dCx0eXBlOm59PXIsaT1BcnJheS5pc0FycmF5KGUpP2U6W2VdO3Bvc3RNZXNzYWdlKHtpZDp0LHR5cGU6bixyZXN1bHQ6ZX0saS5maWx0ZXIobz0+T3IobykpKX1jb25zdCBCcj1DdCgid29ya2VyaXplZCIse30pO2Z1bmN0aW9uIExyKCl7cmV0dXJuIHR5cGVvZiBXb3JrZXJHbG9iYWxTY29wZTwidSImJnNlbGYgaW5zdGFuY2VvZiBXb3JrZXJHbG9iYWxTY29wZX1hc3luYyBmdW5jdGlvbiB4bygpe2lmKExyKCkpUGUoe3R5cGU6ZGUuR0xPQkFMU19TWU5DfSxyZSk7ZWxzZXtjb25zdCByPVtdO2Zvcihjb25zdCBlIGluIEJyKXtjb25zdHt3b3JrZXI6dCxyZXNvbHZlcnM6bn09QnJbZV0ud29ya2VyQ29udGV4dDt0JiZyLnB1c2goX28odCxkZS5HTE9CQUxTX1NZTkMsIiIsW3JlXSxuKSl9YXdhaXQgUHJvbWlzZS5hbGwocil9fWZ1bmN0aW9uIEplKHIsZSl7aWYoQXJyYXkuaXNBcnJheShlKSllLnNwbGljZSgwLGUubGVuZ3RoKTtlbHNlIGlmKHR5cGVvZiBlPT0ib2JqZWN0Iilmb3IoY29uc3QgdCBpbiBlKWRlbGV0ZSBlW3RdO2Zvcihjb25zdCB0IGluIHIpQXJyYXkuaXNBcnJheShyW3RdKT8oZVt0XT1bXSxKZShyW3RdLGVbdF0pKTp0eXBlb2Ygclt0XT09Im9iamVjdCI/KGVbdF09e30sSmUoclt0XSxlW3RdKSk6ZVt0XT1yW3RdfWFzeW5jIGZ1bmN0aW9uIGdvKHIsZSl7Y29uc3R7ZnVuY3Rpb25OYW1lOnQsYXJnczpufT1yO2lmKCFlLmluc3RhbmNlKXRocm93Imluc3RhbmNlIG5vdCBpbml0aWFsaXplZCI7aWYoIXQpdGhyb3cibWlzc2luZyBmdW5jdGlvbiBuYW1lIHRvIGNhbGwiO2lmKCFlLmluc3RhbmNlW3RdKXRocm93YHVuZGVmaW5lZCBmdW5jdGlvbiBbJHt0fV0gaW4gY2xhc3MgJHtlLmluc3RhbmNlLmNvbnN0cnVjdG9yLndvcmtlcklkfWA7UGUocixhd2FpdCBlLmluc3RhbmNlW3RdKC4uLm4hPW51bGw/bjpbXSkpfWNvbnN0IGJvPUN0KCJyZWdpc3RlcmVkV29ya2VycyIse30pO2Z1bmN0aW9uIHZvKHIsZSl7aWYoIXIuYXJncyl0aHJvdyJNaXNzaW5nIGNsYXNzTmFtZSB3aGlsZSBpbml0aWFsaXppbmcgd29ya2VyIjtjb25zdFt0LG5dPXIuYXJncyxpPWJvW3RdO2lmKGkpZS5pbnN0YW5jZT1uZXcgaShyLmFyZ3Muc2xpY2UoMSkpO2Vsc2UgdGhyb3dgdW5rbm93biB3b3JrZXIgY2xhc3MgJHt0fWA7SmUobixyZSksUGUocix0eXBlb2YgZS5pbnN0YW5jZSE9PXZvaWQgMCl9YXN5bmMgZnVuY3Rpb24gRW8ocixlKXtjb25zdHthcmdzOnR9PXI7aWYoIWUuaW5zdGFuY2UpdGhyb3ciaW5zdGFuY2Ugbm90IGluaXRpYWxpemVkIjtsZXQgbjtlLmluc3RhbmNlLnRlcm1pbmF0ZSYmKG49YXdhaXQgZS5pbnN0YW5jZS50ZXJtaW5hdGUoLi4udCE9bnVsbD90OltdKSksUGUocixuKX1mdW5jdGlvbiBUbyhyKXtpZighci5hcmdzKXRocm93Ik1pc3NpbmcgZ2xvYmFscyB3aGlsZSBzeW5jaW5nIjtKZShyLmFyZ3NbMF0scmUpLFBlKHIse30pfWZ1bmN0aW9uIEFvKCl7Y29uc3Qgcj17fTtvbm1lc3NhZ2U9YXN5bmMgZT0+e2NvbnN0IHQ9ZS5kYXRhO3N3aXRjaCh0LnR5cGUpe2Nhc2UgZGUuSU5JVDp2byh0LHIpO2JyZWFrO2Nhc2UgZGUuRk9SV0FSRDpnbyh0LHIpO2JyZWFrO2Nhc2UgZGUuVEVSTUlOQVRFOkVvKHQscik7YnJlYWs7Y2FzZSBkZS5HTE9CQUxTX1NZTkM6VG8odCk7YnJlYWt9fX1McigpJiZBbygpO2Z1bmN0aW9uIHdvKHIsZSl7cmV0dXJuIHJlW3JdfHwocmVbcl09ZSksWygpPT5yZVtyXSxhc3luYyB0PT57cmVbcl09dCxhd2FpdCB4bygpfV19ZnVuY3Rpb24gU28ocixlKXtyZXR1cm4gd28ocixlKX1jb25zdFtSbyxzbF09U28oIm1ldGFkYXRhIik7ZnVuY3Rpb24gT3QoKXtyZXR1cm4gUm8oKX1jbGFzcyBJb3tjb25zdHJ1Y3RvcihlKXtzbyh0aGlzLCJ1dWlkIixwbygpKSx0aGlzLmNvbmZpZz1lfWFzeW5jIHNlbmQoZSl7dmFyIHQsbixpO2NvbnN0e2FwcElkOm8sc291cmNlVHlwZTpzfT0odD1PdCgpKSE9bnVsbD90Ont9O2lmKCFvfHwhcylyZXR1cm4ibWV0YWRhdGEgbWlzc2luZyI7Y29uc3QgYT1uZXcgQWJvcnRDb250cm9sbGVyLHU9c2V0VGltZW91dCgoKT0+YS5hYm9ydCgpLGNvKTtyZXR1cm4gYXdhaXQoKGk9KG49dGhpcy5jb25maWcpPT1udWxsP3ZvaWQgMDpuLmZldGNoKSE9bnVsbD9pOmZldGNoKSh0aGlzLmdldFVybCgpLHttZXRob2Q6IlBPU1QiLGhlYWRlcnM6dGhpcy5nZXRIZWFkZXJzKCksYm9keTpKU09OLnN0cmluZ2lmeSh0aGlzLmJ1aWxkUmVwb3J0KGUpKSxzaWduYWw6YS5zaWduYWx9KSxjbGVhclRpbWVvdXQodSksInN1Y2Nlc3MifWdldFVybCgpe3ZhciBlO2xldCB0PShlPU90KCkucHJveHlVcmwpIT1udWxsP2U6dW87cmV0dXJuIHQrPSh0LmF0KC0xKT09PSIvIj8iIjoiLyIpK2FvLHR9Z2V0SGVhZGVycygpe3JldHVybnsiQ29udGVudC1UeXBlIjoiYXBwbGljYXRpb24vanNvbiJ9fWJ1aWxkUmVwb3J0KGUpe2NvbnN0IHQ9T3QoKTtyZXR1cm57Z3VpZDp0aGlzLnV1aWQsLi4uZSxhcHBsaWNhdGlvbklkOnQuYXBwSWQsdGltZXN0YW1wOkRhdGUubm93KCkscHJveHlVcmw6dC5wcm94eVVybCxzb3VyY2U6dC5zb3VyY2VUeXBlfX19Y29uc3QgRm89IjQuMy41Ijt2YXIgWmU9KHI9PihyLkxvdz0iTG93IixyLkhpZ2g9IkhpZ2giLHIpKShaZXx8e30pO2FzeW5jIGZ1bmN0aW9uIEdyKHIpe3JldHVybiBuZXcgUHJvbWlzZShlPT57c2V0VGltZW91dCgoKT0+e2UoKX0scil9KX1jbGFzcyBQb3tjb25zdHJ1Y3RvcihlKXtwKHRoaXMsImNvbnRleHQiKTtwKHRoaXMsImV4dGVuc2lvbiIpO3AodGhpcywicXVlcmllcyIsW10pO3AodGhpcywiYWN0aXZlUXVlcnkiKTt0aGlzLmNvbnRleHQ9ZSx0aGlzLmV4dGVuc2lvbj1lLmdldEV4dGVuc2lvbigiRVhUX2Rpc2pvaW50X3RpbWVyX3F1ZXJ5X3dlYmdsMiIpfXN0YXJ0KCl7fXN0b3AoKXt0aGlzLmFjdGl2ZVF1ZXJ5JiZ0aGlzLmNvbnRleHQuZW5kUXVlcnkodGhpcy5leHRlbnNpb24uVElNRV9FTEFQU0VEX0VYVCl9cHVzaENvbnRleHQoZSl7dGhpcy5jcmVhdGVRdWVyeSgiUFVTSCIsZSl9cG9wQ29udGV4dChlKXt0aGlzLmNyZWF0ZVF1ZXJ5KCJQT1AiLGUpfWNyZWF0ZVF1ZXJ5KGUsdCl7dGhpcy5hY3RpdmVRdWVyeSYmdGhpcy5jb250ZXh0LmVuZFF1ZXJ5KHRoaXMuZXh0ZW5zaW9uLlRJTUVfRUxBUFNFRF9FWFQpLHRoaXMuYWN0aXZlUXVlcnk9dGhpcy5jb250ZXh0LmNyZWF0ZVF1ZXJ5KCksdGhpcy5jb250ZXh0LmJlZ2luUXVlcnkodGhpcy5leHRlbnNpb24uVElNRV9FTEFQU0VEX0VYVCx0aGlzLmFjdGl2ZVF1ZXJ5KSx0aGlzLnF1ZXJpZXMucHVzaCh7bmFtZTp0LGFjdGlvbjplLHF1ZXJ5OnRoaXMuYWN0aXZlUXVlcnl9KX1hc3luYyBnZXRSZXNvbHZlZFF1ZXJpZXMoKXtjb25zdCBlPShhd2FpdCBQcm9taXNlLmFsbChbLi4udGhpcy5xdWVyaWVzXS5tYXAodD0+dGhpcy5yZXNvbHZlUXVlcnkodCkpKSkuZmlsdGVyKHQ9PnQpO2ZvcihsZXQgdD0xO3Q8ZS5sZW5ndGg7Kyt0KWVbdF0udGltZXN0YW1wKz1lW3QtMV0uZHVyYXRpb24rZVt0LTFdLnRpbWVzdGFtcDtyZXR1cm4gZX1hc3luYyByZXNvbHZlUXVlcnkoZSl7aWYoIWF3YWl0IHRoaXMuYXdhaXRRdWVyeUF2YWlsYWJsZShlKSl7Y29uc29sZS5sb2coIlVuYXdhaXRhYmxlIHF1ZXJ5IixlKTtyZXR1cm59aWYodGhpcy5jb250ZXh0LmdldFBhcmFtZXRlcih0aGlzLmV4dGVuc2lvbi5HUFVfRElTSk9JTlRfRVhUKSl7Y29uc29sZS5sb2coIkRpc2pvaW50ZWQgcXVlcnkiLGUpO3JldHVybn1yZXR1cm57Li4uZSxkdXJhdGlvbjp0aGlzLmNvbnRleHQuZ2V0UXVlcnlQYXJhbWV0ZXIoZS5xdWVyeSx0aGlzLmNvbnRleHQuUVVFUllfUkVTVUxUKSx0aW1lc3RhbXA6MH19YXN5bmMgYXdhaXRRdWVyeUF2YWlsYWJsZShlKXtmb3IobGV0IHQ9MDt0PDEwOysrdCl7aWYodGhpcy5jb250ZXh0LmdldFF1ZXJ5UGFyYW1ldGVyKGUucXVlcnksdGhpcy5jb250ZXh0LlFVRVJZX1JFU1VMVF9BVkFJTEFCTEUpKXJldHVybiBlO2F3YWl0IEdyKDIwMCl9fX0vKiBAbGljZW5zZSB0d2dsLmpzIDUuMy4wIENvcHlyaWdodCAoYykgMjAxNSwgR3JlZ2cgVGF2YXJlcyBBbGwgUmlnaHRzIFJlc2VydmVkLgpBdmFpbGFibGUgdmlhIHRoZSBNSVQgbGljZW5zZS4Kc2VlOiBodHRwOi8vZ2l0aHViLmNvbS9ncmVnZ21hbi90d2dsLmpzIGZvciBkZXRhaWxzICovY29uc3QgQnQ9NTEyMCxEZT01MTIxLEx0PTUxMjIsR3Q9NTEyMywkdD01MTI0LHp0PTUxMjUsV3Q9NTEyNixEbz0zMjgxOSxObz0zMjgyMCxNbz0zMzYzNSxVbz01MTMxLGtvPTMzNjQwLENvPTM1ODk5LE9vPTM1OTAyLEJvPTM2MjY5LExvPTM0MDQyLCRyPXt9O3tjb25zdCByPSRyO3JbQnRdPUludDhBcnJheSxyW0RlXT1VaW50OEFycmF5LHJbTHRdPUludDE2QXJyYXkscltHdF09VWludDE2QXJyYXksclskdF09SW50MzJBcnJheSxyW3p0XT1VaW50MzJBcnJheSxyW1d0XT1GbG9hdDMyQXJyYXkscltEb109VWludDE2QXJyYXkscltOb109VWludDE2QXJyYXkscltNb109VWludDE2QXJyYXkscltVb109VWludDE2QXJyYXkscltrb109VWludDMyQXJyYXkscltDb109VWludDMyQXJyYXkscltPb109VWludDMyQXJyYXkscltCb109VWludDMyQXJyYXkscltMb109VWludDMyQXJyYXl9ZnVuY3Rpb24gVnQocil7aWYociBpbnN0YW5jZW9mIEludDhBcnJheSlyZXR1cm4gQnQ7aWYociBpbnN0YW5jZW9mIFVpbnQ4QXJyYXl8fHIgaW5zdGFuY2VvZiBVaW50OENsYW1wZWRBcnJheSlyZXR1cm4gRGU7aWYociBpbnN0YW5jZW9mIEludDE2QXJyYXkpcmV0dXJuIEx0O2lmKHIgaW5zdGFuY2VvZiBVaW50MTZBcnJheSlyZXR1cm4gR3Q7aWYociBpbnN0YW5jZW9mIEludDMyQXJyYXkpcmV0dXJuICR0O2lmKHIgaW5zdGFuY2VvZiBVaW50MzJBcnJheSlyZXR1cm4genQ7aWYociBpbnN0YW5jZW9mIEZsb2F0MzJBcnJheSlyZXR1cm4gV3Q7dGhyb3cgbmV3IEVycm9yKCJ1bnN1cHBvcnRlZCB0eXBlZCBhcnJheSB0eXBlIil9ZnVuY3Rpb24genIocil7aWYocj09PUludDhBcnJheSlyZXR1cm4gQnQ7aWYocj09PVVpbnQ4QXJyYXl8fHI9PT1VaW50OENsYW1wZWRBcnJheSlyZXR1cm4gRGU7aWYocj09PUludDE2QXJyYXkpcmV0dXJuIEx0O2lmKHI9PT1VaW50MTZBcnJheSlyZXR1cm4gR3Q7aWYocj09PUludDMyQXJyYXkpcmV0dXJuICR0O2lmKHI9PT1VaW50MzJBcnJheSlyZXR1cm4genQ7aWYocj09PUZsb2F0MzJBcnJheSlyZXR1cm4gV3Q7dGhyb3cgbmV3IEVycm9yKCJ1bnN1cHBvcnRlZCB0eXBlZCBhcnJheSB0eXBlIil9ZnVuY3Rpb24gV3Iocil7Y29uc3QgZT0kcltyXTtpZighZSl0aHJvdyBuZXcgRXJyb3IoInVua25vd24gZ2wgdHlwZSIpO3JldHVybiBlfWNvbnN0IGV0PXR5cGVvZiBTaGFyZWRBcnJheUJ1ZmZlcjwidSI/ZnVuY3Rpb24oZSl7cmV0dXJuIGUmJmUuYnVmZmVyJiYoZS5idWZmZXIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcnx8ZS5idWZmZXIgaW5zdGFuY2VvZiBTaGFyZWRBcnJheUJ1ZmZlcil9OmZ1bmN0aW9uKGUpe3JldHVybiBlJiZlLmJ1ZmZlciYmZS5idWZmZXIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcn07ZnVuY3Rpb24gVnIoLi4ucil7Y29uc29sZS5lcnJvciguLi5yKX1jb25zdCBIcj1uZXcgTWFwO2Z1bmN0aW9uIHR0KHIsZSl7aWYoIXJ8fHR5cGVvZiByIT0ib2JqZWN0IilyZXR1cm4hMTtsZXQgdD1Ici5nZXQoZSk7dHx8KHQ9bmV3IFdlYWtNYXAsSHIuc2V0KGUsdCkpO2xldCBuPXQuZ2V0KHIpO2lmKG49PT12b2lkIDApe2NvbnN0IGk9T2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHIpO249aS5zdWJzdHJpbmcoOCxpLmxlbmd0aC0xKT09PWUsdC5zZXQocixuKX1yZXR1cm4gbn1mdW5jdGlvbiBHbyhyLGUpe3JldHVybiB0eXBlb2YgV2ViR0xCdWZmZXI8InUiJiZ0dChlLCJXZWJHTEJ1ZmZlciIpfWZ1bmN0aW9uICRvKHIsZSl7cmV0dXJuIHR5cGVvZiBXZWJHTFJlbmRlcmJ1ZmZlcjwidSImJnR0KGUsIldlYkdMUmVuZGVyYnVmZmVyIil9ZnVuY3Rpb24gSHQocixlKXtyZXR1cm4gdHlwZW9mIFdlYkdMVGV4dHVyZTwidSImJnR0KGUsIldlYkdMVGV4dHVyZSIpfWZ1bmN0aW9uIHpvKHIsZSl7cmV0dXJuIHR5cGVvZiBXZWJHTFNhbXBsZXI8InUiJiZ0dChlLCJXZWJHTFNhbXBsZXIiKX1jb25zdCBZcj0zNTA0NCxtZT0zNDk2MixXbz0zNDk2MyxWbz0zNDY2MCxIbz01MTIwLFlvPTUxMjEsam89NTEyMixYbz01MTIzLFFvPTUxMjQsS289NTEyNSxqcj01MTI2LFhyPXthdHRyaWJQcmVmaXg6IiJ9O2Z1bmN0aW9uIHFvKHIsZSx0LG4saSl7ci5iaW5kQnVmZmVyKGUsdCksci5idWZmZXJEYXRhKGUsbixpfHxZcil9ZnVuY3Rpb24gUXIocixlLHQsbil7aWYoR28ocixlKSlyZXR1cm4gZTt0PXR8fG1lO2NvbnN0IGk9ci5jcmVhdGVCdWZmZXIoKTtyZXR1cm4gcW8ocix0LGksZSxuKSxpfWZ1bmN0aW9uIEtyKHIpe3JldHVybiByPT09ImluZGljZXMifWZ1bmN0aW9uIEpvKHIpe3JldHVybiByPT09SW50OEFycmF5fHxyPT09VWludDhBcnJheX1mdW5jdGlvbiBabyhyKXtyZXR1cm4gci5sZW5ndGg/cjpyLmRhdGF9Y29uc3QgZXM9L2Nvb3JkfHRleHR1cmUvaSx0cz0vY29sb3J8Y29sb3VyL2k7ZnVuY3Rpb24gcnMocixlKXtsZXQgdDtpZihlcy50ZXN0KHIpP3Q9Mjp0cy50ZXN0KHIpP3Q9NDp0PTMsZSV0PjApdGhyb3cgbmV3IEVycm9yKGBDYW4gbm90IGd1ZXNzIG51bUNvbXBvbmVudHMgZm9yIGF0dHJpYnV0ZSAnJHtyfScuIFRyaWVkICR7dH0gYnV0ICR7ZX0gdmFsdWVzIGlzIG5vdCBldmVubHkgZGl2aXNpYmxlIGJ5ICR7dH0uIFlvdSBzaG91bGQgc3BlY2lmeSBpdC5gKTtyZXR1cm4gdH1mdW5jdGlvbiBucyhyLGUsdCl7cmV0dXJuIHIubnVtQ29tcG9uZW50c3x8ci5zaXplfHxycyhlLHR8fFpvKHIpLmxlbmd0aCl9ZnVuY3Rpb24gcXIocixlKXtpZihldChyKSlyZXR1cm4gcjtpZihldChyLmRhdGEpKXJldHVybiByLmRhdGE7QXJyYXkuaXNBcnJheShyKSYmKHI9e2RhdGE6cn0pO2xldCB0PXIudHlwZT9ZdChyLnR5cGUpOnZvaWQgMDtyZXR1cm4gdHx8KEtyKGUpP3Q9VWludDE2QXJyYXk6dD1GbG9hdDMyQXJyYXkpLG5ldyB0KHIuZGF0YSl9ZnVuY3Rpb24gaXMocil7cmV0dXJuIHR5cGVvZiByPT0ibnVtYmVyIj9yOnI/enIocik6anJ9ZnVuY3Rpb24gWXQocil7cmV0dXJuIHR5cGVvZiByPT0ibnVtYmVyIj9XcihyKTpyfHxGbG9hdDMyQXJyYXl9ZnVuY3Rpb24gb3MocixlKXtyZXR1cm57YnVmZmVyOmUuYnVmZmVyLG51bVZhbHVlczoyKjMqNCx0eXBlOmlzKGUudHlwZSksYXJyYXlUeXBlOll0KGUudHlwZSl9fWZ1bmN0aW9uIHNzKHIsZSl7Y29uc3QgdD1lLmRhdGF8fGUsbj1ZdChlLnR5cGUpLGk9dCpuLkJZVEVTX1BFUl9FTEVNRU5ULG89ci5jcmVhdGVCdWZmZXIoKTtyZXR1cm4gci5iaW5kQnVmZmVyKG1lLG8pLHIuYnVmZmVyRGF0YShtZSxpLGUuZHJhd1R5cGV8fFlyKSx7YnVmZmVyOm8sbnVtVmFsdWVzOnQsdHlwZTp6cihuKSxhcnJheVR5cGU6bn19ZnVuY3Rpb24gYXMocixlLHQpe2NvbnN0IG49cXIoZSx0KTtyZXR1cm57YXJyYXlUeXBlOm4uY29uc3RydWN0b3IsYnVmZmVyOlFyKHIsbix2b2lkIDAsZS5kcmF3VHlwZSksdHlwZTpWdChuKSxudW1WYWx1ZXM6MH19ZnVuY3Rpb24gdXMocixlKXtjb25zdCB0PXt9O3JldHVybiBPYmplY3Qua2V5cyhlKS5mb3JFYWNoKGZ1bmN0aW9uKG4pe2lmKCFLcihuKSl7Y29uc3QgaT1lW25dLG89aS5hdHRyaWJ8fGkubmFtZXx8aS5hdHRyaWJOYW1lfHxYci5hdHRyaWJQcmVmaXgrbjtpZihpLnZhbHVlKXtpZighQXJyYXkuaXNBcnJheShpLnZhbHVlKSYmIWV0KGkudmFsdWUpKXRocm93IG5ldyBFcnJvcigiYXJyYXkudmFsdWUgaXMgbm90IGFycmF5IG9yIHR5cGVkYXJyYXkiKTt0W29dPXt2YWx1ZTppLnZhbHVlfX1lbHNle2xldCBzO2kuYnVmZmVyJiZpLmJ1ZmZlciBpbnN0YW5jZW9mIFdlYkdMQnVmZmVyP3M9b3M6dHlwZW9mIGk9PSJudW1iZXIifHx0eXBlb2YgaS5kYXRhPT0ibnVtYmVyIj9zPXNzOnM9YXM7Y29uc3R7YnVmZmVyOmEsdHlwZTp1LG51bVZhbHVlczpmLGFycmF5VHlwZTpkfT1zKHIsaSxuKSxoPWkubm9ybWFsaXplIT09dm9pZCAwP2kubm9ybWFsaXplOkpvKGQpLHk9bnMoaSxuLGYpO3Rbb109e2J1ZmZlcjphLG51bUNvbXBvbmVudHM6eSx0eXBlOnUsbm9ybWFsaXplOmgsc3RyaWRlOmkuc3RyaWRlfHwwLG9mZnNldDppLm9mZnNldHx8MCxkaXZpc29yOmkuZGl2aXNvcj09PXZvaWQgMD92b2lkIDA6aS5kaXZpc29yLGRyYXdUeXBlOmkuZHJhd1R5cGV9fX19KSxyLmJpbmRCdWZmZXIobWUsbnVsbCksdH1mdW5jdGlvbiBjcyhyLGUpe3JldHVybiBlPT09SG98fGU9PT1Zbz8xOmU9PT1qb3x8ZT09PVhvPzI6ZT09PVFvfHxlPT09S298fGU9PT1qcj80OjB9Y29uc3QganQ9WyJwb3NpdGlvbiIsInBvc2l0aW9ucyIsImFfcG9zaXRpb24iXTtmdW5jdGlvbiBmcyhyLGUpe2xldCB0LG47Zm9yKG49MDtuPGp0Lmxlbmd0aCYmKHQ9anRbbl0sISh0IGluIGV8fCh0PVhyLmF0dHJpYlByZWZpeCt0LHQgaW4gZSkpKTsrK24pO249PT1qdC5sZW5ndGgmJih0PU9iamVjdC5rZXlzKGUpWzBdKTtjb25zdCBpPWVbdF07aWYoIWkuYnVmZmVyKXJldHVybiAxO3IuYmluZEJ1ZmZlcihtZSxpLmJ1ZmZlcik7Y29uc3Qgbz1yLmdldEJ1ZmZlclBhcmFtZXRlcihtZSxWbyk7ci5iaW5kQnVmZmVyKG1lLG51bGwpO2NvbnN0IHM9Y3MocixpLnR5cGUpLGE9by9zLHU9aS5udW1Db21wb25lbnRzfHxpLnNpemUsZj1hL3U7aWYoZiUxIT09MCl0aHJvdyBuZXcgRXJyb3IoYG51bUNvbXBvbmVudHMgJHt1fSBub3QgY29ycmVjdCBmb3IgbGVuZ3RoICR7bGVuZ3RofWApO3JldHVybiBmfWZ1bmN0aW9uIGxzKHIsZSx0KXtjb25zdCBuPXVzKHIsZSksaT1PYmplY3QuYXNzaWduKHt9LHR8fHt9KTtpLmF0dHJpYnM9T2JqZWN0LmFzc2lnbih7fSx0P3QuYXR0cmliczp7fSxuKTtjb25zdCBvPWUuaW5kaWNlcztpZihvKXtjb25zdCBzPXFyKG8sImluZGljZXMiKTtpLmluZGljZXM9UXIocixzLFdvKSxpLm51bUVsZW1lbnRzPXMubGVuZ3RoLGkuZWxlbWVudFR5cGU9VnQocyl9ZWxzZSBpLm51bUVsZW1lbnRzfHwoaS5udW1FbGVtZW50cz1mcyhyLGkuYXR0cmlicykpO3JldHVybiBpfWZ1bmN0aW9uIE5lKHIpe3JldHVybiEhci50ZXhTdG9yYWdlMkR9Y29uc3QgSnI9ZnVuY3Rpb24oKXtjb25zdCByPXt9LGU9e307ZnVuY3Rpb24gdChuKXtjb25zdCBpPW4uY29uc3RydWN0b3IubmFtZTtpZighcltpXSl7Zm9yKGNvbnN0IG8gaW4gbilpZih0eXBlb2YgbltvXT09Im51bWJlciIpe2NvbnN0IHM9ZVtuW29dXTtlW25bb11dPXM/YCR7c30gfCAke299YDpvfXJbaV09ITB9fXJldHVybiBmdW5jdGlvbihpLG8pe3JldHVybiB0KGkpLGVbb118fCh0eXBlb2Ygbz09Im51bWJlciI/YDB4JHtvLnRvU3RyaW5nKDE2KX1gOm8pfX0oKSxuZT17dGV4dHVyZUNvbG9yOm5ldyBVaW50OEFycmF5KFsxMjgsMTkyLDI1NSwyNTVdKSx0ZXh0dXJlT3B0aW9uczp7fSxjcm9zc09yaWdpbjp2b2lkIDB9LE1lPWV0LFpyPWZ1bmN0aW9uKCl7bGV0IHI7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIHI9cnx8KHR5cGVvZiBkb2N1bWVudDwidSImJmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQ/ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiY2FudmFzIikuZ2V0Q29udGV4dCgiMmQiKTpudWxsKSxyfX0oKSxlbj02NDA2LFE9NjQwNyxGPTY0MDgsdG49NjQwOSxybj02NDEwLFVlPTY0MDIsbm49MzQwNDEscnQ9MzMwNzEsZHM9OTcyOCxtcz05NzI5LGllPTM1NTMsb2U9MzQwNjcsaGU9MzI4NzkscGU9MzU4NjYsWHQ9MzQwNjksaHM9MzQwNzAscHM9MzQwNzEseXM9MzQwNzIsX3M9MzQwNzMseHM9MzQwNzQsUXQ9MTAyNDEsS3Q9MTAyNDAsbnQ9MTAyNDIsaXQ9MTAyNDMsb249MzI4ODIsZ3M9MzMwODIsYnM9MzMwODMsdnM9MzMwODQsRXM9MzMwODUscXQ9MzMxNyxzbj0zMzE0LGFuPTMyODc4LHVuPTMzMTYsY249MzMxNSxmbj0zMjg3NyxUcz0zNzQ0MyxBcz0zNzQ0MSx3cz0zNzQ0MCxTcz0zMzMyMSxScz0zNjc1NixJcz0zMzMyNSxGcz0zMzMyNixQcz0zMzMzMCxEcz0zMzMyOSxOcz0zMzMzOCxNcz0zMzMzNyxVcz0zMzM0MCxrcz0zMzMzOSxDcz0zMzMyMyxPcz0zNjc1NyxCcz0zMzMyNyxMcz0zMzMyOCxHcz0zMzMzNiwkcz0zMzMzNSx6cz0zMzMzMixXcz0zMzMzMSxWcz0zMzMzNCxIcz0zMzMzMyxZcz0zMjg0OSxqcz0zNTkwNSxYcz0zNjE5NCxRcz0zNjc1OCxLcz0zNTg5OCxxcz0zNTkwMSxKcz0zNDg0Myxacz0zNDgzNyxlYT0zNjIyMSx0YT0zNjIzOSxyYT0zNjIxNSxuYT0zNjIzMyxpYT0zNjIwOSxvYT0zNjIyNyxzYT0zMjg1NixhYT0zNTkwNyx1YT0zNjc1OSxjYT0zMjg1NSxmYT0zMjg1NCxsYT0zMjg1NyxkYT0zNDg0MixtYT0zNDgzNixoYT0zNjIyMCxwYT0zNjIzOCx5YT0zNjk3NSxfYT0zNjIxNCx4YT0zNjIzMixnYT0zNjIyNixiYT0zNjIwOCx2YT0zMzE4OSxFYT0zMzE5MCxUYT0zNjAxMixBYT0zNjAxMyx3YT0zNTA1NixzZT01MTIwLFI9NTEyMSxvdD01MTIyLEVlPTUxMjMsc3Q9NTEyNCx5ZT01MTI1LEM9NTEyNixsbj0zMjgxOSxkbj0zMjgyMCxtbj0zMzYzNSxXPTUxMzEsa2U9MzYxOTMsSnQ9MzM2NDAsU2E9MzU4OTksUmE9MzU5MDIsSWE9MzYyNjksRmE9MzQwNDIsYXQ9MzMzMTksVGU9MzMzMjAsdXQ9NjQwMyxBZT0zNjI0NCx3ZT0zNjI0OCxfZT0zNjI0OTtsZXQgWnQ7ZnVuY3Rpb24gY3Qocil7aWYoIVp0KXtjb25zdCBlPXt9O2VbZW5dPXt0ZXh0dXJlRm9ybWF0OmVuLGNvbG9yUmVuZGVyYWJsZTohMCx0ZXh0dXJlRmlsdGVyYWJsZTohMCxieXRlc1BlckVsZW1lbnQ6WzEsMiwyLDRdLHR5cGU6W1IsVyxrZSxDXX0sZVt0bl09e3RleHR1cmVGb3JtYXQ6dG4sY29sb3JSZW5kZXJhYmxlOiEwLHRleHR1cmVGaWx0ZXJhYmxlOiEwLGJ5dGVzUGVyRWxlbWVudDpbMSwyLDIsNF0sdHlwZTpbUixXLGtlLENdfSxlW3JuXT17dGV4dHVyZUZvcm1hdDpybixjb2xvclJlbmRlcmFibGU6ITAsdGV4dHVyZUZpbHRlcmFibGU6ITAsYnl0ZXNQZXJFbGVtZW50OlsyLDQsNCw4XSx0eXBlOltSLFcsa2UsQ119LGVbUV09e3RleHR1cmVGb3JtYXQ6USxjb2xvclJlbmRlcmFibGU6ITAsdGV4dHVyZUZpbHRlcmFibGU6ITAsYnl0ZXNQZXJFbGVtZW50OlszLDYsNiwxMiwyXSx0eXBlOltSLFcsa2UsQyxtbl19LGVbRl09e3RleHR1cmVGb3JtYXQ6Rixjb2xvclJlbmRlcmFibGU6ITAsdGV4dHVyZUZpbHRlcmFibGU6ITAsYnl0ZXNQZXJFbGVtZW50Ols0LDgsOCwxNiwyLDJdLHR5cGU6W1IsVyxrZSxDLGxuLGRuXX0sZVtVZV09e3RleHR1cmVGb3JtYXQ6VWUsY29sb3JSZW5kZXJhYmxlOiEwLHRleHR1cmVGaWx0ZXJhYmxlOiExLGJ5dGVzUGVyRWxlbWVudDpbMiw0XSx0eXBlOlt5ZSxFZV19LGVbU3NdPXt0ZXh0dXJlRm9ybWF0OnV0LGNvbG9yUmVuZGVyYWJsZTohMCx0ZXh0dXJlRmlsdGVyYWJsZTohMCxieXRlc1BlckVsZW1lbnQ6WzFdLHR5cGU6W1JdfSxlW1JzXT17dGV4dHVyZUZvcm1hdDp1dCxjb2xvclJlbmRlcmFibGU6ITEsdGV4dHVyZUZpbHRlcmFibGU6ITAsYnl0ZXNQZXJFbGVtZW50OlsxXSx0eXBlOltzZV19LGVbSXNdPXt0ZXh0dXJlRm9ybWF0OnV0LGNvbG9yUmVuZGVyYWJsZTohMSx0ZXh0dXJlRmlsdGVyYWJsZTohMCxieXRlc1BlckVsZW1lbnQ6WzQsMl0sdHlwZTpbQyxXXX0sZVtGc109e3RleHR1cmVGb3JtYXQ6dXQsY29sb3JSZW5kZXJhYmxlOiExLHRleHR1cmVGaWx0ZXJhYmxlOiExLGJ5dGVzUGVyRWxlbWVudDpbNF0sdHlwZTpbQ119LGVbUHNdPXt0ZXh0dXJlRm9ybWF0OkFlLGNvbG9yUmVuZGVyYWJsZTohMCx0ZXh0dXJlRmlsdGVyYWJsZTohMSxieXRlc1BlckVsZW1lbnQ6WzFdLHR5cGU6W1JdfSxlW0RzXT17dGV4dHVyZUZvcm1hdDpBZSxjb2xvclJlbmRlcmFibGU6ITAsdGV4dHVyZUZpbHRlcmFibGU6ITEsYnl0ZXNQZXJFbGVtZW50OlsxXSx0eXBlOltzZV19LGVbenNdPXt0ZXh0dXJlRm9ybWF0OkFlLGNvbG9yUmVuZGVyYWJsZTohMCx0ZXh0dXJlRmlsdGVyYWJsZTohMSxieXRlc1BlckVsZW1lbnQ6WzJdLHR5cGU6W0VlXX0sZVtXc109e3RleHR1cmVGb3JtYXQ6QWUsY29sb3JSZW5kZXJhYmxlOiEwLHRleHR1cmVGaWx0ZXJhYmxlOiExLGJ5dGVzUGVyRWxlbWVudDpbMl0sdHlwZTpbb3RdfSxlW1ZzXT17dGV4dHVyZUZvcm1hdDpBZSxjb2xvclJlbmRlcmFibGU6ITAsdGV4dHVyZUZpbHRlcmFibGU6ITEsYnl0ZXNQZXJFbGVtZW50Ols0XSx0eXBlOlt5ZV19LGVbSHNdPXt0ZXh0dXJlRm9ybWF0OkFlLGNvbG9yUmVuZGVyYWJsZTohMCx0ZXh0dXJlRmlsdGVyYWJsZTohMSxieXRlc1BlckVsZW1lbnQ6WzRdLHR5cGU6W3N0XX0sZVtDc109e3RleHR1cmVGb3JtYXQ6YXQsY29sb3JSZW5kZXJhYmxlOiEwLHRleHR1cmVGaWx0ZXJhYmxlOiEwLGJ5dGVzUGVyRWxlbWVudDpbMl0sdHlwZTpbUl19LGVbT3NdPXt0ZXh0dXJlRm9ybWF0OmF0LGNvbG9yUmVuZGVyYWJsZTohMSx0ZXh0dXJlRmlsdGVyYWJsZTohMCxieXRlc1BlckVsZW1lbnQ6WzJdLHR5cGU6W3NlXX0sZVtCc109e3RleHR1cmVGb3JtYXQ6YXQsY29sb3JSZW5kZXJhYmxlOiExLHRleHR1cmVGaWx0ZXJhYmxlOiEwLGJ5dGVzUGVyRWxlbWVudDpbOCw0XSx0eXBlOltDLFddfSxlW0xzXT17dGV4dHVyZUZvcm1hdDphdCxjb2xvclJlbmRlcmFibGU6ITEsdGV4dHVyZUZpbHRlcmFibGU6ITEsYnl0ZXNQZXJFbGVtZW50Ols4XSx0eXBlOltDXX0sZVtHc109e3RleHR1cmVGb3JtYXQ6VGUsY29sb3JSZW5kZXJhYmxlOiEwLHRleHR1cmVGaWx0ZXJhYmxlOiExLGJ5dGVzUGVyRWxlbWVudDpbMl0sdHlwZTpbUl19LGVbJHNdPXt0ZXh0dXJlRm9ybWF0OlRlLGNvbG9yUmVuZGVyYWJsZTohMCx0ZXh0dXJlRmlsdGVyYWJsZTohMSxieXRlc1BlckVsZW1lbnQ6WzJdLHR5cGU6W3NlXX0sZVtOc109e3RleHR1cmVGb3JtYXQ6VGUsY29sb3JSZW5kZXJhYmxlOiEwLHRleHR1cmVGaWx0ZXJhYmxlOiExLGJ5dGVzUGVyRWxlbWVudDpbNF0sdHlwZTpbRWVdfSxlW01zXT17dGV4dHVyZUZvcm1hdDpUZSxjb2xvclJlbmRlcmFibGU6ITAsdGV4dHVyZUZpbHRlcmFibGU6ITEsYnl0ZXNQZXJFbGVtZW50Ols0XSx0eXBlOltvdF19LGVbVXNdPXt0ZXh0dXJlRm9ybWF0OlRlLGNvbG9yUmVuZGVyYWJsZTohMCx0ZXh0dXJlRmlsdGVyYWJsZTohMSxieXRlc1BlckVsZW1lbnQ6WzhdLHR5cGU6W3llXX0sZVtrc109e3RleHR1cmVGb3JtYXQ6VGUsY29sb3JSZW5kZXJhYmxlOiEwLHRleHR1cmVGaWx0ZXJhYmxlOiExLGJ5dGVzUGVyRWxlbWVudDpbOF0sdHlwZTpbc3RdfSxlW1lzXT17dGV4dHVyZUZvcm1hdDpRLGNvbG9yUmVuZGVyYWJsZTohMCx0ZXh0dXJlRmlsdGVyYWJsZTohMCxieXRlc1BlckVsZW1lbnQ6WzNdLHR5cGU6W1JdfSxlW2pzXT17dGV4dHVyZUZvcm1hdDpRLGNvbG9yUmVuZGVyYWJsZTohMSx0ZXh0dXJlRmlsdGVyYWJsZTohMCxieXRlc1BlckVsZW1lbnQ6WzNdLHR5cGU6W1JdfSxlW1hzXT17dGV4dHVyZUZvcm1hdDpRLGNvbG9yUmVuZGVyYWJsZTohMCx0ZXh0dXJlRmlsdGVyYWJsZTohMCxieXRlc1BlckVsZW1lbnQ6WzMsMl0sdHlwZTpbUixtbl19LGVbUXNdPXt0ZXh0dXJlRm9ybWF0OlEsY29sb3JSZW5kZXJhYmxlOiExLHRleHR1cmVGaWx0ZXJhYmxlOiEwLGJ5dGVzUGVyRWxlbWVudDpbM10sdHlwZTpbc2VdfSxlW0tzXT17dGV4dHVyZUZvcm1hdDpRLGNvbG9yUmVuZGVyYWJsZTohMSx0ZXh0dXJlRmlsdGVyYWJsZTohMCxieXRlc1BlckVsZW1lbnQ6WzEyLDYsNF0sdHlwZTpbQyxXLFNhXX0sZVtxc109e3RleHR1cmVGb3JtYXQ6USxjb2xvclJlbmRlcmFibGU6ITEsdGV4dHVyZUZpbHRlcmFibGU6ITAsYnl0ZXNQZXJFbGVtZW50OlsxMiw2LDRdLHR5cGU6W0MsVyxSYV19LGVbSnNdPXt0ZXh0dXJlRm9ybWF0OlEsY29sb3JSZW5kZXJhYmxlOiExLHRleHR1cmVGaWx0ZXJhYmxlOiEwLGJ5dGVzUGVyRWxlbWVudDpbMTIsNl0sdHlwZTpbQyxXXX0sZVtac109e3RleHR1cmVGb3JtYXQ6USxjb2xvclJlbmRlcmFibGU6ITEsdGV4dHVyZUZpbHRlcmFibGU6ITEsYnl0ZXNQZXJFbGVtZW50OlsxMl0sdHlwZTpbQ119LGVbZWFdPXt0ZXh0dXJlRm9ybWF0OndlLGNvbG9yUmVuZGVyYWJsZTohMSx0ZXh0dXJlRmlsdGVyYWJsZTohMSxieXRlc1BlckVsZW1lbnQ6WzNdLHR5cGU6W1JdfSxlW3RhXT17dGV4dHVyZUZvcm1hdDp3ZSxjb2xvclJlbmRlcmFibGU6ITEsdGV4dHVyZUZpbHRlcmFibGU6ITEsYnl0ZXNQZXJFbGVtZW50OlszXSx0eXBlOltzZV19LGVbcmFdPXt0ZXh0dXJlRm9ybWF0OndlLGNvbG9yUmVuZGVyYWJsZTohMSx0ZXh0dXJlRmlsdGVyYWJsZTohMSxieXRlc1BlckVsZW1lbnQ6WzZdLHR5cGU6W0VlXX0sZVtuYV09e3RleHR1cmVGb3JtYXQ6d2UsY29sb3JSZW5kZXJhYmxlOiExLHRleHR1cmVGaWx0ZXJhYmxlOiExLGJ5dGVzUGVyRWxlbWVudDpbNl0sdHlwZTpbb3RdfSxlW2lhXT17dGV4dHVyZUZvcm1hdDp3ZSxjb2xvclJlbmRlcmFibGU6ITEsdGV4dHVyZUZpbHRlcmFibGU6ITEsYnl0ZXNQZXJFbGVtZW50OlsxMl0sdHlwZTpbeWVdfSxlW29hXT17dGV4dHVyZUZvcm1hdDp3ZSxjb2xvclJlbmRlcmFibGU6ITEsdGV4dHVyZUZpbHRlcmFibGU6ITEsYnl0ZXNQZXJFbGVtZW50OlsxMl0sdHlwZTpbc3RdfSxlW3NhXT17dGV4dHVyZUZvcm1hdDpGLGNvbG9yUmVuZGVyYWJsZTohMCx0ZXh0dXJlRmlsdGVyYWJsZTohMCxieXRlc1BlckVsZW1lbnQ6WzRdLHR5cGU6W1JdfSxlW2FhXT17dGV4dHVyZUZvcm1hdDpGLGNvbG9yUmVuZGVyYWJsZTohMCx0ZXh0dXJlRmlsdGVyYWJsZTohMCxieXRlc1BlckVsZW1lbnQ6WzRdLHR5cGU6W1JdfSxlW3VhXT17dGV4dHVyZUZvcm1hdDpGLGNvbG9yUmVuZGVyYWJsZTohMSx0ZXh0dXJlRmlsdGVyYWJsZTohMCxieXRlc1BlckVsZW1lbnQ6WzRdLHR5cGU6W3NlXX0sZVtjYV09e3RleHR1cmVGb3JtYXQ6Rixjb2xvclJlbmRlcmFibGU6ITAsdGV4dHVyZUZpbHRlcmFibGU6ITAsYnl0ZXNQZXJFbGVtZW50Ols0LDIsNF0sdHlwZTpbUixkbixKdF19LGVbZmFdPXt0ZXh0dXJlRm9ybWF0OkYsY29sb3JSZW5kZXJhYmxlOiEwLHRleHR1cmVGaWx0ZXJhYmxlOiEwLGJ5dGVzUGVyRWxlbWVudDpbNCwyXSx0eXBlOltSLGxuXX0sZVtsYV09e3RleHR1cmVGb3JtYXQ6Rixjb2xvclJlbmRlcmFibGU6ITAsdGV4dHVyZUZpbHRlcmFibGU6ITAsYnl0ZXNQZXJFbGVtZW50Ols0XSx0eXBlOltKdF19LGVbZGFdPXt0ZXh0dXJlRm9ybWF0OkYsY29sb3JSZW5kZXJhYmxlOiExLHRleHR1cmVGaWx0ZXJhYmxlOiEwLGJ5dGVzUGVyRWxlbWVudDpbMTYsOF0sdHlwZTpbQyxXXX0sZVttYV09e3RleHR1cmVGb3JtYXQ6Rixjb2xvclJlbmRlcmFibGU6ITEsdGV4dHVyZUZpbHRlcmFibGU6ITEsYnl0ZXNQZXJFbGVtZW50OlsxNl0sdHlwZTpbQ119LGVbaGFdPXt0ZXh0dXJlRm9ybWF0Ol9lLGNvbG9yUmVuZGVyYWJsZTohMCx0ZXh0dXJlRmlsdGVyYWJsZTohMSxieXRlc1BlckVsZW1lbnQ6WzRdLHR5cGU6W1JdfSxlW3BhXT17dGV4dHVyZUZvcm1hdDpfZSxjb2xvclJlbmRlcmFibGU6ITAsdGV4dHVyZUZpbHRlcmFibGU6ITEsYnl0ZXNQZXJFbGVtZW50Ols0XSx0eXBlOltzZV19LGVbeWFdPXt0ZXh0dXJlRm9ybWF0Ol9lLGNvbG9yUmVuZGVyYWJsZTohMCx0ZXh0dXJlRmlsdGVyYWJsZTohMSxieXRlc1BlckVsZW1lbnQ6WzRdLHR5cGU6W0p0XX0sZVtfYV09e3RleHR1cmVGb3JtYXQ6X2UsY29sb3JSZW5kZXJhYmxlOiEwLHRleHR1cmVGaWx0ZXJhYmxlOiExLGJ5dGVzUGVyRWxlbWVudDpbOF0sdHlwZTpbRWVdfSxlW3hhXT17dGV4dHVyZUZvcm1hdDpfZSxjb2xvclJlbmRlcmFibGU6ITAsdGV4dHVyZUZpbHRlcmFibGU6ITEsYnl0ZXNQZXJFbGVtZW50Ols4XSx0eXBlOltvdF19LGVbZ2FdPXt0ZXh0dXJlRm9ybWF0Ol9lLGNvbG9yUmVuZGVyYWJsZTohMCx0ZXh0dXJlRmlsdGVyYWJsZTohMSxieXRlc1BlckVsZW1lbnQ6WzE2XSx0eXBlOltzdF19LGVbYmFdPXt0ZXh0dXJlRm9ybWF0Ol9lLGNvbG9yUmVuZGVyYWJsZTohMCx0ZXh0dXJlRmlsdGVyYWJsZTohMSxieXRlc1BlckVsZW1lbnQ6WzE2XSx0eXBlOlt5ZV19LGVbdmFdPXt0ZXh0dXJlRm9ybWF0OlVlLGNvbG9yUmVuZGVyYWJsZTohMCx0ZXh0dXJlRmlsdGVyYWJsZTohMSxieXRlc1BlckVsZW1lbnQ6WzIsNF0sdHlwZTpbRWUseWVdfSxlW0VhXT17dGV4dHVyZUZvcm1hdDpVZSxjb2xvclJlbmRlcmFibGU6ITAsdGV4dHVyZUZpbHRlcmFibGU6ITEsYnl0ZXNQZXJFbGVtZW50Ols0XSx0eXBlOlt5ZV19LGVbVGFdPXt0ZXh0dXJlRm9ybWF0OlVlLGNvbG9yUmVuZGVyYWJsZTohMCx0ZXh0dXJlRmlsdGVyYWJsZTohMSxieXRlc1BlckVsZW1lbnQ6WzRdLHR5cGU6W0NdfSxlW3dhXT17dGV4dHVyZUZvcm1hdDpubixjb2xvclJlbmRlcmFibGU6ITAsdGV4dHVyZUZpbHRlcmFibGU6ITEsYnl0ZXNQZXJFbGVtZW50Ols0XSx0eXBlOltGYV19LGVbQWFdPXt0ZXh0dXJlRm9ybWF0Om5uLGNvbG9yUmVuZGVyYWJsZTohMCx0ZXh0dXJlRmlsdGVyYWJsZTohMSxieXRlc1BlckVsZW1lbnQ6WzRdLHR5cGU6W0lhXX0sT2JqZWN0LmtleXMoZSkuZm9yRWFjaChmdW5jdGlvbih0KXtjb25zdCBuPWVbdF07bi5ieXRlc1BlckVsZW1lbnRNYXA9e30sbi5ieXRlc1BlckVsZW1lbnQuZm9yRWFjaChmdW5jdGlvbihpLG8pe2NvbnN0IHM9bi50eXBlW29dO24uYnl0ZXNQZXJFbGVtZW50TWFwW3NdPWl9KX0pLFp0PWV9cmV0dXJuIFp0W3JdfWZ1bmN0aW9uIFBhKHIsZSl7Y29uc3QgdD1jdChyKTtpZighdCl0aHJvdyJ1bmtub3duIGludGVybmFsIGZvcm1hdCI7Y29uc3Qgbj10LmJ5dGVzUGVyRWxlbWVudE1hcFtlXTtpZihuPT09dm9pZCAwKXRocm93InVua25vd24gaW50ZXJuYWwgZm9ybWF0IjtyZXR1cm4gbn1mdW5jdGlvbiBDZShyKXtjb25zdCBlPWN0KHIpO2lmKCFlKXRocm93InVua25vd24gaW50ZXJuYWwgZm9ybWF0IjtyZXR1cm57Zm9ybWF0OmUudGV4dHVyZUZvcm1hdCx0eXBlOmUudHlwZVswXX19ZnVuY3Rpb24gaG4ocil7cmV0dXJuKHImci0xKT09PTB9ZnVuY3Rpb24gRGEocixlLHQsbil7aWYoIU5lKHIpKXJldHVybiBobihlKSYmaG4odCk7Y29uc3QgaT1jdChuKTtpZighaSl0aHJvdyJ1bmtub3duIGludGVybmFsIGZvcm1hdCI7cmV0dXJuIGkuY29sb3JSZW5kZXJhYmxlJiZpLnRleHR1cmVGaWx0ZXJhYmxlfWZ1bmN0aW9uIE5hKHIpe2NvbnN0IGU9Y3Qocik7aWYoIWUpdGhyb3cidW5rbm93biBpbnRlcm5hbCBmb3JtYXQiO3JldHVybiBlLnRleHR1cmVGaWx0ZXJhYmxlfWZ1bmN0aW9uIE1hKHIsZSx0KXtyZXR1cm4gTWUoZSk/VnQoZSk6dHx8Un1mdW5jdGlvbiBmdChyLGUsdCxuLGkpe2lmKGklMSE9PTApdGhyb3ciY2FuJ3QgZ3Vlc3MgZGltZW5zaW9ucyI7aWYoIXQmJiFuKXtjb25zdCBvPU1hdGguc3FydChpLyhlPT09b2U/NjoxKSk7byUxPT09MD8odD1vLG49byk6KHQ9aSxuPTEpfWVsc2UgaWYobil7aWYoIXQmJih0PWkvbix0JTEpKXRocm93ImNhbid0IGd1ZXNzIGRpbWVuc2lvbnMifWVsc2UgaWYobj1pL3QsbiUxKXRocm93ImNhbid0IGd1ZXNzIGRpbWVuc2lvbnMiO3JldHVybnt3aWR0aDp0LGhlaWdodDpufX1mdW5jdGlvbiBTZShyLGUpe2UuY29sb3JzcGFjZUNvbnZlcnNpb24hPT12b2lkIDAmJnIucGl4ZWxTdG9yZWkoVHMsZS5jb2xvcnNwYWNlQ29udmVyc2lvbiksZS5wcmVtdWx0aXBseUFscGhhIT09dm9pZCAwJiZyLnBpeGVsU3RvcmVpKEFzLGUucHJlbXVsdGlwbHlBbHBoYSksZS5mbGlwWSE9PXZvaWQgMCYmci5waXhlbFN0b3JlaSh3cyxlLmZsaXBZKX1mdW5jdGlvbiBwbihyKXtyLnBpeGVsU3RvcmVpKHF0LDQpLE5lKHIpJiYoci5waXhlbFN0b3JlaShzbiwwKSxyLnBpeGVsU3RvcmVpKGFuLDApLHIucGl4ZWxTdG9yZWkodW4sMCksci5waXhlbFN0b3JlaShjbiwwKSxyLnBpeGVsU3RvcmVpKGZuLDApKX1mdW5jdGlvbiBVYShyLGUsdCxuKXtuLm1pbk1hZyYmKHQuY2FsbChyLGUsUXQsbi5taW5NYWcpLHQuY2FsbChyLGUsS3Qsbi5taW5NYWcpKSxuLm1pbiYmdC5jYWxsKHIsZSxRdCxuLm1pbiksbi5tYWcmJnQuY2FsbChyLGUsS3Qsbi5tYWcpLG4ud3JhcCYmKHQuY2FsbChyLGUsbnQsbi53cmFwKSx0LmNhbGwocixlLGl0LG4ud3JhcCksKGU9PT1oZXx8em8ocixlKSkmJnQuY2FsbChyLGUsb24sbi53cmFwKSksbi53cmFwUiYmdC5jYWxsKHIsZSxvbixuLndyYXBSKSxuLndyYXBTJiZ0LmNhbGwocixlLG50LG4ud3JhcFMpLG4ud3JhcFQmJnQuY2FsbChyLGUsaXQsbi53cmFwVCksbi5taW5Mb2QmJnQuY2FsbChyLGUsZ3Msbi5taW5Mb2QpLG4ubWF4TG9kJiZ0LmNhbGwocixlLGJzLG4ubWF4TG9kKSxuLmJhc2VMZXZlbCYmdC5jYWxsKHIsZSx2cyxuLmJhc2VMZXZlbCksbi5tYXhMZXZlbCYmdC5jYWxsKHIsZSxFcyxuLm1heExldmVsKX1mdW5jdGlvbiB5bihyLGUsdCl7Y29uc3Qgbj10LnRhcmdldHx8aWU7ci5iaW5kVGV4dHVyZShuLGUpLFVhKHIsbixyLnRleFBhcmFtZXRlcmksdCl9ZnVuY3Rpb24ga2Eocil7cmV0dXJuIHI9cnx8bmUudGV4dHVyZUNvbG9yLE1lKHIpP3I6bmV3IFVpbnQ4QXJyYXkoW3JbMF0qMjU1LHJbMV0qMjU1LHJbMl0qMjU1LHJbM10qMjU1XSl9ZnVuY3Rpb24gZXIocixlLHQsbixpLG8pe3Q9dHx8bmUudGV4dHVyZU9wdGlvbnMsbz1vfHxGO2NvbnN0IHM9dC50YXJnZXR8fGllO2lmKG49bnx8dC53aWR0aCxpPWl8fHQuaGVpZ2h0LHIuYmluZFRleHR1cmUocyxlKSxEYShyLG4saSxvKSlyLmdlbmVyYXRlTWlwbWFwKHMpO2Vsc2V7Y29uc3QgYT1OYShvKT9tczpkcztyLnRleFBhcmFtZXRlcmkocyxRdCxhKSxyLnRleFBhcmFtZXRlcmkocyxLdCxhKSxyLnRleFBhcmFtZXRlcmkocyxudCxydCksci50ZXhQYXJhbWV0ZXJpKHMsaXQscnQpfX1mdW5jdGlvbiBPZShyKXtyZXR1cm4gci5hdXRvPT09ITB8fHIuYXV0bz09PXZvaWQgMCYmci5sZXZlbD09PXZvaWQgMH1mdW5jdGlvbiB0cihyLGUpe3JldHVybiBlPWV8fHt9LGUuY3ViZUZhY2VPcmRlcnx8W1h0LGhzLHBzLHlzLF9zLHhzXX1mdW5jdGlvbiBycihyLGUpe2NvbnN0IG49dHIocixlKS5tYXAoZnVuY3Rpb24oaSxvKXtyZXR1cm57ZmFjZTppLG5keDpvfX0pO3JldHVybiBuLnNvcnQoZnVuY3Rpb24oaSxvKXtyZXR1cm4gaS5mYWNlLW8uZmFjZX0pLG59ZnVuY3Rpb24gX24ocixlLHQsbil7bj1ufHxuZS50ZXh0dXJlT3B0aW9ucztjb25zdCBpPW4udGFyZ2V0fHxpZSxvPW4ubGV2ZWx8fDA7bGV0IHM9dC53aWR0aCxhPXQuaGVpZ2h0O2NvbnN0IHU9bi5pbnRlcm5hbEZvcm1hdHx8bi5mb3JtYXR8fEYsZj1DZSh1KSxkPW4uZm9ybWF0fHxmLmZvcm1hdCxoPW4udHlwZXx8Zi50eXBlO2lmKFNlKHIsbiksci5iaW5kVGV4dHVyZShpLGUpLGk9PT1vZSl7Y29uc3QgeT10LndpZHRoLHg9dC5oZWlnaHQ7bGV0IGwsZztpZih5LzY9PT14KWw9eCxnPVswLDAsMSwwLDIsMCwzLDAsNCwwLDUsMF07ZWxzZSBpZih4LzY9PT15KWw9eSxnPVswLDAsMCwxLDAsMiwwLDMsMCw0LDAsNV07ZWxzZSBpZih5LzM9PT14LzIpbD15LzMsZz1bMCwwLDEsMCwyLDAsMCwxLDEsMSwyLDFdO2Vsc2UgaWYoeS8yPT09eC8zKWw9eS8yLGc9WzAsMCwxLDAsMCwxLDEsMSwwLDIsMSwyXTtlbHNlIHRocm93ImNhbid0IGZpZ3VyZSBvdXQgY3ViZSBtYXAgZnJvbSBlbGVtZW50OiAiKyh0LnNyYz90LnNyYzp0Lm5vZGVOYW1lKTtjb25zdCBFPVpyKCk7RT8oRS5jYW52YXMud2lkdGg9bCxFLmNhbnZhcy5oZWlnaHQ9bCxzPWwsYT1sLHJyKHIsbikuZm9yRWFjaChmdW5jdGlvbih2KXtjb25zdCBJPWdbdi5uZHgqMiswXSpsLEQ9Z1t2Lm5keCoyKzFdKmw7RS5kcmF3SW1hZ2UodCxJLEQsbCxsLDAsMCxsLGwpLHIudGV4SW1hZ2UyRCh2LmZhY2Usbyx1LGQsaCxFLmNhbnZhcyl9KSxFLmNhbnZhcy53aWR0aD0xLEUuY2FudmFzLmhlaWdodD0xKTp0eXBlb2YgY3JlYXRlSW1hZ2VCaXRtYXA8InUiJiYocz1sLGE9bCxycihyLG4pLmZvckVhY2goZnVuY3Rpb24odil7Y29uc3QgST1nW3YubmR4KjIrMF0qbCxEPWdbdi5uZHgqMisxXSpsO3IudGV4SW1hZ2UyRCh2LmZhY2Usbyx1LGwsbCwwLGQsaCxudWxsKSxjcmVhdGVJbWFnZUJpdG1hcCh0LEksRCxsLGwse3ByZW11bHRpcGx5QWxwaGE6Im5vbmUiLGNvbG9yU3BhY2VDb252ZXJzaW9uOiJub25lIn0pLnRoZW4oZnVuY3Rpb24oRyl7U2UocixuKSxyLmJpbmRUZXh0dXJlKGksZSksci50ZXhJbWFnZTJEKHYuZmFjZSxvLHUsZCxoLEcpLE9lKG4pJiZlcihyLGUsbixzLGEsdSl9KX0pKX1lbHNlIGlmKGk9PT1oZXx8aT09PXBlKXtjb25zdCB5PU1hdGgubWluKHQud2lkdGgsdC5oZWlnaHQpLHg9TWF0aC5tYXgodC53aWR0aCx0LmhlaWdodCksbD14L3k7aWYobCUxIT09MCl0aHJvdyJjYW4gbm90IGNvbXB1dGUgM0QgZGltZW5zaW9ucyBvZiBlbGVtZW50Ijtjb25zdCBnPXQud2lkdGg9PT14PzE6MCxFPXQuaGVpZ2h0PT09eD8xOjA7ci5waXhlbFN0b3JlaShxdCwxKSxyLnBpeGVsU3RvcmVpKHNuLHQud2lkdGgpLHIucGl4ZWxTdG9yZWkoYW4sMCksci5waXhlbFN0b3JlaShmbiwwKSxyLnRleEltYWdlM0QoaSxvLHUseSx5LHksMCxkLGgsbnVsbCk7Zm9yKGxldCB2PTA7djxsOysrdil7Y29uc3QgST12KnkqZyxEPXYqeSpFO3IucGl4ZWxTdG9yZWkodW4sSSksci5waXhlbFN0b3JlaShjbixEKSxyLnRleFN1YkltYWdlM0QoaSxvLDAsMCx2LHkseSwxLGQsaCx0KX1wbihyKX1lbHNlIHIudGV4SW1hZ2UyRChpLG8sdSxkLGgsdCk7T2UobikmJmVyKHIsZSxuLHMsYSx1KSx5bihyLGUsbil9ZnVuY3Rpb24gQmUoKXt9ZnVuY3Rpb24gQ2Eocil7aWYodHlwZW9mIGRvY3VtZW50PCJ1Iil7Y29uc3QgZT1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJhIik7cmV0dXJuIGUuaHJlZj1yLGUuaG9zdG5hbWU9PT1sb2NhdGlvbi5ob3N0bmFtZSYmZS5wb3J0PT09bG9jYXRpb24ucG9ydCYmZS5wcm90b2NvbD09PWxvY2F0aW9uLnByb3RvY29sfWVsc2V7Y29uc3QgZT1uZXcgVVJMKGxvY2F0aW9uLmhyZWYpLm9yaWdpbjtyZXR1cm4gbmV3IFVSTChyLGxvY2F0aW9uLmhyZWYpLm9yaWdpbj09PWV9fWZ1bmN0aW9uIE9hKHIsZSl7cmV0dXJuIGU9PT12b2lkIDAmJiFDYShyKT8iYW5vbnltb3VzIjplfWZ1bmN0aW9uIEJhKHIsZSx0KXt0PXR8fEJlO2xldCBuO2lmKGU9ZSE9PXZvaWQgMD9lOm5lLmNyb3NzT3JpZ2luLGU9T2EocixlKSx0eXBlb2YgSW1hZ2U8InUiKXtuPW5ldyBJbWFnZSxlIT09dm9pZCAwJiYobi5jcm9zc09yaWdpbj1lKTtjb25zdCBpPWZ1bmN0aW9uKCl7bi5yZW1vdmVFdmVudExpc3RlbmVyKCJlcnJvciIsbyksbi5yZW1vdmVFdmVudExpc3RlbmVyKCJsb2FkIixzKSxuPW51bGx9LG89ZnVuY3Rpb24oKXtjb25zdCB1PSJjb3VsZG4ndCBsb2FkIGltYWdlOiAiK3I7VnIodSksdCh1LG4pLGkoKX0scz1mdW5jdGlvbigpe3QobnVsbCxuKSxpKCl9O3JldHVybiBuLmFkZEV2ZW50TGlzdGVuZXIoImVycm9yIixvKSxuLmFkZEV2ZW50TGlzdGVuZXIoImxvYWQiLHMpLG4uc3JjPXIsbn1lbHNlIGlmKHR5cGVvZiBJbWFnZUJpdG1hcDwidSIpe2xldCBpLG87Y29uc3Qgcz1mdW5jdGlvbigpe3QoaSxvKX0sYT17fTtlJiYoYS5tb2RlPSJjb3JzIiksZmV0Y2gocixhKS50aGVuKGZ1bmN0aW9uKHUpe2lmKCF1Lm9rKXRocm93IHU7cmV0dXJuIHUuYmxvYigpfSkudGhlbihmdW5jdGlvbih1KXtyZXR1cm4gY3JlYXRlSW1hZ2VCaXRtYXAodSx7cHJlbXVsdGlwbHlBbHBoYToibm9uZSIsY29sb3JTcGFjZUNvbnZlcnNpb246Im5vbmUifSl9KS50aGVuKGZ1bmN0aW9uKHUpe289dSxzZXRUaW1lb3V0KHMpfSkuY2F0Y2goZnVuY3Rpb24odSl7aT11LHNldFRpbWVvdXQocyl9KSxuPW51bGx9cmV0dXJuIG59ZnVuY3Rpb24geG4ocil7cmV0dXJuIHR5cGVvZiBJbWFnZUJpdG1hcDwidSImJnIgaW5zdGFuY2VvZiBJbWFnZUJpdG1hcHx8dHlwZW9mIEltYWdlRGF0YTwidSImJnIgaW5zdGFuY2VvZiBJbWFnZURhdGF8fHR5cGVvZiBIVE1MRWxlbWVudDwidSImJnIgaW5zdGFuY2VvZiBIVE1MRWxlbWVudH1mdW5jdGlvbiBucihyLGUsdCl7cmV0dXJuIHhuKHIpPyhzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7dChudWxsLHIpfSkscik6QmEocixlLHQpfWZ1bmN0aW9uIGlyKHIsZSx0KXt0PXR8fG5lLnRleHR1cmVPcHRpb25zO2NvbnN0IG49dC50YXJnZXR8fGllO2lmKHIuYmluZFRleHR1cmUobixlKSx0LmNvbG9yPT09ITEpcmV0dXJuO2NvbnN0IGk9a2EodC5jb2xvcik7aWYobj09PW9lKWZvcihsZXQgbz0wO288NjsrK28pci50ZXhJbWFnZTJEKFh0K28sMCxGLDEsMSwwLEYsUixpKTtlbHNlIG49PT1oZXx8bj09PXBlP3IudGV4SW1hZ2UzRChuLDAsRiwxLDEsMSwwLEYsUixpKTpyLnRleEltYWdlMkQobiwwLEYsMSwxLDAsRixSLGkpfWZ1bmN0aW9uIExhKHIsZSx0LG4pe3JldHVybiBuPW58fEJlLHQ9dHx8bmUudGV4dHVyZU9wdGlvbnMsaXIocixlLHQpLHQ9T2JqZWN0LmFzc2lnbih7fSx0KSxucih0LnNyYyx0LmNyb3NzT3JpZ2luLGZ1bmN0aW9uKG8scyl7bz9uKG8sZSxzKTooX24ocixlLHMsdCksbihudWxsLGUscykpfSl9ZnVuY3Rpb24gR2EocixlLHQsbil7bj1ufHxCZTtjb25zdCBpPXQuc3JjO2lmKGkubGVuZ3RoIT09Nil0aHJvdyJ0aGVyZSBtdXN0IGJlIDYgdXJscyBmb3IgYSBjdWJlbWFwIjtjb25zdCBvPXQubGV2ZWx8fDAscz10LmludGVybmFsRm9ybWF0fHx0LmZvcm1hdHx8RixhPUNlKHMpLHU9dC5mb3JtYXR8fGEuZm9ybWF0LGY9dC50eXBlfHxSLGQ9dC50YXJnZXR8fGllO2lmKGQhPT1vZSl0aHJvdyJ0YXJnZXQgbXVzdCBiZSBURVhUVVJFX0NVQkVfTUFQIjtpcihyLGUsdCksdD1PYmplY3QuYXNzaWduKHt9LHQpO2xldCBoPTY7Y29uc3QgeT1bXSx4PXRyKHIsdCk7bGV0IGw7ZnVuY3Rpb24gZyhFKXtyZXR1cm4gZnVuY3Rpb24odixJKXstLWgsdj95LnB1c2godik6SS53aWR0aCE9PUkuaGVpZ2h0P3kucHVzaCgiY3ViZW1hcCBmYWNlIGltZyBpcyBub3QgYSBzcXVhcmU6ICIrSS5zcmMpOihTZShyLHQpLHIuYmluZFRleHR1cmUoZCxlKSxoPT09NT90cigpLmZvckVhY2goZnVuY3Rpb24oRCl7ci50ZXhJbWFnZTJEKEQsbyxzLHUsZixJKX0pOnIudGV4SW1hZ2UyRChFLG8scyx1LGYsSSksT2UodCkmJnIuZ2VuZXJhdGVNaXBtYXAoZCkpLGg9PT0wJiZuKHkubGVuZ3RoP3k6dm9pZCAwLGUsbCl9fWw9aS5tYXAoZnVuY3Rpb24oRSx2KXtyZXR1cm4gbnIoRSx0LmNyb3NzT3JpZ2luLGcoeFt2XSkpfSl9ZnVuY3Rpb24gJGEocixlLHQsbil7bj1ufHxCZTtjb25zdCBpPXQuc3JjLG89dC5pbnRlcm5hbEZvcm1hdHx8dC5mb3JtYXR8fEYscz1DZShvKSxhPXQuZm9ybWF0fHxzLmZvcm1hdCx1PXQudHlwZXx8UixmPXQudGFyZ2V0fHxwZTtpZihmIT09aGUmJmYhPT1wZSl0aHJvdyJ0YXJnZXQgbXVzdCBiZSBURVhUVVJFXzNEIG9yIFRFWFRVUkVfMkRfQVJSQVkiO2lyKHIsZSx0KSx0PU9iamVjdC5hc3NpZ24oe30sdCk7bGV0IGQ9aS5sZW5ndGg7Y29uc3QgaD1bXTtsZXQgeTtjb25zdCB4PXQubGV2ZWx8fDA7bGV0IGw9dC53aWR0aCxnPXQuaGVpZ2h0O2NvbnN0IEU9aS5sZW5ndGg7bGV0IHY9ITA7ZnVuY3Rpb24gSShEKXtyZXR1cm4gZnVuY3Rpb24oRywkKXtpZigtLWQsRyloLnB1c2goRyk7ZWxzZXtpZihTZShyLHQpLHIuYmluZFRleHR1cmUoZixlKSx2KXt2PSExLGw9dC53aWR0aHx8JC53aWR0aCxnPXQuaGVpZ2h0fHwkLmhlaWdodCxyLnRleEltYWdlM0QoZix4LG8sbCxnLEUsMCxhLHUsbnVsbCk7Zm9yKGxldCBaPTA7WjxFOysrWilyLnRleFN1YkltYWdlM0QoZix4LDAsMCxaLGwsZywxLGEsdSwkKX1lbHNle2xldCBaPSQsSDsoJC53aWR0aCE9PWx8fCQuaGVpZ2h0IT09ZykmJihIPVpyKCksWj1ILmNhbnZhcyxILmNhbnZhcy53aWR0aD1sLEguY2FudmFzLmhlaWdodD1nLEguZHJhd0ltYWdlKCQsMCwwLGwsZykpLHIudGV4U3ViSW1hZ2UzRChmLHgsMCwwLEQsbCxnLDEsYSx1LFopLEgmJlo9PT1ILmNhbnZhcyYmKEguY2FudmFzLndpZHRoPTAsSC5jYW52YXMuaGVpZ2h0PTApfU9lKHQpJiZyLmdlbmVyYXRlTWlwbWFwKGYpfWQ9PT0wJiZuKGgubGVuZ3RoP2g6dm9pZCAwLGUseSl9fXk9aS5tYXAoZnVuY3Rpb24oRCxHKXtyZXR1cm4gbnIoRCx0LmNyb3NzT3JpZ2luLEkoRykpfSl9ZnVuY3Rpb24gemEocixlLHQsbil7bj1ufHxuZS50ZXh0dXJlT3B0aW9ucztjb25zdCBpPW4udGFyZ2V0fHxpZTtyLmJpbmRUZXh0dXJlKGksZSk7bGV0IG89bi53aWR0aCxzPW4uaGVpZ2h0LGE9bi5kZXB0aDtjb25zdCB1PW4ubGV2ZWx8fDAsZj1uLmludGVybmFsRm9ybWF0fHxuLmZvcm1hdHx8RixkPUNlKGYpLGg9bi5mb3JtYXR8fGQuZm9ybWF0LHk9bi50eXBlfHxNYShyLHQsZC50eXBlKTtpZihNZSh0KSl0IGluc3RhbmNlb2YgVWludDhDbGFtcGVkQXJyYXkmJih0PW5ldyBVaW50OEFycmF5KHQuYnVmZmVyKSk7ZWxzZXtjb25zdCBFPVdyKHkpO3Q9bmV3IEUodCl9Y29uc3QgeD1QYShmLHkpLGw9dC5ieXRlTGVuZ3RoL3g7aWYobCUxKXRocm93Imxlbmd0aCB3cm9uZyBzaXplIGZvciBmb3JtYXQ6ICIrSnIocixoKTtsZXQgZztpZihpPT09aGV8fGk9PT1wZSlpZighbyYmIXMmJiFhKXtjb25zdCBFPU1hdGguY2JydChsKTtpZihFJTEhPT0wKXRocm93ImNhbid0IGd1ZXNzIGN1YmUgc2l6ZSBvZiBhcnJheSBvZiBudW1FbGVtZW50czogIitsO289RSxzPUUsYT1FfWVsc2UgbyYmKCFzfHwhYSk/KGc9ZnQocixpLHMsYSxsL28pLHM9Zy53aWR0aCxhPWcuaGVpZ2h0KTpzJiYoIW98fCFhKT8oZz1mdChyLGksbyxhLGwvcyksbz1nLndpZHRoLGE9Zy5oZWlnaHQpOihnPWZ0KHIsaSxvLHMsbC9hKSxvPWcud2lkdGgscz1nLmhlaWdodCk7ZWxzZSBnPWZ0KHIsaSxvLHMsbCksbz1nLndpZHRoLHM9Zy5oZWlnaHQ7aWYocG4ociksci5waXhlbFN0b3JlaShxdCxuLnVucGFja0FsaWdubWVudHx8MSksU2UocixuKSxpPT09b2Upe2NvbnN0IEU9eC90LkJZVEVTX1BFUl9FTEVNRU5ULHY9bC82KkU7cnIocixuKS5mb3JFYWNoKEk9Pntjb25zdCBEPXYqSS5uZHgsRz10LnN1YmFycmF5KEQsRCt2KTtyLnRleEltYWdlMkQoSS5mYWNlLHUsZixvLHMsMCxoLHksRyl9KX1lbHNlIGk9PT1oZXx8aT09PXBlP3IudGV4SW1hZ2UzRChpLHUsZixvLHMsYSwwLGgseSx0KTpyLnRleEltYWdlMkQoaSx1LGYsbyxzLDAsaCx5LHQpO3JldHVybnt3aWR0aDpvLGhlaWdodDpzLGRlcHRoOmEsdHlwZTp5fX1mdW5jdGlvbiBXYShyLGUsdCl7Y29uc3Qgbj10LnRhcmdldHx8aWU7ci5iaW5kVGV4dHVyZShuLGUpO2NvbnN0IGk9dC5sZXZlbHx8MCxvPXQuaW50ZXJuYWxGb3JtYXR8fHQuZm9ybWF0fHxGLHM9Q2UobyksYT10LmZvcm1hdHx8cy5mb3JtYXQsdT10LnR5cGV8fHMudHlwZTtpZihTZShyLHQpLG49PT1vZSlmb3IobGV0IGY9MDtmPDY7KytmKXIudGV4SW1hZ2UyRChYdCtmLGksbyx0LndpZHRoLHQuaGVpZ2h0LDAsYSx1LG51bGwpO2Vsc2Ugbj09PWhlfHxuPT09cGU/ci50ZXhJbWFnZTNEKG4saSxvLHQud2lkdGgsdC5oZWlnaHQsdC5kZXB0aCwwLGEsdSxudWxsKTpyLnRleEltYWdlMkQobixpLG8sdC53aWR0aCx0LmhlaWdodCwwLGEsdSxudWxsKX1mdW5jdGlvbiBnbihyLGUsdCl7dD10fHxCZSxlPWV8fG5lLnRleHR1cmVPcHRpb25zO2NvbnN0IG49ci5jcmVhdGVUZXh0dXJlKCksaT1lLnRhcmdldHx8aWU7bGV0IG89ZS53aWR0aHx8MSxzPWUuaGVpZ2h0fHwxO2NvbnN0IGE9ZS5pbnRlcm5hbEZvcm1hdHx8RjtyLmJpbmRUZXh0dXJlKGksbiksaT09PW9lJiYoci50ZXhQYXJhbWV0ZXJpKGksbnQscnQpLHIudGV4UGFyYW1ldGVyaShpLGl0LHJ0KSk7bGV0IHU9ZS5zcmM7aWYodSlpZih0eXBlb2YgdT09ImZ1bmN0aW9uIiYmKHU9dShyLGUpKSx0eXBlb2YgdT09InN0cmluZyIpTGEocixuLGUsdCk7ZWxzZSBpZihNZSh1KXx8QXJyYXkuaXNBcnJheSh1KSYmKHR5cGVvZiB1WzBdPT0ibnVtYmVyInx8QXJyYXkuaXNBcnJheSh1WzBdKXx8TWUodVswXSkpKXtjb25zdCBmPXphKHIsbix1LGUpO289Zi53aWR0aCxzPWYuaGVpZ2h0fWVsc2UgQXJyYXkuaXNBcnJheSh1KSYmKHR5cGVvZiB1WzBdPT0ic3RyaW5nInx8eG4odVswXSkpP2k9PT1vZT9HYShyLG4sZSx0KTokYShyLG4sZSx0KTooX24ocixuLHUsZSksbz11LndpZHRoLHM9dS5oZWlnaHQpO2Vsc2UgV2EocixuLGUpO3JldHVybiBPZShlKSYmZXIocixuLGUsbyxzLGEpLHluKHIsbixlKSxufWNvbnN0IG9yPVZyO2Z1bmN0aW9uIGJuKHIpe3JldHVybiB0eXBlb2YgZG9jdW1lbnQ8InUiJiZkb2N1bWVudC5nZXRFbGVtZW50QnlJZD9kb2N1bWVudC5nZXRFbGVtZW50QnlJZChyKTpudWxsfWNvbnN0IGx0PTMzOTg0LGR0PTM0OTYyLFZhPTM0OTYzLEhhPTM1NzEzLFlhPTM1NzE0LGphPTM1NjMyLFhhPTM1NjMzLFFhPTM1OTgxLHZuPTM1NzE4LEthPTM1NzIxLHFhPTM1OTcxLEphPTM1MzgyLFphPTM1Mzk2LGV1PTM1Mzk4LHR1PTM1MzkyLHJ1PTM1Mzk1LG10PTUxMjYsRW49MzU2NjQsVG49MzU2NjUsQW49MzU2NjYsc3I9NTEyNCx3bj0zNTY2NyxTbj0zNTY2OCxSbj0zNTY2OSxJbj0zNTY3MCxGbj0zNTY3MSxQbj0zNTY3MixEbj0zNTY3MyxObj0zNTY3NCxNbj0zNTY3NSxVbj0zNTY3NixudT0zNTY3OCxpdT0zNTY4MCxvdT0zNTY3OSxzdT0zNTY4MixhdT0zNTY4NSx1dT0zNTY4NixjdT0zNTY4NyxmdT0zNTY4OCxsdT0zNTY4OSxkdT0zNTY5MCxtdT0zNjI4OSxodT0zNjI5MixwdT0zNjI5Myxhcj01MTI1LGtuPTM2Mjk0LENuPTM2Mjk1LE9uPTM2Mjk2LHl1PTM2Mjk4LF91PTM2Mjk5LHh1PTM2MzAwLGd1PTM2MzAzLGJ1PTM2MzA2LHZ1PTM2MzA3LEV1PTM2MzA4LFR1PTM2MzExLGh0PTM1NTMscHQ9MzQwNjcsdXI9MzI4NzkseXQ9MzU4NjYsYj17fTtmdW5jdGlvbiBCbihyLGUpe3JldHVybiBiW2VdLmJpbmRQb2ludH1mdW5jdGlvbiBBdShyLGUpe3JldHVybiBmdW5jdGlvbih0KXtyLnVuaWZvcm0xZihlLHQpfX1mdW5jdGlvbiB3dShyLGUpe3JldHVybiBmdW5jdGlvbih0KXtyLnVuaWZvcm0xZnYoZSx0KX19ZnVuY3Rpb24gU3UocixlKXtyZXR1cm4gZnVuY3Rpb24odCl7ci51bmlmb3JtMmZ2KGUsdCl9fWZ1bmN0aW9uIFJ1KHIsZSl7cmV0dXJuIGZ1bmN0aW9uKHQpe3IudW5pZm9ybTNmdihlLHQpfX1mdW5jdGlvbiBJdShyLGUpe3JldHVybiBmdW5jdGlvbih0KXtyLnVuaWZvcm00ZnYoZSx0KX19ZnVuY3Rpb24gTG4ocixlKXtyZXR1cm4gZnVuY3Rpb24odCl7ci51bmlmb3JtMWkoZSx0KX19ZnVuY3Rpb24gR24ocixlKXtyZXR1cm4gZnVuY3Rpb24odCl7ci51bmlmb3JtMWl2KGUsdCl9fWZ1bmN0aW9uICRuKHIsZSl7cmV0dXJuIGZ1bmN0aW9uKHQpe3IudW5pZm9ybTJpdihlLHQpfX1mdW5jdGlvbiB6bihyLGUpe3JldHVybiBmdW5jdGlvbih0KXtyLnVuaWZvcm0zaXYoZSx0KX19ZnVuY3Rpb24gV24ocixlKXtyZXR1cm4gZnVuY3Rpb24odCl7ci51bmlmb3JtNGl2KGUsdCl9fWZ1bmN0aW9uIEZ1KHIsZSl7cmV0dXJuIGZ1bmN0aW9uKHQpe3IudW5pZm9ybTF1aShlLHQpfX1mdW5jdGlvbiBQdShyLGUpe3JldHVybiBmdW5jdGlvbih0KXtyLnVuaWZvcm0xdWl2KGUsdCl9fWZ1bmN0aW9uIER1KHIsZSl7cmV0dXJuIGZ1bmN0aW9uKHQpe3IudW5pZm9ybTJ1aXYoZSx0KX19ZnVuY3Rpb24gTnUocixlKXtyZXR1cm4gZnVuY3Rpb24odCl7ci51bmlmb3JtM3VpdihlLHQpfX1mdW5jdGlvbiBNdShyLGUpe3JldHVybiBmdW5jdGlvbih0KXtyLnVuaWZvcm00dWl2KGUsdCl9fWZ1bmN0aW9uIFV1KHIsZSl7cmV0dXJuIGZ1bmN0aW9uKHQpe3IudW5pZm9ybU1hdHJpeDJmdihlLCExLHQpfX1mdW5jdGlvbiBrdShyLGUpe3JldHVybiBmdW5jdGlvbih0KXtyLnVuaWZvcm1NYXRyaXgzZnYoZSwhMSx0KX19ZnVuY3Rpb24gQ3UocixlKXtyZXR1cm4gZnVuY3Rpb24odCl7ci51bmlmb3JtTWF0cml4NGZ2KGUsITEsdCl9fWZ1bmN0aW9uIE91KHIsZSl7cmV0dXJuIGZ1bmN0aW9uKHQpe3IudW5pZm9ybU1hdHJpeDJ4M2Z2KGUsITEsdCl9fWZ1bmN0aW9uIEJ1KHIsZSl7cmV0dXJuIGZ1bmN0aW9uKHQpe3IudW5pZm9ybU1hdHJpeDN4MmZ2KGUsITEsdCl9fWZ1bmN0aW9uIEx1KHIsZSl7cmV0dXJuIGZ1bmN0aW9uKHQpe3IudW5pZm9ybU1hdHJpeDJ4NGZ2KGUsITEsdCl9fWZ1bmN0aW9uIEd1KHIsZSl7cmV0dXJuIGZ1bmN0aW9uKHQpe3IudW5pZm9ybU1hdHJpeDR4MmZ2KGUsITEsdCl9fWZ1bmN0aW9uICR1KHIsZSl7cmV0dXJuIGZ1bmN0aW9uKHQpe3IudW5pZm9ybU1hdHJpeDN4NGZ2KGUsITEsdCl9fWZ1bmN0aW9uIHp1KHIsZSl7cmV0dXJuIGZ1bmN0aW9uKHQpe3IudW5pZm9ybU1hdHJpeDR4M2Z2KGUsITEsdCl9fWZ1bmN0aW9uIEIocixlLHQsbil7Y29uc3QgaT1CbihyLGUpO3JldHVybiBOZShyKT9mdW5jdGlvbihvKXtsZXQgcyxhOyFvfHxIdChyLG8pPyhzPW8sYT1udWxsKToocz1vLnRleHR1cmUsYT1vLnNhbXBsZXIpLHIudW5pZm9ybTFpKG4sdCksci5hY3RpdmVUZXh0dXJlKGx0K3QpLHIuYmluZFRleHR1cmUoaSxzKSxyLmJpbmRTYW1wbGVyKHQsYSl9OmZ1bmN0aW9uKG8pe3IudW5pZm9ybTFpKG4sdCksci5hY3RpdmVUZXh0dXJlKGx0K3QpLHIuYmluZFRleHR1cmUoaSxvKX19ZnVuY3Rpb24gTChyLGUsdCxuLGkpe2NvbnN0IG89Qm4ocixlKSxzPW5ldyBJbnQzMkFycmF5KGkpO2ZvcihsZXQgYT0wO2E8aTsrK2Epc1thXT10K2E7cmV0dXJuIE5lKHIpP2Z1bmN0aW9uKGEpe3IudW5pZm9ybTFpdihuLHMpLGEuZm9yRWFjaChmdW5jdGlvbih1LGYpe3IuYWN0aXZlVGV4dHVyZShsdCtzW2ZdKTtsZXQgZCxoO0h0KHIsdSk/KGQ9dSxoPW51bGwpOihkPXUudGV4dHVyZSxoPXUuc2FtcGxlciksci5iaW5kU2FtcGxlcih0LGgpLHIuYmluZFRleHR1cmUobyxkKX0pfTpmdW5jdGlvbihhKXtyLnVuaWZvcm0xaXYobixzKSxhLmZvckVhY2goZnVuY3Rpb24odSxmKXtyLmFjdGl2ZVRleHR1cmUobHQrc1tmXSksci5iaW5kVGV4dHVyZShvLHUpfSl9fWJbbXRdPXtUeXBlOkZsb2F0MzJBcnJheSxzaXplOjQsc2V0dGVyOkF1LGFycmF5U2V0dGVyOnd1fSxiW0VuXT17VHlwZTpGbG9hdDMyQXJyYXksc2l6ZTo4LHNldHRlcjpTdSxjb2xzOjJ9LGJbVG5dPXtUeXBlOkZsb2F0MzJBcnJheSxzaXplOjEyLHNldHRlcjpSdSxjb2xzOjN9LGJbQW5dPXtUeXBlOkZsb2F0MzJBcnJheSxzaXplOjE2LHNldHRlcjpJdSxjb2xzOjR9LGJbc3JdPXtUeXBlOkludDMyQXJyYXksc2l6ZTo0LHNldHRlcjpMbixhcnJheVNldHRlcjpHbn0sYlt3bl09e1R5cGU6SW50MzJBcnJheSxzaXplOjgsc2V0dGVyOiRuLGNvbHM6Mn0sYltTbl09e1R5cGU6SW50MzJBcnJheSxzaXplOjEyLHNldHRlcjp6bixjb2xzOjN9LGJbUm5dPXtUeXBlOkludDMyQXJyYXksc2l6ZToxNixzZXR0ZXI6V24sY29sczo0fSxiW2FyXT17VHlwZTpVaW50MzJBcnJheSxzaXplOjQsc2V0dGVyOkZ1LGFycmF5U2V0dGVyOlB1fSxiW2tuXT17VHlwZTpVaW50MzJBcnJheSxzaXplOjgsc2V0dGVyOkR1LGNvbHM6Mn0sYltDbl09e1R5cGU6VWludDMyQXJyYXksc2l6ZToxMixzZXR0ZXI6TnUsY29sczozfSxiW09uXT17VHlwZTpVaW50MzJBcnJheSxzaXplOjE2LHNldHRlcjpNdSxjb2xzOjR9LGJbSW5dPXtUeXBlOlVpbnQzMkFycmF5LHNpemU6NCxzZXR0ZXI6TG4sYXJyYXlTZXR0ZXI6R259LGJbRm5dPXtUeXBlOlVpbnQzMkFycmF5LHNpemU6OCxzZXR0ZXI6JG4sY29sczoyfSxiW1BuXT17VHlwZTpVaW50MzJBcnJheSxzaXplOjEyLHNldHRlcjp6bixjb2xzOjN9LGJbRG5dPXtUeXBlOlVpbnQzMkFycmF5LHNpemU6MTYsc2V0dGVyOlduLGNvbHM6NH0sYltObl09e1R5cGU6RmxvYXQzMkFycmF5LHNpemU6MzIsc2V0dGVyOlV1LHJvd3M6Mixjb2xzOjJ9LGJbTW5dPXtUeXBlOkZsb2F0MzJBcnJheSxzaXplOjQ4LHNldHRlcjprdSxyb3dzOjMsY29sczozfSxiW1VuXT17VHlwZTpGbG9hdDMyQXJyYXksc2l6ZTo2NCxzZXR0ZXI6Q3Uscm93czo0LGNvbHM6NH0sYlthdV09e1R5cGU6RmxvYXQzMkFycmF5LHNpemU6MzIsc2V0dGVyOk91LHJvd3M6Mixjb2xzOjN9LGJbdXVdPXtUeXBlOkZsb2F0MzJBcnJheSxzaXplOjMyLHNldHRlcjpMdSxyb3dzOjIsY29sczo0fSxiW2N1XT17VHlwZTpGbG9hdDMyQXJyYXksc2l6ZTo0OCxzZXR0ZXI6QnUscm93czozLGNvbHM6Mn0sYltmdV09e1R5cGU6RmxvYXQzMkFycmF5LHNpemU6NDgsc2V0dGVyOiR1LHJvd3M6Myxjb2xzOjR9LGJbbHVdPXtUeXBlOkZsb2F0MzJBcnJheSxzaXplOjY0LHNldHRlcjpHdSxyb3dzOjQsY29sczoyfSxiW2R1XT17VHlwZTpGbG9hdDMyQXJyYXksc2l6ZTo2NCxzZXR0ZXI6enUscm93czo0LGNvbHM6M30sYltudV09e1R5cGU6bnVsbCxzaXplOjAsc2V0dGVyOkIsYXJyYXlTZXR0ZXI6TCxiaW5kUG9pbnQ6aHR9LGJbaXVdPXtUeXBlOm51bGwsc2l6ZTowLHNldHRlcjpCLGFycmF5U2V0dGVyOkwsYmluZFBvaW50OnB0fSxiW291XT17VHlwZTpudWxsLHNpemU6MCxzZXR0ZXI6QixhcnJheVNldHRlcjpMLGJpbmRQb2ludDp1cn0sYltzdV09e1R5cGU6bnVsbCxzaXplOjAsc2V0dGVyOkIsYXJyYXlTZXR0ZXI6TCxiaW5kUG9pbnQ6aHR9LGJbbXVdPXtUeXBlOm51bGwsc2l6ZTowLHNldHRlcjpCLGFycmF5U2V0dGVyOkwsYmluZFBvaW50Onl0fSxiW2h1XT17VHlwZTpudWxsLHNpemU6MCxzZXR0ZXI6QixhcnJheVNldHRlcjpMLGJpbmRQb2ludDp5dH0sYltwdV09e1R5cGU6bnVsbCxzaXplOjAsc2V0dGVyOkIsYXJyYXlTZXR0ZXI6TCxiaW5kUG9pbnQ6cHR9LGJbeXVdPXtUeXBlOm51bGwsc2l6ZTowLHNldHRlcjpCLGFycmF5U2V0dGVyOkwsYmluZFBvaW50Omh0fSxiW191XT17VHlwZTpudWxsLHNpemU6MCxzZXR0ZXI6QixhcnJheVNldHRlcjpMLGJpbmRQb2ludDp1cn0sYlt4dV09e1R5cGU6bnVsbCxzaXplOjAsc2V0dGVyOkIsYXJyYXlTZXR0ZXI6TCxiaW5kUG9pbnQ6cHR9LGJbZ3VdPXtUeXBlOm51bGwsc2l6ZTowLHNldHRlcjpCLGFycmF5U2V0dGVyOkwsYmluZFBvaW50Onl0fSxiW2J1XT17VHlwZTpudWxsLHNpemU6MCxzZXR0ZXI6QixhcnJheVNldHRlcjpMLGJpbmRQb2ludDpodH0sYlt2dV09e1R5cGU6bnVsbCxzaXplOjAsc2V0dGVyOkIsYXJyYXlTZXR0ZXI6TCxiaW5kUG9pbnQ6dXJ9LGJbRXVdPXtUeXBlOm51bGwsc2l6ZTowLHNldHRlcjpCLGFycmF5U2V0dGVyOkwsYmluZFBvaW50OnB0fSxiW1R1XT17VHlwZTpudWxsLHNpemU6MCxzZXR0ZXI6QixhcnJheVNldHRlcjpMLGJpbmRQb2ludDp5dH07ZnVuY3Rpb24gX3QocixlKXtyZXR1cm4gZnVuY3Rpb24odCl7aWYodC52YWx1ZSlzd2l0Y2goci5kaXNhYmxlVmVydGV4QXR0cmliQXJyYXkoZSksdC52YWx1ZS5sZW5ndGgpe2Nhc2UgNDpyLnZlcnRleEF0dHJpYjRmdihlLHQudmFsdWUpO2JyZWFrO2Nhc2UgMzpyLnZlcnRleEF0dHJpYjNmdihlLHQudmFsdWUpO2JyZWFrO2Nhc2UgMjpyLnZlcnRleEF0dHJpYjJmdihlLHQudmFsdWUpO2JyZWFrO2Nhc2UgMTpyLnZlcnRleEF0dHJpYjFmdihlLHQudmFsdWUpO2JyZWFrO2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKCJ0aGUgbGVuZ3RoIG9mIGEgZmxvYXQgY29uc3RhbnQgdmFsdWUgbXVzdCBiZSBiZXR3ZWVuIDEgYW5kIDQhIil9ZWxzZSByLmJpbmRCdWZmZXIoZHQsdC5idWZmZXIpLHIuZW5hYmxlVmVydGV4QXR0cmliQXJyYXkoZSksci52ZXJ0ZXhBdHRyaWJQb2ludGVyKGUsdC5udW1Db21wb25lbnRzfHx0LnNpemUsdC50eXBlfHxtdCx0Lm5vcm1hbGl6ZXx8ITEsdC5zdHJpZGV8fDAsdC5vZmZzZXR8fDApLHIudmVydGV4QXR0cmliRGl2aXNvciYmci52ZXJ0ZXhBdHRyaWJEaXZpc29yKGUsdC5kaXZpc29yfHwwKX19ZnVuY3Rpb24gYWUocixlKXtyZXR1cm4gZnVuY3Rpb24odCl7aWYodC52YWx1ZSlpZihyLmRpc2FibGVWZXJ0ZXhBdHRyaWJBcnJheShlKSx0LnZhbHVlLmxlbmd0aD09PTQpci52ZXJ0ZXhBdHRyaWI0aXYoZSx0LnZhbHVlKTtlbHNlIHRocm93IG5ldyBFcnJvcigiVGhlIGxlbmd0aCBvZiBhbiBpbnRlZ2VyIGNvbnN0YW50IHZhbHVlIG11c3QgYmUgNCEiKTtlbHNlIHIuYmluZEJ1ZmZlcihkdCx0LmJ1ZmZlciksci5lbmFibGVWZXJ0ZXhBdHRyaWJBcnJheShlKSxyLnZlcnRleEF0dHJpYklQb2ludGVyKGUsdC5udW1Db21wb25lbnRzfHx0LnNpemUsdC50eXBlfHxzcix0LnN0cmlkZXx8MCx0Lm9mZnNldHx8MCksci52ZXJ0ZXhBdHRyaWJEaXZpc29yJiZyLnZlcnRleEF0dHJpYkRpdmlzb3IoZSx0LmRpdmlzb3J8fDApfX1mdW5jdGlvbiB4dChyLGUpe3JldHVybiBmdW5jdGlvbih0KXtpZih0LnZhbHVlKWlmKHIuZGlzYWJsZVZlcnRleEF0dHJpYkFycmF5KGUpLHQudmFsdWUubGVuZ3RoPT09NClyLnZlcnRleEF0dHJpYjR1aXYoZSx0LnZhbHVlKTtlbHNlIHRocm93IG5ldyBFcnJvcigiVGhlIGxlbmd0aCBvZiBhbiB1bnNpZ25lZCBpbnRlZ2VyIGNvbnN0YW50IHZhbHVlIG11c3QgYmUgNCEiKTtlbHNlIHIuYmluZEJ1ZmZlcihkdCx0LmJ1ZmZlciksci5lbmFibGVWZXJ0ZXhBdHRyaWJBcnJheShlKSxyLnZlcnRleEF0dHJpYklQb2ludGVyKGUsdC5udW1Db21wb25lbnRzfHx0LnNpemUsdC50eXBlfHxhcix0LnN0cmlkZXx8MCx0Lm9mZnNldHx8MCksci52ZXJ0ZXhBdHRyaWJEaXZpc29yJiZyLnZlcnRleEF0dHJpYkRpdmlzb3IoZSx0LmRpdmlzb3J8fDApfX1mdW5jdGlvbiBjcihyLGUsdCl7Y29uc3Qgbj10LnNpemUsaT10LmNvdW50O3JldHVybiBmdW5jdGlvbihvKXtyLmJpbmRCdWZmZXIoZHQsby5idWZmZXIpO2NvbnN0IHM9by5zaXplfHxvLm51bUNvbXBvbmVudHN8fG4sYT1zL2ksdT1vLnR5cGV8fG10LGQ9Ylt1XS5zaXplKnMsaD1vLm5vcm1hbGl6ZXx8ITEseT1vLm9mZnNldHx8MCx4PWQvaTtmb3IobGV0IGw9MDtsPGk7KytsKXIuZW5hYmxlVmVydGV4QXR0cmliQXJyYXkoZStsKSxyLnZlcnRleEF0dHJpYlBvaW50ZXIoZStsLGEsdSxoLGQseSt4KmwpLHIudmVydGV4QXR0cmliRGl2aXNvciYmci52ZXJ0ZXhBdHRyaWJEaXZpc29yKGUrbCxvLmRpdmlzb3J8fDApfX1jb25zdCBQPXt9O1BbbXRdPXtzaXplOjQsc2V0dGVyOl90fSxQW0VuXT17c2l6ZTo4LHNldHRlcjpfdH0sUFtUbl09e3NpemU6MTIsc2V0dGVyOl90fSxQW0FuXT17c2l6ZToxNixzZXR0ZXI6X3R9LFBbc3JdPXtzaXplOjQsc2V0dGVyOmFlfSxQW3duXT17c2l6ZTo4LHNldHRlcjphZX0sUFtTbl09e3NpemU6MTIsc2V0dGVyOmFlfSxQW1JuXT17c2l6ZToxNixzZXR0ZXI6YWV9LFBbYXJdPXtzaXplOjQsc2V0dGVyOnh0fSxQW2tuXT17c2l6ZTo4LHNldHRlcjp4dH0sUFtDbl09e3NpemU6MTIsc2V0dGVyOnh0fSxQW09uXT17c2l6ZToxNixzZXR0ZXI6eHR9LFBbSW5dPXtzaXplOjQsc2V0dGVyOmFlfSxQW0ZuXT17c2l6ZTo4LHNldHRlcjphZX0sUFtQbl09e3NpemU6MTIsc2V0dGVyOmFlfSxQW0RuXT17c2l6ZToxNixzZXR0ZXI6YWV9LFBbTm5dPXtzaXplOjQsc2V0dGVyOmNyLGNvdW50OjJ9LFBbTW5dPXtzaXplOjksc2V0dGVyOmNyLGNvdW50OjN9LFBbVW5dPXtzaXplOjE2LHNldHRlcjpjcixjb3VudDo0fTtjb25zdCBXdT0vRVJST1I6XHMqXGQrOihcZCspL2dpO2Z1bmN0aW9uIFZ1KHIsZT0iIix0PTApe2NvbnN0IG49Wy4uLmUubWF0Y2hBbGwoV3UpXSxpPW5ldyBNYXAobi5tYXAoKG8scyk9Pntjb25zdCBhPXBhcnNlSW50KG9bMV0pLHU9bltzKzFdLGY9dT91LmluZGV4OmUubGVuZ3RoLGQ9ZS5zdWJzdHJpbmcoby5pbmRleCxmKTtyZXR1cm5bYS0xLGRdfSkpO3JldHVybiByLnNwbGl0KGAKYCkubWFwKChvLHMpPT57Y29uc3QgYT1pLmdldChzKTtyZXR1cm5gJHtzKzErdH06ICR7b30ke2E/YAoKXl5eICR7YX1gOiIifWB9KS5qb2luKGAKYCl9Y29uc3QgVm49L15bIFx0XSpcbi87ZnVuY3Rpb24gSG4ocil7bGV0IGU9MDtyZXR1cm4gVm4udGVzdChyKSYmKGU9MSxyPXIucmVwbGFjZShWbiwiIikpLHtsaW5lT2Zmc2V0OmUsc2hhZGVyU291cmNlOnJ9fWZ1bmN0aW9uIEh1KHIsZSl7cmV0dXJuIHIuZXJyb3JDYWxsYmFjayhlKSxyLmNhbGxiYWNrJiZzZXRUaW1lb3V0KCgpPT57ci5jYWxsYmFjayhgJHtlfQoke3IuZXJyb3JzLmpvaW4oYApgKX1gKX0pLG51bGx9ZnVuY3Rpb24gWXUocixlLHQsbil7aWYobj1ufHxvciwhci5nZXRTaGFkZXJQYXJhbWV0ZXIodCxIYSkpe2NvbnN0IG89ci5nZXRTaGFkZXJJbmZvTG9nKHQpLHtsaW5lT2Zmc2V0OnMsc2hhZGVyU291cmNlOmF9PUhuKHIuZ2V0U2hhZGVyU291cmNlKHQpKSx1PWAke1Z1KGEsbyxzKX0KRXJyb3IgY29tcGlsaW5nICR7SnIocixlKX06ICR7b31gO3JldHVybiBuKHUpLHV9cmV0dXJuIiJ9ZnVuY3Rpb24gZnIocixlLHQpe2xldCBuLGksbztpZih0eXBlb2YgZT09ImZ1bmN0aW9uIiYmKHQ9ZSxlPXZvaWQgMCksdHlwZW9mIHI9PSJmdW5jdGlvbiIpdD1yLHI9dm9pZCAwO2Vsc2UgaWYociYmIUFycmF5LmlzQXJyYXkocikpe2NvbnN0IGY9cjt0PWYuZXJyb3JDYWxsYmFjayxyPWYuYXR0cmliTG9jYXRpb25zLG49Zi50cmFuc2Zvcm1GZWVkYmFja1ZhcnlpbmdzLGk9Zi50cmFuc2Zvcm1GZWVkYmFja01vZGUsbz1mLmNhbGxiYWNrfWNvbnN0IHM9dHx8b3IsYT1bXSx1PXtlcnJvckNhbGxiYWNrKGYsLi4uZCl7YS5wdXNoKGYpLHMoZiwuLi5kKX0sdHJhbnNmb3JtRmVlZGJhY2tWYXJ5aW5nczpuLHRyYW5zZm9ybUZlZWRiYWNrTW9kZTppLGNhbGxiYWNrOm8sZXJyb3JzOmF9O3tsZXQgZj17fTtBcnJheS5pc0FycmF5KHIpP3IuZm9yRWFjaChmdW5jdGlvbihkLGgpe2ZbZF09ZT9lW2hdOmh9KTpmPXJ8fHt9LHUuYXR0cmliTG9jYXRpb25zPWZ9cmV0dXJuIHV9Y29uc3QganU9WyJWRVJURVhfU0hBREVSIiwiRlJBR01FTlRfU0hBREVSIl07ZnVuY3Rpb24gWHUocixlKXtpZihlLmluZGV4T2YoImZyYWciKT49MClyZXR1cm4gamE7aWYoZS5pbmRleE9mKCJ2ZXJ0Iik+PTApcmV0dXJuIFhhfWZ1bmN0aW9uIFF1KHIsZSx0KXtjb25zdCBuPXIuZ2V0QXR0YWNoZWRTaGFkZXJzKGUpO2Zvcihjb25zdCBpIG9mIG4pdC5oYXMoaSkmJnIuZGVsZXRlU2hhZGVyKGkpO3IuZGVsZXRlUHJvZ3JhbShlKX1jb25zdCBLdT0ocj0wKT0+bmV3IFByb21pc2UoZT0+c2V0VGltZW91dChlLHIpKTtmdW5jdGlvbiBxdShyLGUsdCl7Y29uc3Qgbj1yLmNyZWF0ZVByb2dyYW0oKSx7YXR0cmliTG9jYXRpb25zOmksdHJhbnNmb3JtRmVlZGJhY2tWYXJ5aW5nczpvLHRyYW5zZm9ybUZlZWRiYWNrTW9kZTpzfT1mcih0KTtmb3IobGV0IGE9MDthPGUubGVuZ3RoOysrYSl7bGV0IHU9ZVthXTtpZih0eXBlb2YgdT09InN0cmluZyIpe2NvbnN0IGY9Ym4odSksZD1mP2YudGV4dDp1O2xldCBoPXJbanVbYV1dO2YmJmYudHlwZSYmKGg9WHUocixmLnR5cGUpfHxoKSx1PXIuY3JlYXRlU2hhZGVyKGgpLHIuc2hhZGVyU291cmNlKHUsSG4oZCkuc2hhZGVyU291cmNlKSxyLmNvbXBpbGVTaGFkZXIodSksci5hdHRhY2hTaGFkZXIobix1KX19T2JqZWN0LmVudHJpZXMoaSkuZm9yRWFjaCgoW2EsdV0pPT5yLmJpbmRBdHRyaWJMb2NhdGlvbihuLHUsYSkpO3tsZXQgYT1vO2EmJihhLmF0dHJpYnMmJihhPWEuYXR0cmlicyksQXJyYXkuaXNBcnJheShhKXx8KGE9T2JqZWN0LmtleXMoYSkpLHIudHJhbnNmb3JtRmVlZGJhY2tWYXJ5aW5ncyhuLGEsc3x8UWEpKX1yZXR1cm4gci5saW5rUHJvZ3JhbShuKSxufWZ1bmN0aW9uIEp1KHIsZSx0LG4saSl7Y29uc3Qgbz1mcih0LG4saSkscz1uZXcgU2V0KGUpLGE9cXUocixlLG8pO2Z1bmN0aW9uIHUoZixkKXtjb25zdCBoPWVjKGYsZCxvLmVycm9yQ2FsbGJhY2spO3JldHVybiBoJiZRdShmLGQscyksaH1pZihvLmNhbGxiYWNrKXtadShyLGEpLnRoZW4oKCk9Pntjb25zdCBmPXUocixhKTtvLmNhbGxiYWNrKGYsZj92b2lkIDA6YSl9KTtyZXR1cm59cmV0dXJuIHUocixhKT92b2lkIDA6YX1hc3luYyBmdW5jdGlvbiBadShyLGUpe2NvbnN0IHQ9ci5nZXRFeHRlbnNpb24oIktIUl9wYXJhbGxlbF9zaGFkZXJfY29tcGlsZSIpLG49dD8obyxzKT0+by5nZXRQcm9ncmFtUGFyYW1ldGVyKHMsdC5DT01QTEVUSU9OX1NUQVRVU19LSFIpOigpPT4hMDtsZXQgaT0wO2RvIGF3YWl0IEt1KGkpLGk9MWUzLzYwO3doaWxlKCFuKHIsZSkpfWZ1bmN0aW9uIGVjKHIsZSx0KXtpZih0PXR8fG9yLCFyLmdldFByb2dyYW1QYXJhbWV0ZXIoZSxZYSkpe2NvbnN0IGk9ci5nZXRQcm9ncmFtSW5mb0xvZyhlKTt0KGBFcnJvciBpbiBwcm9ncmFtIGxpbmtpbmc6ICR7aX1gKTtjb25zdCBzPXIuZ2V0QXR0YWNoZWRTaGFkZXJzKGUpLm1hcChhPT5ZdShyLHIuZ2V0U2hhZGVyUGFyYW1ldGVyKGEsci5TSEFERVJfVFlQRSksYSx0KSk7cmV0dXJuYCR7aX0KJHtzLmZpbHRlcihhPT5hKS5qb2luKGAKYCl9YH19ZnVuY3Rpb24gdGMocixlLHQsbixpKXtyZXR1cm4gSnUocixlLHQsbixpKX1mdW5jdGlvbiBZbihyKXtjb25zdCBlPXIubmFtZTtyZXR1cm4gZS5zdGFydHNXaXRoKCJnbF8iKXx8ZS5zdGFydHNXaXRoKCJ3ZWJnbF8iKX1jb25zdCByYz0vKFwufFxbfF18XHcrKS9nLG5jPXI9PnI+PSIwIiYmcjw9IjkiO2Z1bmN0aW9uIGljKHIsZSx0LG4pe2NvbnN0IGk9ci5zcGxpdChyYykuZmlsdGVyKGE9PmEhPT0iIik7bGV0IG89MCxzPSIiO2Zvcig7Oyl7Y29uc3QgYT1pW28rK107cys9YTtjb25zdCB1PW5jKGFbMF0pLGY9dT9wYXJzZUludChhKTphO2lmKHUmJihzKz1pW28rK10pLG89PT1pLmxlbmd0aCl7dFtmXT1lO2JyZWFrfWVsc2V7Y29uc3QgaD1pW28rK10seT1oPT09IlsiLHg9dFtmXXx8KHk/W106e30pO3RbZl09eCx0PXgsbltzXT1uW3NdfHxmdW5jdGlvbihsKXtyZXR1cm4gZnVuY3Rpb24oZyl7am4obCxnKX19KHgpLHMrPWh9fX1mdW5jdGlvbiBvYyhyLGUpe2xldCB0PTA7ZnVuY3Rpb24gbihhLHUsZil7Y29uc3QgZD11Lm5hbWUuZW5kc1dpdGgoIlswXSIpLGg9dS50eXBlLHk9YltoXTtpZigheSl0aHJvdyBuZXcgRXJyb3IoYHVua25vd24gdHlwZTogMHgke2gudG9TdHJpbmcoMTYpfWApO2xldCB4O2lmKHkuYmluZFBvaW50KXtjb25zdCBsPXQ7dCs9dS5zaXplLGQ/eD15LmFycmF5U2V0dGVyKHIsaCxsLGYsdS5zaXplKTp4PXkuc2V0dGVyKHIsaCxsLGYsdS5zaXplKX1lbHNlIHkuYXJyYXlTZXR0ZXImJmQ/eD15LmFycmF5U2V0dGVyKHIsZik6eD15LnNldHRlcihyLGYpO3JldHVybiB4LmxvY2F0aW9uPWYseH1jb25zdCBpPXt9LG89e30scz1yLmdldFByb2dyYW1QYXJhbWV0ZXIoZSx2bik7Zm9yKGxldCBhPTA7YTxzOysrYSl7Y29uc3QgdT1yLmdldEFjdGl2ZVVuaWZvcm0oZSxhKTtpZihZbih1KSljb250aW51ZTtsZXQgZj11Lm5hbWU7Zi5lbmRzV2l0aCgiWzBdIikmJihmPWYuc3Vic3RyKDAsZi5sZW5ndGgtMykpO2NvbnN0IGQ9ci5nZXRVbmlmb3JtTG9jYXRpb24oZSx1Lm5hbWUpO2lmKGQpe2NvbnN0IGg9bihlLHUsZCk7aVtmXT1oLGljKGYsaCxvLGkpfX1yZXR1cm4gaX1mdW5jdGlvbiBzYyhyLGUpe2NvbnN0IHQ9e30sbj1yLmdldFByb2dyYW1QYXJhbWV0ZXIoZSxxYSk7Zm9yKGxldCBpPTA7aTxuOysraSl7Y29uc3Qgbz1yLmdldFRyYW5zZm9ybUZlZWRiYWNrVmFyeWluZyhlLGkpO3Rbby5uYW1lXT17aW5kZXg6aSx0eXBlOm8udHlwZSxzaXplOm8uc2l6ZX19cmV0dXJuIHR9ZnVuY3Rpb24gYWMocixlKXtjb25zdCB0PXIuZ2V0UHJvZ3JhbVBhcmFtZXRlcihlLHZuKSxuPVtdLGk9W107Zm9yKGxldCBhPTA7YTx0OysrYSl7aS5wdXNoKGEpLG4ucHVzaCh7fSk7Y29uc3QgdT1yLmdldEFjdGl2ZVVuaWZvcm0oZSxhKTtuW2FdLm5hbWU9dS5uYW1lfVtbIlVOSUZPUk1fVFlQRSIsInR5cGUiXSxbIlVOSUZPUk1fU0laRSIsInNpemUiXSxbIlVOSUZPUk1fQkxPQ0tfSU5ERVgiLCJibG9ja05keCJdLFsiVU5JRk9STV9PRkZTRVQiLCJvZmZzZXQiXV0uZm9yRWFjaChmdW5jdGlvbihhKXtjb25zdCB1PWFbMF0sZj1hWzFdO3IuZ2V0QWN0aXZlVW5pZm9ybXMoZSxpLHJbdV0pLmZvckVhY2goZnVuY3Rpb24oZCxoKXtuW2hdW2ZdPWR9KX0pO2NvbnN0IG89e30scz1yLmdldFByb2dyYW1QYXJhbWV0ZXIoZSxKYSk7Zm9yKGxldCBhPTA7YTxzOysrYSl7Y29uc3QgdT1yLmdldEFjdGl2ZVVuaWZvcm1CbG9ja05hbWUoZSxhKSxmPXtpbmRleDpyLmdldFVuaWZvcm1CbG9ja0luZGV4KGUsdSksdXNlZEJ5VmVydGV4U2hhZGVyOnIuZ2V0QWN0aXZlVW5pZm9ybUJsb2NrUGFyYW1ldGVyKGUsYSxaYSksdXNlZEJ5RnJhZ21lbnRTaGFkZXI6ci5nZXRBY3RpdmVVbmlmb3JtQmxvY2tQYXJhbWV0ZXIoZSxhLGV1KSxzaXplOnIuZ2V0QWN0aXZlVW5pZm9ybUJsb2NrUGFyYW1ldGVyKGUsYSx0dSksdW5pZm9ybUluZGljZXM6ci5nZXRBY3RpdmVVbmlmb3JtQmxvY2tQYXJhbWV0ZXIoZSxhLHJ1KX07Zi51c2VkPWYudXNlZEJ5VmVydGV4U2hhZGVyfHxmLnVzZWRCeUZyYWdtZW50U2hhZGVyLG9bdV09Zn1yZXR1cm57YmxvY2tTcGVjczpvLHVuaWZvcm1EYXRhOm59fWZ1bmN0aW9uIGpuKHIsZSl7Zm9yKGNvbnN0IHQgaW4gZSl7Y29uc3Qgbj1yW3RdO3R5cGVvZiBuPT0iZnVuY3Rpb24iP24oZVt0XSk6am4oclt0XSxlW3RdKX19ZnVuY3Rpb24gWG4ociwuLi5lKXtjb25zdCB0PXIudW5pZm9ybVNldHRlcnN8fHIsbj1lLmxlbmd0aDtmb3IobGV0IGk9MDtpPG47KytpKXtjb25zdCBvPWVbaV07aWYoQXJyYXkuaXNBcnJheShvKSl7Y29uc3Qgcz1vLmxlbmd0aDtmb3IobGV0IGE9MDthPHM7KythKVhuKHQsb1thXSl9ZWxzZSBmb3IoY29uc3QgcyBpbiBvKXtjb25zdCBhPXRbc107YSYmYShvW3NdKX19fWZ1bmN0aW9uIHVjKHIsZSl7Y29uc3QgdD17fSxuPXIuZ2V0UHJvZ3JhbVBhcmFtZXRlcihlLEthKTtmb3IobGV0IGk9MDtpPG47KytpKXtjb25zdCBvPXIuZ2V0QWN0aXZlQXR0cmliKGUsaSk7aWYoWW4obykpY29udGludWU7Y29uc3Qgcz1yLmdldEF0dHJpYkxvY2F0aW9uKGUsby5uYW1lKSxhPVBbby50eXBlXSx1PWEuc2V0dGVyKHIscyxhKTt1LmxvY2F0aW9uPXMsdFtvLm5hbWVdPXV9cmV0dXJuIHR9ZnVuY3Rpb24gY2MocixlKXtmb3IoY29uc3QgdCBpbiBlKXtjb25zdCBuPXJbdF07biYmbihlW3RdKX19ZnVuY3Rpb24gZmMocixlLHQpe3QudmVydGV4QXJyYXlPYmplY3Q/ci5iaW5kVmVydGV4QXJyYXkodC52ZXJ0ZXhBcnJheU9iamVjdCk6KGNjKGUuYXR0cmliU2V0dGVyc3x8ZSx0LmF0dHJpYnMpLHQuaW5kaWNlcyYmci5iaW5kQnVmZmVyKFZhLHQuaW5kaWNlcykpfWZ1bmN0aW9uIFFuKHIsZSl7Y29uc3QgdD1vYyhyLGUpLG49dWMocixlKSxpPXtwcm9ncmFtOmUsdW5pZm9ybVNldHRlcnM6dCxhdHRyaWJTZXR0ZXJzOm59O3JldHVybiBOZShyKSYmKGkudW5pZm9ybUJsb2NrU3BlYz1hYyhyLGUpLGkudHJhbnNmb3JtRmVlZGJhY2tJbmZvPXNjKHIsZSkpLGl9Y29uc3QgbGM9L1xzfHt8fXw7LztmdW5jdGlvbiBkYyhyLGUsdCxuLGkpe2NvbnN0IG89ZnIodCxuLGkpLHM9W107aWYoZT1lLm1hcChmdW5jdGlvbihmKXtpZighbGMudGVzdChmKSl7Y29uc3QgZD1ibihmKTtpZihkKWY9ZC50ZXh0O2Vsc2V7Y29uc3QgaD1gbm8gZWxlbWVudCB3aXRoIGlkOiAke2Z9YDtvLmVycm9yQ2FsbGJhY2soaCkscy5wdXNoKGgpfX1yZXR1cm4gZn0pLHMubGVuZ3RoKXJldHVybiBIdShvLCIiKTtjb25zdCBhPW8uY2FsbGJhY2s7YSYmKG8uY2FsbGJhY2s9KGYsZCk9PnthKGYsZj92b2lkIDA6UW4ocixkKSl9KTtjb25zdCB1PXRjKHIsZSxvKTtyZXR1cm4gdT9RbihyLHUpOm51bGx9Y29uc3QgbWM9NCxLbj01MTIzO2Z1bmN0aW9uIGhjKHIsZSx0LG4saSxvKXt0PXQ9PT12b2lkIDA/bWM6dDtjb25zdCBzPWUuaW5kaWNlcyxhPWUuZWxlbWVudFR5cGUsdT1uPT09dm9pZCAwP2UubnVtRWxlbWVudHM6bjtpPWk9PT12b2lkIDA/MDppLGF8fHM/byE9PXZvaWQgMD9yLmRyYXdFbGVtZW50c0luc3RhbmNlZCh0LHUsYT09PXZvaWQgMD9LbjplLmVsZW1lbnRUeXBlLGksbyk6ci5kcmF3RWxlbWVudHModCx1LGE9PT12b2lkIDA/S246ZS5lbGVtZW50VHlwZSxpKTpvIT09dm9pZCAwP3IuZHJhd0FycmF5c0luc3RhbmNlZCh0LGksdSxvKTpyLmRyYXdBcnJheXModCxpLHUpfWNvbnN0IHFuPTM2MTYwLGd0PTM2MTYxLHBjPTM1NTMseWM9NTEyMSxfYz02NDAyLHhjPTY0MDgsZ2M9MzMxOTAsYmM9MzYwMTIsdmM9MzUwNTYsRWM9MzYwMTMsVGM9MzI4NTQsQWM9MzI4NTUsd2M9MzYxOTQsSm49MzMxODksWm49NjQwMSxlaT0zNjE2OCxscj0zNDA0MSxkcj0zNjA2NCxidD0zNjA5Nix0aT0zNjEyOCxtcj0zMzMwNixocj0zMzA3MSxwcj05NzI5LFNjPVt7Zm9ybWF0OnhjLHR5cGU6eWMsbWluOnByLHdyYXA6aHJ9LHtmb3JtYXQ6bHJ9XSxWPXt9O1ZbbHJdPW1yLFZbWm5dPXRpLFZbZWldPXRpLFZbX2NdPWJ0LFZbSm5dPWJ0LFZbZ2NdPWJ0LFZbYmNdPWJ0LFZbdmNdPW1yLFZbRWNdPW1yO2Z1bmN0aW9uIFJjKHIsZSl7cmV0dXJuIFZbcl18fFZbZV19Y29uc3QgdWU9e307dWVbVGNdPSEwLHVlW0FjXT0hMCx1ZVt3Y109ITAsdWVbbHJdPSEwLHVlW0puXT0hMCx1ZVtabl09ITAsdWVbZWldPSEwO2Z1bmN0aW9uIEljKHIpe3JldHVybiB1ZVtyXX1jb25zdCBGYz0zMjtmdW5jdGlvbiBQYyhyKXtyZXR1cm4gcj49ZHImJnI8ZHIrRmN9ZnVuY3Rpb24gdnQocixlLHQsbil7Y29uc3QgaT1xbixvPXIuY3JlYXRlRnJhbWVidWZmZXIoKTtyLmJpbmRGcmFtZWJ1ZmZlcihpLG8pLHQ9dHx8ci5kcmF3aW5nQnVmZmVyV2lkdGgsbj1ufHxyLmRyYXdpbmdCdWZmZXJIZWlnaHQsZT1lfHxTYztjb25zdCBzPVtdLGE9e2ZyYW1lYnVmZmVyOm8sYXR0YWNobWVudHM6W10sd2lkdGg6dCxoZWlnaHQ6bn07cmV0dXJuIGUuZm9yRWFjaChmdW5jdGlvbih1LGYpe2xldCBkPXUuYXR0YWNobWVudDtjb25zdCBoPXUuc2FtcGxlcyx5PXUuZm9ybWF0O2xldCB4PXUuYXR0YWNobWVudFBvaW50fHxSYyh5LHUuaW50ZXJuYWxGb3JtYXQpO2lmKHh8fCh4PWRyK2YpLFBjKHgpJiZzLnB1c2goeCksIWQpaWYoaCE9PXZvaWQgMHx8SWMoeSkpZD1yLmNyZWF0ZVJlbmRlcmJ1ZmZlcigpLHIuYmluZFJlbmRlcmJ1ZmZlcihndCxkKSxoPjE/ci5yZW5kZXJidWZmZXJTdG9yYWdlTXVsdGlzYW1wbGUoZ3QsaCx5LHQsbik6ci5yZW5kZXJidWZmZXJTdG9yYWdlKGd0LHksdCxuKTtlbHNle2NvbnN0IGw9T2JqZWN0LmFzc2lnbih7fSx1KTtsLndpZHRoPXQsbC5oZWlnaHQ9bixsLmF1dG89PT12b2lkIDAmJihsLmF1dG89ITEsbC5taW49bC5taW58fGwubWluTWFnfHxwcixsLm1hZz1sLm1hZ3x8bC5taW5NYWd8fHByLGwud3JhcFM9bC53cmFwU3x8bC53cmFwfHxocixsLndyYXBUPWwud3JhcFR8fGwud3JhcHx8aHIpLGQ9Z24ocixsKX1pZigkbyhyLGQpKXIuZnJhbWVidWZmZXJSZW5kZXJidWZmZXIoaSx4LGd0LGQpO2Vsc2UgaWYoSHQocixkKSl1LmxheWVyIT09dm9pZCAwP3IuZnJhbWVidWZmZXJUZXh0dXJlTGF5ZXIoaSx4LGQsdS5sZXZlbHx8MCx1LmxheWVyKTpyLmZyYW1lYnVmZmVyVGV4dHVyZTJEKGkseCx1LnRhcmdldHx8cGMsZCx1LmxldmVsfHwwKTtlbHNlIHRocm93IG5ldyBFcnJvcigidW5rbm93biBhdHRhY2htZW50IHR5cGUiKTthLmF0dGFjaG1lbnRzLnB1c2goZCl9KSxyLmRyYXdCdWZmZXJzJiZyLmRyYXdCdWZmZXJzKHMpLGF9ZnVuY3Rpb24gRGMocixlLHQpe3Q9dHx8cW4sZT8oci5iaW5kRnJhbWVidWZmZXIodCxlLmZyYW1lYnVmZmVyKSxyLnZpZXdwb3J0KDAsMCxlLndpZHRoLGUuaGVpZ2h0KSk6KHIuYmluZEZyYW1lYnVmZmVyKHQsbnVsbCksci52aWV3cG9ydCgwLDAsci5kcmF3aW5nQnVmZmVyV2lkdGgsci5kcmF3aW5nQnVmZmVySGVpZ2h0KSl9ZnVuY3Rpb24gUyhyLGUpe3JldHVybigpPT5lIGluc3RhbmNlb2YgV2ViR0xUZXh0dXJlP2U6Z24ocix7c3JjOmUsd3JhcDpyLkNMQU1QX1RPX0VER0V9KX1jb25zdCByaT0yO2NsYXNzIHhle2NvbnN0cnVjdG9yKGUpe3AodGhpcywiaWQiLCJfIik7cCh0aGlzLCJjb250ZXh0Iik7cCh0aGlzLCJvdXRwdXQiKTtwKHRoaXMsImZiaSIpO3AodGhpcywib3B0aW9ucyIpO3AodGhpcywicHJvZ3JhbUluZm8iKTtwKHRoaXMsImJ1ZmZlckluZm8iKTtwKHRoaXMsInByb2ZpbGVyIik7cCh0aGlzLCJsYXN0UnVuIik7Y29uc3R7Y29udGV4dDp0LHdpZHRoOm4saGVpZ2h0Oml9PWU7dGhpcy5jb250ZXh0PXQsdGhpcy5vcHRpb25zPWU7Y29uc3Qgbz10aGlzLmJ1aWxkRGVmaW5lcygpO3RoaXMucHJvZ3JhbUluZm89ZGModGhpcy5jb250ZXh0LFtvK3RoaXMuZ2V0VmVydGV4U2hhZGVyKCksbyt0aGlzLmdldEZyYWdtZW50U2hhZGVyKCldKSx0aGlzLmJ1ZmZlckluZm89bHModGhpcy5jb250ZXh0LHRoaXMuZ2V0QnVmZmVycygpKSx0aGlzLmZiaT12dCh0aGlzLmNvbnRleHQsW3tmb3JtYXQ6dGhpcy5jb250ZXh0LlJHQkEsdHlwZTp0aGlzLmNvbnRleHQuVU5TSUdORURfQllURSxtaW46dGhpcy5jb250ZXh0LkxJTkVBUix3cmFwOnRoaXMuY29udGV4dC5DTEFNUF9UT19FREdFfV0sbixpKSx0aGlzLm91dHB1dD10aGlzLmZiaS5hdHRhY2htZW50c1swXX1yZXNpemVPdXRwdXQoZSx0KXt0aGlzLmZiaT12dCh0aGlzLmNvbnRleHQsW3tmb3JtYXQ6dGhpcy5jb250ZXh0LlJHQkEsdHlwZTp0aGlzLmNvbnRleHQuVU5TSUdORURfQllURSxtaW46dGhpcy5jb250ZXh0LkxJTkVBUix3cmFwOnRoaXMuY29udGV4dC5DTEFNUF9UT19FREdFfV0sZSx0KSx0aGlzLm9wdGlvbnMud2lkdGg9ZSx0aGlzLm9wdGlvbnMuaGVpZ2h0PXQsdGhpcy5vdXRwdXQ9dGhpcy5mYmkuYXR0YWNobWVudHNbMF19Z2V0RGVmaW5lcygpe3JldHVybnt9fWdldEJ1ZmZlcnMoKXtyZXR1cm57cG9zaXRpb246e251bUNvbXBvbmVudHM6MixkYXRhOlstMSwtMSwtMSwxLDEsLTEsMSwxLC0xLDEsMSwtMV19LHRleHR1cmVfY29vcmQ6e251bUNvbXBvbmVudHM6MixkYXRhOlswLDAsMCwxLDEsMCwxLDEsMCwxLDEsMF19fX1idWlsZERlZmluZXMoKXtsZXQgZT0iIjtjb25zdCB0PXRoaXMuZ2V0RGVmaW5lcygpO2ZvcihsZXQgbiBpbiB0KWUrPWAjZGVmaW5lICR7bn0gJHt0W25dLnRvRml4ZWQoMSl9CmA7cmV0dXJuIGV9cnVuKGUpe3ZhciBpLG8scyxhLHUsZjsoaT10aGlzLnByb2ZpbGVyKT09bnVsbHx8aS5wdXNoQ29udGV4dChgWyR7dGhpcy5pZH1dIFBST0cgOiAke3RoaXMuY29uc3RydWN0b3IubmFtZX1gKSwobz10aGlzLnByb2ZpbGVyKT09bnVsbHx8by5wdXNoQ29udGV4dChgWyR7dGhpcy5pZH1dIFVOSUZPUk1TYCk7Zm9yKGNvbnN0IGQgaW4gZSl0eXBlb2YgZVtkXT09ImZ1bmN0aW9uIiYmKChzPXRoaXMucHJvZmlsZXIpPT1udWxsfHxzLnB1c2hDb250ZXh0KGBbJHt0aGlzLmlkfV0gVU5JIDogJHtkfWApLGVbZF09ZVtkXSgpLChhPXRoaXMucHJvZmlsZXIpPT1udWxsfHxhLnBvcENvbnRleHQoYFske3RoaXMuaWR9XSBVTkkgOiAke2R9YCkpOyh1PXRoaXMucHJvZmlsZXIpPT1udWxsfHx1LnBvcENvbnRleHQoYFske3RoaXMuaWR9XSBVTklGT1JNU2ApO2NvbnN0IHQ9RGF0ZS5ub3coKTtsZXQgbj0wO3RoaXMubGFzdFJ1biYmKG49KHQtdGhpcy5sYXN0UnVuKS8xZTMpLHRoaXMubGFzdFJ1bj10LHRoaXMuY29udGV4dC52aWV3cG9ydCgwLDAsdGhpcy5jb250ZXh0LmNhbnZhcy53aWR0aCx0aGlzLmNvbnRleHQuY2FudmFzLmhlaWdodCksdGhpcy5jb250ZXh0LnVzZVByb2dyYW0odGhpcy5wcm9ncmFtSW5mby5wcm9ncmFtKSxmYyh0aGlzLmNvbnRleHQsdGhpcy5wcm9ncmFtSW5mbyx0aGlzLmJ1ZmZlckluZm8pLFhuKHRoaXMucHJvZ3JhbUluZm8se2RlbHRhOm4sY2FudmFzOlt0aGlzLmNvbnRleHQuY2FudmFzLndpZHRoLHRoaXMuY29udGV4dC5jYW52YXMuaGVpZ2h0XSwuLi5lfSksRGModGhpcy5jb250ZXh0LHRoaXMub3B0aW9ucy5kaXNhYmxlRnJhbWVidWZmZXI/bnVsbDp0aGlzLmZiaSksaGModGhpcy5jb250ZXh0LHRoaXMuYnVmZmVySW5mbyksKGY9dGhpcy5wcm9maWxlcik9PW51bGx8fGYucG9wQ29udGV4dChgWyR7dGhpcy5pZH1dIFBST0cgOiAke3RoaXMuY29uc3RydWN0b3IubmFtZX1gKX1zZXRQcm9maWxlcihlKXt0aGlzLnByb2ZpbGVyPWV9fXZhciBOYz1gcHJlY2lzaW9uIG1lZGl1bXAgZmxvYXQ7Cgp2YXJ5aW5nIHZlYzIgX3RleHR1cmVfY29vcmQ7Cgp1bmlmb3JtIHZlYzIgY2FudmFzOwp1bmlmb3JtIHNhbXBsZXIyRCB0ZXh0dXJlOwp1bmlmb3JtIHNhbXBsZXIyRCBtYXNrOwoKdmVjNCBsb29wKCk7Cgp2b2lkIG1haW4oKSB7IGdsX0ZyYWdDb2xvciA9IGxvb3AoKTsgfQpgLE1jPWB2YXJ5aW5nIHZlYzIgX3RleHR1cmVfY29vcmQ7CgphdHRyaWJ1dGUgdmVjMiBwb3NpdGlvbjsKYXR0cmlidXRlIHZlYzIgdGV4dHVyZV9jb29yZDsKCnZvaWQgbWFpbigpIHsKICBnbF9Qb3NpdGlvbiA9IHZlYzQocG9zaXRpb24sIDAuLCAxLik7CiAgX3RleHR1cmVfY29vcmQgPSB0ZXh0dXJlX2Nvb3JkOwp9CmA7Y2xhc3MgVWMgZXh0ZW5kcyB4ZXtnZXREZWZpbmVzKCl7dmFyIGU7cmV0dXJue1JBRElVUzooZT10aGlzLm9wdGlvbnMucmFkaXVzKSE9bnVsbD9lOjF9fWdldEZyYWdtZW50U2hhZGVyKCl7cmV0dXJuIE5jK3RoaXMuY3JlYXRlTG9vcEZ1bmN0aW9uKCl9Z2V0VmVydGV4U2hhZGVyKCl7cmV0dXJuIE1jfWNyZWF0ZUxvb3BGdW5jdGlvbigpe3ZhciB0O2xldCBlPSh0PXRoaXMub3B0aW9ucy5yYWRpdXMpIT1udWxsP3Q6MTtyZXR1cm5gCgogICAgICAgIHZlYzQgbG9vcCgpIHsgCiAgICAgICAgICAgIHZlYzQgcmVzdWx0ID0gdmVjNCgwLDAsMCwwKTsKICAgICAgICAgICAgZmxvYXQgZmFjdG9yU3VtID0gMC47CgogICAgICAgICAgICB2ZWMyIG5vcm1hbGl6ZWRSYWRpdXMgPSB2ZWMyKC0ke2V9LikgLyBjYW52YXM7CiAgICAgICAgICAgIHZlYzIgbm9ybWFsaXplZEluY3JlbWVudCA9IHZlYzIoMS4pIC8gY2FudmFzOwogICAgICAgICAgICB2ZWMyIGRpZmYgPSBub3JtYWxpemVkUmFkaXVzOwogICAgICAgICAgICBmbG9hdCBtYXhMZW5ndGggPSBsZW5ndGgobm9ybWFsaXplZFJhZGl1cyk7CgogICAgICAgICAgICBmb3IoaW50IHk9LSR7ZX07IHk8JHtlKzF9OyArK3kpIHsKICAgICAgICAgICAgICAgIGZvcihpbnQgeD0tJHtlfTsgeDwke2UrMX07ICsreCkgewogICAgICAgICAgICAgICAgICAgIGZsb2F0IGZhY3RvciA9ICgxLi0gdGV4dHVyZTJEKG1hc2ssIF90ZXh0dXJlX2Nvb3JkICsgZGlmZikuYSkgKiAobWF4TGVuZ3RoIC0gbGVuZ3RoKGRpZmYpKSAvIG1heExlbmd0aDsKICAgICAgICAgICAgICAgICAgICByZXN1bHQgKz0gZmFjdG9yICogdGV4dHVyZTJEKHRleHR1cmUsIF90ZXh0dXJlX2Nvb3JkICsgZGlmZik7CiAgICAgICAgICAgICAgICAgICAgZmFjdG9yU3VtICs9IGZhY3RvcjsKICAgICAgICAgICAgICAgICAgICBkaWZmLnggKz0gbm9ybWFsaXplZEluY3JlbWVudC54OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZGlmZi55ICs9IG5vcm1hbGl6ZWRJbmNyZW1lbnQueTsKICAgICAgICAgICAgICAgIGRpZmYueCA9IG5vcm1hbGl6ZWRSYWRpdXMueDsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gcmVzdWx0IC8gZmFjdG9yU3VtOwogICAgICAgIH1gfX12YXIga2M9YHByZWNpc2lvbiBtZWRpdW1wIGZsb2F0OwoKdmFyeWluZyB2ZWMyIF90ZXh0dXJlX2Nvb3JkOwoKdW5pZm9ybSBzYW1wbGVyMkQgYmFja2dyb3VuZDsKdW5pZm9ybSBzYW1wbGVyMkQgZm9yZWdyb3VuZDsKdW5pZm9ybSBzYW1wbGVyMkQgdGhyZXNob2xkOwoKdm9pZCBtYWluKCkgewogIHZlYzQgYmFja2dyb3VuZENvbG9yID0gdGV4dHVyZTJEKGJhY2tncm91bmQsIF90ZXh0dXJlX2Nvb3JkKTsKICB2ZWM0IGZvcmVncm91bmRDb2xvciA9IHRleHR1cmUyRChmb3JlZ3JvdW5kLCBfdGV4dHVyZV9jb29yZCk7CiAgdmVjNCB0cmVzaG9sZENvbG9yID0gdGV4dHVyZTJEKHRocmVzaG9sZCwgX3RleHR1cmVfY29vcmQpOwogIGdsX0ZyYWdDb2xvciA9IGZvcmVncm91bmRDb2xvciAqIHRyZXNob2xkQ29sb3IuYSArCiAgICAgICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yICogKDEuIC0gdHJlc2hvbGRDb2xvci5hKTsKfQpgLENjPWB2YXJ5aW5nIHZlYzIgX3RleHR1cmVfY29vcmQ7CgphdHRyaWJ1dGUgdmVjMiBwb3NpdGlvbjsKYXR0cmlidXRlIHZlYzIgdGV4dHVyZV9jb29yZDsKCnZvaWQgbWFpbigpIHsKICBnbF9Qb3NpdGlvbiA9IHZlYzQocG9zaXRpb24sIDAuLCAxLik7CiAgX3RleHR1cmVfY29vcmQgPSB0ZXh0dXJlX2Nvb3JkOwogIF90ZXh0dXJlX2Nvb3JkLnkgPSAxLiAtIHRleHR1cmVfY29vcmQueTsKfQpgO2NsYXNzIHlyIGV4dGVuZHMgeGV7Z2V0RnJhZ21lbnRTaGFkZXIoKXtyZXR1cm4ga2N9Z2V0VmVydGV4U2hhZGVyKCl7cmV0dXJuIENjfX1jbGFzcyBfcntjb25zdHJ1Y3Rvcigpe3AodGhpcywic3RlcHMiLFtdKTtwKHRoaXMsInByb2ZpbGVyIil9YWRkU3RlcChlKXt0aGlzLnN0ZXBzLnB1c2goZSl9YXN5bmMgcnVuKCl7Zm9yKGNvbnN0IGUgb2YgdGhpcy5zdGVwcyllLnByb2dyYW0ucnVuKGUuZ2V0VW5pZm9ybXMoKSl9cmVzaXplT3V0cHV0KGUsdCl7dmFyIG4saTsobj10aGlzLnByb2ZpbGVyKT09bnVsbHx8bi5wdXNoQ29udGV4dChgUElQIFske3RoaXMuY29uc3RydWN0b3IubmFtZX1dYCk7Zm9yKGNvbnN0IG8gb2YgdGhpcy5zdGVwcylvLnByZXZlbnRSZXNpemV8fG8ucHJvZ3JhbS5yZXNpemVPdXRwdXQoZSx0KTsoaT10aGlzLnByb2ZpbGVyKT09bnVsbHx8aS5wb3BDb250ZXh0KGBQSVAgWyR7dGhpcy5jb25zdHJ1Y3Rvci5uYW1lfV1gKX1zZXRQcm9maWxlcihlKXt0aGlzLnByb2ZpbGVyPWU7Zm9yKGNvbnN0IHQgb2YgdGhpcy5zdGVwcyl0LnByb2dyYW0uc2V0UHJvZmlsZXIoZSl9c2V0SWQoZSl7Zm9yKGNvbnN0IHQgb2YgdGhpcy5zdGVwcyl0LnByb2dyYW0uaWQ9ZX19Y2xhc3MgeHIgZXh0ZW5kcyBfcntjb25zdHJ1Y3Rvcigpe3N1cGVyKC4uLmFyZ3VtZW50cyk7cCh0aGlzLCJwcmVjaXNlTWFza0VuYWJsZWQiLCExKX19Y29uc3QgT2M9MTAsQmM9MixMYz04O2NsYXNzIEdjIGV4dGVuZHMgeHJ7Y29uc3RydWN0b3IodCxuKXtzdXBlcigpO3AodGhpcywiaW5wdXRJbWFnZSIpO3AodGhpcywiaW5wdXRNYXNrIik7cCh0aGlzLCJibHVyIik7dGhpcy5jb250ZXh0PXQsdGhpcy5yYWRpdXM9bjtjb25zdCBpPXtjb250ZXh0OnQsaGVpZ2h0OnQuY2FudmFzLmhlaWdodCx3aWR0aDp0LmNhbnZhcy53aWR0aH07dGhpcy5ibHVyPW5ldyBVYyh7Li4uaSxyYWRpdXM6biwuLi50aGlzLmdldEJsdXJUZXh0dXJlU2l6ZSh0LmNhbnZhcy53aWR0aCx0LmNhbnZhcy5oZWlnaHQpfSk7Y29uc3Qgbz1uZXcgeXIoey4uLmksZGlzYWJsZUZyYW1lYnVmZmVyOiEwfSk7dGhpcy5hZGRTdGVwKHtwcm9ncmFtOnRoaXMuYmx1cixwcmV2ZW50UmVzaXplOiEwLGdldFVuaWZvcm1zOigpPT4oe3RleHR1cmU6Uyh0LHRoaXMuaW5wdXRJbWFnZSksbWFzazpTKHQsdGhpcy5pbnB1dE1hc2spfSl9KSx0aGlzLmFkZFN0ZXAoe3Byb2dyYW06byxnZXRVbmlmb3JtczooKT0+KHtiYWNrZ3JvdW5kOlModCx0aGlzLmJsdXIub3V0cHV0KSxmb3JlZ3JvdW5kOlModCx0aGlzLmlucHV0SW1hZ2UpLHRocmVzaG9sZDpTKHQsdGhpcy5pbnB1dE1hc2spfSl9KX1nZXRCbHVyVGV4dHVyZVNpemUodCxuKXtjb25zdCBpPXRoaXMucmFkaXVzPk9jP0xjOkJjO3JldHVybnt3aWR0aDpNYXRoLm1heChyaSx0L2kpLGhlaWdodDpNYXRoLm1heChyaSxuL2kpfX1zZXREYXRhKHQsbil7dGhpcy5pbnB1dEltYWdlPXQsdGhpcy5pbnB1dE1hc2s9bn1yZXNpemVPdXRwdXQodCxuKXtzdXBlci5yZXNpemVPdXRwdXQodCxuKTtjb25zdCBpPXRoaXMuZ2V0Qmx1clRleHR1cmVTaXplKHQsbik7dGhpcy5ibHVyLnJlc2l6ZU91dHB1dChpLndpZHRoLGkuaGVpZ2h0KX19Y2xhc3MgbmkgZXh0ZW5kcyB4cntjb25zdHJ1Y3Rvcih0KXtzdXBlcigpO3AodGhpcywiaW5wdXRJbWFnZSIpO3AodGhpcywiaW5wdXRCYWNrZ3JvdW5kSW1hZ2UiKTtwKHRoaXMsImlucHV0TWFzayIpO3AodGhpcywicHJlY2lzZU1hc2tFbmFibGVkIiwhMCk7dGhpcy5jb250ZXh0PXQ7Y29uc3Qgbj17Y29udGV4dDp0LGhlaWdodDp0LmNhbnZhcy5oZWlnaHQsd2lkdGg6dC5jYW52YXMud2lkdGh9LGk9bmV3IHlyKHsuLi5uLGRpc2FibGVGcmFtZWJ1ZmZlcjohMH0pO3RoaXMuYWRkU3RlcCh7cHJvZ3JhbTppLGdldFVuaWZvcm1zOigpPT4oe2JhY2tncm91bmQ6Uyh0LHRoaXMuaW5wdXRCYWNrZ3JvdW5kSW1hZ2UpLGZvcmVncm91bmQ6Uyh0LHRoaXMuaW5wdXRJbWFnZSksdGhyZXNob2xkOlModCx0aGlzLmlucHV0TWFzayl9KX0pfXNldERhdGEodCxuKXt0aGlzLmlucHV0SW1hZ2U9dCx0aGlzLmlucHV0TWFzaz1ufX1jbGFzcyAkYyBleHRlbmRzIG5pe2NvbnN0cnVjdG9yKCl7c3VwZXIoLi4uYXJndW1lbnRzKTtwKHRoaXMsImZyYW1lUmVhZGVyIik7cCh0aGlzLCJwcmVjaXNlTWFza0VuYWJsZWQiLCEwKX1zZXQgaW5wdXRWaWRlbyh0KXt0aGlzLmZyYW1lUmVhZGVyPXQuZ2V0UmVhZGVyKCksdGhpcy5yZWFkTmV4dFZpZGVvRnJhbWUoKX1hc3luYyBydW4oKXt0aGlzLmZyYW1lUmVhZGVyJiYoYXdhaXQgc3VwZXIucnVuKCksdGhpcy5yZWFkTmV4dFZpZGVvRnJhbWUoKSl9YXN5bmMgcmVhZE5leHRWaWRlb0ZyYW1lKCl7dmFyIG47Y29uc3QgdD1hd2FpdCgobj10aGlzLmZyYW1lUmVhZGVyKT09bnVsbD92b2lkIDA6bi5yZWFkKCkpO3QhPW51bGwmJnQudmFsdWUmJih0aGlzLmlucHV0QmFja2dyb3VuZEltYWdlPWF3YWl0IGNyZWF0ZUltYWdlQml0bWFwKHQudmFsdWUpLHQudmFsdWUuY2xvc2UoKSl9fXZhciB6Yz1gcHJlY2lzaW9uIG1lZGl1bXAgZmxvYXQ7Cgp2YXJ5aW5nIHZlYzIgX3RleHR1cmVfY29vcmQ7Cgp1bmlmb3JtIHZlYzIgY2FudmFzOwp1bmlmb3JtIHNhbXBsZXIyRCB0ZXh0dXJlOwoKdmVjNCBsb29wKCk7Cgp2b2lkIG1haW4oKSB7IGdsX0ZyYWdDb2xvciA9IGxvb3AoKTsgfQpgLFdjPWB2YXJ5aW5nIHZlYzIgX3RleHR1cmVfY29vcmQ7CgphdHRyaWJ1dGUgdmVjMiBwb3NpdGlvbjsKYXR0cmlidXRlIHZlYzIgdGV4dHVyZV9jb29yZDsKCnZvaWQgbWFpbigpIHsKICBnbF9Qb3NpdGlvbiA9IHZlYzQocG9zaXRpb24sIDAuLCAxLik7CiAgX3RleHR1cmVfY29vcmQgPSB0ZXh0dXJlX2Nvb3JkOwp9CmAsZ3I9KHI9PihyW3IuTElORUFSPTBdPSJMSU5FQVIiLHJbci5HQVVTU0lBTj0xXT0iR0FVU1NJQU4iLHIpKShncnx8e30pO2NsYXNzIGlpIGV4dGVuZHMgeGV7Z2V0RGVmaW5lcygpe3ZhciBlO3JldHVybntSQURJVVM6KGU9dGhpcy5vcHRpb25zLnJhZGl1cykhPW51bGw/ZToxfX1nZXRGcmFnbWVudFNoYWRlcigpe3JldHVybiB6Yyt0aGlzLmNyZWF0ZUxvb3BGdW5jdGlvbigpfWdldFZlcnRleFNoYWRlcigpe3JldHVybiBXY31jcmVhdGVMb29wRnVuY3Rpb24oKXt2YXIgdDtsZXQgZT0odD10aGlzLm9wdGlvbnMucmFkaXVzKSE9bnVsbD90OjE7cmV0dXJuYAoKICAgICAgICB2ZWM0IGxvb3AoKSB7IAogICAgICAgICAgICB2ZWM0IHJlc3VsdCA9IHZlYzQoMCwwLDAsMCk7CiAgICAgICAgICAgIGZsb2F0IGZhY3RvclN1bSA9IDAuOwoKICAgICAgICAgICAgdmVjMiBub3JtYWxpemVkUmFkaXVzID0gdmVjMigtJHtlfS4pIC8gY2FudmFzOwogICAgICAgICAgICB2ZWMyIG5vcm1hbGl6ZWRJbmNyZW1lbnQgPSB2ZWMyKDEuKSAvIGNhbnZhczsKICAgICAgICAgICAgdmVjMiBkaWZmID0gbm9ybWFsaXplZFJhZGl1czsKCiAgICAgICAgICAgIGZvcihpbnQgeT0tJHtlfTsgeTwke2UrMX07ICsreSkgewogICAgICAgICAgICAgICAgZm9yKGludCB4PS0ke2V9OyB4PCR7ZSsxfTsgKyt4KSB7CiAgICAgICAgICAgICAgICAgICAgZmxvYXQgZmFjdG9yID0gMS47CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ICs9IGZhY3RvciAqIHRleHR1cmUyRCh0ZXh0dXJlLCBfdGV4dHVyZV9jb29yZCArIGRpZmYpOwogICAgICAgICAgICAgICAgICAgIGZhY3RvclN1bSArPSBmYWN0b3I7CiAgICAgICAgICAgICAgICAgICAgZGlmZi54ICs9IG5vcm1hbGl6ZWRJbmNyZW1lbnQueDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGRpZmYueSArPSBub3JtYWxpemVkSW5jcmVtZW50Lnk7CiAgICAgICAgICAgICAgICBkaWZmLnggPSBub3JtYWxpemVkUmFkaXVzLng7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHJlc3VsdCAvIGZhY3RvclN1bTsKICAgICAgICB9YH1nZXRGYWN0b3IoZSx0KXtzd2l0Y2godGhpcy5vcHRpb25zLnR5cGUpe2Nhc2UgMTpyZXR1cm4gdGhpcy5nZXRMaW5lYXJGYWN0b3IoZSx0KTtjYXNlIDA6ZGVmYXVsdDpyZXR1cm4gdGhpcy5nZXRMaW5lYXJGYWN0b3IoZSx0KX19Z2V0TGluZWFyRmFjdG9yKGUsdCl7cmV0dXJuIDF9Z2V0R2F1c3NpYW5GYWN0b3IoZSx0KXt2YXIgdTtjb25zdCBuPU1hdGguUEkqMixpPU1hdGgubWF4KCh1PXRoaXMub3B0aW9ucy5yYWRpdXMpIT1udWxsP3U6MSwxKSxvPTEvKG4qaSoqMikscz0tKGUqKjIrdCoqMiksYT1vKnM7cmV0dXJuIG8qTWF0aC5FKiphfX1jbGFzcyBWYyBleHRlbmRzIHhye2NvbnN0cnVjdG9yKHQsbil7c3VwZXIoKTtwKHRoaXMsImlucHV0SW1hZ2UiKTtwKHRoaXMsImlucHV0TWFzayIpO3RoaXMuY29udGV4dD10O2NvbnN0IGk9e2NvbnRleHQ6dCxoZWlnaHQ6dC5jYW52YXMuaGVpZ2h0LHdpZHRoOnQuY2FudmFzLndpZHRofSxvPW5ldyBpaSh7Li4uaSxyYWRpdXM6bix0eXBlOmdyLkdBVVNTSUFOfSkscz1uZXcgeXIoey4uLmksZGlzYWJsZUZyYW1lYnVmZmVyOiEwfSk7dGhpcy5hZGRTdGVwKHtwcm9ncmFtOm8sZ2V0VW5pZm9ybXM6KCk9Pih7dGV4dHVyZTpTKHQsdGhpcy5pbnB1dEltYWdlKX0pfSksdGhpcy5hZGRTdGVwKHtwcm9ncmFtOnMsZ2V0VW5pZm9ybXM6KCk9Pih7YmFja2dyb3VuZDpTKHQsdGhpcy5pbnB1dEltYWdlKSxmb3JlZ3JvdW5kOlModCxvLm91dHB1dCksdGhyZXNob2xkOlModCx0aGlzLmlucHV0TWFzayl9KX0pfXNldERhdGEodCxuKXt0aGlzLmlucHV0SW1hZ2U9dCx0aGlzLmlucHV0TWFzaz1ufX1jbGFzcyBiciBleHRlbmRzIHhle2NvbnN0cnVjdG9yKHQpe3N1cGVyKHQpO3AodGhpcywiZmJpMiIpO3RoaXMuZmJpMj12dCh0LmNvbnRleHQsW3tmb3JtYXQ6dC5jb250ZXh0LlJHQkEsdHlwZTp0LmNvbnRleHQuVU5TSUdORURfQllURSxtaW46dC5jb250ZXh0LkxJTkVBUixtYWc6dC5jb250ZXh0LkxJTkVBUix3cmFwOnQuY29udGV4dC5DTEFNUF9UT19FREdFfV0sdC53aWR0aCx0LmhlaWdodCl9cnVuKHQpe2NvbnN0IG49dGhpcy5mYmk7dGhpcy5mYmk9dGhpcy5mYmkyLHRoaXMuZmJpMj1uLHRoaXMub3V0cHV0PXRoaXMuZmJpLmF0dGFjaG1lbnRzWzBdLHN1cGVyLnJ1bih7Li4udCxwcmV2aW91c19yZW5kZXJpbmc6dGhpcy5mYmkyLmF0dGFjaG1lbnRzWzBdfSl9cmVzaXplT3V0cHV0KHQsbil7c3VwZXIucmVzaXplT3V0cHV0KHQsbiksdGhpcy5mYmkyPXZ0KHRoaXMuY29udGV4dCxbe2Zvcm1hdDp0aGlzLmNvbnRleHQuUkdCQSx0eXBlOnRoaXMuY29udGV4dC5VTlNJR05FRF9CWVRFLG1pbjp0aGlzLmNvbnRleHQuTElORUFSLHdyYXA6dGhpcy5jb250ZXh0LkNMQU1QX1RPX0VER0V9XSx0LG4pfX12YXIgSGM9YHByZWNpc2lvbiBtZWRpdW1wIGZsb2F0OwoKdmFyeWluZyB2ZWMyIF90ZXh0dXJlX2Nvb3JkOwoKLy8gdW5pZm9ybSBmbG9hdCB0cmVzaG9sZDsKdW5pZm9ybSBzYW1wbGVyMkQgaW1hZ2Vfbm93Owp1bmlmb3JtIHNhbXBsZXIyRCBpbWFnZV9iZWZvcmU7CnVuaWZvcm0gc2FtcGxlcjJEIG1hc2tfbm93Owp1bmlmb3JtIHNhbXBsZXIyRCBtYXNrX2JlZm9yZTsKdW5pZm9ybSBzYW1wbGVyMkQgcHJldmlvdXNfcmVuZGVyaW5nOwp1bmlmb3JtIHZlYzIgY2FudmFzOwoKdW5pZm9ybSBmbG9hdCBkZWx0YTsKCmZsb2F0IGN1cnJlbnRfZmFjdG9yID0gMC42OTsKZmxvYXQgcHJldmlvdXNfZmFjdG9yID0gMC43NDsKZmxvYXQgdGhyZXNob2xkX2FjdGl2YXRpb24gPSAwLjU0OwoKZmxvYXQgbWFwKGZsb2F0IHZhbHVlLCBmbG9hdCBtaW4xLCBmbG9hdCBtYXgxLCBmbG9hdCBtaW4yLCBmbG9hdCBtYXgyKSB7CiAgcmV0dXJuIG1pbjIgKyAodmFsdWUgLSBtaW4xKSAqIChtYXgyIC0gbWluMikgLyAobWF4MSAtIG1pbjEpOwp9CgpmbG9hdCBnZXRUaHJlc2hvbGQoKSB7CiAgdmVjNCBjb2xvciA9IHZlYzQoMC4pOwogIGZvciAoZmxvYXQgeSA9IC02LjsgeSA8IDcuOyB5ICs9IDEuKSB7CiAgICBmb3IgKGZsb2F0IHggPSAtNi47IHggPCA3LjsgeCArPSAxLikgewogICAgICB2ZWM0IGltYWdlX25vd19jb2xvciA9CiAgICAgICAgICB0ZXh0dXJlMkQoaW1hZ2Vfbm93LCBfdGV4dHVyZV9jb29yZCArIHZlYzIoeCwgeSkgLyBjYW52YXMpOwogICAgICB2ZWM0IGltYWdlX2JlZm9yZV9jb2xvciA9CiAgICAgICAgICB0ZXh0dXJlMkQoaW1hZ2VfYmVmb3JlLCBfdGV4dHVyZV9jb29yZCArIHZlYzIoeCwgeSkgLyBjYW52YXMpOwogICAgICBjb2xvciArPSBhYnMoaW1hZ2VfYmVmb3JlX2NvbG9yIC0gaW1hZ2Vfbm93X2NvbG9yKTsKICAgIH0KICB9CiAgcmV0dXJuIChjb2xvci54ICsgY29sb3IueSArIGNvbG9yLnopIC8gKDMuICogOS4pOwp9Cgp2b2lkIG1haW4oKSB7CiAgZmxvYXQgdHJlc2hvbGRfaW5wdXQgPSAuNDsKICBmbG9hdCB0cmVzaG9sZF9wcmV2aW91c19yZW5kZXJpbmcgPSAuOTg7CgogIHZlYzQgbWFza19ub3dfY29sb3IgPSB0ZXh0dXJlMkQobWFza19ub3csIF90ZXh0dXJlX2Nvb3JkKTsKICB2ZWM0IG1hc2tfYmVmb3JlX2NvbG9yID0gdGV4dHVyZTJEKG1hc2tfYmVmb3JlLCBfdGV4dHVyZV9jb29yZCk7CiAgdmVjNCBwcmV2aW91c19yZW5kZXJpbmdfY29sb3IgPSB0ZXh0dXJlMkQocHJldmlvdXNfcmVuZGVyaW5nLCBfdGV4dHVyZV9jb29yZCk7CgogIHZlYzMgbWFza19kaWZmID0gYWJzKG1hc2tfYmVmb3JlX2NvbG9yLnh5eiAtIG1hc2tfbm93X2NvbG9yLnh5eik7CiAgZmxvYXQgZmxpY2tlcmluZyA9IG1hc2tfZGlmZi54OwogIGZsb2F0IHRocmVzaG9sZCA9IGdldFRocmVzaG9sZCgpOwogIGlmICh0aHJlc2hvbGQgPCB0aHJlc2hvbGRfYWN0aXZhdGlvbikgewogICAgZ2xfRnJhZ0NvbG9yID0gdmVjNChmbGlja2VyaW5nLCAwLiwgMC4sIDEuKSAqIGN1cnJlbnRfZmFjdG9yICsKICAgICAgICAgICAgICAgICAgIHByZXZpb3VzX3JlbmRlcmluZ19jb2xvciAqIHByZXZpb3VzX2ZhY3RvcjsKICAgIGdsX0ZyYWdDb2xvciAqPSAoMS4gLSB0aHJlc2hvbGQpOwogIH0KfQpgLFljPWB2YXJ5aW5nIHZlYzIgX3RleHR1cmVfY29vcmQ7CgphdHRyaWJ1dGUgdmVjMiBwb3NpdGlvbjsKYXR0cmlidXRlIHZlYzIgdGV4dHVyZV9jb29yZDsKCnZvaWQgbWFpbigpIHsKICBnbF9Qb3NpdGlvbiA9IHZlYzQocG9zaXRpb24sIDAuLCAxLik7CiAgX3RleHR1cmVfY29vcmQgPSB0ZXh0dXJlX2Nvb3JkOwp9CmA7Y2xhc3MgamMgZXh0ZW5kcyBicntnZXRGcmFnbWVudFNoYWRlcigpe3JldHVybiBIY31nZXRWZXJ0ZXhTaGFkZXIoKXtyZXR1cm4gWWN9fXZhciBYYz1gI3ZlcnNpb24gMzAwIGVzCi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9Wb2xjb21peC92aXJ0dWFsLWJhY2tncm91bmQvYmxvYi9tYWluL3NyYy9waXBlbGluZXMvd2ViZ2wyL2pvaW50QmlsYXRlcmFsRmlsdGVyU3RhZ2UudHMKCnByZWNpc2lvbiBoaWdocCBmbG9hdDsKdW5pZm9ybSBzYW1wbGVyMkQgaW5wdXRfZnJhbWU7CnVuaWZvcm0gc2FtcGxlcjJEIHNlZ21lbnRhdGlvbl9tYXNrOwp1bmlmb3JtIHNhbXBsZXIyRCB0aHJlc2hvbGQ7CnVuaWZvcm0gdmVjMiB0ZXhlbF9zaXplOwp1bmlmb3JtIGZsb2F0IHN0ZXA7CnVuaWZvcm0gZmxvYXQgcmFkaXVzOwp1bmlmb3JtIGZsb2F0IG9mZnNldDsKdW5pZm9ybSBmbG9hdCBzaWdtYV90ZXhlbDsKdW5pZm9ybSBmbG9hdCBzaWdtYV9jb2xvcjsKCmluIHZlYzIgX3RleHR1cmVfY29vcmQ7Cm91dCB2ZWM0IG91dENvbG9yOwoKZmxvYXQgZ2F1c3NpYW4oZmxvYXQgeCwgZmxvYXQgc2lnbWEpIHsKICBmbG9hdCBjb2VmZiA9IC0wLjUgLyAoc2lnbWEgKiBzaWdtYSAqIDQuMCArIDEuMGUtNik7CiAgcmV0dXJuIGV4cCgoeCAqIHgpICogY29lZmYpOwp9Cgp2b2lkIG1haW4oKSB7CiAgdmVjMiBjZW50ZXJDb29yZCA9IF90ZXh0dXJlX2Nvb3JkOwogIHZlYzMgY2VudGVyQ29sb3IgPSB0ZXh0dXJlKGlucHV0X2ZyYW1lLCBjZW50ZXJDb29yZCkucmdiOwogIGZsb2F0IG5ld1ZhbCA9IDAuMDsKICBmbG9hdCBzcGFjZVdlaWdodCA9IDAuMDsKICBmbG9hdCBjb2xvcldlaWdodCA9IDAuMDsKICBmbG9hdCB0b3RhbFdlaWdodCA9IDAuMDsKICAvLyBTdWJzYW1wbGUga2VybmVsIHNwYWNlLgogIGZvciAoZmxvYXQgaSA9IC1yYWRpdXMgKyBvZmZzZXQ7IGkgPD0gcmFkaXVzOyBpICs9IHN0ZXApIHsKICAgIGZvciAoZmxvYXQgaiA9IC1yYWRpdXMgKyBvZmZzZXQ7IGogPD0gcmFkaXVzOyBqICs9IHN0ZXApIHsKICAgICAgdmVjMiBzaGlmdCA9IHZlYzIoaiwgaSkgKiB0ZXhlbF9zaXplOwogICAgICB2ZWMyIGNvb3JkID0gdmVjMihjZW50ZXJDb29yZCArIHNoaWZ0KTsKICAgICAgdmVjMyBmcmFtZUNvbG9yID0gdGV4dHVyZShpbnB1dF9mcmFtZSwgY29vcmQpLnJnYjsKICAgICAgZmxvYXQgdGhyZXNob2xkID0gdGV4dHVyZSh0aHJlc2hvbGQsIGNvb3JkKS5hOwogICAgICBmbG9hdCBvdXRWYWwgPSB0ZXh0dXJlKHNlZ21lbnRhdGlvbl9tYXNrLCBjb29yZCkuYTsKCiAgICAgIHNwYWNlV2VpZ2h0ID0gZ2F1c3NpYW4oZGlzdGFuY2UoY2VudGVyQ29vcmQsIGNvb3JkKSwgc2lnbWFfdGV4ZWwpOwogICAgICBjb2xvcldlaWdodCA9IGdhdXNzaWFuKGRpc3RhbmNlKGNlbnRlckNvbG9yLCBmcmFtZUNvbG9yKSwgc2lnbWFfY29sb3IpOwogICAgICB0b3RhbFdlaWdodCArPSBzcGFjZVdlaWdodCAqIGNvbG9yV2VpZ2h0OwogICAgICBuZXdWYWwgKz0gc3BhY2VXZWlnaHQgKiBjb2xvcldlaWdodCAqIG91dFZhbCAqIHRocmVzaG9sZDsKICAgIH0KICB9CiAgbmV3VmFsIC89IHRvdGFsV2VpZ2h0OwogIG91dENvbG9yID0gdmVjNCh2ZWMzKDAuKSwgbmV3VmFsKTsKfWAsUWM9YCN2ZXJzaW9uIDMwMCBlcwppbiB2ZWMyIHBvc2l0aW9uOwppbiB2ZWMyIHRleHR1cmVfY29vcmQ7Cm91dCB2ZWMyIF90ZXh0dXJlX2Nvb3JkOwp2b2lkIG1haW4oKSB7CiAgZ2xfUG9zaXRpb24gPSB2ZWM0KHBvc2l0aW9uLCAwLjAsIDEuMCk7CiAgX3RleHR1cmVfY29vcmQgPSB0ZXh0dXJlX2Nvb3JkOwp9YDtjbGFzcyBLYyBleHRlbmRzIHhle2dldEZyYWdtZW50U2hhZGVyKCl7cmV0dXJuIFhjfWdldFZlcnRleFNoYWRlcigpe3JldHVybiBRY319dmFyIHFjPWBwcmVjaXNpb24gbWVkaXVtcCBmbG9hdDsKCnZhcnlpbmcgdmVjMiBfdGV4dHVyZV9jb29yZDsKCnVuaWZvcm0gdmVjMiBjYW52YXM7CnVuaWZvcm0gc2FtcGxlcjJEIHRleHR1cmU7Cgp2b2lkIG1haW4oKSB7CiAgaW50IGNvdW50ID0gMDsKICBmb3IgKGZsb2F0IHkgPSAtMS47IHkgPCAyLjsgeSArPSAxLikgewogICAgZm9yIChmbG9hdCB4ID0gLTEuOyB4IDwgMi47IHggKz0gMS4pIHsKICAgICAgdmVjMiBjb29yZCA9IF90ZXh0dXJlX2Nvb3JkICsgdmVjMih5LCB4KSAvIGNhbnZhczsKICAgICAgdmVjNCBjb2xvciA9IHRleHR1cmUyRCh0ZXh0dXJlLCBjb29yZCk7CiAgICAgIGlmIChjb2xvci5yID4gLjEpIHsKICAgICAgICBjb3VudCsrOwogICAgICB9CiAgICB9CiAgfQogIGlmIChjb3VudCA+IDUpIHsKICAgIGdsX0ZyYWdDb2xvciA9IHRleHR1cmUyRCh0ZXh0dXJlLCBfdGV4dHVyZV9jb29yZCk7CiAgfQp9CmAsSmM9YHZhcnlpbmcgdmVjMiBfdGV4dHVyZV9jb29yZDsKCmF0dHJpYnV0ZSB2ZWMyIHBvc2l0aW9uOwphdHRyaWJ1dGUgdmVjMiB0ZXh0dXJlX2Nvb3JkOwoKdm9pZCBtYWluKCkgewogIGdsX1Bvc2l0aW9uID0gdmVjNChwb3NpdGlvbiwgMC4sIDEuKTsKICBfdGV4dHVyZV9jb29yZCA9IHRleHR1cmVfY29vcmQ7Cn0KYDtjbGFzcyBaYyBleHRlbmRzIHhle2dldEZyYWdtZW50U2hhZGVyKCl7cmV0dXJuIHFjfWdldFZlcnRleFNoYWRlcigpe3JldHVybiBKY319dmFyIGVmPWBwcmVjaXNpb24gbWVkaXVtcCBmbG9hdDsKCnZhcnlpbmcgdmVjMiBfdGV4dHVyZV9jb29yZDsKCnVuaWZvcm0gdmVjMiBjYW52YXM7CnVuaWZvcm0gc2FtcGxlcjJEIHRleHR1cmU7Cgp2b2lkIG1haW4oKSB7CiAgdmVjNCBjb2xvciA9IHRleHR1cmUyRCh0ZXh0dXJlLCBfdGV4dHVyZV9jb29yZCk7CiAgZm9yIChmbG9hdCB5ID0gLTIuOyB5IDwgMy47IHkgKz0gMS4pIHsKICAgIGZvciAoZmxvYXQgeCA9IC0yLjsgeCA8IDMuOyB4ICs9IDEuKSB7CiAgICAgIHZlYzIgY29vcmQgPSBfdGV4dHVyZV9jb29yZDsKICAgICAgY29vcmQgKz0gdmVjMih5LCB4KSAvIGNhbnZhczsKICAgICAgY29sb3IgKz0gdGV4dHVyZTJEKHRleHR1cmUsIGNvb3JkKSAqICgxLiAvIDQuKTsKICAgIH0KICB9CgogIGdsX0ZyYWdDb2xvciA9IGNvbG9yOwp9CmAsdGY9YHZhcnlpbmcgdmVjMiBfdGV4dHVyZV9jb29yZDsKCmF0dHJpYnV0ZSB2ZWMyIHBvc2l0aW9uOwphdHRyaWJ1dGUgdmVjMiB0ZXh0dXJlX2Nvb3JkOwoKdm9pZCBtYWluKCkgewogIGdsX1Bvc2l0aW9uID0gdmVjNChwb3NpdGlvbiwgMC4sIDEuKTsKICBfdGV4dHVyZV9jb29yZCA9IHRleHR1cmVfY29vcmQ7Cn0KYDtjbGFzcyByZiBleHRlbmRzIGJye2dldEZyYWdtZW50U2hhZGVyKCl7cmV0dXJuIGVmfWdldFZlcnRleFNoYWRlcigpe3JldHVybiB0Zn19dmFyIG5mPWBwcmVjaXNpb24gbWVkaXVtcCBmbG9hdDsKCnZhcnlpbmcgdmVjMiBfdGV4dHVyZV9jb29yZDsKCnVuaWZvcm0gc2FtcGxlcjJEIHRocmVzaG9sZDsKdW5pZm9ybSBzYW1wbGVyMkQgaW5wdXRzOwoKdm9pZCBtYWluKCkgewogIHZlYzQgaW5wdXRzX2NvbG9yID0gdGV4dHVyZTJEKGlucHV0cywgX3RleHR1cmVfY29vcmQpOwogIHZlYzQgdGhyZXNob2xkX2NvbG9yID0gdGV4dHVyZTJEKHRocmVzaG9sZCwgX3RleHR1cmVfY29vcmQpOwogIGlmICh0aHJlc2hvbGRfY29sb3IuciA8IC4xICYmIGlucHV0c19jb2xvci5yID4gLjUpIHsKICAgIGdsX0ZyYWdDb2xvciA9IGlucHV0c19jb2xvcjsKICB9Cn0KYCxvZj1gdmFyeWluZyB2ZWMyIF90ZXh0dXJlX2Nvb3JkOwoKYXR0cmlidXRlIHZlYzIgcG9zaXRpb247CmF0dHJpYnV0ZSB2ZWMyIHRleHR1cmVfY29vcmQ7Cgp2b2lkIG1haW4oKSB7CiAgZ2xfUG9zaXRpb24gPSB2ZWM0KHBvc2l0aW9uLCAwLiwgMS4pOwogIF90ZXh0dXJlX2Nvb3JkID0gdGV4dHVyZV9jb29yZDsKfQpgO2NsYXNzIHNmIGV4dGVuZHMgYnJ7Z2V0RnJhZ21lbnRTaGFkZXIoKXtyZXR1cm4gbmZ9Z2V0VmVydGV4U2hhZGVyKCl7cmV0dXJuIG9mfX1jbGFzcyBhZiBleHRlbmRzIF9ye2NvbnN0cnVjdG9yKHQsbixpKXtzdXBlcigpO3AodGhpcywiaW5wdXRJbWFnZSIpO3AodGhpcywiaW5wdXRNYXNrIik7cCh0aGlzLCJwcmV2aW91c0lucHV0SW1hZ2UiKTtwKHRoaXMsInByZXZpb3VzSW5wdXRNYXNrIik7cCh0aGlzLCJvdXRwdXQiKTtwKHRoaXMsIm9wdGlvbnMiLHtjdXJyZW50VGhyZXNob2xkTWluaW11bTowLGN1cnJlbnRUaHJlc2hvbGRNYXhpbXVtOjEscHJldmlvdXNUaHJlc2hvbGRNaW5pbXVtOjAscHJldmlvdXNUaHJlc2hvbGRNYXhpbXVtOjEsdGhyZXNob2xkTWluaW11bTowLHRocmVzaG9sZE1heGltdW06MSx0aHJlc2hvbGRGYWN0b3I6MX0pO3RoaXMuY29udGV4dD10O2NvbnN0IG89e2NvbnRleHQ6dCxoZWlnaHQ6aSx3aWR0aDpufSxzPW5ldyBqYyhvKSxhPW5ldyBpaSh7Li4ubyxyYWRpdXM6MSx0eXBlOmdyLkdBVVNTSUFOfSksdT1uZXcgc2YobyksZj1uZXcgcmYobyksZD1uZXcgWmMobyksaD1uZXcgS2Moey4uLm99KSx5PS42Nix4PTY0MCxsPTQ4MCxnPTI1NixFPTE0NDtsZXQgdj0xO3YqPU1hdGgubWF4KHgvZyxsL0UpO2NvbnN0IEk9TWF0aC5tYXgoMSxNYXRoLnNxcnQodikqeSksRD0xL3gsRz0xL2w7dGhpcy5hZGRTdGVwKHtwcm9ncmFtOnMsZ2V0VW5pZm9ybXM6KCk9Pih7aW1hZ2Vfbm93OlModCx0aGlzLmlucHV0SW1hZ2UpLGltYWdlX2JlZm9yZTpTKHQsdGhpcy5wcmV2aW91c0lucHV0SW1hZ2UpLG1hc2tfbm93OlModCx0aGlzLmlucHV0TWFzayksbWFza19iZWZvcmU6Uyh0LHRoaXMucHJldmlvdXNJbnB1dE1hc2spLGN1cnJlbnRfdGhyZXNob2xkX21pbmltdW06dGhpcy5vcHRpb25zLmN1cnJlbnRUaHJlc2hvbGRNaW5pbXVtLGN1cnJlbnRfdGhyZXNob2xkX21heGltdW06dGhpcy5vcHRpb25zLmN1cnJlbnRUaHJlc2hvbGRNYXhpbXVtLHByZXZpb3VzX3RocmVzaG9sZF9taW5pbXVtOnRoaXMub3B0aW9ucy5wcmV2aW91c1RocmVzaG9sZE1pbmltdW0scHJldmlvdXNfdGhyZXNob2xkX21heGltdW06dGhpcy5vcHRpb25zLnByZXZpb3VzVGhyZXNob2xkTWF4aW11bSx0aHJlc2hvbGRfbWluaW11bTp0aGlzLm9wdGlvbnMudGhyZXNob2xkTWluaW11bSx0aHJlc2hvbGRfbWF4aW11bTp0aGlzLm9wdGlvbnMudGhyZXNob2xkTWF4aW11bSx0aHJlc2hvbGRfZmFjdG9yOnRoaXMub3B0aW9ucy50aHJlc2hvbGRGYWN0b3J9KX0pLHRoaXMuYWRkU3RlcCh7cHJvZ3JhbTp1LGdldFVuaWZvcm1zOigpPT4oe2lucHV0czpTKHQsdGhpcy5pbnB1dE1hc2spLHRocmVzaG9sZDpTKHQscy5vdXRwdXQpfSl9KSx0aGlzLmFkZFN0ZXAoe3Byb2dyYW06ZCxnZXRVbmlmb3JtczooKT0+KHt0ZXh0dXJlOlModCx1Lm91dHB1dCl9KX0pLHRoaXMuYWRkU3RlcCh7cHJvZ3JhbTpmLGdldFVuaWZvcm1zOigpPT4oe3RleHR1cmU6Uyh0LGQub3V0cHV0KX0pfSksdGhpcy5hZGRTdGVwKHtwcm9ncmFtOmEsZ2V0VW5pZm9ybXM6KCk9Pih7dGV4dHVyZTpTKHQsZi5vdXRwdXQpfSl9KSx0aGlzLmFkZFN0ZXAoe3Byb2dyYW06aCxnZXRVbmlmb3JtczooKT0+KHtpbnB1dF9mcmFtZTpTKHQsdGhpcy5pbnB1dEltYWdlKSxzZWdtZW50YXRpb25fbWFzazpTKHQsdGhpcy5pbnB1dE1hc2spLHRocmVzaG9sZDpTKHQsYS5vdXRwdXQpLHRleGVsX3NpemU6W0QsR10sc3RlcDpJLHJhZGl1czp2LG9mZnNldDpJPjE/SSouNTowLHNpZ21hX3RleGVsOk1hdGgubWF4KEQsRykqdixzaWdtYV9jb2xvcjouMX0pfSksdGhpcy5vdXRwdXQ9aC5vdXRwdXR9c2V0RGF0YSh0LG4pe3RoaXMucHJldmlvdXNJbnB1dEltYWdlPXRoaXMuaW5wdXRJbWFnZT90aGlzLmlucHV0SW1hZ2U6dCx0aGlzLnByZXZpb3VzSW5wdXRNYXNrPXRoaXMuaW5wdXRNYXNrP3RoaXMuaW5wdXRNYXNrOm4sdGhpcy5pbnB1dEltYWdlPXQsdGhpcy5pbnB1dE1hc2s9bn1zZXRPcHRpb25zKHQpe3RoaXMub3B0aW9ucz10fX12YXIgdWY9YHByZWNpc2lvbiBtZWRpdW1wIGZsb2F0OwoKdmFyeWluZyB2ZWMyIF90ZXh0dXJlX2Nvb3JkOwp1bmlmb3JtIHNhbXBsZXIyRCB0ZXh0dXJlOwoKdm9pZCBtYWluKCkgeyBnbF9GcmFnQ29sb3IgPSB0ZXh0dXJlMkQodGV4dHVyZSwgX3RleHR1cmVfY29vcmQpOyB9CmAsY2Y9YHZhcnlpbmcgdmVjMiBfdGV4dHVyZV9jb29yZDsKCmF0dHJpYnV0ZSB2ZWMyIHBvc2l0aW9uOwphdHRyaWJ1dGUgdmVjMiB0ZXh0dXJlX2Nvb3JkOwp1bmlmb3JtIGJvb2wgaW52ZXJ0X3k7Cgp2b2lkIG1haW4oKSB7CiAgZ2xfUG9zaXRpb24gPSB2ZWM0KHBvc2l0aW9uLCAwLiwgMS4pOwogIF90ZXh0dXJlX2Nvb3JkID0gdGV4dHVyZV9jb29yZDsKICBpZiAoaW52ZXJ0X3kpIHsKICAgIF90ZXh0dXJlX2Nvb3JkLnkgPSAxLiAtIHRleHR1cmVfY29vcmQueTsKICB9Cn0KYDtjbGFzcyBmZiBleHRlbmRzIHhle2dldEZyYWdtZW50U2hhZGVyKCl7cmV0dXJuIHVmfWdldFZlcnRleFNoYWRlcigpe3JldHVybiBjZn19Y2xhc3MgbGYgZXh0ZW5kcyBfcntjb25zdHJ1Y3Rvcih0LG4saSl7c3VwZXIoKTtwKHRoaXMsImlucHV0SW1hZ2UiKTt0aGlzLmNvbnRleHQ9dDtjb25zdCBvPXtjb250ZXh0OnQsaGVpZ2h0Omksd2lkdGg6bn07dGhpcy5hZGRTdGVwKHtwcm9ncmFtOm5ldyBmZih7Li4ubyxkaXNhYmxlRnJhbWVidWZmZXI6ITB9KSxnZXRVbmlmb3JtczooKT0+KHt0ZXh0dXJlOlModCx0aGlzLmlucHV0SW1hZ2UpLGludmVydF95OiEwfSl9KX1zZXREYXRhKHQpe3RoaXMuaW5wdXRJbWFnZT10fX1jbGFzcyBkZntjb25zdHJ1Y3RvcihlKXtwKHRoaXMsInJlc2l6ZSIpO3AodGhpcywiY2FudmFzIik7cCh0aGlzLCJjb250ZXh0Iik7dGhpcy5jYW52YXM9bmV3IE9mZnNjcmVlbkNhbnZhcygwLDApLHRoaXMuY29udGV4dD10aGlzLmNhbnZhcy5nZXRDb250ZXh0KCJ3ZWJnbDIiKSx0aGlzLmNhbnZhcy53aWR0aD1lLndpZHRoLHRoaXMuY2FudmFzLmhlaWdodD1lLmhlaWdodCx0aGlzLnJlc2l6ZT1uZXcgbGYodGhpcy5jb250ZXh0LGUud2lkdGgsZS5oZWlnaHQpfXJlc2l6ZUZvcmVncm91bmQoZSx0KXt0aGlzLmNhbnZhcy53aWR0aD1lLHRoaXMuY2FudmFzLmhlaWdodD10LHRoaXMucmVzaXplLnJlc2l6ZU91dHB1dChlLHQpfWFzeW5jIHByb2Nlc3MoZSl7dmFyIHQsbjtyZXR1cm4gdGhpcy5jYW52YXMud2lkdGg9dGhpcy5jYW52YXMud2lkdGgsKHQ9dGhpcy5yZXNpemUpPT1udWxsfHx0LnNldERhdGEoZSksKG49dGhpcy5yZXNpemUpPT1udWxsfHxuLnJ1bigpLHRoaXMuY2FudmFzfX1jbGFzcyBtZntjb25zdHJ1Y3RvcihlLHQpe3AodGhpcywiaW1wcm92ZU1hc2tTZWdtZW50YXRpb24iKTtwKHRoaXMsImJhY2tncm91bmRSZXNpemVyIik7cCh0aGlzLCJiYWNrZ3JvdW5kSW1hZ2UiKTtwKHRoaXMsImJhY2tncm91bmRWaWRlbyIpO3AodGhpcywicHJvZmlsZXIiKTtwKHRoaXMsImFjdGl2ZVBpcGVsaW5lIik7cCh0aGlzLCJjYW52YXMiKTtwKHRoaXMsIm9wdGlvbnMiKTtwKHRoaXMsImNvbnRleHQiKTtwKHRoaXMsInZpcnR1YWxCR0ltYWdlIik7dGhpcy5pZD1lLHRoaXMuY2FudmFzPW5ldyBPZmZzY3JlZW5DYW52YXMoMCwwKSx0aGlzLmNvbnRleHQ9dGhpcy5jYW52YXMuZ2V0Q29udGV4dCgid2ViZ2wyIiksdGhpcy5jYW52YXMud2lkdGg9dC5mb3JlZ3JvdW5kV2lkdGgsdGhpcy5jYW52YXMuaGVpZ2h0PXQuZm9yZWdyb3VuZEhlaWdodCx0aGlzLmltcHJvdmVNYXNrU2VnbWVudGF0aW9uPW5ldyBhZih0aGlzLmNvbnRleHQsdC5tYXNrV2lkdGgsdC5tYXNrSGVpZ2h0KSx0aGlzLmJhY2tncm91bmRJbWFnZT1uZXcgbmkodGhpcy5jb250ZXh0KSx0aGlzLmJhY2tncm91bmRWaWRlbz1uZXcgJGModGhpcy5jb250ZXh0KSx0aGlzLmJhY2tncm91bmRSZXNpemVyPW5ldyBkZih7d2lkdGg6dC5mb3JlZ3JvdW5kV2lkdGgsaGVpZ2h0OnQuZm9yZWdyb3VuZEhlaWdodH0pfXNldEJhY2tncm91bmRPcHRpb25zKGUpe3N3aXRjaChlLnRyYW5zZm9ybWVyVHlwZSl7Y2FzZSJCYWNrZ3JvdW5kQmx1ciI6dGhpcy5hY3RpdmVQaXBlbGluZT1uZXcgR2ModGhpcy5jb250ZXh0LHRoaXMuZ2V0Qmx1clNpemUoZS5yYWRpdXMpKTticmVhaztjYXNlIlNpbGhvdWV0dGVCbHVyIjp0aGlzLmFjdGl2ZVBpcGVsaW5lPW5ldyBWYyh0aGlzLmNvbnRleHQsdGhpcy5nZXRCbHVyU2l6ZShlLnJhZGl1cykpO2JyZWFrO2Nhc2UiVmlkZW9CYWNrZ3JvdW5kIjp0aGlzLmFjdGl2ZVBpcGVsaW5lPXRoaXMuYmFja2dyb3VuZFZpZGVvO2JyZWFrO2Nhc2UiVmlydHVhbEJhY2tncm91bmQiOnRoaXMuYWN0aXZlUGlwZWxpbmU9dGhpcy5iYWNrZ3JvdW5kSW1hZ2U7YnJlYWt9dGhpcy5vcHRpb25zPWV9c2V0RmxpY2tlcmluZ09wdGlvbnMoZSl7dmFyIHQ7KHQ9dGhpcy5pbXByb3ZlTWFza1NlZ21lbnRhdGlvbik9PW51bGx8fHQuc2V0T3B0aW9ucyhlKX1zZXRWaWRlb0JHUmVhZGFibGUoZSl7dGhpcy5iYWNrZ3JvdW5kVmlkZW8uaW5wdXRWaWRlbz1lfWFzeW5jIHNldFZpcnR1YWxCR0ltYWdlKGUpe3RoaXMudmlydHVhbEJHSW1hZ2U9ZSx0aGlzLmJhY2tncm91bmRJbWFnZS5pbnB1dEJhY2tncm91bmRJbWFnZT1hd2FpdCB0aGlzLmJhY2tncm91bmRSZXNpemVyLnByb2Nlc3MoZSl9YXN5bmMgcHJvY2VzcyhlLHQpe3ZhciBuLGksbyxzLGEsdSxmO2lmKHRoaXMuYWN0aXZlUGlwZWxpbmUmJmUud2lkdGgmJih0PT1udWxsP3ZvaWQgMDp0LndpZHRoKSl7Y29uc3QgZD1gWyR7dGhpcy5pZH1dIGJhY2tncm91bmQtZmlsdGVyYDsobj10aGlzLnByb2ZpbGVyKT09bnVsbHx8bi5wdXNoQ29udGV4dChkKTtsZXQgaD10OygoKGk9dGhpcy5vcHRpb25zKT09bnVsbD92b2lkIDA6aS5zZWxmaWVTZWdtZW50YXRpb25UeXBlKSYmKChvPXRoaXMub3B0aW9ucyk9PW51bGw/dm9pZCAwOm8uc2VsZmllU2VnbWVudGF0aW9uVHlwZSk9PT0iUFJFQ0lTRSJ8fCEoKHM9dGhpcy5vcHRpb25zKSE9bnVsbCYmcy5zZWxmaWVTZWdtZW50YXRpb25UeXBlKSYmdGhpcy5hY3RpdmVQaXBlbGluZS5wcmVjaXNlTWFza0VuYWJsZWQpJiYodGhpcy5pbXByb3ZlTWFza1NlZ21lbnRhdGlvbi5zZXRJZCh0aGlzLmlkKSx0aGlzLmltcHJvdmVNYXNrU2VnbWVudGF0aW9uLnNldFByb2ZpbGVyKHRoaXMucHJvZmlsZXIpLHRoaXMuaW1wcm92ZU1hc2tTZWdtZW50YXRpb24uc2V0RGF0YShlLHQpLHRoaXMuaW1wcm92ZU1hc2tTZWdtZW50YXRpb24ucnVuKCksaD10aGlzLmltcHJvdmVNYXNrU2VnbWVudGF0aW9uLm91dHB1dCksdGhpcy5hY3RpdmVQaXBlbGluZS5zZXRJZCh0aGlzLmlkKSx0aGlzLmFjdGl2ZVBpcGVsaW5lLnNldFByb2ZpbGVyKHRoaXMucHJvZmlsZXIpLChhPXRoaXMuYWN0aXZlUGlwZWxpbmUpPT1udWxsfHxhLnNldERhdGEoZSxoKSwodT10aGlzLmFjdGl2ZVBpcGVsaW5lKT09bnVsbHx8dS5ydW4oKSwoZj10aGlzLnByb2ZpbGVyKT09bnVsbHx8Zi5wb3BDb250ZXh0KGQpfX1hc3luYyByZXNpemVGb3JlZ3JvdW5kKGUsdCl7dmFyIG47dGhpcy5jYW52YXMud2lkdGg9ZSx0aGlzLmNhbnZhcy5oZWlnaHQ9dCx0aGlzLmJhY2tncm91bmRJbWFnZS5yZXNpemVPdXRwdXQoZSx0KSx0aGlzLmJhY2tncm91bmRWaWRlby5yZXNpemVPdXRwdXQoZSx0KSx0aGlzLmJhY2tncm91bmRSZXNpemVyLnJlc2l6ZUZvcmVncm91bmQoZSx0KSwobj10aGlzLmFjdGl2ZVBpcGVsaW5lKT09bnVsbHx8bi5yZXNpemVPdXRwdXQoZSx0KSx0aGlzLnZpcnR1YWxCR0ltYWdlJiYodGhpcy5iYWNrZ3JvdW5kSW1hZ2UuaW5wdXRCYWNrZ3JvdW5kSW1hZ2U9YXdhaXQgdGhpcy5iYWNrZ3JvdW5kUmVzaXplci5wcm9jZXNzKHRoaXMudmlydHVhbEJHSW1hZ2UpKX1hc3luYyBwcm9maWxlKGUpe2NvbnN0IHQ9bmV3IFBvKHRoaXMuY29udGV4dCk7cmV0dXJuIHRoaXMucHJvZmlsZXI9dCx0LnN0YXJ0KCksYXdhaXQgR3IoZSksdGhpcy5wcm9maWxlcj12b2lkIDAsdC5zdG9wKCksdC5nZXRSZXNvbHZlZFF1ZXJpZXMoKX1nZXRCbHVyU2l6ZShlPVplLkxvdyl7c3dpdGNoKGUpe2Nhc2UgWmUuTG93OnJldHVybiA1O2Nhc2UgWmUuSGlnaDpyZXR1cm4gMTJ9cmV0dXJuIGV9fXZhciBoZj1mdW5jdGlvbigpe3ZhciByPXR5cGVvZiBkb2N1bWVudDwidSImJmRvY3VtZW50LmN1cnJlbnRTY3JpcHQ/ZG9jdW1lbnQuY3VycmVudFNjcmlwdC5zcmM6dm9pZCAwO3JldHVybiBmdW5jdGlvbihlKXtlPWV8fHt9O3ZhciB0PXR5cGVvZiBlPCJ1Ij9lOnt9LG4saTt0LnJlYWR5PW5ldyBQcm9taXNlKGZ1bmN0aW9uKGMsbSl7bj1jLGk9bX0pO3ZhciBvPXt9LHM7Zm9yKHMgaW4gdCl0Lmhhc093blByb3BlcnR5KHMpJiYob1tzXT10W3NdKTt2YXIgYT0iLi90aGlzLnByb2dyYW0iLHU9ZnVuY3Rpb24oYyxtKXt0aHJvdyBtfSxmPSEwLGQ9IiI7ZnVuY3Rpb24gaChjKXtyZXR1cm4gdC5sb2NhdGVGaWxlP3QubG9jYXRlRmlsZShjLGQpOmQrY312YXIgeTt0eXBlb2YgZG9jdW1lbnQ8InUiJiZkb2N1bWVudC5jdXJyZW50U2NyaXB0JiYoZD1kb2N1bWVudC5jdXJyZW50U2NyaXB0LnNyYyksciYmKGQ9ciksZC5pbmRleE9mKCJibG9iOiIpIT09MD9kPWQuc3Vic3RyKDAsZC5yZXBsYWNlKC9bPyNdLiovLCIiKS5sYXN0SW5kZXhPZigiLyIpKzEpOmQ9IiI7dmFyIHg9dC5wcmludHx8Y29uc29sZS5sb2cuYmluZChjb25zb2xlKSxsPXQucHJpbnRFcnJ8fGNvbnNvbGUud2Fybi5iaW5kKGNvbnNvbGUpO2ZvcihzIGluIG8pby5oYXNPd25Qcm9wZXJ0eShzKSYmKHRbc109b1tzXSk7bz1udWxsLHQuYXJndW1lbnRzJiZ0LmFyZ3VtZW50cyx0LnRoaXNQcm9ncmFtJiYoYT10LnRoaXNQcm9ncmFtKSx0LnF1aXQmJih1PXQucXVpdCk7dmFyIGc7dC53YXNtQmluYXJ5JiYoZz10Lndhc21CaW5hcnkpO3ZhciBFPXQubm9FeGl0UnVudGltZXx8ITA7dHlwZW9mIFdlYkFzc2VtYmx5IT0ib2JqZWN0IiYmY2UoIm5vIG5hdGl2ZSB3YXNtIHN1cHBvcnQgZGV0ZWN0ZWQiKTt2YXIgdixJPSExLEQ9dHlwZW9mIFRleHREZWNvZGVyPCJ1Ij9uZXcgVGV4dERlY29kZXIoInV0ZjgiKTp2b2lkIDA7ZnVuY3Rpb24gRyhjLG0sXyl7Zm9yKHZhciBUPW0rXyxOPW07Y1tOXSYmIShOPj1UKTspKytOO2lmKE4tbT4xNiYmYy5zdWJhcnJheSYmRClyZXR1cm4gRC5kZWNvZGUoYy5zdWJhcnJheShtLE4pKTtmb3IodmFyIGs9IiI7bTxOOyl7dmFyIHc9Y1ttKytdO2lmKCEodyYxMjgpKXtrKz1TdHJpbmcuZnJvbUNoYXJDb2RlKHcpO2NvbnRpbnVlfXZhciBPPWNbbSsrXSY2MztpZigodyYyMjQpPT0xOTIpe2srPVN0cmluZy5mcm9tQ2hhckNvZGUoKHcmMzEpPDw2fE8pO2NvbnRpbnVlfXZhciBLPWNbbSsrXSY2MztpZigodyYyNDApPT0yMjQ/dz0odyYxNSk8PDEyfE88PDZ8Szp3PSh3JjcpPDwxOHxPPDwxMnxLPDw2fGNbbSsrXSY2Myx3PDY1NTM2KWsrPVN0cmluZy5mcm9tQ2hhckNvZGUodyk7ZWxzZXt2YXIgaGk9dy02NTUzNjtrKz1TdHJpbmcuZnJvbUNoYXJDb2RlKDU1Mjk2fGhpPj4xMCw1NjMyMHxoaSYxMDIzKX19cmV0dXJuIGt9ZnVuY3Rpb24gJChjLG0pe3JldHVybiBjP0coTGUsYyxtKToiIn1mdW5jdGlvbiBaKGMsbSxfKXtmb3IodmFyIFQ9MDtUPGMubGVuZ3RoOysrVClFdFttKys+PjBdPWMuY2hhckNvZGVBdChUKTtffHwoRXRbbT4+MF09MCl9ZnVuY3Rpb24gSChjLG0pe3JldHVybiBjJW0+MCYmKGMrPW0tYyVtKSxjfXZhciBzaSxFdCxMZSxZO2Z1bmN0aW9uIGFpKGMpe3NpPWMsdC5IRUFQOD1FdD1uZXcgSW50OEFycmF5KGMpLHQuSEVBUDE2PW5ldyBJbnQxNkFycmF5KGMpLHQuSEVBUDMyPVk9bmV3IEludDMyQXJyYXkoYyksdC5IRUFQVTg9TGU9bmV3IFVpbnQ4QXJyYXkoYyksdC5IRUFQVTE2PW5ldyBVaW50MTZBcnJheShjKSx0LkhFQVBVMzI9bmV3IFVpbnQzMkFycmF5KGMpLHQuSEVBUEYzMj1uZXcgRmxvYXQzMkFycmF5KGMpLHQuSEVBUEY2ND1uZXcgRmxvYXQ2NEFycmF5KGMpfXQuSU5JVElBTF9NRU1PUlk7dmFyIEVyLHVpPVtdLGNpPVtdLGZpPVtdLHZmPTA7ZnVuY3Rpb24gRWYoKXtyZXR1cm4gRXx8dmY+MH1mdW5jdGlvbiBUZigpe2lmKHQucHJlUnVuKWZvcih0eXBlb2YgdC5wcmVSdW49PSJmdW5jdGlvbiImJih0LnByZVJ1bj1bdC5wcmVSdW5dKTt0LnByZVJ1bi5sZW5ndGg7KVNmKHQucHJlUnVuLnNoaWZ0KCkpO1RyKHVpKX1mdW5jdGlvbiBBZigpe1RyKGNpKX1mdW5jdGlvbiB3Zigpe2lmKHQucG9zdFJ1bilmb3IodHlwZW9mIHQucG9zdFJ1bj09ImZ1bmN0aW9uIiYmKHQucG9zdFJ1bj1bdC5wb3N0UnVuXSk7dC5wb3N0UnVuLmxlbmd0aDspSWYodC5wb3N0UnVuLnNoaWZ0KCkpO1RyKGZpKX1mdW5jdGlvbiBTZihjKXt1aS51bnNoaWZ0KGMpfWZ1bmN0aW9uIFJmKGMpe2NpLnVuc2hpZnQoYyl9ZnVuY3Rpb24gSWYoYyl7ZmkudW5zaGlmdChjKX12YXIgZ2U9MCxHZT1udWxsO2Z1bmN0aW9uIEZmKGMpe2dlKyssdC5tb25pdG9yUnVuRGVwZW5kZW5jaWVzJiZ0Lm1vbml0b3JSdW5EZXBlbmRlbmNpZXMoZ2UpfWZ1bmN0aW9uIFBmKGMpe2lmKGdlLS0sdC5tb25pdG9yUnVuRGVwZW5kZW5jaWVzJiZ0Lm1vbml0b3JSdW5EZXBlbmRlbmNpZXMoZ2UpLGdlPT0wJiZHZSl7dmFyIG09R2U7R2U9bnVsbCxtKCl9fXQucHJlbG9hZGVkSW1hZ2VzPXt9LHQucHJlbG9hZGVkQXVkaW9zPXt9O2Z1bmN0aW9uIGNlKGMpe3Qub25BYm9ydCYmdC5vbkFib3J0KGMpLGM9IkFib3J0ZWQoIitjKyIpIixsKGMpLEk9ITAsYys9Ii4gQnVpbGQgd2l0aCAtcyBBU1NFUlRJT05TPTEgZm9yIG1vcmUgaW5mby4iO3ZhciBtPW5ldyBXZWJBc3NlbWJseS5SdW50aW1lRXJyb3IoYyk7dGhyb3cgaShtKSxtfXZhciBEZj0iZGF0YTphcHBsaWNhdGlvbi9vY3RldC1zdHJlYW07YmFzZTY0LCI7ZnVuY3Rpb24gbGkoYyl7cmV0dXJuIGMuc3RhcnRzV2l0aChEZil9dmFyIGo7aj0idGZsaXRlLXNpbWQud2FzbSIsbGkoail8fChqPWgoaikpO2Z1bmN0aW9uIGRpKGMpe3RyeXtpZihjPT1qJiZnKXJldHVybiBuZXcgVWludDhBcnJheShnKTtpZigheSl0aHJvdyJib3RoIGFzeW5jIGFuZCBzeW5jIGZldGNoaW5nIG9mIHRoZSB3YXNtIGZhaWxlZCJ9Y2F0Y2gobSl7Y2UobSl9fWZ1bmN0aW9uIE5mKCl7cmV0dXJuIWcmJmYmJnR5cGVvZiBmZXRjaD09ImZ1bmN0aW9uIj9mZXRjaChqLHtjcmVkZW50aWFsczoic2FtZS1vcmlnaW4ifSkudGhlbihmdW5jdGlvbihjKXtpZighYy5vayl0aHJvdyJmYWlsZWQgdG8gbG9hZCB3YXNtIGJpbmFyeSBmaWxlIGF0ICciK2orIiciO3JldHVybiBjLmFycmF5QnVmZmVyKCl9KS5jYXRjaChmdW5jdGlvbigpe3JldHVybiBkaShqKX0pOlByb21pc2UucmVzb2x2ZSgpLnRoZW4oZnVuY3Rpb24oKXtyZXR1cm4gZGkoail9KX1mdW5jdGlvbiBNZigpe3ZhciBjPXthOmVsfTtmdW5jdGlvbiBtKHcsTyl7dmFyIEs9dy5leHBvcnRzO3QuYXNtPUssdj10LmFzbS5xLGFpKHYuYnVmZmVyKSxFcj10LmFzbS5FLFJmKHQuYXNtLnIpLFBmKCl9RmYoKTtmdW5jdGlvbiBfKHcpe20ody5pbnN0YW5jZSl9ZnVuY3Rpb24gVCh3KXtyZXR1cm4gTmYoKS50aGVuKGZ1bmN0aW9uKE8pe3JldHVybiBXZWJBc3NlbWJseS5pbnN0YW50aWF0ZShPLGMpfSkudGhlbihmdW5jdGlvbihPKXtyZXR1cm4gT30pLnRoZW4odyxmdW5jdGlvbihPKXtsKCJmYWlsZWQgdG8gYXN5bmNocm9ub3VzbHkgcHJlcGFyZSB3YXNtOiAiK08pLGNlKE8pfSl9ZnVuY3Rpb24gTigpe3JldHVybiFnJiZ0eXBlb2YgV2ViQXNzZW1ibHkuaW5zdGFudGlhdGVTdHJlYW1pbmc9PSJmdW5jdGlvbiImJiFsaShqKSYmdHlwZW9mIGZldGNoPT0iZnVuY3Rpb24iP2ZldGNoKGose2NyZWRlbnRpYWxzOiJzYW1lLW9yaWdpbiJ9KS50aGVuKGZ1bmN0aW9uKHcpe3ZhciBPPVdlYkFzc2VtYmx5Lmluc3RhbnRpYXRlU3RyZWFtaW5nKHcsYyk7cmV0dXJuIE8udGhlbihfLGZ1bmN0aW9uKEspe3JldHVybiBsKCJ3YXNtIHN0cmVhbWluZyBjb21waWxlIGZhaWxlZDogIitLKSxsKCJmYWxsaW5nIGJhY2sgdG8gQXJyYXlCdWZmZXIgaW5zdGFudGlhdGlvbiIpLFQoXyl9KX0pOlQoXyl9aWYodC5pbnN0YW50aWF0ZVdhc20pdHJ5e3ZhciBrPXQuaW5zdGFudGlhdGVXYXNtKGMsbSk7cmV0dXJuIGt9Y2F0Y2godyl7cmV0dXJuIGwoIk1vZHVsZS5pbnN0YW50aWF0ZVdhc20gY2FsbGJhY2sgZmFpbGVkIHdpdGggZXJyb3I6ICIrdyksITF9cmV0dXJuIE4oKS5jYXRjaChpKSx7fX1mdW5jdGlvbiBUcihjKXtmb3IoO2MubGVuZ3RoPjA7KXt2YXIgbT1jLnNoaWZ0KCk7aWYodHlwZW9mIG09PSJmdW5jdGlvbiIpe20odCk7Y29udGludWV9dmFyIF89bS5mdW5jO3R5cGVvZiBfPT0ibnVtYmVyIj9tLmFyZz09PXZvaWQgMD9Fci5nZXQoXykoKTpFci5nZXQoXykobS5hcmcpOl8obS5hcmc9PT12b2lkIDA/bnVsbDptLmFyZyl9fWZ1bmN0aW9uIFVmKGMsbSxfLFQpe2NlKCJBc3NlcnRpb24gZmFpbGVkOiAiKyQoYykrIiwgYXQ6ICIrW20/JChtKToidW5rbm93biBmaWxlbmFtZSIsXyxUPyQoVCk6InVua25vd24gZnVuY3Rpb24iXSl9ZnVuY3Rpb24ga2YoYyxtKXtjZSgiVG8gdXNlIGRsb3BlbiwgeW91IG5lZWQgdG8gdXNlIEVtc2NyaXB0ZW4ncyBsaW5raW5nIHN1cHBvcnQsIHNlZSBodHRwczovL2dpdGh1Yi5jb20vZW1zY3JpcHRlbi1jb3JlL2Vtc2NyaXB0ZW4vd2lraS9MaW5raW5nIil9ZnVuY3Rpb24gQ2YoYyxtKXtjZSgiVG8gdXNlIGRsb3BlbiwgeW91IG5lZWQgdG8gdXNlIEVtc2NyaXB0ZW4ncyBsaW5raW5nIHN1cHBvcnQsIHNlZSBodHRwczovL2dpdGh1Yi5jb20vZW1zY3JpcHRlbi1jb3JlL2Vtc2NyaXB0ZW4vd2lraS9MaW5raW5nIil9ZnVuY3Rpb24gT2YoKXtjZSgiIil9dmFyIFR0O1R0PWZ1bmN0aW9uKCl7cmV0dXJuIHBlcmZvcm1hbmNlLm5vdygpfTt2YXIgQmY9ITA7ZnVuY3Rpb24gTGYoYyl7cmV0dXJuIFlbbWkoKT4+Ml09YyxjfWZ1bmN0aW9uIEdmKGMsbSl7dmFyIF87aWYoYz09PTApXz1EYXRlLm5vdygpO2Vsc2UgaWYoKGM9PT0xfHxjPT09NCkmJkJmKV89VHQoKTtlbHNlIHJldHVybiBMZigyOCksLTE7cmV0dXJuIFlbbT4+Ml09Xy8xZTN8MCxZW20rND4+Ml09XyUxZTMqMWUzKjFlM3wwLDB9ZnVuY3Rpb24gJGYoKXtyZXR1cm4gMjE0NzQ4MzY0OH1mdW5jdGlvbiB6ZihjLG0sXyl7TGUuY29weVdpdGhpbihjLG0sbStfKX1mdW5jdGlvbiBXZihjKXt0cnl7cmV0dXJuIHYuZ3JvdyhjLXNpLmJ5dGVMZW5ndGgrNjU1MzU+Pj4xNiksYWkodi5idWZmZXIpLDF9Y2F0Y2h7fX1mdW5jdGlvbiBWZihjKXt2YXIgbT1MZS5sZW5ndGg7Yz1jPj4+MDt2YXIgXz0yMTQ3NDgzNjQ4O2lmKGM+XylyZXR1cm4hMTtmb3IodmFyIFQ9MTtUPD00O1QqPTIpe3ZhciBOPW0qKDErLjIvVCk7Tj1NYXRoLm1pbihOLGMrMTAwNjYzMjk2KTt2YXIgaz1NYXRoLm1pbihfLEgoTWF0aC5tYXgoYyxOKSw2NTUzNikpLHc9V2Yoayk7aWYodylyZXR1cm4hMH1yZXR1cm4hMX1mdW5jdGlvbiBIZihjKXtmb3IodmFyIG09VHQoKTtUdCgpLW08YzspO312YXIgQXI9e307ZnVuY3Rpb24gWWYoKXtyZXR1cm4gYXx8Ii4vdGhpcy5wcm9ncmFtIn1mdW5jdGlvbiAkZSgpe2lmKCEkZS5zdHJpbmdzKXt2YXIgYz0odHlwZW9mIG5hdmlnYXRvcj09Im9iamVjdCImJm5hdmlnYXRvci5sYW5ndWFnZXMmJm5hdmlnYXRvci5sYW5ndWFnZXNbMF18fCJDIikucmVwbGFjZSgiLSIsIl8iKSsiLlVURi04IixtPXtVU0VSOiJ3ZWJfdXNlciIsTE9HTkFNRToid2ViX3VzZXIiLFBBVEg6Ii8iLFBXRDoiLyIsSE9NRToiL2hvbWUvd2ViX3VzZXIiLExBTkc6YyxfOllmKCl9O2Zvcih2YXIgXyBpbiBBcilBcltfXT09PXZvaWQgMD9kZWxldGUgbVtfXTptW19dPUFyW19dO3ZhciBUPVtdO2Zvcih2YXIgXyBpbiBtKVQucHVzaChfKyI9IittW19dKTskZS5zdHJpbmdzPVR9cmV0dXJuICRlLnN0cmluZ3N9dmFyIEF0PXttYXBwaW5nczp7fSxidWZmZXJzOltudWxsLFtdLFtdXSxwcmludENoYXI6ZnVuY3Rpb24oYyxtKXt2YXIgXz1BdC5idWZmZXJzW2NdO209PT0wfHxtPT09MTA/KChjPT09MT94OmwpKEcoXywwKSksXy5sZW5ndGg9MCk6Xy5wdXNoKG0pfSx2YXJhcmdzOnZvaWQgMCxnZXQ6ZnVuY3Rpb24oKXtBdC52YXJhcmdzKz00O3ZhciBjPVlbQXQudmFyYXJncy00Pj4yXTtyZXR1cm4gY30sZ2V0U3RyOmZ1bmN0aW9uKGMpe3ZhciBtPSQoYyk7cmV0dXJuIG19LGdldDY0OmZ1bmN0aW9uKGMsbSl7cmV0dXJuIGN9fTtmdW5jdGlvbiBqZihjLG0pe3ZhciBfPTA7cmV0dXJuICRlKCkuZm9yRWFjaChmdW5jdGlvbihULE4pe3ZhciBrPW0rXztZW2MrTio0Pj4yXT1rLFooVCxrKSxfKz1ULmxlbmd0aCsxfSksMH1mdW5jdGlvbiBYZihjLG0pe3ZhciBfPSRlKCk7WVtjPj4yXT1fLmxlbmd0aDt2YXIgVD0wO3JldHVybiBfLmZvckVhY2goZnVuY3Rpb24oTil7VCs9Ti5sZW5ndGgrMX0pLFlbbT4+Ml09VCwwfWZ1bmN0aW9uIFFmKGMpe3JsKGMpfWZ1bmN0aW9uIEtmKGMpe3JldHVybiAwfWZ1bmN0aW9uIHFmKGMsbSxfLFQsTil7fWZ1bmN0aW9uIEpmKGMsbSxfLFQpe2Zvcih2YXIgTj0wLGs9MDtrPF87aysrKXtmb3IodmFyIHc9WVttK2sqOD4+Ml0sTz1ZW20rKGsqOCs0KT4+Ml0sSz0wO0s8TztLKyspQXQucHJpbnRDaGFyKGMsTGVbdytLXSk7Tis9T31yZXR1cm4gWVtUPj4yXT1OLDB9ZnVuY3Rpb24gWmYoKXtpZih0eXBlb2YgY3J5cHRvPT0ib2JqZWN0IiYmdHlwZW9mIGNyeXB0by5nZXRSYW5kb21WYWx1ZXM9PSJmdW5jdGlvbiIpe3ZhciBjPW5ldyBVaW50OEFycmF5KDEpO3JldHVybiBmdW5jdGlvbigpe3JldHVybiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKGMpLGNbMF19fWVsc2UgcmV0dXJuIGZ1bmN0aW9uKCl7Y2UoInJhbmRvbURldmljZSIpfX1mdW5jdGlvbiB3dChjLG0pe3d0LnJhbmRvbURldmljZXx8KHd0LnJhbmRvbURldmljZT1aZigpKTtmb3IodmFyIF89MDtfPG07XysrKUV0W2MrXz4+MF09d3QucmFuZG9tRGV2aWNlKCk7cmV0dXJuIDB9dmFyIGVsPXthOlVmLGU6a2YsZDpDZixiOk9mLG46R2YsaDokZixsOnpmLG06VmYscDpIZixmOmpmLGc6WGYsajpRZixpOktmLGs6cWYsYzpKZixvOnd0fTtNZigpLHQuX19fd2FzbV9jYWxsX2N0b3JzPWZ1bmN0aW9uKCl7cmV0dXJuKHQuX19fd2FzbV9jYWxsX2N0b3JzPXQuYXNtLnIpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sdC5fZ2V0TW9kZWxCdWZmZXJNZW1vcnlPZmZzZXQ9ZnVuY3Rpb24oKXtyZXR1cm4odC5fZ2V0TW9kZWxCdWZmZXJNZW1vcnlPZmZzZXQ9dC5hc20ucykuYXBwbHkobnVsbCxhcmd1bWVudHMpfSx0Ll9nZXRJbnB1dE1lbW9yeU9mZnNldD1mdW5jdGlvbigpe3JldHVybih0Ll9nZXRJbnB1dE1lbW9yeU9mZnNldD10LmFzbS50KS5hcHBseShudWxsLGFyZ3VtZW50cyl9LHQuX2dldElucHV0SGVpZ2h0PWZ1bmN0aW9uKCl7cmV0dXJuKHQuX2dldElucHV0SGVpZ2h0PXQuYXNtLnUpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sdC5fZ2V0SW5wdXRXaWR0aD1mdW5jdGlvbigpe3JldHVybih0Ll9nZXRJbnB1dFdpZHRoPXQuYXNtLnYpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sdC5fZ2V0SW5wdXRDaGFubmVsQ291bnQ9ZnVuY3Rpb24oKXtyZXR1cm4odC5fZ2V0SW5wdXRDaGFubmVsQ291bnQ9dC5hc20udykuYXBwbHkobnVsbCxhcmd1bWVudHMpfSx0Ll9nZXRPdXRwdXRNZW1vcnlPZmZzZXQ9ZnVuY3Rpb24oKXtyZXR1cm4odC5fZ2V0T3V0cHV0TWVtb3J5T2Zmc2V0PXQuYXNtLngpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sdC5fZ2V0T3V0cHV0SGVpZ2h0PWZ1bmN0aW9uKCl7cmV0dXJuKHQuX2dldE91dHB1dEhlaWdodD10LmFzbS55KS5hcHBseShudWxsLGFyZ3VtZW50cyl9LHQuX2dldE91dHB1dFdpZHRoPWZ1bmN0aW9uKCl7cmV0dXJuKHQuX2dldE91dHB1dFdpZHRoPXQuYXNtLnopLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sdC5fZ2V0T3V0cHV0Q2hhbm5lbENvdW50PWZ1bmN0aW9uKCl7cmV0dXJuKHQuX2dldE91dHB1dENoYW5uZWxDb3VudD10LmFzbS5BKS5hcHBseShudWxsLGFyZ3VtZW50cyl9LHQuX2xvYWRNb2RlbD1mdW5jdGlvbigpe3JldHVybih0Ll9sb2FkTW9kZWw9dC5hc20uQikuYXBwbHkobnVsbCxhcmd1bWVudHMpfSx0Ll9ydW5JbmZlcmVuY2U9ZnVuY3Rpb24oKXtyZXR1cm4odC5fcnVuSW5mZXJlbmNlPXQuYXNtLkMpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sdC5faXNHUFVFbmFibGVkPWZ1bmN0aW9uKCl7cmV0dXJuKHQuX2lzR1BVRW5hYmxlZD10LmFzbS5EKS5hcHBseShudWxsLGFyZ3VtZW50cyl9O3ZhciBtaT10Ll9fX2Vycm5vX2xvY2F0aW9uPWZ1bmN0aW9uKCl7cmV0dXJuKG1pPXQuX19fZXJybm9fbG9jYXRpb249dC5hc20uRikuYXBwbHkobnVsbCxhcmd1bWVudHMpfSxTdDtmdW5jdGlvbiB0bChjKXt0aGlzLm5hbWU9IkV4aXRTdGF0dXMiLHRoaXMubWVzc2FnZT0iUHJvZ3JhbSB0ZXJtaW5hdGVkIHdpdGggZXhpdCgiK2MrIikiLHRoaXMuc3RhdHVzPWN9R2U9ZnVuY3Rpb24gYygpe1N0fHx3cigpLFN0fHwoR2U9Yyl9O2Z1bmN0aW9uIHdyKGMpe2lmKGdlPjB8fChUZigpLGdlPjApKXJldHVybjtmdW5jdGlvbiBtKCl7U3R8fChTdD0hMCx0LmNhbGxlZFJ1bj0hMCwhSSYmKEFmKCksbih0KSx0Lm9uUnVudGltZUluaXRpYWxpemVkJiZ0Lm9uUnVudGltZUluaXRpYWxpemVkKCksd2YoKSkpfXQuc2V0U3RhdHVzPyh0LnNldFN0YXR1cygiUnVubmluZy4uLiIpLHNldFRpbWVvdXQoZnVuY3Rpb24oKXtzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7dC5zZXRTdGF0dXMoIiIpfSwxKSxtKCl9LDEpKTptKCl9dC5ydW49d3I7ZnVuY3Rpb24gcmwoYyxtKXtubChjKX1mdW5jdGlvbiBubChjKXtFZigpfHwodC5vbkV4aXQmJnQub25FeGl0KGMpLEk9ITApLHUoYyxuZXcgdGwoYykpfWlmKHQucHJlSW5pdClmb3IodHlwZW9mIHQucHJlSW5pdD09ImZ1bmN0aW9uIiYmKHQucHJlSW5pdD1bdC5wcmVJbml0XSk7dC5wcmVJbml0Lmxlbmd0aD4wOyl0LnByZUluaXQucG9wKCkoKTtyZXR1cm4gd3IoKSxlLnJlYWR5fX0oKTtjbGFzcyBwZntjb25zdHJ1Y3Rvcigpe3AodGhpcywic2VsZWN0ZWRURkxpdGUiKTtwKHRoaXMsImlzU0lNRFN1cHBvcnRlZCIsITEpO3AodGhpcywiaXNUaHJlYWRzU3VwcG9ydGVkIiwhMSk7cCh0aGlzLCJpbnB1dFdpZHRoIiwwKTtwKHRoaXMsImlucHV0SGVpZ2h0IiwwKTtwKHRoaXMsImlucHV0Q2hhbm5lbENvdW50IiwwKTtwKHRoaXMsImlucHV0TWVtb3J5T2Zmc2V0IiwwKTtwKHRoaXMsIm91dHB1dFdpZHRoIiwwKTtwKHRoaXMsIm91dHB1dEhlaWdodCIsMCk7cCh0aGlzLCJvdXRwdXRDaGFubmVsQ291bnQiLDApO3AodGhpcywib3V0cHV0TWVtb3J5T2Zmc2V0IiwwKX19Y29uc3QgeWY9Imh0dHBzOi8vZDNvcHFqbXF6eGYwNTcuY2xvdWRmcm9udC5uZXQvdm9uYWdlLXRlbnNvcmZsb3ctd2FzbS90ZmxpdGUtc2ltZC13YXNtLzEuMS4zLyIsX2Y9Imh0dHBzOi8vZDNvcHFqbXF6eGYwNTcuY2xvdWRmcm9udC5uZXQvbWwvc2VsZmllX3NlZ21lbnRhdGlvbi80LjAuMC8iO2FzeW5jIGZ1bmN0aW9uIHhmKHI9eWYsZT1fZil7bGV0IHQ9bmV3IHBmO3ZhciBuPW5ldyBQcm9taXNlKGZ1bmN0aW9uKGksbyl7YXN5bmMgZnVuY3Rpb24gcygpe3JldHVybiBoZih7bG9jYXRlRmlsZTpmdW5jdGlvbihmKXtyZXR1cm4gcitmfX0pfWFzeW5jIGZ1bmN0aW9uIGEodSl7cmV0dXJuIG5ldyBQcm9taXNlKGFzeW5jKGYsZCk9Pntjb25zdCBoPXU7aWYodHlwZW9mIGg+InUiKXJldHVybiBkKCJURkxpdGUgYmFja2VuZCB1bmF2YWlsYWJsZTogd2FzbVNpbWQiKTtjb25zdCB5PSJzZWxmaWVfc2VnbWVudGF0aW9uX2xhbmRzY2FwZSI7Y29uc29sZS5sb2coIkxvYWRpbmcgdGZsaXRlIG1vZGVsOiIseSk7bGV0IHg9ZStgJHt5fS50ZmxpdGVgO2NvbnNvbGUubG9nKCJURkxpdGUgbW9kZWxVcmw6ICIreCk7dHJ5e2NvbnN0IGc9YXdhaXQoYXdhaXQgZmV0Y2goeCkpLmFycmF5QnVmZmVyKCk7Y29uc29sZS5sb2coIk1vZGVsIGJ1ZmZlciBzaXplOiIsZy5ieXRlTGVuZ3RoKTtjb25zdCBFPWguX2dldE1vZGVsQnVmZmVyTWVtb3J5T2Zmc2V0KCk7Y29uc29sZS5sb2coIk1vZGVsIGJ1ZmZlciBtZW1vcnkgb2Zmc2V0OiIsRSksY29uc29sZS5sb2coIkxvYWRpbmcgbW9kZWwgYnVmZmVyLi4uIiksaC5IRUFQVTguc2V0KG5ldyBVaW50OEFycmF5KGcpLEUpO2NvbnN0IHY9aC5fbG9hZE1vZGVsKGcuYnl0ZUxlbmd0aCk7aWYoY29uc29sZS5sb2coIkxvYWQgbW9kZWwgcmVzdWx0OiIsdiksdiE9PTApe2QoIkNhbm5vdCBsb2FkIG1vZGVsIik7cmV0dXJufXQuaW5wdXRXaWR0aD1oLl9nZXRJbnB1dFdpZHRoKCksdC5pbnB1dEhlaWdodD1oLl9nZXRJbnB1dEhlaWdodCgpLHQuaW5wdXRDaGFubmVsQ291bnQ9aC5fZ2V0SW5wdXRDaGFubmVsQ291bnQoKSx0LmlucHV0TWVtb3J5T2Zmc2V0PWguX2dldElucHV0TWVtb3J5T2Zmc2V0KCksY29uc29sZS5sb2coIklucHV0IG1lbW9yeSBvZmZzZXQ6Iix0LmlucHV0TWVtb3J5T2Zmc2V0KSxjb25zb2xlLmxvZygiSW5wdXQgaGVpZ2h0OiIsdC5pbnB1dEhlaWdodCksY29uc29sZS5sb2coIklucHV0IHdpZHRoOiIsdC5pbnB1dFdpZHRoKSxjb25zb2xlLmxvZygiSW5wdXQgY2hhbm5lbHM6Iix0LmlucHV0Q2hhbm5lbENvdW50KSx0Lm91dHB1dE1lbW9yeU9mZnNldD1oLl9nZXRPdXRwdXRNZW1vcnlPZmZzZXQoKSx0Lm91dHB1dFdpZHRoPWguX2dldE91dHB1dFdpZHRoKCksdC5vdXRwdXRIZWlnaHQ9aC5fZ2V0T3V0cHV0SGVpZ2h0KCksdC5vdXRwdXRDaGFubmVsQ291bnQ9aC5fZ2V0T3V0cHV0Q2hhbm5lbENvdW50KCksY29uc29sZS5sb2coIk91dHB1dCBtZW1vcnkgb2Zmc2V0OiIsdC5vdXRwdXRNZW1vcnlPZmZzZXQpLGNvbnNvbGUubG9nKCJPdXRwdXQgaGVpZ2h0OiIsdC5vdXRwdXRIZWlnaHQpLGNvbnNvbGUubG9nKCJPdXRwdXQgd2lkdGg6Iix0Lm91dHB1dFdpZHRoKSxjb25zb2xlLmxvZygiT3V0cHV0IGNoYW5uZWxzOiIsdC5vdXRwdXRDaGFubmVsQ291bnQpLHQuc2VsZWN0ZWRURkxpdGU9aH1jYXRjaChsKXtkKGwpO3JldHVybn1mKCl9KX1zKCkudGhlbih1PT57aWYodT09PW51bGwpdGhyb3cgY29uc29sZS5lcnJvcigibG9hZFRGTGl0ZSBudWxsIiksImxvYWRURkxpdGUgbnVsbCI7YSh1KS50aGVuKGY9PntpKHQpfSkuY2F0Y2goZj0+e2NvbnNvbGUuZXJyb3IoImxvYWRURkxpdGVNb2RlbCBlcnJvciIpLG8oImxvYWRURkxpdGVNb2RlbCBlcnJvciIpfSl9KS5jYXRjaCh1PT57Y29uc29sZS5lcnJvcigibG9hZFRGTGl0ZSBlcnJvcjoiLHUpLG8oImxvYWRURkxpdGUgZXJyb3I6Iit1KX0pfSk7cmV0dXJuIG59Y2xhc3MgZ2Z7Y29uc3RydWN0b3IoKXtwKHRoaXMsImNhbnZhcyIsbmV3IE9mZnNjcmVlbkNhbnZhcygwLDApKTtwKHRoaXMsImNvbnRleHQiLHRoaXMuY2FudmFzLmdldENvbnRleHQoIjJkIix7d2lsbFJlYWRGcmVxdWVudGx5OiEwfSkpO3AodGhpcywicGl4ZWxDb3VudCIsMCk7cCh0aGlzLCJpbnB1dE9mZnNldCIsMCk7cCh0aGlzLCJvdXRwdXRPZmZzZXQiLDApO3AodGhpcywiaW5mb3MiKTtwKHRoaXMsIm1hc2siKX1hc3luYyBpbml0KGUsdCl7YXdhaXQgdGhpcy5pbml0V2FzbShlLHQpLHRoaXMuaW5mb3MmJih0aGlzLmNhbnZhcy53aWR0aD10aGlzLmluZm9zLmlucHV0V2lkdGgsdGhpcy5jYW52YXMuaGVpZ2h0PXRoaXMuaW5mb3MuaW5wdXRIZWlnaHQsdGhpcy5waXhlbENvdW50PXRoaXMuaW5mb3MuaW5wdXRXaWR0aCp0aGlzLmluZm9zLmlucHV0SGVpZ2h0LHRoaXMubWFzaz1uZXcgSW1hZ2VEYXRhKHRoaXMuaW5mb3MuaW5wdXRXaWR0aCx0aGlzLmluZm9zLmlucHV0SGVpZ2h0KSx0aGlzLmlucHV0T2Zmc2V0PXRoaXMuaW5mb3MuaW5wdXRNZW1vcnlPZmZzZXQvNCx0aGlzLm91dHB1dE9mZnNldD10aGlzLmluZm9zLm91dHB1dE1lbW9yeU9mZnNldC80KX1hc3luYyBpbml0V2FzbShlLHQpe3RoaXMuaW5mb3M9YXdhaXQgeGYoZSx0KX1nZXRPdXRwdXREaW1lbnNpb25zKCl7dmFyIGUsdCxuLGk7cmV0dXJue3dpZHRoOih0PShlPXRoaXMuaW5mb3MpPT1udWxsP3ZvaWQgMDplLm91dHB1dFdpZHRoKSE9bnVsbD90OjAsaGVpZ2h0OihpPShuPXRoaXMuaW5mb3MpPT1udWxsP3ZvaWQgMDpuLm91dHB1dEhlaWdodCkhPW51bGw/aTowfX1hc3luYyBwcm9jZXNzKGUpe2lmKCF0aGlzLm1hc2t8fCF0aGlzLmluZm9zKXJldHVybjtjb25zdCB0PXRoaXMuaW5mb3MuaW5wdXRXaWR0aCxuPXRoaXMuaW5mb3MuaW5wdXRIZWlnaHQ7dGhpcy5jb250ZXh0LmRyYXdJbWFnZShlLDAsMCxlLndpZHRoLGUuaGVpZ2h0LDAsMCx0LG4pO2NvbnN0IGk9dGhpcy5jb250ZXh0LmdldEltYWdlRGF0YSgwLDAsdCxuKSxvPXRoaXMuaW5mb3Muc2VsZWN0ZWRURkxpdGUuSEVBUEYzMjtmb3IobGV0IHM9MDtzPHRoaXMucGl4ZWxDb3VudDtzKyspe2NvbnN0IGE9dGhpcy5pbnB1dE9mZnNldCtzKjM7b1thXT1pLmRhdGFbcyo0XS8yNTUsb1thKzFdPWkuZGF0YVtzKjQrMV0vMjU1LG9bYSsyXT1pLmRhdGFbcyo0KzJdLzI1NX10aGlzLmluZm9zLnNlbGVjdGVkVEZMaXRlLl9ydW5JbmZlcmVuY2UoKTtmb3IobGV0IHM9MDtzPHRoaXMucGl4ZWxDb3VudDtzKyspe2NvbnN0IGE9dGhpcy5pbmZvcy5zZWxlY3RlZFRGTGl0ZS5IRUFQRjMyW3RoaXMub3V0cHV0T2Zmc2V0K3NdO3RoaXMubWFzay5kYXRhW3MqNF09dGhpcy5tYXNrLmRhdGFbcyo0KzNdPTI1NSphfXJldHVybiBjcmVhdGVJbWFnZUJpdG1hcCh0aGlzLm1hc2spfWlzR3B1U3VwcG9ydGVkKCl7dmFyIGUsdCxuO3JldHVybihuPSh0PShlPXRoaXMuaW5mb3MpPT1udWxsP3ZvaWQgMDplLnNlbGVjdGVkVEZMaXRlKT09bnVsbD92b2lkIDA6dC5faXNHUFVFbmFibGVkKCkpIT1udWxsP246ITF9fWNsYXNzIGJme2NvbnN0cnVjdG9yKCl7cCh0aGlzLCJzZWxmaWVTZWdtZW50YXRpb24iLG5ldyBnZik7cCh0aGlzLCJiYWNrZ3JvdW5kRmlsdGVyIik7cCh0aGlzLCJyZXBvcnRlciIsbmV3IElvKTtwKHRoaXMsInByZXZpb3VzRGltZW5zaW9ucyIse3dpZHRoOjAsaGVpZ2h0OjB9KTtwKHRoaXMsImJhY2tncm91bmRPcHRpb25zIil9YXN5bmMgaW5pdChlLHQpe2F3YWl0IHRoaXMuc2VsZmllU2VnbWVudGF0aW9uLmluaXQodC53YXNtQXNzZXRVcmlQYXRoLHQudGZsaXRlQXNzZXRVcmlQYXRoKTtjb25zdHt3aWR0aDpuLGhlaWdodDppfT10aGlzLnNlbGZpZVNlZ21lbnRhdGlvbi5nZXRPdXRwdXREaW1lbnNpb25zKCk7dGhpcy5iYWNrZ3JvdW5kRmlsdGVyPW5ldyBtZihlLHtmb3JlZ3JvdW5kV2lkdGg6MSxmb3JlZ3JvdW5kSGVpZ2h0OjEsbWFza1dpZHRoOm4sbWFza0hlaWdodDppfSksdGhpcy5yZXBvcnQoe3ZhcmlhdGlvbjoiQ3JlYXRlIn0pfWFzeW5jIHRyYW5zZm9ybShlLHQpe3ZhciBzLGEsdSxmO2NvbnN0IG49KHM9ZS50aW1lc3RhbXApIT1udWxsP3M6MCxpPWF3YWl0IGNyZWF0ZUltYWdlQml0bWFwKGUpLG89YXdhaXQgdGhpcy5zZWxmaWVTZWdtZW50YXRpb24ucHJvY2VzcyhpKTtvPygoaS53aWR0aCE9PXRoaXMucHJldmlvdXNEaW1lbnNpb25zLndpZHRofHxpLmhlaWdodCE9PXRoaXMucHJldmlvdXNEaW1lbnNpb25zLmhlaWdodCkmJih0aGlzLnByZXZpb3VzRGltZW5zaW9ucy53aWR0aD1pLndpZHRoLHRoaXMucHJldmlvdXNEaW1lbnNpb25zLmhlaWdodD1pLmhlaWdodCxhd2FpdCgoYT10aGlzLmJhY2tncm91bmRGaWx0ZXIpPT1udWxsP3ZvaWQgMDphLnJlc2l6ZUZvcmVncm91bmQoaS53aWR0aCxpLmhlaWdodCkpKSxhd2FpdCgodT10aGlzLmJhY2tncm91bmRGaWx0ZXIpPT1udWxsP3ZvaWQgMDp1LnByb2Nlc3MoaSxvKSksZS5jbG9zZSgpLHQuZW5xdWV1ZShuZXcgVmlkZW9GcmFtZSgoZj10aGlzLmJhY2tncm91bmRGaWx0ZXIpPT1udWxsP3ZvaWQgMDpmLmNhbnZhcyx7dGltZXN0YW1wOm4sYWxwaGE6ImRpc2NhcmQifSkpKTp0LmVucXVldWUoZSl9YXN5bmMgc2V0QmFja2dyb3VuZE9wdGlvbnMoZSl7dmFyIHQ7dGhpcy5iYWNrZ3JvdW5kT3B0aW9ucz1lLGF3YWl0KCh0PXRoaXMuYmFja2dyb3VuZEZpbHRlcik9PW51bGw/dm9pZCAwOnQuc2V0QmFja2dyb3VuZE9wdGlvbnMoZSkpLHRoaXMucmVwb3J0KHt2YXJpYXRpb246IlVwZGF0ZSJ9KX1hc3luYyBzZXRWaWRlb0JHUmVhZGFibGUoZSl7dmFyIHQ7YXdhaXQoKHQ9dGhpcy5iYWNrZ3JvdW5kRmlsdGVyKT09bnVsbD92b2lkIDA6dC5zZXRWaWRlb0JHUmVhZGFibGUoZSkpfWFzeW5jIHNldFZpcnR1YWxCR0ltYWdlKGUpe3ZhciB0O2F3YWl0KCh0PXRoaXMuYmFja2dyb3VuZEZpbHRlcik9PW51bGw/dm9pZCAwOnQuc2V0VmlydHVhbEJHSW1hZ2UoZSkpfXNldEZsaWNrZXJpbmdPcHRpb25zKGUpe3ZhciB0Oyh0PXRoaXMuYmFja2dyb3VuZEZpbHRlcik9PW51bGx8fHQuc2V0RmxpY2tlcmluZ09wdGlvbnMoZSksdGhpcy5yZXBvcnQoe3ZhcmlhdGlvbjoiVXBkYXRlIn0pfWFzeW5jIHByb2ZpbGUoZSl7dmFyIHQsbjtyZXR1cm4obj0odD10aGlzLmJhY2tncm91bmRGaWx0ZXIpPT1udWxsP3ZvaWQgMDp0LnByb2ZpbGUoZSkpIT1udWxsP246W119Z2V0VHJhbnNmb3JtZXJUeXBlKCl7dmFyIGUsdDtyZXR1cm4odD0oZT10aGlzLmJhY2tncm91bmRPcHRpb25zKT09bnVsbD92b2lkIDA6ZS50cmFuc2Zvcm1lclR5cGUpIT1udWxsP3Q6IlVuZGVmaW5lZCJ9cmVwb3J0KGUpe3ZhciB0O3RoaXMucmVwb3J0ZXIuc2VuZCh7dmVyc2lvbjpGbyxhY3Rpb246Ik1sVHJhbnNmb3JtZXJzIix0cmFuc2Zvcm1lclR5cGU6KHQ9dGhpcy5iYWNrZ3JvdW5kT3B0aW9ucyk9PW51bGw/dm9pZCAwOnQudHJhbnNmb3JtZXJUeXBlLGNvbmZpZzpKU09OLnN0cmluZ2lmeSh0aGlzLmJhY2tncm91bmRPcHRpb25zKSwuLi5lfSl9fWNvbnN0IHZyPWNsYXNze2NvbnN0cnVjdG9yKCl7cCh0aGlzLCJiYWNrZ3JvdW5kVHJhbnNmb3JtZXIiLG5ldyBiZik7cCh0aGlzLCJtZWRpYVByb2Nlc3NvciIsbmV3IG5vKTtwKHRoaXMsInJhdGUiLDMwKTtwKHRoaXMsInJlc29sdmVPbk1lZGlhUHJvY2Vzc29yIik7cCh0aGlzLCJldmVudHNRdWV1ZSIsW10pfWFzeW5jIGluaXQoZSx0KXthd2FpdCB0aGlzLmJhY2tncm91bmRUcmFuc2Zvcm1lci5pbml0KGUsdCksYXdhaXQgdGhpcy5tZWRpYVByb2Nlc3Nvci5zZXRUcmFuc2Zvcm1lcnMoW3RoaXMuYmFja2dyb3VuZFRyYW5zZm9ybWVyXSksdGhpcy5tZWRpYVByb2Nlc3Nvci5zZXRUcmFja0V4cGVjdGVkUmF0ZSh0aGlzLnJhdGUpLHRoaXMubWVkaWFQcm9jZXNzb3Iub25BbnkoKG4saSk9Pnt0aGlzLnJlc29sdmVPbk1lZGlhUHJvY2Vzc29yPyh0aGlzLnJlc29sdmVPbk1lZGlhUHJvY2Vzc29yKHtuYW1lOm4sZGF0YTppfSksdGhpcy5yZXNvbHZlT25NZWRpYVByb2Nlc3Nvcj12b2lkIDApOnRoaXMuZXZlbnRzUXVldWUucHVzaCh7bmFtZTpuLGRhdGE6aX0pfSl9YXN5bmMgb25NZWRpYVByb2Nlc3NvckV2ZW50KCl7cmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKGU9Pnt0aGlzLmV2ZW50c1F1ZXVlLmxlbmd0aD4wP2UodGhpcy5ldmVudHNRdWV1ZS5zaGlmdCgpKTp0aGlzLnJlc29sdmVPbk1lZGlhUHJvY2Vzc29yPWV9KX1hc3luYyBzZXRUcmFja0V4cGVjdGVkUmF0ZShlKXt0aGlzLnJhdGU9ZSx0aGlzLm1lZGlhUHJvY2Vzc29yLnNldFRyYWNrRXhwZWN0ZWRSYXRlKGUpfWFzeW5jIHRyYW5zZm9ybShlLHQpe3RoaXMubWVkaWFQcm9jZXNzb3IudHJhbnNmb3JtKGUsdCl9YXN5bmMgc2V0QmFja2dyb3VuZE9wdGlvbnMoZSl7dmFyIHQ7YXdhaXQoKHQ9dGhpcy5iYWNrZ3JvdW5kVHJhbnNmb3JtZXIpPT1udWxsP3ZvaWQgMDp0LnNldEJhY2tncm91bmRPcHRpb25zKGUpKX1zZXRWaWRlb0JHUmVhZGFibGUoZSl7dGhpcy5iYWNrZ3JvdW5kVHJhbnNmb3JtZXIuc2V0VmlkZW9CR1JlYWRhYmxlKGUpfWFzeW5jIHNldFZpcnR1YWxCR0ltYWdlKGUpe2F3YWl0IHRoaXMuYmFja2dyb3VuZFRyYW5zZm9ybWVyLnNldFZpcnR1YWxCR0ltYWdlKGUpfWFzeW5jIHRlcm1pbmF0ZSgpe2F3YWl0IHRoaXMubWVkaWFQcm9jZXNzb3IuZGVzdHJveSgpfXNldEZsaWNrZXJpbmdPcHRpb25zKGUpe3RoaXMuYmFja2dyb3VuZFRyYW5zZm9ybWVyLnNldEZsaWNrZXJpbmdPcHRpb25zKGUpfXNldFZvbmFnZU1ldGFkYXRhKGUpe3FpKGUpfWFzeW5jIHByb2ZpbGUoZSl7cmV0dXJuIEpTT04uc3RyaW5naWZ5KGF3YWl0IHRoaXMuYmFja2dyb3VuZFRyYW5zZm9ybWVyLnByb2ZpbGUoZSkpfX07bGV0IG9pPXZyOygoKT0+e19pKCJQcm9jZXNzb3JXb3JrZXIiLHZyKX0pKCl9KSgpOwo=",Ml=typeof window<"u"&&window.Blob&&new Blob([atob(Al)],{type:"text/javascript;charset=utf-8"});function n3(){const i=Ml&&(window.URL||window.webkitURL).createObjectURL(Ml);try{return i?new Worker(i):new Worker("data:application/javascript;base64,"+Al)}finally{i&&(window.URL||window.webkitURL).revokeObjectURL(i)}}const Qo=class extends cr{constructor(){super(...arguments);Wt(this,"rate",30);Wt(this,"worker")}async init(r){this.worker=await B2(zo,n3),await this.worker.init(`worker_${Qo.initCount++}`,r),await this.worker.setVonageMetadata(li()),await this.setBackgroundOptions(r),this.listenWorker()}async setTrackExpectedRate(r){var p;await((p=this.worker)==null?void 0:p.setTrackExpectedRate(r))}async setBackgroundOptions(r){var G,S,H;const{transformerType:p}=r;switch(p){case"VideoBackground":await((G=this.worker)==null?void 0:G.setVideoBGReadable(await ys.createVideoReadable(r.backgroundAssetUri)));break;case"VirtualBackground":await((S=this.worker)==null?void 0:S.setVirtualBGImage(await ys.createImageCanvas(r.backgroundAssetUri)));break}await((H=this.worker)==null?void 0:H.setBackgroundOptions(r))}async transform(r,p){var G;await((G=this.worker)==null?void 0:G.transform(r,p))}async destroy(){var r;await((r=this.worker)==null?void 0:r.terminate())}async setFlickeringOptions(r){var p;await((p=this.worker)==null?void 0:p.setFlickeringOptions(r))}async profile(r){var G;const p=await((G=this.worker)==null?void 0:G.profile(r));return JSON.parse(p!=null?p:"[]")}async listenWorker(){var r,p,G;for(;(r=this.worker)!=null&&r.workerContext.worker;){const{name:S,data:H}=await((p=this.worker)==null?void 0:p.onMediaProcessorEvent());switch(S){case"error":case"warn":this.emit(S,H);break;case"pipelineInfo":switch(this.emit(S,H),H){case"pipeline_ended":case"pipeline_ended_with_error":await((G=this.worker)==null?void 0:G.terminate());return}break}}}};let Qi=Qo;Wt(Qi,"initCount",0);class r3{constructor(n){this.queries=n}async downloadSpeedscope(){this.download(await this.convertToSpeedscope())}download(n){const r=document.createElement("a");r.href=URL.createObjectURL(new Blob([n],{type:"application/json"})),r.download=`profile-${+new Date}.speedscope.json`,document.body.appendChild(r),r.click(),document.body.removeChild(r)}convertToSpeedscope(){const n=[],r={},p=[];let G=0;for(const H of this.queries){const w=[];for(const E of H)r[E.name]===void 0&&(r[E.name]=n.length,n.push({name:E.name})),w.push({type:E.action==Ws.PUSH?"O":"C",frame:r[E.name],at:E.timestamp}),G=Math.max(G,E.timestamp+E.duration);p.push({events:w,type:"evented",name:"GPU Profile",unit:"nanoseconds",startValue:0,endValue:G})}const S={$schema:"https://www.speedscope.app/file-format-schema.json",shared:{frames:n},profiles:p};return JSON.stringify(S,null,2)}}class Po extends cr{constructor(){super();Wt(this,"worker",new Qi);Wt(this,"connector",new x2(this.worker))}async init(r){await this.worker.init(r),this.worker.onAny((p,G)=>this.emit(p,G))}async setBackgroundOptions(r){await this.worker.setBackgroundOptions(r)}setTrackExpectedRate(r){this.worker.setTrackExpectedRate(r)}getConnector(){return this.connector}async profile(r){return this.worker.profile(r)}static async profile(r){const p=await Promise.all(this.instances.map(G=>G.profile(r)));return new r3(p)}static async create(r){const p=new this;return await p.init(r),this.instances.push(p),p}}Wt(Po,"instances",[]);function i3(){return ai}function o3(){return di}function s3(){return hi}function l3(){return fi}function c3(){return mi}function u3(){return pi}function a3(){return bi}async function d3(i){return await Po.create(i)}Ae.BackgroundTransformer=Bl,Ae.BackgroundTransformerType=ls,Ae.BlurRadius=Ar,Ae.ErrorFunction=ss,Ae.MediapipeHelper=yi,Ae.PipelineInfoData=ui,Ae.SelfieSegmentationType=cs,Ae.VonageMediaProcessor=Po,Ae.WarningType=os,Ae.createVonageMediaProcessor=d3,Ae.getSupportedBrowserFeatures=as,Ae.getVonageFaceDetection=l3,Ae.getVonageFaceMash=c3,Ae.getVonageHands=o3,Ae.getVonageHolistic=s3,Ae.getVonageObjectron=u3,Ae.getVonagePose=a3,Ae.getVonageSelfieSegmentation=i3,Ae.isSupported=L2,Object.defineProperties(Ae,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
|
|
457
|
+
`;class $0 extends Ir{getFragmentShader(){return Q0}getVertexShader(){return D0}}class q0 extends Mo{constructor(r,p,G){super();Wt(this,"inputImage");this.context=r;const S={context:r,height:G,width:p};this.addStep({program:new $0({...S,disableFramebuffer:!0}),getUniforms:()=>({texture:mn(r,this.inputImage),invert_y:!0})})}setData(r){this.inputImage=r}}class t3{constructor(n){Wt(this,"resize");Wt(this,"canvas");Wt(this,"context");this.canvas=new OffscreenCanvas(0,0),this.context=this.canvas.getContext("webgl2"),this.canvas.width=n.width,this.canvas.height=n.height,this.resize=new q0(this.context,n.width,n.height)}resizeForeground(n,r){this.canvas.width=n,this.canvas.height=r,this.resize.resizeOutput(n,r)}async process(n){var r,p;return this.canvas.width=this.canvas.width,(r=this.resize)==null||r.setData(n),(p=this.resize)==null||p.run(),this.canvas}}class e3{constructor(n,r){Wt(this,"improveMaskSegmentation");Wt(this,"backgroundResizer");Wt(this,"backgroundImage");Wt(this,"backgroundVideo");Wt(this,"profiler");Wt(this,"activePipeline");Wt(this,"canvas");Wt(this,"options");Wt(this,"context");Wt(this,"virtualBGImage");this.id=n,this.canvas=new OffscreenCanvas(0,0),this.context=this.canvas.getContext("webgl2"),this.canvas.width=r.foregroundWidth,this.canvas.height=r.foregroundHeight,this.improveMaskSegmentation=new _0(this.context,r.maskWidth,r.maskHeight),this.backgroundImage=new kl(this.context),this.backgroundVideo=new w0(this.context),this.backgroundResizer=new t3({width:r.foregroundWidth,height:r.foregroundHeight})}setBackgroundOptions(n){switch(n.transformerType){case"BackgroundBlur":this.activePipeline=new T0(this.context,this.getBlurSize(n.radius));break;case"SilhouetteBlur":this.activePipeline=new L0(this.context,this.getBlurSize(n.radius));break;case"VideoBackground":this.activePipeline=this.backgroundVideo;break;case"VirtualBackground":this.activePipeline=this.backgroundImage;break;default:throw`Unknown transformer type [${n.transformerType}]`}this.options=n}setFlickeringOptions(n){var r;(r=this.improveMaskSegmentation)==null||r.setOptions(n)}setVideoBGReadable(n){this.backgroundVideo.inputVideo=n}async setVirtualBGImage(n){this.virtualBGImage=n,this.backgroundImage.inputBackgroundImage=await this.backgroundResizer.process(n)}async process(n,r){var p,G,S,H,w,E,et;if(this.activePipeline&&n.width&&(r==null?void 0:r.width)){const ct=`[${this.id}] background-filter`;(p=this.profiler)==null||p.pushContext(ct);let dt=r;(((G=this.options)==null?void 0:G.selfieSegmentationType)&&((S=this.options)==null?void 0:S.selfieSegmentationType)==="PRECISE"||!((H=this.options)!=null&&H.selfieSegmentationType)&&this.activePipeline.preciseMaskEnabled)&&(this.improveMaskSegmentation.setId(this.id),this.improveMaskSegmentation.setProfiler(this.profiler),this.improveMaskSegmentation.setData(n,r),this.improveMaskSegmentation.run(),dt=this.improveMaskSegmentation.output),this.activePipeline.setId(this.id),this.activePipeline.setProfiler(this.profiler),(w=this.activePipeline)==null||w.setData(n,dt),(E=this.activePipeline)==null||E.run(),(et=this.profiler)==null||et.popContext(ct)}}async resizeForeground(n,r){var p;this.canvas.width=n,this.canvas.height=r,this.backgroundImage.resizeOutput(n,r),this.backgroundVideo.resizeOutput(n,r),this.backgroundResizer.resizeForeground(n,r),(p=this.activePipeline)==null||p.resizeOutput(n,r),this.virtualBGImage&&(this.backgroundImage.inputBackgroundImage=await this.backgroundResizer.process(this.virtualBGImage))}async profile(n){const r=new Z1(this.context);return this.profiler=r,r.start(),await Xs(n),this.profiler=void 0,r.stop(),r.getResolvedQueries()}getBlurSize(n=Ar.Low){switch(n){case Ar.Low:return 5;case Ar.High:return 12}return n}}class Bl{constructor(){Wt(this,"selfieSegmentation",new us);Wt(this,"backgroundFilter");Wt(this,"reporter",new y1);Wt(this,"previousDimensions",{width:0,height:0});Wt(this,"backgroundOptions")}async init(n,r){await this.selfieSegmentation.init(r.wasmAssetUriPath,r.tfliteAssetUriPath);const{width:p,height:G}=this.selfieSegmentation.getOutputDimensions();this.backgroundFilter=new e3(n,{foregroundWidth:1,foregroundHeight:1,maskWidth:p,maskHeight:G}),this.report({variation:"Create"})}async transform(n,r){var H,w,E,et;const p=(H=n.timestamp)!=null?H:0,G=await createImageBitmap(n),S=await this.selfieSegmentation.process(G);S?((G.width!==this.previousDimensions.width||G.height!==this.previousDimensions.height)&&(this.previousDimensions.width=G.width,this.previousDimensions.height=G.height,await((w=this.backgroundFilter)==null?void 0:w.resizeForeground(G.width,G.height))),await((E=this.backgroundFilter)==null?void 0:E.process(G,S)),n.close(),r.enqueue(new VideoFrame((et=this.backgroundFilter)==null?void 0:et.canvas,{timestamp:p,alpha:"discard"}))):r.enqueue(n)}async setBackgroundOptions(n){var r;this.backgroundOptions=n,await((r=this.backgroundFilter)==null?void 0:r.setBackgroundOptions(n)),this.report({variation:"Update"})}async setVideoBGReadable(n){var r;await((r=this.backgroundFilter)==null?void 0:r.setVideoBGReadable(n))}async setVirtualBGImage(n){var r;await((r=this.backgroundFilter)==null?void 0:r.setVirtualBGImage(n))}setFlickeringOptions(n){var r;(r=this.backgroundFilter)==null||r.setFlickeringOptions(n),this.report({variation:"Update"})}async profile(n){var r,p;return(p=(r=this.backgroundFilter)==null?void 0:r.profile(n))!=null?p:[]}getTransformerType(){var n,r;return(r=(n=this.backgroundOptions)==null?void 0:n.transformerType)!=null?r:"Undefined"}report(n){var r;this.reporter.send({version:g1,action:"MlTransformers",transformerType:(r=this.backgroundOptions)==null?void 0:r.transformerType,config:JSON.stringify(this.backgroundOptions),...n})}}const _o=class{constructor(){Wt(this,"backgroundTransformer",new Bl);Wt(this,"mediaProcessor",new V2);Wt(this,"rate",30);Wt(this,"resolveOnMediaProcessor");Wt(this,"eventsQueue",[])}async init(n,r){await this.backgroundTransformer.init(n,r),await this.mediaProcessor.setTransformers([this.backgroundTransformer]),this.mediaProcessor.setTrackExpectedRate(this.rate),this.mediaProcessor.onAny((p,G)=>{this.resolveOnMediaProcessor?(this.resolveOnMediaProcessor({name:p,data:G}),this.resolveOnMediaProcessor=void 0):this.eventsQueue.push({name:p,data:G})})}async onMediaProcessorEvent(){return await new Promise(n=>{this.eventsQueue.length>0?n(this.eventsQueue.shift()):this.resolveOnMediaProcessor=n})}async setTrackExpectedRate(n){this.rate=n,this.mediaProcessor.setTrackExpectedRate(n)}async transform(n,r){this.mediaProcessor.transform(n,r)}async setBackgroundOptions(n){var r;await((r=this.backgroundTransformer)==null?void 0:r.setBackgroundOptions(n))}setVideoBGReadable(n){this.backgroundTransformer.setVideoBGReadable(n)}async setVirtualBGImage(n){await this.backgroundTransformer.setVirtualBGImage(n)}async terminate(){await this.mediaProcessor.destroy()}setFlickeringOptions(n){this.backgroundTransformer.setFlickeringOptions(n)}setVonageMetadata(n){g2(n)}async profile(n){return JSON.stringify(await this.backgroundTransformer.profile(n))}};let zo=_o;(()=>{M2("ProcessorWorker",_o)})();const Al="dmFyIGlsPU9iamVjdC5kZWZpbmVQcm9wZXJ0eTt2YXIgb2w9KHEsWCx6KT0+WCBpbiBxP2lsKHEsWCx7ZW51bWVyYWJsZTohMCxjb25maWd1cmFibGU6ITAsd3JpdGFibGU6ITAsdmFsdWU6en0pOnFbWF09ejt2YXIgcD0ocSxYLHopPT4ob2wocSx0eXBlb2YgWCE9InN5bWJvbCI/WCsiIjpYLHopLHopOyhmdW5jdGlvbigpeyJ1c2Ugc3RyaWN0IjtmdW5jdGlvbiBxKHIsZSl7cmV0dXJuIGdsb2JhbFRoaXNbcl18fChnbG9iYWxUaGlzW3JdPWUpLGdsb2JhbFRoaXNbcl19Y29uc3QgWD1xKCJnbG9iYWxzIix7fSk7dmFyIHo9KHI9PihyLklOSVQ9IklOSVQiLHIuRk9SV0FSRD0iRk9SV0FSRCIsci5URVJNSU5BVEU9IlRFUk1JTkFURSIsci5HTE9CQUxTX1NZTkM9IkdMT0JBTFNfU1lOQyIscikpKHp8fHt9KTtmdW5jdGlvbiBwaShyKXtyZXR1cm5bSW1hZ2VCaXRtYXAsUmVhZGFibGVTdHJlYW0sV3JpdGFibGVTdHJlYW1dLnNvbWUoZT0+ciBpbnN0YW5jZW9mIGUpfWZ1bmN0aW9uIHplKHIsZSl7Y29uc3R7aWQ6dCx0eXBlOm59PXIsaT1BcnJheS5pc0FycmF5KGUpP2U6W2VdO3Bvc3RNZXNzYWdlKHtpZDp0LHR5cGU6bixyZXN1bHQ6ZX0saS5maWx0ZXIobz0+cGkobykpKX1xKCJ3b3JrZXJpemVkIix7fSk7ZnVuY3Rpb24gU3IoKXtyZXR1cm4gdHlwZW9mIFdvcmtlckdsb2JhbFNjb3BlPCJ1IiYmc2VsZiBpbnN0YW5jZW9mIFdvcmtlckdsb2JhbFNjb3BlfWZ1bmN0aW9uIFdlKHIsZSl7aWYoQXJyYXkuaXNBcnJheShlKSllLnNwbGljZSgwLGUubGVuZ3RoKTtlbHNlIGlmKHR5cGVvZiBlPT0ib2JqZWN0Iilmb3IoY29uc3QgdCBpbiBlKWRlbGV0ZSBlW3RdO2Zvcihjb25zdCB0IGluIHIpQXJyYXkuaXNBcnJheShyW3RdKT8oZVt0XT1bXSxXZShyW3RdLGVbdF0pKTp0eXBlb2Ygclt0XT09Im9iamVjdCI/KGVbdF09e30sV2Uoclt0XSxlW3RdKSk6ZVt0XT1yW3RdfWFzeW5jIGZ1bmN0aW9uIHlpKHIsZSl7Y29uc3R7ZnVuY3Rpb25OYW1lOnQsYXJnczpufT1yO2lmKCFlLmluc3RhbmNlKXRocm93Imluc3RhbmNlIG5vdCBpbml0aWFsaXplZCI7aWYoIXQpdGhyb3cibWlzc2luZyBmdW5jdGlvbiBuYW1lIHRvIGNhbGwiO2lmKCFlLmluc3RhbmNlW3RdKXRocm93YHVuZGVmaW5lZCBmdW5jdGlvbiBbJHt0fV0gaW4gY2xhc3MgJHtlLmluc3RhbmNlLmNvbnN0cnVjdG9yLndvcmtlcklkfWA7emUocixhd2FpdCBlLmluc3RhbmNlW3RdKC4uLm4hPW51bGw/bjpbXSkpfWNvbnN0IFJyPXEoInJlZ2lzdGVyZWRXb3JrZXJzIix7fSk7ZnVuY3Rpb24gX2kocixlKXtlLndvcmtlcklkPXIsU3IoKSYmKFJyW2Uud29ya2VySWRdPWUpfWZ1bmN0aW9uIHhpKHIsZSl7aWYoIXIuYXJncyl0aHJvdyJNaXNzaW5nIGNsYXNzTmFtZSB3aGlsZSBpbml0aWFsaXppbmcgd29ya2VyIjtjb25zdFt0LG5dPXIuYXJncyxpPVJyW3RdO2lmKGkpZS5pbnN0YW5jZT1uZXcgaShyLmFyZ3Muc2xpY2UoMSkpO2Vsc2UgdGhyb3dgdW5rbm93biB3b3JrZXIgY2xhc3MgJHt0fWA7V2UobixYKSx6ZShyLHR5cGVvZiBlLmluc3RhbmNlIT09dm9pZCAwKX1hc3luYyBmdW5jdGlvbiBnaShyLGUpe2NvbnN0e2FyZ3M6dH09cjtpZighZS5pbnN0YW5jZSl0aHJvdyJpbnN0YW5jZSBub3QgaW5pdGlhbGl6ZWQiO2xldCBuO2UuaW5zdGFuY2UudGVybWluYXRlJiYobj1hd2FpdCBlLmluc3RhbmNlLnRlcm1pbmF0ZSguLi50IT1udWxsP3Q6W10pKSx6ZShyLG4pfWZ1bmN0aW9uIGJpKHIpe2lmKCFyLmFyZ3MpdGhyb3ciTWlzc2luZyBnbG9iYWxzIHdoaWxlIHN5bmNpbmciO1dlKHIuYXJnc1swXSxYKSx6ZShyLHt9KX1mdW5jdGlvbiB2aSgpe2NvbnN0IHI9e307b25tZXNzYWdlPWFzeW5jIGU9Pntjb25zdCB0PWUuZGF0YTtzd2l0Y2godC50eXBlKXtjYXNlIHouSU5JVDp4aSh0LHIpO2JyZWFrO2Nhc2Ugei5GT1JXQVJEOnlpKHQscik7YnJlYWs7Y2FzZSB6LlRFUk1JTkFURTpnaSh0LHIpO2JyZWFrO2Nhc2Ugei5HTE9CQUxTX1NZTkM6YmkodCk7YnJlYWt9fX1TcigpJiZ2aSgpO3ZhciBFaT1PYmplY3QuZGVmaW5lUHJvcGVydHksVGk9KHIsZSx0KT0+ZSBpbiByP0VpKHIsZSx7ZW51bWVyYWJsZTohMCxjb25maWd1cmFibGU6ITAsd3JpdGFibGU6ITAsdmFsdWU6dH0pOnJbZV09dCxBPShyLGUsdCk9PihUaShyLHR5cGVvZiBlIT0ic3ltYm9sIj9lKyIiOmUsdCksdCk7Y2xhc3MgSnt9QShKLCJ1cGRhdGVzIix7dHJhbnNmb3JtZXJfbmV3OiJOZXcgdHJhbnNmb3JtZXIiLHRyYW5zZm9ybWVyX251bGw6Ik51bGwgdHJhbnNmb3JtZXIifSksQShKLCJlcnJvcnMiLHt0cmFuc2Zvcm1lcl9ub25lOiJObyB0cmFuc2Zvcm1lcnMgcHJvdmlkZWQiLHRyYW5zZm9ybWVyX3N0YXJ0OiJDYW5ub3Qgc3RhcnQgdHJhbnNmb3JtZXIiLHRyYW5zZm9ybWVyX3RyYW5zZm9ybToiQ2Fubm90IHRyYW5zZm9ybSBmcmFtZSIsdHJhbnNmb3JtZXJfZmx1c2g6IkNhbm5vdCBmbHVzaCB0cmFuc2Zvcm1lciIscmVhZGFibGVfbnVsbDoiUmVhZGFibGUgaXMgbnVsbCIsd3JpdGFibGVfbnVsbDoiV3JpdGFibGUgaXMgbnVsbCJ9KTtjb25zdCBlZT1uZXcgV2Vha01hcCxWZT1uZXcgV2Vha01hcCxSZT1uZXcgV2Vha01hcCxSdD1TeW1ib2woImFueVByb2R1Y2VyIiksSXI9UHJvbWlzZS5yZXNvbHZlKCksSGU9U3ltYm9sKCJsaXN0ZW5lckFkZGVkIiksWWU9U3ltYm9sKCJsaXN0ZW5lclJlbW92ZWQiKTtsZXQgSXQ9ITE7ZnVuY3Rpb24gYmUocil7aWYodHlwZW9mIHIhPSJzdHJpbmciJiZ0eXBlb2YgciE9InN5bWJvbCIpdGhyb3cgbmV3IFR5cGVFcnJvcigiZXZlbnROYW1lIG11c3QgYmUgYSBzdHJpbmcgb3IgYSBzeW1ib2wiKX1mdW5jdGlvbiBqZShyKXtpZih0eXBlb2YgciE9ImZ1bmN0aW9uIil0aHJvdyBuZXcgVHlwZUVycm9yKCJsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb24iKX1mdW5jdGlvbiB2ZShyLGUpe2NvbnN0IHQ9VmUuZ2V0KHIpO3JldHVybiB0LmhhcyhlKXx8dC5zZXQoZSxuZXcgU2V0KSx0LmdldChlKX1mdW5jdGlvbiBJZShyLGUpe2NvbnN0IHQ9dHlwZW9mIGU9PSJzdHJpbmcifHx0eXBlb2YgZT09InN5bWJvbCI/ZTpSdCxuPVJlLmdldChyKTtyZXR1cm4gbi5oYXModCl8fG4uc2V0KHQsbmV3IFNldCksbi5nZXQodCl9ZnVuY3Rpb24gQWkocixlLHQpe2NvbnN0IG49UmUuZ2V0KHIpO2lmKG4uaGFzKGUpKWZvcihjb25zdCBpIG9mIG4uZ2V0KGUpKWkuZW5xdWV1ZSh0KTtpZihuLmhhcyhSdCkpe2NvbnN0IGk9UHJvbWlzZS5hbGwoW2UsdF0pO2Zvcihjb25zdCBvIG9mIG4uZ2V0KFJ0KSlvLmVucXVldWUoaSl9fWZ1bmN0aW9uIEZyKHIsZSl7ZT1BcnJheS5pc0FycmF5KGUpP2U6W2VdO2xldCB0PSExLG49KCk9Pnt9LGk9W107Y29uc3Qgbz17ZW5xdWV1ZShzKXtpLnB1c2gocyksbigpfSxmaW5pc2goKXt0PSEwLG4oKX19O2Zvcihjb25zdCBzIG9mIGUpSWUocixzKS5hZGQobyk7cmV0dXJue2FzeW5jIG5leHQoKXtyZXR1cm4gaT9pLmxlbmd0aD09PTA/dD8oaT12b2lkIDAsdGhpcy5uZXh0KCkpOihhd2FpdCBuZXcgUHJvbWlzZShzPT57bj1zfSksdGhpcy5uZXh0KCkpOntkb25lOiExLHZhbHVlOmF3YWl0IGkuc2hpZnQoKX06e2RvbmU6ITB9fSxhc3luYyByZXR1cm4ocyl7aT12b2lkIDA7Zm9yKGNvbnN0IGEgb2YgZSlJZShyLGEpLmRlbGV0ZShvKTtyZXR1cm4gbigpLGFyZ3VtZW50cy5sZW5ndGg+MD97ZG9uZTohMCx2YWx1ZTphd2FpdCBzfTp7ZG9uZTohMH19LFtTeW1ib2wuYXN5bmNJdGVyYXRvcl0oKXtyZXR1cm4gdGhpc319fWZ1bmN0aW9uIFByKHIpe2lmKHI9PT12b2lkIDApcmV0dXJuIERyO2lmKCFBcnJheS5pc0FycmF5KHIpKXRocm93IG5ldyBUeXBlRXJyb3IoImBtZXRob2ROYW1lc2AgbXVzdCBiZSBhbiBhcnJheSBvZiBzdHJpbmdzIik7Zm9yKGNvbnN0IGUgb2YgcilpZighRHIuaW5jbHVkZXMoZSkpdGhyb3cgdHlwZW9mIGUhPSJzdHJpbmciP25ldyBUeXBlRXJyb3IoImBtZXRob2ROYW1lc2AgZWxlbWVudCBtdXN0IGJlIGEgc3RyaW5nIik6bmV3IEVycm9yKGAke2V9IGlzIG5vdCBFbWl0dGVyeSBtZXRob2RgKTtyZXR1cm4gcn1jb25zdCBGdD1yPT5yPT09SGV8fHI9PT1ZZTtjbGFzcyBmZXtzdGF0aWMgbWl4aW4oZSx0KXtyZXR1cm4gdD1Qcih0KSxuPT57aWYodHlwZW9mIG4hPSJmdW5jdGlvbiIpdGhyb3cgbmV3IFR5cGVFcnJvcigiYHRhcmdldGAgbXVzdCBiZSBmdW5jdGlvbiIpO2Zvcihjb25zdCBzIG9mIHQpaWYobi5wcm90b3R5cGVbc10hPT12b2lkIDApdGhyb3cgbmV3IEVycm9yKGBUaGUgcHJvcGVydHkgXGAke3N9XGAgYWxyZWFkeSBleGlzdHMgb24gXGB0YXJnZXRcYGApO2Z1bmN0aW9uIGkoKXtyZXR1cm4gT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsZSx7ZW51bWVyYWJsZTohMSx2YWx1ZTpuZXcgZmV9KSx0aGlzW2VdfU9iamVjdC5kZWZpbmVQcm9wZXJ0eShuLnByb3RvdHlwZSxlLHtlbnVtZXJhYmxlOiExLGdldDppfSk7Y29uc3Qgbz1zPT5mdW5jdGlvbiguLi5hKXtyZXR1cm4gdGhpc1tlXVtzXSguLi5hKX07Zm9yKGNvbnN0IHMgb2YgdClPYmplY3QuZGVmaW5lUHJvcGVydHkobi5wcm90b3R5cGUscyx7ZW51bWVyYWJsZTohMSx2YWx1ZTpvKHMpfSk7cmV0dXJuIG59fXN0YXRpYyBnZXQgaXNEZWJ1Z0VuYWJsZWQoKXtpZih0eXBlb2YgcHJvY2VzcyE9Im9iamVjdCIpcmV0dXJuIEl0O2NvbnN0e2VudjplfT1wcm9jZXNzfHx7ZW52Ont9fTtyZXR1cm4gZS5ERUJVRz09PSJlbWl0dGVyeSJ8fGUuREVCVUc9PT0iKiJ8fEl0fXN0YXRpYyBzZXQgaXNEZWJ1Z0VuYWJsZWQoZSl7SXQ9ZX1jb25zdHJ1Y3RvcihlPXt9KXtlZS5zZXQodGhpcyxuZXcgU2V0KSxWZS5zZXQodGhpcyxuZXcgTWFwKSxSZS5zZXQodGhpcyxuZXcgTWFwKSx0aGlzLmRlYnVnPWUuZGVidWd8fHt9LHRoaXMuZGVidWcuZW5hYmxlZD09PXZvaWQgMCYmKHRoaXMuZGVidWcuZW5hYmxlZD0hMSksdGhpcy5kZWJ1Zy5sb2dnZXJ8fCh0aGlzLmRlYnVnLmxvZ2dlcj0odCxuLGksbyk9Pnt0cnl7bz1KU09OLnN0cmluZ2lmeShvKX1jYXRjaHtvPWBPYmplY3Qgd2l0aCB0aGUgZm9sbG93aW5nIGtleXMgZmFpbGVkIHRvIHN0cmluZ2lmeTogJHtPYmplY3Qua2V5cyhvKS5qb2luKCIsIil9YH10eXBlb2YgaT09InN5bWJvbCImJihpPWkudG9TdHJpbmcoKSk7Y29uc3Qgcz1uZXcgRGF0ZSxhPWAke3MuZ2V0SG91cnMoKX06JHtzLmdldE1pbnV0ZXMoKX06JHtzLmdldFNlY29uZHMoKX0uJHtzLmdldE1pbGxpc2Vjb25kcygpfWA7Y29uc29sZS5sb2coYFske2F9XVtlbWl0dGVyeToke3R9XVske259XSBFdmVudCBOYW1lOiAke2l9CglkYXRhOiAke299YCl9KX1sb2dJZkRlYnVnRW5hYmxlZChlLHQsbil7KGZlLmlzRGVidWdFbmFibGVkfHx0aGlzLmRlYnVnLmVuYWJsZWQpJiZ0aGlzLmRlYnVnLmxvZ2dlcihlLHRoaXMuZGVidWcubmFtZSx0LG4pfW9uKGUsdCl7amUodCksZT1BcnJheS5pc0FycmF5KGUpP2U6W2VdO2Zvcihjb25zdCBuIG9mIGUpYmUobiksdmUodGhpcyxuKS5hZGQodCksdGhpcy5sb2dJZkRlYnVnRW5hYmxlZCgic3Vic2NyaWJlIixuLHZvaWQgMCksRnQobil8fHRoaXMuZW1pdChIZSx7ZXZlbnROYW1lOm4sbGlzdGVuZXI6dH0pO3JldHVybiB0aGlzLm9mZi5iaW5kKHRoaXMsZSx0KX1vZmYoZSx0KXtqZSh0KSxlPUFycmF5LmlzQXJyYXkoZSk/ZTpbZV07Zm9yKGNvbnN0IG4gb2YgZSliZShuKSx2ZSh0aGlzLG4pLmRlbGV0ZSh0KSx0aGlzLmxvZ0lmRGVidWdFbmFibGVkKCJ1bnN1YnNjcmliZSIsbix2b2lkIDApLEZ0KG4pfHx0aGlzLmVtaXQoWWUse2V2ZW50TmFtZTpuLGxpc3RlbmVyOnR9KX1vbmNlKGUpe3JldHVybiBuZXcgUHJvbWlzZSh0PT57Y29uc3Qgbj10aGlzLm9uKGUsaT0+e24oKSx0KGkpfSl9KX1ldmVudHMoZSl7ZT1BcnJheS5pc0FycmF5KGUpP2U6W2VdO2Zvcihjb25zdCB0IG9mIGUpYmUodCk7cmV0dXJuIEZyKHRoaXMsZSl9YXN5bmMgZW1pdChlLHQpe2JlKGUpLHRoaXMubG9nSWZEZWJ1Z0VuYWJsZWQoImVtaXQiLGUsdCksQWkodGhpcyxlLHQpO2NvbnN0IG49dmUodGhpcyxlKSxpPWVlLmdldCh0aGlzKSxvPVsuLi5uXSxzPUZ0KGUpP1tdOlsuLi5pXTthd2FpdCBJcixhd2FpdCBQcm9taXNlLmFsbChbLi4uby5tYXAoYXN5bmMgYT0+e2lmKG4uaGFzKGEpKXJldHVybiBhKHQpfSksLi4ucy5tYXAoYXN5bmMgYT0+e2lmKGkuaGFzKGEpKXJldHVybiBhKGUsdCl9KV0pfWFzeW5jIGVtaXRTZXJpYWwoZSx0KXtiZShlKSx0aGlzLmxvZ0lmRGVidWdFbmFibGVkKCJlbWl0U2VyaWFsIixlLHQpO2NvbnN0IG49dmUodGhpcyxlKSxpPWVlLmdldCh0aGlzKSxvPVsuLi5uXSxzPVsuLi5pXTthd2FpdCBJcjtmb3IoY29uc3QgYSBvZiBvKW4uaGFzKGEpJiZhd2FpdCBhKHQpO2Zvcihjb25zdCBhIG9mIHMpaS5oYXMoYSkmJmF3YWl0IGEoZSx0KX1vbkFueShlKXtyZXR1cm4gamUoZSksdGhpcy5sb2dJZkRlYnVnRW5hYmxlZCgic3Vic2NyaWJlQW55Iix2b2lkIDAsdm9pZCAwKSxlZS5nZXQodGhpcykuYWRkKGUpLHRoaXMuZW1pdChIZSx7bGlzdGVuZXI6ZX0pLHRoaXMub2ZmQW55LmJpbmQodGhpcyxlKX1hbnlFdmVudCgpe3JldHVybiBGcih0aGlzKX1vZmZBbnkoZSl7amUoZSksdGhpcy5sb2dJZkRlYnVnRW5hYmxlZCgidW5zdWJzY3JpYmVBbnkiLHZvaWQgMCx2b2lkIDApLHRoaXMuZW1pdChZZSx7bGlzdGVuZXI6ZX0pLGVlLmdldCh0aGlzKS5kZWxldGUoZSl9Y2xlYXJMaXN0ZW5lcnMoZSl7ZT1BcnJheS5pc0FycmF5KGUpP2U6W2VdO2Zvcihjb25zdCB0IG9mIGUpaWYodGhpcy5sb2dJZkRlYnVnRW5hYmxlZCgiY2xlYXIiLHQsdm9pZCAwKSx0eXBlb2YgdD09InN0cmluZyJ8fHR5cGVvZiB0PT0ic3ltYm9sIil7dmUodGhpcyx0KS5jbGVhcigpO2NvbnN0IG49SWUodGhpcyx0KTtmb3IoY29uc3QgaSBvZiBuKWkuZmluaXNoKCk7bi5jbGVhcigpfWVsc2V7ZWUuZ2V0KHRoaXMpLmNsZWFyKCk7Zm9yKGNvbnN0IG4gb2YgVmUuZ2V0KHRoaXMpLnZhbHVlcygpKW4uY2xlYXIoKTtmb3IoY29uc3QgbiBvZiBSZS5nZXQodGhpcykudmFsdWVzKCkpe2Zvcihjb25zdCBpIG9mIG4paS5maW5pc2goKTtuLmNsZWFyKCl9fX1saXN0ZW5lckNvdW50KGUpe2U9QXJyYXkuaXNBcnJheShlKT9lOltlXTtsZXQgdD0wO2Zvcihjb25zdCBuIG9mIGUpe2lmKHR5cGVvZiBuPT0ic3RyaW5nIil7dCs9ZWUuZ2V0KHRoaXMpLnNpemUrdmUodGhpcyxuKS5zaXplK0llKHRoaXMsbikuc2l6ZStJZSh0aGlzKS5zaXplO2NvbnRpbnVlfXR5cGVvZiBuPCJ1IiYmYmUobiksdCs9ZWUuZ2V0KHRoaXMpLnNpemU7Zm9yKGNvbnN0IGkgb2YgVmUuZ2V0KHRoaXMpLnZhbHVlcygpKXQrPWkuc2l6ZTtmb3IoY29uc3QgaSBvZiBSZS5nZXQodGhpcykudmFsdWVzKCkpdCs9aS5zaXplfXJldHVybiB0fWJpbmRNZXRob2RzKGUsdCl7aWYodHlwZW9mIGUhPSJvYmplY3QifHxlPT09bnVsbCl0aHJvdyBuZXcgVHlwZUVycm9yKCJgdGFyZ2V0YCBtdXN0IGJlIGFuIG9iamVjdCIpO3Q9UHIodCk7Zm9yKGNvbnN0IG4gb2YgdCl7aWYoZVtuXSE9PXZvaWQgMCl0aHJvdyBuZXcgRXJyb3IoYFRoZSBwcm9wZXJ0eSBcYCR7bn1cYCBhbHJlYWR5IGV4aXN0cyBvbiBcYHRhcmdldFxgYCk7T2JqZWN0LmRlZmluZVByb3BlcnR5KGUsbix7ZW51bWVyYWJsZTohMSx2YWx1ZTp0aGlzW25dLmJpbmQodGhpcyl9KX19fWNvbnN0IERyPU9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKGZlLnByb3RvdHlwZSkuZmlsdGVyKHI9PnIhPT0iY29uc3RydWN0b3IiKTtPYmplY3QuZGVmaW5lUHJvcGVydHkoZmUsImxpc3RlbmVyQWRkZWQiLHt2YWx1ZTpIZSx3cml0YWJsZTohMSxlbnVtZXJhYmxlOiEwLGNvbmZpZ3VyYWJsZTohMX0pLE9iamVjdC5kZWZpbmVQcm9wZXJ0eShmZSwibGlzdGVuZXJSZW1vdmVkIix7dmFsdWU6WWUsd3JpdGFibGU6ITEsZW51bWVyYWJsZTohMCxjb25maWd1cmFibGU6ITF9KTt2YXIgUHQ9ZmU7ZnVuY3Rpb24gd2kocil7cmV0dXJuIHR5cGVvZiByPT0ib2JqZWN0IiYmciE9PW51bGwmJiJtZXNzYWdlImluIHImJnR5cGVvZiByLm1lc3NhZ2U9PSJzdHJpbmcifWZ1bmN0aW9uIFNpKHIpe2lmKHdpKHIpKXJldHVybiByO3RyeXtyZXR1cm4gbmV3IEVycm9yKEpTT04uc3RyaW5naWZ5KHIpKX1jYXRjaHtyZXR1cm4gbmV3IEVycm9yKFN0cmluZyhyKSl9fWZ1bmN0aW9uIER0KHIpe3JldHVybiBTaShyKS5tZXNzYWdlfXZhciBSaT1PYmplY3QuZGVmaW5lUHJvcGVydHksSWk9KHIsZSx0KT0+ZSBpbiByP1JpKHIsZSx7ZW51bWVyYWJsZTohMCxjb25maWd1cmFibGU6ITAsd3JpdGFibGU6ITAsdmFsdWU6dH0pOnJbZV09dCxGaT0ocixlLHQpPT4oSWkocix0eXBlb2YgZSE9InN5bWJvbCI/ZSsiIjplLHQpLHQpO2NvbnN0IFBpPSJobGcudG9rYm94LmNvbS9wcm9kL2xvZ2dpbmcvdmNwX3dlYnJ0YyIsRGk9Imh0dHBzOi8vIixOaT0xZTQ7bGV0IFhlO2NvbnN0IE1pPW5ldyBVaW50OEFycmF5KDE2KTtmdW5jdGlvbiBVaSgpe2lmKCFYZSYmKFhlPXR5cGVvZiBjcnlwdG88InUiJiZjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzJiZjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzLmJpbmQoY3J5cHRvKSwhWGUpKXRocm93IG5ldyBFcnJvcigiY3J5cHRvLmdldFJhbmRvbVZhbHVlcygpIG5vdCBzdXBwb3J0ZWQuIFNlZSBodHRwczovL2dpdGh1Yi5jb20vdXVpZGpzL3V1aWQjZ2V0cmFuZG9tdmFsdWVzLW5vdC1zdXBwb3J0ZWQiKTtyZXR1cm4gWGUoTWkpfWNvbnN0IE09W107Zm9yKGxldCByPTA7cjwyNTY7KytyKU0ucHVzaCgocisyNTYpLnRvU3RyaW5nKDE2KS5zbGljZSgxKSk7ZnVuY3Rpb24ga2kocixlPTApe3JldHVybihNW3JbZSswXV0rTVtyW2UrMV1dK01bcltlKzJdXStNW3JbZSszXV0rIi0iK01bcltlKzRdXStNW3JbZSs1XV0rIi0iK01bcltlKzZdXStNW3JbZSs3XV0rIi0iK01bcltlKzhdXStNW3JbZSs5XV0rIi0iK01bcltlKzEwXV0rTVtyW2UrMTFdXStNW3JbZSsxMl1dK01bcltlKzEzXV0rTVtyW2UrMTRdXStNW3JbZSsxNV1dKS50b0xvd2VyQ2FzZSgpfWNvbnN0IENpPXR5cGVvZiBjcnlwdG88InUiJiZjcnlwdG8ucmFuZG9tVVVJRCYmY3J5cHRvLnJhbmRvbVVVSUQuYmluZChjcnlwdG8pLE5yPXtyYW5kb21VVUlEOkNpfTtmdW5jdGlvbiBPaShyLGUsdCl7aWYoTnIucmFuZG9tVVVJRCYmIWUmJiFyKXJldHVybiBOci5yYW5kb21VVUlEKCk7cj1yfHx7fTtjb25zdCBuPXIucmFuZG9tfHwoci5ybmd8fFVpKSgpO2lmKG5bNl09bls2XSYxNXw2NCxuWzhdPW5bOF0mNjN8MTI4LGUpe3Q9dHx8MDtmb3IobGV0IGk9MDtpPDE2OysraSllW3QraV09bltpXTtyZXR1cm4gZX1yZXR1cm4ga2kobil9ZnVuY3Rpb24gTnQocixlKXtyZXR1cm4gZ2xvYmFsVGhpc1tyXXx8KGdsb2JhbFRoaXNbcl09ZSksZ2xvYmFsVGhpc1tyXX1jb25zdCB0ZT1OdCgiZ2xvYmFscyIse30pO3ZhciBsZT0ocj0+KHIuSU5JVD0iSU5JVCIsci5GT1JXQVJEPSJGT1JXQVJEIixyLlRFUk1JTkFURT0iVEVSTUlOQVRFIixyLkdMT0JBTFNfU1lOQz0iR0xPQkFMU19TWU5DIixyKSkobGV8fHt9KTtmdW5jdGlvbiBNcihyKXtyZXR1cm5bSW1hZ2VCaXRtYXAsUmVhZGFibGVTdHJlYW0sV3JpdGFibGVTdHJlYW1dLnNvbWUoZT0+ciBpbnN0YW5jZW9mIGUpfWxldCBCaT0wO2Z1bmN0aW9uIExpKHIsZSx0LG4saSl7Y29uc3Qgbz1CaSsrO3JldHVybiByLnBvc3RNZXNzYWdlKHtpZDpvLHR5cGU6ZSxmdW5jdGlvbk5hbWU6dCxhcmdzOm59LG4uZmlsdGVyKHM9Pk1yKHMpKSksbmV3IFByb21pc2Uocz0+e2k9PW51bGx8fGkuc2V0KG8scyl9KX1mdW5jdGlvbiBGZShyLGUpe2NvbnN0e2lkOnQsdHlwZTpufT1yLGk9QXJyYXkuaXNBcnJheShlKT9lOltlXTtwb3N0TWVzc2FnZSh7aWQ6dCx0eXBlOm4scmVzdWx0OmV9LGkuZmlsdGVyKG89Pk1yKG8pKSl9Y29uc3QgVXI9TnQoIndvcmtlcml6ZWQiLHt9KTtmdW5jdGlvbiBrcigpe3JldHVybiB0eXBlb2YgV29ya2VyR2xvYmFsU2NvcGU8InUiJiZzZWxmIGluc3RhbmNlb2YgV29ya2VyR2xvYmFsU2NvcGV9YXN5bmMgZnVuY3Rpb24gR2koKXtpZihrcigpKUZlKHt0eXBlOmxlLkdMT0JBTFNfU1lOQ30sdGUpO2Vsc2V7Y29uc3Qgcj1bXTtmb3IoY29uc3QgZSBpbiBVcil7Y29uc3R7d29ya2VyOnQscmVzb2x2ZXJzOm59PVVyW2VdLndvcmtlckNvbnRleHQ7dCYmci5wdXNoKExpKHQsbGUuR0xPQkFMU19TWU5DLCIiLFt0ZV0sbikpfWF3YWl0IFByb21pc2UuYWxsKHIpfX1mdW5jdGlvbiBRZShyLGUpe2lmKEFycmF5LmlzQXJyYXkoZSkpZS5zcGxpY2UoMCxlLmxlbmd0aCk7ZWxzZSBpZih0eXBlb2YgZT09Im9iamVjdCIpZm9yKGNvbnN0IHQgaW4gZSlkZWxldGUgZVt0XTtmb3IoY29uc3QgdCBpbiByKUFycmF5LmlzQXJyYXkoclt0XSk/KGVbdF09W10sUWUoclt0XSxlW3RdKSk6dHlwZW9mIHJbdF09PSJvYmplY3QiPyhlW3RdPXt9LFFlKHJbdF0sZVt0XSkpOmVbdF09clt0XX1hc3luYyBmdW5jdGlvbiAkaShyLGUpe2NvbnN0e2Z1bmN0aW9uTmFtZTp0LGFyZ3M6bn09cjtpZighZS5pbnN0YW5jZSl0aHJvdyJpbnN0YW5jZSBub3QgaW5pdGlhbGl6ZWQiO2lmKCF0KXRocm93Im1pc3NpbmcgZnVuY3Rpb24gbmFtZSB0byBjYWxsIjtpZighZS5pbnN0YW5jZVt0XSl0aHJvd2B1bmRlZmluZWQgZnVuY3Rpb24gWyR7dH1dIGluIGNsYXNzICR7ZS5pbnN0YW5jZS5jb25zdHJ1Y3Rvci53b3JrZXJJZH1gO0ZlKHIsYXdhaXQgZS5pbnN0YW5jZVt0XSguLi5uIT1udWxsP246W10pKX1jb25zdCB6aT1OdCgicmVnaXN0ZXJlZFdvcmtlcnMiLHt9KTtmdW5jdGlvbiBXaShyLGUpe2lmKCFyLmFyZ3MpdGhyb3ciTWlzc2luZyBjbGFzc05hbWUgd2hpbGUgaW5pdGlhbGl6aW5nIHdvcmtlciI7Y29uc3RbdCxuXT1yLmFyZ3MsaT16aVt0XTtpZihpKWUuaW5zdGFuY2U9bmV3IGkoci5hcmdzLnNsaWNlKDEpKTtlbHNlIHRocm93YHVua25vd24gd29ya2VyIGNsYXNzICR7dH1gO1FlKG4sdGUpLEZlKHIsdHlwZW9mIGUuaW5zdGFuY2UhPT12b2lkIDApfWFzeW5jIGZ1bmN0aW9uIFZpKHIsZSl7Y29uc3R7YXJnczp0fT1yO2lmKCFlLmluc3RhbmNlKXRocm93Imluc3RhbmNlIG5vdCBpbml0aWFsaXplZCI7bGV0IG47ZS5pbnN0YW5jZS50ZXJtaW5hdGUmJihuPWF3YWl0IGUuaW5zdGFuY2UudGVybWluYXRlKC4uLnQhPW51bGw/dDpbXSkpLEZlKHIsbil9ZnVuY3Rpb24gSGkocil7aWYoIXIuYXJncyl0aHJvdyJNaXNzaW5nIGdsb2JhbHMgd2hpbGUgc3luY2luZyI7UWUoci5hcmdzWzBdLHRlKSxGZShyLHt9KX1mdW5jdGlvbiBZaSgpe2NvbnN0IHI9e307b25tZXNzYWdlPWFzeW5jIGU9Pntjb25zdCB0PWUuZGF0YTtzd2l0Y2godC50eXBlKXtjYXNlIGxlLklOSVQ6V2kodCxyKTticmVhaztjYXNlIGxlLkZPUldBUkQ6JGkodCxyKTticmVhaztjYXNlIGxlLlRFUk1JTkFURTpWaSh0LHIpO2JyZWFrO2Nhc2UgbGUuR0xPQkFMU19TWU5DOkhpKHQpO2JyZWFrfX19a3IoKSYmWWkoKTtmdW5jdGlvbiBqaShyLGUpe3JldHVybiB0ZVtyXXx8KHRlW3JdPWUpLFsoKT0+dGVbcl0sYXN5bmMgdD0+e3RlW3JdPXQsYXdhaXQgR2koKX1dfWZ1bmN0aW9uIFhpKHIsZSl7cmV0dXJuIGppKHIsZSl9Y29uc3RbUWksS2ldPVhpKCJtZXRhZGF0YSIpO2Z1bmN0aW9uIHFpKHIpe0tpKHIpfWZ1bmN0aW9uIE10KCl7cmV0dXJuIFFpKCl9Y2xhc3MgVXR7Y29uc3RydWN0b3IoZSl7RmkodGhpcywidXVpZCIsT2koKSksdGhpcy5jb25maWc9ZX1hc3luYyBzZW5kKGUpe3ZhciB0LG4saTtjb25zdHthcHBJZDpvLHNvdXJjZVR5cGU6c309KHQ9TXQoKSkhPW51bGw/dDp7fTtpZighb3x8IXMpcmV0dXJuIm1ldGFkYXRhIG1pc3NpbmciO2NvbnN0IGE9bmV3IEFib3J0Q29udHJvbGxlcix1PXNldFRpbWVvdXQoKCk9PmEuYWJvcnQoKSxOaSk7cmV0dXJuIGF3YWl0KChpPShuPXRoaXMuY29uZmlnKT09bnVsbD92b2lkIDA6bi5mZXRjaCkhPW51bGw/aTpmZXRjaCkodGhpcy5nZXRVcmwoKSx7bWV0aG9kOiJQT1NUIixoZWFkZXJzOnRoaXMuZ2V0SGVhZGVycygpLGJvZHk6SlNPTi5zdHJpbmdpZnkodGhpcy5idWlsZFJlcG9ydChlKSksc2lnbmFsOmEuc2lnbmFsfSksY2xlYXJUaW1lb3V0KHUpLCJzdWNjZXNzIn1nZXRVcmwoKXt2YXIgZTtsZXQgdD0oZT1NdCgpLnByb3h5VXJsKSE9bnVsbD9lOkRpO3JldHVybiB0Kz0odC5hdCgtMSk9PT0iLyI/IiI6Ii8iKStQaSx0fWdldEhlYWRlcnMoKXtyZXR1cm57IkNvbnRlbnQtVHlwZSI6ImFwcGxpY2F0aW9uL2pzb24ifX1idWlsZFJlcG9ydChlKXtjb25zdCB0PU10KCk7cmV0dXJue2d1aWQ6dGhpcy51dWlkLC4uLmUsYXBwbGljYXRpb25JZDp0LmFwcElkLHRpbWVzdGFtcDpEYXRlLm5vdygpLHByb3h5VXJsOnQucHJveHlVcmwsc291cmNlOnQuc291cmNlVHlwZX19fWNvbnN0IEtlPSIyLjAuMiI7Y2xhc3MgSml7Y29uc3RydWN0b3IoZSl7QSh0aGlzLCJmcmFtZVRyYW5zZm9ybWVkQ291bnQiLDApLEEodGhpcywiZnJhbWVGcm9tU291cmNlQ291bnQiLDApLEEodGhpcywic3RhcnRBdCIsMCksQSh0aGlzLCJyZXBvcnRlciIpLHRoaXMuY29uZmlnPWUsdGhpcy5yZXBvcnRlcj1uZXcgVXQoZSl9YXN5bmMgb25GcmFtZUZyb21Tb3VyY2UoKXt0aGlzLmZyYW1lRnJvbVNvdXJjZUNvdW50Kyt9Z2V0IGZwcygpe2NvbnN0e3N0YXJ0QXQ6ZSxmcmFtZUZyb21Tb3VyY2VDb3VudDp0fT10aGlzLG49KERhdGUubm93KCktZSkvMWUzO3JldHVybiB0L259YXN5bmMgb25GcmFtZVRyYW5zZm9ybWVkKGU9e30sdD0hMSl7dGhpcy5zdGFydEF0PT09MCYmKHRoaXMuc3RhcnRBdD1EYXRlLm5vdygpKSx0aGlzLmZyYW1lVHJhbnNmb3JtZWRDb3VudCsrO2NvbnN0e3N0YXJ0QXQ6bixmcmFtZVRyYW5zZm9ybWVkQ291bnQ6aSxmcmFtZUZyb21Tb3VyY2VDb3VudDpvfT10aGlzLHM9RGF0ZS5ub3coKSxhPShzLW4pLzFlMyx1PWkvYSxmPW8vYTtyZXR1cm4gdHx8dGhpcy5mcmFtZVRyYW5zZm9ybWVkQ291bnQ+PXRoaXMuY29uZmlnLmxvZ2dpbmdJbnRlcnZhbEZyYW1lQ291bnQ/KHRoaXMuZnJhbWVGcm9tU291cmNlQ291bnQ9MCx0aGlzLmZyYW1lVHJhbnNmb3JtZWRDb3VudD0wLHRoaXMuc3RhcnRBdD1zLHRoaXMucmVwb3J0ZXIuY29uZmlnPXRoaXMuY29uZmlnLHRoaXMucmVwb3J0ZXIuc2VuZCh7Li4udGhpcy5jb25maWcucmVwb3J0LHZhcmlhdGlvbjoiUW9TIixmcHM6Zix0cmFuc2Zvcm1lZEZwczp1LGZyYW1lc1RyYW5zZm9ybWVkOmksLi4uZX0pKToic3VjY2VzcyJ9fXZhciBrdD0ocj0+KHIucGlwZWxpbmVfZW5kZWQ9InBpcGVsaW5lX2VuZGVkIixyLnBpcGVsaW5lX2VuZGVkX3dpdGhfZXJyb3I9InBpcGVsaW5lX2VuZGVkX3dpdGhfZXJyb3IiLHIucGlwZWxpbmVfc3RhcnRlZD0icGlwZWxpbmVfc3RhcnRlZCIsci5waXBlbGluZV9zdGFydGVkX3dpdGhfZXJyb3I9InBpcGVsaW5lX3N0YXJ0ZWRfd2l0aF9lcnJvciIsci5waXBlbGluZV9yZXN0YXJ0ZWQ9InBpcGVsaW5lX3Jlc3RhcnRlZCIsci5waXBlbGluZV9yZXN0YXJ0ZWRfd2l0aF9lcnJvcj0icGlwZWxpbmVfcmVzdGFydGVkX3dpdGhfZXJyb3IiLHIpKShrdHx8e30pO2NvbnN0IFppPTUwMCxlbz0uODtjbGFzcyB0byBleHRlbmRzIFB0e2NvbnN0cnVjdG9yKGUsdCl7c3VwZXIoKSxBKHRoaXMsInJlcG9ydGVyXyIsbmV3IFV0KSxBKHRoaXMsInJlcG9ydGVyUW9zXyIsbmV3IEppKHtsb2dnaW5nSW50ZXJ2YWxGcmFtZUNvdW50OlppLHJlcG9ydDp7dmVyc2lvbjpLZX19KSksQSh0aGlzLCJ0cmFuc2Zvcm1lclR5cGVfIiksQSh0aGlzLCJ0cmFuc2Zvcm1lcl8iKSxBKHRoaXMsInNob3VsZFN0b3BfIiksQSh0aGlzLCJpc0ZsYXNoZWRfIiksQSh0aGlzLCJtZWRpYVRyYW5zZm9ybWVyUW9zUmVwb3J0U3RhcnRUaW1lc3RhbXBfIiksQSh0aGlzLCJ2aWRlb0hlaWdodF8iKSxBKHRoaXMsInZpZGVvV2lkdGhfIiksQSh0aGlzLCJ0cmFja0V4cGVjdGVkUmF0ZV8iKSxBKHRoaXMsImluZGV4XyIpLEEodGhpcywiY29udHJvbGxlcl8iKSx0aGlzLmluZGV4Xz10LHRoaXMudHJhbnNmb3JtZXJfPWUsdGhpcy5zaG91bGRTdG9wXz0hMSx0aGlzLmlzRmxhc2hlZF89ITEsdGhpcy5tZWRpYVRyYW5zZm9ybWVyUW9zUmVwb3J0U3RhcnRUaW1lc3RhbXBfPTAsdGhpcy52aWRlb0hlaWdodF89MCx0aGlzLnZpZGVvV2lkdGhfPTAsdGhpcy50cmFja0V4cGVjdGVkUmF0ZV89LTEsdGhpcy50cmFuc2Zvcm1lclR5cGVfPSJDdXN0b20iLCJnZXRUcmFuc2Zvcm1lclR5cGUiaW4gZSYmKHRoaXMudHJhbnNmb3JtZXJUeXBlXz1lLmdldFRyYW5zZm9ybWVyVHlwZSgpKSx0aGlzLnJlcG9ydCh7dmFyaWF0aW9uOiJDcmVhdGUifSl9c2V0VHJhY2tFeHBlY3RlZFJhdGUoZSl7dGhpcy50cmFja0V4cGVjdGVkUmF0ZV89ZX1hc3luYyBzdGFydChlKXtpZih0aGlzLmNvbnRyb2xsZXJfPWUsdGhpcy50cmFuc2Zvcm1lcl8mJnR5cGVvZiB0aGlzLnRyYW5zZm9ybWVyXy5zdGFydD09ImZ1bmN0aW9uIil0cnl7YXdhaXQgdGhpcy50cmFuc2Zvcm1lcl8uc3RhcnQoZSl9Y2F0Y2godCl7dGhpcy5yZXBvcnQoe21lc3NhZ2U6Si5lcnJvcnMudHJhbnNmb3JtZXJfc3RhcnQsdmFyaWF0aW9uOiJFcnJvciIsZXJyb3I6RHQodCl9KTtjb25zdCBuPXtldmVudE1ldGFEYXRhOnt0cmFuc2Zvcm1lckluZGV4OnRoaXMuaW5kZXhffSxlcnJvcjp0LGZ1bmN0aW9uOiJzdGFydCJ9O3RoaXMuZW1pdCgiZXJyb3IiLG4pfX1hc3luYyB0cmFuc2Zvcm0oZSx0KXt2YXIgbixpLG8scztpZih0aGlzLm1lZGlhVHJhbnNmb3JtZXJRb3NSZXBvcnRTdGFydFRpbWVzdGFtcF89PT0wJiYodGhpcy5tZWRpYVRyYW5zZm9ybWVyUW9zUmVwb3J0U3RhcnRUaW1lc3RhbXBfPURhdGUubm93KCkpLGUgaW5zdGFuY2VvZiBWaWRlb0ZyYW1lJiYodGhpcy52aWRlb0hlaWdodF89KG49ZT09bnVsbD92b2lkIDA6ZS5kaXNwbGF5SGVpZ2h0KSE9bnVsbD9uOjAsdGhpcy52aWRlb1dpZHRoXz0oaT1lPT1udWxsP3ZvaWQgMDplLmRpc3BsYXlXaWR0aCkhPW51bGw/aTowKSx0aGlzLnJlcG9ydGVyUW9zXy5vbkZyYW1lRnJvbVNvdXJjZSgpLHRoaXMudHJhbnNmb3JtZXJfKWlmKHRoaXMuc2hvdWxkU3RvcF8pY29uc29sZS53YXJuKCJbUGlwZWxpbmVdIGZsdXNoIGZyb20gdHJhbnNmb3JtIiksZS5jbG9zZSgpLHRoaXMuZmx1c2godCksdC50ZXJtaW5hdGUoKTtlbHNle3RyeXthd2FpdCgocz0obz10aGlzLnRyYW5zZm9ybWVyXykudHJhbnNmb3JtKT09bnVsbD92b2lkIDA6cy5jYWxsKG8sZSx0KSksdGhpcy5yZXBvcnRRb3MoKX1jYXRjaChhKXt0aGlzLnJlcG9ydCh7bWVzc2FnZTpKLmVycm9ycy50cmFuc2Zvcm1lcl90cmFuc2Zvcm0sdmFyaWF0aW9uOiJFcnJvciIsZXJyb3I6RHQoYSl9KTtjb25zdCB1PXtldmVudE1ldGFEYXRhOnt0cmFuc2Zvcm1lckluZGV4OnRoaXMuaW5kZXhffSxlcnJvcjphLGZ1bmN0aW9uOiJ0cmFuc2Zvcm0ifTt0aGlzLmVtaXQoImVycm9yIix1KX1pZih0aGlzLnRyYWNrRXhwZWN0ZWRSYXRlXyE9LTEmJnRoaXMudHJhY2tFeHBlY3RlZFJhdGVfKmVvPnRoaXMucmVwb3J0ZXJRb3NfLmZwcyl7Y29uc3QgYT17ZXZlbnRNZXRhRGF0YTp7dHJhbnNmb3JtZXJJbmRleDp0aGlzLmluZGV4X30sd2FybmluZ1R5cGU6ImZwc19kcm9wIixkcm9wSW5mbzp7cmVxdWVzdGVkOnRoaXMudHJhY2tFeHBlY3RlZFJhdGVfLGN1cnJlbnQ6dGhpcy5yZXBvcnRlclFvc18uZnBzfX07dGhpcy5lbWl0KCJ3YXJuIixhKX19fWFzeW5jIGZsdXNoKGUpe2lmKHRoaXMudHJhbnNmb3JtZXJfJiZ0eXBlb2YgdGhpcy50cmFuc2Zvcm1lcl8uZmx1c2g9PSJmdW5jdGlvbiImJiF0aGlzLmlzRmxhc2hlZF8pe3RoaXMuaXNGbGFzaGVkXz0hMDt0cnl7YXdhaXQgdGhpcy50cmFuc2Zvcm1lcl8uZmx1c2goZSl9Y2F0Y2godCl7dGhpcy5yZXBvcnQoe21lc3NhZ2U6Si5lcnJvcnMudHJhbnNmb3JtZXJfZmx1c2gsdmFyaWF0aW9uOiJFcnJvciIsZXJyb3I6RHQodCl9KTtjb25zdCBuPXtldmVudE1ldGFEYXRhOnt0cmFuc2Zvcm1lckluZGV4OnRoaXMuaW5kZXhffSxlcnJvcjp0LGZ1bmN0aW9uOiJmbHVzaCJ9O3RoaXMuZW1pdCgiZXJyb3IiLG4pfX10aGlzLnJlcG9ydFFvcyghMCksdGhpcy5yZXBvcnQoe3ZhcmlhdGlvbjoiRGVsZXRlIn0pfXN0b3AoKXtjb25zb2xlLmxvZygiW1BpcGVsaW5lXSBTdG9wIHN0cmVhbS4iKSx0aGlzLmNvbnRyb2xsZXJfJiYodGhpcy5mbHVzaCh0aGlzLmNvbnRyb2xsZXJfKSx0aGlzLmNvbnRyb2xsZXJfLnRlcm1pbmF0ZSgpKSx0aGlzLnNob3VsZFN0b3BfPSEwfXJlcG9ydChlKXt0aGlzLnJlcG9ydGVyXy5zZW5kKHt2ZXJzaW9uOktlLGFjdGlvbjoiTWVkaWFUcmFuc2Zvcm1lciIsdHJhbnNmb3JtZXJUeXBlOnRoaXMudHJhbnNmb3JtZXJUeXBlXywuLi5lfSl9cmVwb3J0UW9zKGU9ITEpe3RoaXMucmVwb3J0ZXJRb3NfLmNvbmZpZz17Li4udGhpcy5yZXBvcnRlclFvc18uY29uZmlnfSx0aGlzLnJlcG9ydGVyUW9zXy5vbkZyYW1lVHJhbnNmb3JtZWQoe3ZlcnNpb246S2UsYWN0aW9uOiJNZWRpYVRyYW5zZm9ybWVyIix0cmFuc2Zvcm1lclR5cGU6dGhpcy50cmFuc2Zvcm1lclR5cGVfLHZpZGVvV2lkdGg6dGhpcy52aWRlb1dpZHRoXyx2aWRlb0hlaWdodDp0aGlzLnZpZGVvSGVpZ2h0X30sZSl9fWNsYXNzIHJvIGV4dGVuZHMgUHR7Y29uc3RydWN0b3IoZSl7c3VwZXIoKSxBKHRoaXMsInRyYW5zZm9ybWVyc18iKSxBKHRoaXMsInRyYWNrRXhwZWN0ZWRSYXRlXyIpLHRoaXMudHJhbnNmb3JtZXJzXz1bXSx0aGlzLnRyYWNrRXhwZWN0ZWRSYXRlXz0tMTtmb3IobGV0IHQ9MDt0PGUubGVuZ3RoO3QrKyl7bGV0IG49bmV3IHRvKGVbdF0sdCk7bi5vbigiZXJyb3IiLGk9Pnt0aGlzLmVtaXQoImVycm9yIixpKX0pLG4ub24oIndhcm4iLGk9Pnt0aGlzLmVtaXQoIndhcm4iLGkpfSksdGhpcy50cmFuc2Zvcm1lcnNfLnB1c2gobil9fXNldFRyYWNrRXhwZWN0ZWRSYXRlKGUpe3RoaXMudHJhY2tFeHBlY3RlZFJhdGVfPWU7Zm9yKGxldCB0IG9mIHRoaXMudHJhbnNmb3JtZXJzXyl0LnNldFRyYWNrRXhwZWN0ZWRSYXRlKHRoaXMudHJhY2tFeHBlY3RlZFJhdGVfKX1hc3luYyBzdGFydChlLHQpe2lmKCF0aGlzLnRyYW5zZm9ybWVyc198fHRoaXMudHJhbnNmb3JtZXJzXy5sZW5ndGg9PT0wKXtjb25zb2xlLmxvZygiW1BpcGVsaW5lXSBObyB0cmFuc2Zvcm1lcnMuIik7cmV0dXJufXRyeXtsZXQgbj1lO2ZvcihsZXQgaSBvZiB0aGlzLnRyYW5zZm9ybWVyc18pZT1lLnBpcGVUaHJvdWdoKG5ldyBUcmFuc2Zvcm1TdHJlYW0oaSkpO2UucGlwZVRvKHQpLnRoZW4oYXN5bmMoKT0+e2NvbnNvbGUubG9nKCJbUGlwZWxpbmVdIFNldHVwLiIpLGF3YWl0IHQuYWJvcnQoKSxhd2FpdCBuLmNhbmNlbCgpLHRoaXMuZW1pdCgicGlwZWxpbmVJbmZvIiwicGlwZWxpbmVfZW5kZWQiKX0pLmNhdGNoKGFzeW5jIGk9PntlLmNhbmNlbCgpLnRoZW4oKCk9Pntjb25zb2xlLmxvZygiW1BpcGVsaW5lXSBTaHV0dGluZyBkb3duIHN0cmVhbXMgYWZ0ZXIgYWJvcnQuIil9KS5jYXRjaChvPT57Y29uc29sZS5lcnJvcigiW1BpcGVsaW5lXSBFcnJvciBmcm9tIHN0cmVhbSB0cmFuc2Zvcm06IixvKX0pLGF3YWl0IHQuYWJvcnQoaSksYXdhaXQgbi5jYW5jZWwoaSksdGhpcy5lbWl0KCJwaXBlbGluZUluZm8iLCJwaXBlbGluZV9lbmRlZF93aXRoX2Vycm9yIil9KX1jYXRjaHt0aGlzLmVtaXQoInBpcGVsaW5lSW5mbyIsInBpcGVsaW5lX3N0YXJ0ZWRfd2l0aF9lcnJvciIpLHRoaXMuZGVzdHJveSgpO3JldHVybn10aGlzLmVtaXQoInBpcGVsaW5lSW5mbyIsInBpcGVsaW5lX3N0YXJ0ZWQiKSxjb25zb2xlLmxvZygiW1BpcGVsaW5lXSBQaXBlbGluZSBzdGFydGVkLiIpfWFzeW5jIGRlc3Ryb3koKXtjb25zb2xlLmxvZygiW1BpcGVsaW5lXSBEZXN0cm95aW5nIFBpcGVsaW5lLiIpO2ZvcihsZXQgZSBvZiB0aGlzLnRyYW5zZm9ybWVyc18pZS5zdG9wKCl9fWNsYXNzIG5vIGV4dGVuZHMgUHR7Y29uc3RydWN0b3IoKXtzdXBlcigpLEEodGhpcywicmVwb3J0ZXJfIiksQSh0aGlzLCJwaXBlbGluZV8iKSxBKHRoaXMsInRyYW5zZm9ybWVyc18iKSxBKHRoaXMsInJlYWRhYmxlXyIpLEEodGhpcywid3JpdGFibGVfIiksQSh0aGlzLCJ0cmFja0V4cGVjdGVkUmF0ZV8iKSx0aGlzLnJlcG9ydGVyXz1uZXcgVXQsdGhpcy50cmFja0V4cGVjdGVkUmF0ZV89LTEsdGhpcy5yZXBvcnQoe3ZhcmlhdGlvbjoiQ3JlYXRlIn0pfXNldFRyYWNrRXhwZWN0ZWRSYXRlKGUpe3RoaXMudHJhY2tFeHBlY3RlZFJhdGVfPWUsdGhpcy5waXBlbGluZV8mJnRoaXMucGlwZWxpbmVfLnNldFRyYWNrRXhwZWN0ZWRSYXRlKHRoaXMudHJhY2tFeHBlY3RlZFJhdGVfKX10cmFuc2Zvcm0oZSx0KXtyZXR1cm4gdGhpcy5yZWFkYWJsZV89ZSx0aGlzLndyaXRhYmxlXz10LHRoaXMudHJhbnNmb3JtSW50ZXJuYWwoKX10cmFuc2Zvcm1JbnRlcm5hbCgpe3JldHVybiBuZXcgUHJvbWlzZShhc3luYyhlLHQpPT57aWYoIXRoaXMudHJhbnNmb3JtZXJzX3x8dGhpcy50cmFuc2Zvcm1lcnNfLmxlbmd0aD09PTApe3RoaXMucmVwb3J0KHttZXNzYWdlOkouZXJyb3JzLnRyYW5zZm9ybWVyX25vbmUsdmFyaWF0aW9uOiJFcnJvciJ9KSx0KCJbTWVkaWFQcm9jZXNzb3JdIE5lZWQgdG8gc2V0IHRyYW5zZm9ybWVycy4iKTtyZXR1cm59aWYoIXRoaXMucmVhZGFibGVfKXt0aGlzLnJlcG9ydCh7dmFyaWF0aW9uOiJFcnJvciIsbWVzc2FnZTpKLmVycm9ycy5yZWFkYWJsZV9udWxsfSksdCgiW01lZGlhUHJvY2Vzc29yXSBSZWFkYWJsZSBpcyBudWxsLiIpO3JldHVybn1pZighdGhpcy53cml0YWJsZV8pe3RoaXMucmVwb3J0KHt2YXJpYXRpb246IkVycm9yIixtZXNzYWdlOkouZXJyb3JzLndyaXRhYmxlX251bGx9KSx0KCJbTWVkaWFQcm9jZXNzb3JdIFdyaXRhYmxlIGlzIG51bGwuIik7cmV0dXJufWxldCBuPSExO3RoaXMucGlwZWxpbmVfJiYobj0hMCx0aGlzLnBpcGVsaW5lXy5jbGVhckxpc3RlbmVycygpLHRoaXMucGlwZWxpbmVfLmRlc3Ryb3koKSksdGhpcy5waXBlbGluZV89bmV3IHJvKHRoaXMudHJhbnNmb3JtZXJzXyksdGhpcy5waXBlbGluZV8ub24oIndhcm4iLGk9Pnt0aGlzLmVtaXQoIndhcm4iLGkpfSksdGhpcy5waXBlbGluZV8ub24oImVycm9yIixpPT57dGhpcy5lbWl0KCJlcnJvciIsaSl9KSx0aGlzLnBpcGVsaW5lXy5vbigicGlwZWxpbmVJbmZvIixpPT57biYmKGk9PT0icGlwZWxpbmVfc3RhcnRlZCI/aT1rdC5waXBlbGluZV9yZXN0YXJ0ZWQ6aT09PSJwaXBlbGluZV9zdGFydGVkX3dpdGhfZXJyb3IiJiYoaT1rdC5waXBlbGluZV9yZXN0YXJ0ZWRfd2l0aF9lcnJvcikpLHRoaXMuZW1pdCgicGlwZWxpbmVJbmZvIixpKX0pLHRoaXMudHJhY2tFeHBlY3RlZFJhdGVfIT0tMSYmdGhpcy5waXBlbGluZV8uc2V0VHJhY2tFeHBlY3RlZFJhdGUodGhpcy50cmFja0V4cGVjdGVkUmF0ZV8pLHRoaXMucGlwZWxpbmVfLnN0YXJ0KHRoaXMucmVhZGFibGVfLHRoaXMud3JpdGFibGVfKS50aGVuKCgpPT57ZSgpfSkuY2F0Y2goaT0+e3QoaSl9KX0pfXNldFRyYW5zZm9ybWVycyhlKXtyZXR1cm4gdGhpcy5yZXBvcnQoe3ZhcmlhdGlvbjoiVXBkYXRlIixtZXNzYWdlOkoudXBkYXRlcy50cmFuc2Zvcm1lcl9uZXd9KSx0aGlzLnRyYW5zZm9ybWVyc189ZSx0aGlzLnJlYWRhYmxlXyYmdGhpcy53cml0YWJsZV8/dGhpcy50cmFuc2Zvcm1JbnRlcm5hbCgpOlByb21pc2UucmVzb2x2ZSgpfWRlc3Ryb3koKXtyZXR1cm4gbmV3IFByb21pc2UoYXN5bmMgZT0+e3RoaXMucGlwZWxpbmVfJiZ0aGlzLnBpcGVsaW5lXy5kZXN0cm95KCksdGhpcy5yZXBvcnQoe3ZhcmlhdGlvbjoiRGVsZXRlIn0pLGUoKX0pfXJlcG9ydChlKXt0aGlzLnJlcG9ydGVyXy5zZW5kKHt2ZXJzaW9uOktlLGFjdGlvbjoiTWVkaWFQcm9jZXNzb3IiLC4uLmV9KX19dmFyIGlvPU9iamVjdC5kZWZpbmVQcm9wZXJ0eSxvbz0ocixlLHQpPT5lIGluIHI/aW8ocixlLHtlbnVtZXJhYmxlOiEwLGNvbmZpZ3VyYWJsZTohMCx3cml0YWJsZTohMCx2YWx1ZTp0fSk6cltlXT10LHNvPShyLGUsdCk9PihvbyhyLHR5cGVvZiBlIT0ic3ltYm9sIj9lKyIiOmUsdCksdCk7Y29uc3QgYW89ImhsZy50b2tib3guY29tL3Byb2QvbG9nZ2luZy92Y3Bfd2VicnRjIix1bz0iaHR0cHM6Ly8iLGNvPTFlNDtsZXQgcWU7Y29uc3QgZm89bmV3IFVpbnQ4QXJyYXkoMTYpO2Z1bmN0aW9uIGxvKCl7aWYoIXFlJiYocWU9dHlwZW9mIGNyeXB0bzwidSImJmNyeXB0by5nZXRSYW5kb21WYWx1ZXMmJmNyeXB0by5nZXRSYW5kb21WYWx1ZXMuYmluZChjcnlwdG8pLCFxZSkpdGhyb3cgbmV3IEVycm9yKCJjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKCkgbm90IHN1cHBvcnRlZC4gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS91dWlkanMvdXVpZCNnZXRyYW5kb212YWx1ZXMtbm90LXN1cHBvcnRlZCIpO3JldHVybiBxZShmbyl9Y29uc3QgVT1bXTtmb3IobGV0IHI9MDtyPDI1NjsrK3IpVS5wdXNoKChyKzI1NikudG9TdHJpbmcoMTYpLnNsaWNlKDEpKTtmdW5jdGlvbiBtbyhyLGU9MCl7cmV0dXJuKFVbcltlKzBdXStVW3JbZSsxXV0rVVtyW2UrMl1dK1VbcltlKzNdXSsiLSIrVVtyW2UrNF1dK1VbcltlKzVdXSsiLSIrVVtyW2UrNl1dK1VbcltlKzddXSsiLSIrVVtyW2UrOF1dK1VbcltlKzldXSsiLSIrVVtyW2UrMTBdXStVW3JbZSsxMV1dK1VbcltlKzEyXV0rVVtyW2UrMTNdXStVW3JbZSsxNF1dK1VbcltlKzE1XV0pLnRvTG93ZXJDYXNlKCl9Y29uc3QgaG89dHlwZW9mIGNyeXB0bzwidSImJmNyeXB0by5yYW5kb21VVUlEJiZjcnlwdG8ucmFuZG9tVVVJRC5iaW5kKGNyeXB0byksQ3I9e3JhbmRvbVVVSUQ6aG99O2Z1bmN0aW9uIHBvKHIsZSx0KXtpZihDci5yYW5kb21VVUlEJiYhZSYmIXIpcmV0dXJuIENyLnJhbmRvbVVVSUQoKTtyPXJ8fHt9O2NvbnN0IG49ci5yYW5kb218fChyLnJuZ3x8bG8pKCk7aWYobls2XT1uWzZdJjE1fDY0LG5bOF09bls4XSY2M3wxMjgsZSl7dD10fHwwO2ZvcihsZXQgaT0wO2k8MTY7KytpKWVbdCtpXT1uW2ldO3JldHVybiBlfXJldHVybiBtbyhuKX1mdW5jdGlvbiBDdChyLGUpe3JldHVybiBnbG9iYWxUaGlzW3JdfHwoZ2xvYmFsVGhpc1tyXT1lKSxnbG9iYWxUaGlzW3JdfWNvbnN0IHJlPUN0KCJnbG9iYWxzIix7fSk7dmFyIGRlPShyPT4oci5JTklUPSJJTklUIixyLkZPUldBUkQ9IkZPUldBUkQiLHIuVEVSTUlOQVRFPSJURVJNSU5BVEUiLHIuR0xPQkFMU19TWU5DPSJHTE9CQUxTX1NZTkMiLHIpKShkZXx8e30pO2Z1bmN0aW9uIE9yKHIpe3JldHVybltJbWFnZUJpdG1hcCxSZWFkYWJsZVN0cmVhbSxXcml0YWJsZVN0cmVhbV0uc29tZShlPT5yIGluc3RhbmNlb2YgZSl9bGV0IHlvPTA7ZnVuY3Rpb24gX28ocixlLHQsbixpKXtjb25zdCBvPXlvKys7cmV0dXJuIHIucG9zdE1lc3NhZ2Uoe2lkOm8sdHlwZTplLGZ1bmN0aW9uTmFtZTp0LGFyZ3M6bn0sbi5maWx0ZXIocz0+T3IocykpKSxuZXcgUHJvbWlzZShzPT57aT09bnVsbHx8aS5zZXQobyxzKX0pfWZ1bmN0aW9uIFBlKHIsZSl7Y29uc3R7aWQ6dCx0eXBlOm59PXIsaT1BcnJheS5pc0FycmF5KGUpP2U6W2VdO3Bvc3RNZXNzYWdlKHtpZDp0LHR5cGU6bixyZXN1bHQ6ZX0saS5maWx0ZXIobz0+T3IobykpKX1jb25zdCBCcj1DdCgid29ya2VyaXplZCIse30pO2Z1bmN0aW9uIExyKCl7cmV0dXJuIHR5cGVvZiBXb3JrZXJHbG9iYWxTY29wZTwidSImJnNlbGYgaW5zdGFuY2VvZiBXb3JrZXJHbG9iYWxTY29wZX1hc3luYyBmdW5jdGlvbiB4bygpe2lmKExyKCkpUGUoe3R5cGU6ZGUuR0xPQkFMU19TWU5DfSxyZSk7ZWxzZXtjb25zdCByPVtdO2Zvcihjb25zdCBlIGluIEJyKXtjb25zdHt3b3JrZXI6dCxyZXNvbHZlcnM6bn09QnJbZV0ud29ya2VyQ29udGV4dDt0JiZyLnB1c2goX28odCxkZS5HTE9CQUxTX1NZTkMsIiIsW3JlXSxuKSl9YXdhaXQgUHJvbWlzZS5hbGwocil9fWZ1bmN0aW9uIEplKHIsZSl7aWYoQXJyYXkuaXNBcnJheShlKSllLnNwbGljZSgwLGUubGVuZ3RoKTtlbHNlIGlmKHR5cGVvZiBlPT0ib2JqZWN0Iilmb3IoY29uc3QgdCBpbiBlKWRlbGV0ZSBlW3RdO2Zvcihjb25zdCB0IGluIHIpQXJyYXkuaXNBcnJheShyW3RdKT8oZVt0XT1bXSxKZShyW3RdLGVbdF0pKTp0eXBlb2Ygclt0XT09Im9iamVjdCI/KGVbdF09e30sSmUoclt0XSxlW3RdKSk6ZVt0XT1yW3RdfWFzeW5jIGZ1bmN0aW9uIGdvKHIsZSl7Y29uc3R7ZnVuY3Rpb25OYW1lOnQsYXJnczpufT1yO2lmKCFlLmluc3RhbmNlKXRocm93Imluc3RhbmNlIG5vdCBpbml0aWFsaXplZCI7aWYoIXQpdGhyb3cibWlzc2luZyBmdW5jdGlvbiBuYW1lIHRvIGNhbGwiO2lmKCFlLmluc3RhbmNlW3RdKXRocm93YHVuZGVmaW5lZCBmdW5jdGlvbiBbJHt0fV0gaW4gY2xhc3MgJHtlLmluc3RhbmNlLmNvbnN0cnVjdG9yLndvcmtlcklkfWA7UGUocixhd2FpdCBlLmluc3RhbmNlW3RdKC4uLm4hPW51bGw/bjpbXSkpfWNvbnN0IGJvPUN0KCJyZWdpc3RlcmVkV29ya2VycyIse30pO2Z1bmN0aW9uIHZvKHIsZSl7aWYoIXIuYXJncyl0aHJvdyJNaXNzaW5nIGNsYXNzTmFtZSB3aGlsZSBpbml0aWFsaXppbmcgd29ya2VyIjtjb25zdFt0LG5dPXIuYXJncyxpPWJvW3RdO2lmKGkpZS5pbnN0YW5jZT1uZXcgaShyLmFyZ3Muc2xpY2UoMSkpO2Vsc2UgdGhyb3dgdW5rbm93biB3b3JrZXIgY2xhc3MgJHt0fWA7SmUobixyZSksUGUocix0eXBlb2YgZS5pbnN0YW5jZSE9PXZvaWQgMCl9YXN5bmMgZnVuY3Rpb24gRW8ocixlKXtjb25zdHthcmdzOnR9PXI7aWYoIWUuaW5zdGFuY2UpdGhyb3ciaW5zdGFuY2Ugbm90IGluaXRpYWxpemVkIjtsZXQgbjtlLmluc3RhbmNlLnRlcm1pbmF0ZSYmKG49YXdhaXQgZS5pbnN0YW5jZS50ZXJtaW5hdGUoLi4udCE9bnVsbD90OltdKSksUGUocixuKX1mdW5jdGlvbiBUbyhyKXtpZighci5hcmdzKXRocm93Ik1pc3NpbmcgZ2xvYmFscyB3aGlsZSBzeW5jaW5nIjtKZShyLmFyZ3NbMF0scmUpLFBlKHIse30pfWZ1bmN0aW9uIEFvKCl7Y29uc3Qgcj17fTtvbm1lc3NhZ2U9YXN5bmMgZT0+e2NvbnN0IHQ9ZS5kYXRhO3N3aXRjaCh0LnR5cGUpe2Nhc2UgZGUuSU5JVDp2byh0LHIpO2JyZWFrO2Nhc2UgZGUuRk9SV0FSRDpnbyh0LHIpO2JyZWFrO2Nhc2UgZGUuVEVSTUlOQVRFOkVvKHQscik7YnJlYWs7Y2FzZSBkZS5HTE9CQUxTX1NZTkM6VG8odCk7YnJlYWt9fX1McigpJiZBbygpO2Z1bmN0aW9uIHdvKHIsZSl7cmV0dXJuIHJlW3JdfHwocmVbcl09ZSksWygpPT5yZVtyXSxhc3luYyB0PT57cmVbcl09dCxhd2FpdCB4bygpfV19ZnVuY3Rpb24gU28ocixlKXtyZXR1cm4gd28ocixlKX1jb25zdFtSbyxzbF09U28oIm1ldGFkYXRhIik7ZnVuY3Rpb24gT3QoKXtyZXR1cm4gUm8oKX1jbGFzcyBJb3tjb25zdHJ1Y3RvcihlKXtzbyh0aGlzLCJ1dWlkIixwbygpKSx0aGlzLmNvbmZpZz1lfWFzeW5jIHNlbmQoZSl7dmFyIHQsbixpO2NvbnN0e2FwcElkOm8sc291cmNlVHlwZTpzfT0odD1PdCgpKSE9bnVsbD90Ont9O2lmKCFvfHwhcylyZXR1cm4ibWV0YWRhdGEgbWlzc2luZyI7Y29uc3QgYT1uZXcgQWJvcnRDb250cm9sbGVyLHU9c2V0VGltZW91dCgoKT0+YS5hYm9ydCgpLGNvKTtyZXR1cm4gYXdhaXQoKGk9KG49dGhpcy5jb25maWcpPT1udWxsP3ZvaWQgMDpuLmZldGNoKSE9bnVsbD9pOmZldGNoKSh0aGlzLmdldFVybCgpLHttZXRob2Q6IlBPU1QiLGhlYWRlcnM6dGhpcy5nZXRIZWFkZXJzKCksYm9keTpKU09OLnN0cmluZ2lmeSh0aGlzLmJ1aWxkUmVwb3J0KGUpKSxzaWduYWw6YS5zaWduYWx9KSxjbGVhclRpbWVvdXQodSksInN1Y2Nlc3MifWdldFVybCgpe3ZhciBlO2xldCB0PShlPU90KCkucHJveHlVcmwpIT1udWxsP2U6dW87cmV0dXJuIHQrPSh0LmF0KC0xKT09PSIvIj8iIjoiLyIpK2FvLHR9Z2V0SGVhZGVycygpe3JldHVybnsiQ29udGVudC1UeXBlIjoiYXBwbGljYXRpb24vanNvbiJ9fWJ1aWxkUmVwb3J0KGUpe2NvbnN0IHQ9T3QoKTtyZXR1cm57Z3VpZDp0aGlzLnV1aWQsLi4uZSxhcHBsaWNhdGlvbklkOnQuYXBwSWQsdGltZXN0YW1wOkRhdGUubm93KCkscHJveHlVcmw6dC5wcm94eVVybCxzb3VyY2U6dC5zb3VyY2VUeXBlfX19Y29uc3QgRm89IjQuMy42Ijt2YXIgWmU9KHI9PihyLkxvdz0iTG93IixyLkhpZ2g9IkhpZ2giLHIpKShaZXx8e30pO2FzeW5jIGZ1bmN0aW9uIEdyKHIpe3JldHVybiBuZXcgUHJvbWlzZShlPT57c2V0VGltZW91dCgoKT0+e2UoKX0scil9KX1jbGFzcyBQb3tjb25zdHJ1Y3RvcihlKXtwKHRoaXMsImNvbnRleHQiKTtwKHRoaXMsImV4dGVuc2lvbiIpO3AodGhpcywicXVlcmllcyIsW10pO3AodGhpcywiYWN0aXZlUXVlcnkiKTt0aGlzLmNvbnRleHQ9ZSx0aGlzLmV4dGVuc2lvbj1lLmdldEV4dGVuc2lvbigiRVhUX2Rpc2pvaW50X3RpbWVyX3F1ZXJ5X3dlYmdsMiIpfXN0YXJ0KCl7fXN0b3AoKXt0aGlzLmFjdGl2ZVF1ZXJ5JiZ0aGlzLmNvbnRleHQuZW5kUXVlcnkodGhpcy5leHRlbnNpb24uVElNRV9FTEFQU0VEX0VYVCl9cHVzaENvbnRleHQoZSl7dGhpcy5jcmVhdGVRdWVyeSgiUFVTSCIsZSl9cG9wQ29udGV4dChlKXt0aGlzLmNyZWF0ZVF1ZXJ5KCJQT1AiLGUpfWNyZWF0ZVF1ZXJ5KGUsdCl7dGhpcy5hY3RpdmVRdWVyeSYmdGhpcy5jb250ZXh0LmVuZFF1ZXJ5KHRoaXMuZXh0ZW5zaW9uLlRJTUVfRUxBUFNFRF9FWFQpLHRoaXMuYWN0aXZlUXVlcnk9dGhpcy5jb250ZXh0LmNyZWF0ZVF1ZXJ5KCksdGhpcy5jb250ZXh0LmJlZ2luUXVlcnkodGhpcy5leHRlbnNpb24uVElNRV9FTEFQU0VEX0VYVCx0aGlzLmFjdGl2ZVF1ZXJ5KSx0aGlzLnF1ZXJpZXMucHVzaCh7bmFtZTp0LGFjdGlvbjplLHF1ZXJ5OnRoaXMuYWN0aXZlUXVlcnl9KX1hc3luYyBnZXRSZXNvbHZlZFF1ZXJpZXMoKXtjb25zdCBlPShhd2FpdCBQcm9taXNlLmFsbChbLi4udGhpcy5xdWVyaWVzXS5tYXAodD0+dGhpcy5yZXNvbHZlUXVlcnkodCkpKSkuZmlsdGVyKHQ9PnQpO2ZvcihsZXQgdD0xO3Q8ZS5sZW5ndGg7Kyt0KWVbdF0udGltZXN0YW1wKz1lW3QtMV0uZHVyYXRpb24rZVt0LTFdLnRpbWVzdGFtcDtyZXR1cm4gZX1hc3luYyByZXNvbHZlUXVlcnkoZSl7aWYoIWF3YWl0IHRoaXMuYXdhaXRRdWVyeUF2YWlsYWJsZShlKSl7Y29uc29sZS5sb2coIlVuYXdhaXRhYmxlIHF1ZXJ5IixlKTtyZXR1cm59aWYodGhpcy5jb250ZXh0LmdldFBhcmFtZXRlcih0aGlzLmV4dGVuc2lvbi5HUFVfRElTSk9JTlRfRVhUKSl7Y29uc29sZS5sb2coIkRpc2pvaW50ZWQgcXVlcnkiLGUpO3JldHVybn1yZXR1cm57Li4uZSxkdXJhdGlvbjp0aGlzLmNvbnRleHQuZ2V0UXVlcnlQYXJhbWV0ZXIoZS5xdWVyeSx0aGlzLmNvbnRleHQuUVVFUllfUkVTVUxUKSx0aW1lc3RhbXA6MH19YXN5bmMgYXdhaXRRdWVyeUF2YWlsYWJsZShlKXtmb3IobGV0IHQ9MDt0PDEwOysrdCl7aWYodGhpcy5jb250ZXh0LmdldFF1ZXJ5UGFyYW1ldGVyKGUucXVlcnksdGhpcy5jb250ZXh0LlFVRVJZX1JFU1VMVF9BVkFJTEFCTEUpKXJldHVybiBlO2F3YWl0IEdyKDIwMCl9fX0vKiBAbGljZW5zZSB0d2dsLmpzIDUuMy4wIENvcHlyaWdodCAoYykgMjAxNSwgR3JlZ2cgVGF2YXJlcyBBbGwgUmlnaHRzIFJlc2VydmVkLgpBdmFpbGFibGUgdmlhIHRoZSBNSVQgbGljZW5zZS4Kc2VlOiBodHRwOi8vZ2l0aHViLmNvbS9ncmVnZ21hbi90d2dsLmpzIGZvciBkZXRhaWxzICovY29uc3QgQnQ9NTEyMCxEZT01MTIxLEx0PTUxMjIsR3Q9NTEyMywkdD01MTI0LHp0PTUxMjUsV3Q9NTEyNixEbz0zMjgxOSxObz0zMjgyMCxNbz0zMzYzNSxVbz01MTMxLGtvPTMzNjQwLENvPTM1ODk5LE9vPTM1OTAyLEJvPTM2MjY5LExvPTM0MDQyLCRyPXt9O3tjb25zdCByPSRyO3JbQnRdPUludDhBcnJheSxyW0RlXT1VaW50OEFycmF5LHJbTHRdPUludDE2QXJyYXkscltHdF09VWludDE2QXJyYXksclskdF09SW50MzJBcnJheSxyW3p0XT1VaW50MzJBcnJheSxyW1d0XT1GbG9hdDMyQXJyYXkscltEb109VWludDE2QXJyYXkscltOb109VWludDE2QXJyYXkscltNb109VWludDE2QXJyYXkscltVb109VWludDE2QXJyYXkscltrb109VWludDMyQXJyYXkscltDb109VWludDMyQXJyYXkscltPb109VWludDMyQXJyYXkscltCb109VWludDMyQXJyYXkscltMb109VWludDMyQXJyYXl9ZnVuY3Rpb24gVnQocil7aWYociBpbnN0YW5jZW9mIEludDhBcnJheSlyZXR1cm4gQnQ7aWYociBpbnN0YW5jZW9mIFVpbnQ4QXJyYXl8fHIgaW5zdGFuY2VvZiBVaW50OENsYW1wZWRBcnJheSlyZXR1cm4gRGU7aWYociBpbnN0YW5jZW9mIEludDE2QXJyYXkpcmV0dXJuIEx0O2lmKHIgaW5zdGFuY2VvZiBVaW50MTZBcnJheSlyZXR1cm4gR3Q7aWYociBpbnN0YW5jZW9mIEludDMyQXJyYXkpcmV0dXJuICR0O2lmKHIgaW5zdGFuY2VvZiBVaW50MzJBcnJheSlyZXR1cm4genQ7aWYociBpbnN0YW5jZW9mIEZsb2F0MzJBcnJheSlyZXR1cm4gV3Q7dGhyb3cgbmV3IEVycm9yKCJ1bnN1cHBvcnRlZCB0eXBlZCBhcnJheSB0eXBlIil9ZnVuY3Rpb24genIocil7aWYocj09PUludDhBcnJheSlyZXR1cm4gQnQ7aWYocj09PVVpbnQ4QXJyYXl8fHI9PT1VaW50OENsYW1wZWRBcnJheSlyZXR1cm4gRGU7aWYocj09PUludDE2QXJyYXkpcmV0dXJuIEx0O2lmKHI9PT1VaW50MTZBcnJheSlyZXR1cm4gR3Q7aWYocj09PUludDMyQXJyYXkpcmV0dXJuICR0O2lmKHI9PT1VaW50MzJBcnJheSlyZXR1cm4genQ7aWYocj09PUZsb2F0MzJBcnJheSlyZXR1cm4gV3Q7dGhyb3cgbmV3IEVycm9yKCJ1bnN1cHBvcnRlZCB0eXBlZCBhcnJheSB0eXBlIil9ZnVuY3Rpb24gV3Iocil7Y29uc3QgZT0kcltyXTtpZighZSl0aHJvdyBuZXcgRXJyb3IoInVua25vd24gZ2wgdHlwZSIpO3JldHVybiBlfWNvbnN0IGV0PXR5cGVvZiBTaGFyZWRBcnJheUJ1ZmZlcjwidSI/ZnVuY3Rpb24oZSl7cmV0dXJuIGUmJmUuYnVmZmVyJiYoZS5idWZmZXIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcnx8ZS5idWZmZXIgaW5zdGFuY2VvZiBTaGFyZWRBcnJheUJ1ZmZlcil9OmZ1bmN0aW9uKGUpe3JldHVybiBlJiZlLmJ1ZmZlciYmZS5idWZmZXIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcn07ZnVuY3Rpb24gVnIoLi4ucil7Y29uc29sZS5lcnJvciguLi5yKX1jb25zdCBIcj1uZXcgTWFwO2Z1bmN0aW9uIHR0KHIsZSl7aWYoIXJ8fHR5cGVvZiByIT0ib2JqZWN0IilyZXR1cm4hMTtsZXQgdD1Ici5nZXQoZSk7dHx8KHQ9bmV3IFdlYWtNYXAsSHIuc2V0KGUsdCkpO2xldCBuPXQuZ2V0KHIpO2lmKG49PT12b2lkIDApe2NvbnN0IGk9T2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHIpO249aS5zdWJzdHJpbmcoOCxpLmxlbmd0aC0xKT09PWUsdC5zZXQocixuKX1yZXR1cm4gbn1mdW5jdGlvbiBHbyhyLGUpe3JldHVybiB0eXBlb2YgV2ViR0xCdWZmZXI8InUiJiZ0dChlLCJXZWJHTEJ1ZmZlciIpfWZ1bmN0aW9uICRvKHIsZSl7cmV0dXJuIHR5cGVvZiBXZWJHTFJlbmRlcmJ1ZmZlcjwidSImJnR0KGUsIldlYkdMUmVuZGVyYnVmZmVyIil9ZnVuY3Rpb24gSHQocixlKXtyZXR1cm4gdHlwZW9mIFdlYkdMVGV4dHVyZTwidSImJnR0KGUsIldlYkdMVGV4dHVyZSIpfWZ1bmN0aW9uIHpvKHIsZSl7cmV0dXJuIHR5cGVvZiBXZWJHTFNhbXBsZXI8InUiJiZ0dChlLCJXZWJHTFNhbXBsZXIiKX1jb25zdCBZcj0zNTA0NCxtZT0zNDk2MixXbz0zNDk2MyxWbz0zNDY2MCxIbz01MTIwLFlvPTUxMjEsam89NTEyMixYbz01MTIzLFFvPTUxMjQsS289NTEyNSxqcj01MTI2LFhyPXthdHRyaWJQcmVmaXg6IiJ9O2Z1bmN0aW9uIHFvKHIsZSx0LG4saSl7ci5iaW5kQnVmZmVyKGUsdCksci5idWZmZXJEYXRhKGUsbixpfHxZcil9ZnVuY3Rpb24gUXIocixlLHQsbil7aWYoR28ocixlKSlyZXR1cm4gZTt0PXR8fG1lO2NvbnN0IGk9ci5jcmVhdGVCdWZmZXIoKTtyZXR1cm4gcW8ocix0LGksZSxuKSxpfWZ1bmN0aW9uIEtyKHIpe3JldHVybiByPT09ImluZGljZXMifWZ1bmN0aW9uIEpvKHIpe3JldHVybiByPT09SW50OEFycmF5fHxyPT09VWludDhBcnJheX1mdW5jdGlvbiBabyhyKXtyZXR1cm4gci5sZW5ndGg/cjpyLmRhdGF9Y29uc3QgZXM9L2Nvb3JkfHRleHR1cmUvaSx0cz0vY29sb3J8Y29sb3VyL2k7ZnVuY3Rpb24gcnMocixlKXtsZXQgdDtpZihlcy50ZXN0KHIpP3Q9Mjp0cy50ZXN0KHIpP3Q9NDp0PTMsZSV0PjApdGhyb3cgbmV3IEVycm9yKGBDYW4gbm90IGd1ZXNzIG51bUNvbXBvbmVudHMgZm9yIGF0dHJpYnV0ZSAnJHtyfScuIFRyaWVkICR7dH0gYnV0ICR7ZX0gdmFsdWVzIGlzIG5vdCBldmVubHkgZGl2aXNpYmxlIGJ5ICR7dH0uIFlvdSBzaG91bGQgc3BlY2lmeSBpdC5gKTtyZXR1cm4gdH1mdW5jdGlvbiBucyhyLGUsdCl7cmV0dXJuIHIubnVtQ29tcG9uZW50c3x8ci5zaXplfHxycyhlLHR8fFpvKHIpLmxlbmd0aCl9ZnVuY3Rpb24gcXIocixlKXtpZihldChyKSlyZXR1cm4gcjtpZihldChyLmRhdGEpKXJldHVybiByLmRhdGE7QXJyYXkuaXNBcnJheShyKSYmKHI9e2RhdGE6cn0pO2xldCB0PXIudHlwZT9ZdChyLnR5cGUpOnZvaWQgMDtyZXR1cm4gdHx8KEtyKGUpP3Q9VWludDE2QXJyYXk6dD1GbG9hdDMyQXJyYXkpLG5ldyB0KHIuZGF0YSl9ZnVuY3Rpb24gaXMocil7cmV0dXJuIHR5cGVvZiByPT0ibnVtYmVyIj9yOnI/enIocik6anJ9ZnVuY3Rpb24gWXQocil7cmV0dXJuIHR5cGVvZiByPT0ibnVtYmVyIj9XcihyKTpyfHxGbG9hdDMyQXJyYXl9ZnVuY3Rpb24gb3MocixlKXtyZXR1cm57YnVmZmVyOmUuYnVmZmVyLG51bVZhbHVlczoyKjMqNCx0eXBlOmlzKGUudHlwZSksYXJyYXlUeXBlOll0KGUudHlwZSl9fWZ1bmN0aW9uIHNzKHIsZSl7Y29uc3QgdD1lLmRhdGF8fGUsbj1ZdChlLnR5cGUpLGk9dCpuLkJZVEVTX1BFUl9FTEVNRU5ULG89ci5jcmVhdGVCdWZmZXIoKTtyZXR1cm4gci5iaW5kQnVmZmVyKG1lLG8pLHIuYnVmZmVyRGF0YShtZSxpLGUuZHJhd1R5cGV8fFlyKSx7YnVmZmVyOm8sbnVtVmFsdWVzOnQsdHlwZTp6cihuKSxhcnJheVR5cGU6bn19ZnVuY3Rpb24gYXMocixlLHQpe2NvbnN0IG49cXIoZSx0KTtyZXR1cm57YXJyYXlUeXBlOm4uY29uc3RydWN0b3IsYnVmZmVyOlFyKHIsbix2b2lkIDAsZS5kcmF3VHlwZSksdHlwZTpWdChuKSxudW1WYWx1ZXM6MH19ZnVuY3Rpb24gdXMocixlKXtjb25zdCB0PXt9O3JldHVybiBPYmplY3Qua2V5cyhlKS5mb3JFYWNoKGZ1bmN0aW9uKG4pe2lmKCFLcihuKSl7Y29uc3QgaT1lW25dLG89aS5hdHRyaWJ8fGkubmFtZXx8aS5hdHRyaWJOYW1lfHxYci5hdHRyaWJQcmVmaXgrbjtpZihpLnZhbHVlKXtpZighQXJyYXkuaXNBcnJheShpLnZhbHVlKSYmIWV0KGkudmFsdWUpKXRocm93IG5ldyBFcnJvcigiYXJyYXkudmFsdWUgaXMgbm90IGFycmF5IG9yIHR5cGVkYXJyYXkiKTt0W29dPXt2YWx1ZTppLnZhbHVlfX1lbHNle2xldCBzO2kuYnVmZmVyJiZpLmJ1ZmZlciBpbnN0YW5jZW9mIFdlYkdMQnVmZmVyP3M9b3M6dHlwZW9mIGk9PSJudW1iZXIifHx0eXBlb2YgaS5kYXRhPT0ibnVtYmVyIj9zPXNzOnM9YXM7Y29uc3R7YnVmZmVyOmEsdHlwZTp1LG51bVZhbHVlczpmLGFycmF5VHlwZTpkfT1zKHIsaSxuKSxoPWkubm9ybWFsaXplIT09dm9pZCAwP2kubm9ybWFsaXplOkpvKGQpLHk9bnMoaSxuLGYpO3Rbb109e2J1ZmZlcjphLG51bUNvbXBvbmVudHM6eSx0eXBlOnUsbm9ybWFsaXplOmgsc3RyaWRlOmkuc3RyaWRlfHwwLG9mZnNldDppLm9mZnNldHx8MCxkaXZpc29yOmkuZGl2aXNvcj09PXZvaWQgMD92b2lkIDA6aS5kaXZpc29yLGRyYXdUeXBlOmkuZHJhd1R5cGV9fX19KSxyLmJpbmRCdWZmZXIobWUsbnVsbCksdH1mdW5jdGlvbiBjcyhyLGUpe3JldHVybiBlPT09SG98fGU9PT1Zbz8xOmU9PT1qb3x8ZT09PVhvPzI6ZT09PVFvfHxlPT09S298fGU9PT1qcj80OjB9Y29uc3QganQ9WyJwb3NpdGlvbiIsInBvc2l0aW9ucyIsImFfcG9zaXRpb24iXTtmdW5jdGlvbiBmcyhyLGUpe2xldCB0LG47Zm9yKG49MDtuPGp0Lmxlbmd0aCYmKHQ9anRbbl0sISh0IGluIGV8fCh0PVhyLmF0dHJpYlByZWZpeCt0LHQgaW4gZSkpKTsrK24pO249PT1qdC5sZW5ndGgmJih0PU9iamVjdC5rZXlzKGUpWzBdKTtjb25zdCBpPWVbdF07aWYoIWkuYnVmZmVyKXJldHVybiAxO3IuYmluZEJ1ZmZlcihtZSxpLmJ1ZmZlcik7Y29uc3Qgbz1yLmdldEJ1ZmZlclBhcmFtZXRlcihtZSxWbyk7ci5iaW5kQnVmZmVyKG1lLG51bGwpO2NvbnN0IHM9Y3MocixpLnR5cGUpLGE9by9zLHU9aS5udW1Db21wb25lbnRzfHxpLnNpemUsZj1hL3U7aWYoZiUxIT09MCl0aHJvdyBuZXcgRXJyb3IoYG51bUNvbXBvbmVudHMgJHt1fSBub3QgY29ycmVjdCBmb3IgbGVuZ3RoICR7bGVuZ3RofWApO3JldHVybiBmfWZ1bmN0aW9uIGxzKHIsZSx0KXtjb25zdCBuPXVzKHIsZSksaT1PYmplY3QuYXNzaWduKHt9LHR8fHt9KTtpLmF0dHJpYnM9T2JqZWN0LmFzc2lnbih7fSx0P3QuYXR0cmliczp7fSxuKTtjb25zdCBvPWUuaW5kaWNlcztpZihvKXtjb25zdCBzPXFyKG8sImluZGljZXMiKTtpLmluZGljZXM9UXIocixzLFdvKSxpLm51bUVsZW1lbnRzPXMubGVuZ3RoLGkuZWxlbWVudFR5cGU9VnQocyl9ZWxzZSBpLm51bUVsZW1lbnRzfHwoaS5udW1FbGVtZW50cz1mcyhyLGkuYXR0cmlicykpO3JldHVybiBpfWZ1bmN0aW9uIE5lKHIpe3JldHVybiEhci50ZXhTdG9yYWdlMkR9Y29uc3QgSnI9ZnVuY3Rpb24oKXtjb25zdCByPXt9LGU9e307ZnVuY3Rpb24gdChuKXtjb25zdCBpPW4uY29uc3RydWN0b3IubmFtZTtpZighcltpXSl7Zm9yKGNvbnN0IG8gaW4gbilpZih0eXBlb2YgbltvXT09Im51bWJlciIpe2NvbnN0IHM9ZVtuW29dXTtlW25bb11dPXM/YCR7c30gfCAke299YDpvfXJbaV09ITB9fXJldHVybiBmdW5jdGlvbihpLG8pe3JldHVybiB0KGkpLGVbb118fCh0eXBlb2Ygbz09Im51bWJlciI/YDB4JHtvLnRvU3RyaW5nKDE2KX1gOm8pfX0oKSxuZT17dGV4dHVyZUNvbG9yOm5ldyBVaW50OEFycmF5KFsxMjgsMTkyLDI1NSwyNTVdKSx0ZXh0dXJlT3B0aW9uczp7fSxjcm9zc09yaWdpbjp2b2lkIDB9LE1lPWV0LFpyPWZ1bmN0aW9uKCl7bGV0IHI7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIHI9cnx8KHR5cGVvZiBkb2N1bWVudDwidSImJmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQ/ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiY2FudmFzIikuZ2V0Q29udGV4dCgiMmQiKTpudWxsKSxyfX0oKSxlbj02NDA2LFE9NjQwNyxGPTY0MDgsdG49NjQwOSxybj02NDEwLFVlPTY0MDIsbm49MzQwNDEscnQ9MzMwNzEsZHM9OTcyOCxtcz05NzI5LGllPTM1NTMsb2U9MzQwNjcsaGU9MzI4NzkscGU9MzU4NjYsWHQ9MzQwNjksaHM9MzQwNzAscHM9MzQwNzEseXM9MzQwNzIsX3M9MzQwNzMseHM9MzQwNzQsUXQ9MTAyNDEsS3Q9MTAyNDAsbnQ9MTAyNDIsaXQ9MTAyNDMsb249MzI4ODIsZ3M9MzMwODIsYnM9MzMwODMsdnM9MzMwODQsRXM9MzMwODUscXQ9MzMxNyxzbj0zMzE0LGFuPTMyODc4LHVuPTMzMTYsY249MzMxNSxmbj0zMjg3NyxUcz0zNzQ0MyxBcz0zNzQ0MSx3cz0zNzQ0MCxTcz0zMzMyMSxScz0zNjc1NixJcz0zMzMyNSxGcz0zMzMyNixQcz0zMzMzMCxEcz0zMzMyOSxOcz0zMzMzOCxNcz0zMzMzNyxVcz0zMzM0MCxrcz0zMzMzOSxDcz0zMzMyMyxPcz0zNjc1NyxCcz0zMzMyNyxMcz0zMzMyOCxHcz0zMzMzNiwkcz0zMzMzNSx6cz0zMzMzMixXcz0zMzMzMSxWcz0zMzMzNCxIcz0zMzMzMyxZcz0zMjg0OSxqcz0zNTkwNSxYcz0zNjE5NCxRcz0zNjc1OCxLcz0zNTg5OCxxcz0zNTkwMSxKcz0zNDg0Myxacz0zNDgzNyxlYT0zNjIyMSx0YT0zNjIzOSxyYT0zNjIxNSxuYT0zNjIzMyxpYT0zNjIwOSxvYT0zNjIyNyxzYT0zMjg1NixhYT0zNTkwNyx1YT0zNjc1OSxjYT0zMjg1NSxmYT0zMjg1NCxsYT0zMjg1NyxkYT0zNDg0MixtYT0zNDgzNixoYT0zNjIyMCxwYT0zNjIzOCx5YT0zNjk3NSxfYT0zNjIxNCx4YT0zNjIzMixnYT0zNjIyNixiYT0zNjIwOCx2YT0zMzE4OSxFYT0zMzE5MCxUYT0zNjAxMixBYT0zNjAxMyx3YT0zNTA1NixzZT01MTIwLFI9NTEyMSxvdD01MTIyLEVlPTUxMjMsc3Q9NTEyNCx5ZT01MTI1LEM9NTEyNixsbj0zMjgxOSxkbj0zMjgyMCxtbj0zMzYzNSxXPTUxMzEsa2U9MzYxOTMsSnQ9MzM2NDAsU2E9MzU4OTksUmE9MzU5MDIsSWE9MzYyNjksRmE9MzQwNDIsYXQ9MzMzMTksVGU9MzMzMjAsdXQ9NjQwMyxBZT0zNjI0NCx3ZT0zNjI0OCxfZT0zNjI0OTtsZXQgWnQ7ZnVuY3Rpb24gY3Qocil7aWYoIVp0KXtjb25zdCBlPXt9O2VbZW5dPXt0ZXh0dXJlRm9ybWF0OmVuLGNvbG9yUmVuZGVyYWJsZTohMCx0ZXh0dXJlRmlsdGVyYWJsZTohMCxieXRlc1BlckVsZW1lbnQ6WzEsMiwyLDRdLHR5cGU6W1IsVyxrZSxDXX0sZVt0bl09e3RleHR1cmVGb3JtYXQ6dG4sY29sb3JSZW5kZXJhYmxlOiEwLHRleHR1cmVGaWx0ZXJhYmxlOiEwLGJ5dGVzUGVyRWxlbWVudDpbMSwyLDIsNF0sdHlwZTpbUixXLGtlLENdfSxlW3JuXT17dGV4dHVyZUZvcm1hdDpybixjb2xvclJlbmRlcmFibGU6ITAsdGV4dHVyZUZpbHRlcmFibGU6ITAsYnl0ZXNQZXJFbGVtZW50OlsyLDQsNCw4XSx0eXBlOltSLFcsa2UsQ119LGVbUV09e3RleHR1cmVGb3JtYXQ6USxjb2xvclJlbmRlcmFibGU6ITAsdGV4dHVyZUZpbHRlcmFibGU6ITAsYnl0ZXNQZXJFbGVtZW50OlszLDYsNiwxMiwyXSx0eXBlOltSLFcsa2UsQyxtbl19LGVbRl09e3RleHR1cmVGb3JtYXQ6Rixjb2xvclJlbmRlcmFibGU6ITAsdGV4dHVyZUZpbHRlcmFibGU6ITAsYnl0ZXNQZXJFbGVtZW50Ols0LDgsOCwxNiwyLDJdLHR5cGU6W1IsVyxrZSxDLGxuLGRuXX0sZVtVZV09e3RleHR1cmVGb3JtYXQ6VWUsY29sb3JSZW5kZXJhYmxlOiEwLHRleHR1cmVGaWx0ZXJhYmxlOiExLGJ5dGVzUGVyRWxlbWVudDpbMiw0XSx0eXBlOlt5ZSxFZV19LGVbU3NdPXt0ZXh0dXJlRm9ybWF0OnV0LGNvbG9yUmVuZGVyYWJsZTohMCx0ZXh0dXJlRmlsdGVyYWJsZTohMCxieXRlc1BlckVsZW1lbnQ6WzFdLHR5cGU6W1JdfSxlW1JzXT17dGV4dHVyZUZvcm1hdDp1dCxjb2xvclJlbmRlcmFibGU6ITEsdGV4dHVyZUZpbHRlcmFibGU6ITAsYnl0ZXNQZXJFbGVtZW50OlsxXSx0eXBlOltzZV19LGVbSXNdPXt0ZXh0dXJlRm9ybWF0OnV0LGNvbG9yUmVuZGVyYWJsZTohMSx0ZXh0dXJlRmlsdGVyYWJsZTohMCxieXRlc1BlckVsZW1lbnQ6WzQsMl0sdHlwZTpbQyxXXX0sZVtGc109e3RleHR1cmVGb3JtYXQ6dXQsY29sb3JSZW5kZXJhYmxlOiExLHRleHR1cmVGaWx0ZXJhYmxlOiExLGJ5dGVzUGVyRWxlbWVudDpbNF0sdHlwZTpbQ119LGVbUHNdPXt0ZXh0dXJlRm9ybWF0OkFlLGNvbG9yUmVuZGVyYWJsZTohMCx0ZXh0dXJlRmlsdGVyYWJsZTohMSxieXRlc1BlckVsZW1lbnQ6WzFdLHR5cGU6W1JdfSxlW0RzXT17dGV4dHVyZUZvcm1hdDpBZSxjb2xvclJlbmRlcmFibGU6ITAsdGV4dHVyZUZpbHRlcmFibGU6ITEsYnl0ZXNQZXJFbGVtZW50OlsxXSx0eXBlOltzZV19LGVbenNdPXt0ZXh0dXJlRm9ybWF0OkFlLGNvbG9yUmVuZGVyYWJsZTohMCx0ZXh0dXJlRmlsdGVyYWJsZTohMSxieXRlc1BlckVsZW1lbnQ6WzJdLHR5cGU6W0VlXX0sZVtXc109e3RleHR1cmVGb3JtYXQ6QWUsY29sb3JSZW5kZXJhYmxlOiEwLHRleHR1cmVGaWx0ZXJhYmxlOiExLGJ5dGVzUGVyRWxlbWVudDpbMl0sdHlwZTpbb3RdfSxlW1ZzXT17dGV4dHVyZUZvcm1hdDpBZSxjb2xvclJlbmRlcmFibGU6ITAsdGV4dHVyZUZpbHRlcmFibGU6ITEsYnl0ZXNQZXJFbGVtZW50Ols0XSx0eXBlOlt5ZV19LGVbSHNdPXt0ZXh0dXJlRm9ybWF0OkFlLGNvbG9yUmVuZGVyYWJsZTohMCx0ZXh0dXJlRmlsdGVyYWJsZTohMSxieXRlc1BlckVsZW1lbnQ6WzRdLHR5cGU6W3N0XX0sZVtDc109e3RleHR1cmVGb3JtYXQ6YXQsY29sb3JSZW5kZXJhYmxlOiEwLHRleHR1cmVGaWx0ZXJhYmxlOiEwLGJ5dGVzUGVyRWxlbWVudDpbMl0sdHlwZTpbUl19LGVbT3NdPXt0ZXh0dXJlRm9ybWF0OmF0LGNvbG9yUmVuZGVyYWJsZTohMSx0ZXh0dXJlRmlsdGVyYWJsZTohMCxieXRlc1BlckVsZW1lbnQ6WzJdLHR5cGU6W3NlXX0sZVtCc109e3RleHR1cmVGb3JtYXQ6YXQsY29sb3JSZW5kZXJhYmxlOiExLHRleHR1cmVGaWx0ZXJhYmxlOiEwLGJ5dGVzUGVyRWxlbWVudDpbOCw0XSx0eXBlOltDLFddfSxlW0xzXT17dGV4dHVyZUZvcm1hdDphdCxjb2xvclJlbmRlcmFibGU6ITEsdGV4dHVyZUZpbHRlcmFibGU6ITEsYnl0ZXNQZXJFbGVtZW50Ols4XSx0eXBlOltDXX0sZVtHc109e3RleHR1cmVGb3JtYXQ6VGUsY29sb3JSZW5kZXJhYmxlOiEwLHRleHR1cmVGaWx0ZXJhYmxlOiExLGJ5dGVzUGVyRWxlbWVudDpbMl0sdHlwZTpbUl19LGVbJHNdPXt0ZXh0dXJlRm9ybWF0OlRlLGNvbG9yUmVuZGVyYWJsZTohMCx0ZXh0dXJlRmlsdGVyYWJsZTohMSxieXRlc1BlckVsZW1lbnQ6WzJdLHR5cGU6W3NlXX0sZVtOc109e3RleHR1cmVGb3JtYXQ6VGUsY29sb3JSZW5kZXJhYmxlOiEwLHRleHR1cmVGaWx0ZXJhYmxlOiExLGJ5dGVzUGVyRWxlbWVudDpbNF0sdHlwZTpbRWVdfSxlW01zXT17dGV4dHVyZUZvcm1hdDpUZSxjb2xvclJlbmRlcmFibGU6ITAsdGV4dHVyZUZpbHRlcmFibGU6ITEsYnl0ZXNQZXJFbGVtZW50Ols0XSx0eXBlOltvdF19LGVbVXNdPXt0ZXh0dXJlRm9ybWF0OlRlLGNvbG9yUmVuZGVyYWJsZTohMCx0ZXh0dXJlRmlsdGVyYWJsZTohMSxieXRlc1BlckVsZW1lbnQ6WzhdLHR5cGU6W3llXX0sZVtrc109e3RleHR1cmVGb3JtYXQ6VGUsY29sb3JSZW5kZXJhYmxlOiEwLHRleHR1cmVGaWx0ZXJhYmxlOiExLGJ5dGVzUGVyRWxlbWVudDpbOF0sdHlwZTpbc3RdfSxlW1lzXT17dGV4dHVyZUZvcm1hdDpRLGNvbG9yUmVuZGVyYWJsZTohMCx0ZXh0dXJlRmlsdGVyYWJsZTohMCxieXRlc1BlckVsZW1lbnQ6WzNdLHR5cGU6W1JdfSxlW2pzXT17dGV4dHVyZUZvcm1hdDpRLGNvbG9yUmVuZGVyYWJsZTohMSx0ZXh0dXJlRmlsdGVyYWJsZTohMCxieXRlc1BlckVsZW1lbnQ6WzNdLHR5cGU6W1JdfSxlW1hzXT17dGV4dHVyZUZvcm1hdDpRLGNvbG9yUmVuZGVyYWJsZTohMCx0ZXh0dXJlRmlsdGVyYWJsZTohMCxieXRlc1BlckVsZW1lbnQ6WzMsMl0sdHlwZTpbUixtbl19LGVbUXNdPXt0ZXh0dXJlRm9ybWF0OlEsY29sb3JSZW5kZXJhYmxlOiExLHRleHR1cmVGaWx0ZXJhYmxlOiEwLGJ5dGVzUGVyRWxlbWVudDpbM10sdHlwZTpbc2VdfSxlW0tzXT17dGV4dHVyZUZvcm1hdDpRLGNvbG9yUmVuZGVyYWJsZTohMSx0ZXh0dXJlRmlsdGVyYWJsZTohMCxieXRlc1BlckVsZW1lbnQ6WzEyLDYsNF0sdHlwZTpbQyxXLFNhXX0sZVtxc109e3RleHR1cmVGb3JtYXQ6USxjb2xvclJlbmRlcmFibGU6ITEsdGV4dHVyZUZpbHRlcmFibGU6ITAsYnl0ZXNQZXJFbGVtZW50OlsxMiw2LDRdLHR5cGU6W0MsVyxSYV19LGVbSnNdPXt0ZXh0dXJlRm9ybWF0OlEsY29sb3JSZW5kZXJhYmxlOiExLHRleHR1cmVGaWx0ZXJhYmxlOiEwLGJ5dGVzUGVyRWxlbWVudDpbMTIsNl0sdHlwZTpbQyxXXX0sZVtac109e3RleHR1cmVGb3JtYXQ6USxjb2xvclJlbmRlcmFibGU6ITEsdGV4dHVyZUZpbHRlcmFibGU6ITEsYnl0ZXNQZXJFbGVtZW50OlsxMl0sdHlwZTpbQ119LGVbZWFdPXt0ZXh0dXJlRm9ybWF0OndlLGNvbG9yUmVuZGVyYWJsZTohMSx0ZXh0dXJlRmlsdGVyYWJsZTohMSxieXRlc1BlckVsZW1lbnQ6WzNdLHR5cGU6W1JdfSxlW3RhXT17dGV4dHVyZUZvcm1hdDp3ZSxjb2xvclJlbmRlcmFibGU6ITEsdGV4dHVyZUZpbHRlcmFibGU6ITEsYnl0ZXNQZXJFbGVtZW50OlszXSx0eXBlOltzZV19LGVbcmFdPXt0ZXh0dXJlRm9ybWF0OndlLGNvbG9yUmVuZGVyYWJsZTohMSx0ZXh0dXJlRmlsdGVyYWJsZTohMSxieXRlc1BlckVsZW1lbnQ6WzZdLHR5cGU6W0VlXX0sZVtuYV09e3RleHR1cmVGb3JtYXQ6d2UsY29sb3JSZW5kZXJhYmxlOiExLHRleHR1cmVGaWx0ZXJhYmxlOiExLGJ5dGVzUGVyRWxlbWVudDpbNl0sdHlwZTpbb3RdfSxlW2lhXT17dGV4dHVyZUZvcm1hdDp3ZSxjb2xvclJlbmRlcmFibGU6ITEsdGV4dHVyZUZpbHRlcmFibGU6ITEsYnl0ZXNQZXJFbGVtZW50OlsxMl0sdHlwZTpbeWVdfSxlW29hXT17dGV4dHVyZUZvcm1hdDp3ZSxjb2xvclJlbmRlcmFibGU6ITEsdGV4dHVyZUZpbHRlcmFibGU6ITEsYnl0ZXNQZXJFbGVtZW50OlsxMl0sdHlwZTpbc3RdfSxlW3NhXT17dGV4dHVyZUZvcm1hdDpGLGNvbG9yUmVuZGVyYWJsZTohMCx0ZXh0dXJlRmlsdGVyYWJsZTohMCxieXRlc1BlckVsZW1lbnQ6WzRdLHR5cGU6W1JdfSxlW2FhXT17dGV4dHVyZUZvcm1hdDpGLGNvbG9yUmVuZGVyYWJsZTohMCx0ZXh0dXJlRmlsdGVyYWJsZTohMCxieXRlc1BlckVsZW1lbnQ6WzRdLHR5cGU6W1JdfSxlW3VhXT17dGV4dHVyZUZvcm1hdDpGLGNvbG9yUmVuZGVyYWJsZTohMSx0ZXh0dXJlRmlsdGVyYWJsZTohMCxieXRlc1BlckVsZW1lbnQ6WzRdLHR5cGU6W3NlXX0sZVtjYV09e3RleHR1cmVGb3JtYXQ6Rixjb2xvclJlbmRlcmFibGU6ITAsdGV4dHVyZUZpbHRlcmFibGU6ITAsYnl0ZXNQZXJFbGVtZW50Ols0LDIsNF0sdHlwZTpbUixkbixKdF19LGVbZmFdPXt0ZXh0dXJlRm9ybWF0OkYsY29sb3JSZW5kZXJhYmxlOiEwLHRleHR1cmVGaWx0ZXJhYmxlOiEwLGJ5dGVzUGVyRWxlbWVudDpbNCwyXSx0eXBlOltSLGxuXX0sZVtsYV09e3RleHR1cmVGb3JtYXQ6Rixjb2xvclJlbmRlcmFibGU6ITAsdGV4dHVyZUZpbHRlcmFibGU6ITAsYnl0ZXNQZXJFbGVtZW50Ols0XSx0eXBlOltKdF19LGVbZGFdPXt0ZXh0dXJlRm9ybWF0OkYsY29sb3JSZW5kZXJhYmxlOiExLHRleHR1cmVGaWx0ZXJhYmxlOiEwLGJ5dGVzUGVyRWxlbWVudDpbMTYsOF0sdHlwZTpbQyxXXX0sZVttYV09e3RleHR1cmVGb3JtYXQ6Rixjb2xvclJlbmRlcmFibGU6ITEsdGV4dHVyZUZpbHRlcmFibGU6ITEsYnl0ZXNQZXJFbGVtZW50OlsxNl0sdHlwZTpbQ119LGVbaGFdPXt0ZXh0dXJlRm9ybWF0Ol9lLGNvbG9yUmVuZGVyYWJsZTohMCx0ZXh0dXJlRmlsdGVyYWJsZTohMSxieXRlc1BlckVsZW1lbnQ6WzRdLHR5cGU6W1JdfSxlW3BhXT17dGV4dHVyZUZvcm1hdDpfZSxjb2xvclJlbmRlcmFibGU6ITAsdGV4dHVyZUZpbHRlcmFibGU6ITEsYnl0ZXNQZXJFbGVtZW50Ols0XSx0eXBlOltzZV19LGVbeWFdPXt0ZXh0dXJlRm9ybWF0Ol9lLGNvbG9yUmVuZGVyYWJsZTohMCx0ZXh0dXJlRmlsdGVyYWJsZTohMSxieXRlc1BlckVsZW1lbnQ6WzRdLHR5cGU6W0p0XX0sZVtfYV09e3RleHR1cmVGb3JtYXQ6X2UsY29sb3JSZW5kZXJhYmxlOiEwLHRleHR1cmVGaWx0ZXJhYmxlOiExLGJ5dGVzUGVyRWxlbWVudDpbOF0sdHlwZTpbRWVdfSxlW3hhXT17dGV4dHVyZUZvcm1hdDpfZSxjb2xvclJlbmRlcmFibGU6ITAsdGV4dHVyZUZpbHRlcmFibGU6ITEsYnl0ZXNQZXJFbGVtZW50Ols4XSx0eXBlOltvdF19LGVbZ2FdPXt0ZXh0dXJlRm9ybWF0Ol9lLGNvbG9yUmVuZGVyYWJsZTohMCx0ZXh0dXJlRmlsdGVyYWJsZTohMSxieXRlc1BlckVsZW1lbnQ6WzE2XSx0eXBlOltzdF19LGVbYmFdPXt0ZXh0dXJlRm9ybWF0Ol9lLGNvbG9yUmVuZGVyYWJsZTohMCx0ZXh0dXJlRmlsdGVyYWJsZTohMSxieXRlc1BlckVsZW1lbnQ6WzE2XSx0eXBlOlt5ZV19LGVbdmFdPXt0ZXh0dXJlRm9ybWF0OlVlLGNvbG9yUmVuZGVyYWJsZTohMCx0ZXh0dXJlRmlsdGVyYWJsZTohMSxieXRlc1BlckVsZW1lbnQ6WzIsNF0sdHlwZTpbRWUseWVdfSxlW0VhXT17dGV4dHVyZUZvcm1hdDpVZSxjb2xvclJlbmRlcmFibGU6ITAsdGV4dHVyZUZpbHRlcmFibGU6ITEsYnl0ZXNQZXJFbGVtZW50Ols0XSx0eXBlOlt5ZV19LGVbVGFdPXt0ZXh0dXJlRm9ybWF0OlVlLGNvbG9yUmVuZGVyYWJsZTohMCx0ZXh0dXJlRmlsdGVyYWJsZTohMSxieXRlc1BlckVsZW1lbnQ6WzRdLHR5cGU6W0NdfSxlW3dhXT17dGV4dHVyZUZvcm1hdDpubixjb2xvclJlbmRlcmFibGU6ITAsdGV4dHVyZUZpbHRlcmFibGU6ITEsYnl0ZXNQZXJFbGVtZW50Ols0XSx0eXBlOltGYV19LGVbQWFdPXt0ZXh0dXJlRm9ybWF0Om5uLGNvbG9yUmVuZGVyYWJsZTohMCx0ZXh0dXJlRmlsdGVyYWJsZTohMSxieXRlc1BlckVsZW1lbnQ6WzRdLHR5cGU6W0lhXX0sT2JqZWN0LmtleXMoZSkuZm9yRWFjaChmdW5jdGlvbih0KXtjb25zdCBuPWVbdF07bi5ieXRlc1BlckVsZW1lbnRNYXA9e30sbi5ieXRlc1BlckVsZW1lbnQuZm9yRWFjaChmdW5jdGlvbihpLG8pe2NvbnN0IHM9bi50eXBlW29dO24uYnl0ZXNQZXJFbGVtZW50TWFwW3NdPWl9KX0pLFp0PWV9cmV0dXJuIFp0W3JdfWZ1bmN0aW9uIFBhKHIsZSl7Y29uc3QgdD1jdChyKTtpZighdCl0aHJvdyJ1bmtub3duIGludGVybmFsIGZvcm1hdCI7Y29uc3Qgbj10LmJ5dGVzUGVyRWxlbWVudE1hcFtlXTtpZihuPT09dm9pZCAwKXRocm93InVua25vd24gaW50ZXJuYWwgZm9ybWF0IjtyZXR1cm4gbn1mdW5jdGlvbiBDZShyKXtjb25zdCBlPWN0KHIpO2lmKCFlKXRocm93InVua25vd24gaW50ZXJuYWwgZm9ybWF0IjtyZXR1cm57Zm9ybWF0OmUudGV4dHVyZUZvcm1hdCx0eXBlOmUudHlwZVswXX19ZnVuY3Rpb24gaG4ocil7cmV0dXJuKHImci0xKT09PTB9ZnVuY3Rpb24gRGEocixlLHQsbil7aWYoIU5lKHIpKXJldHVybiBobihlKSYmaG4odCk7Y29uc3QgaT1jdChuKTtpZighaSl0aHJvdyJ1bmtub3duIGludGVybmFsIGZvcm1hdCI7cmV0dXJuIGkuY29sb3JSZW5kZXJhYmxlJiZpLnRleHR1cmVGaWx0ZXJhYmxlfWZ1bmN0aW9uIE5hKHIpe2NvbnN0IGU9Y3Qocik7aWYoIWUpdGhyb3cidW5rbm93biBpbnRlcm5hbCBmb3JtYXQiO3JldHVybiBlLnRleHR1cmVGaWx0ZXJhYmxlfWZ1bmN0aW9uIE1hKHIsZSx0KXtyZXR1cm4gTWUoZSk/VnQoZSk6dHx8Un1mdW5jdGlvbiBmdChyLGUsdCxuLGkpe2lmKGklMSE9PTApdGhyb3ciY2FuJ3QgZ3Vlc3MgZGltZW5zaW9ucyI7aWYoIXQmJiFuKXtjb25zdCBvPU1hdGguc3FydChpLyhlPT09b2U/NjoxKSk7byUxPT09MD8odD1vLG49byk6KHQ9aSxuPTEpfWVsc2UgaWYobil7aWYoIXQmJih0PWkvbix0JTEpKXRocm93ImNhbid0IGd1ZXNzIGRpbWVuc2lvbnMifWVsc2UgaWYobj1pL3QsbiUxKXRocm93ImNhbid0IGd1ZXNzIGRpbWVuc2lvbnMiO3JldHVybnt3aWR0aDp0LGhlaWdodDpufX1mdW5jdGlvbiBTZShyLGUpe2UuY29sb3JzcGFjZUNvbnZlcnNpb24hPT12b2lkIDAmJnIucGl4ZWxTdG9yZWkoVHMsZS5jb2xvcnNwYWNlQ29udmVyc2lvbiksZS5wcmVtdWx0aXBseUFscGhhIT09dm9pZCAwJiZyLnBpeGVsU3RvcmVpKEFzLGUucHJlbXVsdGlwbHlBbHBoYSksZS5mbGlwWSE9PXZvaWQgMCYmci5waXhlbFN0b3JlaSh3cyxlLmZsaXBZKX1mdW5jdGlvbiBwbihyKXtyLnBpeGVsU3RvcmVpKHF0LDQpLE5lKHIpJiYoci5waXhlbFN0b3JlaShzbiwwKSxyLnBpeGVsU3RvcmVpKGFuLDApLHIucGl4ZWxTdG9yZWkodW4sMCksci5waXhlbFN0b3JlaShjbiwwKSxyLnBpeGVsU3RvcmVpKGZuLDApKX1mdW5jdGlvbiBVYShyLGUsdCxuKXtuLm1pbk1hZyYmKHQuY2FsbChyLGUsUXQsbi5taW5NYWcpLHQuY2FsbChyLGUsS3Qsbi5taW5NYWcpKSxuLm1pbiYmdC5jYWxsKHIsZSxRdCxuLm1pbiksbi5tYWcmJnQuY2FsbChyLGUsS3Qsbi5tYWcpLG4ud3JhcCYmKHQuY2FsbChyLGUsbnQsbi53cmFwKSx0LmNhbGwocixlLGl0LG4ud3JhcCksKGU9PT1oZXx8em8ocixlKSkmJnQuY2FsbChyLGUsb24sbi53cmFwKSksbi53cmFwUiYmdC5jYWxsKHIsZSxvbixuLndyYXBSKSxuLndyYXBTJiZ0LmNhbGwocixlLG50LG4ud3JhcFMpLG4ud3JhcFQmJnQuY2FsbChyLGUsaXQsbi53cmFwVCksbi5taW5Mb2QmJnQuY2FsbChyLGUsZ3Msbi5taW5Mb2QpLG4ubWF4TG9kJiZ0LmNhbGwocixlLGJzLG4ubWF4TG9kKSxuLmJhc2VMZXZlbCYmdC5jYWxsKHIsZSx2cyxuLmJhc2VMZXZlbCksbi5tYXhMZXZlbCYmdC5jYWxsKHIsZSxFcyxuLm1heExldmVsKX1mdW5jdGlvbiB5bihyLGUsdCl7Y29uc3Qgbj10LnRhcmdldHx8aWU7ci5iaW5kVGV4dHVyZShuLGUpLFVhKHIsbixyLnRleFBhcmFtZXRlcmksdCl9ZnVuY3Rpb24ga2Eocil7cmV0dXJuIHI9cnx8bmUudGV4dHVyZUNvbG9yLE1lKHIpP3I6bmV3IFVpbnQ4QXJyYXkoW3JbMF0qMjU1LHJbMV0qMjU1LHJbMl0qMjU1LHJbM10qMjU1XSl9ZnVuY3Rpb24gZXIocixlLHQsbixpLG8pe3Q9dHx8bmUudGV4dHVyZU9wdGlvbnMsbz1vfHxGO2NvbnN0IHM9dC50YXJnZXR8fGllO2lmKG49bnx8dC53aWR0aCxpPWl8fHQuaGVpZ2h0LHIuYmluZFRleHR1cmUocyxlKSxEYShyLG4saSxvKSlyLmdlbmVyYXRlTWlwbWFwKHMpO2Vsc2V7Y29uc3QgYT1OYShvKT9tczpkcztyLnRleFBhcmFtZXRlcmkocyxRdCxhKSxyLnRleFBhcmFtZXRlcmkocyxLdCxhKSxyLnRleFBhcmFtZXRlcmkocyxudCxydCksci50ZXhQYXJhbWV0ZXJpKHMsaXQscnQpfX1mdW5jdGlvbiBPZShyKXtyZXR1cm4gci5hdXRvPT09ITB8fHIuYXV0bz09PXZvaWQgMCYmci5sZXZlbD09PXZvaWQgMH1mdW5jdGlvbiB0cihyLGUpe3JldHVybiBlPWV8fHt9LGUuY3ViZUZhY2VPcmRlcnx8W1h0LGhzLHBzLHlzLF9zLHhzXX1mdW5jdGlvbiBycihyLGUpe2NvbnN0IG49dHIocixlKS5tYXAoZnVuY3Rpb24oaSxvKXtyZXR1cm57ZmFjZTppLG5keDpvfX0pO3JldHVybiBuLnNvcnQoZnVuY3Rpb24oaSxvKXtyZXR1cm4gaS5mYWNlLW8uZmFjZX0pLG59ZnVuY3Rpb24gX24ocixlLHQsbil7bj1ufHxuZS50ZXh0dXJlT3B0aW9ucztjb25zdCBpPW4udGFyZ2V0fHxpZSxvPW4ubGV2ZWx8fDA7bGV0IHM9dC53aWR0aCxhPXQuaGVpZ2h0O2NvbnN0IHU9bi5pbnRlcm5hbEZvcm1hdHx8bi5mb3JtYXR8fEYsZj1DZSh1KSxkPW4uZm9ybWF0fHxmLmZvcm1hdCxoPW4udHlwZXx8Zi50eXBlO2lmKFNlKHIsbiksci5iaW5kVGV4dHVyZShpLGUpLGk9PT1vZSl7Y29uc3QgeT10LndpZHRoLHg9dC5oZWlnaHQ7bGV0IGwsZztpZih5LzY9PT14KWw9eCxnPVswLDAsMSwwLDIsMCwzLDAsNCwwLDUsMF07ZWxzZSBpZih4LzY9PT15KWw9eSxnPVswLDAsMCwxLDAsMiwwLDMsMCw0LDAsNV07ZWxzZSBpZih5LzM9PT14LzIpbD15LzMsZz1bMCwwLDEsMCwyLDAsMCwxLDEsMSwyLDFdO2Vsc2UgaWYoeS8yPT09eC8zKWw9eS8yLGc9WzAsMCwxLDAsMCwxLDEsMSwwLDIsMSwyXTtlbHNlIHRocm93ImNhbid0IGZpZ3VyZSBvdXQgY3ViZSBtYXAgZnJvbSBlbGVtZW50OiAiKyh0LnNyYz90LnNyYzp0Lm5vZGVOYW1lKTtjb25zdCBFPVpyKCk7RT8oRS5jYW52YXMud2lkdGg9bCxFLmNhbnZhcy5oZWlnaHQ9bCxzPWwsYT1sLHJyKHIsbikuZm9yRWFjaChmdW5jdGlvbih2KXtjb25zdCBJPWdbdi5uZHgqMiswXSpsLEQ9Z1t2Lm5keCoyKzFdKmw7RS5kcmF3SW1hZ2UodCxJLEQsbCxsLDAsMCxsLGwpLHIudGV4SW1hZ2UyRCh2LmZhY2Usbyx1LGQsaCxFLmNhbnZhcyl9KSxFLmNhbnZhcy53aWR0aD0xLEUuY2FudmFzLmhlaWdodD0xKTp0eXBlb2YgY3JlYXRlSW1hZ2VCaXRtYXA8InUiJiYocz1sLGE9bCxycihyLG4pLmZvckVhY2goZnVuY3Rpb24odil7Y29uc3QgST1nW3YubmR4KjIrMF0qbCxEPWdbdi5uZHgqMisxXSpsO3IudGV4SW1hZ2UyRCh2LmZhY2Usbyx1LGwsbCwwLGQsaCxudWxsKSxjcmVhdGVJbWFnZUJpdG1hcCh0LEksRCxsLGwse3ByZW11bHRpcGx5QWxwaGE6Im5vbmUiLGNvbG9yU3BhY2VDb252ZXJzaW9uOiJub25lIn0pLnRoZW4oZnVuY3Rpb24oRyl7U2UocixuKSxyLmJpbmRUZXh0dXJlKGksZSksci50ZXhJbWFnZTJEKHYuZmFjZSxvLHUsZCxoLEcpLE9lKG4pJiZlcihyLGUsbixzLGEsdSl9KX0pKX1lbHNlIGlmKGk9PT1oZXx8aT09PXBlKXtjb25zdCB5PU1hdGgubWluKHQud2lkdGgsdC5oZWlnaHQpLHg9TWF0aC5tYXgodC53aWR0aCx0LmhlaWdodCksbD14L3k7aWYobCUxIT09MCl0aHJvdyJjYW4gbm90IGNvbXB1dGUgM0QgZGltZW5zaW9ucyBvZiBlbGVtZW50Ijtjb25zdCBnPXQud2lkdGg9PT14PzE6MCxFPXQuaGVpZ2h0PT09eD8xOjA7ci5waXhlbFN0b3JlaShxdCwxKSxyLnBpeGVsU3RvcmVpKHNuLHQud2lkdGgpLHIucGl4ZWxTdG9yZWkoYW4sMCksci5waXhlbFN0b3JlaShmbiwwKSxyLnRleEltYWdlM0QoaSxvLHUseSx5LHksMCxkLGgsbnVsbCk7Zm9yKGxldCB2PTA7djxsOysrdil7Y29uc3QgST12KnkqZyxEPXYqeSpFO3IucGl4ZWxTdG9yZWkodW4sSSksci5waXhlbFN0b3JlaShjbixEKSxyLnRleFN1YkltYWdlM0QoaSxvLDAsMCx2LHkseSwxLGQsaCx0KX1wbihyKX1lbHNlIHIudGV4SW1hZ2UyRChpLG8sdSxkLGgsdCk7T2UobikmJmVyKHIsZSxuLHMsYSx1KSx5bihyLGUsbil9ZnVuY3Rpb24gQmUoKXt9ZnVuY3Rpb24gQ2Eocil7aWYodHlwZW9mIGRvY3VtZW50PCJ1Iil7Y29uc3QgZT1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJhIik7cmV0dXJuIGUuaHJlZj1yLGUuaG9zdG5hbWU9PT1sb2NhdGlvbi5ob3N0bmFtZSYmZS5wb3J0PT09bG9jYXRpb24ucG9ydCYmZS5wcm90b2NvbD09PWxvY2F0aW9uLnByb3RvY29sfWVsc2V7Y29uc3QgZT1uZXcgVVJMKGxvY2F0aW9uLmhyZWYpLm9yaWdpbjtyZXR1cm4gbmV3IFVSTChyLGxvY2F0aW9uLmhyZWYpLm9yaWdpbj09PWV9fWZ1bmN0aW9uIE9hKHIsZSl7cmV0dXJuIGU9PT12b2lkIDAmJiFDYShyKT8iYW5vbnltb3VzIjplfWZ1bmN0aW9uIEJhKHIsZSx0KXt0PXR8fEJlO2xldCBuO2lmKGU9ZSE9PXZvaWQgMD9lOm5lLmNyb3NzT3JpZ2luLGU9T2EocixlKSx0eXBlb2YgSW1hZ2U8InUiKXtuPW5ldyBJbWFnZSxlIT09dm9pZCAwJiYobi5jcm9zc09yaWdpbj1lKTtjb25zdCBpPWZ1bmN0aW9uKCl7bi5yZW1vdmVFdmVudExpc3RlbmVyKCJlcnJvciIsbyksbi5yZW1vdmVFdmVudExpc3RlbmVyKCJsb2FkIixzKSxuPW51bGx9LG89ZnVuY3Rpb24oKXtjb25zdCB1PSJjb3VsZG4ndCBsb2FkIGltYWdlOiAiK3I7VnIodSksdCh1LG4pLGkoKX0scz1mdW5jdGlvbigpe3QobnVsbCxuKSxpKCl9O3JldHVybiBuLmFkZEV2ZW50TGlzdGVuZXIoImVycm9yIixvKSxuLmFkZEV2ZW50TGlzdGVuZXIoImxvYWQiLHMpLG4uc3JjPXIsbn1lbHNlIGlmKHR5cGVvZiBJbWFnZUJpdG1hcDwidSIpe2xldCBpLG87Y29uc3Qgcz1mdW5jdGlvbigpe3QoaSxvKX0sYT17fTtlJiYoYS5tb2RlPSJjb3JzIiksZmV0Y2gocixhKS50aGVuKGZ1bmN0aW9uKHUpe2lmKCF1Lm9rKXRocm93IHU7cmV0dXJuIHUuYmxvYigpfSkudGhlbihmdW5jdGlvbih1KXtyZXR1cm4gY3JlYXRlSW1hZ2VCaXRtYXAodSx7cHJlbXVsdGlwbHlBbHBoYToibm9uZSIsY29sb3JTcGFjZUNvbnZlcnNpb246Im5vbmUifSl9KS50aGVuKGZ1bmN0aW9uKHUpe289dSxzZXRUaW1lb3V0KHMpfSkuY2F0Y2goZnVuY3Rpb24odSl7aT11LHNldFRpbWVvdXQocyl9KSxuPW51bGx9cmV0dXJuIG59ZnVuY3Rpb24geG4ocil7cmV0dXJuIHR5cGVvZiBJbWFnZUJpdG1hcDwidSImJnIgaW5zdGFuY2VvZiBJbWFnZUJpdG1hcHx8dHlwZW9mIEltYWdlRGF0YTwidSImJnIgaW5zdGFuY2VvZiBJbWFnZURhdGF8fHR5cGVvZiBIVE1MRWxlbWVudDwidSImJnIgaW5zdGFuY2VvZiBIVE1MRWxlbWVudH1mdW5jdGlvbiBucihyLGUsdCl7cmV0dXJuIHhuKHIpPyhzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7dChudWxsLHIpfSkscik6QmEocixlLHQpfWZ1bmN0aW9uIGlyKHIsZSx0KXt0PXR8fG5lLnRleHR1cmVPcHRpb25zO2NvbnN0IG49dC50YXJnZXR8fGllO2lmKHIuYmluZFRleHR1cmUobixlKSx0LmNvbG9yPT09ITEpcmV0dXJuO2NvbnN0IGk9a2EodC5jb2xvcik7aWYobj09PW9lKWZvcihsZXQgbz0wO288NjsrK28pci50ZXhJbWFnZTJEKFh0K28sMCxGLDEsMSwwLEYsUixpKTtlbHNlIG49PT1oZXx8bj09PXBlP3IudGV4SW1hZ2UzRChuLDAsRiwxLDEsMSwwLEYsUixpKTpyLnRleEltYWdlMkQobiwwLEYsMSwxLDAsRixSLGkpfWZ1bmN0aW9uIExhKHIsZSx0LG4pe3JldHVybiBuPW58fEJlLHQ9dHx8bmUudGV4dHVyZU9wdGlvbnMsaXIocixlLHQpLHQ9T2JqZWN0LmFzc2lnbih7fSx0KSxucih0LnNyYyx0LmNyb3NzT3JpZ2luLGZ1bmN0aW9uKG8scyl7bz9uKG8sZSxzKTooX24ocixlLHMsdCksbihudWxsLGUscykpfSl9ZnVuY3Rpb24gR2EocixlLHQsbil7bj1ufHxCZTtjb25zdCBpPXQuc3JjO2lmKGkubGVuZ3RoIT09Nil0aHJvdyJ0aGVyZSBtdXN0IGJlIDYgdXJscyBmb3IgYSBjdWJlbWFwIjtjb25zdCBvPXQubGV2ZWx8fDAscz10LmludGVybmFsRm9ybWF0fHx0LmZvcm1hdHx8RixhPUNlKHMpLHU9dC5mb3JtYXR8fGEuZm9ybWF0LGY9dC50eXBlfHxSLGQ9dC50YXJnZXR8fGllO2lmKGQhPT1vZSl0aHJvdyJ0YXJnZXQgbXVzdCBiZSBURVhUVVJFX0NVQkVfTUFQIjtpcihyLGUsdCksdD1PYmplY3QuYXNzaWduKHt9LHQpO2xldCBoPTY7Y29uc3QgeT1bXSx4PXRyKHIsdCk7bGV0IGw7ZnVuY3Rpb24gZyhFKXtyZXR1cm4gZnVuY3Rpb24odixJKXstLWgsdj95LnB1c2godik6SS53aWR0aCE9PUkuaGVpZ2h0P3kucHVzaCgiY3ViZW1hcCBmYWNlIGltZyBpcyBub3QgYSBzcXVhcmU6ICIrSS5zcmMpOihTZShyLHQpLHIuYmluZFRleHR1cmUoZCxlKSxoPT09NT90cigpLmZvckVhY2goZnVuY3Rpb24oRCl7ci50ZXhJbWFnZTJEKEQsbyxzLHUsZixJKX0pOnIudGV4SW1hZ2UyRChFLG8scyx1LGYsSSksT2UodCkmJnIuZ2VuZXJhdGVNaXBtYXAoZCkpLGg9PT0wJiZuKHkubGVuZ3RoP3k6dm9pZCAwLGUsbCl9fWw9aS5tYXAoZnVuY3Rpb24oRSx2KXtyZXR1cm4gbnIoRSx0LmNyb3NzT3JpZ2luLGcoeFt2XSkpfSl9ZnVuY3Rpb24gJGEocixlLHQsbil7bj1ufHxCZTtjb25zdCBpPXQuc3JjLG89dC5pbnRlcm5hbEZvcm1hdHx8dC5mb3JtYXR8fEYscz1DZShvKSxhPXQuZm9ybWF0fHxzLmZvcm1hdCx1PXQudHlwZXx8UixmPXQudGFyZ2V0fHxwZTtpZihmIT09aGUmJmYhPT1wZSl0aHJvdyJ0YXJnZXQgbXVzdCBiZSBURVhUVVJFXzNEIG9yIFRFWFRVUkVfMkRfQVJSQVkiO2lyKHIsZSx0KSx0PU9iamVjdC5hc3NpZ24oe30sdCk7bGV0IGQ9aS5sZW5ndGg7Y29uc3QgaD1bXTtsZXQgeTtjb25zdCB4PXQubGV2ZWx8fDA7bGV0IGw9dC53aWR0aCxnPXQuaGVpZ2h0O2NvbnN0IEU9aS5sZW5ndGg7bGV0IHY9ITA7ZnVuY3Rpb24gSShEKXtyZXR1cm4gZnVuY3Rpb24oRywkKXtpZigtLWQsRyloLnB1c2goRyk7ZWxzZXtpZihTZShyLHQpLHIuYmluZFRleHR1cmUoZixlKSx2KXt2PSExLGw9dC53aWR0aHx8JC53aWR0aCxnPXQuaGVpZ2h0fHwkLmhlaWdodCxyLnRleEltYWdlM0QoZix4LG8sbCxnLEUsMCxhLHUsbnVsbCk7Zm9yKGxldCBaPTA7WjxFOysrWilyLnRleFN1YkltYWdlM0QoZix4LDAsMCxaLGwsZywxLGEsdSwkKX1lbHNle2xldCBaPSQsSDsoJC53aWR0aCE9PWx8fCQuaGVpZ2h0IT09ZykmJihIPVpyKCksWj1ILmNhbnZhcyxILmNhbnZhcy53aWR0aD1sLEguY2FudmFzLmhlaWdodD1nLEguZHJhd0ltYWdlKCQsMCwwLGwsZykpLHIudGV4U3ViSW1hZ2UzRChmLHgsMCwwLEQsbCxnLDEsYSx1LFopLEgmJlo9PT1ILmNhbnZhcyYmKEguY2FudmFzLndpZHRoPTAsSC5jYW52YXMuaGVpZ2h0PTApfU9lKHQpJiZyLmdlbmVyYXRlTWlwbWFwKGYpfWQ9PT0wJiZuKGgubGVuZ3RoP2g6dm9pZCAwLGUseSl9fXk9aS5tYXAoZnVuY3Rpb24oRCxHKXtyZXR1cm4gbnIoRCx0LmNyb3NzT3JpZ2luLEkoRykpfSl9ZnVuY3Rpb24gemEocixlLHQsbil7bj1ufHxuZS50ZXh0dXJlT3B0aW9ucztjb25zdCBpPW4udGFyZ2V0fHxpZTtyLmJpbmRUZXh0dXJlKGksZSk7bGV0IG89bi53aWR0aCxzPW4uaGVpZ2h0LGE9bi5kZXB0aDtjb25zdCB1PW4ubGV2ZWx8fDAsZj1uLmludGVybmFsRm9ybWF0fHxuLmZvcm1hdHx8RixkPUNlKGYpLGg9bi5mb3JtYXR8fGQuZm9ybWF0LHk9bi50eXBlfHxNYShyLHQsZC50eXBlKTtpZihNZSh0KSl0IGluc3RhbmNlb2YgVWludDhDbGFtcGVkQXJyYXkmJih0PW5ldyBVaW50OEFycmF5KHQuYnVmZmVyKSk7ZWxzZXtjb25zdCBFPVdyKHkpO3Q9bmV3IEUodCl9Y29uc3QgeD1QYShmLHkpLGw9dC5ieXRlTGVuZ3RoL3g7aWYobCUxKXRocm93Imxlbmd0aCB3cm9uZyBzaXplIGZvciBmb3JtYXQ6ICIrSnIocixoKTtsZXQgZztpZihpPT09aGV8fGk9PT1wZSlpZighbyYmIXMmJiFhKXtjb25zdCBFPU1hdGguY2JydChsKTtpZihFJTEhPT0wKXRocm93ImNhbid0IGd1ZXNzIGN1YmUgc2l6ZSBvZiBhcnJheSBvZiBudW1FbGVtZW50czogIitsO289RSxzPUUsYT1FfWVsc2UgbyYmKCFzfHwhYSk/KGc9ZnQocixpLHMsYSxsL28pLHM9Zy53aWR0aCxhPWcuaGVpZ2h0KTpzJiYoIW98fCFhKT8oZz1mdChyLGksbyxhLGwvcyksbz1nLndpZHRoLGE9Zy5oZWlnaHQpOihnPWZ0KHIsaSxvLHMsbC9hKSxvPWcud2lkdGgscz1nLmhlaWdodCk7ZWxzZSBnPWZ0KHIsaSxvLHMsbCksbz1nLndpZHRoLHM9Zy5oZWlnaHQ7aWYocG4ociksci5waXhlbFN0b3JlaShxdCxuLnVucGFja0FsaWdubWVudHx8MSksU2UocixuKSxpPT09b2Upe2NvbnN0IEU9eC90LkJZVEVTX1BFUl9FTEVNRU5ULHY9bC82KkU7cnIocixuKS5mb3JFYWNoKEk9Pntjb25zdCBEPXYqSS5uZHgsRz10LnN1YmFycmF5KEQsRCt2KTtyLnRleEltYWdlMkQoSS5mYWNlLHUsZixvLHMsMCxoLHksRyl9KX1lbHNlIGk9PT1oZXx8aT09PXBlP3IudGV4SW1hZ2UzRChpLHUsZixvLHMsYSwwLGgseSx0KTpyLnRleEltYWdlMkQoaSx1LGYsbyxzLDAsaCx5LHQpO3JldHVybnt3aWR0aDpvLGhlaWdodDpzLGRlcHRoOmEsdHlwZTp5fX1mdW5jdGlvbiBXYShyLGUsdCl7Y29uc3Qgbj10LnRhcmdldHx8aWU7ci5iaW5kVGV4dHVyZShuLGUpO2NvbnN0IGk9dC5sZXZlbHx8MCxvPXQuaW50ZXJuYWxGb3JtYXR8fHQuZm9ybWF0fHxGLHM9Q2UobyksYT10LmZvcm1hdHx8cy5mb3JtYXQsdT10LnR5cGV8fHMudHlwZTtpZihTZShyLHQpLG49PT1vZSlmb3IobGV0IGY9MDtmPDY7KytmKXIudGV4SW1hZ2UyRChYdCtmLGksbyx0LndpZHRoLHQuaGVpZ2h0LDAsYSx1LG51bGwpO2Vsc2Ugbj09PWhlfHxuPT09cGU/ci50ZXhJbWFnZTNEKG4saSxvLHQud2lkdGgsdC5oZWlnaHQsdC5kZXB0aCwwLGEsdSxudWxsKTpyLnRleEltYWdlMkQobixpLG8sdC53aWR0aCx0LmhlaWdodCwwLGEsdSxudWxsKX1mdW5jdGlvbiBnbihyLGUsdCl7dD10fHxCZSxlPWV8fG5lLnRleHR1cmVPcHRpb25zO2NvbnN0IG49ci5jcmVhdGVUZXh0dXJlKCksaT1lLnRhcmdldHx8aWU7bGV0IG89ZS53aWR0aHx8MSxzPWUuaGVpZ2h0fHwxO2NvbnN0IGE9ZS5pbnRlcm5hbEZvcm1hdHx8RjtyLmJpbmRUZXh0dXJlKGksbiksaT09PW9lJiYoci50ZXhQYXJhbWV0ZXJpKGksbnQscnQpLHIudGV4UGFyYW1ldGVyaShpLGl0LHJ0KSk7bGV0IHU9ZS5zcmM7aWYodSlpZih0eXBlb2YgdT09ImZ1bmN0aW9uIiYmKHU9dShyLGUpKSx0eXBlb2YgdT09InN0cmluZyIpTGEocixuLGUsdCk7ZWxzZSBpZihNZSh1KXx8QXJyYXkuaXNBcnJheSh1KSYmKHR5cGVvZiB1WzBdPT0ibnVtYmVyInx8QXJyYXkuaXNBcnJheSh1WzBdKXx8TWUodVswXSkpKXtjb25zdCBmPXphKHIsbix1LGUpO289Zi53aWR0aCxzPWYuaGVpZ2h0fWVsc2UgQXJyYXkuaXNBcnJheSh1KSYmKHR5cGVvZiB1WzBdPT0ic3RyaW5nInx8eG4odVswXSkpP2k9PT1vZT9HYShyLG4sZSx0KTokYShyLG4sZSx0KTooX24ocixuLHUsZSksbz11LndpZHRoLHM9dS5oZWlnaHQpO2Vsc2UgV2EocixuLGUpO3JldHVybiBPZShlKSYmZXIocixuLGUsbyxzLGEpLHluKHIsbixlKSxufWNvbnN0IG9yPVZyO2Z1bmN0aW9uIGJuKHIpe3JldHVybiB0eXBlb2YgZG9jdW1lbnQ8InUiJiZkb2N1bWVudC5nZXRFbGVtZW50QnlJZD9kb2N1bWVudC5nZXRFbGVtZW50QnlJZChyKTpudWxsfWNvbnN0IGx0PTMzOTg0LGR0PTM0OTYyLFZhPTM0OTYzLEhhPTM1NzEzLFlhPTM1NzE0LGphPTM1NjMyLFhhPTM1NjMzLFFhPTM1OTgxLHZuPTM1NzE4LEthPTM1NzIxLHFhPTM1OTcxLEphPTM1MzgyLFphPTM1Mzk2LGV1PTM1Mzk4LHR1PTM1MzkyLHJ1PTM1Mzk1LG10PTUxMjYsRW49MzU2NjQsVG49MzU2NjUsQW49MzU2NjYsc3I9NTEyNCx3bj0zNTY2NyxTbj0zNTY2OCxSbj0zNTY2OSxJbj0zNTY3MCxGbj0zNTY3MSxQbj0zNTY3MixEbj0zNTY3MyxObj0zNTY3NCxNbj0zNTY3NSxVbj0zNTY3NixudT0zNTY3OCxpdT0zNTY4MCxvdT0zNTY3OSxzdT0zNTY4MixhdT0zNTY4NSx1dT0zNTY4NixjdT0zNTY4NyxmdT0zNTY4OCxsdT0zNTY4OSxkdT0zNTY5MCxtdT0zNjI4OSxodT0zNjI5MixwdT0zNjI5Myxhcj01MTI1LGtuPTM2Mjk0LENuPTM2Mjk1LE9uPTM2Mjk2LHl1PTM2Mjk4LF91PTM2Mjk5LHh1PTM2MzAwLGd1PTM2MzAzLGJ1PTM2MzA2LHZ1PTM2MzA3LEV1PTM2MzA4LFR1PTM2MzExLGh0PTM1NTMscHQ9MzQwNjcsdXI9MzI4NzkseXQ9MzU4NjYsYj17fTtmdW5jdGlvbiBCbihyLGUpe3JldHVybiBiW2VdLmJpbmRQb2ludH1mdW5jdGlvbiBBdShyLGUpe3JldHVybiBmdW5jdGlvbih0KXtyLnVuaWZvcm0xZihlLHQpfX1mdW5jdGlvbiB3dShyLGUpe3JldHVybiBmdW5jdGlvbih0KXtyLnVuaWZvcm0xZnYoZSx0KX19ZnVuY3Rpb24gU3UocixlKXtyZXR1cm4gZnVuY3Rpb24odCl7ci51bmlmb3JtMmZ2KGUsdCl9fWZ1bmN0aW9uIFJ1KHIsZSl7cmV0dXJuIGZ1bmN0aW9uKHQpe3IudW5pZm9ybTNmdihlLHQpfX1mdW5jdGlvbiBJdShyLGUpe3JldHVybiBmdW5jdGlvbih0KXtyLnVuaWZvcm00ZnYoZSx0KX19ZnVuY3Rpb24gTG4ocixlKXtyZXR1cm4gZnVuY3Rpb24odCl7ci51bmlmb3JtMWkoZSx0KX19ZnVuY3Rpb24gR24ocixlKXtyZXR1cm4gZnVuY3Rpb24odCl7ci51bmlmb3JtMWl2KGUsdCl9fWZ1bmN0aW9uICRuKHIsZSl7cmV0dXJuIGZ1bmN0aW9uKHQpe3IudW5pZm9ybTJpdihlLHQpfX1mdW5jdGlvbiB6bihyLGUpe3JldHVybiBmdW5jdGlvbih0KXtyLnVuaWZvcm0zaXYoZSx0KX19ZnVuY3Rpb24gV24ocixlKXtyZXR1cm4gZnVuY3Rpb24odCl7ci51bmlmb3JtNGl2KGUsdCl9fWZ1bmN0aW9uIEZ1KHIsZSl7cmV0dXJuIGZ1bmN0aW9uKHQpe3IudW5pZm9ybTF1aShlLHQpfX1mdW5jdGlvbiBQdShyLGUpe3JldHVybiBmdW5jdGlvbih0KXtyLnVuaWZvcm0xdWl2KGUsdCl9fWZ1bmN0aW9uIER1KHIsZSl7cmV0dXJuIGZ1bmN0aW9uKHQpe3IudW5pZm9ybTJ1aXYoZSx0KX19ZnVuY3Rpb24gTnUocixlKXtyZXR1cm4gZnVuY3Rpb24odCl7ci51bmlmb3JtM3VpdihlLHQpfX1mdW5jdGlvbiBNdShyLGUpe3JldHVybiBmdW5jdGlvbih0KXtyLnVuaWZvcm00dWl2KGUsdCl9fWZ1bmN0aW9uIFV1KHIsZSl7cmV0dXJuIGZ1bmN0aW9uKHQpe3IudW5pZm9ybU1hdHJpeDJmdihlLCExLHQpfX1mdW5jdGlvbiBrdShyLGUpe3JldHVybiBmdW5jdGlvbih0KXtyLnVuaWZvcm1NYXRyaXgzZnYoZSwhMSx0KX19ZnVuY3Rpb24gQ3UocixlKXtyZXR1cm4gZnVuY3Rpb24odCl7ci51bmlmb3JtTWF0cml4NGZ2KGUsITEsdCl9fWZ1bmN0aW9uIE91KHIsZSl7cmV0dXJuIGZ1bmN0aW9uKHQpe3IudW5pZm9ybU1hdHJpeDJ4M2Z2KGUsITEsdCl9fWZ1bmN0aW9uIEJ1KHIsZSl7cmV0dXJuIGZ1bmN0aW9uKHQpe3IudW5pZm9ybU1hdHJpeDN4MmZ2KGUsITEsdCl9fWZ1bmN0aW9uIEx1KHIsZSl7cmV0dXJuIGZ1bmN0aW9uKHQpe3IudW5pZm9ybU1hdHJpeDJ4NGZ2KGUsITEsdCl9fWZ1bmN0aW9uIEd1KHIsZSl7cmV0dXJuIGZ1bmN0aW9uKHQpe3IudW5pZm9ybU1hdHJpeDR4MmZ2KGUsITEsdCl9fWZ1bmN0aW9uICR1KHIsZSl7cmV0dXJuIGZ1bmN0aW9uKHQpe3IudW5pZm9ybU1hdHJpeDN4NGZ2KGUsITEsdCl9fWZ1bmN0aW9uIHp1KHIsZSl7cmV0dXJuIGZ1bmN0aW9uKHQpe3IudW5pZm9ybU1hdHJpeDR4M2Z2KGUsITEsdCl9fWZ1bmN0aW9uIEIocixlLHQsbil7Y29uc3QgaT1CbihyLGUpO3JldHVybiBOZShyKT9mdW5jdGlvbihvKXtsZXQgcyxhOyFvfHxIdChyLG8pPyhzPW8sYT1udWxsKToocz1vLnRleHR1cmUsYT1vLnNhbXBsZXIpLHIudW5pZm9ybTFpKG4sdCksci5hY3RpdmVUZXh0dXJlKGx0K3QpLHIuYmluZFRleHR1cmUoaSxzKSxyLmJpbmRTYW1wbGVyKHQsYSl9OmZ1bmN0aW9uKG8pe3IudW5pZm9ybTFpKG4sdCksci5hY3RpdmVUZXh0dXJlKGx0K3QpLHIuYmluZFRleHR1cmUoaSxvKX19ZnVuY3Rpb24gTChyLGUsdCxuLGkpe2NvbnN0IG89Qm4ocixlKSxzPW5ldyBJbnQzMkFycmF5KGkpO2ZvcihsZXQgYT0wO2E8aTsrK2Epc1thXT10K2E7cmV0dXJuIE5lKHIpP2Z1bmN0aW9uKGEpe3IudW5pZm9ybTFpdihuLHMpLGEuZm9yRWFjaChmdW5jdGlvbih1LGYpe3IuYWN0aXZlVGV4dHVyZShsdCtzW2ZdKTtsZXQgZCxoO0h0KHIsdSk/KGQ9dSxoPW51bGwpOihkPXUudGV4dHVyZSxoPXUuc2FtcGxlciksci5iaW5kU2FtcGxlcih0LGgpLHIuYmluZFRleHR1cmUobyxkKX0pfTpmdW5jdGlvbihhKXtyLnVuaWZvcm0xaXYobixzKSxhLmZvckVhY2goZnVuY3Rpb24odSxmKXtyLmFjdGl2ZVRleHR1cmUobHQrc1tmXSksci5iaW5kVGV4dHVyZShvLHUpfSl9fWJbbXRdPXtUeXBlOkZsb2F0MzJBcnJheSxzaXplOjQsc2V0dGVyOkF1LGFycmF5U2V0dGVyOnd1fSxiW0VuXT17VHlwZTpGbG9hdDMyQXJyYXksc2l6ZTo4LHNldHRlcjpTdSxjb2xzOjJ9LGJbVG5dPXtUeXBlOkZsb2F0MzJBcnJheSxzaXplOjEyLHNldHRlcjpSdSxjb2xzOjN9LGJbQW5dPXtUeXBlOkZsb2F0MzJBcnJheSxzaXplOjE2LHNldHRlcjpJdSxjb2xzOjR9LGJbc3JdPXtUeXBlOkludDMyQXJyYXksc2l6ZTo0LHNldHRlcjpMbixhcnJheVNldHRlcjpHbn0sYlt3bl09e1R5cGU6SW50MzJBcnJheSxzaXplOjgsc2V0dGVyOiRuLGNvbHM6Mn0sYltTbl09e1R5cGU6SW50MzJBcnJheSxzaXplOjEyLHNldHRlcjp6bixjb2xzOjN9LGJbUm5dPXtUeXBlOkludDMyQXJyYXksc2l6ZToxNixzZXR0ZXI6V24sY29sczo0fSxiW2FyXT17VHlwZTpVaW50MzJBcnJheSxzaXplOjQsc2V0dGVyOkZ1LGFycmF5U2V0dGVyOlB1fSxiW2tuXT17VHlwZTpVaW50MzJBcnJheSxzaXplOjgsc2V0dGVyOkR1LGNvbHM6Mn0sYltDbl09e1R5cGU6VWludDMyQXJyYXksc2l6ZToxMixzZXR0ZXI6TnUsY29sczozfSxiW09uXT17VHlwZTpVaW50MzJBcnJheSxzaXplOjE2LHNldHRlcjpNdSxjb2xzOjR9LGJbSW5dPXtUeXBlOlVpbnQzMkFycmF5LHNpemU6NCxzZXR0ZXI6TG4sYXJyYXlTZXR0ZXI6R259LGJbRm5dPXtUeXBlOlVpbnQzMkFycmF5LHNpemU6OCxzZXR0ZXI6JG4sY29sczoyfSxiW1BuXT17VHlwZTpVaW50MzJBcnJheSxzaXplOjEyLHNldHRlcjp6bixjb2xzOjN9LGJbRG5dPXtUeXBlOlVpbnQzMkFycmF5LHNpemU6MTYsc2V0dGVyOlduLGNvbHM6NH0sYltObl09e1R5cGU6RmxvYXQzMkFycmF5LHNpemU6MzIsc2V0dGVyOlV1LHJvd3M6Mixjb2xzOjJ9LGJbTW5dPXtUeXBlOkZsb2F0MzJBcnJheSxzaXplOjQ4LHNldHRlcjprdSxyb3dzOjMsY29sczozfSxiW1VuXT17VHlwZTpGbG9hdDMyQXJyYXksc2l6ZTo2NCxzZXR0ZXI6Q3Uscm93czo0LGNvbHM6NH0sYlthdV09e1R5cGU6RmxvYXQzMkFycmF5LHNpemU6MzIsc2V0dGVyOk91LHJvd3M6Mixjb2xzOjN9LGJbdXVdPXtUeXBlOkZsb2F0MzJBcnJheSxzaXplOjMyLHNldHRlcjpMdSxyb3dzOjIsY29sczo0fSxiW2N1XT17VHlwZTpGbG9hdDMyQXJyYXksc2l6ZTo0OCxzZXR0ZXI6QnUscm93czozLGNvbHM6Mn0sYltmdV09e1R5cGU6RmxvYXQzMkFycmF5LHNpemU6NDgsc2V0dGVyOiR1LHJvd3M6Myxjb2xzOjR9LGJbbHVdPXtUeXBlOkZsb2F0MzJBcnJheSxzaXplOjY0LHNldHRlcjpHdSxyb3dzOjQsY29sczoyfSxiW2R1XT17VHlwZTpGbG9hdDMyQXJyYXksc2l6ZTo2NCxzZXR0ZXI6enUscm93czo0LGNvbHM6M30sYltudV09e1R5cGU6bnVsbCxzaXplOjAsc2V0dGVyOkIsYXJyYXlTZXR0ZXI6TCxiaW5kUG9pbnQ6aHR9LGJbaXVdPXtUeXBlOm51bGwsc2l6ZTowLHNldHRlcjpCLGFycmF5U2V0dGVyOkwsYmluZFBvaW50OnB0fSxiW291XT17VHlwZTpudWxsLHNpemU6MCxzZXR0ZXI6QixhcnJheVNldHRlcjpMLGJpbmRQb2ludDp1cn0sYltzdV09e1R5cGU6bnVsbCxzaXplOjAsc2V0dGVyOkIsYXJyYXlTZXR0ZXI6TCxiaW5kUG9pbnQ6aHR9LGJbbXVdPXtUeXBlOm51bGwsc2l6ZTowLHNldHRlcjpCLGFycmF5U2V0dGVyOkwsYmluZFBvaW50Onl0fSxiW2h1XT17VHlwZTpudWxsLHNpemU6MCxzZXR0ZXI6QixhcnJheVNldHRlcjpMLGJpbmRQb2ludDp5dH0sYltwdV09e1R5cGU6bnVsbCxzaXplOjAsc2V0dGVyOkIsYXJyYXlTZXR0ZXI6TCxiaW5kUG9pbnQ6cHR9LGJbeXVdPXtUeXBlOm51bGwsc2l6ZTowLHNldHRlcjpCLGFycmF5U2V0dGVyOkwsYmluZFBvaW50Omh0fSxiW191XT17VHlwZTpudWxsLHNpemU6MCxzZXR0ZXI6QixhcnJheVNldHRlcjpMLGJpbmRQb2ludDp1cn0sYlt4dV09e1R5cGU6bnVsbCxzaXplOjAsc2V0dGVyOkIsYXJyYXlTZXR0ZXI6TCxiaW5kUG9pbnQ6cHR9LGJbZ3VdPXtUeXBlOm51bGwsc2l6ZTowLHNldHRlcjpCLGFycmF5U2V0dGVyOkwsYmluZFBvaW50Onl0fSxiW2J1XT17VHlwZTpudWxsLHNpemU6MCxzZXR0ZXI6QixhcnJheVNldHRlcjpMLGJpbmRQb2ludDpodH0sYlt2dV09e1R5cGU6bnVsbCxzaXplOjAsc2V0dGVyOkIsYXJyYXlTZXR0ZXI6TCxiaW5kUG9pbnQ6dXJ9LGJbRXVdPXtUeXBlOm51bGwsc2l6ZTowLHNldHRlcjpCLGFycmF5U2V0dGVyOkwsYmluZFBvaW50OnB0fSxiW1R1XT17VHlwZTpudWxsLHNpemU6MCxzZXR0ZXI6QixhcnJheVNldHRlcjpMLGJpbmRQb2ludDp5dH07ZnVuY3Rpb24gX3QocixlKXtyZXR1cm4gZnVuY3Rpb24odCl7aWYodC52YWx1ZSlzd2l0Y2goci5kaXNhYmxlVmVydGV4QXR0cmliQXJyYXkoZSksdC52YWx1ZS5sZW5ndGgpe2Nhc2UgNDpyLnZlcnRleEF0dHJpYjRmdihlLHQudmFsdWUpO2JyZWFrO2Nhc2UgMzpyLnZlcnRleEF0dHJpYjNmdihlLHQudmFsdWUpO2JyZWFrO2Nhc2UgMjpyLnZlcnRleEF0dHJpYjJmdihlLHQudmFsdWUpO2JyZWFrO2Nhc2UgMTpyLnZlcnRleEF0dHJpYjFmdihlLHQudmFsdWUpO2JyZWFrO2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKCJ0aGUgbGVuZ3RoIG9mIGEgZmxvYXQgY29uc3RhbnQgdmFsdWUgbXVzdCBiZSBiZXR3ZWVuIDEgYW5kIDQhIil9ZWxzZSByLmJpbmRCdWZmZXIoZHQsdC5idWZmZXIpLHIuZW5hYmxlVmVydGV4QXR0cmliQXJyYXkoZSksci52ZXJ0ZXhBdHRyaWJQb2ludGVyKGUsdC5udW1Db21wb25lbnRzfHx0LnNpemUsdC50eXBlfHxtdCx0Lm5vcm1hbGl6ZXx8ITEsdC5zdHJpZGV8fDAsdC5vZmZzZXR8fDApLHIudmVydGV4QXR0cmliRGl2aXNvciYmci52ZXJ0ZXhBdHRyaWJEaXZpc29yKGUsdC5kaXZpc29yfHwwKX19ZnVuY3Rpb24gYWUocixlKXtyZXR1cm4gZnVuY3Rpb24odCl7aWYodC52YWx1ZSlpZihyLmRpc2FibGVWZXJ0ZXhBdHRyaWJBcnJheShlKSx0LnZhbHVlLmxlbmd0aD09PTQpci52ZXJ0ZXhBdHRyaWI0aXYoZSx0LnZhbHVlKTtlbHNlIHRocm93IG5ldyBFcnJvcigiVGhlIGxlbmd0aCBvZiBhbiBpbnRlZ2VyIGNvbnN0YW50IHZhbHVlIG11c3QgYmUgNCEiKTtlbHNlIHIuYmluZEJ1ZmZlcihkdCx0LmJ1ZmZlciksci5lbmFibGVWZXJ0ZXhBdHRyaWJBcnJheShlKSxyLnZlcnRleEF0dHJpYklQb2ludGVyKGUsdC5udW1Db21wb25lbnRzfHx0LnNpemUsdC50eXBlfHxzcix0LnN0cmlkZXx8MCx0Lm9mZnNldHx8MCksci52ZXJ0ZXhBdHRyaWJEaXZpc29yJiZyLnZlcnRleEF0dHJpYkRpdmlzb3IoZSx0LmRpdmlzb3J8fDApfX1mdW5jdGlvbiB4dChyLGUpe3JldHVybiBmdW5jdGlvbih0KXtpZih0LnZhbHVlKWlmKHIuZGlzYWJsZVZlcnRleEF0dHJpYkFycmF5KGUpLHQudmFsdWUubGVuZ3RoPT09NClyLnZlcnRleEF0dHJpYjR1aXYoZSx0LnZhbHVlKTtlbHNlIHRocm93IG5ldyBFcnJvcigiVGhlIGxlbmd0aCBvZiBhbiB1bnNpZ25lZCBpbnRlZ2VyIGNvbnN0YW50IHZhbHVlIG11c3QgYmUgNCEiKTtlbHNlIHIuYmluZEJ1ZmZlcihkdCx0LmJ1ZmZlciksci5lbmFibGVWZXJ0ZXhBdHRyaWJBcnJheShlKSxyLnZlcnRleEF0dHJpYklQb2ludGVyKGUsdC5udW1Db21wb25lbnRzfHx0LnNpemUsdC50eXBlfHxhcix0LnN0cmlkZXx8MCx0Lm9mZnNldHx8MCksci52ZXJ0ZXhBdHRyaWJEaXZpc29yJiZyLnZlcnRleEF0dHJpYkRpdmlzb3IoZSx0LmRpdmlzb3J8fDApfX1mdW5jdGlvbiBjcihyLGUsdCl7Y29uc3Qgbj10LnNpemUsaT10LmNvdW50O3JldHVybiBmdW5jdGlvbihvKXtyLmJpbmRCdWZmZXIoZHQsby5idWZmZXIpO2NvbnN0IHM9by5zaXplfHxvLm51bUNvbXBvbmVudHN8fG4sYT1zL2ksdT1vLnR5cGV8fG10LGQ9Ylt1XS5zaXplKnMsaD1vLm5vcm1hbGl6ZXx8ITEseT1vLm9mZnNldHx8MCx4PWQvaTtmb3IobGV0IGw9MDtsPGk7KytsKXIuZW5hYmxlVmVydGV4QXR0cmliQXJyYXkoZStsKSxyLnZlcnRleEF0dHJpYlBvaW50ZXIoZStsLGEsdSxoLGQseSt4KmwpLHIudmVydGV4QXR0cmliRGl2aXNvciYmci52ZXJ0ZXhBdHRyaWJEaXZpc29yKGUrbCxvLmRpdmlzb3J8fDApfX1jb25zdCBQPXt9O1BbbXRdPXtzaXplOjQsc2V0dGVyOl90fSxQW0VuXT17c2l6ZTo4LHNldHRlcjpfdH0sUFtUbl09e3NpemU6MTIsc2V0dGVyOl90fSxQW0FuXT17c2l6ZToxNixzZXR0ZXI6X3R9LFBbc3JdPXtzaXplOjQsc2V0dGVyOmFlfSxQW3duXT17c2l6ZTo4LHNldHRlcjphZX0sUFtTbl09e3NpemU6MTIsc2V0dGVyOmFlfSxQW1JuXT17c2l6ZToxNixzZXR0ZXI6YWV9LFBbYXJdPXtzaXplOjQsc2V0dGVyOnh0fSxQW2tuXT17c2l6ZTo4LHNldHRlcjp4dH0sUFtDbl09e3NpemU6MTIsc2V0dGVyOnh0fSxQW09uXT17c2l6ZToxNixzZXR0ZXI6eHR9LFBbSW5dPXtzaXplOjQsc2V0dGVyOmFlfSxQW0ZuXT17c2l6ZTo4LHNldHRlcjphZX0sUFtQbl09e3NpemU6MTIsc2V0dGVyOmFlfSxQW0RuXT17c2l6ZToxNixzZXR0ZXI6YWV9LFBbTm5dPXtzaXplOjQsc2V0dGVyOmNyLGNvdW50OjJ9LFBbTW5dPXtzaXplOjksc2V0dGVyOmNyLGNvdW50OjN9LFBbVW5dPXtzaXplOjE2LHNldHRlcjpjcixjb3VudDo0fTtjb25zdCBXdT0vRVJST1I6XHMqXGQrOihcZCspL2dpO2Z1bmN0aW9uIFZ1KHIsZT0iIix0PTApe2NvbnN0IG49Wy4uLmUubWF0Y2hBbGwoV3UpXSxpPW5ldyBNYXAobi5tYXAoKG8scyk9Pntjb25zdCBhPXBhcnNlSW50KG9bMV0pLHU9bltzKzFdLGY9dT91LmluZGV4OmUubGVuZ3RoLGQ9ZS5zdWJzdHJpbmcoby5pbmRleCxmKTtyZXR1cm5bYS0xLGRdfSkpO3JldHVybiByLnNwbGl0KGAKYCkubWFwKChvLHMpPT57Y29uc3QgYT1pLmdldChzKTtyZXR1cm5gJHtzKzErdH06ICR7b30ke2E/YAoKXl5eICR7YX1gOiIifWB9KS5qb2luKGAKYCl9Y29uc3QgVm49L15bIFx0XSpcbi87ZnVuY3Rpb24gSG4ocil7bGV0IGU9MDtyZXR1cm4gVm4udGVzdChyKSYmKGU9MSxyPXIucmVwbGFjZShWbiwiIikpLHtsaW5lT2Zmc2V0OmUsc2hhZGVyU291cmNlOnJ9fWZ1bmN0aW9uIEh1KHIsZSl7cmV0dXJuIHIuZXJyb3JDYWxsYmFjayhlKSxyLmNhbGxiYWNrJiZzZXRUaW1lb3V0KCgpPT57ci5jYWxsYmFjayhgJHtlfQoke3IuZXJyb3JzLmpvaW4oYApgKX1gKX0pLG51bGx9ZnVuY3Rpb24gWXUocixlLHQsbil7aWYobj1ufHxvciwhci5nZXRTaGFkZXJQYXJhbWV0ZXIodCxIYSkpe2NvbnN0IG89ci5nZXRTaGFkZXJJbmZvTG9nKHQpLHtsaW5lT2Zmc2V0OnMsc2hhZGVyU291cmNlOmF9PUhuKHIuZ2V0U2hhZGVyU291cmNlKHQpKSx1PWAke1Z1KGEsbyxzKX0KRXJyb3IgY29tcGlsaW5nICR7SnIocixlKX06ICR7b31gO3JldHVybiBuKHUpLHV9cmV0dXJuIiJ9ZnVuY3Rpb24gZnIocixlLHQpe2xldCBuLGksbztpZih0eXBlb2YgZT09ImZ1bmN0aW9uIiYmKHQ9ZSxlPXZvaWQgMCksdHlwZW9mIHI9PSJmdW5jdGlvbiIpdD1yLHI9dm9pZCAwO2Vsc2UgaWYociYmIUFycmF5LmlzQXJyYXkocikpe2NvbnN0IGY9cjt0PWYuZXJyb3JDYWxsYmFjayxyPWYuYXR0cmliTG9jYXRpb25zLG49Zi50cmFuc2Zvcm1GZWVkYmFja1ZhcnlpbmdzLGk9Zi50cmFuc2Zvcm1GZWVkYmFja01vZGUsbz1mLmNhbGxiYWNrfWNvbnN0IHM9dHx8b3IsYT1bXSx1PXtlcnJvckNhbGxiYWNrKGYsLi4uZCl7YS5wdXNoKGYpLHMoZiwuLi5kKX0sdHJhbnNmb3JtRmVlZGJhY2tWYXJ5aW5nczpuLHRyYW5zZm9ybUZlZWRiYWNrTW9kZTppLGNhbGxiYWNrOm8sZXJyb3JzOmF9O3tsZXQgZj17fTtBcnJheS5pc0FycmF5KHIpP3IuZm9yRWFjaChmdW5jdGlvbihkLGgpe2ZbZF09ZT9lW2hdOmh9KTpmPXJ8fHt9LHUuYXR0cmliTG9jYXRpb25zPWZ9cmV0dXJuIHV9Y29uc3QganU9WyJWRVJURVhfU0hBREVSIiwiRlJBR01FTlRfU0hBREVSIl07ZnVuY3Rpb24gWHUocixlKXtpZihlLmluZGV4T2YoImZyYWciKT49MClyZXR1cm4gamE7aWYoZS5pbmRleE9mKCJ2ZXJ0Iik+PTApcmV0dXJuIFhhfWZ1bmN0aW9uIFF1KHIsZSx0KXtjb25zdCBuPXIuZ2V0QXR0YWNoZWRTaGFkZXJzKGUpO2Zvcihjb25zdCBpIG9mIG4pdC5oYXMoaSkmJnIuZGVsZXRlU2hhZGVyKGkpO3IuZGVsZXRlUHJvZ3JhbShlKX1jb25zdCBLdT0ocj0wKT0+bmV3IFByb21pc2UoZT0+c2V0VGltZW91dChlLHIpKTtmdW5jdGlvbiBxdShyLGUsdCl7Y29uc3Qgbj1yLmNyZWF0ZVByb2dyYW0oKSx7YXR0cmliTG9jYXRpb25zOmksdHJhbnNmb3JtRmVlZGJhY2tWYXJ5aW5nczpvLHRyYW5zZm9ybUZlZWRiYWNrTW9kZTpzfT1mcih0KTtmb3IobGV0IGE9MDthPGUubGVuZ3RoOysrYSl7bGV0IHU9ZVthXTtpZih0eXBlb2YgdT09InN0cmluZyIpe2NvbnN0IGY9Ym4odSksZD1mP2YudGV4dDp1O2xldCBoPXJbanVbYV1dO2YmJmYudHlwZSYmKGg9WHUocixmLnR5cGUpfHxoKSx1PXIuY3JlYXRlU2hhZGVyKGgpLHIuc2hhZGVyU291cmNlKHUsSG4oZCkuc2hhZGVyU291cmNlKSxyLmNvbXBpbGVTaGFkZXIodSksci5hdHRhY2hTaGFkZXIobix1KX19T2JqZWN0LmVudHJpZXMoaSkuZm9yRWFjaCgoW2EsdV0pPT5yLmJpbmRBdHRyaWJMb2NhdGlvbihuLHUsYSkpO3tsZXQgYT1vO2EmJihhLmF0dHJpYnMmJihhPWEuYXR0cmlicyksQXJyYXkuaXNBcnJheShhKXx8KGE9T2JqZWN0LmtleXMoYSkpLHIudHJhbnNmb3JtRmVlZGJhY2tWYXJ5aW5ncyhuLGEsc3x8UWEpKX1yZXR1cm4gci5saW5rUHJvZ3JhbShuKSxufWZ1bmN0aW9uIEp1KHIsZSx0LG4saSl7Y29uc3Qgbz1mcih0LG4saSkscz1uZXcgU2V0KGUpLGE9cXUocixlLG8pO2Z1bmN0aW9uIHUoZixkKXtjb25zdCBoPWVjKGYsZCxvLmVycm9yQ2FsbGJhY2spO3JldHVybiBoJiZRdShmLGQscyksaH1pZihvLmNhbGxiYWNrKXtadShyLGEpLnRoZW4oKCk9Pntjb25zdCBmPXUocixhKTtvLmNhbGxiYWNrKGYsZj92b2lkIDA6YSl9KTtyZXR1cm59cmV0dXJuIHUocixhKT92b2lkIDA6YX1hc3luYyBmdW5jdGlvbiBadShyLGUpe2NvbnN0IHQ9ci5nZXRFeHRlbnNpb24oIktIUl9wYXJhbGxlbF9zaGFkZXJfY29tcGlsZSIpLG49dD8obyxzKT0+by5nZXRQcm9ncmFtUGFyYW1ldGVyKHMsdC5DT01QTEVUSU9OX1NUQVRVU19LSFIpOigpPT4hMDtsZXQgaT0wO2RvIGF3YWl0IEt1KGkpLGk9MWUzLzYwO3doaWxlKCFuKHIsZSkpfWZ1bmN0aW9uIGVjKHIsZSx0KXtpZih0PXR8fG9yLCFyLmdldFByb2dyYW1QYXJhbWV0ZXIoZSxZYSkpe2NvbnN0IGk9ci5nZXRQcm9ncmFtSW5mb0xvZyhlKTt0KGBFcnJvciBpbiBwcm9ncmFtIGxpbmtpbmc6ICR7aX1gKTtjb25zdCBzPXIuZ2V0QXR0YWNoZWRTaGFkZXJzKGUpLm1hcChhPT5ZdShyLHIuZ2V0U2hhZGVyUGFyYW1ldGVyKGEsci5TSEFERVJfVFlQRSksYSx0KSk7cmV0dXJuYCR7aX0KJHtzLmZpbHRlcihhPT5hKS5qb2luKGAKYCl9YH19ZnVuY3Rpb24gdGMocixlLHQsbixpKXtyZXR1cm4gSnUocixlLHQsbixpKX1mdW5jdGlvbiBZbihyKXtjb25zdCBlPXIubmFtZTtyZXR1cm4gZS5zdGFydHNXaXRoKCJnbF8iKXx8ZS5zdGFydHNXaXRoKCJ3ZWJnbF8iKX1jb25zdCByYz0vKFwufFxbfF18XHcrKS9nLG5jPXI9PnI+PSIwIiYmcjw9IjkiO2Z1bmN0aW9uIGljKHIsZSx0LG4pe2NvbnN0IGk9ci5zcGxpdChyYykuZmlsdGVyKGE9PmEhPT0iIik7bGV0IG89MCxzPSIiO2Zvcig7Oyl7Y29uc3QgYT1pW28rK107cys9YTtjb25zdCB1PW5jKGFbMF0pLGY9dT9wYXJzZUludChhKTphO2lmKHUmJihzKz1pW28rK10pLG89PT1pLmxlbmd0aCl7dFtmXT1lO2JyZWFrfWVsc2V7Y29uc3QgaD1pW28rK10seT1oPT09IlsiLHg9dFtmXXx8KHk/W106e30pO3RbZl09eCx0PXgsbltzXT1uW3NdfHxmdW5jdGlvbihsKXtyZXR1cm4gZnVuY3Rpb24oZyl7am4obCxnKX19KHgpLHMrPWh9fX1mdW5jdGlvbiBvYyhyLGUpe2xldCB0PTA7ZnVuY3Rpb24gbihhLHUsZil7Y29uc3QgZD11Lm5hbWUuZW5kc1dpdGgoIlswXSIpLGg9dS50eXBlLHk9YltoXTtpZigheSl0aHJvdyBuZXcgRXJyb3IoYHVua25vd24gdHlwZTogMHgke2gudG9TdHJpbmcoMTYpfWApO2xldCB4O2lmKHkuYmluZFBvaW50KXtjb25zdCBsPXQ7dCs9dS5zaXplLGQ/eD15LmFycmF5U2V0dGVyKHIsaCxsLGYsdS5zaXplKTp4PXkuc2V0dGVyKHIsaCxsLGYsdS5zaXplKX1lbHNlIHkuYXJyYXlTZXR0ZXImJmQ/eD15LmFycmF5U2V0dGVyKHIsZik6eD15LnNldHRlcihyLGYpO3JldHVybiB4LmxvY2F0aW9uPWYseH1jb25zdCBpPXt9LG89e30scz1yLmdldFByb2dyYW1QYXJhbWV0ZXIoZSx2bik7Zm9yKGxldCBhPTA7YTxzOysrYSl7Y29uc3QgdT1yLmdldEFjdGl2ZVVuaWZvcm0oZSxhKTtpZihZbih1KSljb250aW51ZTtsZXQgZj11Lm5hbWU7Zi5lbmRzV2l0aCgiWzBdIikmJihmPWYuc3Vic3RyKDAsZi5sZW5ndGgtMykpO2NvbnN0IGQ9ci5nZXRVbmlmb3JtTG9jYXRpb24oZSx1Lm5hbWUpO2lmKGQpe2NvbnN0IGg9bihlLHUsZCk7aVtmXT1oLGljKGYsaCxvLGkpfX1yZXR1cm4gaX1mdW5jdGlvbiBzYyhyLGUpe2NvbnN0IHQ9e30sbj1yLmdldFByb2dyYW1QYXJhbWV0ZXIoZSxxYSk7Zm9yKGxldCBpPTA7aTxuOysraSl7Y29uc3Qgbz1yLmdldFRyYW5zZm9ybUZlZWRiYWNrVmFyeWluZyhlLGkpO3Rbby5uYW1lXT17aW5kZXg6aSx0eXBlOm8udHlwZSxzaXplOm8uc2l6ZX19cmV0dXJuIHR9ZnVuY3Rpb24gYWMocixlKXtjb25zdCB0PXIuZ2V0UHJvZ3JhbVBhcmFtZXRlcihlLHZuKSxuPVtdLGk9W107Zm9yKGxldCBhPTA7YTx0OysrYSl7aS5wdXNoKGEpLG4ucHVzaCh7fSk7Y29uc3QgdT1yLmdldEFjdGl2ZVVuaWZvcm0oZSxhKTtuW2FdLm5hbWU9dS5uYW1lfVtbIlVOSUZPUk1fVFlQRSIsInR5cGUiXSxbIlVOSUZPUk1fU0laRSIsInNpemUiXSxbIlVOSUZPUk1fQkxPQ0tfSU5ERVgiLCJibG9ja05keCJdLFsiVU5JRk9STV9PRkZTRVQiLCJvZmZzZXQiXV0uZm9yRWFjaChmdW5jdGlvbihhKXtjb25zdCB1PWFbMF0sZj1hWzFdO3IuZ2V0QWN0aXZlVW5pZm9ybXMoZSxpLHJbdV0pLmZvckVhY2goZnVuY3Rpb24oZCxoKXtuW2hdW2ZdPWR9KX0pO2NvbnN0IG89e30scz1yLmdldFByb2dyYW1QYXJhbWV0ZXIoZSxKYSk7Zm9yKGxldCBhPTA7YTxzOysrYSl7Y29uc3QgdT1yLmdldEFjdGl2ZVVuaWZvcm1CbG9ja05hbWUoZSxhKSxmPXtpbmRleDpyLmdldFVuaWZvcm1CbG9ja0luZGV4KGUsdSksdXNlZEJ5VmVydGV4U2hhZGVyOnIuZ2V0QWN0aXZlVW5pZm9ybUJsb2NrUGFyYW1ldGVyKGUsYSxaYSksdXNlZEJ5RnJhZ21lbnRTaGFkZXI6ci5nZXRBY3RpdmVVbmlmb3JtQmxvY2tQYXJhbWV0ZXIoZSxhLGV1KSxzaXplOnIuZ2V0QWN0aXZlVW5pZm9ybUJsb2NrUGFyYW1ldGVyKGUsYSx0dSksdW5pZm9ybUluZGljZXM6ci5nZXRBY3RpdmVVbmlmb3JtQmxvY2tQYXJhbWV0ZXIoZSxhLHJ1KX07Zi51c2VkPWYudXNlZEJ5VmVydGV4U2hhZGVyfHxmLnVzZWRCeUZyYWdtZW50U2hhZGVyLG9bdV09Zn1yZXR1cm57YmxvY2tTcGVjczpvLHVuaWZvcm1EYXRhOm59fWZ1bmN0aW9uIGpuKHIsZSl7Zm9yKGNvbnN0IHQgaW4gZSl7Y29uc3Qgbj1yW3RdO3R5cGVvZiBuPT0iZnVuY3Rpb24iP24oZVt0XSk6am4oclt0XSxlW3RdKX19ZnVuY3Rpb24gWG4ociwuLi5lKXtjb25zdCB0PXIudW5pZm9ybVNldHRlcnN8fHIsbj1lLmxlbmd0aDtmb3IobGV0IGk9MDtpPG47KytpKXtjb25zdCBvPWVbaV07aWYoQXJyYXkuaXNBcnJheShvKSl7Y29uc3Qgcz1vLmxlbmd0aDtmb3IobGV0IGE9MDthPHM7KythKVhuKHQsb1thXSl9ZWxzZSBmb3IoY29uc3QgcyBpbiBvKXtjb25zdCBhPXRbc107YSYmYShvW3NdKX19fWZ1bmN0aW9uIHVjKHIsZSl7Y29uc3QgdD17fSxuPXIuZ2V0UHJvZ3JhbVBhcmFtZXRlcihlLEthKTtmb3IobGV0IGk9MDtpPG47KytpKXtjb25zdCBvPXIuZ2V0QWN0aXZlQXR0cmliKGUsaSk7aWYoWW4obykpY29udGludWU7Y29uc3Qgcz1yLmdldEF0dHJpYkxvY2F0aW9uKGUsby5uYW1lKSxhPVBbby50eXBlXSx1PWEuc2V0dGVyKHIscyxhKTt1LmxvY2F0aW9uPXMsdFtvLm5hbWVdPXV9cmV0dXJuIHR9ZnVuY3Rpb24gY2MocixlKXtmb3IoY29uc3QgdCBpbiBlKXtjb25zdCBuPXJbdF07biYmbihlW3RdKX19ZnVuY3Rpb24gZmMocixlLHQpe3QudmVydGV4QXJyYXlPYmplY3Q/ci5iaW5kVmVydGV4QXJyYXkodC52ZXJ0ZXhBcnJheU9iamVjdCk6KGNjKGUuYXR0cmliU2V0dGVyc3x8ZSx0LmF0dHJpYnMpLHQuaW5kaWNlcyYmci5iaW5kQnVmZmVyKFZhLHQuaW5kaWNlcykpfWZ1bmN0aW9uIFFuKHIsZSl7Y29uc3QgdD1vYyhyLGUpLG49dWMocixlKSxpPXtwcm9ncmFtOmUsdW5pZm9ybVNldHRlcnM6dCxhdHRyaWJTZXR0ZXJzOm59O3JldHVybiBOZShyKSYmKGkudW5pZm9ybUJsb2NrU3BlYz1hYyhyLGUpLGkudHJhbnNmb3JtRmVlZGJhY2tJbmZvPXNjKHIsZSkpLGl9Y29uc3QgbGM9L1xzfHt8fXw7LztmdW5jdGlvbiBkYyhyLGUsdCxuLGkpe2NvbnN0IG89ZnIodCxuLGkpLHM9W107aWYoZT1lLm1hcChmdW5jdGlvbihmKXtpZighbGMudGVzdChmKSl7Y29uc3QgZD1ibihmKTtpZihkKWY9ZC50ZXh0O2Vsc2V7Y29uc3QgaD1gbm8gZWxlbWVudCB3aXRoIGlkOiAke2Z9YDtvLmVycm9yQ2FsbGJhY2soaCkscy5wdXNoKGgpfX1yZXR1cm4gZn0pLHMubGVuZ3RoKXJldHVybiBIdShvLCIiKTtjb25zdCBhPW8uY2FsbGJhY2s7YSYmKG8uY2FsbGJhY2s9KGYsZCk9PnthKGYsZj92b2lkIDA6UW4ocixkKSl9KTtjb25zdCB1PXRjKHIsZSxvKTtyZXR1cm4gdT9RbihyLHUpOm51bGx9Y29uc3QgbWM9NCxLbj01MTIzO2Z1bmN0aW9uIGhjKHIsZSx0LG4saSxvKXt0PXQ9PT12b2lkIDA/bWM6dDtjb25zdCBzPWUuaW5kaWNlcyxhPWUuZWxlbWVudFR5cGUsdT1uPT09dm9pZCAwP2UubnVtRWxlbWVudHM6bjtpPWk9PT12b2lkIDA/MDppLGF8fHM/byE9PXZvaWQgMD9yLmRyYXdFbGVtZW50c0luc3RhbmNlZCh0LHUsYT09PXZvaWQgMD9LbjplLmVsZW1lbnRUeXBlLGksbyk6ci5kcmF3RWxlbWVudHModCx1LGE9PT12b2lkIDA/S246ZS5lbGVtZW50VHlwZSxpKTpvIT09dm9pZCAwP3IuZHJhd0FycmF5c0luc3RhbmNlZCh0LGksdSxvKTpyLmRyYXdBcnJheXModCxpLHUpfWNvbnN0IHFuPTM2MTYwLGd0PTM2MTYxLHBjPTM1NTMseWM9NTEyMSxfYz02NDAyLHhjPTY0MDgsZ2M9MzMxOTAsYmM9MzYwMTIsdmM9MzUwNTYsRWM9MzYwMTMsVGM9MzI4NTQsQWM9MzI4NTUsd2M9MzYxOTQsSm49MzMxODksWm49NjQwMSxlaT0zNjE2OCxscj0zNDA0MSxkcj0zNjA2NCxidD0zNjA5Nix0aT0zNjEyOCxtcj0zMzMwNixocj0zMzA3MSxwcj05NzI5LFNjPVt7Zm9ybWF0OnhjLHR5cGU6eWMsbWluOnByLHdyYXA6aHJ9LHtmb3JtYXQ6bHJ9XSxWPXt9O1ZbbHJdPW1yLFZbWm5dPXRpLFZbZWldPXRpLFZbX2NdPWJ0LFZbSm5dPWJ0LFZbZ2NdPWJ0LFZbYmNdPWJ0LFZbdmNdPW1yLFZbRWNdPW1yO2Z1bmN0aW9uIFJjKHIsZSl7cmV0dXJuIFZbcl18fFZbZV19Y29uc3QgdWU9e307dWVbVGNdPSEwLHVlW0FjXT0hMCx1ZVt3Y109ITAsdWVbbHJdPSEwLHVlW0puXT0hMCx1ZVtabl09ITAsdWVbZWldPSEwO2Z1bmN0aW9uIEljKHIpe3JldHVybiB1ZVtyXX1jb25zdCBGYz0zMjtmdW5jdGlvbiBQYyhyKXtyZXR1cm4gcj49ZHImJnI8ZHIrRmN9ZnVuY3Rpb24gdnQocixlLHQsbil7Y29uc3QgaT1xbixvPXIuY3JlYXRlRnJhbWVidWZmZXIoKTtyLmJpbmRGcmFtZWJ1ZmZlcihpLG8pLHQ9dHx8ci5kcmF3aW5nQnVmZmVyV2lkdGgsbj1ufHxyLmRyYXdpbmdCdWZmZXJIZWlnaHQsZT1lfHxTYztjb25zdCBzPVtdLGE9e2ZyYW1lYnVmZmVyOm8sYXR0YWNobWVudHM6W10sd2lkdGg6dCxoZWlnaHQ6bn07cmV0dXJuIGUuZm9yRWFjaChmdW5jdGlvbih1LGYpe2xldCBkPXUuYXR0YWNobWVudDtjb25zdCBoPXUuc2FtcGxlcyx5PXUuZm9ybWF0O2xldCB4PXUuYXR0YWNobWVudFBvaW50fHxSYyh5LHUuaW50ZXJuYWxGb3JtYXQpO2lmKHh8fCh4PWRyK2YpLFBjKHgpJiZzLnB1c2goeCksIWQpaWYoaCE9PXZvaWQgMHx8SWMoeSkpZD1yLmNyZWF0ZVJlbmRlcmJ1ZmZlcigpLHIuYmluZFJlbmRlcmJ1ZmZlcihndCxkKSxoPjE/ci5yZW5kZXJidWZmZXJTdG9yYWdlTXVsdGlzYW1wbGUoZ3QsaCx5LHQsbik6ci5yZW5kZXJidWZmZXJTdG9yYWdlKGd0LHksdCxuKTtlbHNle2NvbnN0IGw9T2JqZWN0LmFzc2lnbih7fSx1KTtsLndpZHRoPXQsbC5oZWlnaHQ9bixsLmF1dG89PT12b2lkIDAmJihsLmF1dG89ITEsbC5taW49bC5taW58fGwubWluTWFnfHxwcixsLm1hZz1sLm1hZ3x8bC5taW5NYWd8fHByLGwud3JhcFM9bC53cmFwU3x8bC53cmFwfHxocixsLndyYXBUPWwud3JhcFR8fGwud3JhcHx8aHIpLGQ9Z24ocixsKX1pZigkbyhyLGQpKXIuZnJhbWVidWZmZXJSZW5kZXJidWZmZXIoaSx4LGd0LGQpO2Vsc2UgaWYoSHQocixkKSl1LmxheWVyIT09dm9pZCAwP3IuZnJhbWVidWZmZXJUZXh0dXJlTGF5ZXIoaSx4LGQsdS5sZXZlbHx8MCx1LmxheWVyKTpyLmZyYW1lYnVmZmVyVGV4dHVyZTJEKGkseCx1LnRhcmdldHx8cGMsZCx1LmxldmVsfHwwKTtlbHNlIHRocm93IG5ldyBFcnJvcigidW5rbm93biBhdHRhY2htZW50IHR5cGUiKTthLmF0dGFjaG1lbnRzLnB1c2goZCl9KSxyLmRyYXdCdWZmZXJzJiZyLmRyYXdCdWZmZXJzKHMpLGF9ZnVuY3Rpb24gRGMocixlLHQpe3Q9dHx8cW4sZT8oci5iaW5kRnJhbWVidWZmZXIodCxlLmZyYW1lYnVmZmVyKSxyLnZpZXdwb3J0KDAsMCxlLndpZHRoLGUuaGVpZ2h0KSk6KHIuYmluZEZyYW1lYnVmZmVyKHQsbnVsbCksci52aWV3cG9ydCgwLDAsci5kcmF3aW5nQnVmZmVyV2lkdGgsci5kcmF3aW5nQnVmZmVySGVpZ2h0KSl9ZnVuY3Rpb24gUyhyLGUpe3JldHVybigpPT5lIGluc3RhbmNlb2YgV2ViR0xUZXh0dXJlP2U6Z24ocix7c3JjOmUsd3JhcDpyLkNMQU1QX1RPX0VER0V9KX1jb25zdCByaT0yO2NsYXNzIHhle2NvbnN0cnVjdG9yKGUpe3AodGhpcywiaWQiLCJfIik7cCh0aGlzLCJjb250ZXh0Iik7cCh0aGlzLCJvdXRwdXQiKTtwKHRoaXMsImZiaSIpO3AodGhpcywib3B0aW9ucyIpO3AodGhpcywicHJvZ3JhbUluZm8iKTtwKHRoaXMsImJ1ZmZlckluZm8iKTtwKHRoaXMsInByb2ZpbGVyIik7cCh0aGlzLCJsYXN0UnVuIik7Y29uc3R7Y29udGV4dDp0LHdpZHRoOm4saGVpZ2h0Oml9PWU7dGhpcy5jb250ZXh0PXQsdGhpcy5vcHRpb25zPWU7Y29uc3Qgbz10aGlzLmJ1aWxkRGVmaW5lcygpO3RoaXMucHJvZ3JhbUluZm89ZGModGhpcy5jb250ZXh0LFtvK3RoaXMuZ2V0VmVydGV4U2hhZGVyKCksbyt0aGlzLmdldEZyYWdtZW50U2hhZGVyKCldKSx0aGlzLmJ1ZmZlckluZm89bHModGhpcy5jb250ZXh0LHRoaXMuZ2V0QnVmZmVycygpKSx0aGlzLmZiaT12dCh0aGlzLmNvbnRleHQsW3tmb3JtYXQ6dGhpcy5jb250ZXh0LlJHQkEsdHlwZTp0aGlzLmNvbnRleHQuVU5TSUdORURfQllURSxtaW46dGhpcy5jb250ZXh0LkxJTkVBUix3cmFwOnRoaXMuY29udGV4dC5DTEFNUF9UT19FREdFfV0sbixpKSx0aGlzLm91dHB1dD10aGlzLmZiaS5hdHRhY2htZW50c1swXX1yZXNpemVPdXRwdXQoZSx0KXt0aGlzLmZiaT12dCh0aGlzLmNvbnRleHQsW3tmb3JtYXQ6dGhpcy5jb250ZXh0LlJHQkEsdHlwZTp0aGlzLmNvbnRleHQuVU5TSUdORURfQllURSxtaW46dGhpcy5jb250ZXh0LkxJTkVBUix3cmFwOnRoaXMuY29udGV4dC5DTEFNUF9UT19FREdFfV0sZSx0KSx0aGlzLm9wdGlvbnMud2lkdGg9ZSx0aGlzLm9wdGlvbnMuaGVpZ2h0PXQsdGhpcy5vdXRwdXQ9dGhpcy5mYmkuYXR0YWNobWVudHNbMF19Z2V0RGVmaW5lcygpe3JldHVybnt9fWdldEJ1ZmZlcnMoKXtyZXR1cm57cG9zaXRpb246e251bUNvbXBvbmVudHM6MixkYXRhOlstMSwtMSwtMSwxLDEsLTEsMSwxLC0xLDEsMSwtMV19LHRleHR1cmVfY29vcmQ6e251bUNvbXBvbmVudHM6MixkYXRhOlswLDAsMCwxLDEsMCwxLDEsMCwxLDEsMF19fX1idWlsZERlZmluZXMoKXtsZXQgZT0iIjtjb25zdCB0PXRoaXMuZ2V0RGVmaW5lcygpO2ZvcihsZXQgbiBpbiB0KWUrPWAjZGVmaW5lICR7bn0gJHt0W25dLnRvRml4ZWQoMSl9CmA7cmV0dXJuIGV9cnVuKGUpe3ZhciBpLG8scyxhLHUsZjsoaT10aGlzLnByb2ZpbGVyKT09bnVsbHx8aS5wdXNoQ29udGV4dChgWyR7dGhpcy5pZH1dIFBST0cgOiAke3RoaXMuY29uc3RydWN0b3IubmFtZX1gKSwobz10aGlzLnByb2ZpbGVyKT09bnVsbHx8by5wdXNoQ29udGV4dChgWyR7dGhpcy5pZH1dIFVOSUZPUk1TYCk7Zm9yKGNvbnN0IGQgaW4gZSl0eXBlb2YgZVtkXT09ImZ1bmN0aW9uIiYmKChzPXRoaXMucHJvZmlsZXIpPT1udWxsfHxzLnB1c2hDb250ZXh0KGBbJHt0aGlzLmlkfV0gVU5JIDogJHtkfWApLGVbZF09ZVtkXSgpLChhPXRoaXMucHJvZmlsZXIpPT1udWxsfHxhLnBvcENvbnRleHQoYFske3RoaXMuaWR9XSBVTkkgOiAke2R9YCkpOyh1PXRoaXMucHJvZmlsZXIpPT1udWxsfHx1LnBvcENvbnRleHQoYFske3RoaXMuaWR9XSBVTklGT1JNU2ApO2NvbnN0IHQ9RGF0ZS5ub3coKTtsZXQgbj0wO3RoaXMubGFzdFJ1biYmKG49KHQtdGhpcy5sYXN0UnVuKS8xZTMpLHRoaXMubGFzdFJ1bj10LHRoaXMuY29udGV4dC52aWV3cG9ydCgwLDAsdGhpcy5jb250ZXh0LmNhbnZhcy53aWR0aCx0aGlzLmNvbnRleHQuY2FudmFzLmhlaWdodCksdGhpcy5jb250ZXh0LnVzZVByb2dyYW0odGhpcy5wcm9ncmFtSW5mby5wcm9ncmFtKSxmYyh0aGlzLmNvbnRleHQsdGhpcy5wcm9ncmFtSW5mbyx0aGlzLmJ1ZmZlckluZm8pLFhuKHRoaXMucHJvZ3JhbUluZm8se2RlbHRhOm4sY2FudmFzOlt0aGlzLmNvbnRleHQuY2FudmFzLndpZHRoLHRoaXMuY29udGV4dC5jYW52YXMuaGVpZ2h0XSwuLi5lfSksRGModGhpcy5jb250ZXh0LHRoaXMub3B0aW9ucy5kaXNhYmxlRnJhbWVidWZmZXI/bnVsbDp0aGlzLmZiaSksaGModGhpcy5jb250ZXh0LHRoaXMuYnVmZmVySW5mbyksKGY9dGhpcy5wcm9maWxlcik9PW51bGx8fGYucG9wQ29udGV4dChgWyR7dGhpcy5pZH1dIFBST0cgOiAke3RoaXMuY29uc3RydWN0b3IubmFtZX1gKX1zZXRQcm9maWxlcihlKXt0aGlzLnByb2ZpbGVyPWV9fXZhciBOYz1gcHJlY2lzaW9uIG1lZGl1bXAgZmxvYXQ7Cgp2YXJ5aW5nIHZlYzIgX3RleHR1cmVfY29vcmQ7Cgp1bmlmb3JtIHZlYzIgY2FudmFzOwp1bmlmb3JtIHNhbXBsZXIyRCB0ZXh0dXJlOwp1bmlmb3JtIHNhbXBsZXIyRCBtYXNrOwoKdmVjNCBsb29wKCk7Cgp2b2lkIG1haW4oKSB7IGdsX0ZyYWdDb2xvciA9IGxvb3AoKTsgfQpgLE1jPWB2YXJ5aW5nIHZlYzIgX3RleHR1cmVfY29vcmQ7CgphdHRyaWJ1dGUgdmVjMiBwb3NpdGlvbjsKYXR0cmlidXRlIHZlYzIgdGV4dHVyZV9jb29yZDsKCnZvaWQgbWFpbigpIHsKICBnbF9Qb3NpdGlvbiA9IHZlYzQocG9zaXRpb24sIDAuLCAxLik7CiAgX3RleHR1cmVfY29vcmQgPSB0ZXh0dXJlX2Nvb3JkOwp9CmA7Y2xhc3MgVWMgZXh0ZW5kcyB4ZXtnZXREZWZpbmVzKCl7dmFyIGU7cmV0dXJue1JBRElVUzooZT10aGlzLm9wdGlvbnMucmFkaXVzKSE9bnVsbD9lOjF9fWdldEZyYWdtZW50U2hhZGVyKCl7cmV0dXJuIE5jK3RoaXMuY3JlYXRlTG9vcEZ1bmN0aW9uKCl9Z2V0VmVydGV4U2hhZGVyKCl7cmV0dXJuIE1jfWNyZWF0ZUxvb3BGdW5jdGlvbigpe3ZhciB0O2xldCBlPSh0PXRoaXMub3B0aW9ucy5yYWRpdXMpIT1udWxsP3Q6MTtyZXR1cm5gCgogICAgICAgIHZlYzQgbG9vcCgpIHsgCiAgICAgICAgICAgIHZlYzQgcmVzdWx0ID0gdmVjNCgwLDAsMCwwKTsKICAgICAgICAgICAgZmxvYXQgZmFjdG9yU3VtID0gMC47CgogICAgICAgICAgICB2ZWMyIG5vcm1hbGl6ZWRSYWRpdXMgPSB2ZWMyKC0ke2V9LikgLyBjYW52YXM7CiAgICAgICAgICAgIHZlYzIgbm9ybWFsaXplZEluY3JlbWVudCA9IHZlYzIoMS4pIC8gY2FudmFzOwogICAgICAgICAgICB2ZWMyIGRpZmYgPSBub3JtYWxpemVkUmFkaXVzOwogICAgICAgICAgICBmbG9hdCBtYXhMZW5ndGggPSBsZW5ndGgobm9ybWFsaXplZFJhZGl1cyk7CgogICAgICAgICAgICBmb3IoaW50IHk9LSR7ZX07IHk8JHtlKzF9OyArK3kpIHsKICAgICAgICAgICAgICAgIGZvcihpbnQgeD0tJHtlfTsgeDwke2UrMX07ICsreCkgewogICAgICAgICAgICAgICAgICAgIGZsb2F0IGZhY3RvciA9ICgxLi0gdGV4dHVyZTJEKG1hc2ssIF90ZXh0dXJlX2Nvb3JkICsgZGlmZikuYSkgKiAobWF4TGVuZ3RoIC0gbGVuZ3RoKGRpZmYpKSAvIG1heExlbmd0aDsKICAgICAgICAgICAgICAgICAgICByZXN1bHQgKz0gZmFjdG9yICogdGV4dHVyZTJEKHRleHR1cmUsIF90ZXh0dXJlX2Nvb3JkICsgZGlmZik7CiAgICAgICAgICAgICAgICAgICAgZmFjdG9yU3VtICs9IGZhY3RvcjsKICAgICAgICAgICAgICAgICAgICBkaWZmLnggKz0gbm9ybWFsaXplZEluY3JlbWVudC54OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZGlmZi55ICs9IG5vcm1hbGl6ZWRJbmNyZW1lbnQueTsKICAgICAgICAgICAgICAgIGRpZmYueCA9IG5vcm1hbGl6ZWRSYWRpdXMueDsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gcmVzdWx0IC8gZmFjdG9yU3VtOwogICAgICAgIH1gfX12YXIga2M9YHByZWNpc2lvbiBtZWRpdW1wIGZsb2F0OwoKdmFyeWluZyB2ZWMyIF90ZXh0dXJlX2Nvb3JkOwoKdW5pZm9ybSBzYW1wbGVyMkQgYmFja2dyb3VuZDsKdW5pZm9ybSBzYW1wbGVyMkQgZm9yZWdyb3VuZDsKdW5pZm9ybSBzYW1wbGVyMkQgdGhyZXNob2xkOwoKdm9pZCBtYWluKCkgewogIHZlYzQgYmFja2dyb3VuZENvbG9yID0gdGV4dHVyZTJEKGJhY2tncm91bmQsIF90ZXh0dXJlX2Nvb3JkKTsKICB2ZWM0IGZvcmVncm91bmRDb2xvciA9IHRleHR1cmUyRChmb3JlZ3JvdW5kLCBfdGV4dHVyZV9jb29yZCk7CiAgdmVjNCB0cmVzaG9sZENvbG9yID0gdGV4dHVyZTJEKHRocmVzaG9sZCwgX3RleHR1cmVfY29vcmQpOwogIGdsX0ZyYWdDb2xvciA9IGZvcmVncm91bmRDb2xvciAqIHRyZXNob2xkQ29sb3IuYSArCiAgICAgICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yICogKDEuIC0gdHJlc2hvbGRDb2xvci5hKTsKfQpgLENjPWB2YXJ5aW5nIHZlYzIgX3RleHR1cmVfY29vcmQ7CgphdHRyaWJ1dGUgdmVjMiBwb3NpdGlvbjsKYXR0cmlidXRlIHZlYzIgdGV4dHVyZV9jb29yZDsKCnZvaWQgbWFpbigpIHsKICBnbF9Qb3NpdGlvbiA9IHZlYzQocG9zaXRpb24sIDAuLCAxLik7CiAgX3RleHR1cmVfY29vcmQgPSB0ZXh0dXJlX2Nvb3JkOwogIF90ZXh0dXJlX2Nvb3JkLnkgPSAxLiAtIHRleHR1cmVfY29vcmQueTsKfQpgO2NsYXNzIHlyIGV4dGVuZHMgeGV7Z2V0RnJhZ21lbnRTaGFkZXIoKXtyZXR1cm4ga2N9Z2V0VmVydGV4U2hhZGVyKCl7cmV0dXJuIENjfX1jbGFzcyBfcntjb25zdHJ1Y3Rvcigpe3AodGhpcywic3RlcHMiLFtdKTtwKHRoaXMsInByb2ZpbGVyIil9YWRkU3RlcChlKXt0aGlzLnN0ZXBzLnB1c2goZSl9YXN5bmMgcnVuKCl7Zm9yKGNvbnN0IGUgb2YgdGhpcy5zdGVwcyllLnByb2dyYW0ucnVuKGUuZ2V0VW5pZm9ybXMoKSl9cmVzaXplT3V0cHV0KGUsdCl7dmFyIG4saTsobj10aGlzLnByb2ZpbGVyKT09bnVsbHx8bi5wdXNoQ29udGV4dChgUElQIFske3RoaXMuY29uc3RydWN0b3IubmFtZX1dYCk7Zm9yKGNvbnN0IG8gb2YgdGhpcy5zdGVwcylvLnByZXZlbnRSZXNpemV8fG8ucHJvZ3JhbS5yZXNpemVPdXRwdXQoZSx0KTsoaT10aGlzLnByb2ZpbGVyKT09bnVsbHx8aS5wb3BDb250ZXh0KGBQSVAgWyR7dGhpcy5jb25zdHJ1Y3Rvci5uYW1lfV1gKX1zZXRQcm9maWxlcihlKXt0aGlzLnByb2ZpbGVyPWU7Zm9yKGNvbnN0IHQgb2YgdGhpcy5zdGVwcyl0LnByb2dyYW0uc2V0UHJvZmlsZXIoZSl9c2V0SWQoZSl7Zm9yKGNvbnN0IHQgb2YgdGhpcy5zdGVwcyl0LnByb2dyYW0uaWQ9ZX19Y2xhc3MgeHIgZXh0ZW5kcyBfcntjb25zdHJ1Y3Rvcigpe3N1cGVyKC4uLmFyZ3VtZW50cyk7cCh0aGlzLCJwcmVjaXNlTWFza0VuYWJsZWQiLCExKX19Y29uc3QgT2M9MTAsQmM9MixMYz04O2NsYXNzIEdjIGV4dGVuZHMgeHJ7Y29uc3RydWN0b3IodCxuKXtzdXBlcigpO3AodGhpcywiaW5wdXRJbWFnZSIpO3AodGhpcywiaW5wdXRNYXNrIik7cCh0aGlzLCJibHVyIik7dGhpcy5jb250ZXh0PXQsdGhpcy5yYWRpdXM9bjtjb25zdCBpPXtjb250ZXh0OnQsaGVpZ2h0OnQuY2FudmFzLmhlaWdodCx3aWR0aDp0LmNhbnZhcy53aWR0aH07dGhpcy5ibHVyPW5ldyBVYyh7Li4uaSxyYWRpdXM6biwuLi50aGlzLmdldEJsdXJUZXh0dXJlU2l6ZSh0LmNhbnZhcy53aWR0aCx0LmNhbnZhcy5oZWlnaHQpfSk7Y29uc3Qgbz1uZXcgeXIoey4uLmksZGlzYWJsZUZyYW1lYnVmZmVyOiEwfSk7dGhpcy5hZGRTdGVwKHtwcm9ncmFtOnRoaXMuYmx1cixwcmV2ZW50UmVzaXplOiEwLGdldFVuaWZvcm1zOigpPT4oe3RleHR1cmU6Uyh0LHRoaXMuaW5wdXRJbWFnZSksbWFzazpTKHQsdGhpcy5pbnB1dE1hc2spfSl9KSx0aGlzLmFkZFN0ZXAoe3Byb2dyYW06byxnZXRVbmlmb3JtczooKT0+KHtiYWNrZ3JvdW5kOlModCx0aGlzLmJsdXIub3V0cHV0KSxmb3JlZ3JvdW5kOlModCx0aGlzLmlucHV0SW1hZ2UpLHRocmVzaG9sZDpTKHQsdGhpcy5pbnB1dE1hc2spfSl9KX1nZXRCbHVyVGV4dHVyZVNpemUodCxuKXtjb25zdCBpPXRoaXMucmFkaXVzPk9jP0xjOkJjO3JldHVybnt3aWR0aDpNYXRoLm1heChyaSx0L2kpLGhlaWdodDpNYXRoLm1heChyaSxuL2kpfX1zZXREYXRhKHQsbil7dGhpcy5pbnB1dEltYWdlPXQsdGhpcy5pbnB1dE1hc2s9bn1yZXNpemVPdXRwdXQodCxuKXtzdXBlci5yZXNpemVPdXRwdXQodCxuKTtjb25zdCBpPXRoaXMuZ2V0Qmx1clRleHR1cmVTaXplKHQsbik7dGhpcy5ibHVyLnJlc2l6ZU91dHB1dChpLndpZHRoLGkuaGVpZ2h0KX19Y2xhc3MgbmkgZXh0ZW5kcyB4cntjb25zdHJ1Y3Rvcih0KXtzdXBlcigpO3AodGhpcywiaW5wdXRJbWFnZSIpO3AodGhpcywiaW5wdXRCYWNrZ3JvdW5kSW1hZ2UiKTtwKHRoaXMsImlucHV0TWFzayIpO3AodGhpcywicHJlY2lzZU1hc2tFbmFibGVkIiwhMCk7dGhpcy5jb250ZXh0PXQ7Y29uc3Qgbj17Y29udGV4dDp0LGhlaWdodDp0LmNhbnZhcy5oZWlnaHQsd2lkdGg6dC5jYW52YXMud2lkdGh9LGk9bmV3IHlyKHsuLi5uLGRpc2FibGVGcmFtZWJ1ZmZlcjohMH0pO3RoaXMuYWRkU3RlcCh7cHJvZ3JhbTppLGdldFVuaWZvcm1zOigpPT4oe2JhY2tncm91bmQ6Uyh0LHRoaXMuaW5wdXRCYWNrZ3JvdW5kSW1hZ2UpLGZvcmVncm91bmQ6Uyh0LHRoaXMuaW5wdXRJbWFnZSksdGhyZXNob2xkOlModCx0aGlzLmlucHV0TWFzayl9KX0pfXNldERhdGEodCxuKXt0aGlzLmlucHV0SW1hZ2U9dCx0aGlzLmlucHV0TWFzaz1ufX1jbGFzcyAkYyBleHRlbmRzIG5pe2NvbnN0cnVjdG9yKCl7c3VwZXIoLi4uYXJndW1lbnRzKTtwKHRoaXMsImZyYW1lUmVhZGVyIik7cCh0aGlzLCJwcmVjaXNlTWFza0VuYWJsZWQiLCEwKX1zZXQgaW5wdXRWaWRlbyh0KXt0aGlzLmZyYW1lUmVhZGVyPXQuZ2V0UmVhZGVyKCksdGhpcy5yZWFkTmV4dFZpZGVvRnJhbWUoKX1hc3luYyBydW4oKXt0aGlzLmZyYW1lUmVhZGVyJiYoYXdhaXQgc3VwZXIucnVuKCksdGhpcy5yZWFkTmV4dFZpZGVvRnJhbWUoKSl9YXN5bmMgcmVhZE5leHRWaWRlb0ZyYW1lKCl7dmFyIG47Y29uc3QgdD1hd2FpdCgobj10aGlzLmZyYW1lUmVhZGVyKT09bnVsbD92b2lkIDA6bi5yZWFkKCkpO3QhPW51bGwmJnQudmFsdWUmJih0aGlzLmlucHV0QmFja2dyb3VuZEltYWdlPWF3YWl0IGNyZWF0ZUltYWdlQml0bWFwKHQudmFsdWUpLHQudmFsdWUuY2xvc2UoKSl9fXZhciB6Yz1gcHJlY2lzaW9uIG1lZGl1bXAgZmxvYXQ7Cgp2YXJ5aW5nIHZlYzIgX3RleHR1cmVfY29vcmQ7Cgp1bmlmb3JtIHZlYzIgY2FudmFzOwp1bmlmb3JtIHNhbXBsZXIyRCB0ZXh0dXJlOwoKdmVjNCBsb29wKCk7Cgp2b2lkIG1haW4oKSB7IGdsX0ZyYWdDb2xvciA9IGxvb3AoKTsgfQpgLFdjPWB2YXJ5aW5nIHZlYzIgX3RleHR1cmVfY29vcmQ7CgphdHRyaWJ1dGUgdmVjMiBwb3NpdGlvbjsKYXR0cmlidXRlIHZlYzIgdGV4dHVyZV9jb29yZDsKCnZvaWQgbWFpbigpIHsKICBnbF9Qb3NpdGlvbiA9IHZlYzQocG9zaXRpb24sIDAuLCAxLik7CiAgX3RleHR1cmVfY29vcmQgPSB0ZXh0dXJlX2Nvb3JkOwp9CmAsZ3I9KHI9PihyW3IuTElORUFSPTBdPSJMSU5FQVIiLHJbci5HQVVTU0lBTj0xXT0iR0FVU1NJQU4iLHIpKShncnx8e30pO2NsYXNzIGlpIGV4dGVuZHMgeGV7Z2V0RGVmaW5lcygpe3ZhciBlO3JldHVybntSQURJVVM6KGU9dGhpcy5vcHRpb25zLnJhZGl1cykhPW51bGw/ZToxfX1nZXRGcmFnbWVudFNoYWRlcigpe3JldHVybiB6Yyt0aGlzLmNyZWF0ZUxvb3BGdW5jdGlvbigpfWdldFZlcnRleFNoYWRlcigpe3JldHVybiBXY31jcmVhdGVMb29wRnVuY3Rpb24oKXt2YXIgdDtsZXQgZT0odD10aGlzLm9wdGlvbnMucmFkaXVzKSE9bnVsbD90OjE7cmV0dXJuYAoKICAgICAgICB2ZWM0IGxvb3AoKSB7IAogICAgICAgICAgICB2ZWM0IHJlc3VsdCA9IHZlYzQoMCwwLDAsMCk7CiAgICAgICAgICAgIGZsb2F0IGZhY3RvclN1bSA9IDAuOwoKICAgICAgICAgICAgdmVjMiBub3JtYWxpemVkUmFkaXVzID0gdmVjMigtJHtlfS4pIC8gY2FudmFzOwogICAgICAgICAgICB2ZWMyIG5vcm1hbGl6ZWRJbmNyZW1lbnQgPSB2ZWMyKDEuKSAvIGNhbnZhczsKICAgICAgICAgICAgdmVjMiBkaWZmID0gbm9ybWFsaXplZFJhZGl1czsKCiAgICAgICAgICAgIGZvcihpbnQgeT0tJHtlfTsgeTwke2UrMX07ICsreSkgewogICAgICAgICAgICAgICAgZm9yKGludCB4PS0ke2V9OyB4PCR7ZSsxfTsgKyt4KSB7CiAgICAgICAgICAgICAgICAgICAgZmxvYXQgZmFjdG9yID0gMS47CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ICs9IGZhY3RvciAqIHRleHR1cmUyRCh0ZXh0dXJlLCBfdGV4dHVyZV9jb29yZCArIGRpZmYpOwogICAgICAgICAgICAgICAgICAgIGZhY3RvclN1bSArPSBmYWN0b3I7CiAgICAgICAgICAgICAgICAgICAgZGlmZi54ICs9IG5vcm1hbGl6ZWRJbmNyZW1lbnQueDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGRpZmYueSArPSBub3JtYWxpemVkSW5jcmVtZW50Lnk7CiAgICAgICAgICAgICAgICBkaWZmLnggPSBub3JtYWxpemVkUmFkaXVzLng7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHJlc3VsdCAvIGZhY3RvclN1bTsKICAgICAgICB9YH1nZXRGYWN0b3IoZSx0KXtzd2l0Y2godGhpcy5vcHRpb25zLnR5cGUpe2Nhc2UgMTpyZXR1cm4gdGhpcy5nZXRMaW5lYXJGYWN0b3IoZSx0KTtjYXNlIDA6ZGVmYXVsdDpyZXR1cm4gdGhpcy5nZXRMaW5lYXJGYWN0b3IoZSx0KX19Z2V0TGluZWFyRmFjdG9yKGUsdCl7cmV0dXJuIDF9Z2V0R2F1c3NpYW5GYWN0b3IoZSx0KXt2YXIgdTtjb25zdCBuPU1hdGguUEkqMixpPU1hdGgubWF4KCh1PXRoaXMub3B0aW9ucy5yYWRpdXMpIT1udWxsP3U6MSwxKSxvPTEvKG4qaSoqMikscz0tKGUqKjIrdCoqMiksYT1vKnM7cmV0dXJuIG8qTWF0aC5FKiphfX1jbGFzcyBWYyBleHRlbmRzIHhye2NvbnN0cnVjdG9yKHQsbil7c3VwZXIoKTtwKHRoaXMsImlucHV0SW1hZ2UiKTtwKHRoaXMsImlucHV0TWFzayIpO3RoaXMuY29udGV4dD10O2NvbnN0IGk9e2NvbnRleHQ6dCxoZWlnaHQ6dC5jYW52YXMuaGVpZ2h0LHdpZHRoOnQuY2FudmFzLndpZHRofSxvPW5ldyBpaSh7Li4uaSxyYWRpdXM6bix0eXBlOmdyLkdBVVNTSUFOfSkscz1uZXcgeXIoey4uLmksZGlzYWJsZUZyYW1lYnVmZmVyOiEwfSk7dGhpcy5hZGRTdGVwKHtwcm9ncmFtOm8sZ2V0VW5pZm9ybXM6KCk9Pih7dGV4dHVyZTpTKHQsdGhpcy5pbnB1dEltYWdlKX0pfSksdGhpcy5hZGRTdGVwKHtwcm9ncmFtOnMsZ2V0VW5pZm9ybXM6KCk9Pih7YmFja2dyb3VuZDpTKHQsdGhpcy5pbnB1dEltYWdlKSxmb3JlZ3JvdW5kOlModCxvLm91dHB1dCksdGhyZXNob2xkOlModCx0aGlzLmlucHV0TWFzayl9KX0pfXNldERhdGEodCxuKXt0aGlzLmlucHV0SW1hZ2U9dCx0aGlzLmlucHV0TWFzaz1ufX1jbGFzcyBiciBleHRlbmRzIHhle2NvbnN0cnVjdG9yKHQpe3N1cGVyKHQpO3AodGhpcywiZmJpMiIpO3RoaXMuZmJpMj12dCh0LmNvbnRleHQsW3tmb3JtYXQ6dC5jb250ZXh0LlJHQkEsdHlwZTp0LmNvbnRleHQuVU5TSUdORURfQllURSxtaW46dC5jb250ZXh0LkxJTkVBUixtYWc6dC5jb250ZXh0LkxJTkVBUix3cmFwOnQuY29udGV4dC5DTEFNUF9UT19FREdFfV0sdC53aWR0aCx0LmhlaWdodCl9cnVuKHQpe2NvbnN0IG49dGhpcy5mYmk7dGhpcy5mYmk9dGhpcy5mYmkyLHRoaXMuZmJpMj1uLHRoaXMub3V0cHV0PXRoaXMuZmJpLmF0dGFjaG1lbnRzWzBdLHN1cGVyLnJ1bih7Li4udCxwcmV2aW91c19yZW5kZXJpbmc6dGhpcy5mYmkyLmF0dGFjaG1lbnRzWzBdfSl9cmVzaXplT3V0cHV0KHQsbil7c3VwZXIucmVzaXplT3V0cHV0KHQsbiksdGhpcy5mYmkyPXZ0KHRoaXMuY29udGV4dCxbe2Zvcm1hdDp0aGlzLmNvbnRleHQuUkdCQSx0eXBlOnRoaXMuY29udGV4dC5VTlNJR05FRF9CWVRFLG1pbjp0aGlzLmNvbnRleHQuTElORUFSLHdyYXA6dGhpcy5jb250ZXh0LkNMQU1QX1RPX0VER0V9XSx0LG4pfX12YXIgSGM9YHByZWNpc2lvbiBtZWRpdW1wIGZsb2F0OwoKdmFyeWluZyB2ZWMyIF90ZXh0dXJlX2Nvb3JkOwoKLy8gdW5pZm9ybSBmbG9hdCB0cmVzaG9sZDsKdW5pZm9ybSBzYW1wbGVyMkQgaW1hZ2Vfbm93Owp1bmlmb3JtIHNhbXBsZXIyRCBpbWFnZV9iZWZvcmU7CnVuaWZvcm0gc2FtcGxlcjJEIG1hc2tfbm93Owp1bmlmb3JtIHNhbXBsZXIyRCBtYXNrX2JlZm9yZTsKdW5pZm9ybSBzYW1wbGVyMkQgcHJldmlvdXNfcmVuZGVyaW5nOwp1bmlmb3JtIHZlYzIgY2FudmFzOwoKdW5pZm9ybSBmbG9hdCBkZWx0YTsKCmZsb2F0IGN1cnJlbnRfZmFjdG9yID0gMC42OTsKZmxvYXQgcHJldmlvdXNfZmFjdG9yID0gMC43NDsKZmxvYXQgdGhyZXNob2xkX2FjdGl2YXRpb24gPSAwLjU0OwoKZmxvYXQgbWFwKGZsb2F0IHZhbHVlLCBmbG9hdCBtaW4xLCBmbG9hdCBtYXgxLCBmbG9hdCBtaW4yLCBmbG9hdCBtYXgyKSB7CiAgcmV0dXJuIG1pbjIgKyAodmFsdWUgLSBtaW4xKSAqIChtYXgyIC0gbWluMikgLyAobWF4MSAtIG1pbjEpOwp9CgpmbG9hdCBnZXRUaHJlc2hvbGQoKSB7CiAgdmVjNCBjb2xvciA9IHZlYzQoMC4pOwogIGZvciAoZmxvYXQgeSA9IC02LjsgeSA8IDcuOyB5ICs9IDEuKSB7CiAgICBmb3IgKGZsb2F0IHggPSAtNi47IHggPCA3LjsgeCArPSAxLikgewogICAgICB2ZWM0IGltYWdlX25vd19jb2xvciA9CiAgICAgICAgICB0ZXh0dXJlMkQoaW1hZ2Vfbm93LCBfdGV4dHVyZV9jb29yZCArIHZlYzIoeCwgeSkgLyBjYW52YXMpOwogICAgICB2ZWM0IGltYWdlX2JlZm9yZV9jb2xvciA9CiAgICAgICAgICB0ZXh0dXJlMkQoaW1hZ2VfYmVmb3JlLCBfdGV4dHVyZV9jb29yZCArIHZlYzIoeCwgeSkgLyBjYW52YXMpOwogICAgICBjb2xvciArPSBhYnMoaW1hZ2VfYmVmb3JlX2NvbG9yIC0gaW1hZ2Vfbm93X2NvbG9yKTsKICAgIH0KICB9CiAgcmV0dXJuIChjb2xvci54ICsgY29sb3IueSArIGNvbG9yLnopIC8gKDMuICogOS4pOwp9Cgp2b2lkIG1haW4oKSB7CiAgZmxvYXQgdHJlc2hvbGRfaW5wdXQgPSAuNDsKICBmbG9hdCB0cmVzaG9sZF9wcmV2aW91c19yZW5kZXJpbmcgPSAuOTg7CgogIHZlYzQgbWFza19ub3dfY29sb3IgPSB0ZXh0dXJlMkQobWFza19ub3csIF90ZXh0dXJlX2Nvb3JkKTsKICB2ZWM0IG1hc2tfYmVmb3JlX2NvbG9yID0gdGV4dHVyZTJEKG1hc2tfYmVmb3JlLCBfdGV4dHVyZV9jb29yZCk7CiAgdmVjNCBwcmV2aW91c19yZW5kZXJpbmdfY29sb3IgPSB0ZXh0dXJlMkQocHJldmlvdXNfcmVuZGVyaW5nLCBfdGV4dHVyZV9jb29yZCk7CgogIHZlYzMgbWFza19kaWZmID0gYWJzKG1hc2tfYmVmb3JlX2NvbG9yLnh5eiAtIG1hc2tfbm93X2NvbG9yLnh5eik7CiAgZmxvYXQgZmxpY2tlcmluZyA9IG1hc2tfZGlmZi54OwogIGZsb2F0IHRocmVzaG9sZCA9IGdldFRocmVzaG9sZCgpOwogIGlmICh0aHJlc2hvbGQgPCB0aHJlc2hvbGRfYWN0aXZhdGlvbikgewogICAgZ2xfRnJhZ0NvbG9yID0gdmVjNChmbGlja2VyaW5nLCAwLiwgMC4sIDEuKSAqIGN1cnJlbnRfZmFjdG9yICsKICAgICAgICAgICAgICAgICAgIHByZXZpb3VzX3JlbmRlcmluZ19jb2xvciAqIHByZXZpb3VzX2ZhY3RvcjsKICAgIGdsX0ZyYWdDb2xvciAqPSAoMS4gLSB0aHJlc2hvbGQpOwogIH0KfQpgLFljPWB2YXJ5aW5nIHZlYzIgX3RleHR1cmVfY29vcmQ7CgphdHRyaWJ1dGUgdmVjMiBwb3NpdGlvbjsKYXR0cmlidXRlIHZlYzIgdGV4dHVyZV9jb29yZDsKCnZvaWQgbWFpbigpIHsKICBnbF9Qb3NpdGlvbiA9IHZlYzQocG9zaXRpb24sIDAuLCAxLik7CiAgX3RleHR1cmVfY29vcmQgPSB0ZXh0dXJlX2Nvb3JkOwp9CmA7Y2xhc3MgamMgZXh0ZW5kcyBicntnZXRGcmFnbWVudFNoYWRlcigpe3JldHVybiBIY31nZXRWZXJ0ZXhTaGFkZXIoKXtyZXR1cm4gWWN9fXZhciBYYz1gI3ZlcnNpb24gMzAwIGVzCi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9Wb2xjb21peC92aXJ0dWFsLWJhY2tncm91bmQvYmxvYi9tYWluL3NyYy9waXBlbGluZXMvd2ViZ2wyL2pvaW50QmlsYXRlcmFsRmlsdGVyU3RhZ2UudHMKCnByZWNpc2lvbiBoaWdocCBmbG9hdDsKdW5pZm9ybSBzYW1wbGVyMkQgaW5wdXRfZnJhbWU7CnVuaWZvcm0gc2FtcGxlcjJEIHNlZ21lbnRhdGlvbl9tYXNrOwp1bmlmb3JtIHNhbXBsZXIyRCB0aHJlc2hvbGQ7CnVuaWZvcm0gdmVjMiB0ZXhlbF9zaXplOwp1bmlmb3JtIGZsb2F0IHN0ZXA7CnVuaWZvcm0gZmxvYXQgcmFkaXVzOwp1bmlmb3JtIGZsb2F0IG9mZnNldDsKdW5pZm9ybSBmbG9hdCBzaWdtYV90ZXhlbDsKdW5pZm9ybSBmbG9hdCBzaWdtYV9jb2xvcjsKCmluIHZlYzIgX3RleHR1cmVfY29vcmQ7Cm91dCB2ZWM0IG91dENvbG9yOwoKZmxvYXQgZ2F1c3NpYW4oZmxvYXQgeCwgZmxvYXQgc2lnbWEpIHsKICBmbG9hdCBjb2VmZiA9IC0wLjUgLyAoc2lnbWEgKiBzaWdtYSAqIDQuMCArIDEuMGUtNik7CiAgcmV0dXJuIGV4cCgoeCAqIHgpICogY29lZmYpOwp9Cgp2b2lkIG1haW4oKSB7CiAgdmVjMiBjZW50ZXJDb29yZCA9IF90ZXh0dXJlX2Nvb3JkOwogIHZlYzMgY2VudGVyQ29sb3IgPSB0ZXh0dXJlKGlucHV0X2ZyYW1lLCBjZW50ZXJDb29yZCkucmdiOwogIGZsb2F0IG5ld1ZhbCA9IDAuMDsKICBmbG9hdCBzcGFjZVdlaWdodCA9IDAuMDsKICBmbG9hdCBjb2xvcldlaWdodCA9IDAuMDsKICBmbG9hdCB0b3RhbFdlaWdodCA9IDAuMDsKICAvLyBTdWJzYW1wbGUga2VybmVsIHNwYWNlLgogIGZvciAoZmxvYXQgaSA9IC1yYWRpdXMgKyBvZmZzZXQ7IGkgPD0gcmFkaXVzOyBpICs9IHN0ZXApIHsKICAgIGZvciAoZmxvYXQgaiA9IC1yYWRpdXMgKyBvZmZzZXQ7IGogPD0gcmFkaXVzOyBqICs9IHN0ZXApIHsKICAgICAgdmVjMiBzaGlmdCA9IHZlYzIoaiwgaSkgKiB0ZXhlbF9zaXplOwogICAgICB2ZWMyIGNvb3JkID0gdmVjMihjZW50ZXJDb29yZCArIHNoaWZ0KTsKICAgICAgdmVjMyBmcmFtZUNvbG9yID0gdGV4dHVyZShpbnB1dF9mcmFtZSwgY29vcmQpLnJnYjsKICAgICAgZmxvYXQgdGhyZXNob2xkID0gdGV4dHVyZSh0aHJlc2hvbGQsIGNvb3JkKS5hOwogICAgICBmbG9hdCBvdXRWYWwgPSB0ZXh0dXJlKHNlZ21lbnRhdGlvbl9tYXNrLCBjb29yZCkuYTsKCiAgICAgIHNwYWNlV2VpZ2h0ID0gZ2F1c3NpYW4oZGlzdGFuY2UoY2VudGVyQ29vcmQsIGNvb3JkKSwgc2lnbWFfdGV4ZWwpOwogICAgICBjb2xvcldlaWdodCA9IGdhdXNzaWFuKGRpc3RhbmNlKGNlbnRlckNvbG9yLCBmcmFtZUNvbG9yKSwgc2lnbWFfY29sb3IpOwogICAgICB0b3RhbFdlaWdodCArPSBzcGFjZVdlaWdodCAqIGNvbG9yV2VpZ2h0OwogICAgICBuZXdWYWwgKz0gc3BhY2VXZWlnaHQgKiBjb2xvcldlaWdodCAqIG91dFZhbCAqIHRocmVzaG9sZDsKICAgIH0KICB9CiAgbmV3VmFsIC89IHRvdGFsV2VpZ2h0OwogIG91dENvbG9yID0gdmVjNCh2ZWMzKDAuKSwgbmV3VmFsKTsKfWAsUWM9YCN2ZXJzaW9uIDMwMCBlcwppbiB2ZWMyIHBvc2l0aW9uOwppbiB2ZWMyIHRleHR1cmVfY29vcmQ7Cm91dCB2ZWMyIF90ZXh0dXJlX2Nvb3JkOwp2b2lkIG1haW4oKSB7CiAgZ2xfUG9zaXRpb24gPSB2ZWM0KHBvc2l0aW9uLCAwLjAsIDEuMCk7CiAgX3RleHR1cmVfY29vcmQgPSB0ZXh0dXJlX2Nvb3JkOwp9YDtjbGFzcyBLYyBleHRlbmRzIHhle2dldEZyYWdtZW50U2hhZGVyKCl7cmV0dXJuIFhjfWdldFZlcnRleFNoYWRlcigpe3JldHVybiBRY319dmFyIHFjPWBwcmVjaXNpb24gbWVkaXVtcCBmbG9hdDsKCnZhcnlpbmcgdmVjMiBfdGV4dHVyZV9jb29yZDsKCnVuaWZvcm0gdmVjMiBjYW52YXM7CnVuaWZvcm0gc2FtcGxlcjJEIHRleHR1cmU7Cgp2b2lkIG1haW4oKSB7CiAgaW50IGNvdW50ID0gMDsKICBmb3IgKGZsb2F0IHkgPSAtMS47IHkgPCAyLjsgeSArPSAxLikgewogICAgZm9yIChmbG9hdCB4ID0gLTEuOyB4IDwgMi47IHggKz0gMS4pIHsKICAgICAgdmVjMiBjb29yZCA9IF90ZXh0dXJlX2Nvb3JkICsgdmVjMih5LCB4KSAvIGNhbnZhczsKICAgICAgdmVjNCBjb2xvciA9IHRleHR1cmUyRCh0ZXh0dXJlLCBjb29yZCk7CiAgICAgIGlmIChjb2xvci5yID4gLjEpIHsKICAgICAgICBjb3VudCsrOwogICAgICB9CiAgICB9CiAgfQogIGlmIChjb3VudCA+IDUpIHsKICAgIGdsX0ZyYWdDb2xvciA9IHRleHR1cmUyRCh0ZXh0dXJlLCBfdGV4dHVyZV9jb29yZCk7CiAgfQp9CmAsSmM9YHZhcnlpbmcgdmVjMiBfdGV4dHVyZV9jb29yZDsKCmF0dHJpYnV0ZSB2ZWMyIHBvc2l0aW9uOwphdHRyaWJ1dGUgdmVjMiB0ZXh0dXJlX2Nvb3JkOwoKdm9pZCBtYWluKCkgewogIGdsX1Bvc2l0aW9uID0gdmVjNChwb3NpdGlvbiwgMC4sIDEuKTsKICBfdGV4dHVyZV9jb29yZCA9IHRleHR1cmVfY29vcmQ7Cn0KYDtjbGFzcyBaYyBleHRlbmRzIHhle2dldEZyYWdtZW50U2hhZGVyKCl7cmV0dXJuIHFjfWdldFZlcnRleFNoYWRlcigpe3JldHVybiBKY319dmFyIGVmPWBwcmVjaXNpb24gbWVkaXVtcCBmbG9hdDsKCnZhcnlpbmcgdmVjMiBfdGV4dHVyZV9jb29yZDsKCnVuaWZvcm0gdmVjMiBjYW52YXM7CnVuaWZvcm0gc2FtcGxlcjJEIHRleHR1cmU7Cgp2b2lkIG1haW4oKSB7CiAgdmVjNCBjb2xvciA9IHRleHR1cmUyRCh0ZXh0dXJlLCBfdGV4dHVyZV9jb29yZCk7CiAgZm9yIChmbG9hdCB5ID0gLTIuOyB5IDwgMy47IHkgKz0gMS4pIHsKICAgIGZvciAoZmxvYXQgeCA9IC0yLjsgeCA8IDMuOyB4ICs9IDEuKSB7CiAgICAgIHZlYzIgY29vcmQgPSBfdGV4dHVyZV9jb29yZDsKICAgICAgY29vcmQgKz0gdmVjMih5LCB4KSAvIGNhbnZhczsKICAgICAgY29sb3IgKz0gdGV4dHVyZTJEKHRleHR1cmUsIGNvb3JkKSAqICgxLiAvIDQuKTsKICAgIH0KICB9CgogIGdsX0ZyYWdDb2xvciA9IGNvbG9yOwp9CmAsdGY9YHZhcnlpbmcgdmVjMiBfdGV4dHVyZV9jb29yZDsKCmF0dHJpYnV0ZSB2ZWMyIHBvc2l0aW9uOwphdHRyaWJ1dGUgdmVjMiB0ZXh0dXJlX2Nvb3JkOwoKdm9pZCBtYWluKCkgewogIGdsX1Bvc2l0aW9uID0gdmVjNChwb3NpdGlvbiwgMC4sIDEuKTsKICBfdGV4dHVyZV9jb29yZCA9IHRleHR1cmVfY29vcmQ7Cn0KYDtjbGFzcyByZiBleHRlbmRzIGJye2dldEZyYWdtZW50U2hhZGVyKCl7cmV0dXJuIGVmfWdldFZlcnRleFNoYWRlcigpe3JldHVybiB0Zn19dmFyIG5mPWBwcmVjaXNpb24gbWVkaXVtcCBmbG9hdDsKCnZhcnlpbmcgdmVjMiBfdGV4dHVyZV9jb29yZDsKCnVuaWZvcm0gc2FtcGxlcjJEIHRocmVzaG9sZDsKdW5pZm9ybSBzYW1wbGVyMkQgaW5wdXRzOwoKdm9pZCBtYWluKCkgewogIHZlYzQgaW5wdXRzX2NvbG9yID0gdGV4dHVyZTJEKGlucHV0cywgX3RleHR1cmVfY29vcmQpOwogIHZlYzQgdGhyZXNob2xkX2NvbG9yID0gdGV4dHVyZTJEKHRocmVzaG9sZCwgX3RleHR1cmVfY29vcmQpOwogIGlmICh0aHJlc2hvbGRfY29sb3IuciA8IC4xICYmIGlucHV0c19jb2xvci5yID4gLjUpIHsKICAgIGdsX0ZyYWdDb2xvciA9IGlucHV0c19jb2xvcjsKICB9Cn0KYCxvZj1gdmFyeWluZyB2ZWMyIF90ZXh0dXJlX2Nvb3JkOwoKYXR0cmlidXRlIHZlYzIgcG9zaXRpb247CmF0dHJpYnV0ZSB2ZWMyIHRleHR1cmVfY29vcmQ7Cgp2b2lkIG1haW4oKSB7CiAgZ2xfUG9zaXRpb24gPSB2ZWM0KHBvc2l0aW9uLCAwLiwgMS4pOwogIF90ZXh0dXJlX2Nvb3JkID0gdGV4dHVyZV9jb29yZDsKfQpgO2NsYXNzIHNmIGV4dGVuZHMgYnJ7Z2V0RnJhZ21lbnRTaGFkZXIoKXtyZXR1cm4gbmZ9Z2V0VmVydGV4U2hhZGVyKCl7cmV0dXJuIG9mfX1jbGFzcyBhZiBleHRlbmRzIF9ye2NvbnN0cnVjdG9yKHQsbixpKXtzdXBlcigpO3AodGhpcywiaW5wdXRJbWFnZSIpO3AodGhpcywiaW5wdXRNYXNrIik7cCh0aGlzLCJwcmV2aW91c0lucHV0SW1hZ2UiKTtwKHRoaXMsInByZXZpb3VzSW5wdXRNYXNrIik7cCh0aGlzLCJvdXRwdXQiKTtwKHRoaXMsIm9wdGlvbnMiLHtjdXJyZW50VGhyZXNob2xkTWluaW11bTowLGN1cnJlbnRUaHJlc2hvbGRNYXhpbXVtOjEscHJldmlvdXNUaHJlc2hvbGRNaW5pbXVtOjAscHJldmlvdXNUaHJlc2hvbGRNYXhpbXVtOjEsdGhyZXNob2xkTWluaW11bTowLHRocmVzaG9sZE1heGltdW06MSx0aHJlc2hvbGRGYWN0b3I6MX0pO3RoaXMuY29udGV4dD10O2NvbnN0IG89e2NvbnRleHQ6dCxoZWlnaHQ6aSx3aWR0aDpufSxzPW5ldyBqYyhvKSxhPW5ldyBpaSh7Li4ubyxyYWRpdXM6MSx0eXBlOmdyLkdBVVNTSUFOfSksdT1uZXcgc2YobyksZj1uZXcgcmYobyksZD1uZXcgWmMobyksaD1uZXcgS2Moey4uLm99KSx5PS42Nix4PTY0MCxsPTQ4MCxnPTI1NixFPTE0NDtsZXQgdj0xO3YqPU1hdGgubWF4KHgvZyxsL0UpO2NvbnN0IEk9TWF0aC5tYXgoMSxNYXRoLnNxcnQodikqeSksRD0xL3gsRz0xL2w7dGhpcy5hZGRTdGVwKHtwcm9ncmFtOnMsZ2V0VW5pZm9ybXM6KCk9Pih7aW1hZ2Vfbm93OlModCx0aGlzLmlucHV0SW1hZ2UpLGltYWdlX2JlZm9yZTpTKHQsdGhpcy5wcmV2aW91c0lucHV0SW1hZ2UpLG1hc2tfbm93OlModCx0aGlzLmlucHV0TWFzayksbWFza19iZWZvcmU6Uyh0LHRoaXMucHJldmlvdXNJbnB1dE1hc2spLGN1cnJlbnRfdGhyZXNob2xkX21pbmltdW06dGhpcy5vcHRpb25zLmN1cnJlbnRUaHJlc2hvbGRNaW5pbXVtLGN1cnJlbnRfdGhyZXNob2xkX21heGltdW06dGhpcy5vcHRpb25zLmN1cnJlbnRUaHJlc2hvbGRNYXhpbXVtLHByZXZpb3VzX3RocmVzaG9sZF9taW5pbXVtOnRoaXMub3B0aW9ucy5wcmV2aW91c1RocmVzaG9sZE1pbmltdW0scHJldmlvdXNfdGhyZXNob2xkX21heGltdW06dGhpcy5vcHRpb25zLnByZXZpb3VzVGhyZXNob2xkTWF4aW11bSx0aHJlc2hvbGRfbWluaW11bTp0aGlzLm9wdGlvbnMudGhyZXNob2xkTWluaW11bSx0aHJlc2hvbGRfbWF4aW11bTp0aGlzLm9wdGlvbnMudGhyZXNob2xkTWF4aW11bSx0aHJlc2hvbGRfZmFjdG9yOnRoaXMub3B0aW9ucy50aHJlc2hvbGRGYWN0b3J9KX0pLHRoaXMuYWRkU3RlcCh7cHJvZ3JhbTp1LGdldFVuaWZvcm1zOigpPT4oe2lucHV0czpTKHQsdGhpcy5pbnB1dE1hc2spLHRocmVzaG9sZDpTKHQscy5vdXRwdXQpfSl9KSx0aGlzLmFkZFN0ZXAoe3Byb2dyYW06ZCxnZXRVbmlmb3JtczooKT0+KHt0ZXh0dXJlOlModCx1Lm91dHB1dCl9KX0pLHRoaXMuYWRkU3RlcCh7cHJvZ3JhbTpmLGdldFVuaWZvcm1zOigpPT4oe3RleHR1cmU6Uyh0LGQub3V0cHV0KX0pfSksdGhpcy5hZGRTdGVwKHtwcm9ncmFtOmEsZ2V0VW5pZm9ybXM6KCk9Pih7dGV4dHVyZTpTKHQsZi5vdXRwdXQpfSl9KSx0aGlzLmFkZFN0ZXAoe3Byb2dyYW06aCxnZXRVbmlmb3JtczooKT0+KHtpbnB1dF9mcmFtZTpTKHQsdGhpcy5pbnB1dEltYWdlKSxzZWdtZW50YXRpb25fbWFzazpTKHQsdGhpcy5pbnB1dE1hc2spLHRocmVzaG9sZDpTKHQsYS5vdXRwdXQpLHRleGVsX3NpemU6W0QsR10sc3RlcDpJLHJhZGl1czp2LG9mZnNldDpJPjE/SSouNTowLHNpZ21hX3RleGVsOk1hdGgubWF4KEQsRykqdixzaWdtYV9jb2xvcjouMX0pfSksdGhpcy5vdXRwdXQ9aC5vdXRwdXR9c2V0RGF0YSh0LG4pe3RoaXMucHJldmlvdXNJbnB1dEltYWdlPXRoaXMuaW5wdXRJbWFnZT90aGlzLmlucHV0SW1hZ2U6dCx0aGlzLnByZXZpb3VzSW5wdXRNYXNrPXRoaXMuaW5wdXRNYXNrP3RoaXMuaW5wdXRNYXNrOm4sdGhpcy5pbnB1dEltYWdlPXQsdGhpcy5pbnB1dE1hc2s9bn1zZXRPcHRpb25zKHQpe3RoaXMub3B0aW9ucz10fX12YXIgdWY9YHByZWNpc2lvbiBtZWRpdW1wIGZsb2F0OwoKdmFyeWluZyB2ZWMyIF90ZXh0dXJlX2Nvb3JkOwp1bmlmb3JtIHNhbXBsZXIyRCB0ZXh0dXJlOwoKdm9pZCBtYWluKCkgeyBnbF9GcmFnQ29sb3IgPSB0ZXh0dXJlMkQodGV4dHVyZSwgX3RleHR1cmVfY29vcmQpOyB9CmAsY2Y9YHZhcnlpbmcgdmVjMiBfdGV4dHVyZV9jb29yZDsKCmF0dHJpYnV0ZSB2ZWMyIHBvc2l0aW9uOwphdHRyaWJ1dGUgdmVjMiB0ZXh0dXJlX2Nvb3JkOwp1bmlmb3JtIGJvb2wgaW52ZXJ0X3k7Cgp2b2lkIG1haW4oKSB7CiAgZ2xfUG9zaXRpb24gPSB2ZWM0KHBvc2l0aW9uLCAwLiwgMS4pOwogIF90ZXh0dXJlX2Nvb3JkID0gdGV4dHVyZV9jb29yZDsKICBpZiAoaW52ZXJ0X3kpIHsKICAgIF90ZXh0dXJlX2Nvb3JkLnkgPSAxLiAtIHRleHR1cmVfY29vcmQueTsKICB9Cn0KYDtjbGFzcyBmZiBleHRlbmRzIHhle2dldEZyYWdtZW50U2hhZGVyKCl7cmV0dXJuIHVmfWdldFZlcnRleFNoYWRlcigpe3JldHVybiBjZn19Y2xhc3MgbGYgZXh0ZW5kcyBfcntjb25zdHJ1Y3Rvcih0LG4saSl7c3VwZXIoKTtwKHRoaXMsImlucHV0SW1hZ2UiKTt0aGlzLmNvbnRleHQ9dDtjb25zdCBvPXtjb250ZXh0OnQsaGVpZ2h0Omksd2lkdGg6bn07dGhpcy5hZGRTdGVwKHtwcm9ncmFtOm5ldyBmZih7Li4ubyxkaXNhYmxlRnJhbWVidWZmZXI6ITB9KSxnZXRVbmlmb3JtczooKT0+KHt0ZXh0dXJlOlModCx0aGlzLmlucHV0SW1hZ2UpLGludmVydF95OiEwfSl9KX1zZXREYXRhKHQpe3RoaXMuaW5wdXRJbWFnZT10fX1jbGFzcyBkZntjb25zdHJ1Y3RvcihlKXtwKHRoaXMsInJlc2l6ZSIpO3AodGhpcywiY2FudmFzIik7cCh0aGlzLCJjb250ZXh0Iik7dGhpcy5jYW52YXM9bmV3IE9mZnNjcmVlbkNhbnZhcygwLDApLHRoaXMuY29udGV4dD10aGlzLmNhbnZhcy5nZXRDb250ZXh0KCJ3ZWJnbDIiKSx0aGlzLmNhbnZhcy53aWR0aD1lLndpZHRoLHRoaXMuY2FudmFzLmhlaWdodD1lLmhlaWdodCx0aGlzLnJlc2l6ZT1uZXcgbGYodGhpcy5jb250ZXh0LGUud2lkdGgsZS5oZWlnaHQpfXJlc2l6ZUZvcmVncm91bmQoZSx0KXt0aGlzLmNhbnZhcy53aWR0aD1lLHRoaXMuY2FudmFzLmhlaWdodD10LHRoaXMucmVzaXplLnJlc2l6ZU91dHB1dChlLHQpfWFzeW5jIHByb2Nlc3MoZSl7dmFyIHQsbjtyZXR1cm4gdGhpcy5jYW52YXMud2lkdGg9dGhpcy5jYW52YXMud2lkdGgsKHQ9dGhpcy5yZXNpemUpPT1udWxsfHx0LnNldERhdGEoZSksKG49dGhpcy5yZXNpemUpPT1udWxsfHxuLnJ1bigpLHRoaXMuY2FudmFzfX1jbGFzcyBtZntjb25zdHJ1Y3RvcihlLHQpe3AodGhpcywiaW1wcm92ZU1hc2tTZWdtZW50YXRpb24iKTtwKHRoaXMsImJhY2tncm91bmRSZXNpemVyIik7cCh0aGlzLCJiYWNrZ3JvdW5kSW1hZ2UiKTtwKHRoaXMsImJhY2tncm91bmRWaWRlbyIpO3AodGhpcywicHJvZmlsZXIiKTtwKHRoaXMsImFjdGl2ZVBpcGVsaW5lIik7cCh0aGlzLCJjYW52YXMiKTtwKHRoaXMsIm9wdGlvbnMiKTtwKHRoaXMsImNvbnRleHQiKTtwKHRoaXMsInZpcnR1YWxCR0ltYWdlIik7dGhpcy5pZD1lLHRoaXMuY2FudmFzPW5ldyBPZmZzY3JlZW5DYW52YXMoMCwwKSx0aGlzLmNvbnRleHQ9dGhpcy5jYW52YXMuZ2V0Q29udGV4dCgid2ViZ2wyIiksdGhpcy5jYW52YXMud2lkdGg9dC5mb3JlZ3JvdW5kV2lkdGgsdGhpcy5jYW52YXMuaGVpZ2h0PXQuZm9yZWdyb3VuZEhlaWdodCx0aGlzLmltcHJvdmVNYXNrU2VnbWVudGF0aW9uPW5ldyBhZih0aGlzLmNvbnRleHQsdC5tYXNrV2lkdGgsdC5tYXNrSGVpZ2h0KSx0aGlzLmJhY2tncm91bmRJbWFnZT1uZXcgbmkodGhpcy5jb250ZXh0KSx0aGlzLmJhY2tncm91bmRWaWRlbz1uZXcgJGModGhpcy5jb250ZXh0KSx0aGlzLmJhY2tncm91bmRSZXNpemVyPW5ldyBkZih7d2lkdGg6dC5mb3JlZ3JvdW5kV2lkdGgsaGVpZ2h0OnQuZm9yZWdyb3VuZEhlaWdodH0pfXNldEJhY2tncm91bmRPcHRpb25zKGUpe3N3aXRjaChlLnRyYW5zZm9ybWVyVHlwZSl7Y2FzZSJCYWNrZ3JvdW5kQmx1ciI6dGhpcy5hY3RpdmVQaXBlbGluZT1uZXcgR2ModGhpcy5jb250ZXh0LHRoaXMuZ2V0Qmx1clNpemUoZS5yYWRpdXMpKTticmVhaztjYXNlIlNpbGhvdWV0dGVCbHVyIjp0aGlzLmFjdGl2ZVBpcGVsaW5lPW5ldyBWYyh0aGlzLmNvbnRleHQsdGhpcy5nZXRCbHVyU2l6ZShlLnJhZGl1cykpO2JyZWFrO2Nhc2UiVmlkZW9CYWNrZ3JvdW5kIjp0aGlzLmFjdGl2ZVBpcGVsaW5lPXRoaXMuYmFja2dyb3VuZFZpZGVvO2JyZWFrO2Nhc2UiVmlydHVhbEJhY2tncm91bmQiOnRoaXMuYWN0aXZlUGlwZWxpbmU9dGhpcy5iYWNrZ3JvdW5kSW1hZ2U7YnJlYWs7ZGVmYXVsdDp0aHJvd2BVbmtub3duIHRyYW5zZm9ybWVyIHR5cGUgWyR7ZS50cmFuc2Zvcm1lclR5cGV9XWB9dGhpcy5vcHRpb25zPWV9c2V0RmxpY2tlcmluZ09wdGlvbnMoZSl7dmFyIHQ7KHQ9dGhpcy5pbXByb3ZlTWFza1NlZ21lbnRhdGlvbik9PW51bGx8fHQuc2V0T3B0aW9ucyhlKX1zZXRWaWRlb0JHUmVhZGFibGUoZSl7dGhpcy5iYWNrZ3JvdW5kVmlkZW8uaW5wdXRWaWRlbz1lfWFzeW5jIHNldFZpcnR1YWxCR0ltYWdlKGUpe3RoaXMudmlydHVhbEJHSW1hZ2U9ZSx0aGlzLmJhY2tncm91bmRJbWFnZS5pbnB1dEJhY2tncm91bmRJbWFnZT1hd2FpdCB0aGlzLmJhY2tncm91bmRSZXNpemVyLnByb2Nlc3MoZSl9YXN5bmMgcHJvY2VzcyhlLHQpe3ZhciBuLGksbyxzLGEsdSxmO2lmKHRoaXMuYWN0aXZlUGlwZWxpbmUmJmUud2lkdGgmJih0PT1udWxsP3ZvaWQgMDp0LndpZHRoKSl7Y29uc3QgZD1gWyR7dGhpcy5pZH1dIGJhY2tncm91bmQtZmlsdGVyYDsobj10aGlzLnByb2ZpbGVyKT09bnVsbHx8bi5wdXNoQ29udGV4dChkKTtsZXQgaD10OygoKGk9dGhpcy5vcHRpb25zKT09bnVsbD92b2lkIDA6aS5zZWxmaWVTZWdtZW50YXRpb25UeXBlKSYmKChvPXRoaXMub3B0aW9ucyk9PW51bGw/dm9pZCAwOm8uc2VsZmllU2VnbWVudGF0aW9uVHlwZSk9PT0iUFJFQ0lTRSJ8fCEoKHM9dGhpcy5vcHRpb25zKSE9bnVsbCYmcy5zZWxmaWVTZWdtZW50YXRpb25UeXBlKSYmdGhpcy5hY3RpdmVQaXBlbGluZS5wcmVjaXNlTWFza0VuYWJsZWQpJiYodGhpcy5pbXByb3ZlTWFza1NlZ21lbnRhdGlvbi5zZXRJZCh0aGlzLmlkKSx0aGlzLmltcHJvdmVNYXNrU2VnbWVudGF0aW9uLnNldFByb2ZpbGVyKHRoaXMucHJvZmlsZXIpLHRoaXMuaW1wcm92ZU1hc2tTZWdtZW50YXRpb24uc2V0RGF0YShlLHQpLHRoaXMuaW1wcm92ZU1hc2tTZWdtZW50YXRpb24ucnVuKCksaD10aGlzLmltcHJvdmVNYXNrU2VnbWVudGF0aW9uLm91dHB1dCksdGhpcy5hY3RpdmVQaXBlbGluZS5zZXRJZCh0aGlzLmlkKSx0aGlzLmFjdGl2ZVBpcGVsaW5lLnNldFByb2ZpbGVyKHRoaXMucHJvZmlsZXIpLChhPXRoaXMuYWN0aXZlUGlwZWxpbmUpPT1udWxsfHxhLnNldERhdGEoZSxoKSwodT10aGlzLmFjdGl2ZVBpcGVsaW5lKT09bnVsbHx8dS5ydW4oKSwoZj10aGlzLnByb2ZpbGVyKT09bnVsbHx8Zi5wb3BDb250ZXh0KGQpfX1hc3luYyByZXNpemVGb3JlZ3JvdW5kKGUsdCl7dmFyIG47dGhpcy5jYW52YXMud2lkdGg9ZSx0aGlzLmNhbnZhcy5oZWlnaHQ9dCx0aGlzLmJhY2tncm91bmRJbWFnZS5yZXNpemVPdXRwdXQoZSx0KSx0aGlzLmJhY2tncm91bmRWaWRlby5yZXNpemVPdXRwdXQoZSx0KSx0aGlzLmJhY2tncm91bmRSZXNpemVyLnJlc2l6ZUZvcmVncm91bmQoZSx0KSwobj10aGlzLmFjdGl2ZVBpcGVsaW5lKT09bnVsbHx8bi5yZXNpemVPdXRwdXQoZSx0KSx0aGlzLnZpcnR1YWxCR0ltYWdlJiYodGhpcy5iYWNrZ3JvdW5kSW1hZ2UuaW5wdXRCYWNrZ3JvdW5kSW1hZ2U9YXdhaXQgdGhpcy5iYWNrZ3JvdW5kUmVzaXplci5wcm9jZXNzKHRoaXMudmlydHVhbEJHSW1hZ2UpKX1hc3luYyBwcm9maWxlKGUpe2NvbnN0IHQ9bmV3IFBvKHRoaXMuY29udGV4dCk7cmV0dXJuIHRoaXMucHJvZmlsZXI9dCx0LnN0YXJ0KCksYXdhaXQgR3IoZSksdGhpcy5wcm9maWxlcj12b2lkIDAsdC5zdG9wKCksdC5nZXRSZXNvbHZlZFF1ZXJpZXMoKX1nZXRCbHVyU2l6ZShlPVplLkxvdyl7c3dpdGNoKGUpe2Nhc2UgWmUuTG93OnJldHVybiA1O2Nhc2UgWmUuSGlnaDpyZXR1cm4gMTJ9cmV0dXJuIGV9fXZhciBoZj1mdW5jdGlvbigpe3ZhciByPXR5cGVvZiBkb2N1bWVudDwidSImJmRvY3VtZW50LmN1cnJlbnRTY3JpcHQ/ZG9jdW1lbnQuY3VycmVudFNjcmlwdC5zcmM6dm9pZCAwO3JldHVybiBmdW5jdGlvbihlKXtlPWV8fHt9O3ZhciB0PXR5cGVvZiBlPCJ1Ij9lOnt9LG4saTt0LnJlYWR5PW5ldyBQcm9taXNlKGZ1bmN0aW9uKGMsbSl7bj1jLGk9bX0pO3ZhciBvPXt9LHM7Zm9yKHMgaW4gdCl0Lmhhc093blByb3BlcnR5KHMpJiYob1tzXT10W3NdKTt2YXIgYT0iLi90aGlzLnByb2dyYW0iLHU9ZnVuY3Rpb24oYyxtKXt0aHJvdyBtfSxmPSEwLGQ9IiI7ZnVuY3Rpb24gaChjKXtyZXR1cm4gdC5sb2NhdGVGaWxlP3QubG9jYXRlRmlsZShjLGQpOmQrY312YXIgeTt0eXBlb2YgZG9jdW1lbnQ8InUiJiZkb2N1bWVudC5jdXJyZW50U2NyaXB0JiYoZD1kb2N1bWVudC5jdXJyZW50U2NyaXB0LnNyYyksciYmKGQ9ciksZC5pbmRleE9mKCJibG9iOiIpIT09MD9kPWQuc3Vic3RyKDAsZC5yZXBsYWNlKC9bPyNdLiovLCIiKS5sYXN0SW5kZXhPZigiLyIpKzEpOmQ9IiI7dmFyIHg9dC5wcmludHx8Y29uc29sZS5sb2cuYmluZChjb25zb2xlKSxsPXQucHJpbnRFcnJ8fGNvbnNvbGUud2Fybi5iaW5kKGNvbnNvbGUpO2ZvcihzIGluIG8pby5oYXNPd25Qcm9wZXJ0eShzKSYmKHRbc109b1tzXSk7bz1udWxsLHQuYXJndW1lbnRzJiZ0LmFyZ3VtZW50cyx0LnRoaXNQcm9ncmFtJiYoYT10LnRoaXNQcm9ncmFtKSx0LnF1aXQmJih1PXQucXVpdCk7dmFyIGc7dC53YXNtQmluYXJ5JiYoZz10Lndhc21CaW5hcnkpO3ZhciBFPXQubm9FeGl0UnVudGltZXx8ITA7dHlwZW9mIFdlYkFzc2VtYmx5IT0ib2JqZWN0IiYmY2UoIm5vIG5hdGl2ZSB3YXNtIHN1cHBvcnQgZGV0ZWN0ZWQiKTt2YXIgdixJPSExLEQ9dHlwZW9mIFRleHREZWNvZGVyPCJ1Ij9uZXcgVGV4dERlY29kZXIoInV0ZjgiKTp2b2lkIDA7ZnVuY3Rpb24gRyhjLG0sXyl7Zm9yKHZhciBUPW0rXyxOPW07Y1tOXSYmIShOPj1UKTspKytOO2lmKE4tbT4xNiYmYy5zdWJhcnJheSYmRClyZXR1cm4gRC5kZWNvZGUoYy5zdWJhcnJheShtLE4pKTtmb3IodmFyIGs9IiI7bTxOOyl7dmFyIHc9Y1ttKytdO2lmKCEodyYxMjgpKXtrKz1TdHJpbmcuZnJvbUNoYXJDb2RlKHcpO2NvbnRpbnVlfXZhciBPPWNbbSsrXSY2MztpZigodyYyMjQpPT0xOTIpe2srPVN0cmluZy5mcm9tQ2hhckNvZGUoKHcmMzEpPDw2fE8pO2NvbnRpbnVlfXZhciBLPWNbbSsrXSY2MztpZigodyYyNDApPT0yMjQ/dz0odyYxNSk8PDEyfE88PDZ8Szp3PSh3JjcpPDwxOHxPPDwxMnxLPDw2fGNbbSsrXSY2Myx3PDY1NTM2KWsrPVN0cmluZy5mcm9tQ2hhckNvZGUodyk7ZWxzZXt2YXIgaGk9dy02NTUzNjtrKz1TdHJpbmcuZnJvbUNoYXJDb2RlKDU1Mjk2fGhpPj4xMCw1NjMyMHxoaSYxMDIzKX19cmV0dXJuIGt9ZnVuY3Rpb24gJChjLG0pe3JldHVybiBjP0coTGUsYyxtKToiIn1mdW5jdGlvbiBaKGMsbSxfKXtmb3IodmFyIFQ9MDtUPGMubGVuZ3RoOysrVClFdFttKys+PjBdPWMuY2hhckNvZGVBdChUKTtffHwoRXRbbT4+MF09MCl9ZnVuY3Rpb24gSChjLG0pe3JldHVybiBjJW0+MCYmKGMrPW0tYyVtKSxjfXZhciBzaSxFdCxMZSxZO2Z1bmN0aW9uIGFpKGMpe3NpPWMsdC5IRUFQOD1FdD1uZXcgSW50OEFycmF5KGMpLHQuSEVBUDE2PW5ldyBJbnQxNkFycmF5KGMpLHQuSEVBUDMyPVk9bmV3IEludDMyQXJyYXkoYyksdC5IRUFQVTg9TGU9bmV3IFVpbnQ4QXJyYXkoYyksdC5IRUFQVTE2PW5ldyBVaW50MTZBcnJheShjKSx0LkhFQVBVMzI9bmV3IFVpbnQzMkFycmF5KGMpLHQuSEVBUEYzMj1uZXcgRmxvYXQzMkFycmF5KGMpLHQuSEVBUEY2ND1uZXcgRmxvYXQ2NEFycmF5KGMpfXQuSU5JVElBTF9NRU1PUlk7dmFyIEVyLHVpPVtdLGNpPVtdLGZpPVtdLHZmPTA7ZnVuY3Rpb24gRWYoKXtyZXR1cm4gRXx8dmY+MH1mdW5jdGlvbiBUZigpe2lmKHQucHJlUnVuKWZvcih0eXBlb2YgdC5wcmVSdW49PSJmdW5jdGlvbiImJih0LnByZVJ1bj1bdC5wcmVSdW5dKTt0LnByZVJ1bi5sZW5ndGg7KVNmKHQucHJlUnVuLnNoaWZ0KCkpO1RyKHVpKX1mdW5jdGlvbiBBZigpe1RyKGNpKX1mdW5jdGlvbiB3Zigpe2lmKHQucG9zdFJ1bilmb3IodHlwZW9mIHQucG9zdFJ1bj09ImZ1bmN0aW9uIiYmKHQucG9zdFJ1bj1bdC5wb3N0UnVuXSk7dC5wb3N0UnVuLmxlbmd0aDspSWYodC5wb3N0UnVuLnNoaWZ0KCkpO1RyKGZpKX1mdW5jdGlvbiBTZihjKXt1aS51bnNoaWZ0KGMpfWZ1bmN0aW9uIFJmKGMpe2NpLnVuc2hpZnQoYyl9ZnVuY3Rpb24gSWYoYyl7ZmkudW5zaGlmdChjKX12YXIgZ2U9MCxHZT1udWxsO2Z1bmN0aW9uIEZmKGMpe2dlKyssdC5tb25pdG9yUnVuRGVwZW5kZW5jaWVzJiZ0Lm1vbml0b3JSdW5EZXBlbmRlbmNpZXMoZ2UpfWZ1bmN0aW9uIFBmKGMpe2lmKGdlLS0sdC5tb25pdG9yUnVuRGVwZW5kZW5jaWVzJiZ0Lm1vbml0b3JSdW5EZXBlbmRlbmNpZXMoZ2UpLGdlPT0wJiZHZSl7dmFyIG09R2U7R2U9bnVsbCxtKCl9fXQucHJlbG9hZGVkSW1hZ2VzPXt9LHQucHJlbG9hZGVkQXVkaW9zPXt9O2Z1bmN0aW9uIGNlKGMpe3Qub25BYm9ydCYmdC5vbkFib3J0KGMpLGM9IkFib3J0ZWQoIitjKyIpIixsKGMpLEk9ITAsYys9Ii4gQnVpbGQgd2l0aCAtcyBBU1NFUlRJT05TPTEgZm9yIG1vcmUgaW5mby4iO3ZhciBtPW5ldyBXZWJBc3NlbWJseS5SdW50aW1lRXJyb3IoYyk7dGhyb3cgaShtKSxtfXZhciBEZj0iZGF0YTphcHBsaWNhdGlvbi9vY3RldC1zdHJlYW07YmFzZTY0LCI7ZnVuY3Rpb24gbGkoYyl7cmV0dXJuIGMuc3RhcnRzV2l0aChEZil9dmFyIGo7aj0idGZsaXRlLXNpbWQud2FzbSIsbGkoail8fChqPWgoaikpO2Z1bmN0aW9uIGRpKGMpe3RyeXtpZihjPT1qJiZnKXJldHVybiBuZXcgVWludDhBcnJheShnKTtpZigheSl0aHJvdyJib3RoIGFzeW5jIGFuZCBzeW5jIGZldGNoaW5nIG9mIHRoZSB3YXNtIGZhaWxlZCJ9Y2F0Y2gobSl7Y2UobSl9fWZ1bmN0aW9uIE5mKCl7cmV0dXJuIWcmJmYmJnR5cGVvZiBmZXRjaD09ImZ1bmN0aW9uIj9mZXRjaChqLHtjcmVkZW50aWFsczoic2FtZS1vcmlnaW4ifSkudGhlbihmdW5jdGlvbihjKXtpZighYy5vayl0aHJvdyJmYWlsZWQgdG8gbG9hZCB3YXNtIGJpbmFyeSBmaWxlIGF0ICciK2orIiciO3JldHVybiBjLmFycmF5QnVmZmVyKCl9KS5jYXRjaChmdW5jdGlvbigpe3JldHVybiBkaShqKX0pOlByb21pc2UucmVzb2x2ZSgpLnRoZW4oZnVuY3Rpb24oKXtyZXR1cm4gZGkoail9KX1mdW5jdGlvbiBNZigpe3ZhciBjPXthOmVsfTtmdW5jdGlvbiBtKHcsTyl7dmFyIEs9dy5leHBvcnRzO3QuYXNtPUssdj10LmFzbS5xLGFpKHYuYnVmZmVyKSxFcj10LmFzbS5FLFJmKHQuYXNtLnIpLFBmKCl9RmYoKTtmdW5jdGlvbiBfKHcpe20ody5pbnN0YW5jZSl9ZnVuY3Rpb24gVCh3KXtyZXR1cm4gTmYoKS50aGVuKGZ1bmN0aW9uKE8pe3JldHVybiBXZWJBc3NlbWJseS5pbnN0YW50aWF0ZShPLGMpfSkudGhlbihmdW5jdGlvbihPKXtyZXR1cm4gT30pLnRoZW4odyxmdW5jdGlvbihPKXtsKCJmYWlsZWQgdG8gYXN5bmNocm9ub3VzbHkgcHJlcGFyZSB3YXNtOiAiK08pLGNlKE8pfSl9ZnVuY3Rpb24gTigpe3JldHVybiFnJiZ0eXBlb2YgV2ViQXNzZW1ibHkuaW5zdGFudGlhdGVTdHJlYW1pbmc9PSJmdW5jdGlvbiImJiFsaShqKSYmdHlwZW9mIGZldGNoPT0iZnVuY3Rpb24iP2ZldGNoKGose2NyZWRlbnRpYWxzOiJzYW1lLW9yaWdpbiJ9KS50aGVuKGZ1bmN0aW9uKHcpe3ZhciBPPVdlYkFzc2VtYmx5Lmluc3RhbnRpYXRlU3RyZWFtaW5nKHcsYyk7cmV0dXJuIE8udGhlbihfLGZ1bmN0aW9uKEspe3JldHVybiBsKCJ3YXNtIHN0cmVhbWluZyBjb21waWxlIGZhaWxlZDogIitLKSxsKCJmYWxsaW5nIGJhY2sgdG8gQXJyYXlCdWZmZXIgaW5zdGFudGlhdGlvbiIpLFQoXyl9KX0pOlQoXyl9aWYodC5pbnN0YW50aWF0ZVdhc20pdHJ5e3ZhciBrPXQuaW5zdGFudGlhdGVXYXNtKGMsbSk7cmV0dXJuIGt9Y2F0Y2godyl7cmV0dXJuIGwoIk1vZHVsZS5pbnN0YW50aWF0ZVdhc20gY2FsbGJhY2sgZmFpbGVkIHdpdGggZXJyb3I6ICIrdyksITF9cmV0dXJuIE4oKS5jYXRjaChpKSx7fX1mdW5jdGlvbiBUcihjKXtmb3IoO2MubGVuZ3RoPjA7KXt2YXIgbT1jLnNoaWZ0KCk7aWYodHlwZW9mIG09PSJmdW5jdGlvbiIpe20odCk7Y29udGludWV9dmFyIF89bS5mdW5jO3R5cGVvZiBfPT0ibnVtYmVyIj9tLmFyZz09PXZvaWQgMD9Fci5nZXQoXykoKTpFci5nZXQoXykobS5hcmcpOl8obS5hcmc9PT12b2lkIDA/bnVsbDptLmFyZyl9fWZ1bmN0aW9uIFVmKGMsbSxfLFQpe2NlKCJBc3NlcnRpb24gZmFpbGVkOiAiKyQoYykrIiwgYXQ6ICIrW20/JChtKToidW5rbm93biBmaWxlbmFtZSIsXyxUPyQoVCk6InVua25vd24gZnVuY3Rpb24iXSl9ZnVuY3Rpb24ga2YoYyxtKXtjZSgiVG8gdXNlIGRsb3BlbiwgeW91IG5lZWQgdG8gdXNlIEVtc2NyaXB0ZW4ncyBsaW5raW5nIHN1cHBvcnQsIHNlZSBodHRwczovL2dpdGh1Yi5jb20vZW1zY3JpcHRlbi1jb3JlL2Vtc2NyaXB0ZW4vd2lraS9MaW5raW5nIil9ZnVuY3Rpb24gQ2YoYyxtKXtjZSgiVG8gdXNlIGRsb3BlbiwgeW91IG5lZWQgdG8gdXNlIEVtc2NyaXB0ZW4ncyBsaW5raW5nIHN1cHBvcnQsIHNlZSBodHRwczovL2dpdGh1Yi5jb20vZW1zY3JpcHRlbi1jb3JlL2Vtc2NyaXB0ZW4vd2lraS9MaW5raW5nIil9ZnVuY3Rpb24gT2YoKXtjZSgiIil9dmFyIFR0O1R0PWZ1bmN0aW9uKCl7cmV0dXJuIHBlcmZvcm1hbmNlLm5vdygpfTt2YXIgQmY9ITA7ZnVuY3Rpb24gTGYoYyl7cmV0dXJuIFlbbWkoKT4+Ml09YyxjfWZ1bmN0aW9uIEdmKGMsbSl7dmFyIF87aWYoYz09PTApXz1EYXRlLm5vdygpO2Vsc2UgaWYoKGM9PT0xfHxjPT09NCkmJkJmKV89VHQoKTtlbHNlIHJldHVybiBMZigyOCksLTE7cmV0dXJuIFlbbT4+Ml09Xy8xZTN8MCxZW20rND4+Ml09XyUxZTMqMWUzKjFlM3wwLDB9ZnVuY3Rpb24gJGYoKXtyZXR1cm4gMjE0NzQ4MzY0OH1mdW5jdGlvbiB6ZihjLG0sXyl7TGUuY29weVdpdGhpbihjLG0sbStfKX1mdW5jdGlvbiBXZihjKXt0cnl7cmV0dXJuIHYuZ3JvdyhjLXNpLmJ5dGVMZW5ndGgrNjU1MzU+Pj4xNiksYWkodi5idWZmZXIpLDF9Y2F0Y2h7fX1mdW5jdGlvbiBWZihjKXt2YXIgbT1MZS5sZW5ndGg7Yz1jPj4+MDt2YXIgXz0yMTQ3NDgzNjQ4O2lmKGM+XylyZXR1cm4hMTtmb3IodmFyIFQ9MTtUPD00O1QqPTIpe3ZhciBOPW0qKDErLjIvVCk7Tj1NYXRoLm1pbihOLGMrMTAwNjYzMjk2KTt2YXIgaz1NYXRoLm1pbihfLEgoTWF0aC5tYXgoYyxOKSw2NTUzNikpLHc9V2Yoayk7aWYodylyZXR1cm4hMH1yZXR1cm4hMX1mdW5jdGlvbiBIZihjKXtmb3IodmFyIG09VHQoKTtUdCgpLW08YzspO312YXIgQXI9e307ZnVuY3Rpb24gWWYoKXtyZXR1cm4gYXx8Ii4vdGhpcy5wcm9ncmFtIn1mdW5jdGlvbiAkZSgpe2lmKCEkZS5zdHJpbmdzKXt2YXIgYz0odHlwZW9mIG5hdmlnYXRvcj09Im9iamVjdCImJm5hdmlnYXRvci5sYW5ndWFnZXMmJm5hdmlnYXRvci5sYW5ndWFnZXNbMF18fCJDIikucmVwbGFjZSgiLSIsIl8iKSsiLlVURi04IixtPXtVU0VSOiJ3ZWJfdXNlciIsTE9HTkFNRToid2ViX3VzZXIiLFBBVEg6Ii8iLFBXRDoiLyIsSE9NRToiL2hvbWUvd2ViX3VzZXIiLExBTkc6YyxfOllmKCl9O2Zvcih2YXIgXyBpbiBBcilBcltfXT09PXZvaWQgMD9kZWxldGUgbVtfXTptW19dPUFyW19dO3ZhciBUPVtdO2Zvcih2YXIgXyBpbiBtKVQucHVzaChfKyI9IittW19dKTskZS5zdHJpbmdzPVR9cmV0dXJuICRlLnN0cmluZ3N9dmFyIEF0PXttYXBwaW5nczp7fSxidWZmZXJzOltudWxsLFtdLFtdXSxwcmludENoYXI6ZnVuY3Rpb24oYyxtKXt2YXIgXz1BdC5idWZmZXJzW2NdO209PT0wfHxtPT09MTA/KChjPT09MT94OmwpKEcoXywwKSksXy5sZW5ndGg9MCk6Xy5wdXNoKG0pfSx2YXJhcmdzOnZvaWQgMCxnZXQ6ZnVuY3Rpb24oKXtBdC52YXJhcmdzKz00O3ZhciBjPVlbQXQudmFyYXJncy00Pj4yXTtyZXR1cm4gY30sZ2V0U3RyOmZ1bmN0aW9uKGMpe3ZhciBtPSQoYyk7cmV0dXJuIG19LGdldDY0OmZ1bmN0aW9uKGMsbSl7cmV0dXJuIGN9fTtmdW5jdGlvbiBqZihjLG0pe3ZhciBfPTA7cmV0dXJuICRlKCkuZm9yRWFjaChmdW5jdGlvbihULE4pe3ZhciBrPW0rXztZW2MrTio0Pj4yXT1rLFooVCxrKSxfKz1ULmxlbmd0aCsxfSksMH1mdW5jdGlvbiBYZihjLG0pe3ZhciBfPSRlKCk7WVtjPj4yXT1fLmxlbmd0aDt2YXIgVD0wO3JldHVybiBfLmZvckVhY2goZnVuY3Rpb24oTil7VCs9Ti5sZW5ndGgrMX0pLFlbbT4+Ml09VCwwfWZ1bmN0aW9uIFFmKGMpe3JsKGMpfWZ1bmN0aW9uIEtmKGMpe3JldHVybiAwfWZ1bmN0aW9uIHFmKGMsbSxfLFQsTil7fWZ1bmN0aW9uIEpmKGMsbSxfLFQpe2Zvcih2YXIgTj0wLGs9MDtrPF87aysrKXtmb3IodmFyIHc9WVttK2sqOD4+Ml0sTz1ZW20rKGsqOCs0KT4+Ml0sSz0wO0s8TztLKyspQXQucHJpbnRDaGFyKGMsTGVbdytLXSk7Tis9T31yZXR1cm4gWVtUPj4yXT1OLDB9ZnVuY3Rpb24gWmYoKXtpZih0eXBlb2YgY3J5cHRvPT0ib2JqZWN0IiYmdHlwZW9mIGNyeXB0by5nZXRSYW5kb21WYWx1ZXM9PSJmdW5jdGlvbiIpe3ZhciBjPW5ldyBVaW50OEFycmF5KDEpO3JldHVybiBmdW5jdGlvbigpe3JldHVybiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKGMpLGNbMF19fWVsc2UgcmV0dXJuIGZ1bmN0aW9uKCl7Y2UoInJhbmRvbURldmljZSIpfX1mdW5jdGlvbiB3dChjLG0pe3d0LnJhbmRvbURldmljZXx8KHd0LnJhbmRvbURldmljZT1aZigpKTtmb3IodmFyIF89MDtfPG07XysrKUV0W2MrXz4+MF09d3QucmFuZG9tRGV2aWNlKCk7cmV0dXJuIDB9dmFyIGVsPXthOlVmLGU6a2YsZDpDZixiOk9mLG46R2YsaDokZixsOnpmLG06VmYscDpIZixmOmpmLGc6WGYsajpRZixpOktmLGs6cWYsYzpKZixvOnd0fTtNZigpLHQuX19fd2FzbV9jYWxsX2N0b3JzPWZ1bmN0aW9uKCl7cmV0dXJuKHQuX19fd2FzbV9jYWxsX2N0b3JzPXQuYXNtLnIpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sdC5fZ2V0TW9kZWxCdWZmZXJNZW1vcnlPZmZzZXQ9ZnVuY3Rpb24oKXtyZXR1cm4odC5fZ2V0TW9kZWxCdWZmZXJNZW1vcnlPZmZzZXQ9dC5hc20ucykuYXBwbHkobnVsbCxhcmd1bWVudHMpfSx0Ll9nZXRJbnB1dE1lbW9yeU9mZnNldD1mdW5jdGlvbigpe3JldHVybih0Ll9nZXRJbnB1dE1lbW9yeU9mZnNldD10LmFzbS50KS5hcHBseShudWxsLGFyZ3VtZW50cyl9LHQuX2dldElucHV0SGVpZ2h0PWZ1bmN0aW9uKCl7cmV0dXJuKHQuX2dldElucHV0SGVpZ2h0PXQuYXNtLnUpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sdC5fZ2V0SW5wdXRXaWR0aD1mdW5jdGlvbigpe3JldHVybih0Ll9nZXRJbnB1dFdpZHRoPXQuYXNtLnYpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sdC5fZ2V0SW5wdXRDaGFubmVsQ291bnQ9ZnVuY3Rpb24oKXtyZXR1cm4odC5fZ2V0SW5wdXRDaGFubmVsQ291bnQ9dC5hc20udykuYXBwbHkobnVsbCxhcmd1bWVudHMpfSx0Ll9nZXRPdXRwdXRNZW1vcnlPZmZzZXQ9ZnVuY3Rpb24oKXtyZXR1cm4odC5fZ2V0T3V0cHV0TWVtb3J5T2Zmc2V0PXQuYXNtLngpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sdC5fZ2V0T3V0cHV0SGVpZ2h0PWZ1bmN0aW9uKCl7cmV0dXJuKHQuX2dldE91dHB1dEhlaWdodD10LmFzbS55KS5hcHBseShudWxsLGFyZ3VtZW50cyl9LHQuX2dldE91dHB1dFdpZHRoPWZ1bmN0aW9uKCl7cmV0dXJuKHQuX2dldE91dHB1dFdpZHRoPXQuYXNtLnopLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sdC5fZ2V0T3V0cHV0Q2hhbm5lbENvdW50PWZ1bmN0aW9uKCl7cmV0dXJuKHQuX2dldE91dHB1dENoYW5uZWxDb3VudD10LmFzbS5BKS5hcHBseShudWxsLGFyZ3VtZW50cyl9LHQuX2xvYWRNb2RlbD1mdW5jdGlvbigpe3JldHVybih0Ll9sb2FkTW9kZWw9dC5hc20uQikuYXBwbHkobnVsbCxhcmd1bWVudHMpfSx0Ll9ydW5JbmZlcmVuY2U9ZnVuY3Rpb24oKXtyZXR1cm4odC5fcnVuSW5mZXJlbmNlPXQuYXNtLkMpLmFwcGx5KG51bGwsYXJndW1lbnRzKX0sdC5faXNHUFVFbmFibGVkPWZ1bmN0aW9uKCl7cmV0dXJuKHQuX2lzR1BVRW5hYmxlZD10LmFzbS5EKS5hcHBseShudWxsLGFyZ3VtZW50cyl9O3ZhciBtaT10Ll9fX2Vycm5vX2xvY2F0aW9uPWZ1bmN0aW9uKCl7cmV0dXJuKG1pPXQuX19fZXJybm9fbG9jYXRpb249dC5hc20uRikuYXBwbHkobnVsbCxhcmd1bWVudHMpfSxTdDtmdW5jdGlvbiB0bChjKXt0aGlzLm5hbWU9IkV4aXRTdGF0dXMiLHRoaXMubWVzc2FnZT0iUHJvZ3JhbSB0ZXJtaW5hdGVkIHdpdGggZXhpdCgiK2MrIikiLHRoaXMuc3RhdHVzPWN9R2U9ZnVuY3Rpb24gYygpe1N0fHx3cigpLFN0fHwoR2U9Yyl9O2Z1bmN0aW9uIHdyKGMpe2lmKGdlPjB8fChUZigpLGdlPjApKXJldHVybjtmdW5jdGlvbiBtKCl7U3R8fChTdD0hMCx0LmNhbGxlZFJ1bj0hMCwhSSYmKEFmKCksbih0KSx0Lm9uUnVudGltZUluaXRpYWxpemVkJiZ0Lm9uUnVudGltZUluaXRpYWxpemVkKCksd2YoKSkpfXQuc2V0U3RhdHVzPyh0LnNldFN0YXR1cygiUnVubmluZy4uLiIpLHNldFRpbWVvdXQoZnVuY3Rpb24oKXtzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7dC5zZXRTdGF0dXMoIiIpfSwxKSxtKCl9LDEpKTptKCl9dC5ydW49d3I7ZnVuY3Rpb24gcmwoYyxtKXtubChjKX1mdW5jdGlvbiBubChjKXtFZigpfHwodC5vbkV4aXQmJnQub25FeGl0KGMpLEk9ITApLHUoYyxuZXcgdGwoYykpfWlmKHQucHJlSW5pdClmb3IodHlwZW9mIHQucHJlSW5pdD09ImZ1bmN0aW9uIiYmKHQucHJlSW5pdD1bdC5wcmVJbml0XSk7dC5wcmVJbml0Lmxlbmd0aD4wOyl0LnByZUluaXQucG9wKCkoKTtyZXR1cm4gd3IoKSxlLnJlYWR5fX0oKTtjbGFzcyBwZntjb25zdHJ1Y3Rvcigpe3AodGhpcywic2VsZWN0ZWRURkxpdGUiKTtwKHRoaXMsImlzU0lNRFN1cHBvcnRlZCIsITEpO3AodGhpcywiaXNUaHJlYWRzU3VwcG9ydGVkIiwhMSk7cCh0aGlzLCJpbnB1dFdpZHRoIiwwKTtwKHRoaXMsImlucHV0SGVpZ2h0IiwwKTtwKHRoaXMsImlucHV0Q2hhbm5lbENvdW50IiwwKTtwKHRoaXMsImlucHV0TWVtb3J5T2Zmc2V0IiwwKTtwKHRoaXMsIm91dHB1dFdpZHRoIiwwKTtwKHRoaXMsIm91dHB1dEhlaWdodCIsMCk7cCh0aGlzLCJvdXRwdXRDaGFubmVsQ291bnQiLDApO3AodGhpcywib3V0cHV0TWVtb3J5T2Zmc2V0IiwwKX19Y29uc3QgeWY9Imh0dHBzOi8vZDNvcHFqbXF6eGYwNTcuY2xvdWRmcm9udC5uZXQvdm9uYWdlLXRlbnNvcmZsb3ctd2FzbS90ZmxpdGUtc2ltZC13YXNtLzEuMS4zLyIsX2Y9Imh0dHBzOi8vZDNvcHFqbXF6eGYwNTcuY2xvdWRmcm9udC5uZXQvbWwvc2VsZmllX3NlZ21lbnRhdGlvbi80LjAuMC8iO2FzeW5jIGZ1bmN0aW9uIHhmKHI9eWYsZT1fZil7bGV0IHQ9bmV3IHBmO3ZhciBuPW5ldyBQcm9taXNlKGZ1bmN0aW9uKGksbyl7YXN5bmMgZnVuY3Rpb24gcygpe3JldHVybiBoZih7bG9jYXRlRmlsZTpmdW5jdGlvbihmKXtyZXR1cm4gcitmfX0pfWFzeW5jIGZ1bmN0aW9uIGEodSl7cmV0dXJuIG5ldyBQcm9taXNlKGFzeW5jKGYsZCk9Pntjb25zdCBoPXU7aWYodHlwZW9mIGg+InUiKXJldHVybiBkKCJURkxpdGUgYmFja2VuZCB1bmF2YWlsYWJsZTogd2FzbVNpbWQiKTtjb25zdCB5PSJzZWxmaWVfc2VnbWVudGF0aW9uX2xhbmRzY2FwZSI7Y29uc29sZS5sb2coIkxvYWRpbmcgdGZsaXRlIG1vZGVsOiIseSk7bGV0IHg9ZStgJHt5fS50ZmxpdGVgO2NvbnNvbGUubG9nKCJURkxpdGUgbW9kZWxVcmw6ICIreCk7dHJ5e2NvbnN0IGc9YXdhaXQoYXdhaXQgZmV0Y2goeCkpLmFycmF5QnVmZmVyKCk7Y29uc29sZS5sb2coIk1vZGVsIGJ1ZmZlciBzaXplOiIsZy5ieXRlTGVuZ3RoKTtjb25zdCBFPWguX2dldE1vZGVsQnVmZmVyTWVtb3J5T2Zmc2V0KCk7Y29uc29sZS5sb2coIk1vZGVsIGJ1ZmZlciBtZW1vcnkgb2Zmc2V0OiIsRSksY29uc29sZS5sb2coIkxvYWRpbmcgbW9kZWwgYnVmZmVyLi4uIiksaC5IRUFQVTguc2V0KG5ldyBVaW50OEFycmF5KGcpLEUpO2NvbnN0IHY9aC5fbG9hZE1vZGVsKGcuYnl0ZUxlbmd0aCk7aWYoY29uc29sZS5sb2coIkxvYWQgbW9kZWwgcmVzdWx0OiIsdiksdiE9PTApe2QoIkNhbm5vdCBsb2FkIG1vZGVsIik7cmV0dXJufXQuaW5wdXRXaWR0aD1oLl9nZXRJbnB1dFdpZHRoKCksdC5pbnB1dEhlaWdodD1oLl9nZXRJbnB1dEhlaWdodCgpLHQuaW5wdXRDaGFubmVsQ291bnQ9aC5fZ2V0SW5wdXRDaGFubmVsQ291bnQoKSx0LmlucHV0TWVtb3J5T2Zmc2V0PWguX2dldElucHV0TWVtb3J5T2Zmc2V0KCksY29uc29sZS5sb2coIklucHV0IG1lbW9yeSBvZmZzZXQ6Iix0LmlucHV0TWVtb3J5T2Zmc2V0KSxjb25zb2xlLmxvZygiSW5wdXQgaGVpZ2h0OiIsdC5pbnB1dEhlaWdodCksY29uc29sZS5sb2coIklucHV0IHdpZHRoOiIsdC5pbnB1dFdpZHRoKSxjb25zb2xlLmxvZygiSW5wdXQgY2hhbm5lbHM6Iix0LmlucHV0Q2hhbm5lbENvdW50KSx0Lm91dHB1dE1lbW9yeU9mZnNldD1oLl9nZXRPdXRwdXRNZW1vcnlPZmZzZXQoKSx0Lm91dHB1dFdpZHRoPWguX2dldE91dHB1dFdpZHRoKCksdC5vdXRwdXRIZWlnaHQ9aC5fZ2V0T3V0cHV0SGVpZ2h0KCksdC5vdXRwdXRDaGFubmVsQ291bnQ9aC5fZ2V0T3V0cHV0Q2hhbm5lbENvdW50KCksY29uc29sZS5sb2coIk91dHB1dCBtZW1vcnkgb2Zmc2V0OiIsdC5vdXRwdXRNZW1vcnlPZmZzZXQpLGNvbnNvbGUubG9nKCJPdXRwdXQgaGVpZ2h0OiIsdC5vdXRwdXRIZWlnaHQpLGNvbnNvbGUubG9nKCJPdXRwdXQgd2lkdGg6Iix0Lm91dHB1dFdpZHRoKSxjb25zb2xlLmxvZygiT3V0cHV0IGNoYW5uZWxzOiIsdC5vdXRwdXRDaGFubmVsQ291bnQpLHQuc2VsZWN0ZWRURkxpdGU9aH1jYXRjaChsKXtkKGwpO3JldHVybn1mKCl9KX1zKCkudGhlbih1PT57aWYodT09PW51bGwpdGhyb3cgY29uc29sZS5lcnJvcigibG9hZFRGTGl0ZSBudWxsIiksImxvYWRURkxpdGUgbnVsbCI7YSh1KS50aGVuKGY9PntpKHQpfSkuY2F0Y2goZj0+e2NvbnNvbGUuZXJyb3IoImxvYWRURkxpdGVNb2RlbCBlcnJvciIpLG8oImxvYWRURkxpdGVNb2RlbCBlcnJvciIpfSl9KS5jYXRjaCh1PT57Y29uc29sZS5lcnJvcigibG9hZFRGTGl0ZSBlcnJvcjoiLHUpLG8oImxvYWRURkxpdGUgZXJyb3I6Iit1KX0pfSk7cmV0dXJuIG59Y2xhc3MgZ2Z7Y29uc3RydWN0b3IoKXtwKHRoaXMsImNhbnZhcyIsbmV3IE9mZnNjcmVlbkNhbnZhcygwLDApKTtwKHRoaXMsImNvbnRleHQiLHRoaXMuY2FudmFzLmdldENvbnRleHQoIjJkIix7d2lsbFJlYWRGcmVxdWVudGx5OiEwfSkpO3AodGhpcywicGl4ZWxDb3VudCIsMCk7cCh0aGlzLCJpbnB1dE9mZnNldCIsMCk7cCh0aGlzLCJvdXRwdXRPZmZzZXQiLDApO3AodGhpcywiaW5mb3MiKTtwKHRoaXMsIm1hc2siKX1hc3luYyBpbml0KGUsdCl7YXdhaXQgdGhpcy5pbml0V2FzbShlLHQpLHRoaXMuaW5mb3MmJih0aGlzLmNhbnZhcy53aWR0aD10aGlzLmluZm9zLmlucHV0V2lkdGgsdGhpcy5jYW52YXMuaGVpZ2h0PXRoaXMuaW5mb3MuaW5wdXRIZWlnaHQsdGhpcy5waXhlbENvdW50PXRoaXMuaW5mb3MuaW5wdXRXaWR0aCp0aGlzLmluZm9zLmlucHV0SGVpZ2h0LHRoaXMubWFzaz1uZXcgSW1hZ2VEYXRhKHRoaXMuaW5mb3MuaW5wdXRXaWR0aCx0aGlzLmluZm9zLmlucHV0SGVpZ2h0KSx0aGlzLmlucHV0T2Zmc2V0PXRoaXMuaW5mb3MuaW5wdXRNZW1vcnlPZmZzZXQvNCx0aGlzLm91dHB1dE9mZnNldD10aGlzLmluZm9zLm91dHB1dE1lbW9yeU9mZnNldC80KX1hc3luYyBpbml0V2FzbShlLHQpe3RoaXMuaW5mb3M9YXdhaXQgeGYoZSx0KX1nZXRPdXRwdXREaW1lbnNpb25zKCl7dmFyIGUsdCxuLGk7cmV0dXJue3dpZHRoOih0PShlPXRoaXMuaW5mb3MpPT1udWxsP3ZvaWQgMDplLm91dHB1dFdpZHRoKSE9bnVsbD90OjAsaGVpZ2h0OihpPShuPXRoaXMuaW5mb3MpPT1udWxsP3ZvaWQgMDpuLm91dHB1dEhlaWdodCkhPW51bGw/aTowfX1hc3luYyBwcm9jZXNzKGUpe2lmKCF0aGlzLm1hc2t8fCF0aGlzLmluZm9zKXJldHVybjtjb25zdCB0PXRoaXMuaW5mb3MuaW5wdXRXaWR0aCxuPXRoaXMuaW5mb3MuaW5wdXRIZWlnaHQ7dGhpcy5jb250ZXh0LmRyYXdJbWFnZShlLDAsMCxlLndpZHRoLGUuaGVpZ2h0LDAsMCx0LG4pO2NvbnN0IGk9dGhpcy5jb250ZXh0LmdldEltYWdlRGF0YSgwLDAsdCxuKSxvPXRoaXMuaW5mb3Muc2VsZWN0ZWRURkxpdGUuSEVBUEYzMjtmb3IobGV0IHM9MDtzPHRoaXMucGl4ZWxDb3VudDtzKyspe2NvbnN0IGE9dGhpcy5pbnB1dE9mZnNldCtzKjM7b1thXT1pLmRhdGFbcyo0XS8yNTUsb1thKzFdPWkuZGF0YVtzKjQrMV0vMjU1LG9bYSsyXT1pLmRhdGFbcyo0KzJdLzI1NX10aGlzLmluZm9zLnNlbGVjdGVkVEZMaXRlLl9ydW5JbmZlcmVuY2UoKTtmb3IobGV0IHM9MDtzPHRoaXMucGl4ZWxDb3VudDtzKyspe2NvbnN0IGE9dGhpcy5pbmZvcy5zZWxlY3RlZFRGTGl0ZS5IRUFQRjMyW3RoaXMub3V0cHV0T2Zmc2V0K3NdO3RoaXMubWFzay5kYXRhW3MqNF09dGhpcy5tYXNrLmRhdGFbcyo0KzNdPTI1NSphfXJldHVybiBjcmVhdGVJbWFnZUJpdG1hcCh0aGlzLm1hc2spfWlzR3B1U3VwcG9ydGVkKCl7dmFyIGUsdCxuO3JldHVybihuPSh0PShlPXRoaXMuaW5mb3MpPT1udWxsP3ZvaWQgMDplLnNlbGVjdGVkVEZMaXRlKT09bnVsbD92b2lkIDA6dC5faXNHUFVFbmFibGVkKCkpIT1udWxsP246ITF9fWNsYXNzIGJme2NvbnN0cnVjdG9yKCl7cCh0aGlzLCJzZWxmaWVTZWdtZW50YXRpb24iLG5ldyBnZik7cCh0aGlzLCJiYWNrZ3JvdW5kRmlsdGVyIik7cCh0aGlzLCJyZXBvcnRlciIsbmV3IElvKTtwKHRoaXMsInByZXZpb3VzRGltZW5zaW9ucyIse3dpZHRoOjAsaGVpZ2h0OjB9KTtwKHRoaXMsImJhY2tncm91bmRPcHRpb25zIil9YXN5bmMgaW5pdChlLHQpe2F3YWl0IHRoaXMuc2VsZmllU2VnbWVudGF0aW9uLmluaXQodC53YXNtQXNzZXRVcmlQYXRoLHQudGZsaXRlQXNzZXRVcmlQYXRoKTtjb25zdHt3aWR0aDpuLGhlaWdodDppfT10aGlzLnNlbGZpZVNlZ21lbnRhdGlvbi5nZXRPdXRwdXREaW1lbnNpb25zKCk7dGhpcy5iYWNrZ3JvdW5kRmlsdGVyPW5ldyBtZihlLHtmb3JlZ3JvdW5kV2lkdGg6MSxmb3JlZ3JvdW5kSGVpZ2h0OjEsbWFza1dpZHRoOm4sbWFza0hlaWdodDppfSksdGhpcy5yZXBvcnQoe3ZhcmlhdGlvbjoiQ3JlYXRlIn0pfWFzeW5jIHRyYW5zZm9ybShlLHQpe3ZhciBzLGEsdSxmO2NvbnN0IG49KHM9ZS50aW1lc3RhbXApIT1udWxsP3M6MCxpPWF3YWl0IGNyZWF0ZUltYWdlQml0bWFwKGUpLG89YXdhaXQgdGhpcy5zZWxmaWVTZWdtZW50YXRpb24ucHJvY2VzcyhpKTtvPygoaS53aWR0aCE9PXRoaXMucHJldmlvdXNEaW1lbnNpb25zLndpZHRofHxpLmhlaWdodCE9PXRoaXMucHJldmlvdXNEaW1lbnNpb25zLmhlaWdodCkmJih0aGlzLnByZXZpb3VzRGltZW5zaW9ucy53aWR0aD1pLndpZHRoLHRoaXMucHJldmlvdXNEaW1lbnNpb25zLmhlaWdodD1pLmhlaWdodCxhd2FpdCgoYT10aGlzLmJhY2tncm91bmRGaWx0ZXIpPT1udWxsP3ZvaWQgMDphLnJlc2l6ZUZvcmVncm91bmQoaS53aWR0aCxpLmhlaWdodCkpKSxhd2FpdCgodT10aGlzLmJhY2tncm91bmRGaWx0ZXIpPT1udWxsP3ZvaWQgMDp1LnByb2Nlc3MoaSxvKSksZS5jbG9zZSgpLHQuZW5xdWV1ZShuZXcgVmlkZW9GcmFtZSgoZj10aGlzLmJhY2tncm91bmRGaWx0ZXIpPT1udWxsP3ZvaWQgMDpmLmNhbnZhcyx7dGltZXN0YW1wOm4sYWxwaGE6ImRpc2NhcmQifSkpKTp0LmVucXVldWUoZSl9YXN5bmMgc2V0QmFja2dyb3VuZE9wdGlvbnMoZSl7dmFyIHQ7dGhpcy5iYWNrZ3JvdW5kT3B0aW9ucz1lLGF3YWl0KCh0PXRoaXMuYmFja2dyb3VuZEZpbHRlcik9PW51bGw/dm9pZCAwOnQuc2V0QmFja2dyb3VuZE9wdGlvbnMoZSkpLHRoaXMucmVwb3J0KHt2YXJpYXRpb246IlVwZGF0ZSJ9KX1hc3luYyBzZXRWaWRlb0JHUmVhZGFibGUoZSl7dmFyIHQ7YXdhaXQoKHQ9dGhpcy5iYWNrZ3JvdW5kRmlsdGVyKT09bnVsbD92b2lkIDA6dC5zZXRWaWRlb0JHUmVhZGFibGUoZSkpfWFzeW5jIHNldFZpcnR1YWxCR0ltYWdlKGUpe3ZhciB0O2F3YWl0KCh0PXRoaXMuYmFja2dyb3VuZEZpbHRlcik9PW51bGw/dm9pZCAwOnQuc2V0VmlydHVhbEJHSW1hZ2UoZSkpfXNldEZsaWNrZXJpbmdPcHRpb25zKGUpe3ZhciB0Oyh0PXRoaXMuYmFja2dyb3VuZEZpbHRlcik9PW51bGx8fHQuc2V0RmxpY2tlcmluZ09wdGlvbnMoZSksdGhpcy5yZXBvcnQoe3ZhcmlhdGlvbjoiVXBkYXRlIn0pfWFzeW5jIHByb2ZpbGUoZSl7dmFyIHQsbjtyZXR1cm4obj0odD10aGlzLmJhY2tncm91bmRGaWx0ZXIpPT1udWxsP3ZvaWQgMDp0LnByb2ZpbGUoZSkpIT1udWxsP246W119Z2V0VHJhbnNmb3JtZXJUeXBlKCl7dmFyIGUsdDtyZXR1cm4odD0oZT10aGlzLmJhY2tncm91bmRPcHRpb25zKT09bnVsbD92b2lkIDA6ZS50cmFuc2Zvcm1lclR5cGUpIT1udWxsP3Q6IlVuZGVmaW5lZCJ9cmVwb3J0KGUpe3ZhciB0O3RoaXMucmVwb3J0ZXIuc2VuZCh7dmVyc2lvbjpGbyxhY3Rpb246Ik1sVHJhbnNmb3JtZXJzIix0cmFuc2Zvcm1lclR5cGU6KHQ9dGhpcy5iYWNrZ3JvdW5kT3B0aW9ucyk9PW51bGw/dm9pZCAwOnQudHJhbnNmb3JtZXJUeXBlLGNvbmZpZzpKU09OLnN0cmluZ2lmeSh0aGlzLmJhY2tncm91bmRPcHRpb25zKSwuLi5lfSl9fWNvbnN0IHZyPWNsYXNze2NvbnN0cnVjdG9yKCl7cCh0aGlzLCJiYWNrZ3JvdW5kVHJhbnNmb3JtZXIiLG5ldyBiZik7cCh0aGlzLCJtZWRpYVByb2Nlc3NvciIsbmV3IG5vKTtwKHRoaXMsInJhdGUiLDMwKTtwKHRoaXMsInJlc29sdmVPbk1lZGlhUHJvY2Vzc29yIik7cCh0aGlzLCJldmVudHNRdWV1ZSIsW10pfWFzeW5jIGluaXQoZSx0KXthd2FpdCB0aGlzLmJhY2tncm91bmRUcmFuc2Zvcm1lci5pbml0KGUsdCksYXdhaXQgdGhpcy5tZWRpYVByb2Nlc3Nvci5zZXRUcmFuc2Zvcm1lcnMoW3RoaXMuYmFja2dyb3VuZFRyYW5zZm9ybWVyXSksdGhpcy5tZWRpYVByb2Nlc3Nvci5zZXRUcmFja0V4cGVjdGVkUmF0ZSh0aGlzLnJhdGUpLHRoaXMubWVkaWFQcm9jZXNzb3Iub25BbnkoKG4saSk9Pnt0aGlzLnJlc29sdmVPbk1lZGlhUHJvY2Vzc29yPyh0aGlzLnJlc29sdmVPbk1lZGlhUHJvY2Vzc29yKHtuYW1lOm4sZGF0YTppfSksdGhpcy5yZXNvbHZlT25NZWRpYVByb2Nlc3Nvcj12b2lkIDApOnRoaXMuZXZlbnRzUXVldWUucHVzaCh7bmFtZTpuLGRhdGE6aX0pfSl9YXN5bmMgb25NZWRpYVByb2Nlc3NvckV2ZW50KCl7cmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKGU9Pnt0aGlzLmV2ZW50c1F1ZXVlLmxlbmd0aD4wP2UodGhpcy5ldmVudHNRdWV1ZS5zaGlmdCgpKTp0aGlzLnJlc29sdmVPbk1lZGlhUHJvY2Vzc29yPWV9KX1hc3luYyBzZXRUcmFja0V4cGVjdGVkUmF0ZShlKXt0aGlzLnJhdGU9ZSx0aGlzLm1lZGlhUHJvY2Vzc29yLnNldFRyYWNrRXhwZWN0ZWRSYXRlKGUpfWFzeW5jIHRyYW5zZm9ybShlLHQpe3RoaXMubWVkaWFQcm9jZXNzb3IudHJhbnNmb3JtKGUsdCl9YXN5bmMgc2V0QmFja2dyb3VuZE9wdGlvbnMoZSl7dmFyIHQ7YXdhaXQoKHQ9dGhpcy5iYWNrZ3JvdW5kVHJhbnNmb3JtZXIpPT1udWxsP3ZvaWQgMDp0LnNldEJhY2tncm91bmRPcHRpb25zKGUpKX1zZXRWaWRlb0JHUmVhZGFibGUoZSl7dGhpcy5iYWNrZ3JvdW5kVHJhbnNmb3JtZXIuc2V0VmlkZW9CR1JlYWRhYmxlKGUpfWFzeW5jIHNldFZpcnR1YWxCR0ltYWdlKGUpe2F3YWl0IHRoaXMuYmFja2dyb3VuZFRyYW5zZm9ybWVyLnNldFZpcnR1YWxCR0ltYWdlKGUpfWFzeW5jIHRlcm1pbmF0ZSgpe2F3YWl0IHRoaXMubWVkaWFQcm9jZXNzb3IuZGVzdHJveSgpfXNldEZsaWNrZXJpbmdPcHRpb25zKGUpe3RoaXMuYmFja2dyb3VuZFRyYW5zZm9ybWVyLnNldEZsaWNrZXJpbmdPcHRpb25zKGUpfXNldFZvbmFnZU1ldGFkYXRhKGUpe3FpKGUpfWFzeW5jIHByb2ZpbGUoZSl7cmV0dXJuIEpTT04uc3RyaW5naWZ5KGF3YWl0IHRoaXMuYmFja2dyb3VuZFRyYW5zZm9ybWVyLnByb2ZpbGUoZSkpfX07bGV0IG9pPXZyOygoKT0+e19pKCJQcm9jZXNzb3JXb3JrZXIiLHZyKX0pKCl9KSgpOwo=",Ml=typeof window<"u"&&window.Blob&&new Blob([atob(Al)],{type:"text/javascript;charset=utf-8"});function n3(){const i=Ml&&(window.URL||window.webkitURL).createObjectURL(Ml);try{return i?new Worker(i):new Worker("data:application/javascript;base64,"+Al)}finally{i&&(window.URL||window.webkitURL).revokeObjectURL(i)}}const Qo=class extends cr{constructor(){super(...arguments);Wt(this,"rate",30);Wt(this,"worker")}async init(r){this.worker=await B2(zo,n3),await this.worker.init(`worker_${Qo.initCount++}`,r),await this.worker.setVonageMetadata(li()),await this.setBackgroundOptions(r),this.listenWorker()}async setTrackExpectedRate(r){var p;await((p=this.worker)==null?void 0:p.setTrackExpectedRate(r))}async setBackgroundOptions(r){var G,S,H;const{transformerType:p}=r;switch(p){case"VideoBackground":await((G=this.worker)==null?void 0:G.setVideoBGReadable(await ys.createVideoReadable(r.backgroundAssetUri)));break;case"VirtualBackground":await((S=this.worker)==null?void 0:S.setVirtualBGImage(await ys.createImageCanvas(r.backgroundAssetUri)));break}await((H=this.worker)==null?void 0:H.setBackgroundOptions(r))}async transform(r,p){var G;await((G=this.worker)==null?void 0:G.transform(r,p))}async destroy(){var r;await((r=this.worker)==null?void 0:r.terminate())}async setFlickeringOptions(r){var p;await((p=this.worker)==null?void 0:p.setFlickeringOptions(r))}async profile(r){var G;const p=await((G=this.worker)==null?void 0:G.profile(r));return JSON.parse(p!=null?p:"[]")}async listenWorker(){var r,p,G;for(;(r=this.worker)!=null&&r.workerContext.worker;){const{name:S,data:H}=await((p=this.worker)==null?void 0:p.onMediaProcessorEvent());switch(S){case"error":case"warn":this.emit(S,H);break;case"pipelineInfo":switch(this.emit(S,H),H){case"pipeline_ended":case"pipeline_ended_with_error":await((G=this.worker)==null?void 0:G.terminate());return}break}}}};let Qi=Qo;Wt(Qi,"initCount",0);class r3{constructor(n){this.queries=n}async downloadSpeedscope(){this.download(await this.convertToSpeedscope())}download(n){const r=document.createElement("a");r.href=URL.createObjectURL(new Blob([n],{type:"application/json"})),r.download=`profile-${+new Date}.speedscope.json`,document.body.appendChild(r),r.click(),document.body.removeChild(r)}convertToSpeedscope(){const n=[],r={},p=[];let G=0;for(const H of this.queries){const w=[];for(const E of H)r[E.name]===void 0&&(r[E.name]=n.length,n.push({name:E.name})),w.push({type:E.action==Ws.PUSH?"O":"C",frame:r[E.name],at:E.timestamp}),G=Math.max(G,E.timestamp+E.duration);p.push({events:w,type:"evented",name:"GPU Profile",unit:"nanoseconds",startValue:0,endValue:G})}const S={$schema:"https://www.speedscope.app/file-format-schema.json",shared:{frames:n},profiles:p};return JSON.stringify(S,null,2)}}class Po extends cr{constructor(){super();Wt(this,"worker",new Qi);Wt(this,"connector",new x2(this.worker))}async init(r){await this.worker.init(r),this.worker.onAny((p,G)=>this.emit(p,G))}async setBackgroundOptions(r){await this.worker.setBackgroundOptions(r)}setTrackExpectedRate(r){this.worker.setTrackExpectedRate(r)}getConnector(){return this.connector}async profile(r){return this.worker.profile(r)}static async profile(r){const p=await Promise.all(this.instances.map(G=>G.profile(r)));return new r3(p)}static async create(r){const p=new this;return await p.init(r),this.instances.push(p),p}}Wt(Po,"instances",[]);function i3(){return ai}function o3(){return di}function s3(){return hi}function l3(){return fi}function c3(){return mi}function u3(){return pi}function a3(){return bi}async function d3(i){return await Po.create(i)}Ae.BackgroundTransformer=Bl,Ae.BackgroundTransformerType=ls,Ae.BlurRadius=Ar,Ae.ErrorFunction=ss,Ae.MediapipeHelper=yi,Ae.PipelineInfoData=ui,Ae.SelfieSegmentationType=cs,Ae.VonageMediaProcessor=Po,Ae.WarningType=os,Ae.createVonageMediaProcessor=d3,Ae.getSupportedBrowserFeatures=as,Ae.getVonageFaceDetection=l3,Ae.getVonageFaceMash=c3,Ae.getVonageHands=o3,Ae.getVonageHolistic=s3,Ae.getVonageObjectron=u3,Ae.getVonagePose=a3,Ae.getVonageSelfieSegmentation=i3,Ae.isSupported=L2,Object.defineProperties(Ae,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
|