@cearth/tools 2.3.0 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/math/transform.d.ts +20 -3
- package/dist/math/transform.d.ts.map +1 -1
- package/dist/tools.iife.js +24 -24
- package/dist/tools.js +248 -239
- package/dist/tools.umd.cjs +1 -1
- package/package.json +2 -2
package/dist/tools.iife.js
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
var Tools=function(
|
|
2
|
-
`,
|
|
3
|
-
`),l=`function(${
|
|
4
|
-
`),l=`function(${
|
|
5
|
-
`}),p=c.map(function(y){return typeof y=="function"?`${
|
|
6
|
-
`:y}),
|
|
7
|
-
`}),W=[],L=
|
|
8
|
-
`);const V=
|
|
9
|
-
`),[`${
|
|
10
|
-
`,...Z,...p,...G,...W]}function Ii(n,t){const l=n?Ji(n):[];return t||l.unshift(hs,fi),Hi(l)}function ps(n){return n&&Array.isArray(n.args)&&Array.isArray(n.transfer)}const Ws=class hi{constructor(t){if(rn(this,"id",++hi.instanceCount),rn(this,"execCount",0),t)for(const l of Object.keys(t))this.setCMDToSelf(l)}get port(){return this.getPort(this.worker)}get workerAndPort(){const t=this.worker;return[t,this.getPort(t)]}getPort(t){return t.port||t}execStarted(t,l){++t.executingCount}execEnded(t){--t.executingCount}getExecId(t){return t=t??"匿名",`${t}_${this.execCount}`}getExecRecord(t){return{id:this.getExecId(t.name),...t}}listenResponse(t,l){const s=new AbortController,e=s.signal;let d=null;const i=this.getPort(l);return new Promise((c,o)=>{i.addEventListener("message",X=>{const u=X.data,{execId:h,state:m,error:Z,data:p}=u;if(t!==h)return;if(d){if(m===An.End){s.abort(),Z&&d.error(Z),p!==void 0&&d.enqueue(p),d.close(),this.execEnded(l);return}if(Z){d.error(Z);return}d.enqueue(p);return}if(Z){o(Z),s.abort();return}if(m===An.End){s.abort(),c(p),this.execEnded(l);return}const G=new ReadableStream({start:W=>{d=W,Z&&d.error(Z),d.enqueue(p)}});c(G)},{signal:e});const a=X=>{if(s.abort(),d){d.error(X),d.close(),this.execEnded(l);return}o(X)};l.addEventListener("error",a,{signal:e}),i.addEventListener("messageerror",a,{signal:e})}).catch(c=>{throw this.execEnded(l),c})}execCMD(t,l){++this.execCount;const s=this.getExecRecord(t),[e,d]=this.workerAndPort;this.execStarted(e,s);const i=this.listenResponse(s.id,e);d.postMessage(s,l);const c=t.name;return c in this?i:i.then(o=>(this.setCMDToSelf(c),o))}setCMDToSelf(t,l){const s=(...e)=>{const d=e[0];let i;return e.length===1&&ps(d)&&(i=d.transfer,e=d.args),this.execCMD({name:t,args:e.length>0?e:void 0},i)};return Reflect.defineProperty(this,t,{configurable:!0,enumerable:!0,...l?{get:s}:{value:s,writable:!0}})}};rn(Ws,"instanceCount",0);let ki=Ws;function Pi(n){const{url:t,name:l}=n;return new Worker(t,{name:l})}class Qi extends ki{constructor(t,l){super(t?.named),rn(this,"worker");const{id:s}=this;let e=(typeof l=="string"?l:l?.name)||`DynamicWorker/${s}`,d=t;if(!gi(t)){const i=typeof t=="string",{getWorker:c,noDep:o}=l||{},a=i?t:Ii(t,o);d=(c||Pi)({url:a,name:e,clientId:s,id:s}),i||URL.revokeObjectURL(a)}d.executingCount=0,d.name=e,d.id=d.clientId=s,this.worker=d}get executingCount(){return this.worker.executingCount}setCMD(t,l,s){const e=l||t.name;if(!e)return Promise.reject("没有函数的名字");const d=typeof t=="function"?t.toString():t;return this.execCMD({name:"setCMD",args:[d,e]}).then(i=>(i&&this.setCMDToSelf(e,s),i))}removeCMD(t){return this.execCMD({name:"removeCMD",args:[t]}).then(l=>(l&&Reflect.deleteProperty(this,t),l))}}function vi(n){return new Proxy(n,{get:function(t,l,s){const e=t[l];return typeof e=="function"?e.bind(t):e||function(...d){const i=d[0];let c;return d.length===1&&ps(i)&&(c=i.transfer,d=i.args),t.execCMD({name:l,args:d.length>0?d:void 0},c)}},set:function(t,l,s,e){return t.setCMD(s,l,typeof s!="function")},deleteProperty:function(t,l){return t.removeCMD(l)},has:function(t,l){return l in t},ownKeys:function(t){return Reflect.ownKeys(t)}})}function Bi(n,t){const l=new Qi(n,t);return vi(l)}const wi=1/Math.PI*180,Ui=1/180*Math.PI,ji={EPSILON:1e-12,debug:!1,precision:4,printTypes:!1,printDegrees:!1,printRowMajor:!0,_cartographicRadians:!1};globalThis.mathgl=globalThis.mathgl||{config:{...ji}};const B=globalThis.mathgl.config;function Ei(n,{precision:t=B.precision}={}){return n=qi(n),`${parseFloat(n.toPrecision(t))}`}function mt(n){return Array.isArray(n)||ArrayBuffer.isView(n)&&!(n instanceof DataView)}function Oi(n){return Ai(n)}function Di(n){return _i(n)}function Ai(n,t){return qn(n,l=>l*Ui,t)}function _i(n,t){return qn(n,l=>l*wi,t)}function Rt(n,t,l){return qn(n,s=>Math.max(t,Math.min(l,s)))}function E(n,t,l){const s=B.EPSILON;l&&(B.EPSILON=l);try{if(n===t)return!0;if(mt(n)&&mt(t)){if(n.length!==t.length)return!1;for(let e=0;e<n.length;++e)if(!E(n[e],t[e]))return!1;return!0}return n&&n.equals?n.equals(t):t&&t.equals?t.equals(n):typeof n=="number"&&typeof t=="number"?Math.abs(n-t)<=B.EPSILON*Math.max(1,Math.abs(n),Math.abs(t)):!1}finally{B.EPSILON=s}}function qi(n){return Math.round(n/B.EPSILON)*B.EPSILON}function $i(n){return n.clone?n.clone():new Array(n.length)}function qn(n,t,l){if(mt(n)){const s=n;l=l||$i(s);for(let e=0;e<l.length&&e<s.length;++e){const d=typeof n=="number"?n:n[e];l[e]=t(d,e,l)}return l}return t(n)}class mn extends Array{clone(){return new this.constructor().copy(this)}fromArray(t,l=0){for(let s=0;s<this.ELEMENTS;++s)this[s]=t[s+l];return this.check()}toArray(t=[],l=0){for(let s=0;s<this.ELEMENTS;++s)t[l+s]=this[s];return t}toObject(t){return t}from(t){return Array.isArray(t)?this.copy(t):this.fromObject(t)}to(t){return t===this?this:mt(t)?this.toArray(t):this.toObject(t)}toTarget(t){return t?this.to(t):this}toFloat32Array(){return new Float32Array(this)}toString(){return this.formatString(B)}formatString(t){let l="";for(let s=0;s<this.ELEMENTS;++s)l+=(s>0?", ":"")+Ei(this[s],t);return`${t.printTypes?this.constructor.name:""}[${l}]`}equals(t){if(!t||this.length!==t.length)return!1;for(let l=0;l<this.ELEMENTS;++l)if(!E(this[l],t[l]))return!1;return!0}exactEquals(t){if(!t||this.length!==t.length)return!1;for(let l=0;l<this.ELEMENTS;++l)if(this[l]!==t[l])return!1;return!0}negate(){for(let t=0;t<this.ELEMENTS;++t)this[t]=-this[t];return this.check()}lerp(t,l,s){if(s===void 0)return this.lerp(this,t,l);for(let e=0;e<this.ELEMENTS;++e){const d=t[e],i=typeof l=="number"?l:l[e];this[e]=d+s*(i-d)}return this.check()}min(t){for(let l=0;l<this.ELEMENTS;++l)this[l]=Math.min(t[l],this[l]);return this.check()}max(t){for(let l=0;l<this.ELEMENTS;++l)this[l]=Math.max(t[l],this[l]);return this.check()}clamp(t,l){for(let s=0;s<this.ELEMENTS;++s)this[s]=Math.min(Math.max(this[s],t[s]),l[s]);return this.check()}add(...t){for(const l of t)for(let s=0;s<this.ELEMENTS;++s)this[s]+=l[s];return this.check()}subtract(...t){for(const l of t)for(let s=0;s<this.ELEMENTS;++s)this[s]-=l[s];return this.check()}scale(t){if(typeof t=="number")for(let l=0;l<this.ELEMENTS;++l)this[l]*=t;else for(let l=0;l<this.ELEMENTS&&l<t.length;++l)this[l]*=t[l];return this.check()}multiplyByScalar(t){for(let l=0;l<this.ELEMENTS;++l)this[l]*=t;return this.check()}check(){if(B.debug&&!this.validate())throw new Error(`math.gl: ${this.constructor.name} some fields set to invalid numbers'`);return this}validate(){let t=this.length===this.ELEMENTS;for(let l=0;l<this.ELEMENTS;++l)t=t&&Number.isFinite(this[l]);return t}sub(t){return this.subtract(t)}setScalar(t){for(let l=0;l<this.ELEMENTS;++l)this[l]=t;return this.check()}addScalar(t){for(let l=0;l<this.ELEMENTS;++l)this[l]+=t;return this.check()}subScalar(t){return this.addScalar(-t)}multiplyScalar(t){for(let l=0;l<this.ELEMENTS;++l)this[l]*=t;return this.check()}divideScalar(t){return this.multiplyByScalar(1/t)}clampScalar(t,l){for(let s=0;s<this.ELEMENTS;++s)this[s]=Math.min(Math.max(this[s],t),l);return this.check()}get elements(){return this}}function tc(n,t){if(n.length!==t)return!1;for(let l=0;l<n.length;++l)if(!Number.isFinite(n[l]))return!1;return!0}function C(n){if(!Number.isFinite(n))throw new Error(`Invalid number ${JSON.stringify(n)}`);return n}function wt(n,t,l=""){if(B.debug&&!tc(n,t))throw new Error(`math.gl: ${l} some fields set to invalid numbers'`);return n}function it(n,t){if(!n)throw new Error(`math.gl assertion ${t}`)}let $n=class extends mn{get x(){return this[0]}set x(t){this[0]=C(t)}get y(){return this[1]}set y(t){this[1]=C(t)}len(){return Math.sqrt(this.lengthSquared())}magnitude(){return this.len()}lengthSquared(){let t=0;for(let l=0;l<this.ELEMENTS;++l)t+=this[l]*this[l];return t}magnitudeSquared(){return this.lengthSquared()}distance(t){return Math.sqrt(this.distanceSquared(t))}distanceSquared(t){let l=0;for(let s=0;s<this.ELEMENTS;++s){const e=this[s]-t[s];l+=e*e}return C(l)}dot(t){let l=0;for(let s=0;s<this.ELEMENTS;++s)l+=this[s]*t[s];return C(l)}normalize(){const t=this.magnitude();if(t!==0)for(let l=0;l<this.ELEMENTS;++l)this[l]/=t;return this.check()}multiply(...t){for(const l of t)for(let s=0;s<this.ELEMENTS;++s)this[s]*=l[s];return this.check()}divide(...t){for(const l of t)for(let s=0;s<this.ELEMENTS;++s)this[s]/=l[s];return this.check()}lengthSq(){return this.lengthSquared()}distanceTo(t){return this.distance(t)}distanceToSquared(t){return this.distanceSquared(t)}getComponent(t){return it(t>=0&&t<this.ELEMENTS,"index is out of range"),C(this[t])}setComponent(t,l){return it(t>=0&&t<this.ELEMENTS,"index is out of range"),this[t]=l,this.check()}addVectors(t,l){return this.copy(t).add(l)}subVectors(t,l){return this.copy(t).subtract(l)}multiplyVectors(t,l){return this.copy(t).multiply(l)}addScaledVector(t,l){return this.add(new this.constructor(t).multiplyScalar(l))}};const F=1e-6;let Q=typeof Float32Array<"u"?Float32Array:Array;const Zt=Math.random;function et(n){return n>=0?Math.round(n):n%.5===0?Math.floor(n):Math.round(n)}function Vs(){const n=new Q(2);return Q!=Float32Array&&(n[0]=0,n[1]=0),n}function nc(n){const t=new Q(2);return t[0]=n[0],t[1]=n[1],t}function lc(n,t){const l=new Q(2);return l[0]=n,l[1]=t,l}function sc(n,t){return n[0]=t[0],n[1]=t[1],n}function ec(n,t,l){return n[0]=t,n[1]=l,n}function ys(n,t,l){return n[0]=t[0]+l[0],n[1]=t[1]+l[1],n}function _(n,t,l){return n[0]=t[0]-l[0],n[1]=t[1]-l[1],n}function Ls(n,t,l){return n[0]=t[0]*l[0],n[1]=t[1]*l[1],n}function xs(n,t,l){return n[0]=t[0]/l[0],n[1]=t[1]/l[1],n}function dc(n,t){return n[0]=Math.ceil(t[0]),n[1]=Math.ceil(t[1]),n}function ic(n,t){return n[0]=Math.floor(t[0]),n[1]=Math.floor(t[1]),n}function cc(n,t,l){return n[0]=Math.min(t[0],l[0]),n[1]=Math.min(t[1],l[1]),n}function bc(n,t,l){return n[0]=Math.max(t[0],l[0]),n[1]=Math.max(t[1],l[1]),n}function oc(n,t){return n[0]=et(t[0]),n[1]=et(t[1]),n}function ac(n,t,l){return n[0]=t[0]*l,n[1]=t[1]*l,n}function Rs(n,t,l,s){return n[0]=t[0]+l[0]*s,n[1]=t[1]+l[1]*s,n}function Ks(n,t){const l=t[0]-n[0],s=t[1]-n[1];return Math.sqrt(l*l+s*s)}function Ss(n,t){const l=t[0]-n[0],s=t[1]-n[1];return l*l+s*s}function zs(n){const t=n[0],l=n[1];return Math.sqrt(t*t+l*l)}function Ys(n){const t=n[0],l=n[1];return t*t+l*l}function Xc(n,t){return n[0]=-t[0],n[1]=-t[1],n}function uc(n,t){return n[0]=1/t[0],n[1]=1/t[1],n}function rc(n,t){const l=t[0],s=t[1];let e=l*l+s*s;return e>0&&(e=1/Math.sqrt(e)),n[0]=t[0]*e,n[1]=t[1]*e,n}function hc(n,t){return n[0]*t[0]+n[1]*t[1]}function Kt(n,t,l){const s=t[0]*l[1]-t[1]*l[0];return n[0]=n[1]=0,n[2]=s,n}function mc(n,t,l,s){const e=t[0],d=t[1];return n[0]=e+s*(l[0]-e),n[1]=d+s*(l[1]-d),n}function Zc(n,t){t=t===void 0?1:t;const l=Zt()*2*Math.PI;return n[0]=Math.cos(l)*t,n[1]=Math.sin(l)*t,n}function gs(n,t,l){const s=t[0],e=t[1];return n[0]=l[0]*s+l[2]*e,n[1]=l[1]*s+l[3]*e,n}function Ms(n,t,l){const s=t[0],e=t[1];return n[0]=l[0]*s+l[2]*e+l[4],n[1]=l[1]*s+l[3]*e+l[5],n}function tl(n,t,l){const s=t[0],e=t[1];return n[0]=l[0]*s+l[3]*e+l[6],n[1]=l[1]*s+l[4]*e+l[7],n}function nl(n,t,l){const s=t[0],e=t[1];return n[0]=l[0]*s+l[4]*e+l[12],n[1]=l[1]*s+l[5]*e+l[13],n}function Gc(n,t,l,s){const e=t[0]-l[0],d=t[1]-l[1],i=Math.sin(s),c=Math.cos(s);return n[0]=e*c-d*i+l[0],n[1]=e*i+d*c+l[1],n}function pc(n,t){const l=n[0],s=n[1],e=t[0],d=t[1],i=Math.sqrt((l*l+s*s)*(e*e+d*d)),c=i&&(l*e+s*d)/i;return Math.acos(Math.min(Math.max(c,-1),1))}function Wc(n){return n[0]=0,n[1]=0,n}function Vc(n){return`vec2(${n[0]}, ${n[1]})`}function yc(n,t){return n[0]===t[0]&&n[1]===t[1]}function ll(n,t){const l=n[0],s=n[1],e=t[0],d=t[1];return Math.abs(l-e)<=F*Math.max(1,Math.abs(l),Math.abs(e))&&Math.abs(s-d)<=F*Math.max(1,Math.abs(s),Math.abs(d))}const Lc=zs,xc=_,Rc=Ls,Kc=xs,Sc=Ks,zc=Ss,Yc=Ys,gc=function(){const n=Vs();return function(t,l,s,e,d,i){let c,o;for(l||(l=2),s||(s=0),e?o=Math.min(e*l+s,t.length):o=t.length,c=s;c<o;c+=l)n[0]=t[c],n[1]=t[c+1],d(n,n,i),t[c]=n[0],t[c+1]=n[1];return t}}(),Mc=Object.freeze(Object.defineProperty({__proto__:null,add:ys,angle:pc,ceil:dc,clone:nc,copy:sc,create:Vs,cross:Kt,dist:Sc,distance:Ks,div:Kc,divide:xs,dot:hc,equals:ll,exactEquals:yc,floor:ic,forEach:gc,fromValues:lc,inverse:uc,len:Lc,length:zs,lerp:mc,max:bc,min:cc,mul:Rc,multiply:Ls,negate:Xc,normalize:rc,random:Zc,rotate:Gc,round:oc,scale:ac,scaleAndAdd:Rs,set:ec,sqrDist:zc,sqrLen:Yc,squaredDistance:Ss,squaredLength:Ys,str:Vc,sub:xc,subtract:_,transformMat2:gs,transformMat2d:Ms,transformMat3:tl,transformMat4:nl,zero:Wc},Symbol.toStringTag,{value:"Module"}));function Ts(n,t,l){const s=t[0],e=t[1],d=l[3]*s+l[7]*e||1;return n[0]=(l[0]*s+l[4]*e)/d,n[1]=(l[1]*s+l[5]*e)/d,n}function fs(n,t,l){const s=t[0],e=t[1],d=t[2],i=l[3]*s+l[7]*e+l[11]*d||1;return n[0]=(l[0]*s+l[4]*e+l[8]*d)/i,n[1]=(l[1]*s+l[5]*e+l[9]*d)/i,n[2]=(l[2]*s+l[6]*e+l[10]*d)/i,n}function Tc(n,t,l){const s=t[0],e=t[1];return n[0]=l[0]*s+l[2]*e,n[1]=l[1]*s+l[3]*e,n[2]=t[2],n}function fc(n,t,l){const s=t[0],e=t[1];return n[0]=l[0]*s+l[2]*e,n[1]=l[1]*s+l[3]*e,n[2]=t[2],n[3]=t[3],n}function Cs(n,t,l){const s=t[0],e=t[1],d=t[2];return n[0]=l[0]*s+l[3]*e+l[6]*d,n[1]=l[1]*s+l[4]*e+l[7]*d,n[2]=l[2]*s+l[5]*e+l[8]*d,n[3]=t[3],n}class dt extends $n{constructor(t=0,l=0){super(2),mt(t)&&arguments.length===1?this.copy(t):(B.debug&&(C(t),C(l)),this[0]=t,this[1]=l)}set(t,l){return this[0]=t,this[1]=l,this.check()}copy(t){return this[0]=t[0],this[1]=t[1],this.check()}fromObject(t){return B.debug&&(C(t.x),C(t.y)),this[0]=t.x,this[1]=t.y,this.check()}toObject(t){return t.x=this[0],t.y=this[1],t}get ELEMENTS(){return 2}horizontalAngle(){return Math.atan2(this.y,this.x)}verticalAngle(){return Math.atan2(this.x,this.y)}transform(t){return this.transformAsPoint(t)}transformAsPoint(t){return nl(this,this,t),this.check()}transformAsVector(t){return Ts(this,this,t),this.check()}transformByMatrix3(t){return tl(this,this,t),this.check()}transformByMatrix2x3(t){return Ms(this,this,t),this.check()}transformByMatrix2(t){return gs(this,this,t),this.check()}}function sl(){const n=new Q(3);return Q!=Float32Array&&(n[0]=0,n[1]=0,n[2]=0),n}function Cc(n){const t=new Q(3);return t[0]=n[0],t[1]=n[1],t[2]=n[2],t}function Zn(n){const t=n[0],l=n[1],s=n[2];return Math.sqrt(t*t+l*l+s*s)}function el(n,t,l){const s=new Q(3);return s[0]=n,s[1]=t,s[2]=l,s}function Fc(n,t){return n[0]=t[0],n[1]=t[1],n[2]=t[2],n}function Nc(n,t,l,s){return n[0]=t,n[1]=l,n[2]=s,n}function Hc(n,t,l){return n[0]=t[0]+l[0],n[1]=t[1]+l[1],n[2]=t[2]+l[2],n}function dl(n,t,l){return n[0]=t[0]-l[0],n[1]=t[1]-l[1],n[2]=t[2]-l[2],n}function Fs(n,t,l){return n[0]=t[0]*l[0],n[1]=t[1]*l[1],n[2]=t[2]*l[2],n}function Ns(n,t,l){return n[0]=t[0]/l[0],n[1]=t[1]/l[1],n[2]=t[2]/l[2],n}function Jc(n,t){return n[0]=Math.ceil(t[0]),n[1]=Math.ceil(t[1]),n[2]=Math.ceil(t[2]),n}function Ic(n,t){return n[0]=Math.floor(t[0]),n[1]=Math.floor(t[1]),n[2]=Math.floor(t[2]),n}function kc(n,t,l){return n[0]=Math.min(t[0],l[0]),n[1]=Math.min(t[1],l[1]),n[2]=Math.min(t[2],l[2]),n}function Pc(n,t,l){return n[0]=Math.max(t[0],l[0]),n[1]=Math.max(t[1],l[1]),n[2]=Math.max(t[2],l[2]),n}function Qc(n,t){return n[0]=et(t[0]),n[1]=et(t[1]),n[2]=et(t[2]),n}function Hs(n,t,l){return n[0]=t[0]*l,n[1]=t[1]*l,n[2]=t[2]*l,n}function vc(n,t,l,s){return n[0]=t[0]+l[0]*s,n[1]=t[1]+l[1]*s,n[2]=t[2]+l[2]*s,n}function Js(n,t){const l=t[0]-n[0],s=t[1]-n[1],e=t[2]-n[2];return Math.sqrt(l*l+s*s+e*e)}function Is(n,t){const l=t[0]-n[0],s=t[1]-n[1],e=t[2]-n[2];return l*l+s*s+e*e}function ks(n){const t=n[0],l=n[1],s=n[2];return t*t+l*l+s*s}function Bc(n,t){return n[0]=-t[0],n[1]=-t[1],n[2]=-t[2],n}function wc(n,t){return n[0]=1/t[0],n[1]=1/t[1],n[2]=1/t[2],n}function Ps(n,t){const l=t[0],s=t[1],e=t[2];let d=l*l+s*s+e*e;return d>0&&(d=1/Math.sqrt(d)),n[0]=t[0]*d,n[1]=t[1]*d,n[2]=t[2]*d,n}function Ut(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function St(n,t,l){const s=t[0],e=t[1],d=t[2],i=l[0],c=l[1],o=l[2];return n[0]=e*o-d*c,n[1]=d*i-s*o,n[2]=s*c-e*i,n}function Uc(n,t,l,s){const e=t[0],d=t[1],i=t[2];return n[0]=e+s*(l[0]-e),n[1]=d+s*(l[1]-d),n[2]=i+s*(l[2]-i),n}function jc(n,t,l,s){const e=Math.acos(Math.min(Math.max(Ut(t,l),-1),1)),d=Math.sin(e),i=Math.sin((1-s)*e)/d,c=Math.sin(s*e)/d;return n[0]=i*t[0]+c*l[0],n[1]=i*t[1]+c*l[1],n[2]=i*t[2]+c*l[2],n}function Ec(n,t,l,s,e,d){const i=d*d,c=i*(2*d-3)+1,o=i*(d-2)+d,a=i*(d-1),X=i*(3-2*d);return n[0]=t[0]*c+l[0]*o+s[0]*a+e[0]*X,n[1]=t[1]*c+l[1]*o+s[1]*a+e[1]*X,n[2]=t[2]*c+l[2]*o+s[2]*a+e[2]*X,n}function Oc(n,t,l,s,e,d){const i=1-d,c=i*i,o=d*d,a=c*i,X=3*d*c,u=3*o*i,h=o*d;return n[0]=t[0]*a+l[0]*X+s[0]*u+e[0]*h,n[1]=t[1]*a+l[1]*X+s[1]*u+e[1]*h,n[2]=t[2]*a+l[2]*X+s[2]*u+e[2]*h,n}function Dc(n,t){t=t===void 0?1:t;const l=Zt()*2*Math.PI,s=Zt()*2-1,e=Math.sqrt(1-s*s)*t;return n[0]=Math.cos(l)*e,n[1]=Math.sin(l)*e,n[2]=s*t,n}function Gn(n,t,l){const s=t[0],e=t[1],d=t[2];let i=l[3]*s+l[7]*e+l[11]*d+l[15];return i=i||1,n[0]=(l[0]*s+l[4]*e+l[8]*d+l[12])/i,n[1]=(l[1]*s+l[5]*e+l[9]*d+l[13])/i,n[2]=(l[2]*s+l[6]*e+l[10]*d+l[14])/i,n}function il(n,t,l){const s=t[0],e=t[1],d=t[2];return n[0]=s*l[0]+e*l[3]+d*l[6],n[1]=s*l[1]+e*l[4]+d*l[7],n[2]=s*l[2]+e*l[5]+d*l[8],n}function cl(n,t,l){const s=l[0],e=l[1],d=l[2],i=l[3],c=t[0],o=t[1],a=t[2];let X=e*a-d*o,u=d*c-s*a,h=s*o-e*c,m=e*h-d*u,Z=d*X-s*h,p=s*u-e*X;const G=i*2;return X*=G,u*=G,h*=G,m*=2,Z*=2,p*=2,n[0]=c+X+m,n[1]=o+u+Z,n[2]=a+h+p,n}function Qs(n,t,l,s){const e=[],d=[];return e[0]=t[0]-l[0],e[1]=t[1]-l[1],e[2]=t[2]-l[2],d[0]=e[0],d[1]=e[1]*Math.cos(s)-e[2]*Math.sin(s),d[2]=e[1]*Math.sin(s)+e[2]*Math.cos(s),n[0]=d[0]+l[0],n[1]=d[1]+l[1],n[2]=d[2]+l[2],n}function vs(n,t,l,s){const e=[],d=[];return e[0]=t[0]-l[0],e[1]=t[1]-l[1],e[2]=t[2]-l[2],d[0]=e[2]*Math.sin(s)+e[0]*Math.cos(s),d[1]=e[1],d[2]=e[2]*Math.cos(s)-e[0]*Math.sin(s),n[0]=d[0]+l[0],n[1]=d[1]+l[1],n[2]=d[2]+l[2],n}function Bs(n,t,l,s){const e=[],d=[];return e[0]=t[0]-l[0],e[1]=t[1]-l[1],e[2]=t[2]-l[2],d[0]=e[0]*Math.cos(s)-e[1]*Math.sin(s),d[1]=e[0]*Math.sin(s)+e[1]*Math.cos(s),d[2]=e[2],n[0]=d[0]+l[0],n[1]=d[1]+l[1],n[2]=d[2]+l[2],n}function ws(n,t){const l=n[0],s=n[1],e=n[2],d=t[0],i=t[1],c=t[2],o=Math.sqrt((l*l+s*s+e*e)*(d*d+i*i+c*c)),a=o&&Ut(n,t)/o;return Math.acos(Math.min(Math.max(a,-1),1))}function Ac(n){return n[0]=0,n[1]=0,n[2]=0,n}function _c(n){return`vec3(${n[0]}, ${n[1]}, ${n[2]})`}function qc(n,t){return n[0]===t[0]&&n[1]===t[1]&&n[2]===t[2]}function $c(n,t){const l=n[0],s=n[1],e=n[2],d=t[0],i=t[1],c=t[2];return Math.abs(l-d)<=F*Math.max(1,Math.abs(l),Math.abs(d))&&Math.abs(s-i)<=F*Math.max(1,Math.abs(s),Math.abs(i))&&Math.abs(e-c)<=F*Math.max(1,Math.abs(e),Math.abs(c))}const t0=dl,n0=Fs,l0=Ns,s0=Js,e0=Is,Us=Zn,d0=ks,i0=function(){const n=sl();return function(t,l,s,e,d,i){let c,o;for(l||(l=3),s||(s=0),e?o=Math.min(e*l+s,t.length):o=t.length,c=s;c<o;c+=l)n[0]=t[c],n[1]=t[c+1],n[2]=t[c+2],d(n,n,i),t[c]=n[0],t[c+1]=n[1],t[c+2]=n[2];return t}}(),c0=Object.freeze(Object.defineProperty({__proto__:null,add:Hc,angle:ws,bezier:Oc,ceil:Jc,clone:Cc,copy:Fc,create:sl,cross:St,dist:s0,distance:Js,div:l0,divide:Ns,dot:Ut,equals:$c,exactEquals:qc,floor:Ic,forEach:i0,fromValues:el,hermite:Ec,inverse:wc,len:Us,length:Zn,lerp:Uc,max:Pc,min:kc,mul:n0,multiply:Fs,negate:Bc,normalize:Ps,random:Dc,rotateX:Qs,rotateY:vs,rotateZ:Bs,round:Qc,scale:Hs,scaleAndAdd:vc,set:Nc,slerp:jc,sqrDist:e0,sqrLen:d0,squaredDistance:Is,squaredLength:ks,str:_c,sub:t0,subtract:dl,transformMat3:il,transformMat4:Gn,transformQuat:cl,zero:Ac},Symbol.toStringTag,{value:"Module"})),bl=[0,0,0];let pn;class N extends $n{static get ZERO(){return pn||(pn=new N(0,0,0),Object.freeze(pn)),pn}constructor(t=0,l=0,s=0){super(-0,-0,-0),arguments.length===1&&mt(t)?this.copy(t):(B.debug&&(C(t),C(l),C(s)),this[0]=t,this[1]=l,this[2]=s)}set(t,l,s){return this[0]=t,this[1]=l,this[2]=s,this.check()}copy(t){return this[0]=t[0],this[1]=t[1],this[2]=t[2],this.check()}fromObject(t){return B.debug&&(C(t.x),C(t.y),C(t.z)),this[0]=t.x,this[1]=t.y,this[2]=t.z,this.check()}toObject(t){return t.x=this[0],t.y=this[1],t.z=this[2],t}get ELEMENTS(){return 3}get z(){return this[2]}set z(t){this[2]=C(t)}angle(t){return ws(this,t)}cross(t){return St(this,this,t),this.check()}rotateX({radians:t,origin:l=bl}){return Qs(this,this,l,t),this.check()}rotateY({radians:t,origin:l=bl}){return vs(this,this,l,t),this.check()}rotateZ({radians:t,origin:l=bl}){return Bs(this,this,l,t),this.check()}transform(t){return this.transformAsPoint(t)}transformAsPoint(t){return Gn(this,this,t),this.check()}transformAsVector(t){return fs(this,this,t),this.check()}transformByMatrix3(t){return il(this,this,t),this.check()}transformByMatrix2(t){return Tc(this,this,t),this.check()}transformByQuaternion(t){return cl(this,this,t),this.check()}}let Wn;class ct extends $n{static get ZERO(){return Wn||(Wn=new ct(0,0,0,0),Object.freeze(Wn)),Wn}constructor(t=0,l=0,s=0,e=0){super(-0,-0,-0,-0),mt(t)&&arguments.length===1?this.copy(t):(B.debug&&(C(t),C(l),C(s),C(e)),this[0]=t,this[1]=l,this[2]=s,this[3]=e)}set(t,l,s,e){return this[0]=t,this[1]=l,this[2]=s,this[3]=e,this.check()}copy(t){return this[0]=t[0],this[1]=t[1],this[2]=t[2],this[3]=t[3],this.check()}fromObject(t){return B.debug&&(C(t.x),C(t.y),C(t.z),C(t.w)),this[0]=t.x,this[1]=t.y,this[2]=t.z,this[3]=t.w,this}toObject(t){return t.x=this[0],t.y=this[1],t.z=this[2],t.w=this[3],t}get ELEMENTS(){return 4}get z(){return this[2]}set z(t){this[2]=C(t)}get w(){return this[3]}set w(t){this[3]=C(t)}transform(t){return Gn(this,this,t),this.check()}transformByMatrix3(t){return Cs(this,this,t),this.check()}transformByMatrix2(t){return fc(this,this,t),this.check()}transformByQuaternion(t){return cl(this,this,t),this.check()}applyMatrix4(t){return t.transform(this,this),this}}let js=class extends mn{toString(){let t="[";if(B.printRowMajor){t+="row-major:";for(let l=0;l<this.RANK;++l)for(let s=0;s<this.RANK;++s)t+=` ${this[s*this.RANK+l]}`}else{t+="column-major:";for(let l=0;l<this.ELEMENTS;++l)t+=` ${this[l]}`}return t+="]",t}getElementIndex(t,l){return l*this.RANK+t}getElement(t,l){return this[l*this.RANK+t]}setElement(t,l,s){return this[l*this.RANK+t]=C(s),this}getColumn(t,l=new Array(this.RANK).fill(-0)){const s=t*this.RANK;for(let e=0;e<this.RANK;++e)l[e]=this[s+e];return l}setColumn(t,l){const s=t*this.RANK;for(let e=0;e<this.RANK;++e)this[s+e]=l[e];return this}};function Es(){const n=new Q(9);return Q!=Float32Array&&(n[1]=0,n[2]=0,n[3]=0,n[5]=0,n[6]=0,n[7]=0),n[0]=1,n[4]=1,n[8]=1,n}function b0(n,t){return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[4],n[4]=t[5],n[5]=t[6],n[6]=t[8],n[7]=t[9],n[8]=t[10],n}function o0(n){const t=new Q(9);return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t}function a0(n,t){return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n}function X0(n,t,l,s,e,d,i,c,o){const a=new Q(9);return a[0]=n,a[1]=t,a[2]=l,a[3]=s,a[4]=e,a[5]=d,a[6]=i,a[7]=c,a[8]=o,a}function u0(n,t,l,s,e,d,i,c,o,a){return n[0]=t,n[1]=l,n[2]=s,n[3]=e,n[4]=d,n[5]=i,n[6]=c,n[7]=o,n[8]=a,n}function r0(n){return n[0]=1,n[1]=0,n[2]=0,n[3]=0,n[4]=1,n[5]=0,n[6]=0,n[7]=0,n[8]=1,n}function ol(n,t){if(n===t){const l=t[1],s=t[2],e=t[5];n[1]=t[3],n[2]=t[6],n[3]=l,n[5]=t[7],n[6]=s,n[7]=e}else n[0]=t[0],n[1]=t[3],n[2]=t[6],n[3]=t[1],n[4]=t[4],n[5]=t[7],n[6]=t[2],n[7]=t[5],n[8]=t[8];return n}function al(n,t){const l=t[0],s=t[1],e=t[2],d=t[3],i=t[4],c=t[5],o=t[6],a=t[7],X=t[8],u=X*i-c*a,h=-X*d+c*o,m=a*d-i*o;let Z=l*u+s*h+e*m;return Z?(Z=1/Z,n[0]=u*Z,n[1]=(-X*s+e*a)*Z,n[2]=(c*s-e*i)*Z,n[3]=h*Z,n[4]=(X*l-e*o)*Z,n[5]=(-c*l+e*d)*Z,n[6]=m*Z,n[7]=(-a*l+s*o)*Z,n[8]=(i*l-s*d)*Z,n):null}function h0(n,t){const l=t[0],s=t[1],e=t[2],d=t[3],i=t[4],c=t[5],o=t[6],a=t[7],X=t[8];return n[0]=i*X-c*a,n[1]=e*a-s*X,n[2]=s*c-e*i,n[3]=c*o-d*X,n[4]=l*X-e*o,n[5]=e*d-l*c,n[6]=d*a-i*o,n[7]=s*o-l*a,n[8]=l*i-s*d,n}function Xl(n){const t=n[0],l=n[1],s=n[2],e=n[3],d=n[4],i=n[5],c=n[6],o=n[7],a=n[8];return t*(a*d-i*o)+l*(-a*e+i*c)+s*(o*e-d*c)}function Vn(n,t,l){const s=t[0],e=t[1],d=t[2],i=t[3],c=t[4],o=t[5],a=t[6],X=t[7],u=t[8],h=l[0],m=l[1],Z=l[2],p=l[3],G=l[4],W=l[5],L=l[6],V=l[7],y=l[8];return n[0]=h*s+m*i+Z*a,n[1]=h*e+m*c+Z*X,n[2]=h*d+m*o+Z*u,n[3]=p*s+G*i+W*a,n[4]=p*e+G*c+W*X,n[5]=p*d+G*o+W*u,n[6]=L*s+V*i+y*a,n[7]=L*e+V*c+y*X,n[8]=L*d+V*o+y*u,n}function Os(n,t,l){const s=t[0],e=t[1],d=t[2],i=t[3],c=t[4],o=t[5],a=t[6],X=t[7],u=t[8],h=l[0],m=l[1];return n[0]=s,n[1]=e,n[2]=d,n[3]=i,n[4]=c,n[5]=o,n[6]=h*s+m*i+a,n[7]=h*e+m*c+X,n[8]=h*d+m*o+u,n}function Ds(n,t,l){const s=t[0],e=t[1],d=t[2],i=t[3],c=t[4],o=t[5],a=t[6],X=t[7],u=t[8],h=Math.sin(l),m=Math.cos(l);return n[0]=m*s+h*i,n[1]=m*e+h*c,n[2]=m*d+h*o,n[3]=m*i-h*s,n[4]=m*c-h*e,n[5]=m*o-h*d,n[6]=a,n[7]=X,n[8]=u,n}function ul(n,t,l){const s=l[0],e=l[1];return n[0]=s*t[0],n[1]=s*t[1],n[2]=s*t[2],n[3]=e*t[3],n[4]=e*t[4],n[5]=e*t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n}function m0(n,t){return n[0]=1,n[1]=0,n[2]=0,n[3]=0,n[4]=1,n[5]=0,n[6]=t[0],n[7]=t[1],n[8]=1,n}function Z0(n,t){const l=Math.sin(t),s=Math.cos(t);return n[0]=s,n[1]=l,n[2]=0,n[3]=-l,n[4]=s,n[5]=0,n[6]=0,n[7]=0,n[8]=1,n}function G0(n,t){return n[0]=t[0],n[1]=0,n[2]=0,n[3]=0,n[4]=t[1],n[5]=0,n[6]=0,n[7]=0,n[8]=1,n}function p0(n,t){return n[0]=t[0],n[1]=t[1],n[2]=0,n[3]=t[2],n[4]=t[3],n[5]=0,n[6]=t[4],n[7]=t[5],n[8]=1,n}function As(n,t){const l=t[0],s=t[1],e=t[2],d=t[3],i=l+l,c=s+s,o=e+e,a=l*i,X=s*i,u=s*c,h=e*i,m=e*c,Z=e*o,p=d*i,G=d*c,W=d*o;return n[0]=1-u-Z,n[3]=X-W,n[6]=h+G,n[1]=X+W,n[4]=1-a-Z,n[7]=m-p,n[2]=h-G,n[5]=m+p,n[8]=1-a-u,n}function rl(n,t){const l=t[0],s=t[1],e=t[2],d=t[3],i=t[4],c=t[5],o=t[6],a=t[7],X=t[8],u=t[9],h=t[10],m=t[11],Z=t[12],p=t[13],G=t[14],W=t[15],L=l*c-s*i,V=l*o-e*i,y=l*a-d*i,S=s*o-e*c,R=s*a-d*c,T=e*a-d*o,g=X*p-u*Z,M=X*G-h*Z,z=X*W-m*Z,H=u*G-h*p,J=u*W-m*p,I=h*W-m*G;let f=L*I-V*J+y*H+S*z-R*M+T*g;return f?(f=1/f,n[0]=(c*I-o*J+a*H)*f,n[1]=(o*z-i*I-a*M)*f,n[2]=(i*J-c*z+a*g)*f,n[3]=(e*J-s*I-d*H)*f,n[4]=(l*I-e*z+d*M)*f,n[5]=(s*z-l*J-d*g)*f,n[6]=(p*T-G*R+W*S)*f,n[7]=(G*y-Z*T-W*V)*f,n[8]=(Z*R-p*y+W*L)*f,n):null}function W0(n,t,l){return n[0]=2/t,n[1]=0,n[2]=0,n[3]=0,n[4]=-2/l,n[5]=0,n[6]=-1,n[7]=1,n[8]=1,n}function V0(n){return`mat3(${n[0]}, ${n[1]}, ${n[2]}, ${n[3]}, ${n[4]}, ${n[5]}, ${n[6]}, ${n[7]}, ${n[8]})`}function y0(n){return Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]+n[3]*n[3]+n[4]*n[4]+n[5]*n[5]+n[6]*n[6]+n[7]*n[7]+n[8]*n[8])}function L0(n,t,l){return n[0]=t[0]+l[0],n[1]=t[1]+l[1],n[2]=t[2]+l[2],n[3]=t[3]+l[3],n[4]=t[4]+l[4],n[5]=t[5]+l[5],n[6]=t[6]+l[6],n[7]=t[7]+l[7],n[8]=t[8]+l[8],n}function _s(n,t,l){return n[0]=t[0]-l[0],n[1]=t[1]-l[1],n[2]=t[2]-l[2],n[3]=t[3]-l[3],n[4]=t[4]-l[4],n[5]=t[5]-l[5],n[6]=t[6]-l[6],n[7]=t[7]-l[7],n[8]=t[8]-l[8],n}function x0(n,t,l){return n[0]=t[0]*l,n[1]=t[1]*l,n[2]=t[2]*l,n[3]=t[3]*l,n[4]=t[4]*l,n[5]=t[5]*l,n[6]=t[6]*l,n[7]=t[7]*l,n[8]=t[8]*l,n}function R0(n,t,l,s){return n[0]=t[0]+l[0]*s,n[1]=t[1]+l[1]*s,n[2]=t[2]+l[2]*s,n[3]=t[3]+l[3]*s,n[4]=t[4]+l[4]*s,n[5]=t[5]+l[5]*s,n[6]=t[6]+l[6]*s,n[7]=t[7]+l[7]*s,n[8]=t[8]+l[8]*s,n}function K0(n,t){return n[0]===t[0]&&n[1]===t[1]&&n[2]===t[2]&&n[3]===t[3]&&n[4]===t[4]&&n[5]===t[5]&&n[6]===t[6]&&n[7]===t[7]&&n[8]===t[8]}function S0(n,t){const l=n[0],s=n[1],e=n[2],d=n[3],i=n[4],c=n[5],o=n[6],a=n[7],X=n[8],u=t[0],h=t[1],m=t[2],Z=t[3],p=t[4],G=t[5],W=t[6],L=t[7],V=t[8];return Math.abs(l-u)<=F*Math.max(1,Math.abs(l),Math.abs(u))&&Math.abs(s-h)<=F*Math.max(1,Math.abs(s),Math.abs(h))&&Math.abs(e-m)<=F*Math.max(1,Math.abs(e),Math.abs(m))&&Math.abs(d-Z)<=F*Math.max(1,Math.abs(d),Math.abs(Z))&&Math.abs(i-p)<=F*Math.max(1,Math.abs(i),Math.abs(p))&&Math.abs(c-G)<=F*Math.max(1,Math.abs(c),Math.abs(G))&&Math.abs(o-W)<=F*Math.max(1,Math.abs(o),Math.abs(W))&&Math.abs(a-L)<=F*Math.max(1,Math.abs(a),Math.abs(L))&&Math.abs(X-V)<=F*Math.max(1,Math.abs(X),Math.abs(V))}const z0=Object.freeze(Object.defineProperty({__proto__:null,add:L0,adjoint:h0,clone:o0,copy:a0,create:Es,determinant:Xl,equals:S0,exactEquals:K0,frob:y0,fromMat2d:p0,fromMat4:b0,fromQuat:As,fromRotation:Z0,fromScaling:G0,fromTranslation:m0,fromValues:X0,identity:r0,invert:al,mul:Vn,multiply:Vn,multiplyScalar:x0,multiplyScalarAndAdd:R0,normalFromMat4:rl,projection:W0,rotate:Ds,scale:ul,set:u0,str:V0,sub:_s,subtract:_s,translate:Os,transpose:ol},Symbol.toStringTag,{value:"Module"}));var hl;(function(n){n[n.COL0ROW0=0]="COL0ROW0",n[n.COL0ROW1=1]="COL0ROW1",n[n.COL0ROW2=2]="COL0ROW2",n[n.COL1ROW0=3]="COL1ROW0",n[n.COL1ROW1=4]="COL1ROW1",n[n.COL1ROW2=5]="COL1ROW2",n[n.COL2ROW0=6]="COL2ROW0",n[n.COL2ROW1=7]="COL2ROW1",n[n.COL2ROW2=8]="COL2ROW2"})(hl||(hl={}));const Y0=Object.freeze([1,0,0,0,1,0,0,0,1]);class zt extends js{static get IDENTITY(){return M0()}static get ZERO(){return g0()}get ELEMENTS(){return 9}get RANK(){return 3}get INDICES(){return hl}constructor(t,...l){super(-0,-0,-0,-0,-0,-0,-0,-0,-0),arguments.length===1&&Array.isArray(t)?this.copy(t):l.length>0?this.copy([t,...l]):this.identity()}copy(t){return this[0]=t[0],this[1]=t[1],this[2]=t[2],this[3]=t[3],this[4]=t[4],this[5]=t[5],this[6]=t[6],this[7]=t[7],this[8]=t[8],this.check()}identity(){return this.copy(Y0)}fromObject(t){return this.check()}fromQuaternion(t){return As(this,t),this.check()}set(t,l,s,e,d,i,c,o,a){return this[0]=t,this[1]=l,this[2]=s,this[3]=e,this[4]=d,this[5]=i,this[6]=c,this[7]=o,this[8]=a,this.check()}setRowMajor(t,l,s,e,d,i,c,o,a){return this[0]=t,this[1]=e,this[2]=c,this[3]=l,this[4]=d,this[5]=o,this[6]=s,this[7]=i,this[8]=a,this.check()}determinant(){return Xl(this)}transpose(){return ol(this,this),this.check()}invert(){return al(this,this),this.check()}multiplyLeft(t){return Vn(this,t,this),this.check()}multiplyRight(t){return Vn(this,this,t),this.check()}rotate(t){return Ds(this,this,t),this.check()}scale(t){return Array.isArray(t)?ul(this,this,t):ul(this,this,[t,t]),this.check()}translate(t){return Os(this,this,t),this.check()}transform(t,l){let s;switch(t.length){case 2:s=tl(l||[-0,-0],t,this);break;case 3:s=il(l||[-0,-0,-0],t,this);break;case 4:s=Cs(l||[-0,-0,-0,-0],t,this);break;default:throw new Error("Illegal vector")}return wt(s,t.length),s}transformVector(t,l){return this.transform(t,l)}transformVector2(t,l){return this.transform(t,l)}transformVector3(t,l){return this.transform(t,l)}}let yn,Ln=null;function g0(){return yn||(yn=new zt([0,0,0,0,0,0,0,0,0]),Object.freeze(yn)),yn}function M0(){return Ln||(Ln=new zt,Object.freeze(Ln)),Ln}function T0(){const n=new Q(16);return Q!=Float32Array&&(n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[11]=0,n[12]=0,n[13]=0,n[14]=0),n[0]=1,n[5]=1,n[10]=1,n[15]=1,n}function f0(n){const t=new Q(16);return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t[9]=n[9],t[10]=n[10],t[11]=n[11],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15],t}function C0(n,t){return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15],n}function F0(n,t,l,s,e,d,i,c,o,a,X,u,h,m,Z,p){const G=new Q(16);return G[0]=n,G[1]=t,G[2]=l,G[3]=s,G[4]=e,G[5]=d,G[6]=i,G[7]=c,G[8]=o,G[9]=a,G[10]=X,G[11]=u,G[12]=h,G[13]=m,G[14]=Z,G[15]=p,G}function N0(n,t,l,s,e,d,i,c,o,a,X,u,h,m,Z,p,G){return n[0]=t,n[1]=l,n[2]=s,n[3]=e,n[4]=d,n[5]=i,n[6]=c,n[7]=o,n[8]=a,n[9]=X,n[10]=u,n[11]=h,n[12]=m,n[13]=Z,n[14]=p,n[15]=G,n}function qs(n){return n[0]=1,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=1,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=1,n[11]=0,n[12]=0,n[13]=0,n[14]=0,n[15]=1,n}function $s(n,t){if(n===t){const l=t[1],s=t[2],e=t[3],d=t[6],i=t[7],c=t[11];n[1]=t[4],n[2]=t[8],n[3]=t[12],n[4]=l,n[6]=t[9],n[7]=t[13],n[8]=s,n[9]=d,n[11]=t[14],n[12]=e,n[13]=i,n[14]=c}else n[0]=t[0],n[1]=t[4],n[2]=t[8],n[3]=t[12],n[4]=t[1],n[5]=t[5],n[6]=t[9],n[7]=t[13],n[8]=t[2],n[9]=t[6],n[10]=t[10],n[11]=t[14],n[12]=t[3],n[13]=t[7],n[14]=t[11],n[15]=t[15];return n}function te(n,t){const l=t[0],s=t[1],e=t[2],d=t[3],i=t[4],c=t[5],o=t[6],a=t[7],X=t[8],u=t[9],h=t[10],m=t[11],Z=t[12],p=t[13],G=t[14],W=t[15],L=l*c-s*i,V=l*o-e*i,y=l*a-d*i,S=s*o-e*c,R=s*a-d*c,T=e*a-d*o,g=X*p-u*Z,M=X*G-h*Z,z=X*W-m*Z,H=u*G-h*p,J=u*W-m*p,I=h*W-m*G;let f=L*I-V*J+y*H+S*z-R*M+T*g;return f?(f=1/f,n[0]=(c*I-o*J+a*H)*f,n[1]=(e*J-s*I-d*H)*f,n[2]=(p*T-G*R+W*S)*f,n[3]=(h*R-u*T-m*S)*f,n[4]=(o*z-i*I-a*M)*f,n[5]=(l*I-e*z+d*M)*f,n[6]=(G*y-Z*T-W*V)*f,n[7]=(X*T-h*y+m*V)*f,n[8]=(i*J-c*z+a*g)*f,n[9]=(s*z-l*J-d*g)*f,n[10]=(Z*R-p*y+W*L)*f,n[11]=(u*y-X*R-m*L)*f,n[12]=(c*M-i*H-o*g)*f,n[13]=(l*H-s*M+e*g)*f,n[14]=(p*V-Z*S-G*L)*f,n[15]=(X*S-u*V+h*L)*f,n):null}function H0(n,t){const l=t[0],s=t[1],e=t[2],d=t[3],i=t[4],c=t[5],o=t[6],a=t[7],X=t[8],u=t[9],h=t[10],m=t[11],Z=t[12],p=t[13],G=t[14],W=t[15],L=l*c-s*i,V=l*o-e*i,y=l*a-d*i,S=s*o-e*c,R=s*a-d*c,T=e*a-d*o,g=X*p-u*Z,M=X*G-h*Z,z=X*W-m*Z,H=u*G-h*p,J=u*W-m*p,I=h*W-m*G;return n[0]=c*I-o*J+a*H,n[1]=e*J-s*I-d*H,n[2]=p*T-G*R+W*S,n[3]=h*R-u*T-m*S,n[4]=o*z-i*I-a*M,n[5]=l*I-e*z+d*M,n[6]=G*y-Z*T-W*V,n[7]=X*T-h*y+m*V,n[8]=i*J-c*z+a*g,n[9]=s*z-l*J-d*g,n[10]=Z*R-p*y+W*L,n[11]=u*y-X*R-m*L,n[12]=c*M-i*H-o*g,n[13]=l*H-s*M+e*g,n[14]=p*V-Z*S-G*L,n[15]=X*S-u*V+h*L,n}function ml(n){const t=n[0],l=n[1],s=n[2],e=n[3],d=n[4],i=n[5],c=n[6],o=n[7],a=n[8],X=n[9],u=n[10],h=n[11],m=n[12],Z=n[13],p=n[14],G=n[15],W=t*i-l*d,L=t*c-s*d,V=l*c-s*i,y=a*Z-X*m,S=a*p-u*m,R=X*p-u*Z,T=t*R-l*S+s*y,g=d*R-i*S+c*y,M=a*V-X*L+u*W,z=m*V-Z*L+p*W;return o*T-e*g+G*M-h*z}function xn(n,t,l){const s=t[0],e=t[1],d=t[2],i=t[3],c=t[4],o=t[5],a=t[6],X=t[7],u=t[8],h=t[9],m=t[10],Z=t[11],p=t[12],G=t[13],W=t[14],L=t[15];let V=l[0],y=l[1],S=l[2],R=l[3];return n[0]=V*s+y*c+S*u+R*p,n[1]=V*e+y*o+S*h+R*G,n[2]=V*d+y*a+S*m+R*W,n[3]=V*i+y*X+S*Z+R*L,V=l[4],y=l[5],S=l[6],R=l[7],n[4]=V*s+y*c+S*u+R*p,n[5]=V*e+y*o+S*h+R*G,n[6]=V*d+y*a+S*m+R*W,n[7]=V*i+y*X+S*Z+R*L,V=l[8],y=l[9],S=l[10],R=l[11],n[8]=V*s+y*c+S*u+R*p,n[9]=V*e+y*o+S*h+R*G,n[10]=V*d+y*a+S*m+R*W,n[11]=V*i+y*X+S*Z+R*L,V=l[12],y=l[13],S=l[14],R=l[15],n[12]=V*s+y*c+S*u+R*p,n[13]=V*e+y*o+S*h+R*G,n[14]=V*d+y*a+S*m+R*W,n[15]=V*i+y*X+S*Z+R*L,n}function ne(n,t,l){const s=l[0],e=l[1],d=l[2];let i,c,o,a,X,u,h,m,Z,p,G,W;return t===n?(n[12]=t[0]*s+t[4]*e+t[8]*d+t[12],n[13]=t[1]*s+t[5]*e+t[9]*d+t[13],n[14]=t[2]*s+t[6]*e+t[10]*d+t[14],n[15]=t[3]*s+t[7]*e+t[11]*d+t[15]):(i=t[0],c=t[1],o=t[2],a=t[3],X=t[4],u=t[5],h=t[6],m=t[7],Z=t[8],p=t[9],G=t[10],W=t[11],n[0]=i,n[1]=c,n[2]=o,n[3]=a,n[4]=X,n[5]=u,n[6]=h,n[7]=m,n[8]=Z,n[9]=p,n[10]=G,n[11]=W,n[12]=i*s+X*e+Z*d+t[12],n[13]=c*s+u*e+p*d+t[13],n[14]=o*s+h*e+G*d+t[14],n[15]=a*s+m*e+W*d+t[15]),n}function le(n,t,l){const s=l[0],e=l[1],d=l[2];return n[0]=t[0]*s,n[1]=t[1]*s,n[2]=t[2]*s,n[3]=t[3]*s,n[4]=t[4]*e,n[5]=t[5]*e,n[6]=t[6]*e,n[7]=t[7]*e,n[8]=t[8]*d,n[9]=t[9]*d,n[10]=t[10]*d,n[11]=t[11]*d,n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15],n}function se(n,t,l,s){let e=s[0],d=s[1],i=s[2],c=Math.sqrt(e*e+d*d+i*i),o,a,X,u,h,m,Z,p,G,W,L,V,y,S,R,T,g,M,z,H,J,I,f,O;return c<F?null:(c=1/c,e*=c,d*=c,i*=c,a=Math.sin(l),o=Math.cos(l),X=1-o,u=t[0],h=t[1],m=t[2],Z=t[3],p=t[4],G=t[5],W=t[6],L=t[7],V=t[8],y=t[9],S=t[10],R=t[11],T=e*e*X+o,g=d*e*X+i*a,M=i*e*X-d*a,z=e*d*X-i*a,H=d*d*X+o,J=i*d*X+e*a,I=e*i*X+d*a,f=d*i*X-e*a,O=i*i*X+o,n[0]=u*T+p*g+V*M,n[1]=h*T+G*g+y*M,n[2]=m*T+W*g+S*M,n[3]=Z*T+L*g+R*M,n[4]=u*z+p*H+V*J,n[5]=h*z+G*H+y*J,n[6]=m*z+W*H+S*J,n[7]=Z*z+L*H+R*J,n[8]=u*I+p*f+V*O,n[9]=h*I+G*f+y*O,n[10]=m*I+W*f+S*O,n[11]=Z*I+L*f+R*O,t!==n&&(n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15]),n)}function ee(n,t,l){const s=Math.sin(l),e=Math.cos(l),d=t[4],i=t[5],c=t[6],o=t[7],a=t[8],X=t[9],u=t[10],h=t[11];return t!==n&&(n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15]),n[4]=d*e+a*s,n[5]=i*e+X*s,n[6]=c*e+u*s,n[7]=o*e+h*s,n[8]=a*e-d*s,n[9]=X*e-i*s,n[10]=u*e-c*s,n[11]=h*e-o*s,n}function de(n,t,l){const s=Math.sin(l),e=Math.cos(l),d=t[0],i=t[1],c=t[2],o=t[3],a=t[8],X=t[9],u=t[10],h=t[11];return t!==n&&(n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15]),n[0]=d*e-a*s,n[1]=i*e-X*s,n[2]=c*e-u*s,n[3]=o*e-h*s,n[8]=d*s+a*e,n[9]=i*s+X*e,n[10]=c*s+u*e,n[11]=o*s+h*e,n}function ie(n,t,l){const s=Math.sin(l),e=Math.cos(l),d=t[0],i=t[1],c=t[2],o=t[3],a=t[4],X=t[5],u=t[6],h=t[7];return t!==n&&(n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15]),n[0]=d*e+a*s,n[1]=i*e+X*s,n[2]=c*e+u*s,n[3]=o*e+h*s,n[4]=a*e-d*s,n[5]=X*e-i*s,n[6]=u*e-c*s,n[7]=h*e-o*s,n}function J0(n,t){return n[0]=1,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=1,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=1,n[11]=0,n[12]=t[0],n[13]=t[1],n[14]=t[2],n[15]=1,n}function I0(n,t){return n[0]=t[0],n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=t[1],n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=t[2],n[11]=0,n[12]=0,n[13]=0,n[14]=0,n[15]=1,n}function k0(n,t,l){let s=l[0],e=l[1],d=l[2],i=Math.sqrt(s*s+e*e+d*d),c,o,a;return i<F?null:(i=1/i,s*=i,e*=i,d*=i,o=Math.sin(t),c=Math.cos(t),a=1-c,n[0]=s*s*a+c,n[1]=e*s*a+d*o,n[2]=d*s*a-e*o,n[3]=0,n[4]=s*e*a-d*o,n[5]=e*e*a+c,n[6]=d*e*a+s*o,n[7]=0,n[8]=s*d*a+e*o,n[9]=e*d*a-s*o,n[10]=d*d*a+c,n[11]=0,n[12]=0,n[13]=0,n[14]=0,n[15]=1,n)}function P0(n,t){const l=Math.sin(t),s=Math.cos(t);return n[0]=1,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=s,n[6]=l,n[7]=0,n[8]=0,n[9]=-l,n[10]=s,n[11]=0,n[12]=0,n[13]=0,n[14]=0,n[15]=1,n}function Q0(n,t){const l=Math.sin(t),s=Math.cos(t);return n[0]=s,n[1]=0,n[2]=-l,n[3]=0,n[4]=0,n[5]=1,n[6]=0,n[7]=0,n[8]=l,n[9]=0,n[10]=s,n[11]=0,n[12]=0,n[13]=0,n[14]=0,n[15]=1,n}function v0(n,t){const l=Math.sin(t),s=Math.cos(t);return n[0]=s,n[1]=l,n[2]=0,n[3]=0,n[4]=-l,n[5]=s,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=1,n[11]=0,n[12]=0,n[13]=0,n[14]=0,n[15]=1,n}function ce(n,t,l){const s=t[0],e=t[1],d=t[2],i=t[3],c=s+s,o=e+e,a=d+d,X=s*c,u=s*o,h=s*a,m=e*o,Z=e*a,p=d*a,G=i*c,W=i*o,L=i*a;return n[0]=1-(m+p),n[1]=u+L,n[2]=h-W,n[3]=0,n[4]=u-L,n[5]=1-(X+p),n[6]=Z+G,n[7]=0,n[8]=h+W,n[9]=Z-G,n[10]=1-(X+m),n[11]=0,n[12]=l[0],n[13]=l[1],n[14]=l[2],n[15]=1,n}function B0(n,t){const l=new Q(3),s=-t[0],e=-t[1],d=-t[2],i=t[3],c=t[4],o=t[5],a=t[6],X=t[7],u=s*s+e*e+d*d+i*i;return u>0?(l[0]=(c*i+X*s+o*d-a*e)*2/u,l[1]=(o*i+X*e+a*s-c*d)*2/u,l[2]=(a*i+X*d+c*e-o*s)*2/u):(l[0]=(c*i+X*s+o*d-a*e)*2,l[1]=(o*i+X*e+a*s-c*d)*2,l[2]=(a*i+X*d+c*e-o*s)*2),ce(n,t,l),n}function be(n,t){return n[0]=t[12],n[1]=t[13],n[2]=t[14],n}function oe(n,t){const l=t[0],s=t[1],e=t[2],d=t[4],i=t[5],c=t[6],o=t[8],a=t[9],X=t[10];return n[0]=Math.sqrt(l*l+s*s+e*e),n[1]=Math.sqrt(d*d+i*i+c*c),n[2]=Math.sqrt(o*o+a*a+X*X),n}function w0(n,t){const l=new Q(3);oe(l,t);const s=1/l[0],e=1/l[1],d=1/l[2],i=t[0]*s,c=t[1]*e,o=t[2]*d,a=t[4]*s,X=t[5]*e,u=t[6]*d,h=t[8]*s,m=t[9]*e,Z=t[10]*d,p=i+X+Z;let G=0;return p>0?(G=Math.sqrt(p+1)*2,n[3]=.25*G,n[0]=(u-m)/G,n[1]=(h-o)/G,n[2]=(c-a)/G):i>X&&i>Z?(G=Math.sqrt(1+i-X-Z)*2,n[3]=(u-m)/G,n[0]=.25*G,n[1]=(c+a)/G,n[2]=(h+o)/G):X>Z?(G=Math.sqrt(1+X-i-Z)*2,n[3]=(h-o)/G,n[0]=(c+a)/G,n[1]=.25*G,n[2]=(u+m)/G):(G=Math.sqrt(1+Z-i-X)*2,n[3]=(c-a)/G,n[0]=(h+o)/G,n[1]=(u+m)/G,n[2]=.25*G),n}function U0(n,t,l,s){t[0]=s[12],t[1]=s[13],t[2]=s[14];const e=s[0],d=s[1],i=s[2],c=s[4],o=s[5],a=s[6],X=s[8],u=s[9],h=s[10];l[0]=Math.sqrt(e*e+d*d+i*i),l[1]=Math.sqrt(c*c+o*o+a*a),l[2]=Math.sqrt(X*X+u*u+h*h);const m=1/l[0],Z=1/l[1],p=1/l[2],G=e*m,W=d*Z,L=i*p,V=c*m,y=o*Z,S=a*p,R=X*m,T=u*Z,g=h*p,M=G+y+g;let z=0;return M>0?(z=Math.sqrt(M+1)*2,n[3]=.25*z,n[0]=(S-T)/z,n[1]=(R-L)/z,n[2]=(W-V)/z):G>y&&G>g?(z=Math.sqrt(1+G-y-g)*2,n[3]=(S-T)/z,n[0]=.25*z,n[1]=(W+V)/z,n[2]=(R+L)/z):y>g?(z=Math.sqrt(1+y-G-g)*2,n[3]=(R-L)/z,n[0]=(W+V)/z,n[1]=.25*z,n[2]=(S+T)/z):(z=Math.sqrt(1+g-G-y)*2,n[3]=(W-V)/z,n[0]=(R+L)/z,n[1]=(S+T)/z,n[2]=.25*z),n}function j0(n,t,l,s){const e=t[0],d=t[1],i=t[2],c=t[3],o=e+e,a=d+d,X=i+i,u=e*o,h=e*a,m=e*X,Z=d*a,p=d*X,G=i*X,W=c*o,L=c*a,V=c*X,y=s[0],S=s[1],R=s[2];return n[0]=(1-(Z+G))*y,n[1]=(h+V)*y,n[2]=(m-L)*y,n[3]=0,n[4]=(h-V)*S,n[5]=(1-(u+G))*S,n[6]=(p+W)*S,n[7]=0,n[8]=(m+L)*R,n[9]=(p-W)*R,n[10]=(1-(u+Z))*R,n[11]=0,n[12]=l[0],n[13]=l[1],n[14]=l[2],n[15]=1,n}function E0(n,t,l,s,e){const d=t[0],i=t[1],c=t[2],o=t[3],a=d+d,X=i+i,u=c+c,h=d*a,m=d*X,Z=d*u,p=i*X,G=i*u,W=c*u,L=o*a,V=o*X,y=o*u,S=s[0],R=s[1],T=s[2],g=e[0],M=e[1],z=e[2],H=(1-(p+W))*S,J=(m+y)*S,I=(Z-V)*S,f=(m-y)*R,O=(1-(h+W))*R,Lt=(G+L)*R,xt=(Z+V)*T,ls=(G-L)*T,Un=(1-(h+p))*T;return n[0]=H,n[1]=J,n[2]=I,n[3]=0,n[4]=f,n[5]=O,n[6]=Lt,n[7]=0,n[8]=xt,n[9]=ls,n[10]=Un,n[11]=0,n[12]=l[0]+g-(H*g+f*M+xt*z),n[13]=l[1]+M-(J*g+O*M+ls*z),n[14]=l[2]+z-(I*g+Lt*M+Un*z),n[15]=1,n}function ae(n,t){const l=t[0],s=t[1],e=t[2],d=t[3],i=l+l,c=s+s,o=e+e,a=l*i,X=s*i,u=s*c,h=e*i,m=e*c,Z=e*o,p=d*i,G=d*c,W=d*o;return n[0]=1-u-Z,n[1]=X+W,n[2]=h-G,n[3]=0,n[4]=X-W,n[5]=1-a-Z,n[6]=m+p,n[7]=0,n[8]=h+G,n[9]=m-p,n[10]=1-a-u,n[11]=0,n[12]=0,n[13]=0,n[14]=0,n[15]=1,n}function Xe(n,t,l,s,e,d,i){const c=1/(l-t),o=1/(e-s),a=1/(d-i);return n[0]=d*2*c,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=d*2*o,n[6]=0,n[7]=0,n[8]=(l+t)*c,n[9]=(e+s)*o,n[10]=(i+d)*a,n[11]=-1,n[12]=0,n[13]=0,n[14]=i*d*2*a,n[15]=0,n}function ue(n,t,l,s,e){const d=1/Math.tan(t/2);if(n[0]=d/l,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=d,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[11]=-1,n[12]=0,n[13]=0,n[15]=0,e!=null&&e!==1/0){const i=1/(s-e);n[10]=(e+s)*i,n[14]=2*e*s*i}else n[10]=-1,n[14]=-2*s;return n}const re=ue;function O0(n,t,l,s,e){const d=1/Math.tan(t/2);if(n[0]=d/l,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=d,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[11]=-1,n[12]=0,n[13]=0,n[15]=0,e!=null&&e!==1/0){const i=1/(s-e);n[10]=e*i,n[14]=e*s*i}else n[10]=-1,n[14]=-s;return n}function D0(n,t,l,s){const e=Math.tan(t.upDegrees*Math.PI/180),d=Math.tan(t.downDegrees*Math.PI/180),i=Math.tan(t.leftDegrees*Math.PI/180),c=Math.tan(t.rightDegrees*Math.PI/180),o=2/(i+c),a=2/(e+d);return n[0]=o,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=a,n[6]=0,n[7]=0,n[8]=-((i-c)*o*.5),n[9]=(e-d)*a*.5,n[10]=s/(l-s),n[11]=-1,n[12]=0,n[13]=0,n[14]=s*l/(l-s),n[15]=0,n}function he(n,t,l,s,e,d,i){const c=1/(t-l),o=1/(s-e),a=1/(d-i);return n[0]=-2*c,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=-2*o,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=2*a,n[11]=0,n[12]=(t+l)*c,n[13]=(e+s)*o,n[14]=(i+d)*a,n[15]=1,n}const me=he;function A0(n,t,l,s,e,d,i){const c=1/(t-l),o=1/(s-e),a=1/(d-i);return n[0]=-2*c,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=-2*o,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=a,n[11]=0,n[12]=(t+l)*c,n[13]=(e+s)*o,n[14]=d*a,n[15]=1,n}function Ze(n,t,l,s){let e,d,i,c,o,a,X,u,h,m;const Z=t[0],p=t[1],G=t[2],W=s[0],L=s[1],V=s[2],y=l[0],S=l[1],R=l[2];return Math.abs(Z-y)<F&&Math.abs(p-S)<F&&Math.abs(G-R)<F?qs(n):(u=Z-y,h=p-S,m=G-R,e=1/Math.sqrt(u*u+h*h+m*m),u*=e,h*=e,m*=e,d=L*m-V*h,i=V*u-W*m,c=W*h-L*u,e=Math.sqrt(d*d+i*i+c*c),e?(e=1/e,d*=e,i*=e,c*=e):(d=0,i=0,c=0),o=h*c-m*i,a=m*d-u*c,X=u*i-h*d,e=Math.sqrt(o*o+a*a+X*X),e?(e=1/e,o*=e,a*=e,X*=e):(o=0,a=0,X=0),n[0]=d,n[1]=o,n[2]=u,n[3]=0,n[4]=i,n[5]=a,n[6]=h,n[7]=0,n[8]=c,n[9]=X,n[10]=m,n[11]=0,n[12]=-(d*Z+i*p+c*G),n[13]=-(o*Z+a*p+X*G),n[14]=-(u*Z+h*p+m*G),n[15]=1,n)}function _0(n,t,l,s){const e=t[0],d=t[1],i=t[2],c=s[0],o=s[1],a=s[2];let X=e-l[0],u=d-l[1],h=i-l[2],m=X*X+u*u+h*h;m>0&&(m=1/Math.sqrt(m),X*=m,u*=m,h*=m);let Z=o*h-a*u,p=a*X-c*h,G=c*u-o*X;return m=Z*Z+p*p+G*G,m>0&&(m=1/Math.sqrt(m),Z*=m,p*=m,G*=m),n[0]=Z,n[1]=p,n[2]=G,n[3]=0,n[4]=u*G-h*p,n[5]=h*Z-X*G,n[6]=X*p-u*Z,n[7]=0,n[8]=X,n[9]=u,n[10]=h,n[11]=0,n[12]=e,n[13]=d,n[14]=i,n[15]=1,n}function q0(n){return`mat4(${n[0]}, ${n[1]}, ${n[2]}, ${n[3]}, ${n[4]}, ${n[5]}, ${n[6]}, ${n[7]}, ${n[8]}, ${n[9]}, ${n[10]}, ${n[11]}, ${n[12]}, ${n[13]}, ${n[14]}, ${n[15]})`}function $0(n){return Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]+n[3]*n[3]+n[4]*n[4]+n[5]*n[5]+n[6]*n[6]+n[7]*n[7]+n[8]*n[8]+n[9]*n[9]+n[10]*n[10]+n[11]*n[11]+n[12]*n[12]+n[13]*n[13]+n[14]*n[14]+n[15]*n[15])}function tb(n,t,l){return n[0]=t[0]+l[0],n[1]=t[1]+l[1],n[2]=t[2]+l[2],n[3]=t[3]+l[3],n[4]=t[4]+l[4],n[5]=t[5]+l[5],n[6]=t[6]+l[6],n[7]=t[7]+l[7],n[8]=t[8]+l[8],n[9]=t[9]+l[9],n[10]=t[10]+l[10],n[11]=t[11]+l[11],n[12]=t[12]+l[12],n[13]=t[13]+l[13],n[14]=t[14]+l[14],n[15]=t[15]+l[15],n}function Ge(n,t,l){return n[0]=t[0]-l[0],n[1]=t[1]-l[1],n[2]=t[2]-l[2],n[3]=t[3]-l[3],n[4]=t[4]-l[4],n[5]=t[5]-l[5],n[6]=t[6]-l[6],n[7]=t[7]-l[7],n[8]=t[8]-l[8],n[9]=t[9]-l[9],n[10]=t[10]-l[10],n[11]=t[11]-l[11],n[12]=t[12]-l[12],n[13]=t[13]-l[13],n[14]=t[14]-l[14],n[15]=t[15]-l[15],n}function nb(n,t,l){return n[0]=t[0]*l,n[1]=t[1]*l,n[2]=t[2]*l,n[3]=t[3]*l,n[4]=t[4]*l,n[5]=t[5]*l,n[6]=t[6]*l,n[7]=t[7]*l,n[8]=t[8]*l,n[9]=t[9]*l,n[10]=t[10]*l,n[11]=t[11]*l,n[12]=t[12]*l,n[13]=t[13]*l,n[14]=t[14]*l,n[15]=t[15]*l,n}function lb(n,t,l,s){return n[0]=t[0]+l[0]*s,n[1]=t[1]+l[1]*s,n[2]=t[2]+l[2]*s,n[3]=t[3]+l[3]*s,n[4]=t[4]+l[4]*s,n[5]=t[5]+l[5]*s,n[6]=t[6]+l[6]*s,n[7]=t[7]+l[7]*s,n[8]=t[8]+l[8]*s,n[9]=t[9]+l[9]*s,n[10]=t[10]+l[10]*s,n[11]=t[11]+l[11]*s,n[12]=t[12]+l[12]*s,n[13]=t[13]+l[13]*s,n[14]=t[14]+l[14]*s,n[15]=t[15]+l[15]*s,n}function sb(n,t){return n[0]===t[0]&&n[1]===t[1]&&n[2]===t[2]&&n[3]===t[3]&&n[4]===t[4]&&n[5]===t[5]&&n[6]===t[6]&&n[7]===t[7]&&n[8]===t[8]&&n[9]===t[9]&&n[10]===t[10]&&n[11]===t[11]&&n[12]===t[12]&&n[13]===t[13]&&n[14]===t[14]&&n[15]===t[15]}function eb(n,t){const l=n[0],s=n[1],e=n[2],d=n[3],i=n[4],c=n[5],o=n[6],a=n[7],X=n[8],u=n[9],h=n[10],m=n[11],Z=n[12],p=n[13],G=n[14],W=n[15],L=t[0],V=t[1],y=t[2],S=t[3],R=t[4],T=t[5],g=t[6],M=t[7],z=t[8],H=t[9],J=t[10],I=t[11],f=t[12],O=t[13],Lt=t[14],xt=t[15];return Math.abs(l-L)<=F*Math.max(1,Math.abs(l),Math.abs(L))&&Math.abs(s-V)<=F*Math.max(1,Math.abs(s),Math.abs(V))&&Math.abs(e-y)<=F*Math.max(1,Math.abs(e),Math.abs(y))&&Math.abs(d-S)<=F*Math.max(1,Math.abs(d),Math.abs(S))&&Math.abs(i-R)<=F*Math.max(1,Math.abs(i),Math.abs(R))&&Math.abs(c-T)<=F*Math.max(1,Math.abs(c),Math.abs(T))&&Math.abs(o-g)<=F*Math.max(1,Math.abs(o),Math.abs(g))&&Math.abs(a-M)<=F*Math.max(1,Math.abs(a),Math.abs(M))&&Math.abs(X-z)<=F*Math.max(1,Math.abs(X),Math.abs(z))&&Math.abs(u-H)<=F*Math.max(1,Math.abs(u),Math.abs(H))&&Math.abs(h-J)<=F*Math.max(1,Math.abs(h),Math.abs(J))&&Math.abs(m-I)<=F*Math.max(1,Math.abs(m),Math.abs(I))&&Math.abs(Z-f)<=F*Math.max(1,Math.abs(Z),Math.abs(f))&&Math.abs(p-O)<=F*Math.max(1,Math.abs(p),Math.abs(O))&&Math.abs(G-Lt)<=F*Math.max(1,Math.abs(G),Math.abs(Lt))&&Math.abs(W-xt)<=F*Math.max(1,Math.abs(W),Math.abs(xt))}const db=Object.freeze(Object.defineProperty({__proto__:null,add:tb,adjoint:H0,clone:f0,copy:C0,create:T0,decompose:U0,determinant:ml,equals:eb,exactEquals:sb,frob:$0,fromQuat:ae,fromQuat2:B0,fromRotation:k0,fromRotationTranslation:ce,fromRotationTranslationScale:j0,fromRotationTranslationScaleOrigin:E0,fromScaling:I0,fromTranslation:J0,fromValues:F0,fromXRotation:P0,fromYRotation:Q0,fromZRotation:v0,frustum:Xe,getRotation:w0,getScaling:oe,getTranslation:be,identity:qs,invert:te,lookAt:Ze,mul:xn,multiply:xn,multiplyScalar:nb,multiplyScalarAndAdd:lb,ortho:me,orthoNO:he,orthoZO:A0,perspective:re,perspectiveFromFieldOfView:D0,perspectiveNO:ue,perspectiveZO:O0,rotate:se,rotateX:ee,rotateY:de,rotateZ:ie,scale:le,set:N0,str:q0,sub:Ge,subtract:Ge,targetTo:_0,translate:ne,transpose:$s},Symbol.toStringTag,{value:"Module"}));function pe(){const n=new Q(4);return Q!=Float32Array&&(n[0]=0,n[1]=0,n[2]=0,n[3]=0),n}function ib(n){const t=new Q(4);return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t}function cb(n,t,l,s){const e=new Q(4);return e[0]=n,e[1]=t,e[2]=l,e[3]=s,e}function bb(n,t){return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n}function ob(n,t,l,s,e){return n[0]=t,n[1]=l,n[2]=s,n[3]=e,n}function We(n,t,l){return n[0]=t[0]+l[0],n[1]=t[1]+l[1],n[2]=t[2]+l[2],n[3]=t[3]+l[3],n}function Ve(n,t,l){return n[0]=t[0]-l[0],n[1]=t[1]-l[1],n[2]=t[2]-l[2],n[3]=t[3]-l[3],n}function ye(n,t,l){return n[0]=t[0]*l[0],n[1]=t[1]*l[1],n[2]=t[2]*l[2],n[3]=t[3]*l[3],n}function Le(n,t,l){return n[0]=t[0]/l[0],n[1]=t[1]/l[1],n[2]=t[2]/l[2],n[3]=t[3]/l[3],n}function ab(n,t){return n[0]=Math.ceil(t[0]),n[1]=Math.ceil(t[1]),n[2]=Math.ceil(t[2]),n[3]=Math.ceil(t[3]),n}function Xb(n,t){return n[0]=Math.floor(t[0]),n[1]=Math.floor(t[1]),n[2]=Math.floor(t[2]),n[3]=Math.floor(t[3]),n}function ub(n,t,l){return n[0]=Math.min(t[0],l[0]),n[1]=Math.min(t[1],l[1]),n[2]=Math.min(t[2],l[2]),n[3]=Math.min(t[3],l[3]),n}function rb(n,t,l){return n[0]=Math.max(t[0],l[0]),n[1]=Math.max(t[1],l[1]),n[2]=Math.max(t[2],l[2]),n[3]=Math.max(t[3],l[3]),n}function hb(n,t){return n[0]=et(t[0]),n[1]=et(t[1]),n[2]=et(t[2]),n[3]=et(t[3]),n}function xe(n,t,l){return n[0]=t[0]*l,n[1]=t[1]*l,n[2]=t[2]*l,n[3]=t[3]*l,n}function mb(n,t,l,s){return n[0]=t[0]+l[0]*s,n[1]=t[1]+l[1]*s,n[2]=t[2]+l[2]*s,n[3]=t[3]+l[3]*s,n}function Re(n,t){const l=t[0]-n[0],s=t[1]-n[1],e=t[2]-n[2],d=t[3]-n[3];return Math.sqrt(l*l+s*s+e*e+d*d)}function Ke(n,t){const l=t[0]-n[0],s=t[1]-n[1],e=t[2]-n[2],d=t[3]-n[3];return l*l+s*s+e*e+d*d}function Zl(n){const t=n[0],l=n[1],s=n[2],e=n[3];return Math.sqrt(t*t+l*l+s*s+e*e)}function Gl(n){const t=n[0],l=n[1],s=n[2],e=n[3];return t*t+l*l+s*s+e*e}function Zb(n,t){return n[0]=-t[0],n[1]=-t[1],n[2]=-t[2],n[3]=-t[3],n}function Gb(n,t){return n[0]=1/t[0],n[1]=1/t[1],n[2]=1/t[2],n[3]=1/t[3],n}function Se(n,t){const l=t[0],s=t[1],e=t[2],d=t[3];let i=l*l+s*s+e*e+d*d;return i>0&&(i=1/Math.sqrt(i)),n[0]=l*i,n[1]=s*i,n[2]=e*i,n[3]=d*i,n}function ze(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]+n[3]*t[3]}function pb(n,t,l,s){const e=l[0]*s[1]-l[1]*s[0],d=l[0]*s[2]-l[2]*s[0],i=l[0]*s[3]-l[3]*s[0],c=l[1]*s[2]-l[2]*s[1],o=l[1]*s[3]-l[3]*s[1],a=l[2]*s[3]-l[3]*s[2],X=t[0],u=t[1],h=t[2],m=t[3];return n[0]=u*a-h*o+m*c,n[1]=-(X*a)+h*i-m*d,n[2]=X*o-u*i+m*e,n[3]=-(X*c)+u*d-h*e,n}function Ye(n,t,l,s){const e=t[0],d=t[1],i=t[2],c=t[3];return n[0]=e+s*(l[0]-e),n[1]=d+s*(l[1]-d),n[2]=i+s*(l[2]-i),n[3]=c+s*(l[3]-c),n}function Wb(n,t){t=t===void 0?1:t;let l,s,e,d,i,c;do l=Zt()*2-1,s=Zt()*2-1,i=l*l+s*s;while(i>=1);do e=Zt()*2-1,d=Zt()*2-1,c=e*e+d*d;while(c>=1);const o=Math.sqrt((1-i)/c);return n[0]=t*l,n[1]=t*s,n[2]=t*e*o,n[3]=t*d*o,n}function ge(n,t,l){const s=t[0],e=t[1],d=t[2],i=t[3];return n[0]=l[0]*s+l[4]*e+l[8]*d+l[12]*i,n[1]=l[1]*s+l[5]*e+l[9]*d+l[13]*i,n[2]=l[2]*s+l[6]*e+l[10]*d+l[14]*i,n[3]=l[3]*s+l[7]*e+l[11]*d+l[15]*i,n}function Me(n,t,l){const s=t[0],e=t[1],d=t[2],i=l[0],c=l[1],o=l[2],a=l[3],X=a*s+c*d-o*e,u=a*e+o*s-i*d,h=a*d+i*e-c*s,m=-i*s-c*e-o*d;return n[0]=X*a+m*-i+u*-o-h*-c,n[1]=u*a+m*-c+h*-i-X*-o,n[2]=h*a+m*-o+X*-c-u*-i,n[3]=t[3],n}function Vb(n){return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n}function yb(n){return`vec4(${n[0]}, ${n[1]}, ${n[2]}, ${n[3]})`}function Lb(n,t){return n[0]===t[0]&&n[1]===t[1]&&n[2]===t[2]&&n[3]===t[3]}function xb(n,t){const l=n[0],s=n[1],e=n[2],d=n[3],i=t[0],c=t[1],o=t[2],a=t[3];return Math.abs(l-i)<=F*Math.max(1,Math.abs(l),Math.abs(i))&&Math.abs(s-c)<=F*Math.max(1,Math.abs(s),Math.abs(c))&&Math.abs(e-o)<=F*Math.max(1,Math.abs(e),Math.abs(o))&&Math.abs(d-a)<=F*Math.max(1,Math.abs(d),Math.abs(a))}const Rb=Ve,Kb=ye,Sb=Le,zb=Re,Yb=Ke,gb=Zl,Mb=Gl,Tb=function(){const n=pe();return function(t,l,s,e,d,i){let c,o;for(l||(l=4),s||(s=0),e?o=Math.min(e*l+s,t.length):o=t.length,c=s;c<o;c+=l)n[0]=t[c],n[1]=t[c+1],n[2]=t[c+2],n[3]=t[c+3],d(n,n,i),t[c]=n[0],t[c+1]=n[1],t[c+2]=n[2],t[c+3]=n[3];return t}}(),fb=Object.freeze(Object.defineProperty({__proto__:null,add:We,ceil:ab,clone:ib,copy:bb,create:pe,cross:pb,dist:zb,distance:Re,div:Sb,divide:Le,dot:ze,equals:xb,exactEquals:Lb,floor:Xb,forEach:Tb,fromValues:cb,inverse:Gb,len:gb,length:Zl,lerp:Ye,max:rb,min:ub,mul:Kb,multiply:ye,negate:Zb,normalize:Se,random:Wb,round:hb,scale:xe,scaleAndAdd:mb,set:ob,sqrDist:Yb,sqrLen:Mb,squaredDistance:Ke,squaredLength:Gl,str:yb,sub:Rb,subtract:Ve,transformMat4:ge,transformQuat:Me,zero:Vb},Symbol.toStringTag,{value:"Module"}));var pl;(function(n){n[n.COL0ROW0=0]="COL0ROW0",n[n.COL0ROW1=1]="COL0ROW1",n[n.COL0ROW2=2]="COL0ROW2",n[n.COL0ROW3=3]="COL0ROW3",n[n.COL1ROW0=4]="COL1ROW0",n[n.COL1ROW1=5]="COL1ROW1",n[n.COL1ROW2=6]="COL1ROW2",n[n.COL1ROW3=7]="COL1ROW3",n[n.COL2ROW0=8]="COL2ROW0",n[n.COL2ROW1=9]="COL2ROW1",n[n.COL2ROW2=10]="COL2ROW2",n[n.COL2ROW3=11]="COL2ROW3",n[n.COL3ROW0=12]="COL3ROW0",n[n.COL3ROW1=13]="COL3ROW1",n[n.COL3ROW2=14]="COL3ROW2",n[n.COL3ROW3=15]="COL3ROW3"})(pl||(pl={}));const Cb=45*Math.PI/180,Fb=1,Wl=.1,Vl=500,Nb=Object.freeze([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]);class bt extends js{static get IDENTITY(){return Jb()}static get ZERO(){return Hb()}get ELEMENTS(){return 16}get RANK(){return 4}get INDICES(){return pl}constructor(t){super(-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0),arguments.length===1&&Array.isArray(t)?this.copy(t):this.identity()}copy(t){return this[0]=t[0],this[1]=t[1],this[2]=t[2],this[3]=t[3],this[4]=t[4],this[5]=t[5],this[6]=t[6],this[7]=t[7],this[8]=t[8],this[9]=t[9],this[10]=t[10],this[11]=t[11],this[12]=t[12],this[13]=t[13],this[14]=t[14],this[15]=t[15],this.check()}set(t,l,s,e,d,i,c,o,a,X,u,h,m,Z,p,G){return this[0]=t,this[1]=l,this[2]=s,this[3]=e,this[4]=d,this[5]=i,this[6]=c,this[7]=o,this[8]=a,this[9]=X,this[10]=u,this[11]=h,this[12]=m,this[13]=Z,this[14]=p,this[15]=G,this.check()}setRowMajor(t,l,s,e,d,i,c,o,a,X,u,h,m,Z,p,G){return this[0]=t,this[1]=d,this[2]=a,this[3]=m,this[4]=l,this[5]=i,this[6]=X,this[7]=Z,this[8]=s,this[9]=c,this[10]=u,this[11]=p,this[12]=e,this[13]=o,this[14]=h,this[15]=G,this.check()}toRowMajor(t){return t[0]=this[0],t[1]=this[4],t[2]=this[8],t[3]=this[12],t[4]=this[1],t[5]=this[5],t[6]=this[9],t[7]=this[13],t[8]=this[2],t[9]=this[6],t[10]=this[10],t[11]=this[14],t[12]=this[3],t[13]=this[7],t[14]=this[11],t[15]=this[15],t}identity(){return this.copy(Nb)}fromObject(t){return this.check()}fromQuaternion(t){return ae(this,t),this.check()}frustum(t){const{left:l,right:s,bottom:e,top:d,near:i=Wl,far:c=Vl}=t;return c===1/0?Ib(this,l,s,e,d,i):Xe(this,l,s,e,d,i,c),this.check()}lookAt(t){const{eye:l,center:s=[0,0,0],up:e=[0,1,0]}=t;return Ze(this,l,s,e),this.check()}ortho(t){const{left:l,right:s,bottom:e,top:d,near:i=Wl,far:c=Vl}=t;return me(this,l,s,e,d,i,c),this.check()}orthographic(t){const{fovy:l=Cb,aspect:s=Fb,focalDistance:e=1,near:d=Wl,far:i=Vl}=t;Te(l);const c=l/2,o=e*Math.tan(c),a=o*s;return this.ortho({left:-a,right:a,bottom:-o,top:o,near:d,far:i})}perspective(t){const{fovy:l=45*Math.PI/180,aspect:s=1,near:e=.1,far:d=500}=t;return Te(l),re(this,l,s,e,d),this.check()}determinant(){return ml(this)}getScale(t=[-0,-0,-0]){return t[0]=Math.sqrt(this[0]*this[0]+this[1]*this[1]+this[2]*this[2]),t[1]=Math.sqrt(this[4]*this[4]+this[5]*this[5]+this[6]*this[6]),t[2]=Math.sqrt(this[8]*this[8]+this[9]*this[9]+this[10]*this[10]),t}getTranslation(t=[-0,-0,-0]){return t[0]=this[12],t[1]=this[13],t[2]=this[14],t}getRotation(t,l){t=t||[-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0],l=l||[-0,-0,-0];const s=this.getScale(l),e=1/s[0],d=1/s[1],i=1/s[2];return t[0]=this[0]*e,t[1]=this[1]*d,t[2]=this[2]*i,t[3]=0,t[4]=this[4]*e,t[5]=this[5]*d,t[6]=this[6]*i,t[7]=0,t[8]=this[8]*e,t[9]=this[9]*d,t[10]=this[10]*i,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t}getRotationMatrix3(t,l){t=t||[-0,-0,-0,-0,-0,-0,-0,-0,-0],l=l||[-0,-0,-0];const s=this.getScale(l),e=1/s[0],d=1/s[1],i=1/s[2];return t[0]=this[0]*e,t[1]=this[1]*d,t[2]=this[2]*i,t[3]=this[4]*e,t[4]=this[5]*d,t[5]=this[6]*i,t[6]=this[8]*e,t[7]=this[9]*d,t[8]=this[10]*i,t}transpose(){return $s(this,this),this.check()}invert(){return te(this,this),this.check()}multiplyLeft(t){return xn(this,t,this),this.check()}multiplyRight(t){return xn(this,this,t),this.check()}rotateX(t){return ee(this,this,t),this.check()}rotateY(t){return de(this,this,t),this.check()}rotateZ(t){return ie(this,this,t),this.check()}rotateXYZ(t){return this.rotateX(t[0]).rotateY(t[1]).rotateZ(t[2])}rotateAxis(t,l){return se(this,this,t,l),this.check()}scale(t){return le(this,this,Array.isArray(t)?t:[t,t,t]),this.check()}translate(t){return ne(this,this,t),this.check()}transform(t,l){return t.length===4?(l=ge(l||[-0,-0,-0,-0],t,this),wt(l,4),l):this.transformAsPoint(t,l)}transformAsPoint(t,l){const{length:s}=t;let e;switch(s){case 2:e=nl(l||[-0,-0],t,this);break;case 3:e=Gn(l||[-0,-0,-0],t,this);break;default:throw new Error("Illegal vector")}return wt(e,t.length),e}transformAsVector(t,l){let s;switch(t.length){case 2:s=Ts(l||[-0,-0],t,this);break;case 3:s=fs(l||[-0,-0,-0],t,this);break;default:throw new Error("Illegal vector")}return wt(s,t.length),s}transformPoint(t,l){return this.transformAsPoint(t,l)}transformVector(t,l){return this.transformAsPoint(t,l)}transformDirection(t,l){return this.transformAsVector(t,l)}makeRotationX(t){return this.identity().rotateX(t)}makeTranslation(t,l,s){return this.identity().translate([t,l,s])}}let Rn,Kn;function Hb(){return Rn||(Rn=new bt([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]),Object.freeze(Rn)),Rn}function Jb(){return Kn||(Kn=new bt,Object.freeze(Kn)),Kn}function Te(n){if(n>Math.PI*2)throw Error("expected radians")}function Ib(n,t,l,s,e,d){const i=2*d/(l-t),c=2*d/(e-s),o=(l+t)/(l-t),a=(e+s)/(e-s),X=-1,u=-1,h=-2*d;return n[0]=i,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=c,n[6]=0,n[7]=0,n[8]=o,n[9]=a,n[10]=X,n[11]=u,n[12]=0,n[13]=0,n[14]=h,n[15]=0,n}function fe(){const n=new Q(4);return Q!=Float32Array&&(n[0]=0,n[1]=0,n[2]=0),n[3]=1,n}function kb(n){return n[0]=0,n[1]=0,n[2]=0,n[3]=1,n}function Ce(n,t,l){l=l*.5;const s=Math.sin(l);return n[0]=s*t[0],n[1]=s*t[1],n[2]=s*t[2],n[3]=Math.cos(l),n}function Fe(n,t,l){const s=t[0],e=t[1],d=t[2],i=t[3],c=l[0],o=l[1],a=l[2],X=l[3];return n[0]=s*X+i*c+e*a-d*o,n[1]=e*X+i*o+d*c-s*a,n[2]=d*X+i*a+s*o-e*c,n[3]=i*X-s*c-e*o-d*a,n}function Pb(n,t,l){l*=.5;const s=t[0],e=t[1],d=t[2],i=t[3],c=Math.sin(l),o=Math.cos(l);return n[0]=s*o+i*c,n[1]=e*o+d*c,n[2]=d*o-e*c,n[3]=i*o-s*c,n}function Qb(n,t,l){l*=.5;const s=t[0],e=t[1],d=t[2],i=t[3],c=Math.sin(l),o=Math.cos(l);return n[0]=s*o-d*c,n[1]=e*o+i*c,n[2]=d*o+s*c,n[3]=i*o-e*c,n}function vb(n,t,l){l*=.5;const s=t[0],e=t[1],d=t[2],i=t[3],c=Math.sin(l),o=Math.cos(l);return n[0]=s*o+e*c,n[1]=e*o-s*c,n[2]=d*o+i*c,n[3]=i*o-d*c,n}function Bb(n,t){const l=t[0],s=t[1],e=t[2];return n[0]=l,n[1]=s,n[2]=e,n[3]=Math.sqrt(Math.abs(1-l*l-s*s-e*e)),n}function Sn(n,t,l,s){const e=t[0],d=t[1],i=t[2],c=t[3];let o=l[0],a=l[1],X=l[2],u=l[3],h,m,Z,p,G;return h=e*o+d*a+i*X+c*u,h<0&&(h=-h,o=-o,a=-a,X=-X,u=-u),1-h>F?(m=Math.acos(h),G=Math.sin(m),Z=Math.sin((1-s)*m)/G,p=Math.sin(s*m)/G):(Z=1-s,p=s),n[0]=Z*e+p*o,n[1]=Z*d+p*a,n[2]=Z*i+p*X,n[3]=Z*c+p*u,n}function wb(n,t){const l=t[0],s=t[1],e=t[2],d=t[3],i=l*l+s*s+e*e+d*d,c=i?1/i:0;return n[0]=-l*c,n[1]=-s*c,n[2]=-e*c,n[3]=d*c,n}function Ub(n,t){return n[0]=-t[0],n[1]=-t[1],n[2]=-t[2],n[3]=t[3],n}function yl(n,t){const l=t[0]+t[4]+t[8];let s;if(l>0)s=Math.sqrt(l+1),n[3]=.5*s,s=.5/s,n[0]=(t[5]-t[7])*s,n[1]=(t[6]-t[2])*s,n[2]=(t[1]-t[3])*s;else{let e=0;t[4]>t[0]&&(e=1),t[8]>t[e*3+e]&&(e=2);const d=(e+1)%3,i=(e+2)%3;s=Math.sqrt(t[e*3+e]-t[d*3+d]-t[i*3+i]+1),n[e]=.5*s,s=.5/s,n[3]=(t[d*3+i]-t[i*3+d])*s,n[d]=(t[d*3+e]+t[e*3+d])*s,n[i]=(t[i*3+e]+t[e*3+i])*s}return n}const jb=We,Eb=xe,Ob=ze,Db=Ye,Ab=Zl,_b=Gl,Ne=Se,qb=function(){const n=sl(),t=el(1,0,0),l=el(0,1,0);return function(s,e,d){const i=Ut(e,d);return i<-.999999?(St(n,t,e),Us(n)<1e-6&&St(n,l,e),Ps(n,n),Ce(s,n,Math.PI),s):i>.999999?(s[0]=0,s[1]=0,s[2]=0,s[3]=1,s):(St(n,e,d),s[0]=n[0],s[1]=n[1],s[2]=n[2],s[3]=1+i,Ne(s,s))}}();(function(){const n=fe(),t=fe();return function(l,s,e,d,i,c){return Sn(n,s,i,c),Sn(t,e,d,c),Sn(l,n,t,2*c*(1-c)),l}})(),function(){const n=Es();return function(t,l,s,e){return n[0]=s[0],n[3]=s[1],n[6]=s[2],n[1]=e[0],n[4]=e[1],n[7]=e[2],n[2]=-l[0],n[5]=-l[1],n[8]=-l[2],Ne(t,yl(t,n))}}();const $b=[0,0,0,1];class Yt extends mn{constructor(t=0,l=0,s=0,e=1){super(-0,-0,-0,-0),Array.isArray(t)&&arguments.length===1?this.copy(t):this.set(t,l,s,e)}copy(t){return this[0]=t[0],this[1]=t[1],this[2]=t[2],this[3]=t[3],this.check()}set(t,l,s,e){return this[0]=t,this[1]=l,this[2]=s,this[3]=e,this.check()}fromObject(t){return this[0]=t.x,this[1]=t.y,this[2]=t.z,this[3]=t.w,this.check()}fromMatrix3(t){return yl(this,t),this.check()}fromAxisRotation(t,l){return Ce(this,t,l),this.check()}identity(){return kb(this),this.check()}setAxisAngle(t,l){return this.fromAxisRotation(t,l)}get ELEMENTS(){return 4}get x(){return this[0]}set x(t){this[0]=C(t)}get y(){return this[1]}set y(t){this[1]=C(t)}get z(){return this[2]}set z(t){this[2]=C(t)}get w(){return this[3]}set w(t){this[3]=C(t)}len(){return Ab(this)}lengthSquared(){return _b(this)}dot(t){return Ob(this,t)}rotationTo(t,l){return qb(this,t,l),this.check()}add(t){return jb(this,this,t),this.check()}calculateW(){return Bb(this,this),this.check()}conjugate(){return Ub(this,this),this.check()}invert(){return wb(this,this),this.check()}lerp(t,l,s){return s===void 0?this.lerp(this,t,l):(Db(this,t,l,s),this.check())}multiplyRight(t){return Fe(this,this,t),this.check()}multiplyLeft(t){return Fe(this,t,this),this.check()}normalize(){const t=this.len(),l=t>0?1/t:0;return this[0]=this[0]*l,this[1]=this[1]*l,this[2]=this[2]*l,this[3]=this[3]*l,t===0&&(this[3]=1),this.check()}rotateX(t){return Pb(this,this,t),this.check()}rotateY(t){return Qb(this,this,t),this.check()}rotateZ(t){return vb(this,this,t),this.check()}scale(t){return Eb(this,this,t),this.check()}slerp(t,l,s){let e,d,i;switch(arguments.length){case 1:({start:e=$b,target:d,ratio:i}=t);break;case 2:e=this,d=t,i=l;break;default:e=t,d=l,i=s}return Sn(this,e,d,i),this.check()}transformVector4(t,l=new ct){return Me(l,t,this),wt(l,4)}lengthSq(){return this.lengthSquared()}setFromAxisAngle(t,l){return this.setAxisAngle(t,l)}premultiply(t){return this.multiplyLeft(t)}multiply(t){return this.multiplyRight(t)}}const zn="Unknown Euler angle order",gt=.99999;var w;(function(n){n[n.ZYX=0]="ZYX",n[n.YXZ=1]="YXZ",n[n.XZY=2]="XZY",n[n.ZXY=3]="ZXY",n[n.YZX=4]="YZX",n[n.XYZ=5]="XYZ"})(w||(w={}));class v extends mn{static get ZYX(){return w.ZYX}static get YXZ(){return w.YXZ}static get XZY(){return w.XZY}static get ZXY(){return w.ZXY}static get YZX(){return w.YZX}static get XYZ(){return w.XYZ}static get RollPitchYaw(){return w.ZYX}static get DefaultOrder(){return w.ZYX}static get RotationOrders(){return w}static rotationOrder(t){return w[t]}get ELEMENTS(){return 4}constructor(t=0,l=0,s=0,e=v.DefaultOrder){super(-0,-0,-0,-0),arguments.length>0&&Array.isArray(arguments[0])?this.fromVector3(...arguments):this.set(t,l,s,e)}fromQuaternion(t){const[l,s,e,d]=t,i=s*s,c=-2*(i+e*e)+1,o=2*(l*s+d*e);let a=-2*(l*e-d*s);const X=2*(s*e+d*l),u=-2*(l*l+i)+1;a=a>1?1:a,a=a<-1?-1:a;const h=Math.atan2(X,u),m=Math.asin(a),Z=Math.atan2(o,c);return this.set(h,m,Z,v.RollPitchYaw)}fromObject(t){throw new Error("not implemented")}copy(t){return this[0]=t[0],this[1]=t[1],this[2]=t[2],this[3]=Number.isFinite(t[3])||this.order,this.check()}set(t=0,l=0,s=0,e){return this[0]=t,this[1]=l,this[2]=s,this[3]=Number.isFinite(e)?e:this[3],this.check()}validate(){return to(this[3])&&Number.isFinite(this[0])&&Number.isFinite(this[1])&&Number.isFinite(this[2])}toArray(t=[],l=0){return t[l]=this[0],t[l+1]=this[1],t[l+2]=this[2],t}toArray4(t=[],l=0){return t[l]=this[0],t[l+1]=this[1],t[l+2]=this[2],t[l+3]=this[3],t}toVector3(t=[-0,-0,-0]){return t[0]=this[0],t[1]=this[1],t[2]=this[2],t}get x(){return this[0]}set x(t){this[0]=C(t)}get y(){return this[1]}set y(t){this[1]=C(t)}get z(){return this[2]}set z(t){this[2]=C(t)}get alpha(){return this[0]}set alpha(t){this[0]=C(t)}get beta(){return this[1]}set beta(t){this[1]=C(t)}get gamma(){return this[2]}set gamma(t){this[2]=C(t)}get phi(){return this[0]}set phi(t){this[0]=C(t)}get theta(){return this[1]}set theta(t){this[1]=C(t)}get psi(){return this[2]}set psi(t){this[2]=C(t)}get roll(){return this[0]}set roll(t){this[0]=C(t)}get pitch(){return this[1]}set pitch(t){this[1]=C(t)}get yaw(){return this[2]}set yaw(t){this[2]=C(t)}get order(){return this[3]}set order(t){this[3]=no(t)}fromVector3(t,l){return this.set(t[0],t[1],t[2],Number.isFinite(l)?l:this[3])}fromArray(t,l=0){return this[0]=t[0+l],this[1]=t[1+l],this[2]=t[2+l],t[3]!==void 0&&(this[3]=t[3]),this.check()}fromRollPitchYaw(t,l,s){return this.set(t,l,s,w.ZYX)}fromRotationMatrix(t,l=v.DefaultOrder){return this._fromRotationMatrix(t,l),this.check()}getRotationMatrix(t){return this._getRotationMatrix(t)}getQuaternion(){const t=new Yt;switch(this[3]){case w.XYZ:return t.rotateX(this[0]).rotateY(this[1]).rotateZ(this[2]);case w.YXZ:return t.rotateY(this[0]).rotateX(this[1]).rotateZ(this[2]);case w.ZXY:return t.rotateZ(this[0]).rotateX(this[1]).rotateY(this[2]);case w.ZYX:return t.rotateZ(this[0]).rotateY(this[1]).rotateX(this[2]);case w.YZX:return t.rotateY(this[0]).rotateZ(this[1]).rotateX(this[2]);case w.XZY:return t.rotateX(this[0]).rotateZ(this[1]).rotateY(this[2]);default:throw new Error(zn)}}_fromRotationMatrix(t,l=v.DefaultOrder){const s=t[0],e=t[4],d=t[8],i=t[1],c=t[5],o=t[9],a=t[2],X=t[6],u=t[10];switch(l=l||this[3],l){case v.XYZ:this[1]=Math.asin(Rt(d,-1,1)),Math.abs(d)<gt?(this[0]=Math.atan2(-o,u),this[2]=Math.atan2(-e,s)):(this[0]=Math.atan2(X,c),this[2]=0);break;case v.YXZ:this[0]=Math.asin(-Rt(o,-1,1)),Math.abs(o)<gt?(this[1]=Math.atan2(d,u),this[2]=Math.atan2(i,c)):(this[1]=Math.atan2(-a,s),this[2]=0);break;case v.ZXY:this[0]=Math.asin(Rt(X,-1,1)),Math.abs(X)<gt?(this[1]=Math.atan2(-a,u),this[2]=Math.atan2(-e,c)):(this[1]=0,this[2]=Math.atan2(i,s));break;case v.ZYX:this[1]=Math.asin(-Rt(a,-1,1)),Math.abs(a)<gt?(this[0]=Math.atan2(X,u),this[2]=Math.atan2(i,s)):(this[0]=0,this[2]=Math.atan2(-e,c));break;case v.YZX:this[2]=Math.asin(Rt(i,-1,1)),Math.abs(i)<gt?(this[0]=Math.atan2(-o,c),this[1]=Math.atan2(-a,s)):(this[0]=0,this[1]=Math.atan2(d,u));break;case v.XZY:this[2]=Math.asin(-Rt(e,-1,1)),Math.abs(e)<gt?(this[0]=Math.atan2(X,c),this[1]=Math.atan2(d,s)):(this[0]=Math.atan2(-o,u),this[1]=0);break;default:throw new Error(zn)}return this[3]=l,this}_getRotationMatrix(t){const l=t||[-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0],s=this.x,e=this.y,d=this.z,i=Math.cos(s),c=Math.cos(e),o=Math.cos(d),a=Math.sin(s),X=Math.sin(e),u=Math.sin(d);switch(this[3]){case v.XYZ:{const h=i*o,m=i*u,Z=a*o,p=a*u;l[0]=c*o,l[4]=-c*u,l[8]=X,l[1]=m+Z*X,l[5]=h-p*X,l[9]=-a*c,l[2]=p-h*X,l[6]=Z+m*X,l[10]=i*c;break}case v.YXZ:{const h=c*o,m=c*u,Z=X*o,p=X*u;l[0]=h+p*a,l[4]=Z*a-m,l[8]=i*X,l[1]=i*u,l[5]=i*o,l[9]=-a,l[2]=m*a-Z,l[6]=p+h*a,l[10]=i*c;break}case v.ZXY:{const h=c*o,m=c*u,Z=X*o,p=X*u;l[0]=h-p*a,l[4]=-i*u,l[8]=Z+m*a,l[1]=m+Z*a,l[5]=i*o,l[9]=p-h*a,l[2]=-i*X,l[6]=a,l[10]=i*c;break}case v.ZYX:{const h=i*o,m=i*u,Z=a*o,p=a*u;l[0]=c*o,l[4]=Z*X-m,l[8]=h*X+p,l[1]=c*u,l[5]=p*X+h,l[9]=m*X-Z,l[2]=-X,l[6]=a*c,l[10]=i*c;break}case v.YZX:{const h=i*c,m=i*X,Z=a*c,p=a*X;l[0]=c*o,l[4]=p-h*u,l[8]=Z*u+m,l[1]=u,l[5]=i*o,l[9]=-a*o,l[2]=-X*o,l[6]=m*u+Z,l[10]=h-p*u;break}case v.XZY:{const h=i*c,m=i*X,Z=a*c,p=a*X;l[0]=c*o,l[4]=-u,l[8]=X*o,l[1]=h*u+p,l[5]=i*o,l[9]=m*u-Z,l[2]=Z*u-m,l[6]=a*o,l[10]=p*u+h;break}default:throw new Error(zn)}return l[3]=0,l[7]=0,l[11]=0,l[12]=0,l[13]=0,l[14]=0,l[15]=1,l}toQuaternion(){const t=Math.cos(this.yaw*.5),l=Math.sin(this.yaw*.5),s=Math.cos(this.roll*.5),e=Math.sin(this.roll*.5),d=Math.cos(this.pitch*.5),i=Math.sin(this.pitch*.5),c=t*s*d+l*e*i,o=t*e*d-l*s*i,a=t*s*i+l*e*d,X=l*s*d-t*e*i;return new Yt(o,a,X,c)}}function to(n){return n>=0&&n<6}function no(n){if(n<0&&n>=6)throw new Error(zn);return n}const lo=.1,so=1e-12,eo=1e-15;var jt=(n=>(n.equal="equal",n.intersect="intersect",n.intersectEqual="intersectEqual",n))(jt||{});(n=>{function t(l){let s;switch(l){case"equal":s=(e,d)=>e===d;case"intersect":s=(e,d)=>e&d;default:s=(e,d)=>(e&d)===e}return s}n.getEqualFun=t})(jt||(jt={}));const He=!0,io=!1,Et={CCW:-1,CW:1,NOT_ORIENTABLE:0},co=2*Math.PI,Yn=1,Je=0,q=2,bo=3,oo=4,ao=1,Xo=2,Ll=0,Ot=1,Mt=2;var gn=Object.freeze({__proto__:null,BOUNDARY:q,CCW:He,CONTAINS:bo,CW:io,END_VERTEX:Mt,INSIDE:Yn,INTERLACE:oo,NOT_VERTEX:Ll,ORIENTATION:Et,OUTSIDE:Je,OVERLAP_OPPOSITE:Xo,OVERLAP_SAME:ao,PIx2:co,START_VERTEX:Ot});let $=1e-6;function Ie(n){$=n}function ke(){return $}const uo=3;function xl(n){return n<$&&n>-$}function Gt(n,t){return n-t<$&&n-t>-$}function Pe(n,t){return n-t>$}function ro(n,t){return n-t>-$}function Qe(n,t){return n-t<-$}function ho(n,t){return n-t<$}var mo=Object.freeze({__proto__:null,DECIMALS:uo,EQ:Gt,EQ_0:xl,GE:ro,GT:Pe,LE:ho,LT:Qe,getTolerance:ke,setTolerance:Ie});let b={Utils:mo,Errors:void 0,Matrix:void 0,Planar_set:void 0,Point:void 0,Vector:void 0,Line:void 0,Circle:void 0,Segment:void 0,Arc:void 0,Box:void 0,Edge:void 0,Face:void 0,Ray:void 0,Ray_shooting:void 0,Multiline:void 0,Polygon:void 0,Distance:void 0,Inversion:void 0};for(let n in gn)b[n]=gn[n];Object.defineProperty(b,"DP_TOL",{get:function(){return ke()},set:function(n){Ie(n)}});class P{static get ILLEGAL_PARAMETERS(){return new ReferenceError("Illegal Parameters")}static get ZERO_DIVISION(){return new Error("Zero division")}static get UNRESOLVED_BOUNDARY_CONFLICT(){return new Error("Unresolved boundary conflict in boolean operation")}static get INFINITE_LOOP(){return new Error("Infinite loop")}static get CANNOT_COMPLETE_BOOLEAN_OPERATION(){return new Error("Cannot complete boolean operation")}static get CANNOT_INVOKE_ABSTRACT_METHOD(){return new Error("Abstract method cannot be invoked")}static get OPERATION_IS_NOT_SUPPORTED(){return new Error("Operation is not supported")}static get UNSUPPORTED_SHAPE_TYPE(){return new Error("Unsupported shape type")}}b.Errors=P;class Rl{constructor(t,l){this.first=t,this.last=l||this.first}[Symbol.iterator](){let t;return{next:()=>(t=t?t.next:this.first,{value:t,done:t===void 0})}}get size(){let t=0;for(let l of this)t++;return t}toArray(t=void 0,l=void 0){let s=[],e=t||this.first,d=l||this.last,i=e;if(i===void 0)return s;do s.push(i),i=i.next;while(i!==d.next);return s}append(t){return this.isEmpty()?this.first=t:(t.prev=this.last,this.last.next=t),this.last=t,this.last.next=void 0,this.first.prev=void 0,this}insert(t,l){if(this.isEmpty())this.first=t,this.last=t;else if(l==null)t.next=this.first,this.first.prev=t,this.first=t;else{let s=l.next;l.next=t,s&&(s.prev=t),t.prev=l,t.next=s,this.last===l&&(this.last=t)}return this.last.next=void 0,this.first.prev=void 0,this}remove(t){return t===this.first&&t===this.last?(this.first=void 0,this.last=void 0):(t.prev&&(t.prev.next=t.next),t.next&&(t.next.prev=t.prev),t===this.first&&(this.first=t.next),t===this.last&&(this.last=t.prev)),this}isEmpty(){return this.first===void 0}static testInfiniteLoop(t){let l=t,s=t;do{if(l!=t&&l===s)throw P.INFINITE_LOOP;l=l.next,s=s.next.next}while(l!=t)}}const ve={stroke:"black"};class Zo{constructor(t=ve){for(const l in t)this[l]=t[l];this.stroke=t.stroke??ve.stroke}toAttributesString(){return Object.keys(this).reduce((t,l)=>t+(this[l]!==void 0?this.toAttrString(l,this[l]):""),"")}toAttrString(t,l){const s=t==="className"?"class":this.convertCamelToKebabCase(t);return l===null?`${s} `:`${s}="${l.toString()}" `}convertCamelToKebabCase(t){return t.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g).join("-").toLowerCase()}}function pt(n){return new Zo(n).toAttributesString()}function Tt(n,t){let l=[],[s,e,d]=n.standard,[i,c,o]=t.standard,a=s*c-e*i,X=d*c-e*o,u=s*o-d*i;if(!b.Utils.EQ_0(a)){let h,m;e===0?(h=d/s,m=u/a):c===0?(h=o/i,m=u/a):s===0?(h=X/a,m=d/e):i===0?(h=X/a,m=o/c):(h=X/a,m=u/a),l.push(new b.Point(h,m))}return l}function Wt(n,t){let l=[],s=t.pc.projectionOn(n),e=t.pc.distanceTo(s)[0];if(b.Utils.EQ(e,t.r))l.push(s);else if(b.Utils.LT(e,t.r)){let d=Math.sqrt(t.r*t.r-e*e),i,c;i=n.norm.rotate90CCW().multiply(d),c=s.translate(i),l.push(c),i=n.norm.rotate90CW().multiply(d),c=s.translate(i),l.push(c)}return l}function ft(n,t){let l=[];for(let s of t.toSegments()){let e=Dt(s,n);for(let d of e)qe(d,l)||l.push(d)}return l}function Mn(n,t){let l=[];if(ft(n,t.box).length===0)return l;let s=new b.Circle(t.pc,t.r),e=Wt(n,s);for(let d of e)d.on(t)&&l.push(d);return l}function Dt(n,t){let l=[];if(n.ps.on(t)&&l.push(n.ps),n.pe.on(t)&&!n.isZeroLength()&&l.push(n.pe),l.length>0||n.isZeroLength()||n.ps.leftTo(t)&&n.pe.leftTo(t)||!n.ps.leftTo(t)&&!n.pe.leftTo(t))return l;let s=new b.Line(n.ps,n.pe);return Tt(s,t)}function Tn(n,t){let l=[];if(n.isZeroLength())return n.ps.on(t)&&l.push(n.ps),l;if(t.isZeroLength())return t.ps.on(n)&&l.push(t.ps),l;let s=new b.Line(n.ps,n.pe),e=new b.Line(t.ps,t.pe);if(s.incidentTo(e))n.ps.on(t)&&l.push(n.ps),n.pe.on(t)&&l.push(n.pe),t.ps.on(n)&&!t.ps.equalTo(n.ps)&&!t.ps.equalTo(n.pe)&&l.push(t.ps),t.pe.on(n)&&!t.pe.equalTo(n.ps)&&!t.pe.equalTo(n.pe)&&l.push(t.pe);else{let d=Tt(s,e);d.length>0&&Be(d[0],n)&&Be(d[0],t)&&l.push(d[0])}return l}function Be(n,t){const l=t.box;return b.Utils.LE(n.x,l.xmax)&&b.Utils.GE(n.x,l.xmin)&&b.Utils.LE(n.y,l.ymax)&&b.Utils.GE(n.y,l.ymin)}function fn(n,t){let l=[];if(n.isZeroLength()){let[d,i]=n.ps.distanceTo(t.pc);return b.Utils.EQ(d,t.r)&&l.push(n.ps),l}let s=new b.Line(n.ps,n.pe),e=Wt(s,t);for(let d of e)d.on(n)&&l.push(d);return l}function Ct(n,t){let l=[];if(n.isZeroLength())return n.ps.on(t)&&l.push(n.ps),l;let s=new b.Line(n.ps,n.pe),e=new b.Circle(t.pc,t.r),d=Wt(s,e);for(let i of d)i.on(n)&&i.on(t)&&l.push(i);return l}function Go(n,t){let l=[];for(let s of t.toSegments()){let e=Tn(s,n);for(let d of e)l.push(d)}return l}function we(n,t){let l=[],s=new b.Vector(n.pc,t.pc),e=n.r,d=t.r;if(b.Utils.EQ_0(e)||b.Utils.EQ_0(d))return l;if(b.Utils.EQ_0(s.x)&&b.Utils.EQ_0(s.y)&&b.Utils.EQ(e,d))return l.push(n.pc.translate(-e,0)),l;let i=n.pc.distanceTo(t.pc)[0];if(b.Utils.GT(i,e+d)||b.Utils.LT(i,Math.abs(e-d)))return l;s.x/=i,s.y/=i;let c;if(b.Utils.EQ(i,e+d)||b.Utils.EQ(i,Math.abs(e-d)))return c=n.pc.translate(e*s.x,e*s.y),l.push(c),l;let o=e*e/(2*i)-d*d/(2*i)+i/2,a=n.pc.translate(o*s.x,o*s.y),X=Math.sqrt(e*e-o*o);return c=a.translate(s.rotate90CCW().multiply(X)),l.push(c),c=a.translate(s.rotate90CW().multiply(X)),l.push(c),l}function po(n,t){let l=[];for(let s of t.toSegments()){let e=fn(s,n);for(let d of e)l.push(d)}return l}function Ue(n,t){let l=[];if(n.pc.equalTo(t.pc)&&b.Utils.EQ(n.r,t.r)){let i;return i=n.start,i.on(t)&&l.push(i),i=n.end,i.on(t)&&l.push(i),i=t.start,i.on(n)&&l.push(i),i=t.end,i.on(n)&&l.push(i),l}let s=new b.Circle(n.pc,n.r),e=new b.Circle(t.pc,t.r),d=s.intersect(e);for(let i of d)i.on(n)&&i.on(t)&&l.push(i);return l}function Kl(n,t){let l=[];if(t.pc.equalTo(n.pc)&&b.Utils.EQ(t.r,n.r))return l.push(n.start),l.push(n.end),l;let s=t,e=new b.Circle(n.pc,n.r),d=we(s,e);for(let i of d)i.on(n)&&l.push(i);return l}function Wo(n,t){let l=[];for(let s of t.toSegments()){let e=Ct(s,n);for(let d of e)l.push(d)}return l}function je(n,t){return n.isSegment?Tn(n.shape,t):Ct(t,n.shape)}function Ee(n,t){return n.isSegment?Ct(n.shape,t):Ue(n.shape,t)}function Oe(n,t){return n.isSegment?Dt(n.shape,t):Mn(t,n.shape)}function Vo(n,t){return n.isSegment?Yl(t,n.shape):gl(t,n.shape)}function yo(n,t){return n.isSegment?fn(n.shape,t):Kl(n.shape,t)}function Sl(n,t){let l=[];for(let s of t.edges)for(let e of je(s,n))l.push(e);return l}function zl(n,t){let l=[];for(let s of t.edges)for(let e of Ee(s,n))l.push(e);return l}function At(n,t){let l=[];if(t.isEmpty())return l;for(let s of t.edges)for(let e of Oe(s,n))qe(e,l)||l.push(e);return n.sortPoints(l)}function De(n,t){let l=[];if(t.isEmpty())return l;for(let s of t.edges)for(let e of yo(s,n))l.push(e);return l}function Ae(n,t){return n.isSegment?je(t,n.shape):n.isArc?Ee(t,n.shape):n.isLine?Oe(t,n.shape):n.isRay?Vo(t,n.shape):[]}function _e(n,t){let l=[];if(t.isEmpty()||n.shape.box.not_intersect(t.box))return l;let s=t.edges.search(n.shape.box);for(let e of s)l=[...l,...Ae(n,e)];return l}function Lo(n,t){let l=[];if(t.isEmpty()||n.size===0)return l;for(let s of n)l=[...l,..._e(s,t)];return l}function xo(n,t){let l=[];if(n.isEmpty()||t.isEmpty()||n.box.not_intersect(t.box))return l;for(let s of n.edges)l=[...l,..._e(s,t)];return l}function Ro(n,t){return n instanceof b.Line?At(n,t):n instanceof b.Segment?Sl(n,t):n instanceof b.Arc?zl(n,t):[]}function qe(n,t){return t.some(l=>l.equalTo(n))}function ot(n){return new b.Line(n.start,n.norm)}function Yl(n,t){return Dt(t,ot(n)).filter(l=>n.contains(l))}function gl(n,t){return Mn(ot(n),t).filter(l=>n.contains(l))}function $e(n,t){return Wt(ot(n),t).filter(l=>n.contains(l))}function Ko(n,t){return ft(ot(n),t).filter(l=>n.contains(l))}function td(n,t){return Tt(ot(n),t).filter(l=>n.contains(l))}function So(n,t){return Tt(ot(n),ot(t)).filter(l=>n.contains(l)).filter(l=>t.contains(l))}function nd(n,t){return At(ot(n),t).filter(l=>n.contains(l))}function ld(n,t){if(n.intersect&&n.intersect instanceof Function)return n.intersect(t);throw P.UNSUPPORTED_SHAPE_TYPE}function Ft(n,t){let l=[];for(let s of t)l=[...l,...ld(n,s.shape)];return l}function zo(n,t){let l=[];for(let s of n)for(let e of t)l=[...l,...ld(s.shape,e.shape)];return l}let Vt=class on extends Rl{constructor(...t){if(super(),this.isInfinite=!1,t.length===1&&t[0]instanceof Array&&t[0].length>0){const l=t[0],s=l.length,e=o=>o instanceof b.Segment||o instanceof b.Arc||o instanceof b.Ray||o instanceof b.Line,d=o=>o instanceof b.Segment||o instanceof b.Arc||o instanceof b.Ray,i=o=>o instanceof b.Segment||o instanceof b.Arc;if(s===1&&e(l[0])||s>1&&d(l[0])&&d(l[s-1])&&l.slice(1,s-1).every(i)){this.isInfinite=l.some(o=>o instanceof b.Ray||o instanceof b.Line);for(let o of l){let a=new b.Edge(o);this.append(a)}this.setArcLength()}else throw b.Errors.ILLEGAL_PARAMETERS}}get edges(){return[...this]}get box(){return this.edges.reduce((t,l)=>t.merge(l.box),new b.Box)}get vertices(){let t=this.edges.map(l=>l.start);return t.push(this.last.end),t}get length(){if(this.isEmpty())return 0;if(this.isInfinite)return Number.POSITIVE_INFINITY;let t=0;for(let l of this)t+=l.length;return t}clone(){return new on(this.toShapes())}setArcLength(){for(let t of this)this.setOneEdgeArcLength(t)}setOneEdgeArcLength(t){t===this.first?t.arc_length=0:t.arc_length=t.prev.arc_length+t.prev.length}pointAtLength(t){if(t>this.length||t<0||this.isInfinite)return null;let l=null;for(let s of this)if(t>=s.arc_length&&(s===this.last||t<s.next.arc_length)){l=s.pointAtLength(t-s.arc_length);break}return l}addVertex(t,l){let s=l.shape.split(t);if(s[0]===null)return l.prev;if(s[1]===null)return l;let e=new b.Edge(s[0]),d=l.prev;return this.insert(e,d),l.shape=s[1],e}getChain(t,l){let s=[];for(let e=t;e!==l.next;e=e.next)s.push(e);return s}split(t){for(let l of t){let s=this.findEdgeByPoint(l);this.addVertex(l,s)}return this}findEdgeByPoint(t){let l;for(let s of this)if(s.shape.contains(t)){l=s;break}return l}distanceTo(t){if(t instanceof Point){const[l,s]=b.Distance.shape2multiline(t,this);return[l,s.reverse()]}if(t instanceof b.Line){const[l,s]=b.Distance.shape2multiline(t,this);return[l,s.reverse()]}if(t instanceof b.Circle){const[l,s]=b.Distance.shape2multiline(t,this);return[l,s.reverse()]}if(t instanceof b.Segment){const[l,s]=b.Distance.shape2multiline(t,this);return[l,s.reverse()]}if(t instanceof b.Arc){const[l,s]=b.Distance.shape2multiline(t,this);return[l,s.reverse()]}if(t instanceof b.Multiline)return b.Distance.multiline2multiline(this,t);throw b.Errors.UNSUPPORTED_SHAPE_TYPE}intersect(t){return t instanceof b.Multiline?zo(this,t):Ft(t,this)}contains(t){if(t instanceof b.Point)return this.edges.some(l=>l.shape.contains(t));throw b.Errors.UNSUPPORTED_SHAPE_TYPE}translate(t){return new on(this.edges.map(l=>l.shape.translate(t)))}rotate(t=0,l=new b.Point){return new on(this.edges.map(s=>s.shape.rotate(t,l)))}transform(t=new b.Matrix){return new on(this.edges.map(l=>l.shape.transform(t)))}toShapes(){return this.edges.map(t=>t.shape.clone())}toJSON(){return this.edges.map(t=>t.toJSON())}svgPoints(){return this.vertices.map(t=>`${t.x},${t.y}`).join(" ")}dpath(){let t=`M${this.first.start.x},${this.first.start.y}`;for(let l of this)t+=l.svg();return t}svg(t={}){let l=`
|
|
11
|
-
<path ${
|
|
1
|
+
var Tools=function(R,h){"use strict";var ll=typeof document<"u"?document.currentScript:null;function Ji(n){return mn(n)||pn(n)||ps(n)}function mn(n){return"modelMatrix"in n}function pn(n){return"position"in n}function ps(n){return"positions"in n}const Ws={[h.WebGLConstants.BYTE]:Int8Array,[h.WebGLConstants.UNSIGNED_BYTE]:Uint8Array,[h.WebGLConstants.SHORT]:Int16Array,[h.WebGLConstants.UNSIGNED_SHORT]:Uint16Array,[h.WebGLConstants.INT]:Int32Array,[h.WebGLConstants.UNSIGNED_INT]:Uint32Array,[h.WebGLConstants.FLOAT]:Float32Array,[h.WebGLConstants.DOUBLE]:Float64Array};var Vs=(n=>(n[n.x=0]="x",n[n.y=1]="y",n[n.z=2]="z",n))(Vs||{});R.Xyz_Hpr=(n=>(n.x="roll",n.y="pitch",n.z="heading",n))(R.Xyz_Hpr||{}),(n=>{function t(e){for(let[d,i]of Object.entries(n))if(e===i)return d}n.toKey=t;function l(e){return new h.Cartesian3(e.roll,-e.pitch,-e.heading)}n.toCartesian3=l;function s(e){return new h.HeadingPitchRoll(-e[t("heading")],-e[t("pitch")],e[t("roll")])}n.toHeadingPitchRoll=s})(R.Xyz_Hpr||(R.Xyz_Hpr={}));var ys=(n=>(n[n.heading=0]="heading",n[n.pitch=1]="pitch",n[n.roll=2]="roll",n))(ys||{});function sl(n){const t=n?.world,{translation:l,rotation:s,scale:e}=t&&typeof t=="object"?t:{translation:t,rotation:t,scale:t};return{...n,worldTranslation:l,worldRotation:s,worldScale:e}}function Et(n){if(n.axis){const{axis:l,angle:s}=n;return h.Quaternion.fromAxisAngle(l,s)}const t=R.Xyz_Hpr.toHeadingPitchRoll(n);return h.Quaternion.fromHeadingPitchRoll(t)}function Ii(n,t,l){const s=h.Matrix3.fromQuaternion(n),e=h.Matrix4.fromRotation(s),d=h.Matrix4.inverseTransformation(t,new h.Matrix4),i=h.Matrix4.multiply(d,e,e);return el(i)}function el(n,t){const l=h.Matrix4.getMatrix3(n,new h.Matrix3),s=h.Quaternion.fromRotationMatrix(l);return h.HeadingPitchRoll.fromQuaternion(s,t)}function ki(n,t,l){l=l??new h.Matrix4;const s=h.Matrix4.inverse(t,new h.Matrix4);return h.Matrix4.multiply(s,n,l)}function Ls(n,t,l){let s=h.Quaternion.computeAxis(n,new h.Cartesian3);if(s.equals(h.Cartesian3.ZERO))return null;const e=h.Quaternion.computeAngle(n);return s=h.Matrix4.multiplyByPointAsVector(t,s,s),h.Quaternion.fromAxisAngle(s,e)}function Pi(n,t,l){let s=h.Quaternion.computeAxis(n,new h.Cartesian3);if(s.equals(h.Cartesian3.ZERO))return null;const e=h.Quaternion.computeAngle(n),d=h.Matrix4.inverse(t,new h.Matrix4);return s=h.Matrix4.multiplyByPointAsVector(d,s,s),h.Quaternion.fromAxisAngle(s,e)}function Wn(n,t){let{translation:l,rotation:s,scale:e}=n;const{referFrame:d,worldTranslation:i,worldRotation:c,worldScale:o}=sl(t);let X=null;return l&&(i||(l=h.Matrix4.multiplyByPointAsVector(d,l,new h.Cartesian3))),s&&(X=Et(s),c||(X=Ls(X,d))),e&&(o||(e=h.Matrix4.multiplyByPointAsVector(d,e,new h.Cartesian3))),{translation:l,rotation:X,scale:e}}function xs(n,t){let{translation:l,rotation:s,scale:e}=n;const{referFrame:d,worldTranslation:i,worldRotation:c,worldScale:o}=sl(t),X=d?h.Matrix4.inverse(d,new h.Matrix4):null;let a=null;if(l&&i&&(l=h.Matrix4.multiplyByPointAsVector(X,l,new h.Cartesian3)),s&&(a=Et(s),c)){let u=h.Quaternion.computeAxis(a,new h.Cartesian3);if(!u.equals(h.Cartesian3.ZERO)){const r=h.Quaternion.computeAngle(a);u=h.Matrix4.multiplyByPointAsVector(X,u,u),a=h.Quaternion.fromAxisAngle(u,r)}}return e&&o&&(e=h.Matrix4.multiplyByPointAsVector(X,e,new h.Cartesian3)),{translation:l,rotation:a,scale:e}}function Ks(n,t){const l=t?.defaultMatrix;let{translation:s,rotation:e,scale:d}=Wn(n,t);if(l){if(s||(s=h.Matrix4.getTranslation(l,new h.Cartesian3)),!e){const c=h.Matrix4.getMatrix3(l,new h.Matrix3);e=h.Quaternion.fromRotationMatrix(c)}d||(d=h.Matrix4.getScale(l,new h.Cartesian3))}const i=new h.TranslationRotationScale(s??void 0,e??void 0,d??void 0);return h.Matrix4.fromTranslationRotationScale(i)}function Qi(n){const{translation:t,rotation:l,scale:s}=n,e=l?Et(l):void 0,d=new h.TranslationRotationScale(t??void 0,e,s??void 0);return h.Matrix4.fromTranslationRotationScale(d)}function Rs(n,t,l){const s=h.Cartesian3.subtract(t,n,new h.Cartesian3),e=h.Cartesian3.subtract(l,n,new h.Cartesian3),d=h.Cartesian3.cross(s,e,s);return h.Cartesian3.normalize(d,s)}function Bi(n,t,l){const s=Rs(n,t,l);return h.Plane.fromPointNormal(s,n)}function*vi(n,t=!0,l,s){const e=n.length,d=t?e:e-1,i=l||s?h.Cartesian3.prototype.equalsEpsilon:h.Cartesian3.prototype.equals;for(let c=0;c<d;c++){const o=n[c];let X=(c+1)%e,a=n[X],u=c;for(;i.call(o,a,l,s);){if(X=(++u+1)%e,X===c)return;a=n[X]}c=u,yield[o,a]}}function Ss(n){var t=typeof n;return n&&(t==="object"||t==="function")}function zs(n){var t=n;return n!=null&&(t=n.constructor,t==null&&(t=typeof n)),t}function wi(n){switch(n){case void 0:return"undefined";case null:return"null"}let t=typeof n;switch(t){case"function":return n.name;case"string":return n;default:return t}}function Ui(n){let t=zs(n);return wi(t)}function ji(n){return n==null||Ss(n)?zs(n):typeof n}var dl=(n=>(n.equal="equal",n.intersect="intersect",n.intersectEqual="intersectEqual",n))(dl||{});(n=>{function t(l){let s;switch(l){case"equal":s=(e,d)=>e===d;case"intersect":s=(e,d)=>e&d;default:s=(e,d)=>(e&d)===e}return s}n.getEqualFun=t})(dl||(dl={}));const Ei=[globalThis.Worker,globalThis.SharedWorker,globalThis.ServiceWorker].filter(n=>n),Oi=["Worker","SharedWorker","ServiceWorker"];function Ai(n){if(Ei.some(l=>n instanceof l))return!0;const t=Ui(n);return Oi.includes(t)}var il=(n=>(n.Ing="进行中",n.End="结束",n))(il||{}),Di=Object.defineProperty,qi=(n,t,l)=>t in n?Di(n,t,{enumerable:!0,configurable:!0,writable:!0,value:l}):n[t]=l,Vn=(n,t,l)=>qi(n,typeof t!="symbol"?t+"":t,l);const Ms=`(function(){"use strict";function n(){const r=globalThis.currentWorkerType;if(r)return r;let e=globalThis.SharedWorkerGlobalScope;return typeof e=="function"&&globalThis instanceof e?globalThis.currentWorkerType="SharedWorker":(e=globalThis.DedicatedWorkerGlobalScope,typeof e=="function"&&globalThis instanceof e?globalThis.currentWorkerType="DedicatedWorker":(e=globalThis.Window,typeof e=="function"&&globalThis instanceof e?globalThis.currentWorkerType="Window":globalThis.currentWorkerType="unknown"))}function t(r){switch(n()){case"SharedWorker":{globalThis.addEventListener("connect",function(e){for(const o of e.ports)o.addEventListener("message",r),o.start()});break}default:globalThis.addEventListener("message",r)}}globalThis.listenMessage||(globalThis.listenMessage=t)})();
|
|
2
|
+
`,_i='(function(){"use strict";function b(t){var e=t;return t!=null&&(e=t.constructor,e==null&&(e=typeof t)),e}var u=(t=>(t.equal="equal",t.intersect="intersect",t.intersectEqual="intersectEqual",t))(u||{});(t=>{function e(r){let s;switch(r){case"equal":s=(o,n)=>o===n;case"intersect":s=(o,n)=>o&n;default:s=(o,n)=>(o&n)===o}return s}t.getEqualFun=e})(u||(u={}));function d(){const t=globalThis.currentWorkerType;if(t)return t;let e=globalThis.SharedWorkerGlobalScope;return typeof e=="function"&&globalThis instanceof e?globalThis.currentWorkerType="SharedWorker":(e=globalThis.DedicatedWorkerGlobalScope,typeof e=="function"&&globalThis instanceof e?globalThis.currentWorkerType="DedicatedWorker":(e=globalThis.Window,typeof e=="function"&&globalThis instanceof e?globalThis.currentWorkerType="Window":globalThis.currentWorkerType="unknown"))}function h(t,e,r){const s=/(^\\s*(async\\s+)?function\\s*(\\s|\\*)\\s*)[A-Za-z_$]+[\\w$]*(\\s*\\()/,o=/^[A-Za-z_$]+[\\w$]*$/,n=s.test(t),a=e&&o.test(e);if(n&&a&&(t=t.replace(s,`$1${e}$4`)),!n&&a)var i=`var ${e} = ${t} ; return ${e}`;else i=`return (${t})`;return new Function(i)()}function f(t){const{name:e,args:r,this:s}=t,o=s??globalThis,n=globalThis[e];return typeof n=="function"?n.apply(o,r):r||s?{error:"函数不存在",state:"结束"}:{data:n,state:"结束"}}function g(t){const e=b(t);if(e==="object"||e===Object){const{transfer:r,targetOrigin:s}=t;return"data"in t||"error"in t||Array.isArray(r)||typeof s=="string"}return!1}function c(t,e){const{data:r,...s}=g(t)?t:{data:t},o={...e,...s};if(r instanceof ReadableStream){const n=new WritableStream({write:function(a,i){return c(a,{...o,state:"进行中"})},close:function(a){l(void 0,{state:"结束",...o})},abort:function(a){l(void 0,{state:"结束",...o,error:a})}});return r.pipeTo(n)}return r instanceof Promise?r.then(function(n){c(n,{state:"结束",...o})},function(n){l(void 0,{...o,error:n,state:"结束"})}):l(r,{state:"结束",...o})}function l(t,e){const{port:r,...s}=e,{transfer:o,targetOrigin:n,...a}=g(t)?{...s,...t}:{...s,data:t};a.state==null&&(a.state="结束");const i={transfer:o,targetOrigin:n};return(r??globalThis).postMessage(a,i)}function T(t){const e=t.data,r=t.currentTarget;if(e){const s=f(e);c(s,{execId:e.id,port:r})}}function p(t,e){const r=h(t,e);return e=e??r.name,globalThis[e]=r,!0}function y(t){return delete globalThis[t]}Object.assign(globalThis,{execCMD:f,messageListener:T,setCMD:p,removeCMD:y,sendMessage:c}),d(),listenMessage(T)})();\n',yn="event";function Ys(n,t){t=t??n.name;const l=n.toString();return`globalThis['${t}'] = ${l};`}function cl(n,t){const l=typeof n=="string"?n:n.toString();t=t??[];const s=t.map(function(d){return Ss(d)?JSON.stringify(d):d}),e=s.length>0?`,${s.join(",")}`:"";return`(${l}).call(this${e});`}function $i(n,t){return n.name?Ys(n):cl(n,t)}function gs(n){return`globalThis.listenMessage(${typeof n=="string"?n:n.toString()});`}function tc(n){const t=n.map(function(s){return`${s}.call(this,${yn});`}).join(`
|
|
3
|
+
`),l=`function(${yn}){${t}}`;return gs(l)}function nc(n){const t=n.map(function(s){return cl(s,[yn])}).join(`
|
|
4
|
+
`),l=`function(${yn}){${t}}`;return gs(l)}function lc(n,t){const l=new Blob(n,{type:"text/javascript",...t});return URL.createObjectURL(l)}function Ts(n){return n.name||n.fun?[n]:Object.entries(n).map(function([t,l]){return{name:t,fun:l}})}function sc(n,t){const{code:l,named:s,iife:e,message:d}=n,i=[],c=[],o=e||[],X=[],a=[],u=Array.isArray(l)?l:l?[l]:[];for(const y of u){const S=ji(y);if(S===Object||S==="object"){const K=Ts(y);i.push(...K)}else c.push(y)}const r=Array.isArray(s)?s:s?[s]:[];for(const y of r)if(typeof y=="function")i.push({fun:y});else{const S=Ts(y);i.push(...S)}const Z=Array.isArray(d)?d:d?[d]:[];for(const y of Z)switch(typeof y){case"string":{a.push(y);break}case"function":{X.push(y);break}default:{const{name:S,fun:K}=y;K?X.push(K):S&&a.push(S)}}const G=i.map(function({name:y,fun:S}){return`${Ys(S,y)}
|
|
5
|
+
`}),p=c.map(function(y){return typeof y=="function"?`${$i(y)}
|
|
6
|
+
`:y}),m=o.map(function(y){return`${cl(y)}
|
|
7
|
+
`}),W=[],L=nc(X);W.push(`${L}
|
|
8
|
+
`);const V=tc(a);return W.push(`${V}
|
|
9
|
+
`),[`${Ms}
|
|
10
|
+
`,...G,...p,...m,...W]}function ec(n,t){const l=n?sc(n):[];return t||l.unshift(Ms,_i),lc(l)}function Cs(n){return n&&Array.isArray(n.args)&&Array.isArray(n.transfer)}const fs=class Fi{constructor(t){if(Vn(this,"id",++Fi.instanceCount),Vn(this,"execCount",0),t)for(const l of Object.keys(t))this.setCMDToSelf(l)}get port(){return this.getPort(this.worker)}get workerAndPort(){const t=this.worker;return[t,this.getPort(t)]}getPort(t){return t.port||t}execStarted(t,l){++t.executingCount}execEnded(t){--t.executingCount}getExecId(t){return t=t??"匿名",`${t}_${this.execCount}`}getExecRecord(t){return{id:this.getExecId(t.name),...t}}listenResponse(t,l){const s=new AbortController,e=s.signal;let d=null;const i=this.getPort(l);return new Promise((c,o)=>{i.addEventListener("message",a=>{const u=a.data,{execId:r,state:Z,error:G,data:p}=u;if(t!==r)return;if(d){if(Z===il.End){s.abort(),G&&d.error(G),p!==void 0&&d.enqueue(p),d.close(),this.execEnded(l);return}if(G){d.error(G);return}d.enqueue(p);return}if(G){o(G),s.abort();return}if(Z===il.End){s.abort(),c(p),this.execEnded(l);return}const m=new ReadableStream({start:W=>{d=W,G&&d.error(G),d.enqueue(p)}});c(m)},{signal:e});const X=a=>{if(s.abort(),d){d.error(a),d.close(),this.execEnded(l);return}o(a)};l.addEventListener("error",X,{signal:e}),i.addEventListener("messageerror",X,{signal:e})}).catch(c=>{throw this.execEnded(l),c})}execCMD(t,l){++this.execCount;const s=this.getExecRecord(t),[e,d]=this.workerAndPort;this.execStarted(e,s);const i=this.listenResponse(s.id,e);d.postMessage(s,l);const c=t.name;return c in this?i:i.then(o=>(this.setCMDToSelf(c),o))}setCMDToSelf(t,l){const s=(...e)=>{const d=e[0];let i;return e.length===1&&Cs(d)&&(i=d.transfer,e=d.args),this.execCMD({name:t,args:e.length>0?e:void 0},i)};return Reflect.defineProperty(this,t,{configurable:!0,enumerable:!0,...l?{get:s}:{value:s,writable:!0}})}};Vn(fs,"instanceCount",0);let dc=fs;function ic(n){const{url:t,name:l}=n;return new Worker(t,{name:l})}class cc extends dc{constructor(t,l){super(t?.named),Vn(this,"worker");const{id:s}=this;let e=(typeof l=="string"?l:l?.name)||`DynamicWorker/${s}`,d=t;if(!Ai(t)){const i=typeof t=="string",{getWorker:c,noDep:o}=l||{},X=i?t:ec(t,o);d=(c||ic)({url:X,name:e,clientId:s,id:s}),i||URL.revokeObjectURL(X)}d.executingCount=0,d.name=e,d.id=d.clientId=s,this.worker=d}get executingCount(){return this.worker.executingCount}setCMD(t,l,s){const e=l||t.name;if(!e)return Promise.reject("没有函数的名字");const d=typeof t=="function"?t.toString():t;return this.execCMD({name:"setCMD",args:[d,e]}).then(i=>(i&&this.setCMDToSelf(e,s),i))}removeCMD(t){return this.execCMD({name:"removeCMD",args:[t]}).then(l=>(l&&Reflect.deleteProperty(this,t),l))}}function bc(n){return new Proxy(n,{get:function(t,l,s){const e=t[l];return typeof e=="function"?e.bind(t):e||function(...d){const i=d[0];let c;return d.length===1&&Cs(i)&&(c=i.transfer,d=i.args),t.execCMD({name:l,args:d.length>0?d:void 0},c)}},set:function(t,l,s,e){return t.setCMD(s,l,typeof s!="function")},deleteProperty:function(t,l){return t.removeCMD(l)},has:function(t,l){return l in t},ownKeys:function(t){return Reflect.ownKeys(t)}})}function oc(n,t){const l=new cc(n,t);return bc(l)}const Xc=1/Math.PI*180,ac=1/180*Math.PI,uc={EPSILON:1e-12,debug:!1,precision:4,printTypes:!1,printDegrees:!1,printRowMajor:!0,_cartographicRadians:!1};globalThis.mathgl=globalThis.mathgl||{config:{...uc}};const w=globalThis.mathgl.config;function hc(n,{precision:t=w.precision}={}){return n=pc(n),`${parseFloat(n.toPrecision(t))}`}function Vt(n){return Array.isArray(n)||ArrayBuffer.isView(n)&&!(n instanceof DataView)}function rc(n){return Gc(n)}function Zc(n){return mc(n)}function Gc(n,t){return bl(n,l=>l*ac,t)}function mc(n,t){return bl(n,l=>l*Xc,t)}function Yt(n,t,l){return bl(n,s=>Math.max(t,Math.min(l,s)))}function A(n,t,l){const s=w.EPSILON;l&&(w.EPSILON=l);try{if(n===t)return!0;if(Vt(n)&&Vt(t)){if(n.length!==t.length)return!1;for(let e=0;e<n.length;++e)if(!A(n[e],t[e]))return!1;return!0}return n&&n.equals?n.equals(t):t&&t.equals?t.equals(n):typeof n=="number"&&typeof t=="number"?Math.abs(n-t)<=w.EPSILON*Math.max(1,Math.abs(n),Math.abs(t)):!1}finally{w.EPSILON=s}}function pc(n){return Math.round(n/w.EPSILON)*w.EPSILON}function Wc(n){return n.clone?n.clone():new Array(n.length)}function bl(n,t,l){if(Vt(n)){const s=n;l=l||Wc(s);for(let e=0;e<l.length&&e<s.length;++e){const d=typeof n=="number"?n:n[e];l[e]=t(d,e,l)}return l}return t(n)}class Ln extends Array{clone(){return new this.constructor().copy(this)}fromArray(t,l=0){for(let s=0;s<this.ELEMENTS;++s)this[s]=t[s+l];return this.check()}toArray(t=[],l=0){for(let s=0;s<this.ELEMENTS;++s)t[l+s]=this[s];return t}toObject(t){return t}from(t){return Array.isArray(t)?this.copy(t):this.fromObject(t)}to(t){return t===this?this:Vt(t)?this.toArray(t):this.toObject(t)}toTarget(t){return t?this.to(t):this}toFloat32Array(){return new Float32Array(this)}toString(){return this.formatString(w)}formatString(t){let l="";for(let s=0;s<this.ELEMENTS;++s)l+=(s>0?", ":"")+hc(this[s],t);return`${t.printTypes?this.constructor.name:""}[${l}]`}equals(t){if(!t||this.length!==t.length)return!1;for(let l=0;l<this.ELEMENTS;++l)if(!A(this[l],t[l]))return!1;return!0}exactEquals(t){if(!t||this.length!==t.length)return!1;for(let l=0;l<this.ELEMENTS;++l)if(this[l]!==t[l])return!1;return!0}negate(){for(let t=0;t<this.ELEMENTS;++t)this[t]=-this[t];return this.check()}lerp(t,l,s){if(s===void 0)return this.lerp(this,t,l);for(let e=0;e<this.ELEMENTS;++e){const d=t[e],i=typeof l=="number"?l:l[e];this[e]=d+s*(i-d)}return this.check()}min(t){for(let l=0;l<this.ELEMENTS;++l)this[l]=Math.min(t[l],this[l]);return this.check()}max(t){for(let l=0;l<this.ELEMENTS;++l)this[l]=Math.max(t[l],this[l]);return this.check()}clamp(t,l){for(let s=0;s<this.ELEMENTS;++s)this[s]=Math.min(Math.max(this[s],t[s]),l[s]);return this.check()}add(...t){for(const l of t)for(let s=0;s<this.ELEMENTS;++s)this[s]+=l[s];return this.check()}subtract(...t){for(const l of t)for(let s=0;s<this.ELEMENTS;++s)this[s]-=l[s];return this.check()}scale(t){if(typeof t=="number")for(let l=0;l<this.ELEMENTS;++l)this[l]*=t;else for(let l=0;l<this.ELEMENTS&&l<t.length;++l)this[l]*=t[l];return this.check()}multiplyByScalar(t){for(let l=0;l<this.ELEMENTS;++l)this[l]*=t;return this.check()}check(){if(w.debug&&!this.validate())throw new Error(`math.gl: ${this.constructor.name} some fields set to invalid numbers'`);return this}validate(){let t=this.length===this.ELEMENTS;for(let l=0;l<this.ELEMENTS;++l)t=t&&Number.isFinite(this[l]);return t}sub(t){return this.subtract(t)}setScalar(t){for(let l=0;l<this.ELEMENTS;++l)this[l]=t;return this.check()}addScalar(t){for(let l=0;l<this.ELEMENTS;++l)this[l]+=t;return this.check()}subScalar(t){return this.addScalar(-t)}multiplyScalar(t){for(let l=0;l<this.ELEMENTS;++l)this[l]*=t;return this.check()}divideScalar(t){return this.multiplyByScalar(1/t)}clampScalar(t,l){for(let s=0;s<this.ELEMENTS;++s)this[s]=Math.min(Math.max(this[s],t),l);return this.check()}get elements(){return this}}function Vc(n,t){if(n.length!==t)return!1;for(let l=0;l<n.length;++l)if(!Number.isFinite(n[l]))return!1;return!0}function f(n){if(!Number.isFinite(n))throw new Error(`Invalid number ${JSON.stringify(n)}`);return n}function Ot(n,t,l=""){if(w.debug&&!Vc(n,t))throw new Error(`math.gl: ${l} some fields set to invalid numbers'`);return n}function at(n,t){if(!n)throw new Error(`math.gl assertion ${t}`)}let ol=class extends Ln{get x(){return this[0]}set x(t){this[0]=f(t)}get y(){return this[1]}set y(t){this[1]=f(t)}len(){return Math.sqrt(this.lengthSquared())}magnitude(){return this.len()}lengthSquared(){let t=0;for(let l=0;l<this.ELEMENTS;++l)t+=this[l]*this[l];return t}magnitudeSquared(){return this.lengthSquared()}distance(t){return Math.sqrt(this.distanceSquared(t))}distanceSquared(t){let l=0;for(let s=0;s<this.ELEMENTS;++s){const e=this[s]-t[s];l+=e*e}return f(l)}dot(t){let l=0;for(let s=0;s<this.ELEMENTS;++s)l+=this[s]*t[s];return f(l)}normalize(){const t=this.magnitude();if(t!==0)for(let l=0;l<this.ELEMENTS;++l)this[l]/=t;return this.check()}multiply(...t){for(const l of t)for(let s=0;s<this.ELEMENTS;++s)this[s]*=l[s];return this.check()}divide(...t){for(const l of t)for(let s=0;s<this.ELEMENTS;++s)this[s]/=l[s];return this.check()}lengthSq(){return this.lengthSquared()}distanceTo(t){return this.distance(t)}distanceToSquared(t){return this.distanceSquared(t)}getComponent(t){return at(t>=0&&t<this.ELEMENTS,"index is out of range"),f(this[t])}setComponent(t,l){return at(t>=0&&t<this.ELEMENTS,"index is out of range"),this[t]=l,this.check()}addVectors(t,l){return this.copy(t).add(l)}subVectors(t,l){return this.copy(t).subtract(l)}multiplyVectors(t,l){return this.copy(t).multiply(l)}addScaledVector(t,l){return this.add(new this.constructor(t).multiplyScalar(l))}};const F=1e-6;let B=typeof Float32Array<"u"?Float32Array:Array;const yt=Math.random;function ot(n){return n>=0?Math.round(n):n%.5===0?Math.floor(n):Math.round(n)}function Fs(){const n=new B(2);return B!=Float32Array&&(n[0]=0,n[1]=0),n}function yc(n){const t=new B(2);return t[0]=n[0],t[1]=n[1],t}function Lc(n,t){const l=new B(2);return l[0]=n,l[1]=t,l}function xc(n,t){return n[0]=t[0],n[1]=t[1],n}function Kc(n,t,l){return n[0]=t,n[1]=l,n}function Ns(n,t,l){return n[0]=t[0]+l[0],n[1]=t[1]+l[1],n}function tt(n,t,l){return n[0]=t[0]-l[0],n[1]=t[1]-l[1],n}function Hs(n,t,l){return n[0]=t[0]*l[0],n[1]=t[1]*l[1],n}function Js(n,t,l){return n[0]=t[0]/l[0],n[1]=t[1]/l[1],n}function Rc(n,t){return n[0]=Math.ceil(t[0]),n[1]=Math.ceil(t[1]),n}function Sc(n,t){return n[0]=Math.floor(t[0]),n[1]=Math.floor(t[1]),n}function zc(n,t,l){return n[0]=Math.min(t[0],l[0]),n[1]=Math.min(t[1],l[1]),n}function Mc(n,t,l){return n[0]=Math.max(t[0],l[0]),n[1]=Math.max(t[1],l[1]),n}function Yc(n,t){return n[0]=ot(t[0]),n[1]=ot(t[1]),n}function gc(n,t,l){return n[0]=t[0]*l,n[1]=t[1]*l,n}function Is(n,t,l,s){return n[0]=t[0]+l[0]*s,n[1]=t[1]+l[1]*s,n}function ks(n,t){const l=t[0]-n[0],s=t[1]-n[1];return Math.sqrt(l*l+s*s)}function Ps(n,t){const l=t[0]-n[0],s=t[1]-n[1];return l*l+s*s}function Qs(n){const t=n[0],l=n[1];return Math.sqrt(t*t+l*l)}function Bs(n){const t=n[0],l=n[1];return t*t+l*l}function Tc(n,t){return n[0]=-t[0],n[1]=-t[1],n}function Cc(n,t){return n[0]=1/t[0],n[1]=1/t[1],n}function fc(n,t){const l=t[0],s=t[1];let e=l*l+s*s;return e>0&&(e=1/Math.sqrt(e)),n[0]=t[0]*e,n[1]=t[1]*e,n}function Fc(n,t){return n[0]*t[0]+n[1]*t[1]}function gt(n,t,l){const s=t[0]*l[1]-t[1]*l[0];return n[0]=n[1]=0,n[2]=s,n}function Nc(n,t,l,s){const e=t[0],d=t[1];return n[0]=e+s*(l[0]-e),n[1]=d+s*(l[1]-d),n}function Hc(n,t){t=t===void 0?1:t;const l=yt()*2*Math.PI;return n[0]=Math.cos(l)*t,n[1]=Math.sin(l)*t,n}function Xl(n,t,l){const s=t[0],e=t[1];return n[0]=l[0]*s+l[2]*e,n[1]=l[1]*s+l[3]*e,n}function vs(n,t,l){const s=t[0],e=t[1];return n[0]=l[0]*s+l[2]*e+l[4],n[1]=l[1]*s+l[3]*e+l[5],n}function al(n,t,l){const s=t[0],e=t[1];return n[0]=l[0]*s+l[3]*e+l[6],n[1]=l[1]*s+l[4]*e+l[7],n}function ul(n,t,l){const s=t[0],e=t[1];return n[0]=l[0]*s+l[4]*e+l[12],n[1]=l[1]*s+l[5]*e+l[13],n}function Jc(n,t,l,s){const e=t[0]-l[0],d=t[1]-l[1],i=Math.sin(s),c=Math.cos(s);return n[0]=e*c-d*i+l[0],n[1]=e*i+d*c+l[1],n}function Ic(n,t){const l=n[0],s=n[1],e=t[0],d=t[1],i=Math.sqrt((l*l+s*s)*(e*e+d*d)),c=i&&(l*e+s*d)/i;return Math.acos(Math.min(Math.max(c,-1),1))}function kc(n){return n[0]=0,n[1]=0,n}function Pc(n){return`vec2(${n[0]}, ${n[1]})`}function Qc(n,t){return n[0]===t[0]&&n[1]===t[1]}function hl(n,t){const l=n[0],s=n[1],e=t[0],d=t[1];return Math.abs(l-e)<=F*Math.max(1,Math.abs(l),Math.abs(e))&&Math.abs(s-d)<=F*Math.max(1,Math.abs(s),Math.abs(d))}const Bc=Qs,vc=tt,wc=Hs,Uc=Js,jc=ks,Ec=Ps,Oc=Bs,Ac=function(){const n=Fs();return function(t,l,s,e,d,i){let c,o;for(l||(l=2),s||(s=0),e?o=Math.min(e*l+s,t.length):o=t.length,c=s;c<o;c+=l)n[0]=t[c],n[1]=t[c+1],d(n,n,i),t[c]=n[0],t[c+1]=n[1];return t}}(),Dc=Object.freeze(Object.defineProperty({__proto__:null,add:Ns,angle:Ic,ceil:Rc,clone:yc,copy:xc,create:Fs,cross:gt,dist:jc,distance:ks,div:Uc,divide:Js,dot:Fc,equals:hl,exactEquals:Qc,floor:Sc,forEach:Ac,fromValues:Lc,inverse:Cc,len:Bc,length:Qs,lerp:Nc,max:Mc,min:zc,mul:wc,multiply:Hs,negate:Tc,normalize:fc,random:Hc,rotate:Jc,round:Yc,scale:gc,scaleAndAdd:Is,set:Kc,sqrDist:Ec,sqrLen:Oc,squaredDistance:Ps,squaredLength:Bs,str:Pc,sub:vc,subtract:tt,transformMat2:Xl,transformMat2d:vs,transformMat3:al,transformMat4:ul,zero:kc},Symbol.toStringTag,{value:"Module"}));function ws(n,t,l){const s=t[0],e=t[1],d=l[3]*s+l[7]*e||1;return n[0]=(l[0]*s+l[4]*e)/d,n[1]=(l[1]*s+l[5]*e)/d,n}function Us(n,t,l){const s=t[0],e=t[1],d=t[2],i=l[3]*s+l[7]*e+l[11]*d||1;return n[0]=(l[0]*s+l[4]*e+l[8]*d)/i,n[1]=(l[1]*s+l[5]*e+l[9]*d)/i,n[2]=(l[2]*s+l[6]*e+l[10]*d)/i,n}function qc(n,t,l){const s=t[0],e=t[1];return n[0]=l[0]*s+l[2]*e,n[1]=l[1]*s+l[3]*e,n[2]=t[2],n}function _c(n,t,l){const s=t[0],e=t[1];return n[0]=l[0]*s+l[2]*e,n[1]=l[1]*s+l[3]*e,n[2]=t[2],n[3]=t[3],n}function js(n,t,l){const s=t[0],e=t[1],d=t[2];return n[0]=l[0]*s+l[3]*e+l[6]*d,n[1]=l[1]*s+l[4]*e+l[7]*d,n[2]=l[2]*s+l[5]*e+l[8]*d,n[3]=t[3],n}class nt extends ol{constructor(t=0,l=0){super(2),Vt(t)&&arguments.length===1?this.copy(t):(w.debug&&(f(t),f(l)),this[0]=t,this[1]=l)}set(t,l){return this[0]=t,this[1]=l,this.check()}copy(t){return this[0]=t[0],this[1]=t[1],this.check()}fromObject(t){return w.debug&&(f(t.x),f(t.y)),this[0]=t.x,this[1]=t.y,this.check()}toObject(t){return t.x=this[0],t.y=this[1],t}get ELEMENTS(){return 2}horizontalAngle(){return Math.atan2(this.y,this.x)}verticalAngle(){return Math.atan2(this.x,this.y)}transform(t){return this.transformAsPoint(t)}transformAsPoint(t){return ul(this,this,t),this.check()}transformAsVector(t){return ws(this,this,t),this.check()}transformByMatrix3(t){return al(this,this,t),this.check()}transformByMatrix2x3(t){return vs(this,this,t),this.check()}transformByMatrix2(t){return Xl(this,this,t),this.check()}}function rl(){const n=new B(3);return B!=Float32Array&&(n[0]=0,n[1]=0,n[2]=0),n}function $c(n){const t=new B(3);return t[0]=n[0],t[1]=n[1],t[2]=n[2],t}function xn(n){const t=n[0],l=n[1],s=n[2];return Math.sqrt(t*t+l*l+s*s)}function Zl(n,t,l){const s=new B(3);return s[0]=n,s[1]=t,s[2]=l,s}function t0(n,t){return n[0]=t[0],n[1]=t[1],n[2]=t[2],n}function n0(n,t,l,s){return n[0]=t,n[1]=l,n[2]=s,n}function l0(n,t,l){return n[0]=t[0]+l[0],n[1]=t[1]+l[1],n[2]=t[2]+l[2],n}function Gl(n,t,l){return n[0]=t[0]-l[0],n[1]=t[1]-l[1],n[2]=t[2]-l[2],n}function Es(n,t,l){return n[0]=t[0]*l[0],n[1]=t[1]*l[1],n[2]=t[2]*l[2],n}function Os(n,t,l){return n[0]=t[0]/l[0],n[1]=t[1]/l[1],n[2]=t[2]/l[2],n}function s0(n,t){return n[0]=Math.ceil(t[0]),n[1]=Math.ceil(t[1]),n[2]=Math.ceil(t[2]),n}function e0(n,t){return n[0]=Math.floor(t[0]),n[1]=Math.floor(t[1]),n[2]=Math.floor(t[2]),n}function d0(n,t,l){return n[0]=Math.min(t[0],l[0]),n[1]=Math.min(t[1],l[1]),n[2]=Math.min(t[2],l[2]),n}function i0(n,t,l){return n[0]=Math.max(t[0],l[0]),n[1]=Math.max(t[1],l[1]),n[2]=Math.max(t[2],l[2]),n}function c0(n,t){return n[0]=ot(t[0]),n[1]=ot(t[1]),n[2]=ot(t[2]),n}function As(n,t,l){return n[0]=t[0]*l,n[1]=t[1]*l,n[2]=t[2]*l,n}function b0(n,t,l,s){return n[0]=t[0]+l[0]*s,n[1]=t[1]+l[1]*s,n[2]=t[2]+l[2]*s,n}function Ds(n,t){const l=t[0]-n[0],s=t[1]-n[1],e=t[2]-n[2];return Math.sqrt(l*l+s*s+e*e)}function qs(n,t){const l=t[0]-n[0],s=t[1]-n[1],e=t[2]-n[2];return l*l+s*s+e*e}function _s(n){const t=n[0],l=n[1],s=n[2];return t*t+l*l+s*s}function o0(n,t){return n[0]=-t[0],n[1]=-t[1],n[2]=-t[2],n}function ml(n,t){return n[0]=1/t[0],n[1]=1/t[1],n[2]=1/t[2],n}function $s(n,t){const l=t[0],s=t[1],e=t[2];let d=l*l+s*s+e*e;return d>0&&(d=1/Math.sqrt(d)),n[0]=t[0]*d,n[1]=t[1]*d,n[2]=t[2]*d,n}function At(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function Tt(n,t,l){const s=t[0],e=t[1],d=t[2],i=l[0],c=l[1],o=l[2];return n[0]=e*o-d*c,n[1]=d*i-s*o,n[2]=s*c-e*i,n}function X0(n,t,l,s){const e=t[0],d=t[1],i=t[2];return n[0]=e+s*(l[0]-e),n[1]=d+s*(l[1]-d),n[2]=i+s*(l[2]-i),n}function a0(n,t,l,s){const e=Math.acos(Math.min(Math.max(At(t,l),-1),1)),d=Math.sin(e),i=Math.sin((1-s)*e)/d,c=Math.sin(s*e)/d;return n[0]=i*t[0]+c*l[0],n[1]=i*t[1]+c*l[1],n[2]=i*t[2]+c*l[2],n}function u0(n,t,l,s,e,d){const i=d*d,c=i*(2*d-3)+1,o=i*(d-2)+d,X=i*(d-1),a=i*(3-2*d);return n[0]=t[0]*c+l[0]*o+s[0]*X+e[0]*a,n[1]=t[1]*c+l[1]*o+s[1]*X+e[1]*a,n[2]=t[2]*c+l[2]*o+s[2]*X+e[2]*a,n}function h0(n,t,l,s,e,d){const i=1-d,c=i*i,o=d*d,X=c*i,a=3*d*c,u=3*o*i,r=o*d;return n[0]=t[0]*X+l[0]*a+s[0]*u+e[0]*r,n[1]=t[1]*X+l[1]*a+s[1]*u+e[1]*r,n[2]=t[2]*X+l[2]*a+s[2]*u+e[2]*r,n}function r0(n,t){t=t===void 0?1:t;const l=yt()*2*Math.PI,s=yt()*2-1,e=Math.sqrt(1-s*s)*t;return n[0]=Math.cos(l)*e,n[1]=Math.sin(l)*e,n[2]=s*t,n}function Kn(n,t,l){const s=t[0],e=t[1],d=t[2];let i=l[3]*s+l[7]*e+l[11]*d+l[15];return i=i||1,n[0]=(l[0]*s+l[4]*e+l[8]*d+l[12])/i,n[1]=(l[1]*s+l[5]*e+l[9]*d+l[13])/i,n[2]=(l[2]*s+l[6]*e+l[10]*d+l[14])/i,n}function Dt(n,t,l){const s=t[0],e=t[1],d=t[2];return n[0]=s*l[0]+e*l[3]+d*l[6],n[1]=s*l[1]+e*l[4]+d*l[7],n[2]=s*l[2]+e*l[5]+d*l[8],n}function pl(n,t,l){const s=l[0],e=l[1],d=l[2],i=l[3],c=t[0],o=t[1],X=t[2];let a=e*X-d*o,u=d*c-s*X,r=s*o-e*c,Z=e*r-d*u,G=d*a-s*r,p=s*u-e*a;const m=i*2;return a*=m,u*=m,r*=m,Z*=2,G*=2,p*=2,n[0]=c+a+Z,n[1]=o+u+G,n[2]=X+r+p,n}function te(n,t,l,s){const e=[],d=[];return e[0]=t[0]-l[0],e[1]=t[1]-l[1],e[2]=t[2]-l[2],d[0]=e[0],d[1]=e[1]*Math.cos(s)-e[2]*Math.sin(s),d[2]=e[1]*Math.sin(s)+e[2]*Math.cos(s),n[0]=d[0]+l[0],n[1]=d[1]+l[1],n[2]=d[2]+l[2],n}function ne(n,t,l,s){const e=[],d=[];return e[0]=t[0]-l[0],e[1]=t[1]-l[1],e[2]=t[2]-l[2],d[0]=e[2]*Math.sin(s)+e[0]*Math.cos(s),d[1]=e[1],d[2]=e[2]*Math.cos(s)-e[0]*Math.sin(s),n[0]=d[0]+l[0],n[1]=d[1]+l[1],n[2]=d[2]+l[2],n}function le(n,t,l,s){const e=[],d=[];return e[0]=t[0]-l[0],e[1]=t[1]-l[1],e[2]=t[2]-l[2],d[0]=e[0]*Math.cos(s)-e[1]*Math.sin(s),d[1]=e[0]*Math.sin(s)+e[1]*Math.cos(s),d[2]=e[2],n[0]=d[0]+l[0],n[1]=d[1]+l[1],n[2]=d[2]+l[2],n}function se(n,t){const l=n[0],s=n[1],e=n[2],d=t[0],i=t[1],c=t[2],o=Math.sqrt((l*l+s*s+e*e)*(d*d+i*i+c*c)),X=o&&At(n,t)/o;return Math.acos(Math.min(Math.max(X,-1),1))}function Z0(n){return n[0]=0,n[1]=0,n[2]=0,n}function G0(n){return`vec3(${n[0]}, ${n[1]}, ${n[2]})`}function m0(n,t){return n[0]===t[0]&&n[1]===t[1]&&n[2]===t[2]}function p0(n,t){const l=n[0],s=n[1],e=n[2],d=t[0],i=t[1],c=t[2];return Math.abs(l-d)<=F*Math.max(1,Math.abs(l),Math.abs(d))&&Math.abs(s-i)<=F*Math.max(1,Math.abs(s),Math.abs(i))&&Math.abs(e-c)<=F*Math.max(1,Math.abs(e),Math.abs(c))}const W0=Gl,V0=Es,y0=Os,L0=Ds,x0=qs,ee=xn,K0=_s,R0=function(){const n=rl();return function(t,l,s,e,d,i){let c,o;for(l||(l=3),s||(s=0),e?o=Math.min(e*l+s,t.length):o=t.length,c=s;c<o;c+=l)n[0]=t[c],n[1]=t[c+1],n[2]=t[c+2],d(n,n,i),t[c]=n[0],t[c+1]=n[1],t[c+2]=n[2];return t}}(),S0=Object.freeze(Object.defineProperty({__proto__:null,add:l0,angle:se,bezier:h0,ceil:s0,clone:$c,copy:t0,create:rl,cross:Tt,dist:L0,distance:Ds,div:y0,divide:Os,dot:At,equals:p0,exactEquals:m0,floor:e0,forEach:R0,fromValues:Zl,hermite:u0,inverse:ml,len:ee,length:xn,lerp:X0,max:i0,min:d0,mul:V0,multiply:Es,negate:o0,normalize:$s,random:r0,rotateX:te,rotateY:ne,rotateZ:le,round:c0,scale:As,scaleAndAdd:b0,set:n0,slerp:a0,sqrDist:x0,sqrLen:K0,squaredDistance:qs,squaredLength:_s,str:G0,sub:W0,subtract:Gl,transformMat3:Dt,transformMat4:Kn,transformQuat:pl,zero:Z0},Symbol.toStringTag,{value:"Module"})),Wl=[0,0,0];let Rn;class N extends ol{static get ZERO(){return Rn||(Rn=new N(0,0,0),Object.freeze(Rn)),Rn}constructor(t=0,l=0,s=0){super(-0,-0,-0),arguments.length===1&&Vt(t)?this.copy(t):(w.debug&&(f(t),f(l),f(s)),this[0]=t,this[1]=l,this[2]=s)}set(t,l,s){return this[0]=t,this[1]=l,this[2]=s,this.check()}copy(t){return this[0]=t[0],this[1]=t[1],this[2]=t[2],this.check()}fromObject(t){return w.debug&&(f(t.x),f(t.y),f(t.z)),this[0]=t.x,this[1]=t.y,this[2]=t.z,this.check()}toObject(t){return t.x=this[0],t.y=this[1],t.z=this[2],t}get ELEMENTS(){return 3}get z(){return this[2]}set z(t){this[2]=f(t)}angle(t){return se(this,t)}cross(t){return Tt(this,this,t),this.check()}rotateX({radians:t,origin:l=Wl}){return te(this,this,l,t),this.check()}rotateY({radians:t,origin:l=Wl}){return ne(this,this,l,t),this.check()}rotateZ({radians:t,origin:l=Wl}){return le(this,this,l,t),this.check()}transform(t){return this.transformAsPoint(t)}transformAsPoint(t){return Kn(this,this,t),this.check()}transformAsVector(t){return Us(this,this,t),this.check()}transformByMatrix3(t){return Dt(this,this,t),this.check()}transformByMatrix2(t){return qc(this,this,t),this.check()}transformByQuaternion(t){return pl(this,this,t),this.check()}}let Sn;class ut extends ol{static get ZERO(){return Sn||(Sn=new ut(0,0,0,0),Object.freeze(Sn)),Sn}constructor(t=0,l=0,s=0,e=0){super(-0,-0,-0,-0),Vt(t)&&arguments.length===1?this.copy(t):(w.debug&&(f(t),f(l),f(s),f(e)),this[0]=t,this[1]=l,this[2]=s,this[3]=e)}set(t,l,s,e){return this[0]=t,this[1]=l,this[2]=s,this[3]=e,this.check()}copy(t){return this[0]=t[0],this[1]=t[1],this[2]=t[2],this[3]=t[3],this.check()}fromObject(t){return w.debug&&(f(t.x),f(t.y),f(t.z),f(t.w)),this[0]=t.x,this[1]=t.y,this[2]=t.z,this[3]=t.w,this}toObject(t){return t.x=this[0],t.y=this[1],t.z=this[2],t.w=this[3],t}get ELEMENTS(){return 4}get z(){return this[2]}set z(t){this[2]=f(t)}get w(){return this[3]}set w(t){this[3]=f(t)}transform(t){return Kn(this,this,t),this.check()}transformByMatrix3(t){return js(this,this,t),this.check()}transformByMatrix2(t){return _c(this,this,t),this.check()}transformByQuaternion(t){return pl(this,this,t),this.check()}applyMatrix4(t){return t.transform(this,this),this}}let de=class extends Ln{toString(){let t="[";if(w.printRowMajor){t+="row-major:";for(let l=0;l<this.RANK;++l)for(let s=0;s<this.RANK;++s)t+=` ${this[s*this.RANK+l]}`}else{t+="column-major:";for(let l=0;l<this.ELEMENTS;++l)t+=` ${this[l]}`}return t+="]",t}getElementIndex(t,l){return l*this.RANK+t}getElement(t,l){return this[l*this.RANK+t]}setElement(t,l,s){return this[l*this.RANK+t]=f(s),this}getColumn(t,l=new Array(this.RANK).fill(-0)){const s=t*this.RANK;for(let e=0;e<this.RANK;++e)l[e]=this[s+e];return l}setColumn(t,l){const s=t*this.RANK;for(let e=0;e<this.RANK;++e)this[s+e]=l[e];return this}};function ie(){const n=new B(9);return B!=Float32Array&&(n[1]=0,n[2]=0,n[3]=0,n[5]=0,n[6]=0,n[7]=0),n[0]=1,n[4]=1,n[8]=1,n}function Vl(n,t){return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[4],n[4]=t[5],n[5]=t[6],n[6]=t[8],n[7]=t[9],n[8]=t[10],n}function z0(n){const t=new B(9);return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t}function M0(n,t){return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n}function Y0(n,t,l,s,e,d,i,c,o){const X=new B(9);return X[0]=n,X[1]=t,X[2]=l,X[3]=s,X[4]=e,X[5]=d,X[6]=i,X[7]=c,X[8]=o,X}function ce(n,t,l,s,e,d,i,c,o,X){return n[0]=t,n[1]=l,n[2]=s,n[3]=e,n[4]=d,n[5]=i,n[6]=c,n[7]=o,n[8]=X,n}function g0(n){return n[0]=1,n[1]=0,n[2]=0,n[3]=0,n[4]=1,n[5]=0,n[6]=0,n[7]=0,n[8]=1,n}function yl(n,t){if(n===t){const l=t[1],s=t[2],e=t[5];n[1]=t[3],n[2]=t[6],n[3]=l,n[5]=t[7],n[6]=s,n[7]=e}else n[0]=t[0],n[1]=t[3],n[2]=t[6],n[3]=t[1],n[4]=t[4],n[5]=t[7],n[6]=t[2],n[7]=t[5],n[8]=t[8];return n}function zn(n,t){const l=t[0],s=t[1],e=t[2],d=t[3],i=t[4],c=t[5],o=t[6],X=t[7],a=t[8],u=a*i-c*X,r=-a*d+c*o,Z=X*d-i*o;let G=l*u+s*r+e*Z;return G?(G=1/G,n[0]=u*G,n[1]=(-a*s+e*X)*G,n[2]=(c*s-e*i)*G,n[3]=r*G,n[4]=(a*l-e*o)*G,n[5]=(-c*l+e*d)*G,n[6]=Z*G,n[7]=(-X*l+s*o)*G,n[8]=(i*l-s*d)*G,n):null}function T0(n,t){const l=t[0],s=t[1],e=t[2],d=t[3],i=t[4],c=t[5],o=t[6],X=t[7],a=t[8];return n[0]=i*a-c*X,n[1]=e*X-s*a,n[2]=s*c-e*i,n[3]=c*o-d*a,n[4]=l*a-e*o,n[5]=e*d-l*c,n[6]=d*X-i*o,n[7]=s*o-l*X,n[8]=l*i-s*d,n}function qt(n){const t=n[0],l=n[1],s=n[2],e=n[3],d=n[4],i=n[5],c=n[6],o=n[7],X=n[8];return t*(X*d-i*o)+l*(-X*e+i*c)+s*(o*e-d*c)}function Mn(n,t,l){const s=t[0],e=t[1],d=t[2],i=t[3],c=t[4],o=t[5],X=t[6],a=t[7],u=t[8],r=l[0],Z=l[1],G=l[2],p=l[3],m=l[4],W=l[5],L=l[6],V=l[7],y=l[8];return n[0]=r*s+Z*i+G*X,n[1]=r*e+Z*c+G*a,n[2]=r*d+Z*o+G*u,n[3]=p*s+m*i+W*X,n[4]=p*e+m*c+W*a,n[5]=p*d+m*o+W*u,n[6]=L*s+V*i+y*X,n[7]=L*e+V*c+y*a,n[8]=L*d+V*o+y*u,n}function be(n,t,l){const s=t[0],e=t[1],d=t[2],i=t[3],c=t[4],o=t[5],X=t[6],a=t[7],u=t[8],r=l[0],Z=l[1];return n[0]=s,n[1]=e,n[2]=d,n[3]=i,n[4]=c,n[5]=o,n[6]=r*s+Z*i+X,n[7]=r*e+Z*c+a,n[8]=r*d+Z*o+u,n}function oe(n,t,l){const s=t[0],e=t[1],d=t[2],i=t[3],c=t[4],o=t[5],X=t[6],a=t[7],u=t[8],r=Math.sin(l),Z=Math.cos(l);return n[0]=Z*s+r*i,n[1]=Z*e+r*c,n[2]=Z*d+r*o,n[3]=Z*i-r*s,n[4]=Z*c-r*e,n[5]=Z*o-r*d,n[6]=X,n[7]=a,n[8]=u,n}function Ll(n,t,l){const s=l[0],e=l[1];return n[0]=s*t[0],n[1]=s*t[1],n[2]=s*t[2],n[3]=e*t[3],n[4]=e*t[4],n[5]=e*t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n}function C0(n,t){return n[0]=1,n[1]=0,n[2]=0,n[3]=0,n[4]=1,n[5]=0,n[6]=t[0],n[7]=t[1],n[8]=1,n}function f0(n,t){const l=Math.sin(t),s=Math.cos(t);return n[0]=s,n[1]=l,n[2]=0,n[3]=-l,n[4]=s,n[5]=0,n[6]=0,n[7]=0,n[8]=1,n}function F0(n,t){return n[0]=t[0],n[1]=0,n[2]=0,n[3]=0,n[4]=t[1],n[5]=0,n[6]=0,n[7]=0,n[8]=1,n}function N0(n,t){return n[0]=t[0],n[1]=t[1],n[2]=0,n[3]=t[2],n[4]=t[3],n[5]=0,n[6]=t[4],n[7]=t[5],n[8]=1,n}function xl(n,t){const l=t[0],s=t[1],e=t[2],d=t[3],i=l+l,c=s+s,o=e+e,X=l*i,a=s*i,u=s*c,r=e*i,Z=e*c,G=e*o,p=d*i,m=d*c,W=d*o;return n[0]=1-u-G,n[3]=a-W,n[6]=r+m,n[1]=a+W,n[4]=1-X-G,n[7]=Z-p,n[2]=r-m,n[5]=Z+p,n[8]=1-X-u,n}function Kl(n,t){const l=t[0],s=t[1],e=t[2],d=t[3],i=t[4],c=t[5],o=t[6],X=t[7],a=t[8],u=t[9],r=t[10],Z=t[11],G=t[12],p=t[13],m=t[14],W=t[15],L=l*c-s*i,V=l*o-e*i,y=l*X-d*i,S=s*o-e*c,K=s*X-d*c,T=e*X-d*o,Y=a*p-u*G,g=a*m-r*G,z=a*W-Z*G,H=u*m-r*p,J=u*W-Z*p,I=r*W-Z*m;let C=L*I-V*J+y*H+S*z-K*g+T*Y;return C?(C=1/C,n[0]=(c*I-o*J+X*H)*C,n[1]=(o*z-i*I-X*g)*C,n[2]=(i*J-c*z+X*Y)*C,n[3]=(e*J-s*I-d*H)*C,n[4]=(l*I-e*z+d*g)*C,n[5]=(s*z-l*J-d*Y)*C,n[6]=(p*T-m*K+W*S)*C,n[7]=(m*y-G*T-W*V)*C,n[8]=(G*K-p*y+W*L)*C,n):null}function H0(n,t,l){return n[0]=2/t,n[1]=0,n[2]=0,n[3]=0,n[4]=-2/l,n[5]=0,n[6]=-1,n[7]=1,n[8]=1,n}function J0(n){return`mat3(${n[0]}, ${n[1]}, ${n[2]}, ${n[3]}, ${n[4]}, ${n[5]}, ${n[6]}, ${n[7]}, ${n[8]})`}function I0(n){return Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]+n[3]*n[3]+n[4]*n[4]+n[5]*n[5]+n[6]*n[6]+n[7]*n[7]+n[8]*n[8])}function k0(n,t,l){return n[0]=t[0]+l[0],n[1]=t[1]+l[1],n[2]=t[2]+l[2],n[3]=t[3]+l[3],n[4]=t[4]+l[4],n[5]=t[5]+l[5],n[6]=t[6]+l[6],n[7]=t[7]+l[7],n[8]=t[8]+l[8],n}function Xe(n,t,l){return n[0]=t[0]-l[0],n[1]=t[1]-l[1],n[2]=t[2]-l[2],n[3]=t[3]-l[3],n[4]=t[4]-l[4],n[5]=t[5]-l[5],n[6]=t[6]-l[6],n[7]=t[7]-l[7],n[8]=t[8]-l[8],n}function P0(n,t,l){return n[0]=t[0]*l,n[1]=t[1]*l,n[2]=t[2]*l,n[3]=t[3]*l,n[4]=t[4]*l,n[5]=t[5]*l,n[6]=t[6]*l,n[7]=t[7]*l,n[8]=t[8]*l,n}function Q0(n,t,l,s){return n[0]=t[0]+l[0]*s,n[1]=t[1]+l[1]*s,n[2]=t[2]+l[2]*s,n[3]=t[3]+l[3]*s,n[4]=t[4]+l[4]*s,n[5]=t[5]+l[5]*s,n[6]=t[6]+l[6]*s,n[7]=t[7]+l[7]*s,n[8]=t[8]+l[8]*s,n}function B0(n,t){return n[0]===t[0]&&n[1]===t[1]&&n[2]===t[2]&&n[3]===t[3]&&n[4]===t[4]&&n[5]===t[5]&&n[6]===t[6]&&n[7]===t[7]&&n[8]===t[8]}function v0(n,t){const l=n[0],s=n[1],e=n[2],d=n[3],i=n[4],c=n[5],o=n[6],X=n[7],a=n[8],u=t[0],r=t[1],Z=t[2],G=t[3],p=t[4],m=t[5],W=t[6],L=t[7],V=t[8];return Math.abs(l-u)<=F*Math.max(1,Math.abs(l),Math.abs(u))&&Math.abs(s-r)<=F*Math.max(1,Math.abs(s),Math.abs(r))&&Math.abs(e-Z)<=F*Math.max(1,Math.abs(e),Math.abs(Z))&&Math.abs(d-G)<=F*Math.max(1,Math.abs(d),Math.abs(G))&&Math.abs(i-p)<=F*Math.max(1,Math.abs(i),Math.abs(p))&&Math.abs(c-m)<=F*Math.max(1,Math.abs(c),Math.abs(m))&&Math.abs(o-W)<=F*Math.max(1,Math.abs(o),Math.abs(W))&&Math.abs(X-L)<=F*Math.max(1,Math.abs(X),Math.abs(L))&&Math.abs(a-V)<=F*Math.max(1,Math.abs(a),Math.abs(V))}const w0=Object.freeze(Object.defineProperty({__proto__:null,add:k0,adjoint:T0,clone:z0,copy:M0,create:ie,determinant:qt,equals:v0,exactEquals:B0,frob:I0,fromMat2d:N0,fromMat4:Vl,fromQuat:xl,fromRotation:f0,fromScaling:F0,fromTranslation:C0,fromValues:Y0,identity:g0,invert:zn,mul:Mn,multiply:Mn,multiplyScalar:P0,multiplyScalarAndAdd:Q0,normalFromMat4:Kl,projection:H0,rotate:oe,scale:Ll,set:ce,str:J0,sub:Xe,subtract:Xe,translate:be,transpose:yl},Symbol.toStringTag,{value:"Module"}));var Rl;(function(n){n[n.COL0ROW0=0]="COL0ROW0",n[n.COL0ROW1=1]="COL0ROW1",n[n.COL0ROW2=2]="COL0ROW2",n[n.COL1ROW0=3]="COL1ROW0",n[n.COL1ROW1=4]="COL1ROW1",n[n.COL1ROW2=5]="COL1ROW2",n[n.COL2ROW0=6]="COL2ROW0",n[n.COL2ROW1=7]="COL2ROW1",n[n.COL2ROW2=8]="COL2ROW2"})(Rl||(Rl={}));const U0=Object.freeze([1,0,0,0,1,0,0,0,1]);class Xt extends de{static get IDENTITY(){return E0()}static get ZERO(){return j0()}get ELEMENTS(){return 9}get RANK(){return 3}get INDICES(){return Rl}constructor(t,...l){super(-0,-0,-0,-0,-0,-0,-0,-0,-0),arguments.length===1&&Array.isArray(t)?this.copy(t):l.length>0?this.copy([t,...l]):this.identity()}copy(t){return this[0]=t[0],this[1]=t[1],this[2]=t[2],this[3]=t[3],this[4]=t[4],this[5]=t[5],this[6]=t[6],this[7]=t[7],this[8]=t[8],this.check()}identity(){return this.copy(U0)}fromObject(t){return this.check()}fromQuaternion(t){return xl(this,t),this.check()}set(t,l,s,e,d,i,c,o,X){return this[0]=t,this[1]=l,this[2]=s,this[3]=e,this[4]=d,this[5]=i,this[6]=c,this[7]=o,this[8]=X,this.check()}setRowMajor(t,l,s,e,d,i,c,o,X){return this[0]=t,this[1]=e,this[2]=c,this[3]=l,this[4]=d,this[5]=o,this[6]=s,this[7]=i,this[8]=X,this.check()}determinant(){return qt(this)}transpose(){return yl(this,this),this.check()}invert(){return zn(this,this),this.check()}multiplyLeft(t){return Mn(this,t,this),this.check()}multiplyRight(t){return Mn(this,this,t),this.check()}rotate(t){return oe(this,this,t),this.check()}scale(t){return Array.isArray(t)?Ll(this,this,t):Ll(this,this,[t,t]),this.check()}translate(t){return be(this,this,t),this.check()}transform(t,l){let s;switch(t.length){case 2:s=al(l||[-0,-0],t,this);break;case 3:s=Dt(l||[-0,-0,-0],t,this);break;case 4:s=js(l||[-0,-0,-0,-0],t,this);break;default:throw new Error("Illegal vector")}return Ot(s,t.length),s}transformVector(t,l){return this.transform(t,l)}transformVector2(t,l){return this.transform(t,l)}transformVector3(t,l){return this.transform(t,l)}}let Yn,gn=null;function j0(){return Yn||(Yn=new Xt([0,0,0,0,0,0,0,0,0]),Object.freeze(Yn)),Yn}function E0(){return gn||(gn=new Xt,Object.freeze(gn)),gn}function O0(){const n=new B(16);return B!=Float32Array&&(n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[11]=0,n[12]=0,n[13]=0,n[14]=0),n[0]=1,n[5]=1,n[10]=1,n[15]=1,n}function A0(n){const t=new B(16);return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t[9]=n[9],t[10]=n[10],t[11]=n[11],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15],t}function D0(n,t){return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15],n}function q0(n,t,l,s,e,d,i,c,o,X,a,u,r,Z,G,p){const m=new B(16);return m[0]=n,m[1]=t,m[2]=l,m[3]=s,m[4]=e,m[5]=d,m[6]=i,m[7]=c,m[8]=o,m[9]=X,m[10]=a,m[11]=u,m[12]=r,m[13]=Z,m[14]=G,m[15]=p,m}function _0(n,t,l,s,e,d,i,c,o,X,a,u,r,Z,G,p,m){return n[0]=t,n[1]=l,n[2]=s,n[3]=e,n[4]=d,n[5]=i,n[6]=c,n[7]=o,n[8]=X,n[9]=a,n[10]=u,n[11]=r,n[12]=Z,n[13]=G,n[14]=p,n[15]=m,n}function ae(n){return n[0]=1,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=1,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=1,n[11]=0,n[12]=0,n[13]=0,n[14]=0,n[15]=1,n}function ue(n,t){if(n===t){const l=t[1],s=t[2],e=t[3],d=t[6],i=t[7],c=t[11];n[1]=t[4],n[2]=t[8],n[3]=t[12],n[4]=l,n[6]=t[9],n[7]=t[13],n[8]=s,n[9]=d,n[11]=t[14],n[12]=e,n[13]=i,n[14]=c}else n[0]=t[0],n[1]=t[4],n[2]=t[8],n[3]=t[12],n[4]=t[1],n[5]=t[5],n[6]=t[9],n[7]=t[13],n[8]=t[2],n[9]=t[6],n[10]=t[10],n[11]=t[14],n[12]=t[3],n[13]=t[7],n[14]=t[11],n[15]=t[15];return n}function he(n,t){const l=t[0],s=t[1],e=t[2],d=t[3],i=t[4],c=t[5],o=t[6],X=t[7],a=t[8],u=t[9],r=t[10],Z=t[11],G=t[12],p=t[13],m=t[14],W=t[15],L=l*c-s*i,V=l*o-e*i,y=l*X-d*i,S=s*o-e*c,K=s*X-d*c,T=e*X-d*o,Y=a*p-u*G,g=a*m-r*G,z=a*W-Z*G,H=u*m-r*p,J=u*W-Z*p,I=r*W-Z*m;let C=L*I-V*J+y*H+S*z-K*g+T*Y;return C?(C=1/C,n[0]=(c*I-o*J+X*H)*C,n[1]=(e*J-s*I-d*H)*C,n[2]=(p*T-m*K+W*S)*C,n[3]=(r*K-u*T-Z*S)*C,n[4]=(o*z-i*I-X*g)*C,n[5]=(l*I-e*z+d*g)*C,n[6]=(m*y-G*T-W*V)*C,n[7]=(a*T-r*y+Z*V)*C,n[8]=(i*J-c*z+X*Y)*C,n[9]=(s*z-l*J-d*Y)*C,n[10]=(G*K-p*y+W*L)*C,n[11]=(u*y-a*K-Z*L)*C,n[12]=(c*g-i*H-o*Y)*C,n[13]=(l*H-s*g+e*Y)*C,n[14]=(p*V-G*S-m*L)*C,n[15]=(a*S-u*V+r*L)*C,n):null}function $0(n,t){const l=t[0],s=t[1],e=t[2],d=t[3],i=t[4],c=t[5],o=t[6],X=t[7],a=t[8],u=t[9],r=t[10],Z=t[11],G=t[12],p=t[13],m=t[14],W=t[15],L=l*c-s*i,V=l*o-e*i,y=l*X-d*i,S=s*o-e*c,K=s*X-d*c,T=e*X-d*o,Y=a*p-u*G,g=a*m-r*G,z=a*W-Z*G,H=u*m-r*p,J=u*W-Z*p,I=r*W-Z*m;return n[0]=c*I-o*J+X*H,n[1]=e*J-s*I-d*H,n[2]=p*T-m*K+W*S,n[3]=r*K-u*T-Z*S,n[4]=o*z-i*I-X*g,n[5]=l*I-e*z+d*g,n[6]=m*y-G*T-W*V,n[7]=a*T-r*y+Z*V,n[8]=i*J-c*z+X*Y,n[9]=s*z-l*J-d*Y,n[10]=G*K-p*y+W*L,n[11]=u*y-a*K-Z*L,n[12]=c*g-i*H-o*Y,n[13]=l*H-s*g+e*Y,n[14]=p*V-G*S-m*L,n[15]=a*S-u*V+r*L,n}function re(n){const t=n[0],l=n[1],s=n[2],e=n[3],d=n[4],i=n[5],c=n[6],o=n[7],X=n[8],a=n[9],u=n[10],r=n[11],Z=n[12],G=n[13],p=n[14],m=n[15],W=t*i-l*d,L=t*c-s*d,V=l*c-s*i,y=X*G-a*Z,S=X*p-u*Z,K=a*p-u*G,T=t*K-l*S+s*y,Y=d*K-i*S+c*y,g=X*V-a*L+u*W,z=Z*V-G*L+p*W;return o*T-e*Y+m*g-r*z}function Tn(n,t,l){const s=t[0],e=t[1],d=t[2],i=t[3],c=t[4],o=t[5],X=t[6],a=t[7],u=t[8],r=t[9],Z=t[10],G=t[11],p=t[12],m=t[13],W=t[14],L=t[15];let V=l[0],y=l[1],S=l[2],K=l[3];return n[0]=V*s+y*c+S*u+K*p,n[1]=V*e+y*o+S*r+K*m,n[2]=V*d+y*X+S*Z+K*W,n[3]=V*i+y*a+S*G+K*L,V=l[4],y=l[5],S=l[6],K=l[7],n[4]=V*s+y*c+S*u+K*p,n[5]=V*e+y*o+S*r+K*m,n[6]=V*d+y*X+S*Z+K*W,n[7]=V*i+y*a+S*G+K*L,V=l[8],y=l[9],S=l[10],K=l[11],n[8]=V*s+y*c+S*u+K*p,n[9]=V*e+y*o+S*r+K*m,n[10]=V*d+y*X+S*Z+K*W,n[11]=V*i+y*a+S*G+K*L,V=l[12],y=l[13],S=l[14],K=l[15],n[12]=V*s+y*c+S*u+K*p,n[13]=V*e+y*o+S*r+K*m,n[14]=V*d+y*X+S*Z+K*W,n[15]=V*i+y*a+S*G+K*L,n}function Ze(n,t,l){const s=l[0],e=l[1],d=l[2];let i,c,o,X,a,u,r,Z,G,p,m,W;return t===n?(n[12]=t[0]*s+t[4]*e+t[8]*d+t[12],n[13]=t[1]*s+t[5]*e+t[9]*d+t[13],n[14]=t[2]*s+t[6]*e+t[10]*d+t[14],n[15]=t[3]*s+t[7]*e+t[11]*d+t[15]):(i=t[0],c=t[1],o=t[2],X=t[3],a=t[4],u=t[5],r=t[6],Z=t[7],G=t[8],p=t[9],m=t[10],W=t[11],n[0]=i,n[1]=c,n[2]=o,n[3]=X,n[4]=a,n[5]=u,n[6]=r,n[7]=Z,n[8]=G,n[9]=p,n[10]=m,n[11]=W,n[12]=i*s+a*e+G*d+t[12],n[13]=c*s+u*e+p*d+t[13],n[14]=o*s+r*e+m*d+t[14],n[15]=X*s+Z*e+W*d+t[15]),n}function Ge(n,t,l){const s=l[0],e=l[1],d=l[2];return n[0]=t[0]*s,n[1]=t[1]*s,n[2]=t[2]*s,n[3]=t[3]*s,n[4]=t[4]*e,n[5]=t[5]*e,n[6]=t[6]*e,n[7]=t[7]*e,n[8]=t[8]*d,n[9]=t[9]*d,n[10]=t[10]*d,n[11]=t[11]*d,n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15],n}function me(n,t,l,s){let e=s[0],d=s[1],i=s[2],c=Math.sqrt(e*e+d*d+i*i),o,X,a,u,r,Z,G,p,m,W,L,V,y,S,K,T,Y,g,z,H,J,I,C,D;return c<F?null:(c=1/c,e*=c,d*=c,i*=c,X=Math.sin(l),o=Math.cos(l),a=1-o,u=t[0],r=t[1],Z=t[2],G=t[3],p=t[4],m=t[5],W=t[6],L=t[7],V=t[8],y=t[9],S=t[10],K=t[11],T=e*e*a+o,Y=d*e*a+i*X,g=i*e*a-d*X,z=e*d*a-i*X,H=d*d*a+o,J=i*d*a+e*X,I=e*i*a+d*X,C=d*i*a-e*X,D=i*i*a+o,n[0]=u*T+p*Y+V*g,n[1]=r*T+m*Y+y*g,n[2]=Z*T+W*Y+S*g,n[3]=G*T+L*Y+K*g,n[4]=u*z+p*H+V*J,n[5]=r*z+m*H+y*J,n[6]=Z*z+W*H+S*J,n[7]=G*z+L*H+K*J,n[8]=u*I+p*C+V*D,n[9]=r*I+m*C+y*D,n[10]=Z*I+W*C+S*D,n[11]=G*I+L*C+K*D,t!==n&&(n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15]),n)}function pe(n,t,l){const s=Math.sin(l),e=Math.cos(l),d=t[4],i=t[5],c=t[6],o=t[7],X=t[8],a=t[9],u=t[10],r=t[11];return t!==n&&(n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15]),n[4]=d*e+X*s,n[5]=i*e+a*s,n[6]=c*e+u*s,n[7]=o*e+r*s,n[8]=X*e-d*s,n[9]=a*e-i*s,n[10]=u*e-c*s,n[11]=r*e-o*s,n}function We(n,t,l){const s=Math.sin(l),e=Math.cos(l),d=t[0],i=t[1],c=t[2],o=t[3],X=t[8],a=t[9],u=t[10],r=t[11];return t!==n&&(n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15]),n[0]=d*e-X*s,n[1]=i*e-a*s,n[2]=c*e-u*s,n[3]=o*e-r*s,n[8]=d*s+X*e,n[9]=i*s+a*e,n[10]=c*s+u*e,n[11]=o*s+r*e,n}function Ve(n,t,l){const s=Math.sin(l),e=Math.cos(l),d=t[0],i=t[1],c=t[2],o=t[3],X=t[4],a=t[5],u=t[6],r=t[7];return t!==n&&(n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15]),n[0]=d*e+X*s,n[1]=i*e+a*s,n[2]=c*e+u*s,n[3]=o*e+r*s,n[4]=X*e-d*s,n[5]=a*e-i*s,n[6]=u*e-c*s,n[7]=r*e-o*s,n}function tb(n,t){return n[0]=1,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=1,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=1,n[11]=0,n[12]=t[0],n[13]=t[1],n[14]=t[2],n[15]=1,n}function nb(n,t){return n[0]=t[0],n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=t[1],n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=t[2],n[11]=0,n[12]=0,n[13]=0,n[14]=0,n[15]=1,n}function lb(n,t,l){let s=l[0],e=l[1],d=l[2],i=Math.sqrt(s*s+e*e+d*d),c,o,X;return i<F?null:(i=1/i,s*=i,e*=i,d*=i,o=Math.sin(t),c=Math.cos(t),X=1-c,n[0]=s*s*X+c,n[1]=e*s*X+d*o,n[2]=d*s*X-e*o,n[3]=0,n[4]=s*e*X-d*o,n[5]=e*e*X+c,n[6]=d*e*X+s*o,n[7]=0,n[8]=s*d*X+e*o,n[9]=e*d*X-s*o,n[10]=d*d*X+c,n[11]=0,n[12]=0,n[13]=0,n[14]=0,n[15]=1,n)}function sb(n,t){const l=Math.sin(t),s=Math.cos(t);return n[0]=1,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=s,n[6]=l,n[7]=0,n[8]=0,n[9]=-l,n[10]=s,n[11]=0,n[12]=0,n[13]=0,n[14]=0,n[15]=1,n}function eb(n,t){const l=Math.sin(t),s=Math.cos(t);return n[0]=s,n[1]=0,n[2]=-l,n[3]=0,n[4]=0,n[5]=1,n[6]=0,n[7]=0,n[8]=l,n[9]=0,n[10]=s,n[11]=0,n[12]=0,n[13]=0,n[14]=0,n[15]=1,n}function db(n,t){const l=Math.sin(t),s=Math.cos(t);return n[0]=s,n[1]=l,n[2]=0,n[3]=0,n[4]=-l,n[5]=s,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=1,n[11]=0,n[12]=0,n[13]=0,n[14]=0,n[15]=1,n}function ye(n,t,l){const s=t[0],e=t[1],d=t[2],i=t[3],c=s+s,o=e+e,X=d+d,a=s*c,u=s*o,r=s*X,Z=e*o,G=e*X,p=d*X,m=i*c,W=i*o,L=i*X;return n[0]=1-(Z+p),n[1]=u+L,n[2]=r-W,n[3]=0,n[4]=u-L,n[5]=1-(a+p),n[6]=G+m,n[7]=0,n[8]=r+W,n[9]=G-m,n[10]=1-(a+Z),n[11]=0,n[12]=l[0],n[13]=l[1],n[14]=l[2],n[15]=1,n}function ib(n,t){const l=new B(3),s=-t[0],e=-t[1],d=-t[2],i=t[3],c=t[4],o=t[5],X=t[6],a=t[7],u=s*s+e*e+d*d+i*i;return u>0?(l[0]=(c*i+a*s+o*d-X*e)*2/u,l[1]=(o*i+a*e+X*s-c*d)*2/u,l[2]=(X*i+a*d+c*e-o*s)*2/u):(l[0]=(c*i+a*s+o*d-X*e)*2,l[1]=(o*i+a*e+X*s-c*d)*2,l[2]=(X*i+a*d+c*e-o*s)*2),ye(n,t,l),n}function Sl(n,t){return n[0]=t[12],n[1]=t[13],n[2]=t[14],n}function Le(n,t){const l=t[0],s=t[1],e=t[2],d=t[4],i=t[5],c=t[6],o=t[8],X=t[9],a=t[10];return n[0]=Math.sqrt(l*l+s*s+e*e),n[1]=Math.sqrt(d*d+i*i+c*c),n[2]=Math.sqrt(o*o+X*X+a*a),n}function cb(n,t){const l=new B(3);Le(l,t);const s=1/l[0],e=1/l[1],d=1/l[2],i=t[0]*s,c=t[1]*e,o=t[2]*d,X=t[4]*s,a=t[5]*e,u=t[6]*d,r=t[8]*s,Z=t[9]*e,G=t[10]*d,p=i+a+G;let m=0;return p>0?(m=Math.sqrt(p+1)*2,n[3]=.25*m,n[0]=(u-Z)/m,n[1]=(r-o)/m,n[2]=(c-X)/m):i>a&&i>G?(m=Math.sqrt(1+i-a-G)*2,n[3]=(u-Z)/m,n[0]=.25*m,n[1]=(c+X)/m,n[2]=(r+o)/m):a>G?(m=Math.sqrt(1+a-i-G)*2,n[3]=(r-o)/m,n[0]=(c+X)/m,n[1]=.25*m,n[2]=(u+Z)/m):(m=Math.sqrt(1+G-i-a)*2,n[3]=(c-X)/m,n[0]=(r+o)/m,n[1]=(u+Z)/m,n[2]=.25*m),n}function bb(n,t,l,s){t[0]=s[12],t[1]=s[13],t[2]=s[14];const e=s[0],d=s[1],i=s[2],c=s[4],o=s[5],X=s[6],a=s[8],u=s[9],r=s[10];l[0]=Math.sqrt(e*e+d*d+i*i),l[1]=Math.sqrt(c*c+o*o+X*X),l[2]=Math.sqrt(a*a+u*u+r*r);const Z=1/l[0],G=1/l[1],p=1/l[2],m=e*Z,W=d*G,L=i*p,V=c*Z,y=o*G,S=X*p,K=a*Z,T=u*G,Y=r*p,g=m+y+Y;let z=0;return g>0?(z=Math.sqrt(g+1)*2,n[3]=.25*z,n[0]=(S-T)/z,n[1]=(K-L)/z,n[2]=(W-V)/z):m>y&&m>Y?(z=Math.sqrt(1+m-y-Y)*2,n[3]=(S-T)/z,n[0]=.25*z,n[1]=(W+V)/z,n[2]=(K+L)/z):y>Y?(z=Math.sqrt(1+y-m-Y)*2,n[3]=(K-L)/z,n[0]=(W+V)/z,n[1]=.25*z,n[2]=(S+T)/z):(z=Math.sqrt(1+Y-m-y)*2,n[3]=(W-V)/z,n[0]=(K+L)/z,n[1]=(S+T)/z,n[2]=.25*z),n}function ob(n,t,l,s){const e=t[0],d=t[1],i=t[2],c=t[3],o=e+e,X=d+d,a=i+i,u=e*o,r=e*X,Z=e*a,G=d*X,p=d*a,m=i*a,W=c*o,L=c*X,V=c*a,y=s[0],S=s[1],K=s[2];return n[0]=(1-(G+m))*y,n[1]=(r+V)*y,n[2]=(Z-L)*y,n[3]=0,n[4]=(r-V)*S,n[5]=(1-(u+m))*S,n[6]=(p+W)*S,n[7]=0,n[8]=(Z+L)*K,n[9]=(p-W)*K,n[10]=(1-(u+G))*K,n[11]=0,n[12]=l[0],n[13]=l[1],n[14]=l[2],n[15]=1,n}function Xb(n,t,l,s,e){const d=t[0],i=t[1],c=t[2],o=t[3],X=d+d,a=i+i,u=c+c,r=d*X,Z=d*a,G=d*u,p=i*a,m=i*u,W=c*u,L=o*X,V=o*a,y=o*u,S=s[0],K=s[1],T=s[2],Y=e[0],g=e[1],z=e[2],H=(1-(p+W))*S,J=(Z+y)*S,I=(G-V)*S,C=(Z-y)*K,D=(1-(r+W))*K,zt=(m+L)*K,Mt=(G+V)*T,Gs=(m-L)*T,nl=(1-(r+p))*T;return n[0]=H,n[1]=J,n[2]=I,n[3]=0,n[4]=C,n[5]=D,n[6]=zt,n[7]=0,n[8]=Mt,n[9]=Gs,n[10]=nl,n[11]=0,n[12]=l[0]+Y-(H*Y+C*g+Mt*z),n[13]=l[1]+g-(J*Y+D*g+Gs*z),n[14]=l[2]+z-(I*Y+zt*g+nl*z),n[15]=1,n}function xe(n,t){const l=t[0],s=t[1],e=t[2],d=t[3],i=l+l,c=s+s,o=e+e,X=l*i,a=s*i,u=s*c,r=e*i,Z=e*c,G=e*o,p=d*i,m=d*c,W=d*o;return n[0]=1-u-G,n[1]=a+W,n[2]=r-m,n[3]=0,n[4]=a-W,n[5]=1-X-G,n[6]=Z+p,n[7]=0,n[8]=r+m,n[9]=Z-p,n[10]=1-X-u,n[11]=0,n[12]=0,n[13]=0,n[14]=0,n[15]=1,n}function Ke(n,t,l,s,e,d,i){const c=1/(l-t),o=1/(e-s),X=1/(d-i);return n[0]=d*2*c,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=d*2*o,n[6]=0,n[7]=0,n[8]=(l+t)*c,n[9]=(e+s)*o,n[10]=(i+d)*X,n[11]=-1,n[12]=0,n[13]=0,n[14]=i*d*2*X,n[15]=0,n}function Re(n,t,l,s,e){const d=1/Math.tan(t/2);if(n[0]=d/l,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=d,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[11]=-1,n[12]=0,n[13]=0,n[15]=0,e!=null&&e!==1/0){const i=1/(s-e);n[10]=(e+s)*i,n[14]=2*e*s*i}else n[10]=-1,n[14]=-2*s;return n}const Se=Re;function ab(n,t,l,s,e){const d=1/Math.tan(t/2);if(n[0]=d/l,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=d,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[11]=-1,n[12]=0,n[13]=0,n[15]=0,e!=null&&e!==1/0){const i=1/(s-e);n[10]=e*i,n[14]=e*s*i}else n[10]=-1,n[14]=-s;return n}function ub(n,t,l,s){const e=Math.tan(t.upDegrees*Math.PI/180),d=Math.tan(t.downDegrees*Math.PI/180),i=Math.tan(t.leftDegrees*Math.PI/180),c=Math.tan(t.rightDegrees*Math.PI/180),o=2/(i+c),X=2/(e+d);return n[0]=o,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=X,n[6]=0,n[7]=0,n[8]=-((i-c)*o*.5),n[9]=(e-d)*X*.5,n[10]=s/(l-s),n[11]=-1,n[12]=0,n[13]=0,n[14]=s*l/(l-s),n[15]=0,n}function ze(n,t,l,s,e,d,i){const c=1/(t-l),o=1/(s-e),X=1/(d-i);return n[0]=-2*c,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=-2*o,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=2*X,n[11]=0,n[12]=(t+l)*c,n[13]=(e+s)*o,n[14]=(i+d)*X,n[15]=1,n}const Me=ze;function hb(n,t,l,s,e,d,i){const c=1/(t-l),o=1/(s-e),X=1/(d-i);return n[0]=-2*c,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=-2*o,n[6]=0,n[7]=0,n[8]=0,n[9]=0,n[10]=X,n[11]=0,n[12]=(t+l)*c,n[13]=(e+s)*o,n[14]=d*X,n[15]=1,n}function Ye(n,t,l,s){let e,d,i,c,o,X,a,u,r,Z;const G=t[0],p=t[1],m=t[2],W=s[0],L=s[1],V=s[2],y=l[0],S=l[1],K=l[2];return Math.abs(G-y)<F&&Math.abs(p-S)<F&&Math.abs(m-K)<F?ae(n):(u=G-y,r=p-S,Z=m-K,e=1/Math.sqrt(u*u+r*r+Z*Z),u*=e,r*=e,Z*=e,d=L*Z-V*r,i=V*u-W*Z,c=W*r-L*u,e=Math.sqrt(d*d+i*i+c*c),e?(e=1/e,d*=e,i*=e,c*=e):(d=0,i=0,c=0),o=r*c-Z*i,X=Z*d-u*c,a=u*i-r*d,e=Math.sqrt(o*o+X*X+a*a),e?(e=1/e,o*=e,X*=e,a*=e):(o=0,X=0,a=0),n[0]=d,n[1]=o,n[2]=u,n[3]=0,n[4]=i,n[5]=X,n[6]=r,n[7]=0,n[8]=c,n[9]=a,n[10]=Z,n[11]=0,n[12]=-(d*G+i*p+c*m),n[13]=-(o*G+X*p+a*m),n[14]=-(u*G+r*p+Z*m),n[15]=1,n)}function rb(n,t,l,s){const e=t[0],d=t[1],i=t[2],c=s[0],o=s[1],X=s[2];let a=e-l[0],u=d-l[1],r=i-l[2],Z=a*a+u*u+r*r;Z>0&&(Z=1/Math.sqrt(Z),a*=Z,u*=Z,r*=Z);let G=o*r-X*u,p=X*a-c*r,m=c*u-o*a;return Z=G*G+p*p+m*m,Z>0&&(Z=1/Math.sqrt(Z),G*=Z,p*=Z,m*=Z),n[0]=G,n[1]=p,n[2]=m,n[3]=0,n[4]=u*m-r*p,n[5]=r*G-a*m,n[6]=a*p-u*G,n[7]=0,n[8]=a,n[9]=u,n[10]=r,n[11]=0,n[12]=e,n[13]=d,n[14]=i,n[15]=1,n}function Zb(n){return`mat4(${n[0]}, ${n[1]}, ${n[2]}, ${n[3]}, ${n[4]}, ${n[5]}, ${n[6]}, ${n[7]}, ${n[8]}, ${n[9]}, ${n[10]}, ${n[11]}, ${n[12]}, ${n[13]}, ${n[14]}, ${n[15]})`}function Gb(n){return Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]+n[3]*n[3]+n[4]*n[4]+n[5]*n[5]+n[6]*n[6]+n[7]*n[7]+n[8]*n[8]+n[9]*n[9]+n[10]*n[10]+n[11]*n[11]+n[12]*n[12]+n[13]*n[13]+n[14]*n[14]+n[15]*n[15])}function mb(n,t,l){return n[0]=t[0]+l[0],n[1]=t[1]+l[1],n[2]=t[2]+l[2],n[3]=t[3]+l[3],n[4]=t[4]+l[4],n[5]=t[5]+l[5],n[6]=t[6]+l[6],n[7]=t[7]+l[7],n[8]=t[8]+l[8],n[9]=t[9]+l[9],n[10]=t[10]+l[10],n[11]=t[11]+l[11],n[12]=t[12]+l[12],n[13]=t[13]+l[13],n[14]=t[14]+l[14],n[15]=t[15]+l[15],n}function ge(n,t,l){return n[0]=t[0]-l[0],n[1]=t[1]-l[1],n[2]=t[2]-l[2],n[3]=t[3]-l[3],n[4]=t[4]-l[4],n[5]=t[5]-l[5],n[6]=t[6]-l[6],n[7]=t[7]-l[7],n[8]=t[8]-l[8],n[9]=t[9]-l[9],n[10]=t[10]-l[10],n[11]=t[11]-l[11],n[12]=t[12]-l[12],n[13]=t[13]-l[13],n[14]=t[14]-l[14],n[15]=t[15]-l[15],n}function pb(n,t,l){return n[0]=t[0]*l,n[1]=t[1]*l,n[2]=t[2]*l,n[3]=t[3]*l,n[4]=t[4]*l,n[5]=t[5]*l,n[6]=t[6]*l,n[7]=t[7]*l,n[8]=t[8]*l,n[9]=t[9]*l,n[10]=t[10]*l,n[11]=t[11]*l,n[12]=t[12]*l,n[13]=t[13]*l,n[14]=t[14]*l,n[15]=t[15]*l,n}function Wb(n,t,l,s){return n[0]=t[0]+l[0]*s,n[1]=t[1]+l[1]*s,n[2]=t[2]+l[2]*s,n[3]=t[3]+l[3]*s,n[4]=t[4]+l[4]*s,n[5]=t[5]+l[5]*s,n[6]=t[6]+l[6]*s,n[7]=t[7]+l[7]*s,n[8]=t[8]+l[8]*s,n[9]=t[9]+l[9]*s,n[10]=t[10]+l[10]*s,n[11]=t[11]+l[11]*s,n[12]=t[12]+l[12]*s,n[13]=t[13]+l[13]*s,n[14]=t[14]+l[14]*s,n[15]=t[15]+l[15]*s,n}function Vb(n,t){return n[0]===t[0]&&n[1]===t[1]&&n[2]===t[2]&&n[3]===t[3]&&n[4]===t[4]&&n[5]===t[5]&&n[6]===t[6]&&n[7]===t[7]&&n[8]===t[8]&&n[9]===t[9]&&n[10]===t[10]&&n[11]===t[11]&&n[12]===t[12]&&n[13]===t[13]&&n[14]===t[14]&&n[15]===t[15]}function yb(n,t){const l=n[0],s=n[1],e=n[2],d=n[3],i=n[4],c=n[5],o=n[6],X=n[7],a=n[8],u=n[9],r=n[10],Z=n[11],G=n[12],p=n[13],m=n[14],W=n[15],L=t[0],V=t[1],y=t[2],S=t[3],K=t[4],T=t[5],Y=t[6],g=t[7],z=t[8],H=t[9],J=t[10],I=t[11],C=t[12],D=t[13],zt=t[14],Mt=t[15];return Math.abs(l-L)<=F*Math.max(1,Math.abs(l),Math.abs(L))&&Math.abs(s-V)<=F*Math.max(1,Math.abs(s),Math.abs(V))&&Math.abs(e-y)<=F*Math.max(1,Math.abs(e),Math.abs(y))&&Math.abs(d-S)<=F*Math.max(1,Math.abs(d),Math.abs(S))&&Math.abs(i-K)<=F*Math.max(1,Math.abs(i),Math.abs(K))&&Math.abs(c-T)<=F*Math.max(1,Math.abs(c),Math.abs(T))&&Math.abs(o-Y)<=F*Math.max(1,Math.abs(o),Math.abs(Y))&&Math.abs(X-g)<=F*Math.max(1,Math.abs(X),Math.abs(g))&&Math.abs(a-z)<=F*Math.max(1,Math.abs(a),Math.abs(z))&&Math.abs(u-H)<=F*Math.max(1,Math.abs(u),Math.abs(H))&&Math.abs(r-J)<=F*Math.max(1,Math.abs(r),Math.abs(J))&&Math.abs(Z-I)<=F*Math.max(1,Math.abs(Z),Math.abs(I))&&Math.abs(G-C)<=F*Math.max(1,Math.abs(G),Math.abs(C))&&Math.abs(p-D)<=F*Math.max(1,Math.abs(p),Math.abs(D))&&Math.abs(m-zt)<=F*Math.max(1,Math.abs(m),Math.abs(zt))&&Math.abs(W-Mt)<=F*Math.max(1,Math.abs(W),Math.abs(Mt))}const Lb=Object.freeze(Object.defineProperty({__proto__:null,add:mb,adjoint:$0,clone:A0,copy:D0,create:O0,decompose:bb,determinant:re,equals:yb,exactEquals:Vb,frob:Gb,fromQuat:xe,fromQuat2:ib,fromRotation:lb,fromRotationTranslation:ye,fromRotationTranslationScale:ob,fromRotationTranslationScaleOrigin:Xb,fromScaling:nb,fromTranslation:tb,fromValues:q0,fromXRotation:sb,fromYRotation:eb,fromZRotation:db,frustum:Ke,getRotation:cb,getScaling:Le,getTranslation:Sl,identity:ae,invert:he,lookAt:Ye,mul:Tn,multiply:Tn,multiplyScalar:pb,multiplyScalarAndAdd:Wb,ortho:Me,orthoNO:ze,orthoZO:hb,perspective:Se,perspectiveFromFieldOfView:ub,perspectiveNO:Re,perspectiveZO:ab,rotate:me,rotateX:pe,rotateY:We,rotateZ:Ve,scale:Ge,set:_0,str:Zb,sub:ge,subtract:ge,targetTo:rb,translate:Ze,transpose:ue},Symbol.toStringTag,{value:"Module"}));function Te(){const n=new B(4);return B!=Float32Array&&(n[0]=0,n[1]=0,n[2]=0,n[3]=0),n}function xb(n){const t=new B(4);return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t}function Kb(n,t,l,s){const e=new B(4);return e[0]=n,e[1]=t,e[2]=l,e[3]=s,e}function Rb(n,t){return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n}function Sb(n,t,l,s,e){return n[0]=t,n[1]=l,n[2]=s,n[3]=e,n}function Ce(n,t,l){return n[0]=t[0]+l[0],n[1]=t[1]+l[1],n[2]=t[2]+l[2],n[3]=t[3]+l[3],n}function fe(n,t,l){return n[0]=t[0]-l[0],n[1]=t[1]-l[1],n[2]=t[2]-l[2],n[3]=t[3]-l[3],n}function Fe(n,t,l){return n[0]=t[0]*l[0],n[1]=t[1]*l[1],n[2]=t[2]*l[2],n[3]=t[3]*l[3],n}function Ne(n,t,l){return n[0]=t[0]/l[0],n[1]=t[1]/l[1],n[2]=t[2]/l[2],n[3]=t[3]/l[3],n}function zb(n,t){return n[0]=Math.ceil(t[0]),n[1]=Math.ceil(t[1]),n[2]=Math.ceil(t[2]),n[3]=Math.ceil(t[3]),n}function Mb(n,t){return n[0]=Math.floor(t[0]),n[1]=Math.floor(t[1]),n[2]=Math.floor(t[2]),n[3]=Math.floor(t[3]),n}function Yb(n,t,l){return n[0]=Math.min(t[0],l[0]),n[1]=Math.min(t[1],l[1]),n[2]=Math.min(t[2],l[2]),n[3]=Math.min(t[3],l[3]),n}function gb(n,t,l){return n[0]=Math.max(t[0],l[0]),n[1]=Math.max(t[1],l[1]),n[2]=Math.max(t[2],l[2]),n[3]=Math.max(t[3],l[3]),n}function Tb(n,t){return n[0]=ot(t[0]),n[1]=ot(t[1]),n[2]=ot(t[2]),n[3]=ot(t[3]),n}function He(n,t,l){return n[0]=t[0]*l,n[1]=t[1]*l,n[2]=t[2]*l,n[3]=t[3]*l,n}function Cb(n,t,l,s){return n[0]=t[0]+l[0]*s,n[1]=t[1]+l[1]*s,n[2]=t[2]+l[2]*s,n[3]=t[3]+l[3]*s,n}function Je(n,t){const l=t[0]-n[0],s=t[1]-n[1],e=t[2]-n[2],d=t[3]-n[3];return Math.sqrt(l*l+s*s+e*e+d*d)}function Ie(n,t){const l=t[0]-n[0],s=t[1]-n[1],e=t[2]-n[2],d=t[3]-n[3];return l*l+s*s+e*e+d*d}function zl(n){const t=n[0],l=n[1],s=n[2],e=n[3];return Math.sqrt(t*t+l*l+s*s+e*e)}function Ml(n){const t=n[0],l=n[1],s=n[2],e=n[3];return t*t+l*l+s*s+e*e}function fb(n,t){return n[0]=-t[0],n[1]=-t[1],n[2]=-t[2],n[3]=-t[3],n}function Fb(n,t){return n[0]=1/t[0],n[1]=1/t[1],n[2]=1/t[2],n[3]=1/t[3],n}function ke(n,t){const l=t[0],s=t[1],e=t[2],d=t[3];let i=l*l+s*s+e*e+d*d;return i>0&&(i=1/Math.sqrt(i)),n[0]=l*i,n[1]=s*i,n[2]=e*i,n[3]=d*i,n}function Pe(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]+n[3]*t[3]}function Nb(n,t,l,s){const e=l[0]*s[1]-l[1]*s[0],d=l[0]*s[2]-l[2]*s[0],i=l[0]*s[3]-l[3]*s[0],c=l[1]*s[2]-l[2]*s[1],o=l[1]*s[3]-l[3]*s[1],X=l[2]*s[3]-l[3]*s[2],a=t[0],u=t[1],r=t[2],Z=t[3];return n[0]=u*X-r*o+Z*c,n[1]=-(a*X)+r*i-Z*d,n[2]=a*o-u*i+Z*e,n[3]=-(a*c)+u*d-r*e,n}function Qe(n,t,l,s){const e=t[0],d=t[1],i=t[2],c=t[3];return n[0]=e+s*(l[0]-e),n[1]=d+s*(l[1]-d),n[2]=i+s*(l[2]-i),n[3]=c+s*(l[3]-c),n}function Hb(n,t){t=t===void 0?1:t;let l,s,e,d,i,c;do l=yt()*2-1,s=yt()*2-1,i=l*l+s*s;while(i>=1);do e=yt()*2-1,d=yt()*2-1,c=e*e+d*d;while(c>=1);const o=Math.sqrt((1-i)/c);return n[0]=t*l,n[1]=t*s,n[2]=t*e*o,n[3]=t*d*o,n}function Be(n,t,l){const s=t[0],e=t[1],d=t[2],i=t[3];return n[0]=l[0]*s+l[4]*e+l[8]*d+l[12]*i,n[1]=l[1]*s+l[5]*e+l[9]*d+l[13]*i,n[2]=l[2]*s+l[6]*e+l[10]*d+l[14]*i,n[3]=l[3]*s+l[7]*e+l[11]*d+l[15]*i,n}function ve(n,t,l){const s=t[0],e=t[1],d=t[2],i=l[0],c=l[1],o=l[2],X=l[3],a=X*s+c*d-o*e,u=X*e+o*s-i*d,r=X*d+i*e-c*s,Z=-i*s-c*e-o*d;return n[0]=a*X+Z*-i+u*-o-r*-c,n[1]=u*X+Z*-c+r*-i-a*-o,n[2]=r*X+Z*-o+a*-c-u*-i,n[3]=t[3],n}function Jb(n){return n[0]=0,n[1]=0,n[2]=0,n[3]=0,n}function Ib(n){return`vec4(${n[0]}, ${n[1]}, ${n[2]}, ${n[3]})`}function kb(n,t){return n[0]===t[0]&&n[1]===t[1]&&n[2]===t[2]&&n[3]===t[3]}function Pb(n,t){const l=n[0],s=n[1],e=n[2],d=n[3],i=t[0],c=t[1],o=t[2],X=t[3];return Math.abs(l-i)<=F*Math.max(1,Math.abs(l),Math.abs(i))&&Math.abs(s-c)<=F*Math.max(1,Math.abs(s),Math.abs(c))&&Math.abs(e-o)<=F*Math.max(1,Math.abs(e),Math.abs(o))&&Math.abs(d-X)<=F*Math.max(1,Math.abs(d),Math.abs(X))}const Qb=fe,Bb=Fe,vb=Ne,wb=Je,Ub=Ie,jb=zl,Eb=Ml,Ob=function(){const n=Te();return function(t,l,s,e,d,i){let c,o;for(l||(l=4),s||(s=0),e?o=Math.min(e*l+s,t.length):o=t.length,c=s;c<o;c+=l)n[0]=t[c],n[1]=t[c+1],n[2]=t[c+2],n[3]=t[c+3],d(n,n,i),t[c]=n[0],t[c+1]=n[1],t[c+2]=n[2],t[c+3]=n[3];return t}}(),Ab=Object.freeze(Object.defineProperty({__proto__:null,add:Ce,ceil:zb,clone:xb,copy:Rb,create:Te,cross:Nb,dist:wb,distance:Je,div:vb,divide:Ne,dot:Pe,equals:Pb,exactEquals:kb,floor:Mb,forEach:Ob,fromValues:Kb,inverse:Fb,len:jb,length:zl,lerp:Qe,max:gb,min:Yb,mul:Bb,multiply:Fe,negate:fb,normalize:ke,random:Hb,round:Tb,scale:He,scaleAndAdd:Cb,set:Sb,sqrDist:Ub,sqrLen:Eb,squaredDistance:Ie,squaredLength:Ml,str:Ib,sub:Qb,subtract:fe,transformMat4:Be,transformQuat:ve,zero:Jb},Symbol.toStringTag,{value:"Module"}));var Yl;(function(n){n[n.COL0ROW0=0]="COL0ROW0",n[n.COL0ROW1=1]="COL0ROW1",n[n.COL0ROW2=2]="COL0ROW2",n[n.COL0ROW3=3]="COL0ROW3",n[n.COL1ROW0=4]="COL1ROW0",n[n.COL1ROW1=5]="COL1ROW1",n[n.COL1ROW2=6]="COL1ROW2",n[n.COL1ROW3=7]="COL1ROW3",n[n.COL2ROW0=8]="COL2ROW0",n[n.COL2ROW1=9]="COL2ROW1",n[n.COL2ROW2=10]="COL2ROW2",n[n.COL2ROW3=11]="COL2ROW3",n[n.COL3ROW0=12]="COL3ROW0",n[n.COL3ROW1=13]="COL3ROW1",n[n.COL3ROW2=14]="COL3ROW2",n[n.COL3ROW3=15]="COL3ROW3"})(Yl||(Yl={}));const Db=45*Math.PI/180,qb=1,gl=.1,Tl=500,_b=Object.freeze([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]);class ht extends de{static get IDENTITY(){return to()}static get ZERO(){return $b()}get ELEMENTS(){return 16}get RANK(){return 4}get INDICES(){return Yl}constructor(t){super(-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0),arguments.length===1&&Array.isArray(t)?this.copy(t):this.identity()}copy(t){return this[0]=t[0],this[1]=t[1],this[2]=t[2],this[3]=t[3],this[4]=t[4],this[5]=t[5],this[6]=t[6],this[7]=t[7],this[8]=t[8],this[9]=t[9],this[10]=t[10],this[11]=t[11],this[12]=t[12],this[13]=t[13],this[14]=t[14],this[15]=t[15],this.check()}set(t,l,s,e,d,i,c,o,X,a,u,r,Z,G,p,m){return this[0]=t,this[1]=l,this[2]=s,this[3]=e,this[4]=d,this[5]=i,this[6]=c,this[7]=o,this[8]=X,this[9]=a,this[10]=u,this[11]=r,this[12]=Z,this[13]=G,this[14]=p,this[15]=m,this.check()}setRowMajor(t,l,s,e,d,i,c,o,X,a,u,r,Z,G,p,m){return this[0]=t,this[1]=d,this[2]=X,this[3]=Z,this[4]=l,this[5]=i,this[6]=a,this[7]=G,this[8]=s,this[9]=c,this[10]=u,this[11]=p,this[12]=e,this[13]=o,this[14]=r,this[15]=m,this.check()}toRowMajor(t){return t[0]=this[0],t[1]=this[4],t[2]=this[8],t[3]=this[12],t[4]=this[1],t[5]=this[5],t[6]=this[9],t[7]=this[13],t[8]=this[2],t[9]=this[6],t[10]=this[10],t[11]=this[14],t[12]=this[3],t[13]=this[7],t[14]=this[11],t[15]=this[15],t}identity(){return this.copy(_b)}fromObject(t){return this.check()}fromQuaternion(t){return xe(this,t),this.check()}frustum(t){const{left:l,right:s,bottom:e,top:d,near:i=gl,far:c=Tl}=t;return c===1/0?no(this,l,s,e,d,i):Ke(this,l,s,e,d,i,c),this.check()}lookAt(t){const{eye:l,center:s=[0,0,0],up:e=[0,1,0]}=t;return Ye(this,l,s,e),this.check()}ortho(t){const{left:l,right:s,bottom:e,top:d,near:i=gl,far:c=Tl}=t;return Me(this,l,s,e,d,i,c),this.check()}orthographic(t){const{fovy:l=Db,aspect:s=qb,focalDistance:e=1,near:d=gl,far:i=Tl}=t;we(l);const c=l/2,o=e*Math.tan(c),X=o*s;return this.ortho({left:-X,right:X,bottom:-o,top:o,near:d,far:i})}perspective(t){const{fovy:l=45*Math.PI/180,aspect:s=1,near:e=.1,far:d=500}=t;return we(l),Se(this,l,s,e,d),this.check()}determinant(){return re(this)}getScale(t=[-0,-0,-0]){return t[0]=Math.sqrt(this[0]*this[0]+this[1]*this[1]+this[2]*this[2]),t[1]=Math.sqrt(this[4]*this[4]+this[5]*this[5]+this[6]*this[6]),t[2]=Math.sqrt(this[8]*this[8]+this[9]*this[9]+this[10]*this[10]),t}getTranslation(t=[-0,-0,-0]){return t[0]=this[12],t[1]=this[13],t[2]=this[14],t}getRotation(t,l){t=t||[-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0],l=l||[-0,-0,-0];const s=this.getScale(l),e=1/s[0],d=1/s[1],i=1/s[2];return t[0]=this[0]*e,t[1]=this[1]*d,t[2]=this[2]*i,t[3]=0,t[4]=this[4]*e,t[5]=this[5]*d,t[6]=this[6]*i,t[7]=0,t[8]=this[8]*e,t[9]=this[9]*d,t[10]=this[10]*i,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t}getRotationMatrix3(t,l){t=t||[-0,-0,-0,-0,-0,-0,-0,-0,-0],l=l||[-0,-0,-0];const s=this.getScale(l),e=1/s[0],d=1/s[1],i=1/s[2];return t[0]=this[0]*e,t[1]=this[1]*d,t[2]=this[2]*i,t[3]=this[4]*e,t[4]=this[5]*d,t[5]=this[6]*i,t[6]=this[8]*e,t[7]=this[9]*d,t[8]=this[10]*i,t}transpose(){return ue(this,this),this.check()}invert(){return he(this,this),this.check()}multiplyLeft(t){return Tn(this,t,this),this.check()}multiplyRight(t){return Tn(this,this,t),this.check()}rotateX(t){return pe(this,this,t),this.check()}rotateY(t){return We(this,this,t),this.check()}rotateZ(t){return Ve(this,this,t),this.check()}rotateXYZ(t){return this.rotateX(t[0]).rotateY(t[1]).rotateZ(t[2])}rotateAxis(t,l){return me(this,this,t,l),this.check()}scale(t){return Ge(this,this,Array.isArray(t)?t:[t,t,t]),this.check()}translate(t){return Ze(this,this,t),this.check()}transform(t,l){return t.length===4?(l=Be(l||[-0,-0,-0,-0],t,this),Ot(l,4),l):this.transformAsPoint(t,l)}transformAsPoint(t,l){const{length:s}=t;let e;switch(s){case 2:e=ul(l||[-0,-0],t,this);break;case 3:e=Kn(l||[-0,-0,-0],t,this);break;default:throw new Error("Illegal vector")}return Ot(e,t.length),e}transformAsVector(t,l){let s;switch(t.length){case 2:s=ws(l||[-0,-0],t,this);break;case 3:s=Us(l||[-0,-0,-0],t,this);break;default:throw new Error("Illegal vector")}return Ot(s,t.length),s}transformPoint(t,l){return this.transformAsPoint(t,l)}transformVector(t,l){return this.transformAsPoint(t,l)}transformDirection(t,l){return this.transformAsVector(t,l)}makeRotationX(t){return this.identity().rotateX(t)}makeTranslation(t,l,s){return this.identity().translate([t,l,s])}}let Cn,fn;function $b(){return Cn||(Cn=new ht([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]),Object.freeze(Cn)),Cn}function to(){return fn||(fn=new ht,Object.freeze(fn)),fn}function we(n){if(n>Math.PI*2)throw Error("expected radians")}function no(n,t,l,s,e,d){const i=2*d/(l-t),c=2*d/(e-s),o=(l+t)/(l-t),X=(e+s)/(e-s),a=-1,u=-1,r=-2*d;return n[0]=i,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=c,n[6]=0,n[7]=0,n[8]=o,n[9]=X,n[10]=a,n[11]=u,n[12]=0,n[13]=0,n[14]=r,n[15]=0,n}function Ue(){const n=new B(4);return B!=Float32Array&&(n[0]=0,n[1]=0,n[2]=0),n[3]=1,n}function lo(n){return n[0]=0,n[1]=0,n[2]=0,n[3]=1,n}function je(n,t,l){l=l*.5;const s=Math.sin(l);return n[0]=s*t[0],n[1]=s*t[1],n[2]=s*t[2],n[3]=Math.cos(l),n}function Ee(n,t,l){const s=t[0],e=t[1],d=t[2],i=t[3],c=l[0],o=l[1],X=l[2],a=l[3];return n[0]=s*a+i*c+e*X-d*o,n[1]=e*a+i*o+d*c-s*X,n[2]=d*a+i*X+s*o-e*c,n[3]=i*a-s*c-e*o-d*X,n}function so(n,t,l){l*=.5;const s=t[0],e=t[1],d=t[2],i=t[3],c=Math.sin(l),o=Math.cos(l);return n[0]=s*o+i*c,n[1]=e*o+d*c,n[2]=d*o-e*c,n[3]=i*o-s*c,n}function eo(n,t,l){l*=.5;const s=t[0],e=t[1],d=t[2],i=t[3],c=Math.sin(l),o=Math.cos(l);return n[0]=s*o-d*c,n[1]=e*o+i*c,n[2]=d*o+s*c,n[3]=i*o-e*c,n}function io(n,t,l){l*=.5;const s=t[0],e=t[1],d=t[2],i=t[3],c=Math.sin(l),o=Math.cos(l);return n[0]=s*o+e*c,n[1]=e*o-s*c,n[2]=d*o+i*c,n[3]=i*o-d*c,n}function co(n,t){const l=t[0],s=t[1],e=t[2];return n[0]=l,n[1]=s,n[2]=e,n[3]=Math.sqrt(Math.abs(1-l*l-s*s-e*e)),n}function Fn(n,t,l,s){const e=t[0],d=t[1],i=t[2],c=t[3];let o=l[0],X=l[1],a=l[2],u=l[3],r,Z,G,p,m;return r=e*o+d*X+i*a+c*u,r<0&&(r=-r,o=-o,X=-X,a=-a,u=-u),1-r>F?(Z=Math.acos(r),m=Math.sin(Z),G=Math.sin((1-s)*Z)/m,p=Math.sin(s*Z)/m):(G=1-s,p=s),n[0]=G*e+p*o,n[1]=G*d+p*X,n[2]=G*i+p*a,n[3]=G*c+p*u,n}function bo(n,t){const l=t[0],s=t[1],e=t[2],d=t[3],i=l*l+s*s+e*e+d*d,c=i?1/i:0;return n[0]=-l*c,n[1]=-s*c,n[2]=-e*c,n[3]=d*c,n}function oo(n,t){return n[0]=-t[0],n[1]=-t[1],n[2]=-t[2],n[3]=t[3],n}function Cl(n,t){const l=t[0]+t[4]+t[8];let s;if(l>0)s=Math.sqrt(l+1),n[3]=.5*s,s=.5/s,n[0]=(t[5]-t[7])*s,n[1]=(t[6]-t[2])*s,n[2]=(t[1]-t[3])*s;else{let e=0;t[4]>t[0]&&(e=1),t[8]>t[e*3+e]&&(e=2);const d=(e+1)%3,i=(e+2)%3;s=Math.sqrt(t[e*3+e]-t[d*3+d]-t[i*3+i]+1),n[e]=.5*s,s=.5/s,n[3]=(t[d*3+i]-t[i*3+d])*s,n[d]=(t[d*3+e]+t[e*3+d])*s,n[i]=(t[i*3+e]+t[e*3+i])*s}return n}const Xo=Ce,ao=He,uo=Pe,ho=Qe,ro=zl,Zo=Ml,Oe=ke,Go=function(){const n=rl(),t=Zl(1,0,0),l=Zl(0,1,0);return function(s,e,d){const i=At(e,d);return i<-.999999?(Tt(n,t,e),ee(n)<1e-6&&Tt(n,l,e),$s(n,n),je(s,n,Math.PI),s):i>.999999?(s[0]=0,s[1]=0,s[2]=0,s[3]=1,s):(Tt(n,e,d),s[0]=n[0],s[1]=n[1],s[2]=n[2],s[3]=1+i,Oe(s,s))}}();(function(){const n=Ue(),t=Ue();return function(l,s,e,d,i,c){return Fn(n,s,i,c),Fn(t,e,d,c),Fn(l,n,t,2*c*(1-c)),l}})(),function(){const n=ie();return function(t,l,s,e){return n[0]=s[0],n[3]=s[1],n[6]=s[2],n[1]=e[0],n[4]=e[1],n[7]=e[2],n[2]=-l[0],n[5]=-l[1],n[8]=-l[2],Oe(t,Cl(t,n))}}();const mo=[0,0,0,1];class Ct extends Ln{constructor(t=0,l=0,s=0,e=1){super(-0,-0,-0,-0),Array.isArray(t)&&arguments.length===1?this.copy(t):this.set(t,l,s,e)}copy(t){return this[0]=t[0],this[1]=t[1],this[2]=t[2],this[3]=t[3],this.check()}set(t,l,s,e){return this[0]=t,this[1]=l,this[2]=s,this[3]=e,this.check()}fromObject(t){return this[0]=t.x,this[1]=t.y,this[2]=t.z,this[3]=t.w,this.check()}fromMatrix3(t){return Cl(this,t),this.check()}fromAxisRotation(t,l){return je(this,t,l),this.check()}identity(){return lo(this),this.check()}setAxisAngle(t,l){return this.fromAxisRotation(t,l)}get ELEMENTS(){return 4}get x(){return this[0]}set x(t){this[0]=f(t)}get y(){return this[1]}set y(t){this[1]=f(t)}get z(){return this[2]}set z(t){this[2]=f(t)}get w(){return this[3]}set w(t){this[3]=f(t)}len(){return ro(this)}lengthSquared(){return Zo(this)}dot(t){return uo(this,t)}rotationTo(t,l){return Go(this,t,l),this.check()}add(t){return Xo(this,this,t),this.check()}calculateW(){return co(this,this),this.check()}conjugate(){return oo(this,this),this.check()}invert(){return bo(this,this),this.check()}lerp(t,l,s){return s===void 0?this.lerp(this,t,l):(ho(this,t,l,s),this.check())}multiplyRight(t){return Ee(this,this,t),this.check()}multiplyLeft(t){return Ee(this,t,this),this.check()}normalize(){const t=this.len(),l=t>0?1/t:0;return this[0]=this[0]*l,this[1]=this[1]*l,this[2]=this[2]*l,this[3]=this[3]*l,t===0&&(this[3]=1),this.check()}rotateX(t){return so(this,this,t),this.check()}rotateY(t){return eo(this,this,t),this.check()}rotateZ(t){return io(this,this,t),this.check()}scale(t){return ao(this,this,t),this.check()}slerp(t,l,s){let e,d,i;switch(arguments.length){case 1:({start:e=mo,target:d,ratio:i}=t);break;case 2:e=this,d=t,i=l;break;default:e=t,d=l,i=s}return Fn(this,e,d,i),this.check()}transformVector4(t,l=new ut){return ve(l,t,this),Ot(l,4)}lengthSq(){return this.lengthSquared()}setFromAxisAngle(t,l){return this.setAxisAngle(t,l)}premultiply(t){return this.multiplyLeft(t)}multiply(t){return this.multiplyRight(t)}}const Nn="Unknown Euler angle order",ft=.99999;var U;(function(n){n[n.ZYX=0]="ZYX",n[n.YXZ=1]="YXZ",n[n.XZY=2]="XZY",n[n.ZXY=3]="ZXY",n[n.YZX=4]="YZX",n[n.XYZ=5]="XYZ"})(U||(U={}));class v extends Ln{static get ZYX(){return U.ZYX}static get YXZ(){return U.YXZ}static get XZY(){return U.XZY}static get ZXY(){return U.ZXY}static get YZX(){return U.YZX}static get XYZ(){return U.XYZ}static get RollPitchYaw(){return U.ZYX}static get DefaultOrder(){return U.ZYX}static get RotationOrders(){return U}static rotationOrder(t){return U[t]}get ELEMENTS(){return 4}constructor(t=0,l=0,s=0,e=v.DefaultOrder){super(-0,-0,-0,-0),arguments.length>0&&Array.isArray(arguments[0])?this.fromVector3(...arguments):this.set(t,l,s,e)}fromQuaternion(t){const[l,s,e,d]=t,i=s*s,c=-2*(i+e*e)+1,o=2*(l*s+d*e);let X=-2*(l*e-d*s);const a=2*(s*e+d*l),u=-2*(l*l+i)+1;X=X>1?1:X,X=X<-1?-1:X;const r=Math.atan2(a,u),Z=Math.asin(X),G=Math.atan2(o,c);return this.set(r,Z,G,v.RollPitchYaw)}fromObject(t){throw new Error("not implemented")}copy(t){return this[0]=t[0],this[1]=t[1],this[2]=t[2],this[3]=Number.isFinite(t[3])||this.order,this.check()}set(t=0,l=0,s=0,e){return this[0]=t,this[1]=l,this[2]=s,this[3]=Number.isFinite(e)?e:this[3],this.check()}validate(){return po(this[3])&&Number.isFinite(this[0])&&Number.isFinite(this[1])&&Number.isFinite(this[2])}toArray(t=[],l=0){return t[l]=this[0],t[l+1]=this[1],t[l+2]=this[2],t}toArray4(t=[],l=0){return t[l]=this[0],t[l+1]=this[1],t[l+2]=this[2],t[l+3]=this[3],t}toVector3(t=[-0,-0,-0]){return t[0]=this[0],t[1]=this[1],t[2]=this[2],t}get x(){return this[0]}set x(t){this[0]=f(t)}get y(){return this[1]}set y(t){this[1]=f(t)}get z(){return this[2]}set z(t){this[2]=f(t)}get alpha(){return this[0]}set alpha(t){this[0]=f(t)}get beta(){return this[1]}set beta(t){this[1]=f(t)}get gamma(){return this[2]}set gamma(t){this[2]=f(t)}get phi(){return this[0]}set phi(t){this[0]=f(t)}get theta(){return this[1]}set theta(t){this[1]=f(t)}get psi(){return this[2]}set psi(t){this[2]=f(t)}get roll(){return this[0]}set roll(t){this[0]=f(t)}get pitch(){return this[1]}set pitch(t){this[1]=f(t)}get yaw(){return this[2]}set yaw(t){this[2]=f(t)}get order(){return this[3]}set order(t){this[3]=Wo(t)}fromVector3(t,l){return this.set(t[0],t[1],t[2],Number.isFinite(l)?l:this[3])}fromArray(t,l=0){return this[0]=t[0+l],this[1]=t[1+l],this[2]=t[2+l],t[3]!==void 0&&(this[3]=t[3]),this.check()}fromRollPitchYaw(t,l,s){return this.set(t,l,s,U.ZYX)}fromRotationMatrix(t,l=v.DefaultOrder){return this._fromRotationMatrix(t,l),this.check()}getRotationMatrix(t){return this._getRotationMatrix(t)}getQuaternion(){const t=new Ct;switch(this[3]){case U.XYZ:return t.rotateX(this[0]).rotateY(this[1]).rotateZ(this[2]);case U.YXZ:return t.rotateY(this[0]).rotateX(this[1]).rotateZ(this[2]);case U.ZXY:return t.rotateZ(this[0]).rotateX(this[1]).rotateY(this[2]);case U.ZYX:return t.rotateZ(this[0]).rotateY(this[1]).rotateX(this[2]);case U.YZX:return t.rotateY(this[0]).rotateZ(this[1]).rotateX(this[2]);case U.XZY:return t.rotateX(this[0]).rotateZ(this[1]).rotateY(this[2]);default:throw new Error(Nn)}}_fromRotationMatrix(t,l=v.DefaultOrder){const s=t[0],e=t[4],d=t[8],i=t[1],c=t[5],o=t[9],X=t[2],a=t[6],u=t[10];switch(l=l||this[3],l){case v.XYZ:this[1]=Math.asin(Yt(d,-1,1)),Math.abs(d)<ft?(this[0]=Math.atan2(-o,u),this[2]=Math.atan2(-e,s)):(this[0]=Math.atan2(a,c),this[2]=0);break;case v.YXZ:this[0]=Math.asin(-Yt(o,-1,1)),Math.abs(o)<ft?(this[1]=Math.atan2(d,u),this[2]=Math.atan2(i,c)):(this[1]=Math.atan2(-X,s),this[2]=0);break;case v.ZXY:this[0]=Math.asin(Yt(a,-1,1)),Math.abs(a)<ft?(this[1]=Math.atan2(-X,u),this[2]=Math.atan2(-e,c)):(this[1]=0,this[2]=Math.atan2(i,s));break;case v.ZYX:this[1]=Math.asin(-Yt(X,-1,1)),Math.abs(X)<ft?(this[0]=Math.atan2(a,u),this[2]=Math.atan2(i,s)):(this[0]=0,this[2]=Math.atan2(-e,c));break;case v.YZX:this[2]=Math.asin(Yt(i,-1,1)),Math.abs(i)<ft?(this[0]=Math.atan2(-o,c),this[1]=Math.atan2(-X,s)):(this[0]=0,this[1]=Math.atan2(d,u));break;case v.XZY:this[2]=Math.asin(-Yt(e,-1,1)),Math.abs(e)<ft?(this[0]=Math.atan2(a,c),this[1]=Math.atan2(d,s)):(this[0]=Math.atan2(-o,u),this[1]=0);break;default:throw new Error(Nn)}return this[3]=l,this}_getRotationMatrix(t){const l=t||[-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0],s=this.x,e=this.y,d=this.z,i=Math.cos(s),c=Math.cos(e),o=Math.cos(d),X=Math.sin(s),a=Math.sin(e),u=Math.sin(d);switch(this[3]){case v.XYZ:{const r=i*o,Z=i*u,G=X*o,p=X*u;l[0]=c*o,l[4]=-c*u,l[8]=a,l[1]=Z+G*a,l[5]=r-p*a,l[9]=-X*c,l[2]=p-r*a,l[6]=G+Z*a,l[10]=i*c;break}case v.YXZ:{const r=c*o,Z=c*u,G=a*o,p=a*u;l[0]=r+p*X,l[4]=G*X-Z,l[8]=i*a,l[1]=i*u,l[5]=i*o,l[9]=-X,l[2]=Z*X-G,l[6]=p+r*X,l[10]=i*c;break}case v.ZXY:{const r=c*o,Z=c*u,G=a*o,p=a*u;l[0]=r-p*X,l[4]=-i*u,l[8]=G+Z*X,l[1]=Z+G*X,l[5]=i*o,l[9]=p-r*X,l[2]=-i*a,l[6]=X,l[10]=i*c;break}case v.ZYX:{const r=i*o,Z=i*u,G=X*o,p=X*u;l[0]=c*o,l[4]=G*a-Z,l[8]=r*a+p,l[1]=c*u,l[5]=p*a+r,l[9]=Z*a-G,l[2]=-a,l[6]=X*c,l[10]=i*c;break}case v.YZX:{const r=i*c,Z=i*a,G=X*c,p=X*a;l[0]=c*o,l[4]=p-r*u,l[8]=G*u+Z,l[1]=u,l[5]=i*o,l[9]=-X*o,l[2]=-a*o,l[6]=Z*u+G,l[10]=r-p*u;break}case v.XZY:{const r=i*c,Z=i*a,G=X*c,p=X*a;l[0]=c*o,l[4]=-u,l[8]=a*o,l[1]=r*u+p,l[5]=i*o,l[9]=Z*u-G,l[2]=G*u-Z,l[6]=X*o,l[10]=p*u+r;break}default:throw new Error(Nn)}return l[3]=0,l[7]=0,l[11]=0,l[12]=0,l[13]=0,l[14]=0,l[15]=1,l}toQuaternion(){const t=Math.cos(this.yaw*.5),l=Math.sin(this.yaw*.5),s=Math.cos(this.roll*.5),e=Math.sin(this.roll*.5),d=Math.cos(this.pitch*.5),i=Math.sin(this.pitch*.5),c=t*s*d+l*e*i,o=t*e*d-l*s*i,X=t*s*i+l*e*d,a=l*s*d-t*e*i;return new Ct(o,X,a,c)}}function po(n){return n>=0&&n<6}function Wo(n){if(n<0&&n>=6)throw new Error(Nn);return n}const Vo=.1,yo=1e-12,Lo=1e-15;var _t=(n=>(n.equal="equal",n.intersect="intersect",n.intersectEqual="intersectEqual",n))(_t||{});(n=>{function t(l){let s;switch(l){case"equal":s=(e,d)=>e===d;case"intersect":s=(e,d)=>e&d;default:s=(e,d)=>(e&d)===e}return s}n.getEqualFun=t})(_t||(_t={}));const Ae=!0,xo=!1,$t={CCW:-1,CW:1,NOT_ORIENTABLE:0},Ko=2*Math.PI,Hn=1,De=0,lt=2,Ro=3,So=4,zo=1,Mo=2,fl=0,tn=1,Ft=2;var Jn=Object.freeze({__proto__:null,BOUNDARY:lt,CCW:Ae,CONTAINS:Ro,CW:xo,END_VERTEX:Ft,INSIDE:Hn,INTERLACE:So,NOT_VERTEX:fl,ORIENTATION:$t,OUTSIDE:De,OVERLAP_OPPOSITE:Mo,OVERLAP_SAME:zo,PIx2:Ko,START_VERTEX:tn});let st=1e-6;function qe(n){st=n}function _e(){return st}const Yo=3;function Fl(n){return n<st&&n>-st}function Lt(n,t){return n-t<st&&n-t>-st}function $e(n,t){return n-t>st}function go(n,t){return n-t>-st}function td(n,t){return n-t<-st}function To(n,t){return n-t<st}var Co=Object.freeze({__proto__:null,DECIMALS:Yo,EQ:Lt,EQ_0:Fl,GE:go,GT:$e,LE:To,LT:td,getTolerance:_e,setTolerance:qe});let b={Utils:Co,Errors:void 0,Matrix:void 0,Planar_set:void 0,Point:void 0,Vector:void 0,Line:void 0,Circle:void 0,Segment:void 0,Arc:void 0,Box:void 0,Edge:void 0,Face:void 0,Ray:void 0,Ray_shooting:void 0,Multiline:void 0,Polygon:void 0,Distance:void 0,Inversion:void 0};for(let n in Jn)b[n]=Jn[n];Object.defineProperty(b,"DP_TOL",{get:function(){return _e()},set:function(n){qe(n)}});class Q{static get ILLEGAL_PARAMETERS(){return new ReferenceError("Illegal Parameters")}static get ZERO_DIVISION(){return new Error("Zero division")}static get UNRESOLVED_BOUNDARY_CONFLICT(){return new Error("Unresolved boundary conflict in boolean operation")}static get INFINITE_LOOP(){return new Error("Infinite loop")}static get CANNOT_COMPLETE_BOOLEAN_OPERATION(){return new Error("Cannot complete boolean operation")}static get CANNOT_INVOKE_ABSTRACT_METHOD(){return new Error("Abstract method cannot be invoked")}static get OPERATION_IS_NOT_SUPPORTED(){return new Error("Operation is not supported")}static get UNSUPPORTED_SHAPE_TYPE(){return new Error("Unsupported shape type")}}b.Errors=Q;class Nl{constructor(t,l){this.first=t,this.last=l||this.first}[Symbol.iterator](){let t;return{next:()=>(t=t?t.next:this.first,{value:t,done:t===void 0})}}get size(){let t=0;for(let l of this)t++;return t}toArray(t=void 0,l=void 0){let s=[],e=t||this.first,d=l||this.last,i=e;if(i===void 0)return s;do s.push(i),i=i.next;while(i!==d.next);return s}append(t){return this.isEmpty()?this.first=t:(t.prev=this.last,this.last.next=t),this.last=t,this.last.next=void 0,this.first.prev=void 0,this}insert(t,l){if(this.isEmpty())this.first=t,this.last=t;else if(l==null)t.next=this.first,this.first.prev=t,this.first=t;else{let s=l.next;l.next=t,s&&(s.prev=t),t.prev=l,t.next=s,this.last===l&&(this.last=t)}return this.last.next=void 0,this.first.prev=void 0,this}remove(t){return t===this.first&&t===this.last?(this.first=void 0,this.last=void 0):(t.prev&&(t.prev.next=t.next),t.next&&(t.next.prev=t.prev),t===this.first&&(this.first=t.next),t===this.last&&(this.last=t.prev)),this}isEmpty(){return this.first===void 0}static testInfiniteLoop(t){let l=t,s=t;do{if(l!=t&&l===s)throw Q.INFINITE_LOOP;l=l.next,s=s.next.next}while(l!=t)}}const nd={stroke:"black"};class fo{constructor(t=nd){for(const l in t)this[l]=t[l];this.stroke=t.stroke??nd.stroke}toAttributesString(){return Object.keys(this).reduce((t,l)=>t+(this[l]!==void 0?this.toAttrString(l,this[l]):""),"")}toAttrString(t,l){const s=t==="className"?"class":this.convertCamelToKebabCase(t);return l===null?`${s} `:`${s}="${l.toString()}" `}convertCamelToKebabCase(t){return t.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g).join("-").toLowerCase()}}function xt(n){return new fo(n).toAttributesString()}function Nt(n,t){let l=[],[s,e,d]=n.standard,[i,c,o]=t.standard,X=s*c-e*i,a=d*c-e*o,u=s*o-d*i;if(!b.Utils.EQ_0(X)){let r,Z;e===0?(r=d/s,Z=u/X):c===0?(r=o/i,Z=u/X):s===0?(r=a/X,Z=d/e):i===0?(r=a/X,Z=o/c):(r=a/X,Z=u/X),l.push(new b.Point(r,Z))}return l}function Kt(n,t){let l=[],s=t.pc.projectionOn(n),e=t.pc.distanceTo(s)[0];if(b.Utils.EQ(e,t.r))l.push(s);else if(b.Utils.LT(e,t.r)){let d=Math.sqrt(t.r*t.r-e*e),i,c;i=n.norm.rotate90CCW().multiply(d),c=s.translate(i),l.push(c),i=n.norm.rotate90CW().multiply(d),c=s.translate(i),l.push(c)}return l}function Ht(n,t){let l=[];for(let s of t.toSegments()){let e=nn(s,n);for(let d of e)ad(d,l)||l.push(d)}return l}function In(n,t){let l=[];if(Ht(n,t.box).length===0)return l;let s=new b.Circle(t.pc,t.r),e=Kt(n,s);for(let d of e)d.on(t)&&l.push(d);return l}function nn(n,t){let l=[];if(n.ps.on(t)&&l.push(n.ps),n.pe.on(t)&&!n.isZeroLength()&&l.push(n.pe),l.length>0||n.isZeroLength()||n.ps.leftTo(t)&&n.pe.leftTo(t)||!n.ps.leftTo(t)&&!n.pe.leftTo(t))return l;let s=new b.Line(n.ps,n.pe);return Nt(s,t)}function kn(n,t){let l=[];if(n.isZeroLength())return n.ps.on(t)&&l.push(n.ps),l;if(t.isZeroLength())return t.ps.on(n)&&l.push(t.ps),l;let s=new b.Line(n.ps,n.pe),e=new b.Line(t.ps,t.pe);if(s.incidentTo(e))n.ps.on(t)&&l.push(n.ps),n.pe.on(t)&&l.push(n.pe),t.ps.on(n)&&!t.ps.equalTo(n.ps)&&!t.ps.equalTo(n.pe)&&l.push(t.ps),t.pe.on(n)&&!t.pe.equalTo(n.ps)&&!t.pe.equalTo(n.pe)&&l.push(t.pe);else{let d=Nt(s,e);d.length>0&&ld(d[0],n)&&ld(d[0],t)&&l.push(d[0])}return l}function ld(n,t){const l=t.box;return b.Utils.LE(n.x,l.xmax)&&b.Utils.GE(n.x,l.xmin)&&b.Utils.LE(n.y,l.ymax)&&b.Utils.GE(n.y,l.ymin)}function Pn(n,t){let l=[];if(n.isZeroLength()){let[d,i]=n.ps.distanceTo(t.pc);return b.Utils.EQ(d,t.r)&&l.push(n.ps),l}let s=new b.Line(n.ps,n.pe),e=Kt(s,t);for(let d of e)d.on(n)&&l.push(d);return l}function Jt(n,t){let l=[];if(n.isZeroLength())return n.ps.on(t)&&l.push(n.ps),l;let s=new b.Line(n.ps,n.pe),e=new b.Circle(t.pc,t.r),d=Kt(s,e);for(let i of d)i.on(n)&&i.on(t)&&l.push(i);return l}function Fo(n,t){let l=[];for(let s of t.toSegments()){let e=kn(s,n);for(let d of e)l.push(d)}return l}function sd(n,t){let l=[],s=new b.Vector(n.pc,t.pc),e=n.r,d=t.r;if(b.Utils.EQ_0(e)||b.Utils.EQ_0(d))return l;if(b.Utils.EQ_0(s.x)&&b.Utils.EQ_0(s.y)&&b.Utils.EQ(e,d))return l.push(n.pc.translate(-e,0)),l;let i=n.pc.distanceTo(t.pc)[0];if(b.Utils.GT(i,e+d)||b.Utils.LT(i,Math.abs(e-d)))return l;s.x/=i,s.y/=i;let c;if(b.Utils.EQ(i,e+d)||b.Utils.EQ(i,Math.abs(e-d)))return c=n.pc.translate(e*s.x,e*s.y),l.push(c),l;let o=e*e/(2*i)-d*d/(2*i)+i/2,X=n.pc.translate(o*s.x,o*s.y),a=Math.sqrt(e*e-o*o);return c=X.translate(s.rotate90CCW().multiply(a)),l.push(c),c=X.translate(s.rotate90CW().multiply(a)),l.push(c),l}function No(n,t){let l=[];for(let s of t.toSegments()){let e=Pn(s,n);for(let d of e)l.push(d)}return l}function ed(n,t){let l=[];if(n.pc.equalTo(t.pc)&&b.Utils.EQ(n.r,t.r)){let i;return i=n.start,i.on(t)&&l.push(i),i=n.end,i.on(t)&&l.push(i),i=t.start,i.on(n)&&l.push(i),i=t.end,i.on(n)&&l.push(i),l}let s=new b.Circle(n.pc,n.r),e=new b.Circle(t.pc,t.r),d=s.intersect(e);for(let i of d)i.on(n)&&i.on(t)&&l.push(i);return l}function Hl(n,t){let l=[];if(t.pc.equalTo(n.pc)&&b.Utils.EQ(t.r,n.r))return l.push(n.start),l.push(n.end),l;let s=t,e=new b.Circle(n.pc,n.r),d=sd(s,e);for(let i of d)i.on(n)&&l.push(i);return l}function Ho(n,t){let l=[];for(let s of t.toSegments()){let e=Jt(s,n);for(let d of e)l.push(d)}return l}function dd(n,t){return n.isSegment?kn(n.shape,t):Jt(t,n.shape)}function id(n,t){return n.isSegment?Jt(n.shape,t):ed(n.shape,t)}function cd(n,t){return n.isSegment?nn(n.shape,t):In(t,n.shape)}function Jo(n,t){return n.isSegment?kl(t,n.shape):Pl(t,n.shape)}function Io(n,t){return n.isSegment?Pn(n.shape,t):Hl(n.shape,t)}function Jl(n,t){let l=[];for(let s of t.edges)for(let e of dd(s,n))l.push(e);return l}function Il(n,t){let l=[];for(let s of t.edges)for(let e of id(s,n))l.push(e);return l}function ln(n,t){let l=[];if(t.isEmpty())return l;for(let s of t.edges)for(let e of cd(s,n))ad(e,l)||l.push(e);return n.sortPoints(l)}function bd(n,t){let l=[];if(t.isEmpty())return l;for(let s of t.edges)for(let e of Io(s,n))l.push(e);return l}function od(n,t){return n.isSegment?dd(t,n.shape):n.isArc?id(t,n.shape):n.isLine?cd(t,n.shape):n.isRay?Jo(t,n.shape):[]}function Xd(n,t){let l=[];if(t.isEmpty()||n.shape.box.not_intersect(t.box))return l;let s=t.edges.search(n.shape.box);for(let e of s)l=[...l,...od(n,e)];return l}function ko(n,t){let l=[];if(t.isEmpty()||n.size===0)return l;for(let s of n)l=[...l,...Xd(s,t)];return l}function Po(n,t){let l=[];if(n.isEmpty()||t.isEmpty()||n.box.not_intersect(t.box))return l;for(let s of n.edges)l=[...l,...Xd(s,t)];return l}function Qo(n,t){return n instanceof b.Line?ln(n,t):n instanceof b.Segment?Jl(n,t):n instanceof b.Arc?Il(n,t):[]}function ad(n,t){return t.some(l=>l.equalTo(n))}function rt(n){return new b.Line(n.start,n.norm)}function kl(n,t){return nn(t,rt(n)).filter(l=>n.contains(l))}function Pl(n,t){return In(rt(n),t).filter(l=>n.contains(l))}function ud(n,t){return Kt(rt(n),t).filter(l=>n.contains(l))}function Bo(n,t){return Ht(rt(n),t).filter(l=>n.contains(l))}function hd(n,t){return Nt(rt(n),t).filter(l=>n.contains(l))}function vo(n,t){return Nt(rt(n),rt(t)).filter(l=>n.contains(l)).filter(l=>t.contains(l))}function rd(n,t){return ln(rt(n),t).filter(l=>n.contains(l))}function Zd(n,t){if(n.intersect&&n.intersect instanceof Function)return n.intersect(t);throw Q.UNSUPPORTED_SHAPE_TYPE}function It(n,t){let l=[];for(let s of t)l=[...l,...Zd(n,s.shape)];return l}function wo(n,t){let l=[];for(let s of n)for(let e of t)l=[...l,...Zd(s.shape,e.shape)];return l}let Rt=class Gn extends Nl{constructor(...t){if(super(),this.isInfinite=!1,t.length===1&&t[0]instanceof Array&&t[0].length>0){const l=t[0],s=l.length,e=o=>o instanceof b.Segment||o instanceof b.Arc||o instanceof b.Ray||o instanceof b.Line,d=o=>o instanceof b.Segment||o instanceof b.Arc||o instanceof b.Ray,i=o=>o instanceof b.Segment||o instanceof b.Arc;if(s===1&&e(l[0])||s>1&&d(l[0])&&d(l[s-1])&&l.slice(1,s-1).every(i)){this.isInfinite=l.some(o=>o instanceof b.Ray||o instanceof b.Line);for(let o of l){let X=new b.Edge(o);this.append(X)}this.setArcLength()}else throw b.Errors.ILLEGAL_PARAMETERS}}get edges(){return[...this]}get box(){return this.edges.reduce((t,l)=>t.merge(l.box),new b.Box)}get vertices(){let t=this.edges.map(l=>l.start);return t.push(this.last.end),t}get length(){if(this.isEmpty())return 0;if(this.isInfinite)return Number.POSITIVE_INFINITY;let t=0;for(let l of this)t+=l.length;return t}clone(){return new Gn(this.toShapes())}setArcLength(){for(let t of this)this.setOneEdgeArcLength(t)}setOneEdgeArcLength(t){t===this.first?t.arc_length=0:t.arc_length=t.prev.arc_length+t.prev.length}pointAtLength(t){if(t>this.length||t<0||this.isInfinite)return null;let l=null;for(let s of this)if(t>=s.arc_length&&(s===this.last||t<s.next.arc_length)){l=s.pointAtLength(t-s.arc_length);break}return l}addVertex(t,l){let s=l.shape.split(t);if(s[0]===null)return l.prev;if(s[1]===null)return l;let e=new b.Edge(s[0]),d=l.prev;return this.insert(e,d),l.shape=s[1],e}getChain(t,l){let s=[];for(let e=t;e!==l.next;e=e.next)s.push(e);return s}split(t){for(let l of t){let s=this.findEdgeByPoint(l);this.addVertex(l,s)}return this}findEdgeByPoint(t){let l;for(let s of this)if(s.shape.contains(t)){l=s;break}return l}distanceTo(t){if(t instanceof Point){const[l,s]=b.Distance.shape2multiline(t,this);return[l,s.reverse()]}if(t instanceof b.Line){const[l,s]=b.Distance.shape2multiline(t,this);return[l,s.reverse()]}if(t instanceof b.Circle){const[l,s]=b.Distance.shape2multiline(t,this);return[l,s.reverse()]}if(t instanceof b.Segment){const[l,s]=b.Distance.shape2multiline(t,this);return[l,s.reverse()]}if(t instanceof b.Arc){const[l,s]=b.Distance.shape2multiline(t,this);return[l,s.reverse()]}if(t instanceof b.Multiline)return b.Distance.multiline2multiline(this,t);throw b.Errors.UNSUPPORTED_SHAPE_TYPE}intersect(t){return t instanceof b.Multiline?wo(this,t):It(t,this)}contains(t){if(t instanceof b.Point)return this.edges.some(l=>l.shape.contains(t));throw b.Errors.UNSUPPORTED_SHAPE_TYPE}translate(t){return new Gn(this.edges.map(l=>l.shape.translate(t)))}rotate(t=0,l=new b.Point){return new Gn(this.edges.map(s=>s.shape.rotate(t,l)))}transform(t=new b.Matrix){return new Gn(this.edges.map(l=>l.shape.transform(t)))}toShapes(){return this.edges.map(t=>t.shape.clone())}toJSON(){return this.edges.map(t=>t.toJSON())}svgPoints(){return this.vertices.map(t=>`${t.x},${t.y}`).join(" ")}dpath(){let t=`M${this.first.start.x},${this.first.start.y}`;for(let l of this)t+=l.svg();return t}svg(t={}){let l=`
|
|
11
|
+
<path ${xt({fill:"none",...t})} d="`;l+=`
|
|
12
12
|
M${this.first.start.x},${this.first.start.y}`;for(let s of this)l+=s.svg();return l+=`" >
|
|
13
|
-
</path>`,l}};b.Multiline=Vt;const Yo=(...n)=>new b.Multiline(...n);b.multiline=Yo;function Nt(n,t,l){let s=l.length,e=n.shape.split(t);if(e.length===0)return;let d=0;e[0]===null?d=0:e[1]===null?d=n.shape.length:d=e[0].length;let i=Ll;Gt(d,0)&&(i|=Ot),Gt(d,n.shape.length)&&(i|=Mt);let c;d===1/0?c=e[0].coord(t):c=i&Mt&&n.next&&n.next.arc_length===0?0:n.arc_length+d,l.push({id:s,pt:t,arc_length:c,edge_before:n,edge_after:void 0,face:n.face,is_vertex:i})}function _t(n){n.int_points1_sorted=at(n.int_points1),n.int_points2_sorted=at(n.int_points2)}function at(n){let t=new Map,l=0;for(let e of n)t.has(e.face)||(t.set(e.face,l),l++);for(let e of n)e.faceId=t.get(e.face);return n.slice().sort(go)}function go(n,t){return n.faceId<t.faceId?-1:n.faceId>t.faceId?1:n.arc_length<t.arc_length?-1:n.arc_length>t.arc_length?1:0}function Ml(n){if(n.int_points1.length<2)return;let t=!1,l,s,e,d;for(let i=0;i<n.int_points1_sorted.length;i++)if(n.int_points1_sorted[i].id!==-1){l=n.int_points1_sorted[i],s=n.int_points2[l.id];for(let c=i+1;c<n.int_points1_sorted.length&&(e=n.int_points1_sorted[c],!!Gt(e.arc_length,l.arc_length));c++)e.id!==-1&&(d=n.int_points2[e.id],d.id!==-1&&e.edge_before===l.edge_before&&e.edge_after===l.edge_after&&d.edge_before===s.edge_before&&d.edge_after===s.edge_after&&(e.id=-1,d.id=-1,t=!0))}s=n.int_points2_sorted[0],l=n.int_points1[s.id];for(let i=1;i<n.int_points2_sorted.length;i++){let c=n.int_points2_sorted[i];if(c.id===-1)continue;if(s.id===-1||!Gt(c.arc_length,s.arc_length)){s=c,l=n.int_points1[s.id];continue}let o=n.int_points1[c.id];o.edge_before===l.edge_before&&o.edge_after===l.edge_after&&c.edge_before===s.edge_before&&c.edge_after===s.edge_after&&(o.id=-1,c.id=-1,t=!0)}t&&(n.int_points1=n.int_points1.filter(i=>i.id>=0),n.int_points2=n.int_points2.filter(i=>i.id>=0),n.int_points1.forEach((i,c)=>i.id=c),n.int_points2.forEach((i,c)=>i.id=c))}function Tl(n){for(let t of n)t.edge_before&&(t.edge_before.bvStart=void 0,t.edge_before.bvEnd=void 0,t.edge_before.bv=void 0,t.edge_before.overlap=void 0),t.edge_after&&(t.edge_after.bvStart=void 0,t.edge_after.bvEnd=void 0,t.edge_after.bv=void 0,t.edge_after.overlap=void 0);for(let t of n)t.edge_before&&(t.edge_before.bvEnd=q),t.edge_after&&(t.edge_after.bvStart=q)}function fl(n,t){for(let l of n)l.edge_before&&l.edge_before.setInclusion(t),l.edge_after&&l.edge_after.setInclusion(t)}function Mo(n){let t,l,s,e=n.int_points1.length;for(let d=0;d<e;d++){let i=n.int_points1_sorted[d];i.face!==t&&(l=d,t=i.face);let c=d,o=Ht(n.int_points1_sorted,d,t),a;c+o<e&&n.int_points1_sorted[c+o].face===t?a=c+o:a=l;let X=Ht(n.int_points1_sorted,a,t);s=null;for(let W=a;W<a+X;W++){let L=n.int_points1_sorted[W];if(L.face===t&&n.int_points2[L.id].face===n.int_points2[i.id].face){s=L;break}}if(s===null)continue;let u=i.edge_after,h=s.edge_before;if(!(u.bv===q&&h.bv===q)||u!==h)continue;let m=n.int_points2[i.id],Z=n.int_points2[s.id],p=m.edge_after,G=Z.edge_before;p.bv===q&&G.bv===q&&p===G||(m=n.int_points2[s.id],Z=n.int_points2[i.id],p=m.edge_after,G=Z.edge_before),p.bv===q&&G.bv===q&&p===G&&u.setOverlap(p)}}function Ht(n,t,l){let s,e,d=1;if(n.length===1)return 1;s=n[t];for(let i=t+1;i<n.length&&!(s.face!==l||(e=n[i],!(e.pt.equalTo(s.pt)&&e.edge_before===s.edge_before&&e.edge_after===s.edge_after)));i++)d++;return d}function Jt(n,t){if(t){for(let l of t){let s=l.edge_before;if(l.is_vertex=Ll,s.shape.start&&s.shape.start.equalTo(l.pt)&&(l.is_vertex|=Ot),s.shape.end&&s.shape.end.equalTo(l.pt)&&(l.is_vertex|=Mt),l.is_vertex&Ot){l.edge_before=s.prev,s.prev&&(l.is_vertex=Mt);continue}if(l.is_vertex&Mt)continue;let e=n.addVertex(l.pt,s);l.edge_before=e}for(let l of t)l.edge_before?l.edge_after=l.edge_before.next:n instanceof Vt&&l.is_vertex&Ot&&(l.edge_after=n.first)}}function sd(n,t,l){const s=n.edge_before,e=t.edge_after,d=l.length;s.next=l[0],l[0].prev=s,l[d-1].next=e,e.prev=l[d-1]}const{INSIDE:tt,OUTSIDE:nt,BOUNDARY:U,OVERLAP_SAME:To,OVERLAP_OPPOSITE:fo}=gn,{NOT_VERTEX:bu,START_VERTEX:ed,END_VERTEX:dd}=gn,Cn=1,qt=2,yt=3;function Co(n,t){let[l,s]=$t(n,t,Cn,!0);return l}function Cl(n,t){let s=t.clone().reverse(),[e,d]=$t(n,s,yt,!0);return e}function id(n,t){let[l,s]=$t(n,t,qt,!0);return l}function cd(n,t){let[l,s]=$t(n,t,qt,!1),e=[];for(let i of l.faces)e=[...e,...[...i.edges].map(c=>c.shape)];let d=[];for(let i of s.faces)d=[...d,...[...i.edges].map(c=>c.shape)];return[e,d]}function Fl(n,t){let[l,s]=$t(n,t,yt,!1),e=[];for(let d of l.faces)e=[...e,...[...d.edges].map(i=>i.shape)];return e}function bd(n,t){let l=n.clone(),s=t.clone(),e=od(l,s);_t(e),Jt(l,e.int_points1_sorted),Jt(s,e.int_points2_sorted),Ml(e),_t(e);let d=e.int_points1_sorted.map(c=>c.pt),i=e.int_points2_sorted.map(c=>c.pt);return[d,i]}function Fo(n,t,l,s){let e=ad(n,l.int_points1),d=ad(t,l.int_points2);for(Xd(e,t),Xd(d,n),Tl(l.int_points1),Tl(l.int_points2),fl(l.int_points1,t),fl(l.int_points2,n);Ho(n,t,l.int_points1,l.int_points1_sorted,l.int_points2,l););Mo(l),Nl(n,s,l.int_points1_sorted,!0),Nl(t,s,l.int_points2_sorted,!1),ud(n,e,s,!0),ud(t,d,s,!1)}function No(n,t,l,s){Jo(n,t,s,l.int_points2),Io(n,t,l),Hl(n,l.int_points1),Hl(t,l.int_points2),Jl(n,l.int_points1,l.int_points2),Jl(n,l.int_points2,l.int_points1)}function $t(n,t,l,s){let e=n.clone(),d=t.clone(),i=od(e,d);return _t(i),Jt(e,i.int_points1_sorted),Jt(d,i.int_points2_sorted),Ml(i),_t(i),Fo(e,d,i,l),s&&No(e,d,i,l),[e,d]}function od(n,t){let l={int_points1:[],int_points2:[]};for(let s of n.edges){let e=t.edges.search(s.box);for(let d of e){let i=s.shape.intersect(d.shape);for(let c of i)Nt(s,c,l.int_points1),Nt(d,c,l.int_points2)}}return l}function ad(n,t){let l=[];for(let s of n.faces)t.find(e=>e.face===s)||l.push(s);return l}function Xd(n,t){for(let l of n)l.first.bv=l.first.bvStart=l.first.bvEnd=void 0,l.first.setInclusion(t)}function Ho(n,t,l,s,e,d){let i,c,o,a=s.length,X=!1;for(let u=0;u<a;u++){let h=s[u];h.face!==i&&(c=u,i=h.face);let m=u,Z=Ht(s,u,i),p;m+Z<a&&s[m+Z].face===i?p=m+Z:p=c;let G=Ht(s,p,i);o=null;for(let V=p;V<p+G;V++){let y=s[V];if(y.face===i&&e[y.id].face===e[h.id].face){o=y;break}}if(o===null)continue;let W=h.edge_after,L=o.edge_before;if(W.bv===U&&L.bv!=U){W.bv=L.bv;continue}if(W.bv!=U&&L.bv===U){L.bv=W.bv;continue}if(W.bv===U&&L.bv===U&&W!=L||W.bv===tt&&L.bv===nt||W.bv===nt&&L.bv===tt){let V=W.next;for(;V!=L;)V.bvStart=void 0,V.bvEnd=void 0,V.bv=void 0,V.setInclusion(t),V=V.next}if(W.bv===U&&L.bv===U&&W!=L){let V=W.next,y;for(;V!=L;){if(V.bv!=U){if(y===void 0)y=V.bv;else if(V.bv!=y)throw P.UNRESOLVED_BOUNDARY_CONFLICT}V=V.next}y!=null&&(W.bv=y,L.bv=y);continue}if(W.bv===tt&&L.bv===nt||W.bv===nt&&L.bv===tt){let V=W;for(;V!=L;){if(V.bvStart===W.bv&&V.bvEnd===L.bv){let[y,S]=V.shape.distanceTo(t);if(y<10*b.DP_TOL){Nt(V,S.ps,l);let R=l[l.length-1];if(R.is_vertex&ed)R.edge_after=V,R.edge_before=V.prev,V.bvStart=U,V.bv=void 0,V.setInclusion(t);else if(R.is_vertex&dd)R.edge_after=V.next,V.bvEnd=U,V.bv=void 0,V.setInclusion(t);else{let M=t.addVertex(R.pt,V);R.edge_before=M,R.edge_after=M.next,M.setInclusion(t),M.next.bvStart=U,M.next.bvEnd=void 0,M.next.bv=void 0,M.next.setInclusion(t)}let T=t.findEdgeByPoint(S.pe);Nt(T,S.pe,e);let g=e[e.length-1];if(g.is_vertex&ed)g.edge_after=T,g.edge_before=T.prev;else if(g.is_vertex&dd)g.edge_after=T.next;else{let M=e.find(H=>H.edge_after===T),z=t.addVertex(g.pt,T);g.edge_before=z,g.edge_after=z.next,M&&(M.edge_after=z),z.bvStart=void 0,z.bvEnd=U,z.bv=void 0,z.setInclusion(n),z.next.bvStart=U,z.next.bvEnd=void 0,z.next.bv=void 0,z.next.setInclusion(n)}_t(d),X=!0;break}}V=V.next}if(X)break;throw P.UNRESOLVED_BOUNDARY_CONFLICT}}return X}function Nl(n,t,l,s){if(!l)return;let e,d,i,c;for(let o=0;o<l.length;o++){if(i=l[o],i.face!==e&&(d=o,e=i.face),e.isEmpty())continue;let a=o,X=Ht(l,o,e),u;a+X<l.length&&l[a+X].face===i.face?u=a+X:u=d,c=l[u];let h=u,m=Ht(l,h,e),Z=i.edge_after,p=c.edge_before;if(Z.bv===tt&&p.bv===tt&&t===Cn||Z.bv===nt&&p.bv===nt&&t===qt||(Z.bv===nt||p.bv===nt)&&t===yt&&!s||(Z.bv===tt||p.bv===tt)&&t===yt&&s||Z.bv===U&&p.bv===U&&Z.overlap&To&&s||Z.bv===U&&p.bv===U&&Z.overlap&fo){n.removeChain(e,Z,p);for(let G=a;G<a+X;G++)l[G].edge_after=void 0;for(let G=h;G<h+m;G++)l[G].edge_before=void 0}o+=X-1}}function Jo(n,t,l,s){for(let e of t.faces){for(let d of e)n.edges.add(d);s.find(d=>d.face===e)===void 0&&n.addFace(e.first,e.last)}}function Io(n,t,l){if(l.int_points1.length!==0)for(let s=0;s<l.int_points1.length;s++){let e=l.int_points1[s],d=l.int_points2[s];if(e.edge_before!==void 0&&e.edge_after===void 0&&d.edge_before===void 0&&d.edge_after!==void 0&&(e.edge_before.next=d.edge_after,d.edge_after.prev=e.edge_before,e.edge_after=d.edge_after,d.edge_before=e.edge_before),d.edge_before!==void 0&&d.edge_after===void 0&&e.edge_before===void 0&&e.edge_after!==void 0&&(d.edge_before.next=e.edge_after,e.edge_after.prev=d.edge_before,d.edge_after=e.edge_after,e.edge_before=d.edge_before),e.edge_before!==void 0&&e.edge_after===void 0)for(let i of l.int_points1_sorted)i!==e&&i.edge_before===void 0&&i.edge_after!==void 0&&i.pt.equalTo(e.pt)&&(e.edge_before.next=i.edge_after,i.edge_after.prev=e.edge_before,e.edge_after=i.edge_after,i.edge_before=e.edge_before);if(d.edge_before!==void 0&&d.edge_after===void 0)for(let i of l.int_points2_sorted)i!==d&&i.edge_before===void 0&&i.edge_after!==void 0&&i.pt.equalTo(d.pt)&&(d.edge_before.next=i.edge_after,i.edge_after.prev=d.edge_before,d.edge_after=i.edge_after,i.edge_before=d.edge_before)}}function Hl(n,t){for(let l of t)n.faces.delete(l.face),l.face=void 0,l.edge_before&&(l.edge_before.face=void 0),l.edge_after&&(l.edge_after.face=void 0)}function Jl(n,t,l){for(let s of t){if(s.edge_before===void 0||s.edge_after===void 0||s.face||s.edge_after.face||s.edge_before.face)continue;let e=s.edge_after,d=s.edge_before;try{Rl.testInfiniteLoop(e)}catch{throw P.CANNOT_COMPLETE_BOOLEAN_OPERATION}let i=n.addFace(e,d);for(let c of t)c.edge_before&&c.edge_after&&c.edge_before.face===i&&c.edge_after.face===i&&(c.face=i);for(let c of l)c.edge_before&&c.edge_after&&c.edge_before.face===i&&c.edge_after.face===i&&(c.face=i)}}function ud(n,t,l,s){for(let e of t){let d=e.first.bv;(l===Cn&&d===tt||l===yt&&d===tt&&s||l===yt&&d===nt&&!s||l===qt&&d===nt)&&n.deleteFace(e)}}var tn=Object.freeze({__proto__:null,BOOLEAN_INTERSECT:qt,BOOLEAN_SUBTRACT:yt,BOOLEAN_UNION:Cn,calculateIntersections:bd,innerClip:cd,intersect:id,outerClip:Fl,removeNotRelevantChains:Nl,removeOldFaces:Hl,restoreFaces:Jl,subtract:Cl,unify:Co});const ko=RegExp("T.F..FFF.|T.F...F.."),Po=RegExp("T........|.T.......|...T.....|....T...."),Qo=RegExp("FT.......|F..T.....|F...T...."),vo=RegExp("T.F..F..."),Bo=RegExp("T.F..F...|.TF..F...|..FT.F...|..F.TF...");class It{constructor(){this.m=new Array(9).fill(void 0)}get I2I(){return this.m[0]}set I2I(t){this.m[0]=t}get I2B(){return this.m[1]}set I2B(t){this.m[1]=t}get I2E(){return this.m[2]}set I2E(t){this.m[2]=t}get B2I(){return this.m[3]}set B2I(t){this.m[3]=t}get B2B(){return this.m[4]}set B2B(t){this.m[4]=t}get B2E(){return this.m[5]}set B2E(t){this.m[5]=t}get E2I(){return this.m[6]}set E2I(t){this.m[6]=t}get E2B(){return this.m[7]}set E2B(t){this.m[7]=t}get E2E(){return this.m[8]}set E2E(t){this.m[8]=t}toString(){return this.m.map(t=>t instanceof Array&&t.length>0?"T":t instanceof Array&&t.length===0?"F":"*").join("")}equal(){return ko.test(this.toString())}intersect(){return Po.test(this.toString())}touch(){return Qo.test(this.toString())}inside(){return vo.test(this.toString())}covered(){return Bo.test(this.toString())}}function nn(n,t){let l,s=new b.Ray(t),e=new b.Line(s.pt,s.norm);const d=new b.Box(s.box.xmin-b.DP_TOL,s.box.ymin-b.DP_TOL,s.box.xmax+b.DP_TOL,s.box.ymax+b.DP_TOL);if(n.box.not_intersect(d))return b.OUTSIDE;let i=n.edges.search(d);if(i.length===0)return b.OUTSIDE;for(let X of i)if(X.shape.contains(t))return b.BOUNDARY;let c=[...n.faces],o=[];for(let X of i)for(let u of s.intersect(X.shape)){if(u.equalTo(t))return b.BOUNDARY;o.push({pt:u,edge:X,face_index:c.indexOf(X.face)})}o.sort((X,u)=>Qe(X.pt.x,u.pt.x)?-1:Pe(X.pt.x,u.pt.x)?1:X.face_index<u.face_index?-1:X.face_index>u.face_index?1:X.edge.arc_length<u.edge.arc_length?-1:X.edge.arc_length>u.edge.arc_length?1:0);let a=0;for(let X=0;X<o.length;X++){let u=o[X];if(u.pt.equalTo(u.edge.shape.start)){if(X>0&&u.pt.equalTo(o[X-1].pt)&&u.face_index===o[X-1].face_index&&u.edge.prev===o[X-1].edge)continue;let h=u.edge.prev;for(;xl(h.length);)h=h.prev;let m=h.shape.tangentInEnd(),Z=u.pt.translate(m),p=u.edge.shape.tangentInStart(),G=u.pt.translate(p),W=Z.leftTo(e),L=G.leftTo(e);(W&&!L||!W&&L)&&a++}else if(u.pt.equalTo(u.edge.shape.end)){if(X>0&&u.pt.equalTo(o[X-1].pt)&&u.face_index===o[X-1].face_index&&u.edge.next===o[X-1].edge)continue;let h=u.edge.next;for(;xl(h.length);)h=h.next;let m=h.shape.tangentInStart(),Z=u.pt.translate(m),p=u.edge.shape.tangentInEnd(),G=u.pt.translate(p),W=Z.leftTo(e),L=G.leftTo(e);(W&&!L||!W&&L)&&a++}else if(u.edge.shape instanceof b.Segment)a++;else{let h=u.edge.shape.box;Gt(u.pt.y,h.ymin)||Gt(u.pt.y,h.ymax)||a++}}return l=a%2===1?Yn:Je,l}function wo(n,t){return kt(n,t).equal()}function rd(n,t){return kt(n,t).intersect()}function Uo(n,t){return kt(n,t).touch()}function jo(n,t){return!rd(n,t)}function hd(n,t){return kt(n,t).inside()}function md(n,t){return kt(n,t).covered()}function Eo(n,t){return hd(t,n)}function Zd(n,t){return md(t,n)}function kt(n,t){if(n instanceof b.Line&&t instanceof b.Line)return Oo(n,t);if(n instanceof b.Line&&t instanceof b.Circle)return Do(n,t);if(n instanceof b.Line&&t instanceof b.Box)return Ao(n,t);if(n instanceof b.Line&&t instanceof b.Polygon)return _o(n,t);if((n instanceof b.Segment||n instanceof b.Arc)&&t instanceof b.Polygon)return Gd(n,t);if((n instanceof b.Segment||n instanceof b.Arc)&&(t instanceof b.Circle||t instanceof b.Box))return Gd(n,new b.Polygon(t));if(n instanceof b.Polygon&&t instanceof b.Polygon)return Fn(n,t);if((n instanceof b.Circle||n instanceof b.Box)&&(t instanceof b.Circle||t instanceof b.Box))return Fn(new b.Polygon(n),new b.Polygon(t));if((n instanceof b.Circle||n instanceof b.Box)&&t instanceof b.Polygon)return Fn(new b.Polygon(n),t);if(n instanceof b.Polygon&&(t instanceof b.Circle||t instanceof b.Box))return Fn(n,new b.Polygon(t))}function Oo(n,t){let l=new It,s=Tt(n,t);return s.length===0?n.contains(t.pt)&&t.contains(n.pt)?(l.I2I=[n],l.I2E=[],l.E2I=[]):(l.I2I=[],l.I2E=[n],l.E2I=[t]):(l.I2I=s,l.I2E=n.split(s),l.E2I=t.split(s)),l}function Do(n,t){let l=new It,s=Wt(n,t);if(s.length===0)l.I2I=[],l.I2B=[],l.I2E=[n],l.E2I=[t];else if(s.length===1)l.I2I=[],l.I2B=s,l.I2E=n.split(s),l.E2I=[t];else{let e=new Vt([n]),d=n.sortPoints(s);e.split(d);let i=e.toShapes();l.I2I=[i[1]],l.I2B=d,l.I2E=[i[0],i[2]],l.E2I=new b.Polygon([t.toArc()]).cutWithLine(n)}return l}function Ao(n,t){let l=new It,s=ft(n,t);if(s.length===0)l.I2I=[],l.I2B=[],l.I2E=[n],l.E2I=[t];else if(s.length===1)l.I2I=[],l.I2B=s,l.I2E=n.split(s),l.E2I=[t];else{let e=new Vt([n]),d=n.sortPoints(s);e.split(d);let i=e.toShapes();t.toSegments().some(c=>c.contains(s[0])&&c.contains(s[1]))?(l.I2I=[],l.I2B=[i[1]],l.I2E=[i[0],i[2]],l.E2I=[t]):(l.I2I=[i[1]],l.I2B=d,l.I2E=[i[0],i[2]],l.E2I=new b.Polygon(t.toSegments()).cutWithLine(n))}return l}function _o(n,t){let l=new It,s=At(n,t),e=new Vt([n]),d=s.length>0?s.slice():n.sortPoints(s);return e.split(d),[...e].forEach(i=>i.setInclusion(t)),l.I2I=[...e].filter(i=>i.bv===b.INSIDE).map(i=>i.shape),l.I2B=[...e].slice(1).map(i=>i.bv===b.BOUNDARY?i.shape:i.shape.start),l.I2E=[...e].filter(i=>i.bv===b.OUTSIDE).map(i=>i.shape),l.E2I=t.cutWithLine(n),l}function Gd(n,t){let l=new It,s=Ro(n,t),e=s.length>0?s.slice():n.sortPoints(s),d=new Vt([n]);d.split(e),[...d].forEach(i=>i.setInclusion(t)),l.I2I=[...d].filter(i=>i.bv===b.INSIDE).map(i=>i.shape),l.I2B=[...d].slice(1).map(i=>i.bv===b.BOUNDARY?i.shape:i.shape.start),l.I2E=[...d].filter(i=>i.bv===b.OUTSIDE).map(i=>i.shape),l.B2I=[],l.B2B=[],l.B2E=[];for(let i of[n.start,n.end])switch(nn(t,i)){case b.INSIDE:l.B2I.push(i);break;case b.BOUNDARY:l.B2B.push(i);break;case b.OUTSIDE:l.B2E.push(i);break}return l}function Fn(n,t){let l=new It,[s,e]=bd(n,t),d=id(n,t),i=Cl(n,t),c=Cl(t,n),[o,a]=cd(n,t),X=Fl(n,t),u=Fl(t,n);return l.I2I=d.isEmpty()?[]:[d],l.I2B=a,l.I2E=i.isEmpty()?[]:[i],l.B2I=o,l.B2B=s,l.B2E=X,l.E2I=c.isEmpty()?[]:[c],l.E2B=u,l}var qo=Object.freeze({__proto__:null,contain:Eo,cover:Zd,covered:md,disjoint:jo,equal:wo,inside:hd,intersect:rd,relate:kt,touch:Uo});class D{constructor(t=1,l=0,s=0,e=1,d=0,i=0){this.a=t,this.b=l,this.c=s,this.d=e,this.tx=d,this.ty=i}fromMatrix3x3(t){const[l,s,e]=t[0],[d,i,c]=t[1];return new D(l,d,s,i,e,c)}toMatrix3x3(){return[[this.a,this.c,this.tx],[this.b,this.d,this.ty],[0,0,1]]}clone(){return new D(this.a,this.b,this.c,this.d,this.tx,this.ty)}transform(t){return[t[0]*this.a+t[1]*this.c+this.tx,t[0]*this.b+t[1]*this.d+this.ty]}multiply(t){return new D(this.a*t.a+this.c*t.b,this.b*t.a+this.d*t.b,this.a*t.c+this.c*t.d,this.b*t.c+this.d*t.d,this.a*t.tx+this.c*t.ty+this.tx,this.b*t.tx+this.d*t.ty+this.ty)}translate(...t){let l,s;if(t.length==1&&!isNaN(t[0].x)&&!isNaN(t[0].y))l=t[0].x,s=t[0].y;else if(t.length===2&&typeof t[0]=="number"&&typeof t[1]=="number")l=t[0],s=t[1];else throw P.ILLEGAL_PARAMETERS;return this.multiply(new D(1,0,0,1,l,s))}rotate(t,l=0,s=0){let e=Math.cos(t),d=Math.sin(t);return this.translate(l,s).multiply(new D(e,d,-d,e,0,0)).translate(-l,-s)}scale(t,l){return this.multiply(new D(t,0,0,l,0,0))}equalTo(t){return!(!b.Utils.EQ(this.tx,t.tx)||!b.Utils.EQ(this.ty,t.ty)||!b.Utils.EQ(this.a,t.a)||!b.Utils.EQ(this.b,t.b)||!b.Utils.EQ(this.c,t.c)||!b.Utils.EQ(this.d,t.d))}}b.Matrix=D;const $o=(...n)=>new b.Matrix(...n);b.matrix=$o;class ta{constructor(t,l){this.low=t,this.high=l}get max(){return this.clone()}less_than(t){return this.low<t.low||this.low===t.low&&this.high<t.high}equal_to(t){return this.low===t.low&&this.high===t.high}intersect(t){return!this.not_intersect(t)}not_intersect(t){return this.high<t.low||t.high<this.low}merge(t){const l=this.low===void 0?t.low:this.low<t.low?this.low:t.low,s=this.high===void 0?t.high:this.high>t.high?this.high:t.high,e=this.clone();return e.low=l,e.high=s,e}output(){return[this.low,this.high]}comparable_less_than(t,l){return t<l}}class Il extends ta{clone(){return new Il(this.low,this.high)}}const j=1,k=0;class Xt{constructor(t,l,s=null,e=null,d=null,i=k){if(this.left=s,this.right=e,this.parent=d,this.color=i,this.item={key:void 0,values:[]},l!==void 0&&this.item.values.push(l),t!==void 0)if(Array.isArray(t)){const[c,o]=t;if(!Number.isNaN(c)&&!Number.isNaN(o)){let a=c,X=o;a>X&&([a,X]=[X,a]),this.item.key=new Il(a,X)}}else this.item.key=t;this.max=this.item.key?this.item.key.max:void 0}isNil(){return this.item.key===void 0&&this.item.values.length===0&&this.left===null&&this.right===null&&this.color===k}requireKey(){if(!this.item.key)throw new Error("Node key is undefined (nil/sentinel). Operation is not applicable.");return this.item.key}less_than(t){const l=this.requireKey(),s=t.requireKey();return l.less_than(s)}_value_equal(t){const l=this.item.values[0],s=t.item.values[0];return l&&s&&l.equal_to?l.equal_to(s):l===s}equal_to(t){const l=this.requireKey(),s=t.requireKey();return l.equal_to(s)}intersect(t){const l=this.requireKey(),s=t.requireKey();return l.intersect(s)}copy_data(t){this.item.key=t.item.key,this.item.values=t.item.values.slice()}update_max(){this.max=this.item.key?this.item.key.max:void 0,this.right&&this.right.max&&(this.max=this.max?this.max.merge(this.right.max):this.right.max),this.left&&this.left.max&&(this.max=this.max?this.max.merge(this.left.max):this.left.max)}not_intersect_left_subtree(t){if(!this.left)return!0;const l=this.left.max?this.left.max.high:this.left.item.key.high,s=this.requireKey(),e=t.requireKey();return s.comparable_less_than(l,e.low)}not_intersect_right_subtree(t){if(!this.right)return!0;const l=this.right.max?this.right.max.low:this.right.item.key.low,s=this.requireKey(),e=t.requireKey();return s.comparable_less_than(e.high,l)}}class ln{constructor(){this.root=null,this.nil_node=new Xt}get size(){let t=0;return this.tree_walk(this.root,l=>t+=l.item.values.length),t}get keys(){const t=[];return this.tree_walk(this.root,l=>t.push(l.item.key.output())),t}get values(){const t=[];return this.tree_walk(this.root,l=>{for(const s of l.item.values)t.push(s)}),t}get items(){const t=[];return this.tree_walk(this.root,l=>{const s=l.item.key.output();for(const e of l.item.values)t.push({key:s,value:e})}),t}isEmpty(){return this.root==null||this.root===this.nil_node}clear(){this.root=null}insert(t,l=t){if(t===void 0)return;const s=this.tree_search(this.root,new Xt(t));if(s)return s.item.values.push(l),s;const e=new Xt(t,l,this.nil_node,this.nil_node,null,j);return this.tree_insert(e),this.recalc_max(e),e}exist(t,l=t){const s=this.tree_search(this.root,new Xt(t));return s?arguments.length<2||l===t?!0:s.item.values.some(e=>e&&e.equal_to?e.equal_to(l):e===l):!1}remove(t,l=t){const s=this.tree_search(this.root,new Xt(t));if(!s)return;if(arguments.length<2)return this.tree_delete(s),s;const e=s.item.values.findIndex(d=>d&&d.equal_to?d.equal_to(l):d===l);if(e>=0)return s.item.values.splice(e,1),s.item.values.length===0&&this.tree_delete(s),s}search(t,l=(s,e)=>s===e?e.output():s){const s=new Xt(t),e=[];this.tree_search_interval(this.root,s,e);const d=[];for(const i of e)for(const c of i.item.values)d.push(l(c,i.item.key));return d}intersect_any(t){const l=new Xt(t);return this.tree_find_any_interval(this.root,l)}forEach(t){this.tree_walk(this.root,l=>{for(const s of l.item.values)t(l.item.key,s)})}map(t){const l=new ln;return this.tree_walk(this.root,s=>{for(const e of s.item.values)l.insert(s.item.key,t(e,s.item.key))}),l}*iterate(t,l=(s,e)=>s===e?e.output():s){let s=null;for(t?s=this.tree_search_nearest_forward(this.root,new Xt(t)):this.root&&(s=this.local_minimum(this.root));s;){for(const e of s.item.values)yield l(e,s.item.key);s=this.tree_successor(s)}}recalc_max(t){let l=t;for(;l.parent!=null;)l.parent.update_max(),l=l.parent}tree_insert(t){let l=this.root,s=null;if(this.root==null||this.root===this.nil_node)this.root=t;else{for(;l!==this.nil_node;)s=l,t.less_than(l)?l=l.left:l=l.right;t.parent=s,t.less_than(s)?s.left=t:s.right=t}this.insert_fixup(t)}insert_fixup(t){let l,s;for(l=t;l!==this.root&&l.parent.color===j;)l.parent===l.parent.parent.left?(s=l.parent.parent.right,s.color===j?(l.parent.color=k,s.color=k,l.parent.parent.color=j,l=l.parent.parent):(l===l.parent.right&&(l=l.parent,this.rotate_left(l)),l.parent.color=k,l.parent.parent.color=j,this.rotate_right(l.parent.parent))):(s=l.parent.parent.left,s.color===j?(l.parent.color=k,s.color=k,l.parent.parent.color=j,l=l.parent.parent):(l===l.parent.left&&(l=l.parent,this.rotate_right(l)),l.parent.color=k,l.parent.parent.color=j,this.rotate_left(l.parent.parent)));this.root.color=k}tree_delete(t){let l,s;t.left===this.nil_node||t.right===this.nil_node?l=t:l=this.tree_successor(t),l.left!==this.nil_node?s=l.left:s=l.right,s.parent=l.parent,l===this.root?this.root=s:(l===l.parent.left?l.parent.left=s:l.parent.right=s,l.parent.update_max()),this.recalc_max(s),l!==t&&(t.copy_data(l),t.update_max(),this.recalc_max(t)),l.color===k&&this.delete_fixup(s)}delete_fixup(t){let l=t,s;for(;l!==this.root&&l.parent!=null&&l.color===k;)l===l.parent.left?(s=l.parent.right,s.color===j&&(s.color=k,l.parent.color=j,this.rotate_left(l.parent),s=l.parent.right),s.left.color===k&&s.right.color===k?(s.color=j,l=l.parent):(s.right.color===k&&(s.color=j,s.left.color=k,this.rotate_right(s),s=l.parent.right),s.color=l.parent.color,l.parent.color=k,s.right.color=k,this.rotate_left(l.parent),l=this.root)):(s=l.parent.left,s.color===j&&(s.color=k,l.parent.color=j,this.rotate_right(l.parent),s=l.parent.left),s.left.color===k&&s.right.color===k?(s.color=j,l=l.parent):(s.left.color===k&&(s.color=j,s.right.color=k,this.rotate_left(s),s=l.parent.left),s.color=l.parent.color,l.parent.color=k,s.left.color=k,this.rotate_right(l.parent),l=this.root));l.color=k}tree_search(t,l){if(!(t==null||t===this.nil_node))return l.equal_to(t)?t:l.less_than(t)?this.tree_search(t.left,l):this.tree_search(t.right,l)}tree_search_nearest_forward(t,l){let s=null,e=t;for(;e&&e!==this.nil_node;)e.less_than(l)?e.intersect(l)?(s=e,e=e.left):e=e.right:((!s||e.less_than(s))&&(s=e),e=e.left);return s||null}tree_search_interval(t,l,s){t!=null&&t!==this.nil_node&&(t.left!==this.nil_node&&!t.not_intersect_left_subtree(l)&&this.tree_search_interval(t.left,l,s),t.intersect(l)&&s.push(t),t.right!==this.nil_node&&!t.not_intersect_right_subtree(l)&&this.tree_search_interval(t.right,l,s))}tree_find_any_interval(t,l){let s=!1;return t!=null&&t!==this.nil_node&&(t.left!==this.nil_node&&!t.not_intersect_left_subtree(l)&&(s=this.tree_find_any_interval(t.left,l)),s||(s=t.intersect(l)),!s&&t.right!==this.nil_node&&!t.not_intersect_right_subtree(l)&&(s=this.tree_find_any_interval(t.right,l))),s}local_minimum(t){let l=t;for(;l.left!=null&&l.left!==this.nil_node;)l=l.left;return l}local_maximum(t){let l=t;for(;l.right!=null&&l.right!==this.nil_node;)l=l.right;return l}tree_successor(t){let l,s,e;if(t.right!==this.nil_node)l=this.local_minimum(t.right);else{for(s=t,e=t.parent;e!=null&&e.right===s;)s=e,e=e.parent;l=e}return l}rotate_left(t){const l=t.right;t.right=l.left,l.left!==this.nil_node&&(l.left.parent=t),l.parent=t.parent,t===this.root?this.root=l:t===t.parent.left?t.parent.left=l:t.parent.right=l,l.left=t,t.parent=l,t!==null&&t!==this.nil_node&&t.update_max(),l!=null&&l!==this.nil_node&&l.update_max()}rotate_right(t){const l=t.left;t.left=l.right,l.right!==this.nil_node&&(l.right.parent=t),l.parent=t.parent,t===this.root?this.root=l:t===t.parent.left?t.parent.left=l:t.parent.right=l,l.right=t,t.parent=l,t!==null&&t!==this.nil_node&&t.update_max(),l!=null&&l!==this.nil_node&&l.update_max()}tree_walk(t,l){t!=null&&t!==this.nil_node&&(this.tree_walk(t.left,l),l(t),this.tree_walk(t.right,l))}testRedBlackProperty(){let t=!0;return this.tree_walk(this.root,function(l){l.color===j&&(l.left.color===k&&l.right.color===k||(t=!1))}),t}testBlackHeightProperty(t){let l=0,s=0,e=0;if(t.color===k&&l++,t.left!==this.nil_node?s=this.testBlackHeightProperty(t.left):s=1,t.right!==this.nil_node?e=this.testBlackHeightProperty(t.right):e=1,s!==e)throw new Error("Red-black height property violated");return l+=s,l}}class na extends Set{constructor(t){super(t),this.index=new ln,this.forEach(l=>this.index.insert(l))}add(t){let l=this.size;const{key:s,value:e}=t,d=s||t.box,i=e||t;return super.add(i),this.size>l&&this.index.insert(d,i),this}delete(t){const{key:l,value:s}=t,e=l||t.box,d=s||t;let i=super.delete(d);return i&&this.index.remove(e,d),i}clear(){super.clear(),this.index=new ln}search(t){return this.index.search(t)}hit(t){let l=new b.Box(t.x-1,t.y-1,t.x+1,t.y+1);return this.index.search(l).filter(e=>t.on(e))}svg(){return[...this].reduce((l,s)=>l+s.svg(),"")}}b.PlanarSet=na;class ut{get name(){throw P.CANNOT_INVOKE_ABSTRACT_METHOD}get box(){throw P.CANNOT_INVOKE_ABSTRACT_METHOD}clone(){throw P.CANNOT_INVOKE_ABSTRACT_METHOD}translate(...t){return this.transform(new D().translate(...t))}rotate(t,l=new b.Point){return this.transform(new D().rotate(t,l.x,l.y))}scale(t,l){return this.transform(new D().scale(t,l))}transform(...t){throw P.CANNOT_INVOKE_ABSTRACT_METHOD}toJSON(){return Object.assign({},this,{name:this.name})}svg(t={}){throw P.CANNOT_INVOKE_ABSTRACT_METHOD}}let Nn=class mi extends ut{constructor(...t){if(super(),this.x=0,this.y=0,t.length!==0){if(t.length===1&&t[0]instanceof Array&&t[0].length===2){let l=t[0];if(typeof l[0]=="number"&&typeof l[1]=="number"){this.x=l[0],this.y=l[1];return}}if(t.length===1&&t[0]instanceof Object&&t[0].name==="point"){let{x:l,y:s}=t[0];this.x=l,this.y=s;return}if(t.length===2&&typeof t[0]=="number"&&typeof t[1]=="number"){this.x=t[0],this.y=t[1];return}throw P.ILLEGAL_PARAMETERS}}get box(){return new b.Box(this.x,this.y,this.x,this.y)}clone(){return new b.Point(this.x,this.y)}get vertices(){return[this.clone()]}equalTo(t){return b.Utils.EQ(this.x,t.x)&&b.Utils.EQ(this.y,t.y)}lessThan(t){return!!(b.Utils.LT(this.y,t.y)||b.Utils.EQ(this.y,t.y)&&b.Utils.LT(this.x,t.x))}transform(t){return new b.Point(t.transform([this.x,this.y]))}projectionOn(t){if(this.equalTo(t.pt))return this.clone();let l=new b.Vector(this,t.pt);if(b.Utils.EQ_0(l.cross(t.norm)))return t.pt.clone();let s=l.dot(t.norm),e=t.norm.multiply(s);return this.translate(e)}leftTo(t){let l=new b.Vector(t.pt,this);return b.Utils.GT(l.dot(t.norm),0)}distanceTo(t){if(t instanceof mi){let l=t.x-this.x,s=t.y-this.y;return[Math.sqrt(l*l+s*s),new b.Segment(this,t)]}if(t instanceof b.Line)return b.Distance.point2line(this,t);if(t instanceof b.Circle)return b.Distance.point2circle(this,t);if(t instanceof b.Segment)return b.Distance.point2segment(this,t);if(t instanceof b.Arc)return b.Distance.point2arc(this,t);if(t instanceof b.Polygon)return b.Distance.point2polygon(this,t);if(t instanceof b.PlanarSet)return b.Distance.shape2planarSet(this,t);if(t instanceof b.Multiline)return b.Distance.shape2multiline(this,t)}on(t){if(t instanceof b.Point)return this.equalTo(t);if(t.contains&&t.contains instanceof Function)return t.contains(this);throw b.Errors.UNSUPPORTED_SHAPE_TYPE}get name(){return"point"}svg(t={}){const l=t.r??3;return`
|
|
13
|
+
</path>`,l}};b.Multiline=Rt;const Uo=(...n)=>new b.Multiline(...n);b.multiline=Uo;function kt(n,t,l){let s=l.length,e=n.shape.split(t);if(e.length===0)return;let d=0;e[0]===null?d=0:e[1]===null?d=n.shape.length:d=e[0].length;let i=fl;Lt(d,0)&&(i|=tn),Lt(d,n.shape.length)&&(i|=Ft);let c;d===1/0?c=e[0].coord(t):c=i&Ft&&n.next&&n.next.arc_length===0?0:n.arc_length+d,l.push({id:s,pt:t,arc_length:c,edge_before:n,edge_after:void 0,face:n.face,is_vertex:i})}function sn(n){n.int_points1_sorted=Zt(n.int_points1),n.int_points2_sorted=Zt(n.int_points2)}function Zt(n){let t=new Map,l=0;for(let e of n)t.has(e.face)||(t.set(e.face,l),l++);for(let e of n)e.faceId=t.get(e.face);return n.slice().sort(jo)}function jo(n,t){return n.faceId<t.faceId?-1:n.faceId>t.faceId?1:n.arc_length<t.arc_length?-1:n.arc_length>t.arc_length?1:0}function Ql(n){if(n.int_points1.length<2)return;let t=!1,l,s,e,d;for(let i=0;i<n.int_points1_sorted.length;i++)if(n.int_points1_sorted[i].id!==-1){l=n.int_points1_sorted[i],s=n.int_points2[l.id];for(let c=i+1;c<n.int_points1_sorted.length&&(e=n.int_points1_sorted[c],!!Lt(e.arc_length,l.arc_length));c++)e.id!==-1&&(d=n.int_points2[e.id],d.id!==-1&&e.edge_before===l.edge_before&&e.edge_after===l.edge_after&&d.edge_before===s.edge_before&&d.edge_after===s.edge_after&&(e.id=-1,d.id=-1,t=!0))}s=n.int_points2_sorted[0],l=n.int_points1[s.id];for(let i=1;i<n.int_points2_sorted.length;i++){let c=n.int_points2_sorted[i];if(c.id===-1)continue;if(s.id===-1||!Lt(c.arc_length,s.arc_length)){s=c,l=n.int_points1[s.id];continue}let o=n.int_points1[c.id];o.edge_before===l.edge_before&&o.edge_after===l.edge_after&&c.edge_before===s.edge_before&&c.edge_after===s.edge_after&&(o.id=-1,c.id=-1,t=!0)}t&&(n.int_points1=n.int_points1.filter(i=>i.id>=0),n.int_points2=n.int_points2.filter(i=>i.id>=0),n.int_points1.forEach((i,c)=>i.id=c),n.int_points2.forEach((i,c)=>i.id=c))}function Bl(n){for(let t of n)t.edge_before&&(t.edge_before.bvStart=void 0,t.edge_before.bvEnd=void 0,t.edge_before.bv=void 0,t.edge_before.overlap=void 0),t.edge_after&&(t.edge_after.bvStart=void 0,t.edge_after.bvEnd=void 0,t.edge_after.bv=void 0,t.edge_after.overlap=void 0);for(let t of n)t.edge_before&&(t.edge_before.bvEnd=lt),t.edge_after&&(t.edge_after.bvStart=lt)}function vl(n,t){for(let l of n)l.edge_before&&l.edge_before.setInclusion(t),l.edge_after&&l.edge_after.setInclusion(t)}function Eo(n){let t,l,s,e=n.int_points1.length;for(let d=0;d<e;d++){let i=n.int_points1_sorted[d];i.face!==t&&(l=d,t=i.face);let c=d,o=Pt(n.int_points1_sorted,d,t),X;c+o<e&&n.int_points1_sorted[c+o].face===t?X=c+o:X=l;let a=Pt(n.int_points1_sorted,X,t);s=null;for(let W=X;W<X+a;W++){let L=n.int_points1_sorted[W];if(L.face===t&&n.int_points2[L.id].face===n.int_points2[i.id].face){s=L;break}}if(s===null)continue;let u=i.edge_after,r=s.edge_before;if(!(u.bv===lt&&r.bv===lt)||u!==r)continue;let Z=n.int_points2[i.id],G=n.int_points2[s.id],p=Z.edge_after,m=G.edge_before;p.bv===lt&&m.bv===lt&&p===m||(Z=n.int_points2[s.id],G=n.int_points2[i.id],p=Z.edge_after,m=G.edge_before),p.bv===lt&&m.bv===lt&&p===m&&u.setOverlap(p)}}function Pt(n,t,l){let s,e,d=1;if(n.length===1)return 1;s=n[t];for(let i=t+1;i<n.length&&!(s.face!==l||(e=n[i],!(e.pt.equalTo(s.pt)&&e.edge_before===s.edge_before&&e.edge_after===s.edge_after)));i++)d++;return d}function Qt(n,t){if(t){for(let l of t){let s=l.edge_before;if(l.is_vertex=fl,s.shape.start&&s.shape.start.equalTo(l.pt)&&(l.is_vertex|=tn),s.shape.end&&s.shape.end.equalTo(l.pt)&&(l.is_vertex|=Ft),l.is_vertex&tn){l.edge_before=s.prev,s.prev&&(l.is_vertex=Ft);continue}if(l.is_vertex&Ft)continue;let e=n.addVertex(l.pt,s);l.edge_before=e}for(let l of t)l.edge_before?l.edge_after=l.edge_before.next:n instanceof Rt&&l.is_vertex&tn&&(l.edge_after=n.first)}}function Gd(n,t,l){const s=n.edge_before,e=t.edge_after,d=l.length;s.next=l[0],l[0].prev=s,l[d-1].next=e,e.prev=l[d-1]}const{INSIDE:et,OUTSIDE:dt,BOUNDARY:j,OVERLAP_SAME:Oo,OVERLAP_OPPOSITE:Ao}=Jn,{NOT_VERTEX:eh,START_VERTEX:md,END_VERTEX:pd}=Jn,Qn=1,en=2,St=3;function Do(n,t){let[l,s]=dn(n,t,Qn,!0);return l}function wl(n,t){let s=t.clone().reverse(),[e,d]=dn(n,s,St,!0);return e}function Wd(n,t){let[l,s]=dn(n,t,en,!0);return l}function Vd(n,t){let[l,s]=dn(n,t,en,!1),e=[];for(let i of l.faces)e=[...e,...[...i.edges].map(c=>c.shape)];let d=[];for(let i of s.faces)d=[...d,...[...i.edges].map(c=>c.shape)];return[e,d]}function Ul(n,t){let[l,s]=dn(n,t,St,!1),e=[];for(let d of l.faces)e=[...e,...[...d.edges].map(i=>i.shape)];return e}function yd(n,t){let l=n.clone(),s=t.clone(),e=Ld(l,s);sn(e),Qt(l,e.int_points1_sorted),Qt(s,e.int_points2_sorted),Ql(e),sn(e);let d=e.int_points1_sorted.map(c=>c.pt),i=e.int_points2_sorted.map(c=>c.pt);return[d,i]}function qo(n,t,l,s){let e=xd(n,l.int_points1),d=xd(t,l.int_points2);for(Kd(e,t),Kd(d,n),Bl(l.int_points1),Bl(l.int_points2),vl(l.int_points1,t),vl(l.int_points2,n);$o(n,t,l.int_points1,l.int_points1_sorted,l.int_points2,l););Eo(l),jl(n,s,l.int_points1_sorted,!0),jl(t,s,l.int_points2_sorted,!1),Rd(n,e,s,!0),Rd(t,d,s,!1)}function _o(n,t,l,s){tX(n,t,s,l.int_points2),nX(n,t,l),El(n,l.int_points1),El(t,l.int_points2),Ol(n,l.int_points1,l.int_points2),Ol(n,l.int_points2,l.int_points1)}function dn(n,t,l,s){let e=n.clone(),d=t.clone(),i=Ld(e,d);return sn(i),Qt(e,i.int_points1_sorted),Qt(d,i.int_points2_sorted),Ql(i),sn(i),qo(e,d,i,l),s&&_o(e,d,i,l),[e,d]}function Ld(n,t){let l={int_points1:[],int_points2:[]};for(let s of n.edges){let e=t.edges.search(s.box);for(let d of e){let i=s.shape.intersect(d.shape);for(let c of i)kt(s,c,l.int_points1),kt(d,c,l.int_points2)}}return l}function xd(n,t){let l=[];for(let s of n.faces)t.find(e=>e.face===s)||l.push(s);return l}function Kd(n,t){for(let l of n)l.first.bv=l.first.bvStart=l.first.bvEnd=void 0,l.first.setInclusion(t)}function $o(n,t,l,s,e,d){let i,c,o,X=s.length,a=!1;for(let u=0;u<X;u++){let r=s[u];r.face!==i&&(c=u,i=r.face);let Z=u,G=Pt(s,u,i),p;Z+G<X&&s[Z+G].face===i?p=Z+G:p=c;let m=Pt(s,p,i);o=null;for(let V=p;V<p+m;V++){let y=s[V];if(y.face===i&&e[y.id].face===e[r.id].face){o=y;break}}if(o===null)continue;let W=r.edge_after,L=o.edge_before;if(W.bv===j&&L.bv!=j){W.bv=L.bv;continue}if(W.bv!=j&&L.bv===j){L.bv=W.bv;continue}if(W.bv===j&&L.bv===j&&W!=L||W.bv===et&&L.bv===dt||W.bv===dt&&L.bv===et){let V=W.next;for(;V!=L;)V.bvStart=void 0,V.bvEnd=void 0,V.bv=void 0,V.setInclusion(t),V=V.next}if(W.bv===j&&L.bv===j&&W!=L){let V=W.next,y;for(;V!=L;){if(V.bv!=j){if(y===void 0)y=V.bv;else if(V.bv!=y)throw Q.UNRESOLVED_BOUNDARY_CONFLICT}V=V.next}y!=null&&(W.bv=y,L.bv=y);continue}if(W.bv===et&&L.bv===dt||W.bv===dt&&L.bv===et){let V=W;for(;V!=L;){if(V.bvStart===W.bv&&V.bvEnd===L.bv){let[y,S]=V.shape.distanceTo(t);if(y<10*b.DP_TOL){kt(V,S.ps,l);let K=l[l.length-1];if(K.is_vertex&md)K.edge_after=V,K.edge_before=V.prev,V.bvStart=j,V.bv=void 0,V.setInclusion(t);else if(K.is_vertex&pd)K.edge_after=V.next,V.bvEnd=j,V.bv=void 0,V.setInclusion(t);else{let g=t.addVertex(K.pt,V);K.edge_before=g,K.edge_after=g.next,g.setInclusion(t),g.next.bvStart=j,g.next.bvEnd=void 0,g.next.bv=void 0,g.next.setInclusion(t)}let T=t.findEdgeByPoint(S.pe);kt(T,S.pe,e);let Y=e[e.length-1];if(Y.is_vertex&md)Y.edge_after=T,Y.edge_before=T.prev;else if(Y.is_vertex&pd)Y.edge_after=T.next;else{let g=e.find(H=>H.edge_after===T),z=t.addVertex(Y.pt,T);Y.edge_before=z,Y.edge_after=z.next,g&&(g.edge_after=z),z.bvStart=void 0,z.bvEnd=j,z.bv=void 0,z.setInclusion(n),z.next.bvStart=j,z.next.bvEnd=void 0,z.next.bv=void 0,z.next.setInclusion(n)}sn(d),a=!0;break}}V=V.next}if(a)break;throw Q.UNRESOLVED_BOUNDARY_CONFLICT}}return a}function jl(n,t,l,s){if(!l)return;let e,d,i,c;for(let o=0;o<l.length;o++){if(i=l[o],i.face!==e&&(d=o,e=i.face),e.isEmpty())continue;let X=o,a=Pt(l,o,e),u;X+a<l.length&&l[X+a].face===i.face?u=X+a:u=d,c=l[u];let r=u,Z=Pt(l,r,e),G=i.edge_after,p=c.edge_before;if(G.bv===et&&p.bv===et&&t===Qn||G.bv===dt&&p.bv===dt&&t===en||(G.bv===dt||p.bv===dt)&&t===St&&!s||(G.bv===et||p.bv===et)&&t===St&&s||G.bv===j&&p.bv===j&&G.overlap&Oo&&s||G.bv===j&&p.bv===j&&G.overlap&Ao){n.removeChain(e,G,p);for(let m=X;m<X+a;m++)l[m].edge_after=void 0;for(let m=r;m<r+Z;m++)l[m].edge_before=void 0}o+=a-1}}function tX(n,t,l,s){for(let e of t.faces){for(let d of e)n.edges.add(d);s.find(d=>d.face===e)===void 0&&n.addFace(e.first,e.last)}}function nX(n,t,l){if(l.int_points1.length!==0)for(let s=0;s<l.int_points1.length;s++){let e=l.int_points1[s],d=l.int_points2[s];if(e.edge_before!==void 0&&e.edge_after===void 0&&d.edge_before===void 0&&d.edge_after!==void 0&&(e.edge_before.next=d.edge_after,d.edge_after.prev=e.edge_before,e.edge_after=d.edge_after,d.edge_before=e.edge_before),d.edge_before!==void 0&&d.edge_after===void 0&&e.edge_before===void 0&&e.edge_after!==void 0&&(d.edge_before.next=e.edge_after,e.edge_after.prev=d.edge_before,d.edge_after=e.edge_after,e.edge_before=d.edge_before),e.edge_before!==void 0&&e.edge_after===void 0)for(let i of l.int_points1_sorted)i!==e&&i.edge_before===void 0&&i.edge_after!==void 0&&i.pt.equalTo(e.pt)&&(e.edge_before.next=i.edge_after,i.edge_after.prev=e.edge_before,e.edge_after=i.edge_after,i.edge_before=e.edge_before);if(d.edge_before!==void 0&&d.edge_after===void 0)for(let i of l.int_points2_sorted)i!==d&&i.edge_before===void 0&&i.edge_after!==void 0&&i.pt.equalTo(d.pt)&&(d.edge_before.next=i.edge_after,i.edge_after.prev=d.edge_before,d.edge_after=i.edge_after,i.edge_before=d.edge_before)}}function El(n,t){for(let l of t)n.faces.delete(l.face),l.face=void 0,l.edge_before&&(l.edge_before.face=void 0),l.edge_after&&(l.edge_after.face=void 0)}function Ol(n,t,l){for(let s of t){if(s.edge_before===void 0||s.edge_after===void 0||s.face||s.edge_after.face||s.edge_before.face)continue;let e=s.edge_after,d=s.edge_before;try{Nl.testInfiniteLoop(e)}catch{throw Q.CANNOT_COMPLETE_BOOLEAN_OPERATION}let i=n.addFace(e,d);for(let c of t)c.edge_before&&c.edge_after&&c.edge_before.face===i&&c.edge_after.face===i&&(c.face=i);for(let c of l)c.edge_before&&c.edge_after&&c.edge_before.face===i&&c.edge_after.face===i&&(c.face=i)}}function Rd(n,t,l,s){for(let e of t){let d=e.first.bv;(l===Qn&&d===et||l===St&&d===et&&s||l===St&&d===dt&&!s||l===en&&d===dt)&&n.deleteFace(e)}}var cn=Object.freeze({__proto__:null,BOOLEAN_INTERSECT:en,BOOLEAN_SUBTRACT:St,BOOLEAN_UNION:Qn,calculateIntersections:yd,innerClip:Vd,intersect:Wd,outerClip:Ul,removeNotRelevantChains:jl,removeOldFaces:El,restoreFaces:Ol,subtract:wl,unify:Do});const lX=RegExp("T.F..FFF.|T.F...F.."),sX=RegExp("T........|.T.......|...T.....|....T...."),eX=RegExp("FT.......|F..T.....|F...T...."),dX=RegExp("T.F..F..."),iX=RegExp("T.F..F...|.TF..F...|..FT.F...|..F.TF...");class Bt{constructor(){this.m=new Array(9).fill(void 0)}get I2I(){return this.m[0]}set I2I(t){this.m[0]=t}get I2B(){return this.m[1]}set I2B(t){this.m[1]=t}get I2E(){return this.m[2]}set I2E(t){this.m[2]=t}get B2I(){return this.m[3]}set B2I(t){this.m[3]=t}get B2B(){return this.m[4]}set B2B(t){this.m[4]=t}get B2E(){return this.m[5]}set B2E(t){this.m[5]=t}get E2I(){return this.m[6]}set E2I(t){this.m[6]=t}get E2B(){return this.m[7]}set E2B(t){this.m[7]=t}get E2E(){return this.m[8]}set E2E(t){this.m[8]=t}toString(){return this.m.map(t=>t instanceof Array&&t.length>0?"T":t instanceof Array&&t.length===0?"F":"*").join("")}equal(){return lX.test(this.toString())}intersect(){return sX.test(this.toString())}touch(){return eX.test(this.toString())}inside(){return dX.test(this.toString())}covered(){return iX.test(this.toString())}}function bn(n,t){let l,s=new b.Ray(t),e=new b.Line(s.pt,s.norm);const d=new b.Box(s.box.xmin-b.DP_TOL,s.box.ymin-b.DP_TOL,s.box.xmax+b.DP_TOL,s.box.ymax+b.DP_TOL);if(n.box.not_intersect(d))return b.OUTSIDE;let i=n.edges.search(d);if(i.length===0)return b.OUTSIDE;for(let a of i)if(a.shape.contains(t))return b.BOUNDARY;let c=[...n.faces],o=[];for(let a of i)for(let u of s.intersect(a.shape)){if(u.equalTo(t))return b.BOUNDARY;o.push({pt:u,edge:a,face_index:c.indexOf(a.face)})}o.sort((a,u)=>td(a.pt.x,u.pt.x)?-1:$e(a.pt.x,u.pt.x)?1:a.face_index<u.face_index?-1:a.face_index>u.face_index?1:a.edge.arc_length<u.edge.arc_length?-1:a.edge.arc_length>u.edge.arc_length?1:0);let X=0;for(let a=0;a<o.length;a++){let u=o[a];if(u.pt.equalTo(u.edge.shape.start)){if(a>0&&u.pt.equalTo(o[a-1].pt)&&u.face_index===o[a-1].face_index&&u.edge.prev===o[a-1].edge)continue;let r=u.edge.prev;for(;Fl(r.length);)r=r.prev;let Z=r.shape.tangentInEnd(),G=u.pt.translate(Z),p=u.edge.shape.tangentInStart(),m=u.pt.translate(p),W=G.leftTo(e),L=m.leftTo(e);(W&&!L||!W&&L)&&X++}else if(u.pt.equalTo(u.edge.shape.end)){if(a>0&&u.pt.equalTo(o[a-1].pt)&&u.face_index===o[a-1].face_index&&u.edge.next===o[a-1].edge)continue;let r=u.edge.next;for(;Fl(r.length);)r=r.next;let Z=r.shape.tangentInStart(),G=u.pt.translate(Z),p=u.edge.shape.tangentInEnd(),m=u.pt.translate(p),W=G.leftTo(e),L=m.leftTo(e);(W&&!L||!W&&L)&&X++}else if(u.edge.shape instanceof b.Segment)X++;else{let r=u.edge.shape.box;Lt(u.pt.y,r.ymin)||Lt(u.pt.y,r.ymax)||X++}}return l=X%2===1?Hn:De,l}function cX(n,t){return vt(n,t).equal()}function Sd(n,t){return vt(n,t).intersect()}function bX(n,t){return vt(n,t).touch()}function oX(n,t){return!Sd(n,t)}function zd(n,t){return vt(n,t).inside()}function Md(n,t){return vt(n,t).covered()}function XX(n,t){return zd(t,n)}function Yd(n,t){return Md(t,n)}function vt(n,t){if(n instanceof b.Line&&t instanceof b.Line)return aX(n,t);if(n instanceof b.Line&&t instanceof b.Circle)return uX(n,t);if(n instanceof b.Line&&t instanceof b.Box)return hX(n,t);if(n instanceof b.Line&&t instanceof b.Polygon)return rX(n,t);if((n instanceof b.Segment||n instanceof b.Arc)&&t instanceof b.Polygon)return gd(n,t);if((n instanceof b.Segment||n instanceof b.Arc)&&(t instanceof b.Circle||t instanceof b.Box))return gd(n,new b.Polygon(t));if(n instanceof b.Polygon&&t instanceof b.Polygon)return Bn(n,t);if((n instanceof b.Circle||n instanceof b.Box)&&(t instanceof b.Circle||t instanceof b.Box))return Bn(new b.Polygon(n),new b.Polygon(t));if((n instanceof b.Circle||n instanceof b.Box)&&t instanceof b.Polygon)return Bn(new b.Polygon(n),t);if(n instanceof b.Polygon&&(t instanceof b.Circle||t instanceof b.Box))return Bn(n,new b.Polygon(t))}function aX(n,t){let l=new Bt,s=Nt(n,t);return s.length===0?n.contains(t.pt)&&t.contains(n.pt)?(l.I2I=[n],l.I2E=[],l.E2I=[]):(l.I2I=[],l.I2E=[n],l.E2I=[t]):(l.I2I=s,l.I2E=n.split(s),l.E2I=t.split(s)),l}function uX(n,t){let l=new Bt,s=Kt(n,t);if(s.length===0)l.I2I=[],l.I2B=[],l.I2E=[n],l.E2I=[t];else if(s.length===1)l.I2I=[],l.I2B=s,l.I2E=n.split(s),l.E2I=[t];else{let e=new Rt([n]),d=n.sortPoints(s);e.split(d);let i=e.toShapes();l.I2I=[i[1]],l.I2B=d,l.I2E=[i[0],i[2]],l.E2I=new b.Polygon([t.toArc()]).cutWithLine(n)}return l}function hX(n,t){let l=new Bt,s=Ht(n,t);if(s.length===0)l.I2I=[],l.I2B=[],l.I2E=[n],l.E2I=[t];else if(s.length===1)l.I2I=[],l.I2B=s,l.I2E=n.split(s),l.E2I=[t];else{let e=new Rt([n]),d=n.sortPoints(s);e.split(d);let i=e.toShapes();t.toSegments().some(c=>c.contains(s[0])&&c.contains(s[1]))?(l.I2I=[],l.I2B=[i[1]],l.I2E=[i[0],i[2]],l.E2I=[t]):(l.I2I=[i[1]],l.I2B=d,l.I2E=[i[0],i[2]],l.E2I=new b.Polygon(t.toSegments()).cutWithLine(n))}return l}function rX(n,t){let l=new Bt,s=ln(n,t),e=new Rt([n]),d=s.length>0?s.slice():n.sortPoints(s);return e.split(d),[...e].forEach(i=>i.setInclusion(t)),l.I2I=[...e].filter(i=>i.bv===b.INSIDE).map(i=>i.shape),l.I2B=[...e].slice(1).map(i=>i.bv===b.BOUNDARY?i.shape:i.shape.start),l.I2E=[...e].filter(i=>i.bv===b.OUTSIDE).map(i=>i.shape),l.E2I=t.cutWithLine(n),l}function gd(n,t){let l=new Bt,s=Qo(n,t),e=s.length>0?s.slice():n.sortPoints(s),d=new Rt([n]);d.split(e),[...d].forEach(i=>i.setInclusion(t)),l.I2I=[...d].filter(i=>i.bv===b.INSIDE).map(i=>i.shape),l.I2B=[...d].slice(1).map(i=>i.bv===b.BOUNDARY?i.shape:i.shape.start),l.I2E=[...d].filter(i=>i.bv===b.OUTSIDE).map(i=>i.shape),l.B2I=[],l.B2B=[],l.B2E=[];for(let i of[n.start,n.end])switch(bn(t,i)){case b.INSIDE:l.B2I.push(i);break;case b.BOUNDARY:l.B2B.push(i);break;case b.OUTSIDE:l.B2E.push(i);break}return l}function Bn(n,t){let l=new Bt,[s,e]=yd(n,t),d=Wd(n,t),i=wl(n,t),c=wl(t,n),[o,X]=Vd(n,t),a=Ul(n,t),u=Ul(t,n);return l.I2I=d.isEmpty()?[]:[d],l.I2B=X,l.I2E=i.isEmpty()?[]:[i],l.B2I=o,l.B2B=s,l.B2E=a,l.E2I=c.isEmpty()?[]:[c],l.E2B=u,l}var ZX=Object.freeze({__proto__:null,contain:XX,cover:Yd,covered:Md,disjoint:oX,equal:cX,inside:zd,intersect:Sd,relate:vt,touch:bX});class q{constructor(t=1,l=0,s=0,e=1,d=0,i=0){this.a=t,this.b=l,this.c=s,this.d=e,this.tx=d,this.ty=i}fromMatrix3x3(t){const[l,s,e]=t[0],[d,i,c]=t[1];return new q(l,d,s,i,e,c)}toMatrix3x3(){return[[this.a,this.c,this.tx],[this.b,this.d,this.ty],[0,0,1]]}clone(){return new q(this.a,this.b,this.c,this.d,this.tx,this.ty)}transform(t){return[t[0]*this.a+t[1]*this.c+this.tx,t[0]*this.b+t[1]*this.d+this.ty]}multiply(t){return new q(this.a*t.a+this.c*t.b,this.b*t.a+this.d*t.b,this.a*t.c+this.c*t.d,this.b*t.c+this.d*t.d,this.a*t.tx+this.c*t.ty+this.tx,this.b*t.tx+this.d*t.ty+this.ty)}translate(...t){let l,s;if(t.length==1&&!isNaN(t[0].x)&&!isNaN(t[0].y))l=t[0].x,s=t[0].y;else if(t.length===2&&typeof t[0]=="number"&&typeof t[1]=="number")l=t[0],s=t[1];else throw Q.ILLEGAL_PARAMETERS;return this.multiply(new q(1,0,0,1,l,s))}rotate(t,l=0,s=0){let e=Math.cos(t),d=Math.sin(t);return this.translate(l,s).multiply(new q(e,d,-d,e,0,0)).translate(-l,-s)}scale(t,l){return this.multiply(new q(t,0,0,l,0,0))}equalTo(t){return!(!b.Utils.EQ(this.tx,t.tx)||!b.Utils.EQ(this.ty,t.ty)||!b.Utils.EQ(this.a,t.a)||!b.Utils.EQ(this.b,t.b)||!b.Utils.EQ(this.c,t.c)||!b.Utils.EQ(this.d,t.d))}}b.Matrix=q;const GX=(...n)=>new b.Matrix(...n);b.matrix=GX;class mX{constructor(t,l){this.low=t,this.high=l}get max(){return this.clone()}less_than(t){return this.low<t.low||this.low===t.low&&this.high<t.high}equal_to(t){return this.low===t.low&&this.high===t.high}intersect(t){return!this.not_intersect(t)}not_intersect(t){return this.high<t.low||t.high<this.low}merge(t){const l=this.low===void 0?t.low:this.low<t.low?this.low:t.low,s=this.high===void 0?t.high:this.high>t.high?this.high:t.high,e=this.clone();return e.low=l,e.high=s,e}output(){return[this.low,this.high]}comparable_less_than(t,l){return t<l}}class Al extends mX{clone(){return new Al(this.low,this.high)}}const E=1,k=0;class Gt{constructor(t,l,s=null,e=null,d=null,i=k){if(this.left=s,this.right=e,this.parent=d,this.color=i,this.item={key:void 0,values:[]},l!==void 0&&this.item.values.push(l),t!==void 0)if(Array.isArray(t)){const[c,o]=t;if(!Number.isNaN(c)&&!Number.isNaN(o)){let X=c,a=o;X>a&&([X,a]=[a,X]),this.item.key=new Al(X,a)}}else this.item.key=t;this.max=this.item.key?this.item.key.max:void 0}isNil(){return this.item.key===void 0&&this.item.values.length===0&&this.left===null&&this.right===null&&this.color===k}requireKey(){if(!this.item.key)throw new Error("Node key is undefined (nil/sentinel). Operation is not applicable.");return this.item.key}less_than(t){const l=this.requireKey(),s=t.requireKey();return l.less_than(s)}_value_equal(t){const l=this.item.values[0],s=t.item.values[0];return l&&s&&l.equal_to?l.equal_to(s):l===s}equal_to(t){const l=this.requireKey(),s=t.requireKey();return l.equal_to(s)}intersect(t){const l=this.requireKey(),s=t.requireKey();return l.intersect(s)}copy_data(t){this.item.key=t.item.key,this.item.values=t.item.values.slice()}update_max(){this.max=this.item.key?this.item.key.max:void 0,this.right&&this.right.max&&(this.max=this.max?this.max.merge(this.right.max):this.right.max),this.left&&this.left.max&&(this.max=this.max?this.max.merge(this.left.max):this.left.max)}not_intersect_left_subtree(t){if(!this.left)return!0;const l=this.left.max?this.left.max.high:this.left.item.key.high,s=this.requireKey(),e=t.requireKey();return s.comparable_less_than(l,e.low)}not_intersect_right_subtree(t){if(!this.right)return!0;const l=this.right.max?this.right.max.low:this.right.item.key.low,s=this.requireKey(),e=t.requireKey();return s.comparable_less_than(e.high,l)}}class on{constructor(){this.root=null,this.nil_node=new Gt}get size(){let t=0;return this.tree_walk(this.root,l=>t+=l.item.values.length),t}get keys(){const t=[];return this.tree_walk(this.root,l=>t.push(l.item.key.output())),t}get values(){const t=[];return this.tree_walk(this.root,l=>{for(const s of l.item.values)t.push(s)}),t}get items(){const t=[];return this.tree_walk(this.root,l=>{const s=l.item.key.output();for(const e of l.item.values)t.push({key:s,value:e})}),t}isEmpty(){return this.root==null||this.root===this.nil_node}clear(){this.root=null}insert(t,l=t){if(t===void 0)return;const s=this.tree_search(this.root,new Gt(t));if(s)return s.item.values.push(l),s;const e=new Gt(t,l,this.nil_node,this.nil_node,null,E);return this.tree_insert(e),this.recalc_max(e),e}exist(t,l=t){const s=this.tree_search(this.root,new Gt(t));return s?arguments.length<2||l===t?!0:s.item.values.some(e=>e&&e.equal_to?e.equal_to(l):e===l):!1}remove(t,l=t){const s=this.tree_search(this.root,new Gt(t));if(!s)return;if(arguments.length<2)return this.tree_delete(s),s;const e=s.item.values.findIndex(d=>d&&d.equal_to?d.equal_to(l):d===l);if(e>=0)return s.item.values.splice(e,1),s.item.values.length===0&&this.tree_delete(s),s}search(t,l=(s,e)=>s===e?e.output():s){const s=new Gt(t),e=[];this.tree_search_interval(this.root,s,e);const d=[];for(const i of e)for(const c of i.item.values)d.push(l(c,i.item.key));return d}intersect_any(t){const l=new Gt(t);return this.tree_find_any_interval(this.root,l)}forEach(t){this.tree_walk(this.root,l=>{for(const s of l.item.values)t(l.item.key,s)})}map(t){const l=new on;return this.tree_walk(this.root,s=>{for(const e of s.item.values)l.insert(s.item.key,t(e,s.item.key))}),l}*iterate(t,l=(s,e)=>s===e?e.output():s){let s=null;for(t?s=this.tree_search_nearest_forward(this.root,new Gt(t)):this.root&&(s=this.local_minimum(this.root));s;){for(const e of s.item.values)yield l(e,s.item.key);s=this.tree_successor(s)}}recalc_max(t){let l=t;for(;l.parent!=null;)l.parent.update_max(),l=l.parent}tree_insert(t){let l=this.root,s=null;if(this.root==null||this.root===this.nil_node)this.root=t;else{for(;l!==this.nil_node;)s=l,t.less_than(l)?l=l.left:l=l.right;t.parent=s,t.less_than(s)?s.left=t:s.right=t}this.insert_fixup(t)}insert_fixup(t){let l,s;for(l=t;l!==this.root&&l.parent.color===E;)l.parent===l.parent.parent.left?(s=l.parent.parent.right,s.color===E?(l.parent.color=k,s.color=k,l.parent.parent.color=E,l=l.parent.parent):(l===l.parent.right&&(l=l.parent,this.rotate_left(l)),l.parent.color=k,l.parent.parent.color=E,this.rotate_right(l.parent.parent))):(s=l.parent.parent.left,s.color===E?(l.parent.color=k,s.color=k,l.parent.parent.color=E,l=l.parent.parent):(l===l.parent.left&&(l=l.parent,this.rotate_right(l)),l.parent.color=k,l.parent.parent.color=E,this.rotate_left(l.parent.parent)));this.root.color=k}tree_delete(t){let l,s;t.left===this.nil_node||t.right===this.nil_node?l=t:l=this.tree_successor(t),l.left!==this.nil_node?s=l.left:s=l.right,s.parent=l.parent,l===this.root?this.root=s:(l===l.parent.left?l.parent.left=s:l.parent.right=s,l.parent.update_max()),this.recalc_max(s),l!==t&&(t.copy_data(l),t.update_max(),this.recalc_max(t)),l.color===k&&this.delete_fixup(s)}delete_fixup(t){let l=t,s;for(;l!==this.root&&l.parent!=null&&l.color===k;)l===l.parent.left?(s=l.parent.right,s.color===E&&(s.color=k,l.parent.color=E,this.rotate_left(l.parent),s=l.parent.right),s.left.color===k&&s.right.color===k?(s.color=E,l=l.parent):(s.right.color===k&&(s.color=E,s.left.color=k,this.rotate_right(s),s=l.parent.right),s.color=l.parent.color,l.parent.color=k,s.right.color=k,this.rotate_left(l.parent),l=this.root)):(s=l.parent.left,s.color===E&&(s.color=k,l.parent.color=E,this.rotate_right(l.parent),s=l.parent.left),s.left.color===k&&s.right.color===k?(s.color=E,l=l.parent):(s.left.color===k&&(s.color=E,s.right.color=k,this.rotate_left(s),s=l.parent.left),s.color=l.parent.color,l.parent.color=k,s.left.color=k,this.rotate_right(l.parent),l=this.root));l.color=k}tree_search(t,l){if(!(t==null||t===this.nil_node))return l.equal_to(t)?t:l.less_than(t)?this.tree_search(t.left,l):this.tree_search(t.right,l)}tree_search_nearest_forward(t,l){let s=null,e=t;for(;e&&e!==this.nil_node;)e.less_than(l)?e.intersect(l)?(s=e,e=e.left):e=e.right:((!s||e.less_than(s))&&(s=e),e=e.left);return s||null}tree_search_interval(t,l,s){t!=null&&t!==this.nil_node&&(t.left!==this.nil_node&&!t.not_intersect_left_subtree(l)&&this.tree_search_interval(t.left,l,s),t.intersect(l)&&s.push(t),t.right!==this.nil_node&&!t.not_intersect_right_subtree(l)&&this.tree_search_interval(t.right,l,s))}tree_find_any_interval(t,l){let s=!1;return t!=null&&t!==this.nil_node&&(t.left!==this.nil_node&&!t.not_intersect_left_subtree(l)&&(s=this.tree_find_any_interval(t.left,l)),s||(s=t.intersect(l)),!s&&t.right!==this.nil_node&&!t.not_intersect_right_subtree(l)&&(s=this.tree_find_any_interval(t.right,l))),s}local_minimum(t){let l=t;for(;l.left!=null&&l.left!==this.nil_node;)l=l.left;return l}local_maximum(t){let l=t;for(;l.right!=null&&l.right!==this.nil_node;)l=l.right;return l}tree_successor(t){let l,s,e;if(t.right!==this.nil_node)l=this.local_minimum(t.right);else{for(s=t,e=t.parent;e!=null&&e.right===s;)s=e,e=e.parent;l=e}return l}rotate_left(t){const l=t.right;t.right=l.left,l.left!==this.nil_node&&(l.left.parent=t),l.parent=t.parent,t===this.root?this.root=l:t===t.parent.left?t.parent.left=l:t.parent.right=l,l.left=t,t.parent=l,t!==null&&t!==this.nil_node&&t.update_max(),l!=null&&l!==this.nil_node&&l.update_max()}rotate_right(t){const l=t.left;t.left=l.right,l.right!==this.nil_node&&(l.right.parent=t),l.parent=t.parent,t===this.root?this.root=l:t===t.parent.left?t.parent.left=l:t.parent.right=l,l.right=t,t.parent=l,t!==null&&t!==this.nil_node&&t.update_max(),l!=null&&l!==this.nil_node&&l.update_max()}tree_walk(t,l){t!=null&&t!==this.nil_node&&(this.tree_walk(t.left,l),l(t),this.tree_walk(t.right,l))}testRedBlackProperty(){let t=!0;return this.tree_walk(this.root,function(l){l.color===E&&(l.left.color===k&&l.right.color===k||(t=!1))}),t}testBlackHeightProperty(t){let l=0,s=0,e=0;if(t.color===k&&l++,t.left!==this.nil_node?s=this.testBlackHeightProperty(t.left):s=1,t.right!==this.nil_node?e=this.testBlackHeightProperty(t.right):e=1,s!==e)throw new Error("Red-black height property violated");return l+=s,l}}class pX extends Set{constructor(t){super(t),this.index=new on,this.forEach(l=>this.index.insert(l))}add(t){let l=this.size;const{key:s,value:e}=t,d=s||t.box,i=e||t;return super.add(i),this.size>l&&this.index.insert(d,i),this}delete(t){const{key:l,value:s}=t,e=l||t.box,d=s||t;let i=super.delete(d);return i&&this.index.remove(e,d),i}clear(){super.clear(),this.index=new on}search(t){return this.index.search(t)}hit(t){let l=new b.Box(t.x-1,t.y-1,t.x+1,t.y+1);return this.index.search(l).filter(e=>t.on(e))}svg(){return[...this].reduce((l,s)=>l+s.svg(),"")}}b.PlanarSet=pX;class mt{get name(){throw Q.CANNOT_INVOKE_ABSTRACT_METHOD}get box(){throw Q.CANNOT_INVOKE_ABSTRACT_METHOD}clone(){throw Q.CANNOT_INVOKE_ABSTRACT_METHOD}translate(...t){return this.transform(new q().translate(...t))}rotate(t,l=new b.Point){return this.transform(new q().rotate(t,l.x,l.y))}scale(t,l){return this.transform(new q().scale(t,l))}transform(...t){throw Q.CANNOT_INVOKE_ABSTRACT_METHOD}toJSON(){return Object.assign({},this,{name:this.name})}svg(t={}){throw Q.CANNOT_INVOKE_ABSTRACT_METHOD}}let vn=class Ni extends mt{constructor(...t){if(super(),this.x=0,this.y=0,t.length!==0){if(t.length===1&&t[0]instanceof Array&&t[0].length===2){let l=t[0];if(typeof l[0]=="number"&&typeof l[1]=="number"){this.x=l[0],this.y=l[1];return}}if(t.length===1&&t[0]instanceof Object&&t[0].name==="point"){let{x:l,y:s}=t[0];this.x=l,this.y=s;return}if(t.length===2&&typeof t[0]=="number"&&typeof t[1]=="number"){this.x=t[0],this.y=t[1];return}throw Q.ILLEGAL_PARAMETERS}}get box(){return new b.Box(this.x,this.y,this.x,this.y)}clone(){return new b.Point(this.x,this.y)}get vertices(){return[this.clone()]}equalTo(t){return b.Utils.EQ(this.x,t.x)&&b.Utils.EQ(this.y,t.y)}lessThan(t){return!!(b.Utils.LT(this.y,t.y)||b.Utils.EQ(this.y,t.y)&&b.Utils.LT(this.x,t.x))}transform(t){return new b.Point(t.transform([this.x,this.y]))}projectionOn(t){if(this.equalTo(t.pt))return this.clone();let l=new b.Vector(this,t.pt);if(b.Utils.EQ_0(l.cross(t.norm)))return t.pt.clone();let s=l.dot(t.norm),e=t.norm.multiply(s);return this.translate(e)}leftTo(t){let l=new b.Vector(t.pt,this);return b.Utils.GT(l.dot(t.norm),0)}distanceTo(t){if(t instanceof Ni){let l=t.x-this.x,s=t.y-this.y;return[Math.sqrt(l*l+s*s),new b.Segment(this,t)]}if(t instanceof b.Line)return b.Distance.point2line(this,t);if(t instanceof b.Circle)return b.Distance.point2circle(this,t);if(t instanceof b.Segment)return b.Distance.point2segment(this,t);if(t instanceof b.Arc)return b.Distance.point2arc(this,t);if(t instanceof b.Polygon)return b.Distance.point2polygon(this,t);if(t instanceof b.PlanarSet)return b.Distance.shape2planarSet(this,t);if(t instanceof b.Multiline)return b.Distance.shape2multiline(this,t)}on(t){if(t instanceof b.Point)return this.equalTo(t);if(t.contains&&t.contains instanceof Function)return t.contains(this);throw b.Errors.UNSUPPORTED_SHAPE_TYPE}get name(){return"point"}svg(t={}){const l=t.r??3;return`
|
|
14
14
|
<circle cx="${this.x}" cy="${this.y}" r="${l}"
|
|
15
|
-
${
|
|
16
|
-
<line x1="${this.start.x}" y1="${this.start.y}" x2="${this.end.x}" y2="${this.end.y}" ${
|
|
15
|
+
${xt({fill:"red",...t})} />`}};b.Point=vn;const WX=(...n)=>new b.Point(...n);b.point=WX;let VX=class extends mt{constructor(...t){if(super(),this.x=0,this.y=0,t.length!==0){if(t.length===1&&t[0]instanceof Array&&t[0].length===2){let l=t[0];if(typeof l[0]=="number"&&typeof l[1]=="number"){this.x=l[0],this.y=l[1];return}}if(t.length===1&&t[0]instanceof Object&&t[0].name==="vector"){let{x:l,y:s}=t[0];this.x=l,this.y=s;return}if(t.length===1&&t[0]instanceof Object&&t[0].name==="segment"){let{start:l,end:s}=t[0];this.x=s.x-l.x,this.y=s.y-l.y;return}if(t.length===2){let l=t[0],s=t[1];if(typeof l=="number"&&typeof s=="number"){this.x=l,this.y=s;return}if(l instanceof b.Point&&s instanceof b.Point){this.x=s.x-l.x,this.y=s.y-l.y;return}}throw Q.ILLEGAL_PARAMETERS}}clone(){return new b.Vector(this.x,this.y)}get slope(){let t=Math.atan2(this.y,this.x);return t<0&&(t=2*Math.PI+t),t}get length(){return Math.sqrt(this.dot(this))}isZeroLength(){return b.Utils.EQ_0(this.length)}equalTo(t){return b.Utils.EQ(this.x,t.x)&&b.Utils.EQ(this.y,t.y)}multiply(t){return new b.Vector(t*this.x,t*this.y)}dot(t){return this.x*t.x+this.y*t.y}cross(t){return this.x*t.y-this.y*t.x}normalize(){if(this.isZeroLength())throw Q.ZERO_DIVISION;return new b.Vector(this.x/this.length,this.y/this.length)}rotate(t,l=new b.Point){if(l.x===0&&l.y===0)return this.transform(new q().rotate(t));throw Q.OPERATION_IS_NOT_SUPPORTED}transform(t){return new b.Vector(t.transform([this.x,this.y]))}rotate90CCW(){return new b.Vector(-this.y,this.x)}rotate90CW(){return new b.Vector(this.y,-this.x)}invert(){return new b.Vector(-this.x,-this.y)}add(t){return new b.Vector(this.x+t.x,this.y+t.y)}subtract(t){return new b.Vector(this.x-t.x,this.y-t.y)}angleTo(t){let l=this.normalize(),s=t.normalize(),e=Math.atan2(l.cross(s),l.dot(s));return e<0&&(e+=2*Math.PI),e}projectionOn(t){let l=t.normalize(),s=this.dot(l);return l.multiply(s)}get name(){return"vector"}};b.Vector=VX;const Td=(...n)=>new b.Vector(...n);b.vector=Td;let yX=class ms extends mt{constructor(...t){if(super(),this.ps=new b.Point,this.pe=new b.Point,t.length!==0){if(t.length===1&&t[0]instanceof Array&&t[0].length===4){let l=t[0];this.ps=new b.Point(l[0],l[1]),this.pe=new b.Point(l[2],l[3]);return}if(t.length===1&&t[0]instanceof Object&&t[0].name==="segment"){let{ps:l,pe:s}=t[0];this.ps=new b.Point(l.x,l.y),this.pe=new b.Point(s.x,s.y);return}if(t.length===1&&t[0]instanceof b.Point){this.ps=t[0].clone();return}if(t.length===2&&t[0]instanceof b.Point&&t[1]instanceof b.Point){this.ps=t[0].clone(),this.pe=t[1].clone();return}if(t.length===4){this.ps=new b.Point(t[0],t[1]),this.pe=new b.Point(t[2],t[3]);return}throw Q.ILLEGAL_PARAMETERS}}clone(){return new b.Segment(this.start,this.end)}get start(){return this.ps}get end(){return this.pe}get vertices(){return[this.ps.clone(),this.pe.clone()]}get length(){return this.start.distanceTo(this.end)[0]}get slope(){return new b.Vector(this.start,this.end).slope}get box(){return new b.Box(Math.min(this.start.x,this.end.x),Math.min(this.start.y,this.end.y),Math.max(this.start.x,this.end.x),Math.max(this.start.y,this.end.y))}equalTo(t){return this.ps.equalTo(t.ps)&&this.pe.equalTo(t.pe)}contains(t){return b.Utils.EQ_0(this.distanceToPoint(t))}intersect(t){if(t instanceof b.Point)return this.contains(t)?[t]:[];if(t instanceof b.Line)return nn(this,t);if(t instanceof b.Ray)return kl(t,this);if(t instanceof b.Segment)return kn(this,t);if(t instanceof b.Circle)return Pn(this,t);if(t instanceof b.Box)return Fo(this,t);if(t instanceof b.Arc)return Jt(this,t);if(t instanceof b.Polygon)return Jl(this,t);if(t instanceof b.Multiline)return It(this,t)}distanceTo(t){if(t instanceof b.Point){let[l,s]=b.Distance.point2segment(t,this);return s=s.reverse(),[l,s]}if(t instanceof b.Circle){let[l,s]=b.Distance.segment2circle(this,t);return[l,s]}if(t instanceof b.Line){let[l,s]=b.Distance.segment2line(this,t);return[l,s]}if(t instanceof b.Segment){let[l,s]=b.Distance.segment2segment(this,t);return[l,s]}if(t instanceof b.Arc){let[l,s]=b.Distance.segment2arc(this,t);return[l,s]}if(t instanceof b.Polygon){let[l,s]=b.Distance.shape2polygon(this,t);return[l,s]}if(t instanceof b.PlanarSet){let[l,s]=b.Distance.shape2planarSet(this,t);return[l,s]}if(t instanceof b.Multiline)return b.Distance.shape2multiline(this,t)}tangentInStart(){return new b.Vector(this.start,this.end).normalize()}tangentInEnd(){return new b.Vector(this.end,this.start).normalize()}reverse(){return new ms(this.end,this.start)}split(t){return this.start.equalTo(t)?[null,this.clone()]:this.end.equalTo(t)?[this.clone(),null]:[new b.Segment(this.start,t),new b.Segment(t,this.end)]}middle(){return new b.Point((this.start.x+this.end.x)/2,(this.start.y+this.end.y)/2)}pointAtLength(t){if(t>this.length||t<0)return null;if(t==0)return this.start;if(t==this.length)return this.end;let l=t/this.length;return new b.Point((this.end.x-this.start.x)*l+this.start.x,(this.end.y-this.start.y)*l+this.start.y)}distanceToPoint(t){let[l,...s]=b.Distance.point2segment(t,this);return l}definiteIntegral(t=0){let l=this.end.x-this.start.x,s=this.start.y-t,e=this.end.y-t;return l*(s+e)/2}transform(t=new b.Matrix){return new ms(this.ps.transform(t),this.pe.transform(t))}isZeroLength(){return this.ps.equalTo(this.pe)}sortPoints(t){return new b.Line(this.start,this.end).sortPoints(t)}get name(){return"segment"}svg(t={}){return`
|
|
16
|
+
<line x1="${this.start.x}" y1="${this.start.y}" x2="${this.end.x}" y2="${this.end.y}" ${xt(t)} />`}};b.Segment=yX;const LX=(...n)=>new b.Segment(...n);b.segment=LX;let{vector:Xn}=b,xX=class Hi extends mt{constructor(...t){if(super(),this.pt=new b.Point,this.norm=new b.Vector(0,1),t.length!==0){if(t.length===1&&t[0]instanceof Object&&t[0].name==="line"){let{pt:l,norm:s}=t[0];this.pt=new b.Point(l),this.norm=new b.Vector(s);return}if(t.length===2){let l=t[0],s=t[1];if(l instanceof b.Point&&s instanceof b.Point){this.pt=l,this.norm=Hi.points2norm(l,s),this.norm.dot(Xn(this.pt.x,this.pt.y))>=0&&this.norm.invert();return}if(l instanceof b.Point&&s instanceof b.Vector){if(b.Utils.EQ_0(s.x)&&b.Utils.EQ_0(s.y))throw Q.ILLEGAL_PARAMETERS;this.pt=l.clone(),this.norm=s.clone(),this.norm=this.norm.normalize(),this.norm.dot(Xn(this.pt.x,this.pt.y))>=0&&this.norm.invert();return}if(l instanceof b.Vector&&s instanceof b.Point){if(b.Utils.EQ_0(l.x)&&b.Utils.EQ_0(l.y))throw Q.ILLEGAL_PARAMETERS;this.pt=s.clone(),this.norm=l.clone(),this.norm=this.norm.normalize(),this.norm.dot(Xn(this.pt.x,this.pt.y))>=0&&this.norm.invert();return}}throw Q.ILLEGAL_PARAMETERS}}clone(){return new b.Line(this.pt,this.norm)}get start(){}get end(){}get length(){return Number.POSITIVE_INFINITY}get box(){return new b.Box(Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY,Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY)}get middle(){}get slope(){return new b.Vector(this.norm.y,-this.norm.x).slope}get standard(){let t=this.norm.x,l=this.norm.y,s=this.norm.dot(Xn(this.pt.x,this.pt.y));return[t,l,s]}parallelTo(t){return b.Utils.EQ_0(this.norm.cross(t.norm))}incidentTo(t){return this.parallelTo(t)&&this.pt.on(t)}contains(t){if(this.pt.equalTo(t))return!0;let l=new b.Vector(this.pt,t);return b.Utils.EQ_0(this.norm.dot(l))}coord(t){return Xn(t.x,t.y).cross(this.norm)}intersect(t){if(t instanceof b.Point)return this.contains(t)?[t]:[];if(t instanceof b.Line)return Nt(this,t);if(t instanceof b.Ray)return hd(t,this);if(t instanceof b.Circle)return Kt(this,t);if(t instanceof b.Box)return Ht(this,t);if(t instanceof b.Segment)return nn(t,this);if(t instanceof b.Arc)return In(this,t);if(t instanceof b.Polygon)return ln(this,t);if(t instanceof b.Multiline)return It(this,t)}distanceTo(t){if(t instanceof b.Point){let[l,s]=b.Distance.point2line(t,this);return s=s.reverse(),[l,s]}if(t instanceof b.Circle){let[l,s]=b.Distance.circle2line(t,this);return s=s.reverse(),[l,s]}if(t instanceof b.Segment){let[l,s]=b.Distance.segment2line(t,this);return[l,s.reverse()]}if(t instanceof b.Arc){let[l,s]=b.Distance.arc2line(t,this);return[l,s.reverse()]}if(t instanceof b.Polygon){let[l,s]=b.Distance.shape2polygon(this,t);return[l,s]}}split(t){if(t instanceof b.Point)return[new b.Ray(t,this.norm),new b.Ray(t,this.norm)];{let l=new b.Multiline([this]),s=this.sortPoints(t);return l.split(s),l.toShapes()}}rotate(t,l=new b.Point){return new b.Line(this.pt.rotate(t,l),this.norm.rotate(t))}transform(t){return new b.Line(this.pt.transform(t),this.norm.clone())}sortPoints(t){return t.slice().sort((l,s)=>this.coord(l)<this.coord(s)?-1:this.coord(l)>this.coord(s)?1:0)}get name(){return"line"}svg(t,l={}){let s=Ht(this,t);if(s.length===0)return"";let e=s[0],d=s.length===2?s[1]:s.find(c=>!c.equalTo(e));return d===void 0&&(d=e),new b.Segment(e,d).svg(l)}static points2norm(t,l){if(t.equalTo(l))throw Q.ILLEGAL_PARAMETERS;return new b.Vector(t,l).normalize().rotate90CCW()}};b.Line=xX;const KX=(...n)=>new b.Line(...n);b.line=KX;let RX=class extends mt{constructor(...t){if(super(),this.pc=new b.Point,this.r=1,t.length===1&&t[0]instanceof Object&&t[0].name==="circle"){let{pc:l,r:s}=t[0];this.pc=new b.Point(l),this.r=s}else{let[l,s]=[...t];l&&l instanceof b.Point&&(this.pc=l.clone()),s!==void 0&&(this.r=s)}}clone(){return new b.Circle(this.pc.clone(),this.r)}get center(){return this.pc}get box(){return new b.Box(this.pc.x-this.r,this.pc.y-this.r,this.pc.x+this.r,this.pc.y+this.r)}contains(t){if(t instanceof b.Point)return b.Utils.LE(t.distanceTo(this.center)[0],this.r);if(t instanceof b.Segment)return b.Utils.LE(t.start.distanceTo(this.center)[0],this.r)&&b.Utils.LE(t.end.distanceTo(this.center)[0],this.r);if(t instanceof b.Arc)return this.intersect(t).length===0&&b.Utils.LE(t.start.distanceTo(this.center)[0],this.r)&&b.Utils.LE(t.end.distanceTo(this.center)[0],this.r);if(t instanceof b.Circle)return this.intersect(t).length===0&&b.Utils.LE(t.r,this.r)&&b.Utils.LE(t.center.distanceTo(this.center)[0],this.r)}toArc(t=!0){return new b.Arc(this.center,this.r,Math.PI,-Math.PI,t)}scale(t,l){if(t!==l||!(this.pc.x===0&&this.pc.y===0))throw Q.OPERATION_IS_NOT_SUPPORTED;return new b.Circle(this.pc,this.r*t)}transform(t=new b.Matrix){return new b.Circle(this.pc.transform(t),this.r)}intersect(t){if(t instanceof b.Point)return this.contains(t)?[t]:[];if(t instanceof b.Line)return Kt(t,this);if(t instanceof b.Ray)return ud(t,this);if(t instanceof b.Segment)return Pn(t,this);if(t instanceof b.Circle)return sd(t,this);if(t instanceof b.Box)return No(this,t);if(t instanceof b.Arc)return Hl(t,this);if(t instanceof b.Polygon)return bd(this,t);if(t instanceof b.Multiline)return It(this,t)}distanceTo(t){if(t instanceof b.Point){let[l,s]=b.Distance.point2circle(t,this);return s=s.reverse(),[l,s]}if(t instanceof b.Circle){let[l,s]=b.Distance.circle2circle(this,t);return[l,s]}if(t instanceof b.Line){let[l,s]=b.Distance.circle2line(this,t);return[l,s]}if(t instanceof b.Segment){let[l,s]=b.Distance.segment2circle(t,this);return s=s.reverse(),[l,s]}if(t instanceof b.Arc){let[l,s]=b.Distance.arc2circle(t,this);return s=s.reverse(),[l,s]}if(t instanceof b.Polygon){let[l,s]=b.Distance.shape2polygon(this,t);return[l,s]}if(t instanceof b.PlanarSet){let[l,s]=b.Distance.shape2planarSet(this,t);return[l,s]}if(t instanceof b.Multiline){let[l,s]=b.Distance.shape2multiline(this,t);return[l,s]}}get name(){return"circle"}svg(t={}){return`
|
|
17
17
|
<circle cx="${this.pc.x}" cy="${this.pc.y}" r="${this.r}"
|
|
18
|
-
${
|
|
18
|
+
${xt({fill:"none",...t})} />`}};b.Circle=RX;const SX=(...n)=>new b.Circle(...n);b.circle=SX;class zX extends mt{constructor(...t){if(super(),this.pc=new b.Point,this.r=1,this.startAngle=0,this.endAngle=2*Math.PI,this.counterClockwise=!0,t.length!==0)if(t.length===1&&t[0]instanceof Object&&t[0].name==="arc"){let{pc:l,r:s,startAngle:e,endAngle:d,counterClockwise:i}=t[0];this.pc=new b.Point(l.x,l.y),this.r=s,this.startAngle=e,this.endAngle=d,this.counterClockwise=i}else{let[l,s,e,d,i]=[...t];l&&l instanceof b.Point&&(this.pc=l.clone()),s!==void 0&&(this.r=s),e!==void 0&&(this.startAngle=e),d!==void 0&&(this.endAngle=d),i!==void 0&&(this.counterClockwise=i)}}clone(){return new b.Arc(this.pc.clone(),this.r,this.startAngle,this.endAngle,this.counterClockwise)}get sweep(){let t=this.startAngle,l=this.endAngle;if(b.Utils.EQ(Math.abs(t-l),b.PIx2))return b.PIx2;Math.abs(t)>b.PIx2&&(t-=Math.trunc(t/b.PIx2)*b.PIx2),t<0&&(t+=b.PIx2),Math.abs(l)>b.PIx2&&(l-=Math.trunc(l/b.PIx2)*b.PIx2),l<0&&(l+=b.PIx2);let s=this.counterClockwise?l-t:t-l;return s<0&&(s+=b.PIx2),s}get start(){return new b.Point(this.pc.x+this.r,this.pc.y).rotate(this.startAngle,this.pc)}get end(){return new b.Point(this.pc.x+this.r,this.pc.y).rotate(this.endAngle,this.pc)}get center(){return this.pc.clone()}get vertices(){return[this.start.clone(),this.end.clone()]}get length(){return Math.abs(this.sweep*this.r)}get box(){let l=this.breakToFunctional().reduce((s,e)=>s.merge(e.start.box),new b.Box);return l=l.merge(this.end.box),l}contains(t){if(!b.Utils.EQ(this.pc.distanceTo(t)[0],this.r))return!1;if(t.equalTo(this.start))return!0;let l=new b.Vector(this.pc,t).slope,s=new b.Arc(this.pc,this.r,this.startAngle,l,this.counterClockwise);return b.Utils.LE(s.length,this.length)}split(t){if(this.start.equalTo(t))return[null,this.clone()];if(this.end.equalTo(t))return[this.clone(),null];let l=new b.Vector(this.pc,t).slope;return[new b.Arc(this.pc,this.r,this.startAngle,l,this.counterClockwise),new b.Arc(this.pc,this.r,l,this.endAngle,this.counterClockwise)]}middle(){let t=this.counterClockwise?this.startAngle+this.sweep/2:this.startAngle-this.sweep/2;return new b.Arc(this.pc,this.r,this.startAngle,t,this.counterClockwise).end}pointAtLength(t){if(t>this.length||t<0)return null;if(t===0)return this.start;if(t===this.length)return this.end;let l=t/this.length,s=this.counterClockwise?this.startAngle+this.sweep*l:this.startAngle-this.sweep*l;return new b.Arc(this.pc,this.r,this.startAngle,s,this.counterClockwise).end}chordHeight(){return(1-Math.cos(Math.abs(this.sweep/2)))*this.r}intersect(t){if(t instanceof b.Point)return this.contains(t)?[t]:[];if(t instanceof b.Line)return In(t,this);if(t instanceof b.Ray)return Pl(t,this);if(t instanceof b.Circle)return Hl(this,t);if(t instanceof b.Segment)return Jt(t,this);if(t instanceof b.Box)return Ho(this,t);if(t instanceof b.Arc)return ed(this,t);if(t instanceof b.Polygon)return Il(this,t);if(t instanceof b.Multiline)return It(this,t)}distanceTo(t){if(t instanceof b.Point){let[l,s]=b.Distance.point2arc(t,this);return s=s.reverse(),[l,s]}if(t instanceof b.Circle){let[l,s]=b.Distance.arc2circle(this,t);return[l,s]}if(t instanceof b.Line){let[l,s]=b.Distance.arc2line(this,t);return[l,s]}if(t instanceof b.Segment){let[l,s]=b.Distance.segment2arc(t,this);return s=s.reverse(),[l,s]}if(t instanceof b.Arc){let[l,s]=b.Distance.arc2arc(this,t);return[l,s]}if(t instanceof b.Polygon){let[l,s]=b.Distance.shape2polygon(this,t);return[l,s]}if(t instanceof b.PlanarSet){let[l,s]=b.Distance.shape2planarSet(this,t);return[l,s]}if(t instanceof b.Multiline)return b.Distance.shape2multiline(this,t)}breakToFunctional(){let t=[],l=[0,Math.PI/2,Math.PI,3*Math.PI/2],s=this.startAngle,e=this.endAngle;b.Utils.EQ(Math.abs(s-e),b.PIx2)&&(e=s),Math.abs(s)>b.PIx2&&(s-=Math.trunc(s/b.PIx2)*b.PIx2),s<0&&(s+=b.PIx2),Math.abs(e)>b.PIx2&&(e-=Math.trunc(e/b.PIx2)*b.PIx2),e<0&&(e+=b.PIx2);let d=s,i,c,o;this.counterClockwise?(c=Math.ceil(s/(Math.PI/2))%4,o=1):(c=Math.floor(s/(Math.PI/2))%4,o=-1);for(let X=0,a=c;X<4;X++,a=(a+o+4)%4){if(i=l[a],i===d)continue;let u=this.counterClockwise?i-s:s-i;if(u<0&&(u+=b.PIx2),u>this.sweep)break;t.push(new b.Arc(this.pc,this.r,d,i,this.counterClockwise)),d=i}return t.length===0?(t.push(this),t):(i=e,d!==i&&t.push(new b.Arc(this.pc,this.r,d,i,this.counterClockwise)),t)}tangentInStart(){let t=new b.Vector(this.pc,this.start),l=this.counterClockwise?Math.PI/2:-Math.PI/2;return t.rotate(l).normalize()}tangentInEnd(){let t=new b.Vector(this.pc,this.end),l=this.counterClockwise?-Math.PI/2:Math.PI/2;return t.rotate(l).normalize()}reverse(){return new b.Arc(this.pc,this.r,this.endAngle,this.startAngle,!this.counterClockwise)}transform(t=new b.Matrix){let l=this.start.transform(t),s=this.end.transform(t),e=this.pc.transform(t),d=this.counterClockwise;return t.a*t.d<0&&(d=!d),b.Arc.arcSE(e,l,s,d)}static arcSE(t,l,s,e){let{vector:d}=b,i=d(t,l).slope,c=d(t,s).slope;b.Utils.EQ(i,c)&&(c+=2*Math.PI,e=!0);let o=d(t,l).length;return new b.Arc(t,o,i,c,e)}definiteIntegral(t=0){return this.breakToFunctional().reduce((e,d)=>e+d.circularSegmentDefiniteIntegral(t),0)}circularSegmentDefiniteIntegral(t){let s=new b.Segment(this.start,this.end).definiteIntegral(t),e=b.Utils.EQ(this.sweep,b.PIx2)?0:this.circularSegmentArea();return this.counterClockwise?s-e:s+e}circularSegmentArea(){return .5*this.r*this.r*(this.sweep-Math.sin(this.sweep))}sortPoints(t){let{vector:l}=b;return t.slice().sort((s,e)=>{let d=l(this.pc,s).slope,i=l(this.pc,e).slope;return d<i?-1:d>i?1:0})}get name(){return"arc"}svg(t={}){let l=this.sweep<=Math.PI?"0":"1",s=this.counterClockwise?"1":"0";return b.Utils.EQ(this.sweep,2*Math.PI)?new b.Circle(this.pc,this.r).svg(t):`
|
|
19
19
|
<path d="M${this.start.x},${this.start.y}
|
|
20
20
|
A${this.r},${this.r} 0 ${l},${s} ${this.end.x},${this.end.y}"
|
|
21
|
-
${
|
|
21
|
+
${xt({fill:"none",...t})} />`}}b.Arc=zX;const MX=(...n)=>new b.Arc(...n);b.arc=MX;class wt extends mt{constructor(t=void 0,l=void 0,s=void 0,e=void 0){super(),this.xmin=t,this.ymin=l,this.xmax=s,this.ymax=e}clone(){return new wt(this.xmin,this.ymin,this.xmax,this.ymax)}get low(){return new b.Point(this.xmin,this.ymin)}get high(){return new b.Point(this.xmax,this.ymax)}get max(){return this.clone()}get center(){return new b.Point((this.xmin+this.xmax)/2,(this.ymin+this.ymax)/2)}get width(){return Math.abs(this.xmax-this.xmin)}get height(){return Math.abs(this.ymax-this.ymin)}get box(){return this.clone()}not_intersect(t){return this.xmax<t.xmin||this.xmin>t.xmax||this.ymax<t.ymin||this.ymin>t.ymax}intersect(t){return!this.not_intersect(t)}merge(t){return new wt(this.xmin===void 0?t.xmin:Math.min(this.xmin,t.xmin),this.ymin===void 0?t.ymin:Math.min(this.ymin,t.ymin),this.xmax===void 0?t.xmax:Math.max(this.xmax,t.xmax),this.ymax===void 0?t.ymax:Math.max(this.ymax,t.ymax))}less_than(t){return!!(this.low.lessThan(t.low)||this.low.equalTo(t.low)&&this.high.lessThan(t.high))}equal_to(t){return this.low.equalTo(t.low)&&this.high.equalTo(t.high)}output(){return this.clone()}comparable_less_than(t,l){return t.lessThan(l)}set(t,l,s,e){this.xmin=t,this.ymin=l,this.xmax=s,this.ymax=e}extend(t){return t<=0?this.clone():new wt(this.xmin-t,this.ymin-t,this.xmax+t,this.ymax+t)}toPoints(){return[new b.Point(this.xmin,this.ymin),new b.Point(this.xmax,this.ymin),new b.Point(this.xmax,this.ymax),new b.Point(this.xmin,this.ymax)]}toSegments(){let t=this.toPoints();return[new b.Segment(t[0],t[1]),new b.Segment(t[1],t[2]),new b.Segment(t[2],t[3]),new b.Segment(t[3],t[0])]}rotate(t,l=new b.Point){throw Q.OPERATION_IS_NOT_SUPPORTED}transform(t=new b.Matrix){return this.toPoints().map(s=>s.transform(t)).reduce((s,e)=>s.merge(e.box),new wt)}contains(t){if(t instanceof b.Point)return t.x>=this.xmin&&t.x<=this.xmax&&t.y>=this.ymin&&t.y<=this.ymax;if(t instanceof b.Segment)return t.vertices.every(l=>this.contains(l));if(t instanceof b.Box)return t.toSegments().every(l=>this.contains(l));if(t instanceof b.Circle)return this.contains(t.box);if(t instanceof b.Arc)return t.vertices.every(l=>this.contains(l))&&this.toSegments().every(l=>Jt(l,t).length===0);if(t instanceof b.Line||t instanceof b.Ray)return!1;if(t instanceof b.Multiline)return t.toShapes().every(l=>this.contains(l));if(t instanceof b.Polygon)return this.contains(t.box)}distanceTo(t){const l=this.toSegments().map(e=>e.distanceTo(t));let s=[Number.MAX_SAFE_INTEGER,null];return l.forEach(e=>{e[0]<s[0]&&(s=e)}),s}get name(){return"box"}svg(t={}){const l=this.xmax-this.xmin,s=this.ymax-this.ymin;return`
|
|
22
22
|
<rect x="${this.xmin}" y="${this.ymin}" width="${l}" height="${s}"
|
|
23
|
-
${
|
|
24
|
-
A${i.r},${i.r} 0 ${l},${s} ${i.end.x},${i.end.y}`}else return l=t.sweep<=Math.PI?"0":"1",` A${t.r},${t.r} 0 ${l},${s} ${t.end.x},${t.end.y}`}}toJSON(){return this.shape.toJSON()}}b.Edge=ra;class ha extends Rl{constructor(t,l){super(t,l),this.setCircularLinks()}setCircularLinks(){this.isEmpty()||(this.last.next=this.first,this.first.prev=this.last)}[Symbol.iterator](){let t;return{next:()=>{let l=t||this.first,s=this.first?t?t===this.first:!1:!0;return t=l?l.next:void 0,{value:l,done:s}}}}append(t){return super.append(t),this.setCircularLinks(),this}insert(t,l){return super.insert(t,l),this.setCircularLinks(),this}remove(t){return super.remove(t),this}}class Qt extends ha{constructor(t,...l){if(super(),this._box=void 0,this._orientation=void 0,l.length!==0){if(l.length===1){if(l[0]instanceof Array){let s=l[0];if(s.length===0)return;if(s.every(e=>e instanceof b.Point)){let e=Qt.points2segments(s);this.shapes2face(t.edges,e)}else if(s.every(e=>e instanceof Array&&e.length===2)){let e=s.map(i=>new b.Point(i[0],i[1])),d=Qt.points2segments(e);this.shapes2face(t.edges,d)}else if(s.every(e=>e instanceof b.Segment||e instanceof b.Arc))this.shapes2face(t.edges,s);else if(s.every(e=>e.name==="segment"||e.name==="arc")){let e=[];for(let d of s){let i;d.name==="segment"?i=new b.Segment(d):i=new b.Arc(d),e.push(i)}this.shapes2face(t.edges,e)}}else if(l[0]instanceof Qt){let s=l[0];this.first=s.first,this.last=s.last;for(let e of s)t.edges.add(e)}else if(l[0]instanceof b.Circle)this.shapes2face(t.edges,[l[0].toArc(He)]);else if(l[0]instanceof b.Box){let s=l[0];this.shapes2face(t.edges,[new b.Segment(new b.Point(s.xmin,s.ymin),new b.Point(s.xmax,s.ymin)),new b.Segment(new b.Point(s.xmax,s.ymin),new b.Point(s.xmax,s.ymax)),new b.Segment(new b.Point(s.xmax,s.ymax),new b.Point(s.xmin,s.ymax)),new b.Segment(new b.Point(s.xmin,s.ymax),new b.Point(s.xmin,s.ymin))])}}l.length===2&&l[0]instanceof b.Edge&&l[1]instanceof b.Edge&&(this.first=l[0],this.last=l[1],this.last.next=this.first,this.first.prev=this.last,this.setArcLength())}}get edges(){return this.toArray()}get vertices(){return this.edges.map(t=>t.shape.start.clone())}get shapes(){return this.edges.map(t=>t.shape.clone())}get box(){if(this._box===void 0){let t=new b.Box;for(let l of this)t=t.merge(l.box);this._box=t}return this._box}get perimeter(){return this.last.arc_length+this.last.length}pointAtLength(t){if(t>this.perimeter||t<0)return null;let l=null;for(let s of this)if(t>=s.arc_length&&(s===this.last||t<s.next.arc_length)){l=s.pointAtLength(t-s.arc_length);break}return l}static points2segments(t){let l=[];for(let s=0;s<t.length;s++)t[s].equalTo(t[(s+1)%t.length])||l.push(new b.Segment(t[s],t[(s+1)%t.length]));return l}shapes2face(t,l){for(let s of l){let e=new b.Edge(s);this.append(e),t.add(e)}}append(t){return super.append(t),this.setOneEdgeArcLength(t),t.face=this,this}insert(t,l){return super.insert(t,l),this.setOneEdgeArcLength(t),t.face=this,this}remove(t){return super.remove(t),this.setArcLength(),this}merge_with_next_edge(t){return t.shape.end.x=t.next.shape.end.x,t.shape.end.y=t.next.shape.end.y,this.remove(t.next),this}reverse(){let t=[],l=this.last;do l.shape=l.shape.reverse(),t.push(l),l=l.prev;while(l!==this.last);this.first=void 0,this.last=void 0;for(let s of t)this.first===void 0?(s.prev=s,s.next=s,this.first=s,this.last=s):(s.prev=this.last,this.last.next=s,this.last=s,this.last.next=this.first,this.first.prev=this.last),this.setOneEdgeArcLength(s);this._orientation!==void 0&&(this._orientation=void 0,this._orientation=this.orientation())}setArcLength(){for(let t of this)this.setOneEdgeArcLength(t),t.face=this}setOneEdgeArcLength(t){t===this.first?t.arc_length=0:t.arc_length=t.prev.arc_length+t.prev.length}area(){return Math.abs(this.signedArea())}signedArea(){let t=0,l=this.box.ymin;for(let s of this)t+=s.shape.definiteIntegral(l);return t}orientation(){if(this._orientation===void 0){let t=this.signedArea();b.Utils.EQ_0(t)?this._orientation=Et.NOT_ORIENTABLE:b.Utils.LT(t,0)?this._orientation=Et.CCW:this._orientation=Et.CW}return this._orientation}isSimple(t){return Qt.getSelfIntersections(this,t,!0).length===0}static getSelfIntersections(t,l,s=!1){let e=[];for(let d of t){let i=l.search(d.box);for(let c of i){if(d===c||c.face!==t||d.shape instanceof b.Segment&&c.shape instanceof b.Segment&&(d.next===c||d.prev===c))continue;let o=d.shape.intersect(c.shape);for(let a of o)if(!(a.equalTo(d.start)&&a.equalTo(c.end)&&c===d.prev)&&!(a.equalTo(d.end)&&a.equalTo(c.start)&&c===d.next)&&(e.push(a),s))break;if(e.length>0&&s)break}if(e.length>0&&s)break}return e}findEdgeByPoint(t){let l;for(let s of this)if(!t.equalTo(s.shape.start)&&(t.equalTo(s.shape.end)||s.shape.contains(t))){l=s;break}return l}toPolygon(){return new b.Polygon(this.shapes)}toJSON(){return this.edges.map(t=>t.toJSON())}svg(){let t=`M${this.first.start.x},${this.first.start.y}`;for(let l of this)t+=l.svg();return t+=" z",t}}b.Face=Qt;class kl extends ut{constructor(...t){if(super(),this.pt=new b.Point,this.norm=new b.Vector(0,1),t.length!==0&&(t.length>=1&&t[0]instanceof b.Point&&(this.pt=t[0].clone()),t.length!==1)){if(t.length===2&&t[1]instanceof b.Vector){this.norm=t[1].clone();return}throw P.ILLEGAL_PARAMETERS}}clone(){return new kl(this.pt,this.norm)}get slope(){return new b.Vector(this.norm.y,-this.norm.x).slope}get box(){let t=this.slope;return new b.Box(t>Math.PI/2&&t<3*Math.PI/2?Number.NEGATIVE_INFINITY:this.pt.x,t>=0&&t<=Math.PI?this.pt.y:Number.NEGATIVE_INFINITY,t>=Math.PI/2&&t<=3*Math.PI/2?this.pt.x:Number.POSITIVE_INFINITY,t>=Math.PI&&t<=2*Math.PI||t===0?this.pt.y:Number.POSITIVE_INFINITY)}get start(){return this.pt}get end(){}get length(){return Number.POSITIVE_INFINITY}contains(t){if(this.pt.equalTo(t))return!0;let l=new b.Vector(this.pt,t);return b.Utils.EQ_0(this.norm.dot(l))&&b.Utils.GE(l.cross(this.norm),0)}coord(t){return pd(t.x,t.y).cross(this.norm)}split(t){return this.contains(t)?this.pt.equalTo(t)?[this]:[new b.Segment(this.pt,t),new b.Ray(t,this.norm)]:[]}intersect(t){if(t instanceof b.Point)return this.contains(t)?[t]:[];if(t instanceof b.Segment)return Yl(this,t);if(t instanceof b.Arc)return gl(this,t);if(t instanceof b.Line)return td(this,t);if(t instanceof b.Ray)return So(this,t);if(t instanceof b.Circle)return $e(this,t);if(t instanceof b.Box)return Ko(this,t);if(t instanceof b.Polygon)return nd(this,t);if(t instanceof b.Multiline)return Ft(this,t)}rotate(t,l=new b.Point){return new b.Ray(this.pt.rotate(t,l),this.norm.rotate(t))}transform(t){return new b.Ray(this.pt.transform(t),this.norm.clone())}get name(){return"ray"}svg(t,l={}){let s=new b.Line(this.pt,this.norm),e=ft(s,t);return e=e.filter(i=>this.contains(i)),e.length===0||e.length===2?"":new b.Segment(this.pt,e[0]).svg(l)}}b.Ray=kl;const ma=(...n)=>new b.Ray(...n);b.ray=ma;let en=class ht{constructor(){this.faces=new b.PlanarSet,this.edges=new b.PlanarSet;let t=[...arguments];if(t.length===1&&(t[0]instanceof Array&&t[0].length>0||t[0]instanceof b.Circle||t[0]instanceof b.Box)){let l=t[0];if(t[0]instanceof Array&&t[0].every(s=>s instanceof Array))if(l.every(s=>s instanceof Array&&s.length===2&&typeof s[0]=="number"&&typeof s[1]=="number"))this.faces.add(new b.Face(this,l));else for(let s of l)if(s instanceof Array&&s[0]instanceof Array&&s[0].every(e=>e instanceof Array&&e.length===2&&typeof e[0]=="number"&&typeof e[1]=="number"))for(let e of s)this.faces.add(new b.Face(this,e));else this.faces.add(new b.Face(this,s));else this.faces.add(new b.Face(this,l))}}get box(){return[...this.faces].reduce((t,l)=>t.merge(l.box),new b.Box)}get vertices(){return[...this.faces].flatMap(t=>t.vertices)}clone(){let t=new ht;for(let l of this.faces)t.addFace(l.shapes);return t}createFromArray(t){const l=new ht;return t.forEach(s=>[...s.faces].forEach(e=>l.addFace(e.shapes))),l}isEmpty(){return this.edges.size===0||this.faces.size===0}isValid(){let t=!0;for(let l of this.faces)if(!l.isSimple(this.edges)){t=!1;break}return t}area(){let t=[...this.faces].reduce((l,s)=>l+s.signedArea(),0);return Math.abs(t)}addFace(...t){let l=new b.Face(this,...t);return this.faces.add(l),l}deleteFace(t){for(let l of t)this.edges.delete(l);return this.faces.delete(t)}recreateFaces(){this.faces.clear();for(let s of this.edges)s.face=null;let t,l=!0;for(;l;){l=!1;for(let s of this.edges)if(s.face===null){t=s,l=!0;break}if(l){let s=t;do s=s.next;while(s.next!==t);this.addFace(t,s)}}}removeChain(t,l,s){if(s.next===l){this.deleteFace(t);return}for(let e=l;e!==s.next;e=e.next)if(t.remove(e),this.edges.delete(e),t.isEmpty()){this.deleteFace(t);break}}addVertex(t,l){let s=l.shape.split(t);if(s[0]===null)return l.prev;if(s[1]===null)return l;let e=new b.Edge(s[0]),d=l.prev;return l.face.insert(e,d),this.edges.delete(l),this.edges.add(e),l.shape=s[1],this.edges.add(l),e}removeEndVertex(t){const l=t.next;l!==t&&(t.face.merge_with_next_edge(t),this.edges.delete(l))}cut(t){const s=this.splitToIslands().flatMap(e=>e._cutSingleIsland(t)).filter(e=>e.isValid()&&e.isEmpty()===!1);return this.createFromArray(s)}_cutSingleIsland(t){let l=this.clone();const s=t.clone();let e={int_points1:[],int_points2:[],int_points1_sorted:[],int_points2_sorted:[]};for(let c of s.edges)for(let o of l.edges){let a=Ae(c,o);for(let X of a)Nt(c,X,e.int_points1),Nt(o,X,e.int_points2)}if(e.int_points1.length===0)return l;e.int_points1_sorted=at(e.int_points1),e.int_points2_sorted=at(e.int_points2),Jt(s,e.int_points1_sorted),Jt(l,e.int_points2_sorted),Ml(e),e.int_points1_sorted=at(e.int_points1),e.int_points2_sorted=at(e.int_points2),Tl(e.int_points1),fl(e.int_points1,l);for(let c of e.int_points1_sorted)c.edge_before&&c.edge_after&&c.edge_before.bv===c.edge_after.bv&&(e.int_points2[c.id]=-1,c.id=-1);if(e.int_points1=e.int_points1.filter(c=>c.id>=0),e.int_points2=e.int_points2.filter(c=>c.id>=0),e.int_points1.forEach((c,o)=>{c.id=o}),e.int_points2.forEach((c,o)=>{c.id=o}),e.int_points1.length===0)return l;e.int_points1_sorted=at(e.int_points1),e.int_points2_sorted=at(e.int_points2);let d,i;for(let c=1;c<e.int_points1_sorted.length;c++)if(i=e.int_points1_sorted[c],d=e.int_points1_sorted[c-1],i.edge_before&&i.edge_before.bv===Yn){let o=d.edge_after,a=i.edge_before,X=s.getChain(o,a);sd(e.int_points2[d.id],e.int_points2[i.id],X),X.forEach(u=>l.edges.add(u)),X=X.reverse().map(u=>new b.Edge(u.shape.reverse()));for(let u=0;u<X.length-1;u++)X[u].next=X[u+1],X[u+1].prev=X[u];sd(e.int_points2[i.id],e.int_points2[d.id],X),X.forEach(u=>l.edges.add(u))}return l.recreateFaces(),l}cutWithLine(t){let l=new Vt([t]);return this.cut(l)}findEdgeByPoint(t){let l;for(let s of this.faces)if(l=s.findEdgeByPoint(t),l!==void 0)break;return l}splitToIslands(){if(this.isEmpty())return[];let t=this.toArray();t.sort((e,d)=>d.area()-e.area());let l=[...t[0].faces][0].orientation(),s=t.filter(e=>[...e.faces][0].orientation()===l);for(let e of t){let d=[...e.faces][0];if(d.orientation()!==l){for(let i of s)if(d.shapes.every(c=>i.contains(c))){i.addFace(d.shapes);break}}}return s}rearrange(){if(this.faces.size<=1)return this.clone();const t=this.splitToIslands(),l=new ht;return t.forEach(s=>{s.faces.forEach(e=>l.addFace(e.shapes))}),l}orientation(){return this.isEmpty()?Et.NOT_ORIENTABLE:[...this.faces][0].orientation()}isOuter(t){return t.orientation()===this.orientation()}isMultiPolygon(){let t=0;return this.faces.forEach(l=>{this.isOuter(l)&&t++}),t>1}reverse(){for(let t of this.faces)t.reverse();return this}contains(t){if(t instanceof b.Point){let l=nn(this,t);return l===Yn||l===q}else return Zd(this,t)}distanceTo(t){if(t instanceof b.Point){let[l,s]=b.Distance.point2polygon(t,this);return s=s.reverse(),[l,s]}if(t instanceof b.Circle||t instanceof b.Line||t instanceof b.Segment||t instanceof b.Arc){let[l,s]=b.Distance.shape2polygon(t,this);return s=s.reverse(),[l,s]}if(t instanceof b.Polygon){let l=[Number.POSITIVE_INFINITY,new b.Segment],s,e;for(let d of this.edges){let i=l[0];[s,e]=b.Distance.shape2planarSet(d.shape,t.edges,i),b.Utils.LT(s,i)&&(l=[s,e])}return l}}intersect(t){if(t instanceof b.Point)return this.contains(t)?[t]:[];if(t instanceof b.Line)return At(t,this);if(t instanceof b.Ray)return nd(t,this);if(t instanceof b.Circle)return De(t,this);if(t instanceof b.Segment)return Sl(t,this);if(t instanceof b.Arc)return zl(t,this);if(t instanceof b.Polygon)return xo(t,this);if(t instanceof b.Multiline)return Lo(t,this)}translate(t){let l=new ht;for(let s of this.faces)l.addFace(s.shapes.map(e=>e.translate(t)));return l}rotate(t=0,l=new b.Point){let s=new ht;for(let e of this.faces)s.addFace(e.shapes.map(d=>d.rotate(t,l)));return s}scale(t,l){let s=new ht;for(let e of this.faces)s.addFace(e.shapes.map(d=>d.scale(t,l)));return s}transform(t=new b.Matrix){let l=new ht;for(let s of this.faces)l.addFace(s.shapes.map(e=>e.transform(t)));return l}toJSON(){return[...this.faces].map(t=>t.toJSON())}toArray(){return[...this.faces].map(t=>t.toPolygon())}dpath(){return[...this.faces].reduce((t,l)=>t+l.svg(),"")}svg(t={}){let l=`
|
|
25
|
-
<path ${
|
|
23
|
+
${xt({fill:"none",...t})} />`}}b.Box=wt;const YX=(...n)=>new b.Box(...n);b.box=YX;class gX{constructor(t){this.shape=t,this.next=void 0,this.prev=void 0,this.face=void 0,this.arc_length=0,this.bvStart=void 0,this.bvEnd=void 0,this.bv=void 0,this.overlap=void 0}get start(){return this.shape.start}get end(){return this.shape.end}get length(){return this.shape.length}get box(){return this.shape.box}get isSegment(){return this.shape instanceof b.Segment}get isArc(){return this.shape instanceof b.Arc}get isLine(){return this.shape instanceof b.Line}get isRay(){return this.shape instanceof b.Ray}middle(){return this.shape.middle()}pointAtLength(t){return this.shape.pointAtLength(t)}contains(t){return this.shape.contains(t)}setInclusion(t){if(this.bv!==void 0)return this.bv;if(this.shape instanceof b.Line||this.shape instanceof b.Ray)return this.bv=b.OUTSIDE,this.bv;if(this.bvStart===void 0&&(this.bvStart=bn(t,this.start)),this.bvEnd===void 0&&(this.bvEnd=bn(t,this.end)),this.bvStart===b.OUTSIDE||this.bvEnd==b.OUTSIDE)this.bv=b.OUTSIDE;else if(this.bvStart===b.INSIDE||this.bvEnd==b.INSIDE)this.bv=b.INSIDE;else{let l=bn(t,this.middle());this.bv=l}return this.bv}setOverlap(t){let l,s=this.shape,e=t.shape;s instanceof b.Segment&&e instanceof b.Segment?s.start.equalTo(e.start)&&s.end.equalTo(e.end)?l=b.OVERLAP_SAME:s.start.equalTo(e.end)&&s.end.equalTo(e.start)&&(l=b.OVERLAP_OPPOSITE):(s instanceof b.Arc&&e instanceof b.Arc||s instanceof b.Segment&&e instanceof b.Arc||s instanceof b.Arc&&e instanceof b.Segment)&&(s.start.equalTo(e.start)&&s.end.equalTo(e.end)&&s.middle().equalTo(e.middle())?l=b.OVERLAP_SAME:s.start.equalTo(e.end)&&s.end.equalTo(e.start)&&s.middle().equalTo(e.middle())&&(l=b.OVERLAP_OPPOSITE)),this.overlap===void 0&&(this.overlap=l),t.overlap===void 0&&(t.overlap=l)}svg(){if(this.shape instanceof b.Segment)return` L${this.shape.end.x},${this.shape.end.y}`;if(this.shape instanceof b.Arc){let t=this.shape,l,s=t.counterClockwise?"1":"0";if(b.Utils.EQ(t.sweep,2*Math.PI)){let e=t.counterClockwise?1:-1,d=new b.Arc(t.pc,t.r,t.startAngle,t.startAngle+e*Math.PI,t.counterClockwise),i=new b.Arc(t.pc,t.r,t.startAngle+e*Math.PI,t.endAngle,t.counterClockwise);return l="0",` A${d.r},${d.r} 0 ${l},${s} ${d.end.x},${d.end.y}
|
|
24
|
+
A${i.r},${i.r} 0 ${l},${s} ${i.end.x},${i.end.y}`}else return l=t.sweep<=Math.PI?"0":"1",` A${t.r},${t.r} 0 ${l},${s} ${t.end.x},${t.end.y}`}}toJSON(){return this.shape.toJSON()}}b.Edge=gX;class TX extends Nl{constructor(t,l){super(t,l),this.setCircularLinks()}setCircularLinks(){this.isEmpty()||(this.last.next=this.first,this.first.prev=this.last)}[Symbol.iterator](){let t;return{next:()=>{let l=t||this.first,s=this.first?t?t===this.first:!1:!0;return t=l?l.next:void 0,{value:l,done:s}}}}append(t){return super.append(t),this.setCircularLinks(),this}insert(t,l){return super.insert(t,l),this.setCircularLinks(),this}remove(t){return super.remove(t),this}}class Ut extends TX{constructor(t,...l){if(super(),this._box=void 0,this._orientation=void 0,l.length!==0){if(l.length===1){if(l[0]instanceof Array){let s=l[0];if(s.length===0)return;if(s.every(e=>e instanceof b.Point)){let e=Ut.points2segments(s);this.shapes2face(t.edges,e)}else if(s.every(e=>e instanceof Array&&e.length===2)){let e=s.map(i=>new b.Point(i[0],i[1])),d=Ut.points2segments(e);this.shapes2face(t.edges,d)}else if(s.every(e=>e instanceof b.Segment||e instanceof b.Arc))this.shapes2face(t.edges,s);else if(s.every(e=>e.name==="segment"||e.name==="arc")){let e=[];for(let d of s){let i;d.name==="segment"?i=new b.Segment(d):i=new b.Arc(d),e.push(i)}this.shapes2face(t.edges,e)}}else if(l[0]instanceof Ut){let s=l[0];this.first=s.first,this.last=s.last;for(let e of s)t.edges.add(e)}else if(l[0]instanceof b.Circle)this.shapes2face(t.edges,[l[0].toArc(Ae)]);else if(l[0]instanceof b.Box){let s=l[0];this.shapes2face(t.edges,[new b.Segment(new b.Point(s.xmin,s.ymin),new b.Point(s.xmax,s.ymin)),new b.Segment(new b.Point(s.xmax,s.ymin),new b.Point(s.xmax,s.ymax)),new b.Segment(new b.Point(s.xmax,s.ymax),new b.Point(s.xmin,s.ymax)),new b.Segment(new b.Point(s.xmin,s.ymax),new b.Point(s.xmin,s.ymin))])}}l.length===2&&l[0]instanceof b.Edge&&l[1]instanceof b.Edge&&(this.first=l[0],this.last=l[1],this.last.next=this.first,this.first.prev=this.last,this.setArcLength())}}get edges(){return this.toArray()}get vertices(){return this.edges.map(t=>t.shape.start.clone())}get shapes(){return this.edges.map(t=>t.shape.clone())}get box(){if(this._box===void 0){let t=new b.Box;for(let l of this)t=t.merge(l.box);this._box=t}return this._box}get perimeter(){return this.last.arc_length+this.last.length}pointAtLength(t){if(t>this.perimeter||t<0)return null;let l=null;for(let s of this)if(t>=s.arc_length&&(s===this.last||t<s.next.arc_length)){l=s.pointAtLength(t-s.arc_length);break}return l}static points2segments(t){let l=[];for(let s=0;s<t.length;s++)t[s].equalTo(t[(s+1)%t.length])||l.push(new b.Segment(t[s],t[(s+1)%t.length]));return l}shapes2face(t,l){for(let s of l){let e=new b.Edge(s);this.append(e),t.add(e)}}append(t){return super.append(t),this.setOneEdgeArcLength(t),t.face=this,this}insert(t,l){return super.insert(t,l),this.setOneEdgeArcLength(t),t.face=this,this}remove(t){return super.remove(t),this.setArcLength(),this}merge_with_next_edge(t){return t.shape.end.x=t.next.shape.end.x,t.shape.end.y=t.next.shape.end.y,this.remove(t.next),this}reverse(){let t=[],l=this.last;do l.shape=l.shape.reverse(),t.push(l),l=l.prev;while(l!==this.last);this.first=void 0,this.last=void 0;for(let s of t)this.first===void 0?(s.prev=s,s.next=s,this.first=s,this.last=s):(s.prev=this.last,this.last.next=s,this.last=s,this.last.next=this.first,this.first.prev=this.last),this.setOneEdgeArcLength(s);this._orientation!==void 0&&(this._orientation=void 0,this._orientation=this.orientation())}setArcLength(){for(let t of this)this.setOneEdgeArcLength(t),t.face=this}setOneEdgeArcLength(t){t===this.first?t.arc_length=0:t.arc_length=t.prev.arc_length+t.prev.length}area(){return Math.abs(this.signedArea())}signedArea(){let t=0,l=this.box.ymin;for(let s of this)t+=s.shape.definiteIntegral(l);return t}orientation(){if(this._orientation===void 0){let t=this.signedArea();b.Utils.EQ_0(t)?this._orientation=$t.NOT_ORIENTABLE:b.Utils.LT(t,0)?this._orientation=$t.CCW:this._orientation=$t.CW}return this._orientation}isSimple(t){return Ut.getSelfIntersections(this,t,!0).length===0}static getSelfIntersections(t,l,s=!1){let e=[];for(let d of t){let i=l.search(d.box);for(let c of i){if(d===c||c.face!==t||d.shape instanceof b.Segment&&c.shape instanceof b.Segment&&(d.next===c||d.prev===c))continue;let o=d.shape.intersect(c.shape);for(let X of o)if(!(X.equalTo(d.start)&&X.equalTo(c.end)&&c===d.prev)&&!(X.equalTo(d.end)&&X.equalTo(c.start)&&c===d.next)&&(e.push(X),s))break;if(e.length>0&&s)break}if(e.length>0&&s)break}return e}findEdgeByPoint(t){let l;for(let s of this)if(!t.equalTo(s.shape.start)&&(t.equalTo(s.shape.end)||s.shape.contains(t))){l=s;break}return l}toPolygon(){return new b.Polygon(this.shapes)}toJSON(){return this.edges.map(t=>t.toJSON())}svg(){let t=`M${this.first.start.x},${this.first.start.y}`;for(let l of this)t+=l.svg();return t+=" z",t}}b.Face=Ut;class Dl extends mt{constructor(...t){if(super(),this.pt=new b.Point,this.norm=new b.Vector(0,1),t.length!==0&&(t.length>=1&&t[0]instanceof b.Point&&(this.pt=t[0].clone()),t.length!==1)){if(t.length===2&&t[1]instanceof b.Vector){this.norm=t[1].clone();return}throw Q.ILLEGAL_PARAMETERS}}clone(){return new Dl(this.pt,this.norm)}get slope(){return new b.Vector(this.norm.y,-this.norm.x).slope}get box(){let t=this.slope;return new b.Box(t>Math.PI/2&&t<3*Math.PI/2?Number.NEGATIVE_INFINITY:this.pt.x,t>=0&&t<=Math.PI?this.pt.y:Number.NEGATIVE_INFINITY,t>=Math.PI/2&&t<=3*Math.PI/2?this.pt.x:Number.POSITIVE_INFINITY,t>=Math.PI&&t<=2*Math.PI||t===0?this.pt.y:Number.POSITIVE_INFINITY)}get start(){return this.pt}get end(){}get length(){return Number.POSITIVE_INFINITY}contains(t){if(this.pt.equalTo(t))return!0;let l=new b.Vector(this.pt,t);return b.Utils.EQ_0(this.norm.dot(l))&&b.Utils.GE(l.cross(this.norm),0)}coord(t){return Td(t.x,t.y).cross(this.norm)}split(t){return this.contains(t)?this.pt.equalTo(t)?[this]:[new b.Segment(this.pt,t),new b.Ray(t,this.norm)]:[]}intersect(t){if(t instanceof b.Point)return this.contains(t)?[t]:[];if(t instanceof b.Segment)return kl(this,t);if(t instanceof b.Arc)return Pl(this,t);if(t instanceof b.Line)return hd(this,t);if(t instanceof b.Ray)return vo(this,t);if(t instanceof b.Circle)return ud(this,t);if(t instanceof b.Box)return Bo(this,t);if(t instanceof b.Polygon)return rd(this,t);if(t instanceof b.Multiline)return It(this,t)}rotate(t,l=new b.Point){return new b.Ray(this.pt.rotate(t,l),this.norm.rotate(t))}transform(t){return new b.Ray(this.pt.transform(t),this.norm.clone())}get name(){return"ray"}svg(t,l={}){let s=new b.Line(this.pt,this.norm),e=Ht(s,t);return e=e.filter(i=>this.contains(i)),e.length===0||e.length===2?"":new b.Segment(this.pt,e[0]).svg(l)}}b.Ray=Dl;const CX=(...n)=>new b.Ray(...n);b.ray=CX;let an=class Wt{constructor(){this.faces=new b.PlanarSet,this.edges=new b.PlanarSet;let t=[...arguments];if(t.length===1&&(t[0]instanceof Array&&t[0].length>0||t[0]instanceof b.Circle||t[0]instanceof b.Box)){let l=t[0];if(t[0]instanceof Array&&t[0].every(s=>s instanceof Array))if(l.every(s=>s instanceof Array&&s.length===2&&typeof s[0]=="number"&&typeof s[1]=="number"))this.faces.add(new b.Face(this,l));else for(let s of l)if(s instanceof Array&&s[0]instanceof Array&&s[0].every(e=>e instanceof Array&&e.length===2&&typeof e[0]=="number"&&typeof e[1]=="number"))for(let e of s)this.faces.add(new b.Face(this,e));else this.faces.add(new b.Face(this,s));else this.faces.add(new b.Face(this,l))}}get box(){return[...this.faces].reduce((t,l)=>t.merge(l.box),new b.Box)}get vertices(){return[...this.faces].flatMap(t=>t.vertices)}clone(){let t=new Wt;for(let l of this.faces)t.addFace(l.shapes);return t}createFromArray(t){const l=new Wt;return t.forEach(s=>[...s.faces].forEach(e=>l.addFace(e.shapes))),l}isEmpty(){return this.edges.size===0||this.faces.size===0}isValid(){let t=!0;for(let l of this.faces)if(!l.isSimple(this.edges)){t=!1;break}return t}area(){let t=[...this.faces].reduce((l,s)=>l+s.signedArea(),0);return Math.abs(t)}addFace(...t){let l=new b.Face(this,...t);return this.faces.add(l),l}deleteFace(t){for(let l of t)this.edges.delete(l);return this.faces.delete(t)}recreateFaces(){this.faces.clear();for(let s of this.edges)s.face=null;let t,l=!0;for(;l;){l=!1;for(let s of this.edges)if(s.face===null){t=s,l=!0;break}if(l){let s=t;do s=s.next;while(s.next!==t);this.addFace(t,s)}}}removeChain(t,l,s){if(s.next===l){this.deleteFace(t);return}for(let e=l;e!==s.next;e=e.next)if(t.remove(e),this.edges.delete(e),t.isEmpty()){this.deleteFace(t);break}}addVertex(t,l){let s=l.shape.split(t);if(s[0]===null)return l.prev;if(s[1]===null)return l;let e=new b.Edge(s[0]),d=l.prev;return l.face.insert(e,d),this.edges.delete(l),this.edges.add(e),l.shape=s[1],this.edges.add(l),e}removeEndVertex(t){const l=t.next;l!==t&&(t.face.merge_with_next_edge(t),this.edges.delete(l))}cut(t){const s=this.splitToIslands().flatMap(e=>e._cutSingleIsland(t)).filter(e=>e.isValid()&&e.isEmpty()===!1);return this.createFromArray(s)}_cutSingleIsland(t){let l=this.clone();const s=t.clone();let e={int_points1:[],int_points2:[],int_points1_sorted:[],int_points2_sorted:[]};for(let c of s.edges)for(let o of l.edges){let X=od(c,o);for(let a of X)kt(c,a,e.int_points1),kt(o,a,e.int_points2)}if(e.int_points1.length===0)return l;e.int_points1_sorted=Zt(e.int_points1),e.int_points2_sorted=Zt(e.int_points2),Qt(s,e.int_points1_sorted),Qt(l,e.int_points2_sorted),Ql(e),e.int_points1_sorted=Zt(e.int_points1),e.int_points2_sorted=Zt(e.int_points2),Bl(e.int_points1),vl(e.int_points1,l);for(let c of e.int_points1_sorted)c.edge_before&&c.edge_after&&c.edge_before.bv===c.edge_after.bv&&(e.int_points2[c.id]=-1,c.id=-1);if(e.int_points1=e.int_points1.filter(c=>c.id>=0),e.int_points2=e.int_points2.filter(c=>c.id>=0),e.int_points1.forEach((c,o)=>{c.id=o}),e.int_points2.forEach((c,o)=>{c.id=o}),e.int_points1.length===0)return l;e.int_points1_sorted=Zt(e.int_points1),e.int_points2_sorted=Zt(e.int_points2);let d,i;for(let c=1;c<e.int_points1_sorted.length;c++)if(i=e.int_points1_sorted[c],d=e.int_points1_sorted[c-1],i.edge_before&&i.edge_before.bv===Hn){let o=d.edge_after,X=i.edge_before,a=s.getChain(o,X);Gd(e.int_points2[d.id],e.int_points2[i.id],a),a.forEach(u=>l.edges.add(u)),a=a.reverse().map(u=>new b.Edge(u.shape.reverse()));for(let u=0;u<a.length-1;u++)a[u].next=a[u+1],a[u+1].prev=a[u];Gd(e.int_points2[i.id],e.int_points2[d.id],a),a.forEach(u=>l.edges.add(u))}return l.recreateFaces(),l}cutWithLine(t){let l=new Rt([t]);return this.cut(l)}findEdgeByPoint(t){let l;for(let s of this.faces)if(l=s.findEdgeByPoint(t),l!==void 0)break;return l}splitToIslands(){if(this.isEmpty())return[];let t=this.toArray();t.sort((e,d)=>d.area()-e.area());let l=[...t[0].faces][0].orientation(),s=t.filter(e=>[...e.faces][0].orientation()===l);for(let e of t){let d=[...e.faces][0];if(d.orientation()!==l){for(let i of s)if(d.shapes.every(c=>i.contains(c))){i.addFace(d.shapes);break}}}return s}rearrange(){if(this.faces.size<=1)return this.clone();const t=this.splitToIslands(),l=new Wt;return t.forEach(s=>{s.faces.forEach(e=>l.addFace(e.shapes))}),l}orientation(){return this.isEmpty()?$t.NOT_ORIENTABLE:[...this.faces][0].orientation()}isOuter(t){return t.orientation()===this.orientation()}isMultiPolygon(){let t=0;return this.faces.forEach(l=>{this.isOuter(l)&&t++}),t>1}reverse(){for(let t of this.faces)t.reverse();return this}contains(t){if(t instanceof b.Point){let l=bn(this,t);return l===Hn||l===lt}else return Yd(this,t)}distanceTo(t){if(t instanceof b.Point){let[l,s]=b.Distance.point2polygon(t,this);return s=s.reverse(),[l,s]}if(t instanceof b.Circle||t instanceof b.Line||t instanceof b.Segment||t instanceof b.Arc){let[l,s]=b.Distance.shape2polygon(t,this);return s=s.reverse(),[l,s]}if(t instanceof b.Polygon){let l=[Number.POSITIVE_INFINITY,new b.Segment],s,e;for(let d of this.edges){let i=l[0];[s,e]=b.Distance.shape2planarSet(d.shape,t.edges,i),b.Utils.LT(s,i)&&(l=[s,e])}return l}}intersect(t){if(t instanceof b.Point)return this.contains(t)?[t]:[];if(t instanceof b.Line)return ln(t,this);if(t instanceof b.Ray)return rd(t,this);if(t instanceof b.Circle)return bd(t,this);if(t instanceof b.Segment)return Jl(t,this);if(t instanceof b.Arc)return Il(t,this);if(t instanceof b.Polygon)return Po(t,this);if(t instanceof b.Multiline)return ko(t,this)}translate(t){let l=new Wt;for(let s of this.faces)l.addFace(s.shapes.map(e=>e.translate(t)));return l}rotate(t=0,l=new b.Point){let s=new Wt;for(let e of this.faces)s.addFace(e.shapes.map(d=>d.rotate(t,l)));return s}scale(t,l){let s=new Wt;for(let e of this.faces)s.addFace(e.shapes.map(d=>d.scale(t,l)));return s}transform(t=new b.Matrix){let l=new Wt;for(let s of this.faces)l.addFace(s.shapes.map(e=>e.transform(t)));return l}toJSON(){return[...this.faces].map(t=>t.toJSON())}toArray(){return[...this.faces].map(t=>t.toPolygon())}dpath(){return[...this.faces].reduce((t,l)=>t+l.svg(),"")}svg(t={}){let l=`
|
|
25
|
+
<path ${xt({fillRule:"evenodd",fill:"lightcyan",...t})} d="`;for(let s of this.faces)l+=`
|
|
26
26
|
${s.svg()}`;return l+=`" >
|
|
27
|
-
</path>`,l}};b.Polygon=
|
|
28
|
-
`).map(l=>l.match(/\(([^)]+)\)/)[1]).map(
|
|
29
|
-
`).map(l=>l.match(/\(([^)]+)\)/)[1]).map(
|
|
30
|
-
`)?.every(t=>t.includes("POINT"))}function
|
|
31
|
-
`)?.every(t=>t.includes("LINESTRING"))}function Ka(n){return n.startsWith("POINT")||Sd(n)||n.startsWith("LINESTRING")||zd(n)||n.startsWith("MULTILINESTRING")||n.startsWith("POLYGON")||n.startsWith("MULTIPOINT")||n.startsWith("MULTIPOLYGON")||n.startsWith("GEOMETRYCOLLECTION")}b.isWktString=Ka,b.parseWKT=Kd,b.BooleanOperations=tn,b.Relations=qo;const Sa=6378137,za=6378137,Ya=6356752314245179e-9;function Jn(n){return n}new N;function ga(n,t=[],l=Jn){return"longitude"in n?(t[0]=l(n.longitude),t[1]=l(n.latitude),t[2]=n.height):"x"in n?(t[0]=l(n.x),t[1]=l(n.y),t[2]=n.z):(t[0]=l(n[0]),t[1]=l(n[1]),t[2]=n[2]),t}function Ma(n,t=[]){return ga(n,t,B._cartographicRadians?Jn:Oi)}function Ta(n,t,l=Jn){return"longitude"in t?(t.longitude=l(n[0]),t.latitude=l(n[1]),t.height=n[2]):"x"in t?(t.x=l(n[0]),t.y=l(n[1]),t.z=n[2]):(t[0]=l(n[0]),t[1]=l(n[1]),t[2]=n[2]),t}function fa(n,t){return Ta(n,t,B._cartographicRadians?Jn:Di)}const Yd=1e-14,Ca=new N,gd={up:{south:"east",north:"west",west:"south",east:"north"},down:{south:"west",north:"east",west:"north",east:"south"},south:{up:"west",down:"east",west:"down",east:"up"},north:{up:"east",down:"west",west:"up",east:"down"},west:{up:"north",down:"south",north:"down",south:"up"},east:{up:"south",down:"north",north:"up",south:"down"}},wl={north:[-1,0,0],east:[0,1,0],up:[0,0,1],south:[1,0,0],west:[0,-1,0],down:[0,0,-1]},cn={east:new N,north:new N,up:new N,west:new N,south:new N,down:new N},Fa=new N,Na=new N,Ha=new N;function Md(n,t,l,s,e,d){const i=gd[t]&&gd[t][l];it(i&&(!s||s===i));let c,o,a;const X=Ca.copy(e);if(E(X.x,0,Yd)&&E(X.y,0,Yd)){const h=Math.sign(X.z);c=Fa.fromArray(wl[t]),t!=="east"&&t!=="west"&&c.scale(h),o=Na.fromArray(wl[l]),l!=="east"&&l!=="west"&&o.scale(h),a=Ha.fromArray(wl[s]),s!=="east"&&s!=="west"&&a.scale(h)}else{const{up:h,east:m,north:Z}=cn;m.set(-X.y,X.x,0).normalize(),n.geodeticSurfaceNormal(X,h),Z.copy(h).cross(m);const{down:p,west:G,south:W}=cn;p.copy(h).scale(-1),G.copy(m).scale(-1),W.copy(Z).scale(-1),c=cn[t],o=cn[l],a=cn[s]}return d[0]=c.x,d[1]=c.y,d[2]=c.z,d[3]=0,d[4]=o.x,d[5]=o.y,d[6]=o.z,d[7]=0,d[8]=a.x,d[9]=a.y,d[10]=a.z,d[11]=0,d[12]=X.x,d[13]=X.y,d[14]=X.z,d[15]=1,d}const vt=new N,Ja=new N,Ia=new N;function ka(n,t,l=[]){const{oneOverRadii:s,oneOverRadiiSquared:e,centerToleranceSquared:d}=t;vt.from(n);const i=vt.x,c=vt.y,o=vt.z,a=s.x,X=s.y,u=s.z,h=i*i*a*a,m=c*c*X*X,Z=o*o*u*u,p=h+m+Z,G=Math.sqrt(1/p);if(!Number.isFinite(G))return;const W=Ja;if(W.copy(n).scale(G),p<d)return W.to(l);const L=e.x,V=e.y,y=e.z,S=Ia;S.set(W.x*L*2,W.y*V*2,W.z*y*2);let R=(1-G)*vt.len()/(.5*S.len()),T=0,g,M,z,H;do{R-=T,g=1/(1+R*L),M=1/(1+R*V),z=1/(1+R*y);const J=g*g,I=M*M,f=z*z,O=J*g,Lt=I*M,xt=f*z;H=h*J+m*I+Z*f-1;const Un=-2*(h*O*L+m*Lt*V+Z*xt*y);T=H/Un}while(Math.abs(H)>so);return vt.scale([g,M,z]).to(l)}const In=new N,Td=new N,Pa=new N,A=new N,Qa=new N,kn=new N;class fd{constructor(t=0,l=0,s=0){this.centerToleranceSquared=lo,it(t>=0),it(l>=0),it(s>=0),this.radii=new N(t,l,s),this.radiiSquared=new N(t*t,l*l,s*s),this.radiiToTheFourth=new N(t*t*t*t,l*l*l*l,s*s*s*s),this.oneOverRadii=new N(t===0?0:1/t,l===0?0:1/l,s===0?0:1/s),this.oneOverRadiiSquared=new N(t===0?0:1/(t*t),l===0?0:1/(l*l),s===0?0:1/(s*s)),this.minimumRadius=Math.min(t,l,s),this.maximumRadius=Math.max(t,l,s),this.radiiSquared.z!==0&&(this.squaredXOverSquaredZ=this.radiiSquared.x/this.radiiSquared.z),Object.freeze(this)}equals(t){return this===t||!!(t&&this.radii.equals(t.radii))}toString(){return this.radii.toString()}cartographicToCartesian(t,l=[0,0,0]){const s=Td,e=Pa,[,,d]=t;this.geodeticSurfaceNormalCartographic(t,s),e.copy(this.radiiSquared).scale(s);const i=Math.sqrt(s.dot(e));return e.scale(1/i),s.scale(d),e.add(s),e.to(l)}cartesianToCartographic(t,l=[0,0,0]){kn.from(t);const s=this.scaleToGeodeticSurface(kn,A);if(!s)return;const e=this.geodeticSurfaceNormal(s,Td),d=Qa;d.copy(kn).subtract(s);const i=Math.atan2(e.y,e.x),c=Math.asin(e.z),o=Math.sign(Ut(d,kn))*Zn(d);return fa([i,c,o],l)}eastNorthUpToFixedFrame(t,l=new bt){return Md(this,"east","north","up",t,l)}localFrameToFixedFrame(t,l,s,e,d=new bt){return Md(this,t,l,s,e,d)}geocentricSurfaceNormal(t,l=[0,0,0]){return In.from(t).normalize().to(l)}geodeticSurfaceNormalCartographic(t,l=[0,0,0]){const s=Ma(t),e=s[0],d=s[1],i=Math.cos(d);return In.set(i*Math.cos(e),i*Math.sin(e),Math.sin(d)).normalize(),In.to(l)}geodeticSurfaceNormal(t,l=[0,0,0]){return In.from(t).scale(this.oneOverRadiiSquared).normalize().to(l)}scaleToGeodeticSurface(t,l){return ka(t,this,l)}scaleToGeocentricSurface(t,l=[0,0,0]){A.from(t);const s=A.x,e=A.y,d=A.z,i=this.oneOverRadiiSquared,c=1/Math.sqrt(s*s*i.x+e*e*i.y+d*d*i.z);return A.multiplyScalar(c).to(l)}transformPositionToScaledSpace(t,l=[0,0,0]){return A.from(t).scale(this.oneOverRadii).to(l)}transformPositionFromScaledSpace(t,l=[0,0,0]){return A.from(t).scale(this.radii).to(l)}getSurfaceNormalIntersectionWithZAxis(t,l=0,s=[0,0,0]){it(E(this.radii.x,this.radii.y,eo)),it(this.radii.z>0),A.from(t);const e=A.z*(1-this.squaredXOverSquaredZ);if(!(Math.abs(e)>=this.radii.z-l))return A.set(0,0,e).to(s)}}fd.WGS84=new fd(Sa,za,Ya);var Pn=(n=>(n[n.x=0]="x",n[n.y=1]="y",n[n.z=2]="z",n))(Pn||{});(n=>{function t(e){return n[e]}n.toKey=t;function l(e){return n[e]}n.toIndex=l;function s(e){const d=(e+1)%3,i=(e+2)%3;return[d,i]}n.getCrossAxiss=s})(Pn||(Pn={}));var Ul=(n=>(n[n.x=0]="x",n[n.y=1]="y",n[n.z=2]="z",n[n.w=3]="w",n))(Ul||{});(n=>{function t(e){return n[e]}n.toKey=t;function l(e){return n[e]}n.toIndex=l;function s(e){const d=(e+1)%4,i=(e+2)%4,c=(e+3)%4;return[d,i,c]}n.getCrossAxiss=s})(Ul||(Ul={}));var jl=(n=>(n[n.east=0]="east",n[n.west=1]="west",n[n.north=2]="north",n[n.south=3]="south",n[n.up=4]="up",n[n.down=5]="down",n))(jl||{});(n=>{function t(i){return n[i]}n.toKey=t;function l(i){return n[i]}n.toIndex=l;function s(i){return i%2===0?i+1:i-1}n.reverse=s;function e(i){return i%2===0?1:-1}n.getVectorSign=e;function d(i,c){let o=t(i),a=c[o];return a||(o=t(s(i)),a=c[o],a=a.map(X=>-X)),a}n.getVector=d})(jl||(jl={}));function lt(n){switch(n){case 2:return Mc;case 3:return c0;case 4:return fb;case 9:return z0;case 16:return db;default:throw new Error(`不支持获取命名空间: ${n}`)}}const va={4:"transformMat2",6:"transformMat2d",9:"transformMat3",16:"transformMat4"};function El(n,t){const l=lt(t),s=va[n],e=l[s];if(!e)throw new Error(`不支持的矩阵大小:${n}`);return e}const Ba={Array,Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array};var Ol=(n=>(n.Array="Array",n.Int8Array="Int8Array",n.Uint8Array="Uint8Array",n.Uint8ClampedArray="Uint8ClampedArray",n.Int16Array="Int16Array",n.Uint16Array="Uint16Array",n.Int32Array="Int32Array",n.Uint32Array="Uint32Array",n.Float32Array="Float32Array",n.Float64Array="Float64Array",n))(Ol||{});(n=>{function t(e){return Ba[e]}n.toClass=t;function l(e){return e.name}n.toType=l;function s(e){return e.constructor.name}n.toTypeByArray=s})(Ol||(Ol={}));var x=(n=>(n[n.ThroughIntersect=1]="ThroughIntersect",n[n.JointIntersect=2]="JointIntersect",n[n.Intersect=3]="Intersect",n[n.Tangency=4]="Tangency",n[n.Contain=8]="Contain",n[n.Dissociation=16]="Dissociation",n[n.AB=32]="AB",n[n.BA=64]="BA",n[n.ABContain=40]="ABContain",n[n.BAContain=72]="BAContain",n))(x||{});const wa={EPSILON:1e-12,debug:!1,precision:4,printTypes:!1,printDegrees:!1,printRowMajor:!0,_cartographicRadians:!1};globalThis.mathgl=globalThis.mathgl||{config:{...wa}},globalThis.mathgl.config;function Cd(n,t){return al(n,t),ol(n,n)}new dt,new N,new ct;const Qn=[new dt,new dt,new dt,new dt],Ua=[new N,new N,new N,new N],ja=[new ct,new ct,new ct,new ct],vn=[new zt,new zt,new zt,new zt],Ea=[new bt,new bt,new bt,new bt];new Yt,new Yt,new Yt,new Yt,new v,new v,new v,new v;function Dl(n){switch(n){case 2:return Qn;case 3:return Ua;case 4:return ja;case 9:return vn;case 16:return Ea;default:throw new Error(`不支持获取临时变量: ${n}`)}}function Oa(n,t){return n[0]=Math.hypot(t[0],t[1],t[2]),n[1]=Math.hypot(t[4],t[5],t[6]),n[2]=Math.hypot(t[8],t[9],t[10]),ml(t)<0&&(n[0]=-n[0]),n}function Da(n,t,l){Oa(n,l);const s=1/n[0],e=1/n[1],d=1/n[2];return t[0]=l[0]*s,t[1]=l[1]*e,t[2]=l[2]*d,t[3]=l[4]*s,t[4]=l[5]*e,t[5]=l[6]*d,t[6]=l[8]*s,t[7]=l[9]*e,t[8]=l[10]*d,t}function Aa(n,t,l){const s=Da(n,vn[0],l);return yl(t,s),t}function _a(n,t,l,s){return be(n,s),Aa(t,l,s),l}function st(n,t){const l=t.findIndex(e=>!E(e,0));if(l===-1)return 0;const s=n[l];return E(s,0)?1/0:t[l]/s}function Fd(n,t){const l=t.findIndex(e=>!E(e,0));if(l===-1)return!0;const s=n[l]/t[l];return Pn.getCrossAxiss(l).every(e=>E(t[e]*s,n[e]))}function qa(n,t){return E(Kt([],n,t)[2],0)}function $a(n,t){const l=lt(n.length).cross([],n,t);return Math.hypot(...l)}function tX(n,t){return Math.abs(nX(n,t))}function nX(n,t){return Kt([],n,t)[2]}function lX(n,t,l){const s=[...n,...t,...l];return Xl(s)}new N(1,1,1),new N(0,0,1);class Al{array;count=0;vectorSize;start=0;get end(){return this.start+this.count*this.vectorSize}set end(t){this.count=Math.trunc((t-this.start)/this.vectorSize)}constructor(t){t&&this.setOptions(t)}setOptions(t){const{end:l,count:s,...e}=t;Object.assign(this,e),l==null&&s==null?this.count=this.array.length/this.vectorSize:l!=null&&(this.end=l)}from(t){const{array:l,...s}=t;return this.setOptions({array:l.slice(),...s}),this}clone(){const t=new this.constructor;return t.from(this),t}copy(t){for(let l=0;l<this.count;l++)this.copyAt(l,t,l);return this}copyAt(t,l,s){const e=l.getVector(s);return this.setVector(t,e),this}copyArray(t){const l=this.start;for(let s=0,e=t.length;s<e;s++)this.array[l+s]=t[s];return this}getStartArrayIndex(t){return this.start+t*this.vectorSize}getArrayIndexRange(t){const l=this.start+t*this.vectorSize;return[l,l+this.vectorSize]}getVector(t){return this.array.slice(...this.getArrayIndexRange(t))}setVector(t,l,s=0){const e=this.getStartArrayIndex(t);for(let d=0,i=this.vectorSize;d<i;d++)this.array[e+d]=l[s+d];return s+this.vectorSize}toVectors(t=[]){const{start:l,end:s,vectorSize:e,array:d}=this;for(let i=l;i<s;i+=e){const c=d.slice(i,i+e);t.push(c)}return t}map(t,l=[]){for(let s=0;s<this.count;s++){const e=this.getVector(s);l[s]=t(e,s)}return l}mapSelf(t){for(let l=0;l<this.count;l++){const s=this.getVector(l),e=t(s,l);this.setVector(l,e)}return this}filter(t,l=[]){for(let s=0;s<this.count;s++){const e=this.getVector(s);if(t(e,s))for(const d of e)l[l.length]=d}return l}transform(t){const l=El(t.length,this.vectorSize);return this.mapSelf(s=>l(s,s,t))}transformAsNormal(t){const l=vn[0];t.length===16?rl(l,t):Cd(l,t);const s=El(l.length,this.vectorSize);return this.mapSelf(e=>s(e,e,l))}scale(t){const l=lt(this.vectorSize);return this.mapSelf(s=>l.scale(s,s,t))}scaleAndAdd(t,l){const s=lt(this.vectorSize);return this.mapSelf(e=>s.scaleAndAdd(e,e,t,l))}add(t){const l=lt(this.vectorSize);return this.mapSelf(s=>l.add(s,s,t))}subtract(t){const l=lt(this.vectorSize);return this.mapSelf(s=>l.subtract(s,s,t))}multiply(t){const l=lt(this.vectorSize);return this.mapSelf(s=>l.multiply(s,s,t))}divide(t){const l=lt(this.vectorSize);return this.mapSelf(s=>l.divide(s,s,t))}}function sX(n){return n.flatMap(t=>[...t])}class eX{array;attributes;count;constructor(t){t&&this.setOptions(t)}setOptions(t){const{attributes:l,array:s,count:e,...d}=t;Object.assign(this,d,{array:s,count:e});const i=this.attributes={};for(const[c,o]of Object.entries(l))i[c]=new Al({array:s,count:e,...o});return this}setVector(t,l,s,e){return this.attributes[t].setVector(l,s,e)}getVector(t,l){return this.attributes[t].getVector(l)}getVectors(t,l){return t.map(s=>this.attributes[s].getVector(l))}getAttribute(t){return this.attributes[t]}setAttribute(t,l){const{array:s,count:e}=this;return this.attributes[t]=new Al({array:s,...l,count:e})}getAggregateVector(t,l){const s=[];for(const e of t){const d=this.getVector(e,l);s.push(...d)}return s}setAggregateVector(t,l,s,e){if(t.length===1)return this.setVector(t[0],l,s,e);for(const d of t)e=this.setVector(d,l,s,e);return e}getAggregateVectorSize(t){if(t.length===1)return this.getAttribute(t[0]).vectorSize;let l=0;for(const s of t)l+=this.getAttribute(s).vectorSize;return l}createAggregateVectorGetter(t){if(t.length===1){const l=this.attributes[t[0]];return l.getVector.bind(l)}return this.getAggregateVector.bind(this,t)}createAggregateVectorSetter(t){if(t.length===1){const l=this.attributes[t[0]];return l.setVector.bind(l)}return this.setAggregateVector.bind(this,t)}map(t,l,s=[]){for(let e=0;e<this.count;e++){const d=this.getVectors(t,e);s[e]=l(d,e)}return s}mapForAggregate(t,l,s=[]){for(let e=0;e<this.count;e++){const d=this.getAggregateVector(t,e);s[e]=l(d,e)}return s}mapSelf(t,l){for(let s=0;s<this.count;s++){const e=this.getVectors(t,s),d=l(e,s);t.forEach((i,c)=>this.setVector(i,s,d[c]))}return this}mapSelfForAggregate(t,l){for(let s=0;s<this.count;s++){const e=this.getAggregateVector(t,s),d=l(e,s);this.setAggregateVector(t,s,d)}return this}filter(t,l,s=[]){for(let e=0;e<this.count;e++){const d=this.getVectors(t,e);l(d,e)&&s.push(d)}return s}filterForAggregate(t,l,s=[]){return this.filter(t,(e,d)=>l(sX(e),d),s)}transform(t,l){const s=vn[0];l.includes("normal")&&(t.length===16?rl(s,t):Cd(s,t));for(const e of l){const d=this.getAttribute(e);d&&(e==="normal"?d.transformAsNormal(s):d.transform(t))}return this}transformForAggregate(t,l){const s=this.getAggregateVectorSize(l),e=El(t.length,s);return this.mapSelfForAggregate(l,d=>e(d,d,t)),this}}class Nd extends eX{setOptions(t){const{indices:l,...s}=t;super.setOptions(s);const e=l.array?l:{array:l};return this.indices=new Al({count:e.array.length/3,vectorSize:3,...e}),this}getFaceVector(t,l){const s=this.indices.getVector(l);return Array.prototype.map.call(s,e=>this.getVector(t,e))}getFaceVectors(t,l){const s=this.indices.getVector(l);return Array.prototype.map.call(s,e=>this.getVectors(t,e))}getFaceAggregateVector(t,l){const s=this.indices.getVector(l);return Array.prototype.map.call(s,e=>this.getAggregateVector(t,e))}mapFace(t,l,s=[]){return this.indices.map((e,d)=>{const i=Array.prototype.map.call(e,c=>this.getVectors(t,c));return l(i,d,e)},s)}mapFaceForAggregate(t,l,s=[]){return this.indices.map((e,d)=>{const i=Array.prototype.map.call(e,c=>this.getAggregateVector(t,c));return l(i,d,e)},s)}filterFace(t,l,s=[]){return this.indices.filter((e,d)=>{const i=Array.prototype.map.call(e,c=>this.getVectors(t,c));return l(i,d,e)},s)}filterFaceForAggregate(t,l,s=[]){return this.indices.filter((e,d)=>{const i=Array.prototype.map.call(e,c=>this.getAggregateVector(t,c));return l(i,d,e)},s)}}function Hd(n,t){const l=_([],n[1],n[0]),s=_([],t,n[0]);return Kt(l,l,s),E(l[2],0)?0:l[2]}function dX(n,t){const[l,s]=n,[e,d]=Qn;if(e.subVectors(t,l),d.subVectors(s,l),qa(d,e)){const i=st(d,e);return i<0||i>1?x.Tangency:x.Contain}return x.Dissociation}function Jd(n,t){const[l,s]=n,[e,d]=t,[i,c,o]=Dl(l.length);return c.subVectors(s,l),o.subVectors(d,e),Fd(o,c)?(i.subVectors(e,l),Fd(i,c)?x.Tangency:x.Dissociation):x.Intersect}function iX(n,t,l){const[s,e]=t,[d,i]=l,[c,o,a]=Dl(s.length);c.subVectors(e,s),o.subVectors(i,d);const X=lt(s.length),u=X.cross([],c,o);if(E(X.squaredLength(u),0))return null;a.subVectors(d,s);const h=X.cross([],a,o),m=st(u,h);return X.scaleAndAdd(n,s,c,m)}function cX(n,t,l){const[s,e]=t,[d,i]=l,[c,o,a]=Qn;c.subVectors(e,s),o.subVectors(i,d);const X=Kt([],c,o)[2];if(E(X,0))return null;a.subVectors(d,s);const u=Kt([],a,o)[2]/X;return Rs(n,s,c,u)}function bX(n,t){const[l,s]=t,[e,d]=n,i=_([],d,e),c=Jd(n,t);if(c===x.Tangency){let u=0;return st(i,_([],l,e))<0&&u++,st(i,_([],s,e))<0&&u++,u===2?x.Dissociation:u===0?x.Contain:x.Tangency}if(c!==x.Intersect)return c;const o=cX([],n,t),a=_([],s,l),X=st(a,_([],o,l));return X<0||X>1||st(i,_([],o,e))<0?x.Dissociation:x.Intersect}function oX(n,t){const[l,s]=n,[e,d]=t,i=lt(l.length),c=i.subtract([],s,l),o=Jd(n,t);if(o===x.Tangency){let m=0,Z=0;const p=st(c,i.subtract([],e,l));p<0?m++:p>1&&Z++;const G=st(c,i.subtract([],d,l));return G<0?m++:G>1&&Z++,m===2||Z===2?x.Dissociation:m+Z===1?x.Tangency:x.Contain}if(o!==x.Intersect)return o;const a=iX([],n,t),X=i.subtract([],d,e),u=st(X,i.subtract([],a,e));if(u<0||u>1)return x.Dissociation;if(u===0||u===1)return x.JointIntersect;const h=st(c,i.subtract([],a,l));return h<0||h>1?x.Dissociation:h===0||h===1?x.JointIntersect:x.ThroughIntersect}function aX(n){const t=n.length;if(t<4)return!0;let l=0;for(let s=0;s<t;s++){const e=n.at(s-1),d=n.at((s+1)%t),i=Hd([e,n[s]],d);if(i!==0){if(l*i<0)return!1;l=i}}return!0}function rt(n,t){let l=0,s=!1;for(let e=0;e<n.length;e++){const d=n.at(e-1);if(ll(d,t))return x.Tangency;const i=Hd([d,n[e]],t);if(i===0){s=!0;continue}if(l*i<0)return x.Dissociation;l=i}return s?x.Tangency:x.Contain}function Id(n,t){const l=[t,[10,0]];ys(l[1],t,l[1]);const s=n.length;let e=0;for(let d=0;d<s;d++){const i=n[d];if(ll(i,t))return x.Tangency;let c=d+1;c===s&&(c=0);const o=n[c],a=[i,o];if(dX(a,t)===x.Contain)return x.Tangency;const X=bX(l,a);if(X===x.Contain){e+=2;continue}if(X===x.Intersect){let u=0;i[1]>t[1]&&u++,o[1]>t[1]&&u++,u===1&&e++}}return e%2===0?x.Dissociation:x.Contain}function kd(n,t){const l=n.length;let s=0;for(let c=0;c<l;c++){const o=n[c];let a=c+1;a===l&&(a=0);const X=n[a],u=oX([o,X],t);if(u&(x.ThroughIntersect|x.Tangency|x.Contain))return u;u===x.JointIntersect&&s++}const e=rt(n,t[0]);if(s===0||s===1&&e!==x.Tangency)return e;const d=rt(n,t[1]),i=e|d;return i===x.Tangency?x.Contain:i&x.Tangency?i&x.Contain?x.Contain:x.JointIntersect:e}function XX(n,t){const l=n.length;let s=0,e=!1;for(let c=0;c<l;c++){const o=n[c];let a=c+1;a===l&&(a=0);const X=n[a],u=kd(t,[o,X]);if(u===x.ThroughIntersect)return u;u===x.JointIntersect?s++:u===x.Tangency&&(e=!0)}let d=0;e?d|=x.Tangency:s&&(d|=x.JointIntersect);let i=n.some(c=>rt(t,c)===x.Contain);return i?x.BAContain|d:(i=t.some(c=>Id(n,c)===x.Contain),i?x.ABContain|d:n.some(c=>rt(t,c)===x.Dissociation)?x.Dissociation|d:d)}function uX(n,t){const l=n.length;let s=0,e=!1;for(let c=0;c<l;c++){const o=n[c];let a=c+1;a===l&&(a=0);const X=n[a],u=kd(t,[o,X]);if(u===x.ThroughIntersect)return u;u===x.JointIntersect?s++:u===x.Tangency&&(e=!0)}let d=0;e?d|=x.Tangency:s&&(d|=x.JointIntersect);let i=n.some(c=>rt(t,c)===x.Contain);return i?x.BAContain|d:(i=t.some(c=>rt(n,c)===x.Contain),i?x.ABContain|d:n.some(c=>rt(t,c)===x.Dissociation)?x.Dissociation|d:d)}function rX(n,t,l=["position"]){return n.mapForAggregate(l,s=>Id(t,s))}function hX(n,t,l=["position"]){return n.mapForAggregate(l,s=>rt(t,s))}function mX(n,t,l=["position"],s,e){const d=e?uX:XX;return s?s.map(function(i,c){const o=ZX(i);if(o!==null)return o&x.Contain?o|x.AB:o;const a=n.indices.getVector(c),X=Array.prototype.map.call(a,u=>n.getAggregateVector(l,u));return d(t,X)}):n.mapFace(l,i=>d(t,i))}const Pd=x.Dissociation|x.Contain;function ZX(n){return(n&Pd)===Pd?x.ThroughIntersect:n&x.Contain?n&x.Tangency?x.Contain|x.JointIntersect:x.Contain:null}function GX(n,t,l){const s=jt.getEqualFun(l),e=[];return n.forEach((d,i)=>{s(t,d)&&e.push(i)}),e}const pX=32767,_l=1/pX;function Qd(n,t){const[l,s,e]=WX(n,t);return[l,0,0,0,0,s,0,0,0,0,e,0,n.west,n.south,t[0],1]}function WX(n,t){const l=(n.east-n.west)*_l,s=(n.north-n.south)*_l,e=(t[1]-t[1])*_l;return[l,s,e]}function vd(n){return VX(n)/2}function VX(n){const t=n[0],l=[];for(let d=1;d<n.length;d++){const i=n[d],c=dl([],i,t);l.push(c)}const s=St([],l[1],l[0]);let e=Zn(s);Hs(s,s,1/e);for(let d=2;d<l.length;d++)e+=lX(l[d-1],l[d],s);return e}function yX(n,t,l){const[s,e]=Dl(n.length);return s.subVectors(t,n),e.subVectors(l,n),$a(s,e)}function LX(n,t,l){const[s,e]=Qn;return s.subVectors(t,n),e.subVectors(l,n),tX(s,e)}function Bd(n,t){const l=n.length-3;let s=0;for(let e=0;e<l;e+=3){const[d,i,c]=n.slice(e,e+3),o=t(d),a=t(i),X=t(c);s+=yX(o,a,X)}return s/2}function wd(n,t,l=[0,1/0]){const s=n.length-3,[e,d]=l,i=d-e;let c=0;const o=1/3;for(let a=0;a<s;a+=3){const[X,u,h]=n.slice(a,a+3),[m,Z,p]=t(X),[G,W,L]=t(u),[V,y,S]=t(h),R=LX([m,Z],[G,W],[V,y]),T=(p+L+S)*o-e;c+=R*Math.min(T,i)}return c/2}const Ud=["position"];class xX{constructor(t){t&&this.setOptions(t)}geometry;positionNames=Ud;region;relation;relationEqual;get includingThrough(){return this.relation&x.ThroughIntersect}setOptions(t){if(Object.assign(this,t),t.positionNames&&(this._getPosition=null),t.geometry||t.positionNames||t.region)return(t.geometry||t.positionNames)&&(this._geometryPolygon=null),this.update();if(t.relation||t.strict)return this._relationArea=null,this._relationVolume=null,this.updateRelationIndexs()}get geometryPolygon(){return this._geometryPolygon||(this._geometryPolygon=this.generateGeometryPolygon()),this._geometryPolygon}_geometryPolygon=null;generateGeometryPolygon(){const t=new en;return this.geometry.mapFaceForAggregate(this.positionNames,l=>{const s=l.map(e=>new Nn(e[0],e[1]));t.addFace(s)}),t}positionRelations;faceRelations;relationIndexsWithoutThrougn;get throughIndexs(){return this._throughIndexs}set throughIndexs(t){this._throughIndexs=t,this._throughFaces=null,this._throughFaceAreas=null}_throughIndexs=[];get throughFaces(){return this._throughFaces||(this._throughFaces=this.generateThroughFaces()),this._throughFaces}_throughFaces=null;get throughFaceAreas(){return this._throughFaceAreas||(this._throughFaceAreas=this.generateThroughFaceAreas()),this._throughFaceAreas}_throughFaceAreas=null;generateThroughFaceAreas(){return this.throughFaces.map(t=>t.area())}update(){this.updatePositionRelations(),this.updateFaceRelations(),this.updateRelationIndexs(),this.includingThrough&&this.updateThroughIndexs(),this.resetMeasure()}updatePositionRelations(){this.positionRelations=this.generatePositionRelations()}updateFaceRelations(){this.faceRelations=this.generateFaceRelations()}updateRelationIndexs(){const t=~x.ThroughIntersect&this.relation;this.relationIndexsWithoutThrougn=this.filterFaces(t,this.relationEqual)}updateThroughIndexs(){this.throughIndexs=this.filterFaces(x.ThroughIntersect,jt.equal),this._throughFaces=null,this._throughFaceAreas=null}resetMeasure(){this._relationArea=null,this._relationVolume=null,this._area=null,this._volume=null}updateMeasure(){this.resetMeasure(),this.relationArea,this.relationVolume,this.area,this.volume}_getPosition=null;get getPosition(){return this._getPosition||(this._getPosition=this.geometry.createAggregateVectorGetter(this.positionNames))}get relationArea(){return this._relationArea==null&&(this._relationArea=this.computeRelationArea()),this._relationArea}_relationArea=null;computeRelationArea(){const{geometry:t}=this,l=this.relationIndexsWithoutThrougn.flatMap(e=>[...t.indices.getVector(e)]);let s=Bd(l,this.getPosition);if(this.includingThrough)for(const e of this.throughFaceAreas)s+=e;return s}get area(){return this._area==null&&(this._area=this.computeArea()),this._area}_area=null;computeArea(){return Bd(this.geometry.indices.array,this.getPosition)}get relationVolume(){return this._relationVolume==null&&(this._relationVolume=this.computeRelationTerrainVolume()),this._relationVolume}_relationVolume=null;computeRelationTerrainVolume(t=[0,1/0]){const{geometry:l}=this,s=this.relationIndexsWithoutThrougn.flatMap(d=>[...l.indices.getVector(d)]);let e=wd(s,this.getPosition,t);if(this.includingThrough){const[d,i]=t,c=i-d;let o=0;const a=1/3,{geometry:X,positionNames:u}=this;this.throughFaceAreas.forEach((h,m)=>{const Z=this.throughIndexs[m],[p,G,W]=X.getFaceAggregateVector(u,Z),L=(p[2]+G[2]+W[2])*a-d;L<=0||(o+=h*Math.min(L,c))}),o/=2,e+=o}return e}get volume(){return this._volume==null&&(this._volume=this.computeTerrainVolume([-1/0,1/0])),this._volume}_volume=null;computeTerrainVolume(t){return wd(this.geometry.indices.array,this.getPosition,t)}}class RX extends xX{get isConvex(){return this._isConvex==null&&(this._isConvex=aX(this.region)),this._isConvex}set isConvex(t){this._isConvex=t}_isConvex=null;setOptions(t){if(t.region){const l=t.region.map(s=>new Nn(s));this.polygon=new en(l),this.isZeroPolygon=this.polygon.area()===0}super.setOptions(t)}resetMeasure(){super.resetMeasure(),this._polygonOutsideGeometry=null}generatePositionRelations(){return this.isConvex?hX(this.geometry,this.region,this.positionNames):rX(this.geometry,this.region,this.positionNames)}generateFaceRelations(){return mX(this.geometry,this.region,this.positionNames,this.positionRelations,this.isConvex)}generateThroughFaces(){const{geometry:t,polygon:l}=this,s=this.relation&x.Contain;let e=s?tn.intersect:tn.subtract;return this.isZeroPolygon&&(e=s?(d,i)=>l:(d,i)=>d),this.throughIndexs.map(d=>{const i=t.getFaceAggregateVector(this.positionNames,d).map(o=>new Nn(o[0],o[1])),c=new en(i);return e(c,l)})}filterFaces(t,l){return GX(this.faceRelations,t,l)}get polygonOutsideGeometry(){return this._polygonOutsideGeometry==null&&(this._polygonOutsideGeometry=this.isZeroPolygon?this.polygon:tn.subtract(this.polygon,this.geometryPolygon)),this._polygonOutsideGeometry}_polygonOutsideGeometry=null}function KX(n){const{west:t,east:l,south:s,north:e}=n;return[new dt(t,s),new dt(t,e),new dt(l,e),new dt(l,s)]}function SX(n){const{rectangle:t,heightRange:l,positionNames:s=Ud,scale:e}=n,d=new Nd(n),i=Qd(t,l);d.transformForAggregate(i,s);const c=new RX({...n,geometry:d}),o=KX(t),a=new en(o),X=tn.subtract(a,c.geometryPolygon),u=c.relationArea+X.area();if(!e)return u;const h=Math.hypot(e[0],e[2])*e[1];return u*Math.abs(h)}function zX(n){return new Worker(""+new URL("data:text/javascript;base64,KGZ1bmN0aW9uKCl7InVzZSBzdHJpY3QiO2Z1bmN0aW9uIEVjKGUpe3ZhciB0PWU7cmV0dXJuIGUhPW51bGwmJih0PWUuY29uc3RydWN0b3IsdD09bnVsbCYmKHQ9dHlwZW9mIGUpKSx0fXZhciBPbj0oZT0+KGUuZXF1YWw9ImVxdWFsIixlLmludGVyc2VjdD0iaW50ZXJzZWN0IixlLmludGVyc2VjdEVxdWFsPSJpbnRlcnNlY3RFcXVhbCIsZSkpKE9ufHx7fSk7KGU9PntmdW5jdGlvbiB0KG4pe2xldCByO3N3aXRjaChuKXtjYXNlImVxdWFsIjpyPShpLHMpPT5pPT09cztjYXNlImludGVyc2VjdCI6cj0oaSxzKT0+aSZzO2RlZmF1bHQ6cj0oaSxzKT0+KGkmcyk9PT1pfXJldHVybiByfWUuZ2V0RXF1YWxGdW49dH0pKE9ufHwoT249e30pKTtmdW5jdGlvbiBlaSgpe2NvbnN0IGU9Z2xvYmFsVGhpcy5jdXJyZW50V29ya2VyVHlwZTtpZihlKXJldHVybiBlO2xldCB0PWdsb2JhbFRoaXMuU2hhcmVkV29ya2VyR2xvYmFsU2NvcGU7cmV0dXJuIHR5cGVvZiB0PT0iZnVuY3Rpb24iJiZnbG9iYWxUaGlzIGluc3RhbmNlb2YgdD9nbG9iYWxUaGlzLmN1cnJlbnRXb3JrZXJUeXBlPSJTaGFyZWRXb3JrZXIiOih0PWdsb2JhbFRoaXMuRGVkaWNhdGVkV29ya2VyR2xvYmFsU2NvcGUsdHlwZW9mIHQ9PSJmdW5jdGlvbiImJmdsb2JhbFRoaXMgaW5zdGFuY2VvZiB0P2dsb2JhbFRoaXMuY3VycmVudFdvcmtlclR5cGU9IkRlZGljYXRlZFdvcmtlciI6KHQ9Z2xvYmFsVGhpcy5XaW5kb3csdHlwZW9mIHQ9PSJmdW5jdGlvbiImJmdsb2JhbFRoaXMgaW5zdGFuY2VvZiB0P2dsb2JhbFRoaXMuY3VycmVudFdvcmtlclR5cGU9IldpbmRvdyI6Z2xvYmFsVGhpcy5jdXJyZW50V29ya2VyVHlwZT0idW5rbm93biIpKX1mdW5jdGlvbiBPYyhlLHQsbil7Y29uc3Qgcj0vKF5ccyooYXN5bmNccyspP2Z1bmN0aW9uXHMqKFxzfFwqKVxzKilbQS1aYS16XyRdK1tcdyRdKihccypcKCkvLGk9L15bQS1aYS16XyRdK1tcdyRdKiQvLHM9ci50ZXN0KGUpLG89dCYmaS50ZXN0KHQpO2lmKHMmJm8mJihlPWUucmVwbGFjZShyLGAkMSR7dH0kNGApKSwhcyYmbyl2YXIgYz1gdmFyICR7dH0gPSAke2V9IDsgcmV0dXJuICR7dH1gO2Vsc2UgYz1gcmV0dXJuICgke2V9KWA7cmV0dXJuIG5ldyBGdW5jdGlvbihjKSgpfWZ1bmN0aW9uIG5pKGUpe2NvbnN0e25hbWU6dCxhcmdzOm4sdGhpczpyfT1lLGk9cj8/Z2xvYmFsVGhpcyxzPWdsb2JhbFRoaXNbdF07cmV0dXJuIHR5cGVvZiBzPT0iZnVuY3Rpb24iP3MuYXBwbHkoaSxuKTpufHxyP3tlcnJvcjoi5Ye95pWw5LiN5a2Y5ZyoIixzdGF0ZToi57uT5p2fIn06e2RhdGE6cyxzdGF0ZToi57uT5p2fIn19ZnVuY3Rpb24gcmkoZSl7Y29uc3QgdD1FYyhlKTtpZih0PT09Im9iamVjdCJ8fHQ9PT1PYmplY3Qpe2NvbnN0e3RyYW5zZmVyOm4sdGFyZ2V0T3JpZ2luOnJ9PWU7cmV0dXJuImRhdGEiaW4gZXx8ImVycm9yImluIGV8fEFycmF5LmlzQXJyYXkobil8fHR5cGVvZiByPT0ic3RyaW5nIn1yZXR1cm4hMX1mdW5jdGlvbiBOZShlLHQpe2NvbnN0e2RhdGE6biwuLi5yfT1yaShlKT9lOntkYXRhOmV9LGk9ey4uLnQsLi4ucn07aWYobiBpbnN0YW5jZW9mIFJlYWRhYmxlU3RyZWFtKXtjb25zdCBzPW5ldyBXcml0YWJsZVN0cmVhbSh7d3JpdGU6ZnVuY3Rpb24obyxjKXtyZXR1cm4gTmUobyx7Li4uaSxzdGF0ZToi6L+b6KGM5LitIn0pfSxjbG9zZTpmdW5jdGlvbihvKXt6ZSh2b2lkIDAse3N0YXRlOiLnu5PmnZ8iLC4uLml9KX0sYWJvcnQ6ZnVuY3Rpb24obyl7emUodm9pZCAwLHtzdGF0ZToi57uT5p2fIiwuLi5pLGVycm9yOm99KX19KTtyZXR1cm4gbi5waXBlVG8ocyl9cmV0dXJuIG4gaW5zdGFuY2VvZiBQcm9taXNlP24udGhlbihmdW5jdGlvbihzKXtOZShzLHtzdGF0ZToi57uT5p2fIiwuLi5pfSl9LGZ1bmN0aW9uKHMpe3plKHZvaWQgMCx7Li4uaSxlcnJvcjpzLHN0YXRlOiLnu5PmnZ8ifSl9KTp6ZShuLHtzdGF0ZToi57uT5p2fIiwuLi5pfSl9ZnVuY3Rpb24gemUoZSx0KXtjb25zdHtwb3J0Om4sLi4ucn09dCx7dHJhbnNmZXI6aSx0YXJnZXRPcmlnaW46cywuLi5vfT1yaShlKT97Li4uciwuLi5lfTp7Li4ucixkYXRhOmV9O28uc3RhdGU9PW51bGwmJihvLnN0YXRlPSLnu5PmnZ8iKTtjb25zdCBjPXt0cmFuc2ZlcjppLHRhcmdldE9yaWdpbjpzfTtyZXR1cm4obj8/Z2xvYmFsVGhpcykucG9zdE1lc3NhZ2UobyxjKX1mdW5jdGlvbiBpaShlKXtjb25zdCB0PWUuZGF0YSxuPWUuY3VycmVudFRhcmdldDtpZih0KXtjb25zdCByPW5pKHQpO05lKHIse2V4ZWNJZDp0LmlkLHBvcnQ6bn0pfX1mdW5jdGlvbiBiYyhlLHQpe2NvbnN0IG49T2MoZSx0KTtyZXR1cm4gdD10Pz9uLm5hbWUsZ2xvYmFsVGhpc1t0XT1uLCEwfWZ1bmN0aW9uIEljKGUpe3JldHVybiBkZWxldGUgZ2xvYmFsVGhpc1tlXX1mdW5jdGlvbiBTYyhlKXtzd2l0Y2goZWkoKSl7Y2FzZSJTaGFyZWRXb3JrZXIiOntnbG9iYWxUaGlzLmFkZEV2ZW50TGlzdGVuZXIoImNvbm5lY3QiLGZ1bmN0aW9uKHQpe2Zvcihjb25zdCBuIG9mIHQucG9ydHMpbi5hZGRFdmVudExpc3RlbmVyKCJtZXNzYWdlIixlKSxuLnN0YXJ0KCl9KTticmVha31kZWZhdWx0Omdsb2JhbFRoaXMuYWRkRXZlbnRMaXN0ZW5lcigibWVzc2FnZSIsZSl9fWdsb2JhbFRoaXMubGlzdGVuTWVzc2FnZXx8KGdsb2JhbFRoaXMubGlzdGVuTWVzc2FnZT1TYyksT2JqZWN0LmFzc2lnbihnbG9iYWxUaGlzLHtleGVjQ01EOm5pLG1lc3NhZ2VMaXN0ZW5lcjppaSxzZXRDTUQ6YmMscmVtb3ZlQ01EOkljLHNlbmRNZXNzYWdlOk5lfSksZWkoKSxsaXN0ZW5NZXNzYWdlKGlpKTt2YXIgd3Q9KGU9PihlW2UueD0wXT0ieCIsZVtlLnk9MV09InkiLGVbZS56PTJdPSJ6IixlKSkod3R8fHt9KTsoZT0+e2Z1bmN0aW9uIHQoaSl7cmV0dXJuIGVbaV19ZS50b0tleT10O2Z1bmN0aW9uIG4oaSl7cmV0dXJuIGVbaV19ZS50b0luZGV4PW47ZnVuY3Rpb24gcihpKXtjb25zdCBzPShpKzEpJTMsbz0oaSsyKSUzO3JldHVybltzLG9dfWUuZ2V0Q3Jvc3NBeGlzcz1yfSkod3R8fCh3dD17fSkpO3ZhciAkZT0oZT0+KGVbZS54PTBdPSJ4IixlW2UueT0xXT0ieSIsZVtlLno9Ml09InoiLGVbZS53PTNdPSJ3IixlKSkoJGV8fHt9KTsoZT0+e2Z1bmN0aW9uIHQoaSl7cmV0dXJuIGVbaV19ZS50b0tleT10O2Z1bmN0aW9uIG4oaSl7cmV0dXJuIGVbaV19ZS50b0luZGV4PW47ZnVuY3Rpb24gcihpKXtjb25zdCBzPShpKzEpJTQsbz0oaSsyKSU0LGM9KGkrMyklNDtyZXR1cm5bcyxvLGNdfWUuZ2V0Q3Jvc3NBeGlzcz1yfSkoJGV8fCgkZT17fSkpO3ZhciBmdD0oZT0+KGVbZS5lYXN0PTBdPSJlYXN0IixlW2Uud2VzdD0xXT0id2VzdCIsZVtlLm5vcnRoPTJdPSJub3J0aCIsZVtlLnNvdXRoPTNdPSJzb3V0aCIsZVtlLnVwPTRdPSJ1cCIsZVtlLmRvd249NV09ImRvd24iLGUpKShmdHx8e30pOyhlPT57ZnVuY3Rpb24gdChvKXtyZXR1cm4gZVtvXX1lLnRvS2V5PXQ7ZnVuY3Rpb24gbihvKXtyZXR1cm4gZVtvXX1lLnRvSW5kZXg9bjtmdW5jdGlvbiByKG8pe3JldHVybiBvJTI9PT0wP28rMTpvLTF9ZS5yZXZlcnNlPXI7ZnVuY3Rpb24gaShvKXtyZXR1cm4gbyUyPT09MD8xOi0xfWUuZ2V0VmVjdG9yU2lnbj1pO2Z1bmN0aW9uIHMobyxjKXtsZXQgbD10KG8pLGg9Y1tsXTtyZXR1cm4gaHx8KGw9dChyKG8pKSxoPWNbbF0saD1oLm1hcChmPT4tZikpLGh9ZS5nZXRWZWN0b3I9c30pKGZ0fHwoZnQ9e30pKTtjb25zdCBQYz0xL01hdGguUEkqMTgwLExjPTEvMTgwKk1hdGguUEksUmM9e0VQU0lMT046MWUtMTIsZGVidWc6ITEscHJlY2lzaW9uOjQscHJpbnRUeXBlczohMSxwcmludERlZ3JlZXM6ITEscHJpbnRSb3dNYWpvcjohMCxfY2FydG9ncmFwaGljUmFkaWFuczohMX07Z2xvYmFsVGhpcy5tYXRoZ2w9Z2xvYmFsVGhpcy5tYXRoZ2x8fHtjb25maWc6ey4uLlJjfX07Y29uc3QgRz1nbG9iYWxUaGlzLm1hdGhnbC5jb25maWc7ZnVuY3Rpb24gQ2MoZSx7cHJlY2lzaW9uOnQ9Ry5wcmVjaXNpb259PXt9KXtyZXR1cm4gZT0kYyhlKSxgJHtwYXJzZUZsb2F0KGUudG9QcmVjaXNpb24odCkpfWB9ZnVuY3Rpb24gUnQoZSl7cmV0dXJuIEFycmF5LmlzQXJyYXkoZSl8fEFycmF5QnVmZmVyLmlzVmlldyhlKSYmIShlIGluc3RhbmNlb2YgRGF0YVZpZXcpfWZ1bmN0aW9uIGNlKGUpe3JldHVybiBOYyhlKX1mdW5jdGlvbiBWYyhlKXtyZXR1cm4gemMoZSl9ZnVuY3Rpb24gTmMoZSx0KXtyZXR1cm4gYm4oZSxuPT5uKkxjLHQpfWZ1bmN0aW9uIHpjKGUsdCl7cmV0dXJuIGJuKGUsbj0+bipQYyx0KX1mdW5jdGlvbiBDdChlLHQsbil7cmV0dXJuIGJuKGUscj0+TWF0aC5tYXgodCxNYXRoLm1pbihuLHIpKSl9ZnVuY3Rpb24gayhlLHQsbil7Y29uc3Qgcj1HLkVQU0lMT047biYmKEcuRVBTSUxPTj1uKTt0cnl7aWYoZT09PXQpcmV0dXJuITA7aWYoUnQoZSkmJlJ0KHQpKXtpZihlLmxlbmd0aCE9PXQubGVuZ3RoKXJldHVybiExO2ZvcihsZXQgaT0wO2k8ZS5sZW5ndGg7KytpKWlmKCFrKGVbaV0sdFtpXSkpcmV0dXJuITE7cmV0dXJuITB9cmV0dXJuIGUmJmUuZXF1YWxzP2UuZXF1YWxzKHQpOnQmJnQuZXF1YWxzP3QuZXF1YWxzKGUpOnR5cGVvZiBlPT0ibnVtYmVyIiYmdHlwZW9mIHQ9PSJudW1iZXIiP01hdGguYWJzKGUtdCk8PUcuRVBTSUxPTipNYXRoLm1heCgxLE1hdGguYWJzKGUpLE1hdGguYWJzKHQpKTohMX1maW5hbGx5e0cuRVBTSUxPTj1yfX1mdW5jdGlvbiAkYyhlKXtyZXR1cm4gTWF0aC5yb3VuZChlL0cuRVBTSUxPTikqRy5FUFNJTE9OfWZ1bmN0aW9uIGtjKGUpe3JldHVybiBlLmNsb25lP2UuY2xvbmUoKTpuZXcgQXJyYXkoZS5sZW5ndGgpfWZ1bmN0aW9uIGJuKGUsdCxuKXtpZihSdChlKSl7Y29uc3Qgcj1lO249bnx8a2Mocik7Zm9yKGxldCBpPTA7aTxuLmxlbmd0aCYmaTxyLmxlbmd0aDsrK2kpe2NvbnN0IHM9dHlwZW9mIGU9PSJudW1iZXIiP2U6ZVtpXTtuW2ldPXQocyxpLG4pfXJldHVybiBufXJldHVybiB0KGUpfWNsYXNzIGFlIGV4dGVuZHMgQXJyYXl7Y2xvbmUoKXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IoKS5jb3B5KHRoaXMpfWZyb21BcnJheSh0LG49MCl7Zm9yKGxldCByPTA7cjx0aGlzLkVMRU1FTlRTOysrcil0aGlzW3JdPXRbcituXTtyZXR1cm4gdGhpcy5jaGVjaygpfXRvQXJyYXkodD1bXSxuPTApe2ZvcihsZXQgcj0wO3I8dGhpcy5FTEVNRU5UUzsrK3IpdFtuK3JdPXRoaXNbcl07cmV0dXJuIHR9dG9PYmplY3QodCl7cmV0dXJuIHR9ZnJvbSh0KXtyZXR1cm4gQXJyYXkuaXNBcnJheSh0KT90aGlzLmNvcHkodCk6dGhpcy5mcm9tT2JqZWN0KHQpfXRvKHQpe3JldHVybiB0PT09dGhpcz90aGlzOlJ0KHQpP3RoaXMudG9BcnJheSh0KTp0aGlzLnRvT2JqZWN0KHQpfXRvVGFyZ2V0KHQpe3JldHVybiB0P3RoaXMudG8odCk6dGhpc310b0Zsb2F0MzJBcnJheSgpe3JldHVybiBuZXcgRmxvYXQzMkFycmF5KHRoaXMpfXRvU3RyaW5nKCl7cmV0dXJuIHRoaXMuZm9ybWF0U3RyaW5nKEcpfWZvcm1hdFN0cmluZyh0KXtsZXQgbj0iIjtmb3IobGV0IHI9MDtyPHRoaXMuRUxFTUVOVFM7KytyKW4rPShyPjA/IiwgIjoiIikrQ2ModGhpc1tyXSx0KTtyZXR1cm5gJHt0LnByaW50VHlwZXM/dGhpcy5jb25zdHJ1Y3Rvci5uYW1lOiIifVske259XWB9ZXF1YWxzKHQpe2lmKCF0fHx0aGlzLmxlbmd0aCE9PXQubGVuZ3RoKXJldHVybiExO2ZvcihsZXQgbj0wO248dGhpcy5FTEVNRU5UUzsrK24paWYoIWsodGhpc1tuXSx0W25dKSlyZXR1cm4hMTtyZXR1cm4hMH1leGFjdEVxdWFscyh0KXtpZighdHx8dGhpcy5sZW5ndGghPT10Lmxlbmd0aClyZXR1cm4hMTtmb3IobGV0IG49MDtuPHRoaXMuRUxFTUVOVFM7KytuKWlmKHRoaXNbbl0hPT10W25dKXJldHVybiExO3JldHVybiEwfW5lZ2F0ZSgpe2ZvcihsZXQgdD0wO3Q8dGhpcy5FTEVNRU5UUzsrK3QpdGhpc1t0XT0tdGhpc1t0XTtyZXR1cm4gdGhpcy5jaGVjaygpfWxlcnAodCxuLHIpe2lmKHI9PT12b2lkIDApcmV0dXJuIHRoaXMubGVycCh0aGlzLHQsbik7Zm9yKGxldCBpPTA7aTx0aGlzLkVMRU1FTlRTOysraSl7Y29uc3Qgcz10W2ldLG89dHlwZW9mIG49PSJudW1iZXIiP246bltpXTt0aGlzW2ldPXMrciooby1zKX1yZXR1cm4gdGhpcy5jaGVjaygpfW1pbih0KXtmb3IobGV0IG49MDtuPHRoaXMuRUxFTUVOVFM7KytuKXRoaXNbbl09TWF0aC5taW4odFtuXSx0aGlzW25dKTtyZXR1cm4gdGhpcy5jaGVjaygpfW1heCh0KXtmb3IobGV0IG49MDtuPHRoaXMuRUxFTUVOVFM7KytuKXRoaXNbbl09TWF0aC5tYXgodFtuXSx0aGlzW25dKTtyZXR1cm4gdGhpcy5jaGVjaygpfWNsYW1wKHQsbil7Zm9yKGxldCByPTA7cjx0aGlzLkVMRU1FTlRTOysrcil0aGlzW3JdPU1hdGgubWluKE1hdGgubWF4KHRoaXNbcl0sdFtyXSksbltyXSk7cmV0dXJuIHRoaXMuY2hlY2soKX1hZGQoLi4udCl7Zm9yKGNvbnN0IG4gb2YgdClmb3IobGV0IHI9MDtyPHRoaXMuRUxFTUVOVFM7KytyKXRoaXNbcl0rPW5bcl07cmV0dXJuIHRoaXMuY2hlY2soKX1zdWJ0cmFjdCguLi50KXtmb3IoY29uc3QgbiBvZiB0KWZvcihsZXQgcj0wO3I8dGhpcy5FTEVNRU5UUzsrK3IpdGhpc1tyXS09bltyXTtyZXR1cm4gdGhpcy5jaGVjaygpfXNjYWxlKHQpe2lmKHR5cGVvZiB0PT0ibnVtYmVyIilmb3IobGV0IG49MDtuPHRoaXMuRUxFTUVOVFM7KytuKXRoaXNbbl0qPXQ7ZWxzZSBmb3IobGV0IG49MDtuPHRoaXMuRUxFTUVOVFMmJm48dC5sZW5ndGg7KytuKXRoaXNbbl0qPXRbbl07cmV0dXJuIHRoaXMuY2hlY2soKX1tdWx0aXBseUJ5U2NhbGFyKHQpe2ZvcihsZXQgbj0wO248dGhpcy5FTEVNRU5UUzsrK24pdGhpc1tuXSo9dDtyZXR1cm4gdGhpcy5jaGVjaygpfWNoZWNrKCl7aWYoRy5kZWJ1ZyYmIXRoaXMudmFsaWRhdGUoKSl0aHJvdyBuZXcgRXJyb3IoYG1hdGguZ2w6ICR7dGhpcy5jb25zdHJ1Y3Rvci5uYW1lfSBzb21lIGZpZWxkcyBzZXQgdG8gaW52YWxpZCBudW1iZXJzJ2ApO3JldHVybiB0aGlzfXZhbGlkYXRlKCl7bGV0IHQ9dGhpcy5sZW5ndGg9PT10aGlzLkVMRU1FTlRTO2ZvcihsZXQgbj0wO248dGhpcy5FTEVNRU5UUzsrK24pdD10JiZOdW1iZXIuaXNGaW5pdGUodGhpc1tuXSk7cmV0dXJuIHR9c3ViKHQpe3JldHVybiB0aGlzLnN1YnRyYWN0KHQpfXNldFNjYWxhcih0KXtmb3IobGV0IG49MDtuPHRoaXMuRUxFTUVOVFM7KytuKXRoaXNbbl09dDtyZXR1cm4gdGhpcy5jaGVjaygpfWFkZFNjYWxhcih0KXtmb3IobGV0IG49MDtuPHRoaXMuRUxFTUVOVFM7KytuKXRoaXNbbl0rPXQ7cmV0dXJuIHRoaXMuY2hlY2soKX1zdWJTY2FsYXIodCl7cmV0dXJuIHRoaXMuYWRkU2NhbGFyKC10KX1tdWx0aXBseVNjYWxhcih0KXtmb3IobGV0IG49MDtuPHRoaXMuRUxFTUVOVFM7KytuKXRoaXNbbl0qPXQ7cmV0dXJuIHRoaXMuY2hlY2soKX1kaXZpZGVTY2FsYXIodCl7cmV0dXJuIHRoaXMubXVsdGlwbHlCeVNjYWxhcigxL3QpfWNsYW1wU2NhbGFyKHQsbil7Zm9yKGxldCByPTA7cjx0aGlzLkVMRU1FTlRTOysrcil0aGlzW3JdPU1hdGgubWluKE1hdGgubWF4KHRoaXNbcl0sdCksbik7cmV0dXJuIHRoaXMuY2hlY2soKX1nZXQgZWxlbWVudHMoKXtyZXR1cm4gdGhpc319ZnVuY3Rpb24gRmMoZSx0KXtpZihlLmxlbmd0aCE9PXQpcmV0dXJuITE7Zm9yKGxldCBuPTA7bjxlLmxlbmd0aDsrK24paWYoIU51bWJlci5pc0Zpbml0ZShlW25dKSlyZXR1cm4hMTtyZXR1cm4hMH1mdW5jdGlvbiBSKGUpe2lmKCFOdW1iZXIuaXNGaW5pdGUoZSkpdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIG51bWJlciAke0pTT04uc3RyaW5naWZ5KGUpfWApO3JldHVybiBlfWZ1bmN0aW9uIGxlKGUsdCxuPSIiKXtpZihHLmRlYnVnJiYhRmMoZSx0KSl0aHJvdyBuZXcgRXJyb3IoYG1hdGguZ2w6ICR7bn0gc29tZSBmaWVsZHMgc2V0IHRvIGludmFsaWQgbnVtYmVycydgKTtyZXR1cm4gZX1mdW5jdGlvbiBidChlLHQpe2lmKCFlKXRocm93IG5ldyBFcnJvcihgbWF0aC5nbCBhc3NlcnRpb24gJHt0fWApfWxldCBrZT1jbGFzcyBleHRlbmRzIGFle2dldCB4KCl7cmV0dXJuIHRoaXNbMF19c2V0IHgodCl7dGhpc1swXT1SKHQpfWdldCB5KCl7cmV0dXJuIHRoaXNbMV19c2V0IHkodCl7dGhpc1sxXT1SKHQpfWxlbigpe3JldHVybiBNYXRoLnNxcnQodGhpcy5sZW5ndGhTcXVhcmVkKCkpfW1hZ25pdHVkZSgpe3JldHVybiB0aGlzLmxlbigpfWxlbmd0aFNxdWFyZWQoKXtsZXQgdD0wO2ZvcihsZXQgbj0wO248dGhpcy5FTEVNRU5UUzsrK24pdCs9dGhpc1tuXSp0aGlzW25dO3JldHVybiB0fW1hZ25pdHVkZVNxdWFyZWQoKXtyZXR1cm4gdGhpcy5sZW5ndGhTcXVhcmVkKCl9ZGlzdGFuY2UodCl7cmV0dXJuIE1hdGguc3FydCh0aGlzLmRpc3RhbmNlU3F1YXJlZCh0KSl9ZGlzdGFuY2VTcXVhcmVkKHQpe2xldCBuPTA7Zm9yKGxldCByPTA7cjx0aGlzLkVMRU1FTlRTOysrcil7Y29uc3QgaT10aGlzW3JdLXRbcl07bis9aSppfXJldHVybiBSKG4pfWRvdCh0KXtsZXQgbj0wO2ZvcihsZXQgcj0wO3I8dGhpcy5FTEVNRU5UUzsrK3Ipbis9dGhpc1tyXSp0W3JdO3JldHVybiBSKG4pfW5vcm1hbGl6ZSgpe2NvbnN0IHQ9dGhpcy5tYWduaXR1ZGUoKTtpZih0IT09MClmb3IobGV0IG49MDtuPHRoaXMuRUxFTUVOVFM7KytuKXRoaXNbbl0vPXQ7cmV0dXJuIHRoaXMuY2hlY2soKX1tdWx0aXBseSguLi50KXtmb3IoY29uc3QgbiBvZiB0KWZvcihsZXQgcj0wO3I8dGhpcy5FTEVNRU5UUzsrK3IpdGhpc1tyXSo9bltyXTtyZXR1cm4gdGhpcy5jaGVjaygpfWRpdmlkZSguLi50KXtmb3IoY29uc3QgbiBvZiB0KWZvcihsZXQgcj0wO3I8dGhpcy5FTEVNRU5UUzsrK3IpdGhpc1tyXS89bltyXTtyZXR1cm4gdGhpcy5jaGVjaygpfWxlbmd0aFNxKCl7cmV0dXJuIHRoaXMubGVuZ3RoU3F1YXJlZCgpfWRpc3RhbmNlVG8odCl7cmV0dXJuIHRoaXMuZGlzdGFuY2UodCl9ZGlzdGFuY2VUb1NxdWFyZWQodCl7cmV0dXJuIHRoaXMuZGlzdGFuY2VTcXVhcmVkKHQpfWdldENvbXBvbmVudCh0KXtyZXR1cm4gYnQodD49MCYmdDx0aGlzLkVMRU1FTlRTLCJpbmRleCBpcyBvdXQgb2YgcmFuZ2UiKSxSKHRoaXNbdF0pfXNldENvbXBvbmVudCh0LG4pe3JldHVybiBidCh0Pj0wJiZ0PHRoaXMuRUxFTUVOVFMsImluZGV4IGlzIG91dCBvZiByYW5nZSIpLHRoaXNbdF09bix0aGlzLmNoZWNrKCl9YWRkVmVjdG9ycyh0LG4pe3JldHVybiB0aGlzLmNvcHkodCkuYWRkKG4pfXN1YlZlY3RvcnModCxuKXtyZXR1cm4gdGhpcy5jb3B5KHQpLnN1YnRyYWN0KG4pfW11bHRpcGx5VmVjdG9ycyh0LG4pe3JldHVybiB0aGlzLmNvcHkodCkubXVsdGlwbHkobil9YWRkU2NhbGVkVmVjdG9yKHQsbil7cmV0dXJuIHRoaXMuYWRkKG5ldyB0aGlzLmNvbnN0cnVjdG9yKHQpLm11bHRpcGx5U2NhbGFyKG4pKX19O2NvbnN0IEM9MWUtNjtsZXQgQj10eXBlb2YgRmxvYXQzMkFycmF5PCJ1Ij9GbG9hdDMyQXJyYXk6QXJyYXk7Y29uc3QgVnQ9TWF0aC5yYW5kb207ZnVuY3Rpb24gQXQoZSl7cmV0dXJuIGU+PTA/TWF0aC5yb3VuZChlKTplJS41PT09MD9NYXRoLmZsb29yKGUpOk1hdGgucm91bmQoZSl9ZnVuY3Rpb24gc2koKXtjb25zdCBlPW5ldyBCKDIpO3JldHVybiBCIT1GbG9hdDMyQXJyYXkmJihlWzBdPTAsZVsxXT0wKSxlfWZ1bmN0aW9uIHFjKGUpe2NvbnN0IHQ9bmV3IEIoMik7cmV0dXJuIHRbMF09ZVswXSx0WzFdPWVbMV0sdH1mdW5jdGlvbiBVYyhlLHQpe2NvbnN0IG49bmV3IEIoMik7cmV0dXJuIG5bMF09ZSxuWzFdPXQsbn1mdW5jdGlvbiBEYyhlLHQpe3JldHVybiBlWzBdPXRbMF0sZVsxXT10WzFdLGV9ZnVuY3Rpb24gQmMoZSx0LG4pe3JldHVybiBlWzBdPXQsZVsxXT1uLGV9ZnVuY3Rpb24gb2koZSx0LG4pe3JldHVybiBlWzBdPXRbMF0rblswXSxlWzFdPXRbMV0rblsxXSxlfWZ1bmN0aW9uIGooZSx0LG4pe3JldHVybiBlWzBdPXRbMF0tblswXSxlWzFdPXRbMV0tblsxXSxlfWZ1bmN0aW9uIGNpKGUsdCxuKXtyZXR1cm4gZVswXT10WzBdKm5bMF0sZVsxXT10WzFdKm5bMV0sZX1mdW5jdGlvbiBJbihlLHQsbil7cmV0dXJuIGVbMF09dFswXS9uWzBdLGVbMV09dFsxXS9uWzFdLGV9ZnVuY3Rpb24gWWMoZSx0KXtyZXR1cm4gZVswXT1NYXRoLmNlaWwodFswXSksZVsxXT1NYXRoLmNlaWwodFsxXSksZX1mdW5jdGlvbiBXYyhlLHQpe3JldHVybiBlWzBdPU1hdGguZmxvb3IodFswXSksZVsxXT1NYXRoLmZsb29yKHRbMV0pLGV9ZnVuY3Rpb24gWmMoZSx0LG4pe3JldHVybiBlWzBdPU1hdGgubWluKHRbMF0sblswXSksZVsxXT1NYXRoLm1pbih0WzFdLG5bMV0pLGV9ZnVuY3Rpb24gR2MoZSx0LG4pe3JldHVybiBlWzBdPU1hdGgubWF4KHRbMF0sblswXSksZVsxXT1NYXRoLm1heCh0WzFdLG5bMV0pLGV9ZnVuY3Rpb24gWGMoZSx0KXtyZXR1cm4gZVswXT1BdCh0WzBdKSxlWzFdPUF0KHRbMV0pLGV9ZnVuY3Rpb24gYWkoZSx0LG4pe3JldHVybiBlWzBdPXRbMF0qbixlWzFdPXRbMV0qbixlfWZ1bmN0aW9uIGxpKGUsdCxuLHIpe3JldHVybiBlWzBdPXRbMF0rblswXSpyLGVbMV09dFsxXStuWzFdKnIsZX1mdW5jdGlvbiBoaShlLHQpe2NvbnN0IG49dFswXS1lWzBdLHI9dFsxXS1lWzFdO3JldHVybiBNYXRoLnNxcnQobipuK3Iqcil9ZnVuY3Rpb24gRmUoZSx0KXtjb25zdCBuPXRbMF0tZVswXSxyPXRbMV0tZVsxXTtyZXR1cm4gbipuK3Iqcn1mdW5jdGlvbiBmaShlKXtjb25zdCB0PWVbMF0sbj1lWzFdO3JldHVybiBNYXRoLnNxcnQodCp0K24qbil9ZnVuY3Rpb24gdWkoZSl7Y29uc3QgdD1lWzBdLG49ZVsxXTtyZXR1cm4gdCp0K24qbn1mdW5jdGlvbiBqYyhlLHQpe3JldHVybiBlWzBdPS10WzBdLGVbMV09LXRbMV0sZX1mdW5jdGlvbiBRYyhlLHQpe3JldHVybiBlWzBdPTEvdFswXSxlWzFdPTEvdFsxXSxlfWZ1bmN0aW9uIEtjKGUsdCl7Y29uc3Qgbj10WzBdLHI9dFsxXTtsZXQgaT1uKm4rcipyO3JldHVybiBpPjAmJihpPTEvTWF0aC5zcXJ0KGkpKSxlWzBdPXRbMF0qaSxlWzFdPXRbMV0qaSxlfWZ1bmN0aW9uIEpjKGUsdCl7cmV0dXJuIGVbMF0qdFswXStlWzFdKnRbMV19ZnVuY3Rpb24gRHQoZSx0LG4pe2NvbnN0IHI9dFswXSpuWzFdLXRbMV0qblswXTtyZXR1cm4gZVswXT1lWzFdPTAsZVsyXT1yLGV9ZnVuY3Rpb24gZGkoZSx0LG4scil7Y29uc3QgaT10WzBdLHM9dFsxXTtyZXR1cm4gZVswXT1pK3IqKG5bMF0taSksZVsxXT1zK3IqKG5bMV0tcyksZX1mdW5jdGlvbiBIYyhlLHQpe3Q9dD09PXZvaWQgMD8xOnQ7Y29uc3Qgbj1WdCgpKjIqTWF0aC5QSTtyZXR1cm4gZVswXT1NYXRoLmNvcyhuKSp0LGVbMV09TWF0aC5zaW4obikqdCxlfWZ1bmN0aW9uIGdpKGUsdCxuKXtjb25zdCByPXRbMF0saT10WzFdO3JldHVybiBlWzBdPW5bMF0qcituWzJdKmksZVsxXT1uWzFdKnIrblszXSppLGV9ZnVuY3Rpb24gbWkoZSx0LG4pe2NvbnN0IHI9dFswXSxpPXRbMV07cmV0dXJuIGVbMF09blswXSpyK25bMl0qaStuWzRdLGVbMV09blsxXSpyK25bM10qaStuWzVdLGV9ZnVuY3Rpb24gU24oZSx0LG4pe2NvbnN0IHI9dFswXSxpPXRbMV07cmV0dXJuIGVbMF09blswXSpyK25bM10qaStuWzZdLGVbMV09blsxXSpyK25bNF0qaStuWzddLGV9ZnVuY3Rpb24gUG4oZSx0LG4pe2NvbnN0IHI9dFswXSxpPXRbMV07cmV0dXJuIGVbMF09blswXSpyK25bNF0qaStuWzEyXSxlWzFdPW5bMV0qcituWzVdKmkrblsxM10sZX1mdW5jdGlvbiB0YShlLHQsbixyKXtjb25zdCBpPXRbMF0tblswXSxzPXRbMV0tblsxXSxvPU1hdGguc2luKHIpLGM9TWF0aC5jb3Mocik7cmV0dXJuIGVbMF09aSpjLXMqbytuWzBdLGVbMV09aSpvK3MqYytuWzFdLGV9ZnVuY3Rpb24gZWEoZSx0KXtjb25zdCBuPWVbMF0scj1lWzFdLGk9dFswXSxzPXRbMV0sbz1NYXRoLnNxcnQoKG4qbityKnIpKihpKmkrcypzKSksYz1vJiYobippK3IqcykvbztyZXR1cm4gTWF0aC5hY29zKE1hdGgubWluKE1hdGgubWF4KGMsLTEpLDEpKX1mdW5jdGlvbiBuYShlKXtyZXR1cm4gZVswXT0wLGVbMV09MCxlfWZ1bmN0aW9uIHJhKGUpe3JldHVybmB2ZWMyKCR7ZVswXX0sICR7ZVsxXX0pYH1mdW5jdGlvbiBpYShlLHQpe3JldHVybiBlWzBdPT09dFswXSYmZVsxXT09PXRbMV19ZnVuY3Rpb24gcWUoZSx0KXtjb25zdCBuPWVbMF0scj1lWzFdLGk9dFswXSxzPXRbMV07cmV0dXJuIE1hdGguYWJzKG4taSk8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhuKSxNYXRoLmFicyhpKSkmJk1hdGguYWJzKHItcyk8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhyKSxNYXRoLmFicyhzKSl9Y29uc3Qgc2E9Zmksb2E9aixjYT1jaSxhYT1JbixsYT1oaSxoYT1GZSxmYT11aSx1YT1mdW5jdGlvbigpe2NvbnN0IGU9c2koKTtyZXR1cm4gZnVuY3Rpb24odCxuLHIsaSxzLG8pe2xldCBjLGw7Zm9yKG58fChuPTIpLHJ8fChyPTApLGk/bD1NYXRoLm1pbihpKm4rcix0Lmxlbmd0aCk6bD10Lmxlbmd0aCxjPXI7YzxsO2MrPW4pZVswXT10W2NdLGVbMV09dFtjKzFdLHMoZSxlLG8pLHRbY109ZVswXSx0W2MrMV09ZVsxXTtyZXR1cm4gdH19KCk7dmFyIGRhPU9iamVjdC5mcmVlemUoe19fcHJvdG9fXzpudWxsLGFkZDpvaSxhbmdsZTplYSxjZWlsOlljLGNsb25lOnFjLGNvcHk6RGMsY3JlYXRlOnNpLGNyb3NzOkR0LGRpc3Q6bGEsZGlzdGFuY2U6aGksZGl2OmFhLGRpdmlkZTpJbixkb3Q6SmMsZXF1YWxzOnFlLGV4YWN0RXF1YWxzOmlhLGZsb29yOldjLGZvckVhY2g6dWEsZnJvbVZhbHVlczpVYyxpbnZlcnNlOlFjLGxlbjpzYSxsZW5ndGg6ZmksbGVycDpkaSxtYXg6R2MsbWluOlpjLG11bDpjYSxtdWx0aXBseTpjaSxuZWdhdGU6amMsbm9ybWFsaXplOktjLHJhbmRvbTpIYyxyb3RhdGU6dGEscm91bmQ6WGMsc2NhbGU6YWksc2NhbGVBbmRBZGQ6bGksc2V0OkJjLHNxckRpc3Q6aGEsc3FyTGVuOmZhLHNxdWFyZWREaXN0YW5jZTpGZSxzcXVhcmVkTGVuZ3RoOnVpLHN0cjpyYSxzdWI6b2Esc3VidHJhY3Q6aix0cmFuc2Zvcm1NYXQyOmdpLHRyYW5zZm9ybU1hdDJkOm1pLHRyYW5zZm9ybU1hdDM6U24sdHJhbnNmb3JtTWF0NDpQbix6ZXJvOm5hfSk7ZnVuY3Rpb24gTG4oZSx0LG4pe2NvbnN0IHI9dFswXSxpPXRbMV0scz1uWzNdKnIrbls3XSppfHwxO3JldHVybiBlWzBdPShuWzBdKnIrbls0XSppKS9zLGVbMV09KG5bMV0qcituWzVdKmkpL3MsZX1mdW5jdGlvbiBSbihlLHQsbil7Y29uc3Qgcj10WzBdLGk9dFsxXSxzPXRbMl0sbz1uWzNdKnIrbls3XSppK25bMTFdKnN8fDE7cmV0dXJuIGVbMF09KG5bMF0qcituWzRdKmkrbls4XSpzKS9vLGVbMV09KG5bMV0qcituWzVdKmkrbls5XSpzKS9vLGVbMl09KG5bMl0qcituWzZdKmkrblsxMF0qcykvbyxlfWZ1bmN0aW9uIHBpKGUsdCxuKXtjb25zdCByPXRbMF0saT10WzFdO3JldHVybiBlWzBdPW5bMF0qcituWzJdKmksZVsxXT1uWzFdKnIrblszXSppLGVbMl09dFsyXSxlfWZ1bmN0aW9uIF9pKGUsdCxuKXtjb25zdCByPXRbMF0saT10WzFdO3JldHVybiBlWzBdPW5bMF0qcituWzJdKmksZVsxXT1uWzFdKnIrblszXSppLGVbMl09dFsyXSxlWzNdPXRbM10sZX1mdW5jdGlvbiBDbihlLHQsbil7Y29uc3Qgcj10WzBdLGk9dFsxXSxzPXRbMl07cmV0dXJuIGVbMF09blswXSpyK25bM10qaStuWzZdKnMsZVsxXT1uWzFdKnIrbls0XSppK25bN10qcyxlWzJdPW5bMl0qcituWzVdKmkrbls4XSpzLGVbM109dFszXSxlfWNsYXNzIEsgZXh0ZW5kcyBrZXtjb25zdHJ1Y3Rvcih0PTAsbj0wKXtzdXBlcigyKSxSdCh0KSYmYXJndW1lbnRzLmxlbmd0aD09PTE/dGhpcy5jb3B5KHQpOihHLmRlYnVnJiYoUih0KSxSKG4pKSx0aGlzWzBdPXQsdGhpc1sxXT1uKX1zZXQodCxuKXtyZXR1cm4gdGhpc1swXT10LHRoaXNbMV09bix0aGlzLmNoZWNrKCl9Y29weSh0KXtyZXR1cm4gdGhpc1swXT10WzBdLHRoaXNbMV09dFsxXSx0aGlzLmNoZWNrKCl9ZnJvbU9iamVjdCh0KXtyZXR1cm4gRy5kZWJ1ZyYmKFIodC54KSxSKHQueSkpLHRoaXNbMF09dC54LHRoaXNbMV09dC55LHRoaXMuY2hlY2soKX10b09iamVjdCh0KXtyZXR1cm4gdC54PXRoaXNbMF0sdC55PXRoaXNbMV0sdH1nZXQgRUxFTUVOVFMoKXtyZXR1cm4gMn1ob3Jpem9udGFsQW5nbGUoKXtyZXR1cm4gTWF0aC5hdGFuMih0aGlzLnksdGhpcy54KX12ZXJ0aWNhbEFuZ2xlKCl7cmV0dXJuIE1hdGguYXRhbjIodGhpcy54LHRoaXMueSl9dHJhbnNmb3JtKHQpe3JldHVybiB0aGlzLnRyYW5zZm9ybUFzUG9pbnQodCl9dHJhbnNmb3JtQXNQb2ludCh0KXtyZXR1cm4gUG4odGhpcyx0aGlzLHQpLHRoaXMuY2hlY2soKX10cmFuc2Zvcm1Bc1ZlY3Rvcih0KXtyZXR1cm4gTG4odGhpcyx0aGlzLHQpLHRoaXMuY2hlY2soKX10cmFuc2Zvcm1CeU1hdHJpeDModCl7cmV0dXJuIFNuKHRoaXMsdGhpcyx0KSx0aGlzLmNoZWNrKCl9dHJhbnNmb3JtQnlNYXRyaXgyeDModCl7cmV0dXJuIG1pKHRoaXMsdGhpcyx0KSx0aGlzLmNoZWNrKCl9dHJhbnNmb3JtQnlNYXRyaXgyKHQpe3JldHVybiBnaSh0aGlzLHRoaXMsdCksdGhpcy5jaGVjaygpfX1mdW5jdGlvbiBWbigpe2NvbnN0IGU9bmV3IEIoMyk7cmV0dXJuIEIhPUZsb2F0MzJBcnJheSYmKGVbMF09MCxlWzFdPTAsZVsyXT0wKSxlfWZ1bmN0aW9uIGdhKGUpe2NvbnN0IHQ9bmV3IEIoMyk7cmV0dXJuIHRbMF09ZVswXSx0WzFdPWVbMV0sdFsyXT1lWzJdLHR9ZnVuY3Rpb24gVWUoZSl7Y29uc3QgdD1lWzBdLG49ZVsxXSxyPWVbMl07cmV0dXJuIE1hdGguc3FydCh0KnQrbipuK3Iqcil9ZnVuY3Rpb24gTm4oZSx0LG4pe2NvbnN0IHI9bmV3IEIoMyk7cmV0dXJuIHJbMF09ZSxyWzFdPXQsclsyXT1uLHJ9ZnVuY3Rpb24gbWEoZSx0KXtyZXR1cm4gZVswXT10WzBdLGVbMV09dFsxXSxlWzJdPXRbMl0sZX1mdW5jdGlvbiBwYShlLHQsbixyKXtyZXR1cm4gZVswXT10LGVbMV09bixlWzJdPXIsZX1mdW5jdGlvbiB5aShlLHQsbil7cmV0dXJuIGVbMF09dFswXStuWzBdLGVbMV09dFsxXStuWzFdLGVbMl09dFsyXStuWzJdLGV9ZnVuY3Rpb24gem4oZSx0LG4pe3JldHVybiBlWzBdPXRbMF0tblswXSxlWzFdPXRbMV0tblsxXSxlWzJdPXRbMl0tblsyXSxlfWZ1bmN0aW9uICRuKGUsdCxuKXtyZXR1cm4gZVswXT10WzBdKm5bMF0sZVsxXT10WzFdKm5bMV0sZVsyXT10WzJdKm5bMl0sZX1mdW5jdGlvbiB4aShlLHQsbil7cmV0dXJuIGVbMF09dFswXS9uWzBdLGVbMV09dFsxXS9uWzFdLGVbMl09dFsyXS9uWzJdLGV9ZnVuY3Rpb24gX2EoZSx0KXtyZXR1cm4gZVswXT1NYXRoLmNlaWwodFswXSksZVsxXT1NYXRoLmNlaWwodFsxXSksZVsyXT1NYXRoLmNlaWwodFsyXSksZX1mdW5jdGlvbiB5YShlLHQpe3JldHVybiBlWzBdPU1hdGguZmxvb3IodFswXSksZVsxXT1NYXRoLmZsb29yKHRbMV0pLGVbMl09TWF0aC5mbG9vcih0WzJdKSxlfWZ1bmN0aW9uIHhhKGUsdCxuKXtyZXR1cm4gZVswXT1NYXRoLm1pbih0WzBdLG5bMF0pLGVbMV09TWF0aC5taW4odFsxXSxuWzFdKSxlWzJdPU1hdGgubWluKHRbMl0sblsyXSksZX1mdW5jdGlvbiBNYShlLHQsbil7cmV0dXJuIGVbMF09TWF0aC5tYXgodFswXSxuWzBdKSxlWzFdPU1hdGgubWF4KHRbMV0sblsxXSksZVsyXT1NYXRoLm1heCh0WzJdLG5bMl0pLGV9ZnVuY3Rpb24gd2EoZSx0KXtyZXR1cm4gZVswXT1BdCh0WzBdKSxlWzFdPUF0KHRbMV0pLGVbMl09QXQodFsyXSksZX1mdW5jdGlvbiBNaShlLHQsbil7cmV0dXJuIGVbMF09dFswXSpuLGVbMV09dFsxXSpuLGVbMl09dFsyXSpuLGV9ZnVuY3Rpb24gQWEoZSx0LG4scil7cmV0dXJuIGVbMF09dFswXStuWzBdKnIsZVsxXT10WzFdK25bMV0qcixlWzJdPXRbMl0rblsyXSpyLGV9ZnVuY3Rpb24ga24oZSx0KXtjb25zdCBuPXRbMF0tZVswXSxyPXRbMV0tZVsxXSxpPXRbMl0tZVsyXTtyZXR1cm4gTWF0aC5zcXJ0KG4qbityKnIraSppKX1mdW5jdGlvbiB3aShlLHQpe2NvbnN0IG49dFswXS1lWzBdLHI9dFsxXS1lWzFdLGk9dFsyXS1lWzJdO3JldHVybiBuKm4rcipyK2kqaX1mdW5jdGlvbiBEZShlKXtjb25zdCB0PWVbMF0sbj1lWzFdLHI9ZVsyXTtyZXR1cm4gdCp0K24qbityKnJ9ZnVuY3Rpb24gQmUoZSx0KXtyZXR1cm4gZVswXT0tdFswXSxlWzFdPS10WzFdLGVbMl09LXRbMl0sZX1mdW5jdGlvbiBUYShlLHQpe3JldHVybiBlWzBdPTEvdFswXSxlWzFdPTEvdFsxXSxlWzJdPTEvdFsyXSxlfWZ1bmN0aW9uIEl0KGUsdCl7Y29uc3Qgbj10WzBdLHI9dFsxXSxpPXRbMl07bGV0IHM9bipuK3IqcitpKmk7cmV0dXJuIHM+MCYmKHM9MS9NYXRoLnNxcnQocykpLGVbMF09dFswXSpzLGVbMV09dFsxXSpzLGVbMl09dFsyXSpzLGV9ZnVuY3Rpb24gaGUoZSx0KXtyZXR1cm4gZVswXSp0WzBdK2VbMV0qdFsxXStlWzJdKnRbMl19ZnVuY3Rpb24gcnQoZSx0LG4pe2NvbnN0IHI9dFswXSxpPXRbMV0scz10WzJdLG89blswXSxjPW5bMV0sbD1uWzJdO3JldHVybiBlWzBdPWkqbC1zKmMsZVsxXT1zKm8tcipsLGVbMl09cipjLWkqbyxlfWZ1bmN0aW9uIHZhKGUsdCxuLHIpe2NvbnN0IGk9dFswXSxzPXRbMV0sbz10WzJdO3JldHVybiBlWzBdPWkrciooblswXS1pKSxlWzFdPXMrciooblsxXS1zKSxlWzJdPW8rciooblsyXS1vKSxlfWZ1bmN0aW9uIEVhKGUsdCxuLHIpe2NvbnN0IGk9TWF0aC5hY29zKE1hdGgubWluKE1hdGgubWF4KGhlKHQsbiksLTEpLDEpKSxzPU1hdGguc2luKGkpLG89TWF0aC5zaW4oKDEtcikqaSkvcyxjPU1hdGguc2luKHIqaSkvcztyZXR1cm4gZVswXT1vKnRbMF0rYypuWzBdLGVbMV09byp0WzFdK2MqblsxXSxlWzJdPW8qdFsyXStjKm5bMl0sZX1mdW5jdGlvbiBPYShlLHQsbixyLGkscyl7Y29uc3Qgbz1zKnMsYz1vKigyKnMtMykrMSxsPW8qKHMtMikrcyxoPW8qKHMtMSksZj1vKigzLTIqcyk7cmV0dXJuIGVbMF09dFswXSpjK25bMF0qbCtyWzBdKmgraVswXSpmLGVbMV09dFsxXSpjK25bMV0qbCtyWzFdKmgraVsxXSpmLGVbMl09dFsyXSpjK25bMl0qbCtyWzJdKmgraVsyXSpmLGV9ZnVuY3Rpb24gYmEoZSx0LG4scixpLHMpe2NvbnN0IG89MS1zLGM9bypvLGw9cypzLGg9YypvLGY9MypzKmMsdT0zKmwqbyxkPWwqcztyZXR1cm4gZVswXT10WzBdKmgrblswXSpmK3JbMF0qdStpWzBdKmQsZVsxXT10WzFdKmgrblsxXSpmK3JbMV0qdStpWzFdKmQsZVsyXT10WzJdKmgrblsyXSpmK3JbMl0qdStpWzJdKmQsZX1mdW5jdGlvbiBJYShlLHQpe3Q9dD09PXZvaWQgMD8xOnQ7Y29uc3Qgbj1WdCgpKjIqTWF0aC5QSSxyPVZ0KCkqMi0xLGk9TWF0aC5zcXJ0KDEtcipyKSp0O3JldHVybiBlWzBdPU1hdGguY29zKG4pKmksZVsxXT1NYXRoLnNpbihuKSppLGVbMl09cip0LGV9ZnVuY3Rpb24gWWUoZSx0LG4pe2NvbnN0IHI9dFswXSxpPXRbMV0scz10WzJdO2xldCBvPW5bM10qcituWzddKmkrblsxMV0qcytuWzE1XTtyZXR1cm4gbz1vfHwxLGVbMF09KG5bMF0qcituWzRdKmkrbls4XSpzK25bMTJdKS9vLGVbMV09KG5bMV0qcituWzVdKmkrbls5XSpzK25bMTNdKS9vLGVbMl09KG5bMl0qcituWzZdKmkrblsxMF0qcytuWzE0XSkvbyxlfWZ1bmN0aW9uIEZuKGUsdCxuKXtjb25zdCByPXRbMF0saT10WzFdLHM9dFsyXTtyZXR1cm4gZVswXT1yKm5bMF0raSpuWzNdK3Mqbls2XSxlWzFdPXIqblsxXStpKm5bNF0rcypuWzddLGVbMl09cipuWzJdK2kqbls1XStzKm5bOF0sZX1mdW5jdGlvbiBCdChlLHQsbil7Y29uc3Qgcj1uWzBdLGk9blsxXSxzPW5bMl0sbz1uWzNdLGM9dFswXSxsPXRbMV0saD10WzJdO2xldCBmPWkqaC1zKmwsdT1zKmMtcipoLGQ9cipsLWkqYyxnPWkqZC1zKnUsbT1zKmYtcipkLF89cip1LWkqZjtjb25zdCBwPW8qMjtyZXR1cm4gZio9cCx1Kj1wLGQqPXAsZyo9MixtKj0yLF8qPTIsZVswXT1jK2YrZyxlWzFdPWwrdSttLGVbMl09aCtkK18sZX1mdW5jdGlvbiBBaShlLHQsbixyKXtjb25zdCBpPVtdLHM9W107cmV0dXJuIGlbMF09dFswXS1uWzBdLGlbMV09dFsxXS1uWzFdLGlbMl09dFsyXS1uWzJdLHNbMF09aVswXSxzWzFdPWlbMV0qTWF0aC5jb3MociktaVsyXSpNYXRoLnNpbihyKSxzWzJdPWlbMV0qTWF0aC5zaW4ocikraVsyXSpNYXRoLmNvcyhyKSxlWzBdPXNbMF0rblswXSxlWzFdPXNbMV0rblsxXSxlWzJdPXNbMl0rblsyXSxlfWZ1bmN0aW9uIFRpKGUsdCxuLHIpe2NvbnN0IGk9W10scz1bXTtyZXR1cm4gaVswXT10WzBdLW5bMF0saVsxXT10WzFdLW5bMV0saVsyXT10WzJdLW5bMl0sc1swXT1pWzJdKk1hdGguc2luKHIpK2lbMF0qTWF0aC5jb3Mociksc1sxXT1pWzFdLHNbMl09aVsyXSpNYXRoLmNvcyhyKS1pWzBdKk1hdGguc2luKHIpLGVbMF09c1swXStuWzBdLGVbMV09c1sxXStuWzFdLGVbMl09c1syXStuWzJdLGV9ZnVuY3Rpb24gdmkoZSx0LG4scil7Y29uc3QgaT1bXSxzPVtdO3JldHVybiBpWzBdPXRbMF0tblswXSxpWzFdPXRbMV0tblsxXSxpWzJdPXRbMl0tblsyXSxzWzBdPWlbMF0qTWF0aC5jb3MociktaVsxXSpNYXRoLnNpbihyKSxzWzFdPWlbMF0qTWF0aC5zaW4ocikraVsxXSpNYXRoLmNvcyhyKSxzWzJdPWlbMl0sZVswXT1zWzBdK25bMF0sZVsxXT1zWzFdK25bMV0sZVsyXT1zWzJdK25bMl0sZX1mdW5jdGlvbiBFaShlLHQpe2NvbnN0IG49ZVswXSxyPWVbMV0saT1lWzJdLHM9dFswXSxvPXRbMV0sYz10WzJdLGw9TWF0aC5zcXJ0KChuKm4rcipyK2kqaSkqKHMqcytvKm8rYypjKSksaD1sJiZoZShlLHQpL2w7cmV0dXJuIE1hdGguYWNvcyhNYXRoLm1pbihNYXRoLm1heChoLC0xKSwxKSl9ZnVuY3Rpb24gU2EoZSl7cmV0dXJuIGVbMF09MCxlWzFdPTAsZVsyXT0wLGV9ZnVuY3Rpb24gUGEoZSl7cmV0dXJuYHZlYzMoJHtlWzBdfSwgJHtlWzFdfSwgJHtlWzJdfSlgfWZ1bmN0aW9uIExhKGUsdCl7cmV0dXJuIGVbMF09PT10WzBdJiZlWzFdPT09dFsxXSYmZVsyXT09PXRbMl19ZnVuY3Rpb24gUmEoZSx0KXtjb25zdCBuPWVbMF0scj1lWzFdLGk9ZVsyXSxzPXRbMF0sbz10WzFdLGM9dFsyXTtyZXR1cm4gTWF0aC5hYnMobi1zKTw9QypNYXRoLm1heCgxLE1hdGguYWJzKG4pLE1hdGguYWJzKHMpKSYmTWF0aC5hYnMoci1vKTw9QypNYXRoLm1heCgxLE1hdGguYWJzKHIpLE1hdGguYWJzKG8pKSYmTWF0aC5hYnMoaS1jKTw9QypNYXRoLm1heCgxLE1hdGguYWJzKGkpLE1hdGguYWJzKGMpKX1jb25zdCBDYT16bixWYT0kbixOYT14aSx6YT1rbiwkYT13aSxPaT1VZSxrYT1EZSxGYT1mdW5jdGlvbigpe2NvbnN0IGU9Vm4oKTtyZXR1cm4gZnVuY3Rpb24odCxuLHIsaSxzLG8pe2xldCBjLGw7Zm9yKG58fChuPTMpLHJ8fChyPTApLGk/bD1NYXRoLm1pbihpKm4rcix0Lmxlbmd0aCk6bD10Lmxlbmd0aCxjPXI7YzxsO2MrPW4pZVswXT10W2NdLGVbMV09dFtjKzFdLGVbMl09dFtjKzJdLHMoZSxlLG8pLHRbY109ZVswXSx0W2MrMV09ZVsxXSx0W2MrMl09ZVsyXTtyZXR1cm4gdH19KCk7dmFyIHFhPU9iamVjdC5mcmVlemUoe19fcHJvdG9fXzpudWxsLGFkZDp5aSxhbmdsZTpFaSxiZXppZXI6YmEsY2VpbDpfYSxjbG9uZTpnYSxjb3B5Om1hLGNyZWF0ZTpWbixjcm9zczpydCxkaXN0OnphLGRpc3RhbmNlOmtuLGRpdjpOYSxkaXZpZGU6eGksZG90OmhlLGVxdWFsczpSYSxleGFjdEVxdWFsczpMYSxmbG9vcjp5YSxmb3JFYWNoOkZhLGZyb21WYWx1ZXM6Tm4saGVybWl0ZTpPYSxpbnZlcnNlOlRhLGxlbjpPaSxsZW5ndGg6VWUsbGVycDp2YSxtYXg6TWEsbWluOnhhLG11bDpWYSxtdWx0aXBseTokbixuZWdhdGU6QmUsbm9ybWFsaXplOkl0LHJhbmRvbTpJYSxyb3RhdGVYOkFpLHJvdGF0ZVk6VGkscm90YXRlWjp2aSxyb3VuZDp3YSxzY2FsZTpNaSxzY2FsZUFuZEFkZDpBYSxzZXQ6cGEsc2xlcnA6RWEsc3FyRGlzdDokYSxzcXJMZW46a2Esc3F1YXJlZERpc3RhbmNlOndpLHNxdWFyZWRMZW5ndGg6RGUsc3RyOlBhLHN1YjpDYSxzdWJ0cmFjdDp6bix0cmFuc2Zvcm1NYXQzOkZuLHRyYW5zZm9ybU1hdDQ6WWUsdHJhbnNmb3JtUXVhdDpCdCx6ZXJvOlNhfSk7Y29uc3QgcW49WzAsMCwwXTtsZXQgV2U7Y2xhc3MgUCBleHRlbmRzIGtle3N0YXRpYyBnZXQgWkVSTygpe3JldHVybiBXZXx8KFdlPW5ldyBQKDAsMCwwKSxPYmplY3QuZnJlZXplKFdlKSksV2V9Y29uc3RydWN0b3IodD0wLG49MCxyPTApe3N1cGVyKC0wLC0wLC0wKSxhcmd1bWVudHMubGVuZ3RoPT09MSYmUnQodCk/dGhpcy5jb3B5KHQpOihHLmRlYnVnJiYoUih0KSxSKG4pLFIocikpLHRoaXNbMF09dCx0aGlzWzFdPW4sdGhpc1syXT1yKX1zZXQodCxuLHIpe3JldHVybiB0aGlzWzBdPXQsdGhpc1sxXT1uLHRoaXNbMl09cix0aGlzLmNoZWNrKCl9Y29weSh0KXtyZXR1cm4gdGhpc1swXT10WzBdLHRoaXNbMV09dFsxXSx0aGlzWzJdPXRbMl0sdGhpcy5jaGVjaygpfWZyb21PYmplY3QodCl7cmV0dXJuIEcuZGVidWcmJihSKHQueCksUih0LnkpLFIodC56KSksdGhpc1swXT10LngsdGhpc1sxXT10LnksdGhpc1syXT10LnosdGhpcy5jaGVjaygpfXRvT2JqZWN0KHQpe3JldHVybiB0Lng9dGhpc1swXSx0Lnk9dGhpc1sxXSx0Lno9dGhpc1syXSx0fWdldCBFTEVNRU5UUygpe3JldHVybiAzfWdldCB6KCl7cmV0dXJuIHRoaXNbMl19c2V0IHoodCl7dGhpc1syXT1SKHQpfWFuZ2xlKHQpe3JldHVybiBFaSh0aGlzLHQpfWNyb3NzKHQpe3JldHVybiBydCh0aGlzLHRoaXMsdCksdGhpcy5jaGVjaygpfXJvdGF0ZVgoe3JhZGlhbnM6dCxvcmlnaW46bj1xbn0pe3JldHVybiBBaSh0aGlzLHRoaXMsbix0KSx0aGlzLmNoZWNrKCl9cm90YXRlWSh7cmFkaWFuczp0LG9yaWdpbjpuPXFufSl7cmV0dXJuIFRpKHRoaXMsdGhpcyxuLHQpLHRoaXMuY2hlY2soKX1yb3RhdGVaKHtyYWRpYW5zOnQsb3JpZ2luOm49cW59KXtyZXR1cm4gdmkodGhpcyx0aGlzLG4sdCksdGhpcy5jaGVjaygpfXRyYW5zZm9ybSh0KXtyZXR1cm4gdGhpcy50cmFuc2Zvcm1Bc1BvaW50KHQpfXRyYW5zZm9ybUFzUG9pbnQodCl7cmV0dXJuIFllKHRoaXMsdGhpcyx0KSx0aGlzLmNoZWNrKCl9dHJhbnNmb3JtQXNWZWN0b3IodCl7cmV0dXJuIFJuKHRoaXMsdGhpcyx0KSx0aGlzLmNoZWNrKCl9dHJhbnNmb3JtQnlNYXRyaXgzKHQpe3JldHVybiBGbih0aGlzLHRoaXMsdCksdGhpcy5jaGVjaygpfXRyYW5zZm9ybUJ5TWF0cml4Mih0KXtyZXR1cm4gcGkodGhpcyx0aGlzLHQpLHRoaXMuY2hlY2soKX10cmFuc2Zvcm1CeVF1YXRlcm5pb24odCl7cmV0dXJuIEJ0KHRoaXMsdGhpcyx0KSx0aGlzLmNoZWNrKCl9fWxldCBaZTtjbGFzcyB1dCBleHRlbmRzIGtle3N0YXRpYyBnZXQgWkVSTygpe3JldHVybiBaZXx8KFplPW5ldyB1dCgwLDAsMCwwKSxPYmplY3QuZnJlZXplKFplKSksWmV9Y29uc3RydWN0b3IodD0wLG49MCxyPTAsaT0wKXtzdXBlcigtMCwtMCwtMCwtMCksUnQodCkmJmFyZ3VtZW50cy5sZW5ndGg9PT0xP3RoaXMuY29weSh0KTooRy5kZWJ1ZyYmKFIodCksUihuKSxSKHIpLFIoaSkpLHRoaXNbMF09dCx0aGlzWzFdPW4sdGhpc1syXT1yLHRoaXNbM109aSl9c2V0KHQsbixyLGkpe3JldHVybiB0aGlzWzBdPXQsdGhpc1sxXT1uLHRoaXNbMl09cix0aGlzWzNdPWksdGhpcy5jaGVjaygpfWNvcHkodCl7cmV0dXJuIHRoaXNbMF09dFswXSx0aGlzWzFdPXRbMV0sdGhpc1syXT10WzJdLHRoaXNbM109dFszXSx0aGlzLmNoZWNrKCl9ZnJvbU9iamVjdCh0KXtyZXR1cm4gRy5kZWJ1ZyYmKFIodC54KSxSKHQueSksUih0LnopLFIodC53KSksdGhpc1swXT10LngsdGhpc1sxXT10LnksdGhpc1syXT10LnosdGhpc1szXT10LncsdGhpc310b09iamVjdCh0KXtyZXR1cm4gdC54PXRoaXNbMF0sdC55PXRoaXNbMV0sdC56PXRoaXNbMl0sdC53PXRoaXNbM10sdH1nZXQgRUxFTUVOVFMoKXtyZXR1cm4gNH1nZXQgeigpe3JldHVybiB0aGlzWzJdfXNldCB6KHQpe3RoaXNbMl09Uih0KX1nZXQgdygpe3JldHVybiB0aGlzWzNdfXNldCB3KHQpe3RoaXNbM109Uih0KX10cmFuc2Zvcm0odCl7cmV0dXJuIFllKHRoaXMsdGhpcyx0KSx0aGlzLmNoZWNrKCl9dHJhbnNmb3JtQnlNYXRyaXgzKHQpe3JldHVybiBDbih0aGlzLHRoaXMsdCksdGhpcy5jaGVjaygpfXRyYW5zZm9ybUJ5TWF0cml4Mih0KXtyZXR1cm4gX2kodGhpcyx0aGlzLHQpLHRoaXMuY2hlY2soKX10cmFuc2Zvcm1CeVF1YXRlcm5pb24odCl7cmV0dXJuIEJ0KHRoaXMsdGhpcyx0KSx0aGlzLmNoZWNrKCl9YXBwbHlNYXRyaXg0KHQpe3JldHVybiB0LnRyYW5zZm9ybSh0aGlzLHRoaXMpLHRoaXN9fWxldCBVbj1jbGFzcyBleHRlbmRzIGFle3RvU3RyaW5nKCl7bGV0IHQ9IlsiO2lmKEcucHJpbnRSb3dNYWpvcil7dCs9InJvdy1tYWpvcjoiO2ZvcihsZXQgbj0wO248dGhpcy5SQU5LOysrbilmb3IobGV0IHI9MDtyPHRoaXMuUkFOSzsrK3IpdCs9YCAke3RoaXNbcip0aGlzLlJBTksrbl19YH1lbHNle3QrPSJjb2x1bW4tbWFqb3I6Ijtmb3IobGV0IG49MDtuPHRoaXMuRUxFTUVOVFM7KytuKXQrPWAgJHt0aGlzW25dfWB9cmV0dXJuIHQrPSJdIix0fWdldEVsZW1lbnRJbmRleCh0LG4pe3JldHVybiBuKnRoaXMuUkFOSyt0fWdldEVsZW1lbnQodCxuKXtyZXR1cm4gdGhpc1tuKnRoaXMuUkFOSyt0XX1zZXRFbGVtZW50KHQsbixyKXtyZXR1cm4gdGhpc1tuKnRoaXMuUkFOSyt0XT1SKHIpLHRoaXN9Z2V0Q29sdW1uKHQsbj1uZXcgQXJyYXkodGhpcy5SQU5LKS5maWxsKC0wKSl7Y29uc3Qgcj10KnRoaXMuUkFOSztmb3IobGV0IGk9MDtpPHRoaXMuUkFOSzsrK2kpbltpXT10aGlzW3IraV07cmV0dXJuIG59c2V0Q29sdW1uKHQsbil7Y29uc3Qgcj10KnRoaXMuUkFOSztmb3IobGV0IGk9MDtpPHRoaXMuUkFOSzsrK2kpdGhpc1tyK2ldPW5baV07cmV0dXJuIHRoaXN9fTtmdW5jdGlvbiBiaSgpe2NvbnN0IGU9bmV3IEIoOSk7cmV0dXJuIEIhPUZsb2F0MzJBcnJheSYmKGVbMV09MCxlWzJdPTAsZVszXT0wLGVbNV09MCxlWzZdPTAsZVs3XT0wKSxlWzBdPTEsZVs0XT0xLGVbOF09MSxlfWZ1bmN0aW9uIFVhKGUsdCl7cmV0dXJuIGVbMF09dFswXSxlWzFdPXRbMV0sZVsyXT10WzJdLGVbM109dFs0XSxlWzRdPXRbNV0sZVs1XT10WzZdLGVbNl09dFs4XSxlWzddPXRbOV0sZVs4XT10WzEwXSxlfWZ1bmN0aW9uIERhKGUpe2NvbnN0IHQ9bmV3IEIoOSk7cmV0dXJuIHRbMF09ZVswXSx0WzFdPWVbMV0sdFsyXT1lWzJdLHRbM109ZVszXSx0WzRdPWVbNF0sdFs1XT1lWzVdLHRbNl09ZVs2XSx0WzddPWVbN10sdFs4XT1lWzhdLHR9ZnVuY3Rpb24gQmEoZSx0KXtyZXR1cm4gZVswXT10WzBdLGVbMV09dFsxXSxlWzJdPXRbMl0sZVszXT10WzNdLGVbNF09dFs0XSxlWzVdPXRbNV0sZVs2XT10WzZdLGVbN109dFs3XSxlWzhdPXRbOF0sZX1mdW5jdGlvbiBZYShlLHQsbixyLGkscyxvLGMsbCl7Y29uc3QgaD1uZXcgQig5KTtyZXR1cm4gaFswXT1lLGhbMV09dCxoWzJdPW4saFszXT1yLGhbNF09aSxoWzVdPXMsaFs2XT1vLGhbN109YyxoWzhdPWwsaH1mdW5jdGlvbiBXYShlLHQsbixyLGkscyxvLGMsbCxoKXtyZXR1cm4gZVswXT10LGVbMV09bixlWzJdPXIsZVszXT1pLGVbNF09cyxlWzVdPW8sZVs2XT1jLGVbN109bCxlWzhdPWgsZX1mdW5jdGlvbiBaYShlKXtyZXR1cm4gZVswXT0xLGVbMV09MCxlWzJdPTAsZVszXT0wLGVbNF09MSxlWzVdPTAsZVs2XT0wLGVbN109MCxlWzhdPTEsZX1mdW5jdGlvbiBEbihlLHQpe2lmKGU9PT10KXtjb25zdCBuPXRbMV0scj10WzJdLGk9dFs1XTtlWzFdPXRbM10sZVsyXT10WzZdLGVbM109bixlWzVdPXRbN10sZVs2XT1yLGVbN109aX1lbHNlIGVbMF09dFswXSxlWzFdPXRbM10sZVsyXT10WzZdLGVbM109dFsxXSxlWzRdPXRbNF0sZVs1XT10WzddLGVbNl09dFsyXSxlWzddPXRbNV0sZVs4XT10WzhdO3JldHVybiBlfWZ1bmN0aW9uIEJuKGUsdCl7Y29uc3Qgbj10WzBdLHI9dFsxXSxpPXRbMl0scz10WzNdLG89dFs0XSxjPXRbNV0sbD10WzZdLGg9dFs3XSxmPXRbOF0sdT1mKm8tYypoLGQ9LWYqcytjKmwsZz1oKnMtbypsO2xldCBtPW4qdStyKmQraSpnO3JldHVybiBtPyhtPTEvbSxlWzBdPXUqbSxlWzFdPSgtZipyK2kqaCkqbSxlWzJdPShjKnItaSpvKSptLGVbM109ZCptLGVbNF09KGYqbi1pKmwpKm0sZVs1XT0oLWMqbitpKnMpKm0sZVs2XT1nKm0sZVs3XT0oLWgqbityKmwpKm0sZVs4XT0obypuLXIqcykqbSxlKTpudWxsfWZ1bmN0aW9uIEdhKGUsdCl7Y29uc3Qgbj10WzBdLHI9dFsxXSxpPXRbMl0scz10WzNdLG89dFs0XSxjPXRbNV0sbD10WzZdLGg9dFs3XSxmPXRbOF07cmV0dXJuIGVbMF09bypmLWMqaCxlWzFdPWkqaC1yKmYsZVsyXT1yKmMtaSpvLGVbM109YypsLXMqZixlWzRdPW4qZi1pKmwsZVs1XT1pKnMtbipjLGVbNl09cypoLW8qbCxlWzddPXIqbC1uKmgsZVs4XT1uKm8tcipzLGV9ZnVuY3Rpb24gZmUoZSl7Y29uc3QgdD1lWzBdLG49ZVsxXSxyPWVbMl0saT1lWzNdLHM9ZVs0XSxvPWVbNV0sYz1lWzZdLGw9ZVs3XSxoPWVbOF07cmV0dXJuIHQqKGgqcy1vKmwpK24qKC1oKmkrbypjKStyKihsKmktcypjKX1mdW5jdGlvbiBHZShlLHQsbil7Y29uc3Qgcj10WzBdLGk9dFsxXSxzPXRbMl0sbz10WzNdLGM9dFs0XSxsPXRbNV0saD10WzZdLGY9dFs3XSx1PXRbOF0sZD1uWzBdLGc9blsxXSxtPW5bMl0sXz1uWzNdLHA9bls0XSxNPW5bNV0sQT1uWzZdLHg9bls3XSxUPW5bOF07cmV0dXJuIGVbMF09ZCpyK2cqbyttKmgsZVsxXT1kKmkrZypjK20qZixlWzJdPWQqcytnKmwrbSp1LGVbM109XypyK3AqbytNKmgsZVs0XT1fKmkrcCpjK00qZixlWzVdPV8qcytwKmwrTSp1LGVbNl09QSpyK3gqbytUKmgsZVs3XT1BKmkreCpjK1QqZixlWzhdPUEqcyt4KmwrVCp1LGV9ZnVuY3Rpb24gSWkoZSx0LG4pe2NvbnN0IHI9dFswXSxpPXRbMV0scz10WzJdLG89dFszXSxjPXRbNF0sbD10WzVdLGg9dFs2XSxmPXRbN10sdT10WzhdLGQ9blswXSxnPW5bMV07cmV0dXJuIGVbMF09cixlWzFdPWksZVsyXT1zLGVbM109byxlWzRdPWMsZVs1XT1sLGVbNl09ZCpyK2cqbytoLGVbN109ZCppK2cqYytmLGVbOF09ZCpzK2cqbCt1LGV9ZnVuY3Rpb24gU2koZSx0LG4pe2NvbnN0IHI9dFswXSxpPXRbMV0scz10WzJdLG89dFszXSxjPXRbNF0sbD10WzVdLGg9dFs2XSxmPXRbN10sdT10WzhdLGQ9TWF0aC5zaW4obiksZz1NYXRoLmNvcyhuKTtyZXR1cm4gZVswXT1nKnIrZCpvLGVbMV09ZyppK2QqYyxlWzJdPWcqcytkKmwsZVszXT1nKm8tZCpyLGVbNF09ZypjLWQqaSxlWzVdPWcqbC1kKnMsZVs2XT1oLGVbN109ZixlWzhdPXUsZX1mdW5jdGlvbiBZbihlLHQsbil7Y29uc3Qgcj1uWzBdLGk9blsxXTtyZXR1cm4gZVswXT1yKnRbMF0sZVsxXT1yKnRbMV0sZVsyXT1yKnRbMl0sZVszXT1pKnRbM10sZVs0XT1pKnRbNF0sZVs1XT1pKnRbNV0sZVs2XT10WzZdLGVbN109dFs3XSxlWzhdPXRbOF0sZX1mdW5jdGlvbiBYYShlLHQpe3JldHVybiBlWzBdPTEsZVsxXT0wLGVbMl09MCxlWzNdPTAsZVs0XT0xLGVbNV09MCxlWzZdPXRbMF0sZVs3XT10WzFdLGVbOF09MSxlfWZ1bmN0aW9uIGphKGUsdCl7Y29uc3Qgbj1NYXRoLnNpbih0KSxyPU1hdGguY29zKHQpO3JldHVybiBlWzBdPXIsZVsxXT1uLGVbMl09MCxlWzNdPS1uLGVbNF09cixlWzVdPTAsZVs2XT0wLGVbN109MCxlWzhdPTEsZX1mdW5jdGlvbiBRYShlLHQpe3JldHVybiBlWzBdPXRbMF0sZVsxXT0wLGVbMl09MCxlWzNdPTAsZVs0XT10WzFdLGVbNV09MCxlWzZdPTAsZVs3XT0wLGVbOF09MSxlfWZ1bmN0aW9uIEthKGUsdCl7cmV0dXJuIGVbMF09dFswXSxlWzFdPXRbMV0sZVsyXT0wLGVbM109dFsyXSxlWzRdPXRbM10sZVs1XT0wLGVbNl09dFs0XSxlWzddPXRbNV0sZVs4XT0xLGV9ZnVuY3Rpb24gUGkoZSx0KXtjb25zdCBuPXRbMF0scj10WzFdLGk9dFsyXSxzPXRbM10sbz1uK24sYz1yK3IsbD1pK2ksaD1uKm8sZj1yKm8sdT1yKmMsZD1pKm8sZz1pKmMsbT1pKmwsXz1zKm8scD1zKmMsTT1zKmw7cmV0dXJuIGVbMF09MS11LW0sZVszXT1mLU0sZVs2XT1kK3AsZVsxXT1mK00sZVs0XT0xLWgtbSxlWzddPWctXyxlWzJdPWQtcCxlWzVdPWcrXyxlWzhdPTEtaC11LGV9ZnVuY3Rpb24gV24oZSx0KXtjb25zdCBuPXRbMF0scj10WzFdLGk9dFsyXSxzPXRbM10sbz10WzRdLGM9dFs1XSxsPXRbNl0saD10WzddLGY9dFs4XSx1PXRbOV0sZD10WzEwXSxnPXRbMTFdLG09dFsxMl0sXz10WzEzXSxwPXRbMTRdLE09dFsxNV0sQT1uKmMtcipvLHg9bipsLWkqbyxUPW4qaC1zKm8sdj1yKmwtaSpjLHc9cipoLXMqYyxTPWkqaC1zKmwsYj1mKl8tdSptLEk9ZipwLWQqbSxFPWYqTS1nKm0sVj11KnAtZCpfLE49dSpNLWcqXyx6PWQqTS1nKnA7bGV0IEw9QSp6LXgqTitUKlYrdipFLXcqSStTKmI7cmV0dXJuIEw/KEw9MS9MLGVbMF09KGMqei1sKk4raCpWKSpMLGVbMV09KGwqRS1vKnotaCpJKSpMLGVbMl09KG8qTi1jKkUraCpiKSpMLGVbM109KGkqTi1yKnotcypWKSpMLGVbNF09KG4qei1pKkUrcypJKSpMLGVbNV09KHIqRS1uKk4tcypiKSpMLGVbNl09KF8qUy1wKncrTSp2KSpMLGVbN109KHAqVC1tKlMtTSp4KSpMLGVbOF09KG0qdy1fKlQrTSpBKSpMLGUpOm51bGx9ZnVuY3Rpb24gSmEoZSx0LG4pe3JldHVybiBlWzBdPTIvdCxlWzFdPTAsZVsyXT0wLGVbM109MCxlWzRdPS0yL24sZVs1XT0wLGVbNl09LTEsZVs3XT0xLGVbOF09MSxlfWZ1bmN0aW9uIEhhKGUpe3JldHVybmBtYXQzKCR7ZVswXX0sICR7ZVsxXX0sICR7ZVsyXX0sICR7ZVszXX0sICR7ZVs0XX0sICR7ZVs1XX0sICR7ZVs2XX0sICR7ZVs3XX0sICR7ZVs4XX0pYH1mdW5jdGlvbiB0bChlKXtyZXR1cm4gTWF0aC5zcXJ0KGVbMF0qZVswXStlWzFdKmVbMV0rZVsyXSplWzJdK2VbM10qZVszXStlWzRdKmVbNF0rZVs1XSplWzVdK2VbNl0qZVs2XStlWzddKmVbN10rZVs4XSplWzhdKX1mdW5jdGlvbiBlbChlLHQsbil7cmV0dXJuIGVbMF09dFswXStuWzBdLGVbMV09dFsxXStuWzFdLGVbMl09dFsyXStuWzJdLGVbM109dFszXStuWzNdLGVbNF09dFs0XStuWzRdLGVbNV09dFs1XStuWzVdLGVbNl09dFs2XStuWzZdLGVbN109dFs3XStuWzddLGVbOF09dFs4XStuWzhdLGV9ZnVuY3Rpb24gTGkoZSx0LG4pe3JldHVybiBlWzBdPXRbMF0tblswXSxlWzFdPXRbMV0tblsxXSxlWzJdPXRbMl0tblsyXSxlWzNdPXRbM10tblszXSxlWzRdPXRbNF0tbls0XSxlWzVdPXRbNV0tbls1XSxlWzZdPXRbNl0tbls2XSxlWzddPXRbN10tbls3XSxlWzhdPXRbOF0tbls4XSxlfWZ1bmN0aW9uIG5sKGUsdCxuKXtyZXR1cm4gZVswXT10WzBdKm4sZVsxXT10WzFdKm4sZVsyXT10WzJdKm4sZVszXT10WzNdKm4sZVs0XT10WzRdKm4sZVs1XT10WzVdKm4sZVs2XT10WzZdKm4sZVs3XT10WzddKm4sZVs4XT10WzhdKm4sZX1mdW5jdGlvbiBybChlLHQsbixyKXtyZXR1cm4gZVswXT10WzBdK25bMF0qcixlWzFdPXRbMV0rblsxXSpyLGVbMl09dFsyXStuWzJdKnIsZVszXT10WzNdK25bM10qcixlWzRdPXRbNF0rbls0XSpyLGVbNV09dFs1XStuWzVdKnIsZVs2XT10WzZdK25bNl0qcixlWzddPXRbN10rbls3XSpyLGVbOF09dFs4XStuWzhdKnIsZX1mdW5jdGlvbiBpbChlLHQpe3JldHVybiBlWzBdPT09dFswXSYmZVsxXT09PXRbMV0mJmVbMl09PT10WzJdJiZlWzNdPT09dFszXSYmZVs0XT09PXRbNF0mJmVbNV09PT10WzVdJiZlWzZdPT09dFs2XSYmZVs3XT09PXRbN10mJmVbOF09PT10WzhdfWZ1bmN0aW9uIHNsKGUsdCl7Y29uc3Qgbj1lWzBdLHI9ZVsxXSxpPWVbMl0scz1lWzNdLG89ZVs0XSxjPWVbNV0sbD1lWzZdLGg9ZVs3XSxmPWVbOF0sdT10WzBdLGQ9dFsxXSxnPXRbMl0sbT10WzNdLF89dFs0XSxwPXRbNV0sTT10WzZdLEE9dFs3XSx4PXRbOF07cmV0dXJuIE1hdGguYWJzKG4tdSk8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhuKSxNYXRoLmFicyh1KSkmJk1hdGguYWJzKHItZCk8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhyKSxNYXRoLmFicyhkKSkmJk1hdGguYWJzKGktZyk8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhpKSxNYXRoLmFicyhnKSkmJk1hdGguYWJzKHMtbSk8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhzKSxNYXRoLmFicyhtKSkmJk1hdGguYWJzKG8tXyk8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhvKSxNYXRoLmFicyhfKSkmJk1hdGguYWJzKGMtcCk8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhjKSxNYXRoLmFicyhwKSkmJk1hdGguYWJzKGwtTSk8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhsKSxNYXRoLmFicyhNKSkmJk1hdGguYWJzKGgtQSk8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhoKSxNYXRoLmFicyhBKSkmJk1hdGguYWJzKGYteCk8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhmKSxNYXRoLmFicyh4KSl9dmFyIG9sPU9iamVjdC5mcmVlemUoe19fcHJvdG9fXzpudWxsLGFkZDplbCxhZGpvaW50OkdhLGNsb25lOkRhLGNvcHk6QmEsY3JlYXRlOmJpLGRldGVybWluYW50OmZlLGVxdWFsczpzbCxleGFjdEVxdWFsczppbCxmcm9iOnRsLGZyb21NYXQyZDpLYSxmcm9tTWF0NDpVYSxmcm9tUXVhdDpQaSxmcm9tUm90YXRpb246amEsZnJvbVNjYWxpbmc6UWEsZnJvbVRyYW5zbGF0aW9uOlhhLGZyb21WYWx1ZXM6WWEsaWRlbnRpdHk6WmEsaW52ZXJ0OkJuLG11bDpHZSxtdWx0aXBseTpHZSxtdWx0aXBseVNjYWxhcjpubCxtdWx0aXBseVNjYWxhckFuZEFkZDpybCxub3JtYWxGcm9tTWF0NDpXbixwcm9qZWN0aW9uOkphLHJvdGF0ZTpTaSxzY2FsZTpZbixzZXQ6V2Esc3RyOkhhLHN1YjpMaSxzdWJ0cmFjdDpMaSx0cmFuc2xhdGU6SWksdHJhbnNwb3NlOkRufSksWm47KGZ1bmN0aW9uKGUpe2VbZS5DT0wwUk9XMD0wXT0iQ09MMFJPVzAiLGVbZS5DT0wwUk9XMT0xXT0iQ09MMFJPVzEiLGVbZS5DT0wwUk9XMj0yXT0iQ09MMFJPVzIiLGVbZS5DT0wxUk9XMD0zXT0iQ09MMVJPVzAiLGVbZS5DT0wxUk9XMT00XT0iQ09MMVJPVzEiLGVbZS5DT0wxUk9XMj01XT0iQ09MMVJPVzIiLGVbZS5DT0wyUk9XMD02XT0iQ09MMlJPVzAiLGVbZS5DT0wyUk9XMT03XT0iQ09MMlJPVzEiLGVbZS5DT0wyUk9XMj04XT0iQ09MMlJPVzIifSkoWm58fChabj17fSkpO2NvbnN0IGNsPU9iamVjdC5mcmVlemUoWzEsMCwwLDAsMSwwLDAsMCwxXSk7Y2xhc3MgZHQgZXh0ZW5kcyBVbntzdGF0aWMgZ2V0IElERU5USVRZKCl7cmV0dXJuIGxsKCl9c3RhdGljIGdldCBaRVJPKCl7cmV0dXJuIGFsKCl9Z2V0IEVMRU1FTlRTKCl7cmV0dXJuIDl9Z2V0IFJBTksoKXtyZXR1cm4gM31nZXQgSU5ESUNFUygpe3JldHVybiBabn1jb25zdHJ1Y3Rvcih0LC4uLm4pe3N1cGVyKC0wLC0wLC0wLC0wLC0wLC0wLC0wLC0wLC0wKSxhcmd1bWVudHMubGVuZ3RoPT09MSYmQXJyYXkuaXNBcnJheSh0KT90aGlzLmNvcHkodCk6bi5sZW5ndGg+MD90aGlzLmNvcHkoW3QsLi4ubl0pOnRoaXMuaWRlbnRpdHkoKX1jb3B5KHQpe3JldHVybiB0aGlzWzBdPXRbMF0sdGhpc1sxXT10WzFdLHRoaXNbMl09dFsyXSx0aGlzWzNdPXRbM10sdGhpc1s0XT10WzRdLHRoaXNbNV09dFs1XSx0aGlzWzZdPXRbNl0sdGhpc1s3XT10WzddLHRoaXNbOF09dFs4XSx0aGlzLmNoZWNrKCl9aWRlbnRpdHkoKXtyZXR1cm4gdGhpcy5jb3B5KGNsKX1mcm9tT2JqZWN0KHQpe3JldHVybiB0aGlzLmNoZWNrKCl9ZnJvbVF1YXRlcm5pb24odCl7cmV0dXJuIFBpKHRoaXMsdCksdGhpcy5jaGVjaygpfXNldCh0LG4scixpLHMsbyxjLGwsaCl7cmV0dXJuIHRoaXNbMF09dCx0aGlzWzFdPW4sdGhpc1syXT1yLHRoaXNbM109aSx0aGlzWzRdPXMsdGhpc1s1XT1vLHRoaXNbNl09Yyx0aGlzWzddPWwsdGhpc1s4XT1oLHRoaXMuY2hlY2soKX1zZXRSb3dNYWpvcih0LG4scixpLHMsbyxjLGwsaCl7cmV0dXJuIHRoaXNbMF09dCx0aGlzWzFdPWksdGhpc1syXT1jLHRoaXNbM109bix0aGlzWzRdPXMsdGhpc1s1XT1sLHRoaXNbNl09cix0aGlzWzddPW8sdGhpc1s4XT1oLHRoaXMuY2hlY2soKX1kZXRlcm1pbmFudCgpe3JldHVybiBmZSh0aGlzKX10cmFuc3Bvc2UoKXtyZXR1cm4gRG4odGhpcyx0aGlzKSx0aGlzLmNoZWNrKCl9aW52ZXJ0KCl7cmV0dXJuIEJuKHRoaXMsdGhpcyksdGhpcy5jaGVjaygpfW11bHRpcGx5TGVmdCh0KXtyZXR1cm4gR2UodGhpcyx0LHRoaXMpLHRoaXMuY2hlY2soKX1tdWx0aXBseVJpZ2h0KHQpe3JldHVybiBHZSh0aGlzLHRoaXMsdCksdGhpcy5jaGVjaygpfXJvdGF0ZSh0KXtyZXR1cm4gU2kodGhpcyx0aGlzLHQpLHRoaXMuY2hlY2soKX1zY2FsZSh0KXtyZXR1cm4gQXJyYXkuaXNBcnJheSh0KT9Zbih0aGlzLHRoaXMsdCk6WW4odGhpcyx0aGlzLFt0LHRdKSx0aGlzLmNoZWNrKCl9dHJhbnNsYXRlKHQpe3JldHVybiBJaSh0aGlzLHRoaXMsdCksdGhpcy5jaGVjaygpfXRyYW5zZm9ybSh0LG4pe2xldCByO3N3aXRjaCh0Lmxlbmd0aCl7Y2FzZSAyOnI9U24obnx8Wy0wLC0wXSx0LHRoaXMpO2JyZWFrO2Nhc2UgMzpyPUZuKG58fFstMCwtMCwtMF0sdCx0aGlzKTticmVhaztjYXNlIDQ6cj1DbihufHxbLTAsLTAsLTAsLTBdLHQsdGhpcyk7YnJlYWs7ZGVmYXVsdDp0aHJvdyBuZXcgRXJyb3IoIklsbGVnYWwgdmVjdG9yIil9cmV0dXJuIGxlKHIsdC5sZW5ndGgpLHJ9dHJhbnNmb3JtVmVjdG9yKHQsbil7cmV0dXJuIHRoaXMudHJhbnNmb3JtKHQsbil9dHJhbnNmb3JtVmVjdG9yMih0LG4pe3JldHVybiB0aGlzLnRyYW5zZm9ybSh0LG4pfXRyYW5zZm9ybVZlY3RvcjModCxuKXtyZXR1cm4gdGhpcy50cmFuc2Zvcm0odCxuKX19bGV0IFhlLGplPW51bGw7ZnVuY3Rpb24gYWwoKXtyZXR1cm4gWGV8fChYZT1uZXcgZHQoWzAsMCwwLDAsMCwwLDAsMCwwXSksT2JqZWN0LmZyZWV6ZShYZSkpLFhlfWZ1bmN0aW9uIGxsKCl7cmV0dXJuIGplfHwoamU9bmV3IGR0LE9iamVjdC5mcmVlemUoamUpKSxqZX1mdW5jdGlvbiBobCgpe2NvbnN0IGU9bmV3IEIoMTYpO3JldHVybiBCIT1GbG9hdDMyQXJyYXkmJihlWzFdPTAsZVsyXT0wLGVbM109MCxlWzRdPTAsZVs2XT0wLGVbN109MCxlWzhdPTAsZVs5XT0wLGVbMTFdPTAsZVsxMl09MCxlWzEzXT0wLGVbMTRdPTApLGVbMF09MSxlWzVdPTEsZVsxMF09MSxlWzE1XT0xLGV9ZnVuY3Rpb24gZmwoZSl7Y29uc3QgdD1uZXcgQigxNik7cmV0dXJuIHRbMF09ZVswXSx0WzFdPWVbMV0sdFsyXT1lWzJdLHRbM109ZVszXSx0WzRdPWVbNF0sdFs1XT1lWzVdLHRbNl09ZVs2XSx0WzddPWVbN10sdFs4XT1lWzhdLHRbOV09ZVs5XSx0WzEwXT1lWzEwXSx0WzExXT1lWzExXSx0WzEyXT1lWzEyXSx0WzEzXT1lWzEzXSx0WzE0XT1lWzE0XSx0WzE1XT1lWzE1XSx0fWZ1bmN0aW9uIHVsKGUsdCl7cmV0dXJuIGVbMF09dFswXSxlWzFdPXRbMV0sZVsyXT10WzJdLGVbM109dFszXSxlWzRdPXRbNF0sZVs1XT10WzVdLGVbNl09dFs2XSxlWzddPXRbN10sZVs4XT10WzhdLGVbOV09dFs5XSxlWzEwXT10WzEwXSxlWzExXT10WzExXSxlWzEyXT10WzEyXSxlWzEzXT10WzEzXSxlWzE0XT10WzE0XSxlWzE1XT10WzE1XSxlfWZ1bmN0aW9uIGRsKGUsdCxuLHIsaSxzLG8sYyxsLGgsZix1LGQsZyxtLF8pe2NvbnN0IHA9bmV3IEIoMTYpO3JldHVybiBwWzBdPWUscFsxXT10LHBbMl09bixwWzNdPXIscFs0XT1pLHBbNV09cyxwWzZdPW8scFs3XT1jLHBbOF09bCxwWzldPWgscFsxMF09ZixwWzExXT11LHBbMTJdPWQscFsxM109ZyxwWzE0XT1tLHBbMTVdPV8scH1mdW5jdGlvbiBnbChlLHQsbixyLGkscyxvLGMsbCxoLGYsdSxkLGcsbSxfLHApe3JldHVybiBlWzBdPXQsZVsxXT1uLGVbMl09cixlWzNdPWksZVs0XT1zLGVbNV09byxlWzZdPWMsZVs3XT1sLGVbOF09aCxlWzldPWYsZVsxMF09dSxlWzExXT1kLGVbMTJdPWcsZVsxM109bSxlWzE0XT1fLGVbMTVdPXAsZX1mdW5jdGlvbiBSaShlKXtyZXR1cm4gZVswXT0xLGVbMV09MCxlWzJdPTAsZVszXT0wLGVbNF09MCxlWzVdPTEsZVs2XT0wLGVbN109MCxlWzhdPTAsZVs5XT0wLGVbMTBdPTEsZVsxMV09MCxlWzEyXT0wLGVbMTNdPTAsZVsxNF09MCxlWzE1XT0xLGV9ZnVuY3Rpb24gQ2koZSx0KXtpZihlPT09dCl7Y29uc3Qgbj10WzFdLHI9dFsyXSxpPXRbM10scz10WzZdLG89dFs3XSxjPXRbMTFdO2VbMV09dFs0XSxlWzJdPXRbOF0sZVszXT10WzEyXSxlWzRdPW4sZVs2XT10WzldLGVbN109dFsxM10sZVs4XT1yLGVbOV09cyxlWzExXT10WzE0XSxlWzEyXT1pLGVbMTNdPW8sZVsxNF09Y31lbHNlIGVbMF09dFswXSxlWzFdPXRbNF0sZVsyXT10WzhdLGVbM109dFsxMl0sZVs0XT10WzFdLGVbNV09dFs1XSxlWzZdPXRbOV0sZVs3XT10WzEzXSxlWzhdPXRbMl0sZVs5XT10WzZdLGVbMTBdPXRbMTBdLGVbMTFdPXRbMTRdLGVbMTJdPXRbM10sZVsxM109dFs3XSxlWzE0XT10WzExXSxlWzE1XT10WzE1XTtyZXR1cm4gZX1mdW5jdGlvbiBHbihlLHQpe2NvbnN0IG49dFswXSxyPXRbMV0saT10WzJdLHM9dFszXSxvPXRbNF0sYz10WzVdLGw9dFs2XSxoPXRbN10sZj10WzhdLHU9dFs5XSxkPXRbMTBdLGc9dFsxMV0sbT10WzEyXSxfPXRbMTNdLHA9dFsxNF0sTT10WzE1XSxBPW4qYy1yKm8seD1uKmwtaSpvLFQ9bipoLXMqbyx2PXIqbC1pKmMsdz1yKmgtcypjLFM9aSpoLXMqbCxiPWYqXy11Km0sST1mKnAtZCptLEU9ZipNLWcqbSxWPXUqcC1kKl8sTj11Kk0tZypfLHo9ZCpNLWcqcDtsZXQgTD1BKnoteCpOK1QqVit2KkUtdypJK1MqYjtyZXR1cm4gTD8oTD0xL0wsZVswXT0oYyp6LWwqTitoKlYpKkwsZVsxXT0oaSpOLXIqei1zKlYpKkwsZVsyXT0oXypTLXAqdytNKnYpKkwsZVszXT0oZCp3LXUqUy1nKnYpKkwsZVs0XT0obCpFLW8qei1oKkkpKkwsZVs1XT0obip6LWkqRStzKkkpKkwsZVs2XT0ocCpULW0qUy1NKngpKkwsZVs3XT0oZipTLWQqVCtnKngpKkwsZVs4XT0obypOLWMqRStoKmIpKkwsZVs5XT0ocipFLW4qTi1zKmIpKkwsZVsxMF09KG0qdy1fKlQrTSpBKSpMLGVbMTFdPSh1KlQtZip3LWcqQSkqTCxlWzEyXT0oYypJLW8qVi1sKmIpKkwsZVsxM109KG4qVi1yKkkraSpiKSpMLGVbMTRdPShfKngtbSp2LXAqQSkqTCxlWzE1XT0oZip2LXUqeCtkKkEpKkwsZSk6bnVsbH1mdW5jdGlvbiBtbChlLHQpe2NvbnN0IG49dFswXSxyPXRbMV0saT10WzJdLHM9dFszXSxvPXRbNF0sYz10WzVdLGw9dFs2XSxoPXRbN10sZj10WzhdLHU9dFs5XSxkPXRbMTBdLGc9dFsxMV0sbT10WzEyXSxfPXRbMTNdLHA9dFsxNF0sTT10WzE1XSxBPW4qYy1yKm8seD1uKmwtaSpvLFQ9bipoLXMqbyx2PXIqbC1pKmMsdz1yKmgtcypjLFM9aSpoLXMqbCxiPWYqXy11Km0sST1mKnAtZCptLEU9ZipNLWcqbSxWPXUqcC1kKl8sTj11Kk0tZypfLHo9ZCpNLWcqcDtyZXR1cm4gZVswXT1jKnotbCpOK2gqVixlWzFdPWkqTi1yKnotcypWLGVbMl09XypTLXAqdytNKnYsZVszXT1kKnctdSpTLWcqdixlWzRdPWwqRS1vKnotaCpJLGVbNV09bip6LWkqRStzKkksZVs2XT1wKlQtbSpTLU0qeCxlWzddPWYqUy1kKlQrZyp4LGVbOF09bypOLWMqRStoKmIsZVs5XT1yKkUtbipOLXMqYixlWzEwXT1tKnctXypUK00qQSxlWzExXT11KlQtZip3LWcqQSxlWzEyXT1jKkktbypWLWwqYixlWzEzXT1uKlYtcipJK2kqYixlWzE0XT1fKngtbSp2LXAqQSxlWzE1XT1mKnYtdSp4K2QqQSxlfWZ1bmN0aW9uIFhuKGUpe2NvbnN0IHQ9ZVswXSxuPWVbMV0scj1lWzJdLGk9ZVszXSxzPWVbNF0sbz1lWzVdLGM9ZVs2XSxsPWVbN10saD1lWzhdLGY9ZVs5XSx1PWVbMTBdLGQ9ZVsxMV0sZz1lWzEyXSxtPWVbMTNdLF89ZVsxNF0scD1lWzE1XSxNPXQqby1uKnMsQT10KmMtcipzLHg9bipjLXIqbyxUPWgqbS1mKmcsdj1oKl8tdSpnLHc9ZipfLXUqbSxTPXQqdy1uKnYrcipULGI9cyp3LW8qditjKlQsST1oKngtZipBK3UqTSxFPWcqeC1tKkErXypNO3JldHVybiBsKlMtaSpiK3AqSS1kKkV9ZnVuY3Rpb24gUWUoZSx0LG4pe2NvbnN0IHI9dFswXSxpPXRbMV0scz10WzJdLG89dFszXSxjPXRbNF0sbD10WzVdLGg9dFs2XSxmPXRbN10sdT10WzhdLGQ9dFs5XSxnPXRbMTBdLG09dFsxMV0sXz10WzEyXSxwPXRbMTNdLE09dFsxNF0sQT10WzE1XTtsZXQgeD1uWzBdLFQ9blsxXSx2PW5bMl0sdz1uWzNdO3JldHVybiBlWzBdPXgqcitUKmMrdip1K3cqXyxlWzFdPXgqaStUKmwrdipkK3cqcCxlWzJdPXgqcytUKmgrdipnK3cqTSxlWzNdPXgqbytUKmYrdiptK3cqQSx4PW5bNF0sVD1uWzVdLHY9bls2XSx3PW5bN10sZVs0XT14KnIrVCpjK3YqdSt3Kl8sZVs1XT14KmkrVCpsK3YqZCt3KnAsZVs2XT14KnMrVCpoK3YqZyt3Kk0sZVs3XT14Km8rVCpmK3YqbSt3KkEseD1uWzhdLFQ9bls5XSx2PW5bMTBdLHc9blsxMV0sZVs4XT14KnIrVCpjK3YqdSt3Kl8sZVs5XT14KmkrVCpsK3YqZCt3KnAsZVsxMF09eCpzK1QqaCt2KmcrdypNLGVbMTFdPXgqbytUKmYrdiptK3cqQSx4PW5bMTJdLFQ9blsxM10sdj1uWzE0XSx3PW5bMTVdLGVbMTJdPXgqcitUKmMrdip1K3cqXyxlWzEzXT14KmkrVCpsK3YqZCt3KnAsZVsxNF09eCpzK1QqaCt2KmcrdypNLGVbMTVdPXgqbytUKmYrdiptK3cqQSxlfWZ1bmN0aW9uIFZpKGUsdCxuKXtjb25zdCByPW5bMF0saT1uWzFdLHM9blsyXTtsZXQgbyxjLGwsaCxmLHUsZCxnLG0sXyxwLE07cmV0dXJuIHQ9PT1lPyhlWzEyXT10WzBdKnIrdFs0XSppK3RbOF0qcyt0WzEyXSxlWzEzXT10WzFdKnIrdFs1XSppK3RbOV0qcyt0WzEzXSxlWzE0XT10WzJdKnIrdFs2XSppK3RbMTBdKnMrdFsxNF0sZVsxNV09dFszXSpyK3RbN10qaSt0WzExXSpzK3RbMTVdKToobz10WzBdLGM9dFsxXSxsPXRbMl0saD10WzNdLGY9dFs0XSx1PXRbNV0sZD10WzZdLGc9dFs3XSxtPXRbOF0sXz10WzldLHA9dFsxMF0sTT10WzExXSxlWzBdPW8sZVsxXT1jLGVbMl09bCxlWzNdPWgsZVs0XT1mLGVbNV09dSxlWzZdPWQsZVs3XT1nLGVbOF09bSxlWzldPV8sZVsxMF09cCxlWzExXT1NLGVbMTJdPW8qcitmKmkrbSpzK3RbMTJdLGVbMTNdPWMqcit1KmkrXypzK3RbMTNdLGVbMTRdPWwqcitkKmkrcCpzK3RbMTRdLGVbMTVdPWgqcitnKmkrTSpzK3RbMTVdKSxlfWZ1bmN0aW9uIE5pKGUsdCxuKXtjb25zdCByPW5bMF0saT1uWzFdLHM9blsyXTtyZXR1cm4gZVswXT10WzBdKnIsZVsxXT10WzFdKnIsZVsyXT10WzJdKnIsZVszXT10WzNdKnIsZVs0XT10WzRdKmksZVs1XT10WzVdKmksZVs2XT10WzZdKmksZVs3XT10WzddKmksZVs4XT10WzhdKnMsZVs5XT10WzldKnMsZVsxMF09dFsxMF0qcyxlWzExXT10WzExXSpzLGVbMTJdPXRbMTJdLGVbMTNdPXRbMTNdLGVbMTRdPXRbMTRdLGVbMTVdPXRbMTVdLGV9ZnVuY3Rpb24gemkoZSx0LG4scil7bGV0IGk9clswXSxzPXJbMV0sbz1yWzJdLGM9TWF0aC5zcXJ0KGkqaStzKnMrbypvKSxsLGgsZix1LGQsZyxtLF8scCxNLEEseCxULHYsdyxTLGIsSSxFLFYsTix6LEwsSDtyZXR1cm4gYzxDP251bGw6KGM9MS9jLGkqPWMscyo9YyxvKj1jLGg9TWF0aC5zaW4obiksbD1NYXRoLmNvcyhuKSxmPTEtbCx1PXRbMF0sZD10WzFdLGc9dFsyXSxtPXRbM10sXz10WzRdLHA9dFs1XSxNPXRbNl0sQT10WzddLHg9dFs4XSxUPXRbOV0sdj10WzEwXSx3PXRbMTFdLFM9aSppKmYrbCxiPXMqaSpmK28qaCxJPW8qaSpmLXMqaCxFPWkqcypmLW8qaCxWPXMqcypmK2wsTj1vKnMqZitpKmgsej1pKm8qZitzKmgsTD1zKm8qZi1pKmgsSD1vKm8qZitsLGVbMF09dSpTK18qYit4KkksZVsxXT1kKlMrcCpiK1QqSSxlWzJdPWcqUytNKmIrdipJLGVbM109bSpTK0EqYit3KkksZVs0XT11KkUrXypWK3gqTixlWzVdPWQqRStwKlYrVCpOLGVbNl09ZypFK00qVit2Kk4sZVs3XT1tKkUrQSpWK3cqTixlWzhdPXUqeitfKkwreCpILGVbOV09ZCp6K3AqTCtUKkgsZVsxMF09Zyp6K00qTCt2KkgsZVsxMV09bSp6K0EqTCt3KkgsdCE9PWUmJihlWzEyXT10WzEyXSxlWzEzXT10WzEzXSxlWzE0XT10WzE0XSxlWzE1XT10WzE1XSksZSl9ZnVuY3Rpb24gJGkoZSx0LG4pe2NvbnN0IHI9TWF0aC5zaW4obiksaT1NYXRoLmNvcyhuKSxzPXRbNF0sbz10WzVdLGM9dFs2XSxsPXRbN10saD10WzhdLGY9dFs5XSx1PXRbMTBdLGQ9dFsxMV07cmV0dXJuIHQhPT1lJiYoZVswXT10WzBdLGVbMV09dFsxXSxlWzJdPXRbMl0sZVszXT10WzNdLGVbMTJdPXRbMTJdLGVbMTNdPXRbMTNdLGVbMTRdPXRbMTRdLGVbMTVdPXRbMTVdKSxlWzRdPXMqaStoKnIsZVs1XT1vKmkrZipyLGVbNl09YyppK3UqcixlWzddPWwqaStkKnIsZVs4XT1oKmktcypyLGVbOV09ZippLW8qcixlWzEwXT11KmktYypyLGVbMTFdPWQqaS1sKnIsZX1mdW5jdGlvbiBraShlLHQsbil7Y29uc3Qgcj1NYXRoLnNpbihuKSxpPU1hdGguY29zKG4pLHM9dFswXSxvPXRbMV0sYz10WzJdLGw9dFszXSxoPXRbOF0sZj10WzldLHU9dFsxMF0sZD10WzExXTtyZXR1cm4gdCE9PWUmJihlWzRdPXRbNF0sZVs1XT10WzVdLGVbNl09dFs2XSxlWzddPXRbN10sZVsxMl09dFsxMl0sZVsxM109dFsxM10sZVsxNF09dFsxNF0sZVsxNV09dFsxNV0pLGVbMF09cyppLWgqcixlWzFdPW8qaS1mKnIsZVsyXT1jKmktdSpyLGVbM109bCppLWQqcixlWzhdPXMqcitoKmksZVs5XT1vKnIrZippLGVbMTBdPWMqcit1KmksZVsxMV09bCpyK2QqaSxlfWZ1bmN0aW9uIEZpKGUsdCxuKXtjb25zdCByPU1hdGguc2luKG4pLGk9TWF0aC5jb3Mobikscz10WzBdLG89dFsxXSxjPXRbMl0sbD10WzNdLGg9dFs0XSxmPXRbNV0sdT10WzZdLGQ9dFs3XTtyZXR1cm4gdCE9PWUmJihlWzhdPXRbOF0sZVs5XT10WzldLGVbMTBdPXRbMTBdLGVbMTFdPXRbMTFdLGVbMTJdPXRbMTJdLGVbMTNdPXRbMTNdLGVbMTRdPXRbMTRdLGVbMTVdPXRbMTVdKSxlWzBdPXMqaStoKnIsZVsxXT1vKmkrZipyLGVbMl09YyppK3UqcixlWzNdPWwqaStkKnIsZVs0XT1oKmktcypyLGVbNV09ZippLW8qcixlWzZdPXUqaS1jKnIsZVs3XT1kKmktbCpyLGV9ZnVuY3Rpb24gcGwoZSx0KXtyZXR1cm4gZVswXT0xLGVbMV09MCxlWzJdPTAsZVszXT0wLGVbNF09MCxlWzVdPTEsZVs2XT0wLGVbN109MCxlWzhdPTAsZVs5XT0wLGVbMTBdPTEsZVsxMV09MCxlWzEyXT10WzBdLGVbMTNdPXRbMV0sZVsxNF09dFsyXSxlWzE1XT0xLGV9ZnVuY3Rpb24gcWkoZSx0KXtyZXR1cm4gZVswXT10WzBdLGVbMV09MCxlWzJdPTAsZVszXT0wLGVbNF09MCxlWzVdPXRbMV0sZVs2XT0wLGVbN109MCxlWzhdPTAsZVs5XT0wLGVbMTBdPXRbMl0sZVsxMV09MCxlWzEyXT0wLGVbMTNdPTAsZVsxNF09MCxlWzE1XT0xLGV9ZnVuY3Rpb24gX2woZSx0LG4pe2xldCByPW5bMF0saT1uWzFdLHM9blsyXSxvPU1hdGguc3FydChyKnIraSppK3MqcyksYyxsLGg7cmV0dXJuIG88Qz9udWxsOihvPTEvbyxyKj1vLGkqPW8scyo9byxsPU1hdGguc2luKHQpLGM9TWF0aC5jb3ModCksaD0xLWMsZVswXT1yKnIqaCtjLGVbMV09aSpyKmgrcypsLGVbMl09cypyKmgtaSpsLGVbM109MCxlWzRdPXIqaSpoLXMqbCxlWzVdPWkqaSpoK2MsZVs2XT1zKmkqaCtyKmwsZVs3XT0wLGVbOF09cipzKmgraSpsLGVbOV09aSpzKmgtcipsLGVbMTBdPXMqcypoK2MsZVsxMV09MCxlWzEyXT0wLGVbMTNdPTAsZVsxNF09MCxlWzE1XT0xLGUpfWZ1bmN0aW9uIHlsKGUsdCl7Y29uc3Qgbj1NYXRoLnNpbih0KSxyPU1hdGguY29zKHQpO3JldHVybiBlWzBdPTEsZVsxXT0wLGVbMl09MCxlWzNdPTAsZVs0XT0wLGVbNV09cixlWzZdPW4sZVs3XT0wLGVbOF09MCxlWzldPS1uLGVbMTBdPXIsZVsxMV09MCxlWzEyXT0wLGVbMTNdPTAsZVsxNF09MCxlWzE1XT0xLGV9ZnVuY3Rpb24geGwoZSx0KXtjb25zdCBuPU1hdGguc2luKHQpLHI9TWF0aC5jb3ModCk7cmV0dXJuIGVbMF09cixlWzFdPTAsZVsyXT0tbixlWzNdPTAsZVs0XT0wLGVbNV09MSxlWzZdPTAsZVs3XT0wLGVbOF09bixlWzldPTAsZVsxMF09cixlWzExXT0wLGVbMTJdPTAsZVsxM109MCxlWzE0XT0wLGVbMTVdPTEsZX1mdW5jdGlvbiBNbChlLHQpe2NvbnN0IG49TWF0aC5zaW4odCkscj1NYXRoLmNvcyh0KTtyZXR1cm4gZVswXT1yLGVbMV09bixlWzJdPTAsZVszXT0wLGVbNF09LW4sZVs1XT1yLGVbNl09MCxlWzddPTAsZVs4XT0wLGVbOV09MCxlWzEwXT0xLGVbMTFdPTAsZVsxMl09MCxlWzEzXT0wLGVbMTRdPTAsZVsxNV09MSxlfWZ1bmN0aW9uIFVpKGUsdCxuKXtjb25zdCByPXRbMF0saT10WzFdLHM9dFsyXSxvPXRbM10sYz1yK3IsbD1pK2ksaD1zK3MsZj1yKmMsdT1yKmwsZD1yKmgsZz1pKmwsbT1pKmgsXz1zKmgscD1vKmMsTT1vKmwsQT1vKmg7cmV0dXJuIGVbMF09MS0oZytfKSxlWzFdPXUrQSxlWzJdPWQtTSxlWzNdPTAsZVs0XT11LUEsZVs1XT0xLShmK18pLGVbNl09bStwLGVbN109MCxlWzhdPWQrTSxlWzldPW0tcCxlWzEwXT0xLShmK2cpLGVbMTFdPTAsZVsxMl09blswXSxlWzEzXT1uWzFdLGVbMTRdPW5bMl0sZVsxNV09MSxlfWZ1bmN0aW9uIHdsKGUsdCl7Y29uc3Qgbj1uZXcgQigzKSxyPS10WzBdLGk9LXRbMV0scz0tdFsyXSxvPXRbM10sYz10WzRdLGw9dFs1XSxoPXRbNl0sZj10WzddLHU9cipyK2kqaStzKnMrbypvO3JldHVybiB1PjA/KG5bMF09KGMqbytmKnIrbCpzLWgqaSkqMi91LG5bMV09KGwqbytmKmkraCpyLWMqcykqMi91LG5bMl09KGgqbytmKnMrYyppLWwqcikqMi91KTooblswXT0oYypvK2YqcitsKnMtaCppKSoyLG5bMV09KGwqbytmKmkraCpyLWMqcykqMixuWzJdPShoKm8rZipzK2MqaS1sKnIpKjIpLFVpKGUsdCxuKSxlfWZ1bmN0aW9uIERpKGUsdCl7cmV0dXJuIGVbMF09dFsxMl0sZVsxXT10WzEzXSxlWzJdPXRbMTRdLGV9ZnVuY3Rpb24gQmkoZSx0KXtjb25zdCBuPXRbMF0scj10WzFdLGk9dFsyXSxzPXRbNF0sbz10WzVdLGM9dFs2XSxsPXRbOF0saD10WzldLGY9dFsxMF07cmV0dXJuIGVbMF09TWF0aC5zcXJ0KG4qbityKnIraSppKSxlWzFdPU1hdGguc3FydChzKnMrbypvK2MqYyksZVsyXT1NYXRoLnNxcnQobCpsK2gqaCtmKmYpLGV9ZnVuY3Rpb24gQWwoZSx0KXtjb25zdCBuPW5ldyBCKDMpO0JpKG4sdCk7Y29uc3Qgcj0xL25bMF0saT0xL25bMV0scz0xL25bMl0sbz10WzBdKnIsYz10WzFdKmksbD10WzJdKnMsaD10WzRdKnIsZj10WzVdKmksdT10WzZdKnMsZD10WzhdKnIsZz10WzldKmksbT10WzEwXSpzLF89bytmK207bGV0IHA9MDtyZXR1cm4gXz4wPyhwPU1hdGguc3FydChfKzEpKjIsZVszXT0uMjUqcCxlWzBdPSh1LWcpL3AsZVsxXT0oZC1sKS9wLGVbMl09KGMtaCkvcCk6bz5mJiZvPm0/KHA9TWF0aC5zcXJ0KDErby1mLW0pKjIsZVszXT0odS1nKS9wLGVbMF09LjI1KnAsZVsxXT0oYytoKS9wLGVbMl09KGQrbCkvcCk6Zj5tPyhwPU1hdGguc3FydCgxK2Ytby1tKSoyLGVbM109KGQtbCkvcCxlWzBdPShjK2gpL3AsZVsxXT0uMjUqcCxlWzJdPSh1K2cpL3ApOihwPU1hdGguc3FydCgxK20tby1mKSoyLGVbM109KGMtaCkvcCxlWzBdPShkK2wpL3AsZVsxXT0odStnKS9wLGVbMl09LjI1KnApLGV9ZnVuY3Rpb24gVGwoZSx0LG4scil7dFswXT1yWzEyXSx0WzFdPXJbMTNdLHRbMl09clsxNF07Y29uc3QgaT1yWzBdLHM9clsxXSxvPXJbMl0sYz1yWzRdLGw9cls1XSxoPXJbNl0sZj1yWzhdLHU9cls5XSxkPXJbMTBdO25bMF09TWF0aC5zcXJ0KGkqaStzKnMrbypvKSxuWzFdPU1hdGguc3FydChjKmMrbCpsK2gqaCksblsyXT1NYXRoLnNxcnQoZipmK3UqdStkKmQpO2NvbnN0IGc9MS9uWzBdLG09MS9uWzFdLF89MS9uWzJdLHA9aSpnLE09cyptLEE9bypfLHg9YypnLFQ9bCptLHY9aCpfLHc9ZipnLFM9dSptLGI9ZCpfLEk9cCtUK2I7bGV0IEU9MDtyZXR1cm4gST4wPyhFPU1hdGguc3FydChJKzEpKjIsZVszXT0uMjUqRSxlWzBdPSh2LVMpL0UsZVsxXT0ody1BKS9FLGVbMl09KE0teCkvRSk6cD5UJiZwPmI/KEU9TWF0aC5zcXJ0KDErcC1ULWIpKjIsZVszXT0odi1TKS9FLGVbMF09LjI1KkUsZVsxXT0oTSt4KS9FLGVbMl09KHcrQSkvRSk6VD5iPyhFPU1hdGguc3FydCgxK1QtcC1iKSoyLGVbM109KHctQSkvRSxlWzBdPShNK3gpL0UsZVsxXT0uMjUqRSxlWzJdPSh2K1MpL0UpOihFPU1hdGguc3FydCgxK2ItcC1UKSoyLGVbM109KE0teCkvRSxlWzBdPSh3K0EpL0UsZVsxXT0oditTKS9FLGVbMl09LjI1KkUpLGV9ZnVuY3Rpb24gWWkoZSx0LG4scil7Y29uc3QgaT10WzBdLHM9dFsxXSxvPXRbMl0sYz10WzNdLGw9aStpLGg9cytzLGY9bytvLHU9aSpsLGQ9aSpoLGc9aSpmLG09cypoLF89cypmLHA9bypmLE09YypsLEE9YypoLHg9YypmLFQ9clswXSx2PXJbMV0sdz1yWzJdO3JldHVybiBlWzBdPSgxLShtK3ApKSpULGVbMV09KGQreCkqVCxlWzJdPShnLUEpKlQsZVszXT0wLGVbNF09KGQteCkqdixlWzVdPSgxLSh1K3ApKSp2LGVbNl09KF8rTSkqdixlWzddPTAsZVs4XT0oZytBKSp3LGVbOV09KF8tTSkqdyxlWzEwXT0oMS0odSttKSkqdyxlWzExXT0wLGVbMTJdPW5bMF0sZVsxM109blsxXSxlWzE0XT1uWzJdLGVbMTVdPTEsZX1mdW5jdGlvbiB2bChlLHQsbixyLGkpe2NvbnN0IHM9dFswXSxvPXRbMV0sYz10WzJdLGw9dFszXSxoPXMrcyxmPW8rbyx1PWMrYyxkPXMqaCxnPXMqZixtPXMqdSxfPW8qZixwPW8qdSxNPWMqdSxBPWwqaCx4PWwqZixUPWwqdSx2PXJbMF0sdz1yWzFdLFM9clsyXSxiPWlbMF0sST1pWzFdLEU9aVsyXSxWPSgxLShfK00pKSp2LE49KGcrVCkqdix6PShtLXgpKnYsTD0oZy1UKSp3LEg9KDEtKGQrTSkpKncscT0ocCtBKSp3LFo9KG0reCkqUyxldD0ocC1BKSpTLG50PSgxLShkK18pKSpTO3JldHVybiBlWzBdPVYsZVsxXT1OLGVbMl09eixlWzNdPTAsZVs0XT1MLGVbNV09SCxlWzZdPXEsZVs3XT0wLGVbOF09WixlWzldPWV0LGVbMTBdPW50LGVbMTFdPTAsZVsxMl09blswXStiLShWKmIrTCpJK1oqRSksZVsxM109blsxXStJLShOKmIrSCpJK2V0KkUpLGVbMTRdPW5bMl0rRS0oeipiK3EqSStudCpFKSxlWzE1XT0xLGV9ZnVuY3Rpb24gV2koZSx0KXtjb25zdCBuPXRbMF0scj10WzFdLGk9dFsyXSxzPXRbM10sbz1uK24sYz1yK3IsbD1pK2ksaD1uKm8sZj1yKm8sdT1yKmMsZD1pKm8sZz1pKmMsbT1pKmwsXz1zKm8scD1zKmMsTT1zKmw7cmV0dXJuIGVbMF09MS11LW0sZVsxXT1mK00sZVsyXT1kLXAsZVszXT0wLGVbNF09Zi1NLGVbNV09MS1oLW0sZVs2XT1nK18sZVs3XT0wLGVbOF09ZCtwLGVbOV09Zy1fLGVbMTBdPTEtaC11LGVbMTFdPTAsZVsxMl09MCxlWzEzXT0wLGVbMTRdPTAsZVsxNV09MSxlfWZ1bmN0aW9uIFppKGUsdCxuLHIsaSxzLG8pe2NvbnN0IGM9MS8obi10KSxsPTEvKGktciksaD0xLyhzLW8pO3JldHVybiBlWzBdPXMqMipjLGVbMV09MCxlWzJdPTAsZVszXT0wLGVbNF09MCxlWzVdPXMqMipsLGVbNl09MCxlWzddPTAsZVs4XT0obit0KSpjLGVbOV09KGkrcikqbCxlWzEwXT0obytzKSpoLGVbMTFdPS0xLGVbMTJdPTAsZVsxM109MCxlWzE0XT1vKnMqMipoLGVbMTVdPTAsZX1mdW5jdGlvbiBHaShlLHQsbixyLGkpe2NvbnN0IHM9MS9NYXRoLnRhbih0LzIpO2lmKGVbMF09cy9uLGVbMV09MCxlWzJdPTAsZVszXT0wLGVbNF09MCxlWzVdPXMsZVs2XT0wLGVbN109MCxlWzhdPTAsZVs5XT0wLGVbMTFdPS0xLGVbMTJdPTAsZVsxM109MCxlWzE1XT0wLGkhPW51bGwmJmkhPT0xLzApe2NvbnN0IG89MS8oci1pKTtlWzEwXT0oaStyKSpvLGVbMTRdPTIqaSpyKm99ZWxzZSBlWzEwXT0tMSxlWzE0XT0tMipyO3JldHVybiBlfWNvbnN0IFhpPUdpO2Z1bmN0aW9uIEVsKGUsdCxuLHIsaSl7Y29uc3Qgcz0xL01hdGgudGFuKHQvMik7aWYoZVswXT1zL24sZVsxXT0wLGVbMl09MCxlWzNdPTAsZVs0XT0wLGVbNV09cyxlWzZdPTAsZVs3XT0wLGVbOF09MCxlWzldPTAsZVsxMV09LTEsZVsxMl09MCxlWzEzXT0wLGVbMTVdPTAsaSE9bnVsbCYmaSE9PTEvMCl7Y29uc3Qgbz0xLyhyLWkpO2VbMTBdPWkqbyxlWzE0XT1pKnIqb31lbHNlIGVbMTBdPS0xLGVbMTRdPS1yO3JldHVybiBlfWZ1bmN0aW9uIE9sKGUsdCxuLHIpe2NvbnN0IGk9TWF0aC50YW4odC51cERlZ3JlZXMqTWF0aC5QSS8xODApLHM9TWF0aC50YW4odC5kb3duRGVncmVlcypNYXRoLlBJLzE4MCksbz1NYXRoLnRhbih0LmxlZnREZWdyZWVzKk1hdGguUEkvMTgwKSxjPU1hdGgudGFuKHQucmlnaHREZWdyZWVzKk1hdGguUEkvMTgwKSxsPTIvKG8rYyksaD0yLyhpK3MpO3JldHVybiBlWzBdPWwsZVsxXT0wLGVbMl09MCxlWzNdPTAsZVs0XT0wLGVbNV09aCxlWzZdPTAsZVs3XT0wLGVbOF09LSgoby1jKSpsKi41KSxlWzldPShpLXMpKmgqLjUsZVsxMF09ci8obi1yKSxlWzExXT0tMSxlWzEyXT0wLGVbMTNdPTAsZVsxNF09cipuLyhuLXIpLGVbMTVdPTAsZX1mdW5jdGlvbiBqaShlLHQsbixyLGkscyxvKXtjb25zdCBjPTEvKHQtbiksbD0xLyhyLWkpLGg9MS8ocy1vKTtyZXR1cm4gZVswXT0tMipjLGVbMV09MCxlWzJdPTAsZVszXT0wLGVbNF09MCxlWzVdPS0yKmwsZVs2XT0wLGVbN109MCxlWzhdPTAsZVs5XT0wLGVbMTBdPTIqaCxlWzExXT0wLGVbMTJdPSh0K24pKmMsZVsxM109KGkrcikqbCxlWzE0XT0obytzKSpoLGVbMTVdPTEsZX1jb25zdCBRaT1qaTtmdW5jdGlvbiBibChlLHQsbixyLGkscyxvKXtjb25zdCBjPTEvKHQtbiksbD0xLyhyLWkpLGg9MS8ocy1vKTtyZXR1cm4gZVswXT0tMipjLGVbMV09MCxlWzJdPTAsZVszXT0wLGVbNF09MCxlWzVdPS0yKmwsZVs2XT0wLGVbN109MCxlWzhdPTAsZVs5XT0wLGVbMTBdPWgsZVsxMV09MCxlWzEyXT0odCtuKSpjLGVbMTNdPShpK3IpKmwsZVsxNF09cypoLGVbMTVdPTEsZX1mdW5jdGlvbiBLaShlLHQsbixyKXtsZXQgaSxzLG8sYyxsLGgsZix1LGQsZztjb25zdCBtPXRbMF0sXz10WzFdLHA9dFsyXSxNPXJbMF0sQT1yWzFdLHg9clsyXSxUPW5bMF0sdj1uWzFdLHc9blsyXTtyZXR1cm4gTWF0aC5hYnMobS1UKTxDJiZNYXRoLmFicyhfLXYpPEMmJk1hdGguYWJzKHAtdyk8Qz9SaShlKToodT1tLVQsZD1fLXYsZz1wLXcsaT0xL01hdGguc3FydCh1KnUrZCpkK2cqZyksdSo9aSxkKj1pLGcqPWkscz1BKmcteCpkLG89eCp1LU0qZyxjPU0qZC1BKnUsaT1NYXRoLnNxcnQocypzK28qbytjKmMpLGk/KGk9MS9pLHMqPWksbyo9aSxjKj1pKToocz0wLG89MCxjPTApLGw9ZCpjLWcqbyxoPWcqcy11KmMsZj11Km8tZCpzLGk9TWF0aC5zcXJ0KGwqbCtoKmgrZipmKSxpPyhpPTEvaSxsKj1pLGgqPWksZio9aSk6KGw9MCxoPTAsZj0wKSxlWzBdPXMsZVsxXT1sLGVbMl09dSxlWzNdPTAsZVs0XT1vLGVbNV09aCxlWzZdPWQsZVs3XT0wLGVbOF09YyxlWzldPWYsZVsxMF09ZyxlWzExXT0wLGVbMTJdPS0ocyptK28qXytjKnApLGVbMTNdPS0obCptK2gqXytmKnApLGVbMTRdPS0odSptK2QqXytnKnApLGVbMTVdPTEsZSl9ZnVuY3Rpb24gSWwoZSx0LG4scil7Y29uc3QgaT10WzBdLHM9dFsxXSxvPXRbMl0sYz1yWzBdLGw9clsxXSxoPXJbMl07bGV0IGY9aS1uWzBdLHU9cy1uWzFdLGQ9by1uWzJdLGc9ZipmK3UqdStkKmQ7Zz4wJiYoZz0xL01hdGguc3FydChnKSxmKj1nLHUqPWcsZCo9Zyk7bGV0IG09bCpkLWgqdSxfPWgqZi1jKmQscD1jKnUtbCpmO3JldHVybiBnPW0qbStfKl8rcCpwLGc+MCYmKGc9MS9NYXRoLnNxcnQoZyksbSo9ZyxfKj1nLHAqPWcpLGVbMF09bSxlWzFdPV8sZVsyXT1wLGVbM109MCxlWzRdPXUqcC1kKl8sZVs1XT1kKm0tZipwLGVbNl09ZipfLXUqbSxlWzddPTAsZVs4XT1mLGVbOV09dSxlWzEwXT1kLGVbMTFdPTAsZVsxMl09aSxlWzEzXT1zLGVbMTRdPW8sZVsxNV09MSxlfWZ1bmN0aW9uIFNsKGUpe3JldHVybmBtYXQ0KCR7ZVswXX0sICR7ZVsxXX0sICR7ZVsyXX0sICR7ZVszXX0sICR7ZVs0XX0sICR7ZVs1XX0sICR7ZVs2XX0sICR7ZVs3XX0sICR7ZVs4XX0sICR7ZVs5XX0sICR7ZVsxMF19LCAke2VbMTFdfSwgJHtlWzEyXX0sICR7ZVsxM119LCAke2VbMTRdfSwgJHtlWzE1XX0pYH1mdW5jdGlvbiBQbChlKXtyZXR1cm4gTWF0aC5zcXJ0KGVbMF0qZVswXStlWzFdKmVbMV0rZVsyXSplWzJdK2VbM10qZVszXStlWzRdKmVbNF0rZVs1XSplWzVdK2VbNl0qZVs2XStlWzddKmVbN10rZVs4XSplWzhdK2VbOV0qZVs5XStlWzEwXSplWzEwXStlWzExXSplWzExXStlWzEyXSplWzEyXStlWzEzXSplWzEzXStlWzE0XSplWzE0XStlWzE1XSplWzE1XSl9ZnVuY3Rpb24gTGwoZSx0LG4pe3JldHVybiBlWzBdPXRbMF0rblswXSxlWzFdPXRbMV0rblsxXSxlWzJdPXRbMl0rblsyXSxlWzNdPXRbM10rblszXSxlWzRdPXRbNF0rbls0XSxlWzVdPXRbNV0rbls1XSxlWzZdPXRbNl0rbls2XSxlWzddPXRbN10rbls3XSxlWzhdPXRbOF0rbls4XSxlWzldPXRbOV0rbls5XSxlWzEwXT10WzEwXStuWzEwXSxlWzExXT10WzExXStuWzExXSxlWzEyXT10WzEyXStuWzEyXSxlWzEzXT10WzEzXStuWzEzXSxlWzE0XT10WzE0XStuWzE0XSxlWzE1XT10WzE1XStuWzE1XSxlfWZ1bmN0aW9uIEppKGUsdCxuKXtyZXR1cm4gZVswXT10WzBdLW5bMF0sZVsxXT10WzFdLW5bMV0sZVsyXT10WzJdLW5bMl0sZVszXT10WzNdLW5bM10sZVs0XT10WzRdLW5bNF0sZVs1XT10WzVdLW5bNV0sZVs2XT10WzZdLW5bNl0sZVs3XT10WzddLW5bN10sZVs4XT10WzhdLW5bOF0sZVs5XT10WzldLW5bOV0sZVsxMF09dFsxMF0tblsxMF0sZVsxMV09dFsxMV0tblsxMV0sZVsxMl09dFsxMl0tblsxMl0sZVsxM109dFsxM10tblsxM10sZVsxNF09dFsxNF0tblsxNF0sZVsxNV09dFsxNV0tblsxNV0sZX1mdW5jdGlvbiBSbChlLHQsbil7cmV0dXJuIGVbMF09dFswXSpuLGVbMV09dFsxXSpuLGVbMl09dFsyXSpuLGVbM109dFszXSpuLGVbNF09dFs0XSpuLGVbNV09dFs1XSpuLGVbNl09dFs2XSpuLGVbN109dFs3XSpuLGVbOF09dFs4XSpuLGVbOV09dFs5XSpuLGVbMTBdPXRbMTBdKm4sZVsxMV09dFsxMV0qbixlWzEyXT10WzEyXSpuLGVbMTNdPXRbMTNdKm4sZVsxNF09dFsxNF0qbixlWzE1XT10WzE1XSpuLGV9ZnVuY3Rpb24gQ2woZSx0LG4scil7cmV0dXJuIGVbMF09dFswXStuWzBdKnIsZVsxXT10WzFdK25bMV0qcixlWzJdPXRbMl0rblsyXSpyLGVbM109dFszXStuWzNdKnIsZVs0XT10WzRdK25bNF0qcixlWzVdPXRbNV0rbls1XSpyLGVbNl09dFs2XStuWzZdKnIsZVs3XT10WzddK25bN10qcixlWzhdPXRbOF0rbls4XSpyLGVbOV09dFs5XStuWzldKnIsZVsxMF09dFsxMF0rblsxMF0qcixlWzExXT10WzExXStuWzExXSpyLGVbMTJdPXRbMTJdK25bMTJdKnIsZVsxM109dFsxM10rblsxM10qcixlWzE0XT10WzE0XStuWzE0XSpyLGVbMTVdPXRbMTVdK25bMTVdKnIsZX1mdW5jdGlvbiBWbChlLHQpe3JldHVybiBlWzBdPT09dFswXSYmZVsxXT09PXRbMV0mJmVbMl09PT10WzJdJiZlWzNdPT09dFszXSYmZVs0XT09PXRbNF0mJmVbNV09PT10WzVdJiZlWzZdPT09dFs2XSYmZVs3XT09PXRbN10mJmVbOF09PT10WzhdJiZlWzldPT09dFs5XSYmZVsxMF09PT10WzEwXSYmZVsxMV09PT10WzExXSYmZVsxMl09PT10WzEyXSYmZVsxM109PT10WzEzXSYmZVsxNF09PT10WzE0XSYmZVsxNV09PT10WzE1XX1mdW5jdGlvbiBObChlLHQpe2NvbnN0IG49ZVswXSxyPWVbMV0saT1lWzJdLHM9ZVszXSxvPWVbNF0sYz1lWzVdLGw9ZVs2XSxoPWVbN10sZj1lWzhdLHU9ZVs5XSxkPWVbMTBdLGc9ZVsxMV0sbT1lWzEyXSxfPWVbMTNdLHA9ZVsxNF0sTT1lWzE1XSxBPXRbMF0seD10WzFdLFQ9dFsyXSx2PXRbM10sdz10WzRdLFM9dFs1XSxiPXRbNl0sST10WzddLEU9dFs4XSxWPXRbOV0sTj10WzEwXSx6PXRbMTFdLEw9dFsxMl0sSD10WzEzXSxxPXRbMTRdLFo9dFsxNV07cmV0dXJuIE1hdGguYWJzKG4tQSk8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhuKSxNYXRoLmFicyhBKSkmJk1hdGguYWJzKHIteCk8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhyKSxNYXRoLmFicyh4KSkmJk1hdGguYWJzKGktVCk8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhpKSxNYXRoLmFicyhUKSkmJk1hdGguYWJzKHMtdik8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhzKSxNYXRoLmFicyh2KSkmJk1hdGguYWJzKG8tdyk8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhvKSxNYXRoLmFicyh3KSkmJk1hdGguYWJzKGMtUyk8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhjKSxNYXRoLmFicyhTKSkmJk1hdGguYWJzKGwtYik8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhsKSxNYXRoLmFicyhiKSkmJk1hdGguYWJzKGgtSSk8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhoKSxNYXRoLmFicyhJKSkmJk1hdGguYWJzKGYtRSk8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhmKSxNYXRoLmFicyhFKSkmJk1hdGguYWJzKHUtVik8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyh1KSxNYXRoLmFicyhWKSkmJk1hdGguYWJzKGQtTik8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhkKSxNYXRoLmFicyhOKSkmJk1hdGguYWJzKGcteik8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhnKSxNYXRoLmFicyh6KSkmJk1hdGguYWJzKG0tTCk8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhtKSxNYXRoLmFicyhMKSkmJk1hdGguYWJzKF8tSCk8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhfKSxNYXRoLmFicyhIKSkmJk1hdGguYWJzKHAtcSk8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhwKSxNYXRoLmFicyhxKSkmJk1hdGguYWJzKE0tWik8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhNKSxNYXRoLmFicyhaKSl9dmFyIHpsPU9iamVjdC5mcmVlemUoe19fcHJvdG9fXzpudWxsLGFkZDpMbCxhZGpvaW50Om1sLGNsb25lOmZsLGNvcHk6dWwsY3JlYXRlOmhsLGRlY29tcG9zZTpUbCxkZXRlcm1pbmFudDpYbixlcXVhbHM6TmwsZXhhY3RFcXVhbHM6VmwsZnJvYjpQbCxmcm9tUXVhdDpXaSxmcm9tUXVhdDI6d2wsZnJvbVJvdGF0aW9uOl9sLGZyb21Sb3RhdGlvblRyYW5zbGF0aW9uOlVpLGZyb21Sb3RhdGlvblRyYW5zbGF0aW9uU2NhbGU6WWksZnJvbVJvdGF0aW9uVHJhbnNsYXRpb25TY2FsZU9yaWdpbjp2bCxmcm9tU2NhbGluZzpxaSxmcm9tVHJhbnNsYXRpb246cGwsZnJvbVZhbHVlczpkbCxmcm9tWFJvdGF0aW9uOnlsLGZyb21ZUm90YXRpb246eGwsZnJvbVpSb3RhdGlvbjpNbCxmcnVzdHVtOlppLGdldFJvdGF0aW9uOkFsLGdldFNjYWxpbmc6QmksZ2V0VHJhbnNsYXRpb246RGksaWRlbnRpdHk6UmksaW52ZXJ0OkduLGxvb2tBdDpLaSxtdWw6UWUsbXVsdGlwbHk6UWUsbXVsdGlwbHlTY2FsYXI6UmwsbXVsdGlwbHlTY2FsYXJBbmRBZGQ6Q2wsb3J0aG86UWksb3J0aG9OTzpqaSxvcnRob1pPOmJsLHBlcnNwZWN0aXZlOlhpLHBlcnNwZWN0aXZlRnJvbUZpZWxkT2ZWaWV3Ok9sLHBlcnNwZWN0aXZlTk86R2kscGVyc3BlY3RpdmVaTzpFbCxyb3RhdGU6emkscm90YXRlWDokaSxyb3RhdGVZOmtpLHJvdGF0ZVo6Rmksc2NhbGU6Tmksc2V0OmdsLHN0cjpTbCxzdWI6Smksc3VidHJhY3Q6SmksdGFyZ2V0VG86SWwsdHJhbnNsYXRlOlZpLHRyYW5zcG9zZTpDaX0pO2Z1bmN0aW9uIEhpKCl7Y29uc3QgZT1uZXcgQig0KTtyZXR1cm4gQiE9RmxvYXQzMkFycmF5JiYoZVswXT0wLGVbMV09MCxlWzJdPTAsZVszXT0wKSxlfWZ1bmN0aW9uICRsKGUpe2NvbnN0IHQ9bmV3IEIoNCk7cmV0dXJuIHRbMF09ZVswXSx0WzFdPWVbMV0sdFsyXT1lWzJdLHRbM109ZVszXSx0fWZ1bmN0aW9uIGtsKGUsdCxuLHIpe2NvbnN0IGk9bmV3IEIoNCk7cmV0dXJuIGlbMF09ZSxpWzFdPXQsaVsyXT1uLGlbM109cixpfWZ1bmN0aW9uIEZsKGUsdCl7cmV0dXJuIGVbMF09dFswXSxlWzFdPXRbMV0sZVsyXT10WzJdLGVbM109dFszXSxlfWZ1bmN0aW9uIHFsKGUsdCxuLHIsaSl7cmV0dXJuIGVbMF09dCxlWzFdPW4sZVsyXT1yLGVbM109aSxlfWZ1bmN0aW9uIHRzKGUsdCxuKXtyZXR1cm4gZVswXT10WzBdK25bMF0sZVsxXT10WzFdK25bMV0sZVsyXT10WzJdK25bMl0sZVszXT10WzNdK25bM10sZX1mdW5jdGlvbiBlcyhlLHQsbil7cmV0dXJuIGVbMF09dFswXS1uWzBdLGVbMV09dFsxXS1uWzFdLGVbMl09dFsyXS1uWzJdLGVbM109dFszXS1uWzNdLGV9ZnVuY3Rpb24gbnMoZSx0LG4pe3JldHVybiBlWzBdPXRbMF0qblswXSxlWzFdPXRbMV0qblsxXSxlWzJdPXRbMl0qblsyXSxlWzNdPXRbM10qblszXSxlfWZ1bmN0aW9uIHJzKGUsdCxuKXtyZXR1cm4gZVswXT10WzBdL25bMF0sZVsxXT10WzFdL25bMV0sZVsyXT10WzJdL25bMl0sZVszXT10WzNdL25bM10sZX1mdW5jdGlvbiBVbChlLHQpe3JldHVybiBlWzBdPU1hdGguY2VpbCh0WzBdKSxlWzFdPU1hdGguY2VpbCh0WzFdKSxlWzJdPU1hdGguY2VpbCh0WzJdKSxlWzNdPU1hdGguY2VpbCh0WzNdKSxlfWZ1bmN0aW9uIERsKGUsdCl7cmV0dXJuIGVbMF09TWF0aC5mbG9vcih0WzBdKSxlWzFdPU1hdGguZmxvb3IodFsxXSksZVsyXT1NYXRoLmZsb29yKHRbMl0pLGVbM109TWF0aC5mbG9vcih0WzNdKSxlfWZ1bmN0aW9uIEJsKGUsdCxuKXtyZXR1cm4gZVswXT1NYXRoLm1pbih0WzBdLG5bMF0pLGVbMV09TWF0aC5taW4odFsxXSxuWzFdKSxlWzJdPU1hdGgubWluKHRbMl0sblsyXSksZVszXT1NYXRoLm1pbih0WzNdLG5bM10pLGV9ZnVuY3Rpb24gWWwoZSx0LG4pe3JldHVybiBlWzBdPU1hdGgubWF4KHRbMF0sblswXSksZVsxXT1NYXRoLm1heCh0WzFdLG5bMV0pLGVbMl09TWF0aC5tYXgodFsyXSxuWzJdKSxlWzNdPU1hdGgubWF4KHRbM10sblszXSksZX1mdW5jdGlvbiBXbChlLHQpe3JldHVybiBlWzBdPUF0KHRbMF0pLGVbMV09QXQodFsxXSksZVsyXT1BdCh0WzJdKSxlWzNdPUF0KHRbM10pLGV9ZnVuY3Rpb24gaXMoZSx0LG4pe3JldHVybiBlWzBdPXRbMF0qbixlWzFdPXRbMV0qbixlWzJdPXRbMl0qbixlWzNdPXRbM10qbixlfWZ1bmN0aW9uIFpsKGUsdCxuLHIpe3JldHVybiBlWzBdPXRbMF0rblswXSpyLGVbMV09dFsxXStuWzFdKnIsZVsyXT10WzJdK25bMl0qcixlWzNdPXRbM10rblszXSpyLGV9ZnVuY3Rpb24gc3MoZSx0KXtjb25zdCBuPXRbMF0tZVswXSxyPXRbMV0tZVsxXSxpPXRbMl0tZVsyXSxzPXRbM10tZVszXTtyZXR1cm4gTWF0aC5zcXJ0KG4qbityKnIraSppK3Mqcyl9ZnVuY3Rpb24gb3MoZSx0KXtjb25zdCBuPXRbMF0tZVswXSxyPXRbMV0tZVsxXSxpPXRbMl0tZVsyXSxzPXRbM10tZVszXTtyZXR1cm4gbipuK3IqcitpKmkrcypzfWZ1bmN0aW9uIGpuKGUpe2NvbnN0IHQ9ZVswXSxuPWVbMV0scj1lWzJdLGk9ZVszXTtyZXR1cm4gTWF0aC5zcXJ0KHQqdCtuKm4rcipyK2kqaSl9ZnVuY3Rpb24gUW4oZSl7Y29uc3QgdD1lWzBdLG49ZVsxXSxyPWVbMl0saT1lWzNdO3JldHVybiB0KnQrbipuK3IqcitpKml9ZnVuY3Rpb24gR2woZSx0KXtyZXR1cm4gZVswXT0tdFswXSxlWzFdPS10WzFdLGVbMl09LXRbMl0sZVszXT0tdFszXSxlfWZ1bmN0aW9uIFhsKGUsdCl7cmV0dXJuIGVbMF09MS90WzBdLGVbMV09MS90WzFdLGVbMl09MS90WzJdLGVbM109MS90WzNdLGV9ZnVuY3Rpb24gY3MoZSx0KXtjb25zdCBuPXRbMF0scj10WzFdLGk9dFsyXSxzPXRbM107bGV0IG89bipuK3IqcitpKmkrcypzO3JldHVybiBvPjAmJihvPTEvTWF0aC5zcXJ0KG8pKSxlWzBdPW4qbyxlWzFdPXIqbyxlWzJdPWkqbyxlWzNdPXMqbyxlfWZ1bmN0aW9uIGFzKGUsdCl7cmV0dXJuIGVbMF0qdFswXStlWzFdKnRbMV0rZVsyXSp0WzJdK2VbM10qdFszXX1mdW5jdGlvbiBqbChlLHQsbixyKXtjb25zdCBpPW5bMF0qclsxXS1uWzFdKnJbMF0scz1uWzBdKnJbMl0tblsyXSpyWzBdLG89blswXSpyWzNdLW5bM10qclswXSxjPW5bMV0qclsyXS1uWzJdKnJbMV0sbD1uWzFdKnJbM10tblszXSpyWzFdLGg9blsyXSpyWzNdLW5bM10qclsyXSxmPXRbMF0sdT10WzFdLGQ9dFsyXSxnPXRbM107cmV0dXJuIGVbMF09dSpoLWQqbCtnKmMsZVsxXT0tKGYqaCkrZCpvLWcqcyxlWzJdPWYqbC11Km8rZyppLGVbM109LShmKmMpK3Uqcy1kKmksZX1mdW5jdGlvbiBscyhlLHQsbixyKXtjb25zdCBpPXRbMF0scz10WzFdLG89dFsyXSxjPXRbM107cmV0dXJuIGVbMF09aStyKihuWzBdLWkpLGVbMV09cytyKihuWzFdLXMpLGVbMl09bytyKihuWzJdLW8pLGVbM109YytyKihuWzNdLWMpLGV9ZnVuY3Rpb24gUWwoZSx0KXt0PXQ9PT12b2lkIDA/MTp0O2xldCBuLHIsaSxzLG8sYztkbyBuPVZ0KCkqMi0xLHI9VnQoKSoyLTEsbz1uKm4rcipyO3doaWxlKG8+PTEpO2RvIGk9VnQoKSoyLTEscz1WdCgpKjItMSxjPWkqaStzKnM7d2hpbGUoYz49MSk7Y29uc3QgbD1NYXRoLnNxcnQoKDEtbykvYyk7cmV0dXJuIGVbMF09dCpuLGVbMV09dCpyLGVbMl09dCppKmwsZVszXT10KnMqbCxlfWZ1bmN0aW9uIGhzKGUsdCxuKXtjb25zdCByPXRbMF0saT10WzFdLHM9dFsyXSxvPXRbM107cmV0dXJuIGVbMF09blswXSpyK25bNF0qaStuWzhdKnMrblsxMl0qbyxlWzFdPW5bMV0qcituWzVdKmkrbls5XSpzK25bMTNdKm8sZVsyXT1uWzJdKnIrbls2XSppK25bMTBdKnMrblsxNF0qbyxlWzNdPW5bM10qcituWzddKmkrblsxMV0qcytuWzE1XSpvLGV9ZnVuY3Rpb24gZnMoZSx0LG4pe2NvbnN0IHI9dFswXSxpPXRbMV0scz10WzJdLG89blswXSxjPW5bMV0sbD1uWzJdLGg9blszXSxmPWgqcitjKnMtbCppLHU9aCppK2wqci1vKnMsZD1oKnMrbyppLWMqcixnPS1vKnItYyppLWwqcztyZXR1cm4gZVswXT1mKmgrZyotbyt1Ki1sLWQqLWMsZVsxXT11KmgrZyotYytkKi1vLWYqLWwsZVsyXT1kKmgrZyotbCtmKi1jLXUqLW8sZVszXT10WzNdLGV9ZnVuY3Rpb24gS2woZSl7cmV0dXJuIGVbMF09MCxlWzFdPTAsZVsyXT0wLGVbM109MCxlfWZ1bmN0aW9uIEpsKGUpe3JldHVybmB2ZWM0KCR7ZVswXX0sICR7ZVsxXX0sICR7ZVsyXX0sICR7ZVszXX0pYH1mdW5jdGlvbiBIbChlLHQpe3JldHVybiBlWzBdPT09dFswXSYmZVsxXT09PXRbMV0mJmVbMl09PT10WzJdJiZlWzNdPT09dFszXX1mdW5jdGlvbiB0aChlLHQpe2NvbnN0IG49ZVswXSxyPWVbMV0saT1lWzJdLHM9ZVszXSxvPXRbMF0sYz10WzFdLGw9dFsyXSxoPXRbM107cmV0dXJuIE1hdGguYWJzKG4tbyk8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhuKSxNYXRoLmFicyhvKSkmJk1hdGguYWJzKHItYyk8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhyKSxNYXRoLmFicyhjKSkmJk1hdGguYWJzKGktbCk8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhpKSxNYXRoLmFicyhsKSkmJk1hdGguYWJzKHMtaCk8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhzKSxNYXRoLmFicyhoKSl9Y29uc3QgZWg9ZXMsbmg9bnMscmg9cnMsaWg9c3Msc2g9b3Msb2g9am4sY2g9UW4sYWg9ZnVuY3Rpb24oKXtjb25zdCBlPUhpKCk7cmV0dXJuIGZ1bmN0aW9uKHQsbixyLGkscyxvKXtsZXQgYyxsO2ZvcihufHwobj00KSxyfHwocj0wKSxpP2w9TWF0aC5taW4oaSpuK3IsdC5sZW5ndGgpOmw9dC5sZW5ndGgsYz1yO2M8bDtjKz1uKWVbMF09dFtjXSxlWzFdPXRbYysxXSxlWzJdPXRbYysyXSxlWzNdPXRbYyszXSxzKGUsZSxvKSx0W2NdPWVbMF0sdFtjKzFdPWVbMV0sdFtjKzJdPWVbMl0sdFtjKzNdPWVbM107cmV0dXJuIHR9fSgpO3ZhciBsaD1PYmplY3QuZnJlZXplKHtfX3Byb3RvX186bnVsbCxhZGQ6dHMsY2VpbDpVbCxjbG9uZTokbCxjb3B5OkZsLGNyZWF0ZTpIaSxjcm9zczpqbCxkaXN0OmloLGRpc3RhbmNlOnNzLGRpdjpyaCxkaXZpZGU6cnMsZG90OmFzLGVxdWFsczp0aCxleGFjdEVxdWFsczpIbCxmbG9vcjpEbCxmb3JFYWNoOmFoLGZyb21WYWx1ZXM6a2wsaW52ZXJzZTpYbCxsZW46b2gsbGVuZ3RoOmpuLGxlcnA6bHMsbWF4OllsLG1pbjpCbCxtdWw6bmgsbXVsdGlwbHk6bnMsbmVnYXRlOkdsLG5vcm1hbGl6ZTpjcyxyYW5kb206UWwscm91bmQ6V2wsc2NhbGU6aXMsc2NhbGVBbmRBZGQ6Wmwsc2V0OnFsLHNxckRpc3Q6c2gsc3FyTGVuOmNoLHNxdWFyZWREaXN0YW5jZTpvcyxzcXVhcmVkTGVuZ3RoOlFuLHN0cjpKbCxzdWI6ZWgsc3VidHJhY3Q6ZXMsdHJhbnNmb3JtTWF0NDpocyx0cmFuc2Zvcm1RdWF0OmZzLHplcm86S2x9KSxLbjsoZnVuY3Rpb24oZSl7ZVtlLkNPTDBST1cwPTBdPSJDT0wwUk9XMCIsZVtlLkNPTDBST1cxPTFdPSJDT0wwUk9XMSIsZVtlLkNPTDBST1cyPTJdPSJDT0wwUk9XMiIsZVtlLkNPTDBST1czPTNdPSJDT0wwUk9XMyIsZVtlLkNPTDFST1cwPTRdPSJDT0wxUk9XMCIsZVtlLkNPTDFST1cxPTVdPSJDT0wxUk9XMSIsZVtlLkNPTDFST1cyPTZdPSJDT0wxUk9XMiIsZVtlLkNPTDFST1czPTddPSJDT0wxUk9XMyIsZVtlLkNPTDJST1cwPThdPSJDT0wyUk9XMCIsZVtlLkNPTDJST1cxPTldPSJDT0wyUk9XMSIsZVtlLkNPTDJST1cyPTEwXT0iQ09MMlJPVzIiLGVbZS5DT0wyUk9XMz0xMV09IkNPTDJST1czIixlW2UuQ09MM1JPVzA9MTJdPSJDT0wzUk9XMCIsZVtlLkNPTDNST1cxPTEzXT0iQ09MM1JPVzEiLGVbZS5DT0wzUk9XMj0xNF09IkNPTDNST1cyIixlW2UuQ09MM1JPVzM9MTVdPSJDT0wzUk9XMyJ9KShLbnx8KEtuPXt9KSk7Y29uc3QgaGg9NDUqTWF0aC5QSS8xODAsZmg9MSxKbj0uMSxIbj01MDAsdWg9T2JqZWN0LmZyZWV6ZShbMSwwLDAsMCwwLDEsMCwwLDAsMCwxLDAsMCwwLDAsMV0pO2NsYXNzIHR0IGV4dGVuZHMgVW57c3RhdGljIGdldCBJREVOVElUWSgpe3JldHVybiBnaCgpfXN0YXRpYyBnZXQgWkVSTygpe3JldHVybiBkaCgpfWdldCBFTEVNRU5UUygpe3JldHVybiAxNn1nZXQgUkFOSygpe3JldHVybiA0fWdldCBJTkRJQ0VTKCl7cmV0dXJuIEtufWNvbnN0cnVjdG9yKHQpe3N1cGVyKC0wLC0wLC0wLC0wLC0wLC0wLC0wLC0wLC0wLC0wLC0wLC0wLC0wLC0wLC0wLC0wKSxhcmd1bWVudHMubGVuZ3RoPT09MSYmQXJyYXkuaXNBcnJheSh0KT90aGlzLmNvcHkodCk6dGhpcy5pZGVudGl0eSgpfWNvcHkodCl7cmV0dXJuIHRoaXNbMF09dFswXSx0aGlzWzFdPXRbMV0sdGhpc1syXT10WzJdLHRoaXNbM109dFszXSx0aGlzWzRdPXRbNF0sdGhpc1s1XT10WzVdLHRoaXNbNl09dFs2XSx0aGlzWzddPXRbN10sdGhpc1s4XT10WzhdLHRoaXNbOV09dFs5XSx0aGlzWzEwXT10WzEwXSx0aGlzWzExXT10WzExXSx0aGlzWzEyXT10WzEyXSx0aGlzWzEzXT10WzEzXSx0aGlzWzE0XT10WzE0XSx0aGlzWzE1XT10WzE1XSx0aGlzLmNoZWNrKCl9c2V0KHQsbixyLGkscyxvLGMsbCxoLGYsdSxkLGcsbSxfLHApe3JldHVybiB0aGlzWzBdPXQsdGhpc1sxXT1uLHRoaXNbMl09cix0aGlzWzNdPWksdGhpc1s0XT1zLHRoaXNbNV09byx0aGlzWzZdPWMsdGhpc1s3XT1sLHRoaXNbOF09aCx0aGlzWzldPWYsdGhpc1sxMF09dSx0aGlzWzExXT1kLHRoaXNbMTJdPWcsdGhpc1sxM109bSx0aGlzWzE0XT1fLHRoaXNbMTVdPXAsdGhpcy5jaGVjaygpfXNldFJvd01ham9yKHQsbixyLGkscyxvLGMsbCxoLGYsdSxkLGcsbSxfLHApe3JldHVybiB0aGlzWzBdPXQsdGhpc1sxXT1zLHRoaXNbMl09aCx0aGlzWzNdPWcsdGhpc1s0XT1uLHRoaXNbNV09byx0aGlzWzZdPWYsdGhpc1s3XT1tLHRoaXNbOF09cix0aGlzWzldPWMsdGhpc1sxMF09dSx0aGlzWzExXT1fLHRoaXNbMTJdPWksdGhpc1sxM109bCx0aGlzWzE0XT1kLHRoaXNbMTVdPXAsdGhpcy5jaGVjaygpfXRvUm93TWFqb3IodCl7cmV0dXJuIHRbMF09dGhpc1swXSx0WzFdPXRoaXNbNF0sdFsyXT10aGlzWzhdLHRbM109dGhpc1sxMl0sdFs0XT10aGlzWzFdLHRbNV09dGhpc1s1XSx0WzZdPXRoaXNbOV0sdFs3XT10aGlzWzEzXSx0WzhdPXRoaXNbMl0sdFs5XT10aGlzWzZdLHRbMTBdPXRoaXNbMTBdLHRbMTFdPXRoaXNbMTRdLHRbMTJdPXRoaXNbM10sdFsxM109dGhpc1s3XSx0WzE0XT10aGlzWzExXSx0WzE1XT10aGlzWzE1XSx0fWlkZW50aXR5KCl7cmV0dXJuIHRoaXMuY29weSh1aCl9ZnJvbU9iamVjdCh0KXtyZXR1cm4gdGhpcy5jaGVjaygpfWZyb21RdWF0ZXJuaW9uKHQpe3JldHVybiBXaSh0aGlzLHQpLHRoaXMuY2hlY2soKX1mcnVzdHVtKHQpe2NvbnN0e2xlZnQ6bixyaWdodDpyLGJvdHRvbTppLHRvcDpzLG5lYXI6bz1KbixmYXI6Yz1Ibn09dDtyZXR1cm4gYz09PTEvMD9taCh0aGlzLG4scixpLHMsbyk6WmkodGhpcyxuLHIsaSxzLG8sYyksdGhpcy5jaGVjaygpfWxvb2tBdCh0KXtjb25zdHtleWU6bixjZW50ZXI6cj1bMCwwLDBdLHVwOmk9WzAsMSwwXX09dDtyZXR1cm4gS2kodGhpcyxuLHIsaSksdGhpcy5jaGVjaygpfW9ydGhvKHQpe2NvbnN0e2xlZnQ6bixyaWdodDpyLGJvdHRvbTppLHRvcDpzLG5lYXI6bz1KbixmYXI6Yz1Ibn09dDtyZXR1cm4gUWkodGhpcyxuLHIsaSxzLG8sYyksdGhpcy5jaGVjaygpfW9ydGhvZ3JhcGhpYyh0KXtjb25zdHtmb3Z5Om49aGgsYXNwZWN0OnI9ZmgsZm9jYWxEaXN0YW5jZTppPTEsbmVhcjpzPUpuLGZhcjpvPUhufT10O3VzKG4pO2NvbnN0IGM9bi8yLGw9aSpNYXRoLnRhbihjKSxoPWwqcjtyZXR1cm4gdGhpcy5vcnRobyh7bGVmdDotaCxyaWdodDpoLGJvdHRvbTotbCx0b3A6bCxuZWFyOnMsZmFyOm99KX1wZXJzcGVjdGl2ZSh0KXtjb25zdHtmb3Z5Om49NDUqTWF0aC5QSS8xODAsYXNwZWN0OnI9MSxuZWFyOmk9LjEsZmFyOnM9NTAwfT10O3JldHVybiB1cyhuKSxYaSh0aGlzLG4scixpLHMpLHRoaXMuY2hlY2soKX1kZXRlcm1pbmFudCgpe3JldHVybiBYbih0aGlzKX1nZXRTY2FsZSh0PVstMCwtMCwtMF0pe3JldHVybiB0WzBdPU1hdGguc3FydCh0aGlzWzBdKnRoaXNbMF0rdGhpc1sxXSp0aGlzWzFdK3RoaXNbMl0qdGhpc1syXSksdFsxXT1NYXRoLnNxcnQodGhpc1s0XSp0aGlzWzRdK3RoaXNbNV0qdGhpc1s1XSt0aGlzWzZdKnRoaXNbNl0pLHRbMl09TWF0aC5zcXJ0KHRoaXNbOF0qdGhpc1s4XSt0aGlzWzldKnRoaXNbOV0rdGhpc1sxMF0qdGhpc1sxMF0pLHR9Z2V0VHJhbnNsYXRpb24odD1bLTAsLTAsLTBdKXtyZXR1cm4gdFswXT10aGlzWzEyXSx0WzFdPXRoaXNbMTNdLHRbMl09dGhpc1sxNF0sdH1nZXRSb3RhdGlvbih0LG4pe3Q9dHx8Wy0wLC0wLC0wLC0wLC0wLC0wLC0wLC0wLC0wLC0wLC0wLC0wLC0wLC0wLC0wLC0wXSxuPW58fFstMCwtMCwtMF07Y29uc3Qgcj10aGlzLmdldFNjYWxlKG4pLGk9MS9yWzBdLHM9MS9yWzFdLG89MS9yWzJdO3JldHVybiB0WzBdPXRoaXNbMF0qaSx0WzFdPXRoaXNbMV0qcyx0WzJdPXRoaXNbMl0qbyx0WzNdPTAsdFs0XT10aGlzWzRdKmksdFs1XT10aGlzWzVdKnMsdFs2XT10aGlzWzZdKm8sdFs3XT0wLHRbOF09dGhpc1s4XSppLHRbOV09dGhpc1s5XSpzLHRbMTBdPXRoaXNbMTBdKm8sdFsxMV09MCx0WzEyXT0wLHRbMTNdPTAsdFsxNF09MCx0WzE1XT0xLHR9Z2V0Um90YXRpb25NYXRyaXgzKHQsbil7dD10fHxbLTAsLTAsLTAsLTAsLTAsLTAsLTAsLTAsLTBdLG49bnx8Wy0wLC0wLC0wXTtjb25zdCByPXRoaXMuZ2V0U2NhbGUobiksaT0xL3JbMF0scz0xL3JbMV0sbz0xL3JbMl07cmV0dXJuIHRbMF09dGhpc1swXSppLHRbMV09dGhpc1sxXSpzLHRbMl09dGhpc1syXSpvLHRbM109dGhpc1s0XSppLHRbNF09dGhpc1s1XSpzLHRbNV09dGhpc1s2XSpvLHRbNl09dGhpc1s4XSppLHRbN109dGhpc1s5XSpzLHRbOF09dGhpc1sxMF0qbyx0fXRyYW5zcG9zZSgpe3JldHVybiBDaSh0aGlzLHRoaXMpLHRoaXMuY2hlY2soKX1pbnZlcnQoKXtyZXR1cm4gR24odGhpcyx0aGlzKSx0aGlzLmNoZWNrKCl9bXVsdGlwbHlMZWZ0KHQpe3JldHVybiBRZSh0aGlzLHQsdGhpcyksdGhpcy5jaGVjaygpfW11bHRpcGx5UmlnaHQodCl7cmV0dXJuIFFlKHRoaXMsdGhpcyx0KSx0aGlzLmNoZWNrKCl9cm90YXRlWCh0KXtyZXR1cm4gJGkodGhpcyx0aGlzLHQpLHRoaXMuY2hlY2soKX1yb3RhdGVZKHQpe3JldHVybiBraSh0aGlzLHRoaXMsdCksdGhpcy5jaGVjaygpfXJvdGF0ZVoodCl7cmV0dXJuIEZpKHRoaXMsdGhpcyx0KSx0aGlzLmNoZWNrKCl9cm90YXRlWFlaKHQpe3JldHVybiB0aGlzLnJvdGF0ZVgodFswXSkucm90YXRlWSh0WzFdKS5yb3RhdGVaKHRbMl0pfXJvdGF0ZUF4aXModCxuKXtyZXR1cm4gemkodGhpcyx0aGlzLHQsbiksdGhpcy5jaGVjaygpfXNjYWxlKHQpe3JldHVybiBOaSh0aGlzLHRoaXMsQXJyYXkuaXNBcnJheSh0KT90Olt0LHQsdF0pLHRoaXMuY2hlY2soKX10cmFuc2xhdGUodCl7cmV0dXJuIFZpKHRoaXMsdGhpcyx0KSx0aGlzLmNoZWNrKCl9dHJhbnNmb3JtKHQsbil7cmV0dXJuIHQubGVuZ3RoPT09ND8obj1ocyhufHxbLTAsLTAsLTAsLTBdLHQsdGhpcyksbGUobiw0KSxuKTp0aGlzLnRyYW5zZm9ybUFzUG9pbnQodCxuKX10cmFuc2Zvcm1Bc1BvaW50KHQsbil7Y29uc3R7bGVuZ3RoOnJ9PXQ7bGV0IGk7c3dpdGNoKHIpe2Nhc2UgMjppPVBuKG58fFstMCwtMF0sdCx0aGlzKTticmVhaztjYXNlIDM6aT1ZZShufHxbLTAsLTAsLTBdLHQsdGhpcyk7YnJlYWs7ZGVmYXVsdDp0aHJvdyBuZXcgRXJyb3IoIklsbGVnYWwgdmVjdG9yIil9cmV0dXJuIGxlKGksdC5sZW5ndGgpLGl9dHJhbnNmb3JtQXNWZWN0b3IodCxuKXtsZXQgcjtzd2l0Y2godC5sZW5ndGgpe2Nhc2UgMjpyPUxuKG58fFstMCwtMF0sdCx0aGlzKTticmVhaztjYXNlIDM6cj1SbihufHxbLTAsLTAsLTBdLHQsdGhpcyk7YnJlYWs7ZGVmYXVsdDp0aHJvdyBuZXcgRXJyb3IoIklsbGVnYWwgdmVjdG9yIil9cmV0dXJuIGxlKHIsdC5sZW5ndGgpLHJ9dHJhbnNmb3JtUG9pbnQodCxuKXtyZXR1cm4gdGhpcy50cmFuc2Zvcm1Bc1BvaW50KHQsbil9dHJhbnNmb3JtVmVjdG9yKHQsbil7cmV0dXJuIHRoaXMudHJhbnNmb3JtQXNQb2ludCh0LG4pfXRyYW5zZm9ybURpcmVjdGlvbih0LG4pe3JldHVybiB0aGlzLnRyYW5zZm9ybUFzVmVjdG9yKHQsbil9bWFrZVJvdGF0aW9uWCh0KXtyZXR1cm4gdGhpcy5pZGVudGl0eSgpLnJvdGF0ZVgodCl9bWFrZVRyYW5zbGF0aW9uKHQsbixyKXtyZXR1cm4gdGhpcy5pZGVudGl0eSgpLnRyYW5zbGF0ZShbdCxuLHJdKX19bGV0IEtlLEplO2Z1bmN0aW9uIGRoKCl7cmV0dXJuIEtlfHwoS2U9bmV3IHR0KFswLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwXSksT2JqZWN0LmZyZWV6ZShLZSkpLEtlfWZ1bmN0aW9uIGdoKCl7cmV0dXJuIEplfHwoSmU9bmV3IHR0LE9iamVjdC5mcmVlemUoSmUpKSxKZX1mdW5jdGlvbiB1cyhlKXtpZihlPk1hdGguUEkqMil0aHJvdyBFcnJvcigiZXhwZWN0ZWQgcmFkaWFucyIpfWZ1bmN0aW9uIG1oKGUsdCxuLHIsaSxzKXtjb25zdCBvPTIqcy8obi10KSxjPTIqcy8oaS1yKSxsPShuK3QpLyhuLXQpLGg9KGkrcikvKGktciksZj0tMSx1PS0xLGQ9LTIqcztyZXR1cm4gZVswXT1vLGVbMV09MCxlWzJdPTAsZVszXT0wLGVbNF09MCxlWzVdPWMsZVs2XT0wLGVbN109MCxlWzhdPWwsZVs5XT1oLGVbMTBdPWYsZVsxMV09dSxlWzEyXT0wLGVbMTNdPTAsZVsxNF09ZCxlWzE1XT0wLGV9ZnVuY3Rpb24gZHMoKXtjb25zdCBlPW5ldyBCKDQpO3JldHVybiBCIT1GbG9hdDMyQXJyYXkmJihlWzBdPTAsZVsxXT0wLGVbMl09MCksZVszXT0xLGV9ZnVuY3Rpb24gcGgoZSl7cmV0dXJuIGVbMF09MCxlWzFdPTAsZVsyXT0wLGVbM109MSxlfWZ1bmN0aW9uIGdzKGUsdCxuKXtuPW4qLjU7Y29uc3Qgcj1NYXRoLnNpbihuKTtyZXR1cm4gZVswXT1yKnRbMF0sZVsxXT1yKnRbMV0sZVsyXT1yKnRbMl0sZVszXT1NYXRoLmNvcyhuKSxlfWZ1bmN0aW9uIG1zKGUsdCxuKXtjb25zdCByPXRbMF0saT10WzFdLHM9dFsyXSxvPXRbM10sYz1uWzBdLGw9blsxXSxoPW5bMl0sZj1uWzNdO3JldHVybiBlWzBdPXIqZitvKmMraSpoLXMqbCxlWzFdPWkqZitvKmwrcypjLXIqaCxlWzJdPXMqZitvKmgrcipsLWkqYyxlWzNdPW8qZi1yKmMtaSpsLXMqaCxlfWZ1bmN0aW9uIF9oKGUsdCxuKXtuKj0uNTtjb25zdCByPXRbMF0saT10WzFdLHM9dFsyXSxvPXRbM10sYz1NYXRoLnNpbihuKSxsPU1hdGguY29zKG4pO3JldHVybiBlWzBdPXIqbCtvKmMsZVsxXT1pKmwrcypjLGVbMl09cypsLWkqYyxlWzNdPW8qbC1yKmMsZX1mdW5jdGlvbiB5aChlLHQsbil7bio9LjU7Y29uc3Qgcj10WzBdLGk9dFsxXSxzPXRbMl0sbz10WzNdLGM9TWF0aC5zaW4obiksbD1NYXRoLmNvcyhuKTtyZXR1cm4gZVswXT1yKmwtcypjLGVbMV09aSpsK28qYyxlWzJdPXMqbCtyKmMsZVszXT1vKmwtaSpjLGV9ZnVuY3Rpb24geGgoZSx0LG4pe24qPS41O2NvbnN0IHI9dFswXSxpPXRbMV0scz10WzJdLG89dFszXSxjPU1hdGguc2luKG4pLGw9TWF0aC5jb3Mobik7cmV0dXJuIGVbMF09cipsK2kqYyxlWzFdPWkqbC1yKmMsZVsyXT1zKmwrbypjLGVbM109bypsLXMqYyxlfWZ1bmN0aW9uIE1oKGUsdCl7Y29uc3Qgbj10WzBdLHI9dFsxXSxpPXRbMl07cmV0dXJuIGVbMF09bixlWzFdPXIsZVsyXT1pLGVbM109TWF0aC5zcXJ0KE1hdGguYWJzKDEtbipuLXIqci1pKmkpKSxlfWZ1bmN0aW9uIEhlKGUsdCxuLHIpe2NvbnN0IGk9dFswXSxzPXRbMV0sbz10WzJdLGM9dFszXTtsZXQgbD1uWzBdLGg9blsxXSxmPW5bMl0sdT1uWzNdLGQsZyxtLF8scDtyZXR1cm4gZD1pKmwrcypoK28qZitjKnUsZDwwJiYoZD0tZCxsPS1sLGg9LWgsZj0tZix1PS11KSwxLWQ+Qz8oZz1NYXRoLmFjb3MoZCkscD1NYXRoLnNpbihnKSxtPU1hdGguc2luKCgxLXIpKmcpL3AsXz1NYXRoLnNpbihyKmcpL3ApOihtPTEtcixfPXIpLGVbMF09bSppK18qbCxlWzFdPW0qcytfKmgsZVsyXT1tKm8rXypmLGVbM109bSpjK18qdSxlfWZ1bmN0aW9uIHdoKGUsdCl7Y29uc3Qgbj10WzBdLHI9dFsxXSxpPXRbMl0scz10WzNdLG89bipuK3IqcitpKmkrcypzLGM9bz8xL286MDtyZXR1cm4gZVswXT0tbipjLGVbMV09LXIqYyxlWzJdPS1pKmMsZVszXT1zKmMsZX1mdW5jdGlvbiBBaChlLHQpe3JldHVybiBlWzBdPS10WzBdLGVbMV09LXRbMV0sZVsyXT0tdFsyXSxlWzNdPXRbM10sZX1mdW5jdGlvbiB0cihlLHQpe2NvbnN0IG49dFswXSt0WzRdK3RbOF07bGV0IHI7aWYobj4wKXI9TWF0aC5zcXJ0KG4rMSksZVszXT0uNSpyLHI9LjUvcixlWzBdPSh0WzVdLXRbN10pKnIsZVsxXT0odFs2XS10WzJdKSpyLGVbMl09KHRbMV0tdFszXSkqcjtlbHNle2xldCBpPTA7dFs0XT50WzBdJiYoaT0xKSx0WzhdPnRbaSozK2ldJiYoaT0yKTtjb25zdCBzPShpKzEpJTMsbz0oaSsyKSUzO3I9TWF0aC5zcXJ0KHRbaSozK2ldLXRbcyozK3NdLXRbbyozK29dKzEpLGVbaV09LjUqcixyPS41L3IsZVszXT0odFtzKjMrb10tdFtvKjMrc10pKnIsZVtzXT0odFtzKjMraV0rdFtpKjMrc10pKnIsZVtvXT0odFtvKjMraV0rdFtpKjMrb10pKnJ9cmV0dXJuIGV9Y29uc3QgVGg9dHMsdmg9aXMsRWg9YXMsT2g9bHMsYmg9am4sSWg9UW4scHM9Y3MsU2g9ZnVuY3Rpb24oKXtjb25zdCBlPVZuKCksdD1ObigxLDAsMCksbj1ObigwLDEsMCk7cmV0dXJuIGZ1bmN0aW9uKHIsaSxzKXtjb25zdCBvPWhlKGkscyk7cmV0dXJuIG88LS45OTk5OTk/KHJ0KGUsdCxpKSxPaShlKTwxZS02JiZydChlLG4saSksSXQoZSxlKSxncyhyLGUsTWF0aC5QSSkscik6bz4uOTk5OTk5PyhyWzBdPTAsclsxXT0wLHJbMl09MCxyWzNdPTEscik6KHJ0KGUsaSxzKSxyWzBdPWVbMF0sclsxXT1lWzFdLHJbMl09ZVsyXSxyWzNdPTErbyxwcyhyLHIpKX19KCk7KGZ1bmN0aW9uKCl7Y29uc3QgZT1kcygpLHQ9ZHMoKTtyZXR1cm4gZnVuY3Rpb24obixyLGkscyxvLGMpe3JldHVybiBIZShlLHIsbyxjKSxIZSh0LGkscyxjKSxIZShuLGUsdCwyKmMqKDEtYykpLG59fSkoKSxmdW5jdGlvbigpe2NvbnN0IGU9YmkoKTtyZXR1cm4gZnVuY3Rpb24odCxuLHIsaSl7cmV0dXJuIGVbMF09clswXSxlWzNdPXJbMV0sZVs2XT1yWzJdLGVbMV09aVswXSxlWzRdPWlbMV0sZVs3XT1pWzJdLGVbMl09LW5bMF0sZVs1XT0tblsxXSxlWzhdPS1uWzJdLHBzKHQsdHIodCxlKSl9fSgpO2NvbnN0IFBoPVswLDAsMCwxXTtjbGFzcyBpdCBleHRlbmRzIGFle2NvbnN0cnVjdG9yKHQ9MCxuPTAscj0wLGk9MSl7c3VwZXIoLTAsLTAsLTAsLTApLEFycmF5LmlzQXJyYXkodCkmJmFyZ3VtZW50cy5sZW5ndGg9PT0xP3RoaXMuY29weSh0KTp0aGlzLnNldCh0LG4scixpKX1jb3B5KHQpe3JldHVybiB0aGlzWzBdPXRbMF0sdGhpc1sxXT10WzFdLHRoaXNbMl09dFsyXSx0aGlzWzNdPXRbM10sdGhpcy5jaGVjaygpfXNldCh0LG4scixpKXtyZXR1cm4gdGhpc1swXT10LHRoaXNbMV09bix0aGlzWzJdPXIsdGhpc1szXT1pLHRoaXMuY2hlY2soKX1mcm9tT2JqZWN0KHQpe3JldHVybiB0aGlzWzBdPXQueCx0aGlzWzFdPXQueSx0aGlzWzJdPXQueix0aGlzWzNdPXQudyx0aGlzLmNoZWNrKCl9ZnJvbU1hdHJpeDModCl7cmV0dXJuIHRyKHRoaXMsdCksdGhpcy5jaGVjaygpfWZyb21BeGlzUm90YXRpb24odCxuKXtyZXR1cm4gZ3ModGhpcyx0LG4pLHRoaXMuY2hlY2soKX1pZGVudGl0eSgpe3JldHVybiBwaCh0aGlzKSx0aGlzLmNoZWNrKCl9c2V0QXhpc0FuZ2xlKHQsbil7cmV0dXJuIHRoaXMuZnJvbUF4aXNSb3RhdGlvbih0LG4pfWdldCBFTEVNRU5UUygpe3JldHVybiA0fWdldCB4KCl7cmV0dXJuIHRoaXNbMF19c2V0IHgodCl7dGhpc1swXT1SKHQpfWdldCB5KCl7cmV0dXJuIHRoaXNbMV19c2V0IHkodCl7dGhpc1sxXT1SKHQpfWdldCB6KCl7cmV0dXJuIHRoaXNbMl19c2V0IHoodCl7dGhpc1syXT1SKHQpfWdldCB3KCl7cmV0dXJuIHRoaXNbM119c2V0IHcodCl7dGhpc1szXT1SKHQpfWxlbigpe3JldHVybiBiaCh0aGlzKX1sZW5ndGhTcXVhcmVkKCl7cmV0dXJuIEloKHRoaXMpfWRvdCh0KXtyZXR1cm4gRWgodGhpcyx0KX1yb3RhdGlvblRvKHQsbil7cmV0dXJuIFNoKHRoaXMsdCxuKSx0aGlzLmNoZWNrKCl9YWRkKHQpe3JldHVybiBUaCh0aGlzLHRoaXMsdCksdGhpcy5jaGVjaygpfWNhbGN1bGF0ZVcoKXtyZXR1cm4gTWgodGhpcyx0aGlzKSx0aGlzLmNoZWNrKCl9Y29uanVnYXRlKCl7cmV0dXJuIEFoKHRoaXMsdGhpcyksdGhpcy5jaGVjaygpfWludmVydCgpe3JldHVybiB3aCh0aGlzLHRoaXMpLHRoaXMuY2hlY2soKX1sZXJwKHQsbixyKXtyZXR1cm4gcj09PXZvaWQgMD90aGlzLmxlcnAodGhpcyx0LG4pOihPaCh0aGlzLHQsbixyKSx0aGlzLmNoZWNrKCkpfW11bHRpcGx5UmlnaHQodCl7cmV0dXJuIG1zKHRoaXMsdGhpcyx0KSx0aGlzLmNoZWNrKCl9bXVsdGlwbHlMZWZ0KHQpe3JldHVybiBtcyh0aGlzLHQsdGhpcyksdGhpcy5jaGVjaygpfW5vcm1hbGl6ZSgpe2NvbnN0IHQ9dGhpcy5sZW4oKSxuPXQ+MD8xL3Q6MDtyZXR1cm4gdGhpc1swXT10aGlzWzBdKm4sdGhpc1sxXT10aGlzWzFdKm4sdGhpc1syXT10aGlzWzJdKm4sdGhpc1szXT10aGlzWzNdKm4sdD09PTAmJih0aGlzWzNdPTEpLHRoaXMuY2hlY2soKX1yb3RhdGVYKHQpe3JldHVybiBfaCh0aGlzLHRoaXMsdCksdGhpcy5jaGVjaygpfXJvdGF0ZVkodCl7cmV0dXJuIHloKHRoaXMsdGhpcyx0KSx0aGlzLmNoZWNrKCl9cm90YXRlWih0KXtyZXR1cm4geGgodGhpcyx0aGlzLHQpLHRoaXMuY2hlY2soKX1zY2FsZSh0KXtyZXR1cm4gdmgodGhpcyx0aGlzLHQpLHRoaXMuY2hlY2soKX1zbGVycCh0LG4scil7bGV0IGkscyxvO3N3aXRjaChhcmd1bWVudHMubGVuZ3RoKXtjYXNlIDE6KHtzdGFydDppPVBoLHRhcmdldDpzLHJhdGlvOm99PXQpO2JyZWFrO2Nhc2UgMjppPXRoaXMscz10LG89bjticmVhaztkZWZhdWx0Omk9dCxzPW4sbz1yfXJldHVybiBIZSh0aGlzLGkscyxvKSx0aGlzLmNoZWNrKCl9dHJhbnNmb3JtVmVjdG9yNCh0LG49bmV3IHV0KXtyZXR1cm4gZnMobix0LHRoaXMpLGxlKG4sNCl9bGVuZ3RoU3EoKXtyZXR1cm4gdGhpcy5sZW5ndGhTcXVhcmVkKCl9c2V0RnJvbUF4aXNBbmdsZSh0LG4pe3JldHVybiB0aGlzLnNldEF4aXNBbmdsZSh0LG4pfXByZW11bHRpcGx5KHQpe3JldHVybiB0aGlzLm11bHRpcGx5TGVmdCh0KX1tdWx0aXBseSh0KXtyZXR1cm4gdGhpcy5tdWx0aXBseVJpZ2h0KHQpfX1jb25zdCB0bj0iVW5rbm93biBFdWxlciBhbmdsZSBvcmRlciIsWXQ9Ljk5OTk5O3ZhciBYOyhmdW5jdGlvbihlKXtlW2UuWllYPTBdPSJaWVgiLGVbZS5ZWFo9MV09IllYWiIsZVtlLlhaWT0yXT0iWFpZIixlW2UuWlhZPTNdPSJaWFkiLGVbZS5ZWlg9NF09IllaWCIsZVtlLlhZWj01XT0iWFlaIn0pKFh8fChYPXt9KSk7Y2xhc3MgRiBleHRlbmRzIGFle3N0YXRpYyBnZXQgWllYKCl7cmV0dXJuIFguWllYfXN0YXRpYyBnZXQgWVhaKCl7cmV0dXJuIFguWVhafXN0YXRpYyBnZXQgWFpZKCl7cmV0dXJuIFguWFpZfXN0YXRpYyBnZXQgWlhZKCl7cmV0dXJuIFguWlhZfXN0YXRpYyBnZXQgWVpYKCl7cmV0dXJuIFguWVpYfXN0YXRpYyBnZXQgWFlaKCl7cmV0dXJuIFguWFlafXN0YXRpYyBnZXQgUm9sbFBpdGNoWWF3KCl7cmV0dXJuIFguWllYfXN0YXRpYyBnZXQgRGVmYXVsdE9yZGVyKCl7cmV0dXJuIFguWllYfXN0YXRpYyBnZXQgUm90YXRpb25PcmRlcnMoKXtyZXR1cm4gWH1zdGF0aWMgcm90YXRpb25PcmRlcih0KXtyZXR1cm4gWFt0XX1nZXQgRUxFTUVOVFMoKXtyZXR1cm4gNH1jb25zdHJ1Y3Rvcih0PTAsbj0wLHI9MCxpPUYuRGVmYXVsdE9yZGVyKXtzdXBlcigtMCwtMCwtMCwtMCksYXJndW1lbnRzLmxlbmd0aD4wJiZBcnJheS5pc0FycmF5KGFyZ3VtZW50c1swXSk/dGhpcy5mcm9tVmVjdG9yMyguLi5hcmd1bWVudHMpOnRoaXMuc2V0KHQsbixyLGkpfWZyb21RdWF0ZXJuaW9uKHQpe2NvbnN0W24scixpLHNdPXQsbz1yKnIsYz0tMioobytpKmkpKzEsbD0yKihuKnIrcyppKTtsZXQgaD0tMioobippLXMqcik7Y29uc3QgZj0yKihyKmkrcypuKSx1PS0yKihuKm4rbykrMTtoPWg+MT8xOmgsaD1oPC0xPy0xOmg7Y29uc3QgZD1NYXRoLmF0YW4yKGYsdSksZz1NYXRoLmFzaW4oaCksbT1NYXRoLmF0YW4yKGwsYyk7cmV0dXJuIHRoaXMuc2V0KGQsZyxtLEYuUm9sbFBpdGNoWWF3KX1mcm9tT2JqZWN0KHQpe3Rocm93IG5ldyBFcnJvcigibm90IGltcGxlbWVudGVkIil9Y29weSh0KXtyZXR1cm4gdGhpc1swXT10WzBdLHRoaXNbMV09dFsxXSx0aGlzWzJdPXRbMl0sdGhpc1szXT1OdW1iZXIuaXNGaW5pdGUodFszXSl8fHRoaXMub3JkZXIsdGhpcy5jaGVjaygpfXNldCh0PTAsbj0wLHI9MCxpKXtyZXR1cm4gdGhpc1swXT10LHRoaXNbMV09bix0aGlzWzJdPXIsdGhpc1szXT1OdW1iZXIuaXNGaW5pdGUoaSk/aTp0aGlzWzNdLHRoaXMuY2hlY2soKX12YWxpZGF0ZSgpe3JldHVybiBMaCh0aGlzWzNdKSYmTnVtYmVyLmlzRmluaXRlKHRoaXNbMF0pJiZOdW1iZXIuaXNGaW5pdGUodGhpc1sxXSkmJk51bWJlci5pc0Zpbml0ZSh0aGlzWzJdKX10b0FycmF5KHQ9W10sbj0wKXtyZXR1cm4gdFtuXT10aGlzWzBdLHRbbisxXT10aGlzWzFdLHRbbisyXT10aGlzWzJdLHR9dG9BcnJheTQodD1bXSxuPTApe3JldHVybiB0W25dPXRoaXNbMF0sdFtuKzFdPXRoaXNbMV0sdFtuKzJdPXRoaXNbMl0sdFtuKzNdPXRoaXNbM10sdH10b1ZlY3RvcjModD1bLTAsLTAsLTBdKXtyZXR1cm4gdFswXT10aGlzWzBdLHRbMV09dGhpc1sxXSx0WzJdPXRoaXNbMl0sdH1nZXQgeCgpe3JldHVybiB0aGlzWzBdfXNldCB4KHQpe3RoaXNbMF09Uih0KX1nZXQgeSgpe3JldHVybiB0aGlzWzFdfXNldCB5KHQpe3RoaXNbMV09Uih0KX1nZXQgeigpe3JldHVybiB0aGlzWzJdfXNldCB6KHQpe3RoaXNbMl09Uih0KX1nZXQgYWxwaGEoKXtyZXR1cm4gdGhpc1swXX1zZXQgYWxwaGEodCl7dGhpc1swXT1SKHQpfWdldCBiZXRhKCl7cmV0dXJuIHRoaXNbMV19c2V0IGJldGEodCl7dGhpc1sxXT1SKHQpfWdldCBnYW1tYSgpe3JldHVybiB0aGlzWzJdfXNldCBnYW1tYSh0KXt0aGlzWzJdPVIodCl9Z2V0IHBoaSgpe3JldHVybiB0aGlzWzBdfXNldCBwaGkodCl7dGhpc1swXT1SKHQpfWdldCB0aGV0YSgpe3JldHVybiB0aGlzWzFdfXNldCB0aGV0YSh0KXt0aGlzWzFdPVIodCl9Z2V0IHBzaSgpe3JldHVybiB0aGlzWzJdfXNldCBwc2kodCl7dGhpc1syXT1SKHQpfWdldCByb2xsKCl7cmV0dXJuIHRoaXNbMF19c2V0IHJvbGwodCl7dGhpc1swXT1SKHQpfWdldCBwaXRjaCgpe3JldHVybiB0aGlzWzFdfXNldCBwaXRjaCh0KXt0aGlzWzFdPVIodCl9Z2V0IHlhdygpe3JldHVybiB0aGlzWzJdfXNldCB5YXcodCl7dGhpc1syXT1SKHQpfWdldCBvcmRlcigpe3JldHVybiB0aGlzWzNdfXNldCBvcmRlcih0KXt0aGlzWzNdPVJoKHQpfWZyb21WZWN0b3IzKHQsbil7cmV0dXJuIHRoaXMuc2V0KHRbMF0sdFsxXSx0WzJdLE51bWJlci5pc0Zpbml0ZShuKT9uOnRoaXNbM10pfWZyb21BcnJheSh0LG49MCl7cmV0dXJuIHRoaXNbMF09dFswK25dLHRoaXNbMV09dFsxK25dLHRoaXNbMl09dFsyK25dLHRbM10hPT12b2lkIDAmJih0aGlzWzNdPXRbM10pLHRoaXMuY2hlY2soKX1mcm9tUm9sbFBpdGNoWWF3KHQsbixyKXtyZXR1cm4gdGhpcy5zZXQodCxuLHIsWC5aWVgpfWZyb21Sb3RhdGlvbk1hdHJpeCh0LG49Ri5EZWZhdWx0T3JkZXIpe3JldHVybiB0aGlzLl9mcm9tUm90YXRpb25NYXRyaXgodCxuKSx0aGlzLmNoZWNrKCl9Z2V0Um90YXRpb25NYXRyaXgodCl7cmV0dXJuIHRoaXMuX2dldFJvdGF0aW9uTWF0cml4KHQpfWdldFF1YXRlcm5pb24oKXtjb25zdCB0PW5ldyBpdDtzd2l0Y2godGhpc1szXSl7Y2FzZSBYLlhZWjpyZXR1cm4gdC5yb3RhdGVYKHRoaXNbMF0pLnJvdGF0ZVkodGhpc1sxXSkucm90YXRlWih0aGlzWzJdKTtjYXNlIFguWVhaOnJldHVybiB0LnJvdGF0ZVkodGhpc1swXSkucm90YXRlWCh0aGlzWzFdKS5yb3RhdGVaKHRoaXNbMl0pO2Nhc2UgWC5aWFk6cmV0dXJuIHQucm90YXRlWih0aGlzWzBdKS5yb3RhdGVYKHRoaXNbMV0pLnJvdGF0ZVkodGhpc1syXSk7Y2FzZSBYLlpZWDpyZXR1cm4gdC5yb3RhdGVaKHRoaXNbMF0pLnJvdGF0ZVkodGhpc1sxXSkucm90YXRlWCh0aGlzWzJdKTtjYXNlIFguWVpYOnJldHVybiB0LnJvdGF0ZVkodGhpc1swXSkucm90YXRlWih0aGlzWzFdKS5yb3RhdGVYKHRoaXNbMl0pO2Nhc2UgWC5YWlk6cmV0dXJuIHQucm90YXRlWCh0aGlzWzBdKS5yb3RhdGVaKHRoaXNbMV0pLnJvdGF0ZVkodGhpc1syXSk7ZGVmYXVsdDp0aHJvdyBuZXcgRXJyb3IodG4pfX1fZnJvbVJvdGF0aW9uTWF0cml4KHQsbj1GLkRlZmF1bHRPcmRlcil7Y29uc3Qgcj10WzBdLGk9dFs0XSxzPXRbOF0sbz10WzFdLGM9dFs1XSxsPXRbOV0saD10WzJdLGY9dFs2XSx1PXRbMTBdO3N3aXRjaChuPW58fHRoaXNbM10sbil7Y2FzZSBGLlhZWjp0aGlzWzFdPU1hdGguYXNpbihDdChzLC0xLDEpKSxNYXRoLmFicyhzKTxZdD8odGhpc1swXT1NYXRoLmF0YW4yKC1sLHUpLHRoaXNbMl09TWF0aC5hdGFuMigtaSxyKSk6KHRoaXNbMF09TWF0aC5hdGFuMihmLGMpLHRoaXNbMl09MCk7YnJlYWs7Y2FzZSBGLllYWjp0aGlzWzBdPU1hdGguYXNpbigtQ3QobCwtMSwxKSksTWF0aC5hYnMobCk8WXQ/KHRoaXNbMV09TWF0aC5hdGFuMihzLHUpLHRoaXNbMl09TWF0aC5hdGFuMihvLGMpKToodGhpc1sxXT1NYXRoLmF0YW4yKC1oLHIpLHRoaXNbMl09MCk7YnJlYWs7Y2FzZSBGLlpYWTp0aGlzWzBdPU1hdGguYXNpbihDdChmLC0xLDEpKSxNYXRoLmFicyhmKTxZdD8odGhpc1sxXT1NYXRoLmF0YW4yKC1oLHUpLHRoaXNbMl09TWF0aC5hdGFuMigtaSxjKSk6KHRoaXNbMV09MCx0aGlzWzJdPU1hdGguYXRhbjIobyxyKSk7YnJlYWs7Y2FzZSBGLlpZWDp0aGlzWzFdPU1hdGguYXNpbigtQ3QoaCwtMSwxKSksTWF0aC5hYnMoaCk8WXQ/KHRoaXNbMF09TWF0aC5hdGFuMihmLHUpLHRoaXNbMl09TWF0aC5hdGFuMihvLHIpKToodGhpc1swXT0wLHRoaXNbMl09TWF0aC5hdGFuMigtaSxjKSk7YnJlYWs7Y2FzZSBGLllaWDp0aGlzWzJdPU1hdGguYXNpbihDdChvLC0xLDEpKSxNYXRoLmFicyhvKTxZdD8odGhpc1swXT1NYXRoLmF0YW4yKC1sLGMpLHRoaXNbMV09TWF0aC5hdGFuMigtaCxyKSk6KHRoaXNbMF09MCx0aGlzWzFdPU1hdGguYXRhbjIocyx1KSk7YnJlYWs7Y2FzZSBGLlhaWTp0aGlzWzJdPU1hdGguYXNpbigtQ3QoaSwtMSwxKSksTWF0aC5hYnMoaSk8WXQ/KHRoaXNbMF09TWF0aC5hdGFuMihmLGMpLHRoaXNbMV09TWF0aC5hdGFuMihzLHIpKToodGhpc1swXT1NYXRoLmF0YW4yKC1sLHUpLHRoaXNbMV09MCk7YnJlYWs7ZGVmYXVsdDp0aHJvdyBuZXcgRXJyb3IodG4pfXJldHVybiB0aGlzWzNdPW4sdGhpc31fZ2V0Um90YXRpb25NYXRyaXgodCl7Y29uc3Qgbj10fHxbLTAsLTAsLTAsLTAsLTAsLTAsLTAsLTAsLTAsLTAsLTAsLTAsLTAsLTAsLTAsLTBdLHI9dGhpcy54LGk9dGhpcy55LHM9dGhpcy56LG89TWF0aC5jb3MociksYz1NYXRoLmNvcyhpKSxsPU1hdGguY29zKHMpLGg9TWF0aC5zaW4ociksZj1NYXRoLnNpbihpKSx1PU1hdGguc2luKHMpO3N3aXRjaCh0aGlzWzNdKXtjYXNlIEYuWFlaOntjb25zdCBkPW8qbCxnPW8qdSxtPWgqbCxfPWgqdTtuWzBdPWMqbCxuWzRdPS1jKnUsbls4XT1mLG5bMV09ZyttKmYsbls1XT1kLV8qZixuWzldPS1oKmMsblsyXT1fLWQqZixuWzZdPW0rZypmLG5bMTBdPW8qYzticmVha31jYXNlIEYuWVhaOntjb25zdCBkPWMqbCxnPWMqdSxtPWYqbCxfPWYqdTtuWzBdPWQrXypoLG5bNF09bSpoLWcsbls4XT1vKmYsblsxXT1vKnUsbls1XT1vKmwsbls5XT0taCxuWzJdPWcqaC1tLG5bNl09XytkKmgsblsxMF09bypjO2JyZWFrfWNhc2UgRi5aWFk6e2NvbnN0IGQ9YypsLGc9Yyp1LG09ZipsLF89Zip1O25bMF09ZC1fKmgsbls0XT0tbyp1LG5bOF09bStnKmgsblsxXT1nK20qaCxuWzVdPW8qbCxuWzldPV8tZCpoLG5bMl09LW8qZixuWzZdPWgsblsxMF09bypjO2JyZWFrfWNhc2UgRi5aWVg6e2NvbnN0IGQ9bypsLGc9byp1LG09aCpsLF89aCp1O25bMF09YypsLG5bNF09bSpmLWcsbls4XT1kKmYrXyxuWzFdPWMqdSxuWzVdPV8qZitkLG5bOV09ZypmLW0sblsyXT0tZixuWzZdPWgqYyxuWzEwXT1vKmM7YnJlYWt9Y2FzZSBGLllaWDp7Y29uc3QgZD1vKmMsZz1vKmYsbT1oKmMsXz1oKmY7blswXT1jKmwsbls0XT1fLWQqdSxuWzhdPW0qdStnLG5bMV09dSxuWzVdPW8qbCxuWzldPS1oKmwsblsyXT0tZipsLG5bNl09Zyp1K20sblsxMF09ZC1fKnU7YnJlYWt9Y2FzZSBGLlhaWTp7Y29uc3QgZD1vKmMsZz1vKmYsbT1oKmMsXz1oKmY7blswXT1jKmwsbls0XT0tdSxuWzhdPWYqbCxuWzFdPWQqdStfLG5bNV09bypsLG5bOV09Zyp1LW0sblsyXT1tKnUtZyxuWzZdPWgqbCxuWzEwXT1fKnUrZDticmVha31kZWZhdWx0OnRocm93IG5ldyBFcnJvcih0bil9cmV0dXJuIG5bM109MCxuWzddPTAsblsxMV09MCxuWzEyXT0wLG5bMTNdPTAsblsxNF09MCxuWzE1XT0xLG59dG9RdWF0ZXJuaW9uKCl7Y29uc3QgdD1NYXRoLmNvcyh0aGlzLnlhdyouNSksbj1NYXRoLnNpbih0aGlzLnlhdyouNSkscj1NYXRoLmNvcyh0aGlzLnJvbGwqLjUpLGk9TWF0aC5zaW4odGhpcy5yb2xsKi41KSxzPU1hdGguY29zKHRoaXMucGl0Y2gqLjUpLG89TWF0aC5zaW4odGhpcy5waXRjaCouNSksYz10KnIqcytuKmkqbyxsPXQqaSpzLW4qcipvLGg9dCpyKm8rbippKnMsZj1uKnIqcy10KmkqbztyZXR1cm4gbmV3IGl0KGwsaCxmLGMpfX1mdW5jdGlvbiBMaChlKXtyZXR1cm4gZT49MCYmZTw2fWZ1bmN0aW9uIFJoKGUpe2lmKGU8MCYmZT49Nil0aHJvdyBuZXcgRXJyb3IodG4pO3JldHVybiBlfWNvbnN0IENoPS4xLFZoPTFlLTEyLGVuPTFlLTE0LE5oPTFlLTE1LGVyPU1hdGguUEkvMixXPU1hdGguUEkqMjtmdW5jdGlvbiB6aChlKXtzd2l0Y2goZSl7Y2FzZSAyOnJldHVybiBLO2Nhc2UgMzpyZXR1cm4gUDtjYXNlIDQ6cmV0dXJuIHV0O2Nhc2UgOTpyZXR1cm4gZHQ7Y2FzZSAxNjpyZXR1cm4gdHQ7ZGVmYXVsdDp0aHJvdyBuZXcgRXJyb3IoYOS4jeaUr+aMgeiOt+WPluexuzogJHtlfWApfX1mdW5jdGlvbiBVKGUpe3N3aXRjaChlKXtjYXNlIDI6cmV0dXJuIGRhO2Nhc2UgMzpyZXR1cm4gcWE7Y2FzZSA0OnJldHVybiBsaDtjYXNlIDk6cmV0dXJuIG9sO2Nhc2UgMTY6cmV0dXJuIHpsO2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKGDkuI3mlK/mjIHojrflj5blkb3lkI3nqbrpl7Q6ICR7ZX1gKX19ZnVuY3Rpb24gX3MoZSl7c3dpdGNoKGUubGVuZ3RoKXtjYXNlIDI6cmV0dXJuIG5ldyBLKGUpO2Nhc2UgMzpyZXR1cm4gbmV3IFAoZSk7Y2FzZSA0OnJldHVybiBuZXcgdXQoZSk7Y2FzZSA5OnJldHVybiBuZXcgZHQoZSk7Y2FzZSAxNjpyZXR1cm4gbmV3IHR0KGUpO2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKGDkuI3mlK/mjIHliJvlu7rlrp7kvos6ICR7bGVuZ3RofWApfX1jb25zdCAkaD17NDoidHJhbnNmb3JtTWF0MiIsNjoidHJhbnNmb3JtTWF0MmQiLDk6InRyYW5zZm9ybU1hdDMiLDE2OiJ0cmFuc2Zvcm1NYXQ0In07ZnVuY3Rpb24gdWUoZSx0KXtjb25zdCBuPVUodCkscj0kaFtlXSxpPW5bcl07aWYoIWkpdGhyb3cgbmV3IEVycm9yKGDkuI3mlK/mjIHnmoTnn6npmLXlpKflsI/vvJoke2V9YCk7cmV0dXJuIGl9Y29uc3QgeXM9e0FycmF5LEludDhBcnJheSxVaW50OEFycmF5LFVpbnQ4Q2xhbXBlZEFycmF5LEludDE2QXJyYXksVWludDE2QXJyYXksSW50MzJBcnJheSxVaW50MzJBcnJheSxGbG9hdDMyQXJyYXksRmxvYXQ2NEFycmF5fTt2YXIgbm49KGU9PihlLkFycmF5PSJBcnJheSIsZS5JbnQ4QXJyYXk9IkludDhBcnJheSIsZS5VaW50OEFycmF5PSJVaW50OEFycmF5IixlLlVpbnQ4Q2xhbXBlZEFycmF5PSJVaW50OENsYW1wZWRBcnJheSIsZS5JbnQxNkFycmF5PSJJbnQxNkFycmF5IixlLlVpbnQxNkFycmF5PSJVaW50MTZBcnJheSIsZS5JbnQzMkFycmF5PSJJbnQzMkFycmF5IixlLlVpbnQzMkFycmF5PSJVaW50MzJBcnJheSIsZS5GbG9hdDMyQXJyYXk9IkZsb2F0MzJBcnJheSIsZS5GbG9hdDY0QXJyYXk9IkZsb2F0NjRBcnJheSIsZSkpKG5ufHx7fSk7KGU9PntmdW5jdGlvbiB0KGkpe3JldHVybiB5c1tpXX1lLnRvQ2xhc3M9dDtmdW5jdGlvbiBuKGkpe3JldHVybiBpLm5hbWV9ZS50b1R5cGU9bjtmdW5jdGlvbiByKGkpe3JldHVybiBpLmNvbnN0cnVjdG9yLm5hbWV9ZS50b1R5cGVCeUFycmF5PXJ9KShubnx8KG5uPXt9KSk7ZnVuY3Rpb24ga2goZSl7dmFyIHQ9dHlwZW9mIGU7cmV0dXJuIGU9PW51bGx8fHQhPT0ib2JqZWN0IiYmdCE9PSJmdW5jdGlvbiJ9ZnVuY3Rpb24gRmgoZSl7cmV0dXJuIGUmJnR5cGVvZiBlW1N5bWJvbC5pdGVyYXRvcl09PSJmdW5jdGlvbiJ9dmFyIGRlPShlPT4oZS5lcXVhbD0iZXF1YWwiLGUuaW50ZXJzZWN0PSJpbnRlcnNlY3QiLGUuaW50ZXJzZWN0RXF1YWw9ImludGVyc2VjdEVxdWFsIixlKSkoZGV8fHt9KTsoZT0+e2Z1bmN0aW9uIHQobil7bGV0IHI7c3dpdGNoKG4pe2Nhc2UiZXF1YWwiOnI9KGkscyk9Pmk9PT1zO2Nhc2UiaW50ZXJzZWN0IjpyPShpLHMpPT5pJnM7ZGVmYXVsdDpyPShpLHMpPT4oaSZzKT09PWl9cmV0dXJuIHJ9ZS5nZXRFcXVhbEZ1bj10fSkoZGV8fChkZT17fSkpO2Z1bmN0aW9uIHhzKGUpe2NvbnN0IHQ9W107Zm9yKGNvbnN0IG4gb2ZbIngiLCJ5IiwieiIsInciXSl7aWYoZVtuXT09bnVsbClyZXR1cm4gdDt0LnB1c2goZVtuXSl9cmV0dXJuIHR9ZnVuY3Rpb24gTXMoZSl7cmV0dXJuIF9zKHhzKGUpKX1mdW5jdGlvbiBnZShlLHQsbil7bj1uPz8wO2NvbnN0IHI9bisxO2lmKGtoKGUpKXJldHVybiBlO2lmKGUueCE9bnVsbCYmZS55IT1udWxsKXJldHVybiBNcyhlKTtpZihBcnJheS5pc0FycmF5KGUpKXJldHVybiBlLm1hcChzPT5nZShzLHQscikpO2lmKGUgaW5zdGFuY2VvZiBNYXApe2NvbnN0IHM9bmV3IE1hcDtmb3IoY29uc3QgbyBvZiBlLmtleXMoKSl7Y29uc3QgYz1lLmdldChvKSxsPWdlKGMsdCxyKTtzLnNldChvLGwpfXJldHVybiBzfWlmKEZoKGUpKXtjb25zdCBzPVtdO2Zvcihjb25zdCBvIG9mIGUpe2NvbnN0IGM9Z2Uobyx0LHIpO3MucHVzaChjKX1yZXR1cm4gc31pZigodHx8bj09PTApJiZ0eXBlb2YgZT09Im9iamVjdCIpe2NvbnN0IHM9e307Zm9yKGNvbnN0IG8gb2YgT2JqZWN0LmtleXMoZSkpc1tvXT1nZShlW29dLHQscik7cmV0dXJuIHN9cmV0dXJuIGV9dmFyIHk9KGU9PihlW2UuVGhyb3VnaEludGVyc2VjdD0xXT0iVGhyb3VnaEludGVyc2VjdCIsZVtlLkpvaW50SW50ZXJzZWN0PTJdPSJKb2ludEludGVyc2VjdCIsZVtlLkludGVyc2VjdD0zXT0iSW50ZXJzZWN0IixlW2UuVGFuZ2VuY3k9NF09IlRhbmdlbmN5IixlW2UuQ29udGFpbj04XT0iQ29udGFpbiIsZVtlLkRpc3NvY2lhdGlvbj0xNl09IkRpc3NvY2lhdGlvbiIsZVtlLkFCPTMyXT0iQUIiLGVbZS5CQT02NF09IkJBIixlW2UuQUJDb250YWluPTQwXT0iQUJDb250YWluIixlW2UuQkFDb250YWluPTcyXT0iQkFDb250YWluIixlKSkoeXx8e30pO2Z1bmN0aW9uIHdzKGUsdCxuKXtmb3IobGV0IHI9MDtyPG47cisrKXtjb25zdCBpPXIqbixzPXQuc2xpY2UoaSxpK24pO2Vbcl09TWF0aC5oeXBvdCguLi5zKX1yZXR1cm4gZX1mdW5jdGlvbiBxaChlLHQsbil7Y29uc3Qgcj10LTEsaT10KnI7Zm9yKGxldCBzPTA7czxyO3MrKyllW2krc109bltzXTtyZXR1cm4gZX1mdW5jdGlvbiBucihlLHQpe3JldHVybiBCbihlLHQpLERuKGUsZSl9ZnVuY3Rpb24gVWgoZSx0KXtyZXR1cm4gd3MoZSx0LDMpfW5ldyBLLG5ldyBQLG5ldyB1dDtjb25zdCBndD1bbmV3IEssbmV3IEssbmV3IEssbmV3IEtdLG90PVtuZXcgUCxuZXcgUCxuZXcgUCxuZXcgUF0sRGg9W25ldyB1dCxuZXcgdXQsbmV3IHV0LG5ldyB1dF0scm49W25ldyBkdCxuZXcgZHQsbmV3IGR0LG5ldyBkdF0sQXM9W25ldyB0dCxuZXcgdHQsbmV3IHR0LG5ldyB0dF0sVHM9W25ldyBpdCxuZXcgaXQsbmV3IGl0LG5ldyBpdF0sQmg9W25ldyBGLG5ldyBGLG5ldyBGLG5ldyBGXTtmdW5jdGlvbiBjdChlKXtzd2l0Y2goZSl7Y2FzZSAyOnJldHVybiBndDtjYXNlIDM6cmV0dXJuIG90O2Nhc2UgNDpyZXR1cm4gRGg7Y2FzZSA5OnJldHVybiBybjtjYXNlIDE2OnJldHVybiBBcztkZWZhdWx0OnRocm93IG5ldyBFcnJvcihg5LiN5pSv5oyB6I635Y+W5Li05pe25Y+Y6YePOiAke2V9YCl9fWZ1bmN0aW9uIFloKGUsdD1uZXcgdHQpe3JldHVybiB0WzBdPWVbMF0sdFsxXT1lWzFdLHRbMl09ZVsyXSx0WzNdPTAsdFs0XT1lWzNdLHRbNV09ZVs0XSx0WzZdPWVbNV0sdFs3XT0wLHRbOF09ZVs2XSx0WzldPWVbN10sdFsxMF09ZVs4XSx0WzExXT0wLHRbMTJdPTAsdFsxM109MCx0WzE0XT0wLHRbMTVdPTEsdC5jaGVjaygpfWZ1bmN0aW9uIFdoKGUsdCl7cmV0dXJuIGVbMTJdPXRbMF0sZVsxM109dFsxXSxlWzE0XT10WzJdLGV9ZnVuY3Rpb24gdnMoZSx0KXtyZXR1cm4gZVswXT1NYXRoLmh5cG90KHRbMF0sdFsxXSx0WzJdKSxlWzFdPU1hdGguaHlwb3QodFs0XSx0WzVdLHRbNl0pLGVbMl09TWF0aC5oeXBvdCh0WzhdLHRbOV0sdFsxMF0pLFhuKHQpPDAmJihlWzBdPS1lWzBdKSxlfWZ1bmN0aW9uIEVzKGUsdCxuKXt2cyhlLG4pO2NvbnN0IHI9MS9lWzBdLGk9MS9lWzFdLHM9MS9lWzJdO3JldHVybiB0WzBdPW5bMF0qcix0WzFdPW5bMV0qaSx0WzJdPW5bMl0qcyx0WzNdPW5bNF0qcix0WzRdPW5bNV0qaSx0WzVdPW5bNl0qcyx0WzZdPW5bOF0qcix0WzddPW5bOV0qaSx0WzhdPW5bMTBdKnMsdH1mdW5jdGlvbiBycihlLHQsbil7Y29uc3Qgcj1FcyhlLHJuWzBdLG4pO3JldHVybiB0cih0LHIpLHR9ZnVuY3Rpb24gWmgoZSx0LG4pe2NvbnN0IHI9blswXSxpPW5bMV0scz1uWzJdLG89blszXSxjPXIrcixsPWkraSxoPXMrcyxmPXIqYyx1PXIqbCxkPXIqaCxnPWkqbCxtPWkqaCxfPXMqaCxwPW8qYyxNPW8qbCxBPW8qaCx4PXRbMF0sVD10WzFdLHY9dFsyXTtyZXR1cm4gZVswXT0oMS0oZytfKSkqeCxlWzFdPSh1K0EpKngsZVsyXT0oZC1NKSp4LGVbM109MCxlWzRdPSh1LUEpKlQsZVs1XT0oMS0oZitfKSkqVCxlWzZdPShtK3ApKlQsZVs3XT0wLGVbOF09KGQrTSkqdixlWzldPShtLXApKnYsZVsxMF09KDEtKGYrZykpKnYsZVsxMV09MCxlWzE1XT0xLGV9ZnVuY3Rpb24gaXIoZSx0LG4pe2NvbnN0IHI9blswXSxpPW5bMV0scz1uWzJdLG89blszXSxjPXIrcixsPWkraSxoPXMrcyxmPXIqYyx1PXIqbCxkPXIqaCxnPWkqbCxtPWkqaCxfPXMqaCxwPW8qYyxNPW8qbCxBPW8qaCx4PXRbMF0sVD10WzFdLHY9dFsyXTtyZXR1cm4gZVswXT0oMS0oZytfKSkqeCxlWzFdPSh1K0EpKngsZVsyXT0oZC1NKSp4LGVbM109MCxlWzRdPSh1LUEpKlQsZVs1XT0oMS0oZitfKSkqVCxlWzZdPShtK3ApKlQsZVs3XT0wLGVbOF09KGQrTSkqdixlWzldPShtLXApKnYsZVsxMF09KDEtKGYrZykpKnYsZVsxMV09MCxlWzEyXT0wLGVbMTNdPTAsZVsxNF09MCxlWzE1XT0xLGV9ZnVuY3Rpb24gR2goZSx0LG4scil7cmV0dXJuIERpKGUscikscnIodCxuLHIpLG59ZnVuY3Rpb24gWGgoZSx0LG4scil7cmV0dXJuIFlpKGUscix0LG4pLGV9ZnVuY3Rpb24gT3MoZSx0LG4pe2NvbnN0IHI9VSh0Lmxlbmd0aCksaT1yLnNxdWFyZWRMZW5ndGgobik7aWYoayhpLDApKXJldHVybiByLnNjYWxlKGUsdCwwKTtjb25zdCBzPXIuZG90KHQsbikvaTtyZXR1cm4gci5zY2FsZShlLG4scyl9ZnVuY3Rpb24gbXQoZSx0LG4pe3JldHVybiBPcyhlLHQsbiksVHQoZSx0LGUpfWZ1bmN0aW9uIGpoKGUsdCxuKXtyZXR1cm4gVSh0Lmxlbmd0aCkuY3Jvc3MoZSx0LG4pfWZ1bmN0aW9uIFkoZSx0KXtjb25zdCBuPXQuZmluZEluZGV4KGk9PiFrKGksMCkpO2lmKG49PT0tMSlyZXR1cm4gMDtjb25zdCByPWVbbl07cmV0dXJuIGsociwwKT8xLzA6dFtuXS9yfWZ1bmN0aW9uIHNuKGUsdCl7Y29uc3Qgbj10LmZpbmRJbmRleChzPT4hayhzLDApKTtpZihuPT09LTEpcmV0dXJuITA7Y29uc3Qgcj1lW25dL3Rbbl07cmV0dXJuIHd0LmdldENyb3NzQXhpc3MobikuZXZlcnkocz0+ayh0W3NdKnIsZVtzXSkpfWZ1bmN0aW9uIFFoKGUsdCl7Y29uc3Qgbj1VKGUubGVuZ3RoKSxyPW4uY3Jvc3MoW10sZSx0KSxpPW4uc3F1YXJlZExlbmd0aChyKTtyZXR1cm4gayhpLDApfWZ1bmN0aW9uIGJzKGUsdCl7cmV0dXJuIGsoRHQoW10sZSx0KVsyXSwwKX1mdW5jdGlvbiBLaChlLHQpe2NvbnN0IG49cnQoW10sZSx0KTtyZXR1cm4gayhEZShuKSwwKX1mdW5jdGlvbiBJcyhlLHQpe2NvbnN0IHI9VShlLmxlbmd0aCkuY3Jvc3MoW10sZSx0KTtyZXR1cm4gTWF0aC5oeXBvdCguLi5yKX1mdW5jdGlvbiBTcyhlLHQpe2NvbnN0IG49cnQoW10sZSx0KTtyZXR1cm4gTWF0aC5oeXBvdCguLi5uKX1mdW5jdGlvbiBQcyhlLHQpe3JldHVybiBNYXRoLmFicyhXdChlLHQpKX1mdW5jdGlvbiBMcyhlLHQsbil7cmV0dXJuIGUubGVuZ3RoPT09Mj9XdChlLHQpOnNyKGUsdCxuKX1mdW5jdGlvbiBXdChlLHQpe3JldHVybiBEdChbXSxlLHQpWzJdfWZ1bmN0aW9uIHNyKGUsdCxuKXtjb25zdCByPVsuLi5lLC4uLnQsLi4ubl07cmV0dXJuIGZlKHIpfWZ1bmN0aW9uIG9yKGUsdCl7Y29uc3Qgbj1VKGUubGVuZ3RoKTtyZXR1cm4gbi5kb3QoZSx0KTwwJiZuLm5lZ2F0ZShlLGUpLGV9ZnVuY3Rpb24gUnMoZSl7cmV0dXJuIE1hdGguaHlwb3QoLi4uZSl9ZnVuY3Rpb24gQ3MoZSx0LG4pe2NvbnN0IHI9dC5sZW5ndGg7Zm9yKGxldCBpPTA7aTxyO2krKyllW2ldPXRbaV0rbltpXTtyZXR1cm4gZX1mdW5jdGlvbiBUdChlLHQsbil7Y29uc3Qgcj10Lmxlbmd0aDtmb3IobGV0IGk9MDtpPHI7aSsrKWVbaV09dFtpXS1uW2ldO3JldHVybiBlfWZ1bmN0aW9uIEpoKGUsdCxuKXtjb25zdCByPXQubGVuZ3RoO2ZvcihsZXQgaT0wO2k8cjtpKyspZVtpXT10W2ldKm5baV07cmV0dXJuIGV9ZnVuY3Rpb24gSGgoZSx0LG4pe2NvbnN0IHI9dC5sZW5ndGg7Zm9yKGxldCBpPTA7aTxyO2krKyllW2ldPXRbaV0vbltpXTtyZXR1cm4gZX1mdW5jdGlvbiB0ZihlLHQpe2NvbnN0IG49dC5sZW5ndGg7Zm9yKGxldCByPTA7cjxuO3IrKyllW3JdPU1hdGguY2VpbCh0W3JdKTtyZXR1cm4gZX1mdW5jdGlvbiBlZihlLHQpe2NvbnN0IG49dC5sZW5ndGg7Zm9yKGxldCByPTA7cjxuO3IrKyllW3JdPU1hdGguZmxvb3IodFtyXSk7cmV0dXJuIGV9ZnVuY3Rpb24gbmYoZSx0LG4pe2NvbnN0IHI9dC5sZW5ndGg7Zm9yKGxldCBpPTA7aTxyO2krKyllW2ldPU1hdGgubWluKHRbaV0sbltpXSk7cmV0dXJuIGV9ZnVuY3Rpb24gcmYoZSx0LG4pe2NvbnN0IHI9dC5sZW5ndGg7Zm9yKGxldCBpPTA7aTxyO2krKyllW2ldPU1hdGgubWF4KHRbaV0sbltpXSk7cmV0dXJuIGV9ZnVuY3Rpb24gc2YoZSl7cmV0dXJuIGU8MD9NYXRoLmNlaWwoZS0uNSk6TWF0aC5mbG9vcihlKy41KX1mdW5jdGlvbiBvZihlLHQpe2NvbnN0IG49dC5sZW5ndGg7Zm9yKGxldCByPTA7cjxuO3IrKyllW3JdPXNmKHRbcl0pO3JldHVybiBlfWZ1bmN0aW9uIGNyKGUsdCxuKXtjb25zdCByPXQubGVuZ3RoO2ZvcihsZXQgaT0wO2k8cjtpKyspZVtpXT10W2ldKm47cmV0dXJuIGV9ZnVuY3Rpb24gYXIoZSx0LG4scil7Y29uc3QgaT10Lmxlbmd0aDtmb3IobGV0IHM9MDtzPGk7cysrKWVbc109dFtzXStuW3NdKnI7cmV0dXJuIGV9ZnVuY3Rpb24gVnMoZSx0KXtjb25zdCBuPVR0KFtdLHQsZSk7cmV0dXJuIFJzKG4pfWZ1bmN0aW9uIE5zKGUsdCl7Y29uc3Qgbj1UdChbXSx0LGUpO3JldHVybiBscihuKX1mdW5jdGlvbiBscihlKXtjb25zdCB0PWUubGVuZ3RoO2xldCBuPTA7Zm9yKGxldCByPTA7cjx0O3IrKyluKz1lW3JdKioyO3JldHVybiBufWZ1bmN0aW9uIGNmKGUsdCl7Y29uc3Qgbj10Lmxlbmd0aDtmb3IobGV0IHI9MDtyPG47cisrKWVbcl09LXRbcl07cmV0dXJuIGV9ZnVuY3Rpb24gYWYoZSx0KXtjb25zdCBuPXQubGVuZ3RoO2ZvcihsZXQgcj0wO3I8bjtyKyspZVtyXT0xL3Rbcl07cmV0dXJuIGV9ZnVuY3Rpb24gbGYoZSx0KXtjb25zdCBuPWxyKHQpLHI9bj4wPzEvTWF0aC5zcXJ0KG4pOjA7cmV0dXJuIGNyKGUsdCxyKX1mdW5jdGlvbiBvbihlLHQpe2NvbnN0IG49ZS5sZW5ndGg7bGV0IHI9MDtmb3IobGV0IGk9MDtpPG47aSsrKXIrPWVbaV0qdFtpXTtyZXR1cm4gcn1mdW5jdGlvbiBoZihlLHQsbixyKXtjb25zdCBpPXQubGVuZ3RoO2ZvcihsZXQgcz0wO3M8aTtzKyspZVtzXT10W3NdK3IqKG5bc10tdFtzXSk7cmV0dXJuIGV9ZnVuY3Rpb24gZmYoZSx0LG4scil7Y29uc3QgaT1NYXRoLmFjb3MoTWF0aC5taW4oTWF0aC5tYXgob24odCxuKSwtMSksMSkpLHM9TWF0aC5zaW4oaSksbz1NYXRoLnNpbigoMS1yKSppKS9zLGM9TWF0aC5zaW4ocippKS9zLGw9dC5sZW5ndGg7Zm9yKGxldCBoPTA7aDxsO2grKyllW2hdPW8qdFtoXStjKm5baF07cmV0dXJuIGV9ZnVuY3Rpb24gdWYoZSx0PW5ldyBpdCl7c3dpdGNoKHQuaWRlbnRpdHkoKSxlLm9yZGVyKXtjYXNlIEYuWFlaOnJldHVybiB0LnJvdGF0ZVgoZVswXSkucm90YXRlWShlWzFdKS5yb3RhdGVaKGVbMl0pO2Nhc2UgRi5ZWFo6cmV0dXJuIHQucm90YXRlWShlWzBdKS5yb3RhdGVYKGVbMV0pLnJvdGF0ZVooZVsyXSk7Y2FzZSBGLlpYWTpyZXR1cm4gdC5yb3RhdGVaKGVbMF0pLnJvdGF0ZVgoZVsxXSkucm90YXRlWShlWzJdKTtjYXNlIEYuWllYOnJldHVybiB0LnJvdGF0ZVooZVswXSkucm90YXRlWShlWzFdKS5yb3RhdGVYKGVbMl0pO2Nhc2UgRi5ZWlg6cmV0dXJuIHQucm90YXRlWShlWzBdKS5yb3RhdGVaKGVbMV0pLnJvdGF0ZVgoZVsyXSk7Y2FzZSBGLlhaWTpyZXR1cm4gdC5yb3RhdGVYKGVbMF0pLnJvdGF0ZVooZVsxXSkucm90YXRlWShlWzJdKTtkZWZhdWx0OnRocm93IG5ldyBFcnJvcigiVW5rbm93biBFdWxlciBhbmdsZSBvcmRlciIpfX1mdW5jdGlvbiB6cyhlLHQsbixyPW5ldyBpdCl7Y29uc3RbaSxzXT1vdDtyZXR1cm4gbXQoaSxlLG4pLm5vcm1hbGl6ZSgpLG10KHMsdCxuKS5ub3JtYWxpemUoKSxyLnJvdGF0aW9uVG8oaSxzKX1mdW5jdGlvbiBocihlLHQsbj1uZXcgaXQpe2NvbnN0W3IsaSxzXT1vdDtyLmNvcHkoZS50YW5nZW50KS5ub3JtYWxpemUoKSxpLmNvcHkodC50YW5nZW50KS5ub3JtYWxpemUoKTtjb25zdCBvPVRzWzBdLnJvdGF0aW9uVG8ocixpKTtyZXR1cm4gQnQocyxlLm5vcm1hbCxvKSx6cyhzLHQubm9ybWFsLGksbiksbi5tdWx0aXBseShvKSxufWZ1bmN0aW9uICRzKGUsdCl7cmV0dXJuIE1hdGguc2lnbihlKT09PU1hdGguc2lnbih0KSYmTWF0aC5hYnMoZSk8TWF0aC5hYnModCk/ZTooZSV0K3QpJXR9ZnVuY3Rpb24gZnIoZSx0LG49MCxyPW4pe2NvbnN0IGk9TWF0aC5hYnMoZS10KTtyZXR1cm4gaTw9cnx8aTw9bipNYXRoLm1heChNYXRoLmFicyhlKSxNYXRoLmFicyh0KSl9ZnVuY3Rpb24gdXIoZSx0LG49MCl7Y29uc3Qgcj1VKGUubGVuZ3RoKTtsZXQgaT1yLnNxdWFyZWRMZW5ndGgoZSkqci5zcXVhcmVkTGVuZ3RoKHQpO2lmKGk9PT0wKXJldHVybiBuO2k9TWF0aC5zcXJ0KGkpO2xldCBzPXIuZG90KGUsdCkvaTtyZXR1cm4gcz1NYXRoLm1heCgtMSxNYXRoLm1pbigxLHMpKSxNYXRoLmFjb3Mocyl9ZnVuY3Rpb24gbWUoZSx0LG4pe2xldCByPXVyKGUsdCk7cmV0dXJuIHI9PT0wP3I6b3RbMF0uY29weShlKS5jcm9zcyh0KS5kb3Qobik8MD8tcjpyfWZ1bmN0aW9uIGRmKGUsdCxuKXtjb25zdFtyLGldPWN0KGUubGVuZ3RoKTtyZXR1cm4gbXQocixlLG4pLG10KGksdCxuKSxtZShyLGksbil9ZnVuY3Rpb24gZ2YoZSx0LG4pe2NvbnN0W3IsaSxzLG9dPW90O3IubmVnYXRlKCksbXQoaSxuLHQpLG10KHMsZSxpKTtjb25zdCBjPW1lKHQscyxpKSxsPW5ldyBQKHQpLmNyb3NzKGkpO210KG8sZSxsKTtjb25zdCBoPW1lKHQsbyxsKSxmPW10KG5ldyBQLGUsciksdT1tZShpLGYscik7cmV0dXJue3lhdzpjLHBpdGNoOmgscm9sbDp1fX1mdW5jdGlvbiBadChlKXtyZXR1cm4gZT49LU1hdGguUEkmJmU8PU1hdGguUEk/ZTprcyhlK01hdGguUEkpLU1hdGguUEl9ZnVuY3Rpb24ga3MoZSl7aWYoZT49MCYmZTw9VylyZXR1cm4gZTtjb25zdCB0PSRzKGUsVyk7cmV0dXJuIE1hdGguYWJzKHQpPGVuJiZNYXRoLmFicyhlKT5lbj9XOnR9ZnVuY3Rpb24gbWYoZSx0KXtjb25zdCBuPXVyKGUsdCk7cmV0dXJuIG4+ZXI/Vy1uOm59ZnVuY3Rpb24gRnMoZSx0LG4scil7Y29uc3QgaT1yfHxlLnNsaWNlKCk7cmV0dXJuIHJ0KGksaSx0KSxrKERlKGkpLDApJiYobj9rKE1hdGguYWJzKHRbMl0pLDEpP2VbMF0tPTFlLTQ6ZVsyXSs9MWUtNDprKE1hdGguYWJzKGVbMF0pLDEpP3RbMl0tPTFlLTQ6dFswXSs9MWUtNCxJdCh0LHQpLHJ0KGksZSx0KSksbj9ydChlLHQsaSk6cnQodCxpLGUpLEl0KGksaSksSXQodCx0KSxJdChlLGUpLHt0YW5nZW50OmUsbm9ybWFsOnQsYmlub3JtYWw6aX19ZnVuY3Rpb24gcXMoZSx0LG4scil7Y29uc3R7Ymlub3JtYWw6aX09RnMoZSx0LG4scik7cmV0dXJuIEJlKGksaSkse2Zyb250OmUsdXA6dCxiaW5vcm1hbDppfX1mdW5jdGlvbiBwZihlKXtjb25zdHt0YW5nZW50OnQsbm9ybWFsOm4sYmlub3JtYWw6cn09ZTtyZXR1cm57ZnJvbnQ6dCx1cDpuLGJpbm9ybWFsOkJlKFtdLHIpfX1mdW5jdGlvbiBfZihlKXtjb25zdHtmcm9udDp0LHVwOm4sYmlub3JtYWw6cn09ZTtyZXR1cm57dGFuZ2VudDp0LG5vcm1hbDpuLGJpbm9ybWFsOkJlKFtdLHIpfX1mdW5jdGlvbiB5ZihlLHQsbixyPW5ldyBkdCl7Y29uc3R7ZnJvbnQ6aSx1cDpzLGJpbm9ybWFsOm99PXFzKEl0KFtdLGUpLEl0KFtdLHQpLG4pO3JldHVybiByLnNldENvbHVtbigwLG8pLHIuc2V0Q29sdW1uKDEscyksci5zZXRDb2x1bW4oMixpKSxyfWNvbnN0IFVzPXtlYXN0OlsxLDAsMF0sbm9ydGg6WzAsMCwxXSx1cDpbMCwtMSwwXX07ZnVuY3Rpb24gRHMoZSx0PVVzKXtjb25zdFtuLHJdPWUscz1CaFswXS5zZXQoLXIsMCxuLEYuWVhaKS50b1F1YXRlcm5pb24oKSx7ZWFzdDpvLG5vcnRoOmMsdXA6bH09dCxoPW5ldyBQKC4uLm8pLnRyYW5zZm9ybUJ5UXVhdGVybmlvbihzKSxmPW5ldyBQKC4uLmMpLnRyYW5zZm9ybUJ5UXVhdGVybmlvbihzKSx1PW5ldyBQKC4uLmwpLnRyYW5zZm9ybUJ5UXVhdGVybmlvbihzKTtyZXR1cm57ZWFzdDpoLG5vcnRoOmYsdXA6dX19ZnVuY3Rpb24gZHIoZSx0PVVzKXtjb25zdFtuLHIsaSxzXT1vdDtpLnNldCgwLC0xLDApLG4uc2V0KDAsMCwxKSxzLmNvcHkoZSkubm9ybWFsaXplKCksbXQocixzLG4pLHIubm9ybWFsaXplKCk7Y29uc3RbbyxjXT1UcztvLnJvdGF0aW9uVG8oaSxyKSxjLnJvdGF0aW9uVG8ocixzKSxjLm11bHRpcGx5UmlnaHQobyk7Y29uc3R7ZWFzdDpsLG5vcnRoOmgsdXA6Zn09dCx1PW5ldyBQKC4uLmwpLnRyYW5zZm9ybUJ5UXVhdGVybmlvbihjKSxkPW5ldyBQKC4uLmgpLnRyYW5zZm9ybUJ5UXVhdGVybmlvbihjKSxnPW5ldyBQKC4uLmYpLnRyYW5zZm9ybUJ5UXVhdGVybmlvbihjKTtyZXR1cm57ZWFzdDp1LG5vcnRoOmQsdXA6Z319ZnVuY3Rpb24gY24oZSx0KXtjb25zdHt4Om4seTpyLHo6aX09ZSxzPWZ0LmdldFZlY3RvcihmdFtuXSx0KSxvPWZ0LmdldFZlY3RvcihmdFtyXSx0KSxjPWZ0LmdldFZlY3RvcihmdFtpXSx0KTtyZXR1cm4gbmV3IGR0KFsuLi5zLC4uLm8sLi4uY10pfWZ1bmN0aW9uIEJzKGUsdCxuKXtjb25zdCByPW90WzBdLmNvcHkoZSksaT1jbih0LG4pO3JldHVybiByLnRyYW5zZm9ybUJ5TWF0cml4MyhpKS5uZWdhdGUoKSxyLmFkZChlKSxuZXcgdHQoWy4uLmkuc2xpY2UoMCwzKSwwLC4uLmkuc2xpY2UoMyw2KSwwLC4uLmkuc2xpY2UoNiw5KSwwLC4uLnIsMV0pfWZ1bmN0aW9uIHhmKGUsdCxuKXtjb25zdCByPWRyKGUsbik7cmV0dXJuIEJzKGUsdCxyKX1mdW5jdGlvbiBNZihlLHQsbil7Y29uc3Qgcj1kcihlLG4pO3JldHVybiBjbih0LHIpfWZ1bmN0aW9uIHdmKGUsdCxuKXtjb25zdCByPURzKGUsbik7cmV0dXJuIGNuKHQscil9Y29uc3QgWXM9bmV3IFAoMSwxLDEpLFdzPW5ldyBQKDAsMCwxKTtjbGFzcyBOdHthcnJheTtjb3VudD0wO3ZlY3RvclNpemU7c3RhcnQ9MDtnZXQgZW5kKCl7cmV0dXJuIHRoaXMuc3RhcnQrdGhpcy5jb3VudCp0aGlzLnZlY3RvclNpemV9c2V0IGVuZCh0KXt0aGlzLmNvdW50PU1hdGgudHJ1bmMoKHQtdGhpcy5zdGFydCkvdGhpcy52ZWN0b3JTaXplKX1jb25zdHJ1Y3Rvcih0KXt0JiZ0aGlzLnNldE9wdGlvbnModCl9c2V0T3B0aW9ucyh0KXtjb25zdHtlbmQ6bixjb3VudDpyLC4uLml9PXQ7T2JqZWN0LmFzc2lnbih0aGlzLGkpLG49PW51bGwmJnI9PW51bGw/dGhpcy5jb3VudD10aGlzLmFycmF5Lmxlbmd0aC90aGlzLnZlY3RvclNpemU6biE9bnVsbCYmKHRoaXMuZW5kPW4pfWZyb20odCl7Y29uc3R7YXJyYXk6biwuLi5yfT10O3JldHVybiB0aGlzLnNldE9wdGlvbnMoe2FycmF5Om4uc2xpY2UoKSwuLi5yfSksdGhpc31jbG9uZSgpe2NvbnN0IHQ9bmV3IHRoaXMuY29uc3RydWN0b3I7cmV0dXJuIHQuZnJvbSh0aGlzKSx0fWNvcHkodCl7Zm9yKGxldCBuPTA7bjx0aGlzLmNvdW50O24rKyl0aGlzLmNvcHlBdChuLHQsbik7cmV0dXJuIHRoaXN9Y29weUF0KHQsbixyKXtjb25zdCBpPW4uZ2V0VmVjdG9yKHIpO3JldHVybiB0aGlzLnNldFZlY3Rvcih0LGkpLHRoaXN9Y29weUFycmF5KHQpe2NvbnN0IG49dGhpcy5zdGFydDtmb3IobGV0IHI9MCxpPXQubGVuZ3RoO3I8aTtyKyspdGhpcy5hcnJheVtuK3JdPXRbcl07cmV0dXJuIHRoaXN9Z2V0U3RhcnRBcnJheUluZGV4KHQpe3JldHVybiB0aGlzLnN0YXJ0K3QqdGhpcy52ZWN0b3JTaXplfWdldEFycmF5SW5kZXhSYW5nZSh0KXtjb25zdCBuPXRoaXMuc3RhcnQrdCp0aGlzLnZlY3RvclNpemU7cmV0dXJuW24sbit0aGlzLnZlY3RvclNpemVdfWdldFZlY3Rvcih0KXtyZXR1cm4gdGhpcy5hcnJheS5zbGljZSguLi50aGlzLmdldEFycmF5SW5kZXhSYW5nZSh0KSl9c2V0VmVjdG9yKHQsbixyPTApe2NvbnN0IGk9dGhpcy5nZXRTdGFydEFycmF5SW5kZXgodCk7Zm9yKGxldCBzPTAsbz10aGlzLnZlY3RvclNpemU7czxvO3MrKyl0aGlzLmFycmF5W2krc109bltyK3NdO3JldHVybiByK3RoaXMudmVjdG9yU2l6ZX10b1ZlY3RvcnModD1bXSl7Y29uc3R7c3RhcnQ6bixlbmQ6cix2ZWN0b3JTaXplOmksYXJyYXk6c309dGhpcztmb3IobGV0IG89bjtvPHI7bys9aSl7Y29uc3QgYz1zLnNsaWNlKG8sbytpKTt0LnB1c2goYyl9cmV0dXJuIHR9bWFwKHQsbj1bXSl7Zm9yKGxldCByPTA7cjx0aGlzLmNvdW50O3IrKyl7Y29uc3QgaT10aGlzLmdldFZlY3RvcihyKTtuW3JdPXQoaSxyKX1yZXR1cm4gbn1tYXBTZWxmKHQpe2ZvcihsZXQgbj0wO248dGhpcy5jb3VudDtuKyspe2NvbnN0IHI9dGhpcy5nZXRWZWN0b3IobiksaT10KHIsbik7dGhpcy5zZXRWZWN0b3IobixpKX1yZXR1cm4gdGhpc31maWx0ZXIodCxuPVtdKXtmb3IobGV0IHI9MDtyPHRoaXMuY291bnQ7cisrKXtjb25zdCBpPXRoaXMuZ2V0VmVjdG9yKHIpO2lmKHQoaSxyKSlmb3IoY29uc3QgcyBvZiBpKW5bbi5sZW5ndGhdPXN9cmV0dXJuIG59dHJhbnNmb3JtKHQpe2NvbnN0IG49dWUodC5sZW5ndGgsdGhpcy52ZWN0b3JTaXplKTtyZXR1cm4gdGhpcy5tYXBTZWxmKHI9Pm4ocixyLHQpKX10cmFuc2Zvcm1Bc05vcm1hbCh0KXtjb25zdCBuPXJuWzBdO3QubGVuZ3RoPT09MTY/V24obix0KTpucihuLHQpO2NvbnN0IHI9dWUobi5sZW5ndGgsdGhpcy52ZWN0b3JTaXplKTtyZXR1cm4gdGhpcy5tYXBTZWxmKGk9PnIoaSxpLG4pKX1zY2FsZSh0KXtjb25zdCBuPVUodGhpcy52ZWN0b3JTaXplKTtyZXR1cm4gdGhpcy5tYXBTZWxmKHI9Pm4uc2NhbGUocixyLHQpKX1zY2FsZUFuZEFkZCh0LG4pe2NvbnN0IHI9VSh0aGlzLnZlY3RvclNpemUpO3JldHVybiB0aGlzLm1hcFNlbGYoaT0+ci5zY2FsZUFuZEFkZChpLGksdCxuKSl9YWRkKHQpe2NvbnN0IG49VSh0aGlzLnZlY3RvclNpemUpO3JldHVybiB0aGlzLm1hcFNlbGYocj0+bi5hZGQocixyLHQpKX1zdWJ0cmFjdCh0KXtjb25zdCBuPVUodGhpcy52ZWN0b3JTaXplKTtyZXR1cm4gdGhpcy5tYXBTZWxmKHI9Pm4uc3VidHJhY3QocixyLHQpKX1tdWx0aXBseSh0KXtjb25zdCBuPVUodGhpcy52ZWN0b3JTaXplKTtyZXR1cm4gdGhpcy5tYXBTZWxmKHI9Pm4ubXVsdGlwbHkocixyLHQpKX1kaXZpZGUodCl7Y29uc3Qgbj1VKHRoaXMudmVjdG9yU2l6ZSk7cmV0dXJuIHRoaXMubWFwU2VsZihyPT5uLmRpdmlkZShyLHIsdCkpfX1mdW5jdGlvbiBBZihlLHQpe2NvbnN0e3ZlY3RvclNpemU6bixzdGFydDpyPTAsYXJyYXk6aX09ZSxzPXVlKHQubGVuZ3RoLG4pLG89ZS5lbmQ/P2kubGVuZ3RoO2ZvcihsZXQgYz1yO2M8bztjKz1uKXtjb25zdCBsPWkuc2xpY2UoYyxjK24pO3MobCxsLHQpO2ZvcihsZXQgaD0wO2g8bjtoKyspaVtjK2hdPWxbaF19cmV0dXJuIGV9ZnVuY3Rpb24gVGYoZSx0KXtjb25zdHt2ZWN0b3JTaXplOm4sc3RhcnQ6cj0wLGFycmF5Oml9PWUscz1VKG4pLG89ZS5lbmQ/P2kubGVuZ3RoO2ZvcihsZXQgYz1yO2M8bztjKz1uKXtjb25zdCBsPWkuc2xpY2UoYyxjK24pO3Muc2NhbGUobCxsLHQpO2ZvcihsZXQgaD0wO2g8bjtoKyspaVtjK2hdPWxbaF19cmV0dXJuIGV9ZnVuY3Rpb24gdmYoZSx0LG4pe2NvbnN0e3ZlY3RvclNpemU6cixzdGFydDppPTAsYXJyYXk6c309ZSxvPVUociksYz1lLmVuZD8/cy5sZW5ndGg7Zm9yKGxldCBsPWk7bDxjO2wrPXIpe2NvbnN0IGg9cy5zbGljZShsLGwrcik7by5zY2FsZUFuZEFkZChoLGgsdCxuKTtmb3IobGV0IGY9MDtmPHI7ZisrKXNbbCtmXT1oW2ZdfXJldHVybiBlfWZ1bmN0aW9uIEVmKGUsdCl7Y29uc3R7dmVjdG9yU2l6ZTpuLHN0YXJ0OnI9MCxhcnJheTppfT1lLHM9VShuKSxvPWUuZW5kPz9pLmxlbmd0aDtmb3IobGV0IGM9cjtjPG87Yys9bil7Y29uc3QgbD1pLnNsaWNlKGMsYytuKTtzLmFkZChsLGwsdCk7Zm9yKGxldCBoPTA7aDxuO2grKylpW2MraF09bFtoXX1yZXR1cm4gZX1mdW5jdGlvbiBPZihlLHQpe2NvbnN0e3ZlY3RvclNpemU6bixzdGFydDpyPTAsYXJyYXk6aX09ZSxzPVUobiksbz1lLmVuZD8/aS5sZW5ndGg7Zm9yKGxldCBjPXI7YzxvO2MrPW4pe2NvbnN0IGw9aS5zbGljZShjLGMrbik7cy5zdWJ0cmFjdChsLGwsdCk7Zm9yKGxldCBoPTA7aDxuO2grKylpW2MraF09bFtoXX1yZXR1cm4gZX1mdW5jdGlvbiBiZihlLHQpe2NvbnN0e3ZlY3RvclNpemU6bixzdGFydDpyPTAsYXJyYXk6aX09ZSxzPVUobiksbz1lLmVuZD8/aS5sZW5ndGg7Zm9yKGxldCBjPXI7YzxvO2MrPW4pe2NvbnN0IGw9aS5zbGljZShjLGMrbik7cy5tdWx0aXBseShsLGwsdCk7Zm9yKGxldCBoPTA7aDxuO2grKylpW2MraF09bFtoXX1yZXR1cm4gZX1mdW5jdGlvbiBJZihlLHQpe2NvbnN0e3ZlY3RvclNpemU6bixzdGFydDpyPTAsYXJyYXk6aX09ZSxzPVUobiksbz1lLmVuZD8/aS5sZW5ndGg7Zm9yKGxldCBjPXI7YzxvO2MrPW4pe2NvbnN0IGw9aS5zbGljZShjLGMrbik7cy5kaXZpZGUobCxsLHQpO2ZvcihsZXQgaD0wO2g8bjtoKyspaVtjK2hdPWxbaF19cmV0dXJuIGV9ZnVuY3Rpb24gU2YoZSx0LG4scj1bXSl7Y29uc3QgaT1NYXRoLmNlaWwoZS5sZW5ndGgvdCk7bGV0IHM9MDtmb3IobGV0IG89MDtvPGk7bysrKXtzPW8qdDtjb25zdCBjPWUuc2xpY2UocyxzK3QpO3Jbb109bihjKX1yZXR1cm4gcn1mdW5jdGlvbiBQZihlLHQsbixyPVtdKXtjb25zdCBpPU1hdGguY2VpbChlLmxlbmd0aC90KTtsZXQgcz0wO2ZvcihsZXQgbz0wO288aTtvKyspe3M9byp0O2NvbnN0IGM9ZS5zbGljZShzLHMrdCk7bihjKSYmci5wdXNoKC4uLmMpfXJldHVybiByfWZ1bmN0aW9uIFpzKGUpe3JldHVybiBlLmZsYXRNYXAodD0+Wy4uLnRdKX12YXIgR3M9KGU9PihlLnBvc2l0aW9uPSJwb3NpdGlvbiIsZS5ub3JtYWw9Im5vcm1hbCIsZS5iaW5vcm1hbD0iYmlub3JtYWwiLGUudGFuZ2VudD0idGFuZ2VudCIsZS51dj0idXYiLGUuY29sb3I9ImNvbG9yIixlLmhlaWdodD0iaGVpZ2h0IixlKSkoR3N8fHt9KTtjbGFzcyBYc3thcnJheTthdHRyaWJ1dGVzO2NvdW50O2NvbnN0cnVjdG9yKHQpe3QmJnRoaXMuc2V0T3B0aW9ucyh0KX1zZXRPcHRpb25zKHQpe2NvbnN0e2F0dHJpYnV0ZXM6bixhcnJheTpyLGNvdW50OmksLi4uc309dDtPYmplY3QuYXNzaWduKHRoaXMscyx7YXJyYXk6cixjb3VudDppfSk7Y29uc3Qgbz10aGlzLmF0dHJpYnV0ZXM9e307Zm9yKGNvbnN0W2MsbF1vZiBPYmplY3QuZW50cmllcyhuKSlvW2NdPW5ldyBOdCh7YXJyYXk6cixjb3VudDppLC4uLmx9KTtyZXR1cm4gdGhpc31zZXRWZWN0b3IodCxuLHIsaSl7cmV0dXJuIHRoaXMuYXR0cmlidXRlc1t0XS5zZXRWZWN0b3IobixyLGkpfWdldFZlY3Rvcih0LG4pe3JldHVybiB0aGlzLmF0dHJpYnV0ZXNbdF0uZ2V0VmVjdG9yKG4pfWdldFZlY3RvcnModCxuKXtyZXR1cm4gdC5tYXAocj0+dGhpcy5hdHRyaWJ1dGVzW3JdLmdldFZlY3RvcihuKSl9Z2V0QXR0cmlidXRlKHQpe3JldHVybiB0aGlzLmF0dHJpYnV0ZXNbdF19c2V0QXR0cmlidXRlKHQsbil7Y29uc3R7YXJyYXk6cixjb3VudDppfT10aGlzO3JldHVybiB0aGlzLmF0dHJpYnV0ZXNbdF09bmV3IE50KHthcnJheTpyLC4uLm4sY291bnQ6aX0pfWdldEFnZ3JlZ2F0ZVZlY3Rvcih0LG4pe2NvbnN0IHI9W107Zm9yKGNvbnN0IGkgb2YgdCl7Y29uc3Qgcz10aGlzLmdldFZlY3RvcihpLG4pO3IucHVzaCguLi5zKX1yZXR1cm4gcn1zZXRBZ2dyZWdhdGVWZWN0b3IodCxuLHIsaSl7aWYodC5sZW5ndGg9PT0xKXJldHVybiB0aGlzLnNldFZlY3Rvcih0WzBdLG4scixpKTtmb3IoY29uc3QgcyBvZiB0KWk9dGhpcy5zZXRWZWN0b3IocyxuLHIsaSk7cmV0dXJuIGl9Z2V0QWdncmVnYXRlVmVjdG9yU2l6ZSh0KXtpZih0Lmxlbmd0aD09PTEpcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKHRbMF0pLnZlY3RvclNpemU7bGV0IG49MDtmb3IoY29uc3QgciBvZiB0KW4rPXRoaXMuZ2V0QXR0cmlidXRlKHIpLnZlY3RvclNpemU7cmV0dXJuIG59Y3JlYXRlQWdncmVnYXRlVmVjdG9yR2V0dGVyKHQpe2lmKHQubGVuZ3RoPT09MSl7Y29uc3Qgbj10aGlzLmF0dHJpYnV0ZXNbdFswXV07cmV0dXJuIG4uZ2V0VmVjdG9yLmJpbmQobil9cmV0dXJuIHRoaXMuZ2V0QWdncmVnYXRlVmVjdG9yLmJpbmQodGhpcyx0KX1jcmVhdGVBZ2dyZWdhdGVWZWN0b3JTZXR0ZXIodCl7aWYodC5sZW5ndGg9PT0xKXtjb25zdCBuPXRoaXMuYXR0cmlidXRlc1t0WzBdXTtyZXR1cm4gbi5zZXRWZWN0b3IuYmluZChuKX1yZXR1cm4gdGhpcy5zZXRBZ2dyZWdhdGVWZWN0b3IuYmluZCh0aGlzLHQpfW1hcCh0LG4scj1bXSl7Zm9yKGxldCBpPTA7aTx0aGlzLmNvdW50O2krKyl7Y29uc3Qgcz10aGlzLmdldFZlY3RvcnModCxpKTtyW2ldPW4ocyxpKX1yZXR1cm4gcn1tYXBGb3JBZ2dyZWdhdGUodCxuLHI9W10pe2ZvcihsZXQgaT0wO2k8dGhpcy5jb3VudDtpKyspe2NvbnN0IHM9dGhpcy5nZXRBZ2dyZWdhdGVWZWN0b3IodCxpKTtyW2ldPW4ocyxpKX1yZXR1cm4gcn1tYXBTZWxmKHQsbil7Zm9yKGxldCByPTA7cjx0aGlzLmNvdW50O3IrKyl7Y29uc3QgaT10aGlzLmdldFZlY3RvcnModCxyKSxzPW4oaSxyKTt0LmZvckVhY2goKG8sYyk9PnRoaXMuc2V0VmVjdG9yKG8scixzW2NdKSl9cmV0dXJuIHRoaXN9bWFwU2VsZkZvckFnZ3JlZ2F0ZSh0LG4pe2ZvcihsZXQgcj0wO3I8dGhpcy5jb3VudDtyKyspe2NvbnN0IGk9dGhpcy5nZXRBZ2dyZWdhdGVWZWN0b3IodCxyKSxzPW4oaSxyKTt0aGlzLnNldEFnZ3JlZ2F0ZVZlY3Rvcih0LHIscyl9cmV0dXJuIHRoaXN9ZmlsdGVyKHQsbixyPVtdKXtmb3IobGV0IGk9MDtpPHRoaXMuY291bnQ7aSsrKXtjb25zdCBzPXRoaXMuZ2V0VmVjdG9ycyh0LGkpO24ocyxpKSYmci5wdXNoKHMpfXJldHVybiByfWZpbHRlckZvckFnZ3JlZ2F0ZSh0LG4scj1bXSl7cmV0dXJuIHRoaXMuZmlsdGVyKHQsKGkscyk9Pm4oWnMoaSkscykscil9dHJhbnNmb3JtKHQsbil7Y29uc3Qgcj1yblswXTtuLmluY2x1ZGVzKCJub3JtYWwiKSYmKHQubGVuZ3RoPT09MTY/V24ocix0KTpucihyLHQpKTtmb3IoY29uc3QgaSBvZiBuKXtjb25zdCBzPXRoaXMuZ2V0QXR0cmlidXRlKGkpO3MmJihpPT09Im5vcm1hbCI/cy50cmFuc2Zvcm1Bc05vcm1hbChyKTpzLnRyYW5zZm9ybSh0KSl9cmV0dXJuIHRoaXN9dHJhbnNmb3JtRm9yQWdncmVnYXRlKHQsbil7Y29uc3Qgcj10aGlzLmdldEFnZ3JlZ2F0ZVZlY3RvclNpemUobiksaT11ZSh0Lmxlbmd0aCxyKTtyZXR1cm4gdGhpcy5tYXBTZWxmRm9yQWdncmVnYXRlKG4scz0+aShzLHMsdCkpLHRoaXN9fWNsYXNzIGFuIGV4dGVuZHMgWHN7c2V0T3B0aW9ucyh0KXtjb25zdHtpbmRpY2VzOm4sLi4ucn09dDtzdXBlci5zZXRPcHRpb25zKHIpO2NvbnN0IGk9bi5hcnJheT9uOnthcnJheTpufTtyZXR1cm4gdGhpcy5pbmRpY2VzPW5ldyBOdCh7Y291bnQ6aS5hcnJheS5sZW5ndGgvMyx2ZWN0b3JTaXplOjMsLi4uaX0pLHRoaXN9Z2V0RmFjZVZlY3Rvcih0LG4pe2NvbnN0IHI9dGhpcy5pbmRpY2VzLmdldFZlY3RvcihuKTtyZXR1cm4gQXJyYXkucHJvdG90eXBlLm1hcC5jYWxsKHIsaT0+dGhpcy5nZXRWZWN0b3IodCxpKSl9Z2V0RmFjZVZlY3RvcnModCxuKXtjb25zdCByPXRoaXMuaW5kaWNlcy5nZXRWZWN0b3Iobik7cmV0dXJuIEFycmF5LnByb3RvdHlwZS5tYXAuY2FsbChyLGk9PnRoaXMuZ2V0VmVjdG9ycyh0LGkpKX1nZXRGYWNlQWdncmVnYXRlVmVjdG9yKHQsbil7Y29uc3Qgcj10aGlzLmluZGljZXMuZ2V0VmVjdG9yKG4pO3JldHVybiBBcnJheS5wcm90b3R5cGUubWFwLmNhbGwocixpPT50aGlzLmdldEFnZ3JlZ2F0ZVZlY3Rvcih0LGkpKX1tYXBGYWNlKHQsbixyPVtdKXtyZXR1cm4gdGhpcy5pbmRpY2VzLm1hcCgoaSxzKT0+e2NvbnN0IG89QXJyYXkucHJvdG90eXBlLm1hcC5jYWxsKGksYz0+dGhpcy5nZXRWZWN0b3JzKHQsYykpO3JldHVybiBuKG8scyxpKX0scil9bWFwRmFjZUZvckFnZ3JlZ2F0ZSh0LG4scj1bXSl7cmV0dXJuIHRoaXMuaW5kaWNlcy5tYXAoKGkscyk9Pntjb25zdCBvPUFycmF5LnByb3RvdHlwZS5tYXAuY2FsbChpLGM9PnRoaXMuZ2V0QWdncmVnYXRlVmVjdG9yKHQsYykpO3JldHVybiBuKG8scyxpKX0scil9ZmlsdGVyRmFjZSh0LG4scj1bXSl7cmV0dXJuIHRoaXMuaW5kaWNlcy5maWx0ZXIoKGkscyk9Pntjb25zdCBvPUFycmF5LnByb3RvdHlwZS5tYXAuY2FsbChpLGM9PnRoaXMuZ2V0VmVjdG9ycyh0LGMpKTtyZXR1cm4gbihvLHMsaSl9LHIpfWZpbHRlckZhY2VGb3JBZ2dyZWdhdGUodCxuLHI9W10pe3JldHVybiB0aGlzLmluZGljZXMuZmlsdGVyKChpLHMpPT57Y29uc3Qgbz1BcnJheS5wcm90b3R5cGUubWFwLmNhbGwoaSxjPT50aGlzLmdldEFnZ3JlZ2F0ZVZlY3Rvcih0LGMpKTtyZXR1cm4gbihvLHMsaSl9LHIpfX1sZXQgZ3I9Y2xhc3MgZXh0ZW5kcyBOdHtjb25zdHJ1Y3Rvcih0KXtzdXBlcih0KSx0aGlzLmNvdW50PTJ9Z2V0IHN0YXJ0UG9pbnQoKXtyZXR1cm4gdGhpcy5nZXRWZWN0b3IoMCl9c2V0IHN0YXJ0UG9pbnQodCl7dGhpcy5zZXRWZWN0b3IoMCx0KX1nZXQgZW5kUG9pbnQoKXtyZXR1cm4gdGhpcy5nZXRWZWN0b3IoMSl9c2V0IGVuZFBvaW50KHQpe3RoaXMuc2V0VmVjdG9yKDAsdCl9Z2V0Q2VudGVyKHQpe3JldHVybiBDcyh0LHRoaXMuc3RhcnRQb2ludCx0aGlzLmVuZFBvaW50KSxjcih0LHQsLjUpfWRlbHRhKHQpe3JldHVybiBUdCh0LHRoaXMuZW5kUG9pbnQsdGhpcy5zdGFydFBvaW50KX1zcXVhcmVkTGVuZ3RoKCl7cmV0dXJuIE5zKHRoaXMuc3RhcnRQb2ludCx0aGlzLmVuZFBvaW50KX1sZW5ndGgoKXtyZXR1cm4gVnModGhpcy5zdGFydFBvaW50LHRoaXMuZW5kUG9pbnQpfWF0VCh0LG4pe2NvbnN0e3N0YXJ0UG9pbnQ6cixlbmRQb2ludDppfT10aGlzO3JldHVybiBUdChuLGksciksYXIobixyLG4sdCl9Y2xvc2VzdFBvaW50VG9Qb2ludFBhcmFtZXRlcih0LG4pe2NvbnN0e3N0YXJ0UG9pbnQ6cixlbmRQb2ludDppfT10aGlzLHM9VHQoW10sdCxyKSxvPVR0KFtdLGksciksYz1vbihvLG8pO2xldCBoPW9uKG8scykvYztyZXR1cm4gbiYmKGg9Q3QoaCwwLDEpKSxofWNsb3Nlc3RQb2ludFRvUG9pbnQodCxuLHI9W10pe2NvbnN0IGk9dGhpcy5jbG9zZXN0UG9pbnRUb1BvaW50UGFyYW1ldGVyKHQsbik7cmV0dXJuIGFyKHIsdGhpcy5zdGFydFBvaW50LHRoaXMuZGVsdGEociksaSl9fTtjbGFzcyBqcyBleHRlbmRzIE50e2dldCBzdGFydFBvaW50KCl7cmV0dXJuIHRoaXMuZ2V0VmVjdG9yKDApfXNldCBzdGFydFBvaW50KHQpe3RoaXMuc2V0VmVjdG9yKDAsdCl9Z2V0IGVuZFBvaW50KCl7cmV0dXJuIHRoaXMuZ2V0VmVjdG9yKDEpfXNldCBlbmRQb2ludCh0KXt0aGlzLnNldFZlY3RvcigwLHQpfWRlbHRhKHQpe3JldHVybiBUdCh0LHRoaXMuZW5kUG9pbnQsdGhpcy5zdGFydFBvaW50KX1nZXRMaW5lKHQpe2NvbnN0e2FycmF5Om4sc3RhcnQ6cixlbmQ6aSx2ZWN0b3JTaXplOnN9PXRoaXMsbz1yK3QqcztyZXR1cm4gbmV3IGdyKHthcnJheTpuLHN0YXJ0Om8sZW5kOmksdmVjdG9yU2l6ZTpzfSl9bGVuZ3RoKCl7cmV0dXJuIHRoaXMubGVuZ3RocygpLmF0KC0xKX1sZW5ndGhzKCl7Y29uc3R7YXJyYXk6dCxzdGFydDpuLGVuZDpyLHZlY3RvclNpemU6aX09dGhpcyxzPW5ldyBncih7YXJyYXk6dCxzdGFydDpuLHZlY3RvclNpemU6aX0pO2xldCBvPTA7Y29uc3QgYz1bMF0sbD1yLWk7Zm9yKGxldCBoPW47aDxsO2grPWkpcy5zdGFydD1oLG8rPXMubGVuZ3RoKCksYy5wdXNoKG8pO3JldHVybiBjfWxlbmd0aEluZm8oKXtjb25zdCB0PXRoaXMubGVuZ3RocygpLG49dC5hdCgtMSk7cmV0dXJue2xlbmd0aHM6dCxsZW5ndGg6bn19fWZ1bmN0aW9uIFFzKGUsdCl7Y29uc3Qgbj1uZXcganMoe2FycmF5OmUsdmVjdG9yU2l6ZTozfSkse2xlbmd0aDpyLGxlbmd0aHM6aX09bi5sZW5ndGhJbmZvKCkscz1Lcyh0LHIpO3JldHVybnt0aW1lczppLm1hcChjPT5jL3IqcyksZHVyYXRpb246cyxsZW5ndGhzOmksbGVuZ3RoOnJ9fWZ1bmN0aW9uIExmKGUpe2NvbnN0IHQ9UXMoZS5wb2ludHMsZSk7cmV0dXJuey4uLkpzKHsuLi5lLHRpbWVzOnQudGltZXN9KSwuLi50fX1mdW5jdGlvbiBLcyhlLHQpe2xldCBuPWUuZHVyYXRpb247aWYoIW4pe2NvbnN0IHI9ZS5zcGVlZDtpZihyPT1udWxsKXRocm93Iue8uuWwkemAiemhuSBkdXJhdGlvbiDmiJbogIUgc3BlZWQiO2lmKCF0KXRocm93Iue8uuWwkeWPguaVsCBsZW5ndGgiO249dC9yfXJldHVybiBufWZ1bmN0aW9uIEpzKGUpe2NvbnN0e3RhcmdldDp0LGZyYW1lOm4sdGltZXM6cixlbmFibGVVcDppLGZpeFVwOnMsaW5GcmFtZTpvfT1lLGM9ZS5wb3NpdGlvbj8/ITAsbD1lLnJvdGF0ZT8/ITAsaD1lLmRpcmVjdGlvbj8/ITEsZj1bXSx1PVtdLGQ9W10sZz1yLG09W10scD17cG9pbnRzOmYscG9pbnRUaW1lczp1LHJvdGF0ZXM6ZCxyb3RhdGVUaW1lczpnLHRhbmdlbnRzOm0sZGlyZWN0aW9uczpbXX07aWYoIShjfHxsKSlyZXR1cm4gcDtjb25zdCBNPW5ldyBOdCh7YXJyYXk6ZS5wb2ludHMsdmVjdG9yU2l6ZTozfSksQT1NLmNvdW50LHg9QS0xLFQ9ZS51cD9uZXcgUChlLnVwKS5ub3JtYWxpemUoKTpXcy5jbG9uZSgpLHY9bmV3IFA7aWYoZS5hbmNob3ImJnYuY29weShlLmFuY2hvciksbil7Y29uc3QgcT1uZXcgdHQobikuaW52ZXJ0KCk7TS50cmFuc2Zvcm0ocSksVC50cmFuc2Zvcm1Bc1ZlY3RvcihxKS5ub3JtYWxpemUoKX1jb25zdCB3PU0udG9WZWN0b3JzKCksUz1uZXcgUCh3WzFdKS5zdWJ0cmFjdCh3WzBdKS5ub3JtYWxpemUoKTtsZXQgYj1uZXcgUDtlLmZyb250P2IuY29weShlLmZyb250KS5ub3JtYWxpemUoKTpiPVM7Y29uc3QgST1lLnRhcmdldFVwP25ldyBQKGUudGFyZ2V0VXApLm5vcm1hbGl6ZSgpOlQuY2xvbmUoKSxFPW5ldyB0dCxWPVlzLmNsb25lKCksTj1uZXcgaXQ7dCYmKEUuY29weSh0KSxvJiZHbihBc1sxXSxFKS50cmFuc2Zvcm1Bc1BvaW50KHYsdikscnIoVixOLEUpLGw/cWkoRSxWKTppcihFLFYsTiksb3x8KGUuZnJvbnQmJkUudHJhbnNmb3JtQXNWZWN0b3IoYixiKSxlLnRhcmdldFVwJiZFLnRyYW5zZm9ybUFzVmVjdG9yKEksSSkpKTtjb25zdCB6PUUuY2xvbmUoKSxMPWUucGFyYWxsZWw/PyF2LmVxdWFscyhbMCwwLDBdKTtsZXQgSD1xPT57Y29uc3QgWj1uZXcgUCh3W3ErMV0pLnN1YnRyYWN0KHdbcV0pLm5vcm1hbGl6ZSgpO20ucHVzaChaKTtjb25zdCBldD1xLTEsbnQ9ZXQ8MCxDZT1udD9iOm1bZXRdLGh0PW5ldyBpdCgpLnJvdGF0aW9uVG8oQ2UsWik7aWYoIW50KXtjb25zdCBPdD1kW2V0XTtodC5tdWx0aXBseShPdCkubm9ybWFsaXplKCksb3IoaHQsT3QpfXJldHVybiBodH07aWYoaSl7Y29uc3QgcT1uZXcgUDtIPWZ1bmN0aW9uKFope2NvbnN0IGV0PW5ldyBQKHdbWisxXSkuc3VidHJhY3Qod1taXSkubm9ybWFsaXplKCk7bS5wdXNoKGV0KTtjb25zdCBudD1aLTEsQ2U9bnQ8MCxodD1uZXcgaXQsT3Q9W2V0LFRdO2lmKENlKXtjb25zdCBVdD1bYixJXTtzJiYoVXQucmV2ZXJzZSgpLE90LnJldmVyc2UoKSksaHIoe3RhbmdlbnQ6VXRbMF0sbm9ybWFsOlV0WzFdfSx7dGFuZ2VudDpPdFswXSxub3JtYWw6T3RbMV19LGh0KX1lbHNle2NvbnN0IFV0PWRbbnRdO0J0KHEsSSxVdCk7Y29uc3QgSnI9W21bbnRdLHFdO3MmJihKci5yZXZlcnNlKCksT3QucmV2ZXJzZSgpKSxocih7dGFuZ2VudDpKclswXSxub3JtYWw6SnJbMV19LHt0YW5nZW50Ok90WzBdLG5vcm1hbDpPdFsxXX0saHQpLGh0Lm11bHRpcGx5KFV0KSxvcihodCxVdCl9cmV0dXJuIGh0Lm5vcm1hbGl6ZSgpfX1mb3IobGV0IHE9MDtxPEE7cSsrKXtpZihsKWlmKHE8eCl7Y29uc3QgWj1IKHEpO2QucHVzaChaKSxpcihFLFYsWil9ZWxzZSBkLnB1c2goZFtxLTFdLmNsb25lKCkpLG0ucHVzaChtW3EtMV0uY2xvbmUoKSk7aWYoYyl7Y29uc3QgWj1yW3FdLGV0PW5ldyBQKHdbcV0pO2lmKEwpe2NvbnN0IENlPXoudHJhbnNmb3JtKHYsdi5jbG9uZSgpKSxodD1ldC5jbG9uZSgpLnN1YnRyYWN0KENlKTtmLnB1c2goaHQpLHUucHVzaChaKSx6LmNvcHkoRSl9Y29uc3QgbnQ9RS50cmFuc2Zvcm0odix2LmNsb25lKCkpO2V0LnN1YnRyYWN0KG50KSxmLnB1c2goZXQpLHUucHVzaChaKX19cmV0dXJuIGgmJihwLmRpcmVjdGlvbnM9ZC5tYXAocT0+QnQobmV3IFAoMCwwLDEpLGIscSkpKSxwfWZ1bmN0aW9uIFJmKGUpe2xldCB0O2NvbnN0IG49cj0+e2UociksdD1yZXF1ZXN0QW5pbWF0aW9uRnJhbWUobil9O3JldHVybiB0PXJlcXVlc3RBbmltYXRpb25GcmFtZShuKSwoKT0+e2NhbmNlbEFuaW1hdGlvbkZyYW1lKHQpfX1mdW5jdGlvbiBDZihlLHQpe2NvbnN0W24scl09ZSx7Y2VudGVyOmkscmFkaXVzOnN9PXQsW28sY109Y3Qobi5sZW5ndGgpO28uc3ViVmVjdG9ycyhyLG4pLGMuc3ViVmVjdG9ycyhpLG4pO2NvbnN0IGw9by5sZW5ndGhTcXVhcmVkKCksaD1vLmRvdChjKSoqMixmPWwqKGMubGVuZ3RoU3F1YXJlZCgpLXMqKjIpLHU9aC1mO3JldHVybiBrKHUsMCk/eS5UYW5nZW5jeTp1PDA/eS5EaXNzb2NpYXRpb246eS5JbnRlcnNlY3R9ZnVuY3Rpb24gR3QoZSx0KXtjb25zdFtuLHJdPWUse2NlbnRlcjppLHJhZGl1czpzfT10LFtvLGNdPWN0KG4ubGVuZ3RoKTtvLnN1YlZlY3RvcnMocixuKSxjLnN1YlZlY3RvcnMobixpKTtjb25zdCBsPW8ubGVuZ3RoU3F1YXJlZCgpLGg9MipvLmRvdChjKSxmPWMubGVuZ3RoU3F1YXJlZCgpLXMqKjIsdT1oKioyLTQqbCpmLGQ9ayh1LDApO2lmKCFkJiZ1PDApcmV0dXJuW107Y29uc3QgZz1sKjIsbT0taC9nO2lmKGQpcmV0dXJuW21dO2NvbnN0IHA9TWF0aC5zcXJ0KHUpL2csTT1tLXAsQT1tK3A7cmV0dXJuW00sQV19ZnVuY3Rpb24gVmYoZSx0KXtjb25zdFtuLHJdPWUsaT1jdChuLmxlbmd0aClbMl07cmV0dXJuIGkuc3ViVmVjdG9ycyhyLG4pLEd0KGUsdCkubWFwKG89PmkuY2xvbmUoKS5tdWx0aXBseUJ5U2NhbGFyKG8pLmFkZChuKSl9ZnVuY3Rpb24gSHMoZSx0KXtjb25zdCBuPUd0KGUsdCkscj1uLmxlbmd0aDtpZihyPT09MClyZXR1cm4geS5EaXNzb2NpYXRpb247bGV0IGk9MCxzPTAsbz0wO2Zvcihjb25zdCBsIG9mIG4payhsLDApfHxrKGwsMSk/bysrOmw+MT9zKys6bDwwJiZpKys7Y29uc3QgYz1pK3M7cmV0dXJuIHI9PT0xJiZjPT09MD95LlRhbmdlbmN5Omk9PT0xJiZzPT09MXx8bz09PTI/eS5Db250YWluOmk9PT0yfHxzPT09Mj95LkRpc3NvY2lhdGlvbjp5LkludGVyc2VjdH1mdW5jdGlvbiB0byhlLHQpe2NvbnN0W24scl09ZSxpPWN0KGVbMF0ubGVuZ3RoKVsyXTtpLnN1YlZlY3RvcnMocixuKTtjb25zdCBzPUd0KGUsdCksbz1bXTtmb3IoY29uc3QgYyBvZiBzKXtpZighayhjLDApJiZjPDB8fCFrKGMsMSkmJmM+MSljb250aW51ZTtjb25zdCBsPWkuY2xvbmUoKS5tdWx0aXBseUJ5U2NhbGFyKGMpLmFkZChuKTtvLnB1c2gobCl9cmV0dXJuIG99ZnVuY3Rpb24gTmYoZSx0KXtjb25zdCBuPUd0KGUsdCkscj1uLmxlbmd0aDtpZihyPT09MClyZXR1cm4geS5EaXNzb2NpYXRpb247bGV0IGk9MDtmb3IoY29uc3QgcyBvZiBuKXM8MCYmaSsrO3JldHVybiByPT09MSYmaT09PTA/eS5UYW5nZW5jeTppPT09Mj95LkRpc3NvY2lhdGlvbjp5LkludGVyc2VjdH1mdW5jdGlvbiB6ZihlLHQpe2NvbnN0W24scl09ZSxpPWN0KG4ubGVuZ3RoKVsyXTtpLnN1YlZlY3RvcnMocixuKTtjb25zdCBzPUd0KGUsdCksbz1bXTtmb3IoY29uc3QgYyBvZiBzKXtpZihjPDApY29udGludWU7Y29uc3QgbD1pLmNsb25lKCkubXVsdGlwbHlCeVNjYWxhcihjKS5hZGQobik7by5wdXNoKGwpfXJldHVybiBvfWZ1bmN0aW9uIHZ0KGUsdCl7Y29uc3Qgbj1qKFtdLGVbMV0sZVswXSkscj1qKFtdLHQsZVswXSk7cmV0dXJuIER0KG4sbixyKSxrKG5bMl0sMCk/MDpuWzJdfWZ1bmN0aW9uICRmKGUsdCl7Y29uc3Qgbj1bLi4uZVswXSwuLi5lWzFdLC4uLnRdO2xldCByPWZlKG4pO3JldHVybiBrKHIsMCk/KG5bMl0rPTEsbls1XSs9MSxuWzhdKz0xLHI9ZmUobiksayhyLDApPzA6cik6cn1mdW5jdGlvbiBrZihlLHQpe2NvbnN0W24scl09ZSxbaSxzXT1jdCh0Lmxlbmd0aCk7aWYoaS5zdWJWZWN0b3JzKHQsbikscy5zdWJWZWN0b3JzKHIsbiksc24ocyxpKSl7Y29uc3Qgbz1ZKHMsaSk7cmV0dXJuIG88MHx8bz4xP3kuVGFuZ2VuY3k6eS5Db250YWlufXJldHVybiB5LkRpc3NvY2lhdGlvbn1mdW5jdGlvbiBlbyhlLHQpe2NvbnN0W24scl09ZSxbaSxzXT1ndDtpZihpLnN1YlZlY3RvcnModCxuKSxzLnN1YlZlY3RvcnMocixuKSxicyhzLGkpKXtjb25zdCBvPVkocyxpKTtyZXR1cm4gbzwwfHxvPjE/eS5UYW5nZW5jeTp5LkNvbnRhaW59cmV0dXJuIHkuRGlzc29jaWF0aW9ufWZ1bmN0aW9uIGxuKGUsdCl7Y29uc3RbbixyXT1lLFtpLHNdPXQsW28sYyxsXT1jdChuLmxlbmd0aCk7cmV0dXJuIGMuc3ViVmVjdG9ycyhyLG4pLGwuc3ViVmVjdG9ycyhzLGkpLHNuKGwsYyk/KG8uc3ViVmVjdG9ycyhpLG4pLHNuKG8sYyk/eS5UYW5nZW5jeTp5LkRpc3NvY2lhdGlvbik6eS5JbnRlcnNlY3R9ZnVuY3Rpb24gcGUoZSx0LG4pe2NvbnN0W3IsaV09dCxbcyxvXT1uLFtjLGwsaF09Y3Qoci5sZW5ndGgpO2Muc3ViVmVjdG9ycyhpLHIpLGwuc3ViVmVjdG9ycyhvLHMpO2NvbnN0IGY9VShyLmxlbmd0aCksdT1mLmNyb3NzKFtdLGMsbCk7aWYoayhmLnNxdWFyZWRMZW5ndGgodSksMCkpcmV0dXJuIG51bGw7aC5zdWJWZWN0b3JzKHMscik7Y29uc3QgZD1mLmNyb3NzKFtdLGgsbCksZz1ZKHUsZCk7cmV0dXJuIGYuc2NhbGVBbmRBZGQoZSxyLGMsZyl9ZnVuY3Rpb24gaG4oZSx0LG4pe2NvbnN0W3IsaV09dCxbcyxvXT1uLFtjLGwsaF09Z3Q7Yy5zdWJWZWN0b3JzKGksciksbC5zdWJWZWN0b3JzKG8scyk7Y29uc3QgZj1EdChbXSxjLGwpWzJdO2lmKGsoZiwwKSlyZXR1cm4gbnVsbDtoLnN1YlZlY3RvcnMocyxyKTtjb25zdCBkPUR0KFtdLGgsbClbMl0vZjtyZXR1cm4gbGkoZSxyLGMsZCl9ZnVuY3Rpb24gRmYoZSx0KXtjb25zdFtuLHJdPXQsW2ksc109ZSxvPVUobi5sZW5ndGgpLGM9by5zdWJ0cmFjdChbXSxzLGkpLGw9bG4oZSx0KTtpZihsPT09eS5UYW5nZW5jeSl7bGV0IGc9MDtyZXR1cm4gWShjLG8uc3VidHJhY3QoW10sbixpKSk8MCYmZysrLFkoYyxvLnN1YnRyYWN0KFtdLHIsaSkpPDAmJmcrKyxnPT09Mj95LkRpc3NvY2lhdGlvbjpnPT09MD95LkNvbnRhaW46eS5UYW5nZW5jeX1pZihsIT09eS5JbnRlcnNlY3QpcmV0dXJuIGw7Y29uc3QgaD1wZShbXSxlLHQpLGY9by5zdWJ0cmFjdChbXSxyLG4pLHU9WShmLG8uc3VidHJhY3QoW10saCxuKSk7cmV0dXJuIHU8MHx8dT4xfHxZKGMsby5zdWJ0cmFjdChbXSxoLGkpKTwwP3kuRGlzc29jaWF0aW9uOnkuSW50ZXJzZWN0fWZ1bmN0aW9uIG5vKGUsdCl7Y29uc3RbbixyXT10LFtpLHNdPWUsbz1qKFtdLHMsaSksYz1sbihlLHQpO2lmKGM9PT15LlRhbmdlbmN5KXtsZXQgZD0wO3JldHVybiBZKG8saihbXSxuLGkpKTwwJiZkKyssWShvLGooW10scixpKSk8MCYmZCsrLGQ9PT0yP3kuRGlzc29jaWF0aW9uOmQ9PT0wP3kuQ29udGFpbjp5LlRhbmdlbmN5fWlmKGMhPT15LkludGVyc2VjdClyZXR1cm4gYztjb25zdCBsPWhuKFtdLGUsdCksaD1qKFtdLHIsbiksZj1ZKGgsaihbXSxsLG4pKTtyZXR1cm4gZjwwfHxmPjF8fFkobyxqKFtdLGwsaSkpPDA/eS5EaXNzb2NpYXRpb246eS5JbnRlcnNlY3R9ZnVuY3Rpb24gcWYoZSx0LG4pe2NvbnN0IHI9cGUoZSx0LG4pO2lmKHI9PT1udWxsKXJldHVybiBudWxsO2NvbnN0W2ksc109bixvPVUoaS5sZW5ndGgpLGM9by5zdWJ0cmFjdChbXSxzLGkpLGw9WShjLG8uc3VidHJhY3QoW10scixpKSk7aWYobDwwfHxsPjEpcmV0dXJuIG51bGw7Y29uc3RbaCxmXT10LHU9by5zdWJ0cmFjdChbXSxmLGgpO3JldHVybiBZKHUsby5zdWJ0cmFjdChbXSxyLGgpKTwwP251bGw6cn1mdW5jdGlvbiBVZihlLHQsbil7Y29uc3Qgcj1obihlLHQsbik7aWYocj09PW51bGwpcmV0dXJuIG51bGw7Y29uc3RbaSxzXT1uLG89aihbXSxzLGkpLGM9WShvLGooW10scixpKSk7aWYoYzwwfHxjPjEpcmV0dXJuIG51bGw7Y29uc3RbbCxoXT10LGY9aihbXSxoLGwpO3JldHVybiBZKGYsaihbXSxyLGwpKTwwP251bGw6cn1mdW5jdGlvbiBtcihlLHQpe2NvbnN0W24scl09ZSxbaSxzXT10LG89VShuLmxlbmd0aCksYz1vLnN1YnRyYWN0KFtdLHIsbiksbD1sbihlLHQpO2lmKGw9PT15LlRhbmdlbmN5KXtsZXQgZz0wLG09MDtjb25zdCBfPVkoYyxvLnN1YnRyYWN0KFtdLGksbikpO188MD9nKys6Xz4xJiZtKys7Y29uc3QgcD1ZKGMsby5zdWJ0cmFjdChbXSxzLG4pKTtyZXR1cm4gcDwwP2crKzpwPjEmJm0rKyxnPT09Mnx8bT09PTI/eS5EaXNzb2NpYXRpb246ZyttPT09MT95LlRhbmdlbmN5OnkuQ29udGFpbn1pZihsIT09eS5JbnRlcnNlY3QpcmV0dXJuIGw7Y29uc3QgaD1wZShbXSxlLHQpLGY9by5zdWJ0cmFjdChbXSxzLGkpLHU9WShmLG8uc3VidHJhY3QoW10saCxpKSk7aWYodTwwfHx1PjEpcmV0dXJuIHkuRGlzc29jaWF0aW9uO2lmKHU9PT0wfHx1PT09MSlyZXR1cm4geS5Kb2ludEludGVyc2VjdDtjb25zdCBkPVkoYyxvLnN1YnRyYWN0KFtdLGgsbikpO3JldHVybiBkPDB8fGQ+MT95LkRpc3NvY2lhdGlvbjpkPT09MHx8ZD09PTE/eS5Kb2ludEludGVyc2VjdDp5LlRocm91Z2hJbnRlcnNlY3R9ZnVuY3Rpb24gRGYoZSx0LG4pe2NvbnN0IHI9cGUoZSx0LG4pO2lmKHI9PT1udWxsKXJldHVybiBudWxsO2NvbnN0W2ksc109bixvPVUoaS5sZW5ndGgpLGM9by5zdWJ0cmFjdChbXSxzLGkpLGw9WShjLG8uc3VidHJhY3QoW10scixpKSk7aWYobDwwfHxsPjEpcmV0dXJuIG51bGw7Y29uc3RbaCxmXT10LHU9by5zdWJ0cmFjdChbXSxmLGgpLGQ9WSh1LG8uc3VidHJhY3QoW10scixoKSk7cmV0dXJuIGQ8MHx8ZD4xP251bGw6cn1mdW5jdGlvbiBCZihlLHQsbil7Y29uc3Qgcj1obihlLHQsbik7aWYocj09PW51bGwpcmV0dXJuIG51bGw7Y29uc3RbaSxzXT1uLG89aihbXSxzLGkpLGM9WShvLGooW10scixpKSk7aWYoYzwwfHxjPjEpcmV0dXJuIG51bGw7Y29uc3RbbCxoXT10LGY9aihbXSxoLGwpLHU9WShmLGooW10scixsKSk7cmV0dXJuIHU8MHx8dT4xP251bGw6cn1mdW5jdGlvbiBZZihlKXtjb25zdCB0PVtdO2ZvcihsZXQgcj0wO3I8ZS5sZW5ndGg7cisrKXtjb25zdCBpPWVbcl07dC5wdXNoKFtpWzBdLCEwLHJdLFtpWzFdLCExLHJdKX1sZXQgbj0hMTt0LnNvcnQoKHIsaSk9PntsZXQgcz1yWzBdLWlbMF07cmV0dXJuIHMhPT0wfHwocz1yWzJdLWlbMl0scyE9PTAmJihuPSEwKSksc30pO2ZvcihsZXQgcj0wO3I8dC5sZW5ndGg7cis9Mil7Y29uc3QgaT10W3JdLHM9dFtyKzFdO2lmKGlbMV09PT1zWzFdKXJldHVybiB5LlRocm91Z2hJbnRlcnNlY3R9cmV0dXJuIG4/eS5Kb2ludEludGVyc2VjdDp5LkRpc3NvY2lhdGlvbn1mdW5jdGlvbiBybyhlKXtjb25zdCB0PWUubGVuZ3RoO2lmKHQ8MylyZXR1cm4gZTtsZXQgbj1lWzBdWzFdLHI9WzBdO2ZvcihsZXQgbz0xO288dDtvKyspe2NvbnN0IGM9ZVtvXVsxXTtjPG4/KG49YyxyPVtvXSk6Yz09PW4mJnIucHVzaChvKX1sZXQgaT1yWzBdO2lmKHIubGVuZ3RoPjEpe249ZVtyWzBdXVswXTtmb3IobGV0IG89MTtvPHIubGVuZ3RoO28rKyl7Y29uc3QgYz1yW29dLGw9ZVtjXVswXTtsPG4mJihuPWwsaT1jKX19Y29uc3Qgcz1lLnNwbGljZShpLDEpWzBdO3JldHVybiBlLnNvcnQoKG8sYyk9PnZ0KFtzLGNdLG8pKSxlLnVuc2hpZnQocyksZX1mdW5jdGlvbiBpbyhlKXtjb25zdCB0PWUuc2xpY2UoMCwyKTt0OmZvcihsZXQgbj0yO248ZS5sZW5ndGg7bisrKXtsZXQgcj10LmF0KC0yKSxpPXQuYXQoLTEpO2NvbnN0IHM9ZVtuXTtsZXQgbz12dChbcixpXSxzKTtmb3IoO288PTA7KXtpZihvPT09MCl7RmUocixzKT5GZShyLGkpJiYodFt0Lmxlbmd0aC0xXT1zKTtjb250aW51ZSB0fXQucG9wKCksaT1yLHI9dC5hdCgtMiksbz12dChbcixpXSxzKX10LnB1c2gocyl9cmV0dXJuIHR9ZnVuY3Rpb24gV2YoZSl7cmV0dXJuIGlvKHJvKGUpKX1mdW5jdGlvbiBzbyhlKXtjb25zdCB0PWUubGVuZ3RoO2lmKHQ8NClyZXR1cm4hMDtsZXQgbj0wO2ZvcihsZXQgcj0wO3I8dDtyKyspe2NvbnN0IGk9ZS5hdChyLTEpLHM9ZS5hdCgocisxKSV0KSxvPXZ0KFtpLGVbcl1dLHMpO2lmKG8hPT0wKXtpZihuKm88MClyZXR1cm4hMTtuPW99fXJldHVybiEwfWZ1bmN0aW9uIFpmKGUpe2NvbnN0IHQ9ZS5sZW5ndGg7aWYodDw0KXJldHVybi0xO2xldCBuPTA7Zm9yKGxldCByPTA7cjx0O3IrKyl7Y29uc3QgaT1lLmF0KHItMSkscz1lLmF0KChyKzEpJXQpLG89dnQoW2ksZVtyXV0scyk7aWYobyE9PTApe2lmKG4qbzwwKXJldHVybiByO249b319cmV0dXJuLTF9ZnVuY3Rpb24gRXQoZSx0KXtsZXQgbj0wLHI9ITE7Zm9yKGxldCBpPTA7aTxlLmxlbmd0aDtpKyspe2NvbnN0IHM9ZS5hdChpLTEpO2lmKHFlKHMsdCkpcmV0dXJuIHkuVGFuZ2VuY3k7Y29uc3Qgbz12dChbcyxlW2ldXSx0KTtpZihvPT09MCl7cj0hMDtjb250aW51ZX1pZihuKm88MClyZXR1cm4geS5EaXNzb2NpYXRpb247bj1vfXJldHVybiByP3kuVGFuZ2VuY3k6eS5Db250YWlufWZ1bmN0aW9uIEdmKGUsdCl7Y29uc3Qgbj1lLmxlbmd0aDtsZXQgcj1bXTtjb25zdCBpPVtdO2ZvcihsZXQgcz0wO3M8bjtzKyspe2NvbnN0IG89cy0xLGM9ZS5hdChvKTtpZihxZShjLHQpKXtpLnB1c2gobyk7YnJlYWt9Y29uc3QgbD1vLTEsaD12dChbdCxjXSxlLmF0KGwpKSxmPXZ0KFt0LGNdLGUuYXQocykpLHU9aCpmO2lmKCEodTwwKSl7aWYodT4wKXtpZihpLnB1c2gobyksaS5sZW5ndGg9PT0yKWJyZWFrO2NvbnRpbnVlfWg9PT0wJiZyLnB1c2gobCxvKSxmPT09MCYmci5wdXNoKG8scyl9fXJldHVybiBpLnB1c2goLi4uciksaS5tYXAocz0+czwwP3MrbjpzKX1mdW5jdGlvbiBwdChlLHQpe2NvbnN0IG49W3QsWzEwLDBdXTtvaShuWzFdLHQsblsxXSk7Y29uc3Qgcj1lLmxlbmd0aDtsZXQgaT0wO2ZvcihsZXQgcz0wO3M8cjtzKyspe2NvbnN0IG89ZVtzXTtpZihxZShvLHQpKXJldHVybiB5LlRhbmdlbmN5O2xldCBjPXMrMTtjPT09ciYmKGM9MCk7Y29uc3QgbD1lW2NdLGg9W28sbF07aWYoZW8oaCx0KT09PXkuQ29udGFpbilyZXR1cm4geS5UYW5nZW5jeTtjb25zdCB1PW5vKG4saCk7aWYodT09PXkuQ29udGFpbil7aSs9Mjtjb250aW51ZX1pZih1PT09eS5JbnRlcnNlY3Qpe2xldCBkPTA7b1sxXT50WzFdJiZkKyssbFsxXT50WzFdJiZkKyssZD09PTEmJmkrK319cmV0dXJuIGklMj09PTA/eS5EaXNzb2NpYXRpb246eS5Db250YWlufWZ1bmN0aW9uIHByKGUsdCl7Y29uc3Qgbj1lLmxlbmd0aDtsZXQgcj0wO2ZvcihsZXQgYz0wO2M8bjtjKyspe2NvbnN0IGw9ZVtjXTtsZXQgaD1jKzE7aD09PW4mJihoPTApO2NvbnN0IGY9ZVtoXSxkPW1yKFtsLGZdLHQpO2lmKGQmKHkuVGhyb3VnaEludGVyc2VjdHx5LlRhbmdlbmN5fHkuQ29udGFpbikpcmV0dXJuIGQ7ZD09PXkuSm9pbnRJbnRlcnNlY3QmJnIrK31jb25zdCBpPUV0KGUsdFswXSk7aWYocj09PTB8fHI9PT0xJiZpIT09eS5UYW5nZW5jeSlyZXR1cm4gaTtjb25zdCBzPUV0KGUsdFsxXSksbz1pfHM7cmV0dXJuIG89PT15LlRhbmdlbmN5P3kuQ29udGFpbjpvJnkuVGFuZ2VuY3k/byZ5LkNvbnRhaW4/eS5Db250YWluOnkuSm9pbnRJbnRlcnNlY3Q6aX1mdW5jdGlvbiBvbyhlLHQpe2NvbnN0IG49ZS5sZW5ndGg7bGV0IHI9MCxpPSExO2ZvcihsZXQgbD0wO2w8bjtsKyspe2NvbnN0IGg9ZVtsXTtsZXQgZj1sKzE7Zj09PW4mJihmPTApO2NvbnN0IHU9ZVtmXSxnPW1yKFtoLHVdLHQpO2lmKGc9PT15LlRocm91Z2hJbnRlcnNlY3QpcmV0dXJuIGc7Zz09PXkuSm9pbnRJbnRlcnNlY3Q/cisrOmc9PT15LkNvbnRhaW4mJihpPSEwKX1jb25zdCBzPXB0KGUsdFswXSksbz1wdChlLHRbMV0pLGM9c3xvO2lmKGkpcmV0dXJuIGMmeS5Db250YWluP3kuVGhyb3VnaEludGVyc2VjdDp5LlRhbmdlbmN5O2lmKHI9PT0xKXJldHVybiBjJnkuQ29udGFpbj95LkNvbnRhaW46eS5Kb2ludEludGVyc2VjdDtpZihyPjIpe2NvbnN0IGw9ZGkoW10sdFswXSx0WzFdLC41KTtyZXR1cm4gcHQoZSxsKT09PXkuQ29udGFpbj95LkNvbnRhaW46eS5Kb2ludEludGVyc2VjdH1yZXR1cm4gc31mdW5jdGlvbiBYZihlLHQpe2NvbnN0IG49ZS5sZW5ndGg7bGV0IHI9MCxpPTA7Zm9yKGxldCBsPTA7bDxuO2wrKyl7Y29uc3QgaD1lW2xdO2xldCBmPWwrMTtmPT09biYmKGY9MCk7Y29uc3QgdT1lW2ZdLGc9SHMoW2gsdV0sdCk7aWYoZz09PXkuSW50ZXJzZWN0KXJldHVybiB5LkludGVyc2VjdDtnPT09eS5Db250YWluP3IrKzpnPT09eS5UYW5nZW5jeSYmaSsrfWlmKHI9PT1uKXJldHVybiB5LkJBQ29udGFpbjtpZihyPjApcmV0dXJuIHkuSW50ZXJzZWN0O2NvbnN0e2NlbnRlcjpzLHJhZGl1czpvfT10O2xldCBjPXB0KGUscyk7cmV0dXJuIGM9PT15LkNvbnRhaW4/eS5BQkNvbnRhaW46bz09PTA/YzppPjA/eS5UYW5nZW5jeTp5LkRpc3NvY2lhdGlvbn1mdW5jdGlvbiBqZihlLHQpe2NvbnN0IG49ZS5sZW5ndGg7bGV0IHI9W107Zm9yKGxldCBpPTA7aTxuO2krKyl7Y29uc3Qgcz1lW2ldO2xldCBvPWkrMTtvPT09biYmKG89MCk7Y29uc3QgYz1lW29dLGg9dG8oW3MsY10sdCk7cj1bLi4uciwuLi5oXX1yZXR1cm4gcn1mdW5jdGlvbiBjbyhlLHQpe2NvbnN0IG49ZS5sZW5ndGg7bGV0IHI9MCxpPSExO2ZvcihsZXQgbD0wO2w8bjtsKyspe2NvbnN0IGg9ZVtsXTtsZXQgZj1sKzE7Zj09PW4mJihmPTApO2NvbnN0IHU9ZVtmXSxnPXByKHQsW2gsdV0pO2lmKGc9PT15LlRocm91Z2hJbnRlcnNlY3QpcmV0dXJuIGc7Zz09PXkuSm9pbnRJbnRlcnNlY3Q/cisrOmc9PT15LlRhbmdlbmN5JiYoaT0hMCl9bGV0IHM9MDtpP3N8PXkuVGFuZ2VuY3k6ciYmKHN8PXkuSm9pbnRJbnRlcnNlY3QpO2xldCBvPWUuc29tZShsPT5FdCh0LGwpPT09eS5Db250YWluKTtyZXR1cm4gbz95LkJBQ29udGFpbnxzOihvPXQuc29tZShsPT5wdChlLGwpPT09eS5Db250YWluKSxvP3kuQUJDb250YWlufHM6ZS5zb21lKGw9PkV0KHQsbCk9PT15LkRpc3NvY2lhdGlvbik/eS5EaXNzb2NpYXRpb258czpzKX1mdW5jdGlvbiBhbyhlLHQpe2NvbnN0IG49ZS5sZW5ndGg7bGV0IHI9MCxpPSExO2ZvcihsZXQgbD0wO2w8bjtsKyspe2NvbnN0IGg9ZVtsXTtsZXQgZj1sKzE7Zj09PW4mJihmPTApO2NvbnN0IHU9ZVtmXSxnPXByKHQsW2gsdV0pO2lmKGc9PT15LlRocm91Z2hJbnRlcnNlY3QpcmV0dXJuIGc7Zz09PXkuSm9pbnRJbnRlcnNlY3Q/cisrOmc9PT15LlRhbmdlbmN5JiYoaT0hMCl9bGV0IHM9MDtpP3N8PXkuVGFuZ2VuY3k6ciYmKHN8PXkuSm9pbnRJbnRlcnNlY3QpO2xldCBvPWUuc29tZShsPT5FdCh0LGwpPT09eS5Db250YWluKTtyZXR1cm4gbz95LkJBQ29udGFpbnxzOihvPXQuc29tZShsPT5FdChlLGwpPT09eS5Db250YWluKSxvP3kuQUJDb250YWlufHM6ZS5zb21lKGw9PkV0KHQsbCk9PT15LkRpc3NvY2lhdGlvbik/eS5EaXNzb2NpYXRpb258czpzKX1mdW5jdGlvbiBRZihlLHQpe2NvbnN0IG49ZS5sZW5ndGg7bGV0IHI9MCxpPSExO2ZvcihsZXQgbD0wO2w8bjtsKyspe2NvbnN0IGg9ZVtsXTtsZXQgZj1sKzE7Zj09PW4mJihmPTApO2NvbnN0IHU9ZVtmXSxnPW9vKHQsW2gsdV0pO2lmKGc9PT15LlRocm91Z2hJbnRlcnNlY3QpcmV0dXJuIGc7Zz09PXkuSm9pbnRJbnRlcnNlY3Q/cisrOmc9PT15LlRhbmdlbmN5JiYoaT0hMCl9bGV0IHM9MDtpP3N8PXkuVGFuZ2VuY3k6ciYmKHN8PXkuSm9pbnRJbnRlcnNlY3QpO2xldCBvPWUuc29tZShsPT5wdCh0LGwpPT09eS5Db250YWluKTtyZXR1cm4gbz95LkJBQ29udGFpbnxzOihvPXQuc29tZShsPT5wdChlLGwpPT09eS5Db250YWluKSxvP3kuQUJDb250YWlufHM6ZS5zb21lKGw9PnB0KHQsbCk9PT15LkRpc3NvY2lhdGlvbik/eS5EaXNzb2NpYXRpb258czpzKX1mdW5jdGlvbiBLZihlLHQsbil7Zm9yKGxldCByPTA7cjxuLmxlbmd0aDtyKyspe2NvbnN0IGk9bltyXTtlPV9yKGUsdCxyLGkpLGU9X3IoZSx0LHIsLWkpfXJldHVybiBlfWZ1bmN0aW9uIF9yKGUsdCxuLHIsaSl7Y29uc3Qgcz1lLmxlbmd0aDtpZighaSl7aT1bXTtmb3IobGV0IGw9MDtsPHM7bCsrKWlbbF09W119Y29uc3Qgbz1lWzBdLmxlbmd0aC90LGM9ZS5tYXAobD0+bC5sZW5ndGgvb3wwKTtmb3IobGV0IGw9MDtsPG87bCs9Myl7Y29uc3QgaD1bXSxmPVtdLHU9W107Zm9yKGxldCB3PTA7dzxzO3crKyl7Y29uc3QgUz1lW3ddLGI9Y1t3XTtsZXQgST1sKmIsRT1JK2I7aFt3XT1TLnNsaWNlKEksRSksST1FLEUrPWIsZlt3XT1TLnNsaWNlKEksRSksST1FLEUrPWIsdVt3XT1TLnNsaWNlKEksRSl9Y29uc3QgZD1oWzBdW25dLXIsZz1mWzBdW25dLXIsbT11WzBdW25dLXI7bGV0IF89ZD4wLHA9Zz4wLE09bT4wO3I8MCYmKF89IV8scD0hcCxNPSFNKTtsZXQgQSx4LFQsdjtzd2l0Y2goXytwK00pe2Nhc2UgMDp7Zm9yKGxldCB3PTA7dzxzO3crKylpW3ddLnB1c2goLi4uaFt3XSwuLi5mW3ddLC4uLnVbd10pO2JyZWFrfWNhc2UgMTp7Xz8oQT1mLHg9dSxUPXN0KHUsaCxuLHIpLHY9c3QoZixoLG4scikpOnA/KEE9dSx4PWgsVD1zdChoLGYsbixyKSx2PXN0KHUsZixuLHIpKTooQT1oLHg9ZixUPXN0KGYsdSxuLHIpLHY9c3QoaCx1LG4scikpO2ZvcihsZXQgdz0wO3c8czt3KyspaVt3XS5wdXNoKC4uLkFbd10sLi4ueFt3XSwuLi5UW3ddKSxpW3ddLnB1c2goLi4uVFt3XSwuLi52W3ddLC4uLkFbd10pO2JyZWFrfWNhc2UgMjp7Xz9wPyhBPXUseD1zdChoLHUsbixyKSxUPXN0KGYsdSxuLHIpKTooQT1mLHg9c3QodSxmLG4sciksVD1zdChoLGYsbixyKSk6KEE9aCx4PXN0KGYsaCxuLHIpLFQ9c3QodSxoLG4scikpO2ZvcihsZXQgdz0wO3c8czt3KyspaVt3XS5wdXNoKC4uLkFbd10sLi4ueFt3XSwuLi5UW3ddKTticmVha319fXJldHVybiBpfWZ1bmN0aW9uIHN0KGUsdCxuLHIsaT1bXSl7Y29uc3Qgcz1lWzBdLG89dFswXSxjPXNbbl0sbD1NYXRoLmFicygoci1jKS8ob1tuXS1jKSk7Zm9yKGxldCBoPTA7aDxlLmxlbmd0aDtoKyspe2NvbnN0IGY9ZVtoXSx1PXRbaF0sZD1pW2hdfHwoaVtoXT1bXSk7Zm9yKGxldCBnPTA7ZzxmLmxlbmd0aDtnKyspZFtnXT1sKih1W2ddLWZbZ10pK2ZbZ119cmV0dXJuIGl9ZnVuY3Rpb24gSmYoZSx0KXtjb25zdCBuPWUubGVuZ3RoL3R8MDtmb3IobGV0IHI9MDtyPHQ7cisrKXtjb25zdCBpPXIqbixzPWUuc2xpY2UoaSxpK24pO2xldCBvPU1hdGguaHlwb3QoLi4ucyk7bz1rKG8sMCk/MToxL287Zm9yKGxldCBjPTA7YzxuO2MrKyllW2krY10qPW99cmV0dXJuIGV9ZnVuY3Rpb24gbG8oZSx0LG49WyJwb3NpdGlvbiJdKXtyZXR1cm4gZS5tYXBGb3JBZ2dyZWdhdGUobixyPT5wdCh0LHIpKX1mdW5jdGlvbiBobyhlLHQsbj1bInBvc2l0aW9uIl0pe3JldHVybiBlLm1hcEZvckFnZ3JlZ2F0ZShuLHI9PkV0KHQscikpfWZ1bmN0aW9uIEhmKGUsdCl7cmV0dXJuIGUuaW5kaWNlcy5tYXAobj0+e2xldCByPTA7Zm9yKGNvbnN0IGkgb2YgbilyfD10W2ldO3JldHVybiByfSl9ZnVuY3Rpb24gZm8oZSx0LG49WyJwb3NpdGlvbiJdLHIsaSl7Y29uc3Qgcz1pP2FvOmNvO3JldHVybiByP3IubWFwKGZ1bmN0aW9uKG8sYyl7Y29uc3QgbD1nbyhvKTtpZihsIT09bnVsbClyZXR1cm4gbCZ5LkNvbnRhaW4/bHx5LkFCOmw7Y29uc3QgaD1lLmluZGljZXMuZ2V0VmVjdG9yKGMpLGY9QXJyYXkucHJvdG90eXBlLm1hcC5jYWxsKGgsdT0+ZS5nZXRBZ2dyZWdhdGVWZWN0b3Iobix1KSk7cmV0dXJuIHModCxmKX0pOmUubWFwRmFjZShuLG89PnModCxvKSl9Y29uc3QgdW89eS5EaXNzb2NpYXRpb258eS5Db250YWluO2Z1bmN0aW9uIGdvKGUpe3JldHVybihlJnVvKT09PXVvP3kuVGhyb3VnaEludGVyc2VjdDplJnkuQ29udGFpbj9lJnkuVGFuZ2VuY3k/eS5Db250YWlufHkuSm9pbnRJbnRlcnNlY3Q6eS5Db250YWluOm51bGx9ZnVuY3Rpb24gbW8oZSx0LG4pe2NvbnN0IHI9ZGUuZ2V0RXF1YWxGdW4obiksaT1bXTtyZXR1cm4gZS5mb3JFYWNoKChzLG8pPT57cih0LHMpJiZpLnB1c2gobyl9KSxpfWNvbnN0IHlyPTEvMzI3Njc7ZnVuY3Rpb24geHIoZSx0KXtjb25zdFtuLHIsaV09TXIoZSx0KTtyZXR1cm5bbiwwLDAsMCwwLHIsMCwwLDAsMCxpLDAsZS53ZXN0LGUuc291dGgsdFswXSwxXX1mdW5jdGlvbiBNcihlLHQpe2NvbnN0IG49KGUuZWFzdC1lLndlc3QpKnlyLHI9KGUubm9ydGgtZS5zb3V0aCkqeXIsaT0odFsxXS10WzFdKSp5cjtyZXR1cm5bbixyLGldfWZ1bmN0aW9uIHR1KGUsdCl7Y29uc3Qgbj1NcihlLHQpLHt3ZXN0OnIsc291dGg6aX09ZSxbc109dDtyZXR1cm4gZnVuY3Rpb24oYyxsPVtdKXskbihsLGMsbikseWkobCxsLFtyLGksc10pfX1mdW5jdGlvbiBldShlKXtyZXR1cm4gcG8oZSkvMn1mdW5jdGlvbiBwbyhlKXtsZXQgdD0wO2ZvcihsZXQgbj0wO248ZS5sZW5ndGg7bisrKXtjb25zdCByPWUuYXQobi0xKTt0Kz1XdChyLGVbbl0pfXJldHVybiB0fWZ1bmN0aW9uIG51KGUpe3JldHVybiBfbyhlKS8yfWZ1bmN0aW9uIF9vKGUpe2NvbnN0IHQ9ZVswXSxuPVtdO2ZvcihsZXQgcz0xO3M8ZS5sZW5ndGg7cysrKXtjb25zdCBvPWVbc10sYz16bihbXSxvLHQpO24ucHVzaChjKX1jb25zdCByPXJ0KFtdLG5bMV0sblswXSk7bGV0IGk9VWUocik7TWkocixyLDEvaSk7Zm9yKGxldCBzPTI7czxuLmxlbmd0aDtzKyspaSs9c3IobltzLTFdLG5bc10scik7cmV0dXJuIGl9ZnVuY3Rpb24gcnUoZSx0LG4pe3JldHVybiB5byhlLHQsbikvMn1mdW5jdGlvbiB5byhlLHQsbil7cmV0dXJuIGd0WzBdLnN1YlZlY3RvcnModCxlKSxndFsyXS5zdWJWZWN0b3JzKG4sZSksV3QoZ3RbMF0sZ3RbMV0pfWZ1bmN0aW9uIGl1KGUsdCxuKXtyZXR1cm4geG8oZSx0LG4pLzJ9ZnVuY3Rpb24geG8oZSx0LG4pe3JldHVybiBvdFswXS5zdWJWZWN0b3JzKHQsZSksb3RbMl0uc3ViVmVjdG9ycyhuLGUpLFd0KGd0WzBdLGd0WzFdKX1mdW5jdGlvbiBzdShlLHQsbil7cmV0dXJuIE1vKGUsdCxuKS8yfWZ1bmN0aW9uIE1vKGUsdCxuKXtjb25zdFtyLGldPWN0KGUubGVuZ3RoKTtyZXR1cm4gci5zdWJWZWN0b3JzKHQsZSksaS5zdWJWZWN0b3JzKG4sZSksTHMocixpKX1mdW5jdGlvbiBvdShlLHQsbil7cmV0dXJuIHdyKGUsdCxuKS8yfWZ1bmN0aW9uIHdyKGUsdCxuKXtjb25zdFtyLGldPWN0KGUubGVuZ3RoKTtyZXR1cm4gci5zdWJWZWN0b3JzKHQsZSksaS5zdWJWZWN0b3JzKG4sZSksSXMocixpKX1mdW5jdGlvbiBjdShlLHQsbil7cmV0dXJuIHdvKGUsdCxuKS8yfWZ1bmN0aW9uIHdvKGUsdCxuKXtjb25zdFtyLGldPW90O3JldHVybiByLnN1YlZlY3RvcnModCxlKSxpLnN1YlZlY3RvcnMobixlKSxTcyhyLGkpfWZ1bmN0aW9uIGF1KGUsdCxuKXtyZXR1cm4gQXIoZSx0LG4pLzJ9ZnVuY3Rpb24gQXIoZSx0LG4pe2NvbnN0W3IsaV09Z3Q7cmV0dXJuIHIuc3ViVmVjdG9ycyh0LGUpLGkuc3ViVmVjdG9ycyhuLGUpLFBzKHIsaSl9ZnVuY3Rpb24gVHIoZSx0KXtjb25zdCBuPWUubGVuZ3RoLTM7bGV0IHI9MDtmb3IobGV0IGk9MDtpPG47aSs9Myl7Y29uc3RbcyxvLGNdPWUuc2xpY2UoaSxpKzMpLGw9dChzKSxoPXQobyksZj10KGMpO3IrPXdyKGwsaCxmKX1yZXR1cm4gci8yfWZ1bmN0aW9uIHZyKGUsdCxuPVswLDEvMF0pe2NvbnN0IHI9ZS5sZW5ndGgtMyxbaSxzXT1uLG89cy1pO2xldCBjPTA7Y29uc3QgbD0xLzM7Zm9yKGxldCBoPTA7aDxyO2grPTMpe2NvbnN0W2YsdSxkXT1lLnNsaWNlKGgsaCszKSxbZyxtLF9dPXQoZiksW3AsTSxBXT10KHUpLFt4LFQsdl09dChkKSx3PUFyKFtnLG1dLFtwLE1dLFt4LFRdKSxTPShfK0ErdikqbC1pO2MrPXcqTWF0aC5taW4oUyxvKX1yZXR1cm4gYy8yfWNvbnN0IEFvPSEwLGx1PSExLGZuPXtDQ1c6LTEsQ1c6MSxOT1RfT1JJRU5UQUJMRTowfSxodT0yKk1hdGguUEksdW49MSxUbz0wLF90PTIsZnU9Myx1dT00LGR1PTEsZ3U9MixFcj0wLF9lPTEsWHQ9Mjt2YXIgZG49T2JqZWN0LmZyZWV6ZSh7X19wcm90b19fOm51bGwsQk9VTkRBUlk6X3QsQ0NXOkFvLENPTlRBSU5TOmZ1LENXOmx1LEVORF9WRVJURVg6WHQsSU5TSURFOnVuLElOVEVSTEFDRTp1dSxOT1RfVkVSVEVYOkVyLE9SSUVOVEFUSU9OOmZuLE9VVFNJREU6VG8sT1ZFUkxBUF9PUFBPU0lURTpndSxPVkVSTEFQX1NBTUU6ZHUsUEl4MjpodSxTVEFSVF9WRVJURVg6X2V9KTtsZXQgeXQ9MWUtNjtmdW5jdGlvbiB2byhlKXt5dD1lfWZ1bmN0aW9uIEVvKCl7cmV0dXJuIHl0fWNvbnN0IG11PTM7ZnVuY3Rpb24gT3IoZSl7cmV0dXJuIGU8eXQmJmU+LXl0fWZ1bmN0aW9uIHp0KGUsdCl7cmV0dXJuIGUtdDx5dCYmZS10Pi15dH1mdW5jdGlvbiBPbyhlLHQpe3JldHVybiBlLXQ+eXR9ZnVuY3Rpb24gcHUoZSx0KXtyZXR1cm4gZS10Pi15dH1mdW5jdGlvbiBibyhlLHQpe3JldHVybiBlLXQ8LXl0fWZ1bmN0aW9uIF91KGUsdCl7cmV0dXJuIGUtdDx5dH12YXIgeXU9T2JqZWN0LmZyZWV6ZSh7X19wcm90b19fOm51bGwsREVDSU1BTFM6bXUsRVE6enQsRVFfMDpPcixHRTpwdSxHVDpPbyxMRTpfdSxMVDpibyxnZXRUb2xlcmFuY2U6RW8sc2V0VG9sZXJhbmNlOnZvfSk7bGV0IGE9e1V0aWxzOnl1LEVycm9yczp2b2lkIDAsTWF0cml4OnZvaWQgMCxQbGFuYXJfc2V0OnZvaWQgMCxQb2ludDp2b2lkIDAsVmVjdG9yOnZvaWQgMCxMaW5lOnZvaWQgMCxDaXJjbGU6dm9pZCAwLFNlZ21lbnQ6dm9pZCAwLEFyYzp2b2lkIDAsQm94OnZvaWQgMCxFZGdlOnZvaWQgMCxGYWNlOnZvaWQgMCxSYXk6dm9pZCAwLFJheV9zaG9vdGluZzp2b2lkIDAsTXVsdGlsaW5lOnZvaWQgMCxQb2x5Z29uOnZvaWQgMCxEaXN0YW5jZTp2b2lkIDAsSW52ZXJzaW9uOnZvaWQgMH07Zm9yKGxldCBlIGluIGRuKWFbZV09ZG5bZV07T2JqZWN0LmRlZmluZVByb3BlcnR5KGEsIkRQX1RPTCIse2dldDpmdW5jdGlvbigpe3JldHVybiBFbygpfSxzZXQ6ZnVuY3Rpb24oZSl7dm8oZSl9fSk7Y2xhc3MgRHtzdGF0aWMgZ2V0IElMTEVHQUxfUEFSQU1FVEVSUygpe3JldHVybiBuZXcgUmVmZXJlbmNlRXJyb3IoIklsbGVnYWwgUGFyYW1ldGVycyIpfXN0YXRpYyBnZXQgWkVST19ESVZJU0lPTigpe3JldHVybiBuZXcgRXJyb3IoIlplcm8gZGl2aXNpb24iKX1zdGF0aWMgZ2V0IFVOUkVTT0xWRURfQk9VTkRBUllfQ09ORkxJQ1QoKXtyZXR1cm4gbmV3IEVycm9yKCJVbnJlc29sdmVkIGJvdW5kYXJ5IGNvbmZsaWN0IGluIGJvb2xlYW4gb3BlcmF0aW9uIil9c3RhdGljIGdldCBJTkZJTklURV9MT09QKCl7cmV0dXJuIG5ldyBFcnJvcigiSW5maW5pdGUgbG9vcCIpfXN0YXRpYyBnZXQgQ0FOTk9UX0NPTVBMRVRFX0JPT0xFQU5fT1BFUkFUSU9OKCl7cmV0dXJuIG5ldyBFcnJvcigiQ2Fubm90IGNvbXBsZXRlIGJvb2xlYW4gb3BlcmF0aW9uIil9c3RhdGljIGdldCBDQU5OT1RfSU5WT0tFX0FCU1RSQUNUX01FVEhPRCgpe3JldHVybiBuZXcgRXJyb3IoIkFic3RyYWN0IG1ldGhvZCBjYW5ub3QgYmUgaW52b2tlZCIpfXN0YXRpYyBnZXQgT1BFUkFUSU9OX0lTX05PVF9TVVBQT1JURUQoKXtyZXR1cm4gbmV3IEVycm9yKCJPcGVyYXRpb24gaXMgbm90IHN1cHBvcnRlZCIpfXN0YXRpYyBnZXQgVU5TVVBQT1JURURfU0hBUEVfVFlQRSgpe3JldHVybiBuZXcgRXJyb3IoIlVuc3VwcG9ydGVkIHNoYXBlIHR5cGUiKX19YS5FcnJvcnM9RDtjbGFzcyBicntjb25zdHJ1Y3Rvcih0LG4pe3RoaXMuZmlyc3Q9dCx0aGlzLmxhc3Q9bnx8dGhpcy5maXJzdH1bU3ltYm9sLml0ZXJhdG9yXSgpe2xldCB0O3JldHVybntuZXh0OigpPT4odD10P3QubmV4dDp0aGlzLmZpcnN0LHt2YWx1ZTp0LGRvbmU6dD09PXZvaWQgMH0pfX1nZXQgc2l6ZSgpe2xldCB0PTA7Zm9yKGxldCBuIG9mIHRoaXMpdCsrO3JldHVybiB0fXRvQXJyYXkodD12b2lkIDAsbj12b2lkIDApe2xldCByPVtdLGk9dHx8dGhpcy5maXJzdCxzPW58fHRoaXMubGFzdCxvPWk7aWYobz09PXZvaWQgMClyZXR1cm4gcjtkbyByLnB1c2gobyksbz1vLm5leHQ7d2hpbGUobyE9PXMubmV4dCk7cmV0dXJuIHJ9YXBwZW5kKHQpe3JldHVybiB0aGlzLmlzRW1wdHkoKT90aGlzLmZpcnN0PXQ6KHQucHJldj10aGlzLmxhc3QsdGhpcy5sYXN0Lm5leHQ9dCksdGhpcy5sYXN0PXQsdGhpcy5sYXN0Lm5leHQ9dm9pZCAwLHRoaXMuZmlyc3QucHJldj12b2lkIDAsdGhpc31pbnNlcnQodCxuKXtpZih0aGlzLmlzRW1wdHkoKSl0aGlzLmZpcnN0PXQsdGhpcy5sYXN0PXQ7ZWxzZSBpZihuPT1udWxsKXQubmV4dD10aGlzLmZpcnN0LHRoaXMuZmlyc3QucHJldj10LHRoaXMuZmlyc3Q9dDtlbHNle2xldCByPW4ubmV4dDtuLm5leHQ9dCxyJiYoci5wcmV2PXQpLHQucHJldj1uLHQubmV4dD1yLHRoaXMubGFzdD09PW4mJih0aGlzLmxhc3Q9dCl9cmV0dXJuIHRoaXMubGFzdC5uZXh0PXZvaWQgMCx0aGlzLmZpcnN0LnByZXY9dm9pZCAwLHRoaXN9cmVtb3ZlKHQpe3JldHVybiB0PT09dGhpcy5maXJzdCYmdD09PXRoaXMubGFzdD8odGhpcy5maXJzdD12b2lkIDAsdGhpcy5sYXN0PXZvaWQgMCk6KHQucHJldiYmKHQucHJldi5uZXh0PXQubmV4dCksdC5uZXh0JiYodC5uZXh0LnByZXY9dC5wcmV2KSx0PT09dGhpcy5maXJzdCYmKHRoaXMuZmlyc3Q9dC5uZXh0KSx0PT09dGhpcy5sYXN0JiYodGhpcy5sYXN0PXQucHJldikpLHRoaXN9aXNFbXB0eSgpe3JldHVybiB0aGlzLmZpcnN0PT09dm9pZCAwfXN0YXRpYyB0ZXN0SW5maW5pdGVMb29wKHQpe2xldCBuPXQscj10O2Rve2lmKG4hPXQmJm49PT1yKXRocm93IEQuSU5GSU5JVEVfTE9PUDtuPW4ubmV4dCxyPXIubmV4dC5uZXh0fXdoaWxlKG4hPXQpfX1jb25zdCBJbz17c3Ryb2tlOiJibGFjayJ9O2NsYXNzIHh1e2NvbnN0cnVjdG9yKHQ9SW8pe2Zvcihjb25zdCBuIGluIHQpdGhpc1tuXT10W25dO3RoaXMuc3Ryb2tlPXQuc3Ryb2tlPz9Jby5zdHJva2V9dG9BdHRyaWJ1dGVzU3RyaW5nKCl7cmV0dXJuIE9iamVjdC5rZXlzKHRoaXMpLnJlZHVjZSgodCxuKT0+dCsodGhpc1tuXSE9PXZvaWQgMD90aGlzLnRvQXR0clN0cmluZyhuLHRoaXNbbl0pOiIiKSwiIil9dG9BdHRyU3RyaW5nKHQsbil7Y29uc3Qgcj10PT09ImNsYXNzTmFtZSI/ImNsYXNzIjp0aGlzLmNvbnZlcnRDYW1lbFRvS2ViYWJDYXNlKHQpO3JldHVybiBuPT09bnVsbD9gJHtyfSBgOmAke3J9PSIke24udG9TdHJpbmcoKX0iIGB9Y29udmVydENhbWVsVG9LZWJhYkNhc2UodCl7cmV0dXJuIHQubWF0Y2goL1tBLVpdezIsfSg/PVtBLVpdW2Etel0rWzAtOV0qfFxiKXxbQS1aXT9bYS16XStbMC05XSp8W0EtWl18WzAtOV0rL2cpLmpvaW4oIi0iKS50b0xvd2VyQ2FzZSgpfX1mdW5jdGlvbiAkdChlKXtyZXR1cm4gbmV3IHh1KGUpLnRvQXR0cmlidXRlc1N0cmluZygpfWZ1bmN0aW9uIGp0KGUsdCl7bGV0IG49W10sW3IsaSxzXT1lLnN0YW5kYXJkLFtvLGMsbF09dC5zdGFuZGFyZCxoPXIqYy1pKm8sZj1zKmMtaSpsLHU9cipsLXMqbztpZighYS5VdGlscy5FUV8wKGgpKXtsZXQgZCxnO2k9PT0wPyhkPXMvcixnPXUvaCk6Yz09PTA/KGQ9bC9vLGc9dS9oKTpyPT09MD8oZD1mL2gsZz1zL2kpOm89PT0wPyhkPWYvaCxnPWwvYyk6KGQ9Zi9oLGc9dS9oKSxuLnB1c2gobmV3IGEuUG9pbnQoZCxnKSl9cmV0dXJuIG59ZnVuY3Rpb24ga3QoZSx0KXtsZXQgbj1bXSxyPXQucGMucHJvamVjdGlvbk9uKGUpLGk9dC5wYy5kaXN0YW5jZVRvKHIpWzBdO2lmKGEuVXRpbHMuRVEoaSx0LnIpKW4ucHVzaChyKTtlbHNlIGlmKGEuVXRpbHMuTFQoaSx0LnIpKXtsZXQgcz1NYXRoLnNxcnQodC5yKnQuci1pKmkpLG8sYztvPWUubm9ybS5yb3RhdGU5MENDVygpLm11bHRpcGx5KHMpLGM9ci50cmFuc2xhdGUobyksbi5wdXNoKGMpLG89ZS5ub3JtLnJvdGF0ZTkwQ1coKS5tdWx0aXBseShzKSxjPXIudHJhbnNsYXRlKG8pLG4ucHVzaChjKX1yZXR1cm4gbn1mdW5jdGlvbiBRdChlLHQpe2xldCBuPVtdO2ZvcihsZXQgciBvZiB0LnRvU2VnbWVudHMoKSl7bGV0IGk9eWUocixlKTtmb3IobGV0IHMgb2YgaSlrbyhzLG4pfHxuLnB1c2gocyl9cmV0dXJuIG59ZnVuY3Rpb24gZ24oZSx0KXtsZXQgbj1bXTtpZihRdChlLHQuYm94KS5sZW5ndGg9PT0wKXJldHVybiBuO2xldCByPW5ldyBhLkNpcmNsZSh0LnBjLHQuciksaT1rdChlLHIpO2ZvcihsZXQgcyBvZiBpKXMub24odCkmJm4ucHVzaChzKTtyZXR1cm4gbn1mdW5jdGlvbiB5ZShlLHQpe2xldCBuPVtdO2lmKGUucHMub24odCkmJm4ucHVzaChlLnBzKSxlLnBlLm9uKHQpJiYhZS5pc1plcm9MZW5ndGgoKSYmbi5wdXNoKGUucGUpLG4ubGVuZ3RoPjB8fGUuaXNaZXJvTGVuZ3RoKCl8fGUucHMubGVmdFRvKHQpJiZlLnBlLmxlZnRUbyh0KXx8IWUucHMubGVmdFRvKHQpJiYhZS5wZS5sZWZ0VG8odCkpcmV0dXJuIG47bGV0IHI9bmV3IGEuTGluZShlLnBzLGUucGUpO3JldHVybiBqdChyLHQpfWZ1bmN0aW9uIG1uKGUsdCl7bGV0IG49W107aWYoZS5ib3gubm90X2ludGVyc2VjdCh0LmJveCkpcmV0dXJuIG47aWYoZS5pc1plcm9MZW5ndGgoKSlyZXR1cm4gZS5wcy5vbih0KSYmbi5wdXNoKGUucHMpLG47aWYodC5pc1plcm9MZW5ndGgoKSlyZXR1cm4gdC5wcy5vbihlKSYmbi5wdXNoKHQucHMpLG47bGV0IHI9bmV3IGEuTGluZShlLnBzLGUucGUpLGk9bmV3IGEuTGluZSh0LnBzLHQucGUpO2lmKHIuaW5jaWRlbnRUbyhpKSllLnBzLm9uKHQpJiZuLnB1c2goZS5wcyksZS5wZS5vbih0KSYmbi5wdXNoKGUucGUpLHQucHMub24oZSkmJiF0LnBzLmVxdWFsVG8oZS5wcykmJiF0LnBzLmVxdWFsVG8oZS5wZSkmJm4ucHVzaCh0LnBzKSx0LnBlLm9uKGUpJiYhdC5wZS5lcXVhbFRvKGUucHMpJiYhdC5wZS5lcXVhbFRvKGUucGUpJiZuLnB1c2godC5wZSk7ZWxzZXtsZXQgcz1qdChyLGkpO3MubGVuZ3RoPjAmJlNvKHNbMF0sZSkmJlNvKHNbMF0sdCkmJm4ucHVzaChzWzBdKX1yZXR1cm4gbn1mdW5jdGlvbiBTbyhlLHQpe2NvbnN0IG49dC5ib3g7cmV0dXJuIGEuVXRpbHMuTEUoZS54LG4ueG1heCkmJmEuVXRpbHMuR0UoZS54LG4ueG1pbikmJmEuVXRpbHMuTEUoZS55LG4ueW1heCkmJmEuVXRpbHMuR0UoZS55LG4ueW1pbil9ZnVuY3Rpb24gcG4oZSx0KXtsZXQgbj1bXTtpZihlLmJveC5ub3RfaW50ZXJzZWN0KHQuYm94KSlyZXR1cm4gbjtpZihlLmlzWmVyb0xlbmd0aCgpKXtsZXRbcyxvXT1lLnBzLmRpc3RhbmNlVG8odC5wYyk7cmV0dXJuIGEuVXRpbHMuRVEocyx0LnIpJiZuLnB1c2goZS5wcyksbn1sZXQgcj1uZXcgYS5MaW5lKGUucHMsZS5wZSksaT1rdChyLHQpO2ZvcihsZXQgcyBvZiBpKXMub24oZSkmJm4ucHVzaChzKTtyZXR1cm4gbn1mdW5jdGlvbiBLdChlLHQpe2xldCBuPVtdO2lmKGUuYm94Lm5vdF9pbnRlcnNlY3QodC5ib3gpKXJldHVybiBuO2lmKGUuaXNaZXJvTGVuZ3RoKCkpcmV0dXJuIGUucHMub24odCkmJm4ucHVzaChlLnBzKSxuO2xldCByPW5ldyBhLkxpbmUoZS5wcyxlLnBlKSxpPW5ldyBhLkNpcmNsZSh0LnBjLHQucikscz1rdChyLGkpO2ZvcihsZXQgbyBvZiBzKW8ub24oZSkmJm8ub24odCkmJm4ucHVzaChvKTtyZXR1cm4gbn1mdW5jdGlvbiBNdShlLHQpe2xldCBuPVtdO2ZvcihsZXQgciBvZiB0LnRvU2VnbWVudHMoKSl7bGV0IGk9bW4ocixlKTtmb3IobGV0IHMgb2YgaSluLnB1c2gocyl9cmV0dXJuIG59ZnVuY3Rpb24gUG8oZSx0KXtsZXQgbj1bXTtpZihlLmJveC5ub3RfaW50ZXJzZWN0KHQuYm94KSlyZXR1cm4gbjtsZXQgcj1uZXcgYS5WZWN0b3IoZS5wYyx0LnBjKSxpPWUucixzPXQucjtpZihhLlV0aWxzLkVRXzAoaSl8fGEuVXRpbHMuRVFfMChzKSlyZXR1cm4gbjtpZihhLlV0aWxzLkVRXzAoci54KSYmYS5VdGlscy5FUV8wKHIueSkmJmEuVXRpbHMuRVEoaSxzKSlyZXR1cm4gbi5wdXNoKGUucGMudHJhbnNsYXRlKC1pLDApKSxuO2xldCBvPWUucGMuZGlzdGFuY2VUbyh0LnBjKVswXTtpZihhLlV0aWxzLkdUKG8saStzKXx8YS5VdGlscy5MVChvLE1hdGguYWJzKGktcykpKXJldHVybiBuO3IueC89byxyLnkvPW87bGV0IGM7aWYoYS5VdGlscy5FUShvLGkrcyl8fGEuVXRpbHMuRVEobyxNYXRoLmFicyhpLXMpKSlyZXR1cm4gYz1lLnBjLnRyYW5zbGF0ZShpKnIueCxpKnIueSksbi5wdXNoKGMpLG47bGV0IGw9aSppLygyKm8pLXMqcy8oMipvKStvLzIsaD1lLnBjLnRyYW5zbGF0ZShsKnIueCxsKnIueSksZj1NYXRoLnNxcnQoaSppLWwqbCk7cmV0dXJuIGM9aC50cmFuc2xhdGUoci5yb3RhdGU5MENDVygpLm11bHRpcGx5KGYpKSxuLnB1c2goYyksYz1oLnRyYW5zbGF0ZShyLnJvdGF0ZTkwQ1coKS5tdWx0aXBseShmKSksbi5wdXNoKGMpLG59ZnVuY3Rpb24gd3UoZSx0KXtsZXQgbj1bXTtmb3IobGV0IHIgb2YgdC50b1NlZ21lbnRzKCkpe2xldCBpPXBuKHIsZSk7Zm9yKGxldCBzIG9mIGkpbi5wdXNoKHMpfXJldHVybiBufWZ1bmN0aW9uIExvKGUsdCl7bGV0IG49W107aWYoZS5ib3gubm90X2ludGVyc2VjdCh0LmJveCkpcmV0dXJuIG47aWYoZS5wYy5lcXVhbFRvKHQucGMpJiZhLlV0aWxzLkVRKGUucix0LnIpKXtsZXQgbztyZXR1cm4gbz1lLnN0YXJ0LG8ub24odCkmJm4ucHVzaChvKSxvPWUuZW5kLG8ub24odCkmJm4ucHVzaChvKSxvPXQuc3RhcnQsby5vbihlKSYmbi5wdXNoKG8pLG89dC5lbmQsby5vbihlKSYmbi5wdXNoKG8pLG59bGV0IHI9bmV3IGEuQ2lyY2xlKGUucGMsZS5yKSxpPW5ldyBhLkNpcmNsZSh0LnBjLHQucikscz1yLmludGVyc2VjdChpKTtmb3IobGV0IG8gb2YgcylvLm9uKGUpJiZvLm9uKHQpJiZuLnB1c2gobyk7cmV0dXJuIG59ZnVuY3Rpb24gSXIoZSx0KXtsZXQgbj1bXTtpZihlLmJveC5ub3RfaW50ZXJzZWN0KHQuYm94KSlyZXR1cm4gbjtpZih0LnBjLmVxdWFsVG8oZS5wYykmJmEuVXRpbHMuRVEodC5yLGUucikpcmV0dXJuIG4ucHVzaChlLnN0YXJ0KSxuLnB1c2goZS5lbmQpLG47bGV0IHI9dCxpPW5ldyBhLkNpcmNsZShlLnBjLGUucikscz1QbyhyLGkpO2ZvcihsZXQgbyBvZiBzKW8ub24oZSkmJm4ucHVzaChvKTtyZXR1cm4gbn1mdW5jdGlvbiBBdShlLHQpe2xldCBuPVtdO2ZvcihsZXQgciBvZiB0LnRvU2VnbWVudHMoKSl7bGV0IGk9S3QocixlKTtmb3IobGV0IHMgb2YgaSluLnB1c2gocyl9cmV0dXJuIG59ZnVuY3Rpb24gUm8oZSx0KXtyZXR1cm4gZS5pc1NlZ21lbnQ/bW4oZS5zaGFwZSx0KTpLdCh0LGUuc2hhcGUpfWZ1bmN0aW9uIENvKGUsdCl7cmV0dXJuIGUuaXNTZWdtZW50P0t0KGUuc2hhcGUsdCk6TG8oZS5zaGFwZSx0KX1mdW5jdGlvbiBWbyhlLHQpe3JldHVybiBlLmlzU2VnbWVudD95ZShlLnNoYXBlLHQpOmduKHQsZS5zaGFwZSl9ZnVuY3Rpb24gVHUoZSx0KXtyZXR1cm4gZS5pc1NlZ21lbnQ/THIodCxlLnNoYXBlKTpScih0LGUuc2hhcGUpfWZ1bmN0aW9uIHZ1KGUsdCl7cmV0dXJuIGUuaXNTZWdtZW50P3BuKGUuc2hhcGUsdCk6SXIoZS5zaGFwZSx0KX1mdW5jdGlvbiBTcihlLHQpe2xldCBuPVtdO2ZvcihsZXQgciBvZiB0LmVkZ2VzKWZvcihsZXQgaSBvZiBSbyhyLGUpKW4ucHVzaChpKTtyZXR1cm4gbn1mdW5jdGlvbiBQcihlLHQpe2xldCBuPVtdO2ZvcihsZXQgciBvZiB0LmVkZ2VzKWZvcihsZXQgaSBvZiBDbyhyLGUpKW4ucHVzaChpKTtyZXR1cm4gbn1mdW5jdGlvbiB4ZShlLHQpe2xldCBuPVtdO2lmKHQuaXNFbXB0eSgpKXJldHVybiBuO2ZvcihsZXQgciBvZiB0LmVkZ2VzKWZvcihsZXQgaSBvZiBWbyhyLGUpKWtvKGksbil8fG4ucHVzaChpKTtyZXR1cm4gZS5zb3J0UG9pbnRzKG4pfWZ1bmN0aW9uIE5vKGUsdCl7bGV0IG49W107aWYodC5pc0VtcHR5KCkpcmV0dXJuIG47Zm9yKGxldCByIG9mIHQuZWRnZXMpZm9yKGxldCBpIG9mIHZ1KHIsZSkpbi5wdXNoKGkpO3JldHVybiBufWZ1bmN0aW9uIHpvKGUsdCl7cmV0dXJuIGUuaXNTZWdtZW50P1JvKHQsZS5zaGFwZSk6ZS5pc0FyYz9Dbyh0LGUuc2hhcGUpOmUuaXNMaW5lP1ZvKHQsZS5zaGFwZSk6ZS5pc1JheT9UdSh0LGUuc2hhcGUpOltdfWZ1bmN0aW9uICRvKGUsdCl7bGV0IG49W107aWYodC5pc0VtcHR5KCl8fGUuc2hhcGUuYm94Lm5vdF9pbnRlcnNlY3QodC5ib3gpKXJldHVybiBuO2xldCByPXQuZWRnZXMuc2VhcmNoKGUuc2hhcGUuYm94KTtmb3IobGV0IGkgb2YgciluPVsuLi5uLC4uLnpvKGUsaSldO3JldHVybiBufWZ1bmN0aW9uIEV1KGUsdCl7bGV0IG49W107aWYodC5pc0VtcHR5KCl8fGUuc2l6ZT09PTApcmV0dXJuIG47Zm9yKGxldCByIG9mIGUpbj1bLi4ubiwuLi4kbyhyLHQpXTtyZXR1cm4gbn1mdW5jdGlvbiBPdShlLHQpe2xldCBuPVtdO2lmKGUuaXNFbXB0eSgpfHx0LmlzRW1wdHkoKXx8ZS5ib3gubm90X2ludGVyc2VjdCh0LmJveCkpcmV0dXJuIG47Zm9yKGxldCByIG9mIGUuZWRnZXMpbj1bLi4ubiwuLi4kbyhyLHQpXTtyZXR1cm4gbn1mdW5jdGlvbiBidShlLHQpe3JldHVybiBlIGluc3RhbmNlb2YgYS5MaW5lP3hlKGUsdCk6ZSBpbnN0YW5jZW9mIGEuU2VnbWVudD9TcihlLHQpOmUgaW5zdGFuY2VvZiBhLkFyYz9QcihlLHQpOltdfWZ1bmN0aW9uIGtvKGUsdCl7cmV0dXJuIHQuc29tZShuPT5uLmVxdWFsVG8oZSkpfWZ1bmN0aW9uIFN0KGUpe3JldHVybiBuZXcgYS5MaW5lKGUuc3RhcnQsZS5ub3JtKX1mdW5jdGlvbiBMcihlLHQpe3JldHVybiB5ZSh0LFN0KGUpKS5maWx0ZXIobj0+ZS5jb250YWlucyhuKSl9ZnVuY3Rpb24gUnIoZSx0KXtyZXR1cm4gZ24oU3QoZSksdCkuZmlsdGVyKG49PmUuY29udGFpbnMobikpfWZ1bmN0aW9uIEZvKGUsdCl7cmV0dXJuIGt0KFN0KGUpLHQpLmZpbHRlcihuPT5lLmNvbnRhaW5zKG4pKX1mdW5jdGlvbiBJdShlLHQpe3JldHVybiBRdChTdChlKSx0KS5maWx0ZXIobj0+ZS5jb250YWlucyhuKSl9ZnVuY3Rpb24gcW8oZSx0KXtyZXR1cm4ganQoU3QoZSksdCkuZmlsdGVyKG49PmUuY29udGFpbnMobikpfWZ1bmN0aW9uIFN1KGUsdCl7cmV0dXJuIGp0KFN0KGUpLFN0KHQpKS5maWx0ZXIobj0+ZS5jb250YWlucyhuKSkuZmlsdGVyKG49PnQuY29udGFpbnMobikpfWZ1bmN0aW9uIFVvKGUsdCl7cmV0dXJuIHhlKFN0KGUpLHQpLmZpbHRlcihuPT5lLmNvbnRhaW5zKG4pKX1mdW5jdGlvbiBEbyhlLHQpe2lmKGUuaW50ZXJzZWN0JiZlLmludGVyc2VjdCBpbnN0YW5jZW9mIEZ1bmN0aW9uKXJldHVybiBlLmludGVyc2VjdCh0KTt0aHJvdyBELlVOU1VQUE9SVEVEX1NIQVBFX1RZUEV9ZnVuY3Rpb24gTWUoZSx0KXtsZXQgbj1bXTtmb3IobGV0IHIgb2YgdCluPVsuLi5uLC4uLkRvKGUsci5zaGFwZSldO3JldHVybiBufWZ1bmN0aW9uIFB1KGUsdCl7bGV0IG49W107Zm9yKGxldCByIG9mIGUpZm9yKGxldCBpIG9mIHQpbj1bLi4ubiwuLi5EbyhyLGkpXTtyZXR1cm4gbn1sZXQgRnQ9Y2xhc3MgVmUgZXh0ZW5kcyBicntjb25zdHJ1Y3RvciguLi50KXtpZihzdXBlcigpLHRoaXMuaXNJbmZpbml0ZT0hMSx0Lmxlbmd0aD09PTEmJnRbMF1pbnN0YW5jZW9mIEFycmF5JiZ0WzBdLmxlbmd0aD4wKXtsZXQgbj0hMTtjb25zdCByPXRbMF0saT1yLmxlbmd0aCxzPWw9PmwgaW5zdGFuY2VvZiBhLlNlZ21lbnR8fGwgaW5zdGFuY2VvZiBhLkFyY3x8bCBpbnN0YW5jZW9mIGEuUmF5fHxsIGluc3RhbmNlb2YgYS5MaW5lLG89bD0+bCBpbnN0YW5jZW9mIGEuU2VnbWVudHx8bCBpbnN0YW5jZW9mIGEuQXJjfHxsIGluc3RhbmNlb2YgYS5SYXksYz1sPT5sIGluc3RhbmNlb2YgYS5TZWdtZW50fHxsIGluc3RhbmNlb2YgYS5BcmM7aWYobj1pPT09MSYmcyhyWzBdKXx8aT4xJiZvKHJbMF0pJiZvKHJbaS0xXSkmJnIuc2xpY2UoMSxpLTEpLmV2ZXJ5KGMpLG4pe3RoaXMuaXNJbmZpbml0ZT1yLnNvbWUobD0+bCBpbnN0YW5jZW9mIGEuUmF5fHxsIGluc3RhbmNlb2YgYS5MaW5lKTtmb3IobGV0IGwgb2Ygcil7bGV0IGg9bmV3IGEuRWRnZShsKTt0aGlzLmFwcGVuZChoKX10aGlzLnNldEFyY0xlbmd0aCgpfWVsc2UgdGhyb3cgYS5FcnJvcnMuSUxMRUdBTF9QQVJBTUVURVJTfX1nZXQgZWRnZXMoKXtyZXR1cm5bLi4udGhpc119Z2V0IGJveCgpe3JldHVybiB0aGlzLmVkZ2VzLnJlZHVjZSgodCxuKT0+dC5tZXJnZShuLmJveCksbmV3IGEuQm94KX1nZXQgdmVydGljZXMoKXtsZXQgdD10aGlzLmVkZ2VzLm1hcChuPT5uLnN0YXJ0KTtyZXR1cm4gdC5wdXNoKHRoaXMubGFzdC5lbmQpLHR9Z2V0IGxlbmd0aCgpe2lmKHRoaXMuaXNFbXB0eSgpKXJldHVybiAwO2lmKHRoaXMuaXNJbmZpbml0ZSlyZXR1cm4gTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZO2xldCB0PTA7Zm9yKGxldCBuIG9mIHRoaXMpdCs9bi5sZW5ndGg7cmV0dXJuIHR9Y2xvbmUoKXtyZXR1cm4gbmV3IFZlKHRoaXMudG9TaGFwZXMoKSl9c2V0QXJjTGVuZ3RoKCl7Zm9yKGxldCB0IG9mIHRoaXMpdGhpcy5zZXRPbmVFZGdlQXJjTGVuZ3RoKHQpfXNldE9uZUVkZ2VBcmNMZW5ndGgodCl7dD09PXRoaXMuZmlyc3Q/dC5hcmNfbGVuZ3RoPTA6dC5hcmNfbGVuZ3RoPXQucHJldi5hcmNfbGVuZ3RoK3QucHJldi5sZW5ndGh9cG9pbnRBdExlbmd0aCh0KXtpZih0PnRoaXMubGVuZ3RofHx0PDB8fHRoaXMuaXNJbmZpbml0ZSlyZXR1cm4gbnVsbDtsZXQgbj1udWxsO2ZvcihsZXQgciBvZiB0aGlzKWlmKHQ+PXIuYXJjX2xlbmd0aCYmKHI9PT10aGlzLmxhc3R8fHQ8ci5uZXh0LmFyY19sZW5ndGgpKXtuPXIucG9pbnRBdExlbmd0aCh0LXIuYXJjX2xlbmd0aCk7YnJlYWt9cmV0dXJuIG59YWRkVmVydGV4KHQsbil7bGV0IHI9bi5zaGFwZS5zcGxpdCh0KTtpZihyWzBdPT09bnVsbClyZXR1cm4gbi5wcmV2O2lmKHJbMV09PT1udWxsKXJldHVybiBuO2xldCBpPW5ldyBhLkVkZ2UoclswXSkscz1uLnByZXY7cmV0dXJuIHRoaXMuaW5zZXJ0KGkscyksbi5zaGFwZT1yWzFdLGl9Z2V0Q2hhaW4odCxuKXtsZXQgcj1bXTtmb3IobGV0IGk9dDtpIT09bi5uZXh0O2k9aS5uZXh0KXIucHVzaChpKTtyZXR1cm4gcn1zcGxpdCh0KXtmb3IobGV0IG4gb2YgdCl7bGV0IHI9dGhpcy5maW5kRWRnZUJ5UG9pbnQobik7dGhpcy5hZGRWZXJ0ZXgobixyKX1yZXR1cm4gdGhpc31maW5kRWRnZUJ5UG9pbnQodCl7bGV0IG47Zm9yKGxldCByIG9mIHRoaXMpaWYoci5zaGFwZS5jb250YWlucyh0KSl7bj1yO2JyZWFrfXJldHVybiBufWRpc3RhbmNlVG8odCl7aWYodCBpbnN0YW5jZW9mIFBvaW50KXtjb25zdFtuLHJdPWEuRGlzdGFuY2Uuc2hhcGUybXVsdGlsaW5lKHQsdGhpcyk7cmV0dXJuW24sci5yZXZlcnNlKCldfWlmKHQgaW5zdGFuY2VvZiBhLkxpbmUpe2NvbnN0W24scl09YS5EaXN0YW5jZS5zaGFwZTJtdWx0aWxpbmUodCx0aGlzKTtyZXR1cm5bbixyLnJldmVyc2UoKV19aWYodCBpbnN0YW5jZW9mIGEuQ2lyY2xlKXtjb25zdFtuLHJdPWEuRGlzdGFuY2Uuc2hhcGUybXVsdGlsaW5lKHQsdGhpcyk7cmV0dXJuW24sci5yZXZlcnNlKCldfWlmKHQgaW5zdGFuY2VvZiBhLlNlZ21lbnQpe2NvbnN0W24scl09YS5EaXN0YW5jZS5zaGFwZTJtdWx0aWxpbmUodCx0aGlzKTtyZXR1cm5bbixyLnJldmVyc2UoKV19aWYodCBpbnN0YW5jZW9mIGEuQXJjKXtjb25zdFtuLHJdPWEuRGlzdGFuY2Uuc2hhcGUybXVsdGlsaW5lKHQsdGhpcyk7cmV0dXJuW24sci5yZXZlcnNlKCldfWlmKHQgaW5zdGFuY2VvZiBhLk11bHRpbGluZSlyZXR1cm4gYS5EaXN0YW5jZS5tdWx0aWxpbmUybXVsdGlsaW5lKHRoaXMsdCk7dGhyb3cgYS5FcnJvcnMuVU5TVVBQT1JURURfU0hBUEVfVFlQRX1pbnRlcnNlY3QodCl7cmV0dXJuIHQgaW5zdGFuY2VvZiBhLk11bHRpbGluZT9QdSh0aGlzLHQpOk1lKHQsdGhpcyl9Y29udGFpbnModCl7aWYodCBpbnN0YW5jZW9mIGEuUG9pbnQpcmV0dXJuIHRoaXMuZWRnZXMuc29tZShuPT5uLnNoYXBlLmNvbnRhaW5zKHQpKTt0aHJvdyBhLkVycm9ycy5VTlNVUFBPUlRFRF9TSEFQRV9UWVBFfXRyYW5zbGF0ZSh0KXtyZXR1cm4gbmV3IFZlKHRoaXMuZWRnZXMubWFwKG49Pm4uc2hhcGUudHJhbnNsYXRlKHQpKSl9cm90YXRlKHQ9MCxuPW5ldyBhLlBvaW50KXtyZXR1cm4gbmV3IFZlKHRoaXMuZWRnZXMubWFwKHI9PnIuc2hhcGUucm90YXRlKHQsbikpKX10cmFuc2Zvcm0odD1uZXcgYS5NYXRyaXgpe3JldHVybiBuZXcgVmUodGhpcy5lZGdlcy5tYXAobj0+bi5zaGFwZS50cmFuc2Zvcm0odCkpKX10b1NoYXBlcygpe3JldHVybiB0aGlzLmVkZ2VzLm1hcCh0PT50LnNoYXBlLmNsb25lKCkpfXRvSlNPTigpe3JldHVybiB0aGlzLmVkZ2VzLm1hcCh0PT50LnRvSlNPTigpKX1zdmdQb2ludHMoKXtyZXR1cm4gdGhpcy52ZXJ0aWNlcy5tYXAodD0+YCR7dC54fSwke3QueX1gKS5qb2luKCIgIil9ZHBhdGgoKXtsZXQgdD1gTSR7dGhpcy5maXJzdC5zdGFydC54fSwke3RoaXMuZmlyc3Quc3RhcnQueX1gO2ZvcihsZXQgbiBvZiB0aGlzKXQrPW4uc3ZnKCk7cmV0dXJuIHR9c3ZnKHQ9e30pe2xldCBuPWAKPHBhdGggJHskdCh7ZmlsbDoibm9uZSIsLi4udH0pfSBkPSJgO24rPWAKTSR7dGhpcy5maXJzdC5zdGFydC54fSwke3RoaXMuZmlyc3Quc3RhcnQueX1gO2ZvcihsZXQgciBvZiB0aGlzKW4rPXIuc3ZnKCk7cmV0dXJuIG4rPWAiID4KPC9wYXRoPmAsbn19O2EuTXVsdGlsaW5lPUZ0O2NvbnN0IEx1PSguLi5lKT0+bmV3IGEuTXVsdGlsaW5lKC4uLmUpO2EubXVsdGlsaW5lPUx1O2Z1bmN0aW9uIEp0KGUsdCxuKXtsZXQgcj1uLmxlbmd0aCxpPWUuc2hhcGUuc3BsaXQodCk7aWYoaS5sZW5ndGg9PT0wKXJldHVybjtsZXQgcz0wO2lbMF09PT1udWxsP3M9MDppWzFdPT09bnVsbD9zPWUuc2hhcGUubGVuZ3RoOnM9aVswXS5sZW5ndGg7bGV0IG89RXI7enQocywwKSYmKG98PV9lKSx6dChzLGUuc2hhcGUubGVuZ3RoKSYmKG98PVh0KTtsZXQgYztzPT09MS8wP2M9aVswXS5jb29yZCh0KTpjPW8mWHQmJmUubmV4dCYmZS5uZXh0LmFyY19sZW5ndGg9PT0wPzA6ZS5hcmNfbGVuZ3RoK3Msbi5wdXNoKHtpZDpyLHB0OnQsYXJjX2xlbmd0aDpjLGVkZ2VfYmVmb3JlOmUsZWRnZV9hZnRlcjp2b2lkIDAsZmFjZTplLmZhY2UsaXNfdmVydGV4Om99KX1mdW5jdGlvbiB3ZShlKXtlLmludF9wb2ludHMxX3NvcnRlZD1QdChlLmludF9wb2ludHMxKSxlLmludF9wb2ludHMyX3NvcnRlZD1QdChlLmludF9wb2ludHMyKX1mdW5jdGlvbiBQdChlKXtsZXQgdD1uZXcgTWFwLG49MDtmb3IobGV0IGkgb2YgZSl0LmhhcyhpLmZhY2UpfHwodC5zZXQoaS5mYWNlLG4pLG4rKyk7Zm9yKGxldCBpIG9mIGUpaS5mYWNlSWQ9dC5nZXQoaS5mYWNlKTtyZXR1cm4gZS5zbGljZSgpLnNvcnQoUnUpfWZ1bmN0aW9uIFJ1KGUsdCl7cmV0dXJuIGUuZmFjZUlkPHQuZmFjZUlkPy0xOmUuZmFjZUlkPnQuZmFjZUlkPzE6ZS5hcmNfbGVuZ3RoPHQuYXJjX2xlbmd0aD8tMTplLmFyY19sZW5ndGg+dC5hcmNfbGVuZ3RoPzE6MH1mdW5jdGlvbiBDcihlKXtpZihlLmludF9wb2ludHMxLmxlbmd0aDwyKXJldHVybjtsZXQgdD0hMSxuLHIsaSxzO2ZvcihsZXQgbz0wO288ZS5pbnRfcG9pbnRzMV9zb3J0ZWQubGVuZ3RoO28rKylpZihlLmludF9wb2ludHMxX3NvcnRlZFtvXS5pZCE9PS0xKXtuPWUuaW50X3BvaW50czFfc29ydGVkW29dLHI9ZS5pbnRfcG9pbnRzMltuLmlkXTtmb3IobGV0IGM9bysxO2M8ZS5pbnRfcG9pbnRzMV9zb3J0ZWQubGVuZ3RoJiYoaT1lLmludF9wb2ludHMxX3NvcnRlZFtjXSwhIXp0KGkuYXJjX2xlbmd0aCxuLmFyY19sZW5ndGgpKTtjKyspaS5pZCE9PS0xJiYocz1lLmludF9wb2ludHMyW2kuaWRdLHMuaWQhPT0tMSYmaS5lZGdlX2JlZm9yZT09PW4uZWRnZV9iZWZvcmUmJmkuZWRnZV9hZnRlcj09PW4uZWRnZV9hZnRlciYmcy5lZGdlX2JlZm9yZT09PXIuZWRnZV9iZWZvcmUmJnMuZWRnZV9hZnRlcj09PXIuZWRnZV9hZnRlciYmKGkuaWQ9LTEscy5pZD0tMSx0PSEwKSl9cj1lLmludF9wb2ludHMyX3NvcnRlZFswXSxuPWUuaW50X3BvaW50czFbci5pZF07Zm9yKGxldCBvPTE7bzxlLmludF9wb2ludHMyX3NvcnRlZC5sZW5ndGg7bysrKXtsZXQgYz1lLmludF9wb2ludHMyX3NvcnRlZFtvXTtpZihjLmlkPT09LTEpY29udGludWU7aWYoci5pZD09PS0xfHwhenQoYy5hcmNfbGVuZ3RoLHIuYXJjX2xlbmd0aCkpe3I9YyxuPWUuaW50X3BvaW50czFbci5pZF07Y29udGludWV9bGV0IGw9ZS5pbnRfcG9pbnRzMVtjLmlkXTtsLmVkZ2VfYmVmb3JlPT09bi5lZGdlX2JlZm9yZSYmbC5lZGdlX2FmdGVyPT09bi5lZGdlX2FmdGVyJiZjLmVkZ2VfYmVmb3JlPT09ci5lZGdlX2JlZm9yZSYmYy5lZGdlX2FmdGVyPT09ci5lZGdlX2FmdGVyJiYobC5pZD0tMSxjLmlkPS0xLHQ9ITApfXQmJihlLmludF9wb2ludHMxPWUuaW50X3BvaW50czEuZmlsdGVyKG89Pm8uaWQ+PTApLGUuaW50X3BvaW50czI9ZS5pbnRfcG9pbnRzMi5maWx0ZXIobz0+by5pZD49MCksZS5pbnRfcG9pbnRzMS5mb3JFYWNoKChvLGMpPT5vLmlkPWMpLGUuaW50X3BvaW50czIuZm9yRWFjaCgobyxjKT0+by5pZD1jKSl9ZnVuY3Rpb24gVnIoZSl7Zm9yKGxldCB0IG9mIGUpdC5lZGdlX2JlZm9yZSYmKHQuZWRnZV9iZWZvcmUuYnZTdGFydD12b2lkIDAsdC5lZGdlX2JlZm9yZS5idkVuZD12b2lkIDAsdC5lZGdlX2JlZm9yZS5idj12b2lkIDAsdC5lZGdlX2JlZm9yZS5vdmVybGFwPXZvaWQgMCksdC5lZGdlX2FmdGVyJiYodC5lZGdlX2FmdGVyLmJ2U3RhcnQ9dm9pZCAwLHQuZWRnZV9hZnRlci5idkVuZD12b2lkIDAsdC5lZGdlX2FmdGVyLmJ2PXZvaWQgMCx0LmVkZ2VfYWZ0ZXIub3ZlcmxhcD12b2lkIDApO2ZvcihsZXQgdCBvZiBlKXQuZWRnZV9iZWZvcmUmJih0LmVkZ2VfYmVmb3JlLmJ2RW5kPV90KSx0LmVkZ2VfYWZ0ZXImJih0LmVkZ2VfYWZ0ZXIuYnZTdGFydD1fdCl9ZnVuY3Rpb24gTnIoZSx0KXtmb3IobGV0IG4gb2YgZSluLmVkZ2VfYmVmb3JlJiZuLmVkZ2VfYmVmb3JlLnNldEluY2x1c2lvbih0KSxuLmVkZ2VfYWZ0ZXImJm4uZWRnZV9hZnRlci5zZXRJbmNsdXNpb24odCl9ZnVuY3Rpb24gQ3UoZSl7bGV0IHQsbixyLGk9ZS5pbnRfcG9pbnRzMS5sZW5ndGg7Zm9yKGxldCBzPTA7czxpO3MrKyl7bGV0IG89ZS5pbnRfcG9pbnRzMV9zb3J0ZWRbc107by5mYWNlIT09dCYmKG49cyx0PW8uZmFjZSk7bGV0IGM9cyxsPUh0KGUuaW50X3BvaW50czFfc29ydGVkLHMsdCksaDtjK2w8aSYmZS5pbnRfcG9pbnRzMV9zb3J0ZWRbYytsXS5mYWNlPT09dD9oPWMrbDpoPW47bGV0IGY9SHQoZS5pbnRfcG9pbnRzMV9zb3J0ZWQsaCx0KTtyPW51bGw7Zm9yKGxldCBNPWg7TTxoK2Y7TSsrKXtsZXQgQT1lLmludF9wb2ludHMxX3NvcnRlZFtNXTtpZihBLmZhY2U9PT10JiZlLmludF9wb2ludHMyW0EuaWRdLmZhY2U9PT1lLmludF9wb2ludHMyW28uaWRdLmZhY2Upe3I9QTticmVha319aWYocj09PW51bGwpY29udGludWU7bGV0IHU9by5lZGdlX2FmdGVyLGQ9ci5lZGdlX2JlZm9yZTtpZighKHUuYnY9PT1fdCYmZC5idj09PV90KXx8dSE9PWQpY29udGludWU7bGV0IGc9ZS5pbnRfcG9pbnRzMltvLmlkXSxtPWUuaW50X3BvaW50czJbci5pZF0sXz1nLmVkZ2VfYWZ0ZXIscD1tLmVkZ2VfYmVmb3JlO18uYnY9PT1fdCYmcC5idj09PV90JiZfPT09cHx8KGc9ZS5pbnRfcG9pbnRzMltyLmlkXSxtPWUuaW50X3BvaW50czJbby5pZF0sXz1nLmVkZ2VfYWZ0ZXIscD1tLmVkZ2VfYmVmb3JlKSxfLmJ2PT09X3QmJnAuYnY9PT1fdCYmXz09PXAmJnUuc2V0T3ZlcmxhcChfKX19ZnVuY3Rpb24gSHQoZSx0LG4pe2xldCByLGkscz0xO2lmKGUubGVuZ3RoPT09MSlyZXR1cm4gMTtyPWVbdF07Zm9yKGxldCBvPXQrMTtvPGUubGVuZ3RoJiYhKHIuZmFjZSE9PW58fChpPWVbb10sIShpLnB0LmVxdWFsVG8oci5wdCkmJmkuZWRnZV9iZWZvcmU9PT1yLmVkZ2VfYmVmb3JlJiZpLmVkZ2VfYWZ0ZXI9PT1yLmVkZ2VfYWZ0ZXIpKSk7bysrKXMrKztyZXR1cm4gc31mdW5jdGlvbiB0ZShlLHQpe2lmKHQpe2ZvcihsZXQgbiBvZiB0KXtsZXQgcj1uLmVkZ2VfYmVmb3JlO2lmKG4uaXNfdmVydGV4PUVyLHIuc2hhcGUuc3RhcnQmJnIuc2hhcGUuc3RhcnQuZXF1YWxUbyhuLnB0KSYmKG4uaXNfdmVydGV4fD1fZSksci5zaGFwZS5lbmQmJnIuc2hhcGUuZW5kLmVxdWFsVG8obi5wdCkmJihuLmlzX3ZlcnRleHw9WHQpLG4uaXNfdmVydGV4Jl9lKXtuLmVkZ2VfYmVmb3JlPXIucHJldixyLnByZXYmJihuLmlzX3ZlcnRleD1YdCk7Y29udGludWV9aWYobi5pc192ZXJ0ZXgmWHQpY29udGludWU7bGV0IGk9ZS5hZGRWZXJ0ZXgobi5wdCxyKTtuLmVkZ2VfYmVmb3JlPWl9Zm9yKGxldCBuIG9mIHQpbi5lZGdlX2JlZm9yZT9uLmVkZ2VfYWZ0ZXI9bi5lZGdlX2JlZm9yZS5uZXh0OmUgaW5zdGFuY2VvZiBGdCYmbi5pc192ZXJ0ZXgmX2UmJihuLmVkZ2VfYWZ0ZXI9ZS5maXJzdCl9fWZ1bmN0aW9uIEJvKGUsdCxuKXtjb25zdCByPWUuZWRnZV9iZWZvcmUsaT10LmVkZ2VfYWZ0ZXIscz1uLmxlbmd0aDtyLm5leHQ9blswXSxuWzBdLnByZXY9cixuW3MtMV0ubmV4dD1pLGkucHJldj1uW3MtMV19Y29uc3R7SU5TSURFOnh0LE9VVFNJREU6TXQsQk9VTkRBUlk6USxPVkVSTEFQX1NBTUU6VnUsT1ZFUkxBUF9PUFBPU0lURTpOdX09ZG4se05PVF9WRVJURVg6UDEsU1RBUlRfVkVSVEVYOllvLEVORF9WRVJURVg6V299PWRuLF9uPTEsQWU9MixxdD0zO2Z1bmN0aW9uIHp1KGUsdCl7bGV0W24scl09VGUoZSx0LF9uLCEwKTtyZXR1cm4gbn1mdW5jdGlvbiB6cihlLHQpe2xldCByPXQuY2xvbmUoKS5yZXZlcnNlKCksW2ksc109VGUoZSxyLHF0LCEwKTtyZXR1cm4gaX1mdW5jdGlvbiBabyhlLHQpe2xldFtuLHJdPVRlKGUsdCxBZSwhMCk7cmV0dXJuIG59ZnVuY3Rpb24gR28oZSx0KXtsZXRbbixyXT1UZShlLHQsQWUsITEpLGk9W107Zm9yKGxldCBvIG9mIG4uZmFjZXMpaT1bLi4uaSwuLi5bLi4uby5lZGdlc10ubWFwKGM9PmMuc2hhcGUpXTtsZXQgcz1bXTtmb3IobGV0IG8gb2Ygci5mYWNlcylzPVsuLi5zLC4uLlsuLi5vLmVkZ2VzXS5tYXAoYz0+Yy5zaGFwZSldO3JldHVybltpLHNdfWZ1bmN0aW9uICRyKGUsdCl7bGV0W24scl09VGUoZSx0LHF0LCExKSxpPVtdO2ZvcihsZXQgcyBvZiBuLmZhY2VzKWk9Wy4uLmksLi4uWy4uLnMuZWRnZXNdLm1hcChvPT5vLnNoYXBlKV07cmV0dXJuIGl9ZnVuY3Rpb24gWG8oZSx0KXtsZXQgbj1lLmNsb25lKCkscj10LmNsb25lKCksaT1qbyhuLHIpO3dlKGkpLHRlKG4saS5pbnRfcG9pbnRzMV9zb3J0ZWQpLHRlKHIsaS5pbnRfcG9pbnRzMl9zb3J0ZWQpLENyKGkpLHdlKGkpO2xldCBzPWkuaW50X3BvaW50czFfc29ydGVkLm1hcChjPT5jLnB0KSxvPWkuaW50X3BvaW50czJfc29ydGVkLm1hcChjPT5jLnB0KTtyZXR1cm5bcyxvXX1mdW5jdGlvbiAkdShlLHQsbixyKXtsZXQgaT1RbyhlLG4uaW50X3BvaW50czEpLHM9UW8odCxuLmludF9wb2ludHMyKTtmb3IoS28oaSx0KSxLbyhzLGUpLFZyKG4uaW50X3BvaW50czEpLFZyKG4uaW50X3BvaW50czIpLE5yKG4uaW50X3BvaW50czEsdCksTnIobi5pbnRfcG9pbnRzMixlKTtGdShlLHQsbi5pbnRfcG9pbnRzMSxuLmludF9wb2ludHMxX3NvcnRlZCxuLmludF9wb2ludHMyLG4pOyk7Q3Uobiksa3IoZSxyLG4uaW50X3BvaW50czFfc29ydGVkLCEwKSxrcih0LHIsbi5pbnRfcG9pbnRzMl9zb3J0ZWQsITEpLEpvKGUsaSxyLCEwKSxKbyh0LHMsciwhMSl9ZnVuY3Rpb24ga3UoZSx0LG4scil7cXUoZSx0LHIsbi5pbnRfcG9pbnRzMiksVXUoZSx0LG4pLEZyKGUsbi5pbnRfcG9pbnRzMSksRnIodCxuLmludF9wb2ludHMyKSxxcihlLG4uaW50X3BvaW50czEsbi5pbnRfcG9pbnRzMikscXIoZSxuLmludF9wb2ludHMyLG4uaW50X3BvaW50czEpfWZ1bmN0aW9uIFRlKGUsdCxuLHIpe2xldCBpPWUuY2xvbmUoKSxzPXQuY2xvbmUoKSxvPWpvKGkscyk7cmV0dXJuIHdlKG8pLHRlKGksby5pbnRfcG9pbnRzMV9zb3J0ZWQpLHRlKHMsby5pbnRfcG9pbnRzMl9zb3J0ZWQpLENyKG8pLHdlKG8pLCR1KGkscyxvLG4pLHImJmt1KGkscyxvLG4pLFtpLHNdfWZ1bmN0aW9uIGpvKGUsdCl7bGV0IG49e2ludF9wb2ludHMxOltdLGludF9wb2ludHMyOltdfTtmb3IobGV0IHIgb2YgZS5lZGdlcyl7bGV0IGk9dC5lZGdlcy5zZWFyY2goci5ib3gpO2ZvcihsZXQgcyBvZiBpKXtsZXQgbz1yLnNoYXBlLmludGVyc2VjdChzLnNoYXBlKTtmb3IobGV0IGMgb2YgbylKdChyLGMsbi5pbnRfcG9pbnRzMSksSnQocyxjLG4uaW50X3BvaW50czIpfX1yZXR1cm4gbn1mdW5jdGlvbiBRbyhlLHQpe2xldCBuPVtdO2ZvcihsZXQgciBvZiBlLmZhY2VzKXQuZmluZChpPT5pLmZhY2U9PT1yKXx8bi5wdXNoKHIpO3JldHVybiBufWZ1bmN0aW9uIEtvKGUsdCl7Zm9yKGxldCBuIG9mIGUpbi5maXJzdC5idj1uLmZpcnN0LmJ2U3RhcnQ9bi5maXJzdC5idkVuZD12b2lkIDAsbi5maXJzdC5zZXRJbmNsdXNpb24odCl9ZnVuY3Rpb24gRnUoZSx0LG4scixpLHMpe2xldCBvLGMsbCxoPXIubGVuZ3RoLGY9ITE7Zm9yKGxldCB1PTA7dTxoO3UrKyl7bGV0IGQ9clt1XTtkLmZhY2UhPT1vJiYoYz11LG89ZC5mYWNlKTtsZXQgZz11LG09SHQocix1LG8pLF87ZyttPGgmJnJbZyttXS5mYWNlPT09bz9fPWcrbTpfPWM7bGV0IHA9SHQocixfLG8pO2w9bnVsbDtmb3IobGV0IHg9Xzt4PF8rcDt4Kyspe2xldCBUPXJbeF07aWYoVC5mYWNlPT09byYmaVtULmlkXS5mYWNlPT09aVtkLmlkXS5mYWNlKXtsPVQ7YnJlYWt9fWlmKGw9PT1udWxsKWNvbnRpbnVlO2xldCBNPWQuZWRnZV9hZnRlcixBPWwuZWRnZV9iZWZvcmU7aWYoTS5idj09PVEmJkEuYnYhPVEpe00uYnY9QS5idjtjb250aW51ZX1pZihNLmJ2IT1RJiZBLmJ2PT09USl7QS5idj1NLmJ2O2NvbnRpbnVlfWlmKE0uYnY9PT1RJiZBLmJ2PT09USYmTSE9QXx8TS5idj09PXh0JiZBLmJ2PT09TXR8fE0uYnY9PT1NdCYmQS5idj09PXh0KXtsZXQgeD1NLm5leHQ7Zm9yKDt4IT1BOyl4LmJ2U3RhcnQ9dm9pZCAwLHguYnZFbmQ9dm9pZCAwLHguYnY9dm9pZCAwLHguc2V0SW5jbHVzaW9uKHQpLHg9eC5uZXh0fWlmKE0uYnY9PT1RJiZBLmJ2PT09USYmTSE9QSl7bGV0IHg9TS5uZXh0LFQ7Zm9yKDt4IT1BOyl7aWYoeC5idiE9USl7aWYoVD09PXZvaWQgMClUPXguYnY7ZWxzZSBpZih4LmJ2IT1UKXRocm93IEQuVU5SRVNPTFZFRF9CT1VOREFSWV9DT05GTElDVH14PXgubmV4dH1UIT1udWxsJiYoTS5idj1ULEEuYnY9VCk7Y29udGludWV9aWYoTS5idj09PXh0JiZBLmJ2PT09TXR8fE0uYnY9PT1NdCYmQS5idj09PXh0KXtsZXQgeD1NO2Zvcig7eCE9QTspe2lmKHguYnZTdGFydD09PU0uYnYmJnguYnZFbmQ9PT1BLmJ2KXtsZXRbVCx2XT14LnNoYXBlLmRpc3RhbmNlVG8odCk7aWYoVDwxMCphLkRQX1RPTCl7SnQoeCx2LnBzLG4pO2xldCB3PW5bbi5sZW5ndGgtMV07aWYody5pc192ZXJ0ZXgmWW8pdy5lZGdlX2FmdGVyPXgsdy5lZGdlX2JlZm9yZT14LnByZXYseC5idlN0YXJ0PVEseC5idj12b2lkIDAseC5zZXRJbmNsdXNpb24odCk7ZWxzZSBpZih3LmlzX3ZlcnRleCZXbyl3LmVkZ2VfYWZ0ZXI9eC5uZXh0LHguYnZFbmQ9USx4LmJ2PXZvaWQgMCx4LnNldEluY2x1c2lvbih0KTtlbHNle2xldCBJPXQuYWRkVmVydGV4KHcucHQseCk7dy5lZGdlX2JlZm9yZT1JLHcuZWRnZV9hZnRlcj1JLm5leHQsSS5zZXRJbmNsdXNpb24odCksSS5uZXh0LmJ2U3RhcnQ9USxJLm5leHQuYnZFbmQ9dm9pZCAwLEkubmV4dC5idj12b2lkIDAsSS5uZXh0LnNldEluY2x1c2lvbih0KX1sZXQgUz10LmZpbmRFZGdlQnlQb2ludCh2LnBlKTtKdChTLHYucGUsaSk7bGV0IGI9aVtpLmxlbmd0aC0xXTtpZihiLmlzX3ZlcnRleCZZbyliLmVkZ2VfYWZ0ZXI9UyxiLmVkZ2VfYmVmb3JlPVMucHJldjtlbHNlIGlmKGIuaXNfdmVydGV4JldvKWIuZWRnZV9hZnRlcj1TLm5leHQ7ZWxzZXtsZXQgST1pLmZpbmQoVj0+Vi5lZGdlX2FmdGVyPT09UyksRT10LmFkZFZlcnRleChiLnB0LFMpO2IuZWRnZV9iZWZvcmU9RSxiLmVkZ2VfYWZ0ZXI9RS5uZXh0LEkmJihJLmVkZ2VfYWZ0ZXI9RSksRS5idlN0YXJ0PXZvaWQgMCxFLmJ2RW5kPVEsRS5idj12b2lkIDAsRS5zZXRJbmNsdXNpb24oZSksRS5uZXh0LmJ2U3RhcnQ9USxFLm5leHQuYnZFbmQ9dm9pZCAwLEUubmV4dC5idj12b2lkIDAsRS5uZXh0LnNldEluY2x1c2lvbihlKX13ZShzKSxmPSEwO2JyZWFrfX14PXgubmV4dH1pZihmKWJyZWFrO3Rocm93IEQuVU5SRVNPTFZFRF9CT1VOREFSWV9DT05GTElDVH19cmV0dXJuIGZ9ZnVuY3Rpb24ga3IoZSx0LG4scil7aWYoIW4pcmV0dXJuO2xldCBpLHMsbyxjO2ZvcihsZXQgbD0wO2w8bi5sZW5ndGg7bCsrKXtpZihvPW5bbF0sby5mYWNlIT09aSYmKHM9bCxpPW8uZmFjZSksaS5pc0VtcHR5KCkpY29udGludWU7bGV0IGg9bCxmPUh0KG4sbCxpKSx1O2grZjxuLmxlbmd0aCYmbltoK2ZdLmZhY2U9PT1vLmZhY2U/dT1oK2Y6dT1zLGM9blt1XTtsZXQgZD11LGc9SHQobixkLGkpLG09by5lZGdlX2FmdGVyLF89Yy5lZGdlX2JlZm9yZTtpZihtLmJ2PT09eHQmJl8uYnY9PT14dCYmdD09PV9ufHxtLmJ2PT09TXQmJl8uYnY9PT1NdCYmdD09PUFlfHwobS5idj09PU10fHxfLmJ2PT09TXQpJiZ0PT09cXQmJiFyfHwobS5idj09PXh0fHxfLmJ2PT09eHQpJiZ0PT09cXQmJnJ8fG0uYnY9PT1RJiZfLmJ2PT09USYmbS5vdmVybGFwJlZ1JiZyfHxtLmJ2PT09USYmXy5idj09PVEmJm0ub3ZlcmxhcCZOdSl7ZS5yZW1vdmVDaGFpbihpLG0sXyk7Zm9yKGxldCBwPWg7cDxoK2Y7cCsrKW5bcF0uZWRnZV9hZnRlcj12b2lkIDA7Zm9yKGxldCBwPWQ7cDxkK2c7cCsrKW5bcF0uZWRnZV9iZWZvcmU9dm9pZCAwfWwrPWYtMX19ZnVuY3Rpb24gcXUoZSx0LG4scil7Zm9yKGxldCBpIG9mIHQuZmFjZXMpe2ZvcihsZXQgcyBvZiBpKWUuZWRnZXMuYWRkKHMpO3IuZmluZChzPT5zLmZhY2U9PT1pKT09PXZvaWQgMCYmZS5hZGRGYWNlKGkuZmlyc3QsaS5sYXN0KX19ZnVuY3Rpb24gVXUoZSx0LG4pe2lmKG4uaW50X3BvaW50czEubGVuZ3RoIT09MClmb3IobGV0IHI9MDtyPG4uaW50X3BvaW50czEubGVuZ3RoO3IrKyl7bGV0IGk9bi5pbnRfcG9pbnRzMVtyXSxzPW4uaW50X3BvaW50czJbcl07aWYoaS5lZGdlX2JlZm9yZSE9PXZvaWQgMCYmaS5lZGdlX2FmdGVyPT09dm9pZCAwJiZzLmVkZ2VfYmVmb3JlPT09dm9pZCAwJiZzLmVkZ2VfYWZ0ZXIhPT12b2lkIDAmJihpLmVkZ2VfYmVmb3JlLm5leHQ9cy5lZGdlX2FmdGVyLHMuZWRnZV9hZnRlci5wcmV2PWkuZWRnZV9iZWZvcmUsaS5lZGdlX2FmdGVyPXMuZWRnZV9hZnRlcixzLmVkZ2VfYmVmb3JlPWkuZWRnZV9iZWZvcmUpLHMuZWRnZV9iZWZvcmUhPT12b2lkIDAmJnMuZWRnZV9hZnRlcj09PXZvaWQgMCYmaS5lZGdlX2JlZm9yZT09PXZvaWQgMCYmaS5lZGdlX2FmdGVyIT09dm9pZCAwJiYocy5lZGdlX2JlZm9yZS5uZXh0PWkuZWRnZV9hZnRlcixpLmVkZ2VfYWZ0ZXIucHJldj1zLmVkZ2VfYmVmb3JlLHMuZWRnZV9hZnRlcj1pLmVkZ2VfYWZ0ZXIsaS5lZGdlX2JlZm9yZT1zLmVkZ2VfYmVmb3JlKSxpLmVkZ2VfYmVmb3JlIT09dm9pZCAwJiZpLmVkZ2VfYWZ0ZXI9PT12b2lkIDApZm9yKGxldCBvIG9mIG4uaW50X3BvaW50czFfc29ydGVkKW8hPT1pJiZvLmVkZ2VfYmVmb3JlPT09dm9pZCAwJiZvLmVkZ2VfYWZ0ZXIhPT12b2lkIDAmJm8ucHQuZXF1YWxUbyhpLnB0KSYmKGkuZWRnZV9iZWZvcmUubmV4dD1vLmVkZ2VfYWZ0ZXIsby5lZGdlX2FmdGVyLnByZXY9aS5lZGdlX2JlZm9yZSxpLmVkZ2VfYWZ0ZXI9by5lZGdlX2FmdGVyLG8uZWRnZV9iZWZvcmU9aS5lZGdlX2JlZm9yZSk7aWYocy5lZGdlX2JlZm9yZSE9PXZvaWQgMCYmcy5lZGdlX2FmdGVyPT09dm9pZCAwKWZvcihsZXQgbyBvZiBuLmludF9wb2ludHMyX3NvcnRlZClvIT09cyYmby5lZGdlX2JlZm9yZT09PXZvaWQgMCYmby5lZGdlX2FmdGVyIT09dm9pZCAwJiZvLnB0LmVxdWFsVG8ocy5wdCkmJihzLmVkZ2VfYmVmb3JlLm5leHQ9by5lZGdlX2FmdGVyLG8uZWRnZV9hZnRlci5wcmV2PXMuZWRnZV9iZWZvcmUscy5lZGdlX2FmdGVyPW8uZWRnZV9hZnRlcixvLmVkZ2VfYmVmb3JlPXMuZWRnZV9iZWZvcmUpfX1mdW5jdGlvbiBGcihlLHQpe2ZvcihsZXQgbiBvZiB0KWUuZmFjZXMuZGVsZXRlKG4uZmFjZSksbi5mYWNlPXZvaWQgMCxuLmVkZ2VfYmVmb3JlJiYobi5lZGdlX2JlZm9yZS5mYWNlPXZvaWQgMCksbi5lZGdlX2FmdGVyJiYobi5lZGdlX2FmdGVyLmZhY2U9dm9pZCAwKX1mdW5jdGlvbiBxcihlLHQsbil7Zm9yKGxldCByIG9mIHQpe2lmKHIuZWRnZV9iZWZvcmU9PT12b2lkIDB8fHIuZWRnZV9hZnRlcj09PXZvaWQgMHx8ci5mYWNlfHxyLmVkZ2VfYWZ0ZXIuZmFjZXx8ci5lZGdlX2JlZm9yZS5mYWNlKWNvbnRpbnVlO2xldCBpPXIuZWRnZV9hZnRlcixzPXIuZWRnZV9iZWZvcmU7dHJ5e2JyLnRlc3RJbmZpbml0ZUxvb3AoaSl9Y2F0Y2h7dGhyb3cgRC5DQU5OT1RfQ09NUExFVEVfQk9PTEVBTl9PUEVSQVRJT059bGV0IG89ZS5hZGRGYWNlKGkscyk7Zm9yKGxldCBjIG9mIHQpYy5lZGdlX2JlZm9yZSYmYy5lZGdlX2FmdGVyJiZjLmVkZ2VfYmVmb3JlLmZhY2U9PT1vJiZjLmVkZ2VfYWZ0ZXIuZmFjZT09PW8mJihjLmZhY2U9byk7Zm9yKGxldCBjIG9mIG4pYy5lZGdlX2JlZm9yZSYmYy5lZGdlX2FmdGVyJiZjLmVkZ2VfYmVmb3JlLmZhY2U9PT1vJiZjLmVkZ2VfYWZ0ZXIuZmFjZT09PW8mJihjLmZhY2U9byl9fWZ1bmN0aW9uIEpvKGUsdCxuLHIpe2ZvcihsZXQgaSBvZiB0KXtsZXQgcz1pLmZpcnN0LmJ2OyhuPT09X24mJnM9PT14dHx8bj09PXF0JiZzPT09eHQmJnJ8fG49PT1xdCYmcz09PU10JiYhcnx8bj09PUFlJiZzPT09TXQpJiZlLmRlbGV0ZUZhY2UoaSl9fXZhciB2ZT1PYmplY3QuZnJlZXplKHtfX3Byb3RvX186bnVsbCxCT09MRUFOX0lOVEVSU0VDVDpBZSxCT09MRUFOX1NVQlRSQUNUOnF0LEJPT0xFQU5fVU5JT046X24sY2FsY3VsYXRlSW50ZXJzZWN0aW9uczpYbyxpbm5lckNsaXA6R28saW50ZXJzZWN0OlpvLG91dGVyQ2xpcDokcixyZW1vdmVOb3RSZWxldmFudENoYWluczprcixyZW1vdmVPbGRGYWNlczpGcixyZXN0b3JlRmFjZXM6cXIsc3VidHJhY3Q6enIsdW5pZnk6enV9KTtjb25zdCBEdT1SZWdFeHAoIlQuRi4uRkZGLnxULkYuLi5GLi4iKSxCdT1SZWdFeHAoIlQuLi4uLi4uLnwuVC4uLi4uLi58Li4uVC4uLi4ufC4uLi5ULi4uLiIpLFl1PVJlZ0V4cCgiRlQuLi4uLi4ufEYuLlQuLi4uLnxGLi4uVC4uLi4iKSxXdT1SZWdFeHAoIlQuRi4uRi4uLiIpLFp1PVJlZ0V4cCgiVC5GLi5GLi4ufC5URi4uRi4uLnwuLkZULkYuLi58Li5GLlRGLi4uIik7Y2xhc3MgZWV7Y29uc3RydWN0b3IoKXt0aGlzLm09bmV3IEFycmF5KDkpLmZpbGwodm9pZCAwKX1nZXQgSTJJKCl7cmV0dXJuIHRoaXMubVswXX1zZXQgSTJJKHQpe3RoaXMubVswXT10fWdldCBJMkIoKXtyZXR1cm4gdGhpcy5tWzFdfXNldCBJMkIodCl7dGhpcy5tWzFdPXR9Z2V0IEkyRSgpe3JldHVybiB0aGlzLm1bMl19c2V0IEkyRSh0KXt0aGlzLm1bMl09dH1nZXQgQjJJKCl7cmV0dXJuIHRoaXMubVszXX1zZXQgQjJJKHQpe3RoaXMubVszXT10fWdldCBCMkIoKXtyZXR1cm4gdGhpcy5tWzRdfXNldCBCMkIodCl7dGhpcy5tWzRdPXR9Z2V0IEIyRSgpe3JldHVybiB0aGlzLm1bNV19c2V0IEIyRSh0KXt0aGlzLm1bNV09dH1nZXQgRTJJKCl7cmV0dXJuIHRoaXMubVs2XX1zZXQgRTJJKHQpe3RoaXMubVs2XT10fWdldCBFMkIoKXtyZXR1cm4gdGhpcy5tWzddfXNldCBFMkIodCl7dGhpcy5tWzddPXR9Z2V0IEUyRSgpe3JldHVybiB0aGlzLm1bOF19c2V0IEUyRSh0KXt0aGlzLm1bOF09dH10b1N0cmluZygpe3JldHVybiB0aGlzLm0ubWFwKHQ9PnQgaW5zdGFuY2VvZiBBcnJheSYmdC5sZW5ndGg+MD8iVCI6dCBpbnN0YW5jZW9mIEFycmF5JiZ0Lmxlbmd0aD09PTA/IkYiOiIqIikuam9pbigiIil9ZXF1YWwoKXtyZXR1cm4gRHUudGVzdCh0aGlzLnRvU3RyaW5nKCkpfWludGVyc2VjdCgpe3JldHVybiBCdS50ZXN0KHRoaXMudG9TdHJpbmcoKSl9dG91Y2goKXtyZXR1cm4gWXUudGVzdCh0aGlzLnRvU3RyaW5nKCkpfWluc2lkZSgpe3JldHVybiBXdS50ZXN0KHRoaXMudG9TdHJpbmcoKSl9Y292ZXJlZCgpe3JldHVybiBadS50ZXN0KHRoaXMudG9TdHJpbmcoKSl9fWZ1bmN0aW9uIEVlKGUsdCl7bGV0IG4scj1uZXcgYS5SYXkodCksaT1uZXcgYS5MaW5lKHIucHQsci5ub3JtKTtjb25zdCBzPW5ldyBhLkJveChyLmJveC54bWluLWEuRFBfVE9MLHIuYm94LnltaW4tYS5EUF9UT0wsci5ib3gueG1heCxyLmJveC55bWF4K2EuRFBfVE9MKTtpZihlLmJveC5ub3RfaW50ZXJzZWN0KHMpKXJldHVybiBhLk9VVFNJREU7bGV0IG89ZS5lZGdlcy5zZWFyY2gocyk7aWYoby5sZW5ndGg9PT0wKXJldHVybiBhLk9VVFNJREU7Zm9yKGxldCBmIG9mIG8paWYoZi5zaGFwZS5jb250YWlucyh0KSlyZXR1cm4gYS5CT1VOREFSWTtsZXQgYz1bLi4uZS5mYWNlc10sbD1bXTtmb3IobGV0IGYgb2Ygbylmb3IobGV0IHUgb2Ygci5pbnRlcnNlY3QoZi5zaGFwZSkpe2lmKHUuZXF1YWxUbyh0KSlyZXR1cm4gYS5CT1VOREFSWTtsLnB1c2goe3B0OnUsZWRnZTpmLGZhY2VfaW5kZXg6Yy5pbmRleE9mKGYuZmFjZSl9KX1sLnNvcnQoKGYsdSk9PmJvKGYucHQueCx1LnB0LngpPy0xOk9vKGYucHQueCx1LnB0LngpPzE6Zi5mYWNlX2luZGV4PHUuZmFjZV9pbmRleD8tMTpmLmZhY2VfaW5kZXg+dS5mYWNlX2luZGV4PzE6Zi5lZGdlLmFyY19sZW5ndGg8dS5lZGdlLmFyY19sZW5ndGg/LTE6Zi5lZGdlLmFyY19sZW5ndGg+dS5lZGdlLmFyY19sZW5ndGg/MTowKTtsZXQgaD0wO2ZvcihsZXQgZj0wO2Y8bC5sZW5ndGg7ZisrKXtsZXQgdT1sW2ZdO2lmKHUucHQuZXF1YWxUbyh1LmVkZ2Uuc2hhcGUuc3RhcnQpKXtpZihmPjAmJnUucHQuZXF1YWxUbyhsW2YtMV0ucHQpJiZ1LmZhY2VfaW5kZXg9PT1sW2YtMV0uZmFjZV9pbmRleCYmdS5lZGdlLnByZXY9PT1sW2YtMV0uZWRnZSljb250aW51ZTtsZXQgZD11LmVkZ2UucHJldjtmb3IoO09yKGQubGVuZ3RoKTspZD1kLnByZXY7bGV0IGc9ZC5zaGFwZS50YW5nZW50SW5FbmQoKSxtPXUucHQudHJhbnNsYXRlKGcpLF89dS5lZGdlLnNoYXBlLnRhbmdlbnRJblN0YXJ0KCkscD11LnB0LnRyYW5zbGF0ZShfKSxNPW0ubGVmdFRvKGkpLEE9cC5sZWZ0VG8oaSk7KE0mJiFBfHwhTSYmQSkmJmgrK31lbHNlIGlmKHUucHQuZXF1YWxUbyh1LmVkZ2Uuc2hhcGUuZW5kKSl7aWYoZj4wJiZ1LnB0LmVxdWFsVG8obFtmLTFdLnB0KSYmdS5mYWNlX2luZGV4PT09bFtmLTFdLmZhY2VfaW5kZXgmJnUuZWRnZS5uZXh0PT09bFtmLTFdLmVkZ2UpY29udGludWU7bGV0IGQ9dS5lZGdlLm5leHQ7Zm9yKDtPcihkLmxlbmd0aCk7KWQ9ZC5uZXh0O2xldCBnPWQuc2hhcGUudGFuZ2VudEluU3RhcnQoKSxtPXUucHQudHJhbnNsYXRlKGcpLF89dS5lZGdlLnNoYXBlLnRhbmdlbnRJbkVuZCgpLHA9dS5wdC50cmFuc2xhdGUoXyksTT1tLmxlZnRUbyhpKSxBPXAubGVmdFRvKGkpOyhNJiYhQXx8IU0mJkEpJiZoKyt9ZWxzZSBpZih1LmVkZ2Uuc2hhcGUgaW5zdGFuY2VvZiBhLlNlZ21lbnQpaCsrO2Vsc2V7bGV0IGQ9dS5lZGdlLnNoYXBlLmJveDt6dCh1LnB0LnksZC55bWluKXx8enQodS5wdC55LGQueW1heCl8fGgrK319cmV0dXJuIG49aCUyPT09MT91bjpUbyxufWZ1bmN0aW9uIEd1KGUsdCl7cmV0dXJuIG5lKGUsdCkuZXF1YWwoKX1mdW5jdGlvbiBIbyhlLHQpe3JldHVybiBuZShlLHQpLmludGVyc2VjdCgpfWZ1bmN0aW9uIFh1KGUsdCl7cmV0dXJuIG5lKGUsdCkudG91Y2goKX1mdW5jdGlvbiBqdShlLHQpe3JldHVybiFIbyhlLHQpfWZ1bmN0aW9uIHRjKGUsdCl7cmV0dXJuIG5lKGUsdCkuaW5zaWRlKCl9ZnVuY3Rpb24gZWMoZSx0KXtyZXR1cm4gbmUoZSx0KS5jb3ZlcmVkKCl9ZnVuY3Rpb24gUXUoZSx0KXtyZXR1cm4gdGModCxlKX1mdW5jdGlvbiBuYyhlLHQpe3JldHVybiBlYyh0LGUpfWZ1bmN0aW9uIG5lKGUsdCl7aWYoZSBpbnN0YW5jZW9mIGEuTGluZSYmdCBpbnN0YW5jZW9mIGEuTGluZSlyZXR1cm4gS3UoZSx0KTtpZihlIGluc3RhbmNlb2YgYS5MaW5lJiZ0IGluc3RhbmNlb2YgYS5DaXJjbGUpcmV0dXJuIEp1KGUsdCk7aWYoZSBpbnN0YW5jZW9mIGEuTGluZSYmdCBpbnN0YW5jZW9mIGEuQm94KXJldHVybiBIdShlLHQpO2lmKGUgaW5zdGFuY2VvZiBhLkxpbmUmJnQgaW5zdGFuY2VvZiBhLlBvbHlnb24pcmV0dXJuIHQwKGUsdCk7aWYoKGUgaW5zdGFuY2VvZiBhLlNlZ21lbnR8fGUgaW5zdGFuY2VvZiBhLkFyYykmJnQgaW5zdGFuY2VvZiBhLlBvbHlnb24pcmV0dXJuIHJjKGUsdCk7aWYoKGUgaW5zdGFuY2VvZiBhLlNlZ21lbnR8fGUgaW5zdGFuY2VvZiBhLkFyYykmJih0IGluc3RhbmNlb2YgYS5DaXJjbGV8fHQgaW5zdGFuY2VvZiBhLkJveCkpcmV0dXJuIHJjKGUsbmV3IGEuUG9seWdvbih0KSk7aWYoZSBpbnN0YW5jZW9mIGEuUG9seWdvbiYmdCBpbnN0YW5jZW9mIGEuUG9seWdvbilyZXR1cm4geW4oZSx0KTtpZigoZSBpbnN0YW5jZW9mIGEuQ2lyY2xlfHxlIGluc3RhbmNlb2YgYS5Cb3gpJiYodCBpbnN0YW5jZW9mIGEuQ2lyY2xlfHx0IGluc3RhbmNlb2YgYS5Cb3gpKXJldHVybiB5bihuZXcgYS5Qb2x5Z29uKGUpLG5ldyBhLlBvbHlnb24odCkpO2lmKChlIGluc3RhbmNlb2YgYS5DaXJjbGV8fGUgaW5zdGFuY2VvZiBhLkJveCkmJnQgaW5zdGFuY2VvZiBhLlBvbHlnb24pcmV0dXJuIHluKG5ldyBhLlBvbHlnb24oZSksdCk7aWYoZSBpbnN0YW5jZW9mIGEuUG9seWdvbiYmKHQgaW5zdGFuY2VvZiBhLkNpcmNsZXx8dCBpbnN0YW5jZW9mIGEuQm94KSlyZXR1cm4geW4oZSxuZXcgYS5Qb2x5Z29uKHQpKX1mdW5jdGlvbiBLdShlLHQpe2xldCBuPW5ldyBlZSxyPWp0KGUsdCk7cmV0dXJuIHIubGVuZ3RoPT09MD9lLmNvbnRhaW5zKHQucHQpJiZ0LmNvbnRhaW5zKGUucHQpPyhuLkkyST1bZV0sbi5JMkU9W10sbi5FMkk9W10pOihuLkkyST1bXSxuLkkyRT1bZV0sbi5FMkk9W3RdKToobi5JMkk9cixuLkkyRT1lLnNwbGl0KHIpLG4uRTJJPXQuc3BsaXQocikpLG59ZnVuY3Rpb24gSnUoZSx0KXtsZXQgbj1uZXcgZWUscj1rdChlLHQpO2lmKHIubGVuZ3RoPT09MCluLkkyST1bXSxuLkkyQj1bXSxuLkkyRT1bZV0sbi5FMkk9W3RdO2Vsc2UgaWYoci5sZW5ndGg9PT0xKW4uSTJJPVtdLG4uSTJCPXIsbi5JMkU9ZS5zcGxpdChyKSxuLkUyST1bdF07ZWxzZXtsZXQgaT1uZXcgRnQoW2VdKSxzPWUuc29ydFBvaW50cyhyKTtpLnNwbGl0KHMpO2xldCBvPWkudG9TaGFwZXMoKTtuLkkyST1bb1sxXV0sbi5JMkI9cyxuLkkyRT1bb1swXSxvWzJdXSxuLkUyST1uZXcgYS5Qb2x5Z29uKFt0LnRvQXJjKCldKS5jdXRXaXRoTGluZShlKX1yZXR1cm4gbn1mdW5jdGlvbiBIdShlLHQpe2xldCBuPW5ldyBlZSxyPVF0KGUsdCk7aWYoci5sZW5ndGg9PT0wKW4uSTJJPVtdLG4uSTJCPVtdLG4uSTJFPVtlXSxuLkUyST1bdF07ZWxzZSBpZihyLmxlbmd0aD09PTEpbi5JMkk9W10sbi5JMkI9cixuLkkyRT1lLnNwbGl0KHIpLG4uRTJJPVt0XTtlbHNle2xldCBpPW5ldyBGdChbZV0pLHM9ZS5zb3J0UG9pbnRzKHIpO2kuc3BsaXQocyk7bGV0IG89aS50b1NoYXBlcygpO3QudG9TZWdtZW50cygpLnNvbWUoYz0+Yy5jb250YWlucyhyWzBdKSYmYy5jb250YWlucyhyWzFdKSk/KG4uSTJJPVtdLG4uSTJCPVtvWzFdXSxuLkkyRT1bb1swXSxvWzJdXSxuLkUyST1bdF0pOihuLkkyST1bb1sxXV0sbi5JMkI9cyxuLkkyRT1bb1swXSxvWzJdXSxuLkUyST1uZXcgYS5Qb2x5Z29uKHQudG9TZWdtZW50cygpKS5jdXRXaXRoTGluZShlKSl9cmV0dXJuIG59ZnVuY3Rpb24gdDAoZSx0KXtsZXQgbj1uZXcgZWUscj14ZShlLHQpLGk9bmV3IEZ0KFtlXSkscz1yLmxlbmd0aD4wP3Iuc2xpY2UoKTplLnNvcnRQb2ludHMocik7cmV0dXJuIGkuc3BsaXQocyksWy4uLmldLmZvckVhY2gobz0+by5zZXRJbmNsdXNpb24odCkpLG4uSTJJPVsuLi5pXS5maWx0ZXIobz0+by5idj09PWEuSU5TSURFKS5tYXAobz0+by5zaGFwZSksbi5JMkI9Wy4uLmldLnNsaWNlKDEpLm1hcChvPT5vLmJ2PT09YS5CT1VOREFSWT9vLnNoYXBlOm8uc2hhcGUuc3RhcnQpLG4uSTJFPVsuLi5pXS5maWx0ZXIobz0+by5idj09PWEuT1VUU0lERSkubWFwKG89Pm8uc2hhcGUpLG4uRTJJPXQuY3V0V2l0aExpbmUoZSksbn1mdW5jdGlvbiByYyhlLHQpe2xldCBuPW5ldyBlZSxyPWJ1KGUsdCksaT1yLmxlbmd0aD4wP3Iuc2xpY2UoKTplLnNvcnRQb2ludHMocikscz1uZXcgRnQoW2VdKTtzLnNwbGl0KGkpLFsuLi5zXS5mb3JFYWNoKG89Pm8uc2V0SW5jbHVzaW9uKHQpKSxuLkkyST1bLi4uc10uZmlsdGVyKG89Pm8uYnY9PT1hLklOU0lERSkubWFwKG89Pm8uc2hhcGUpLG4uSTJCPVsuLi5zXS5zbGljZSgxKS5tYXAobz0+by5idj09PWEuQk9VTkRBUlk/by5zaGFwZTpvLnNoYXBlLnN0YXJ0KSxuLkkyRT1bLi4uc10uZmlsdGVyKG89Pm8uYnY9PT1hLk9VVFNJREUpLm1hcChvPT5vLnNoYXBlKSxuLkIyST1bXSxuLkIyQj1bXSxuLkIyRT1bXTtmb3IobGV0IG8gb2ZbZS5zdGFydCxlLmVuZF0pc3dpdGNoKEVlKHQsbykpe2Nhc2UgYS5JTlNJREU6bi5CMkkucHVzaChvKTticmVhaztjYXNlIGEuQk9VTkRBUlk6bi5CMkIucHVzaChvKTticmVhaztjYXNlIGEuT1VUU0lERTpuLkIyRS5wdXNoKG8pO2JyZWFrfXJldHVybiBufWZ1bmN0aW9uIHluKGUsdCl7bGV0IG49bmV3IGVlLFtyLGldPVhvKGUsdCkscz1abyhlLHQpLG89enIoZSx0KSxjPXpyKHQsZSksW2wsaF09R28oZSx0KSxmPSRyKGUsdCksdT0kcih0LGUpO3JldHVybiBuLkkyST1zLmlzRW1wdHkoKT9bXTpbc10sbi5JMkI9aCxuLkkyRT1vLmlzRW1wdHkoKT9bXTpbb10sbi5CMkk9bCxuLkIyQj1yLG4uQjJFPWYsbi5FMkk9Yy5pc0VtcHR5KCk/W106W2NdLG4uRTJCPXUsbn12YXIgZTA9T2JqZWN0LmZyZWV6ZSh7X19wcm90b19fOm51bGwsY29udGFpbjpRdSxjb3ZlcjpuYyxjb3ZlcmVkOmVjLGRpc2pvaW50Omp1LGVxdWFsOkd1LGluc2lkZTp0YyxpbnRlcnNlY3Q6SG8scmVsYXRlOm5lLHRvdWNoOlh1fSk7Y2xhc3MgYXR7Y29uc3RydWN0b3IodD0xLG49MCxyPTAsaT0xLHM9MCxvPTApe3RoaXMuYT10LHRoaXMuYj1uLHRoaXMuYz1yLHRoaXMuZD1pLHRoaXMudHg9cyx0aGlzLnR5PW99Y2xvbmUoKXtyZXR1cm4gbmV3IGF0KHRoaXMuYSx0aGlzLmIsdGhpcy5jLHRoaXMuZCx0aGlzLnR4LHRoaXMudHkpfXRyYW5zZm9ybSh0KXtyZXR1cm5bdFswXSp0aGlzLmErdFsxXSp0aGlzLmMrdGhpcy50eCx0WzBdKnRoaXMuYit0WzFdKnRoaXMuZCt0aGlzLnR5XX1tdWx0aXBseSh0KXtyZXR1cm4gbmV3IGF0KHRoaXMuYSp0LmErdGhpcy5jKnQuYix0aGlzLmIqdC5hK3RoaXMuZCp0LmIsdGhpcy5hKnQuYyt0aGlzLmMqdC5kLHRoaXMuYip0LmMrdGhpcy5kKnQuZCx0aGlzLmEqdC50eCt0aGlzLmMqdC50eSt0aGlzLnR4LHRoaXMuYip0LnR4K3RoaXMuZCp0LnR5K3RoaXMudHkpfXRyYW5zbGF0ZSguLi50KXtsZXQgbixyO2lmKHQubGVuZ3RoPT0xJiYhaXNOYU4odFswXS54KSYmIWlzTmFOKHRbMF0ueSkpbj10WzBdLngscj10WzBdLnk7ZWxzZSBpZih0Lmxlbmd0aD09PTImJnR5cGVvZiB0WzBdPT0ibnVtYmVyIiYmdHlwZW9mIHRbMV09PSJudW1iZXIiKW49dFswXSxyPXRbMV07ZWxzZSB0aHJvdyBELklMTEVHQUxfUEFSQU1FVEVSUztyZXR1cm4gdGhpcy5tdWx0aXBseShuZXcgYXQoMSwwLDAsMSxuLHIpKX1yb3RhdGUodCxuPTAscj0wKXtsZXQgaT1NYXRoLmNvcyh0KSxzPU1hdGguc2luKHQpO3JldHVybiB0aGlzLnRyYW5zbGF0ZShuLHIpLm11bHRpcGx5KG5ldyBhdChpLHMsLXMsaSwwLDApKS50cmFuc2xhdGUoLW4sLXIpfXNjYWxlKHQsbil7cmV0dXJuIHRoaXMubXVsdGlwbHkobmV3IGF0KHQsMCwwLG4sMCwwKSl9ZXF1YWxUbyh0KXtyZXR1cm4hKCFhLlV0aWxzLkVRKHRoaXMudHgsdC50eCl8fCFhLlV0aWxzLkVRKHRoaXMudHksdC50eSl8fCFhLlV0aWxzLkVRKHRoaXMuYSx0LmEpfHwhYS5VdGlscy5FUSh0aGlzLmIsdC5iKXx8IWEuVXRpbHMuRVEodGhpcy5jLHQuYyl8fCFhLlV0aWxzLkVRKHRoaXMuZCx0LmQpKX19YS5NYXRyaXg9YXQ7Y29uc3QgbjA9KC4uLmUpPT5uZXcgYS5NYXRyaXgoLi4uZSk7YS5tYXRyaXg9bjA7Y29uc3QgcjA9Y2xhc3MgSHJ7Y29uc3RydWN0b3IodCxuKXt0aGlzLmxvdz10LHRoaXMuaGlnaD1ufWNsb25lKCl7cmV0dXJuIG5ldyBIcih0aGlzLmxvdyx0aGlzLmhpZ2gpfWdldCBtYXgoKXtyZXR1cm4gdGhpcy5jbG9uZSgpfWxlc3NfdGhhbih0KXtyZXR1cm4gdGhpcy5sb3c8dC5sb3d8fHRoaXMubG93PT10LmxvdyYmdGhpcy5oaWdoPHQuaGlnaH1lcXVhbF90byh0KXtyZXR1cm4gdGhpcy5sb3c9PXQubG93JiZ0aGlzLmhpZ2g9PXQuaGlnaH1pbnRlcnNlY3QodCl7cmV0dXJuIXRoaXMubm90X2ludGVyc2VjdCh0KX1ub3RfaW50ZXJzZWN0KHQpe3JldHVybiB0aGlzLmhpZ2g8dC5sb3d8fHQuaGlnaDx0aGlzLmxvd31tZXJnZSh0KXtyZXR1cm4gbmV3IEhyKHRoaXMubG93PT09dm9pZCAwP3QubG93Ok1hdGgubWluKHRoaXMubG93LHQubG93KSx0aGlzLmhpZ2g9PT12b2lkIDA/dC5oaWdoOk1hdGgubWF4KHRoaXMuaGlnaCx0LmhpZ2gpKX1vdXRwdXQoKXtyZXR1cm5bdGhpcy5sb3csdGhpcy5oaWdoXX1zdGF0aWMgY29tcGFyYWJsZV9tYXgodCxuKXtyZXR1cm4gdC5tZXJnZShuKX1zdGF0aWMgY29tcGFyYWJsZV9sZXNzX3RoYW4odCxuKXtyZXR1cm4gdDxufX0sSj0wLCQ9MTtjbGFzcyByZXtjb25zdHJ1Y3Rvcih0PXZvaWQgMCxuPXZvaWQgMCxyPW51bGwsaT1udWxsLHM9bnVsbCxvPSQpe3RoaXMubGVmdD1yLHRoaXMucmlnaHQ9aSx0aGlzLnBhcmVudD1zLHRoaXMuY29sb3I9byx0aGlzLml0ZW09e2tleTp0LHZhbHVlOm59LHQmJnQgaW5zdGFuY2VvZiBBcnJheSYmdC5sZW5ndGg9PTImJiFOdW1iZXIuaXNOYU4odFswXSkmJiFOdW1iZXIuaXNOYU4odFsxXSkmJih0aGlzLml0ZW0ua2V5PW5ldyByMChNYXRoLm1pbih0WzBdLHRbMV0pLE1hdGgubWF4KHRbMF0sdFsxXSkpKSx0aGlzLm1heD10aGlzLml0ZW0ua2V5P3RoaXMuaXRlbS5rZXkubWF4OnZvaWQgMH1pc05pbCgpe3JldHVybiB0aGlzLml0ZW0ua2V5PT09dm9pZCAwJiZ0aGlzLml0ZW0udmFsdWU9PT12b2lkIDAmJnRoaXMubGVmdD09PW51bGwmJnRoaXMucmlnaHQ9PT1udWxsJiZ0aGlzLmNvbG9yPT09JH1fdmFsdWVfbGVzc190aGFuKHQpe3JldHVybiB0aGlzLml0ZW0udmFsdWUmJnQuaXRlbS52YWx1ZSYmdGhpcy5pdGVtLnZhbHVlLmxlc3NfdGhhbj90aGlzLml0ZW0udmFsdWUubGVzc190aGFuKHQuaXRlbS52YWx1ZSk6dGhpcy5pdGVtLnZhbHVlPHQuaXRlbS52YWx1ZX1sZXNzX3RoYW4odCl7cmV0dXJuIHRoaXMuaXRlbS52YWx1ZT09PXRoaXMuaXRlbS5rZXkmJnQuaXRlbS52YWx1ZT09PXQuaXRlbS5rZXk/dGhpcy5pdGVtLmtleS5sZXNzX3RoYW4odC5pdGVtLmtleSk6dGhpcy5pdGVtLmtleS5sZXNzX3RoYW4odC5pdGVtLmtleSl8fHRoaXMuaXRlbS5rZXkuZXF1YWxfdG8odC5pdGVtLmtleSkmJnRoaXMuX3ZhbHVlX2xlc3NfdGhhbih0KX1fdmFsdWVfZXF1YWwodCl7cmV0dXJuIHRoaXMuaXRlbS52YWx1ZSYmdC5pdGVtLnZhbHVlJiZ0aGlzLml0ZW0udmFsdWUuZXF1YWxfdG8/dGhpcy5pdGVtLnZhbHVlLmVxdWFsX3RvKHQuaXRlbS52YWx1ZSk6dGhpcy5pdGVtLnZhbHVlPT10Lml0ZW0udmFsdWV9ZXF1YWxfdG8odCl7cmV0dXJuIHRoaXMuaXRlbS52YWx1ZT09PXRoaXMuaXRlbS5rZXkmJnQuaXRlbS52YWx1ZT09PXQuaXRlbS5rZXk/dGhpcy5pdGVtLmtleS5lcXVhbF90byh0Lml0ZW0ua2V5KTp0aGlzLml0ZW0ua2V5LmVxdWFsX3RvKHQuaXRlbS5rZXkpJiZ0aGlzLl92YWx1ZV9lcXVhbCh0KX1pbnRlcnNlY3QodCl7cmV0dXJuIHRoaXMuaXRlbS5rZXkuaW50ZXJzZWN0KHQuaXRlbS5rZXkpfWNvcHlfZGF0YSh0KXt0aGlzLml0ZW0ua2V5PXQuaXRlbS5rZXksdGhpcy5pdGVtLnZhbHVlPXQuaXRlbS52YWx1ZX11cGRhdGVfbWF4KCl7aWYodGhpcy5tYXg9dGhpcy5pdGVtLmtleT90aGlzLml0ZW0ua2V5Lm1heDp2b2lkIDAsdGhpcy5yaWdodCYmdGhpcy5yaWdodC5tYXgpe2NvbnN0IHQ9dGhpcy5pdGVtLmtleS5jb25zdHJ1Y3Rvci5jb21wYXJhYmxlX21heDt0aGlzLm1heD10KHRoaXMubWF4LHRoaXMucmlnaHQubWF4KX1pZih0aGlzLmxlZnQmJnRoaXMubGVmdC5tYXgpe2NvbnN0IHQ9dGhpcy5pdGVtLmtleS5jb25zdHJ1Y3Rvci5jb21wYXJhYmxlX21heDt0aGlzLm1heD10KHRoaXMubWF4LHRoaXMubGVmdC5tYXgpfX1ub3RfaW50ZXJzZWN0X2xlZnRfc3VidHJlZSh0KXtjb25zdCBuPXRoaXMuaXRlbS5rZXkuY29uc3RydWN0b3IuY29tcGFyYWJsZV9sZXNzX3RoYW47bGV0IHI9dGhpcy5sZWZ0Lm1heC5oaWdoIT09dm9pZCAwP3RoaXMubGVmdC5tYXguaGlnaDp0aGlzLmxlZnQubWF4O3JldHVybiBuKHIsdC5pdGVtLmtleS5sb3cpfW5vdF9pbnRlcnNlY3RfcmlnaHRfc3VidHJlZSh0KXtjb25zdCBuPXRoaXMuaXRlbS5rZXkuY29uc3RydWN0b3IuY29tcGFyYWJsZV9sZXNzX3RoYW47bGV0IHI9dGhpcy5yaWdodC5tYXgubG93IT09dm9pZCAwP3RoaXMucmlnaHQubWF4Lmxvdzp0aGlzLnJpZ2h0Lml0ZW0ua2V5LmxvdztyZXR1cm4gbih0Lml0ZW0ua2V5LmhpZ2gscil9fWNsYXNzIE9le2NvbnN0cnVjdG9yKCl7dGhpcy5yb290PW51bGwsdGhpcy5uaWxfbm9kZT1uZXcgcmV9Z2V0IHNpemUoKXtsZXQgdD0wO3JldHVybiB0aGlzLnRyZWVfd2Fsayh0aGlzLnJvb3QsKCk9PnQrKyksdH1nZXQga2V5cygpe2xldCB0PVtdO3JldHVybiB0aGlzLnRyZWVfd2Fsayh0aGlzLnJvb3Qsbj0+dC5wdXNoKG4uaXRlbS5rZXkub3V0cHV0P24uaXRlbS5rZXkub3V0cHV0KCk6bi5pdGVtLmtleSkpLHR9Z2V0IHZhbHVlcygpe2xldCB0PVtdO3JldHVybiB0aGlzLnRyZWVfd2Fsayh0aGlzLnJvb3Qsbj0+dC5wdXNoKG4uaXRlbS52YWx1ZSkpLHR9Z2V0IGl0ZW1zKCl7bGV0IHQ9W107cmV0dXJuIHRoaXMudHJlZV93YWxrKHRoaXMucm9vdCxuPT50LnB1c2goe2tleTpuLml0ZW0ua2V5Lm91dHB1dD9uLml0ZW0ua2V5Lm91dHB1dCgpOm4uaXRlbS5rZXksdmFsdWU6bi5pdGVtLnZhbHVlfSkpLHR9aXNFbXB0eSgpe3JldHVybiB0aGlzLnJvb3Q9PW51bGx8fHRoaXMucm9vdD09dGhpcy5uaWxfbm9kZX1jbGVhcigpe3RoaXMucm9vdD1udWxsfWluc2VydCh0LG49dCl7aWYodD09PXZvaWQgMClyZXR1cm47bGV0IHI9bmV3IHJlKHQsbix0aGlzLm5pbF9ub2RlLHRoaXMubmlsX25vZGUsbnVsbCxKKTtyZXR1cm4gdGhpcy50cmVlX2luc2VydChyKSx0aGlzLnJlY2FsY19tYXgocikscn1leGlzdCh0LG49dCl7bGV0IHI9bmV3IHJlKHQsbik7cmV0dXJuISF0aGlzLnRyZWVfc2VhcmNoKHRoaXMucm9vdCxyKX1yZW1vdmUodCxuPXQpe2xldCByPW5ldyByZSh0LG4pLGk9dGhpcy50cmVlX3NlYXJjaCh0aGlzLnJvb3Qscik7cmV0dXJuIGkmJnRoaXMudHJlZV9kZWxldGUoaSksaX1zZWFyY2godCxuPShyLGkpPT5yPT09aT9pLm91dHB1dCgpOnIpe2xldCByPW5ldyByZSh0KSxpPVtdO3JldHVybiB0aGlzLnRyZWVfc2VhcmNoX2ludGVydmFsKHRoaXMucm9vdCxyLGkpLGkubWFwKHM9Pm4ocy5pdGVtLnZhbHVlLHMuaXRlbS5rZXkpKX1pbnRlcnNlY3RfYW55KHQpe2xldCBuPW5ldyByZSh0KTtyZXR1cm4gdGhpcy50cmVlX2ZpbmRfYW55X2ludGVydmFsKHRoaXMucm9vdCxuKX1mb3JFYWNoKHQpe3RoaXMudHJlZV93YWxrKHRoaXMucm9vdCxuPT50KG4uaXRlbS5rZXksbi5pdGVtLnZhbHVlKSl9bWFwKHQpe2NvbnN0IG49bmV3IE9lO3JldHVybiB0aGlzLnRyZWVfd2Fsayh0aGlzLnJvb3Qscj0+bi5pbnNlcnQoci5pdGVtLmtleSx0KHIuaXRlbS52YWx1ZSxyLml0ZW0ua2V5KSkpLG59cmVjYWxjX21heCh0KXtsZXQgbj10O2Zvcig7bi5wYXJlbnQhPW51bGw7KW4ucGFyZW50LnVwZGF0ZV9tYXgoKSxuPW4ucGFyZW50fXRyZWVfaW5zZXJ0KHQpe2xldCBuPXRoaXMucm9vdCxyPW51bGw7aWYodGhpcy5yb290PT1udWxsfHx0aGlzLnJvb3Q9PXRoaXMubmlsX25vZGUpdGhpcy5yb290PXQ7ZWxzZXtmb3IoO24hPXRoaXMubmlsX25vZGU7KXI9bix0Lmxlc3NfdGhhbihuKT9uPW4ubGVmdDpuPW4ucmlnaHQ7dC5wYXJlbnQ9cix0Lmxlc3NfdGhhbihyKT9yLmxlZnQ9dDpyLnJpZ2h0PXR9dGhpcy5pbnNlcnRfZml4dXAodCl9aW5zZXJ0X2ZpeHVwKHQpe2xldCBuLHI7Zm9yKG49dDtuIT10aGlzLnJvb3QmJm4ucGFyZW50LmNvbG9yPT1KOyluLnBhcmVudD09bi5wYXJlbnQucGFyZW50LmxlZnQ/KHI9bi5wYXJlbnQucGFyZW50LnJpZ2h0LHIuY29sb3I9PUo/KG4ucGFyZW50LmNvbG9yPSQsci5jb2xvcj0kLG4ucGFyZW50LnBhcmVudC5jb2xvcj1KLG49bi5wYXJlbnQucGFyZW50KToobj09bi5wYXJlbnQucmlnaHQmJihuPW4ucGFyZW50LHRoaXMucm90YXRlX2xlZnQobikpLG4ucGFyZW50LmNvbG9yPSQsbi5wYXJlbnQucGFyZW50LmNvbG9yPUosdGhpcy5yb3RhdGVfcmlnaHQobi5wYXJlbnQucGFyZW50KSkpOihyPW4ucGFyZW50LnBhcmVudC5sZWZ0LHIuY29sb3I9PUo/KG4ucGFyZW50LmNvbG9yPSQsci5jb2xvcj0kLG4ucGFyZW50LnBhcmVudC5jb2xvcj1KLG49bi5wYXJlbnQucGFyZW50KToobj09bi5wYXJlbnQubGVmdCYmKG49bi5wYXJlbnQsdGhpcy5yb3RhdGVfcmlnaHQobikpLG4ucGFyZW50LmNvbG9yPSQsbi5wYXJlbnQucGFyZW50LmNvbG9yPUosdGhpcy5yb3RhdGVfbGVmdChuLnBhcmVudC5wYXJlbnQpKSk7dGhpcy5yb290LmNvbG9yPSR9dHJlZV9kZWxldGUodCl7bGV0IG4scjt0LmxlZnQ9PXRoaXMubmlsX25vZGV8fHQucmlnaHQ9PXRoaXMubmlsX25vZGU/bj10Om49dGhpcy50cmVlX3N1Y2Nlc3Nvcih0KSxuLmxlZnQhPXRoaXMubmlsX25vZGU/cj1uLmxlZnQ6cj1uLnJpZ2h0LHIucGFyZW50PW4ucGFyZW50LG49PXRoaXMucm9vdD90aGlzLnJvb3Q9cjoobj09bi5wYXJlbnQubGVmdD9uLnBhcmVudC5sZWZ0PXI6bi5wYXJlbnQucmlnaHQ9cixuLnBhcmVudC51cGRhdGVfbWF4KCkpLHRoaXMucmVjYWxjX21heChyKSxuIT10JiYodC5jb3B5X2RhdGEobiksdC51cGRhdGVfbWF4KCksdGhpcy5yZWNhbGNfbWF4KHQpKSxuLmNvbG9yPT0kJiZ0aGlzLmRlbGV0ZV9maXh1cChyKX1kZWxldGVfZml4dXAodCl7bGV0IG49dCxyO2Zvcig7biE9dGhpcy5yb290JiZuLnBhcmVudCE9bnVsbCYmbi5jb2xvcj09JDspbj09bi5wYXJlbnQubGVmdD8ocj1uLnBhcmVudC5yaWdodCxyLmNvbG9yPT1KJiYoci5jb2xvcj0kLG4ucGFyZW50LmNvbG9yPUosdGhpcy5yb3RhdGVfbGVmdChuLnBhcmVudCkscj1uLnBhcmVudC5yaWdodCksci5sZWZ0LmNvbG9yPT0kJiZyLnJpZ2h0LmNvbG9yPT0kPyhyLmNvbG9yPUosbj1uLnBhcmVudCk6KHIucmlnaHQuY29sb3I9PSQmJihyLmNvbG9yPUosci5sZWZ0LmNvbG9yPSQsdGhpcy5yb3RhdGVfcmlnaHQocikscj1uLnBhcmVudC5yaWdodCksci5jb2xvcj1uLnBhcmVudC5jb2xvcixuLnBhcmVudC5jb2xvcj0kLHIucmlnaHQuY29sb3I9JCx0aGlzLnJvdGF0ZV9sZWZ0KG4ucGFyZW50KSxuPXRoaXMucm9vdCkpOihyPW4ucGFyZW50LmxlZnQsci5jb2xvcj09SiYmKHIuY29sb3I9JCxuLnBhcmVudC5jb2xvcj1KLHRoaXMucm90YXRlX3JpZ2h0KG4ucGFyZW50KSxyPW4ucGFyZW50LmxlZnQpLHIubGVmdC5jb2xvcj09JCYmci5yaWdodC5jb2xvcj09JD8oci5jb2xvcj1KLG49bi5wYXJlbnQpOihyLmxlZnQuY29sb3I9PSQmJihyLmNvbG9yPUosci5yaWdodC5jb2xvcj0kLHRoaXMucm90YXRlX2xlZnQocikscj1uLnBhcmVudC5sZWZ0KSxyLmNvbG9yPW4ucGFyZW50LmNvbG9yLG4ucGFyZW50LmNvbG9yPSQsci5sZWZ0LmNvbG9yPSQsdGhpcy5yb3RhdGVfcmlnaHQobi5wYXJlbnQpLG49dGhpcy5yb290KSk7bi5jb2xvcj0kfXRyZWVfc2VhcmNoKHQsbil7aWYoISh0PT1udWxsfHx0PT10aGlzLm5pbF9ub2RlKSlyZXR1cm4gbi5lcXVhbF90byh0KT90Om4ubGVzc190aGFuKHQpP3RoaXMudHJlZV9zZWFyY2godC5sZWZ0LG4pOnRoaXMudHJlZV9zZWFyY2godC5yaWdodCxuKX10cmVlX3NlYXJjaF9pbnRlcnZhbCh0LG4scil7dCE9bnVsbCYmdCE9dGhpcy5uaWxfbm9kZSYmKHQubGVmdCE9dGhpcy5uaWxfbm9kZSYmIXQubm90X2ludGVyc2VjdF9sZWZ0X3N1YnRyZWUobikmJnRoaXMudHJlZV9zZWFyY2hfaW50ZXJ2YWwodC5sZWZ0LG4sciksdC5pbnRlcnNlY3QobikmJnIucHVzaCh0KSx0LnJpZ2h0IT10aGlzLm5pbF9ub2RlJiYhdC5ub3RfaW50ZXJzZWN0X3JpZ2h0X3N1YnRyZWUobikmJnRoaXMudHJlZV9zZWFyY2hfaW50ZXJ2YWwodC5yaWdodCxuLHIpKX10cmVlX2ZpbmRfYW55X2ludGVydmFsKHQsbil7bGV0IHI9ITE7cmV0dXJuIHQhPW51bGwmJnQhPXRoaXMubmlsX25vZGUmJih0LmxlZnQhPXRoaXMubmlsX25vZGUmJiF0Lm5vdF9pbnRlcnNlY3RfbGVmdF9zdWJ0cmVlKG4pJiYocj10aGlzLnRyZWVfZmluZF9hbnlfaW50ZXJ2YWwodC5sZWZ0LG4pKSxyfHwocj10LmludGVyc2VjdChuKSksIXImJnQucmlnaHQhPXRoaXMubmlsX25vZGUmJiF0Lm5vdF9pbnRlcnNlY3RfcmlnaHRfc3VidHJlZShuKSYmKHI9dGhpcy50cmVlX2ZpbmRfYW55X2ludGVydmFsKHQucmlnaHQsbikpKSxyfWxvY2FsX21pbmltdW0odCl7bGV0IG49dDtmb3IoO24ubGVmdCE9bnVsbCYmbi5sZWZ0IT10aGlzLm5pbF9ub2RlOyluPW4ubGVmdDtyZXR1cm4gbn1sb2NhbF9tYXhpbXVtKHQpe2xldCBuPXQ7Zm9yKDtuLnJpZ2h0IT1udWxsJiZuLnJpZ2h0IT10aGlzLm5pbF9ub2RlOyluPW4ucmlnaHQ7cmV0dXJuIG59dHJlZV9zdWNjZXNzb3IodCl7bGV0IG4scixpO2lmKHQucmlnaHQhPXRoaXMubmlsX25vZGUpbj10aGlzLmxvY2FsX21pbmltdW0odC5yaWdodCk7ZWxzZXtmb3Iocj10LGk9dC5wYXJlbnQ7aSE9bnVsbCYmaS5yaWdodD09cjspcj1pLGk9aS5wYXJlbnQ7bj1pfXJldHVybiBufXJvdGF0ZV9sZWZ0KHQpe2xldCBuPXQucmlnaHQ7dC5yaWdodD1uLmxlZnQsbi5sZWZ0IT10aGlzLm5pbF9ub2RlJiYobi5sZWZ0LnBhcmVudD10KSxuLnBhcmVudD10LnBhcmVudCx0PT10aGlzLnJvb3Q/dGhpcy5yb290PW46dD09dC5wYXJlbnQubGVmdD90LnBhcmVudC5sZWZ0PW46dC5wYXJlbnQucmlnaHQ9bixuLmxlZnQ9dCx0LnBhcmVudD1uLHQhPW51bGwmJnQhPXRoaXMubmlsX25vZGUmJnQudXBkYXRlX21heCgpLG49dC5wYXJlbnQsbiE9bnVsbCYmbiE9dGhpcy5uaWxfbm9kZSYmbi51cGRhdGVfbWF4KCl9cm90YXRlX3JpZ2h0KHQpe2xldCBuPXQubGVmdDt0LmxlZnQ9bi5yaWdodCxuLnJpZ2h0IT10aGlzLm5pbF9ub2RlJiYobi5yaWdodC5wYXJlbnQ9dCksbi5wYXJlbnQ9dC5wYXJlbnQsdD09dGhpcy5yb290P3RoaXMucm9vdD1uOnQ9PXQucGFyZW50LmxlZnQ/dC5wYXJlbnQubGVmdD1uOnQucGFyZW50LnJpZ2h0PW4sbi5yaWdodD10LHQucGFyZW50PW4sdCE9bnVsbCYmdCE9dGhpcy5uaWxfbm9kZSYmdC51cGRhdGVfbWF4KCksbj10LnBhcmVudCxuIT1udWxsJiZuIT10aGlzLm5pbF9ub2RlJiZuLnVwZGF0ZV9tYXgoKX10cmVlX3dhbGsodCxuKXt0IT1udWxsJiZ0IT10aGlzLm5pbF9ub2RlJiYodGhpcy50cmVlX3dhbGsodC5sZWZ0LG4pLG4odCksdGhpcy50cmVlX3dhbGsodC5yaWdodCxuKSl9dGVzdFJlZEJsYWNrUHJvcGVydHkoKXtsZXQgdD0hMDtyZXR1cm4gdGhpcy50cmVlX3dhbGsodGhpcy5yb290LGZ1bmN0aW9uKG4pe24uY29sb3I9PUomJihuLmxlZnQuY29sb3I9PSQmJm4ucmlnaHQuY29sb3I9PSR8fCh0PSExKSl9KSx0fXRlc3RCbGFja0hlaWdodFByb3BlcnR5KHQpe2xldCBuPTAscj0wLGk9MDtpZih0LmNvbG9yPT0kJiZuKyssdC5sZWZ0IT10aGlzLm5pbF9ub2RlP3I9dGhpcy50ZXN0QmxhY2tIZWlnaHRQcm9wZXJ0eSh0LmxlZnQpOnI9MSx0LnJpZ2h0IT10aGlzLm5pbF9ub2RlP2k9dGhpcy50ZXN0QmxhY2tIZWlnaHRQcm9wZXJ0eSh0LnJpZ2h0KTppPTEsciE9aSl0aHJvdyBuZXcgRXJyb3IoIlJlZC1ibGFjayBoZWlnaHQgcHJvcGVydHkgdmlvbGF0ZWQiKTtyZXR1cm4gbis9cixufX1jbGFzcyBpMCBleHRlbmRzIFNldHtjb25zdHJ1Y3Rvcih0KXtzdXBlcih0KSx0aGlzLmluZGV4PW5ldyBPZSx0aGlzLmZvckVhY2gobj0+dGhpcy5pbmRleC5pbnNlcnQobikpfWFkZCh0KXtsZXQgbj10aGlzLnNpemU7Y29uc3R7a2V5OnIsdmFsdWU6aX09dCxzPXJ8fHQuYm94LG89aXx8dDtyZXR1cm4gc3VwZXIuYWRkKG8pLHRoaXMuc2l6ZT5uJiZ0aGlzLmluZGV4Lmluc2VydChzLG8pLHRoaXN9ZGVsZXRlKHQpe2NvbnN0e2tleTpuLHZhbHVlOnJ9PXQsaT1ufHx0LmJveCxzPXJ8fHQ7bGV0IG89c3VwZXIuZGVsZXRlKHMpO3JldHVybiBvJiZ0aGlzLmluZGV4LnJlbW92ZShpLHMpLG99Y2xlYXIoKXtzdXBlci5jbGVhcigpLHRoaXMuaW5kZXg9bmV3IE9lfXNlYXJjaCh0KXtyZXR1cm4gdGhpcy5pbmRleC5zZWFyY2godCl9aGl0KHQpe2xldCBuPW5ldyBhLkJveCh0LngtMSx0LnktMSx0LngrMSx0LnkrMSk7cmV0dXJuIHRoaXMuaW5kZXguc2VhcmNoKG4pLmZpbHRlcihpPT50Lm9uKGkpKX1zdmcoKXtyZXR1cm5bLi4udGhpc10ucmVkdWNlKChuLHIpPT5uK3Iuc3ZnKCksIiIpfX1hLlBsYW5hclNldD1pMDtjbGFzcyBMdHtnZXQgbmFtZSgpe3Rocm93IEQuQ0FOTk9UX0lOVk9LRV9BQlNUUkFDVF9NRVRIT0R9Z2V0IGJveCgpe3Rocm93IEQuQ0FOTk9UX0lOVk9LRV9BQlNUUkFDVF9NRVRIT0R9Y2xvbmUoKXt0aHJvdyBELkNBTk5PVF9JTlZPS0VfQUJTVFJBQ1RfTUVUSE9EfXRyYW5zbGF0ZSguLi50KXtyZXR1cm4gdGhpcy50cmFuc2Zvcm0obmV3IGF0KCkudHJhbnNsYXRlKC4uLnQpKX1yb3RhdGUodCxuPW5ldyBhLlBvaW50KXtyZXR1cm4gdGhpcy50cmFuc2Zvcm0obmV3IGF0KCkucm90YXRlKHQsbi54LG4ueSkpfXNjYWxlKHQsbil7cmV0dXJuIHRoaXMudHJhbnNmb3JtKG5ldyBhdCgpLnNjYWxlKHQsbikpfXRyYW5zZm9ybSguLi50KXt0aHJvdyBELkNBTk5PVF9JTlZPS0VfQUJTVFJBQ1RfTUVUSE9EfXRvSlNPTigpe3JldHVybiBPYmplY3QuYXNzaWduKHt9LHRoaXMse25hbWU6dGhpcy5uYW1lfSl9c3ZnKHQ9e30pe3Rocm93IEQuQ0FOTk9UX0lOVk9LRV9BQlNUUkFDVF9NRVRIT0R9fWxldCB4bj1jbGFzcyBUYyBleHRlbmRzIEx0e2NvbnN0cnVjdG9yKC4uLnQpe2lmKHN1cGVyKCksdGhpcy54PTAsdGhpcy55PTAsdC5sZW5ndGghPT0wKXtpZih0Lmxlbmd0aD09PTEmJnRbMF1pbnN0YW5jZW9mIEFycmF5JiZ0WzBdLmxlbmd0aD09PTIpe2xldCBuPXRbMF07aWYodHlwZW9mIG5bMF09PSJudW1iZXIiJiZ0eXBlb2YgblsxXT09Im51bWJlciIpe3RoaXMueD1uWzBdLHRoaXMueT1uWzFdO3JldHVybn19aWYodC5sZW5ndGg9PT0xJiZ0WzBdaW5zdGFuY2VvZiBPYmplY3QmJnRbMF0ubmFtZT09PSJwb2ludCIpe2xldHt4Om4seTpyfT10WzBdO3RoaXMueD1uLHRoaXMueT1yO3JldHVybn1pZih0Lmxlbmd0aD09PTImJnR5cGVvZiB0WzBdPT0ibnVtYmVyIiYmdHlwZW9mIHRbMV09PSJudW1iZXIiKXt0aGlzLng9dFswXSx0aGlzLnk9dFsxXTtyZXR1cm59dGhyb3cgRC5JTExFR0FMX1BBUkFNRVRFUlN9fWdldCBib3goKXtyZXR1cm4gbmV3IGEuQm94KHRoaXMueCx0aGlzLnksdGhpcy54LHRoaXMueSl9Y2xvbmUoKXtyZXR1cm4gbmV3IGEuUG9pbnQodGhpcy54LHRoaXMueSl9Z2V0IHZlcnRpY2VzKCl7cmV0dXJuW3RoaXMuY2xvbmUoKV19ZXF1YWxUbyh0KXtyZXR1cm4gYS5VdGlscy5FUSh0aGlzLngsdC54KSYmYS5VdGlscy5FUSh0aGlzLnksdC55KX1sZXNzVGhhbih0KXtyZXR1cm4hIShhLlV0aWxzLkxUKHRoaXMueSx0LnkpfHxhLlV0aWxzLkVRKHRoaXMueSx0LnkpJiZhLlV0aWxzLkxUKHRoaXMueCx0LngpKX10cmFuc2Zvcm0odCl7cmV0dXJuIG5ldyBhLlBvaW50KHQudHJhbnNmb3JtKFt0aGlzLngsdGhpcy55XSkpfXByb2plY3Rpb25Pbih0KXtpZih0aGlzLmVxdWFsVG8odC5wdCkpcmV0dXJuIHRoaXMuY2xvbmUoKTtsZXQgbj1uZXcgYS5WZWN0b3IodGhpcyx0LnB0KTtpZihhLlV0aWxzLkVRXzAobi5jcm9zcyh0Lm5vcm0pKSlyZXR1cm4gdC5wdC5jbG9uZSgpO2xldCByPW4uZG90KHQubm9ybSksaT10Lm5vcm0ubXVsdGlwbHkocik7cmV0dXJuIHRoaXMudHJhbnNsYXRlKGkpfWxlZnRUbyh0KXtsZXQgbj1uZXcgYS5WZWN0b3IodC5wdCx0aGlzKTtyZXR1cm4gYS5VdGlscy5HVChuLmRvdCh0Lm5vcm0pLDApfWRpc3RhbmNlVG8odCl7aWYodCBpbnN0YW5jZW9mIFRjKXtsZXQgbj10LngtdGhpcy54LHI9dC55LXRoaXMueTtyZXR1cm5bTWF0aC5zcXJ0KG4qbityKnIpLG5ldyBhLlNlZ21lbnQodGhpcyx0KV19aWYodCBpbnN0YW5jZW9mIGEuTGluZSlyZXR1cm4gYS5EaXN0YW5jZS5wb2ludDJsaW5lKHRoaXMsdCk7aWYodCBpbnN0YW5jZW9mIGEuQ2lyY2xlKXJldHVybiBhLkRpc3RhbmNlLnBvaW50MmNpcmNsZSh0aGlzLHQpO2lmKHQgaW5zdGFuY2VvZiBhLlNlZ21lbnQpcmV0dXJuIGEuRGlzdGFuY2UucG9pbnQyc2VnbWVudCh0aGlzLHQpO2lmKHQgaW5zdGFuY2VvZiBhLkFyYylyZXR1cm4gYS5EaXN0YW5jZS5wb2ludDJhcmModGhpcyx0KTtpZih0IGluc3RhbmNlb2YgYS5Qb2x5Z29uKXJldHVybiBhLkRpc3RhbmNlLnBvaW50MnBvbHlnb24odGhpcyx0KTtpZih0IGluc3RhbmNlb2YgYS5QbGFuYXJTZXQpcmV0dXJuIGEuRGlzdGFuY2Uuc2hhcGUycGxhbmFyU2V0KHRoaXMsdCk7aWYodCBpbnN0YW5jZW9mIGEuTXVsdGlsaW5lKXJldHVybiBhLkRpc3RhbmNlLnNoYXBlMm11bHRpbGluZSh0aGlzLHQpfW9uKHQpe2lmKHQgaW5zdGFuY2VvZiBhLlBvaW50KXJldHVybiB0aGlzLmVxdWFsVG8odCk7aWYodC5jb250YWlucyYmdC5jb250YWlucyBpbnN0YW5jZW9mIEZ1bmN0aW9uKXJldHVybiB0LmNvbnRhaW5zKHRoaXMpO3Rocm93IGEuRXJyb3JzLlVOU1VQUE9SVEVEX1NIQVBFX1RZUEV9Z2V0IG5hbWUoKXtyZXR1cm4icG9pbnQifXN2Zyh0PXt9KXtjb25zdCBuPXQucj8/MztyZXR1cm5gCjxjaXJjbGUgY3g9IiR7dGhpcy54fSIgY3k9IiR7dGhpcy55fSIgcj0iJHtufSIKICAgICAgICAgICAgJHskdCh7ZmlsbDoicmVkIiwuLi50fSl9IC8+YH19O2EuUG9pbnQ9eG47Y29uc3QgczA9KC4uLmUpPT5uZXcgYS5Qb2ludCguLi5lKTthLnBvaW50PXMwO2xldCBvMD1jbGFzcyBleHRlbmRzIEx0e2NvbnN0cnVjdG9yKC4uLnQpe2lmKHN1cGVyKCksdGhpcy54PTAsdGhpcy55PTAsdC5sZW5ndGghPT0wKXtpZih0Lmxlbmd0aD09PTEmJnRbMF1pbnN0YW5jZW9mIEFycmF5JiZ0WzBdLmxlbmd0aD09PTIpe2xldCBuPXRbMF07aWYodHlwZW9mIG5bMF09PSJudW1iZXIiJiZ0eXBlb2YgblsxXT09Im51bWJlciIpe3RoaXMueD1uWzBdLHRoaXMueT1uWzFdO3JldHVybn19aWYodC5sZW5ndGg9PT0xJiZ0WzBdaW5zdGFuY2VvZiBPYmplY3QmJnRbMF0ubmFtZT09PSJ2ZWN0b3IiKXtsZXR7eDpuLHk6cn09dFswXTt0aGlzLng9bix0aGlzLnk9cjtyZXR1cm59aWYodC5sZW5ndGg9PT0yKXtsZXQgbj10WzBdLHI9dFsxXTtpZih0eXBlb2Ygbj09Im51bWJlciImJnR5cGVvZiByPT0ibnVtYmVyIil7dGhpcy54PW4sdGhpcy55PXI7cmV0dXJufWlmKG4gaW5zdGFuY2VvZiBhLlBvaW50JiZyIGluc3RhbmNlb2YgYS5Qb2ludCl7dGhpcy54PXIueC1uLngsdGhpcy55PXIueS1uLnk7cmV0dXJufX10aHJvdyBELklMTEVHQUxfUEFSQU1FVEVSU319Y2xvbmUoKXtyZXR1cm4gbmV3IGEuVmVjdG9yKHRoaXMueCx0aGlzLnkpfWdldCBzbG9wZSgpe2xldCB0PU1hdGguYXRhbjIodGhpcy55LHRoaXMueCk7cmV0dXJuIHQ8MCYmKHQ9MipNYXRoLlBJK3QpLHR9Z2V0IGxlbmd0aCgpe3JldHVybiBNYXRoLnNxcnQodGhpcy5kb3QodGhpcykpfWVxdWFsVG8odCl7cmV0dXJuIGEuVXRpbHMuRVEodGhpcy54LHQueCkmJmEuVXRpbHMuRVEodGhpcy55LHQueSl9bXVsdGlwbHkodCl7cmV0dXJuIG5ldyBhLlZlY3Rvcih0KnRoaXMueCx0KnRoaXMueSl9ZG90KHQpe3JldHVybiB0aGlzLngqdC54K3RoaXMueSp0Lnl9Y3Jvc3ModCl7cmV0dXJuIHRoaXMueCp0LnktdGhpcy55KnQueH1ub3JtYWxpemUoKXtpZighYS5VdGlscy5FUV8wKHRoaXMubGVuZ3RoKSlyZXR1cm4gbmV3IGEuVmVjdG9yKHRoaXMueC90aGlzLmxlbmd0aCx0aGlzLnkvdGhpcy5sZW5ndGgpO3Rocm93IEQuWkVST19ESVZJU0lPTn1yb3RhdGUodCxuPW5ldyBhLlBvaW50KXtpZihuLng9PT0wJiZuLnk9PT0wKXJldHVybiB0aGlzLnRyYW5zZm9ybShuZXcgYXQoKS5yb3RhdGUodCkpO3Rocm93IEQuT1BFUkFUSU9OX0lTX05PVF9TVVBQT1JURUR9dHJhbnNmb3JtKHQpe3JldHVybiBuZXcgYS5WZWN0b3IodC50cmFuc2Zvcm0oW3RoaXMueCx0aGlzLnldKSl9cm90YXRlOTBDQ1coKXtyZXR1cm4gbmV3IGEuVmVjdG9yKC10aGlzLnksdGhpcy54KX1yb3RhdGU5MENXKCl7cmV0dXJuIG5ldyBhLlZlY3Rvcih0aGlzLnksLXRoaXMueCl9aW52ZXJ0KCl7cmV0dXJuIG5ldyBhLlZlY3RvcigtdGhpcy54LC10aGlzLnkpfWFkZCh0KXtyZXR1cm4gbmV3IGEuVmVjdG9yKHRoaXMueCt0LngsdGhpcy55K3QueSl9c3VidHJhY3QodCl7cmV0dXJuIG5ldyBhLlZlY3Rvcih0aGlzLngtdC54LHRoaXMueS10LnkpfWFuZ2xlVG8odCl7bGV0IG49dGhpcy5ub3JtYWxpemUoKSxyPXQubm9ybWFsaXplKCksaT1NYXRoLmF0YW4yKG4uY3Jvc3Mociksbi5kb3QocikpO3JldHVybiBpPDAmJihpKz0yKk1hdGguUEkpLGl9cHJvamVjdGlvbk9uKHQpe2xldCBuPXQubm9ybWFsaXplKCkscj10aGlzLmRvdChuKTtyZXR1cm4gbi5tdWx0aXBseShyKX1nZXQgbmFtZSgpe3JldHVybiJ2ZWN0b3IifX07YS5WZWN0b3I9bzA7Y29uc3QgaWM9KC4uLmUpPT5uZXcgYS5WZWN0b3IoLi4uZSk7YS52ZWN0b3I9aWM7bGV0IGMwPWNsYXNzIHRpIGV4dGVuZHMgTHR7Y29uc3RydWN0b3IoLi4udCl7aWYoc3VwZXIoKSx0aGlzLnBzPW5ldyBhLlBvaW50LHRoaXMucGU9bmV3IGEuUG9pbnQsdC5sZW5ndGghPT0wKXtpZih0Lmxlbmd0aD09PTEmJnRbMF1pbnN0YW5jZW9mIEFycmF5JiZ0WzBdLmxlbmd0aD09PTQpe2xldCBuPXRbMF07dGhpcy5wcz1uZXcgYS5Qb2ludChuWzBdLG5bMV0pLHRoaXMucGU9bmV3IGEuUG9pbnQoblsyXSxuWzNdKTtyZXR1cm59aWYodC5sZW5ndGg9PT0xJiZ0WzBdaW5zdGFuY2VvZiBPYmplY3QmJnRbMF0ubmFtZT09PSJzZWdtZW50Iil7bGV0e3BzOm4scGU6cn09dFswXTt0aGlzLnBzPW5ldyBhLlBvaW50KG4ueCxuLnkpLHRoaXMucGU9bmV3IGEuUG9pbnQoci54LHIueSk7cmV0dXJufWlmKHQubGVuZ3RoPT09MSYmdFswXWluc3RhbmNlb2YgYS5Qb2ludCl7dGhpcy5wcz10WzBdLmNsb25lKCk7cmV0dXJufWlmKHQubGVuZ3RoPT09MiYmdFswXWluc3RhbmNlb2YgYS5Qb2ludCYmdFsxXWluc3RhbmNlb2YgYS5Qb2ludCl7dGhpcy5wcz10WzBdLmNsb25lKCksdGhpcy5wZT10WzFdLmNsb25lKCk7cmV0dXJufWlmKHQubGVuZ3RoPT09NCl7dGhpcy5wcz1uZXcgYS5Qb2ludCh0WzBdLHRbMV0pLHRoaXMucGU9bmV3IGEuUG9pbnQodFsyXSx0WzNdKTtyZXR1cm59dGhyb3cgRC5JTExFR0FMX1BBUkFNRVRFUlN9fWNsb25lKCl7cmV0dXJuIG5ldyBhLlNlZ21lbnQodGhpcy5zdGFydCx0aGlzLmVuZCl9Z2V0IHN0YXJ0KCl7cmV0dXJuIHRoaXMucHN9Z2V0IGVuZCgpe3JldHVybiB0aGlzLnBlfWdldCB2ZXJ0aWNlcygpe3JldHVyblt0aGlzLnBzLmNsb25lKCksdGhpcy5wZS5jbG9uZSgpXX1nZXQgbGVuZ3RoKCl7cmV0dXJuIHRoaXMuc3RhcnQuZGlzdGFuY2VUbyh0aGlzLmVuZClbMF19Z2V0IHNsb3BlKCl7cmV0dXJuIG5ldyBhLlZlY3Rvcih0aGlzLnN0YXJ0LHRoaXMuZW5kKS5zbG9wZX1nZXQgYm94KCl7cmV0dXJuIG5ldyBhLkJveChNYXRoLm1pbih0aGlzLnN0YXJ0LngsdGhpcy5lbmQueCksTWF0aC5taW4odGhpcy5zdGFydC55LHRoaXMuZW5kLnkpLE1hdGgubWF4KHRoaXMuc3RhcnQueCx0aGlzLmVuZC54KSxNYXRoLm1heCh0aGlzLnN0YXJ0LnksdGhpcy5lbmQueSkpfWVxdWFsVG8odCl7cmV0dXJuIHRoaXMucHMuZXF1YWxUbyh0LnBzKSYmdGhpcy5wZS5lcXVhbFRvKHQucGUpfWNvbnRhaW5zKHQpe3JldHVybiBhLlV0aWxzLkVRXzAodGhpcy5kaXN0YW5jZVRvUG9pbnQodCkpfWludGVyc2VjdCh0KXtpZih0IGluc3RhbmNlb2YgYS5Qb2ludClyZXR1cm4gdGhpcy5jb250YWlucyh0KT9bdF06W107aWYodCBpbnN0YW5jZW9mIGEuTGluZSlyZXR1cm4geWUodGhpcyx0KTtpZih0IGluc3RhbmNlb2YgYS5SYXkpcmV0dXJuIExyKHQsdGhpcyk7aWYodCBpbnN0YW5jZW9mIGEuU2VnbWVudClyZXR1cm4gbW4odGhpcyx0KTtpZih0IGluc3RhbmNlb2YgYS5DaXJjbGUpcmV0dXJuIHBuKHRoaXMsdCk7aWYodCBpbnN0YW5jZW9mIGEuQm94KXJldHVybiBNdSh0aGlzLHQpO2lmKHQgaW5zdGFuY2VvZiBhLkFyYylyZXR1cm4gS3QodGhpcyx0KTtpZih0IGluc3RhbmNlb2YgYS5Qb2x5Z29uKXJldHVybiBTcih0aGlzLHQpO2lmKHQgaW5zdGFuY2VvZiBhLk11bHRpbGluZSlyZXR1cm4gTWUodGhpcyx0KX1kaXN0YW5jZVRvKHQpe2lmKHQgaW5zdGFuY2VvZiBhLlBvaW50KXtsZXRbbixyXT1hLkRpc3RhbmNlLnBvaW50MnNlZ21lbnQodCx0aGlzKTtyZXR1cm4gcj1yLnJldmVyc2UoKSxbbixyXX1pZih0IGluc3RhbmNlb2YgYS5DaXJjbGUpe2xldFtuLHJdPWEuRGlzdGFuY2Uuc2VnbWVudDJjaXJjbGUodGhpcyx0KTtyZXR1cm5bbixyXX1pZih0IGluc3RhbmNlb2YgYS5MaW5lKXtsZXRbbixyXT1hLkRpc3RhbmNlLnNlZ21lbnQybGluZSh0aGlzLHQpO3JldHVybltuLHJdfWlmKHQgaW5zdGFuY2VvZiBhLlNlZ21lbnQpe2xldFtuLHJdPWEuRGlzdGFuY2Uuc2VnbWVudDJzZWdtZW50KHRoaXMsdCk7cmV0dXJuW24scl19aWYodCBpbnN0YW5jZW9mIGEuQXJjKXtsZXRbbixyXT1hLkRpc3RhbmNlLnNlZ21lbnQyYXJjKHRoaXMsdCk7cmV0dXJuW24scl19aWYodCBpbnN0YW5jZW9mIGEuUG9seWdvbil7bGV0W24scl09YS5EaXN0YW5jZS5zaGFwZTJwb2x5Z29uKHRoaXMsdCk7cmV0dXJuW24scl19aWYodCBpbnN0YW5jZW9mIGEuUGxhbmFyU2V0KXtsZXRbbixyXT1hLkRpc3RhbmNlLnNoYXBlMnBsYW5hclNldCh0aGlzLHQpO3JldHVybltuLHJdfWlmKHQgaW5zdGFuY2VvZiBhLk11bHRpbGluZSlyZXR1cm4gYS5EaXN0YW5jZS5zaGFwZTJtdWx0aWxpbmUodGhpcyx0KX10YW5nZW50SW5TdGFydCgpe3JldHVybiBuZXcgYS5WZWN0b3IodGhpcy5zdGFydCx0aGlzLmVuZCkubm9ybWFsaXplKCl9dGFuZ2VudEluRW5kKCl7cmV0dXJuIG5ldyBhLlZlY3Rvcih0aGlzLmVuZCx0aGlzLnN0YXJ0KS5ub3JtYWxpemUoKX1yZXZlcnNlKCl7cmV0dXJuIG5ldyB0aSh0aGlzLmVuZCx0aGlzLnN0YXJ0KX1zcGxpdCh0KXtyZXR1cm4gdGhpcy5zdGFydC5lcXVhbFRvKHQpP1tudWxsLHRoaXMuY2xvbmUoKV06dGhpcy5lbmQuZXF1YWxUbyh0KT9bdGhpcy5jbG9uZSgpLG51bGxdOltuZXcgYS5TZWdtZW50KHRoaXMuc3RhcnQsdCksbmV3IGEuU2VnbWVudCh0LHRoaXMuZW5kKV19bWlkZGxlKCl7cmV0dXJuIG5ldyBhLlBvaW50KCh0aGlzLnN0YXJ0LngrdGhpcy5lbmQueCkvMiwodGhpcy5zdGFydC55K3RoaXMuZW5kLnkpLzIpfXBvaW50QXRMZW5ndGgodCl7aWYodD50aGlzLmxlbmd0aHx8dDwwKXJldHVybiBudWxsO2lmKHQ9PTApcmV0dXJuIHRoaXMuc3RhcnQ7aWYodD09dGhpcy5sZW5ndGgpcmV0dXJuIHRoaXMuZW5kO2xldCBuPXQvdGhpcy5sZW5ndGg7cmV0dXJuIG5ldyBhLlBvaW50KCh0aGlzLmVuZC54LXRoaXMuc3RhcnQueCkqbit0aGlzLnN0YXJ0LngsKHRoaXMuZW5kLnktdGhpcy5zdGFydC55KSpuK3RoaXMuc3RhcnQueSl9ZGlzdGFuY2VUb1BvaW50KHQpe2xldFtuLC4uLnJdPWEuRGlzdGFuY2UucG9pbnQyc2VnbWVudCh0LHRoaXMpO3JldHVybiBufWRlZmluaXRlSW50ZWdyYWwodD0wKXtsZXQgbj10aGlzLmVuZC54LXRoaXMuc3RhcnQueCxyPXRoaXMuc3RhcnQueS10LGk9dGhpcy5lbmQueS10O3JldHVybiBuKihyK2kpLzJ9dHJhbnNmb3JtKHQ9bmV3IGEuTWF0cml4KXtyZXR1cm4gbmV3IHRpKHRoaXMucHMudHJhbnNmb3JtKHQpLHRoaXMucGUudHJhbnNmb3JtKHQpKX1pc1plcm9MZW5ndGgoKXtyZXR1cm4gdGhpcy5wcy5lcXVhbFRvKHRoaXMucGUpfXNvcnRQb2ludHModCl7cmV0dXJuIG5ldyBhLkxpbmUodGhpcy5zdGFydCx0aGlzLmVuZCkuc29ydFBvaW50cyh0KX1nZXQgbmFtZSgpe3JldHVybiJzZWdtZW50In1zdmcodD17fSl7cmV0dXJuYAo8bGluZSB4MT0iJHt0aGlzLnN0YXJ0Lnh9IiB5MT0iJHt0aGlzLnN0YXJ0Lnl9IiB4Mj0iJHt0aGlzLmVuZC54fSIgeTI9IiR7dGhpcy5lbmQueX0iICR7JHQodCl9IC8+YH19O2EuU2VnbWVudD1jMDtjb25zdCBhMD0oLi4uZSk9Pm5ldyBhLlNlZ21lbnQoLi4uZSk7YS5zZWdtZW50PWEwO2xldHt2ZWN0b3I6YmV9PWEsbDA9Y2xhc3MgdmMgZXh0ZW5kcyBMdHtjb25zdHJ1Y3RvciguLi50KXtpZihzdXBlcigpLHRoaXMucHQ9bmV3IGEuUG9pbnQsdGhpcy5ub3JtPW5ldyBhLlZlY3RvcigwLDEpLHQubGVuZ3RoIT09MCl7aWYodC5sZW5ndGg9PT0xJiZ0WzBdaW5zdGFuY2VvZiBPYmplY3QmJnRbMF0ubmFtZT09PSJsaW5lIil7bGV0e3B0Om4sbm9ybTpyfT10WzBdO3RoaXMucHQ9bmV3IGEuUG9pbnQobiksdGhpcy5ub3JtPW5ldyBhLlZlY3RvcihyKTtyZXR1cm59aWYodC5sZW5ndGg9PT0yKXtsZXQgbj10WzBdLHI9dFsxXTtpZihuIGluc3RhbmNlb2YgYS5Qb2ludCYmciBpbnN0YW5jZW9mIGEuUG9pbnQpe3RoaXMucHQ9bix0aGlzLm5vcm09dmMucG9pbnRzMm5vcm0obixyKSx0aGlzLm5vcm0uZG90KGJlKHRoaXMucHQueCx0aGlzLnB0LnkpKT49MCYmdGhpcy5ub3JtLmludmVydCgpO3JldHVybn1pZihuIGluc3RhbmNlb2YgYS5Qb2ludCYmciBpbnN0YW5jZW9mIGEuVmVjdG9yKXtpZihhLlV0aWxzLkVRXzAoci54KSYmYS5VdGlscy5FUV8wKHIueSkpdGhyb3cgRC5JTExFR0FMX1BBUkFNRVRFUlM7dGhpcy5wdD1uLmNsb25lKCksdGhpcy5ub3JtPXIuY2xvbmUoKSx0aGlzLm5vcm09dGhpcy5ub3JtLm5vcm1hbGl6ZSgpLHRoaXMubm9ybS5kb3QoYmUodGhpcy5wdC54LHRoaXMucHQueSkpPj0wJiZ0aGlzLm5vcm0uaW52ZXJ0KCk7cmV0dXJufWlmKG4gaW5zdGFuY2VvZiBhLlZlY3RvciYmciBpbnN0YW5jZW9mIGEuUG9pbnQpe2lmKGEuVXRpbHMuRVFfMChuLngpJiZhLlV0aWxzLkVRXzAobi55KSl0aHJvdyBELklMTEVHQUxfUEFSQU1FVEVSUzt0aGlzLnB0PXIuY2xvbmUoKSx0aGlzLm5vcm09bi5jbG9uZSgpLHRoaXMubm9ybT10aGlzLm5vcm0ubm9ybWFsaXplKCksdGhpcy5ub3JtLmRvdChiZSh0aGlzLnB0LngsdGhpcy5wdC55KSk+PTAmJnRoaXMubm9ybS5pbnZlcnQoKTtyZXR1cm59fXRocm93IEQuSUxMRUdBTF9QQVJBTUVURVJTfX1jbG9uZSgpe3JldHVybiBuZXcgYS5MaW5lKHRoaXMucHQsdGhpcy5ub3JtKX1nZXQgc3RhcnQoKXt9Z2V0IGVuZCgpe31nZXQgbGVuZ3RoKCl7cmV0dXJuIE51bWJlci5QT1NJVElWRV9JTkZJTklUWX1nZXQgYm94KCl7cmV0dXJuIG5ldyBhLkJveChOdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFksTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZLE51bWJlci5QT1NJVElWRV9JTkZJTklUWSxOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFkpfWdldCBtaWRkbGUoKXt9Z2V0IHNsb3BlKCl7cmV0dXJuIG5ldyBhLlZlY3Rvcih0aGlzLm5vcm0ueSwtdGhpcy5ub3JtLngpLnNsb3BlfWdldCBzdGFuZGFyZCgpe2xldCB0PXRoaXMubm9ybS54LG49dGhpcy5ub3JtLnkscj10aGlzLm5vcm0uZG90KGJlKHRoaXMucHQueCx0aGlzLnB0LnkpKTtyZXR1cm5bdCxuLHJdfXBhcmFsbGVsVG8odCl7cmV0dXJuIGEuVXRpbHMuRVFfMCh0aGlzLm5vcm0uY3Jvc3ModC5ub3JtKSl9aW5jaWRlbnRUbyh0KXtyZXR1cm4gdGhpcy5wYXJhbGxlbFRvKHQpJiZ0aGlzLnB0Lm9uKHQpfWNvbnRhaW5zKHQpe2lmKHRoaXMucHQuZXF1YWxUbyh0KSlyZXR1cm4hMDtsZXQgbj1uZXcgYS5WZWN0b3IodGhpcy5wdCx0KTtyZXR1cm4gYS5VdGlscy5FUV8wKHRoaXMubm9ybS5kb3QobikpfWNvb3JkKHQpe3JldHVybiBiZSh0LngsdC55KS5jcm9zcyh0aGlzLm5vcm0pfWludGVyc2VjdCh0KXtpZih0IGluc3RhbmNlb2YgYS5Qb2ludClyZXR1cm4gdGhpcy5jb250YWlucyh0KT9bdF06W107aWYodCBpbnN0YW5jZW9mIGEuTGluZSlyZXR1cm4ganQodGhpcyx0KTtpZih0IGluc3RhbmNlb2YgYS5SYXkpcmV0dXJuIHFvKHQsdGhpcyk7aWYodCBpbnN0YW5jZW9mIGEuQ2lyY2xlKXJldHVybiBrdCh0aGlzLHQpO2lmKHQgaW5zdGFuY2VvZiBhLkJveClyZXR1cm4gUXQodGhpcyx0KTtpZih0IGluc3RhbmNlb2YgYS5TZWdtZW50KXJldHVybiB5ZSh0LHRoaXMpO2lmKHQgaW5zdGFuY2VvZiBhLkFyYylyZXR1cm4gZ24odGhpcyx0KTtpZih0IGluc3RhbmNlb2YgYS5Qb2x5Z29uKXJldHVybiB4ZSh0aGlzLHQpO2lmKHQgaW5zdGFuY2VvZiBhLk11bHRpbGluZSlyZXR1cm4gTWUodGhpcyx0KX1kaXN0YW5jZVRvKHQpe2lmKHQgaW5zdGFuY2VvZiBhLlBvaW50KXtsZXRbbixyXT1hLkRpc3RhbmNlLnBvaW50MmxpbmUodCx0aGlzKTtyZXR1cm4gcj1yLnJldmVyc2UoKSxbbixyXX1pZih0IGluc3RhbmNlb2YgYS5DaXJjbGUpe2xldFtuLHJdPWEuRGlzdGFuY2UuY2lyY2xlMmxpbmUodCx0aGlzKTtyZXR1cm4gcj1yLnJldmVyc2UoKSxbbixyXX1pZih0IGluc3RhbmNlb2YgYS5TZWdtZW50KXtsZXRbbixyXT1hLkRpc3RhbmNlLnNlZ21lbnQybGluZSh0LHRoaXMpO3JldHVybltuLHIucmV2ZXJzZSgpXX1pZih0IGluc3RhbmNlb2YgYS5BcmMpe2xldFtuLHJdPWEuRGlzdGFuY2UuYXJjMmxpbmUodCx0aGlzKTtyZXR1cm5bbixyLnJldmVyc2UoKV19aWYodCBpbnN0YW5jZW9mIGEuUG9seWdvbil7bGV0W24scl09YS5EaXN0YW5jZS5zaGFwZTJwb2x5Z29uKHRoaXMsdCk7cmV0dXJuW24scl19fXNwbGl0KHQpe2lmKHQgaW5zdGFuY2VvZiBhLlBvaW50KXJldHVybltuZXcgYS5SYXkodCx0aGlzLm5vcm0pLG5ldyBhLlJheSh0LHRoaXMubm9ybSldO3tsZXQgbj1uZXcgYS5NdWx0aWxpbmUoW3RoaXNdKSxyPXRoaXMuc29ydFBvaW50cyh0KTtyZXR1cm4gbi5zcGxpdChyKSxuLnRvU2hhcGVzKCl9fXJvdGF0ZSh0LG49bmV3IGEuUG9pbnQpe3JldHVybiBuZXcgYS5MaW5lKHRoaXMucHQucm90YXRlKHQsbiksdGhpcy5ub3JtLnJvdGF0ZSh0KSl9dHJhbnNmb3JtKHQpe3JldHVybiBuZXcgYS5MaW5lKHRoaXMucHQudHJhbnNmb3JtKHQpLHRoaXMubm9ybS5jbG9uZSgpKX1zb3J0UG9pbnRzKHQpe3JldHVybiB0LnNsaWNlKCkuc29ydCgobixyKT0+dGhpcy5jb29yZChuKTx0aGlzLmNvb3JkKHIpPy0xOnRoaXMuY29vcmQobik+dGhpcy5jb29yZChyKT8xOjApfWdldCBuYW1lKCl7cmV0dXJuImxpbmUifXN2Zyh0LG49e30pe2xldCByPVF0KHRoaXMsdCk7aWYoci5sZW5ndGg9PT0wKXJldHVybiIiO2xldCBpPXJbMF0scz1yLmxlbmd0aD09PTI/clsxXTpyLmZpbmQoYz0+IWMuZXF1YWxUbyhpKSk7cmV0dXJuIHM9PT12b2lkIDAmJihzPWkpLG5ldyBhLlNlZ21lbnQoaSxzKS5zdmcobil9c3RhdGljIHBvaW50czJub3JtKHQsbil7aWYodC5lcXVhbFRvKG4pKXRocm93IEQuSUxMRUdBTF9QQVJBTUVURVJTO3JldHVybiBuZXcgYS5WZWN0b3IodCxuKS5ub3JtYWxpemUoKS5yb3RhdGU5MENDVygpfX07YS5MaW5lPWwwO2NvbnN0IGgwPSguLi5lKT0+bmV3IGEuTGluZSguLi5lKTthLmxpbmU9aDA7bGV0IGYwPWNsYXNzIGV4dGVuZHMgTHR7Y29uc3RydWN0b3IoLi4udCl7aWYoc3VwZXIoKSx0aGlzLnBjPW5ldyBhLlBvaW50LHRoaXMucj0xLHQubGVuZ3RoPT09MSYmdFswXWluc3RhbmNlb2YgT2JqZWN0JiZ0WzBdLm5hbWU9PT0iY2lyY2xlIil7bGV0e3BjOm4scn09dFswXTt0aGlzLnBjPW5ldyBhLlBvaW50KG4pLHRoaXMucj1yfWVsc2V7bGV0W24scl09Wy4uLnRdO24mJm4gaW5zdGFuY2VvZiBhLlBvaW50JiYodGhpcy5wYz1uLmNsb25lKCkpLHIhPT12b2lkIDAmJih0aGlzLnI9cil9fWNsb25lKCl7cmV0dXJuIG5ldyBhLkNpcmNsZSh0aGlzLnBjLmNsb25lKCksdGhpcy5yKX1nZXQgY2VudGVyKCl7cmV0dXJuIHRoaXMucGN9Z2V0IGJveCgpe3JldHVybiBuZXcgYS5Cb3godGhpcy5wYy54LXRoaXMucix0aGlzLnBjLnktdGhpcy5yLHRoaXMucGMueCt0aGlzLnIsdGhpcy5wYy55K3RoaXMucil9Y29udGFpbnModCl7aWYodCBpbnN0YW5jZW9mIGEuUG9pbnQpcmV0dXJuIGEuVXRpbHMuTEUodC5kaXN0YW5jZVRvKHRoaXMuY2VudGVyKVswXSx0aGlzLnIpO2lmKHQgaW5zdGFuY2VvZiBhLlNlZ21lbnQpcmV0dXJuIGEuVXRpbHMuTEUodC5zdGFydC5kaXN0YW5jZVRvKHRoaXMuY2VudGVyKVswXSx0aGlzLnIpJiZhLlV0aWxzLkxFKHQuZW5kLmRpc3RhbmNlVG8odGhpcy5jZW50ZXIpWzBdLHRoaXMucik7aWYodCBpbnN0YW5jZW9mIGEuQXJjKXJldHVybiB0aGlzLmludGVyc2VjdCh0KS5sZW5ndGg9PT0wJiZhLlV0aWxzLkxFKHQuc3RhcnQuZGlzdGFuY2VUbyh0aGlzLmNlbnRlcilbMF0sdGhpcy5yKSYmYS5VdGlscy5MRSh0LmVuZC5kaXN0YW5jZVRvKHRoaXMuY2VudGVyKVswXSx0aGlzLnIpO2lmKHQgaW5zdGFuY2VvZiBhLkNpcmNsZSlyZXR1cm4gdGhpcy5pbnRlcnNlY3QodCkubGVuZ3RoPT09MCYmYS5VdGlscy5MRSh0LnIsdGhpcy5yKSYmYS5VdGlscy5MRSh0LmNlbnRlci5kaXN0YW5jZVRvKHRoaXMuY2VudGVyKVswXSx0aGlzLnIpfXRvQXJjKHQ9ITApe3JldHVybiBuZXcgYS5BcmModGhpcy5jZW50ZXIsdGhpcy5yLE1hdGguUEksLU1hdGguUEksdCl9c2NhbGUodCxuKXtpZih0IT09bnx8ISh0aGlzLnBjLng9PT0wJiZ0aGlzLnBjLnk9PT0wKSl0aHJvdyBELk9QRVJBVElPTl9JU19OT1RfU1VQUE9SVEVEO3JldHVybiBuZXcgYS5DaXJjbGUodGhpcy5wYyx0aGlzLnIqdCl9dHJhbnNmb3JtKHQ9bmV3IGEuTWF0cml4KXtyZXR1cm4gbmV3IGEuQ2lyY2xlKHRoaXMucGMudHJhbnNmb3JtKHQpLHRoaXMucil9aW50ZXJzZWN0KHQpe2lmKHQgaW5zdGFuY2VvZiBhLlBvaW50KXJldHVybiB0aGlzLmNvbnRhaW5zKHQpP1t0XTpbXTtpZih0IGluc3RhbmNlb2YgYS5MaW5lKXJldHVybiBrdCh0LHRoaXMpO2lmKHQgaW5zdGFuY2VvZiBhLlJheSlyZXR1cm4gRm8odCx0aGlzKTtpZih0IGluc3RhbmNlb2YgYS5TZWdtZW50KXJldHVybiBwbih0LHRoaXMpO2lmKHQgaW5zdGFuY2VvZiBhLkNpcmNsZSlyZXR1cm4gUG8odCx0aGlzKTtpZih0IGluc3RhbmNlb2YgYS5Cb3gpcmV0dXJuIHd1KHRoaXMsdCk7aWYodCBpbnN0YW5jZW9mIGEuQXJjKXJldHVybiBJcih0LHRoaXMpO2lmKHQgaW5zdGFuY2VvZiBhLlBvbHlnb24pcmV0dXJuIE5vKHRoaXMsdCk7aWYodCBpbnN0YW5jZW9mIGEuTXVsdGlsaW5lKXJldHVybiBNZSh0aGlzLHQpfWRpc3RhbmNlVG8odCl7aWYodCBpbnN0YW5jZW9mIGEuUG9pbnQpe2xldFtuLHJdPWEuRGlzdGFuY2UucG9pbnQyY2lyY2xlKHQsdGhpcyk7cmV0dXJuIHI9ci5yZXZlcnNlKCksW24scl19aWYodCBpbnN0YW5jZW9mIGEuQ2lyY2xlKXtsZXRbbixyXT1hLkRpc3RhbmNlLmNpcmNsZTJjaXJjbGUodGhpcyx0KTtyZXR1cm5bbixyXX1pZih0IGluc3RhbmNlb2YgYS5MaW5lKXtsZXRbbixyXT1hLkRpc3RhbmNlLmNpcmNsZTJsaW5lKHRoaXMsdCk7cmV0dXJuW24scl19aWYodCBpbnN0YW5jZW9mIGEuU2VnbWVudCl7bGV0W24scl09YS5EaXN0YW5jZS5zZWdtZW50MmNpcmNsZSh0LHRoaXMpO3JldHVybiByPXIucmV2ZXJzZSgpLFtuLHJdfWlmKHQgaW5zdGFuY2VvZiBhLkFyYyl7bGV0W24scl09YS5EaXN0YW5jZS5hcmMyY2lyY2xlKHQsdGhpcyk7cmV0dXJuIHI9ci5yZXZlcnNlKCksW24scl19aWYodCBpbnN0YW5jZW9mIGEuUG9seWdvbil7bGV0W24scl09YS5EaXN0YW5jZS5zaGFwZTJwb2x5Z29uKHRoaXMsdCk7cmV0dXJuW24scl19aWYodCBpbnN0YW5jZW9mIGEuUGxhbmFyU2V0KXtsZXRbbixyXT1hLkRpc3RhbmNlLnNoYXBlMnBsYW5hclNldCh0aGlzLHQpO3JldHVybltuLHJdfWlmKHQgaW5zdGFuY2VvZiBhLk11bHRpbGluZSl7bGV0W24scl09YS5EaXN0YW5jZS5zaGFwZTJtdWx0aWxpbmUodGhpcyx0KTtyZXR1cm5bbixyXX19Z2V0IG5hbWUoKXtyZXR1cm4iY2lyY2xlIn1zdmcodD17fSl7cmV0dXJuYAo8Y2lyY2xlIGN4PSIke3RoaXMucGMueH0iIGN5PSIke3RoaXMucGMueX0iIHI9IiR7dGhpcy5yfSIKICAgICAgICAgICAgICAgICR7JHQoe2ZpbGw6Im5vbmUiLC4uLnR9KX0gLz5gfX07YS5DaXJjbGU9ZjA7Y29uc3QgdTA9KC4uLmUpPT5uZXcgYS5DaXJjbGUoLi4uZSk7YS5jaXJjbGU9dTA7Y2xhc3MgZDAgZXh0ZW5kcyBMdHtjb25zdHJ1Y3RvciguLi50KXtpZihzdXBlcigpLHRoaXMucGM9bmV3IGEuUG9pbnQsdGhpcy5yPTEsdGhpcy5zdGFydEFuZ2xlPTAsdGhpcy5lbmRBbmdsZT0yKk1hdGguUEksdGhpcy5jb3VudGVyQ2xvY2t3aXNlPWEuQ0NXLHQubGVuZ3RoIT09MClpZih0Lmxlbmd0aD09PTEmJnRbMF1pbnN0YW5jZW9mIE9iamVjdCYmdFswXS5uYW1lPT09ImFyYyIpe2xldHtwYzpuLHIsc3RhcnRBbmdsZTppLGVuZEFuZ2xlOnMsY291bnRlckNsb2Nrd2lzZTpvfT10WzBdO3RoaXMucGM9bmV3IGEuUG9pbnQobi54LG4ueSksdGhpcy5yPXIsdGhpcy5zdGFydEFuZ2xlPWksdGhpcy5lbmRBbmdsZT1zLHRoaXMuY291bnRlckNsb2Nrd2lzZT1vfWVsc2V7bGV0W24scixpLHMsb109Wy4uLnRdO24mJm4gaW5zdGFuY2VvZiBhLlBvaW50JiYodGhpcy5wYz1uLmNsb25lKCkpLHIhPT12b2lkIDAmJih0aGlzLnI9ciksaSE9PXZvaWQgMCYmKHRoaXMuc3RhcnRBbmdsZT1pKSxzIT09dm9pZCAwJiYodGhpcy5lbmRBbmdsZT1zKSxvIT09dm9pZCAwJiYodGhpcy5jb3VudGVyQ2xvY2t3aXNlPW8pfX1jbG9uZSgpe3JldHVybiBuZXcgYS5BcmModGhpcy5wYy5jbG9uZSgpLHRoaXMucix0aGlzLnN0YXJ0QW5nbGUsdGhpcy5lbmRBbmdsZSx0aGlzLmNvdW50ZXJDbG9ja3dpc2UpfWdldCBzd2VlcCgpe2lmKGEuVXRpbHMuRVEodGhpcy5zdGFydEFuZ2xlLHRoaXMuZW5kQW5nbGUpKXJldHVybiAwO2lmKGEuVXRpbHMuRVEoTWF0aC5hYnModGhpcy5zdGFydEFuZ2xlLXRoaXMuZW5kQW5nbGUpLGEuUEl4MikpcmV0dXJuIGEuUEl4MjtsZXQgdDtyZXR1cm4gdGhpcy5jb3VudGVyQ2xvY2t3aXNlP3Q9YS5VdGlscy5HVCh0aGlzLmVuZEFuZ2xlLHRoaXMuc3RhcnRBbmdsZSk/dGhpcy5lbmRBbmdsZS10aGlzLnN0YXJ0QW5nbGU6dGhpcy5lbmRBbmdsZS10aGlzLnN0YXJ0QW5nbGUrYS5QSXgyOnQ9YS5VdGlscy5HVCh0aGlzLnN0YXJ0QW5nbGUsdGhpcy5lbmRBbmdsZSk/dGhpcy5zdGFydEFuZ2xlLXRoaXMuZW5kQW5nbGU6dGhpcy5zdGFydEFuZ2xlLXRoaXMuZW5kQW5nbGUrYS5QSXgyLGEuVXRpbHMuR1QodCxhLlBJeDIpJiYodC09YS5QSXgyKSxhLlV0aWxzLkxUKHQsMCkmJih0Kz1hLlBJeDIpLHR9Z2V0IHN0YXJ0KCl7cmV0dXJuIG5ldyBhLlBvaW50KHRoaXMucGMueCt0aGlzLnIsdGhpcy5wYy55KS5yb3RhdGUodGhpcy5zdGFydEFuZ2xlLHRoaXMucGMpfWdldCBlbmQoKXtyZXR1cm4gbmV3IGEuUG9pbnQodGhpcy5wYy54K3RoaXMucix0aGlzLnBjLnkpLnJvdGF0ZSh0aGlzLmVuZEFuZ2xlLHRoaXMucGMpfWdldCBjZW50ZXIoKXtyZXR1cm4gdGhpcy5wYy5jbG9uZSgpfWdldCB2ZXJ0aWNlcygpe3JldHVyblt0aGlzLnN0YXJ0LmNsb25lKCksdGhpcy5lbmQuY2xvbmUoKV19Z2V0IGxlbmd0aCgpe3JldHVybiBNYXRoLmFicyh0aGlzLnN3ZWVwKnRoaXMucil9Z2V0IGJveCgpe2xldCBuPXRoaXMuYnJlYWtUb0Z1bmN0aW9uYWwoKS5yZWR1Y2UoKHIsaSk9PnIubWVyZ2UoaS5zdGFydC5ib3gpLG5ldyBhLkJveCk7cmV0dXJuIG49bi5tZXJnZSh0aGlzLmVuZC5ib3gpLG59Y29udGFpbnModCl7aWYoIWEuVXRpbHMuRVEodGhpcy5wYy5kaXN0YW5jZVRvKHQpWzBdLHRoaXMucikpcmV0dXJuITE7aWYodC5lcXVhbFRvKHRoaXMuc3RhcnQpKXJldHVybiEwO2xldCBuPW5ldyBhLlZlY3Rvcih0aGlzLnBjLHQpLnNsb3BlLHI9bmV3IGEuQXJjKHRoaXMucGMsdGhpcy5yLHRoaXMuc3RhcnRBbmdsZSxuLHRoaXMuY291bnRlckNsb2Nrd2lzZSk7cmV0dXJuIGEuVXRpbHMuTEUoci5sZW5ndGgsdGhpcy5sZW5ndGgpfXNwbGl0KHQpe2lmKHRoaXMuc3RhcnQuZXF1YWxUbyh0KSlyZXR1cm5bbnVsbCx0aGlzLmNsb25lKCldO2lmKHRoaXMuZW5kLmVxdWFsVG8odCkpcmV0dXJuW3RoaXMuY2xvbmUoKSxudWxsXTtsZXQgbj1uZXcgYS5WZWN0b3IodGhpcy5wYyx0KS5zbG9wZTtyZXR1cm5bbmV3IGEuQXJjKHRoaXMucGMsdGhpcy5yLHRoaXMuc3RhcnRBbmdsZSxuLHRoaXMuY291bnRlckNsb2Nrd2lzZSksbmV3IGEuQXJjKHRoaXMucGMsdGhpcy5yLG4sdGhpcy5lbmRBbmdsZSx0aGlzLmNvdW50ZXJDbG9ja3dpc2UpXX1taWRkbGUoKXtsZXQgdD10aGlzLmNvdW50ZXJDbG9ja3dpc2U/dGhpcy5zdGFydEFuZ2xlK3RoaXMuc3dlZXAvMjp0aGlzLnN0YXJ0QW5nbGUtdGhpcy5zd2VlcC8yO3JldHVybiBuZXcgYS5BcmModGhpcy5wYyx0aGlzLnIsdGhpcy5zdGFydEFuZ2xlLHQsdGhpcy5jb3VudGVyQ2xvY2t3aXNlKS5lbmR9cG9pbnRBdExlbmd0aCh0KXtpZih0PnRoaXMubGVuZ3RofHx0PDApcmV0dXJuIG51bGw7aWYodD09PTApcmV0dXJuIHRoaXMuc3RhcnQ7aWYodD09PXRoaXMubGVuZ3RoKXJldHVybiB0aGlzLmVuZDtsZXQgbj10L3RoaXMubGVuZ3RoLHI9dGhpcy5jb3VudGVyQ2xvY2t3aXNlP3RoaXMuc3RhcnRBbmdsZSt0aGlzLnN3ZWVwKm46dGhpcy5zdGFydEFuZ2xlLXRoaXMuc3dlZXAqbjtyZXR1cm4gbmV3IGEuQXJjKHRoaXMucGMsdGhpcy5yLHRoaXMuc3RhcnRBbmdsZSxyLHRoaXMuY291bnRlckNsb2Nrd2lzZSkuZW5kfWNob3JkSGVpZ2h0KCl7cmV0dXJuKDEtTWF0aC5jb3MoTWF0aC5hYnModGhpcy5zd2VlcC8yKSkpKnRoaXMucn1pbnRlcnNlY3QodCl7aWYodCBpbnN0YW5jZW9mIGEuUG9pbnQpcmV0dXJuIHRoaXMuY29udGFpbnModCk/W3RdOltdO2lmKHQgaW5zdGFuY2VvZiBhLkxpbmUpcmV0dXJuIGduKHQsdGhpcyk7aWYodCBpbnN0YW5jZW9mIGEuUmF5KXJldHVybiBScih0LHRoaXMpO2lmKHQgaW5zdGFuY2VvZiBhLkNpcmNsZSlyZXR1cm4gSXIodGhpcyx0KTtpZih0IGluc3RhbmNlb2YgYS5TZWdtZW50KXJldHVybiBLdCh0LHRoaXMpO2lmKHQgaW5zdGFuY2VvZiBhLkJveClyZXR1cm4gQXUodGhpcyx0KTtpZih0IGluc3RhbmNlb2YgYS5BcmMpcmV0dXJuIExvKHRoaXMsdCk7aWYodCBpbnN0YW5jZW9mIGEuUG9seWdvbilyZXR1cm4gUHIodGhpcyx0KTtpZih0IGluc3RhbmNlb2YgYS5NdWx0aWxpbmUpcmV0dXJuIE1lKHRoaXMsdCl9ZGlzdGFuY2VUbyh0KXtpZih0IGluc3RhbmNlb2YgYS5Qb2ludCl7bGV0W24scl09YS5EaXN0YW5jZS5wb2ludDJhcmModCx0aGlzKTtyZXR1cm4gcj1yLnJldmVyc2UoKSxbbixyXX1pZih0IGluc3RhbmNlb2YgYS5DaXJjbGUpe2xldFtuLHJdPWEuRGlzdGFuY2UuYXJjMmNpcmNsZSh0aGlzLHQpO3JldHVybltuLHJdfWlmKHQgaW5zdGFuY2VvZiBhLkxpbmUpe2xldFtuLHJdPWEuRGlzdGFuY2UuYXJjMmxpbmUodGhpcyx0KTtyZXR1cm5bbixyXX1pZih0IGluc3RhbmNlb2YgYS5TZWdtZW50KXtsZXRbbixyXT1hLkRpc3RhbmNlLnNlZ21lbnQyYXJjKHQsdGhpcyk7cmV0dXJuIHI9ci5yZXZlcnNlKCksW24scl19aWYodCBpbnN0YW5jZW9mIGEuQXJjKXtsZXRbbixyXT1hLkRpc3RhbmNlLmFyYzJhcmModGhpcyx0KTtyZXR1cm5bbixyXX1pZih0IGluc3RhbmNlb2YgYS5Qb2x5Z29uKXtsZXRbbixyXT1hLkRpc3RhbmNlLnNoYXBlMnBvbHlnb24odGhpcyx0KTtyZXR1cm5bbixyXX1pZih0IGluc3RhbmNlb2YgYS5QbGFuYXJTZXQpe2xldFtuLHJdPWEuRGlzdGFuY2Uuc2hhcGUycGxhbmFyU2V0KHRoaXMsdCk7cmV0dXJuW24scl19aWYodCBpbnN0YW5jZW9mIGEuTXVsdGlsaW5lKXJldHVybiBhLkRpc3RhbmNlLnNoYXBlMm11bHRpbGluZSh0aGlzLHQpfWJyZWFrVG9GdW5jdGlvbmFsKCl7bGV0IHQ9W10sbj1bMCxNYXRoLlBJLzIsMipNYXRoLlBJLzIsMypNYXRoLlBJLzJdLHI9W3RoaXMucGMudHJhbnNsYXRlKHRoaXMuciwwKSx0aGlzLnBjLnRyYW5zbGF0ZSgwLHRoaXMuciksdGhpcy5wYy50cmFuc2xhdGUoLXRoaXMuciwwKSx0aGlzLnBjLnRyYW5zbGF0ZSgwLC10aGlzLnIpXSxpPVtdO2ZvcihsZXQgcz0wO3M8NDtzKyspcltzXS5vbih0aGlzKSYmaS5wdXNoKG5ldyBhLkFyYyh0aGlzLnBjLHRoaXMucix0aGlzLnN0YXJ0QW5nbGUsbltzXSx0aGlzLmNvdW50ZXJDbG9ja3dpc2UpKTtpZihpLmxlbmd0aD09PTApdC5wdXNoKHRoaXMuY2xvbmUoKSk7ZWxzZXtpLnNvcnQoKGMsbCk9PmMubGVuZ3RoLWwubGVuZ3RoKTtmb3IobGV0IGM9MDtjPGkubGVuZ3RoO2MrKyl7bGV0IGw9dC5sZW5ndGg+MD90W3QubGVuZ3RoLTFdOnZvaWQgMCxoO2w/aD1uZXcgYS5BcmModGhpcy5wYyx0aGlzLnIsbC5lbmRBbmdsZSxpW2NdLmVuZEFuZ2xlLHRoaXMuY291bnRlckNsb2Nrd2lzZSk6aD1uZXcgYS5BcmModGhpcy5wYyx0aGlzLnIsdGhpcy5zdGFydEFuZ2xlLGlbY10uZW5kQW5nbGUsdGhpcy5jb3VudGVyQ2xvY2t3aXNlKSxhLlV0aWxzLkVRXzAoaC5sZW5ndGgpfHx0LnB1c2goaC5jbG9uZSgpKX1sZXQgcz10Lmxlbmd0aD4wP3RbdC5sZW5ndGgtMV06dm9pZCAwLG87cz9vPW5ldyBhLkFyYyh0aGlzLnBjLHRoaXMucixzLmVuZEFuZ2xlLHRoaXMuZW5kQW5nbGUsdGhpcy5jb3VudGVyQ2xvY2t3aXNlKTpvPW5ldyBhLkFyYyh0aGlzLnBjLHRoaXMucix0aGlzLnN0YXJ0QW5nbGUsdGhpcy5lbmRBbmdsZSx0aGlzLmNvdW50ZXJDbG9ja3dpc2UpLCFhLlV0aWxzLkVRXzAoby5sZW5ndGgpJiYhYS5VdGlscy5FUShvLnN3ZWVwLDIqTWF0aC5QSSkmJnQucHVzaChvLmNsb25lKCkpfXJldHVybiB0fXRhbmdlbnRJblN0YXJ0KCl7bGV0IHQ9bmV3IGEuVmVjdG9yKHRoaXMucGMsdGhpcy5zdGFydCksbj10aGlzLmNvdW50ZXJDbG9ja3dpc2U/TWF0aC5QSS8yOi1NYXRoLlBJLzI7cmV0dXJuIHQucm90YXRlKG4pLm5vcm1hbGl6ZSgpfXRhbmdlbnRJbkVuZCgpe2xldCB0PW5ldyBhLlZlY3Rvcih0aGlzLnBjLHRoaXMuZW5kKSxuPXRoaXMuY291bnRlckNsb2Nrd2lzZT8tTWF0aC5QSS8yOk1hdGguUEkvMjtyZXR1cm4gdC5yb3RhdGUobikubm9ybWFsaXplKCl9cmV2ZXJzZSgpe3JldHVybiBuZXcgYS5BcmModGhpcy5wYyx0aGlzLnIsdGhpcy5lbmRBbmdsZSx0aGlzLnN0YXJ0QW5nbGUsIXRoaXMuY291bnRlckNsb2Nrd2lzZSl9dHJhbnNmb3JtKHQ9bmV3IGEuTWF0cml4KXtsZXQgbj10aGlzLnN0YXJ0LnRyYW5zZm9ybSh0KSxyPXRoaXMuZW5kLnRyYW5zZm9ybSh0KSxpPXRoaXMucGMudHJhbnNmb3JtKHQpLHM9dGhpcy5jb3VudGVyQ2xvY2t3aXNlO3JldHVybiB0LmEqdC5kPDAmJihzPSFzKSxhLkFyYy5hcmNTRShpLG4scixzKX1zdGF0aWMgYXJjU0UodCxuLHIsaSl7bGV0e3ZlY3RvcjpzfT1hLG89cyh0LG4pLnNsb3BlLGM9cyh0LHIpLnNsb3BlO2EuVXRpbHMuRVEobyxjKSYmKGMrPTIqTWF0aC5QSSxpPSEwKTtsZXQgbD1zKHQsbikubGVuZ3RoO3JldHVybiBuZXcgYS5BcmModCxsLG8sYyxpKX1kZWZpbml0ZUludGVncmFsKHQ9MCl7cmV0dXJuIHRoaXMuYnJlYWtUb0Z1bmN0aW9uYWwoKS5yZWR1Y2UoKGkscyk9Pmkrcy5jaXJjdWxhclNlZ21lbnREZWZpbml0ZUludGVncmFsKHQpLDApfWNpcmN1bGFyU2VnbWVudERlZmluaXRlSW50ZWdyYWwodCl7bGV0IG49bmV3IGEuTGluZSh0aGlzLnN0YXJ0LHRoaXMuZW5kKSxyPXRoaXMucGMubGVmdFRvKG4pLHM9bmV3IGEuU2VnbWVudCh0aGlzLnN0YXJ0LHRoaXMuZW5kKS5kZWZpbml0ZUludGVncmFsKHQpLG89dGhpcy5jaXJjdWxhclNlZ21lbnRBcmVhKCk7cmV0dXJuIHI/cy1vOnMrb31jaXJjdWxhclNlZ21lbnRBcmVhKCl7cmV0dXJuIC41KnRoaXMucip0aGlzLnIqKHRoaXMuc3dlZXAtTWF0aC5zaW4odGhpcy5zd2VlcCkpfXNvcnRQb2ludHModCl7bGV0e3ZlY3RvcjpufT1hO3JldHVybiB0LnNsaWNlKCkuc29ydCgocixpKT0+e2xldCBzPW4odGhpcy5wYyxyKS5zbG9wZSxvPW4odGhpcy5wYyxpKS5zbG9wZTtyZXR1cm4gczxvPy0xOnM+bz8xOjB9KX1nZXQgbmFtZSgpe3JldHVybiJhcmMifXN2Zyh0PXt9KXtsZXQgbj10aGlzLnN3ZWVwPD1NYXRoLlBJPyIwIjoiMSIscj10aGlzLmNvdW50ZXJDbG9ja3dpc2U/IjEiOiIwIjtyZXR1cm4gYS5VdGlscy5FUSh0aGlzLnN3ZWVwLDIqTWF0aC5QSSk/bmV3IGEuQ2lyY2xlKHRoaXMucGMsdGhpcy5yKS5zdmcodCk6YAo8cGF0aCBkPSJNJHt0aGlzLnN0YXJ0Lnh9LCR7dGhpcy5zdGFydC55fQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIEEke3RoaXMucn0sJHt0aGlzLnJ9IDAgJHtufSwke3J9ICR7dGhpcy5lbmQueH0sJHt0aGlzLmVuZC55fSIKICAgICAgICAgICAgICAgICAgICAkeyR0KHtmaWxsOiJub25lIiwuLi50fSl9IC8+YH19YS5BcmM9ZDA7Y29uc3QgZzA9KC4uLmUpPT5uZXcgYS5BcmMoLi4uZSk7YS5hcmM9ZzA7Y2xhc3MgSWUgZXh0ZW5kcyBMdHtjb25zdHJ1Y3Rvcih0PXZvaWQgMCxuPXZvaWQgMCxyPXZvaWQgMCxpPXZvaWQgMCl7c3VwZXIoKSx0aGlzLnhtaW49dCx0aGlzLnltaW49bix0aGlzLnhtYXg9cix0aGlzLnltYXg9aX1jbG9uZSgpe3JldHVybiBuZXcgSWUodGhpcy54bWluLHRoaXMueW1pbix0aGlzLnhtYXgsdGhpcy55bWF4KX1nZXQgbG93KCl7cmV0dXJuIG5ldyBhLlBvaW50KHRoaXMueG1pbix0aGlzLnltaW4pfWdldCBoaWdoKCl7cmV0dXJuIG5ldyBhLlBvaW50KHRoaXMueG1heCx0aGlzLnltYXgpfWdldCBtYXgoKXtyZXR1cm4gdGhpcy5jbG9uZSgpfWdldCBjZW50ZXIoKXtyZXR1cm4gbmV3IGEuUG9pbnQoKHRoaXMueG1pbit0aGlzLnhtYXgpLzIsKHRoaXMueW1pbit0aGlzLnltYXgpLzIpfWdldCB3aWR0aCgpe3JldHVybiBNYXRoLmFicyh0aGlzLnhtYXgtdGhpcy54bWluKX1nZXQgaGVpZ2h0KCl7cmV0dXJuIE1hdGguYWJzKHRoaXMueW1heC10aGlzLnltaW4pfWdldCBib3goKXtyZXR1cm4gdGhpcy5jbG9uZSgpfW5vdF9pbnRlcnNlY3QodCl7cmV0dXJuIHRoaXMueG1heDx0LnhtaW58fHRoaXMueG1pbj50LnhtYXh8fHRoaXMueW1heDx0LnltaW58fHRoaXMueW1pbj50LnltYXh9aW50ZXJzZWN0KHQpe3JldHVybiF0aGlzLm5vdF9pbnRlcnNlY3QodCl9bWVyZ2UodCl7cmV0dXJuIG5ldyBJZSh0aGlzLnhtaW49PT12b2lkIDA/dC54bWluOk1hdGgubWluKHRoaXMueG1pbix0LnhtaW4pLHRoaXMueW1pbj09PXZvaWQgMD90LnltaW46TWF0aC5taW4odGhpcy55bWluLHQueW1pbiksdGhpcy54bWF4PT09dm9pZCAwP3QueG1heDpNYXRoLm1heCh0aGlzLnhtYXgsdC54bWF4KSx0aGlzLnltYXg9PT12b2lkIDA/dC55bWF4Ok1hdGgubWF4KHRoaXMueW1heCx0LnltYXgpKX1sZXNzX3RoYW4odCl7cmV0dXJuISEodGhpcy5sb3cubGVzc1RoYW4odC5sb3cpfHx0aGlzLmxvdy5lcXVhbFRvKHQubG93KSYmdGhpcy5oaWdoLmxlc3NUaGFuKHQuaGlnaCkpfWVxdWFsX3RvKHQpe3JldHVybiB0aGlzLmxvdy5lcXVhbFRvKHQubG93KSYmdGhpcy5oaWdoLmVxdWFsVG8odC5oaWdoKX1vdXRwdXQoKXtyZXR1cm4gdGhpcy5jbG9uZSgpfXN0YXRpYyBjb21wYXJhYmxlX21heCh0LG4pe3JldHVybiB0Lm1lcmdlKG4pfXN0YXRpYyBjb21wYXJhYmxlX2xlc3NfdGhhbih0LG4pe3JldHVybiB0Lmxlc3NUaGFuKG4pfXNldCh0LG4scixpKXt0aGlzLnhtaW49dCx0aGlzLnltaW49bix0aGlzLnhtYXg9cix0aGlzLnltYXg9aX10b1BvaW50cygpe3JldHVybltuZXcgYS5Qb2ludCh0aGlzLnhtaW4sdGhpcy55bWluKSxuZXcgYS5Qb2ludCh0aGlzLnhtYXgsdGhpcy55bWluKSxuZXcgYS5Qb2ludCh0aGlzLnhtYXgsdGhpcy55bWF4KSxuZXcgYS5Qb2ludCh0aGlzLnhtaW4sdGhpcy55bWF4KV19dG9TZWdtZW50cygpe2xldCB0PXRoaXMudG9Qb2ludHMoKTtyZXR1cm5bbmV3IGEuU2VnbWVudCh0WzBdLHRbMV0pLG5ldyBhLlNlZ21lbnQodFsxXSx0WzJdKSxuZXcgYS5TZWdtZW50KHRbMl0sdFszXSksbmV3IGEuU2VnbWVudCh0WzNdLHRbMF0pXX1yb3RhdGUodCxuPW5ldyBhLlBvaW50KXt0aHJvdyBELk9QRVJBVElPTl9JU19OT1RfU1VQUE9SVEVEfXRyYW5zZm9ybSh0PW5ldyBhLk1hdHJpeCl7cmV0dXJuIHRoaXMudG9Qb2ludHMoKS5tYXAocj0+ci50cmFuc2Zvcm0odCkpLnJlZHVjZSgocixpKT0+ci5tZXJnZShpLmJveCksbmV3IEllKX1jb250YWlucyh0KXtpZih0IGluc3RhbmNlb2YgYS5Qb2ludClyZXR1cm4gdC54Pj10aGlzLnhtaW4mJnQueDw9dGhpcy54bWF4JiZ0Lnk+PXRoaXMueW1pbiYmdC55PD10aGlzLnltYXg7aWYodCBpbnN0YW5jZW9mIGEuU2VnbWVudClyZXR1cm4gdC52ZXJ0aWNlcy5ldmVyeShuPT50aGlzLmNvbnRhaW5zKG4pKTtpZih0IGluc3RhbmNlb2YgYS5Cb3gpcmV0dXJuIHQudG9TZWdtZW50cygpLmV2ZXJ5KG49PnRoaXMuY29udGFpbnMobikpO2lmKHQgaW5zdGFuY2VvZiBhLkNpcmNsZSlyZXR1cm4gdGhpcy5jb250YWlucyh0LmJveCk7aWYodCBpbnN0YW5jZW9mIGEuQXJjKXJldHVybiB0LnZlcnRpY2VzLmV2ZXJ5KG49PnRoaXMuY29udGFpbnMobikpJiZ0LnRvU2VnbWVudHMoKS5ldmVyeShuPT5LdChuLHQpLmxlbmd0aD09PTApO2lmKHQgaW5zdGFuY2VvZiBhLkxpbmV8fHQgaW5zdGFuY2VvZiBhLlJheSlyZXR1cm4hMTtpZih0IGluc3RhbmNlb2YgYS5NdWx0aWxpbmUpcmV0dXJuIHQudG9TaGFwZXMoKS5ldmVyeShuPT50aGlzLmNvbnRhaW5zKG4pKTtpZih0IGluc3RhbmNlb2YgYS5Qb2x5Z29uKXJldHVybiB0aGlzLmNvbnRhaW5zKHQuYm94KX1kaXN0YW5jZVRvKHQpe2NvbnN0IG49dGhpcy50b1NlZ21lbnRzKCkubWFwKGk9PmkuZGlzdGFuY2VUbyh0KSk7bGV0IHI9W051bWJlci5NQVhfU0FGRV9JTlRFR0VSLG51bGxdO3JldHVybiBuLmZvckVhY2goaT0+e2lbMF08clswXSYmKHI9aSl9KSxyfWdldCBuYW1lKCl7cmV0dXJuImJveCJ9c3ZnKHQ9e30pe2NvbnN0IG49dGhpcy54bWF4LXRoaXMueG1pbixyPXRoaXMueW1heC10aGlzLnltaW47cmV0dXJuYAo8cmVjdCB4PSIke3RoaXMueG1pbn0iIHk9IiR7dGhpcy55bWlufSIgd2lkdGg9IiR7bn0iIGhlaWdodD0iJHtyfSIKICAgICAgICAgICAgICAgICR7JHQoe2ZpbGw6Im5vbmUiLC4uLnR9KX0gLz5gfX1hLkJveD1JZTtjb25zdCBtMD0oLi4uZSk9Pm5ldyBhLkJveCguLi5lKTthLmJveD1tMDtjbGFzcyBwMHtjb25zdHJ1Y3Rvcih0KXt0aGlzLnNoYXBlPXQsdGhpcy5uZXh0PXZvaWQgMCx0aGlzLnByZXY9dm9pZCAwLHRoaXMuZmFjZT12b2lkIDAsdGhpcy5hcmNfbGVuZ3RoPTAsdGhpcy5idlN0YXJ0PXZvaWQgMCx0aGlzLmJ2RW5kPXZvaWQgMCx0aGlzLmJ2PXZvaWQgMCx0aGlzLm92ZXJsYXA9dm9pZCAwfWdldCBzdGFydCgpe3JldHVybiB0aGlzLnNoYXBlLnN0YXJ0fWdldCBlbmQoKXtyZXR1cm4gdGhpcy5zaGFwZS5lbmR9Z2V0IGxlbmd0aCgpe3JldHVybiB0aGlzLnNoYXBlLmxlbmd0aH1nZXQgYm94KCl7cmV0dXJuIHRoaXMuc2hhcGUuYm94fWdldCBpc1NlZ21lbnQoKXtyZXR1cm4gdGhpcy5zaGFwZSBpbnN0YW5jZW9mIGEuU2VnbWVudH1nZXQgaXNBcmMoKXtyZXR1cm4gdGhpcy5zaGFwZSBpbnN0YW5jZW9mIGEuQXJjfWdldCBpc0xpbmUoKXtyZXR1cm4gdGhpcy5zaGFwZSBpbnN0YW5jZW9mIGEuTGluZX1nZXQgaXNSYXkoKXtyZXR1cm4gdGhpcy5zaGFwZSBpbnN0YW5jZW9mIGEuUmF5fW1pZGRsZSgpe3JldHVybiB0aGlzLnNoYXBlLm1pZGRsZSgpfXBvaW50QXRMZW5ndGgodCl7cmV0dXJuIHRoaXMuc2hhcGUucG9pbnRBdExlbmd0aCh0KX1jb250YWlucyh0KXtyZXR1cm4gdGhpcy5zaGFwZS5jb250YWlucyh0KX1zZXRJbmNsdXNpb24odCl7aWYodGhpcy5idiE9PXZvaWQgMClyZXR1cm4gdGhpcy5idjtpZih0aGlzLnNoYXBlIGluc3RhbmNlb2YgYS5MaW5lfHx0aGlzLnNoYXBlIGluc3RhbmNlb2YgYS5SYXkpcmV0dXJuIHRoaXMuYnY9YS5PVVRTSURFLHRoaXMuYnY7aWYodGhpcy5idlN0YXJ0PT09dm9pZCAwJiYodGhpcy5idlN0YXJ0PUVlKHQsdGhpcy5zdGFydCkpLHRoaXMuYnZFbmQ9PT12b2lkIDAmJih0aGlzLmJ2RW5kPUVlKHQsdGhpcy5lbmQpKSx0aGlzLmJ2U3RhcnQ9PT1hLk9VVFNJREV8fHRoaXMuYnZFbmQ9PWEuT1VUU0lERSl0aGlzLmJ2PWEuT1VUU0lERTtlbHNlIGlmKHRoaXMuYnZTdGFydD09PWEuSU5TSURFfHx0aGlzLmJ2RW5kPT1hLklOU0lERSl0aGlzLmJ2PWEuSU5TSURFO2Vsc2V7bGV0IG49RWUodCx0aGlzLm1pZGRsZSgpKTt0aGlzLmJ2PW59cmV0dXJuIHRoaXMuYnZ9c2V0T3ZlcmxhcCh0KXtsZXQgbixyPXRoaXMuc2hhcGUsaT10LnNoYXBlO3IgaW5zdGFuY2VvZiBhLlNlZ21lbnQmJmkgaW5zdGFuY2VvZiBhLlNlZ21lbnQ/ci5zdGFydC5lcXVhbFRvKGkuc3RhcnQpJiZyLmVuZC5lcXVhbFRvKGkuZW5kKT9uPWEuT1ZFUkxBUF9TQU1FOnIuc3RhcnQuZXF1YWxUbyhpLmVuZCkmJnIuZW5kLmVxdWFsVG8oaS5zdGFydCkmJihuPWEuT1ZFUkxBUF9PUFBPU0lURSk6KHIgaW5zdGFuY2VvZiBhLkFyYyYmaSBpbnN0YW5jZW9mIGEuQXJjfHxyIGluc3RhbmNlb2YgYS5TZWdtZW50JiZpIGluc3RhbmNlb2YgYS5BcmN8fHIgaW5zdGFuY2VvZiBhLkFyYyYmaSBpbnN0YW5jZW9mIGEuU2VnbWVudCkmJihyLnN0YXJ0LmVxdWFsVG8oaS5zdGFydCkmJnIuZW5kLmVxdWFsVG8oaS5lbmQpJiZyLm1pZGRsZSgpLmVxdWFsVG8oaS5taWRkbGUoKSk/bj1hLk9WRVJMQVBfU0FNRTpyLnN0YXJ0LmVxdWFsVG8oaS5lbmQpJiZyLmVuZC5lcXVhbFRvKGkuc3RhcnQpJiZyLm1pZGRsZSgpLmVxdWFsVG8oaS5taWRkbGUoKSkmJihuPWEuT1ZFUkxBUF9PUFBPU0lURSkpLHRoaXMub3ZlcmxhcD09PXZvaWQgMCYmKHRoaXMub3ZlcmxhcD1uKSx0Lm92ZXJsYXA9PT12b2lkIDAmJih0Lm92ZXJsYXA9bil9c3ZnKCl7aWYodGhpcy5zaGFwZSBpbnN0YW5jZW9mIGEuU2VnbWVudClyZXR1cm5gIEwke3RoaXMuc2hhcGUuZW5kLnh9LCR7dGhpcy5zaGFwZS5lbmQueX1gO2lmKHRoaXMuc2hhcGUgaW5zdGFuY2VvZiBhLkFyYyl7bGV0IHQ9dGhpcy5zaGFwZSxuLHI9dC5jb3VudGVyQ2xvY2t3aXNlPyIxIjoiMCI7aWYoYS5VdGlscy5FUSh0LnN3ZWVwLDIqTWF0aC5QSSkpe2xldCBpPXQuY291bnRlckNsb2Nrd2lzZT8xOi0xLHM9bmV3IGEuQXJjKHQucGMsdC5yLHQuc3RhcnRBbmdsZSx0LnN0YXJ0QW5nbGUraSpNYXRoLlBJLHQuY291bnRlckNsb2Nrd2lzZSksbz1uZXcgYS5BcmModC5wYyx0LnIsdC5zdGFydEFuZ2xlK2kqTWF0aC5QSSx0LmVuZEFuZ2xlLHQuY291bnRlckNsb2Nrd2lzZSk7cmV0dXJuIG49IjAiLGAgQSR7cy5yfSwke3Mucn0gMCAke259LCR7cn0gJHtzLmVuZC54fSwke3MuZW5kLnl9CiAgICAgICAgICAgICAgICAgICAgQSR7by5yfSwke28ucn0gMCAke259LCR7cn0gJHtvLmVuZC54fSwke28uZW5kLnl9YH1lbHNlIHJldHVybiBuPXQuc3dlZXA8PU1hdGguUEk/IjAiOiIxIixgIEEke3Qucn0sJHt0LnJ9IDAgJHtufSwke3J9ICR7dC5lbmQueH0sJHt0LmVuZC55fWB9fXRvSlNPTigpe3JldHVybiB0aGlzLnNoYXBlLnRvSlNPTigpfX1hLkVkZ2U9cDA7Y2xhc3MgXzAgZXh0ZW5kcyBicntjb25zdHJ1Y3Rvcih0LG4pe3N1cGVyKHQsbiksdGhpcy5zZXRDaXJjdWxhckxpbmtzKCl9c2V0Q2lyY3VsYXJMaW5rcygpe3RoaXMuaXNFbXB0eSgpfHwodGhpcy5sYXN0Lm5leHQ9dGhpcy5maXJzdCx0aGlzLmZpcnN0LnByZXY9dGhpcy5sYXN0KX1bU3ltYm9sLml0ZXJhdG9yXSgpe2xldCB0O3JldHVybntuZXh0OigpPT57bGV0IG49dHx8dGhpcy5maXJzdCxyPXRoaXMuZmlyc3Q/dD90PT09dGhpcy5maXJzdDohMTohMDtyZXR1cm4gdD1uP24ubmV4dDp2b2lkIDAse3ZhbHVlOm4sZG9uZTpyfX19fWFwcGVuZCh0KXtyZXR1cm4gc3VwZXIuYXBwZW5kKHQpLHRoaXMuc2V0Q2lyY3VsYXJMaW5rcygpLHRoaXN9aW5zZXJ0KHQsbil7cmV0dXJuIHN1cGVyLmluc2VydCh0LG4pLHRoaXMuc2V0Q2lyY3VsYXJMaW5rcygpLHRoaXN9cmVtb3ZlKHQpe3JldHVybiBzdXBlci5yZW1vdmUodCksdGhpc319Y2xhc3MgaWUgZXh0ZW5kcyBfMHtjb25zdHJ1Y3Rvcih0LC4uLm4pe2lmKHN1cGVyKCksdGhpcy5fYm94PXZvaWQgMCx0aGlzLl9vcmllbnRhdGlvbj12b2lkIDAsbi5sZW5ndGghPT0wKXtpZihuLmxlbmd0aD09PTEpe2lmKG5bMF1pbnN0YW5jZW9mIEFycmF5KXtsZXQgcj1uWzBdO2lmKHIubGVuZ3RoPT09MClyZXR1cm47aWYoci5ldmVyeShpPT5pIGluc3RhbmNlb2YgYS5Qb2ludCkpe2xldCBpPWllLnBvaW50czJzZWdtZW50cyhyKTt0aGlzLnNoYXBlczJmYWNlKHQuZWRnZXMsaSl9ZWxzZSBpZihyLmV2ZXJ5KGk9PmkgaW5zdGFuY2VvZiBBcnJheSYmaS5sZW5ndGg9PT0yKSl7bGV0IGk9ci5tYXAobz0+bmV3IGEuUG9pbnQob1swXSxvWzFdKSkscz1pZS5wb2ludHMyc2VnbWVudHMoaSk7dGhpcy5zaGFwZXMyZmFjZSh0LmVkZ2VzLHMpfWVsc2UgaWYoci5ldmVyeShpPT5pIGluc3RhbmNlb2YgYS5TZWdtZW50fHxpIGluc3RhbmNlb2YgYS5BcmMpKXRoaXMuc2hhcGVzMmZhY2UodC5lZGdlcyxyKTtlbHNlIGlmKHIuZXZlcnkoaT0+aS5uYW1lPT09InNlZ21lbnQifHxpLm5hbWU9PT0iYXJjIikpe2xldCBpPVtdO2ZvcihsZXQgcyBvZiByKXtsZXQgbztzLm5hbWU9PT0ic2VnbWVudCI/bz1uZXcgYS5TZWdtZW50KHMpOm89bmV3IGEuQXJjKHMpLGkucHVzaChvKX10aGlzLnNoYXBlczJmYWNlKHQuZWRnZXMsaSl9fWVsc2UgaWYoblswXWluc3RhbmNlb2YgaWUpe2xldCByPW5bMF07dGhpcy5maXJzdD1yLmZpcnN0LHRoaXMubGFzdD1yLmxhc3Q7Zm9yKGxldCBpIG9mIHIpdC5lZGdlcy5hZGQoaSl9ZWxzZSBpZihuWzBdaW5zdGFuY2VvZiBhLkNpcmNsZSl0aGlzLnNoYXBlczJmYWNlKHQuZWRnZXMsW25bMF0udG9BcmMoQW8pXSk7ZWxzZSBpZihuWzBdaW5zdGFuY2VvZiBhLkJveCl7bGV0IHI9blswXTt0aGlzLnNoYXBlczJmYWNlKHQuZWRnZXMsW25ldyBhLlNlZ21lbnQobmV3IGEuUG9pbnQoci54bWluLHIueW1pbiksbmV3IGEuUG9pbnQoci54bWF4LHIueW1pbikpLG5ldyBhLlNlZ21lbnQobmV3IGEuUG9pbnQoci54bWF4LHIueW1pbiksbmV3IGEuUG9pbnQoci54bWF4LHIueW1heCkpLG5ldyBhLlNlZ21lbnQobmV3IGEuUG9pbnQoci54bWF4LHIueW1heCksbmV3IGEuUG9pbnQoci54bWluLHIueW1heCkpLG5ldyBhLlNlZ21lbnQobmV3IGEuUG9pbnQoci54bWluLHIueW1heCksbmV3IGEuUG9pbnQoci54bWluLHIueW1pbikpXSl9fW4ubGVuZ3RoPT09MiYmblswXWluc3RhbmNlb2YgYS5FZGdlJiZuWzFdaW5zdGFuY2VvZiBhLkVkZ2UmJih0aGlzLmZpcnN0PW5bMF0sdGhpcy5sYXN0PW5bMV0sdGhpcy5sYXN0Lm5leHQ9dGhpcy5maXJzdCx0aGlzLmZpcnN0LnByZXY9dGhpcy5sYXN0LHRoaXMuc2V0QXJjTGVuZ3RoKCkpfX1nZXQgZWRnZXMoKXtyZXR1cm4gdGhpcy50b0FycmF5KCl9Z2V0IHNoYXBlcygpe3JldHVybiB0aGlzLmVkZ2VzLm1hcCh0PT50LnNoYXBlLmNsb25lKCkpfWdldCBib3goKXtpZih0aGlzLl9ib3g9PT12b2lkIDApe2xldCB0PW5ldyBhLkJveDtmb3IobGV0IG4gb2YgdGhpcyl0PXQubWVyZ2Uobi5ib3gpO3RoaXMuX2JveD10fXJldHVybiB0aGlzLl9ib3h9Z2V0IHBlcmltZXRlcigpe3JldHVybiB0aGlzLmxhc3QuYXJjX2xlbmd0aCt0aGlzLmxhc3QubGVuZ3RofXBvaW50QXRMZW5ndGgodCl7aWYodD50aGlzLnBlcmltZXRlcnx8dDwwKXJldHVybiBudWxsO2xldCBuPW51bGw7Zm9yKGxldCByIG9mIHRoaXMpaWYodD49ci5hcmNfbGVuZ3RoJiYocj09PXRoaXMubGFzdHx8dDxyLm5leHQuYXJjX2xlbmd0aCkpe249ci5wb2ludEF0TGVuZ3RoKHQtci5hcmNfbGVuZ3RoKTticmVha31yZXR1cm4gbn1zdGF0aWMgcG9pbnRzMnNlZ21lbnRzKHQpe2xldCBuPVtdO2ZvcihsZXQgcj0wO3I8dC5sZW5ndGg7cisrKXRbcl0uZXF1YWxUbyh0WyhyKzEpJXQubGVuZ3RoXSl8fG4ucHVzaChuZXcgYS5TZWdtZW50KHRbcl0sdFsocisxKSV0Lmxlbmd0aF0pKTtyZXR1cm4gbn1zaGFwZXMyZmFjZSh0LG4pe2ZvcihsZXQgciBvZiBuKXtsZXQgaT1uZXcgYS5FZGdlKHIpO3RoaXMuYXBwZW5kKGkpLHQuYWRkKGkpfX1hcHBlbmQodCl7cmV0dXJuIHN1cGVyLmFwcGVuZCh0KSx0aGlzLnNldE9uZUVkZ2VBcmNMZW5ndGgodCksdC5mYWNlPXRoaXMsdGhpc31pbnNlcnQodCxuKXtyZXR1cm4gc3VwZXIuaW5zZXJ0KHQsbiksdGhpcy5zZXRPbmVFZGdlQXJjTGVuZ3RoKHQpLHQuZmFjZT10aGlzLHRoaXN9cmVtb3ZlKHQpe3JldHVybiBzdXBlci5yZW1vdmUodCksdGhpcy5zZXRBcmNMZW5ndGgoKSx0aGlzfW1lcmdlX3dpdGhfbmV4dF9lZGdlKHQpe3JldHVybiB0LnNoYXBlLmVuZC54PXQubmV4dC5zaGFwZS5lbmQueCx0LnNoYXBlLmVuZC55PXQubmV4dC5zaGFwZS5lbmQueSx0aGlzLnJlbW92ZSh0Lm5leHQpLHRoaXN9cmV2ZXJzZSgpe2xldCB0PVtdLG49dGhpcy5sYXN0O2RvIG4uc2hhcGU9bi5zaGFwZS5yZXZlcnNlKCksdC5wdXNoKG4pLG49bi5wcmV2O3doaWxlKG4hPT10aGlzLmxhc3QpO3RoaXMuZmlyc3Q9dm9pZCAwLHRoaXMubGFzdD12b2lkIDA7Zm9yKGxldCByIG9mIHQpdGhpcy5maXJzdD09PXZvaWQgMD8oci5wcmV2PXIsci5uZXh0PXIsdGhpcy5maXJzdD1yLHRoaXMubGFzdD1yKTooci5wcmV2PXRoaXMubGFzdCx0aGlzLmxhc3QubmV4dD1yLHRoaXMubGFzdD1yLHRoaXMubGFzdC5uZXh0PXRoaXMuZmlyc3QsdGhpcy5maXJzdC5wcmV2PXRoaXMubGFzdCksdGhpcy5zZXRPbmVFZGdlQXJjTGVuZ3RoKHIpO3RoaXMuX29yaWVudGF0aW9uIT09dm9pZCAwJiYodGhpcy5fb3JpZW50YXRpb249dm9pZCAwLHRoaXMuX29yaWVudGF0aW9uPXRoaXMub3JpZW50YXRpb24oKSl9c2V0QXJjTGVuZ3RoKCl7Zm9yKGxldCB0IG9mIHRoaXMpdGhpcy5zZXRPbmVFZGdlQXJjTGVuZ3RoKHQpLHQuZmFjZT10aGlzfXNldE9uZUVkZ2VBcmNMZW5ndGgodCl7dD09PXRoaXMuZmlyc3Q/dC5hcmNfbGVuZ3RoPTA6dC5hcmNfbGVuZ3RoPXQucHJldi5hcmNfbGVuZ3RoK3QucHJldi5sZW5ndGh9YXJlYSgpe3JldHVybiBNYXRoLmFicyh0aGlzLnNpZ25lZEFyZWEoKSl9c2lnbmVkQXJlYSgpe2xldCB0PTAsbj10aGlzLmJveC55bWluO2ZvcihsZXQgciBvZiB0aGlzKXQrPXIuc2hhcGUuZGVmaW5pdGVJbnRlZ3JhbChuKTtyZXR1cm4gdH1vcmllbnRhdGlvbigpe2lmKHRoaXMuX29yaWVudGF0aW9uPT09dm9pZCAwKXtsZXQgdD10aGlzLnNpZ25lZEFyZWEoKTthLlV0aWxzLkVRXzAodCk/dGhpcy5fb3JpZW50YXRpb249Zm4uTk9UX09SSUVOVEFCTEU6YS5VdGlscy5MVCh0LDApP3RoaXMuX29yaWVudGF0aW9uPWZuLkNDVzp0aGlzLl9vcmllbnRhdGlvbj1mbi5DV31yZXR1cm4gdGhpcy5fb3JpZW50YXRpb259aXNTaW1wbGUodCl7cmV0dXJuIGllLmdldFNlbGZJbnRlcnNlY3Rpb25zKHRoaXMsdCwhMCkubGVuZ3RoPT09MH1zdGF0aWMgZ2V0U2VsZkludGVyc2VjdGlvbnModCxuLHI9ITEpe2xldCBpPVtdO2ZvcihsZXQgcyBvZiB0KXtsZXQgbz1uLnNlYXJjaChzLmJveCk7Zm9yKGxldCBjIG9mIG8pe2lmKHM9PT1jfHxjLmZhY2UhPT10fHxzLnNoYXBlIGluc3RhbmNlb2YgYS5TZWdtZW50JiZjLnNoYXBlIGluc3RhbmNlb2YgYS5TZWdtZW50JiYocy5uZXh0PT09Y3x8cy5wcmV2PT09YykpY29udGludWU7bGV0IGw9cy5zaGFwZS5pbnRlcnNlY3QoYy5zaGFwZSk7Zm9yKGxldCBoIG9mIGwpaWYoIShoLmVxdWFsVG8ocy5zdGFydCkmJmguZXF1YWxUbyhjLmVuZCkmJmM9PT1zLnByZXYpJiYhKGguZXF1YWxUbyhzLmVuZCkmJmguZXF1YWxUbyhjLnN0YXJ0KSYmYz09PXMubmV4dCkmJihpLnB1c2goaCkscikpYnJlYWs7aWYoaS5sZW5ndGg+MCYmcilicmVha31pZihpLmxlbmd0aD4wJiZyKWJyZWFrfXJldHVybiBpfWZpbmRFZGdlQnlQb2ludCh0KXtsZXQgbjtmb3IobGV0IHIgb2YgdGhpcylpZighdC5lcXVhbFRvKHIuc2hhcGUuc3RhcnQpJiYodC5lcXVhbFRvKHIuc2hhcGUuZW5kKXx8ci5zaGFwZS5jb250YWlucyh0KSkpe249cjticmVha31yZXR1cm4gbn10b1BvbHlnb24oKXtyZXR1cm4gbmV3IGEuUG9seWdvbih0aGlzLnNoYXBlcyl9dG9KU09OKCl7cmV0dXJuIHRoaXMuZWRnZXMubWFwKHQ9PnQudG9KU09OKCkpfXN2Zygpe2xldCB0PWBNJHt0aGlzLmZpcnN0LnN0YXJ0Lnh9LCR7dGhpcy5maXJzdC5zdGFydC55fWA7Zm9yKGxldCBuIG9mIHRoaXMpdCs9bi5zdmcoKTtyZXR1cm4gdCs9IiB6Iix0fX1hLkZhY2U9aWU7Y2xhc3MgVXIgZXh0ZW5kcyBMdHtjb25zdHJ1Y3RvciguLi50KXtpZihzdXBlcigpLHRoaXMucHQ9bmV3IGEuUG9pbnQsdGhpcy5ub3JtPW5ldyBhLlZlY3RvcigwLDEpLHQubGVuZ3RoIT09MCYmKHQubGVuZ3RoPj0xJiZ0WzBdaW5zdGFuY2VvZiBhLlBvaW50JiYodGhpcy5wdD10WzBdLmNsb25lKCkpLHQubGVuZ3RoIT09MSkpe2lmKHQubGVuZ3RoPT09MiYmdFsxXWluc3RhbmNlb2YgYS5WZWN0b3Ipe3RoaXMubm9ybT10WzFdLmNsb25lKCk7cmV0dXJufXRocm93IEQuSUxMRUdBTF9QQVJBTUVURVJTfX1jbG9uZSgpe3JldHVybiBuZXcgVXIodGhpcy5wdCx0aGlzLm5vcm0pfWdldCBzbG9wZSgpe3JldHVybiBuZXcgYS5WZWN0b3IodGhpcy5ub3JtLnksLXRoaXMubm9ybS54KS5zbG9wZX1nZXQgYm94KCl7bGV0IHQ9dGhpcy5zbG9wZTtyZXR1cm4gbmV3IGEuQm94KHQ+TWF0aC5QSS8yJiZ0PDMqTWF0aC5QSS8yP051bWJlci5ORUdBVElWRV9JTkZJTklUWTp0aGlzLnB0LngsdD49MCYmdDw9TWF0aC5QST90aGlzLnB0Lnk6TnVtYmVyLk5FR0FUSVZFX0lORklOSVRZLHQ+PU1hdGguUEkvMiYmdDw9MypNYXRoLlBJLzI/dGhpcy5wdC54Ok51bWJlci5QT1NJVElWRV9JTkZJTklUWSx0Pj1NYXRoLlBJJiZ0PD0yKk1hdGguUEl8fHQ9PT0wP3RoaXMucHQueTpOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFkpfWdldCBzdGFydCgpe3JldHVybiB0aGlzLnB0fWdldCBlbmQoKXt9Z2V0IGxlbmd0aCgpe3JldHVybiBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFl9Y29udGFpbnModCl7aWYodGhpcy5wdC5lcXVhbFRvKHQpKXJldHVybiEwO2xldCBuPW5ldyBhLlZlY3Rvcih0aGlzLnB0LHQpO3JldHVybiBhLlV0aWxzLkVRXzAodGhpcy5ub3JtLmRvdChuKSkmJmEuVXRpbHMuR0Uobi5jcm9zcyh0aGlzLm5vcm0pLDApfWNvb3JkKHQpe3JldHVybiBpYyh0LngsdC55KS5jcm9zcyh0aGlzLm5vcm0pfXNwbGl0KHQpe3JldHVybiB0aGlzLmNvbnRhaW5zKHQpP3RoaXMucHQuZXF1YWxUbyh0KT9bdGhpc106W25ldyBhLlNlZ21lbnQodGhpcy5wdCx0KSxuZXcgYS5SYXkodCx0aGlzLm5vcm0pXTpbXX1pbnRlcnNlY3QodCl7aWYodCBpbnN0YW5jZW9mIGEuUG9pbnQpcmV0dXJuIHRoaXMuY29udGFpbnModCk/W3RdOltdO2lmKHQgaW5zdGFuY2VvZiBhLlNlZ21lbnQpcmV0dXJuIExyKHRoaXMsdCk7aWYodCBpbnN0YW5jZW9mIGEuQXJjKXJldHVybiBScih0aGlzLHQpO2lmKHQgaW5zdGFuY2VvZiBhLkxpbmUpcmV0dXJuIHFvKHRoaXMsdCk7aWYodCBpbnN0YW5jZW9mIGEuUmF5KXJldHVybiBTdSh0aGlzLHQpO2lmKHQgaW5zdGFuY2VvZiBhLkNpcmNsZSlyZXR1cm4gRm8odGhpcyx0KTtpZih0IGluc3RhbmNlb2YgYS5Cb3gpcmV0dXJuIEl1KHRoaXMsdCk7aWYodCBpbnN0YW5jZW9mIGEuUG9seWdvbilyZXR1cm4gVW8odGhpcyx0KX1yb3RhdGUodCxuPW5ldyBhLlBvaW50KXtyZXR1cm4gbmV3IGEuUmF5KHRoaXMucHQucm90YXRlKHQsbiksdGhpcy5ub3JtLnJvdGF0ZSh0KSl9dHJhbnNmb3JtKHQpe3JldHVybiBuZXcgYS5SYXkodGhpcy5wdC50cmFuc2Zvcm0odCksdGhpcy5ub3JtLmNsb25lKCkpfWdldCBuYW1lKCl7cmV0dXJuInJheSJ9c3ZnKHQsbj17fSl7bGV0IHI9bmV3IGEuTGluZSh0aGlzLnB0LHRoaXMubm9ybSksaT1RdChyLHQpO3JldHVybiBpPWkuZmlsdGVyKG89PnRoaXMuY29udGFpbnMobykpLGkubGVuZ3RoPT09MHx8aS5sZW5ndGg9PT0yPyIiOm5ldyBhLlNlZ21lbnQodGhpcy5wdCxpWzBdKS5zdmcobil9fWEuUmF5PVVyO2NvbnN0IHkwPSguLi5lKT0+bmV3IGEuUmF5KC4uLmUpO2EucmF5PXkwO2xldCBTZT1jbGFzcyBvZXtjb25zdHJ1Y3Rvcigpe3RoaXMuZmFjZXM9bmV3IGEuUGxhbmFyU2V0LHRoaXMuZWRnZXM9bmV3IGEuUGxhbmFyU2V0O2xldCB0PVsuLi5hcmd1bWVudHNdO2lmKHQubGVuZ3RoPT09MSYmKHRbMF1pbnN0YW5jZW9mIEFycmF5JiZ0WzBdLmxlbmd0aD4wfHx0WzBdaW5zdGFuY2VvZiBhLkNpcmNsZXx8dFswXWluc3RhbmNlb2YgYS5Cb3gpKXtsZXQgbj10WzBdO2lmKHRbMF1pbnN0YW5jZW9mIEFycmF5JiZ0WzBdLmV2ZXJ5KHI9PnIgaW5zdGFuY2VvZiBBcnJheSkpaWYobi5ldmVyeShyPT5yIGluc3RhbmNlb2YgQXJyYXkmJnIubGVuZ3RoPT09MiYmdHlwZW9mIHJbMF09PSJudW1iZXIiJiZ0eXBlb2YgclsxXT09Im51bWJlciIpKXRoaXMuZmFjZXMuYWRkKG5ldyBhLkZhY2UodGhpcyxuKSk7ZWxzZSBmb3IobGV0IHIgb2YgbilpZihyIGluc3RhbmNlb2YgQXJyYXkmJnJbMF1pbnN0YW5jZW9mIEFycmF5JiZyWzBdLmV2ZXJ5KGk9PmkgaW5zdGFuY2VvZiBBcnJheSYmaS5sZW5ndGg9PT0yJiZ0eXBlb2YgaVswXT09Im51bWJlciImJnR5cGVvZiBpWzFdPT0ibnVtYmVyIikpZm9yKGxldCBpIG9mIHIpdGhpcy5mYWNlcy5hZGQobmV3IGEuRmFjZSh0aGlzLGkpKTtlbHNlIHRoaXMuZmFjZXMuYWRkKG5ldyBhLkZhY2UodGhpcyxyKSk7ZWxzZSB0aGlzLmZhY2VzLmFkZChuZXcgYS5GYWNlKHRoaXMsbikpfX1nZXQgYm94KCl7cmV0dXJuWy4uLnRoaXMuZmFjZXNdLnJlZHVjZSgodCxuKT0+dC5tZXJnZShuLmJveCksbmV3IGEuQm94KX1nZXQgdmVydGljZXMoKXtyZXR1cm5bLi4udGhpcy5lZGdlc10ubWFwKHQ9PnQuc3RhcnQpfWNsb25lKCl7bGV0IHQ9bmV3IG9lO2ZvcihsZXQgbiBvZiB0aGlzLmZhY2VzKXQuYWRkRmFjZShuLnNoYXBlcyk7cmV0dXJuIHR9aXNFbXB0eSgpe3JldHVybiB0aGlzLmVkZ2VzLnNpemU9PT0wfWlzVmFsaWQoKXtsZXQgdD0hMDtmb3IobGV0IG4gb2YgdGhpcy5mYWNlcylpZighbi5pc1NpbXBsZSh0aGlzLmVkZ2VzKSl7dD0hMTticmVha31yZXR1cm4gdH1hcmVhKCl7bGV0IHQ9Wy4uLnRoaXMuZmFjZXNdLnJlZHVjZSgobixyKT0+bityLnNpZ25lZEFyZWEoKSwwKTtyZXR1cm4gTWF0aC5hYnModCl9YWRkRmFjZSguLi50KXtsZXQgbj1uZXcgYS5GYWNlKHRoaXMsLi4udCk7cmV0dXJuIHRoaXMuZmFjZXMuYWRkKG4pLG59ZGVsZXRlRmFjZSh0KXtmb3IobGV0IG4gb2YgdCl0aGlzLmVkZ2VzLmRlbGV0ZShuKTtyZXR1cm4gdGhpcy5mYWNlcy5kZWxldGUodCl9cmVjcmVhdGVGYWNlcygpe3RoaXMuZmFjZXMuY2xlYXIoKTtmb3IobGV0IHIgb2YgdGhpcy5lZGdlcylyLmZhY2U9bnVsbDtsZXQgdCxuPSEwO2Zvcig7bjspe249ITE7Zm9yKGxldCByIG9mIHRoaXMuZWRnZXMpaWYoci5mYWNlPT09bnVsbCl7dD1yLG49ITA7YnJlYWt9aWYobil7bGV0IHI9dDtkbyByPXIubmV4dDt3aGlsZShyLm5leHQhPT10KTt0aGlzLmFkZEZhY2UodCxyKX19fXJlbW92ZUNoYWluKHQsbixyKXtpZihyLm5leHQ9PT1uKXt0aGlzLmRlbGV0ZUZhY2UodCk7cmV0dXJufWZvcihsZXQgaT1uO2khPT1yLm5leHQ7aT1pLm5leHQpaWYodC5yZW1vdmUoaSksdGhpcy5lZGdlcy5kZWxldGUoaSksdC5pc0VtcHR5KCkpe3RoaXMuZGVsZXRlRmFjZSh0KTticmVha319YWRkVmVydGV4KHQsbil7bGV0IHI9bi5zaGFwZS5zcGxpdCh0KTtpZihyWzBdPT09bnVsbClyZXR1cm4gbi5wcmV2O2lmKHJbMV09PT1udWxsKXJldHVybiBuO2xldCBpPW5ldyBhLkVkZ2UoclswXSkscz1uLnByZXY7cmV0dXJuIG4uZmFjZS5pbnNlcnQoaSxzKSx0aGlzLmVkZ2VzLmRlbGV0ZShuKSx0aGlzLmVkZ2VzLmFkZChpKSxuLnNoYXBlPXJbMV0sdGhpcy5lZGdlcy5hZGQobiksaX1yZW1vdmVFbmRWZXJ0ZXgodCl7Y29uc3Qgbj10Lm5leHQ7biE9PXQmJih0LmZhY2UubWVyZ2Vfd2l0aF9uZXh0X2VkZ2UodCksdGhpcy5lZGdlcy5kZWxldGUobikpfWN1dCh0KXtsZXQgbj10aGlzLmNsb25lKCkscj17aW50X3BvaW50czE6W10saW50X3BvaW50czI6W10saW50X3BvaW50czFfc29ydGVkOltdLGludF9wb2ludHMyX3NvcnRlZDpbXX07Zm9yKGxldCBvIG9mIHQuZWRnZXMpZm9yKGxldCBjIG9mIG4uZWRnZXMpe2xldCBsPXpvKG8sYyk7Zm9yKGxldCBoIG9mIGwpSnQobyxoLHIuaW50X3BvaW50czEpLEp0KGMsaCxyLmludF9wb2ludHMyKX1pZihyLmludF9wb2ludHMxLmxlbmd0aD09PTApcmV0dXJuIG47ci5pbnRfcG9pbnRzMV9zb3J0ZWQ9UHQoci5pbnRfcG9pbnRzMSksci5pbnRfcG9pbnRzMl9zb3J0ZWQ9UHQoci5pbnRfcG9pbnRzMiksdGUodCxyLmludF9wb2ludHMxX3NvcnRlZCksdGUobixyLmludF9wb2ludHMyX3NvcnRlZCksQ3Iociksci5pbnRfcG9pbnRzMV9zb3J0ZWQ9UHQoci5pbnRfcG9pbnRzMSksci5pbnRfcG9pbnRzMl9zb3J0ZWQ9UHQoci5pbnRfcG9pbnRzMiksVnIoci5pbnRfcG9pbnRzMSksTnIoci5pbnRfcG9pbnRzMSxuKTtmb3IobGV0IG8gb2Ygci5pbnRfcG9pbnRzMV9zb3J0ZWQpby5lZGdlX2JlZm9yZSYmby5lZGdlX2FmdGVyJiZvLmVkZ2VfYmVmb3JlLmJ2PT09by5lZGdlX2FmdGVyLmJ2JiYoci5pbnRfcG9pbnRzMltvLmlkXT0tMSxvLmlkPS0xKTtpZihyLmludF9wb2ludHMxPXIuaW50X3BvaW50czEuZmlsdGVyKG89Pm8uaWQ+PTApLHIuaW50X3BvaW50czI9ci5pbnRfcG9pbnRzMi5maWx0ZXIobz0+by5pZD49MCksci5pbnRfcG9pbnRzMS5mb3JFYWNoKChvLGMpPT57by5pZD1jfSksci5pbnRfcG9pbnRzMi5mb3JFYWNoKChvLGMpPT57by5pZD1jfSksci5pbnRfcG9pbnRzMS5sZW5ndGg9PT0wKXJldHVybiBuO3IuaW50X3BvaW50czFfc29ydGVkPVB0KHIuaW50X3BvaW50czEpLHIuaW50X3BvaW50czJfc29ydGVkPVB0KHIuaW50X3BvaW50czIpO2xldCBpLHM7Zm9yKGxldCBvPTE7bzxyLmludF9wb2ludHMxX3NvcnRlZC5sZW5ndGg7bysrKWlmKHM9ci5pbnRfcG9pbnRzMV9zb3J0ZWRbb10saT1yLmludF9wb2ludHMxX3NvcnRlZFtvLTFdLHMuZWRnZV9iZWZvcmUmJnMuZWRnZV9iZWZvcmUuYnY9PT11bil7bGV0IGM9aS5lZGdlX2FmdGVyLGw9cy5lZGdlX2JlZm9yZSxoPXQuZ2V0Q2hhaW4oYyxsKTtCbyhyLmludF9wb2ludHMyW2kuaWRdLHIuaW50X3BvaW50czJbcy5pZF0saCksaC5mb3JFYWNoKGY9Pm4uZWRnZXMuYWRkKGYpKSxoPWgucmV2ZXJzZSgpLm1hcChmPT5uZXcgYS5FZGdlKGYuc2hhcGUucmV2ZXJzZSgpKSk7Zm9yKGxldCBmPTA7ZjxoLmxlbmd0aC0xO2YrKyloW2ZdLm5leHQ9aFtmKzFdLGhbZisxXS5wcmV2PWhbZl07Qm8oci5pbnRfcG9pbnRzMltzLmlkXSxyLmludF9wb2ludHMyW2kuaWRdLGgpLGguZm9yRWFjaChmPT5uLmVkZ2VzLmFkZChmKSl9cmV0dXJuIG4ucmVjcmVhdGVGYWNlcygpLG59Y3V0V2l0aExpbmUodCl7bGV0IG49bmV3IEZ0KFt0XSk7cmV0dXJuIHRoaXMuY3V0KG4pfWZpbmRFZGdlQnlQb2ludCh0KXtsZXQgbjtmb3IobGV0IHIgb2YgdGhpcy5mYWNlcylpZihuPXIuZmluZEVkZ2VCeVBvaW50KHQpLG4hPT12b2lkIDApYnJlYWs7cmV0dXJuIG59c3BsaXRUb0lzbGFuZHMoKXtpZih0aGlzLmlzRW1wdHkoKSlyZXR1cm5bXTtsZXQgdD10aGlzLnRvQXJyYXkoKTt0LnNvcnQoKGkscyk9PnMuYXJlYSgpLWkuYXJlYSgpKTtsZXQgbj1bLi4udFswXS5mYWNlc11bMF0ub3JpZW50YXRpb24oKSxyPXQuZmlsdGVyKGk9PlsuLi5pLmZhY2VzXVswXS5vcmllbnRhdGlvbigpPT09bik7Zm9yKGxldCBpIG9mIHQpe2xldCBzPVsuLi5pLmZhY2VzXVswXTtpZihzLm9yaWVudGF0aW9uKCkhPT1uKXtmb3IobGV0IG8gb2YgcilpZihzLnNoYXBlcy5ldmVyeShjPT5vLmNvbnRhaW5zKGMpKSl7by5hZGRGYWNlKHMuc2hhcGVzKTticmVha319fXJldHVybiByfXJldmVyc2UoKXtmb3IobGV0IHQgb2YgdGhpcy5mYWNlcyl0LnJldmVyc2UoKTtyZXR1cm4gdGhpc31jb250YWlucyh0KXtpZih0IGluc3RhbmNlb2YgYS5Qb2ludCl7bGV0IG49RWUodGhpcyx0KTtyZXR1cm4gbj09PXVufHxuPT09X3R9ZWxzZSByZXR1cm4gbmModGhpcyx0KX1kaXN0YW5jZVRvKHQpe2lmKHQgaW5zdGFuY2VvZiBhLlBvaW50KXtsZXRbbixyXT1hLkRpc3RhbmNlLnBvaW50MnBvbHlnb24odCx0aGlzKTtyZXR1cm4gcj1yLnJldmVyc2UoKSxbbixyXX1pZih0IGluc3RhbmNlb2YgYS5DaXJjbGV8fHQgaW5zdGFuY2VvZiBhLkxpbmV8fHQgaW5zdGFuY2VvZiBhLlNlZ21lbnR8fHQgaW5zdGFuY2VvZiBhLkFyYyl7bGV0W24scl09YS5EaXN0YW5jZS5zaGFwZTJwb2x5Z29uKHQsdGhpcyk7cmV0dXJuIHI9ci5yZXZlcnNlKCksW24scl19aWYodCBpbnN0YW5jZW9mIGEuUG9seWdvbil7bGV0IG49W051bWJlci5QT1NJVElWRV9JTkZJTklUWSxuZXcgYS5TZWdtZW50XSxyLGk7Zm9yKGxldCBzIG9mIHRoaXMuZWRnZXMpe2xldCBvPW5bMF07W3IsaV09YS5EaXN0YW5jZS5zaGFwZTJwbGFuYXJTZXQocy5zaGFwZSx0LmVkZ2VzLG8pLGEuVXRpbHMuTFQocixvKSYmKG49W3IsaV0pfXJldHVybiBufX1pbnRlcnNlY3QodCl7aWYodCBpbnN0YW5jZW9mIGEuUG9pbnQpcmV0dXJuIHRoaXMuY29udGFpbnModCk/W3RdOltdO2lmKHQgaW5zdGFuY2VvZiBhLkxpbmUpcmV0dXJuIHhlKHQsdGhpcyk7aWYodCBpbnN0YW5jZW9mIGEuUmF5KXJldHVybiBVbyh0LHRoaXMpO2lmKHQgaW5zdGFuY2VvZiBhLkNpcmNsZSlyZXR1cm4gTm8odCx0aGlzKTtpZih0IGluc3RhbmNlb2YgYS5TZWdtZW50KXJldHVybiBTcih0LHRoaXMpO2lmKHQgaW5zdGFuY2VvZiBhLkFyYylyZXR1cm4gUHIodCx0aGlzKTtpZih0IGluc3RhbmNlb2YgYS5Qb2x5Z29uKXJldHVybiBPdSh0LHRoaXMpO2lmKHQgaW5zdGFuY2VvZiBhLk11bHRpbGluZSlyZXR1cm4gRXUodCx0aGlzKX10cmFuc2xhdGUodCl7bGV0IG49bmV3IG9lO2ZvcihsZXQgciBvZiB0aGlzLmZhY2VzKW4uYWRkRmFjZShyLnNoYXBlcy5tYXAoaT0+aS50cmFuc2xhdGUodCkpKTtyZXR1cm4gbn1yb3RhdGUodD0wLG49bmV3IGEuUG9pbnQpe2xldCByPW5ldyBvZTtmb3IobGV0IGkgb2YgdGhpcy5mYWNlcylyLmFkZEZhY2UoaS5zaGFwZXMubWFwKHM9PnMucm90YXRlKHQsbikpKTtyZXR1cm4gcn1zY2FsZSh0LG4pe2xldCByPW5ldyBvZTtmb3IobGV0IGkgb2YgdGhpcy5mYWNlcylyLmFkZEZhY2UoaS5zaGFwZXMubWFwKHM9PnMuc2NhbGUodCxuKSkpO3JldHVybiByfXRyYW5zZm9ybSh0PW5ldyBhLk1hdHJpeCl7bGV0IG49bmV3IG9lO2ZvcihsZXQgciBvZiB0aGlzLmZhY2VzKW4uYWRkRmFjZShyLnNoYXBlcy5tYXAoaT0+aS50cmFuc2Zvcm0odCkpKTtyZXR1cm4gbn10b0pTT04oKXtyZXR1cm5bLi4udGhpcy5mYWNlc10ubWFwKHQ9PnQudG9KU09OKCkpfXRvQXJyYXkoKXtyZXR1cm5bLi4udGhpcy5mYWNlc10ubWFwKHQ9PnQudG9Qb2x5Z29uKCkpfWRwYXRoKCl7cmV0dXJuWy4uLnRoaXMuZmFjZXNdLnJlZHVjZSgodCxuKT0+dCtuLnN2ZygpLCIiKX1zdmcodD17fSl7bGV0IG49YAo8cGF0aCAkeyR0KHtmaWxsUnVsZToiZXZlbm9kZCIsZmlsbDoibGlnaHRjeWFuIiwuLi50fSl9IGQ9ImA7Zm9yKGxldCByIG9mIHRoaXMuZmFjZXMpbis9YAoke3Iuc3ZnKCl9YDtyZXR1cm4gbis9YCIgPgo8L3BhdGg+YCxufX07YS5Qb2x5Z29uPVNlO2NvbnN0IHgwPSguLi5lKT0+bmV3IGEuUG9seWdvbiguLi5lKTthLnBvbHlnb249eDA7Y29uc3R7Q2lyY2xlOkRyLExpbmU6c2MsUG9pbnQ6b2MsVmVjdG9yOk1uLFV0aWxzOkJyfT1hO2NsYXNzIFBle2NvbnN0cnVjdG9yKHQpe3RoaXMuY2lyY2xlPXR9Z2V0IGludmVyc2lvbl9jaXJjbGUoKXtyZXR1cm4gdGhpcy5jaXJjbGV9c3RhdGljIGludmVyc2VQb2ludCh0LG4pe2NvbnN0IHI9bmV3IE1uKHQucGMsbiksaT10LnIqdC5yLHM9ci5kb3Qocik7cmV0dXJuIEJyLkVRXzAocyk/bmV3IG9jKE51bWJlci5QT1NJVElWRV9JTkZJTklUWSxOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFkpOnQucGMudHJhbnNsYXRlKHIubXVsdGlwbHkoaS9zKSl9c3RhdGljIGludmVyc2VDaXJjbGUodCxuKXtjb25zdCByPXQucGMuZGlzdGFuY2VUbyhuLnBjKVswXTtpZihCci5FUShyLG4ucikpe2xldCBpPXQucip0LnIvKDIqbi5yKSxzPW5ldyBNbih0LnBjLG4ucGMpO3M9cy5ub3JtYWxpemUoKTtsZXQgbz10LnBjLnRyYW5zbGF0ZShzLm11bHRpcGx5KGkpKTtyZXR1cm4gbmV3IHNjKG8scyl9ZWxzZXtsZXQgaT1uZXcgTW4odC5wYyxuLnBjKSxzPXQucip0LnIvKGkuZG90KGkpLW4ucipuLnIpLG89dC5wYy50cmFuc2xhdGUoaS5tdWx0aXBseShzKSksYz1NYXRoLmFicyhzKSpuLnI7cmV0dXJuIG5ldyBEcihvLGMpfX1zdGF0aWMgaW52ZXJzZUxpbmUodCxuKXtjb25zdFtyLGldPXQucGMuZGlzdGFuY2VUbyhuKTtpZihCci5FUV8wKHIpKXJldHVybiBuLmNsb25lKCk7e2xldCBzPXQucip0LnIvKDIqciksbz1uZXcgTW4odC5wYyxpLmVuZCk7cmV0dXJuIG89by5tdWx0aXBseShzL3IpLG5ldyBEcih0LnBjLnRyYW5zbGF0ZShvKSxzKX19aW52ZXJzZSh0KXtpZih0IGluc3RhbmNlb2Ygb2MpcmV0dXJuIFBlLmludmVyc2VQb2ludCh0aGlzLmNpcmNsZSx0KTtpZih0IGluc3RhbmNlb2YgRHIpcmV0dXJuIFBlLmludmVyc2VDaXJjbGUodGhpcy5jaXJjbGUsdCk7aWYodCBpbnN0YW5jZW9mIHNjKXJldHVybiBQZS5pbnZlcnNlTGluZSh0aGlzLmNpcmNsZSx0KX19YS5JbnZlcnNpb249UGU7Y29uc3QgTTA9ZT0+bmV3IGEuSW52ZXJzaW9uKGUpO2EuaW52ZXJzaW9uPU0wO2NsYXNzIE97c3RhdGljIHBvaW50MnBvaW50KHQsbil7cmV0dXJuIHQuZGlzdGFuY2VUbyhuKX1zdGF0aWMgcG9pbnQybGluZSh0LG4pe2xldCByPXQucHJvamVjdGlvbk9uKG4pO3JldHVybltuZXcgYS5WZWN0b3IodCxyKS5sZW5ndGgsbmV3IGEuU2VnbWVudCh0LHIpXX1zdGF0aWMgcG9pbnQyY2lyY2xlKHQsbil7bGV0W3IsaV09dC5kaXN0YW5jZVRvKG4uY2VudGVyKTtpZihhLlV0aWxzLkVRXzAocikpcmV0dXJuW24ucixuZXcgYS5TZWdtZW50KHQsbi50b0FyYygpLnN0YXJ0KV07e2xldCBzPU1hdGguYWJzKHItbi5yKSxvPW5ldyBhLlZlY3RvcihuLnBjLHQpLm5vcm1hbGl6ZSgpLm11bHRpcGx5KG4uciksYz1uLnBjLnRyYW5zbGF0ZShvKTtyZXR1cm5bcyxuZXcgYS5TZWdtZW50KHQsYyldfX1zdGF0aWMgcG9pbnQyc2VnbWVudCh0LG4pe2lmKG4uc3RhcnQuZXF1YWxUbyhuLmVuZCkpcmV0dXJuIE8ucG9pbnQycG9pbnQodCxuLnN0YXJ0KTtsZXQgcj1uZXcgYS5WZWN0b3Iobi5zdGFydCxuLmVuZCksaT1uZXcgYS5WZWN0b3Iobi5zdGFydCx0KSxzPW5ldyBhLlZlY3RvcihuLmVuZCx0KSxvPXIuZG90KGkpLGM9LXIuZG90KHMpLGwsaDtpZihhLlV0aWxzLkdFKG8sMCkmJmEuVXRpbHMuR0UoYywwKSl7bGV0IGY9bi50YW5nZW50SW5TdGFydCgpO3JldHVybiBsPU1hdGguYWJzKGYuY3Jvc3MoaSkpLGg9bi5zdGFydC50cmFuc2xhdGUoZi5tdWx0aXBseShmLmRvdChpKSkpLFtsLG5ldyBhLlNlZ21lbnQodCxoKV19ZWxzZSByZXR1cm4gbzwwP3QuZGlzdGFuY2VUbyhuLnN0YXJ0KTp0LmRpc3RhbmNlVG8obi5lbmQpfXN0YXRpYyBwb2ludDJhcmModCxuKXtsZXQgcj1uZXcgYS5DaXJjbGUobi5wYyxuLnIpLGk9W10scyxvO3JldHVybltzLG9dPU8ucG9pbnQyY2lyY2xlKHQsciksby5lbmQub24obikmJmkucHVzaChPLnBvaW50MmNpcmNsZSh0LHIpKSxpLnB1c2goTy5wb2ludDJwb2ludCh0LG4uc3RhcnQpKSxpLnB1c2goTy5wb2ludDJwb2ludCh0LG4uZW5kKSksTy5zb3J0KGkpLGlbMF19c3RhdGljIHBvaW50MmVkZ2UodCxuKXtyZXR1cm4gbi5zaGFwZSBpbnN0YW5jZW9mIGEuU2VnbWVudD9PLnBvaW50MnNlZ21lbnQodCxuLnNoYXBlKTpPLnBvaW50MmFyYyh0LG4uc2hhcGUpfXN0YXRpYyBzZWdtZW50MmxpbmUodCxuKXtsZXQgcj10LmludGVyc2VjdChuKTtpZihyLmxlbmd0aD4wKXJldHVyblswLG5ldyBhLlNlZ21lbnQoclswXSxyWzBdKV07bGV0IGk9W107cmV0dXJuIGkucHVzaChPLnBvaW50MmxpbmUodC5zdGFydCxuKSksaS5wdXNoKE8ucG9pbnQybGluZSh0LmVuZCxuKSksTy5zb3J0KGkpLGlbMF19c3RhdGljIHNlZ21lbnQyc2VnbWVudCh0LG4pe2xldCByPW1uKHQsbik7aWYoci5sZW5ndGg+MClyZXR1cm5bMCxuZXcgYS5TZWdtZW50KHJbMF0sclswXSldO2xldCBpPVtdLHMsbztyZXR1cm5bcyxvXT1PLnBvaW50MnNlZ21lbnQobi5zdGFydCx0KSxpLnB1c2goW3Msby5yZXZlcnNlKCldKSxbcyxvXT1PLnBvaW50MnNlZ21lbnQobi5lbmQsdCksaS5wdXNoKFtzLG8ucmV2ZXJzZSgpXSksaS5wdXNoKE8ucG9pbnQyc2VnbWVudCh0LnN0YXJ0LG4pKSxpLnB1c2goTy5wb2ludDJzZWdtZW50KHQuZW5kLG4pKSxPLnNvcnQoaSksaVswXX1zdGF0aWMgc2VnbWVudDJjaXJjbGUodCxuKXtsZXQgcj10LmludGVyc2VjdChuKTtpZihyLmxlbmd0aD4wKXJldHVyblswLG5ldyBhLlNlZ21lbnQoclswXSxyWzBdKV07bGV0IGk9bmV3IGEuTGluZSh0LnBzLHQucGUpLFtzLG9dPU8ucG9pbnQybGluZShuLmNlbnRlcixpKTtpZihhLlV0aWxzLkdFKHMsbi5yKSYmby5lbmQub24odCkpcmV0dXJuIE8ucG9pbnQyY2lyY2xlKG8uZW5kLG4pO3tsZXRbYyxsXT1PLnBvaW50MmNpcmNsZSh0LnN0YXJ0LG4pLFtoLGZdPU8ucG9pbnQyY2lyY2xlKHQuZW5kLG4pO3JldHVybiBhLlV0aWxzLkxUKGMsaCk/W2MsbF06W2gsZl19fXN0YXRpYyBzZWdtZW50MmFyYyh0LG4pe2xldCByPXQuaW50ZXJzZWN0KG4pO2lmKHIubGVuZ3RoPjApcmV0dXJuWzAsbmV3IGEuU2VnbWVudChyWzBdLHJbMF0pXTtsZXQgaT1uZXcgYS5MaW5lKHQucHMsdC5wZSkscz1uZXcgYS5DaXJjbGUobi5wYyxuLnIpLFtvLGNdPU8ucG9pbnQybGluZShzLmNlbnRlcixpKTtpZihhLlV0aWxzLkdFKG8scy5yKSYmYy5lbmQub24odCkpe2xldFt1LGRdPU8ucG9pbnQyY2lyY2xlKGMuZW5kLHMpO2lmKGQuZW5kLm9uKG4pKXJldHVyblt1LGRdfWxldCBsPVtdO2wucHVzaChPLnBvaW50MmFyYyh0LnN0YXJ0LG4pKSxsLnB1c2goTy5wb2ludDJhcmModC5lbmQsbikpO2xldCBoLGY7cmV0dXJuW2gsZl09Ty5wb2ludDJzZWdtZW50KG4uc3RhcnQsdCksbC5wdXNoKFtoLGYucmV2ZXJzZSgpXSksW2gsZl09Ty5wb2ludDJzZWdtZW50KG4uZW5kLHQpLGwucHVzaChbaCxmLnJldmVyc2UoKV0pLE8uc29ydChsKSxsWzBdfXN0YXRpYyBjaXJjbGUyY2lyY2xlKHQsbil7bGV0IHI9dC5pbnRlcnNlY3Qobik7aWYoci5sZW5ndGg+MClyZXR1cm5bMCxuZXcgYS5TZWdtZW50KHJbMF0sclswXSldO2lmKHQuY2VudGVyLmVxdWFsVG8obi5jZW50ZXIpKXtsZXQgaT10LnRvQXJjKCkscz1uLnRvQXJjKCk7cmV0dXJuIE8ucG9pbnQycG9pbnQoaS5zdGFydCxzLnN0YXJ0KX1lbHNle2xldCBpPW5ldyBhLkxpbmUodC5jZW50ZXIsbi5jZW50ZXIpLHM9aS5pbnRlcnNlY3QodCksbz1pLmludGVyc2VjdChuKSxjPVtdO3JldHVybiBjLnB1c2goTy5wb2ludDJwb2ludChzWzBdLG9bMF0pKSxjLnB1c2goTy5wb2ludDJwb2ludChzWzBdLG9bMV0pKSxjLnB1c2goTy5wb2ludDJwb2ludChzWzFdLG9bMF0pKSxjLnB1c2goTy5wb2ludDJwb2ludChzWzFdLG9bMV0pKSxPLnNvcnQoYyksY1swXX19c3RhdGljIGNpcmNsZTJsaW5lKHQsbil7bGV0IHI9dC5pbnRlcnNlY3Qobik7aWYoci5sZW5ndGg+MClyZXR1cm5bMCxuZXcgYS5TZWdtZW50KHJbMF0sclswXSldO2xldFtpLHNdPU8ucG9pbnQybGluZSh0LmNlbnRlcixuKSxbbyxjXT1PLnBvaW50MmNpcmNsZShzLmVuZCx0KTtyZXR1cm4gYz1jLnJldmVyc2UoKSxbbyxjXX1zdGF0aWMgYXJjMmxpbmUodCxuKXtsZXQgcj1uLmludGVyc2VjdCh0KTtpZihyLmxlbmd0aD4wKXJldHVyblswLG5ldyBhLlNlZ21lbnQoclswXSxyWzBdKV07bGV0IGk9bmV3IGEuQ2lyY2xlKHQuY2VudGVyLHQuciksW3Msb109Ty5wb2ludDJsaW5lKGkuY2VudGVyLG4pO2lmKGEuVXRpbHMuR0UocyxpLnIpKXtsZXRbYyxsXT1PLnBvaW50MmNpcmNsZShvLmVuZCxpKTtpZihsLmVuZC5vbih0KSlyZXR1cm5bYyxsXX1lbHNle2xldCBjPVtdO3JldHVybiBjLnB1c2goTy5wb2ludDJsaW5lKHQuc3RhcnQsbikpLGMucHVzaChPLnBvaW50MmxpbmUodC5lbmQsbikpLE8uc29ydChjKSxjWzBdfX1zdGF0aWMgYXJjMmNpcmNsZSh0LG4pe2xldCByPXQuaW50ZXJzZWN0KG4pO2lmKHIubGVuZ3RoPjApcmV0dXJuWzAsbmV3IGEuU2VnbWVudChyWzBdLHJbMF0pXTtsZXQgaT1uZXcgYS5DaXJjbGUodC5jZW50ZXIsdC5yKSxbcyxvXT1PLmNpcmNsZTJjaXJjbGUoaSxuKTtpZihvLnN0YXJ0Lm9uKHQpKXJldHVybltzLG9dO3tsZXQgYz1bXTtyZXR1cm4gYy5wdXNoKE8ucG9pbnQyY2lyY2xlKHQuc3RhcnQsbikpLGMucHVzaChPLnBvaW50MmNpcmNsZSh0LmVuZCxuKSksTy5zb3J0KGMpLGNbMF19fXN0YXRpYyBhcmMyYXJjKHQsbil7bGV0IHI9dC5pbnRlcnNlY3Qobik7aWYoci5sZW5ndGg+MClyZXR1cm5bMCxuZXcgYS5TZWdtZW50KHJbMF0sclswXSldO2xldCBpPW5ldyBhLkNpcmNsZSh0LmNlbnRlcix0LnIpLHM9bmV3IGEuQ2lyY2xlKG4uY2VudGVyLG4uciksW28sY109Ty5jaXJjbGUyY2lyY2xlKGkscyk7aWYoYy5zdGFydC5vbih0KSYmYy5lbmQub24obikpcmV0dXJuW28sY107e2xldCBsPVtdLGgsZjtyZXR1cm5baCxmXT1PLnBvaW50MmFyYyh0LnN0YXJ0LG4pLGYuZW5kLm9uKG4pJiZsLnB1c2goW2gsZl0pLFtoLGZdPU8ucG9pbnQyYXJjKHQuZW5kLG4pLGYuZW5kLm9uKG4pJiZsLnB1c2goW2gsZl0pLFtoLGZdPU8ucG9pbnQyYXJjKG4uc3RhcnQsdCksZi5lbmQub24odCkmJmwucHVzaChbaCxmLnJldmVyc2UoKV0pLFtoLGZdPU8ucG9pbnQyYXJjKG4uZW5kLHQpLGYuZW5kLm9uKHQpJiZsLnB1c2goW2gsZi5yZXZlcnNlKCldKSxbaCxmXT1PLnBvaW50MnBvaW50KHQuc3RhcnQsbi5zdGFydCksbC5wdXNoKFtoLGZdKSxbaCxmXT1PLnBvaW50MnBvaW50KHQuc3RhcnQsbi5lbmQpLGwucHVzaChbaCxmXSksW2gsZl09Ty5wb2ludDJwb2ludCh0LmVuZCxuLnN0YXJ0KSxsLnB1c2goW2gsZl0pLFtoLGZdPU8ucG9pbnQycG9pbnQodC5lbmQsbi5lbmQpLGwucHVzaChbaCxmXSksTy5zb3J0KGwpLGxbMF19fXN0YXRpYyBwb2ludDJwb2x5Z29uKHQsbil7bGV0IHI9W051bWJlci5QT1NJVElWRV9JTkZJTklUWSxuZXcgYS5TZWdtZW50XTtmb3IobGV0IGkgb2Ygbi5lZGdlcyl7bGV0W3Msb109Ty5wb2ludDJlZGdlKHQsaSk7YS5VdGlscy5MVChzLHJbMF0pJiYocj1bcyxvXSl9cmV0dXJuIHJ9c3RhdGljIHNoYXBlMnBvbHlnb24odCxuKXtsZXQgcj1bTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZLG5ldyBhLlNlZ21lbnRdO2ZvcihsZXQgaSBvZiBuLmVkZ2VzKXtsZXRbcyxvXT10LmRpc3RhbmNlVG8oaS5zaGFwZSk7YS5VdGlscy5MVChzLHJbMF0pJiYocj1bcyxvXSl9cmV0dXJuIHJ9c3RhdGljIHBvbHlnb24ycG9seWdvbih0LG4pe2xldCByPVtOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFksbmV3IGEuU2VnbWVudF07Zm9yKGxldCBpIG9mIHQuZWRnZXMpZm9yKGxldCBzIG9mIG4uZWRnZXMpe2xldFtvLGNdPWkuc2hhcGUuZGlzdGFuY2VUbyhzLnNoYXBlKTthLlV0aWxzLkxUKG8sclswXSkmJihyPVtvLGNdKX1yZXR1cm4gcn1zdGF0aWMgYm94MmJveF9taW5tYXgodCxuKXtsZXQgcj1NYXRoLm1heChNYXRoLm1heCh0LnhtaW4tbi54bWF4LDApLE1hdGgubWF4KG4ueG1pbi10LnhtYXgsMCkpLGk9TWF0aC5tYXgoTWF0aC5tYXgodC55bWluLW4ueW1heCwwKSxNYXRoLm1heChuLnltaW4tdC55bWF4LDApKSxzPXIqcitpKmksbz10Lm1lcmdlKG4pLGM9by54bWF4LW8ueG1pbixsPW8ueW1heC1vLnltaW4saD1jKmMrbCpsO3JldHVybltzLGhdfXN0YXRpYyBtaW5tYXhfdHJlZV9wcm9jZXNzX2xldmVsKHQsbixyLGkpe2xldCBzLG87Zm9yKGxldCBmIG9mIG4pW3Msb109Ty5ib3gyYm94X21pbm1heCh0LmJveCxmLml0ZW0ua2V5KSxmLml0ZW0udmFsdWUgaW5zdGFuY2VvZiBhLkVkZ2U/aS5pbnNlcnQoW3Msb10sZi5pdGVtLnZhbHVlLnNoYXBlKTppLmluc2VydChbcyxvXSxmLml0ZW0udmFsdWUpLGEuVXRpbHMuTFQobyxyKSYmKHI9byk7aWYobi5sZW5ndGg9PT0wKXJldHVybiByO2xldCBjPW4ubWFwKGY9PmYubGVmdC5pc05pbCgpP3ZvaWQgMDpmLmxlZnQpLmZpbHRlcihmPT5mIT09dm9pZCAwKSxsPW4ubWFwKGY9PmYucmlnaHQuaXNOaWwoKT92b2lkIDA6Zi5yaWdodCkuZmlsdGVyKGY9PmYhPT12b2lkIDApLGg9Wy4uLmMsLi4ubF0uZmlsdGVyKGY9PntsZXRbdSxkXT1PLmJveDJib3hfbWlubWF4KHQuYm94LGYubWF4KTtyZXR1cm4gYS5VdGlscy5MRSh1LHIpfSk7cmV0dXJuIHI9Ty5taW5tYXhfdHJlZV9wcm9jZXNzX2xldmVsKHQsaCxyLGkpLHJ9c3RhdGljIG1pbm1heF90cmVlKHQsbixyKXtsZXQgaT1uZXcgT2Uscz1bbi5pbmRleC5yb290XSxvPXI8TnVtYmVyLlBPU0lUSVZFX0lORklOSVRZP3IqcjpOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFk7cmV0dXJuIG89Ty5taW5tYXhfdHJlZV9wcm9jZXNzX2xldmVsKHQscyxvLGkpLGl9c3RhdGljIG1pbm1heF90cmVlX2NhbGNfZGlzdGFuY2UodCxuLHIpe2xldCBpLHM7aWYobiE9bnVsbCYmIW4uaXNOaWwoKSl7aWYoW2ksc109Ty5taW5tYXhfdHJlZV9jYWxjX2Rpc3RhbmNlKHQsbi5sZWZ0LHIpLHMpcmV0dXJuW2ksc107aWYoYS5VdGlscy5MVChpWzBdLE1hdGguc3FydChuLml0ZW0ua2V5LmxvdykpKXJldHVybltpLCEwXTtsZXRbbyxjXT1PLmRpc3RhbmNlKHQsbi5pdGVtLnZhbHVlKTtyZXR1cm4gYS5VdGlscy5MVChvLGlbMF0pJiYoaT1bbyxjXSksW2ksc109Ty5taW5tYXhfdHJlZV9jYWxjX2Rpc3RhbmNlKHQsbi5yaWdodCxpKSxbaSxzXX1yZXR1cm5bciwhMV19c3RhdGljIHNoYXBlMnBsYW5hclNldCh0LG4scj1OdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFkpe2xldCBpPVtyLG5ldyBhLlNlZ21lbnRdLHM9ITE7aWYobiBpbnN0YW5jZW9mIGEuUGxhbmFyU2V0KXtsZXQgbz1PLm1pbm1heF90cmVlKHQsbixyKTtbaSxzXT1PLm1pbm1heF90cmVlX2NhbGNfZGlzdGFuY2UodCxvLnJvb3QsaSl9cmV0dXJuIGl9c3RhdGljIHNvcnQodCl7dC5zb3J0KChuLHIpPT5hLlV0aWxzLkxUKG5bMF0sclswXSk/LTE6YS5VdGlscy5HVChuWzBdLHJbMF0pPzE6MCl9c3RhdGljIGRpc3RhbmNlKHQsbil7cmV0dXJuIHQuZGlzdGFuY2VUbyhuKX1zdGF0aWMgc2hhcGUybXVsdGlsaW5lKHQsbil7bGV0IHI9W051bWJlci5QT1NJVElWRV9JTkZJTklUWSxuZXcgYS5TZWdtZW50XTtmb3IobGV0IGkgb2Ygbil7bGV0W3Msb109Ty5kaXN0YW5jZSh0LGkuc2hhcGUpO2EuVXRpbHMuTFQocyxyWzBdKSYmKHI9W3Msb10pfXJldHVybiByfXN0YXRpYyBtdWx0aWxpbmUybXVsdGlsaW5lKHQsbil7bGV0IHI9W051bWJlci5QT1NJVElWRV9JTkZJTklUWSxuZXcgYS5TZWdtZW50XTtmb3IobGV0IGkgb2YgdClmb3IobGV0IHMgb2Ygbil7bGV0W28sY109Ty5kaXN0YW5jZShpLnNoYXBlLHMuc2hhcGUpO2EuVXRpbHMuTFQobyxyWzBdKSYmKHI9W28sY10pfXJldHVybiByfX1hLkRpc3RhbmNlPU87Y29uc3R7TXVsdGlsaW5lOncwLFBvaW50OmNjLFNlZ21lbnQ6QTAsUG9seWdvbjphY309YTtmdW5jdGlvbiBZcihlKXtyZXR1cm4gbmV3IGNjKGUuc3BsaXQoIiAiKS5tYXAoTnVtYmVyKSl9ZnVuY3Rpb24gbGMoZSl7cmV0dXJuIGUuc3BsaXQoIiwgIikubWFwKFlyKX1mdW5jdGlvbiBXcihlKXtjb25zdCB0PWxjKGUpO2xldCBuPVtdO2ZvcihsZXQgcj0wO3I8dC5sZW5ndGgtMTtyKyspbi5wdXNoKG5ldyBBMCh0W3JdLHRbcisxXSkpO3JldHVybiBuZXcgdzAobil9ZnVuY3Rpb24gVDAoZSl7cmV0dXJuIGUucmVwbGFjZSgvXChcKC8sIiIpLnJlcGxhY2UoL1wpXCkkLywiIikuc3BsaXQoIiksICgiKS5tYXAoV3IpfWZ1bmN0aW9uIGhjKGUpe2NvbnN0IHQ9ZS5yZXBsYWNlKC9cKFwoLywiIikucmVwbGFjZSgvXClcKSQvLCIiKS5zcGxpdCgiKSwgKCIpLG49bmV3IGFjO2xldCByO3JldHVybiB0LmZvckVhY2goKGkscyk9PntsZXQgbz1pLnNwbGl0KCIsICIpLm1hcChsPT5uZXcgY2MobC5zcGxpdCgiICIpLm1hcChOdW1iZXIpKSk7Y29uc3QgYz1uLmFkZEZhY2Uobyk7cz09PTA/cj1jLm9yaWVudGF0aW9uKCk6Yy5vcmllbnRhdGlvbigpPT09ciYmYy5yZXZlcnNlKCl9KSxufWZ1bmN0aW9uIHYwKGUpe2NvbnN0IG49ZS5zcGxpdCgvXClcKSwgXChcKC8pLm1hcChzPT4iKCgiK3MrIikpIikubWFwKGhjKSxyPW5ldyBhYztyZXR1cm4gbi5yZWR1Y2UoKHMsbyk9PlsuLi5zLC4uLm8/LmZhY2VzXSxbXSkuZm9yRWFjaChzPT5yLmFkZEZhY2UoWy4uLnM/LnNoYXBlc10pKSxyfWZ1bmN0aW9uIEUwKGUpe2lmKGUuc3RhcnRzV2l0aCgiUE9MWUdPTiIpKXtjb25zdCB0PWUucmVwbGFjZSgvXlBPTFlHT04gLywiIik7cmV0dXJuIGhjKHQpfWVsc2V7Y29uc3QgdD1lLnJlcGxhY2UoL15NVUxUSVBPTFlHT04gXChcKFwoKC4qKVwpXClcKSQvLCIkMSIpO3JldHVybiB2MCh0KX19ZnVuY3Rpb24gTzAoZSl7cmV0dXJuIGUuc3BsaXQoYApgKS5tYXAobj0+bi5tYXRjaCgvXCgoW14pXSspXCkvKVsxXSkubWFwKFlyKX1mdW5jdGlvbiBiMChlKXtyZXR1cm4gZS5zcGxpdChgCmApLm1hcChuPT5uLm1hdGNoKC9cKChbXildKylcKS8pWzFdKS5tYXAoV3IpLnJlZHVjZSgobixyKT0+Wy4uLm4sLi4ucl0sW10pfWZ1bmN0aW9uIGZjKGUpe2lmKGUuc3RhcnRzV2l0aCgiUE9JTlQiKSl7Y29uc3QgdD1lLnJlcGxhY2UoL15QT0lOVCBcKC8sIiIpLnJlcGxhY2UoL1wpJC8sIiIpO3JldHVybiBZcih0KX1lbHNlIGlmKGUuc3RhcnRzV2l0aCgiTVVMVElQT0lOVCIpKXtjb25zdCB0PWUucmVwbGFjZSgvXk1VTFRJUE9JTlQgXCgvLCIiKS5yZXBsYWNlKC9cKSQvLCIiKTtyZXR1cm4gbGModCl9ZWxzZSBpZihlLnN0YXJ0c1dpdGgoIkxJTkVTVFJJTkciKSl7Y29uc3QgdD1lLnJlcGxhY2UoL15MSU5FU1RSSU5HIFwoLywiIikucmVwbGFjZSgvXCkkLywiIik7cmV0dXJuIFdyKHQpfWVsc2UgaWYoZS5zdGFydHNXaXRoKCJNVUxUSUxJTkVTVFJJTkciKSl7Y29uc3QgdD1lLnJlcGxhY2UoL15NVUxUSUxJTkVTVFJJTkcgLywiIik7cmV0dXJuIFQwKHQpfWVsc2V7aWYoZS5zdGFydHNXaXRoKCJQT0xZR09OIil8fGUuc3RhcnRzV2l0aCgiTVVMVElQT0xZR09OIikpcmV0dXJuIEUwKGUpO2lmKGUuc3RhcnRzV2l0aCgiR0VPTUVUUllDT0xMRUNUSU9OIikpe2NvbnN0IHQ9Lyg/PHR5cGU+UE9JTlR8TElORVNUUklOR3xQT0xZR09OfE1VTFRJUE9JTlR8TVVMVElMSU5FU1RSSU5HfE1VTFRJUE9MWUdPTikgXCgoPzpbXlwoXCldfFwoW15cKV0qXCkpKlwpL2csbj1lLm1hdGNoKHQpO3JldHVybiBuWzBdLnN0YXJ0c1dpdGgoIkdFT01FVFJZQ09MTEVDVElPTiIpJiYoblswXT1uWzBdLnJlcGxhY2UoIkdFT01FVFJZQ09MTEVDVElPTiAoIiwiIikpLG4ubWFwKGZjKS5tYXAoaT0+aSBpbnN0YW5jZW9mIEFycmF5P2k6W2ldKS5yZWR1Y2UoKGkscyk9PlsuLi5pLC4uLnNdLFtdKX1lbHNle2lmKHVjKGUpKXJldHVybiBPMChlKTtpZihkYyhlKSlyZXR1cm4gYjAoZSl9fXJldHVybltdfWZ1bmN0aW9uIHVjKGUpe3JldHVybiBlLnNwbGl0KGAKYCk/LmV2ZXJ5KHQ9PnQuaW5jbHVkZXMoIlBPSU5UIikpfWZ1bmN0aW9uIGRjKGUpe3JldHVybiBlLnNwbGl0KGAKYCk/LmV2ZXJ5KHQ9PnQuaW5jbHVkZXMoIkxJTkVTVFJJTkciKSl9ZnVuY3Rpb24gSTAoZSl7cmV0dXJuIGUuc3RhcnRzV2l0aCgiUE9JTlQiKXx8dWMoZSl8fGUuc3RhcnRzV2l0aCgiTElORVNUUklORyIpfHxkYyhlKXx8ZS5zdGFydHNXaXRoKCJNVUxUSUxJTkVTVFJJTkciKXx8ZS5zdGFydHNXaXRoKCJQT0xZR09OIil8fGUuc3RhcnRzV2l0aCgiTVVMVElQT0lOVCIpfHxlLnN0YXJ0c1dpdGgoIk1VTFRJUE9MWUdPTiIpfHxlLnN0YXJ0c1dpdGgoIkdFT01FVFJZQ09MTEVDVElPTiIpfWEuaXNXa3RTdHJpbmc9STAsYS5wYXJzZVdLVD1mYyxhLkJvb2xlYW5PcGVyYXRpb25zPXZlLGEuUmVsYXRpb25zPWUwO2NvbnN0IExlPVsicG9zaXRpb24iXTtjbGFzcyBnY3tjb25zdHJ1Y3Rvcih0KXt0JiZ0aGlzLnNldE9wdGlvbnModCl9Z2VvbWV0cnk7cG9zaXRpb25OYW1lcz1MZTtyZWdpb247cmVsYXRpb247cmVsYXRpb25FcXVhbDtnZXQgaW5jbHVkaW5nVGhyb3VnaCgpe3JldHVybiB0aGlzLnJlbGF0aW9uJnkuVGhyb3VnaEludGVyc2VjdH1zZXRPcHRpb25zKHQpe2lmKE9iamVjdC5hc3NpZ24odGhpcyx0KSx0LnBvc2l0aW9uTmFtZXMmJih0aGlzLl9nZXRQb3NpdGlvbj1udWxsKSx0Lmdlb21ldHJ5fHx0LnBvc2l0aW9uTmFtZXN8fHQucmVnaW9uKXJldHVybih0Lmdlb21ldHJ5fHx0LnBvc2l0aW9uTmFtZXMpJiYodGhpcy5fZ2VvbWV0cnlQb2x5Z29uPW51bGwpLHRoaXMudXBkYXRlKCk7aWYodC5yZWxhdGlvbnx8dC5zdHJpY3QpcmV0dXJuIHRoaXMuX3JlbGF0aW9uQXJlYT1udWxsLHRoaXMuX3JlbGF0aW9uVm9sdW1lPW51bGwsdGhpcy51cGRhdGVSZWxhdGlvbkluZGV4cygpfWdldCBnZW9tZXRyeVBvbHlnb24oKXtyZXR1cm4gdGhpcy5fZ2VvbWV0cnlQb2x5Z29ufHwodGhpcy5fZ2VvbWV0cnlQb2x5Z29uPXRoaXMuZ2VuZXJhdGVHZW9tZXRyeVBvbHlnb24oKSksdGhpcy5fZ2VvbWV0cnlQb2x5Z29ufV9nZW9tZXRyeVBvbHlnb249bnVsbDtnZW5lcmF0ZUdlb21ldHJ5UG9seWdvbigpe2NvbnN0IHQ9bmV3IFNlO3JldHVybiB0aGlzLmdlb21ldHJ5Lm1hcEZhY2VGb3JBZ2dyZWdhdGUodGhpcy5wb3NpdGlvbk5hbWVzLG49Pntjb25zdCByPW4ubWFwKGk9Pm5ldyB4bihpWzBdLGlbMV0pKTt0LmFkZEZhY2Uocil9KSx0fXBvc2l0aW9uUmVsYXRpb25zO2ZhY2VSZWxhdGlvbnM7cmVsYXRpb25JbmRleHNXaXRob3V0VGhyb3VnbjtnZXQgdGhyb3VnaEluZGV4cygpe3JldHVybiB0aGlzLl90aHJvdWdoSW5kZXhzfXNldCB0aHJvdWdoSW5kZXhzKHQpe3RoaXMuX3Rocm91Z2hJbmRleHM9dCx0aGlzLl90aHJvdWdoRmFjZXM9bnVsbCx0aGlzLl90aHJvdWdoRmFjZUFyZWFzPW51bGx9X3Rocm91Z2hJbmRleHM9W107Z2V0IHRocm91Z2hGYWNlcygpe3JldHVybiB0aGlzLl90aHJvdWdoRmFjZXN8fCh0aGlzLl90aHJvdWdoRmFjZXM9dGhpcy5nZW5lcmF0ZVRocm91Z2hGYWNlcygpKSx0aGlzLl90aHJvdWdoRmFjZXN9X3Rocm91Z2hGYWNlcz1udWxsO2dldCB0aHJvdWdoRmFjZUFyZWFzKCl7cmV0dXJuIHRoaXMuX3Rocm91Z2hGYWNlQXJlYXN8fCh0aGlzLl90aHJvdWdoRmFjZUFyZWFzPXRoaXMuZ2VuZXJhdGVUaHJvdWdoRmFjZUFyZWFzKCkpLHRoaXMuX3Rocm91Z2hGYWNlQXJlYXN9X3Rocm91Z2hGYWNlQXJlYXM9bnVsbDtnZW5lcmF0ZVRocm91Z2hGYWNlQXJlYXMoKXtyZXR1cm4gdGhpcy50aHJvdWdoRmFjZXMubWFwKHQ9PnQuYXJlYSgpKX11cGRhdGUoKXt0aGlzLnVwZGF0ZVBvc2l0aW9uUmVsYXRpb25zKCksdGhpcy51cGRhdGVGYWNlUmVsYXRpb25zKCksdGhpcy51cGRhdGVSZWxhdGlvbkluZGV4cygpLHRoaXMuaW5jbHVkaW5nVGhyb3VnaCYmdGhpcy51cGRhdGVUaHJvdWdoSW5kZXhzKCksdGhpcy5yZXNldE1lYXN1cmUoKX11cGRhdGVQb3NpdGlvblJlbGF0aW9ucygpe3RoaXMucG9zaXRpb25SZWxhdGlvbnM9dGhpcy5nZW5lcmF0ZVBvc2l0aW9uUmVsYXRpb25zKCl9dXBkYXRlRmFjZVJlbGF0aW9ucygpe3RoaXMuZmFjZVJlbGF0aW9ucz10aGlzLmdlbmVyYXRlRmFjZVJlbGF0aW9ucygpfXVwZGF0ZVJlbGF0aW9uSW5kZXhzKCl7Y29uc3QgdD1+eS5UaHJvdWdoSW50ZXJzZWN0JnRoaXMucmVsYXRpb247dGhpcy5yZWxhdGlvbkluZGV4c1dpdGhvdXRUaHJvdWduPXRoaXMuZmlsdGVyRmFjZXModCx0aGlzLnJlbGF0aW9uRXF1YWwpfXVwZGF0ZVRocm91Z2hJbmRleHMoKXt0aGlzLnRocm91Z2hJbmRleHM9dGhpcy5maWx0ZXJGYWNlcyh5LlRocm91Z2hJbnRlcnNlY3QsZGUuZXF1YWwpLHRoaXMuX3Rocm91Z2hGYWNlcz1udWxsLHRoaXMuX3Rocm91Z2hGYWNlQXJlYXM9bnVsbH1yZXNldE1lYXN1cmUoKXt0aGlzLl9yZWxhdGlvbkFyZWE9bnVsbCx0aGlzLl9yZWxhdGlvblZvbHVtZT1udWxsLHRoaXMuX2FyZWE9bnVsbCx0aGlzLl92b2x1bWU9bnVsbH11cGRhdGVNZWFzdXJlKCl7dGhpcy5yZXNldE1lYXN1cmUoKSx0aGlzLnJlbGF0aW9uQXJlYSx0aGlzLnJlbGF0aW9uVm9sdW1lLHRoaXMuYXJlYSx0aGlzLnZvbHVtZX1fZ2V0UG9zaXRpb249bnVsbDtnZXQgZ2V0UG9zaXRpb24oKXtyZXR1cm4gdGhpcy5fZ2V0UG9zaXRpb258fCh0aGlzLl9nZXRQb3NpdGlvbj10aGlzLmdlb21ldHJ5LmNyZWF0ZUFnZ3JlZ2F0ZVZlY3RvckdldHRlcih0aGlzLnBvc2l0aW9uTmFtZXMpKX1nZXQgcmVsYXRpb25BcmVhKCl7cmV0dXJuIHRoaXMuX3JlbGF0aW9uQXJlYT09bnVsbCYmKHRoaXMuX3JlbGF0aW9uQXJlYT10aGlzLmNvbXB1dGVSZWxhdGlvbkFyZWEoKSksdGhpcy5fcmVsYXRpb25BcmVhfV9yZWxhdGlvbkFyZWE9bnVsbDtjb21wdXRlUmVsYXRpb25BcmVhKCl7Y29uc3R7Z2VvbWV0cnk6dH09dGhpcyxuPXRoaXMucmVsYXRpb25JbmRleHNXaXRob3V0VGhyb3Vnbi5mbGF0TWFwKGk9PlsuLi50LmluZGljZXMuZ2V0VmVjdG9yKGkpXSk7bGV0IHI9VHIobix0aGlzLmdldFBvc2l0aW9uKTtpZih0aGlzLmluY2x1ZGluZ1Rocm91Z2gpZm9yKGNvbnN0IGkgb2YgdGhpcy50aHJvdWdoRmFjZUFyZWFzKXIrPWk7cmV0dXJuIHJ9Z2V0IGFyZWEoKXtyZXR1cm4gdGhpcy5fYXJlYT09bnVsbCYmKHRoaXMuX2FyZWE9dGhpcy5jb21wdXRlQXJlYSgpKSx0aGlzLl9hcmVhfV9hcmVhPW51bGw7Y29tcHV0ZUFyZWEoKXtyZXR1cm4gVHIodGhpcy5nZW9tZXRyeS5pbmRpY2VzLmFycmF5LHRoaXMuZ2V0UG9zaXRpb24pfWdldCByZWxhdGlvblZvbHVtZSgpe3JldHVybiB0aGlzLl9yZWxhdGlvblZvbHVtZT09bnVsbCYmKHRoaXMuX3JlbGF0aW9uVm9sdW1lPXRoaXMuY29tcHV0ZVJlbGF0aW9uVGVycmFpblZvbHVtZSgpKSx0aGlzLl9yZWxhdGlvblZvbHVtZX1fcmVsYXRpb25Wb2x1bWU9bnVsbDtjb21wdXRlUmVsYXRpb25UZXJyYWluVm9sdW1lKHQ9WzAsMS8wXSl7Y29uc3R7Z2VvbWV0cnk6bn09dGhpcyxyPXRoaXMucmVsYXRpb25JbmRleHNXaXRob3V0VGhyb3Vnbi5mbGF0TWFwKHM9PlsuLi5uLmluZGljZXMuZ2V0VmVjdG9yKHMpXSk7bGV0IGk9dnIocix0aGlzLmdldFBvc2l0aW9uLHQpO2lmKHRoaXMuaW5jbHVkaW5nVGhyb3VnaCl7Y29uc3RbcyxvXT10LGM9by1zO2xldCBsPTA7Y29uc3QgaD0xLzMse2dlb21ldHJ5OmYscG9zaXRpb25OYW1lczp1fT10aGlzO3RoaXMudGhyb3VnaEZhY2VBcmVhcy5mb3JFYWNoKChkLGcpPT57Y29uc3QgbT10aGlzLnRocm91Z2hJbmRleHNbZ10sW18scCxNXT1mLmdldEZhY2VBZ2dyZWdhdGVWZWN0b3IodSxtKSxBPShfWzJdK3BbMl0rTVsyXSkqaC1zO0E8PTB8fChsKz1kKk1hdGgubWluKEEsYykpfSksbC89MixpKz1sfXJldHVybiBpfWdldCB2b2x1bWUoKXtyZXR1cm4gdGhpcy5fdm9sdW1lPT1udWxsJiYodGhpcy5fdm9sdW1lPXRoaXMuY29tcHV0ZVRlcnJhaW5Wb2x1bWUoWy0xLzAsMS8wXSkpLHRoaXMuX3ZvbHVtZX1fdm9sdW1lPW51bGw7Y29tcHV0ZVRlcnJhaW5Wb2x1bWUodCl7cmV0dXJuIHZyKHRoaXMuZ2VvbWV0cnkuaW5kaWNlcy5hcnJheSx0aGlzLmdldFBvc2l0aW9uLHQpfX1jbGFzcyB3biBleHRlbmRzIGdje2dldCBpc0NvbnZleCgpe3JldHVybiB0aGlzLl9pc0NvbnZleD09bnVsbCYmKHRoaXMuX2lzQ29udmV4PXNvKHRoaXMucmVnaW9uKSksdGhpcy5faXNDb252ZXh9c2V0IGlzQ29udmV4KHQpe3RoaXMuX2lzQ29udmV4PXR9X2lzQ29udmV4PW51bGw7c2V0T3B0aW9ucyh0KXtpZih0LnJlZ2lvbil7Y29uc3Qgbj10LnJlZ2lvbi5tYXAocj0+bmV3IHhuKHIpKTt0aGlzLnBvbHlnb249bmV3IFNlKG4pLHRoaXMuaXNaZXJvUG9seWdvbj10aGlzLnBvbHlnb24uYXJlYSgpPT09MH1zdXBlci5zZXRPcHRpb25zKHQpfXJlc2V0TWVhc3VyZSgpe3N1cGVyLnJlc2V0TWVhc3VyZSgpLHRoaXMuX3BvbHlnb25PdXRzaWRlR2VvbWV0cnk9bnVsbH1nZW5lcmF0ZVBvc2l0aW9uUmVsYXRpb25zKCl7cmV0dXJuIHRoaXMuaXNDb252ZXg/aG8odGhpcy5nZW9tZXRyeSx0aGlzLnJlZ2lvbix0aGlzLnBvc2l0aW9uTmFtZXMpOmxvKHRoaXMuZ2VvbWV0cnksdGhpcy5yZWdpb24sdGhpcy5wb3NpdGlvbk5hbWVzKX1nZW5lcmF0ZUZhY2VSZWxhdGlvbnMoKXtyZXR1cm4gZm8odGhpcy5nZW9tZXRyeSx0aGlzLnJlZ2lvbix0aGlzLnBvc2l0aW9uTmFtZXMsdGhpcy5wb3NpdGlvblJlbGF0aW9ucyx0aGlzLmlzQ29udmV4KX1nZW5lcmF0ZVRocm91Z2hGYWNlcygpe2NvbnN0e2dlb21ldHJ5OnQscG9seWdvbjpufT10aGlzLHI9dGhpcy5yZWxhdGlvbiZ5LkNvbnRhaW47bGV0IGk9cj92ZS5pbnRlcnNlY3Q6dmUuc3VidHJhY3Q7cmV0dXJuIHRoaXMuaXNaZXJvUG9seWdvbiYmKGk9cj8ocyxvKT0+bjoocyxvKT0+cyksdGhpcy50aHJvdWdoSW5kZXhzLm1hcChzPT57Y29uc3QgYz10LmdldEZhY2VBZ2dyZWdhdGVWZWN0b3IodGhpcy5wb3NpdGlvbk5hbWVzLHMpLm1hcChoPT5uZXcgeG4oaFswXSxoWzFdKSksbD1uZXcgU2UoYyk7cmV0dXJuIGkobCxuKX0pfWZpbHRlckZhY2VzKHQsbil7cmV0dXJuIG1vKHRoaXMuZmFjZVJlbGF0aW9ucyx0LG4pfWdldCBwb2x5Z29uT3V0c2lkZUdlb21ldHJ5KCl7cmV0dXJuIHRoaXMuX3BvbHlnb25PdXRzaWRlR2VvbWV0cnk9PW51bGwmJih0aGlzLl9wb2x5Z29uT3V0c2lkZUdlb21ldHJ5PXRoaXMuaXNaZXJvUG9seWdvbj90aGlzLnBvbHlnb246dmUuc3VidHJhY3QodGhpcy5wb2x5Z29uLHRoaXMuZ2VvbWV0cnlQb2x5Z29uKSksdGhpcy5fcG9seWdvbk91dHNpZGVHZW9tZXRyeX1fcG9seWdvbk91dHNpZGVHZW9tZXRyeT1udWxsfWNvbnN0IFMwPTYzNzgxMzcsUDA9NjM3ODEzNyxMMD02MzU2NzUyMzE0MjQ1MTc5ZS05O2Z1bmN0aW9uIEFuKGUpe3JldHVybiBlfW5ldyBQO2Z1bmN0aW9uIFIwKGUsdD1bXSxuPUFuKXtyZXR1cm4ibG9uZ2l0dWRlImluIGU/KHRbMF09bihlLmxvbmdpdHVkZSksdFsxXT1uKGUubGF0aXR1ZGUpLHRbMl09ZS5oZWlnaHQpOiJ4ImluIGU/KHRbMF09bihlLngpLHRbMV09bihlLnkpLHRbMl09ZS56KToodFswXT1uKGVbMF0pLHRbMV09bihlWzFdKSx0WzJdPWVbMl0pLHR9ZnVuY3Rpb24gQzAoZSx0PVtdKXtyZXR1cm4gUjAoZSx0LEcuX2NhcnRvZ3JhcGhpY1JhZGlhbnM/QW46Y2UpfWZ1bmN0aW9uIFYwKGUsdCxuPUFuKXtyZXR1cm4ibG9uZ2l0dWRlImluIHQ/KHQubG9uZ2l0dWRlPW4oZVswXSksdC5sYXRpdHVkZT1uKGVbMV0pLHQuaGVpZ2h0PWVbMl0pOiJ4ImluIHQ/KHQueD1uKGVbMF0pLHQueT1uKGVbMV0pLHQuej1lWzJdKToodFswXT1uKGVbMF0pLHRbMV09bihlWzFdKSx0WzJdPWVbMl0pLHR9ZnVuY3Rpb24gTjAoZSx0KXtyZXR1cm4gVjAoZSx0LEcuX2NhcnRvZ3JhcGhpY1JhZGlhbnM/QW46VmMpfWNvbnN0IG1jPTFlLTE0LHowPW5ldyBQLHBjPXt1cDp7c291dGg6ImVhc3QiLG5vcnRoOiJ3ZXN0Iix3ZXN0OiJzb3V0aCIsZWFzdDoibm9ydGgifSxkb3duOntzb3V0aDoid2VzdCIsbm9ydGg6ImVhc3QiLHdlc3Q6Im5vcnRoIixlYXN0OiJzb3V0aCJ9LHNvdXRoOnt1cDoid2VzdCIsZG93bjoiZWFzdCIsd2VzdDoiZG93biIsZWFzdDoidXAifSxub3J0aDp7dXA6ImVhc3QiLGRvd246Indlc3QiLHdlc3Q6InVwIixlYXN0OiJkb3duIn0sd2VzdDp7dXA6Im5vcnRoIixkb3duOiJzb3V0aCIsbm9ydGg6ImRvd24iLHNvdXRoOiJ1cCJ9LGVhc3Q6e3VwOiJzb3V0aCIsZG93bjoibm9ydGgiLG5vcnRoOiJ1cCIsc291dGg6ImRvd24ifX0sWnI9e25vcnRoOlstMSwwLDBdLGVhc3Q6WzAsMSwwXSx1cDpbMCwwLDFdLHNvdXRoOlsxLDAsMF0sd2VzdDpbMCwtMSwwXSxkb3duOlswLDAsLTFdfSxSZT17ZWFzdDpuZXcgUCxub3J0aDpuZXcgUCx1cDpuZXcgUCx3ZXN0Om5ldyBQLHNvdXRoOm5ldyBQLGRvd246bmV3IFB9LCQwPW5ldyBQLGswPW5ldyBQLEYwPW5ldyBQO2Z1bmN0aW9uIF9jKGUsdCxuLHIsaSxzKXtjb25zdCBvPXBjW3RdJiZwY1t0XVtuXTtidChvJiYoIXJ8fHI9PT1vKSk7bGV0IGMsbCxoO2NvbnN0IGY9ejAuY29weShpKTtpZihrKGYueCwwLG1jKSYmayhmLnksMCxtYykpe2NvbnN0IGQ9TWF0aC5zaWduKGYueik7Yz0kMC5mcm9tQXJyYXkoWnJbdF0pLHQhPT0iZWFzdCImJnQhPT0id2VzdCImJmMuc2NhbGUoZCksbD1rMC5mcm9tQXJyYXkoWnJbbl0pLG4hPT0iZWFzdCImJm4hPT0id2VzdCImJmwuc2NhbGUoZCksaD1GMC5mcm9tQXJyYXkoWnJbcl0pLHIhPT0iZWFzdCImJnIhPT0id2VzdCImJmguc2NhbGUoZCl9ZWxzZXtjb25zdHt1cDpkLGVhc3Q6Zyxub3J0aDptfT1SZTtnLnNldCgtZi55LGYueCwwKS5ub3JtYWxpemUoKSxlLmdlb2RldGljU3VyZmFjZU5vcm1hbChmLGQpLG0uY29weShkKS5jcm9zcyhnKTtjb25zdHtkb3duOl8sd2VzdDpwLHNvdXRoOk19PVJlO18uY29weShkKS5zY2FsZSgtMSkscC5jb3B5KGcpLnNjYWxlKC0xKSxNLmNvcHkobSkuc2NhbGUoLTEpLGM9UmVbdF0sbD1SZVtuXSxoPVJlW3JdfXJldHVybiBzWzBdPWMueCxzWzFdPWMueSxzWzJdPWMueixzWzNdPTAsc1s0XT1sLngsc1s1XT1sLnksc1s2XT1sLnosc1s3XT0wLHNbOF09aC54LHNbOV09aC55LHNbMTBdPWgueixzWzExXT0wLHNbMTJdPWYueCxzWzEzXT1mLnksc1sxNF09Zi56LHNbMTVdPTEsc31jb25zdCBzZT1uZXcgUCxxMD1uZXcgUCxVMD1uZXcgUDtmdW5jdGlvbiBEMChlLHQsbj1bXSl7Y29uc3R7b25lT3ZlclJhZGlpOnIsb25lT3ZlclJhZGlpU3F1YXJlZDppLGNlbnRlclRvbGVyYW5jZVNxdWFyZWQ6c309dDtzZS5mcm9tKGUpO2NvbnN0IG89c2UueCxjPXNlLnksbD1zZS56LGg9ci54LGY9ci55LHU9ci56LGQ9bypvKmgqaCxnPWMqYypmKmYsbT1sKmwqdSp1LF89ZCtnK20scD1NYXRoLnNxcnQoMS9fKTtpZighTnVtYmVyLmlzRmluaXRlKHApKXJldHVybjtjb25zdCBNPXEwO2lmKE0uY29weShlKS5zY2FsZShwKSxfPHMpcmV0dXJuIE0udG8obik7Y29uc3QgQT1pLngseD1pLnksVD1pLnosdj1VMDt2LnNldChNLngqQSoyLE0ueSp4KjIsTS56KlQqMik7bGV0IHc9KDEtcCkqc2UubGVuKCkvKC41KnYubGVuKCkpLFM9MCxiLEksRSxWO2Rve3ctPVMsYj0xLygxK3cqQSksST0xLygxK3cqeCksRT0xLygxK3cqVCk7Y29uc3QgTj1iKmIsej1JKkksTD1FKkUsSD1OKmIscT16KkksWj1MKkU7Vj1kKk4rZyp6K20qTC0xO2NvbnN0IG50PS0yKihkKkgqQStnKnEqeCttKloqVCk7Uz1WL250fXdoaWxlKE1hdGguYWJzKFYpPlZoKTtyZXR1cm4gc2Uuc2NhbGUoW2IsSSxFXSkudG8obil9Y29uc3QgVG49bmV3IFAseWM9bmV3IFAsQjA9bmV3IFAsbHQ9bmV3IFAsWTA9bmV3IFAsdm49bmV3IFA7Y2xhc3MgRW57Y29uc3RydWN0b3IodD0wLG49MCxyPTApe3RoaXMuY2VudGVyVG9sZXJhbmNlU3F1YXJlZD1DaCxidCh0Pj0wKSxidChuPj0wKSxidChyPj0wKSx0aGlzLnJhZGlpPW5ldyBQKHQsbixyKSx0aGlzLnJhZGlpU3F1YXJlZD1uZXcgUCh0KnQsbipuLHIqciksdGhpcy5yYWRpaVRvVGhlRm91cnRoPW5ldyBQKHQqdCp0KnQsbipuKm4qbixyKnIqcipyKSx0aGlzLm9uZU92ZXJSYWRpaT1uZXcgUCh0PT09MD8wOjEvdCxuPT09MD8wOjEvbixyPT09MD8wOjEvciksdGhpcy5vbmVPdmVyUmFkaWlTcXVhcmVkPW5ldyBQKHQ9PT0wPzA6MS8odCp0KSxuPT09MD8wOjEvKG4qbikscj09PTA/MDoxLyhyKnIpKSx0aGlzLm1pbmltdW1SYWRpdXM9TWF0aC5taW4odCxuLHIpLHRoaXMubWF4aW11bVJhZGl1cz1NYXRoLm1heCh0LG4sciksdGhpcy5yYWRpaVNxdWFyZWQueiE9PTAmJih0aGlzLnNxdWFyZWRYT3ZlclNxdWFyZWRaPXRoaXMucmFkaWlTcXVhcmVkLngvdGhpcy5yYWRpaVNxdWFyZWQueiksT2JqZWN0LmZyZWV6ZSh0aGlzKX1lcXVhbHModCl7cmV0dXJuIHRoaXM9PT10fHwhISh0JiZ0aGlzLnJhZGlpLmVxdWFscyh0LnJhZGlpKSl9dG9TdHJpbmcoKXtyZXR1cm4gdGhpcy5yYWRpaS50b1N0cmluZygpfWNhcnRvZ3JhcGhpY1RvQ2FydGVzaWFuKHQsbj1bMCwwLDBdKXtjb25zdCByPXljLGk9QjAsWywsc109dDt0aGlzLmdlb2RldGljU3VyZmFjZU5vcm1hbENhcnRvZ3JhcGhpYyh0LHIpLGkuY29weSh0aGlzLnJhZGlpU3F1YXJlZCkuc2NhbGUocik7Y29uc3Qgbz1NYXRoLnNxcnQoci5kb3QoaSkpO3JldHVybiBpLnNjYWxlKDEvbyksci5zY2FsZShzKSxpLmFkZChyKSxpLnRvKG4pfWNhcnRlc2lhblRvQ2FydG9ncmFwaGljKHQsbj1bMCwwLDBdKXt2bi5mcm9tKHQpO2NvbnN0IHI9dGhpcy5zY2FsZVRvR2VvZGV0aWNTdXJmYWNlKHZuLGx0KTtpZighcilyZXR1cm47Y29uc3QgaT10aGlzLmdlb2RldGljU3VyZmFjZU5vcm1hbChyLHljKSxzPVkwO3MuY29weSh2bikuc3VidHJhY3Qocik7Y29uc3Qgbz1NYXRoLmF0YW4yKGkueSxpLngpLGM9TWF0aC5hc2luKGkueiksbD1NYXRoLnNpZ24oaGUocyx2bikpKlVlKHMpO3JldHVybiBOMChbbyxjLGxdLG4pfWVhc3ROb3J0aFVwVG9GaXhlZEZyYW1lKHQsbj1uZXcgdHQpe3JldHVybiBfYyh0aGlzLCJlYXN0Iiwibm9ydGgiLCJ1cCIsdCxuKX1sb2NhbEZyYW1lVG9GaXhlZEZyYW1lKHQsbixyLGkscz1uZXcgdHQpe3JldHVybiBfYyh0aGlzLHQsbixyLGkscyl9Z2VvY2VudHJpY1N1cmZhY2VOb3JtYWwodCxuPVswLDAsMF0pe3JldHVybiBUbi5mcm9tKHQpLm5vcm1hbGl6ZSgpLnRvKG4pfWdlb2RldGljU3VyZmFjZU5vcm1hbENhcnRvZ3JhcGhpYyh0LG49WzAsMCwwXSl7Y29uc3Qgcj1DMCh0KSxpPXJbMF0scz1yWzFdLG89TWF0aC5jb3Mocyk7cmV0dXJuIFRuLnNldChvKk1hdGguY29zKGkpLG8qTWF0aC5zaW4oaSksTWF0aC5zaW4ocykpLm5vcm1hbGl6ZSgpLFRuLnRvKG4pfWdlb2RldGljU3VyZmFjZU5vcm1hbCh0LG49WzAsMCwwXSl7cmV0dXJuIFRuLmZyb20odCkuc2NhbGUodGhpcy5vbmVPdmVyUmFkaWlTcXVhcmVkKS5ub3JtYWxpemUoKS50byhuKX1zY2FsZVRvR2VvZGV0aWNTdXJmYWNlKHQsbil7cmV0dXJuIEQwKHQsdGhpcyxuKX1zY2FsZVRvR2VvY2VudHJpY1N1cmZhY2UodCxuPVswLDAsMF0pe2x0LmZyb20odCk7Y29uc3Qgcj1sdC54LGk9bHQueSxzPWx0Lnosbz10aGlzLm9uZU92ZXJSYWRpaVNxdWFyZWQsYz0xL01hdGguc3FydChyKnIqby54K2kqaSpvLnkrcypzKm8ueik7cmV0dXJuIGx0Lm11bHRpcGx5U2NhbGFyKGMpLnRvKG4pfXRyYW5zZm9ybVBvc2l0aW9uVG9TY2FsZWRTcGFjZSh0LG49WzAsMCwwXSl7cmV0dXJuIGx0LmZyb20odCkuc2NhbGUodGhpcy5vbmVPdmVyUmFkaWkpLnRvKG4pfXRyYW5zZm9ybVBvc2l0aW9uRnJvbVNjYWxlZFNwYWNlKHQsbj1bMCwwLDBdKXtyZXR1cm4gbHQuZnJvbSh0KS5zY2FsZSh0aGlzLnJhZGlpKS50byhuKX1nZXRTdXJmYWNlTm9ybWFsSW50ZXJzZWN0aW9uV2l0aFpBeGlzKHQsbj0wLHI9WzAsMCwwXSl7YnQoayh0aGlzLnJhZGlpLngsdGhpcy5yYWRpaS55LE5oKSksYnQodGhpcy5yYWRpaS56PjApLGx0LmZyb20odCk7Y29uc3QgaT1sdC56KigxLXRoaXMuc3F1YXJlZFhPdmVyU3F1YXJlZFopO2lmKCEoTWF0aC5hYnMoaSk+PXRoaXMucmFkaWkuei1uKSlyZXR1cm4gbHQuc2V0KDAsMCxpKS50byhyKX19RW4uV0dTODQ9bmV3IEVuKFMwLFAwLEwwKTtmdW5jdGlvbiBHcihlLHQ9RW4uV0dTODQsbj1uZXcgSyl7Y29uc3Qgcj10LmdldFN1cmZhY2VOb3JtYWxJbnRlcnNlY3Rpb25XaXRoWkF4aXMoZSwwLG90WzBdKSxpPWtuKGUscikscz10Lm1pbmltdW1SYWRpdXMqaS90Lm1heGltdW1SYWRpdXMqKjIsbz1pKnMqKjI7cmV0dXJuIG5bMF09aSxuWzBdPW8sbn1mdW5jdGlvbiBXMChlLHQsbil7cmV0dXJuIG49R3IoZSx0LG4pLEluKFsxLDFdLG4sbiksbn1mdW5jdGlvbiBaMChlLHQsbil7bj1HcihlLHQsbik7Y29uc3Qgcj1NYXRoLlBJLzE4MDtyZXR1cm4gYWkobixuLHIpfWZ1bmN0aW9uIEcwKGUpe2xldCB0PWUuZWFzdDtjb25zdCBuPWUud2VzdDtyZXR1cm4gdDxuJiYodCs9VyksdC1ufWZ1bmN0aW9uIFgwKGUpe3JldHVybiBlLm5vcnRoLWUuc291dGh9ZnVuY3Rpb24gajAoZSx0LG4scixpPXt9KXtyZXR1cm4gaS53ZXN0PWNlKGU/PzApLGkuc291dGg9Y2UodD8/MCksaS5lYXN0PWNlKG4/PzApLGkubm9ydGg9Y2Uocj8/MCksaX1mdW5jdGlvbiBRMChlLHQ9e30pe2xldCBuPU51bWJlci5NQVhfVkFMVUUscj0tTnVtYmVyLk1BWF9WQUxVRSxpPU51bWJlci5NQVhfVkFMVUUscz0tTnVtYmVyLk1BWF9WQUxVRSxvPU51bWJlci5NQVhfVkFMVUUsYz0tTnVtYmVyLk1BWF9WQUxVRTtmb3IobGV0IGw9MCxoPWUubGVuZ3RoO2w8aDtsKyspe2NvbnN0W2YsdV09ZVtsXTtuPU1hdGgubWluKG4sZikscj1NYXRoLm1heChyLGYpLG89TWF0aC5taW4obyx1KSxjPU1hdGgubWF4KGMsdSk7Y29uc3QgZD1mPj0wP2Y6ZitXO2k9TWF0aC5taW4oaSxkKSxzPU1hdGgubWF4KHMsZCl9cmV0dXJuIHItbj5zLWkmJihuPWkscj1zLHI+TWF0aC5QSSYmKHI9ci1XKSxuPk1hdGguUEkmJihuPW4tVykpLHQud2VzdD1uLHQuc291dGg9byx0LmVhc3Q9cix0Lm5vcnRoPWMsdH1mdW5jdGlvbiBLMChlLHQsbj17fSl7dD10Pz9Fbi5XR1M4NDtsZXQgcj1OdW1iZXIuTUFYX1ZBTFVFLGk9LU51bWJlci5NQVhfVkFMVUUscz1OdW1iZXIuTUFYX1ZBTFVFLG89LU51bWJlci5NQVhfVkFMVUUsYz1OdW1iZXIuTUFYX1ZBTFVFLGw9LU51bWJlci5NQVhfVkFMVUU7Zm9yKGxldCBoPTAsZj1lLmxlbmd0aDtoPGY7aCsrKXtjb25zdFt1LGRdPXQuY2FydGVzaWFuVG9DYXJ0b2dyYXBoaWMoZVtoXSk7cj1NYXRoLm1pbihyLHUpLGk9TWF0aC5tYXgoaSx1KSxjPU1hdGgubWluKGMsZCksbD1NYXRoLm1heChsLGQpO2NvbnN0IGc9dT49MD91OnUrVztzPU1hdGgubWluKHMsZyksbz1NYXRoLm1heChvLGcpfXJldHVybiBpLXI+by1zJiYocj1zLGk9byxpPk1hdGguUEkmJihpPWktVykscj5NYXRoLlBJJiYocj1yLVcpKSxuLndlc3Q9cixuLnNvdXRoPWMsbi5lYXN0PWksbi5ub3J0aD1sLG59ZnVuY3Rpb24gSjAoZSx0LG49MCl7cmV0dXJuIGU9PT10fHxlJiZ0JiZNYXRoLmFicyhlLndlc3QtdC53ZXN0KTw9biYmTWF0aC5hYnMoZS5zb3V0aC10LnNvdXRoKTw9biYmTWF0aC5hYnMoZS5lYXN0LXQuZWFzdCk8PW4mJk1hdGguYWJzKGUubm9ydGgtdC5ub3J0aCk8PW59ZnVuY3Rpb24gSDAoZSx0KXtyZXR1cm4gZT09PXR8fGUmJnQmJmUud2VzdD09PXQud2VzdCYmZS5zb3V0aD09PXQuc291dGgmJmUuZWFzdD09PXQuZWFzdCYmZS5ub3J0aD09PXQubm9ydGh9ZnVuY3Rpb24gdDEoZSx0PW5ldyBLKXtyZXR1cm4gdFswXT1lLndlc3QsdFsxXT1lLnNvdXRoLHR9ZnVuY3Rpb24gZTEoZSx0PW5ldyBLKXtyZXR1cm4gdFswXT1lLndlc3QsdFsxXT1lLm5vcnRoLHR9ZnVuY3Rpb24gbjEoZSx0PW5ldyBLKXtyZXR1cm4gdFswXT1lLmVhc3QsdFsxXT1lLm5vcnRoLHR9ZnVuY3Rpb24gcjEoZSx0PW5ldyBLKXtyZXR1cm4gdFswXT1lLmVhc3QsdFsxXT1lLnNvdXRoLHR9ZnVuY3Rpb24geGMoZSl7Y29uc3R7d2VzdDp0LGVhc3Q6bixzb3V0aDpyLG5vcnRoOml9PWU7cmV0dXJuW25ldyBLKHQsciksbmV3IEsodCxpKSxuZXcgSyhuLGkpLG5ldyBLKG4scildfWZ1bmN0aW9uIGkxKGUsdD1uZXcgSyl7bGV0IG49ZS5lYXN0O2NvbnN0IHI9ZS53ZXN0O248ciYmKG4rPVcpO2NvbnN0IGk9WnQoKHIrbikqLjUpLHM9KGUuc291dGgrZS5ub3J0aCkqLjU7cmV0dXJuIHRbMF09aSx0WzFdPXMsdH1mdW5jdGlvbiBzMShlLHQsbj17fSl7bGV0IHI9ZS5lYXN0LGk9ZS53ZXN0LHM9dC5lYXN0LG89dC53ZXN0O3I8aSYmcz4wP3IrPVc6czxvJiZyPjAmJihzKz1XKSxyPGkmJm88MD9vKz1XOnM8byYmaTwwJiYoaSs9Vyk7Y29uc3QgYz1adChNYXRoLm1heChpLG8pKSxsPVp0KE1hdGgubWluKHIscykpO2lmKChlLndlc3Q8ZS5lYXN0fHx0Lndlc3Q8dC5lYXN0KSYmbDw9YylyZXR1cm47Y29uc3QgaD1NYXRoLm1heChlLnNvdXRoLHQuc291dGgpLGY9TWF0aC5taW4oZS5ub3J0aCx0Lm5vcnRoKTtpZighKGg+PWYpKXJldHVybiBuLndlc3Q9YyxuLnNvdXRoPWgsbi5lYXN0PWwsbi5ub3J0aD1mLG59ZnVuY3Rpb24gbzEoZSx0LG4pe2NvbnN0IHI9TWF0aC5tYXgoZS53ZXN0LHQud2VzdCksaT1NYXRoLm1heChlLnNvdXRoLHQuc291dGgpLHM9TWF0aC5taW4oZS5lYXN0LHQuZWFzdCksbz1NYXRoLm1pbihlLm5vcnRoLHQubm9ydGgpO2lmKCEoaT49b3x8cj49cykpcmV0dXJuIG4/Pz17fSxuLndlc3Q9cixuLnNvdXRoPWksbi5lYXN0PXMsbi5ub3J0aD1vLG59ZnVuY3Rpb24gYzEoZSx0LG49e30pe2xldCByPWUuZWFzdCxpPWUud2VzdCxzPXQuZWFzdCxvPXQud2VzdDtyPGkmJnM+MD9yKz1XOnM8byYmcj4wJiYocys9VykscjxpJiZvPDA/bys9VzpzPG8mJmk8MCYmKGkrPVcpO2NvbnN0IGM9WnQoTWF0aC5taW4oaSxvKSksbD1adChNYXRoLm1heChyLHMpKTtyZXR1cm4gbi53ZXN0PWMsbi5zb3V0aD1NYXRoLm1pbihlLnNvdXRoLHQuc291dGgpLG4uZWFzdD1sLG4ubm9ydGg9TWF0aC5tYXgoZS5ub3J0aCx0Lm5vcnRoKSxufWZ1bmN0aW9uIGExKGUsdCxuPXt9KXtyZXR1cm4gbi53ZXN0PU1hdGgubWluKGUud2VzdCx0WzBdKSxuLnNvdXRoPU1hdGgubWluKGUuc291dGgsdFsxXSksbi5lYXN0PU1hdGgubWF4KGUuZWFzdCx0WzBdKSxuLm5vcnRoPU1hdGgubWF4KGUubm9ydGgsdFsxXSksbn1mdW5jdGlvbiBsMShlLHQpe2xldCBuPXRbMF07Y29uc3Qgcj10WzFdLGk9ZS53ZXN0O2xldCBzPWUuZWFzdDtyZXR1cm4gczxpJiYocys9VyxuPDAmJihuKz1XKSksKG4+aXx8ZnIobixpLGVuKSkmJihuPHN8fGZyKG4scyxlbikpJiZyPj1lLnNvdXRoJiZyPD1lLm5vcnRofWNvbnN0IGgxPU9iamVjdC5mcmVlemUoe3dlc3Q6LU1hdGguUEksZWFzdDpNYXRoLlBJLHNvdXRoOi1lcixub3J0aDplcn0pO2Z1bmN0aW9uIGYxKGUpe2NvbnN0e21hdHJpeDp0LHBvc2l0aW9uTmFtZXM6bj1MZSxzY2FsZTpyfT1lLGk9bmV3IGFuKGUpO3QmJmkudHJhbnNmb3JtRm9yQWdncmVnYXRlKHQsbik7Y29uc3Qgbz1uZXcgd24oey4uLmUsZ2VvbWV0cnk6aX0pLnJlbGF0aW9uQXJlYTtpZighcilyZXR1cm4gbztjb25zdCBjPU1hdGguaHlwb3QoclswXSxyWzJdKSpyWzFdO3JldHVybiBvKk1hdGguYWJzKGMpfWZ1bmN0aW9uIE1jKGUpe2NvbnN0e21hdHJpeDp0LHBvc2l0aW9uTmFtZXM6bj1MZSxzY2FsZTpyLGhlaWdodFJhbmdlOml9PWUscz1uZXcgYW4oZSk7dCYmcy50cmFuc2Zvcm1Gb3JBZ2dyZWdhdGUodCxuKTtjb25zdCBvPW5ldyB3bih7Li4uZSxnZW9tZXRyeTpzfSk7bGV0IGM9MTtpZihyKWZvcihsZXQgbCBvZiByKWMqPWw7cmV0dXJuIG8uY29tcHV0ZVJlbGF0aW9uVGVycmFpblZvbHVtZShpKSpjfWZ1bmN0aW9uIHUxKGUpe2NvbnN0e3JlY3RhbmdsZTp0LGhlaWdodFJhbmdlOm4scG9zaXRpb25OYW1lczpyPUxlLHNjYWxlOml9PWUscz1uZXcgYW4oZSksbz14cih0LG4pO3MudHJhbnNmb3JtRm9yQWdncmVnYXRlKG8scik7Y29uc3QgYz1uZXcgd24oey4uLmUsZ2VvbWV0cnk6c30pLGw9eGModCksaD1uZXcgU2UobCksZj12ZS5zdWJ0cmFjdChoLGMuZ2VvbWV0cnlQb2x5Z29uKSx1PWMucmVsYXRpb25BcmVhK2YuYXJlYSgpO2lmKCFpKXJldHVybiB1O2NvbnN0IGQ9TWF0aC5oeXBvdChpWzBdLGlbMl0pKmlbMV07cmV0dXJuIHUqTWF0aC5hYnMoZCl9ZnVuY3Rpb24gZDEoZSl7Y29uc3R7cmVjdGFuZ2xlOnQsaGVpZ2h0UmFuZ2U6biwuLi5yfT1lLGk9eHIodCxuKTtyZXR1cm4gTWMoey4uLnIsbWF0cml4OmksaGVpZ2h0UmFuZ2U6bn0pfWZ1bmN0aW9uIFhyKGUsdCl7cmV0dXJuIGUueSp0LngrZS54fWZ1bmN0aW9uIGcxKGUsdCl7Y29uc3R7eDpufT10LHI9TWF0aC50cnVuYyhlL24pO3JldHVybnt4OmUtcipuLHk6cn19ZnVuY3Rpb24gbTEoZSx0LG49MSl7bGV0e3g6cix5Oml9PXQ7Y29uc3Qgcz1lLnNpemU7cmV0dXJuIHI9TWF0aC5tYXgoMCxNYXRoLm1pbihzLngtMSxyKSksaT1NYXRoLm1heCgwLE1hdGgubWluKHMueS0xLGkpKSx3YyhlLHt4OnIseTppfSxuKX1mdW5jdGlvbiB3YyhlLHQsbj0xKXtjb25zdHtkYXRhOnIsc2l6ZTppfT1lLHM9WHIodCxpKTtsZXQgbz1bXTtpZihuPjApe2NvbnN0IGM9cypuO2ZvcihsZXQgbD0wO2w8bjtsKyspby5wdXNoKHJbYytsXSl9cmV0dXJue2luZGV4OnMsdmFsdWU6b319ZnVuY3Rpb24gcDEoZSx0KXtsZXR7eDpuLHk6cn09dDtjb25zdCBpPWUuc2l6ZTtyZXR1cm4gbj1NYXRoLm1heCgwLE1hdGgubWluKGkueC0xLG4pKSxyPU1hdGgubWF4KDAsTWF0aC5taW4oaS55LTEscikpLEFjKGUse3g6bix5OnJ9KX1mdW5jdGlvbiBBYyhlLHQpe2NvbnN0e2RhdGE6bixzaXplOnJ9PWUsaT1Ycih0LHIpO3JldHVybntpbmRleDppLHZhbHVlOm5baV19fWZ1bmN0aW9uIF8xKGUsdCxuPTEpe2NvbnN0e2RhdGE6cixzaXplOml9PWUscz1pLngsbz10KnMsYz1vK3M7cmV0dXJuKHR5cGVvZiByLnNsaWNlPT0iZnVuY3Rpb24iP3I6QXJyYXkuZnJvbShyKSkuc2xpY2UobypuLGMqbil9ZnVuY3Rpb24geTEoZSx0KXtmb3IoY29uc3RbbixyXW9mIE9iamVjdC5lbnRyaWVzKGUpKWlmKDA8PXImJnI8PXRbbl0pcmV0dXJuITA7cmV0dXJuITF9ZnVuY3Rpb24ganIoZSx0KXtjb25zdHt4Om4seTpyfT10O3JldHVybiBlLnoqcipuK2UueSpuK2UueH1mdW5jdGlvbiB4MShlLHQpe2NvbnN0e3g6bix5OnJ9PXQsaT1NYXRoLnRydW5jKGUvbikscz1lLWkqbixvPU1hdGgudHJ1bmMoaS9yKSxjPWktbypyO3JldHVybnt4OnMseTpjLHo6b319ZnVuY3Rpb24gTTEoZSx0LG49MSl7bGV0e3g6cix5OmksejpzfT10O2NvbnN0IG89ZS5zaXplO3JldHVybiByPU1hdGgubWF4KDAsTWF0aC5taW4oby54LTEscikpLGk9TWF0aC5tYXgoMCxNYXRoLm1pbihvLnktMSxpKSkscz1NYXRoLm1heCgwLE1hdGgubWluKG8uei0xLHMpKSxRcihlLHt4OnIseTppLHo6c30sbil9ZnVuY3Rpb24gUXIoZSx0LG49MSl7Y29uc3R7ZGF0YTpyLHNpemU6aX09ZSxzPWpyKHQsaSk7bGV0IG89W107aWYobj4wKXtjb25zdCBjPXMqbjtmb3IobGV0IGw9MDtsPG47bCsrKW8ucHVzaChyW2MrbF0pfXJldHVybntpbmRleDpzLHZhbHVlOm99fWZ1bmN0aW9uIHcxKGUsdCl7bGV0e3g6bix5OnIsejppfT10O2NvbnN0IHM9ZS5zaXplO3JldHVybiBuPU1hdGgubWF4KDAsTWF0aC5taW4ocy54LTEsbikpLHI9TWF0aC5tYXgoMCxNYXRoLm1pbihzLnktMSxyKSksaT1NYXRoLm1heCgwLE1hdGgubWluKHMuei0xLGkpKSxLcihlLHt4Om4seTpyLHo6aX0pfWZ1bmN0aW9uIEtyKGUsdCl7Y29uc3R7ZGF0YTpuLHNpemU6cn09ZSxpPWpyKHQscik7cmV0dXJue2luZGV4OmksdmFsdWU6bltpXX19ZnVuY3Rpb24gQTEoZSx0KXtjb25zdHt2b2lkVmFsdWU6bix2YWx1ZXNBY2N1bXVsYXRlOnIsdmVyaWZ5Vm9pZDppPSgpPT4hMX09dDtsZXR7eDpzLHk6byx6OmN9PWVbMF0uc2l6ZTtjb25zdCBsPWUubGVuZ3RoO2ZvcihsZXQgZD0xO2Q8bDtkKyspe2NvbnN0IGc9ZVtkXS5zaXplO3M9TWF0aC5tYXgocyxnLngpLG89TWF0aC5tYXgobyxnLnkpLGM9TWF0aC5tYXgoYyxnLnopfWNvbnN0IGg9cypvKmMsZj1uZXcgQXJyYXkoaCksdT1zKm87Zm9yKGxldCBkPTA7ZDxjO2QrKyl7Y29uc3QgZz1kKnU7Zm9yKGxldCBtPTA7bTxvO20rKyl7Y29uc3QgXz1nK20qcztmb3IobGV0IHA9MDtwPHM7cCsrKXtjb25zdCBNPV8rcCxBPXt4OnAseTptLHo6ZH0seD1bXTtmb3IoY29uc3QgdyBvZiBlKXtjb25zdCBTPXcuc2l6ZTtpZihwPFMueCYmbTxTLnkmJmQ8Uy56KWNvbnRpbnVlO2NvbnN0e2luZGV4OmIsdmFsdWU6SX09S3IodyxBKTtpKEksdyxiKXx8eC5wdXNoKHt2YWx1ZTpJLGluZGV4OmIsZGF0YTNEOncsY29vcmQ6QX0pfWNvbnN0IFQ9eC5sZW5ndGg7bGV0IHY9bjtUPjE/dj1yKHgpOlQ9PT0xJiYodj14WzBdLnZhbHVlKSxmW01dPXZ9fX1yZXR1cm57ZGF0YTpmLHNpemU6e3g6cyx5Om8sejpjfX19ZnVuY3Rpb24gVDEoZSx0LG4scj0xKXtjb25zdHtzaXplOml9PWUscz13dC50b0tleSh0KSxbbyxjXT13dC5nZXRDcm9zc0F4aXNzKHQpLGw9d3QudG9LZXkobyksaD13dC50b0tleShjKSxmPWlbbF0sdT1pW2hdLGQ9W10sZz1pW3NdO249TWF0aC50cnVuYyhuKSxuPU1hdGgubWF4KDAsTWF0aC5taW4oZy0xLG4pKTtsZXQgbT17eDowLHk6MCx6OjB9O21bc109bjtmb3IobGV0IF89MDtfPHU7XysrKXttW2hdPV87Zm9yKGxldCBwPTA7cDxmO3ArKyl7bVtsXT1wO2NvbnN0e3ZhbHVlOk19PVFyKGUsbSxyKTtkLnB1c2goLi4uTSl9fXJldHVybntkYXRhOmQsc2l6ZTp7eDpmLHk6dX19fXZhciB2MT1PYmplY3QuZnJlZXplKHtfX3Byb3RvX186bnVsbCxBdHRyaWJ1dGVOYW1lOkdzLEF0dHJpYnV0ZXM6WHMsZ2V0IEF4aXMoKXtyZXR1cm4gd3R9LGdldCBBeGlzNCgpe3JldHVybiAkZX0sR2VvbWV0cmljUmVsYXRpb246eSxHZW9tZXRyeTphbixHZW9tZXRyeVJlbGF0aW9uTWVhc3VyZTpnYyxMaW5lOmdyLE1hdGhBcnJheTphZSxNYXRyaXg6VW4sZ2V0IE51bWVyaWNBcnJheVR5cGUoKXtyZXR1cm4gbm59LGdldCBPcmllbnRhdGlvbigpe3JldHVybiBmdH0sUG9seWdvbjJHZW9tZXRyeVJlbGF0aW9uTWVhc3VyZTp3bixQb2x5bGluZTpqcyxWZWN0b3I6a2UsVmVjdG9yQXJyYXk6TnQsYWRkVmVjdG9yQXJyYXk6RWYsYWRqdXN0RnJlbmV0RnJhbWU6RnMsYWRqdXN0RnJvbnRVcEZyYW1lOnFzLGFkanVzdE9yaWVudGF0aW9uOnlmLGFnZ3JlZ2F0ZUZhY2VQb3NpdGlvblJlbGF0aW9uc09mR2VvbWV0cnlfUG9seWdvbjpIZixjYWxjdWxhdGVQYXRoQW5pbWF0aW9uVGltZXM6UXMsY2xpcEdlb21ldHJ5QnlCb3JkZXI6X3IsY2xpcEdlb21ldHJ5QnlCb3JkZXJzOktmLGNvbXB1dGVBcmVhT2ZHZW9tZXRyeTpUcixjb21wdXRlQXJlYU9mVHJpYW5nbGUyOmF1LGNvbXB1dGVBcmVhT2ZUcmlhbmdsZTIzOm91LGNvbXB1dGVBcmVhT2ZUcmlhbmdsZTM6Y3UsY29tcHV0ZUNvbnZleEh1bGwyOldmLGNvbXB1dGVDb252ZXhIdWxsMkZvclNvcnRlZDppbyxjb21wdXRlRG91YmxlQXJlYU9mVHJpYW5nbGUyOkFyLGNvbXB1dGVEb3VibGVBcmVhT2ZUcmlhbmdsZTIzOndyLGNvbXB1dGVEb3VibGVBcmVhT2ZUcmlhbmdsZTM6d28sY29tcHV0ZURvdWJsZVNpZ25BcmVhT2ZQb2x5Z29uMjpwbyxjb21wdXRlRG91YmxlU2lnbkFyZWFPZlBvbHlnb24zOl9vLGNvbXB1dGVEb3VibGVTaWduQXJlYU9mVHJpYW5nbGUyOnlvLGNvbXB1dGVEb3VibGVTaWduQXJlYU9mVHJpYW5nbGUyMzpNbyxjb21wdXRlRG91YmxlU2lnbkFyZWFPZlRyaWFuZ2xlMzp4byxjb21wdXRlR2xvYmVPcmllbnRhdGlvbkZyYW1lT25Mb25MYXQ6RHMsY29tcHV0ZUdsb2JlT3JpZW50YXRpb25GcmFtZU9uUG9zaXRpb246ZHIsY29tcHV0ZUludGVyc2VjdGlvbkZhY3Rvck9mTGluZV9DaXJjbGU6R3QsY29tcHV0ZUludGVyc2VjdGlvbk9mMjNMaW5lU2VnbWVudF9MaW5lU2VnbWVudDpEZixjb21wdXRlSW50ZXJzZWN0aW9uT2YyM0xpbmVfTGluZTpwZSxjb21wdXRlSW50ZXJzZWN0aW9uT2YyM1JheV9MaW5lU2VnbWVudDpxZixjb21wdXRlSW50ZXJzZWN0aW9uT2YyTGluZVNlZ21lbnRfTGluZVNlZ21lbnQ6QmYsY29tcHV0ZUludGVyc2VjdGlvbk9mMkxpbmVfTGluZTpobixjb21wdXRlSW50ZXJzZWN0aW9uT2YyUG9seWdvbl9DaXJjbGU6amYsY29tcHV0ZUludGVyc2VjdGlvbk9mMlJheV9MaW5lU2VnbWVudDpVZixjb21wdXRlSW50ZXJzZWN0aW9uT2ZMaW5lU2VnbWVudF9DaXJjbGU6dG8sY29tcHV0ZUludGVyc2VjdGlvbk9mTGluZV9DaXJjbGU6VmYsY29tcHV0ZUludGVyc2VjdGlvbk9mUmF5X0NpcmNsZTp6Zixjb21wdXRlUmVsYXRpb25BcmVhT2ZQb2x5Z29uMkdlb21ldHJ5OmYxLGNvbXB1dGVSZWxhdGlvbkFyZWFPZlBvbHlnb24yVGVycmFpbjp1MSxjb21wdXRlUmVsYXRpb25UZXJyYWluVm9sdW1lT2ZQb2x5Z29uMkdlb21ldHJ5Ok1jLGNvbXB1dGVSZWxhdGlvblRlcnJhaW5Wb2x1bWVPZlBvbHlnb24yVGVycmFpbjpkMSxjb21wdXRlU2lnbkFyZWFPZlBvbHlnb24yOmV1LGNvbXB1dGVTaWduQXJlYU9mUG9seWdvbjM6bnUsY29tcHV0ZVNpZ25BcmVhT2ZUcmlhbmdsZTI6cnUsY29tcHV0ZVNpZ25BcmVhT2ZUcmlhbmdsZTIzOnN1LGNvbXB1dGVTaWduQXJlYU9mVHJpYW5nbGUzOml1LGNvbXB1dGVWb2x1bWVPZlRlcnJhaW46dnIsY3JlYXRlR2xvYmVPcmllbnRhdGlvbkZyYW1lTWF0cml4M09uTG9uTGF0OndmLGNyZWF0ZUdsb2JlT3JpZW50YXRpb25GcmFtZU1hdHJpeDNPblBvc2l0aW9uOk1mLGNyZWF0ZUdsb2JlT3JpZW50YXRpb25GcmFtZU1hdHJpeDRPblBvc2l0aW9uOnhmLGNyZWF0ZUtleWZyYW1lVHJhY2tzT2ZDdXJ2ZUFuaW1hdGlvbkJ5UG9seWxpbmU6TGYsY3JlYXRlT3JpZW50YXRpb25GcmFtZU1hdHJpeDM6Y24sY3JlYXRlT3JpZW50YXRpb25GcmFtZU1hdHJpeDQ6QnMsY3JlYXRlUXVhbnRpemVkTWVzaFRlcnJhaW5WZXJ0ZXhHZXR0ZXI6dHUsY3JlYXRlVmVjdG9yOl9zLGRhdGEyRENvb3JkVG9JbmRleDpYcixkYXRhMkRJbmRleFRvQ29vcmQ6ZzEsZGF0YTNEQ29vcmRUb0luZGV4OmpyLGRhdGEzREluZGV4VG9Db29yZDp4MSxkZWZhdWx0U2NhbGU6WXMsZGVmYXVsdFVwOldzLGRpdmlkZVZlY3RvckFycmF5OklmLGVsbGlwc29pZF9nZXRMb2NhbEN1cnZhdHVyZTpXMCxlbGxpcHNvaWRfZ2V0TG9jYWxDdXJ2YXR1cmVSYWRpdXM6R3IsZWxsaXBzb2lkX2dldExvY2FsU2l6ZVBlckRlZ3JlZXM6WjAsZXF1YWxzRXBzaWxvbjpmcixmaWx0ZXJGYWNlQnlQb2x5Z29uUmVsYXRpb246bW8sZmlsdGVyR3JvdXBzOlBmLGZpbmRDb25jYXZlUG9pbnRJbmRleE9mUG9seWdvbjI6WmYsZmluZFRhbmdlbnRQb2ludE9mMkNvbnZleFBvbHlnb246R2YsZmxhdE51bWVyaWNBcnJheUFycmF5OlpzLGZyYW1lTG9vcDpSZixmcmVuZXRGcmFtZVRvRnJvbnRVcEZyYW1lOnBmLGZyb250VXBGcmFtZVRvRnJlbmV0RnJhbWU6X2YsZ2VuZXJhdGVGYWNlUmVsYXRpb25zT2ZHZW9tZXRyeV9Qb2x5Z29uOmZvLGdlbmVyYXRlUG9zaXRpb25SZWxhdGlvbnNPZkdlb21ldHJ5X0NvbnZleFBvbHlnb246aG8sZ2VuZXJhdGVQb3NpdGlvblJlbGF0aW9uc09mR2VvbWV0cnlfUG9seWdvbjpsbyxnZXRBeGlzUm90YXRpb25BbmdsZTpkZixnZXRBemltdXRoQW5nbGU6Z2YsZ2V0RGF0YTJESXRlbTp3YyxnZXREYXRhMkRJdGVtU2FmZTptMSxnZXREYXRhMkRSb3c6XzEsZ2V0RGF0YTJEVmFsdWU6QWMsZ2V0RGF0YTJEVmFsdWVTYWZlOnAxLGdldERhdGEzREl0ZW06UXIsZ2V0RGF0YTNESXRlbVNhZmU6TTEsZ2V0RGF0YTNEU2xpY2U6VDEsZ2V0RGF0YTNEVmFsdWU6S3IsZ2V0RGF0YTNEVmFsdWVTYWZlOncxLGdldER1cmF0aW9uT2ZQYXRoQW5pbWF0aW9uT3B0aW9uczpLcyxnZXRJbmNsdWRlZEFuZ2xlOnVyLGdldEtleWZyYW1lVHJhbnNmb3JtRGF0YXNCeVBvbHlsaW5lOkpzLGdldE1hdHJpeE9mUXVhbnRpemVkTWVzaFRlcnJhaW5EYXRhOnhyLGdldE1pbkFuZ2xlQmV0d2VlbkxpbmVzOm1mLGdldFBvbHlnb25SZWxhdGlvbkJ5QWdncmVnYXRlUG9zaXRpb25SZWxhdGlvbjpnbyxnZXRSb3RhdGlvbkFuZ2xlOm1lLGdldFNjYWxlT2ZRdWFudGl6ZWRNZXNoVGVycmFpbkRhdGE6TXIsZ2V0VHJhbnNmb3JtTWF0RnVuOnVlLGdldFZlY0Z1bnM6VSxnZXRWZWN0b3JDbGFzczp6aCxpVmVjdG9yVG9OdW1iZXJBcnJheTp4cyxpc0NvbnZleFBvbHlnb24yOnNvLGlzT3V0T2ZTaXplOnkxLGl2ZWN0b3JNZW1iZXJUb1ZlY3RvcjpnZSxpdmVjdG9yVG9WZWN0b3I6TXMsbG5nTGF0UmVjdGFuZ2xlX0hlaWdodDpYMCxsbmdMYXRSZWN0YW5nbGVfV2lkdGg6RzAsbG5nTGF0UmVjdGFuZ2xlX2NlbnRlcjppMSxsbmdMYXRSZWN0YW5nbGVfY29udGFpbnM6bDEsbG5nTGF0UmVjdGFuZ2xlX2Nvcm5lcnM6eGMsbG5nTGF0UmVjdGFuZ2xlX2VxdWFsczpIMCxsbmdMYXRSZWN0YW5nbGVfZXF1YWxzRXBzaWxvbjpKMCxsbmdMYXRSZWN0YW5nbGVfZXhwYW5kOmExLGxuZ0xhdFJlY3RhbmdsZV9mcm9tQ2FydGVzaWFuQXJyYXk6SzAsbG5nTGF0UmVjdGFuZ2xlX2Zyb21DYXJ0b2dyYXBoaWNBcnJheTpRMCxsbmdMYXRSZWN0YW5nbGVfZnJvbURlZ3JlZXM6ajAsbG5nTGF0UmVjdGFuZ2xlX2ludGVyc2VjdGlvbjpzMSxsbmdMYXRSZWN0YW5nbGVfbm9ydGhlYXN0Om4xLGxuZ0xhdFJlY3RhbmdsZV9ub3J0aHdlc3Q6ZTEsbG5nTGF0UmVjdGFuZ2xlX3NpbXBsZUludGVyc2VjdGlvbjpvMSxsbmdMYXRSZWN0YW5nbGVfc291dGhlYXN0OnIxLGxuZ0xhdFJlY3RhbmdsZV9zb3V0aHdlc3Q6dDEsbG5nTGF0UmVjdGFuZ2xlX3VuaW9uOmMxLG1hcEdyb3VwczpTZixtYXQzX2dldFNjYWxlOlVoLG1hdDNfbm9ybWFsTWF0cml4Om5yLG1hdDRfY29tcG9zZTpYaCxtYXQ0X2RlY29tcG9zZTpHaCxtYXQ0X2Zyb21NYXRyaXgzOlloLG1hdDRfZnJvbVNjYWxlUm90YXRpb246aXIsbWF0NF9nZXRTY2FsZTp2cyxtYXQ0X2dldFNjYWxlUm90YXRpb246cnIsbWF0NF9nZXRTY2FsZVJvdGF0aW9uTWF0cml4MzpFcyxtYXQ0X3NldFNjYWxlUm90YXRpb246WmgsbWF0NF9zZXRUcmFuc2xhdGlvbjpXaCxtYXRfZ2V0U2NhbGU6d3MsbWF0X3NldFRyYW5zbGF0aW9uOnFoLG1heExuZ0xhdFJlY3RhbmdsOmgxLG1lcmdlRGF0YTNEczpBMSxtdWx0aXBseVZlY3RvckFycmF5OmJmLG5lZ2F0aXZlUGlUb1BpOlp0LG5vcm1hbGl6ZVZlY3RvcnM6SmYsbnVtZXJpY0FycmF5VHlwZUNsYXNzTWFwOnlzLHBvc2l0aW9uTmFtZXNfZGVmYXVsdDpMZSxxdWF0X2FsaWduRnJlbmV0RnJhbWU6aHIscXVhdF9mcm9tRXVsZXI6dWYscXVhdF9yb3RhdGlvbkJldHdlZW5WZWN0b3JzQXJvdW5kQXhpczp6cyxyZWxhdGlvbk9mMjNMaW5lU2VnbWVudF9MaW5lU2VnbWVudDptcixyZWxhdGlvbk9mMjNSYXlfTGluZVNlZ21lbnQ6RmYscmVsYXRpb25PZjJDb252ZXhQb2x5Z29uX0NvbnZleFBvbHlnb246YW8scmVsYXRpb25PZjJDb252ZXhQb2x5Z29uX0xpbmVTZWdtZW50OnByLHJlbGF0aW9uT2YyQ29udmV4UG9seWdvbl9Qb2ludDpFdCxyZWxhdGlvbk9mMkxpbmVTZWdtZW50X1BvaW50OmVvLHJlbGF0aW9uT2YyUG9seWdvbl9DaXJjbGU6WGYscmVsYXRpb25PZjJQb2x5Z29uX0NvbnZleFBvbHlnb246Y28scmVsYXRpb25PZjJQb2x5Z29uX0xpbmVTZWdtZW50Om9vLHJlbGF0aW9uT2YyUG9seWdvbl9Qb2ludDpwdCxyZWxhdGlvbk9mMlBvbHlnb25fUG9seWdvbjpRZixyZWxhdGlvbk9mMlJheV9MaW5lU2VnbWVudDpubyxyZWxhdGlvbk9mTGluZVNlZ21lbnRfQ2lyY2xlOkhzLHJlbGF0aW9uT2ZMaW5lU2VnbWVudF9Qb2ludDprZixyZWxhdGlvbk9mTGluZV9DaXJjbGU6Q2YscmVsYXRpb25PZkxpbmVfTGluZTpsbixyZWxhdGlvbk9mTnVtYmVyUmFuZ2VzOllmLHJlbGF0aW9uT2ZSYXlfQ2lyY2xlOk5mLHNhZmVNb2Q6JHMsc2NhbGVBbmRBZGRWZWN0b3JBcnJheTp2ZixzY2FsZVZlY3RvckFycmF5OlRmLHNvcnRQb2ludHMyQ0NXOnJvLHN1YnRyYWN0VmVjdG9yQXJyYXk6T2YsdHJhbnNmb3JtVmVjdG9yQXJyYXk6QWYsdmVjMjNfYXJlYTpJcyx2ZWMyM19jcm9zczpqaCx2ZWMyM19pc0NvbGxpbmVhcjpRaCx2ZWMyM19zaWduQXJlYTpMcyx2ZWMyX2FyZWE6UHMsdmVjMl9pc0NvbGxpbmVhcjpicyx2ZWMyX3NpZ25BcmVhOld0LHZlYzJfdHJhbnNmb3JtTWF0NEFzVmVjdG9yOkxuLHZlYzNfYXJlYTpTcyx2ZWMzX2lzQ29sbGluZWFyOktoLHZlYzNfc2lnbkFyZWE6c3IsdmVjM190cmFuc2Zvcm1NYXQyOnBpLHZlYzNfdHJhbnNmb3JtTWF0NEFzVmVjdG9yOlJuLHZlYzRfdHJhbnNmb3JtTWF0MjpfaSx2ZWM0X3RyYW5zZm9ybU1hdDM6Q24sdmVjX2FkZDpDcyx2ZWNfY2VpbDp0Zix2ZWNfY29tcHV0ZVZlY3RvclNjYWxhcjpZLHZlY19kaXN0YW5jZTpWcyx2ZWNfZGl2aWRlOkhoLHZlY19kb3Q6b24sdmVjX2Zsb29yOmVmLHZlY19pbnZlcnNlOmFmLHZlY19pc0NvbGxpbmVhcjpzbix2ZWNfbGVuZ3RoOlJzLHZlY19sZXJwOmhmLHZlY19tYXg6cmYsdmVjX21pbjpuZix2ZWNfbXVsdGlwbHk6SmgsdmVjX25lZ2F0ZTpjZix2ZWNfbm9ybWFsaXplOmxmLHZlY19wcm9qZWN0T25QbGFuZTptdCx2ZWNfcHJvamVjdE9uVmVjdG9yOk9zLHZlY19yb3VuZDpvZix2ZWNfc2NhbGU6Y3IsdmVjX3NjYWxlQW5kQWRkOmFyLHZlY19zbGVycDpmZix2ZWNfc3F1YXJlZERpc3RhbmNlOk5zLHZlY19zcXVhcmVkTGVuZ3RoOmxyLHZlY19zdWJ0cmFjdDpUdCx2ZWNfdG9TYW1lRGlyZWN0b246b3Isd2hpY2hTaWRlT2YybGluZTp2dCx3aGljaFNpZGVPZjNsaW5lOiRmLHplcm9Ub1R3b1BpOmtzfSk7T2JqZWN0LmFzc2lnbihnbG9iYWxUaGlzLHYxKSxjb25zb2xlLmxvZygi5Yqo5oCBV29ya2Vy5bey5Yqg6L29OiBAd2ViLTNkL3Rvb2xzIil9KSgpOwo=",jn&&jn.tagName.toUpperCase()==="SCRIPT"&&jn.src||new URL("tools.iife.js",document.baseURI).href).href,{name:n?.name})}function YX(n="@web-3d/tools"){const t=new zX({name:n});return Bi(t)}const gX=YX();function bn(n,t,l){l=l??new r.Matrix4;const s=r.Matrix4.inverse(t,new r.Matrix4),e=r.Matrix4.multiply(n,s,s);return r.Matrix4.multiply(t,e,l)}function MX(n,t,l,s){s=s??new r.Matrix4;const e=r.Matrix4.inverse(l,new r.Matrix4);let d=r.Matrix4.multiply(e,n,e);return d=r.Matrix4.multiply(t,d,d),r.Matrix4.multiply(l,d,s)}function TX(n,t,l){const s=r.Matrix4.fromTranslation(n);return bn(s,t,l)}function fX(n,t,l,s){const e=r.Quaternion.fromAxisAngle(n,t),d=r.Matrix3.fromQuaternion(e),i=r.Matrix4.fromRotation(d);return bn(i,l,s)}function CX(n,t,l){const s=r.Matrix4.fromScale(n);return bn(s,t,l)}function FX(n,t,l){const s=r.Matrix3.fromScale(t);if(l)for(const e of n)r.Cartesian3.subtract(e,l,e),r.Matrix3.multiplyByVector(s,e,e),r.Cartesian3.add(e,l,e);else{const e=r.Matrix3.fromScale(t);for(const d of n)r.Matrix3.multiplyByVector(e,d,d)}return n}function NX(n,t){const{translation:l,rotation:s,scale:e}=n;let d;if(s){const{axis:c,angle:o}=s;d=r.Quaternion.fromAxisAngle(c,o)}const i=new r.TranslationRotationScale(l??void 0,d,e??void 0);return r.Matrix4.fromTranslationRotationScale(i,t??void 0)}function jd(n,t){t??=new r.TranslationRotationScale;const l=r.Matrix4.pack(n,[]),s=[],e=[],d=[];return _a(s,e,d,l),r.Cartesian3.unpack(s,0,t.translation),r.Cartesian3.unpack(e,0,t.scale),r.Quaternion.unpack(d,0,t.rotation),t}const Ed=r.Matrix4.fromTranslationRotationScale;function Od(n){const t=r.Matrix4.inverse(n,new r.Matrix4),l=new r.Matrix4;function s(d,i){return i=Ed(d,i),r.Matrix4.multiply(n,i,i)}function e(d,i){return r.Matrix4.multiply(t,d,l),jd(l,i)}return{compose:s,decompose:e,referInverse:t}}function HX(n,t){const l=r.Transforms.eastNorthUpToFixedFrame(n,t??void 0);return{...Od(l),refer:l}}function JX(n){let t=n.boundingSphere;if(t)return t;let l=n.geometryInstances;if(l){l=Array.isArray(l)?l:[l];const e=l.map(d=>d.geometry.boundingSphere);return r.BoundingSphere.fromBoundingSpheres(e)}const s=n.positions;return s?.length>0?r.BoundingSphere.fromPoints(s):null}function IX(n,t){t=t??new r.Cartesian3;const l=n.position;if(l)return l instanceof r.Cartesian3?l:l.getValue(r.JulianDate.now(),t);const s=n.modelMatrix;if(s)return r.Matrix4.getTranslation(s,t);const e=n.positions;return e?.length>0?r.BoundingSphere.fromPoints(e).center:null}function kX(n,t,l){let{translation:s,rotation:e,scale:d}=un(t,l);const i=new r.TranslationRotationScale(s??void 0,e??void 0,d??void 0),c=r.Matrix4.fromTranslationRotationScale(i);return Dd(n,c)}function Dd(n,t){const l=n.modelMatrix;if(l)return r.Matrix4.multiply(t,l,l),n.modelMatrix=l,!0;const s=n.position;if(s){if("scale"in n){const d=r.Matrix4.getTranslation(t,new r.Cartesian3);r.Cartesian3.add(s,d,s);const i=n.scale??1,c=r.Matrix4.getScale(t,new r.Cartesian3);n.scale=r.Cartesian3.maximumComponent(c)*i}else r.Matrix4.multiplyByPoint(t,s,s);return n.position=s,!0}const e=n.positions;if(e?.length>0){for(const d of e)r.Matrix4.multiplyByPoint(t,d,d);return n.positions=e,!0}return!1}function PX(n,t,l){const s=_d(n),e=as(t,{...l,defaultMatrix:s});return Ad(n,e)}function Ad(n,t){if(an(n))return n.modelMatrix=t,!0;const l=r.Matrix4.getTranslation(t,new r.Cartesian3);if(Xn(n)){if(n.position=l,"scale"in n){const e=r.Matrix4.getScale(t,new r.Cartesian3);n.scale=r.Cartesian3.maximumComponent(e)}return!0}const s=n.positions;if(s?.length>0){const e=r.BoundingSphere.fromPoints(s);r.Cartesian3.subtract(l,e.center,l);for(const d of s)r.Cartesian3.add(d,l,d);return n.positions=s,!0}return!1}function _d(n){if(an(n))return n.modelMatrix;if(Xn(n)){const l=n.position,s=n.scale??1,e=new r.TranslationRotationScale(l,void 0,new r.Cartesian3(s,s,s));return r.Matrix4.fromTranslationRotationScale(e)}const t=n.positions;if(t?.length>0){const l=r.BoundingSphere.fromPoints(t);return r.Matrix4.fromTranslation(l.center)}return null}function QX(n,t){let{translation:l,rotation:s,scale:e}=un(t,t);const{reset:d,referFrame:i}=t,c=r.JulianDate.now(),o=!d;if(s){let V=s;if(o){const y=n.orientation?.getValue(c);y&&(V=r.Quaternion.multiply(s,y,y))}n.orientation=V}if(l){let V=l;if(o){const y=n.position?.getValue(c);y&&(V=r.Cartesian3.add(y,l,y))}n.position=V}if(!i)return;const{translation:a,rotation:X,scale:u}=os(t,t),h=new r.TranslationRotationScale(a??void 0,X??void 0,u??void 0);let m=r.Matrix4.fromTranslationRotationScale(h);if(m=bn(m,i,m),u){const V=n.box;V&&qd(V,u);const y=n.cylinder;y&&$d(y,u);const S=n.ellipse;S&&ti(S,u);const R=n.ellipsoid;R&&ni(R,u);const T=n.model;T&&li(T,u,d);const g=n.plane;g&&si(g,u)}const Z=n.corridor;Z&&ei(Z,m,u);const p=n.polygon;p&&di(p,m,u);const G=n.polyline;G&&ii(G,m,u);const W=n.polylineVolume;W&&ci(W,m,u);const L=n.wall;L&&bi(L,m,u)}function qd(n,t){const l=r.JulianDate.now(),s=n.dimensions?.getValue(l);s&&(n.dimensions=r.Cartesian3.multiplyComponents(s,t,s))}function $d(n,t){const l=r.JulianDate.now(),s=n.length?.getValue(l);s!=null&&(n.length=s*t.z);const e=Math.max(t.x,t.y),d=n.topRadius?.getValue(l);d!=null&&(n.topRadius=d*e);const i=t.z,c=n.bottomRadius?.getValue(l);c!=null&&(n.bottomRadius=c*i)}function ti(n,t){const l=r.JulianDate.now(),s=Math.max(t.x,t.y),e=t.z,d=n.semiMajorAxis?.getValue(l);d!=null&&(n.semiMajorAxis=d*s);const i=n.semiMinorAxis?.getValue(l);i!=null&&(n.semiMinorAxis=i*s);const c=n.height?.getValue(l);c!=null&&(n.height=c*e);const o=n.extrudedHeight?.getValue(l);o!=null&&(n.extrudedHeight=o*e)}function ni(n,t){const l=r.JulianDate.now(),s=n.radii?.getValue(l);s!=null&&(n.radii=r.Cartesian3.multiplyComponents(s,t,s));const e=n.innerRadii?.getValue(l);e!=null&&(n.innerRadii=r.Cartesian3.multiplyComponents(e,t,e))}function li(n,t,l){let s=r.Cartesian3.maximumComponent(t);if(!l){const e=r.JulianDate.now(),d=n.scale?.getValue(e)??1;s*=d}n.scale=s}function si(n,t){const l=r.JulianDate.now(),s=r.Cartesian2.fromCartesian3(t),e=n.dimensions?.getValue(l);e&&(n.dimensions=r.Cartesian2.multiplyComponents(e,s,e))}function ei(n,t,l){const s=r.JulianDate.now(),e=new r.Cartesian3,d=n.positions?.getValue(s);if(d?.length>0){for(const u of d)r.Matrix4.multiplyByPoint(t,u,u);n.dimensions=d}const i=l??r.Matrix4.getScale(t,e),c=Math.max(i.x,i.y);n.width?.getValue(s)!=null&&(n.width=c*scale);const a=n.height?.getValue(s),X=i.z;a!=null&&(n.height=a*X)}function di(n,t,l){const s=r.JulianDate.now(),e=new r.Cartesian3,d=n.hierarchy?.getValue(s);d&&(ql(d,t),n.hierarchy=d);const c=(l??r.Matrix4.getScale(t,e)).z,o=n.height?.getValue(s);o!=null&&(n.height=o*c);const a=n.extrudedHeight?.getValue(s);a!=null&&(n.extrudedHeight=a*c)}function ql(n,t){const{positions:l,holes:s}=n;for(const e of l)r.Matrix4.multiplyByPoint(t,e,e);n.positions=l;for(const e of s)ql(e,t)}function ii(n,t,l){const s=r.JulianDate.now(),e=new r.Cartesian3,d=n.positions?.getValue(s);if(d?.length>0){for(const a of d)r.Matrix4.multiplyByPoint(t,a,a);n.positions=d}const i=l??r.Matrix4.getScale(t,e),c=Math.max(i.x,i.y);n.width?.getValue(s)!=null&&(n.width=c*scale)}function ci(n,t,l){const s=r.JulianDate.now(),e=new r.Cartesian3,d=n.positions?.getValue(s);if(d?.length>0){for(const a of d)r.Matrix4.multiplyByPoint(t,a,a);n.positions=d}const i=l??r.Matrix4.getScale(t,e),c=r.Cartesian2.fromCartesian3(i),o=n.shape?.getValue(s);if(o!=null){for(const a of o)r.Cartesian2.multiplyComponents(a,c,a);n.shape=o}}function bi(n,t,l){const s=r.JulianDate.now(),e=new r.Cartesian3,d=n.positions?.getValue(s);if(d?.length>0){for(const X of d)r.Matrix4.multiplyByPoint(t,X,X);n.positions=d}const c=(l??r.Matrix4.getScale(t,e)).z,o=n.minimumHeights?.getValue(s);o!=null&&(graphicsgraphics.minimumHeights=o.map(X=>X*c));const a=n.maximumHeights?.getValue(s);a!=null&&(graphicsgraphics.maximumHeights=a.map(X=>X*c))}function vX(n,t,l){const s=r.JulianDate.now(),e=n.position?.getValue(s);if(!e)return null;const d=n.orientation?.getValue(s),i=n.model?.scale?.getValue(s)??1,c=new r.Cartesian3(i,i,i),o=t(e,l),a=r.Matrix4.inverse(o,new r.Matrix4),X=r.Matrix4.multiplyByPoint(a,e,new r.Cartesian3),u={translation:X,position:e,scale:c,rotation:new r.Cartesian3};let h;if(d){const p=r.Matrix3.fromQuaternion(d),G=r.Matrix4.fromRotation(p),W=r.Matrix4.multiply(a,G,G),L=On(W);h=K.Xyz_Hpr.toCartesian3(L),u.rotation=h}const m=new r.TranslationRotationScale(X??void 0,h?Bt(h):void 0,c??void 0);let Z=r.Matrix4.fromTranslationRotationScale(m);return u.matrix=Z,u}function BX(n){return n.values.length/n.componentsPerAttribute}function wX(n){return r.ComponentDatatype.getSizeInBytes(n.componentDatatype)*n.componentsPerAttribute}function UX(n){const{componentDatatype:t,vertexBuffer:l}=n,s=ds[t];if(!s)throw new Error("不支持的数据类型");const e=l.sizeInBytes,d=r.ComponentDatatype.getSizeInBytes(t),i=e/d;let c=new s(i);return l.getBufferData(c,0,0,e),c}new r.Cartesian2,new r.Cartesian3,new r.Cartesian4;const $l=[new r.Cartesian2,new r.Cartesian2,new r.Cartesian2,new r.Cartesian2],Bn=[new r.Cartesian3,new r.Cartesian3,new r.Cartesian3,new r.Cartesian3];new r.Cartesian4,new r.Cartesian4,new r.Cartesian4,new r.Cartesian4;const jX=[new r.Cartographic,new r.Cartographic,new r.Cartographic,new r.Cartographic];new r.Rectangle,new r.Rectangle,new r.Rectangle,new r.Rectangle,new r.Matrix2,new r.Matrix2,new r.Matrix2,new r.Matrix2,new r.Matrix3,new r.Matrix3,new r.Matrix3,new r.Matrix3,new r.Matrix4,new r.Matrix4,new r.Matrix4,new r.Matrix4,new r.Quaternion,new r.Quaternion,new r.Quaternion,new r.Quaternion,new r.HeadingPitchRoll,new r.HeadingPitchRoll,new r.HeadingPitchRoll,new r.HeadingPitchRoll;function EX(n,t=[]){const{stride:l,vertexArray:s}=n,e=s.length/l,d=Bn[0];for(let i=0;i<e;i++)n.encoding.decodePosition(s,i,d),r.Cartesian3.pack(d,t,t.length);return t}function OX(n,t,l){return n.encoding.decodePosition(n.vertexArray,t,l)}function oi(n){const{stride:t,vertices:l,indices:s,encoding:e}=n,d=l.length/t,i=Bn[0],c=new Float32Array(d*3),o=$l[0],a=new Float32Array(d*2),X=new Float32Array(d);for(let u=0;u<d;u++){e.decodePosition(l,u,i),r.Cartesian3.pack(i,c,u*3);const h=e.decodeHeight(l,u);X[u]=h,e.decodeTextureCoordinates(l,u,o),r.Cartesian2.pack(o,a,u*2)}return{attributes:{position:{array:c,vectorSize:3},uv:{array:a,vectorSize:2},height:{array:X,vectorSize:1}},indices:s.slice(),count:d}}function ts(n,t){const l=n._surface._tilesToRender,s=[],e=new r.Rectangle;for(const d of l){const{rectangle:i}=d;r.Rectangle.intersection(t,i,e)&&s.push(d)}return s}function DX(n){const t=n._surface._tilesToRender;return ai(t)}function ai(n){const t=new Set;for(const d of n)t.add(d.level);const l=[...t],s=Math.min.apply(Math,l),e=Math.max.apply(Math,l);return{min:s,max:e}}function ns(n){return n.map(t=>{const{mesh:l,terrainData:s}=t.data,e=oi(l),{x:d,y:i,level:c}=t,o=[s._minimumHeight,s._maximumHeight];return{data:e,encoding:l.encoding,rectangle:t.rectangle,heightRange:o,x:d,y:i,level:c}})}function AX(n){const{x:t,y:l,level:s}=n;return n.data.terrainData.upsample(n.tilingScheme,t,l,s,t,l,s)}function Xi(n,t,l){const{east:s,north:e,south:d,west:i}=t,c=jX[0];c.longitude=i,c.latitude=d;const o=n.positionToTileXY(c,l,$l[0]);c.longitude=s,c.latitude=e;const a=n.positionToTileXY(c,l,$l[1]),[X,u]=o.x<a.x?[o.x,a.x]:[a.x,o.x],[h,m]=o.y<a.y?[o.y,a.y]:[a.y,o.y];return{min:[X,h],max:[u,m]}}const _X=32767;function qX(n,t=new r.Cartesian3){return r.Matrix3.getScale(n.halfAxes,t),r.Cartesian3.multiplyByScalar(t,2*_X,t),t}function wn(n,t,l){return l=n.getLocalCurvature(t,l),l.x=1/l.x,l.y=1/l.y,l}function $X(n,t,l){l=wn(n,t,l);const s=Math.PI/180;return r.Cartesian2.multiplyByScalar(l,s,l)}function ui(n){const{_quantizedVertices:t,_indices:l}=n,s=t.length/3,e={type:"Float32Array",start:0,vectorSize:1},d={type:"Float32Array",start:s,vectorSize:1},i={type:"Float32Array",start:s*2,vectorSize:1};return{array:new Float32Array(t),attributes:{u:e,v:d,height:i},count:s,indices:l}}async function tu(n,t,l,s){const e=await n.requestTileGeometry(t,l,s);if(!e)return null;const d=ui(e),i=[data._minimumHeight,data._maximumHeight],c=n.tilingScheme.tileXYToRectangle(t,l,s),o=Qd(c,i),a=r.Matrix4.fromArray(o,void 0),X=["u","v","height"],u=new Nd({...d,positionNames:X}),h=new r.Cartesian3;return u.mapForAggregate(X,(m,Z)=>(r.Cartesian3.fromArray(m,0,h),r.Matrix4.multiplyByPoint(a,h,h),new r.Cartographic(h.x,h.y,h.z)))}async function nu(n,t,l){const{min:s,max:e}=Xi(n.tilingScheme,t,l),d=[],i=[];for(let o=s[0];o<=e[0];o++)for(let a=s[1];a<=e[1];a++){const X=ri(n,o,a,l);X&&(d.push(X),i.push({x:o,y:a}))}return(await Promise.all(d)).map(function(o,a){const{x:X,y:u}=i[a];return{x:X,y:u,level:l,data:o}})}async function ri(n,t,l,s){return n.getTileDataAvailable(t,l,s)?(await n.loadTileDataAvailability(t,l,s),n.requestTileGeometry(t,l,s)):Promise.reject("不可用")}async function lu(n,t){const l=r.Rectangle.fromCartesianArray(t),s=r.Cartographic.toCartesian(r.Rectangle.center(l)),e=wn(n.ellipsoid,s),d=[e.x,e.y,1],i=ts(n,l),c=ns(i),o=r.Transforms.eastNorthUpToFixedFrame(s);r.Matrix4.inverseTransformation(o,o);const a=t.map(h=>{const m=r.Matrix4.multiplyByPoint(o,h,Bn[2]);return[m.x,m.y]});let X=0;const u=c.map(async h=>{const{data:m,...Z}=h,{position:p,uv:G,height:W}=m.attributes;X+=await gX.computeRelationAreaOfPolygon2Terrain({args:[{...m,...Z,positionNames:["position"],region:a,matrix:r.Matrix4.pack(o,[]),relation:x.Contain|x.Intersect,scale:d}],transfer:[p.array.buffer,G.array.buffer,W.array.buffer,m.indices.buffer]})});if(await Promise.all(u),X===0||isNaN(X)){console.warn("贴地面积计算异常,已回退到椭球面投影面积",X);const h=t.map(m=>r.Cartesian3.pack(m,[]));return X=vd(h),Math.abs(X)}return X}function su(n,t){const l=r.Rectangle.fromCartesianArray(t),s=r.Cartographic.toCartesian(r.Rectangle.center(l)),e=wn(n.ellipsoid,s),d=[e.x,e.y,1],i=ts(n,l),c=ns(i),o=r.Transforms.eastNorthUpToFixedFrame(s);r.Matrix4.inverseTransformation(o,o);const a=t.map(u=>{const h=r.Matrix4.multiplyByPoint(o,u,Bn[2]);return[h.x,h.y]});let X=0;for(const u of c){const{data:h,...m}=u;X+=SX({...h,...m,positionNames:["position"],region:a,matrix:r.Matrix4.pack(o,[]),relation:x.Contain|x.Intersect,scale:d})}if(X===0||isNaN(X)){console.warn("贴地面积计算异常,已回退到椭球面投影面积",X);const u=t.map(h=>r.Cartesian3.pack(h,[]));return X=vd(u),Math.abs(X)}return X}return K.CartesianAxis=is,K.HeadingPitchRollComponent=cs,K.applyMatrixReferFrame=MX,K.applyTransformInPrimitive=Dd,K.applyTransformInfoPrimitive=kX,K.componentDatatypeTypedArrayMap=ds,K.computeAttributeSizeInBytes=wX,K.computeNormalOfCoplanars=Xs,K.computeTerrainAreaOfPolygon=su,K.computeTerrainAreaOfPolygon_worker=lu,K.computeVertexNumOfAttribute=BX,K.createPlaneOfCoplanars=Li,K.flatTransformInfoOptions=En,K.getAttributeData=UX,K.getBoundingSphere=JX,K.getDecodePositionsOfTerrainMesh=EX,K.getEntityInfo=vX,K.getGeometryDataOfQuantizedMeshTerrainData=ui,K.getGeometryDataOfTerrainMesh=oi,K.getLevelRangeOfQuadtreeTiles=ai,K.getLocalCurvatureRadius=wn,K.getLocalSizePerDegrees=$X,K.getLocalTransformInfo=os,K.getMatrix4OfTransformInfo=NX,K.getNeighborPairs=xi,K.getPosition=IX,K.getPositionOfTerrainMesh=OX,K.getRenderedQuadtreeTilesOfIntersectRectangle=ts,K.getRenderedTileLevelRange=DX,K.getScaleOfTerrainDataByOrientedBoundingBox=qX,K.getTerrainData=ri,K.getTerrainDataOfQuadtreeTile=AX,K.getTerrainDatasOfIntersectRectangle=nu,K.getTerrainDatasOfQuadtreeTiles=ns,K.getTileRangeOfIntersectRectangle=Xi,K.getTransform=_d,K.getWorldDataOfQuantizedMeshTerrainData=tu,K.getWorldMatrix=as,K.getWorldTransformInfo=un,K.isMatrixPrimitive=an,K.isPositionListPrimitive=es,K.isPositionPrimitive=Xn,K.isPrimitiveObject=Gi,K.localQuaternionToWorld=bs,K.localTRS_WorldMatrix4_Convert=Od,K.localTRS_WorldMatrix4_ENU_Convert=HX,K.makeMatrixReferFrame=bn,K.mat4_compose=Ed,K.mat4_decompose=jd,K.matrix4ToHeadingPitchRoll=On,K.quaternionToHeadingPitchRoll=pi,K.resetTransformInPrimitive=Ad,K.resetTransformInfoPrimitive=PX,K.rotateMatrixReferFrame=fX,K.rotationInfoToQuaternion=Bt,K.scaleBoxGraphics=qd,K.scaleCylinderGraphics=$d,K.scaleEllipseGraphics=ti,K.scaleEllipsoidGraphics=ni,K.scaleMatrixReferFrame=CX,K.scaleModelGraphics=li,K.scalePlaneGraphics=si,K.scalePoints=FX,K.transformCorridorGraphics=ei,K.transformEntity=QX,K.transformInfoToMatrix=yi,K.transformPolygonGraphics=di,K.transformPolygonHierarchy=ql,K.transformPolylineGraphics=ii,K.transformPolylineVolumeGraphics=ci,K.transformWallGraphics=bi,K.translationMatrixReferFrame=TX,K.worldMatrixToLocal=Wi,K.worldQuaternionToLocal=Vi,Object.defineProperty(K,Symbol.toStringTag,{value:"Module"}),K}({},cesium);
|
|
27
|
+
</path>`,l}};b.Polygon=an;const fX=(...n)=>new b.Polygon(...n);b.polygon=fX;const{Circle:ql,Line:Cd,Point:fd,Vector:wn,Utils:_l}=b;class un{constructor(t){this.circle=t}get inversion_circle(){return this.circle}static inversePoint(t,l){const s=new wn(t.pc,l),e=t.r*t.r,d=s.dot(s);return _l.EQ_0(d)?new fd(Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY):t.pc.translate(s.multiply(e/d))}static inverseCircle(t,l){const s=t.pc.distanceTo(l.pc)[0];if(_l.EQ(s,l.r)){let e=t.r*t.r/(2*l.r),d=new wn(t.pc,l.pc);d=d.normalize();let i=t.pc.translate(d.multiply(e));return new Cd(i,d)}else{let e=new wn(t.pc,l.pc),d=t.r*t.r/(e.dot(e)-l.r*l.r),i=t.pc.translate(e.multiply(d)),c=Math.abs(d)*l.r;return new ql(i,c)}}static inverseLine(t,l){const[s,e]=t.pc.distanceTo(l);if(_l.EQ_0(s))return l.clone();{let d=t.r*t.r/(2*s),i=new wn(t.pc,e.end);return i=i.multiply(d/s),new ql(t.pc.translate(i),d)}}inverse(t){if(t instanceof fd)return un.inversePoint(this.circle,t);if(t instanceof ql)return un.inverseCircle(this.circle,t);if(t instanceof Cd)return un.inverseLine(this.circle,t)}}b.Inversion=un;const FX=n=>new b.Inversion(n);b.inversion=FX;class M{static point2point(t,l){return t.distanceTo(l)}static point2line(t,l){let s=t.projectionOn(l);return[new b.Vector(t,s).length,new b.Segment(t,s)]}static point2circle(t,l){let[s,e]=t.distanceTo(l.center);if(b.Utils.EQ_0(s))return[l.r,new b.Segment(t,l.toArc().start)];{let d=Math.abs(s-l.r),i=new b.Vector(l.pc,t).normalize().multiply(l.r),c=l.pc.translate(i);return[d,new b.Segment(t,c)]}}static point2segment(t,l){if(l.start.equalTo(l.end))return M.point2point(t,l.start);let s=new b.Vector(l.start,l.end),e=new b.Vector(l.start,t),d=new b.Vector(l.end,t),i=s.dot(e),c=-s.dot(d),o,X;if(b.Utils.GE(i,0)&&b.Utils.GE(c,0)){let a=l.tangentInStart();return o=Math.abs(a.cross(e)),X=l.start.translate(a.multiply(a.dot(e))),[o,new b.Segment(t,X)]}else return i<0?t.distanceTo(l.start):t.distanceTo(l.end)}static point2arc(t,l){let s=new b.Circle(l.pc,l.r),e=[],d,i;return[d,i]=M.point2circle(t,s),i.end.on(l)&&e.push(M.point2circle(t,s)),e.push(M.point2point(t,l.start)),e.push(M.point2point(t,l.end)),M.sort(e),e[0]}static point2edge(t,l){return l.shape instanceof b.Segment?M.point2segment(t,l.shape):M.point2arc(t,l.shape)}static segment2line(t,l){let s=t.intersect(l);if(s.length>0)return[0,new b.Segment(s[0],s[0])];let e=[];return e.push(M.point2line(t.start,l)),e.push(M.point2line(t.end,l)),M.sort(e),e[0]}static segment2segment(t,l){let s=kn(t,l);if(s.length>0)return[0,new b.Segment(s[0],s[0])];let e=[],d,i;return[d,i]=M.point2segment(l.start,t),e.push([d,i.reverse()]),[d,i]=M.point2segment(l.end,t),e.push([d,i.reverse()]),e.push(M.point2segment(t.start,l)),e.push(M.point2segment(t.end,l)),M.sort(e),e[0]}static segment2circle(t,l){let s=t.intersect(l);if(s.length>0)return[0,new b.Segment(s[0],s[0])];let e=new b.Line(t.ps,t.pe),[d,i]=M.point2line(l.center,e);if(b.Utils.GE(d,l.r)&&i.end.on(t))return M.point2circle(i.end,l);{let[c,o]=M.point2circle(t.start,l),[X,a]=M.point2circle(t.end,l);return b.Utils.LT(c,X)?[c,o]:[X,a]}}static segment2arc(t,l){let s=t.intersect(l);if(s.length>0)return[0,new b.Segment(s[0],s[0])];let e=new b.Line(t.ps,t.pe),d=new b.Circle(l.pc,l.r),[i,c]=M.point2line(d.center,e);if(b.Utils.GE(i,d.r)&&c.end.on(t)){let[u,r]=M.point2circle(c.end,d);if(r.end.on(l))return[u,r]}let o=[];o.push(M.point2arc(t.start,l)),o.push(M.point2arc(t.end,l));let X,a;return[X,a]=M.point2segment(l.start,t),o.push([X,a.reverse()]),[X,a]=M.point2segment(l.end,t),o.push([X,a.reverse()]),M.sort(o),o[0]}static circle2circle(t,l){let s=t.intersect(l);if(s.length>0)return[0,new b.Segment(s[0],s[0])];if(t.center.equalTo(l.center)){let e=t.toArc(),d=l.toArc();return M.point2point(e.start,d.start)}else{let e=new b.Line(t.center,l.center),d=e.intersect(t),i=e.intersect(l),c=[];return c.push(M.point2point(d[0],i[0])),c.push(M.point2point(d[0],i[1])),c.push(M.point2point(d[1],i[0])),c.push(M.point2point(d[1],i[1])),M.sort(c),c[0]}}static circle2line(t,l){let s=t.intersect(l);if(s.length>0)return[0,new b.Segment(s[0],s[0])];let[e,d]=M.point2line(t.center,l),[i,c]=M.point2circle(d.end,t);return c=c.reverse(),[i,c]}static arc2line(t,l){let s=l.intersect(t);if(s.length>0)return[0,new b.Segment(s[0],s[0])];let e=new b.Circle(t.center,t.r),[d,i]=M.point2line(e.center,l);if(b.Utils.GE(d,e.r)){let[c,o]=M.point2circle(i.end,e);if(o.end.on(t))return[c,o]}else{let c=[];return c.push(M.point2line(t.start,l)),c.push(M.point2line(t.end,l)),M.sort(c),c[0]}}static arc2circle(t,l){let s=t.intersect(l);if(s.length>0)return[0,new b.Segment(s[0],s[0])];let e=new b.Circle(t.center,t.r),[d,i]=M.circle2circle(e,l);if(i.start.on(t))return[d,i];{let c=[];return c.push(M.point2circle(t.start,l)),c.push(M.point2circle(t.end,l)),M.sort(c),c[0]}}static arc2arc(t,l){let s=t.intersect(l);if(s.length>0)return[0,new b.Segment(s[0],s[0])];let e=new b.Circle(t.center,t.r),d=new b.Circle(l.center,l.r),[i,c]=M.circle2circle(e,d);if(c.start.on(t)&&c.end.on(l))return[i,c];{let o=[],X,a;return[X,a]=M.point2arc(t.start,l),a.end.on(l)&&o.push([X,a]),[X,a]=M.point2arc(t.end,l),a.end.on(l)&&o.push([X,a]),[X,a]=M.point2arc(l.start,t),a.end.on(t)&&o.push([X,a.reverse()]),[X,a]=M.point2arc(l.end,t),a.end.on(t)&&o.push([X,a.reverse()]),[X,a]=M.point2point(t.start,l.start),o.push([X,a]),[X,a]=M.point2point(t.start,l.end),o.push([X,a]),[X,a]=M.point2point(t.end,l.start),o.push([X,a]),[X,a]=M.point2point(t.end,l.end),o.push([X,a]),M.sort(o),o[0]}}static point2polygon(t,l){let s=[Number.POSITIVE_INFINITY,new b.Segment];for(let e of l.edges){let[d,i]=M.point2edge(t,e);b.Utils.LT(d,s[0])&&(s=[d,i])}return s}static shape2polygon(t,l){let s=[Number.POSITIVE_INFINITY,new b.Segment];for(let e of l.edges){let[d,i]=t.distanceTo(e.shape);b.Utils.LT(d,s[0])&&(s=[d,i])}return s}static polygon2polygon(t,l){let s=[Number.POSITIVE_INFINITY,new b.Segment];for(let e of t.edges)for(let d of l.edges){let[i,c]=e.shape.distanceTo(d.shape);b.Utils.LT(i,s[0])&&(s=[i,c])}return s}static box2box_minmax(t,l){let s=Math.max(Math.max(t.xmin-l.xmax,0),Math.max(l.xmin-t.xmax,0)),e=Math.max(Math.max(t.ymin-l.ymax,0),Math.max(l.ymin-t.ymax,0)),d=s*s+e*e,i=t.merge(l),c=i.xmax-i.xmin,o=i.ymax-i.ymin,X=c*c+o*o;return[d,X]}static minmax_tree_process_level(t,l,s,e){let d,i;for(let a of l){[d,i]=M.box2box_minmax(t.box,a.item.key);for(let u of a.item.values)u instanceof b.Edge?e.insert([d,i],u.shape):e.insert([d,i],u);b.Utils.LT(i,s)&&(s=i)}if(l.length===0)return s;let c=l.map(a=>a.left.isNil()?void 0:a.left).filter(a=>a!==void 0),o=l.map(a=>a.right.isNil()?void 0:a.right).filter(a=>a!==void 0),X=[...c,...o].filter(a=>{let[u,r]=M.box2box_minmax(t.box,a.max);return b.Utils.LE(u,s)});return s=M.minmax_tree_process_level(t,X,s,e),s}static minmax_tree(t,l,s){let e=new on,d=[l.index.root],i=s<Number.POSITIVE_INFINITY?s*s:Number.POSITIVE_INFINITY;return i=M.minmax_tree_process_level(t,d,i,e),e}static minmax_tree_calc_distance(t,l,s){let e,d;if(l!=null&&!l.isNil()){if([e,d]=M.minmax_tree_calc_distance(t,l.left,s),d)return[e,d];if(b.Utils.LT(e[0],Math.sqrt(l.item.key.low)))return[e,!0];let[i,c]=M.distanceToArray(t,l.item.values);return b.Utils.LT(i,e[0])&&(e=[i,c]),[e,d]=M.minmax_tree_calc_distance(t,l.right,e),[e,d]}return[s,!1]}static shape2planarSet(t,l,s=Number.POSITIVE_INFINITY){let e=[s,new b.Segment],d=!1;if(l instanceof b.PlanarSet){let i=M.minmax_tree(t,l,s);[e,d]=M.minmax_tree_calc_distance(t,i.root,e)}return e}static sort(t){t.sort((l,s)=>b.Utils.LT(l[0],s[0])?-1:b.Utils.GT(l[0],s[0])?1:0)}static distance(t,l){return t.distanceTo(l)}static distanceToArray(t,l){let s=[Number.POSITIVE_INFINITY,new b.Segment];for(let e of l){let[d,i]=t.distanceTo(e);b.Utils.LT(d,s[0])&&(s=[d,i])}return s}static shape2multiline(t,l){let s=[Number.POSITIVE_INFINITY,new b.Segment];for(let e of l){let[d,i]=M.distance(t,e.shape);b.Utils.LT(d,s[0])&&(s=[d,i])}return s}static multiline2multiline(t,l){let s=[Number.POSITIVE_INFINITY,new b.Segment];for(let e of t)for(let d of l){let[i,c]=M.distance(e.shape,d.shape);b.Utils.LT(i,s[0])&&(s=[i,c])}return s}}b.Distance=M;const{Multiline:NX,Point:Fd,Segment:HX,Polygon:Nd}=b;function $l(n){return new Fd(n.split(" ").map(Number))}function Hd(n){return n.split(", ").map($l)}function ts(n){const t=Hd(n);let l=[];for(let s=0;s<t.length-1;s++)l.push(new HX(t[s],t[s+1]));return new NX(l)}function JX(n){return n.replace(/\(\(/,"").replace(/\)\)$/,"").split("), (").map(ts)}function Jd(n){const t=n.replace(/\(\(/,"").replace(/\)\)$/,"").split("), ("),l=new Nd;let s;return t.forEach((e,d)=>{let i=e.split(", ").map(o=>new Fd(o.split(" ").map(Number)));const c=l.addFace(i);d===0?s=c.orientation():c.orientation()===s&&c.reverse()}),l}function IX(n){const l=n.split(/\)\), \(\(/).map(d=>"(("+d+"))").map(Jd),s=new Nd;return l.reduce((d,i)=>[...d,...i?.faces],[]).forEach(d=>s.addFace([...d?.shapes])),s}function kX(n){if(n.startsWith("POLYGON")){const t=n.replace(/^POLYGON /,"");return Jd(t)}else{const t=n.replace(/^MULTIPOLYGON \(\(\((.*)\)\)\)$/,"$1");return IX(t)}}function PX(n){return n.split(`
|
|
28
|
+
`).map(l=>l.match(/\(([^)]+)\)/)[1]).map($l)}function QX(n){return n.split(`
|
|
29
|
+
`).map(l=>l.match(/\(([^)]+)\)/)[1]).map(ts).reduce((l,s)=>[...l,...s],[])}function Id(n){if(n.startsWith("POINT")){const t=n.replace(/^POINT \(/,"").replace(/\)$/,"");return $l(t)}else if(n.startsWith("MULTIPOINT")){const t=n.replace(/^MULTIPOINT \(/,"").replace(/\)$/,"");return Hd(t)}else if(n.startsWith("LINESTRING")){const t=n.replace(/^LINESTRING \(/,"").replace(/\)$/,"");return ts(t)}else if(n.startsWith("MULTILINESTRING")){const t=n.replace(/^MULTILINESTRING /,"");return JX(t)}else{if(n.startsWith("POLYGON")||n.startsWith("MULTIPOLYGON"))return kX(n);if(n.startsWith("GEOMETRYCOLLECTION")){const t=/(?<type>POINT|LINESTRING|POLYGON|MULTIPOINT|MULTILINESTRING|MULTIPOLYGON) \((?:[^\(\)]|\([^\)]*\))*\)/g,l=n.match(t);return l[0].startsWith("GEOMETRYCOLLECTION")&&(l[0]=l[0].replace("GEOMETRYCOLLECTION (","")),l.map(Id).map(e=>e instanceof Array?e:[e]).reduce((e,d)=>[...e,...d],[])}else{if(kd(n))return PX(n);if(Pd(n))return QX(n)}}return[]}function kd(n){return n.split(`
|
|
30
|
+
`)?.every(t=>t.includes("POINT"))}function Pd(n){return n.split(`
|
|
31
|
+
`)?.every(t=>t.includes("LINESTRING"))}function BX(n){return n.startsWith("POINT")||kd(n)||n.startsWith("LINESTRING")||Pd(n)||n.startsWith("MULTILINESTRING")||n.startsWith("POLYGON")||n.startsWith("MULTIPOINT")||n.startsWith("MULTIPOLYGON")||n.startsWith("GEOMETRYCOLLECTION")}b.isWktString=BX,b.parseWKT=Id,b.BooleanOperations=cn,b.Relations=ZX;const vX=6378137,wX=6378137,UX=6356752314245179e-9;function Un(n){return n}new N;function jX(n,t=[],l=Un){return"longitude"in n?(t[0]=l(n.longitude),t[1]=l(n.latitude),t[2]=n.height):"x"in n?(t[0]=l(n.x),t[1]=l(n.y),t[2]=n.z):(t[0]=l(n[0]),t[1]=l(n[1]),t[2]=n[2]),t}function EX(n,t=[]){return jX(n,t,w._cartographicRadians?Un:rc)}function OX(n,t,l=Un){return"longitude"in t?(t.longitude=l(n[0]),t.latitude=l(n[1]),t.height=n[2]):"x"in t?(t.x=l(n[0]),t.y=l(n[1]),t.z=n[2]):(t[0]=l(n[0]),t[1]=l(n[1]),t[2]=n[2]),t}function AX(n,t){return OX(n,t,w._cartographicRadians?Un:Zc)}const Qd=1e-14,DX=new N,Bd={up:{south:"east",north:"west",west:"south",east:"north"},down:{south:"west",north:"east",west:"north",east:"south"},south:{up:"west",down:"east",west:"down",east:"up"},north:{up:"east",down:"west",west:"up",east:"down"},west:{up:"north",down:"south",north:"down",south:"up"},east:{up:"south",down:"north",north:"up",south:"down"}},ns={north:[-1,0,0],east:[0,1,0],up:[0,0,1],south:[1,0,0],west:[0,-1,0],down:[0,0,-1]},hn={east:new N,north:new N,up:new N,west:new N,south:new N,down:new N},qX=new N,_X=new N,$X=new N;function vd(n,t,l,s,e,d){const i=Bd[t]&&Bd[t][l];at(i&&(!s||s===i));let c,o,X;const a=DX.copy(e);if(A(a.x,0,Qd)&&A(a.y,0,Qd)){const r=Math.sign(a.z);c=qX.fromArray(ns[t]),t!=="east"&&t!=="west"&&c.scale(r),o=_X.fromArray(ns[l]),l!=="east"&&l!=="west"&&o.scale(r),X=$X.fromArray(ns[s]),s!=="east"&&s!=="west"&&X.scale(r)}else{const{up:r,east:Z,north:G}=hn;Z.set(-a.y,a.x,0).normalize(),n.geodeticSurfaceNormal(a,r),G.copy(r).cross(Z);const{down:p,west:m,south:W}=hn;p.copy(r).scale(-1),m.copy(Z).scale(-1),W.copy(G).scale(-1),c=hn[t],o=hn[l],X=hn[s]}return d[0]=c.x,d[1]=c.y,d[2]=c.z,d[3]=0,d[4]=o.x,d[5]=o.y,d[6]=o.z,d[7]=0,d[8]=X.x,d[9]=X.y,d[10]=X.z,d[11]=0,d[12]=a.x,d[13]=a.y,d[14]=a.z,d[15]=1,d}const jt=new N,ta=new N,na=new N;function la(n,t,l=[]){const{oneOverRadii:s,oneOverRadiiSquared:e,centerToleranceSquared:d}=t;jt.from(n);const i=jt.x,c=jt.y,o=jt.z,X=s.x,a=s.y,u=s.z,r=i*i*X*X,Z=c*c*a*a,G=o*o*u*u,p=r+Z+G,m=Math.sqrt(1/p);if(!Number.isFinite(m))return;const W=ta;if(W.copy(n).scale(m),p<d)return W.to(l);const L=e.x,V=e.y,y=e.z,S=na;S.set(W.x*L*2,W.y*V*2,W.z*y*2);let K=(1-m)*jt.len()/(.5*S.len()),T=0,Y,g,z,H;do{K-=T,Y=1/(1+K*L),g=1/(1+K*V),z=1/(1+K*y);const J=Y*Y,I=g*g,C=z*z,D=J*Y,zt=I*g,Mt=C*z;H=r*J+Z*I+G*C-1;const nl=-2*(r*D*L+Z*zt*V+G*Mt*y);T=H/nl}while(Math.abs(H)>yo);return jt.scale([Y,g,z]).to(l)}const jn=new N,wd=new N,sa=new N,$=new N,ea=new N,En=new N;class Ud{constructor(t=0,l=0,s=0){this.centerToleranceSquared=Vo,at(t>=0),at(l>=0),at(s>=0),this.radii=new N(t,l,s),this.radiiSquared=new N(t*t,l*l,s*s),this.radiiToTheFourth=new N(t*t*t*t,l*l*l*l,s*s*s*s),this.oneOverRadii=new N(t===0?0:1/t,l===0?0:1/l,s===0?0:1/s),this.oneOverRadiiSquared=new N(t===0?0:1/(t*t),l===0?0:1/(l*l),s===0?0:1/(s*s)),this.minimumRadius=Math.min(t,l,s),this.maximumRadius=Math.max(t,l,s),this.radiiSquared.z!==0&&(this.squaredXOverSquaredZ=this.radiiSquared.x/this.radiiSquared.z),Object.freeze(this)}equals(t){return this===t||!!(t&&this.radii.equals(t.radii))}toString(){return this.radii.toString()}cartographicToCartesian(t,l=[0,0,0]){const s=wd,e=sa,[,,d]=t;this.geodeticSurfaceNormalCartographic(t,s),e.copy(this.radiiSquared).scale(s);const i=Math.sqrt(s.dot(e));return e.scale(1/i),s.scale(d),e.add(s),e.to(l)}cartesianToCartographic(t,l=[0,0,0]){En.from(t);const s=this.scaleToGeodeticSurface(En,$);if(!s)return;const e=this.geodeticSurfaceNormal(s,wd),d=ea;d.copy(En).subtract(s);const i=Math.atan2(e.y,e.x),c=Math.asin(e.z),o=Math.sign(At(d,En))*xn(d);return AX([i,c,o],l)}eastNorthUpToFixedFrame(t,l=new ht){return vd(this,"east","north","up",t,l)}localFrameToFixedFrame(t,l,s,e,d=new ht){return vd(this,t,l,s,e,d)}geocentricSurfaceNormal(t,l=[0,0,0]){return jn.from(t).normalize().to(l)}geodeticSurfaceNormalCartographic(t,l=[0,0,0]){const s=EX(t),e=s[0],d=s[1],i=Math.cos(d);return jn.set(i*Math.cos(e),i*Math.sin(e),Math.sin(d)).normalize(),jn.to(l)}geodeticSurfaceNormal(t,l=[0,0,0]){return jn.from(t).scale(this.oneOverRadiiSquared).normalize().to(l)}scaleToGeodeticSurface(t,l){return la(t,this,l)}scaleToGeocentricSurface(t,l=[0,0,0]){$.from(t);const s=$.x,e=$.y,d=$.z,i=this.oneOverRadiiSquared,c=1/Math.sqrt(s*s*i.x+e*e*i.y+d*d*i.z);return $.multiplyScalar(c).to(l)}transformPositionToScaledSpace(t,l=[0,0,0]){return $.from(t).scale(this.oneOverRadii).to(l)}transformPositionFromScaledSpace(t,l=[0,0,0]){return $.from(t).scale(this.radii).to(l)}getSurfaceNormalIntersectionWithZAxis(t,l=0,s=[0,0,0]){at(A(this.radii.x,this.radii.y,Lo)),at(this.radii.z>0),$.from(t);const e=$.z*(1-this.squaredXOverSquaredZ);if(!(Math.abs(e)>=this.radii.z-l))return $.set(0,0,e).to(s)}}Ud.WGS84=new Ud(vX,wX,UX);var da=Object.defineProperty,ia=(n,t,l)=>t in n?da(n,t,{enumerable:!0,configurable:!0,writable:!0,value:l}):n[t]=l,P=(n,t,l)=>ia(n,typeof t!="symbol"?t+"":t,l),On=(n=>(n[n.x=0]="x",n[n.y=1]="y",n[n.z=2]="z",n))(On||{});(n=>{function t(e){return n[e]}n.toKey=t;function l(e){return n[e]}n.toIndex=l;function s(e){const d=(e+1)%3,i=(e+2)%3;return[d,i]}n.getCrossAxiss=s})(On||(On={}));var ls=(n=>(n[n.x=0]="x",n[n.y=1]="y",n[n.z=2]="z",n[n.w=3]="w",n))(ls||{});(n=>{function t(e){return n[e]}n.toKey=t;function l(e){return n[e]}n.toIndex=l;function s(e){const d=(e+1)%4,i=(e+2)%4,c=(e+3)%4;return[d,i,c]}n.getCrossAxiss=s})(ls||(ls={}));var ss=(n=>(n[n.east=0]="east",n[n.west=1]="west",n[n.north=2]="north",n[n.south=3]="south",n[n.up=4]="up",n[n.down=5]="down",n))(ss||{});(n=>{function t(i){return n[i]}n.toKey=t;function l(i){return n[i]}n.toIndex=l;function s(i){return i%2===0?i+1:i-1}n.reverse=s;function e(i){return i%2===0?1:-1}n.getVectorSign=e;function d(i,c){let o=t(i),X=c[o];return X||(o=t(s(i)),X=c[o],X=X.map(a=>-a)),X}n.getVector=d})(ss||(ss={}));function it(n){switch(n){case 2:return Dc;case 3:return S0;case 4:return Ab;case 9:return w0;case 16:return Lb;default:throw new Error(`不支持获取命名空间: ${n}`)}}const ca={4:"transformMat2",6:"transformMat2d",9:"transformMat3",16:"transformMat4"};function es(n,t){const l=it(t),s=ca[n],e=l[s];if(!e)throw new Error(`不支持的矩阵大小:${n}`);return e}const ba={Array,Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array};var ds=(n=>(n.Array="Array",n.Int8Array="Int8Array",n.Uint8Array="Uint8Array",n.Uint8ClampedArray="Uint8ClampedArray",n.Int16Array="Int16Array",n.Uint16Array="Uint16Array",n.Int32Array="Int32Array",n.Uint32Array="Uint32Array",n.Float32Array="Float32Array",n.Float64Array="Float64Array",n))(ds||{});(n=>{function t(e){return ba[e]}n.toClass=t;function l(e){return e.name}n.toType=l;function s(e){return e.constructor.name}n.toTypeByArray=s})(ds||(ds={}));var O=(n=>(n[n.trs=0]="trs",n[n.tsr=1]="tsr",n[n.rst=2]="rst",n[n.srt=3]="srt",n))(O||{});(n=>{function t(s){return!!(s&2)}n.isLocalTranslation=t;function l(s){return!!(s&1)}n.isSR=l})(O||(O={}));var x=(n=>(n[n.ThroughIntersect=1]="ThroughIntersect",n[n.JointIntersect=2]="JointIntersect",n[n.Intersect=3]="Intersect",n[n.Tangency=4]="Tangency",n[n.Contain=8]="Contain",n[n.Dissociation=16]="Dissociation",n[n.AB=32]="AB",n[n.BA=64]="BA",n[n.ABContain=40]="ABContain",n[n.BAContain=72]="BAContain",n))(x||{});const oa={EPSILON:1e-12,debug:!1,precision:4,printTypes:!1,printDegrees:!1,printRowMajor:!0,_cartographicRadians:!1};globalThis.mathgl=globalThis.mathgl||{config:{...oa}};const ct=globalThis.mathgl.config;function Xa(n,{precision:t=ct.precision}={}){return n=aa(n),`${parseFloat(n.toPrecision(t))}`}function is(n){return Array.isArray(n)||ArrayBuffer.isView(n)&&!(n instanceof DataView)}function jd(n,t,l){const s=ct.EPSILON;try{if(n===t)return!0;if(is(n)&&is(t)){if(n.length!==t.length)return!1;for(let e=0;e<n.length;++e)if(!jd(n[e],t[e]))return!1;return!0}return n&&n.equals?n.equals(t):t&&t.equals?t.equals(n):typeof n=="number"&&typeof t=="number"?Math.abs(n-t)<=ct.EPSILON*Math.max(1,Math.abs(n),Math.abs(t)):!1}finally{ct.EPSILON=s}}function aa(n){return Math.round(n/ct.EPSILON)*ct.EPSILON}class ua extends Array{clone(){return new this.constructor().copy(this)}fromArray(t,l=0){for(let s=0;s<this.ELEMENTS;++s)this[s]=t[s+l];return this.check()}toArray(t=[],l=0){for(let s=0;s<this.ELEMENTS;++s)t[l+s]=this[s];return t}toObject(t){return t}from(t){return Array.isArray(t)?this.copy(t):this.fromObject(t)}to(t){return t===this?this:is(t)?this.toArray(t):this.toObject(t)}toTarget(t){return t?this.to(t):this}toFloat32Array(){return new Float32Array(this)}toString(){return this.formatString(ct)}formatString(t){let l="";for(let s=0;s<this.ELEMENTS;++s)l+=(s>0?", ":"")+Xa(this[s],t);return`${t.printTypes?this.constructor.name:""}[${l}]`}equals(t){if(!t||this.length!==t.length)return!1;for(let l=0;l<this.ELEMENTS;++l)if(!jd(this[l],t[l]))return!1;return!0}exactEquals(t){if(!t||this.length!==t.length)return!1;for(let l=0;l<this.ELEMENTS;++l)if(this[l]!==t[l])return!1;return!0}negate(){for(let t=0;t<this.ELEMENTS;++t)this[t]=-this[t];return this.check()}lerp(t,l,s){if(s===void 0)return this.lerp(this,t,l);for(let e=0;e<this.ELEMENTS;++e){const d=t[e],i=typeof l=="number"?l:l[e];this[e]=d+s*(i-d)}return this.check()}min(t){for(let l=0;l<this.ELEMENTS;++l)this[l]=Math.min(t[l],this[l]);return this.check()}max(t){for(let l=0;l<this.ELEMENTS;++l)this[l]=Math.max(t[l],this[l]);return this.check()}clamp(t,l){for(let s=0;s<this.ELEMENTS;++s)this[s]=Math.min(Math.max(this[s],t[s]),l[s]);return this.check()}add(...t){for(const l of t)for(let s=0;s<this.ELEMENTS;++s)this[s]+=l[s];return this.check()}subtract(...t){for(const l of t)for(let s=0;s<this.ELEMENTS;++s)this[s]-=l[s];return this.check()}scale(t){if(typeof t=="number")for(let l=0;l<this.ELEMENTS;++l)this[l]*=t;else for(let l=0;l<this.ELEMENTS&&l<t.length;++l)this[l]*=t[l];return this.check()}multiplyByScalar(t){for(let l=0;l<this.ELEMENTS;++l)this[l]*=t;return this.check()}check(){if(ct.debug&&!this.validate())throw new Error(`math.gl: ${this.constructor.name} some fields set to invalid numbers'`);return this}validate(){let t=this.length===this.ELEMENTS;for(let l=0;l<this.ELEMENTS;++l)t=t&&Number.isFinite(this[l]);return t}sub(t){return this.subtract(t)}setScalar(t){for(let l=0;l<this.ELEMENTS;++l)this[l]=t;return this.check()}addScalar(t){for(let l=0;l<this.ELEMENTS;++l)this[l]+=t;return this.check()}subScalar(t){return this.addScalar(-t)}multiplyScalar(t){for(let l=0;l<this.ELEMENTS;++l)this[l]*=t;return this.check()}divideScalar(t){return this.multiplyByScalar(1/t)}clampScalar(t,l){for(let s=0;s<this.ELEMENTS;++s)this[s]=Math.min(Math.max(this[s],t),l);return this.check()}get elements(){return this}}function ha(n,t){if(n.length!==t)return!1;for(let l=0;l<n.length;++l)if(!Number.isFinite(n[l]))return!1;return!0}function ra(n){if(!Number.isFinite(n))throw new Error(`Invalid number ${JSON.stringify(n)}`);return n}function Za(n,t,l=""){if(ct.debug&&!ha(n,t))throw new Error(`math.gl: ${l} some fields set to invalid numbers'`);return n}class Ga extends ua{toString(){let t="[";if(ct.printRowMajor){t+="row-major:";for(let l=0;l<this.RANK;++l)for(let s=0;s<this.RANK;++s)t+=` ${this[s*this.RANK+l]}`}else{t+="column-major:";for(let l=0;l<this.ELEMENTS;++l)t+=` ${this[l]}`}return t+="]",t}getElementIndex(t,l){return l*this.RANK+t}getElement(t,l){return this[l*this.RANK+t]}setElement(t,l,s){return this[l*this.RANK+t]=ra(s),this}getColumn(t,l=new Array(this.RANK).fill(-0)){const s=t*this.RANK;for(let e=0;e<this.RANK;++e)l[e]=this[s+e];return l}setColumn(t,l){const s=t*this.RANK;for(let e=0;e<this.RANK;++e)this[s+e]=l[e];return this}}function ma(n,t){if(n===t){let l=t[1];n[1]=t[2],n[2]=l}else n[0]=t[0],n[1]=t[2],n[2]=t[1],n[3]=t[3];return n}function pa(n,t){let l=t[0],s=t[1],e=t[2],d=t[3],i=l*d-e*s;return i?(i=1/i,n[0]=d*i,n[1]=-s*i,n[2]=-e*i,n[3]=l*i,n):null}function Wa(n){return n[0]*n[3]-n[2]*n[1]}function Ed(n,t,l){let s=t[0],e=t[1],d=t[2],i=t[3],c=l[0],o=l[1],X=l[2],a=l[3];return n[0]=s*c+d*o,n[1]=e*c+i*o,n[2]=s*X+d*a,n[3]=e*X+i*a,n}function Va(n,t,l){let s=t[0],e=t[1],d=t[2],i=t[3],c=Math.sin(l),o=Math.cos(l);return n[0]=s*o+d*c,n[1]=e*o+i*c,n[2]=s*-c+d*o,n[3]=e*-c+i*o,n}function Od(n,t,l){let s=t[0],e=t[1],d=t[2],i=t[3],c=l[0],o=l[1];return n[0]=s*c,n[1]=e*c,n[2]=d*o,n[3]=i*o,n}function ya(n,t){const l=[];for(let s=0;s<t;s++){const e=s*t;l[s]=n.slice(e,e+t)}return l}function La(n,t,l,s){for(let e=0;e<s;e++)n[e]=t[e*s+l];return n}function xa(n,t){const l=[];for(let s=0;s<t;s++)La(l[s]=[],n,s,t);return l}function Ka(n,t,l){const s=ya(t,l);for(let e=0;e<l;e++){const d=s[e];n[e]=Math.hypot(...d)}return n}function Ra(n,t,l){const s=xa(t,l);for(let e=0;e<l;e++){const d=s[e];n[e]=Math.hypot(...d)}return n}function Ad(n,t,l,s){for(let e=0;e<s;e++){const d=e*s,i=l[e];for(let c=0;c<s;c++){const o=d+c;n[o]=t[o]*i}}return n}function Dd(n,t,l,s){for(let e=0;e<s;e++){const d=e*s;for(let i=0;i<s;i++){const c=d+i;n[c]=t[c]*l[i]}}return n}new nt,new N,new ut;const An=[new nt,new nt,new nt,new nt],qd=[new N,new N,new N,new N],Sa=[new ut,new ut,new ut,new ut],cs=[new Xt,new Xt,new Xt,new Xt],za=[new ht,new ht,new ht,new ht];new Ct,new Ct,new Ct,new Ct,new v,new v,new v,new v;function bs(n){switch(n){case 2:return An;case 3:return qd;case 4:return Sa;case 9:return cs;case 16:return za;default:throw new Error(`不支持获取临时变量: ${n}`)}}var _d=(n=>(n[n.COL0ROW0=0]="COL0ROW0",n[n.COL0ROW1=1]="COL0ROW1",n[n.COL1ROW0=2]="COL1ROW0",n[n.COL1ROW1=3]="COL1ROW1",n))(_d||{});const Ma=Object.freeze([1,0,0,1]);class rn extends Ga{static get IDENTITY(){return ga()}static get ZERO(){return Ya()}get ELEMENTS(){return 4}get RANK(){return 2}get INDICES(){return _d}constructor(t,...l){super(-0,-0,-0,-0),arguments.length===1&&Array.isArray(t)?this.copy(t):l.length>0?this.copy([t,...l]):this.identity()}copy(t){return this[0]=t[0],this[1]=t[1],this[2]=t[2],this[3]=t[3],this.check()}identity(){return this.copy(Ma)}fromObject(t){return this.check()}set(t,l,s,e){return this[0]=t,this[1]=l,this[2]=s,this[3]=e,this.check()}setRowMajor(t,l,s,e){return this[0]=t,this[1]=s,this[2]=l,this[3]=e,this.check()}determinant(){return Wa(this)}transpose(){return ma(this,this),this.check()}invert(){return pa(this,this),this.check()}multiplyLeft(t){return Ed(this,t,this),this.check()}multiplyRight(t){return Ed(this,this,t),this.check()}multiplyByVector(t,l){l||(l=new nt);const s=t.x,e=t.y,d=this[0]*s+this[2]*e,i=this[1]*s+this[3]*e;return l.x=d,l.y=i,l}multiplyByScale(t,l){return l||(l=new rn),l[0]=this[0]*t.x,l[1]=this[1]*t.x,l[2]=this[2]*t.y,l[3]=this[3]*t.y,l}rotate(t){return Va(this,this,t),this.check()}scale(t){return Array.isArray(t)?Od(this,this,t):Od(this,this,[t,t]),this.check()}transform(t,l){const s=Xl(l||[-0,-0],t,this);return Za(s,t.length),s}transformVector(t,l){return this.transform(t,l)}transformVector2(t,l){return this.transform(t,l)}transformVector3(t,l){return this.transform(t,l)}}let Dn,qn=null;function Ya(){return Dn||(Dn=new rn([0,0,0,0]),Object.freeze(Dn)),Dn}function ga(){return qn||(qn=new rn,Object.freeze(qn)),qn}function $d(n,t){return zn(n,t),yl(n,n)}function Ta(n,t){return Ka(n,t,3),qt(t)<0&&(n[0]=-n[0]),n}function Ca(n,t){return Ra(n,t,3),qt(t)<0&&(n[0]=-n[0]),n}function fa(n,t,l){Ca(n,l),ml(n,n),Dd(t,l,n,3)}new Xt;function Fa(n,t,l){return Dd(n,l,t,3)}function Na(n,t,l){Ta(t,l),ml(t,t),Ad(n,l,t,3)}function Ha(n,t,l){return Ad(n,t,l,3)}new rn;function Ja(n,t){return ce(n,t[0],t[1],t[2],t[4],t[5],t[6],t[8],t[9],t[10])}function Ia(n,t){return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[4]=t[3],n[5]=t[4],n[6]=t[5],n[8]=t[6],n[9]=t[7],n[10]=t[8],n}function ka(n,t){return Ia(n,t),n[3]=0,n[7]=0,n[11]=0,n[12]=0,n[13]=0,n[14]=0,n[15]=1,n}function ti(n,t){return n[12]=t[0],n[13]=t[1],n[14]=t[2],n}const _=new Xt;function Pa(n,t){Vl(_,n);const l=Dt(qd[0],t,_);return ti(n,l)}function Qa(n,t){return Sl(n,t),Vl(_,t),zn(_,_),Dt(n,n,_)}function Ba(n,t,l,s,e=O.trs){O.isLocalTranslation(e)?Qa(n,s):Sl(n,s),Ja(_,s),O.isSR(e)?fa(l,t,_):Na(t,l,_)}const _n=new Xt;function va(n,t,l,s,e=O.trs){Ba(n,_n,l,s,e),Cl(t,_n)}function wa(n,t,l,s,e=O.trs){return O.isSR(e)?Fa(_,s,l):Ha(_,l,s),ka(n,_),O.isLocalTranslation(e)?Pa(n,t):ti(n,t),n}function Ua(n,t,l,s,e=O.trs){return xl(_n,l),wa(n,t,_n,s,e)}function bt(n,t){const l=t.findIndex(e=>!A(e,0));if(l===-1)return 0;const s=n[l];return A(s,0)?1/0:t[l]/s}function ni(n,t){const l=t.findIndex(e=>!A(e,0));if(l===-1)return!0;const s=n[l]/t[l];return On.getCrossAxiss(l).every(e=>A(t[e]*s,n[e]))}function ja(n,t){return A(gt([],n,t)[2],0)}function Ea(n,t){const l=it(n.length).cross([],n,t);return Math.hypot(...l)}function Oa(n,t){return Math.abs(Aa(n,t))}function Aa(n,t){return gt([],n,t)[2]}function Da(n,t,l){const s=[...n,...t,...l];return qt(s)}new N(1,1,1),new N(0,0,1);class os{constructor(t){P(this,"array"),P(this,"count",0),P(this,"vectorSize"),P(this,"start",0),t&&this.setOptions(t)}get end(){return this.start+this.count*this.vectorSize}set end(t){this.count=Math.trunc((t-this.start)/this.vectorSize)}setOptions(t){const{end:l,count:s,...e}=t;Object.assign(this,e),l==null&&s==null?this.count=this.array.length/this.vectorSize:l!=null&&(this.end=l)}from(t){const{array:l,...s}=t;return this.setOptions({array:l.slice(),...s}),this}clone(){const t=new this.constructor;return t.from(this),t}copy(t){for(let l=0;l<this.count;l++)this.copyAt(l,t,l);return this}copyAt(t,l,s){const e=l.getVector(s);return this.setVector(t,e),this}copyArray(t){const l=this.start;for(let s=0,e=t.length;s<e;s++)this.array[l+s]=t[s];return this}getStartArrayIndex(t){return this.start+t*this.vectorSize}getArrayIndexRange(t){const l=this.start+t*this.vectorSize;return[l,l+this.vectorSize]}getVector(t){return this.array.slice(...this.getArrayIndexRange(t))}setVector(t,l,s=0){const e=this.getStartArrayIndex(t);for(let d=0,i=this.vectorSize;d<i;d++)this.array[e+d]=l[s+d];return s+this.vectorSize}toVectors(t=[]){const{start:l,end:s,vectorSize:e,array:d}=this;for(let i=l;i<s;i+=e){const c=d.slice(i,i+e);t.push(c)}return t}map(t,l=[]){for(let s=0;s<this.count;s++){const e=this.getVector(s);l[s]=t(e,s)}return l}mapSelf(t){for(let l=0;l<this.count;l++){const s=this.getVector(l),e=t(s,l);this.setVector(l,e)}return this}filter(t,l=[]){for(let s=0;s<this.count;s++){const e=this.getVector(s);if(t(e,s))for(const d of e)l[l.length]=d}return l}transform(t){const l=es(t.length,this.vectorSize);return this.mapSelf(s=>l(s,s,t))}transformAsNormal(t){const l=cs[0];t.length===16?Kl(l,t):$d(l,t);const s=es(l.length,this.vectorSize);return this.mapSelf(e=>s(e,e,l))}scale(t){const l=it(this.vectorSize);return this.mapSelf(s=>l.scale(s,s,t))}scaleAndAdd(t,l){const s=it(this.vectorSize);return this.mapSelf(e=>s.scaleAndAdd(e,e,t,l))}add(t){const l=it(this.vectorSize);return this.mapSelf(s=>l.add(s,s,t))}subtract(t){const l=it(this.vectorSize);return this.mapSelf(s=>l.subtract(s,s,t))}multiply(t){const l=it(this.vectorSize);return this.mapSelf(s=>l.multiply(s,s,t))}divide(t){const l=it(this.vectorSize);return this.mapSelf(s=>l.divide(s,s,t))}}function qa(n){return n.flatMap(t=>[...t])}class _a{constructor(t){P(this,"array"),P(this,"attributes"),P(this,"count"),t&&this.setOptions(t)}setOptions(t){const{attributes:l,array:s,count:e,...d}=t;Object.assign(this,d,{array:s,count:e});const i=this.attributes={};for(const[c,o]of Object.entries(l))i[c]=new os({array:s,count:e,...o});return this}setVector(t,l,s,e){return this.attributes[t].setVector(l,s,e)}getVector(t,l){return this.attributes[t].getVector(l)}getVectors(t,l){return t.map(s=>this.attributes[s].getVector(l))}getAttribute(t){return this.attributes[t]}setAttribute(t,l){const{array:s,count:e}=this;return this.attributes[t]=new os({array:s,...l,count:e})}getAggregateVector(t,l){const s=[];for(const e of t){const d=this.getVector(e,l);s.push(...d)}return s}setAggregateVector(t,l,s,e){if(t.length===1)return this.setVector(t[0],l,s,e);for(const d of t)e=this.setVector(d,l,s,e);return e}getAggregateVectorSize(t){if(t.length===1)return this.getAttribute(t[0]).vectorSize;let l=0;for(const s of t)l+=this.getAttribute(s).vectorSize;return l}createAggregateVectorGetter(t){if(t.length===1){const l=this.attributes[t[0]];return l.getVector.bind(l)}return this.getAggregateVector.bind(this,t)}createAggregateVectorSetter(t){if(t.length===1){const l=this.attributes[t[0]];return l.setVector.bind(l)}return this.setAggregateVector.bind(this,t)}map(t,l,s=[]){for(let e=0;e<this.count;e++){const d=this.getVectors(t,e);s[e]=l(d,e)}return s}mapForAggregate(t,l,s=[]){for(let e=0;e<this.count;e++){const d=this.getAggregateVector(t,e);s[e]=l(d,e)}return s}mapSelf(t,l){for(let s=0;s<this.count;s++){const e=this.getVectors(t,s),d=l(e,s);t.forEach((i,c)=>this.setVector(i,s,d[c]))}return this}mapSelfForAggregate(t,l){for(let s=0;s<this.count;s++){const e=this.getAggregateVector(t,s),d=l(e,s);this.setAggregateVector(t,s,d)}return this}filter(t,l,s=[]){for(let e=0;e<this.count;e++){const d=this.getVectors(t,e);l(d,e)&&s.push(d)}return s}filterForAggregate(t,l,s=[]){return this.filter(t,(e,d)=>l(qa(e),d),s)}transform(t,l){const s=cs[0];l.includes("normal")&&(t.length===16?Kl(s,t):$d(s,t));for(const e of l){const d=this.getAttribute(e);d&&(e==="normal"?d.transformAsNormal(s):d.transform(t))}return this}transformForAggregate(t,l){const s=this.getAggregateVectorSize(l),e=es(t.length,s);return this.mapSelfForAggregate(l,d=>e(d,d,t)),this}}class li extends _a{setOptions(t){const{indices:l,...s}=t;super.setOptions(s);const e=l.array?l:{array:l};return this.indices=new os({count:e.array.length/3,vectorSize:3,...e}),this}getFaceVector(t,l){const s=this.indices.getVector(l);return Array.prototype.map.call(s,e=>this.getVector(t,e))}getFaceVectors(t,l){const s=this.indices.getVector(l);return Array.prototype.map.call(s,e=>this.getVectors(t,e))}getFaceAggregateVector(t,l){const s=this.indices.getVector(l);return Array.prototype.map.call(s,e=>this.getAggregateVector(t,e))}mapFace(t,l,s=[]){return this.indices.map((e,d)=>{const i=Array.prototype.map.call(e,c=>this.getVectors(t,c));return l(i,d,e)},s)}mapFaceForAggregate(t,l,s=[]){return this.indices.map((e,d)=>{const i=Array.prototype.map.call(e,c=>this.getAggregateVector(t,c));return l(i,d,e)},s)}filterFace(t,l,s=[]){return this.indices.filter((e,d)=>{const i=Array.prototype.map.call(e,c=>this.getVectors(t,c));return l(i,d,e)},s)}filterFaceForAggregate(t,l,s=[]){return this.indices.filter((e,d)=>{const i=Array.prototype.map.call(e,c=>this.getAggregateVector(t,c));return l(i,d,e)},s)}}function si(n,t){const l=tt([],n[1],n[0]),s=tt([],t,n[0]);return gt(l,l,s),A(l[2],0)?0:l[2]}function $a(n,t){const[l,s]=n,[e,d]=An;if(e.subVectors(t,l),d.subVectors(s,l),ja(d,e)){const i=bt(d,e);return i<0||i>1?x.Tangency:x.Contain}return x.Dissociation}function ei(n,t){const[l,s]=n,[e,d]=t,[i,c,o]=bs(l.length);return c.subVectors(s,l),o.subVectors(d,e),ni(o,c)?(i.subVectors(e,l),ni(i,c)?x.Tangency:x.Dissociation):x.Intersect}function tu(n,t,l){const[s,e]=t,[d,i]=l,[c,o,X]=bs(s.length);c.subVectors(e,s),o.subVectors(i,d);const a=it(s.length),u=a.cross([],c,o);if(A(a.squaredLength(u),0))return null;X.subVectors(d,s);const r=a.cross([],X,o),Z=bt(u,r);return a.scaleAndAdd(n,s,c,Z)}function nu(n,t,l){const[s,e]=t,[d,i]=l,[c,o,X]=An;c.subVectors(e,s),o.subVectors(i,d);const a=gt([],c,o)[2];if(A(a,0))return null;X.subVectors(d,s);const u=gt([],X,o)[2]/a;return Is(n,s,c,u)}function lu(n,t){const[l,s]=t,[e,d]=n,i=tt([],d,e),c=ei(n,t);if(c===x.Tangency){let u=0;return bt(i,tt([],l,e))<0&&u++,bt(i,tt([],s,e))<0&&u++,u===2?x.Dissociation:u===0?x.Contain:x.Tangency}if(c!==x.Intersect)return c;const o=nu([],n,t),X=tt([],s,l),a=bt(X,tt([],o,l));return a<0||a>1||bt(i,tt([],o,e))<0?x.Dissociation:x.Intersect}function su(n,t){const[l,s]=n,[e,d]=t,i=it(l.length),c=i.subtract([],s,l),o=ei(n,t);if(o===x.Tangency){let Z=0,G=0;const p=bt(c,i.subtract([],e,l));p<0?Z++:p>1&&G++;const m=bt(c,i.subtract([],d,l));return m<0?Z++:m>1&&G++,Z===2||G===2?x.Dissociation:Z+G===1?x.Tangency:x.Contain}if(o!==x.Intersect)return o;const X=tu([],n,t),a=i.subtract([],d,e),u=bt(a,i.subtract([],X,e));if(u<0||u>1)return x.Dissociation;if(u===0||u===1)return x.JointIntersect;const r=bt(c,i.subtract([],X,l));return r<0||r>1?x.Dissociation:r===0||r===1?x.JointIntersect:x.ThroughIntersect}function eu(n){const t=n.length;if(t<4)return!0;let l=0;for(let s=0;s<t;s++){const e=n.at(s-1),d=n.at((s+1)%t),i=si([e,n[s]],d);if(i!==0){if(l*i<0)return!1;l=i}}return!0}function pt(n,t){let l=0,s=!1;for(let e=0;e<n.length;e++){const d=n.at(e-1);if(hl(d,t))return x.Tangency;const i=si([d,n[e]],t);if(i===0){s=!0;continue}if(l*i<0)return x.Dissociation;l=i}return s?x.Tangency:x.Contain}function di(n,t){const l=[t,[10,0]];Ns(l[1],t,l[1]);const s=n.length;let e=0;for(let d=0;d<s;d++){const i=n[d];if(hl(i,t))return x.Tangency;let c=d+1;c===s&&(c=0);const o=n[c],X=[i,o];if($a(X,t)===x.Contain)return x.Tangency;const a=lu(l,X);if(a===x.Contain){e+=2;continue}if(a===x.Intersect){let u=0;i[1]>t[1]&&u++,o[1]>t[1]&&u++,u===1&&e++}}return e%2===0?x.Dissociation:x.Contain}function ii(n,t){const l=n.length;let s=0;for(let c=0;c<l;c++){const o=n[c];let X=c+1;X===l&&(X=0);const a=n[X],u=su([o,a],t);if(u&(x.ThroughIntersect|x.Tangency|x.Contain))return u;u===x.JointIntersect&&s++}const e=pt(n,t[0]);if(s===0||s===1&&e!==x.Tangency)return e;const d=pt(n,t[1]),i=e|d;return i===x.Tangency?x.Contain:i&x.Tangency?i&x.Contain?x.Contain:x.JointIntersect:e}function du(n,t){const l=n.length;let s=0,e=!1;for(let c=0;c<l;c++){const o=n[c];let X=c+1;X===l&&(X=0);const a=n[X],u=ii(t,[o,a]);if(u===x.ThroughIntersect)return u;u===x.JointIntersect?s++:u===x.Tangency&&(e=!0)}let d=0;e?d|=x.Tangency:s&&(d|=x.JointIntersect);let i=n.some(c=>pt(t,c)===x.Contain);return i?x.BAContain|d:(i=t.some(c=>di(n,c)===x.Contain),i?x.ABContain|d:n.some(c=>pt(t,c)===x.Dissociation)?x.Dissociation|d:d)}function iu(n,t){const l=n.length;let s=0,e=!1;for(let c=0;c<l;c++){const o=n[c];let X=c+1;X===l&&(X=0);const a=n[X],u=ii(t,[o,a]);if(u===x.ThroughIntersect)return u;u===x.JointIntersect?s++:u===x.Tangency&&(e=!0)}let d=0;e?d|=x.Tangency:s&&(d|=x.JointIntersect);let i=n.some(c=>pt(t,c)===x.Contain);return i?x.BAContain|d:(i=t.some(c=>pt(n,c)===x.Contain),i?x.ABContain|d:n.some(c=>pt(t,c)===x.Dissociation)?x.Dissociation|d:d)}function cu(n,t,l=["position"]){return n.mapForAggregate(l,s=>di(t,s))}function bu(n,t,l=["position"]){return n.mapForAggregate(l,s=>pt(t,s))}function ou(n,t,l=["position"],s,e){const d=e?iu:du;return s?s.map(function(i,c){const o=Xu(i);if(o!==null)return o&x.Contain?o|x.AB:o;const X=n.indices.getVector(c),a=Array.prototype.map.call(X,u=>n.getAggregateVector(l,u));return d(t,a)}):n.mapFace(l,i=>d(t,i))}const ci=x.Dissociation|x.Contain;function Xu(n){return(n&ci)===ci?x.ThroughIntersect:n&x.Contain?n&x.Tangency?x.Contain|x.JointIntersect:x.Contain:null}function au(n,t,l){const s=_t.getEqualFun(l),e=[];return n.forEach((d,i)=>{s(t,d)&&e.push(i)}),e}const uu=32767,Xs=1/uu;function bi(n,t){const[l,s,e]=hu(n,t);return[l,0,0,0,0,s,0,0,0,0,e,0,n.west,n.south,t[0],1]}function hu(n,t){const l=(n.east-n.west)*Xs,s=(n.north-n.south)*Xs,e=(t[1]-t[1])*Xs;return[l,s,e]}function oi(n){return ru(n)/2}function ru(n){const t=n[0],l=[];for(let d=1;d<n.length;d++){const i=n[d],c=Gl([],i,t);l.push(c)}const s=Tt([],l[1],l[0]);let e=xn(s);As(s,s,1/e);for(let d=2;d<l.length;d++)e+=Da(l[d-1],l[d],s);return e}function Zu(n,t,l){const[s,e]=bs(n.length);return s.subVectors(t,n),e.subVectors(l,n),Ea(s,e)}function Gu(n,t,l){const[s,e]=An;return s.subVectors(t,n),e.subVectors(l,n),Oa(s,e)}function Xi(n,t){const l=n.length-3;let s=0;for(let e=0;e<l;e+=3){const[d,i,c]=n.slice(e,e+3),o=t(d),X=t(i),a=t(c);s+=Zu(o,X,a)}return s/2}function ai(n,t,l=[0,1/0]){const s=n.length-3,[e,d]=l,i=d-e;let c=0;const o=1/3;for(let X=0;X<s;X+=3){const[a,u,r]=n.slice(X,X+3),[Z,G,p]=t(a),[m,W,L]=t(u),[V,y,S]=t(r),K=Gu([Z,G],[m,W],[V,y]),T=(p+L+S)*o-e;c+=K*Math.min(T,i)}return c/2}const ui=["position"];class mu{constructor(t){P(this,"geometry"),P(this,"positionNames",ui),P(this,"region"),P(this,"relation"),P(this,"relationEqual"),P(this,"_geometryPolygon",null),P(this,"positionRelations"),P(this,"faceRelations"),P(this,"relationIndexsWithoutThrougn"),P(this,"_throughIndexs",[]),P(this,"_throughFaces",null),P(this,"_throughFaceAreas",null),P(this,"_getPosition",null),P(this,"_relationArea",null),P(this,"_area",null),P(this,"_relationVolume",null),P(this,"_volume",null),t&&this.setOptions(t)}get includingThrough(){return this.relation&x.ThroughIntersect}setOptions(t){if(Object.assign(this,t),t.positionNames&&(this._getPosition=null),t.geometry||t.positionNames||t.region)return(t.geometry||t.positionNames)&&(this._geometryPolygon=null),this.update();if(t.relation||t.strict)return this._relationArea=null,this._relationVolume=null,this.updateRelationIndexs()}get geometryPolygon(){return this._geometryPolygon||(this._geometryPolygon=this.generateGeometryPolygon()),this._geometryPolygon}generateGeometryPolygon(){const t=new an;return this.geometry.mapFaceForAggregate(this.positionNames,l=>{const s=l.map(e=>new vn(e[0],e[1]));t.addFace(s)}),t}get throughIndexs(){return this._throughIndexs}set throughIndexs(t){this._throughIndexs=t,this._throughFaces=null,this._throughFaceAreas=null}get throughFaces(){return this._throughFaces||(this._throughFaces=this.generateThroughFaces()),this._throughFaces}get throughFaceAreas(){return this._throughFaceAreas||(this._throughFaceAreas=this.generateThroughFaceAreas()),this._throughFaceAreas}generateThroughFaceAreas(){return this.throughFaces.map(t=>t.area())}update(){this.updatePositionRelations(),this.updateFaceRelations(),this.updateRelationIndexs(),this.includingThrough&&this.updateThroughIndexs(),this.resetMeasure()}updatePositionRelations(){this.positionRelations=this.generatePositionRelations()}updateFaceRelations(){this.faceRelations=this.generateFaceRelations()}updateRelationIndexs(){const t=~x.ThroughIntersect&this.relation;this.relationIndexsWithoutThrougn=this.filterFaces(t,this.relationEqual)}updateThroughIndexs(){this.throughIndexs=this.filterFaces(x.ThroughIntersect,_t.equal),this._throughFaces=null,this._throughFaceAreas=null}resetMeasure(){this._relationArea=null,this._relationVolume=null,this._area=null,this._volume=null}updateMeasure(){this.resetMeasure(),this.relationArea,this.relationVolume,this.area,this.volume}get getPosition(){return this._getPosition||(this._getPosition=this.geometry.createAggregateVectorGetter(this.positionNames))}get relationArea(){return this._relationArea==null&&(this._relationArea=this.computeRelationArea()),this._relationArea}computeRelationArea(){const{geometry:t}=this,l=this.relationIndexsWithoutThrougn.flatMap(e=>[...t.indices.getVector(e)]);let s=Xi(l,this.getPosition);if(this.includingThrough)for(const e of this.throughFaceAreas)s+=e;return s}get area(){return this._area==null&&(this._area=this.computeArea()),this._area}computeArea(){return Xi(this.geometry.indices.array,this.getPosition)}get relationVolume(){return this._relationVolume==null&&(this._relationVolume=this.computeRelationTerrainVolume()),this._relationVolume}computeRelationTerrainVolume(t=[0,1/0]){const{geometry:l}=this,s=this.relationIndexsWithoutThrougn.flatMap(d=>[...l.indices.getVector(d)]);let e=ai(s,this.getPosition,t);if(this.includingThrough){const[d,i]=t,c=i-d;let o=0;const X=1/3,{geometry:a,positionNames:u}=this;this.throughFaceAreas.forEach((r,Z)=>{const G=this.throughIndexs[Z],[p,m,W]=a.getFaceAggregateVector(u,G),L=(p[2]+m[2]+W[2])*X-d;L<=0||(o+=r*Math.min(L,c))}),o/=2,e+=o}return e}get volume(){return this._volume==null&&(this._volume=this.computeTerrainVolume([-1/0,1/0])),this._volume}computeTerrainVolume(t){return ai(this.geometry.indices.array,this.getPosition,t)}}class pu extends mu{constructor(){super(...arguments),P(this,"_isConvex",null),P(this,"_polygonOutsideGeometry",null)}get isConvex(){return this._isConvex==null&&(this._isConvex=eu(this.region)),this._isConvex}set isConvex(t){this._isConvex=t}setOptions(t){if(t.region){const l=t.region.map(s=>new vn(s));this.polygon=new an(l),this.isZeroPolygon=this.polygon.area()===0}super.setOptions(t)}resetMeasure(){super.resetMeasure(),this._polygonOutsideGeometry=null}generatePositionRelations(){return this.isConvex?bu(this.geometry,this.region,this.positionNames):cu(this.geometry,this.region,this.positionNames)}generateFaceRelations(){return ou(this.geometry,this.region,this.positionNames,this.positionRelations,this.isConvex)}generateThroughFaces(){const{geometry:t,polygon:l}=this,s=this.relation&x.Contain;let e=s?cn.intersect:cn.subtract;return this.isZeroPolygon&&(e=s?(d,i)=>l:(d,i)=>d),this.throughIndexs.map(d=>{const i=t.getFaceAggregateVector(this.positionNames,d).map(o=>new vn(o[0],o[1])),c=new an(i);return e(c,l)})}filterFaces(t,l){return au(this.faceRelations,t,l)}get polygonOutsideGeometry(){return this._polygonOutsideGeometry==null&&(this._polygonOutsideGeometry=this.isZeroPolygon?this.polygon:cn.subtract(this.polygon,this.geometryPolygon)),this._polygonOutsideGeometry}}function Wu(n){const{west:t,east:l,south:s,north:e}=n;return[new nt(t,s),new nt(t,e),new nt(l,e),new nt(l,s)]}function Vu(n){const{rectangle:t,heightRange:l,positionNames:s=ui,scale:e}=n,d=new li(n),i=bi(t,l);d.transformForAggregate(i,s);const c=new pu({...n,geometry:d}),o=Wu(t),X=new an(o),a=cn.subtract(X,c.geometryPolygon),u=c.relationArea+a.area();if(!e)return u;const r=Math.hypot(e[0],e[2])*e[1];return u*Math.abs(r)}function yu(n){return new Worker(""+new URL("data:text/javascript;base64,dmFyIGNtPU9iamVjdC5kZWZpbmVQcm9wZXJ0eTt2YXIgYW09KFd0LHZ0LHNlKT0+dnQgaW4gV3Q/Y20oV3QsdnQse2VudW1lcmFibGU6ITAsY29uZmlndXJhYmxlOiEwLHdyaXRhYmxlOiEwLHZhbHVlOnNlfSk6V3RbdnRdPXNlO3ZhciBVPShXdCx2dCxzZSk9PmFtKFd0LHR5cGVvZiB2dCE9InN5bWJvbCI/dnQrIiI6dnQsc2UpOyhmdW5jdGlvbigpeyJ1c2Ugc3RyaWN0IjtmdW5jdGlvbiBXdChlKXt2YXIgdD1lO3JldHVybiBlIT1udWxsJiYodD1lLmNvbnN0cnVjdG9yLHQ9PW51bGwmJih0PXR5cGVvZiBlKSksdH1mdW5jdGlvbiB2dChlKXt2YXIgdD10eXBlb2YgZTtyZXR1cm4gZT09bnVsbHx8dCE9PSJvYmplY3QiJiZ0IT09ImZ1bmN0aW9uIn1mdW5jdGlvbiBzZShlKXtyZXR1cm4gZSYmdHlwZW9mIGVbU3ltYm9sLml0ZXJhdG9yXT09ImZ1bmN0aW9uIn12YXIgRWU9KGU9PihlLmVxdWFsPSJlcXVhbCIsZS5pbnRlcnNlY3Q9ImludGVyc2VjdCIsZS5pbnRlcnNlY3RFcXVhbD0iaW50ZXJzZWN0RXF1YWwiLGUpKShFZXx8e30pOyhlPT57ZnVuY3Rpb24gdChuKXtsZXQgcjtzd2l0Y2gobil7Y2FzZSJlcXVhbCI6cj0oaSxzKT0+aT09PXM7Y2FzZSJpbnRlcnNlY3QiOnI9KGkscyk9PmkmcztkZWZhdWx0OnI9KGkscyk9PihpJnMpPT09aX1yZXR1cm4gcn1lLmdldEVxdWFsRnVuPXR9KShFZXx8KEVlPXt9KSk7ZnVuY3Rpb24gcWkoKXtjb25zdCBlPWdsb2JhbFRoaXMuY3VycmVudFdvcmtlclR5cGU7aWYoZSlyZXR1cm4gZTtsZXQgdD1nbG9iYWxUaGlzLlNoYXJlZFdvcmtlckdsb2JhbFNjb3BlO3JldHVybiB0eXBlb2YgdD09ImZ1bmN0aW9uIiYmZ2xvYmFsVGhpcyBpbnN0YW5jZW9mIHQ/Z2xvYmFsVGhpcy5jdXJyZW50V29ya2VyVHlwZT0iU2hhcmVkV29ya2VyIjoodD1nbG9iYWxUaGlzLkRlZGljYXRlZFdvcmtlckdsb2JhbFNjb3BlLHR5cGVvZiB0PT0iZnVuY3Rpb24iJiZnbG9iYWxUaGlzIGluc3RhbmNlb2YgdD9nbG9iYWxUaGlzLmN1cnJlbnRXb3JrZXJUeXBlPSJEZWRpY2F0ZWRXb3JrZXIiOih0PWdsb2JhbFRoaXMuV2luZG93LHR5cGVvZiB0PT0iZnVuY3Rpb24iJiZnbG9iYWxUaGlzIGluc3RhbmNlb2YgdD9nbG9iYWxUaGlzLmN1cnJlbnRXb3JrZXJUeXBlPSJXaW5kb3ciOmdsb2JhbFRoaXMuY3VycmVudFdvcmtlclR5cGU9InVua25vd24iKSl9ZnVuY3Rpb24gV2EoZSx0LG4pe2NvbnN0IHI9LyheXHMqKGFzeW5jXHMrKT9mdW5jdGlvblxzKihcc3xcKilccyopW0EtWmEtel8kXStbXHckXSooXHMqXCgpLyxpPS9eW0EtWmEtel8kXStbXHckXSokLyxzPXIudGVzdChlKSxvPXQmJmkudGVzdCh0KTtpZihzJiZvJiYoZT1lLnJlcGxhY2UocixgJDEke3R9JDRgKSksIXMmJm8pdmFyIGM9YHZhciAke3R9ID0gJHtlfSA7IHJldHVybiAke3R9YDtlbHNlIGM9YHJldHVybiAoJHtlfSlgO3JldHVybiBuZXcgRnVuY3Rpb24oYykoKX1mdW5jdGlvbiBGaShlKXtjb25zdHtuYW1lOnQsYXJnczpuLHRoaXM6cn09ZSxpPXI/P2dsb2JhbFRoaXMscz1nbG9iYWxUaGlzW3RdO3JldHVybiB0eXBlb2Ygcz09ImZ1bmN0aW9uIj9zLmFwcGx5KGksbik6bnx8cj97ZXJyb3I6IuWHveaVsOS4jeWtmOWcqCIsc3RhdGU6Iue7k+adnyJ9OntkYXRhOnMsc3RhdGU6Iue7k+adnyJ9fWZ1bmN0aW9uIGtpKGUpe2NvbnN0IHQ9V3QoZSk7aWYodD09PSJvYmplY3QifHx0PT09T2JqZWN0KXtjb25zdHt0cmFuc2ZlcjpuLHRhcmdldE9yaWdpbjpyfT1lO3JldHVybiJkYXRhImluIGV8fCJlcnJvciJpbiBlfHxBcnJheS5pc0FycmF5KG4pfHx0eXBlb2Ygcj09InN0cmluZyJ9cmV0dXJuITF9ZnVuY3Rpb24gdG4oZSx0KXtjb25zdHtkYXRhOm4sLi4ucn09a2koZSk/ZTp7ZGF0YTplfSxpPXsuLi50LC4uLnJ9O2lmKG4gaW5zdGFuY2VvZiBSZWFkYWJsZVN0cmVhbSl7Y29uc3Qgcz1uZXcgV3JpdGFibGVTdHJlYW0oe3dyaXRlOmZ1bmN0aW9uKG8sYyl7cmV0dXJuIHRuKG8sey4uLmksc3RhdGU6Iui/m+ihjOS4rSJ9KX0sY2xvc2U6ZnVuY3Rpb24obyl7ZW4odm9pZCAwLHtzdGF0ZToi57uT5p2fIiwuLi5pfSl9LGFib3J0OmZ1bmN0aW9uKG8pe2VuKHZvaWQgMCx7c3RhdGU6Iue7k+adnyIsLi4uaSxlcnJvcjpvfSl9fSk7cmV0dXJuIG4ucGlwZVRvKHMpfXJldHVybiBuIGluc3RhbmNlb2YgUHJvbWlzZT9uLnRoZW4oZnVuY3Rpb24ocyl7dG4ocyx7c3RhdGU6Iue7k+adnyIsLi4uaX0pfSxmdW5jdGlvbihzKXtlbih2b2lkIDAsey4uLmksZXJyb3I6cyxzdGF0ZToi57uT5p2fIn0pfSk6ZW4obix7c3RhdGU6Iue7k+adnyIsLi4uaX0pfWZ1bmN0aW9uIGVuKGUsdCl7Y29uc3R7cG9ydDpuLC4uLnJ9PXQse3RyYW5zZmVyOmksdGFyZ2V0T3JpZ2luOnMsLi4ub309a2koZSk/ey4uLnIsLi4uZX06ey4uLnIsZGF0YTplfTtvLnN0YXRlPT1udWxsJiYoby5zdGF0ZT0i57uT5p2fIik7Y29uc3QgYz17dHJhbnNmZXI6aSx0YXJnZXRPcmlnaW46c307cmV0dXJuKG4/P2dsb2JhbFRoaXMpLnBvc3RNZXNzYWdlKG8sYyl9ZnVuY3Rpb24gQmkoZSl7Y29uc3QgdD1lLmRhdGEsbj1lLmN1cnJlbnRUYXJnZXQ7aWYodCl7Y29uc3Qgcj1GaSh0KTt0bihyLHtleGVjSWQ6dC5pZCxwb3J0Om59KX19ZnVuY3Rpb24gWmEoZSx0KXtjb25zdCBuPVdhKGUsdCk7cmV0dXJuIHQ9dD8/bi5uYW1lLGdsb2JhbFRoaXNbdF09biwhMH1mdW5jdGlvbiBYYShlKXtyZXR1cm4gZGVsZXRlIGdsb2JhbFRoaXNbZV19ZnVuY3Rpb24gR2EoZSl7c3dpdGNoKHFpKCkpe2Nhc2UiU2hhcmVkV29ya2VyIjp7Z2xvYmFsVGhpcy5hZGRFdmVudExpc3RlbmVyKCJjb25uZWN0IixmdW5jdGlvbih0KXtmb3IoY29uc3QgbiBvZiB0LnBvcnRzKW4uYWRkRXZlbnRMaXN0ZW5lcigibWVzc2FnZSIsZSksbi5zdGFydCgpfSk7YnJlYWt9ZGVmYXVsdDpnbG9iYWxUaGlzLmFkZEV2ZW50TGlzdGVuZXIoIm1lc3NhZ2UiLGUpfX1nbG9iYWxUaGlzLmxpc3Rlbk1lc3NhZ2V8fChnbG9iYWxUaGlzLmxpc3Rlbk1lc3NhZ2U9R2EpLE9iamVjdC5hc3NpZ24oZ2xvYmFsVGhpcyx7ZXhlY0NNRDpGaSxtZXNzYWdlTGlzdGVuZXI6Qmksc2V0Q01EOlphLHJlbW92ZUNNRDpYYSxzZW5kTWVzc2FnZTp0bn0pLHFpKCksbGlzdGVuTWVzc2FnZShCaSk7dmFyIEV0PShlPT4oZVtlLng9MF09IngiLGVbZS55PTFdPSJ5IixlW2Uuej0yXT0ieiIsZSkpKEV0fHx7fSk7KGU9PntmdW5jdGlvbiB0KGkpe3JldHVybiBlW2ldfWUudG9LZXk9dDtmdW5jdGlvbiBuKGkpe3JldHVybiBlW2ldfWUudG9JbmRleD1uO2Z1bmN0aW9uIHIoaSl7Y29uc3Qgcz0oaSsxKSUzLG89KGkrMiklMztyZXR1cm5bcyxvXX1lLmdldENyb3NzQXhpc3M9cn0pKEV0fHwoRXQ9e30pKTt2YXIgbm49KGU9PihlW2UueD0wXT0ieCIsZVtlLnk9MV09InkiLGVbZS56PTJdPSJ6IixlW2Uudz0zXT0idyIsZSkpKG5ufHx7fSk7KGU9PntmdW5jdGlvbiB0KGkpe3JldHVybiBlW2ldfWUudG9LZXk9dDtmdW5jdGlvbiBuKGkpe3JldHVybiBlW2ldfWUudG9JbmRleD1uO2Z1bmN0aW9uIHIoaSl7Y29uc3Qgcz0oaSsxKSU0LG89KGkrMiklNCxjPShpKzMpJTQ7cmV0dXJuW3MsbyxjXX1lLmdldENyb3NzQXhpc3M9cn0pKG5ufHwobm49e30pKTt2YXIgX3Q9KGU9PihlW2UuZWFzdD0wXT0iZWFzdCIsZVtlLndlc3Q9MV09Indlc3QiLGVbZS5ub3J0aD0yXT0ibm9ydGgiLGVbZS5zb3V0aD0zXT0ic291dGgiLGVbZS51cD00XT0idXAiLGVbZS5kb3duPTVdPSJkb3duIixlKSkoX3R8fHt9KTsoZT0+e2Z1bmN0aW9uIHQobyl7cmV0dXJuIGVbb119ZS50b0tleT10O2Z1bmN0aW9uIG4obyl7cmV0dXJuIGVbb119ZS50b0luZGV4PW47ZnVuY3Rpb24gcihvKXtyZXR1cm4gbyUyPT09MD9vKzE6by0xfWUucmV2ZXJzZT1yO2Z1bmN0aW9uIGkobyl7cmV0dXJuIG8lMj09PTA/MTotMX1lLmdldFZlY3RvclNpZ249aTtmdW5jdGlvbiBzKG8sYyl7bGV0IGE9dChvKSxoPWNbYV07cmV0dXJuIGh8fChhPXQocihvKSksaD1jW2FdLGg9aC5tYXAoZj0+LWYpKSxofWUuZ2V0VmVjdG9yPXN9KShfdHx8KF90PXt9KSk7Y29uc3QgamE9MS9NYXRoLlBJKjE4MCxRYT0xLzE4MCpNYXRoLlBJLEthPXtFUFNJTE9OOjFlLTEyLGRlYnVnOiExLHByZWNpc2lvbjo0LHByaW50VHlwZXM6ITEscHJpbnREZWdyZWVzOiExLHByaW50Um93TWFqb3I6ITAsX2NhcnRvZ3JhcGhpY1JhZGlhbnM6ITF9O2dsb2JhbFRoaXMubWF0aGdsPWdsb2JhbFRoaXMubWF0aGdsfHx7Y29uZmlnOnsuLi5LYX19O2NvbnN0IEc9Z2xvYmFsVGhpcy5tYXRoZ2wuY29uZmlnO2Z1bmN0aW9uIEhhKGUse3ByZWNpc2lvbjp0PUcucHJlY2lzaW9ufT17fSl7cmV0dXJuIGU9bmwoZSksYCR7cGFyc2VGbG9hdChlLnRvUHJlY2lzaW9uKHQpKX1gfWZ1bmN0aW9uIFp0KGUpe3JldHVybiBBcnJheS5pc0FycmF5KGUpfHxBcnJheUJ1ZmZlci5pc1ZpZXcoZSkmJiEoZSBpbnN0YW5jZW9mIERhdGFWaWV3KX1mdW5jdGlvbiBiZShlKXtyZXR1cm4gdGwoZSl9ZnVuY3Rpb24gSmEoZSl7cmV0dXJuIGVsKGUpfWZ1bmN0aW9uIHRsKGUsdCl7cmV0dXJuIG5yKGUsbj0+bipRYSx0KX1mdW5jdGlvbiBlbChlLHQpe3JldHVybiBucihlLG49Pm4qamEsdCl9ZnVuY3Rpb24gWHQoZSx0LG4pe3JldHVybiBucihlLHI9Pk1hdGgubWF4KHQsTWF0aC5taW4obixyKSkpfWZ1bmN0aW9uIEYoZSx0LG4pe2NvbnN0IHI9Ry5FUFNJTE9OO24mJihHLkVQU0lMT049bik7dHJ5e2lmKGU9PT10KXJldHVybiEwO2lmKFp0KGUpJiZadCh0KSl7aWYoZS5sZW5ndGghPT10Lmxlbmd0aClyZXR1cm4hMTtmb3IobGV0IGk9MDtpPGUubGVuZ3RoOysraSlpZighRihlW2ldLHRbaV0pKXJldHVybiExO3JldHVybiEwfXJldHVybiBlJiZlLmVxdWFscz9lLmVxdWFscyh0KTp0JiZ0LmVxdWFscz90LmVxdWFscyhlKTp0eXBlb2YgZT09Im51bWJlciImJnR5cGVvZiB0PT0ibnVtYmVyIj9NYXRoLmFicyhlLXQpPD1HLkVQU0lMT04qTWF0aC5tYXgoMSxNYXRoLmFicyhlKSxNYXRoLmFicyh0KSk6ITF9ZmluYWxseXtHLkVQU0lMT049cn19ZnVuY3Rpb24gbmwoZSl7cmV0dXJuIE1hdGgucm91bmQoZS9HLkVQU0lMT04pKkcuRVBTSUxPTn1mdW5jdGlvbiBybChlKXtyZXR1cm4gZS5jbG9uZT9lLmNsb25lKCk6bmV3IEFycmF5KGUubGVuZ3RoKX1mdW5jdGlvbiBucihlLHQsbil7aWYoWnQoZSkpe2NvbnN0IHI9ZTtuPW58fHJsKHIpO2ZvcihsZXQgaT0wO2k8bi5sZW5ndGgmJmk8ci5sZW5ndGg7KytpKXtjb25zdCBzPXR5cGVvZiBlPT0ibnVtYmVyIj9lOmVbaV07bltpXT10KHMsaSxuKX1yZXR1cm4gbn1yZXR1cm4gdChlKX1jbGFzcyBTZSBleHRlbmRzIEFycmF5e2Nsb25lKCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKCkuY29weSh0aGlzKX1mcm9tQXJyYXkodCxuPTApe2ZvcihsZXQgcj0wO3I8dGhpcy5FTEVNRU5UUzsrK3IpdGhpc1tyXT10W3Irbl07cmV0dXJuIHRoaXMuY2hlY2soKX10b0FycmF5KHQ9W10sbj0wKXtmb3IobGV0IHI9MDtyPHRoaXMuRUxFTUVOVFM7KytyKXRbbityXT10aGlzW3JdO3JldHVybiB0fXRvT2JqZWN0KHQpe3JldHVybiB0fWZyb20odCl7cmV0dXJuIEFycmF5LmlzQXJyYXkodCk/dGhpcy5jb3B5KHQpOnRoaXMuZnJvbU9iamVjdCh0KX10byh0KXtyZXR1cm4gdD09PXRoaXM/dGhpczpadCh0KT90aGlzLnRvQXJyYXkodCk6dGhpcy50b09iamVjdCh0KX10b1RhcmdldCh0KXtyZXR1cm4gdD90aGlzLnRvKHQpOnRoaXN9dG9GbG9hdDMyQXJyYXkoKXtyZXR1cm4gbmV3IEZsb2F0MzJBcnJheSh0aGlzKX10b1N0cmluZygpe3JldHVybiB0aGlzLmZvcm1hdFN0cmluZyhHKX1mb3JtYXRTdHJpbmcodCl7bGV0IG49IiI7Zm9yKGxldCByPTA7cjx0aGlzLkVMRU1FTlRTOysrciluKz0ocj4wPyIsICI6IiIpK0hhKHRoaXNbcl0sdCk7cmV0dXJuYCR7dC5wcmludFR5cGVzP3RoaXMuY29uc3RydWN0b3IubmFtZToiIn1bJHtufV1gfWVxdWFscyh0KXtpZighdHx8dGhpcy5sZW5ndGghPT10Lmxlbmd0aClyZXR1cm4hMTtmb3IobGV0IG49MDtuPHRoaXMuRUxFTUVOVFM7KytuKWlmKCFGKHRoaXNbbl0sdFtuXSkpcmV0dXJuITE7cmV0dXJuITB9ZXhhY3RFcXVhbHModCl7aWYoIXR8fHRoaXMubGVuZ3RoIT09dC5sZW5ndGgpcmV0dXJuITE7Zm9yKGxldCBuPTA7bjx0aGlzLkVMRU1FTlRTOysrbilpZih0aGlzW25dIT09dFtuXSlyZXR1cm4hMTtyZXR1cm4hMH1uZWdhdGUoKXtmb3IobGV0IHQ9MDt0PHRoaXMuRUxFTUVOVFM7Kyt0KXRoaXNbdF09LXRoaXNbdF07cmV0dXJuIHRoaXMuY2hlY2soKX1sZXJwKHQsbixyKXtpZihyPT09dm9pZCAwKXJldHVybiB0aGlzLmxlcnAodGhpcyx0LG4pO2ZvcihsZXQgaT0wO2k8dGhpcy5FTEVNRU5UUzsrK2kpe2NvbnN0IHM9dFtpXSxvPXR5cGVvZiBuPT0ibnVtYmVyIj9uOm5baV07dGhpc1tpXT1zK3IqKG8tcyl9cmV0dXJuIHRoaXMuY2hlY2soKX1taW4odCl7Zm9yKGxldCBuPTA7bjx0aGlzLkVMRU1FTlRTOysrbil0aGlzW25dPU1hdGgubWluKHRbbl0sdGhpc1tuXSk7cmV0dXJuIHRoaXMuY2hlY2soKX1tYXgodCl7Zm9yKGxldCBuPTA7bjx0aGlzLkVMRU1FTlRTOysrbil0aGlzW25dPU1hdGgubWF4KHRbbl0sdGhpc1tuXSk7cmV0dXJuIHRoaXMuY2hlY2soKX1jbGFtcCh0LG4pe2ZvcihsZXQgcj0wO3I8dGhpcy5FTEVNRU5UUzsrK3IpdGhpc1tyXT1NYXRoLm1pbihNYXRoLm1heCh0aGlzW3JdLHRbcl0pLG5bcl0pO3JldHVybiB0aGlzLmNoZWNrKCl9YWRkKC4uLnQpe2Zvcihjb25zdCBuIG9mIHQpZm9yKGxldCByPTA7cjx0aGlzLkVMRU1FTlRTOysrcil0aGlzW3JdKz1uW3JdO3JldHVybiB0aGlzLmNoZWNrKCl9c3VidHJhY3QoLi4udCl7Zm9yKGNvbnN0IG4gb2YgdClmb3IobGV0IHI9MDtyPHRoaXMuRUxFTUVOVFM7KytyKXRoaXNbcl0tPW5bcl07cmV0dXJuIHRoaXMuY2hlY2soKX1zY2FsZSh0KXtpZih0eXBlb2YgdD09Im51bWJlciIpZm9yKGxldCBuPTA7bjx0aGlzLkVMRU1FTlRTOysrbil0aGlzW25dKj10O2Vsc2UgZm9yKGxldCBuPTA7bjx0aGlzLkVMRU1FTlRTJiZuPHQubGVuZ3RoOysrbil0aGlzW25dKj10W25dO3JldHVybiB0aGlzLmNoZWNrKCl9bXVsdGlwbHlCeVNjYWxhcih0KXtmb3IobGV0IG49MDtuPHRoaXMuRUxFTUVOVFM7KytuKXRoaXNbbl0qPXQ7cmV0dXJuIHRoaXMuY2hlY2soKX1jaGVjaygpe2lmKEcuZGVidWcmJiF0aGlzLnZhbGlkYXRlKCkpdGhyb3cgbmV3IEVycm9yKGBtYXRoLmdsOiAke3RoaXMuY29uc3RydWN0b3IubmFtZX0gc29tZSBmaWVsZHMgc2V0IHRvIGludmFsaWQgbnVtYmVycydgKTtyZXR1cm4gdGhpc312YWxpZGF0ZSgpe2xldCB0PXRoaXMubGVuZ3RoPT09dGhpcy5FTEVNRU5UUztmb3IobGV0IG49MDtuPHRoaXMuRUxFTUVOVFM7KytuKXQ9dCYmTnVtYmVyLmlzRmluaXRlKHRoaXNbbl0pO3JldHVybiB0fXN1Yih0KXtyZXR1cm4gdGhpcy5zdWJ0cmFjdCh0KX1zZXRTY2FsYXIodCl7Zm9yKGxldCBuPTA7bjx0aGlzLkVMRU1FTlRTOysrbil0aGlzW25dPXQ7cmV0dXJuIHRoaXMuY2hlY2soKX1hZGRTY2FsYXIodCl7Zm9yKGxldCBuPTA7bjx0aGlzLkVMRU1FTlRTOysrbil0aGlzW25dKz10O3JldHVybiB0aGlzLmNoZWNrKCl9c3ViU2NhbGFyKHQpe3JldHVybiB0aGlzLmFkZFNjYWxhcigtdCl9bXVsdGlwbHlTY2FsYXIodCl7Zm9yKGxldCBuPTA7bjx0aGlzLkVMRU1FTlRTOysrbil0aGlzW25dKj10O3JldHVybiB0aGlzLmNoZWNrKCl9ZGl2aWRlU2NhbGFyKHQpe3JldHVybiB0aGlzLm11bHRpcGx5QnlTY2FsYXIoMS90KX1jbGFtcFNjYWxhcih0LG4pe2ZvcihsZXQgcj0wO3I8dGhpcy5FTEVNRU5UUzsrK3IpdGhpc1tyXT1NYXRoLm1pbihNYXRoLm1heCh0aGlzW3JdLHQpLG4pO3JldHVybiB0aGlzLmNoZWNrKCl9Z2V0IGVsZW1lbnRzKCl7cmV0dXJuIHRoaXN9fWZ1bmN0aW9uIFVpKGUsdCl7aWYoZS5sZW5ndGghPT10KXJldHVybiExO2ZvcihsZXQgbj0wO248ZS5sZW5ndGg7KytuKWlmKCFOdW1iZXIuaXNGaW5pdGUoZVtuXSkpcmV0dXJuITE7cmV0dXJuITB9ZnVuY3Rpb24gJChlKXtpZighTnVtYmVyLmlzRmluaXRlKGUpKXRocm93IG5ldyBFcnJvcihgSW52YWxpZCBudW1iZXIgJHtKU09OLnN0cmluZ2lmeShlKX1gKTtyZXR1cm4gZX1mdW5jdGlvbiBHdChlLHQsbj0iIil7aWYoRy5kZWJ1ZyYmIVVpKGUsdCkpdGhyb3cgbmV3IEVycm9yKGBtYXRoLmdsOiAke259IHNvbWUgZmllbGRzIHNldCB0byBpbnZhbGlkIG51bWJlcnMnYCk7cmV0dXJuIGV9Y29uc3QgRGk9e307ZnVuY3Rpb24gaWwoZSx0KXtEaVtlXXx8KERpW2VdPSEwLGNvbnNvbGUud2FybihgJHtlfSBoYXMgYmVlbiByZW1vdmVkIGluIHZlcnNpb24gJHt0fSwgc2VlIHVwZ3JhZGUgZ3VpZGUgZm9yIG1vcmUgaW5mb3JtYXRpb25gKSl9ZnVuY3Rpb24gUnQoZSx0KXtpZighZSl0aHJvdyBuZXcgRXJyb3IoYG1hdGguZ2wgYXNzZXJ0aW9uICR7dH1gKX1sZXQgcm49Y2xhc3MgZXh0ZW5kcyBTZXtnZXQgeCgpe3JldHVybiB0aGlzWzBdfXNldCB4KHQpe3RoaXNbMF09JCh0KX1nZXQgeSgpe3JldHVybiB0aGlzWzFdfXNldCB5KHQpe3RoaXNbMV09JCh0KX1sZW4oKXtyZXR1cm4gTWF0aC5zcXJ0KHRoaXMubGVuZ3RoU3F1YXJlZCgpKX1tYWduaXR1ZGUoKXtyZXR1cm4gdGhpcy5sZW4oKX1sZW5ndGhTcXVhcmVkKCl7bGV0IHQ9MDtmb3IobGV0IG49MDtuPHRoaXMuRUxFTUVOVFM7KytuKXQrPXRoaXNbbl0qdGhpc1tuXTtyZXR1cm4gdH1tYWduaXR1ZGVTcXVhcmVkKCl7cmV0dXJuIHRoaXMubGVuZ3RoU3F1YXJlZCgpfWRpc3RhbmNlKHQpe3JldHVybiBNYXRoLnNxcnQodGhpcy5kaXN0YW5jZVNxdWFyZWQodCkpfWRpc3RhbmNlU3F1YXJlZCh0KXtsZXQgbj0wO2ZvcihsZXQgcj0wO3I8dGhpcy5FTEVNRU5UUzsrK3Ipe2NvbnN0IGk9dGhpc1tyXS10W3JdO24rPWkqaX1yZXR1cm4gJChuKX1kb3QodCl7bGV0IG49MDtmb3IobGV0IHI9MDtyPHRoaXMuRUxFTUVOVFM7KytyKW4rPXRoaXNbcl0qdFtyXTtyZXR1cm4gJChuKX1ub3JtYWxpemUoKXtjb25zdCB0PXRoaXMubWFnbml0dWRlKCk7aWYodCE9PTApZm9yKGxldCBuPTA7bjx0aGlzLkVMRU1FTlRTOysrbil0aGlzW25dLz10O3JldHVybiB0aGlzLmNoZWNrKCl9bXVsdGlwbHkoLi4udCl7Zm9yKGNvbnN0IG4gb2YgdClmb3IobGV0IHI9MDtyPHRoaXMuRUxFTUVOVFM7KytyKXRoaXNbcl0qPW5bcl07cmV0dXJuIHRoaXMuY2hlY2soKX1kaXZpZGUoLi4udCl7Zm9yKGNvbnN0IG4gb2YgdClmb3IobGV0IHI9MDtyPHRoaXMuRUxFTUVOVFM7KytyKXRoaXNbcl0vPW5bcl07cmV0dXJuIHRoaXMuY2hlY2soKX1sZW5ndGhTcSgpe3JldHVybiB0aGlzLmxlbmd0aFNxdWFyZWQoKX1kaXN0YW5jZVRvKHQpe3JldHVybiB0aGlzLmRpc3RhbmNlKHQpfWRpc3RhbmNlVG9TcXVhcmVkKHQpe3JldHVybiB0aGlzLmRpc3RhbmNlU3F1YXJlZCh0KX1nZXRDb21wb25lbnQodCl7cmV0dXJuIFJ0KHQ+PTAmJnQ8dGhpcy5FTEVNRU5UUywiaW5kZXggaXMgb3V0IG9mIHJhbmdlIiksJCh0aGlzW3RdKX1zZXRDb21wb25lbnQodCxuKXtyZXR1cm4gUnQodD49MCYmdDx0aGlzLkVMRU1FTlRTLCJpbmRleCBpcyBvdXQgb2YgcmFuZ2UiKSx0aGlzW3RdPW4sdGhpcy5jaGVjaygpfWFkZFZlY3RvcnModCxuKXtyZXR1cm4gdGhpcy5jb3B5KHQpLmFkZChuKX1zdWJWZWN0b3JzKHQsbil7cmV0dXJuIHRoaXMuY29weSh0KS5zdWJ0cmFjdChuKX1tdWx0aXBseVZlY3RvcnModCxuKXtyZXR1cm4gdGhpcy5jb3B5KHQpLm11bHRpcGx5KG4pfWFkZFNjYWxlZFZlY3Rvcih0LG4pe3JldHVybiB0aGlzLmFkZChuZXcgdGhpcy5jb25zdHJ1Y3Rvcih0KS5tdWx0aXBseVNjYWxhcihuKSl9fTtjb25zdCBJPTFlLTY7bGV0IEM9dHlwZW9mIEZsb2F0MzJBcnJheTwidSI/RmxvYXQzMkFycmF5OkFycmF5O2NvbnN0IGp0PU1hdGgucmFuZG9tO2Z1bmN0aW9uIGJ0KGUpe3JldHVybiBlPj0wP01hdGgucm91bmQoZSk6ZSUuNT09PTA/TWF0aC5mbG9vcihlKTpNYXRoLnJvdW5kKGUpfWZ1bmN0aW9uIFlpKCl7Y29uc3QgZT1uZXcgQygyKTtyZXR1cm4gQyE9RmxvYXQzMkFycmF5JiYoZVswXT0wLGVbMV09MCksZX1mdW5jdGlvbiBzbChlKXtjb25zdCB0PW5ldyBDKDIpO3JldHVybiB0WzBdPWVbMF0sdFsxXT1lWzFdLHR9ZnVuY3Rpb24gb2woZSx0KXtjb25zdCBuPW5ldyBDKDIpO3JldHVybiBuWzBdPWUsblsxXT10LG59ZnVuY3Rpb24gY2woZSx0KXtyZXR1cm4gZVswXT10WzBdLGVbMV09dFsxXSxlfWZ1bmN0aW9uIGFsKGUsdCxuKXtyZXR1cm4gZVswXT10LGVbMV09bixlfWZ1bmN0aW9uIFdpKGUsdCxuKXtyZXR1cm4gZVswXT10WzBdK25bMF0sZVsxXT10WzFdK25bMV0sZX1mdW5jdGlvbiBRKGUsdCxuKXtyZXR1cm4gZVswXT10WzBdLW5bMF0sZVsxXT10WzFdLW5bMV0sZX1mdW5jdGlvbiBaaShlLHQsbil7cmV0dXJuIGVbMF09dFswXSpuWzBdLGVbMV09dFsxXSpuWzFdLGV9ZnVuY3Rpb24gcnIoZSx0LG4pe3JldHVybiBlWzBdPXRbMF0vblswXSxlWzFdPXRbMV0vblsxXSxlfWZ1bmN0aW9uIGxsKGUsdCl7cmV0dXJuIGVbMF09TWF0aC5jZWlsKHRbMF0pLGVbMV09TWF0aC5jZWlsKHRbMV0pLGV9ZnVuY3Rpb24gaGwoZSx0KXtyZXR1cm4gZVswXT1NYXRoLmZsb29yKHRbMF0pLGVbMV09TWF0aC5mbG9vcih0WzFdKSxlfWZ1bmN0aW9uIGZsKGUsdCxuKXtyZXR1cm4gZVswXT1NYXRoLm1pbih0WzBdLG5bMF0pLGVbMV09TWF0aC5taW4odFsxXSxuWzFdKSxlfWZ1bmN0aW9uIHVsKGUsdCxuKXtyZXR1cm4gZVswXT1NYXRoLm1heCh0WzBdLG5bMF0pLGVbMV09TWF0aC5tYXgodFsxXSxuWzFdKSxlfWZ1bmN0aW9uIGRsKGUsdCl7cmV0dXJuIGVbMF09YnQodFswXSksZVsxXT1idCh0WzFdKSxlfWZ1bmN0aW9uIFhpKGUsdCxuKXtyZXR1cm4gZVswXT10WzBdKm4sZVsxXT10WzFdKm4sZX1mdW5jdGlvbiBHaShlLHQsbixyKXtyZXR1cm4gZVswXT10WzBdK25bMF0qcixlWzFdPXRbMV0rblsxXSpyLGV9ZnVuY3Rpb24gamkoZSx0KXtjb25zdCBuPXRbMF0tZVswXSxyPXRbMV0tZVsxXTtyZXR1cm4gTWF0aC5zcXJ0KG4qbityKnIpfWZ1bmN0aW9uIHNuKGUsdCl7Y29uc3Qgbj10WzBdLWVbMF0scj10WzFdLWVbMV07cmV0dXJuIG4qbityKnJ9ZnVuY3Rpb24gUWkoZSl7Y29uc3QgdD1lWzBdLG49ZVsxXTtyZXR1cm4gTWF0aC5zcXJ0KHQqdCtuKm4pfWZ1bmN0aW9uIEtpKGUpe2NvbnN0IHQ9ZVswXSxuPWVbMV07cmV0dXJuIHQqdCtuKm59ZnVuY3Rpb24gZ2woZSx0KXtyZXR1cm4gZVswXT0tdFswXSxlWzFdPS10WzFdLGV9ZnVuY3Rpb24gaXIoZSx0KXtyZXR1cm4gZVswXT0xL3RbMF0sZVsxXT0xL3RbMV0sZX1mdW5jdGlvbiBtbChlLHQpe2NvbnN0IG49dFswXSxyPXRbMV07bGV0IGk9bipuK3IqcjtyZXR1cm4gaT4wJiYoaT0xL01hdGguc3FydChpKSksZVswXT10WzBdKmksZVsxXT10WzFdKmksZX1mdW5jdGlvbiBwbChlLHQpe3JldHVybiBlWzBdKnRbMF0rZVsxXSp0WzFdfWZ1bmN0aW9uIG9lKGUsdCxuKXtjb25zdCByPXRbMF0qblsxXS10WzFdKm5bMF07cmV0dXJuIGVbMF09ZVsxXT0wLGVbMl09cixlfWZ1bmN0aW9uIEhpKGUsdCxuLHIpe2NvbnN0IGk9dFswXSxzPXRbMV07cmV0dXJuIGVbMF09aStyKihuWzBdLWkpLGVbMV09cytyKihuWzFdLXMpLGV9ZnVuY3Rpb24gX2woZSx0KXt0PXQ9PT12b2lkIDA/MTp0O2NvbnN0IG49anQoKSoyKk1hdGguUEk7cmV0dXJuIGVbMF09TWF0aC5jb3MobikqdCxlWzFdPU1hdGguc2luKG4pKnQsZX1mdW5jdGlvbiBJZShlLHQsbil7Y29uc3Qgcj10WzBdLGk9dFsxXTtyZXR1cm4gZVswXT1uWzBdKnIrblsyXSppLGVbMV09blsxXSpyK25bM10qaSxlfWZ1bmN0aW9uIEppKGUsdCxuKXtjb25zdCByPXRbMF0saT10WzFdO3JldHVybiBlWzBdPW5bMF0qcituWzJdKmkrbls0XSxlWzFdPW5bMV0qcituWzNdKmkrbls1XSxlfWZ1bmN0aW9uIHNyKGUsdCxuKXtjb25zdCByPXRbMF0saT10WzFdO3JldHVybiBlWzBdPW5bMF0qcituWzNdKmkrbls2XSxlWzFdPW5bMV0qcituWzRdKmkrbls3XSxlfWZ1bmN0aW9uIG9yKGUsdCxuKXtjb25zdCByPXRbMF0saT10WzFdO3JldHVybiBlWzBdPW5bMF0qcituWzRdKmkrblsxMl0sZVsxXT1uWzFdKnIrbls1XSppK25bMTNdLGV9ZnVuY3Rpb24geWwoZSx0LG4scil7Y29uc3QgaT10WzBdLW5bMF0scz10WzFdLW5bMV0sbz1NYXRoLnNpbihyKSxjPU1hdGguY29zKHIpO3JldHVybiBlWzBdPWkqYy1zKm8rblswXSxlWzFdPWkqbytzKmMrblsxXSxlfWZ1bmN0aW9uIHhsKGUsdCl7Y29uc3Qgbj1lWzBdLHI9ZVsxXSxpPXRbMF0scz10WzFdLG89TWF0aC5zcXJ0KChuKm4rcipyKSooaSppK3MqcykpLGM9byYmKG4qaStyKnMpL287cmV0dXJuIE1hdGguYWNvcyhNYXRoLm1pbihNYXRoLm1heChjLC0xKSwxKSl9ZnVuY3Rpb24gTWwoZSl7cmV0dXJuIGVbMF09MCxlWzFdPTAsZX1mdW5jdGlvbiB3bChlKXtyZXR1cm5gdmVjMigke2VbMF19LCAke2VbMV19KWB9ZnVuY3Rpb24gVGwoZSx0KXtyZXR1cm4gZVswXT09PXRbMF0mJmVbMV09PT10WzFdfWZ1bmN0aW9uIG9uKGUsdCl7Y29uc3Qgbj1lWzBdLHI9ZVsxXSxpPXRbMF0scz10WzFdO3JldHVybiBNYXRoLmFicyhuLWkpPD1JKk1hdGgubWF4KDEsTWF0aC5hYnMobiksTWF0aC5hYnMoaSkpJiZNYXRoLmFicyhyLXMpPD1JKk1hdGgubWF4KDEsTWF0aC5hYnMociksTWF0aC5hYnMocykpfWNvbnN0IEFsPVFpLE9sPVEsdmw9WmksRWw9cnIsYmw9amksU2w9c24sSWw9S2ksUGw9ZnVuY3Rpb24oKXtjb25zdCBlPVlpKCk7cmV0dXJuIGZ1bmN0aW9uKHQsbixyLGkscyxvKXtsZXQgYyxhO2ZvcihufHwobj0yKSxyfHwocj0wKSxpP2E9TWF0aC5taW4oaSpuK3IsdC5sZW5ndGgpOmE9dC5sZW5ndGgsYz1yO2M8YTtjKz1uKWVbMF09dFtjXSxlWzFdPXRbYysxXSxzKGUsZSxvKSx0W2NdPWVbMF0sdFtjKzFdPWVbMV07cmV0dXJuIHR9fSgpO3ZhciBMbD1PYmplY3QuZnJlZXplKHtfX3Byb3RvX186bnVsbCxhZGQ6V2ksYW5nbGU6eGwsY2VpbDpsbCxjbG9uZTpzbCxjb3B5OmNsLGNyZWF0ZTpZaSxjcm9zczpvZSxkaXN0OmJsLGRpc3RhbmNlOmppLGRpdjpFbCxkaXZpZGU6cnIsZG90OnBsLGVxdWFsczpvbixleGFjdEVxdWFsczpUbCxmbG9vcjpobCxmb3JFYWNoOlBsLGZyb21WYWx1ZXM6b2wsaW52ZXJzZTppcixsZW46QWwsbGVuZ3RoOlFpLGxlcnA6SGksbWF4OnVsLG1pbjpmbCxtdWw6dmwsbXVsdGlwbHk6WmksbmVnYXRlOmdsLG5vcm1hbGl6ZTptbCxyYW5kb206X2wscm90YXRlOnlsLHJvdW5kOmRsLHNjYWxlOlhpLHNjYWxlQW5kQWRkOkdpLHNldDphbCxzcXJEaXN0OlNsLHNxckxlbjpJbCxzcXVhcmVkRGlzdGFuY2U6c24sc3F1YXJlZExlbmd0aDpLaSxzdHI6d2wsc3ViOk9sLHN1YnRyYWN0OlEsdHJhbnNmb3JtTWF0MjpJZSx0cmFuc2Zvcm1NYXQyZDpKaSx0cmFuc2Zvcm1NYXQzOnNyLHRyYW5zZm9ybU1hdDQ6b3IsemVybzpNbH0pO2Z1bmN0aW9uIGNyKGUsdCxuKXtjb25zdCByPXRbMF0saT10WzFdLHM9blszXSpyK25bN10qaXx8MTtyZXR1cm4gZVswXT0oblswXSpyK25bNF0qaSkvcyxlWzFdPShuWzFdKnIrbls1XSppKS9zLGV9ZnVuY3Rpb24gYXIoZSx0LG4pe2NvbnN0IHI9dFswXSxpPXRbMV0scz10WzJdLG89blszXSpyK25bN10qaStuWzExXSpzfHwxO3JldHVybiBlWzBdPShuWzBdKnIrbls0XSppK25bOF0qcykvbyxlWzFdPShuWzFdKnIrbls1XSppK25bOV0qcykvbyxlWzJdPShuWzJdKnIrbls2XSppK25bMTBdKnMpL28sZX1mdW5jdGlvbiB0cyhlLHQsbil7Y29uc3Qgcj10WzBdLGk9dFsxXTtyZXR1cm4gZVswXT1uWzBdKnIrblsyXSppLGVbMV09blsxXSpyK25bM10qaSxlWzJdPXRbMl0sZX1mdW5jdGlvbiBlcyhlLHQsbil7Y29uc3Qgcj10WzBdLGk9dFsxXTtyZXR1cm4gZVswXT1uWzBdKnIrblsyXSppLGVbMV09blsxXSpyK25bM10qaSxlWzJdPXRbMl0sZVszXT10WzNdLGV9ZnVuY3Rpb24gbHIoZSx0LG4pe2NvbnN0IHI9dFswXSxpPXRbMV0scz10WzJdO3JldHVybiBlWzBdPW5bMF0qcituWzNdKmkrbls2XSpzLGVbMV09blsxXSpyK25bNF0qaStuWzddKnMsZVsyXT1uWzJdKnIrbls1XSppK25bOF0qcyxlWzNdPXRbM10sZX1jbGFzcyBLIGV4dGVuZHMgcm57Y29uc3RydWN0b3IodD0wLG49MCl7c3VwZXIoMiksWnQodCkmJmFyZ3VtZW50cy5sZW5ndGg9PT0xP3RoaXMuY29weSh0KTooRy5kZWJ1ZyYmKCQodCksJChuKSksdGhpc1swXT10LHRoaXNbMV09bil9c2V0KHQsbil7cmV0dXJuIHRoaXNbMF09dCx0aGlzWzFdPW4sdGhpcy5jaGVjaygpfWNvcHkodCl7cmV0dXJuIHRoaXNbMF09dFswXSx0aGlzWzFdPXRbMV0sdGhpcy5jaGVjaygpfWZyb21PYmplY3QodCl7cmV0dXJuIEcuZGVidWcmJigkKHQueCksJCh0LnkpKSx0aGlzWzBdPXQueCx0aGlzWzFdPXQueSx0aGlzLmNoZWNrKCl9dG9PYmplY3QodCl7cmV0dXJuIHQueD10aGlzWzBdLHQueT10aGlzWzFdLHR9Z2V0IEVMRU1FTlRTKCl7cmV0dXJuIDJ9aG9yaXpvbnRhbEFuZ2xlKCl7cmV0dXJuIE1hdGguYXRhbjIodGhpcy55LHRoaXMueCl9dmVydGljYWxBbmdsZSgpe3JldHVybiBNYXRoLmF0YW4yKHRoaXMueCx0aGlzLnkpfXRyYW5zZm9ybSh0KXtyZXR1cm4gdGhpcy50cmFuc2Zvcm1Bc1BvaW50KHQpfXRyYW5zZm9ybUFzUG9pbnQodCl7cmV0dXJuIG9yKHRoaXMsdGhpcyx0KSx0aGlzLmNoZWNrKCl9dHJhbnNmb3JtQXNWZWN0b3IodCl7cmV0dXJuIGNyKHRoaXMsdGhpcyx0KSx0aGlzLmNoZWNrKCl9dHJhbnNmb3JtQnlNYXRyaXgzKHQpe3JldHVybiBzcih0aGlzLHRoaXMsdCksdGhpcy5jaGVjaygpfXRyYW5zZm9ybUJ5TWF0cml4MngzKHQpe3JldHVybiBKaSh0aGlzLHRoaXMsdCksdGhpcy5jaGVjaygpfXRyYW5zZm9ybUJ5TWF0cml4Mih0KXtyZXR1cm4gSWUodGhpcyx0aGlzLHQpLHRoaXMuY2hlY2soKX19ZnVuY3Rpb24gaHIoKXtjb25zdCBlPW5ldyBDKDMpO3JldHVybiBDIT1GbG9hdDMyQXJyYXkmJihlWzBdPTAsZVsxXT0wLGVbMl09MCksZX1mdW5jdGlvbiBSbChlKXtjb25zdCB0PW5ldyBDKDMpO3JldHVybiB0WzBdPWVbMF0sdFsxXT1lWzFdLHRbMl09ZVsyXSx0fWZ1bmN0aW9uIGNuKGUpe2NvbnN0IHQ9ZVswXSxuPWVbMV0scj1lWzJdO3JldHVybiBNYXRoLnNxcnQodCp0K24qbityKnIpfWZ1bmN0aW9uIGZyKGUsdCxuKXtjb25zdCByPW5ldyBDKDMpO3JldHVybiByWzBdPWUsclsxXT10LHJbMl09bixyfWZ1bmN0aW9uICRsKGUsdCl7cmV0dXJuIGVbMF09dFswXSxlWzFdPXRbMV0sZVsyXT10WzJdLGV9ZnVuY3Rpb24gQ2woZSx0LG4scil7cmV0dXJuIGVbMF09dCxlWzFdPW4sZVsyXT1yLGV9ZnVuY3Rpb24gbnMoZSx0LG4pe3JldHVybiBlWzBdPXRbMF0rblswXSxlWzFdPXRbMV0rblsxXSxlWzJdPXRbMl0rblsyXSxlfWZ1bmN0aW9uIHVyKGUsdCxuKXtyZXR1cm4gZVswXT10WzBdLW5bMF0sZVsxXT10WzFdLW5bMV0sZVsyXT10WzJdLW5bMl0sZX1mdW5jdGlvbiBkcihlLHQsbil7cmV0dXJuIGVbMF09dFswXSpuWzBdLGVbMV09dFsxXSpuWzFdLGVbMl09dFsyXSpuWzJdLGV9ZnVuY3Rpb24gcnMoZSx0LG4pe3JldHVybiBlWzBdPXRbMF0vblswXSxlWzFdPXRbMV0vblsxXSxlWzJdPXRbMl0vblsyXSxlfWZ1bmN0aW9uIFZsKGUsdCl7cmV0dXJuIGVbMF09TWF0aC5jZWlsKHRbMF0pLGVbMV09TWF0aC5jZWlsKHRbMV0pLGVbMl09TWF0aC5jZWlsKHRbMl0pLGV9ZnVuY3Rpb24gTmwoZSx0KXtyZXR1cm4gZVswXT1NYXRoLmZsb29yKHRbMF0pLGVbMV09TWF0aC5mbG9vcih0WzFdKSxlWzJdPU1hdGguZmxvb3IodFsyXSksZX1mdW5jdGlvbiB6bChlLHQsbil7cmV0dXJuIGVbMF09TWF0aC5taW4odFswXSxuWzBdKSxlWzFdPU1hdGgubWluKHRbMV0sblsxXSksZVsyXT1NYXRoLm1pbih0WzJdLG5bMl0pLGV9ZnVuY3Rpb24gcWwoZSx0LG4pe3JldHVybiBlWzBdPU1hdGgubWF4KHRbMF0sblswXSksZVsxXT1NYXRoLm1heCh0WzFdLG5bMV0pLGVbMl09TWF0aC5tYXgodFsyXSxuWzJdKSxlfWZ1bmN0aW9uIEZsKGUsdCl7cmV0dXJuIGVbMF09YnQodFswXSksZVsxXT1idCh0WzFdKSxlWzJdPWJ0KHRbMl0pLGV9ZnVuY3Rpb24gaXMoZSx0LG4pe3JldHVybiBlWzBdPXRbMF0qbixlWzFdPXRbMV0qbixlWzJdPXRbMl0qbixlfWZ1bmN0aW9uIGtsKGUsdCxuLHIpe3JldHVybiBlWzBdPXRbMF0rblswXSpyLGVbMV09dFsxXStuWzFdKnIsZVsyXT10WzJdK25bMl0qcixlfWZ1bmN0aW9uIGdyKGUsdCl7Y29uc3Qgbj10WzBdLWVbMF0scj10WzFdLWVbMV0saT10WzJdLWVbMl07cmV0dXJuIE1hdGguc3FydChuKm4rcipyK2kqaSl9ZnVuY3Rpb24gc3MoZSx0KXtjb25zdCBuPXRbMF0tZVswXSxyPXRbMV0tZVsxXSxpPXRbMl0tZVsyXTtyZXR1cm4gbipuK3IqcitpKml9ZnVuY3Rpb24gYW4oZSl7Y29uc3QgdD1lWzBdLG49ZVsxXSxyPWVbMl07cmV0dXJuIHQqdCtuKm4rcipyfWZ1bmN0aW9uIGxuKGUsdCl7cmV0dXJuIGVbMF09LXRbMF0sZVsxXT0tdFsxXSxlWzJdPS10WzJdLGV9ZnVuY3Rpb24gbXIoZSx0KXtyZXR1cm4gZVswXT0xL3RbMF0sZVsxXT0xL3RbMV0sZVsyXT0xL3RbMl0sZX1mdW5jdGlvbiAkdChlLHQpe2NvbnN0IG49dFswXSxyPXRbMV0saT10WzJdO2xldCBzPW4qbityKnIraSppO3JldHVybiBzPjAmJihzPTEvTWF0aC5zcXJ0KHMpKSxlWzBdPXRbMF0qcyxlWzFdPXRbMV0qcyxlWzJdPXRbMl0qcyxlfWZ1bmN0aW9uIFBlKGUsdCl7cmV0dXJuIGVbMF0qdFswXStlWzFdKnRbMV0rZVsyXSp0WzJdfWZ1bmN0aW9uIHN0KGUsdCxuKXtjb25zdCByPXRbMF0saT10WzFdLHM9dFsyXSxvPW5bMF0sYz1uWzFdLGE9blsyXTtyZXR1cm4gZVswXT1pKmEtcypjLGVbMV09cypvLXIqYSxlWzJdPXIqYy1pKm8sZX1mdW5jdGlvbiBCbChlLHQsbixyKXtjb25zdCBpPXRbMF0scz10WzFdLG89dFsyXTtyZXR1cm4gZVswXT1pK3IqKG5bMF0taSksZVsxXT1zK3IqKG5bMV0tcyksZVsyXT1vK3IqKG5bMl0tbyksZX1mdW5jdGlvbiBVbChlLHQsbixyKXtjb25zdCBpPU1hdGguYWNvcyhNYXRoLm1pbihNYXRoLm1heChQZSh0LG4pLC0xKSwxKSkscz1NYXRoLnNpbihpKSxvPU1hdGguc2luKCgxLXIpKmkpL3MsYz1NYXRoLnNpbihyKmkpL3M7cmV0dXJuIGVbMF09byp0WzBdK2MqblswXSxlWzFdPW8qdFsxXStjKm5bMV0sZVsyXT1vKnRbMl0rYypuWzJdLGV9ZnVuY3Rpb24gRGwoZSx0LG4scixpLHMpe2NvbnN0IG89cypzLGM9byooMipzLTMpKzEsYT1vKihzLTIpK3MsaD1vKihzLTEpLGY9byooMy0yKnMpO3JldHVybiBlWzBdPXRbMF0qYytuWzBdKmErclswXSpoK2lbMF0qZixlWzFdPXRbMV0qYytuWzFdKmErclsxXSpoK2lbMV0qZixlWzJdPXRbMl0qYytuWzJdKmErclsyXSpoK2lbMl0qZixlfWZ1bmN0aW9uIFlsKGUsdCxuLHIsaSxzKXtjb25zdCBvPTEtcyxjPW8qbyxhPXMqcyxoPWMqbyxmPTMqcypjLHU9MyphKm8sZD1hKnM7cmV0dXJuIGVbMF09dFswXSpoK25bMF0qZityWzBdKnUraVswXSpkLGVbMV09dFsxXSpoK25bMV0qZityWzFdKnUraVsxXSpkLGVbMl09dFsyXSpoK25bMl0qZityWzJdKnUraVsyXSpkLGV9ZnVuY3Rpb24gV2woZSx0KXt0PXQ9PT12b2lkIDA/MTp0O2NvbnN0IG49anQoKSoyKk1hdGguUEkscj1qdCgpKjItMSxpPU1hdGguc3FydCgxLXIqcikqdDtyZXR1cm4gZVswXT1NYXRoLmNvcyhuKSppLGVbMV09TWF0aC5zaW4obikqaSxlWzJdPXIqdCxlfWZ1bmN0aW9uIGhuKGUsdCxuKXtjb25zdCByPXRbMF0saT10WzFdLHM9dFsyXTtsZXQgbz1uWzNdKnIrbls3XSppK25bMTFdKnMrblsxNV07cmV0dXJuIG89b3x8MSxlWzBdPShuWzBdKnIrbls0XSppK25bOF0qcytuWzEyXSkvbyxlWzFdPShuWzFdKnIrbls1XSppK25bOV0qcytuWzEzXSkvbyxlWzJdPShuWzJdKnIrbls2XSppK25bMTBdKnMrblsxNF0pL28sZX1mdW5jdGlvbiBRdChlLHQsbil7Y29uc3Qgcj10WzBdLGk9dFsxXSxzPXRbMl07cmV0dXJuIGVbMF09cipuWzBdK2kqblszXStzKm5bNl0sZVsxXT1yKm5bMV0raSpuWzRdK3Mqbls3XSxlWzJdPXIqblsyXStpKm5bNV0rcypuWzhdLGV9ZnVuY3Rpb24gY2UoZSx0LG4pe2NvbnN0IHI9blswXSxpPW5bMV0scz1uWzJdLG89blszXSxjPXRbMF0sYT10WzFdLGg9dFsyXTtsZXQgZj1pKmgtcyphLHU9cypjLXIqaCxkPXIqYS1pKmMsZz1pKmQtcyp1LG09cypmLXIqZCxfPXIqdS1pKmY7Y29uc3QgcD1vKjI7cmV0dXJuIGYqPXAsdSo9cCxkKj1wLGcqPTIsbSo9MixfKj0yLGVbMF09YytmK2csZVsxXT1hK3UrbSxlWzJdPWgrZCtfLGV9ZnVuY3Rpb24gb3MoZSx0LG4scil7Y29uc3QgaT1bXSxzPVtdO3JldHVybiBpWzBdPXRbMF0tblswXSxpWzFdPXRbMV0tblsxXSxpWzJdPXRbMl0tblsyXSxzWzBdPWlbMF0sc1sxXT1pWzFdKk1hdGguY29zKHIpLWlbMl0qTWF0aC5zaW4ociksc1syXT1pWzFdKk1hdGguc2luKHIpK2lbMl0qTWF0aC5jb3MociksZVswXT1zWzBdK25bMF0sZVsxXT1zWzFdK25bMV0sZVsyXT1zWzJdK25bMl0sZX1mdW5jdGlvbiBjcyhlLHQsbixyKXtjb25zdCBpPVtdLHM9W107cmV0dXJuIGlbMF09dFswXS1uWzBdLGlbMV09dFsxXS1uWzFdLGlbMl09dFsyXS1uWzJdLHNbMF09aVsyXSpNYXRoLnNpbihyKStpWzBdKk1hdGguY29zKHIpLHNbMV09aVsxXSxzWzJdPWlbMl0qTWF0aC5jb3MociktaVswXSpNYXRoLnNpbihyKSxlWzBdPXNbMF0rblswXSxlWzFdPXNbMV0rblsxXSxlWzJdPXNbMl0rblsyXSxlfWZ1bmN0aW9uIGFzKGUsdCxuLHIpe2NvbnN0IGk9W10scz1bXTtyZXR1cm4gaVswXT10WzBdLW5bMF0saVsxXT10WzFdLW5bMV0saVsyXT10WzJdLW5bMl0sc1swXT1pWzBdKk1hdGguY29zKHIpLWlbMV0qTWF0aC5zaW4ociksc1sxXT1pWzBdKk1hdGguc2luKHIpK2lbMV0qTWF0aC5jb3Mociksc1syXT1pWzJdLGVbMF09c1swXStuWzBdLGVbMV09c1sxXStuWzFdLGVbMl09c1syXStuWzJdLGV9ZnVuY3Rpb24gbHMoZSx0KXtjb25zdCBuPWVbMF0scj1lWzFdLGk9ZVsyXSxzPXRbMF0sbz10WzFdLGM9dFsyXSxhPU1hdGguc3FydCgobipuK3IqcitpKmkpKihzKnMrbypvK2MqYykpLGg9YSYmUGUoZSx0KS9hO3JldHVybiBNYXRoLmFjb3MoTWF0aC5taW4oTWF0aC5tYXgoaCwtMSksMSkpfWZ1bmN0aW9uIFpsKGUpe3JldHVybiBlWzBdPTAsZVsxXT0wLGVbMl09MCxlfWZ1bmN0aW9uIFhsKGUpe3JldHVybmB2ZWMzKCR7ZVswXX0sICR7ZVsxXX0sICR7ZVsyXX0pYH1mdW5jdGlvbiBHbChlLHQpe3JldHVybiBlWzBdPT09dFswXSYmZVsxXT09PXRbMV0mJmVbMl09PT10WzJdfWZ1bmN0aW9uIGpsKGUsdCl7Y29uc3Qgbj1lWzBdLHI9ZVsxXSxpPWVbMl0scz10WzBdLG89dFsxXSxjPXRbMl07cmV0dXJuIE1hdGguYWJzKG4tcyk8PUkqTWF0aC5tYXgoMSxNYXRoLmFicyhuKSxNYXRoLmFicyhzKSkmJk1hdGguYWJzKHItbyk8PUkqTWF0aC5tYXgoMSxNYXRoLmFicyhyKSxNYXRoLmFicyhvKSkmJk1hdGguYWJzKGktYyk8PUkqTWF0aC5tYXgoMSxNYXRoLmFicyhpKSxNYXRoLmFicyhjKSl9Y29uc3QgUWw9dXIsS2w9ZHIsSGw9cnMsSmw9Z3IsdGg9c3MsaHM9Y24sZWg9YW4sbmg9ZnVuY3Rpb24oKXtjb25zdCBlPWhyKCk7cmV0dXJuIGZ1bmN0aW9uKHQsbixyLGkscyxvKXtsZXQgYyxhO2ZvcihufHwobj0zKSxyfHwocj0wKSxpP2E9TWF0aC5taW4oaSpuK3IsdC5sZW5ndGgpOmE9dC5sZW5ndGgsYz1yO2M8YTtjKz1uKWVbMF09dFtjXSxlWzFdPXRbYysxXSxlWzJdPXRbYysyXSxzKGUsZSxvKSx0W2NdPWVbMF0sdFtjKzFdPWVbMV0sdFtjKzJdPWVbMl07cmV0dXJuIHR9fSgpO3ZhciByaD1PYmplY3QuZnJlZXplKHtfX3Byb3RvX186bnVsbCxhZGQ6bnMsYW5nbGU6bHMsYmV6aWVyOllsLGNlaWw6VmwsY2xvbmU6UmwsY29weTokbCxjcmVhdGU6aHIsY3Jvc3M6c3QsZGlzdDpKbCxkaXN0YW5jZTpncixkaXY6SGwsZGl2aWRlOnJzLGRvdDpQZSxlcXVhbHM6amwsZXhhY3RFcXVhbHM6R2wsZmxvb3I6TmwsZm9yRWFjaDpuaCxmcm9tVmFsdWVzOmZyLGhlcm1pdGU6RGwsaW52ZXJzZTptcixsZW46aHMsbGVuZ3RoOmNuLGxlcnA6QmwsbWF4OnFsLG1pbjp6bCxtdWw6S2wsbXVsdGlwbHk6ZHIsbmVnYXRlOmxuLG5vcm1hbGl6ZTokdCxyYW5kb206V2wscm90YXRlWDpvcyxyb3RhdGVZOmNzLHJvdGF0ZVo6YXMscm91bmQ6Rmwsc2NhbGU6aXMsc2NhbGVBbmRBZGQ6a2wsc2V0OkNsLHNsZXJwOlVsLHNxckRpc3Q6dGgsc3FyTGVuOmVoLHNxdWFyZWREaXN0YW5jZTpzcyxzcXVhcmVkTGVuZ3RoOmFuLHN0cjpYbCxzdWI6UWwsc3VidHJhY3Q6dXIsdHJhbnNmb3JtTWF0MzpRdCx0cmFuc2Zvcm1NYXQ0OmhuLHRyYW5zZm9ybVF1YXQ6Y2UsemVybzpabH0pO2NvbnN0IHByPVswLDAsMF07bGV0IGZuO2NsYXNzIEwgZXh0ZW5kcyBybntzdGF0aWMgZ2V0IFpFUk8oKXtyZXR1cm4gZm58fChmbj1uZXcgTCgwLDAsMCksT2JqZWN0LmZyZWV6ZShmbikpLGZufWNvbnN0cnVjdG9yKHQ9MCxuPTAscj0wKXtzdXBlcigtMCwtMCwtMCksYXJndW1lbnRzLmxlbmd0aD09PTEmJlp0KHQpP3RoaXMuY29weSh0KTooRy5kZWJ1ZyYmKCQodCksJChuKSwkKHIpKSx0aGlzWzBdPXQsdGhpc1sxXT1uLHRoaXNbMl09cil9c2V0KHQsbixyKXtyZXR1cm4gdGhpc1swXT10LHRoaXNbMV09bix0aGlzWzJdPXIsdGhpcy5jaGVjaygpfWNvcHkodCl7cmV0dXJuIHRoaXNbMF09dFswXSx0aGlzWzFdPXRbMV0sdGhpc1syXT10WzJdLHRoaXMuY2hlY2soKX1mcm9tT2JqZWN0KHQpe3JldHVybiBHLmRlYnVnJiYoJCh0LngpLCQodC55KSwkKHQueikpLHRoaXNbMF09dC54LHRoaXNbMV09dC55LHRoaXNbMl09dC56LHRoaXMuY2hlY2soKX10b09iamVjdCh0KXtyZXR1cm4gdC54PXRoaXNbMF0sdC55PXRoaXNbMV0sdC56PXRoaXNbMl0sdH1nZXQgRUxFTUVOVFMoKXtyZXR1cm4gM31nZXQgeigpe3JldHVybiB0aGlzWzJdfXNldCB6KHQpe3RoaXNbMl09JCh0KX1hbmdsZSh0KXtyZXR1cm4gbHModGhpcyx0KX1jcm9zcyh0KXtyZXR1cm4gc3QodGhpcyx0aGlzLHQpLHRoaXMuY2hlY2soKX1yb3RhdGVYKHtyYWRpYW5zOnQsb3JpZ2luOm49cHJ9KXtyZXR1cm4gb3ModGhpcyx0aGlzLG4sdCksdGhpcy5jaGVjaygpfXJvdGF0ZVkoe3JhZGlhbnM6dCxvcmlnaW46bj1wcn0pe3JldHVybiBjcyh0aGlzLHRoaXMsbix0KSx0aGlzLmNoZWNrKCl9cm90YXRlWih7cmFkaWFuczp0LG9yaWdpbjpuPXByfSl7cmV0dXJuIGFzKHRoaXMsdGhpcyxuLHQpLHRoaXMuY2hlY2soKX10cmFuc2Zvcm0odCl7cmV0dXJuIHRoaXMudHJhbnNmb3JtQXNQb2ludCh0KX10cmFuc2Zvcm1Bc1BvaW50KHQpe3JldHVybiBobih0aGlzLHRoaXMsdCksdGhpcy5jaGVjaygpfXRyYW5zZm9ybUFzVmVjdG9yKHQpe3JldHVybiBhcih0aGlzLHRoaXMsdCksdGhpcy5jaGVjaygpfXRyYW5zZm9ybUJ5TWF0cml4Myh0KXtyZXR1cm4gUXQodGhpcyx0aGlzLHQpLHRoaXMuY2hlY2soKX10cmFuc2Zvcm1CeU1hdHJpeDIodCl7cmV0dXJuIHRzKHRoaXMsdGhpcyx0KSx0aGlzLmNoZWNrKCl9dHJhbnNmb3JtQnlRdWF0ZXJuaW9uKHQpe3JldHVybiBjZSh0aGlzLHRoaXMsdCksdGhpcy5jaGVjaygpfX1sZXQgdW47Y2xhc3MgeXQgZXh0ZW5kcyBybntzdGF0aWMgZ2V0IFpFUk8oKXtyZXR1cm4gdW58fCh1bj1uZXcgeXQoMCwwLDAsMCksT2JqZWN0LmZyZWV6ZSh1bikpLHVufWNvbnN0cnVjdG9yKHQ9MCxuPTAscj0wLGk9MCl7c3VwZXIoLTAsLTAsLTAsLTApLFp0KHQpJiZhcmd1bWVudHMubGVuZ3RoPT09MT90aGlzLmNvcHkodCk6KEcuZGVidWcmJigkKHQpLCQobiksJChyKSwkKGkpKSx0aGlzWzBdPXQsdGhpc1sxXT1uLHRoaXNbMl09cix0aGlzWzNdPWkpfXNldCh0LG4scixpKXtyZXR1cm4gdGhpc1swXT10LHRoaXNbMV09bix0aGlzWzJdPXIsdGhpc1szXT1pLHRoaXMuY2hlY2soKX1jb3B5KHQpe3JldHVybiB0aGlzWzBdPXRbMF0sdGhpc1sxXT10WzFdLHRoaXNbMl09dFsyXSx0aGlzWzNdPXRbM10sdGhpcy5jaGVjaygpfWZyb21PYmplY3QodCl7cmV0dXJuIEcuZGVidWcmJigkKHQueCksJCh0LnkpLCQodC56KSwkKHQudykpLHRoaXNbMF09dC54LHRoaXNbMV09dC55LHRoaXNbMl09dC56LHRoaXNbM109dC53LHRoaXN9dG9PYmplY3QodCl7cmV0dXJuIHQueD10aGlzWzBdLHQueT10aGlzWzFdLHQuej10aGlzWzJdLHQudz10aGlzWzNdLHR9Z2V0IEVMRU1FTlRTKCl7cmV0dXJuIDR9Z2V0IHooKXtyZXR1cm4gdGhpc1syXX1zZXQgeih0KXt0aGlzWzJdPSQodCl9Z2V0IHcoKXtyZXR1cm4gdGhpc1szXX1zZXQgdyh0KXt0aGlzWzNdPSQodCl9dHJhbnNmb3JtKHQpe3JldHVybiBobih0aGlzLHRoaXMsdCksdGhpcy5jaGVjaygpfXRyYW5zZm9ybUJ5TWF0cml4Myh0KXtyZXR1cm4gbHIodGhpcyx0aGlzLHQpLHRoaXMuY2hlY2soKX10cmFuc2Zvcm1CeU1hdHJpeDIodCl7cmV0dXJuIGVzKHRoaXMsdGhpcyx0KSx0aGlzLmNoZWNrKCl9dHJhbnNmb3JtQnlRdWF0ZXJuaW9uKHQpe3JldHVybiBjZSh0aGlzLHRoaXMsdCksdGhpcy5jaGVjaygpfWFwcGx5TWF0cml4NCh0KXtyZXR1cm4gdC50cmFuc2Zvcm0odGhpcyx0aGlzKSx0aGlzfX1sZXQgZG49Y2xhc3MgZXh0ZW5kcyBTZXt0b1N0cmluZygpe2xldCB0PSJbIjtpZihHLnByaW50Um93TWFqb3Ipe3QrPSJyb3ctbWFqb3I6Ijtmb3IobGV0IG49MDtuPHRoaXMuUkFOSzsrK24pZm9yKGxldCByPTA7cjx0aGlzLlJBTks7KytyKXQrPWAgJHt0aGlzW3IqdGhpcy5SQU5LK25dfWB9ZWxzZXt0Kz0iY29sdW1uLW1ham9yOiI7Zm9yKGxldCBuPTA7bjx0aGlzLkVMRU1FTlRTOysrbil0Kz1gICR7dGhpc1tuXX1gfXJldHVybiB0Kz0iXSIsdH1nZXRFbGVtZW50SW5kZXgodCxuKXtyZXR1cm4gbip0aGlzLlJBTksrdH1nZXRFbGVtZW50KHQsbil7cmV0dXJuIHRoaXNbbip0aGlzLlJBTksrdF19c2V0RWxlbWVudCh0LG4scil7cmV0dXJuIHRoaXNbbip0aGlzLlJBTksrdF09JChyKSx0aGlzfWdldENvbHVtbih0LG49bmV3IEFycmF5KHRoaXMuUkFOSykuZmlsbCgtMCkpe2NvbnN0IHI9dCp0aGlzLlJBTks7Zm9yKGxldCBpPTA7aTx0aGlzLlJBTks7KytpKW5baV09dGhpc1tyK2ldO3JldHVybiBufXNldENvbHVtbih0LG4pe2NvbnN0IHI9dCp0aGlzLlJBTks7Zm9yKGxldCBpPTA7aTx0aGlzLlJBTks7KytpKXRoaXNbcitpXT1uW2ldO3JldHVybiB0aGlzfX07ZnVuY3Rpb24gZnMoKXtjb25zdCBlPW5ldyBDKDkpO3JldHVybiBDIT1GbG9hdDMyQXJyYXkmJihlWzFdPTAsZVsyXT0wLGVbM109MCxlWzVdPTAsZVs2XT0wLGVbN109MCksZVswXT0xLGVbNF09MSxlWzhdPTEsZX1mdW5jdGlvbiBfcihlLHQpe3JldHVybiBlWzBdPXRbMF0sZVsxXT10WzFdLGVbMl09dFsyXSxlWzNdPXRbNF0sZVs0XT10WzVdLGVbNV09dFs2XSxlWzZdPXRbOF0sZVs3XT10WzldLGVbOF09dFsxMF0sZX1mdW5jdGlvbiBpaChlKXtjb25zdCB0PW5ldyBDKDkpO3JldHVybiB0WzBdPWVbMF0sdFsxXT1lWzFdLHRbMl09ZVsyXSx0WzNdPWVbM10sdFs0XT1lWzRdLHRbNV09ZVs1XSx0WzZdPWVbNl0sdFs3XT1lWzddLHRbOF09ZVs4XSx0fWZ1bmN0aW9uIHNoKGUsdCl7cmV0dXJuIGVbMF09dFswXSxlWzFdPXRbMV0sZVsyXT10WzJdLGVbM109dFszXSxlWzRdPXRbNF0sZVs1XT10WzVdLGVbNl09dFs2XSxlWzddPXRbN10sZVs4XT10WzhdLGV9ZnVuY3Rpb24gb2goZSx0LG4scixpLHMsbyxjLGEpe2NvbnN0IGg9bmV3IEMoOSk7cmV0dXJuIGhbMF09ZSxoWzFdPXQsaFsyXT1uLGhbM109cixoWzRdPWksaFs1XT1zLGhbNl09byxoWzddPWMsaFs4XT1hLGh9ZnVuY3Rpb24gdXMoZSx0LG4scixpLHMsbyxjLGEsaCl7cmV0dXJuIGVbMF09dCxlWzFdPW4sZVsyXT1yLGVbM109aSxlWzRdPXMsZVs1XT1vLGVbNl09YyxlWzddPWEsZVs4XT1oLGV9ZnVuY3Rpb24gY2goZSl7cmV0dXJuIGVbMF09MSxlWzFdPTAsZVsyXT0wLGVbM109MCxlWzRdPTEsZVs1XT0wLGVbNl09MCxlWzddPTAsZVs4XT0xLGV9ZnVuY3Rpb24geXIoZSx0KXtpZihlPT09dCl7Y29uc3Qgbj10WzFdLHI9dFsyXSxpPXRbNV07ZVsxXT10WzNdLGVbMl09dFs2XSxlWzNdPW4sZVs1XT10WzddLGVbNl09cixlWzddPWl9ZWxzZSBlWzBdPXRbMF0sZVsxXT10WzNdLGVbMl09dFs2XSxlWzNdPXRbMV0sZVs0XT10WzRdLGVbNV09dFs3XSxlWzZdPXRbMl0sZVs3XT10WzVdLGVbOF09dFs4XTtyZXR1cm4gZX1mdW5jdGlvbiBnbihlLHQpe2NvbnN0IG49dFswXSxyPXRbMV0saT10WzJdLHM9dFszXSxvPXRbNF0sYz10WzVdLGE9dFs2XSxoPXRbN10sZj10WzhdLHU9ZipvLWMqaCxkPS1mKnMrYyphLGc9aCpzLW8qYTtsZXQgbT1uKnUrcipkK2kqZztyZXR1cm4gbT8obT0xL20sZVswXT11Km0sZVsxXT0oLWYqcitpKmgpKm0sZVsyXT0oYypyLWkqbykqbSxlWzNdPWQqbSxlWzRdPShmKm4taSphKSptLGVbNV09KC1jKm4raSpzKSptLGVbNl09ZyptLGVbN109KC1oKm4rciphKSptLGVbOF09KG8qbi1yKnMpKm0sZSk6bnVsbH1mdW5jdGlvbiBhaChlLHQpe2NvbnN0IG49dFswXSxyPXRbMV0saT10WzJdLHM9dFszXSxvPXRbNF0sYz10WzVdLGE9dFs2XSxoPXRbN10sZj10WzhdO3JldHVybiBlWzBdPW8qZi1jKmgsZVsxXT1pKmgtcipmLGVbMl09cipjLWkqbyxlWzNdPWMqYS1zKmYsZVs0XT1uKmYtaSphLGVbNV09aSpzLW4qYyxlWzZdPXMqaC1vKmEsZVs3XT1yKmEtbipoLGVbOF09bipvLXIqcyxlfWZ1bmN0aW9uIEt0KGUpe2NvbnN0IHQ9ZVswXSxuPWVbMV0scj1lWzJdLGk9ZVszXSxzPWVbNF0sbz1lWzVdLGM9ZVs2XSxhPWVbN10saD1lWzhdO3JldHVybiB0KihoKnMtbyphKStuKigtaCppK28qYykrciooYSppLXMqYyl9ZnVuY3Rpb24gbW4oZSx0LG4pe2NvbnN0IHI9dFswXSxpPXRbMV0scz10WzJdLG89dFszXSxjPXRbNF0sYT10WzVdLGg9dFs2XSxmPXRbN10sdT10WzhdLGQ9blswXSxnPW5bMV0sbT1uWzJdLF89blszXSxwPW5bNF0seD1uWzVdLFQ9bls2XSxNPW5bN10sQT1uWzhdO3JldHVybiBlWzBdPWQqcitnKm8rbSpoLGVbMV09ZCppK2cqYyttKmYsZVsyXT1kKnMrZyphK20qdSxlWzNdPV8qcitwKm8reCpoLGVbNF09XyppK3AqYyt4KmYsZVs1XT1fKnMrcCphK3gqdSxlWzZdPVQqcitNKm8rQSpoLGVbN109VCppK00qYytBKmYsZVs4XT1UKnMrTSphK0EqdSxlfWZ1bmN0aW9uIGRzKGUsdCxuKXtjb25zdCByPXRbMF0saT10WzFdLHM9dFsyXSxvPXRbM10sYz10WzRdLGE9dFs1XSxoPXRbNl0sZj10WzddLHU9dFs4XSxkPW5bMF0sZz1uWzFdO3JldHVybiBlWzBdPXIsZVsxXT1pLGVbMl09cyxlWzNdPW8sZVs0XT1jLGVbNV09YSxlWzZdPWQqcitnKm8raCxlWzddPWQqaStnKmMrZixlWzhdPWQqcytnKmErdSxlfWZ1bmN0aW9uIGdzKGUsdCxuKXtjb25zdCByPXRbMF0saT10WzFdLHM9dFsyXSxvPXRbM10sYz10WzRdLGE9dFs1XSxoPXRbNl0sZj10WzddLHU9dFs4XSxkPU1hdGguc2luKG4pLGc9TWF0aC5jb3Mobik7cmV0dXJuIGVbMF09ZypyK2QqbyxlWzFdPWcqaStkKmMsZVsyXT1nKnMrZCphLGVbM109ZypvLWQqcixlWzRdPWcqYy1kKmksZVs1XT1nKmEtZCpzLGVbNl09aCxlWzddPWYsZVs4XT11LGV9ZnVuY3Rpb24geHIoZSx0LG4pe2NvbnN0IHI9blswXSxpPW5bMV07cmV0dXJuIGVbMF09cip0WzBdLGVbMV09cip0WzFdLGVbMl09cip0WzJdLGVbM109aSp0WzNdLGVbNF09aSp0WzRdLGVbNV09aSp0WzVdLGVbNl09dFs2XSxlWzddPXRbN10sZVs4XT10WzhdLGV9ZnVuY3Rpb24gbGgoZSx0KXtyZXR1cm4gZVswXT0xLGVbMV09MCxlWzJdPTAsZVszXT0wLGVbNF09MSxlWzVdPTAsZVs2XT10WzBdLGVbN109dFsxXSxlWzhdPTEsZX1mdW5jdGlvbiBoaChlLHQpe2NvbnN0IG49TWF0aC5zaW4odCkscj1NYXRoLmNvcyh0KTtyZXR1cm4gZVswXT1yLGVbMV09bixlWzJdPTAsZVszXT0tbixlWzRdPXIsZVs1XT0wLGVbNl09MCxlWzddPTAsZVs4XT0xLGV9ZnVuY3Rpb24gbXMoZSx0KXtyZXR1cm4gZVswXT10WzBdLGVbMV09MCxlWzJdPTAsZVszXT0wLGVbNF09dFsxXSxlWzVdPTAsZVs2XT0wLGVbN109MCxlWzhdPTEsZX1mdW5jdGlvbiBmaChlLHQpe3JldHVybiBlWzBdPXRbMF0sZVsxXT10WzFdLGVbMl09MCxlWzNdPXRbMl0sZVs0XT10WzNdLGVbNV09MCxlWzZdPXRbNF0sZVs3XT10WzVdLGVbOF09MSxlfWZ1bmN0aW9uIExlKGUsdCl7Y29uc3Qgbj10WzBdLHI9dFsxXSxpPXRbMl0scz10WzNdLG89bituLGM9cityLGE9aStpLGg9bipvLGY9cipvLHU9cipjLGQ9aSpvLGc9aSpjLG09aSphLF89cypvLHA9cypjLHg9cyphO3JldHVybiBlWzBdPTEtdS1tLGVbM109Zi14LGVbNl09ZCtwLGVbMV09Zit4LGVbNF09MS1oLW0sZVs3XT1nLV8sZVsyXT1kLXAsZVs1XT1nK18sZVs4XT0xLWgtdSxlfWZ1bmN0aW9uIE1yKGUsdCl7Y29uc3Qgbj10WzBdLHI9dFsxXSxpPXRbMl0scz10WzNdLG89dFs0XSxjPXRbNV0sYT10WzZdLGg9dFs3XSxmPXRbOF0sdT10WzldLGQ9dFsxMF0sZz10WzExXSxtPXRbMTJdLF89dFsxM10scD10WzE0XSx4PXRbMTVdLFQ9bipjLXIqbyxNPW4qYS1pKm8sQT1uKmgtcypvLHY9ciphLWkqYyx3PXIqaC1zKmMsUD1pKmgtcyphLGI9ZipfLXUqbSxTPWYqcC1kKm0sTz1mKngtZyptLFY9dSpwLWQqXyx6PXUqeC1nKl8sTj1kKngtZypwO2xldCBSPVQqTi1NKnorQSpWK3YqTy13KlMrUCpiO3JldHVybiBSPyhSPTEvUixlWzBdPShjKk4tYSp6K2gqVikqUixlWzFdPShhKk8tbypOLWgqUykqUixlWzJdPShvKnotYypPK2gqYikqUixlWzNdPShpKnotcipOLXMqVikqUixlWzRdPShuKk4taSpPK3MqUykqUixlWzVdPShyKk8tbip6LXMqYikqUixlWzZdPShfKlAtcCp3K3gqdikqUixlWzddPShwKkEtbSpQLXgqTSkqUixlWzhdPShtKnctXypBK3gqVCkqUixlKTpudWxsfWZ1bmN0aW9uIHVoKGUsdCxuKXtyZXR1cm4gZVswXT0yL3QsZVsxXT0wLGVbMl09MCxlWzNdPTAsZVs0XT0tMi9uLGVbNV09MCxlWzZdPS0xLGVbN109MSxlWzhdPTEsZX1mdW5jdGlvbiBkaChlKXtyZXR1cm5gbWF0Mygke2VbMF19LCAke2VbMV19LCAke2VbMl19LCAke2VbM119LCAke2VbNF19LCAke2VbNV19LCAke2VbNl19LCAke2VbN119LCAke2VbOF19KWB9ZnVuY3Rpb24gZ2goZSl7cmV0dXJuIE1hdGguc3FydChlWzBdKmVbMF0rZVsxXSplWzFdK2VbMl0qZVsyXStlWzNdKmVbM10rZVs0XSplWzRdK2VbNV0qZVs1XStlWzZdKmVbNl0rZVs3XSplWzddK2VbOF0qZVs4XSl9ZnVuY3Rpb24gbWgoZSx0LG4pe3JldHVybiBlWzBdPXRbMF0rblswXSxlWzFdPXRbMV0rblsxXSxlWzJdPXRbMl0rblsyXSxlWzNdPXRbM10rblszXSxlWzRdPXRbNF0rbls0XSxlWzVdPXRbNV0rbls1XSxlWzZdPXRbNl0rbls2XSxlWzddPXRbN10rbls3XSxlWzhdPXRbOF0rbls4XSxlfWZ1bmN0aW9uIHBzKGUsdCxuKXtyZXR1cm4gZVswXT10WzBdLW5bMF0sZVsxXT10WzFdLW5bMV0sZVsyXT10WzJdLW5bMl0sZVszXT10WzNdLW5bM10sZVs0XT10WzRdLW5bNF0sZVs1XT10WzVdLW5bNV0sZVs2XT10WzZdLW5bNl0sZVs3XT10WzddLW5bN10sZVs4XT10WzhdLW5bOF0sZX1mdW5jdGlvbiBwaChlLHQsbil7cmV0dXJuIGVbMF09dFswXSpuLGVbMV09dFsxXSpuLGVbMl09dFsyXSpuLGVbM109dFszXSpuLGVbNF09dFs0XSpuLGVbNV09dFs1XSpuLGVbNl09dFs2XSpuLGVbN109dFs3XSpuLGVbOF09dFs4XSpuLGV9ZnVuY3Rpb24gX2goZSx0LG4scil7cmV0dXJuIGVbMF09dFswXStuWzBdKnIsZVsxXT10WzFdK25bMV0qcixlWzJdPXRbMl0rblsyXSpyLGVbM109dFszXStuWzNdKnIsZVs0XT10WzRdK25bNF0qcixlWzVdPXRbNV0rbls1XSpyLGVbNl09dFs2XStuWzZdKnIsZVs3XT10WzddK25bN10qcixlWzhdPXRbOF0rbls4XSpyLGV9ZnVuY3Rpb24geWgoZSx0KXtyZXR1cm4gZVswXT09PXRbMF0mJmVbMV09PT10WzFdJiZlWzJdPT09dFsyXSYmZVszXT09PXRbM10mJmVbNF09PT10WzRdJiZlWzVdPT09dFs1XSYmZVs2XT09PXRbNl0mJmVbN109PT10WzddJiZlWzhdPT09dFs4XX1mdW5jdGlvbiB4aChlLHQpe2NvbnN0IG49ZVswXSxyPWVbMV0saT1lWzJdLHM9ZVszXSxvPWVbNF0sYz1lWzVdLGE9ZVs2XSxoPWVbN10sZj1lWzhdLHU9dFswXSxkPXRbMV0sZz10WzJdLG09dFszXSxfPXRbNF0scD10WzVdLHg9dFs2XSxUPXRbN10sTT10WzhdO3JldHVybiBNYXRoLmFicyhuLXUpPD1JKk1hdGgubWF4KDEsTWF0aC5hYnMobiksTWF0aC5hYnModSkpJiZNYXRoLmFicyhyLWQpPD1JKk1hdGgubWF4KDEsTWF0aC5hYnMociksTWF0aC5hYnMoZCkpJiZNYXRoLmFicyhpLWcpPD1JKk1hdGgubWF4KDEsTWF0aC5hYnMoaSksTWF0aC5hYnMoZykpJiZNYXRoLmFicyhzLW0pPD1JKk1hdGgubWF4KDEsTWF0aC5hYnMocyksTWF0aC5hYnMobSkpJiZNYXRoLmFicyhvLV8pPD1JKk1hdGgubWF4KDEsTWF0aC5hYnMobyksTWF0aC5hYnMoXykpJiZNYXRoLmFicyhjLXApPD1JKk1hdGgubWF4KDEsTWF0aC5hYnMoYyksTWF0aC5hYnMocCkpJiZNYXRoLmFicyhhLXgpPD1JKk1hdGgubWF4KDEsTWF0aC5hYnMoYSksTWF0aC5hYnMoeCkpJiZNYXRoLmFicyhoLVQpPD1JKk1hdGgubWF4KDEsTWF0aC5hYnMoaCksTWF0aC5hYnMoVCkpJiZNYXRoLmFicyhmLU0pPD1JKk1hdGgubWF4KDEsTWF0aC5hYnMoZiksTWF0aC5hYnMoTSkpfXZhciBNaD1PYmplY3QuZnJlZXplKHtfX3Byb3RvX186bnVsbCxhZGQ6bWgsYWRqb2ludDphaCxjbG9uZTppaCxjb3B5OnNoLGNyZWF0ZTpmcyxkZXRlcm1pbmFudDpLdCxlcXVhbHM6eGgsZXhhY3RFcXVhbHM6eWgsZnJvYjpnaCxmcm9tTWF0MmQ6ZmgsZnJvbU1hdDQ6X3IsZnJvbVF1YXQ6TGUsZnJvbVJvdGF0aW9uOmhoLGZyb21TY2FsaW5nOm1zLGZyb21UcmFuc2xhdGlvbjpsaCxmcm9tVmFsdWVzOm9oLGlkZW50aXR5OmNoLGludmVydDpnbixtdWw6bW4sbXVsdGlwbHk6bW4sbXVsdGlwbHlTY2FsYXI6cGgsbXVsdGlwbHlTY2FsYXJBbmRBZGQ6X2gsbm9ybWFsRnJvbU1hdDQ6TXIscHJvamVjdGlvbjp1aCxyb3RhdGU6Z3Msc2NhbGU6eHIsc2V0OnVzLHN0cjpkaCxzdWI6cHMsc3VidHJhY3Q6cHMsdHJhbnNsYXRlOmRzLHRyYW5zcG9zZTp5cn0pLHdyOyhmdW5jdGlvbihlKXtlW2UuQ09MMFJPVzA9MF09IkNPTDBST1cwIixlW2UuQ09MMFJPVzE9MV09IkNPTDBST1cxIixlW2UuQ09MMFJPVzI9Ml09IkNPTDBST1cyIixlW2UuQ09MMVJPVzA9M109IkNPTDFST1cwIixlW2UuQ09MMVJPVzE9NF09IkNPTDFST1cxIixlW2UuQ09MMVJPVzI9NV09IkNPTDFST1cyIixlW2UuQ09MMlJPVzA9Nl09IkNPTDJST1cwIixlW2UuQ09MMlJPVzE9N109IkNPTDJST1cxIixlW2UuQ09MMlJPVzI9OF09IkNPTDJST1cyIn0pKHdyfHwod3I9e30pKTtjb25zdCB3aD1PYmplY3QuZnJlZXplKFsxLDAsMCwwLDEsMCwwLDAsMV0pO2NsYXNzIG50IGV4dGVuZHMgZG57c3RhdGljIGdldCBJREVOVElUWSgpe3JldHVybiBBaCgpfXN0YXRpYyBnZXQgWkVSTygpe3JldHVybiBUaCgpfWdldCBFTEVNRU5UUygpe3JldHVybiA5fWdldCBSQU5LKCl7cmV0dXJuIDN9Z2V0IElORElDRVMoKXtyZXR1cm4gd3J9Y29uc3RydWN0b3IodCwuLi5uKXtzdXBlcigtMCwtMCwtMCwtMCwtMCwtMCwtMCwtMCwtMCksYXJndW1lbnRzLmxlbmd0aD09PTEmJkFycmF5LmlzQXJyYXkodCk/dGhpcy5jb3B5KHQpOm4ubGVuZ3RoPjA/dGhpcy5jb3B5KFt0LC4uLm5dKTp0aGlzLmlkZW50aXR5KCl9Y29weSh0KXtyZXR1cm4gdGhpc1swXT10WzBdLHRoaXNbMV09dFsxXSx0aGlzWzJdPXRbMl0sdGhpc1szXT10WzNdLHRoaXNbNF09dFs0XSx0aGlzWzVdPXRbNV0sdGhpc1s2XT10WzZdLHRoaXNbN109dFs3XSx0aGlzWzhdPXRbOF0sdGhpcy5jaGVjaygpfWlkZW50aXR5KCl7cmV0dXJuIHRoaXMuY29weSh3aCl9ZnJvbU9iamVjdCh0KXtyZXR1cm4gdGhpcy5jaGVjaygpfWZyb21RdWF0ZXJuaW9uKHQpe3JldHVybiBMZSh0aGlzLHQpLHRoaXMuY2hlY2soKX1zZXQodCxuLHIsaSxzLG8sYyxhLGgpe3JldHVybiB0aGlzWzBdPXQsdGhpc1sxXT1uLHRoaXNbMl09cix0aGlzWzNdPWksdGhpc1s0XT1zLHRoaXNbNV09byx0aGlzWzZdPWMsdGhpc1s3XT1hLHRoaXNbOF09aCx0aGlzLmNoZWNrKCl9c2V0Um93TWFqb3IodCxuLHIsaSxzLG8sYyxhLGgpe3JldHVybiB0aGlzWzBdPXQsdGhpc1sxXT1pLHRoaXNbMl09Yyx0aGlzWzNdPW4sdGhpc1s0XT1zLHRoaXNbNV09YSx0aGlzWzZdPXIsdGhpc1s3XT1vLHRoaXNbOF09aCx0aGlzLmNoZWNrKCl9ZGV0ZXJtaW5hbnQoKXtyZXR1cm4gS3QodGhpcyl9dHJhbnNwb3NlKCl7cmV0dXJuIHlyKHRoaXMsdGhpcyksdGhpcy5jaGVjaygpfWludmVydCgpe3JldHVybiBnbih0aGlzLHRoaXMpLHRoaXMuY2hlY2soKX1tdWx0aXBseUxlZnQodCl7cmV0dXJuIG1uKHRoaXMsdCx0aGlzKSx0aGlzLmNoZWNrKCl9bXVsdGlwbHlSaWdodCh0KXtyZXR1cm4gbW4odGhpcyx0aGlzLHQpLHRoaXMuY2hlY2soKX1yb3RhdGUodCl7cmV0dXJuIGdzKHRoaXMsdGhpcyx0KSx0aGlzLmNoZWNrKCl9c2NhbGUodCl7cmV0dXJuIEFycmF5LmlzQXJyYXkodCk/eHIodGhpcyx0aGlzLHQpOnhyKHRoaXMsdGhpcyxbdCx0XSksdGhpcy5jaGVjaygpfXRyYW5zbGF0ZSh0KXtyZXR1cm4gZHModGhpcyx0aGlzLHQpLHRoaXMuY2hlY2soKX10cmFuc2Zvcm0odCxuKXtsZXQgcjtzd2l0Y2godC5sZW5ndGgpe2Nhc2UgMjpyPXNyKG58fFstMCwtMF0sdCx0aGlzKTticmVhaztjYXNlIDM6cj1RdChufHxbLTAsLTAsLTBdLHQsdGhpcyk7YnJlYWs7Y2FzZSA0OnI9bHIobnx8Wy0wLC0wLC0wLC0wXSx0LHRoaXMpO2JyZWFrO2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKCJJbGxlZ2FsIHZlY3RvciIpfXJldHVybiBHdChyLHQubGVuZ3RoKSxyfXRyYW5zZm9ybVZlY3Rvcih0LG4pe3JldHVybiB0aGlzLnRyYW5zZm9ybSh0LG4pfXRyYW5zZm9ybVZlY3RvcjIodCxuKXtyZXR1cm4gdGhpcy50cmFuc2Zvcm0odCxuKX10cmFuc2Zvcm1WZWN0b3IzKHQsbil7cmV0dXJuIHRoaXMudHJhbnNmb3JtKHQsbil9fWxldCBwbixfbj1udWxsO2Z1bmN0aW9uIFRoKCl7cmV0dXJuIHBufHwocG49bmV3IG50KFswLDAsMCwwLDAsMCwwLDAsMF0pLE9iamVjdC5mcmVlemUocG4pKSxwbn1mdW5jdGlvbiBBaCgpe3JldHVybiBfbnx8KF9uPW5ldyBudCxPYmplY3QuZnJlZXplKF9uKSksX259ZnVuY3Rpb24gT2goKXtjb25zdCBlPW5ldyBDKDE2KTtyZXR1cm4gQyE9RmxvYXQzMkFycmF5JiYoZVsxXT0wLGVbMl09MCxlWzNdPTAsZVs0XT0wLGVbNl09MCxlWzddPTAsZVs4XT0wLGVbOV09MCxlWzExXT0wLGVbMTJdPTAsZVsxM109MCxlWzE0XT0wKSxlWzBdPTEsZVs1XT0xLGVbMTBdPTEsZVsxNV09MSxlfWZ1bmN0aW9uIHZoKGUpe2NvbnN0IHQ9bmV3IEMoMTYpO3JldHVybiB0WzBdPWVbMF0sdFsxXT1lWzFdLHRbMl09ZVsyXSx0WzNdPWVbM10sdFs0XT1lWzRdLHRbNV09ZVs1XSx0WzZdPWVbNl0sdFs3XT1lWzddLHRbOF09ZVs4XSx0WzldPWVbOV0sdFsxMF09ZVsxMF0sdFsxMV09ZVsxMV0sdFsxMl09ZVsxMl0sdFsxM109ZVsxM10sdFsxNF09ZVsxNF0sdFsxNV09ZVsxNV0sdH1mdW5jdGlvbiBFaChlLHQpe3JldHVybiBlWzBdPXRbMF0sZVsxXT10WzFdLGVbMl09dFsyXSxlWzNdPXRbM10sZVs0XT10WzRdLGVbNV09dFs1XSxlWzZdPXRbNl0sZVs3XT10WzddLGVbOF09dFs4XSxlWzldPXRbOV0sZVsxMF09dFsxMF0sZVsxMV09dFsxMV0sZVsxMl09dFsxMl0sZVsxM109dFsxM10sZVsxNF09dFsxNF0sZVsxNV09dFsxNV0sZX1mdW5jdGlvbiBiaChlLHQsbixyLGkscyxvLGMsYSxoLGYsdSxkLGcsbSxfKXtjb25zdCBwPW5ldyBDKDE2KTtyZXR1cm4gcFswXT1lLHBbMV09dCxwWzJdPW4scFszXT1yLHBbNF09aSxwWzVdPXMscFs2XT1vLHBbN109YyxwWzhdPWEscFs5XT1oLHBbMTBdPWYscFsxMV09dSxwWzEyXT1kLHBbMTNdPWcscFsxNF09bSxwWzE1XT1fLHB9ZnVuY3Rpb24gU2goZSx0LG4scixpLHMsbyxjLGEsaCxmLHUsZCxnLG0sXyxwKXtyZXR1cm4gZVswXT10LGVbMV09bixlWzJdPXIsZVszXT1pLGVbNF09cyxlWzVdPW8sZVs2XT1jLGVbN109YSxlWzhdPWgsZVs5XT1mLGVbMTBdPXUsZVsxMV09ZCxlWzEyXT1nLGVbMTNdPW0sZVsxNF09XyxlWzE1XT1wLGV9ZnVuY3Rpb24gX3MoZSl7cmV0dXJuIGVbMF09MSxlWzFdPTAsZVsyXT0wLGVbM109MCxlWzRdPTAsZVs1XT0xLGVbNl09MCxlWzddPTAsZVs4XT0wLGVbOV09MCxlWzEwXT0xLGVbMTFdPTAsZVsxMl09MCxlWzEzXT0wLGVbMTRdPTAsZVsxNV09MSxlfWZ1bmN0aW9uIHlzKGUsdCl7aWYoZT09PXQpe2NvbnN0IG49dFsxXSxyPXRbMl0saT10WzNdLHM9dFs2XSxvPXRbN10sYz10WzExXTtlWzFdPXRbNF0sZVsyXT10WzhdLGVbM109dFsxMl0sZVs0XT1uLGVbNl09dFs5XSxlWzddPXRbMTNdLGVbOF09cixlWzldPXMsZVsxMV09dFsxNF0sZVsxMl09aSxlWzEzXT1vLGVbMTRdPWN9ZWxzZSBlWzBdPXRbMF0sZVsxXT10WzRdLGVbMl09dFs4XSxlWzNdPXRbMTJdLGVbNF09dFsxXSxlWzVdPXRbNV0sZVs2XT10WzldLGVbN109dFsxM10sZVs4XT10WzJdLGVbOV09dFs2XSxlWzEwXT10WzEwXSxlWzExXT10WzE0XSxlWzEyXT10WzNdLGVbMTNdPXRbN10sZVsxNF09dFsxMV0sZVsxNV09dFsxNV07cmV0dXJuIGV9ZnVuY3Rpb24gVHIoZSx0KXtjb25zdCBuPXRbMF0scj10WzFdLGk9dFsyXSxzPXRbM10sbz10WzRdLGM9dFs1XSxhPXRbNl0saD10WzddLGY9dFs4XSx1PXRbOV0sZD10WzEwXSxnPXRbMTFdLG09dFsxMl0sXz10WzEzXSxwPXRbMTRdLHg9dFsxNV0sVD1uKmMtcipvLE09biphLWkqbyxBPW4qaC1zKm8sdj1yKmEtaSpjLHc9cipoLXMqYyxQPWkqaC1zKmEsYj1mKl8tdSptLFM9ZipwLWQqbSxPPWYqeC1nKm0sVj11KnAtZCpfLHo9dSp4LWcqXyxOPWQqeC1nKnA7bGV0IFI9VCpOLU0qeitBKlYrdipPLXcqUytQKmI7cmV0dXJuIFI/KFI9MS9SLGVbMF09KGMqTi1hKnoraCpWKSpSLGVbMV09KGkqei1yKk4tcypWKSpSLGVbMl09KF8qUC1wKncreCp2KSpSLGVbM109KGQqdy11KlAtZyp2KSpSLGVbNF09KGEqTy1vKk4taCpTKSpSLGVbNV09KG4qTi1pKk8rcypTKSpSLGVbNl09KHAqQS1tKlAteCpNKSpSLGVbN109KGYqUC1kKkErZypNKSpSLGVbOF09KG8qei1jKk8raCpiKSpSLGVbOV09KHIqTy1uKnotcypiKSpSLGVbMTBdPShtKnctXypBK3gqVCkqUixlWzExXT0odSpBLWYqdy1nKlQpKlIsZVsxMl09KGMqUy1vKlYtYSpiKSpSLGVbMTNdPShuKlYtcipTK2kqYikqUixlWzE0XT0oXypNLW0qdi1wKlQpKlIsZVsxNV09KGYqdi11Kk0rZCpUKSpSLGUpOm51bGx9ZnVuY3Rpb24gSWgoZSx0KXtjb25zdCBuPXRbMF0scj10WzFdLGk9dFsyXSxzPXRbM10sbz10WzRdLGM9dFs1XSxhPXRbNl0saD10WzddLGY9dFs4XSx1PXRbOV0sZD10WzEwXSxnPXRbMTFdLG09dFsxMl0sXz10WzEzXSxwPXRbMTRdLHg9dFsxNV0sVD1uKmMtcipvLE09biphLWkqbyxBPW4qaC1zKm8sdj1yKmEtaSpjLHc9cipoLXMqYyxQPWkqaC1zKmEsYj1mKl8tdSptLFM9ZipwLWQqbSxPPWYqeC1nKm0sVj11KnAtZCpfLHo9dSp4LWcqXyxOPWQqeC1nKnA7cmV0dXJuIGVbMF09YypOLWEqeitoKlYsZVsxXT1pKnotcipOLXMqVixlWzJdPV8qUC1wKncreCp2LGVbM109ZCp3LXUqUC1nKnYsZVs0XT1hKk8tbypOLWgqUyxlWzVdPW4qTi1pKk8rcypTLGVbNl09cCpBLW0qUC14Kk0sZVs3XT1mKlAtZCpBK2cqTSxlWzhdPW8qei1jKk8raCpiLGVbOV09cipPLW4qei1zKmIsZVsxMF09bSp3LV8qQSt4KlQsZVsxMV09dSpBLWYqdy1nKlQsZVsxMl09YypTLW8qVi1hKmIsZVsxM109bipWLXIqUytpKmIsZVsxNF09XypNLW0qdi1wKlQsZVsxNV09Zip2LXUqTStkKlQsZX1mdW5jdGlvbiB5bihlKXtjb25zdCB0PWVbMF0sbj1lWzFdLHI9ZVsyXSxpPWVbM10scz1lWzRdLG89ZVs1XSxjPWVbNl0sYT1lWzddLGg9ZVs4XSxmPWVbOV0sdT1lWzEwXSxkPWVbMTFdLGc9ZVsxMl0sbT1lWzEzXSxfPWVbMTRdLHA9ZVsxNV0seD10Km8tbipzLFQ9dCpjLXIqcyxNPW4qYy1yKm8sQT1oKm0tZipnLHY9aCpfLXUqZyx3PWYqXy11Km0sUD10Knctbip2K3IqQSxiPXMqdy1vKnYrYypBLFM9aCpNLWYqVCt1KngsTz1nKk0tbSpUK18qeDtyZXR1cm4gYSpQLWkqYitwKlMtZCpPfWZ1bmN0aW9uIHhuKGUsdCxuKXtjb25zdCByPXRbMF0saT10WzFdLHM9dFsyXSxvPXRbM10sYz10WzRdLGE9dFs1XSxoPXRbNl0sZj10WzddLHU9dFs4XSxkPXRbOV0sZz10WzEwXSxtPXRbMTFdLF89dFsxMl0scD10WzEzXSx4PXRbMTRdLFQ9dFsxNV07bGV0IE09blswXSxBPW5bMV0sdj1uWzJdLHc9blszXTtyZXR1cm4gZVswXT1NKnIrQSpjK3YqdSt3Kl8sZVsxXT1NKmkrQSphK3YqZCt3KnAsZVsyXT1NKnMrQSpoK3YqZyt3KngsZVszXT1NKm8rQSpmK3YqbSt3KlQsTT1uWzRdLEE9bls1XSx2PW5bNl0sdz1uWzddLGVbNF09TSpyK0EqYyt2KnUrdypfLGVbNV09TSppK0EqYSt2KmQrdypwLGVbNl09TSpzK0EqaCt2Kmcrdyp4LGVbN109TSpvK0EqZit2Km0rdypULE09bls4XSxBPW5bOV0sdj1uWzEwXSx3PW5bMTFdLGVbOF09TSpyK0EqYyt2KnUrdypfLGVbOV09TSppK0EqYSt2KmQrdypwLGVbMTBdPU0qcytBKmgrdipnK3cqeCxlWzExXT1NKm8rQSpmK3YqbSt3KlQsTT1uWzEyXSxBPW5bMTNdLHY9blsxNF0sdz1uWzE1XSxlWzEyXT1NKnIrQSpjK3YqdSt3Kl8sZVsxM109TSppK0EqYSt2KmQrdypwLGVbMTRdPU0qcytBKmgrdipnK3cqeCxlWzE1XT1NKm8rQSpmK3YqbSt3KlQsZX1mdW5jdGlvbiB4cyhlLHQsbil7Y29uc3Qgcj1uWzBdLGk9blsxXSxzPW5bMl07bGV0IG8sYyxhLGgsZix1LGQsZyxtLF8scCx4O3JldHVybiB0PT09ZT8oZVsxMl09dFswXSpyK3RbNF0qaSt0WzhdKnMrdFsxMl0sZVsxM109dFsxXSpyK3RbNV0qaSt0WzldKnMrdFsxM10sZVsxNF09dFsyXSpyK3RbNl0qaSt0WzEwXSpzK3RbMTRdLGVbMTVdPXRbM10qcit0WzddKmkrdFsxMV0qcyt0WzE1XSk6KG89dFswXSxjPXRbMV0sYT10WzJdLGg9dFszXSxmPXRbNF0sdT10WzVdLGQ9dFs2XSxnPXRbN10sbT10WzhdLF89dFs5XSxwPXRbMTBdLHg9dFsxMV0sZVswXT1vLGVbMV09YyxlWzJdPWEsZVszXT1oLGVbNF09ZixlWzVdPXUsZVs2XT1kLGVbN109ZyxlWzhdPW0sZVs5XT1fLGVbMTBdPXAsZVsxMV09eCxlWzEyXT1vKnIrZippK20qcyt0WzEyXSxlWzEzXT1jKnIrdSppK18qcyt0WzEzXSxlWzE0XT1hKnIrZCppK3Aqcyt0WzE0XSxlWzE1XT1oKnIrZyppK3gqcyt0WzE1XSksZX1mdW5jdGlvbiBNcyhlLHQsbil7Y29uc3Qgcj1uWzBdLGk9blsxXSxzPW5bMl07cmV0dXJuIGVbMF09dFswXSpyLGVbMV09dFsxXSpyLGVbMl09dFsyXSpyLGVbM109dFszXSpyLGVbNF09dFs0XSppLGVbNV09dFs1XSppLGVbNl09dFs2XSppLGVbN109dFs3XSppLGVbOF09dFs4XSpzLGVbOV09dFs5XSpzLGVbMTBdPXRbMTBdKnMsZVsxMV09dFsxMV0qcyxlWzEyXT10WzEyXSxlWzEzXT10WzEzXSxlWzE0XT10WzE0XSxlWzE1XT10WzE1XSxlfWZ1bmN0aW9uIHdzKGUsdCxuLHIpe2xldCBpPXJbMF0scz1yWzFdLG89clsyXSxjPU1hdGguc3FydChpKmkrcypzK28qbyksYSxoLGYsdSxkLGcsbSxfLHAseCxULE0sQSx2LHcsUCxiLFMsTyxWLHosTixSLGV0O3JldHVybiBjPEk/bnVsbDooYz0xL2MsaSo9YyxzKj1jLG8qPWMsaD1NYXRoLnNpbihuKSxhPU1hdGguY29zKG4pLGY9MS1hLHU9dFswXSxkPXRbMV0sZz10WzJdLG09dFszXSxfPXRbNF0scD10WzVdLHg9dFs2XSxUPXRbN10sTT10WzhdLEE9dFs5XSx2PXRbMTBdLHc9dFsxMV0sUD1pKmkqZithLGI9cyppKmYrbypoLFM9byppKmYtcypoLE89aSpzKmYtbypoLFY9cypzKmYrYSx6PW8qcypmK2kqaCxOPWkqbypmK3MqaCxSPXMqbypmLWkqaCxldD1vKm8qZithLGVbMF09dSpQK18qYitNKlMsZVsxXT1kKlArcCpiK0EqUyxlWzJdPWcqUCt4KmIrdipTLGVbM109bSpQK1QqYit3KlMsZVs0XT11Kk8rXypWK00qeixlWzVdPWQqTytwKlYrQSp6LGVbNl09ZypPK3gqVit2KnosZVs3XT1tKk8rVCpWK3cqeixlWzhdPXUqTitfKlIrTSpldCxlWzldPWQqTitwKlIrQSpldCxlWzEwXT1nKk4reCpSK3YqZXQsZVsxMV09bSpOK1QqUit3KmV0LHQhPT1lJiYoZVsxMl09dFsxMl0sZVsxM109dFsxM10sZVsxNF09dFsxNF0sZVsxNV09dFsxNV0pLGUpfWZ1bmN0aW9uIFRzKGUsdCxuKXtjb25zdCByPU1hdGguc2luKG4pLGk9TWF0aC5jb3Mobikscz10WzRdLG89dFs1XSxjPXRbNl0sYT10WzddLGg9dFs4XSxmPXRbOV0sdT10WzEwXSxkPXRbMTFdO3JldHVybiB0IT09ZSYmKGVbMF09dFswXSxlWzFdPXRbMV0sZVsyXT10WzJdLGVbM109dFszXSxlWzEyXT10WzEyXSxlWzEzXT10WzEzXSxlWzE0XT10WzE0XSxlWzE1XT10WzE1XSksZVs0XT1zKmkraCpyLGVbNV09byppK2YqcixlWzZdPWMqaSt1KnIsZVs3XT1hKmkrZCpyLGVbOF09aCppLXMqcixlWzldPWYqaS1vKnIsZVsxMF09dSppLWMqcixlWzExXT1kKmktYSpyLGV9ZnVuY3Rpb24gQXMoZSx0LG4pe2NvbnN0IHI9TWF0aC5zaW4obiksaT1NYXRoLmNvcyhuKSxzPXRbMF0sbz10WzFdLGM9dFsyXSxhPXRbM10saD10WzhdLGY9dFs5XSx1PXRbMTBdLGQ9dFsxMV07cmV0dXJuIHQhPT1lJiYoZVs0XT10WzRdLGVbNV09dFs1XSxlWzZdPXRbNl0sZVs3XT10WzddLGVbMTJdPXRbMTJdLGVbMTNdPXRbMTNdLGVbMTRdPXRbMTRdLGVbMTVdPXRbMTVdKSxlWzBdPXMqaS1oKnIsZVsxXT1vKmktZipyLGVbMl09YyppLXUqcixlWzNdPWEqaS1kKnIsZVs4XT1zKnIraCppLGVbOV09bypyK2YqaSxlWzEwXT1jKnIrdSppLGVbMTFdPWEqcitkKmksZX1mdW5jdGlvbiBPcyhlLHQsbil7Y29uc3Qgcj1NYXRoLnNpbihuKSxpPU1hdGguY29zKG4pLHM9dFswXSxvPXRbMV0sYz10WzJdLGE9dFszXSxoPXRbNF0sZj10WzVdLHU9dFs2XSxkPXRbN107cmV0dXJuIHQhPT1lJiYoZVs4XT10WzhdLGVbOV09dFs5XSxlWzEwXT10WzEwXSxlWzExXT10WzExXSxlWzEyXT10WzEyXSxlWzEzXT10WzEzXSxlWzE0XT10WzE0XSxlWzE1XT10WzE1XSksZVswXT1zKmkraCpyLGVbMV09byppK2YqcixlWzJdPWMqaSt1KnIsZVszXT1hKmkrZCpyLGVbNF09aCppLXMqcixlWzVdPWYqaS1vKnIsZVs2XT11KmktYypyLGVbN109ZCppLWEqcixlfWZ1bmN0aW9uIFBoKGUsdCl7cmV0dXJuIGVbMF09MSxlWzFdPTAsZVsyXT0wLGVbM109MCxlWzRdPTAsZVs1XT0xLGVbNl09MCxlWzddPTAsZVs4XT0wLGVbOV09MCxlWzEwXT0xLGVbMTFdPTAsZVsxMl09dFswXSxlWzEzXT10WzFdLGVbMTRdPXRbMl0sZVsxNV09MSxlfWZ1bmN0aW9uIExoKGUsdCl7cmV0dXJuIGVbMF09dFswXSxlWzFdPTAsZVsyXT0wLGVbM109MCxlWzRdPTAsZVs1XT10WzFdLGVbNl09MCxlWzddPTAsZVs4XT0wLGVbOV09MCxlWzEwXT10WzJdLGVbMTFdPTAsZVsxMl09MCxlWzEzXT0wLGVbMTRdPTAsZVsxNV09MSxlfWZ1bmN0aW9uIFJoKGUsdCxuKXtsZXQgcj1uWzBdLGk9blsxXSxzPW5bMl0sbz1NYXRoLnNxcnQocipyK2kqaStzKnMpLGMsYSxoO3JldHVybiBvPEk/bnVsbDoobz0xL28scio9byxpKj1vLHMqPW8sYT1NYXRoLnNpbih0KSxjPU1hdGguY29zKHQpLGg9MS1jLGVbMF09cipyKmgrYyxlWzFdPWkqcipoK3MqYSxlWzJdPXMqcipoLWkqYSxlWzNdPTAsZVs0XT1yKmkqaC1zKmEsZVs1XT1pKmkqaCtjLGVbNl09cyppKmgrciphLGVbN109MCxlWzhdPXIqcypoK2kqYSxlWzldPWkqcypoLXIqYSxlWzEwXT1zKnMqaCtjLGVbMTFdPTAsZVsxMl09MCxlWzEzXT0wLGVbMTRdPTAsZVsxNV09MSxlKX1mdW5jdGlvbiAkaChlLHQpe2NvbnN0IG49TWF0aC5zaW4odCkscj1NYXRoLmNvcyh0KTtyZXR1cm4gZVswXT0xLGVbMV09MCxlWzJdPTAsZVszXT0wLGVbNF09MCxlWzVdPXIsZVs2XT1uLGVbN109MCxlWzhdPTAsZVs5XT0tbixlWzEwXT1yLGVbMTFdPTAsZVsxMl09MCxlWzEzXT0wLGVbMTRdPTAsZVsxNV09MSxlfWZ1bmN0aW9uIENoKGUsdCl7Y29uc3Qgbj1NYXRoLnNpbih0KSxyPU1hdGguY29zKHQpO3JldHVybiBlWzBdPXIsZVsxXT0wLGVbMl09LW4sZVszXT0wLGVbNF09MCxlWzVdPTEsZVs2XT0wLGVbN109MCxlWzhdPW4sZVs5XT0wLGVbMTBdPXIsZVsxMV09MCxlWzEyXT0wLGVbMTNdPTAsZVsxNF09MCxlWzE1XT0xLGV9ZnVuY3Rpb24gVmgoZSx0KXtjb25zdCBuPU1hdGguc2luKHQpLHI9TWF0aC5jb3ModCk7cmV0dXJuIGVbMF09cixlWzFdPW4sZVsyXT0wLGVbM109MCxlWzRdPS1uLGVbNV09cixlWzZdPTAsZVs3XT0wLGVbOF09MCxlWzldPTAsZVsxMF09MSxlWzExXT0wLGVbMTJdPTAsZVsxM109MCxlWzE0XT0wLGVbMTVdPTEsZX1mdW5jdGlvbiB2cyhlLHQsbil7Y29uc3Qgcj10WzBdLGk9dFsxXSxzPXRbMl0sbz10WzNdLGM9cityLGE9aStpLGg9cytzLGY9cipjLHU9ciphLGQ9cipoLGc9aSphLG09aSpoLF89cypoLHA9bypjLHg9byphLFQ9bypoO3JldHVybiBlWzBdPTEtKGcrXyksZVsxXT11K1QsZVsyXT1kLXgsZVszXT0wLGVbNF09dS1ULGVbNV09MS0oZitfKSxlWzZdPW0rcCxlWzddPTAsZVs4XT1kK3gsZVs5XT1tLXAsZVsxMF09MS0oZitnKSxlWzExXT0wLGVbMTJdPW5bMF0sZVsxM109blsxXSxlWzE0XT1uWzJdLGVbMTVdPTEsZX1mdW5jdGlvbiBOaChlLHQpe2NvbnN0IG49bmV3IEMoMykscj0tdFswXSxpPS10WzFdLHM9LXRbMl0sbz10WzNdLGM9dFs0XSxhPXRbNV0saD10WzZdLGY9dFs3XSx1PXIqcitpKmkrcypzK28qbztyZXR1cm4gdT4wPyhuWzBdPShjKm8rZipyK2Eqcy1oKmkpKjIvdSxuWzFdPShhKm8rZippK2gqci1jKnMpKjIvdSxuWzJdPShoKm8rZipzK2MqaS1hKnIpKjIvdSk6KG5bMF09KGMqbytmKnIrYSpzLWgqaSkqMixuWzFdPShhKm8rZippK2gqci1jKnMpKjIsblsyXT0oaCpvK2YqcytjKmktYSpyKSoyKSx2cyhlLHQsbiksZX1mdW5jdGlvbiBNbihlLHQpe3JldHVybiBlWzBdPXRbMTJdLGVbMV09dFsxM10sZVsyXT10WzE0XSxlfWZ1bmN0aW9uIEVzKGUsdCl7Y29uc3Qgbj10WzBdLHI9dFsxXSxpPXRbMl0scz10WzRdLG89dFs1XSxjPXRbNl0sYT10WzhdLGg9dFs5XSxmPXRbMTBdO3JldHVybiBlWzBdPU1hdGguc3FydChuKm4rcipyK2kqaSksZVsxXT1NYXRoLnNxcnQocypzK28qbytjKmMpLGVbMl09TWF0aC5zcXJ0KGEqYStoKmgrZipmKSxlfWZ1bmN0aW9uIGJzKGUsdCl7Y29uc3Qgbj1uZXcgQygzKTtFcyhuLHQpO2NvbnN0IHI9MS9uWzBdLGk9MS9uWzFdLHM9MS9uWzJdLG89dFswXSpyLGM9dFsxXSppLGE9dFsyXSpzLGg9dFs0XSpyLGY9dFs1XSppLHU9dFs2XSpzLGQ9dFs4XSpyLGc9dFs5XSppLG09dFsxMF0qcyxfPW8rZittO2xldCBwPTA7cmV0dXJuIF8+MD8ocD1NYXRoLnNxcnQoXysxKSoyLGVbM109LjI1KnAsZVswXT0odS1nKS9wLGVbMV09KGQtYSkvcCxlWzJdPShjLWgpL3ApOm8+ZiYmbz5tPyhwPU1hdGguc3FydCgxK28tZi1tKSoyLGVbM109KHUtZykvcCxlWzBdPS4yNSpwLGVbMV09KGMraCkvcCxlWzJdPShkK2EpL3ApOmY+bT8ocD1NYXRoLnNxcnQoMStmLW8tbSkqMixlWzNdPShkLWEpL3AsZVswXT0oYytoKS9wLGVbMV09LjI1KnAsZVsyXT0odStnKS9wKToocD1NYXRoLnNxcnQoMSttLW8tZikqMixlWzNdPShjLWgpL3AsZVswXT0oZCthKS9wLGVbMV09KHUrZykvcCxlWzJdPS4yNSpwKSxlfWZ1bmN0aW9uIHpoKGUsdCxuLHIpe3RbMF09clsxMl0sdFsxXT1yWzEzXSx0WzJdPXJbMTRdO2NvbnN0IGk9clswXSxzPXJbMV0sbz1yWzJdLGM9cls0XSxhPXJbNV0saD1yWzZdLGY9cls4XSx1PXJbOV0sZD1yWzEwXTtuWzBdPU1hdGguc3FydChpKmkrcypzK28qbyksblsxXT1NYXRoLnNxcnQoYypjK2EqYStoKmgpLG5bMl09TWF0aC5zcXJ0KGYqZit1KnUrZCpkKTtjb25zdCBnPTEvblswXSxtPTEvblsxXSxfPTEvblsyXSxwPWkqZyx4PXMqbSxUPW8qXyxNPWMqZyxBPWEqbSx2PWgqXyx3PWYqZyxQPXUqbSxiPWQqXyxTPXArQStiO2xldCBPPTA7cmV0dXJuIFM+MD8oTz1NYXRoLnNxcnQoUysxKSoyLGVbM109LjI1Kk8sZVswXT0odi1QKS9PLGVbMV09KHctVCkvTyxlWzJdPSh4LU0pL08pOnA+QSYmcD5iPyhPPU1hdGguc3FydCgxK3AtQS1iKSoyLGVbM109KHYtUCkvTyxlWzBdPS4yNSpPLGVbMV09KHgrTSkvTyxlWzJdPSh3K1QpL08pOkE+Yj8oTz1NYXRoLnNxcnQoMStBLXAtYikqMixlWzNdPSh3LVQpL08sZVswXT0oeCtNKS9PLGVbMV09LjI1Kk8sZVsyXT0oditQKS9PKTooTz1NYXRoLnNxcnQoMStiLXAtQSkqMixlWzNdPSh4LU0pL08sZVswXT0odytUKS9PLGVbMV09KHYrUCkvTyxlWzJdPS4yNSpPKSxlfWZ1bmN0aW9uIHFoKGUsdCxuLHIpe2NvbnN0IGk9dFswXSxzPXRbMV0sbz10WzJdLGM9dFszXSxhPWkraSxoPXMrcyxmPW8rbyx1PWkqYSxkPWkqaCxnPWkqZixtPXMqaCxfPXMqZixwPW8qZix4PWMqYSxUPWMqaCxNPWMqZixBPXJbMF0sdj1yWzFdLHc9clsyXTtyZXR1cm4gZVswXT0oMS0obStwKSkqQSxlWzFdPShkK00pKkEsZVsyXT0oZy1UKSpBLGVbM109MCxlWzRdPShkLU0pKnYsZVs1XT0oMS0odStwKSkqdixlWzZdPShfK3gpKnYsZVs3XT0wLGVbOF09KGcrVCkqdyxlWzldPShfLXgpKncsZVsxMF09KDEtKHUrbSkpKncsZVsxMV09MCxlWzEyXT1uWzBdLGVbMTNdPW5bMV0sZVsxNF09blsyXSxlWzE1XT0xLGV9ZnVuY3Rpb24gRmgoZSx0LG4scixpKXtjb25zdCBzPXRbMF0sbz10WzFdLGM9dFsyXSxhPXRbM10saD1zK3MsZj1vK28sdT1jK2MsZD1zKmgsZz1zKmYsbT1zKnUsXz1vKmYscD1vKnUseD1jKnUsVD1hKmgsTT1hKmYsQT1hKnUsdj1yWzBdLHc9clsxXSxQPXJbMl0sYj1pWzBdLFM9aVsxXSxPPWlbMl0sVj0oMS0oXyt4KSkqdix6PShnK0EpKnYsTj0obS1NKSp2LFI9KGctQSkqdyxldD0oMS0oZCt4KSkqdyxCPShwK1QpKncsWD0obStNKSpQLHJ0PShwLVQpKlAsaXQ9KDEtKGQrXykpKlA7cmV0dXJuIGVbMF09VixlWzFdPXosZVsyXT1OLGVbM109MCxlWzRdPVIsZVs1XT1ldCxlWzZdPUIsZVs3XT0wLGVbOF09WCxlWzldPXJ0LGVbMTBdPWl0LGVbMTFdPTAsZVsxMl09blswXStiLShWKmIrUipTK1gqTyksZVsxM109blsxXStTLSh6KmIrZXQqUytydCpPKSxlWzE0XT1uWzJdK08tKE4qYitCKlMraXQqTyksZVsxNV09MSxlfWZ1bmN0aW9uIFNzKGUsdCl7Y29uc3Qgbj10WzBdLHI9dFsxXSxpPXRbMl0scz10WzNdLG89bituLGM9cityLGE9aStpLGg9bipvLGY9cipvLHU9cipjLGQ9aSpvLGc9aSpjLG09aSphLF89cypvLHA9cypjLHg9cyphO3JldHVybiBlWzBdPTEtdS1tLGVbMV09Zit4LGVbMl09ZC1wLGVbM109MCxlWzRdPWYteCxlWzVdPTEtaC1tLGVbNl09ZytfLGVbN109MCxlWzhdPWQrcCxlWzldPWctXyxlWzEwXT0xLWgtdSxlWzExXT0wLGVbMTJdPTAsZVsxM109MCxlWzE0XT0wLGVbMTVdPTEsZX1mdW5jdGlvbiBJcyhlLHQsbixyLGkscyxvKXtjb25zdCBjPTEvKG4tdCksYT0xLyhpLXIpLGg9MS8ocy1vKTtyZXR1cm4gZVswXT1zKjIqYyxlWzFdPTAsZVsyXT0wLGVbM109MCxlWzRdPTAsZVs1XT1zKjIqYSxlWzZdPTAsZVs3XT0wLGVbOF09KG4rdCkqYyxlWzldPShpK3IpKmEsZVsxMF09KG8rcykqaCxlWzExXT0tMSxlWzEyXT0wLGVbMTNdPTAsZVsxNF09bypzKjIqaCxlWzE1XT0wLGV9ZnVuY3Rpb24gUHMoZSx0LG4scixpKXtjb25zdCBzPTEvTWF0aC50YW4odC8yKTtpZihlWzBdPXMvbixlWzFdPTAsZVsyXT0wLGVbM109MCxlWzRdPTAsZVs1XT1zLGVbNl09MCxlWzddPTAsZVs4XT0wLGVbOV09MCxlWzExXT0tMSxlWzEyXT0wLGVbMTNdPTAsZVsxNV09MCxpIT1udWxsJiZpIT09MS8wKXtjb25zdCBvPTEvKHItaSk7ZVsxMF09KGkrcikqbyxlWzE0XT0yKmkqcipvfWVsc2UgZVsxMF09LTEsZVsxNF09LTIqcjtyZXR1cm4gZX1jb25zdCBMcz1QcztmdW5jdGlvbiBraChlLHQsbixyLGkpe2NvbnN0IHM9MS9NYXRoLnRhbih0LzIpO2lmKGVbMF09cy9uLGVbMV09MCxlWzJdPTAsZVszXT0wLGVbNF09MCxlWzVdPXMsZVs2XT0wLGVbN109MCxlWzhdPTAsZVs5XT0wLGVbMTFdPS0xLGVbMTJdPTAsZVsxM109MCxlWzE1XT0wLGkhPW51bGwmJmkhPT0xLzApe2NvbnN0IG89MS8oci1pKTtlWzEwXT1pKm8sZVsxNF09aSpyKm99ZWxzZSBlWzEwXT0tMSxlWzE0XT0tcjtyZXR1cm4gZX1mdW5jdGlvbiBCaChlLHQsbixyKXtjb25zdCBpPU1hdGgudGFuKHQudXBEZWdyZWVzKk1hdGguUEkvMTgwKSxzPU1hdGgudGFuKHQuZG93bkRlZ3JlZXMqTWF0aC5QSS8xODApLG89TWF0aC50YW4odC5sZWZ0RGVncmVlcypNYXRoLlBJLzE4MCksYz1NYXRoLnRhbih0LnJpZ2h0RGVncmVlcypNYXRoLlBJLzE4MCksYT0yLyhvK2MpLGg9Mi8oaStzKTtyZXR1cm4gZVswXT1hLGVbMV09MCxlWzJdPTAsZVszXT0wLGVbNF09MCxlWzVdPWgsZVs2XT0wLGVbN109MCxlWzhdPS0oKG8tYykqYSouNSksZVs5XT0oaS1zKSpoKi41LGVbMTBdPXIvKG4tciksZVsxMV09LTEsZVsxMl09MCxlWzEzXT0wLGVbMTRdPXIqbi8obi1yKSxlWzE1XT0wLGV9ZnVuY3Rpb24gUnMoZSx0LG4scixpLHMsbyl7Y29uc3QgYz0xLyh0LW4pLGE9MS8oci1pKSxoPTEvKHMtbyk7cmV0dXJuIGVbMF09LTIqYyxlWzFdPTAsZVsyXT0wLGVbM109MCxlWzRdPTAsZVs1XT0tMiphLGVbNl09MCxlWzddPTAsZVs4XT0wLGVbOV09MCxlWzEwXT0yKmgsZVsxMV09MCxlWzEyXT0odCtuKSpjLGVbMTNdPShpK3IpKmEsZVsxNF09KG8rcykqaCxlWzE1XT0xLGV9Y29uc3QgJHM9UnM7ZnVuY3Rpb24gVWgoZSx0LG4scixpLHMsbyl7Y29uc3QgYz0xLyh0LW4pLGE9MS8oci1pKSxoPTEvKHMtbyk7cmV0dXJuIGVbMF09LTIqYyxlWzFdPTAsZVsyXT0wLGVbM109MCxlWzRdPTAsZVs1XT0tMiphLGVbNl09MCxlWzddPTAsZVs4XT0wLGVbOV09MCxlWzEwXT1oLGVbMTFdPTAsZVsxMl09KHQrbikqYyxlWzEzXT0oaStyKSphLGVbMTRdPXMqaCxlWzE1XT0xLGV9ZnVuY3Rpb24gQ3MoZSx0LG4scil7bGV0IGkscyxvLGMsYSxoLGYsdSxkLGc7Y29uc3QgbT10WzBdLF89dFsxXSxwPXRbMl0seD1yWzBdLFQ9clsxXSxNPXJbMl0sQT1uWzBdLHY9blsxXSx3PW5bMl07cmV0dXJuIE1hdGguYWJzKG0tQSk8SSYmTWF0aC5hYnMoXy12KTxJJiZNYXRoLmFicyhwLXcpPEk/X3MoZSk6KHU9bS1BLGQ9Xy12LGc9cC13LGk9MS9NYXRoLnNxcnQodSp1K2QqZCtnKmcpLHUqPWksZCo9aSxnKj1pLHM9VCpnLU0qZCxvPU0qdS14KmcsYz14KmQtVCp1LGk9TWF0aC5zcXJ0KHMqcytvKm8rYypjKSxpPyhpPTEvaSxzKj1pLG8qPWksYyo9aSk6KHM9MCxvPTAsYz0wKSxhPWQqYy1nKm8saD1nKnMtdSpjLGY9dSpvLWQqcyxpPU1hdGguc3FydChhKmEraCpoK2YqZiksaT8oaT0xL2ksYSo9aSxoKj1pLGYqPWkpOihhPTAsaD0wLGY9MCksZVswXT1zLGVbMV09YSxlWzJdPXUsZVszXT0wLGVbNF09byxlWzVdPWgsZVs2XT1kLGVbN109MCxlWzhdPWMsZVs5XT1mLGVbMTBdPWcsZVsxMV09MCxlWzEyXT0tKHMqbStvKl8rYypwKSxlWzEzXT0tKGEqbStoKl8rZipwKSxlWzE0XT0tKHUqbStkKl8rZypwKSxlWzE1XT0xLGUpfWZ1bmN0aW9uIERoKGUsdCxuLHIpe2NvbnN0IGk9dFswXSxzPXRbMV0sbz10WzJdLGM9clswXSxhPXJbMV0saD1yWzJdO2xldCBmPWktblswXSx1PXMtblsxXSxkPW8tblsyXSxnPWYqZit1KnUrZCpkO2c+MCYmKGc9MS9NYXRoLnNxcnQoZyksZio9Zyx1Kj1nLGQqPWcpO2xldCBtPWEqZC1oKnUsXz1oKmYtYypkLHA9Yyp1LWEqZjtyZXR1cm4gZz1tKm0rXypfK3AqcCxnPjAmJihnPTEvTWF0aC5zcXJ0KGcpLG0qPWcsXyo9ZyxwKj1nKSxlWzBdPW0sZVsxXT1fLGVbMl09cCxlWzNdPTAsZVs0XT11KnAtZCpfLGVbNV09ZCptLWYqcCxlWzZdPWYqXy11Km0sZVs3XT0wLGVbOF09ZixlWzldPXUsZVsxMF09ZCxlWzExXT0wLGVbMTJdPWksZVsxM109cyxlWzE0XT1vLGVbMTVdPTEsZX1mdW5jdGlvbiBZaChlKXtyZXR1cm5gbWF0NCgke2VbMF19LCAke2VbMV19LCAke2VbMl19LCAke2VbM119LCAke2VbNF19LCAke2VbNV19LCAke2VbNl19LCAke2VbN119LCAke2VbOF19LCAke2VbOV19LCAke2VbMTBdfSwgJHtlWzExXX0sICR7ZVsxMl19LCAke2VbMTNdfSwgJHtlWzE0XX0sICR7ZVsxNV19KWB9ZnVuY3Rpb24gV2goZSl7cmV0dXJuIE1hdGguc3FydChlWzBdKmVbMF0rZVsxXSplWzFdK2VbMl0qZVsyXStlWzNdKmVbM10rZVs0XSplWzRdK2VbNV0qZVs1XStlWzZdKmVbNl0rZVs3XSplWzddK2VbOF0qZVs4XStlWzldKmVbOV0rZVsxMF0qZVsxMF0rZVsxMV0qZVsxMV0rZVsxMl0qZVsxMl0rZVsxM10qZVsxM10rZVsxNF0qZVsxNF0rZVsxNV0qZVsxNV0pfWZ1bmN0aW9uIFpoKGUsdCxuKXtyZXR1cm4gZVswXT10WzBdK25bMF0sZVsxXT10WzFdK25bMV0sZVsyXT10WzJdK25bMl0sZVszXT10WzNdK25bM10sZVs0XT10WzRdK25bNF0sZVs1XT10WzVdK25bNV0sZVs2XT10WzZdK25bNl0sZVs3XT10WzddK25bN10sZVs4XT10WzhdK25bOF0sZVs5XT10WzldK25bOV0sZVsxMF09dFsxMF0rblsxMF0sZVsxMV09dFsxMV0rblsxMV0sZVsxMl09dFsxMl0rblsxMl0sZVsxM109dFsxM10rblsxM10sZVsxNF09dFsxNF0rblsxNF0sZVsxNV09dFsxNV0rblsxNV0sZX1mdW5jdGlvbiBWcyhlLHQsbil7cmV0dXJuIGVbMF09dFswXS1uWzBdLGVbMV09dFsxXS1uWzFdLGVbMl09dFsyXS1uWzJdLGVbM109dFszXS1uWzNdLGVbNF09dFs0XS1uWzRdLGVbNV09dFs1XS1uWzVdLGVbNl09dFs2XS1uWzZdLGVbN109dFs3XS1uWzddLGVbOF09dFs4XS1uWzhdLGVbOV09dFs5XS1uWzldLGVbMTBdPXRbMTBdLW5bMTBdLGVbMTFdPXRbMTFdLW5bMTFdLGVbMTJdPXRbMTJdLW5bMTJdLGVbMTNdPXRbMTNdLW5bMTNdLGVbMTRdPXRbMTRdLW5bMTRdLGVbMTVdPXRbMTVdLW5bMTVdLGV9ZnVuY3Rpb24gWGgoZSx0LG4pe3JldHVybiBlWzBdPXRbMF0qbixlWzFdPXRbMV0qbixlWzJdPXRbMl0qbixlWzNdPXRbM10qbixlWzRdPXRbNF0qbixlWzVdPXRbNV0qbixlWzZdPXRbNl0qbixlWzddPXRbN10qbixlWzhdPXRbOF0qbixlWzldPXRbOV0qbixlWzEwXT10WzEwXSpuLGVbMTFdPXRbMTFdKm4sZVsxMl09dFsxMl0qbixlWzEzXT10WzEzXSpuLGVbMTRdPXRbMTRdKm4sZVsxNV09dFsxNV0qbixlfWZ1bmN0aW9uIEdoKGUsdCxuLHIpe3JldHVybiBlWzBdPXRbMF0rblswXSpyLGVbMV09dFsxXStuWzFdKnIsZVsyXT10WzJdK25bMl0qcixlWzNdPXRbM10rblszXSpyLGVbNF09dFs0XStuWzRdKnIsZVs1XT10WzVdK25bNV0qcixlWzZdPXRbNl0rbls2XSpyLGVbN109dFs3XStuWzddKnIsZVs4XT10WzhdK25bOF0qcixlWzldPXRbOV0rbls5XSpyLGVbMTBdPXRbMTBdK25bMTBdKnIsZVsxMV09dFsxMV0rblsxMV0qcixlWzEyXT10WzEyXStuWzEyXSpyLGVbMTNdPXRbMTNdK25bMTNdKnIsZVsxNF09dFsxNF0rblsxNF0qcixlWzE1XT10WzE1XStuWzE1XSpyLGV9ZnVuY3Rpb24gamgoZSx0KXtyZXR1cm4gZVswXT09PXRbMF0mJmVbMV09PT10WzFdJiZlWzJdPT09dFsyXSYmZVszXT09PXRbM10mJmVbNF09PT10WzRdJiZlWzVdPT09dFs1XSYmZVs2XT09PXRbNl0mJmVbN109PT10WzddJiZlWzhdPT09dFs4XSYmZVs5XT09PXRbOV0mJmVbMTBdPT09dFsxMF0mJmVbMTFdPT09dFsxMV0mJmVbMTJdPT09dFsxMl0mJmVbMTNdPT09dFsxM10mJmVbMTRdPT09dFsxNF0mJmVbMTVdPT09dFsxNV19ZnVuY3Rpb24gUWgoZSx0KXtjb25zdCBuPWVbMF0scj1lWzFdLGk9ZVsyXSxzPWVbM10sbz1lWzRdLGM9ZVs1XSxhPWVbNl0saD1lWzddLGY9ZVs4XSx1PWVbOV0sZD1lWzEwXSxnPWVbMTFdLG09ZVsxMl0sXz1lWzEzXSxwPWVbMTRdLHg9ZVsxNV0sVD10WzBdLE09dFsxXSxBPXRbMl0sdj10WzNdLHc9dFs0XSxQPXRbNV0sYj10WzZdLFM9dFs3XSxPPXRbOF0sVj10WzldLHo9dFsxMF0sTj10WzExXSxSPXRbMTJdLGV0PXRbMTNdLEI9dFsxNF0sWD10WzE1XTtyZXR1cm4gTWF0aC5hYnMobi1UKTw9SSpNYXRoLm1heCgxLE1hdGguYWJzKG4pLE1hdGguYWJzKFQpKSYmTWF0aC5hYnMoci1NKTw9SSpNYXRoLm1heCgxLE1hdGguYWJzKHIpLE1hdGguYWJzKE0pKSYmTWF0aC5hYnMoaS1BKTw9SSpNYXRoLm1heCgxLE1hdGguYWJzKGkpLE1hdGguYWJzKEEpKSYmTWF0aC5hYnMocy12KTw9SSpNYXRoLm1heCgxLE1hdGguYWJzKHMpLE1hdGguYWJzKHYpKSYmTWF0aC5hYnMoby13KTw9SSpNYXRoLm1heCgxLE1hdGguYWJzKG8pLE1hdGguYWJzKHcpKSYmTWF0aC5hYnMoYy1QKTw9SSpNYXRoLm1heCgxLE1hdGguYWJzKGMpLE1hdGguYWJzKFApKSYmTWF0aC5hYnMoYS1iKTw9SSpNYXRoLm1heCgxLE1hdGguYWJzKGEpLE1hdGguYWJzKGIpKSYmTWF0aC5hYnMoaC1TKTw9SSpNYXRoLm1heCgxLE1hdGguYWJzKGgpLE1hdGguYWJzKFMpKSYmTWF0aC5hYnMoZi1PKTw9SSpNYXRoLm1heCgxLE1hdGguYWJzKGYpLE1hdGguYWJzKE8pKSYmTWF0aC5hYnModS1WKTw9SSpNYXRoLm1heCgxLE1hdGguYWJzKHUpLE1hdGguYWJzKFYpKSYmTWF0aC5hYnMoZC16KTw9SSpNYXRoLm1heCgxLE1hdGguYWJzKGQpLE1hdGguYWJzKHopKSYmTWF0aC5hYnMoZy1OKTw9SSpNYXRoLm1heCgxLE1hdGguYWJzKGcpLE1hdGguYWJzKE4pKSYmTWF0aC5hYnMobS1SKTw9SSpNYXRoLm1heCgxLE1hdGguYWJzKG0pLE1hdGguYWJzKFIpKSYmTWF0aC5hYnMoXy1ldCk8PUkqTWF0aC5tYXgoMSxNYXRoLmFicyhfKSxNYXRoLmFicyhldCkpJiZNYXRoLmFicyhwLUIpPD1JKk1hdGgubWF4KDEsTWF0aC5hYnMocCksTWF0aC5hYnMoQikpJiZNYXRoLmFicyh4LVgpPD1JKk1hdGgubWF4KDEsTWF0aC5hYnMoeCksTWF0aC5hYnMoWCkpfXZhciBLaD1PYmplY3QuZnJlZXplKHtfX3Byb3RvX186bnVsbCxhZGQ6WmgsYWRqb2ludDpJaCxjbG9uZTp2aCxjb3B5OkVoLGNyZWF0ZTpPaCxkZWNvbXBvc2U6emgsZGV0ZXJtaW5hbnQ6eW4sZXF1YWxzOlFoLGV4YWN0RXF1YWxzOmpoLGZyb2I6V2gsZnJvbVF1YXQ6U3MsZnJvbVF1YXQyOk5oLGZyb21Sb3RhdGlvbjpSaCxmcm9tUm90YXRpb25UcmFuc2xhdGlvbjp2cyxmcm9tUm90YXRpb25UcmFuc2xhdGlvblNjYWxlOnFoLGZyb21Sb3RhdGlvblRyYW5zbGF0aW9uU2NhbGVPcmlnaW46RmgsZnJvbVNjYWxpbmc6TGgsZnJvbVRyYW5zbGF0aW9uOlBoLGZyb21WYWx1ZXM6YmgsZnJvbVhSb3RhdGlvbjokaCxmcm9tWVJvdGF0aW9uOkNoLGZyb21aUm90YXRpb246VmgsZnJ1c3R1bTpJcyxnZXRSb3RhdGlvbjpicyxnZXRTY2FsaW5nOkVzLGdldFRyYW5zbGF0aW9uOk1uLGlkZW50aXR5Ol9zLGludmVydDpUcixsb29rQXQ6Q3MsbXVsOnhuLG11bHRpcGx5OnhuLG11bHRpcGx5U2NhbGFyOlhoLG11bHRpcGx5U2NhbGFyQW5kQWRkOkdoLG9ydGhvOiRzLG9ydGhvTk86UnMsb3J0aG9aTzpVaCxwZXJzcGVjdGl2ZTpMcyxwZXJzcGVjdGl2ZUZyb21GaWVsZE9mVmlldzpCaCxwZXJzcGVjdGl2ZU5POlBzLHBlcnNwZWN0aXZlWk86a2gscm90YXRlOndzLHJvdGF0ZVg6VHMscm90YXRlWTpBcyxyb3RhdGVaOk9zLHNjYWxlOk1zLHNldDpTaCxzdHI6WWgsc3ViOlZzLHN1YnRyYWN0OlZzLHRhcmdldFRvOkRoLHRyYW5zbGF0ZTp4cyx0cmFuc3Bvc2U6eXN9KTtmdW5jdGlvbiBOcygpe2NvbnN0IGU9bmV3IEMoNCk7cmV0dXJuIEMhPUZsb2F0MzJBcnJheSYmKGVbMF09MCxlWzFdPTAsZVsyXT0wLGVbM109MCksZX1mdW5jdGlvbiBIaChlKXtjb25zdCB0PW5ldyBDKDQpO3JldHVybiB0WzBdPWVbMF0sdFsxXT1lWzFdLHRbMl09ZVsyXSx0WzNdPWVbM10sdH1mdW5jdGlvbiBKaChlLHQsbixyKXtjb25zdCBpPW5ldyBDKDQpO3JldHVybiBpWzBdPWUsaVsxXT10LGlbMl09bixpWzNdPXIsaX1mdW5jdGlvbiB6cyhlLHQpe3JldHVybiBlWzBdPXRbMF0sZVsxXT10WzFdLGVbMl09dFsyXSxlWzNdPXRbM10sZX1mdW5jdGlvbiB0ZihlLHQsbixyLGkpe3JldHVybiBlWzBdPXQsZVsxXT1uLGVbMl09cixlWzNdPWksZX1mdW5jdGlvbiBxcyhlLHQsbil7cmV0dXJuIGVbMF09dFswXStuWzBdLGVbMV09dFsxXStuWzFdLGVbMl09dFsyXStuWzJdLGVbM109dFszXStuWzNdLGV9ZnVuY3Rpb24gRnMoZSx0LG4pe3JldHVybiBlWzBdPXRbMF0tblswXSxlWzFdPXRbMV0tblsxXSxlWzJdPXRbMl0tblsyXSxlWzNdPXRbM10tblszXSxlfWZ1bmN0aW9uIGtzKGUsdCxuKXtyZXR1cm4gZVswXT10WzBdKm5bMF0sZVsxXT10WzFdKm5bMV0sZVsyXT10WzJdKm5bMl0sZVszXT10WzNdKm5bM10sZX1mdW5jdGlvbiBCcyhlLHQsbil7cmV0dXJuIGVbMF09dFswXS9uWzBdLGVbMV09dFsxXS9uWzFdLGVbMl09dFsyXS9uWzJdLGVbM109dFszXS9uWzNdLGV9ZnVuY3Rpb24gZWYoZSx0KXtyZXR1cm4gZVswXT1NYXRoLmNlaWwodFswXSksZVsxXT1NYXRoLmNlaWwodFsxXSksZVsyXT1NYXRoLmNlaWwodFsyXSksZVszXT1NYXRoLmNlaWwodFszXSksZX1mdW5jdGlvbiBuZihlLHQpe3JldHVybiBlWzBdPU1hdGguZmxvb3IodFswXSksZVsxXT1NYXRoLmZsb29yKHRbMV0pLGVbMl09TWF0aC5mbG9vcih0WzJdKSxlWzNdPU1hdGguZmxvb3IodFszXSksZX1mdW5jdGlvbiByZihlLHQsbil7cmV0dXJuIGVbMF09TWF0aC5taW4odFswXSxuWzBdKSxlWzFdPU1hdGgubWluKHRbMV0sblsxXSksZVsyXT1NYXRoLm1pbih0WzJdLG5bMl0pLGVbM109TWF0aC5taW4odFszXSxuWzNdKSxlfWZ1bmN0aW9uIHNmKGUsdCxuKXtyZXR1cm4gZVswXT1NYXRoLm1heCh0WzBdLG5bMF0pLGVbMV09TWF0aC5tYXgodFsxXSxuWzFdKSxlWzJdPU1hdGgubWF4KHRbMl0sblsyXSksZVszXT1NYXRoLm1heCh0WzNdLG5bM10pLGV9ZnVuY3Rpb24gb2YoZSx0KXtyZXR1cm4gZVswXT1idCh0WzBdKSxlWzFdPWJ0KHRbMV0pLGVbMl09YnQodFsyXSksZVszXT1idCh0WzNdKSxlfWZ1bmN0aW9uIFVzKGUsdCxuKXtyZXR1cm4gZVswXT10WzBdKm4sZVsxXT10WzFdKm4sZVsyXT10WzJdKm4sZVszXT10WzNdKm4sZX1mdW5jdGlvbiBjZihlLHQsbixyKXtyZXR1cm4gZVswXT10WzBdK25bMF0qcixlWzFdPXRbMV0rblsxXSpyLGVbMl09dFsyXStuWzJdKnIsZVszXT10WzNdK25bM10qcixlfWZ1bmN0aW9uIERzKGUsdCl7Y29uc3Qgbj10WzBdLWVbMF0scj10WzFdLWVbMV0saT10WzJdLWVbMl0scz10WzNdLWVbM107cmV0dXJuIE1hdGguc3FydChuKm4rcipyK2kqaStzKnMpfWZ1bmN0aW9uIFlzKGUsdCl7Y29uc3Qgbj10WzBdLWVbMF0scj10WzFdLWVbMV0saT10WzJdLWVbMl0scz10WzNdLWVbM107cmV0dXJuIG4qbityKnIraSppK3Mqc31mdW5jdGlvbiBBcihlKXtjb25zdCB0PWVbMF0sbj1lWzFdLHI9ZVsyXSxpPWVbM107cmV0dXJuIE1hdGguc3FydCh0KnQrbipuK3IqcitpKmkpfWZ1bmN0aW9uIE9yKGUpe2NvbnN0IHQ9ZVswXSxuPWVbMV0scj1lWzJdLGk9ZVszXTtyZXR1cm4gdCp0K24qbityKnIraSppfWZ1bmN0aW9uIGFmKGUsdCl7cmV0dXJuIGVbMF09LXRbMF0sZVsxXT0tdFsxXSxlWzJdPS10WzJdLGVbM109LXRbM10sZX1mdW5jdGlvbiBsZihlLHQpe3JldHVybiBlWzBdPTEvdFswXSxlWzFdPTEvdFsxXSxlWzJdPTEvdFsyXSxlWzNdPTEvdFszXSxlfWZ1bmN0aW9uIFdzKGUsdCl7Y29uc3Qgbj10WzBdLHI9dFsxXSxpPXRbMl0scz10WzNdO2xldCBvPW4qbityKnIraSppK3MqcztyZXR1cm4gbz4wJiYobz0xL01hdGguc3FydChvKSksZVswXT1uKm8sZVsxXT1yKm8sZVsyXT1pKm8sZVszXT1zKm8sZX1mdW5jdGlvbiBacyhlLHQpe3JldHVybiBlWzBdKnRbMF0rZVsxXSp0WzFdK2VbMl0qdFsyXStlWzNdKnRbM119ZnVuY3Rpb24gaGYoZSx0LG4scil7Y29uc3QgaT1uWzBdKnJbMV0tblsxXSpyWzBdLHM9blswXSpyWzJdLW5bMl0qclswXSxvPW5bMF0qclszXS1uWzNdKnJbMF0sYz1uWzFdKnJbMl0tblsyXSpyWzFdLGE9blsxXSpyWzNdLW5bM10qclsxXSxoPW5bMl0qclszXS1uWzNdKnJbMl0sZj10WzBdLHU9dFsxXSxkPXRbMl0sZz10WzNdO3JldHVybiBlWzBdPXUqaC1kKmErZypjLGVbMV09LShmKmgpK2Qqby1nKnMsZVsyXT1mKmEtdSpvK2cqaSxlWzNdPS0oZipjKSt1KnMtZCppLGV9ZnVuY3Rpb24gWHMoZSx0LG4scil7Y29uc3QgaT10WzBdLHM9dFsxXSxvPXRbMl0sYz10WzNdO3JldHVybiBlWzBdPWkrciooblswXS1pKSxlWzFdPXMrciooblsxXS1zKSxlWzJdPW8rciooblsyXS1vKSxlWzNdPWMrciooblszXS1jKSxlfWZ1bmN0aW9uIGZmKGUsdCl7dD10PT09dm9pZCAwPzE6dDtsZXQgbixyLGkscyxvLGM7ZG8gbj1qdCgpKjItMSxyPWp0KCkqMi0xLG89bipuK3Iqcjt3aGlsZShvPj0xKTtkbyBpPWp0KCkqMi0xLHM9anQoKSoyLTEsYz1pKmkrcypzO3doaWxlKGM+PTEpO2NvbnN0IGE9TWF0aC5zcXJ0KCgxLW8pL2MpO3JldHVybiBlWzBdPXQqbixlWzFdPXQqcixlWzJdPXQqaSphLGVbM109dCpzKmEsZX1mdW5jdGlvbiBHcyhlLHQsbil7Y29uc3Qgcj10WzBdLGk9dFsxXSxzPXRbMl0sbz10WzNdO3JldHVybiBlWzBdPW5bMF0qcituWzRdKmkrbls4XSpzK25bMTJdKm8sZVsxXT1uWzFdKnIrbls1XSppK25bOV0qcytuWzEzXSpvLGVbMl09blsyXSpyK25bNl0qaStuWzEwXSpzK25bMTRdKm8sZVszXT1uWzNdKnIrbls3XSppK25bMTFdKnMrblsxNV0qbyxlfWZ1bmN0aW9uIGpzKGUsdCxuKXtjb25zdCByPXRbMF0saT10WzFdLHM9dFsyXSxvPW5bMF0sYz1uWzFdLGE9blsyXSxoPW5bM10sZj1oKnIrYypzLWEqaSx1PWgqaSthKnItbypzLGQ9aCpzK28qaS1jKnIsZz0tbypyLWMqaS1hKnM7cmV0dXJuIGVbMF09ZipoK2cqLW8rdSotYS1kKi1jLGVbMV09dSpoK2cqLWMrZCotby1mKi1hLGVbMl09ZCpoK2cqLWErZiotYy11Ki1vLGVbM109dFszXSxlfWZ1bmN0aW9uIHVmKGUpe3JldHVybiBlWzBdPTAsZVsxXT0wLGVbMl09MCxlWzNdPTAsZX1mdW5jdGlvbiBkZihlKXtyZXR1cm5gdmVjNCgke2VbMF19LCAke2VbMV19LCAke2VbMl19LCAke2VbM119KWB9ZnVuY3Rpb24gZ2YoZSx0KXtyZXR1cm4gZVswXT09PXRbMF0mJmVbMV09PT10WzFdJiZlWzJdPT09dFsyXSYmZVszXT09PXRbM119ZnVuY3Rpb24gbWYoZSx0KXtjb25zdCBuPWVbMF0scj1lWzFdLGk9ZVsyXSxzPWVbM10sbz10WzBdLGM9dFsxXSxhPXRbMl0saD10WzNdO3JldHVybiBNYXRoLmFicyhuLW8pPD1JKk1hdGgubWF4KDEsTWF0aC5hYnMobiksTWF0aC5hYnMobykpJiZNYXRoLmFicyhyLWMpPD1JKk1hdGgubWF4KDEsTWF0aC5hYnMociksTWF0aC5hYnMoYykpJiZNYXRoLmFicyhpLWEpPD1JKk1hdGgubWF4KDEsTWF0aC5hYnMoaSksTWF0aC5hYnMoYSkpJiZNYXRoLmFicyhzLWgpPD1JKk1hdGgubWF4KDEsTWF0aC5hYnMocyksTWF0aC5hYnMoaCkpfWNvbnN0IHBmPUZzLF9mPWtzLHlmPUJzLHhmPURzLE1mPVlzLHdmPUFyLFRmPU9yLEFmPWZ1bmN0aW9uKCl7Y29uc3QgZT1OcygpO3JldHVybiBmdW5jdGlvbih0LG4scixpLHMsbyl7bGV0IGMsYTtmb3Iobnx8KG49NCkscnx8KHI9MCksaT9hPU1hdGgubWluKGkqbityLHQubGVuZ3RoKTphPXQubGVuZ3RoLGM9cjtjPGE7Yys9billWzBdPXRbY10sZVsxXT10W2MrMV0sZVsyXT10W2MrMl0sZVszXT10W2MrM10scyhlLGUsbyksdFtjXT1lWzBdLHRbYysxXT1lWzFdLHRbYysyXT1lWzJdLHRbYyszXT1lWzNdO3JldHVybiB0fX0oKTt2YXIgT2Y9T2JqZWN0LmZyZWV6ZSh7X19wcm90b19fOm51bGwsYWRkOnFzLGNlaWw6ZWYsY2xvbmU6SGgsY29weTp6cyxjcmVhdGU6TnMsY3Jvc3M6aGYsZGlzdDp4ZixkaXN0YW5jZTpEcyxkaXY6eWYsZGl2aWRlOkJzLGRvdDpacyxlcXVhbHM6bWYsZXhhY3RFcXVhbHM6Z2YsZmxvb3I6bmYsZm9yRWFjaDpBZixmcm9tVmFsdWVzOkpoLGludmVyc2U6bGYsbGVuOndmLGxlbmd0aDpBcixsZXJwOlhzLG1heDpzZixtaW46cmYsbXVsOl9mLG11bHRpcGx5OmtzLG5lZ2F0ZTphZixub3JtYWxpemU6V3MscmFuZG9tOmZmLHJvdW5kOm9mLHNjYWxlOlVzLHNjYWxlQW5kQWRkOmNmLHNldDp0ZixzcXJEaXN0Ok1mLHNxckxlbjpUZixzcXVhcmVkRGlzdGFuY2U6WXMsc3F1YXJlZExlbmd0aDpPcixzdHI6ZGYsc3ViOnBmLHN1YnRyYWN0OkZzLHRyYW5zZm9ybU1hdDQ6R3MsdHJhbnNmb3JtUXVhdDpqcyx6ZXJvOnVmfSksdnI7KGZ1bmN0aW9uKGUpe2VbZS5DT0wwUk9XMD0wXT0iQ09MMFJPVzAiLGVbZS5DT0wwUk9XMT0xXT0iQ09MMFJPVzEiLGVbZS5DT0wwUk9XMj0yXT0iQ09MMFJPVzIiLGVbZS5DT0wwUk9XMz0zXT0iQ09MMFJPVzMiLGVbZS5DT0wxUk9XMD00XT0iQ09MMVJPVzAiLGVbZS5DT0wxUk9XMT01XT0iQ09MMVJPVzEiLGVbZS5DT0wxUk9XMj02XT0iQ09MMVJPVzIiLGVbZS5DT0wxUk9XMz03XT0iQ09MMVJPVzMiLGVbZS5DT0wyUk9XMD04XT0iQ09MMlJPVzAiLGVbZS5DT0wyUk9XMT05XT0iQ09MMlJPVzEiLGVbZS5DT0wyUk9XMj0xMF09IkNPTDJST1cyIixlW2UuQ09MMlJPVzM9MTFdPSJDT0wyUk9XMyIsZVtlLkNPTDNST1cwPTEyXT0iQ09MM1JPVzAiLGVbZS5DT0wzUk9XMT0xM109IkNPTDNST1cxIixlW2UuQ09MM1JPVzI9MTRdPSJDT0wzUk9XMiIsZVtlLkNPTDNST1czPTE1XT0iQ09MM1JPVzMifSkodnJ8fCh2cj17fSkpO2NvbnN0IHZmPTQ1Kk1hdGguUEkvMTgwLEVmPTEsRXI9LjEsYnI9NTAwLGJmPU9iamVjdC5mcmVlemUoWzEsMCwwLDAsMCwxLDAsMCwwLDAsMSwwLDAsMCwwLDFdKTtjbGFzcyBvdCBleHRlbmRzIGRue3N0YXRpYyBnZXQgSURFTlRJVFkoKXtyZXR1cm4gSWYoKX1zdGF0aWMgZ2V0IFpFUk8oKXtyZXR1cm4gU2YoKX1nZXQgRUxFTUVOVFMoKXtyZXR1cm4gMTZ9Z2V0IFJBTksoKXtyZXR1cm4gNH1nZXQgSU5ESUNFUygpe3JldHVybiB2cn1jb25zdHJ1Y3Rvcih0KXtzdXBlcigtMCwtMCwtMCwtMCwtMCwtMCwtMCwtMCwtMCwtMCwtMCwtMCwtMCwtMCwtMCwtMCksYXJndW1lbnRzLmxlbmd0aD09PTEmJkFycmF5LmlzQXJyYXkodCk/dGhpcy5jb3B5KHQpOnRoaXMuaWRlbnRpdHkoKX1jb3B5KHQpe3JldHVybiB0aGlzWzBdPXRbMF0sdGhpc1sxXT10WzFdLHRoaXNbMl09dFsyXSx0aGlzWzNdPXRbM10sdGhpc1s0XT10WzRdLHRoaXNbNV09dFs1XSx0aGlzWzZdPXRbNl0sdGhpc1s3XT10WzddLHRoaXNbOF09dFs4XSx0aGlzWzldPXRbOV0sdGhpc1sxMF09dFsxMF0sdGhpc1sxMV09dFsxMV0sdGhpc1sxMl09dFsxMl0sdGhpc1sxM109dFsxM10sdGhpc1sxNF09dFsxNF0sdGhpc1sxNV09dFsxNV0sdGhpcy5jaGVjaygpfXNldCh0LG4scixpLHMsbyxjLGEsaCxmLHUsZCxnLG0sXyxwKXtyZXR1cm4gdGhpc1swXT10LHRoaXNbMV09bix0aGlzWzJdPXIsdGhpc1szXT1pLHRoaXNbNF09cyx0aGlzWzVdPW8sdGhpc1s2XT1jLHRoaXNbN109YSx0aGlzWzhdPWgsdGhpc1s5XT1mLHRoaXNbMTBdPXUsdGhpc1sxMV09ZCx0aGlzWzEyXT1nLHRoaXNbMTNdPW0sdGhpc1sxNF09Xyx0aGlzWzE1XT1wLHRoaXMuY2hlY2soKX1zZXRSb3dNYWpvcih0LG4scixpLHMsbyxjLGEsaCxmLHUsZCxnLG0sXyxwKXtyZXR1cm4gdGhpc1swXT10LHRoaXNbMV09cyx0aGlzWzJdPWgsdGhpc1szXT1nLHRoaXNbNF09bix0aGlzWzVdPW8sdGhpc1s2XT1mLHRoaXNbN109bSx0aGlzWzhdPXIsdGhpc1s5XT1jLHRoaXNbMTBdPXUsdGhpc1sxMV09Xyx0aGlzWzEyXT1pLHRoaXNbMTNdPWEsdGhpc1sxNF09ZCx0aGlzWzE1XT1wLHRoaXMuY2hlY2soKX10b1Jvd01ham9yKHQpe3JldHVybiB0WzBdPXRoaXNbMF0sdFsxXT10aGlzWzRdLHRbMl09dGhpc1s4XSx0WzNdPXRoaXNbMTJdLHRbNF09dGhpc1sxXSx0WzVdPXRoaXNbNV0sdFs2XT10aGlzWzldLHRbN109dGhpc1sxM10sdFs4XT10aGlzWzJdLHRbOV09dGhpc1s2XSx0WzEwXT10aGlzWzEwXSx0WzExXT10aGlzWzE0XSx0WzEyXT10aGlzWzNdLHRbMTNdPXRoaXNbN10sdFsxNF09dGhpc1sxMV0sdFsxNV09dGhpc1sxNV0sdH1pZGVudGl0eSgpe3JldHVybiB0aGlzLmNvcHkoYmYpfWZyb21PYmplY3QodCl7cmV0dXJuIHRoaXMuY2hlY2soKX1mcm9tUXVhdGVybmlvbih0KXtyZXR1cm4gU3ModGhpcyx0KSx0aGlzLmNoZWNrKCl9ZnJ1c3R1bSh0KXtjb25zdHtsZWZ0Om4scmlnaHQ6cixib3R0b206aSx0b3A6cyxuZWFyOm89RXIsZmFyOmM9YnJ9PXQ7cmV0dXJuIGM9PT0xLzA/UGYodGhpcyxuLHIsaSxzLG8pOklzKHRoaXMsbixyLGkscyxvLGMpLHRoaXMuY2hlY2soKX1sb29rQXQodCl7Y29uc3R7ZXllOm4sY2VudGVyOnI9WzAsMCwwXSx1cDppPVswLDEsMF19PXQ7cmV0dXJuIENzKHRoaXMsbixyLGkpLHRoaXMuY2hlY2soKX1vcnRobyh0KXtjb25zdHtsZWZ0Om4scmlnaHQ6cixib3R0b206aSx0b3A6cyxuZWFyOm89RXIsZmFyOmM9YnJ9PXQ7cmV0dXJuICRzKHRoaXMsbixyLGkscyxvLGMpLHRoaXMuY2hlY2soKX1vcnRob2dyYXBoaWModCl7Y29uc3R7Zm92eTpuPXZmLGFzcGVjdDpyPUVmLGZvY2FsRGlzdGFuY2U6aT0xLG5lYXI6cz1FcixmYXI6bz1icn09dDtRcyhuKTtjb25zdCBjPW4vMixhPWkqTWF0aC50YW4oYyksaD1hKnI7cmV0dXJuIHRoaXMub3J0aG8oe2xlZnQ6LWgscmlnaHQ6aCxib3R0b206LWEsdG9wOmEsbmVhcjpzLGZhcjpvfSl9cGVyc3BlY3RpdmUodCl7Y29uc3R7Zm92eTpuPTQ1Kk1hdGguUEkvMTgwLGFzcGVjdDpyPTEsbmVhcjppPS4xLGZhcjpzPTUwMH09dDtyZXR1cm4gUXMobiksTHModGhpcyxuLHIsaSxzKSx0aGlzLmNoZWNrKCl9ZGV0ZXJtaW5hbnQoKXtyZXR1cm4geW4odGhpcyl9Z2V0U2NhbGUodD1bLTAsLTAsLTBdKXtyZXR1cm4gdFswXT1NYXRoLnNxcnQodGhpc1swXSp0aGlzWzBdK3RoaXNbMV0qdGhpc1sxXSt0aGlzWzJdKnRoaXNbMl0pLHRbMV09TWF0aC5zcXJ0KHRoaXNbNF0qdGhpc1s0XSt0aGlzWzVdKnRoaXNbNV0rdGhpc1s2XSp0aGlzWzZdKSx0WzJdPU1hdGguc3FydCh0aGlzWzhdKnRoaXNbOF0rdGhpc1s5XSp0aGlzWzldK3RoaXNbMTBdKnRoaXNbMTBdKSx0fWdldFRyYW5zbGF0aW9uKHQ9Wy0wLC0wLC0wXSl7cmV0dXJuIHRbMF09dGhpc1sxMl0sdFsxXT10aGlzWzEzXSx0WzJdPXRoaXNbMTRdLHR9Z2V0Um90YXRpb24odCxuKXt0PXR8fFstMCwtMCwtMCwtMCwtMCwtMCwtMCwtMCwtMCwtMCwtMCwtMCwtMCwtMCwtMCwtMF0sbj1ufHxbLTAsLTAsLTBdO2NvbnN0IHI9dGhpcy5nZXRTY2FsZShuKSxpPTEvclswXSxzPTEvclsxXSxvPTEvclsyXTtyZXR1cm4gdFswXT10aGlzWzBdKmksdFsxXT10aGlzWzFdKnMsdFsyXT10aGlzWzJdKm8sdFszXT0wLHRbNF09dGhpc1s0XSppLHRbNV09dGhpc1s1XSpzLHRbNl09dGhpc1s2XSpvLHRbN109MCx0WzhdPXRoaXNbOF0qaSx0WzldPXRoaXNbOV0qcyx0WzEwXT10aGlzWzEwXSpvLHRbMTFdPTAsdFsxMl09MCx0WzEzXT0wLHRbMTRdPTAsdFsxNV09MSx0fWdldFJvdGF0aW9uTWF0cml4Myh0LG4pe3Q9dHx8Wy0wLC0wLC0wLC0wLC0wLC0wLC0wLC0wLC0wXSxuPW58fFstMCwtMCwtMF07Y29uc3Qgcj10aGlzLmdldFNjYWxlKG4pLGk9MS9yWzBdLHM9MS9yWzFdLG89MS9yWzJdO3JldHVybiB0WzBdPXRoaXNbMF0qaSx0WzFdPXRoaXNbMV0qcyx0WzJdPXRoaXNbMl0qbyx0WzNdPXRoaXNbNF0qaSx0WzRdPXRoaXNbNV0qcyx0WzVdPXRoaXNbNl0qbyx0WzZdPXRoaXNbOF0qaSx0WzddPXRoaXNbOV0qcyx0WzhdPXRoaXNbMTBdKm8sdH10cmFuc3Bvc2UoKXtyZXR1cm4geXModGhpcyx0aGlzKSx0aGlzLmNoZWNrKCl9aW52ZXJ0KCl7cmV0dXJuIFRyKHRoaXMsdGhpcyksdGhpcy5jaGVjaygpfW11bHRpcGx5TGVmdCh0KXtyZXR1cm4geG4odGhpcyx0LHRoaXMpLHRoaXMuY2hlY2soKX1tdWx0aXBseVJpZ2h0KHQpe3JldHVybiB4bih0aGlzLHRoaXMsdCksdGhpcy5jaGVjaygpfXJvdGF0ZVgodCl7cmV0dXJuIFRzKHRoaXMsdGhpcyx0KSx0aGlzLmNoZWNrKCl9cm90YXRlWSh0KXtyZXR1cm4gQXModGhpcyx0aGlzLHQpLHRoaXMuY2hlY2soKX1yb3RhdGVaKHQpe3JldHVybiBPcyh0aGlzLHRoaXMsdCksdGhpcy5jaGVjaygpfXJvdGF0ZVhZWih0KXtyZXR1cm4gdGhpcy5yb3RhdGVYKHRbMF0pLnJvdGF0ZVkodFsxXSkucm90YXRlWih0WzJdKX1yb3RhdGVBeGlzKHQsbil7cmV0dXJuIHdzKHRoaXMsdGhpcyx0LG4pLHRoaXMuY2hlY2soKX1zY2FsZSh0KXtyZXR1cm4gTXModGhpcyx0aGlzLEFycmF5LmlzQXJyYXkodCk/dDpbdCx0LHRdKSx0aGlzLmNoZWNrKCl9dHJhbnNsYXRlKHQpe3JldHVybiB4cyh0aGlzLHRoaXMsdCksdGhpcy5jaGVjaygpfXRyYW5zZm9ybSh0LG4pe3JldHVybiB0Lmxlbmd0aD09PTQ/KG49R3Mobnx8Wy0wLC0wLC0wLC0wXSx0LHRoaXMpLEd0KG4sNCksbik6dGhpcy50cmFuc2Zvcm1Bc1BvaW50KHQsbil9dHJhbnNmb3JtQXNQb2ludCh0LG4pe2NvbnN0e2xlbmd0aDpyfT10O2xldCBpO3N3aXRjaChyKXtjYXNlIDI6aT1vcihufHxbLTAsLTBdLHQsdGhpcyk7YnJlYWs7Y2FzZSAzOmk9aG4obnx8Wy0wLC0wLC0wXSx0LHRoaXMpO2JyZWFrO2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKCJJbGxlZ2FsIHZlY3RvciIpfXJldHVybiBHdChpLHQubGVuZ3RoKSxpfXRyYW5zZm9ybUFzVmVjdG9yKHQsbil7bGV0IHI7c3dpdGNoKHQubGVuZ3RoKXtjYXNlIDI6cj1jcihufHxbLTAsLTBdLHQsdGhpcyk7YnJlYWs7Y2FzZSAzOnI9YXIobnx8Wy0wLC0wLC0wXSx0LHRoaXMpO2JyZWFrO2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKCJJbGxlZ2FsIHZlY3RvciIpfXJldHVybiBHdChyLHQubGVuZ3RoKSxyfXRyYW5zZm9ybVBvaW50KHQsbil7cmV0dXJuIHRoaXMudHJhbnNmb3JtQXNQb2ludCh0LG4pfXRyYW5zZm9ybVZlY3Rvcih0LG4pe3JldHVybiB0aGlzLnRyYW5zZm9ybUFzUG9pbnQodCxuKX10cmFuc2Zvcm1EaXJlY3Rpb24odCxuKXtyZXR1cm4gdGhpcy50cmFuc2Zvcm1Bc1ZlY3Rvcih0LG4pfW1ha2VSb3RhdGlvblgodCl7cmV0dXJuIHRoaXMuaWRlbnRpdHkoKS5yb3RhdGVYKHQpfW1ha2VUcmFuc2xhdGlvbih0LG4scil7cmV0dXJuIHRoaXMuaWRlbnRpdHkoKS50cmFuc2xhdGUoW3QsbixyXSl9fWxldCB3bixUbjtmdW5jdGlvbiBTZigpe3JldHVybiB3bnx8KHduPW5ldyBvdChbMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMF0pLE9iamVjdC5mcmVlemUod24pKSx3bn1mdW5jdGlvbiBJZigpe3JldHVybiBUbnx8KFRuPW5ldyBvdCxPYmplY3QuZnJlZXplKFRuKSksVG59ZnVuY3Rpb24gUXMoZSl7aWYoZT5NYXRoLlBJKjIpdGhyb3cgRXJyb3IoImV4cGVjdGVkIHJhZGlhbnMiKX1mdW5jdGlvbiBQZihlLHQsbixyLGkscyl7Y29uc3Qgbz0yKnMvKG4tdCksYz0yKnMvKGktciksYT0obit0KS8obi10KSxoPShpK3IpLyhpLXIpLGY9LTEsdT0tMSxkPS0yKnM7cmV0dXJuIGVbMF09byxlWzFdPTAsZVsyXT0wLGVbM109MCxlWzRdPTAsZVs1XT1jLGVbNl09MCxlWzddPTAsZVs4XT1hLGVbOV09aCxlWzEwXT1mLGVbMTFdPXUsZVsxMl09MCxlWzEzXT0wLGVbMTRdPWQsZVsxNV09MCxlfWZ1bmN0aW9uIFNyKCl7Y29uc3QgZT1uZXcgQyg0KTtyZXR1cm4gQyE9RmxvYXQzMkFycmF5JiYoZVswXT0wLGVbMV09MCxlWzJdPTApLGVbM109MSxlfWZ1bmN0aW9uIEtzKGUpe3JldHVybiBlWzBdPTAsZVsxXT0wLGVbMl09MCxlWzNdPTEsZX1mdW5jdGlvbiBIcyhlLHQsbil7bj1uKi41O2NvbnN0IHI9TWF0aC5zaW4obik7cmV0dXJuIGVbMF09cip0WzBdLGVbMV09cip0WzFdLGVbMl09cip0WzJdLGVbM109TWF0aC5jb3MobiksZX1mdW5jdGlvbiBKcyhlLHQsbil7Y29uc3Qgcj10WzBdLGk9dFsxXSxzPXRbMl0sbz10WzNdLGM9blswXSxhPW5bMV0saD1uWzJdLGY9blszXTtyZXR1cm4gZVswXT1yKmYrbypjK2kqaC1zKmEsZVsxXT1pKmYrbyphK3MqYy1yKmgsZVsyXT1zKmYrbypoK3IqYS1pKmMsZVszXT1vKmYtcipjLWkqYS1zKmgsZX1mdW5jdGlvbiBDdChlLHQsbil7bio9LjU7Y29uc3Qgcj10WzBdLGk9dFsxXSxzPXRbMl0sbz10WzNdLGM9TWF0aC5zaW4obiksYT1NYXRoLmNvcyhuKTtyZXR1cm4gZVswXT1yKmErbypjLGVbMV09aSphK3MqYyxlWzJdPXMqYS1pKmMsZVszXT1vKmEtcipjLGV9ZnVuY3Rpb24gVnQoZSx0LG4pe24qPS41O2NvbnN0IHI9dFswXSxpPXRbMV0scz10WzJdLG89dFszXSxjPU1hdGguc2luKG4pLGE9TWF0aC5jb3Mobik7cmV0dXJuIGVbMF09ciphLXMqYyxlWzFdPWkqYStvKmMsZVsyXT1zKmErcipjLGVbM109byphLWkqYyxlfWZ1bmN0aW9uIE50KGUsdCxuKXtuKj0uNTtjb25zdCByPXRbMF0saT10WzFdLHM9dFsyXSxvPXRbM10sYz1NYXRoLnNpbihuKSxhPU1hdGguY29zKG4pO3JldHVybiBlWzBdPXIqYStpKmMsZVsxXT1pKmEtcipjLGVbMl09cyphK28qYyxlWzNdPW8qYS1zKmMsZX1mdW5jdGlvbiBMZihlLHQpe2NvbnN0IG49dFswXSxyPXRbMV0saT10WzJdO3JldHVybiBlWzBdPW4sZVsxXT1yLGVbMl09aSxlWzNdPU1hdGguc3FydChNYXRoLmFicygxLW4qbi1yKnItaSppKSksZX1mdW5jdGlvbiBBbihlLHQsbixyKXtjb25zdCBpPXRbMF0scz10WzFdLG89dFsyXSxjPXRbM107bGV0IGE9blswXSxoPW5bMV0sZj1uWzJdLHU9blszXSxkLGcsbSxfLHA7cmV0dXJuIGQ9aSphK3MqaCtvKmYrYyp1LGQ8MCYmKGQ9LWQsYT0tYSxoPS1oLGY9LWYsdT0tdSksMS1kPkk/KGc9TWF0aC5hY29zKGQpLHA9TWF0aC5zaW4oZyksbT1NYXRoLnNpbigoMS1yKSpnKS9wLF89TWF0aC5zaW4ocipnKS9wKToobT0xLXIsXz1yKSxlWzBdPW0qaStfKmEsZVsxXT1tKnMrXypoLGVbMl09bSpvK18qZixlWzNdPW0qYytfKnUsZX1mdW5jdGlvbiBSZihlLHQpe2NvbnN0IG49dFswXSxyPXRbMV0saT10WzJdLHM9dFszXSxvPW4qbityKnIraSppK3MqcyxjPW8/MS9vOjA7cmV0dXJuIGVbMF09LW4qYyxlWzFdPS1yKmMsZVsyXT0taSpjLGVbM109cypjLGV9ZnVuY3Rpb24gJGYoZSx0KXtyZXR1cm4gZVswXT0tdFswXSxlWzFdPS10WzFdLGVbMl09LXRbMl0sZVszXT10WzNdLGV9ZnVuY3Rpb24gUmUoZSx0KXtjb25zdCBuPXRbMF0rdFs0XSt0WzhdO2xldCByO2lmKG4+MClyPU1hdGguc3FydChuKzEpLGVbM109LjUqcixyPS41L3IsZVswXT0odFs1XS10WzddKSpyLGVbMV09KHRbNl0tdFsyXSkqcixlWzJdPSh0WzFdLXRbM10pKnI7ZWxzZXtsZXQgaT0wO3RbNF0+dFswXSYmKGk9MSksdFs4XT50W2kqMytpXSYmKGk9Mik7Y29uc3Qgcz0oaSsxKSUzLG89KGkrMiklMztyPU1hdGguc3FydCh0W2kqMytpXS10W3MqMytzXS10W28qMytvXSsxKSxlW2ldPS41KnIscj0uNS9yLGVbM109KHRbcyozK29dLXRbbyozK3NdKSpyLGVbc109KHRbcyozK2ldK3RbaSozK3NdKSpyLGVbb109KHRbbyozK2ldK3RbaSozK29dKSpyfXJldHVybiBlfWNvbnN0IHRvPXpzLENmPXFzLFZmPVVzLGVvPVpzLE5mPVhzLG5vPUFyLHJvPU9yLGlvPVdzLHpmPWZ1bmN0aW9uKCl7Y29uc3QgZT1ocigpLHQ9ZnIoMSwwLDApLG49ZnIoMCwxLDApO3JldHVybiBmdW5jdGlvbihyLGkscyl7Y29uc3Qgbz1QZShpLHMpO3JldHVybiBvPC0uOTk5OTk5PyhzdChlLHQsaSksaHMoZSk8MWUtNiYmc3QoZSxuLGkpLCR0KGUsZSksSHMocixlLE1hdGguUEkpLHIpOm8+Ljk5OTk5OT8oclswXT0wLHJbMV09MCxyWzJdPTAsclszXT0xLHIpOihzdChlLGkscyksclswXT1lWzBdLHJbMV09ZVsxXSxyWzJdPWVbMl0sclszXT0xK28saW8ocixyKSl9fSgpOyhmdW5jdGlvbigpe2NvbnN0IGU9U3IoKSx0PVNyKCk7cmV0dXJuIGZ1bmN0aW9uKG4scixpLHMsbyxjKXtyZXR1cm4gQW4oZSxyLG8sYyksQW4odCxpLHMsYyksQW4obixlLHQsMipjKigxLWMpKSxufX0pKCksZnVuY3Rpb24oKXtjb25zdCBlPWZzKCk7cmV0dXJuIGZ1bmN0aW9uKHQsbixyLGkpe3JldHVybiBlWzBdPXJbMF0sZVszXT1yWzFdLGVbNl09clsyXSxlWzFdPWlbMF0sZVs0XT1pWzFdLGVbN109aVsyXSxlWzJdPS1uWzBdLGVbNV09LW5bMV0sZVs4XT0tblsyXSxpbyh0LFJlKHQsZSkpfX0oKTtjb25zdCBxZj1bMCwwLDAsMV07Y2xhc3MgdXQgZXh0ZW5kcyBTZXtjb25zdHJ1Y3Rvcih0PTAsbj0wLHI9MCxpPTEpe3N1cGVyKC0wLC0wLC0wLC0wKSxBcnJheS5pc0FycmF5KHQpJiZhcmd1bWVudHMubGVuZ3RoPT09MT90aGlzLmNvcHkodCk6dGhpcy5zZXQodCxuLHIsaSl9Y29weSh0KXtyZXR1cm4gdGhpc1swXT10WzBdLHRoaXNbMV09dFsxXSx0aGlzWzJdPXRbMl0sdGhpc1szXT10WzNdLHRoaXMuY2hlY2soKX1zZXQodCxuLHIsaSl7cmV0dXJuIHRoaXNbMF09dCx0aGlzWzFdPW4sdGhpc1syXT1yLHRoaXNbM109aSx0aGlzLmNoZWNrKCl9ZnJvbU9iamVjdCh0KXtyZXR1cm4gdGhpc1swXT10LngsdGhpc1sxXT10LnksdGhpc1syXT10LnosdGhpc1szXT10LncsdGhpcy5jaGVjaygpfWZyb21NYXRyaXgzKHQpe3JldHVybiBSZSh0aGlzLHQpLHRoaXMuY2hlY2soKX1mcm9tQXhpc1JvdGF0aW9uKHQsbil7cmV0dXJuIEhzKHRoaXMsdCxuKSx0aGlzLmNoZWNrKCl9aWRlbnRpdHkoKXtyZXR1cm4gS3ModGhpcyksdGhpcy5jaGVjaygpfXNldEF4aXNBbmdsZSh0LG4pe3JldHVybiB0aGlzLmZyb21BeGlzUm90YXRpb24odCxuKX1nZXQgRUxFTUVOVFMoKXtyZXR1cm4gNH1nZXQgeCgpe3JldHVybiB0aGlzWzBdfXNldCB4KHQpe3RoaXNbMF09JCh0KX1nZXQgeSgpe3JldHVybiB0aGlzWzFdfXNldCB5KHQpe3RoaXNbMV09JCh0KX1nZXQgeigpe3JldHVybiB0aGlzWzJdfXNldCB6KHQpe3RoaXNbMl09JCh0KX1nZXQgdygpe3JldHVybiB0aGlzWzNdfXNldCB3KHQpe3RoaXNbM109JCh0KX1sZW4oKXtyZXR1cm4gbm8odGhpcyl9bGVuZ3RoU3F1YXJlZCgpe3JldHVybiBybyh0aGlzKX1kb3QodCl7cmV0dXJuIGVvKHRoaXMsdCl9cm90YXRpb25Ubyh0LG4pe3JldHVybiB6Zih0aGlzLHQsbiksdGhpcy5jaGVjaygpfWFkZCh0KXtyZXR1cm4gQ2YodGhpcyx0aGlzLHQpLHRoaXMuY2hlY2soKX1jYWxjdWxhdGVXKCl7cmV0dXJuIExmKHRoaXMsdGhpcyksdGhpcy5jaGVjaygpfWNvbmp1Z2F0ZSgpe3JldHVybiAkZih0aGlzLHRoaXMpLHRoaXMuY2hlY2soKX1pbnZlcnQoKXtyZXR1cm4gUmYodGhpcyx0aGlzKSx0aGlzLmNoZWNrKCl9bGVycCh0LG4scil7cmV0dXJuIHI9PT12b2lkIDA/dGhpcy5sZXJwKHRoaXMsdCxuKTooTmYodGhpcyx0LG4sciksdGhpcy5jaGVjaygpKX1tdWx0aXBseVJpZ2h0KHQpe3JldHVybiBKcyh0aGlzLHRoaXMsdCksdGhpcy5jaGVjaygpfW11bHRpcGx5TGVmdCh0KXtyZXR1cm4gSnModGhpcyx0LHRoaXMpLHRoaXMuY2hlY2soKX1ub3JtYWxpemUoKXtjb25zdCB0PXRoaXMubGVuKCksbj10PjA/MS90OjA7cmV0dXJuIHRoaXNbMF09dGhpc1swXSpuLHRoaXNbMV09dGhpc1sxXSpuLHRoaXNbMl09dGhpc1syXSpuLHRoaXNbM109dGhpc1szXSpuLHQ9PT0wJiYodGhpc1szXT0xKSx0aGlzLmNoZWNrKCl9cm90YXRlWCh0KXtyZXR1cm4gQ3QodGhpcyx0aGlzLHQpLHRoaXMuY2hlY2soKX1yb3RhdGVZKHQpe3JldHVybiBWdCh0aGlzLHRoaXMsdCksdGhpcy5jaGVjaygpfXJvdGF0ZVoodCl7cmV0dXJuIE50KHRoaXMsdGhpcyx0KSx0aGlzLmNoZWNrKCl9c2NhbGUodCl7cmV0dXJuIFZmKHRoaXMsdGhpcyx0KSx0aGlzLmNoZWNrKCl9c2xlcnAodCxuLHIpe2xldCBpLHMsbztzd2l0Y2goYXJndW1lbnRzLmxlbmd0aCl7Y2FzZSAxOih7c3RhcnQ6aT1xZix0YXJnZXQ6cyxyYXRpbzpvfT10KTticmVhaztjYXNlIDI6aT10aGlzLHM9dCxvPW47YnJlYWs7ZGVmYXVsdDppPXQscz1uLG89cn1yZXR1cm4gQW4odGhpcyxpLHMsbyksdGhpcy5jaGVjaygpfXRyYW5zZm9ybVZlY3RvcjQodCxuPW5ldyB5dCl7cmV0dXJuIGpzKG4sdCx0aGlzKSxHdChuLDQpfWxlbmd0aFNxKCl7cmV0dXJuIHRoaXMubGVuZ3RoU3F1YXJlZCgpfXNldEZyb21BeGlzQW5nbGUodCxuKXtyZXR1cm4gdGhpcy5zZXRBeGlzQW5nbGUodCxuKX1wcmVtdWx0aXBseSh0KXtyZXR1cm4gdGhpcy5tdWx0aXBseUxlZnQodCl9bXVsdGlwbHkodCl7cmV0dXJuIHRoaXMubXVsdGlwbHlSaWdodCh0KX19Y29uc3QgT249IlVua25vd24gRXVsZXIgYW5nbGUgb3JkZXIiLGFlPS45OTk5OTt2YXIgajsoZnVuY3Rpb24oZSl7ZVtlLlpZWD0wXT0iWllYIixlW2UuWVhaPTFdPSJZWFoiLGVbZS5YWlk9Ml09IlhaWSIsZVtlLlpYWT0zXT0iWlhZIixlW2UuWVpYPTRdPSJZWlgiLGVbZS5YWVo9NV09IlhZWiJ9KShqfHwoaj17fSkpO2NsYXNzIGsgZXh0ZW5kcyBTZXtzdGF0aWMgZ2V0IFpZWCgpe3JldHVybiBqLlpZWH1zdGF0aWMgZ2V0IFlYWigpe3JldHVybiBqLllYWn1zdGF0aWMgZ2V0IFhaWSgpe3JldHVybiBqLlhaWX1zdGF0aWMgZ2V0IFpYWSgpe3JldHVybiBqLlpYWX1zdGF0aWMgZ2V0IFlaWCgpe3JldHVybiBqLllaWH1zdGF0aWMgZ2V0IFhZWigpe3JldHVybiBqLlhZWn1zdGF0aWMgZ2V0IFJvbGxQaXRjaFlhdygpe3JldHVybiBqLlpZWH1zdGF0aWMgZ2V0IERlZmF1bHRPcmRlcigpe3JldHVybiBqLlpZWH1zdGF0aWMgZ2V0IFJvdGF0aW9uT3JkZXJzKCl7cmV0dXJuIGp9c3RhdGljIHJvdGF0aW9uT3JkZXIodCl7cmV0dXJuIGpbdF19Z2V0IEVMRU1FTlRTKCl7cmV0dXJuIDR9Y29uc3RydWN0b3IodD0wLG49MCxyPTAsaT1rLkRlZmF1bHRPcmRlcil7c3VwZXIoLTAsLTAsLTAsLTApLGFyZ3VtZW50cy5sZW5ndGg+MCYmQXJyYXkuaXNBcnJheShhcmd1bWVudHNbMF0pP3RoaXMuZnJvbVZlY3RvcjMoLi4uYXJndW1lbnRzKTp0aGlzLnNldCh0LG4scixpKX1mcm9tUXVhdGVybmlvbih0KXtjb25zdFtuLHIsaSxzXT10LG89cipyLGM9LTIqKG8raSppKSsxLGE9MioobipyK3MqaSk7bGV0IGg9LTIqKG4qaS1zKnIpO2NvbnN0IGY9MioocippK3MqbiksdT0tMioobipuK28pKzE7aD1oPjE/MTpoLGg9aDwtMT8tMTpoO2NvbnN0IGQ9TWF0aC5hdGFuMihmLHUpLGc9TWF0aC5hc2luKGgpLG09TWF0aC5hdGFuMihhLGMpO3JldHVybiB0aGlzLnNldChkLGcsbSxrLlJvbGxQaXRjaFlhdyl9ZnJvbU9iamVjdCh0KXt0aHJvdyBuZXcgRXJyb3IoIm5vdCBpbXBsZW1lbnRlZCIpfWNvcHkodCl7cmV0dXJuIHRoaXNbMF09dFswXSx0aGlzWzFdPXRbMV0sdGhpc1syXT10WzJdLHRoaXNbM109TnVtYmVyLmlzRmluaXRlKHRbM10pfHx0aGlzLm9yZGVyLHRoaXMuY2hlY2soKX1zZXQodD0wLG49MCxyPTAsaSl7cmV0dXJuIHRoaXNbMF09dCx0aGlzWzFdPW4sdGhpc1syXT1yLHRoaXNbM109TnVtYmVyLmlzRmluaXRlKGkpP2k6dGhpc1szXSx0aGlzLmNoZWNrKCl9dmFsaWRhdGUoKXtyZXR1cm4gRmYodGhpc1szXSkmJk51bWJlci5pc0Zpbml0ZSh0aGlzWzBdKSYmTnVtYmVyLmlzRmluaXRlKHRoaXNbMV0pJiZOdW1iZXIuaXNGaW5pdGUodGhpc1syXSl9dG9BcnJheSh0PVtdLG49MCl7cmV0dXJuIHRbbl09dGhpc1swXSx0W24rMV09dGhpc1sxXSx0W24rMl09dGhpc1syXSx0fXRvQXJyYXk0KHQ9W10sbj0wKXtyZXR1cm4gdFtuXT10aGlzWzBdLHRbbisxXT10aGlzWzFdLHRbbisyXT10aGlzWzJdLHRbbiszXT10aGlzWzNdLHR9dG9WZWN0b3IzKHQ9Wy0wLC0wLC0wXSl7cmV0dXJuIHRbMF09dGhpc1swXSx0WzFdPXRoaXNbMV0sdFsyXT10aGlzWzJdLHR9Z2V0IHgoKXtyZXR1cm4gdGhpc1swXX1zZXQgeCh0KXt0aGlzWzBdPSQodCl9Z2V0IHkoKXtyZXR1cm4gdGhpc1sxXX1zZXQgeSh0KXt0aGlzWzFdPSQodCl9Z2V0IHooKXtyZXR1cm4gdGhpc1syXX1zZXQgeih0KXt0aGlzWzJdPSQodCl9Z2V0IGFscGhhKCl7cmV0dXJuIHRoaXNbMF19c2V0IGFscGhhKHQpe3RoaXNbMF09JCh0KX1nZXQgYmV0YSgpe3JldHVybiB0aGlzWzFdfXNldCBiZXRhKHQpe3RoaXNbMV09JCh0KX1nZXQgZ2FtbWEoKXtyZXR1cm4gdGhpc1syXX1zZXQgZ2FtbWEodCl7dGhpc1syXT0kKHQpfWdldCBwaGkoKXtyZXR1cm4gdGhpc1swXX1zZXQgcGhpKHQpe3RoaXNbMF09JCh0KX1nZXQgdGhldGEoKXtyZXR1cm4gdGhpc1sxXX1zZXQgdGhldGEodCl7dGhpc1sxXT0kKHQpfWdldCBwc2koKXtyZXR1cm4gdGhpc1syXX1zZXQgcHNpKHQpe3RoaXNbMl09JCh0KX1nZXQgcm9sbCgpe3JldHVybiB0aGlzWzBdfXNldCByb2xsKHQpe3RoaXNbMF09JCh0KX1nZXQgcGl0Y2goKXtyZXR1cm4gdGhpc1sxXX1zZXQgcGl0Y2godCl7dGhpc1sxXT0kKHQpfWdldCB5YXcoKXtyZXR1cm4gdGhpc1syXX1zZXQgeWF3KHQpe3RoaXNbMl09JCh0KX1nZXQgb3JkZXIoKXtyZXR1cm4gdGhpc1szXX1zZXQgb3JkZXIodCl7dGhpc1szXT1rZih0KX1mcm9tVmVjdG9yMyh0LG4pe3JldHVybiB0aGlzLnNldCh0WzBdLHRbMV0sdFsyXSxOdW1iZXIuaXNGaW5pdGUobik/bjp0aGlzWzNdKX1mcm9tQXJyYXkodCxuPTApe3JldHVybiB0aGlzWzBdPXRbMCtuXSx0aGlzWzFdPXRbMStuXSx0aGlzWzJdPXRbMituXSx0WzNdIT09dm9pZCAwJiYodGhpc1szXT10WzNdKSx0aGlzLmNoZWNrKCl9ZnJvbVJvbGxQaXRjaFlhdyh0LG4scil7cmV0dXJuIHRoaXMuc2V0KHQsbixyLGouWllYKX1mcm9tUm90YXRpb25NYXRyaXgodCxuPWsuRGVmYXVsdE9yZGVyKXtyZXR1cm4gdGhpcy5fZnJvbVJvdGF0aW9uTWF0cml4KHQsbiksdGhpcy5jaGVjaygpfWdldFJvdGF0aW9uTWF0cml4KHQpe3JldHVybiB0aGlzLl9nZXRSb3RhdGlvbk1hdHJpeCh0KX1nZXRRdWF0ZXJuaW9uKCl7Y29uc3QgdD1uZXcgdXQ7c3dpdGNoKHRoaXNbM10pe2Nhc2Ugai5YWVo6cmV0dXJuIHQucm90YXRlWCh0aGlzWzBdKS5yb3RhdGVZKHRoaXNbMV0pLnJvdGF0ZVoodGhpc1syXSk7Y2FzZSBqLllYWjpyZXR1cm4gdC5yb3RhdGVZKHRoaXNbMF0pLnJvdGF0ZVgodGhpc1sxXSkucm90YXRlWih0aGlzWzJdKTtjYXNlIGouWlhZOnJldHVybiB0LnJvdGF0ZVoodGhpc1swXSkucm90YXRlWCh0aGlzWzFdKS5yb3RhdGVZKHRoaXNbMl0pO2Nhc2Ugai5aWVg6cmV0dXJuIHQucm90YXRlWih0aGlzWzBdKS5yb3RhdGVZKHRoaXNbMV0pLnJvdGF0ZVgodGhpc1syXSk7Y2FzZSBqLllaWDpyZXR1cm4gdC5yb3RhdGVZKHRoaXNbMF0pLnJvdGF0ZVoodGhpc1sxXSkucm90YXRlWCh0aGlzWzJdKTtjYXNlIGouWFpZOnJldHVybiB0LnJvdGF0ZVgodGhpc1swXSkucm90YXRlWih0aGlzWzFdKS5yb3RhdGVZKHRoaXNbMl0pO2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKE9uKX19X2Zyb21Sb3RhdGlvbk1hdHJpeCh0LG49ay5EZWZhdWx0T3JkZXIpe2NvbnN0IHI9dFswXSxpPXRbNF0scz10WzhdLG89dFsxXSxjPXRbNV0sYT10WzldLGg9dFsyXSxmPXRbNl0sdT10WzEwXTtzd2l0Y2gobj1ufHx0aGlzWzNdLG4pe2Nhc2Ugay5YWVo6dGhpc1sxXT1NYXRoLmFzaW4oWHQocywtMSwxKSksTWF0aC5hYnMocyk8YWU/KHRoaXNbMF09TWF0aC5hdGFuMigtYSx1KSx0aGlzWzJdPU1hdGguYXRhbjIoLWkscikpOih0aGlzWzBdPU1hdGguYXRhbjIoZixjKSx0aGlzWzJdPTApO2JyZWFrO2Nhc2Ugay5ZWFo6dGhpc1swXT1NYXRoLmFzaW4oLVh0KGEsLTEsMSkpLE1hdGguYWJzKGEpPGFlPyh0aGlzWzFdPU1hdGguYXRhbjIocyx1KSx0aGlzWzJdPU1hdGguYXRhbjIobyxjKSk6KHRoaXNbMV09TWF0aC5hdGFuMigtaCxyKSx0aGlzWzJdPTApO2JyZWFrO2Nhc2Ugay5aWFk6dGhpc1swXT1NYXRoLmFzaW4oWHQoZiwtMSwxKSksTWF0aC5hYnMoZik8YWU/KHRoaXNbMV09TWF0aC5hdGFuMigtaCx1KSx0aGlzWzJdPU1hdGguYXRhbjIoLWksYykpOih0aGlzWzFdPTAsdGhpc1syXT1NYXRoLmF0YW4yKG8scikpO2JyZWFrO2Nhc2Ugay5aWVg6dGhpc1sxXT1NYXRoLmFzaW4oLVh0KGgsLTEsMSkpLE1hdGguYWJzKGgpPGFlPyh0aGlzWzBdPU1hdGguYXRhbjIoZix1KSx0aGlzWzJdPU1hdGguYXRhbjIobyxyKSk6KHRoaXNbMF09MCx0aGlzWzJdPU1hdGguYXRhbjIoLWksYykpO2JyZWFrO2Nhc2Ugay5ZWlg6dGhpc1syXT1NYXRoLmFzaW4oWHQobywtMSwxKSksTWF0aC5hYnMobyk8YWU/KHRoaXNbMF09TWF0aC5hdGFuMigtYSxjKSx0aGlzWzFdPU1hdGguYXRhbjIoLWgscikpOih0aGlzWzBdPTAsdGhpc1sxXT1NYXRoLmF0YW4yKHMsdSkpO2JyZWFrO2Nhc2Ugay5YWlk6dGhpc1syXT1NYXRoLmFzaW4oLVh0KGksLTEsMSkpLE1hdGguYWJzKGkpPGFlPyh0aGlzWzBdPU1hdGguYXRhbjIoZixjKSx0aGlzWzFdPU1hdGguYXRhbjIocyxyKSk6KHRoaXNbMF09TWF0aC5hdGFuMigtYSx1KSx0aGlzWzFdPTApO2JyZWFrO2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKE9uKX1yZXR1cm4gdGhpc1szXT1uLHRoaXN9X2dldFJvdGF0aW9uTWF0cml4KHQpe2NvbnN0IG49dHx8Wy0wLC0wLC0wLC0wLC0wLC0wLC0wLC0wLC0wLC0wLC0wLC0wLC0wLC0wLC0wLC0wXSxyPXRoaXMueCxpPXRoaXMueSxzPXRoaXMueixvPU1hdGguY29zKHIpLGM9TWF0aC5jb3MoaSksYT1NYXRoLmNvcyhzKSxoPU1hdGguc2luKHIpLGY9TWF0aC5zaW4oaSksdT1NYXRoLnNpbihzKTtzd2l0Y2godGhpc1szXSl7Y2FzZSBrLlhZWjp7Y29uc3QgZD1vKmEsZz1vKnUsbT1oKmEsXz1oKnU7blswXT1jKmEsbls0XT0tYyp1LG5bOF09ZixuWzFdPWcrbSpmLG5bNV09ZC1fKmYsbls5XT0taCpjLG5bMl09Xy1kKmYsbls2XT1tK2cqZixuWzEwXT1vKmM7YnJlYWt9Y2FzZSBrLllYWjp7Y29uc3QgZD1jKmEsZz1jKnUsbT1mKmEsXz1mKnU7blswXT1kK18qaCxuWzRdPW0qaC1nLG5bOF09bypmLG5bMV09byp1LG5bNV09byphLG5bOV09LWgsblsyXT1nKmgtbSxuWzZdPV8rZCpoLG5bMTBdPW8qYzticmVha31jYXNlIGsuWlhZOntjb25zdCBkPWMqYSxnPWMqdSxtPWYqYSxfPWYqdTtuWzBdPWQtXypoLG5bNF09LW8qdSxuWzhdPW0rZypoLG5bMV09ZyttKmgsbls1XT1vKmEsbls5XT1fLWQqaCxuWzJdPS1vKmYsbls2XT1oLG5bMTBdPW8qYzticmVha31jYXNlIGsuWllYOntjb25zdCBkPW8qYSxnPW8qdSxtPWgqYSxfPWgqdTtuWzBdPWMqYSxuWzRdPW0qZi1nLG5bOF09ZCpmK18sblsxXT1jKnUsbls1XT1fKmYrZCxuWzldPWcqZi1tLG5bMl09LWYsbls2XT1oKmMsblsxMF09bypjO2JyZWFrfWNhc2Ugay5ZWlg6e2NvbnN0IGQ9bypjLGc9bypmLG09aCpjLF89aCpmO25bMF09YyphLG5bNF09Xy1kKnUsbls4XT1tKnUrZyxuWzFdPXUsbls1XT1vKmEsbls5XT0taCphLG5bMl09LWYqYSxuWzZdPWcqdSttLG5bMTBdPWQtXyp1O2JyZWFrfWNhc2Ugay5YWlk6e2NvbnN0IGQ9bypjLGc9bypmLG09aCpjLF89aCpmO25bMF09YyphLG5bNF09LXUsbls4XT1mKmEsblsxXT1kKnUrXyxuWzVdPW8qYSxuWzldPWcqdS1tLG5bMl09bSp1LWcsbls2XT1oKmEsblsxMF09Xyp1K2Q7YnJlYWt9ZGVmYXVsdDp0aHJvdyBuZXcgRXJyb3IoT24pfXJldHVybiBuWzNdPTAsbls3XT0wLG5bMTFdPTAsblsxMl09MCxuWzEzXT0wLG5bMTRdPTAsblsxNV09MSxufXRvUXVhdGVybmlvbigpe2NvbnN0IHQ9TWF0aC5jb3ModGhpcy55YXcqLjUpLG49TWF0aC5zaW4odGhpcy55YXcqLjUpLHI9TWF0aC5jb3ModGhpcy5yb2xsKi41KSxpPU1hdGguc2luKHRoaXMucm9sbCouNSkscz1NYXRoLmNvcyh0aGlzLnBpdGNoKi41KSxvPU1hdGguc2luKHRoaXMucGl0Y2gqLjUpLGM9dCpyKnMrbippKm8sYT10Kmkqcy1uKnIqbyxoPXQqcipvK24qaSpzLGY9bipyKnMtdCppKm87cmV0dXJuIG5ldyB1dChhLGgsZixjKX19ZnVuY3Rpb24gRmYoZSl7cmV0dXJuIGU+PTAmJmU8Nn1mdW5jdGlvbiBrZihlKXtpZihlPDAmJmU+PTYpdGhyb3cgbmV3IEVycm9yKE9uKTtyZXR1cm4gZX1jb25zdCBCZj0uMSxVZj0xZS0xMix2bj0xZS0xNCxEZj0xZS0xNSxJcj1NYXRoLlBJLzIsWj1NYXRoLlBJKjI7ZnVuY3Rpb24gWWYoZSl7c3dpdGNoKGUpe2Nhc2UgMjpyZXR1cm4gSztjYXNlIDM6cmV0dXJuIEw7Y2FzZSA0OnJldHVybiB5dDtjYXNlIDk6cmV0dXJuIG50O2Nhc2UgMTY6cmV0dXJuIG90O2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKGDkuI3mlK/mjIHojrflj5bnsbs6ICR7ZX1gKX19ZnVuY3Rpb24gRChlKXtzd2l0Y2goZSl7Y2FzZSAyOnJldHVybiBMbDtjYXNlIDM6cmV0dXJuIHJoO2Nhc2UgNDpyZXR1cm4gT2Y7Y2FzZSA5OnJldHVybiBNaDtjYXNlIDE2OnJldHVybiBLaDtkZWZhdWx0OnRocm93IG5ldyBFcnJvcihg5LiN5pSv5oyB6I635Y+W5ZG95ZCN56m66Ze0OiAke2V9YCl9fWZ1bmN0aW9uIHNvKGUpe3N3aXRjaChlLmxlbmd0aCl7Y2FzZSAyOnJldHVybiBuZXcgSyhlKTtjYXNlIDM6cmV0dXJuIG5ldyBMKGUpO2Nhc2UgNDpyZXR1cm4gbmV3IHl0KGUpO2Nhc2UgOTpyZXR1cm4gbmV3IG50KGUpO2Nhc2UgMTY6cmV0dXJuIG5ldyBvdChlKTtkZWZhdWx0OnRocm93IG5ldyBFcnJvcihg5LiN5pSv5oyB5Yib5bu65a6e5L6LOiAke2xlbmd0aH1gKX19Y29uc3QgV2Y9ezQ6InRyYW5zZm9ybU1hdDIiLDY6InRyYW5zZm9ybU1hdDJkIiw5OiJ0cmFuc2Zvcm1NYXQzIiwxNjoidHJhbnNmb3JtTWF0NCJ9O2Z1bmN0aW9uICRlKGUsdCl7Y29uc3Qgbj1EKHQpLHI9V2ZbZV0saT1uW3JdO2lmKCFpKXRocm93IG5ldyBFcnJvcihg5LiN5pSv5oyB55qE55+p6Zi15aSn5bCP77yaJHtlfWApO3JldHVybiBpfWNvbnN0IG9vPXtBcnJheSxJbnQ4QXJyYXksVWludDhBcnJheSxVaW50OENsYW1wZWRBcnJheSxJbnQxNkFycmF5LFVpbnQxNkFycmF5LEludDMyQXJyYXksVWludDMyQXJyYXksRmxvYXQzMkFycmF5LEZsb2F0NjRBcnJheX07dmFyIEVuPShlPT4oZS5BcnJheT0iQXJyYXkiLGUuSW50OEFycmF5PSJJbnQ4QXJyYXkiLGUuVWludDhBcnJheT0iVWludDhBcnJheSIsZS5VaW50OENsYW1wZWRBcnJheT0iVWludDhDbGFtcGVkQXJyYXkiLGUuSW50MTZBcnJheT0iSW50MTZBcnJheSIsZS5VaW50MTZBcnJheT0iVWludDE2QXJyYXkiLGUuSW50MzJBcnJheT0iSW50MzJBcnJheSIsZS5VaW50MzJBcnJheT0iVWludDMyQXJyYXkiLGUuRmxvYXQzMkFycmF5PSJGbG9hdDMyQXJyYXkiLGUuRmxvYXQ2NEFycmF5PSJGbG9hdDY0QXJyYXkiLGUpKShFbnx8e30pOyhlPT57ZnVuY3Rpb24gdChpKXtyZXR1cm4gb29baV19ZS50b0NsYXNzPXQ7ZnVuY3Rpb24gbihpKXtyZXR1cm4gaS5uYW1lfWUudG9UeXBlPW47ZnVuY3Rpb24gcihpKXtyZXR1cm4gaS5jb25zdHJ1Y3Rvci5uYW1lfWUudG9UeXBlQnlBcnJheT1yfSkoRW58fChFbj17fSkpO3ZhciBIPShlPT4oZVtlLnRycz0wXT0idHJzIixlW2UudHNyPTFdPSJ0c3IiLGVbZS5yc3Q9Ml09InJzdCIsZVtlLnNydD0zXT0ic3J0IixlKSkoSHx8e30pOyhlPT57ZnVuY3Rpb24gdChyKXtyZXR1cm4hIShyJjIpfWUuaXNMb2NhbFRyYW5zbGF0aW9uPXQ7ZnVuY3Rpb24gbihyKXtyZXR1cm4hIShyJjEpfWUuaXNTUj1ufSkoSHx8KEg9e30pKTtmdW5jdGlvbiBjbyhlKXtjb25zdCB0PVtdO2Zvcihjb25zdCBuIG9mWyJ4IiwieSIsInoiLCJ3Il0pe2lmKGVbbl09PW51bGwpcmV0dXJuIHQ7dC5wdXNoKGVbbl0pfXJldHVybiB0fWZ1bmN0aW9uIGFvKGUpe3JldHVybiBzbyhjbyhlKSl9ZnVuY3Rpb24gQ2UoZSx0LG4pe249bj8/MDtjb25zdCByPW4rMTtpZih2dChlKSlyZXR1cm4gZTtpZihlLnghPW51bGwmJmUueSE9bnVsbClyZXR1cm4gYW8oZSk7aWYoQXJyYXkuaXNBcnJheShlKSlyZXR1cm4gZS5tYXAocz0+Q2Uocyx0LHIpKTtpZihlIGluc3RhbmNlb2YgTWFwKXtjb25zdCBzPW5ldyBNYXA7Zm9yKGNvbnN0IG8gb2YgZS5rZXlzKCkpe2NvbnN0IGM9ZS5nZXQobyksYT1DZShjLHQscik7cy5zZXQobyxhKX1yZXR1cm4gc31pZihzZShlKSl7Y29uc3Qgcz1bXTtmb3IoY29uc3QgbyBvZiBlKXtjb25zdCBjPUNlKG8sdCxyKTtzLnB1c2goYyl9cmV0dXJuIHN9aWYoKHR8fG49PT0wKSYmdHlwZW9mIGU9PSJvYmplY3QiKXtjb25zdCBzPXt9O2Zvcihjb25zdCBvIG9mIE9iamVjdC5rZXlzKGUpKXNbb109Q2UoZVtvXSx0LHIpO3JldHVybiBzfXJldHVybiBlfXZhciB5PShlPT4oZVtlLlRocm91Z2hJbnRlcnNlY3Q9MV09IlRocm91Z2hJbnRlcnNlY3QiLGVbZS5Kb2ludEludGVyc2VjdD0yXT0iSm9pbnRJbnRlcnNlY3QiLGVbZS5JbnRlcnNlY3Q9M109IkludGVyc2VjdCIsZVtlLlRhbmdlbmN5PTRdPSJUYW5nZW5jeSIsZVtlLkNvbnRhaW49OF09IkNvbnRhaW4iLGVbZS5EaXNzb2NpYXRpb249MTZdPSJEaXNzb2NpYXRpb24iLGVbZS5BQj0zMl09IkFCIixlW2UuQkE9NjRdPSJCQSIsZVtlLkFCQ29udGFpbj00MF09IkFCQ29udGFpbiIsZVtlLkJBQ29udGFpbj03Ml09IkJBQ29udGFpbiIsZSkpKHl8fHt9KTtmdW5jdGlvbiBaZigpe2xldCBlPW5ldyBDKDQpO3JldHVybiBDIT1GbG9hdDMyQXJyYXkmJihlWzFdPTAsZVsyXT0wKSxlWzBdPTEsZVszXT0xLGV9ZnVuY3Rpb24gWGYoZSl7bGV0IHQ9bmV3IEMoNCk7cmV0dXJuIHRbMF09ZVswXSx0WzFdPWVbMV0sdFsyXT1lWzJdLHRbM109ZVszXSx0fWZ1bmN0aW9uIEdmKGUsdCl7cmV0dXJuIGVbMF09dFswXSxlWzFdPXRbMV0sZVsyXT10WzJdLGVbM109dFszXSxlfWZ1bmN0aW9uIGpmKGUpe3JldHVybiBlWzBdPTEsZVsxXT0wLGVbMl09MCxlWzNdPTEsZX1mdW5jdGlvbiBRZihlLHQsbixyKXtsZXQgaT1uZXcgQyg0KTtyZXR1cm4gaVswXT1lLGlbMV09dCxpWzJdPW4saVszXT1yLGl9ZnVuY3Rpb24gbG8oZSx0LG4scixpKXtyZXR1cm4gZVswXT10LGVbMV09bixlWzJdPXIsZVszXT1pLGV9ZnVuY3Rpb24gaG8oZSx0KXtpZihlPT09dCl7bGV0IG49dFsxXTtlWzFdPXRbMl0sZVsyXT1ufWVsc2UgZVswXT10WzBdLGVbMV09dFsyXSxlWzJdPXRbMV0sZVszXT10WzNdO3JldHVybiBlfWZ1bmN0aW9uIFByKGUsdCl7bGV0IG49dFswXSxyPXRbMV0saT10WzJdLHM9dFszXSxvPW4qcy1pKnI7cmV0dXJuIG8/KG89MS9vLGVbMF09cypvLGVbMV09LXIqbyxlWzJdPS1pKm8sZVszXT1uKm8sZSk6bnVsbH1mdW5jdGlvbiBLZihlLHQpe2xldCBuPXRbMF07cmV0dXJuIGVbMF09dFszXSxlWzFdPS10WzFdLGVbMl09LXRbMl0sZVszXT1uLGV9ZnVuY3Rpb24gYm4oZSl7cmV0dXJuIGVbMF0qZVszXS1lWzJdKmVbMV19ZnVuY3Rpb24gU24oZSx0LG4pe2xldCByPXRbMF0saT10WzFdLHM9dFsyXSxvPXRbM10sYz1uWzBdLGE9blsxXSxoPW5bMl0sZj1uWzNdO3JldHVybiBlWzBdPXIqYytzKmEsZVsxXT1pKmMrbyphLGVbMl09cipoK3MqZixlWzNdPWkqaCtvKmYsZX1mdW5jdGlvbiBmbyhlLHQsbil7bGV0IHI9dFswXSxpPXRbMV0scz10WzJdLG89dFszXSxjPU1hdGguc2luKG4pLGE9TWF0aC5jb3Mobik7cmV0dXJuIGVbMF09ciphK3MqYyxlWzFdPWkqYStvKmMsZVsyXT1yKi1jK3MqYSxlWzNdPWkqLWMrbyphLGV9ZnVuY3Rpb24gTHIoZSx0LG4pe2xldCByPXRbMF0saT10WzFdLHM9dFsyXSxvPXRbM10sYz1uWzBdLGE9blsxXTtyZXR1cm4gZVswXT1yKmMsZVsxXT1pKmMsZVsyXT1zKmEsZVszXT1vKmEsZX1mdW5jdGlvbiBIZihlLHQpe2xldCBuPU1hdGguc2luKHQpLHI9TWF0aC5jb3ModCk7cmV0dXJuIGVbMF09cixlWzFdPW4sZVsyXT0tbixlWzNdPXIsZX1mdW5jdGlvbiBKZihlLHQpe3JldHVybiBlWzBdPXRbMF0sZVsxXT0wLGVbMl09MCxlWzNdPXRbMV0sZX1mdW5jdGlvbiB0dShlKXtyZXR1cm4ibWF0MigiK2VbMF0rIiwgIitlWzFdKyIsICIrZVsyXSsiLCAiK2VbM10rIikifWZ1bmN0aW9uIGV1KGUpe3JldHVybiBNYXRoLnNxcnQoZVswXSplWzBdK2VbMV0qZVsxXStlWzJdKmVbMl0rZVszXSplWzNdKX1mdW5jdGlvbiBudShlLHQsbixyKXtyZXR1cm4gZVsyXT1yWzJdL3JbMF0sblswXT1yWzBdLG5bMV09clsxXSxuWzNdPXJbM10tZVsyXSpuWzFdLFtlLHQsbl19ZnVuY3Rpb24gcnUoZSx0LG4pe3JldHVybiBlWzBdPXRbMF0rblswXSxlWzFdPXRbMV0rblsxXSxlWzJdPXRbMl0rblsyXSxlWzNdPXRbM10rblszXSxlfWZ1bmN0aW9uIHVvKGUsdCxuKXtyZXR1cm4gZVswXT10WzBdLW5bMF0sZVsxXT10WzFdLW5bMV0sZVsyXT10WzJdLW5bMl0sZVszXT10WzNdLW5bM10sZX1mdW5jdGlvbiBpdShlLHQpe3JldHVybiBlWzBdPT09dFswXSYmZVsxXT09PXRbMV0mJmVbMl09PT10WzJdJiZlWzNdPT09dFszXX1mdW5jdGlvbiBzdShlLHQpe2xldCBuPWVbMF0scj1lWzFdLGk9ZVsyXSxzPWVbM10sbz10WzBdLGM9dFsxXSxhPXRbMl0saD10WzNdO3JldHVybiBNYXRoLmFicyhuLW8pPD1JKk1hdGgubWF4KDEsTWF0aC5hYnMobiksTWF0aC5hYnMobykpJiZNYXRoLmFicyhyLWMpPD1JKk1hdGgubWF4KDEsTWF0aC5hYnMociksTWF0aC5hYnMoYykpJiZNYXRoLmFicyhpLWEpPD1JKk1hdGgubWF4KDEsTWF0aC5hYnMoaSksTWF0aC5hYnMoYSkpJiZNYXRoLmFicyhzLWgpPD1JKk1hdGgubWF4KDEsTWF0aC5hYnMocyksTWF0aC5hYnMoaCkpfWZ1bmN0aW9uIG91KGUsdCxuKXtyZXR1cm4gZVswXT10WzBdKm4sZVsxXT10WzFdKm4sZVsyXT10WzJdKm4sZVszXT10WzNdKm4sZX1mdW5jdGlvbiBjdShlLHQsbixyKXtyZXR1cm4gZVswXT10WzBdK25bMF0qcixlWzFdPXRbMV0rblsxXSpyLGVbMl09dFsyXStuWzJdKnIsZVszXT10WzNdK25bM10qcixlfXZhciBhdT1PYmplY3QuZnJlZXplKHtfX3Byb3RvX186bnVsbCxMRFU6bnUsYWRkOnJ1LGFkam9pbnQ6S2YsY2xvbmU6WGYsY29weTpHZixjcmVhdGU6WmYsZGV0ZXJtaW5hbnQ6Ym4sZXF1YWxzOnN1LGV4YWN0RXF1YWxzOml1LGZyb2I6ZXUsZnJvbVJvdGF0aW9uOkhmLGZyb21TY2FsaW5nOkpmLGZyb21WYWx1ZXM6UWYsaWRlbnRpdHk6amYsaW52ZXJ0OlByLG11bDpTbixtdWx0aXBseTpTbixtdWx0aXBseVNjYWxhcjpvdSxtdWx0aXBseVNjYWxhckFuZEFkZDpjdSxyb3RhdGU6Zm8sc2NhbGU6THIsc2V0OmxvLHN0cjp0dSxzdWI6dW8sc3VidHJhY3Q6dW8sdHJhbnNwb3NlOmhvfSk7ZnVuY3Rpb24gbHUoKXtsZXQgZT1uZXcgQyg2KTtyZXR1cm4gQyE9RmxvYXQzMkFycmF5JiYoZVsxXT0wLGVbMl09MCxlWzRdPTAsZVs1XT0wKSxlWzBdPTEsZVszXT0xLGV9ZnVuY3Rpb24gaHUoZSl7bGV0IHQ9bmV3IEMoNik7cmV0dXJuIHRbMF09ZVswXSx0WzFdPWVbMV0sdFsyXT1lWzJdLHRbM109ZVszXSx0WzRdPWVbNF0sdFs1XT1lWzVdLHR9ZnVuY3Rpb24gZnUoZSx0KXtyZXR1cm4gZVswXT10WzBdLGVbMV09dFsxXSxlWzJdPXRbMl0sZVszXT10WzNdLGVbNF09dFs0XSxlWzVdPXRbNV0sZX1mdW5jdGlvbiB1dShlKXtyZXR1cm4gZVswXT0xLGVbMV09MCxlWzJdPTAsZVszXT0xLGVbNF09MCxlWzVdPTAsZX1mdW5jdGlvbiBkdShlLHQsbixyLGkscyl7bGV0IG89bmV3IEMoNik7cmV0dXJuIG9bMF09ZSxvWzFdPXQsb1syXT1uLG9bM109cixvWzRdPWksb1s1XT1zLG99ZnVuY3Rpb24gZ3UoZSx0LG4scixpLHMsbyl7cmV0dXJuIGVbMF09dCxlWzFdPW4sZVsyXT1yLGVbM109aSxlWzRdPXMsZVs1XT1vLGV9ZnVuY3Rpb24gbXUoZSx0KXtsZXQgbj10WzBdLHI9dFsxXSxpPXRbMl0scz10WzNdLG89dFs0XSxjPXRbNV0sYT1uKnMtcippO3JldHVybiBhPyhhPTEvYSxlWzBdPXMqYSxlWzFdPS1yKmEsZVsyXT0taSphLGVbM109biphLGVbNF09KGkqYy1zKm8pKmEsZVs1XT0ocipvLW4qYykqYSxlKTpudWxsfWZ1bmN0aW9uIHB1KGUpe3JldHVybiBlWzBdKmVbM10tZVsxXSplWzJdfWZ1bmN0aW9uIGdvKGUsdCxuKXtsZXQgcj10WzBdLGk9dFsxXSxzPXRbMl0sbz10WzNdLGM9dFs0XSxhPXRbNV0saD1uWzBdLGY9blsxXSx1PW5bMl0sZD1uWzNdLGc9bls0XSxtPW5bNV07cmV0dXJuIGVbMF09cipoK3MqZixlWzFdPWkqaCtvKmYsZVsyXT1yKnUrcypkLGVbM109aSp1K28qZCxlWzRdPXIqZytzKm0rYyxlWzVdPWkqZytvKm0rYSxlfWZ1bmN0aW9uIF91KGUsdCxuKXtsZXQgcj10WzBdLGk9dFsxXSxzPXRbMl0sbz10WzNdLGM9dFs0XSxhPXRbNV0saD1NYXRoLnNpbihuKSxmPU1hdGguY29zKG4pO3JldHVybiBlWzBdPXIqZitzKmgsZVsxXT1pKmYrbypoLGVbMl09ciotaCtzKmYsZVszXT1pKi1oK28qZixlWzRdPWMsZVs1XT1hLGV9ZnVuY3Rpb24geXUoZSx0LG4pe2xldCByPXRbMF0saT10WzFdLHM9dFsyXSxvPXRbM10sYz10WzRdLGE9dFs1XSxoPW5bMF0sZj1uWzFdO3JldHVybiBlWzBdPXIqaCxlWzFdPWkqaCxlWzJdPXMqZixlWzNdPW8qZixlWzRdPWMsZVs1XT1hLGV9ZnVuY3Rpb24geHUoZSx0LG4pe2xldCByPXRbMF0saT10WzFdLHM9dFsyXSxvPXRbM10sYz10WzRdLGE9dFs1XSxoPW5bMF0sZj1uWzFdO3JldHVybiBlWzBdPXIsZVsxXT1pLGVbMl09cyxlWzNdPW8sZVs0XT1yKmgrcypmK2MsZVs1XT1pKmgrbypmK2EsZX1mdW5jdGlvbiBNdShlLHQpe2xldCBuPU1hdGguc2luKHQpLHI9TWF0aC5jb3ModCk7cmV0dXJuIGVbMF09cixlWzFdPW4sZVsyXT0tbixlWzNdPXIsZVs0XT0wLGVbNV09MCxlfWZ1bmN0aW9uIHd1KGUsdCl7cmV0dXJuIGVbMF09dFswXSxlWzFdPTAsZVsyXT0wLGVbM109dFsxXSxlWzRdPTAsZVs1XT0wLGV9ZnVuY3Rpb24gVHUoZSx0KXtyZXR1cm4gZVswXT0xLGVbMV09MCxlWzJdPTAsZVszXT0xLGVbNF09dFswXSxlWzVdPXRbMV0sZX1mdW5jdGlvbiBBdShlKXtyZXR1cm4ibWF0MmQoIitlWzBdKyIsICIrZVsxXSsiLCAiK2VbMl0rIiwgIitlWzNdKyIsICIrZVs0XSsiLCAiK2VbNV0rIikifWZ1bmN0aW9uIE91KGUpe3JldHVybiBNYXRoLnNxcnQoZVswXSplWzBdK2VbMV0qZVsxXStlWzJdKmVbMl0rZVszXSplWzNdK2VbNF0qZVs0XStlWzVdKmVbNV0rMSl9ZnVuY3Rpb24gdnUoZSx0LG4pe3JldHVybiBlWzBdPXRbMF0rblswXSxlWzFdPXRbMV0rblsxXSxlWzJdPXRbMl0rblsyXSxlWzNdPXRbM10rblszXSxlWzRdPXRbNF0rbls0XSxlWzVdPXRbNV0rbls1XSxlfWZ1bmN0aW9uIG1vKGUsdCxuKXtyZXR1cm4gZVswXT10WzBdLW5bMF0sZVsxXT10WzFdLW5bMV0sZVsyXT10WzJdLW5bMl0sZVszXT10WzNdLW5bM10sZVs0XT10WzRdLW5bNF0sZVs1XT10WzVdLW5bNV0sZX1mdW5jdGlvbiBFdShlLHQsbil7cmV0dXJuIGVbMF09dFswXSpuLGVbMV09dFsxXSpuLGVbMl09dFsyXSpuLGVbM109dFszXSpuLGVbNF09dFs0XSpuLGVbNV09dFs1XSpuLGV9ZnVuY3Rpb24gYnUoZSx0LG4scil7cmV0dXJuIGVbMF09dFswXStuWzBdKnIsZVsxXT10WzFdK25bMV0qcixlWzJdPXRbMl0rblsyXSpyLGVbM109dFszXStuWzNdKnIsZVs0XT10WzRdK25bNF0qcixlWzVdPXRbNV0rbls1XSpyLGV9ZnVuY3Rpb24gU3UoZSx0KXtyZXR1cm4gZVswXT09PXRbMF0mJmVbMV09PT10WzFdJiZlWzJdPT09dFsyXSYmZVszXT09PXRbM10mJmVbNF09PT10WzRdJiZlWzVdPT09dFs1XX1mdW5jdGlvbiBJdShlLHQpe2xldCBuPWVbMF0scj1lWzFdLGk9ZVsyXSxzPWVbM10sbz1lWzRdLGM9ZVs1XSxhPXRbMF0saD10WzFdLGY9dFsyXSx1PXRbM10sZD10WzRdLGc9dFs1XTtyZXR1cm4gTWF0aC5hYnMobi1hKTw9SSpNYXRoLm1heCgxLE1hdGguYWJzKG4pLE1hdGguYWJzKGEpKSYmTWF0aC5hYnMoci1oKTw9SSpNYXRoLm1heCgxLE1hdGguYWJzKHIpLE1hdGguYWJzKGgpKSYmTWF0aC5hYnMoaS1mKTw9SSpNYXRoLm1heCgxLE1hdGguYWJzKGkpLE1hdGguYWJzKGYpKSYmTWF0aC5hYnMocy11KTw9SSpNYXRoLm1heCgxLE1hdGguYWJzKHMpLE1hdGguYWJzKHUpKSYmTWF0aC5hYnMoby1kKTw9SSpNYXRoLm1heCgxLE1hdGguYWJzKG8pLE1hdGguYWJzKGQpKSYmTWF0aC5hYnMoYy1nKTw9SSpNYXRoLm1heCgxLE1hdGguYWJzKGMpLE1hdGguYWJzKGcpKX12YXIgUHU9T2JqZWN0LmZyZWV6ZSh7X19wcm90b19fOm51bGwsYWRkOnZ1LGNsb25lOmh1LGNvcHk6ZnUsY3JlYXRlOmx1LGRldGVybWluYW50OnB1LGVxdWFsczpJdSxleGFjdEVxdWFsczpTdSxmcm9iOk91LGZyb21Sb3RhdGlvbjpNdSxmcm9tU2NhbGluZzp3dSxmcm9tVHJhbnNsYXRpb246VHUsZnJvbVZhbHVlczpkdSxpZGVudGl0eTp1dSxpbnZlcnQ6bXUsbXVsOmdvLG11bHRpcGx5OmdvLG11bHRpcGx5U2NhbGFyOkV1LG11bHRpcGx5U2NhbGFyQW5kQWRkOmJ1LHJvdGF0ZTpfdSxzY2FsZTp5dSxzZXQ6Z3Usc3RyOkF1LHN1YjptbyxzdWJ0cmFjdDptbyx0cmFuc2xhdGU6eHV9KTtmdW5jdGlvbiBMdSgpe2xldCBlPW5ldyBDKDgpO3JldHVybiBDIT1GbG9hdDMyQXJyYXkmJihlWzBdPTAsZVsxXT0wLGVbMl09MCxlWzRdPTAsZVs1XT0wLGVbNl09MCxlWzddPTApLGVbM109MSxlfWZ1bmN0aW9uIFJ1KGUpe2xldCB0PW5ldyBDKDgpO3JldHVybiB0WzBdPWVbMF0sdFsxXT1lWzFdLHRbMl09ZVsyXSx0WzNdPWVbM10sdFs0XT1lWzRdLHRbNV09ZVs1XSx0WzZdPWVbNl0sdFs3XT1lWzddLHR9ZnVuY3Rpb24gJHUoZSx0LG4scixpLHMsbyxjKXtsZXQgYT1uZXcgQyg4KTtyZXR1cm4gYVswXT1lLGFbMV09dCxhWzJdPW4sYVszXT1yLGFbNF09aSxhWzVdPXMsYVs2XT1vLGFbN109YyxhfWZ1bmN0aW9uIEN1KGUsdCxuLHIsaSxzLG8pe2xldCBjPW5ldyBDKDgpO2NbMF09ZSxjWzFdPXQsY1syXT1uLGNbM109cjtsZXQgYT1pKi41LGg9cyouNSxmPW8qLjU7cmV0dXJuIGNbNF09YSpyK2gqbi1mKnQsY1s1XT1oKnIrZiplLWEqbixjWzZdPWYqcithKnQtaCplLGNbN109LWEqZS1oKnQtZipuLGN9ZnVuY3Rpb24gcG8oZSx0LG4pe2xldCByPW5bMF0qLjUsaT1uWzFdKi41LHM9blsyXSouNSxvPXRbMF0sYz10WzFdLGE9dFsyXSxoPXRbM107cmV0dXJuIGVbMF09byxlWzFdPWMsZVsyXT1hLGVbM109aCxlWzRdPXIqaCtpKmEtcypjLGVbNV09aSpoK3Mqby1yKmEsZVs2XT1zKmgrcipjLWkqbyxlWzddPS1yKm8taSpjLXMqYSxlfWZ1bmN0aW9uIFZ1KGUsdCl7cmV0dXJuIGVbMF09MCxlWzFdPTAsZVsyXT0wLGVbM109MSxlWzRdPXRbMF0qLjUsZVs1XT10WzFdKi41LGVbNl09dFsyXSouNSxlWzddPTAsZX1mdW5jdGlvbiBOdShlLHQpe3JldHVybiBlWzBdPXRbMF0sZVsxXT10WzFdLGVbMl09dFsyXSxlWzNdPXRbM10sZVs0XT0wLGVbNV09MCxlWzZdPTAsZVs3XT0wLGV9ZnVuY3Rpb24genUoZSx0KXtsZXQgbj1TcigpO2JzKG4sdCk7bGV0IHI9bmV3IEMoMyk7cmV0dXJuIE1uKHIsdCkscG8oZSxuLHIpLGV9ZnVuY3Rpb24gX28oZSx0KXtyZXR1cm4gZVswXT10WzBdLGVbMV09dFsxXSxlWzJdPXRbMl0sZVszXT10WzNdLGVbNF09dFs0XSxlWzVdPXRbNV0sZVs2XT10WzZdLGVbN109dFs3XSxlfWZ1bmN0aW9uIHF1KGUpe3JldHVybiBlWzBdPTAsZVsxXT0wLGVbMl09MCxlWzNdPTEsZVs0XT0wLGVbNV09MCxlWzZdPTAsZVs3XT0wLGV9ZnVuY3Rpb24gRnUoZSx0LG4scixpLHMsbyxjLGEpe3JldHVybiBlWzBdPXQsZVsxXT1uLGVbMl09cixlWzNdPWksZVs0XT1zLGVbNV09byxlWzZdPWMsZVs3XT1hLGV9Y29uc3Qga3U9dG87ZnVuY3Rpb24gQnUoZSx0KXtyZXR1cm4gZVswXT10WzRdLGVbMV09dFs1XSxlWzJdPXRbNl0sZVszXT10WzddLGV9Y29uc3QgVXU9dG87ZnVuY3Rpb24gRHUoZSx0KXtyZXR1cm4gZVs0XT10WzBdLGVbNV09dFsxXSxlWzZdPXRbMl0sZVs3XT10WzNdLGV9ZnVuY3Rpb24gWXUoZSx0KXtsZXQgbj10WzRdLHI9dFs1XSxpPXRbNl0scz10WzddLG89LXRbMF0sYz0tdFsxXSxhPS10WzJdLGg9dFszXTtyZXR1cm4gZVswXT0obipoK3MqbytyKmEtaSpjKSoyLGVbMV09KHIqaCtzKmMraSpvLW4qYSkqMixlWzJdPShpKmgrcyphK24qYy1yKm8pKjIsZX1mdW5jdGlvbiBXdShlLHQsbil7bGV0IHI9dFswXSxpPXRbMV0scz10WzJdLG89dFszXSxjPW5bMF0qLjUsYT1uWzFdKi41LGg9blsyXSouNSxmPXRbNF0sdT10WzVdLGQ9dFs2XSxnPXRbN107cmV0dXJuIGVbMF09cixlWzFdPWksZVsyXT1zLGVbM109byxlWzRdPW8qYytpKmgtcyphK2YsZVs1XT1vKmErcypjLXIqaCt1LGVbNl09bypoK3IqYS1pKmMrZCxlWzddPS1yKmMtaSphLXMqaCtnLGV9ZnVuY3Rpb24gWnUoZSx0LG4pe2xldCByPS10WzBdLGk9LXRbMV0scz0tdFsyXSxvPXRbM10sYz10WzRdLGE9dFs1XSxoPXRbNl0sZj10WzddLHU9YypvK2YqcithKnMtaCppLGQ9YSpvK2YqaStoKnItYypzLGc9aCpvK2YqcytjKmktYSpyLG09ZipvLWMqci1hKmktaCpzO3JldHVybiBDdChlLHQsbikscj1lWzBdLGk9ZVsxXSxzPWVbMl0sbz1lWzNdLGVbNF09dSpvK20qcitkKnMtZyppLGVbNV09ZCpvK20qaStnKnItdSpzLGVbNl09ZypvK20qcyt1KmktZCpyLGVbN109bSpvLXUqci1kKmktZypzLGV9ZnVuY3Rpb24gWHUoZSx0LG4pe2xldCByPS10WzBdLGk9LXRbMV0scz0tdFsyXSxvPXRbM10sYz10WzRdLGE9dFs1XSxoPXRbNl0sZj10WzddLHU9YypvK2YqcithKnMtaCppLGQ9YSpvK2YqaStoKnItYypzLGc9aCpvK2YqcytjKmktYSpyLG09ZipvLWMqci1hKmktaCpzO3JldHVybiBWdChlLHQsbikscj1lWzBdLGk9ZVsxXSxzPWVbMl0sbz1lWzNdLGVbNF09dSpvK20qcitkKnMtZyppLGVbNV09ZCpvK20qaStnKnItdSpzLGVbNl09ZypvK20qcyt1KmktZCpyLGVbN109bSpvLXUqci1kKmktZypzLGV9ZnVuY3Rpb24gR3UoZSx0LG4pe2xldCByPS10WzBdLGk9LXRbMV0scz0tdFsyXSxvPXRbM10sYz10WzRdLGE9dFs1XSxoPXRbNl0sZj10WzddLHU9YypvK2YqcithKnMtaCppLGQ9YSpvK2YqaStoKnItYypzLGc9aCpvK2YqcytjKmktYSpyLG09ZipvLWMqci1hKmktaCpzO3JldHVybiBOdChlLHQsbikscj1lWzBdLGk9ZVsxXSxzPWVbMl0sbz1lWzNdLGVbNF09dSpvK20qcitkKnMtZyppLGVbNV09ZCpvK20qaStnKnItdSpzLGVbNl09ZypvK20qcyt1KmktZCpyLGVbN109bSpvLXUqci1kKmktZypzLGV9ZnVuY3Rpb24ganUoZSx0LG4pe2xldCByPW5bMF0saT1uWzFdLHM9blsyXSxvPW5bM10sYz10WzBdLGE9dFsxXSxoPXRbMl0sZj10WzNdO3JldHVybiBlWzBdPWMqbytmKnIrYSpzLWgqaSxlWzFdPWEqbytmKmkraCpyLWMqcyxlWzJdPWgqbytmKnMrYyppLWEqcixlWzNdPWYqby1jKnItYSppLWgqcyxjPXRbNF0sYT10WzVdLGg9dFs2XSxmPXRbN10sZVs0XT1jKm8rZipyK2Eqcy1oKmksZVs1XT1hKm8rZippK2gqci1jKnMsZVs2XT1oKm8rZipzK2MqaS1hKnIsZVs3XT1mKm8tYypyLWEqaS1oKnMsZX1mdW5jdGlvbiBRdShlLHQsbil7bGV0IHI9dFswXSxpPXRbMV0scz10WzJdLG89dFszXSxjPW5bMF0sYT1uWzFdLGg9blsyXSxmPW5bM107cmV0dXJuIGVbMF09cipmK28qYytpKmgtcyphLGVbMV09aSpmK28qYStzKmMtcipoLGVbMl09cypmK28qaCtyKmEtaSpjLGVbM109bypmLXIqYy1pKmEtcypoLGM9bls0XSxhPW5bNV0saD1uWzZdLGY9bls3XSxlWzRdPXIqZitvKmMraSpoLXMqYSxlWzVdPWkqZitvKmErcypjLXIqaCxlWzZdPXMqZitvKmgrciphLWkqYyxlWzddPW8qZi1yKmMtaSphLXMqaCxlfWZ1bmN0aW9uIEt1KGUsdCxuLHIpe2lmKE1hdGguYWJzKHIpPEkpcmV0dXJuIF9vKGUsdCk7bGV0IGk9TWF0aC5zcXJ0KG5bMF0qblswXStuWzFdKm5bMV0rblsyXSpuWzJdKTtyPXIqLjU7bGV0IHM9TWF0aC5zaW4ociksbz1zKm5bMF0vaSxjPXMqblsxXS9pLGE9cypuWzJdL2ksaD1NYXRoLmNvcyhyKSxmPXRbMF0sdT10WzFdLGQ9dFsyXSxnPXRbM107ZVswXT1mKmgrZypvK3UqYS1kKmMsZVsxXT11KmgrZypjK2Qqby1mKmEsZVsyXT1kKmgrZyphK2YqYy11Km8sZVszXT1nKmgtZipvLXUqYy1kKmE7bGV0IG09dFs0XSxfPXRbNV0scD10WzZdLHg9dFs3XTtyZXR1cm4gZVs0XT1tKmgreCpvK18qYS1wKmMsZVs1XT1fKmgreCpjK3Aqby1tKmEsZVs2XT1wKmgreCphK20qYy1fKm8sZVs3XT14KmgtbSpvLV8qYy1wKmEsZX1mdW5jdGlvbiBIdShlLHQsbil7cmV0dXJuIGVbMF09dFswXStuWzBdLGVbMV09dFsxXStuWzFdLGVbMl09dFsyXStuWzJdLGVbM109dFszXStuWzNdLGVbNF09dFs0XStuWzRdLGVbNV09dFs1XStuWzVdLGVbNl09dFs2XStuWzZdLGVbN109dFs3XStuWzddLGV9ZnVuY3Rpb24geW8oZSx0LG4pe2xldCByPXRbMF0saT10WzFdLHM9dFsyXSxvPXRbM10sYz1uWzRdLGE9bls1XSxoPW5bNl0sZj1uWzddLHU9dFs0XSxkPXRbNV0sZz10WzZdLG09dFs3XSxfPW5bMF0scD1uWzFdLHg9blsyXSxUPW5bM107cmV0dXJuIGVbMF09cipUK28qXytpKngtcypwLGVbMV09aSpUK28qcCtzKl8tcip4LGVbMl09cypUK28qeCtyKnAtaSpfLGVbM109bypULXIqXy1pKnAtcyp4LGVbNF09cipmK28qYytpKmgtcyphK3UqVCttKl8rZCp4LWcqcCxlWzVdPWkqZitvKmErcypjLXIqaCtkKlQrbSpwK2cqXy11KngsZVs2XT1zKmYrbypoK3IqYS1pKmMrZypUK20qeCt1KnAtZCpfLGVbN109bypmLXIqYy1pKmEtcypoK20qVC11Kl8tZCpwLWcqeCxlfWNvbnN0IEp1PXlvO2Z1bmN0aW9uIHQwKGUsdCxuKXtyZXR1cm4gZVswXT10WzBdKm4sZVsxXT10WzFdKm4sZVsyXT10WzJdKm4sZVszXT10WzNdKm4sZVs0XT10WzRdKm4sZVs1XT10WzVdKm4sZVs2XT10WzZdKm4sZVs3XT10WzddKm4sZX1jb25zdCB4bz1lbztmdW5jdGlvbiBlMChlLHQsbixyKXtsZXQgaT0xLXI7cmV0dXJuIHhvKHQsbik8MCYmKHI9LXIpLGVbMF09dFswXSppK25bMF0qcixlWzFdPXRbMV0qaStuWzFdKnIsZVsyXT10WzJdKmkrblsyXSpyLGVbM109dFszXSppK25bM10qcixlWzRdPXRbNF0qaStuWzRdKnIsZVs1XT10WzVdKmkrbls1XSpyLGVbNl09dFs2XSppK25bNl0qcixlWzddPXRbN10qaStuWzddKnIsZX1mdW5jdGlvbiBuMChlLHQpe2xldCBuPUluKHQpO3JldHVybiBlWzBdPS10WzBdL24sZVsxXT0tdFsxXS9uLGVbMl09LXRbMl0vbixlWzNdPXRbM10vbixlWzRdPS10WzRdL24sZVs1XT0tdFs1XS9uLGVbNl09LXRbNl0vbixlWzddPXRbN10vbixlfWZ1bmN0aW9uIHIwKGUsdCl7cmV0dXJuIGVbMF09LXRbMF0sZVsxXT0tdFsxXSxlWzJdPS10WzJdLGVbM109dFszXSxlWzRdPS10WzRdLGVbNV09LXRbNV0sZVs2XT0tdFs2XSxlWzddPXRbN10sZX1jb25zdCBNbz1ubyxpMD1NbyxJbj1ybyxzMD1JbjtmdW5jdGlvbiBvMChlLHQpe2xldCBuPUluKHQpO2lmKG4+MCl7bj1NYXRoLnNxcnQobik7bGV0IHI9dFswXS9uLGk9dFsxXS9uLHM9dFsyXS9uLG89dFszXS9uLGM9dFs0XSxhPXRbNV0saD10WzZdLGY9dFs3XSx1PXIqYytpKmErcypoK28qZjtlWzBdPXIsZVsxXT1pLGVbMl09cyxlWzNdPW8sZVs0XT0oYy1yKnUpL24sZVs1XT0oYS1pKnUpL24sZVs2XT0oaC1zKnUpL24sZVs3XT0oZi1vKnUpL259cmV0dXJuIGV9ZnVuY3Rpb24gYzAoZSl7cmV0dXJuInF1YXQyKCIrZVswXSsiLCAiK2VbMV0rIiwgIitlWzJdKyIsICIrZVszXSsiLCAiK2VbNF0rIiwgIitlWzVdKyIsICIrZVs2XSsiLCAiK2VbN10rIikifWZ1bmN0aW9uIGEwKGUsdCl7cmV0dXJuIGVbMF09PT10WzBdJiZlWzFdPT09dFsxXSYmZVsyXT09PXRbMl0mJmVbM109PT10WzNdJiZlWzRdPT09dFs0XSYmZVs1XT09PXRbNV0mJmVbNl09PT10WzZdJiZlWzddPT09dFs3XX1mdW5jdGlvbiBsMChlLHQpe2xldCBuPWVbMF0scj1lWzFdLGk9ZVsyXSxzPWVbM10sbz1lWzRdLGM9ZVs1XSxhPWVbNl0saD1lWzddLGY9dFswXSx1PXRbMV0sZD10WzJdLGc9dFszXSxtPXRbNF0sXz10WzVdLHA9dFs2XSx4PXRbN107cmV0dXJuIE1hdGguYWJzKG4tZik8PUkqTWF0aC5tYXgoMSxNYXRoLmFicyhuKSxNYXRoLmFicyhmKSkmJk1hdGguYWJzKHItdSk8PUkqTWF0aC5tYXgoMSxNYXRoLmFicyhyKSxNYXRoLmFicyh1KSkmJk1hdGguYWJzKGktZCk8PUkqTWF0aC5tYXgoMSxNYXRoLmFicyhpKSxNYXRoLmFicyhkKSkmJk1hdGguYWJzKHMtZyk8PUkqTWF0aC5tYXgoMSxNYXRoLmFicyhzKSxNYXRoLmFicyhnKSkmJk1hdGguYWJzKG8tbSk8PUkqTWF0aC5tYXgoMSxNYXRoLmFicyhvKSxNYXRoLmFicyhtKSkmJk1hdGguYWJzKGMtXyk8PUkqTWF0aC5tYXgoMSxNYXRoLmFicyhjKSxNYXRoLmFicyhfKSkmJk1hdGguYWJzKGEtcCk8PUkqTWF0aC5tYXgoMSxNYXRoLmFicyhhKSxNYXRoLmFicyhwKSkmJk1hdGguYWJzKGgteCk8PUkqTWF0aC5tYXgoMSxNYXRoLmFicyhoKSxNYXRoLmFicyh4KSl9dmFyIGgwPU9iamVjdC5mcmVlemUoe19fcHJvdG9fXzpudWxsLGFkZDpIdSxjbG9uZTpSdSxjb25qdWdhdGU6cjAsY29weTpfbyxjcmVhdGU6THUsZG90OnhvLGVxdWFsczpsMCxleGFjdEVxdWFsczphMCxmcm9tTWF0NDp6dSxmcm9tUm90YXRpb246TnUsZnJvbVJvdGF0aW9uVHJhbnNsYXRpb246cG8sZnJvbVJvdGF0aW9uVHJhbnNsYXRpb25WYWx1ZXM6Q3UsZnJvbVRyYW5zbGF0aW9uOlZ1LGZyb21WYWx1ZXM6JHUsZ2V0RHVhbDpCdSxnZXRSZWFsOmt1LGdldFRyYW5zbGF0aW9uOll1LGlkZW50aXR5OnF1LGludmVydDpuMCxsZW46aTAsbGVuZ3RoOk1vLGxlcnA6ZTAsbXVsOkp1LG11bHRpcGx5OnlvLG5vcm1hbGl6ZTpvMCxyb3RhdGVBcm91bmRBeGlzOkt1LHJvdGF0ZUJ5UXVhdEFwcGVuZDpqdSxyb3RhdGVCeVF1YXRQcmVwZW5kOlF1LHJvdGF0ZVg6WnUscm90YXRlWTpYdSxyb3RhdGVaOkd1LHNjYWxlOnQwLHNldDpGdSxzZXREdWFsOkR1LHNldFJlYWw6VXUsc3FyTGVuOnMwLHNxdWFyZWRMZW5ndGg6SW4sc3RyOmMwLHRyYW5zbGF0ZTpXdX0pO2Z1bmN0aW9uIGYwKGUsdCxuLHIpe2NvbnN0IGk9bipyO3JldHVybiB0LnNsaWNlKGksaStyKX1mdW5jdGlvbiB3byhlLHQpe2NvbnN0IG49W107Zm9yKGxldCByPTA7cjx0O3IrKyl7Y29uc3QgaT1yKnQ7bltyXT1lLnNsaWNlKGksaSt0KX1yZXR1cm4gbn1mdW5jdGlvbiBUbyhlLHQsbixyKXtmb3IobGV0IGk9MDtpPHI7aSsrKWVbaV09dFtpKnIrbl07cmV0dXJuIGV9ZnVuY3Rpb24gQW8oZSx0KXtjb25zdCBuPVtdO2ZvcihsZXQgcj0wO3I8dDtyKyspVG8obltyXT1bXSxlLHIsdCk7cmV0dXJuIG59ZnVuY3Rpb24gUG4oZSx0LG4pe2NvbnN0IHI9d28odCxuKTtmb3IobGV0IGk9MDtpPG47aSsrKXtjb25zdCBzPXJbaV07ZVtpXT1NYXRoLmh5cG90KC4uLnMpfXJldHVybiBlfWZ1bmN0aW9uIExuKGUsdCxuKXtjb25zdCByPUFvKHQsbik7Zm9yKGxldCBpPTA7aTxuO2krKyl7Y29uc3Qgcz1yW2ldO2VbaV09TWF0aC5oeXBvdCguLi5zKX1yZXR1cm4gZX1mdW5jdGlvbiB1MChlLHQsbil7Y29uc3Qgcj10LTEsaT10KnI7Zm9yKGxldCBzPTA7czxyO3MrKyllW2krc109bltzXTtyZXR1cm4gZX1mdW5jdGlvbiB6dChlLHQsbixyKXtyPz8ocj1uLmxlbmd0aCk7Zm9yKGxldCBpPTA7aTxyO2krKyl7Y29uc3Qgcz1pKnIsbz1uW2ldO2ZvcihsZXQgYz0wO2M8cjtjKyspe2NvbnN0IGE9cytjO2VbYV09dFthXSpvfX1yZXR1cm4gZX1mdW5jdGlvbiBxdChlLHQsbixyKXtyPz8ocj1uLmxlbmd0aCk7Zm9yKGxldCBpPTA7aTxyO2krKyl7Y29uc3Qgcz1pKnI7Zm9yKGxldCBvPTA7bzxyO28rKyl7Y29uc3QgYz1zK287ZVtjXT10W2NdKm5bb119fXJldHVybiBlfW5ldyBLLG5ldyBMLG5ldyB5dDtjb25zdCBkdD1bbmV3IEssbmV3IEssbmV3IEssbmV3IEtdLGN0PVtuZXcgTCxuZXcgTCxuZXcgTCxuZXcgTF0sZDA9W25ldyB5dCxuZXcgeXQsbmV3IHl0LG5ldyB5dF0sUnI9W25ldyBudCxuZXcgbnQsbmV3IG50LG5ldyBudF0sT289W25ldyBvdCxuZXcgb3QsbmV3IG90LG5ldyBvdF0sdm89W25ldyB1dCxuZXcgdXQsbmV3IHV0LG5ldyB1dF0sZzA9W25ldyBrLG5ldyBrLG5ldyBrLG5ldyBrXTtmdW5jdGlvbiBndChlKXtzd2l0Y2goZSl7Y2FzZSAyOnJldHVybiBkdDtjYXNlIDM6cmV0dXJuIGN0O2Nhc2UgNDpyZXR1cm4gZDA7Y2FzZSA5OnJldHVybiBScjtjYXNlIDE2OnJldHVybiBPbztkZWZhdWx0OnRocm93IG5ldyBFcnJvcihg5LiN5pSv5oyB6I635Y+W5Li05pe25Y+Y6YePOiAke2V9YCl9fXZhciBFbz0oZT0+KGVbZS5DT0wwUk9XMD0wXT0iQ09MMFJPVzAiLGVbZS5DT0wwUk9XMT0xXT0iQ09MMFJPVzEiLGVbZS5DT0wxUk9XMD0yXT0iQ09MMVJPVzAiLGVbZS5DT0wxUk9XMT0zXT0iQ09MMVJPVzEiLGUpKShFb3x8e30pO2NvbnN0IG0wPU9iamVjdC5mcmVlemUoWzEsMCwwLDFdKTtjbGFzcyBsZSBleHRlbmRzIGRue3N0YXRpYyBnZXQgSURFTlRJVFkoKXtyZXR1cm4gXzAoKX1zdGF0aWMgZ2V0IFpFUk8oKXtyZXR1cm4gcDAoKX1nZXQgRUxFTUVOVFMoKXtyZXR1cm4gNH1nZXQgUkFOSygpe3JldHVybiAyfWdldCBJTkRJQ0VTKCl7cmV0dXJuIEVvfWNvbnN0cnVjdG9yKHQsLi4ubil7c3VwZXIoLTAsLTAsLTAsLTApLGFyZ3VtZW50cy5sZW5ndGg9PT0xJiZBcnJheS5pc0FycmF5KHQpP3RoaXMuY29weSh0KTpuLmxlbmd0aD4wP3RoaXMuY29weShbdCwuLi5uXSk6dGhpcy5pZGVudGl0eSgpfWNvcHkodCl7cmV0dXJuIHRoaXNbMF09dFswXSx0aGlzWzFdPXRbMV0sdGhpc1syXT10WzJdLHRoaXNbM109dFszXSx0aGlzLmNoZWNrKCl9aWRlbnRpdHkoKXtyZXR1cm4gdGhpcy5jb3B5KG0wKX1mcm9tT2JqZWN0KHQpe3JldHVybiB0aGlzLmNoZWNrKCl9c2V0KHQsbixyLGkpe3JldHVybiB0aGlzWzBdPXQsdGhpc1sxXT1uLHRoaXNbMl09cix0aGlzWzNdPWksdGhpcy5jaGVjaygpfXNldFJvd01ham9yKHQsbixyLGkpe3JldHVybiB0aGlzWzBdPXQsdGhpc1sxXT1yLHRoaXNbMl09bix0aGlzWzNdPWksdGhpcy5jaGVjaygpfWRldGVybWluYW50KCl7cmV0dXJuIGJuKHRoaXMpfXRyYW5zcG9zZSgpe3JldHVybiBobyh0aGlzLHRoaXMpLHRoaXMuY2hlY2soKX1pbnZlcnQoKXtyZXR1cm4gUHIodGhpcyx0aGlzKSx0aGlzLmNoZWNrKCl9bXVsdGlwbHlMZWZ0KHQpe3JldHVybiBTbih0aGlzLHQsdGhpcyksdGhpcy5jaGVjaygpfW11bHRpcGx5UmlnaHQodCl7cmV0dXJuIFNuKHRoaXMsdGhpcyx0KSx0aGlzLmNoZWNrKCl9bXVsdGlwbHlCeVZlY3Rvcih0LG4pe258fChuPW5ldyBLKTtjb25zdCByPXQueCxpPXQueSxzPXRoaXNbMF0qcit0aGlzWzJdKmksbz10aGlzWzFdKnIrdGhpc1szXSppO3JldHVybiBuLng9cyxuLnk9byxufW11bHRpcGx5QnlTY2FsZSh0LG4pe3JldHVybiBufHwobj1uZXcgbGUpLG5bMF09dGhpc1swXSp0LngsblsxXT10aGlzWzFdKnQueCxuWzJdPXRoaXNbMl0qdC55LG5bM109dGhpc1szXSp0Lnksbn1yb3RhdGUodCl7cmV0dXJuIGZvKHRoaXMsdGhpcyx0KSx0aGlzLmNoZWNrKCl9c2NhbGUodCl7cmV0dXJuIEFycmF5LmlzQXJyYXkodCk/THIodGhpcyx0aGlzLHQpOkxyKHRoaXMsdGhpcyxbdCx0XSksdGhpcy5jaGVjaygpfXRyYW5zZm9ybSh0LG4pe2NvbnN0IHI9SWUobnx8Wy0wLC0wXSx0LHRoaXMpO3JldHVybiBHdChyLHQubGVuZ3RoKSxyfXRyYW5zZm9ybVZlY3Rvcih0LG4pe3JldHVybiB0aGlzLnRyYW5zZm9ybSh0LG4pfXRyYW5zZm9ybVZlY3RvcjIodCxuKXtyZXR1cm4gdGhpcy50cmFuc2Zvcm0odCxuKX10cmFuc2Zvcm1WZWN0b3IzKHQsbil7cmV0dXJuIHRoaXMudHJhbnNmb3JtKHQsbil9fWxldCBSbiwkbj1udWxsO2Z1bmN0aW9uIHAwKCl7cmV0dXJuIFJufHwoUm49bmV3IGxlKFswLDAsMCwwXSksT2JqZWN0LmZyZWV6ZShSbikpLFJufWZ1bmN0aW9uIF8wKCl7cmV0dXJuICRufHwoJG49bmV3IGxlLE9iamVjdC5mcmVlemUoJG4pKSwkbn1mdW5jdGlvbiBibyhlLHQpe3JldHVybiBQbihlLHQsMiksYm4odCk8MCYmKGVbMF09LWVbMF0pLGV9ZnVuY3Rpb24gU28oZSx0KXtyZXR1cm4gTG4oZSx0LDIpLGJuKHQpPDAmJihlWzBdPS1lWzBdKSxlfWZ1bmN0aW9uIHkwKGUsdCxuKXtyZXR1cm4genQoZSx0LG4sMil9ZnVuY3Rpb24geDAoZSx0LG4pe3JldHVybiBxdChlLHQsbiwyKX1mdW5jdGlvbiBJbyhlLHQsbil7U28oZSxuKSxpcihlLGUpLHF0KHQsbixlLDIpfWZ1bmN0aW9uIFBvKGUsdCxuKXtyZXR1cm4gcXQoZSxuLHQsMil9ZnVuY3Rpb24gTG8oZSx0LG4pe2JvKHQsbiksaXIodCx0KSx6dChlLG4sdCwyKX1mdW5jdGlvbiBSbyhlLHQsbil7cmV0dXJuIHp0KGUsdCxuLDIpfWZ1bmN0aW9uIENuKGUsdCl7cmV0dXJuIGxvKGUsdFswXSx0WzFdLHRbM10sdFs0XSl9ZnVuY3Rpb24gJHIoZSx0KXtyZXR1cm4gZ24oZSx0KSx5cihlLGUpfWZ1bmN0aW9uICRvKGUsdCl7cmV0dXJuIFBuKGUsdCwzKSxLdCh0KTwwJiYoZVswXT0tZVswXSksZX1mdW5jdGlvbiBDbyhlLHQpe3JldHVybiBMbihlLHQsMyksS3QodCk8MCYmKGVbMF09LWVbMF0pLGV9ZnVuY3Rpb24gTTAoZSx0LG4pe3JldHVybiB6dChlLHQsbiwzKX1mdW5jdGlvbiB3MChlLHQsbil7cmV0dXJuIHF0KGUsdCxuLDMpfWZ1bmN0aW9uIENyKGUsdCxuKXtDbyhlLG4pLG1yKGUsZSkscXQodCxuLGUsMyl9Y29uc3QgRnQ9bmV3IG50O2Z1bmN0aW9uIFQwKGUsdCxuKXtDcihlLEZ0LG4pLFJlKHQsRnQpfWZ1bmN0aW9uIFZyKGUsdCxuKXtyZXR1cm4gcXQoZSxuLHQsMyl9ZnVuY3Rpb24gQTAoZSx0LG4pe3JldHVybiBMZShGdCxuKSxWcihlLHQsRnQpfWZ1bmN0aW9uIE5yKGUsdCxuKXskbyh0LG4pLG1yKHQsdCksenQoZSxuLHQsMyl9ZnVuY3Rpb24gVm8oZSx0LG4pe05yKEZ0LHQsbiksUmUoZSxGdCl9ZnVuY3Rpb24genIoZSx0LG4pe3JldHVybiB6dChlLHQsbiwzKX1mdW5jdGlvbiBObyhlLHQsbil7cmV0dXJuIExlKEZ0LHQpLHpyKGUsRnQsbil9ZnVuY3Rpb24gcXIoZSx0KXtyZXR1cm4gZVs2XT10WzBdLGVbN109dFsxXSxlfWZ1bmN0aW9uIEZyKGUsdCl7cmV0dXJuIGVbMF09dFs2XSxlWzFdPXRbN10sZX1jb25zdCBhdD1uZXcgbGU7ZnVuY3Rpb24gem8oZSx0KXtDbihhdCxlKTtjb25zdCBuPUllKGR0WzBdLHQsYXQpO3JldHVybiBxcihlLG4pfWZ1bmN0aW9uIHFvKGUsdCl7cmV0dXJuIEZyKGUsdCksQ24oYXQsdCksUHIoYXQsYXQpLEllKGUsZSxhdCl9ZnVuY3Rpb24gTzAoZSx0LG4scixpPUgudHJzKXtILmlzTG9jYWxUcmFuc2xhdGlvbihpKT9xbyhlLHIpOkZyKGUsciksQ24oYXQsciksSC5pc1NSKGkpP0lvKG4sdCxhdCk6TG8odCxuLGF0KX1mdW5jdGlvbiB2MChlLHQsbixyLGk9SC50cnMpe0guaXNTUihpKT9QbyhhdCxyLG4pOlJvKGF0LG4sciksa28oZSxhdCksSC5pc0xvY2FsVHJhbnNsYXRpb24oaSk/em8oZSx0KTpxcihlLHQpfWZ1bmN0aW9uIEZvKGUsdCl7cmV0dXJuIGVbMF09dFswXSxlWzFdPXRbMV0sZVszXT10WzJdLGVbNF09dFszXSxlfWZ1bmN0aW9uIGtvKGUsdCl7cmV0dXJuIEZvKGUsdCksZVsyXT0wLGVbNV09MCxlWzZdPTAsZVs3XT0wLGVbOF09MSxlfWZ1bmN0aW9uIGtyKGUsdCl7cmV0dXJuIHVzKGUsdFswXSx0WzFdLHRbMl0sdFs0XSx0WzVdLHRbNl0sdFs4XSx0WzldLHRbMTBdKX1mdW5jdGlvbiBCbyhlLHQpe3JldHVybiBlWzBdPXRbMF0sZVsxXT10WzFdLGVbMl09dFsyXSxlWzRdPXRbM10sZVs1XT10WzRdLGVbNl09dFs1XSxlWzhdPXRbNl0sZVs5XT10WzddLGVbMTBdPXRbOF0sZX1mdW5jdGlvbiBVbyhlLHQpe3JldHVybiBCbyhlLHQpLGVbM109MCxlWzddPTAsZVsxMV09MCxlWzEyXT0wLGVbMTNdPTAsZVsxNF09MCxlWzE1XT0xLGV9ZnVuY3Rpb24gQnIoZSx0KXtyZXR1cm4gZVsxMl09dFswXSxlWzEzXT10WzFdLGVbMTRdPXRbMl0sZX1jb25zdCBsdD1uZXcgbnQ7ZnVuY3Rpb24gRG8oZSx0KXtfcihsdCxlKTtjb25zdCBuPVF0KGN0WzBdLHQsbHQpO3JldHVybiBCcihlLG4pfWZ1bmN0aW9uIFlvKGUsdCl7cmV0dXJuIE1uKGUsdCksX3IobHQsdCksZ24obHQsbHQpLFF0KGUsZSxsdCl9ZnVuY3Rpb24gRTAoZSx0KXtyZXR1cm4gUG4oZSx0LDQpLHluKHQpPDAmJihlWzBdPS1lWzBdKSxlfWZ1bmN0aW9uIGIwKGUsdCl7cmV0dXJuIExuKGUsdCw0KSx5bih0KTwwJiYoZVswXT0tZVswXSksZX1mdW5jdGlvbiBTMChlLHQsbil7cmV0dXJuIHp0KGUsdCxuLDQpfWZ1bmN0aW9uIEkwKGUsdCxuKXtyZXR1cm4gcXQoZSx0LG4sNCl9ZnVuY3Rpb24gV28oZSx0LG4scixpPUgudHJzKXtILmlzTG9jYWxUcmFuc2xhdGlvbihpKT9ZbyhlLHIpOk1uKGUsciksa3IobHQsciksSC5pc1NSKGkpP0NyKG4sdCxsdCk6TnIodCxuLGx0KX1jb25zdCBWbj1uZXcgbnQ7ZnVuY3Rpb24gUDAoZSx0LG4scixpPUgudHJzKXtXbyhlLFZuLG4scixpKSxSZSh0LFZuKX1mdW5jdGlvbiBabyhlLHQsbixyLGk9SC50cnMpe3JldHVybiBILmlzU1IoaSk/VnIobHQscixuKTp6cihsdCxuLHIpLFVvKGUsbHQpLEguaXNMb2NhbFRyYW5zbGF0aW9uKGkpP0RvKGUsdCk6QnIoZSx0KSxlfWZ1bmN0aW9uIEwwKGUsdCxuLHIsaT1ILnRycyl7cmV0dXJuIExlKFZuLG4pLFpvKGUsdCxWbixyLGkpfWZ1bmN0aW9uIFhvKGUsdCxuKXtjb25zdCByPUQodC5sZW5ndGgpLGk9ci5zcXVhcmVkTGVuZ3RoKG4pO2lmKEYoaSwwKSlyZXR1cm4gci5zY2FsZShlLHQsMCk7Y29uc3Qgcz1yLmRvdCh0LG4pL2k7cmV0dXJuIHIuc2NhbGUoZSxuLHMpfWZ1bmN0aW9uIHh0KGUsdCxuKXtyZXR1cm4gWG8oZSx0LG4pLFN0KGUsdCxlKX1mdW5jdGlvbiBSMChlLHQsbil7cmV0dXJuIEQodC5sZW5ndGgpLmNyb3NzKGUsdCxuKX1mdW5jdGlvbiBXKGUsdCl7Y29uc3Qgbj10LmZpbmRJbmRleChpPT4hRihpLDApKTtpZihuPT09LTEpcmV0dXJuIDA7Y29uc3Qgcj1lW25dO3JldHVybiBGKHIsMCk/MS8wOnRbbl0vcn1mdW5jdGlvbiBObihlLHQpe2NvbnN0IG49dC5maW5kSW5kZXgocz0+IUYocywwKSk7aWYobj09PS0xKXJldHVybiEwO2NvbnN0IHI9ZVtuXS90W25dO3JldHVybiBFdC5nZXRDcm9zc0F4aXNzKG4pLmV2ZXJ5KHM9PkYodFtzXSpyLGVbc10pKX1mdW5jdGlvbiAkMChlLHQpe2NvbnN0IG49RChlLmxlbmd0aCkscj1uLmNyb3NzKFtdLGUsdCksaT1uLnNxdWFyZWRMZW5ndGgocik7cmV0dXJuIEYoaSwwKX1mdW5jdGlvbiBHbyhlLHQpe3JldHVybiBGKG9lKFtdLGUsdClbMl0sMCl9ZnVuY3Rpb24gQzAoZSx0KXtjb25zdCBuPXN0KFtdLGUsdCk7cmV0dXJuIEYoYW4obiksMCl9ZnVuY3Rpb24gam8oZSx0KXtjb25zdCByPUQoZS5sZW5ndGgpLmNyb3NzKFtdLGUsdCk7cmV0dXJuIE1hdGguaHlwb3QoLi4ucil9ZnVuY3Rpb24gUW8oZSx0KXtjb25zdCBuPXN0KFtdLGUsdCk7cmV0dXJuIE1hdGguaHlwb3QoLi4ubil9ZnVuY3Rpb24gS28oZSx0KXtyZXR1cm4gTWF0aC5hYnMoaGUoZSx0KSl9ZnVuY3Rpb24gSG8oZSx0LG4pe3JldHVybiBlLmxlbmd0aD09PTI/aGUoZSx0KTpVcihlLHQsbil9ZnVuY3Rpb24gaGUoZSx0KXtyZXR1cm4gb2UoW10sZSx0KVsyXX1mdW5jdGlvbiBVcihlLHQsbil7Y29uc3Qgcj1bLi4uZSwuLi50LC4uLm5dO3JldHVybiBLdChyKX1mdW5jdGlvbiBEcihlLHQpe2NvbnN0IG49RChlLmxlbmd0aCk7cmV0dXJuIG4uZG90KGUsdCk8MCYmbi5uZWdhdGUoZSxlKSxlfWZ1bmN0aW9uIEpvKGUpe3JldHVybiBNYXRoLmh5cG90KC4uLmUpfWZ1bmN0aW9uIHRjKGUsdCxuKXtjb25zdCByPXQubGVuZ3RoO2ZvcihsZXQgaT0wO2k8cjtpKyspZVtpXT10W2ldK25baV07cmV0dXJuIGV9ZnVuY3Rpb24gU3QoZSx0LG4pe2NvbnN0IHI9dC5sZW5ndGg7Zm9yKGxldCBpPTA7aTxyO2krKyllW2ldPXRbaV0tbltpXTtyZXR1cm4gZX1mdW5jdGlvbiBWMChlLHQsbil7Y29uc3Qgcj10Lmxlbmd0aDtmb3IobGV0IGk9MDtpPHI7aSsrKWVbaV09dFtpXSpuW2ldO3JldHVybiBlfWZ1bmN0aW9uIE4wKGUsdCxuKXtjb25zdCByPXQubGVuZ3RoO2ZvcihsZXQgaT0wO2k8cjtpKyspZVtpXT10W2ldL25baV07cmV0dXJuIGV9ZnVuY3Rpb24gejAoZSx0KXtjb25zdCBuPXQubGVuZ3RoO2ZvcihsZXQgcj0wO3I8bjtyKyspZVtyXT1NYXRoLmNlaWwodFtyXSk7cmV0dXJuIGV9ZnVuY3Rpb24gcTAoZSx0KXtjb25zdCBuPXQubGVuZ3RoO2ZvcihsZXQgcj0wO3I8bjtyKyspZVtyXT1NYXRoLmZsb29yKHRbcl0pO3JldHVybiBlfWZ1bmN0aW9uIEYwKGUsdCxuKXtjb25zdCByPXQubGVuZ3RoO2ZvcihsZXQgaT0wO2k8cjtpKyspZVtpXT1NYXRoLm1pbih0W2ldLG5baV0pO3JldHVybiBlfWZ1bmN0aW9uIGswKGUsdCxuKXtjb25zdCByPXQubGVuZ3RoO2ZvcihsZXQgaT0wO2k8cjtpKyspZVtpXT1NYXRoLm1heCh0W2ldLG5baV0pO3JldHVybiBlfWZ1bmN0aW9uIEIwKGUpe3JldHVybiBlPDA/TWF0aC5jZWlsKGUtLjUpOk1hdGguZmxvb3IoZSsuNSl9ZnVuY3Rpb24gVTAoZSx0KXtjb25zdCBuPXQubGVuZ3RoO2ZvcihsZXQgcj0wO3I8bjtyKyspZVtyXT1CMCh0W3JdKTtyZXR1cm4gZX1mdW5jdGlvbiBZcihlLHQsbil7Y29uc3Qgcj10Lmxlbmd0aDtmb3IobGV0IGk9MDtpPHI7aSsrKWVbaV09dFtpXSpuO3JldHVybiBlfWZ1bmN0aW9uIFdyKGUsdCxuLHIpe2NvbnN0IGk9dC5sZW5ndGg7Zm9yKGxldCBzPTA7czxpO3MrKyllW3NdPXRbc10rbltzXSpyO3JldHVybiBlfWZ1bmN0aW9uIGVjKGUsdCl7Y29uc3Qgbj1TdChbXSx0LGUpO3JldHVybiBKbyhuKX1mdW5jdGlvbiBuYyhlLHQpe2NvbnN0IG49U3QoW10sdCxlKTtyZXR1cm4gWnIobil9ZnVuY3Rpb24gWnIoZSl7Y29uc3QgdD1lLmxlbmd0aDtsZXQgbj0wO2ZvcihsZXQgcj0wO3I8dDtyKyspbis9ZVtyXSoqMjtyZXR1cm4gbn1mdW5jdGlvbiBEMChlLHQpe2NvbnN0IG49dC5sZW5ndGg7Zm9yKGxldCByPTA7cjxuO3IrKyllW3JdPS10W3JdO3JldHVybiBlfWZ1bmN0aW9uIFkwKGUsdCl7Y29uc3Qgbj10Lmxlbmd0aDtmb3IobGV0IHI9MDtyPG47cisrKWVbcl09MS90W3JdO3JldHVybiBlfWZ1bmN0aW9uIFcwKGUsdCl7Y29uc3Qgbj1acih0KSxyPW4+MD8xL01hdGguc3FydChuKTowO3JldHVybiBZcihlLHQscil9ZnVuY3Rpb24gem4oZSx0KXtjb25zdCBuPWUubGVuZ3RoO2xldCByPTA7Zm9yKGxldCBpPTA7aTxuO2krKylyKz1lW2ldKnRbaV07cmV0dXJuIHJ9ZnVuY3Rpb24gWjAoZSx0LG4scil7Y29uc3QgaT10Lmxlbmd0aDtmb3IobGV0IHM9MDtzPGk7cysrKWVbc109dFtzXStyKihuW3NdLXRbc10pO3JldHVybiBlfWZ1bmN0aW9uIFgwKGUsdCxuLHIpe2NvbnN0IGk9TWF0aC5hY29zKE1hdGgubWluKE1hdGgubWF4KHpuKHQsbiksLTEpLDEpKSxzPU1hdGguc2luKGkpLG89TWF0aC5zaW4oKDEtcikqaSkvcyxjPU1hdGguc2luKHIqaSkvcyxhPXQubGVuZ3RoO2ZvcihsZXQgaD0wO2g8YTtoKyspZVtoXT1vKnRbaF0rYypuW2hdO3JldHVybiBlfWZ1bmN0aW9uIEcwKGUsdCl7c3dpdGNoKEtzKGUpLHQub3JkZXIpe2Nhc2Ugay5YWVo6e0N0KGUsZSx0WzBdKSxWdChlLGUsdFsxXSksTnQoZSxlLHRbMl0pO2JyZWFrfWNhc2Ugay5ZWFo6e1Z0KGUsZSx0WzBdKSxDdChlLGUsdFsxXSksTnQoZSxlLHRbMl0pO2JyZWFrfWNhc2Ugay5aWFk6e050KGUsZSx0WzBdKSxDdChlLGUsdFsxXSksVnQoZSxlLHRbMl0pO2JyZWFrfWNhc2Ugay5aWVg6e050KGUsZSx0WzBdKSxWdChlLGUsdFsxXSksQ3QoZSxlLHRbMl0pO2JyZWFrfWNhc2Ugay5ZWlg6e1Z0KGUsZSx0WzBdKSxOdChlLGUsdFsxXSksQ3QoZSxlLHRbMl0pO2JyZWFrfWNhc2Ugay5YWlk6e0N0KGUsZSx0WzBdKSxOdChlLGUsdFsxXSksVnQoZSxlLHRbMl0pO2JyZWFrfWRlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKCJVbmtub3duIEV1bGVyIGFuZ2xlIG9yZGVyIil9cmV0dXJuIGV9ZnVuY3Rpb24gcmMoZSx0LG4scj1uZXcgdXQpe2NvbnN0W2ksc109Y3Q7cmV0dXJuIHh0KGksZSxuKS5ub3JtYWxpemUoKSx4dChzLHQsbikubm9ybWFsaXplKCksci5yb3RhdGlvblRvKGkscyl9ZnVuY3Rpb24gWHIoZSx0LG49bmV3IHV0KXtjb25zdFtyLGksc109Y3Q7ci5jb3B5KGUudGFuZ2VudCkubm9ybWFsaXplKCksaS5jb3B5KHQudGFuZ2VudCkubm9ybWFsaXplKCk7Y29uc3Qgbz12b1swXS5yb3RhdGlvblRvKHIsaSk7cmV0dXJuIGNlKHMsZS5ub3JtYWwsbykscmMocyx0Lm5vcm1hbCxpLG4pLG4ubXVsdGlwbHkobyksbn1mdW5jdGlvbiBpYyhlLHQpe3JldHVybiBNYXRoLnNpZ24oZSk9PT1NYXRoLnNpZ24odCkmJk1hdGguYWJzKGUpPE1hdGguYWJzKHQpP2U6KGUldCt0KSV0fWZ1bmN0aW9uIEdyKGUsdCxuPTAscj1uKXtjb25zdCBpPU1hdGguYWJzKGUtdCk7cmV0dXJuIGk8PXJ8fGk8PW4qTWF0aC5tYXgoTWF0aC5hYnMoZSksTWF0aC5hYnModCkpfWZ1bmN0aW9uIGpyKGUsdCxuPTApe2NvbnN0IHI9RChlLmxlbmd0aCk7bGV0IGk9ci5zcXVhcmVkTGVuZ3RoKGUpKnIuc3F1YXJlZExlbmd0aCh0KTtpZihpPT09MClyZXR1cm4gbjtpPU1hdGguc3FydChpKTtsZXQgcz1yLmRvdChlLHQpL2k7cmV0dXJuIHM9TWF0aC5tYXgoLTEsTWF0aC5taW4oMSxzKSksTWF0aC5hY29zKHMpfWZ1bmN0aW9uIFZlKGUsdCxuKXtsZXQgcj1qcihlLHQpO3JldHVybiByPT09MD9yOmN0WzBdLmNvcHkoZSkuY3Jvc3ModCkuZG90KG4pPDA/LXI6cn1mdW5jdGlvbiBqMChlLHQsbil7Y29uc3RbcixpXT1ndChlLmxlbmd0aCk7cmV0dXJuIHh0KHIsZSxuKSx4dChpLHQsbiksVmUocixpLG4pfWZ1bmN0aW9uIFEwKGUsdCxuKXtjb25zdFtyLGkscyxvXT1jdDtyLm5lZ2F0ZSgpLHh0KGksbix0KSx4dChzLGUsaSk7Y29uc3QgYz1WZSh0LHMsaSksYT1uZXcgTCh0KS5jcm9zcyhpKTt4dChvLGUsYSk7Y29uc3QgaD1WZSh0LG8sYSksZj14dChuZXcgTCxlLHIpLHU9VmUoaSxmLHIpO3JldHVybnt5YXc6YyxwaXRjaDpoLHJvbGw6dX19ZnVuY3Rpb24gZmUoZSl7cmV0dXJuIGU+PS1NYXRoLlBJJiZlPD1NYXRoLlBJP2U6c2MoZStNYXRoLlBJKS1NYXRoLlBJfWZ1bmN0aW9uIHNjKGUpe2lmKGU+PTAmJmU8PVopcmV0dXJuIGU7Y29uc3QgdD1pYyhlLFopO3JldHVybiBNYXRoLmFicyh0KTx2biYmTWF0aC5hYnMoZSk+dm4/Wjp0fWZ1bmN0aW9uIEswKGUsdCl7Y29uc3Qgbj1qcihlLHQpO3JldHVybiBuPklyP1otbjpufWZ1bmN0aW9uIG9jKGUsdCxuLHIpe2NvbnN0IGk9cnx8ZS5zbGljZSgpO3JldHVybiBzdChpLGksdCksRihhbihpKSwwKSYmKG4/RihNYXRoLmFicyh0WzJdKSwxKT9lWzBdLT0xZS00OmVbMl0rPTFlLTQ6RihNYXRoLmFicyhlWzBdKSwxKT90WzJdLT0xZS00OnRbMF0rPTFlLTQsJHQodCx0KSxzdChpLGUsdCkpLG4/c3QoZSx0LGkpOnN0KHQsaSxlKSwkdChpLGkpLCR0KHQsdCksJHQoZSxlKSx7dGFuZ2VudDplLG5vcm1hbDp0LGJpbm9ybWFsOml9fWZ1bmN0aW9uIGNjKGUsdCxuLHIpe2NvbnN0e2Jpbm9ybWFsOml9PW9jKGUsdCxuLHIpO3JldHVybiBsbihpLGkpLHtmcm9udDplLHVwOnQsYmlub3JtYWw6aX19ZnVuY3Rpb24gSDAoZSl7Y29uc3R7dGFuZ2VudDp0LG5vcm1hbDpuLGJpbm9ybWFsOnJ9PWU7cmV0dXJue2Zyb250OnQsdXA6bixiaW5vcm1hbDpsbihbXSxyKX19ZnVuY3Rpb24gSjAoZSl7Y29uc3R7ZnJvbnQ6dCx1cDpuLGJpbm9ybWFsOnJ9PWU7cmV0dXJue3RhbmdlbnQ6dCxub3JtYWw6bixiaW5vcm1hbDpsbihbXSxyKX19ZnVuY3Rpb24gdDEoZSx0LG4scj1uZXcgbnQpe2NvbnN0e2Zyb250OmksdXA6cyxiaW5vcm1hbDpvfT1jYygkdChbXSxlKSwkdChbXSx0KSxuKTtyZXR1cm4gci5zZXRDb2x1bW4oMCxvKSxyLnNldENvbHVtbigxLHMpLHIuc2V0Q29sdW1uKDIsaSkscn1jb25zdCBhYz17ZWFzdDpbMSwwLDBdLG5vcnRoOlswLDAsMV0sdXA6WzAsLTEsMF19O2Z1bmN0aW9uIGxjKGUsdD1hYyl7Y29uc3RbbixyXT1lLHM9ZzBbMF0uc2V0KC1yLDAsbixrLllYWikudG9RdWF0ZXJuaW9uKCkse2Vhc3Q6byxub3J0aDpjLHVwOmF9PXQsaD1uZXcgTCguLi5vKS50cmFuc2Zvcm1CeVF1YXRlcm5pb24ocyksZj1uZXcgTCguLi5jKS50cmFuc2Zvcm1CeVF1YXRlcm5pb24ocyksdT1uZXcgTCguLi5hKS50cmFuc2Zvcm1CeVF1YXRlcm5pb24ocyk7cmV0dXJue2Vhc3Q6aCxub3J0aDpmLHVwOnV9fWZ1bmN0aW9uIFFyKGUsdD1hYyl7Y29uc3RbbixyLGksc109Y3Q7aS5zZXQoMCwtMSwwKSxuLnNldCgwLDAsMSkscy5jb3B5KGUpLm5vcm1hbGl6ZSgpLHh0KHIscyxuKSxyLm5vcm1hbGl6ZSgpO2NvbnN0W28sY109dm87by5yb3RhdGlvblRvKGksciksYy5yb3RhdGlvblRvKHIscyksYy5tdWx0aXBseVJpZ2h0KG8pO2NvbnN0e2Vhc3Q6YSxub3J0aDpoLHVwOmZ9PXQsdT1uZXcgTCguLi5hKS50cmFuc2Zvcm1CeVF1YXRlcm5pb24oYyksZD1uZXcgTCguLi5oKS50cmFuc2Zvcm1CeVF1YXRlcm5pb24oYyksZz1uZXcgTCguLi5mKS50cmFuc2Zvcm1CeVF1YXRlcm5pb24oYyk7cmV0dXJue2Vhc3Q6dSxub3J0aDpkLHVwOmd9fWZ1bmN0aW9uIHFuKGUsdCl7Y29uc3R7eDpuLHk6cix6Oml9PWUscz1fdC5nZXRWZWN0b3IoX3Rbbl0sdCksbz1fdC5nZXRWZWN0b3IoX3Rbcl0sdCksYz1fdC5nZXRWZWN0b3IoX3RbaV0sdCk7cmV0dXJuIG5ldyBudChbLi4ucywuLi5vLC4uLmNdKX1mdW5jdGlvbiBoYyhlLHQsbil7Y29uc3Qgcj1jdFswXS5jb3B5KGUpLGk9cW4odCxuKTtyZXR1cm4gci50cmFuc2Zvcm1CeU1hdHJpeDMoaSkubmVnYXRlKCksci5hZGQoZSksbmV3IG90KFsuLi5pLnNsaWNlKDAsMyksMCwuLi5pLnNsaWNlKDMsNiksMCwuLi5pLnNsaWNlKDYsOSksMCwuLi5yLDFdKX1mdW5jdGlvbiBlMShlLHQsbil7Y29uc3Qgcj1RcihlLG4pO3JldHVybiBoYyhlLHQscil9ZnVuY3Rpb24gbjEoZSx0LG4pe2NvbnN0IHI9UXIoZSxuKTtyZXR1cm4gcW4odCxyKX1mdW5jdGlvbiByMShlLHQsbil7Y29uc3Qgcj1sYyhlLG4pO3JldHVybiBxbih0LHIpfWNvbnN0IGZjPW5ldyBMKDEsMSwxKSx1Yz1uZXcgTCgwLDAsMSk7Y2xhc3MgSHR7Y29uc3RydWN0b3IodCl7VSh0aGlzLCJhcnJheSIpO1UodGhpcywiY291bnQiLDApO1UodGhpcywidmVjdG9yU2l6ZSIpO1UodGhpcywic3RhcnQiLDApO3QmJnRoaXMuc2V0T3B0aW9ucyh0KX1nZXQgZW5kKCl7cmV0dXJuIHRoaXMuc3RhcnQrdGhpcy5jb3VudCp0aGlzLnZlY3RvclNpemV9c2V0IGVuZCh0KXt0aGlzLmNvdW50PU1hdGgudHJ1bmMoKHQtdGhpcy5zdGFydCkvdGhpcy52ZWN0b3JTaXplKX1zZXRPcHRpb25zKHQpe2NvbnN0e2VuZDpuLGNvdW50OnIsLi4uaX09dDtPYmplY3QuYXNzaWduKHRoaXMsaSksbj09bnVsbCYmcj09bnVsbD90aGlzLmNvdW50PXRoaXMuYXJyYXkubGVuZ3RoL3RoaXMudmVjdG9yU2l6ZTpuIT1udWxsJiYodGhpcy5lbmQ9bil9ZnJvbSh0KXtjb25zdHthcnJheTpuLC4uLnJ9PXQ7cmV0dXJuIHRoaXMuc2V0T3B0aW9ucyh7YXJyYXk6bi5zbGljZSgpLC4uLnJ9KSx0aGlzfWNsb25lKCl7Y29uc3QgdD1uZXcgdGhpcy5jb25zdHJ1Y3RvcjtyZXR1cm4gdC5mcm9tKHRoaXMpLHR9Y29weSh0KXtmb3IobGV0IG49MDtuPHRoaXMuY291bnQ7bisrKXRoaXMuY29weUF0KG4sdCxuKTtyZXR1cm4gdGhpc31jb3B5QXQodCxuLHIpe2NvbnN0IGk9bi5nZXRWZWN0b3Iocik7cmV0dXJuIHRoaXMuc2V0VmVjdG9yKHQsaSksdGhpc31jb3B5QXJyYXkodCl7Y29uc3Qgbj10aGlzLnN0YXJ0O2ZvcihsZXQgcj0wLGk9dC5sZW5ndGg7cjxpO3IrKyl0aGlzLmFycmF5W24rcl09dFtyXTtyZXR1cm4gdGhpc31nZXRTdGFydEFycmF5SW5kZXgodCl7cmV0dXJuIHRoaXMuc3RhcnQrdCp0aGlzLnZlY3RvclNpemV9Z2V0QXJyYXlJbmRleFJhbmdlKHQpe2NvbnN0IG49dGhpcy5zdGFydCt0KnRoaXMudmVjdG9yU2l6ZTtyZXR1cm5bbixuK3RoaXMudmVjdG9yU2l6ZV19Z2V0VmVjdG9yKHQpe3JldHVybiB0aGlzLmFycmF5LnNsaWNlKC4uLnRoaXMuZ2V0QXJyYXlJbmRleFJhbmdlKHQpKX1zZXRWZWN0b3IodCxuLHI9MCl7Y29uc3QgaT10aGlzLmdldFN0YXJ0QXJyYXlJbmRleCh0KTtmb3IobGV0IHM9MCxvPXRoaXMudmVjdG9yU2l6ZTtzPG87cysrKXRoaXMuYXJyYXlbaStzXT1uW3Irc107cmV0dXJuIHIrdGhpcy52ZWN0b3JTaXplfXRvVmVjdG9ycyh0PVtdKXtjb25zdHtzdGFydDpuLGVuZDpyLHZlY3RvclNpemU6aSxhcnJheTpzfT10aGlzO2ZvcihsZXQgbz1uO288cjtvKz1pKXtjb25zdCBjPXMuc2xpY2UobyxvK2kpO3QucHVzaChjKX1yZXR1cm4gdH1tYXAodCxuPVtdKXtmb3IobGV0IHI9MDtyPHRoaXMuY291bnQ7cisrKXtjb25zdCBpPXRoaXMuZ2V0VmVjdG9yKHIpO25bcl09dChpLHIpfXJldHVybiBufW1hcFNlbGYodCl7Zm9yKGxldCBuPTA7bjx0aGlzLmNvdW50O24rKyl7Y29uc3Qgcj10aGlzLmdldFZlY3RvcihuKSxpPXQocixuKTt0aGlzLnNldFZlY3RvcihuLGkpfXJldHVybiB0aGlzfWZpbHRlcih0LG49W10pe2ZvcihsZXQgcj0wO3I8dGhpcy5jb3VudDtyKyspe2NvbnN0IGk9dGhpcy5nZXRWZWN0b3Iocik7aWYodChpLHIpKWZvcihjb25zdCBzIG9mIGkpbltuLmxlbmd0aF09c31yZXR1cm4gbn10cmFuc2Zvcm0odCl7Y29uc3Qgbj0kZSh0Lmxlbmd0aCx0aGlzLnZlY3RvclNpemUpO3JldHVybiB0aGlzLm1hcFNlbGYocj0+bihyLHIsdCkpfXRyYW5zZm9ybUFzTm9ybWFsKHQpe2NvbnN0IG49UnJbMF07dC5sZW5ndGg9PT0xNj9NcihuLHQpOiRyKG4sdCk7Y29uc3Qgcj0kZShuLmxlbmd0aCx0aGlzLnZlY3RvclNpemUpO3JldHVybiB0aGlzLm1hcFNlbGYoaT0+cihpLGksbikpfXNjYWxlKHQpe2NvbnN0IG49RCh0aGlzLnZlY3RvclNpemUpO3JldHVybiB0aGlzLm1hcFNlbGYocj0+bi5zY2FsZShyLHIsdCkpfXNjYWxlQW5kQWRkKHQsbil7Y29uc3Qgcj1EKHRoaXMudmVjdG9yU2l6ZSk7cmV0dXJuIHRoaXMubWFwU2VsZihpPT5yLnNjYWxlQW5kQWRkKGksaSx0LG4pKX1hZGQodCl7Y29uc3Qgbj1EKHRoaXMudmVjdG9yU2l6ZSk7cmV0dXJuIHRoaXMubWFwU2VsZihyPT5uLmFkZChyLHIsdCkpfXN1YnRyYWN0KHQpe2NvbnN0IG49RCh0aGlzLnZlY3RvclNpemUpO3JldHVybiB0aGlzLm1hcFNlbGYocj0+bi5zdWJ0cmFjdChyLHIsdCkpfW11bHRpcGx5KHQpe2NvbnN0IG49RCh0aGlzLnZlY3RvclNpemUpO3JldHVybiB0aGlzLm1hcFNlbGYocj0+bi5tdWx0aXBseShyLHIsdCkpfWRpdmlkZSh0KXtjb25zdCBuPUQodGhpcy52ZWN0b3JTaXplKTtyZXR1cm4gdGhpcy5tYXBTZWxmKHI9Pm4uZGl2aWRlKHIscix0KSl9fWZ1bmN0aW9uIGkxKGUsdCl7Y29uc3R7dmVjdG9yU2l6ZTpuLHN0YXJ0OnI9MCxhcnJheTppfT1lLHM9JGUodC5sZW5ndGgsbiksbz1lLmVuZD8/aS5sZW5ndGg7Zm9yKGxldCBjPXI7YzxvO2MrPW4pe2NvbnN0IGE9aS5zbGljZShjLGMrbik7cyhhLGEsdCk7Zm9yKGxldCBoPTA7aDxuO2grKylpW2MraF09YVtoXX1yZXR1cm4gZX1mdW5jdGlvbiBzMShlLHQpe2NvbnN0e3ZlY3RvclNpemU6bixzdGFydDpyPTAsYXJyYXk6aX09ZSxzPUQobiksbz1lLmVuZD8/aS5sZW5ndGg7Zm9yKGxldCBjPXI7YzxvO2MrPW4pe2NvbnN0IGE9aS5zbGljZShjLGMrbik7cy5zY2FsZShhLGEsdCk7Zm9yKGxldCBoPTA7aDxuO2grKylpW2MraF09YVtoXX1yZXR1cm4gZX1mdW5jdGlvbiBvMShlLHQsbil7Y29uc3R7dmVjdG9yU2l6ZTpyLHN0YXJ0Omk9MCxhcnJheTpzfT1lLG89RChyKSxjPWUuZW5kPz9zLmxlbmd0aDtmb3IobGV0IGE9aTthPGM7YSs9cil7Y29uc3QgaD1zLnNsaWNlKGEsYStyKTtvLnNjYWxlQW5kQWRkKGgsaCx0LG4pO2ZvcihsZXQgZj0wO2Y8cjtmKyspc1thK2ZdPWhbZl19cmV0dXJuIGV9ZnVuY3Rpb24gYzEoZSx0KXtjb25zdHt2ZWN0b3JTaXplOm4sc3RhcnQ6cj0wLGFycmF5Oml9PWUscz1EKG4pLG89ZS5lbmQ/P2kubGVuZ3RoO2ZvcihsZXQgYz1yO2M8bztjKz1uKXtjb25zdCBhPWkuc2xpY2UoYyxjK24pO3MuYWRkKGEsYSx0KTtmb3IobGV0IGg9MDtoPG47aCsrKWlbYytoXT1hW2hdfXJldHVybiBlfWZ1bmN0aW9uIGExKGUsdCl7Y29uc3R7dmVjdG9yU2l6ZTpuLHN0YXJ0OnI9MCxhcnJheTppfT1lLHM9RChuKSxvPWUuZW5kPz9pLmxlbmd0aDtmb3IobGV0IGM9cjtjPG87Yys9bil7Y29uc3QgYT1pLnNsaWNlKGMsYytuKTtzLnN1YnRyYWN0KGEsYSx0KTtmb3IobGV0IGg9MDtoPG47aCsrKWlbYytoXT1hW2hdfXJldHVybiBlfWZ1bmN0aW9uIGwxKGUsdCl7Y29uc3R7dmVjdG9yU2l6ZTpuLHN0YXJ0OnI9MCxhcnJheTppfT1lLHM9RChuKSxvPWUuZW5kPz9pLmxlbmd0aDtmb3IobGV0IGM9cjtjPG87Yys9bil7Y29uc3QgYT1pLnNsaWNlKGMsYytuKTtzLm11bHRpcGx5KGEsYSx0KTtmb3IobGV0IGg9MDtoPG47aCsrKWlbYytoXT1hW2hdfXJldHVybiBlfWZ1bmN0aW9uIGgxKGUsdCl7Y29uc3R7dmVjdG9yU2l6ZTpuLHN0YXJ0OnI9MCxhcnJheTppfT1lLHM9RChuKSxvPWUuZW5kPz9pLmxlbmd0aDtmb3IobGV0IGM9cjtjPG87Yys9bil7Y29uc3QgYT1pLnNsaWNlKGMsYytuKTtzLmRpdmlkZShhLGEsdCk7Zm9yKGxldCBoPTA7aDxuO2grKylpW2MraF09YVtoXX1yZXR1cm4gZX1mdW5jdGlvbiBmMShlLHQsbixyPVtdKXtjb25zdCBpPU1hdGguY2VpbChlLmxlbmd0aC90KTtsZXQgcz0wO2ZvcihsZXQgbz0wO288aTtvKyspe3M9byp0O2NvbnN0IGM9ZS5zbGljZShzLHMrdCk7cltvXT1uKGMpfXJldHVybiByfWZ1bmN0aW9uIHUxKGUsdCxuLHI9W10pe2NvbnN0IGk9TWF0aC5jZWlsKGUubGVuZ3RoL3QpO2xldCBzPTA7Zm9yKGxldCBvPTA7bzxpO28rKyl7cz1vKnQ7Y29uc3QgYz1lLnNsaWNlKHMscyt0KTtuKGMpJiZyLnB1c2goLi4uYyl9cmV0dXJuIHJ9ZnVuY3Rpb24gZGMoZSl7cmV0dXJuIGUuZmxhdE1hcCh0PT5bLi4udF0pfXZhciBnYz0oZT0+KGUucG9zaXRpb249InBvc2l0aW9uIixlLm5vcm1hbD0ibm9ybWFsIixlLmJpbm9ybWFsPSJiaW5vcm1hbCIsZS50YW5nZW50PSJ0YW5nZW50IixlLnV2PSJ1diIsZS5jb2xvcj0iY29sb3IiLGUuaGVpZ2h0PSJoZWlnaHQiLGUpKShnY3x8e30pO2NsYXNzIG1je2NvbnN0cnVjdG9yKHQpe1UodGhpcywiYXJyYXkiKTtVKHRoaXMsImF0dHJpYnV0ZXMiKTtVKHRoaXMsImNvdW50Iik7dCYmdGhpcy5zZXRPcHRpb25zKHQpfXNldE9wdGlvbnModCl7Y29uc3R7YXR0cmlidXRlczpuLGFycmF5OnIsY291bnQ6aSwuLi5zfT10O09iamVjdC5hc3NpZ24odGhpcyxzLHthcnJheTpyLGNvdW50Oml9KTtjb25zdCBvPXRoaXMuYXR0cmlidXRlcz17fTtmb3IoY29uc3RbYyxhXW9mIE9iamVjdC5lbnRyaWVzKG4pKW9bY109bmV3IEh0KHthcnJheTpyLGNvdW50OmksLi4uYX0pO3JldHVybiB0aGlzfXNldFZlY3Rvcih0LG4scixpKXtyZXR1cm4gdGhpcy5hdHRyaWJ1dGVzW3RdLnNldFZlY3RvcihuLHIsaSl9Z2V0VmVjdG9yKHQsbil7cmV0dXJuIHRoaXMuYXR0cmlidXRlc1t0XS5nZXRWZWN0b3Iobil9Z2V0VmVjdG9ycyh0LG4pe3JldHVybiB0Lm1hcChyPT50aGlzLmF0dHJpYnV0ZXNbcl0uZ2V0VmVjdG9yKG4pKX1nZXRBdHRyaWJ1dGUodCl7cmV0dXJuIHRoaXMuYXR0cmlidXRlc1t0XX1zZXRBdHRyaWJ1dGUodCxuKXtjb25zdHthcnJheTpyLGNvdW50Oml9PXRoaXM7cmV0dXJuIHRoaXMuYXR0cmlidXRlc1t0XT1uZXcgSHQoe2FycmF5OnIsLi4ubixjb3VudDppfSl9Z2V0QWdncmVnYXRlVmVjdG9yKHQsbil7Y29uc3Qgcj1bXTtmb3IoY29uc3QgaSBvZiB0KXtjb25zdCBzPXRoaXMuZ2V0VmVjdG9yKGksbik7ci5wdXNoKC4uLnMpfXJldHVybiByfXNldEFnZ3JlZ2F0ZVZlY3Rvcih0LG4scixpKXtpZih0Lmxlbmd0aD09PTEpcmV0dXJuIHRoaXMuc2V0VmVjdG9yKHRbMF0sbixyLGkpO2Zvcihjb25zdCBzIG9mIHQpaT10aGlzLnNldFZlY3RvcihzLG4scixpKTtyZXR1cm4gaX1nZXRBZ2dyZWdhdGVWZWN0b3JTaXplKHQpe2lmKHQubGVuZ3RoPT09MSlyZXR1cm4gdGhpcy5nZXRBdHRyaWJ1dGUodFswXSkudmVjdG9yU2l6ZTtsZXQgbj0wO2Zvcihjb25zdCByIG9mIHQpbis9dGhpcy5nZXRBdHRyaWJ1dGUocikudmVjdG9yU2l6ZTtyZXR1cm4gbn1jcmVhdGVBZ2dyZWdhdGVWZWN0b3JHZXR0ZXIodCl7aWYodC5sZW5ndGg9PT0xKXtjb25zdCBuPXRoaXMuYXR0cmlidXRlc1t0WzBdXTtyZXR1cm4gbi5nZXRWZWN0b3IuYmluZChuKX1yZXR1cm4gdGhpcy5nZXRBZ2dyZWdhdGVWZWN0b3IuYmluZCh0aGlzLHQpfWNyZWF0ZUFnZ3JlZ2F0ZVZlY3RvclNldHRlcih0KXtpZih0Lmxlbmd0aD09PTEpe2NvbnN0IG49dGhpcy5hdHRyaWJ1dGVzW3RbMF1dO3JldHVybiBuLnNldFZlY3Rvci5iaW5kKG4pfXJldHVybiB0aGlzLnNldEFnZ3JlZ2F0ZVZlY3Rvci5iaW5kKHRoaXMsdCl9bWFwKHQsbixyPVtdKXtmb3IobGV0IGk9MDtpPHRoaXMuY291bnQ7aSsrKXtjb25zdCBzPXRoaXMuZ2V0VmVjdG9ycyh0LGkpO3JbaV09bihzLGkpfXJldHVybiByfW1hcEZvckFnZ3JlZ2F0ZSh0LG4scj1bXSl7Zm9yKGxldCBpPTA7aTx0aGlzLmNvdW50O2krKyl7Y29uc3Qgcz10aGlzLmdldEFnZ3JlZ2F0ZVZlY3Rvcih0LGkpO3JbaV09bihzLGkpfXJldHVybiByfW1hcFNlbGYodCxuKXtmb3IobGV0IHI9MDtyPHRoaXMuY291bnQ7cisrKXtjb25zdCBpPXRoaXMuZ2V0VmVjdG9ycyh0LHIpLHM9bihpLHIpO3QuZm9yRWFjaCgobyxjKT0+dGhpcy5zZXRWZWN0b3IobyxyLHNbY10pKX1yZXR1cm4gdGhpc31tYXBTZWxmRm9yQWdncmVnYXRlKHQsbil7Zm9yKGxldCByPTA7cjx0aGlzLmNvdW50O3IrKyl7Y29uc3QgaT10aGlzLmdldEFnZ3JlZ2F0ZVZlY3Rvcih0LHIpLHM9bihpLHIpO3RoaXMuc2V0QWdncmVnYXRlVmVjdG9yKHQscixzKX1yZXR1cm4gdGhpc31maWx0ZXIodCxuLHI9W10pe2ZvcihsZXQgaT0wO2k8dGhpcy5jb3VudDtpKyspe2NvbnN0IHM9dGhpcy5nZXRWZWN0b3JzKHQsaSk7bihzLGkpJiZyLnB1c2gocyl9cmV0dXJuIHJ9ZmlsdGVyRm9yQWdncmVnYXRlKHQsbixyPVtdKXtyZXR1cm4gdGhpcy5maWx0ZXIodCwoaSxzKT0+bihkYyhpKSxzKSxyKX10cmFuc2Zvcm0odCxuKXtjb25zdCByPVJyWzBdO24uaW5jbHVkZXMoIm5vcm1hbCIpJiYodC5sZW5ndGg9PT0xNj9NcihyLHQpOiRyKHIsdCkpO2Zvcihjb25zdCBpIG9mIG4pe2NvbnN0IHM9dGhpcy5nZXRBdHRyaWJ1dGUoaSk7cyYmKGk9PT0ibm9ybWFsIj9zLnRyYW5zZm9ybUFzTm9ybWFsKHIpOnMudHJhbnNmb3JtKHQpKX1yZXR1cm4gdGhpc310cmFuc2Zvcm1Gb3JBZ2dyZWdhdGUodCxuKXtjb25zdCByPXRoaXMuZ2V0QWdncmVnYXRlVmVjdG9yU2l6ZShuKSxpPSRlKHQubGVuZ3RoLHIpO3JldHVybiB0aGlzLm1hcFNlbGZGb3JBZ2dyZWdhdGUobixzPT5pKHMscyx0KSksdGhpc319Y2xhc3MgRm4gZXh0ZW5kcyBtY3tzZXRPcHRpb25zKHQpe2NvbnN0e2luZGljZXM6biwuLi5yfT10O3N1cGVyLnNldE9wdGlvbnMocik7Y29uc3QgaT1uLmFycmF5P246e2FycmF5Om59O3JldHVybiB0aGlzLmluZGljZXM9bmV3IEh0KHtjb3VudDppLmFycmF5Lmxlbmd0aC8zLHZlY3RvclNpemU6MywuLi5pfSksdGhpc31nZXRGYWNlVmVjdG9yKHQsbil7Y29uc3Qgcj10aGlzLmluZGljZXMuZ2V0VmVjdG9yKG4pO3JldHVybiBBcnJheS5wcm90b3R5cGUubWFwLmNhbGwocixpPT50aGlzLmdldFZlY3Rvcih0LGkpKX1nZXRGYWNlVmVjdG9ycyh0LG4pe2NvbnN0IHI9dGhpcy5pbmRpY2VzLmdldFZlY3RvcihuKTtyZXR1cm4gQXJyYXkucHJvdG90eXBlLm1hcC5jYWxsKHIsaT0+dGhpcy5nZXRWZWN0b3JzKHQsaSkpfWdldEZhY2VBZ2dyZWdhdGVWZWN0b3IodCxuKXtjb25zdCByPXRoaXMuaW5kaWNlcy5nZXRWZWN0b3Iobik7cmV0dXJuIEFycmF5LnByb3RvdHlwZS5tYXAuY2FsbChyLGk9PnRoaXMuZ2V0QWdncmVnYXRlVmVjdG9yKHQsaSkpfW1hcEZhY2UodCxuLHI9W10pe3JldHVybiB0aGlzLmluZGljZXMubWFwKChpLHMpPT57Y29uc3Qgbz1BcnJheS5wcm90b3R5cGUubWFwLmNhbGwoaSxjPT50aGlzLmdldFZlY3RvcnModCxjKSk7cmV0dXJuIG4obyxzLGkpfSxyKX1tYXBGYWNlRm9yQWdncmVnYXRlKHQsbixyPVtdKXtyZXR1cm4gdGhpcy5pbmRpY2VzLm1hcCgoaSxzKT0+e2NvbnN0IG89QXJyYXkucHJvdG90eXBlLm1hcC5jYWxsKGksYz0+dGhpcy5nZXRBZ2dyZWdhdGVWZWN0b3IodCxjKSk7cmV0dXJuIG4obyxzLGkpfSxyKX1maWx0ZXJGYWNlKHQsbixyPVtdKXtyZXR1cm4gdGhpcy5pbmRpY2VzLmZpbHRlcigoaSxzKT0+e2NvbnN0IG89QXJyYXkucHJvdG90eXBlLm1hcC5jYWxsKGksYz0+dGhpcy5nZXRWZWN0b3JzKHQsYykpO3JldHVybiBuKG8scyxpKX0scil9ZmlsdGVyRmFjZUZvckFnZ3JlZ2F0ZSh0LG4scj1bXSl7cmV0dXJuIHRoaXMuaW5kaWNlcy5maWx0ZXIoKGkscyk9Pntjb25zdCBvPUFycmF5LnByb3RvdHlwZS5tYXAuY2FsbChpLGM9PnRoaXMuZ2V0QWdncmVnYXRlVmVjdG9yKHQsYykpO3JldHVybiBuKG8scyxpKX0scil9fWxldCBLcj1jbGFzcyBleHRlbmRzIEh0e2NvbnN0cnVjdG9yKHQpe3N1cGVyKHQpLHRoaXMuY291bnQ9Mn1nZXQgc3RhcnRQb2ludCgpe3JldHVybiB0aGlzLmdldFZlY3RvcigwKX1zZXQgc3RhcnRQb2ludCh0KXt0aGlzLnNldFZlY3RvcigwLHQpfWdldCBlbmRQb2ludCgpe3JldHVybiB0aGlzLmdldFZlY3RvcigxKX1zZXQgZW5kUG9pbnQodCl7dGhpcy5zZXRWZWN0b3IoMCx0KX1nZXRDZW50ZXIodCl7cmV0dXJuIHRjKHQsdGhpcy5zdGFydFBvaW50LHRoaXMuZW5kUG9pbnQpLFlyKHQsdCwuNSl9ZGVsdGEodCl7cmV0dXJuIFN0KHQsdGhpcy5lbmRQb2ludCx0aGlzLnN0YXJ0UG9pbnQpfXNxdWFyZWRMZW5ndGgoKXtyZXR1cm4gbmModGhpcy5zdGFydFBvaW50LHRoaXMuZW5kUG9pbnQpfWxlbmd0aCgpe3JldHVybiBlYyh0aGlzLnN0YXJ0UG9pbnQsdGhpcy5lbmRQb2ludCl9YXRUKHQsbil7Y29uc3R7c3RhcnRQb2ludDpyLGVuZFBvaW50Oml9PXRoaXM7cmV0dXJuIFN0KG4saSxyKSxXcihuLHIsbix0KX1jbG9zZXN0UG9pbnRUb1BvaW50UGFyYW1ldGVyKHQsbil7Y29uc3R7c3RhcnRQb2ludDpyLGVuZFBvaW50Oml9PXRoaXMscz1TdChbXSx0LHIpLG89U3QoW10saSxyKSxjPXpuKG8sbyk7bGV0IGg9em4obyxzKS9jO3JldHVybiBuJiYoaD1YdChoLDAsMSkpLGh9Y2xvc2VzdFBvaW50VG9Qb2ludCh0LG4scj1bXSl7Y29uc3QgaT10aGlzLmNsb3Nlc3RQb2ludFRvUG9pbnRQYXJhbWV0ZXIodCxuKTtyZXR1cm4gV3Iocix0aGlzLnN0YXJ0UG9pbnQsdGhpcy5kZWx0YShyKSxpKX19O2NsYXNzIHBjIGV4dGVuZHMgSHR7Z2V0IHN0YXJ0UG9pbnQoKXtyZXR1cm4gdGhpcy5nZXRWZWN0b3IoMCl9c2V0IHN0YXJ0UG9pbnQodCl7dGhpcy5zZXRWZWN0b3IoMCx0KX1nZXQgZW5kUG9pbnQoKXtyZXR1cm4gdGhpcy5nZXRWZWN0b3IoMSl9c2V0IGVuZFBvaW50KHQpe3RoaXMuc2V0VmVjdG9yKDAsdCl9ZGVsdGEodCl7cmV0dXJuIFN0KHQsdGhpcy5lbmRQb2ludCx0aGlzLnN0YXJ0UG9pbnQpfWdldExpbmUodCl7Y29uc3R7YXJyYXk6bixzdGFydDpyLGVuZDppLHZlY3RvclNpemU6c309dGhpcyxvPXIrdCpzO3JldHVybiBuZXcgS3Ioe2FycmF5Om4sc3RhcnQ6byxlbmQ6aSx2ZWN0b3JTaXplOnN9KX1sZW5ndGgoKXtyZXR1cm4gdGhpcy5sZW5ndGhzKCkuYXQoLTEpfWxlbmd0aHMoKXtjb25zdHthcnJheTp0LHN0YXJ0Om4sZW5kOnIsdmVjdG9yU2l6ZTppfT10aGlzLHM9bmV3IEtyKHthcnJheTp0LHN0YXJ0Om4sdmVjdG9yU2l6ZTppfSk7bGV0IG89MDtjb25zdCBjPVswXSxhPXItaTtmb3IobGV0IGg9bjtoPGE7aCs9aSlzLnN0YXJ0PWgsbys9cy5sZW5ndGgoKSxjLnB1c2gobyk7cmV0dXJuIGN9bGVuZ3RoSW5mbygpe2NvbnN0IHQ9dGhpcy5sZW5ndGhzKCksbj10LmF0KC0xKTtyZXR1cm57bGVuZ3Roczp0LGxlbmd0aDpufX19ZnVuY3Rpb24gX2MoZSx0KXtjb25zdCBuPW5ldyBwYyh7YXJyYXk6ZSx2ZWN0b3JTaXplOjN9KSx7bGVuZ3RoOnIsbGVuZ3RoczppfT1uLmxlbmd0aEluZm8oKSxzPXljKHQscik7cmV0dXJue3RpbWVzOmkubWFwKGM9PmMvcipzKSxkdXJhdGlvbjpzLGxlbmd0aHM6aSxsZW5ndGg6cn19ZnVuY3Rpb24gZDEoZSl7Y29uc3QgdD1fYyhlLnBvaW50cyxlKTtyZXR1cm57Li4ueGMoey4uLmUsdGltZXM6dC50aW1lc30pLC4uLnR9fWZ1bmN0aW9uIHljKGUsdCl7bGV0IG49ZS5kdXJhdGlvbjtpZighbil7Y29uc3Qgcj1lLnNwZWVkO2lmKHI9PW51bGwpdGhyb3ci57y65bCR6YCJ6aG5IGR1cmF0aW9uIOaIluiAhSBzcGVlZCI7aWYoIXQpdGhyb3ci57y65bCR5Y+C5pWwIGxlbmd0aCI7bj10L3J9cmV0dXJuIG59ZnVuY3Rpb24geGMoZSl7Y29uc3R7dGFyZ2V0OnQsZnJhbWU6bix0aW1lczpyLGVuYWJsZVVwOmksZml4VXA6cyxpbkZyYW1lOm99PWUsYz1lLnBvc2l0aW9uPz8hMCxhPWUucm90YXRlPz8hMCxoPWUuZGlyZWN0aW9uPz8hMSxmPVtdLHU9W10sZD1bXSxnPXIsbT1bXSxwPXtwb2ludHM6Zixwb2ludFRpbWVzOnUscm90YXRlczpkLHJvdGF0ZVRpbWVzOmcsdGFuZ2VudHM6bSxkaXJlY3Rpb25zOltdfTtpZighKGN8fGEpKXJldHVybiBwO2NvbnN0IHg9bmV3IEh0KHthcnJheTplLnBvaW50cyx2ZWN0b3JTaXplOjN9KSxUPXguY291bnQsTT1ULTEsQT1lLnVwP25ldyBMKGUudXApLm5vcm1hbGl6ZSgpOnVjLmNsb25lKCksdj1uZXcgTDtpZihlLmFuY2hvciYmdi5jb3B5KGUuYW5jaG9yKSxuKXtjb25zdCBCPW5ldyBvdChuKS5pbnZlcnQoKTt4LnRyYW5zZm9ybShCKSxBLnRyYW5zZm9ybUFzVmVjdG9yKEIpLm5vcm1hbGl6ZSgpfWNvbnN0IHc9eC50b1ZlY3RvcnMoKSxQPW5ldyBMKHdbMV0pLnN1YnRyYWN0KHdbMF0pLm5vcm1hbGl6ZSgpO2xldCBiPW5ldyBMO2UuZnJvbnQ/Yi5jb3B5KGUuZnJvbnQpLm5vcm1hbGl6ZSgpOmI9UDtjb25zdCBTPWUudGFyZ2V0VXA/bmV3IEwoZS50YXJnZXRVcCkubm9ybWFsaXplKCk6QS5jbG9uZSgpLE89bmV3IG50LFY9ZmMuY2xvbmUoKSx6PW5ldyB1dDt0JiYoa3IoTyx0KSxvJiZUcihPb1sxXSx0KS50cmFuc2Zvcm1Bc1BvaW50KHYsdiksVm8oeixWLE8pLGEmJm1zKE8sViksb3x8KGUuZnJvbnQmJlF0KGIsYixPKSxlLnRhcmdldFVwJiZRdChTLFMsTykpKTtjb25zdCBOPU8uY2xvbmUoKSxSPWUucGFyYWxsZWw/PyF2LmVxdWFscyhbMCwwLDBdKTtsZXQgZXQ9Qj0+e2NvbnN0IFg9bmV3IEwod1tCKzFdKS5zdWJ0cmFjdCh3W0JdKS5ub3JtYWxpemUoKTttLnB1c2goWCk7Y29uc3QgcnQ9Qi0xLGl0PXJ0PDAsSGU9aXQ/YjptW3J0XSxwdD1uZXcgdXQoKS5yb3RhdGlvblRvKEhlLFgpO2lmKCFpdCl7Y29uc3QgTHQ9ZFtydF07cHQubXVsdGlwbHkoTHQpLm5vcm1hbGl6ZSgpLERyKHB0LEx0KX1yZXR1cm4gcHR9O2lmKGkpe2NvbnN0IEI9bmV3IEw7ZXQ9ZnVuY3Rpb24oWCl7Y29uc3QgcnQ9bmV3IEwod1tYKzFdKS5zdWJ0cmFjdCh3W1hdKS5ub3JtYWxpemUoKTttLnB1c2gocnQpO2NvbnN0IGl0PVgtMSxIZT1pdDwwLHB0PW5ldyB1dCxMdD1bcnQsQV07aWYoSGUpe2NvbnN0IGllPVtiLFNdO3MmJihpZS5yZXZlcnNlKCksTHQucmV2ZXJzZSgpKSxYcih7dGFuZ2VudDppZVswXSxub3JtYWw6aWVbMV19LHt0YW5nZW50Okx0WzBdLG5vcm1hbDpMdFsxXX0scHQpfWVsc2V7Y29uc3QgaWU9ZFtpdF07Y2UoQixTLGllKTtjb25zdCBOaT1bbVtpdF0sQl07cyYmKE5pLnJldmVyc2UoKSxMdC5yZXZlcnNlKCkpLFhyKHt0YW5nZW50Ok5pWzBdLG5vcm1hbDpOaVsxXX0se3RhbmdlbnQ6THRbMF0sbm9ybWFsOkx0WzFdfSxwdCkscHQubXVsdGlwbHkoaWUpLERyKHB0LGllKX1yZXR1cm4gcHQubm9ybWFsaXplKCl9fWZvcihsZXQgQj0wO0I8VDtCKyspe2lmKGEpaWYoQjxNKXtjb25zdCBYPWV0KEIpO2QucHVzaChYKSxObyhPLFgsVil9ZWxzZSBkLnB1c2goZFtCLTFdLmNsb25lKCkpLG0ucHVzaChtW0ItMV0uY2xvbmUoKSk7aWYoYyl7Y29uc3QgWD1yW0JdLHJ0PW5ldyBMKHdbQl0pO2lmKFIpe2NvbnN0IEhlPU4udHJhbnNmb3JtKHYsdi5jbG9uZSgpKSxwdD1ydC5jbG9uZSgpLnN1YnRyYWN0KEhlKTtmLnB1c2gocHQpLHUucHVzaChYKSxOLmNvcHkoTyl9Y29uc3QgaXQ9Ty50cmFuc2Zvcm0odix2LmNsb25lKCkpO3J0LnN1YnRyYWN0KGl0KSxmLnB1c2gocnQpLHUucHVzaChYKX19cmV0dXJuIGgmJihwLmRpcmVjdGlvbnM9ZC5tYXAoQj0+Y2UobmV3IEwoMCwwLDEpLGIsQikpKSxwfWZ1bmN0aW9uIGcxKGUpe2xldCB0O2NvbnN0IG49cj0+e2UociksdD1yZXF1ZXN0QW5pbWF0aW9uRnJhbWUobil9O3JldHVybiB0PXJlcXVlc3RBbmltYXRpb25GcmFtZShuKSwoKT0+e2NhbmNlbEFuaW1hdGlvbkZyYW1lKHQpfX1mdW5jdGlvbiBtMShlLHQpe2NvbnN0W24scl09ZSx7Y2VudGVyOmkscmFkaXVzOnN9PXQsW28sY109Z3Qobi5sZW5ndGgpO28uc3ViVmVjdG9ycyhyLG4pLGMuc3ViVmVjdG9ycyhpLG4pO2NvbnN0IGE9by5sZW5ndGhTcXVhcmVkKCksaD1vLmRvdChjKSoqMixmPWEqKGMubGVuZ3RoU3F1YXJlZCgpLXMqKjIpLHU9aC1mO3JldHVybiBGKHUsMCk/eS5UYW5nZW5jeTp1PDA/eS5EaXNzb2NpYXRpb246eS5JbnRlcnNlY3R9ZnVuY3Rpb24gdWUoZSx0KXtjb25zdFtuLHJdPWUse2NlbnRlcjppLHJhZGl1czpzfT10LFtvLGNdPWd0KG4ubGVuZ3RoKTtvLnN1YlZlY3RvcnMocixuKSxjLnN1YlZlY3RvcnMobixpKTtjb25zdCBhPW8ubGVuZ3RoU3F1YXJlZCgpLGg9MipvLmRvdChjKSxmPWMubGVuZ3RoU3F1YXJlZCgpLXMqKjIsdT1oKioyLTQqYSpmLGQ9Rih1LDApO2lmKCFkJiZ1PDApcmV0dXJuW107Y29uc3QgZz1hKjIsbT0taC9nO2lmKGQpcmV0dXJuW21dO2NvbnN0IHA9TWF0aC5zcXJ0KHUpL2cseD1tLXAsVD1tK3A7cmV0dXJuW3gsVF19ZnVuY3Rpb24gcDEoZSx0KXtjb25zdFtuLHJdPWUsaT1ndChuLmxlbmd0aClbMl07cmV0dXJuIGkuc3ViVmVjdG9ycyhyLG4pLHVlKGUsdCkubWFwKG89PmkuY2xvbmUoKS5tdWx0aXBseUJ5U2NhbGFyKG8pLmFkZChuKSl9ZnVuY3Rpb24gTWMoZSx0KXtjb25zdCBuPXVlKGUsdCkscj1uLmxlbmd0aDtpZihyPT09MClyZXR1cm4geS5EaXNzb2NpYXRpb247bGV0IGk9MCxzPTAsbz0wO2Zvcihjb25zdCBhIG9mIG4pRihhLDApfHxGKGEsMSk/bysrOmE+MT9zKys6YTwwJiZpKys7Y29uc3QgYz1pK3M7cmV0dXJuIHI9PT0xJiZjPT09MD95LlRhbmdlbmN5Omk9PT0xJiZzPT09MXx8bz09PTI/eS5Db250YWluOmk9PT0yfHxzPT09Mj95LkRpc3NvY2lhdGlvbjp5LkludGVyc2VjdH1mdW5jdGlvbiB3YyhlLHQpe2NvbnN0W24scl09ZSxpPWd0KGVbMF0ubGVuZ3RoKVsyXTtpLnN1YlZlY3RvcnMocixuKTtjb25zdCBzPXVlKGUsdCksbz1bXTtmb3IoY29uc3QgYyBvZiBzKXtpZighRihjLDApJiZjPDB8fCFGKGMsMSkmJmM+MSljb250aW51ZTtjb25zdCBhPWkuY2xvbmUoKS5tdWx0aXBseUJ5U2NhbGFyKGMpLmFkZChuKTtvLnB1c2goYSl9cmV0dXJuIG99ZnVuY3Rpb24gXzEoZSx0KXtjb25zdCBuPXVlKGUsdCkscj1uLmxlbmd0aDtpZihyPT09MClyZXR1cm4geS5EaXNzb2NpYXRpb247bGV0IGk9MDtmb3IoY29uc3QgcyBvZiBuKXM8MCYmaSsrO3JldHVybiByPT09MSYmaT09PTA/eS5UYW5nZW5jeTppPT09Mj95LkRpc3NvY2lhdGlvbjp5LkludGVyc2VjdH1mdW5jdGlvbiB5MShlLHQpe2NvbnN0W24scl09ZSxpPWd0KG4ubGVuZ3RoKVsyXTtpLnN1YlZlY3RvcnMocixuKTtjb25zdCBzPXVlKGUsdCksbz1bXTtmb3IoY29uc3QgYyBvZiBzKXtpZihjPDApY29udGludWU7Y29uc3QgYT1pLmNsb25lKCkubXVsdGlwbHlCeVNjYWxhcihjKS5hZGQobik7by5wdXNoKGEpfXJldHVybiBvfWZ1bmN0aW9uIEl0KGUsdCl7Y29uc3Qgbj1RKFtdLGVbMV0sZVswXSkscj1RKFtdLHQsZVswXSk7cmV0dXJuIG9lKG4sbixyKSxGKG5bMl0sMCk/MDpuWzJdfWZ1bmN0aW9uIHgxKGUsdCl7Y29uc3Qgbj1bLi4uZVswXSwuLi5lWzFdLC4uLnRdO2xldCByPUt0KG4pO3JldHVybiBGKHIsMCk/KG5bMl0rPTEsbls1XSs9MSxuWzhdKz0xLHI9S3QobiksRihyLDApPzA6cik6cn1mdW5jdGlvbiBNMShlLHQpe2NvbnN0W24scl09ZSxbaSxzXT1ndCh0Lmxlbmd0aCk7aWYoaS5zdWJWZWN0b3JzKHQsbikscy5zdWJWZWN0b3JzKHIsbiksTm4ocyxpKSl7Y29uc3Qgbz1XKHMsaSk7cmV0dXJuIG88MHx8bz4xP3kuVGFuZ2VuY3k6eS5Db250YWlufXJldHVybiB5LkRpc3NvY2lhdGlvbn1mdW5jdGlvbiBUYyhlLHQpe2NvbnN0W24scl09ZSxbaSxzXT1kdDtpZihpLnN1YlZlY3RvcnModCxuKSxzLnN1YlZlY3RvcnMocixuKSxHbyhzLGkpKXtjb25zdCBvPVcocyxpKTtyZXR1cm4gbzwwfHxvPjE/eS5UYW5nZW5jeTp5LkNvbnRhaW59cmV0dXJuIHkuRGlzc29jaWF0aW9ufWZ1bmN0aW9uIGtuKGUsdCl7Y29uc3RbbixyXT1lLFtpLHNdPXQsW28sYyxhXT1ndChuLmxlbmd0aCk7cmV0dXJuIGMuc3ViVmVjdG9ycyhyLG4pLGEuc3ViVmVjdG9ycyhzLGkpLE5uKGEsYyk/KG8uc3ViVmVjdG9ycyhpLG4pLE5uKG8sYyk/eS5UYW5nZW5jeTp5LkRpc3NvY2lhdGlvbik6eS5JbnRlcnNlY3R9ZnVuY3Rpb24gTmUoZSx0LG4pe2NvbnN0W3IsaV09dCxbcyxvXT1uLFtjLGEsaF09Z3Qoci5sZW5ndGgpO2Muc3ViVmVjdG9ycyhpLHIpLGEuc3ViVmVjdG9ycyhvLHMpO2NvbnN0IGY9RChyLmxlbmd0aCksdT1mLmNyb3NzKFtdLGMsYSk7aWYoRihmLnNxdWFyZWRMZW5ndGgodSksMCkpcmV0dXJuIG51bGw7aC5zdWJWZWN0b3JzKHMscik7Y29uc3QgZD1mLmNyb3NzKFtdLGgsYSksZz1XKHUsZCk7cmV0dXJuIGYuc2NhbGVBbmRBZGQoZSxyLGMsZyl9ZnVuY3Rpb24gQm4oZSx0LG4pe2NvbnN0W3IsaV09dCxbcyxvXT1uLFtjLGEsaF09ZHQ7Yy5zdWJWZWN0b3JzKGksciksYS5zdWJWZWN0b3JzKG8scyk7Y29uc3QgZj1vZShbXSxjLGEpWzJdO2lmKEYoZiwwKSlyZXR1cm4gbnVsbDtoLnN1YlZlY3RvcnMocyxyKTtjb25zdCBkPW9lKFtdLGgsYSlbMl0vZjtyZXR1cm4gR2koZSxyLGMsZCl9ZnVuY3Rpb24gdzEoZSx0KXtjb25zdFtuLHJdPXQsW2ksc109ZSxvPUQobi5sZW5ndGgpLGM9by5zdWJ0cmFjdChbXSxzLGkpLGE9a24oZSx0KTtpZihhPT09eS5UYW5nZW5jeSl7bGV0IGc9MDtyZXR1cm4gVyhjLG8uc3VidHJhY3QoW10sbixpKSk8MCYmZysrLFcoYyxvLnN1YnRyYWN0KFtdLHIsaSkpPDAmJmcrKyxnPT09Mj95LkRpc3NvY2lhdGlvbjpnPT09MD95LkNvbnRhaW46eS5UYW5nZW5jeX1pZihhIT09eS5JbnRlcnNlY3QpcmV0dXJuIGE7Y29uc3QgaD1OZShbXSxlLHQpLGY9by5zdWJ0cmFjdChbXSxyLG4pLHU9VyhmLG8uc3VidHJhY3QoW10saCxuKSk7cmV0dXJuIHU8MHx8dT4xfHxXKGMsby5zdWJ0cmFjdChbXSxoLGkpKTwwP3kuRGlzc29jaWF0aW9uOnkuSW50ZXJzZWN0fWZ1bmN0aW9uIEFjKGUsdCl7Y29uc3RbbixyXT10LFtpLHNdPWUsbz1RKFtdLHMsaSksYz1rbihlLHQpO2lmKGM9PT15LlRhbmdlbmN5KXtsZXQgZD0wO3JldHVybiBXKG8sUShbXSxuLGkpKTwwJiZkKyssVyhvLFEoW10scixpKSk8MCYmZCsrLGQ9PT0yP3kuRGlzc29jaWF0aW9uOmQ9PT0wP3kuQ29udGFpbjp5LlRhbmdlbmN5fWlmKGMhPT15LkludGVyc2VjdClyZXR1cm4gYztjb25zdCBhPUJuKFtdLGUsdCksaD1RKFtdLHIsbiksZj1XKGgsUShbXSxhLG4pKTtyZXR1cm4gZjwwfHxmPjF8fFcobyxRKFtdLGEsaSkpPDA/eS5EaXNzb2NpYXRpb246eS5JbnRlcnNlY3R9ZnVuY3Rpb24gVDEoZSx0LG4pe2NvbnN0IHI9TmUoZSx0LG4pO2lmKHI9PT1udWxsKXJldHVybiBudWxsO2NvbnN0W2ksc109bixvPUQoaS5sZW5ndGgpLGM9by5zdWJ0cmFjdChbXSxzLGkpLGE9VyhjLG8uc3VidHJhY3QoW10scixpKSk7aWYoYTwwfHxhPjEpcmV0dXJuIG51bGw7Y29uc3RbaCxmXT10LHU9by5zdWJ0cmFjdChbXSxmLGgpO3JldHVybiBXKHUsby5zdWJ0cmFjdChbXSxyLGgpKTwwP251bGw6cn1mdW5jdGlvbiBBMShlLHQsbil7Y29uc3Qgcj1CbihlLHQsbik7aWYocj09PW51bGwpcmV0dXJuIG51bGw7Y29uc3RbaSxzXT1uLG89UShbXSxzLGkpLGM9VyhvLFEoW10scixpKSk7aWYoYzwwfHxjPjEpcmV0dXJuIG51bGw7Y29uc3RbYSxoXT10LGY9UShbXSxoLGEpO3JldHVybiBXKGYsUShbXSxyLGEpKTwwP251bGw6cn1mdW5jdGlvbiBIcihlLHQpe2NvbnN0W24scl09ZSxbaSxzXT10LG89RChuLmxlbmd0aCksYz1vLnN1YnRyYWN0KFtdLHIsbiksYT1rbihlLHQpO2lmKGE9PT15LlRhbmdlbmN5KXtsZXQgZz0wLG09MDtjb25zdCBfPVcoYyxvLnN1YnRyYWN0KFtdLGksbikpO188MD9nKys6Xz4xJiZtKys7Y29uc3QgcD1XKGMsby5zdWJ0cmFjdChbXSxzLG4pKTtyZXR1cm4gcDwwP2crKzpwPjEmJm0rKyxnPT09Mnx8bT09PTI/eS5EaXNzb2NpYXRpb246ZyttPT09MT95LlRhbmdlbmN5OnkuQ29udGFpbn1pZihhIT09eS5JbnRlcnNlY3QpcmV0dXJuIGE7Y29uc3QgaD1OZShbXSxlLHQpLGY9by5zdWJ0cmFjdChbXSxzLGkpLHU9VyhmLG8uc3VidHJhY3QoW10saCxpKSk7aWYodTwwfHx1PjEpcmV0dXJuIHkuRGlzc29jaWF0aW9uO2lmKHU9PT0wfHx1PT09MSlyZXR1cm4geS5Kb2ludEludGVyc2VjdDtjb25zdCBkPVcoYyxvLnN1YnRyYWN0KFtdLGgsbikpO3JldHVybiBkPDB8fGQ+MT95LkRpc3NvY2lhdGlvbjpkPT09MHx8ZD09PTE/eS5Kb2ludEludGVyc2VjdDp5LlRocm91Z2hJbnRlcnNlY3R9ZnVuY3Rpb24gTzEoZSx0LG4pe2NvbnN0IHI9TmUoZSx0LG4pO2lmKHI9PT1udWxsKXJldHVybiBudWxsO2NvbnN0W2ksc109bixvPUQoaS5sZW5ndGgpLGM9by5zdWJ0cmFjdChbXSxzLGkpLGE9VyhjLG8uc3VidHJhY3QoW10scixpKSk7aWYoYTwwfHxhPjEpcmV0dXJuIG51bGw7Y29uc3RbaCxmXT10LHU9by5zdWJ0cmFjdChbXSxmLGgpLGQ9Vyh1LG8uc3VidHJhY3QoW10scixoKSk7cmV0dXJuIGQ8MHx8ZD4xP251bGw6cn1mdW5jdGlvbiB2MShlLHQsbil7Y29uc3Qgcj1CbihlLHQsbik7aWYocj09PW51bGwpcmV0dXJuIG51bGw7Y29uc3RbaSxzXT1uLG89UShbXSxzLGkpLGM9VyhvLFEoW10scixpKSk7aWYoYzwwfHxjPjEpcmV0dXJuIG51bGw7Y29uc3RbYSxoXT10LGY9UShbXSxoLGEpLHU9VyhmLFEoW10scixhKSk7cmV0dXJuIHU8MHx8dT4xP251bGw6cn1mdW5jdGlvbiBFMShlKXtjb25zdCB0PVtdO2ZvcihsZXQgcj0wO3I8ZS5sZW5ndGg7cisrKXtjb25zdCBpPWVbcl07dC5wdXNoKFtpWzBdLCEwLHJdLFtpWzFdLCExLHJdKX1sZXQgbj0hMTt0LnNvcnQoKHIsaSk9PntsZXQgcz1yWzBdLWlbMF07cmV0dXJuIHMhPT0wfHwocz1yWzJdLWlbMl0scyE9PTAmJihuPSEwKSksc30pO2ZvcihsZXQgcj0wO3I8dC5sZW5ndGg7cis9Mil7Y29uc3QgaT10W3JdLHM9dFtyKzFdO2lmKGlbMV09PT1zWzFdKXJldHVybiB5LlRocm91Z2hJbnRlcnNlY3R9cmV0dXJuIG4/eS5Kb2ludEludGVyc2VjdDp5LkRpc3NvY2lhdGlvbn1mdW5jdGlvbiBPYyhlKXtjb25zdCB0PWUubGVuZ3RoO2lmKHQ8MylyZXR1cm4gZTtsZXQgbj1lWzBdWzFdLHI9WzBdO2ZvcihsZXQgbz0xO288dDtvKyspe2NvbnN0IGM9ZVtvXVsxXTtjPG4/KG49YyxyPVtvXSk6Yz09PW4mJnIucHVzaChvKX1sZXQgaT1yWzBdO2lmKHIubGVuZ3RoPjEpe249ZVtyWzBdXVswXTtmb3IobGV0IG89MTtvPHIubGVuZ3RoO28rKyl7Y29uc3QgYz1yW29dLGE9ZVtjXVswXTthPG4mJihuPWEsaT1jKX19Y29uc3Qgcz1lLnNwbGljZShpLDEpWzBdO3JldHVybiBlLnNvcnQoKG8sYyk9Pkl0KFtzLGNdLG8pKSxlLnVuc2hpZnQocyksZX1mdW5jdGlvbiB2YyhlKXtjb25zdCB0PWUuc2xpY2UoMCwyKTt0OmZvcihsZXQgbj0yO248ZS5sZW5ndGg7bisrKXtsZXQgcj10LmF0KC0yKSxpPXQuYXQoLTEpO2NvbnN0IHM9ZVtuXTtsZXQgbz1JdChbcixpXSxzKTtmb3IoO288PTA7KXtpZihvPT09MCl7c24ocixzKT5zbihyLGkpJiYodFt0Lmxlbmd0aC0xXT1zKTtjb250aW51ZSB0fXQucG9wKCksaT1yLHI9dC5hdCgtMiksbz1JdChbcixpXSxzKX10LnB1c2gocyl9cmV0dXJuIHR9ZnVuY3Rpb24gYjEoZSl7cmV0dXJuIHZjKE9jKGUpKX1mdW5jdGlvbiBFYyhlKXtjb25zdCB0PWUubGVuZ3RoO2lmKHQ8NClyZXR1cm4hMDtsZXQgbj0wO2ZvcihsZXQgcj0wO3I8dDtyKyspe2NvbnN0IGk9ZS5hdChyLTEpLHM9ZS5hdCgocisxKSV0KSxvPUl0KFtpLGVbcl1dLHMpO2lmKG8hPT0wKXtpZihuKm88MClyZXR1cm4hMTtuPW99fXJldHVybiEwfWZ1bmN0aW9uIFMxKGUpe2NvbnN0IHQ9ZS5sZW5ndGg7aWYodDw0KXJldHVybi0xO2xldCBuPTA7Zm9yKGxldCByPTA7cjx0O3IrKyl7Y29uc3QgaT1lLmF0KHItMSkscz1lLmF0KChyKzEpJXQpLG89SXQoW2ksZVtyXV0scyk7aWYobyE9PTApe2lmKG4qbzwwKXJldHVybiByO249b319cmV0dXJuLTF9ZnVuY3Rpb24gUHQoZSx0KXtsZXQgbj0wLHI9ITE7Zm9yKGxldCBpPTA7aTxlLmxlbmd0aDtpKyspe2NvbnN0IHM9ZS5hdChpLTEpO2lmKG9uKHMsdCkpcmV0dXJuIHkuVGFuZ2VuY3k7Y29uc3Qgbz1JdChbcyxlW2ldXSx0KTtpZihvPT09MCl7cj0hMDtjb250aW51ZX1pZihuKm88MClyZXR1cm4geS5EaXNzb2NpYXRpb247bj1vfXJldHVybiByP3kuVGFuZ2VuY3k6eS5Db250YWlufWZ1bmN0aW9uIEkxKGUsdCl7Y29uc3Qgbj1lLmxlbmd0aDtsZXQgcj1bXTtjb25zdCBpPVtdO2ZvcihsZXQgcz0wO3M8bjtzKyspe2NvbnN0IG89cy0xLGM9ZS5hdChvKTtpZihvbihjLHQpKXtpLnB1c2gobyk7YnJlYWt9Y29uc3QgYT1vLTEsaD1JdChbdCxjXSxlLmF0KGEpKSxmPUl0KFt0LGNdLGUuYXQocykpLHU9aCpmO2lmKCEodTwwKSl7aWYodT4wKXtpZihpLnB1c2gobyksaS5sZW5ndGg9PT0yKWJyZWFrO2NvbnRpbnVlfWg9PT0wJiZyLnB1c2goYSxvKSxmPT09MCYmci5wdXNoKG8scyl9fXJldHVybiBpLnB1c2goLi4uciksaS5tYXAocz0+czwwP3MrbjpzKX1mdW5jdGlvbiBNdChlLHQpe2NvbnN0IG49W3QsWzEwLDBdXTtXaShuWzFdLHQsblsxXSk7Y29uc3Qgcj1lLmxlbmd0aDtsZXQgaT0wO2ZvcihsZXQgcz0wO3M8cjtzKyspe2NvbnN0IG89ZVtzXTtpZihvbihvLHQpKXJldHVybiB5LlRhbmdlbmN5O2xldCBjPXMrMTtjPT09ciYmKGM9MCk7Y29uc3QgYT1lW2NdLGg9W28sYV07aWYoVGMoaCx0KT09PXkuQ29udGFpbilyZXR1cm4geS5UYW5nZW5jeTtjb25zdCB1PUFjKG4saCk7aWYodT09PXkuQ29udGFpbil7aSs9Mjtjb250aW51ZX1pZih1PT09eS5JbnRlcnNlY3Qpe2xldCBkPTA7b1sxXT50WzFdJiZkKyssYVsxXT50WzFdJiZkKyssZD09PTEmJmkrK319cmV0dXJuIGklMj09PTA/eS5EaXNzb2NpYXRpb246eS5Db250YWlufWZ1bmN0aW9uIEpyKGUsdCl7Y29uc3Qgbj1lLmxlbmd0aDtsZXQgcj0wO2ZvcihsZXQgYz0wO2M8bjtjKyspe2NvbnN0IGE9ZVtjXTtsZXQgaD1jKzE7aD09PW4mJihoPTApO2NvbnN0IGY9ZVtoXSxkPUhyKFthLGZdLHQpO2lmKGQmKHkuVGhyb3VnaEludGVyc2VjdHx5LlRhbmdlbmN5fHkuQ29udGFpbikpcmV0dXJuIGQ7ZD09PXkuSm9pbnRJbnRlcnNlY3QmJnIrK31jb25zdCBpPVB0KGUsdFswXSk7aWYocj09PTB8fHI9PT0xJiZpIT09eS5UYW5nZW5jeSlyZXR1cm4gaTtjb25zdCBzPVB0KGUsdFsxXSksbz1pfHM7cmV0dXJuIG89PT15LlRhbmdlbmN5P3kuQ29udGFpbjpvJnkuVGFuZ2VuY3k/byZ5LkNvbnRhaW4/eS5Db250YWluOnkuSm9pbnRJbnRlcnNlY3Q6aX1mdW5jdGlvbiBiYyhlLHQpe2NvbnN0IG49ZS5sZW5ndGg7bGV0IHI9MCxpPSExO2ZvcihsZXQgYT0wO2E8bjthKyspe2NvbnN0IGg9ZVthXTtsZXQgZj1hKzE7Zj09PW4mJihmPTApO2NvbnN0IHU9ZVtmXSxnPUhyKFtoLHVdLHQpO2lmKGc9PT15LlRocm91Z2hJbnRlcnNlY3QpcmV0dXJuIGc7Zz09PXkuSm9pbnRJbnRlcnNlY3Q/cisrOmc9PT15LkNvbnRhaW4mJihpPSEwKX1jb25zdCBzPU10KGUsdFswXSksbz1NdChlLHRbMV0pLGM9c3xvO2lmKGkpcmV0dXJuIGMmeS5Db250YWluP3kuVGhyb3VnaEludGVyc2VjdDp5LlRhbmdlbmN5O2lmKHI9PT0xKXJldHVybiBjJnkuQ29udGFpbj95LkNvbnRhaW46eS5Kb2ludEludGVyc2VjdDtpZihyPjIpe2NvbnN0IGE9SGkoW10sdFswXSx0WzFdLC41KTtyZXR1cm4gTXQoZSxhKT09PXkuQ29udGFpbj95LkNvbnRhaW46eS5Kb2ludEludGVyc2VjdH1yZXR1cm4gc31mdW5jdGlvbiBQMShlLHQpe2NvbnN0IG49ZS5sZW5ndGg7bGV0IHI9MCxpPTA7Zm9yKGxldCBhPTA7YTxuO2ErKyl7Y29uc3QgaD1lW2FdO2xldCBmPWErMTtmPT09biYmKGY9MCk7Y29uc3QgdT1lW2ZdLGc9TWMoW2gsdV0sdCk7aWYoZz09PXkuSW50ZXJzZWN0KXJldHVybiB5LkludGVyc2VjdDtnPT09eS5Db250YWluP3IrKzpnPT09eS5UYW5nZW5jeSYmaSsrfWlmKHI9PT1uKXJldHVybiB5LkJBQ29udGFpbjtpZihyPjApcmV0dXJuIHkuSW50ZXJzZWN0O2NvbnN0e2NlbnRlcjpzLHJhZGl1czpvfT10O2xldCBjPU10KGUscyk7cmV0dXJuIGM9PT15LkNvbnRhaW4/eS5BQkNvbnRhaW46bz09PTA/YzppPjA/eS5UYW5nZW5jeTp5LkRpc3NvY2lhdGlvbn1mdW5jdGlvbiBMMShlLHQpe2NvbnN0IG49ZS5sZW5ndGg7bGV0IHI9W107Zm9yKGxldCBpPTA7aTxuO2krKyl7Y29uc3Qgcz1lW2ldO2xldCBvPWkrMTtvPT09biYmKG89MCk7Y29uc3QgYz1lW29dLGg9d2MoW3MsY10sdCk7cj1bLi4uciwuLi5oXX1yZXR1cm4gcn1mdW5jdGlvbiBTYyhlLHQpe2NvbnN0IG49ZS5sZW5ndGg7bGV0IHI9MCxpPSExO2ZvcihsZXQgYT0wO2E8bjthKyspe2NvbnN0IGg9ZVthXTtsZXQgZj1hKzE7Zj09PW4mJihmPTApO2NvbnN0IHU9ZVtmXSxnPUpyKHQsW2gsdV0pO2lmKGc9PT15LlRocm91Z2hJbnRlcnNlY3QpcmV0dXJuIGc7Zz09PXkuSm9pbnRJbnRlcnNlY3Q/cisrOmc9PT15LlRhbmdlbmN5JiYoaT0hMCl9bGV0IHM9MDtpP3N8PXkuVGFuZ2VuY3k6ciYmKHN8PXkuSm9pbnRJbnRlcnNlY3QpO2xldCBvPWUuc29tZShhPT5QdCh0LGEpPT09eS5Db250YWluKTtyZXR1cm4gbz95LkJBQ29udGFpbnxzOihvPXQuc29tZShhPT5NdChlLGEpPT09eS5Db250YWluKSxvP3kuQUJDb250YWlufHM6ZS5zb21lKGE9PlB0KHQsYSk9PT15LkRpc3NvY2lhdGlvbik/eS5EaXNzb2NpYXRpb258czpzKX1mdW5jdGlvbiBJYyhlLHQpe2NvbnN0IG49ZS5sZW5ndGg7bGV0IHI9MCxpPSExO2ZvcihsZXQgYT0wO2E8bjthKyspe2NvbnN0IGg9ZVthXTtsZXQgZj1hKzE7Zj09PW4mJihmPTApO2NvbnN0IHU9ZVtmXSxnPUpyKHQsW2gsdV0pO2lmKGc9PT15LlRocm91Z2hJbnRlcnNlY3QpcmV0dXJuIGc7Zz09PXkuSm9pbnRJbnRlcnNlY3Q/cisrOmc9PT15LlRhbmdlbmN5JiYoaT0hMCl9bGV0IHM9MDtpP3N8PXkuVGFuZ2VuY3k6ciYmKHN8PXkuSm9pbnRJbnRlcnNlY3QpO2xldCBvPWUuc29tZShhPT5QdCh0LGEpPT09eS5Db250YWluKTtyZXR1cm4gbz95LkJBQ29udGFpbnxzOihvPXQuc29tZShhPT5QdChlLGEpPT09eS5Db250YWluKSxvP3kuQUJDb250YWlufHM6ZS5zb21lKGE9PlB0KHQsYSk9PT15LkRpc3NvY2lhdGlvbik/eS5EaXNzb2NpYXRpb258czpzKX1mdW5jdGlvbiBSMShlLHQpe2NvbnN0IG49ZS5sZW5ndGg7bGV0IHI9MCxpPSExO2ZvcihsZXQgYT0wO2E8bjthKyspe2NvbnN0IGg9ZVthXTtsZXQgZj1hKzE7Zj09PW4mJihmPTApO2NvbnN0IHU9ZVtmXSxnPWJjKHQsW2gsdV0pO2lmKGc9PT15LlRocm91Z2hJbnRlcnNlY3QpcmV0dXJuIGc7Zz09PXkuSm9pbnRJbnRlcnNlY3Q/cisrOmc9PT15LlRhbmdlbmN5JiYoaT0hMCl9bGV0IHM9MDtpP3N8PXkuVGFuZ2VuY3k6ciYmKHN8PXkuSm9pbnRJbnRlcnNlY3QpO2xldCBvPWUuc29tZShhPT5NdCh0LGEpPT09eS5Db250YWluKTtyZXR1cm4gbz95LkJBQ29udGFpbnxzOihvPXQuc29tZShhPT5NdChlLGEpPT09eS5Db250YWluKSxvP3kuQUJDb250YWlufHM6ZS5zb21lKGE9Pk10KHQsYSk9PT15LkRpc3NvY2lhdGlvbik/eS5EaXNzb2NpYXRpb258czpzKX1mdW5jdGlvbiAkMShlLHQsbil7Zm9yKGxldCByPTA7cjxuLmxlbmd0aDtyKyspe2NvbnN0IGk9bltyXTtlPXRpKGUsdCxyLGkpLGU9dGkoZSx0LHIsLWkpfXJldHVybiBlfWZ1bmN0aW9uIHRpKGUsdCxuLHIsaSl7Y29uc3Qgcz1lLmxlbmd0aDtpZighaSl7aT1bXTtmb3IobGV0IGE9MDthPHM7YSsrKWlbYV09W119Y29uc3Qgbz1lWzBdLmxlbmd0aC90LGM9ZS5tYXAoYT0+YS5sZW5ndGgvb3wwKTtmb3IobGV0IGE9MDthPG87YSs9Myl7Y29uc3QgaD1bXSxmPVtdLHU9W107Zm9yKGxldCB3PTA7dzxzO3crKyl7Y29uc3QgUD1lW3ddLGI9Y1t3XTtsZXQgUz1hKmIsTz1TK2I7aFt3XT1QLnNsaWNlKFMsTyksUz1PLE8rPWIsZlt3XT1QLnNsaWNlKFMsTyksUz1PLE8rPWIsdVt3XT1QLnNsaWNlKFMsTyl9Y29uc3QgZD1oWzBdW25dLXIsZz1mWzBdW25dLXIsbT11WzBdW25dLXI7bGV0IF89ZD4wLHA9Zz4wLHg9bT4wO3I8MCYmKF89IV8scD0hcCx4PSF4KTtsZXQgVCxNLEEsdjtzd2l0Y2goXytwK3gpe2Nhc2UgMDp7Zm9yKGxldCB3PTA7dzxzO3crKylpW3ddLnB1c2goLi4uaFt3XSwuLi5mW3ddLC4uLnVbd10pO2JyZWFrfWNhc2UgMTp7Xz8oVD1mLE09dSxBPWh0KHUsaCxuLHIpLHY9aHQoZixoLG4scikpOnA/KFQ9dSxNPWgsQT1odChoLGYsbixyKSx2PWh0KHUsZixuLHIpKTooVD1oLE09ZixBPWh0KGYsdSxuLHIpLHY9aHQoaCx1LG4scikpO2ZvcihsZXQgdz0wO3c8czt3KyspaVt3XS5wdXNoKC4uLlRbd10sLi4uTVt3XSwuLi5BW3ddKSxpW3ddLnB1c2goLi4uQVt3XSwuLi52W3ddLC4uLlRbd10pO2JyZWFrfWNhc2UgMjp7Xz9wPyhUPXUsTT1odChoLHUsbixyKSxBPWh0KGYsdSxuLHIpKTooVD1mLE09aHQodSxmLG4sciksQT1odChoLGYsbixyKSk6KFQ9aCxNPWh0KGYsaCxuLHIpLEE9aHQodSxoLG4scikpO2ZvcihsZXQgdz0wO3c8czt3KyspaVt3XS5wdXNoKC4uLlRbd10sLi4uTVt3XSwuLi5BW3ddKTticmVha319fXJldHVybiBpfWZ1bmN0aW9uIGh0KGUsdCxuLHIsaT1bXSl7Y29uc3Qgcz1lWzBdLG89dFswXSxjPXNbbl0sYT1NYXRoLmFicygoci1jKS8ob1tuXS1jKSk7Zm9yKGxldCBoPTA7aDxlLmxlbmd0aDtoKyspe2NvbnN0IGY9ZVtoXSx1PXRbaF0sZD1pW2hdfHwoaVtoXT1bXSk7Zm9yKGxldCBnPTA7ZzxmLmxlbmd0aDtnKyspZFtnXT1hKih1W2ddLWZbZ10pK2ZbZ119cmV0dXJuIGl9ZnVuY3Rpb24gQzEoZSx0KXtjb25zdCBuPWUubGVuZ3RoL3R8MDtmb3IobGV0IHI9MDtyPHQ7cisrKXtjb25zdCBpPXIqbixzPWUuc2xpY2UoaSxpK24pO2xldCBvPU1hdGguaHlwb3QoLi4ucyk7bz1GKG8sMCk/MToxL287Zm9yKGxldCBjPTA7YzxuO2MrKyllW2krY10qPW99cmV0dXJuIGV9ZnVuY3Rpb24gUGMoZSx0LG49WyJwb3NpdGlvbiJdKXtyZXR1cm4gZS5tYXBGb3JBZ2dyZWdhdGUobixyPT5NdCh0LHIpKX1mdW5jdGlvbiBMYyhlLHQsbj1bInBvc2l0aW9uIl0pe3JldHVybiBlLm1hcEZvckFnZ3JlZ2F0ZShuLHI9PlB0KHQscikpfWZ1bmN0aW9uIFYxKGUsdCl7cmV0dXJuIGUuaW5kaWNlcy5tYXAobj0+e2xldCByPTA7Zm9yKGNvbnN0IGkgb2YgbilyfD10W2ldO3JldHVybiByfSl9ZnVuY3Rpb24gUmMoZSx0LG49WyJwb3NpdGlvbiJdLHIsaSl7Y29uc3Qgcz1pP0ljOlNjO3JldHVybiByP3IubWFwKGZ1bmN0aW9uKG8sYyl7Y29uc3QgYT1DYyhvKTtpZihhIT09bnVsbClyZXR1cm4gYSZ5LkNvbnRhaW4/YXx5LkFCOmE7Y29uc3QgaD1lLmluZGljZXMuZ2V0VmVjdG9yKGMpLGY9QXJyYXkucHJvdG90eXBlLm1hcC5jYWxsKGgsdT0+ZS5nZXRBZ2dyZWdhdGVWZWN0b3Iobix1KSk7cmV0dXJuIHModCxmKX0pOmUubWFwRmFjZShuLG89PnModCxvKSl9Y29uc3QgJGM9eS5EaXNzb2NpYXRpb258eS5Db250YWluO2Z1bmN0aW9uIENjKGUpe3JldHVybihlJiRjKT09PSRjP3kuVGhyb3VnaEludGVyc2VjdDplJnkuQ29udGFpbj9lJnkuVGFuZ2VuY3k/eS5Db250YWlufHkuSm9pbnRJbnRlcnNlY3Q6eS5Db250YWluOm51bGx9ZnVuY3Rpb24gVmMoZSx0LG4pe2NvbnN0IHI9RWUuZ2V0RXF1YWxGdW4obiksaT1bXTtyZXR1cm4gZS5mb3JFYWNoKChzLG8pPT57cih0LHMpJiZpLnB1c2gobyl9KSxpfWNvbnN0IGVpPTEvMzI3Njc7ZnVuY3Rpb24gbmkoZSx0KXtjb25zdFtuLHIsaV09cmkoZSx0KTtyZXR1cm5bbiwwLDAsMCwwLHIsMCwwLDAsMCxpLDAsZS53ZXN0LGUuc291dGgsdFswXSwxXX1mdW5jdGlvbiByaShlLHQpe2NvbnN0IG49KGUuZWFzdC1lLndlc3QpKmVpLHI9KGUubm9ydGgtZS5zb3V0aCkqZWksaT0odFsxXS10WzFdKSplaTtyZXR1cm5bbixyLGldfWZ1bmN0aW9uIE4xKGUsdCl7Y29uc3Qgbj1yaShlLHQpLHt3ZXN0OnIsc291dGg6aX09ZSxbc109dDtyZXR1cm4gZnVuY3Rpb24oYyxhPVtdKXtkcihhLGMsbiksbnMoYSxhLFtyLGksc10pfX1mdW5jdGlvbiB6MShlKXtyZXR1cm4gTmMoZSkvMn1mdW5jdGlvbiBOYyhlKXtsZXQgdD0wO2ZvcihsZXQgbj0wO248ZS5sZW5ndGg7bisrKXtjb25zdCByPWUuYXQobi0xKTt0Kz1oZShyLGVbbl0pfXJldHVybiB0fWZ1bmN0aW9uIHExKGUpe3JldHVybiB6YyhlKS8yfWZ1bmN0aW9uIHpjKGUpe2NvbnN0IHQ9ZVswXSxuPVtdO2ZvcihsZXQgcz0xO3M8ZS5sZW5ndGg7cysrKXtjb25zdCBvPWVbc10sYz11cihbXSxvLHQpO24ucHVzaChjKX1jb25zdCByPXN0KFtdLG5bMV0sblswXSk7bGV0IGk9Y24ocik7aXMocixyLDEvaSk7Zm9yKGxldCBzPTI7czxuLmxlbmd0aDtzKyspaSs9VXIobltzLTFdLG5bc10scik7cmV0dXJuIGl9ZnVuY3Rpb24gRjEoZSx0LG4pe3JldHVybiBxYyhlLHQsbikvMn1mdW5jdGlvbiBxYyhlLHQsbil7cmV0dXJuIGR0WzBdLnN1YlZlY3RvcnModCxlKSxkdFsyXS5zdWJWZWN0b3JzKG4sZSksaGUoZHRbMF0sZHRbMV0pfWZ1bmN0aW9uIGsxKGUsdCxuKXtyZXR1cm4gRmMoZSx0LG4pLzJ9ZnVuY3Rpb24gRmMoZSx0LG4pe3JldHVybiBjdFswXS5zdWJWZWN0b3JzKHQsZSksY3RbMl0uc3ViVmVjdG9ycyhuLGUpLGhlKGR0WzBdLGR0WzFdKX1mdW5jdGlvbiBCMShlLHQsbil7cmV0dXJuIGtjKGUsdCxuKS8yfWZ1bmN0aW9uIGtjKGUsdCxuKXtjb25zdFtyLGldPWd0KGUubGVuZ3RoKTtyZXR1cm4gci5zdWJWZWN0b3JzKHQsZSksaS5zdWJWZWN0b3JzKG4sZSksSG8ocixpKX1mdW5jdGlvbiBVMShlLHQsbil7cmV0dXJuIGlpKGUsdCxuKS8yfWZ1bmN0aW9uIGlpKGUsdCxuKXtjb25zdFtyLGldPWd0KGUubGVuZ3RoKTtyZXR1cm4gci5zdWJWZWN0b3JzKHQsZSksaS5zdWJWZWN0b3JzKG4sZSksam8ocixpKX1mdW5jdGlvbiBEMShlLHQsbil7cmV0dXJuIEJjKGUsdCxuKS8yfWZ1bmN0aW9uIEJjKGUsdCxuKXtjb25zdFtyLGldPWN0O3JldHVybiByLnN1YlZlY3RvcnModCxlKSxpLnN1YlZlY3RvcnMobixlKSxRbyhyLGkpfWZ1bmN0aW9uIFkxKGUsdCxuKXtyZXR1cm4gc2koZSx0LG4pLzJ9ZnVuY3Rpb24gc2koZSx0LG4pe2NvbnN0W3IsaV09ZHQ7cmV0dXJuIHIuc3ViVmVjdG9ycyh0LGUpLGkuc3ViVmVjdG9ycyhuLGUpLEtvKHIsaSl9ZnVuY3Rpb24gb2koZSx0KXtjb25zdCBuPWUubGVuZ3RoLTM7bGV0IHI9MDtmb3IobGV0IGk9MDtpPG47aSs9Myl7Y29uc3RbcyxvLGNdPWUuc2xpY2UoaSxpKzMpLGE9dChzKSxoPXQobyksZj10KGMpO3IrPWlpKGEsaCxmKX1yZXR1cm4gci8yfWZ1bmN0aW9uIGNpKGUsdCxuPVswLDEvMF0pe2NvbnN0IHI9ZS5sZW5ndGgtMyxbaSxzXT1uLG89cy1pO2xldCBjPTA7Y29uc3QgYT0xLzM7Zm9yKGxldCBoPTA7aDxyO2grPTMpe2NvbnN0W2YsdSxkXT1lLnNsaWNlKGgsaCszKSxbZyxtLF9dPXQoZiksW3AseCxUXT10KHUpLFtNLEEsdl09dChkKSx3PXNpKFtnLG1dLFtwLHhdLFtNLEFdKSxQPShfK1QrdikqYS1pO2MrPXcqTWF0aC5taW4oUCxvKX1yZXR1cm4gYy8yfWNvbnN0IFVjPSEwLFcxPSExLHplPXtDQ1c6LTEsQ1c6MSxOT1RfT1JJRU5UQUJMRTowfSxaMT0yKk1hdGguUEksVW49MSxEYz0wLHd0PTIsWDE9MyxHMT00LGoxPTEsUTE9MixhaT0wLHFlPTEsZGU9Mjt2YXIgRG49T2JqZWN0LmZyZWV6ZSh7X19wcm90b19fOm51bGwsQk9VTkRBUlk6d3QsQ0NXOlVjLENPTlRBSU5TOlgxLENXOlcxLEVORF9WRVJURVg6ZGUsSU5TSURFOlVuLElOVEVSTEFDRTpHMSxOT1RfVkVSVEVYOmFpLE9SSUVOVEFUSU9OOnplLE9VVFNJREU6RGMsT1ZFUkxBUF9PUFBPU0lURTpRMSxPVkVSTEFQX1NBTUU6ajEsUEl4MjpaMSxTVEFSVF9WRVJURVg6cWV9KTtsZXQgVHQ9MWUtNjtmdW5jdGlvbiBZYyhlKXtUdD1lfWZ1bmN0aW9uIFdjKCl7cmV0dXJuIFR0fWNvbnN0IEsxPTM7ZnVuY3Rpb24gbGkoZSl7cmV0dXJuIGU8VHQmJmU+LVR0fWZ1bmN0aW9uIEp0KGUsdCl7cmV0dXJuIGUtdDxUdCYmZS10Pi1UdH1mdW5jdGlvbiBaYyhlLHQpe3JldHVybiBlLXQ+VHR9ZnVuY3Rpb24gSDEoZSx0KXtyZXR1cm4gZS10Pi1UdH1mdW5jdGlvbiBYYyhlLHQpe3JldHVybiBlLXQ8LVR0fWZ1bmN0aW9uIEoxKGUsdCl7cmV0dXJuIGUtdDxUdH12YXIgdGQ9T2JqZWN0LmZyZWV6ZSh7X19wcm90b19fOm51bGwsREVDSU1BTFM6SzEsRVE6SnQsRVFfMDpsaSxHRTpIMSxHVDpaYyxMRTpKMSxMVDpYYyxnZXRUb2xlcmFuY2U6V2Msc2V0VG9sZXJhbmNlOlljfSk7bGV0IGw9e1V0aWxzOnRkLEVycm9yczp2b2lkIDAsTWF0cml4OnZvaWQgMCxQbGFuYXJfc2V0OnZvaWQgMCxQb2ludDp2b2lkIDAsVmVjdG9yOnZvaWQgMCxMaW5lOnZvaWQgMCxDaXJjbGU6dm9pZCAwLFNlZ21lbnQ6dm9pZCAwLEFyYzp2b2lkIDAsQm94OnZvaWQgMCxFZGdlOnZvaWQgMCxGYWNlOnZvaWQgMCxSYXk6dm9pZCAwLFJheV9zaG9vdGluZzp2b2lkIDAsTXVsdGlsaW5lOnZvaWQgMCxQb2x5Z29uOnZvaWQgMCxEaXN0YW5jZTp2b2lkIDAsSW52ZXJzaW9uOnZvaWQgMH07Zm9yKGxldCBlIGluIERuKWxbZV09RG5bZV07T2JqZWN0LmRlZmluZVByb3BlcnR5KGwsIkRQX1RPTCIse2dldDpmdW5jdGlvbigpe3JldHVybiBXYygpfSxzZXQ6ZnVuY3Rpb24oZSl7WWMoZSl9fSk7Y2xhc3MgWXtzdGF0aWMgZ2V0IElMTEVHQUxfUEFSQU1FVEVSUygpe3JldHVybiBuZXcgUmVmZXJlbmNlRXJyb3IoIklsbGVnYWwgUGFyYW1ldGVycyIpfXN0YXRpYyBnZXQgWkVST19ESVZJU0lPTigpe3JldHVybiBuZXcgRXJyb3IoIlplcm8gZGl2aXNpb24iKX1zdGF0aWMgZ2V0IFVOUkVTT0xWRURfQk9VTkRBUllfQ09ORkxJQ1QoKXtyZXR1cm4gbmV3IEVycm9yKCJVbnJlc29sdmVkIGJvdW5kYXJ5IGNvbmZsaWN0IGluIGJvb2xlYW4gb3BlcmF0aW9uIil9c3RhdGljIGdldCBJTkZJTklURV9MT09QKCl7cmV0dXJuIG5ldyBFcnJvcigiSW5maW5pdGUgbG9vcCIpfXN0YXRpYyBnZXQgQ0FOTk9UX0NPTVBMRVRFX0JPT0xFQU5fT1BFUkFUSU9OKCl7cmV0dXJuIG5ldyBFcnJvcigiQ2Fubm90IGNvbXBsZXRlIGJvb2xlYW4gb3BlcmF0aW9uIil9c3RhdGljIGdldCBDQU5OT1RfSU5WT0tFX0FCU1RSQUNUX01FVEhPRCgpe3JldHVybiBuZXcgRXJyb3IoIkFic3RyYWN0IG1ldGhvZCBjYW5ub3QgYmUgaW52b2tlZCIpfXN0YXRpYyBnZXQgT1BFUkFUSU9OX0lTX05PVF9TVVBQT1JURUQoKXtyZXR1cm4gbmV3IEVycm9yKCJPcGVyYXRpb24gaXMgbm90IHN1cHBvcnRlZCIpfXN0YXRpYyBnZXQgVU5TVVBQT1JURURfU0hBUEVfVFlQRSgpe3JldHVybiBuZXcgRXJyb3IoIlVuc3VwcG9ydGVkIHNoYXBlIHR5cGUiKX19bC5FcnJvcnM9WTtjbGFzcyBoaXtjb25zdHJ1Y3Rvcih0LG4pe3RoaXMuZmlyc3Q9dCx0aGlzLmxhc3Q9bnx8dGhpcy5maXJzdH1bU3ltYm9sLml0ZXJhdG9yXSgpe2xldCB0O3JldHVybntuZXh0OigpPT4odD10P3QubmV4dDp0aGlzLmZpcnN0LHt2YWx1ZTp0LGRvbmU6dD09PXZvaWQgMH0pfX1nZXQgc2l6ZSgpe2xldCB0PTA7Zm9yKGxldCBuIG9mIHRoaXMpdCsrO3JldHVybiB0fXRvQXJyYXkodD12b2lkIDAsbj12b2lkIDApe2xldCByPVtdLGk9dHx8dGhpcy5maXJzdCxzPW58fHRoaXMubGFzdCxvPWk7aWYobz09PXZvaWQgMClyZXR1cm4gcjtkbyByLnB1c2gobyksbz1vLm5leHQ7d2hpbGUobyE9PXMubmV4dCk7cmV0dXJuIHJ9YXBwZW5kKHQpe3JldHVybiB0aGlzLmlzRW1wdHkoKT90aGlzLmZpcnN0PXQ6KHQucHJldj10aGlzLmxhc3QsdGhpcy5sYXN0Lm5leHQ9dCksdGhpcy5sYXN0PXQsdGhpcy5sYXN0Lm5leHQ9dm9pZCAwLHRoaXMuZmlyc3QucHJldj12b2lkIDAsdGhpc31pbnNlcnQodCxuKXtpZih0aGlzLmlzRW1wdHkoKSl0aGlzLmZpcnN0PXQsdGhpcy5sYXN0PXQ7ZWxzZSBpZihuPT1udWxsKXQubmV4dD10aGlzLmZpcnN0LHRoaXMuZmlyc3QucHJldj10LHRoaXMuZmlyc3Q9dDtlbHNle2xldCByPW4ubmV4dDtuLm5leHQ9dCxyJiYoci5wcmV2PXQpLHQucHJldj1uLHQubmV4dD1yLHRoaXMubGFzdD09PW4mJih0aGlzLmxhc3Q9dCl9cmV0dXJuIHRoaXMubGFzdC5uZXh0PXZvaWQgMCx0aGlzLmZpcnN0LnByZXY9dm9pZCAwLHRoaXN9cmVtb3ZlKHQpe3JldHVybiB0PT09dGhpcy5maXJzdCYmdD09PXRoaXMubGFzdD8odGhpcy5maXJzdD12b2lkIDAsdGhpcy5sYXN0PXZvaWQgMCk6KHQucHJldiYmKHQucHJldi5uZXh0PXQubmV4dCksdC5uZXh0JiYodC5uZXh0LnByZXY9dC5wcmV2KSx0PT09dGhpcy5maXJzdCYmKHRoaXMuZmlyc3Q9dC5uZXh0KSx0PT09dGhpcy5sYXN0JiYodGhpcy5sYXN0PXQucHJldikpLHRoaXN9aXNFbXB0eSgpe3JldHVybiB0aGlzLmZpcnN0PT09dm9pZCAwfXN0YXRpYyB0ZXN0SW5maW5pdGVMb29wKHQpe2xldCBuPXQscj10O2Rve2lmKG4hPXQmJm49PT1yKXRocm93IFkuSU5GSU5JVEVfTE9PUDtuPW4ubmV4dCxyPXIubmV4dC5uZXh0fXdoaWxlKG4hPXQpfX1jb25zdCBHYz17c3Ryb2tlOiJibGFjayJ9O2NsYXNzIGVke2NvbnN0cnVjdG9yKHQ9R2Mpe2Zvcihjb25zdCBuIGluIHQpdGhpc1tuXT10W25dO3RoaXMuc3Ryb2tlPXQuc3Ryb2tlPz9HYy5zdHJva2V9dG9BdHRyaWJ1dGVzU3RyaW5nKCl7cmV0dXJuIE9iamVjdC5rZXlzKHRoaXMpLnJlZHVjZSgodCxuKT0+dCsodGhpc1tuXSE9PXZvaWQgMD90aGlzLnRvQXR0clN0cmluZyhuLHRoaXNbbl0pOiIiKSwiIil9dG9BdHRyU3RyaW5nKHQsbil7Y29uc3Qgcj10PT09ImNsYXNzTmFtZSI/ImNsYXNzIjp0aGlzLmNvbnZlcnRDYW1lbFRvS2ViYWJDYXNlKHQpO3JldHVybiBuPT09bnVsbD9gJHtyfSBgOmAke3J9PSIke24udG9TdHJpbmcoKX0iIGB9Y29udmVydENhbWVsVG9LZWJhYkNhc2UodCl7cmV0dXJuIHQubWF0Y2goL1tBLVpdezIsfSg/PVtBLVpdW2Etel0rWzAtOV0qfFxiKXxbQS1aXT9bYS16XStbMC05XSp8W0EtWl18WzAtOV0rL2cpLmpvaW4oIi0iKS50b0xvd2VyQ2FzZSgpfX1mdW5jdGlvbiB0ZShlKXtyZXR1cm4gbmV3IGVkKGUpLnRvQXR0cmlidXRlc1N0cmluZygpfWZ1bmN0aW9uIGdlKGUsdCl7bGV0IG49W10sW3IsaSxzXT1lLnN0YW5kYXJkLFtvLGMsYV09dC5zdGFuZGFyZCxoPXIqYy1pKm8sZj1zKmMtaSphLHU9ciphLXMqbztpZighbC5VdGlscy5FUV8wKGgpKXtsZXQgZCxnO2k9PT0wPyhkPXMvcixnPXUvaCk6Yz09PTA/KGQ9YS9vLGc9dS9oKTpyPT09MD8oZD1mL2gsZz1zL2kpOm89PT0wPyhkPWYvaCxnPWEvYyk6KGQ9Zi9oLGc9dS9oKSxuLnB1c2gobmV3IGwuUG9pbnQoZCxnKSl9cmV0dXJuIG59ZnVuY3Rpb24gZWUoZSx0KXtsZXQgbj1bXSxyPXQucGMucHJvamVjdGlvbk9uKGUpLGk9dC5wYy5kaXN0YW5jZVRvKHIpWzBdO2lmKGwuVXRpbHMuRVEoaSx0LnIpKW4ucHVzaChyKTtlbHNlIGlmKGwuVXRpbHMuTFQoaSx0LnIpKXtsZXQgcz1NYXRoLnNxcnQodC5yKnQuci1pKmkpLG8sYztvPWUubm9ybS5yb3RhdGU5MENDVygpLm11bHRpcGx5KHMpLGM9ci50cmFuc2xhdGUobyksbi5wdXNoKGMpLG89ZS5ub3JtLnJvdGF0ZTkwQ1coKS5tdWx0aXBseShzKSxjPXIudHJhbnNsYXRlKG8pLG4ucHVzaChjKX1yZXR1cm4gbn1mdW5jdGlvbiBtZShlLHQpe2xldCBuPVtdO2ZvcihsZXQgciBvZiB0LnRvU2VnbWVudHMoKSl7bGV0IGk9RmUocixlKTtmb3IobGV0IHMgb2YgaSlpYShzLG4pfHxuLnB1c2gocyl9cmV0dXJuIG59ZnVuY3Rpb24gWW4oZSx0KXtsZXQgbj1bXTtpZihtZShlLHQuYm94KS5sZW5ndGg9PT0wKXJldHVybiBuO2xldCByPW5ldyBsLkNpcmNsZSh0LnBjLHQuciksaT1lZShlLHIpO2ZvcihsZXQgcyBvZiBpKXMub24odCkmJm4ucHVzaChzKTtyZXR1cm4gbn1mdW5jdGlvbiBGZShlLHQpe2xldCBuPVtdO2lmKGUucHMub24odCkmJm4ucHVzaChlLnBzKSxlLnBlLm9uKHQpJiYhZS5pc1plcm9MZW5ndGgoKSYmbi5wdXNoKGUucGUpLG4ubGVuZ3RoPjB8fGUuaXNaZXJvTGVuZ3RoKCl8fGUucHMubGVmdFRvKHQpJiZlLnBlLmxlZnRUbyh0KXx8IWUucHMubGVmdFRvKHQpJiYhZS5wZS5sZWZ0VG8odCkpcmV0dXJuIG47bGV0IHI9bmV3IGwuTGluZShlLnBzLGUucGUpO3JldHVybiBnZShyLHQpfWZ1bmN0aW9uIFduKGUsdCl7bGV0IG49W107aWYoZS5pc1plcm9MZW5ndGgoKSlyZXR1cm4gZS5wcy5vbih0KSYmbi5wdXNoKGUucHMpLG47aWYodC5pc1plcm9MZW5ndGgoKSlyZXR1cm4gdC5wcy5vbihlKSYmbi5wdXNoKHQucHMpLG47bGV0IHI9bmV3IGwuTGluZShlLnBzLGUucGUpLGk9bmV3IGwuTGluZSh0LnBzLHQucGUpO2lmKHIuaW5jaWRlbnRUbyhpKSllLnBzLm9uKHQpJiZuLnB1c2goZS5wcyksZS5wZS5vbih0KSYmbi5wdXNoKGUucGUpLHQucHMub24oZSkmJiF0LnBzLmVxdWFsVG8oZS5wcykmJiF0LnBzLmVxdWFsVG8oZS5wZSkmJm4ucHVzaCh0LnBzKSx0LnBlLm9uKGUpJiYhdC5wZS5lcXVhbFRvKGUucHMpJiYhdC5wZS5lcXVhbFRvKGUucGUpJiZuLnB1c2godC5wZSk7ZWxzZXtsZXQgcz1nZShyLGkpO3MubGVuZ3RoPjAmJmpjKHNbMF0sZSkmJmpjKHNbMF0sdCkmJm4ucHVzaChzWzBdKX1yZXR1cm4gbn1mdW5jdGlvbiBqYyhlLHQpe2NvbnN0IG49dC5ib3g7cmV0dXJuIGwuVXRpbHMuTEUoZS54LG4ueG1heCkmJmwuVXRpbHMuR0UoZS54LG4ueG1pbikmJmwuVXRpbHMuTEUoZS55LG4ueW1heCkmJmwuVXRpbHMuR0UoZS55LG4ueW1pbil9ZnVuY3Rpb24gWm4oZSx0KXtsZXQgbj1bXTtpZihlLmlzWmVyb0xlbmd0aCgpKXtsZXRbcyxvXT1lLnBzLmRpc3RhbmNlVG8odC5wYyk7cmV0dXJuIGwuVXRpbHMuRVEocyx0LnIpJiZuLnB1c2goZS5wcyksbn1sZXQgcj1uZXcgbC5MaW5lKGUucHMsZS5wZSksaT1lZShyLHQpO2ZvcihsZXQgcyBvZiBpKXMub24oZSkmJm4ucHVzaChzKTtyZXR1cm4gbn1mdW5jdGlvbiBwZShlLHQpe2xldCBuPVtdO2lmKGUuaXNaZXJvTGVuZ3RoKCkpcmV0dXJuIGUucHMub24odCkmJm4ucHVzaChlLnBzKSxuO2xldCByPW5ldyBsLkxpbmUoZS5wcyxlLnBlKSxpPW5ldyBsLkNpcmNsZSh0LnBjLHQucikscz1lZShyLGkpO2ZvcihsZXQgbyBvZiBzKW8ub24oZSkmJm8ub24odCkmJm4ucHVzaChvKTtyZXR1cm4gbn1mdW5jdGlvbiBuZChlLHQpe2xldCBuPVtdO2ZvcihsZXQgciBvZiB0LnRvU2VnbWVudHMoKSl7bGV0IGk9V24ocixlKTtmb3IobGV0IHMgb2YgaSluLnB1c2gocyl9cmV0dXJuIG59ZnVuY3Rpb24gUWMoZSx0KXtsZXQgbj1bXSxyPW5ldyBsLlZlY3RvcihlLnBjLHQucGMpLGk9ZS5yLHM9dC5yO2lmKGwuVXRpbHMuRVFfMChpKXx8bC5VdGlscy5FUV8wKHMpKXJldHVybiBuO2lmKGwuVXRpbHMuRVFfMChyLngpJiZsLlV0aWxzLkVRXzAoci55KSYmbC5VdGlscy5FUShpLHMpKXJldHVybiBuLnB1c2goZS5wYy50cmFuc2xhdGUoLWksMCkpLG47bGV0IG89ZS5wYy5kaXN0YW5jZVRvKHQucGMpWzBdO2lmKGwuVXRpbHMuR1QobyxpK3MpfHxsLlV0aWxzLkxUKG8sTWF0aC5hYnMoaS1zKSkpcmV0dXJuIG47ci54Lz1vLHIueS89bztsZXQgYztpZihsLlV0aWxzLkVRKG8saStzKXx8bC5VdGlscy5FUShvLE1hdGguYWJzKGktcykpKXJldHVybiBjPWUucGMudHJhbnNsYXRlKGkqci54LGkqci55KSxuLnB1c2goYyksbjtsZXQgYT1pKmkvKDIqbyktcypzLygyKm8pK28vMixoPWUucGMudHJhbnNsYXRlKGEqci54LGEqci55KSxmPU1hdGguc3FydChpKmktYSphKTtyZXR1cm4gYz1oLnRyYW5zbGF0ZShyLnJvdGF0ZTkwQ0NXKCkubXVsdGlwbHkoZikpLG4ucHVzaChjKSxjPWgudHJhbnNsYXRlKHIucm90YXRlOTBDVygpLm11bHRpcGx5KGYpKSxuLnB1c2goYyksbn1mdW5jdGlvbiByZChlLHQpe2xldCBuPVtdO2ZvcihsZXQgciBvZiB0LnRvU2VnbWVudHMoKSl7bGV0IGk9Wm4ocixlKTtmb3IobGV0IHMgb2YgaSluLnB1c2gocyl9cmV0dXJuIG59ZnVuY3Rpb24gS2MoZSx0KXtsZXQgbj1bXTtpZihlLnBjLmVxdWFsVG8odC5wYykmJmwuVXRpbHMuRVEoZS5yLHQucikpe2xldCBvO3JldHVybiBvPWUuc3RhcnQsby5vbih0KSYmbi5wdXNoKG8pLG89ZS5lbmQsby5vbih0KSYmbi5wdXNoKG8pLG89dC5zdGFydCxvLm9uKGUpJiZuLnB1c2gobyksbz10LmVuZCxvLm9uKGUpJiZuLnB1c2gobyksbn1sZXQgcj1uZXcgbC5DaXJjbGUoZS5wYyxlLnIpLGk9bmV3IGwuQ2lyY2xlKHQucGMsdC5yKSxzPXIuaW50ZXJzZWN0KGkpO2ZvcihsZXQgbyBvZiBzKW8ub24oZSkmJm8ub24odCkmJm4ucHVzaChvKTtyZXR1cm4gbn1mdW5jdGlvbiBmaShlLHQpe2xldCBuPVtdO2lmKHQucGMuZXF1YWxUbyhlLnBjKSYmbC5VdGlscy5FUSh0LnIsZS5yKSlyZXR1cm4gbi5wdXNoKGUuc3RhcnQpLG4ucHVzaChlLmVuZCksbjtsZXQgcj10LGk9bmV3IGwuQ2lyY2xlKGUucGMsZS5yKSxzPVFjKHIsaSk7Zm9yKGxldCBvIG9mIHMpby5vbihlKSYmbi5wdXNoKG8pO3JldHVybiBufWZ1bmN0aW9uIGlkKGUsdCl7bGV0IG49W107Zm9yKGxldCByIG9mIHQudG9TZWdtZW50cygpKXtsZXQgaT1wZShyLGUpO2ZvcihsZXQgcyBvZiBpKW4ucHVzaChzKX1yZXR1cm4gbn1mdW5jdGlvbiBIYyhlLHQpe3JldHVybiBlLmlzU2VnbWVudD9XbihlLnNoYXBlLHQpOnBlKHQsZS5zaGFwZSl9ZnVuY3Rpb24gSmMoZSx0KXtyZXR1cm4gZS5pc1NlZ21lbnQ/cGUoZS5zaGFwZSx0KTpLYyhlLnNoYXBlLHQpfWZ1bmN0aW9uIHRhKGUsdCl7cmV0dXJuIGUuaXNTZWdtZW50P0ZlKGUuc2hhcGUsdCk6WW4odCxlLnNoYXBlKX1mdW5jdGlvbiBzZChlLHQpe3JldHVybiBlLmlzU2VnbWVudD9naSh0LGUuc2hhcGUpOm1pKHQsZS5zaGFwZSl9ZnVuY3Rpb24gb2QoZSx0KXtyZXR1cm4gZS5pc1NlZ21lbnQ/Wm4oZS5zaGFwZSx0KTpmaShlLnNoYXBlLHQpfWZ1bmN0aW9uIHVpKGUsdCl7bGV0IG49W107Zm9yKGxldCByIG9mIHQuZWRnZXMpZm9yKGxldCBpIG9mIEhjKHIsZSkpbi5wdXNoKGkpO3JldHVybiBufWZ1bmN0aW9uIGRpKGUsdCl7bGV0IG49W107Zm9yKGxldCByIG9mIHQuZWRnZXMpZm9yKGxldCBpIG9mIEpjKHIsZSkpbi5wdXNoKGkpO3JldHVybiBufWZ1bmN0aW9uIGtlKGUsdCl7bGV0IG49W107aWYodC5pc0VtcHR5KCkpcmV0dXJuIG47Zm9yKGxldCByIG9mIHQuZWRnZXMpZm9yKGxldCBpIG9mIHRhKHIsZSkpaWEoaSxuKXx8bi5wdXNoKGkpO3JldHVybiBlLnNvcnRQb2ludHMobil9ZnVuY3Rpb24gZWEoZSx0KXtsZXQgbj1bXTtpZih0LmlzRW1wdHkoKSlyZXR1cm4gbjtmb3IobGV0IHIgb2YgdC5lZGdlcylmb3IobGV0IGkgb2Ygb2QocixlKSluLnB1c2goaSk7cmV0dXJuIG59ZnVuY3Rpb24gbmEoZSx0KXtyZXR1cm4gZS5pc1NlZ21lbnQ/SGModCxlLnNoYXBlKTplLmlzQXJjP0pjKHQsZS5zaGFwZSk6ZS5pc0xpbmU/dGEodCxlLnNoYXBlKTplLmlzUmF5P3NkKHQsZS5zaGFwZSk6W119ZnVuY3Rpb24gcmEoZSx0KXtsZXQgbj1bXTtpZih0LmlzRW1wdHkoKXx8ZS5zaGFwZS5ib3gubm90X2ludGVyc2VjdCh0LmJveCkpcmV0dXJuIG47bGV0IHI9dC5lZGdlcy5zZWFyY2goZS5zaGFwZS5ib3gpO2ZvcihsZXQgaSBvZiByKW49Wy4uLm4sLi4ubmEoZSxpKV07cmV0dXJuIG59ZnVuY3Rpb24gY2QoZSx0KXtsZXQgbj1bXTtpZih0LmlzRW1wdHkoKXx8ZS5zaXplPT09MClyZXR1cm4gbjtmb3IobGV0IHIgb2YgZSluPVsuLi5uLC4uLnJhKHIsdCldO3JldHVybiBufWZ1bmN0aW9uIGFkKGUsdCl7bGV0IG49W107aWYoZS5pc0VtcHR5KCl8fHQuaXNFbXB0eSgpfHxlLmJveC5ub3RfaW50ZXJzZWN0KHQuYm94KSlyZXR1cm4gbjtmb3IobGV0IHIgb2YgZS5lZGdlcyluPVsuLi5uLC4uLnJhKHIsdCldO3JldHVybiBufWZ1bmN0aW9uIGxkKGUsdCl7cmV0dXJuIGUgaW5zdGFuY2VvZiBsLkxpbmU/a2UoZSx0KTplIGluc3RhbmNlb2YgbC5TZWdtZW50P3VpKGUsdCk6ZSBpbnN0YW5jZW9mIGwuQXJjP2RpKGUsdCk6W119ZnVuY3Rpb24gaWEoZSx0KXtyZXR1cm4gdC5zb21lKG49Pm4uZXF1YWxUbyhlKSl9ZnVuY3Rpb24ga3QoZSl7cmV0dXJuIG5ldyBsLkxpbmUoZS5zdGFydCxlLm5vcm0pfWZ1bmN0aW9uIGdpKGUsdCl7cmV0dXJuIEZlKHQsa3QoZSkpLmZpbHRlcihuPT5lLmNvbnRhaW5zKG4pKX1mdW5jdGlvbiBtaShlLHQpe3JldHVybiBZbihrdChlKSx0KS5maWx0ZXIobj0+ZS5jb250YWlucyhuKSl9ZnVuY3Rpb24gc2EoZSx0KXtyZXR1cm4gZWUoa3QoZSksdCkuZmlsdGVyKG49PmUuY29udGFpbnMobikpfWZ1bmN0aW9uIGhkKGUsdCl7cmV0dXJuIG1lKGt0KGUpLHQpLmZpbHRlcihuPT5lLmNvbnRhaW5zKG4pKX1mdW5jdGlvbiBvYShlLHQpe3JldHVybiBnZShrdChlKSx0KS5maWx0ZXIobj0+ZS5jb250YWlucyhuKSl9ZnVuY3Rpb24gZmQoZSx0KXtyZXR1cm4gZ2Uoa3QoZSksa3QodCkpLmZpbHRlcihuPT5lLmNvbnRhaW5zKG4pKS5maWx0ZXIobj0+dC5jb250YWlucyhuKSl9ZnVuY3Rpb24gY2EoZSx0KXtyZXR1cm4ga2Uoa3QoZSksdCkuZmlsdGVyKG49PmUuY29udGFpbnMobikpfWZ1bmN0aW9uIGFhKGUsdCl7aWYoZS5pbnRlcnNlY3QmJmUuaW50ZXJzZWN0IGluc3RhbmNlb2YgRnVuY3Rpb24pcmV0dXJuIGUuaW50ZXJzZWN0KHQpO3Rocm93IFkuVU5TVVBQT1JURURfU0hBUEVfVFlQRX1mdW5jdGlvbiBfZShlLHQpe2xldCBuPVtdO2ZvcihsZXQgciBvZiB0KW49Wy4uLm4sLi4uYWEoZSxyLnNoYXBlKV07cmV0dXJuIG59ZnVuY3Rpb24gdWQoZSx0KXtsZXQgbj1bXTtmb3IobGV0IHIgb2YgZSlmb3IobGV0IGkgb2YgdCluPVsuLi5uLC4uLmFhKHIuc2hhcGUsaS5zaGFwZSldO3JldHVybiBufWxldCBuZT1jbGFzcyBKZSBleHRlbmRzIGhpe2NvbnN0cnVjdG9yKC4uLnQpe2lmKHN1cGVyKCksdGhpcy5pc0luZmluaXRlPSExLHQubGVuZ3RoPT09MSYmdFswXWluc3RhbmNlb2YgQXJyYXkmJnRbMF0ubGVuZ3RoPjApe2NvbnN0IG49dFswXSxyPW4ubGVuZ3RoLGk9YT0+YSBpbnN0YW5jZW9mIGwuU2VnbWVudHx8YSBpbnN0YW5jZW9mIGwuQXJjfHxhIGluc3RhbmNlb2YgbC5SYXl8fGEgaW5zdGFuY2VvZiBsLkxpbmUscz1hPT5hIGluc3RhbmNlb2YgbC5TZWdtZW50fHxhIGluc3RhbmNlb2YgbC5BcmN8fGEgaW5zdGFuY2VvZiBsLlJheSxvPWE9PmEgaW5zdGFuY2VvZiBsLlNlZ21lbnR8fGEgaW5zdGFuY2VvZiBsLkFyYztpZihyPT09MSYmaShuWzBdKXx8cj4xJiZzKG5bMF0pJiZzKG5bci0xXSkmJm4uc2xpY2UoMSxyLTEpLmV2ZXJ5KG8pKXt0aGlzLmlzSW5maW5pdGU9bi5zb21lKGE9PmEgaW5zdGFuY2VvZiBsLlJheXx8YSBpbnN0YW5jZW9mIGwuTGluZSk7Zm9yKGxldCBhIG9mIG4pe2xldCBoPW5ldyBsLkVkZ2UoYSk7dGhpcy5hcHBlbmQoaCl9dGhpcy5zZXRBcmNMZW5ndGgoKX1lbHNlIHRocm93IGwuRXJyb3JzLklMTEVHQUxfUEFSQU1FVEVSU319Z2V0IGVkZ2VzKCl7cmV0dXJuWy4uLnRoaXNdfWdldCBib3goKXtyZXR1cm4gdGhpcy5lZGdlcy5yZWR1Y2UoKHQsbik9PnQubWVyZ2Uobi5ib3gpLG5ldyBsLkJveCl9Z2V0IHZlcnRpY2VzKCl7bGV0IHQ9dGhpcy5lZGdlcy5tYXAobj0+bi5zdGFydCk7cmV0dXJuIHQucHVzaCh0aGlzLmxhc3QuZW5kKSx0fWdldCBsZW5ndGgoKXtpZih0aGlzLmlzRW1wdHkoKSlyZXR1cm4gMDtpZih0aGlzLmlzSW5maW5pdGUpcmV0dXJuIE51bWJlci5QT1NJVElWRV9JTkZJTklUWTtsZXQgdD0wO2ZvcihsZXQgbiBvZiB0aGlzKXQrPW4ubGVuZ3RoO3JldHVybiB0fWNsb25lKCl7cmV0dXJuIG5ldyBKZSh0aGlzLnRvU2hhcGVzKCkpfXNldEFyY0xlbmd0aCgpe2ZvcihsZXQgdCBvZiB0aGlzKXRoaXMuc2V0T25lRWRnZUFyY0xlbmd0aCh0KX1zZXRPbmVFZGdlQXJjTGVuZ3RoKHQpe3Q9PT10aGlzLmZpcnN0P3QuYXJjX2xlbmd0aD0wOnQuYXJjX2xlbmd0aD10LnByZXYuYXJjX2xlbmd0aCt0LnByZXYubGVuZ3RofXBvaW50QXRMZW5ndGgodCl7aWYodD50aGlzLmxlbmd0aHx8dDwwfHx0aGlzLmlzSW5maW5pdGUpcmV0dXJuIG51bGw7bGV0IG49bnVsbDtmb3IobGV0IHIgb2YgdGhpcylpZih0Pj1yLmFyY19sZW5ndGgmJihyPT09dGhpcy5sYXN0fHx0PHIubmV4dC5hcmNfbGVuZ3RoKSl7bj1yLnBvaW50QXRMZW5ndGgodC1yLmFyY19sZW5ndGgpO2JyZWFrfXJldHVybiBufWFkZFZlcnRleCh0LG4pe2xldCByPW4uc2hhcGUuc3BsaXQodCk7aWYoclswXT09PW51bGwpcmV0dXJuIG4ucHJldjtpZihyWzFdPT09bnVsbClyZXR1cm4gbjtsZXQgaT1uZXcgbC5FZGdlKHJbMF0pLHM9bi5wcmV2O3JldHVybiB0aGlzLmluc2VydChpLHMpLG4uc2hhcGU9clsxXSxpfWdldENoYWluKHQsbil7bGV0IHI9W107Zm9yKGxldCBpPXQ7aSE9PW4ubmV4dDtpPWkubmV4dClyLnB1c2goaSk7cmV0dXJuIHJ9c3BsaXQodCl7Zm9yKGxldCBuIG9mIHQpe2xldCByPXRoaXMuZmluZEVkZ2VCeVBvaW50KG4pO3RoaXMuYWRkVmVydGV4KG4scil9cmV0dXJuIHRoaXN9ZmluZEVkZ2VCeVBvaW50KHQpe2xldCBuO2ZvcihsZXQgciBvZiB0aGlzKWlmKHIuc2hhcGUuY29udGFpbnModCkpe249cjticmVha31yZXR1cm4gbn1kaXN0YW5jZVRvKHQpe2lmKHQgaW5zdGFuY2VvZiBQb2ludCl7Y29uc3RbbixyXT1sLkRpc3RhbmNlLnNoYXBlMm11bHRpbGluZSh0LHRoaXMpO3JldHVybltuLHIucmV2ZXJzZSgpXX1pZih0IGluc3RhbmNlb2YgbC5MaW5lKXtjb25zdFtuLHJdPWwuRGlzdGFuY2Uuc2hhcGUybXVsdGlsaW5lKHQsdGhpcyk7cmV0dXJuW24sci5yZXZlcnNlKCldfWlmKHQgaW5zdGFuY2VvZiBsLkNpcmNsZSl7Y29uc3RbbixyXT1sLkRpc3RhbmNlLnNoYXBlMm11bHRpbGluZSh0LHRoaXMpO3JldHVybltuLHIucmV2ZXJzZSgpXX1pZih0IGluc3RhbmNlb2YgbC5TZWdtZW50KXtjb25zdFtuLHJdPWwuRGlzdGFuY2Uuc2hhcGUybXVsdGlsaW5lKHQsdGhpcyk7cmV0dXJuW24sci5yZXZlcnNlKCldfWlmKHQgaW5zdGFuY2VvZiBsLkFyYyl7Y29uc3RbbixyXT1sLkRpc3RhbmNlLnNoYXBlMm11bHRpbGluZSh0LHRoaXMpO3JldHVybltuLHIucmV2ZXJzZSgpXX1pZih0IGluc3RhbmNlb2YgbC5NdWx0aWxpbmUpcmV0dXJuIGwuRGlzdGFuY2UubXVsdGlsaW5lMm11bHRpbGluZSh0aGlzLHQpO3Rocm93IGwuRXJyb3JzLlVOU1VQUE9SVEVEX1NIQVBFX1RZUEV9aW50ZXJzZWN0KHQpe3JldHVybiB0IGluc3RhbmNlb2YgbC5NdWx0aWxpbmU/dWQodGhpcyx0KTpfZSh0LHRoaXMpfWNvbnRhaW5zKHQpe2lmKHQgaW5zdGFuY2VvZiBsLlBvaW50KXJldHVybiB0aGlzLmVkZ2VzLnNvbWUobj0+bi5zaGFwZS5jb250YWlucyh0KSk7dGhyb3cgbC5FcnJvcnMuVU5TVVBQT1JURURfU0hBUEVfVFlQRX10cmFuc2xhdGUodCl7cmV0dXJuIG5ldyBKZSh0aGlzLmVkZ2VzLm1hcChuPT5uLnNoYXBlLnRyYW5zbGF0ZSh0KSkpfXJvdGF0ZSh0PTAsbj1uZXcgbC5Qb2ludCl7cmV0dXJuIG5ldyBKZSh0aGlzLmVkZ2VzLm1hcChyPT5yLnNoYXBlLnJvdGF0ZSh0LG4pKSl9dHJhbnNmb3JtKHQ9bmV3IGwuTWF0cml4KXtyZXR1cm4gbmV3IEplKHRoaXMuZWRnZXMubWFwKG49Pm4uc2hhcGUudHJhbnNmb3JtKHQpKSl9dG9TaGFwZXMoKXtyZXR1cm4gdGhpcy5lZGdlcy5tYXAodD0+dC5zaGFwZS5jbG9uZSgpKX10b0pTT04oKXtyZXR1cm4gdGhpcy5lZGdlcy5tYXAodD0+dC50b0pTT04oKSl9c3ZnUG9pbnRzKCl7cmV0dXJuIHRoaXMudmVydGljZXMubWFwKHQ9PmAke3QueH0sJHt0Lnl9YCkuam9pbigiICIpfWRwYXRoKCl7bGV0IHQ9YE0ke3RoaXMuZmlyc3Quc3RhcnQueH0sJHt0aGlzLmZpcnN0LnN0YXJ0Lnl9YDtmb3IobGV0IG4gb2YgdGhpcyl0Kz1uLnN2ZygpO3JldHVybiB0fXN2Zyh0PXt9KXtsZXQgbj1gCjxwYXRoICR7dGUoe2ZpbGw6Im5vbmUiLC4uLnR9KX0gZD0iYDtuKz1gCk0ke3RoaXMuZmlyc3Quc3RhcnQueH0sJHt0aGlzLmZpcnN0LnN0YXJ0Lnl9YDtmb3IobGV0IHIgb2YgdGhpcyluKz1yLnN2ZygpO3JldHVybiBuKz1gIiA+CjwvcGF0aD5gLG59fTtsLk11bHRpbGluZT1uZTtjb25zdCBkZD0oLi4uZSk9Pm5ldyBsLk11bHRpbGluZSguLi5lKTtsLm11bHRpbGluZT1kZDtmdW5jdGlvbiB5ZShlLHQsbil7bGV0IHI9bi5sZW5ndGgsaT1lLnNoYXBlLnNwbGl0KHQpO2lmKGkubGVuZ3RoPT09MClyZXR1cm47bGV0IHM9MDtpWzBdPT09bnVsbD9zPTA6aVsxXT09PW51bGw/cz1lLnNoYXBlLmxlbmd0aDpzPWlbMF0ubGVuZ3RoO2xldCBvPWFpO0p0KHMsMCkmJihvfD1xZSksSnQocyxlLnNoYXBlLmxlbmd0aCkmJihvfD1kZSk7bGV0IGM7cz09PTEvMD9jPWlbMF0uY29vcmQodCk6Yz1vJmRlJiZlLm5leHQmJmUubmV4dC5hcmNfbGVuZ3RoPT09MD8wOmUuYXJjX2xlbmd0aCtzLG4ucHVzaCh7aWQ6cixwdDp0LGFyY19sZW5ndGg6YyxlZGdlX2JlZm9yZTplLGVkZ2VfYWZ0ZXI6dm9pZCAwLGZhY2U6ZS5mYWNlLGlzX3ZlcnRleDpvfSl9ZnVuY3Rpb24gQmUoZSl7ZS5pbnRfcG9pbnRzMV9zb3J0ZWQ9QnQoZS5pbnRfcG9pbnRzMSksZS5pbnRfcG9pbnRzMl9zb3J0ZWQ9QnQoZS5pbnRfcG9pbnRzMil9ZnVuY3Rpb24gQnQoZSl7bGV0IHQ9bmV3IE1hcCxuPTA7Zm9yKGxldCBpIG9mIGUpdC5oYXMoaS5mYWNlKXx8KHQuc2V0KGkuZmFjZSxuKSxuKyspO2ZvcihsZXQgaSBvZiBlKWkuZmFjZUlkPXQuZ2V0KGkuZmFjZSk7cmV0dXJuIGUuc2xpY2UoKS5zb3J0KGdkKX1mdW5jdGlvbiBnZChlLHQpe3JldHVybiBlLmZhY2VJZDx0LmZhY2VJZD8tMTplLmZhY2VJZD50LmZhY2VJZD8xOmUuYXJjX2xlbmd0aDx0LmFyY19sZW5ndGg/LTE6ZS5hcmNfbGVuZ3RoPnQuYXJjX2xlbmd0aD8xOjB9ZnVuY3Rpb24gcGkoZSl7aWYoZS5pbnRfcG9pbnRzMS5sZW5ndGg8MilyZXR1cm47bGV0IHQ9ITEsbixyLGkscztmb3IobGV0IG89MDtvPGUuaW50X3BvaW50czFfc29ydGVkLmxlbmd0aDtvKyspaWYoZS5pbnRfcG9pbnRzMV9zb3J0ZWRbb10uaWQhPT0tMSl7bj1lLmludF9wb2ludHMxX3NvcnRlZFtvXSxyPWUuaW50X3BvaW50czJbbi5pZF07Zm9yKGxldCBjPW8rMTtjPGUuaW50X3BvaW50czFfc29ydGVkLmxlbmd0aCYmKGk9ZS5pbnRfcG9pbnRzMV9zb3J0ZWRbY10sISFKdChpLmFyY19sZW5ndGgsbi5hcmNfbGVuZ3RoKSk7YysrKWkuaWQhPT0tMSYmKHM9ZS5pbnRfcG9pbnRzMltpLmlkXSxzLmlkIT09LTEmJmkuZWRnZV9iZWZvcmU9PT1uLmVkZ2VfYmVmb3JlJiZpLmVkZ2VfYWZ0ZXI9PT1uLmVkZ2VfYWZ0ZXImJnMuZWRnZV9iZWZvcmU9PT1yLmVkZ2VfYmVmb3JlJiZzLmVkZ2VfYWZ0ZXI9PT1yLmVkZ2VfYWZ0ZXImJihpLmlkPS0xLHMuaWQ9LTEsdD0hMCkpfXI9ZS5pbnRfcG9pbnRzMl9zb3J0ZWRbMF0sbj1lLmludF9wb2ludHMxW3IuaWRdO2ZvcihsZXQgbz0xO288ZS5pbnRfcG9pbnRzMl9zb3J0ZWQubGVuZ3RoO28rKyl7bGV0IGM9ZS5pbnRfcG9pbnRzMl9zb3J0ZWRbb107aWYoYy5pZD09PS0xKWNvbnRpbnVlO2lmKHIuaWQ9PT0tMXx8IUp0KGMuYXJjX2xlbmd0aCxyLmFyY19sZW5ndGgpKXtyPWMsbj1lLmludF9wb2ludHMxW3IuaWRdO2NvbnRpbnVlfWxldCBhPWUuaW50X3BvaW50czFbYy5pZF07YS5lZGdlX2JlZm9yZT09PW4uZWRnZV9iZWZvcmUmJmEuZWRnZV9hZnRlcj09PW4uZWRnZV9hZnRlciYmYy5lZGdlX2JlZm9yZT09PXIuZWRnZV9iZWZvcmUmJmMuZWRnZV9hZnRlcj09PXIuZWRnZV9hZnRlciYmKGEuaWQ9LTEsYy5pZD0tMSx0PSEwKX10JiYoZS5pbnRfcG9pbnRzMT1lLmludF9wb2ludHMxLmZpbHRlcihvPT5vLmlkPj0wKSxlLmludF9wb2ludHMyPWUuaW50X3BvaW50czIuZmlsdGVyKG89Pm8uaWQ+PTApLGUuaW50X3BvaW50czEuZm9yRWFjaCgobyxjKT0+by5pZD1jKSxlLmludF9wb2ludHMyLmZvckVhY2goKG8sYyk9Pm8uaWQ9YykpfWZ1bmN0aW9uIF9pKGUpe2ZvcihsZXQgdCBvZiBlKXQuZWRnZV9iZWZvcmUmJih0LmVkZ2VfYmVmb3JlLmJ2U3RhcnQ9dm9pZCAwLHQuZWRnZV9iZWZvcmUuYnZFbmQ9dm9pZCAwLHQuZWRnZV9iZWZvcmUuYnY9dm9pZCAwLHQuZWRnZV9iZWZvcmUub3ZlcmxhcD12b2lkIDApLHQuZWRnZV9hZnRlciYmKHQuZWRnZV9hZnRlci5idlN0YXJ0PXZvaWQgMCx0LmVkZ2VfYWZ0ZXIuYnZFbmQ9dm9pZCAwLHQuZWRnZV9hZnRlci5idj12b2lkIDAsdC5lZGdlX2FmdGVyLm92ZXJsYXA9dm9pZCAwKTtmb3IobGV0IHQgb2YgZSl0LmVkZ2VfYmVmb3JlJiYodC5lZGdlX2JlZm9yZS5idkVuZD13dCksdC5lZGdlX2FmdGVyJiYodC5lZGdlX2FmdGVyLmJ2U3RhcnQ9d3QpfWZ1bmN0aW9uIHlpKGUsdCl7Zm9yKGxldCBuIG9mIGUpbi5lZGdlX2JlZm9yZSYmbi5lZGdlX2JlZm9yZS5zZXRJbmNsdXNpb24odCksbi5lZGdlX2FmdGVyJiZuLmVkZ2VfYWZ0ZXIuc2V0SW5jbHVzaW9uKHQpfWZ1bmN0aW9uIG1kKGUpe2xldCB0LG4scixpPWUuaW50X3BvaW50czEubGVuZ3RoO2ZvcihsZXQgcz0wO3M8aTtzKyspe2xldCBvPWUuaW50X3BvaW50czFfc29ydGVkW3NdO28uZmFjZSE9PXQmJihuPXMsdD1vLmZhY2UpO2xldCBjPXMsYT14ZShlLmludF9wb2ludHMxX3NvcnRlZCxzLHQpLGg7YythPGkmJmUuaW50X3BvaW50czFfc29ydGVkW2MrYV0uZmFjZT09PXQ/aD1jK2E6aD1uO2xldCBmPXhlKGUuaW50X3BvaW50czFfc29ydGVkLGgsdCk7cj1udWxsO2ZvcihsZXQgeD1oO3g8aCtmO3grKyl7bGV0IFQ9ZS5pbnRfcG9pbnRzMV9zb3J0ZWRbeF07aWYoVC5mYWNlPT09dCYmZS5pbnRfcG9pbnRzMltULmlkXS5mYWNlPT09ZS5pbnRfcG9pbnRzMltvLmlkXS5mYWNlKXtyPVQ7YnJlYWt9fWlmKHI9PT1udWxsKWNvbnRpbnVlO2xldCB1PW8uZWRnZV9hZnRlcixkPXIuZWRnZV9iZWZvcmU7aWYoISh1LmJ2PT09d3QmJmQuYnY9PT13dCl8fHUhPT1kKWNvbnRpbnVlO2xldCBnPWUuaW50X3BvaW50czJbby5pZF0sbT1lLmludF9wb2ludHMyW3IuaWRdLF89Zy5lZGdlX2FmdGVyLHA9bS5lZGdlX2JlZm9yZTtfLmJ2PT09d3QmJnAuYnY9PT13dCYmXz09PXB8fChnPWUuaW50X3BvaW50czJbci5pZF0sbT1lLmludF9wb2ludHMyW28uaWRdLF89Zy5lZGdlX2FmdGVyLHA9bS5lZGdlX2JlZm9yZSksXy5idj09PXd0JiZwLmJ2PT09d3QmJl89PT1wJiZ1LnNldE92ZXJsYXAoXyl9fWZ1bmN0aW9uIHhlKGUsdCxuKXtsZXQgcixpLHM9MTtpZihlLmxlbmd0aD09PTEpcmV0dXJuIDE7cj1lW3RdO2ZvcihsZXQgbz10KzE7bzxlLmxlbmd0aCYmIShyLmZhY2UhPT1ufHwoaT1lW29dLCEoaS5wdC5lcXVhbFRvKHIucHQpJiZpLmVkZ2VfYmVmb3JlPT09ci5lZGdlX2JlZm9yZSYmaS5lZGdlX2FmdGVyPT09ci5lZGdlX2FmdGVyKSkpO28rKylzKys7cmV0dXJuIHN9ZnVuY3Rpb24gTWUoZSx0KXtpZih0KXtmb3IobGV0IG4gb2YgdCl7bGV0IHI9bi5lZGdlX2JlZm9yZTtpZihuLmlzX3ZlcnRleD1haSxyLnNoYXBlLnN0YXJ0JiZyLnNoYXBlLnN0YXJ0LmVxdWFsVG8obi5wdCkmJihuLmlzX3ZlcnRleHw9cWUpLHIuc2hhcGUuZW5kJiZyLnNoYXBlLmVuZC5lcXVhbFRvKG4ucHQpJiYobi5pc192ZXJ0ZXh8PWRlKSxuLmlzX3ZlcnRleCZxZSl7bi5lZGdlX2JlZm9yZT1yLnByZXYsci5wcmV2JiYobi5pc192ZXJ0ZXg9ZGUpO2NvbnRpbnVlfWlmKG4uaXNfdmVydGV4JmRlKWNvbnRpbnVlO2xldCBpPWUuYWRkVmVydGV4KG4ucHQscik7bi5lZGdlX2JlZm9yZT1pfWZvcihsZXQgbiBvZiB0KW4uZWRnZV9iZWZvcmU/bi5lZGdlX2FmdGVyPW4uZWRnZV9iZWZvcmUubmV4dDplIGluc3RhbmNlb2YgbmUmJm4uaXNfdmVydGV4JnFlJiYobi5lZGdlX2FmdGVyPWUuZmlyc3QpfX1mdW5jdGlvbiBsYShlLHQsbil7Y29uc3Qgcj1lLmVkZ2VfYmVmb3JlLGk9dC5lZGdlX2FmdGVyLHM9bi5sZW5ndGg7ci5uZXh0PW5bMF0sblswXS5wcmV2PXIsbltzLTFdLm5leHQ9aSxpLnByZXY9bltzLTFdfWNvbnN0e0lOU0lERTpBdCxPVVRTSURFOk90LEJPVU5EQVJZOkosT1ZFUkxBUF9TQU1FOnBkLE9WRVJMQVBfT1BQT1NJVEU6X2R9PURuLHtOT1RfVkVSVEVYOnltLFNUQVJUX1ZFUlRFWDpoYSxFTkRfVkVSVEVYOmZhfT1EbixYbj0xLFVlPTIscmU9MztmdW5jdGlvbiB5ZChlLHQpe2xldFtuLHJdPURlKGUsdCxYbiwhMCk7cmV0dXJuIG59ZnVuY3Rpb24geGkoZSx0KXtsZXQgcj10LmNsb25lKCkucmV2ZXJzZSgpLFtpLHNdPURlKGUscixyZSwhMCk7cmV0dXJuIGl9ZnVuY3Rpb24gdWEoZSx0KXtsZXRbbixyXT1EZShlLHQsVWUsITApO3JldHVybiBufWZ1bmN0aW9uIGRhKGUsdCl7bGV0W24scl09RGUoZSx0LFVlLCExKSxpPVtdO2ZvcihsZXQgbyBvZiBuLmZhY2VzKWk9Wy4uLmksLi4uWy4uLm8uZWRnZXNdLm1hcChjPT5jLnNoYXBlKV07bGV0IHM9W107Zm9yKGxldCBvIG9mIHIuZmFjZXMpcz1bLi4ucywuLi5bLi4uby5lZGdlc10ubWFwKGM9PmMuc2hhcGUpXTtyZXR1cm5baSxzXX1mdW5jdGlvbiBNaShlLHQpe2xldFtuLHJdPURlKGUsdCxyZSwhMSksaT1bXTtmb3IobGV0IHMgb2Ygbi5mYWNlcylpPVsuLi5pLC4uLlsuLi5zLmVkZ2VzXS5tYXAobz0+by5zaGFwZSldO3JldHVybiBpfWZ1bmN0aW9uIGdhKGUsdCl7bGV0IG49ZS5jbG9uZSgpLHI9dC5jbG9uZSgpLGk9bWEobixyKTtCZShpKSxNZShuLGkuaW50X3BvaW50czFfc29ydGVkKSxNZShyLGkuaW50X3BvaW50czJfc29ydGVkKSxwaShpKSxCZShpKTtsZXQgcz1pLmludF9wb2ludHMxX3NvcnRlZC5tYXAoYz0+Yy5wdCksbz1pLmludF9wb2ludHMyX3NvcnRlZC5tYXAoYz0+Yy5wdCk7cmV0dXJuW3Msb119ZnVuY3Rpb24geGQoZSx0LG4scil7bGV0IGk9cGEoZSxuLmludF9wb2ludHMxKSxzPXBhKHQsbi5pbnRfcG9pbnRzMik7Zm9yKF9hKGksdCksX2EocyxlKSxfaShuLmludF9wb2ludHMxKSxfaShuLmludF9wb2ludHMyKSx5aShuLmludF9wb2ludHMxLHQpLHlpKG4uaW50X3BvaW50czIsZSk7d2QoZSx0LG4uaW50X3BvaW50czEsbi5pbnRfcG9pbnRzMV9zb3J0ZWQsbi5pbnRfcG9pbnRzMixuKTspO21kKG4pLHdpKGUscixuLmludF9wb2ludHMxX3NvcnRlZCwhMCksd2kodCxyLG4uaW50X3BvaW50czJfc29ydGVkLCExKSx5YShlLGksciwhMCkseWEodCxzLHIsITEpfWZ1bmN0aW9uIE1kKGUsdCxuLHIpe1RkKGUsdCxyLG4uaW50X3BvaW50czIpLEFkKGUsdCxuKSxUaShlLG4uaW50X3BvaW50czEpLFRpKHQsbi5pbnRfcG9pbnRzMiksQWkoZSxuLmludF9wb2ludHMxLG4uaW50X3BvaW50czIpLEFpKGUsbi5pbnRfcG9pbnRzMixuLmludF9wb2ludHMxKX1mdW5jdGlvbiBEZShlLHQsbixyKXtsZXQgaT1lLmNsb25lKCkscz10LmNsb25lKCksbz1tYShpLHMpO3JldHVybiBCZShvKSxNZShpLG8uaW50X3BvaW50czFfc29ydGVkKSxNZShzLG8uaW50X3BvaW50czJfc29ydGVkKSxwaShvKSxCZShvKSx4ZChpLHMsbyxuKSxyJiZNZChpLHMsbyxuKSxbaSxzXX1mdW5jdGlvbiBtYShlLHQpe2xldCBuPXtpbnRfcG9pbnRzMTpbXSxpbnRfcG9pbnRzMjpbXX07Zm9yKGxldCByIG9mIGUuZWRnZXMpe2xldCBpPXQuZWRnZXMuc2VhcmNoKHIuYm94KTtmb3IobGV0IHMgb2YgaSl7bGV0IG89ci5zaGFwZS5pbnRlcnNlY3Qocy5zaGFwZSk7Zm9yKGxldCBjIG9mIG8peWUocixjLG4uaW50X3BvaW50czEpLHllKHMsYyxuLmludF9wb2ludHMyKX19cmV0dXJuIG59ZnVuY3Rpb24gcGEoZSx0KXtsZXQgbj1bXTtmb3IobGV0IHIgb2YgZS5mYWNlcyl0LmZpbmQoaT0+aS5mYWNlPT09cil8fG4ucHVzaChyKTtyZXR1cm4gbn1mdW5jdGlvbiBfYShlLHQpe2ZvcihsZXQgbiBvZiBlKW4uZmlyc3QuYnY9bi5maXJzdC5idlN0YXJ0PW4uZmlyc3QuYnZFbmQ9dm9pZCAwLG4uZmlyc3Quc2V0SW5jbHVzaW9uKHQpfWZ1bmN0aW9uIHdkKGUsdCxuLHIsaSxzKXtsZXQgbyxjLGEsaD1yLmxlbmd0aCxmPSExO2ZvcihsZXQgdT0wO3U8aDt1Kyspe2xldCBkPXJbdV07ZC5mYWNlIT09byYmKGM9dSxvPWQuZmFjZSk7bGV0IGc9dSxtPXhlKHIsdSxvKSxfO2crbTxoJiZyW2crbV0uZmFjZT09PW8/Xz1nK206Xz1jO2xldCBwPXhlKHIsXyxvKTthPW51bGw7Zm9yKGxldCBNPV87TTxfK3A7TSsrKXtsZXQgQT1yW01dO2lmKEEuZmFjZT09PW8mJmlbQS5pZF0uZmFjZT09PWlbZC5pZF0uZmFjZSl7YT1BO2JyZWFrfX1pZihhPT09bnVsbCljb250aW51ZTtsZXQgeD1kLmVkZ2VfYWZ0ZXIsVD1hLmVkZ2VfYmVmb3JlO2lmKHguYnY9PT1KJiZULmJ2IT1KKXt4LmJ2PVQuYnY7Y29udGludWV9aWYoeC5idiE9SiYmVC5idj09PUope1QuYnY9eC5idjtjb250aW51ZX1pZih4LmJ2PT09SiYmVC5idj09PUomJnghPVR8fHguYnY9PT1BdCYmVC5idj09PU90fHx4LmJ2PT09T3QmJlQuYnY9PT1BdCl7bGV0IE09eC5uZXh0O2Zvcig7TSE9VDspTS5idlN0YXJ0PXZvaWQgMCxNLmJ2RW5kPXZvaWQgMCxNLmJ2PXZvaWQgMCxNLnNldEluY2x1c2lvbih0KSxNPU0ubmV4dH1pZih4LmJ2PT09SiYmVC5idj09PUomJnghPVQpe2xldCBNPXgubmV4dCxBO2Zvcig7TSE9VDspe2lmKE0uYnYhPUope2lmKEE9PT12b2lkIDApQT1NLmJ2O2Vsc2UgaWYoTS5idiE9QSl0aHJvdyBZLlVOUkVTT0xWRURfQk9VTkRBUllfQ09ORkxJQ1R9TT1NLm5leHR9QSE9bnVsbCYmKHguYnY9QSxULmJ2PUEpO2NvbnRpbnVlfWlmKHguYnY9PT1BdCYmVC5idj09PU90fHx4LmJ2PT09T3QmJlQuYnY9PT1BdCl7bGV0IE09eDtmb3IoO00hPVQ7KXtpZihNLmJ2U3RhcnQ9PT14LmJ2JiZNLmJ2RW5kPT09VC5idil7bGV0W0Esdl09TS5zaGFwZS5kaXN0YW5jZVRvKHQpO2lmKEE8MTAqbC5EUF9UT0wpe3llKE0sdi5wcyxuKTtsZXQgdz1uW24ubGVuZ3RoLTFdO2lmKHcuaXNfdmVydGV4JmhhKXcuZWRnZV9hZnRlcj1NLHcuZWRnZV9iZWZvcmU9TS5wcmV2LE0uYnZTdGFydD1KLE0uYnY9dm9pZCAwLE0uc2V0SW5jbHVzaW9uKHQpO2Vsc2UgaWYody5pc192ZXJ0ZXgmZmEpdy5lZGdlX2FmdGVyPU0ubmV4dCxNLmJ2RW5kPUosTS5idj12b2lkIDAsTS5zZXRJbmNsdXNpb24odCk7ZWxzZXtsZXQgUz10LmFkZFZlcnRleCh3LnB0LE0pO3cuZWRnZV9iZWZvcmU9Uyx3LmVkZ2VfYWZ0ZXI9Uy5uZXh0LFMuc2V0SW5jbHVzaW9uKHQpLFMubmV4dC5idlN0YXJ0PUosUy5uZXh0LmJ2RW5kPXZvaWQgMCxTLm5leHQuYnY9dm9pZCAwLFMubmV4dC5zZXRJbmNsdXNpb24odCl9bGV0IFA9dC5maW5kRWRnZUJ5UG9pbnQodi5wZSk7eWUoUCx2LnBlLGkpO2xldCBiPWlbaS5sZW5ndGgtMV07aWYoYi5pc192ZXJ0ZXgmaGEpYi5lZGdlX2FmdGVyPVAsYi5lZGdlX2JlZm9yZT1QLnByZXY7ZWxzZSBpZihiLmlzX3ZlcnRleCZmYSliLmVkZ2VfYWZ0ZXI9UC5uZXh0O2Vsc2V7bGV0IFM9aS5maW5kKFY9PlYuZWRnZV9hZnRlcj09PVApLE89dC5hZGRWZXJ0ZXgoYi5wdCxQKTtiLmVkZ2VfYmVmb3JlPU8sYi5lZGdlX2FmdGVyPU8ubmV4dCxTJiYoUy5lZGdlX2FmdGVyPU8pLE8uYnZTdGFydD12b2lkIDAsTy5idkVuZD1KLE8uYnY9dm9pZCAwLE8uc2V0SW5jbHVzaW9uKGUpLE8ubmV4dC5idlN0YXJ0PUosTy5uZXh0LmJ2RW5kPXZvaWQgMCxPLm5leHQuYnY9dm9pZCAwLE8ubmV4dC5zZXRJbmNsdXNpb24oZSl9QmUocyksZj0hMDticmVha319TT1NLm5leHR9aWYoZilicmVhazt0aHJvdyBZLlVOUkVTT0xWRURfQk9VTkRBUllfQ09ORkxJQ1R9fXJldHVybiBmfWZ1bmN0aW9uIHdpKGUsdCxuLHIpe2lmKCFuKXJldHVybjtsZXQgaSxzLG8sYztmb3IobGV0IGE9MDthPG4ubGVuZ3RoO2ErKyl7aWYobz1uW2FdLG8uZmFjZSE9PWkmJihzPWEsaT1vLmZhY2UpLGkuaXNFbXB0eSgpKWNvbnRpbnVlO2xldCBoPWEsZj14ZShuLGEsaSksdTtoK2Y8bi5sZW5ndGgmJm5baCtmXS5mYWNlPT09by5mYWNlP3U9aCtmOnU9cyxjPW5bdV07bGV0IGQ9dSxnPXhlKG4sZCxpKSxtPW8uZWRnZV9hZnRlcixfPWMuZWRnZV9iZWZvcmU7aWYobS5idj09PUF0JiZfLmJ2PT09QXQmJnQ9PT1Ybnx8bS5idj09PU90JiZfLmJ2PT09T3QmJnQ9PT1VZXx8KG0uYnY9PT1PdHx8Xy5idj09PU90KSYmdD09PXJlJiYhcnx8KG0uYnY9PT1BdHx8Xy5idj09PUF0KSYmdD09PXJlJiZyfHxtLmJ2PT09SiYmXy5idj09PUomJm0ub3ZlcmxhcCZwZCYmcnx8bS5idj09PUomJl8uYnY9PT1KJiZtLm92ZXJsYXAmX2Qpe2UucmVtb3ZlQ2hhaW4oaSxtLF8pO2ZvcihsZXQgcD1oO3A8aCtmO3ArKyluW3BdLmVkZ2VfYWZ0ZXI9dm9pZCAwO2ZvcihsZXQgcD1kO3A8ZCtnO3ArKyluW3BdLmVkZ2VfYmVmb3JlPXZvaWQgMH1hKz1mLTF9fWZ1bmN0aW9uIFRkKGUsdCxuLHIpe2ZvcihsZXQgaSBvZiB0LmZhY2VzKXtmb3IobGV0IHMgb2YgaSllLmVkZ2VzLmFkZChzKTtyLmZpbmQocz0+cy5mYWNlPT09aSk9PT12b2lkIDAmJmUuYWRkRmFjZShpLmZpcnN0LGkubGFzdCl9fWZ1bmN0aW9uIEFkKGUsdCxuKXtpZihuLmludF9wb2ludHMxLmxlbmd0aCE9PTApZm9yKGxldCByPTA7cjxuLmludF9wb2ludHMxLmxlbmd0aDtyKyspe2xldCBpPW4uaW50X3BvaW50czFbcl0scz1uLmludF9wb2ludHMyW3JdO2lmKGkuZWRnZV9iZWZvcmUhPT12b2lkIDAmJmkuZWRnZV9hZnRlcj09PXZvaWQgMCYmcy5lZGdlX2JlZm9yZT09PXZvaWQgMCYmcy5lZGdlX2FmdGVyIT09dm9pZCAwJiYoaS5lZGdlX2JlZm9yZS5uZXh0PXMuZWRnZV9hZnRlcixzLmVkZ2VfYWZ0ZXIucHJldj1pLmVkZ2VfYmVmb3JlLGkuZWRnZV9hZnRlcj1zLmVkZ2VfYWZ0ZXIscy5lZGdlX2JlZm9yZT1pLmVkZ2VfYmVmb3JlKSxzLmVkZ2VfYmVmb3JlIT09dm9pZCAwJiZzLmVkZ2VfYWZ0ZXI9PT12b2lkIDAmJmkuZWRnZV9iZWZvcmU9PT12b2lkIDAmJmkuZWRnZV9hZnRlciE9PXZvaWQgMCYmKHMuZWRnZV9iZWZvcmUubmV4dD1pLmVkZ2VfYWZ0ZXIsaS5lZGdlX2FmdGVyLnByZXY9cy5lZGdlX2JlZm9yZSxzLmVkZ2VfYWZ0ZXI9aS5lZGdlX2FmdGVyLGkuZWRnZV9iZWZvcmU9cy5lZGdlX2JlZm9yZSksaS5lZGdlX2JlZm9yZSE9PXZvaWQgMCYmaS5lZGdlX2FmdGVyPT09dm9pZCAwKWZvcihsZXQgbyBvZiBuLmludF9wb2ludHMxX3NvcnRlZClvIT09aSYmby5lZGdlX2JlZm9yZT09PXZvaWQgMCYmby5lZGdlX2FmdGVyIT09dm9pZCAwJiZvLnB0LmVxdWFsVG8oaS5wdCkmJihpLmVkZ2VfYmVmb3JlLm5leHQ9by5lZGdlX2FmdGVyLG8uZWRnZV9hZnRlci5wcmV2PWkuZWRnZV9iZWZvcmUsaS5lZGdlX2FmdGVyPW8uZWRnZV9hZnRlcixvLmVkZ2VfYmVmb3JlPWkuZWRnZV9iZWZvcmUpO2lmKHMuZWRnZV9iZWZvcmUhPT12b2lkIDAmJnMuZWRnZV9hZnRlcj09PXZvaWQgMClmb3IobGV0IG8gb2Ygbi5pbnRfcG9pbnRzMl9zb3J0ZWQpbyE9PXMmJm8uZWRnZV9iZWZvcmU9PT12b2lkIDAmJm8uZWRnZV9hZnRlciE9PXZvaWQgMCYmby5wdC5lcXVhbFRvKHMucHQpJiYocy5lZGdlX2JlZm9yZS5uZXh0PW8uZWRnZV9hZnRlcixvLmVkZ2VfYWZ0ZXIucHJldj1zLmVkZ2VfYmVmb3JlLHMuZWRnZV9hZnRlcj1vLmVkZ2VfYWZ0ZXIsby5lZGdlX2JlZm9yZT1zLmVkZ2VfYmVmb3JlKX19ZnVuY3Rpb24gVGkoZSx0KXtmb3IobGV0IG4gb2YgdCllLmZhY2VzLmRlbGV0ZShuLmZhY2UpLG4uZmFjZT12b2lkIDAsbi5lZGdlX2JlZm9yZSYmKG4uZWRnZV9iZWZvcmUuZmFjZT12b2lkIDApLG4uZWRnZV9hZnRlciYmKG4uZWRnZV9hZnRlci5mYWNlPXZvaWQgMCl9ZnVuY3Rpb24gQWkoZSx0LG4pe2ZvcihsZXQgciBvZiB0KXtpZihyLmVkZ2VfYmVmb3JlPT09dm9pZCAwfHxyLmVkZ2VfYWZ0ZXI9PT12b2lkIDB8fHIuZmFjZXx8ci5lZGdlX2FmdGVyLmZhY2V8fHIuZWRnZV9iZWZvcmUuZmFjZSljb250aW51ZTtsZXQgaT1yLmVkZ2VfYWZ0ZXIscz1yLmVkZ2VfYmVmb3JlO3RyeXtoaS50ZXN0SW5maW5pdGVMb29wKGkpfWNhdGNoe3Rocm93IFkuQ0FOTk9UX0NPTVBMRVRFX0JPT0xFQU5fT1BFUkFUSU9OfWxldCBvPWUuYWRkRmFjZShpLHMpO2ZvcihsZXQgYyBvZiB0KWMuZWRnZV9iZWZvcmUmJmMuZWRnZV9hZnRlciYmYy5lZGdlX2JlZm9yZS5mYWNlPT09byYmYy5lZGdlX2FmdGVyLmZhY2U9PT1vJiYoYy5mYWNlPW8pO2ZvcihsZXQgYyBvZiBuKWMuZWRnZV9iZWZvcmUmJmMuZWRnZV9hZnRlciYmYy5lZGdlX2JlZm9yZS5mYWNlPT09byYmYy5lZGdlX2FmdGVyLmZhY2U9PT1vJiYoYy5mYWNlPW8pfX1mdW5jdGlvbiB5YShlLHQsbixyKXtmb3IobGV0IGkgb2YgdCl7bGV0IHM9aS5maXJzdC5idjsobj09PVhuJiZzPT09QXR8fG49PT1yZSYmcz09PUF0JiZyfHxuPT09cmUmJnM9PT1PdCYmIXJ8fG49PT1VZSYmcz09PU90KSYmZS5kZWxldGVGYWNlKGkpfX12YXIgWWU9T2JqZWN0LmZyZWV6ZSh7X19wcm90b19fOm51bGwsQk9PTEVBTl9JTlRFUlNFQ1Q6VWUsQk9PTEVBTl9TVUJUUkFDVDpyZSxCT09MRUFOX1VOSU9OOlhuLGNhbGN1bGF0ZUludGVyc2VjdGlvbnM6Z2EsaW5uZXJDbGlwOmRhLGludGVyc2VjdDp1YSxvdXRlckNsaXA6TWkscmVtb3ZlTm90UmVsZXZhbnRDaGFpbnM6d2kscmVtb3ZlT2xkRmFjZXM6VGkscmVzdG9yZUZhY2VzOkFpLHN1YnRyYWN0OnhpLHVuaWZ5OnlkfSk7Y29uc3QgT2Q9UmVnRXhwKCJULkYuLkZGRi58VC5GLi4uRi4uIiksdmQ9UmVnRXhwKCJULi4uLi4uLi58LlQuLi4uLi4ufC4uLlQuLi4uLnwuLi4uVC4uLi4iKSxFZD1SZWdFeHAoIkZULi4uLi4uLnxGLi5ULi4uLi58Ri4uLlQuLi4uIiksYmQ9UmVnRXhwKCJULkYuLkYuLi4iKSxTZD1SZWdFeHAoIlQuRi4uRi4uLnwuVEYuLkYuLi58Li5GVC5GLi4ufC4uRi5URi4uLiIpO2NsYXNzIHdle2NvbnN0cnVjdG9yKCl7dGhpcy5tPW5ldyBBcnJheSg5KS5maWxsKHZvaWQgMCl9Z2V0IEkySSgpe3JldHVybiB0aGlzLm1bMF19c2V0IEkySSh0KXt0aGlzLm1bMF09dH1nZXQgSTJCKCl7cmV0dXJuIHRoaXMubVsxXX1zZXQgSTJCKHQpe3RoaXMubVsxXT10fWdldCBJMkUoKXtyZXR1cm4gdGhpcy5tWzJdfXNldCBJMkUodCl7dGhpcy5tWzJdPXR9Z2V0IEIySSgpe3JldHVybiB0aGlzLm1bM119c2V0IEIySSh0KXt0aGlzLm1bM109dH1nZXQgQjJCKCl7cmV0dXJuIHRoaXMubVs0XX1zZXQgQjJCKHQpe3RoaXMubVs0XT10fWdldCBCMkUoKXtyZXR1cm4gdGhpcy5tWzVdfXNldCBCMkUodCl7dGhpcy5tWzVdPXR9Z2V0IEUySSgpe3JldHVybiB0aGlzLm1bNl19c2V0IEUySSh0KXt0aGlzLm1bNl09dH1nZXQgRTJCKCl7cmV0dXJuIHRoaXMubVs3XX1zZXQgRTJCKHQpe3RoaXMubVs3XT10fWdldCBFMkUoKXtyZXR1cm4gdGhpcy5tWzhdfXNldCBFMkUodCl7dGhpcy5tWzhdPXR9dG9TdHJpbmcoKXtyZXR1cm4gdGhpcy5tLm1hcCh0PT50IGluc3RhbmNlb2YgQXJyYXkmJnQubGVuZ3RoPjA/IlQiOnQgaW5zdGFuY2VvZiBBcnJheSYmdC5sZW5ndGg9PT0wPyJGIjoiKiIpLmpvaW4oIiIpfWVxdWFsKCl7cmV0dXJuIE9kLnRlc3QodGhpcy50b1N0cmluZygpKX1pbnRlcnNlY3QoKXtyZXR1cm4gdmQudGVzdCh0aGlzLnRvU3RyaW5nKCkpfXRvdWNoKCl7cmV0dXJuIEVkLnRlc3QodGhpcy50b1N0cmluZygpKX1pbnNpZGUoKXtyZXR1cm4gYmQudGVzdCh0aGlzLnRvU3RyaW5nKCkpfWNvdmVyZWQoKXtyZXR1cm4gU2QudGVzdCh0aGlzLnRvU3RyaW5nKCkpfX1mdW5jdGlvbiBXZShlLHQpe2xldCBuLHI9bmV3IGwuUmF5KHQpLGk9bmV3IGwuTGluZShyLnB0LHIubm9ybSk7Y29uc3Qgcz1uZXcgbC5Cb3goci5ib3gueG1pbi1sLkRQX1RPTCxyLmJveC55bWluLWwuRFBfVE9MLHIuYm94LnhtYXgrbC5EUF9UT0wsci5ib3gueW1heCtsLkRQX1RPTCk7aWYoZS5ib3gubm90X2ludGVyc2VjdChzKSlyZXR1cm4gbC5PVVRTSURFO2xldCBvPWUuZWRnZXMuc2VhcmNoKHMpO2lmKG8ubGVuZ3RoPT09MClyZXR1cm4gbC5PVVRTSURFO2ZvcihsZXQgZiBvZiBvKWlmKGYuc2hhcGUuY29udGFpbnModCkpcmV0dXJuIGwuQk9VTkRBUlk7bGV0IGM9Wy4uLmUuZmFjZXNdLGE9W107Zm9yKGxldCBmIG9mIG8pZm9yKGxldCB1IG9mIHIuaW50ZXJzZWN0KGYuc2hhcGUpKXtpZih1LmVxdWFsVG8odCkpcmV0dXJuIGwuQk9VTkRBUlk7YS5wdXNoKHtwdDp1LGVkZ2U6ZixmYWNlX2luZGV4OmMuaW5kZXhPZihmLmZhY2UpfSl9YS5zb3J0KChmLHUpPT5YYyhmLnB0LngsdS5wdC54KT8tMTpaYyhmLnB0LngsdS5wdC54KT8xOmYuZmFjZV9pbmRleDx1LmZhY2VfaW5kZXg/LTE6Zi5mYWNlX2luZGV4PnUuZmFjZV9pbmRleD8xOmYuZWRnZS5hcmNfbGVuZ3RoPHUuZWRnZS5hcmNfbGVuZ3RoPy0xOmYuZWRnZS5hcmNfbGVuZ3RoPnUuZWRnZS5hcmNfbGVuZ3RoPzE6MCk7bGV0IGg9MDtmb3IobGV0IGY9MDtmPGEubGVuZ3RoO2YrKyl7bGV0IHU9YVtmXTtpZih1LnB0LmVxdWFsVG8odS5lZGdlLnNoYXBlLnN0YXJ0KSl7aWYoZj4wJiZ1LnB0LmVxdWFsVG8oYVtmLTFdLnB0KSYmdS5mYWNlX2luZGV4PT09YVtmLTFdLmZhY2VfaW5kZXgmJnUuZWRnZS5wcmV2PT09YVtmLTFdLmVkZ2UpY29udGludWU7bGV0IGQ9dS5lZGdlLnByZXY7Zm9yKDtsaShkLmxlbmd0aCk7KWQ9ZC5wcmV2O2xldCBnPWQuc2hhcGUudGFuZ2VudEluRW5kKCksbT11LnB0LnRyYW5zbGF0ZShnKSxfPXUuZWRnZS5zaGFwZS50YW5nZW50SW5TdGFydCgpLHA9dS5wdC50cmFuc2xhdGUoXykseD1tLmxlZnRUbyhpKSxUPXAubGVmdFRvKGkpOyh4JiYhVHx8IXgmJlQpJiZoKyt9ZWxzZSBpZih1LnB0LmVxdWFsVG8odS5lZGdlLnNoYXBlLmVuZCkpe2lmKGY+MCYmdS5wdC5lcXVhbFRvKGFbZi0xXS5wdCkmJnUuZmFjZV9pbmRleD09PWFbZi0xXS5mYWNlX2luZGV4JiZ1LmVkZ2UubmV4dD09PWFbZi0xXS5lZGdlKWNvbnRpbnVlO2xldCBkPXUuZWRnZS5uZXh0O2Zvcig7bGkoZC5sZW5ndGgpOylkPWQubmV4dDtsZXQgZz1kLnNoYXBlLnRhbmdlbnRJblN0YXJ0KCksbT11LnB0LnRyYW5zbGF0ZShnKSxfPXUuZWRnZS5zaGFwZS50YW5nZW50SW5FbmQoKSxwPXUucHQudHJhbnNsYXRlKF8pLHg9bS5sZWZ0VG8oaSksVD1wLmxlZnRUbyhpKTsoeCYmIVR8fCF4JiZUKSYmaCsrfWVsc2UgaWYodS5lZGdlLnNoYXBlIGluc3RhbmNlb2YgbC5TZWdtZW50KWgrKztlbHNle2xldCBkPXUuZWRnZS5zaGFwZS5ib3g7SnQodS5wdC55LGQueW1pbil8fEp0KHUucHQueSxkLnltYXgpfHxoKyt9fXJldHVybiBuPWglMj09PTE/VW46RGMsbn1mdW5jdGlvbiBJZChlLHQpe3JldHVybiBUZShlLHQpLmVxdWFsKCl9ZnVuY3Rpb24geGEoZSx0KXtyZXR1cm4gVGUoZSx0KS5pbnRlcnNlY3QoKX1mdW5jdGlvbiBQZChlLHQpe3JldHVybiBUZShlLHQpLnRvdWNoKCl9ZnVuY3Rpb24gTGQoZSx0KXtyZXR1cm4heGEoZSx0KX1mdW5jdGlvbiBNYShlLHQpe3JldHVybiBUZShlLHQpLmluc2lkZSgpfWZ1bmN0aW9uIHdhKGUsdCl7cmV0dXJuIFRlKGUsdCkuY292ZXJlZCgpfWZ1bmN0aW9uIFJkKGUsdCl7cmV0dXJuIE1hKHQsZSl9ZnVuY3Rpb24gVGEoZSx0KXtyZXR1cm4gd2EodCxlKX1mdW5jdGlvbiBUZShlLHQpe2lmKGUgaW5zdGFuY2VvZiBsLkxpbmUmJnQgaW5zdGFuY2VvZiBsLkxpbmUpcmV0dXJuICRkKGUsdCk7aWYoZSBpbnN0YW5jZW9mIGwuTGluZSYmdCBpbnN0YW5jZW9mIGwuQ2lyY2xlKXJldHVybiBDZChlLHQpO2lmKGUgaW5zdGFuY2VvZiBsLkxpbmUmJnQgaW5zdGFuY2VvZiBsLkJveClyZXR1cm4gVmQoZSx0KTtpZihlIGluc3RhbmNlb2YgbC5MaW5lJiZ0IGluc3RhbmNlb2YgbC5Qb2x5Z29uKXJldHVybiBOZChlLHQpO2lmKChlIGluc3RhbmNlb2YgbC5TZWdtZW50fHxlIGluc3RhbmNlb2YgbC5BcmMpJiZ0IGluc3RhbmNlb2YgbC5Qb2x5Z29uKXJldHVybiBBYShlLHQpO2lmKChlIGluc3RhbmNlb2YgbC5TZWdtZW50fHxlIGluc3RhbmNlb2YgbC5BcmMpJiYodCBpbnN0YW5jZW9mIGwuQ2lyY2xlfHx0IGluc3RhbmNlb2YgbC5Cb3gpKXJldHVybiBBYShlLG5ldyBsLlBvbHlnb24odCkpO2lmKGUgaW5zdGFuY2VvZiBsLlBvbHlnb24mJnQgaW5zdGFuY2VvZiBsLlBvbHlnb24pcmV0dXJuIEduKGUsdCk7aWYoKGUgaW5zdGFuY2VvZiBsLkNpcmNsZXx8ZSBpbnN0YW5jZW9mIGwuQm94KSYmKHQgaW5zdGFuY2VvZiBsLkNpcmNsZXx8dCBpbnN0YW5jZW9mIGwuQm94KSlyZXR1cm4gR24obmV3IGwuUG9seWdvbihlKSxuZXcgbC5Qb2x5Z29uKHQpKTtpZigoZSBpbnN0YW5jZW9mIGwuQ2lyY2xlfHxlIGluc3RhbmNlb2YgbC5Cb3gpJiZ0IGluc3RhbmNlb2YgbC5Qb2x5Z29uKXJldHVybiBHbihuZXcgbC5Qb2x5Z29uKGUpLHQpO2lmKGUgaW5zdGFuY2VvZiBsLlBvbHlnb24mJih0IGluc3RhbmNlb2YgbC5DaXJjbGV8fHQgaW5zdGFuY2VvZiBsLkJveCkpcmV0dXJuIEduKGUsbmV3IGwuUG9seWdvbih0KSl9ZnVuY3Rpb24gJGQoZSx0KXtsZXQgbj1uZXcgd2Uscj1nZShlLHQpO3JldHVybiByLmxlbmd0aD09PTA/ZS5jb250YWlucyh0LnB0KSYmdC5jb250YWlucyhlLnB0KT8obi5JMkk9W2VdLG4uSTJFPVtdLG4uRTJJPVtdKToobi5JMkk9W10sbi5JMkU9W2VdLG4uRTJJPVt0XSk6KG4uSTJJPXIsbi5JMkU9ZS5zcGxpdChyKSxuLkUyST10LnNwbGl0KHIpKSxufWZ1bmN0aW9uIENkKGUsdCl7bGV0IG49bmV3IHdlLHI9ZWUoZSx0KTtpZihyLmxlbmd0aD09PTApbi5JMkk9W10sbi5JMkI9W10sbi5JMkU9W2VdLG4uRTJJPVt0XTtlbHNlIGlmKHIubGVuZ3RoPT09MSluLkkyST1bXSxuLkkyQj1yLG4uSTJFPWUuc3BsaXQociksbi5FMkk9W3RdO2Vsc2V7bGV0IGk9bmV3IG5lKFtlXSkscz1lLnNvcnRQb2ludHMocik7aS5zcGxpdChzKTtsZXQgbz1pLnRvU2hhcGVzKCk7bi5JMkk9W29bMV1dLG4uSTJCPXMsbi5JMkU9W29bMF0sb1syXV0sbi5FMkk9bmV3IGwuUG9seWdvbihbdC50b0FyYygpXSkuY3V0V2l0aExpbmUoZSl9cmV0dXJuIG59ZnVuY3Rpb24gVmQoZSx0KXtsZXQgbj1uZXcgd2Uscj1tZShlLHQpO2lmKHIubGVuZ3RoPT09MCluLkkyST1bXSxuLkkyQj1bXSxuLkkyRT1bZV0sbi5FMkk9W3RdO2Vsc2UgaWYoci5sZW5ndGg9PT0xKW4uSTJJPVtdLG4uSTJCPXIsbi5JMkU9ZS5zcGxpdChyKSxuLkUyST1bdF07ZWxzZXtsZXQgaT1uZXcgbmUoW2VdKSxzPWUuc29ydFBvaW50cyhyKTtpLnNwbGl0KHMpO2xldCBvPWkudG9TaGFwZXMoKTt0LnRvU2VnbWVudHMoKS5zb21lKGM9PmMuY29udGFpbnMoclswXSkmJmMuY29udGFpbnMoclsxXSkpPyhuLkkyST1bXSxuLkkyQj1bb1sxXV0sbi5JMkU9W29bMF0sb1syXV0sbi5FMkk9W3RdKToobi5JMkk9W29bMV1dLG4uSTJCPXMsbi5JMkU9W29bMF0sb1syXV0sbi5FMkk9bmV3IGwuUG9seWdvbih0LnRvU2VnbWVudHMoKSkuY3V0V2l0aExpbmUoZSkpfXJldHVybiBufWZ1bmN0aW9uIE5kKGUsdCl7bGV0IG49bmV3IHdlLHI9a2UoZSx0KSxpPW5ldyBuZShbZV0pLHM9ci5sZW5ndGg+MD9yLnNsaWNlKCk6ZS5zb3J0UG9pbnRzKHIpO3JldHVybiBpLnNwbGl0KHMpLFsuLi5pXS5mb3JFYWNoKG89Pm8uc2V0SW5jbHVzaW9uKHQpKSxuLkkyST1bLi4uaV0uZmlsdGVyKG89Pm8uYnY9PT1sLklOU0lERSkubWFwKG89Pm8uc2hhcGUpLG4uSTJCPVsuLi5pXS5zbGljZSgxKS5tYXAobz0+by5idj09PWwuQk9VTkRBUlk/by5zaGFwZTpvLnNoYXBlLnN0YXJ0KSxuLkkyRT1bLi4uaV0uZmlsdGVyKG89Pm8uYnY9PT1sLk9VVFNJREUpLm1hcChvPT5vLnNoYXBlKSxuLkUyST10LmN1dFdpdGhMaW5lKGUpLG59ZnVuY3Rpb24gQWEoZSx0KXtsZXQgbj1uZXcgd2Uscj1sZChlLHQpLGk9ci5sZW5ndGg+MD9yLnNsaWNlKCk6ZS5zb3J0UG9pbnRzKHIpLHM9bmV3IG5lKFtlXSk7cy5zcGxpdChpKSxbLi4uc10uZm9yRWFjaChvPT5vLnNldEluY2x1c2lvbih0KSksbi5JMkk9Wy4uLnNdLmZpbHRlcihvPT5vLmJ2PT09bC5JTlNJREUpLm1hcChvPT5vLnNoYXBlKSxuLkkyQj1bLi4uc10uc2xpY2UoMSkubWFwKG89Pm8uYnY9PT1sLkJPVU5EQVJZP28uc2hhcGU6by5zaGFwZS5zdGFydCksbi5JMkU9Wy4uLnNdLmZpbHRlcihvPT5vLmJ2PT09bC5PVVRTSURFKS5tYXAobz0+by5zaGFwZSksbi5CMkk9W10sbi5CMkI9W10sbi5CMkU9W107Zm9yKGxldCBvIG9mW2Uuc3RhcnQsZS5lbmRdKXN3aXRjaChXZSh0LG8pKXtjYXNlIGwuSU5TSURFOm4uQjJJLnB1c2gobyk7YnJlYWs7Y2FzZSBsLkJPVU5EQVJZOm4uQjJCLnB1c2gobyk7YnJlYWs7Y2FzZSBsLk9VVFNJREU6bi5CMkUucHVzaChvKTticmVha31yZXR1cm4gbn1mdW5jdGlvbiBHbihlLHQpe2xldCBuPW5ldyB3ZSxbcixpXT1nYShlLHQpLHM9dWEoZSx0KSxvPXhpKGUsdCksYz14aSh0LGUpLFthLGhdPWRhKGUsdCksZj1NaShlLHQpLHU9TWkodCxlKTtyZXR1cm4gbi5JMkk9cy5pc0VtcHR5KCk/W106W3NdLG4uSTJCPWgsbi5JMkU9by5pc0VtcHR5KCk/W106W29dLG4uQjJJPWEsbi5CMkI9cixuLkIyRT1mLG4uRTJJPWMuaXNFbXB0eSgpP1tdOltjXSxuLkUyQj11LG59dmFyIHpkPU9iamVjdC5mcmVlemUoe19fcHJvdG9fXzpudWxsLGNvbnRhaW46UmQsY292ZXI6VGEsY292ZXJlZDp3YSxkaXNqb2ludDpMZCxlcXVhbDpJZCxpbnNpZGU6TWEsaW50ZXJzZWN0OnhhLHJlbGF0ZTpUZSx0b3VjaDpQZH0pO2NsYXNzIGZ0e2NvbnN0cnVjdG9yKHQ9MSxuPTAscj0wLGk9MSxzPTAsbz0wKXt0aGlzLmE9dCx0aGlzLmI9bix0aGlzLmM9cix0aGlzLmQ9aSx0aGlzLnR4PXMsdGhpcy50eT1vfWZyb21NYXRyaXgzeDModCl7Y29uc3RbbixyLGldPXRbMF0sW3MsbyxjXT10WzFdO3JldHVybiBuZXcgZnQobixzLHIsbyxpLGMpfXRvTWF0cml4M3gzKCl7cmV0dXJuW1t0aGlzLmEsdGhpcy5jLHRoaXMudHhdLFt0aGlzLmIsdGhpcy5kLHRoaXMudHldLFswLDAsMV1dfWNsb25lKCl7cmV0dXJuIG5ldyBmdCh0aGlzLmEsdGhpcy5iLHRoaXMuYyx0aGlzLmQsdGhpcy50eCx0aGlzLnR5KX10cmFuc2Zvcm0odCl7cmV0dXJuW3RbMF0qdGhpcy5hK3RbMV0qdGhpcy5jK3RoaXMudHgsdFswXSp0aGlzLmIrdFsxXSp0aGlzLmQrdGhpcy50eV19bXVsdGlwbHkodCl7cmV0dXJuIG5ldyBmdCh0aGlzLmEqdC5hK3RoaXMuYyp0LmIsdGhpcy5iKnQuYSt0aGlzLmQqdC5iLHRoaXMuYSp0LmMrdGhpcy5jKnQuZCx0aGlzLmIqdC5jK3RoaXMuZCp0LmQsdGhpcy5hKnQudHgrdGhpcy5jKnQudHkrdGhpcy50eCx0aGlzLmIqdC50eCt0aGlzLmQqdC50eSt0aGlzLnR5KX10cmFuc2xhdGUoLi4udCl7bGV0IG4scjtpZih0Lmxlbmd0aD09MSYmIWlzTmFOKHRbMF0ueCkmJiFpc05hTih0WzBdLnkpKW49dFswXS54LHI9dFswXS55O2Vsc2UgaWYodC5sZW5ndGg9PT0yJiZ0eXBlb2YgdFswXT09Im51bWJlciImJnR5cGVvZiB0WzFdPT0ibnVtYmVyIiluPXRbMF0scj10WzFdO2Vsc2UgdGhyb3cgWS5JTExFR0FMX1BBUkFNRVRFUlM7cmV0dXJuIHRoaXMubXVsdGlwbHkobmV3IGZ0KDEsMCwwLDEsbixyKSl9cm90YXRlKHQsbj0wLHI9MCl7bGV0IGk9TWF0aC5jb3ModCkscz1NYXRoLnNpbih0KTtyZXR1cm4gdGhpcy50cmFuc2xhdGUobixyKS5tdWx0aXBseShuZXcgZnQoaSxzLC1zLGksMCwwKSkudHJhbnNsYXRlKC1uLC1yKX1zY2FsZSh0LG4pe3JldHVybiB0aGlzLm11bHRpcGx5KG5ldyBmdCh0LDAsMCxuLDAsMCkpfWVxdWFsVG8odCl7cmV0dXJuISghbC5VdGlscy5FUSh0aGlzLnR4LHQudHgpfHwhbC5VdGlscy5FUSh0aGlzLnR5LHQudHkpfHwhbC5VdGlscy5FUSh0aGlzLmEsdC5hKXx8IWwuVXRpbHMuRVEodGhpcy5iLHQuYil8fCFsLlV0aWxzLkVRKHRoaXMuYyx0LmMpfHwhbC5VdGlscy5FUSh0aGlzLmQsdC5kKSl9fWwuTWF0cml4PWZ0O2NvbnN0IHFkPSguLi5lKT0+bmV3IGwuTWF0cml4KC4uLmUpO2wubWF0cml4PXFkO2NsYXNzIEZke2NvbnN0cnVjdG9yKHQsbil7dGhpcy5sb3c9dCx0aGlzLmhpZ2g9bn1nZXQgbWF4KCl7cmV0dXJuIHRoaXMuY2xvbmUoKX1sZXNzX3RoYW4odCl7cmV0dXJuIHRoaXMubG93PHQubG93fHx0aGlzLmxvdz09PXQubG93JiZ0aGlzLmhpZ2g8dC5oaWdofWVxdWFsX3RvKHQpe3JldHVybiB0aGlzLmxvdz09PXQubG93JiZ0aGlzLmhpZ2g9PT10LmhpZ2h9aW50ZXJzZWN0KHQpe3JldHVybiF0aGlzLm5vdF9pbnRlcnNlY3QodCl9bm90X2ludGVyc2VjdCh0KXtyZXR1cm4gdGhpcy5oaWdoPHQubG93fHx0LmhpZ2g8dGhpcy5sb3d9bWVyZ2UodCl7Y29uc3Qgbj10aGlzLmxvdz09PXZvaWQgMD90Lmxvdzp0aGlzLmxvdzx0Lmxvdz90aGlzLmxvdzp0LmxvdyxyPXRoaXMuaGlnaD09PXZvaWQgMD90LmhpZ2g6dGhpcy5oaWdoPnQuaGlnaD90aGlzLmhpZ2g6dC5oaWdoLGk9dGhpcy5jbG9uZSgpO3JldHVybiBpLmxvdz1uLGkuaGlnaD1yLGl9b3V0cHV0KCl7cmV0dXJuW3RoaXMubG93LHRoaXMuaGlnaF19Y29tcGFyYWJsZV9sZXNzX3RoYW4odCxuKXtyZXR1cm4gdDxufX1jbGFzcyBPaSBleHRlbmRzIEZke2Nsb25lKCl7cmV0dXJuIG5ldyBPaSh0aGlzLmxvdyx0aGlzLmhpZ2gpfX1jb25zdCB0dD0xLHE9MDtjbGFzcyBVdHtjb25zdHJ1Y3Rvcih0LG4scj1udWxsLGk9bnVsbCxzPW51bGwsbz1xKXtpZih0aGlzLmxlZnQ9cix0aGlzLnJpZ2h0PWksdGhpcy5wYXJlbnQ9cyx0aGlzLmNvbG9yPW8sdGhpcy5pdGVtPXtrZXk6dm9pZCAwLHZhbHVlczpbXX0sbiE9PXZvaWQgMCYmdGhpcy5pdGVtLnZhbHVlcy5wdXNoKG4pLHQhPT12b2lkIDApaWYoQXJyYXkuaXNBcnJheSh0KSl7Y29uc3RbYyxhXT10O2lmKCFOdW1iZXIuaXNOYU4oYykmJiFOdW1iZXIuaXNOYU4oYSkpe2xldCBoPWMsZj1hO2g+ZiYmKFtoLGZdPVtmLGhdKSx0aGlzLml0ZW0ua2V5PW5ldyBPaShoLGYpfX1lbHNlIHRoaXMuaXRlbS5rZXk9dDt0aGlzLm1heD10aGlzLml0ZW0ua2V5P3RoaXMuaXRlbS5rZXkubWF4OnZvaWQgMH1pc05pbCgpe3JldHVybiB0aGlzLml0ZW0ua2V5PT09dm9pZCAwJiZ0aGlzLml0ZW0udmFsdWVzLmxlbmd0aD09PTAmJnRoaXMubGVmdD09PW51bGwmJnRoaXMucmlnaHQ9PT1udWxsJiZ0aGlzLmNvbG9yPT09cX1yZXF1aXJlS2V5KCl7aWYoIXRoaXMuaXRlbS5rZXkpdGhyb3cgbmV3IEVycm9yKCJOb2RlIGtleSBpcyB1bmRlZmluZWQgKG5pbC9zZW50aW5lbCkuIE9wZXJhdGlvbiBpcyBub3QgYXBwbGljYWJsZS4iKTtyZXR1cm4gdGhpcy5pdGVtLmtleX1sZXNzX3RoYW4odCl7Y29uc3Qgbj10aGlzLnJlcXVpcmVLZXkoKSxyPXQucmVxdWlyZUtleSgpO3JldHVybiBuLmxlc3NfdGhhbihyKX1fdmFsdWVfZXF1YWwodCl7Y29uc3Qgbj10aGlzLml0ZW0udmFsdWVzWzBdLHI9dC5pdGVtLnZhbHVlc1swXTtyZXR1cm4gbiYmciYmbi5lcXVhbF90bz9uLmVxdWFsX3RvKHIpOm49PT1yfWVxdWFsX3RvKHQpe2NvbnN0IG49dGhpcy5yZXF1aXJlS2V5KCkscj10LnJlcXVpcmVLZXkoKTtyZXR1cm4gbi5lcXVhbF90byhyKX1pbnRlcnNlY3QodCl7Y29uc3Qgbj10aGlzLnJlcXVpcmVLZXkoKSxyPXQucmVxdWlyZUtleSgpO3JldHVybiBuLmludGVyc2VjdChyKX1jb3B5X2RhdGEodCl7dGhpcy5pdGVtLmtleT10Lml0ZW0ua2V5LHRoaXMuaXRlbS52YWx1ZXM9dC5pdGVtLnZhbHVlcy5zbGljZSgpfXVwZGF0ZV9tYXgoKXt0aGlzLm1heD10aGlzLml0ZW0ua2V5P3RoaXMuaXRlbS5rZXkubWF4OnZvaWQgMCx0aGlzLnJpZ2h0JiZ0aGlzLnJpZ2h0Lm1heCYmKHRoaXMubWF4PXRoaXMubWF4P3RoaXMubWF4Lm1lcmdlKHRoaXMucmlnaHQubWF4KTp0aGlzLnJpZ2h0Lm1heCksdGhpcy5sZWZ0JiZ0aGlzLmxlZnQubWF4JiYodGhpcy5tYXg9dGhpcy5tYXg/dGhpcy5tYXgubWVyZ2UodGhpcy5sZWZ0Lm1heCk6dGhpcy5sZWZ0Lm1heCl9bm90X2ludGVyc2VjdF9sZWZ0X3N1YnRyZWUodCl7aWYoIXRoaXMubGVmdClyZXR1cm4hMDtjb25zdCBuPXRoaXMubGVmdC5tYXg/dGhpcy5sZWZ0Lm1heC5oaWdoOnRoaXMubGVmdC5pdGVtLmtleS5oaWdoLHI9dGhpcy5yZXF1aXJlS2V5KCksaT10LnJlcXVpcmVLZXkoKTtyZXR1cm4gci5jb21wYXJhYmxlX2xlc3NfdGhhbihuLGkubG93KX1ub3RfaW50ZXJzZWN0X3JpZ2h0X3N1YnRyZWUodCl7aWYoIXRoaXMucmlnaHQpcmV0dXJuITA7Y29uc3Qgbj10aGlzLnJpZ2h0Lm1heD90aGlzLnJpZ2h0Lm1heC5sb3c6dGhpcy5yaWdodC5pdGVtLmtleS5sb3cscj10aGlzLnJlcXVpcmVLZXkoKSxpPXQucmVxdWlyZUtleSgpO3JldHVybiByLmNvbXBhcmFibGVfbGVzc190aGFuKGkuaGlnaCxuKX19Y2xhc3MgWmV7Y29uc3RydWN0b3IoKXt0aGlzLnJvb3Q9bnVsbCx0aGlzLm5pbF9ub2RlPW5ldyBVdH1nZXQgc2l6ZSgpe2xldCB0PTA7cmV0dXJuIHRoaXMudHJlZV93YWxrKHRoaXMucm9vdCxuPT50Kz1uLml0ZW0udmFsdWVzLmxlbmd0aCksdH1nZXQga2V5cygpe2NvbnN0IHQ9W107cmV0dXJuIHRoaXMudHJlZV93YWxrKHRoaXMucm9vdCxuPT50LnB1c2gobi5pdGVtLmtleS5vdXRwdXQoKSkpLHR9Z2V0IHZhbHVlcygpe2NvbnN0IHQ9W107cmV0dXJuIHRoaXMudHJlZV93YWxrKHRoaXMucm9vdCxuPT57Zm9yKGNvbnN0IHIgb2Ygbi5pdGVtLnZhbHVlcyl0LnB1c2gocil9KSx0fWdldCBpdGVtcygpe2NvbnN0IHQ9W107cmV0dXJuIHRoaXMudHJlZV93YWxrKHRoaXMucm9vdCxuPT57Y29uc3Qgcj1uLml0ZW0ua2V5Lm91dHB1dCgpO2Zvcihjb25zdCBpIG9mIG4uaXRlbS52YWx1ZXMpdC5wdXNoKHtrZXk6cix2YWx1ZTppfSl9KSx0fWlzRW1wdHkoKXtyZXR1cm4gdGhpcy5yb290PT1udWxsfHx0aGlzLnJvb3Q9PT10aGlzLm5pbF9ub2RlfWNsZWFyKCl7dGhpcy5yb290PW51bGx9aW5zZXJ0KHQsbj10KXtpZih0PT09dm9pZCAwKXJldHVybjtjb25zdCByPXRoaXMudHJlZV9zZWFyY2godGhpcy5yb290LG5ldyBVdCh0KSk7aWYocilyZXR1cm4gci5pdGVtLnZhbHVlcy5wdXNoKG4pLHI7Y29uc3QgaT1uZXcgVXQodCxuLHRoaXMubmlsX25vZGUsdGhpcy5uaWxfbm9kZSxudWxsLHR0KTtyZXR1cm4gdGhpcy50cmVlX2luc2VydChpKSx0aGlzLnJlY2FsY19tYXgoaSksaX1leGlzdCh0LG49dCl7Y29uc3Qgcj10aGlzLnRyZWVfc2VhcmNoKHRoaXMucm9vdCxuZXcgVXQodCkpO3JldHVybiByP2FyZ3VtZW50cy5sZW5ndGg8Mnx8bj09PXQ/ITA6ci5pdGVtLnZhbHVlcy5zb21lKGk9PmkmJmkuZXF1YWxfdG8/aS5lcXVhbF90byhuKTppPT09bik6ITF9cmVtb3ZlKHQsbj10KXtjb25zdCByPXRoaXMudHJlZV9zZWFyY2godGhpcy5yb290LG5ldyBVdCh0KSk7aWYoIXIpcmV0dXJuO2lmKGFyZ3VtZW50cy5sZW5ndGg8MilyZXR1cm4gdGhpcy50cmVlX2RlbGV0ZShyKSxyO2NvbnN0IGk9ci5pdGVtLnZhbHVlcy5maW5kSW5kZXgocz0+cyYmcy5lcXVhbF90bz9zLmVxdWFsX3RvKG4pOnM9PT1uKTtpZihpPj0wKXJldHVybiByLml0ZW0udmFsdWVzLnNwbGljZShpLDEpLHIuaXRlbS52YWx1ZXMubGVuZ3RoPT09MCYmdGhpcy50cmVlX2RlbGV0ZShyKSxyfXNlYXJjaCh0LG49KHIsaSk9PnI9PT1pP2kub3V0cHV0KCk6cil7Y29uc3Qgcj1uZXcgVXQodCksaT1bXTt0aGlzLnRyZWVfc2VhcmNoX2ludGVydmFsKHRoaXMucm9vdCxyLGkpO2NvbnN0IHM9W107Zm9yKGNvbnN0IG8gb2YgaSlmb3IoY29uc3QgYyBvZiBvLml0ZW0udmFsdWVzKXMucHVzaChuKGMsby5pdGVtLmtleSkpO3JldHVybiBzfWludGVyc2VjdF9hbnkodCl7Y29uc3Qgbj1uZXcgVXQodCk7cmV0dXJuIHRoaXMudHJlZV9maW5kX2FueV9pbnRlcnZhbCh0aGlzLnJvb3Qsbil9Zm9yRWFjaCh0KXt0aGlzLnRyZWVfd2Fsayh0aGlzLnJvb3Qsbj0+e2Zvcihjb25zdCByIG9mIG4uaXRlbS52YWx1ZXMpdChuLml0ZW0ua2V5LHIpfSl9bWFwKHQpe2NvbnN0IG49bmV3IFplO3JldHVybiB0aGlzLnRyZWVfd2Fsayh0aGlzLnJvb3Qscj0+e2Zvcihjb25zdCBpIG9mIHIuaXRlbS52YWx1ZXMpbi5pbnNlcnQoci5pdGVtLmtleSx0KGksci5pdGVtLmtleSkpfSksbn0qaXRlcmF0ZSh0LG49KHIsaSk9PnI9PT1pP2kub3V0cHV0KCk6cil7bGV0IHI9bnVsbDtmb3IodD9yPXRoaXMudHJlZV9zZWFyY2hfbmVhcmVzdF9mb3J3YXJkKHRoaXMucm9vdCxuZXcgVXQodCkpOnRoaXMucm9vdCYmKHI9dGhpcy5sb2NhbF9taW5pbXVtKHRoaXMucm9vdCkpO3I7KXtmb3IoY29uc3QgaSBvZiByLml0ZW0udmFsdWVzKXlpZWxkIG4oaSxyLml0ZW0ua2V5KTtyPXRoaXMudHJlZV9zdWNjZXNzb3Iocil9fXJlY2FsY19tYXgodCl7bGV0IG49dDtmb3IoO24ucGFyZW50IT1udWxsOyluLnBhcmVudC51cGRhdGVfbWF4KCksbj1uLnBhcmVudH10cmVlX2luc2VydCh0KXtsZXQgbj10aGlzLnJvb3Qscj1udWxsO2lmKHRoaXMucm9vdD09bnVsbHx8dGhpcy5yb290PT09dGhpcy5uaWxfbm9kZSl0aGlzLnJvb3Q9dDtlbHNle2Zvcig7biE9PXRoaXMubmlsX25vZGU7KXI9bix0Lmxlc3NfdGhhbihuKT9uPW4ubGVmdDpuPW4ucmlnaHQ7dC5wYXJlbnQ9cix0Lmxlc3NfdGhhbihyKT9yLmxlZnQ9dDpyLnJpZ2h0PXR9dGhpcy5pbnNlcnRfZml4dXAodCl9aW5zZXJ0X2ZpeHVwKHQpe2xldCBuLHI7Zm9yKG49dDtuIT09dGhpcy5yb290JiZuLnBhcmVudC5jb2xvcj09PXR0OyluLnBhcmVudD09PW4ucGFyZW50LnBhcmVudC5sZWZ0PyhyPW4ucGFyZW50LnBhcmVudC5yaWdodCxyLmNvbG9yPT09dHQ/KG4ucGFyZW50LmNvbG9yPXEsci5jb2xvcj1xLG4ucGFyZW50LnBhcmVudC5jb2xvcj10dCxuPW4ucGFyZW50LnBhcmVudCk6KG49PT1uLnBhcmVudC5yaWdodCYmKG49bi5wYXJlbnQsdGhpcy5yb3RhdGVfbGVmdChuKSksbi5wYXJlbnQuY29sb3I9cSxuLnBhcmVudC5wYXJlbnQuY29sb3I9dHQsdGhpcy5yb3RhdGVfcmlnaHQobi5wYXJlbnQucGFyZW50KSkpOihyPW4ucGFyZW50LnBhcmVudC5sZWZ0LHIuY29sb3I9PT10dD8obi5wYXJlbnQuY29sb3I9cSxyLmNvbG9yPXEsbi5wYXJlbnQucGFyZW50LmNvbG9yPXR0LG49bi5wYXJlbnQucGFyZW50KToobj09PW4ucGFyZW50LmxlZnQmJihuPW4ucGFyZW50LHRoaXMucm90YXRlX3JpZ2h0KG4pKSxuLnBhcmVudC5jb2xvcj1xLG4ucGFyZW50LnBhcmVudC5jb2xvcj10dCx0aGlzLnJvdGF0ZV9sZWZ0KG4ucGFyZW50LnBhcmVudCkpKTt0aGlzLnJvb3QuY29sb3I9cX10cmVlX2RlbGV0ZSh0KXtsZXQgbixyO3QubGVmdD09PXRoaXMubmlsX25vZGV8fHQucmlnaHQ9PT10aGlzLm5pbF9ub2RlP249dDpuPXRoaXMudHJlZV9zdWNjZXNzb3IodCksbi5sZWZ0IT09dGhpcy5uaWxfbm9kZT9yPW4ubGVmdDpyPW4ucmlnaHQsci5wYXJlbnQ9bi5wYXJlbnQsbj09PXRoaXMucm9vdD90aGlzLnJvb3Q9cjoobj09PW4ucGFyZW50LmxlZnQ/bi5wYXJlbnQubGVmdD1yOm4ucGFyZW50LnJpZ2h0PXIsbi5wYXJlbnQudXBkYXRlX21heCgpKSx0aGlzLnJlY2FsY19tYXgociksbiE9PXQmJih0LmNvcHlfZGF0YShuKSx0LnVwZGF0ZV9tYXgoKSx0aGlzLnJlY2FsY19tYXgodCkpLG4uY29sb3I9PT1xJiZ0aGlzLmRlbGV0ZV9maXh1cChyKX1kZWxldGVfZml4dXAodCl7bGV0IG49dCxyO2Zvcig7biE9PXRoaXMucm9vdCYmbi5wYXJlbnQhPW51bGwmJm4uY29sb3I9PT1xOyluPT09bi5wYXJlbnQubGVmdD8ocj1uLnBhcmVudC5yaWdodCxyLmNvbG9yPT09dHQmJihyLmNvbG9yPXEsbi5wYXJlbnQuY29sb3I9dHQsdGhpcy5yb3RhdGVfbGVmdChuLnBhcmVudCkscj1uLnBhcmVudC5yaWdodCksci5sZWZ0LmNvbG9yPT09cSYmci5yaWdodC5jb2xvcj09PXE/KHIuY29sb3I9dHQsbj1uLnBhcmVudCk6KHIucmlnaHQuY29sb3I9PT1xJiYoci5jb2xvcj10dCxyLmxlZnQuY29sb3I9cSx0aGlzLnJvdGF0ZV9yaWdodChyKSxyPW4ucGFyZW50LnJpZ2h0KSxyLmNvbG9yPW4ucGFyZW50LmNvbG9yLG4ucGFyZW50LmNvbG9yPXEsci5yaWdodC5jb2xvcj1xLHRoaXMucm90YXRlX2xlZnQobi5wYXJlbnQpLG49dGhpcy5yb290KSk6KHI9bi5wYXJlbnQubGVmdCxyLmNvbG9yPT09dHQmJihyLmNvbG9yPXEsbi5wYXJlbnQuY29sb3I9dHQsdGhpcy5yb3RhdGVfcmlnaHQobi5wYXJlbnQpLHI9bi5wYXJlbnQubGVmdCksci5sZWZ0LmNvbG9yPT09cSYmci5yaWdodC5jb2xvcj09PXE/KHIuY29sb3I9dHQsbj1uLnBhcmVudCk6KHIubGVmdC5jb2xvcj09PXEmJihyLmNvbG9yPXR0LHIucmlnaHQuY29sb3I9cSx0aGlzLnJvdGF0ZV9sZWZ0KHIpLHI9bi5wYXJlbnQubGVmdCksci5jb2xvcj1uLnBhcmVudC5jb2xvcixuLnBhcmVudC5jb2xvcj1xLHIubGVmdC5jb2xvcj1xLHRoaXMucm90YXRlX3JpZ2h0KG4ucGFyZW50KSxuPXRoaXMucm9vdCkpO24uY29sb3I9cX10cmVlX3NlYXJjaCh0LG4pe2lmKCEodD09bnVsbHx8dD09PXRoaXMubmlsX25vZGUpKXJldHVybiBuLmVxdWFsX3RvKHQpP3Q6bi5sZXNzX3RoYW4odCk/dGhpcy50cmVlX3NlYXJjaCh0LmxlZnQsbik6dGhpcy50cmVlX3NlYXJjaCh0LnJpZ2h0LG4pfXRyZWVfc2VhcmNoX25lYXJlc3RfZm9yd2FyZCh0LG4pe2xldCByPW51bGwsaT10O2Zvcig7aSYmaSE9PXRoaXMubmlsX25vZGU7KWkubGVzc190aGFuKG4pP2kuaW50ZXJzZWN0KG4pPyhyPWksaT1pLmxlZnQpOmk9aS5yaWdodDooKCFyfHxpLmxlc3NfdGhhbihyKSkmJihyPWkpLGk9aS5sZWZ0KTtyZXR1cm4gcnx8bnVsbH10cmVlX3NlYXJjaF9pbnRlcnZhbCh0LG4scil7dCE9bnVsbCYmdCE9PXRoaXMubmlsX25vZGUmJih0LmxlZnQhPT10aGlzLm5pbF9ub2RlJiYhdC5ub3RfaW50ZXJzZWN0X2xlZnRfc3VidHJlZShuKSYmdGhpcy50cmVlX3NlYXJjaF9pbnRlcnZhbCh0LmxlZnQsbixyKSx0LmludGVyc2VjdChuKSYmci5wdXNoKHQpLHQucmlnaHQhPT10aGlzLm5pbF9ub2RlJiYhdC5ub3RfaW50ZXJzZWN0X3JpZ2h0X3N1YnRyZWUobikmJnRoaXMudHJlZV9zZWFyY2hfaW50ZXJ2YWwodC5yaWdodCxuLHIpKX10cmVlX2ZpbmRfYW55X2ludGVydmFsKHQsbil7bGV0IHI9ITE7cmV0dXJuIHQhPW51bGwmJnQhPT10aGlzLm5pbF9ub2RlJiYodC5sZWZ0IT09dGhpcy5uaWxfbm9kZSYmIXQubm90X2ludGVyc2VjdF9sZWZ0X3N1YnRyZWUobikmJihyPXRoaXMudHJlZV9maW5kX2FueV9pbnRlcnZhbCh0LmxlZnQsbikpLHJ8fChyPXQuaW50ZXJzZWN0KG4pKSwhciYmdC5yaWdodCE9PXRoaXMubmlsX25vZGUmJiF0Lm5vdF9pbnRlcnNlY3RfcmlnaHRfc3VidHJlZShuKSYmKHI9dGhpcy50cmVlX2ZpbmRfYW55X2ludGVydmFsKHQucmlnaHQsbikpKSxyfWxvY2FsX21pbmltdW0odCl7bGV0IG49dDtmb3IoO24ubGVmdCE9bnVsbCYmbi5sZWZ0IT09dGhpcy5uaWxfbm9kZTspbj1uLmxlZnQ7cmV0dXJuIG59bG9jYWxfbWF4aW11bSh0KXtsZXQgbj10O2Zvcig7bi5yaWdodCE9bnVsbCYmbi5yaWdodCE9PXRoaXMubmlsX25vZGU7KW49bi5yaWdodDtyZXR1cm4gbn10cmVlX3N1Y2Nlc3Nvcih0KXtsZXQgbixyLGk7aWYodC5yaWdodCE9PXRoaXMubmlsX25vZGUpbj10aGlzLmxvY2FsX21pbmltdW0odC5yaWdodCk7ZWxzZXtmb3Iocj10LGk9dC5wYXJlbnQ7aSE9bnVsbCYmaS5yaWdodD09PXI7KXI9aSxpPWkucGFyZW50O249aX1yZXR1cm4gbn1yb3RhdGVfbGVmdCh0KXtjb25zdCBuPXQucmlnaHQ7dC5yaWdodD1uLmxlZnQsbi5sZWZ0IT09dGhpcy5uaWxfbm9kZSYmKG4ubGVmdC5wYXJlbnQ9dCksbi5wYXJlbnQ9dC5wYXJlbnQsdD09PXRoaXMucm9vdD90aGlzLnJvb3Q9bjp0PT09dC5wYXJlbnQubGVmdD90LnBhcmVudC5sZWZ0PW46dC5wYXJlbnQucmlnaHQ9bixuLmxlZnQ9dCx0LnBhcmVudD1uLHQhPT1udWxsJiZ0IT09dGhpcy5uaWxfbm9kZSYmdC51cGRhdGVfbWF4KCksbiE9bnVsbCYmbiE9PXRoaXMubmlsX25vZGUmJm4udXBkYXRlX21heCgpfXJvdGF0ZV9yaWdodCh0KXtjb25zdCBuPXQubGVmdDt0LmxlZnQ9bi5yaWdodCxuLnJpZ2h0IT09dGhpcy5uaWxfbm9kZSYmKG4ucmlnaHQucGFyZW50PXQpLG4ucGFyZW50PXQucGFyZW50LHQ9PT10aGlzLnJvb3Q/dGhpcy5yb290PW46dD09PXQucGFyZW50LmxlZnQ/dC5wYXJlbnQubGVmdD1uOnQucGFyZW50LnJpZ2h0PW4sbi5yaWdodD10LHQucGFyZW50PW4sdCE9PW51bGwmJnQhPT10aGlzLm5pbF9ub2RlJiZ0LnVwZGF0ZV9tYXgoKSxuIT1udWxsJiZuIT09dGhpcy5uaWxfbm9kZSYmbi51cGRhdGVfbWF4KCl9dHJlZV93YWxrKHQsbil7dCE9bnVsbCYmdCE9PXRoaXMubmlsX25vZGUmJih0aGlzLnRyZWVfd2Fsayh0LmxlZnQsbiksbih0KSx0aGlzLnRyZWVfd2Fsayh0LnJpZ2h0LG4pKX10ZXN0UmVkQmxhY2tQcm9wZXJ0eSgpe2xldCB0PSEwO3JldHVybiB0aGlzLnRyZWVfd2Fsayh0aGlzLnJvb3QsZnVuY3Rpb24obil7bi5jb2xvcj09PXR0JiYobi5sZWZ0LmNvbG9yPT09cSYmbi5yaWdodC5jb2xvcj09PXF8fCh0PSExKSl9KSx0fXRlc3RCbGFja0hlaWdodFByb3BlcnR5KHQpe2xldCBuPTAscj0wLGk9MDtpZih0LmNvbG9yPT09cSYmbisrLHQubGVmdCE9PXRoaXMubmlsX25vZGU/cj10aGlzLnRlc3RCbGFja0hlaWdodFByb3BlcnR5KHQubGVmdCk6cj0xLHQucmlnaHQhPT10aGlzLm5pbF9ub2RlP2k9dGhpcy50ZXN0QmxhY2tIZWlnaHRQcm9wZXJ0eSh0LnJpZ2h0KTppPTEsciE9PWkpdGhyb3cgbmV3IEVycm9yKCJSZWQtYmxhY2sgaGVpZ2h0IHByb3BlcnR5IHZpb2xhdGVkIik7cmV0dXJuIG4rPXIsbn19Y2xhc3Mga2QgZXh0ZW5kcyBTZXR7Y29uc3RydWN0b3IodCl7c3VwZXIodCksdGhpcy5pbmRleD1uZXcgWmUsdGhpcy5mb3JFYWNoKG49PnRoaXMuaW5kZXguaW5zZXJ0KG4pKX1hZGQodCl7bGV0IG49dGhpcy5zaXplO2NvbnN0e2tleTpyLHZhbHVlOml9PXQscz1yfHx0LmJveCxvPWl8fHQ7cmV0dXJuIHN1cGVyLmFkZChvKSx0aGlzLnNpemU+biYmdGhpcy5pbmRleC5pbnNlcnQocyxvKSx0aGlzfWRlbGV0ZSh0KXtjb25zdHtrZXk6bix2YWx1ZTpyfT10LGk9bnx8dC5ib3gscz1yfHx0O2xldCBvPXN1cGVyLmRlbGV0ZShzKTtyZXR1cm4gbyYmdGhpcy5pbmRleC5yZW1vdmUoaSxzKSxvfWNsZWFyKCl7c3VwZXIuY2xlYXIoKSx0aGlzLmluZGV4PW5ldyBaZX1zZWFyY2godCl7cmV0dXJuIHRoaXMuaW5kZXguc2VhcmNoKHQpfWhpdCh0KXtsZXQgbj1uZXcgbC5Cb3godC54LTEsdC55LTEsdC54KzEsdC55KzEpO3JldHVybiB0aGlzLmluZGV4LnNlYXJjaChuKS5maWx0ZXIoaT0+dC5vbihpKSl9c3ZnKCl7cmV0dXJuWy4uLnRoaXNdLnJlZHVjZSgobixyKT0+bityLnN2ZygpLCIiKX19bC5QbGFuYXJTZXQ9a2Q7Y2xhc3MgRHR7Z2V0IG5hbWUoKXt0aHJvdyBZLkNBTk5PVF9JTlZPS0VfQUJTVFJBQ1RfTUVUSE9EfWdldCBib3goKXt0aHJvdyBZLkNBTk5PVF9JTlZPS0VfQUJTVFJBQ1RfTUVUSE9EfWNsb25lKCl7dGhyb3cgWS5DQU5OT1RfSU5WT0tFX0FCU1RSQUNUX01FVEhPRH10cmFuc2xhdGUoLi4udCl7cmV0dXJuIHRoaXMudHJhbnNmb3JtKG5ldyBmdCgpLnRyYW5zbGF0ZSguLi50KSl9cm90YXRlKHQsbj1uZXcgbC5Qb2ludCl7cmV0dXJuIHRoaXMudHJhbnNmb3JtKG5ldyBmdCgpLnJvdGF0ZSh0LG4ueCxuLnkpKX1zY2FsZSh0LG4pe3JldHVybiB0aGlzLnRyYW5zZm9ybShuZXcgZnQoKS5zY2FsZSh0LG4pKX10cmFuc2Zvcm0oLi4udCl7dGhyb3cgWS5DQU5OT1RfSU5WT0tFX0FCU1RSQUNUX01FVEhPRH10b0pTT04oKXtyZXR1cm4gT2JqZWN0LmFzc2lnbih7fSx0aGlzLHtuYW1lOnRoaXMubmFtZX0pfXN2Zyh0PXt9KXt0aHJvdyBZLkNBTk5PVF9JTlZPS0VfQUJTVFJBQ1RfTUVUSE9EfX1sZXQgam49Y2xhc3MgRGEgZXh0ZW5kcyBEdHtjb25zdHJ1Y3RvciguLi50KXtpZihzdXBlcigpLHRoaXMueD0wLHRoaXMueT0wLHQubGVuZ3RoIT09MCl7aWYodC5sZW5ndGg9PT0xJiZ0WzBdaW5zdGFuY2VvZiBBcnJheSYmdFswXS5sZW5ndGg9PT0yKXtsZXQgbj10WzBdO2lmKHR5cGVvZiBuWzBdPT0ibnVtYmVyIiYmdHlwZW9mIG5bMV09PSJudW1iZXIiKXt0aGlzLng9blswXSx0aGlzLnk9blsxXTtyZXR1cm59fWlmKHQubGVuZ3RoPT09MSYmdFswXWluc3RhbmNlb2YgT2JqZWN0JiZ0WzBdLm5hbWU9PT0icG9pbnQiKXtsZXR7eDpuLHk6cn09dFswXTt0aGlzLng9bix0aGlzLnk9cjtyZXR1cm59aWYodC5sZW5ndGg9PT0yJiZ0eXBlb2YgdFswXT09Im51bWJlciImJnR5cGVvZiB0WzFdPT0ibnVtYmVyIil7dGhpcy54PXRbMF0sdGhpcy55PXRbMV07cmV0dXJufXRocm93IFkuSUxMRUdBTF9QQVJBTUVURVJTfX1nZXQgYm94KCl7cmV0dXJuIG5ldyBsLkJveCh0aGlzLngsdGhpcy55LHRoaXMueCx0aGlzLnkpfWNsb25lKCl7cmV0dXJuIG5ldyBsLlBvaW50KHRoaXMueCx0aGlzLnkpfWdldCB2ZXJ0aWNlcygpe3JldHVyblt0aGlzLmNsb25lKCldfWVxdWFsVG8odCl7cmV0dXJuIGwuVXRpbHMuRVEodGhpcy54LHQueCkmJmwuVXRpbHMuRVEodGhpcy55LHQueSl9bGVzc1RoYW4odCl7cmV0dXJuISEobC5VdGlscy5MVCh0aGlzLnksdC55KXx8bC5VdGlscy5FUSh0aGlzLnksdC55KSYmbC5VdGlscy5MVCh0aGlzLngsdC54KSl9dHJhbnNmb3JtKHQpe3JldHVybiBuZXcgbC5Qb2ludCh0LnRyYW5zZm9ybShbdGhpcy54LHRoaXMueV0pKX1wcm9qZWN0aW9uT24odCl7aWYodGhpcy5lcXVhbFRvKHQucHQpKXJldHVybiB0aGlzLmNsb25lKCk7bGV0IG49bmV3IGwuVmVjdG9yKHRoaXMsdC5wdCk7aWYobC5VdGlscy5FUV8wKG4uY3Jvc3ModC5ub3JtKSkpcmV0dXJuIHQucHQuY2xvbmUoKTtsZXQgcj1uLmRvdCh0Lm5vcm0pLGk9dC5ub3JtLm11bHRpcGx5KHIpO3JldHVybiB0aGlzLnRyYW5zbGF0ZShpKX1sZWZ0VG8odCl7bGV0IG49bmV3IGwuVmVjdG9yKHQucHQsdGhpcyk7cmV0dXJuIGwuVXRpbHMuR1Qobi5kb3QodC5ub3JtKSwwKX1kaXN0YW5jZVRvKHQpe2lmKHQgaW5zdGFuY2VvZiBEYSl7bGV0IG49dC54LXRoaXMueCxyPXQueS10aGlzLnk7cmV0dXJuW01hdGguc3FydChuKm4rcipyKSxuZXcgbC5TZWdtZW50KHRoaXMsdCldfWlmKHQgaW5zdGFuY2VvZiBsLkxpbmUpcmV0dXJuIGwuRGlzdGFuY2UucG9pbnQybGluZSh0aGlzLHQpO2lmKHQgaW5zdGFuY2VvZiBsLkNpcmNsZSlyZXR1cm4gbC5EaXN0YW5jZS5wb2ludDJjaXJjbGUodGhpcyx0KTtpZih0IGluc3RhbmNlb2YgbC5TZWdtZW50KXJldHVybiBsLkRpc3RhbmNlLnBvaW50MnNlZ21lbnQodGhpcyx0KTtpZih0IGluc3RhbmNlb2YgbC5BcmMpcmV0dXJuIGwuRGlzdGFuY2UucG9pbnQyYXJjKHRoaXMsdCk7aWYodCBpbnN0YW5jZW9mIGwuUG9seWdvbilyZXR1cm4gbC5EaXN0YW5jZS5wb2ludDJwb2x5Z29uKHRoaXMsdCk7aWYodCBpbnN0YW5jZW9mIGwuUGxhbmFyU2V0KXJldHVybiBsLkRpc3RhbmNlLnNoYXBlMnBsYW5hclNldCh0aGlzLHQpO2lmKHQgaW5zdGFuY2VvZiBsLk11bHRpbGluZSlyZXR1cm4gbC5EaXN0YW5jZS5zaGFwZTJtdWx0aWxpbmUodGhpcyx0KX1vbih0KXtpZih0IGluc3RhbmNlb2YgbC5Qb2ludClyZXR1cm4gdGhpcy5lcXVhbFRvKHQpO2lmKHQuY29udGFpbnMmJnQuY29udGFpbnMgaW5zdGFuY2VvZiBGdW5jdGlvbilyZXR1cm4gdC5jb250YWlucyh0aGlzKTt0aHJvdyBsLkVycm9ycy5VTlNVUFBPUlRFRF9TSEFQRV9UWVBFfWdldCBuYW1lKCl7cmV0dXJuInBvaW50In1zdmcodD17fSl7Y29uc3Qgbj10LnI/PzM7cmV0dXJuYAo8Y2lyY2xlIGN4PSIke3RoaXMueH0iIGN5PSIke3RoaXMueX0iIHI9IiR7bn0iCiAgICAgICAgICAgICR7dGUoe2ZpbGw6InJlZCIsLi4udH0pfSAvPmB9fTtsLlBvaW50PWpuO2NvbnN0IEJkPSguLi5lKT0+bmV3IGwuUG9pbnQoLi4uZSk7bC5wb2ludD1CZDtsZXQgVWQ9Y2xhc3MgZXh0ZW5kcyBEdHtjb25zdHJ1Y3RvciguLi50KXtpZihzdXBlcigpLHRoaXMueD0wLHRoaXMueT0wLHQubGVuZ3RoIT09MCl7aWYodC5sZW5ndGg9PT0xJiZ0WzBdaW5zdGFuY2VvZiBBcnJheSYmdFswXS5sZW5ndGg9PT0yKXtsZXQgbj10WzBdO2lmKHR5cGVvZiBuWzBdPT0ibnVtYmVyIiYmdHlwZW9mIG5bMV09PSJudW1iZXIiKXt0aGlzLng9blswXSx0aGlzLnk9blsxXTtyZXR1cm59fWlmKHQubGVuZ3RoPT09MSYmdFswXWluc3RhbmNlb2YgT2JqZWN0JiZ0WzBdLm5hbWU9PT0idmVjdG9yIil7bGV0e3g6bix5OnJ9PXRbMF07dGhpcy54PW4sdGhpcy55PXI7cmV0dXJufWlmKHQubGVuZ3RoPT09MSYmdFswXWluc3RhbmNlb2YgT2JqZWN0JiZ0WzBdLm5hbWU9PT0ic2VnbWVudCIpe2xldHtzdGFydDpuLGVuZDpyfT10WzBdO3RoaXMueD1yLngtbi54LHRoaXMueT1yLnktbi55O3JldHVybn1pZih0Lmxlbmd0aD09PTIpe2xldCBuPXRbMF0scj10WzFdO2lmKHR5cGVvZiBuPT0ibnVtYmVyIiYmdHlwZW9mIHI9PSJudW1iZXIiKXt0aGlzLng9bix0aGlzLnk9cjtyZXR1cm59aWYobiBpbnN0YW5jZW9mIGwuUG9pbnQmJnIgaW5zdGFuY2VvZiBsLlBvaW50KXt0aGlzLng9ci54LW4ueCx0aGlzLnk9ci55LW4ueTtyZXR1cm59fXRocm93IFkuSUxMRUdBTF9QQVJBTUVURVJTfX1jbG9uZSgpe3JldHVybiBuZXcgbC5WZWN0b3IodGhpcy54LHRoaXMueSl9Z2V0IHNsb3BlKCl7bGV0IHQ9TWF0aC5hdGFuMih0aGlzLnksdGhpcy54KTtyZXR1cm4gdDwwJiYodD0yKk1hdGguUEkrdCksdH1nZXQgbGVuZ3RoKCl7cmV0dXJuIE1hdGguc3FydCh0aGlzLmRvdCh0aGlzKSl9aXNaZXJvTGVuZ3RoKCl7cmV0dXJuIGwuVXRpbHMuRVFfMCh0aGlzLmxlbmd0aCl9ZXF1YWxUbyh0KXtyZXR1cm4gbC5VdGlscy5FUSh0aGlzLngsdC54KSYmbC5VdGlscy5FUSh0aGlzLnksdC55KX1tdWx0aXBseSh0KXtyZXR1cm4gbmV3IGwuVmVjdG9yKHQqdGhpcy54LHQqdGhpcy55KX1kb3QodCl7cmV0dXJuIHRoaXMueCp0LngrdGhpcy55KnQueX1jcm9zcyh0KXtyZXR1cm4gdGhpcy54KnQueS10aGlzLnkqdC54fW5vcm1hbGl6ZSgpe2lmKHRoaXMuaXNaZXJvTGVuZ3RoKCkpdGhyb3cgWS5aRVJPX0RJVklTSU9OO3JldHVybiBuZXcgbC5WZWN0b3IodGhpcy54L3RoaXMubGVuZ3RoLHRoaXMueS90aGlzLmxlbmd0aCl9cm90YXRlKHQsbj1uZXcgbC5Qb2ludCl7aWYobi54PT09MCYmbi55PT09MClyZXR1cm4gdGhpcy50cmFuc2Zvcm0obmV3IGZ0KCkucm90YXRlKHQpKTt0aHJvdyBZLk9QRVJBVElPTl9JU19OT1RfU1VQUE9SVEVEfXRyYW5zZm9ybSh0KXtyZXR1cm4gbmV3IGwuVmVjdG9yKHQudHJhbnNmb3JtKFt0aGlzLngsdGhpcy55XSkpfXJvdGF0ZTkwQ0NXKCl7cmV0dXJuIG5ldyBsLlZlY3RvcigtdGhpcy55LHRoaXMueCl9cm90YXRlOTBDVygpe3JldHVybiBuZXcgbC5WZWN0b3IodGhpcy55LC10aGlzLngpfWludmVydCgpe3JldHVybiBuZXcgbC5WZWN0b3IoLXRoaXMueCwtdGhpcy55KX1hZGQodCl7cmV0dXJuIG5ldyBsLlZlY3Rvcih0aGlzLngrdC54LHRoaXMueSt0LnkpfXN1YnRyYWN0KHQpe3JldHVybiBuZXcgbC5WZWN0b3IodGhpcy54LXQueCx0aGlzLnktdC55KX1hbmdsZVRvKHQpe2xldCBuPXRoaXMubm9ybWFsaXplKCkscj10Lm5vcm1hbGl6ZSgpLGk9TWF0aC5hdGFuMihuLmNyb3NzKHIpLG4uZG90KHIpKTtyZXR1cm4gaTwwJiYoaSs9MipNYXRoLlBJKSxpfXByb2plY3Rpb25Pbih0KXtsZXQgbj10Lm5vcm1hbGl6ZSgpLHI9dGhpcy5kb3Qobik7cmV0dXJuIG4ubXVsdGlwbHkocil9Z2V0IG5hbWUoKXtyZXR1cm4idmVjdG9yIn19O2wuVmVjdG9yPVVkO2NvbnN0IE9hPSguLi5lKT0+bmV3IGwuVmVjdG9yKC4uLmUpO2wudmVjdG9yPU9hO2xldCBEZD1jbGFzcyB6aSBleHRlbmRzIER0e2NvbnN0cnVjdG9yKC4uLnQpe2lmKHN1cGVyKCksdGhpcy5wcz1uZXcgbC5Qb2ludCx0aGlzLnBlPW5ldyBsLlBvaW50LHQubGVuZ3RoIT09MCl7aWYodC5sZW5ndGg9PT0xJiZ0WzBdaW5zdGFuY2VvZiBBcnJheSYmdFswXS5sZW5ndGg9PT00KXtsZXQgbj10WzBdO3RoaXMucHM9bmV3IGwuUG9pbnQoblswXSxuWzFdKSx0aGlzLnBlPW5ldyBsLlBvaW50KG5bMl0sblszXSk7cmV0dXJufWlmKHQubGVuZ3RoPT09MSYmdFswXWluc3RhbmNlb2YgT2JqZWN0JiZ0WzBdLm5hbWU9PT0ic2VnbWVudCIpe2xldHtwczpuLHBlOnJ9PXRbMF07dGhpcy5wcz1uZXcgbC5Qb2ludChuLngsbi55KSx0aGlzLnBlPW5ldyBsLlBvaW50KHIueCxyLnkpO3JldHVybn1pZih0Lmxlbmd0aD09PTEmJnRbMF1pbnN0YW5jZW9mIGwuUG9pbnQpe3RoaXMucHM9dFswXS5jbG9uZSgpO3JldHVybn1pZih0Lmxlbmd0aD09PTImJnRbMF1pbnN0YW5jZW9mIGwuUG9pbnQmJnRbMV1pbnN0YW5jZW9mIGwuUG9pbnQpe3RoaXMucHM9dFswXS5jbG9uZSgpLHRoaXMucGU9dFsxXS5jbG9uZSgpO3JldHVybn1pZih0Lmxlbmd0aD09PTQpe3RoaXMucHM9bmV3IGwuUG9pbnQodFswXSx0WzFdKSx0aGlzLnBlPW5ldyBsLlBvaW50KHRbMl0sdFszXSk7cmV0dXJufXRocm93IFkuSUxMRUdBTF9QQVJBTUVURVJTfX1jbG9uZSgpe3JldHVybiBuZXcgbC5TZWdtZW50KHRoaXMuc3RhcnQsdGhpcy5lbmQpfWdldCBzdGFydCgpe3JldHVybiB0aGlzLnBzfWdldCBlbmQoKXtyZXR1cm4gdGhpcy5wZX1nZXQgdmVydGljZXMoKXtyZXR1cm5bdGhpcy5wcy5jbG9uZSgpLHRoaXMucGUuY2xvbmUoKV19Z2V0IGxlbmd0aCgpe3JldHVybiB0aGlzLnN0YXJ0LmRpc3RhbmNlVG8odGhpcy5lbmQpWzBdfWdldCBzbG9wZSgpe3JldHVybiBuZXcgbC5WZWN0b3IodGhpcy5zdGFydCx0aGlzLmVuZCkuc2xvcGV9Z2V0IGJveCgpe3JldHVybiBuZXcgbC5Cb3goTWF0aC5taW4odGhpcy5zdGFydC54LHRoaXMuZW5kLngpLE1hdGgubWluKHRoaXMuc3RhcnQueSx0aGlzLmVuZC55KSxNYXRoLm1heCh0aGlzLnN0YXJ0LngsdGhpcy5lbmQueCksTWF0aC5tYXgodGhpcy5zdGFydC55LHRoaXMuZW5kLnkpKX1lcXVhbFRvKHQpe3JldHVybiB0aGlzLnBzLmVxdWFsVG8odC5wcykmJnRoaXMucGUuZXF1YWxUbyh0LnBlKX1jb250YWlucyh0KXtyZXR1cm4gbC5VdGlscy5FUV8wKHRoaXMuZGlzdGFuY2VUb1BvaW50KHQpKX1pbnRlcnNlY3QodCl7aWYodCBpbnN0YW5jZW9mIGwuUG9pbnQpcmV0dXJuIHRoaXMuY29udGFpbnModCk/W3RdOltdO2lmKHQgaW5zdGFuY2VvZiBsLkxpbmUpcmV0dXJuIEZlKHRoaXMsdCk7aWYodCBpbnN0YW5jZW9mIGwuUmF5KXJldHVybiBnaSh0LHRoaXMpO2lmKHQgaW5zdGFuY2VvZiBsLlNlZ21lbnQpcmV0dXJuIFduKHRoaXMsdCk7aWYodCBpbnN0YW5jZW9mIGwuQ2lyY2xlKXJldHVybiBabih0aGlzLHQpO2lmKHQgaW5zdGFuY2VvZiBsLkJveClyZXR1cm4gbmQodGhpcyx0KTtpZih0IGluc3RhbmNlb2YgbC5BcmMpcmV0dXJuIHBlKHRoaXMsdCk7aWYodCBpbnN0YW5jZW9mIGwuUG9seWdvbilyZXR1cm4gdWkodGhpcyx0KTtpZih0IGluc3RhbmNlb2YgbC5NdWx0aWxpbmUpcmV0dXJuIF9lKHRoaXMsdCl9ZGlzdGFuY2VUbyh0KXtpZih0IGluc3RhbmNlb2YgbC5Qb2ludCl7bGV0W24scl09bC5EaXN0YW5jZS5wb2ludDJzZWdtZW50KHQsdGhpcyk7cmV0dXJuIHI9ci5yZXZlcnNlKCksW24scl19aWYodCBpbnN0YW5jZW9mIGwuQ2lyY2xlKXtsZXRbbixyXT1sLkRpc3RhbmNlLnNlZ21lbnQyY2lyY2xlKHRoaXMsdCk7cmV0dXJuW24scl19aWYodCBpbnN0YW5jZW9mIGwuTGluZSl7bGV0W24scl09bC5EaXN0YW5jZS5zZWdtZW50MmxpbmUodGhpcyx0KTtyZXR1cm5bbixyXX1pZih0IGluc3RhbmNlb2YgbC5TZWdtZW50KXtsZXRbbixyXT1sLkRpc3RhbmNlLnNlZ21lbnQyc2VnbWVudCh0aGlzLHQpO3JldHVybltuLHJdfWlmKHQgaW5zdGFuY2VvZiBsLkFyYyl7bGV0W24scl09bC5EaXN0YW5jZS5zZWdtZW50MmFyYyh0aGlzLHQpO3JldHVybltuLHJdfWlmKHQgaW5zdGFuY2VvZiBsLlBvbHlnb24pe2xldFtuLHJdPWwuRGlzdGFuY2Uuc2hhcGUycG9seWdvbih0aGlzLHQpO3JldHVybltuLHJdfWlmKHQgaW5zdGFuY2VvZiBsLlBsYW5hclNldCl7bGV0W24scl09bC5EaXN0YW5jZS5zaGFwZTJwbGFuYXJTZXQodGhpcyx0KTtyZXR1cm5bbixyXX1pZih0IGluc3RhbmNlb2YgbC5NdWx0aWxpbmUpcmV0dXJuIGwuRGlzdGFuY2Uuc2hhcGUybXVsdGlsaW5lKHRoaXMsdCl9dGFuZ2VudEluU3RhcnQoKXtyZXR1cm4gbmV3IGwuVmVjdG9yKHRoaXMuc3RhcnQsdGhpcy5lbmQpLm5vcm1hbGl6ZSgpfXRhbmdlbnRJbkVuZCgpe3JldHVybiBuZXcgbC5WZWN0b3IodGhpcy5lbmQsdGhpcy5zdGFydCkubm9ybWFsaXplKCl9cmV2ZXJzZSgpe3JldHVybiBuZXcgemkodGhpcy5lbmQsdGhpcy5zdGFydCl9c3BsaXQodCl7cmV0dXJuIHRoaXMuc3RhcnQuZXF1YWxUbyh0KT9bbnVsbCx0aGlzLmNsb25lKCldOnRoaXMuZW5kLmVxdWFsVG8odCk/W3RoaXMuY2xvbmUoKSxudWxsXTpbbmV3IGwuU2VnbWVudCh0aGlzLnN0YXJ0LHQpLG5ldyBsLlNlZ21lbnQodCx0aGlzLmVuZCldfW1pZGRsZSgpe3JldHVybiBuZXcgbC5Qb2ludCgodGhpcy5zdGFydC54K3RoaXMuZW5kLngpLzIsKHRoaXMuc3RhcnQueSt0aGlzLmVuZC55KS8yKX1wb2ludEF0TGVuZ3RoKHQpe2lmKHQ+dGhpcy5sZW5ndGh8fHQ8MClyZXR1cm4gbnVsbDtpZih0PT0wKXJldHVybiB0aGlzLnN0YXJ0O2lmKHQ9PXRoaXMubGVuZ3RoKXJldHVybiB0aGlzLmVuZDtsZXQgbj10L3RoaXMubGVuZ3RoO3JldHVybiBuZXcgbC5Qb2ludCgodGhpcy5lbmQueC10aGlzLnN0YXJ0LngpKm4rdGhpcy5zdGFydC54LCh0aGlzLmVuZC55LXRoaXMuc3RhcnQueSkqbit0aGlzLnN0YXJ0LnkpfWRpc3RhbmNlVG9Qb2ludCh0KXtsZXRbbiwuLi5yXT1sLkRpc3RhbmNlLnBvaW50MnNlZ21lbnQodCx0aGlzKTtyZXR1cm4gbn1kZWZpbml0ZUludGVncmFsKHQ9MCl7bGV0IG49dGhpcy5lbmQueC10aGlzLnN0YXJ0Lngscj10aGlzLnN0YXJ0LnktdCxpPXRoaXMuZW5kLnktdDtyZXR1cm4gbioocitpKS8yfXRyYW5zZm9ybSh0PW5ldyBsLk1hdHJpeCl7cmV0dXJuIG5ldyB6aSh0aGlzLnBzLnRyYW5zZm9ybSh0KSx0aGlzLnBlLnRyYW5zZm9ybSh0KSl9aXNaZXJvTGVuZ3RoKCl7cmV0dXJuIHRoaXMucHMuZXF1YWxUbyh0aGlzLnBlKX1zb3J0UG9pbnRzKHQpe3JldHVybiBuZXcgbC5MaW5lKHRoaXMuc3RhcnQsdGhpcy5lbmQpLnNvcnRQb2ludHModCl9Z2V0IG5hbWUoKXtyZXR1cm4ic2VnbWVudCJ9c3ZnKHQ9e30pe3JldHVybmAKPGxpbmUgeDE9IiR7dGhpcy5zdGFydC54fSIgeTE9IiR7dGhpcy5zdGFydC55fSIgeDI9IiR7dGhpcy5lbmQueH0iIHkyPSIke3RoaXMuZW5kLnl9IiAke3RlKHQpfSAvPmB9fTtsLlNlZ21lbnQ9RGQ7Y29uc3QgWWQ9KC4uLmUpPT5uZXcgbC5TZWdtZW50KC4uLmUpO2wuc2VnbWVudD1ZZDtsZXR7dmVjdG9yOlhlfT1sLFdkPWNsYXNzIFlhIGV4dGVuZHMgRHR7Y29uc3RydWN0b3IoLi4udCl7aWYoc3VwZXIoKSx0aGlzLnB0PW5ldyBsLlBvaW50LHRoaXMubm9ybT1uZXcgbC5WZWN0b3IoMCwxKSx0Lmxlbmd0aCE9PTApe2lmKHQubGVuZ3RoPT09MSYmdFswXWluc3RhbmNlb2YgT2JqZWN0JiZ0WzBdLm5hbWU9PT0ibGluZSIpe2xldHtwdDpuLG5vcm06cn09dFswXTt0aGlzLnB0PW5ldyBsLlBvaW50KG4pLHRoaXMubm9ybT1uZXcgbC5WZWN0b3Iocik7cmV0dXJufWlmKHQubGVuZ3RoPT09Mil7bGV0IG49dFswXSxyPXRbMV07aWYobiBpbnN0YW5jZW9mIGwuUG9pbnQmJnIgaW5zdGFuY2VvZiBsLlBvaW50KXt0aGlzLnB0PW4sdGhpcy5ub3JtPVlhLnBvaW50czJub3JtKG4sciksdGhpcy5ub3JtLmRvdChYZSh0aGlzLnB0LngsdGhpcy5wdC55KSk+PTAmJnRoaXMubm9ybS5pbnZlcnQoKTtyZXR1cm59aWYobiBpbnN0YW5jZW9mIGwuUG9pbnQmJnIgaW5zdGFuY2VvZiBsLlZlY3Rvcil7aWYobC5VdGlscy5FUV8wKHIueCkmJmwuVXRpbHMuRVFfMChyLnkpKXRocm93IFkuSUxMRUdBTF9QQVJBTUVURVJTO3RoaXMucHQ9bi5jbG9uZSgpLHRoaXMubm9ybT1yLmNsb25lKCksdGhpcy5ub3JtPXRoaXMubm9ybS5ub3JtYWxpemUoKSx0aGlzLm5vcm0uZG90KFhlKHRoaXMucHQueCx0aGlzLnB0LnkpKT49MCYmdGhpcy5ub3JtLmludmVydCgpO3JldHVybn1pZihuIGluc3RhbmNlb2YgbC5WZWN0b3ImJnIgaW5zdGFuY2VvZiBsLlBvaW50KXtpZihsLlV0aWxzLkVRXzAobi54KSYmbC5VdGlscy5FUV8wKG4ueSkpdGhyb3cgWS5JTExFR0FMX1BBUkFNRVRFUlM7dGhpcy5wdD1yLmNsb25lKCksdGhpcy5ub3JtPW4uY2xvbmUoKSx0aGlzLm5vcm09dGhpcy5ub3JtLm5vcm1hbGl6ZSgpLHRoaXMubm9ybS5kb3QoWGUodGhpcy5wdC54LHRoaXMucHQueSkpPj0wJiZ0aGlzLm5vcm0uaW52ZXJ0KCk7cmV0dXJufX10aHJvdyBZLklMTEVHQUxfUEFSQU1FVEVSU319Y2xvbmUoKXtyZXR1cm4gbmV3IGwuTGluZSh0aGlzLnB0LHRoaXMubm9ybSl9Z2V0IHN0YXJ0KCl7fWdldCBlbmQoKXt9Z2V0IGxlbmd0aCgpe3JldHVybiBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFl9Z2V0IGJveCgpe3JldHVybiBuZXcgbC5Cb3goTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZLE51bWJlci5ORUdBVElWRV9JTkZJTklUWSxOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFksTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZKX1nZXQgbWlkZGxlKCl7fWdldCBzbG9wZSgpe3JldHVybiBuZXcgbC5WZWN0b3IodGhpcy5ub3JtLnksLXRoaXMubm9ybS54KS5zbG9wZX1nZXQgc3RhbmRhcmQoKXtsZXQgdD10aGlzLm5vcm0ueCxuPXRoaXMubm9ybS55LHI9dGhpcy5ub3JtLmRvdChYZSh0aGlzLnB0LngsdGhpcy5wdC55KSk7cmV0dXJuW3QsbixyXX1wYXJhbGxlbFRvKHQpe3JldHVybiBsLlV0aWxzLkVRXzAodGhpcy5ub3JtLmNyb3NzKHQubm9ybSkpfWluY2lkZW50VG8odCl7cmV0dXJuIHRoaXMucGFyYWxsZWxUbyh0KSYmdGhpcy5wdC5vbih0KX1jb250YWlucyh0KXtpZih0aGlzLnB0LmVxdWFsVG8odCkpcmV0dXJuITA7bGV0IG49bmV3IGwuVmVjdG9yKHRoaXMucHQsdCk7cmV0dXJuIGwuVXRpbHMuRVFfMCh0aGlzLm5vcm0uZG90KG4pKX1jb29yZCh0KXtyZXR1cm4gWGUodC54LHQueSkuY3Jvc3ModGhpcy5ub3JtKX1pbnRlcnNlY3QodCl7aWYodCBpbnN0YW5jZW9mIGwuUG9pbnQpcmV0dXJuIHRoaXMuY29udGFpbnModCk/W3RdOltdO2lmKHQgaW5zdGFuY2VvZiBsLkxpbmUpcmV0dXJuIGdlKHRoaXMsdCk7aWYodCBpbnN0YW5jZW9mIGwuUmF5KXJldHVybiBvYSh0LHRoaXMpO2lmKHQgaW5zdGFuY2VvZiBsLkNpcmNsZSlyZXR1cm4gZWUodGhpcyx0KTtpZih0IGluc3RhbmNlb2YgbC5Cb3gpcmV0dXJuIG1lKHRoaXMsdCk7aWYodCBpbnN0YW5jZW9mIGwuU2VnbWVudClyZXR1cm4gRmUodCx0aGlzKTtpZih0IGluc3RhbmNlb2YgbC5BcmMpcmV0dXJuIFluKHRoaXMsdCk7aWYodCBpbnN0YW5jZW9mIGwuUG9seWdvbilyZXR1cm4ga2UodGhpcyx0KTtpZih0IGluc3RhbmNlb2YgbC5NdWx0aWxpbmUpcmV0dXJuIF9lKHRoaXMsdCl9ZGlzdGFuY2VUbyh0KXtpZih0IGluc3RhbmNlb2YgbC5Qb2ludCl7bGV0W24scl09bC5EaXN0YW5jZS5wb2ludDJsaW5lKHQsdGhpcyk7cmV0dXJuIHI9ci5yZXZlcnNlKCksW24scl19aWYodCBpbnN0YW5jZW9mIGwuQ2lyY2xlKXtsZXRbbixyXT1sLkRpc3RhbmNlLmNpcmNsZTJsaW5lKHQsdGhpcyk7cmV0dXJuIHI9ci5yZXZlcnNlKCksW24scl19aWYodCBpbnN0YW5jZW9mIGwuU2VnbWVudCl7bGV0W24scl09bC5EaXN0YW5jZS5zZWdtZW50MmxpbmUodCx0aGlzKTtyZXR1cm5bbixyLnJldmVyc2UoKV19aWYodCBpbnN0YW5jZW9mIGwuQXJjKXtsZXRbbixyXT1sLkRpc3RhbmNlLmFyYzJsaW5lKHQsdGhpcyk7cmV0dXJuW24sci5yZXZlcnNlKCldfWlmKHQgaW5zdGFuY2VvZiBsLlBvbHlnb24pe2xldFtuLHJdPWwuRGlzdGFuY2Uuc2hhcGUycG9seWdvbih0aGlzLHQpO3JldHVybltuLHJdfX1zcGxpdCh0KXtpZih0IGluc3RhbmNlb2YgbC5Qb2ludClyZXR1cm5bbmV3IGwuUmF5KHQsdGhpcy5ub3JtKSxuZXcgbC5SYXkodCx0aGlzLm5vcm0pXTt7bGV0IG49bmV3IGwuTXVsdGlsaW5lKFt0aGlzXSkscj10aGlzLnNvcnRQb2ludHModCk7cmV0dXJuIG4uc3BsaXQociksbi50b1NoYXBlcygpfX1yb3RhdGUodCxuPW5ldyBsLlBvaW50KXtyZXR1cm4gbmV3IGwuTGluZSh0aGlzLnB0LnJvdGF0ZSh0LG4pLHRoaXMubm9ybS5yb3RhdGUodCkpfXRyYW5zZm9ybSh0KXtyZXR1cm4gbmV3IGwuTGluZSh0aGlzLnB0LnRyYW5zZm9ybSh0KSx0aGlzLm5vcm0uY2xvbmUoKSl9c29ydFBvaW50cyh0KXtyZXR1cm4gdC5zbGljZSgpLnNvcnQoKG4scik9PnRoaXMuY29vcmQobik8dGhpcy5jb29yZChyKT8tMTp0aGlzLmNvb3JkKG4pPnRoaXMuY29vcmQocik/MTowKX1nZXQgbmFtZSgpe3JldHVybiJsaW5lIn1zdmcodCxuPXt9KXtsZXQgcj1tZSh0aGlzLHQpO2lmKHIubGVuZ3RoPT09MClyZXR1cm4iIjtsZXQgaT1yWzBdLHM9ci5sZW5ndGg9PT0yP3JbMV06ci5maW5kKGM9PiFjLmVxdWFsVG8oaSkpO3JldHVybiBzPT09dm9pZCAwJiYocz1pKSxuZXcgbC5TZWdtZW50KGkscykuc3ZnKG4pfXN0YXRpYyBwb2ludHMybm9ybSh0LG4pe2lmKHQuZXF1YWxUbyhuKSl0aHJvdyBZLklMTEVHQUxfUEFSQU1FVEVSUztyZXR1cm4gbmV3IGwuVmVjdG9yKHQsbikubm9ybWFsaXplKCkucm90YXRlOTBDQ1coKX19O2wuTGluZT1XZDtjb25zdCBaZD0oLi4uZSk9Pm5ldyBsLkxpbmUoLi4uZSk7bC5saW5lPVpkO2xldCBYZD1jbGFzcyBleHRlbmRzIER0e2NvbnN0cnVjdG9yKC4uLnQpe2lmKHN1cGVyKCksdGhpcy5wYz1uZXcgbC5Qb2ludCx0aGlzLnI9MSx0Lmxlbmd0aD09PTEmJnRbMF1pbnN0YW5jZW9mIE9iamVjdCYmdFswXS5uYW1lPT09ImNpcmNsZSIpe2xldHtwYzpuLHJ9PXRbMF07dGhpcy5wYz1uZXcgbC5Qb2ludChuKSx0aGlzLnI9cn1lbHNle2xldFtuLHJdPVsuLi50XTtuJiZuIGluc3RhbmNlb2YgbC5Qb2ludCYmKHRoaXMucGM9bi5jbG9uZSgpKSxyIT09dm9pZCAwJiYodGhpcy5yPXIpfX1jbG9uZSgpe3JldHVybiBuZXcgbC5DaXJjbGUodGhpcy5wYy5jbG9uZSgpLHRoaXMucil9Z2V0IGNlbnRlcigpe3JldHVybiB0aGlzLnBjfWdldCBib3goKXtyZXR1cm4gbmV3IGwuQm94KHRoaXMucGMueC10aGlzLnIsdGhpcy5wYy55LXRoaXMucix0aGlzLnBjLngrdGhpcy5yLHRoaXMucGMueSt0aGlzLnIpfWNvbnRhaW5zKHQpe2lmKHQgaW5zdGFuY2VvZiBsLlBvaW50KXJldHVybiBsLlV0aWxzLkxFKHQuZGlzdGFuY2VUbyh0aGlzLmNlbnRlcilbMF0sdGhpcy5yKTtpZih0IGluc3RhbmNlb2YgbC5TZWdtZW50KXJldHVybiBsLlV0aWxzLkxFKHQuc3RhcnQuZGlzdGFuY2VUbyh0aGlzLmNlbnRlcilbMF0sdGhpcy5yKSYmbC5VdGlscy5MRSh0LmVuZC5kaXN0YW5jZVRvKHRoaXMuY2VudGVyKVswXSx0aGlzLnIpO2lmKHQgaW5zdGFuY2VvZiBsLkFyYylyZXR1cm4gdGhpcy5pbnRlcnNlY3QodCkubGVuZ3RoPT09MCYmbC5VdGlscy5MRSh0LnN0YXJ0LmRpc3RhbmNlVG8odGhpcy5jZW50ZXIpWzBdLHRoaXMucikmJmwuVXRpbHMuTEUodC5lbmQuZGlzdGFuY2VUbyh0aGlzLmNlbnRlcilbMF0sdGhpcy5yKTtpZih0IGluc3RhbmNlb2YgbC5DaXJjbGUpcmV0dXJuIHRoaXMuaW50ZXJzZWN0KHQpLmxlbmd0aD09PTAmJmwuVXRpbHMuTEUodC5yLHRoaXMucikmJmwuVXRpbHMuTEUodC5jZW50ZXIuZGlzdGFuY2VUbyh0aGlzLmNlbnRlcilbMF0sdGhpcy5yKX10b0FyYyh0PSEwKXtyZXR1cm4gbmV3IGwuQXJjKHRoaXMuY2VudGVyLHRoaXMucixNYXRoLlBJLC1NYXRoLlBJLHQpfXNjYWxlKHQsbil7aWYodCE9PW58fCEodGhpcy5wYy54PT09MCYmdGhpcy5wYy55PT09MCkpdGhyb3cgWS5PUEVSQVRJT05fSVNfTk9UX1NVUFBPUlRFRDtyZXR1cm4gbmV3IGwuQ2lyY2xlKHRoaXMucGMsdGhpcy5yKnQpfXRyYW5zZm9ybSh0PW5ldyBsLk1hdHJpeCl7cmV0dXJuIG5ldyBsLkNpcmNsZSh0aGlzLnBjLnRyYW5zZm9ybSh0KSx0aGlzLnIpfWludGVyc2VjdCh0KXtpZih0IGluc3RhbmNlb2YgbC5Qb2ludClyZXR1cm4gdGhpcy5jb250YWlucyh0KT9bdF06W107aWYodCBpbnN0YW5jZW9mIGwuTGluZSlyZXR1cm4gZWUodCx0aGlzKTtpZih0IGluc3RhbmNlb2YgbC5SYXkpcmV0dXJuIHNhKHQsdGhpcyk7aWYodCBpbnN0YW5jZW9mIGwuU2VnbWVudClyZXR1cm4gWm4odCx0aGlzKTtpZih0IGluc3RhbmNlb2YgbC5DaXJjbGUpcmV0dXJuIFFjKHQsdGhpcyk7aWYodCBpbnN0YW5jZW9mIGwuQm94KXJldHVybiByZCh0aGlzLHQpO2lmKHQgaW5zdGFuY2VvZiBsLkFyYylyZXR1cm4gZmkodCx0aGlzKTtpZih0IGluc3RhbmNlb2YgbC5Qb2x5Z29uKXJldHVybiBlYSh0aGlzLHQpO2lmKHQgaW5zdGFuY2VvZiBsLk11bHRpbGluZSlyZXR1cm4gX2UodGhpcyx0KX1kaXN0YW5jZVRvKHQpe2lmKHQgaW5zdGFuY2VvZiBsLlBvaW50KXtsZXRbbixyXT1sLkRpc3RhbmNlLnBvaW50MmNpcmNsZSh0LHRoaXMpO3JldHVybiByPXIucmV2ZXJzZSgpLFtuLHJdfWlmKHQgaW5zdGFuY2VvZiBsLkNpcmNsZSl7bGV0W24scl09bC5EaXN0YW5jZS5jaXJjbGUyY2lyY2xlKHRoaXMsdCk7cmV0dXJuW24scl19aWYodCBpbnN0YW5jZW9mIGwuTGluZSl7bGV0W24scl09bC5EaXN0YW5jZS5jaXJjbGUybGluZSh0aGlzLHQpO3JldHVybltuLHJdfWlmKHQgaW5zdGFuY2VvZiBsLlNlZ21lbnQpe2xldFtuLHJdPWwuRGlzdGFuY2Uuc2VnbWVudDJjaXJjbGUodCx0aGlzKTtyZXR1cm4gcj1yLnJldmVyc2UoKSxbbixyXX1pZih0IGluc3RhbmNlb2YgbC5BcmMpe2xldFtuLHJdPWwuRGlzdGFuY2UuYXJjMmNpcmNsZSh0LHRoaXMpO3JldHVybiByPXIucmV2ZXJzZSgpLFtuLHJdfWlmKHQgaW5zdGFuY2VvZiBsLlBvbHlnb24pe2xldFtuLHJdPWwuRGlzdGFuY2Uuc2hhcGUycG9seWdvbih0aGlzLHQpO3JldHVybltuLHJdfWlmKHQgaW5zdGFuY2VvZiBsLlBsYW5hclNldCl7bGV0W24scl09bC5EaXN0YW5jZS5zaGFwZTJwbGFuYXJTZXQodGhpcyx0KTtyZXR1cm5bbixyXX1pZih0IGluc3RhbmNlb2YgbC5NdWx0aWxpbmUpe2xldFtuLHJdPWwuRGlzdGFuY2Uuc2hhcGUybXVsdGlsaW5lKHRoaXMsdCk7cmV0dXJuW24scl19fWdldCBuYW1lKCl7cmV0dXJuImNpcmNsZSJ9c3ZnKHQ9e30pe3JldHVybmAKPGNpcmNsZSBjeD0iJHt0aGlzLnBjLnh9IiBjeT0iJHt0aGlzLnBjLnl9IiByPSIke3RoaXMucn0iCiAgICAgICAgICAgICAgICAke3RlKHtmaWxsOiJub25lIiwuLi50fSl9IC8+YH19O2wuQ2lyY2xlPVhkO2NvbnN0IEdkPSguLi5lKT0+bmV3IGwuQ2lyY2xlKC4uLmUpO2wuY2lyY2xlPUdkO2NsYXNzIGpkIGV4dGVuZHMgRHR7Y29uc3RydWN0b3IoLi4udCl7aWYoc3VwZXIoKSx0aGlzLnBjPW5ldyBsLlBvaW50LHRoaXMucj0xLHRoaXMuc3RhcnRBbmdsZT0wLHRoaXMuZW5kQW5nbGU9MipNYXRoLlBJLHRoaXMuY291bnRlckNsb2Nrd2lzZT0hMCx0Lmxlbmd0aCE9PTApaWYodC5sZW5ndGg9PT0xJiZ0WzBdaW5zdGFuY2VvZiBPYmplY3QmJnRbMF0ubmFtZT09PSJhcmMiKXtsZXR7cGM6bixyLHN0YXJ0QW5nbGU6aSxlbmRBbmdsZTpzLGNvdW50ZXJDbG9ja3dpc2U6b309dFswXTt0aGlzLnBjPW5ldyBsLlBvaW50KG4ueCxuLnkpLHRoaXMucj1yLHRoaXMuc3RhcnRBbmdsZT1pLHRoaXMuZW5kQW5nbGU9cyx0aGlzLmNvdW50ZXJDbG9ja3dpc2U9b31lbHNle2xldFtuLHIsaSxzLG9dPVsuLi50XTtuJiZuIGluc3RhbmNlb2YgbC5Qb2ludCYmKHRoaXMucGM9bi5jbG9uZSgpKSxyIT09dm9pZCAwJiYodGhpcy5yPXIpLGkhPT12b2lkIDAmJih0aGlzLnN0YXJ0QW5nbGU9aSkscyE9PXZvaWQgMCYmKHRoaXMuZW5kQW5nbGU9cyksbyE9PXZvaWQgMCYmKHRoaXMuY291bnRlckNsb2Nrd2lzZT1vKX19Y2xvbmUoKXtyZXR1cm4gbmV3IGwuQXJjKHRoaXMucGMuY2xvbmUoKSx0aGlzLnIsdGhpcy5zdGFydEFuZ2xlLHRoaXMuZW5kQW5nbGUsdGhpcy5jb3VudGVyQ2xvY2t3aXNlKX1nZXQgc3dlZXAoKXtsZXQgdD10aGlzLnN0YXJ0QW5nbGUsbj10aGlzLmVuZEFuZ2xlO2lmKGwuVXRpbHMuRVEoTWF0aC5hYnModC1uKSxsLlBJeDIpKXJldHVybiBsLlBJeDI7TWF0aC5hYnModCk+bC5QSXgyJiYodC09TWF0aC50cnVuYyh0L2wuUEl4MikqbC5QSXgyKSx0PDAmJih0Kz1sLlBJeDIpLE1hdGguYWJzKG4pPmwuUEl4MiYmKG4tPU1hdGgudHJ1bmMobi9sLlBJeDIpKmwuUEl4MiksbjwwJiYobis9bC5QSXgyKTtsZXQgcj10aGlzLmNvdW50ZXJDbG9ja3dpc2U/bi10OnQtbjtyZXR1cm4gcjwwJiYocis9bC5QSXgyKSxyfWdldCBzdGFydCgpe3JldHVybiBuZXcgbC5Qb2ludCh0aGlzLnBjLngrdGhpcy5yLHRoaXMucGMueSkucm90YXRlKHRoaXMuc3RhcnRBbmdsZSx0aGlzLnBjKX1nZXQgZW5kKCl7cmV0dXJuIG5ldyBsLlBvaW50KHRoaXMucGMueCt0aGlzLnIsdGhpcy5wYy55KS5yb3RhdGUodGhpcy5lbmRBbmdsZSx0aGlzLnBjKX1nZXQgY2VudGVyKCl7cmV0dXJuIHRoaXMucGMuY2xvbmUoKX1nZXQgdmVydGljZXMoKXtyZXR1cm5bdGhpcy5zdGFydC5jbG9uZSgpLHRoaXMuZW5kLmNsb25lKCldfWdldCBsZW5ndGgoKXtyZXR1cm4gTWF0aC5hYnModGhpcy5zd2VlcCp0aGlzLnIpfWdldCBib3goKXtsZXQgbj10aGlzLmJyZWFrVG9GdW5jdGlvbmFsKCkucmVkdWNlKChyLGkpPT5yLm1lcmdlKGkuc3RhcnQuYm94KSxuZXcgbC5Cb3gpO3JldHVybiBuPW4ubWVyZ2UodGhpcy5lbmQuYm94KSxufWNvbnRhaW5zKHQpe2lmKCFsLlV0aWxzLkVRKHRoaXMucGMuZGlzdGFuY2VUbyh0KVswXSx0aGlzLnIpKXJldHVybiExO2lmKHQuZXF1YWxUbyh0aGlzLnN0YXJ0KSlyZXR1cm4hMDtsZXQgbj1uZXcgbC5WZWN0b3IodGhpcy5wYyx0KS5zbG9wZSxyPW5ldyBsLkFyYyh0aGlzLnBjLHRoaXMucix0aGlzLnN0YXJ0QW5nbGUsbix0aGlzLmNvdW50ZXJDbG9ja3dpc2UpO3JldHVybiBsLlV0aWxzLkxFKHIubGVuZ3RoLHRoaXMubGVuZ3RoKX1zcGxpdCh0KXtpZih0aGlzLnN0YXJ0LmVxdWFsVG8odCkpcmV0dXJuW251bGwsdGhpcy5jbG9uZSgpXTtpZih0aGlzLmVuZC5lcXVhbFRvKHQpKXJldHVyblt0aGlzLmNsb25lKCksbnVsbF07bGV0IG49bmV3IGwuVmVjdG9yKHRoaXMucGMsdCkuc2xvcGU7cmV0dXJuW25ldyBsLkFyYyh0aGlzLnBjLHRoaXMucix0aGlzLnN0YXJ0QW5nbGUsbix0aGlzLmNvdW50ZXJDbG9ja3dpc2UpLG5ldyBsLkFyYyh0aGlzLnBjLHRoaXMucixuLHRoaXMuZW5kQW5nbGUsdGhpcy5jb3VudGVyQ2xvY2t3aXNlKV19bWlkZGxlKCl7bGV0IHQ9dGhpcy5jb3VudGVyQ2xvY2t3aXNlP3RoaXMuc3RhcnRBbmdsZSt0aGlzLnN3ZWVwLzI6dGhpcy5zdGFydEFuZ2xlLXRoaXMuc3dlZXAvMjtyZXR1cm4gbmV3IGwuQXJjKHRoaXMucGMsdGhpcy5yLHRoaXMuc3RhcnRBbmdsZSx0LHRoaXMuY291bnRlckNsb2Nrd2lzZSkuZW5kfXBvaW50QXRMZW5ndGgodCl7aWYodD50aGlzLmxlbmd0aHx8dDwwKXJldHVybiBudWxsO2lmKHQ9PT0wKXJldHVybiB0aGlzLnN0YXJ0O2lmKHQ9PT10aGlzLmxlbmd0aClyZXR1cm4gdGhpcy5lbmQ7bGV0IG49dC90aGlzLmxlbmd0aCxyPXRoaXMuY291bnRlckNsb2Nrd2lzZT90aGlzLnN0YXJ0QW5nbGUrdGhpcy5zd2VlcCpuOnRoaXMuc3RhcnRBbmdsZS10aGlzLnN3ZWVwKm47cmV0dXJuIG5ldyBsLkFyYyh0aGlzLnBjLHRoaXMucix0aGlzLnN0YXJ0QW5nbGUscix0aGlzLmNvdW50ZXJDbG9ja3dpc2UpLmVuZH1jaG9yZEhlaWdodCgpe3JldHVybigxLU1hdGguY29zKE1hdGguYWJzKHRoaXMuc3dlZXAvMikpKSp0aGlzLnJ9aW50ZXJzZWN0KHQpe2lmKHQgaW5zdGFuY2VvZiBsLlBvaW50KXJldHVybiB0aGlzLmNvbnRhaW5zKHQpP1t0XTpbXTtpZih0IGluc3RhbmNlb2YgbC5MaW5lKXJldHVybiBZbih0LHRoaXMpO2lmKHQgaW5zdGFuY2VvZiBsLlJheSlyZXR1cm4gbWkodCx0aGlzKTtpZih0IGluc3RhbmNlb2YgbC5DaXJjbGUpcmV0dXJuIGZpKHRoaXMsdCk7aWYodCBpbnN0YW5jZW9mIGwuU2VnbWVudClyZXR1cm4gcGUodCx0aGlzKTtpZih0IGluc3RhbmNlb2YgbC5Cb3gpcmV0dXJuIGlkKHRoaXMsdCk7aWYodCBpbnN0YW5jZW9mIGwuQXJjKXJldHVybiBLYyh0aGlzLHQpO2lmKHQgaW5zdGFuY2VvZiBsLlBvbHlnb24pcmV0dXJuIGRpKHRoaXMsdCk7aWYodCBpbnN0YW5jZW9mIGwuTXVsdGlsaW5lKXJldHVybiBfZSh0aGlzLHQpfWRpc3RhbmNlVG8odCl7aWYodCBpbnN0YW5jZW9mIGwuUG9pbnQpe2xldFtuLHJdPWwuRGlzdGFuY2UucG9pbnQyYXJjKHQsdGhpcyk7cmV0dXJuIHI9ci5yZXZlcnNlKCksW24scl19aWYodCBpbnN0YW5jZW9mIGwuQ2lyY2xlKXtsZXRbbixyXT1sLkRpc3RhbmNlLmFyYzJjaXJjbGUodGhpcyx0KTtyZXR1cm5bbixyXX1pZih0IGluc3RhbmNlb2YgbC5MaW5lKXtsZXRbbixyXT1sLkRpc3RhbmNlLmFyYzJsaW5lKHRoaXMsdCk7cmV0dXJuW24scl19aWYodCBpbnN0YW5jZW9mIGwuU2VnbWVudCl7bGV0W24scl09bC5EaXN0YW5jZS5zZWdtZW50MmFyYyh0LHRoaXMpO3JldHVybiByPXIucmV2ZXJzZSgpLFtuLHJdfWlmKHQgaW5zdGFuY2VvZiBsLkFyYyl7bGV0W24scl09bC5EaXN0YW5jZS5hcmMyYXJjKHRoaXMsdCk7cmV0dXJuW24scl19aWYodCBpbnN0YW5jZW9mIGwuUG9seWdvbil7bGV0W24scl09bC5EaXN0YW5jZS5zaGFwZTJwb2x5Z29uKHRoaXMsdCk7cmV0dXJuW24scl19aWYodCBpbnN0YW5jZW9mIGwuUGxhbmFyU2V0KXtsZXRbbixyXT1sLkRpc3RhbmNlLnNoYXBlMnBsYW5hclNldCh0aGlzLHQpO3JldHVybltuLHJdfWlmKHQgaW5zdGFuY2VvZiBsLk11bHRpbGluZSlyZXR1cm4gbC5EaXN0YW5jZS5zaGFwZTJtdWx0aWxpbmUodGhpcyx0KX1icmVha1RvRnVuY3Rpb25hbCgpe2xldCB0PVtdLG49WzAsTWF0aC5QSS8yLE1hdGguUEksMypNYXRoLlBJLzJdLHI9dGhpcy5zdGFydEFuZ2xlLGk9dGhpcy5lbmRBbmdsZTtsLlV0aWxzLkVRKE1hdGguYWJzKHItaSksbC5QSXgyKSYmKGk9ciksTWF0aC5hYnMocik+bC5QSXgyJiYoci09TWF0aC50cnVuYyhyL2wuUEl4MikqbC5QSXgyKSxyPDAmJihyKz1sLlBJeDIpLE1hdGguYWJzKGkpPmwuUEl4MiYmKGktPU1hdGgudHJ1bmMoaS9sLlBJeDIpKmwuUEl4MiksaTwwJiYoaSs9bC5QSXgyKTtsZXQgcz1yLG8sYyxhO3RoaXMuY291bnRlckNsb2Nrd2lzZT8oYz1NYXRoLmNlaWwoci8oTWF0aC5QSS8yKSklNCxhPTEpOihjPU1hdGguZmxvb3Ioci8oTWF0aC5QSS8yKSklNCxhPS0xKTtmb3IobGV0IGg9MCxmPWM7aDw0O2grKyxmPShmK2ErNCklNCl7aWYobz1uW2ZdLG89PT1zKWNvbnRpbnVlO2xldCB1PXRoaXMuY291bnRlckNsb2Nrd2lzZT9vLXI6ci1vO2lmKHU8MCYmKHUrPWwuUEl4MiksdT50aGlzLnN3ZWVwKWJyZWFrO3QucHVzaChuZXcgbC5BcmModGhpcy5wYyx0aGlzLnIscyxvLHRoaXMuY291bnRlckNsb2Nrd2lzZSkpLHM9b31yZXR1cm4gdC5sZW5ndGg9PT0wPyh0LnB1c2godGhpcyksdCk6KG89aSxzIT09byYmdC5wdXNoKG5ldyBsLkFyYyh0aGlzLnBjLHRoaXMucixzLG8sdGhpcy5jb3VudGVyQ2xvY2t3aXNlKSksdCl9dGFuZ2VudEluU3RhcnQoKXtsZXQgdD1uZXcgbC5WZWN0b3IodGhpcy5wYyx0aGlzLnN0YXJ0KSxuPXRoaXMuY291bnRlckNsb2Nrd2lzZT9NYXRoLlBJLzI6LU1hdGguUEkvMjtyZXR1cm4gdC5yb3RhdGUobikubm9ybWFsaXplKCl9dGFuZ2VudEluRW5kKCl7bGV0IHQ9bmV3IGwuVmVjdG9yKHRoaXMucGMsdGhpcy5lbmQpLG49dGhpcy5jb3VudGVyQ2xvY2t3aXNlPy1NYXRoLlBJLzI6TWF0aC5QSS8yO3JldHVybiB0LnJvdGF0ZShuKS5ub3JtYWxpemUoKX1yZXZlcnNlKCl7cmV0dXJuIG5ldyBsLkFyYyh0aGlzLnBjLHRoaXMucix0aGlzLmVuZEFuZ2xlLHRoaXMuc3RhcnRBbmdsZSwhdGhpcy5jb3VudGVyQ2xvY2t3aXNlKX10cmFuc2Zvcm0odD1uZXcgbC5NYXRyaXgpe2xldCBuPXRoaXMuc3RhcnQudHJhbnNmb3JtKHQpLHI9dGhpcy5lbmQudHJhbnNmb3JtKHQpLGk9dGhpcy5wYy50cmFuc2Zvcm0odCkscz10aGlzLmNvdW50ZXJDbG9ja3dpc2U7cmV0dXJuIHQuYSp0LmQ8MCYmKHM9IXMpLGwuQXJjLmFyY1NFKGksbixyLHMpfXN0YXRpYyBhcmNTRSh0LG4scixpKXtsZXR7dmVjdG9yOnN9PWwsbz1zKHQsbikuc2xvcGUsYz1zKHQscikuc2xvcGU7bC5VdGlscy5FUShvLGMpJiYoYys9MipNYXRoLlBJLGk9ITApO2xldCBhPXModCxuKS5sZW5ndGg7cmV0dXJuIG5ldyBsLkFyYyh0LGEsbyxjLGkpfWRlZmluaXRlSW50ZWdyYWwodD0wKXtyZXR1cm4gdGhpcy5icmVha1RvRnVuY3Rpb25hbCgpLnJlZHVjZSgoaSxzKT0+aStzLmNpcmN1bGFyU2VnbWVudERlZmluaXRlSW50ZWdyYWwodCksMCl9Y2lyY3VsYXJTZWdtZW50RGVmaW5pdGVJbnRlZ3JhbCh0KXtsZXQgcj1uZXcgbC5TZWdtZW50KHRoaXMuc3RhcnQsdGhpcy5lbmQpLmRlZmluaXRlSW50ZWdyYWwodCksaT1sLlV0aWxzLkVRKHRoaXMuc3dlZXAsbC5QSXgyKT8wOnRoaXMuY2lyY3VsYXJTZWdtZW50QXJlYSgpO3JldHVybiB0aGlzLmNvdW50ZXJDbG9ja3dpc2U/ci1pOnIraX1jaXJjdWxhclNlZ21lbnRBcmVhKCl7cmV0dXJuIC41KnRoaXMucip0aGlzLnIqKHRoaXMuc3dlZXAtTWF0aC5zaW4odGhpcy5zd2VlcCkpfXNvcnRQb2ludHModCl7bGV0e3ZlY3RvcjpufT1sO3JldHVybiB0LnNsaWNlKCkuc29ydCgocixpKT0+e2xldCBzPW4odGhpcy5wYyxyKS5zbG9wZSxvPW4odGhpcy5wYyxpKS5zbG9wZTtyZXR1cm4gczxvPy0xOnM+bz8xOjB9KX1nZXQgbmFtZSgpe3JldHVybiJhcmMifXN2Zyh0PXt9KXtsZXQgbj10aGlzLnN3ZWVwPD1NYXRoLlBJPyIwIjoiMSIscj10aGlzLmNvdW50ZXJDbG9ja3dpc2U/IjEiOiIwIjtyZXR1cm4gbC5VdGlscy5FUSh0aGlzLnN3ZWVwLDIqTWF0aC5QSSk/bmV3IGwuQ2lyY2xlKHRoaXMucGMsdGhpcy5yKS5zdmcodCk6YAo8cGF0aCBkPSJNJHt0aGlzLnN0YXJ0Lnh9LCR7dGhpcy5zdGFydC55fQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIEEke3RoaXMucn0sJHt0aGlzLnJ9IDAgJHtufSwke3J9ICR7dGhpcy5lbmQueH0sJHt0aGlzLmVuZC55fSIKICAgICAgICAgICAgICAgICAgICAke3RlKHtmaWxsOiJub25lIiwuLi50fSl9IC8+YH19bC5BcmM9amQ7Y29uc3QgUWQ9KC4uLmUpPT5uZXcgbC5BcmMoLi4uZSk7bC5hcmM9UWQ7Y2xhc3MgQWUgZXh0ZW5kcyBEdHtjb25zdHJ1Y3Rvcih0PXZvaWQgMCxuPXZvaWQgMCxyPXZvaWQgMCxpPXZvaWQgMCl7c3VwZXIoKSx0aGlzLnhtaW49dCx0aGlzLnltaW49bix0aGlzLnhtYXg9cix0aGlzLnltYXg9aX1jbG9uZSgpe3JldHVybiBuZXcgQWUodGhpcy54bWluLHRoaXMueW1pbix0aGlzLnhtYXgsdGhpcy55bWF4KX1nZXQgbG93KCl7cmV0dXJuIG5ldyBsLlBvaW50KHRoaXMueG1pbix0aGlzLnltaW4pfWdldCBoaWdoKCl7cmV0dXJuIG5ldyBsLlBvaW50KHRoaXMueG1heCx0aGlzLnltYXgpfWdldCBtYXgoKXtyZXR1cm4gdGhpcy5jbG9uZSgpfWdldCBjZW50ZXIoKXtyZXR1cm4gbmV3IGwuUG9pbnQoKHRoaXMueG1pbit0aGlzLnhtYXgpLzIsKHRoaXMueW1pbit0aGlzLnltYXgpLzIpfWdldCB3aWR0aCgpe3JldHVybiBNYXRoLmFicyh0aGlzLnhtYXgtdGhpcy54bWluKX1nZXQgaGVpZ2h0KCl7cmV0dXJuIE1hdGguYWJzKHRoaXMueW1heC10aGlzLnltaW4pfWdldCBib3goKXtyZXR1cm4gdGhpcy5jbG9uZSgpfW5vdF9pbnRlcnNlY3QodCl7cmV0dXJuIHRoaXMueG1heDx0LnhtaW58fHRoaXMueG1pbj50LnhtYXh8fHRoaXMueW1heDx0LnltaW58fHRoaXMueW1pbj50LnltYXh9aW50ZXJzZWN0KHQpe3JldHVybiF0aGlzLm5vdF9pbnRlcnNlY3QodCl9bWVyZ2UodCl7cmV0dXJuIG5ldyBBZSh0aGlzLnhtaW49PT12b2lkIDA/dC54bWluOk1hdGgubWluKHRoaXMueG1pbix0LnhtaW4pLHRoaXMueW1pbj09PXZvaWQgMD90LnltaW46TWF0aC5taW4odGhpcy55bWluLHQueW1pbiksdGhpcy54bWF4PT09dm9pZCAwP3QueG1heDpNYXRoLm1heCh0aGlzLnhtYXgsdC54bWF4KSx0aGlzLnltYXg9PT12b2lkIDA/dC55bWF4Ok1hdGgubWF4KHRoaXMueW1heCx0LnltYXgpKX1sZXNzX3RoYW4odCl7cmV0dXJuISEodGhpcy5sb3cubGVzc1RoYW4odC5sb3cpfHx0aGlzLmxvdy5lcXVhbFRvKHQubG93KSYmdGhpcy5oaWdoLmxlc3NUaGFuKHQuaGlnaCkpfWVxdWFsX3RvKHQpe3JldHVybiB0aGlzLmxvdy5lcXVhbFRvKHQubG93KSYmdGhpcy5oaWdoLmVxdWFsVG8odC5oaWdoKX1vdXRwdXQoKXtyZXR1cm4gdGhpcy5jbG9uZSgpfWNvbXBhcmFibGVfbGVzc190aGFuKHQsbil7cmV0dXJuIHQubGVzc1RoYW4obil9c2V0KHQsbixyLGkpe3RoaXMueG1pbj10LHRoaXMueW1pbj1uLHRoaXMueG1heD1yLHRoaXMueW1heD1pfWV4dGVuZCh0KXtyZXR1cm4gdDw9MD90aGlzLmNsb25lKCk6bmV3IEFlKHRoaXMueG1pbi10LHRoaXMueW1pbi10LHRoaXMueG1heCt0LHRoaXMueW1heCt0KX10b1BvaW50cygpe3JldHVybltuZXcgbC5Qb2ludCh0aGlzLnhtaW4sdGhpcy55bWluKSxuZXcgbC5Qb2ludCh0aGlzLnhtYXgsdGhpcy55bWluKSxuZXcgbC5Qb2ludCh0aGlzLnhtYXgsdGhpcy55bWF4KSxuZXcgbC5Qb2ludCh0aGlzLnhtaW4sdGhpcy55bWF4KV19dG9TZWdtZW50cygpe2xldCB0PXRoaXMudG9Qb2ludHMoKTtyZXR1cm5bbmV3IGwuU2VnbWVudCh0WzBdLHRbMV0pLG5ldyBsLlNlZ21lbnQodFsxXSx0WzJdKSxuZXcgbC5TZWdtZW50KHRbMl0sdFszXSksbmV3IGwuU2VnbWVudCh0WzNdLHRbMF0pXX1yb3RhdGUodCxuPW5ldyBsLlBvaW50KXt0aHJvdyBZLk9QRVJBVElPTl9JU19OT1RfU1VQUE9SVEVEfXRyYW5zZm9ybSh0PW5ldyBsLk1hdHJpeCl7cmV0dXJuIHRoaXMudG9Qb2ludHMoKS5tYXAocj0+ci50cmFuc2Zvcm0odCkpLnJlZHVjZSgocixpKT0+ci5tZXJnZShpLmJveCksbmV3IEFlKX1jb250YWlucyh0KXtpZih0IGluc3RhbmNlb2YgbC5Qb2ludClyZXR1cm4gdC54Pj10aGlzLnhtaW4mJnQueDw9dGhpcy54bWF4JiZ0Lnk+PXRoaXMueW1pbiYmdC55PD10aGlzLnltYXg7aWYodCBpbnN0YW5jZW9mIGwuU2VnbWVudClyZXR1cm4gdC52ZXJ0aWNlcy5ldmVyeShuPT50aGlzLmNvbnRhaW5zKG4pKTtpZih0IGluc3RhbmNlb2YgbC5Cb3gpcmV0dXJuIHQudG9TZWdtZW50cygpLmV2ZXJ5KG49PnRoaXMuY29udGFpbnMobikpO2lmKHQgaW5zdGFuY2VvZiBsLkNpcmNsZSlyZXR1cm4gdGhpcy5jb250YWlucyh0LmJveCk7aWYodCBpbnN0YW5jZW9mIGwuQXJjKXJldHVybiB0LnZlcnRpY2VzLmV2ZXJ5KG49PnRoaXMuY29udGFpbnMobikpJiZ0aGlzLnRvU2VnbWVudHMoKS5ldmVyeShuPT5wZShuLHQpLmxlbmd0aD09PTApO2lmKHQgaW5zdGFuY2VvZiBsLkxpbmV8fHQgaW5zdGFuY2VvZiBsLlJheSlyZXR1cm4hMTtpZih0IGluc3RhbmNlb2YgbC5NdWx0aWxpbmUpcmV0dXJuIHQudG9TaGFwZXMoKS5ldmVyeShuPT50aGlzLmNvbnRhaW5zKG4pKTtpZih0IGluc3RhbmNlb2YgbC5Qb2x5Z29uKXJldHVybiB0aGlzLmNvbnRhaW5zKHQuYm94KX1kaXN0YW5jZVRvKHQpe2NvbnN0IG49dGhpcy50b1NlZ21lbnRzKCkubWFwKGk9PmkuZGlzdGFuY2VUbyh0KSk7bGV0IHI9W051bWJlci5NQVhfU0FGRV9JTlRFR0VSLG51bGxdO3JldHVybiBuLmZvckVhY2goaT0+e2lbMF08clswXSYmKHI9aSl9KSxyfWdldCBuYW1lKCl7cmV0dXJuImJveCJ9c3ZnKHQ9e30pe2NvbnN0IG49dGhpcy54bWF4LXRoaXMueG1pbixyPXRoaXMueW1heC10aGlzLnltaW47cmV0dXJuYAo8cmVjdCB4PSIke3RoaXMueG1pbn0iIHk9IiR7dGhpcy55bWlufSIgd2lkdGg9IiR7bn0iIGhlaWdodD0iJHtyfSIKICAgICAgICAgICAgICAgICR7dGUoe2ZpbGw6Im5vbmUiLC4uLnR9KX0gLz5gfX1sLkJveD1BZTtjb25zdCBLZD0oLi4uZSk9Pm5ldyBsLkJveCguLi5lKTtsLmJveD1LZDtjbGFzcyBIZHtjb25zdHJ1Y3Rvcih0KXt0aGlzLnNoYXBlPXQsdGhpcy5uZXh0PXZvaWQgMCx0aGlzLnByZXY9dm9pZCAwLHRoaXMuZmFjZT12b2lkIDAsdGhpcy5hcmNfbGVuZ3RoPTAsdGhpcy5idlN0YXJ0PXZvaWQgMCx0aGlzLmJ2RW5kPXZvaWQgMCx0aGlzLmJ2PXZvaWQgMCx0aGlzLm92ZXJsYXA9dm9pZCAwfWdldCBzdGFydCgpe3JldHVybiB0aGlzLnNoYXBlLnN0YXJ0fWdldCBlbmQoKXtyZXR1cm4gdGhpcy5zaGFwZS5lbmR9Z2V0IGxlbmd0aCgpe3JldHVybiB0aGlzLnNoYXBlLmxlbmd0aH1nZXQgYm94KCl7cmV0dXJuIHRoaXMuc2hhcGUuYm94fWdldCBpc1NlZ21lbnQoKXtyZXR1cm4gdGhpcy5zaGFwZSBpbnN0YW5jZW9mIGwuU2VnbWVudH1nZXQgaXNBcmMoKXtyZXR1cm4gdGhpcy5zaGFwZSBpbnN0YW5jZW9mIGwuQXJjfWdldCBpc0xpbmUoKXtyZXR1cm4gdGhpcy5zaGFwZSBpbnN0YW5jZW9mIGwuTGluZX1nZXQgaXNSYXkoKXtyZXR1cm4gdGhpcy5zaGFwZSBpbnN0YW5jZW9mIGwuUmF5fW1pZGRsZSgpe3JldHVybiB0aGlzLnNoYXBlLm1pZGRsZSgpfXBvaW50QXRMZW5ndGgodCl7cmV0dXJuIHRoaXMuc2hhcGUucG9pbnRBdExlbmd0aCh0KX1jb250YWlucyh0KXtyZXR1cm4gdGhpcy5zaGFwZS5jb250YWlucyh0KX1zZXRJbmNsdXNpb24odCl7aWYodGhpcy5idiE9PXZvaWQgMClyZXR1cm4gdGhpcy5idjtpZih0aGlzLnNoYXBlIGluc3RhbmNlb2YgbC5MaW5lfHx0aGlzLnNoYXBlIGluc3RhbmNlb2YgbC5SYXkpcmV0dXJuIHRoaXMuYnY9bC5PVVRTSURFLHRoaXMuYnY7aWYodGhpcy5idlN0YXJ0PT09dm9pZCAwJiYodGhpcy5idlN0YXJ0PVdlKHQsdGhpcy5zdGFydCkpLHRoaXMuYnZFbmQ9PT12b2lkIDAmJih0aGlzLmJ2RW5kPVdlKHQsdGhpcy5lbmQpKSx0aGlzLmJ2U3RhcnQ9PT1sLk9VVFNJREV8fHRoaXMuYnZFbmQ9PWwuT1VUU0lERSl0aGlzLmJ2PWwuT1VUU0lERTtlbHNlIGlmKHRoaXMuYnZTdGFydD09PWwuSU5TSURFfHx0aGlzLmJ2RW5kPT1sLklOU0lERSl0aGlzLmJ2PWwuSU5TSURFO2Vsc2V7bGV0IG49V2UodCx0aGlzLm1pZGRsZSgpKTt0aGlzLmJ2PW59cmV0dXJuIHRoaXMuYnZ9c2V0T3ZlcmxhcCh0KXtsZXQgbixyPXRoaXMuc2hhcGUsaT10LnNoYXBlO3IgaW5zdGFuY2VvZiBsLlNlZ21lbnQmJmkgaW5zdGFuY2VvZiBsLlNlZ21lbnQ/ci5zdGFydC5lcXVhbFRvKGkuc3RhcnQpJiZyLmVuZC5lcXVhbFRvKGkuZW5kKT9uPWwuT1ZFUkxBUF9TQU1FOnIuc3RhcnQuZXF1YWxUbyhpLmVuZCkmJnIuZW5kLmVxdWFsVG8oaS5zdGFydCkmJihuPWwuT1ZFUkxBUF9PUFBPU0lURSk6KHIgaW5zdGFuY2VvZiBsLkFyYyYmaSBpbnN0YW5jZW9mIGwuQXJjfHxyIGluc3RhbmNlb2YgbC5TZWdtZW50JiZpIGluc3RhbmNlb2YgbC5BcmN8fHIgaW5zdGFuY2VvZiBsLkFyYyYmaSBpbnN0YW5jZW9mIGwuU2VnbWVudCkmJihyLnN0YXJ0LmVxdWFsVG8oaS5zdGFydCkmJnIuZW5kLmVxdWFsVG8oaS5lbmQpJiZyLm1pZGRsZSgpLmVxdWFsVG8oaS5taWRkbGUoKSk/bj1sLk9WRVJMQVBfU0FNRTpyLnN0YXJ0LmVxdWFsVG8oaS5lbmQpJiZyLmVuZC5lcXVhbFRvKGkuc3RhcnQpJiZyLm1pZGRsZSgpLmVxdWFsVG8oaS5taWRkbGUoKSkmJihuPWwuT1ZFUkxBUF9PUFBPU0lURSkpLHRoaXMub3ZlcmxhcD09PXZvaWQgMCYmKHRoaXMub3ZlcmxhcD1uKSx0Lm92ZXJsYXA9PT12b2lkIDAmJih0Lm92ZXJsYXA9bil9c3ZnKCl7aWYodGhpcy5zaGFwZSBpbnN0YW5jZW9mIGwuU2VnbWVudClyZXR1cm5gIEwke3RoaXMuc2hhcGUuZW5kLnh9LCR7dGhpcy5zaGFwZS5lbmQueX1gO2lmKHRoaXMuc2hhcGUgaW5zdGFuY2VvZiBsLkFyYyl7bGV0IHQ9dGhpcy5zaGFwZSxuLHI9dC5jb3VudGVyQ2xvY2t3aXNlPyIxIjoiMCI7aWYobC5VdGlscy5FUSh0LnN3ZWVwLDIqTWF0aC5QSSkpe2xldCBpPXQuY291bnRlckNsb2Nrd2lzZT8xOi0xLHM9bmV3IGwuQXJjKHQucGMsdC5yLHQuc3RhcnRBbmdsZSx0LnN0YXJ0QW5nbGUraSpNYXRoLlBJLHQuY291bnRlckNsb2Nrd2lzZSksbz1uZXcgbC5BcmModC5wYyx0LnIsdC5zdGFydEFuZ2xlK2kqTWF0aC5QSSx0LmVuZEFuZ2xlLHQuY291bnRlckNsb2Nrd2lzZSk7cmV0dXJuIG49IjAiLGAgQSR7cy5yfSwke3Mucn0gMCAke259LCR7cn0gJHtzLmVuZC54fSwke3MuZW5kLnl9CiAgICAgICAgICAgICAgICAgICAgQSR7by5yfSwke28ucn0gMCAke259LCR7cn0gJHtvLmVuZC54fSwke28uZW5kLnl9YH1lbHNlIHJldHVybiBuPXQuc3dlZXA8PU1hdGguUEk/IjAiOiIxIixgIEEke3Qucn0sJHt0LnJ9IDAgJHtufSwke3J9ICR7dC5lbmQueH0sJHt0LmVuZC55fWB9fXRvSlNPTigpe3JldHVybiB0aGlzLnNoYXBlLnRvSlNPTigpfX1sLkVkZ2U9SGQ7Y2xhc3MgSmQgZXh0ZW5kcyBoaXtjb25zdHJ1Y3Rvcih0LG4pe3N1cGVyKHQsbiksdGhpcy5zZXRDaXJjdWxhckxpbmtzKCl9c2V0Q2lyY3VsYXJMaW5rcygpe3RoaXMuaXNFbXB0eSgpfHwodGhpcy5sYXN0Lm5leHQ9dGhpcy5maXJzdCx0aGlzLmZpcnN0LnByZXY9dGhpcy5sYXN0KX1bU3ltYm9sLml0ZXJhdG9yXSgpe2xldCB0O3JldHVybntuZXh0OigpPT57bGV0IG49dHx8dGhpcy5maXJzdCxyPXRoaXMuZmlyc3Q/dD90PT09dGhpcy5maXJzdDohMTohMDtyZXR1cm4gdD1uP24ubmV4dDp2b2lkIDAse3ZhbHVlOm4sZG9uZTpyfX19fWFwcGVuZCh0KXtyZXR1cm4gc3VwZXIuYXBwZW5kKHQpLHRoaXMuc2V0Q2lyY3VsYXJMaW5rcygpLHRoaXN9aW5zZXJ0KHQsbil7cmV0dXJuIHN1cGVyLmluc2VydCh0LG4pLHRoaXMuc2V0Q2lyY3VsYXJMaW5rcygpLHRoaXN9cmVtb3ZlKHQpe3JldHVybiBzdXBlci5yZW1vdmUodCksdGhpc319Y2xhc3MgT2UgZXh0ZW5kcyBKZHtjb25zdHJ1Y3Rvcih0LC4uLm4pe2lmKHN1cGVyKCksdGhpcy5fYm94PXZvaWQgMCx0aGlzLl9vcmllbnRhdGlvbj12b2lkIDAsbi5sZW5ndGghPT0wKXtpZihuLmxlbmd0aD09PTEpe2lmKG5bMF1pbnN0YW5jZW9mIEFycmF5KXtsZXQgcj1uWzBdO2lmKHIubGVuZ3RoPT09MClyZXR1cm47aWYoci5ldmVyeShpPT5pIGluc3RhbmNlb2YgbC5Qb2ludCkpe2xldCBpPU9lLnBvaW50czJzZWdtZW50cyhyKTt0aGlzLnNoYXBlczJmYWNlKHQuZWRnZXMsaSl9ZWxzZSBpZihyLmV2ZXJ5KGk9PmkgaW5zdGFuY2VvZiBBcnJheSYmaS5sZW5ndGg9PT0yKSl7bGV0IGk9ci5tYXAobz0+bmV3IGwuUG9pbnQob1swXSxvWzFdKSkscz1PZS5wb2ludHMyc2VnbWVudHMoaSk7dGhpcy5zaGFwZXMyZmFjZSh0LmVkZ2VzLHMpfWVsc2UgaWYoci5ldmVyeShpPT5pIGluc3RhbmNlb2YgbC5TZWdtZW50fHxpIGluc3RhbmNlb2YgbC5BcmMpKXRoaXMuc2hhcGVzMmZhY2UodC5lZGdlcyxyKTtlbHNlIGlmKHIuZXZlcnkoaT0+aS5uYW1lPT09InNlZ21lbnQifHxpLm5hbWU9PT0iYXJjIikpe2xldCBpPVtdO2ZvcihsZXQgcyBvZiByKXtsZXQgbztzLm5hbWU9PT0ic2VnbWVudCI/bz1uZXcgbC5TZWdtZW50KHMpOm89bmV3IGwuQXJjKHMpLGkucHVzaChvKX10aGlzLnNoYXBlczJmYWNlKHQuZWRnZXMsaSl9fWVsc2UgaWYoblswXWluc3RhbmNlb2YgT2Upe2xldCByPW5bMF07dGhpcy5maXJzdD1yLmZpcnN0LHRoaXMubGFzdD1yLmxhc3Q7Zm9yKGxldCBpIG9mIHIpdC5lZGdlcy5hZGQoaSl9ZWxzZSBpZihuWzBdaW5zdGFuY2VvZiBsLkNpcmNsZSl0aGlzLnNoYXBlczJmYWNlKHQuZWRnZXMsW25bMF0udG9BcmMoVWMpXSk7ZWxzZSBpZihuWzBdaW5zdGFuY2VvZiBsLkJveCl7bGV0IHI9blswXTt0aGlzLnNoYXBlczJmYWNlKHQuZWRnZXMsW25ldyBsLlNlZ21lbnQobmV3IGwuUG9pbnQoci54bWluLHIueW1pbiksbmV3IGwuUG9pbnQoci54bWF4LHIueW1pbikpLG5ldyBsLlNlZ21lbnQobmV3IGwuUG9pbnQoci54bWF4LHIueW1pbiksbmV3IGwuUG9pbnQoci54bWF4LHIueW1heCkpLG5ldyBsLlNlZ21lbnQobmV3IGwuUG9pbnQoci54bWF4LHIueW1heCksbmV3IGwuUG9pbnQoci54bWluLHIueW1heCkpLG5ldyBsLlNlZ21lbnQobmV3IGwuUG9pbnQoci54bWluLHIueW1heCksbmV3IGwuUG9pbnQoci54bWluLHIueW1pbikpXSl9fW4ubGVuZ3RoPT09MiYmblswXWluc3RhbmNlb2YgbC5FZGdlJiZuWzFdaW5zdGFuY2VvZiBsLkVkZ2UmJih0aGlzLmZpcnN0PW5bMF0sdGhpcy5sYXN0PW5bMV0sdGhpcy5sYXN0Lm5leHQ9dGhpcy5maXJzdCx0aGlzLmZpcnN0LnByZXY9dGhpcy5sYXN0LHRoaXMuc2V0QXJjTGVuZ3RoKCkpfX1nZXQgZWRnZXMoKXtyZXR1cm4gdGhpcy50b0FycmF5KCl9Z2V0IHZlcnRpY2VzKCl7cmV0dXJuIHRoaXMuZWRnZXMubWFwKHQ9PnQuc2hhcGUuc3RhcnQuY2xvbmUoKSl9Z2V0IHNoYXBlcygpe3JldHVybiB0aGlzLmVkZ2VzLm1hcCh0PT50LnNoYXBlLmNsb25lKCkpfWdldCBib3goKXtpZih0aGlzLl9ib3g9PT12b2lkIDApe2xldCB0PW5ldyBsLkJveDtmb3IobGV0IG4gb2YgdGhpcyl0PXQubWVyZ2Uobi5ib3gpO3RoaXMuX2JveD10fXJldHVybiB0aGlzLl9ib3h9Z2V0IHBlcmltZXRlcigpe3JldHVybiB0aGlzLmxhc3QuYXJjX2xlbmd0aCt0aGlzLmxhc3QubGVuZ3RofXBvaW50QXRMZW5ndGgodCl7aWYodD50aGlzLnBlcmltZXRlcnx8dDwwKXJldHVybiBudWxsO2xldCBuPW51bGw7Zm9yKGxldCByIG9mIHRoaXMpaWYodD49ci5hcmNfbGVuZ3RoJiYocj09PXRoaXMubGFzdHx8dDxyLm5leHQuYXJjX2xlbmd0aCkpe249ci5wb2ludEF0TGVuZ3RoKHQtci5hcmNfbGVuZ3RoKTticmVha31yZXR1cm4gbn1zdGF0aWMgcG9pbnRzMnNlZ21lbnRzKHQpe2xldCBuPVtdO2ZvcihsZXQgcj0wO3I8dC5sZW5ndGg7cisrKXRbcl0uZXF1YWxUbyh0WyhyKzEpJXQubGVuZ3RoXSl8fG4ucHVzaChuZXcgbC5TZWdtZW50KHRbcl0sdFsocisxKSV0Lmxlbmd0aF0pKTtyZXR1cm4gbn1zaGFwZXMyZmFjZSh0LG4pe2ZvcihsZXQgciBvZiBuKXtsZXQgaT1uZXcgbC5FZGdlKHIpO3RoaXMuYXBwZW5kKGkpLHQuYWRkKGkpfX1hcHBlbmQodCl7cmV0dXJuIHN1cGVyLmFwcGVuZCh0KSx0aGlzLnNldE9uZUVkZ2VBcmNMZW5ndGgodCksdC5mYWNlPXRoaXMsdGhpc31pbnNlcnQodCxuKXtyZXR1cm4gc3VwZXIuaW5zZXJ0KHQsbiksdGhpcy5zZXRPbmVFZGdlQXJjTGVuZ3RoKHQpLHQuZmFjZT10aGlzLHRoaXN9cmVtb3ZlKHQpe3JldHVybiBzdXBlci5yZW1vdmUodCksdGhpcy5zZXRBcmNMZW5ndGgoKSx0aGlzfW1lcmdlX3dpdGhfbmV4dF9lZGdlKHQpe3JldHVybiB0LnNoYXBlLmVuZC54PXQubmV4dC5zaGFwZS5lbmQueCx0LnNoYXBlLmVuZC55PXQubmV4dC5zaGFwZS5lbmQueSx0aGlzLnJlbW92ZSh0Lm5leHQpLHRoaXN9cmV2ZXJzZSgpe2xldCB0PVtdLG49dGhpcy5sYXN0O2RvIG4uc2hhcGU9bi5zaGFwZS5yZXZlcnNlKCksdC5wdXNoKG4pLG49bi5wcmV2O3doaWxlKG4hPT10aGlzLmxhc3QpO3RoaXMuZmlyc3Q9dm9pZCAwLHRoaXMubGFzdD12b2lkIDA7Zm9yKGxldCByIG9mIHQpdGhpcy5maXJzdD09PXZvaWQgMD8oci5wcmV2PXIsci5uZXh0PXIsdGhpcy5maXJzdD1yLHRoaXMubGFzdD1yKTooci5wcmV2PXRoaXMubGFzdCx0aGlzLmxhc3QubmV4dD1yLHRoaXMubGFzdD1yLHRoaXMubGFzdC5uZXh0PXRoaXMuZmlyc3QsdGhpcy5maXJzdC5wcmV2PXRoaXMubGFzdCksdGhpcy5zZXRPbmVFZGdlQXJjTGVuZ3RoKHIpO3RoaXMuX29yaWVudGF0aW9uIT09dm9pZCAwJiYodGhpcy5fb3JpZW50YXRpb249dm9pZCAwLHRoaXMuX29yaWVudGF0aW9uPXRoaXMub3JpZW50YXRpb24oKSl9c2V0QXJjTGVuZ3RoKCl7Zm9yKGxldCB0IG9mIHRoaXMpdGhpcy5zZXRPbmVFZGdlQXJjTGVuZ3RoKHQpLHQuZmFjZT10aGlzfXNldE9uZUVkZ2VBcmNMZW5ndGgodCl7dD09PXRoaXMuZmlyc3Q/dC5hcmNfbGVuZ3RoPTA6dC5hcmNfbGVuZ3RoPXQucHJldi5hcmNfbGVuZ3RoK3QucHJldi5sZW5ndGh9YXJlYSgpe3JldHVybiBNYXRoLmFicyh0aGlzLnNpZ25lZEFyZWEoKSl9c2lnbmVkQXJlYSgpe2xldCB0PTAsbj10aGlzLmJveC55bWluO2ZvcihsZXQgciBvZiB0aGlzKXQrPXIuc2hhcGUuZGVmaW5pdGVJbnRlZ3JhbChuKTtyZXR1cm4gdH1vcmllbnRhdGlvbigpe2lmKHRoaXMuX29yaWVudGF0aW9uPT09dm9pZCAwKXtsZXQgdD10aGlzLnNpZ25lZEFyZWEoKTtsLlV0aWxzLkVRXzAodCk/dGhpcy5fb3JpZW50YXRpb249emUuTk9UX09SSUVOVEFCTEU6bC5VdGlscy5MVCh0LDApP3RoaXMuX29yaWVudGF0aW9uPXplLkNDVzp0aGlzLl9vcmllbnRhdGlvbj16ZS5DV31yZXR1cm4gdGhpcy5fb3JpZW50YXRpb259aXNTaW1wbGUodCl7cmV0dXJuIE9lLmdldFNlbGZJbnRlcnNlY3Rpb25zKHRoaXMsdCwhMCkubGVuZ3RoPT09MH1zdGF0aWMgZ2V0U2VsZkludGVyc2VjdGlvbnModCxuLHI9ITEpe2xldCBpPVtdO2ZvcihsZXQgcyBvZiB0KXtsZXQgbz1uLnNlYXJjaChzLmJveCk7Zm9yKGxldCBjIG9mIG8pe2lmKHM9PT1jfHxjLmZhY2UhPT10fHxzLnNoYXBlIGluc3RhbmNlb2YgbC5TZWdtZW50JiZjLnNoYXBlIGluc3RhbmNlb2YgbC5TZWdtZW50JiYocy5uZXh0PT09Y3x8cy5wcmV2PT09YykpY29udGludWU7bGV0IGE9cy5zaGFwZS5pbnRlcnNlY3QoYy5zaGFwZSk7Zm9yKGxldCBoIG9mIGEpaWYoIShoLmVxdWFsVG8ocy5zdGFydCkmJmguZXF1YWxUbyhjLmVuZCkmJmM9PT1zLnByZXYpJiYhKGguZXF1YWxUbyhzLmVuZCkmJmguZXF1YWxUbyhjLnN0YXJ0KSYmYz09PXMubmV4dCkmJihpLnB1c2goaCkscikpYnJlYWs7aWYoaS5sZW5ndGg+MCYmcilicmVha31pZihpLmxlbmd0aD4wJiZyKWJyZWFrfXJldHVybiBpfWZpbmRFZGdlQnlQb2ludCh0KXtsZXQgbjtmb3IobGV0IHIgb2YgdGhpcylpZighdC5lcXVhbFRvKHIuc2hhcGUuc3RhcnQpJiYodC5lcXVhbFRvKHIuc2hhcGUuZW5kKXx8ci5zaGFwZS5jb250YWlucyh0KSkpe249cjticmVha31yZXR1cm4gbn10b1BvbHlnb24oKXtyZXR1cm4gbmV3IGwuUG9seWdvbih0aGlzLnNoYXBlcyl9dG9KU09OKCl7cmV0dXJuIHRoaXMuZWRnZXMubWFwKHQ9PnQudG9KU09OKCkpfXN2Zygpe2xldCB0PWBNJHt0aGlzLmZpcnN0LnN0YXJ0Lnh9LCR7dGhpcy5maXJzdC5zdGFydC55fWA7Zm9yKGxldCBuIG9mIHRoaXMpdCs9bi5zdmcoKTtyZXR1cm4gdCs9IiB6Iix0fX1sLkZhY2U9T2U7Y2xhc3MgdmkgZXh0ZW5kcyBEdHtjb25zdHJ1Y3RvciguLi50KXtpZihzdXBlcigpLHRoaXMucHQ9bmV3IGwuUG9pbnQsdGhpcy5ub3JtPW5ldyBsLlZlY3RvcigwLDEpLHQubGVuZ3RoIT09MCYmKHQubGVuZ3RoPj0xJiZ0WzBdaW5zdGFuY2VvZiBsLlBvaW50JiYodGhpcy5wdD10WzBdLmNsb25lKCkpLHQubGVuZ3RoIT09MSkpe2lmKHQubGVuZ3RoPT09MiYmdFsxXWluc3RhbmNlb2YgbC5WZWN0b3Ipe3RoaXMubm9ybT10WzFdLmNsb25lKCk7cmV0dXJufXRocm93IFkuSUxMRUdBTF9QQVJBTUVURVJTfX1jbG9uZSgpe3JldHVybiBuZXcgdmkodGhpcy5wdCx0aGlzLm5vcm0pfWdldCBzbG9wZSgpe3JldHVybiBuZXcgbC5WZWN0b3IodGhpcy5ub3JtLnksLXRoaXMubm9ybS54KS5zbG9wZX1nZXQgYm94KCl7bGV0IHQ9dGhpcy5zbG9wZTtyZXR1cm4gbmV3IGwuQm94KHQ+TWF0aC5QSS8yJiZ0PDMqTWF0aC5QSS8yP051bWJlci5ORUdBVElWRV9JTkZJTklUWTp0aGlzLnB0LngsdD49MCYmdDw9TWF0aC5QST90aGlzLnB0Lnk6TnVtYmVyLk5FR0FUSVZFX0lORklOSVRZLHQ+PU1hdGguUEkvMiYmdDw9MypNYXRoLlBJLzI/dGhpcy5wdC54Ok51bWJlci5QT1NJVElWRV9JTkZJTklUWSx0Pj1NYXRoLlBJJiZ0PD0yKk1hdGguUEl8fHQ9PT0wP3RoaXMucHQueTpOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFkpfWdldCBzdGFydCgpe3JldHVybiB0aGlzLnB0fWdldCBlbmQoKXt9Z2V0IGxlbmd0aCgpe3JldHVybiBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFl9Y29udGFpbnModCl7aWYodGhpcy5wdC5lcXVhbFRvKHQpKXJldHVybiEwO2xldCBuPW5ldyBsLlZlY3Rvcih0aGlzLnB0LHQpO3JldHVybiBsLlV0aWxzLkVRXzAodGhpcy5ub3JtLmRvdChuKSkmJmwuVXRpbHMuR0Uobi5jcm9zcyh0aGlzLm5vcm0pLDApfWNvb3JkKHQpe3JldHVybiBPYSh0LngsdC55KS5jcm9zcyh0aGlzLm5vcm0pfXNwbGl0KHQpe3JldHVybiB0aGlzLmNvbnRhaW5zKHQpP3RoaXMucHQuZXF1YWxUbyh0KT9bdGhpc106W25ldyBsLlNlZ21lbnQodGhpcy5wdCx0KSxuZXcgbC5SYXkodCx0aGlzLm5vcm0pXTpbXX1pbnRlcnNlY3QodCl7aWYodCBpbnN0YW5jZW9mIGwuUG9pbnQpcmV0dXJuIHRoaXMuY29udGFpbnModCk/W3RdOltdO2lmKHQgaW5zdGFuY2VvZiBsLlNlZ21lbnQpcmV0dXJuIGdpKHRoaXMsdCk7aWYodCBpbnN0YW5jZW9mIGwuQXJjKXJldHVybiBtaSh0aGlzLHQpO2lmKHQgaW5zdGFuY2VvZiBsLkxpbmUpcmV0dXJuIG9hKHRoaXMsdCk7aWYodCBpbnN0YW5jZW9mIGwuUmF5KXJldHVybiBmZCh0aGlzLHQpO2lmKHQgaW5zdGFuY2VvZiBsLkNpcmNsZSlyZXR1cm4gc2EodGhpcyx0KTtpZih0IGluc3RhbmNlb2YgbC5Cb3gpcmV0dXJuIGhkKHRoaXMsdCk7aWYodCBpbnN0YW5jZW9mIGwuUG9seWdvbilyZXR1cm4gY2EodGhpcyx0KTtpZih0IGluc3RhbmNlb2YgbC5NdWx0aWxpbmUpcmV0dXJuIF9lKHRoaXMsdCl9cm90YXRlKHQsbj1uZXcgbC5Qb2ludCl7cmV0dXJuIG5ldyBsLlJheSh0aGlzLnB0LnJvdGF0ZSh0LG4pLHRoaXMubm9ybS5yb3RhdGUodCkpfXRyYW5zZm9ybSh0KXtyZXR1cm4gbmV3IGwuUmF5KHRoaXMucHQudHJhbnNmb3JtKHQpLHRoaXMubm9ybS5jbG9uZSgpKX1nZXQgbmFtZSgpe3JldHVybiJyYXkifXN2Zyh0LG49e30pe2xldCByPW5ldyBsLkxpbmUodGhpcy5wdCx0aGlzLm5vcm0pLGk9bWUocix0KTtyZXR1cm4gaT1pLmZpbHRlcihvPT50aGlzLmNvbnRhaW5zKG8pKSxpLmxlbmd0aD09PTB8fGkubGVuZ3RoPT09Mj8iIjpuZXcgbC5TZWdtZW50KHRoaXMucHQsaVswXSkuc3ZnKG4pfX1sLlJheT12aTtjb25zdCB0Zz0oLi4uZSk9Pm5ldyBsLlJheSguLi5lKTtsLnJheT10ZztsZXQgR2U9Y2xhc3MgWXR7Y29uc3RydWN0b3IoKXt0aGlzLmZhY2VzPW5ldyBsLlBsYW5hclNldCx0aGlzLmVkZ2VzPW5ldyBsLlBsYW5hclNldDtsZXQgdD1bLi4uYXJndW1lbnRzXTtpZih0Lmxlbmd0aD09PTEmJih0WzBdaW5zdGFuY2VvZiBBcnJheSYmdFswXS5sZW5ndGg+MHx8dFswXWluc3RhbmNlb2YgbC5DaXJjbGV8fHRbMF1pbnN0YW5jZW9mIGwuQm94KSl7bGV0IG49dFswXTtpZih0WzBdaW5zdGFuY2VvZiBBcnJheSYmdFswXS5ldmVyeShyPT5yIGluc3RhbmNlb2YgQXJyYXkpKWlmKG4uZXZlcnkocj0+ciBpbnN0YW5jZW9mIEFycmF5JiZyLmxlbmd0aD09PTImJnR5cGVvZiByWzBdPT0ibnVtYmVyIiYmdHlwZW9mIHJbMV09PSJudW1iZXIiKSl0aGlzLmZhY2VzLmFkZChuZXcgbC5GYWNlKHRoaXMsbikpO2Vsc2UgZm9yKGxldCByIG9mIG4paWYociBpbnN0YW5jZW9mIEFycmF5JiZyWzBdaW5zdGFuY2VvZiBBcnJheSYmclswXS5ldmVyeShpPT5pIGluc3RhbmNlb2YgQXJyYXkmJmkubGVuZ3RoPT09MiYmdHlwZW9mIGlbMF09PSJudW1iZXIiJiZ0eXBlb2YgaVsxXT09Im51bWJlciIpKWZvcihsZXQgaSBvZiByKXRoaXMuZmFjZXMuYWRkKG5ldyBsLkZhY2UodGhpcyxpKSk7ZWxzZSB0aGlzLmZhY2VzLmFkZChuZXcgbC5GYWNlKHRoaXMscikpO2Vsc2UgdGhpcy5mYWNlcy5hZGQobmV3IGwuRmFjZSh0aGlzLG4pKX19Z2V0IGJveCgpe3JldHVyblsuLi50aGlzLmZhY2VzXS5yZWR1Y2UoKHQsbik9PnQubWVyZ2Uobi5ib3gpLG5ldyBsLkJveCl9Z2V0IHZlcnRpY2VzKCl7cmV0dXJuWy4uLnRoaXMuZmFjZXNdLmZsYXRNYXAodD0+dC52ZXJ0aWNlcyl9Y2xvbmUoKXtsZXQgdD1uZXcgWXQ7Zm9yKGxldCBuIG9mIHRoaXMuZmFjZXMpdC5hZGRGYWNlKG4uc2hhcGVzKTtyZXR1cm4gdH1jcmVhdGVGcm9tQXJyYXkodCl7Y29uc3Qgbj1uZXcgWXQ7cmV0dXJuIHQuZm9yRWFjaChyPT5bLi4uci5mYWNlc10uZm9yRWFjaChpPT5uLmFkZEZhY2UoaS5zaGFwZXMpKSksbn1pc0VtcHR5KCl7cmV0dXJuIHRoaXMuZWRnZXMuc2l6ZT09PTB8fHRoaXMuZmFjZXMuc2l6ZT09PTB9aXNWYWxpZCgpe2xldCB0PSEwO2ZvcihsZXQgbiBvZiB0aGlzLmZhY2VzKWlmKCFuLmlzU2ltcGxlKHRoaXMuZWRnZXMpKXt0PSExO2JyZWFrfXJldHVybiB0fWFyZWEoKXtsZXQgdD1bLi4udGhpcy5mYWNlc10ucmVkdWNlKChuLHIpPT5uK3Iuc2lnbmVkQXJlYSgpLDApO3JldHVybiBNYXRoLmFicyh0KX1hZGRGYWNlKC4uLnQpe2xldCBuPW5ldyBsLkZhY2UodGhpcywuLi50KTtyZXR1cm4gdGhpcy5mYWNlcy5hZGQobiksbn1kZWxldGVGYWNlKHQpe2ZvcihsZXQgbiBvZiB0KXRoaXMuZWRnZXMuZGVsZXRlKG4pO3JldHVybiB0aGlzLmZhY2VzLmRlbGV0ZSh0KX1yZWNyZWF0ZUZhY2VzKCl7dGhpcy5mYWNlcy5jbGVhcigpO2ZvcihsZXQgciBvZiB0aGlzLmVkZ2VzKXIuZmFjZT1udWxsO2xldCB0LG49ITA7Zm9yKDtuOyl7bj0hMTtmb3IobGV0IHIgb2YgdGhpcy5lZGdlcylpZihyLmZhY2U9PT1udWxsKXt0PXIsbj0hMDticmVha31pZihuKXtsZXQgcj10O2RvIHI9ci5uZXh0O3doaWxlKHIubmV4dCE9PXQpO3RoaXMuYWRkRmFjZSh0LHIpfX19cmVtb3ZlQ2hhaW4odCxuLHIpe2lmKHIubmV4dD09PW4pe3RoaXMuZGVsZXRlRmFjZSh0KTtyZXR1cm59Zm9yKGxldCBpPW47aSE9PXIubmV4dDtpPWkubmV4dClpZih0LnJlbW92ZShpKSx0aGlzLmVkZ2VzLmRlbGV0ZShpKSx0LmlzRW1wdHkoKSl7dGhpcy5kZWxldGVGYWNlKHQpO2JyZWFrfX1hZGRWZXJ0ZXgodCxuKXtsZXQgcj1uLnNoYXBlLnNwbGl0KHQpO2lmKHJbMF09PT1udWxsKXJldHVybiBuLnByZXY7aWYoclsxXT09PW51bGwpcmV0dXJuIG47bGV0IGk9bmV3IGwuRWRnZShyWzBdKSxzPW4ucHJldjtyZXR1cm4gbi5mYWNlLmluc2VydChpLHMpLHRoaXMuZWRnZXMuZGVsZXRlKG4pLHRoaXMuZWRnZXMuYWRkKGkpLG4uc2hhcGU9clsxXSx0aGlzLmVkZ2VzLmFkZChuKSxpfXJlbW92ZUVuZFZlcnRleCh0KXtjb25zdCBuPXQubmV4dDtuIT09dCYmKHQuZmFjZS5tZXJnZV93aXRoX25leHRfZWRnZSh0KSx0aGlzLmVkZ2VzLmRlbGV0ZShuKSl9Y3V0KHQpe2NvbnN0IHI9dGhpcy5zcGxpdFRvSXNsYW5kcygpLmZsYXRNYXAoaT0+aS5fY3V0U2luZ2xlSXNsYW5kKHQpKS5maWx0ZXIoaT0+aS5pc1ZhbGlkKCkmJmkuaXNFbXB0eSgpPT09ITEpO3JldHVybiB0aGlzLmNyZWF0ZUZyb21BcnJheShyKX1fY3V0U2luZ2xlSXNsYW5kKHQpe2xldCBuPXRoaXMuY2xvbmUoKTtjb25zdCByPXQuY2xvbmUoKTtsZXQgaT17aW50X3BvaW50czE6W10saW50X3BvaW50czI6W10saW50X3BvaW50czFfc29ydGVkOltdLGludF9wb2ludHMyX3NvcnRlZDpbXX07Zm9yKGxldCBjIG9mIHIuZWRnZXMpZm9yKGxldCBhIG9mIG4uZWRnZXMpe2xldCBoPW5hKGMsYSk7Zm9yKGxldCBmIG9mIGgpeWUoYyxmLGkuaW50X3BvaW50czEpLHllKGEsZixpLmludF9wb2ludHMyKX1pZihpLmludF9wb2ludHMxLmxlbmd0aD09PTApcmV0dXJuIG47aS5pbnRfcG9pbnRzMV9zb3J0ZWQ9QnQoaS5pbnRfcG9pbnRzMSksaS5pbnRfcG9pbnRzMl9zb3J0ZWQ9QnQoaS5pbnRfcG9pbnRzMiksTWUocixpLmludF9wb2ludHMxX3NvcnRlZCksTWUobixpLmludF9wb2ludHMyX3NvcnRlZCkscGkoaSksaS5pbnRfcG9pbnRzMV9zb3J0ZWQ9QnQoaS5pbnRfcG9pbnRzMSksaS5pbnRfcG9pbnRzMl9zb3J0ZWQ9QnQoaS5pbnRfcG9pbnRzMiksX2koaS5pbnRfcG9pbnRzMSkseWkoaS5pbnRfcG9pbnRzMSxuKTtmb3IobGV0IGMgb2YgaS5pbnRfcG9pbnRzMV9zb3J0ZWQpYy5lZGdlX2JlZm9yZSYmYy5lZGdlX2FmdGVyJiZjLmVkZ2VfYmVmb3JlLmJ2PT09Yy5lZGdlX2FmdGVyLmJ2JiYoaS5pbnRfcG9pbnRzMltjLmlkXT0tMSxjLmlkPS0xKTtpZihpLmludF9wb2ludHMxPWkuaW50X3BvaW50czEuZmlsdGVyKGM9PmMuaWQ+PTApLGkuaW50X3BvaW50czI9aS5pbnRfcG9pbnRzMi5maWx0ZXIoYz0+Yy5pZD49MCksaS5pbnRfcG9pbnRzMS5mb3JFYWNoKChjLGEpPT57Yy5pZD1hfSksaS5pbnRfcG9pbnRzMi5mb3JFYWNoKChjLGEpPT57Yy5pZD1hfSksaS5pbnRfcG9pbnRzMS5sZW5ndGg9PT0wKXJldHVybiBuO2kuaW50X3BvaW50czFfc29ydGVkPUJ0KGkuaW50X3BvaW50czEpLGkuaW50X3BvaW50czJfc29ydGVkPUJ0KGkuaW50X3BvaW50czIpO2xldCBzLG87Zm9yKGxldCBjPTE7YzxpLmludF9wb2ludHMxX3NvcnRlZC5sZW5ndGg7YysrKWlmKG89aS5pbnRfcG9pbnRzMV9zb3J0ZWRbY10scz1pLmludF9wb2ludHMxX3NvcnRlZFtjLTFdLG8uZWRnZV9iZWZvcmUmJm8uZWRnZV9iZWZvcmUuYnY9PT1Vbil7bGV0IGE9cy5lZGdlX2FmdGVyLGg9by5lZGdlX2JlZm9yZSxmPXIuZ2V0Q2hhaW4oYSxoKTtsYShpLmludF9wb2ludHMyW3MuaWRdLGkuaW50X3BvaW50czJbby5pZF0sZiksZi5mb3JFYWNoKHU9Pm4uZWRnZXMuYWRkKHUpKSxmPWYucmV2ZXJzZSgpLm1hcCh1PT5uZXcgbC5FZGdlKHUuc2hhcGUucmV2ZXJzZSgpKSk7Zm9yKGxldCB1PTA7dTxmLmxlbmd0aC0xO3UrKylmW3VdLm5leHQ9Zlt1KzFdLGZbdSsxXS5wcmV2PWZbdV07bGEoaS5pbnRfcG9pbnRzMltvLmlkXSxpLmludF9wb2ludHMyW3MuaWRdLGYpLGYuZm9yRWFjaCh1PT5uLmVkZ2VzLmFkZCh1KSl9cmV0dXJuIG4ucmVjcmVhdGVGYWNlcygpLG59Y3V0V2l0aExpbmUodCl7bGV0IG49bmV3IG5lKFt0XSk7cmV0dXJuIHRoaXMuY3V0KG4pfWZpbmRFZGdlQnlQb2ludCh0KXtsZXQgbjtmb3IobGV0IHIgb2YgdGhpcy5mYWNlcylpZihuPXIuZmluZEVkZ2VCeVBvaW50KHQpLG4hPT12b2lkIDApYnJlYWs7cmV0dXJuIG59c3BsaXRUb0lzbGFuZHMoKXtpZih0aGlzLmlzRW1wdHkoKSlyZXR1cm5bXTtsZXQgdD10aGlzLnRvQXJyYXkoKTt0LnNvcnQoKGkscyk9PnMuYXJlYSgpLWkuYXJlYSgpKTtsZXQgbj1bLi4udFswXS5mYWNlc11bMF0ub3JpZW50YXRpb24oKSxyPXQuZmlsdGVyKGk9PlsuLi5pLmZhY2VzXVswXS5vcmllbnRhdGlvbigpPT09bik7Zm9yKGxldCBpIG9mIHQpe2xldCBzPVsuLi5pLmZhY2VzXVswXTtpZihzLm9yaWVudGF0aW9uKCkhPT1uKXtmb3IobGV0IG8gb2YgcilpZihzLnNoYXBlcy5ldmVyeShjPT5vLmNvbnRhaW5zKGMpKSl7by5hZGRGYWNlKHMuc2hhcGVzKTticmVha319fXJldHVybiByfXJlYXJyYW5nZSgpe2lmKHRoaXMuZmFjZXMuc2l6ZTw9MSlyZXR1cm4gdGhpcy5jbG9uZSgpO2NvbnN0IHQ9dGhpcy5zcGxpdFRvSXNsYW5kcygpLG49bmV3IFl0O3JldHVybiB0LmZvckVhY2gocj0+e3IuZmFjZXMuZm9yRWFjaChpPT5uLmFkZEZhY2UoaS5zaGFwZXMpKX0pLG59b3JpZW50YXRpb24oKXtyZXR1cm4gdGhpcy5pc0VtcHR5KCk/emUuTk9UX09SSUVOVEFCTEU6Wy4uLnRoaXMuZmFjZXNdWzBdLm9yaWVudGF0aW9uKCl9aXNPdXRlcih0KXtyZXR1cm4gdC5vcmllbnRhdGlvbigpPT09dGhpcy5vcmllbnRhdGlvbigpfWlzTXVsdGlQb2x5Z29uKCl7bGV0IHQ9MDtyZXR1cm4gdGhpcy5mYWNlcy5mb3JFYWNoKG49Pnt0aGlzLmlzT3V0ZXIobikmJnQrK30pLHQ+MX1yZXZlcnNlKCl7Zm9yKGxldCB0IG9mIHRoaXMuZmFjZXMpdC5yZXZlcnNlKCk7cmV0dXJuIHRoaXN9Y29udGFpbnModCl7aWYodCBpbnN0YW5jZW9mIGwuUG9pbnQpe2xldCBuPVdlKHRoaXMsdCk7cmV0dXJuIG49PT1Vbnx8bj09PXd0fWVsc2UgcmV0dXJuIFRhKHRoaXMsdCl9ZGlzdGFuY2VUbyh0KXtpZih0IGluc3RhbmNlb2YgbC5Qb2ludCl7bGV0W24scl09bC5EaXN0YW5jZS5wb2ludDJwb2x5Z29uKHQsdGhpcyk7cmV0dXJuIHI9ci5yZXZlcnNlKCksW24scl19aWYodCBpbnN0YW5jZW9mIGwuQ2lyY2xlfHx0IGluc3RhbmNlb2YgbC5MaW5lfHx0IGluc3RhbmNlb2YgbC5TZWdtZW50fHx0IGluc3RhbmNlb2YgbC5BcmMpe2xldFtuLHJdPWwuRGlzdGFuY2Uuc2hhcGUycG9seWdvbih0LHRoaXMpO3JldHVybiByPXIucmV2ZXJzZSgpLFtuLHJdfWlmKHQgaW5zdGFuY2VvZiBsLlBvbHlnb24pe2xldCBuPVtOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFksbmV3IGwuU2VnbWVudF0scixpO2ZvcihsZXQgcyBvZiB0aGlzLmVkZ2VzKXtsZXQgbz1uWzBdO1tyLGldPWwuRGlzdGFuY2Uuc2hhcGUycGxhbmFyU2V0KHMuc2hhcGUsdC5lZGdlcyxvKSxsLlV0aWxzLkxUKHIsbykmJihuPVtyLGldKX1yZXR1cm4gbn19aW50ZXJzZWN0KHQpe2lmKHQgaW5zdGFuY2VvZiBsLlBvaW50KXJldHVybiB0aGlzLmNvbnRhaW5zKHQpP1t0XTpbXTtpZih0IGluc3RhbmNlb2YgbC5MaW5lKXJldHVybiBrZSh0LHRoaXMpO2lmKHQgaW5zdGFuY2VvZiBsLlJheSlyZXR1cm4gY2EodCx0aGlzKTtpZih0IGluc3RhbmNlb2YgbC5DaXJjbGUpcmV0dXJuIGVhKHQsdGhpcyk7aWYodCBpbnN0YW5jZW9mIGwuU2VnbWVudClyZXR1cm4gdWkodCx0aGlzKTtpZih0IGluc3RhbmNlb2YgbC5BcmMpcmV0dXJuIGRpKHQsdGhpcyk7aWYodCBpbnN0YW5jZW9mIGwuUG9seWdvbilyZXR1cm4gYWQodCx0aGlzKTtpZih0IGluc3RhbmNlb2YgbC5NdWx0aWxpbmUpcmV0dXJuIGNkKHQsdGhpcyl9dHJhbnNsYXRlKHQpe2xldCBuPW5ldyBZdDtmb3IobGV0IHIgb2YgdGhpcy5mYWNlcyluLmFkZEZhY2Uoci5zaGFwZXMubWFwKGk9PmkudHJhbnNsYXRlKHQpKSk7cmV0dXJuIG59cm90YXRlKHQ9MCxuPW5ldyBsLlBvaW50KXtsZXQgcj1uZXcgWXQ7Zm9yKGxldCBpIG9mIHRoaXMuZmFjZXMpci5hZGRGYWNlKGkuc2hhcGVzLm1hcChzPT5zLnJvdGF0ZSh0LG4pKSk7cmV0dXJuIHJ9c2NhbGUodCxuKXtsZXQgcj1uZXcgWXQ7Zm9yKGxldCBpIG9mIHRoaXMuZmFjZXMpci5hZGRGYWNlKGkuc2hhcGVzLm1hcChzPT5zLnNjYWxlKHQsbikpKTtyZXR1cm4gcn10cmFuc2Zvcm0odD1uZXcgbC5NYXRyaXgpe2xldCBuPW5ldyBZdDtmb3IobGV0IHIgb2YgdGhpcy5mYWNlcyluLmFkZEZhY2Uoci5zaGFwZXMubWFwKGk9PmkudHJhbnNmb3JtKHQpKSk7cmV0dXJuIG59dG9KU09OKCl7cmV0dXJuWy4uLnRoaXMuZmFjZXNdLm1hcCh0PT50LnRvSlNPTigpKX10b0FycmF5KCl7cmV0dXJuWy4uLnRoaXMuZmFjZXNdLm1hcCh0PT50LnRvUG9seWdvbigpKX1kcGF0aCgpe3JldHVyblsuLi50aGlzLmZhY2VzXS5yZWR1Y2UoKHQsbik9PnQrbi5zdmcoKSwiIil9c3ZnKHQ9e30pe2xldCBuPWAKPHBhdGggJHt0ZSh7ZmlsbFJ1bGU6ImV2ZW5vZGQiLGZpbGw6ImxpZ2h0Y3lhbiIsLi4udH0pfSBkPSJgO2ZvcihsZXQgciBvZiB0aGlzLmZhY2VzKW4rPWAKJHtyLnN2ZygpfWA7cmV0dXJuIG4rPWAiID4KPC9wYXRoPmAsbn19O2wuUG9seWdvbj1HZTtjb25zdCBlZz0oLi4uZSk9Pm5ldyBsLlBvbHlnb24oLi4uZSk7bC5wb2x5Z29uPWVnO2NvbnN0e0NpcmNsZTpFaSxMaW5lOnZhLFBvaW50OkVhLFZlY3RvcjpRbixVdGlsczpiaX09bDtjbGFzcyBqZXtjb25zdHJ1Y3Rvcih0KXt0aGlzLmNpcmNsZT10fWdldCBpbnZlcnNpb25fY2lyY2xlKCl7cmV0dXJuIHRoaXMuY2lyY2xlfXN0YXRpYyBpbnZlcnNlUG9pbnQodCxuKXtjb25zdCByPW5ldyBRbih0LnBjLG4pLGk9dC5yKnQucixzPXIuZG90KHIpO3JldHVybiBiaS5FUV8wKHMpP25ldyBFYShOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFksTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZKTp0LnBjLnRyYW5zbGF0ZShyLm11bHRpcGx5KGkvcykpfXN0YXRpYyBpbnZlcnNlQ2lyY2xlKHQsbil7Y29uc3Qgcj10LnBjLmRpc3RhbmNlVG8obi5wYylbMF07aWYoYmkuRVEocixuLnIpKXtsZXQgaT10LnIqdC5yLygyKm4ucikscz1uZXcgUW4odC5wYyxuLnBjKTtzPXMubm9ybWFsaXplKCk7bGV0IG89dC5wYy50cmFuc2xhdGUocy5tdWx0aXBseShpKSk7cmV0dXJuIG5ldyB2YShvLHMpfWVsc2V7bGV0IGk9bmV3IFFuKHQucGMsbi5wYykscz10LnIqdC5yLyhpLmRvdChpKS1uLnIqbi5yKSxvPXQucGMudHJhbnNsYXRlKGkubXVsdGlwbHkocykpLGM9TWF0aC5hYnMocykqbi5yO3JldHVybiBuZXcgRWkobyxjKX19c3RhdGljIGludmVyc2VMaW5lKHQsbil7Y29uc3RbcixpXT10LnBjLmRpc3RhbmNlVG8obik7aWYoYmkuRVFfMChyKSlyZXR1cm4gbi5jbG9uZSgpO3tsZXQgcz10LnIqdC5yLygyKnIpLG89bmV3IFFuKHQucGMsaS5lbmQpO3JldHVybiBvPW8ubXVsdGlwbHkocy9yKSxuZXcgRWkodC5wYy50cmFuc2xhdGUobykscyl9fWludmVyc2UodCl7aWYodCBpbnN0YW5jZW9mIEVhKXJldHVybiBqZS5pbnZlcnNlUG9pbnQodGhpcy5jaXJjbGUsdCk7aWYodCBpbnN0YW5jZW9mIEVpKXJldHVybiBqZS5pbnZlcnNlQ2lyY2xlKHRoaXMuY2lyY2xlLHQpO2lmKHQgaW5zdGFuY2VvZiB2YSlyZXR1cm4gamUuaW52ZXJzZUxpbmUodGhpcy5jaXJjbGUsdCl9fWwuSW52ZXJzaW9uPWplO2NvbnN0IG5nPWU9Pm5ldyBsLkludmVyc2lvbihlKTtsLmludmVyc2lvbj1uZztjbGFzcyBFe3N0YXRpYyBwb2ludDJwb2ludCh0LG4pe3JldHVybiB0LmRpc3RhbmNlVG8obil9c3RhdGljIHBvaW50MmxpbmUodCxuKXtsZXQgcj10LnByb2plY3Rpb25PbihuKTtyZXR1cm5bbmV3IGwuVmVjdG9yKHQscikubGVuZ3RoLG5ldyBsLlNlZ21lbnQodCxyKV19c3RhdGljIHBvaW50MmNpcmNsZSh0LG4pe2xldFtyLGldPXQuZGlzdGFuY2VUbyhuLmNlbnRlcik7aWYobC5VdGlscy5FUV8wKHIpKXJldHVybltuLnIsbmV3IGwuU2VnbWVudCh0LG4udG9BcmMoKS5zdGFydCldO3tsZXQgcz1NYXRoLmFicyhyLW4uciksbz1uZXcgbC5WZWN0b3Iobi5wYyx0KS5ub3JtYWxpemUoKS5tdWx0aXBseShuLnIpLGM9bi5wYy50cmFuc2xhdGUobyk7cmV0dXJuW3MsbmV3IGwuU2VnbWVudCh0LGMpXX19c3RhdGljIHBvaW50MnNlZ21lbnQodCxuKXtpZihuLnN0YXJ0LmVxdWFsVG8obi5lbmQpKXJldHVybiBFLnBvaW50MnBvaW50KHQsbi5zdGFydCk7bGV0IHI9bmV3IGwuVmVjdG9yKG4uc3RhcnQsbi5lbmQpLGk9bmV3IGwuVmVjdG9yKG4uc3RhcnQsdCkscz1uZXcgbC5WZWN0b3Iobi5lbmQsdCksbz1yLmRvdChpKSxjPS1yLmRvdChzKSxhLGg7aWYobC5VdGlscy5HRShvLDApJiZsLlV0aWxzLkdFKGMsMCkpe2xldCBmPW4udGFuZ2VudEluU3RhcnQoKTtyZXR1cm4gYT1NYXRoLmFicyhmLmNyb3NzKGkpKSxoPW4uc3RhcnQudHJhbnNsYXRlKGYubXVsdGlwbHkoZi5kb3QoaSkpKSxbYSxuZXcgbC5TZWdtZW50KHQsaCldfWVsc2UgcmV0dXJuIG88MD90LmRpc3RhbmNlVG8obi5zdGFydCk6dC5kaXN0YW5jZVRvKG4uZW5kKX1zdGF0aWMgcG9pbnQyYXJjKHQsbil7bGV0IHI9bmV3IGwuQ2lyY2xlKG4ucGMsbi5yKSxpPVtdLHMsbztyZXR1cm5bcyxvXT1FLnBvaW50MmNpcmNsZSh0LHIpLG8uZW5kLm9uKG4pJiZpLnB1c2goRS5wb2ludDJjaXJjbGUodCxyKSksaS5wdXNoKEUucG9pbnQycG9pbnQodCxuLnN0YXJ0KSksaS5wdXNoKEUucG9pbnQycG9pbnQodCxuLmVuZCkpLEUuc29ydChpKSxpWzBdfXN0YXRpYyBwb2ludDJlZGdlKHQsbil7cmV0dXJuIG4uc2hhcGUgaW5zdGFuY2VvZiBsLlNlZ21lbnQ/RS5wb2ludDJzZWdtZW50KHQsbi5zaGFwZSk6RS5wb2ludDJhcmModCxuLnNoYXBlKX1zdGF0aWMgc2VnbWVudDJsaW5lKHQsbil7bGV0IHI9dC5pbnRlcnNlY3Qobik7aWYoci5sZW5ndGg+MClyZXR1cm5bMCxuZXcgbC5TZWdtZW50KHJbMF0sclswXSldO2xldCBpPVtdO3JldHVybiBpLnB1c2goRS5wb2ludDJsaW5lKHQuc3RhcnQsbikpLGkucHVzaChFLnBvaW50MmxpbmUodC5lbmQsbikpLEUuc29ydChpKSxpWzBdfXN0YXRpYyBzZWdtZW50MnNlZ21lbnQodCxuKXtsZXQgcj1Xbih0LG4pO2lmKHIubGVuZ3RoPjApcmV0dXJuWzAsbmV3IGwuU2VnbWVudChyWzBdLHJbMF0pXTtsZXQgaT1bXSxzLG87cmV0dXJuW3Msb109RS5wb2ludDJzZWdtZW50KG4uc3RhcnQsdCksaS5wdXNoKFtzLG8ucmV2ZXJzZSgpXSksW3Msb109RS5wb2ludDJzZWdtZW50KG4uZW5kLHQpLGkucHVzaChbcyxvLnJldmVyc2UoKV0pLGkucHVzaChFLnBvaW50MnNlZ21lbnQodC5zdGFydCxuKSksaS5wdXNoKEUucG9pbnQyc2VnbWVudCh0LmVuZCxuKSksRS5zb3J0KGkpLGlbMF19c3RhdGljIHNlZ21lbnQyY2lyY2xlKHQsbil7bGV0IHI9dC5pbnRlcnNlY3Qobik7aWYoci5sZW5ndGg+MClyZXR1cm5bMCxuZXcgbC5TZWdtZW50KHJbMF0sclswXSldO2xldCBpPW5ldyBsLkxpbmUodC5wcyx0LnBlKSxbcyxvXT1FLnBvaW50MmxpbmUobi5jZW50ZXIsaSk7aWYobC5VdGlscy5HRShzLG4ucikmJm8uZW5kLm9uKHQpKXJldHVybiBFLnBvaW50MmNpcmNsZShvLmVuZCxuKTt7bGV0W2MsYV09RS5wb2ludDJjaXJjbGUodC5zdGFydCxuKSxbaCxmXT1FLnBvaW50MmNpcmNsZSh0LmVuZCxuKTtyZXR1cm4gbC5VdGlscy5MVChjLGgpP1tjLGFdOltoLGZdfX1zdGF0aWMgc2VnbWVudDJhcmModCxuKXtsZXQgcj10LmludGVyc2VjdChuKTtpZihyLmxlbmd0aD4wKXJldHVyblswLG5ldyBsLlNlZ21lbnQoclswXSxyWzBdKV07bGV0IGk9bmV3IGwuTGluZSh0LnBzLHQucGUpLHM9bmV3IGwuQ2lyY2xlKG4ucGMsbi5yKSxbbyxjXT1FLnBvaW50MmxpbmUocy5jZW50ZXIsaSk7aWYobC5VdGlscy5HRShvLHMucikmJmMuZW5kLm9uKHQpKXtsZXRbdSxkXT1FLnBvaW50MmNpcmNsZShjLmVuZCxzKTtpZihkLmVuZC5vbihuKSlyZXR1cm5bdSxkXX1sZXQgYT1bXTthLnB1c2goRS5wb2ludDJhcmModC5zdGFydCxuKSksYS5wdXNoKEUucG9pbnQyYXJjKHQuZW5kLG4pKTtsZXQgaCxmO3JldHVybltoLGZdPUUucG9pbnQyc2VnbWVudChuLnN0YXJ0LHQpLGEucHVzaChbaCxmLnJldmVyc2UoKV0pLFtoLGZdPUUucG9pbnQyc2VnbWVudChuLmVuZCx0KSxhLnB1c2goW2gsZi5yZXZlcnNlKCldKSxFLnNvcnQoYSksYVswXX1zdGF0aWMgY2lyY2xlMmNpcmNsZSh0LG4pe2xldCByPXQuaW50ZXJzZWN0KG4pO2lmKHIubGVuZ3RoPjApcmV0dXJuWzAsbmV3IGwuU2VnbWVudChyWzBdLHJbMF0pXTtpZih0LmNlbnRlci5lcXVhbFRvKG4uY2VudGVyKSl7bGV0IGk9dC50b0FyYygpLHM9bi50b0FyYygpO3JldHVybiBFLnBvaW50MnBvaW50KGkuc3RhcnQscy5zdGFydCl9ZWxzZXtsZXQgaT1uZXcgbC5MaW5lKHQuY2VudGVyLG4uY2VudGVyKSxzPWkuaW50ZXJzZWN0KHQpLG89aS5pbnRlcnNlY3QobiksYz1bXTtyZXR1cm4gYy5wdXNoKEUucG9pbnQycG9pbnQoc1swXSxvWzBdKSksYy5wdXNoKEUucG9pbnQycG9pbnQoc1swXSxvWzFdKSksYy5wdXNoKEUucG9pbnQycG9pbnQoc1sxXSxvWzBdKSksYy5wdXNoKEUucG9pbnQycG9pbnQoc1sxXSxvWzFdKSksRS5zb3J0KGMpLGNbMF19fXN0YXRpYyBjaXJjbGUybGluZSh0LG4pe2xldCByPXQuaW50ZXJzZWN0KG4pO2lmKHIubGVuZ3RoPjApcmV0dXJuWzAsbmV3IGwuU2VnbWVudChyWzBdLHJbMF0pXTtsZXRbaSxzXT1FLnBvaW50MmxpbmUodC5jZW50ZXIsbiksW28sY109RS5wb2ludDJjaXJjbGUocy5lbmQsdCk7cmV0dXJuIGM9Yy5yZXZlcnNlKCksW28sY119c3RhdGljIGFyYzJsaW5lKHQsbil7bGV0IHI9bi5pbnRlcnNlY3QodCk7aWYoci5sZW5ndGg+MClyZXR1cm5bMCxuZXcgbC5TZWdtZW50KHJbMF0sclswXSldO2xldCBpPW5ldyBsLkNpcmNsZSh0LmNlbnRlcix0LnIpLFtzLG9dPUUucG9pbnQybGluZShpLmNlbnRlcixuKTtpZihsLlV0aWxzLkdFKHMsaS5yKSl7bGV0W2MsYV09RS5wb2ludDJjaXJjbGUoby5lbmQsaSk7aWYoYS5lbmQub24odCkpcmV0dXJuW2MsYV19ZWxzZXtsZXQgYz1bXTtyZXR1cm4gYy5wdXNoKEUucG9pbnQybGluZSh0LnN0YXJ0LG4pKSxjLnB1c2goRS5wb2ludDJsaW5lKHQuZW5kLG4pKSxFLnNvcnQoYyksY1swXX19c3RhdGljIGFyYzJjaXJjbGUodCxuKXtsZXQgcj10LmludGVyc2VjdChuKTtpZihyLmxlbmd0aD4wKXJldHVyblswLG5ldyBsLlNlZ21lbnQoclswXSxyWzBdKV07bGV0IGk9bmV3IGwuQ2lyY2xlKHQuY2VudGVyLHQuciksW3Msb109RS5jaXJjbGUyY2lyY2xlKGksbik7aWYoby5zdGFydC5vbih0KSlyZXR1cm5bcyxvXTt7bGV0IGM9W107cmV0dXJuIGMucHVzaChFLnBvaW50MmNpcmNsZSh0LnN0YXJ0LG4pKSxjLnB1c2goRS5wb2ludDJjaXJjbGUodC5lbmQsbikpLEUuc29ydChjKSxjWzBdfX1zdGF0aWMgYXJjMmFyYyh0LG4pe2xldCByPXQuaW50ZXJzZWN0KG4pO2lmKHIubGVuZ3RoPjApcmV0dXJuWzAsbmV3IGwuU2VnbWVudChyWzBdLHJbMF0pXTtsZXQgaT1uZXcgbC5DaXJjbGUodC5jZW50ZXIsdC5yKSxzPW5ldyBsLkNpcmNsZShuLmNlbnRlcixuLnIpLFtvLGNdPUUuY2lyY2xlMmNpcmNsZShpLHMpO2lmKGMuc3RhcnQub24odCkmJmMuZW5kLm9uKG4pKXJldHVybltvLGNdO3tsZXQgYT1bXSxoLGY7cmV0dXJuW2gsZl09RS5wb2ludDJhcmModC5zdGFydCxuKSxmLmVuZC5vbihuKSYmYS5wdXNoKFtoLGZdKSxbaCxmXT1FLnBvaW50MmFyYyh0LmVuZCxuKSxmLmVuZC5vbihuKSYmYS5wdXNoKFtoLGZdKSxbaCxmXT1FLnBvaW50MmFyYyhuLnN0YXJ0LHQpLGYuZW5kLm9uKHQpJiZhLnB1c2goW2gsZi5yZXZlcnNlKCldKSxbaCxmXT1FLnBvaW50MmFyYyhuLmVuZCx0KSxmLmVuZC5vbih0KSYmYS5wdXNoKFtoLGYucmV2ZXJzZSgpXSksW2gsZl09RS5wb2ludDJwb2ludCh0LnN0YXJ0LG4uc3RhcnQpLGEucHVzaChbaCxmXSksW2gsZl09RS5wb2ludDJwb2ludCh0LnN0YXJ0LG4uZW5kKSxhLnB1c2goW2gsZl0pLFtoLGZdPUUucG9pbnQycG9pbnQodC5lbmQsbi5zdGFydCksYS5wdXNoKFtoLGZdKSxbaCxmXT1FLnBvaW50MnBvaW50KHQuZW5kLG4uZW5kKSxhLnB1c2goW2gsZl0pLEUuc29ydChhKSxhWzBdfX1zdGF0aWMgcG9pbnQycG9seWdvbih0LG4pe2xldCByPVtOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFksbmV3IGwuU2VnbWVudF07Zm9yKGxldCBpIG9mIG4uZWRnZXMpe2xldFtzLG9dPUUucG9pbnQyZWRnZSh0LGkpO2wuVXRpbHMuTFQocyxyWzBdKSYmKHI9W3Msb10pfXJldHVybiByfXN0YXRpYyBzaGFwZTJwb2x5Z29uKHQsbil7bGV0IHI9W051bWJlci5QT1NJVElWRV9JTkZJTklUWSxuZXcgbC5TZWdtZW50XTtmb3IobGV0IGkgb2Ygbi5lZGdlcyl7bGV0W3Msb109dC5kaXN0YW5jZVRvKGkuc2hhcGUpO2wuVXRpbHMuTFQocyxyWzBdKSYmKHI9W3Msb10pfXJldHVybiByfXN0YXRpYyBwb2x5Z29uMnBvbHlnb24odCxuKXtsZXQgcj1bTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZLG5ldyBsLlNlZ21lbnRdO2ZvcihsZXQgaSBvZiB0LmVkZ2VzKWZvcihsZXQgcyBvZiBuLmVkZ2VzKXtsZXRbbyxjXT1pLnNoYXBlLmRpc3RhbmNlVG8ocy5zaGFwZSk7bC5VdGlscy5MVChvLHJbMF0pJiYocj1bbyxjXSl9cmV0dXJuIHJ9c3RhdGljIGJveDJib3hfbWlubWF4KHQsbil7bGV0IHI9TWF0aC5tYXgoTWF0aC5tYXgodC54bWluLW4ueG1heCwwKSxNYXRoLm1heChuLnhtaW4tdC54bWF4LDApKSxpPU1hdGgubWF4KE1hdGgubWF4KHQueW1pbi1uLnltYXgsMCksTWF0aC5tYXgobi55bWluLXQueW1heCwwKSkscz1yKnIraSppLG89dC5tZXJnZShuKSxjPW8ueG1heC1vLnhtaW4sYT1vLnltYXgtby55bWluLGg9YypjK2EqYTtyZXR1cm5bcyxoXX1zdGF0aWMgbWlubWF4X3RyZWVfcHJvY2Vzc19sZXZlbCh0LG4scixpKXtsZXQgcyxvO2ZvcihsZXQgZiBvZiBuKXtbcyxvXT1FLmJveDJib3hfbWlubWF4KHQuYm94LGYuaXRlbS5rZXkpO2ZvcihsZXQgdSBvZiBmLml0ZW0udmFsdWVzKXUgaW5zdGFuY2VvZiBsLkVkZ2U/aS5pbnNlcnQoW3Msb10sdS5zaGFwZSk6aS5pbnNlcnQoW3Msb10sdSk7bC5VdGlscy5MVChvLHIpJiYocj1vKX1pZihuLmxlbmd0aD09PTApcmV0dXJuIHI7bGV0IGM9bi5tYXAoZj0+Zi5sZWZ0LmlzTmlsKCk/dm9pZCAwOmYubGVmdCkuZmlsdGVyKGY9PmYhPT12b2lkIDApLGE9bi5tYXAoZj0+Zi5yaWdodC5pc05pbCgpP3ZvaWQgMDpmLnJpZ2h0KS5maWx0ZXIoZj0+ZiE9PXZvaWQgMCksaD1bLi4uYywuLi5hXS5maWx0ZXIoZj0+e2xldFt1LGRdPUUuYm94MmJveF9taW5tYXgodC5ib3gsZi5tYXgpO3JldHVybiBsLlV0aWxzLkxFKHUscil9KTtyZXR1cm4gcj1FLm1pbm1heF90cmVlX3Byb2Nlc3NfbGV2ZWwodCxoLHIsaSkscn1zdGF0aWMgbWlubWF4X3RyZWUodCxuLHIpe2xldCBpPW5ldyBaZSxzPVtuLmluZGV4LnJvb3RdLG89cjxOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFk/cipyOk51bWJlci5QT1NJVElWRV9JTkZJTklUWTtyZXR1cm4gbz1FLm1pbm1heF90cmVlX3Byb2Nlc3NfbGV2ZWwodCxzLG8saSksaX1zdGF0aWMgbWlubWF4X3RyZWVfY2FsY19kaXN0YW5jZSh0LG4scil7bGV0IGkscztpZihuIT1udWxsJiYhbi5pc05pbCgpKXtpZihbaSxzXT1FLm1pbm1heF90cmVlX2NhbGNfZGlzdGFuY2UodCxuLmxlZnQscikscylyZXR1cm5baSxzXTtpZihsLlV0aWxzLkxUKGlbMF0sTWF0aC5zcXJ0KG4uaXRlbS5rZXkubG93KSkpcmV0dXJuW2ksITBdO2xldFtvLGNdPUUuZGlzdGFuY2VUb0FycmF5KHQsbi5pdGVtLnZhbHVlcyk7cmV0dXJuIGwuVXRpbHMuTFQobyxpWzBdKSYmKGk9W28sY10pLFtpLHNdPUUubWlubWF4X3RyZWVfY2FsY19kaXN0YW5jZSh0LG4ucmlnaHQsaSksW2ksc119cmV0dXJuW3IsITFdfXN0YXRpYyBzaGFwZTJwbGFuYXJTZXQodCxuLHI9TnVtYmVyLlBPU0lUSVZFX0lORklOSVRZKXtsZXQgaT1bcixuZXcgbC5TZWdtZW50XSxzPSExO2lmKG4gaW5zdGFuY2VvZiBsLlBsYW5hclNldCl7bGV0IG89RS5taW5tYXhfdHJlZSh0LG4scik7W2ksc109RS5taW5tYXhfdHJlZV9jYWxjX2Rpc3RhbmNlKHQsby5yb290LGkpfXJldHVybiBpfXN0YXRpYyBzb3J0KHQpe3Quc29ydCgobixyKT0+bC5VdGlscy5MVChuWzBdLHJbMF0pPy0xOmwuVXRpbHMuR1QoblswXSxyWzBdKT8xOjApfXN0YXRpYyBkaXN0YW5jZSh0LG4pe3JldHVybiB0LmRpc3RhbmNlVG8obil9c3RhdGljIGRpc3RhbmNlVG9BcnJheSh0LG4pe2xldCByPVtOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFksbmV3IGwuU2VnbWVudF07Zm9yKGxldCBpIG9mIG4pe2xldFtzLG9dPXQuZGlzdGFuY2VUbyhpKTtsLlV0aWxzLkxUKHMsclswXSkmJihyPVtzLG9dKX1yZXR1cm4gcn1zdGF0aWMgc2hhcGUybXVsdGlsaW5lKHQsbil7bGV0IHI9W051bWJlci5QT1NJVElWRV9JTkZJTklUWSxuZXcgbC5TZWdtZW50XTtmb3IobGV0IGkgb2Ygbil7bGV0W3Msb109RS5kaXN0YW5jZSh0LGkuc2hhcGUpO2wuVXRpbHMuTFQocyxyWzBdKSYmKHI9W3Msb10pfXJldHVybiByfXN0YXRpYyBtdWx0aWxpbmUybXVsdGlsaW5lKHQsbil7bGV0IHI9W051bWJlci5QT1NJVElWRV9JTkZJTklUWSxuZXcgbC5TZWdtZW50XTtmb3IobGV0IGkgb2YgdClmb3IobGV0IHMgb2Ygbil7bGV0W28sY109RS5kaXN0YW5jZShpLnNoYXBlLHMuc2hhcGUpO2wuVXRpbHMuTFQobyxyWzBdKSYmKHI9W28sY10pfXJldHVybiByfX1sLkRpc3RhbmNlPUU7Y29uc3R7TXVsdGlsaW5lOnJnLFBvaW50OmJhLFNlZ21lbnQ6aWcsUG9seWdvbjpTYX09bDtmdW5jdGlvbiBTaShlKXtyZXR1cm4gbmV3IGJhKGUuc3BsaXQoIiAiKS5tYXAoTnVtYmVyKSl9ZnVuY3Rpb24gSWEoZSl7cmV0dXJuIGUuc3BsaXQoIiwgIikubWFwKFNpKX1mdW5jdGlvbiBJaShlKXtjb25zdCB0PUlhKGUpO2xldCBuPVtdO2ZvcihsZXQgcj0wO3I8dC5sZW5ndGgtMTtyKyspbi5wdXNoKG5ldyBpZyh0W3JdLHRbcisxXSkpO3JldHVybiBuZXcgcmcobil9ZnVuY3Rpb24gc2coZSl7cmV0dXJuIGUucmVwbGFjZSgvXChcKC8sIiIpLnJlcGxhY2UoL1wpXCkkLywiIikuc3BsaXQoIiksICgiKS5tYXAoSWkpfWZ1bmN0aW9uIFBhKGUpe2NvbnN0IHQ9ZS5yZXBsYWNlKC9cKFwoLywiIikucmVwbGFjZSgvXClcKSQvLCIiKS5zcGxpdCgiKSwgKCIpLG49bmV3IFNhO2xldCByO3JldHVybiB0LmZvckVhY2goKGkscyk9PntsZXQgbz1pLnNwbGl0KCIsICIpLm1hcChhPT5uZXcgYmEoYS5zcGxpdCgiICIpLm1hcChOdW1iZXIpKSk7Y29uc3QgYz1uLmFkZEZhY2Uobyk7cz09PTA/cj1jLm9yaWVudGF0aW9uKCk6Yy5vcmllbnRhdGlvbigpPT09ciYmYy5yZXZlcnNlKCl9KSxufWZ1bmN0aW9uIG9nKGUpe2NvbnN0IG49ZS5zcGxpdCgvXClcKSwgXChcKC8pLm1hcChzPT4iKCgiK3MrIikpIikubWFwKFBhKSxyPW5ldyBTYTtyZXR1cm4gbi5yZWR1Y2UoKHMsbyk9PlsuLi5zLC4uLm89PW51bGw/dm9pZCAwOm8uZmFjZXNdLFtdKS5mb3JFYWNoKHM9PnIuYWRkRmFjZShbLi4ucz09bnVsbD92b2lkIDA6cy5zaGFwZXNdKSkscn1mdW5jdGlvbiBjZyhlKXtpZihlLnN0YXJ0c1dpdGgoIlBPTFlHT04iKSl7Y29uc3QgdD1lLnJlcGxhY2UoL15QT0xZR09OIC8sIiIpO3JldHVybiBQYSh0KX1lbHNle2NvbnN0IHQ9ZS5yZXBsYWNlKC9eTVVMVElQT0xZR09OIFwoXChcKCguKilcKVwpXCkkLywiJDEiKTtyZXR1cm4gb2codCl9fWZ1bmN0aW9uIGFnKGUpe3JldHVybiBlLnNwbGl0KGAKYCkubWFwKG49Pm4ubWF0Y2goL1woKFteKV0rKVwpLylbMV0pLm1hcChTaSl9ZnVuY3Rpb24gbGcoZSl7cmV0dXJuIGUuc3BsaXQoYApgKS5tYXAobj0+bi5tYXRjaCgvXCgoW14pXSspXCkvKVsxXSkubWFwKElpKS5yZWR1Y2UoKG4scik9PlsuLi5uLC4uLnJdLFtdKX1mdW5jdGlvbiBMYShlKXtpZihlLnN0YXJ0c1dpdGgoIlBPSU5UIikpe2NvbnN0IHQ9ZS5yZXBsYWNlKC9eUE9JTlQgXCgvLCIiKS5yZXBsYWNlKC9cKSQvLCIiKTtyZXR1cm4gU2kodCl9ZWxzZSBpZihlLnN0YXJ0c1dpdGgoIk1VTFRJUE9JTlQiKSl7Y29uc3QgdD1lLnJlcGxhY2UoL15NVUxUSVBPSU5UIFwoLywiIikucmVwbGFjZSgvXCkkLywiIik7cmV0dXJuIElhKHQpfWVsc2UgaWYoZS5zdGFydHNXaXRoKCJMSU5FU1RSSU5HIikpe2NvbnN0IHQ9ZS5yZXBsYWNlKC9eTElORVNUUklORyBcKC8sIiIpLnJlcGxhY2UoL1wpJC8sIiIpO3JldHVybiBJaSh0KX1lbHNlIGlmKGUuc3RhcnRzV2l0aCgiTVVMVElMSU5FU1RSSU5HIikpe2NvbnN0IHQ9ZS5yZXBsYWNlKC9eTVVMVElMSU5FU1RSSU5HIC8sIiIpO3JldHVybiBzZyh0KX1lbHNle2lmKGUuc3RhcnRzV2l0aCgiUE9MWUdPTiIpfHxlLnN0YXJ0c1dpdGgoIk1VTFRJUE9MWUdPTiIpKXJldHVybiBjZyhlKTtpZihlLnN0YXJ0c1dpdGgoIkdFT01FVFJZQ09MTEVDVElPTiIpKXtjb25zdCB0PS8oPzx0eXBlPlBPSU5UfExJTkVTVFJJTkd8UE9MWUdPTnxNVUxUSVBPSU5UfE1VTFRJTElORVNUUklOR3xNVUxUSVBPTFlHT04pIFwoKD86W15cKFwpXXxcKFteXCldKlwpKSpcKS9nLG49ZS5tYXRjaCh0KTtyZXR1cm4gblswXS5zdGFydHNXaXRoKCJHRU9NRVRSWUNPTExFQ1RJT04iKSYmKG5bMF09blswXS5yZXBsYWNlKCJHRU9NRVRSWUNPTExFQ1RJT04gKCIsIiIpKSxuLm1hcChMYSkubWFwKGk9PmkgaW5zdGFuY2VvZiBBcnJheT9pOltpXSkucmVkdWNlKChpLHMpPT5bLi4uaSwuLi5zXSxbXSl9ZWxzZXtpZihSYShlKSlyZXR1cm4gYWcoZSk7aWYoJGEoZSkpcmV0dXJuIGxnKGUpfX1yZXR1cm5bXX1mdW5jdGlvbiBSYShlKXt2YXIgdDtyZXR1cm4odD1lLnNwbGl0KGAKYCkpPT1udWxsP3ZvaWQgMDp0LmV2ZXJ5KG49Pm4uaW5jbHVkZXMoIlBPSU5UIikpfWZ1bmN0aW9uICRhKGUpe3ZhciB0O3JldHVybih0PWUuc3BsaXQoYApgKSk9PW51bGw/dm9pZCAwOnQuZXZlcnkobj0+bi5pbmNsdWRlcygiTElORVNUUklORyIpKX1mdW5jdGlvbiBoZyhlKXtyZXR1cm4gZS5zdGFydHNXaXRoKCJQT0lOVCIpfHxSYShlKXx8ZS5zdGFydHNXaXRoKCJMSU5FU1RSSU5HIil8fCRhKGUpfHxlLnN0YXJ0c1dpdGgoIk1VTFRJTElORVNUUklORyIpfHxlLnN0YXJ0c1dpdGgoIlBPTFlHT04iKXx8ZS5zdGFydHNXaXRoKCJNVUxUSVBPSU5UIil8fGUuc3RhcnRzV2l0aCgiTVVMVElQT0xZR09OIil8fGUuc3RhcnRzV2l0aCgiR0VPTUVUUllDT0xMRUNUSU9OIil9bC5pc1drdFN0cmluZz1oZyxsLnBhcnNlV0tUPUxhLGwuQm9vbGVhbk9wZXJhdGlvbnM9WWUsbC5SZWxhdGlvbnM9emQ7Y29uc3QgUWU9WyJwb3NpdGlvbiJdO2NsYXNzIENhe2NvbnN0cnVjdG9yKHQpe1UodGhpcywiZ2VvbWV0cnkiKTtVKHRoaXMsInBvc2l0aW9uTmFtZXMiLFFlKTtVKHRoaXMsInJlZ2lvbiIpO1UodGhpcywicmVsYXRpb24iKTtVKHRoaXMsInJlbGF0aW9uRXF1YWwiKTtVKHRoaXMsIl9nZW9tZXRyeVBvbHlnb24iLG51bGwpO1UodGhpcywicG9zaXRpb25SZWxhdGlvbnMiKTtVKHRoaXMsImZhY2VSZWxhdGlvbnMiKTtVKHRoaXMsInJlbGF0aW9uSW5kZXhzV2l0aG91dFRocm91Z24iKTtVKHRoaXMsIl90aHJvdWdoSW5kZXhzIixbXSk7VSh0aGlzLCJfdGhyb3VnaEZhY2VzIixudWxsKTtVKHRoaXMsIl90aHJvdWdoRmFjZUFyZWFzIixudWxsKTtVKHRoaXMsIl9nZXRQb3NpdGlvbiIsbnVsbCk7VSh0aGlzLCJfcmVsYXRpb25BcmVhIixudWxsKTtVKHRoaXMsIl9hcmVhIixudWxsKTtVKHRoaXMsIl9yZWxhdGlvblZvbHVtZSIsbnVsbCk7VSh0aGlzLCJfdm9sdW1lIixudWxsKTt0JiZ0aGlzLnNldE9wdGlvbnModCl9Z2V0IGluY2x1ZGluZ1Rocm91Z2goKXtyZXR1cm4gdGhpcy5yZWxhdGlvbiZ5LlRocm91Z2hJbnRlcnNlY3R9c2V0T3B0aW9ucyh0KXtpZihPYmplY3QuYXNzaWduKHRoaXMsdCksdC5wb3NpdGlvbk5hbWVzJiYodGhpcy5fZ2V0UG9zaXRpb249bnVsbCksdC5nZW9tZXRyeXx8dC5wb3NpdGlvbk5hbWVzfHx0LnJlZ2lvbilyZXR1cm4odC5nZW9tZXRyeXx8dC5wb3NpdGlvbk5hbWVzKSYmKHRoaXMuX2dlb21ldHJ5UG9seWdvbj1udWxsKSx0aGlzLnVwZGF0ZSgpO2lmKHQucmVsYXRpb258fHQuc3RyaWN0KXJldHVybiB0aGlzLl9yZWxhdGlvbkFyZWE9bnVsbCx0aGlzLl9yZWxhdGlvblZvbHVtZT1udWxsLHRoaXMudXBkYXRlUmVsYXRpb25JbmRleHMoKX1nZXQgZ2VvbWV0cnlQb2x5Z29uKCl7cmV0dXJuIHRoaXMuX2dlb21ldHJ5UG9seWdvbnx8KHRoaXMuX2dlb21ldHJ5UG9seWdvbj10aGlzLmdlbmVyYXRlR2VvbWV0cnlQb2x5Z29uKCkpLHRoaXMuX2dlb21ldHJ5UG9seWdvbn1nZW5lcmF0ZUdlb21ldHJ5UG9seWdvbigpe2NvbnN0IHQ9bmV3IEdlO3JldHVybiB0aGlzLmdlb21ldHJ5Lm1hcEZhY2VGb3JBZ2dyZWdhdGUodGhpcy5wb3NpdGlvbk5hbWVzLG49Pntjb25zdCByPW4ubWFwKGk9Pm5ldyBqbihpWzBdLGlbMV0pKTt0LmFkZEZhY2Uocil9KSx0fWdldCB0aHJvdWdoSW5kZXhzKCl7cmV0dXJuIHRoaXMuX3Rocm91Z2hJbmRleHN9c2V0IHRocm91Z2hJbmRleHModCl7dGhpcy5fdGhyb3VnaEluZGV4cz10LHRoaXMuX3Rocm91Z2hGYWNlcz1udWxsLHRoaXMuX3Rocm91Z2hGYWNlQXJlYXM9bnVsbH1nZXQgdGhyb3VnaEZhY2VzKCl7cmV0dXJuIHRoaXMuX3Rocm91Z2hGYWNlc3x8KHRoaXMuX3Rocm91Z2hGYWNlcz10aGlzLmdlbmVyYXRlVGhyb3VnaEZhY2VzKCkpLHRoaXMuX3Rocm91Z2hGYWNlc31nZXQgdGhyb3VnaEZhY2VBcmVhcygpe3JldHVybiB0aGlzLl90aHJvdWdoRmFjZUFyZWFzfHwodGhpcy5fdGhyb3VnaEZhY2VBcmVhcz10aGlzLmdlbmVyYXRlVGhyb3VnaEZhY2VBcmVhcygpKSx0aGlzLl90aHJvdWdoRmFjZUFyZWFzfWdlbmVyYXRlVGhyb3VnaEZhY2VBcmVhcygpe3JldHVybiB0aGlzLnRocm91Z2hGYWNlcy5tYXAodD0+dC5hcmVhKCkpfXVwZGF0ZSgpe3RoaXMudXBkYXRlUG9zaXRpb25SZWxhdGlvbnMoKSx0aGlzLnVwZGF0ZUZhY2VSZWxhdGlvbnMoKSx0aGlzLnVwZGF0ZVJlbGF0aW9uSW5kZXhzKCksdGhpcy5pbmNsdWRpbmdUaHJvdWdoJiZ0aGlzLnVwZGF0ZVRocm91Z2hJbmRleHMoKSx0aGlzLnJlc2V0TWVhc3VyZSgpfXVwZGF0ZVBvc2l0aW9uUmVsYXRpb25zKCl7dGhpcy5wb3NpdGlvblJlbGF0aW9ucz10aGlzLmdlbmVyYXRlUG9zaXRpb25SZWxhdGlvbnMoKX11cGRhdGVGYWNlUmVsYXRpb25zKCl7dGhpcy5mYWNlUmVsYXRpb25zPXRoaXMuZ2VuZXJhdGVGYWNlUmVsYXRpb25zKCl9dXBkYXRlUmVsYXRpb25JbmRleHMoKXtjb25zdCB0PX55LlRocm91Z2hJbnRlcnNlY3QmdGhpcy5yZWxhdGlvbjt0aGlzLnJlbGF0aW9uSW5kZXhzV2l0aG91dFRocm91Z249dGhpcy5maWx0ZXJGYWNlcyh0LHRoaXMucmVsYXRpb25FcXVhbCl9dXBkYXRlVGhyb3VnaEluZGV4cygpe3RoaXMudGhyb3VnaEluZGV4cz10aGlzLmZpbHRlckZhY2VzKHkuVGhyb3VnaEludGVyc2VjdCxFZS5lcXVhbCksdGhpcy5fdGhyb3VnaEZhY2VzPW51bGwsdGhpcy5fdGhyb3VnaEZhY2VBcmVhcz1udWxsfXJlc2V0TWVhc3VyZSgpe3RoaXMuX3JlbGF0aW9uQXJlYT1udWxsLHRoaXMuX3JlbGF0aW9uVm9sdW1lPW51bGwsdGhpcy5fYXJlYT1udWxsLHRoaXMuX3ZvbHVtZT1udWxsfXVwZGF0ZU1lYXN1cmUoKXt0aGlzLnJlc2V0TWVhc3VyZSgpLHRoaXMucmVsYXRpb25BcmVhLHRoaXMucmVsYXRpb25Wb2x1bWUsdGhpcy5hcmVhLHRoaXMudm9sdW1lfWdldCBnZXRQb3NpdGlvbigpe3JldHVybiB0aGlzLl9nZXRQb3NpdGlvbnx8KHRoaXMuX2dldFBvc2l0aW9uPXRoaXMuZ2VvbWV0cnkuY3JlYXRlQWdncmVnYXRlVmVjdG9yR2V0dGVyKHRoaXMucG9zaXRpb25OYW1lcykpfWdldCByZWxhdGlvbkFyZWEoKXtyZXR1cm4gdGhpcy5fcmVsYXRpb25BcmVhPT1udWxsJiYodGhpcy5fcmVsYXRpb25BcmVhPXRoaXMuY29tcHV0ZVJlbGF0aW9uQXJlYSgpKSx0aGlzLl9yZWxhdGlvbkFyZWF9Y29tcHV0ZVJlbGF0aW9uQXJlYSgpe2NvbnN0e2dlb21ldHJ5OnR9PXRoaXMsbj10aGlzLnJlbGF0aW9uSW5kZXhzV2l0aG91dFRocm91Z24uZmxhdE1hcChpPT5bLi4udC5pbmRpY2VzLmdldFZlY3RvcihpKV0pO2xldCByPW9pKG4sdGhpcy5nZXRQb3NpdGlvbik7aWYodGhpcy5pbmNsdWRpbmdUaHJvdWdoKWZvcihjb25zdCBpIG9mIHRoaXMudGhyb3VnaEZhY2VBcmVhcylyKz1pO3JldHVybiByfWdldCBhcmVhKCl7cmV0dXJuIHRoaXMuX2FyZWE9PW51bGwmJih0aGlzLl9hcmVhPXRoaXMuY29tcHV0ZUFyZWEoKSksdGhpcy5fYXJlYX1jb21wdXRlQXJlYSgpe3JldHVybiBvaSh0aGlzLmdlb21ldHJ5LmluZGljZXMuYXJyYXksdGhpcy5nZXRQb3NpdGlvbil9Z2V0IHJlbGF0aW9uVm9sdW1lKCl7cmV0dXJuIHRoaXMuX3JlbGF0aW9uVm9sdW1lPT1udWxsJiYodGhpcy5fcmVsYXRpb25Wb2x1bWU9dGhpcy5jb21wdXRlUmVsYXRpb25UZXJyYWluVm9sdW1lKCkpLHRoaXMuX3JlbGF0aW9uVm9sdW1lfWNvbXB1dGVSZWxhdGlvblRlcnJhaW5Wb2x1bWUodD1bMCwxLzBdKXtjb25zdHtnZW9tZXRyeTpufT10aGlzLHI9dGhpcy5yZWxhdGlvbkluZGV4c1dpdGhvdXRUaHJvdWduLmZsYXRNYXAocz0+Wy4uLm4uaW5kaWNlcy5nZXRWZWN0b3IocyldKTtsZXQgaT1jaShyLHRoaXMuZ2V0UG9zaXRpb24sdCk7aWYodGhpcy5pbmNsdWRpbmdUaHJvdWdoKXtjb25zdFtzLG9dPXQsYz1vLXM7bGV0IGE9MDtjb25zdCBoPTEvMyx7Z2VvbWV0cnk6Zixwb3NpdGlvbk5hbWVzOnV9PXRoaXM7dGhpcy50aHJvdWdoRmFjZUFyZWFzLmZvckVhY2goKGQsZyk9Pntjb25zdCBtPXRoaXMudGhyb3VnaEluZGV4c1tnXSxbXyxwLHhdPWYuZ2V0RmFjZUFnZ3JlZ2F0ZVZlY3Rvcih1LG0pLFQ9KF9bMl0rcFsyXSt4WzJdKSpoLXM7VDw9MHx8KGErPWQqTWF0aC5taW4oVCxjKSl9KSxhLz0yLGkrPWF9cmV0dXJuIGl9Z2V0IHZvbHVtZSgpe3JldHVybiB0aGlzLl92b2x1bWU9PW51bGwmJih0aGlzLl92b2x1bWU9dGhpcy5jb21wdXRlVGVycmFpblZvbHVtZShbLTEvMCwxLzBdKSksdGhpcy5fdm9sdW1lfWNvbXB1dGVUZXJyYWluVm9sdW1lKHQpe3JldHVybiBjaSh0aGlzLmdlb21ldHJ5LmluZGljZXMuYXJyYXksdGhpcy5nZXRQb3NpdGlvbix0KX19Y2xhc3MgS24gZXh0ZW5kcyBDYXtjb25zdHJ1Y3Rvcigpe3N1cGVyKC4uLmFyZ3VtZW50cyk7VSh0aGlzLCJfaXNDb252ZXgiLG51bGwpO1UodGhpcywiX3BvbHlnb25PdXRzaWRlR2VvbWV0cnkiLG51bGwpfWdldCBpc0NvbnZleCgpe3JldHVybiB0aGlzLl9pc0NvbnZleD09bnVsbCYmKHRoaXMuX2lzQ29udmV4PUVjKHRoaXMucmVnaW9uKSksdGhpcy5faXNDb252ZXh9c2V0IGlzQ29udmV4KG4pe3RoaXMuX2lzQ29udmV4PW59c2V0T3B0aW9ucyhuKXtpZihuLnJlZ2lvbil7Y29uc3Qgcj1uLnJlZ2lvbi5tYXAoaT0+bmV3IGpuKGkpKTt0aGlzLnBvbHlnb249bmV3IEdlKHIpLHRoaXMuaXNaZXJvUG9seWdvbj10aGlzLnBvbHlnb24uYXJlYSgpPT09MH1zdXBlci5zZXRPcHRpb25zKG4pfXJlc2V0TWVhc3VyZSgpe3N1cGVyLnJlc2V0TWVhc3VyZSgpLHRoaXMuX3BvbHlnb25PdXRzaWRlR2VvbWV0cnk9bnVsbH1nZW5lcmF0ZVBvc2l0aW9uUmVsYXRpb25zKCl7cmV0dXJuIHRoaXMuaXNDb252ZXg/TGModGhpcy5nZW9tZXRyeSx0aGlzLnJlZ2lvbix0aGlzLnBvc2l0aW9uTmFtZXMpOlBjKHRoaXMuZ2VvbWV0cnksdGhpcy5yZWdpb24sdGhpcy5wb3NpdGlvbk5hbWVzKX1nZW5lcmF0ZUZhY2VSZWxhdGlvbnMoKXtyZXR1cm4gUmModGhpcy5nZW9tZXRyeSx0aGlzLnJlZ2lvbix0aGlzLnBvc2l0aW9uTmFtZXMsdGhpcy5wb3NpdGlvblJlbGF0aW9ucyx0aGlzLmlzQ29udmV4KX1nZW5lcmF0ZVRocm91Z2hGYWNlcygpe2NvbnN0e2dlb21ldHJ5Om4scG9seWdvbjpyfT10aGlzLGk9dGhpcy5yZWxhdGlvbiZ5LkNvbnRhaW47bGV0IHM9aT9ZZS5pbnRlcnNlY3Q6WWUuc3VidHJhY3Q7cmV0dXJuIHRoaXMuaXNaZXJvUG9seWdvbiYmKHM9aT8obyxjKT0+cjoobyxjKT0+byksdGhpcy50aHJvdWdoSW5kZXhzLm1hcChvPT57Y29uc3QgYT1uLmdldEZhY2VBZ2dyZWdhdGVWZWN0b3IodGhpcy5wb3NpdGlvbk5hbWVzLG8pLm1hcChmPT5uZXcgam4oZlswXSxmWzFdKSksaD1uZXcgR2UoYSk7cmV0dXJuIHMoaCxyKX0pfWZpbHRlckZhY2VzKG4scil7cmV0dXJuIFZjKHRoaXMuZmFjZVJlbGF0aW9ucyxuLHIpfWdldCBwb2x5Z29uT3V0c2lkZUdlb21ldHJ5KCl7cmV0dXJuIHRoaXMuX3BvbHlnb25PdXRzaWRlR2VvbWV0cnk9PW51bGwmJih0aGlzLl9wb2x5Z29uT3V0c2lkZUdlb21ldHJ5PXRoaXMuaXNaZXJvUG9seWdvbj90aGlzLnBvbHlnb246WWUuc3VidHJhY3QodGhpcy5wb2x5Z29uLHRoaXMuZ2VvbWV0cnlQb2x5Z29uKSksdGhpcy5fcG9seWdvbk91dHNpZGVHZW9tZXRyeX19Y29uc3QgZmc9NjM3ODEzNyx1Zz02Mzc4MTM3LGRnPTYzNTY3NTIzMTQyNDUxNzllLTk7ZnVuY3Rpb24gSG4oZSl7cmV0dXJuIGV9bmV3IEw7ZnVuY3Rpb24gZ2coZSx0PVtdLG49SG4pe3JldHVybiJsb25naXR1ZGUiaW4gZT8odFswXT1uKGUubG9uZ2l0dWRlKSx0WzFdPW4oZS5sYXRpdHVkZSksdFsyXT1lLmhlaWdodCk6IngiaW4gZT8odFswXT1uKGUueCksdFsxXT1uKGUueSksdFsyXT1lLnopOih0WzBdPW4oZVswXSksdFsxXT1uKGVbMV0pLHRbMl09ZVsyXSksdH1mdW5jdGlvbiBtZyhlLHQ9W10pe3JldHVybiBnZyhlLHQsRy5fY2FydG9ncmFwaGljUmFkaWFucz9IbjpiZSl9ZnVuY3Rpb24gcGcoZSx0LG49SG4pe3JldHVybiJsb25naXR1ZGUiaW4gdD8odC5sb25naXR1ZGU9bihlWzBdKSx0LmxhdGl0dWRlPW4oZVsxXSksdC5oZWlnaHQ9ZVsyXSk6IngiaW4gdD8odC54PW4oZVswXSksdC55PW4oZVsxXSksdC56PWVbMl0pOih0WzBdPW4oZVswXSksdFsxXT1uKGVbMV0pLHRbMl09ZVsyXSksdH1mdW5jdGlvbiBfZyhlLHQpe3JldHVybiBwZyhlLHQsRy5fY2FydG9ncmFwaGljUmFkaWFucz9IbjpKYSl9Y29uc3QgVmE9MWUtMTQseWc9bmV3IEwsTmE9e3VwOntzb3V0aDoiZWFzdCIsbm9ydGg6Indlc3QiLHdlc3Q6InNvdXRoIixlYXN0OiJub3J0aCJ9LGRvd246e3NvdXRoOiJ3ZXN0Iixub3J0aDoiZWFzdCIsd2VzdDoibm9ydGgiLGVhc3Q6InNvdXRoIn0sc291dGg6e3VwOiJ3ZXN0Iixkb3duOiJlYXN0Iix3ZXN0OiJkb3duIixlYXN0OiJ1cCJ9LG5vcnRoOnt1cDoiZWFzdCIsZG93bjoid2VzdCIsd2VzdDoidXAiLGVhc3Q6ImRvd24ifSx3ZXN0Ont1cDoibm9ydGgiLGRvd246InNvdXRoIixub3J0aDoiZG93biIsc291dGg6InVwIn0sZWFzdDp7dXA6InNvdXRoIixkb3duOiJub3J0aCIsbm9ydGg6InVwIixzb3V0aDoiZG93biJ9fSxQaT17bm9ydGg6Wy0xLDAsMF0sZWFzdDpbMCwxLDBdLHVwOlswLDAsMV0sc291dGg6WzEsMCwwXSx3ZXN0OlswLC0xLDBdLGRvd246WzAsMCwtMV19LEtlPXtlYXN0Om5ldyBMLG5vcnRoOm5ldyBMLHVwOm5ldyBMLHdlc3Q6bmV3IEwsc291dGg6bmV3IEwsZG93bjpuZXcgTH0seGc9bmV3IEwsTWc9bmV3IEwsd2c9bmV3IEw7ZnVuY3Rpb24gemEoZSx0LG4scixpLHMpe2NvbnN0IG89TmFbdF0mJk5hW3RdW25dO1J0KG8mJighcnx8cj09PW8pKTtsZXQgYyxhLGg7Y29uc3QgZj15Zy5jb3B5KGkpO2lmKEYoZi54LDAsVmEpJiZGKGYueSwwLFZhKSl7Y29uc3QgZD1NYXRoLnNpZ24oZi56KTtjPXhnLmZyb21BcnJheShQaVt0XSksdCE9PSJlYXN0IiYmdCE9PSJ3ZXN0IiYmYy5zY2FsZShkKSxhPU1nLmZyb21BcnJheShQaVtuXSksbiE9PSJlYXN0IiYmbiE9PSJ3ZXN0IiYmYS5zY2FsZShkKSxoPXdnLmZyb21BcnJheShQaVtyXSksciE9PSJlYXN0IiYmciE9PSJ3ZXN0IiYmaC5zY2FsZShkKX1lbHNle2NvbnN0e3VwOmQsZWFzdDpnLG5vcnRoOm19PUtlO2cuc2V0KC1mLnksZi54LDApLm5vcm1hbGl6ZSgpLGUuZ2VvZGV0aWNTdXJmYWNlTm9ybWFsKGYsZCksbS5jb3B5KGQpLmNyb3NzKGcpO2NvbnN0e2Rvd246Xyx3ZXN0OnAsc291dGg6eH09S2U7Xy5jb3B5KGQpLnNjYWxlKC0xKSxwLmNvcHkoZykuc2NhbGUoLTEpLHguY29weShtKS5zY2FsZSgtMSksYz1LZVt0XSxhPUtlW25dLGg9S2Vbcl19cmV0dXJuIHNbMF09Yy54LHNbMV09Yy55LHNbMl09Yy56LHNbM109MCxzWzRdPWEueCxzWzVdPWEueSxzWzZdPWEueixzWzddPTAsc1s4XT1oLngsc1s5XT1oLnksc1sxMF09aC56LHNbMTFdPTAsc1sxMl09Zi54LHNbMTNdPWYueSxzWzE0XT1mLnosc1sxNV09MSxzfWNvbnN0IHZlPW5ldyBMLFRnPW5ldyBMLEFnPW5ldyBMO2Z1bmN0aW9uIE9nKGUsdCxuPVtdKXtjb25zdHtvbmVPdmVyUmFkaWk6cixvbmVPdmVyUmFkaWlTcXVhcmVkOmksY2VudGVyVG9sZXJhbmNlU3F1YXJlZDpzfT10O3ZlLmZyb20oZSk7Y29uc3Qgbz12ZS54LGM9dmUueSxhPXZlLnosaD1yLngsZj1yLnksdT1yLnosZD1vKm8qaCpoLGc9YypjKmYqZixtPWEqYSp1KnUsXz1kK2crbSxwPU1hdGguc3FydCgxL18pO2lmKCFOdW1iZXIuaXNGaW5pdGUocCkpcmV0dXJuO2NvbnN0IHg9VGc7aWYoeC5jb3B5KGUpLnNjYWxlKHApLF88cylyZXR1cm4geC50byhuKTtjb25zdCBUPWkueCxNPWkueSxBPWkueix2PUFnO3Yuc2V0KHgueCpUKjIseC55Kk0qMix4LnoqQSoyKTtsZXQgdz0oMS1wKSp2ZS5sZW4oKS8oLjUqdi5sZW4oKSksUD0wLGIsUyxPLFY7ZG97dy09UCxiPTEvKDErdypUKSxTPTEvKDErdypNKSxPPTEvKDErdypBKTtjb25zdCB6PWIqYixOPVMqUyxSPU8qTyxldD16KmIsQj1OKlMsWD1SKk87Vj1kKnorZypOK20qUi0xO2NvbnN0IGl0PS0yKihkKmV0KlQrZypCKk0rbSpYKkEpO1A9Vi9pdH13aGlsZShNYXRoLmFicyhWKT5VZik7cmV0dXJuIHZlLnNjYWxlKFtiLFMsT10pLnRvKG4pfWNvbnN0IEpuPW5ldyBMLHFhPW5ldyBMLHZnPW5ldyBMLG10PW5ldyBMLEVnPW5ldyBMLHRyPW5ldyBMO2NsYXNzIGVye2NvbnN0cnVjdG9yKHQ9MCxuPTAscj0wKXt0aGlzLmNlbnRlclRvbGVyYW5jZVNxdWFyZWQ9QmYsUnQodD49MCksUnQobj49MCksUnQocj49MCksdGhpcy5yYWRpaT1uZXcgTCh0LG4sciksdGhpcy5yYWRpaVNxdWFyZWQ9bmV3IEwodCp0LG4qbixyKnIpLHRoaXMucmFkaWlUb1RoZUZvdXJ0aD1uZXcgTCh0KnQqdCp0LG4qbipuKm4scipyKnIqciksdGhpcy5vbmVPdmVyUmFkaWk9bmV3IEwodD09PTA/MDoxL3Qsbj09PTA/MDoxL24scj09PTA/MDoxL3IpLHRoaXMub25lT3ZlclJhZGlpU3F1YXJlZD1uZXcgTCh0PT09MD8wOjEvKHQqdCksbj09PTA/MDoxLyhuKm4pLHI9PT0wPzA6MS8ocipyKSksdGhpcy5taW5pbXVtUmFkaXVzPU1hdGgubWluKHQsbixyKSx0aGlzLm1heGltdW1SYWRpdXM9TWF0aC5tYXgodCxuLHIpLHRoaXMucmFkaWlTcXVhcmVkLnohPT0wJiYodGhpcy5zcXVhcmVkWE92ZXJTcXVhcmVkWj10aGlzLnJhZGlpU3F1YXJlZC54L3RoaXMucmFkaWlTcXVhcmVkLnopLE9iamVjdC5mcmVlemUodGhpcyl9ZXF1YWxzKHQpe3JldHVybiB0aGlzPT09dHx8ISEodCYmdGhpcy5yYWRpaS5lcXVhbHModC5yYWRpaSkpfXRvU3RyaW5nKCl7cmV0dXJuIHRoaXMucmFkaWkudG9TdHJpbmcoKX1jYXJ0b2dyYXBoaWNUb0NhcnRlc2lhbih0LG49WzAsMCwwXSl7Y29uc3Qgcj1xYSxpPXZnLFssLHNdPXQ7dGhpcy5nZW9kZXRpY1N1cmZhY2VOb3JtYWxDYXJ0b2dyYXBoaWModCxyKSxpLmNvcHkodGhpcy5yYWRpaVNxdWFyZWQpLnNjYWxlKHIpO2NvbnN0IG89TWF0aC5zcXJ0KHIuZG90KGkpKTtyZXR1cm4gaS5zY2FsZSgxL28pLHIuc2NhbGUocyksaS5hZGQociksaS50byhuKX1jYXJ0ZXNpYW5Ub0NhcnRvZ3JhcGhpYyh0LG49WzAsMCwwXSl7dHIuZnJvbSh0KTtjb25zdCByPXRoaXMuc2NhbGVUb0dlb2RldGljU3VyZmFjZSh0cixtdCk7aWYoIXIpcmV0dXJuO2NvbnN0IGk9dGhpcy5nZW9kZXRpY1N1cmZhY2VOb3JtYWwocixxYSkscz1FZztzLmNvcHkodHIpLnN1YnRyYWN0KHIpO2NvbnN0IG89TWF0aC5hdGFuMihpLnksaS54KSxjPU1hdGguYXNpbihpLnopLGE9TWF0aC5zaWduKFBlKHMsdHIpKSpjbihzKTtyZXR1cm4gX2coW28sYyxhXSxuKX1lYXN0Tm9ydGhVcFRvRml4ZWRGcmFtZSh0LG49bmV3IG90KXtyZXR1cm4gemEodGhpcywiZWFzdCIsIm5vcnRoIiwidXAiLHQsbil9bG9jYWxGcmFtZVRvRml4ZWRGcmFtZSh0LG4scixpLHM9bmV3IG90KXtyZXR1cm4gemEodGhpcyx0LG4scixpLHMpfWdlb2NlbnRyaWNTdXJmYWNlTm9ybWFsKHQsbj1bMCwwLDBdKXtyZXR1cm4gSm4uZnJvbSh0KS5ub3JtYWxpemUoKS50byhuKX1nZW9kZXRpY1N1cmZhY2VOb3JtYWxDYXJ0b2dyYXBoaWModCxuPVswLDAsMF0pe2NvbnN0IHI9bWcodCksaT1yWzBdLHM9clsxXSxvPU1hdGguY29zKHMpO3JldHVybiBKbi5zZXQobypNYXRoLmNvcyhpKSxvKk1hdGguc2luKGkpLE1hdGguc2luKHMpKS5ub3JtYWxpemUoKSxKbi50byhuKX1nZW9kZXRpY1N1cmZhY2VOb3JtYWwodCxuPVswLDAsMF0pe3JldHVybiBKbi5mcm9tKHQpLnNjYWxlKHRoaXMub25lT3ZlclJhZGlpU3F1YXJlZCkubm9ybWFsaXplKCkudG8obil9c2NhbGVUb0dlb2RldGljU3VyZmFjZSh0LG4pe3JldHVybiBPZyh0LHRoaXMsbil9c2NhbGVUb0dlb2NlbnRyaWNTdXJmYWNlKHQsbj1bMCwwLDBdKXttdC5mcm9tKHQpO2NvbnN0IHI9bXQueCxpPW10Lnkscz1tdC56LG89dGhpcy5vbmVPdmVyUmFkaWlTcXVhcmVkLGM9MS9NYXRoLnNxcnQocipyKm8ueCtpKmkqby55K3MqcypvLnopO3JldHVybiBtdC5tdWx0aXBseVNjYWxhcihjKS50byhuKX10cmFuc2Zvcm1Qb3NpdGlvblRvU2NhbGVkU3BhY2UodCxuPVswLDAsMF0pe3JldHVybiBtdC5mcm9tKHQpLnNjYWxlKHRoaXMub25lT3ZlclJhZGlpKS50byhuKX10cmFuc2Zvcm1Qb3NpdGlvbkZyb21TY2FsZWRTcGFjZSh0LG49WzAsMCwwXSl7cmV0dXJuIG10LmZyb20odCkuc2NhbGUodGhpcy5yYWRpaSkudG8obil9Z2V0U3VyZmFjZU5vcm1hbEludGVyc2VjdGlvbldpdGhaQXhpcyh0LG49MCxyPVswLDAsMF0pe1J0KEYodGhpcy5yYWRpaS54LHRoaXMucmFkaWkueSxEZikpLFJ0KHRoaXMucmFkaWkuej4wKSxtdC5mcm9tKHQpO2NvbnN0IGk9bXQueiooMS10aGlzLnNxdWFyZWRYT3ZlclNxdWFyZWRaKTtpZighKE1hdGguYWJzKGkpPj10aGlzLnJhZGlpLnotbikpcmV0dXJuIG10LnNldCgwLDAsaSkudG8ocil9fWVyLldHUzg0PW5ldyBlcihmZyx1ZyxkZyk7ZnVuY3Rpb24gTGkoZSx0PWVyLldHUzg0LG49bmV3IEspe2NvbnN0IHI9dC5nZXRTdXJmYWNlTm9ybWFsSW50ZXJzZWN0aW9uV2l0aFpBeGlzKGUsMCxjdFswXSksaT1ncihlLHIpLHM9dC5taW5pbXVtUmFkaXVzKmkvdC5tYXhpbXVtUmFkaXVzKioyLG89aSpzKioyO3JldHVybiBuWzBdPWksblswXT1vLG59ZnVuY3Rpb24gYmcoZSx0LG4pe3JldHVybiBuPUxpKGUsdCxuKSxycihbMSwxXSxuLG4pLG59ZnVuY3Rpb24gU2coZSx0LG4pe249TGkoZSx0LG4pO2NvbnN0IHI9TWF0aC5QSS8xODA7cmV0dXJuIFhpKG4sbixyKX1mdW5jdGlvbiBJZyhlKXtsZXQgdD1lLmVhc3Q7Y29uc3Qgbj1lLndlc3Q7cmV0dXJuIHQ8biYmKHQrPVopLHQtbn1mdW5jdGlvbiBQZyhlKXtyZXR1cm4gZS5ub3J0aC1lLnNvdXRofWZ1bmN0aW9uIExnKGUsdCxuLHIsaT17fSl7cmV0dXJuIGkud2VzdD1iZShlPz8wKSxpLnNvdXRoPWJlKHQ/PzApLGkuZWFzdD1iZShuPz8wKSxpLm5vcnRoPWJlKHI/PzApLGl9ZnVuY3Rpb24gUmcoZSx0PXt9KXtsZXQgbj1OdW1iZXIuTUFYX1ZBTFVFLHI9LU51bWJlci5NQVhfVkFMVUUsaT1OdW1iZXIuTUFYX1ZBTFVFLHM9LU51bWJlci5NQVhfVkFMVUUsbz1OdW1iZXIuTUFYX1ZBTFVFLGM9LU51bWJlci5NQVhfVkFMVUU7Zm9yKGxldCBhPTAsaD1lLmxlbmd0aDthPGg7YSsrKXtjb25zdFtmLHVdPWVbYV07bj1NYXRoLm1pbihuLGYpLHI9TWF0aC5tYXgocixmKSxvPU1hdGgubWluKG8sdSksYz1NYXRoLm1heChjLHUpO2NvbnN0IGQ9Zj49MD9mOmYrWjtpPU1hdGgubWluKGksZCkscz1NYXRoLm1heChzLGQpfXJldHVybiByLW4+cy1pJiYobj1pLHI9cyxyPk1hdGguUEkmJihyPXItWiksbj5NYXRoLlBJJiYobj1uLVopKSx0Lndlc3Q9bix0LnNvdXRoPW8sdC5lYXN0PXIsdC5ub3J0aD1jLHR9ZnVuY3Rpb24gJGcoZSx0LG49e30pe3Q9dD8/ZXIuV0dTODQ7bGV0IHI9TnVtYmVyLk1BWF9WQUxVRSxpPS1OdW1iZXIuTUFYX1ZBTFVFLHM9TnVtYmVyLk1BWF9WQUxVRSxvPS1OdW1iZXIuTUFYX1ZBTFVFLGM9TnVtYmVyLk1BWF9WQUxVRSxhPS1OdW1iZXIuTUFYX1ZBTFVFO2ZvcihsZXQgaD0wLGY9ZS5sZW5ndGg7aDxmO2grKyl7Y29uc3RbdSxkXT10LmNhcnRlc2lhblRvQ2FydG9ncmFwaGljKGVbaF0pO3I9TWF0aC5taW4ocix1KSxpPU1hdGgubWF4KGksdSksYz1NYXRoLm1pbihjLGQpLGE9TWF0aC5tYXgoYSxkKTtjb25zdCBnPXU+PTA/dTp1K1o7cz1NYXRoLm1pbihzLGcpLG89TWF0aC5tYXgobyxnKX1yZXR1cm4gaS1yPm8tcyYmKHI9cyxpPW8saT5NYXRoLlBJJiYoaT1pLVopLHI+TWF0aC5QSSYmKHI9ci1aKSksbi53ZXN0PXIsbi5zb3V0aD1jLG4uZWFzdD1pLG4ubm9ydGg9YSxufWZ1bmN0aW9uIENnKGUsdCxuPTApe3JldHVybiBlPT09dHx8ZSYmdCYmTWF0aC5hYnMoZS53ZXN0LXQud2VzdCk8PW4mJk1hdGguYWJzKGUuc291dGgtdC5zb3V0aCk8PW4mJk1hdGguYWJzKGUuZWFzdC10LmVhc3QpPD1uJiZNYXRoLmFicyhlLm5vcnRoLXQubm9ydGgpPD1ufWZ1bmN0aW9uIFZnKGUsdCl7cmV0dXJuIGU9PT10fHxlJiZ0JiZlLndlc3Q9PT10Lndlc3QmJmUuc291dGg9PT10LnNvdXRoJiZlLmVhc3Q9PT10LmVhc3QmJmUubm9ydGg9PT10Lm5vcnRofWZ1bmN0aW9uIE5nKGUsdD1uZXcgSyl7cmV0dXJuIHRbMF09ZS53ZXN0LHRbMV09ZS5zb3V0aCx0fWZ1bmN0aW9uIHpnKGUsdD1uZXcgSyl7cmV0dXJuIHRbMF09ZS53ZXN0LHRbMV09ZS5ub3J0aCx0fWZ1bmN0aW9uIHFnKGUsdD1uZXcgSyl7cmV0dXJuIHRbMF09ZS5lYXN0LHRbMV09ZS5ub3J0aCx0fWZ1bmN0aW9uIEZnKGUsdD1uZXcgSyl7cmV0dXJuIHRbMF09ZS5lYXN0LHRbMV09ZS5zb3V0aCx0fWZ1bmN0aW9uIEZhKGUpe2NvbnN0e3dlc3Q6dCxlYXN0Om4sc291dGg6cixub3J0aDppfT1lO3JldHVybltuZXcgSyh0LHIpLG5ldyBLKHQsaSksbmV3IEsobixpKSxuZXcgSyhuLHIpXX1mdW5jdGlvbiBrZyhlLHQ9bmV3IEspe2xldCBuPWUuZWFzdDtjb25zdCByPWUud2VzdDtuPHImJihuKz1aKTtjb25zdCBpPWZlKChyK24pKi41KSxzPShlLnNvdXRoK2Uubm9ydGgpKi41O3JldHVybiB0WzBdPWksdFsxXT1zLHR9ZnVuY3Rpb24gQmcoZSx0LG49e30pe2xldCByPWUuZWFzdCxpPWUud2VzdCxzPXQuZWFzdCxvPXQud2VzdDtyPGkmJnM+MD9yKz1aOnM8byYmcj4wJiYocys9WikscjxpJiZvPDA/bys9WjpzPG8mJmk8MCYmKGkrPVopO2NvbnN0IGM9ZmUoTWF0aC5tYXgoaSxvKSksYT1mZShNYXRoLm1pbihyLHMpKTtpZigoZS53ZXN0PGUuZWFzdHx8dC53ZXN0PHQuZWFzdCkmJmE8PWMpcmV0dXJuO2NvbnN0IGg9TWF0aC5tYXgoZS5zb3V0aCx0LnNvdXRoKSxmPU1hdGgubWluKGUubm9ydGgsdC5ub3J0aCk7aWYoIShoPj1mKSlyZXR1cm4gbi53ZXN0PWMsbi5zb3V0aD1oLG4uZWFzdD1hLG4ubm9ydGg9ZixufWZ1bmN0aW9uIFVnKGUsdCxuKXtjb25zdCByPU1hdGgubWF4KGUud2VzdCx0Lndlc3QpLGk9TWF0aC5tYXgoZS5zb3V0aCx0LnNvdXRoKSxzPU1hdGgubWluKGUuZWFzdCx0LmVhc3QpLG89TWF0aC5taW4oZS5ub3J0aCx0Lm5vcnRoKTtpZighKGk+PW98fHI+PXMpKXJldHVybiBuPz8obj17fSksbi53ZXN0PXIsbi5zb3V0aD1pLG4uZWFzdD1zLG4ubm9ydGg9byxufWZ1bmN0aW9uIERnKGUsdCxuPXt9KXtsZXQgcj1lLmVhc3QsaT1lLndlc3Qscz10LmVhc3Qsbz10Lndlc3Q7cjxpJiZzPjA/cis9WjpzPG8mJnI+MCYmKHMrPVopLHI8aSYmbzwwP28rPVo6czxvJiZpPDAmJihpKz1aKTtjb25zdCBjPWZlKE1hdGgubWluKGksbykpLGE9ZmUoTWF0aC5tYXgocixzKSk7cmV0dXJuIG4ud2VzdD1jLG4uc291dGg9TWF0aC5taW4oZS5zb3V0aCx0LnNvdXRoKSxuLmVhc3Q9YSxuLm5vcnRoPU1hdGgubWF4KGUubm9ydGgsdC5ub3J0aCksbn1mdW5jdGlvbiBZZyhlLHQsbj17fSl7cmV0dXJuIG4ud2VzdD1NYXRoLm1pbihlLndlc3QsdFswXSksbi5zb3V0aD1NYXRoLm1pbihlLnNvdXRoLHRbMV0pLG4uZWFzdD1NYXRoLm1heChlLmVhc3QsdFswXSksbi5ub3J0aD1NYXRoLm1heChlLm5vcnRoLHRbMV0pLG59ZnVuY3Rpb24gV2coZSx0KXtsZXQgbj10WzBdO2NvbnN0IHI9dFsxXSxpPWUud2VzdDtsZXQgcz1lLmVhc3Q7cmV0dXJuIHM8aSYmKHMrPVosbjwwJiYobis9WikpLChuPml8fEdyKG4saSx2bikpJiYobjxzfHxHcihuLHMsdm4pKSYmcj49ZS5zb3V0aCYmcjw9ZS5ub3J0aH1jb25zdCBaZz1PYmplY3QuZnJlZXplKHt3ZXN0Oi1NYXRoLlBJLGVhc3Q6TWF0aC5QSSxzb3V0aDotSXIsbm9ydGg6SXJ9KTtmdW5jdGlvbiBYZyhlKXtjb25zdHttYXRyaXg6dCxwb3NpdGlvbk5hbWVzOm49UWUsc2NhbGU6cn09ZSxpPW5ldyBGbihlKTt0JiZpLnRyYW5zZm9ybUZvckFnZ3JlZ2F0ZSh0LG4pO2NvbnN0IG89bmV3IEtuKHsuLi5lLGdlb21ldHJ5Oml9KS5yZWxhdGlvbkFyZWE7aWYoIXIpcmV0dXJuIG87Y29uc3QgYz1NYXRoLmh5cG90KHJbMF0sclsyXSkqclsxXTtyZXR1cm4gbypNYXRoLmFicyhjKX1mdW5jdGlvbiBrYShlKXtjb25zdHttYXRyaXg6dCxwb3NpdGlvbk5hbWVzOm49UWUsc2NhbGU6cixoZWlnaHRSYW5nZTppfT1lLHM9bmV3IEZuKGUpO3QmJnMudHJhbnNmb3JtRm9yQWdncmVnYXRlKHQsbik7Y29uc3Qgbz1uZXcgS24oey4uLmUsZ2VvbWV0cnk6c30pO2xldCBjPTE7aWYocilmb3IobGV0IGEgb2YgciljKj1hO3JldHVybiBvLmNvbXB1dGVSZWxhdGlvblRlcnJhaW5Wb2x1bWUoaSkqY31mdW5jdGlvbiBHZyhlKXtjb25zdHtyZWN0YW5nbGU6dCxoZWlnaHRSYW5nZTpuLHBvc2l0aW9uTmFtZXM6cj1RZSxzY2FsZTppfT1lLHM9bmV3IEZuKGUpLG89bmkodCxuKTtzLnRyYW5zZm9ybUZvckFnZ3JlZ2F0ZShvLHIpO2NvbnN0IGM9bmV3IEtuKHsuLi5lLGdlb21ldHJ5OnN9KSxhPUZhKHQpLGg9bmV3IEdlKGEpLGY9WWUuc3VidHJhY3QoaCxjLmdlb21ldHJ5UG9seWdvbiksdT1jLnJlbGF0aW9uQXJlYStmLmFyZWEoKTtpZighaSlyZXR1cm4gdTtjb25zdCBkPU1hdGguaHlwb3QoaVswXSxpWzJdKSppWzFdO3JldHVybiB1Kk1hdGguYWJzKGQpfWZ1bmN0aW9uIGpnKGUpe2NvbnN0e3JlY3RhbmdsZTp0LGhlaWdodFJhbmdlOm4sLi4ucn09ZSxpPW5pKHQsbik7cmV0dXJuIGthKHsuLi5yLG1hdHJpeDppLGhlaWdodFJhbmdlOm59KX1mdW5jdGlvbiBSaShlLHQpe3JldHVybiBlLnkqdC54K2UueH1mdW5jdGlvbiBRZyhlLHQpe2NvbnN0e3g6bn09dCxyPU1hdGgudHJ1bmMoZS9uKTtyZXR1cm57eDplLXIqbix5OnJ9fWZ1bmN0aW9uIEtnKGUsdCxuPTEpe2xldHt4OnIseTppfT10O2NvbnN0IHM9ZS5zaXplO3JldHVybiByPU1hdGgubWF4KDAsTWF0aC5taW4ocy54LTEscikpLGk9TWF0aC5tYXgoMCxNYXRoLm1pbihzLnktMSxpKSksQmEoZSx7eDpyLHk6aX0sbil9ZnVuY3Rpb24gQmEoZSx0LG49MSl7Y29uc3R7ZGF0YTpyLHNpemU6aX09ZSxzPVJpKHQsaSk7bGV0IG89W107aWYobj4wKXtjb25zdCBjPXMqbjtmb3IobGV0IGE9MDthPG47YSsrKW8ucHVzaChyW2MrYV0pfXJldHVybntpbmRleDpzLHZhbHVlOm99fWZ1bmN0aW9uIEhnKGUsdCl7bGV0e3g6bix5OnJ9PXQ7Y29uc3QgaT1lLnNpemU7cmV0dXJuIG49TWF0aC5tYXgoMCxNYXRoLm1pbihpLngtMSxuKSkscj1NYXRoLm1heCgwLE1hdGgubWluKGkueS0xLHIpKSxVYShlLHt4Om4seTpyfSl9ZnVuY3Rpb24gVWEoZSx0KXtjb25zdHtkYXRhOm4sc2l6ZTpyfT1lLGk9UmkodCxyKTtyZXR1cm57aW5kZXg6aSx2YWx1ZTpuW2ldfX1mdW5jdGlvbiBKZyhlLHQsbj0xKXtjb25zdHtkYXRhOnIsc2l6ZTppfT1lLHM9aS54LG89dCpzLGM9bytzO3JldHVybih0eXBlb2Ygci5zbGljZT09ImZ1bmN0aW9uIj9yOkFycmF5LmZyb20ocikpLnNsaWNlKG8qbixjKm4pfWZ1bmN0aW9uIHRtKGUsdCl7Zm9yKGNvbnN0W24scl1vZiBPYmplY3QuZW50cmllcyhlKSlpZigwPD1yJiZyPD10W25dKXJldHVybiEwO3JldHVybiExfWZ1bmN0aW9uICRpKGUsdCl7Y29uc3R7eDpuLHk6cn09dDtyZXR1cm4gZS56KnIqbitlLnkqbitlLnh9ZnVuY3Rpb24gZW0oZSx0KXtjb25zdHt4Om4seTpyfT10LGk9TWF0aC50cnVuYyhlL24pLHM9ZS1pKm4sbz1NYXRoLnRydW5jKGkvciksYz1pLW8qcjtyZXR1cm57eDpzLHk6Yyx6Om99fWZ1bmN0aW9uIG5tKGUsdCxuPTEpe2xldHt4OnIseTppLHo6c309dDtjb25zdCBvPWUuc2l6ZTtyZXR1cm4gcj1NYXRoLm1heCgwLE1hdGgubWluKG8ueC0xLHIpKSxpPU1hdGgubWF4KDAsTWF0aC5taW4oby55LTEsaSkpLHM9TWF0aC5tYXgoMCxNYXRoLm1pbihvLnotMSxzKSksQ2koZSx7eDpyLHk6aSx6OnN9LG4pfWZ1bmN0aW9uIENpKGUsdCxuPTEpe2NvbnN0e2RhdGE6cixzaXplOml9PWUscz0kaSh0LGkpO2xldCBvPVtdO2lmKG4+MCl7Y29uc3QgYz1zKm47Zm9yKGxldCBhPTA7YTxuO2ErKylvLnB1c2gocltjK2FdKX1yZXR1cm57aW5kZXg6cyx2YWx1ZTpvfX1mdW5jdGlvbiBybShlLHQpe2xldHt4Om4seTpyLHo6aX09dDtjb25zdCBzPWUuc2l6ZTtyZXR1cm4gbj1NYXRoLm1heCgwLE1hdGgubWluKHMueC0xLG4pKSxyPU1hdGgubWF4KDAsTWF0aC5taW4ocy55LTEscikpLGk9TWF0aC5tYXgoMCxNYXRoLm1pbihzLnotMSxpKSksVmkoZSx7eDpuLHk6cix6Oml9KX1mdW5jdGlvbiBWaShlLHQpe2NvbnN0e2RhdGE6bixzaXplOnJ9PWUsaT0kaSh0LHIpO3JldHVybntpbmRleDppLHZhbHVlOm5baV19fWZ1bmN0aW9uIGltKGUsdCl7Y29uc3R7dm9pZFZhbHVlOm4sdmFsdWVzQWNjdW11bGF0ZTpyLHZlcmlmeVZvaWQ6aT0oKT0+ITF9PXQ7bGV0e3g6cyx5Om8sejpjfT1lWzBdLnNpemU7Y29uc3QgYT1lLmxlbmd0aDtmb3IobGV0IGQ9MTtkPGE7ZCsrKXtjb25zdCBnPWVbZF0uc2l6ZTtzPU1hdGgubWF4KHMsZy54KSxvPU1hdGgubWF4KG8sZy55KSxjPU1hdGgubWF4KGMsZy56KX1jb25zdCBoPXMqbypjLGY9bmV3IEFycmF5KGgpLHU9cypvO2ZvcihsZXQgZD0wO2Q8YztkKyspe2NvbnN0IGc9ZCp1O2ZvcihsZXQgbT0wO208bzttKyspe2NvbnN0IF89ZyttKnM7Zm9yKGxldCBwPTA7cDxzO3ArKyl7Y29uc3QgeD1fK3AsVD17eDpwLHk6bSx6OmR9LE09W107Zm9yKGNvbnN0IHcgb2YgZSl7Y29uc3QgUD13LnNpemU7aWYocDxQLngmJm08UC55JiZkPFAueiljb250aW51ZTtjb25zdHtpbmRleDpiLHZhbHVlOlN9PVZpKHcsVCk7aShTLHcsYil8fE0ucHVzaCh7dmFsdWU6UyxpbmRleDpiLGRhdGEzRDp3LGNvb3JkOlR9KX1jb25zdCBBPU0ubGVuZ3RoO2xldCB2PW47QT4xP3Y9cihNKTpBPT09MSYmKHY9TVswXS52YWx1ZSksZlt4XT12fX19cmV0dXJue2RhdGE6ZixzaXplOnt4OnMseTpvLHo6Y319fWZ1bmN0aW9uIHNtKGUsdCxuLHI9MSl7Y29uc3R7c2l6ZTppfT1lLHM9RXQudG9LZXkodCksW28sY109RXQuZ2V0Q3Jvc3NBeGlzcyh0KSxhPUV0LnRvS2V5KG8pLGg9RXQudG9LZXkoYyksZj1pW2FdLHU9aVtoXSxkPVtdLGc9aVtzXTtuPU1hdGgudHJ1bmMobiksbj1NYXRoLm1heCgwLE1hdGgubWluKGctMSxuKSk7bGV0IG09e3g6MCx5OjAsejowfTttW3NdPW47Zm9yKGxldCBfPTA7Xzx1O18rKyl7bVtoXT1fO2ZvcihsZXQgcD0wO3A8ZjtwKyspe21bYV09cDtjb25zdHt2YWx1ZTp4fT1DaShlLG0scik7ZC5wdXNoKC4uLngpfX1yZXR1cm57ZGF0YTpkLHNpemU6e3g6Zix5OnV9fX12YXIgb209T2JqZWN0LmZyZWV6ZSh7X19wcm90b19fOm51bGwsQXR0cmlidXRlTmFtZTpnYyxBdHRyaWJ1dGVzOm1jLGdldCBBeGlzKCl7cmV0dXJuIEV0fSxnZXQgQXhpczQoKXtyZXR1cm4gbm59LEdlb21ldHJpY1JlbGF0aW9uOnksR2VvbWV0cnk6Rm4sR2VvbWV0cnlSZWxhdGlvbk1lYXN1cmU6Q2EsTGluZTpLcixNYXRoQXJyYXk6U2UsTWF0cml4OmRuLE1hdHJpeDI6bGUsZ2V0IE1hdHJpeENvbXBvc2VPcmRlcigpe3JldHVybiBIfSxnZXQgTnVtZXJpY0FycmF5VHlwZSgpe3JldHVybiBFbn0sZ2V0IE9yaWVudGF0aW9uKCl7cmV0dXJuIF90fSxQb2x5Z29uMkdlb21ldHJ5UmVsYXRpb25NZWFzdXJlOktuLFBvbHlsaW5lOnBjLFZlY3RvcjpybixWZWN0b3JBcnJheTpIdCxhZGRWZWN0b3JBcnJheTpjMSxhZGp1c3RGcmVuZXRGcmFtZTpvYyxhZGp1c3RGcm9udFVwRnJhbWU6Y2MsYWRqdXN0T3JpZW50YXRpb246dDEsYWdncmVnYXRlRmFjZVBvc2l0aW9uUmVsYXRpb25zT2ZHZW9tZXRyeV9Qb2x5Z29uOlYxLGNhbGN1bGF0ZVBhdGhBbmltYXRpb25UaW1lczpfYyxjaGVja051bWJlcjokLGNoZWNrVmVjdG9yOkd0LGNsaXBHZW9tZXRyeUJ5Qm9yZGVyOnRpLGNsaXBHZW9tZXRyeUJ5Qm9yZGVyczokMSxjb21wdXRlQXJlYU9mR2VvbWV0cnk6b2ksY29tcHV0ZUFyZWFPZlRyaWFuZ2xlMjpZMSxjb21wdXRlQXJlYU9mVHJpYW5nbGUyMzpVMSxjb21wdXRlQXJlYU9mVHJpYW5nbGUzOkQxLGNvbXB1dGVDb252ZXhIdWxsMjpiMSxjb21wdXRlQ29udmV4SHVsbDJGb3JTb3J0ZWQ6dmMsY29tcHV0ZURvdWJsZUFyZWFPZlRyaWFuZ2xlMjpzaSxjb21wdXRlRG91YmxlQXJlYU9mVHJpYW5nbGUyMzppaSxjb21wdXRlRG91YmxlQXJlYU9mVHJpYW5nbGUzOkJjLGNvbXB1dGVEb3VibGVTaWduQXJlYU9mUG9seWdvbjI6TmMsY29tcHV0ZURvdWJsZVNpZ25BcmVhT2ZQb2x5Z29uMzp6Yyxjb21wdXRlRG91YmxlU2lnbkFyZWFPZlRyaWFuZ2xlMjpxYyxjb21wdXRlRG91YmxlU2lnbkFyZWFPZlRyaWFuZ2xlMjM6a2MsY29tcHV0ZURvdWJsZVNpZ25BcmVhT2ZUcmlhbmdsZTM6RmMsY29tcHV0ZUdsb2JlT3JpZW50YXRpb25GcmFtZU9uTG9uTGF0OmxjLGNvbXB1dGVHbG9iZU9yaWVudGF0aW9uRnJhbWVPblBvc2l0aW9uOlFyLGNvbXB1dGVJbnRlcnNlY3Rpb25GYWN0b3JPZkxpbmVfQ2lyY2xlOnVlLGNvbXB1dGVJbnRlcnNlY3Rpb25PZjIzTGluZVNlZ21lbnRfTGluZVNlZ21lbnQ6TzEsY29tcHV0ZUludGVyc2VjdGlvbk9mMjNMaW5lX0xpbmU6TmUsY29tcHV0ZUludGVyc2VjdGlvbk9mMjNSYXlfTGluZVNlZ21lbnQ6VDEsY29tcHV0ZUludGVyc2VjdGlvbk9mMkxpbmVTZWdtZW50X0xpbmVTZWdtZW50OnYxLGNvbXB1dGVJbnRlcnNlY3Rpb25PZjJMaW5lX0xpbmU6Qm4sY29tcHV0ZUludGVyc2VjdGlvbk9mMlBvbHlnb25fQ2lyY2xlOkwxLGNvbXB1dGVJbnRlcnNlY3Rpb25PZjJSYXlfTGluZVNlZ21lbnQ6QTEsY29tcHV0ZUludGVyc2VjdGlvbk9mTGluZVNlZ21lbnRfQ2lyY2xlOndjLGNvbXB1dGVJbnRlcnNlY3Rpb25PZkxpbmVfQ2lyY2xlOnAxLGNvbXB1dGVJbnRlcnNlY3Rpb25PZlJheV9DaXJjbGU6eTEsY29tcHV0ZVJlbGF0aW9uQXJlYU9mUG9seWdvbjJHZW9tZXRyeTpYZyxjb21wdXRlUmVsYXRpb25BcmVhT2ZQb2x5Z29uMlRlcnJhaW46R2csY29tcHV0ZVJlbGF0aW9uVGVycmFpblZvbHVtZU9mUG9seWdvbjJHZW9tZXRyeTprYSxjb21wdXRlUmVsYXRpb25UZXJyYWluVm9sdW1lT2ZQb2x5Z29uMlRlcnJhaW46amcsY29tcHV0ZVNpZ25BcmVhT2ZQb2x5Z29uMjp6MSxjb21wdXRlU2lnbkFyZWFPZlBvbHlnb24zOnExLGNvbXB1dGVTaWduQXJlYU9mVHJpYW5nbGUyOkYxLGNvbXB1dGVTaWduQXJlYU9mVHJpYW5nbGUyMzpCMSxjb21wdXRlU2lnbkFyZWFPZlRyaWFuZ2xlMzprMSxjb21wdXRlVm9sdW1lT2ZUZXJyYWluOmNpLGNyZWF0ZUdsb2JlT3JpZW50YXRpb25GcmFtZU1hdHJpeDNPbkxvbkxhdDpyMSxjcmVhdGVHbG9iZU9yaWVudGF0aW9uRnJhbWVNYXRyaXgzT25Qb3NpdGlvbjpuMSxjcmVhdGVHbG9iZU9yaWVudGF0aW9uRnJhbWVNYXRyaXg0T25Qb3NpdGlvbjplMSxjcmVhdGVLZXlmcmFtZVRyYWNrc09mQ3VydmVBbmltYXRpb25CeVBvbHlsaW5lOmQxLGNyZWF0ZU9yaWVudGF0aW9uRnJhbWVNYXRyaXgzOnFuLGNyZWF0ZU9yaWVudGF0aW9uRnJhbWVNYXRyaXg0OmhjLGNyZWF0ZVF1YW50aXplZE1lc2hUZXJyYWluVmVydGV4R2V0dGVyOk4xLGNyZWF0ZVZlY3RvcjpzbyxkYXRhMkRDb29yZFRvSW5kZXg6UmksZGF0YTJESW5kZXhUb0Nvb3JkOlFnLGRhdGEzRENvb3JkVG9JbmRleDokaSxkYXRhM0RJbmRleFRvQ29vcmQ6ZW0sZGVmYXVsdFNjYWxlOmZjLGRlZmF1bHRVcDp1YyxkZXByZWNhdGVkOmlsLGRpdmlkZVZlY3RvckFycmF5OmgxLGVsbGlwc29pZF9nZXRMb2NhbEN1cnZhdHVyZTpiZyxlbGxpcHNvaWRfZ2V0TG9jYWxDdXJ2YXR1cmVSYWRpdXM6TGksZWxsaXBzb2lkX2dldExvY2FsU2l6ZVBlckRlZ3JlZXM6U2csZXF1YWxzRXBzaWxvbjpHcixmaWx0ZXJGYWNlQnlQb2x5Z29uUmVsYXRpb246VmMsZmlsdGVyR3JvdXBzOnUxLGZpbmRDb25jYXZlUG9pbnRJbmRleE9mUG9seWdvbjI6UzEsZmluZFRhbmdlbnRQb2ludE9mMkNvbnZleFBvbHlnb246STEsZmxhdE51bWVyaWNBcnJheUFycmF5OmRjLGZyYW1lTG9vcDpnMSxmcmVuZXRGcmFtZVRvRnJvbnRVcEZyYW1lOkgwLGZyb250VXBGcmFtZVRvRnJlbmV0RnJhbWU6SjAsZ2VuZXJhdGVGYWNlUmVsYXRpb25zT2ZHZW9tZXRyeV9Qb2x5Z29uOlJjLGdlbmVyYXRlUG9zaXRpb25SZWxhdGlvbnNPZkdlb21ldHJ5X0NvbnZleFBvbHlnb246TGMsZ2VuZXJhdGVQb3NpdGlvblJlbGF0aW9uc09mR2VvbWV0cnlfUG9seWdvbjpQYyxnZXRBeGlzUm90YXRpb25BbmdsZTpqMCxnZXRBemltdXRoQW5nbGU6UTAsZ2V0RGF0YTJESXRlbTpCYSxnZXREYXRhMkRJdGVtU2FmZTpLZyxnZXREYXRhMkRSb3c6SmcsZ2V0RGF0YTJEVmFsdWU6VWEsZ2V0RGF0YTJEVmFsdWVTYWZlOkhnLGdldERhdGEzREl0ZW06Q2ksZ2V0RGF0YTNESXRlbVNhZmU6bm0sZ2V0RGF0YTNEU2xpY2U6c20sZ2V0RGF0YTNEVmFsdWU6VmksZ2V0RGF0YTNEVmFsdWVTYWZlOnJtLGdldER1cmF0aW9uT2ZQYXRoQW5pbWF0aW9uT3B0aW9uczp5YyxnZXRJbmNsdWRlZEFuZ2xlOmpyLGdldEtleWZyYW1lVHJhbnNmb3JtRGF0YXNCeVBvbHlsaW5lOnhjLGdldE1hdHJpeE9mUXVhbnRpemVkTWVzaFRlcnJhaW5EYXRhOm5pLGdldE1pbkFuZ2xlQmV0d2VlbkxpbmVzOkswLGdldFBvbHlnb25SZWxhdGlvbkJ5QWdncmVnYXRlUG9zaXRpb25SZWxhdGlvbjpDYyxnZXRSb3RhdGlvbkFuZ2xlOlZlLGdldFNjYWxlT2ZRdWFudGl6ZWRNZXNoVGVycmFpbkRhdGE6cmksZ2V0VHJhbnNmb3JtTWF0RnVuOiRlLGdldFZlY0Z1bnM6RCxnZXRWZWN0b3JDbGFzczpZZixpVmVjdG9yVG9OdW1iZXJBcnJheTpjbyxpc0NvbnZleFBvbHlnb24yOkVjLGlzT3V0T2ZTaXplOnRtLGl2ZWN0b3JNZW1iZXJUb1ZlY3RvcjpDZSxpdmVjdG9yVG9WZWN0b3I6YW8sbG5nTGF0UmVjdGFuZ2xlX0hlaWdodDpQZyxsbmdMYXRSZWN0YW5nbGVfV2lkdGg6SWcsbG5nTGF0UmVjdGFuZ2xlX2NlbnRlcjprZyxsbmdMYXRSZWN0YW5nbGVfY29udGFpbnM6V2csbG5nTGF0UmVjdGFuZ2xlX2Nvcm5lcnM6RmEsbG5nTGF0UmVjdGFuZ2xlX2VxdWFsczpWZyxsbmdMYXRSZWN0YW5nbGVfZXF1YWxzRXBzaWxvbjpDZyxsbmdMYXRSZWN0YW5nbGVfZXhwYW5kOllnLGxuZ0xhdFJlY3RhbmdsZV9mcm9tQ2FydGVzaWFuQXJyYXk6JGcsbG5nTGF0UmVjdGFuZ2xlX2Zyb21DYXJ0b2dyYXBoaWNBcnJheTpSZyxsbmdMYXRSZWN0YW5nbGVfZnJvbURlZ3JlZXM6TGcsbG5nTGF0UmVjdGFuZ2xlX2ludGVyc2VjdGlvbjpCZyxsbmdMYXRSZWN0YW5nbGVfbm9ydGhlYXN0OnFnLGxuZ0xhdFJlY3RhbmdsZV9ub3J0aHdlc3Q6emcsbG5nTGF0UmVjdGFuZ2xlX3NpbXBsZUludGVyc2VjdGlvbjpVZyxsbmdMYXRSZWN0YW5nbGVfc291dGhlYXN0OkZnLGxuZ0xhdFJlY3RhbmdsZV9zb3V0aHdlc3Q6TmcsbG5nTGF0UmVjdGFuZ2xlX3VuaW9uOkRnLG1hcEdyb3VwczpmMSxtYXQyOmF1LG1hdDJfY29tcG9zZV9yczpSbyxtYXQyX2NvbXBvc2Vfc3I6UG8sbWF0Ml9kZWNvbXBvc2VfcnM6TG8sbWF0Ml9kZWNvbXBvc2Vfc3I6SW8sbWF0Ml9mcm9tTWF0MzpDbixtYXQyX2dldENvbFNjYWxlOmJvLG1hdDJfZ2V0Um93U2NhbGU6U28sbWF0Ml9tdWx0aXBseUJ5Q29sU2NhbGU6eTAsbWF0Ml9tdWx0aXBseUJ5Um93U2NhbGU6eDAsbWF0MmQ6UHUsbWF0M19jb21wb3NlOnYwLG1hdDNfY29tcG9zZV9yczp6cixtYXQzX2NvbXBvc2VfcnNfcXVhdDpObyxtYXQzX2NvbXBvc2Vfc3I6VnIsbWF0M19jb21wb3NlX3NyX3F1YXQ6QTAsbWF0M19kZWNvbXBvc2U6TzAsbWF0M19kZWNvbXBvc2VfcnM6TnIsbWF0M19kZWNvbXBvc2VfcnNfcXVhdDpWbyxtYXQzX2RlY29tcG9zZV9zcjpDcixtYXQzX2RlY29tcG9zZV9zcl9xdWF0OlQwLG1hdDNfZnJvbU1hdDI6a28sbWF0M19mcm9tTWF0NDprcixtYXQzX2dldENvbFNjYWxlOiRvLG1hdDNfZ2V0TG9jYWxUcmFuc2xhdGlvbjpxbyxtYXQzX2dldFJvd1NjYWxlOkNvLG1hdDNfZ2V0VHJhbnNsYXRpb246RnIsbWF0M19tdWx0aXBseUJ5Q29sU2NhbGU6TTAsbWF0M19tdWx0aXBseUJ5Um93U2NhbGU6dzAsbWF0M19ub3JtYWxNYXRyaXg6JHIsbWF0M19zZXRMb2NhbFRyYW5zbGF0aW9uOnpvLG1hdDNfc2V0TWF0MjpGbyxtYXQzX3NldFRyYW5zbGF0aW9uOnFyLG1hdDRfY29tcG9zZTpabyxtYXQ0X2NvbXBvc2VfcXVhdDpMMCxtYXQ0X2RlY29tcG9zZTpXbyxtYXQ0X2RlY29tcG9zZV9xdWF0OlAwLG1hdDRfZnJvbU1hdDM6VW8sbWF0NF9nZXRDb2xTY2FsZTpFMCxtYXQ0X2dldExvY2FsVHJhbnNsYXRpb246WW8sbWF0NF9nZXRSb3dTY2FsZTpiMCxtYXQ0X211bHRpcGx5QnlDb2xTY2FsZTpTMCxtYXQ0X211bHRpcGx5QnlSb3dTY2FsZTpJMCxtYXQ0X3NldExvY2FsVHJhbnNsYXRpb246RG8sbWF0NF9zZXRNYXQzOkJvLG1hdDRfc2V0VHJhbnNsYXRpb246QnIsbWF0X2dldENvbFNjYWxlOlBuLG1hdF9nZXRDb2x1bW46ZjAsbWF0X2dldENvbHVtbnM6d28sbWF0X2dldFJvdzpUbyxtYXRfZ2V0Um93U2NhbGU6TG4sbWF0X2dldFJvd3M6QW8sbWF0X211bHRpcGx5QnlDb2xTY2FsZTp6dCxtYXRfbXVsdGlwbHlCeVJvd1NjYWxlOnF0LG1hdF9zZXRUcmFuc2xhdGlvbjp1MCxtYXhMbmdMYXRSZWN0YW5nbDpaZyxtZXJnZURhdGEzRHM6aW0sbXVsdGlwbHlWZWN0b3JBcnJheTpsMSxuZWdhdGl2ZVBpVG9QaTpmZSxub3JtYWxpemVWZWN0b3JzOkMxLG51bWVyaWNBcnJheVR5cGVDbGFzc01hcDpvbyxwb3NpdGlvbk5hbWVzX2RlZmF1bHQ6UWUscXVhdDI6aDAscXVhdF9hbGlnbkZyZW5ldEZyYW1lOlhyLHF1YXRfZnJvbUV1bGVyOkcwLHF1YXRfcm90YXRpb25CZXR3ZWVuVmVjdG9yc0Fyb3VuZEF4aXM6cmMscmVsYXRpb25PZjIzTGluZVNlZ21lbnRfTGluZVNlZ21lbnQ6SHIscmVsYXRpb25PZjIzUmF5X0xpbmVTZWdtZW50OncxLHJlbGF0aW9uT2YyQ29udmV4UG9seWdvbl9Db252ZXhQb2x5Z29uOkljLHJlbGF0aW9uT2YyQ29udmV4UG9seWdvbl9MaW5lU2VnbWVudDpKcixyZWxhdGlvbk9mMkNvbnZleFBvbHlnb25fUG9pbnQ6UHQscmVsYXRpb25PZjJMaW5lU2VnbWVudF9Qb2ludDpUYyxyZWxhdGlvbk9mMlBvbHlnb25fQ2lyY2xlOlAxLHJlbGF0aW9uT2YyUG9seWdvbl9Db252ZXhQb2x5Z29uOlNjLHJlbGF0aW9uT2YyUG9seWdvbl9MaW5lU2VnbWVudDpiYyxyZWxhdGlvbk9mMlBvbHlnb25fUG9pbnQ6TXQscmVsYXRpb25PZjJQb2x5Z29uX1BvbHlnb246UjEscmVsYXRpb25PZjJSYXlfTGluZVNlZ21lbnQ6QWMscmVsYXRpb25PZkxpbmVTZWdtZW50X0NpcmNsZTpNYyxyZWxhdGlvbk9mTGluZVNlZ21lbnRfUG9pbnQ6TTEscmVsYXRpb25PZkxpbmVfQ2lyY2xlOm0xLHJlbGF0aW9uT2ZMaW5lX0xpbmU6a24scmVsYXRpb25PZk51bWJlclJhbmdlczpFMSxyZWxhdGlvbk9mUmF5X0NpcmNsZTpfMSxzYWZlTW9kOmljLHNjYWxlQW5kQWRkVmVjdG9yQXJyYXk6bzEsc2NhbGVWZWN0b3JBcnJheTpzMSxzb3J0UG9pbnRzMkNDVzpPYyxzdWJ0cmFjdFZlY3RvckFycmF5OmExLHRyYW5zZm9ybVZlY3RvckFycmF5OmkxLHZhbGlkYXRlVmVjdG9yOlVpLHZlYzIzX2FyZWE6am8sdmVjMjNfY3Jvc3M6UjAsdmVjMjNfaXNDb2xsaW5lYXI6JDAsdmVjMjNfc2lnbkFyZWE6SG8sdmVjMl9hcmVhOktvLHZlYzJfaXNDb2xsaW5lYXI6R28sdmVjMl9zaWduQXJlYTpoZSx2ZWMyX3RyYW5zZm9ybU1hdDRBc1ZlY3Rvcjpjcix2ZWMzX2FyZWE6UW8sdmVjM19pc0NvbGxpbmVhcjpDMCx2ZWMzX3NpZ25BcmVhOlVyLHZlYzNfdHJhbnNmb3JtTWF0Mjp0cyx2ZWMzX3RyYW5zZm9ybU1hdDRBc1ZlY3Rvcjphcix2ZWM0X3RyYW5zZm9ybU1hdDI6ZXMsdmVjNF90cmFuc2Zvcm1NYXQzOmxyLHZlY19hZGQ6dGMsdmVjX2NlaWw6ejAsdmVjX2NvbXB1dGVWZWN0b3JTY2FsYXI6Vyx2ZWNfZGlzdGFuY2U6ZWMsdmVjX2RpdmlkZTpOMCx2ZWNfZG90OnpuLHZlY19mbG9vcjpxMCx2ZWNfaW52ZXJzZTpZMCx2ZWNfaXNDb2xsaW5lYXI6Tm4sdmVjX2xlbmd0aDpKbyx2ZWNfbGVycDpaMCx2ZWNfbWF4OmswLHZlY19taW46RjAsdmVjX211bHRpcGx5OlYwLHZlY19uZWdhdGU6RDAsdmVjX25vcm1hbGl6ZTpXMCx2ZWNfcHJvamVjdE9uUGxhbmU6eHQsdmVjX3Byb2plY3RPblZlY3RvcjpYbyx2ZWNfcm91bmQ6VTAsdmVjX3NjYWxlOllyLHZlY19zY2FsZUFuZEFkZDpXcix2ZWNfc2xlcnA6WDAsdmVjX3NxdWFyZWREaXN0YW5jZTpuYyx2ZWNfc3F1YXJlZExlbmd0aDpacix2ZWNfc3VidHJhY3Q6U3QsdmVjX3RvU2FtZURpcmVjdG9uOkRyLHdoaWNoU2lkZU9mMmxpbmU6SXQsd2hpY2hTaWRlT2YzbGluZTp4MSx6ZXJvVG9Ud29QaTpzY30pO09iamVjdC5hc3NpZ24oZ2xvYmFsVGhpcyxvbSksY29uc29sZS5sb2coIuWKqOaAgVdvcmtlcuW3suWKoOi9vTogQHdlYi0zZC90b29scyIpfSkoKTsK",ll&&ll.tagName.toUpperCase()==="SCRIPT"&&ll.src||new URL("tools.iife.js",document.baseURI).href).href,{name:n?.name})}function Lu(n="@web-3d/tools"){const t=new yu({name:n});return oc(t)}const xu=Lu();function Zn(n,t,l){l=l??new h.Matrix4;const s=h.Matrix4.inverse(t,new h.Matrix4),e=h.Matrix4.multiply(n,s,s);return h.Matrix4.multiply(t,e,l)}function Ku(n,t,l,s){s=s??new h.Matrix4;const e=h.Matrix4.inverse(l,new h.Matrix4);let d=h.Matrix4.multiply(e,n,e);return d=h.Matrix4.multiply(t,d,d),h.Matrix4.multiply(l,d,s)}function Ru(n,t,l){const s=h.Matrix4.fromTranslation(n);return Zn(s,t,l)}function Su(n,t,l,s){const e=h.Quaternion.fromAxisAngle(n,t),d=h.Matrix3.fromQuaternion(e),i=h.Matrix4.fromRotation(d);return Zn(i,l,s)}function zu(n,t,l){const s=h.Matrix4.fromScale(n);return Zn(s,t,l)}function Mu(n,t,l){const s=h.Matrix3.fromScale(t);if(l)for(const e of n)h.Cartesian3.subtract(e,l,e),h.Matrix3.multiplyByVector(s,e,e),h.Cartesian3.add(e,l,e);else{const e=h.Matrix3.fromScale(t);for(const d of n)h.Matrix3.multiplyByVector(e,d,d)}return n}function Yu(n,t){const{translation:l,rotation:s,scale:e}=n;let d;if(s){const{axis:c,angle:o}=s;d=h.Quaternion.fromAxisAngle(c,o)}const i=new h.TranslationRotationScale(l??void 0,d,e??void 0);return h.Matrix4.fromTranslationRotationScale(i,t??void 0)}function as(n,t,l){l??=new h.TranslationRotationScale;const s=h.Matrix4.pack(n,[]),e=[],d=[],i=[],c=t?O[t]:O.trs;return va(e,i,d,s,c),h.Cartesian3.unpack(e,0,l.translation),h.Cartesian3.unpack(d,0,l.scale),h.Quaternion.unpack(i,0,l.rotation),l}function gu(n,t){return as(n,null,t)}function hi(n,t,l){const s=h.Cartesian3.pack(n.translation,[]),e=h.Cartesian3.pack(n.scale,[]),d=h.Quaternion.pack(n.rotation,[]),i=t?O[t]:O.trs,c=Ua([],s,d,e,i);return h.Matrix4.unpack(c,0,l)}const Tu=h.Matrix4.fromTranslationRotationScale;function ri(n,t){const l=h.Matrix4.inverse(n,new h.Matrix4),s=new h.Matrix4;function e(i,c){return c=hi(i,t,c),h.Matrix4.multiply(n,c,c)}function d(i,c){return h.Matrix4.multiply(l,i,s),as(s,t,c)}return{compose:e,decompose:d,referInverse:l}}function Cu(n,t,l){const s=h.Transforms.eastNorthUpToFixedFrame(n,l??void 0);return{...ri(s,t),refer:s}}function fu(n){let t=n.boundingSphere;if(t)return t;let l=n.geometryInstances;if(l){l=Array.isArray(l)?l:[l];const e=l.map(d=>d.geometry.boundingSphere);return h.BoundingSphere.fromBoundingSpheres(e)}const s=n.positions;return s?.length>0?h.BoundingSphere.fromPoints(s):null}function Fu(n,t){t=t??new h.Cartesian3;const l=n.position;if(l)return l instanceof h.Cartesian3?l:l.getValue(h.JulianDate.now(),t);const s=n.modelMatrix;if(s)return h.Matrix4.getTranslation(s,t);const e=n.positions;return e?.length>0?h.BoundingSphere.fromPoints(e).center:null}function Nu(n,t,l){let{translation:s,rotation:e,scale:d}=Wn(t,l);const i=new h.TranslationRotationScale(s??void 0,e??void 0,d??void 0),c=h.Matrix4.fromTranslationRotationScale(i);return Zi(n,c)}function Zi(n,t){const l=n.modelMatrix;if(l)return h.Matrix4.multiply(t,l,l),n.modelMatrix=l,!0;const s=n.position;if(s){if("scale"in n){const d=h.Matrix4.getTranslation(t,new h.Cartesian3);h.Cartesian3.add(s,d,s);const i=n.scale??1,c=h.Matrix4.getScale(t,new h.Cartesian3);n.scale=h.Cartesian3.maximumComponent(c)*i}else h.Matrix4.multiplyByPoint(t,s,s);return n.position=s,!0}const e=n.positions;if(e?.length>0){for(const d of e)h.Matrix4.multiplyByPoint(t,d,d);return n.positions=e,!0}return!1}function Hu(n,t,l){const s=mi(n),e=Ks(t,{...l,defaultMatrix:s});return Gi(n,e)}function Gi(n,t){if(mn(n))return n.modelMatrix=t,!0;const l=h.Matrix4.getTranslation(t,new h.Cartesian3);if(pn(n)){if(n.position=l,"scale"in n){const e=h.Matrix4.getScale(t,new h.Cartesian3);n.scale=h.Cartesian3.maximumComponent(e)}return!0}const s=n.positions;if(s?.length>0){const e=h.BoundingSphere.fromPoints(s);h.Cartesian3.subtract(l,e.center,l);for(const d of s)h.Cartesian3.add(d,l,d);return n.positions=s,!0}return!1}function mi(n){if(mn(n))return n.modelMatrix;if(pn(n)){const l=n.position,s=n.scale??1,e=new h.TranslationRotationScale(l,void 0,new h.Cartesian3(s,s,s));return h.Matrix4.fromTranslationRotationScale(e)}const t=n.positions;if(t?.length>0){const l=h.BoundingSphere.fromPoints(t);return h.Matrix4.fromTranslation(l.center)}return null}function Ju(n,t){let{translation:l,rotation:s,scale:e}=Wn(t,t);const{reset:d,referFrame:i}=t,c=h.JulianDate.now(),o=!d;if(s){let V=s;if(o){const y=n.orientation?.getValue(c);y&&(V=h.Quaternion.multiply(s,y,y))}n.orientation=V}if(l){let V=l;if(o){const y=n.position?.getValue(c);y&&(V=h.Cartesian3.add(y,l,y))}n.position=V}if(!i)return;const{translation:X,rotation:a,scale:u}=xs(t,t),r=new h.TranslationRotationScale(X??void 0,a??void 0,u??void 0);let Z=h.Matrix4.fromTranslationRotationScale(r);if(Z=Zn(Z,i,Z),u){const V=n.box;V&&pi(V,u);const y=n.cylinder;y&&Wi(y,u);const S=n.ellipse;S&&Vi(S,u);const K=n.ellipsoid;K&&yi(K,u);const T=n.model;T&&Li(T,u,d);const Y=n.plane;Y&&xi(Y,u)}const G=n.corridor;G&&Ki(G,Z,u);const p=n.polygon;p&&Ri(p,Z,u);const m=n.polyline;m&&Si(m,Z,u);const W=n.polylineVolume;W&&zi(W,Z,u);const L=n.wall;L&&Mi(L,Z,u)}function pi(n,t){const l=h.JulianDate.now(),s=n.dimensions?.getValue(l);s&&(n.dimensions=h.Cartesian3.multiplyComponents(s,t,s))}function Wi(n,t){const l=h.JulianDate.now(),s=n.length?.getValue(l);s!=null&&(n.length=s*t.z);const e=Math.max(t.x,t.y),d=n.topRadius?.getValue(l);d!=null&&(n.topRadius=d*e);const i=t.z,c=n.bottomRadius?.getValue(l);c!=null&&(n.bottomRadius=c*i)}function Vi(n,t){const l=h.JulianDate.now(),s=Math.max(t.x,t.y),e=t.z,d=n.semiMajorAxis?.getValue(l);d!=null&&(n.semiMajorAxis=d*s);const i=n.semiMinorAxis?.getValue(l);i!=null&&(n.semiMinorAxis=i*s);const c=n.height?.getValue(l);c!=null&&(n.height=c*e);const o=n.extrudedHeight?.getValue(l);o!=null&&(n.extrudedHeight=o*e)}function yi(n,t){const l=h.JulianDate.now(),s=n.radii?.getValue(l);s!=null&&(n.radii=h.Cartesian3.multiplyComponents(s,t,s));const e=n.innerRadii?.getValue(l);e!=null&&(n.innerRadii=h.Cartesian3.multiplyComponents(e,t,e))}function Li(n,t,l){let s=h.Cartesian3.maximumComponent(t);if(!l){const e=h.JulianDate.now(),d=n.scale?.getValue(e)??1;s*=d}n.scale=s}function xi(n,t){const l=h.JulianDate.now(),s=h.Cartesian2.fromCartesian3(t),e=n.dimensions?.getValue(l);e&&(n.dimensions=h.Cartesian2.multiplyComponents(e,s,e))}function Ki(n,t,l){const s=h.JulianDate.now(),e=new h.Cartesian3,d=n.positions?.getValue(s);if(d?.length>0){for(const u of d)h.Matrix4.multiplyByPoint(t,u,u);n.dimensions=d}const i=l??h.Matrix4.getScale(t,e),c=Math.max(i.x,i.y);n.width?.getValue(s)!=null&&(n.width=c*scale);const X=n.height?.getValue(s),a=i.z;X!=null&&(n.height=X*a)}function Ri(n,t,l){const s=h.JulianDate.now(),e=new h.Cartesian3,d=n.hierarchy?.getValue(s);d&&(us(d,t),n.hierarchy=d);const c=(l??h.Matrix4.getScale(t,e)).z,o=n.height?.getValue(s);o!=null&&(n.height=o*c);const X=n.extrudedHeight?.getValue(s);X!=null&&(n.extrudedHeight=X*c)}function us(n,t){const{positions:l,holes:s}=n;for(const e of l)h.Matrix4.multiplyByPoint(t,e,e);n.positions=l;for(const e of s)us(e,t)}function Si(n,t,l){const s=h.JulianDate.now(),e=new h.Cartesian3,d=n.positions?.getValue(s);if(d?.length>0){for(const X of d)h.Matrix4.multiplyByPoint(t,X,X);n.positions=d}const i=l??h.Matrix4.getScale(t,e),c=Math.max(i.x,i.y);n.width?.getValue(s)!=null&&(n.width=c*scale)}function zi(n,t,l){const s=h.JulianDate.now(),e=new h.Cartesian3,d=n.positions?.getValue(s);if(d?.length>0){for(const X of d)h.Matrix4.multiplyByPoint(t,X,X);n.positions=d}const i=l??h.Matrix4.getScale(t,e),c=h.Cartesian2.fromCartesian3(i),o=n.shape?.getValue(s);if(o!=null){for(const X of o)h.Cartesian2.multiplyComponents(X,c,X);n.shape=o}}function Mi(n,t,l){const s=h.JulianDate.now(),e=new h.Cartesian3,d=n.positions?.getValue(s);if(d?.length>0){for(const a of d)h.Matrix4.multiplyByPoint(t,a,a);n.positions=d}const c=(l??h.Matrix4.getScale(t,e)).z,o=n.minimumHeights?.getValue(s);o!=null&&(graphicsgraphics.minimumHeights=o.map(a=>a*c));const X=n.maximumHeights?.getValue(s);X!=null&&(graphicsgraphics.maximumHeights=X.map(a=>a*c))}function Iu(n,t,l){const s=h.JulianDate.now(),e=n.position?.getValue(s);if(!e)return null;const d=n.orientation?.getValue(s),i=n.model?.scale?.getValue(s)??1,c=new h.Cartesian3(i,i,i),o=t(e,l),X=h.Matrix4.inverse(o,new h.Matrix4),a=h.Matrix4.multiplyByPoint(X,e,new h.Cartesian3),u={translation:a,position:e,scale:c,rotation:new h.Cartesian3};let r;if(d){const p=h.Matrix3.fromQuaternion(d),m=h.Matrix4.fromRotation(p),W=h.Matrix4.multiply(X,m,m),L=el(W);r=R.Xyz_Hpr.toCartesian3(L),u.rotation=r}const Z=new h.TranslationRotationScale(a??void 0,r?Et(r):void 0,c??void 0);let G=h.Matrix4.fromTranslationRotationScale(Z);return u.matrix=G,u}function ku(n){return n.values.length/n.componentsPerAttribute}function Pu(n){return h.ComponentDatatype.getSizeInBytes(n.componentDatatype)*n.componentsPerAttribute}function Qu(n){const{componentDatatype:t,vertexBuffer:l}=n,s=Ws[t];if(!s)throw new Error("不支持的数据类型");const e=l.sizeInBytes,d=h.ComponentDatatype.getSizeInBytes(t),i=e/d;let c=new s(i);return l.getBufferData(c,0,0,e),c}new h.Cartesian2,new h.Cartesian3,new h.Cartesian4;const hs=[new h.Cartesian2,new h.Cartesian2,new h.Cartesian2,new h.Cartesian2],$n=[new h.Cartesian3,new h.Cartesian3,new h.Cartesian3,new h.Cartesian3];new h.Cartesian4,new h.Cartesian4,new h.Cartesian4,new h.Cartesian4;const Bu=[new h.Cartographic,new h.Cartographic,new h.Cartographic,new h.Cartographic];new h.Rectangle,new h.Rectangle,new h.Rectangle,new h.Rectangle,new h.Matrix2,new h.Matrix2,new h.Matrix2,new h.Matrix2,new h.Matrix3,new h.Matrix3,new h.Matrix3,new h.Matrix3,new h.Matrix4,new h.Matrix4,new h.Matrix4,new h.Matrix4,new h.Quaternion,new h.Quaternion,new h.Quaternion,new h.Quaternion,new h.HeadingPitchRoll,new h.HeadingPitchRoll,new h.HeadingPitchRoll,new h.HeadingPitchRoll;function vu(n,t=[]){const{stride:l,vertexArray:s}=n,e=s.length/l,d=$n[0];for(let i=0;i<e;i++)n.encoding.decodePosition(s,i,d),h.Cartesian3.pack(d,t,t.length);return t}function wu(n,t,l){return n.encoding.decodePosition(n.vertexArray,t,l)}function Yi(n){const{stride:t,vertices:l,indices:s,encoding:e}=n,d=l.length/t,i=$n[0],c=new Float32Array(d*3),o=hs[0],X=new Float32Array(d*2),a=new Float32Array(d);for(let u=0;u<d;u++){e.decodePosition(l,u,i),h.Cartesian3.pack(i,c,u*3);const r=e.decodeHeight(l,u);a[u]=r,e.decodeTextureCoordinates(l,u,o),h.Cartesian2.pack(o,X,u*2)}return{attributes:{position:{array:c,vectorSize:3},uv:{array:X,vectorSize:2},height:{array:a,vectorSize:1}},indices:s.slice(),count:d}}function rs(n,t){const l=n._surface._tilesToRender,s=[],e=new h.Rectangle;for(const d of l){const{rectangle:i}=d;h.Rectangle.intersection(t,i,e)&&s.push(d)}return s}function Uu(n){const t=n._surface._tilesToRender;return gi(t)}function gi(n){const t=new Set;for(const d of n)t.add(d.level);const l=[...t],s=Math.min.apply(Math,l),e=Math.max.apply(Math,l);return{min:s,max:e}}function Zs(n){return n.map(t=>{const{mesh:l,terrainData:s}=t.data,e=Yi(l),{x:d,y:i,level:c}=t,o=[s._minimumHeight,s._maximumHeight];return{data:e,encoding:l.encoding,rectangle:t.rectangle,heightRange:o,x:d,y:i,level:c}})}function ju(n){const{x:t,y:l,level:s}=n;return n.data.terrainData.upsample(n.tilingScheme,t,l,s,t,l,s)}function Ti(n,t,l){const{east:s,north:e,south:d,west:i}=t,c=Bu[0];c.longitude=i,c.latitude=d;const o=n.positionToTileXY(c,l,hs[0]);c.longitude=s,c.latitude=e;const X=n.positionToTileXY(c,l,hs[1]),[a,u]=o.x<X.x?[o.x,X.x]:[X.x,o.x],[r,Z]=o.y<X.y?[o.y,X.y]:[X.y,o.y];return{min:[a,r],max:[u,Z]}}const Eu=32767;function Ou(n,t=new h.Cartesian3){return h.Matrix3.getScale(n.halfAxes,t),h.Cartesian3.multiplyByScalar(t,2*Eu,t),t}function tl(n,t,l){return l=n.getLocalCurvature(t,l),l.x=1/l.x,l.y=1/l.y,l}function Au(n,t,l){l=tl(n,t,l);const s=Math.PI/180;return h.Cartesian2.multiplyByScalar(l,s,l)}function Ci(n){const{_quantizedVertices:t,_indices:l}=n,s=t.length/3,e={type:"Float32Array",start:0,vectorSize:1},d={type:"Float32Array",start:s,vectorSize:1},i={type:"Float32Array",start:s*2,vectorSize:1};return{array:new Float32Array(t),attributes:{u:e,v:d,height:i},count:s,indices:l}}async function Du(n,t,l,s){const e=await n.requestTileGeometry(t,l,s);if(!e)return null;const d=Ci(e),i=[data._minimumHeight,data._maximumHeight],c=n.tilingScheme.tileXYToRectangle(t,l,s),o=bi(c,i),X=h.Matrix4.fromArray(o,void 0),a=["u","v","height"],u=new li({...d,positionNames:a}),r=new h.Cartesian3;return u.mapForAggregate(a,(Z,G)=>(h.Cartesian3.fromArray(Z,0,r),h.Matrix4.multiplyByPoint(X,r,r),new h.Cartographic(r.x,r.y,r.z)))}async function qu(n,t,l){const{min:s,max:e}=Ti(n.tilingScheme,t,l),d=[],i=[];for(let o=s[0];o<=e[0];o++)for(let X=s[1];X<=e[1];X++){const a=fi(n,o,X,l);a&&(d.push(a),i.push({x:o,y:X}))}return(await Promise.all(d)).map(function(o,X){const{x:a,y:u}=i[X];return{x:a,y:u,level:l,data:o}})}async function fi(n,t,l,s){return n.getTileDataAvailable(t,l,s)?(await n.loadTileDataAvailability(t,l,s),n.requestTileGeometry(t,l,s)):Promise.reject("不可用")}async function _u(n,t){const l=h.Rectangle.fromCartesianArray(t),s=h.Cartographic.toCartesian(h.Rectangle.center(l)),e=tl(n.ellipsoid,s),d=[e.x,e.y,1],i=rs(n,l),c=Zs(i),o=h.Transforms.eastNorthUpToFixedFrame(s);h.Matrix4.inverseTransformation(o,o);const X=t.map(r=>{const Z=h.Matrix4.multiplyByPoint(o,r,$n[2]);return[Z.x,Z.y]});let a=0;const u=c.map(async r=>{const{data:Z,...G}=r,{position:p,uv:m,height:W}=Z.attributes;a+=await xu.computeRelationAreaOfPolygon2Terrain({args:[{...Z,...G,positionNames:["position"],region:X,matrix:h.Matrix4.pack(o,[]),relation:x.Contain|x.Intersect,scale:d}],transfer:[p.array.buffer,m.array.buffer,W.array.buffer,Z.indices.buffer]})});if(await Promise.all(u),a===0||isNaN(a)){console.warn("贴地面积计算异常,已回退到椭球面投影面积",a);const r=t.map(Z=>h.Cartesian3.pack(Z,[]));return a=oi(r),Math.abs(a)}return a}function $u(n,t){const l=h.Rectangle.fromCartesianArray(t),s=h.Cartographic.toCartesian(h.Rectangle.center(l)),e=tl(n.ellipsoid,s),d=[e.x,e.y,1],i=rs(n,l),c=Zs(i),o=h.Transforms.eastNorthUpToFixedFrame(s);h.Matrix4.inverseTransformation(o,o);const X=t.map(u=>{const r=h.Matrix4.multiplyByPoint(o,u,$n[2]);return[r.x,r.y]});let a=0;for(const u of c){const{data:r,...Z}=u;a+=Vu({...r,...Z,positionNames:["position"],region:X,matrix:h.Matrix4.pack(o,[]),relation:x.Contain|x.Intersect,scale:d})}if(a===0||isNaN(a)){console.warn("贴地面积计算异常,已回退到椭球面投影面积",a);const u=t.map(r=>h.Cartesian3.pack(r,[]));return a=oi(u),Math.abs(a)}return a}return R.CartesianAxis=Vs,R.HeadingPitchRollComponent=ys,R.applyMatrixReferFrame=Ku,R.applyTransformInPrimitive=Zi,R.applyTransformInfoPrimitive=Nu,R.componentDatatypeTypedArrayMap=Ws,R.computeAttributeSizeInBytes=Pu,R.computeNormalOfCoplanars=Rs,R.computeTerrainAreaOfPolygon=$u,R.computeTerrainAreaOfPolygon_worker=_u,R.computeVertexNumOfAttribute=ku,R.createPlaneOfCoplanars=Bi,R.flatTransformInfoOptions=sl,R.getAttributeData=Qu,R.getBoundingSphere=fu,R.getDecodePositionsOfTerrainMesh=vu,R.getEntityInfo=Iu,R.getGeometryDataOfQuantizedMeshTerrainData=Ci,R.getGeometryDataOfTerrainMesh=Yi,R.getLevelRangeOfQuadtreeTiles=gi,R.getLocalCurvatureRadius=tl,R.getLocalSizePerDegrees=Au,R.getLocalTransformInfo=xs,R.getMatrix4OfTransformInfo=Yu,R.getNeighborPairs=vi,R.getPosition=Fu,R.getPositionOfTerrainMesh=wu,R.getRenderedQuadtreeTilesOfIntersectRectangle=rs,R.getRenderedTileLevelRange=Uu,R.getScaleOfTerrainDataByOrientedBoundingBox=Ou,R.getTerrainData=fi,R.getTerrainDataOfQuadtreeTile=ju,R.getTerrainDatasOfIntersectRectangle=qu,R.getTerrainDatasOfQuadtreeTiles=Zs,R.getTileRangeOfIntersectRectangle=Ti,R.getTransform=mi,R.getWorldDataOfQuantizedMeshTerrainData=Du,R.getWorldMatrix=Ks,R.getWorldTransformInfo=Wn,R.isMatrixPrimitive=mn,R.isPositionListPrimitive=ps,R.isPositionPrimitive=pn,R.isPrimitiveObject=Ji,R.localQuaternionToWorld=Ls,R.localTRS_WorldMatrix4_Convert=ri,R.localTRS_WorldMatrix4_ENU_Convert=Cu,R.makeMatrixReferFrame=Zn,R.mat4_compose=Tu,R.mat4_composeByOrder=hi,R.mat4_decompose=gu,R.mat4_decomposeByOrder=as,R.matrix4ToHeadingPitchRoll=el,R.quaternionToHeadingPitchRoll=Ii,R.resetTransformInPrimitive=Gi,R.resetTransformInfoPrimitive=Hu,R.rotateMatrixReferFrame=Su,R.rotationInfoToQuaternion=Et,R.scaleBoxGraphics=pi,R.scaleCylinderGraphics=Wi,R.scaleEllipseGraphics=Vi,R.scaleEllipsoidGraphics=yi,R.scaleMatrixReferFrame=zu,R.scaleModelGraphics=Li,R.scalePlaneGraphics=xi,R.scalePoints=Mu,R.transformCorridorGraphics=Ki,R.transformEntity=Ju,R.transformInfoToMatrix=Qi,R.transformPolygonGraphics=Ri,R.transformPolygonHierarchy=us,R.transformPolylineGraphics=Si,R.transformPolylineVolumeGraphics=zi,R.transformWallGraphics=Mi,R.translationMatrixReferFrame=Ru,R.worldMatrixToLocal=ki,R.worldQuaternionToLocal=Pi,Object.defineProperty(R,Symbol.toStringTag,{value:"Module"}),R}({},cesium);
|