class t{constructor(t=0,F=0,U=0){this.x=t,this.y=F,this.z=U}equals(t){return this.x===t.x&&(this.y===t.y&&this.z===t.z)}add(F){return"number"==typeof F?new t(this.x+F,this.y+F,this.z+F):new t(this.x+F.x,this.y+F.y,this.z+F.z)}subtract(F){return"number"==typeof F?new t(this.x-F,this.y-F,this.z-F):new t(this.x-F.x,this.y-F.y,this.z-F.z)}multiply(F){return"number"==typeof F?new t(this.x*F,this.y*F,this.z*F):F instanceof t?new t(this.x*F.x,this.y*F.y,this.z*F.z):new t(this.x*F.buffer[0]+this.y*F.buffer[4]+this.z*F.buffer[8]+F.buffer[12],this.x*F.buffer[1]+this.y*F.buffer[5]+this.z*F.buffer[9]+F.buffer[13],this.x*F.buffer[2]+this.y*F.buffer[6]+this.z*F.buffer[10]+F.buffer[14])}divide(F){return"number"==typeof F?new t(this.x/F,this.y/F,this.z/F):new t(this.x/F.x,this.y/F.y,this.z/F.z)}cross(F){const U=this.y*F.z-this.z*F.y,l=this.z*F.x-this.x*F.z,n=this.x*F.y-this.y*F.x;return new t(U,l,n)}dot(t){return this.x*t.x+this.y*t.y+this.z*t.z}lerp(F,U){return new t(this.x+(F.x-this.x)*U,this.y+(F.y-this.y)*U,this.z+(F.z-this.z)*U)}min(F){return new t(Math.min(this.x,F.x),Math.min(this.y,F.y),Math.min(this.z,F.z))}max(F){return new t(Math.max(this.x,F.x),Math.max(this.y,F.y),Math.max(this.z,F.z))}getComponent(t){switch(t){case 0:return this.x;case 1:return this.y;case 2:return this.z;default:throw new Error(`Invalid component index: ${t}`)}}minComponent(){return this.xthis.y&&this.x>this.z?0:this.y>this.z?1:2}magnitude(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)}distanceTo(t){return Math.sqrt((this.x-t.x)**2+(this.y-t.y)**2+(this.z-t.z)**2)}normalize(){const F=this.magnitude();return new t(this.x/F,this.y/F,this.z/F)}flat(){return[this.x,this.y,this.z]}clone(){return new t(this.x,this.y,this.z)}toString(){return`[${this.flat().join(", ")}]`}static One(F=1){return new t(F,F,F)}}class F{constructor(t=0,F=0,U=0,l=1){this.x=t,this.y=F,this.z=U,this.w=l}equals(t){return this.x===t.x&&(this.y===t.y&&(this.z===t.z&&this.w===t.w))}normalize(){const t=Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w);return new F(this.x/t,this.y/t,this.z/t,this.w/t)}multiply(t){const U=this.w,l=this.x,n=this.y,Q=this.z,e=t.w,d=t.x,A=t.y,B=t.z;return new F(U*d+l*e+n*B-Q*A,U*A-l*B+n*e+Q*d,U*B+l*A-n*d+Q*e,U*e-l*d-n*A-Q*B)}inverse(){const t=this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w;return new F(-this.x/t,-this.y/t,-this.z/t,this.w/t)}apply(U){const l=new F(U.x,U.y,U.z,0),n=new F(-this.x,-this.y,-this.z,this.w),Q=this.multiply(l).multiply(n);return new t(Q.x,Q.y,Q.z)}flat(){return[this.x,this.y,this.z,this.w]}clone(){return new F(this.x,this.y,this.z,this.w)}static FromEuler(t){const U=t.x/2,l=t.y/2,n=t.z/2,Q=Math.cos(l),e=Math.sin(l),d=Math.cos(U),A=Math.sin(U),B=Math.cos(n),a=Math.sin(n);return new F(Q*A*B+e*d*a,e*d*B-Q*A*a,Q*d*a-e*A*B,Q*d*B+e*A*a)}toEuler(){const F=2*(this.w*this.x+this.y*this.z),U=1-2*(this.x*this.x+this.y*this.y),l=Math.atan2(F,U);let n;const Q=2*(this.w*this.y-this.z*this.x);n=Math.abs(Q)>=1?Math.sign(Q)*Math.PI/2:Math.asin(Q);const e=2*(this.w*this.z+this.x*this.y),d=1-2*(this.y*this.y+this.z*this.z),A=Math.atan2(e,d);return new t(l,n,A)}static FromMatrix3(t){const U=t.buffer,l=U[0]+U[4]+U[8];let n,Q,e,d;if(l>0){const t=.5/Math.sqrt(l+1);d=.25/t,n=(U[7]-U[5])*t,Q=(U[2]-U[6])*t,e=(U[3]-U[1])*t}else if(U[0]>U[4]&&U[0]>U[8]){const t=2*Math.sqrt(1+U[0]-U[4]-U[8]);d=(U[7]-U[5])/t,n=.25*t,Q=(U[1]+U[3])/t,e=(U[2]+U[6])/t}else if(U[4]>U[8]){const t=2*Math.sqrt(1+U[4]-U[0]-U[8]);d=(U[2]-U[6])/t,n=(U[1]+U[3])/t,Q=.25*t,e=(U[5]+U[7])/t}else{const t=2*Math.sqrt(1+U[8]-U[0]-U[4]);d=(U[3]-U[1])/t,n=(U[2]+U[6])/t,Q=(U[5]+U[7])/t,e=.25*t}return new F(n,Q,e,d)}static FromAxisAngle(t,U){const l=U/2,n=Math.sin(l),Q=Math.cos(l);return new F(t.x*n,t.y*n,t.z*n,Q)}static LookRotation(U){const l=new t(0,0,1),n=l.dot(U);if(Math.abs(n- -1)<1e-6)return new F(0,1,0,Math.PI);if(Math.abs(n-1)<1e-6)return new F;const Q=Math.acos(n),e=l.cross(U).normalize();return F.FromAxisAngle(e,Q)}toString(){return`[${this.flat().join(", ")}]`}}class U{constructor(){const t=new Map;this.addEventListener=(F,U)=>{t.has(F)||t.set(F,new Set),t.get(F).add(U)},this.removeEventListener=(F,U)=>{t.has(F)&&t.get(F).delete(U)},this.hasEventListener=(F,U)=>!!t.has(F)&&t.get(F).has(U),this.dispatchEvent=F=>{if(t.has(F.type))for(const U of t.get(F.type))U(F)}}}class l{constructor(t=1,F=0,U=0,l=0,n=0,Q=1,e=0,d=0,A=0,B=0,a=1,i=0,V=0,Z=0,R=0,c=1){this.buffer=[t,F,U,l,n,Q,e,d,A,B,a,i,V,Z,R,c]}equals(t){if(this.buffer.length!==t.buffer.length)return!1;if(this.buffer===t.buffer)return!0;for(let F=0;F{},this.applyPosition=()=>{this.position=new t},this.applyRotation=()=>{this.rotation=new F},this.applyScale=()=>{this.scale=new t(1,1,1)},this.raiseChangeEvent=()=>{this.dispatchEvent(this._changeEvent)}}_updateMatrix(){this._transform=l.Compose(this._position,this._rotation,this._scale)}get position(){return this._position}set position(t){this._position.equals(t)||(this._position=t,this.positionChanged=!0,this._updateMatrix(),this.dispatchEvent(this._changeEvent))}get rotation(){return this._rotation}set rotation(t){this._rotation.equals(t)||(this._rotation=t,this.rotationChanged=!0,this._updateMatrix(),this.dispatchEvent(this._changeEvent))}get scale(){return this._scale}set scale(t){this._scale.equals(t)||(this._scale=t,this.scaleChanged=!0,this._updateMatrix(),this.dispatchEvent(this._changeEvent))}get forward(){let F=new t(0,0,1);return F=this.rotation.apply(F),F}get transform(){return this._transform}}class A{constructor(t=1,F=0,U=0,l=0,n=1,Q=0,e=0,d=0,A=1){this.buffer=[t,F,U,l,n,Q,e,d,A]}equals(t){if(this.buffer.length!==t.buffer.length)return!1;if(this.buffer===t.buffer)return!0;for(let F=0;F{for(let F=0;F{const U=A.RotationFromQuaternion(t).buffer;for(let l=0;l{for(let F=0;F{const t=new Uint8Array(this.vertexCount*B.RowLength),F=new Float32Array(t.buffer),U=new Uint8Array(t.buffer);for(let t=0;t{console.assert(t.byteLength===3*this.vertexCount*4,`Expected ${3*this.vertexCount*4} bytes, got ${t.byteLength} bytes`),this._positions=new Float32Array(t),this._rotations=new Float32Array(F),this._scales=new Float32Array(U),this._colors=new Uint8Array(l),this._selection=new Uint8Array(n),this.detached=!1}}static Deserialize(t){const F=t.length/B.RowLength,U=new Float32Array(3*F),l=new Float32Array(4*F),n=new Float32Array(3*F),Q=new Uint8Array(4*F),e=new Float32Array(t.buffer),d=new Uint8Array(t.buffer);for(let t=0;tnew Uint8Array(this._data.buffer)}static Deserialize(t,F,U){const l=new Uint32Array(t.buffer),n=new Float32Array(t.buffer),Q=Math.floor(n.byteLength/this.RowLength),e=new Float32Array(3*Q);for(let t=0;t=this.min.x&&t.x<=this.max.x&&t.y>=this.min.y&&t.y<=this.max.y&&t.z>=this.min.z&&t.z<=this.max.z}intersects(t){return this.max.x>=t.min.x&&this.min.x<=t.max.x&&this.max.y>=t.min.y&&this.min.y<=t.max.y&&this.max.z>=t.min.z&&this.min.z<=t.max.z}size(){return this.max.subtract(this.min)}center(){return this.min.add(this.max).divide(2)}expand(t){this.min=this.min.min(t),this.max=this.max.max(t)}permute(){const F=this.min,U=this.max;this.min=new t(Math.min(F.x,U.x),Math.min(F.y,U.y),Math.min(F.z,U.z)),this.max=new t(Math.max(F.x,U.x),Math.max(F.y,U.y),Math.max(F.z,U.z))}}class Z extends d{constructor(U=void 0){super(),this.selectedChanged=!1,this.colorTransformChanged=!1,this._selected=!1,this._colorTransforms=[],this._colorTransformsMap=new Map,this._data=U||new B,this._bounds=new V(new t(1/0,1/0,1/0),new t(-1/0,-1/0,-1/0)),this.recalculateBounds=()=>{this._bounds=new V(new t(1/0,1/0,1/0),new t(-1/0,-1/0,-1/0));for(let F=0;F{this.data.translate(this.position),this.position=new t},this.applyRotation=()=>{this.data.rotate(this.rotation),this.rotation=new F},this.applyScale=()=>{this.data.scale(this.scale),this.scale=new t(1,1,1)},this.recalculateBounds()}saveToFile(t=null,F="splat"){if(!document)return;if(!t){const U=new Date;t=`splat-${U.getFullYear()}-${U.getMonth()+1}-${U.getDate()}.${F}`}const U=this.clone();U.applyRotation(),U.applyScale(),U.applyPosition();const l=U.data.serialize();let n;if("ply"===F){const t=i.SplatToPLY(l.buffer,U.data.vertexCount);n=new Blob([t],{type:"application/octet-stream"})}else n=new Blob([l.buffer],{type:"application/octet-stream"});const Q=document.createElement("a");Q.download=t,Q.href=URL.createObjectURL(n),Q.click()}get data(){return this._data}get selected(){return this._selected}set selected(t){this._selected!==t&&(this._selected=t,this.selectedChanged=!0,this.dispatchEvent(this._changeEvent))}get colorTransforms(){return this._colorTransforms}get colorTransformsMap(){return this._colorTransformsMap}get bounds(){let t=this._bounds.center();t=t.add(this.position);let F=this._bounds.size();return F=F.multiply(this.scale),new V(t.subtract(F.divide(2)),t.add(F.divide(2)))}clone(){const t=new Z(this.data.clone());return t.position=this.position.clone(),t.rotation=this.rotation.clone(),t.scale=this.scale.clone(),t}}class R extends d{constructor(t){super(),this._data=t}get data(){return this._data}}class c{constructor(){this._fx=1132,this._fy=1132,this._near=.1,this._far=100,this._width=512,this._height=512,this._projectionMatrix=new l,this._viewMatrix=new l,this._viewProj=new l,this._updateProjectionMatrix=()=>{this._projectionMatrix=new l(2*this.fx/this.width,0,0,0,0,-2*this.fy/this.height,0,0,0,0,this.far/(this.far-this.near),1,0,0,-this.far*this.near/(this.far-this.near),0),this._viewProj=this.projectionMatrix.multiply(this.viewMatrix)},this.update=(t,F)=>{const U=A.RotationFromQuaternion(F).buffer,n=t.flat();this._viewMatrix=new l(U[0],U[1],U[2],0,U[3],U[4],U[5],0,U[6],U[7],U[8],0,-n[0]*U[0]-n[1]*U[3]-n[2]*U[6],-n[0]*U[1]-n[1]*U[4]-n[2]*U[7],-n[0]*U[2]-n[1]*U[5]-n[2]*U[8],1),this._viewProj=this.projectionMatrix.multiply(this.viewMatrix)},this.setSize=(t,F)=>{this._width=t,this._height=F,this._updateProjectionMatrix()}}get fx(){return this._fx}set fx(t){this._fx!==t&&(this._fx=t,this._updateProjectionMatrix())}get fy(){return this._fy}set fy(t){this._fy!==t&&(this._fy=t,this._updateProjectionMatrix())}get near(){return this._near}set near(t){this._near!==t&&(this._near=t,this._updateProjectionMatrix())}get far(){return this._far}set far(t){this._far!==t&&(this._far=t,this._updateProjectionMatrix())}get width(){return this._width}get height(){return this._height}get projectionMatrix(){return this._projectionMatrix}get viewMatrix(){return this._viewMatrix}get viewProj(){return this._viewProj}}class s{constructor(t=0,F=0,U=0,l=0){this.x=t,this.y=F,this.z=U,this.w=l}equals(t){return this.x===t.x&&(this.y===t.y&&(this.z===t.z&&this.w===t.w))}add(t){return"number"==typeof t?new s(this.x+t,this.y+t,this.z+t,this.w+t):new s(this.x+t.x,this.y+t.y,this.z+t.z,this.w+t.w)}subtract(t){return"number"==typeof t?new s(this.x-t,this.y-t,this.z-t,this.w-t):new s(this.x-t.x,this.y-t.y,this.z-t.z,this.w-t.w)}multiply(t){return"number"==typeof t?new s(this.x*t,this.y*t,this.z*t,this.w*t):t instanceof s?new s(this.x*t.x,this.y*t.y,this.z*t.z,this.w*t.w):new s(this.x*t.buffer[0]+this.y*t.buffer[4]+this.z*t.buffer[8]+this.w*t.buffer[12],this.x*t.buffer[1]+this.y*t.buffer[5]+this.z*t.buffer[9]+this.w*t.buffer[13],this.x*t.buffer[2]+this.y*t.buffer[6]+this.z*t.buffer[10]+this.w*t.buffer[14],this.x*t.buffer[3]+this.y*t.buffer[7]+this.z*t.buffer[11]+this.w*t.buffer[15])}dot(t){return this.x*t.x+this.y*t.y+this.z*t.z+this.w*t.w}lerp(t,F){return new s(this.x+(t.x-this.x)*F,this.y+(t.y-this.y)*F,this.z+(t.z-this.z)*F,this.w+(t.w-this.w)*F)}magnitude(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w)}distanceTo(t){return Math.sqrt((this.x-t.x)**2+(this.y-t.y)**2+(this.z-t.z)**2+(this.w-t.w)**2)}normalize(){const t=this.magnitude();return new s(this.x/t,this.y/t,this.z/t,this.w/t)}flat(){return[this.x,this.y,this.z,this.w]}clone(){return new s(this.x,this.y,this.z,this.w)}toString(){return`[${this.flat().join(", ")}]`}}class o extends d{constructor(F,U){super(),this._data=F||new c,this._position=U||new t(1,1,5),this.update=()=>{this.data.update(this.position,this.rotation)},this.screenPointToRay=(F,U)=>{const l=new s(F,U,-1,1),n=this._data.projectionMatrix.invert(),Q=l.multiply(n),e=this._data.viewMatrix.invert(),d=Q.multiply(e);return new t(d.x/d.w,d.y/d.w,d.z/d.w).subtract(this.position).normalize()}}get data(){return this._data}}class r extends U{constructor(){super(),this._objects=[],this.addObject=t=>{this.objects.push(t),this.dispatchEvent(new n(t))},this.removeObject=t=>{const F=this.objects.indexOf(t);if(F<0)throw new Error("Object not found in scene");this.objects.splice(F,1),this.dispatchEvent(new Q(t))},this.findObject=t=>{for(const F of this.objects)if(t(F))return F},this.findObjectOfType=t=>{for(const F of this.objects)if(F instanceof t)return F},this.reset=()=>{const t=this.objects.slice();for(const F of t)this.removeObject(F)},this.reset()}getMergedSceneDataBuffer(t="splat"){const F=[];let U=0;for(const t of this.objects)if(t instanceof Z){const l=t.clone();l.applyRotation(),l.applyScale(),l.applyPosition();const n=l.data.serialize();F.push(n),U+=l.data.vertexCount}const l=new Uint8Array(U*B.RowLength);let n=0;for(const t of F)l.set(t,n),n+=t.length;return"ply"===t?i.SplatToPLY(l.buffer,U):l.buffer}saveToFile(t=null,F="splat"){if(!document)return;if(!t){const U=new Date;t=`scene-${U.getFullYear()}-${U.getMonth()+1}-${U.getDate()}.${F}`}const U=this.getMergedSceneDataBuffer(F),l=new Blob([U],{type:"application/octet-stream"}),n=document.createElement("a");n.download=t,n.href=URL.createObjectURL(l),n.click()}get objects(){return this._objects}}async function h(t,F){const U=await fetch(t,{mode:"cors",credentials:"omit",cache:F?"force-cache":"default"});if(200!=U.status)throw new Error(U.status+" Unable to load "+U.url);return U}async function W(t,F){return t.headers.has("content-length")?async function(t,F){const U=t.body.getReader(),l=parseInt(t.headers.get("content-length")),n=new Uint8Array(l);let Q=0;for(;;){const{done:t,value:e}=await U.read();if(t)break;n.set(e,Q),Q+=e.length,null==F||F(Q/l)}return n}(t,F):async function(t,F){const U=t.body.getReader(),l=[];let n=0;for(;;){const{done:t,value:F}=await U.read();if(t)break;l.push(F),n+=F.length}const Q=new Uint8Array(n);let e=0;for(const t of l)Q.set(t,e),e+=t.length,null==F||F(e/n);return Q}(t,F)}class I{static async LoadAsync(t,F,U,l=!1){const n=await h(t,l),Q=await W(n,U);return this.LoadFromArrayBuffer(Q,F)}static async LoadFromFileAsync(t,F,U){const l=new FileReader;let n=new Z;return l.onload=t=>{n=this.LoadFromArrayBuffer(t.target.result,F)},l.onprogress=t=>{null==U||U(t.loaded/t.total)},l.readAsArrayBuffer(t),await new Promise((t=>{l.onloadend=()=>{t()}})),n}static LoadFromArrayBuffer(t,F){const U=new Uint8Array(t),l=B.Deserialize(U),n=new Z(l);return F.addObject(n),n}}class m{static async LoadAsync(t,F,U,l="",n=!1){const Q=await h(t,n),e=await W(Q,U);if(112!==e[0]||108!==e[1]||121!==e[2]||10!==e[3])throw new Error("Invalid PLY file");return this.LoadFromArrayBuffer(e.buffer,F,l)}static async LoadFromFileAsync(t,F,U,l=""){const n=new FileReader;let Q=new Z;return n.onload=t=>{Q=this.LoadFromArrayBuffer(t.target.result,F,l)},n.onprogress=t=>{null==U||U(t.loaded/t.total)},n.readAsArrayBuffer(t),await new Promise((t=>{n.onloadend=()=>{t()}})),Q}static LoadFromArrayBuffer(t,F,U=""){const l=new Uint8Array(this._ParsePLYBuffer(t,U)),n=B.Deserialize(l),Q=new Z(n);return F.addObject(Q),Q}static _ParsePLYBuffer(U,l){const n=new Uint8Array(U),Q=(new TextDecoder).decode(n.slice(0,10240)),e="end_header\n",d=Q.indexOf(e);if(d<0)throw new Error("Unable to read .ply file header");const A=parseInt(/element vertex (\d+)\n/.exec(Q)[1]);let a=0;const V={double:8,int:4,uint:4,float:4,short:2,ushort:2,uchar:1},Z=[];for(const t of Q.slice(0,d).split("\n").filter((t=>t.startsWith("property ")))){const[F,U,l]=t.split(" ");if(Z.push({name:l,type:U,offset:a}),!V[U])throw new Error(`Unsupported property type: ${U}`);a+=V[U]}const R=new DataView(U,d+11),c=new ArrayBuffer(B.RowLength*A),s=F.FromEuler(new t(Math.PI/2,0,0));for(let t=0;t{let l;switch(F.type){case"float":l=R.getFloat32(F.offset+t*a,!0);break;case"int":l=R.getInt32(F.offset+t*a,!0);break;default:throw new Error(`Unsupported property type: ${F.type}`)}switch(F.name){case"x":U[0]=l;break;case"y":U[1]=l;break;case"z":U[2]=l;break;case"scale_0":case"scaling_0":n[0]=Math.exp(l);break;case"scale_1":case"scaling_1":n[1]=Math.exp(l);break;case"scale_2":case"scaling_2":n[2]=Math.exp(l);break;case"red":Q[0]=l;break;case"green":Q[1]=l;break;case"blue":Q[2]=l;break;case"f_dc_0":case"features_0":Q[0]=255*(.5+i.SH_C0*l);break;case"f_dc_1":case"features_1":Q[1]=255*(.5+i.SH_C0*l);break;case"f_dc_2":case"features_2":Q[2]=255*(.5+i.SH_C0*l);break;case"f_dc_3":Q[3]=255*(.5+i.SH_C0*l);break;case"opacity":case"opacity_0":Q[3]=1/(1+Math.exp(-l))*255;break;case"rot_0":case"rotation_0":d=l;break;case"rot_1":case"rotation_1":A=l;break;case"rot_2":case"rotation_2":V=l;break;case"rot_3":case"rotation_3":o=l}}));let r=new F(A,V,o,d);switch(l){case"polycam":{const t=U[1];U[1]=-U[2],U[2]=t,r=s.multiply(r);break}case"":break;default:throw new Error(`Unsupported format: ${l}`)}r=r.normalize(),e[0]=128*r.w+128,e[1]=128*r.x+128,e[2]=128*r.y+128,e[3]=128*r.z+128}return c}}class b{static async LoadAsync(t,F,U,l,n=!1){const Q=await h(t,n),e=await W(Q,l);return this._ParseSplatvBuffer(e.buffer,F,U)}static async LoadFromFileAsync(t,F,U,l){const n=new FileReader;let Q=null;if(n.onload=t=>{Q=this._ParseSplatvBuffer(t.target.result,F,U)},n.onprogress=t=>{null==l||l(t.loaded/t.total)},n.readAsArrayBuffer(t),await new Promise((t=>{n.onloadend=()=>{t()}})),!Q)throw new Error("Failed to load splatv file");return Q}static _ParseSplatvBuffer(U,l,n){let Q=null;const e=(U,e,d)=>{if("magic"===U.type){const t=new Int32Array(e.buffer);if(26443!==t[0])throw new Error("Invalid splatv file");d.push({size:t[1],type:"chunks"})}else if("chunks"===U.type){const U=JSON.parse(new TextDecoder("utf-8").decode(e));if(0==U.length)throw new Error("Invalid splatv file");U.length>1&&console.warn("Splatv file contains more than one chunk, only the first one will be loaded");const l=U[0],Q=l.cameras;if(n&&Q&&Q.length){const U=Q[0],l=new t(U.position[0],U.position[1],U.position[2]),e=F.FromMatrix3(new A(U.rotation[0][0],U.rotation[0][1],U.rotation[0][2],U.rotation[1][0],U.rotation[1][1],U.rotation[1][2],U.rotation[2][0],U.rotation[2][1],U.rotation[2][2]));n.position=l,n.rotation=e}d.push(l)}else if("splat"===U.type){const t=a.Deserialize(e,U.texwidth,U.texheight),F=new R(t);l.addObject(F),Q=F}},d=new Uint8Array(U),B=[{size:8,type:"magic",texwidth:0,texheight:0}];let i=B.shift(),V=new Uint8Array(i.size),Z=0,c=0;for(;i;){for(;Z{U.useProgram(this._program),this._resize()},this.initialize=()=>{console.assert(!this._initialized,"ShaderProgram already initialized"),U.useProgram(this._program),this._initialize();for(const t of this.passes)t.initialize(this);this._initialized=!0,this._started=!0},this.render=(t,F)=>{U.useProgram(this._program),this._scene===t&&this._camera===F||(this.dispose(),this._scene=t,this._camera=F,this.initialize());for(const t of this.passes)t.render();this._render()},this.dispose=()=>{if(this._initialized){U.useProgram(this._program);for(const t of this.passes)t.dispose();this._dispose(),this._scene=null,this._camera=null,this._initialized=!1}}}get renderer(){return this._renderer}get scene(){return this._scene}get camera(){return this._camera}get program(){return this._program}get passes(){return this._passes}get started(){return this._started}}var G=g("Lyogcm9sbHVwLXBsdWdpbi13ZWItd29ya2VyLWxvYWRlciAqLwooZnVuY3Rpb24gKCkgewogICd1c2Ugc3RyaWN0JzsKCiAgdmFyIGxvYWRXYXNtID0gKCgpID0+IHsNCiAgICANCiAgICByZXR1cm4gKA0KICBhc3luYyBmdW5jdGlvbihtb2R1bGVBcmcgPSB7fSkgew0KICAgIHZhciBtb2R1bGVSdG47DQoNCiAgdmFyIE1vZHVsZT1tb2R1bGVBcmc7dmFyIHJlYWR5UHJvbWlzZVJlc29sdmUscmVhZHlQcm9taXNlUmVqZWN0O3ZhciByZWFkeVByb21pc2U9bmV3IFByb21pc2UoKHJlc29sdmUscmVqZWN0KT0+e3JlYWR5UHJvbWlzZVJlc29sdmU9cmVzb2x2ZTtyZWFkeVByb21pc2VSZWplY3Q9cmVqZWN0O30pO3ZhciBtb2R1bGVPdmVycmlkZXM9T2JqZWN0LmFzc2lnbih7fSxNb2R1bGUpO3ZhciBzY3JpcHREaXJlY3Rvcnk9IiI7dmFyIHJlYWRCaW5hcnk7e3tzY3JpcHREaXJlY3Rvcnk9c2VsZi5sb2NhdGlvbi5ocmVmO31pZihzY3JpcHREaXJlY3Rvcnkuc3RhcnRzV2l0aCgiYmxvYjoiKSl7c2NyaXB0RGlyZWN0b3J5PSIiO31lbHNlIHtzY3JpcHREaXJlY3Rvcnk9c2NyaXB0RGlyZWN0b3J5LnNsaWNlKDAsc2NyaXB0RGlyZWN0b3J5LnJlcGxhY2UoL1s/I10uKi8sIiIpLmxhc3RJbmRleE9mKCIvIikrMSk7fXt7cmVhZEJpbmFyeT11cmw9Pnt2YXIgeGhyPW5ldyBYTUxIdHRwUmVxdWVzdDt4aHIub3BlbigiR0VUIix1cmwsZmFsc2UpO3hoci5yZXNwb25zZVR5cGU9ImFycmF5YnVmZmVyIjt4aHIuc2VuZChudWxsKTtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoeGhyLnJlc3BvbnNlKX07fX19TW9kdWxlWyJwcmludCJdfHxjb25zb2xlLmxvZy5iaW5kKGNvbnNvbGUpO3ZhciBlcnI9TW9kdWxlWyJwcmludEVyciJdfHxjb25zb2xlLmVycm9yLmJpbmQoY29uc29sZSk7T2JqZWN0LmFzc2lnbihNb2R1bGUsbW9kdWxlT3ZlcnJpZGVzKTttb2R1bGVPdmVycmlkZXM9bnVsbDtpZihNb2R1bGVbImFyZ3VtZW50cyJdKU1vZHVsZVsiYXJndW1lbnRzIl07aWYoTW9kdWxlWyJ0aGlzUHJvZ3JhbSJdKU1vZHVsZVsidGhpc1Byb2dyYW0iXTt2YXIgd2FzbUJpbmFyeT1Nb2R1bGVbIndhc21CaW5hcnkiXTt2YXIgd2FzbU1lbW9yeTt2YXIgQUJPUlQ9ZmFsc2U7dmFyIEhFQVA4LEhFQVBVOCxIRUFQMTYsSEVBUFUxNixIRUFQMzIsSEVBUFUzMixIRUFQRjMyLEhFQVA2NCxIRUFQVTY0LEhFQVBGNjQ7ZnVuY3Rpb24gdXBkYXRlTWVtb3J5Vmlld3MoKXt2YXIgYj13YXNtTWVtb3J5LmJ1ZmZlcjtNb2R1bGVbIkhFQVA4Il09SEVBUDg9bmV3IEludDhBcnJheShiKTtNb2R1bGVbIkhFQVAxNiJdPUhFQVAxNj1uZXcgSW50MTZBcnJheShiKTtNb2R1bGVbIkhFQVBVOCJdPUhFQVBVOD1uZXcgVWludDhBcnJheShiKTtNb2R1bGVbIkhFQVBVMTYiXT1IRUFQVTE2PW5ldyBVaW50MTZBcnJheShiKTtNb2R1bGVbIkhFQVAzMiJdPUhFQVAzMj1uZXcgSW50MzJBcnJheShiKTtNb2R1bGVbIkhFQVBVMzIiXT1IRUFQVTMyPW5ldyBVaW50MzJBcnJheShiKTtNb2R1bGVbIkhFQVBGMzIiXT1IRUFQRjMyPW5ldyBGbG9hdDMyQXJyYXkoYik7TW9kdWxlWyJIRUFQRjY0Il09SEVBUEY2ND1uZXcgRmxvYXQ2NEFycmF5KGIpO01vZHVsZVsiSEVBUDY0Il09SEVBUDY0PW5ldyBCaWdJbnQ2NEFycmF5KGIpO01vZHVsZVsiSEVBUFU2NCJdPUhFQVBVNjQ9bmV3IEJpZ1VpbnQ2NEFycmF5KGIpO31mdW5jdGlvbiBwcmVSdW4oKXtpZihNb2R1bGVbInByZVJ1biJdKXtpZih0eXBlb2YgTW9kdWxlWyJwcmVSdW4iXT09ImZ1bmN0aW9uIilNb2R1bGVbInByZVJ1biJdPVtNb2R1bGVbInByZVJ1biJdXTt3aGlsZShNb2R1bGVbInByZVJ1biJdLmxlbmd0aCl7YWRkT25QcmVSdW4oTW9kdWxlWyJwcmVSdW4iXS5zaGlmdCgpKTt9fWNhbGxSdW50aW1lQ2FsbGJhY2tzKG9uUHJlUnVucyk7fWZ1bmN0aW9uIGluaXRSdW50aW1lKCl7d2FzbUV4cG9ydHNbIm0iXSgpO31mdW5jdGlvbiBwb3N0UnVuKCl7aWYoTW9kdWxlWyJwb3N0UnVuIl0pe2lmKHR5cGVvZiBNb2R1bGVbInBvc3RSdW4iXT09ImZ1bmN0aW9uIilNb2R1bGVbInBvc3RSdW4iXT1bTW9kdWxlWyJwb3N0UnVuIl1dO3doaWxlKE1vZHVsZVsicG9zdFJ1biJdLmxlbmd0aCl7YWRkT25Qb3N0UnVuKE1vZHVsZVsicG9zdFJ1biJdLnNoaWZ0KCkpO319Y2FsbFJ1bnRpbWVDYWxsYmFja3Mob25Qb3N0UnVucyk7fXZhciBydW5EZXBlbmRlbmNpZXM9MDt2YXIgZGVwZW5kZW5jaWVzRnVsZmlsbGVkPW51bGw7ZnVuY3Rpb24gYWRkUnVuRGVwZW5kZW5jeShpZCl7cnVuRGVwZW5kZW5jaWVzKys7TW9kdWxlWyJtb25pdG9yUnVuRGVwZW5kZW5jaWVzIl0/LihydW5EZXBlbmRlbmNpZXMpO31mdW5jdGlvbiByZW1vdmVSdW5EZXBlbmRlbmN5KGlkKXtydW5EZXBlbmRlbmNpZXMtLTtNb2R1bGVbIm1vbml0b3JSdW5EZXBlbmRlbmNpZXMiXT8uKHJ1bkRlcGVuZGVuY2llcyk7aWYocnVuRGVwZW5kZW5jaWVzPT0wKXtpZihkZXBlbmRlbmNpZXNGdWxmaWxsZWQpe3ZhciBjYWxsYmFjaz1kZXBlbmRlbmNpZXNGdWxmaWxsZWQ7ZGVwZW5kZW5jaWVzRnVsZmlsbGVkPW51bGw7Y2FsbGJhY2soKTt9fX1mdW5jdGlvbiBhYm9ydCh3aGF0KXtNb2R1bGVbIm9uQWJvcnQiXT8uKHdoYXQpO3doYXQ9IkFib3J0ZWQoIit3aGF0KyIpIjtlcnIod2hhdCk7QUJPUlQ9dHJ1ZTt3aGF0Kz0iLiBCdWlsZCB3aXRoIC1zQVNTRVJUSU9OUyBmb3IgbW9yZSBpbmZvLiI7dmFyIGU9bmV3IFdlYkFzc2VtYmx5LlJ1bnRpbWVFcnJvcih3aGF0KTtyZWFkeVByb21pc2VSZWplY3QoZSk7dGhyb3cgZX12YXIgd2FzbUJpbmFyeUZpbGU9ImRhdGE6YXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtO2Jhc2U2NCxBR0Z6YlFFQUFBQUJXQTFnQkg5L2YzOEFZQU4vZjM4QVlBVi9mMzkvZndCZ0JuOS9mMzkvZndCZ0FYOEFZQUYvQVg5Z0FBQmdBMzkvZndGL1lBSi9md0JnQlg5L2YzNStBR0FDZlgwQmYyQUJmUUYvWUF0L2YzOS9mMzkvZjM5L2Z3QUNRd3NCWVFGaEFBRUJZUUZpQUFJQllRRmpBQUVCWVFGa0FBRUJZUUZsQUFrQllRRm1BQVFCWVFGbkFBZ0JZUUZvQUFBQllRRnBBQWdCWVFGcUFBWUJZUUZyQUFVREdCY0hCUW9FQmdRR0FRQUJCQXNGREFNREFnSUFBQWNIQlFRRkFYQUJFQkFGQndFQmdnS0FnQUlHQ0FGL0FVSFFuUVFMQnhrR0FXd0NBQUZ0QUE4QmJnQVlBVzhBRndGd0FCQUJjUUVBQ1JVQkFFRUJDdzhoRGhVVklBNGZHUnNlRGhvY0hSRU1BUUlLeEZFWGNRRUJmeUFDUlFSQUlBQW9BZ1FnQVNnQ0JFWVBDeUFBSUFGR0JFQkJBUThMQWtBZ0FDZ0NCQ0lDTFFBQUlnQkZJQUFnQVNnQ0JDSUJMUUFBSWdOSGNnMEFBMEFnQVMwQUFTRURJQUl0QUFFaUFFVU5BU0FCUVFGcUlRRWdBa0VCYWlFQ0lBQWdBMFlOQUFzTElBQWdBMFlMVHdFQ2YwSE1HU2dDQUNJQklBQkJCMnBCZUhFaUFtb2hBQUpBSUFKQkFDQUFJQUZORzBVRVFDQUFQd0JCRUhSTkRRRWdBQkFLRFFFTFFkQVpRVEEyQWdCQmZ3OExRY3daSUFBMkFnQWdBUXNPQUNBQUVCWWdBUkFXUVJCMGNnc0dBQ0FBRUJBTEtRQkJ5QjFCRHpZQ0FFSE1IVUVBTmdJQUVCRkJ6QjFCeEIwb0FnQTJBZ0JCeEIxQnlCMDJBZ0FMM0FzQkNIOENRQ0FBUlEwQUlBQkJDR3NpQXlBQVFRUnJLQUlBSWdKQmVIRWlBR29oQlFKQUlBSkJBWEVOQUNBQ1FRSnhSUTBCSUFNZ0F5Z0NBQ0lFYXlJRFFlUVpLQUlBU1EwQklBQWdCR29oQUFKQUFrQUNRRUhvR1NnQ0FDQURSd1JBSUFNb0Fnd2hBU0FFUWY4QlRRUkFJQUVnQXlnQ0NDSUNSdzBDUWRRWlFkUVpLQUlBUVg0Z0JFRURkbmR4TmdJQURBVUxJQU1vQWhnaEJ5QUJJQU5IQkVBZ0F5Z0NDQ0lDSUFFMkFnd2dBU0FDTmdJSURBUUxJQU1vQWhRaUFnUi9JQU5CRkdvRklBTW9BaEFpQWtVTkF5QURRUkJxQ3lFRUEwQWdCQ0VHSUFJaUFVRVVhaUVFSUFFb0FoUWlBZzBBSUFGQkVHb2hCQ0FCS0FJUUlnSU5BQXNnQmtFQU5nSUFEQU1MSUFVb0FnUWlBa0VEY1VFRFJ3MERRZHdaSUFBMkFnQWdCU0FDUVg1eE5nSUVJQU1nQUVFQmNqWUNCQ0FGSUFBMkFnQVBDeUFDSUFFMkFnd2dBU0FDTmdJSURBSUxRUUFoQVFzZ0IwVU5BQUpBSUFNb0Fod2lCRUVDZEVHRUhHb2lBaWdDQUNBRFJnUkFJQUlnQVRZQ0FDQUJEUUZCMkJsQjJCa29BZ0JCZmlBRWQzRTJBZ0FNQWdzQ1FDQURJQWNvQWhCR0JFQWdCeUFCTmdJUURBRUxJQWNnQVRZQ0ZBc2dBVVVOQVFzZ0FTQUhOZ0lZSUFNb0FoQWlBZ1JBSUFFZ0FqWUNFQ0FDSUFFMkFoZ0xJQU1vQWhRaUFrVU5BQ0FCSUFJMkFoUWdBaUFCTmdJWUN5QURJQVZQRFFBZ0JTZ0NCQ0lFUVFGeFJRMEFBa0FDUUFKQUFrQWdCRUVDY1VVRVFFSHNHU2dDQUNBRlJnUkFRZXdaSUFNMkFnQkI0QmxCNEJrb0FnQWdBR29pQURZQ0FDQURJQUJCQVhJMkFnUWdBMEhvR1NnQ0FFY05Ca0hjR1VFQU5nSUFRZWdaUVFBMkFnQVBDMEhvR1NnQ0FDSUhJQVZHQkVCQjZCa2dBellDQUVIY0dVSGNHU2dDQUNBQWFpSUFOZ0lBSUFNZ0FFRUJjallDQkNBQUlBTnFJQUEyQWdBUEN5QUVRWGh4SUFCcUlRQWdCU2dDRENFQklBUkIvd0ZOQkVBZ0JTZ0NDQ0lDSUFGR0JFQkIxQmxCMUJrb0FnQkJmaUFFUVFOMmQzRTJBZ0FNQlFzZ0FpQUJOZ0lNSUFFZ0FqWUNDQXdFQ3lBRktBSVlJUWdnQVNBRlJ3UkFJQVVvQWdnaUFpQUJOZ0lNSUFFZ0FqWUNDQXdEQ3lBRktBSVVJZ0lFZnlBRlFSUnFCU0FGS0FJUUlnSkZEUUlnQlVFUWFnc2hCQU5BSUFRaEJpQUNJZ0ZCRkdvaEJDQUJLQUlVSWdJTkFDQUJRUkJxSVFRZ0FTZ0NFQ0lDRFFBTElBWkJBRFlDQUF3Q0N5QUZJQVJCZm5FMkFnUWdBeUFBUVFGeU5nSUVJQUFnQTJvZ0FEWUNBQXdEQzBFQUlRRUxJQWhGRFFBQ1FDQUZLQUljSWdSQkFuUkJoQnhxSWdJb0FnQWdCVVlFUUNBQ0lBRTJBZ0FnQVEwQlFkZ1pRZGdaS0FJQVFYNGdCSGR4TmdJQURBSUxBa0FnQlNBSUtBSVFSZ1JBSUFnZ0FUWUNFQXdCQ3lBSUlBRTJBaFFMSUFGRkRRRUxJQUVnQ0RZQ0dDQUZLQUlRSWdJRVFDQUJJQUkyQWhBZ0FpQUJOZ0lZQ3lBRktBSVVJZ0pGRFFBZ0FTQUNOZ0lVSUFJZ0FUWUNHQXNnQXlBQVFRRnlOZ0lFSUFBZ0Eyb2dBRFlDQUNBRElBZEhEUUJCM0JrZ0FEWUNBQThMSUFCQi93Rk5CRUFnQUVGNGNVSDhHV29oQWdKL1FkUVpLQUlBSWdSQkFTQUFRUU4yZENJQWNVVUVRRUhVR1NBQUlBUnlOZ0lBSUFJTUFRc2dBaWdDQ0FzaEFDQUNJQU0yQWdnZ0FDQUROZ0lNSUFNZ0FqWUNEQ0FESUFBMkFnZ1BDMEVmSVFFZ0FFSC8vLzhIVFFSQUlBQkJKaUFBUVFoMlp5SUNhM1pCQVhFZ0FrRUJkR3RCUG1vaEFRc2dBeUFCTmdJY0lBTkNBRGNDRUNBQlFRSjBRWVFjYWlFRUFuOENRQUovUWRnWktBSUFJZ1pCQVNBQmRDSUNjVVVFUUVIWUdTQUNJQVp5TmdJQUlBUWdBellDQUVFWUlRRkJDQXdCQ3lBQVFSa2dBVUVCZG10QkFDQUJRUjlIRzNRaEFTQUVLQUlBSVFRRFFDQUVJZ0lvQWdSQmVIRWdBRVlOQWlBQlFSMTJJUVFnQVVFQmRDRUJJQUlnQkVFRWNXb2lCaWdDRUNJRURRQUxJQVlnQXpZQ0VFRVlJUUVnQWlFRVFRZ0xJUUFnQXlJQ0RBRUxJQUlvQWdnaUJDQUROZ0lNSUFJZ0F6WUNDRUVZSVFCQkNDRUJRUUFMSVFZZ0FTQURhaUFFTmdJQUlBTWdBallDRENBQUlBTnFJQVkyQWdCQjlCbEI5QmtvQWdCQkFXc2lBRUYvSUFBYk5nSUFDd3ZhQXdCQnlCQkJ5Z29RQ0VIVUVFSDVDVUVCUVFBUUIwSGdFRUcwQ1VFQlFZQi9RZjhBRUFGQitCQkJyUWxCQVVHQWYwSC9BQkFCUWV3UVFhc0pRUUZCQUVIL0FSQUJRWVFSUWY4SVFRSkJnSUIrUWYvL0FSQUJRWkFSUWZZSVFRSkJBRUgvL3dNUUFVR2NFVUdPQ1VFRVFZQ0FnSUI0UWYvLy8vOEhFQUZCcUJGQmhRbEJCRUVBUVg4UUFVRzBFVUdIQ2tFRVFZQ0FnSUI0UWYvLy8vOEhFQUZCd0JGQi9nbEJCRUVBUVg4UUFVSE1FVUdaQ1VFSVFvQ0FnSUNBZ0lDQWdIOUMvLy8vLy8vLy8vLy9BQkFFUWRnUlFaZ0pRUWhDQUVKL0VBUkI1QkZCa2dsQkJCQURRZkFSUWNNS1FRZ1FBMEdBRTBHWkNoQUdRY2dUUVFSQmpBb1FBa0dRRkVFQ1FhVUtFQUpCM0JSQkJFRzBDaEFDUWFnVkVBVkJ4QlZCQUVHbURoQUFRZXdWUVFCQjZ3NFFBRUdVRmtFQlFjUU9FQUJCdkJaQkFrSHpDaEFBUWVRV1FRTkJrZ3NRQUVHTUYwRUVRYm9MRUFCQnRCZEJCVUhYQ3hBQVFkd1hRUVJCa0E4UUFFR0VHRUVGUWE0UEVBQkI3QlZCQUVHOURCQUFRWlFXUVFGQm5Bd1FBRUc4RmtFQ1FmOE1FQUJCNUJaQkEwSGREQkFBUVl3WFFRUkJoUTRRQUVHMEYwRUZRZU1ORUFCQnJCaEJDRUhDRFJBQVFkUVlRUWxCb0EwUUFFSDhHRUVHUWYwTEVBQkJwQmxCQjBIVkR4QUFDeUFBQWtBZ0FTQUFLQUlFUncwQUlBQW9BaHhCQVVZTkFDQUFJQUkyQWh3TEM1b0JBQ0FBUVFFNkFEVUNRQ0FDSUFBb0FnUkhEUUFnQUVFQk9nQTBBa0FnQUNnQ0VDSUNSUVJBSUFCQkFUWUNKQ0FBSUFNMkFoZ2dBQ0FCTmdJUUlBTkJBVWNOQWlBQUtBSXdRUUZHRFFFTUFnc2dBU0FDUmdSQUlBQW9BaGdpQWtFQ1JnUkFJQUFnQXpZQ0dDQURJUUlMSUFBb0FqQkJBVWNOQWlBQ1FRRkdEUUVNQWdzZ0FDQUFLQUlrUVFGcU5nSWtDeUFBUVFFNkFEWUxDM1lCQVg4Z0FDZ0NKQ0lEUlFSQUlBQWdBallDR0NBQUlBRTJBaEFnQUVFQk5nSWtJQUFnQUNnQ09EWUNGQThMQWtBQ1FDQUFLQUlVSUFBb0FqaEhEUUFnQUNnQ0VDQUJSdzBBSUFBb0FoaEJBa2NOQVNBQUlBSTJBaGdQQ3lBQVFRRTZBRFlnQUVFQ05nSVlJQUFnQTBFQmFqWUNKQXNMQWdBTGNnRUVmeUFBdkNJRVFmLy8vd054SVFFQ1FDQUVRUmQyUWY4QmNTSUNSUTBBSUFKQjhBQk5CRUFnQVVHQWdJQUVja0h4QUNBQ2EzWWhBUXdCQ3lBQ1FZMEJTd1JBUVlENEFTRURRUUFoQVF3QkN5QUNRUXAwUVlDQUIyc2hBd3NnQXlBRVFSQjJRWUNBQW5GeUlBRkJEWFp5QzlFbkFRdC9Jd0JCRUdzaUNpUUFBa0FDUUFKQUFrQUNRQUpBQWtBQ1FBSkFBa0FnQUVIMEFVMEVRRUhVR1NnQ0FDSUVRUkFnQUVFTGFrSDRBM0VnQUVFTFNSc2lCa0VEZGlJQWRpSUJRUU54QkVBQ1FDQUJRWDl6UVFGeElBQnFJZ0pCQTNRaUFVSDhHV29pQUNBQlFZUWFhaWdDQUNJQktBSUlJZ1ZHQkVCQjFCa2dCRUYrSUFKM2NUWUNBQXdCQ3lBRklBQTJBZ3dnQUNBRk5nSUlDeUFCUVFocUlRQWdBU0FDUVFOMElnSkJBM0kyQWdRZ0FTQUNhaUlCSUFFb0FnUkJBWEkyQWdRTUN3c2dCa0hjR1NnQ0FDSUlUUTBCSUFFRVFBSkFRUUlnQUhRaUFrRUFJQUpyY2lBQklBQjBjV2dpQVVFRGRDSUFRZndaYWlJQ0lBQkJoQnBxS0FJQUlnQW9BZ2dpQlVZRVFFSFVHU0FFUVg0Z0FYZHhJZ1EyQWdBTUFRc2dCU0FDTmdJTUlBSWdCVFlDQ0FzZ0FDQUdRUU55TmdJRUlBQWdCbW9pQnlBQlFRTjBJZ0VnQm1zaUJVRUJjallDQkNBQUlBRnFJQVUyQWdBZ0NBUkFJQWhCZUhGQi9CbHFJUUZCNkJrb0FnQWhBZ0ovSUFSQkFTQUlRUU4yZENJRGNVVUVRRUhVR1NBRElBUnlOZ0lBSUFFTUFRc2dBU2dDQ0FzaEF5QUJJQUkyQWdnZ0F5QUNOZ0lNSUFJZ0FUWUNEQ0FDSUFNMkFnZ0xJQUJCQ0dvaEFFSG9HU0FITmdJQVFkd1pJQVUyQWdBTUN3dEIyQmtvQWdBaUMwVU5BU0FMYUVFQ2RFR0VIR29vQWdBaUFpZ0NCRUY0Y1NBR2F5RURJQUloQVFOQUFrQWdBU2dDRUNJQVJRUkFJQUVvQWhRaUFFVU5BUXNnQUNnQ0JFRjRjU0FHYXlJQklBTWdBU0FEU1NJQkd5RURJQUFnQWlBQkd5RUNJQUFoQVF3QkN3c2dBaWdDR0NFSklBSWdBaWdDRENJQVJ3UkFJQUlvQWdnaUFTQUFOZ0lNSUFBZ0FUWUNDQXdLQ3lBQ0tBSVVJZ0VFZnlBQ1FSUnFCU0FDS0FJUUlnRkZEUU1nQWtFUWFnc2hCUU5BSUFVaEJ5QUJJZ0JCRkdvaEJTQUFLQUlVSWdFTkFDQUFRUkJxSVFVZ0FDZ0NFQ0lCRFFBTElBZEJBRFlDQUF3SkMwRi9JUVlnQUVHL2Ywc05BQ0FBUVF0cUlnRkJlSEVoQmtIWUdTZ0NBQ0lIUlEwQVFSOGhDRUVBSUFacklRTWdBRUgwLy84SFRRUkFJQVpCSmlBQlFRaDJaeUlBYTNaQkFYRWdBRUVCZEd0QlBtb2hDQXNDUUFKQUFrQWdDRUVDZEVHRUhHb29BZ0FpQVVVRVFFRUFJUUFNQVF0QkFDRUFJQVpCR1NBSVFRRjJhMEVBSUFoQkgwY2JkQ0VDQTBBQ1FDQUJLQUlFUVhoeElBWnJJZ1FnQTA4TkFDQUJJUVVnQkNJRERRQkJBQ0VESUFFaEFBd0RDeUFBSUFFb0FoUWlCQ0FFSUFFZ0FrRWRka0VFY1dvb0FoQWlBVVliSUFBZ0JCc2hBQ0FDUVFGMElRSWdBUTBBQ3dzZ0FDQUZja1VFUUVFQUlRVkJBaUFJZENJQVFRQWdBR3R5SUFkeElnQkZEUU1nQUdoQkFuUkJoQnhxS0FJQUlRQUxJQUJGRFFFTEEwQWdBQ2dDQkVGNGNTQUdheUlDSUFOSklRRWdBaUFESUFFYklRTWdBQ0FGSUFFYklRVWdBQ2dDRUNJQkJIOGdBUVVnQUNnQ0ZBc2lBQTBBQ3dzZ0JVVU5BQ0FEUWR3WktBSUFJQVpyVHcwQUlBVW9BaGdoQ0NBRklBVW9BZ3dpQUVjRVFDQUZLQUlJSWdFZ0FEWUNEQ0FBSUFFMkFnZ01DQXNnQlNnQ0ZDSUJCSDhnQlVFVWFnVWdCU2dDRUNJQlJRMERJQVZCRUdvTElRSURRQ0FDSVFRZ0FTSUFRUlJxSVFJZ0FDZ0NGQ0lCRFFBZ0FFRVFhaUVDSUFBb0FoQWlBUTBBQ3lBRVFRQTJBZ0FNQndzZ0JrSGNHU2dDQUNJRlRRUkFRZWdaS0FJQUlRQUNRQ0FGSUFacklnRkJFRThFUUNBQUlBWnFJZ0lnQVVFQmNqWUNCQ0FBSUFWcUlBRTJBZ0FnQUNBR1FRTnlOZ0lFREFFTElBQWdCVUVEY2pZQ0JDQUFJQVZxSWdFZ0FTZ0NCRUVCY2pZQ0JFRUFJUUpCQUNFQkMwSGNHU0FCTmdJQVFlZ1pJQUkyQWdBZ0FFRUlhaUVBREFrTElBWkI0QmtvQWdBaUFra0VRRUhnR1NBQ0lBWnJJZ0UyQWdCQjdCbEI3QmtvQWdBaUFDQUdhaUlDTmdJQUlBSWdBVUVCY2pZQ0JDQUFJQVpCQTNJMkFnUWdBRUVJYWlFQURBa0xRUUFoQUNBR1FTOXFJZ01DZjBHc0hTZ0NBQVJBUWJRZEtBSUFEQUVMUWJnZFFuODNBZ0JCc0IxQ2dLQ0FnSUNBQkRjQ0FFR3NIU0FLUVF4cVFYQnhRZGlxMWFvRmN6WUNBRUhBSFVFQU5nSUFRWkFkUVFBMkFnQkJnQ0FMSWdGcUlnUkJBQ0FCYXlJSGNTSUJJQVpORFFoQmpCMG9BZ0FpQlFSQVFZUWRLQUlBSWdnZ0FXb2lDU0FJVFNBRklBbEpjZzBKQ3dKQVFaQWRMUUFBUVFSeFJRUkFBa0FDUUFKQUFrQkI3QmtvQWdBaUJRUkFRWlFkSVFBRFFDQUFLQUlBSWdnZ0JVMEVRQ0FGSUFnZ0FDZ0NCR3BKRFFNTElBQW9BZ2dpQUEwQUN3dEJBQkFNSWdKQmYwWU5BeUFCSVFSQnNCMG9BZ0FpQUVFQmF5SUZJQUp4QkVBZ0FTQUNheUFDSUFWcVFRQWdBR3R4YWlFRUN5QUVJQVpORFFOQmpCMG9BZ0FpQUFSQVFZUWRLQUlBSWdVZ0JHb2lCeUFGVFNBQUlBZEpjZzBFQ3lBRUVBd2lBQ0FDUncwQkRBVUxJQVFnQW1zZ0IzRWlCQkFNSWdJZ0FDZ0NBQ0FBS0FJRWFrWU5BU0FDSVFBTElBQkJmMFlOQVNBR1FUQnFJQVJOQkVBZ0FDRUNEQVFMUWJRZEtBSUFJZ0lnQXlBRWEycEJBQ0FDYTNFaUFoQU1RWDlHRFFFZ0FpQUVhaUVFSUFBaEFnd0RDeUFDUVg5SERRSUxRWkFkUVpBZEtBSUFRUVJ5TmdJQUN5QUJFQXdpQWtGL1JrRUFFQXdpQUVGL1JuSWdBQ0FDVFhJTkJTQUFJQUpySWdRZ0JrRW9hazBOQlF0QmhCMUJoQjBvQWdBZ0JHb2lBRFlDQUVHSUhTZ0NBQ0FBU1FSQVFZZ2RJQUEyQWdBTEFrQkI3QmtvQWdBaUF3UkFRWlFkSVFBRFFDQUNJQUFvQWdBaUFTQUFLQUlFSWdWcVJnMENJQUFvQWdnaUFBMEFDd3dFQzBIa0dTZ0NBQ0lBUVFBZ0FDQUNUUnRGQkVCQjVCa2dBallDQUF0QkFDRUFRWmdkSUFRMkFnQkJsQjBnQWpZQ0FFSDBHVUYvTmdJQVFmZ1pRYXdkS0FJQU5nSUFRYUFkUVFBMkFnQURRQ0FBUVFOMElnRkJoQnBxSUFGQi9CbHFJZ1UyQWdBZ0FVR0lHbW9nQlRZQ0FDQUFRUUZxSWdCQklFY05BQXRCNEJrZ0JFRW9heUlBUVhnZ0FtdEJCM0VpQVdzaUJUWUNBRUhzR1NBQklBSnFJZ0UyQWdBZ0FTQUZRUUZ5TmdJRUlBQWdBbXBCS0RZQ0JFSHdHVUc4SFNnQ0FEWUNBQXdFQ3lBQ0lBTk5JQUVnQTB0eURRSWdBQ2dDREVFSWNRMENJQUFnQkNBRmFqWUNCRUhzR1NBRFFYZ2dBMnRCQjNFaUFHb2lBVFlDQUVIZ0dVSGdHU2dDQUNBRWFpSUNJQUJySWdBMkFnQWdBU0FBUVFGeU5nSUVJQUlnQTJwQktEWUNCRUh3R1VHOEhTZ0NBRFlDQUF3REMwRUFJUUFNQmd0QkFDRUFEQVFMUWVRWktBSUFJQUpMQkVCQjVCa2dBallDQUFzZ0FpQUVhaUVGUVpRZElRQUNRQU5BSUFVZ0FDZ0NBQ0lCUndSQUlBQW9BZ2dpQUEwQkRBSUxDeUFBTFFBTVFRaHhSUTBEQzBHVUhTRUFBMEFDUUNBQUtBSUFJZ0VnQTAwRVFDQURJQUVnQUNnQ0JHb2lCVWtOQVFzZ0FDZ0NDQ0VBREFFTEMwSGdHU0FFUVNocklnQkJlQ0FDYTBFSGNTSUJheUlITmdJQVFld1pJQUVnQW1vaUFUWUNBQ0FCSUFkQkFYSTJBZ1FnQUNBQ2FrRW9OZ0lFUWZBWlFid2RLQUlBTmdJQUlBTWdCVUVuSUFWclFRZHhha0V2YXlJQUlBQWdBMEVRYWtrYklnRkJHellDQkNBQlFad2RLUUlBTndJUUlBRkJsQjBwQWdBM0FnaEJuQjBnQVVFSWFqWUNBRUdZSFNBRU5nSUFRWlFkSUFJMkFnQkJvQjFCQURZQ0FDQUJRUmhxSVFBRFFDQUFRUWMyQWdRZ0FFRUlhaUFBUVFScUlRQWdCVWtOQUFzZ0FTQURSZzBBSUFFZ0FTZ0NCRUYrY1RZQ0JDQURJQUVnQTJzaUFrRUJjallDQkNBQklBSTJBZ0FDZnlBQ1FmOEJUUVJBSUFKQmVIRkIvQmxxSVFBQ2YwSFVHU2dDQUNJQlFRRWdBa0VEZG5RaUFuRkZCRUJCMUJrZ0FTQUNjallDQUNBQURBRUxJQUFvQWdnTElRRWdBQ0FETmdJSUlBRWdBellDREVFTUlRSkJDQXdCQzBFZklRQWdBa0gvLy84SFRRUkFJQUpCSmlBQ1FRaDJaeUlBYTNaQkFYRWdBRUVCZEd0QlBtb2hBQXNnQXlBQU5nSWNJQU5DQURjQ0VDQUFRUUowUVlRY2FpRUJBa0FDUUVIWUdTZ0NBQ0lGUVFFZ0FIUWlCSEZGQkVCQjJCa2dCQ0FGY2pZQ0FDQUJJQU0yQWdBTUFRc2dBa0VaSUFCQkFYWnJRUUFnQUVFZlJ4dDBJUUFnQVNnQ0FDRUZBMEFnQlNJQktBSUVRWGh4SUFKR0RRSWdBRUVkZGlFRklBQkJBWFFoQUNBQklBVkJCSEZxSWdRb0FoQWlCUTBBQ3lBRUlBTTJBaEFMSUFNZ0FUWUNHRUVJSVFJZ0F5SUJJUUJCREF3QkN5QUJLQUlJSWdBZ0F6WUNEQ0FCSUFNMkFnZ2dBeUFBTmdJSVFRQWhBRUVZSVFKQkRBc2dBMm9nQVRZQ0FDQUNJQU5xSUFBMkFnQUxRZUFaS0FJQUlnQWdCazBOQUVIZ0dTQUFJQVpySWdFMkFnQkI3QmxCN0Jrb0FnQWlBQ0FHYWlJQ05nSUFJQUlnQVVFQmNqWUNCQ0FBSUFaQkEzSTJBZ1FnQUVFSWFpRUFEQVFMUWRBWlFUQTJBZ0JCQUNFQURBTUxJQUFnQWpZQ0FDQUFJQUFvQWdRZ0JHbzJBZ1FnQWtGNElBSnJRUWR4YWlJSUlBWkJBM0kyQWdRZ0FVRjRJQUZyUVFkeGFpSUVJQVlnQ0dvaUEyc2hCd0pBUWV3WktBSUFJQVJHQkVCQjdCa2dBellDQUVIZ0dVSGdHU2dDQUNBSGFpSUFOZ0lBSUFNZ0FFRUJjallDQkF3QkMwSG9HU2dDQUNBRVJnUkFRZWdaSUFNMkFnQkIzQmxCM0Jrb0FnQWdCMm9pQURZQ0FDQURJQUJCQVhJMkFnUWdBQ0FEYWlBQU5nSUFEQUVMSUFRb0FnUWlBRUVEY1VFQlJnUkFJQUJCZUhFaENTQUVLQUlNSVFJQ1FDQUFRZjhCVFFSQUlBUW9BZ2dpQVNBQ1JnUkFRZFFaUWRRWktBSUFRWDRnQUVFRGRuZHhOZ0lBREFJTElBRWdBallDRENBQ0lBRTJBZ2dNQVFzZ0JDZ0NHQ0VHQWtBZ0FpQUVSd1JBSUFRb0FnZ2lBQ0FDTmdJTUlBSWdBRFlDQ0F3QkN3SkFJQVFvQWhRaUFBUi9JQVJCRkdvRklBUW9BaEFpQUVVTkFTQUVRUkJxQ3lFQkEwQWdBU0VGSUFBaUFrRVVhaUVCSUFBb0FoUWlBQTBBSUFKQkVHb2hBU0FDS0FJUUlnQU5BQXNnQlVFQU5nSUFEQUVMUVFBaEFnc2dCa1VOQUFKQUlBUW9BaHdpQUVFQ2RFR0VIR29pQVNnQ0FDQUVSZ1JBSUFFZ0FqWUNBQ0FDRFFGQjJCbEIyQmtvQWdCQmZpQUFkM0UyQWdBTUFnc0NRQ0FFSUFZb0FoQkdCRUFnQmlBQ05nSVFEQUVMSUFZZ0FqWUNGQXNnQWtVTkFRc2dBaUFHTmdJWUlBUW9BaEFpQUFSQUlBSWdBRFlDRUNBQUlBSTJBaGdMSUFRb0FoUWlBRVVOQUNBQ0lBQTJBaFFnQUNBQ05nSVlDeUFISUFscUlRY2dCQ0FKYWlJRUtBSUVJUUFMSUFRZ0FFRitjVFlDQkNBRElBZEJBWEkyQWdRZ0F5QUhhaUFITmdJQUlBZEIvd0ZOQkVBZ0IwRjRjVUg4R1dvaEFBSi9RZFFaS0FJQUlnRkJBU0FIUVFOMmRDSUNjVVVFUUVIVUdTQUJJQUp5TmdJQUlBQU1BUXNnQUNnQ0NBc2hBU0FBSUFNMkFnZ2dBU0FETmdJTUlBTWdBRFlDRENBRElBRTJBZ2dNQVF0Qkh5RUNJQWRCLy8vL0IwMEVRQ0FIUVNZZ0IwRUlkbWNpQUd0MlFRRnhJQUJCQVhSclFUNXFJUUlMSUFNZ0FqWUNIQ0FEUWdBM0FoQWdBa0VDZEVHRUhHb2hBQUpBQWtCQjJCa29BZ0FpQVVFQklBSjBJZ1Z4UlFSQVFkZ1pJQUVnQlhJMkFnQWdBQ0FETmdJQURBRUxJQWRCR1NBQ1FRRjJhMEVBSUFKQkgwY2JkQ0VDSUFBb0FnQWhBUU5BSUFFaUFDZ0NCRUY0Y1NBSFJnMENJQUpCSFhZaEFTQUNRUUYwSVFJZ0FDQUJRUVJ4YWlJRktBSVFJZ0VOQUFzZ0JTQUROZ0lRQ3lBRElBQTJBaGdnQXlBRE5nSU1JQU1nQXpZQ0NBd0JDeUFBS0FJSUlnRWdBellDRENBQUlBTTJBZ2dnQTBFQU5nSVlJQU1nQURZQ0RDQURJQUUyQWdnTElBaEJDR29oQUF3Q0N3SkFJQWhGRFFBQ1FDQUZLQUljSWdGQkFuUkJoQnhxSWdJb0FnQWdCVVlFUUNBQ0lBQTJBZ0FnQUEwQlFkZ1pJQWRCZmlBQmQzRWlCellDQUF3Q0N3SkFJQVVnQ0NnQ0VFWUVRQ0FJSUFBMkFoQU1BUXNnQ0NBQU5nSVVDeUFBUlEwQkN5QUFJQWcyQWhnZ0JTZ0NFQ0lCQkVBZ0FDQUJOZ0lRSUFFZ0FEWUNHQXNnQlNnQ0ZDSUJSUTBBSUFBZ0FUWUNGQ0FCSUFBMkFoZ0xBa0FnQTBFUFRRUkFJQVVnQXlBR2FpSUFRUU55TmdJRUlBQWdCV29pQUNBQUtBSUVRUUZ5TmdJRURBRUxJQVVnQmtFRGNqWUNCQ0FGSUFacUlnUWdBMEVCY2pZQ0JDQURJQVJxSUFNMkFnQWdBMEgvQVUwRVFDQURRWGh4UWZ3WmFpRUFBbjlCMUJrb0FnQWlBVUVCSUFOQkEzWjBJZ0p4UlFSQVFkUVpJQUVnQW5JMkFnQWdBQXdCQ3lBQUtBSUlDeUVCSUFBZ0JEWUNDQ0FCSUFRMkFnd2dCQ0FBTmdJTUlBUWdBVFlDQ0F3QkMwRWZJUUFnQTBILy8vOEhUUVJBSUFOQkppQURRUWgyWnlJQWEzWkJBWEVnQUVFQmRHdEJQbW9oQUFzZ0JDQUFOZ0ljSUFSQ0FEY0NFQ0FBUVFKMFFZUWNhaUVCQWtBQ1FDQUhRUUVnQUhRaUFuRkZCRUJCMkJrZ0FpQUhjallDQUNBQklBUTJBZ0FnQkNBQk5nSVlEQUVMSUFOQkdTQUFRUUYyYTBFQUlBQkJIMGNiZENFQUlBRW9BZ0FoQVFOQUlBRWlBaWdDQkVGNGNTQURSZzBDSUFCQkhYWWhBU0FBUVFGMElRQWdBaUFCUVFSeGFpSUhLQUlRSWdFTkFBc2dCeUFFTmdJUUlBUWdBallDR0FzZ0JDQUVOZ0lNSUFRZ0JEWUNDQXdCQ3lBQ0tBSUlJZ0FnQkRZQ0RDQUNJQVEyQWdnZ0JFRUFOZ0lZSUFRZ0FqWUNEQ0FFSUFBMkFnZ0xJQVZCQ0dvaEFBd0JDd0pBSUFsRkRRQUNRQ0FDS0FJY0lnRkJBblJCaEJ4cUlnVW9BZ0FnQWtZRVFDQUZJQUEyQWdBZ0FBMEJRZGdaSUF0QmZpQUJkM0UyQWdBTUFnc0NRQ0FDSUFrb0FoQkdCRUFnQ1NBQU5nSVFEQUVMSUFrZ0FEWUNGQXNnQUVVTkFRc2dBQ0FKTmdJWUlBSW9BaEFpQVFSQUlBQWdBVFlDRUNBQklBQTJBaGdMSUFJb0FoUWlBVVVOQUNBQUlBRTJBaFFnQVNBQU5nSVlDd0pBSUFOQkQwMEVRQ0FDSUFNZ0Jtb2lBRUVEY2pZQ0JDQUFJQUpxSWdBZ0FDZ0NCRUVCY2pZQ0JBd0JDeUFDSUFaQkEzSTJBZ1FnQWlBR2FpSUZJQU5CQVhJMkFnUWdBeUFGYWlBRE5nSUFJQWdFUUNBSVFYaHhRZndaYWlFQVFlZ1pLQUlBSVFFQ2YwRUJJQWhCQTNaMElnY2dCSEZGQkVCQjFCa2dCQ0FIY2pZQ0FDQUFEQUVMSUFBb0FnZ0xJUVFnQUNBQk5nSUlJQVFnQVRZQ0RDQUJJQUEyQWd3Z0FTQUVOZ0lJQzBIb0dTQUZOZ0lBUWR3WklBTTJBZ0FMSUFKQkNHb2hBQXNnQ2tFUWFpUUFJQUFMcVFzQ0MzOEpmU01BUWFBQmF5SUxKQUFnQzBFd2FrRUFRU1Q4Q3dBRFFDQUJJQTFIQkVBZ0FpQU5RUU5zSWd4QkFtcEJBblFpRG1vcUFnQWhGeUFDSUF4QkFXcEJBblFpRDJvcUFnQWhHQ0FJSUF4QkFuUWlFR29nQWlBUWFpb0NBQ0laT0FJQUlBZ2dEMm9nR0RnQ0FDQUlJQTVxSUJjNEFnQWdCeUFOUVFWMGFpSU1JQmc0QWdRZ0RDQVpPQUlBSUF3Z0Z6Z0NDQ0FNUVFBMkFnd0NRQ0FBUlFSQUlBWWdEV290QUFCRkRRRUxJQXhCZ0lDQUNEWUNEQXNnQnlBTlFRVjBhaUlSSUFVZ0RVRUNkQ0lNUVFGeUloSnFMUUFBUVFoMElBVWdER290QUFCeUlBVWdERUVDY2lJVGFpMEFBRUVRZEhJZ0JTQU1RUU55SWd4cUxRQUFRUmgwY2pZQ0hDQUxJQU1nRWtFQ2RDSVNhaW9DQUNJWE9BS1FBU0FMSUFNZ0UwRUNkQ0lUYWlvQ0FDSVlPQUtVQVNBTElBTWdERUVDZENJVWFpb0NBQ0laT0FLWUFTQUxJQU1nRFVFRWRDSVZhaW9DQUl3aUdqZ0NuQUVnQzBIZ0FHb2lEQ0FMS2dLWUFTSVdRd0FBQU1DVUlCYVVJQXNxQXBRQkloWkRBQUFBd0pRZ0ZwUkRBQUNBUDVLU09BSUFJQXdnQ3lvQ2tBRWlGaUFXa2lBTEtnS1VBWlFnQ3lvQ21BRWlGaUFXa2lBTEtnS2NBWlNUT0FJRUlBd2dDeW9Da0FFaUZpQVdraUFMS2dLWUFaUWdDeW9DbEFFaUZpQVdraUFMS2dLY0FaU1NPQUlJSUF3Z0N5b0NrQUVpRmlBV2tpQUxLZ0tVQVpRZ0N5b0NtQUVpRmlBV2tpQUxLZ0tjQVpTU09BSU1JQXdnQ3lvQ21BRWlGa01BQUFEQWxDQVdsQ0FMS2dLUUFTSVdRd0FBQU1DVUlCYVVRd0FBZ0QrU2tqZ0NFQ0FNSUFzcUFwUUJJaFlnRnBJZ0N5b0NtQUdVSUFzcUFwQUJJaFlnRnBJZ0N5b0NuQUdVa3pnQ0ZDQU1JQXNxQXBBQkloWWdGcElnQ3lvQ21BR1VJQXNxQXBRQkloWWdGcElnQ3lvQ25BR1VremdDR0NBTUlBc3FBcFFCSWhZZ0ZwSWdDeW9DbUFHVUlBc3FBcEFCSWhZZ0ZwSWdDeW9DbkFHVWtqZ0NIQ0FNSUFzcUFwUUJJaFpEQUFBQXdKUWdGcFFnQ3lvQ2tBRWlGa01BQUFEQWxDQVdsRU1BQUlBL2twSTRBaUFnQ1NBVmFpQVhPQUlBSUFrZ0Vtb2dHRGdDQUNBSklCTnFJQms0QWdBZ0NTQVVhaUFhT0FJQUlBc2dCQ0FRYWlvQ0FDSVhPQUl3SUFzZ0JDQVBhaW9DQUNJWU9BSkFJQXNnQkNBT2Fpb0NBQ0laT0FKUUlBb2dFR29nRnpnQ0FDQUtJQTlxSUJnNEFnQWdDaUFPYWlBWk9BSUFJQXNnRENvQ0dDQUxLZ0k0bENBTUtnSUFJQXNxQWpDVUlBd3FBZ3dnQ3lvQ05KU1NramdDQUNBTElBd3FBaHdnQ3lvQ09KUWdEQ29DQkNBTEtnSXdsQ0FNS2dJUUlBc3FBalNVa3BJNEFnUWdDeUFNS2dJZ0lBc3FBamlVSUF3cUFnZ2dDeW9DTUpRZ0RDb0NGQ0FMS2dJMGxKS1NPQUlJSUFzZ0RDb0NHQ0FMS2dKRWxDQU1LZ0lBSUFzcUFqeVVJQXdxQWd3Z0N5b0NRSlNTa2pnQ0RDQUxJQXdxQWh3Z0N5b0NSSlFnRENvQ0JDQUxLZ0k4bENBTUtnSVFJQXNxQWtDVWtwSTRBaEFnQ3lBTUtnSWdJQXNxQWtTVUlBd3FBZ2dnQ3lvQ1BKUWdEQ29DRkNBTEtnSkFsSktTT0FJVUlBc2dEQ29DR0NBTEtnSlFsQ0FNS2dJQUlBc3FBa2lVSUF3cUFnd2dDeW9DVEpTU2tqZ0NHQ0FMSUF3cUFod2dDeW9DVUpRZ0RDb0NCQ0FMS2dKSWxDQU1LZ0lRSUFzcUFreVVrcEk0QWh3Z0N5QU1LZ0lnSUFzcUFsQ1VJQXdxQWdnZ0N5b0NTSlFnRENvQ0ZDQUxLZ0pNbEpLU09BSWdJQXNxQWlBaEZ5QUxLZ0lJSVJnZ0N5b0NGQ0VaSUJFZ0N5b0NHQ0lhSUJxVUlBc3FBZ0FpRmlBV2xDQUxLZ0lNSWhzZ0c1U1Nra01BQUlCQWxDQWFJQXNxQWh3aUhKUWdGaUFMS2dJRUloMlVJQnNnQ3lvQ0VDSWVsSktTUXdBQWdFQ1VFQTAyQWhBZ0VTQWFJQmVVSUJZZ0dKUWdHeUFabEpLU1F3QUFnRUNVSUJ3Z0hKUWdIU0FkbENBZUlCNlVrcEpEQUFDQVFKUVFEVFlDRkNBUklCd2dGNVFnSFNBWWxDQWVJQm1Va3BKREFBQ0FRSlFnRnlBWGxDQVlJQmlVSUJrZ0daU1Nra01BQUlCQWxCQU5OZ0lZSUExQkFXb2hEUXdCQ3dzZ0MwR2dBV29rQUFzYUFDQUFJQUVvQWdnZ0JSQUxCRUFnQVNBQ0lBTWdCQkFUQ3dzM0FDQUFJQUVvQWdnZ0JSQUxCRUFnQVNBQ0lBTWdCQkFURHdzZ0FDZ0NDQ0lBSUFFZ0FpQURJQVFnQlNBQUtBSUFLQUlVRVFNQUM1RUJBQ0FBSUFFb0FnZ2dCQkFMQkVBZ0FTQUNJQU1RRWc4TEFrQWdBQ0FCS0FJQUlBUVFDMFVOQUFKQUlBRW9BaEFnQWtjRVFDQUNJQUVvQWhSSERRRUxJQU5CQVVjTkFTQUJRUUUyQWlBUEN5QUJJQUkyQWhRZ0FTQUROZ0lnSUFFZ0FTZ0NLRUVCYWpZQ0tBSkFJQUVvQWlSQkFVY05BQ0FCS0FJWVFRSkhEUUFnQVVFQk9nQTJDeUFCUVFRMkFpd0xDL1VCQUNBQUlBRW9BZ2dnQkJBTEJFQWdBU0FDSUFNUUVnOExBa0FnQUNBQktBSUFJQVFRQ3dSQUFrQWdBU2dDRUNBQ1J3UkFJQUlnQVNnQ0ZFY05BUXNnQTBFQlJ3MENJQUZCQVRZQ0lBOExJQUVnQXpZQ0lBSkFJQUVvQWl4QkJFWU5BQ0FCUVFBN0FUUWdBQ2dDQ0NJQUlBRWdBaUFDUVFFZ0JDQUFLQUlBS0FJVUVRTUFJQUV0QURWQkFVWUVRQ0FCUVFNMkFpd2dBUzBBTkVVTkFRd0RDeUFCUVFRMkFpd0xJQUVnQWpZQ0ZDQUJJQUVvQWloQkFXbzJBaWdnQVNnQ0pFRUJSdzBCSUFFb0FoaEJBa2NOQVNBQlFRRTZBRFlQQ3lBQUtBSUlJZ0FnQVNBQ0lBTWdCQ0FBS0FJQUtBSVlFUUlBQ3dzeEFDQUFJQUVvQWdoQkFCQUxCRUFnQVNBQ0lBTVFGQThMSUFBb0FnZ2lBQ0FCSUFJZ0F5QUFLQUlBS0FJY0VRQUFDeGdBSUFBZ0FTZ0NDRUVBRUFzRVFDQUJJQUlnQXhBVUN3dWxCUUVHZnlNQVFkQUFheUlFSkFBQ1FBSi9RUUVnQUNBQlFRQVFDdzBBR2tFQUlBRkZEUUFhSXdCQkVHc2lCaVFBSUFZZ0FTZ0NBQ0lEUVFocktBSUFJZ1UyQWd3Z0JpQUJJQVZxTmdJRUlBWWdBMEVFYXlnQ0FEWUNDQ0FHS0FJSUlnTkJ5QWhCQUJBTElRVWdCaWdDQkNFSEFrQWdCUVJBSUFZb0Fnd2hBU01BUVVCcUlnTWtBQ0FEUVVCckpBQkJBQ0FISUFFYklRTU1BUXNnQXlFRkl3QkJRR29pQXlRQUlBRWdCMDRFUUNBRFFnQTNBaHdnQTBJQU53SWtJQU5DQURjQ0xDQURRZ0EzQWhRZ0EwRUFOZ0lRSUFOQnlBZzJBZ3dnQXlBRk5nSUVJQU5CQURZQ1BDQURRb0dBZ0lDQWdJQ0FBVGNDTkNBRElBRTJBZ2dnQlNBRFFRUnFJQWNnQjBFQlFRQWdCU2dDQUNnQ0ZCRURBQ0FCUVFBZ0F5Z0NIQnNoQ0FzZ0EwRkFheVFBSUFnaUF3MEFJd0JCUUdvaUF5UUFJQU5CQURZQ0VDQURRWmdJTmdJTUlBTWdBVFlDQ0NBRFFjZ0lOZ0lFUVFBaEFTQURRUlJxUVFCQkovd0xBQ0FEUVFBMkFqd2dBMEVCT2dBN0lBVWdBMEVFYWlBSFFRRkJBQ0FGS0FJQUtBSVlFUUlBQWtBQ1FBSkFJQU1vQWlnT0FnQUJBZ3NnQXlnQ0dFRUFJQU1vQWlSQkFVWWJRUUFnQXlnQ0lFRUJSaHRCQUNBREtBSXNRUUZHR3lFQkRBRUxJQU1vQWh4QkFVY0VRQ0FES0FJc0RRRWdBeWdDSUVFQlJ3MEJJQU1vQWlSQkFVY05BUXNnQXlnQ0ZDRUJDeUFEUVVCckpBQWdBU0VEQ3lBR1FSQnFKQUJCQUNBRFJRMEFHaUFDS0FJQUlnRkZEUUVnQkVFWWFrRUFRVGo4Q3dBZ0JFRUJPZ0JMSUFSQmZ6WUNJQ0FFSUFBMkFod2dCQ0FETmdJVUlBUkJBVFlDUkNBRElBUkJGR29nQVVFQklBTW9BZ0FvQWh3UkFBQWdCQ2dDTENJQVFRRkdCRUFnQWlBRUtBSWtOZ0lBQ3lBQVFRRkdDeUFFUWRBQWFpUUFEd3NnQkVIUENqWUNDQ0FFUWVVRE5nSUVJQVJCdVFrMkFnQVFDUUFMQ2dBZ0FDQUJRUUFRQ3dzRUFDQUFDd3ZiRVFJQVFZQUlDOG9SQkFrQUFBZ0VBQUJUZERsMGVYQmxYMmx1Wm04QUFBQUFMQWtBQUNRRUFBQUFCQUFBVGpFd1gxOWplSGhoWW1sMk1URTJYMTl6YUdsdFgzUjVjR1ZmYVc1bWIwVUFBQUFBTEFrQUFGUUVBQUFZQkFBQVRqRXdYMTlqZUhoaFltbDJNVEUzWDE5amJHRnpjMTkwZVhCbFgybHVabTlGQUhWdWMybG5ibVZrSUhOb2IzSjBBSFZ1YzJsbmJtVmtJR2x1ZEFCbWJHOWhkQUIxYVc1ME5qUmZkQUFsY3pvbFpEb2dKWE1BZFc1emFXZHVaV1FnWTJoaGNnQXZaVzF6WkdzdlpXMXpZM0pwY0hSbGJpOXplWE4wWlcwdmJHbGlMMnhwWW1ONGVHRmlhUzl6Y21NdmNISnBkbUYwWlY5MGVYQmxhVzVtYnk1amNIQUFZbTl2YkFCMWJuTnBaMjVsWkNCc2IyNW5BSE4wWkRvNmQzTjBjbWx1WndCemRHUTZPbk4wY21sdVp3QnpkR1E2T25VeE5uTjBjbWx1WndCemRHUTZPblV6TW5OMGNtbHVad0JrYjNWaWJHVUFkbTlwWkFCallYUmphR2x1WnlCaElHTnNZWE56SUhkcGRHaHZkWFFnWVc0Z2IySnFaV04wUHdCbGJYTmpjbWx3ZEdWdU9qcHRaVzF2Y25sZmRtbGxkenh6YUc5eWRENEFaVzF6WTNKcGNIUmxiam82YldWdGIzSjVYM1pwWlhjOGRXNXphV2R1WldRZ2MyaHZjblErQUdWdGMyTnlhWEIwWlc0Nk9tMWxiVzl5ZVY5MmFXVjNQR2x1ZEQ0QVpXMXpZM0pwY0hSbGJqbzZiV1Z0YjNKNVgzWnBaWGM4ZFc1emFXZHVaV1FnYVc1MFBnQmxiWE5qY21sd2RHVnVPanB0WlcxdmNubGZkbWxsZHp4bWJHOWhkRDRBWlcxelkzSnBjSFJsYmpvNmJXVnRiM0o1WDNacFpYYzhkV2x1ZERoZmRENEFaVzF6WTNKcGNIUmxiam82YldWdGIzSjVYM1pwWlhjOGFXNTBPRjkwUGdCbGJYTmpjbWx3ZEdWdU9qcHRaVzF2Y25sZmRtbGxkengxYVc1ME1UWmZkRDRBWlcxelkzSnBjSFJsYmpvNmJXVnRiM0o1WDNacFpYYzhhVzUwTVRaZmRENEFaVzF6WTNKcGNIUmxiam82YldWdGIzSjVYM1pwWlhjOGRXbHVkRFkwWDNRK0FHVnRjMk55YVhCMFpXNDZPbTFsYlc5eWVWOTJhV1YzUEdsdWREWTBYM1ErQUdWdGMyTnlhWEIwWlc0Nk9tMWxiVzl5ZVY5MmFXVjNQSFZwYm5Rek1sOTBQZ0JsYlhOamNtbHdkR1Z1T2pwdFpXMXZjbmxmZG1sbGR6eHBiblF6TWw5MFBnQmxiWE5qY21sd2RHVnVPanB0WlcxdmNubGZkbWxsZHp4amFHRnlQZ0JsYlhOamNtbHdkR1Z1T2pwdFpXMXZjbmxmZG1sbGR6eDFibk5wWjI1bFpDQmphR0Z5UGdCbGJYTmpjbWx3ZEdWdU9qcHRaVzF2Y25sZmRtbGxkenh6YVdkdVpXUWdZMmhoY2o0QVpXMXpZM0pwY0hSbGJqbzZiV1Z0YjNKNVgzWnBaWGM4Ykc5dVp6NEFaVzF6WTNKcGNIUmxiam82YldWdGIzSjVYM1pwWlhjOGRXNXphV2R1WldRZ2JHOXVaejRBWlcxelkzSnBjSFJsYmpvNmJXVnRiM0o1WDNacFpYYzhaRzkxWW14bFBnQUFBQUFBQUFBQUZBZ0FBQUVBQUFBQ0FBQUFBd0FBQUFRQUFBQUZBQUFBTEFrQUFDQUlBQUFZQkFBQVRqRXdYMTlqZUhoaFltbDJNVEl6WDE5bWRXNWtZVzFsYm5SaGJGOTBlWEJsWDJsdVptOUZBQUFJQUFCUUNBQUFkZ0FBQUFBSUFBQmNDQUFBWWdBQUFBQUlBQUJvQ0FBQVl3QUFBQUFJQUFCMENBQUFhQUFBQUFBSUFBQ0FDQUFBWVFBQUFBQUlBQUNNQ0FBQWN3QUFBQUFJQUFDWUNBQUFkQUFBQUFBSUFBQ2tDQUFBYVFBQUFBQUlBQUN3Q0FBQWFnQUFBQUFJQUFDOENBQUFiQUFBQUFBSUFBRElDQUFBYlFBQUFBQUlBQURVQ0FBQWVBQUFBQUFJQUFEZ0NBQUFlUUFBQUFBSUFBRHNDQUFBWmdBQUFBQUlBQUQ0Q0FBQVpBQUFBQUFBQUFCSUJBQUFBUUFBQUFZQUFBQURBQUFBQkFBQUFBY0FBQUFJQUFBQUNRQUFBQW9BQUFBQUFBQUFUQWtBQUFFQUFBQUxBQUFBQXdBQUFBUUFBQUFIQUFBQURBQUFBQTBBQUFBT0FBQUFMQWtBQUZnSkFBQklCQUFBVGpFd1gxOWplSGhoWW1sMk1USXdYMTl6YVY5amJHRnpjMTkwZVhCbFgybHVabTlGQUFBQUFBUUpBQUNJQ1FBQVRsTjBNMTlmTWpFeVltRnphV05mYzNSeWFXNW5TV05PVTE4eE1XTm9ZWEpmZEhKaGFYUnpTV05GUlU1VFh6bGhiR3h2WTJGMGIzSkpZMFZGUlVVQUFBUUpBQURRQ1FBQVRsTjBNMTlmTWpFeVltRnphV05mYzNSeWFXNW5TWGRPVTE4eE1XTm9ZWEpmZEhKaGFYUnpTWGRGUlU1VFh6bGhiR3h2WTJGMGIzSkpkMFZGUlVVQUFBUUpBQUFZQ2dBQVRsTjBNMTlmTWpFeVltRnphV05mYzNSeWFXNW5TVVJ6VGxOZk1URmphR0Z5WDNSeVlXbDBjMGxFYzBWRlRsTmZPV0ZzYkc5allYUnZja2xFYzBWRlJVVUFBQUFFQ1FBQVpBb0FBRTVUZEROZlh6SXhNbUpoYzJsalgzTjBjbWx1WjBsRWFVNVRYekV4WTJoaGNsOTBjbUZwZEhOSlJHbEZSVTVUWHpsaGJHeHZZMkYwYjNKSlJHbEZSVVZGQUFBQUJBa0FBTEFLQUFCT01UQmxiWE5qY21sd2RHVnVNM1poYkVVQUFBUUpBQURNQ2dBQVRqRXdaVzF6WTNKcGNIUmxiakV4YldWdGIzSjVYM1pwWlhkSlkwVkZBQUFFQ1FBQTlBb0FBRTR4TUdWdGMyTnlhWEIwWlc0eE1XMWxiVzl5ZVY5MmFXVjNTV0ZGUlFBQUJBa0FBQndMQUFCT01UQmxiWE5qY21sd2RHVnVNVEZ0WlcxdmNubGZkbWxsZDBsb1JVVUFBQVFKQUFCRUN3QUFUakV3WlcxelkzSnBjSFJsYmpFeGJXVnRiM0o1WDNacFpYZEpjMFZGQUFBRUNRQUFiQXNBQUU0eE1HVnRjMk55YVhCMFpXNHhNVzFsYlc5eWVWOTJhV1YzU1hSRlJRQUFCQWtBQUpRTEFBQk9NVEJsYlhOamNtbHdkR1Z1TVRGdFpXMXZjbmxmZG1sbGQwbHBSVVVBQUFRSkFBQzhDd0FBVGpFd1pXMXpZM0pwY0hSbGJqRXhiV1Z0YjNKNVgzWnBaWGRKYWtWRkFBQUVDUUFBNUFzQUFFNHhNR1Z0YzJOeWFYQjBaVzR4TVcxbGJXOXllVjkyYVdWM1NXeEZSUUFBQkFrQUFBd01BQUJPTVRCbGJYTmpjbWx3ZEdWdU1URnRaVzF2Y25sZmRtbGxkMGx0UlVVQUFBUUpBQUEwREFBQVRqRXdaVzF6WTNKcGNIUmxiakV4YldWdGIzSjVYM1pwWlhkSmVFVkZBQUFFQ1FBQVhBd0FBRTR4TUdWdGMyTnlhWEIwWlc0eE1XMWxiVzl5ZVY5MmFXVjNTWGxGUlFBQUJBa0FBSVFNQUFCT01UQmxiWE5qY21sd2RHVnVNVEZ0WlcxdmNubGZkbWxsZDBsbVJVVUFBQVFKQUFDc0RBQUFUakV3WlcxelkzSnBjSFJsYmpFeGJXVnRiM0o1WDNacFpYZEpaRVZGQUVITUdRc0QwQTRCIjtmdW5jdGlvbiBnZXRCaW5hcnlTeW5jKGZpbGUpe2lmKGZpbGU9PXdhc21CaW5hcnlGaWxlJiZ3YXNtQmluYXJ5KXtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkod2FzbUJpbmFyeSl9dmFyIGJpbmFyeT10cnlQYXJzZUFzRGF0YVVSSShmaWxlKTtpZihiaW5hcnkpe3JldHVybiBiaW5hcnl9aWYocmVhZEJpbmFyeSl7cmV0dXJuIHJlYWRCaW5hcnkoZmlsZSl9dGhyb3cgImJvdGggYXN5bmMgYW5kIHN5bmMgZmV0Y2hpbmcgb2YgdGhlIHdhc20gZmFpbGVkIn1hc3luYyBmdW5jdGlvbiBnZXRXYXNtQmluYXJ5KGJpbmFyeUZpbGUpe3JldHVybiBnZXRCaW5hcnlTeW5jKGJpbmFyeUZpbGUpfWFzeW5jIGZ1bmN0aW9uIGluc3RhbnRpYXRlQXJyYXlCdWZmZXIoYmluYXJ5RmlsZSxpbXBvcnRzKXt0cnl7dmFyIGJpbmFyeT1hd2FpdCBnZXRXYXNtQmluYXJ5KGJpbmFyeUZpbGUpO3ZhciBpbnN0YW5jZT1hd2FpdCBXZWJBc3NlbWJseS5pbnN0YW50aWF0ZShiaW5hcnksaW1wb3J0cyk7cmV0dXJuIGluc3RhbmNlfWNhdGNoKHJlYXNvbil7ZXJyKGBmYWlsZWQgdG8gYXN5bmNocm9ub3VzbHkgcHJlcGFyZSB3YXNtOiAke3JlYXNvbn1gKTthYm9ydChyZWFzb24pO319YXN5bmMgZnVuY3Rpb24gaW5zdGFudGlhdGVBc3luYyhiaW5hcnksYmluYXJ5RmlsZSxpbXBvcnRzKXtyZXR1cm4gaW5zdGFudGlhdGVBcnJheUJ1ZmZlcihiaW5hcnlGaWxlLGltcG9ydHMpfWZ1bmN0aW9uIGdldFdhc21JbXBvcnRzKCl7cmV0dXJuIHthOndhc21JbXBvcnRzfX1hc3luYyBmdW5jdGlvbiBjcmVhdGVXYXNtKCl7ZnVuY3Rpb24gcmVjZWl2ZUluc3RhbmNlKGluc3RhbmNlLG1vZHVsZSl7d2FzbUV4cG9ydHM9aW5zdGFuY2UuZXhwb3J0czt3YXNtTWVtb3J5PXdhc21FeHBvcnRzWyJsIl07dXBkYXRlTWVtb3J5Vmlld3MoKTtyZW1vdmVSdW5EZXBlbmRlbmN5KCk7cmV0dXJuIHdhc21FeHBvcnRzfWFkZFJ1bkRlcGVuZGVuY3koKTtmdW5jdGlvbiByZWNlaXZlSW5zdGFudGlhdGlvblJlc3VsdChyZXN1bHQpe3JldHVybiByZWNlaXZlSW5zdGFuY2UocmVzdWx0WyJpbnN0YW5jZSJdKX12YXIgaW5mbz1nZXRXYXNtSW1wb3J0cygpO2lmKE1vZHVsZVsiaW5zdGFudGlhdGVXYXNtIl0pe3JldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSxyZWplY3QpPT57TW9kdWxlWyJpbnN0YW50aWF0ZVdhc20iXShpbmZvLChtb2QsaW5zdCk9PntyZWNlaXZlSW5zdGFuY2UobW9kKTtyZXNvbHZlKG1vZC5leHBvcnRzKTt9KTt9KX10cnl7dmFyIHJlc3VsdD1hd2FpdCBpbnN0YW50aWF0ZUFzeW5jKHdhc21CaW5hcnksd2FzbUJpbmFyeUZpbGUsaW5mbyk7dmFyIGV4cG9ydHM9cmVjZWl2ZUluc3RhbnRpYXRpb25SZXN1bHQocmVzdWx0KTtyZXR1cm4gZXhwb3J0c31jYXRjaChlKXtyZWFkeVByb21pc2VSZWplY3QoZSk7cmV0dXJuIFByb21pc2UucmVqZWN0KGUpfX12YXIgY2FsbFJ1bnRpbWVDYWxsYmFja3M9Y2FsbGJhY2tzPT57d2hpbGUoY2FsbGJhY2tzLmxlbmd0aD4wKXtjYWxsYmFja3Muc2hpZnQoKShNb2R1bGUpO319O3ZhciBvblBvc3RSdW5zPVtdO3ZhciBhZGRPblBvc3RSdW49Y2I9Pm9uUG9zdFJ1bnMudW5zaGlmdChjYik7dmFyIG9uUHJlUnVucz1bXTt2YXIgYWRkT25QcmVSdW49Y2I9Pm9uUHJlUnVucy51bnNoaWZ0KGNiKTtNb2R1bGVbIm5vRXhpdFJ1bnRpbWUiXXx8dHJ1ZTt2YXIgYmFzZTY0RGVjb2RlPWI2ND0+e3ZhciBiMSxiMixpPTAsaj0wLGJMZW5ndGg9YjY0Lmxlbmd0aDt2YXIgb3V0cHV0PW5ldyBVaW50OEFycmF5KChiTGVuZ3RoKjM+PjIpLShiNjRbYkxlbmd0aC0yXT09Ij0iKS0oYjY0W2JMZW5ndGgtMV09PSI9IikpO2Zvcig7aTxiTGVuZ3RoO2krPTQsais9Myl7YjE9YmFzZTY0UmV2ZXJzZUxvb2t1cFtiNjQuY2hhckNvZGVBdChpKzEpXTtiMj1iYXNlNjRSZXZlcnNlTG9va3VwW2I2NC5jaGFyQ29kZUF0KGkrMildO291dHB1dFtqXT1iYXNlNjRSZXZlcnNlTG9va3VwW2I2NC5jaGFyQ29kZUF0KGkpXTw8MnxiMT4+NDtvdXRwdXRbaisxXT1iMTw8NHxiMj4+MjtvdXRwdXRbaisyXT1iMjw8NnxiYXNlNjRSZXZlcnNlTG9va3VwW2I2NC5jaGFyQ29kZUF0KGkrMyldO31yZXR1cm4gb3V0cHV0fTt2YXIgaXNEYXRhVVJJPWZpbGVuYW1lPT5maWxlbmFtZS5zdGFydHNXaXRoKGRhdGFVUklQcmVmaXgpO3ZhciBkYXRhVVJJUHJlZml4PSJkYXRhOmFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbTtiYXNlNjQsIjt2YXIgdHJ5UGFyc2VBc0RhdGFVUkk9ZmlsZW5hbWU9PntpZihpc0RhdGFVUkkoZmlsZW5hbWUpKXtyZXR1cm4gYmFzZTY0RGVjb2RlKGZpbGVuYW1lLnNsaWNlKGRhdGFVUklQcmVmaXgubGVuZ3RoKSl9fTt2YXIgX19hYm9ydF9qcz0oKT0+YWJvcnQoIiIpO3ZhciBlbWJpbmRSZXByPXY9PntpZih2PT09bnVsbCl7cmV0dXJuICJudWxsIn12YXIgdD10eXBlb2YgdjtpZih0PT09Im9iamVjdCJ8fHQ9PT0iYXJyYXkifHx0PT09ImZ1bmN0aW9uIil7cmV0dXJuIHYudG9TdHJpbmcoKX1lbHNlIHtyZXR1cm4gIiIrdn19O3ZhciBlbWJpbmRfaW5pdF9jaGFyQ29kZXM9KCk9Pnt2YXIgY29kZXM9bmV3IEFycmF5KDI1Nik7Zm9yKHZhciBpPTA7aTwyNTY7KytpKXtjb2Rlc1tpXT1TdHJpbmcuZnJvbUNoYXJDb2RlKGkpO31lbWJpbmRfY2hhckNvZGVzPWNvZGVzO307dmFyIGVtYmluZF9jaGFyQ29kZXM7dmFyIHJlYWRMYXRpbjFTdHJpbmc9cHRyPT57dmFyIHJldD0iIjt2YXIgYz1wdHI7d2hpbGUoSEVBUFU4W2NdKXtyZXQrPWVtYmluZF9jaGFyQ29kZXNbSEVBUFU4W2MrK11dO31yZXR1cm4gcmV0fTt2YXIgYXdhaXRpbmdEZXBlbmRlbmNpZXM9e307dmFyIHJlZ2lzdGVyZWRUeXBlcz17fTt2YXIgQmluZGluZ0Vycm9yO3ZhciB0aHJvd0JpbmRpbmdFcnJvcj1tZXNzYWdlPT57dGhyb3cgbmV3IEJpbmRpbmdFcnJvcihtZXNzYWdlKX07ZnVuY3Rpb24gc2hhcmVkUmVnaXN0ZXJUeXBlKHJhd1R5cGUscmVnaXN0ZXJlZEluc3RhbmNlLG9wdGlvbnM9e30pe3ZhciBuYW1lPXJlZ2lzdGVyZWRJbnN0YW5jZS5uYW1lO2lmKCFyYXdUeXBlKXt0aHJvd0JpbmRpbmdFcnJvcihgdHlwZSAiJHtuYW1lfSIgbXVzdCBoYXZlIGEgcG9zaXRpdmUgaW50ZWdlciB0eXBlaWQgcG9pbnRlcmApO31pZihyZWdpc3RlcmVkVHlwZXMuaGFzT3duUHJvcGVydHkocmF3VHlwZSkpe2lmKG9wdGlvbnMuaWdub3JlRHVwbGljYXRlUmVnaXN0cmF0aW9ucyl7cmV0dXJufWVsc2Uge3Rocm93QmluZGluZ0Vycm9yKGBDYW5ub3QgcmVnaXN0ZXIgdHlwZSAnJHtuYW1lfScgdHdpY2VgKTt9fXJlZ2lzdGVyZWRUeXBlc1tyYXdUeXBlXT1yZWdpc3RlcmVkSW5zdGFuY2U7aWYoYXdhaXRpbmdEZXBlbmRlbmNpZXMuaGFzT3duUHJvcGVydHkocmF3VHlwZSkpe3ZhciBjYWxsYmFja3M9YXdhaXRpbmdEZXBlbmRlbmNpZXNbcmF3VHlwZV07ZGVsZXRlIGF3YWl0aW5nRGVwZW5kZW5jaWVzW3Jhd1R5cGVdO2NhbGxiYWNrcy5mb3JFYWNoKGNiPT5jYigpKTt9fWZ1bmN0aW9uIHJlZ2lzdGVyVHlwZShyYXdUeXBlLHJlZ2lzdGVyZWRJbnN0YW5jZSxvcHRpb25zPXt9KXtyZXR1cm4gc2hhcmVkUmVnaXN0ZXJUeXBlKHJhd1R5cGUscmVnaXN0ZXJlZEluc3RhbmNlLG9wdGlvbnMpfXZhciBpbnRlZ2VyUmVhZFZhbHVlRnJvbVBvaW50ZXI9KG5hbWUsd2lkdGgsc2lnbmVkKT0+e3N3aXRjaCh3aWR0aCl7Y2FzZSAxOnJldHVybiBzaWduZWQ/cG9pbnRlcj0+SEVBUDhbcG9pbnRlcl06cG9pbnRlcj0+SEVBUFU4W3BvaW50ZXJdO2Nhc2UgMjpyZXR1cm4gc2lnbmVkP3BvaW50ZXI9PkhFQVAxNltwb2ludGVyPj4xXTpwb2ludGVyPT5IRUFQVTE2W3BvaW50ZXI+PjFdO2Nhc2UgNDpyZXR1cm4gc2lnbmVkP3BvaW50ZXI9PkhFQVAzMltwb2ludGVyPj4yXTpwb2ludGVyPT5IRUFQVTMyW3BvaW50ZXI+PjJdO2Nhc2UgODpyZXR1cm4gc2lnbmVkP3BvaW50ZXI9PkhFQVA2NFtwb2ludGVyPj4zXTpwb2ludGVyPT5IRUFQVTY0W3BvaW50ZXI+PjNdO2RlZmF1bHQ6dGhyb3cgbmV3IFR5cGVFcnJvcihgaW52YWxpZCBpbnRlZ2VyIHdpZHRoICgke3dpZHRofSk6ICR7bmFtZX1gKX19O3ZhciBfX2VtYmluZF9yZWdpc3Rlcl9iaWdpbnQ9KHByaW1pdGl2ZVR5cGUsbmFtZSxzaXplLG1pblJhbmdlLG1heFJhbmdlKT0+e25hbWU9cmVhZExhdGluMVN0cmluZyhuYW1lKTt2YXIgaXNVbnNpZ25lZFR5cGU9bmFtZS5pbmRleE9mKCJ1IikhPS0xO3JlZ2lzdGVyVHlwZShwcmltaXRpdmVUeXBlLHtuYW1lLGZyb21XaXJlVHlwZTp2YWx1ZT0+dmFsdWUsdG9XaXJlVHlwZTpmdW5jdGlvbihkZXN0cnVjdG9ycyx2YWx1ZSl7aWYodHlwZW9mIHZhbHVlIT0iYmlnaW50IiYmdHlwZW9mIHZhbHVlIT0ibnVtYmVyIil7dGhyb3cgbmV3IFR5cGVFcnJvcihgQ2Fubm90IGNvbnZlcnQgIiR7ZW1iaW5kUmVwcih2YWx1ZSl9IiB0byAke3RoaXMubmFtZX1gKX1pZih0eXBlb2YgdmFsdWU9PSJudW1iZXIiKXt2YWx1ZT1CaWdJbnQodmFsdWUpO31yZXR1cm4gdmFsdWV9LGFyZ1BhY2tBZHZhbmNlOkdlbmVyaWNXaXJlVHlwZVNpemUscmVhZFZhbHVlRnJvbVBvaW50ZXI6aW50ZWdlclJlYWRWYWx1ZUZyb21Qb2ludGVyKG5hbWUsc2l6ZSwhaXNVbnNpZ25lZFR5cGUpLGRlc3RydWN0b3JGdW5jdGlvbjpudWxsfSk7fTt2YXIgR2VuZXJpY1dpcmVUeXBlU2l6ZT04O3ZhciBfX2VtYmluZF9yZWdpc3Rlcl9ib29sPShyYXdUeXBlLG5hbWUsdHJ1ZVZhbHVlLGZhbHNlVmFsdWUpPT57bmFtZT1yZWFkTGF0aW4xU3RyaW5nKG5hbWUpO3JlZ2lzdGVyVHlwZShyYXdUeXBlLHtuYW1lLGZyb21XaXJlVHlwZTpmdW5jdGlvbih3dCl7cmV0dXJuICEhd3R9LHRvV2lyZVR5cGU6ZnVuY3Rpb24oZGVzdHJ1Y3RvcnMsbyl7cmV0dXJuIG8/dHJ1ZVZhbHVlOmZhbHNlVmFsdWV9LGFyZ1BhY2tBZHZhbmNlOkdlbmVyaWNXaXJlVHlwZVNpemUscmVhZFZhbHVlRnJvbVBvaW50ZXI6ZnVuY3Rpb24ocG9pbnRlcil7cmV0dXJuIHRoaXNbImZyb21XaXJlVHlwZSJdKEhFQVBVOFtwb2ludGVyXSl9LGRlc3RydWN0b3JGdW5jdGlvbjpudWxsfSk7fTt2YXIgZW12YWxfZnJlZWxpc3Q9W107dmFyIGVtdmFsX2hhbmRsZXM9W107dmFyIF9fZW12YWxfZGVjcmVmPWhhbmRsZT0+e2lmKGhhbmRsZT45JiYwPT09LS1lbXZhbF9oYW5kbGVzW2hhbmRsZSsxXSl7ZW12YWxfaGFuZGxlc1toYW5kbGVdPXVuZGVmaW5lZDtlbXZhbF9mcmVlbGlzdC5wdXNoKGhhbmRsZSk7fX07dmFyIGNvdW50X2VtdmFsX2hhbmRsZXM9KCk9PmVtdmFsX2hhbmRsZXMubGVuZ3RoLzItNS1lbXZhbF9mcmVlbGlzdC5sZW5ndGg7dmFyIGluaXRfZW12YWw9KCk9PntlbXZhbF9oYW5kbGVzLnB1c2goMCwxLHVuZGVmaW5lZCwxLG51bGwsMSx0cnVlLDEsZmFsc2UsMSk7TW9kdWxlWyJjb3VudF9lbXZhbF9oYW5kbGVzIl09Y291bnRfZW12YWxfaGFuZGxlczt9O3ZhciBFbXZhbD17dG9WYWx1ZTpoYW5kbGU9PntpZighaGFuZGxlKXt0aHJvd0JpbmRpbmdFcnJvcigiQ2Fubm90IHVzZSBkZWxldGVkIHZhbC4gaGFuZGxlID0gIitoYW5kbGUpO31yZXR1cm4gZW12YWxfaGFuZGxlc1toYW5kbGVdfSx0b0hhbmRsZTp2YWx1ZT0+e3N3aXRjaCh2YWx1ZSl7Y2FzZSB1bmRlZmluZWQ6cmV0dXJuIDI7Y2FzZSBudWxsOnJldHVybiA0O2Nhc2UgdHJ1ZTpyZXR1cm4gNjtjYXNlIGZhbHNlOnJldHVybiA4O2RlZmF1bHQ6e2NvbnN0IGhhbmRsZT1lbXZhbF9mcmVlbGlzdC5wb3AoKXx8ZW12YWxfaGFuZGxlcy5sZW5ndGg7ZW12YWxfaGFuZGxlc1toYW5kbGVdPXZhbHVlO2VtdmFsX2hhbmRsZXNbaGFuZGxlKzFdPTE7cmV0dXJuIGhhbmRsZX19fX07ZnVuY3Rpb24gcmVhZFBvaW50ZXIocG9pbnRlcil7cmV0dXJuIHRoaXNbImZyb21XaXJlVHlwZSJdKEhFQVBVMzJbcG9pbnRlcj4+Ml0pfXZhciBFbVZhbFR5cGU9e25hbWU6ImVtc2NyaXB0ZW46OnZhbCIsZnJvbVdpcmVUeXBlOmhhbmRsZT0+e3ZhciBydj1FbXZhbC50b1ZhbHVlKGhhbmRsZSk7X19lbXZhbF9kZWNyZWYoaGFuZGxlKTtyZXR1cm4gcnZ9LHRvV2lyZVR5cGU6KGRlc3RydWN0b3JzLHZhbHVlKT0+RW12YWwudG9IYW5kbGUodmFsdWUpLGFyZ1BhY2tBZHZhbmNlOkdlbmVyaWNXaXJlVHlwZVNpemUscmVhZFZhbHVlRnJvbVBvaW50ZXI6cmVhZFBvaW50ZXIsZGVzdHJ1Y3RvckZ1bmN0aW9uOm51bGx9O3ZhciBfX2VtYmluZF9yZWdpc3Rlcl9lbXZhbD1yYXdUeXBlPT5yZWdpc3RlclR5cGUocmF3VHlwZSxFbVZhbFR5cGUpO3ZhciBmbG9hdFJlYWRWYWx1ZUZyb21Qb2ludGVyPShuYW1lLHdpZHRoKT0+e3N3aXRjaCh3aWR0aCl7Y2FzZSA0OnJldHVybiBmdW5jdGlvbihwb2ludGVyKXtyZXR1cm4gdGhpc1siZnJvbVdpcmVUeXBlIl0oSEVBUEYzMltwb2ludGVyPj4yXSl9O2Nhc2UgODpyZXR1cm4gZnVuY3Rpb24ocG9pbnRlcil7cmV0dXJuIHRoaXNbImZyb21XaXJlVHlwZSJdKEhFQVBGNjRbcG9pbnRlcj4+M10pfTtkZWZhdWx0OnRocm93IG5ldyBUeXBlRXJyb3IoYGludmFsaWQgZmxvYXQgd2lkdGggKCR7d2lkdGh9KTogJHtuYW1lfWApfX07dmFyIF9fZW1iaW5kX3JlZ2lzdGVyX2Zsb2F0PShyYXdUeXBlLG5hbWUsc2l6ZSk9PntuYW1lPXJlYWRMYXRpbjFTdHJpbmcobmFtZSk7cmVnaXN0ZXJUeXBlKHJhd1R5cGUse25hbWUsZnJvbVdpcmVUeXBlOnZhbHVlPT52YWx1ZSx0b1dpcmVUeXBlOihkZXN0cnVjdG9ycyx2YWx1ZSk9PnZhbHVlLGFyZ1BhY2tBZHZhbmNlOkdlbmVyaWNXaXJlVHlwZVNpemUscmVhZFZhbHVlRnJvbVBvaW50ZXI6ZmxvYXRSZWFkVmFsdWVGcm9tUG9pbnRlcihuYW1lLHNpemUpLGRlc3RydWN0b3JGdW5jdGlvbjpudWxsfSk7fTt2YXIgX19lbWJpbmRfcmVnaXN0ZXJfaW50ZWdlcj0ocHJpbWl0aXZlVHlwZSxuYW1lLHNpemUsbWluUmFuZ2UsbWF4UmFuZ2UpPT57bmFtZT1yZWFkTGF0aW4xU3RyaW5nKG5hbWUpO3ZhciBmcm9tV2lyZVR5cGU9dmFsdWU9PnZhbHVlO2lmKG1pblJhbmdlPT09MCl7dmFyIGJpdHNoaWZ0PTMyLTgqc2l6ZTtmcm9tV2lyZVR5cGU9dmFsdWU9PnZhbHVlPDxiaXRzaGlmdD4+PmJpdHNoaWZ0O312YXIgaXNVbnNpZ25lZFR5cGU9bmFtZS5pbmNsdWRlcygidW5zaWduZWQiKTt2YXIgY2hlY2tBc3NlcnRpb25zPSh2YWx1ZSx0b1R5cGVOYW1lKT0+e307dmFyIHRvV2lyZVR5cGU7aWYoaXNVbnNpZ25lZFR5cGUpe3RvV2lyZVR5cGU9ZnVuY3Rpb24oZGVzdHJ1Y3RvcnMsdmFsdWUpe2NoZWNrQXNzZXJ0aW9ucyh2YWx1ZSx0aGlzLm5hbWUpO3JldHVybiB2YWx1ZT4+PjB9O31lbHNlIHt0b1dpcmVUeXBlPWZ1bmN0aW9uKGRlc3RydWN0b3JzLHZhbHVlKXtjaGVja0Fzc2VydGlvbnModmFsdWUsdGhpcy5uYW1lKTtyZXR1cm4gdmFsdWV9O31yZWdpc3RlclR5cGUocHJpbWl0aXZlVHlwZSx7bmFtZSxmcm9tV2lyZVR5cGUsdG9XaXJlVHlwZSxhcmdQYWNrQWR2YW5jZTpHZW5lcmljV2lyZVR5cGVTaXplLHJlYWRWYWx1ZUZyb21Qb2ludGVyOmludGVnZXJSZWFkVmFsdWVGcm9tUG9pbnRlcihuYW1lLHNpemUsbWluUmFuZ2UhPT0wKSxkZXN0cnVjdG9yRnVuY3Rpb246bnVsbH0pO307dmFyIF9fZW1iaW5kX3JlZ2lzdGVyX21lbW9yeV92aWV3PShyYXdUeXBlLGRhdGFUeXBlSW5kZXgsbmFtZSk9Pnt2YXIgdHlwZU1hcHBpbmc9W0ludDhBcnJheSxVaW50OEFycmF5LEludDE2QXJyYXksVWludDE2QXJyYXksSW50MzJBcnJheSxVaW50MzJBcnJheSxGbG9hdDMyQXJyYXksRmxvYXQ2NEFycmF5LEJpZ0ludDY0QXJyYXksQmlnVWludDY0QXJyYXldO3ZhciBUQT10eXBlTWFwcGluZ1tkYXRhVHlwZUluZGV4XTtmdW5jdGlvbiBkZWNvZGVNZW1vcnlWaWV3KGhhbmRsZSl7dmFyIHNpemU9SEVBUFUzMltoYW5kbGU+PjJdO3ZhciBkYXRhPUhFQVBVMzJbaGFuZGxlKzQ+PjJdO3JldHVybiBuZXcgVEEoSEVBUDguYnVmZmVyLGRhdGEsc2l6ZSl9bmFtZT1yZWFkTGF0aW4xU3RyaW5nKG5hbWUpO3JlZ2lzdGVyVHlwZShyYXdUeXBlLHtuYW1lLGZyb21XaXJlVHlwZTpkZWNvZGVNZW1vcnlWaWV3LGFyZ1BhY2tBZHZhbmNlOkdlbmVyaWNXaXJlVHlwZVNpemUscmVhZFZhbHVlRnJvbVBvaW50ZXI6ZGVjb2RlTWVtb3J5Vmlld30se2lnbm9yZUR1cGxpY2F0ZVJlZ2lzdHJhdGlvbnM6dHJ1ZX0pO307dmFyIHN0cmluZ1RvVVRGOEFycmF5PShzdHIsaGVhcCxvdXRJZHgsbWF4Qnl0ZXNUb1dyaXRlKT0+e2lmKCEobWF4Qnl0ZXNUb1dyaXRlPjApKXJldHVybiAwO3ZhciBzdGFydElkeD1vdXRJZHg7dmFyIGVuZElkeD1vdXRJZHgrbWF4Qnl0ZXNUb1dyaXRlLTE7Zm9yKHZhciBpPTA7aTxzdHIubGVuZ3RoOysraSl7dmFyIHU9c3RyLmNoYXJDb2RlQXQoaSk7aWYodT49NTUyOTYmJnU8PTU3MzQzKXt2YXIgdTE9c3RyLmNoYXJDb2RlQXQoKytpKTt1PTY1NTM2KygodSYxMDIzKTw8MTApfHUxJjEwMjM7fWlmKHU8PTEyNyl7aWYob3V0SWR4Pj1lbmRJZHgpYnJlYWs7aGVhcFtvdXRJZHgrK109dTt9ZWxzZSBpZih1PD0yMDQ3KXtpZihvdXRJZHgrMT49ZW5kSWR4KWJyZWFrO2hlYXBbb3V0SWR4KytdPTE5Mnx1Pj42O2hlYXBbb3V0SWR4KytdPTEyOHx1JjYzO31lbHNlIGlmKHU8PTY1NTM1KXtpZihvdXRJZHgrMj49ZW5kSWR4KWJyZWFrO2hlYXBbb3V0SWR4KytdPTIyNHx1Pj4xMjtoZWFwW291dElkeCsrXT0xMjh8dT4+NiY2MztoZWFwW291dElkeCsrXT0xMjh8dSY2Mzt9ZWxzZSB7aWYob3V0SWR4KzM+PWVuZElkeClicmVhaztoZWFwW291dElkeCsrXT0yNDB8dT4+MTg7aGVhcFtvdXRJZHgrK109MTI4fHU+PjEyJjYzO2hlYXBbb3V0SWR4KytdPTEyOHx1Pj42JjYzO2hlYXBbb3V0SWR4KytdPTEyOHx1JjYzO319aGVhcFtvdXRJZHhdPTA7cmV0dXJuIG91dElkeC1zdGFydElkeH07dmFyIHN0cmluZ1RvVVRGOD0oc3RyLG91dFB0cixtYXhCeXRlc1RvV3JpdGUpPT5zdHJpbmdUb1VURjhBcnJheShzdHIsSEVBUFU4LG91dFB0cixtYXhCeXRlc1RvV3JpdGUpO3ZhciBsZW5ndGhCeXRlc1VURjg9c3RyPT57dmFyIGxlbj0wO2Zvcih2YXIgaT0wO2k8c3RyLmxlbmd0aDsrK2kpe3ZhciBjPXN0ci5jaGFyQ29kZUF0KGkpO2lmKGM8PTEyNyl7bGVuKys7fWVsc2UgaWYoYzw9MjA0Nyl7bGVuKz0yO31lbHNlIGlmKGM+PTU1Mjk2JiZjPD01NzM0Myl7bGVuKz00OysraTt9ZWxzZSB7bGVuKz0zO319cmV0dXJuIGxlbn07dmFyIFVURjhEZWNvZGVyPXR5cGVvZiBUZXh0RGVjb2RlciE9InVuZGVmaW5lZCI/bmV3IFRleHREZWNvZGVyOnVuZGVmaW5lZDt2YXIgVVRGOEFycmF5VG9TdHJpbmc9KGhlYXBPckFycmF5LGlkeD0wLG1heEJ5dGVzVG9SZWFkPU5hTik9Pnt2YXIgZW5kSWR4PWlkeCttYXhCeXRlc1RvUmVhZDt2YXIgZW5kUHRyPWlkeDt3aGlsZShoZWFwT3JBcnJheVtlbmRQdHJdJiYhKGVuZFB0cj49ZW5kSWR4KSkrK2VuZFB0cjtpZihlbmRQdHItaWR4PjE2JiZoZWFwT3JBcnJheS5idWZmZXImJlVURjhEZWNvZGVyKXtyZXR1cm4gVVRGOERlY29kZXIuZGVjb2RlKGhlYXBPckFycmF5LnN1YmFycmF5KGlkeCxlbmRQdHIpKX12YXIgc3RyPSIiO3doaWxlKGlkeDxlbmRQdHIpe3ZhciB1MD1oZWFwT3JBcnJheVtpZHgrK107aWYoISh1MCYxMjgpKXtzdHIrPVN0cmluZy5mcm9tQ2hhckNvZGUodTApO2NvbnRpbnVlfXZhciB1MT1oZWFwT3JBcnJheVtpZHgrK10mNjM7aWYoKHUwJjIyNCk9PTE5Mil7c3RyKz1TdHJpbmcuZnJvbUNoYXJDb2RlKCh1MCYzMSk8PDZ8dTEpO2NvbnRpbnVlfXZhciB1Mj1oZWFwT3JBcnJheVtpZHgrK10mNjM7aWYoKHUwJjI0MCk9PTIyNCl7dTA9KHUwJjE1KTw8MTJ8dTE8PDZ8dTI7fWVsc2Uge3UwPSh1MCY3KTw8MTh8dTE8PDEyfHUyPDw2fGhlYXBPckFycmF5W2lkeCsrXSY2Mzt9aWYodTA8NjU1MzYpe3N0cis9U3RyaW5nLmZyb21DaGFyQ29kZSh1MCk7fWVsc2Uge3ZhciBjaD11MC02NTUzNjtzdHIrPVN0cmluZy5mcm9tQ2hhckNvZGUoNTUyOTZ8Y2g+PjEwLDU2MzIwfGNoJjEwMjMpO319cmV0dXJuIHN0cn07dmFyIFVURjhUb1N0cmluZz0ocHRyLG1heEJ5dGVzVG9SZWFkKT0+cHRyP1VURjhBcnJheVRvU3RyaW5nKEhFQVBVOCxwdHIsbWF4Qnl0ZXNUb1JlYWQpOiIiO3ZhciBfX2VtYmluZF9yZWdpc3Rlcl9zdGRfc3RyaW5nPShyYXdUeXBlLG5hbWUpPT57bmFtZT1yZWFkTGF0aW4xU3RyaW5nKG5hbWUpO3JlZ2lzdGVyVHlwZShyYXdUeXBlLHtuYW1lLGZyb21XaXJlVHlwZSh2YWx1ZSl7dmFyIGxlbmd0aD1IRUFQVTMyW3ZhbHVlPj4yXTt2YXIgcGF5bG9hZD12YWx1ZSs0O3ZhciBzdHI7dmFyIGk7IHt2YXIgZGVjb2RlU3RhcnRQdHI9cGF5bG9hZDtmb3IodmFyIGk9MDtpPD1sZW5ndGg7KytpKXt2YXIgY3VycmVudEJ5dGVQdHI9cGF5bG9hZCtpO2lmKGk9PWxlbmd0aHx8SEVBUFU4W2N1cnJlbnRCeXRlUHRyXT09MCl7dmFyIG1heFJlYWQ9Y3VycmVudEJ5dGVQdHItZGVjb2RlU3RhcnRQdHI7dmFyIHN0cmluZ1NlZ21lbnQ9VVRGOFRvU3RyaW5nKGRlY29kZVN0YXJ0UHRyLG1heFJlYWQpO2lmKHN0cj09PXVuZGVmaW5lZCl7c3RyPXN0cmluZ1NlZ21lbnQ7fWVsc2Uge3N0cis9U3RyaW5nLmZyb21DaGFyQ29kZSgwKTtzdHIrPXN0cmluZ1NlZ21lbnQ7fWRlY29kZVN0YXJ0UHRyPWN1cnJlbnRCeXRlUHRyKzE7fX19X2ZyZWUodmFsdWUpO3JldHVybiBzdHJ9LHRvV2lyZVR5cGUoZGVzdHJ1Y3RvcnMsdmFsdWUpe2lmKHZhbHVlIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpe3ZhbHVlPW5ldyBVaW50OEFycmF5KHZhbHVlKTt9dmFyIGxlbmd0aDt2YXIgdmFsdWVJc09mVHlwZVN0cmluZz10eXBlb2YgdmFsdWU9PSJzdHJpbmciO2lmKCEodmFsdWVJc09mVHlwZVN0cmluZ3x8dmFsdWUgaW5zdGFuY2VvZiBVaW50OEFycmF5fHx2YWx1ZSBpbnN0YW5jZW9mIFVpbnQ4Q2xhbXBlZEFycmF5fHx2YWx1ZSBpbnN0YW5jZW9mIEludDhBcnJheSkpe3Rocm93QmluZGluZ0Vycm9yKCJDYW5ub3QgcGFzcyBub24tc3RyaW5nIHRvIHN0ZDo6c3RyaW5nIik7fWlmKHZhbHVlSXNPZlR5cGVTdHJpbmcpe2xlbmd0aD1sZW5ndGhCeXRlc1VURjgodmFsdWUpO31lbHNlIHtsZW5ndGg9dmFsdWUubGVuZ3RoO312YXIgYmFzZT1fbWFsbG9jKDQrbGVuZ3RoKzEpO3ZhciBwdHI9YmFzZSs0O0hFQVBVMzJbYmFzZT4+Ml09bGVuZ3RoO2lmKHZhbHVlSXNPZlR5cGVTdHJpbmcpe3N0cmluZ1RvVVRGOCh2YWx1ZSxwdHIsbGVuZ3RoKzEpO31lbHNlIHtpZih2YWx1ZUlzT2ZUeXBlU3RyaW5nKXtmb3IodmFyIGk9MDtpPGxlbmd0aDsrK2kpe3ZhciBjaGFyQ29kZT12YWx1ZS5jaGFyQ29kZUF0KGkpO2lmKGNoYXJDb2RlPjI1NSl7X2ZyZWUoYmFzZSk7dGhyb3dCaW5kaW5nRXJyb3IoIlN0cmluZyBoYXMgVVRGLTE2IGNvZGUgdW5pdHMgdGhhdCBkbyBub3QgZml0IGluIDggYml0cyIpO31IRUFQVThbcHRyK2ldPWNoYXJDb2RlO319ZWxzZSB7Zm9yKHZhciBpPTA7aTxsZW5ndGg7KytpKXtIRUFQVThbcHRyK2ldPXZhbHVlW2ldO319fWlmKGRlc3RydWN0b3JzIT09bnVsbCl7ZGVzdHJ1Y3RvcnMucHVzaChfZnJlZSxiYXNlKTt9cmV0dXJuIGJhc2V9LGFyZ1BhY2tBZHZhbmNlOkdlbmVyaWNXaXJlVHlwZVNpemUscmVhZFZhbHVlRnJvbVBvaW50ZXI6cmVhZFBvaW50ZXIsZGVzdHJ1Y3RvckZ1bmN0aW9uKHB0cil7X2ZyZWUocHRyKTt9fSk7fTt2YXIgVVRGMTZEZWNvZGVyPXR5cGVvZiBUZXh0RGVjb2RlciE9InVuZGVmaW5lZCI/bmV3IFRleHREZWNvZGVyKCJ1dGYtMTZsZSIpOnVuZGVmaW5lZDt2YXIgVVRGMTZUb1N0cmluZz0ocHRyLG1heEJ5dGVzVG9SZWFkKT0+e3ZhciBlbmRQdHI9cHRyO3ZhciBpZHg9ZW5kUHRyPj4xO3ZhciBtYXhJZHg9aWR4K21heEJ5dGVzVG9SZWFkLzI7d2hpbGUoIShpZHg+PW1heElkeCkmJkhFQVBVMTZbaWR4XSkrK2lkeDtlbmRQdHI9aWR4PDwxO2lmKGVuZFB0ci1wdHI+MzImJlVURjE2RGVjb2RlcilyZXR1cm4gVVRGMTZEZWNvZGVyLmRlY29kZShIRUFQVTguc3ViYXJyYXkocHRyLGVuZFB0cikpO3ZhciBzdHI9IiI7Zm9yKHZhciBpPTA7IShpPj1tYXhCeXRlc1RvUmVhZC8yKTsrK2kpe3ZhciBjb2RlVW5pdD1IRUFQMTZbcHRyK2kqMj4+MV07aWYoY29kZVVuaXQ9PTApYnJlYWs7c3RyKz1TdHJpbmcuZnJvbUNoYXJDb2RlKGNvZGVVbml0KTt9cmV0dXJuIHN0cn07dmFyIHN0cmluZ1RvVVRGMTY9KHN0cixvdXRQdHIsbWF4Qnl0ZXNUb1dyaXRlKT0+e21heEJ5dGVzVG9Xcml0ZT8/PTIxNDc0ODM2NDc7aWYobWF4Qnl0ZXNUb1dyaXRlPDIpcmV0dXJuIDA7bWF4Qnl0ZXNUb1dyaXRlLT0yO3ZhciBzdGFydFB0cj1vdXRQdHI7dmFyIG51bUNoYXJzVG9Xcml0ZT1tYXhCeXRlc1RvV3JpdGU8c3RyLmxlbmd0aCoyP21heEJ5dGVzVG9Xcml0ZS8yOnN0ci5sZW5ndGg7Zm9yKHZhciBpPTA7aTxudW1DaGFyc1RvV3JpdGU7KytpKXt2YXIgY29kZVVuaXQ9c3RyLmNoYXJDb2RlQXQoaSk7SEVBUDE2W291dFB0cj4+MV09Y29kZVVuaXQ7b3V0UHRyKz0yO31IRUFQMTZbb3V0UHRyPj4xXT0wO3JldHVybiBvdXRQdHItc3RhcnRQdHJ9O3ZhciBsZW5ndGhCeXRlc1VURjE2PXN0cj0+c3RyLmxlbmd0aCoyO3ZhciBVVEYzMlRvU3RyaW5nPShwdHIsbWF4Qnl0ZXNUb1JlYWQpPT57dmFyIGk9MDt2YXIgc3RyPSIiO3doaWxlKCEoaT49bWF4Qnl0ZXNUb1JlYWQvNCkpe3ZhciB1dGYzMj1IRUFQMzJbcHRyK2kqND4+Ml07aWYodXRmMzI9PTApYnJlYWs7KytpO2lmKHV0ZjMyPj02NTUzNil7dmFyIGNoPXV0ZjMyLTY1NTM2O3N0cis9U3RyaW5nLmZyb21DaGFyQ29kZSg1NTI5NnxjaD4+MTAsNTYzMjB8Y2gmMTAyMyk7fWVsc2Uge3N0cis9U3RyaW5nLmZyb21DaGFyQ29kZSh1dGYzMik7fX1yZXR1cm4gc3RyfTt2YXIgc3RyaW5nVG9VVEYzMj0oc3RyLG91dFB0cixtYXhCeXRlc1RvV3JpdGUpPT57bWF4Qnl0ZXNUb1dyaXRlPz89MjE0NzQ4MzY0NztpZihtYXhCeXRlc1RvV3JpdGU8NClyZXR1cm4gMDt2YXIgc3RhcnRQdHI9b3V0UHRyO3ZhciBlbmRQdHI9c3RhcnRQdHIrbWF4Qnl0ZXNUb1dyaXRlLTQ7Zm9yKHZhciBpPTA7aTxzdHIubGVuZ3RoOysraSl7dmFyIGNvZGVVbml0PXN0ci5jaGFyQ29kZUF0KGkpO2lmKGNvZGVVbml0Pj01NTI5NiYmY29kZVVuaXQ8PTU3MzQzKXt2YXIgdHJhaWxTdXJyb2dhdGU9c3RyLmNoYXJDb2RlQXQoKytpKTtjb2RlVW5pdD02NTUzNisoKGNvZGVVbml0JjEwMjMpPDwxMCl8dHJhaWxTdXJyb2dhdGUmMTAyMzt9SEVBUDMyW291dFB0cj4+Ml09Y29kZVVuaXQ7b3V0UHRyKz00O2lmKG91dFB0cis0PmVuZFB0cilicmVha31IRUFQMzJbb3V0UHRyPj4yXT0wO3JldHVybiBvdXRQdHItc3RhcnRQdHJ9O3ZhciBsZW5ndGhCeXRlc1VURjMyPXN0cj0+e3ZhciBsZW49MDtmb3IodmFyIGk9MDtpPHN0ci5sZW5ndGg7KytpKXt2YXIgY29kZVVuaXQ9c3RyLmNoYXJDb2RlQXQoaSk7aWYoY29kZVVuaXQ+PTU1Mjk2JiZjb2RlVW5pdDw9NTczNDMpKytpO2xlbis9NDt9cmV0dXJuIGxlbn07dmFyIF9fZW1iaW5kX3JlZ2lzdGVyX3N0ZF93c3RyaW5nPShyYXdUeXBlLGNoYXJTaXplLG5hbWUpPT57bmFtZT1yZWFkTGF0aW4xU3RyaW5nKG5hbWUpO3ZhciBkZWNvZGVTdHJpbmcsZW5jb2RlU3RyaW5nLHJlYWRDaGFyQXQsbGVuZ3RoQnl0ZXNVVEY7aWYoY2hhclNpemU9PT0yKXtkZWNvZGVTdHJpbmc9VVRGMTZUb1N0cmluZztlbmNvZGVTdHJpbmc9c3RyaW5nVG9VVEYxNjtsZW5ndGhCeXRlc1VURj1sZW5ndGhCeXRlc1VURjE2O3JlYWRDaGFyQXQ9cG9pbnRlcj0+SEVBUFUxNltwb2ludGVyPj4xXTt9ZWxzZSBpZihjaGFyU2l6ZT09PTQpe2RlY29kZVN0cmluZz1VVEYzMlRvU3RyaW5nO2VuY29kZVN0cmluZz1zdHJpbmdUb1VURjMyO2xlbmd0aEJ5dGVzVVRGPWxlbmd0aEJ5dGVzVVRGMzI7cmVhZENoYXJBdD1wb2ludGVyPT5IRUFQVTMyW3BvaW50ZXI+PjJdO31yZWdpc3RlclR5cGUocmF3VHlwZSx7bmFtZSxmcm9tV2lyZVR5cGU6dmFsdWU9Pnt2YXIgbGVuZ3RoPUhFQVBVMzJbdmFsdWU+PjJdO3ZhciBzdHI7dmFyIGRlY29kZVN0YXJ0UHRyPXZhbHVlKzQ7Zm9yKHZhciBpPTA7aTw9bGVuZ3RoOysraSl7dmFyIGN1cnJlbnRCeXRlUHRyPXZhbHVlKzQraSpjaGFyU2l6ZTtpZihpPT1sZW5ndGh8fHJlYWRDaGFyQXQoY3VycmVudEJ5dGVQdHIpPT0wKXt2YXIgbWF4UmVhZEJ5dGVzPWN1cnJlbnRCeXRlUHRyLWRlY29kZVN0YXJ0UHRyO3ZhciBzdHJpbmdTZWdtZW50PWRlY29kZVN0cmluZyhkZWNvZGVTdGFydFB0cixtYXhSZWFkQnl0ZXMpO2lmKHN0cj09PXVuZGVmaW5lZCl7c3RyPXN0cmluZ1NlZ21lbnQ7fWVsc2Uge3N0cis9U3RyaW5nLmZyb21DaGFyQ29kZSgwKTtzdHIrPXN0cmluZ1NlZ21lbnQ7fWRlY29kZVN0YXJ0UHRyPWN1cnJlbnRCeXRlUHRyK2NoYXJTaXplO319X2ZyZWUodmFsdWUpO3JldHVybiBzdHJ9LHRvV2lyZVR5cGU6KGRlc3RydWN0b3JzLHZhbHVlKT0+e2lmKCEodHlwZW9mIHZhbHVlPT0ic3RyaW5nIikpe3Rocm93QmluZGluZ0Vycm9yKGBDYW5ub3QgcGFzcyBub24tc3RyaW5nIHRvIEMrKyBzdHJpbmcgdHlwZSAke25hbWV9YCk7fXZhciBsZW5ndGg9bGVuZ3RoQnl0ZXNVVEYodmFsdWUpO3ZhciBwdHI9X21hbGxvYyg0K2xlbmd0aCtjaGFyU2l6ZSk7SEVBUFUzMltwdHI+PjJdPWxlbmd0aC9jaGFyU2l6ZTtlbmNvZGVTdHJpbmcodmFsdWUscHRyKzQsbGVuZ3RoK2NoYXJTaXplKTtpZihkZXN0cnVjdG9ycyE9PW51bGwpe2Rlc3RydWN0b3JzLnB1c2goX2ZyZWUscHRyKTt9cmV0dXJuIHB0cn0sYXJnUGFja0FkdmFuY2U6R2VuZXJpY1dpcmVUeXBlU2l6ZSxyZWFkVmFsdWVGcm9tUG9pbnRlcjpyZWFkUG9pbnRlcixkZXN0cnVjdG9yRnVuY3Rpb24ocHRyKXtfZnJlZShwdHIpO319KTt9O3ZhciBfX2VtYmluZF9yZWdpc3Rlcl92b2lkPShyYXdUeXBlLG5hbWUpPT57bmFtZT1yZWFkTGF0aW4xU3RyaW5nKG5hbWUpO3JlZ2lzdGVyVHlwZShyYXdUeXBlLHtpc1ZvaWQ6dHJ1ZSxuYW1lLGFyZ1BhY2tBZHZhbmNlOjAsZnJvbVdpcmVUeXBlOigpPT51bmRlZmluZWQsdG9XaXJlVHlwZTooZGVzdHJ1Y3RvcnMsbyk9PnVuZGVmaW5lZH0pO307dmFyIGdldEhlYXBNYXg9KCk9PjIxNDc0ODM2NDg7dmFyIGFsaWduTWVtb3J5PShzaXplLGFsaWdubWVudCk9Pk1hdGguY2VpbChzaXplL2FsaWdubWVudCkqYWxpZ25tZW50O3ZhciBncm93TWVtb3J5PXNpemU9Pnt2YXIgYj13YXNtTWVtb3J5LmJ1ZmZlcjt2YXIgcGFnZXM9KHNpemUtYi5ieXRlTGVuZ3RoKzY1NTM1KS82NTUzNnwwO3RyeXt3YXNtTWVtb3J5Lmdyb3cocGFnZXMpO3VwZGF0ZU1lbW9yeVZpZXdzKCk7cmV0dXJuIDF9Y2F0Y2goZSl7fX07dmFyIF9lbXNjcmlwdGVuX3Jlc2l6ZV9oZWFwPXJlcXVlc3RlZFNpemU9Pnt2YXIgb2xkU2l6ZT1IRUFQVTgubGVuZ3RoO3JlcXVlc3RlZFNpemU+Pj49MDt2YXIgbWF4SGVhcFNpemU9Z2V0SGVhcE1heCgpO2lmKHJlcXVlc3RlZFNpemU+bWF4SGVhcFNpemUpe3JldHVybiBmYWxzZX1mb3IodmFyIGN1dERvd249MTtjdXREb3duPD00O2N1dERvd24qPTIpe3ZhciBvdmVyR3Jvd25IZWFwU2l6ZT1vbGRTaXplKigxKy4yL2N1dERvd24pO292ZXJHcm93bkhlYXBTaXplPU1hdGgubWluKG92ZXJHcm93bkhlYXBTaXplLHJlcXVlc3RlZFNpemUrMTAwNjYzMjk2KTt2YXIgbmV3U2l6ZT1NYXRoLm1pbihtYXhIZWFwU2l6ZSxhbGlnbk1lbW9yeShNYXRoLm1heChyZXF1ZXN0ZWRTaXplLG92ZXJHcm93bkhlYXBTaXplKSw2NTUzNikpO3ZhciByZXBsYWNlbWVudD1ncm93TWVtb3J5KG5ld1NpemUpO2lmKHJlcGxhY2VtZW50KXtyZXR1cm4gdHJ1ZX19cmV0dXJuIGZhbHNlfTtmb3IodmFyIGJhc2U2NFJldmVyc2VMb29rdXA9bmV3IFVpbnQ4QXJyYXkoMTIzKSxpPTI1O2k+PTA7LS1pKXtiYXNlNjRSZXZlcnNlTG9va3VwWzQ4K2ldPTUyK2k7YmFzZTY0UmV2ZXJzZUxvb2t1cFs2NStpXT1pO2Jhc2U2NFJldmVyc2VMb29rdXBbOTcraV09MjYraTt9YmFzZTY0UmV2ZXJzZUxvb2t1cFs0M109NjI7YmFzZTY0UmV2ZXJzZUxvb2t1cFs0N109NjM7ZW1iaW5kX2luaXRfY2hhckNvZGVzKCk7QmluZGluZ0Vycm9yPU1vZHVsZVsiQmluZGluZ0Vycm9yIl09Y2xhc3MgQmluZGluZ0Vycm9yIGV4dGVuZHMgRXJyb3J7Y29uc3RydWN0b3IobWVzc2FnZSl7c3VwZXIobWVzc2FnZSk7dGhpcy5uYW1lPSJCaW5kaW5nRXJyb3IiO319O01vZHVsZVsiSW50ZXJuYWxFcnJvciJdPWNsYXNzIEludGVybmFsRXJyb3IgZXh0ZW5kcyBFcnJvcntjb25zdHJ1Y3RvcihtZXNzYWdlKXtzdXBlcihtZXNzYWdlKTt0aGlzLm5hbWU9IkludGVybmFsRXJyb3IiO319O2luaXRfZW12YWwoKTt2YXIgd2FzbUltcG9ydHM9e2o6X19hYm9ydF9qcyxlOl9fZW1iaW5kX3JlZ2lzdGVyX2JpZ2ludCxoOl9fZW1iaW5kX3JlZ2lzdGVyX2Jvb2wsZjpfX2VtYmluZF9yZWdpc3Rlcl9lbXZhbCxkOl9fZW1iaW5kX3JlZ2lzdGVyX2Zsb2F0LGI6X19lbWJpbmRfcmVnaXN0ZXJfaW50ZWdlcixhOl9fZW1iaW5kX3JlZ2lzdGVyX21lbW9yeV92aWV3LGc6X19lbWJpbmRfcmVnaXN0ZXJfc3RkX3N0cmluZyxjOl9fZW1iaW5kX3JlZ2lzdGVyX3N0ZF93c3RyaW5nLGk6X19lbWJpbmRfcmVnaXN0ZXJfdm9pZCxrOl9lbXNjcmlwdGVuX3Jlc2l6ZV9oZWFwfTt2YXIgd2FzbUV4cG9ydHM9YXdhaXQgY3JlYXRlV2FzbSgpO3dhc21FeHBvcnRzWyJtIl07TW9kdWxlWyJfcGFjayJdPXdhc21FeHBvcnRzWyJuIl07dmFyIF9tYWxsb2M9TW9kdWxlWyJfbWFsbG9jIl09d2FzbUV4cG9ydHNbIm8iXTt2YXIgX2ZyZWU9TW9kdWxlWyJfZnJlZSJdPXdhc21FeHBvcnRzWyJwIl07ZnVuY3Rpb24gcnVuKCl7aWYocnVuRGVwZW5kZW5jaWVzPjApe2RlcGVuZGVuY2llc0Z1bGZpbGxlZD1ydW47cmV0dXJufXByZVJ1bigpO2lmKHJ1bkRlcGVuZGVuY2llcz4wKXtkZXBlbmRlbmNpZXNGdWxmaWxsZWQ9cnVuO3JldHVybn1mdW5jdGlvbiBkb1J1bigpe01vZHVsZVsiY2FsbGVkUnVuIl09dHJ1ZTtpZihBQk9SVClyZXR1cm47aW5pdFJ1bnRpbWUoKTtyZWFkeVByb21pc2VSZXNvbHZlKE1vZHVsZSk7TW9kdWxlWyJvblJ1bnRpbWVJbml0aWFsaXplZCJdPy4oKTtwb3N0UnVuKCk7fWlmKE1vZHVsZVsic2V0U3RhdHVzIl0pe01vZHVsZVsic2V0U3RhdHVzIl0oIlJ1bm5pbmcuLi4iKTtzZXRUaW1lb3V0KCgpPT57c2V0VGltZW91dCgoKT0+TW9kdWxlWyJzZXRTdGF0dXMiXSgiIiksMSk7ZG9SdW4oKTt9LDEpO31lbHNlIHtkb1J1bigpO319aWYoTW9kdWxlWyJwcmVJbml0Il0pe2lmKHR5cGVvZiBNb2R1bGVbInByZUluaXQiXT09ImZ1bmN0aW9uIilNb2R1bGVbInByZUluaXQiXT1bTW9kdWxlWyJwcmVJbml0Il1dO3doaWxlKE1vZHVsZVsicHJlSW5pdCJdLmxlbmd0aD4wKXtNb2R1bGVbInByZUluaXQiXS5wb3AoKSgpO319cnVuKCk7bW9kdWxlUnRuPXJlYWR5UHJvbWlzZTsNCg0KDQogICAgcmV0dXJuIG1vZHVsZVJ0bjsNCiAgfQ0KICApOw0KICB9KSgpOwoKICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueQogIGxldCB3YXNtTW9kdWxlOwogIGFzeW5jIGZ1bmN0aW9uIGluaXRXYXNtKCkgewogICAgICB3YXNtTW9kdWxlID0gYXdhaXQgbG9hZFdhc20oKTsKICB9CiAgbGV0IGFsbG9jYXRlZFZlcnRleENvdW50ID0gMDsKICBjb25zdCB1cGRhdGVRdWV1ZSA9IG5ldyBBcnJheSgpOwogIGxldCBydW5uaW5nID0gZmFsc2U7CiAgbGV0IGxvYWRpbmcgPSBmYWxzZTsKICBsZXQgcG9zaXRpb25zUHRyOwogIGxldCByb3RhdGlvbnNQdHI7CiAgbGV0IHNjYWxlc1B0cjsKICBsZXQgY29sb3JzUHRyOwogIGxldCBzZWxlY3Rpb25QdHI7CiAgbGV0IGRhdGFQdHI7CiAgbGV0IHdvcmxkUG9zaXRpb25zUHRyOwogIGxldCB3b3JsZFJvdGF0aW9uc1B0cjsKICBsZXQgd29ybGRTY2FsZXNQdHI7CiAgY29uc3QgcGFjayA9IGFzeW5jIChzcGxhdCkgPT4gewogICAgICB3aGlsZSAobG9hZGluZykgewogICAgICAgICAgYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgMCkpOwogICAgICB9CiAgICAgIGlmICghd2FzbU1vZHVsZSkgewogICAgICAgICAgbG9hZGluZyA9IHRydWU7CiAgICAgICAgICBhd2FpdCBpbml0V2FzbSgpOwogICAgICAgICAgbG9hZGluZyA9IGZhbHNlOwogICAgICB9CiAgICAgIGNvbnN0IHRhcmdldEFsbG9jYXRlZFZlcnRleENvdW50ID0gTWF0aC5wb3coMiwgTWF0aC5jZWlsKE1hdGgubG9nMihzcGxhdC52ZXJ0ZXhDb3VudCkpKTsKICAgICAgaWYgKHRhcmdldEFsbG9jYXRlZFZlcnRleENvdW50ID4gYWxsb2NhdGVkVmVydGV4Q291bnQpIHsKICAgICAgICAgIGlmIChhbGxvY2F0ZWRWZXJ0ZXhDb3VudCA+IDApIHsKICAgICAgICAgICAgICB3YXNtTW9kdWxlLl9mcmVlKHBvc2l0aW9uc1B0cik7CiAgICAgICAgICAgICAgd2FzbU1vZHVsZS5fZnJlZShyb3RhdGlvbnNQdHIpOwogICAgICAgICAgICAgIHdhc21Nb2R1bGUuX2ZyZWUoc2NhbGVzUHRyKTsKICAgICAgICAgICAgICB3YXNtTW9kdWxlLl9mcmVlKGNvbG9yc1B0cik7CiAgICAgICAgICAgICAgd2FzbU1vZHVsZS5fZnJlZShzZWxlY3Rpb25QdHIpOwogICAgICAgICAgICAgIHdhc21Nb2R1bGUuX2ZyZWUoZGF0YVB0cik7CiAgICAgICAgICAgICAgd2FzbU1vZHVsZS5fZnJlZSh3b3JsZFBvc2l0aW9uc1B0cik7CiAgICAgICAgICAgICAgd2FzbU1vZHVsZS5fZnJlZSh3b3JsZFJvdGF0aW9uc1B0cik7CiAgICAgICAgICAgICAgd2FzbU1vZHVsZS5fZnJlZSh3b3JsZFNjYWxlc1B0cik7CiAgICAgICAgICB9CiAgICAgICAgICBhbGxvY2F0ZWRWZXJ0ZXhDb3VudCA9IHRhcmdldEFsbG9jYXRlZFZlcnRleENvdW50OwogICAgICAgICAgcG9zaXRpb25zUHRyID0gd2FzbU1vZHVsZS5fbWFsbG9jKDMgKiBhbGxvY2F0ZWRWZXJ0ZXhDb3VudCAqIDQpOwogICAgICAgICAgcm90YXRpb25zUHRyID0gd2FzbU1vZHVsZS5fbWFsbG9jKDQgKiBhbGxvY2F0ZWRWZXJ0ZXhDb3VudCAqIDQpOwogICAgICAgICAgc2NhbGVzUHRyID0gd2FzbU1vZHVsZS5fbWFsbG9jKDMgKiBhbGxvY2F0ZWRWZXJ0ZXhDb3VudCAqIDQpOwogICAgICAgICAgY29sb3JzUHRyID0gd2FzbU1vZHVsZS5fbWFsbG9jKDQgKiBhbGxvY2F0ZWRWZXJ0ZXhDb3VudCk7CiAgICAgICAgICBzZWxlY3Rpb25QdHIgPSB3YXNtTW9kdWxlLl9tYWxsb2MoYWxsb2NhdGVkVmVydGV4Q291bnQpOwogICAgICAgICAgZGF0YVB0ciA9IHdhc21Nb2R1bGUuX21hbGxvYyg4ICogYWxsb2NhdGVkVmVydGV4Q291bnQgKiA0KTsKICAgICAgICAgIHdvcmxkUG9zaXRpb25zUHRyID0gd2FzbU1vZHVsZS5fbWFsbG9jKDMgKiBhbGxvY2F0ZWRWZXJ0ZXhDb3VudCAqIDQpOwogICAgICAgICAgd29ybGRSb3RhdGlvbnNQdHIgPSB3YXNtTW9kdWxlLl9tYWxsb2MoNCAqIGFsbG9jYXRlZFZlcnRleENvdW50ICogNCk7CiAgICAgICAgICB3b3JsZFNjYWxlc1B0ciA9IHdhc21Nb2R1bGUuX21hbGxvYygzICogYWxsb2NhdGVkVmVydGV4Q291bnQgKiA0KTsKICAgICAgfQogICAgICB3YXNtTW9kdWxlLkhFQVBGMzIuc2V0KHNwbGF0LnBvc2l0aW9ucywgcG9zaXRpb25zUHRyIC8gNCk7CiAgICAgIHdhc21Nb2R1bGUuSEVBUEYzMi5zZXQoc3BsYXQucm90YXRpb25zLCByb3RhdGlvbnNQdHIgLyA0KTsKICAgICAgd2FzbU1vZHVsZS5IRUFQRjMyLnNldChzcGxhdC5zY2FsZXMsIHNjYWxlc1B0ciAvIDQpOwogICAgICB3YXNtTW9kdWxlLkhFQVBVOC5zZXQoc3BsYXQuY29sb3JzLCBjb2xvcnNQdHIpOwogICAgICB3YXNtTW9kdWxlLkhFQVBVOC5zZXQoc3BsYXQuc2VsZWN0aW9uLCBzZWxlY3Rpb25QdHIpOwogICAgICB3YXNtTW9kdWxlLl9wYWNrKHNwbGF0LnNlbGVjdGVkLCBzcGxhdC52ZXJ0ZXhDb3VudCwgcG9zaXRpb25zUHRyLCByb3RhdGlvbnNQdHIsIHNjYWxlc1B0ciwgY29sb3JzUHRyLCBzZWxlY3Rpb25QdHIsIGRhdGFQdHIsIHdvcmxkUG9zaXRpb25zUHRyLCB3b3JsZFJvdGF0aW9uc1B0ciwgd29ybGRTY2FsZXNQdHIpOwogICAgICBjb25zdCBvdXREYXRhID0gbmV3IFVpbnQzMkFycmF5KHdhc21Nb2R1bGUuSEVBUFUzMi5idWZmZXIsIGRhdGFQdHIsIHNwbGF0LnZlcnRleENvdW50ICogOCk7CiAgICAgIGNvbnN0IGRldGFjaGVkRGF0YSA9IG5ldyBVaW50MzJBcnJheShvdXREYXRhLnNsaWNlKCkuYnVmZmVyKTsKICAgICAgY29uc3Qgd29ybGRQb3NpdGlvbnMgPSBuZXcgRmxvYXQzMkFycmF5KHdhc21Nb2R1bGUuSEVBUEYzMi5idWZmZXIsIHdvcmxkUG9zaXRpb25zUHRyLCBzcGxhdC52ZXJ0ZXhDb3VudCAqIDMpOwogICAgICBjb25zdCBkZXRhY2hlZFdvcmxkUG9zaXRpb25zID0gbmV3IEZsb2F0MzJBcnJheSh3b3JsZFBvc2l0aW9ucy5zbGljZSgpLmJ1ZmZlcik7CiAgICAgIGNvbnN0IHdvcmxkUm90YXRpb25zID0gbmV3IEZsb2F0MzJBcnJheSh3YXNtTW9kdWxlLkhFQVBGMzIuYnVmZmVyLCB3b3JsZFJvdGF0aW9uc1B0ciwgc3BsYXQudmVydGV4Q291bnQgKiA0KTsKICAgICAgY29uc3QgZGV0YWNoZWRXb3JsZFJvdGF0aW9ucyA9IG5ldyBGbG9hdDMyQXJyYXkod29ybGRSb3RhdGlvbnMuc2xpY2UoKS5idWZmZXIpOwogICAgICBjb25zdCB3b3JsZFNjYWxlcyA9IG5ldyBGbG9hdDMyQXJyYXkod2FzbU1vZHVsZS5IRUFQRjMyLmJ1ZmZlciwgd29ybGRTY2FsZXNQdHIsIHNwbGF0LnZlcnRleENvdW50ICogMyk7CiAgICAgIGNvbnN0IGRldGFjaGVkV29ybGRTY2FsZXMgPSBuZXcgRmxvYXQzMkFycmF5KHdvcmxkU2NhbGVzLnNsaWNlKCkuYnVmZmVyKTsKICAgICAgY29uc3QgcmVzcG9uc2UgPSB7CiAgICAgICAgICBkYXRhOiBkZXRhY2hlZERhdGEsCiAgICAgICAgICB3b3JsZFBvc2l0aW9uczogZGV0YWNoZWRXb3JsZFBvc2l0aW9ucywKICAgICAgICAgIHdvcmxkUm90YXRpb25zOiBkZXRhY2hlZFdvcmxkUm90YXRpb25zLAogICAgICAgICAgd29ybGRTY2FsZXM6IGRldGFjaGVkV29ybGRTY2FsZXMsCiAgICAgICAgICBvZmZzZXQ6IHNwbGF0Lm9mZnNldCwKICAgICAgICAgIHZlcnRleENvdW50OiBzcGxhdC52ZXJ0ZXhDb3VudCwKICAgICAgICAgIHBvc2l0aW9uczogc3BsYXQucG9zaXRpb25zLmJ1ZmZlciwKICAgICAgICAgIHJvdGF0aW9uczogc3BsYXQucm90YXRpb25zLmJ1ZmZlciwKICAgICAgICAgIHNjYWxlczogc3BsYXQuc2NhbGVzLmJ1ZmZlciwKICAgICAgICAgIGNvbG9yczogc3BsYXQuY29sb3JzLmJ1ZmZlciwKICAgICAgICAgIHNlbGVjdGlvbjogc3BsYXQuc2VsZWN0aW9uLmJ1ZmZlciwKICAgICAgfTsKICAgICAgc2VsZi5wb3N0TWVzc2FnZSh7IHJlc3BvbnNlOiByZXNwb25zZSB9LCBbCiAgICAgICAgICByZXNwb25zZS5kYXRhLmJ1ZmZlciwKICAgICAgICAgIHJlc3BvbnNlLndvcmxkUG9zaXRpb25zLmJ1ZmZlciwKICAgICAgICAgIHJlc3BvbnNlLndvcmxkUm90YXRpb25zLmJ1ZmZlciwKICAgICAgICAgIHJlc3BvbnNlLndvcmxkU2NhbGVzLmJ1ZmZlciwKICAgICAgICAgIHJlc3BvbnNlLnBvc2l0aW9ucywKICAgICAgICAgIHJlc3BvbnNlLnJvdGF0aW9ucywKICAgICAgICAgIHJlc3BvbnNlLnNjYWxlcywKICAgICAgICAgIHJlc3BvbnNlLmNvbG9ycywKICAgICAgICAgIHJlc3BvbnNlLnNlbGVjdGlvbiwKICAgICAgXSk7CiAgICAgIHJ1bm5pbmcgPSBmYWxzZTsKICB9OwogIGNvbnN0IHBhY2tUaHJvdHRsZWQgPSAoKSA9PiB7CiAgICAgIGlmICh1cGRhdGVRdWV1ZS5sZW5ndGggPT09IDApCiAgICAgICAgICByZXR1cm47CiAgICAgIGlmICghcnVubmluZykgewogICAgICAgICAgcnVubmluZyA9IHRydWU7CiAgICAgICAgICBjb25zdCBzcGxhdCA9IHVwZGF0ZVF1ZXVlLnNoaWZ0KCk7CiAgICAgICAgICBwYWNrKHNwbGF0KTsKICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gewogICAgICAgICAgICAgIHJ1bm5pbmcgPSBmYWxzZTsKICAgICAgICAgICAgICBwYWNrVGhyb3R0bGVkKCk7CiAgICAgICAgICB9LCAwKTsKICAgICAgfQogIH07CiAgc2VsZi5vbm1lc3NhZ2UgPSAoZSkgPT4gewogICAgICBpZiAoZS5kYXRhLnNwbGF0KSB7CiAgICAgICAgICBjb25zdCBzcGxhdCA9IGUuZGF0YS5zcGxhdDsKICAgICAgICAgIGZvciAoY29uc3QgW2luZGV4LCBleGlzdGluZ10gb2YgdXBkYXRlUXVldWUuZW50cmllcygpKSB7CiAgICAgICAgICAgICAgaWYgKGV4aXN0aW5nLm9mZnNldCA9PT0gc3BsYXQub2Zmc2V0KSB7CiAgICAgICAgICAgICAgICAgIHVwZGF0ZVF1ZXVlW2luZGV4XSA9IHNwbGF0OwogICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgdXBkYXRlUXVldWUucHVzaChzcGxhdCk7CiAgICAgICAgICBwYWNrVGhyb3R0bGVkKCk7CiAgICAgIH0KICB9OwoKfSkoKTsKCg==",null,!1),X=async function(t={}){var F,U,l,n=t,Q=new Promise(((t,l)=>{F=t,U=l})),e=Object.assign({},n),d="";d=(d=self.location.href).startsWith("blob:")?"":d.slice(0,d.replace(/[?#].*/,"").lastIndexOf("/")+1),l=t=>{var F=new XMLHttpRequest;return F.open("GET",t,!1),F.responseType="arraybuffer",F.send(null),new Uint8Array(F.response)},n.print||console.log.bind(console);var A=n.printErr||console.error.bind(console);Object.assign(n,e),e=null,n.arguments&&n.arguments,n.thisProgram&&n.thisProgram;var B,a,i,V,Z,R,c,s,o,r,h,W=n.wasmBinary,I=!1;function m(){var t=B.buffer;n.HEAP8=a=new Int8Array(t),n.HEAP16=V=new Int16Array(t),n.HEAPU8=i=new Uint8Array(t),n.HEAPU16=Z=new Uint16Array(t),n.HEAP32=R=new Int32Array(t),n.HEAPU32=c=new Uint32Array(t),n.HEAPF32=s=new Float32Array(t),n.HEAPF64=h=new Float64Array(t),n.HEAP64=o=new BigInt64Array(t),n.HEAPU64=r=new BigUint64Array(t)}var b=0,J=null;function g(t){n.onAbort?.(t),A(t="Aborted("+t+")"),I=!0,t+=". Build with -sASSERTIONS for more info.";var F=new WebAssembly.RuntimeError(t);throw U(F),F}var C="data:application/octet-stream;base64,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AkcNASABQQE6ADYPCyAAKAIIIgAgASACIAMgBCAAKAIAKAIYEQIACwsxACAAIAEoAghBABALBEAgASACIAMQFA8LIAAoAggiACABIAIgAyAAKAIAKAIcEQAACxgAIAAgASgCCEEAEAsEQCABIAIgAxAUCwulBQEGfyMAQdAAayIEJAACQAJ/QQEgACABQQAQCw0AGkEAIAFFDQAaIwBBEGsiBiQAIAYgASgCACIDQQhrKAIAIgU2AgwgBiABIAVqNgIEIAYgA0EEaygCADYCCCAGKAIIIgNByAhBABALIQUgBigCBCEHAkAgBQRAIAYoAgwhASMAQUBqIgMkACADQUBrJABBACAHIAEbIQMMAQsgAyEFIwBBQGoiAyQAIAEgB04EQCADQgA3AhwgA0IANwIkIANCADcCLCADQgA3AhQgA0EANgIQIANByAg2AgwgAyAFNgIEIANBADYCPCADQoGAgICAgICAATcCNCADIAE2AgggBSADQQRqIAcgB0EBQQAgBSgCACgCFBEDACABQQAgAygCHBshCAsgA0FAayQAIAgiAw0AIwBBQGoiAyQAIANBADYCECADQZgINgIMIAMgATYCCCADQcgINgIEQQAhASADQRRqQQBBJ/wLACADQQA2AjwgA0EBOgA7IAUgA0EEaiAHQQFBACAFKAIAKAIYEQIAAkACQAJAIAMoAigOAgABAgsgAygCGEEAIAMoAiRBAUYbQQAgAygCIEEBRhtBACADKAIsQQFGGyEBDAELIAMoAhxBAUcEQCADKAIsDQEgAygCIEEBRw0BIAMoAiRBAUcNAQsgAygCFCEBCyADQUBrJAAgASEDCyAGQRBqJABBACADRQ0AGiACKAIAIgFFDQEgBEEYakEAQTj8CwAgBEEBOgBLIARBfzYCICAEIAA2AhwgBCADNgIUIARBATYCRCADIARBFGogAUEBIAMoAgAoAhwRAAAgBCgCLCIAQQFGBEAgAiAEKAIkNgIACyAAQQFGCyAEQdAAaiQADwsgBEHPCjYCCCAEQeUDNgIEIARBuQk2AgAQCQALCgAgACABQQAQCwsEACAACwvbEQIAQYAIC8oRBAkAAAgEAABTdDl0eXBlX2luZm8AAAAALAkAACQEAAAABAAATjEwX19jeHhhYml2MTE2X19zaGltX3R5cGVfaW5mb0UAAAAALAkAAFQEAAAYBAAATjEwX19jeHhhYml2MTE3X19jbGFzc190eXBlX2luZm9FAHVuc2lnbmVkIHNob3J0AHVuc2lnbmVkIGludABmbG9hdAB1aW50NjRfdAAlczolZDogJXMAdW5zaWduZWQgY2hhcgAvZW1zZGsvZW1zY3JpcHRlbi9zeXN0ZW0vbGliL2xpYmN4eGFiaS9zcmMvcHJpdmF0ZV90eXBlaW5mby5jcHAAYm9vbAB1bnNpZ25lZCBsb25nAHN0ZDo6d3N0cmluZwBzdGQ6OnN0cmluZwBzdGQ6OnUxNnN0cmluZwBzdGQ6OnUzMnN0cmluZwBkb3VibGUAdm9pZABjYXRjaGluZyBhIGNsYXNzIHdpdGhvdXQgYW4gb2JqZWN0PwBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzxzaG9ydD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8dW5zaWduZWQgc2hvcnQ+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PGludD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8dW5zaWduZWQgaW50PgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzxmbG9hdD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8dWludDhfdD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8aW50OF90PgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzx1aW50MTZfdD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8aW50MTZfdD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8dWludDY0X3Q+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PGludDY0X3Q+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PHVpbnQzMl90PgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzxpbnQzMl90PgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzxjaGFyPgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzx1bnNpZ25lZCBjaGFyPgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzxzaWduZWQgY2hhcj4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8bG9uZz4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8dW5zaWduZWQgbG9uZz4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8ZG91YmxlPgAAAAAAAAAAFAgAAAEAAAACAAAAAwAAAAQAAAAFAAAALAkAACAIAAAYBAAATjEwX19jeHhhYml2MTIzX19mdW5kYW1lbnRhbF90eXBlX2luZm9FAAAIAABQCAAAdgAAAAAIAABcCAAAYgAAAAAIAABoCAAAYwAAAAAIAAB0CAAAaAAAAAAIAACACAAAYQAAAAAIAACMCAAAcwAAAAAIAACYCAAAdAAAAAAIAACkCAAAaQAAAAAIAACwCAAAagAAAAAIAAC8CAAAbAAAAAAIAADICAAAbQAAAAAIAADUCAAAeAAAAAAIAADgCAAAeQAAAAAIAADsCAAAZgAAAAAIAAD4CAAAZAAAAAAAAABIBAAAAQAAAAYAAAADAAAABAAAAAcAAAAIAAAACQAAAAoAAAAAAAAATAkAAAEAAAALAAAAAwAAAAQAAAAHAAAADAAAAA0AAAAOAAAALAkAAFgJAABIBAAATjEwX19jeHhhYml2MTIwX19zaV9jbGFzc190eXBlX2luZm9FAAAAAAQJAACICQAATlN0M19fMjEyYmFzaWNfc3RyaW5nSWNOU18xMWNoYXJfdHJhaXRzSWNFRU5TXzlhbGxvY2F0b3JJY0VFRUUAAAQJAADQCQAATlN0M19fMjEyYmFzaWNfc3RyaW5nSXdOU18xMWNoYXJfdHJhaXRzSXdFRU5TXzlhbGxvY2F0b3JJd0VFRUUAAAQJAAAYCgAATlN0M19fMjEyYmFzaWNfc3RyaW5nSURzTlNfMTFjaGFyX3RyYWl0c0lEc0VFTlNfOWFsbG9jYXRvcklEc0VFRUUAAAAECQAAZAoAAE5TdDNfXzIxMmJhc2ljX3N0cmluZ0lEaU5TXzExY2hhcl90cmFpdHNJRGlFRU5TXzlhbGxvY2F0b3JJRGlFRUVFAAAABAkAALAKAABOMTBlbXNjcmlwdGVuM3ZhbEUAAAQJAADMCgAATjEwZW1zY3JpcHRlbjExbWVtb3J5X3ZpZXdJY0VFAAAECQAA9AoAAE4xMGVtc2NyaXB0ZW4xMW1lbW9yeV92aWV3SWFFRQAABAkAABwLAABOMTBlbXNjcmlwdGVuMTFtZW1vcnlfdmlld0loRUUAAAQJAABECwAATjEwZW1zY3JpcHRlbjExbWVtb3J5X3ZpZXdJc0VFAAAECQAAbAsAAE4xMGVtc2NyaXB0ZW4xMW1lbW9yeV92aWV3SXRFRQAABAkAAJQLAABOMTBlbXNjcmlwdGVuMTFtZW1vcnlfdmlld0lpRUUAAAQJAAC8CwAATjEwZW1zY3JpcHRlbjExbWVtb3J5X3ZpZXdJakVFAAAECQAA5AsAAE4xMGVtc2NyaXB0ZW4xMW1lbW9yeV92aWV3SWxFRQAABAkAAAwMAABOMTBlbXNjcmlwdGVuMTFtZW1vcnlfdmlld0ltRUUAAAQJAAA0DAAATjEwZW1zY3JpcHRlbjExbWVtb3J5X3ZpZXdJeEVFAAAECQAAXAwAAE4xMGVtc2NyaXB0ZW4xMW1lbW9yeV92aWV3SXlFRQAABAkAAIQMAABOMTBlbXNjcmlwdGVuMTFtZW1vcnlfdmlld0lmRUUAAAQJAACsDAAATjEwZW1zY3JpcHRlbjExbWVtb3J5X3ZpZXdJZEVFAEHMGQsD0A4B";async function N(t){return function(t){if(t==C&&W)return new Uint8Array(W);var F=T(t);if(F)return F;if(l)return l(t);throw"both async and sync fetching of the wasm failed"}(t)}async function G(t,F,U){return async function(t,F){try{var U=await N(t);return await WebAssembly.instantiate(U,F)}catch(t){A(`failed to asynchronously prepare wasm: ${t}`),g(t)}}(F,U)}var X=t=>{for(;t.length>0;)t.shift()(n)},E=[],p=t=>E.unshift(t),y=[],S=t=>y.unshift(t);n.noExitRuntime;var k,u,Y="data:application/octet-stream;base64,",T=t=>{if((t=>t.startsWith(Y))(t))return(t=>{for(var F,U,l=0,n=0,Q=t.length,e=new Uint8Array((3*Q>>2)-("="==t[Q-2])-("="==t[Q-1]));l>4,e[n+1]=F<<4|U>>2,e[n+2]=U<<6|Bt[t.charCodeAt(l+3)];return e})(t.slice(Y.length))},x=t=>{for(var F="",U=t;i[U];)F+=k[i[U++]];return F},H={},D={},f=t=>{throw new u(t)};function w(t,F,U={}){return function(t,F,U={}){var l=F.name;if(t||f(`type "${l}" must have a positive integer typeid pointer`),D.hasOwnProperty(t)){if(U.ignoreDuplicateRegistrations)return;f(`Cannot register type '${l}' twice`)}if(D[t]=F,H.hasOwnProperty(t)){var n=H[t];delete H[t],n.forEach((t=>t()))}}(t,F,U)}var v=(t,F,U)=>{switch(F){case 1:return U?t=>a[t]:t=>i[t];case 2:return U?t=>V[t>>1]:t=>Z[t>>1];case 4:return U?t=>R[t>>2]:t=>c[t>>2];case 8:return U?t=>o[t>>3]:t=>r[t>>3];default:throw new TypeError(`invalid integer width (${F}): ${t}`)}},z=8,M=[],j=[],K=()=>j.length/2-5-M.length,O=t=>(t||f("Cannot use deleted val. handle = "+t),j[t]),L=t=>{switch(t){case void 0:return 2;case null:return 4;case!0:return 6;case!1:return 8;default:{const F=M.pop()||j.length;return j[F]=t,j[F+1]=1,F}}};function P(t){return this.fromWireType(c[t>>2])}for(var _={name:"emscripten::val",fromWireType:t=>{var F=O(t);return(t=>{t>9&&0==--j[t+1]&&(j[t]=void 0,M.push(t))})(t),F},toWireType:(t,F)=>L(F),argPackAdvance:z,readValueFromPointer:P,destructorFunction:null},q=(t,F)=>{switch(F){case 4:return function(t){return this.fromWireType(s[t>>2])};case 8:return function(t){return this.fromWireType(h[t>>3])};default:throw new TypeError(`invalid float width (${F}): ${t}`)}},$="undefined"!=typeof TextDecoder?new TextDecoder:void 0,tt=(t,F)=>t?((t,F=0,U=NaN)=>{for(var l=F+U,n=F;t[n]&&!(n>=l);)++n;if(n-F>16&&t.buffer&&$)return $.decode(t.subarray(F,n));for(var Q="";F>10,56320|1023&B)}}else Q+=String.fromCharCode((31&e)<<6|d)}else Q+=String.fromCharCode(e)}return Q})(i,t,F):"",Ft="undefined"!=typeof TextDecoder?new TextDecoder("utf-16le"):void 0,Ut=(t,F)=>{for(var U=t,l=U>>1,n=l+F/2;!(l>=n)&&Z[l];)++l;if((U=l<<1)-t>32&&Ft)return Ft.decode(i.subarray(t,U));for(var Q="",e=0;!(e>=F/2);++e){var d=V[t+2*e>>1];if(0==d)break;Q+=String.fromCharCode(d)}return Q},lt=(t,F,U)=>{if(U??=2147483647,U<2)return 0;for(var l=F,n=(U-=2)<2*t.length?U/2:t.length,Q=0;Q>1]=e,F+=2}return V[F>>1]=0,F-l},nt=t=>2*t.length,Qt=(t,F)=>{for(var U=0,l="";!(U>=F/4);){var n=R[t+4*U>>2];if(0==n)break;if(++U,n>=65536){var Q=n-65536;l+=String.fromCharCode(55296|Q>>10,56320|1023&Q)}else l+=String.fromCharCode(n)}return l},et=(t,F,U)=>{if(U??=2147483647,U<4)return 0;for(var l=F,n=l+U-4,Q=0;Q=55296&&e<=57343&&(e=65536+((1023&e)<<10)|1023&t.charCodeAt(++Q)),R[F>>2]=e,(F+=4)+4>n)break}return R[F>>2]=0,F-l},dt=t=>{for(var F=0,U=0;U=55296&&l<=57343&&++U,F+=4}return F},At=t=>{var F=(t-B.buffer.byteLength+65535)/65536|0;try{return B.grow(F),m(),1}catch(t){}},Bt=new Uint8Array(123),at=25;at>=0;--at)Bt[48+at]=52+at,Bt[65+at]=at,Bt[97+at]=26+at;Bt[43]=62,Bt[47]=63,(()=>{for(var t=new Array(256),F=0;F<256;++F)t[F]=String.fromCharCode(F);k=t})(),u=n.BindingError=class extends Error{constructor(t){super(t),this.name="BindingError"}},n.InternalError=class extends Error{constructor(t){super(t),this.name="InternalError"}},j.push(0,1,void 0,1,null,1,!0,1,!1,1),n.count_emval_handles=K;var it={j:()=>g(""),e:(t,F,U,l,n)=>{var Q=-1!=(F=x(F)).indexOf("u");w(t,{name:F,fromWireType:t=>t,toWireType:function(t,F){if("bigint"!=typeof F&&"number"!=typeof F)throw new TypeError(`Cannot convert "${(t=>{if(null===t)return"null";var F=typeof t;return"object"===F||"array"===F||"function"===F?t.toString():""+t})(F)}" to ${this.name}`);return"number"==typeof F&&(F=BigInt(F)),F},argPackAdvance:z,readValueFromPointer:v(F,U,!Q),destructorFunction:null})},h:(t,F,U,l)=>{w(t,{name:F=x(F),fromWireType:function(t){return!!t},toWireType:function(t,F){return F?U:l},argPackAdvance:z,readValueFromPointer:function(t){return this.fromWireType(i[t])},destructorFunction:null})},f:t=>w(t,_),d:(t,F,U)=>{w(t,{name:F=x(F),fromWireType:t=>t,toWireType:(t,F)=>F,argPackAdvance:z,readValueFromPointer:q(F,U),destructorFunction:null})},b:(t,F,U,l,n)=>{F=x(F);var Q=t=>t;if(0===l){var e=32-8*U;Q=t=>t<>>e}var d=F.includes("unsigned");w(t,{name:F,fromWireType:Q,toWireType:d?function(t,F){return this.name,F>>>0}:function(t,F){return this.name,F},argPackAdvance:z,readValueFromPointer:v(F,U,0!==l),destructorFunction:null})},a:(t,F,U)=>{var l=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array,BigInt64Array,BigUint64Array][F];function n(t){var F=c[t>>2],U=c[t+4>>2];return new l(a.buffer,U,F)}w(t,{name:U=x(U),fromWireType:n,argPackAdvance:z,readValueFromPointer:n},{ignoreDuplicateRegistrations:!0})},g:(t,F)=>{w(t,{name:F=x(F),fromWireType(t){for(var F,U=c[t>>2],l=t+4,n=l,Q=0;Q<=U;++Q){var e=l+Q;if(Q==U||0==i[e]){var d=tt(n,e-n);void 0===F?F=d:(F+=String.fromCharCode(0),F+=d),n=e+1}}return Rt(t),F},toWireType(t,F){var U;F instanceof ArrayBuffer&&(F=new Uint8Array(F));var l="string"==typeof F;l||F instanceof Uint8Array||F instanceof Uint8ClampedArray||F instanceof Int8Array||f("Cannot pass non-string to std::string"),U=l?(t=>{for(var F=0,U=0;U=55296&&l<=57343?(F+=4,++U):F+=3}return F})(F):F.length;var n=Zt(4+U+1),Q=n+4;if(c[n>>2]=U,l)((t,F,U,l)=>{if(!(l>0))return 0;for(var n=U+l-1,Q=0;Q=55296&&e<=57343&&(e=65536+((1023&e)<<10)|1023&t.charCodeAt(++Q)),e<=127){if(U>=n)break;F[U++]=e}else if(e<=2047){if(U+1>=n)break;F[U++]=192|e>>6,F[U++]=128|63&e}else if(e<=65535){if(U+2>=n)break;F[U++]=224|e>>12,F[U++]=128|e>>6&63,F[U++]=128|63&e}else{if(U+3>=n)break;F[U++]=240|e>>18,F[U++]=128|e>>12&63,F[U++]=128|e>>6&63,F[U++]=128|63&e}}F[U]=0})(F,i,Q,U+1);else if(l)for(var e=0;e255&&(Rt(n),f("String has UTF-16 code units that do not fit in 8 bits")),i[Q+e]=d}else for(e=0;e{var l,n,Q,e;U=x(U),2===F?(l=Ut,n=lt,e=nt,Q=t=>Z[t>>1]):4===F&&(l=Qt,n=et,e=dt,Q=t=>c[t>>2]),w(t,{name:U,fromWireType:t=>{for(var U,n=c[t>>2],e=t+4,d=0;d<=n;++d){var A=t+4+d*F;if(d==n||0==Q(A)){var B=l(e,A-e);void 0===U?U=B:(U+=String.fromCharCode(0),U+=B),e=A+F}}return Rt(t),U},toWireType:(t,l)=>{"string"!=typeof l&&f(`Cannot pass non-string to C++ string type ${U}`);var Q=e(l),d=Zt(4+Q+F);return c[d>>2]=Q/F,n(l,d+4,Q+F),null!==t&&t.push(Rt,d),d},argPackAdvance:z,readValueFromPointer:P,destructorFunction(t){Rt(t)}})},i:(t,F)=>{w(t,{isVoid:!0,name:F=x(F),argPackAdvance:0,fromWireType:()=>{},toWireType:(t,F)=>{}})},k:t=>{var F,U,l=i.length,n=2147483648;if((t>>>=0)>n)return!1;for(var Q=1;Q<=4;Q*=2){var e=l*(1+.2/Q);e=Math.min(e,t+100663296);var d=Math.min(n,(F=Math.max(t,e),U=65536,Math.ceil(F/U)*U));if(At(d))return!0}return!1}},Vt=await async function(){function t(t,F){return Vt=t.exports,B=Vt.l,m(),function(t){if(b--,n.monitorRunDependencies?.(b),0==b&&J){var F=J;J=null,F()}}(),Vt}b++,n.monitorRunDependencies?.(b);var F={a:it};if(n.instantiateWasm)return new Promise(((U,l)=>{n.instantiateWasm(F,((F,l)=>{t(F),U(F.exports)}))}));try{var l=function(F){return t(F.instance)}(await G(0,C,F));return l}catch(t){return U(t),Promise.reject(t)}}();Vt.m,n._pack=Vt.n;var Zt=n._malloc=Vt.o,Rt=n._free=Vt.p;if(n.preInit)for("function"==typeof n.preInit&&(n.preInit=[n.preInit]);n.preInit.length>0;)n.preInit.pop()();return function t(){function U(){n.calledRun=!0,I||(Vt.m(),F(n),n.onRuntimeInitialized?.(),function(){if(n.postRun)for("function"==typeof n.postRun&&(n.postRun=[n.postRun]);n.postRun.length;)p(n.postRun.shift());X(E)}())}b>0?J=t:(function(){if(n.preRun)for("function"==typeof n.preRun&&(n.preRun=[n.preRun]);n.preRun.length;)S(n.preRun.shift());X(y)}(),b>0?J=t:n.setStatus?(n.setStatus("Running..."),setTimeout((()=>{setTimeout((()=>n.setStatus("")),1),U()}),1)):U())}(),Q};class E{constructor(t){this.dataChanged=!1,this.transformsChanged=!1,this.colorTransformsChanged=!1,this._updating=new Set,this._dirty=new Set;let F=0,U=0;this._splatIndices=new Map,this._offsets=new Map;const n=new Map;for(const l of t.objects)l instanceof Z&&(this._splatIndices.set(l,U),this._offsets.set(l,F),n.set(F,l),F+=l.data.vertexCount,U++);this._vertexCount=F,this._width=2048,this._height=Math.ceil(2*this.vertexCount/this.width),this._data=new Uint32Array(this.width*this.height*4),this._transformsWidth=5,this._transformsHeight=n.size,this._transforms=new Float32Array(this._transformsWidth*this._transformsHeight*4),this._transformIndicesWidth=1024,this._transformIndicesHeight=Math.ceil(this.vertexCount/this._transformIndicesWidth),this._transformIndices=new Uint32Array(this._transformIndicesWidth*this._transformIndicesHeight),this._colorTransformsWidth=4,this._colorTransformsHeight=64,this._colorTransforms=new Float32Array(this._colorTransformsWidth*this._colorTransformsHeight*4),this._colorTransforms.fill(0),this._colorTransforms[0]=1,this._colorTransforms[5]=1,this._colorTransforms[10]=1,this._colorTransforms[15]=1,this._colorTransformIndicesWidth=1024,this._colorTransformIndicesHeight=Math.ceil(this.vertexCount/this._colorTransformIndicesWidth),this._colorTransformIndices=new Uint32Array(this._colorTransformIndicesWidth*this._colorTransformIndicesHeight),this.colorTransformIndices.fill(0),this._positions=new Float32Array(3*this.vertexCount),this._rotations=new Float32Array(4*this.vertexCount),this._scales=new Float32Array(3*this.vertexCount),this._worker=new G;const Q=t=>{const F=this._splatIndices.get(t);this._transforms.set(t.transform.buffer,20*F),this._transforms[20*F+16]=t.selected?1:0,t.positionChanged=!1,t.rotationChanged=!1,t.scaleChanged=!1,t.selectedChanged=!1,this.transformsChanged=!0},e=()=>{let t=!1;for(const F of this._splatIndices.keys())if(F.colorTransformChanged){t=!0;break}if(!t)return;const F=[new l];this._colorTransformIndices.fill(0);let U=1;for(const t of this._splatIndices.keys()){const l=this._offsets.get(t);for(const l of t.colorTransforms)F.includes(l)||(F.push(l),U++);for(const F of t.colorTransformsMap.keys()){const n=t.colorTransformsMap.get(F);this._colorTransformIndices[F+l]=n+U-1}t.colorTransformChanged=!1}for(let t=0;t{if(t.data.response){const F=t.data.response,U=n.get(F.offset);Q(U),e();const l=this._splatIndices.get(U);for(let t=0;t{if(!d)return void async function(){for(;!d;)await new Promise((t=>setTimeout(t,0)))}().then((()=>{A(t)}));Q(t);const F=d._malloc(3*t.data.vertexCount*4),U=d._malloc(4*t.data.vertexCount*4),l=d._malloc(3*t.data.vertexCount*4),n=d._malloc(4*t.data.vertexCount),e=d._malloc(t.data.vertexCount),B=d._malloc(8*t.data.vertexCount*4),a=d._malloc(3*t.data.vertexCount*4),i=d._malloc(4*t.data.vertexCount*4),V=d._malloc(3*t.data.vertexCount*4);d.HEAPF32.set(t.data.positions,F/4),d.HEAPF32.set(t.data.rotations,U/4),d.HEAPF32.set(t.data.scales,l/4),d.HEAPU8.set(t.data.colors,n),d.HEAPU8.set(t.data.selection,e),d._pack(t.selected,t.data.vertexCount,F,U,l,n,e,B,a,i,V);const Z=new Uint32Array(d.HEAPU32.buffer,B,8*t.data.vertexCount),R=new Float32Array(d.HEAPF32.buffer,a,3*t.data.vertexCount),c=new Float32Array(d.HEAPF32.buffer,i,4*t.data.vertexCount),s=new Float32Array(d.HEAPF32.buffer,V,3*t.data.vertexCount),o=this._splatIndices.get(t),r=this._offsets.get(t);for(let F=0;F{if((t.positionChanged||t.rotationChanged||t.scaleChanged||t.selectedChanged)&&Q(t),t.colorTransformChanged&&e(),!t.data.changed||t.data.detached)return;const F={position:new Float32Array(t.position.flat()),rotation:new Float32Array(t.rotation.flat()),scale:new Float32Array(t.scale.flat()),selected:t.selected,vertexCount:t.data.vertexCount,positions:t.data.positions,rotations:t.data.rotations,scales:t.data.scales,colors:t.data.colors,selection:t.data.selection,offset:this._offsets.get(t)};this._worker.postMessage({splat:F},[F.position.buffer,F.rotation.buffer,F.scale.buffer,F.positions.buffer,F.rotations.buffer,F.scales.buffer,F.colors.buffer,F.selection.buffer]),this._updating.add(t),t.data.detached=!0};this.getSplat=t=>{let F=null;for(const[U,l]of this._offsets){if(!(t>=l))break;F=U}return F},this.getLocalIndex=(t,F)=>F-this._offsets.get(t),this.markDirty=t=>{this._dirty.add(t)},this.rebuild=()=>{for(const t of this._dirty)B(t);this._dirty.clear()},this.dispose=()=>{this._worker.terminate()};for(const t of this._splatIndices.keys())A(t);e()}get offsets(){return this._offsets}get data(){return this._data}get width(){return this._width}get height(){return this._height}get transforms(){return this._transforms}get transformsWidth(){return this._transformsWidth}get transformsHeight(){return this._transformsHeight}get transformIndices(){return this._transformIndices}get transformIndicesWidth(){return this._transformIndicesWidth}get transformIndicesHeight(){return this._transformIndicesHeight}get colorTransforms(){return this._colorTransforms}get colorTransformsWidth(){return this._colorTransformsWidth}get colorTransformsHeight(){return this._colorTransformsHeight}get colorTransformIndices(){return this._colorTransformIndices}get colorTransformIndicesWidth(){return this._colorTransformIndicesWidth}get colorTransformIndicesHeight(){return this._colorTransformIndicesHeight}get positions(){return this._positions}get rotations(){return this._rotations}get scales(){return this._scales}get vertexCount(){return this._vertexCount}get needsRebuild(){return this._dirty.size>0}get updating(){return this._updating.size>0}}class p{constructor(t=0,F=0,U=0,l=255){this.r=t,this.g=F,this.b=U,this.a=l}flat(){return[this.r,this.g,this.b,this.a]}flatNorm(){return[this.r/255,this.g/255,this.b/255,this.a/255]}toHexString(){return"#"+this.flat().map((t=>t.toString(16).padStart(2,"0"))).join("")}toString(){return`[${this.flat().join(", ")}]`}}class y extends N{constructor(t,F){super(t,F),this._outlineThickness=10,this._outlineColor=new p(255,165,0,255),this._renderData=null,this._depthIndex=new Uint32Array,this._splatTexture=null,this._worker=null;const U=t.canvas,l=t.gl;let n,Q,e,d,A,B,a,i,V,R,c,s,o,r,h,W,I,m,b;this._resize=()=>{this._camera&&(this._camera.data.setSize(U.width,U.height),this._camera.update(),n=l.getUniformLocation(this.program,"projection"),l.uniformMatrix4fv(n,!1,this._camera.data.projectionMatrix.buffer),Q=l.getUniformLocation(this.program,"viewport"),l.uniform2fv(Q,new Float32Array([U.width,U.height])))};const J=()=>{this._worker=new C,this._worker.onmessage=t=>{if(t.data.depthIndex){const{depthIndex:F}=t.data;this._depthIndex=F,l.bindBuffer(l.ARRAY_BUFFER,b),l.bufferData(l.ARRAY_BUFFER,F,l.STATIC_DRAW)}}};this._initialize=()=>{if(this._scene&&this._camera){this._resize(),this._scene.addEventListener("objectAdded",g),this._scene.addEventListener("objectRemoved",N);for(const t of this._scene.objects)t instanceof Z&&t.addEventListener("objectChanged",G);this._renderData=new E(this._scene),e=l.getUniformLocation(this.program,"focal"),l.uniform2fv(e,new Float32Array([this._camera.data.fx,this._camera.data.fy])),d=l.getUniformLocation(this.program,"view"),l.uniformMatrix4fv(d,!1,this._camera.data.viewMatrix.buffer),R=l.getUniformLocation(this.program,"outlineThickness"),l.uniform1f(R,this.outlineThickness),c=l.getUniformLocation(this.program,"outlineColor"),l.uniform4fv(c,new Float32Array(this.outlineColor.flatNorm())),this._splatTexture=l.createTexture(),A=l.getUniformLocation(this.program,"u_texture"),l.uniform1i(A,0),r=l.createTexture(),B=l.getUniformLocation(this.program,"u_transforms"),l.uniform1i(B,1),h=l.createTexture(),a=l.getUniformLocation(this.program,"u_transformIndices"),l.uniform1i(a,2),W=l.createTexture(),i=l.getUniformLocation(this.program,"u_colorTransforms"),l.uniform1i(i,3),I=l.createTexture(),V=l.getUniformLocation(this.program,"u_colorTransformIndices"),l.uniform1i(V,4),m=l.createBuffer(),l.bindBuffer(l.ARRAY_BUFFER,m),l.bufferData(l.ARRAY_BUFFER,new Float32Array([-2,-2,2,-2,2,2,-2,2]),l.STATIC_DRAW),s=l.getAttribLocation(this.program,"position"),l.enableVertexAttribArray(s),l.vertexAttribPointer(s,2,l.FLOAT,!1,0,0),b=l.createBuffer(),o=l.getAttribLocation(this.program,"index"),l.enableVertexAttribArray(o),l.bindBuffer(l.ARRAY_BUFFER,b),J()}else console.error("Cannot render without scene and camera")};const g=t=>{const F=t;F.object instanceof Z&&F.object.addEventListener("objectChanged",G),X()},N=t=>{const F=t;F.object instanceof Z&&F.object.removeEventListener("objectChanged",G),X()},G=t=>{const F=t;F.object instanceof Z&&this._renderData&&this._renderData.markDirty(F.object)},X=()=>{var t,F;null===(t=this._renderData)||void 0===t||t.dispose(),this._renderData=new E(this._scene),null===(F=this._worker)||void 0===F||F.terminate(),J()};this._render=()=>{var t,F;if(this._scene&&this._camera&&this.renderData){if(this.renderData.needsRebuild&&this.renderData.rebuild(),this.renderData.dataChanged||this.renderData.transformsChanged||this.renderData.colorTransformsChanged){this.renderData.dataChanged&&(l.activeTexture(l.TEXTURE0),l.bindTexture(l.TEXTURE_2D,this.splatTexture),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_WRAP_S,l.CLAMP_TO_EDGE),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_WRAP_T,l.CLAMP_TO_EDGE),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_MIN_FILTER,l.NEAREST),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_MAG_FILTER,l.NEAREST),l.texImage2D(l.TEXTURE_2D,0,l.RGBA32UI,this.renderData.width,this.renderData.height,0,l.RGBA_INTEGER,l.UNSIGNED_INT,this.renderData.data)),this.renderData.transformsChanged&&(l.activeTexture(l.TEXTURE1),l.bindTexture(l.TEXTURE_2D,r),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_WRAP_S,l.CLAMP_TO_EDGE),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_WRAP_T,l.CLAMP_TO_EDGE),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_MIN_FILTER,l.NEAREST),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_MAG_FILTER,l.NEAREST),l.texImage2D(l.TEXTURE_2D,0,l.RGBA32F,this.renderData.transformsWidth,this.renderData.transformsHeight,0,l.RGBA,l.FLOAT,this.renderData.transforms),l.activeTexture(l.TEXTURE2),l.bindTexture(l.TEXTURE_2D,h),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_WRAP_S,l.CLAMP_TO_EDGE),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_WRAP_T,l.CLAMP_TO_EDGE),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_MIN_FILTER,l.NEAREST),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_MAG_FILTER,l.NEAREST),l.texImage2D(l.TEXTURE_2D,0,l.R32UI,this.renderData.transformIndicesWidth,this.renderData.transformIndicesHeight,0,l.RED_INTEGER,l.UNSIGNED_INT,this.renderData.transformIndices)),this.renderData.colorTransformsChanged&&(l.activeTexture(l.TEXTURE3),l.bindTexture(l.TEXTURE_2D,W),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_WRAP_S,l.CLAMP_TO_EDGE),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_WRAP_T,l.CLAMP_TO_EDGE),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_MIN_FILTER,l.NEAREST),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_MAG_FILTER,l.NEAREST),l.texImage2D(l.TEXTURE_2D,0,l.RGBA32F,this.renderData.colorTransformsWidth,this.renderData.colorTransformsHeight,0,l.RGBA,l.FLOAT,this.renderData.colorTransforms),l.activeTexture(l.TEXTURE4),l.bindTexture(l.TEXTURE_2D,I),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_WRAP_S,l.CLAMP_TO_EDGE),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_WRAP_T,l.CLAMP_TO_EDGE),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_MIN_FILTER,l.NEAREST),l.texParameteri(l.TEXTURE_2D,l.TEXTURE_MAG_FILTER,l.NEAREST),l.texImage2D(l.TEXTURE_2D,0,l.R32UI,this.renderData.colorTransformIndicesWidth,this.renderData.colorTransformIndicesHeight,0,l.RED_INTEGER,l.UNSIGNED_INT,this.renderData.colorTransformIndices));const F=new Float32Array(this.renderData.positions.slice().buffer),U=new Float32Array(this.renderData.transforms.slice().buffer),n=new Uint32Array(this.renderData.transformIndices.slice().buffer);null===(t=this._worker)||void 0===t||t.postMessage({sortData:{positions:F,transforms:U,transformIndices:n,vertexCount:this.renderData.vertexCount}},[F.buffer,U.buffer,n.buffer]),this.renderData.dataChanged=!1,this.renderData.transformsChanged=!1,this.renderData.colorTransformsChanged=!1}this._camera.update(),null===(F=this._worker)||void 0===F||F.postMessage({viewProj:this._camera.data.viewProj.buffer}),l.viewport(0,0,U.width,U.height),l.clearColor(0,0,0,0),l.clear(l.COLOR_BUFFER_BIT),l.disable(l.DEPTH_TEST),l.enable(l.BLEND),l.blendFuncSeparate(l.ONE_MINUS_DST_ALPHA,l.ONE,l.ONE_MINUS_DST_ALPHA,l.ONE),l.blendEquationSeparate(l.FUNC_ADD,l.FUNC_ADD),l.uniformMatrix4fv(n,!1,this._camera.data.projectionMatrix.buffer),l.uniformMatrix4fv(d,!1,this._camera.data.viewMatrix.buffer),l.bindBuffer(l.ARRAY_BUFFER,m),l.vertexAttribPointer(s,2,l.FLOAT,!1,0,0),l.bindBuffer(l.ARRAY_BUFFER,b),l.bufferData(l.ARRAY_BUFFER,this.depthIndex,l.STATIC_DRAW),l.vertexAttribIPointer(o,1,l.INT,0,0),l.vertexAttribDivisor(o,1),l.drawArraysInstanced(l.TRIANGLE_FAN,0,4,this.depthIndex.length)}else console.error("Cannot render without scene and camera")},this._dispose=()=>{var t;if(this._scene&&this._camera&&this.renderData){this._scene.removeEventListener("objectAdded",g),this._scene.removeEventListener("objectRemoved",N);for(const t of this._scene.objects)t instanceof Z&&t.removeEventListener("objectChanged",G);null===(t=this._worker)||void 0===t||t.terminate(),this.renderData.dispose(),l.deleteTexture(this.splatTexture),l.deleteTexture(r),l.deleteTexture(h),l.deleteBuffer(b),l.deleteBuffer(m)}else console.error("Cannot dispose without scene and camera")},this._setOutlineThickness=t=>{this._outlineThickness=t,this._initialized&&l.uniform1f(R,t)},this._setOutlineColor=t=>{this._outlineColor=t,this._initialized&&l.uniform4fv(c,new Float32Array(t.flatNorm()))}}get renderData(){return this._renderData}get depthIndex(){return this._depthIndex}get splatTexture(){return this._splatTexture}get outlineThickness(){return this._outlineThickness}set outlineThickness(t){this._setOutlineThickness(t)}get outlineColor(){return this._outlineColor}set outlineColor(t){this._setOutlineColor(t)}get worker(){return this._worker}_getVertexSource(){return"#version 300 es\nprecision highp float;\nprecision highp int;\n\nuniform highp usampler2D u_texture;\nuniform highp sampler2D u_transforms;\nuniform highp usampler2D u_transformIndices;\nuniform highp sampler2D u_colorTransforms;\nuniform highp usampler2D u_colorTransformIndices;\nuniform mat4 projection, view;\nuniform vec2 focal;\nuniform vec2 viewport;\n\nuniform bool useDepthFade;\nuniform float depthFade;\n\nin vec2 position;\nin int index;\n\nout vec4 vColor;\nout vec2 vPosition;\nout float vSize;\nout float vSelected;\n\nvoid main () {\n uvec4 cen = texelFetch(u_texture, ivec2((uint(index) & 0x3ffu) << 1, uint(index) >> 10), 0);\n float selected = float((cen.w >> 24) & 0xffu);\n\n uint transformIndex = texelFetch(u_transformIndices, ivec2(uint(index) & 0x3ffu, uint(index) >> 10), 0).x;\n mat4 transform = mat4(\n texelFetch(u_transforms, ivec2(0, transformIndex), 0),\n texelFetch(u_transforms, ivec2(1, transformIndex), 0),\n texelFetch(u_transforms, ivec2(2, transformIndex), 0),\n texelFetch(u_transforms, ivec2(3, transformIndex), 0)\n );\n\n if (selected < 0.5) {\n selected = texelFetch(u_transforms, ivec2(4, transformIndex), 0).x;\n }\n\n mat4 viewTransform = view * transform;\n\n vec4 cam = viewTransform * vec4(uintBitsToFloat(cen.xyz), 1);\n vec4 pos2d = projection * cam;\n\n float clip = 1.2 * pos2d.w;\n if (pos2d.z < -pos2d.w || pos2d.z > pos2d.w || pos2d.x < -clip || pos2d.x > clip || pos2d.y < -clip || pos2d.y > clip) {\n gl_Position = vec4(0.0, 0.0, 2.0, 1.0);\n return;\n }\n\n uvec4 cov = texelFetch(u_texture, ivec2(((uint(index) & 0x3ffu) << 1) | 1u, uint(index) >> 10), 0);\n vec2 u1 = unpackHalf2x16(cov.x), u2 = unpackHalf2x16(cov.y), u3 = unpackHalf2x16(cov.z);\n mat3 Vrk = mat3(u1.x, u1.y, u2.x, u1.y, u2.y, u3.x, u2.x, u3.x, u3.y);\n\n mat3 J = mat3(\n focal.x / cam.z, 0., -(focal.x * cam.x) / (cam.z * cam.z), \n 0., -focal.y / cam.z, (focal.y * cam.y) / (cam.z * cam.z), \n 0., 0., 0.\n );\n\n mat3 T = transpose(mat3(viewTransform)) * J;\n mat3 cov2d = transpose(T) * Vrk * T;\n\n //ref: https://github.com/graphdeco-inria/diff-gaussian-rasterization/blob/main/cuda_rasterizer/forward.cu#L110-L111\n cov2d[0][0] += 0.3;\n cov2d[1][1] += 0.3;\n\n float mid = (cov2d[0][0] + cov2d[1][1]) / 2.0;\n float radius = length(vec2((cov2d[0][0] - cov2d[1][1]) / 2.0, cov2d[0][1]));\n float lambda1 = mid + radius, lambda2 = mid - radius;\n\n if (lambda2 < 0.0) return;\n vec2 diagonalVector = normalize(vec2(cov2d[0][1], lambda1 - cov2d[0][0]));\n vec2 majorAxis = min(sqrt(2.0 * lambda1), 1024.0) * diagonalVector;\n vec2 minorAxis = min(sqrt(2.0 * lambda2), 1024.0) * vec2(diagonalVector.y, -diagonalVector.x);\n\n uint colorTransformIndex = texelFetch(u_colorTransformIndices, ivec2(uint(index) & 0x3ffu, uint(index) >> 10), 0).x;\n mat4 colorTransform = mat4(\n texelFetch(u_colorTransforms, ivec2(0, colorTransformIndex), 0),\n texelFetch(u_colorTransforms, ivec2(1, colorTransformIndex), 0),\n texelFetch(u_colorTransforms, ivec2(2, colorTransformIndex), 0),\n texelFetch(u_colorTransforms, ivec2(3, colorTransformIndex), 0)\n );\n\n vec4 color = vec4((cov.w) & 0xffu, (cov.w >> 8) & 0xffu, (cov.w >> 16) & 0xffu, (cov.w >> 24) & 0xffu) / 255.0;\n vColor = colorTransform * color;\n\n vPosition = position;\n vSize = length(majorAxis);\n vSelected = selected;\n\n float scalingFactor = 1.0;\n\n if (useDepthFade) {\n float depthNorm = (pos2d.z / pos2d.w + 1.0) / 2.0;\n float near = 0.1; float far = 100.0;\n float normalizedDepth = (2.0 * near) / (far + near - depthNorm * (far - near));\n float start = max(normalizedDepth - 0.1, 0.0);\n float end = min(normalizedDepth + 0.1, 1.0);\n scalingFactor = clamp((depthFade - start) / (end - start), 0.0, 1.0);\n }\n\n vec2 vCenter = vec2(pos2d) / pos2d.w;\n gl_Position = vec4(\n vCenter \n + position.x * majorAxis * scalingFactor / viewport\n + position.y * minorAxis * scalingFactor / viewport, 0.0, 1.0);\n}\n"}_getFragmentSource(){return"#version 300 es\nprecision highp float;\n\nuniform float outlineThickness;\nuniform vec4 outlineColor;\n\nin vec4 vColor;\nin vec2 vPosition;\nin float vSize;\nin float vSelected;\n\nout vec4 fragColor;\n\nvoid main () {\n float A = -dot(vPosition, vPosition);\n\n if (A < -4.0) discard;\n\n if (vSelected < 0.5) {\n float B = exp(A) * vColor.a;\n fragColor = vec4(B * vColor.rgb, B);\n return;\n }\n\n float outlineThreshold = -4.0 + (outlineThickness / vSize);\n\n if (A < outlineThreshold) {\n fragColor = outlineColor;\n } \n else {\n float B = exp(A) * vColor.a;\n fragColor = vec4(B * vColor.rgb, B);\n }\n}\n"}}class S{constructor(t=1){let F,U,l,n,Q=0,e=!1;this.initialize=t=>{if(!(t instanceof y))throw new Error("FadeInPass requires a RenderProgram");Q=t.started?1:0,e=!0,F=t,U=t.renderer.gl,l=U.getUniformLocation(F.program,"useDepthFade"),U.uniform1i(l,1),n=U.getUniformLocation(F.program,"depthFade"),U.uniform1f(n,Q)},this.render=()=>{var d;e&&!(null===(d=F.renderData)||void 0===d?void 0:d.updating)&&(U.useProgram(F.program),Q=Math.min(Q+.01*t,1),Q>=1&&(e=!1,U.uniform1i(l,0)),U.uniform1f(n,Q))}}dispose(){}}class k{constructor(t=null,F=null){this._backgroundColor=new p;const U=t||document.createElement("canvas");t||(U.style.display="block",U.style.boxSizing="border-box",U.style.width="100%",U.style.height="100%",U.style.margin="0",U.style.padding="0",document.body.appendChild(U)),U.style.background=this._backgroundColor.toHexString(),this._canvas=U,this._gl=U.getContext("webgl2",{antialias:!1});const l=F||[];F||l.push(new S),this._renderProgram=new y(this,l);const n=[this._renderProgram];this.resize=()=>{const t=U.clientWidth,F=U.clientHeight;U.width===t&&U.height===F||this.setSize(t,F)},this.setSize=(t,F)=>{U.width=t,U.height=F,this._gl.viewport(0,0,U.width,U.height);for(const t of n)t.resize()},this.render=(t,F)=>{for(const U of n)U.render(t,F)},this.dispose=()=>{for(const t of n)t.dispose()},this.addProgram=t=>{n.push(t)},this.removeProgram=t=>{const F=n.indexOf(t);if(F<0)throw new Error("Program not found");n.splice(F,1)},this.resize()}get canvas(){return this._canvas}get gl(){return this._gl}get renderProgram(){return this._renderProgram}get backgroundColor(){return this._backgroundColor}set backgroundColor(t){this._backgroundColor=t,this._canvas.style.background=t.toHexString()}}class u{constructor(U,l,n=.5,Q=.5,e=5,d=!0,B=new t,a,i,V){this.minAngle=-1/0,this.maxAngle=1/0,this.minAzimuth=-1/0,this.maxAzimuth=1/0,this.minZoom=.1,this.maxZoom=30,this.orbitSpeed=1,this.panSpeed=1,this.zoomSpeed=1,this.dampening=.12,this.setCameraTarget=()=>{};const Z=void 0!==a?a:n,R=void 0!==i?i:Q,c=void 0!==V?V:e;let s=B.clone(),o=s.clone(),r=Z,h=R,W=c,I=Z,m=R,b=c,J=!1,g=!1,C=0,N=0,G=0;const X={};this.setCameraTarget=F=>{const l=F.x-U.position.x,n=F.y-U.position.y,Q=F.z-U.position.z;W=Math.sqrt(l*l+n*n+Q*Q),h=Math.atan2(n,Math.sqrt(l*l+Q*Q)),r=-Math.atan2(l,Q),o=new t(F.x,F.y,F.z)};const E=()=>.1+.9*(W-this.minZoom)/(this.maxZoom-this.minZoom),p=t=>{X[t.code]=!0,"ArrowUp"===t.code&&(X.KeyW=!0),"ArrowDown"===t.code&&(X.KeyS=!0),"ArrowLeft"===t.code&&(X.KeyA=!0),"ArrowRight"===t.code&&(X.KeyD=!0)},y=t=>{X[t.code]=!1,"ArrowUp"===t.code&&(X.KeyW=!1),"ArrowDown"===t.code&&(X.KeyS=!1),"ArrowLeft"===t.code&&(X.KeyA=!1),"ArrowRight"===t.code&&(X.KeyD=!1)},S=t=>{f(t),J=!0,g=2===t.button,N=t.clientX,G=t.clientY,window.addEventListener("mouseup",k)},k=t=>{f(t),J=!1,g=!1,window.removeEventListener("mouseup",k)},u=F=>{if(f(F),!J||!U)return;const l=F.clientX-N,n=F.clientY-G;if(g){const F=E(),Q=-l*this.panSpeed*.01*F,e=-n*this.panSpeed*.01*F,d=A.RotationFromQuaternion(U.rotation).buffer,B=new t(d[0],d[3],d[6]),a=new t(d[1],d[4],d[7]);o=o.add(B.multiply(Q)),o=o.add(a.multiply(e))}else r-=l*this.orbitSpeed*.003,h+=n*this.orbitSpeed*.003,h=Math.min(Math.max(h,this.minAngle*Math.PI/180),this.maxAngle*Math.PI/180);N=F.clientX,G=F.clientY},Y=t=>{f(t);const F=E();W+=t.deltaY*this.zoomSpeed*.025*F,W=Math.min(Math.max(W,this.minZoom),this.maxZoom)},T=t=>{if(f(t),1===t.touches.length)J=!0,g=!1,N=t.touches[0].clientX,G=t.touches[0].clientY,C=0;else if(2===t.touches.length){J=!0,g=!0,N=(t.touches[0].clientX+t.touches[1].clientX)/2,G=(t.touches[0].clientY+t.touches[1].clientY)/2;const F=t.touches[0].clientX-t.touches[1].clientX,U=t.touches[0].clientY-t.touches[1].clientY;C=Math.sqrt(F*F+U*U)}},x=t=>{f(t),J=!1,g=!1},H=F=>{if(f(F),J&&U)if(g){const l=E(),n=F.touches[0].clientX-F.touches[1].clientX,Q=F.touches[0].clientY-F.touches[1].clientY,e=Math.sqrt(n*n+Q*Q);W+=(C-e)*this.zoomSpeed*.1*l,W=Math.min(Math.max(W,this.minZoom),this.maxZoom),C=e;const d=(F.touches[0].clientX+F.touches[1].clientX)/2,B=(F.touches[0].clientY+F.touches[1].clientY)/2,a=d-N,i=B-G,V=A.RotationFromQuaternion(U.rotation).buffer,Z=new t(V[0],V[3],V[6]),R=new t(V[1],V[4],V[7]);o=o.add(Z.multiply(-a*this.panSpeed*.025*l)),o=o.add(R.multiply(-i*this.panSpeed*.025*l)),N=d,G=B}else{const t=F.touches[0].clientX-N,U=F.touches[0].clientY-G;r-=t*this.orbitSpeed*.003,h+=U*this.orbitSpeed*.003,h=Math.min(Math.max(h,this.minAngle*Math.PI/180),this.maxAngle*Math.PI/180),N=F.touches[0].clientX,G=F.touches[0].clientY}},D=(t,F,U)=>(1-U)*t+U*F;this.update=()=>{I=D(I,r,this.dampening),m=D(m,h,this.dampening),b=D(b,W,this.dampening),s=s.lerp(o,this.dampening);const l=s.x+b*Math.sin(I)*Math.cos(m),n=s.y-b*Math.sin(m),Q=s.z-b*Math.cos(I)*Math.cos(m);U.position=new t(l,n,Q);const e=s.subtract(U.position).normalize(),d=Math.asin(-e.y),B=Math.atan2(e.x,e.z);U.rotation=F.FromEuler(new t(d,B,0));const a=.025,i=.01,V=A.RotationFromQuaternion(U.rotation).buffer,Z=new t(-V[2],-V[5],-V[8]),R=new t(V[0],V[3],V[6]);X.KeyS&&(o=o.add(Z.multiply(a))),X.KeyW&&(o=o.subtract(Z.multiply(a))),X.KeyA&&(o=o.subtract(R.multiply(a))),X.KeyD&&(o=o.add(R.multiply(a))),X.KeyE&&(r+=i),X.KeyQ&&(r-=i),r=Math.min(Math.max(r,this.minAzimuth*Math.PI/180),this.maxAzimuth*Math.PI/180),X.KeyR&&(h+=i),X.KeyF&&(h-=i),h=Math.min(Math.max(h,this.minAngle*Math.PI/180),this.maxAngle*Math.PI/180)};const f=t=>{t.preventDefault(),t.stopPropagation()};this.dispose=()=>{l.removeEventListener("dragenter",f),l.removeEventListener("dragover",f),l.removeEventListener("dragleave",f),l.removeEventListener("contextmenu",f),l.removeEventListener("mousedown",S),l.removeEventListener("mousemove",u),l.removeEventListener("wheel",Y),l.removeEventListener("touchstart",T),l.removeEventListener("touchend",x),l.removeEventListener("touchmove",H),d&&(window.removeEventListener("keydown",p),window.removeEventListener("keyup",y))},d&&(window.addEventListener("keydown",p),window.addEventListener("keyup",y)),l.addEventListener("dragenter",f),l.addEventListener("dragover",f),l.addEventListener("dragleave",f),l.addEventListener("contextmenu",f),l.addEventListener("mousedown",S),l.addEventListener("mousemove",u),l.addEventListener("wheel",Y),l.addEventListener("touchstart",T),l.addEventListener("touchend",x),l.addEventListener("touchmove",H),this.update()}}class Y{constructor(U,l){this.moveSpeed=1.5,this.lookSpeed=.7,this.dampening=.5;const n={};let Q=U.rotation.toEuler().x,e=U.rotation.toEuler().y,d=U.position,B=!1;const a=()=>{l.requestPointerLock()},i=()=>{B=document.pointerLockElement===l,B?l.addEventListener("mousemove",V):l.removeEventListener("mousemove",V)},V=t=>{const F=t.movementX,U=t.movementY;e+=F*this.lookSpeed*.001,Q-=U*this.lookSpeed*.001,Q=Math.max(-Math.PI/2,Math.min(Math.PI/2,Q))},Z=t=>{n[t.code]=!0,"ArrowUp"===t.code&&(n.KeyW=!0),"ArrowDown"===t.code&&(n.KeyS=!0),"ArrowLeft"===t.code&&(n.KeyA=!0),"ArrowRight"===t.code&&(n.KeyD=!0)},R=t=>{n[t.code]=!1,"ArrowUp"===t.code&&(n.KeyW=!1),"ArrowDown"===t.code&&(n.KeyS=!1),"ArrowLeft"===t.code&&(n.KeyA=!1),"ArrowRight"===t.code&&(n.KeyD=!1),"Escape"===t.code&&document.exitPointerLock()};this.update=()=>{const l=A.RotationFromQuaternion(U.rotation).buffer,B=new t(-l[2],-l[5],-l[8]),a=new t(l[0],l[3],l[6]);let i=new t(0,0,0);n.KeyS&&(i=i.add(B)),n.KeyW&&(i=i.subtract(B)),n.KeyA&&(i=i.subtract(a)),n.KeyD&&(i=i.add(a)),i=new t(i.x,0,i.z),i.magnitude()>0&&(i=i.normalize()),d=d.add(i.multiply(.01*this.moveSpeed)),U.position=U.position.add(d.subtract(U.position).multiply(this.dampening)),U.rotation=F.FromEuler(new t(Q,e,0))};const c=t=>{t.preventDefault(),t.stopPropagation()};this.dispose=()=>{l.removeEventListener("dragenter",c),l.removeEventListener("dragover",c),l.removeEventListener("dragleave",c),l.removeEventListener("contextmenu",c),l.removeEventListener("mousedown",a),document.removeEventListener("pointerlockchange",i),window.removeEventListener("keydown",Z),window.removeEventListener("keyup",R)},window.addEventListener("keydown",Z),window.addEventListener("keyup",R),l.addEventListener("dragenter",c),l.addEventListener("dragover",c),l.addEventListener("dragleave",c),l.addEventListener("contextmenu",c),l.addEventListener("mousedown",a),document.addEventListener("pointerlockchange",i),this.update()}}class T{constructor(t,F){this.normal=t,this.point=F}intersect(t,F){const U=this.normal.dot(F);if(Math.abs(U)<1e-4)return null;const l=this.normal.dot(this.point.subtract(t))/U;return l<0?null:t.add(F.multiply(l))}}class x{initialize(t){}render(){}dispose(){}}class H extends N{constructor(t,F=[]){super(t,F),this._renderData=null,this._depthIndex=new Uint32Array,this._splatTexture=null;const U=t.canvas,n=t.gl;let Q,e,d,A,B,a,i,V,Z,c,s;this._resize=()=>{this._camera&&(this._camera.data.setSize(U.width,U.height),this._camera.update(),e=n.getUniformLocation(this.program,"projection"),n.uniformMatrix4fv(e,!1,this._camera.data.projectionMatrix.buffer),d=n.getUniformLocation(this.program,"viewport"),n.uniform2fv(d,new Float32Array([U.width,U.height])))};const o=()=>{null!==t.renderProgram.worker?(Q=t.renderProgram.worker,Q.onmessage=t=>{if(t.data.depthIndex){const{depthIndex:F}=t.data;this._depthIndex=F,n.bindBuffer(n.ARRAY_BUFFER,s),n.bufferData(n.ARRAY_BUFFER,F,n.STATIC_DRAW)}}):console.error("Render program is not initialized. Cannot render without worker")};this._initialize=()=>{if(!this._scene||!this._camera)return void console.error("Cannot render without scene and camera");this._resize(),this._scene.addEventListener("objectAdded",r),this._scene.addEventListener("objectRemoved",h);for(const t of this._scene.objects)t instanceof R&&(null===this._renderData?(this._renderData=t.data,t.addEventListener("objectChanged",W)):console.warn("Multiple Splatv objects are not currently supported"));if(null===this._renderData)return void console.error("Cannot render without Splatv object");A=n.getUniformLocation(this.program,"focal"),n.uniform2fv(A,new Float32Array([this._camera.data.fx,this._camera.data.fy])),B=n.getUniformLocation(this.program,"view"),n.uniformMatrix4fv(B,!1,this._camera.data.viewMatrix.buffer),this._splatTexture=n.createTexture(),a=n.getUniformLocation(this.program,"u_texture"),n.uniform1i(a,0),i=n.getUniformLocation(this.program,"time"),n.uniform1f(i,Math.sin(Date.now()/1e3)/2+.5),c=n.createBuffer(),n.bindBuffer(n.ARRAY_BUFFER,c),n.bufferData(n.ARRAY_BUFFER,new Float32Array([-2,-2,2,-2,2,2,-2,2]),n.STATIC_DRAW),V=n.getAttribLocation(this.program,"position"),n.enableVertexAttribArray(V),n.vertexAttribPointer(V,2,n.FLOAT,!1,0,0),s=n.createBuffer(),Z=n.getAttribLocation(this.program,"index"),n.enableVertexAttribArray(Z),n.bindBuffer(n.ARRAY_BUFFER,s),o(),n.activeTexture(n.TEXTURE0),n.bindTexture(n.TEXTURE_2D,this._splatTexture),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_WRAP_S,n.CLAMP_TO_EDGE),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_WRAP_T,n.CLAMP_TO_EDGE),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_MIN_FILTER,n.NEAREST),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_MAG_FILTER,n.NEAREST),n.texImage2D(n.TEXTURE_2D,0,n.RGBA32UI,this._renderData.width,this._renderData.height,0,n.RGBA_INTEGER,n.UNSIGNED_INT,this._renderData.data);const t=this._renderData.positions,F=new Float32Array((new l).buffer),U=new Uint32Array(this._renderData.vertexCount);U.fill(0),Q.postMessage({sortData:{positions:t,transforms:F,transformIndices:U,vertexCount:this._renderData.vertexCount}},[t.buffer,F.buffer,U.buffer])};const r=t=>{const F=t;F.object instanceof R&&(null===this._renderData?(this._renderData=F.object.data,F.object.addEventListener("objectChanged",W)):console.warn("Splatv not supported by default RenderProgram. Use VideoRenderProgram instead.")),this.dispose()},h=t=>{const F=t;F.object instanceof R&&this._renderData===F.object.data&&(this._renderData=null,F.object.removeEventListener("objectChanged",W)),this.dispose()},W=t=>{const F=t;F.object instanceof R&&this._renderData===F.object.data&&this.dispose()};this._render=()=>{this._scene&&this._camera?this._renderData?(this._camera.update(),Q.postMessage({viewProj:this._camera.data.viewProj.buffer}),n.viewport(0,0,U.width,U.height),n.clearColor(0,0,0,0),n.clear(n.COLOR_BUFFER_BIT),n.disable(n.DEPTH_TEST),n.enable(n.BLEND),n.blendFuncSeparate(n.ONE_MINUS_DST_ALPHA,n.ONE,n.ONE_MINUS_DST_ALPHA,n.ONE),n.blendEquationSeparate(n.FUNC_ADD,n.FUNC_ADD),n.uniformMatrix4fv(e,!1,this._camera.data.projectionMatrix.buffer),n.uniformMatrix4fv(B,!1,this._camera.data.viewMatrix.buffer),n.uniform1f(i,Math.sin(Date.now()/1e3)/2+.5),n.bindBuffer(n.ARRAY_BUFFER,c),n.vertexAttribPointer(V,2,n.FLOAT,!1,0,0),n.bindBuffer(n.ARRAY_BUFFER,s),n.bufferData(n.ARRAY_BUFFER,this._depthIndex,n.STATIC_DRAW),n.vertexAttribIPointer(Z,1,n.INT,0,0),n.vertexAttribDivisor(Z,1),n.drawArraysInstanced(n.TRIANGLE_FAN,0,4,this._renderData.vertexCount)):console.warn("Cannot render without Splatv object"):console.error("Cannot render without scene and camera")},this._dispose=()=>{if(this._scene&&this._camera){this._scene.removeEventListener("objectAdded",r),this._scene.removeEventListener("objectRemoved",h);for(const t of this._scene.objects)t instanceof R&&this._renderData===t.data&&(this._renderData=null,t.removeEventListener("objectChanged",W));null==Q||Q.terminate(),n.deleteTexture(this._splatTexture),n.deleteBuffer(s),n.deleteBuffer(c)}else console.error("Cannot dispose without scene and camera")}}get renderData(){return this._renderData}_getVertexSource(){return"#version 300 es\nprecision highp float;\nprecision highp int;\n \nuniform highp usampler2D u_texture;\nuniform mat4 projection, view;\nuniform vec2 focal;\nuniform vec2 viewport;\nuniform float time;\n \nin vec2 position;\nin int index;\n \nout vec4 vColor;\nout vec2 vPosition;\n \nvoid main () {\n gl_Position = vec4(0.0, 0.0, 2.0, 1.0);\n\n uvec4 motion1 = texelFetch(u_texture, ivec2(((uint(index) & 0x3ffu) << 2) | 3u, uint(index) >> 10), 0);\n vec2 trbf = unpackHalf2x16(motion1.w);\n float dt = time - trbf.x;\n\n float topacity = exp(-1.0 * pow(dt / trbf.y, 2.0));\n if(topacity < 0.02) return;\n\n uvec4 motion0 = texelFetch(u_texture, ivec2(((uint(index) & 0x3ffu) << 2) | 2u, uint(index) >> 10), 0);\n uvec4 static0 = texelFetch(u_texture, ivec2(((uint(index) & 0x3ffu) << 2), uint(index) >> 10), 0);\n\n vec2 m0 = unpackHalf2x16(motion0.x), m1 = unpackHalf2x16(motion0.y), m2 = unpackHalf2x16(motion0.z), \n m3 = unpackHalf2x16(motion0.w), m4 = unpackHalf2x16(motion1.x); \n \n vec4 trot = vec4(unpackHalf2x16(motion1.y).xy, unpackHalf2x16(motion1.z).xy) * dt;\n vec3 tpos = (vec3(m0.xy, m1.x) * dt + vec3(m1.y, m2.xy) * dt*dt + vec3(m3.xy, m4.x) * dt*dt*dt);\n \n vec4 cam = view * vec4(uintBitsToFloat(static0.xyz) + tpos, 1);\n vec4 pos = projection * cam;\n \n float clip = 1.2 * pos.w;\n if (pos.z < -clip || pos.x < -clip || pos.x > clip || pos.y < -clip || pos.y > clip) return;\n uvec4 static1 = texelFetch(u_texture, ivec2(((uint(index) & 0x3ffu) << 2) | 1u, uint(index) >> 10), 0);\n\n vec4 rot = vec4(unpackHalf2x16(static0.w).xy, unpackHalf2x16(static1.x).xy) + trot;\n vec3 scale = vec3(unpackHalf2x16(static1.y).xy, unpackHalf2x16(static1.z).x);\n rot /= sqrt(dot(rot, rot));\n \n mat3 S = mat3(scale.x, 0.0, 0.0, 0.0, scale.y, 0.0, 0.0, 0.0, scale.z);\n mat3 R = mat3(\n 1.0 - 2.0 * (rot.z * rot.z + rot.w * rot.w), 2.0 * (rot.y * rot.z - rot.x * rot.w), 2.0 * (rot.y * rot.w + rot.x * rot.z),\n 2.0 * (rot.y * rot.z + rot.x * rot.w), 1.0 - 2.0 * (rot.y * rot.y + rot.w * rot.w), 2.0 * (rot.z * rot.w - rot.x * rot.y),\n 2.0 * (rot.y * rot.w - rot.x * rot.z), 2.0 * (rot.z * rot.w + rot.x * rot.y), 1.0 - 2.0 * (rot.y * rot.y + rot.z * rot.z));\n mat3 M = S * R;\n mat3 Vrk = 4.0 * transpose(M) * M;\n mat3 J = mat3(\n focal.x / cam.z, 0., -(focal.x * cam.x) / (cam.z * cam.z), \n 0., -focal.y / cam.z, (focal.y * cam.y) / (cam.z * cam.z), \n 0., 0., 0.\n );\n \n mat3 T = transpose(mat3(view)) * J;\n mat3 cov2d = transpose(T) * Vrk * T;\n \n float mid = (cov2d[0][0] + cov2d[1][1]) / 2.0;\n float radius = length(vec2((cov2d[0][0] - cov2d[1][1]) / 2.0, cov2d[0][1]));\n float lambda1 = mid + radius, lambda2 = mid - radius;\n \n if(lambda2 < 0.0) return;\n vec2 diagonalVector = normalize(vec2(cov2d[0][1], lambda1 - cov2d[0][0]));\n vec2 majorAxis = min(sqrt(2.0 * lambda1), 1024.0) * diagonalVector;\n vec2 minorAxis = min(sqrt(2.0 * lambda2), 1024.0) * vec2(diagonalVector.y, -diagonalVector.x);\n \n uint rgba = static1.w;\n vColor = \n clamp(pos.z/pos.w+1.0, 0.0, 1.0) * \n vec4(1.0, 1.0, 1.0, topacity) *\n vec4(\n (rgba) & 0xffu, \n (rgba >> 8) & 0xffu, \n (rgba >> 16) & 0xffu, \n (rgba >> 24) & 0xffu) / 255.0;\n\n vec2 vCenter = vec2(pos) / pos.w;\n gl_Position = vec4(\n vCenter \n + position.x * majorAxis / viewport \n + position.y * minorAxis / viewport, 0.0, 1.0);\n\n vPosition = position;\n}\n"}_getFragmentSource(){return"#version 300 es\nprecision highp float;\n \nin vec4 vColor;\nin vec2 vPosition;\n\nout vec4 fragColor;\n\nvoid main () {\n float A = -dot(vPosition, vPosition);\n if (A < -4.0) discard;\n float B = exp(A) * vColor.a;\n fragColor = vec4(B * vColor.rgb, B);\n}\n"}}class D{constructor(t,F,U){this.bounds=t,this.boxes=F,this.left=null,this.right=null,this.pointIndices=[],U.length>1?this.split(t,F,U):U.length>0&&(this.pointIndices=U)}split(t,F,U){const l=t.size().maxComponent();U.sort(((t,U)=>F[t].center().getComponent(l)-F[U].center().getComponent(l)));const n=Math.floor(U.length/2),Q=U.slice(0,n),e=U.slice(n);this.left=new D(t,F,Q),this.right=new D(t,F,e)}queryRange(t){return this.bounds.intersects(t)?null!==this.left&&null!==this.right?this.left.queryRange(t).concat(this.right.queryRange(t)):this.pointIndices.filter((F=>t.intersects(this.boxes[F]))):[]}}class f{constructor(t,F){const U=F.map(((t,F)=>F));this.root=new D(t,F,U)}queryRange(t){return this.root.queryRange(t)}}class w{constructor(F,U=100,l=1){let n=0,Q=null,e=[];this.testPoint=(d,A)=>{if(null===F.renderData||null===F.camera)return console.error("IntersectionTester cannot be called before renderProgram has been initialized"),null;if((()=>{if(null===F.renderData)return void console.error("IntersectionTester cannot be called before renderProgram has been initialized");e=[];const U=F.renderData,l=new Array(U.offsets.size);let d=0;const A=new V(new t(1/0,1/0,1/0),new t(-1/0,-1/0,-1/0));for(const t of U.offsets.keys()){const F=t.bounds;l[d++]=F,A.expand(F.min),A.expand(F.max),e.push(t)}A.permute(),Q=new f(A,l),n=U.vertexCount})(),null===Q)return console.error("Failed to build octree for IntersectionTester"),null;const B=F.renderData,a=F.camera;n!==B.vertexCount&&console.warn("IntersectionTester has not been rebuilt since the last render");const i=a.screenPointToRay(d,A);for(let F=0;F0)return e[B[0]]}return null}}}export{o as Camera,c as CameraData,p as Color32,Y as FPSControls,S as FadeInPass,w as IntersectionTester,I as Loader,A as Matrix3,l as Matrix4,d as Object3D,u as OrbitControls,m as PLYLoader,T as Plane,F as Quaternion,E as RenderData,y as RenderProgram,r as Scene,x as ShaderPass,N as ShaderProgram,Z as Splat,B as SplatData,R as Splatv,a as SplatvData,b as SplatvLoader,t as Vector3,s as Vector4,H as VideoRenderProgram,k as WebGLRenderer}; //# sourceMappingURL=index.js.map