@cearth/tools 2.1.0 → 2.3.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 +60 -1
- package/dist/math/transform.d.ts.map +1 -1
- package/dist/primitive/VertexArray.d.ts.map +1 -1
- package/dist/tools.iife.js +24 -24
- package/dist/tools.js +548 -537
- 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(S,h){"use strict";var jn=typeof document<"u"?document.currentScript:null;function ri(n){return an(n)||un(n)||ls(n)}function an(n){return"modelMatrix"in n}function un(n){return"position"in n}function ls(n){return"positions"in n}const ss={[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 es=(n=>(n[n.x=0]="x",n[n.y=1]="y",n[n.z=2]="z",n))(es||{});S.Xyz_Hpr=(n=>(n.x="roll",n.y="pitch",n.z="heading",n))(S.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})(S.Xyz_Hpr||(S.Xyz_Hpr={}));var ds=(n=>(n[n.heading=0]="heading",n[n.pitch=1]="pitch",n[n.roll=2]="roll",n))(ds||{});function En(n){const t=n==null?void 0: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 Bt(n){if(n.axis){const{axis:l,angle:s}=n;return h.Quaternion.fromAxisAngle(l,s)}const t=S.Xyz_Hpr.toHeadingPitchRoll(n);return h.Quaternion.fromHeadingPitchRoll(t)}function hi(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 On(i)}function On(n,t){const l=h.Matrix4.getMatrix3(n,new h.Matrix3),s=h.Quaternion.fromRotationMatrix(l);return h.HeadingPitchRoll.fromQuaternion(s,t)}function mi(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 is(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 Zi(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 Xn(n,t){let{translation:l,rotation:s,scale:e}=n;const{referFrame:d,worldTranslation:i,worldRotation:c,worldScale:o}=En(t);let a=null;return l&&(i||(l=h.Matrix4.multiplyByPointAsVector(d,l,new h.Cartesian3))),s&&(a=Bt(s),c||(a=is(a,d))),e&&(o||(e=h.Matrix4.multiplyByPointAsVector(d,e,new h.Cartesian3))),{translation:l,rotation:a,scale:e}}function cs(n,t){let{translation:l,rotation:s,scale:e}=n;const{referFrame:d,worldTranslation:i,worldRotation:c,worldScale:o}=En(t),a=d?h.Matrix4.inverse(d,new h.Matrix4):null;let u=null;if(l&&i&&(l=h.Matrix4.multiplyByPointAsVector(a,l,new h.Cartesian3)),s&&(u=Bt(s),c)){let X=h.Quaternion.computeAxis(u,new h.Cartesian3);if(!X.equals(h.Cartesian3.ZERO)){const r=h.Quaternion.computeAngle(u);X=h.Matrix4.multiplyByPointAsVector(a,X,X),u=h.Quaternion.fromAxisAngle(X,r)}}return e&&o&&(e=h.Matrix4.multiplyByPointAsVector(a,e,new h.Cartesian3)),{translation:l,rotation:u,scale:e}}function bs(n,t){const l=t==null?void 0:t.defaultMatrix;let{translation:s,rotation:e,scale:d}=Xn(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 Gi(n){const{translation:t,rotation:l,scale:s}=n,e=l?Bt(l):void 0,d=new h.TranslationRotationScale(t??void 0,e,s??void 0);return h.Matrix4.fromTranslationRotationScale(d)}function os(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 Wi(n,t,l){const s=os(n,t,l);return h.Plane.fromPointNormal(s,n)}function*pi(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 a=(c+1)%e,u=n[a],X=c;for(;i.call(o,u,l,s);){if(a=(++X+1)%e,a===c)return;u=n[a]}c=X,yield[o,u]}}function vt(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 Vi(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 yi(n,t,l){const s=h.Matrix4.fromTranslation(n);return vt(s,t,l)}function Li(n,t,l,s){const e=h.Quaternion.fromAxisAngle(n,t),d=h.Matrix3.fromQuaternion(e),i=h.Matrix4.fromRotation(d);return vt(i,l,s)}function xi(n,t,l){const s=h.Matrix4.fromScale(n);return vt(s,t,l)}function Ri(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 Ki(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 Si(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==null?void 0:s.length)>0?h.BoundingSphere.fromPoints(s):null}function zi(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==null?void 0:e.length)>0?h.BoundingSphere.fromPoints(e).center:null}function Yi(n,t,l){let{translation:s,rotation:e,scale:d}=Xn(t,l);const i=new h.TranslationRotationScale(s??void 0,e??void 0,d??void 0),c=h.Matrix4.fromTranslationRotationScale(i);return as(n,c)}function as(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==null?void 0:e.length)>0){for(const d of e)h.Matrix4.multiplyByPoint(t,d,d);return n.positions=e,!0}return!1}function Mi(n,t,l){const s=Xs(n),e=bs(t,{...l,defaultMatrix:s});return us(n,e)}function us(n,t){if(an(n))return n.modelMatrix=t,!0;const l=h.Matrix4.getTranslation(t,new h.Cartesian3);if(un(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==null?void 0: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 Xs(n){if(an(n))return n.modelMatrix;if(un(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==null?void 0:t.length)>0){const l=h.BoundingSphere.fromPoints(t);return h.Matrix4.fromTranslation(l.center)}return null}function gi(n,t){var V,y;let{translation:l,rotation:s,scale:e}=Xn(t,t);const{reset:d,referFrame:i}=t,c=h.JulianDate.now(),o=!d;if(s){let R=s;if(o){const x=(V=n.orientation)==null?void 0:V.getValue(c);x&&(R=h.Quaternion.multiply(s,x,x))}n.orientation=R}if(l){let R=l;if(o){const x=(y=n.position)==null?void 0:y.getValue(c);x&&(R=h.Cartesian3.add(x,l,x))}n.position=R}if(!i)return;const{translation:a,rotation:u,scale:X}=cs(t,t),r=new h.TranslationRotationScale(a??void 0,u??void 0,X??void 0);let m=h.Matrix4.fromTranslationRotationScale(r);if(m=vt(m,i,m),X){const R=n.box;R&&rs(R,X);const x=n.cylinder;x&&hs(x,X);const f=n.ellipse;f&&ms(f,X);const M=n.ellipsoid;M&&Zs(M,X);const g=n.model;g&&Gs(g,X,d);const z=n.plane;z&&Ws(z,X)}const Z=n.corridor;Z&&ps(Z,m,X);const W=n.polygon;W&&Vs(W,m,X);const G=n.polyline;G&&ys(G,m,X);const p=n.polylineVolume;p&&Ls(p,m,X);const L=n.wall;L&&xs(L,m,X)}function rs(n,t){var e;const l=h.JulianDate.now(),s=(e=n.dimensions)==null?void 0:e.getValue(l);s&&(n.dimensions=h.Cartesian3.multiplyComponents(s,t,s))}function hs(n,t){var o,a,u;const l=h.JulianDate.now(),s=(o=n.length)==null?void 0:o.getValue(l);s!=null&&(n.length=s*t.z);const e=Math.max(t.x,t.y),d=(a=n.topRadius)==null?void 0:a.getValue(l);d!=null&&(n.topRadius=d*e);const i=t.z,c=(u=n.bottomRadius)==null?void 0:u.getValue(l);c!=null&&(n.bottomRadius=c*i)}function ms(n,t){var a,u,X,r;const l=h.JulianDate.now(),s=Math.max(t.x,t.y),e=t.z,d=(a=n.semiMajorAxis)==null?void 0:a.getValue(l);d!=null&&(n.semiMajorAxis=d*s);const i=(u=n.semiMinorAxis)==null?void 0:u.getValue(l);i!=null&&(n.semiMinorAxis=i*s);const c=(X=n.height)==null?void 0:X.getValue(l);c!=null&&(n.height=c*e);const o=(r=n.extrudedHeight)==null?void 0:r.getValue(l);o!=null&&(n.extrudedHeight=o*e)}function Zs(n,t){var d,i;const l=h.JulianDate.now(),s=(d=n.radii)==null?void 0:d.getValue(l);s!=null&&(n.radii=h.Cartesian3.multiplyComponents(s,t,s));const e=(i=n.innerRadii)==null?void 0:i.getValue(l);e!=null&&(n.innerRadii=h.Cartesian3.multiplyComponents(e,t,e))}function Gs(n,t,l){var e;let s=h.Cartesian3.maximumComponent(t);if(!l){const d=h.JulianDate.now(),i=((e=n.scale)==null?void 0:e.getValue(d))??1;s*=i}n.scale=s}function Ws(n,t){var d;const l=h.JulianDate.now(),s=h.Cartesian2.fromCartesian3(t),e=(d=n.dimensions)==null?void 0:d.getValue(l);e&&(n.dimensions=h.Cartesian2.multiplyComponents(e,s,e))}function ps(n,t,l){var X,r,m;const s=h.JulianDate.now(),e=new h.Cartesian3,d=(X=n.positions)==null?void 0:X.getValue(s);if((d==null?void 0:d.length)>0){for(const Z of d)h.Matrix4.multiplyByPoint(t,Z,Z);n.dimensions=d}const i=l??h.Matrix4.getScale(t,e),c=Math.max(i.x,i.y);((r=n.width)==null?void 0:r.getValue(s))!=null&&(n.width=c*scale);const a=(m=n.height)==null?void 0:m.getValue(s),u=i.z;a!=null&&(n.height=a*u)}function Vs(n,t,l){var u,X,r;const s=h.JulianDate.now(),e=new h.Cartesian3,d=(u=n.hierarchy)==null?void 0:u.getValue(s);d&&(An(d,t),n.hierarchy=d);const c=(l??h.Matrix4.getScale(t,e)).z,o=(X=n.height)==null?void 0:X.getValue(s);o!=null&&(n.height=o*c);const a=(r=n.extrudedHeight)==null?void 0:r.getValue(s);a!=null&&(n.extrudedHeight=a*c)}function An(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)An(e,t)}function ys(n,t,l){var a,u;const s=h.JulianDate.now(),e=new h.Cartesian3,d=(a=n.positions)==null?void 0:a.getValue(s);if((d==null?void 0: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);((u=n.width)==null?void 0:u.getValue(s))!=null&&(n.width=c*scale)}function Ls(n,t,l){var a,u;const s=h.JulianDate.now(),e=new h.Cartesian3,d=(a=n.positions)==null?void 0:a.getValue(s);if((d==null?void 0: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=(u=n.shape)==null?void 0:u.getValue(s);if(o!=null){for(const X of o)h.Cartesian2.multiplyComponents(X,c,X);n.shape=o}}function xs(n,t,l){var u,X,r;const s=h.JulianDate.now(),e=new h.Cartesian3,d=(u=n.positions)==null?void 0:u.getValue(s);if((d==null?void 0:d.length)>0){for(const m of d)h.Matrix4.multiplyByPoint(t,m,m);n.positions=d}const c=(l??h.Matrix4.getScale(t,e)).z,o=(X=n.minimumHeights)==null?void 0:X.getValue(s);o!=null&&(graphicsgraphics.minimumHeights=o.map(m=>m*c));const a=(r=n.maximumHeights)==null?void 0:r.getValue(s);a!=null&&(graphicsgraphics.maximumHeights=a.map(m=>m*c))}function fi(n,t,l){var W,G,p,L;const s=h.JulianDate.now(),e=(W=n.position)==null?void 0:W.getValue(s);if(!e)return null;const d=(G=n.orientation)==null?void 0:G.getValue(s),i=((L=(p=n.model)==null?void 0:p.scale)==null?void 0:L.getValue(s))??1,c=new h.Cartesian3(i,i,i),o=t(e,l),a=h.Matrix4.inverse(o,new h.Matrix4),u=h.Matrix4.multiplyByPoint(a,e,new h.Cartesian3),X={translation:u,position:e,scale:c,rotation:new h.Cartesian3};let r;if(d){const V=h.Matrix3.fromQuaternion(d),y=h.Matrix4.fromRotation(V),R=h.Matrix4.multiply(a,y,y),x=On(R);r=S.Xyz_Hpr.toCartesian3(x),X.rotation=r}const m=new h.TranslationRotationScale(u??void 0,r?Bt(r):void 0,c??void 0);let Z=h.Matrix4.fromTranslationRotationScale(m);return X.matrix=Z,X}function Ti(n){return n.values.length/n.componentsPerAttribute}function Ci(n){return h.ComponentDatatype.getSizeInBytes(n.componentDatatype)*n.componentsPerAttribute}function Fi(n){const{componentDatatype:t,vertexBuffer:l}=n,s=ss[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 Dn=[new h.Cartesian2,new h.Cartesian2,new h.Cartesian2,new h.Cartesian2],rn=[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 Ni=[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 Ji(n,t=[]){const{stride:l,vertexArray:s}=n,e=s.length/l,d=rn[0];for(let i=0;i<e;i++)n.encoding.decodePosition(s,i,d),h.Cartesian3.pack(d,t,t.length);return t}function Hi(n,t,l){return n.encoding.decodePosition(n.vertexArray,t,l)}function Rs(n){const{stride:t,vertices:l,indices:s,encoding:e}=n,d=l.length/t,i=rn[0],c=new Float32Array(d*3),o=Dn[0],a=new Float32Array(d*2),u=new Float32Array(d);for(let X=0;X<d;X++){e.decodePosition(l,X,i),h.Cartesian3.pack(i,c,X*3);const r=e.decodeHeight(l,X);u[X]=r,e.decodeTextureCoordinates(l,X,o),h.Cartesian2.pack(o,a,X*2)}return{attributes:{position:{array:c,vectorSize:3},uv:{array:a,vectorSize:2},height:{array:u,vectorSize:1}},indices:s.slice(),count:d}}function _n(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 Ii(n){const t=n._surface._tilesToRender;return Ks(t)}function Ks(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 qn(n){return n.map(t=>{const{mesh:l,terrainData:s}=t.data,e=Rs(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 ki(n){const{x:t,y:l,level:s}=n;return n.data.terrainData.upsample(n.tilingScheme,t,l,s,t,l,s)}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 Pi(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 Qi(n){let t=zs(n);return Pi(t)}function Bi(n){return n==null||Ss(n)?zs(n):typeof n}var wt=(n=>(n.equal="equal",n.intersect="intersect",n.intersectEqual="intersectEqual",n))(wt||{});(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})(wt||(wt={}));const vi=[globalThis.Worker,globalThis.SharedWorker,globalThis.ServiceWorker].filter(n=>n),wi=["Worker","SharedWorker","ServiceWorker"];function Ui(n){if(vi.some(l=>n instanceof l))return!0;const t=Qi(n);return wi.includes(t)}var $n=(n=>(n.Ing="进行中",n.End="结束",n))($n||{}),ji=Object.defineProperty,Ei=(n,t,l)=>t in n?ji(n,t,{enumerable:!0,configurable:!0,writable:!0,value:l}):n[t]=l,hn=(n,t,l)=>Ei(n,typeof t!="symbol"?t+"":t,l);const Ys=`(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
|
-
`,
|
|
3
|
-
`),l=`function(${
|
|
4
|
-
`),l=`function(${
|
|
5
|
-
`}),
|
|
6
|
-
`:y}),G=o.map(function(y){return`${
|
|
7
|
-
`}),
|
|
8
|
-
`);const V=
|
|
9
|
-
`),[`${
|
|
10
|
-
`,...Z,...W,...G,...p]}function tc(n,t){const l=n?$i(n):[];return t||l.unshift(Ys,Oi),qi(l)}function Ts(n){return n&&Array.isArray(n.args)&&Array.isArray(n.transfer)}const Cs=class ai{constructor(t){if(hn(this,"id",++ai.instanceCount),hn(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",u=>{const X=u.data,{execId:r,state:m,error:Z,data:W}=X;if(t!==r)return;if(d){if(m===$n.End){s.abort(),Z&&d.error(Z),W!==void 0&&d.enqueue(W),d.close(),this.execEnded(l);return}if(Z){d.error(Z);return}d.enqueue(W);return}if(Z){o(Z),s.abort();return}if(m===$n.End){s.abort(),c(W),this.execEnded(l);return}const G=new ReadableStream({start:p=>{d=p,Z&&d.error(Z),d.enqueue(W)}});c(G)},{signal:e});const a=u=>{if(s.abort(),d){d.error(u),d.close(),this.execEnded(l);return}o(u)};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&&Ts(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}})}};hn(Cs,"instanceCount",0);let nc=Cs;function lc(n){const{url:t,name:l}=n;return new Worker(t,{name:l})}class sc extends nc{constructor(t,l){super(t==null?void 0:t.named),hn(this,"worker");const{id:s}=this;let e=(typeof l=="string"?l:l==null?void 0:l.name)||`DynamicWorker/${s}`,d=t;if(!Ui(t)){const i=typeof t=="string",{getWorker:c,noDep:o}=l||{},a=i?t:tc(t,o);d=(c||lc)({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 ec(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&&Ts(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 dc(n,t){const l=new sc(n,t);return ec(l)}const ic=1/Math.PI*180,cc=1/180*Math.PI,bc={EPSILON:1e-12,debug:!1,precision:4,printTypes:!1,printDegrees:!1,printRowMajor:!0,_cartographicRadians:!1};globalThis.mathgl=globalThis.mathgl||{config:{...bc}};const w=globalThis.mathgl.config;function oc(n,{precision:t=w.precision}={}){return n=hc(n),`${parseFloat(n.toPrecision(t))}`}function ht(n){return Array.isArray(n)||ArrayBuffer.isView(n)&&!(n instanceof DataView)}function ac(n){return Xc(n)}function uc(n){return rc(n)}function Xc(n,t){return nl(n,l=>l*cc,t)}function rc(n,t){return nl(n,l=>l*ic,t)}function xt(n,t,l){return nl(n,s=>Math.max(t,Math.min(l,s)))}function O(n,t,l){const s=w.EPSILON;l&&(w.EPSILON=l);try{if(n===t)return!0;if(ht(n)&&ht(t)){if(n.length!==t.length)return!1;for(let e=0;e<n.length;++e)if(!O(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 hc(n){return Math.round(n/w.EPSILON)*w.EPSILON}function mc(n){return n.clone?n.clone():new Array(n.length)}function nl(n,t,l){if(ht(n)){const s=n;l=l||mc(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 Zn 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:ht(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?", ":"")+oc(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(!O(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 Zc(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 Ut(n,t,l=""){if(w.debug&&!Zc(n,t))throw new Error(`math.gl: ${l} some fields set to invalid numbers'`);return n}function ct(n,t){if(!n)throw new Error(`math.gl assertion ${t}`)}let ll=class extends Zn{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 ct(t>=0&&t<this.ELEMENTS,"index is out of range"),C(this[t])}setComponent(t,l){return ct(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 mt=Math.random;function dt(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 Gc(n){const t=new B(2);return t[0]=n[0],t[1]=n[1],t}function Wc(n,t){const l=new B(2);return l[0]=n,l[1]=t,l}function pc(n,t){return n[0]=t[0],n[1]=t[1],n}function Vc(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 q(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 Hs(n,t,l){return n[0]=t[0]/l[0],n[1]=t[1]/l[1],n}function yc(n,t){return n[0]=Math.ceil(t[0]),n[1]=Math.ceil(t[1]),n}function Lc(n,t){return n[0]=Math.floor(t[0]),n[1]=Math.floor(t[1]),n}function xc(n,t,l){return n[0]=Math.min(t[0],l[0]),n[1]=Math.min(t[1],l[1]),n}function Rc(n,t,l){return n[0]=Math.max(t[0],l[0]),n[1]=Math.max(t[1],l[1]),n}function Kc(n,t){return n[0]=dt(t[0]),n[1]=dt(t[1]),n}function Sc(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 zc(n,t){return n[0]=-t[0],n[1]=-t[1],n}function Yc(n,t){return n[0]=1/t[0],n[1]=1/t[1],n}function Mc(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 gc(n,t){return n[0]*t[0]+n[1]*t[1]}function Rt(n,t,l){const s=t[0]*l[1]-t[1]*l[0];return n[0]=n[1]=0,n[2]=s,n}function fc(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 Tc(n,t){t=t===void 0?1:t;const l=mt()*2*Math.PI;return n[0]=Math.cos(l)*t,n[1]=Math.sin(l)*t,n}function vs(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 ws(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 sl(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 el(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 Cc(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 Fc(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 Nc(n){return n[0]=0,n[1]=0,n}function Jc(n){return`vec2(${n[0]}, ${n[1]})`}function Hc(n,t){return n[0]===t[0]&&n[1]===t[1]}function dl(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 Ic=Qs,kc=q,Pc=Js,Qc=Hs,Bc=ks,vc=Ps,wc=Bs,Uc=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}}(),jc=Object.freeze(Object.defineProperty({__proto__:null,add:Ns,angle:Fc,ceil:yc,clone:Gc,copy:pc,create:Fs,cross:Rt,dist:Bc,distance:ks,div:Qc,divide:Hs,dot:gc,equals:dl,exactEquals:Hc,floor:Lc,forEach:Uc,fromValues:Wc,inverse:Yc,len:Ic,length:Qs,lerp:fc,max:Rc,min:xc,mul:Pc,multiply:Js,negate:zc,normalize:Mc,random:Tc,rotate:Cc,round:Kc,scale:Sc,scaleAndAdd:Is,set:Vc,sqrDist:vc,sqrLen:wc,squaredDistance:Ps,squaredLength:Bs,str:Jc,sub:kc,subtract:q,transformMat2:vs,transformMat2d:ws,transformMat3:sl,transformMat4:el,zero:Nc},Symbol.toStringTag,{value:"Module"}));function Us(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 js(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 Ec(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 Oc(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 Es(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 it extends ll{constructor(t=0,l=0){super(2),ht(t)&&arguments.length===1?this.copy(t):(w.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 w.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 el(this,this,t),this.check()}transformAsVector(t){return Us(this,this,t),this.check()}transformByMatrix3(t){return sl(this,this,t),this.check()}transformByMatrix2x3(t){return ws(this,this,t),this.check()}transformByMatrix2(t){return vs(this,this,t),this.check()}}function il(){const n=new B(3);return B!=Float32Array&&(n[0]=0,n[1]=0,n[2]=0),n}function Ac(n){const t=new B(3);return t[0]=n[0],t[1]=n[1],t[2]=n[2],t}function Gn(n){const t=n[0],l=n[1],s=n[2];return Math.sqrt(t*t+l*l+s*s)}function cl(n,t,l){const s=new B(3);return s[0]=n,s[1]=t,s[2]=l,s}function Dc(n,t){return n[0]=t[0],n[1]=t[1],n[2]=t[2],n}function _c(n,t,l,s){return n[0]=t,n[1]=l,n[2]=s,n}function qc(n,t,l){return n[0]=t[0]+l[0],n[1]=t[1]+l[1],n[2]=t[2]+l[2],n}function bl(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 As(n,t,l){return n[0]=t[0]/l[0],n[1]=t[1]/l[1],n[2]=t[2]/l[2],n}function $c(n,t){return n[0]=Math.ceil(t[0]),n[1]=Math.ceil(t[1]),n[2]=Math.ceil(t[2]),n}function t0(n,t){return n[0]=Math.floor(t[0]),n[1]=Math.floor(t[1]),n[2]=Math.floor(t[2]),n}function n0(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 l0(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 s0(n,t){return n[0]=dt(t[0]),n[1]=dt(t[1]),n[2]=dt(t[2]),n}function Ds(n,t,l){return n[0]=t[0]*l,n[1]=t[1]*l,n[2]=t[2]*l,n}function e0(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 _s(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 d0(n,t){return n[0]=-t[0],n[1]=-t[1],n[2]=-t[2],n}function i0(n,t){return n[0]=1/t[0],n[1]=1/t[1],n[2]=1/t[2],n}function te(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 jt(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function Kt(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 c0(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 b0(n,t,l,s){const e=Math.acos(Math.min(Math.max(jt(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 o0(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),u=i*(3-2*d);return n[0]=t[0]*c+l[0]*o+s[0]*a+e[0]*u,n[1]=t[1]*c+l[1]*o+s[1]*a+e[1]*u,n[2]=t[2]*c+l[2]*o+s[2]*a+e[2]*u,n}function a0(n,t,l,s,e,d){const i=1-d,c=i*i,o=d*d,a=c*i,u=3*d*c,X=3*o*i,r=o*d;return n[0]=t[0]*a+l[0]*u+s[0]*X+e[0]*r,n[1]=t[1]*a+l[1]*u+s[1]*X+e[1]*r,n[2]=t[2]*a+l[2]*u+s[2]*X+e[2]*r,n}function u0(n,t){t=t===void 0?1:t;const l=mt()*2*Math.PI,s=mt()*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 Wn(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 ol(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 al(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 u=e*a-d*o,X=d*c-s*a,r=s*o-e*c,m=e*r-d*X,Z=d*u-s*r,W=s*X-e*u;const G=i*2;return u*=G,X*=G,r*=G,m*=2,Z*=2,W*=2,n[0]=c+u+m,n[1]=o+X+Z,n[2]=a+r+W,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[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 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[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 se(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 ee(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&&jt(n,t)/o;return Math.acos(Math.min(Math.max(a,-1),1))}function X0(n){return n[0]=0,n[1]=0,n[2]=0,n}function r0(n){return`vec3(${n[0]}, ${n[1]}, ${n[2]})`}function h0(n,t){return n[0]===t[0]&&n[1]===t[1]&&n[2]===t[2]}function m0(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 Z0=bl,G0=Os,W0=As,p0=_s,V0=qs,de=Gn,y0=$s,L0=function(){const n=il();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}}(),x0=Object.freeze(Object.defineProperty({__proto__:null,add:qc,angle:ee,bezier:a0,ceil:$c,clone:Ac,copy:Dc,create:il,cross:Kt,dist:p0,distance:_s,div:W0,divide:As,dot:jt,equals:m0,exactEquals:h0,floor:t0,forEach:L0,fromValues:cl,hermite:o0,inverse:i0,len:de,length:Gn,lerp:c0,max:l0,min:n0,mul:G0,multiply:Os,negate:d0,normalize:te,random:u0,rotateX:ne,rotateY:le,rotateZ:se,round:s0,scale:Ds,scaleAndAdd:e0,set:_c,slerp:b0,sqrDist:V0,sqrLen:y0,squaredDistance:qs,squaredLength:$s,str:r0,sub:Z0,subtract:bl,transformMat3:ol,transformMat4:Wn,transformQuat:al,zero:X0},Symbol.toStringTag,{value:"Module"})),ul=[0,0,0];let pn;class N extends ll{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&&ht(t)?this.copy(t):(w.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 w.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 ee(this,t)}cross(t){return Kt(this,this,t),this.check()}rotateX({radians:t,origin:l=ul}){return ne(this,this,l,t),this.check()}rotateY({radians:t,origin:l=ul}){return le(this,this,l,t),this.check()}rotateZ({radians:t,origin:l=ul}){return se(this,this,l,t),this.check()}transform(t){return this.transformAsPoint(t)}transformAsPoint(t){return Wn(this,this,t),this.check()}transformAsVector(t){return js(this,this,t),this.check()}transformByMatrix3(t){return ol(this,this,t),this.check()}transformByMatrix2(t){return Ec(this,this,t),this.check()}transformByQuaternion(t){return al(this,this,t),this.check()}}let Vn;class bt extends ll{static get ZERO(){return Vn||(Vn=new bt(0,0,0,0),Object.freeze(Vn)),Vn}constructor(t=0,l=0,s=0,e=0){super(-0,-0,-0,-0),ht(t)&&arguments.length===1?this.copy(t):(w.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 w.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 Wn(this,this,t),this.check()}transformByMatrix3(t){return Es(this,this,t),this.check()}transformByMatrix2(t){return Oc(this,this,t),this.check()}transformByQuaternion(t){return al(this,this,t),this.check()}applyMatrix4(t){return t.transform(this,this),this}}let ie=class extends Zn{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]=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 ce(){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 R0(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 K0(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 S0(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 z0(n,t,l,s,e,d,i,c,o){const a=new B(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 Y0(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 M0(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 Xl(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 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],u=t[8],X=u*i-c*a,r=-u*d+c*o,m=a*d-i*o;let Z=l*X+s*r+e*m;return Z?(Z=1/Z,n[0]=X*Z,n[1]=(-u*s+e*a)*Z,n[2]=(c*s-e*i)*Z,n[3]=r*Z,n[4]=(u*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 g0(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],u=t[8];return n[0]=i*u-c*a,n[1]=e*a-s*u,n[2]=s*c-e*i,n[3]=c*o-d*u,n[4]=l*u-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 hl(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 yn(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],u=t[7],X=t[8],r=l[0],m=l[1],Z=l[2],W=l[3],G=l[4],p=l[5],L=l[6],V=l[7],y=l[8];return n[0]=r*s+m*i+Z*a,n[1]=r*e+m*c+Z*u,n[2]=r*d+m*o+Z*X,n[3]=W*s+G*i+p*a,n[4]=W*e+G*c+p*u,n[5]=W*d+G*o+p*X,n[6]=L*s+V*i+y*a,n[7]=L*e+V*c+y*u,n[8]=L*d+V*o+y*X,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],a=t[6],u=t[7],X=t[8],r=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]=r*s+m*i+a,n[7]=r*e+m*c+u,n[8]=r*d+m*o+X,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],a=t[6],u=t[7],X=t[8],r=Math.sin(l),m=Math.cos(l);return n[0]=m*s+r*i,n[1]=m*e+r*c,n[2]=m*d+r*o,n[3]=m*i-r*s,n[4]=m*c-r*e,n[5]=m*o-r*d,n[6]=a,n[7]=u,n[8]=X,n}function ml(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 f0(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 T0(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 C0(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 F0(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 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,u=s*i,X=s*c,r=e*i,m=e*c,Z=e*o,W=d*i,G=d*c,p=d*o;return n[0]=1-X-Z,n[3]=u-p,n[6]=r+G,n[1]=u+p,n[4]=1-a-Z,n[7]=m-W,n[2]=r-G,n[5]=m+W,n[8]=1-a-X,n}function Zl(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],u=t[8],X=t[9],r=t[10],m=t[11],Z=t[12],W=t[13],G=t[14],p=t[15],L=l*c-s*i,V=l*o-e*i,y=l*a-d*i,R=s*o-e*c,x=s*a-d*c,f=e*a-d*o,M=u*W-X*Z,g=u*G-r*Z,z=u*p-m*Z,J=X*G-r*W,H=X*p-m*W,I=r*p-m*G;let T=L*I-V*H+y*J+R*z-x*g+f*M;return T?(T=1/T,n[0]=(c*I-o*H+a*J)*T,n[1]=(o*z-i*I-a*g)*T,n[2]=(i*H-c*z+a*M)*T,n[3]=(e*H-s*I-d*J)*T,n[4]=(l*I-e*z+d*g)*T,n[5]=(s*z-l*H-d*M)*T,n[6]=(W*f-G*x+p*R)*T,n[7]=(G*y-Z*f-p*V)*T,n[8]=(Z*x-W*y+p*L)*T,n):null}function N0(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 H0(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 I0(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 ue(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 k0(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 P0(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 Q0(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 B0(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],u=n[8],X=t[0],r=t[1],m=t[2],Z=t[3],W=t[4],G=t[5],p=t[6],L=t[7],V=t[8];return Math.abs(l-X)<=F*Math.max(1,Math.abs(l),Math.abs(X))&&Math.abs(s-r)<=F*Math.max(1,Math.abs(s),Math.abs(r))&&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-W)<=F*Math.max(1,Math.abs(i),Math.abs(W))&&Math.abs(c-G)<=F*Math.max(1,Math.abs(c),Math.abs(G))&&Math.abs(o-p)<=F*Math.max(1,Math.abs(o),Math.abs(p))&&Math.abs(a-L)<=F*Math.max(1,Math.abs(a),Math.abs(L))&&Math.abs(u-V)<=F*Math.max(1,Math.abs(u),Math.abs(V))}const v0=Object.freeze(Object.defineProperty({__proto__:null,add:I0,adjoint:g0,clone:K0,copy:S0,create:ce,determinant:hl,equals:B0,exactEquals:Q0,frob:H0,fromMat2d:F0,fromMat4:R0,fromQuat:ae,fromRotation:T0,fromScaling:C0,fromTranslation:f0,fromValues:z0,identity:M0,invert:rl,mul:yn,multiply:yn,multiplyScalar:k0,multiplyScalarAndAdd:P0,normalFromMat4:Zl,projection:N0,rotate:oe,scale:ml,set:Y0,str:J0,sub:ue,subtract:ue,translate:be,transpose:Xl},Symbol.toStringTag,{value:"Module"}));var Gl;(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"})(Gl||(Gl={}));const w0=Object.freeze([1,0,0,0,1,0,0,0,1]);class St extends ie{static get IDENTITY(){return j0()}static get ZERO(){return U0()}get ELEMENTS(){return 9}get RANK(){return 3}get INDICES(){return Gl}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(w0)}fromObject(t){return this.check()}fromQuaternion(t){return ae(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 hl(this)}transpose(){return Xl(this,this),this.check()}invert(){return rl(this,this),this.check()}multiplyLeft(t){return yn(this,t,this),this.check()}multiplyRight(t){return yn(this,this,t),this.check()}rotate(t){return oe(this,this,t),this.check()}scale(t){return Array.isArray(t)?ml(this,this,t):ml(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=sl(l||[-0,-0],t,this);break;case 3:s=ol(l||[-0,-0,-0],t,this);break;case 4:s=Es(l||[-0,-0,-0,-0],t,this);break;default:throw new Error("Illegal vector")}return Ut(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 Ln,xn=null;function U0(){return Ln||(Ln=new St([0,0,0,0,0,0,0,0,0]),Object.freeze(Ln)),Ln}function j0(){return xn||(xn=new St,Object.freeze(xn)),xn}function E0(){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 O0(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 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[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 D0(n,t,l,s,e,d,i,c,o,a,u,X,r,m,Z,W){const G=new B(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]=u,G[11]=X,G[12]=r,G[13]=m,G[14]=Z,G[15]=W,G}function _0(n,t,l,s,e,d,i,c,o,a,u,X,r,m,Z,W,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]=u,n[10]=X,n[11]=r,n[12]=m,n[13]=Z,n[14]=W,n[15]=G,n}function Xe(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 re(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],a=t[7],u=t[8],X=t[9],r=t[10],m=t[11],Z=t[12],W=t[13],G=t[14],p=t[15],L=l*c-s*i,V=l*o-e*i,y=l*a-d*i,R=s*o-e*c,x=s*a-d*c,f=e*a-d*o,M=u*W-X*Z,g=u*G-r*Z,z=u*p-m*Z,J=X*G-r*W,H=X*p-m*W,I=r*p-m*G;let T=L*I-V*H+y*J+R*z-x*g+f*M;return T?(T=1/T,n[0]=(c*I-o*H+a*J)*T,n[1]=(e*H-s*I-d*J)*T,n[2]=(W*f-G*x+p*R)*T,n[3]=(r*x-X*f-m*R)*T,n[4]=(o*z-i*I-a*g)*T,n[5]=(l*I-e*z+d*g)*T,n[6]=(G*y-Z*f-p*V)*T,n[7]=(u*f-r*y+m*V)*T,n[8]=(i*H-c*z+a*M)*T,n[9]=(s*z-l*H-d*M)*T,n[10]=(Z*x-W*y+p*L)*T,n[11]=(X*y-u*x-m*L)*T,n[12]=(c*g-i*J-o*M)*T,n[13]=(l*J-s*g+e*M)*T,n[14]=(W*V-Z*R-G*L)*T,n[15]=(u*R-X*V+r*L)*T,n):null}function q0(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],u=t[8],X=t[9],r=t[10],m=t[11],Z=t[12],W=t[13],G=t[14],p=t[15],L=l*c-s*i,V=l*o-e*i,y=l*a-d*i,R=s*o-e*c,x=s*a-d*c,f=e*a-d*o,M=u*W-X*Z,g=u*G-r*Z,z=u*p-m*Z,J=X*G-r*W,H=X*p-m*W,I=r*p-m*G;return n[0]=c*I-o*H+a*J,n[1]=e*H-s*I-d*J,n[2]=W*f-G*x+p*R,n[3]=r*x-X*f-m*R,n[4]=o*z-i*I-a*g,n[5]=l*I-e*z+d*g,n[6]=G*y-Z*f-p*V,n[7]=u*f-r*y+m*V,n[8]=i*H-c*z+a*M,n[9]=s*z-l*H-d*M,n[10]=Z*x-W*y+p*L,n[11]=X*y-u*x-m*L,n[12]=c*g-i*J-o*M,n[13]=l*J-s*g+e*M,n[14]=W*V-Z*R-G*L,n[15]=u*R-X*V+r*L,n}function me(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],u=n[9],X=n[10],r=n[11],m=n[12],Z=n[13],W=n[14],G=n[15],p=t*i-l*d,L=t*c-s*d,V=l*c-s*i,y=a*Z-u*m,R=a*W-X*m,x=u*W-X*Z,f=t*x-l*R+s*y,M=d*x-i*R+c*y,g=a*V-u*L+X*p,z=m*V-Z*L+W*p;return o*f-e*M+G*g-r*z}function Rn(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],u=t[7],X=t[8],r=t[9],m=t[10],Z=t[11],W=t[12],G=t[13],p=t[14],L=t[15];let V=l[0],y=l[1],R=l[2],x=l[3];return n[0]=V*s+y*c+R*X+x*W,n[1]=V*e+y*o+R*r+x*G,n[2]=V*d+y*a+R*m+x*p,n[3]=V*i+y*u+R*Z+x*L,V=l[4],y=l[5],R=l[6],x=l[7],n[4]=V*s+y*c+R*X+x*W,n[5]=V*e+y*o+R*r+x*G,n[6]=V*d+y*a+R*m+x*p,n[7]=V*i+y*u+R*Z+x*L,V=l[8],y=l[9],R=l[10],x=l[11],n[8]=V*s+y*c+R*X+x*W,n[9]=V*e+y*o+R*r+x*G,n[10]=V*d+y*a+R*m+x*p,n[11]=V*i+y*u+R*Z+x*L,V=l[12],y=l[13],R=l[14],x=l[15],n[12]=V*s+y*c+R*X+x*W,n[13]=V*e+y*o+R*r+x*G,n[14]=V*d+y*a+R*m+x*p,n[15]=V*i+y*u+R*Z+x*L,n}function Ze(n,t,l){const s=l[0],e=l[1],d=l[2];let i,c,o,a,u,X,r,m,Z,W,G,p;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],u=t[4],X=t[5],r=t[6],m=t[7],Z=t[8],W=t[9],G=t[10],p=t[11],n[0]=i,n[1]=c,n[2]=o,n[3]=a,n[4]=u,n[5]=X,n[6]=r,n[7]=m,n[8]=Z,n[9]=W,n[10]=G,n[11]=p,n[12]=i*s+u*e+Z*d+t[12],n[13]=c*s+X*e+W*d+t[13],n[14]=o*s+r*e+G*d+t[14],n[15]=a*s+m*e+p*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 We(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,u,X,r,m,Z,W,G,p,L,V,y,R,x,f,M,g,z,J,H,I,T,A;return c<F?null:(c=1/c,e*=c,d*=c,i*=c,a=Math.sin(l),o=Math.cos(l),u=1-o,X=t[0],r=t[1],m=t[2],Z=t[3],W=t[4],G=t[5],p=t[6],L=t[7],V=t[8],y=t[9],R=t[10],x=t[11],f=e*e*u+o,M=d*e*u+i*a,g=i*e*u-d*a,z=e*d*u-i*a,J=d*d*u+o,H=i*d*u+e*a,I=e*i*u+d*a,T=d*i*u-e*a,A=i*i*u+o,n[0]=X*f+W*M+V*g,n[1]=r*f+G*M+y*g,n[2]=m*f+p*M+R*g,n[3]=Z*f+L*M+x*g,n[4]=X*z+W*J+V*H,n[5]=r*z+G*J+y*H,n[6]=m*z+p*J+R*H,n[7]=Z*z+L*J+x*H,n[8]=X*I+W*T+V*A,n[9]=r*I+G*T+y*A,n[10]=m*I+p*T+R*A,n[11]=Z*I+L*T+x*A,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],a=t[8],u=t[9],X=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+a*s,n[5]=i*e+u*s,n[6]=c*e+X*s,n[7]=o*e+r*s,n[8]=a*e-d*s,n[9]=u*e-i*s,n[10]=X*e-c*s,n[11]=r*e-o*s,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],a=t[8],u=t[9],X=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-a*s,n[1]=i*e-u*s,n[2]=c*e-X*s,n[3]=o*e-r*s,n[8]=d*s+a*e,n[9]=i*s+u*e,n[10]=c*s+X*e,n[11]=o*s+r*e,n}function ye(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],u=t[5],X=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+a*s,n[1]=i*e+u*s,n[2]=c*e+X*s,n[3]=o*e+r*s,n[4]=a*e-d*s,n[5]=u*e-i*s,n[6]=X*e-c*s,n[7]=r*e-o*s,n}function $0(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 tb(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 nb(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 lb(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 sb(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 eb(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 Le(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,u=s*c,X=s*o,r=s*a,m=e*o,Z=e*a,W=d*a,G=i*c,p=i*o,L=i*a;return n[0]=1-(m+W),n[1]=X+L,n[2]=r-p,n[3]=0,n[4]=X-L,n[5]=1-(u+W),n[6]=Z+G,n[7]=0,n[8]=r+p,n[9]=Z-G,n[10]=1-(u+m),n[11]=0,n[12]=l[0],n[13]=l[1],n[14]=l[2],n[15]=1,n}function db(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],a=t[6],u=t[7],X=s*s+e*e+d*d+i*i;return X>0?(l[0]=(c*i+u*s+o*d-a*e)*2/X,l[1]=(o*i+u*e+a*s-c*d)*2/X,l[2]=(a*i+u*d+c*e-o*s)*2/X):(l[0]=(c*i+u*s+o*d-a*e)*2,l[1]=(o*i+u*e+a*s-c*d)*2,l[2]=(a*i+u*d+c*e-o*s)*2),Le(n,t,l),n}function ib(n,t){return n[0]=t[12],n[1]=t[13],n[2]=t[14],n}function xe(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],u=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+u*u),n}function cb(n,t){const l=new B(3);xe(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,u=t[5]*e,X=t[6]*d,r=t[8]*s,m=t[9]*e,Z=t[10]*d,W=i+u+Z;let G=0;return W>0?(G=Math.sqrt(W+1)*2,n[3]=.25*G,n[0]=(X-m)/G,n[1]=(r-o)/G,n[2]=(c-a)/G):i>u&&i>Z?(G=Math.sqrt(1+i-u-Z)*2,n[3]=(X-m)/G,n[0]=.25*G,n[1]=(c+a)/G,n[2]=(r+o)/G):u>Z?(G=Math.sqrt(1+u-i-Z)*2,n[3]=(r-o)/G,n[0]=(c+a)/G,n[1]=.25*G,n[2]=(X+m)/G):(G=Math.sqrt(1+Z-i-u)*2,n[3]=(c-a)/G,n[0]=(r+o)/G,n[1]=(X+m)/G,n[2]=.25*G),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],a=s[6],u=s[8],X=s[9],r=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(u*u+X*X+r*r);const m=1/l[0],Z=1/l[1],W=1/l[2],G=e*m,p=d*Z,L=i*W,V=c*m,y=o*Z,R=a*W,x=u*m,f=X*Z,M=r*W,g=G+y+M;let z=0;return g>0?(z=Math.sqrt(g+1)*2,n[3]=.25*z,n[0]=(R-f)/z,n[1]=(x-L)/z,n[2]=(p-V)/z):G>y&&G>M?(z=Math.sqrt(1+G-y-M)*2,n[3]=(R-f)/z,n[0]=.25*z,n[1]=(p+V)/z,n[2]=(x+L)/z):y>M?(z=Math.sqrt(1+y-G-M)*2,n[3]=(x-L)/z,n[0]=(p+V)/z,n[1]=.25*z,n[2]=(R+f)/z):(z=Math.sqrt(1+M-G-y)*2,n[3]=(p-V)/z,n[0]=(x+L)/z,n[1]=(R+f)/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,a=d+d,u=i+i,X=e*o,r=e*a,m=e*u,Z=d*a,W=d*u,G=i*u,p=c*o,L=c*a,V=c*u,y=s[0],R=s[1],x=s[2];return n[0]=(1-(Z+G))*y,n[1]=(r+V)*y,n[2]=(m-L)*y,n[3]=0,n[4]=(r-V)*R,n[5]=(1-(X+G))*R,n[6]=(W+p)*R,n[7]=0,n[8]=(m+L)*x,n[9]=(W-p)*x,n[10]=(1-(X+Z))*x,n[11]=0,n[12]=l[0],n[13]=l[1],n[14]=l[2],n[15]=1,n}function ab(n,t,l,s,e){const d=t[0],i=t[1],c=t[2],o=t[3],a=d+d,u=i+i,X=c+c,r=d*a,m=d*u,Z=d*X,W=i*u,G=i*X,p=c*X,L=o*a,V=o*u,y=o*X,R=s[0],x=s[1],f=s[2],M=e[0],g=e[1],z=e[2],J=(1-(W+p))*R,H=(m+y)*R,I=(Z-V)*R,T=(m-y)*x,A=(1-(r+p))*x,yt=(G+L)*x,Lt=(Z+V)*f,$l=(G-L)*f,Un=(1-(r+W))*f;return n[0]=J,n[1]=H,n[2]=I,n[3]=0,n[4]=T,n[5]=A,n[6]=yt,n[7]=0,n[8]=Lt,n[9]=$l,n[10]=Un,n[11]=0,n[12]=l[0]+M-(J*M+T*g+Lt*z),n[13]=l[1]+g-(H*M+A*g+$l*z),n[14]=l[2]+z-(I*M+yt*g+Un*z),n[15]=1,n}function Re(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,u=s*i,X=s*c,r=e*i,m=e*c,Z=e*o,W=d*i,G=d*c,p=d*o;return n[0]=1-X-Z,n[1]=u+p,n[2]=r-G,n[3]=0,n[4]=u-p,n[5]=1-a-Z,n[6]=m+W,n[7]=0,n[8]=r+G,n[9]=m-W,n[10]=1-a-X,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),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 Se(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 ze=Se;function ub(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 Xb(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 Ye(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=Ye;function rb(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 ge(n,t,l,s){let e,d,i,c,o,a,u,X,r,m;const Z=t[0],W=t[1],G=t[2],p=s[0],L=s[1],V=s[2],y=l[0],R=l[1],x=l[2];return Math.abs(Z-y)<F&&Math.abs(W-R)<F&&Math.abs(G-x)<F?Xe(n):(X=Z-y,r=W-R,m=G-x,e=1/Math.sqrt(X*X+r*r+m*m),X*=e,r*=e,m*=e,d=L*m-V*r,i=V*X-p*m,c=p*r-L*X,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-m*i,a=m*d-X*c,u=X*i-r*d,e=Math.sqrt(o*o+a*a+u*u),e?(e=1/e,o*=e,a*=e,u*=e):(o=0,a=0,u=0),n[0]=d,n[1]=o,n[2]=X,n[3]=0,n[4]=i,n[5]=a,n[6]=r,n[7]=0,n[8]=c,n[9]=u,n[10]=m,n[11]=0,n[12]=-(d*Z+i*W+c*G),n[13]=-(o*Z+a*W+u*G),n[14]=-(X*Z+r*W+m*G),n[15]=1,n)}function hb(n,t,l,s){const e=t[0],d=t[1],i=t[2],c=s[0],o=s[1],a=s[2];let u=e-l[0],X=d-l[1],r=i-l[2],m=u*u+X*X+r*r;m>0&&(m=1/Math.sqrt(m),u*=m,X*=m,r*=m);let Z=o*r-a*X,W=a*u-c*r,G=c*X-o*u;return m=Z*Z+W*W+G*G,m>0&&(m=1/Math.sqrt(m),Z*=m,W*=m,G*=m),n[0]=Z,n[1]=W,n[2]=G,n[3]=0,n[4]=X*G-r*W,n[5]=r*Z-u*G,n[6]=u*W-X*Z,n[7]=0,n[8]=u,n[9]=X,n[10]=r,n[11]=0,n[12]=e,n[13]=d,n[14]=i,n[15]=1,n}function mb(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 Zb(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 Gb(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 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[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 Wb(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 pb(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],a=n[7],u=n[8],X=n[9],r=n[10],m=n[11],Z=n[12],W=n[13],G=n[14],p=n[15],L=t[0],V=t[1],y=t[2],R=t[3],x=t[4],f=t[5],M=t[6],g=t[7],z=t[8],J=t[9],H=t[10],I=t[11],T=t[12],A=t[13],yt=t[14],Lt=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-R)<=F*Math.max(1,Math.abs(d),Math.abs(R))&&Math.abs(i-x)<=F*Math.max(1,Math.abs(i),Math.abs(x))&&Math.abs(c-f)<=F*Math.max(1,Math.abs(c),Math.abs(f))&&Math.abs(o-M)<=F*Math.max(1,Math.abs(o),Math.abs(M))&&Math.abs(a-g)<=F*Math.max(1,Math.abs(a),Math.abs(g))&&Math.abs(u-z)<=F*Math.max(1,Math.abs(u),Math.abs(z))&&Math.abs(X-J)<=F*Math.max(1,Math.abs(X),Math.abs(J))&&Math.abs(r-H)<=F*Math.max(1,Math.abs(r),Math.abs(H))&&Math.abs(m-I)<=F*Math.max(1,Math.abs(m),Math.abs(I))&&Math.abs(Z-T)<=F*Math.max(1,Math.abs(Z),Math.abs(T))&&Math.abs(W-A)<=F*Math.max(1,Math.abs(W),Math.abs(A))&&Math.abs(G-yt)<=F*Math.max(1,Math.abs(G),Math.abs(yt))&&Math.abs(p-Lt)<=F*Math.max(1,Math.abs(p),Math.abs(Lt))}const Lb=Object.freeze(Object.defineProperty({__proto__:null,add:Gb,adjoint:q0,clone:O0,copy:A0,create:E0,decompose:bb,determinant:me,equals:yb,exactEquals:Vb,frob:Zb,fromQuat:Re,fromQuat2:db,fromRotation:nb,fromRotationTranslation:Le,fromRotationTranslationScale:ob,fromRotationTranslationScaleOrigin:ab,fromScaling:tb,fromTranslation:$0,fromValues:D0,fromXRotation:lb,fromYRotation:sb,fromZRotation:eb,frustum:Ke,getRotation:cb,getScaling:xe,getTranslation:ib,identity:Xe,invert:he,lookAt:ge,mul:Rn,multiply:Rn,multiplyScalar:Wb,multiplyScalarAndAdd:pb,ortho:Me,orthoNO:Ye,orthoZO:rb,perspective:ze,perspectiveFromFieldOfView:Xb,perspectiveNO:Se,perspectiveZO:ub,rotate:We,rotateX:pe,rotateY:Ve,rotateZ:ye,scale:Ge,set:_0,str:mb,sub:fe,subtract:fe,targetTo:hb,translate:Ze,transpose:re},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 Rb(n,t,l,s){const e=new B(4);return e[0]=n,e[1]=t,e[2]=l,e[3]=s,e}function Kb(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 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 Je(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 Yb(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 Mb(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 fb(n,t){return n[0]=dt(t[0]),n[1]=dt(t[1]),n[2]=dt(t[2]),n[3]=dt(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 Tb(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 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 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 Wl(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 pl(n){const t=n[0],l=n[1],s=n[2],e=n[3];return t*t+l*l+s*s+e*e}function Cb(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 Pe(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 Qe(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],a=l[2]*s[3]-l[3]*s[2],u=t[0],X=t[1],r=t[2],m=t[3];return n[0]=X*a-r*o+m*c,n[1]=-(u*a)+r*i-m*d,n[2]=u*o-X*i+m*e,n[3]=-(u*c)+X*d-r*e,n}function Be(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 Jb(n,t){t=t===void 0?1:t;let l,s,e,d,i,c;do l=mt()*2-1,s=mt()*2-1,i=l*l+s*s;while(i>=1);do e=mt()*2-1,d=mt()*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 ve(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 we(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],u=a*s+c*d-o*e,X=a*e+o*s-i*d,r=a*d+i*e-c*s,m=-i*s-c*e-o*d;return n[0]=u*a+m*-i+X*-o-r*-c,n[1]=X*a+m*-c+r*-i-u*-o,n[2]=r*a+m*-o+u*-c-X*-i,n[3]=t[3],n}function Hb(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],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 Qb=Fe,Bb=Ne,vb=Je,wb=Ie,Ub=ke,jb=Wl,Eb=pl,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:Kb,create:Te,cross:Nb,dist:wb,distance:Ie,div:vb,divide:Je,dot:Qe,equals:Pb,exactEquals:kb,floor:Yb,forEach:Ob,fromValues:Rb,inverse:Fb,len:jb,length:Wl,lerp:Be,max:gb,min:Mb,mul:Bb,multiply:Ne,negate:Cb,normalize:Pe,random:Jb,round:fb,scale:He,scaleAndAdd:Tb,set:Sb,sqrDist:Ub,sqrLen:Eb,squaredDistance:ke,squaredLength:pl,str:Ib,sub:Qb,subtract:Fe,transformMat4:ve,transformQuat:we,zero:Hb},Symbol.toStringTag,{value:"Module"}));var Vl;(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"})(Vl||(Vl={}));const Db=45*Math.PI/180,_b=1,yl=.1,Ll=500,qb=Object.freeze([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]);class ot extends ie{static get IDENTITY(){return to()}static get ZERO(){return $b()}get ELEMENTS(){return 16}get RANK(){return 4}get INDICES(){return Vl}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,u,X,r,m,Z,W,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]=u,this[10]=X,this[11]=r,this[12]=m,this[13]=Z,this[14]=W,this[15]=G,this.check()}setRowMajor(t,l,s,e,d,i,c,o,a,u,X,r,m,Z,W,G){return this[0]=t,this[1]=d,this[2]=a,this[3]=m,this[4]=l,this[5]=i,this[6]=u,this[7]=Z,this[8]=s,this[9]=c,this[10]=X,this[11]=W,this[12]=e,this[13]=o,this[14]=r,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(qb)}fromObject(t){return this.check()}fromQuaternion(t){return Re(this,t),this.check()}frustum(t){const{left:l,right:s,bottom:e,top:d,near:i=yl,far:c=Ll}=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 ge(this,l,s,e),this.check()}ortho(t){const{left:l,right:s,bottom:e,top:d,near:i=yl,far:c=Ll}=t;return Me(this,l,s,e,d,i,c),this.check()}orthographic(t){const{fovy:l=Db,aspect:s=_b,focalDistance:e=1,near:d=yl,far:i=Ll}=t;Ue(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 Ue(l),ze(this,l,s,e,d),this.check()}determinant(){return me(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 re(this,this),this.check()}invert(){return he(this,this),this.check()}multiplyLeft(t){return Rn(this,t,this),this.check()}multiplyRight(t){return Rn(this,this,t),this.check()}rotateX(t){return pe(this,this,t),this.check()}rotateY(t){return Ve(this,this,t),this.check()}rotateZ(t){return ye(this,this,t),this.check()}rotateXYZ(t){return this.rotateX(t[0]).rotateY(t[1]).rotateZ(t[2])}rotateAxis(t,l){return We(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=ve(l||[-0,-0,-0,-0],t,this),Ut(l,4),l):this.transformAsPoint(t,l)}transformAsPoint(t,l){const{length:s}=t;let e;switch(s){case 2:e=el(l||[-0,-0],t,this);break;case 3:e=Wn(l||[-0,-0,-0],t,this);break;default:throw new Error("Illegal vector")}return Ut(e,t.length),e}transformAsVector(t,l){let s;switch(t.length){case 2:s=Us(l||[-0,-0],t,this);break;case 3:s=js(l||[-0,-0,-0],t,this);break;default:throw new Error("Illegal vector")}return Ut(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 Kn,Sn;function $b(){return Kn||(Kn=new ot([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]),Object.freeze(Kn)),Kn}function to(){return Sn||(Sn=new ot,Object.freeze(Sn)),Sn}function Ue(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),a=(e+s)/(e-s),u=-1,X=-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]=a,n[10]=u,n[11]=X,n[12]=0,n[13]=0,n[14]=r,n[15]=0,n}function je(){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 Ee(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 Oe(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],u=l[3];return n[0]=s*u+i*c+e*a-d*o,n[1]=e*u+i*o+d*c-s*a,n[2]=d*u+i*a+s*o-e*c,n[3]=i*u-s*c-e*o-d*a,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 zn(n,t,l,s){const e=t[0],d=t[1],i=t[2],c=t[3];let o=l[0],a=l[1],u=l[2],X=l[3],r,m,Z,W,G;return r=e*o+d*a+i*u+c*X,r<0&&(r=-r,o=-o,a=-a,u=-u,X=-X),1-r>F?(m=Math.acos(r),G=Math.sin(m),Z=Math.sin((1-s)*m)/G,W=Math.sin(s*m)/G):(Z=1-s,W=s),n[0]=Z*e+W*o,n[1]=Z*d+W*a,n[2]=Z*i+W*u,n[3]=Z*c+W*X,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 Ae(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 ao=Ce,uo=He,Xo=Qe,ro=Be,ho=Wl,mo=pl,De=Pe,Zo=function(){const n=il(),t=cl(1,0,0),l=cl(0,1,0);return function(s,e,d){const i=jt(e,d);return i<-.999999?(Kt(n,t,e),de(n)<1e-6&&Kt(n,l,e),te(n,n),Ee(s,n,Math.PI),s):i>.999999?(s[0]=0,s[1]=0,s[2]=0,s[3]=1,s):(Kt(n,e,d),s[0]=n[0],s[1]=n[1],s[2]=n[2],s[3]=1+i,De(s,s))}}();(function(){const n=je(),t=je();return function(l,s,e,d,i,c){return zn(n,s,i,c),zn(t,e,d,c),zn(l,n,t,2*c*(1-c)),l}})(),function(){const n=ce();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],De(t,Ae(t,n))}}();const Go=[0,0,0,1];class zt extends Zn{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 Ae(this,t),this.check()}fromAxisRotation(t,l){return Ee(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]=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 ho(this)}lengthSquared(){return mo(this)}dot(t){return Xo(this,t)}rotationTo(t,l){return Zo(this,t,l),this.check()}add(t){return ao(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):(ro(this,t,l,s),this.check())}multiplyRight(t){return Oe(this,this,t),this.check()}multiplyLeft(t){return Oe(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 uo(this,this,t),this.check()}slerp(t,l,s){let e,d,i;switch(arguments.length){case 1:({start:e=Go,target:d,ratio:i}=t);break;case 2:e=this,d=t,i=l;break;default:e=t,d=l,i=s}return zn(this,e,d,i),this.check()}transformVector4(t,l=new bt){return we(l,t,this),Ut(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 Yn="Unknown Euler angle order",Yt=.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 Zn{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 a=-2*(l*e-d*s);const u=2*(s*e+d*l),X=-2*(l*l+i)+1;a=a>1?1:a,a=a<-1?-1:a;const r=Math.atan2(u,X),m=Math.asin(a),Z=Math.atan2(o,c);return this.set(r,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 Wo(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]=po(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 zt;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(Yn)}}_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],u=t[6],X=t[10];switch(l=l||this[3],l){case v.XYZ:this[1]=Math.asin(xt(d,-1,1)),Math.abs(d)<Yt?(this[0]=Math.atan2(-o,X),this[2]=Math.atan2(-e,s)):(this[0]=Math.atan2(u,c),this[2]=0);break;case v.YXZ:this[0]=Math.asin(-xt(o,-1,1)),Math.abs(o)<Yt?(this[1]=Math.atan2(d,X),this[2]=Math.atan2(i,c)):(this[1]=Math.atan2(-a,s),this[2]=0);break;case v.ZXY:this[0]=Math.asin(xt(u,-1,1)),Math.abs(u)<Yt?(this[1]=Math.atan2(-a,X),this[2]=Math.atan2(-e,c)):(this[1]=0,this[2]=Math.atan2(i,s));break;case v.ZYX:this[1]=Math.asin(-xt(a,-1,1)),Math.abs(a)<Yt?(this[0]=Math.atan2(u,X),this[2]=Math.atan2(i,s)):(this[0]=0,this[2]=Math.atan2(-e,c));break;case v.YZX:this[2]=Math.asin(xt(i,-1,1)),Math.abs(i)<Yt?(this[0]=Math.atan2(-o,c),this[1]=Math.atan2(-a,s)):(this[0]=0,this[1]=Math.atan2(d,X));break;case v.XZY:this[2]=Math.asin(-xt(e,-1,1)),Math.abs(e)<Yt?(this[0]=Math.atan2(u,c),this[1]=Math.atan2(d,s)):(this[0]=Math.atan2(-o,X),this[1]=0);break;default:throw new Error(Yn)}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),u=Math.sin(e),X=Math.sin(d);switch(this[3]){case v.XYZ:{const r=i*o,m=i*X,Z=a*o,W=a*X;l[0]=c*o,l[4]=-c*X,l[8]=u,l[1]=m+Z*u,l[5]=r-W*u,l[9]=-a*c,l[2]=W-r*u,l[6]=Z+m*u,l[10]=i*c;break}case v.YXZ:{const r=c*o,m=c*X,Z=u*o,W=u*X;l[0]=r+W*a,l[4]=Z*a-m,l[8]=i*u,l[1]=i*X,l[5]=i*o,l[9]=-a,l[2]=m*a-Z,l[6]=W+r*a,l[10]=i*c;break}case v.ZXY:{const r=c*o,m=c*X,Z=u*o,W=u*X;l[0]=r-W*a,l[4]=-i*X,l[8]=Z+m*a,l[1]=m+Z*a,l[5]=i*o,l[9]=W-r*a,l[2]=-i*u,l[6]=a,l[10]=i*c;break}case v.ZYX:{const r=i*o,m=i*X,Z=a*o,W=a*X;l[0]=c*o,l[4]=Z*u-m,l[8]=r*u+W,l[1]=c*X,l[5]=W*u+r,l[9]=m*u-Z,l[2]=-u,l[6]=a*c,l[10]=i*c;break}case v.YZX:{const r=i*c,m=i*u,Z=a*c,W=a*u;l[0]=c*o,l[4]=W-r*X,l[8]=Z*X+m,l[1]=X,l[5]=i*o,l[9]=-a*o,l[2]=-u*o,l[6]=m*X+Z,l[10]=r-W*X;break}case v.XZY:{const r=i*c,m=i*u,Z=a*c,W=a*u;l[0]=c*o,l[4]=-X,l[8]=u*o,l[1]=r*X+W,l[5]=i*o,l[9]=m*X-Z,l[2]=Z*X-m,l[6]=a*o,l[10]=W*X+r;break}default:throw new Error(Yn)}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,u=l*s*d-t*e*i;return new zt(o,a,u,c)}}function Wo(n){return n>=0&&n<6}function po(n){if(n<0&&n>=6)throw new Error(Yn);return n}const Vo=.1,yo=1e-12,Lo=1e-15,_e=!0,xo=!1,Mn={CCW:-1,CW:1,NOT_ORIENTABLE:0},Ro=2*Math.PI,gn=1,qe=0,$=2,Ko=3,So=4,zo=1,Yo=2,xl=0,Et=1,Mt=2;var fn=Object.freeze({__proto__:null,BOUNDARY:$,CCW:_e,CONTAINS:Ko,CW:xo,END_VERTEX:Mt,INSIDE:gn,INTERLACE:So,NOT_VERTEX:xl,ORIENTATION:Mn,OUTSIDE:qe,OVERLAP_OPPOSITE:Yo,OVERLAP_SAME:zo,PIx2:Ro,START_VERTEX:Et});let tt=1e-6;function $e(n){tt=n}function td(){return tt}const Mo=3;function Rl(n){return n<tt&&n>-tt}function Zt(n,t){return n-t<tt&&n-t>-tt}function nd(n,t){return n-t>tt}function go(n,t){return n-t>-tt}function ld(n,t){return n-t<-tt}function fo(n,t){return n-t<tt}var To=Object.freeze({__proto__:null,DECIMALS:Mo,EQ:Zt,EQ_0:Rl,GE:go,GT:nd,LE:fo,LT:ld,getTolerance:td,setTolerance:$e});let b={Utils:To,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 fn)b[n]=fn[n];Object.defineProperty(b,"DP_TOL",{get:function(){return td()},set:function(n){$e(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 Kl{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 sd={stroke:"black"};class Co{constructor(t=sd){for(const l in t)this[l]=t[l];this.stroke=t.stroke??sd.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 Gt(n){return new Co(n).toAttributesString()}function gt(n,t){let l=[],[s,e,d]=n.standard,[i,c,o]=t.standard,a=s*c-e*i,u=d*c-e*o,X=s*o-d*i;if(!b.Utils.EQ_0(a)){let r,m;e===0?(r=d/s,m=X/a):c===0?(r=o/i,m=X/a):s===0?(r=u/a,m=d/e):i===0?(r=u/a,m=o/c):(r=u/a,m=X/a),l.push(new b.Point(r,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=Ot(s,n);for(let d of e)rd(d,l)||l.push(d)}return l}function Tn(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 Ot(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 gt(s,t)}function Cn(n,t){let l=[];if(n.box.not_intersect(t.box))return 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=gt(s,e);d.length>0&&ed(d[0],n)&&ed(d[0],t)&&l.push(d[0])}return l}function ed(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.box.not_intersect(t.box))return 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 Tt(n,t){let l=[];if(n.box.not_intersect(t.box))return 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 Fo(n,t){let l=[];for(let s of t.toSegments()){let e=Cn(s,n);for(let d of e)l.push(d)}return l}function dd(n,t){let l=[];if(n.box.not_intersect(t.box))return l;let 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),u=Math.sqrt(e*e-o*o);return c=a.translate(s.rotate90CCW().multiply(u)),l.push(c),c=a.translate(s.rotate90CW().multiply(u)),l.push(c),l}function No(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 id(n,t){let l=[];if(n.box.not_intersect(t.box))return 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 Sl(n,t){let l=[];if(n.box.not_intersect(t.box))return 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=dd(s,e);for(let i of d)i.on(n)&&l.push(i);return l}function Jo(n,t){let l=[];for(let s of t.toSegments()){let e=Tt(s,n);for(let d of e)l.push(d)}return l}function cd(n,t){return n.isSegment?Cn(n.shape,t):Tt(t,n.shape)}function bd(n,t){return n.isSegment?Tt(n.shape,t):id(n.shape,t)}function od(n,t){return n.isSegment?Ot(n.shape,t):Tn(t,n.shape)}function Ho(n,t){return n.isSegment?Ml(t,n.shape):gl(t,n.shape)}function Io(n,t){return n.isSegment?Fn(n.shape,t):Sl(n.shape,t)}function zl(n,t){let l=[];for(let s of t.edges)for(let e of cd(s,n))l.push(e);return l}function Yl(n,t){let l=[];for(let s of t.edges)for(let e of bd(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 od(s,n))rd(e,l)||l.push(e);return n.sortPoints(l)}function ad(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 ud(n,t){return n.isSegment?cd(t,n.shape):n.isArc?bd(t,n.shape):n.isLine?od(t,n.shape):n.isRay?Ho(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,...ud(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?At(n,t):n instanceof b.Segment?zl(n,t):n instanceof b.Arc?Yl(n,t):[]}function rd(n,t){return t.some(l=>l.equalTo(n))}function at(n){return new b.Line(n.start,n.norm)}function Ml(n,t){return Ot(t,at(n)).filter(l=>n.contains(l))}function gl(n,t){return Tn(at(n),t).filter(l=>n.contains(l))}function hd(n,t){return Wt(at(n),t).filter(l=>n.contains(l))}function Bo(n,t){return ft(at(n),t).filter(l=>n.contains(l))}function md(n,t){return gt(at(n),t).filter(l=>n.contains(l))}function vo(n,t){return gt(at(n),at(t)).filter(l=>n.contains(l)).filter(l=>t.contains(l))}function Zd(n,t){return At(at(n),t).filter(l=>n.contains(l))}function Gd(n,t){if(n.intersect&&n.intersect instanceof Function)return n.intersect(t);throw Q.UNSUPPORTED_SHAPE_TYPE}function Dt(n,t){let l=[];for(let s of t)l=[...l,...Gd(n,s.shape)];return l}function wo(n,t){let l=[];for(let s of n)for(let e of t)l=[...l,...Gd(s,e)];return l}let pt=class on extends Kl{constructor(...t){if(super(),this.isInfinite=!1,t.length===1&&t[0]instanceof Array&&t[0].length>0){let l=!1;const s=t[0],e=s.length,d=o=>o instanceof b.Segment||o instanceof b.Arc||o instanceof b.Ray||o instanceof b.Line,i=o=>o instanceof b.Segment||o instanceof b.Arc||o instanceof b.Ray,c=o=>o instanceof b.Segment||o instanceof b.Arc;if(l=e===1&&d(s[0])||e>1&&i(s[0])&&i(s[e-1])&&s.slice(1,e-1).every(c),l){this.isInfinite=s.some(o=>o instanceof b.Ray||o instanceof b.Line);for(let o of s){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?wo(this,t):Dt(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(K,r){"use strict";var jn=typeof document<"u"?document.currentScript:null;function Gi(n){return an(n)||Xn(n)||es(n)}function an(n){return"modelMatrix"in n}function Xn(n){return"position"in n}function es(n){return"positions"in n}const ds={[r.WebGLConstants.BYTE]:Int8Array,[r.WebGLConstants.UNSIGNED_BYTE]:Uint8Array,[r.WebGLConstants.SHORT]:Int16Array,[r.WebGLConstants.UNSIGNED_SHORT]:Uint16Array,[r.WebGLConstants.INT]:Int32Array,[r.WebGLConstants.UNSIGNED_INT]:Uint32Array,[r.WebGLConstants.FLOAT]:Float32Array,[r.WebGLConstants.DOUBLE]:Float64Array};var is=(n=>(n[n.x=0]="x",n[n.y=1]="y",n[n.z=2]="z",n))(is||{});K.Xyz_Hpr=(n=>(n.x="roll",n.y="pitch",n.z="heading",n))(K.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 r.Cartesian3(e.roll,-e.pitch,-e.heading)}n.toCartesian3=l;function s(e){return new r.HeadingPitchRoll(-e[t("heading")],-e[t("pitch")],e[t("roll")])}n.toHeadingPitchRoll=s})(K.Xyz_Hpr||(K.Xyz_Hpr={}));var cs=(n=>(n[n.heading=0]="heading",n[n.pitch=1]="pitch",n[n.roll=2]="roll",n))(cs||{});function En(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 Bt(n){if(n.axis){const{axis:l,angle:s}=n;return r.Quaternion.fromAxisAngle(l,s)}const t=K.Xyz_Hpr.toHeadingPitchRoll(n);return r.Quaternion.fromHeadingPitchRoll(t)}function pi(n,t,l){const s=r.Matrix3.fromQuaternion(n),e=r.Matrix4.fromRotation(s),d=r.Matrix4.inverseTransformation(t,new r.Matrix4),i=r.Matrix4.multiply(d,e,e);return On(i)}function On(n,t){const l=r.Matrix4.getMatrix3(n,new r.Matrix3),s=r.Quaternion.fromRotationMatrix(l);return r.HeadingPitchRoll.fromQuaternion(s,t)}function Wi(n,t,l){l=l??new r.Matrix4;const s=r.Matrix4.inverse(t,new r.Matrix4);return r.Matrix4.multiply(s,n,l)}function bs(n,t,l){let s=r.Quaternion.computeAxis(n,new r.Cartesian3);if(s.equals(r.Cartesian3.ZERO))return null;const e=r.Quaternion.computeAngle(n);return s=r.Matrix4.multiplyByPointAsVector(t,s,s),r.Quaternion.fromAxisAngle(s,e)}function Vi(n,t,l){let s=r.Quaternion.computeAxis(n,new r.Cartesian3);if(s.equals(r.Cartesian3.ZERO))return null;const e=r.Quaternion.computeAngle(n),d=r.Matrix4.inverse(t,new r.Matrix4);return s=r.Matrix4.multiplyByPointAsVector(d,s,s),r.Quaternion.fromAxisAngle(s,e)}function un(n,t){let{translation:l,rotation:s,scale:e}=n;const{referFrame:d,worldTranslation:i,worldRotation:c,worldScale:o}=En(t);let a=null;return l&&(i||(l=r.Matrix4.multiplyByPointAsVector(d,l,new r.Cartesian3))),s&&(a=Bt(s),c||(a=bs(a,d))),e&&(o||(e=r.Matrix4.multiplyByPointAsVector(d,e,new r.Cartesian3))),{translation:l,rotation:a,scale:e}}function os(n,t){let{translation:l,rotation:s,scale:e}=n;const{referFrame:d,worldTranslation:i,worldRotation:c,worldScale:o}=En(t),a=d?r.Matrix4.inverse(d,new r.Matrix4):null;let X=null;if(l&&i&&(l=r.Matrix4.multiplyByPointAsVector(a,l,new r.Cartesian3)),s&&(X=Bt(s),c)){let u=r.Quaternion.computeAxis(X,new r.Cartesian3);if(!u.equals(r.Cartesian3.ZERO)){const h=r.Quaternion.computeAngle(X);u=r.Matrix4.multiplyByPointAsVector(a,u,u),X=r.Quaternion.fromAxisAngle(u,h)}}return e&&o&&(e=r.Matrix4.multiplyByPointAsVector(a,e,new r.Cartesian3)),{translation:l,rotation:X,scale:e}}function as(n,t){const l=t?.defaultMatrix;let{translation:s,rotation:e,scale:d}=un(n,t);if(l){if(s||(s=r.Matrix4.getTranslation(l,new r.Cartesian3)),!e){const c=r.Matrix4.getMatrix3(l,new r.Matrix3);e=r.Quaternion.fromRotationMatrix(c)}d||(d=r.Matrix4.getScale(l,new r.Cartesian3))}const i=new r.TranslationRotationScale(s??void 0,e??void 0,d??void 0);return r.Matrix4.fromTranslationRotationScale(i)}function yi(n){const{translation:t,rotation:l,scale:s}=n,e=l?Bt(l):void 0,d=new r.TranslationRotationScale(t??void 0,e,s??void 0);return r.Matrix4.fromTranslationRotationScale(d)}function Xs(n,t,l){const s=r.Cartesian3.subtract(t,n,new r.Cartesian3),e=r.Cartesian3.subtract(l,n,new r.Cartesian3),d=r.Cartesian3.cross(s,e,s);return r.Cartesian3.normalize(d,s)}function Li(n,t,l){const s=Xs(n,t,l);return r.Plane.fromPointNormal(s,n)}function*xi(n,t=!0,l,s){const e=n.length,d=t?e:e-1,i=l||s?r.Cartesian3.prototype.equalsEpsilon:r.Cartesian3.prototype.equals;for(let c=0;c<d;c++){const o=n[c];let a=(c+1)%e,X=n[a],u=c;for(;i.call(o,X,l,s);){if(a=(++u+1)%e,a===c)return;X=n[a]}c=u,yield[o,X]}}function us(n){var t=typeof n;return n&&(t==="object"||t==="function")}function rs(n){var t=n;return n!=null&&(t=n.constructor,t==null&&(t=typeof n)),t}function Ri(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 Ki(n){let t=rs(n);return Ri(t)}function Si(n){return n==null||us(n)?rs(n):typeof n}var Dn=(n=>(n.equal="equal",n.intersect="intersect",n.intersectEqual="intersectEqual",n))(Dn||{});(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})(Dn||(Dn={}));const zi=[globalThis.Worker,globalThis.SharedWorker,globalThis.ServiceWorker].filter(n=>n),Yi=["Worker","SharedWorker","ServiceWorker"];function gi(n){if(zi.some(l=>n instanceof l))return!0;const t=Ki(n);return Yi.includes(t)}var An=(n=>(n.Ing="进行中",n.End="结束",n))(An||{}),Mi=Object.defineProperty,Ti=(n,t,l)=>t in n?Mi(n,t,{enumerable:!0,configurable:!0,writable:!0,value:l}):n[t]=l,rn=(n,t,l)=>Ti(n,typeof t!="symbol"?t+"":t,l);const hs=`(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
|
+
`,fi='(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',hn="event";function ms(n,t){t=t??n.name;const l=n.toString();return`globalThis['${t}'] = ${l};`}function _n(n,t){const l=typeof n=="string"?n:n.toString();t=t??[];const s=t.map(function(d){return us(d)?JSON.stringify(d):d}),e=s.length>0?`,${s.join(",")}`:"";return`(${l}).call(this${e});`}function Ci(n,t){return n.name?ms(n):_n(n,t)}function Zs(n){return`globalThis.listenMessage(${typeof n=="string"?n:n.toString()});`}function Fi(n){const t=n.map(function(s){return`${s}.call(this,${hn});`}).join(`
|
|
3
|
+
`),l=`function(${hn}){${t}}`;return Zs(l)}function Ni(n){const t=n.map(function(s){return _n(s,[hn])}).join(`
|
|
4
|
+
`),l=`function(${hn}){${t}}`;return Zs(l)}function Hi(n,t){const l=new Blob(n,{type:"text/javascript",...t});return URL.createObjectURL(l)}function Gs(n){return n.name||n.fun?[n]:Object.entries(n).map(function([t,l]){return{name:t,fun:l}})}function Ji(n,t){const{code:l,named:s,iife:e,message:d}=n,i=[],c=[],o=e||[],a=[],X=[],u=Array.isArray(l)?l:l?[l]:[];for(const y of u){const S=Si(y);if(S===Object||S==="object"){const R=Gs(y);i.push(...R)}else c.push(y)}const h=Array.isArray(s)?s:s?[s]:[];for(const y of h)if(typeof y=="function")i.push({fun:y});else{const S=Gs(y);i.push(...S)}const m=Array.isArray(d)?d:d?[d]:[];for(const y of m)switch(typeof y){case"string":{X.push(y);break}case"function":{a.push(y);break}default:{const{name:S,fun:R}=y;R?a.push(R):S&&X.push(S)}}const Z=i.map(function({name:y,fun:S}){return`${ms(S,y)}
|
|
5
|
+
`}),p=c.map(function(y){return typeof y=="function"?`${Ci(y)}
|
|
6
|
+
`:y}),G=o.map(function(y){return`${_n(y)}
|
|
7
|
+
`}),W=[],L=Ni(a);W.push(`${L}
|
|
8
|
+
`);const V=Fi(X);return W.push(`${V}
|
|
9
|
+
`),[`${hs}
|
|
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 ${pt({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=pt;const Uo=(...n)=>new b.Multiline(...n);b.multiline=Uo;function Ct(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=xl;Zt(d,0)&&(i|=Et),Zt(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=ut(n.int_points1),n.int_points2_sorted=ut(n.int_points2)}function ut(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 fl(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],!!Zt(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||!Zt(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=$),t.edge_after&&(t.edge_after.bvStart=$)}function Cl(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=Ft(n.int_points1_sorted,d,t),a;c+o<e&&n.int_points1_sorted[c+o].face===t?a=c+o:a=l;let u=Ft(n.int_points1_sorted,a,t);s=null;for(let p=a;p<a+u;p++){let L=n.int_points1_sorted[p];if(L.face===t&&n.int_points2[L.id].face===n.int_points2[i.id].face){s=L;break}}if(s===null)continue;let X=i.edge_after,r=s.edge_before;if(!(X.bv===$&&r.bv===$)||X!==r)continue;let m=n.int_points2[i.id],Z=n.int_points2[s.id],W=m.edge_after,G=Z.edge_before;W.bv===$&&G.bv===$&&W===G||(m=n.int_points2[s.id],Z=n.int_points2[i.id],W=m.edge_after,G=Z.edge_before),W.bv===$&&G.bv===$&&W===G&&X.setOverlap(W)}}function Ft(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 Nt(n,t){if(t){for(let l of t){let s=l.edge_before;if(l.is_vertex=xl,s.shape.start&&s.shape.start.equalTo(l.pt)&&(l.is_vertex|=Et),s.shape.end&&s.shape.end.equalTo(l.pt)&&(l.is_vertex|=Mt),l.is_vertex&Et){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 pt&&l.is_vertex&Et&&(l.edge_after=n.first)}}function Wd(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:nt,OUTSIDE:lt,BOUNDARY:j,OVERLAP_SAME:Oo,OVERLAP_OPPOSITE:Ao}=fn,{NOT_VERTEX:lX,START_VERTEX:pd,END_VERTEX:Vd}=fn,Nn=1,qt=2,Vt=3;function Do(n,t){let[l,s]=$t(n,t,Nn,!0);return l}function Fl(n,t){let s=t.clone().reverse(),[e,d]=$t(n,s,Vt,!0);return e}function yd(n,t){let[l,s]=$t(n,t,qt,!0);return l}function Ld(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 Nl(n,t){let[l,s]=$t(n,t,Vt,!1),e=[];for(let d of l.faces)e=[...e,...[...d.edges].map(i=>i.shape)];return e}function xd(n,t){let l=n.clone(),s=t.clone(),e=Rd(l,s);_t(e),Nt(l,e.int_points1_sorted),Nt(s,e.int_points2_sorted),fl(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 _o(n,t,l,s){let e=Kd(n,l.int_points1),d=Kd(t,l.int_points2);for(Sd(e,t),Sd(d,n),Tl(l.int_points1),Tl(l.int_points2),Cl(l.int_points1,t),Cl(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),zd(n,e,s,!0),zd(t,d,s,!1)}function qo(n,t,l,s){ta(n,t,s,l.int_points2),na(n,t,l),Hl(n,l.int_points1),Hl(t,l.int_points2),Il(n,l.int_points1,l.int_points2),Il(n,l.int_points2,l.int_points1)}function $t(n,t,l,s){let e=n.clone(),d=t.clone(),i=Rd(e,d);return _t(i),Nt(e,i.int_points1_sorted),Nt(d,i.int_points2_sorted),fl(i),_t(i),_o(e,d,i,l),s&&qo(e,d,i,l),[e,d]}function Rd(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)Ct(s,c,l.int_points1),Ct(d,c,l.int_points2)}}return l}function Kd(n,t){let l=[];for(let s of n.faces)t.find(e=>e.face===s)||l.push(s);return l}function Sd(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,a=s.length,u=!1;for(let X=0;X<a;X++){let r=s[X];r.face!==i&&(c=X,i=r.face);let m=X,Z=Ft(s,X,i),W;m+Z<a&&s[m+Z].face===i?W=m+Z:W=c;let G=Ft(s,W,i);o=null;for(let V=W;V<W+G;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 p=r.edge_after,L=o.edge_before;if(p.bv===j&&L.bv!=j){p.bv=L.bv;continue}if(p.bv!=j&&L.bv===j){L.bv=p.bv;continue}if(p.bv===j&&L.bv===j&&p!=L||p.bv===nt&&L.bv===lt||p.bv===lt&&L.bv===nt){let V=p.next;for(;V!=L;)V.bvStart=void 0,V.bvEnd=void 0,V.bv=void 0,V.setInclusion(t),V=V.next}if(p.bv===j&&L.bv===j&&p!=L){let V=p.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&&(p.bv=y,L.bv=y);continue}if(p.bv===nt&&L.bv===lt||p.bv===lt&&L.bv===nt){let V=p;for(;V!=L;){if(V.bvStart===p.bv&&V.bvEnd===L.bv){let[y,R]=V.shape.distanceTo(t);if(y<10*b.DP_TOL){Ct(V,R.ps,l);let x=l[l.length-1];if(x.is_vertex&pd)x.edge_after=V,x.edge_before=V.prev,V.bvStart=j,V.bv=void 0,V.setInclusion(t);else if(x.is_vertex&Vd)x.edge_after=V.next,V.bvEnd=j,V.bv=void 0,V.setInclusion(t);else{let g=t.addVertex(x.pt,V);x.edge_before=g,x.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 f=t.findEdgeByPoint(R.pe);Ct(f,R.pe,e);let M=e[e.length-1];if(M.is_vertex&pd)M.edge_after=f,M.edge_before=f.prev;else if(M.is_vertex&Vd)M.edge_after=f.next;else{let g=e.find(J=>J.edge_after===f),z=t.addVertex(M.pt,f);M.edge_before=z,M.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)}_t(d),u=!0;break}}V=V.next}if(u)break;throw Q.UNRESOLVED_BOUNDARY_CONFLICT}}return u}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 a=o,u=Ft(l,o,e),X;a+u<l.length&&l[a+u].face===i.face?X=a+u:X=d,c=l[X];let r=X,m=Ft(l,r,e),Z=i.edge_after,W=c.edge_before;if(Z.bv===nt&&W.bv===nt&&t===Nn||Z.bv===lt&&W.bv===lt&&t===qt||(Z.bv===lt||W.bv===lt)&&t===Vt&&!s||(Z.bv===nt||W.bv===nt)&&t===Vt&&s||Z.bv===j&&W.bv===j&&Z.overlap&Oo&&s||Z.bv===j&&W.bv===j&&Z.overlap&Ao){n.removeChain(e,Z,W);for(let G=a;G<a+u;G++)l[G].edge_after=void 0;for(let G=r;G<r+m;G++)l[G].edge_before=void 0}o+=u-1}}function ta(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 na(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 Il(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{Kl.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 zd(n,t,l,s){for(let e of t){let d=e.first.bv;(l===Nn&&d===nt||l===Vt&&d===nt&&s||l===Vt&&d===lt&&!s||l===qt&&d===lt)&&n.deleteFace(e)}}var tn=Object.freeze({__proto__:null,BOOLEAN_INTERSECT:qt,BOOLEAN_SUBTRACT:Vt,BOOLEAN_UNION:Nn,calculateIntersections:xd,innerClip:Ld,intersect:yd,outerClip:Nl,removeNotRelevantChains:Jl,removeOldFaces:Hl,restoreFaces:Il,subtract:Fl,unify:Do});const la=RegExp("T.F..FFF.|T.F...F.."),sa=RegExp("T........|.T.......|...T.....|....T...."),ea=RegExp("FT.......|F..T.....|F...T...."),da=RegExp("T.F..F..."),ia=RegExp("T.F..F...|.TF..F...|..FT.F...|..F.TF...");class Jt{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 la.test(this.toString())}intersect(){return sa.test(this.toString())}touch(){return ea.test(this.toString())}inside(){return da.test(this.toString())}covered(){return ia.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,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 u of i)if(u.shape.contains(t))return b.BOUNDARY;let c=[...n.faces],o=[];for(let u of i)for(let X of s.intersect(u.shape)){if(X.equalTo(t))return b.BOUNDARY;o.push({pt:X,edge:u,face_index:c.indexOf(u.face)})}o.sort((u,X)=>ld(u.pt.x,X.pt.x)?-1:nd(u.pt.x,X.pt.x)?1:u.face_index<X.face_index?-1:u.face_index>X.face_index?1:u.edge.arc_length<X.edge.arc_length?-1:u.edge.arc_length>X.edge.arc_length?1:0);let a=0;for(let u=0;u<o.length;u++){let X=o[u];if(X.pt.equalTo(X.edge.shape.start)){if(u>0&&X.pt.equalTo(o[u-1].pt)&&X.face_index===o[u-1].face_index&&X.edge.prev===o[u-1].edge)continue;let r=X.edge.prev;for(;Rl(r.length);)r=r.prev;let m=r.shape.tangentInEnd(),Z=X.pt.translate(m),W=X.edge.shape.tangentInStart(),G=X.pt.translate(W),p=Z.leftTo(e),L=G.leftTo(e);(p&&!L||!p&&L)&&a++}else if(X.pt.equalTo(X.edge.shape.end)){if(u>0&&X.pt.equalTo(o[u-1].pt)&&X.face_index===o[u-1].face_index&&X.edge.next===o[u-1].edge)continue;let r=X.edge.next;for(;Rl(r.length);)r=r.next;let m=r.shape.tangentInStart(),Z=X.pt.translate(m),W=X.edge.shape.tangentInEnd(),G=X.pt.translate(W),p=Z.leftTo(e),L=G.leftTo(e);(p&&!L||!p&&L)&&a++}else if(X.edge.shape instanceof b.Segment)a++;else{let r=X.edge.shape.box;Zt(X.pt.y,r.ymin)||Zt(X.pt.y,r.ymax)||a++}}return l=a%2===1?gn:qe,l}function ca(n,t){return Ht(n,t).equal()}function Yd(n,t){return Ht(n,t).intersect()}function ba(n,t){return Ht(n,t).touch()}function oa(n,t){return!Yd(n,t)}function Md(n,t){return Ht(n,t).inside()}function gd(n,t){return Ht(n,t).covered()}function aa(n,t){return Md(t,n)}function fd(n,t){return gd(t,n)}function Ht(n,t){if(n instanceof b.Line&&t instanceof b.Line)return ua(n,t);if(n instanceof b.Line&&t instanceof b.Circle)return Xa(n,t);if(n instanceof b.Line&&t instanceof b.Box)return ra(n,t);if(n instanceof b.Line&&t instanceof b.Polygon)return ha(n,t);if((n instanceof b.Segment||n instanceof b.Arc)&&t instanceof b.Polygon)return Td(n,t);if((n instanceof b.Segment||n instanceof b.Arc)&&(t instanceof b.Circle||t instanceof b.Box))return Td(n,new b.Polygon(t));if(n instanceof b.Polygon&&t instanceof b.Polygon)return Jn(n,t);if((n instanceof b.Circle||n instanceof b.Box)&&(t instanceof b.Circle||t instanceof b.Box))return Jn(new b.Polygon(n),new b.Polygon(t));if((n instanceof b.Circle||n instanceof b.Box)&&t instanceof b.Polygon)return Jn(new b.Polygon(n),t);if(n instanceof b.Polygon&&(t instanceof b.Circle||t instanceof b.Box))return Jn(n,new b.Polygon(t))}function ua(n,t){let l=new Jt,s=gt(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 Xa(n,t){let l=new Jt,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 pt([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 ra(n,t){let l=new Jt,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 pt([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 ha(n,t){let l=new Jt,s=At(n,t),e=new pt([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 Td(n,t){let l=new Jt,s=Qo(n,t),e=s.length>0?s.slice():n.sortPoints(s),d=new pt([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 Jn(n,t){let l=new Jt,[s,e]=xd(n,t),d=yd(n,t),i=Fl(n,t),c=Fl(t,n),[o,a]=Ld(n,t),u=Nl(n,t),X=Nl(t,n);return l.I2I=d.isEmpty()?[]:[d],l.I2B=a,l.I2E=i.isEmpty()?[]:[i],l.B2I=o,l.B2B=s,l.B2E=u,l.E2I=c.isEmpty()?[]:[c],l.E2B=X,l}var ma=Object.freeze({__proto__:null,contain:aa,cover:fd,covered:gd,disjoint:oa,equal:ca,inside:Md,intersect:Yd,relate:Ht,touch:ba});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}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 Q.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 Za=(...n)=>new b.Matrix(...n);b.matrix=Za;const Ga=class ts{constructor(t,l){this.low=t,this.high=l}clone(){return new ts(this.low,this.high)}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){return new ts(this.low===void 0?t.low:Math.min(this.low,t.low),this.high===void 0?t.high:Math.max(this.high,t.high))}output(){return[this.low,this.high]}static comparable_max(t,l){return t.merge(l)}static comparable_less_than(t,l){return t<l}},E=0,k=1;class It{constructor(t=void 0,l=void 0,s=null,e=null,d=null,i=k){this.left=s,this.right=e,this.parent=d,this.color=i,this.item={key:t,value:l},t&&t instanceof Array&&t.length==2&&!Number.isNaN(t[0])&&!Number.isNaN(t[1])&&(this.item.key=new Ga(Math.min(t[0],t[1]),Math.max(t[0],t[1]))),this.max=this.item.key?this.item.key.max:void 0}isNil(){return this.item.key===void 0&&this.item.value===void 0&&this.left===null&&this.right===null&&this.color===k}_value_less_than(t){return this.item.value&&t.item.value&&this.item.value.less_than?this.item.value.less_than(t.item.value):this.item.value<t.item.value}less_than(t){return this.item.value===this.item.key&&t.item.value===t.item.key?this.item.key.less_than(t.item.key):this.item.key.less_than(t.item.key)||this.item.key.equal_to(t.item.key)&&this._value_less_than(t)}_value_equal(t){return this.item.value&&t.item.value&&this.item.value.equal_to?this.item.value.equal_to(t.item.value):this.item.value==t.item.value}equal_to(t){return this.item.value===this.item.key&&t.item.value===t.item.key?this.item.key.equal_to(t.item.key):this.item.key.equal_to(t.item.key)&&this._value_equal(t)}intersect(t){return this.item.key.intersect(t.item.key)}copy_data(t){this.item.key=t.item.key,this.item.value=t.item.value}update_max(){if(this.max=this.item.key?this.item.key.max:void 0,this.right&&this.right.max){const t=this.item.key.constructor.comparable_max;this.max=t(this.max,this.right.max)}if(this.left&&this.left.max){const t=this.item.key.constructor.comparable_max;this.max=t(this.max,this.left.max)}}not_intersect_left_subtree(t){const l=this.item.key.constructor.comparable_less_than;let s=this.left.max.high!==void 0?this.left.max.high:this.left.max;return l(s,t.item.key.low)}not_intersect_right_subtree(t){const l=this.item.key.constructor.comparable_less_than;let s=this.right.max.low!==void 0?this.right.max.low:this.right.item.key.low;return l(t.item.key.high,s)}}class ln{constructor(){this.root=null,this.nil_node=new It}get size(){let t=0;return this.tree_walk(this.root,()=>t++),t}get keys(){let t=[];return this.tree_walk(this.root,l=>t.push(l.item.key.output?l.item.key.output():l.item.key)),t}get values(){let t=[];return this.tree_walk(this.root,l=>t.push(l.item.value)),t}get items(){let t=[];return this.tree_walk(this.root,l=>t.push({key:l.item.key.output?l.item.key.output():l.item.key,value:l.item.value})),t}isEmpty(){return this.root==null||this.root==this.nil_node}clear(){this.root=null}insert(t,l=t){if(t===void 0)return;let s=new It(t,l,this.nil_node,this.nil_node,null,E);return this.tree_insert(s),this.recalc_max(s),s}exist(t,l=t){let s=new It(t,l);return!!this.tree_search(this.root,s)}remove(t,l=t){let s=new It(t,l),e=this.tree_search(this.root,s);return e&&this.tree_delete(e),e}search(t,l=(s,e)=>s===e?e.output():s){let s=new It(t),e=[];return this.tree_search_interval(this.root,s,e),e.map(d=>l(d.item.value,d.item.key))}intersect_any(t){let l=new It(t);return this.tree_find_any_interval(this.root,l)}forEach(t){this.tree_walk(this.root,l=>t(l.item.key,l.item.value))}map(t){const l=new ln;return this.tree_walk(this.root,s=>l.insert(s.item.key,t(s.item.value,s.item.key))),l}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_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){let 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=t.parent,l!=null&&l!=this.nil_node&&l.update_max()}rotate_right(t){let 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=t.parent,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 Wa 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=Wa;class Xt{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 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 Q.CANNOT_INVOKE_ABSTRACT_METHOD}toJSON(){return Object.assign({},this,{name:this.name})}svg(t={}){throw Q.CANNOT_INVOKE_ABSTRACT_METHOD}}let Hn=class ui extends Xt{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 ui){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=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`
|
|
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
|
+
${pt({fill:"red",...t})} />`}};b.Point=Nn;const la=(...n)=>new b.Point(...n);b.point=la;let sa=class 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==="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 P.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 P.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 D().rotate(t));throw P.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=sa;const pd=(...n)=>new b.Vector(...n);b.vector=pd;let ea=class ss extends ut{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 P.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 Dt(this,t);if(t instanceof b.Ray)return Yl(t,this);if(t instanceof b.Segment)return Tn(this,t);if(t instanceof b.Circle)return fn(this,t);if(t instanceof b.Box)return Go(this,t);if(t instanceof b.Arc)return Ct(this,t);if(t instanceof b.Polygon)return Sl(this,t);if(t instanceof b.Multiline)return Ft(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 ss(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 ss(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}" ${pt(t)} />`}};b.Segment=ea;const da=(...n)=>new b.Segment(...n);b.segment=da;let{vector:sn}=b,ia=class Zi extends ut{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=Zi.points2norm(l,s),this.norm.dot(sn(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 P.ILLEGAL_PARAMETERS;this.pt=l.clone(),this.norm=s.clone(),this.norm=this.norm.normalize(),this.norm.dot(sn(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 P.ILLEGAL_PARAMETERS;this.pt=s.clone(),this.norm=l.clone(),this.norm=this.norm.normalize(),this.norm.dot(sn(this.pt.x,this.pt.y))>=0&&this.norm.invert();return}}throw P.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(sn(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 sn(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 Tt(this,t);if(t instanceof b.Ray)return td(t,this);if(t instanceof b.Circle)return Wt(this,t);if(t instanceof b.Box)return ft(this,t);if(t instanceof b.Segment)return Dt(t,this);if(t instanceof b.Arc)return Mn(this,t);if(t instanceof b.Polygon)return At(this,t);if(t instanceof b.Multiline)return Ft(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=ft(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 P.ILLEGAL_PARAMETERS;return new b.Vector(t,l).normalize().rotate90CCW()}};b.Line=ia;const ca=(...n)=>new b.Line(...n);b.line=ca;let ba=class extends ut{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 P.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 Wt(t,this);if(t instanceof b.Ray)return $e(t,this);if(t instanceof b.Segment)return fn(t,this);if(t instanceof b.Circle)return we(t,this);if(t instanceof b.Box)return po(this,t);if(t instanceof b.Arc)return Kl(t,this);if(t instanceof b.Polygon)return De(this,t);if(t instanceof b.Multiline)return Ft(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
|
+
${pt({fill:"none",...t})} />`}};b.Circle=ba;const oa=(...n)=>new b.Circle(...n);b.circle=oa;class aa extends ut{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 Mn(t,this);if(t instanceof b.Ray)return gl(t,this);if(t instanceof b.Circle)return Kl(this,t);if(t instanceof b.Segment)return Ct(t,this);if(t instanceof b.Box)return Wo(this,t);if(t instanceof b.Arc)return Ue(this,t);if(t instanceof b.Polygon)return zl(this,t);if(t instanceof b.Multiline)return Ft(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 a=0,X=c;a<4;a++,X=(X+o+4)%4){if(i=l[X],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
|
+
${pt({fill:"none",...t})} />`}}b.Arc=aa;const Xa=(...n)=>new b.Arc(...n);b.arc=Xa;class Pt extends ut{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 Pt(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 Pt(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 Pt(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 P.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 Pt)}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=>Ct(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=ga;class fa extends Kl{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 kt extends fa{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=kt.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=kt.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 kt){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(_e)]);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 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=Mn.NOT_ORIENTABLE:b.Utils.LT(t,0)?this._orientation=Mn.CCW:this._orientation=Mn.CW}return this._orientation}isSimple(t){return kt.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=kt;class kl extends Xt{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 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 Cd(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 Ml(this,t);if(t instanceof b.Arc)return gl(this,t);if(t instanceof b.Line)return md(this,t);if(t instanceof b.Ray)return vo(this,t);if(t instanceof b.Circle)return hd(this,t);if(t instanceof b.Box)return Bo(this,t);if(t instanceof b.Polygon)return Zd(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 Ta=(...n)=>new b.Ray(...n);b.ray=Ta;let dn=class Qt{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.edges].map(t=>t.start)}clone(){let t=new Qt;for(let l of this.faces)t.addFace(l.shapes);return t}isEmpty(){return this.edges.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){let l=this.clone(),s={int_points1:[],int_points2:[],int_points1_sorted:[],int_points2_sorted:[]};for(let i of t.edges)for(let c of l.edges){let o=ud(i,c);for(let a of o)Ct(i,a,s.int_points1),Ct(c,a,s.int_points2)}if(s.int_points1.length===0)return l;s.int_points1_sorted=ut(s.int_points1),s.int_points2_sorted=ut(s.int_points2),Nt(t,s.int_points1_sorted),Nt(l,s.int_points2_sorted),fl(s),s.int_points1_sorted=ut(s.int_points1),s.int_points2_sorted=ut(s.int_points2),Tl(s.int_points1),Cl(s.int_points1,l);for(let i of s.int_points1_sorted)i.edge_before&&i.edge_after&&i.edge_before.bv===i.edge_after.bv&&(s.int_points2[i.id]=-1,i.id=-1);if(s.int_points1=s.int_points1.filter(i=>i.id>=0),s.int_points2=s.int_points2.filter(i=>i.id>=0),s.int_points1.forEach((i,c)=>{i.id=c}),s.int_points2.forEach((i,c)=>{i.id=c}),s.int_points1.length===0)return l;s.int_points1_sorted=ut(s.int_points1),s.int_points2_sorted=ut(s.int_points2);let e,d;for(let i=1;i<s.int_points1_sorted.length;i++)if(d=s.int_points1_sorted[i],e=s.int_points1_sorted[i-1],d.edge_before&&d.edge_before.bv===gn){let c=e.edge_after,o=d.edge_before,a=t.getChain(c,o);Wd(s.int_points2[e.id],s.int_points2[d.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];Wd(s.int_points2[d.id],s.int_points2[e.id],a),a.forEach(u=>l.edges.add(u))}return l.recreateFaces(),l}cutWithLine(t){let l=new pt([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}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===gn||l===$}else return fd(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 Zd(t,this);if(t instanceof b.Circle)return ad(t,this);if(t instanceof b.Segment)return zl(t,this);if(t instanceof b.Arc)return Yl(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 Qt;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 Qt;for(let e of this.faces)s.addFace(e.shapes.map(d=>d.rotate(t,l)));return s}scale(t,l){let s=new Qt;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 Qt;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
|
+
${pt({fill:"none",...t})} />`}}b.Box=Pt;const ua=(...n)=>new b.Box(...n);b.box=ua;class ra{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=nn(t,this.start)),this.bvEnd===void 0&&(this.bvEnd=nn(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=nn(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=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 ${pt({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
|
-
`)
|
|
31
|
-
`))==null?void 0:t.every(l=>l.includes("LINESTRING"))}function Ba(n){return n.startsWith("POINT")||Qd(n)||n.startsWith("LINESTRING")||Bd(n)||n.startsWith("MULTILINESTRING")||n.startsWith("POLYGON")||n.startsWith("MULTIPOINT")||n.startsWith("MULTIPOLYGON")||n.startsWith("GEOMETRYCOLLECTION")}b.isWktString=Ba,b.parseWKT=Pd,b.BooleanOperations=tn,b.Relations=ma;const va=6378137,wa=6378137,Ua=6356752314245179e-9;function kn(n){return n}new N;function ja(n,t=[],l=kn){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 Ea(n,t=[]){return ja(n,t,w._cartographicRadians?kn:ac)}function Oa(n,t,l=kn){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 Aa(n,t){return Oa(n,t,w._cartographicRadians?kn:uc)}const vd=1e-14,Da=new N,wd={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]},bn={east:new N,north:new N,up:new N,west:new N,south:new N,down:new N},_a=new N,qa=new N,$a=new N;function Ud(n,t,l,s,e,d){const i=wd[t]&&wd[t][l];ct(i&&(!s||s===i));let c,o,a;const u=Da.copy(e);if(O(u.x,0,vd)&&O(u.y,0,vd)){const r=Math.sign(u.z);c=_a.fromArray(wl[t]),t!=="east"&&t!=="west"&&c.scale(r),o=qa.fromArray(wl[l]),l!=="east"&&l!=="west"&&o.scale(r),a=$a.fromArray(wl[s]),s!=="east"&&s!=="west"&&a.scale(r)}else{const{up:r,east:m,north:Z}=bn;m.set(-u.y,u.x,0).normalize(),n.geodeticSurfaceNormal(u,r),Z.copy(r).cross(m);const{down:W,west:G,south:p}=bn;W.copy(r).scale(-1),G.copy(m).scale(-1),p.copy(Z).scale(-1),c=bn[t],o=bn[l],a=bn[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]=u.x,d[13]=u.y,d[14]=u.z,d[15]=1,d}const Pt=new N,tu=new N,nu=new N;function lu(n,t,l=[]){const{oneOverRadii:s,oneOverRadiiSquared:e,centerToleranceSquared:d}=t;Pt.from(n);const i=Pt.x,c=Pt.y,o=Pt.z,a=s.x,u=s.y,X=s.z,r=i*i*a*a,m=c*c*u*u,Z=o*o*X*X,W=r+m+Z,G=Math.sqrt(1/W);if(!Number.isFinite(G))return;const p=tu;if(p.copy(n).scale(G),W<d)return p.to(l);const L=e.x,V=e.y,y=e.z,R=nu;R.set(p.x*L*2,p.y*V*2,p.z*y*2);let x=(1-G)*Pt.len()/(.5*R.len()),f=0,M,g,z,J;do{x-=f,M=1/(1+x*L),g=1/(1+x*V),z=1/(1+x*y);const H=M*M,I=g*g,T=z*z,A=H*M,yt=I*g,Lt=T*z;J=r*H+m*I+Z*T-1;const Un=-2*(r*A*L+m*yt*V+Z*Lt*y);f=J/Un}while(Math.abs(J)>yo);return Pt.scale([M,g,z]).to(l)}const Pn=new N,jd=new N,su=new N,_=new N,eu=new N,Qn=new N;class Ed{constructor(t=0,l=0,s=0){this.centerToleranceSquared=Vo,ct(t>=0),ct(l>=0),ct(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=jd,e=su,[,,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]){Qn.from(t);const s=this.scaleToGeodeticSurface(Qn,_);if(!s)return;const e=this.geodeticSurfaceNormal(s,jd),d=eu;d.copy(Qn).subtract(s);const i=Math.atan2(e.y,e.x),c=Math.asin(e.z),o=Math.sign(jt(d,Qn))*Gn(d);return Aa([i,c,o],l)}eastNorthUpToFixedFrame(t,l=new ot){return Ud(this,"east","north","up",t,l)}localFrameToFixedFrame(t,l,s,e,d=new ot){return Ud(this,t,l,s,e,d)}geocentricSurfaceNormal(t,l=[0,0,0]){return Pn.from(t).normalize().to(l)}geodeticSurfaceNormalCartographic(t,l=[0,0,0]){const s=Ea(t),e=s[0],d=s[1],i=Math.cos(d);return Pn.set(i*Math.cos(e),i*Math.sin(e),Math.sin(d)).normalize(),Pn.to(l)}geodeticSurfaceNormal(t,l=[0,0,0]){return Pn.from(t).scale(this.oneOverRadiiSquared).normalize().to(l)}scaleToGeodeticSurface(t,l){return lu(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]){ct(O(this.radii.x,this.radii.y,Lo)),ct(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)}}Ed.WGS84=new Ed(va,wa,Ua);var du=Object.defineProperty,iu=(n,t,l)=>t in n?du(n,t,{enumerable:!0,configurable:!0,writable:!0,value:l}):n[t]=l,P=(n,t,l)=>iu(n,typeof t!="symbol"?t+"":t,l),Bn=(n=>(n[n.x=0]="x",n[n.y=1]="y",n[n.z=2]="z",n))(Bn||{});(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})(Bn||(Bn={}));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;return[d,i]}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(u=>-u)),a}n.getVector=d})(jl||(jl={}));function st(n){switch(n){case 2:return jc;case 3:return x0;case 4:return Ab;case 9:return v0;case 16:return Lb;default:throw new Error(`不支持获取命名空间: ${n}`)}}const cu={4:"transformMat2",6:"transformMat2d",9:"transformMat3",16:"transformMat4"};function El(n,t){const l=st(t),s=cu[n],e=l[s];if(!e)throw new Error(`不支持的矩阵大小:${n}`);return e}const bu={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 bu[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 K=(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))(K||{});const ou={EPSILON:1e-12,debug:!1,precision:4,printTypes:!1,printDegrees:!1,printRowMajor:!0,_cartographicRadians:!1};globalThis.mathgl=globalThis.mathgl||{config:{...ou}},globalThis.mathgl.config;function Od(n,t){return rl(n,t),Xl(n,n)}function et(n,t){const l=t.findIndex(e=>!O(e,0));if(l===-1)return 0;const s=n[l];return O(s,0)?1/0:t[l]/s}function Ad(n,t){const l=t.findIndex(e=>!O(e,0));if(l===-1)return!0;const s=n[l]/t[l];return Bn.getCrossAxiss(l).every(e=>O(t[e]*s,n[e]))}function au(n,t){return O(Rt([],n,t)[2],0)}function uu(n,t){const l=st(n.length).cross([],n,t);return Math.hypot(...l)}function Xu(n,t){return Math.abs(ru(n,t))}function ru(n,t){return Rt([],n,t)[2]}function hu(n,t,l){const s=[...n,...t,...l];return hl(s)}new it,new N,new bt;const vn=[new it,new it,new it,new it],mu=[new N,new N,new N,new N],Zu=[new bt,new bt,new bt,new bt],Al=[new St,new St,new St,new St],Gu=[new ot,new ot,new ot,new ot];new zt,new zt,new zt,new zt,new v,new v,new v,new v;function Dl(n){switch(n){case 2:return vn;case 3:return mu;case 4:return Zu;case 9:return Al;case 16:return Gu;default:throw new Error(`不支持获取临时变量: ${n}`)}}function Dd(n,t){const l=q([],n[1],n[0]),s=q([],t,n[0]);return Rt(l,l,s),O(l[2],0)?0:l[2]}function Wu(n,t){const[l,s]=n,[e,d]=vn;if(e.subVectors(t,l),d.subVectors(s,l),au(d,e)){const i=et(d,e);return i<0||i>1?K.Tangency:K.Contain}return K.Dissociation}function _d(n,t){const[l,s]=n,[e,d]=t,[i,c,o]=Dl(l.length);return c.subVectors(s,l),o.subVectors(d,e),Ad(o,c)?(i.subVectors(e,l),Ad(i,c)?K.Tangency:K.Dissociation):K.Intersect}function pu(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 u=st(s.length),X=u.cross([],c,o);if(O(u.squaredLength(X),0))return null;a.subVectors(d,s);const r=u.cross([],a,o),m=et(X,r);return u.scaleAndAdd(n,s,c,m)}function Vu(n,t,l){const[s,e]=t,[d,i]=l,[c,o,a]=vn;c.subVectors(e,s),o.subVectors(i,d);const u=Rt([],c,o)[2];if(O(u,0))return null;a.subVectors(d,s);const X=Rt([],a,o)[2]/u;return Is(n,s,c,X)}function yu(n,t){const[l,s]=t,[e,d]=n,i=q([],d,e),c=_d(n,t);if(c===K.Tangency){let X=0;return et(i,q([],l,e))<0&&X++,et(i,q([],s,e))<0&&X++,X===2?K.Dissociation:X===0?K.Contain:K.Tangency}if(c!==K.Intersect)return c;const o=Vu([],n,t),a=q([],s,l),u=et(a,q([],o,l));return u<0||u>1||et(i,q([],o,e))<0?K.Dissociation:K.Intersect}function Lu(n,t){const[l,s]=n,[e,d]=t,i=st(l.length),c=i.subtract([],s,l),o=_d(n,t);if(o===K.Tangency){let m=0,Z=0;const W=et(c,i.subtract([],e,l));W<0?m++:W>1&&Z++;const G=et(c,i.subtract([],d,l));return G<0?m++:G>1&&Z++,m===2||Z===2?K.Dissociation:m+Z===1?K.Tangency:K.Contain}if(o!==K.Intersect)return o;const a=pu([],n,t),u=i.subtract([],d,e),X=et(u,i.subtract([],a,e));if(X<0||X>1)return K.Dissociation;if(X===0||X===1)return K.JointIntersect;const r=et(c,i.subtract([],a,l));return r<0||r>1?K.Dissociation:r===0||r===1?K.JointIntersect:K.ThroughIntersect}function xu(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=Dd([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(dl(d,t))return K.Tangency;const i=Dd([d,n[e]],t);if(i===0){s=!0;continue}if(l*i<0)return K.Dissociation;l=i}return s?K.Tangency:K.Contain}function qd(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(dl(i,t))return K.Tangency;let c=d+1;c===s&&(c=0);const o=n[c],a=[i,o];if(Wu(a,t)===K.Contain)return K.Tangency;const u=yu(l,a);if(u===K.Contain){e+=2;continue}if(u===K.Intersect){let X=0;i[1]>t[1]&&X++,o[1]>t[1]&&X++,X===1&&e++}}return e%2===0?K.Dissociation:K.Contain}function $d(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 u=n[a],X=Lu([o,u],t);if(X&(K.ThroughIntersect|K.Tangency|K.Contain))return X;X===K.JointIntersect&&s++}const e=rt(n,t[0]);if(s===0||s===1&&e!==K.Tangency)return e;const d=rt(n,t[1]),i=e|d;return i===K.Tangency?K.Contain:i&K.Tangency?i&K.Contain?K.Contain:K.JointIntersect:e}function Ru(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 u=n[a],X=$d(t,[o,u]);if(X===K.ThroughIntersect)return X;X===K.JointIntersect?s++:X===K.Tangency&&(e=!0)}let d=0;e?d|=K.Tangency:s&&(d|=K.JointIntersect);let i=n.some(c=>rt(t,c)===K.Contain);return i?K.BAContain|d:(i=t.some(c=>qd(n,c)===K.Contain),i?K.ABContain|d:n.some(c=>rt(t,c)===K.Dissociation)?K.Dissociation|d:d)}function Ku(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 u=n[a],X=$d(t,[o,u]);if(X===K.ThroughIntersect)return X;X===K.JointIntersect?s++:X===K.Tangency&&(e=!0)}let d=0;e?d|=K.Tangency:s&&(d|=K.JointIntersect);let i=n.some(c=>rt(t,c)===K.Contain);return i?K.BAContain|d:(i=t.some(c=>rt(n,c)===K.Contain),i?K.ABContain|d:n.some(c=>rt(t,c)===K.Dissociation)?K.Dissociation|d:d)}function Su(n,t,l=["position"]){return n.mapForAggregate(l,s=>qd(t,s))}function zu(n,t,l=["position"]){return n.mapForAggregate(l,s=>rt(t,s))}function Yu(n,t,l=["position"],s,e){const d=e?Ku:Ru;return s?s.map(function(i,c){const o=Mu(i);if(o!==null)return o&K.Contain?o|K.AB:o;const a=n.indices.getVector(c),u=Array.prototype.map.call(a,X=>n.getAggregateVector(l,X));return d(t,u)}):n.mapFace(l,i=>d(t,i))}const ti=K.Dissociation|K.Contain;function Mu(n){return(n&ti)===ti?K.ThroughIntersect:n&K.Contain?n&K.Tangency?K.Contain|K.JointIntersect:K.Contain:null}function gu(n,t,l){const s=wt.getEqualFun(l),e=[];return n.forEach((d,i)=>{s(t,d)&&e.push(i)}),e}const fu=32767,_l=1/fu;function ni(n,t){const[l,s,e]=Tu(n,t);return[l,0,0,0,0,s,0,0,0,0,e,0,n.west,n.south,t[0],1]}function Tu(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]}class ql{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}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=Al[0];t.length===16?Zl(l,t):Od(l,t);const s=El(l.length,this.vectorSize);return this.mapSelf(e=>s(e,e,l))}scale(t){const l=st(this.vectorSize);return this.mapSelf(s=>l.scale(s,s,t))}scaleAndAdd(t,l){const s=st(this.vectorSize);return this.mapSelf(e=>s.scaleAndAdd(e,e,t,l))}add(t){const l=st(this.vectorSize);return this.mapSelf(s=>l.add(s,s,t))}subtract(t){const l=st(this.vectorSize);return this.mapSelf(s=>l.subtract(s,s,t))}multiply(t){const l=st(this.vectorSize);return this.mapSelf(s=>l.multiply(s,s,t))}divide(t){const l=st(this.vectorSize);return this.mapSelf(s=>l.divide(s,s,t))}}function Cu(n){return n.flatMap(t=>[...t])}class Fu{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 ql({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 ql({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(Cu(e),d),s)}transform(t,l){const s=Al[0];l.includes("normal")&&(t.length===16?Zl(s,t):Od(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 li extends Fu{setOptions(t){const{indices:l,...s}=t;super.setOptions(s);const e=l.array?l:{array:l};return this.indices=new ql({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){return Nu(n)/2}function Nu(n){const t=n[0],l=[];for(let d=1;d<n.length;d++){const i=n[d],c=bl([],i,t);l.push(c)}const s=Kt([],l[1],l[0]);let e=Gn(s);Ds(s,s,1/e);for(let d=2;d<l.length;d++)e+=hu(l[d-1],l[d],s);return e}function Ju(n,t,l){const[s,e]=Dl(n.length);return s.subVectors(t,n),e.subVectors(l,n),uu(s,e)}function Hu(n,t,l){const[s,e]=vn;return s.subVectors(t,n),e.subVectors(l,n),Xu(s,e)}function ei(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),u=t(c);s+=Ju(o,a,u)}return s/2}function di(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[u,X,r]=n.slice(a,a+3),[m,Z,W]=t(u),[G,p,L]=t(X),[V,y,R]=t(r),x=Hu([m,Z],[G,p],[V,y]),f=(W+L+R)*o-e;c+=x*Math.min(f,i)}return c/2}const ii=["position"];class Iu{constructor(t){P(this,"geometry"),P(this,"positionNames",ii),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&K.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 dn;return this.geometry.mapFaceForAggregate(this.positionNames,l=>{const s=l.map(e=>new Hn(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=~K.ThroughIntersect&this.relation;this.relationIndexsWithoutThrougn=this.filterFaces(t,this.relationEqual)}updateThroughIndexs(){this.throughIndexs=this.filterFaces(K.ThroughIntersect,wt.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=ei(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 ei(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=di(s,this.getPosition,t);if(this.includingThrough){const[d,i]=t,c=i-d;let o=0;const a=1/3,{geometry:u,positionNames:X}=this;this.throughFaceAreas.forEach((r,m)=>{const Z=this.throughIndexs[m],[W,G,p]=u.getFaceAggregateVector(X,Z),L=(W[2]+G[2]+p[2])*a-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 di(this.geometry.indices.array,this.getPosition,t)}}class ku extends Iu{constructor(){super(...arguments),P(this,"_isConvex",null),P(this,"_polygonOutsideGeometry",null)}get isConvex(){return this._isConvex==null&&(this._isConvex=xu(this.region)),this._isConvex}set isConvex(t){this._isConvex=t}setOptions(t){if(t.region){const l=t.region.map(s=>new Hn(s));this.polygon=new dn(l),this.isZeroPolygon=this.polygon.area()===0}super.setOptions(t)}resetMeasure(){super.resetMeasure(),this._polygonOutsideGeometry=null}generatePositionRelations(){return this.isConvex?zu(this.geometry,this.region,this.positionNames):Su(this.geometry,this.region,this.positionNames)}generateFaceRelations(){return Yu(this.geometry,this.region,this.positionNames,this.positionRelations,this.isConvex)}generateThroughFaces(){const{geometry:t,polygon:l}=this,s=this.relation&K.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 Hn(o[0],o[1])),c=new dn(i);return e(c,l)})}filterFaces(t,l){return gu(this.faceRelations,t,l)}get polygonOutsideGeometry(){return this._polygonOutsideGeometry==null&&(this._polygonOutsideGeometry=this.isZeroPolygon?this.polygon:tn.subtract(this.polygon,this.geometryPolygon)),this._polygonOutsideGeometry}}function Pu(n){const{west:t,east:l,south:s,north:e}=n;return[new it(t,s),new it(t,e),new it(l,e),new it(l,s)]}function Qu(n){const{rectangle:t,heightRange:l,positionNames:s=ii,scale:e}=n,d=new li(n),i=ni(t,l);d.transformForAggregate(i,s);const c=new ku({...n,geometry:d}),o=Pu(t),a=new dn(o),u=tn.subtract(a,c.geometryPolygon),X=c.relationArea+u.area();if(!e)return X;const r=Math.hypot(e[0],e[2])*e[1];return X*Math.abs(r)}function Bu(n){return new Worker(""+new URL("data:text/javascript;base64,dmFyIEwwPU9iamVjdC5kZWZpbmVQcm9wZXJ0eTt2YXIgUDA9KGJ0LHB0LHp0KT0+cHQgaW4gYnQ/TDAoYnQscHQse2VudW1lcmFibGU6ITAsY29uZmlndXJhYmxlOiEwLHdyaXRhYmxlOiEwLHZhbHVlOnp0fSk6YnRbcHRdPXp0O3ZhciBxPShidCxwdCx6dCk9PlAwKGJ0LHR5cGVvZiBwdCE9InN5bWJvbCI/cHQrIiI6cHQsenQpOyhmdW5jdGlvbigpeyJ1c2Ugc3RyaWN0IjtmdW5jdGlvbiBidChlKXt2YXIgdD1lO3JldHVybiBlIT1udWxsJiYodD1lLmNvbnN0cnVjdG9yLHQ9PW51bGwmJih0PXR5cGVvZiBlKSksdH1mdW5jdGlvbiBwdChlKXt2YXIgdD10eXBlb2YgZTtyZXR1cm4gZT09bnVsbHx8dCE9PSJvYmplY3QiJiZ0IT09ImZ1bmN0aW9uIn1mdW5jdGlvbiB6dChlKXtyZXR1cm4gZSYmdHlwZW9mIGVbU3ltYm9sLml0ZXJhdG9yXT09ImZ1bmN0aW9uIn12YXIgc2U9KGU9PihlLmVxdWFsPSJlcXVhbCIsZS5pbnRlcnNlY3Q9ImludGVyc2VjdCIsZS5pbnRlcnNlY3RFcXVhbD0iaW50ZXJzZWN0RXF1YWwiLGUpKShzZXx8e30pOyhlPT57ZnVuY3Rpb24gdChuKXtsZXQgcjtzd2l0Y2gobil7Y2FzZSJlcXVhbCI6cj0oaSxzKT0+aT09PXM7Y2FzZSJpbnRlcnNlY3QiOnI9KGkscyk9PmkmcztkZWZhdWx0OnI9KGkscyk9PihpJnMpPT09aX1yZXR1cm4gcn1lLmdldEVxdWFsRnVuPXR9KShzZXx8KHNlPXt9KSk7ZnVuY3Rpb24gTnIoKXtjb25zdCBlPWdsb2JhbFRoaXMuY3VycmVudFdvcmtlclR5cGU7aWYoZSlyZXR1cm4gZTtsZXQgdD1nbG9iYWxUaGlzLlNoYXJlZFdvcmtlckdsb2JhbFNjb3BlO3JldHVybiB0eXBlb2YgdD09ImZ1bmN0aW9uIiYmZ2xvYmFsVGhpcyBpbnN0YW5jZW9mIHQ/Z2xvYmFsVGhpcy5jdXJyZW50V29ya2VyVHlwZT0iU2hhcmVkV29ya2VyIjoodD1nbG9iYWxUaGlzLkRlZGljYXRlZFdvcmtlckdsb2JhbFNjb3BlLHR5cGVvZiB0PT0iZnVuY3Rpb24iJiZnbG9iYWxUaGlzIGluc3RhbmNlb2YgdD9nbG9iYWxUaGlzLmN1cnJlbnRXb3JrZXJUeXBlPSJEZWRpY2F0ZWRXb3JrZXIiOih0PWdsb2JhbFRoaXMuV2luZG93LHR5cGVvZiB0PT0iZnVuY3Rpb24iJiZnbG9iYWxUaGlzIGluc3RhbmNlb2YgdD9nbG9iYWxUaGlzLmN1cnJlbnRXb3JrZXJUeXBlPSJXaW5kb3ciOmdsb2JhbFRoaXMuY3VycmVudFdvcmtlclR5cGU9InVua25vd24iKSl9ZnVuY3Rpb24gV28oZSx0LG4pe2NvbnN0IHI9LyheXHMqKGFzeW5jXHMrKT9mdW5jdGlvblxzKihcc3xcKilccyopW0EtWmEtel8kXStbXHckXSooXHMqXCgpLyxpPS9eW0EtWmEtel8kXStbXHckXSokLyxzPXIudGVzdChlKSxvPXQmJmkudGVzdCh0KTtpZihzJiZvJiYoZT1lLnJlcGxhY2UocixgJDEke3R9JDRgKSksIXMmJm8pdmFyIGM9YHZhciAke3R9ID0gJHtlfSA7IHJldHVybiAke3R9YDtlbHNlIGM9YHJldHVybiAoJHtlfSlgO3JldHVybiBuZXcgRnVuY3Rpb24oYykoKX1mdW5jdGlvbiAkcihlKXtjb25zdHtuYW1lOnQsYXJnczpuLHRoaXM6cn09ZSxpPXI/P2dsb2JhbFRoaXMscz1nbG9iYWxUaGlzW3RdO3JldHVybiB0eXBlb2Ygcz09ImZ1bmN0aW9uIj9zLmFwcGx5KGksbik6bnx8cj97ZXJyb3I6IuWHveaVsOS4jeWtmOWcqCIsc3RhdGU6Iue7k+adnyJ9OntkYXRhOnMsc3RhdGU6Iue7k+adnyJ9fWZ1bmN0aW9uIHpyKGUpe2NvbnN0IHQ9YnQoZSk7aWYodD09PSJvYmplY3QifHx0PT09T2JqZWN0KXtjb25zdHt0cmFuc2ZlcjpuLHRhcmdldE9yaWdpbjpyfT1lO3JldHVybiJkYXRhImluIGV8fCJlcnJvciJpbiBlfHxBcnJheS5pc0FycmF5KG4pfHx0eXBlb2Ygcj09InN0cmluZyJ9cmV0dXJuITF9ZnVuY3Rpb24gUGUoZSx0KXtjb25zdHtkYXRhOm4sLi4ucn09enIoZSk/ZTp7ZGF0YTplfSxpPXsuLi50LC4uLnJ9O2lmKG4gaW5zdGFuY2VvZiBSZWFkYWJsZVN0cmVhbSl7Y29uc3Qgcz1uZXcgV3JpdGFibGVTdHJlYW0oe3dyaXRlOmZ1bmN0aW9uKG8sYyl7cmV0dXJuIFBlKG8sey4uLmksc3RhdGU6Iui/m+ihjOS4rSJ9KX0sY2xvc2U6ZnVuY3Rpb24obyl7UmUodm9pZCAwLHtzdGF0ZToi57uT5p2fIiwuLi5pfSl9LGFib3J0OmZ1bmN0aW9uKG8pe1JlKHZvaWQgMCx7c3RhdGU6Iue7k+adnyIsLi4uaSxlcnJvcjpvfSl9fSk7cmV0dXJuIG4ucGlwZVRvKHMpfXJldHVybiBuIGluc3RhbmNlb2YgUHJvbWlzZT9uLnRoZW4oZnVuY3Rpb24ocyl7UGUocyx7c3RhdGU6Iue7k+adnyIsLi4uaX0pfSxmdW5jdGlvbihzKXtSZSh2b2lkIDAsey4uLmksZXJyb3I6cyxzdGF0ZToi57uT5p2fIn0pfSk6UmUobix7c3RhdGU6Iue7k+adnyIsLi4uaX0pfWZ1bmN0aW9uIFJlKGUsdCl7Y29uc3R7cG9ydDpuLC4uLnJ9PXQse3RyYW5zZmVyOmksdGFyZ2V0T3JpZ2luOnMsLi4ub309enIoZSk/ey4uLnIsLi4uZX06ey4uLnIsZGF0YTplfTtvLnN0YXRlPT1udWxsJiYoby5zdGF0ZT0i57uT5p2fIik7Y29uc3QgYz17dHJhbnNmZXI6aSx0YXJnZXRPcmlnaW46c307cmV0dXJuKG4/P2dsb2JhbFRoaXMpLnBvc3RNZXNzYWdlKG8sYyl9ZnVuY3Rpb24ga3IoZSl7Y29uc3QgdD1lLmRhdGEsbj1lLmN1cnJlbnRUYXJnZXQ7aWYodCl7Y29uc3Qgcj0kcih0KTtQZShyLHtleGVjSWQ6dC5pZCxwb3J0Om59KX19ZnVuY3Rpb24gWm8oZSx0KXtjb25zdCBuPVdvKGUsdCk7cmV0dXJuIHQ9dD8/bi5uYW1lLGdsb2JhbFRoaXNbdF09biwhMH1mdW5jdGlvbiBHbyhlKXtyZXR1cm4gZGVsZXRlIGdsb2JhbFRoaXNbZV19ZnVuY3Rpb24gWG8oZSl7c3dpdGNoKE5yKCkpe2Nhc2UiU2hhcmVkV29ya2VyIjp7Z2xvYmFsVGhpcy5hZGRFdmVudExpc3RlbmVyKCJjb25uZWN0IixmdW5jdGlvbih0KXtmb3IoY29uc3QgbiBvZiB0LnBvcnRzKW4uYWRkRXZlbnRMaXN0ZW5lcigibWVzc2FnZSIsZSksbi5zdGFydCgpfSk7YnJlYWt9ZGVmYXVsdDpnbG9iYWxUaGlzLmFkZEV2ZW50TGlzdGVuZXIoIm1lc3NhZ2UiLGUpfX1nbG9iYWxUaGlzLmxpc3Rlbk1lc3NhZ2V8fChnbG9iYWxUaGlzLmxpc3Rlbk1lc3NhZ2U9WG8pLE9iamVjdC5hc3NpZ24oZ2xvYmFsVGhpcyx7ZXhlY0NNRDokcixtZXNzYWdlTGlzdGVuZXI6a3Isc2V0Q01EOlpvLHJlbW92ZUNNRDpHbyxzZW5kTWVzc2FnZTpQZX0pLE5yKCksbGlzdGVuTWVzc2FnZShrcik7dmFyIF90PShlPT4oZVtlLng9MF09IngiLGVbZS55PTFdPSJ5IixlW2Uuej0yXT0ieiIsZSkpKF90fHx7fSk7KGU9PntmdW5jdGlvbiB0KGkpe3JldHVybiBlW2ldfWUudG9LZXk9dDtmdW5jdGlvbiBuKGkpe3JldHVybiBlW2ldfWUudG9JbmRleD1uO2Z1bmN0aW9uIHIoaSl7Y29uc3Qgcz0oaSsxKSUzLG89KGkrMiklMztyZXR1cm5bcyxvXX1lLmdldENyb3NzQXhpc3M9cn0pKF90fHwoX3Q9e30pKTt2YXIgQ2U9KGU9PihlW2UueD0wXT0ieCIsZVtlLnk9MV09InkiLGVbZS56PTJdPSJ6IixlW2Uudz0zXT0idyIsZSkpKENlfHx7fSk7KGU9PntmdW5jdGlvbiB0KGkpe3JldHVybiBlW2ldfWUudG9LZXk9dDtmdW5jdGlvbiBuKGkpe3JldHVybiBlW2ldfWUudG9JbmRleD1uO2Z1bmN0aW9uIHIoaSl7Y29uc3Qgcz0oaSsxKSU0LG89KGkrMiklNDtyZXR1cm5bcyxvXX1lLmdldENyb3NzQXhpc3M9cn0pKENlfHwoQ2U9e30pKTt2YXIgc3Q9KGU9PihlW2UuZWFzdD0wXT0iZWFzdCIsZVtlLndlc3Q9MV09Indlc3QiLGVbZS5ub3J0aD0yXT0ibm9ydGgiLGVbZS5zb3V0aD0zXT0ic291dGgiLGVbZS51cD00XT0idXAiLGVbZS5kb3duPTVdPSJkb3duIixlKSkoc3R8fHt9KTsoZT0+e2Z1bmN0aW9uIHQobyl7cmV0dXJuIGVbb119ZS50b0tleT10O2Z1bmN0aW9uIG4obyl7cmV0dXJuIGVbb119ZS50b0luZGV4PW47ZnVuY3Rpb24gcihvKXtyZXR1cm4gbyUyPT09MD9vKzE6by0xfWUucmV2ZXJzZT1yO2Z1bmN0aW9uIGkobyl7cmV0dXJuIG8lMj09PTA/MTotMX1lLmdldFZlY3RvclNpZ249aTtmdW5jdGlvbiBzKG8sYyl7bGV0IGw9dChvKSxoPWNbbF07cmV0dXJuIGh8fChsPXQocihvKSksaD1jW2xdLGg9aC5tYXAoZj0+LWYpKSxofWUuZ2V0VmVjdG9yPXN9KShzdHx8KHN0PXt9KSk7Y29uc3Qgam89MS9NYXRoLlBJKjE4MCxRbz0xLzE4MCpNYXRoLlBJLEtvPXtFUFNJTE9OOjFlLTEyLGRlYnVnOiExLHByZWNpc2lvbjo0LHByaW50VHlwZXM6ITEscHJpbnREZWdyZWVzOiExLHByaW50Um93TWFqb3I6ITAsX2NhcnRvZ3JhcGhpY1JhZGlhbnM6ITF9O2dsb2JhbFRoaXMubWF0aGdsPWdsb2JhbFRoaXMubWF0aGdsfHx7Y29uZmlnOnsuLi5Lb319O2NvbnN0IFo9Z2xvYmFsVGhpcy5tYXRoZ2wuY29uZmlnO2Z1bmN0aW9uIEpvKGUse3ByZWNpc2lvbjp0PVoucHJlY2lzaW9ufT17fSl7cmV0dXJuIGU9bmMoZSksYCR7cGFyc2VGbG9hdChlLnRvUHJlY2lzaW9uKHQpKX1gfWZ1bmN0aW9uIEl0KGUpe3JldHVybiBBcnJheS5pc0FycmF5KGUpfHxBcnJheUJ1ZmZlci5pc1ZpZXcoZSkmJiEoZSBpbnN0YW5jZW9mIERhdGFWaWV3KX1mdW5jdGlvbiBvZShlKXtyZXR1cm4gdGMoZSl9ZnVuY3Rpb24gSG8oZSl7cmV0dXJuIGVjKGUpfWZ1bmN0aW9uIHRjKGUsdCl7cmV0dXJuIHduKGUsbj0+bipRbyx0KX1mdW5jdGlvbiBlYyhlLHQpe3JldHVybiB3bihlLG49Pm4qam8sdCl9ZnVuY3Rpb24ga3QoZSx0LG4pe3JldHVybiB3bihlLHI9Pk1hdGgubWF4KHQsTWF0aC5taW4obixyKSkpfWZ1bmN0aW9uIGsoZSx0LG4pe2NvbnN0IHI9Wi5FUFNJTE9OO24mJihaLkVQU0lMT049bik7dHJ5e2lmKGU9PT10KXJldHVybiEwO2lmKEl0KGUpJiZJdCh0KSl7aWYoZS5sZW5ndGghPT10Lmxlbmd0aClyZXR1cm4hMTtmb3IobGV0IGk9MDtpPGUubGVuZ3RoOysraSlpZighayhlW2ldLHRbaV0pKXJldHVybiExO3JldHVybiEwfXJldHVybiBlJiZlLmVxdWFscz9lLmVxdWFscyh0KTp0JiZ0LmVxdWFscz90LmVxdWFscyhlKTp0eXBlb2YgZT09Im51bWJlciImJnR5cGVvZiB0PT0ibnVtYmVyIj9NYXRoLmFicyhlLXQpPD1aLkVQU0lMT04qTWF0aC5tYXgoMSxNYXRoLmFicyhlKSxNYXRoLmFicyh0KSk6ITF9ZmluYWxseXtaLkVQU0lMT049cn19ZnVuY3Rpb24gbmMoZSl7cmV0dXJuIE1hdGgucm91bmQoZS9aLkVQU0lMT04pKlouRVBTSUxPTn1mdW5jdGlvbiByYyhlKXtyZXR1cm4gZS5jbG9uZT9lLmNsb25lKCk6bmV3IEFycmF5KGUubGVuZ3RoKX1mdW5jdGlvbiB3bihlLHQsbil7aWYoSXQoZSkpe2NvbnN0IHI9ZTtuPW58fHJjKHIpO2ZvcihsZXQgaT0wO2k8bi5sZW5ndGgmJmk8ci5sZW5ndGg7KytpKXtjb25zdCBzPXR5cGVvZiBlPT0ibnVtYmVyIj9lOmVbaV07bltpXT10KHMsaSxuKX1yZXR1cm4gbn1yZXR1cm4gdChlKX1jbGFzcyBjZSBleHRlbmRzIEFycmF5e2Nsb25lKCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKCkuY29weSh0aGlzKX1mcm9tQXJyYXkodCxuPTApe2ZvcihsZXQgcj0wO3I8dGhpcy5FTEVNRU5UUzsrK3IpdGhpc1tyXT10W3Irbl07cmV0dXJuIHRoaXMuY2hlY2soKX10b0FycmF5KHQ9W10sbj0wKXtmb3IobGV0IHI9MDtyPHRoaXMuRUxFTUVOVFM7KytyKXRbbityXT10aGlzW3JdO3JldHVybiB0fXRvT2JqZWN0KHQpe3JldHVybiB0fWZyb20odCl7cmV0dXJuIEFycmF5LmlzQXJyYXkodCk/dGhpcy5jb3B5KHQpOnRoaXMuZnJvbU9iamVjdCh0KX10byh0KXtyZXR1cm4gdD09PXRoaXM/dGhpczpJdCh0KT90aGlzLnRvQXJyYXkodCk6dGhpcy50b09iamVjdCh0KX10b1RhcmdldCh0KXtyZXR1cm4gdD90aGlzLnRvKHQpOnRoaXN9dG9GbG9hdDMyQXJyYXkoKXtyZXR1cm4gbmV3IEZsb2F0MzJBcnJheSh0aGlzKX10b1N0cmluZygpe3JldHVybiB0aGlzLmZvcm1hdFN0cmluZyhaKX1mb3JtYXRTdHJpbmcodCl7bGV0IG49IiI7Zm9yKGxldCByPTA7cjx0aGlzLkVMRU1FTlRTOysrciluKz0ocj4wPyIsICI6IiIpK0pvKHRoaXNbcl0sdCk7cmV0dXJuYCR7dC5wcmludFR5cGVzP3RoaXMuY29uc3RydWN0b3IubmFtZToiIn1bJHtufV1gfWVxdWFscyh0KXtpZighdHx8dGhpcy5sZW5ndGghPT10Lmxlbmd0aClyZXR1cm4hMTtmb3IobGV0IG49MDtuPHRoaXMuRUxFTUVOVFM7KytuKWlmKCFrKHRoaXNbbl0sdFtuXSkpcmV0dXJuITE7cmV0dXJuITB9ZXhhY3RFcXVhbHModCl7aWYoIXR8fHRoaXMubGVuZ3RoIT09dC5sZW5ndGgpcmV0dXJuITE7Zm9yKGxldCBuPTA7bjx0aGlzLkVMRU1FTlRTOysrbilpZih0aGlzW25dIT09dFtuXSlyZXR1cm4hMTtyZXR1cm4hMH1uZWdhdGUoKXtmb3IobGV0IHQ9MDt0PHRoaXMuRUxFTUVOVFM7Kyt0KXRoaXNbdF09LXRoaXNbdF07cmV0dXJuIHRoaXMuY2hlY2soKX1sZXJwKHQsbixyKXtpZihyPT09dm9pZCAwKXJldHVybiB0aGlzLmxlcnAodGhpcyx0LG4pO2ZvcihsZXQgaT0wO2k8dGhpcy5FTEVNRU5UUzsrK2kpe2NvbnN0IHM9dFtpXSxvPXR5cGVvZiBuPT0ibnVtYmVyIj9uOm5baV07dGhpc1tpXT1zK3IqKG8tcyl9cmV0dXJuIHRoaXMuY2hlY2soKX1taW4odCl7Zm9yKGxldCBuPTA7bjx0aGlzLkVMRU1FTlRTOysrbil0aGlzW25dPU1hdGgubWluKHRbbl0sdGhpc1tuXSk7cmV0dXJuIHRoaXMuY2hlY2soKX1tYXgodCl7Zm9yKGxldCBuPTA7bjx0aGlzLkVMRU1FTlRTOysrbil0aGlzW25dPU1hdGgubWF4KHRbbl0sdGhpc1tuXSk7cmV0dXJuIHRoaXMuY2hlY2soKX1jbGFtcCh0LG4pe2ZvcihsZXQgcj0wO3I8dGhpcy5FTEVNRU5UUzsrK3IpdGhpc1tyXT1NYXRoLm1pbihNYXRoLm1heCh0aGlzW3JdLHRbcl0pLG5bcl0pO3JldHVybiB0aGlzLmNoZWNrKCl9YWRkKC4uLnQpe2Zvcihjb25zdCBuIG9mIHQpZm9yKGxldCByPTA7cjx0aGlzLkVMRU1FTlRTOysrcil0aGlzW3JdKz1uW3JdO3JldHVybiB0aGlzLmNoZWNrKCl9c3VidHJhY3QoLi4udCl7Zm9yKGNvbnN0IG4gb2YgdClmb3IobGV0IHI9MDtyPHRoaXMuRUxFTUVOVFM7KytyKXRoaXNbcl0tPW5bcl07cmV0dXJuIHRoaXMuY2hlY2soKX1zY2FsZSh0KXtpZih0eXBlb2YgdD09Im51bWJlciIpZm9yKGxldCBuPTA7bjx0aGlzLkVMRU1FTlRTOysrbil0aGlzW25dKj10O2Vsc2UgZm9yKGxldCBuPTA7bjx0aGlzLkVMRU1FTlRTJiZuPHQubGVuZ3RoOysrbil0aGlzW25dKj10W25dO3JldHVybiB0aGlzLmNoZWNrKCl9bXVsdGlwbHlCeVNjYWxhcih0KXtmb3IobGV0IG49MDtuPHRoaXMuRUxFTUVOVFM7KytuKXRoaXNbbl0qPXQ7cmV0dXJuIHRoaXMuY2hlY2soKX1jaGVjaygpe2lmKFouZGVidWcmJiF0aGlzLnZhbGlkYXRlKCkpdGhyb3cgbmV3IEVycm9yKGBtYXRoLmdsOiAke3RoaXMuY29uc3RydWN0b3IubmFtZX0gc29tZSBmaWVsZHMgc2V0IHRvIGludmFsaWQgbnVtYmVycydgKTtyZXR1cm4gdGhpc312YWxpZGF0ZSgpe2xldCB0PXRoaXMubGVuZ3RoPT09dGhpcy5FTEVNRU5UUztmb3IobGV0IG49MDtuPHRoaXMuRUxFTUVOVFM7KytuKXQ9dCYmTnVtYmVyLmlzRmluaXRlKHRoaXNbbl0pO3JldHVybiB0fXN1Yih0KXtyZXR1cm4gdGhpcy5zdWJ0cmFjdCh0KX1zZXRTY2FsYXIodCl7Zm9yKGxldCBuPTA7bjx0aGlzLkVMRU1FTlRTOysrbil0aGlzW25dPXQ7cmV0dXJuIHRoaXMuY2hlY2soKX1hZGRTY2FsYXIodCl7Zm9yKGxldCBuPTA7bjx0aGlzLkVMRU1FTlRTOysrbil0aGlzW25dKz10O3JldHVybiB0aGlzLmNoZWNrKCl9c3ViU2NhbGFyKHQpe3JldHVybiB0aGlzLmFkZFNjYWxhcigtdCl9bXVsdGlwbHlTY2FsYXIodCl7Zm9yKGxldCBuPTA7bjx0aGlzLkVMRU1FTlRTOysrbil0aGlzW25dKj10O3JldHVybiB0aGlzLmNoZWNrKCl9ZGl2aWRlU2NhbGFyKHQpe3JldHVybiB0aGlzLm11bHRpcGx5QnlTY2FsYXIoMS90KX1jbGFtcFNjYWxhcih0LG4pe2ZvcihsZXQgcj0wO3I8dGhpcy5FTEVNRU5UUzsrK3IpdGhpc1tyXT1NYXRoLm1pbihNYXRoLm1heCh0aGlzW3JdLHQpLG4pO3JldHVybiB0aGlzLmNoZWNrKCl9Z2V0IGVsZW1lbnRzKCl7cmV0dXJuIHRoaXN9fWZ1bmN0aW9uIGljKGUsdCl7aWYoZS5sZW5ndGghPT10KXJldHVybiExO2ZvcihsZXQgbj0wO248ZS5sZW5ndGg7KytuKWlmKCFOdW1iZXIuaXNGaW5pdGUoZVtuXSkpcmV0dXJuITE7cmV0dXJuITB9ZnVuY3Rpb24gUChlKXtpZighTnVtYmVyLmlzRmluaXRlKGUpKXRocm93IG5ldyBFcnJvcihgSW52YWxpZCBudW1iZXIgJHtKU09OLnN0cmluZ2lmeShlKX1gKTtyZXR1cm4gZX1mdW5jdGlvbiBhZShlLHQsbj0iIil7aWYoWi5kZWJ1ZyYmIWljKGUsdCkpdGhyb3cgbmV3IEVycm9yKGBtYXRoLmdsOiAke259IHNvbWUgZmllbGRzIHNldCB0byBpbnZhbGlkIG51bWJlcnMnYCk7cmV0dXJuIGV9ZnVuY3Rpb24gd3QoZSx0KXtpZighZSl0aHJvdyBuZXcgRXJyb3IoYG1hdGguZ2wgYXNzZXJ0aW9uICR7dH1gKX1sZXQgVmU9Y2xhc3MgZXh0ZW5kcyBjZXtnZXQgeCgpe3JldHVybiB0aGlzWzBdfXNldCB4KHQpe3RoaXNbMF09UCh0KX1nZXQgeSgpe3JldHVybiB0aGlzWzFdfXNldCB5KHQpe3RoaXNbMV09UCh0KX1sZW4oKXtyZXR1cm4gTWF0aC5zcXJ0KHRoaXMubGVuZ3RoU3F1YXJlZCgpKX1tYWduaXR1ZGUoKXtyZXR1cm4gdGhpcy5sZW4oKX1sZW5ndGhTcXVhcmVkKCl7bGV0IHQ9MDtmb3IobGV0IG49MDtuPHRoaXMuRUxFTUVOVFM7KytuKXQrPXRoaXNbbl0qdGhpc1tuXTtyZXR1cm4gdH1tYWduaXR1ZGVTcXVhcmVkKCl7cmV0dXJuIHRoaXMubGVuZ3RoU3F1YXJlZCgpfWRpc3RhbmNlKHQpe3JldHVybiBNYXRoLnNxcnQodGhpcy5kaXN0YW5jZVNxdWFyZWQodCkpfWRpc3RhbmNlU3F1YXJlZCh0KXtsZXQgbj0wO2ZvcihsZXQgcj0wO3I8dGhpcy5FTEVNRU5UUzsrK3Ipe2NvbnN0IGk9dGhpc1tyXS10W3JdO24rPWkqaX1yZXR1cm4gUChuKX1kb3QodCl7bGV0IG49MDtmb3IobGV0IHI9MDtyPHRoaXMuRUxFTUVOVFM7KytyKW4rPXRoaXNbcl0qdFtyXTtyZXR1cm4gUChuKX1ub3JtYWxpemUoKXtjb25zdCB0PXRoaXMubWFnbml0dWRlKCk7aWYodCE9PTApZm9yKGxldCBuPTA7bjx0aGlzLkVMRU1FTlRTOysrbil0aGlzW25dLz10O3JldHVybiB0aGlzLmNoZWNrKCl9bXVsdGlwbHkoLi4udCl7Zm9yKGNvbnN0IG4gb2YgdClmb3IobGV0IHI9MDtyPHRoaXMuRUxFTUVOVFM7KytyKXRoaXNbcl0qPW5bcl07cmV0dXJuIHRoaXMuY2hlY2soKX1kaXZpZGUoLi4udCl7Zm9yKGNvbnN0IG4gb2YgdClmb3IobGV0IHI9MDtyPHRoaXMuRUxFTUVOVFM7KytyKXRoaXNbcl0vPW5bcl07cmV0dXJuIHRoaXMuY2hlY2soKX1sZW5ndGhTcSgpe3JldHVybiB0aGlzLmxlbmd0aFNxdWFyZWQoKX1kaXN0YW5jZVRvKHQpe3JldHVybiB0aGlzLmRpc3RhbmNlKHQpfWRpc3RhbmNlVG9TcXVhcmVkKHQpe3JldHVybiB0aGlzLmRpc3RhbmNlU3F1YXJlZCh0KX1nZXRDb21wb25lbnQodCl7cmV0dXJuIHd0KHQ+PTAmJnQ8dGhpcy5FTEVNRU5UUywiaW5kZXggaXMgb3V0IG9mIHJhbmdlIiksUCh0aGlzW3RdKX1zZXRDb21wb25lbnQodCxuKXtyZXR1cm4gd3QodD49MCYmdDx0aGlzLkVMRU1FTlRTLCJpbmRleCBpcyBvdXQgb2YgcmFuZ2UiKSx0aGlzW3RdPW4sdGhpcy5jaGVjaygpfWFkZFZlY3RvcnModCxuKXtyZXR1cm4gdGhpcy5jb3B5KHQpLmFkZChuKX1zdWJWZWN0b3JzKHQsbil7cmV0dXJuIHRoaXMuY29weSh0KS5zdWJ0cmFjdChuKX1tdWx0aXBseVZlY3RvcnModCxuKXtyZXR1cm4gdGhpcy5jb3B5KHQpLm11bHRpcGx5KG4pfWFkZFNjYWxlZFZlY3Rvcih0LG4pe3JldHVybiB0aGlzLmFkZChuZXcgdGhpcy5jb25zdHJ1Y3Rvcih0KS5tdWx0aXBseVNjYWxhcihuKSl9fTtjb25zdCBDPTFlLTY7bGV0IEQ9dHlwZW9mIEZsb2F0MzJBcnJheTwidSI/RmxvYXQzMkFycmF5OkFycmF5O2NvbnN0IFN0PU1hdGgucmFuZG9tO2Z1bmN0aW9uIHl0KGUpe3JldHVybiBlPj0wP01hdGgucm91bmQoZSk6ZSUuNT09PTA/TWF0aC5mbG9vcihlKTpNYXRoLnJvdW5kKGUpfWZ1bmN0aW9uIEZyKCl7Y29uc3QgZT1uZXcgRCgyKTtyZXR1cm4gRCE9RmxvYXQzMkFycmF5JiYoZVswXT0wLGVbMV09MCksZX1mdW5jdGlvbiBzYyhlKXtjb25zdCB0PW5ldyBEKDIpO3JldHVybiB0WzBdPWVbMF0sdFsxXT1lWzFdLHR9ZnVuY3Rpb24gb2MoZSx0KXtjb25zdCBuPW5ldyBEKDIpO3JldHVybiBuWzBdPWUsblsxXT10LG59ZnVuY3Rpb24gY2MoZSx0KXtyZXR1cm4gZVswXT10WzBdLGVbMV09dFsxXSxlfWZ1bmN0aW9uIGFjKGUsdCxuKXtyZXR1cm4gZVswXT10LGVbMV09bixlfWZ1bmN0aW9uIHFyKGUsdCxuKXtyZXR1cm4gZVswXT10WzBdK25bMF0sZVsxXT10WzFdK25bMV0sZX1mdW5jdGlvbiBHKGUsdCxuKXtyZXR1cm4gZVswXT10WzBdLW5bMF0sZVsxXT10WzFdLW5bMV0sZX1mdW5jdGlvbiBVcihlLHQsbil7cmV0dXJuIGVbMF09dFswXSpuWzBdLGVbMV09dFsxXSpuWzFdLGV9ZnVuY3Rpb24gQW4oZSx0LG4pe3JldHVybiBlWzBdPXRbMF0vblswXSxlWzFdPXRbMV0vblsxXSxlfWZ1bmN0aW9uIGxjKGUsdCl7cmV0dXJuIGVbMF09TWF0aC5jZWlsKHRbMF0pLGVbMV09TWF0aC5jZWlsKHRbMV0pLGV9ZnVuY3Rpb24gaGMoZSx0KXtyZXR1cm4gZVswXT1NYXRoLmZsb29yKHRbMF0pLGVbMV09TWF0aC5mbG9vcih0WzFdKSxlfWZ1bmN0aW9uIGZjKGUsdCxuKXtyZXR1cm4gZVswXT1NYXRoLm1pbih0WzBdLG5bMF0pLGVbMV09TWF0aC5taW4odFsxXSxuWzFdKSxlfWZ1bmN0aW9uIHVjKGUsdCxuKXtyZXR1cm4gZVswXT1NYXRoLm1heCh0WzBdLG5bMF0pLGVbMV09TWF0aC5tYXgodFsxXSxuWzFdKSxlfWZ1bmN0aW9uIGRjKGUsdCl7cmV0dXJuIGVbMF09eXQodFswXSksZVsxXT15dCh0WzFdKSxlfWZ1bmN0aW9uIERyKGUsdCxuKXtyZXR1cm4gZVswXT10WzBdKm4sZVsxXT10WzFdKm4sZX1mdW5jdGlvbiBCcihlLHQsbixyKXtyZXR1cm4gZVswXT10WzBdK25bMF0qcixlWzFdPXRbMV0rblsxXSpyLGV9ZnVuY3Rpb24gWXIoZSx0KXtjb25zdCBuPXRbMF0tZVswXSxyPXRbMV0tZVsxXTtyZXR1cm4gTWF0aC5zcXJ0KG4qbityKnIpfWZ1bmN0aW9uIE5lKGUsdCl7Y29uc3Qgbj10WzBdLWVbMF0scj10WzFdLWVbMV07cmV0dXJuIG4qbityKnJ9ZnVuY3Rpb24gV3IoZSl7Y29uc3QgdD1lWzBdLG49ZVsxXTtyZXR1cm4gTWF0aC5zcXJ0KHQqdCtuKm4pfWZ1bmN0aW9uIFpyKGUpe2NvbnN0IHQ9ZVswXSxuPWVbMV07cmV0dXJuIHQqdCtuKm59ZnVuY3Rpb24gZ2MoZSx0KXtyZXR1cm4gZVswXT0tdFswXSxlWzFdPS10WzFdLGV9ZnVuY3Rpb24gbWMoZSx0KXtyZXR1cm4gZVswXT0xL3RbMF0sZVsxXT0xL3RbMV0sZX1mdW5jdGlvbiBwYyhlLHQpe2NvbnN0IG49dFswXSxyPXRbMV07bGV0IGk9bipuK3IqcjtyZXR1cm4gaT4wJiYoaT0xL01hdGguc3FydChpKSksZVswXT10WzBdKmksZVsxXT10WzFdKmksZX1mdW5jdGlvbiBfYyhlLHQpe3JldHVybiBlWzBdKnRbMF0rZVsxXSp0WzFdfWZ1bmN0aW9uIEZ0KGUsdCxuKXtjb25zdCByPXRbMF0qblsxXS10WzFdKm5bMF07cmV0dXJuIGVbMF09ZVsxXT0wLGVbMl09cixlfWZ1bmN0aW9uIEdyKGUsdCxuLHIpe2NvbnN0IGk9dFswXSxzPXRbMV07cmV0dXJuIGVbMF09aStyKihuWzBdLWkpLGVbMV09cytyKihuWzFdLXMpLGV9ZnVuY3Rpb24geWMoZSx0KXt0PXQ9PT12b2lkIDA/MTp0O2NvbnN0IG49U3QoKSoyKk1hdGguUEk7cmV0dXJuIGVbMF09TWF0aC5jb3MobikqdCxlWzFdPU1hdGguc2luKG4pKnQsZX1mdW5jdGlvbiBYcihlLHQsbil7Y29uc3Qgcj10WzBdLGk9dFsxXTtyZXR1cm4gZVswXT1uWzBdKnIrblsyXSppLGVbMV09blsxXSpyK25bM10qaSxlfWZ1bmN0aW9uIGpyKGUsdCxuKXtjb25zdCByPXRbMF0saT10WzFdO3JldHVybiBlWzBdPW5bMF0qcituWzJdKmkrbls0XSxlWzFdPW5bMV0qcituWzNdKmkrbls1XSxlfWZ1bmN0aW9uIFRuKGUsdCxuKXtjb25zdCByPXRbMF0saT10WzFdO3JldHVybiBlWzBdPW5bMF0qcituWzNdKmkrbls2XSxlWzFdPW5bMV0qcituWzRdKmkrbls3XSxlfWZ1bmN0aW9uIEVuKGUsdCxuKXtjb25zdCByPXRbMF0saT10WzFdO3JldHVybiBlWzBdPW5bMF0qcituWzRdKmkrblsxMl0sZVsxXT1uWzFdKnIrbls1XSppK25bMTNdLGV9ZnVuY3Rpb24geGMoZSx0LG4scil7Y29uc3QgaT10WzBdLW5bMF0scz10WzFdLW5bMV0sbz1NYXRoLnNpbihyKSxjPU1hdGguY29zKHIpO3JldHVybiBlWzBdPWkqYy1zKm8rblswXSxlWzFdPWkqbytzKmMrblsxXSxlfWZ1bmN0aW9uIE1jKGUsdCl7Y29uc3Qgbj1lWzBdLHI9ZVsxXSxpPXRbMF0scz10WzFdLG89TWF0aC5zcXJ0KChuKm4rcipyKSooaSppK3MqcykpLGM9byYmKG4qaStyKnMpL287cmV0dXJuIE1hdGguYWNvcyhNYXRoLm1pbihNYXRoLm1heChjLC0xKSwxKSl9ZnVuY3Rpb24gd2MoZSl7cmV0dXJuIGVbMF09MCxlWzFdPTAsZX1mdW5jdGlvbiBBYyhlKXtyZXR1cm5gdmVjMigke2VbMF19LCAke2VbMV19KWB9ZnVuY3Rpb24gVGMoZSx0KXtyZXR1cm4gZVswXT09PXRbMF0mJmVbMV09PT10WzFdfWZ1bmN0aW9uICRlKGUsdCl7Y29uc3Qgbj1lWzBdLHI9ZVsxXSxpPXRbMF0scz10WzFdO3JldHVybiBNYXRoLmFicyhuLWkpPD1DKk1hdGgubWF4KDEsTWF0aC5hYnMobiksTWF0aC5hYnMoaSkpJiZNYXRoLmFicyhyLXMpPD1DKk1hdGgubWF4KDEsTWF0aC5hYnMociksTWF0aC5hYnMocykpfWNvbnN0IEVjPVdyLE9jPUcsdmM9VXIsYmM9QW4sSWM9WXIsU2M9TmUsTGM9WnIsUGM9ZnVuY3Rpb24oKXtjb25zdCBlPUZyKCk7cmV0dXJuIGZ1bmN0aW9uKHQsbixyLGkscyxvKXtsZXQgYyxsO2ZvcihufHwobj0yKSxyfHwocj0wKSxpP2w9TWF0aC5taW4oaSpuK3IsdC5sZW5ndGgpOmw9dC5sZW5ndGgsYz1yO2M8bDtjKz1uKWVbMF09dFtjXSxlWzFdPXRbYysxXSxzKGUsZSxvKSx0W2NdPWVbMF0sdFtjKzFdPWVbMV07cmV0dXJuIHR9fSgpO3ZhciBSYz1PYmplY3QuZnJlZXplKHtfX3Byb3RvX186bnVsbCxhZGQ6cXIsYW5nbGU6TWMsY2VpbDpsYyxjbG9uZTpzYyxjb3B5OmNjLGNyZWF0ZTpGcixjcm9zczpGdCxkaXN0OkljLGRpc3RhbmNlOllyLGRpdjpiYyxkaXZpZGU6QW4sZG90Ol9jLGVxdWFsczokZSxleGFjdEVxdWFsczpUYyxmbG9vcjpoYyxmb3JFYWNoOlBjLGZyb21WYWx1ZXM6b2MsaW52ZXJzZTptYyxsZW46RWMsbGVuZ3RoOldyLGxlcnA6R3IsbWF4OnVjLG1pbjpmYyxtdWw6dmMsbXVsdGlwbHk6VXIsbmVnYXRlOmdjLG5vcm1hbGl6ZTpwYyxyYW5kb206eWMscm90YXRlOnhjLHJvdW5kOmRjLHNjYWxlOkRyLHNjYWxlQW5kQWRkOkJyLHNldDphYyxzcXJEaXN0OlNjLHNxckxlbjpMYyxzcXVhcmVkRGlzdGFuY2U6TmUsc3F1YXJlZExlbmd0aDpacixzdHI6QWMsc3ViOk9jLHN1YnRyYWN0OkcsdHJhbnNmb3JtTWF0MjpYcix0cmFuc2Zvcm1NYXQyZDpqcix0cmFuc2Zvcm1NYXQzOlRuLHRyYW5zZm9ybU1hdDQ6RW4semVybzp3Y30pO2Z1bmN0aW9uIFFyKGUsdCxuKXtjb25zdCByPXRbMF0saT10WzFdLHM9blszXSpyK25bN10qaXx8MTtyZXR1cm4gZVswXT0oblswXSpyK25bNF0qaSkvcyxlWzFdPShuWzFdKnIrbls1XSppKS9zLGV9ZnVuY3Rpb24gS3IoZSx0LG4pe2NvbnN0IHI9dFswXSxpPXRbMV0scz10WzJdLG89blszXSpyK25bN10qaStuWzExXSpzfHwxO3JldHVybiBlWzBdPShuWzBdKnIrbls0XSppK25bOF0qcykvbyxlWzFdPShuWzFdKnIrbls1XSppK25bOV0qcykvbyxlWzJdPShuWzJdKnIrbls2XSppK25bMTBdKnMpL28sZX1mdW5jdGlvbiBDYyhlLHQsbil7Y29uc3Qgcj10WzBdLGk9dFsxXTtyZXR1cm4gZVswXT1uWzBdKnIrblsyXSppLGVbMV09blsxXSpyK25bM10qaSxlWzJdPXRbMl0sZX1mdW5jdGlvbiBWYyhlLHQsbil7Y29uc3Qgcj10WzBdLGk9dFsxXTtyZXR1cm4gZVswXT1uWzBdKnIrblsyXSppLGVbMV09blsxXSpyK25bM10qaSxlWzJdPXRbMl0sZVszXT10WzNdLGV9ZnVuY3Rpb24gSnIoZSx0LG4pe2NvbnN0IHI9dFswXSxpPXRbMV0scz10WzJdO3JldHVybiBlWzBdPW5bMF0qcituWzNdKmkrbls2XSpzLGVbMV09blsxXSpyK25bNF0qaStuWzddKnMsZVsyXT1uWzJdKnIrbls1XSppK25bOF0qcyxlWzNdPXRbM10sZX1jbGFzcyBRIGV4dGVuZHMgVmV7Y29uc3RydWN0b3IodD0wLG49MCl7c3VwZXIoMiksSXQodCkmJmFyZ3VtZW50cy5sZW5ndGg9PT0xP3RoaXMuY29weSh0KTooWi5kZWJ1ZyYmKFAodCksUChuKSksdGhpc1swXT10LHRoaXNbMV09bil9c2V0KHQsbil7cmV0dXJuIHRoaXNbMF09dCx0aGlzWzFdPW4sdGhpcy5jaGVjaygpfWNvcHkodCl7cmV0dXJuIHRoaXNbMF09dFswXSx0aGlzWzFdPXRbMV0sdGhpcy5jaGVjaygpfWZyb21PYmplY3QodCl7cmV0dXJuIFouZGVidWcmJihQKHQueCksUCh0LnkpKSx0aGlzWzBdPXQueCx0aGlzWzFdPXQueSx0aGlzLmNoZWNrKCl9dG9PYmplY3QodCl7cmV0dXJuIHQueD10aGlzWzBdLHQueT10aGlzWzFdLHR9Z2V0IEVMRU1FTlRTKCl7cmV0dXJuIDJ9aG9yaXpvbnRhbEFuZ2xlKCl7cmV0dXJuIE1hdGguYXRhbjIodGhpcy55LHRoaXMueCl9dmVydGljYWxBbmdsZSgpe3JldHVybiBNYXRoLmF0YW4yKHRoaXMueCx0aGlzLnkpfXRyYW5zZm9ybSh0KXtyZXR1cm4gdGhpcy50cmFuc2Zvcm1Bc1BvaW50KHQpfXRyYW5zZm9ybUFzUG9pbnQodCl7cmV0dXJuIEVuKHRoaXMsdGhpcyx0KSx0aGlzLmNoZWNrKCl9dHJhbnNmb3JtQXNWZWN0b3IodCl7cmV0dXJuIFFyKHRoaXMsdGhpcyx0KSx0aGlzLmNoZWNrKCl9dHJhbnNmb3JtQnlNYXRyaXgzKHQpe3JldHVybiBUbih0aGlzLHRoaXMsdCksdGhpcy5jaGVjaygpfXRyYW5zZm9ybUJ5TWF0cml4MngzKHQpe3JldHVybiBqcih0aGlzLHRoaXMsdCksdGhpcy5jaGVjaygpfXRyYW5zZm9ybUJ5TWF0cml4Mih0KXtyZXR1cm4gWHIodGhpcyx0aGlzLHQpLHRoaXMuY2hlY2soKX19ZnVuY3Rpb24gT24oKXtjb25zdCBlPW5ldyBEKDMpO3JldHVybiBEIT1GbG9hdDMyQXJyYXkmJihlWzBdPTAsZVsxXT0wLGVbMl09MCksZX1mdW5jdGlvbiBOYyhlKXtjb25zdCB0PW5ldyBEKDMpO3JldHVybiB0WzBdPWVbMF0sdFsxXT1lWzFdLHRbMl09ZVsyXSx0fWZ1bmN0aW9uIHplKGUpe2NvbnN0IHQ9ZVswXSxuPWVbMV0scj1lWzJdO3JldHVybiBNYXRoLnNxcnQodCp0K24qbityKnIpfWZ1bmN0aW9uIHZuKGUsdCxuKXtjb25zdCByPW5ldyBEKDMpO3JldHVybiByWzBdPWUsclsxXT10LHJbMl09bixyfWZ1bmN0aW9uICRjKGUsdCl7cmV0dXJuIGVbMF09dFswXSxlWzFdPXRbMV0sZVsyXT10WzJdLGV9ZnVuY3Rpb24gemMoZSx0LG4scil7cmV0dXJuIGVbMF09dCxlWzFdPW4sZVsyXT1yLGV9ZnVuY3Rpb24gSHIoZSx0LG4pe3JldHVybiBlWzBdPXRbMF0rblswXSxlWzFdPXRbMV0rblsxXSxlWzJdPXRbMl0rblsyXSxlfWZ1bmN0aW9uIGJuKGUsdCxuKXtyZXR1cm4gZVswXT10WzBdLW5bMF0sZVsxXT10WzFdLW5bMV0sZVsyXT10WzJdLW5bMl0sZX1mdW5jdGlvbiBJbihlLHQsbil7cmV0dXJuIGVbMF09dFswXSpuWzBdLGVbMV09dFsxXSpuWzFdLGVbMl09dFsyXSpuWzJdLGV9ZnVuY3Rpb24gdGkoZSx0LG4pe3JldHVybiBlWzBdPXRbMF0vblswXSxlWzFdPXRbMV0vblsxXSxlWzJdPXRbMl0vblsyXSxlfWZ1bmN0aW9uIGtjKGUsdCl7cmV0dXJuIGVbMF09TWF0aC5jZWlsKHRbMF0pLGVbMV09TWF0aC5jZWlsKHRbMV0pLGVbMl09TWF0aC5jZWlsKHRbMl0pLGV9ZnVuY3Rpb24gRmMoZSx0KXtyZXR1cm4gZVswXT1NYXRoLmZsb29yKHRbMF0pLGVbMV09TWF0aC5mbG9vcih0WzFdKSxlWzJdPU1hdGguZmxvb3IodFsyXSksZX1mdW5jdGlvbiBxYyhlLHQsbil7cmV0dXJuIGVbMF09TWF0aC5taW4odFswXSxuWzBdKSxlWzFdPU1hdGgubWluKHRbMV0sblsxXSksZVsyXT1NYXRoLm1pbih0WzJdLG5bMl0pLGV9ZnVuY3Rpb24gVWMoZSx0LG4pe3JldHVybiBlWzBdPU1hdGgubWF4KHRbMF0sblswXSksZVsxXT1NYXRoLm1heCh0WzFdLG5bMV0pLGVbMl09TWF0aC5tYXgodFsyXSxuWzJdKSxlfWZ1bmN0aW9uIERjKGUsdCl7cmV0dXJuIGVbMF09eXQodFswXSksZVsxXT15dCh0WzFdKSxlWzJdPXl0KHRbMl0pLGV9ZnVuY3Rpb24gZWkoZSx0LG4pe3JldHVybiBlWzBdPXRbMF0qbixlWzFdPXRbMV0qbixlWzJdPXRbMl0qbixlfWZ1bmN0aW9uIEJjKGUsdCxuLHIpe3JldHVybiBlWzBdPXRbMF0rblswXSpyLGVbMV09dFsxXStuWzFdKnIsZVsyXT10WzJdK25bMl0qcixlfWZ1bmN0aW9uIFNuKGUsdCl7Y29uc3Qgbj10WzBdLWVbMF0scj10WzFdLWVbMV0saT10WzJdLWVbMl07cmV0dXJuIE1hdGguc3FydChuKm4rcipyK2kqaSl9ZnVuY3Rpb24gbmkoZSx0KXtjb25zdCBuPXRbMF0tZVswXSxyPXRbMV0tZVsxXSxpPXRbMl0tZVsyXTtyZXR1cm4gbipuK3IqcitpKml9ZnVuY3Rpb24gcXQoZSl7Y29uc3QgdD1lWzBdLG49ZVsxXSxyPWVbMl07cmV0dXJuIHQqdCtuKm4rcipyfWZ1bmN0aW9uIGtlKGUsdCl7cmV0dXJuIGVbMF09LXRbMF0sZVsxXT0tdFsxXSxlWzJdPS10WzJdLGV9ZnVuY3Rpb24gWWMoZSx0KXtyZXR1cm4gZVswXT0xL3RbMF0sZVsxXT0xL3RbMV0sZVsyXT0xL3RbMl0sZX1mdW5jdGlvbiBBdChlLHQpe2NvbnN0IG49dFswXSxyPXRbMV0saT10WzJdO2xldCBzPW4qbityKnIraSppO3JldHVybiBzPjAmJihzPTEvTWF0aC5zcXJ0KHMpKSxlWzBdPXRbMF0qcyxlWzFdPXRbMV0qcyxlWzJdPXRbMl0qcyxlfWZ1bmN0aW9uIFV0KGUsdCl7cmV0dXJuIGVbMF0qdFswXStlWzFdKnRbMV0rZVsyXSp0WzJdfWZ1bmN0aW9uIEgoZSx0LG4pe2NvbnN0IHI9dFswXSxpPXRbMV0scz10WzJdLG89blswXSxjPW5bMV0sbD1uWzJdO3JldHVybiBlWzBdPWkqbC1zKmMsZVsxXT1zKm8tcipsLGVbMl09cipjLWkqbyxlfWZ1bmN0aW9uIFdjKGUsdCxuLHIpe2NvbnN0IGk9dFswXSxzPXRbMV0sbz10WzJdO3JldHVybiBlWzBdPWkrciooblswXS1pKSxlWzFdPXMrciooblsxXS1zKSxlWzJdPW8rciooblsyXS1vKSxlfWZ1bmN0aW9uIFpjKGUsdCxuLHIpe2NvbnN0IGk9TWF0aC5hY29zKE1hdGgubWluKE1hdGgubWF4KFV0KHQsbiksLTEpLDEpKSxzPU1hdGguc2luKGkpLG89TWF0aC5zaW4oKDEtcikqaSkvcyxjPU1hdGguc2luKHIqaSkvcztyZXR1cm4gZVswXT1vKnRbMF0rYypuWzBdLGVbMV09byp0WzFdK2MqblsxXSxlWzJdPW8qdFsyXStjKm5bMl0sZX1mdW5jdGlvbiBHYyhlLHQsbixyLGkscyl7Y29uc3Qgbz1zKnMsYz1vKigyKnMtMykrMSxsPW8qKHMtMikrcyxoPW8qKHMtMSksZj1vKigzLTIqcyk7cmV0dXJuIGVbMF09dFswXSpjK25bMF0qbCtyWzBdKmgraVswXSpmLGVbMV09dFsxXSpjK25bMV0qbCtyWzFdKmgraVsxXSpmLGVbMl09dFsyXSpjK25bMl0qbCtyWzJdKmgraVsyXSpmLGV9ZnVuY3Rpb24gWGMoZSx0LG4scixpLHMpe2NvbnN0IG89MS1zLGM9bypvLGw9cypzLGg9YypvLGY9MypzKmMsdT0zKmwqbyxkPWwqcztyZXR1cm4gZVswXT10WzBdKmgrblswXSpmK3JbMF0qdStpWzBdKmQsZVsxXT10WzFdKmgrblsxXSpmK3JbMV0qdStpWzFdKmQsZVsyXT10WzJdKmgrblsyXSpmK3JbMl0qdStpWzJdKmQsZX1mdW5jdGlvbiBqYyhlLHQpe3Q9dD09PXZvaWQgMD8xOnQ7Y29uc3Qgbj1TdCgpKjIqTWF0aC5QSSxyPVN0KCkqMi0xLGk9TWF0aC5zcXJ0KDEtcipyKSp0O3JldHVybiBlWzBdPU1hdGguY29zKG4pKmksZVsxXT1NYXRoLnNpbihuKSppLGVbMl09cip0LGV9ZnVuY3Rpb24gRmUoZSx0LG4pe2NvbnN0IHI9dFswXSxpPXRbMV0scz10WzJdO2xldCBvPW5bM10qcituWzddKmkrblsxMV0qcytuWzE1XTtyZXR1cm4gbz1vfHwxLGVbMF09KG5bMF0qcituWzRdKmkrbls4XSpzK25bMTJdKS9vLGVbMV09KG5bMV0qcituWzVdKmkrbls5XSpzK25bMTNdKS9vLGVbMl09KG5bMl0qcituWzZdKmkrblsxMF0qcytuWzE0XSkvbyxlfWZ1bmN0aW9uIExuKGUsdCxuKXtjb25zdCByPXRbMF0saT10WzFdLHM9dFsyXTtyZXR1cm4gZVswXT1yKm5bMF0raSpuWzNdK3Mqbls2XSxlWzFdPXIqblsxXStpKm5bNF0rcypuWzddLGVbMl09cipuWzJdK2kqbls1XStzKm5bOF0sZX1mdW5jdGlvbiBQbihlLHQsbil7Y29uc3Qgcj1uWzBdLGk9blsxXSxzPW5bMl0sbz1uWzNdLGM9dFswXSxsPXRbMV0saD10WzJdO2xldCBmPWkqaC1zKmwsdT1zKmMtcipoLGQ9cipsLWkqYyxnPWkqZC1zKnUsbT1zKmYtcipkLF89cip1LWkqZjtjb25zdCBwPW8qMjtyZXR1cm4gZio9cCx1Kj1wLGQqPXAsZyo9MixtKj0yLF8qPTIsZVswXT1jK2YrZyxlWzFdPWwrdSttLGVbMl09aCtkK18sZX1mdW5jdGlvbiByaShlLHQsbixyKXtjb25zdCBpPVtdLHM9W107cmV0dXJuIGlbMF09dFswXS1uWzBdLGlbMV09dFsxXS1uWzFdLGlbMl09dFsyXS1uWzJdLHNbMF09aVswXSxzWzFdPWlbMV0qTWF0aC5jb3MociktaVsyXSpNYXRoLnNpbihyKSxzWzJdPWlbMV0qTWF0aC5zaW4ocikraVsyXSpNYXRoLmNvcyhyKSxlWzBdPXNbMF0rblswXSxlWzFdPXNbMV0rblsxXSxlWzJdPXNbMl0rblsyXSxlfWZ1bmN0aW9uIGlpKGUsdCxuLHIpe2NvbnN0IGk9W10scz1bXTtyZXR1cm4gaVswXT10WzBdLW5bMF0saVsxXT10WzFdLW5bMV0saVsyXT10WzJdLW5bMl0sc1swXT1pWzJdKk1hdGguc2luKHIpK2lbMF0qTWF0aC5jb3Mociksc1sxXT1pWzFdLHNbMl09aVsyXSpNYXRoLmNvcyhyKS1pWzBdKk1hdGguc2luKHIpLGVbMF09c1swXStuWzBdLGVbMV09c1sxXStuWzFdLGVbMl09c1syXStuWzJdLGV9ZnVuY3Rpb24gc2koZSx0LG4scil7Y29uc3QgaT1bXSxzPVtdO3JldHVybiBpWzBdPXRbMF0tblswXSxpWzFdPXRbMV0tblsxXSxpWzJdPXRbMl0tblsyXSxzWzBdPWlbMF0qTWF0aC5jb3MociktaVsxXSpNYXRoLnNpbihyKSxzWzFdPWlbMF0qTWF0aC5zaW4ocikraVsxXSpNYXRoLmNvcyhyKSxzWzJdPWlbMl0sZVswXT1zWzBdK25bMF0sZVsxXT1zWzFdK25bMV0sZVsyXT1zWzJdK25bMl0sZX1mdW5jdGlvbiBvaShlLHQpe2NvbnN0IG49ZVswXSxyPWVbMV0saT1lWzJdLHM9dFswXSxvPXRbMV0sYz10WzJdLGw9TWF0aC5zcXJ0KChuKm4rcipyK2kqaSkqKHMqcytvKm8rYypjKSksaD1sJiZVdChlLHQpL2w7cmV0dXJuIE1hdGguYWNvcyhNYXRoLm1pbihNYXRoLm1heChoLC0xKSwxKSl9ZnVuY3Rpb24gUWMoZSl7cmV0dXJuIGVbMF09MCxlWzFdPTAsZVsyXT0wLGV9ZnVuY3Rpb24gS2MoZSl7cmV0dXJuYHZlYzMoJHtlWzBdfSwgJHtlWzFdfSwgJHtlWzJdfSlgfWZ1bmN0aW9uIEpjKGUsdCl7cmV0dXJuIGVbMF09PT10WzBdJiZlWzFdPT09dFsxXSYmZVsyXT09PXRbMl19ZnVuY3Rpb24gSGMoZSx0KXtjb25zdCBuPWVbMF0scj1lWzFdLGk9ZVsyXSxzPXRbMF0sbz10WzFdLGM9dFsyXTtyZXR1cm4gTWF0aC5hYnMobi1zKTw9QypNYXRoLm1heCgxLE1hdGguYWJzKG4pLE1hdGguYWJzKHMpKSYmTWF0aC5hYnMoci1vKTw9QypNYXRoLm1heCgxLE1hdGguYWJzKHIpLE1hdGguYWJzKG8pKSYmTWF0aC5hYnMoaS1jKTw9QypNYXRoLm1heCgxLE1hdGguYWJzKGkpLE1hdGguYWJzKGMpKX1jb25zdCB0YT1ibixlYT1JbixuYT10aSxyYT1TbixpYT1uaSxjaT16ZSxzYT1xdCxvYT1mdW5jdGlvbigpe2NvbnN0IGU9T24oKTtyZXR1cm4gZnVuY3Rpb24odCxuLHIsaSxzLG8pe2xldCBjLGw7Zm9yKG58fChuPTMpLHJ8fChyPTApLGk/bD1NYXRoLm1pbihpKm4rcix0Lmxlbmd0aCk6bD10Lmxlbmd0aCxjPXI7YzxsO2MrPW4pZVswXT10W2NdLGVbMV09dFtjKzFdLGVbMl09dFtjKzJdLHMoZSxlLG8pLHRbY109ZVswXSx0W2MrMV09ZVsxXSx0W2MrMl09ZVsyXTtyZXR1cm4gdH19KCk7dmFyIGNhPU9iamVjdC5mcmVlemUoe19fcHJvdG9fXzpudWxsLGFkZDpIcixhbmdsZTpvaSxiZXppZXI6WGMsY2VpbDprYyxjbG9uZTpOYyxjb3B5OiRjLGNyZWF0ZTpPbixjcm9zczpILGRpc3Q6cmEsZGlzdGFuY2U6U24sZGl2Om5hLGRpdmlkZTp0aSxkb3Q6VXQsZXF1YWxzOkhjLGV4YWN0RXF1YWxzOkpjLGZsb29yOkZjLGZvckVhY2g6b2EsZnJvbVZhbHVlczp2bixoZXJtaXRlOkdjLGludmVyc2U6WWMsbGVuOmNpLGxlbmd0aDp6ZSxsZXJwOldjLG1heDpVYyxtaW46cWMsbXVsOmVhLG11bHRpcGx5OkluLG5lZ2F0ZTprZSxub3JtYWxpemU6QXQscmFuZG9tOmpjLHJvdGF0ZVg6cmkscm90YXRlWTppaSxyb3RhdGVaOnNpLHJvdW5kOkRjLHNjYWxlOmVpLHNjYWxlQW5kQWRkOkJjLHNldDp6YyxzbGVycDpaYyxzcXJEaXN0OmlhLHNxckxlbjpzYSxzcXVhcmVkRGlzdGFuY2U6bmksc3F1YXJlZExlbmd0aDpxdCxzdHI6S2Msc3ViOnRhLHN1YnRyYWN0OmJuLHRyYW5zZm9ybU1hdDM6TG4sdHJhbnNmb3JtTWF0NDpGZSx0cmFuc2Zvcm1RdWF0OlBuLHplcm86UWN9KTtjb25zdCBSbj1bMCwwLDBdO2xldCBxZTtjbGFzcyBSIGV4dGVuZHMgVmV7c3RhdGljIGdldCBaRVJPKCl7cmV0dXJuIHFlfHwocWU9bmV3IFIoMCwwLDApLE9iamVjdC5mcmVlemUocWUpKSxxZX1jb25zdHJ1Y3Rvcih0PTAsbj0wLHI9MCl7c3VwZXIoLTAsLTAsLTApLGFyZ3VtZW50cy5sZW5ndGg9PT0xJiZJdCh0KT90aGlzLmNvcHkodCk6KFouZGVidWcmJihQKHQpLFAobiksUChyKSksdGhpc1swXT10LHRoaXNbMV09bix0aGlzWzJdPXIpfXNldCh0LG4scil7cmV0dXJuIHRoaXNbMF09dCx0aGlzWzFdPW4sdGhpc1syXT1yLHRoaXMuY2hlY2soKX1jb3B5KHQpe3JldHVybiB0aGlzWzBdPXRbMF0sdGhpc1sxXT10WzFdLHRoaXNbMl09dFsyXSx0aGlzLmNoZWNrKCl9ZnJvbU9iamVjdCh0KXtyZXR1cm4gWi5kZWJ1ZyYmKFAodC54KSxQKHQueSksUCh0LnopKSx0aGlzWzBdPXQueCx0aGlzWzFdPXQueSx0aGlzWzJdPXQueix0aGlzLmNoZWNrKCl9dG9PYmplY3QodCl7cmV0dXJuIHQueD10aGlzWzBdLHQueT10aGlzWzFdLHQuej10aGlzWzJdLHR9Z2V0IEVMRU1FTlRTKCl7cmV0dXJuIDN9Z2V0IHooKXtyZXR1cm4gdGhpc1syXX1zZXQgeih0KXt0aGlzWzJdPVAodCl9YW5nbGUodCl7cmV0dXJuIG9pKHRoaXMsdCl9Y3Jvc3ModCl7cmV0dXJuIEgodGhpcyx0aGlzLHQpLHRoaXMuY2hlY2soKX1yb3RhdGVYKHtyYWRpYW5zOnQsb3JpZ2luOm49Um59KXtyZXR1cm4gcmkodGhpcyx0aGlzLG4sdCksdGhpcy5jaGVjaygpfXJvdGF0ZVkoe3JhZGlhbnM6dCxvcmlnaW46bj1Sbn0pe3JldHVybiBpaSh0aGlzLHRoaXMsbix0KSx0aGlzLmNoZWNrKCl9cm90YXRlWih7cmFkaWFuczp0LG9yaWdpbjpuPVJufSl7cmV0dXJuIHNpKHRoaXMsdGhpcyxuLHQpLHRoaXMuY2hlY2soKX10cmFuc2Zvcm0odCl7cmV0dXJuIHRoaXMudHJhbnNmb3JtQXNQb2ludCh0KX10cmFuc2Zvcm1Bc1BvaW50KHQpe3JldHVybiBGZSh0aGlzLHRoaXMsdCksdGhpcy5jaGVjaygpfXRyYW5zZm9ybUFzVmVjdG9yKHQpe3JldHVybiBLcih0aGlzLHRoaXMsdCksdGhpcy5jaGVjaygpfXRyYW5zZm9ybUJ5TWF0cml4Myh0KXtyZXR1cm4gTG4odGhpcyx0aGlzLHQpLHRoaXMuY2hlY2soKX10cmFuc2Zvcm1CeU1hdHJpeDIodCl7cmV0dXJuIENjKHRoaXMsdGhpcyx0KSx0aGlzLmNoZWNrKCl9dHJhbnNmb3JtQnlRdWF0ZXJuaW9uKHQpe3JldHVybiBQbih0aGlzLHRoaXMsdCksdGhpcy5jaGVjaygpfX1sZXQgVWU7Y2xhc3Mgb3QgZXh0ZW5kcyBWZXtzdGF0aWMgZ2V0IFpFUk8oKXtyZXR1cm4gVWV8fChVZT1uZXcgb3QoMCwwLDAsMCksT2JqZWN0LmZyZWV6ZShVZSkpLFVlfWNvbnN0cnVjdG9yKHQ9MCxuPTAscj0wLGk9MCl7c3VwZXIoLTAsLTAsLTAsLTApLEl0KHQpJiZhcmd1bWVudHMubGVuZ3RoPT09MT90aGlzLmNvcHkodCk6KFouZGVidWcmJihQKHQpLFAobiksUChyKSxQKGkpKSx0aGlzWzBdPXQsdGhpc1sxXT1uLHRoaXNbMl09cix0aGlzWzNdPWkpfXNldCh0LG4scixpKXtyZXR1cm4gdGhpc1swXT10LHRoaXNbMV09bix0aGlzWzJdPXIsdGhpc1szXT1pLHRoaXMuY2hlY2soKX1jb3B5KHQpe3JldHVybiB0aGlzWzBdPXRbMF0sdGhpc1sxXT10WzFdLHRoaXNbMl09dFsyXSx0aGlzWzNdPXRbM10sdGhpcy5jaGVjaygpfWZyb21PYmplY3QodCl7cmV0dXJuIFouZGVidWcmJihQKHQueCksUCh0LnkpLFAodC56KSxQKHQudykpLHRoaXNbMF09dC54LHRoaXNbMV09dC55LHRoaXNbMl09dC56LHRoaXNbM109dC53LHRoaXN9dG9PYmplY3QodCl7cmV0dXJuIHQueD10aGlzWzBdLHQueT10aGlzWzFdLHQuej10aGlzWzJdLHQudz10aGlzWzNdLHR9Z2V0IEVMRU1FTlRTKCl7cmV0dXJuIDR9Z2V0IHooKXtyZXR1cm4gdGhpc1syXX1zZXQgeih0KXt0aGlzWzJdPVAodCl9Z2V0IHcoKXtyZXR1cm4gdGhpc1szXX1zZXQgdyh0KXt0aGlzWzNdPVAodCl9dHJhbnNmb3JtKHQpe3JldHVybiBGZSh0aGlzLHRoaXMsdCksdGhpcy5jaGVjaygpfXRyYW5zZm9ybUJ5TWF0cml4Myh0KXtyZXR1cm4gSnIodGhpcyx0aGlzLHQpLHRoaXMuY2hlY2soKX10cmFuc2Zvcm1CeU1hdHJpeDIodCl7cmV0dXJuIFZjKHRoaXMsdGhpcyx0KSx0aGlzLmNoZWNrKCl9dHJhbnNmb3JtQnlRdWF0ZXJuaW9uKHQpe3JldHVybiBQbih0aGlzLHRoaXMsdCksdGhpcy5jaGVjaygpfWFwcGx5TWF0cml4NCh0KXtyZXR1cm4gdC50cmFuc2Zvcm0odGhpcyx0aGlzKSx0aGlzfX1sZXQgQ249Y2xhc3MgZXh0ZW5kcyBjZXt0b1N0cmluZygpe2xldCB0PSJbIjtpZihaLnByaW50Um93TWFqb3Ipe3QrPSJyb3ctbWFqb3I6Ijtmb3IobGV0IG49MDtuPHRoaXMuUkFOSzsrK24pZm9yKGxldCByPTA7cjx0aGlzLlJBTks7KytyKXQrPWAgJHt0aGlzW3IqdGhpcy5SQU5LK25dfWB9ZWxzZXt0Kz0iY29sdW1uLW1ham9yOiI7Zm9yKGxldCBuPTA7bjx0aGlzLkVMRU1FTlRTOysrbil0Kz1gICR7dGhpc1tuXX1gfXJldHVybiB0Kz0iXSIsdH1nZXRFbGVtZW50SW5kZXgodCxuKXtyZXR1cm4gbip0aGlzLlJBTksrdH1nZXRFbGVtZW50KHQsbil7cmV0dXJuIHRoaXNbbip0aGlzLlJBTksrdF19c2V0RWxlbWVudCh0LG4scil7cmV0dXJuIHRoaXNbbip0aGlzLlJBTksrdF09UChyKSx0aGlzfWdldENvbHVtbih0LG49bmV3IEFycmF5KHRoaXMuUkFOSykuZmlsbCgtMCkpe2NvbnN0IHI9dCp0aGlzLlJBTks7Zm9yKGxldCBpPTA7aTx0aGlzLlJBTks7KytpKW5baV09dGhpc1tyK2ldO3JldHVybiBufXNldENvbHVtbih0LG4pe2NvbnN0IHI9dCp0aGlzLlJBTks7Zm9yKGxldCBpPTA7aTx0aGlzLlJBTks7KytpKXRoaXNbcitpXT1uW2ldO3JldHVybiB0aGlzfX07ZnVuY3Rpb24gYWkoKXtjb25zdCBlPW5ldyBEKDkpO3JldHVybiBEIT1GbG9hdDMyQXJyYXkmJihlWzFdPTAsZVsyXT0wLGVbM109MCxlWzVdPTAsZVs2XT0wLGVbN109MCksZVswXT0xLGVbNF09MSxlWzhdPTEsZX1mdW5jdGlvbiBhYShlLHQpe3JldHVybiBlWzBdPXRbMF0sZVsxXT10WzFdLGVbMl09dFsyXSxlWzNdPXRbNF0sZVs0XT10WzVdLGVbNV09dFs2XSxlWzZdPXRbOF0sZVs3XT10WzldLGVbOF09dFsxMF0sZX1mdW5jdGlvbiBsYShlKXtjb25zdCB0PW5ldyBEKDkpO3JldHVybiB0WzBdPWVbMF0sdFsxXT1lWzFdLHRbMl09ZVsyXSx0WzNdPWVbM10sdFs0XT1lWzRdLHRbNV09ZVs1XSx0WzZdPWVbNl0sdFs3XT1lWzddLHRbOF09ZVs4XSx0fWZ1bmN0aW9uIGhhKGUsdCl7cmV0dXJuIGVbMF09dFswXSxlWzFdPXRbMV0sZVsyXT10WzJdLGVbM109dFszXSxlWzRdPXRbNF0sZVs1XT10WzVdLGVbNl09dFs2XSxlWzddPXRbN10sZVs4XT10WzhdLGV9ZnVuY3Rpb24gZmEoZSx0LG4scixpLHMsbyxjLGwpe2NvbnN0IGg9bmV3IEQoOSk7cmV0dXJuIGhbMF09ZSxoWzFdPXQsaFsyXT1uLGhbM109cixoWzRdPWksaFs1XT1zLGhbNl09byxoWzddPWMsaFs4XT1sLGh9ZnVuY3Rpb24gdWEoZSx0LG4scixpLHMsbyxjLGwsaCl7cmV0dXJuIGVbMF09dCxlWzFdPW4sZVsyXT1yLGVbM109aSxlWzRdPXMsZVs1XT1vLGVbNl09YyxlWzddPWwsZVs4XT1oLGV9ZnVuY3Rpb24gZGEoZSl7cmV0dXJuIGVbMF09MSxlWzFdPTAsZVsyXT0wLGVbM109MCxlWzRdPTEsZVs1XT0wLGVbNl09MCxlWzddPTAsZVs4XT0xLGV9ZnVuY3Rpb24gVm4oZSx0KXtpZihlPT09dCl7Y29uc3Qgbj10WzFdLHI9dFsyXSxpPXRbNV07ZVsxXT10WzNdLGVbMl09dFs2XSxlWzNdPW4sZVs1XT10WzddLGVbNl09cixlWzddPWl9ZWxzZSBlWzBdPXRbMF0sZVsxXT10WzNdLGVbMl09dFs2XSxlWzNdPXRbMV0sZVs0XT10WzRdLGVbNV09dFs3XSxlWzZdPXRbMl0sZVs3XT10WzVdLGVbOF09dFs4XTtyZXR1cm4gZX1mdW5jdGlvbiBObihlLHQpe2NvbnN0IG49dFswXSxyPXRbMV0saT10WzJdLHM9dFszXSxvPXRbNF0sYz10WzVdLGw9dFs2XSxoPXRbN10sZj10WzhdLHU9ZipvLWMqaCxkPS1mKnMrYypsLGc9aCpzLW8qbDtsZXQgbT1uKnUrcipkK2kqZztyZXR1cm4gbT8obT0xL20sZVswXT11Km0sZVsxXT0oLWYqcitpKmgpKm0sZVsyXT0oYypyLWkqbykqbSxlWzNdPWQqbSxlWzRdPShmKm4taSpsKSptLGVbNV09KC1jKm4raSpzKSptLGVbNl09ZyptLGVbN109KC1oKm4rcipsKSptLGVbOF09KG8qbi1yKnMpKm0sZSk6bnVsbH1mdW5jdGlvbiBnYShlLHQpe2NvbnN0IG49dFswXSxyPXRbMV0saT10WzJdLHM9dFszXSxvPXRbNF0sYz10WzVdLGw9dFs2XSxoPXRbN10sZj10WzhdO3JldHVybiBlWzBdPW8qZi1jKmgsZVsxXT1pKmgtcipmLGVbMl09cipjLWkqbyxlWzNdPWMqbC1zKmYsZVs0XT1uKmYtaSpsLGVbNV09aSpzLW4qYyxlWzZdPXMqaC1vKmwsZVs3XT1yKmwtbipoLGVbOF09bipvLXIqcyxlfWZ1bmN0aW9uIGxlKGUpe2NvbnN0IHQ9ZVswXSxuPWVbMV0scj1lWzJdLGk9ZVszXSxzPWVbNF0sbz1lWzVdLGM9ZVs2XSxsPWVbN10saD1lWzhdO3JldHVybiB0KihoKnMtbypsKStuKigtaCppK28qYykrcioobCppLXMqYyl9ZnVuY3Rpb24gRGUoZSx0LG4pe2NvbnN0IHI9dFswXSxpPXRbMV0scz10WzJdLG89dFszXSxjPXRbNF0sbD10WzVdLGg9dFs2XSxmPXRbN10sdT10WzhdLGQ9blswXSxnPW5bMV0sbT1uWzJdLF89blszXSxwPW5bNF0sTT1uWzVdLEE9bls2XSx4PW5bN10sVD1uWzhdO3JldHVybiBlWzBdPWQqcitnKm8rbSpoLGVbMV09ZCppK2cqYyttKmYsZVsyXT1kKnMrZypsK20qdSxlWzNdPV8qcitwKm8rTSpoLGVbNF09XyppK3AqYytNKmYsZVs1XT1fKnMrcCpsK00qdSxlWzZdPUEqcit4Km8rVCpoLGVbN109QSppK3gqYytUKmYsZVs4XT1BKnMreCpsK1QqdSxlfWZ1bmN0aW9uIGxpKGUsdCxuKXtjb25zdCByPXRbMF0saT10WzFdLHM9dFsyXSxvPXRbM10sYz10WzRdLGw9dFs1XSxoPXRbNl0sZj10WzddLHU9dFs4XSxkPW5bMF0sZz1uWzFdO3JldHVybiBlWzBdPXIsZVsxXT1pLGVbMl09cyxlWzNdPW8sZVs0XT1jLGVbNV09bCxlWzZdPWQqcitnKm8raCxlWzddPWQqaStnKmMrZixlWzhdPWQqcytnKmwrdSxlfWZ1bmN0aW9uIGhpKGUsdCxuKXtjb25zdCByPXRbMF0saT10WzFdLHM9dFsyXSxvPXRbM10sYz10WzRdLGw9dFs1XSxoPXRbNl0sZj10WzddLHU9dFs4XSxkPU1hdGguc2luKG4pLGc9TWF0aC5jb3Mobik7cmV0dXJuIGVbMF09ZypyK2QqbyxlWzFdPWcqaStkKmMsZVsyXT1nKnMrZCpsLGVbM109ZypvLWQqcixlWzRdPWcqYy1kKmksZVs1XT1nKmwtZCpzLGVbNl09aCxlWzddPWYsZVs4XT11LGV9ZnVuY3Rpb24gJG4oZSx0LG4pe2NvbnN0IHI9blswXSxpPW5bMV07cmV0dXJuIGVbMF09cip0WzBdLGVbMV09cip0WzFdLGVbMl09cip0WzJdLGVbM109aSp0WzNdLGVbNF09aSp0WzRdLGVbNV09aSp0WzVdLGVbNl09dFs2XSxlWzddPXRbN10sZVs4XT10WzhdLGV9ZnVuY3Rpb24gbWEoZSx0KXtyZXR1cm4gZVswXT0xLGVbMV09MCxlWzJdPTAsZVszXT0wLGVbNF09MSxlWzVdPTAsZVs2XT10WzBdLGVbN109dFsxXSxlWzhdPTEsZX1mdW5jdGlvbiBwYShlLHQpe2NvbnN0IG49TWF0aC5zaW4odCkscj1NYXRoLmNvcyh0KTtyZXR1cm4gZVswXT1yLGVbMV09bixlWzJdPTAsZVszXT0tbixlWzRdPXIsZVs1XT0wLGVbNl09MCxlWzddPTAsZVs4XT0xLGV9ZnVuY3Rpb24gX2EoZSx0KXtyZXR1cm4gZVswXT10WzBdLGVbMV09MCxlWzJdPTAsZVszXT0wLGVbNF09dFsxXSxlWzVdPTAsZVs2XT0wLGVbN109MCxlWzhdPTEsZX1mdW5jdGlvbiB5YShlLHQpe3JldHVybiBlWzBdPXRbMF0sZVsxXT10WzFdLGVbMl09MCxlWzNdPXRbMl0sZVs0XT10WzNdLGVbNV09MCxlWzZdPXRbNF0sZVs3XT10WzVdLGVbOF09MSxlfWZ1bmN0aW9uIGZpKGUsdCl7Y29uc3Qgbj10WzBdLHI9dFsxXSxpPXRbMl0scz10WzNdLG89bituLGM9cityLGw9aStpLGg9bipvLGY9cipvLHU9cipjLGQ9aSpvLGc9aSpjLG09aSpsLF89cypvLHA9cypjLE09cypsO3JldHVybiBlWzBdPTEtdS1tLGVbM109Zi1NLGVbNl09ZCtwLGVbMV09ZitNLGVbNF09MS1oLW0sZVs3XT1nLV8sZVsyXT1kLXAsZVs1XT1nK18sZVs4XT0xLWgtdSxlfWZ1bmN0aW9uIHpuKGUsdCl7Y29uc3Qgbj10WzBdLHI9dFsxXSxpPXRbMl0scz10WzNdLG89dFs0XSxjPXRbNV0sbD10WzZdLGg9dFs3XSxmPXRbOF0sdT10WzldLGQ9dFsxMF0sZz10WzExXSxtPXRbMTJdLF89dFsxM10scD10WzE0XSxNPXRbMTVdLEE9bipjLXIqbyx4PW4qbC1pKm8sVD1uKmgtcypvLE89cipsLWkqYyx3PXIqaC1zKmMsUz1pKmgtcypsLGI9ZipfLXUqbSxJPWYqcC1kKm0sRT1mKk0tZyptLFY9dSpwLWQqXyxOPXUqTS1nKl8sJD1kKk0tZypwO2xldCBMPUEqJC14Kk4rVCpWK08qRS13KkkrUypiO3JldHVybiBMPyhMPTEvTCxlWzBdPShjKiQtbCpOK2gqVikqTCxlWzFdPShsKkUtbyokLWgqSSkqTCxlWzJdPShvKk4tYypFK2gqYikqTCxlWzNdPShpKk4tciokLXMqVikqTCxlWzRdPShuKiQtaSpFK3MqSSkqTCxlWzVdPShyKkUtbipOLXMqYikqTCxlWzZdPShfKlMtcCp3K00qTykqTCxlWzddPShwKlQtbSpTLU0qeCkqTCxlWzhdPShtKnctXypUK00qQSkqTCxlKTpudWxsfWZ1bmN0aW9uIHhhKGUsdCxuKXtyZXR1cm4gZVswXT0yL3QsZVsxXT0wLGVbMl09MCxlWzNdPTAsZVs0XT0tMi9uLGVbNV09MCxlWzZdPS0xLGVbN109MSxlWzhdPTEsZX1mdW5jdGlvbiBNYShlKXtyZXR1cm5gbWF0Mygke2VbMF19LCAke2VbMV19LCAke2VbMl19LCAke2VbM119LCAke2VbNF19LCAke2VbNV19LCAke2VbNl19LCAke2VbN119LCAke2VbOF19KWB9ZnVuY3Rpb24gd2EoZSl7cmV0dXJuIE1hdGguc3FydChlWzBdKmVbMF0rZVsxXSplWzFdK2VbMl0qZVsyXStlWzNdKmVbM10rZVs0XSplWzRdK2VbNV0qZVs1XStlWzZdKmVbNl0rZVs3XSplWzddK2VbOF0qZVs4XSl9ZnVuY3Rpb24gQWEoZSx0LG4pe3JldHVybiBlWzBdPXRbMF0rblswXSxlWzFdPXRbMV0rblsxXSxlWzJdPXRbMl0rblsyXSxlWzNdPXRbM10rblszXSxlWzRdPXRbNF0rbls0XSxlWzVdPXRbNV0rbls1XSxlWzZdPXRbNl0rbls2XSxlWzddPXRbN10rbls3XSxlWzhdPXRbOF0rbls4XSxlfWZ1bmN0aW9uIHVpKGUsdCxuKXtyZXR1cm4gZVswXT10WzBdLW5bMF0sZVsxXT10WzFdLW5bMV0sZVsyXT10WzJdLW5bMl0sZVszXT10WzNdLW5bM10sZVs0XT10WzRdLW5bNF0sZVs1XT10WzVdLW5bNV0sZVs2XT10WzZdLW5bNl0sZVs3XT10WzddLW5bN10sZVs4XT10WzhdLW5bOF0sZX1mdW5jdGlvbiBUYShlLHQsbil7cmV0dXJuIGVbMF09dFswXSpuLGVbMV09dFsxXSpuLGVbMl09dFsyXSpuLGVbM109dFszXSpuLGVbNF09dFs0XSpuLGVbNV09dFs1XSpuLGVbNl09dFs2XSpuLGVbN109dFs3XSpuLGVbOF09dFs4XSpuLGV9ZnVuY3Rpb24gRWEoZSx0LG4scil7cmV0dXJuIGVbMF09dFswXStuWzBdKnIsZVsxXT10WzFdK25bMV0qcixlWzJdPXRbMl0rblsyXSpyLGVbM109dFszXStuWzNdKnIsZVs0XT10WzRdK25bNF0qcixlWzVdPXRbNV0rbls1XSpyLGVbNl09dFs2XStuWzZdKnIsZVs3XT10WzddK25bN10qcixlWzhdPXRbOF0rbls4XSpyLGV9ZnVuY3Rpb24gT2EoZSx0KXtyZXR1cm4gZVswXT09PXRbMF0mJmVbMV09PT10WzFdJiZlWzJdPT09dFsyXSYmZVszXT09PXRbM10mJmVbNF09PT10WzRdJiZlWzVdPT09dFs1XSYmZVs2XT09PXRbNl0mJmVbN109PT10WzddJiZlWzhdPT09dFs4XX1mdW5jdGlvbiB2YShlLHQpe2NvbnN0IG49ZVswXSxyPWVbMV0saT1lWzJdLHM9ZVszXSxvPWVbNF0sYz1lWzVdLGw9ZVs2XSxoPWVbN10sZj1lWzhdLHU9dFswXSxkPXRbMV0sZz10WzJdLG09dFszXSxfPXRbNF0scD10WzVdLE09dFs2XSxBPXRbN10seD10WzhdO3JldHVybiBNYXRoLmFicyhuLXUpPD1DKk1hdGgubWF4KDEsTWF0aC5hYnMobiksTWF0aC5hYnModSkpJiZNYXRoLmFicyhyLWQpPD1DKk1hdGgubWF4KDEsTWF0aC5hYnMociksTWF0aC5hYnMoZCkpJiZNYXRoLmFicyhpLWcpPD1DKk1hdGgubWF4KDEsTWF0aC5hYnMoaSksTWF0aC5hYnMoZykpJiZNYXRoLmFicyhzLW0pPD1DKk1hdGgubWF4KDEsTWF0aC5hYnMocyksTWF0aC5hYnMobSkpJiZNYXRoLmFicyhvLV8pPD1DKk1hdGgubWF4KDEsTWF0aC5hYnMobyksTWF0aC5hYnMoXykpJiZNYXRoLmFicyhjLXApPD1DKk1hdGgubWF4KDEsTWF0aC5hYnMoYyksTWF0aC5hYnMocCkpJiZNYXRoLmFicyhsLU0pPD1DKk1hdGgubWF4KDEsTWF0aC5hYnMobCksTWF0aC5hYnMoTSkpJiZNYXRoLmFicyhoLUEpPD1DKk1hdGgubWF4KDEsTWF0aC5hYnMoaCksTWF0aC5hYnMoQSkpJiZNYXRoLmFicyhmLXgpPD1DKk1hdGgubWF4KDEsTWF0aC5hYnMoZiksTWF0aC5hYnMoeCkpfXZhciBiYT1PYmplY3QuZnJlZXplKHtfX3Byb3RvX186bnVsbCxhZGQ6QWEsYWRqb2ludDpnYSxjbG9uZTpsYSxjb3B5OmhhLGNyZWF0ZTphaSxkZXRlcm1pbmFudDpsZSxlcXVhbHM6dmEsZXhhY3RFcXVhbHM6T2EsZnJvYjp3YSxmcm9tTWF0MmQ6eWEsZnJvbU1hdDQ6YWEsZnJvbVF1YXQ6ZmksZnJvbVJvdGF0aW9uOnBhLGZyb21TY2FsaW5nOl9hLGZyb21UcmFuc2xhdGlvbjptYSxmcm9tVmFsdWVzOmZhLGlkZW50aXR5OmRhLGludmVydDpObixtdWw6RGUsbXVsdGlwbHk6RGUsbXVsdGlwbHlTY2FsYXI6VGEsbXVsdGlwbHlTY2FsYXJBbmRBZGQ6RWEsbm9ybWFsRnJvbU1hdDQ6em4scHJvamVjdGlvbjp4YSxyb3RhdGU6aGksc2NhbGU6JG4sc2V0OnVhLHN0cjpNYSxzdWI6dWksc3VidHJhY3Q6dWksdHJhbnNsYXRlOmxpLHRyYW5zcG9zZTpWbn0pLGtuOyhmdW5jdGlvbihlKXtlW2UuQ09MMFJPVzA9MF09IkNPTDBST1cwIixlW2UuQ09MMFJPVzE9MV09IkNPTDBST1cxIixlW2UuQ09MMFJPVzI9Ml09IkNPTDBST1cyIixlW2UuQ09MMVJPVzA9M109IkNPTDFST1cwIixlW2UuQ09MMVJPVzE9NF09IkNPTDFST1cxIixlW2UuQ09MMVJPVzI9NV09IkNPTDFST1cyIixlW2UuQ09MMlJPVzA9Nl09IkNPTDJST1cwIixlW2UuQ09MMlJPVzE9N109IkNPTDJST1cxIixlW2UuQ09MMlJPVzI9OF09IkNPTDJST1cyIn0pKGtufHwoa249e30pKTtjb25zdCBJYT1PYmplY3QuZnJlZXplKFsxLDAsMCwwLDEsMCwwLDAsMV0pO2NsYXNzIGN0IGV4dGVuZHMgQ257c3RhdGljIGdldCBJREVOVElUWSgpe3JldHVybiBMYSgpfXN0YXRpYyBnZXQgWkVSTygpe3JldHVybiBTYSgpfWdldCBFTEVNRU5UUygpe3JldHVybiA5fWdldCBSQU5LKCl7cmV0dXJuIDN9Z2V0IElORElDRVMoKXtyZXR1cm4ga259Y29uc3RydWN0b3IodCwuLi5uKXtzdXBlcigtMCwtMCwtMCwtMCwtMCwtMCwtMCwtMCwtMCksYXJndW1lbnRzLmxlbmd0aD09PTEmJkFycmF5LmlzQXJyYXkodCk/dGhpcy5jb3B5KHQpOm4ubGVuZ3RoPjA/dGhpcy5jb3B5KFt0LC4uLm5dKTp0aGlzLmlkZW50aXR5KCl9Y29weSh0KXtyZXR1cm4gdGhpc1swXT10WzBdLHRoaXNbMV09dFsxXSx0aGlzWzJdPXRbMl0sdGhpc1szXT10WzNdLHRoaXNbNF09dFs0XSx0aGlzWzVdPXRbNV0sdGhpc1s2XT10WzZdLHRoaXNbN109dFs3XSx0aGlzWzhdPXRbOF0sdGhpcy5jaGVjaygpfWlkZW50aXR5KCl7cmV0dXJuIHRoaXMuY29weShJYSl9ZnJvbU9iamVjdCh0KXtyZXR1cm4gdGhpcy5jaGVjaygpfWZyb21RdWF0ZXJuaW9uKHQpe3JldHVybiBmaSh0aGlzLHQpLHRoaXMuY2hlY2soKX1zZXQodCxuLHIsaSxzLG8sYyxsLGgpe3JldHVybiB0aGlzWzBdPXQsdGhpc1sxXT1uLHRoaXNbMl09cix0aGlzWzNdPWksdGhpc1s0XT1zLHRoaXNbNV09byx0aGlzWzZdPWMsdGhpc1s3XT1sLHRoaXNbOF09aCx0aGlzLmNoZWNrKCl9c2V0Um93TWFqb3IodCxuLHIsaSxzLG8sYyxsLGgpe3JldHVybiB0aGlzWzBdPXQsdGhpc1sxXT1pLHRoaXNbMl09Yyx0aGlzWzNdPW4sdGhpc1s0XT1zLHRoaXNbNV09bCx0aGlzWzZdPXIsdGhpc1s3XT1vLHRoaXNbOF09aCx0aGlzLmNoZWNrKCl9ZGV0ZXJtaW5hbnQoKXtyZXR1cm4gbGUodGhpcyl9dHJhbnNwb3NlKCl7cmV0dXJuIFZuKHRoaXMsdGhpcyksdGhpcy5jaGVjaygpfWludmVydCgpe3JldHVybiBObih0aGlzLHRoaXMpLHRoaXMuY2hlY2soKX1tdWx0aXBseUxlZnQodCl7cmV0dXJuIERlKHRoaXMsdCx0aGlzKSx0aGlzLmNoZWNrKCl9bXVsdGlwbHlSaWdodCh0KXtyZXR1cm4gRGUodGhpcyx0aGlzLHQpLHRoaXMuY2hlY2soKX1yb3RhdGUodCl7cmV0dXJuIGhpKHRoaXMsdGhpcyx0KSx0aGlzLmNoZWNrKCl9c2NhbGUodCl7cmV0dXJuIEFycmF5LmlzQXJyYXkodCk/JG4odGhpcyx0aGlzLHQpOiRuKHRoaXMsdGhpcyxbdCx0XSksdGhpcy5jaGVjaygpfXRyYW5zbGF0ZSh0KXtyZXR1cm4gbGkodGhpcyx0aGlzLHQpLHRoaXMuY2hlY2soKX10cmFuc2Zvcm0odCxuKXtsZXQgcjtzd2l0Y2godC5sZW5ndGgpe2Nhc2UgMjpyPVRuKG58fFstMCwtMF0sdCx0aGlzKTticmVhaztjYXNlIDM6cj1MbihufHxbLTAsLTAsLTBdLHQsdGhpcyk7YnJlYWs7Y2FzZSA0OnI9SnIobnx8Wy0wLC0wLC0wLC0wXSx0LHRoaXMpO2JyZWFrO2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKCJJbGxlZ2FsIHZlY3RvciIpfXJldHVybiBhZShyLHQubGVuZ3RoKSxyfXRyYW5zZm9ybVZlY3Rvcih0LG4pe3JldHVybiB0aGlzLnRyYW5zZm9ybSh0LG4pfXRyYW5zZm9ybVZlY3RvcjIodCxuKXtyZXR1cm4gdGhpcy50cmFuc2Zvcm0odCxuKX10cmFuc2Zvcm1WZWN0b3IzKHQsbil7cmV0dXJuIHRoaXMudHJhbnNmb3JtKHQsbil9fWxldCBCZSxZZT1udWxsO2Z1bmN0aW9uIFNhKCl7cmV0dXJuIEJlfHwoQmU9bmV3IGN0KFswLDAsMCwwLDAsMCwwLDAsMF0pLE9iamVjdC5mcmVlemUoQmUpKSxCZX1mdW5jdGlvbiBMYSgpe3JldHVybiBZZXx8KFllPW5ldyBjdCxPYmplY3QuZnJlZXplKFllKSksWWV9ZnVuY3Rpb24gUGEoKXtjb25zdCBlPW5ldyBEKDE2KTtyZXR1cm4gRCE9RmxvYXQzMkFycmF5JiYoZVsxXT0wLGVbMl09MCxlWzNdPTAsZVs0XT0wLGVbNl09MCxlWzddPTAsZVs4XT0wLGVbOV09MCxlWzExXT0wLGVbMTJdPTAsZVsxM109MCxlWzE0XT0wKSxlWzBdPTEsZVs1XT0xLGVbMTBdPTEsZVsxNV09MSxlfWZ1bmN0aW9uIFJhKGUpe2NvbnN0IHQ9bmV3IEQoMTYpO3JldHVybiB0WzBdPWVbMF0sdFsxXT1lWzFdLHRbMl09ZVsyXSx0WzNdPWVbM10sdFs0XT1lWzRdLHRbNV09ZVs1XSx0WzZdPWVbNl0sdFs3XT1lWzddLHRbOF09ZVs4XSx0WzldPWVbOV0sdFsxMF09ZVsxMF0sdFsxMV09ZVsxMV0sdFsxMl09ZVsxMl0sdFsxM109ZVsxM10sdFsxNF09ZVsxNF0sdFsxNV09ZVsxNV0sdH1mdW5jdGlvbiBDYShlLHQpe3JldHVybiBlWzBdPXRbMF0sZVsxXT10WzFdLGVbMl09dFsyXSxlWzNdPXRbM10sZVs0XT10WzRdLGVbNV09dFs1XSxlWzZdPXRbNl0sZVs3XT10WzddLGVbOF09dFs4XSxlWzldPXRbOV0sZVsxMF09dFsxMF0sZVsxMV09dFsxMV0sZVsxMl09dFsxMl0sZVsxM109dFsxM10sZVsxNF09dFsxNF0sZVsxNV09dFsxNV0sZX1mdW5jdGlvbiBWYShlLHQsbixyLGkscyxvLGMsbCxoLGYsdSxkLGcsbSxfKXtjb25zdCBwPW5ldyBEKDE2KTtyZXR1cm4gcFswXT1lLHBbMV09dCxwWzJdPW4scFszXT1yLHBbNF09aSxwWzVdPXMscFs2XT1vLHBbN109YyxwWzhdPWwscFs5XT1oLHBbMTBdPWYscFsxMV09dSxwWzEyXT1kLHBbMTNdPWcscFsxNF09bSxwWzE1XT1fLHB9ZnVuY3Rpb24gTmEoZSx0LG4scixpLHMsbyxjLGwsaCxmLHUsZCxnLG0sXyxwKXtyZXR1cm4gZVswXT10LGVbMV09bixlWzJdPXIsZVszXT1pLGVbNF09cyxlWzVdPW8sZVs2XT1jLGVbN109bCxlWzhdPWgsZVs5XT1mLGVbMTBdPXUsZVsxMV09ZCxlWzEyXT1nLGVbMTNdPW0sZVsxNF09XyxlWzE1XT1wLGV9ZnVuY3Rpb24gZGkoZSl7cmV0dXJuIGVbMF09MSxlWzFdPTAsZVsyXT0wLGVbM109MCxlWzRdPTAsZVs1XT0xLGVbNl09MCxlWzddPTAsZVs4XT0wLGVbOV09MCxlWzEwXT0xLGVbMTFdPTAsZVsxMl09MCxlWzEzXT0wLGVbMTRdPTAsZVsxNV09MSxlfWZ1bmN0aW9uIGdpKGUsdCl7aWYoZT09PXQpe2NvbnN0IG49dFsxXSxyPXRbMl0saT10WzNdLHM9dFs2XSxvPXRbN10sYz10WzExXTtlWzFdPXRbNF0sZVsyXT10WzhdLGVbM109dFsxMl0sZVs0XT1uLGVbNl09dFs5XSxlWzddPXRbMTNdLGVbOF09cixlWzldPXMsZVsxMV09dFsxNF0sZVsxMl09aSxlWzEzXT1vLGVbMTRdPWN9ZWxzZSBlWzBdPXRbMF0sZVsxXT10WzRdLGVbMl09dFs4XSxlWzNdPXRbMTJdLGVbNF09dFsxXSxlWzVdPXRbNV0sZVs2XT10WzldLGVbN109dFsxM10sZVs4XT10WzJdLGVbOV09dFs2XSxlWzEwXT10WzEwXSxlWzExXT10WzE0XSxlWzEyXT10WzNdLGVbMTNdPXRbN10sZVsxNF09dFsxMV0sZVsxNV09dFsxNV07cmV0dXJuIGV9ZnVuY3Rpb24gbWkoZSx0KXtjb25zdCBuPXRbMF0scj10WzFdLGk9dFsyXSxzPXRbM10sbz10WzRdLGM9dFs1XSxsPXRbNl0saD10WzddLGY9dFs4XSx1PXRbOV0sZD10WzEwXSxnPXRbMTFdLG09dFsxMl0sXz10WzEzXSxwPXRbMTRdLE09dFsxNV0sQT1uKmMtcipvLHg9bipsLWkqbyxUPW4qaC1zKm8sTz1yKmwtaSpjLHc9cipoLXMqYyxTPWkqaC1zKmwsYj1mKl8tdSptLEk9ZipwLWQqbSxFPWYqTS1nKm0sVj11KnAtZCpfLE49dSpNLWcqXywkPWQqTS1nKnA7bGV0IEw9QSokLXgqTitUKlYrTypFLXcqSStTKmI7cmV0dXJuIEw/KEw9MS9MLGVbMF09KGMqJC1sKk4raCpWKSpMLGVbMV09KGkqTi1yKiQtcypWKSpMLGVbMl09KF8qUy1wKncrTSpPKSpMLGVbM109KGQqdy11KlMtZypPKSpMLGVbNF09KGwqRS1vKiQtaCpJKSpMLGVbNV09KG4qJC1pKkUrcypJKSpMLGVbNl09KHAqVC1tKlMtTSp4KSpMLGVbN109KGYqUy1kKlQrZyp4KSpMLGVbOF09KG8qTi1jKkUraCpiKSpMLGVbOV09KHIqRS1uKk4tcypiKSpMLGVbMTBdPShtKnctXypUK00qQSkqTCxlWzExXT0odSpULWYqdy1nKkEpKkwsZVsxMl09KGMqSS1vKlYtbCpiKSpMLGVbMTNdPShuKlYtcipJK2kqYikqTCxlWzE0XT0oXyp4LW0qTy1wKkEpKkwsZVsxNV09KGYqTy11KngrZCpBKSpMLGUpOm51bGx9ZnVuY3Rpb24gJGEoZSx0KXtjb25zdCBuPXRbMF0scj10WzFdLGk9dFsyXSxzPXRbM10sbz10WzRdLGM9dFs1XSxsPXRbNl0saD10WzddLGY9dFs4XSx1PXRbOV0sZD10WzEwXSxnPXRbMTFdLG09dFsxMl0sXz10WzEzXSxwPXRbMTRdLE09dFsxNV0sQT1uKmMtcipvLHg9bipsLWkqbyxUPW4qaC1zKm8sTz1yKmwtaSpjLHc9cipoLXMqYyxTPWkqaC1zKmwsYj1mKl8tdSptLEk9ZipwLWQqbSxFPWYqTS1nKm0sVj11KnAtZCpfLE49dSpNLWcqXywkPWQqTS1nKnA7cmV0dXJuIGVbMF09YyokLWwqTitoKlYsZVsxXT1pKk4tciokLXMqVixlWzJdPV8qUy1wKncrTSpPLGVbM109ZCp3LXUqUy1nKk8sZVs0XT1sKkUtbyokLWgqSSxlWzVdPW4qJC1pKkUrcypJLGVbNl09cCpULW0qUy1NKngsZVs3XT1mKlMtZCpUK2cqeCxlWzhdPW8qTi1jKkUraCpiLGVbOV09cipFLW4qTi1zKmIsZVsxMF09bSp3LV8qVCtNKkEsZVsxMV09dSpULWYqdy1nKkEsZVsxMl09YypJLW8qVi1sKmIsZVsxM109bipWLXIqSStpKmIsZVsxNF09Xyp4LW0qTy1wKkEsZVsxNV09ZipPLXUqeCtkKkEsZX1mdW5jdGlvbiBwaShlKXtjb25zdCB0PWVbMF0sbj1lWzFdLHI9ZVsyXSxpPWVbM10scz1lWzRdLG89ZVs1XSxjPWVbNl0sbD1lWzddLGg9ZVs4XSxmPWVbOV0sdT1lWzEwXSxkPWVbMTFdLGc9ZVsxMl0sbT1lWzEzXSxfPWVbMTRdLHA9ZVsxNV0sTT10Km8tbipzLEE9dCpjLXIqcyx4PW4qYy1yKm8sVD1oKm0tZipnLE89aCpfLXUqZyx3PWYqXy11Km0sUz10KnctbipPK3IqVCxiPXMqdy1vKk8rYypULEk9aCp4LWYqQSt1Kk0sRT1nKngtbSpBK18qTTtyZXR1cm4gbCpTLWkqYitwKkktZCpFfWZ1bmN0aW9uIFdlKGUsdCxuKXtjb25zdCByPXRbMF0saT10WzFdLHM9dFsyXSxvPXRbM10sYz10WzRdLGw9dFs1XSxoPXRbNl0sZj10WzddLHU9dFs4XSxkPXRbOV0sZz10WzEwXSxtPXRbMTFdLF89dFsxMl0scD10WzEzXSxNPXRbMTRdLEE9dFsxNV07bGV0IHg9blswXSxUPW5bMV0sTz1uWzJdLHc9blszXTtyZXR1cm4gZVswXT14KnIrVCpjK08qdSt3Kl8sZVsxXT14KmkrVCpsK08qZCt3KnAsZVsyXT14KnMrVCpoK08qZyt3Kk0sZVszXT14Km8rVCpmK08qbSt3KkEseD1uWzRdLFQ9bls1XSxPPW5bNl0sdz1uWzddLGVbNF09eCpyK1QqYytPKnUrdypfLGVbNV09eCppK1QqbCtPKmQrdypwLGVbNl09eCpzK1QqaCtPKmcrdypNLGVbN109eCpvK1QqZitPKm0rdypBLHg9bls4XSxUPW5bOV0sTz1uWzEwXSx3PW5bMTFdLGVbOF09eCpyK1QqYytPKnUrdypfLGVbOV09eCppK1QqbCtPKmQrdypwLGVbMTBdPXgqcytUKmgrTypnK3cqTSxlWzExXT14Km8rVCpmK08qbSt3KkEseD1uWzEyXSxUPW5bMTNdLE89blsxNF0sdz1uWzE1XSxlWzEyXT14KnIrVCpjK08qdSt3Kl8sZVsxM109eCppK1QqbCtPKmQrdypwLGVbMTRdPXgqcytUKmgrTypnK3cqTSxlWzE1XT14Km8rVCpmK08qbSt3KkEsZX1mdW5jdGlvbiBfaShlLHQsbil7Y29uc3Qgcj1uWzBdLGk9blsxXSxzPW5bMl07bGV0IG8sYyxsLGgsZix1LGQsZyxtLF8scCxNO3JldHVybiB0PT09ZT8oZVsxMl09dFswXSpyK3RbNF0qaSt0WzhdKnMrdFsxMl0sZVsxM109dFsxXSpyK3RbNV0qaSt0WzldKnMrdFsxM10sZVsxNF09dFsyXSpyK3RbNl0qaSt0WzEwXSpzK3RbMTRdLGVbMTVdPXRbM10qcit0WzddKmkrdFsxMV0qcyt0WzE1XSk6KG89dFswXSxjPXRbMV0sbD10WzJdLGg9dFszXSxmPXRbNF0sdT10WzVdLGQ9dFs2XSxnPXRbN10sbT10WzhdLF89dFs5XSxwPXRbMTBdLE09dFsxMV0sZVswXT1vLGVbMV09YyxlWzJdPWwsZVszXT1oLGVbNF09ZixlWzVdPXUsZVs2XT1kLGVbN109ZyxlWzhdPW0sZVs5XT1fLGVbMTBdPXAsZVsxMV09TSxlWzEyXT1vKnIrZippK20qcyt0WzEyXSxlWzEzXT1jKnIrdSppK18qcyt0WzEzXSxlWzE0XT1sKnIrZCppK3Aqcyt0WzE0XSxlWzE1XT1oKnIrZyppK00qcyt0WzE1XSksZX1mdW5jdGlvbiB5aShlLHQsbil7Y29uc3Qgcj1uWzBdLGk9blsxXSxzPW5bMl07cmV0dXJuIGVbMF09dFswXSpyLGVbMV09dFsxXSpyLGVbMl09dFsyXSpyLGVbM109dFszXSpyLGVbNF09dFs0XSppLGVbNV09dFs1XSppLGVbNl09dFs2XSppLGVbN109dFs3XSppLGVbOF09dFs4XSpzLGVbOV09dFs5XSpzLGVbMTBdPXRbMTBdKnMsZVsxMV09dFsxMV0qcyxlWzEyXT10WzEyXSxlWzEzXT10WzEzXSxlWzE0XT10WzE0XSxlWzE1XT10WzE1XSxlfWZ1bmN0aW9uIHhpKGUsdCxuLHIpe2xldCBpPXJbMF0scz1yWzFdLG89clsyXSxjPU1hdGguc3FydChpKmkrcypzK28qbyksbCxoLGYsdSxkLGcsbSxfLHAsTSxBLHgsVCxPLHcsUyxiLEksRSxWLE4sJCxMLEo7cmV0dXJuIGM8Qz9udWxsOihjPTEvYyxpKj1jLHMqPWMsbyo9YyxoPU1hdGguc2luKG4pLGw9TWF0aC5jb3MobiksZj0xLWwsdT10WzBdLGQ9dFsxXSxnPXRbMl0sbT10WzNdLF89dFs0XSxwPXRbNV0sTT10WzZdLEE9dFs3XSx4PXRbOF0sVD10WzldLE89dFsxMF0sdz10WzExXSxTPWkqaSpmK2wsYj1zKmkqZitvKmgsST1vKmkqZi1zKmgsRT1pKnMqZi1vKmgsVj1zKnMqZitsLE49bypzKmYraSpoLCQ9aSpvKmYrcypoLEw9cypvKmYtaSpoLEo9bypvKmYrbCxlWzBdPXUqUytfKmIreCpJLGVbMV09ZCpTK3AqYitUKkksZVsyXT1nKlMrTSpiK08qSSxlWzNdPW0qUytBKmIrdypJLGVbNF09dSpFK18qVit4Kk4sZVs1XT1kKkUrcCpWK1QqTixlWzZdPWcqRStNKlYrTypOLGVbN109bSpFK0EqVit3Kk4sZVs4XT11KiQrXypMK3gqSixlWzldPWQqJCtwKkwrVCpKLGVbMTBdPWcqJCtNKkwrTypKLGVbMTFdPW0qJCtBKkwrdypKLHQhPT1lJiYoZVsxMl09dFsxMl0sZVsxM109dFsxM10sZVsxNF09dFsxNF0sZVsxNV09dFsxNV0pLGUpfWZ1bmN0aW9uIE1pKGUsdCxuKXtjb25zdCByPU1hdGguc2luKG4pLGk9TWF0aC5jb3Mobikscz10WzRdLG89dFs1XSxjPXRbNl0sbD10WzddLGg9dFs4XSxmPXRbOV0sdT10WzEwXSxkPXRbMTFdO3JldHVybiB0IT09ZSYmKGVbMF09dFswXSxlWzFdPXRbMV0sZVsyXT10WzJdLGVbM109dFszXSxlWzEyXT10WzEyXSxlWzEzXT10WzEzXSxlWzE0XT10WzE0XSxlWzE1XT10WzE1XSksZVs0XT1zKmkraCpyLGVbNV09byppK2YqcixlWzZdPWMqaSt1KnIsZVs3XT1sKmkrZCpyLGVbOF09aCppLXMqcixlWzldPWYqaS1vKnIsZVsxMF09dSppLWMqcixlWzExXT1kKmktbCpyLGV9ZnVuY3Rpb24gd2koZSx0LG4pe2NvbnN0IHI9TWF0aC5zaW4obiksaT1NYXRoLmNvcyhuKSxzPXRbMF0sbz10WzFdLGM9dFsyXSxsPXRbM10saD10WzhdLGY9dFs5XSx1PXRbMTBdLGQ9dFsxMV07cmV0dXJuIHQhPT1lJiYoZVs0XT10WzRdLGVbNV09dFs1XSxlWzZdPXRbNl0sZVs3XT10WzddLGVbMTJdPXRbMTJdLGVbMTNdPXRbMTNdLGVbMTRdPXRbMTRdLGVbMTVdPXRbMTVdKSxlWzBdPXMqaS1oKnIsZVsxXT1vKmktZipyLGVbMl09YyppLXUqcixlWzNdPWwqaS1kKnIsZVs4XT1zKnIraCppLGVbOV09bypyK2YqaSxlWzEwXT1jKnIrdSppLGVbMTFdPWwqcitkKmksZX1mdW5jdGlvbiBBaShlLHQsbil7Y29uc3Qgcj1NYXRoLnNpbihuKSxpPU1hdGguY29zKG4pLHM9dFswXSxvPXRbMV0sYz10WzJdLGw9dFszXSxoPXRbNF0sZj10WzVdLHU9dFs2XSxkPXRbN107cmV0dXJuIHQhPT1lJiYoZVs4XT10WzhdLGVbOV09dFs5XSxlWzEwXT10WzEwXSxlWzExXT10WzExXSxlWzEyXT10WzEyXSxlWzEzXT10WzEzXSxlWzE0XT10WzE0XSxlWzE1XT10WzE1XSksZVswXT1zKmkraCpyLGVbMV09byppK2YqcixlWzJdPWMqaSt1KnIsZVszXT1sKmkrZCpyLGVbNF09aCppLXMqcixlWzVdPWYqaS1vKnIsZVs2XT11KmktYypyLGVbN109ZCppLWwqcixlfWZ1bmN0aW9uIHphKGUsdCl7cmV0dXJuIGVbMF09MSxlWzFdPTAsZVsyXT0wLGVbM109MCxlWzRdPTAsZVs1XT0xLGVbNl09MCxlWzddPTAsZVs4XT0wLGVbOV09MCxlWzEwXT0xLGVbMTFdPTAsZVsxMl09dFswXSxlWzEzXT10WzFdLGVbMTRdPXRbMl0sZVsxNV09MSxlfWZ1bmN0aW9uIGthKGUsdCl7cmV0dXJuIGVbMF09dFswXSxlWzFdPTAsZVsyXT0wLGVbM109MCxlWzRdPTAsZVs1XT10WzFdLGVbNl09MCxlWzddPTAsZVs4XT0wLGVbOV09MCxlWzEwXT10WzJdLGVbMTFdPTAsZVsxMl09MCxlWzEzXT0wLGVbMTRdPTAsZVsxNV09MSxlfWZ1bmN0aW9uIEZhKGUsdCxuKXtsZXQgcj1uWzBdLGk9blsxXSxzPW5bMl0sbz1NYXRoLnNxcnQocipyK2kqaStzKnMpLGMsbCxoO3JldHVybiBvPEM/bnVsbDoobz0xL28scio9byxpKj1vLHMqPW8sbD1NYXRoLnNpbih0KSxjPU1hdGguY29zKHQpLGg9MS1jLGVbMF09cipyKmgrYyxlWzFdPWkqcipoK3MqbCxlWzJdPXMqcipoLWkqbCxlWzNdPTAsZVs0XT1yKmkqaC1zKmwsZVs1XT1pKmkqaCtjLGVbNl09cyppKmgrcipsLGVbN109MCxlWzhdPXIqcypoK2kqbCxlWzldPWkqcypoLXIqbCxlWzEwXT1zKnMqaCtjLGVbMTFdPTAsZVsxMl09MCxlWzEzXT0wLGVbMTRdPTAsZVsxNV09MSxlKX1mdW5jdGlvbiBxYShlLHQpe2NvbnN0IG49TWF0aC5zaW4odCkscj1NYXRoLmNvcyh0KTtyZXR1cm4gZVswXT0xLGVbMV09MCxlWzJdPTAsZVszXT0wLGVbNF09MCxlWzVdPXIsZVs2XT1uLGVbN109MCxlWzhdPTAsZVs5XT0tbixlWzEwXT1yLGVbMTFdPTAsZVsxMl09MCxlWzEzXT0wLGVbMTRdPTAsZVsxNV09MSxlfWZ1bmN0aW9uIFVhKGUsdCl7Y29uc3Qgbj1NYXRoLnNpbih0KSxyPU1hdGguY29zKHQpO3JldHVybiBlWzBdPXIsZVsxXT0wLGVbMl09LW4sZVszXT0wLGVbNF09MCxlWzVdPTEsZVs2XT0wLGVbN109MCxlWzhdPW4sZVs5XT0wLGVbMTBdPXIsZVsxMV09MCxlWzEyXT0wLGVbMTNdPTAsZVsxNF09MCxlWzE1XT0xLGV9ZnVuY3Rpb24gRGEoZSx0KXtjb25zdCBuPU1hdGguc2luKHQpLHI9TWF0aC5jb3ModCk7cmV0dXJuIGVbMF09cixlWzFdPW4sZVsyXT0wLGVbM109MCxlWzRdPS1uLGVbNV09cixlWzZdPTAsZVs3XT0wLGVbOF09MCxlWzldPTAsZVsxMF09MSxlWzExXT0wLGVbMTJdPTAsZVsxM109MCxlWzE0XT0wLGVbMTVdPTEsZX1mdW5jdGlvbiBUaShlLHQsbil7Y29uc3Qgcj10WzBdLGk9dFsxXSxzPXRbMl0sbz10WzNdLGM9cityLGw9aStpLGg9cytzLGY9cipjLHU9cipsLGQ9cipoLGc9aSpsLG09aSpoLF89cypoLHA9bypjLE09bypsLEE9bypoO3JldHVybiBlWzBdPTEtKGcrXyksZVsxXT11K0EsZVsyXT1kLU0sZVszXT0wLGVbNF09dS1BLGVbNV09MS0oZitfKSxlWzZdPW0rcCxlWzddPTAsZVs4XT1kK00sZVs5XT1tLXAsZVsxMF09MS0oZitnKSxlWzExXT0wLGVbMTJdPW5bMF0sZVsxM109blsxXSxlWzE0XT1uWzJdLGVbMTVdPTEsZX1mdW5jdGlvbiBCYShlLHQpe2NvbnN0IG49bmV3IEQoMykscj0tdFswXSxpPS10WzFdLHM9LXRbMl0sbz10WzNdLGM9dFs0XSxsPXRbNV0saD10WzZdLGY9dFs3XSx1PXIqcitpKmkrcypzK28qbztyZXR1cm4gdT4wPyhuWzBdPShjKm8rZipyK2wqcy1oKmkpKjIvdSxuWzFdPShsKm8rZippK2gqci1jKnMpKjIvdSxuWzJdPShoKm8rZipzK2MqaS1sKnIpKjIvdSk6KG5bMF09KGMqbytmKnIrbCpzLWgqaSkqMixuWzFdPShsKm8rZippK2gqci1jKnMpKjIsblsyXT0oaCpvK2YqcytjKmktbCpyKSoyKSxUaShlLHQsbiksZX1mdW5jdGlvbiBZYShlLHQpe3JldHVybiBlWzBdPXRbMTJdLGVbMV09dFsxM10sZVsyXT10WzE0XSxlfWZ1bmN0aW9uIEVpKGUsdCl7Y29uc3Qgbj10WzBdLHI9dFsxXSxpPXRbMl0scz10WzRdLG89dFs1XSxjPXRbNl0sbD10WzhdLGg9dFs5XSxmPXRbMTBdO3JldHVybiBlWzBdPU1hdGguc3FydChuKm4rcipyK2kqaSksZVsxXT1NYXRoLnNxcnQocypzK28qbytjKmMpLGVbMl09TWF0aC5zcXJ0KGwqbCtoKmgrZipmKSxlfWZ1bmN0aW9uIFdhKGUsdCl7Y29uc3Qgbj1uZXcgRCgzKTtFaShuLHQpO2NvbnN0IHI9MS9uWzBdLGk9MS9uWzFdLHM9MS9uWzJdLG89dFswXSpyLGM9dFsxXSppLGw9dFsyXSpzLGg9dFs0XSpyLGY9dFs1XSppLHU9dFs2XSpzLGQ9dFs4XSpyLGc9dFs5XSppLG09dFsxMF0qcyxfPW8rZittO2xldCBwPTA7cmV0dXJuIF8+MD8ocD1NYXRoLnNxcnQoXysxKSoyLGVbM109LjI1KnAsZVswXT0odS1nKS9wLGVbMV09KGQtbCkvcCxlWzJdPShjLWgpL3ApOm8+ZiYmbz5tPyhwPU1hdGguc3FydCgxK28tZi1tKSoyLGVbM109KHUtZykvcCxlWzBdPS4yNSpwLGVbMV09KGMraCkvcCxlWzJdPShkK2wpL3ApOmY+bT8ocD1NYXRoLnNxcnQoMStmLW8tbSkqMixlWzNdPShkLWwpL3AsZVswXT0oYytoKS9wLGVbMV09LjI1KnAsZVsyXT0odStnKS9wKToocD1NYXRoLnNxcnQoMSttLW8tZikqMixlWzNdPShjLWgpL3AsZVswXT0oZCtsKS9wLGVbMV09KHUrZykvcCxlWzJdPS4yNSpwKSxlfWZ1bmN0aW9uIFphKGUsdCxuLHIpe3RbMF09clsxMl0sdFsxXT1yWzEzXSx0WzJdPXJbMTRdO2NvbnN0IGk9clswXSxzPXJbMV0sbz1yWzJdLGM9cls0XSxsPXJbNV0saD1yWzZdLGY9cls4XSx1PXJbOV0sZD1yWzEwXTtuWzBdPU1hdGguc3FydChpKmkrcypzK28qbyksblsxXT1NYXRoLnNxcnQoYypjK2wqbCtoKmgpLG5bMl09TWF0aC5zcXJ0KGYqZit1KnUrZCpkKTtjb25zdCBnPTEvblswXSxtPTEvblsxXSxfPTEvblsyXSxwPWkqZyxNPXMqbSxBPW8qXyx4PWMqZyxUPWwqbSxPPWgqXyx3PWYqZyxTPXUqbSxiPWQqXyxJPXArVCtiO2xldCBFPTA7cmV0dXJuIEk+MD8oRT1NYXRoLnNxcnQoSSsxKSoyLGVbM109LjI1KkUsZVswXT0oTy1TKS9FLGVbMV09KHctQSkvRSxlWzJdPShNLXgpL0UpOnA+VCYmcD5iPyhFPU1hdGguc3FydCgxK3AtVC1iKSoyLGVbM109KE8tUykvRSxlWzBdPS4yNSpFLGVbMV09KE0reCkvRSxlWzJdPSh3K0EpL0UpOlQ+Yj8oRT1NYXRoLnNxcnQoMStULXAtYikqMixlWzNdPSh3LUEpL0UsZVswXT0oTSt4KS9FLGVbMV09LjI1KkUsZVsyXT0oTytTKS9FKTooRT1NYXRoLnNxcnQoMStiLXAtVCkqMixlWzNdPShNLXgpL0UsZVswXT0odytBKS9FLGVbMV09KE8rUykvRSxlWzJdPS4yNSpFKSxlfWZ1bmN0aW9uIEdhKGUsdCxuLHIpe2NvbnN0IGk9dFswXSxzPXRbMV0sbz10WzJdLGM9dFszXSxsPWkraSxoPXMrcyxmPW8rbyx1PWkqbCxkPWkqaCxnPWkqZixtPXMqaCxfPXMqZixwPW8qZixNPWMqbCxBPWMqaCx4PWMqZixUPXJbMF0sTz1yWzFdLHc9clsyXTtyZXR1cm4gZVswXT0oMS0obStwKSkqVCxlWzFdPShkK3gpKlQsZVsyXT0oZy1BKSpULGVbM109MCxlWzRdPShkLXgpKk8sZVs1XT0oMS0odStwKSkqTyxlWzZdPShfK00pKk8sZVs3XT0wLGVbOF09KGcrQSkqdyxlWzldPShfLU0pKncsZVsxMF09KDEtKHUrbSkpKncsZVsxMV09MCxlWzEyXT1uWzBdLGVbMTNdPW5bMV0sZVsxNF09blsyXSxlWzE1XT0xLGV9ZnVuY3Rpb24gWGEoZSx0LG4scixpKXtjb25zdCBzPXRbMF0sbz10WzFdLGM9dFsyXSxsPXRbM10saD1zK3MsZj1vK28sdT1jK2MsZD1zKmgsZz1zKmYsbT1zKnUsXz1vKmYscD1vKnUsTT1jKnUsQT1sKmgseD1sKmYsVD1sKnUsTz1yWzBdLHc9clsxXSxTPXJbMl0sYj1pWzBdLEk9aVsxXSxFPWlbMl0sVj0oMS0oXytNKSkqTyxOPShnK1QpKk8sJD0obS14KSpPLEw9KGctVCkqdyxKPSgxLShkK00pKSp3LE50PShwK0EpKncsJHQ9KG0reCkqUyxScj0ocC1BKSpTLE1uPSgxLShkK18pKSpTO3JldHVybiBlWzBdPVYsZVsxXT1OLGVbMl09JCxlWzNdPTAsZVs0XT1MLGVbNV09SixlWzZdPU50LGVbN109MCxlWzhdPSR0LGVbOV09UnIsZVsxMF09TW4sZVsxMV09MCxlWzEyXT1uWzBdK2ItKFYqYitMKkkrJHQqRSksZVsxM109blsxXStJLShOKmIrSipJK1JyKkUpLGVbMTRdPW5bMl0rRS0oJCpiK050KkkrTW4qRSksZVsxNV09MSxlfWZ1bmN0aW9uIE9pKGUsdCl7Y29uc3Qgbj10WzBdLHI9dFsxXSxpPXRbMl0scz10WzNdLG89bituLGM9cityLGw9aStpLGg9bipvLGY9cipvLHU9cipjLGQ9aSpvLGc9aSpjLG09aSpsLF89cypvLHA9cypjLE09cypsO3JldHVybiBlWzBdPTEtdS1tLGVbMV09ZitNLGVbMl09ZC1wLGVbM109MCxlWzRdPWYtTSxlWzVdPTEtaC1tLGVbNl09ZytfLGVbN109MCxlWzhdPWQrcCxlWzldPWctXyxlWzEwXT0xLWgtdSxlWzExXT0wLGVbMTJdPTAsZVsxM109MCxlWzE0XT0wLGVbMTVdPTEsZX1mdW5jdGlvbiB2aShlLHQsbixyLGkscyxvKXtjb25zdCBjPTEvKG4tdCksbD0xLyhpLXIpLGg9MS8ocy1vKTtyZXR1cm4gZVswXT1zKjIqYyxlWzFdPTAsZVsyXT0wLGVbM109MCxlWzRdPTAsZVs1XT1zKjIqbCxlWzZdPTAsZVs3XT0wLGVbOF09KG4rdCkqYyxlWzldPShpK3IpKmwsZVsxMF09KG8rcykqaCxlWzExXT0tMSxlWzEyXT0wLGVbMTNdPTAsZVsxNF09bypzKjIqaCxlWzE1XT0wLGV9ZnVuY3Rpb24gYmkoZSx0LG4scixpKXtjb25zdCBzPTEvTWF0aC50YW4odC8yKTtpZihlWzBdPXMvbixlWzFdPTAsZVsyXT0wLGVbM109MCxlWzRdPTAsZVs1XT1zLGVbNl09MCxlWzddPTAsZVs4XT0wLGVbOV09MCxlWzExXT0tMSxlWzEyXT0wLGVbMTNdPTAsZVsxNV09MCxpIT1udWxsJiZpIT09MS8wKXtjb25zdCBvPTEvKHItaSk7ZVsxMF09KGkrcikqbyxlWzE0XT0yKmkqcipvfWVsc2UgZVsxMF09LTEsZVsxNF09LTIqcjtyZXR1cm4gZX1jb25zdCBJaT1iaTtmdW5jdGlvbiBqYShlLHQsbixyLGkpe2NvbnN0IHM9MS9NYXRoLnRhbih0LzIpO2lmKGVbMF09cy9uLGVbMV09MCxlWzJdPTAsZVszXT0wLGVbNF09MCxlWzVdPXMsZVs2XT0wLGVbN109MCxlWzhdPTAsZVs5XT0wLGVbMTFdPS0xLGVbMTJdPTAsZVsxM109MCxlWzE1XT0wLGkhPW51bGwmJmkhPT0xLzApe2NvbnN0IG89MS8oci1pKTtlWzEwXT1pKm8sZVsxNF09aSpyKm99ZWxzZSBlWzEwXT0tMSxlWzE0XT0tcjtyZXR1cm4gZX1mdW5jdGlvbiBRYShlLHQsbixyKXtjb25zdCBpPU1hdGgudGFuKHQudXBEZWdyZWVzKk1hdGguUEkvMTgwKSxzPU1hdGgudGFuKHQuZG93bkRlZ3JlZXMqTWF0aC5QSS8xODApLG89TWF0aC50YW4odC5sZWZ0RGVncmVlcypNYXRoLlBJLzE4MCksYz1NYXRoLnRhbih0LnJpZ2h0RGVncmVlcypNYXRoLlBJLzE4MCksbD0yLyhvK2MpLGg9Mi8oaStzKTtyZXR1cm4gZVswXT1sLGVbMV09MCxlWzJdPTAsZVszXT0wLGVbNF09MCxlWzVdPWgsZVs2XT0wLGVbN109MCxlWzhdPS0oKG8tYykqbCouNSksZVs5XT0oaS1zKSpoKi41LGVbMTBdPXIvKG4tciksZVsxMV09LTEsZVsxMl09MCxlWzEzXT0wLGVbMTRdPXIqbi8obi1yKSxlWzE1XT0wLGV9ZnVuY3Rpb24gU2koZSx0LG4scixpLHMsbyl7Y29uc3QgYz0xLyh0LW4pLGw9MS8oci1pKSxoPTEvKHMtbyk7cmV0dXJuIGVbMF09LTIqYyxlWzFdPTAsZVsyXT0wLGVbM109MCxlWzRdPTAsZVs1XT0tMipsLGVbNl09MCxlWzddPTAsZVs4XT0wLGVbOV09MCxlWzEwXT0yKmgsZVsxMV09MCxlWzEyXT0odCtuKSpjLGVbMTNdPShpK3IpKmwsZVsxNF09KG8rcykqaCxlWzE1XT0xLGV9Y29uc3QgTGk9U2k7ZnVuY3Rpb24gS2EoZSx0LG4scixpLHMsbyl7Y29uc3QgYz0xLyh0LW4pLGw9MS8oci1pKSxoPTEvKHMtbyk7cmV0dXJuIGVbMF09LTIqYyxlWzFdPTAsZVsyXT0wLGVbM109MCxlWzRdPTAsZVs1XT0tMipsLGVbNl09MCxlWzddPTAsZVs4XT0wLGVbOV09MCxlWzEwXT1oLGVbMTFdPTAsZVsxMl09KHQrbikqYyxlWzEzXT0oaStyKSpsLGVbMTRdPXMqaCxlWzE1XT0xLGV9ZnVuY3Rpb24gUGkoZSx0LG4scil7bGV0IGkscyxvLGMsbCxoLGYsdSxkLGc7Y29uc3QgbT10WzBdLF89dFsxXSxwPXRbMl0sTT1yWzBdLEE9clsxXSx4PXJbMl0sVD1uWzBdLE89blsxXSx3PW5bMl07cmV0dXJuIE1hdGguYWJzKG0tVCk8QyYmTWF0aC5hYnMoXy1PKTxDJiZNYXRoLmFicyhwLXcpPEM/ZGkoZSk6KHU9bS1ULGQ9Xy1PLGc9cC13LGk9MS9NYXRoLnNxcnQodSp1K2QqZCtnKmcpLHUqPWksZCo9aSxnKj1pLHM9QSpnLXgqZCxvPXgqdS1NKmcsYz1NKmQtQSp1LGk9TWF0aC5zcXJ0KHMqcytvKm8rYypjKSxpPyhpPTEvaSxzKj1pLG8qPWksYyo9aSk6KHM9MCxvPTAsYz0wKSxsPWQqYy1nKm8saD1nKnMtdSpjLGY9dSpvLWQqcyxpPU1hdGguc3FydChsKmwraCpoK2YqZiksaT8oaT0xL2ksbCo9aSxoKj1pLGYqPWkpOihsPTAsaD0wLGY9MCksZVswXT1zLGVbMV09bCxlWzJdPXUsZVszXT0wLGVbNF09byxlWzVdPWgsZVs2XT1kLGVbN109MCxlWzhdPWMsZVs5XT1mLGVbMTBdPWcsZVsxMV09MCxlWzEyXT0tKHMqbStvKl8rYypwKSxlWzEzXT0tKGwqbStoKl8rZipwKSxlWzE0XT0tKHUqbStkKl8rZypwKSxlWzE1XT0xLGUpfWZ1bmN0aW9uIEphKGUsdCxuLHIpe2NvbnN0IGk9dFswXSxzPXRbMV0sbz10WzJdLGM9clswXSxsPXJbMV0saD1yWzJdO2xldCBmPWktblswXSx1PXMtblsxXSxkPW8tblsyXSxnPWYqZit1KnUrZCpkO2c+MCYmKGc9MS9NYXRoLnNxcnQoZyksZio9Zyx1Kj1nLGQqPWcpO2xldCBtPWwqZC1oKnUsXz1oKmYtYypkLHA9Yyp1LWwqZjtyZXR1cm4gZz1tKm0rXypfK3AqcCxnPjAmJihnPTEvTWF0aC5zcXJ0KGcpLG0qPWcsXyo9ZyxwKj1nKSxlWzBdPW0sZVsxXT1fLGVbMl09cCxlWzNdPTAsZVs0XT11KnAtZCpfLGVbNV09ZCptLWYqcCxlWzZdPWYqXy11Km0sZVs3XT0wLGVbOF09ZixlWzldPXUsZVsxMF09ZCxlWzExXT0wLGVbMTJdPWksZVsxM109cyxlWzE0XT1vLGVbMTVdPTEsZX1mdW5jdGlvbiBIYShlKXtyZXR1cm5gbWF0NCgke2VbMF19LCAke2VbMV19LCAke2VbMl19LCAke2VbM119LCAke2VbNF19LCAke2VbNV19LCAke2VbNl19LCAke2VbN119LCAke2VbOF19LCAke2VbOV19LCAke2VbMTBdfSwgJHtlWzExXX0sICR7ZVsxMl19LCAke2VbMTNdfSwgJHtlWzE0XX0sICR7ZVsxNV19KWB9ZnVuY3Rpb24gdGwoZSl7cmV0dXJuIE1hdGguc3FydChlWzBdKmVbMF0rZVsxXSplWzFdK2VbMl0qZVsyXStlWzNdKmVbM10rZVs0XSplWzRdK2VbNV0qZVs1XStlWzZdKmVbNl0rZVs3XSplWzddK2VbOF0qZVs4XStlWzldKmVbOV0rZVsxMF0qZVsxMF0rZVsxMV0qZVsxMV0rZVsxMl0qZVsxMl0rZVsxM10qZVsxM10rZVsxNF0qZVsxNF0rZVsxNV0qZVsxNV0pfWZ1bmN0aW9uIGVsKGUsdCxuKXtyZXR1cm4gZVswXT10WzBdK25bMF0sZVsxXT10WzFdK25bMV0sZVsyXT10WzJdK25bMl0sZVszXT10WzNdK25bM10sZVs0XT10WzRdK25bNF0sZVs1XT10WzVdK25bNV0sZVs2XT10WzZdK25bNl0sZVs3XT10WzddK25bN10sZVs4XT10WzhdK25bOF0sZVs5XT10WzldK25bOV0sZVsxMF09dFsxMF0rblsxMF0sZVsxMV09dFsxMV0rblsxMV0sZVsxMl09dFsxMl0rblsxMl0sZVsxM109dFsxM10rblsxM10sZVsxNF09dFsxNF0rblsxNF0sZVsxNV09dFsxNV0rblsxNV0sZX1mdW5jdGlvbiBSaShlLHQsbil7cmV0dXJuIGVbMF09dFswXS1uWzBdLGVbMV09dFsxXS1uWzFdLGVbMl09dFsyXS1uWzJdLGVbM109dFszXS1uWzNdLGVbNF09dFs0XS1uWzRdLGVbNV09dFs1XS1uWzVdLGVbNl09dFs2XS1uWzZdLGVbN109dFs3XS1uWzddLGVbOF09dFs4XS1uWzhdLGVbOV09dFs5XS1uWzldLGVbMTBdPXRbMTBdLW5bMTBdLGVbMTFdPXRbMTFdLW5bMTFdLGVbMTJdPXRbMTJdLW5bMTJdLGVbMTNdPXRbMTNdLW5bMTNdLGVbMTRdPXRbMTRdLW5bMTRdLGVbMTVdPXRbMTVdLW5bMTVdLGV9ZnVuY3Rpb24gbmwoZSx0LG4pe3JldHVybiBlWzBdPXRbMF0qbixlWzFdPXRbMV0qbixlWzJdPXRbMl0qbixlWzNdPXRbM10qbixlWzRdPXRbNF0qbixlWzVdPXRbNV0qbixlWzZdPXRbNl0qbixlWzddPXRbN10qbixlWzhdPXRbOF0qbixlWzldPXRbOV0qbixlWzEwXT10WzEwXSpuLGVbMTFdPXRbMTFdKm4sZVsxMl09dFsxMl0qbixlWzEzXT10WzEzXSpuLGVbMTRdPXRbMTRdKm4sZVsxNV09dFsxNV0qbixlfWZ1bmN0aW9uIHJsKGUsdCxuLHIpe3JldHVybiBlWzBdPXRbMF0rblswXSpyLGVbMV09dFsxXStuWzFdKnIsZVsyXT10WzJdK25bMl0qcixlWzNdPXRbM10rblszXSpyLGVbNF09dFs0XStuWzRdKnIsZVs1XT10WzVdK25bNV0qcixlWzZdPXRbNl0rbls2XSpyLGVbN109dFs3XStuWzddKnIsZVs4XT10WzhdK25bOF0qcixlWzldPXRbOV0rbls5XSpyLGVbMTBdPXRbMTBdK25bMTBdKnIsZVsxMV09dFsxMV0rblsxMV0qcixlWzEyXT10WzEyXStuWzEyXSpyLGVbMTNdPXRbMTNdK25bMTNdKnIsZVsxNF09dFsxNF0rblsxNF0qcixlWzE1XT10WzE1XStuWzE1XSpyLGV9ZnVuY3Rpb24gaWwoZSx0KXtyZXR1cm4gZVswXT09PXRbMF0mJmVbMV09PT10WzFdJiZlWzJdPT09dFsyXSYmZVszXT09PXRbM10mJmVbNF09PT10WzRdJiZlWzVdPT09dFs1XSYmZVs2XT09PXRbNl0mJmVbN109PT10WzddJiZlWzhdPT09dFs4XSYmZVs5XT09PXRbOV0mJmVbMTBdPT09dFsxMF0mJmVbMTFdPT09dFsxMV0mJmVbMTJdPT09dFsxMl0mJmVbMTNdPT09dFsxM10mJmVbMTRdPT09dFsxNF0mJmVbMTVdPT09dFsxNV19ZnVuY3Rpb24gc2woZSx0KXtjb25zdCBuPWVbMF0scj1lWzFdLGk9ZVsyXSxzPWVbM10sbz1lWzRdLGM9ZVs1XSxsPWVbNl0saD1lWzddLGY9ZVs4XSx1PWVbOV0sZD1lWzEwXSxnPWVbMTFdLG09ZVsxMl0sXz1lWzEzXSxwPWVbMTRdLE09ZVsxNV0sQT10WzBdLHg9dFsxXSxUPXRbMl0sTz10WzNdLHc9dFs0XSxTPXRbNV0sYj10WzZdLEk9dFs3XSxFPXRbOF0sVj10WzldLE49dFsxMF0sJD10WzExXSxMPXRbMTJdLEo9dFsxM10sTnQ9dFsxNF0sJHQ9dFsxNV07cmV0dXJuIE1hdGguYWJzKG4tQSk8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhuKSxNYXRoLmFicyhBKSkmJk1hdGguYWJzKHIteCk8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhyKSxNYXRoLmFicyh4KSkmJk1hdGguYWJzKGktVCk8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhpKSxNYXRoLmFicyhUKSkmJk1hdGguYWJzKHMtTyk8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhzKSxNYXRoLmFicyhPKSkmJk1hdGguYWJzKG8tdyk8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhvKSxNYXRoLmFicyh3KSkmJk1hdGguYWJzKGMtUyk8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhjKSxNYXRoLmFicyhTKSkmJk1hdGguYWJzKGwtYik8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhsKSxNYXRoLmFicyhiKSkmJk1hdGguYWJzKGgtSSk8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhoKSxNYXRoLmFicyhJKSkmJk1hdGguYWJzKGYtRSk8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhmKSxNYXRoLmFicyhFKSkmJk1hdGguYWJzKHUtVik8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyh1KSxNYXRoLmFicyhWKSkmJk1hdGguYWJzKGQtTik8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhkKSxNYXRoLmFicyhOKSkmJk1hdGguYWJzKGctJCk8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhnKSxNYXRoLmFicygkKSkmJk1hdGguYWJzKG0tTCk8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhtKSxNYXRoLmFicyhMKSkmJk1hdGguYWJzKF8tSik8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhfKSxNYXRoLmFicyhKKSkmJk1hdGguYWJzKHAtTnQpPD1DKk1hdGgubWF4KDEsTWF0aC5hYnMocCksTWF0aC5hYnMoTnQpKSYmTWF0aC5hYnMoTS0kdCk8PUMqTWF0aC5tYXgoMSxNYXRoLmFicyhNKSxNYXRoLmFicygkdCkpfXZhciBvbD1PYmplY3QuZnJlZXplKHtfX3Byb3RvX186bnVsbCxhZGQ6ZWwsYWRqb2ludDokYSxjbG9uZTpSYSxjb3B5OkNhLGNyZWF0ZTpQYSxkZWNvbXBvc2U6WmEsZGV0ZXJtaW5hbnQ6cGksZXF1YWxzOnNsLGV4YWN0RXF1YWxzOmlsLGZyb2I6dGwsZnJvbVF1YXQ6T2ksZnJvbVF1YXQyOkJhLGZyb21Sb3RhdGlvbjpGYSxmcm9tUm90YXRpb25UcmFuc2xhdGlvbjpUaSxmcm9tUm90YXRpb25UcmFuc2xhdGlvblNjYWxlOkdhLGZyb21Sb3RhdGlvblRyYW5zbGF0aW9uU2NhbGVPcmlnaW46WGEsZnJvbVNjYWxpbmc6a2EsZnJvbVRyYW5zbGF0aW9uOnphLGZyb21WYWx1ZXM6VmEsZnJvbVhSb3RhdGlvbjpxYSxmcm9tWVJvdGF0aW9uOlVhLGZyb21aUm90YXRpb246RGEsZnJ1c3R1bTp2aSxnZXRSb3RhdGlvbjpXYSxnZXRTY2FsaW5nOkVpLGdldFRyYW5zbGF0aW9uOllhLGlkZW50aXR5OmRpLGludmVydDptaSxsb29rQXQ6UGksbXVsOldlLG11bHRpcGx5OldlLG11bHRpcGx5U2NhbGFyOm5sLG11bHRpcGx5U2NhbGFyQW5kQWRkOnJsLG9ydGhvOkxpLG9ydGhvTk86U2ksb3J0aG9aTzpLYSxwZXJzcGVjdGl2ZTpJaSxwZXJzcGVjdGl2ZUZyb21GaWVsZE9mVmlldzpRYSxwZXJzcGVjdGl2ZU5POmJpLHBlcnNwZWN0aXZlWk86amEscm90YXRlOnhpLHJvdGF0ZVg6TWkscm90YXRlWTp3aSxyb3RhdGVaOkFpLHNjYWxlOnlpLHNldDpOYSxzdHI6SGEsc3ViOlJpLHN1YnRyYWN0OlJpLHRhcmdldFRvOkphLHRyYW5zbGF0ZTpfaSx0cmFuc3Bvc2U6Z2l9KTtmdW5jdGlvbiBDaSgpe2NvbnN0IGU9bmV3IEQoNCk7cmV0dXJuIEQhPUZsb2F0MzJBcnJheSYmKGVbMF09MCxlWzFdPTAsZVsyXT0wLGVbM109MCksZX1mdW5jdGlvbiBjbChlKXtjb25zdCB0PW5ldyBEKDQpO3JldHVybiB0WzBdPWVbMF0sdFsxXT1lWzFdLHRbMl09ZVsyXSx0WzNdPWVbM10sdH1mdW5jdGlvbiBhbChlLHQsbixyKXtjb25zdCBpPW5ldyBEKDQpO3JldHVybiBpWzBdPWUsaVsxXT10LGlbMl09bixpWzNdPXIsaX1mdW5jdGlvbiBsbChlLHQpe3JldHVybiBlWzBdPXRbMF0sZVsxXT10WzFdLGVbMl09dFsyXSxlWzNdPXRbM10sZX1mdW5jdGlvbiBobChlLHQsbixyLGkpe3JldHVybiBlWzBdPXQsZVsxXT1uLGVbMl09cixlWzNdPWksZX1mdW5jdGlvbiBWaShlLHQsbil7cmV0dXJuIGVbMF09dFswXStuWzBdLGVbMV09dFsxXStuWzFdLGVbMl09dFsyXStuWzJdLGVbM109dFszXStuWzNdLGV9ZnVuY3Rpb24gTmkoZSx0LG4pe3JldHVybiBlWzBdPXRbMF0tblswXSxlWzFdPXRbMV0tblsxXSxlWzJdPXRbMl0tblsyXSxlWzNdPXRbM10tblszXSxlfWZ1bmN0aW9uICRpKGUsdCxuKXtyZXR1cm4gZVswXT10WzBdKm5bMF0sZVsxXT10WzFdKm5bMV0sZVsyXT10WzJdKm5bMl0sZVszXT10WzNdKm5bM10sZX1mdW5jdGlvbiB6aShlLHQsbil7cmV0dXJuIGVbMF09dFswXS9uWzBdLGVbMV09dFsxXS9uWzFdLGVbMl09dFsyXS9uWzJdLGVbM109dFszXS9uWzNdLGV9ZnVuY3Rpb24gZmwoZSx0KXtyZXR1cm4gZVswXT1NYXRoLmNlaWwodFswXSksZVsxXT1NYXRoLmNlaWwodFsxXSksZVsyXT1NYXRoLmNlaWwodFsyXSksZVszXT1NYXRoLmNlaWwodFszXSksZX1mdW5jdGlvbiB1bChlLHQpe3JldHVybiBlWzBdPU1hdGguZmxvb3IodFswXSksZVsxXT1NYXRoLmZsb29yKHRbMV0pLGVbMl09TWF0aC5mbG9vcih0WzJdKSxlWzNdPU1hdGguZmxvb3IodFszXSksZX1mdW5jdGlvbiBkbChlLHQsbil7cmV0dXJuIGVbMF09TWF0aC5taW4odFswXSxuWzBdKSxlWzFdPU1hdGgubWluKHRbMV0sblsxXSksZVsyXT1NYXRoLm1pbih0WzJdLG5bMl0pLGVbM109TWF0aC5taW4odFszXSxuWzNdKSxlfWZ1bmN0aW9uIGdsKGUsdCxuKXtyZXR1cm4gZVswXT1NYXRoLm1heCh0WzBdLG5bMF0pLGVbMV09TWF0aC5tYXgodFsxXSxuWzFdKSxlWzJdPU1hdGgubWF4KHRbMl0sblsyXSksZVszXT1NYXRoLm1heCh0WzNdLG5bM10pLGV9ZnVuY3Rpb24gbWwoZSx0KXtyZXR1cm4gZVswXT15dCh0WzBdKSxlWzFdPXl0KHRbMV0pLGVbMl09eXQodFsyXSksZVszXT15dCh0WzNdKSxlfWZ1bmN0aW9uIGtpKGUsdCxuKXtyZXR1cm4gZVswXT10WzBdKm4sZVsxXT10WzFdKm4sZVsyXT10WzJdKm4sZVszXT10WzNdKm4sZX1mdW5jdGlvbiBwbChlLHQsbixyKXtyZXR1cm4gZVswXT10WzBdK25bMF0qcixlWzFdPXRbMV0rblsxXSpyLGVbMl09dFsyXStuWzJdKnIsZVszXT10WzNdK25bM10qcixlfWZ1bmN0aW9uIEZpKGUsdCl7Y29uc3Qgbj10WzBdLWVbMF0scj10WzFdLWVbMV0saT10WzJdLWVbMl0scz10WzNdLWVbM107cmV0dXJuIE1hdGguc3FydChuKm4rcipyK2kqaStzKnMpfWZ1bmN0aW9uIHFpKGUsdCl7Y29uc3Qgbj10WzBdLWVbMF0scj10WzFdLWVbMV0saT10WzJdLWVbMl0scz10WzNdLWVbM107cmV0dXJuIG4qbityKnIraSppK3Mqc31mdW5jdGlvbiBGbihlKXtjb25zdCB0PWVbMF0sbj1lWzFdLHI9ZVsyXSxpPWVbM107cmV0dXJuIE1hdGguc3FydCh0KnQrbipuK3IqcitpKmkpfWZ1bmN0aW9uIHFuKGUpe2NvbnN0IHQ9ZVswXSxuPWVbMV0scj1lWzJdLGk9ZVszXTtyZXR1cm4gdCp0K24qbityKnIraSppfWZ1bmN0aW9uIF9sKGUsdCl7cmV0dXJuIGVbMF09LXRbMF0sZVsxXT0tdFsxXSxlWzJdPS10WzJdLGVbM109LXRbM10sZX1mdW5jdGlvbiB5bChlLHQpe3JldHVybiBlWzBdPTEvdFswXSxlWzFdPTEvdFsxXSxlWzJdPTEvdFsyXSxlWzNdPTEvdFszXSxlfWZ1bmN0aW9uIFVpKGUsdCl7Y29uc3Qgbj10WzBdLHI9dFsxXSxpPXRbMl0scz10WzNdO2xldCBvPW4qbityKnIraSppK3MqcztyZXR1cm4gbz4wJiYobz0xL01hdGguc3FydChvKSksZVswXT1uKm8sZVsxXT1yKm8sZVsyXT1pKm8sZVszXT1zKm8sZX1mdW5jdGlvbiBEaShlLHQpe3JldHVybiBlWzBdKnRbMF0rZVsxXSp0WzFdK2VbMl0qdFsyXStlWzNdKnRbM119ZnVuY3Rpb24geGwoZSx0LG4scil7Y29uc3QgaT1uWzBdKnJbMV0tblsxXSpyWzBdLHM9blswXSpyWzJdLW5bMl0qclswXSxvPW5bMF0qclszXS1uWzNdKnJbMF0sYz1uWzFdKnJbMl0tblsyXSpyWzFdLGw9blsxXSpyWzNdLW5bM10qclsxXSxoPW5bMl0qclszXS1uWzNdKnJbMl0sZj10WzBdLHU9dFsxXSxkPXRbMl0sZz10WzNdO3JldHVybiBlWzBdPXUqaC1kKmwrZypjLGVbMV09LShmKmgpK2Qqby1nKnMsZVsyXT1mKmwtdSpvK2cqaSxlWzNdPS0oZipjKSt1KnMtZCppLGV9ZnVuY3Rpb24gQmkoZSx0LG4scil7Y29uc3QgaT10WzBdLHM9dFsxXSxvPXRbMl0sYz10WzNdO3JldHVybiBlWzBdPWkrciooblswXS1pKSxlWzFdPXMrciooblsxXS1zKSxlWzJdPW8rciooblsyXS1vKSxlWzNdPWMrciooblszXS1jKSxlfWZ1bmN0aW9uIE1sKGUsdCl7dD10PT09dm9pZCAwPzE6dDtsZXQgbixyLGkscyxvLGM7ZG8gbj1TdCgpKjItMSxyPVN0KCkqMi0xLG89bipuK3Iqcjt3aGlsZShvPj0xKTtkbyBpPVN0KCkqMi0xLHM9U3QoKSoyLTEsYz1pKmkrcypzO3doaWxlKGM+PTEpO2NvbnN0IGw9TWF0aC5zcXJ0KCgxLW8pL2MpO3JldHVybiBlWzBdPXQqbixlWzFdPXQqcixlWzJdPXQqaSpsLGVbM109dCpzKmwsZX1mdW5jdGlvbiBZaShlLHQsbil7Y29uc3Qgcj10WzBdLGk9dFsxXSxzPXRbMl0sbz10WzNdO3JldHVybiBlWzBdPW5bMF0qcituWzRdKmkrbls4XSpzK25bMTJdKm8sZVsxXT1uWzFdKnIrbls1XSppK25bOV0qcytuWzEzXSpvLGVbMl09blsyXSpyK25bNl0qaStuWzEwXSpzK25bMTRdKm8sZVszXT1uWzNdKnIrbls3XSppK25bMTFdKnMrblsxNV0qbyxlfWZ1bmN0aW9uIFdpKGUsdCxuKXtjb25zdCByPXRbMF0saT10WzFdLHM9dFsyXSxvPW5bMF0sYz1uWzFdLGw9blsyXSxoPW5bM10sZj1oKnIrYypzLWwqaSx1PWgqaStsKnItbypzLGQ9aCpzK28qaS1jKnIsZz0tbypyLWMqaS1sKnM7cmV0dXJuIGVbMF09ZipoK2cqLW8rdSotbC1kKi1jLGVbMV09dSpoK2cqLWMrZCotby1mKi1sLGVbMl09ZCpoK2cqLWwrZiotYy11Ki1vLGVbM109dFszXSxlfWZ1bmN0aW9uIHdsKGUpe3JldHVybiBlWzBdPTAsZVsxXT0wLGVbMl09MCxlWzNdPTAsZX1mdW5jdGlvbiBBbChlKXtyZXR1cm5gdmVjNCgke2VbMF19LCAke2VbMV19LCAke2VbMl19LCAke2VbM119KWB9ZnVuY3Rpb24gVGwoZSx0KXtyZXR1cm4gZVswXT09PXRbMF0mJmVbMV09PT10WzFdJiZlWzJdPT09dFsyXSYmZVszXT09PXRbM119ZnVuY3Rpb24gRWwoZSx0KXtjb25zdCBuPWVbMF0scj1lWzFdLGk9ZVsyXSxzPWVbM10sbz10WzBdLGM9dFsxXSxsPXRbMl0saD10WzNdO3JldHVybiBNYXRoLmFicyhuLW8pPD1DKk1hdGgubWF4KDEsTWF0aC5hYnMobiksTWF0aC5hYnMobykpJiZNYXRoLmFicyhyLWMpPD1DKk1hdGgubWF4KDEsTWF0aC5hYnMociksTWF0aC5hYnMoYykpJiZNYXRoLmFicyhpLWwpPD1DKk1hdGgubWF4KDEsTWF0aC5hYnMoaSksTWF0aC5hYnMobCkpJiZNYXRoLmFicyhzLWgpPD1DKk1hdGgubWF4KDEsTWF0aC5hYnMocyksTWF0aC5hYnMoaCkpfWNvbnN0IE9sPU5pLHZsPSRpLGJsPXppLElsPUZpLFNsPXFpLExsPUZuLFBsPXFuLFJsPWZ1bmN0aW9uKCl7Y29uc3QgZT1DaSgpO3JldHVybiBmdW5jdGlvbih0LG4scixpLHMsbyl7bGV0IGMsbDtmb3Iobnx8KG49NCkscnx8KHI9MCksaT9sPU1hdGgubWluKGkqbityLHQubGVuZ3RoKTpsPXQubGVuZ3RoLGM9cjtjPGw7Yys9billWzBdPXRbY10sZVsxXT10W2MrMV0sZVsyXT10W2MrMl0sZVszXT10W2MrM10scyhlLGUsbyksdFtjXT1lWzBdLHRbYysxXT1lWzFdLHRbYysyXT1lWzJdLHRbYyszXT1lWzNdO3JldHVybiB0fX0oKTt2YXIgQ2w9T2JqZWN0LmZyZWV6ZSh7X19wcm90b19fOm51bGwsYWRkOlZpLGNlaWw6ZmwsY2xvbmU6Y2wsY29weTpsbCxjcmVhdGU6Q2ksY3Jvc3M6eGwsZGlzdDpJbCxkaXN0YW5jZTpGaSxkaXY6YmwsZGl2aWRlOnppLGRvdDpEaSxlcXVhbHM6RWwsZXhhY3RFcXVhbHM6VGwsZmxvb3I6dWwsZm9yRWFjaDpSbCxmcm9tVmFsdWVzOmFsLGludmVyc2U6eWwsbGVuOkxsLGxlbmd0aDpGbixsZXJwOkJpLG1heDpnbCxtaW46ZGwsbXVsOnZsLG11bHRpcGx5OiRpLG5lZ2F0ZTpfbCxub3JtYWxpemU6VWkscmFuZG9tOk1sLHJvdW5kOm1sLHNjYWxlOmtpLHNjYWxlQW5kQWRkOnBsLHNldDpobCxzcXJEaXN0OlNsLHNxckxlbjpQbCxzcXVhcmVkRGlzdGFuY2U6cWksc3F1YXJlZExlbmd0aDpxbixzdHI6QWwsc3ViOk9sLHN1YnRyYWN0Ok5pLHRyYW5zZm9ybU1hdDQ6WWksdHJhbnNmb3JtUXVhdDpXaSx6ZXJvOndsfSksVW47KGZ1bmN0aW9uKGUpe2VbZS5DT0wwUk9XMD0wXT0iQ09MMFJPVzAiLGVbZS5DT0wwUk9XMT0xXT0iQ09MMFJPVzEiLGVbZS5DT0wwUk9XMj0yXT0iQ09MMFJPVzIiLGVbZS5DT0wwUk9XMz0zXT0iQ09MMFJPVzMiLGVbZS5DT0wxUk9XMD00XT0iQ09MMVJPVzAiLGVbZS5DT0wxUk9XMT01XT0iQ09MMVJPVzEiLGVbZS5DT0wxUk9XMj02XT0iQ09MMVJPVzIiLGVbZS5DT0wxUk9XMz03XT0iQ09MMVJPVzMiLGVbZS5DT0wyUk9XMD04XT0iQ09MMlJPVzAiLGVbZS5DT0wyUk9XMT05XT0iQ09MMlJPVzEiLGVbZS5DT0wyUk9XMj0xMF09IkNPTDJST1cyIixlW2UuQ09MMlJPVzM9MTFdPSJDT0wyUk9XMyIsZVtlLkNPTDNST1cwPTEyXT0iQ09MM1JPVzAiLGVbZS5DT0wzUk9XMT0xM109IkNPTDNST1cxIixlW2UuQ09MM1JPVzI9MTRdPSJDT0wzUk9XMiIsZVtlLkNPTDNST1czPTE1XT0iQ09MM1JPVzMifSkoVW58fChVbj17fSkpO2NvbnN0IFZsPTQ1Kk1hdGguUEkvMTgwLE5sPTEsRG49LjEsQm49NTAwLCRsPU9iamVjdC5mcmVlemUoWzEsMCwwLDAsMCwxLDAsMCwwLDAsMSwwLDAsMCwwLDFdKTtjbGFzcyB0dCBleHRlbmRzIENue3N0YXRpYyBnZXQgSURFTlRJVFkoKXtyZXR1cm4ga2woKX1zdGF0aWMgZ2V0IFpFUk8oKXtyZXR1cm4gemwoKX1nZXQgRUxFTUVOVFMoKXtyZXR1cm4gMTZ9Z2V0IFJBTksoKXtyZXR1cm4gNH1nZXQgSU5ESUNFUygpe3JldHVybiBVbn1jb25zdHJ1Y3Rvcih0KXtzdXBlcigtMCwtMCwtMCwtMCwtMCwtMCwtMCwtMCwtMCwtMCwtMCwtMCwtMCwtMCwtMCwtMCksYXJndW1lbnRzLmxlbmd0aD09PTEmJkFycmF5LmlzQXJyYXkodCk/dGhpcy5jb3B5KHQpOnRoaXMuaWRlbnRpdHkoKX1jb3B5KHQpe3JldHVybiB0aGlzWzBdPXRbMF0sdGhpc1sxXT10WzFdLHRoaXNbMl09dFsyXSx0aGlzWzNdPXRbM10sdGhpc1s0XT10WzRdLHRoaXNbNV09dFs1XSx0aGlzWzZdPXRbNl0sdGhpc1s3XT10WzddLHRoaXNbOF09dFs4XSx0aGlzWzldPXRbOV0sdGhpc1sxMF09dFsxMF0sdGhpc1sxMV09dFsxMV0sdGhpc1sxMl09dFsxMl0sdGhpc1sxM109dFsxM10sdGhpc1sxNF09dFsxNF0sdGhpc1sxNV09dFsxNV0sdGhpcy5jaGVjaygpfXNldCh0LG4scixpLHMsbyxjLGwsaCxmLHUsZCxnLG0sXyxwKXtyZXR1cm4gdGhpc1swXT10LHRoaXNbMV09bix0aGlzWzJdPXIsdGhpc1szXT1pLHRoaXNbNF09cyx0aGlzWzVdPW8sdGhpc1s2XT1jLHRoaXNbN109bCx0aGlzWzhdPWgsdGhpc1s5XT1mLHRoaXNbMTBdPXUsdGhpc1sxMV09ZCx0aGlzWzEyXT1nLHRoaXNbMTNdPW0sdGhpc1sxNF09Xyx0aGlzWzE1XT1wLHRoaXMuY2hlY2soKX1zZXRSb3dNYWpvcih0LG4scixpLHMsbyxjLGwsaCxmLHUsZCxnLG0sXyxwKXtyZXR1cm4gdGhpc1swXT10LHRoaXNbMV09cyx0aGlzWzJdPWgsdGhpc1szXT1nLHRoaXNbNF09bix0aGlzWzVdPW8sdGhpc1s2XT1mLHRoaXNbN109bSx0aGlzWzhdPXIsdGhpc1s5XT1jLHRoaXNbMTBdPXUsdGhpc1sxMV09Xyx0aGlzWzEyXT1pLHRoaXNbMTNdPWwsdGhpc1sxNF09ZCx0aGlzWzE1XT1wLHRoaXMuY2hlY2soKX10b1Jvd01ham9yKHQpe3JldHVybiB0WzBdPXRoaXNbMF0sdFsxXT10aGlzWzRdLHRbMl09dGhpc1s4XSx0WzNdPXRoaXNbMTJdLHRbNF09dGhpc1sxXSx0WzVdPXRoaXNbNV0sdFs2XT10aGlzWzldLHRbN109dGhpc1sxM10sdFs4XT10aGlzWzJdLHRbOV09dGhpc1s2XSx0WzEwXT10aGlzWzEwXSx0WzExXT10aGlzWzE0XSx0WzEyXT10aGlzWzNdLHRbMTNdPXRoaXNbN10sdFsxNF09dGhpc1sxMV0sdFsxNV09dGhpc1sxNV0sdH1pZGVudGl0eSgpe3JldHVybiB0aGlzLmNvcHkoJGwpfWZyb21PYmplY3QodCl7cmV0dXJuIHRoaXMuY2hlY2soKX1mcm9tUXVhdGVybmlvbih0KXtyZXR1cm4gT2kodGhpcyx0KSx0aGlzLmNoZWNrKCl9ZnJ1c3R1bSh0KXtjb25zdHtsZWZ0Om4scmlnaHQ6cixib3R0b206aSx0b3A6cyxuZWFyOm89RG4sZmFyOmM9Qm59PXQ7cmV0dXJuIGM9PT0xLzA/RmwodGhpcyxuLHIsaSxzLG8pOnZpKHRoaXMsbixyLGkscyxvLGMpLHRoaXMuY2hlY2soKX1sb29rQXQodCl7Y29uc3R7ZXllOm4sY2VudGVyOnI9WzAsMCwwXSx1cDppPVswLDEsMF19PXQ7cmV0dXJuIFBpKHRoaXMsbixyLGkpLHRoaXMuY2hlY2soKX1vcnRobyh0KXtjb25zdHtsZWZ0Om4scmlnaHQ6cixib3R0b206aSx0b3A6cyxuZWFyOm89RG4sZmFyOmM9Qm59PXQ7cmV0dXJuIExpKHRoaXMsbixyLGkscyxvLGMpLHRoaXMuY2hlY2soKX1vcnRob2dyYXBoaWModCl7Y29uc3R7Zm92eTpuPVZsLGFzcGVjdDpyPU5sLGZvY2FsRGlzdGFuY2U6aT0xLG5lYXI6cz1EbixmYXI6bz1Cbn09dDtaaShuKTtjb25zdCBjPW4vMixsPWkqTWF0aC50YW4oYyksaD1sKnI7cmV0dXJuIHRoaXMub3J0aG8oe2xlZnQ6LWgscmlnaHQ6aCxib3R0b206LWwsdG9wOmwsbmVhcjpzLGZhcjpvfSl9cGVyc3BlY3RpdmUodCl7Y29uc3R7Zm92eTpuPTQ1Kk1hdGguUEkvMTgwLGFzcGVjdDpyPTEsbmVhcjppPS4xLGZhcjpzPTUwMH09dDtyZXR1cm4gWmkobiksSWkodGhpcyxuLHIsaSxzKSx0aGlzLmNoZWNrKCl9ZGV0ZXJtaW5hbnQoKXtyZXR1cm4gcGkodGhpcyl9Z2V0U2NhbGUodD1bLTAsLTAsLTBdKXtyZXR1cm4gdFswXT1NYXRoLnNxcnQodGhpc1swXSp0aGlzWzBdK3RoaXNbMV0qdGhpc1sxXSt0aGlzWzJdKnRoaXNbMl0pLHRbMV09TWF0aC5zcXJ0KHRoaXNbNF0qdGhpc1s0XSt0aGlzWzVdKnRoaXNbNV0rdGhpc1s2XSp0aGlzWzZdKSx0WzJdPU1hdGguc3FydCh0aGlzWzhdKnRoaXNbOF0rdGhpc1s5XSp0aGlzWzldK3RoaXNbMTBdKnRoaXNbMTBdKSx0fWdldFRyYW5zbGF0aW9uKHQ9Wy0wLC0wLC0wXSl7cmV0dXJuIHRbMF09dGhpc1sxMl0sdFsxXT10aGlzWzEzXSx0WzJdPXRoaXNbMTRdLHR9Z2V0Um90YXRpb24odCxuKXt0PXR8fFstMCwtMCwtMCwtMCwtMCwtMCwtMCwtMCwtMCwtMCwtMCwtMCwtMCwtMCwtMCwtMF0sbj1ufHxbLTAsLTAsLTBdO2NvbnN0IHI9dGhpcy5nZXRTY2FsZShuKSxpPTEvclswXSxzPTEvclsxXSxvPTEvclsyXTtyZXR1cm4gdFswXT10aGlzWzBdKmksdFsxXT10aGlzWzFdKnMsdFsyXT10aGlzWzJdKm8sdFszXT0wLHRbNF09dGhpc1s0XSppLHRbNV09dGhpc1s1XSpzLHRbNl09dGhpc1s2XSpvLHRbN109MCx0WzhdPXRoaXNbOF0qaSx0WzldPXRoaXNbOV0qcyx0WzEwXT10aGlzWzEwXSpvLHRbMTFdPTAsdFsxMl09MCx0WzEzXT0wLHRbMTRdPTAsdFsxNV09MSx0fWdldFJvdGF0aW9uTWF0cml4Myh0LG4pe3Q9dHx8Wy0wLC0wLC0wLC0wLC0wLC0wLC0wLC0wLC0wXSxuPW58fFstMCwtMCwtMF07Y29uc3Qgcj10aGlzLmdldFNjYWxlKG4pLGk9MS9yWzBdLHM9MS9yWzFdLG89MS9yWzJdO3JldHVybiB0WzBdPXRoaXNbMF0qaSx0WzFdPXRoaXNbMV0qcyx0WzJdPXRoaXNbMl0qbyx0WzNdPXRoaXNbNF0qaSx0WzRdPXRoaXNbNV0qcyx0WzVdPXRoaXNbNl0qbyx0WzZdPXRoaXNbOF0qaSx0WzddPXRoaXNbOV0qcyx0WzhdPXRoaXNbMTBdKm8sdH10cmFuc3Bvc2UoKXtyZXR1cm4gZ2kodGhpcyx0aGlzKSx0aGlzLmNoZWNrKCl9aW52ZXJ0KCl7cmV0dXJuIG1pKHRoaXMsdGhpcyksdGhpcy5jaGVjaygpfW11bHRpcGx5TGVmdCh0KXtyZXR1cm4gV2UodGhpcyx0LHRoaXMpLHRoaXMuY2hlY2soKX1tdWx0aXBseVJpZ2h0KHQpe3JldHVybiBXZSh0aGlzLHRoaXMsdCksdGhpcy5jaGVjaygpfXJvdGF0ZVgodCl7cmV0dXJuIE1pKHRoaXMsdGhpcyx0KSx0aGlzLmNoZWNrKCl9cm90YXRlWSh0KXtyZXR1cm4gd2kodGhpcyx0aGlzLHQpLHRoaXMuY2hlY2soKX1yb3RhdGVaKHQpe3JldHVybiBBaSh0aGlzLHRoaXMsdCksdGhpcy5jaGVjaygpfXJvdGF0ZVhZWih0KXtyZXR1cm4gdGhpcy5yb3RhdGVYKHRbMF0pLnJvdGF0ZVkodFsxXSkucm90YXRlWih0WzJdKX1yb3RhdGVBeGlzKHQsbil7cmV0dXJuIHhpKHRoaXMsdGhpcyx0LG4pLHRoaXMuY2hlY2soKX1zY2FsZSh0KXtyZXR1cm4geWkodGhpcyx0aGlzLEFycmF5LmlzQXJyYXkodCk/dDpbdCx0LHRdKSx0aGlzLmNoZWNrKCl9dHJhbnNsYXRlKHQpe3JldHVybiBfaSh0aGlzLHRoaXMsdCksdGhpcy5jaGVjaygpfXRyYW5zZm9ybSh0LG4pe3JldHVybiB0Lmxlbmd0aD09PTQ/KG49WWkobnx8Wy0wLC0wLC0wLC0wXSx0LHRoaXMpLGFlKG4sNCksbik6dGhpcy50cmFuc2Zvcm1Bc1BvaW50KHQsbil9dHJhbnNmb3JtQXNQb2ludCh0LG4pe2NvbnN0e2xlbmd0aDpyfT10O2xldCBpO3N3aXRjaChyKXtjYXNlIDI6aT1FbihufHxbLTAsLTBdLHQsdGhpcyk7YnJlYWs7Y2FzZSAzOmk9RmUobnx8Wy0wLC0wLC0wXSx0LHRoaXMpO2JyZWFrO2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKCJJbGxlZ2FsIHZlY3RvciIpfXJldHVybiBhZShpLHQubGVuZ3RoKSxpfXRyYW5zZm9ybUFzVmVjdG9yKHQsbil7bGV0IHI7c3dpdGNoKHQubGVuZ3RoKXtjYXNlIDI6cj1RcihufHxbLTAsLTBdLHQsdGhpcyk7YnJlYWs7Y2FzZSAzOnI9S3Iobnx8Wy0wLC0wLC0wXSx0LHRoaXMpO2JyZWFrO2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKCJJbGxlZ2FsIHZlY3RvciIpfXJldHVybiBhZShyLHQubGVuZ3RoKSxyfXRyYW5zZm9ybVBvaW50KHQsbil7cmV0dXJuIHRoaXMudHJhbnNmb3JtQXNQb2ludCh0LG4pfXRyYW5zZm9ybVZlY3Rvcih0LG4pe3JldHVybiB0aGlzLnRyYW5zZm9ybUFzUG9pbnQodCxuKX10cmFuc2Zvcm1EaXJlY3Rpb24odCxuKXtyZXR1cm4gdGhpcy50cmFuc2Zvcm1Bc1ZlY3Rvcih0LG4pfW1ha2VSb3RhdGlvblgodCl7cmV0dXJuIHRoaXMuaWRlbnRpdHkoKS5yb3RhdGVYKHQpfW1ha2VUcmFuc2xhdGlvbih0LG4scil7cmV0dXJuIHRoaXMuaWRlbnRpdHkoKS50cmFuc2xhdGUoW3QsbixyXSl9fWxldCBaZSxHZTtmdW5jdGlvbiB6bCgpe3JldHVybiBaZXx8KFplPW5ldyB0dChbMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMF0pLE9iamVjdC5mcmVlemUoWmUpKSxaZX1mdW5jdGlvbiBrbCgpe3JldHVybiBHZXx8KEdlPW5ldyB0dCxPYmplY3QuZnJlZXplKEdlKSksR2V9ZnVuY3Rpb24gWmkoZSl7aWYoZT5NYXRoLlBJKjIpdGhyb3cgRXJyb3IoImV4cGVjdGVkIHJhZGlhbnMiKX1mdW5jdGlvbiBGbChlLHQsbixyLGkscyl7Y29uc3Qgbz0yKnMvKG4tdCksYz0yKnMvKGktciksbD0obit0KS8obi10KSxoPShpK3IpLyhpLXIpLGY9LTEsdT0tMSxkPS0yKnM7cmV0dXJuIGVbMF09byxlWzFdPTAsZVsyXT0wLGVbM109MCxlWzRdPTAsZVs1XT1jLGVbNl09MCxlWzddPTAsZVs4XT1sLGVbOV09aCxlWzEwXT1mLGVbMTFdPXUsZVsxMl09MCxlWzEzXT0wLGVbMTRdPWQsZVsxNV09MCxlfWZ1bmN0aW9uIEdpKCl7Y29uc3QgZT1uZXcgRCg0KTtyZXR1cm4gRCE9RmxvYXQzMkFycmF5JiYoZVswXT0wLGVbMV09MCxlWzJdPTApLGVbM109MSxlfWZ1bmN0aW9uIHFsKGUpe3JldHVybiBlWzBdPTAsZVsxXT0wLGVbMl09MCxlWzNdPTEsZX1mdW5jdGlvbiBYaShlLHQsbil7bj1uKi41O2NvbnN0IHI9TWF0aC5zaW4obik7cmV0dXJuIGVbMF09cip0WzBdLGVbMV09cip0WzFdLGVbMl09cip0WzJdLGVbM109TWF0aC5jb3MobiksZX1mdW5jdGlvbiBqaShlLHQsbil7Y29uc3Qgcj10WzBdLGk9dFsxXSxzPXRbMl0sbz10WzNdLGM9blswXSxsPW5bMV0saD1uWzJdLGY9blszXTtyZXR1cm4gZVswXT1yKmYrbypjK2kqaC1zKmwsZVsxXT1pKmYrbypsK3MqYy1yKmgsZVsyXT1zKmYrbypoK3IqbC1pKmMsZVszXT1vKmYtcipjLWkqbC1zKmgsZX1mdW5jdGlvbiBVbChlLHQsbil7bio9LjU7Y29uc3Qgcj10WzBdLGk9dFsxXSxzPXRbMl0sbz10WzNdLGM9TWF0aC5zaW4obiksbD1NYXRoLmNvcyhuKTtyZXR1cm4gZVswXT1yKmwrbypjLGVbMV09aSpsK3MqYyxlWzJdPXMqbC1pKmMsZVszXT1vKmwtcipjLGV9ZnVuY3Rpb24gRGwoZSx0LG4pe24qPS41O2NvbnN0IHI9dFswXSxpPXRbMV0scz10WzJdLG89dFszXSxjPU1hdGguc2luKG4pLGw9TWF0aC5jb3Mobik7cmV0dXJuIGVbMF09cipsLXMqYyxlWzFdPWkqbCtvKmMsZVsyXT1zKmwrcipjLGVbM109bypsLWkqYyxlfWZ1bmN0aW9uIEJsKGUsdCxuKXtuKj0uNTtjb25zdCByPXRbMF0saT10WzFdLHM9dFsyXSxvPXRbM10sYz1NYXRoLnNpbihuKSxsPU1hdGguY29zKG4pO3JldHVybiBlWzBdPXIqbCtpKmMsZVsxXT1pKmwtcipjLGVbMl09cypsK28qYyxlWzNdPW8qbC1zKmMsZX1mdW5jdGlvbiBZbChlLHQpe2NvbnN0IG49dFswXSxyPXRbMV0saT10WzJdO3JldHVybiBlWzBdPW4sZVsxXT1yLGVbMl09aSxlWzNdPU1hdGguc3FydChNYXRoLmFicygxLW4qbi1yKnItaSppKSksZX1mdW5jdGlvbiBYZShlLHQsbixyKXtjb25zdCBpPXRbMF0scz10WzFdLG89dFsyXSxjPXRbM107bGV0IGw9blswXSxoPW5bMV0sZj1uWzJdLHU9blszXSxkLGcsbSxfLHA7cmV0dXJuIGQ9aSpsK3MqaCtvKmYrYyp1LGQ8MCYmKGQ9LWQsbD0tbCxoPS1oLGY9LWYsdT0tdSksMS1kPkM/KGc9TWF0aC5hY29zKGQpLHA9TWF0aC5zaW4oZyksbT1NYXRoLnNpbigoMS1yKSpnKS9wLF89TWF0aC5zaW4ocipnKS9wKToobT0xLXIsXz1yKSxlWzBdPW0qaStfKmwsZVsxXT1tKnMrXypoLGVbMl09bSpvK18qZixlWzNdPW0qYytfKnUsZX1mdW5jdGlvbiBXbChlLHQpe2NvbnN0IG49dFswXSxyPXRbMV0saT10WzJdLHM9dFszXSxvPW4qbityKnIraSppK3MqcyxjPW8/MS9vOjA7cmV0dXJuIGVbMF09LW4qYyxlWzFdPS1yKmMsZVsyXT0taSpjLGVbM109cypjLGV9ZnVuY3Rpb24gWmwoZSx0KXtyZXR1cm4gZVswXT0tdFswXSxlWzFdPS10WzFdLGVbMl09LXRbMl0sZVszXT10WzNdLGV9ZnVuY3Rpb24gUWkoZSx0KXtjb25zdCBuPXRbMF0rdFs0XSt0WzhdO2xldCByO2lmKG4+MClyPU1hdGguc3FydChuKzEpLGVbM109LjUqcixyPS41L3IsZVswXT0odFs1XS10WzddKSpyLGVbMV09KHRbNl0tdFsyXSkqcixlWzJdPSh0WzFdLXRbM10pKnI7ZWxzZXtsZXQgaT0wO3RbNF0+dFswXSYmKGk9MSksdFs4XT50W2kqMytpXSYmKGk9Mik7Y29uc3Qgcz0oaSsxKSUzLG89KGkrMiklMztyPU1hdGguc3FydCh0W2kqMytpXS10W3MqMytzXS10W28qMytvXSsxKSxlW2ldPS41KnIscj0uNS9yLGVbM109KHRbcyozK29dLXRbbyozK3NdKSpyLGVbc109KHRbcyozK2ldK3RbaSozK3NdKSpyLGVbb109KHRbbyozK2ldK3RbaSozK29dKSpyfXJldHVybiBlfWNvbnN0IEdsPVZpLFhsPWtpLGpsPURpLFFsPUJpLEtsPUZuLEpsPXFuLEtpPVVpLEhsPWZ1bmN0aW9uKCl7Y29uc3QgZT1PbigpLHQ9dm4oMSwwLDApLG49dm4oMCwxLDApO3JldHVybiBmdW5jdGlvbihyLGkscyl7Y29uc3Qgbz1VdChpLHMpO3JldHVybiBvPC0uOTk5OTk5PyhIKGUsdCxpKSxjaShlKTwxZS02JiZIKGUsbixpKSxBdChlLGUpLFhpKHIsZSxNYXRoLlBJKSxyKTpvPi45OTk5OTk/KHJbMF09MCxyWzFdPTAsclsyXT0wLHJbM109MSxyKTooSChlLGkscyksclswXT1lWzBdLHJbMV09ZVsxXSxyWzJdPWVbMl0sclszXT0xK28sS2kocixyKSl9fSgpOyhmdW5jdGlvbigpe2NvbnN0IGU9R2koKSx0PUdpKCk7cmV0dXJuIGZ1bmN0aW9uKG4scixpLHMsbyxjKXtyZXR1cm4gWGUoZSxyLG8sYyksWGUodCxpLHMsYyksWGUobixlLHQsMipjKigxLWMpKSxufX0pKCksZnVuY3Rpb24oKXtjb25zdCBlPWFpKCk7cmV0dXJuIGZ1bmN0aW9uKHQsbixyLGkpe3JldHVybiBlWzBdPXJbMF0sZVszXT1yWzFdLGVbNl09clsyXSxlWzFdPWlbMF0sZVs0XT1pWzFdLGVbN109aVsyXSxlWzJdPS1uWzBdLGVbNV09LW5bMV0sZVs4XT0tblsyXSxLaSh0LFFpKHQsZSkpfX0oKTtjb25zdCB0aD1bMCwwLDAsMV07Y2xhc3MgVHQgZXh0ZW5kcyBjZXtjb25zdHJ1Y3Rvcih0PTAsbj0wLHI9MCxpPTEpe3N1cGVyKC0wLC0wLC0wLC0wKSxBcnJheS5pc0FycmF5KHQpJiZhcmd1bWVudHMubGVuZ3RoPT09MT90aGlzLmNvcHkodCk6dGhpcy5zZXQodCxuLHIsaSl9Y29weSh0KXtyZXR1cm4gdGhpc1swXT10WzBdLHRoaXNbMV09dFsxXSx0aGlzWzJdPXRbMl0sdGhpc1szXT10WzNdLHRoaXMuY2hlY2soKX1zZXQodCxuLHIsaSl7cmV0dXJuIHRoaXNbMF09dCx0aGlzWzFdPW4sdGhpc1syXT1yLHRoaXNbM109aSx0aGlzLmNoZWNrKCl9ZnJvbU9iamVjdCh0KXtyZXR1cm4gdGhpc1swXT10LngsdGhpc1sxXT10LnksdGhpc1syXT10LnosdGhpc1szXT10LncsdGhpcy5jaGVjaygpfWZyb21NYXRyaXgzKHQpe3JldHVybiBRaSh0aGlzLHQpLHRoaXMuY2hlY2soKX1mcm9tQXhpc1JvdGF0aW9uKHQsbil7cmV0dXJuIFhpKHRoaXMsdCxuKSx0aGlzLmNoZWNrKCl9aWRlbnRpdHkoKXtyZXR1cm4gcWwodGhpcyksdGhpcy5jaGVjaygpfXNldEF4aXNBbmdsZSh0LG4pe3JldHVybiB0aGlzLmZyb21BeGlzUm90YXRpb24odCxuKX1nZXQgRUxFTUVOVFMoKXtyZXR1cm4gNH1nZXQgeCgpe3JldHVybiB0aGlzWzBdfXNldCB4KHQpe3RoaXNbMF09UCh0KX1nZXQgeSgpe3JldHVybiB0aGlzWzFdfXNldCB5KHQpe3RoaXNbMV09UCh0KX1nZXQgeigpe3JldHVybiB0aGlzWzJdfXNldCB6KHQpe3RoaXNbMl09UCh0KX1nZXQgdygpe3JldHVybiB0aGlzWzNdfXNldCB3KHQpe3RoaXNbM109UCh0KX1sZW4oKXtyZXR1cm4gS2wodGhpcyl9bGVuZ3RoU3F1YXJlZCgpe3JldHVybiBKbCh0aGlzKX1kb3QodCl7cmV0dXJuIGpsKHRoaXMsdCl9cm90YXRpb25Ubyh0LG4pe3JldHVybiBIbCh0aGlzLHQsbiksdGhpcy5jaGVjaygpfWFkZCh0KXtyZXR1cm4gR2wodGhpcyx0aGlzLHQpLHRoaXMuY2hlY2soKX1jYWxjdWxhdGVXKCl7cmV0dXJuIFlsKHRoaXMsdGhpcyksdGhpcy5jaGVjaygpfWNvbmp1Z2F0ZSgpe3JldHVybiBabCh0aGlzLHRoaXMpLHRoaXMuY2hlY2soKX1pbnZlcnQoKXtyZXR1cm4gV2wodGhpcyx0aGlzKSx0aGlzLmNoZWNrKCl9bGVycCh0LG4scil7cmV0dXJuIHI9PT12b2lkIDA/dGhpcy5sZXJwKHRoaXMsdCxuKTooUWwodGhpcyx0LG4sciksdGhpcy5jaGVjaygpKX1tdWx0aXBseVJpZ2h0KHQpe3JldHVybiBqaSh0aGlzLHRoaXMsdCksdGhpcy5jaGVjaygpfW11bHRpcGx5TGVmdCh0KXtyZXR1cm4gamkodGhpcyx0LHRoaXMpLHRoaXMuY2hlY2soKX1ub3JtYWxpemUoKXtjb25zdCB0PXRoaXMubGVuKCksbj10PjA/MS90OjA7cmV0dXJuIHRoaXNbMF09dGhpc1swXSpuLHRoaXNbMV09dGhpc1sxXSpuLHRoaXNbMl09dGhpc1syXSpuLHRoaXNbM109dGhpc1szXSpuLHQ9PT0wJiYodGhpc1szXT0xKSx0aGlzLmNoZWNrKCl9cm90YXRlWCh0KXtyZXR1cm4gVWwodGhpcyx0aGlzLHQpLHRoaXMuY2hlY2soKX1yb3RhdGVZKHQpe3JldHVybiBEbCh0aGlzLHRoaXMsdCksdGhpcy5jaGVjaygpfXJvdGF0ZVoodCl7cmV0dXJuIEJsKHRoaXMsdGhpcyx0KSx0aGlzLmNoZWNrKCl9c2NhbGUodCl7cmV0dXJuIFhsKHRoaXMsdGhpcyx0KSx0aGlzLmNoZWNrKCl9c2xlcnAodCxuLHIpe2xldCBpLHMsbztzd2l0Y2goYXJndW1lbnRzLmxlbmd0aCl7Y2FzZSAxOih7c3RhcnQ6aT10aCx0YXJnZXQ6cyxyYXRpbzpvfT10KTticmVhaztjYXNlIDI6aT10aGlzLHM9dCxvPW47YnJlYWs7ZGVmYXVsdDppPXQscz1uLG89cn1yZXR1cm4gWGUodGhpcyxpLHMsbyksdGhpcy5jaGVjaygpfXRyYW5zZm9ybVZlY3RvcjQodCxuPW5ldyBvdCl7cmV0dXJuIFdpKG4sdCx0aGlzKSxhZShuLDQpfWxlbmd0aFNxKCl7cmV0dXJuIHRoaXMubGVuZ3RoU3F1YXJlZCgpfXNldEZyb21BeGlzQW5nbGUodCxuKXtyZXR1cm4gdGhpcy5zZXRBeGlzQW5nbGUodCxuKX1wcmVtdWx0aXBseSh0KXtyZXR1cm4gdGhpcy5tdWx0aXBseUxlZnQodCl9bXVsdGlwbHkodCl7cmV0dXJuIHRoaXMubXVsdGlwbHlSaWdodCh0KX19Y29uc3QgamU9IlVua25vd24gRXVsZXIgYW5nbGUgb3JkZXIiLER0PS45OTk5OTt2YXIgWDsoZnVuY3Rpb24oZSl7ZVtlLlpZWD0wXT0iWllYIixlW2UuWVhaPTFdPSJZWFoiLGVbZS5YWlk9Ml09IlhaWSIsZVtlLlpYWT0zXT0iWlhZIixlW2UuWVpYPTRdPSJZWlgiLGVbZS5YWVo9NV09IlhZWiJ9KShYfHwoWD17fSkpO2NsYXNzIEYgZXh0ZW5kcyBjZXtzdGF0aWMgZ2V0IFpZWCgpe3JldHVybiBYLlpZWH1zdGF0aWMgZ2V0IFlYWigpe3JldHVybiBYLllYWn1zdGF0aWMgZ2V0IFhaWSgpe3JldHVybiBYLlhaWX1zdGF0aWMgZ2V0IFpYWSgpe3JldHVybiBYLlpYWX1zdGF0aWMgZ2V0IFlaWCgpe3JldHVybiBYLllaWH1zdGF0aWMgZ2V0IFhZWigpe3JldHVybiBYLlhZWn1zdGF0aWMgZ2V0IFJvbGxQaXRjaFlhdygpe3JldHVybiBYLlpZWH1zdGF0aWMgZ2V0IERlZmF1bHRPcmRlcigpe3JldHVybiBYLlpZWH1zdGF0aWMgZ2V0IFJvdGF0aW9uT3JkZXJzKCl7cmV0dXJuIFh9c3RhdGljIHJvdGF0aW9uT3JkZXIodCl7cmV0dXJuIFhbdF19Z2V0IEVMRU1FTlRTKCl7cmV0dXJuIDR9Y29uc3RydWN0b3IodD0wLG49MCxyPTAsaT1GLkRlZmF1bHRPcmRlcil7c3VwZXIoLTAsLTAsLTAsLTApLGFyZ3VtZW50cy5sZW5ndGg+MCYmQXJyYXkuaXNBcnJheShhcmd1bWVudHNbMF0pP3RoaXMuZnJvbVZlY3RvcjMoLi4uYXJndW1lbnRzKTp0aGlzLnNldCh0LG4scixpKX1mcm9tUXVhdGVybmlvbih0KXtjb25zdFtuLHIsaSxzXT10LG89cipyLGM9LTIqKG8raSppKSsxLGw9MioobipyK3MqaSk7bGV0IGg9LTIqKG4qaS1zKnIpO2NvbnN0IGY9MioocippK3MqbiksdT0tMioobipuK28pKzE7aD1oPjE/MTpoLGg9aDwtMT8tMTpoO2NvbnN0IGQ9TWF0aC5hdGFuMihmLHUpLGc9TWF0aC5hc2luKGgpLG09TWF0aC5hdGFuMihsLGMpO3JldHVybiB0aGlzLnNldChkLGcsbSxGLlJvbGxQaXRjaFlhdyl9ZnJvbU9iamVjdCh0KXt0aHJvdyBuZXcgRXJyb3IoIm5vdCBpbXBsZW1lbnRlZCIpfWNvcHkodCl7cmV0dXJuIHRoaXNbMF09dFswXSx0aGlzWzFdPXRbMV0sdGhpc1syXT10WzJdLHRoaXNbM109TnVtYmVyLmlzRmluaXRlKHRbM10pfHx0aGlzLm9yZGVyLHRoaXMuY2hlY2soKX1zZXQodD0wLG49MCxyPTAsaSl7cmV0dXJuIHRoaXNbMF09dCx0aGlzWzFdPW4sdGhpc1syXT1yLHRoaXNbM109TnVtYmVyLmlzRmluaXRlKGkpP2k6dGhpc1szXSx0aGlzLmNoZWNrKCl9dmFsaWRhdGUoKXtyZXR1cm4gZWgodGhpc1szXSkmJk51bWJlci5pc0Zpbml0ZSh0aGlzWzBdKSYmTnVtYmVyLmlzRmluaXRlKHRoaXNbMV0pJiZOdW1iZXIuaXNGaW5pdGUodGhpc1syXSl9dG9BcnJheSh0PVtdLG49MCl7cmV0dXJuIHRbbl09dGhpc1swXSx0W24rMV09dGhpc1sxXSx0W24rMl09dGhpc1syXSx0fXRvQXJyYXk0KHQ9W10sbj0wKXtyZXR1cm4gdFtuXT10aGlzWzBdLHRbbisxXT10aGlzWzFdLHRbbisyXT10aGlzWzJdLHRbbiszXT10aGlzWzNdLHR9dG9WZWN0b3IzKHQ9Wy0wLC0wLC0wXSl7cmV0dXJuIHRbMF09dGhpc1swXSx0WzFdPXRoaXNbMV0sdFsyXT10aGlzWzJdLHR9Z2V0IHgoKXtyZXR1cm4gdGhpc1swXX1zZXQgeCh0KXt0aGlzWzBdPVAodCl9Z2V0IHkoKXtyZXR1cm4gdGhpc1sxXX1zZXQgeSh0KXt0aGlzWzFdPVAodCl9Z2V0IHooKXtyZXR1cm4gdGhpc1syXX1zZXQgeih0KXt0aGlzWzJdPVAodCl9Z2V0IGFscGhhKCl7cmV0dXJuIHRoaXNbMF19c2V0IGFscGhhKHQpe3RoaXNbMF09UCh0KX1nZXQgYmV0YSgpe3JldHVybiB0aGlzWzFdfXNldCBiZXRhKHQpe3RoaXNbMV09UCh0KX1nZXQgZ2FtbWEoKXtyZXR1cm4gdGhpc1syXX1zZXQgZ2FtbWEodCl7dGhpc1syXT1QKHQpfWdldCBwaGkoKXtyZXR1cm4gdGhpc1swXX1zZXQgcGhpKHQpe3RoaXNbMF09UCh0KX1nZXQgdGhldGEoKXtyZXR1cm4gdGhpc1sxXX1zZXQgdGhldGEodCl7dGhpc1sxXT1QKHQpfWdldCBwc2koKXtyZXR1cm4gdGhpc1syXX1zZXQgcHNpKHQpe3RoaXNbMl09UCh0KX1nZXQgcm9sbCgpe3JldHVybiB0aGlzWzBdfXNldCByb2xsKHQpe3RoaXNbMF09UCh0KX1nZXQgcGl0Y2goKXtyZXR1cm4gdGhpc1sxXX1zZXQgcGl0Y2godCl7dGhpc1sxXT1QKHQpfWdldCB5YXcoKXtyZXR1cm4gdGhpc1syXX1zZXQgeWF3KHQpe3RoaXNbMl09UCh0KX1nZXQgb3JkZXIoKXtyZXR1cm4gdGhpc1szXX1zZXQgb3JkZXIodCl7dGhpc1szXT1uaCh0KX1mcm9tVmVjdG9yMyh0LG4pe3JldHVybiB0aGlzLnNldCh0WzBdLHRbMV0sdFsyXSxOdW1iZXIuaXNGaW5pdGUobik/bjp0aGlzWzNdKX1mcm9tQXJyYXkodCxuPTApe3JldHVybiB0aGlzWzBdPXRbMCtuXSx0aGlzWzFdPXRbMStuXSx0aGlzWzJdPXRbMituXSx0WzNdIT09dm9pZCAwJiYodGhpc1szXT10WzNdKSx0aGlzLmNoZWNrKCl9ZnJvbVJvbGxQaXRjaFlhdyh0LG4scil7cmV0dXJuIHRoaXMuc2V0KHQsbixyLFguWllYKX1mcm9tUm90YXRpb25NYXRyaXgodCxuPUYuRGVmYXVsdE9yZGVyKXtyZXR1cm4gdGhpcy5fZnJvbVJvdGF0aW9uTWF0cml4KHQsbiksdGhpcy5jaGVjaygpfWdldFJvdGF0aW9uTWF0cml4KHQpe3JldHVybiB0aGlzLl9nZXRSb3RhdGlvbk1hdHJpeCh0KX1nZXRRdWF0ZXJuaW9uKCl7Y29uc3QgdD1uZXcgVHQ7c3dpdGNoKHRoaXNbM10pe2Nhc2UgWC5YWVo6cmV0dXJuIHQucm90YXRlWCh0aGlzWzBdKS5yb3RhdGVZKHRoaXNbMV0pLnJvdGF0ZVoodGhpc1syXSk7Y2FzZSBYLllYWjpyZXR1cm4gdC5yb3RhdGVZKHRoaXNbMF0pLnJvdGF0ZVgodGhpc1sxXSkucm90YXRlWih0aGlzWzJdKTtjYXNlIFguWlhZOnJldHVybiB0LnJvdGF0ZVoodGhpc1swXSkucm90YXRlWCh0aGlzWzFdKS5yb3RhdGVZKHRoaXNbMl0pO2Nhc2UgWC5aWVg6cmV0dXJuIHQucm90YXRlWih0aGlzWzBdKS5yb3RhdGVZKHRoaXNbMV0pLnJvdGF0ZVgodGhpc1syXSk7Y2FzZSBYLllaWDpyZXR1cm4gdC5yb3RhdGVZKHRoaXNbMF0pLnJvdGF0ZVoodGhpc1sxXSkucm90YXRlWCh0aGlzWzJdKTtjYXNlIFguWFpZOnJldHVybiB0LnJvdGF0ZVgodGhpc1swXSkucm90YXRlWih0aGlzWzFdKS5yb3RhdGVZKHRoaXNbMl0pO2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKGplKX19X2Zyb21Sb3RhdGlvbk1hdHJpeCh0LG49Ri5EZWZhdWx0T3JkZXIpe2NvbnN0IHI9dFswXSxpPXRbNF0scz10WzhdLG89dFsxXSxjPXRbNV0sbD10WzldLGg9dFsyXSxmPXRbNl0sdT10WzEwXTtzd2l0Y2gobj1ufHx0aGlzWzNdLG4pe2Nhc2UgRi5YWVo6dGhpc1sxXT1NYXRoLmFzaW4oa3QocywtMSwxKSksTWF0aC5hYnMocyk8RHQ/KHRoaXNbMF09TWF0aC5hdGFuMigtbCx1KSx0aGlzWzJdPU1hdGguYXRhbjIoLWkscikpOih0aGlzWzBdPU1hdGguYXRhbjIoZixjKSx0aGlzWzJdPTApO2JyZWFrO2Nhc2UgRi5ZWFo6dGhpc1swXT1NYXRoLmFzaW4oLWt0KGwsLTEsMSkpLE1hdGguYWJzKGwpPER0Pyh0aGlzWzFdPU1hdGguYXRhbjIocyx1KSx0aGlzWzJdPU1hdGguYXRhbjIobyxjKSk6KHRoaXNbMV09TWF0aC5hdGFuMigtaCxyKSx0aGlzWzJdPTApO2JyZWFrO2Nhc2UgRi5aWFk6dGhpc1swXT1NYXRoLmFzaW4oa3QoZiwtMSwxKSksTWF0aC5hYnMoZik8RHQ/KHRoaXNbMV09TWF0aC5hdGFuMigtaCx1KSx0aGlzWzJdPU1hdGguYXRhbjIoLWksYykpOih0aGlzWzFdPTAsdGhpc1syXT1NYXRoLmF0YW4yKG8scikpO2JyZWFrO2Nhc2UgRi5aWVg6dGhpc1sxXT1NYXRoLmFzaW4oLWt0KGgsLTEsMSkpLE1hdGguYWJzKGgpPER0Pyh0aGlzWzBdPU1hdGguYXRhbjIoZix1KSx0aGlzWzJdPU1hdGguYXRhbjIobyxyKSk6KHRoaXNbMF09MCx0aGlzWzJdPU1hdGguYXRhbjIoLWksYykpO2JyZWFrO2Nhc2UgRi5ZWlg6dGhpc1syXT1NYXRoLmFzaW4oa3QobywtMSwxKSksTWF0aC5hYnMobyk8RHQ/KHRoaXNbMF09TWF0aC5hdGFuMigtbCxjKSx0aGlzWzFdPU1hdGguYXRhbjIoLWgscikpOih0aGlzWzBdPTAsdGhpc1sxXT1NYXRoLmF0YW4yKHMsdSkpO2JyZWFrO2Nhc2UgRi5YWlk6dGhpc1syXT1NYXRoLmFzaW4oLWt0KGksLTEsMSkpLE1hdGguYWJzKGkpPER0Pyh0aGlzWzBdPU1hdGguYXRhbjIoZixjKSx0aGlzWzFdPU1hdGguYXRhbjIocyxyKSk6KHRoaXNbMF09TWF0aC5hdGFuMigtbCx1KSx0aGlzWzFdPTApO2JyZWFrO2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKGplKX1yZXR1cm4gdGhpc1szXT1uLHRoaXN9X2dldFJvdGF0aW9uTWF0cml4KHQpe2NvbnN0IG49dHx8Wy0wLC0wLC0wLC0wLC0wLC0wLC0wLC0wLC0wLC0wLC0wLC0wLC0wLC0wLC0wLC0wXSxyPXRoaXMueCxpPXRoaXMueSxzPXRoaXMueixvPU1hdGguY29zKHIpLGM9TWF0aC5jb3MoaSksbD1NYXRoLmNvcyhzKSxoPU1hdGguc2luKHIpLGY9TWF0aC5zaW4oaSksdT1NYXRoLnNpbihzKTtzd2l0Y2godGhpc1szXSl7Y2FzZSBGLlhZWjp7Y29uc3QgZD1vKmwsZz1vKnUsbT1oKmwsXz1oKnU7blswXT1jKmwsbls0XT0tYyp1LG5bOF09ZixuWzFdPWcrbSpmLG5bNV09ZC1fKmYsbls5XT0taCpjLG5bMl09Xy1kKmYsbls2XT1tK2cqZixuWzEwXT1vKmM7YnJlYWt9Y2FzZSBGLllYWjp7Y29uc3QgZD1jKmwsZz1jKnUsbT1mKmwsXz1mKnU7blswXT1kK18qaCxuWzRdPW0qaC1nLG5bOF09bypmLG5bMV09byp1LG5bNV09bypsLG5bOV09LWgsblsyXT1nKmgtbSxuWzZdPV8rZCpoLG5bMTBdPW8qYzticmVha31jYXNlIEYuWlhZOntjb25zdCBkPWMqbCxnPWMqdSxtPWYqbCxfPWYqdTtuWzBdPWQtXypoLG5bNF09LW8qdSxuWzhdPW0rZypoLG5bMV09ZyttKmgsbls1XT1vKmwsbls5XT1fLWQqaCxuWzJdPS1vKmYsbls2XT1oLG5bMTBdPW8qYzticmVha31jYXNlIEYuWllYOntjb25zdCBkPW8qbCxnPW8qdSxtPWgqbCxfPWgqdTtuWzBdPWMqbCxuWzRdPW0qZi1nLG5bOF09ZCpmK18sblsxXT1jKnUsbls1XT1fKmYrZCxuWzldPWcqZi1tLG5bMl09LWYsbls2XT1oKmMsblsxMF09bypjO2JyZWFrfWNhc2UgRi5ZWlg6e2NvbnN0IGQ9bypjLGc9bypmLG09aCpjLF89aCpmO25bMF09YypsLG5bNF09Xy1kKnUsbls4XT1tKnUrZyxuWzFdPXUsbls1XT1vKmwsbls5XT0taCpsLG5bMl09LWYqbCxuWzZdPWcqdSttLG5bMTBdPWQtXyp1O2JyZWFrfWNhc2UgRi5YWlk6e2NvbnN0IGQ9bypjLGc9bypmLG09aCpjLF89aCpmO25bMF09YypsLG5bNF09LXUsbls4XT1mKmwsblsxXT1kKnUrXyxuWzVdPW8qbCxuWzldPWcqdS1tLG5bMl09bSp1LWcsbls2XT1oKmwsblsxMF09Xyp1K2Q7YnJlYWt9ZGVmYXVsdDp0aHJvdyBuZXcgRXJyb3IoamUpfXJldHVybiBuWzNdPTAsbls3XT0wLG5bMTFdPTAsblsxMl09MCxuWzEzXT0wLG5bMTRdPTAsblsxNV09MSxufXRvUXVhdGVybmlvbigpe2NvbnN0IHQ9TWF0aC5jb3ModGhpcy55YXcqLjUpLG49TWF0aC5zaW4odGhpcy55YXcqLjUpLHI9TWF0aC5jb3ModGhpcy5yb2xsKi41KSxpPU1hdGguc2luKHRoaXMucm9sbCouNSkscz1NYXRoLmNvcyh0aGlzLnBpdGNoKi41KSxvPU1hdGguc2luKHRoaXMucGl0Y2gqLjUpLGM9dCpyKnMrbippKm8sbD10Kmkqcy1uKnIqbyxoPXQqcipvK24qaSpzLGY9bipyKnMtdCppKm87cmV0dXJuIG5ldyBUdChsLGgsZixjKX19ZnVuY3Rpb24gZWgoZSl7cmV0dXJuIGU+PTAmJmU8Nn1mdW5jdGlvbiBuaChlKXtpZihlPDAmJmU+PTYpdGhyb3cgbmV3IEVycm9yKGplKTtyZXR1cm4gZX1jb25zdCByaD0uMSxpaD0xZS0xMixRZT0xZS0xNCxzaD0xZS0xNSxKaT1NYXRoLlBJLzIsVz1NYXRoLlBJKjI7ZnVuY3Rpb24gb2goZSl7c3dpdGNoKGUpe2Nhc2UgMjpyZXR1cm4gUTtjYXNlIDM6cmV0dXJuIFI7Y2FzZSA0OnJldHVybiBvdDtjYXNlIDk6cmV0dXJuIGN0O2Nhc2UgMTY6cmV0dXJuIHR0O2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKGDkuI3mlK/mjIHojrflj5bnsbs6ICR7ZX1gKX19ZnVuY3Rpb24gWShlKXtzd2l0Y2goZSl7Y2FzZSAyOnJldHVybiBSYztjYXNlIDM6cmV0dXJuIGNhO2Nhc2UgNDpyZXR1cm4gQ2w7Y2FzZSA5OnJldHVybiBiYTtjYXNlIDE2OnJldHVybiBvbDtkZWZhdWx0OnRocm93IG5ldyBFcnJvcihg5LiN5pSv5oyB6I635Y+W5ZG95ZCN56m66Ze0OiAke2V9YCl9fWZ1bmN0aW9uIEhpKGUpe3N3aXRjaChlLmxlbmd0aCl7Y2FzZSAyOnJldHVybiBuZXcgUShlKTtjYXNlIDM6cmV0dXJuIG5ldyBSKGUpO2Nhc2UgNDpyZXR1cm4gbmV3IG90KGUpO2Nhc2UgOTpyZXR1cm4gbmV3IGN0KGUpO2Nhc2UgMTY6cmV0dXJuIG5ldyB0dChlKTtkZWZhdWx0OnRocm93IG5ldyBFcnJvcihg5LiN5pSv5oyB5Yib5bu65a6e5L6LOiAke2xlbmd0aH1gKX19Y29uc3QgY2g9ezQ6InRyYW5zZm9ybU1hdDIiLDY6InRyYW5zZm9ybU1hdDJkIiw5OiJ0cmFuc2Zvcm1NYXQzIiwxNjoidHJhbnNmb3JtTWF0NCJ9O2Z1bmN0aW9uIGhlKGUsdCl7Y29uc3Qgbj1ZKHQpLHI9Y2hbZV0saT1uW3JdO2lmKCFpKXRocm93IG5ldyBFcnJvcihg5LiN5pSv5oyB55qE55+p6Zi15aSn5bCP77yaJHtlfWApO3JldHVybiBpfWNvbnN0IHRzPXtBcnJheSxJbnQ4QXJyYXksVWludDhBcnJheSxVaW50OENsYW1wZWRBcnJheSxJbnQxNkFycmF5LFVpbnQxNkFycmF5LEludDMyQXJyYXksVWludDMyQXJyYXksRmxvYXQzMkFycmF5LEZsb2F0NjRBcnJheX07dmFyIEtlPShlPT4oZS5BcnJheT0iQXJyYXkiLGUuSW50OEFycmF5PSJJbnQ4QXJyYXkiLGUuVWludDhBcnJheT0iVWludDhBcnJheSIsZS5VaW50OENsYW1wZWRBcnJheT0iVWludDhDbGFtcGVkQXJyYXkiLGUuSW50MTZBcnJheT0iSW50MTZBcnJheSIsZS5VaW50MTZBcnJheT0iVWludDE2QXJyYXkiLGUuSW50MzJBcnJheT0iSW50MzJBcnJheSIsZS5VaW50MzJBcnJheT0iVWludDMyQXJyYXkiLGUuRmxvYXQzMkFycmF5PSJGbG9hdDMyQXJyYXkiLGUuRmxvYXQ2NEFycmF5PSJGbG9hdDY0QXJyYXkiLGUpKShLZXx8e30pOyhlPT57ZnVuY3Rpb24gdChpKXtyZXR1cm4gdHNbaV19ZS50b0NsYXNzPXQ7ZnVuY3Rpb24gbihpKXtyZXR1cm4gaS5uYW1lfWUudG9UeXBlPW47ZnVuY3Rpb24gcihpKXtyZXR1cm4gaS5jb25zdHJ1Y3Rvci5uYW1lfWUudG9UeXBlQnlBcnJheT1yfSkoS2V8fChLZT17fSkpO2Z1bmN0aW9uIGVzKGUpe2NvbnN0IHQ9W107Zm9yKGNvbnN0IG4gb2ZbIngiLCJ5IiwieiIsInciXSl7aWYoZVtuXT09bnVsbClyZXR1cm4gdDt0LnB1c2goZVtuXSl9cmV0dXJuIHR9ZnVuY3Rpb24gbnMoZSl7cmV0dXJuIEhpKGVzKGUpKX1mdW5jdGlvbiBmZShlLHQsbil7bj1uPz8wO2NvbnN0IHI9bisxO2lmKHB0KGUpKXJldHVybiBlO2lmKGUueCE9bnVsbCYmZS55IT1udWxsKXJldHVybiBucyhlKTtpZihBcnJheS5pc0FycmF5KGUpKXJldHVybiBlLm1hcChzPT5mZShzLHQscikpO2lmKGUgaW5zdGFuY2VvZiBNYXApe2NvbnN0IHM9bmV3IE1hcDtmb3IoY29uc3QgbyBvZiBlLmtleXMoKSl7Y29uc3QgYz1lLmdldChvKSxsPWZlKGMsdCxyKTtzLnNldChvLGwpfXJldHVybiBzfWlmKHp0KGUpKXtjb25zdCBzPVtdO2Zvcihjb25zdCBvIG9mIGUpe2NvbnN0IGM9ZmUobyx0LHIpO3MucHVzaChjKX1yZXR1cm4gc31pZigodHx8bj09PTApJiZ0eXBlb2YgZT09Im9iamVjdCIpe2NvbnN0IHM9e307Zm9yKGNvbnN0IG8gb2YgT2JqZWN0LmtleXMoZSkpc1tvXT1mZShlW29dLHQscik7cmV0dXJuIHN9cmV0dXJuIGV9dmFyIHk9KGU9PihlW2UuVGhyb3VnaEludGVyc2VjdD0xXT0iVGhyb3VnaEludGVyc2VjdCIsZVtlLkpvaW50SW50ZXJzZWN0PTJdPSJKb2ludEludGVyc2VjdCIsZVtlLkludGVyc2VjdD0zXT0iSW50ZXJzZWN0IixlW2UuVGFuZ2VuY3k9NF09IlRhbmdlbmN5IixlW2UuQ29udGFpbj04XT0iQ29udGFpbiIsZVtlLkRpc3NvY2lhdGlvbj0xNl09IkRpc3NvY2lhdGlvbiIsZVtlLkFCPTMyXT0iQUIiLGVbZS5CQT02NF09IkJBIixlW2UuQUJDb250YWluPTQwXT0iQUJDb250YWluIixlW2UuQkFDb250YWluPTcyXT0iQkFDb250YWluIixlKSkoeXx8e30pO2Z1bmN0aW9uIFluKGUsdCl7cmV0dXJuIE5uKGUsdCksVm4oZSxlKX1mdW5jdGlvbiBhaChlLHQ9bmV3IHR0KXtyZXR1cm4gdFswXT1lWzBdLHRbMV09ZVsxXSx0WzJdPWVbMl0sdFszXT0wLHRbNF09ZVszXSx0WzVdPWVbNF0sdFs2XT1lWzVdLHRbN109MCx0WzhdPWVbNl0sdFs5XT1lWzddLHRbMTBdPWVbOF0sdFsxMV09MCx0WzEyXT0wLHRbMTNdPTAsdFsxNF09MCx0WzE1XT0xLHQuY2hlY2soKX1mdW5jdGlvbiBycyhlLHQsbil7Y29uc3Qgcj1ZKHQubGVuZ3RoKSxpPXIuc3F1YXJlZExlbmd0aChuKTtpZihrKGksMCkpcmV0dXJuIHIuc2NhbGUoZSx0LDApO2NvbnN0IHM9ci5kb3QodCxuKS9pO3JldHVybiByLnNjYWxlKGUsbixzKX1mdW5jdGlvbiBhdChlLHQsbil7cmV0dXJuIHJzKGUsdCxuKSxHKGUsdCxlKX1mdW5jdGlvbiBsaChlLHQsbil7cmV0dXJuIFkodC5sZW5ndGgpLmNyb3NzKGUsdCxuKX1mdW5jdGlvbiBCKGUsdCl7Y29uc3Qgbj10LmZpbmRJbmRleChpPT4hayhpLDApKTtpZihuPT09LTEpcmV0dXJuIDA7Y29uc3Qgcj1lW25dO3JldHVybiBrKHIsMCk/MS8wOnRbbl0vcn1mdW5jdGlvbiBKZShlLHQpe2NvbnN0IG49dC5maW5kSW5kZXgocz0+IWsocywwKSk7aWYobj09PS0xKXJldHVybiEwO2NvbnN0IHI9ZVtuXS90W25dO3JldHVybiBfdC5nZXRDcm9zc0F4aXNzKG4pLmV2ZXJ5KHM9PmsodFtzXSpyLGVbc10pKX1mdW5jdGlvbiBoaChlLHQpe2NvbnN0IG49WShlLmxlbmd0aCkscj1uLmNyb3NzKFtdLGUsdCksaT1uLnNxdWFyZWRMZW5ndGgocik7cmV0dXJuIGsoaSwwKX1mdW5jdGlvbiBpcyhlLHQpe3JldHVybiBrKEZ0KFtdLGUsdClbMl0sMCl9ZnVuY3Rpb24gZmgoZSx0KXtjb25zdCBuPUgoW10sZSx0KTtyZXR1cm4gayhxdChuKSwwKX1mdW5jdGlvbiBzcyhlLHQpe2NvbnN0IHI9WShlLmxlbmd0aCkuY3Jvc3MoW10sZSx0KTtyZXR1cm4gTWF0aC5oeXBvdCguLi5yKX1mdW5jdGlvbiBvcyhlLHQpe2NvbnN0IG49SChbXSxlLHQpO3JldHVybiBNYXRoLmh5cG90KC4uLm4pfWZ1bmN0aW9uIGNzKGUsdCl7cmV0dXJuIE1hdGguYWJzKEJ0KGUsdCkpfWZ1bmN0aW9uIGFzKGUsdCxuKXtyZXR1cm4gZS5sZW5ndGg9PT0yP0J0KGUsdCk6V24oZSx0LG4pfWZ1bmN0aW9uIEJ0KGUsdCl7cmV0dXJuIEZ0KFtdLGUsdClbMl19ZnVuY3Rpb24gV24oZSx0LG4pe2NvbnN0IHI9Wy4uLmUsLi4udCwuLi5uXTtyZXR1cm4gbGUocil9bmV3IFEsbmV3IFIsbmV3IG90O2NvbnN0IGx0PVtuZXcgUSxuZXcgUSxuZXcgUSxuZXcgUV0saHQ9W25ldyBSLG5ldyBSLG5ldyBSLG5ldyBSXSx1aD1bbmV3IG90LG5ldyBvdCxuZXcgb3QsbmV3IG90XSxabj1bbmV3IGN0LG5ldyBjdCxuZXcgY3QsbmV3IGN0XSxkaD1bbmV3IHR0LG5ldyB0dCxuZXcgdHQsbmV3IHR0XSxnaD1bbmV3IFR0LG5ldyBUdCxuZXcgVHQsbmV3IFR0XSxtaD1bbmV3IEYsbmV3IEYsbmV3IEYsbmV3IEZdO2Z1bmN0aW9uIG50KGUpe3N3aXRjaChlKXtjYXNlIDI6cmV0dXJuIGx0O2Nhc2UgMzpyZXR1cm4gaHQ7Y2FzZSA0OnJldHVybiB1aDtjYXNlIDk6cmV0dXJuIFpuO2Nhc2UgMTY6cmV0dXJuIGRoO2RlZmF1bHQ6dGhyb3cgbmV3IEVycm9yKGDkuI3mlK/mjIHojrflj5bkuLTml7blj5jph486ICR7ZX1gKX19ZnVuY3Rpb24gcGgoZSx0PW5ldyBUdCl7c3dpdGNoKHQuaWRlbnRpdHkoKSxlLm9yZGVyKXtjYXNlIEYuWFlaOnJldHVybiB0LnJvdGF0ZVgoZVswXSkucm90YXRlWShlWzFdKS5yb3RhdGVaKGVbMl0pO2Nhc2UgRi5ZWFo6cmV0dXJuIHQucm90YXRlWShlWzBdKS5yb3RhdGVYKGVbMV0pLnJvdGF0ZVooZVsyXSk7Y2FzZSBGLlpYWTpyZXR1cm4gdC5yb3RhdGVaKGVbMF0pLnJvdGF0ZVgoZVsxXSkucm90YXRlWShlWzJdKTtjYXNlIEYuWllYOnJldHVybiB0LnJvdGF0ZVooZVswXSkucm90YXRlWShlWzFdKS5yb3RhdGVYKGVbMl0pO2Nhc2UgRi5ZWlg6cmV0dXJuIHQucm90YXRlWShlWzBdKS5yb3RhdGVaKGVbMV0pLnJvdGF0ZVgoZVsyXSk7Y2FzZSBGLlhaWTpyZXR1cm4gdC5yb3RhdGVYKGVbMF0pLnJvdGF0ZVooZVsxXSkucm90YXRlWShlWzJdKTtkZWZhdWx0OnRocm93IG5ldyBFcnJvcigiVW5rbm93biBFdWxlciBhbmdsZSBvcmRlciIpfX1mdW5jdGlvbiBfaChlLHQsbixyPW5ldyBUdCl7Y29uc3RbaSxzXT1odDtyZXR1cm4gYXQoaSxlLG4pLm5vcm1hbGl6ZSgpLGF0KHMsdCxuKS5ub3JtYWxpemUoKSxyLnJvdGF0aW9uVG8oaSxzKX1mdW5jdGlvbiBscyhlLHQpe3JldHVybiBNYXRoLnNpZ24oZSk9PT1NYXRoLnNpZ24odCkmJk1hdGguYWJzKGUpPE1hdGguYWJzKHQpP2U6KGUldCt0KSV0fWZ1bmN0aW9uIEduKGUsdCxuPTAscj1uKXtjb25zdCBpPU1hdGguYWJzKGUtdCk7cmV0dXJuIGk8PXJ8fGk8PW4qTWF0aC5tYXgoTWF0aC5hYnMoZSksTWF0aC5hYnModCkpfWZ1bmN0aW9uIGhzKGUsdCxuPTApe2xldCByPXF0KGUpKnF0KHQpO2lmKHI9PT0wKXJldHVybiBuO3I9TWF0aC5zcXJ0KHIpO2xldCBpPVV0KGUsdCkvcjtyZXR1cm4gaT1NYXRoLm1heCgtMSxNYXRoLm1pbigxLGkpKSxNYXRoLmFjb3MoaSl9ZnVuY3Rpb24gdWUoZSx0LG4pe2xldCByPWhzKGUsdCk7cmV0dXJuIHI9PT0wP3I6aHRbMF0uY29weShlKS5jcm9zcyh0KS5kb3Qobik8MD8tcjpyfWZ1bmN0aW9uIHloKGUsdCxuKXtjb25zdFtyLGldPW50KGUubGVuZ3RoKTtyZXR1cm4gYXQocixlLG4pLGF0KGksdCxuKSx1ZShyLGksbil9ZnVuY3Rpb24geGgoZSx0LG4pe2NvbnN0W3IsaSxzLG9dPWh0O3IubmVnYXRlKCksYXQoaSxuLHQpLGF0KHMsZSxpKTtjb25zdCBjPXVlKHQscyxpKSxsPW5ldyBSKHQpLmNyb3NzKGkpO2F0KG8sZSxsKTtjb25zdCBoPXVlKHQsbyxsKSxmPWF0KG5ldyBSLGUsciksdT11ZShpLGYscik7cmV0dXJue3lhdzpjLHBpdGNoOmgscm9sbDp1fX1mdW5jdGlvbiBZdChlKXtyZXR1cm4gZT49LU1hdGguUEkmJmU8PU1hdGguUEk/ZTpNaChlK01hdGguUEkpLU1hdGguUEl9ZnVuY3Rpb24gTWgoZSl7aWYoZT49MCYmZTw9VylyZXR1cm4gZTtjb25zdCB0PWxzKGUsVyk7cmV0dXJuIE1hdGguYWJzKHQpPFFlJiZNYXRoLmFicyhlKT5RZT9XOnR9ZnVuY3Rpb24gZnMoZSx0LG4scil7Y29uc3QgaT1yfHxlLnNsaWNlKCk7cmV0dXJuIEgoaSxpLHQpLGsocXQoaSksMCkmJihuP2soTWF0aC5hYnModFsyXSksMSk/ZVswXS09MWUtNDplWzJdKz0xZS00OmsoTWF0aC5hYnMoZVswXSksMSk/dFsyXS09MWUtNDp0WzBdKz0xZS00LEF0KHQsdCksSChpLGUsdCkpLG4/SChlLHQsaSk6SCh0LGksZSksQXQoaSxpKSxBdCh0LHQpLEF0KGUsZSkse3RhbmdlbnQ6ZSxub3JtYWw6dCxiaW5vcm1hbDppfX1mdW5jdGlvbiB1cyhlLHQsbixyKXtjb25zdHtiaW5vcm1hbDppfT1mcyhlLHQsbixyKTtyZXR1cm4ga2UoaSxpKSx7ZnJvbnQ6ZSx1cDp0LGJpbm9ybWFsOml9fWZ1bmN0aW9uIHdoKGUpe2NvbnN0e3RhbmdlbnQ6dCxub3JtYWw6bixiaW5vcm1hbDpyfT1lO3JldHVybntmcm9udDp0LHVwOm4sYmlub3JtYWw6a2UoW10scil9fWZ1bmN0aW9uIEFoKGUpe2NvbnN0e2Zyb250OnQsdXA6bixiaW5vcm1hbDpyfT1lO3JldHVybnt0YW5nZW50OnQsbm9ybWFsOm4sYmlub3JtYWw6a2UoW10scil9fWZ1bmN0aW9uIFRoKGUsdCxuLHI9bmV3IGN0KXtjb25zdHtmcm9udDppLHVwOnMsYmlub3JtYWw6b309dXMoQXQoW10sZSksQXQoW10sdCksbik7cmV0dXJuIHIuc2V0Q29sdW1uKDAsbyksci5zZXRDb2x1bW4oMSxzKSxyLnNldENvbHVtbigyLGkpLHJ9Y29uc3QgZHM9e2Vhc3Q6WzEsMCwwXSxub3J0aDpbMCwwLDFdLHVwOlswLC0xLDBdfTtmdW5jdGlvbiBncyhlLHQ9ZHMpe2NvbnN0W24scl09ZSxzPW1oWzBdLnNldCgtciwwLG4sRi5ZWFopLnRvUXVhdGVybmlvbigpLHtlYXN0Om8sbm9ydGg6Yyx1cDpsfT10LGg9bmV3IFIoLi4ubykudHJhbnNmb3JtQnlRdWF0ZXJuaW9uKHMpLGY9bmV3IFIoLi4uYykudHJhbnNmb3JtQnlRdWF0ZXJuaW9uKHMpLHU9bmV3IFIoLi4ubCkudHJhbnNmb3JtQnlRdWF0ZXJuaW9uKHMpO3JldHVybntlYXN0Omgsbm9ydGg6Zix1cDp1fX1mdW5jdGlvbiBYbihlLHQ9ZHMpe2NvbnN0W24scixpLHNdPWh0O2kuc2V0KDAsLTEsMCksbi5zZXQoMCwwLDEpLHMuY29weShlKS5ub3JtYWxpemUoKSxhdChyLHMsbiksci5ub3JtYWxpemUoKTtjb25zdFtvLGNdPWdoO28ucm90YXRpb25UbyhpLHIpLGMucm90YXRpb25UbyhyLHMpLGMubXVsdGlwbHlSaWdodChvKTtjb25zdHtlYXN0Omwsbm9ydGg6aCx1cDpmfT10LHU9bmV3IFIoLi4ubCkudHJhbnNmb3JtQnlRdWF0ZXJuaW9uKGMpLGQ9bmV3IFIoLi4uaCkudHJhbnNmb3JtQnlRdWF0ZXJuaW9uKGMpLGc9bmV3IFIoLi4uZikudHJhbnNmb3JtQnlRdWF0ZXJuaW9uKGMpO3JldHVybntlYXN0OnUsbm9ydGg6ZCx1cDpnfX1mdW5jdGlvbiBIZShlLHQpe2NvbnN0e3g6bix5OnIsejppfT1lLHM9c3QuZ2V0VmVjdG9yKHN0W25dLHQpLG89c3QuZ2V0VmVjdG9yKHN0W3JdLHQpLGM9c3QuZ2V0VmVjdG9yKHN0W2ldLHQpO3JldHVybiBuZXcgY3QoWy4uLnMsLi4ubywuLi5jXSl9ZnVuY3Rpb24gbXMoZSx0LG4pe2NvbnN0IHI9aHRbMF0uY29weShlKSxpPUhlKHQsbik7cmV0dXJuIHIudHJhbnNmb3JtQnlNYXRyaXgzKGkpLm5lZ2F0ZSgpLHIuYWRkKGUpLG5ldyB0dChbLi4uaS5zbGljZSgwLDMpLDAsLi4uaS5zbGljZSgzLDYpLDAsLi4uaS5zbGljZSg2LDkpLDAsLi4uciwxXSl9ZnVuY3Rpb24gRWgoZSx0LG4pe2NvbnN0IHI9WG4oZSxuKTtyZXR1cm4gbXMoZSx0LHIpfWZ1bmN0aW9uIE9oKGUsdCxuKXtjb25zdCByPVhuKGUsbik7cmV0dXJuIEhlKHQscil9ZnVuY3Rpb24gdmgoZSx0LG4pe2NvbnN0IHI9Z3MoZSxuKTtyZXR1cm4gSGUodCxyKX1mdW5jdGlvbiBiaChlKXtsZXQgdDtjb25zdCBuPXI9PntlKHIpLHQ9cmVxdWVzdEFuaW1hdGlvbkZyYW1lKG4pfTtyZXR1cm4gdD1yZXF1ZXN0QW5pbWF0aW9uRnJhbWUobiksKCk9PntjYW5jZWxBbmltYXRpb25GcmFtZSh0KX19ZnVuY3Rpb24gSWgoZSx0KXtjb25zdFtuLHJdPWUse2NlbnRlcjppLHJhZGl1czpzfT10LFtvLGNdPW50KG4ubGVuZ3RoKTtvLnN1YlZlY3RvcnMocixuKSxjLnN1YlZlY3RvcnMoaSxuKTtjb25zdCBsPW8ubGVuZ3RoU3F1YXJlZCgpLGg9by5kb3QoYykqKjIsZj1sKihjLmxlbmd0aFNxdWFyZWQoKS1zKioyKSx1PWgtZjtyZXR1cm4gayh1LDApP3kuVGFuZ2VuY3k6dTwwP3kuRGlzc29jaWF0aW9uOnkuSW50ZXJzZWN0fWZ1bmN0aW9uIFd0KGUsdCl7Y29uc3RbbixyXT1lLHtjZW50ZXI6aSxyYWRpdXM6c309dCxbbyxjXT1udChuLmxlbmd0aCk7by5zdWJWZWN0b3JzKHIsbiksYy5zdWJWZWN0b3JzKG4saSk7Y29uc3QgbD1vLmxlbmd0aFNxdWFyZWQoKSxoPTIqby5kb3QoYyksZj1jLmxlbmd0aFNxdWFyZWQoKS1zKioyLHU9aCoqMi00KmwqZixkPWsodSwwKTtpZighZCYmdTwwKXJldHVybltdO2NvbnN0IGc9bCoyLG09LWgvZztpZihkKXJldHVyblttXTtjb25zdCBwPU1hdGguc3FydCh1KS9nLE09bS1wLEE9bStwO3JldHVybltNLEFdfWZ1bmN0aW9uIFNoKGUsdCl7Y29uc3RbbixyXT1lLGk9bnQobi5sZW5ndGgpWzJdO3JldHVybiBpLnN1YlZlY3RvcnMocixuKSxXdChlLHQpLm1hcChvPT5pLmNsb25lKCkubXVsdGlwbHlCeVNjYWxhcihvKS5hZGQobikpfWZ1bmN0aW9uIHBzKGUsdCl7Y29uc3Qgbj1XdChlLHQpLHI9bi5sZW5ndGg7aWYocj09PTApcmV0dXJuIHkuRGlzc29jaWF0aW9uO2xldCBpPTAscz0wLG89MDtmb3IoY29uc3QgbCBvZiBuKWsobCwwKXx8ayhsLDEpP28rKzpsPjE/cysrOmw8MCYmaSsrO2NvbnN0IGM9aStzO3JldHVybiByPT09MSYmYz09PTA/eS5UYW5nZW5jeTppPT09MSYmcz09PTF8fG89PT0yP3kuQ29udGFpbjppPT09Mnx8cz09PTI/eS5EaXNzb2NpYXRpb246eS5JbnRlcnNlY3R9ZnVuY3Rpb24gX3MoZSx0KXtjb25zdFtuLHJdPWUsaT1udChlWzBdLmxlbmd0aClbMl07aS5zdWJWZWN0b3JzKHIsbik7Y29uc3Qgcz1XdChlLHQpLG89W107Zm9yKGNvbnN0IGMgb2Ygcyl7aWYoIWsoYywwKSYmYzwwfHwhayhjLDEpJiZjPjEpY29udGludWU7Y29uc3QgbD1pLmNsb25lKCkubXVsdGlwbHlCeVNjYWxhcihjKS5hZGQobik7by5wdXNoKGwpfXJldHVybiBvfWZ1bmN0aW9uIExoKGUsdCl7Y29uc3Qgbj1XdChlLHQpLHI9bi5sZW5ndGg7aWYocj09PTApcmV0dXJuIHkuRGlzc29jaWF0aW9uO2xldCBpPTA7Zm9yKGNvbnN0IHMgb2YgbilzPDAmJmkrKztyZXR1cm4gcj09PTEmJmk9PT0wP3kuVGFuZ2VuY3k6aT09PTI/eS5EaXNzb2NpYXRpb246eS5JbnRlcnNlY3R9ZnVuY3Rpb24gUGgoZSx0KXtjb25zdFtuLHJdPWUsaT1udChuLmxlbmd0aClbMl07aS5zdWJWZWN0b3JzKHIsbik7Y29uc3Qgcz1XdChlLHQpLG89W107Zm9yKGNvbnN0IGMgb2Ygcyl7aWYoYzwwKWNvbnRpbnVlO2NvbnN0IGw9aS5jbG9uZSgpLm11bHRpcGx5QnlTY2FsYXIoYykuYWRkKG4pO28ucHVzaChsKX1yZXR1cm4gb31mdW5jdGlvbiB4dChlLHQpe2NvbnN0IG49RyhbXSxlWzFdLGVbMF0pLHI9RyhbXSx0LGVbMF0pO3JldHVybiBGdChuLG4sciksayhuWzJdLDApPzA6blsyXX1mdW5jdGlvbiBSaChlLHQpe2NvbnN0IG49Wy4uLmVbMF0sLi4uZVsxXSwuLi50XTtsZXQgcj1sZShuKTtyZXR1cm4gayhyLDApPyhuWzJdKz0xLG5bNV0rPTEsbls4XSs9MSxyPWxlKG4pLGsociwwKT8wOnIpOnJ9ZnVuY3Rpb24gQ2goZSx0KXtjb25zdFtuLHJdPWUsW2ksc109bnQodC5sZW5ndGgpO2lmKGkuc3ViVmVjdG9ycyh0LG4pLHMuc3ViVmVjdG9ycyhyLG4pLEplKHMsaSkpe2NvbnN0IG89QihzLGkpO3JldHVybiBvPDB8fG8+MT95LlRhbmdlbmN5OnkuQ29udGFpbn1yZXR1cm4geS5EaXNzb2NpYXRpb259ZnVuY3Rpb24geXMoZSx0KXtjb25zdFtuLHJdPWUsW2ksc109bHQ7aWYoaS5zdWJWZWN0b3JzKHQsbikscy5zdWJWZWN0b3JzKHIsbiksaXMocyxpKSl7Y29uc3Qgbz1CKHMsaSk7cmV0dXJuIG88MHx8bz4xP3kuVGFuZ2VuY3k6eS5Db250YWlufXJldHVybiB5LkRpc3NvY2lhdGlvbn1mdW5jdGlvbiB0bihlLHQpe2NvbnN0W24scl09ZSxbaSxzXT10LFtvLGMsbF09bnQobi5sZW5ndGgpO3JldHVybiBjLnN1YlZlY3RvcnMocixuKSxsLnN1YlZlY3RvcnMocyxpKSxKZShsLGMpPyhvLnN1YlZlY3RvcnMoaSxuKSxKZShvLGMpP3kuVGFuZ2VuY3k6eS5EaXNzb2NpYXRpb24pOnkuSW50ZXJzZWN0fWZ1bmN0aW9uIGRlKGUsdCxuKXtjb25zdFtyLGldPXQsW3Msb109bixbYyxsLGhdPW50KHIubGVuZ3RoKTtjLnN1YlZlY3RvcnMoaSxyKSxsLnN1YlZlY3RvcnMobyxzKTtjb25zdCBmPVkoci5sZW5ndGgpLHU9Zi5jcm9zcyhbXSxjLGwpO2lmKGsoZi5zcXVhcmVkTGVuZ3RoKHUpLDApKXJldHVybiBudWxsO2guc3ViVmVjdG9ycyhzLHIpO2NvbnN0IGQ9Zi5jcm9zcyhbXSxoLGwpLGc9Qih1LGQpO3JldHVybiBmLnNjYWxlQW5kQWRkKGUscixjLGcpfWZ1bmN0aW9uIGVuKGUsdCxuKXtjb25zdFtyLGldPXQsW3Msb109bixbYyxsLGhdPWx0O2Muc3ViVmVjdG9ycyhpLHIpLGwuc3ViVmVjdG9ycyhvLHMpO2NvbnN0IGY9RnQoW10sYyxsKVsyXTtpZihrKGYsMCkpcmV0dXJuIG51bGw7aC5zdWJWZWN0b3JzKHMscik7Y29uc3QgZD1GdChbXSxoLGwpWzJdL2Y7cmV0dXJuIEJyKGUscixjLGQpfWZ1bmN0aW9uIFZoKGUsdCl7Y29uc3RbbixyXT10LFtpLHNdPWUsbz1ZKG4ubGVuZ3RoKSxjPW8uc3VidHJhY3QoW10scyxpKSxsPXRuKGUsdCk7aWYobD09PXkuVGFuZ2VuY3kpe2xldCBnPTA7cmV0dXJuIEIoYyxvLnN1YnRyYWN0KFtdLG4saSkpPDAmJmcrKyxCKGMsby5zdWJ0cmFjdChbXSxyLGkpKTwwJiZnKyssZz09PTI/eS5EaXNzb2NpYXRpb246Zz09PTA/eS5Db250YWluOnkuVGFuZ2VuY3l9aWYobCE9PXkuSW50ZXJzZWN0KXJldHVybiBsO2NvbnN0IGg9ZGUoW10sZSx0KSxmPW8uc3VidHJhY3QoW10scixuKSx1PUIoZixvLnN1YnRyYWN0KFtdLGgsbikpO3JldHVybiB1PDB8fHU+MXx8QihjLG8uc3VidHJhY3QoW10saCxpKSk8MD95LkRpc3NvY2lhdGlvbjp5LkludGVyc2VjdH1mdW5jdGlvbiB4cyhlLHQpe2NvbnN0W24scl09dCxbaSxzXT1lLG89RyhbXSxzLGkpLGM9dG4oZSx0KTtpZihjPT09eS5UYW5nZW5jeSl7bGV0IGQ9MDtyZXR1cm4gQihvLEcoW10sbixpKSk8MCYmZCsrLEIobyxHKFtdLHIsaSkpPDAmJmQrKyxkPT09Mj95LkRpc3NvY2lhdGlvbjpkPT09MD95LkNvbnRhaW46eS5UYW5nZW5jeX1pZihjIT09eS5JbnRlcnNlY3QpcmV0dXJuIGM7Y29uc3QgbD1lbihbXSxlLHQpLGg9RyhbXSxyLG4pLGY9QihoLEcoW10sbCxuKSk7cmV0dXJuIGY8MHx8Zj4xfHxCKG8sRyhbXSxsLGkpKTwwP3kuRGlzc29jaWF0aW9uOnkuSW50ZXJzZWN0fWZ1bmN0aW9uIE5oKGUsdCxuKXtjb25zdCByPWRlKGUsdCxuKTtpZihyPT09bnVsbClyZXR1cm4gbnVsbDtjb25zdFtpLHNdPW4sbz1ZKGkubGVuZ3RoKSxjPW8uc3VidHJhY3QoW10scyxpKSxsPUIoYyxvLnN1YnRyYWN0KFtdLHIsaSkpO2lmKGw8MHx8bD4xKXJldHVybiBudWxsO2NvbnN0W2gsZl09dCx1PW8uc3VidHJhY3QoW10sZixoKTtyZXR1cm4gQih1LG8uc3VidHJhY3QoW10scixoKSk8MD9udWxsOnJ9ZnVuY3Rpb24gJGgoZSx0LG4pe2NvbnN0IHI9ZW4oZSx0LG4pO2lmKHI9PT1udWxsKXJldHVybiBudWxsO2NvbnN0W2ksc109bixvPUcoW10scyxpKSxjPUIobyxHKFtdLHIsaSkpO2lmKGM8MHx8Yz4xKXJldHVybiBudWxsO2NvbnN0W2wsaF09dCxmPUcoW10saCxsKTtyZXR1cm4gQihmLEcoW10scixsKSk8MD9udWxsOnJ9ZnVuY3Rpb24gam4oZSx0KXtjb25zdFtuLHJdPWUsW2ksc109dCxvPVkobi5sZW5ndGgpLGM9by5zdWJ0cmFjdChbXSxyLG4pLGw9dG4oZSx0KTtpZihsPT09eS5UYW5nZW5jeSl7bGV0IGc9MCxtPTA7Y29uc3QgXz1CKGMsby5zdWJ0cmFjdChbXSxpLG4pKTtfPDA/ZysrOl8+MSYmbSsrO2NvbnN0IHA9QihjLG8uc3VidHJhY3QoW10scyxuKSk7cmV0dXJuIHA8MD9nKys6cD4xJiZtKyssZz09PTJ8fG09PT0yP3kuRGlzc29jaWF0aW9uOmcrbT09PTE/eS5UYW5nZW5jeTp5LkNvbnRhaW59aWYobCE9PXkuSW50ZXJzZWN0KXJldHVybiBsO2NvbnN0IGg9ZGUoW10sZSx0KSxmPW8uc3VidHJhY3QoW10scyxpKSx1PUIoZixvLnN1YnRyYWN0KFtdLGgsaSkpO2lmKHU8MHx8dT4xKXJldHVybiB5LkRpc3NvY2lhdGlvbjtpZih1PT09MHx8dT09PTEpcmV0dXJuIHkuSm9pbnRJbnRlcnNlY3Q7Y29uc3QgZD1CKGMsby5zdWJ0cmFjdChbXSxoLG4pKTtyZXR1cm4gZDwwfHxkPjE/eS5EaXNzb2NpYXRpb246ZD09PTB8fGQ9PT0xP3kuSm9pbnRJbnRlcnNlY3Q6eS5UaHJvdWdoSW50ZXJzZWN0fWZ1bmN0aW9uIHpoKGUsdCxuKXtjb25zdCByPWRlKGUsdCxuKTtpZihyPT09bnVsbClyZXR1cm4gbnVsbDtjb25zdFtpLHNdPW4sbz1ZKGkubGVuZ3RoKSxjPW8uc3VidHJhY3QoW10scyxpKSxsPUIoYyxvLnN1YnRyYWN0KFtdLHIsaSkpO2lmKGw8MHx8bD4xKXJldHVybiBudWxsO2NvbnN0W2gsZl09dCx1PW8uc3VidHJhY3QoW10sZixoKSxkPUIodSxvLnN1YnRyYWN0KFtdLHIsaCkpO3JldHVybiBkPDB8fGQ+MT9udWxsOnJ9ZnVuY3Rpb24ga2goZSx0LG4pe2NvbnN0IHI9ZW4oZSx0LG4pO2lmKHI9PT1udWxsKXJldHVybiBudWxsO2NvbnN0W2ksc109bixvPUcoW10scyxpKSxjPUIobyxHKFtdLHIsaSkpO2lmKGM8MHx8Yz4xKXJldHVybiBudWxsO2NvbnN0W2wsaF09dCxmPUcoW10saCxsKSx1PUIoZixHKFtdLHIsbCkpO3JldHVybiB1PDB8fHU+MT9udWxsOnJ9ZnVuY3Rpb24gRmgoZSl7Y29uc3QgdD1bXTtmb3IobGV0IHI9MDtyPGUubGVuZ3RoO3IrKyl7Y29uc3QgaT1lW3JdO3QucHVzaChbaVswXSwhMCxyXSxbaVsxXSwhMSxyXSl9bGV0IG49ITE7dC5zb3J0KChyLGkpPT57bGV0IHM9clswXS1pWzBdO3JldHVybiBzIT09MHx8KHM9clsyXS1pWzJdLHMhPT0wJiYobj0hMCkpLHN9KTtmb3IobGV0IHI9MDtyPHQubGVuZ3RoO3IrPTIpe2NvbnN0IGk9dFtyXSxzPXRbcisxXTtpZihpWzFdPT09c1sxXSlyZXR1cm4geS5UaHJvdWdoSW50ZXJzZWN0fXJldHVybiBuP3kuSm9pbnRJbnRlcnNlY3Q6eS5EaXNzb2NpYXRpb259ZnVuY3Rpb24gTXMoZSl7Y29uc3QgdD1lLmxlbmd0aDtpZih0PDMpcmV0dXJuIGU7bGV0IG49ZVswXVsxXSxyPVswXTtmb3IobGV0IG89MTtvPHQ7bysrKXtjb25zdCBjPWVbb11bMV07YzxuPyhuPWMscj1bb10pOmM9PT1uJiZyLnB1c2gobyl9bGV0IGk9clswXTtpZihyLmxlbmd0aD4xKXtuPWVbclswXV1bMF07Zm9yKGxldCBvPTE7bzxyLmxlbmd0aDtvKyspe2NvbnN0IGM9cltvXSxsPWVbY11bMF07bDxuJiYobj1sLGk9Yyl9fWNvbnN0IHM9ZS5zcGxpY2UoaSwxKVswXTtyZXR1cm4gZS5zb3J0KChvLGMpPT54dChbcyxjXSxvKSksZS51bnNoaWZ0KHMpLGV9ZnVuY3Rpb24gd3MoZSl7Y29uc3QgdD1lLnNsaWNlKDAsMik7dDpmb3IobGV0IG49MjtuPGUubGVuZ3RoO24rKyl7bGV0IHI9dC5hdCgtMiksaT10LmF0KC0xKTtjb25zdCBzPWVbbl07bGV0IG89eHQoW3IsaV0scyk7Zm9yKDtvPD0wOyl7aWYobz09PTApe05lKHIscyk+TmUocixpKSYmKHRbdC5sZW5ndGgtMV09cyk7Y29udGludWUgdH10LnBvcCgpLGk9cixyPXQuYXQoLTIpLG89eHQoW3IsaV0scyl9dC5wdXNoKHMpfXJldHVybiB0fWZ1bmN0aW9uIHFoKGUpe3JldHVybiB3cyhNcyhlKSl9ZnVuY3Rpb24gQXMoZSl7Y29uc3QgdD1lLmxlbmd0aDtpZih0PDQpcmV0dXJuITA7bGV0IG49MDtmb3IobGV0IHI9MDtyPHQ7cisrKXtjb25zdCBpPWUuYXQoci0xKSxzPWUuYXQoKHIrMSkldCksbz14dChbaSxlW3JdXSxzKTtpZihvIT09MCl7aWYobipvPDApcmV0dXJuITE7bj1vfX1yZXR1cm4hMH1mdW5jdGlvbiBVaChlKXtjb25zdCB0PWUubGVuZ3RoO2lmKHQ8NClyZXR1cm4tMTtsZXQgbj0wO2ZvcihsZXQgcj0wO3I8dDtyKyspe2NvbnN0IGk9ZS5hdChyLTEpLHM9ZS5hdCgocisxKSV0KSxvPXh0KFtpLGVbcl1dLHMpO2lmKG8hPT0wKXtpZihuKm88MClyZXR1cm4gcjtuPW99fXJldHVybi0xfWZ1bmN0aW9uIE10KGUsdCl7bGV0IG49MCxyPSExO2ZvcihsZXQgaT0wO2k8ZS5sZW5ndGg7aSsrKXtjb25zdCBzPWUuYXQoaS0xKTtpZigkZShzLHQpKXJldHVybiB5LlRhbmdlbmN5O2NvbnN0IG89eHQoW3MsZVtpXV0sdCk7aWYobz09PTApe3I9ITA7Y29udGludWV9aWYobipvPDApcmV0dXJuIHkuRGlzc29jaWF0aW9uO249b31yZXR1cm4gcj95LlRhbmdlbmN5OnkuQ29udGFpbn1mdW5jdGlvbiBEaChlLHQpe2NvbnN0IG49ZS5sZW5ndGg7bGV0IHI9W107Y29uc3QgaT1bXTtmb3IobGV0IHM9MDtzPG47cysrKXtjb25zdCBvPXMtMSxjPWUuYXQobyk7aWYoJGUoYyx0KSl7aS5wdXNoKG8pO2JyZWFrfWNvbnN0IGw9by0xLGg9eHQoW3QsY10sZS5hdChsKSksZj14dChbdCxjXSxlLmF0KHMpKSx1PWgqZjtpZighKHU8MCkpe2lmKHU+MCl7aWYoaS5wdXNoKG8pLGkubGVuZ3RoPT09MilicmVhaztjb250aW51ZX1oPT09MCYmci5wdXNoKGwsbyksZj09PTAmJnIucHVzaChvLHMpfX1yZXR1cm4gaS5wdXNoKC4uLnIpLGkubWFwKHM9PnM8MD9zK246cyl9ZnVuY3Rpb24gZnQoZSx0KXtjb25zdCBuPVt0LFsxMCwwXV07cXIoblsxXSx0LG5bMV0pO2NvbnN0IHI9ZS5sZW5ndGg7bGV0IGk9MDtmb3IobGV0IHM9MDtzPHI7cysrKXtjb25zdCBvPWVbc107aWYoJGUobyx0KSlyZXR1cm4geS5UYW5nZW5jeTtsZXQgYz1zKzE7Yz09PXImJihjPTApO2NvbnN0IGw9ZVtjXSxoPVtvLGxdO2lmKHlzKGgsdCk9PT15LkNvbnRhaW4pcmV0dXJuIHkuVGFuZ2VuY3k7Y29uc3QgdT14cyhuLGgpO2lmKHU9PT15LkNvbnRhaW4pe2krPTI7Y29udGludWV9aWYodT09PXkuSW50ZXJzZWN0KXtsZXQgZD0wO29bMV0+dFsxXSYmZCsrLGxbMV0+dFsxXSYmZCsrLGQ9PT0xJiZpKyt9fXJldHVybiBpJTI9PT0wP3kuRGlzc29jaWF0aW9uOnkuQ29udGFpbn1mdW5jdGlvbiBRbihlLHQpe2NvbnN0IG49ZS5sZW5ndGg7bGV0IHI9MDtmb3IobGV0IGM9MDtjPG47YysrKXtjb25zdCBsPWVbY107bGV0IGg9YysxO2g9PT1uJiYoaD0wKTtjb25zdCBmPWVbaF0sZD1qbihbbCxmXSx0KTtpZihkJih5LlRocm91Z2hJbnRlcnNlY3R8eS5UYW5nZW5jeXx5LkNvbnRhaW4pKXJldHVybiBkO2Q9PT15LkpvaW50SW50ZXJzZWN0JiZyKyt9Y29uc3QgaT1NdChlLHRbMF0pO2lmKHI9PT0wfHxyPT09MSYmaSE9PXkuVGFuZ2VuY3kpcmV0dXJuIGk7Y29uc3Qgcz1NdChlLHRbMV0pLG89aXxzO3JldHVybiBvPT09eS5UYW5nZW5jeT95LkNvbnRhaW46byZ5LlRhbmdlbmN5P28meS5Db250YWluP3kuQ29udGFpbjp5LkpvaW50SW50ZXJzZWN0Oml9ZnVuY3Rpb24gVHMoZSx0KXtjb25zdCBuPWUubGVuZ3RoO2xldCByPTAsaT0hMTtmb3IobGV0IGw9MDtsPG47bCsrKXtjb25zdCBoPWVbbF07bGV0IGY9bCsxO2Y9PT1uJiYoZj0wKTtjb25zdCB1PWVbZl0sZz1qbihbaCx1XSx0KTtpZihnPT09eS5UaHJvdWdoSW50ZXJzZWN0KXJldHVybiBnO2c9PT15LkpvaW50SW50ZXJzZWN0P3IrKzpnPT09eS5Db250YWluJiYoaT0hMCl9Y29uc3Qgcz1mdChlLHRbMF0pLG89ZnQoZSx0WzFdKSxjPXN8bztpZihpKXJldHVybiBjJnkuQ29udGFpbj95LlRocm91Z2hJbnRlcnNlY3Q6eS5UYW5nZW5jeTtpZihyPT09MSlyZXR1cm4gYyZ5LkNvbnRhaW4/eS5Db250YWluOnkuSm9pbnRJbnRlcnNlY3Q7aWYocj4yKXtjb25zdCBsPUdyKFtdLHRbMF0sdFsxXSwuNSk7cmV0dXJuIGZ0KGUsbCk9PT15LkNvbnRhaW4/eS5Db250YWluOnkuSm9pbnRJbnRlcnNlY3R9cmV0dXJuIHN9ZnVuY3Rpb24gQmgoZSx0KXtjb25zdCBuPWUubGVuZ3RoO2xldCByPTAsaT0wO2ZvcihsZXQgbD0wO2w8bjtsKyspe2NvbnN0IGg9ZVtsXTtsZXQgZj1sKzE7Zj09PW4mJihmPTApO2NvbnN0IHU9ZVtmXSxnPXBzKFtoLHVdLHQpO2lmKGc9PT15LkludGVyc2VjdClyZXR1cm4geS5JbnRlcnNlY3Q7Zz09PXkuQ29udGFpbj9yKys6Zz09PXkuVGFuZ2VuY3kmJmkrK31pZihyPT09bilyZXR1cm4geS5CQUNvbnRhaW47aWYocj4wKXJldHVybiB5LkludGVyc2VjdDtjb25zdHtjZW50ZXI6cyxyYWRpdXM6b309dDtsZXQgYz1mdChlLHMpO3JldHVybiBjPT09eS5Db250YWluP3kuQUJDb250YWluOm89PT0wP2M6aT4wP3kuVGFuZ2VuY3k6eS5EaXNzb2NpYXRpb259ZnVuY3Rpb24gWWgoZSx0KXtjb25zdCBuPWUubGVuZ3RoO2xldCByPVtdO2ZvcihsZXQgaT0wO2k8bjtpKyspe2NvbnN0IHM9ZVtpXTtsZXQgbz1pKzE7bz09PW4mJihvPTApO2NvbnN0IGM9ZVtvXSxoPV9zKFtzLGNdLHQpO3I9Wy4uLnIsLi4uaF19cmV0dXJuIHJ9ZnVuY3Rpb24gRXMoZSx0KXtjb25zdCBuPWUubGVuZ3RoO2xldCByPTAsaT0hMTtmb3IobGV0IGw9MDtsPG47bCsrKXtjb25zdCBoPWVbbF07bGV0IGY9bCsxO2Y9PT1uJiYoZj0wKTtjb25zdCB1PWVbZl0sZz1Rbih0LFtoLHVdKTtpZihnPT09eS5UaHJvdWdoSW50ZXJzZWN0KXJldHVybiBnO2c9PT15LkpvaW50SW50ZXJzZWN0P3IrKzpnPT09eS5UYW5nZW5jeSYmKGk9ITApfWxldCBzPTA7aT9zfD15LlRhbmdlbmN5OnImJihzfD15LkpvaW50SW50ZXJzZWN0KTtsZXQgbz1lLnNvbWUobD0+TXQodCxsKT09PXkuQ29udGFpbik7cmV0dXJuIG8/eS5CQUNvbnRhaW58czoobz10LnNvbWUobD0+ZnQoZSxsKT09PXkuQ29udGFpbiksbz95LkFCQ29udGFpbnxzOmUuc29tZShsPT5NdCh0LGwpPT09eS5EaXNzb2NpYXRpb24pP3kuRGlzc29jaWF0aW9ufHM6cyl9ZnVuY3Rpb24gT3MoZSx0KXtjb25zdCBuPWUubGVuZ3RoO2xldCByPTAsaT0hMTtmb3IobGV0IGw9MDtsPG47bCsrKXtjb25zdCBoPWVbbF07bGV0IGY9bCsxO2Y9PT1uJiYoZj0wKTtjb25zdCB1PWVbZl0sZz1Rbih0LFtoLHVdKTtpZihnPT09eS5UaHJvdWdoSW50ZXJzZWN0KXJldHVybiBnO2c9PT15LkpvaW50SW50ZXJzZWN0P3IrKzpnPT09eS5UYW5nZW5jeSYmKGk9ITApfWxldCBzPTA7aT9zfD15LlRhbmdlbmN5OnImJihzfD15LkpvaW50SW50ZXJzZWN0KTtsZXQgbz1lLnNvbWUobD0+TXQodCxsKT09PXkuQ29udGFpbik7cmV0dXJuIG8/eS5CQUNvbnRhaW58czoobz10LnNvbWUobD0+TXQoZSxsKT09PXkuQ29udGFpbiksbz95LkFCQ29udGFpbnxzOmUuc29tZShsPT5NdCh0LGwpPT09eS5EaXNzb2NpYXRpb24pP3kuRGlzc29jaWF0aW9ufHM6cyl9ZnVuY3Rpb24gV2goZSx0KXtjb25zdCBuPWUubGVuZ3RoO2xldCByPTAsaT0hMTtmb3IobGV0IGw9MDtsPG47bCsrKXtjb25zdCBoPWVbbF07bGV0IGY9bCsxO2Y9PT1uJiYoZj0wKTtjb25zdCB1PWVbZl0sZz1Ucyh0LFtoLHVdKTtpZihnPT09eS5UaHJvdWdoSW50ZXJzZWN0KXJldHVybiBnO2c9PT15LkpvaW50SW50ZXJzZWN0P3IrKzpnPT09eS5UYW5nZW5jeSYmKGk9ITApfWxldCBzPTA7aT9zfD15LlRhbmdlbmN5OnImJihzfD15LkpvaW50SW50ZXJzZWN0KTtsZXQgbz1lLnNvbWUobD0+ZnQodCxsKT09PXkuQ29udGFpbik7cmV0dXJuIG8/eS5CQUNvbnRhaW58czoobz10LnNvbWUobD0+ZnQoZSxsKT09PXkuQ29udGFpbiksbz95LkFCQ29udGFpbnxzOmUuc29tZShsPT5mdCh0LGwpPT09eS5EaXNzb2NpYXRpb24pP3kuRGlzc29jaWF0aW9ufHM6cyl9ZnVuY3Rpb24gWmgoZSx0LG4pe2ZvcihsZXQgcj0wO3I8bi5sZW5ndGg7cisrKXtjb25zdCBpPW5bcl07ZT1LbihlLHQscixpKSxlPUtuKGUsdCxyLC1pKX1yZXR1cm4gZX1mdW5jdGlvbiBLbihlLHQsbixyLGkpe2NvbnN0IHM9ZS5sZW5ndGg7aWYoIWkpe2k9W107Zm9yKGxldCBsPTA7bDxzO2wrKylpW2xdPVtdfWNvbnN0IG89ZVswXS5sZW5ndGgvdCxjPWUubWFwKGw9PmwubGVuZ3RoL298MCk7Zm9yKGxldCBsPTA7bDxvO2wrPTMpe2NvbnN0IGg9W10sZj1bXSx1PVtdO2ZvcihsZXQgdz0wO3c8czt3Kyspe2NvbnN0IFM9ZVt3XSxiPWNbd107bGV0IEk9bCpiLEU9SStiO2hbd109Uy5zbGljZShJLEUpLEk9RSxFKz1iLGZbd109Uy5zbGljZShJLEUpLEk9RSxFKz1iLHVbd109Uy5zbGljZShJLEUpfWNvbnN0IGQ9aFswXVtuXS1yLGc9ZlswXVtuXS1yLG09dVswXVtuXS1yO2xldCBfPWQ+MCxwPWc+MCxNPW0+MDtyPDAmJihfPSFfLHA9IXAsTT0hTSk7bGV0IEEseCxULE87c3dpdGNoKF8rcCtNKXtjYXNlIDA6e2ZvcihsZXQgdz0wO3c8czt3KyspaVt3XS5wdXNoKC4uLmhbd10sLi4uZlt3XSwuLi51W3ddKTticmVha31jYXNlIDE6e18/KEE9Zix4PXUsVD1ldCh1LGgsbixyKSxPPWV0KGYsaCxuLHIpKTpwPyhBPXUseD1oLFQ9ZXQoaCxmLG4sciksTz1ldCh1LGYsbixyKSk6KEE9aCx4PWYsVD1ldChmLHUsbixyKSxPPWV0KGgsdSxuLHIpKTtmb3IobGV0IHc9MDt3PHM7dysrKWlbd10ucHVzaCguLi5BW3ddLC4uLnhbd10sLi4uVFt3XSksaVt3XS5wdXNoKC4uLlRbd10sLi4uT1t3XSwuLi5BW3ddKTticmVha31jYXNlIDI6e18/cD8oQT11LHg9ZXQoaCx1LG4sciksVD1ldChmLHUsbixyKSk6KEE9Zix4PWV0KHUsZixuLHIpLFQ9ZXQoaCxmLG4scikpOihBPWgseD1ldChmLGgsbixyKSxUPWV0KHUsaCxuLHIpKTtmb3IobGV0IHc9MDt3PHM7dysrKWlbd10ucHVzaCguLi5BW3ddLC4uLnhbd10sLi4uVFt3XSk7YnJlYWt9fX1yZXR1cm4gaX1mdW5jdGlvbiBldChlLHQsbixyLGk9W10pe2NvbnN0IHM9ZVswXSxvPXRbMF0sYz1zW25dLGw9TWF0aC5hYnMoKHItYykvKG9bbl0tYykpO2ZvcihsZXQgaD0wO2g8ZS5sZW5ndGg7aCsrKXtjb25zdCBmPWVbaF0sdT10W2hdLGQ9aVtoXXx8KGlbaF09W10pO2ZvcihsZXQgZz0wO2c8Zi5sZW5ndGg7ZysrKWRbZ109bCoodVtnXS1mW2ddKStmW2ddfXJldHVybiBpfWZ1bmN0aW9uIEdoKGUsdCl7Y29uc3Qgbj1lLmxlbmd0aC90fDA7Zm9yKGxldCByPTA7cjx0O3IrKyl7Y29uc3QgaT1yKm4scz1lLnNsaWNlKGksaStuKTtsZXQgbz1NYXRoLmh5cG90KC4uLnMpO289ayhvLDApPzE6MS9vO2ZvcihsZXQgYz0wO2M8bjtjKyspZVtpK2NdKj1vfXJldHVybiBlfWZ1bmN0aW9uIHZzKGUsdCxuPVsicG9zaXRpb24iXSl7cmV0dXJuIGUubWFwRm9yQWdncmVnYXRlKG4scj0+ZnQodCxyKSl9ZnVuY3Rpb24gYnMoZSx0LG49WyJwb3NpdGlvbiJdKXtyZXR1cm4gZS5tYXBGb3JBZ2dyZWdhdGUobixyPT5NdCh0LHIpKX1mdW5jdGlvbiBYaChlLHQpe3JldHVybiBlLmluZGljZXMubWFwKG49PntsZXQgcj0wO2Zvcihjb25zdCBpIG9mIG4pcnw9dFtpXTtyZXR1cm4gcn0pfWZ1bmN0aW9uIElzKGUsdCxuPVsicG9zaXRpb24iXSxyLGkpe2NvbnN0IHM9aT9PczpFcztyZXR1cm4gcj9yLm1hcChmdW5jdGlvbihvLGMpe2NvbnN0IGw9THMobyk7aWYobCE9PW51bGwpcmV0dXJuIGwmeS5Db250YWluP2x8eS5BQjpsO2NvbnN0IGg9ZS5pbmRpY2VzLmdldFZlY3RvcihjKSxmPUFycmF5LnByb3RvdHlwZS5tYXAuY2FsbChoLHU9PmUuZ2V0QWdncmVnYXRlVmVjdG9yKG4sdSkpO3JldHVybiBzKHQsZil9KTplLm1hcEZhY2UobixvPT5zKHQsbykpfWNvbnN0IFNzPXkuRGlzc29jaWF0aW9ufHkuQ29udGFpbjtmdW5jdGlvbiBMcyhlKXtyZXR1cm4oZSZTcyk9PT1Tcz95LlRocm91Z2hJbnRlcnNlY3Q6ZSZ5LkNvbnRhaW4/ZSZ5LlRhbmdlbmN5P3kuQ29udGFpbnx5LkpvaW50SW50ZXJzZWN0OnkuQ29udGFpbjpudWxsfWZ1bmN0aW9uIFBzKGUsdCxuKXtjb25zdCByPXNlLmdldEVxdWFsRnVuKG4pLGk9W107cmV0dXJuIGUuZm9yRWFjaCgocyxvKT0+e3IodCxzKSYmaS5wdXNoKG8pfSksaX1jb25zdCBKbj0xLzMyNzY3O2Z1bmN0aW9uIEhuKGUsdCl7Y29uc3RbbixyLGldPXRyKGUsdCk7cmV0dXJuW24sMCwwLDAsMCxyLDAsMCwwLDAsaSwwLGUud2VzdCxlLnNvdXRoLHRbMF0sMV19ZnVuY3Rpb24gdHIoZSx0KXtjb25zdCBuPShlLmVhc3QtZS53ZXN0KSpKbixyPShlLm5vcnRoLWUuc291dGgpKkpuLGk9KHRbMV0tdFsxXSkqSm47cmV0dXJuW24scixpXX1mdW5jdGlvbiBqaChlLHQpe2NvbnN0IG49dHIoZSx0KSx7d2VzdDpyLHNvdXRoOml9PWUsW3NdPXQ7cmV0dXJuIGZ1bmN0aW9uKGMsbD1bXSl7SW4obCxjLG4pLEhyKGwsbCxbcixpLHNdKX19Y2xhc3Mgbm57Y29uc3RydWN0b3IodCl7cSh0aGlzLCJhcnJheSIpO3EodGhpcywiY291bnQiLDApO3EodGhpcywidmVjdG9yU2l6ZSIpO3EodGhpcywic3RhcnQiLDApO3QmJnRoaXMuc2V0T3B0aW9ucyh0KX1nZXQgZW5kKCl7cmV0dXJuIHRoaXMuc3RhcnQrdGhpcy5jb3VudCp0aGlzLnZlY3RvclNpemV9c2V0IGVuZCh0KXt0aGlzLmNvdW50PU1hdGgudHJ1bmMoKHQtdGhpcy5zdGFydCkvdGhpcy52ZWN0b3JTaXplKX1zZXRPcHRpb25zKHQpe2NvbnN0e2VuZDpuLGNvdW50OnIsLi4uaX09dDtPYmplY3QuYXNzaWduKHRoaXMsaSksbj09bnVsbCYmcj09bnVsbD90aGlzLmNvdW50PXRoaXMuYXJyYXkubGVuZ3RoL3RoaXMudmVjdG9yU2l6ZTpuIT1udWxsJiYodGhpcy5lbmQ9bil9ZnJvbSh0KXtjb25zdHthcnJheTpuLC4uLnJ9PXQ7cmV0dXJuIHRoaXMuc2V0T3B0aW9ucyh7YXJyYXk6bi5zbGljZSgpLC4uLnJ9KSx0aGlzfWNsb25lKCl7Y29uc3QgdD1uZXcgdGhpcy5jb25zdHJ1Y3RvcjtyZXR1cm4gdC5mcm9tKHRoaXMpLHR9Y29weSh0KXtmb3IobGV0IG49MDtuPHRoaXMuY291bnQ7bisrKXRoaXMuY29weUF0KG4sdCxuKTtyZXR1cm4gdGhpc31jb3B5QXQodCxuLHIpe2NvbnN0IGk9bi5nZXRWZWN0b3Iocik7cmV0dXJuIHRoaXMuc2V0VmVjdG9yKHQsaSksdGhpc31jb3B5QXJyYXkodCl7Y29uc3Qgbj10aGlzLnN0YXJ0O2ZvcihsZXQgcj0wLGk9dC5sZW5ndGg7cjxpO3IrKyl0aGlzLmFycmF5W24rcl09dFtyXTtyZXR1cm4gdGhpc31nZXRTdGFydEFycmF5SW5kZXgodCl7cmV0dXJuIHRoaXMuc3RhcnQrdCp0aGlzLnZlY3RvclNpemV9Z2V0QXJyYXlJbmRleFJhbmdlKHQpe2NvbnN0IG49dGhpcy5zdGFydCt0KnRoaXMudmVjdG9yU2l6ZTtyZXR1cm5bbixuK3RoaXMudmVjdG9yU2l6ZV19Z2V0VmVjdG9yKHQpe3JldHVybiB0aGlzLmFycmF5LnNsaWNlKC4uLnRoaXMuZ2V0QXJyYXlJbmRleFJhbmdlKHQpKX1zZXRWZWN0b3IodCxuLHI9MCl7Y29uc3QgaT10aGlzLmdldFN0YXJ0QXJyYXlJbmRleCh0KTtmb3IobGV0IHM9MCxvPXRoaXMudmVjdG9yU2l6ZTtzPG87cysrKXRoaXMuYXJyYXlbaStzXT1uW3Irc107cmV0dXJuIHIrdGhpcy52ZWN0b3JTaXplfW1hcCh0LG49W10pe2ZvcihsZXQgcj0wO3I8dGhpcy5jb3VudDtyKyspe2NvbnN0IGk9dGhpcy5nZXRWZWN0b3Iocik7bltyXT10KGkscil9cmV0dXJuIG59bWFwU2VsZih0KXtmb3IobGV0IG49MDtuPHRoaXMuY291bnQ7bisrKXtjb25zdCByPXRoaXMuZ2V0VmVjdG9yKG4pLGk9dChyLG4pO3RoaXMuc2V0VmVjdG9yKG4saSl9cmV0dXJuIHRoaXN9ZmlsdGVyKHQsbj1bXSl7Zm9yKGxldCByPTA7cjx0aGlzLmNvdW50O3IrKyl7Y29uc3QgaT10aGlzLmdldFZlY3RvcihyKTtpZih0KGkscikpZm9yKGNvbnN0IHMgb2YgaSluW24ubGVuZ3RoXT1zfXJldHVybiBufXRyYW5zZm9ybSh0KXtjb25zdCBuPWhlKHQubGVuZ3RoLHRoaXMudmVjdG9yU2l6ZSk7cmV0dXJuIHRoaXMubWFwU2VsZihyPT5uKHIscix0KSl9dHJhbnNmb3JtQXNOb3JtYWwodCl7Y29uc3Qgbj1ablswXTt0Lmxlbmd0aD09PTE2P3puKG4sdCk6WW4obix0KTtjb25zdCByPWhlKG4ubGVuZ3RoLHRoaXMudmVjdG9yU2l6ZSk7cmV0dXJuIHRoaXMubWFwU2VsZihpPT5yKGksaSxuKSl9c2NhbGUodCl7Y29uc3Qgbj1ZKHRoaXMudmVjdG9yU2l6ZSk7cmV0dXJuIHRoaXMubWFwU2VsZihyPT5uLnNjYWxlKHIscix0KSl9c2NhbGVBbmRBZGQodCxuKXtjb25zdCByPVkodGhpcy52ZWN0b3JTaXplKTtyZXR1cm4gdGhpcy5tYXBTZWxmKGk9PnIuc2NhbGVBbmRBZGQoaSxpLHQsbikpfWFkZCh0KXtjb25zdCBuPVkodGhpcy52ZWN0b3JTaXplKTtyZXR1cm4gdGhpcy5tYXBTZWxmKHI9Pm4uYWRkKHIscix0KSl9c3VidHJhY3QodCl7Y29uc3Qgbj1ZKHRoaXMudmVjdG9yU2l6ZSk7cmV0dXJuIHRoaXMubWFwU2VsZihyPT5uLnN1YnRyYWN0KHIscix0KSl9bXVsdGlwbHkodCl7Y29uc3Qgbj1ZKHRoaXMudmVjdG9yU2l6ZSk7cmV0dXJuIHRoaXMubWFwU2VsZihyPT5uLm11bHRpcGx5KHIscix0KSl9ZGl2aWRlKHQpe2NvbnN0IG49WSh0aGlzLnZlY3RvclNpemUpO3JldHVybiB0aGlzLm1hcFNlbGYocj0+bi5kaXZpZGUocixyLHQpKX19ZnVuY3Rpb24gUWgoZSx0KXtjb25zdHt2ZWN0b3JTaXplOm4sc3RhcnQ6cj0wLGFycmF5Oml9PWUscz1oZSh0Lmxlbmd0aCxuKSxvPWUuZW5kPz9pLmxlbmd0aDtmb3IobGV0IGM9cjtjPG87Yys9bil7Y29uc3QgbD1pLnNsaWNlKGMsYytuKTtzKGwsbCx0KTtmb3IobGV0IGg9MDtoPG47aCsrKWlbYytoXT1sW2hdfXJldHVybiBlfWZ1bmN0aW9uIEtoKGUsdCl7Y29uc3R7dmVjdG9yU2l6ZTpuLHN0YXJ0OnI9MCxhcnJheTppfT1lLHM9WShuKSxvPWUuZW5kPz9pLmxlbmd0aDtmb3IobGV0IGM9cjtjPG87Yys9bil7Y29uc3QgbD1pLnNsaWNlKGMsYytuKTtzLnNjYWxlKGwsbCx0KTtmb3IobGV0IGg9MDtoPG47aCsrKWlbYytoXT1sW2hdfXJldHVybiBlfWZ1bmN0aW9uIEpoKGUsdCxuKXtjb25zdHt2ZWN0b3JTaXplOnIsc3RhcnQ6aT0wLGFycmF5OnN9PWUsbz1ZKHIpLGM9ZS5lbmQ/P3MubGVuZ3RoO2ZvcihsZXQgbD1pO2w8YztsKz1yKXtjb25zdCBoPXMuc2xpY2UobCxsK3IpO28uc2NhbGVBbmRBZGQoaCxoLHQsbik7Zm9yKGxldCBmPTA7ZjxyO2YrKylzW2wrZl09aFtmXX1yZXR1cm4gZX1mdW5jdGlvbiBIaChlLHQpe2NvbnN0e3ZlY3RvclNpemU6bixzdGFydDpyPTAsYXJyYXk6aX09ZSxzPVkobiksbz1lLmVuZD8/aS5sZW5ndGg7Zm9yKGxldCBjPXI7YzxvO2MrPW4pe2NvbnN0IGw9aS5zbGljZShjLGMrbik7cy5hZGQobCxsLHQpO2ZvcihsZXQgaD0wO2g8bjtoKyspaVtjK2hdPWxbaF19cmV0dXJuIGV9ZnVuY3Rpb24gdGYoZSx0KXtjb25zdHt2ZWN0b3JTaXplOm4sc3RhcnQ6cj0wLGFycmF5Oml9PWUscz1ZKG4pLG89ZS5lbmQ/P2kubGVuZ3RoO2ZvcihsZXQgYz1yO2M8bztjKz1uKXtjb25zdCBsPWkuc2xpY2UoYyxjK24pO3Muc3VidHJhY3QobCxsLHQpO2ZvcihsZXQgaD0wO2g8bjtoKyspaVtjK2hdPWxbaF19cmV0dXJuIGV9ZnVuY3Rpb24gZWYoZSx0KXtjb25zdHt2ZWN0b3JTaXplOm4sc3RhcnQ6cj0wLGFycmF5Oml9PWUscz1ZKG4pLG89ZS5lbmQ/P2kubGVuZ3RoO2ZvcihsZXQgYz1yO2M8bztjKz1uKXtjb25zdCBsPWkuc2xpY2UoYyxjK24pO3MubXVsdGlwbHkobCxsLHQpO2ZvcihsZXQgaD0wO2g8bjtoKyspaVtjK2hdPWxbaF19cmV0dXJuIGV9ZnVuY3Rpb24gbmYoZSx0KXtjb25zdHt2ZWN0b3JTaXplOm4sc3RhcnQ6cj0wLGFycmF5Oml9PWUscz1ZKG4pLG89ZS5lbmQ/P2kubGVuZ3RoO2ZvcihsZXQgYz1yO2M8bztjKz1uKXtjb25zdCBsPWkuc2xpY2UoYyxjK24pO3MuZGl2aWRlKGwsbCx0KTtmb3IobGV0IGg9MDtoPG47aCsrKWlbYytoXT1sW2hdfXJldHVybiBlfWZ1bmN0aW9uIHJmKGUsdCxuLHI9W10pe2NvbnN0IGk9TWF0aC5jZWlsKGUubGVuZ3RoL3QpO2xldCBzPTA7Zm9yKGxldCBvPTA7bzxpO28rKyl7cz1vKnQ7Y29uc3QgYz1lLnNsaWNlKHMscyt0KTtyW29dPW4oYyl9cmV0dXJuIHJ9ZnVuY3Rpb24gc2YoZSx0LG4scj1bXSl7Y29uc3QgaT1NYXRoLmNlaWwoZS5sZW5ndGgvdCk7bGV0IHM9MDtmb3IobGV0IG89MDtvPGk7bysrKXtzPW8qdDtjb25zdCBjPWUuc2xpY2UocyxzK3QpO24oYykmJnIucHVzaCguLi5jKX1yZXR1cm4gcn1mdW5jdGlvbiBScyhlKXtyZXR1cm4gZS5mbGF0TWFwKHQ9PlsuLi50XSl9dmFyIENzPShlPT4oZS5wb3NpdGlvbj0icG9zaXRpb24iLGUubm9ybWFsPSJub3JtYWwiLGUuYmlub3JtYWw9ImJpbm9ybWFsIixlLnRhbmdlbnQ9InRhbmdlbnQiLGUudXY9InV2IixlLmNvbG9yPSJjb2xvciIsZS5oZWlnaHQ9ImhlaWdodCIsZSkpKENzfHx7fSk7Y2xhc3MgVnN7Y29uc3RydWN0b3IodCl7cSh0aGlzLCJhcnJheSIpO3EodGhpcywiYXR0cmlidXRlcyIpO3EodGhpcywiY291bnQiKTt0JiZ0aGlzLnNldE9wdGlvbnModCl9c2V0T3B0aW9ucyh0KXtjb25zdHthdHRyaWJ1dGVzOm4sYXJyYXk6cixjb3VudDppLC4uLnN9PXQ7T2JqZWN0LmFzc2lnbih0aGlzLHMse2FycmF5OnIsY291bnQ6aX0pO2NvbnN0IG89dGhpcy5hdHRyaWJ1dGVzPXt9O2Zvcihjb25zdFtjLGxdb2YgT2JqZWN0LmVudHJpZXMobikpb1tjXT1uZXcgbm4oe2FycmF5OnIsY291bnQ6aSwuLi5sfSk7cmV0dXJuIHRoaXN9c2V0VmVjdG9yKHQsbixyLGkpe3JldHVybiB0aGlzLmF0dHJpYnV0ZXNbdF0uc2V0VmVjdG9yKG4scixpKX1nZXRWZWN0b3IodCxuKXtyZXR1cm4gdGhpcy5hdHRyaWJ1dGVzW3RdLmdldFZlY3RvcihuKX1nZXRWZWN0b3JzKHQsbil7cmV0dXJuIHQubWFwKHI9PnRoaXMuYXR0cmlidXRlc1tyXS5nZXRWZWN0b3IobikpfWdldEF0dHJpYnV0ZSh0KXtyZXR1cm4gdGhpcy5hdHRyaWJ1dGVzW3RdfXNldEF0dHJpYnV0ZSh0LG4pe2NvbnN0e2FycmF5OnIsY291bnQ6aX09dGhpcztyZXR1cm4gdGhpcy5hdHRyaWJ1dGVzW3RdPW5ldyBubih7YXJyYXk6ciwuLi5uLGNvdW50Oml9KX1nZXRBZ2dyZWdhdGVWZWN0b3IodCxuKXtjb25zdCByPVtdO2Zvcihjb25zdCBpIG9mIHQpe2NvbnN0IHM9dGhpcy5nZXRWZWN0b3IoaSxuKTtyLnB1c2goLi4ucyl9cmV0dXJuIHJ9c2V0QWdncmVnYXRlVmVjdG9yKHQsbixyLGkpe2lmKHQubGVuZ3RoPT09MSlyZXR1cm4gdGhpcy5zZXRWZWN0b3IodFswXSxuLHIsaSk7Zm9yKGNvbnN0IHMgb2YgdClpPXRoaXMuc2V0VmVjdG9yKHMsbixyLGkpO3JldHVybiBpfWdldEFnZ3JlZ2F0ZVZlY3RvclNpemUodCl7aWYodC5sZW5ndGg9PT0xKXJldHVybiB0aGlzLmdldEF0dHJpYnV0ZSh0WzBdKS52ZWN0b3JTaXplO2xldCBuPTA7Zm9yKGNvbnN0IHIgb2YgdCluKz10aGlzLmdldEF0dHJpYnV0ZShyKS52ZWN0b3JTaXplO3JldHVybiBufWNyZWF0ZUFnZ3JlZ2F0ZVZlY3RvckdldHRlcih0KXtpZih0Lmxlbmd0aD09PTEpe2NvbnN0IG49dGhpcy5hdHRyaWJ1dGVzW3RbMF1dO3JldHVybiBuLmdldFZlY3Rvci5iaW5kKG4pfXJldHVybiB0aGlzLmdldEFnZ3JlZ2F0ZVZlY3Rvci5iaW5kKHRoaXMsdCl9Y3JlYXRlQWdncmVnYXRlVmVjdG9yU2V0dGVyKHQpe2lmKHQubGVuZ3RoPT09MSl7Y29uc3Qgbj10aGlzLmF0dHJpYnV0ZXNbdFswXV07cmV0dXJuIG4uc2V0VmVjdG9yLmJpbmQobil9cmV0dXJuIHRoaXMuc2V0QWdncmVnYXRlVmVjdG9yLmJpbmQodGhpcyx0KX1tYXAodCxuLHI9W10pe2ZvcihsZXQgaT0wO2k8dGhpcy5jb3VudDtpKyspe2NvbnN0IHM9dGhpcy5nZXRWZWN0b3JzKHQsaSk7cltpXT1uKHMsaSl9cmV0dXJuIHJ9bWFwRm9yQWdncmVnYXRlKHQsbixyPVtdKXtmb3IobGV0IGk9MDtpPHRoaXMuY291bnQ7aSsrKXtjb25zdCBzPXRoaXMuZ2V0QWdncmVnYXRlVmVjdG9yKHQsaSk7cltpXT1uKHMsaSl9cmV0dXJuIHJ9bWFwU2VsZih0LG4pe2ZvcihsZXQgcj0wO3I8dGhpcy5jb3VudDtyKyspe2NvbnN0IGk9dGhpcy5nZXRWZWN0b3JzKHQscikscz1uKGkscik7dC5mb3JFYWNoKChvLGMpPT50aGlzLnNldFZlY3RvcihvLHIsc1tjXSkpfXJldHVybiB0aGlzfW1hcFNlbGZGb3JBZ2dyZWdhdGUodCxuKXtmb3IobGV0IHI9MDtyPHRoaXMuY291bnQ7cisrKXtjb25zdCBpPXRoaXMuZ2V0QWdncmVnYXRlVmVjdG9yKHQscikscz1uKGkscik7dGhpcy5zZXRBZ2dyZWdhdGVWZWN0b3IodCxyLHMpfXJldHVybiB0aGlzfWZpbHRlcih0LG4scj1bXSl7Zm9yKGxldCBpPTA7aTx0aGlzLmNvdW50O2krKyl7Y29uc3Qgcz10aGlzLmdldFZlY3RvcnModCxpKTtuKHMsaSkmJnIucHVzaChzKX1yZXR1cm4gcn1maWx0ZXJGb3JBZ2dyZWdhdGUodCxuLHI9W10pe3JldHVybiB0aGlzLmZpbHRlcih0LChpLHMpPT5uKFJzKGkpLHMpLHIpfXRyYW5zZm9ybSh0LG4pe2NvbnN0IHI9Wm5bMF07bi5pbmNsdWRlcygibm9ybWFsIikmJih0Lmxlbmd0aD09PTE2P3puKHIsdCk6WW4ocix0KSk7Zm9yKGNvbnN0IGkgb2Ygbil7Y29uc3Qgcz10aGlzLmdldEF0dHJpYnV0ZShpKTtzJiYoaT09PSJub3JtYWwiP3MudHJhbnNmb3JtQXNOb3JtYWwocik6cy50cmFuc2Zvcm0odCkpfXJldHVybiB0aGlzfXRyYW5zZm9ybUZvckFnZ3JlZ2F0ZSh0LG4pe2NvbnN0IHI9dGhpcy5nZXRBZ2dyZWdhdGVWZWN0b3JTaXplKG4pLGk9aGUodC5sZW5ndGgscik7cmV0dXJuIHRoaXMubWFwU2VsZkZvckFnZ3JlZ2F0ZShuLHM9PmkocyxzLHQpKSx0aGlzfX1jbGFzcyBybiBleHRlbmRzIFZze3NldE9wdGlvbnModCl7Y29uc3R7aW5kaWNlczpuLC4uLnJ9PXQ7c3VwZXIuc2V0T3B0aW9ucyhyKTtjb25zdCBpPW4uYXJyYXk/bjp7YXJyYXk6bn07cmV0dXJuIHRoaXMuaW5kaWNlcz1uZXcgbm4oe2NvdW50OmkuYXJyYXkubGVuZ3RoLzMsdmVjdG9yU2l6ZTozLC4uLml9KSx0aGlzfWdldEZhY2VWZWN0b3IodCxuKXtjb25zdCByPXRoaXMuaW5kaWNlcy5nZXRWZWN0b3Iobik7cmV0dXJuIEFycmF5LnByb3RvdHlwZS5tYXAuY2FsbChyLGk9PnRoaXMuZ2V0VmVjdG9yKHQsaSkpfWdldEZhY2VWZWN0b3JzKHQsbil7Y29uc3Qgcj10aGlzLmluZGljZXMuZ2V0VmVjdG9yKG4pO3JldHVybiBBcnJheS5wcm90b3R5cGUubWFwLmNhbGwocixpPT50aGlzLmdldFZlY3RvcnModCxpKSl9Z2V0RmFjZUFnZ3JlZ2F0ZVZlY3Rvcih0LG4pe2NvbnN0IHI9dGhpcy5pbmRpY2VzLmdldFZlY3RvcihuKTtyZXR1cm4gQXJyYXkucHJvdG90eXBlLm1hcC5jYWxsKHIsaT0+dGhpcy5nZXRBZ2dyZWdhdGVWZWN0b3IodCxpKSl9bWFwRmFjZSh0LG4scj1bXSl7cmV0dXJuIHRoaXMuaW5kaWNlcy5tYXAoKGkscyk9Pntjb25zdCBvPUFycmF5LnByb3RvdHlwZS5tYXAuY2FsbChpLGM9PnRoaXMuZ2V0VmVjdG9ycyh0LGMpKTtyZXR1cm4gbihvLHMsaSl9LHIpfW1hcEZhY2VGb3JBZ2dyZWdhdGUodCxuLHI9W10pe3JldHVybiB0aGlzLmluZGljZXMubWFwKChpLHMpPT57Y29uc3Qgbz1BcnJheS5wcm90b3R5cGUubWFwLmNhbGwoaSxjPT50aGlzLmdldEFnZ3JlZ2F0ZVZlY3Rvcih0LGMpKTtyZXR1cm4gbihvLHMsaSl9LHIpfWZpbHRlckZhY2UodCxuLHI9W10pe3JldHVybiB0aGlzLmluZGljZXMuZmlsdGVyKChpLHMpPT57Y29uc3Qgbz1BcnJheS5wcm90b3R5cGUubWFwLmNhbGwoaSxjPT50aGlzLmdldFZlY3RvcnModCxjKSk7cmV0dXJuIG4obyxzLGkpfSxyKX1maWx0ZXJGYWNlRm9yQWdncmVnYXRlKHQsbixyPVtdKXtyZXR1cm4gdGhpcy5pbmRpY2VzLmZpbHRlcigoaSxzKT0+e2NvbnN0IG89QXJyYXkucHJvdG90eXBlLm1hcC5jYWxsKGksYz0+dGhpcy5nZXRBZ2dyZWdhdGVWZWN0b3IodCxjKSk7cmV0dXJuIG4obyxzLGkpfSxyKX19ZnVuY3Rpb24gb2YoZSl7cmV0dXJuIE5zKGUpLzJ9ZnVuY3Rpb24gTnMoZSl7bGV0IHQ9MDtmb3IobGV0IG49MDtuPGUubGVuZ3RoO24rKyl7Y29uc3Qgcj1lLmF0KG4tMSk7dCs9QnQocixlW25dKX1yZXR1cm4gdH1mdW5jdGlvbiBjZihlKXtyZXR1cm4gJHMoZSkvMn1mdW5jdGlvbiAkcyhlKXtjb25zdCB0PWVbMF0sbj1bXTtmb3IobGV0IHM9MTtzPGUubGVuZ3RoO3MrKyl7Y29uc3Qgbz1lW3NdLGM9Ym4oW10sbyx0KTtuLnB1c2goYyl9Y29uc3Qgcj1IKFtdLG5bMV0sblswXSk7bGV0IGk9emUocik7ZWkocixyLDEvaSk7Zm9yKGxldCBzPTI7czxuLmxlbmd0aDtzKyspaSs9V24obltzLTFdLG5bc10scik7cmV0dXJuIGl9ZnVuY3Rpb24gYWYoZSx0LG4pe3JldHVybiB6cyhlLHQsbikvMn1mdW5jdGlvbiB6cyhlLHQsbil7cmV0dXJuIGx0WzBdLnN1YlZlY3RvcnModCxlKSxsdFsyXS5zdWJWZWN0b3JzKG4sZSksQnQobHRbMF0sbHRbMV0pfWZ1bmN0aW9uIGxmKGUsdCxuKXtyZXR1cm4ga3MoZSx0LG4pLzJ9ZnVuY3Rpb24ga3MoZSx0LG4pe3JldHVybiBodFswXS5zdWJWZWN0b3JzKHQsZSksaHRbMl0uc3ViVmVjdG9ycyhuLGUpLEJ0KGx0WzBdLGx0WzFdKX1mdW5jdGlvbiBoZihlLHQsbil7cmV0dXJuIEZzKGUsdCxuKS8yfWZ1bmN0aW9uIEZzKGUsdCxuKXtjb25zdFtyLGldPW50KGUubGVuZ3RoKTtyZXR1cm4gci5zdWJWZWN0b3JzKHQsZSksaS5zdWJWZWN0b3JzKG4sZSksYXMocixpKX1mdW5jdGlvbiBmZihlLHQsbil7cmV0dXJuIGVyKGUsdCxuKS8yfWZ1bmN0aW9uIGVyKGUsdCxuKXtjb25zdFtyLGldPW50KGUubGVuZ3RoKTtyZXR1cm4gci5zdWJWZWN0b3JzKHQsZSksaS5zdWJWZWN0b3JzKG4sZSksc3MocixpKX1mdW5jdGlvbiB1ZihlLHQsbil7cmV0dXJuIHFzKGUsdCxuKS8yfWZ1bmN0aW9uIHFzKGUsdCxuKXtjb25zdFtyLGldPWh0O3JldHVybiByLnN1YlZlY3RvcnModCxlKSxpLnN1YlZlY3RvcnMobixlKSxvcyhyLGkpfWZ1bmN0aW9uIGRmKGUsdCxuKXtyZXR1cm4gbnIoZSx0LG4pLzJ9ZnVuY3Rpb24gbnIoZSx0LG4pe2NvbnN0W3IsaV09bHQ7cmV0dXJuIHIuc3ViVmVjdG9ycyh0LGUpLGkuc3ViVmVjdG9ycyhuLGUpLGNzKHIsaSl9ZnVuY3Rpb24gcnIoZSx0KXtjb25zdCBuPWUubGVuZ3RoLTM7bGV0IHI9MDtmb3IobGV0IGk9MDtpPG47aSs9Myl7Y29uc3RbcyxvLGNdPWUuc2xpY2UoaSxpKzMpLGw9dChzKSxoPXQobyksZj10KGMpO3IrPWVyKGwsaCxmKX1yZXR1cm4gci8yfWZ1bmN0aW9uIGlyKGUsdCxuPVswLDEvMF0pe2NvbnN0IHI9ZS5sZW5ndGgtMyxbaSxzXT1uLG89cy1pO2xldCBjPTA7Y29uc3QgbD0xLzM7Zm9yKGxldCBoPTA7aDxyO2grPTMpe2NvbnN0W2YsdSxkXT1lLnNsaWNlKGgsaCszKSxbZyxtLF9dPXQoZiksW3AsTSxBXT10KHUpLFt4LFQsT109dChkKSx3PW5yKFtnLG1dLFtwLE1dLFt4LFRdKSxTPShfK0ErTykqbC1pO2MrPXcqTWF0aC5taW4oUyxvKX1yZXR1cm4gYy8yfWNvbnN0IFVzPSEwLGdmPSExLHNuPXtDQ1c6LTEsQ1c6MSxOT1RfT1JJRU5UQUJMRTowfSxtZj0yKk1hdGguUEksb249MSxEcz0wLHV0PTIscGY9MyxfZj00LHlmPTEseGY9Mixzcj0wLGdlPTEsWnQ9Mjt2YXIgY249T2JqZWN0LmZyZWV6ZSh7X19wcm90b19fOm51bGwsQk9VTkRBUlk6dXQsQ0NXOlVzLENPTlRBSU5TOnBmLENXOmdmLEVORF9WRVJURVg6WnQsSU5TSURFOm9uLElOVEVSTEFDRTpfZixOT1RfVkVSVEVYOnNyLE9SSUVOVEFUSU9OOnNuLE9VVFNJREU6RHMsT1ZFUkxBUF9PUFBPU0lURTp4ZixPVkVSTEFQX1NBTUU6eWYsUEl4MjptZixTVEFSVF9WRVJURVg6Z2V9KTtsZXQgZHQ9MWUtNjtmdW5jdGlvbiBCcyhlKXtkdD1lfWZ1bmN0aW9uIFlzKCl7cmV0dXJuIGR0fWNvbnN0IE1mPTM7ZnVuY3Rpb24gb3IoZSl7cmV0dXJuIGU8ZHQmJmU+LWR0fWZ1bmN0aW9uIEx0KGUsdCl7cmV0dXJuIGUtdDxkdCYmZS10Pi1kdH1mdW5jdGlvbiBXcyhlLHQpe3JldHVybiBlLXQ+ZHR9ZnVuY3Rpb24gd2YoZSx0KXtyZXR1cm4gZS10Pi1kdH1mdW5jdGlvbiBacyhlLHQpe3JldHVybiBlLXQ8LWR0fWZ1bmN0aW9uIEFmKGUsdCl7cmV0dXJuIGUtdDxkdH12YXIgVGY9T2JqZWN0LmZyZWV6ZSh7X19wcm90b19fOm51bGwsREVDSU1BTFM6TWYsRVE6THQsRVFfMDpvcixHRTp3ZixHVDpXcyxMRTpBZixMVDpacyxnZXRUb2xlcmFuY2U6WXMsc2V0VG9sZXJhbmNlOkJzfSk7bGV0IGE9e1V0aWxzOlRmLEVycm9yczp2b2lkIDAsTWF0cml4OnZvaWQgMCxQbGFuYXJfc2V0OnZvaWQgMCxQb2ludDp2b2lkIDAsVmVjdG9yOnZvaWQgMCxMaW5lOnZvaWQgMCxDaXJjbGU6dm9pZCAwLFNlZ21lbnQ6dm9pZCAwLEFyYzp2b2lkIDAsQm94OnZvaWQgMCxFZGdlOnZvaWQgMCxGYWNlOnZvaWQgMCxSYXk6dm9pZCAwLFJheV9zaG9vdGluZzp2b2lkIDAsTXVsdGlsaW5lOnZvaWQgMCxQb2x5Z29uOnZvaWQgMCxEaXN0YW5jZTp2b2lkIDAsSW52ZXJzaW9uOnZvaWQgMH07Zm9yKGxldCBlIGluIGNuKWFbZV09Y25bZV07T2JqZWN0LmRlZmluZVByb3BlcnR5KGEsIkRQX1RPTCIse2dldDpmdW5jdGlvbigpe3JldHVybiBZcygpfSxzZXQ6ZnVuY3Rpb24oZSl7QnMoZSl9fSk7Y2xhc3MgVXtzdGF0aWMgZ2V0IElMTEVHQUxfUEFSQU1FVEVSUygpe3JldHVybiBuZXcgUmVmZXJlbmNlRXJyb3IoIklsbGVnYWwgUGFyYW1ldGVycyIpfXN0YXRpYyBnZXQgWkVST19ESVZJU0lPTigpe3JldHVybiBuZXcgRXJyb3IoIlplcm8gZGl2aXNpb24iKX1zdGF0aWMgZ2V0IFVOUkVTT0xWRURfQk9VTkRBUllfQ09ORkxJQ1QoKXtyZXR1cm4gbmV3IEVycm9yKCJVbnJlc29sdmVkIGJvdW5kYXJ5IGNvbmZsaWN0IGluIGJvb2xlYW4gb3BlcmF0aW9uIil9c3RhdGljIGdldCBJTkZJTklURV9MT09QKCl7cmV0dXJuIG5ldyBFcnJvcigiSW5maW5pdGUgbG9vcCIpfXN0YXRpYyBnZXQgQ0FOTk9UX0NPTVBMRVRFX0JPT0xFQU5fT1BFUkFUSU9OKCl7cmV0dXJuIG5ldyBFcnJvcigiQ2Fubm90IGNvbXBsZXRlIGJvb2xlYW4gb3BlcmF0aW9uIil9c3RhdGljIGdldCBDQU5OT1RfSU5WT0tFX0FCU1RSQUNUX01FVEhPRCgpe3JldHVybiBuZXcgRXJyb3IoIkFic3RyYWN0IG1ldGhvZCBjYW5ub3QgYmUgaW52b2tlZCIpfXN0YXRpYyBnZXQgT1BFUkFUSU9OX0lTX05PVF9TVVBQT1JURUQoKXtyZXR1cm4gbmV3IEVycm9yKCJPcGVyYXRpb24gaXMgbm90IHN1cHBvcnRlZCIpfXN0YXRpYyBnZXQgVU5TVVBQT1JURURfU0hBUEVfVFlQRSgpe3JldHVybiBuZXcgRXJyb3IoIlVuc3VwcG9ydGVkIHNoYXBlIHR5cGUiKX19YS5FcnJvcnM9VTtjbGFzcyBjcntjb25zdHJ1Y3Rvcih0LG4pe3RoaXMuZmlyc3Q9dCx0aGlzLmxhc3Q9bnx8dGhpcy5maXJzdH1bU3ltYm9sLml0ZXJhdG9yXSgpe2xldCB0O3JldHVybntuZXh0OigpPT4odD10P3QubmV4dDp0aGlzLmZpcnN0LHt2YWx1ZTp0LGRvbmU6dD09PXZvaWQgMH0pfX1nZXQgc2l6ZSgpe2xldCB0PTA7Zm9yKGxldCBuIG9mIHRoaXMpdCsrO3JldHVybiB0fXRvQXJyYXkodD12b2lkIDAsbj12b2lkIDApe2xldCByPVtdLGk9dHx8dGhpcy5maXJzdCxzPW58fHRoaXMubGFzdCxvPWk7aWYobz09PXZvaWQgMClyZXR1cm4gcjtkbyByLnB1c2gobyksbz1vLm5leHQ7d2hpbGUobyE9PXMubmV4dCk7cmV0dXJuIHJ9YXBwZW5kKHQpe3JldHVybiB0aGlzLmlzRW1wdHkoKT90aGlzLmZpcnN0PXQ6KHQucHJldj10aGlzLmxhc3QsdGhpcy5sYXN0Lm5leHQ9dCksdGhpcy5sYXN0PXQsdGhpcy5sYXN0Lm5leHQ9dm9pZCAwLHRoaXMuZmlyc3QucHJldj12b2lkIDAsdGhpc31pbnNlcnQodCxuKXtpZih0aGlzLmlzRW1wdHkoKSl0aGlzLmZpcnN0PXQsdGhpcy5sYXN0PXQ7ZWxzZSBpZihuPT1udWxsKXQubmV4dD10aGlzLmZpcnN0LHRoaXMuZmlyc3QucHJldj10LHRoaXMuZmlyc3Q9dDtlbHNle2xldCByPW4ubmV4dDtuLm5leHQ9dCxyJiYoci5wcmV2PXQpLHQucHJldj1uLHQubmV4dD1yLHRoaXMubGFzdD09PW4mJih0aGlzLmxhc3Q9dCl9cmV0dXJuIHRoaXMubGFzdC5uZXh0PXZvaWQgMCx0aGlzLmZpcnN0LnByZXY9dm9pZCAwLHRoaXN9cmVtb3ZlKHQpe3JldHVybiB0PT09dGhpcy5maXJzdCYmdD09PXRoaXMubGFzdD8odGhpcy5maXJzdD12b2lkIDAsdGhpcy5sYXN0PXZvaWQgMCk6KHQucHJldiYmKHQucHJldi5uZXh0PXQubmV4dCksdC5uZXh0JiYodC5uZXh0LnByZXY9dC5wcmV2KSx0PT09dGhpcy5maXJzdCYmKHRoaXMuZmlyc3Q9dC5uZXh0KSx0PT09dGhpcy5sYXN0JiYodGhpcy5sYXN0PXQucHJldikpLHRoaXN9aXNFbXB0eSgpe3JldHVybiB0aGlzLmZpcnN0PT09dm9pZCAwfXN0YXRpYyB0ZXN0SW5maW5pdGVMb29wKHQpe2xldCBuPXQscj10O2Rve2lmKG4hPXQmJm49PT1yKXRocm93IFUuSU5GSU5JVEVfTE9PUDtuPW4ubmV4dCxyPXIubmV4dC5uZXh0fXdoaWxlKG4hPXQpfX1jb25zdCBHcz17c3Ryb2tlOiJibGFjayJ9O2NsYXNzIEVme2NvbnN0cnVjdG9yKHQ9R3Mpe2Zvcihjb25zdCBuIGluIHQpdGhpc1tuXT10W25dO3RoaXMuc3Ryb2tlPXQuc3Ryb2tlPz9Hcy5zdHJva2V9dG9BdHRyaWJ1dGVzU3RyaW5nKCl7cmV0dXJuIE9iamVjdC5rZXlzKHRoaXMpLnJlZHVjZSgodCxuKT0+dCsodGhpc1tuXSE9PXZvaWQgMD90aGlzLnRvQXR0clN0cmluZyhuLHRoaXNbbl0pOiIiKSwiIil9dG9BdHRyU3RyaW5nKHQsbil7Y29uc3Qgcj10PT09ImNsYXNzTmFtZSI/ImNsYXNzIjp0aGlzLmNvbnZlcnRDYW1lbFRvS2ViYWJDYXNlKHQpO3JldHVybiBuPT09bnVsbD9gJHtyfSBgOmAke3J9PSIke24udG9TdHJpbmcoKX0iIGB9Y29udmVydENhbWVsVG9LZWJhYkNhc2UodCl7cmV0dXJuIHQubWF0Y2goL1tBLVpdezIsfSg/PVtBLVpdW2Etel0rWzAtOV0qfFxiKXxbQS1aXT9bYS16XStbMC05XSp8W0EtWl18WzAtOV0rL2cpLmpvaW4oIi0iKS50b0xvd2VyQ2FzZSgpfX1mdW5jdGlvbiBQdChlKXtyZXR1cm4gbmV3IEVmKGUpLnRvQXR0cmlidXRlc1N0cmluZygpfWZ1bmN0aW9uIEd0KGUsdCl7bGV0IG49W10sW3IsaSxzXT1lLnN0YW5kYXJkLFtvLGMsbF09dC5zdGFuZGFyZCxoPXIqYy1pKm8sZj1zKmMtaSpsLHU9cipsLXMqbztpZighYS5VdGlscy5FUV8wKGgpKXtsZXQgZCxnO2k9PT0wPyhkPXMvcixnPXUvaCk6Yz09PTA/KGQ9bC9vLGc9dS9oKTpyPT09MD8oZD1mL2gsZz1zL2kpOm89PT0wPyhkPWYvaCxnPWwvYyk6KGQ9Zi9oLGc9dS9oKSxuLnB1c2gobmV3IGEuUG9pbnQoZCxnKSl9cmV0dXJuIG59ZnVuY3Rpb24gUnQoZSx0KXtsZXQgbj1bXSxyPXQucGMucHJvamVjdGlvbk9uKGUpLGk9dC5wYy5kaXN0YW5jZVRvKHIpWzBdO2lmKGEuVXRpbHMuRVEoaSx0LnIpKW4ucHVzaChyKTtlbHNlIGlmKGEuVXRpbHMuTFQoaSx0LnIpKXtsZXQgcz1NYXRoLnNxcnQodC5yKnQuci1pKmkpLG8sYztvPWUubm9ybS5yb3RhdGU5MENDVygpLm11bHRpcGx5KHMpLGM9ci50cmFuc2xhdGUobyksbi5wdXNoKGMpLG89ZS5ub3JtLnJvdGF0ZTkwQ1coKS5tdWx0aXBseShzKSxjPXIudHJhbnNsYXRlKG8pLG4ucHVzaChjKX1yZXR1cm4gbn1mdW5jdGlvbiBYdChlLHQpe2xldCBuPVtdO2ZvcihsZXQgciBvZiB0LnRvU2VnbWVudHMoKSl7bGV0IGk9bWUocixlKTtmb3IobGV0IHMgb2YgaSlybyhzLG4pfHxuLnB1c2gocyl9cmV0dXJuIG59ZnVuY3Rpb24gYW4oZSx0KXtsZXQgbj1bXTtpZihYdChlLHQuYm94KS5sZW5ndGg9PT0wKXJldHVybiBuO2xldCByPW5ldyBhLkNpcmNsZSh0LnBjLHQuciksaT1SdChlLHIpO2ZvcihsZXQgcyBvZiBpKXMub24odCkmJm4ucHVzaChzKTtyZXR1cm4gbn1mdW5jdGlvbiBtZShlLHQpe2xldCBuPVtdO2lmKGUucHMub24odCkmJm4ucHVzaChlLnBzKSxlLnBlLm9uKHQpJiYhZS5pc1plcm9MZW5ndGgoKSYmbi5wdXNoKGUucGUpLG4ubGVuZ3RoPjB8fGUuaXNaZXJvTGVuZ3RoKCl8fGUucHMubGVmdFRvKHQpJiZlLnBlLmxlZnRUbyh0KXx8IWUucHMubGVmdFRvKHQpJiYhZS5wZS5sZWZ0VG8odCkpcmV0dXJuIG47bGV0IHI9bmV3IGEuTGluZShlLnBzLGUucGUpO3JldHVybiBHdChyLHQpfWZ1bmN0aW9uIGxuKGUsdCl7bGV0IG49W107aWYoZS5ib3gubm90X2ludGVyc2VjdCh0LmJveCkpcmV0dXJuIG47aWYoZS5pc1plcm9MZW5ndGgoKSlyZXR1cm4gZS5wcy5vbih0KSYmbi5wdXNoKGUucHMpLG47aWYodC5pc1plcm9MZW5ndGgoKSlyZXR1cm4gdC5wcy5vbihlKSYmbi5wdXNoKHQucHMpLG47bGV0IHI9bmV3IGEuTGluZShlLnBzLGUucGUpLGk9bmV3IGEuTGluZSh0LnBzLHQucGUpO2lmKHIuaW5jaWRlbnRUbyhpKSllLnBzLm9uKHQpJiZuLnB1c2goZS5wcyksZS5wZS5vbih0KSYmbi5wdXNoKGUucGUpLHQucHMub24oZSkmJiF0LnBzLmVxdWFsVG8oZS5wcykmJiF0LnBzLmVxdWFsVG8oZS5wZSkmJm4ucHVzaCh0LnBzKSx0LnBlLm9uKGUpJiYhdC5wZS5lcXVhbFRvKGUucHMpJiYhdC5wZS5lcXVhbFRvKGUucGUpJiZuLnB1c2godC5wZSk7ZWxzZXtsZXQgcz1HdChyLGkpO3MubGVuZ3RoPjAmJlhzKHNbMF0sZSkmJlhzKHNbMF0sdCkmJm4ucHVzaChzWzBdKX1yZXR1cm4gbn1mdW5jdGlvbiBYcyhlLHQpe2NvbnN0IG49dC5ib3g7cmV0dXJuIGEuVXRpbHMuTEUoZS54LG4ueG1heCkmJmEuVXRpbHMuR0UoZS54LG4ueG1pbikmJmEuVXRpbHMuTEUoZS55LG4ueW1heCkmJmEuVXRpbHMuR0UoZS55LG4ueW1pbil9ZnVuY3Rpb24gaG4oZSx0KXtsZXQgbj1bXTtpZihlLmJveC5ub3RfaW50ZXJzZWN0KHQuYm94KSlyZXR1cm4gbjtpZihlLmlzWmVyb0xlbmd0aCgpKXtsZXRbcyxvXT1lLnBzLmRpc3RhbmNlVG8odC5wYyk7cmV0dXJuIGEuVXRpbHMuRVEocyx0LnIpJiZuLnB1c2goZS5wcyksbn1sZXQgcj1uZXcgYS5MaW5lKGUucHMsZS5wZSksaT1SdChyLHQpO2ZvcihsZXQgcyBvZiBpKXMub24oZSkmJm4ucHVzaChzKTtyZXR1cm4gbn1mdW5jdGlvbiBqdChlLHQpe2xldCBuPVtdO2lmKGUuYm94Lm5vdF9pbnRlcnNlY3QodC5ib3gpKXJldHVybiBuO2lmKGUuaXNaZXJvTGVuZ3RoKCkpcmV0dXJuIGUucHMub24odCkmJm4ucHVzaChlLnBzKSxuO2xldCByPW5ldyBhLkxpbmUoZS5wcyxlLnBlKSxpPW5ldyBhLkNpcmNsZSh0LnBjLHQucikscz1SdChyLGkpO2ZvcihsZXQgbyBvZiBzKW8ub24oZSkmJm8ub24odCkmJm4ucHVzaChvKTtyZXR1cm4gbn1mdW5jdGlvbiBPZihlLHQpe2xldCBuPVtdO2ZvcihsZXQgciBvZiB0LnRvU2VnbWVudHMoKSl7bGV0IGk9bG4ocixlKTtmb3IobGV0IHMgb2YgaSluLnB1c2gocyl9cmV0dXJuIG59ZnVuY3Rpb24ganMoZSx0KXtsZXQgbj1bXTtpZihlLmJveC5ub3RfaW50ZXJzZWN0KHQuYm94KSlyZXR1cm4gbjtsZXQgcj1uZXcgYS5WZWN0b3IoZS5wYyx0LnBjKSxpPWUucixzPXQucjtpZihhLlV0aWxzLkVRXzAoaSl8fGEuVXRpbHMuRVFfMChzKSlyZXR1cm4gbjtpZihhLlV0aWxzLkVRXzAoci54KSYmYS5VdGlscy5FUV8wKHIueSkmJmEuVXRpbHMuRVEoaSxzKSlyZXR1cm4gbi5wdXNoKGUucGMudHJhbnNsYXRlKC1pLDApKSxuO2xldCBvPWUucGMuZGlzdGFuY2VUbyh0LnBjKVswXTtpZihhLlV0aWxzLkdUKG8saStzKXx8YS5VdGlscy5MVChvLE1hdGguYWJzKGktcykpKXJldHVybiBuO3IueC89byxyLnkvPW87bGV0IGM7aWYoYS5VdGlscy5FUShvLGkrcyl8fGEuVXRpbHMuRVEobyxNYXRoLmFicyhpLXMpKSlyZXR1cm4gYz1lLnBjLnRyYW5zbGF0ZShpKnIueCxpKnIueSksbi5wdXNoKGMpLG47bGV0IGw9aSppLygyKm8pLXMqcy8oMipvKStvLzIsaD1lLnBjLnRyYW5zbGF0ZShsKnIueCxsKnIueSksZj1NYXRoLnNxcnQoaSppLWwqbCk7cmV0dXJuIGM9aC50cmFuc2xhdGUoci5yb3RhdGU5MENDVygpLm11bHRpcGx5KGYpKSxuLnB1c2goYyksYz1oLnRyYW5zbGF0ZShyLnJvdGF0ZTkwQ1coKS5tdWx0aXBseShmKSksbi5wdXNoKGMpLG59ZnVuY3Rpb24gdmYoZSx0KXtsZXQgbj1bXTtmb3IobGV0IHIgb2YgdC50b1NlZ21lbnRzKCkpe2xldCBpPWhuKHIsZSk7Zm9yKGxldCBzIG9mIGkpbi5wdXNoKHMpfXJldHVybiBufWZ1bmN0aW9uIFFzKGUsdCl7bGV0IG49W107aWYoZS5ib3gubm90X2ludGVyc2VjdCh0LmJveCkpcmV0dXJuIG47aWYoZS5wYy5lcXVhbFRvKHQucGMpJiZhLlV0aWxzLkVRKGUucix0LnIpKXtsZXQgbztyZXR1cm4gbz1lLnN0YXJ0LG8ub24odCkmJm4ucHVzaChvKSxvPWUuZW5kLG8ub24odCkmJm4ucHVzaChvKSxvPXQuc3RhcnQsby5vbihlKSYmbi5wdXNoKG8pLG89dC5lbmQsby5vbihlKSYmbi5wdXNoKG8pLG59bGV0IHI9bmV3IGEuQ2lyY2xlKGUucGMsZS5yKSxpPW5ldyBhLkNpcmNsZSh0LnBjLHQucikscz1yLmludGVyc2VjdChpKTtmb3IobGV0IG8gb2YgcylvLm9uKGUpJiZvLm9uKHQpJiZuLnB1c2gobyk7cmV0dXJuIG59ZnVuY3Rpb24gYXIoZSx0KXtsZXQgbj1bXTtpZihlLmJveC5ub3RfaW50ZXJzZWN0KHQuYm94KSlyZXR1cm4gbjtpZih0LnBjLmVxdWFsVG8oZS5wYykmJmEuVXRpbHMuRVEodC5yLGUucikpcmV0dXJuIG4ucHVzaChlLnN0YXJ0KSxuLnB1c2goZS5lbmQpLG47bGV0IHI9dCxpPW5ldyBhLkNpcmNsZShlLnBjLGUucikscz1qcyhyLGkpO2ZvcihsZXQgbyBvZiBzKW8ub24oZSkmJm4ucHVzaChvKTtyZXR1cm4gbn1mdW5jdGlvbiBiZihlLHQpe2xldCBuPVtdO2ZvcihsZXQgciBvZiB0LnRvU2VnbWVudHMoKSl7bGV0IGk9anQocixlKTtmb3IobGV0IHMgb2YgaSluLnB1c2gocyl9cmV0dXJuIG59ZnVuY3Rpb24gS3MoZSx0KXtyZXR1cm4gZS5pc1NlZ21lbnQ/bG4oZS5zaGFwZSx0KTpqdCh0LGUuc2hhcGUpfWZ1bmN0aW9uIEpzKGUsdCl7cmV0dXJuIGUuaXNTZWdtZW50P2p0KGUuc2hhcGUsdCk6UXMoZS5zaGFwZSx0KX1mdW5jdGlvbiBIcyhlLHQpe3JldHVybiBlLmlzU2VnbWVudD9tZShlLnNoYXBlLHQpOmFuKHQsZS5zaGFwZSl9ZnVuY3Rpb24gSWYoZSx0KXtyZXR1cm4gZS5pc1NlZ21lbnQ/ZnIodCxlLnNoYXBlKTp1cih0LGUuc2hhcGUpfWZ1bmN0aW9uIFNmKGUsdCl7cmV0dXJuIGUuaXNTZWdtZW50P2huKGUuc2hhcGUsdCk6YXIoZS5zaGFwZSx0KX1mdW5jdGlvbiBscihlLHQpe2xldCBuPVtdO2ZvcihsZXQgciBvZiB0LmVkZ2VzKWZvcihsZXQgaSBvZiBLcyhyLGUpKW4ucHVzaChpKTtyZXR1cm4gbn1mdW5jdGlvbiBocihlLHQpe2xldCBuPVtdO2ZvcihsZXQgciBvZiB0LmVkZ2VzKWZvcihsZXQgaSBvZiBKcyhyLGUpKW4ucHVzaChpKTtyZXR1cm4gbn1mdW5jdGlvbiBwZShlLHQpe2xldCBuPVtdO2lmKHQuaXNFbXB0eSgpKXJldHVybiBuO2ZvcihsZXQgciBvZiB0LmVkZ2VzKWZvcihsZXQgaSBvZiBIcyhyLGUpKXJvKGksbil8fG4ucHVzaChpKTtyZXR1cm4gZS5zb3J0UG9pbnRzKG4pfWZ1bmN0aW9uIHRvKGUsdCl7bGV0IG49W107aWYodC5pc0VtcHR5KCkpcmV0dXJuIG47Zm9yKGxldCByIG9mIHQuZWRnZXMpZm9yKGxldCBpIG9mIFNmKHIsZSkpbi5wdXNoKGkpO3JldHVybiBufWZ1bmN0aW9uIGVvKGUsdCl7cmV0dXJuIGUuaXNTZWdtZW50P0tzKHQsZS5zaGFwZSk6ZS5pc0FyYz9Kcyh0LGUuc2hhcGUpOmUuaXNMaW5lP0hzKHQsZS5zaGFwZSk6ZS5pc1JheT9JZih0LGUuc2hhcGUpOltdfWZ1bmN0aW9uIG5vKGUsdCl7bGV0IG49W107aWYodC5pc0VtcHR5KCl8fGUuc2hhcGUuYm94Lm5vdF9pbnRlcnNlY3QodC5ib3gpKXJldHVybiBuO2xldCByPXQuZWRnZXMuc2VhcmNoKGUuc2hhcGUuYm94KTtmb3IobGV0IGkgb2YgciluPVsuLi5uLC4uLmVvKGUsaSldO3JldHVybiBufWZ1bmN0aW9uIExmKGUsdCl7bGV0IG49W107aWYodC5pc0VtcHR5KCl8fGUuc2l6ZT09PTApcmV0dXJuIG47Zm9yKGxldCByIG9mIGUpbj1bLi4ubiwuLi5ubyhyLHQpXTtyZXR1cm4gbn1mdW5jdGlvbiBQZihlLHQpe2xldCBuPVtdO2lmKGUuaXNFbXB0eSgpfHx0LmlzRW1wdHkoKXx8ZS5ib3gubm90X2ludGVyc2VjdCh0LmJveCkpcmV0dXJuIG47Zm9yKGxldCByIG9mIGUuZWRnZXMpbj1bLi4ubiwuLi5ubyhyLHQpXTtyZXR1cm4gbn1mdW5jdGlvbiBSZihlLHQpe3JldHVybiBlIGluc3RhbmNlb2YgYS5MaW5lP3BlKGUsdCk6ZSBpbnN0YW5jZW9mIGEuU2VnbWVudD9scihlLHQpOmUgaW5zdGFuY2VvZiBhLkFyYz9ocihlLHQpOltdfWZ1bmN0aW9uIHJvKGUsdCl7cmV0dXJuIHQuc29tZShuPT5uLmVxdWFsVG8oZSkpfWZ1bmN0aW9uIEV0KGUpe3JldHVybiBuZXcgYS5MaW5lKGUuc3RhcnQsZS5ub3JtKX1mdW5jdGlvbiBmcihlLHQpe3JldHVybiBtZSh0LEV0KGUpKS5maWx0ZXIobj0+ZS5jb250YWlucyhuKSl9ZnVuY3Rpb24gdXIoZSx0KXtyZXR1cm4gYW4oRXQoZSksdCkuZmlsdGVyKG49PmUuY29udGFpbnMobikpfWZ1bmN0aW9uIGlvKGUsdCl7cmV0dXJuIFJ0KEV0KGUpLHQpLmZpbHRlcihuPT5lLmNvbnRhaW5zKG4pKX1mdW5jdGlvbiBDZihlLHQpe3JldHVybiBYdChFdChlKSx0KS5maWx0ZXIobj0+ZS5jb250YWlucyhuKSl9ZnVuY3Rpb24gc28oZSx0KXtyZXR1cm4gR3QoRXQoZSksdCkuZmlsdGVyKG49PmUuY29udGFpbnMobikpfWZ1bmN0aW9uIFZmKGUsdCl7cmV0dXJuIEd0KEV0KGUpLEV0KHQpKS5maWx0ZXIobj0+ZS5jb250YWlucyhuKSkuZmlsdGVyKG49PnQuY29udGFpbnMobikpfWZ1bmN0aW9uIG9vKGUsdCl7cmV0dXJuIHBlKEV0KGUpLHQpLmZpbHRlcihuPT5lLmNvbnRhaW5zKG4pKX1mdW5jdGlvbiBjbyhlLHQpe2lmKGUuaW50ZXJzZWN0JiZlLmludGVyc2VjdCBpbnN0YW5jZW9mIEZ1bmN0aW9uKXJldHVybiBlLmludGVyc2VjdCh0KTt0aHJvdyBVLlVOU1VQUE9SVEVEX1NIQVBFX1RZUEV9ZnVuY3Rpb24gX2UoZSx0KXtsZXQgbj1bXTtmb3IobGV0IHIgb2YgdCluPVsuLi5uLC4uLmNvKGUsci5zaGFwZSldO3JldHVybiBufWZ1bmN0aW9uIE5mKGUsdCl7bGV0IG49W107Zm9yKGxldCByIG9mIGUpZm9yKGxldCBpIG9mIHQpbj1bLi4ubiwuLi5jbyhyLGkpXTtyZXR1cm4gbn1sZXQgQ3Q9Y2xhc3MgTGUgZXh0ZW5kcyBjcntjb25zdHJ1Y3RvciguLi50KXtpZihzdXBlcigpLHRoaXMuaXNJbmZpbml0ZT0hMSx0Lmxlbmd0aD09PTEmJnRbMF1pbnN0YW5jZW9mIEFycmF5JiZ0WzBdLmxlbmd0aD4wKXtsZXQgbj0hMTtjb25zdCByPXRbMF0saT1yLmxlbmd0aCxzPWw9PmwgaW5zdGFuY2VvZiBhLlNlZ21lbnR8fGwgaW5zdGFuY2VvZiBhLkFyY3x8bCBpbnN0YW5jZW9mIGEuUmF5fHxsIGluc3RhbmNlb2YgYS5MaW5lLG89bD0+bCBpbnN0YW5jZW9mIGEuU2VnbWVudHx8bCBpbnN0YW5jZW9mIGEuQXJjfHxsIGluc3RhbmNlb2YgYS5SYXksYz1sPT5sIGluc3RhbmNlb2YgYS5TZWdtZW50fHxsIGluc3RhbmNlb2YgYS5BcmM7aWYobj1pPT09MSYmcyhyWzBdKXx8aT4xJiZvKHJbMF0pJiZvKHJbaS0xXSkmJnIuc2xpY2UoMSxpLTEpLmV2ZXJ5KGMpLG4pe3RoaXMuaXNJbmZpbml0ZT1yLnNvbWUobD0+bCBpbnN0YW5jZW9mIGEuUmF5fHxsIGluc3RhbmNlb2YgYS5MaW5lKTtmb3IobGV0IGwgb2Ygcil7bGV0IGg9bmV3IGEuRWRnZShsKTt0aGlzLmFwcGVuZChoKX10aGlzLnNldEFyY0xlbmd0aCgpfWVsc2UgdGhyb3cgYS5FcnJvcnMuSUxMRUdBTF9QQVJBTUVURVJTfX1nZXQgZWRnZXMoKXtyZXR1cm5bLi4udGhpc119Z2V0IGJveCgpe3JldHVybiB0aGlzLmVkZ2VzLnJlZHVjZSgodCxuKT0+dC5tZXJnZShuLmJveCksbmV3IGEuQm94KX1nZXQgdmVydGljZXMoKXtsZXQgdD10aGlzLmVkZ2VzLm1hcChuPT5uLnN0YXJ0KTtyZXR1cm4gdC5wdXNoKHRoaXMubGFzdC5lbmQpLHR9Z2V0IGxlbmd0aCgpe2lmKHRoaXMuaXNFbXB0eSgpKXJldHVybiAwO2lmKHRoaXMuaXNJbmZpbml0ZSlyZXR1cm4gTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZO2xldCB0PTA7Zm9yKGxldCBuIG9mIHRoaXMpdCs9bi5sZW5ndGg7cmV0dXJuIHR9Y2xvbmUoKXtyZXR1cm4gbmV3IExlKHRoaXMudG9TaGFwZXMoKSl9c2V0QXJjTGVuZ3RoKCl7Zm9yKGxldCB0IG9mIHRoaXMpdGhpcy5zZXRPbmVFZGdlQXJjTGVuZ3RoKHQpfXNldE9uZUVkZ2VBcmNMZW5ndGgodCl7dD09PXRoaXMuZmlyc3Q/dC5hcmNfbGVuZ3RoPTA6dC5hcmNfbGVuZ3RoPXQucHJldi5hcmNfbGVuZ3RoK3QucHJldi5sZW5ndGh9cG9pbnRBdExlbmd0aCh0KXtpZih0PnRoaXMubGVuZ3RofHx0PDB8fHRoaXMuaXNJbmZpbml0ZSlyZXR1cm4gbnVsbDtsZXQgbj1udWxsO2ZvcihsZXQgciBvZiB0aGlzKWlmKHQ+PXIuYXJjX2xlbmd0aCYmKHI9PT10aGlzLmxhc3R8fHQ8ci5uZXh0LmFyY19sZW5ndGgpKXtuPXIucG9pbnRBdExlbmd0aCh0LXIuYXJjX2xlbmd0aCk7YnJlYWt9cmV0dXJuIG59YWRkVmVydGV4KHQsbil7bGV0IHI9bi5zaGFwZS5zcGxpdCh0KTtpZihyWzBdPT09bnVsbClyZXR1cm4gbi5wcmV2O2lmKHJbMV09PT1udWxsKXJldHVybiBuO2xldCBpPW5ldyBhLkVkZ2UoclswXSkscz1uLnByZXY7cmV0dXJuIHRoaXMuaW5zZXJ0KGkscyksbi5zaGFwZT1yWzFdLGl9Z2V0Q2hhaW4odCxuKXtsZXQgcj1bXTtmb3IobGV0IGk9dDtpIT09bi5uZXh0O2k9aS5uZXh0KXIucHVzaChpKTtyZXR1cm4gcn1zcGxpdCh0KXtmb3IobGV0IG4gb2YgdCl7bGV0IHI9dGhpcy5maW5kRWRnZUJ5UG9pbnQobik7dGhpcy5hZGRWZXJ0ZXgobixyKX1yZXR1cm4gdGhpc31maW5kRWRnZUJ5UG9pbnQodCl7bGV0IG47Zm9yKGxldCByIG9mIHRoaXMpaWYoci5zaGFwZS5jb250YWlucyh0KSl7bj1yO2JyZWFrfXJldHVybiBufWRpc3RhbmNlVG8odCl7aWYodCBpbnN0YW5jZW9mIFBvaW50KXtjb25zdFtuLHJdPWEuRGlzdGFuY2Uuc2hhcGUybXVsdGlsaW5lKHQsdGhpcyk7cmV0dXJuW24sci5yZXZlcnNlKCldfWlmKHQgaW5zdGFuY2VvZiBhLkxpbmUpe2NvbnN0W24scl09YS5EaXN0YW5jZS5zaGFwZTJtdWx0aWxpbmUodCx0aGlzKTtyZXR1cm5bbixyLnJldmVyc2UoKV19aWYodCBpbnN0YW5jZW9mIGEuQ2lyY2xlKXtjb25zdFtuLHJdPWEuRGlzdGFuY2Uuc2hhcGUybXVsdGlsaW5lKHQsdGhpcyk7cmV0dXJuW24sci5yZXZlcnNlKCldfWlmKHQgaW5zdGFuY2VvZiBhLlNlZ21lbnQpe2NvbnN0W24scl09YS5EaXN0YW5jZS5zaGFwZTJtdWx0aWxpbmUodCx0aGlzKTtyZXR1cm5bbixyLnJldmVyc2UoKV19aWYodCBpbnN0YW5jZW9mIGEuQXJjKXtjb25zdFtuLHJdPWEuRGlzdGFuY2Uuc2hhcGUybXVsdGlsaW5lKHQsdGhpcyk7cmV0dXJuW24sci5yZXZlcnNlKCldfWlmKHQgaW5zdGFuY2VvZiBhLk11bHRpbGluZSlyZXR1cm4gYS5EaXN0YW5jZS5tdWx0aWxpbmUybXVsdGlsaW5lKHRoaXMsdCk7dGhyb3cgYS5FcnJvcnMuVU5TVVBQT1JURURfU0hBUEVfVFlQRX1pbnRlcnNlY3QodCl7cmV0dXJuIHQgaW5zdGFuY2VvZiBhLk11bHRpbGluZT9OZih0aGlzLHQpOl9lKHQsdGhpcyl9Y29udGFpbnModCl7aWYodCBpbnN0YW5jZW9mIGEuUG9pbnQpcmV0dXJuIHRoaXMuZWRnZXMuc29tZShuPT5uLnNoYXBlLmNvbnRhaW5zKHQpKTt0aHJvdyBhLkVycm9ycy5VTlNVUFBPUlRFRF9TSEFQRV9UWVBFfXRyYW5zbGF0ZSh0KXtyZXR1cm4gbmV3IExlKHRoaXMuZWRnZXMubWFwKG49Pm4uc2hhcGUudHJhbnNsYXRlKHQpKSl9cm90YXRlKHQ9MCxuPW5ldyBhLlBvaW50KXtyZXR1cm4gbmV3IExlKHRoaXMuZWRnZXMubWFwKHI9PnIuc2hhcGUucm90YXRlKHQsbikpKX10cmFuc2Zvcm0odD1uZXcgYS5NYXRyaXgpe3JldHVybiBuZXcgTGUodGhpcy5lZGdlcy5tYXAobj0+bi5zaGFwZS50cmFuc2Zvcm0odCkpKX10b1NoYXBlcygpe3JldHVybiB0aGlzLmVkZ2VzLm1hcCh0PT50LnNoYXBlLmNsb25lKCkpfXRvSlNPTigpe3JldHVybiB0aGlzLmVkZ2VzLm1hcCh0PT50LnRvSlNPTigpKX1zdmdQb2ludHMoKXtyZXR1cm4gdGhpcy52ZXJ0aWNlcy5tYXAodD0+YCR7dC54fSwke3QueX1gKS5qb2luKCIgIil9ZHBhdGgoKXtsZXQgdD1gTSR7dGhpcy5maXJzdC5zdGFydC54fSwke3RoaXMuZmlyc3Quc3RhcnQueX1gO2ZvcihsZXQgbiBvZiB0aGlzKXQrPW4uc3ZnKCk7cmV0dXJuIHR9c3ZnKHQ9e30pe2xldCBuPWAKPHBhdGggJHtQdCh7ZmlsbDoibm9uZSIsLi4udH0pfSBkPSJgO24rPWAKTSR7dGhpcy5maXJzdC5zdGFydC54fSwke3RoaXMuZmlyc3Quc3RhcnQueX1gO2ZvcihsZXQgciBvZiB0aGlzKW4rPXIuc3ZnKCk7cmV0dXJuIG4rPWAiID4KPC9wYXRoPmAsbn19O2EuTXVsdGlsaW5lPUN0O2NvbnN0ICRmPSguLi5lKT0+bmV3IGEuTXVsdGlsaW5lKC4uLmUpO2EubXVsdGlsaW5lPSRmO2Z1bmN0aW9uIFF0KGUsdCxuKXtsZXQgcj1uLmxlbmd0aCxpPWUuc2hhcGUuc3BsaXQodCk7aWYoaS5sZW5ndGg9PT0wKXJldHVybjtsZXQgcz0wO2lbMF09PT1udWxsP3M9MDppWzFdPT09bnVsbD9zPWUuc2hhcGUubGVuZ3RoOnM9aVswXS5sZW5ndGg7bGV0IG89c3I7THQocywwKSYmKG98PWdlKSxMdChzLGUuc2hhcGUubGVuZ3RoKSYmKG98PVp0KTtsZXQgYztzPT09MS8wP2M9aVswXS5jb29yZCh0KTpjPW8mWnQmJmUubmV4dCYmZS5uZXh0LmFyY19sZW5ndGg9PT0wPzA6ZS5hcmNfbGVuZ3RoK3Msbi5wdXNoKHtpZDpyLHB0OnQsYXJjX2xlbmd0aDpjLGVkZ2VfYmVmb3JlOmUsZWRnZV9hZnRlcjp2b2lkIDAsZmFjZTplLmZhY2UsaXNfdmVydGV4Om99KX1mdW5jdGlvbiB5ZShlKXtlLmludF9wb2ludHMxX3NvcnRlZD1PdChlLmludF9wb2ludHMxKSxlLmludF9wb2ludHMyX3NvcnRlZD1PdChlLmludF9wb2ludHMyKX1mdW5jdGlvbiBPdChlKXtsZXQgdD1uZXcgTWFwLG49MDtmb3IobGV0IGkgb2YgZSl0LmhhcyhpLmZhY2UpfHwodC5zZXQoaS5mYWNlLG4pLG4rKyk7Zm9yKGxldCBpIG9mIGUpaS5mYWNlSWQ9dC5nZXQoaS5mYWNlKTtyZXR1cm4gZS5zbGljZSgpLnNvcnQoemYpfWZ1bmN0aW9uIHpmKGUsdCl7cmV0dXJuIGUuZmFjZUlkPHQuZmFjZUlkPy0xOmUuZmFjZUlkPnQuZmFjZUlkPzE6ZS5hcmNfbGVuZ3RoPHQuYXJjX2xlbmd0aD8tMTplLmFyY19sZW5ndGg+dC5hcmNfbGVuZ3RoPzE6MH1mdW5jdGlvbiBkcihlKXtpZihlLmludF9wb2ludHMxLmxlbmd0aDwyKXJldHVybjtsZXQgdD0hMSxuLHIsaSxzO2ZvcihsZXQgbz0wO288ZS5pbnRfcG9pbnRzMV9zb3J0ZWQubGVuZ3RoO28rKylpZihlLmludF9wb2ludHMxX3NvcnRlZFtvXS5pZCE9PS0xKXtuPWUuaW50X3BvaW50czFfc29ydGVkW29dLHI9ZS5pbnRfcG9pbnRzMltuLmlkXTtmb3IobGV0IGM9bysxO2M8ZS5pbnRfcG9pbnRzMV9zb3J0ZWQubGVuZ3RoJiYoaT1lLmludF9wb2ludHMxX3NvcnRlZFtjXSwhIUx0KGkuYXJjX2xlbmd0aCxuLmFyY19sZW5ndGgpKTtjKyspaS5pZCE9PS0xJiYocz1lLmludF9wb2ludHMyW2kuaWRdLHMuaWQhPT0tMSYmaS5lZGdlX2JlZm9yZT09PW4uZWRnZV9iZWZvcmUmJmkuZWRnZV9hZnRlcj09PW4uZWRnZV9hZnRlciYmcy5lZGdlX2JlZm9yZT09PXIuZWRnZV9iZWZvcmUmJnMuZWRnZV9hZnRlcj09PXIuZWRnZV9hZnRlciYmKGkuaWQ9LTEscy5pZD0tMSx0PSEwKSl9cj1lLmludF9wb2ludHMyX3NvcnRlZFswXSxuPWUuaW50X3BvaW50czFbci5pZF07Zm9yKGxldCBvPTE7bzxlLmludF9wb2ludHMyX3NvcnRlZC5sZW5ndGg7bysrKXtsZXQgYz1lLmludF9wb2ludHMyX3NvcnRlZFtvXTtpZihjLmlkPT09LTEpY29udGludWU7aWYoci5pZD09PS0xfHwhTHQoYy5hcmNfbGVuZ3RoLHIuYXJjX2xlbmd0aCkpe3I9YyxuPWUuaW50X3BvaW50czFbci5pZF07Y29udGludWV9bGV0IGw9ZS5pbnRfcG9pbnRzMVtjLmlkXTtsLmVkZ2VfYmVmb3JlPT09bi5lZGdlX2JlZm9yZSYmbC5lZGdlX2FmdGVyPT09bi5lZGdlX2FmdGVyJiZjLmVkZ2VfYmVmb3JlPT09ci5lZGdlX2JlZm9yZSYmYy5lZGdlX2FmdGVyPT09ci5lZGdlX2FmdGVyJiYobC5pZD0tMSxjLmlkPS0xLHQ9ITApfXQmJihlLmludF9wb2ludHMxPWUuaW50X3BvaW50czEuZmlsdGVyKG89Pm8uaWQ+PTApLGUuaW50X3BvaW50czI9ZS5pbnRfcG9pbnRzMi5maWx0ZXIobz0+by5pZD49MCksZS5pbnRfcG9pbnRzMS5mb3JFYWNoKChvLGMpPT5vLmlkPWMpLGUuaW50X3BvaW50czIuZm9yRWFjaCgobyxjKT0+by5pZD1jKSl9ZnVuY3Rpb24gZ3IoZSl7Zm9yKGxldCB0IG9mIGUpdC5lZGdlX2JlZm9yZSYmKHQuZWRnZV9iZWZvcmUuYnZTdGFydD12b2lkIDAsdC5lZGdlX2JlZm9yZS5idkVuZD12b2lkIDAsdC5lZGdlX2JlZm9yZS5idj12b2lkIDAsdC5lZGdlX2JlZm9yZS5vdmVybGFwPXZvaWQgMCksdC5lZGdlX2FmdGVyJiYodC5lZGdlX2FmdGVyLmJ2U3RhcnQ9dm9pZCAwLHQuZWRnZV9hZnRlci5idkVuZD12b2lkIDAsdC5lZGdlX2FmdGVyLmJ2PXZvaWQgMCx0LmVkZ2VfYWZ0ZXIub3ZlcmxhcD12b2lkIDApO2ZvcihsZXQgdCBvZiBlKXQuZWRnZV9iZWZvcmUmJih0LmVkZ2VfYmVmb3JlLmJ2RW5kPXV0KSx0LmVkZ2VfYWZ0ZXImJih0LmVkZ2VfYWZ0ZXIuYnZTdGFydD11dCl9ZnVuY3Rpb24gbXIoZSx0KXtmb3IobGV0IG4gb2YgZSluLmVkZ2VfYmVmb3JlJiZuLmVkZ2VfYmVmb3JlLnNldEluY2x1c2lvbih0KSxuLmVkZ2VfYWZ0ZXImJm4uZWRnZV9hZnRlci5zZXRJbmNsdXNpb24odCl9ZnVuY3Rpb24ga2YoZSl7bGV0IHQsbixyLGk9ZS5pbnRfcG9pbnRzMS5sZW5ndGg7Zm9yKGxldCBzPTA7czxpO3MrKyl7bGV0IG89ZS5pbnRfcG9pbnRzMV9zb3J0ZWRbc107by5mYWNlIT09dCYmKG49cyx0PW8uZmFjZSk7bGV0IGM9cyxsPUt0KGUuaW50X3BvaW50czFfc29ydGVkLHMsdCksaDtjK2w8aSYmZS5pbnRfcG9pbnRzMV9zb3J0ZWRbYytsXS5mYWNlPT09dD9oPWMrbDpoPW47bGV0IGY9S3QoZS5pbnRfcG9pbnRzMV9zb3J0ZWQsaCx0KTtyPW51bGw7Zm9yKGxldCBNPWg7TTxoK2Y7TSsrKXtsZXQgQT1lLmludF9wb2ludHMxX3NvcnRlZFtNXTtpZihBLmZhY2U9PT10JiZlLmludF9wb2ludHMyW0EuaWRdLmZhY2U9PT1lLmludF9wb2ludHMyW28uaWRdLmZhY2Upe3I9QTticmVha319aWYocj09PW51bGwpY29udGludWU7bGV0IHU9by5lZGdlX2FmdGVyLGQ9ci5lZGdlX2JlZm9yZTtpZighKHUuYnY9PT11dCYmZC5idj09PXV0KXx8dSE9PWQpY29udGludWU7bGV0IGc9ZS5pbnRfcG9pbnRzMltvLmlkXSxtPWUuaW50X3BvaW50czJbci5pZF0sXz1nLmVkZ2VfYWZ0ZXIscD1tLmVkZ2VfYmVmb3JlO18uYnY9PT11dCYmcC5idj09PXV0JiZfPT09cHx8KGc9ZS5pbnRfcG9pbnRzMltyLmlkXSxtPWUuaW50X3BvaW50czJbby5pZF0sXz1nLmVkZ2VfYWZ0ZXIscD1tLmVkZ2VfYmVmb3JlKSxfLmJ2PT09dXQmJnAuYnY9PT11dCYmXz09PXAmJnUuc2V0T3ZlcmxhcChfKX19ZnVuY3Rpb24gS3QoZSx0LG4pe2xldCByLGkscz0xO2lmKGUubGVuZ3RoPT09MSlyZXR1cm4gMTtyPWVbdF07Zm9yKGxldCBvPXQrMTtvPGUubGVuZ3RoJiYhKHIuZmFjZSE9PW58fChpPWVbb10sIShpLnB0LmVxdWFsVG8oci5wdCkmJmkuZWRnZV9iZWZvcmU9PT1yLmVkZ2VfYmVmb3JlJiZpLmVkZ2VfYWZ0ZXI9PT1yLmVkZ2VfYWZ0ZXIpKSk7bysrKXMrKztyZXR1cm4gc31mdW5jdGlvbiBKdChlLHQpe2lmKHQpe2ZvcihsZXQgbiBvZiB0KXtsZXQgcj1uLmVkZ2VfYmVmb3JlO2lmKG4uaXNfdmVydGV4PXNyLHIuc2hhcGUuc3RhcnQmJnIuc2hhcGUuc3RhcnQuZXF1YWxUbyhuLnB0KSYmKG4uaXNfdmVydGV4fD1nZSksci5zaGFwZS5lbmQmJnIuc2hhcGUuZW5kLmVxdWFsVG8obi5wdCkmJihuLmlzX3ZlcnRleHw9WnQpLG4uaXNfdmVydGV4JmdlKXtuLmVkZ2VfYmVmb3JlPXIucHJldixyLnByZXYmJihuLmlzX3ZlcnRleD1adCk7Y29udGludWV9aWYobi5pc192ZXJ0ZXgmWnQpY29udGludWU7bGV0IGk9ZS5hZGRWZXJ0ZXgobi5wdCxyKTtuLmVkZ2VfYmVmb3JlPWl9Zm9yKGxldCBuIG9mIHQpbi5lZGdlX2JlZm9yZT9uLmVkZ2VfYWZ0ZXI9bi5lZGdlX2JlZm9yZS5uZXh0OmUgaW5zdGFuY2VvZiBDdCYmbi5pc192ZXJ0ZXgmZ2UmJihuLmVkZ2VfYWZ0ZXI9ZS5maXJzdCl9fWZ1bmN0aW9uIGFvKGUsdCxuKXtjb25zdCByPWUuZWRnZV9iZWZvcmUsaT10LmVkZ2VfYWZ0ZXIscz1uLmxlbmd0aDtyLm5leHQ9blswXSxuWzBdLnByZXY9cixuW3MtMV0ubmV4dD1pLGkucHJldj1uW3MtMV19Y29uc3R7SU5TSURFOmd0LE9VVFNJREU6bXQsQk9VTkRBUlk6aixPVkVSTEFQX1NBTUU6RmYsT1ZFUkxBUF9PUFBPU0lURTpxZn09Y24se05PVF9WRVJURVg6ejAsU1RBUlRfVkVSVEVYOmxvLEVORF9WRVJURVg6aG99PWNuLGZuPTEseGU9MixWdD0zO2Z1bmN0aW9uIFVmKGUsdCl7bGV0W24scl09TWUoZSx0LGZuLCEwKTtyZXR1cm4gbn1mdW5jdGlvbiBwcihlLHQpe2xldCByPXQuY2xvbmUoKS5yZXZlcnNlKCksW2ksc109TWUoZSxyLFZ0LCEwKTtyZXR1cm4gaX1mdW5jdGlvbiBmbyhlLHQpe2xldFtuLHJdPU1lKGUsdCx4ZSwhMCk7cmV0dXJuIG59ZnVuY3Rpb24gdW8oZSx0KXtsZXRbbixyXT1NZShlLHQseGUsITEpLGk9W107Zm9yKGxldCBvIG9mIG4uZmFjZXMpaT1bLi4uaSwuLi5bLi4uby5lZGdlc10ubWFwKGM9PmMuc2hhcGUpXTtsZXQgcz1bXTtmb3IobGV0IG8gb2Ygci5mYWNlcylzPVsuLi5zLC4uLlsuLi5vLmVkZ2VzXS5tYXAoYz0+Yy5zaGFwZSldO3JldHVybltpLHNdfWZ1bmN0aW9uIF9yKGUsdCl7bGV0W24scl09TWUoZSx0LFZ0LCExKSxpPVtdO2ZvcihsZXQgcyBvZiBuLmZhY2VzKWk9Wy4uLmksLi4uWy4uLnMuZWRnZXNdLm1hcChvPT5vLnNoYXBlKV07cmV0dXJuIGl9ZnVuY3Rpb24gZ28oZSx0KXtsZXQgbj1lLmNsb25lKCkscj10LmNsb25lKCksaT1tbyhuLHIpO3llKGkpLEp0KG4saS5pbnRfcG9pbnRzMV9zb3J0ZWQpLEp0KHIsaS5pbnRfcG9pbnRzMl9zb3J0ZWQpLGRyKGkpLHllKGkpO2xldCBzPWkuaW50X3BvaW50czFfc29ydGVkLm1hcChjPT5jLnB0KSxvPWkuaW50X3BvaW50czJfc29ydGVkLm1hcChjPT5jLnB0KTtyZXR1cm5bcyxvXX1mdW5jdGlvbiBEZihlLHQsbixyKXtsZXQgaT1wbyhlLG4uaW50X3BvaW50czEpLHM9cG8odCxuLmludF9wb2ludHMyKTtmb3IoX28oaSx0KSxfbyhzLGUpLGdyKG4uaW50X3BvaW50czEpLGdyKG4uaW50X3BvaW50czIpLG1yKG4uaW50X3BvaW50czEsdCksbXIobi5pbnRfcG9pbnRzMixlKTtZZihlLHQsbi5pbnRfcG9pbnRzMSxuLmludF9wb2ludHMxX3NvcnRlZCxuLmludF9wb2ludHMyLG4pOyk7a2YobikseXIoZSxyLG4uaW50X3BvaW50czFfc29ydGVkLCEwKSx5cih0LHIsbi5pbnRfcG9pbnRzMl9zb3J0ZWQsITEpLHlvKGUsaSxyLCEwKSx5byh0LHMsciwhMSl9ZnVuY3Rpb24gQmYoZSx0LG4scil7V2YoZSx0LHIsbi5pbnRfcG9pbnRzMiksWmYoZSx0LG4pLHhyKGUsbi5pbnRfcG9pbnRzMSkseHIodCxuLmludF9wb2ludHMyKSxNcihlLG4uaW50X3BvaW50czEsbi5pbnRfcG9pbnRzMiksTXIoZSxuLmludF9wb2ludHMyLG4uaW50X3BvaW50czEpfWZ1bmN0aW9uIE1lKGUsdCxuLHIpe2xldCBpPWUuY2xvbmUoKSxzPXQuY2xvbmUoKSxvPW1vKGkscyk7cmV0dXJuIHllKG8pLEp0KGksby5pbnRfcG9pbnRzMV9zb3J0ZWQpLEp0KHMsby5pbnRfcG9pbnRzMl9zb3J0ZWQpLGRyKG8pLHllKG8pLERmKGkscyxvLG4pLHImJkJmKGkscyxvLG4pLFtpLHNdfWZ1bmN0aW9uIG1vKGUsdCl7bGV0IG49e2ludF9wb2ludHMxOltdLGludF9wb2ludHMyOltdfTtmb3IobGV0IHIgb2YgZS5lZGdlcyl7bGV0IGk9dC5lZGdlcy5zZWFyY2goci5ib3gpO2ZvcihsZXQgcyBvZiBpKXtsZXQgbz1yLnNoYXBlLmludGVyc2VjdChzLnNoYXBlKTtmb3IobGV0IGMgb2YgbylRdChyLGMsbi5pbnRfcG9pbnRzMSksUXQocyxjLG4uaW50X3BvaW50czIpfX1yZXR1cm4gbn1mdW5jdGlvbiBwbyhlLHQpe2xldCBuPVtdO2ZvcihsZXQgciBvZiBlLmZhY2VzKXQuZmluZChpPT5pLmZhY2U9PT1yKXx8bi5wdXNoKHIpO3JldHVybiBufWZ1bmN0aW9uIF9vKGUsdCl7Zm9yKGxldCBuIG9mIGUpbi5maXJzdC5idj1uLmZpcnN0LmJ2U3RhcnQ9bi5maXJzdC5idkVuZD12b2lkIDAsbi5maXJzdC5zZXRJbmNsdXNpb24odCl9ZnVuY3Rpb24gWWYoZSx0LG4scixpLHMpe2xldCBvLGMsbCxoPXIubGVuZ3RoLGY9ITE7Zm9yKGxldCB1PTA7dTxoO3UrKyl7bGV0IGQ9clt1XTtkLmZhY2UhPT1vJiYoYz11LG89ZC5mYWNlKTtsZXQgZz11LG09S3Qocix1LG8pLF87ZyttPGgmJnJbZyttXS5mYWNlPT09bz9fPWcrbTpfPWM7bGV0IHA9S3QocixfLG8pO2w9bnVsbDtmb3IobGV0IHg9Xzt4PF8rcDt4Kyspe2xldCBUPXJbeF07aWYoVC5mYWNlPT09byYmaVtULmlkXS5mYWNlPT09aVtkLmlkXS5mYWNlKXtsPVQ7YnJlYWt9fWlmKGw9PT1udWxsKWNvbnRpbnVlO2xldCBNPWQuZWRnZV9hZnRlcixBPWwuZWRnZV9iZWZvcmU7aWYoTS5idj09PWomJkEuYnYhPWope00uYnY9QS5idjtjb250aW51ZX1pZihNLmJ2IT1qJiZBLmJ2PT09ail7QS5idj1NLmJ2O2NvbnRpbnVlfWlmKE0uYnY9PT1qJiZBLmJ2PT09aiYmTSE9QXx8TS5idj09PWd0JiZBLmJ2PT09bXR8fE0uYnY9PT1tdCYmQS5idj09PWd0KXtsZXQgeD1NLm5leHQ7Zm9yKDt4IT1BOyl4LmJ2U3RhcnQ9dm9pZCAwLHguYnZFbmQ9dm9pZCAwLHguYnY9dm9pZCAwLHguc2V0SW5jbHVzaW9uKHQpLHg9eC5uZXh0fWlmKE0uYnY9PT1qJiZBLmJ2PT09aiYmTSE9QSl7bGV0IHg9TS5uZXh0LFQ7Zm9yKDt4IT1BOyl7aWYoeC5idiE9ail7aWYoVD09PXZvaWQgMClUPXguYnY7ZWxzZSBpZih4LmJ2IT1UKXRocm93IFUuVU5SRVNPTFZFRF9CT1VOREFSWV9DT05GTElDVH14PXgubmV4dH1UIT1udWxsJiYoTS5idj1ULEEuYnY9VCk7Y29udGludWV9aWYoTS5idj09PWd0JiZBLmJ2PT09bXR8fE0uYnY9PT1tdCYmQS5idj09PWd0KXtsZXQgeD1NO2Zvcig7eCE9QTspe2lmKHguYnZTdGFydD09PU0uYnYmJnguYnZFbmQ9PT1BLmJ2KXtsZXRbVCxPXT14LnNoYXBlLmRpc3RhbmNlVG8odCk7aWYoVDwxMCphLkRQX1RPTCl7UXQoeCxPLnBzLG4pO2xldCB3PW5bbi5sZW5ndGgtMV07aWYody5pc192ZXJ0ZXgmbG8pdy5lZGdlX2FmdGVyPXgsdy5lZGdlX2JlZm9yZT14LnByZXYseC5idlN0YXJ0PWoseC5idj12b2lkIDAseC5zZXRJbmNsdXNpb24odCk7ZWxzZSBpZih3LmlzX3ZlcnRleCZobyl3LmVkZ2VfYWZ0ZXI9eC5uZXh0LHguYnZFbmQ9aix4LmJ2PXZvaWQgMCx4LnNldEluY2x1c2lvbih0KTtlbHNle2xldCBJPXQuYWRkVmVydGV4KHcucHQseCk7dy5lZGdlX2JlZm9yZT1JLHcuZWRnZV9hZnRlcj1JLm5leHQsSS5zZXRJbmNsdXNpb24odCksSS5uZXh0LmJ2U3RhcnQ9aixJLm5leHQuYnZFbmQ9dm9pZCAwLEkubmV4dC5idj12b2lkIDAsSS5uZXh0LnNldEluY2x1c2lvbih0KX1sZXQgUz10LmZpbmRFZGdlQnlQb2ludChPLnBlKTtRdChTLE8ucGUsaSk7bGV0IGI9aVtpLmxlbmd0aC0xXTtpZihiLmlzX3ZlcnRleCZsbyliLmVkZ2VfYWZ0ZXI9UyxiLmVkZ2VfYmVmb3JlPVMucHJldjtlbHNlIGlmKGIuaXNfdmVydGV4JmhvKWIuZWRnZV9hZnRlcj1TLm5leHQ7ZWxzZXtsZXQgST1pLmZpbmQoVj0+Vi5lZGdlX2FmdGVyPT09UyksRT10LmFkZFZlcnRleChiLnB0LFMpO2IuZWRnZV9iZWZvcmU9RSxiLmVkZ2VfYWZ0ZXI9RS5uZXh0LEkmJihJLmVkZ2VfYWZ0ZXI9RSksRS5idlN0YXJ0PXZvaWQgMCxFLmJ2RW5kPWosRS5idj12b2lkIDAsRS5zZXRJbmNsdXNpb24oZSksRS5uZXh0LmJ2U3RhcnQ9aixFLm5leHQuYnZFbmQ9dm9pZCAwLEUubmV4dC5idj12b2lkIDAsRS5uZXh0LnNldEluY2x1c2lvbihlKX15ZShzKSxmPSEwO2JyZWFrfX14PXgubmV4dH1pZihmKWJyZWFrO3Rocm93IFUuVU5SRVNPTFZFRF9CT1VOREFSWV9DT05GTElDVH19cmV0dXJuIGZ9ZnVuY3Rpb24geXIoZSx0LG4scil7aWYoIW4pcmV0dXJuO2xldCBpLHMsbyxjO2ZvcihsZXQgbD0wO2w8bi5sZW5ndGg7bCsrKXtpZihvPW5bbF0sby5mYWNlIT09aSYmKHM9bCxpPW8uZmFjZSksaS5pc0VtcHR5KCkpY29udGludWU7bGV0IGg9bCxmPUt0KG4sbCxpKSx1O2grZjxuLmxlbmd0aCYmbltoK2ZdLmZhY2U9PT1vLmZhY2U/dT1oK2Y6dT1zLGM9blt1XTtsZXQgZD11LGc9S3QobixkLGkpLG09by5lZGdlX2FmdGVyLF89Yy5lZGdlX2JlZm9yZTtpZihtLmJ2PT09Z3QmJl8uYnY9PT1ndCYmdD09PWZufHxtLmJ2PT09bXQmJl8uYnY9PT1tdCYmdD09PXhlfHwobS5idj09PW10fHxfLmJ2PT09bXQpJiZ0PT09VnQmJiFyfHwobS5idj09PWd0fHxfLmJ2PT09Z3QpJiZ0PT09VnQmJnJ8fG0uYnY9PT1qJiZfLmJ2PT09aiYmbS5vdmVybGFwJkZmJiZyfHxtLmJ2PT09aiYmXy5idj09PWomJm0ub3ZlcmxhcCZxZil7ZS5yZW1vdmVDaGFpbihpLG0sXyk7Zm9yKGxldCBwPWg7cDxoK2Y7cCsrKW5bcF0uZWRnZV9hZnRlcj12b2lkIDA7Zm9yKGxldCBwPWQ7cDxkK2c7cCsrKW5bcF0uZWRnZV9iZWZvcmU9dm9pZCAwfWwrPWYtMX19ZnVuY3Rpb24gV2YoZSx0LG4scil7Zm9yKGxldCBpIG9mIHQuZmFjZXMpe2ZvcihsZXQgcyBvZiBpKWUuZWRnZXMuYWRkKHMpO3IuZmluZChzPT5zLmZhY2U9PT1pKT09PXZvaWQgMCYmZS5hZGRGYWNlKGkuZmlyc3QsaS5sYXN0KX19ZnVuY3Rpb24gWmYoZSx0LG4pe2lmKG4uaW50X3BvaW50czEubGVuZ3RoIT09MClmb3IobGV0IHI9MDtyPG4uaW50X3BvaW50czEubGVuZ3RoO3IrKyl7bGV0IGk9bi5pbnRfcG9pbnRzMVtyXSxzPW4uaW50X3BvaW50czJbcl07aWYoaS5lZGdlX2JlZm9yZSE9PXZvaWQgMCYmaS5lZGdlX2FmdGVyPT09dm9pZCAwJiZzLmVkZ2VfYmVmb3JlPT09dm9pZCAwJiZzLmVkZ2VfYWZ0ZXIhPT12b2lkIDAmJihpLmVkZ2VfYmVmb3JlLm5leHQ9cy5lZGdlX2FmdGVyLHMuZWRnZV9hZnRlci5wcmV2PWkuZWRnZV9iZWZvcmUsaS5lZGdlX2FmdGVyPXMuZWRnZV9hZnRlcixzLmVkZ2VfYmVmb3JlPWkuZWRnZV9iZWZvcmUpLHMuZWRnZV9iZWZvcmUhPT12b2lkIDAmJnMuZWRnZV9hZnRlcj09PXZvaWQgMCYmaS5lZGdlX2JlZm9yZT09PXZvaWQgMCYmaS5lZGdlX2FmdGVyIT09dm9pZCAwJiYocy5lZGdlX2JlZm9yZS5uZXh0PWkuZWRnZV9hZnRlcixpLmVkZ2VfYWZ0ZXIucHJldj1zLmVkZ2VfYmVmb3JlLHMuZWRnZV9hZnRlcj1pLmVkZ2VfYWZ0ZXIsaS5lZGdlX2JlZm9yZT1zLmVkZ2VfYmVmb3JlKSxpLmVkZ2VfYmVmb3JlIT09dm9pZCAwJiZpLmVkZ2VfYWZ0ZXI9PT12b2lkIDApZm9yKGxldCBvIG9mIG4uaW50X3BvaW50czFfc29ydGVkKW8hPT1pJiZvLmVkZ2VfYmVmb3JlPT09dm9pZCAwJiZvLmVkZ2VfYWZ0ZXIhPT12b2lkIDAmJm8ucHQuZXF1YWxUbyhpLnB0KSYmKGkuZWRnZV9iZWZvcmUubmV4dD1vLmVkZ2VfYWZ0ZXIsby5lZGdlX2FmdGVyLnByZXY9aS5lZGdlX2JlZm9yZSxpLmVkZ2VfYWZ0ZXI9by5lZGdlX2FmdGVyLG8uZWRnZV9iZWZvcmU9aS5lZGdlX2JlZm9yZSk7aWYocy5lZGdlX2JlZm9yZSE9PXZvaWQgMCYmcy5lZGdlX2FmdGVyPT09dm9pZCAwKWZvcihsZXQgbyBvZiBuLmludF9wb2ludHMyX3NvcnRlZClvIT09cyYmby5lZGdlX2JlZm9yZT09PXZvaWQgMCYmby5lZGdlX2FmdGVyIT09dm9pZCAwJiZvLnB0LmVxdWFsVG8ocy5wdCkmJihzLmVkZ2VfYmVmb3JlLm5leHQ9by5lZGdlX2FmdGVyLG8uZWRnZV9hZnRlci5wcmV2PXMuZWRnZV9iZWZvcmUscy5lZGdlX2FmdGVyPW8uZWRnZV9hZnRlcixvLmVkZ2VfYmVmb3JlPXMuZWRnZV9iZWZvcmUpfX1mdW5jdGlvbiB4cihlLHQpe2ZvcihsZXQgbiBvZiB0KWUuZmFjZXMuZGVsZXRlKG4uZmFjZSksbi5mYWNlPXZvaWQgMCxuLmVkZ2VfYmVmb3JlJiYobi5lZGdlX2JlZm9yZS5mYWNlPXZvaWQgMCksbi5lZGdlX2FmdGVyJiYobi5lZGdlX2FmdGVyLmZhY2U9dm9pZCAwKX1mdW5jdGlvbiBNcihlLHQsbil7Zm9yKGxldCByIG9mIHQpe2lmKHIuZWRnZV9iZWZvcmU9PT12b2lkIDB8fHIuZWRnZV9hZnRlcj09PXZvaWQgMHx8ci5mYWNlfHxyLmVkZ2VfYWZ0ZXIuZmFjZXx8ci5lZGdlX2JlZm9yZS5mYWNlKWNvbnRpbnVlO2xldCBpPXIuZWRnZV9hZnRlcixzPXIuZWRnZV9iZWZvcmU7dHJ5e2NyLnRlc3RJbmZpbml0ZUxvb3AoaSl9Y2F0Y2h7dGhyb3cgVS5DQU5OT1RfQ09NUExFVEVfQk9PTEVBTl9PUEVSQVRJT059bGV0IG89ZS5hZGRGYWNlKGkscyk7Zm9yKGxldCBjIG9mIHQpYy5lZGdlX2JlZm9yZSYmYy5lZGdlX2FmdGVyJiZjLmVkZ2VfYmVmb3JlLmZhY2U9PT1vJiZjLmVkZ2VfYWZ0ZXIuZmFjZT09PW8mJihjLmZhY2U9byk7Zm9yKGxldCBjIG9mIG4pYy5lZGdlX2JlZm9yZSYmYy5lZGdlX2FmdGVyJiZjLmVkZ2VfYmVmb3JlLmZhY2U9PT1vJiZjLmVkZ2VfYWZ0ZXIuZmFjZT09PW8mJihjLmZhY2U9byl9fWZ1bmN0aW9uIHlvKGUsdCxuLHIpe2ZvcihsZXQgaSBvZiB0KXtsZXQgcz1pLmZpcnN0LmJ2OyhuPT09Zm4mJnM9PT1ndHx8bj09PVZ0JiZzPT09Z3QmJnJ8fG49PT1WdCYmcz09PW10JiYhcnx8bj09PXhlJiZzPT09bXQpJiZlLmRlbGV0ZUZhY2UoaSl9fXZhciB3ZT1PYmplY3QuZnJlZXplKHtfX3Byb3RvX186bnVsbCxCT09MRUFOX0lOVEVSU0VDVDp4ZSxCT09MRUFOX1NVQlRSQUNUOlZ0LEJPT0xFQU5fVU5JT046Zm4sY2FsY3VsYXRlSW50ZXJzZWN0aW9uczpnbyxpbm5lckNsaXA6dW8saW50ZXJzZWN0OmZvLG91dGVyQ2xpcDpfcixyZW1vdmVOb3RSZWxldmFudENoYWluczp5cixyZW1vdmVPbGRGYWNlczp4cixyZXN0b3JlRmFjZXM6TXIsc3VidHJhY3Q6cHIsdW5pZnk6VWZ9KTtjb25zdCBHZj1SZWdFeHAoIlQuRi4uRkZGLnxULkYuLi5GLi4iKSxYZj1SZWdFeHAoIlQuLi4uLi4uLnwuVC4uLi4uLi58Li4uVC4uLi4ufC4uLi5ULi4uLiIpLGpmPVJlZ0V4cCgiRlQuLi4uLi4ufEYuLlQuLi4uLnxGLi4uVC4uLi4iKSxRZj1SZWdFeHAoIlQuRi4uRi4uLiIpLEtmPVJlZ0V4cCgiVC5GLi5GLi4ufC5URi4uRi4uLnwuLkZULkYuLi58Li5GLlRGLi4uIik7Y2xhc3MgSHR7Y29uc3RydWN0b3IoKXt0aGlzLm09bmV3IEFycmF5KDkpLmZpbGwodm9pZCAwKX1nZXQgSTJJKCl7cmV0dXJuIHRoaXMubVswXX1zZXQgSTJJKHQpe3RoaXMubVswXT10fWdldCBJMkIoKXtyZXR1cm4gdGhpcy5tWzFdfXNldCBJMkIodCl7dGhpcy5tWzFdPXR9Z2V0IEkyRSgpe3JldHVybiB0aGlzLm1bMl19c2V0IEkyRSh0KXt0aGlzLm1bMl09dH1nZXQgQjJJKCl7cmV0dXJuIHRoaXMubVszXX1zZXQgQjJJKHQpe3RoaXMubVszXT10fWdldCBCMkIoKXtyZXR1cm4gdGhpcy5tWzRdfXNldCBCMkIodCl7dGhpcy5tWzRdPXR9Z2V0IEIyRSgpe3JldHVybiB0aGlzLm1bNV19c2V0IEIyRSh0KXt0aGlzLm1bNV09dH1nZXQgRTJJKCl7cmV0dXJuIHRoaXMubVs2XX1zZXQgRTJJKHQpe3RoaXMubVs2XT10fWdldCBFMkIoKXtyZXR1cm4gdGhpcy5tWzddfXNldCBFMkIodCl7dGhpcy5tWzddPXR9Z2V0IEUyRSgpe3JldHVybiB0aGlzLm1bOF19c2V0IEUyRSh0KXt0aGlzLm1bOF09dH10b1N0cmluZygpe3JldHVybiB0aGlzLm0ubWFwKHQ9PnQgaW5zdGFuY2VvZiBBcnJheSYmdC5sZW5ndGg+MD8iVCI6dCBpbnN0YW5jZW9mIEFycmF5JiZ0Lmxlbmd0aD09PTA/IkYiOiIqIikuam9pbigiIil9ZXF1YWwoKXtyZXR1cm4gR2YudGVzdCh0aGlzLnRvU3RyaW5nKCkpfWludGVyc2VjdCgpe3JldHVybiBYZi50ZXN0KHRoaXMudG9TdHJpbmcoKSl9dG91Y2goKXtyZXR1cm4gamYudGVzdCh0aGlzLnRvU3RyaW5nKCkpfWluc2lkZSgpe3JldHVybiBRZi50ZXN0KHRoaXMudG9TdHJpbmcoKSl9Y292ZXJlZCgpe3JldHVybiBLZi50ZXN0KHRoaXMudG9TdHJpbmcoKSl9fWZ1bmN0aW9uIEFlKGUsdCl7bGV0IG4scj1uZXcgYS5SYXkodCksaT1uZXcgYS5MaW5lKHIucHQsci5ub3JtKTtjb25zdCBzPW5ldyBhLkJveChyLmJveC54bWluLWEuRFBfVE9MLHIuYm94LnltaW4tYS5EUF9UT0wsci5ib3gueG1heCxyLmJveC55bWF4K2EuRFBfVE9MKTtpZihlLmJveC5ub3RfaW50ZXJzZWN0KHMpKXJldHVybiBhLk9VVFNJREU7bGV0IG89ZS5lZGdlcy5zZWFyY2gocyk7aWYoby5sZW5ndGg9PT0wKXJldHVybiBhLk9VVFNJREU7Zm9yKGxldCBmIG9mIG8paWYoZi5zaGFwZS5jb250YWlucyh0KSlyZXR1cm4gYS5CT1VOREFSWTtsZXQgYz1bLi4uZS5mYWNlc10sbD1bXTtmb3IobGV0IGYgb2Ygbylmb3IobGV0IHUgb2Ygci5pbnRlcnNlY3QoZi5zaGFwZSkpe2lmKHUuZXF1YWxUbyh0KSlyZXR1cm4gYS5CT1VOREFSWTtsLnB1c2goe3B0OnUsZWRnZTpmLGZhY2VfaW5kZXg6Yy5pbmRleE9mKGYuZmFjZSl9KX1sLnNvcnQoKGYsdSk9PlpzKGYucHQueCx1LnB0LngpPy0xOldzKGYucHQueCx1LnB0LngpPzE6Zi5mYWNlX2luZGV4PHUuZmFjZV9pbmRleD8tMTpmLmZhY2VfaW5kZXg+dS5mYWNlX2luZGV4PzE6Zi5lZGdlLmFyY19sZW5ndGg8dS5lZGdlLmFyY19sZW5ndGg/LTE6Zi5lZGdlLmFyY19sZW5ndGg+dS5lZGdlLmFyY19sZW5ndGg/MTowKTtsZXQgaD0wO2ZvcihsZXQgZj0wO2Y8bC5sZW5ndGg7ZisrKXtsZXQgdT1sW2ZdO2lmKHUucHQuZXF1YWxUbyh1LmVkZ2Uuc2hhcGUuc3RhcnQpKXtpZihmPjAmJnUucHQuZXF1YWxUbyhsW2YtMV0ucHQpJiZ1LmZhY2VfaW5kZXg9PT1sW2YtMV0uZmFjZV9pbmRleCYmdS5lZGdlLnByZXY9PT1sW2YtMV0uZWRnZSljb250aW51ZTtsZXQgZD11LmVkZ2UucHJldjtmb3IoO29yKGQubGVuZ3RoKTspZD1kLnByZXY7bGV0IGc9ZC5zaGFwZS50YW5nZW50SW5FbmQoKSxtPXUucHQudHJhbnNsYXRlKGcpLF89dS5lZGdlLnNoYXBlLnRhbmdlbnRJblN0YXJ0KCkscD11LnB0LnRyYW5zbGF0ZShfKSxNPW0ubGVmdFRvKGkpLEE9cC5sZWZ0VG8oaSk7KE0mJiFBfHwhTSYmQSkmJmgrK31lbHNlIGlmKHUucHQuZXF1YWxUbyh1LmVkZ2Uuc2hhcGUuZW5kKSl7aWYoZj4wJiZ1LnB0LmVxdWFsVG8obFtmLTFdLnB0KSYmdS5mYWNlX2luZGV4PT09bFtmLTFdLmZhY2VfaW5kZXgmJnUuZWRnZS5uZXh0PT09bFtmLTFdLmVkZ2UpY29udGludWU7bGV0IGQ9dS5lZGdlLm5leHQ7Zm9yKDtvcihkLmxlbmd0aCk7KWQ9ZC5uZXh0O2xldCBnPWQuc2hhcGUudGFuZ2VudEluU3RhcnQoKSxtPXUucHQudHJhbnNsYXRlKGcpLF89dS5lZGdlLnNoYXBlLnRhbmdlbnRJbkVuZCgpLHA9dS5wdC50cmFuc2xhdGUoXyksTT1tLmxlZnRUbyhpKSxBPXAubGVmdFRvKGkpOyhNJiYhQXx8IU0mJkEpJiZoKyt9ZWxzZSBpZih1LmVkZ2Uuc2hhcGUgaW5zdGFuY2VvZiBhLlNlZ21lbnQpaCsrO2Vsc2V7bGV0IGQ9dS5lZGdlLnNoYXBlLmJveDtMdCh1LnB0LnksZC55bWluKXx8THQodS5wdC55LGQueW1heCl8fGgrK319cmV0dXJuIG49aCUyPT09MT9vbjpEcyxufWZ1bmN0aW9uIEpmKGUsdCl7cmV0dXJuIHRlKGUsdCkuZXF1YWwoKX1mdW5jdGlvbiB4byhlLHQpe3JldHVybiB0ZShlLHQpLmludGVyc2VjdCgpfWZ1bmN0aW9uIEhmKGUsdCl7cmV0dXJuIHRlKGUsdCkudG91Y2goKX1mdW5jdGlvbiB0dShlLHQpe3JldHVybiF4byhlLHQpfWZ1bmN0aW9uIE1vKGUsdCl7cmV0dXJuIHRlKGUsdCkuaW5zaWRlKCl9ZnVuY3Rpb24gd28oZSx0KXtyZXR1cm4gdGUoZSx0KS5jb3ZlcmVkKCl9ZnVuY3Rpb24gZXUoZSx0KXtyZXR1cm4gTW8odCxlKX1mdW5jdGlvbiBBbyhlLHQpe3JldHVybiB3byh0LGUpfWZ1bmN0aW9uIHRlKGUsdCl7aWYoZSBpbnN0YW5jZW9mIGEuTGluZSYmdCBpbnN0YW5jZW9mIGEuTGluZSlyZXR1cm4gbnUoZSx0KTtpZihlIGluc3RhbmNlb2YgYS5MaW5lJiZ0IGluc3RhbmNlb2YgYS5DaXJjbGUpcmV0dXJuIHJ1KGUsdCk7aWYoZSBpbnN0YW5jZW9mIGEuTGluZSYmdCBpbnN0YW5jZW9mIGEuQm94KXJldHVybiBpdShlLHQpO2lmKGUgaW5zdGFuY2VvZiBhLkxpbmUmJnQgaW5zdGFuY2VvZiBhLlBvbHlnb24pcmV0dXJuIHN1KGUsdCk7aWYoKGUgaW5zdGFuY2VvZiBhLlNlZ21lbnR8fGUgaW5zdGFuY2VvZiBhLkFyYykmJnQgaW5zdGFuY2VvZiBhLlBvbHlnb24pcmV0dXJuIFRvKGUsdCk7aWYoKGUgaW5zdGFuY2VvZiBhLlNlZ21lbnR8fGUgaW5zdGFuY2VvZiBhLkFyYykmJih0IGluc3RhbmNlb2YgYS5DaXJjbGV8fHQgaW5zdGFuY2VvZiBhLkJveCkpcmV0dXJuIFRvKGUsbmV3IGEuUG9seWdvbih0KSk7aWYoZSBpbnN0YW5jZW9mIGEuUG9seWdvbiYmdCBpbnN0YW5jZW9mIGEuUG9seWdvbilyZXR1cm4gdW4oZSx0KTtpZigoZSBpbnN0YW5jZW9mIGEuQ2lyY2xlfHxlIGluc3RhbmNlb2YgYS5Cb3gpJiYodCBpbnN0YW5jZW9mIGEuQ2lyY2xlfHx0IGluc3RhbmNlb2YgYS5Cb3gpKXJldHVybiB1bihuZXcgYS5Qb2x5Z29uKGUpLG5ldyBhLlBvbHlnb24odCkpO2lmKChlIGluc3RhbmNlb2YgYS5DaXJjbGV8fGUgaW5zdGFuY2VvZiBhLkJveCkmJnQgaW5zdGFuY2VvZiBhLlBvbHlnb24pcmV0dXJuIHVuKG5ldyBhLlBvbHlnb24oZSksdCk7aWYoZSBpbnN0YW5jZW9mIGEuUG9seWdvbiYmKHQgaW5zdGFuY2VvZiBhLkNpcmNsZXx8dCBpbnN0YW5jZW9mIGEuQm94KSlyZXR1cm4gdW4oZSxuZXcgYS5Qb2x5Z29uKHQpKX1mdW5jdGlvbiBudShlLHQpe2xldCBuPW5ldyBIdCxyPUd0KGUsdCk7cmV0dXJuIHIubGVuZ3RoPT09MD9lLmNvbnRhaW5zKHQucHQpJiZ0LmNvbnRhaW5zKGUucHQpPyhuLkkyST1bZV0sbi5JMkU9W10sbi5FMkk9W10pOihuLkkyST1bXSxuLkkyRT1bZV0sbi5FMkk9W3RdKToobi5JMkk9cixuLkkyRT1lLnNwbGl0KHIpLG4uRTJJPXQuc3BsaXQocikpLG59ZnVuY3Rpb24gcnUoZSx0KXtsZXQgbj1uZXcgSHQscj1SdChlLHQpO2lmKHIubGVuZ3RoPT09MCluLkkyST1bXSxuLkkyQj1bXSxuLkkyRT1bZV0sbi5FMkk9W3RdO2Vsc2UgaWYoci5sZW5ndGg9PT0xKW4uSTJJPVtdLG4uSTJCPXIsbi5JMkU9ZS5zcGxpdChyKSxuLkUyST1bdF07ZWxzZXtsZXQgaT1uZXcgQ3QoW2VdKSxzPWUuc29ydFBvaW50cyhyKTtpLnNwbGl0KHMpO2xldCBvPWkudG9TaGFwZXMoKTtuLkkyST1bb1sxXV0sbi5JMkI9cyxuLkkyRT1bb1swXSxvWzJdXSxuLkUyST1uZXcgYS5Qb2x5Z29uKFt0LnRvQXJjKCldKS5jdXRXaXRoTGluZShlKX1yZXR1cm4gbn1mdW5jdGlvbiBpdShlLHQpe2xldCBuPW5ldyBIdCxyPVh0KGUsdCk7aWYoci5sZW5ndGg9PT0wKW4uSTJJPVtdLG4uSTJCPVtdLG4uSTJFPVtlXSxuLkUyST1bdF07ZWxzZSBpZihyLmxlbmd0aD09PTEpbi5JMkk9W10sbi5JMkI9cixuLkkyRT1lLnNwbGl0KHIpLG4uRTJJPVt0XTtlbHNle2xldCBpPW5ldyBDdChbZV0pLHM9ZS5zb3J0UG9pbnRzKHIpO2kuc3BsaXQocyk7bGV0IG89aS50b1NoYXBlcygpO3QudG9TZWdtZW50cygpLnNvbWUoYz0+Yy5jb250YWlucyhyWzBdKSYmYy5jb250YWlucyhyWzFdKSk/KG4uSTJJPVtdLG4uSTJCPVtvWzFdXSxuLkkyRT1bb1swXSxvWzJdXSxuLkUyST1bdF0pOihuLkkyST1bb1sxXV0sbi5JMkI9cyxuLkkyRT1bb1swXSxvWzJdXSxuLkUyST1uZXcgYS5Qb2x5Z29uKHQudG9TZWdtZW50cygpKS5jdXRXaXRoTGluZShlKSl9cmV0dXJuIG59ZnVuY3Rpb24gc3UoZSx0KXtsZXQgbj1uZXcgSHQscj1wZShlLHQpLGk9bmV3IEN0KFtlXSkscz1yLmxlbmd0aD4wP3Iuc2xpY2UoKTplLnNvcnRQb2ludHMocik7cmV0dXJuIGkuc3BsaXQocyksWy4uLmldLmZvckVhY2gobz0+by5zZXRJbmNsdXNpb24odCkpLG4uSTJJPVsuLi5pXS5maWx0ZXIobz0+by5idj09PWEuSU5TSURFKS5tYXAobz0+by5zaGFwZSksbi5JMkI9Wy4uLmldLnNsaWNlKDEpLm1hcChvPT5vLmJ2PT09YS5CT1VOREFSWT9vLnNoYXBlOm8uc2hhcGUuc3RhcnQpLG4uSTJFPVsuLi5pXS5maWx0ZXIobz0+by5idj09PWEuT1VUU0lERSkubWFwKG89Pm8uc2hhcGUpLG4uRTJJPXQuY3V0V2l0aExpbmUoZSksbn1mdW5jdGlvbiBUbyhlLHQpe2xldCBuPW5ldyBIdCxyPVJmKGUsdCksaT1yLmxlbmd0aD4wP3Iuc2xpY2UoKTplLnNvcnRQb2ludHMocikscz1uZXcgQ3QoW2VdKTtzLnNwbGl0KGkpLFsuLi5zXS5mb3JFYWNoKG89Pm8uc2V0SW5jbHVzaW9uKHQpKSxuLkkyST1bLi4uc10uZmlsdGVyKG89Pm8uYnY9PT1hLklOU0lERSkubWFwKG89Pm8uc2hhcGUpLG4uSTJCPVsuLi5zXS5zbGljZSgxKS5tYXAobz0+by5idj09PWEuQk9VTkRBUlk/by5zaGFwZTpvLnNoYXBlLnN0YXJ0KSxuLkkyRT1bLi4uc10uZmlsdGVyKG89Pm8uYnY9PT1hLk9VVFNJREUpLm1hcChvPT5vLnNoYXBlKSxuLkIyST1bXSxuLkIyQj1bXSxuLkIyRT1bXTtmb3IobGV0IG8gb2ZbZS5zdGFydCxlLmVuZF0pc3dpdGNoKEFlKHQsbykpe2Nhc2UgYS5JTlNJREU6bi5CMkkucHVzaChvKTticmVhaztjYXNlIGEuQk9VTkRBUlk6bi5CMkIucHVzaChvKTticmVhaztjYXNlIGEuT1VUU0lERTpuLkIyRS5wdXNoKG8pO2JyZWFrfXJldHVybiBufWZ1bmN0aW9uIHVuKGUsdCl7bGV0IG49bmV3IEh0LFtyLGldPWdvKGUsdCkscz1mbyhlLHQpLG89cHIoZSx0KSxjPXByKHQsZSksW2wsaF09dW8oZSx0KSxmPV9yKGUsdCksdT1fcih0LGUpO3JldHVybiBuLkkyST1zLmlzRW1wdHkoKT9bXTpbc10sbi5JMkI9aCxuLkkyRT1vLmlzRW1wdHkoKT9bXTpbb10sbi5CMkk9bCxuLkIyQj1yLG4uQjJFPWYsbi5FMkk9Yy5pc0VtcHR5KCk/W106W2NdLG4uRTJCPXUsbn12YXIgb3U9T2JqZWN0LmZyZWV6ZSh7X19wcm90b19fOm51bGwsY29udGFpbjpldSxjb3ZlcjpBbyxjb3ZlcmVkOndvLGRpc2pvaW50OnR1LGVxdWFsOkpmLGluc2lkZTpNbyxpbnRlcnNlY3Q6eG8scmVsYXRlOnRlLHRvdWNoOkhmfSk7Y2xhc3MgcnR7Y29uc3RydWN0b3IodD0xLG49MCxyPTAsaT0xLHM9MCxvPTApe3RoaXMuYT10LHRoaXMuYj1uLHRoaXMuYz1yLHRoaXMuZD1pLHRoaXMudHg9cyx0aGlzLnR5PW99Y2xvbmUoKXtyZXR1cm4gbmV3IHJ0KHRoaXMuYSx0aGlzLmIsdGhpcy5jLHRoaXMuZCx0aGlzLnR4LHRoaXMudHkpfXRyYW5zZm9ybSh0KXtyZXR1cm5bdFswXSp0aGlzLmErdFsxXSp0aGlzLmMrdGhpcy50eCx0WzBdKnRoaXMuYit0WzFdKnRoaXMuZCt0aGlzLnR5XX1tdWx0aXBseSh0KXtyZXR1cm4gbmV3IHJ0KHRoaXMuYSp0LmErdGhpcy5jKnQuYix0aGlzLmIqdC5hK3RoaXMuZCp0LmIsdGhpcy5hKnQuYyt0aGlzLmMqdC5kLHRoaXMuYip0LmMrdGhpcy5kKnQuZCx0aGlzLmEqdC50eCt0aGlzLmMqdC50eSt0aGlzLnR4LHRoaXMuYip0LnR4K3RoaXMuZCp0LnR5K3RoaXMudHkpfXRyYW5zbGF0ZSguLi50KXtsZXQgbixyO2lmKHQubGVuZ3RoPT0xJiYhaXNOYU4odFswXS54KSYmIWlzTmFOKHRbMF0ueSkpbj10WzBdLngscj10WzBdLnk7ZWxzZSBpZih0Lmxlbmd0aD09PTImJnR5cGVvZiB0WzBdPT0ibnVtYmVyIiYmdHlwZW9mIHRbMV09PSJudW1iZXIiKW49dFswXSxyPXRbMV07ZWxzZSB0aHJvdyBVLklMTEVHQUxfUEFSQU1FVEVSUztyZXR1cm4gdGhpcy5tdWx0aXBseShuZXcgcnQoMSwwLDAsMSxuLHIpKX1yb3RhdGUodCxuPTAscj0wKXtsZXQgaT1NYXRoLmNvcyh0KSxzPU1hdGguc2luKHQpO3JldHVybiB0aGlzLnRyYW5zbGF0ZShuLHIpLm11bHRpcGx5KG5ldyBydChpLHMsLXMsaSwwLDApKS50cmFuc2xhdGUoLW4sLXIpfXNjYWxlKHQsbil7cmV0dXJuIHRoaXMubXVsdGlwbHkobmV3IHJ0KHQsMCwwLG4sMCwwKSl9ZXF1YWxUbyh0KXtyZXR1cm4hKCFhLlV0aWxzLkVRKHRoaXMudHgsdC50eCl8fCFhLlV0aWxzLkVRKHRoaXMudHksdC50eSl8fCFhLlV0aWxzLkVRKHRoaXMuYSx0LmEpfHwhYS5VdGlscy5FUSh0aGlzLmIsdC5iKXx8IWEuVXRpbHMuRVEodGhpcy5jLHQuYyl8fCFhLlV0aWxzLkVRKHRoaXMuZCx0LmQpKX19YS5NYXRyaXg9cnQ7Y29uc3QgY3U9KC4uLmUpPT5uZXcgYS5NYXRyaXgoLi4uZSk7YS5tYXRyaXg9Y3U7Y29uc3QgYXU9Y2xhc3MgQ3J7Y29uc3RydWN0b3IodCxuKXt0aGlzLmxvdz10LHRoaXMuaGlnaD1ufWNsb25lKCl7cmV0dXJuIG5ldyBDcih0aGlzLmxvdyx0aGlzLmhpZ2gpfWdldCBtYXgoKXtyZXR1cm4gdGhpcy5jbG9uZSgpfWxlc3NfdGhhbih0KXtyZXR1cm4gdGhpcy5sb3c8dC5sb3d8fHRoaXMubG93PT10LmxvdyYmdGhpcy5oaWdoPHQuaGlnaH1lcXVhbF90byh0KXtyZXR1cm4gdGhpcy5sb3c9PXQubG93JiZ0aGlzLmhpZ2g9PXQuaGlnaH1pbnRlcnNlY3QodCl7cmV0dXJuIXRoaXMubm90X2ludGVyc2VjdCh0KX1ub3RfaW50ZXJzZWN0KHQpe3JldHVybiB0aGlzLmhpZ2g8dC5sb3d8fHQuaGlnaDx0aGlzLmxvd31tZXJnZSh0KXtyZXR1cm4gbmV3IENyKHRoaXMubG93PT09dm9pZCAwP3QubG93Ok1hdGgubWluKHRoaXMubG93LHQubG93KSx0aGlzLmhpZ2g9PT12b2lkIDA/dC5oaWdoOk1hdGgubWF4KHRoaXMuaGlnaCx0LmhpZ2gpKX1vdXRwdXQoKXtyZXR1cm5bdGhpcy5sb3csdGhpcy5oaWdoXX1zdGF0aWMgY29tcGFyYWJsZV9tYXgodCxuKXtyZXR1cm4gdC5tZXJnZShuKX1zdGF0aWMgY29tcGFyYWJsZV9sZXNzX3RoYW4odCxuKXtyZXR1cm4gdDxufX0sSz0wLHo9MTtjbGFzcyBlZXtjb25zdHJ1Y3Rvcih0PXZvaWQgMCxuPXZvaWQgMCxyPW51bGwsaT1udWxsLHM9bnVsbCxvPXope3RoaXMubGVmdD1yLHRoaXMucmlnaHQ9aSx0aGlzLnBhcmVudD1zLHRoaXMuY29sb3I9byx0aGlzLml0ZW09e2tleTp0LHZhbHVlOm59LHQmJnQgaW5zdGFuY2VvZiBBcnJheSYmdC5sZW5ndGg9PTImJiFOdW1iZXIuaXNOYU4odFswXSkmJiFOdW1iZXIuaXNOYU4odFsxXSkmJih0aGlzLml0ZW0ua2V5PW5ldyBhdShNYXRoLm1pbih0WzBdLHRbMV0pLE1hdGgubWF4KHRbMF0sdFsxXSkpKSx0aGlzLm1heD10aGlzLml0ZW0ua2V5P3RoaXMuaXRlbS5rZXkubWF4OnZvaWQgMH1pc05pbCgpe3JldHVybiB0aGlzLml0ZW0ua2V5PT09dm9pZCAwJiZ0aGlzLml0ZW0udmFsdWU9PT12b2lkIDAmJnRoaXMubGVmdD09PW51bGwmJnRoaXMucmlnaHQ9PT1udWxsJiZ0aGlzLmNvbG9yPT09en1fdmFsdWVfbGVzc190aGFuKHQpe3JldHVybiB0aGlzLml0ZW0udmFsdWUmJnQuaXRlbS52YWx1ZSYmdGhpcy5pdGVtLnZhbHVlLmxlc3NfdGhhbj90aGlzLml0ZW0udmFsdWUubGVzc190aGFuKHQuaXRlbS52YWx1ZSk6dGhpcy5pdGVtLnZhbHVlPHQuaXRlbS52YWx1ZX1sZXNzX3RoYW4odCl7cmV0dXJuIHRoaXMuaXRlbS52YWx1ZT09PXRoaXMuaXRlbS5rZXkmJnQuaXRlbS52YWx1ZT09PXQuaXRlbS5rZXk/dGhpcy5pdGVtLmtleS5sZXNzX3RoYW4odC5pdGVtLmtleSk6dGhpcy5pdGVtLmtleS5sZXNzX3RoYW4odC5pdGVtLmtleSl8fHRoaXMuaXRlbS5rZXkuZXF1YWxfdG8odC5pdGVtLmtleSkmJnRoaXMuX3ZhbHVlX2xlc3NfdGhhbih0KX1fdmFsdWVfZXF1YWwodCl7cmV0dXJuIHRoaXMuaXRlbS52YWx1ZSYmdC5pdGVtLnZhbHVlJiZ0aGlzLml0ZW0udmFsdWUuZXF1YWxfdG8/dGhpcy5pdGVtLnZhbHVlLmVxdWFsX3RvKHQuaXRlbS52YWx1ZSk6dGhpcy5pdGVtLnZhbHVlPT10Lml0ZW0udmFsdWV9ZXF1YWxfdG8odCl7cmV0dXJuIHRoaXMuaXRlbS52YWx1ZT09PXRoaXMuaXRlbS5rZXkmJnQuaXRlbS52YWx1ZT09PXQuaXRlbS5rZXk/dGhpcy5pdGVtLmtleS5lcXVhbF90byh0Lml0ZW0ua2V5KTp0aGlzLml0ZW0ua2V5LmVxdWFsX3RvKHQuaXRlbS5rZXkpJiZ0aGlzLl92YWx1ZV9lcXVhbCh0KX1pbnRlcnNlY3QodCl7cmV0dXJuIHRoaXMuaXRlbS5rZXkuaW50ZXJzZWN0KHQuaXRlbS5rZXkpfWNvcHlfZGF0YSh0KXt0aGlzLml0ZW0ua2V5PXQuaXRlbS5rZXksdGhpcy5pdGVtLnZhbHVlPXQuaXRlbS52YWx1ZX11cGRhdGVfbWF4KCl7aWYodGhpcy5tYXg9dGhpcy5pdGVtLmtleT90aGlzLml0ZW0ua2V5Lm1heDp2b2lkIDAsdGhpcy5yaWdodCYmdGhpcy5yaWdodC5tYXgpe2NvbnN0IHQ9dGhpcy5pdGVtLmtleS5jb25zdHJ1Y3Rvci5jb21wYXJhYmxlX21heDt0aGlzLm1heD10KHRoaXMubWF4LHRoaXMucmlnaHQubWF4KX1pZih0aGlzLmxlZnQmJnRoaXMubGVmdC5tYXgpe2NvbnN0IHQ9dGhpcy5pdGVtLmtleS5jb25zdHJ1Y3Rvci5jb21wYXJhYmxlX21heDt0aGlzLm1heD10KHRoaXMubWF4LHRoaXMubGVmdC5tYXgpfX1ub3RfaW50ZXJzZWN0X2xlZnRfc3VidHJlZSh0KXtjb25zdCBuPXRoaXMuaXRlbS5rZXkuY29uc3RydWN0b3IuY29tcGFyYWJsZV9sZXNzX3RoYW47bGV0IHI9dGhpcy5sZWZ0Lm1heC5oaWdoIT09dm9pZCAwP3RoaXMubGVmdC5tYXguaGlnaDp0aGlzLmxlZnQubWF4O3JldHVybiBuKHIsdC5pdGVtLmtleS5sb3cpfW5vdF9pbnRlcnNlY3RfcmlnaHRfc3VidHJlZSh0KXtjb25zdCBuPXRoaXMuaXRlbS5rZXkuY29uc3RydWN0b3IuY29tcGFyYWJsZV9sZXNzX3RoYW47bGV0IHI9dGhpcy5yaWdodC5tYXgubG93IT09dm9pZCAwP3RoaXMucmlnaHQubWF4Lmxvdzp0aGlzLnJpZ2h0Lml0ZW0ua2V5LmxvdztyZXR1cm4gbih0Lml0ZW0ua2V5LmhpZ2gscil9fWNsYXNzIFRle2NvbnN0cnVjdG9yKCl7dGhpcy5yb290PW51bGwsdGhpcy5uaWxfbm9kZT1uZXcgZWV9Z2V0IHNpemUoKXtsZXQgdD0wO3JldHVybiB0aGlzLnRyZWVfd2Fsayh0aGlzLnJvb3QsKCk9PnQrKyksdH1nZXQga2V5cygpe2xldCB0PVtdO3JldHVybiB0aGlzLnRyZWVfd2Fsayh0aGlzLnJvb3Qsbj0+dC5wdXNoKG4uaXRlbS5rZXkub3V0cHV0P24uaXRlbS5rZXkub3V0cHV0KCk6bi5pdGVtLmtleSkpLHR9Z2V0IHZhbHVlcygpe2xldCB0PVtdO3JldHVybiB0aGlzLnRyZWVfd2Fsayh0aGlzLnJvb3Qsbj0+dC5wdXNoKG4uaXRlbS52YWx1ZSkpLHR9Z2V0IGl0ZW1zKCl7bGV0IHQ9W107cmV0dXJuIHRoaXMudHJlZV93YWxrKHRoaXMucm9vdCxuPT50LnB1c2goe2tleTpuLml0ZW0ua2V5Lm91dHB1dD9uLml0ZW0ua2V5Lm91dHB1dCgpOm4uaXRlbS5rZXksdmFsdWU6bi5pdGVtLnZhbHVlfSkpLHR9aXNFbXB0eSgpe3JldHVybiB0aGlzLnJvb3Q9PW51bGx8fHRoaXMucm9vdD09dGhpcy5uaWxfbm9kZX1jbGVhcigpe3RoaXMucm9vdD1udWxsfWluc2VydCh0LG49dCl7aWYodD09PXZvaWQgMClyZXR1cm47bGV0IHI9bmV3IGVlKHQsbix0aGlzLm5pbF9ub2RlLHRoaXMubmlsX25vZGUsbnVsbCxLKTtyZXR1cm4gdGhpcy50cmVlX2luc2VydChyKSx0aGlzLnJlY2FsY19tYXgocikscn1leGlzdCh0LG49dCl7bGV0IHI9bmV3IGVlKHQsbik7cmV0dXJuISF0aGlzLnRyZWVfc2VhcmNoKHRoaXMucm9vdCxyKX1yZW1vdmUodCxuPXQpe2xldCByPW5ldyBlZSh0LG4pLGk9dGhpcy50cmVlX3NlYXJjaCh0aGlzLnJvb3Qscik7cmV0dXJuIGkmJnRoaXMudHJlZV9kZWxldGUoaSksaX1zZWFyY2godCxuPShyLGkpPT5yPT09aT9pLm91dHB1dCgpOnIpe2xldCByPW5ldyBlZSh0KSxpPVtdO3JldHVybiB0aGlzLnRyZWVfc2VhcmNoX2ludGVydmFsKHRoaXMucm9vdCxyLGkpLGkubWFwKHM9Pm4ocy5pdGVtLnZhbHVlLHMuaXRlbS5rZXkpKX1pbnRlcnNlY3RfYW55KHQpe2xldCBuPW5ldyBlZSh0KTtyZXR1cm4gdGhpcy50cmVlX2ZpbmRfYW55X2ludGVydmFsKHRoaXMucm9vdCxuKX1mb3JFYWNoKHQpe3RoaXMudHJlZV93YWxrKHRoaXMucm9vdCxuPT50KG4uaXRlbS5rZXksbi5pdGVtLnZhbHVlKSl9bWFwKHQpe2NvbnN0IG49bmV3IFRlO3JldHVybiB0aGlzLnRyZWVfd2Fsayh0aGlzLnJvb3Qscj0+bi5pbnNlcnQoci5pdGVtLmtleSx0KHIuaXRlbS52YWx1ZSxyLml0ZW0ua2V5KSkpLG59cmVjYWxjX21heCh0KXtsZXQgbj10O2Zvcig7bi5wYXJlbnQhPW51bGw7KW4ucGFyZW50LnVwZGF0ZV9tYXgoKSxuPW4ucGFyZW50fXRyZWVfaW5zZXJ0KHQpe2xldCBuPXRoaXMucm9vdCxyPW51bGw7aWYodGhpcy5yb290PT1udWxsfHx0aGlzLnJvb3Q9PXRoaXMubmlsX25vZGUpdGhpcy5yb290PXQ7ZWxzZXtmb3IoO24hPXRoaXMubmlsX25vZGU7KXI9bix0Lmxlc3NfdGhhbihuKT9uPW4ubGVmdDpuPW4ucmlnaHQ7dC5wYXJlbnQ9cix0Lmxlc3NfdGhhbihyKT9yLmxlZnQ9dDpyLnJpZ2h0PXR9dGhpcy5pbnNlcnRfZml4dXAodCl9aW5zZXJ0X2ZpeHVwKHQpe2xldCBuLHI7Zm9yKG49dDtuIT10aGlzLnJvb3QmJm4ucGFyZW50LmNvbG9yPT1LOyluLnBhcmVudD09bi5wYXJlbnQucGFyZW50LmxlZnQ/KHI9bi5wYXJlbnQucGFyZW50LnJpZ2h0LHIuY29sb3I9PUs/KG4ucGFyZW50LmNvbG9yPXosci5jb2xvcj16LG4ucGFyZW50LnBhcmVudC5jb2xvcj1LLG49bi5wYXJlbnQucGFyZW50KToobj09bi5wYXJlbnQucmlnaHQmJihuPW4ucGFyZW50LHRoaXMucm90YXRlX2xlZnQobikpLG4ucGFyZW50LmNvbG9yPXosbi5wYXJlbnQucGFyZW50LmNvbG9yPUssdGhpcy5yb3RhdGVfcmlnaHQobi5wYXJlbnQucGFyZW50KSkpOihyPW4ucGFyZW50LnBhcmVudC5sZWZ0LHIuY29sb3I9PUs/KG4ucGFyZW50LmNvbG9yPXosci5jb2xvcj16LG4ucGFyZW50LnBhcmVudC5jb2xvcj1LLG49bi5wYXJlbnQucGFyZW50KToobj09bi5wYXJlbnQubGVmdCYmKG49bi5wYXJlbnQsdGhpcy5yb3RhdGVfcmlnaHQobikpLG4ucGFyZW50LmNvbG9yPXosbi5wYXJlbnQucGFyZW50LmNvbG9yPUssdGhpcy5yb3RhdGVfbGVmdChuLnBhcmVudC5wYXJlbnQpKSk7dGhpcy5yb290LmNvbG9yPXp9dHJlZV9kZWxldGUodCl7bGV0IG4scjt0LmxlZnQ9PXRoaXMubmlsX25vZGV8fHQucmlnaHQ9PXRoaXMubmlsX25vZGU/bj10Om49dGhpcy50cmVlX3N1Y2Nlc3Nvcih0KSxuLmxlZnQhPXRoaXMubmlsX25vZGU/cj1uLmxlZnQ6cj1uLnJpZ2h0LHIucGFyZW50PW4ucGFyZW50LG49PXRoaXMucm9vdD90aGlzLnJvb3Q9cjoobj09bi5wYXJlbnQubGVmdD9uLnBhcmVudC5sZWZ0PXI6bi5wYXJlbnQucmlnaHQ9cixuLnBhcmVudC51cGRhdGVfbWF4KCkpLHRoaXMucmVjYWxjX21heChyKSxuIT10JiYodC5jb3B5X2RhdGEobiksdC51cGRhdGVfbWF4KCksdGhpcy5yZWNhbGNfbWF4KHQpKSxuLmNvbG9yPT16JiZ0aGlzLmRlbGV0ZV9maXh1cChyKX1kZWxldGVfZml4dXAodCl7bGV0IG49dCxyO2Zvcig7biE9dGhpcy5yb290JiZuLnBhcmVudCE9bnVsbCYmbi5jb2xvcj09ejspbj09bi5wYXJlbnQubGVmdD8ocj1uLnBhcmVudC5yaWdodCxyLmNvbG9yPT1LJiYoci5jb2xvcj16LG4ucGFyZW50LmNvbG9yPUssdGhpcy5yb3RhdGVfbGVmdChuLnBhcmVudCkscj1uLnBhcmVudC5yaWdodCksci5sZWZ0LmNvbG9yPT16JiZyLnJpZ2h0LmNvbG9yPT16PyhyLmNvbG9yPUssbj1uLnBhcmVudCk6KHIucmlnaHQuY29sb3I9PXomJihyLmNvbG9yPUssci5sZWZ0LmNvbG9yPXosdGhpcy5yb3RhdGVfcmlnaHQocikscj1uLnBhcmVudC5yaWdodCksci5jb2xvcj1uLnBhcmVudC5jb2xvcixuLnBhcmVudC5jb2xvcj16LHIucmlnaHQuY29sb3I9eix0aGlzLnJvdGF0ZV9sZWZ0KG4ucGFyZW50KSxuPXRoaXMucm9vdCkpOihyPW4ucGFyZW50LmxlZnQsci5jb2xvcj09SyYmKHIuY29sb3I9eixuLnBhcmVudC5jb2xvcj1LLHRoaXMucm90YXRlX3JpZ2h0KG4ucGFyZW50KSxyPW4ucGFyZW50LmxlZnQpLHIubGVmdC5jb2xvcj09eiYmci5yaWdodC5jb2xvcj09ej8oci5jb2xvcj1LLG49bi5wYXJlbnQpOihyLmxlZnQuY29sb3I9PXomJihyLmNvbG9yPUssci5yaWdodC5jb2xvcj16LHRoaXMucm90YXRlX2xlZnQocikscj1uLnBhcmVudC5sZWZ0KSxyLmNvbG9yPW4ucGFyZW50LmNvbG9yLG4ucGFyZW50LmNvbG9yPXosci5sZWZ0LmNvbG9yPXosdGhpcy5yb3RhdGVfcmlnaHQobi5wYXJlbnQpLG49dGhpcy5yb290KSk7bi5jb2xvcj16fXRyZWVfc2VhcmNoKHQsbil7aWYoISh0PT1udWxsfHx0PT10aGlzLm5pbF9ub2RlKSlyZXR1cm4gbi5lcXVhbF90byh0KT90Om4ubGVzc190aGFuKHQpP3RoaXMudHJlZV9zZWFyY2godC5sZWZ0LG4pOnRoaXMudHJlZV9zZWFyY2godC5yaWdodCxuKX10cmVlX3NlYXJjaF9pbnRlcnZhbCh0LG4scil7dCE9bnVsbCYmdCE9dGhpcy5uaWxfbm9kZSYmKHQubGVmdCE9dGhpcy5uaWxfbm9kZSYmIXQubm90X2ludGVyc2VjdF9sZWZ0X3N1YnRyZWUobikmJnRoaXMudHJlZV9zZWFyY2hfaW50ZXJ2YWwodC5sZWZ0LG4sciksdC5pbnRlcnNlY3QobikmJnIucHVzaCh0KSx0LnJpZ2h0IT10aGlzLm5pbF9ub2RlJiYhdC5ub3RfaW50ZXJzZWN0X3JpZ2h0X3N1YnRyZWUobikmJnRoaXMudHJlZV9zZWFyY2hfaW50ZXJ2YWwodC5yaWdodCxuLHIpKX10cmVlX2ZpbmRfYW55X2ludGVydmFsKHQsbil7bGV0IHI9ITE7cmV0dXJuIHQhPW51bGwmJnQhPXRoaXMubmlsX25vZGUmJih0LmxlZnQhPXRoaXMubmlsX25vZGUmJiF0Lm5vdF9pbnRlcnNlY3RfbGVmdF9zdWJ0cmVlKG4pJiYocj10aGlzLnRyZWVfZmluZF9hbnlfaW50ZXJ2YWwodC5sZWZ0LG4pKSxyfHwocj10LmludGVyc2VjdChuKSksIXImJnQucmlnaHQhPXRoaXMubmlsX25vZGUmJiF0Lm5vdF9pbnRlcnNlY3RfcmlnaHRfc3VidHJlZShuKSYmKHI9dGhpcy50cmVlX2ZpbmRfYW55X2ludGVydmFsKHQucmlnaHQsbikpKSxyfWxvY2FsX21pbmltdW0odCl7bGV0IG49dDtmb3IoO24ubGVmdCE9bnVsbCYmbi5sZWZ0IT10aGlzLm5pbF9ub2RlOyluPW4ubGVmdDtyZXR1cm4gbn1sb2NhbF9tYXhpbXVtKHQpe2xldCBuPXQ7Zm9yKDtuLnJpZ2h0IT1udWxsJiZuLnJpZ2h0IT10aGlzLm5pbF9ub2RlOyluPW4ucmlnaHQ7cmV0dXJuIG59dHJlZV9zdWNjZXNzb3IodCl7bGV0IG4scixpO2lmKHQucmlnaHQhPXRoaXMubmlsX25vZGUpbj10aGlzLmxvY2FsX21pbmltdW0odC5yaWdodCk7ZWxzZXtmb3Iocj10LGk9dC5wYXJlbnQ7aSE9bnVsbCYmaS5yaWdodD09cjspcj1pLGk9aS5wYXJlbnQ7bj1pfXJldHVybiBufXJvdGF0ZV9sZWZ0KHQpe2xldCBuPXQucmlnaHQ7dC5yaWdodD1uLmxlZnQsbi5sZWZ0IT10aGlzLm5pbF9ub2RlJiYobi5sZWZ0LnBhcmVudD10KSxuLnBhcmVudD10LnBhcmVudCx0PT10aGlzLnJvb3Q/dGhpcy5yb290PW46dD09dC5wYXJlbnQubGVmdD90LnBhcmVudC5sZWZ0PW46dC5wYXJlbnQucmlnaHQ9bixuLmxlZnQ9dCx0LnBhcmVudD1uLHQhPW51bGwmJnQhPXRoaXMubmlsX25vZGUmJnQudXBkYXRlX21heCgpLG49dC5wYXJlbnQsbiE9bnVsbCYmbiE9dGhpcy5uaWxfbm9kZSYmbi51cGRhdGVfbWF4KCl9cm90YXRlX3JpZ2h0KHQpe2xldCBuPXQubGVmdDt0LmxlZnQ9bi5yaWdodCxuLnJpZ2h0IT10aGlzLm5pbF9ub2RlJiYobi5yaWdodC5wYXJlbnQ9dCksbi5wYXJlbnQ9dC5wYXJlbnQsdD09dGhpcy5yb290P3RoaXMucm9vdD1uOnQ9PXQucGFyZW50LmxlZnQ/dC5wYXJlbnQubGVmdD1uOnQucGFyZW50LnJpZ2h0PW4sbi5yaWdodD10LHQucGFyZW50PW4sdCE9bnVsbCYmdCE9dGhpcy5uaWxfbm9kZSYmdC51cGRhdGVfbWF4KCksbj10LnBhcmVudCxuIT1udWxsJiZuIT10aGlzLm5pbF9ub2RlJiZuLnVwZGF0ZV9tYXgoKX10cmVlX3dhbGsodCxuKXt0IT1udWxsJiZ0IT10aGlzLm5pbF9ub2RlJiYodGhpcy50cmVlX3dhbGsodC5sZWZ0LG4pLG4odCksdGhpcy50cmVlX3dhbGsodC5yaWdodCxuKSl9dGVzdFJlZEJsYWNrUHJvcGVydHkoKXtsZXQgdD0hMDtyZXR1cm4gdGhpcy50cmVlX3dhbGsodGhpcy5yb290LGZ1bmN0aW9uKG4pe24uY29sb3I9PUsmJihuLmxlZnQuY29sb3I9PXomJm4ucmlnaHQuY29sb3I9PXp8fCh0PSExKSl9KSx0fXRlc3RCbGFja0hlaWdodFByb3BlcnR5KHQpe2xldCBuPTAscj0wLGk9MDtpZih0LmNvbG9yPT16JiZuKyssdC5sZWZ0IT10aGlzLm5pbF9ub2RlP3I9dGhpcy50ZXN0QmxhY2tIZWlnaHRQcm9wZXJ0eSh0LmxlZnQpOnI9MSx0LnJpZ2h0IT10aGlzLm5pbF9ub2RlP2k9dGhpcy50ZXN0QmxhY2tIZWlnaHRQcm9wZXJ0eSh0LnJpZ2h0KTppPTEsciE9aSl0aHJvdyBuZXcgRXJyb3IoIlJlZC1ibGFjayBoZWlnaHQgcHJvcGVydHkgdmlvbGF0ZWQiKTtyZXR1cm4gbis9cixufX1jbGFzcyBsdSBleHRlbmRzIFNldHtjb25zdHJ1Y3Rvcih0KXtzdXBlcih0KSx0aGlzLmluZGV4PW5ldyBUZSx0aGlzLmZvckVhY2gobj0+dGhpcy5pbmRleC5pbnNlcnQobikpfWFkZCh0KXtsZXQgbj10aGlzLnNpemU7Y29uc3R7a2V5OnIsdmFsdWU6aX09dCxzPXJ8fHQuYm94LG89aXx8dDtyZXR1cm4gc3VwZXIuYWRkKG8pLHRoaXMuc2l6ZT5uJiZ0aGlzLmluZGV4Lmluc2VydChzLG8pLHRoaXN9ZGVsZXRlKHQpe2NvbnN0e2tleTpuLHZhbHVlOnJ9PXQsaT1ufHx0LmJveCxzPXJ8fHQ7bGV0IG89c3VwZXIuZGVsZXRlKHMpO3JldHVybiBvJiZ0aGlzLmluZGV4LnJlbW92ZShpLHMpLG99Y2xlYXIoKXtzdXBlci5jbGVhcigpLHRoaXMuaW5kZXg9bmV3IFRlfXNlYXJjaCh0KXtyZXR1cm4gdGhpcy5pbmRleC5zZWFyY2godCl9aGl0KHQpe2xldCBuPW5ldyBhLkJveCh0LngtMSx0LnktMSx0LngrMSx0LnkrMSk7cmV0dXJuIHRoaXMuaW5kZXguc2VhcmNoKG4pLmZpbHRlcihpPT50Lm9uKGkpKX1zdmcoKXtyZXR1cm5bLi4udGhpc10ucmVkdWNlKChuLHIpPT5uK3Iuc3ZnKCksIiIpfX1hLlBsYW5hclNldD1sdTtjbGFzcyB2dHtnZXQgbmFtZSgpe3Rocm93IFUuQ0FOTk9UX0lOVk9LRV9BQlNUUkFDVF9NRVRIT0R9Z2V0IGJveCgpe3Rocm93IFUuQ0FOTk9UX0lOVk9LRV9BQlNUUkFDVF9NRVRIT0R9Y2xvbmUoKXt0aHJvdyBVLkNBTk5PVF9JTlZPS0VfQUJTVFJBQ1RfTUVUSE9EfXRyYW5zbGF0ZSguLi50KXtyZXR1cm4gdGhpcy50cmFuc2Zvcm0obmV3IHJ0KCkudHJhbnNsYXRlKC4uLnQpKX1yb3RhdGUodCxuPW5ldyBhLlBvaW50KXtyZXR1cm4gdGhpcy50cmFuc2Zvcm0obmV3IHJ0KCkucm90YXRlKHQsbi54LG4ueSkpfXNjYWxlKHQsbil7cmV0dXJuIHRoaXMudHJhbnNmb3JtKG5ldyBydCgpLnNjYWxlKHQsbikpfXRyYW5zZm9ybSguLi50KXt0aHJvdyBVLkNBTk5PVF9JTlZPS0VfQUJTVFJBQ1RfTUVUSE9EfXRvSlNPTigpe3JldHVybiBPYmplY3QuYXNzaWduKHt9LHRoaXMse25hbWU6dGhpcy5uYW1lfSl9c3ZnKHQ9e30pe3Rocm93IFUuQ0FOTk9UX0lOVk9LRV9BQlNUUkFDVF9NRVRIT0R9fWxldCBkbj1jbGFzcyBCbyBleHRlbmRzIHZ0e2NvbnN0cnVjdG9yKC4uLnQpe2lmKHN1cGVyKCksdGhpcy54PTAsdGhpcy55PTAsdC5sZW5ndGghPT0wKXtpZih0Lmxlbmd0aD09PTEmJnRbMF1pbnN0YW5jZW9mIEFycmF5JiZ0WzBdLmxlbmd0aD09PTIpe2xldCBuPXRbMF07aWYodHlwZW9mIG5bMF09PSJudW1iZXIiJiZ0eXBlb2YgblsxXT09Im51bWJlciIpe3RoaXMueD1uWzBdLHRoaXMueT1uWzFdO3JldHVybn19aWYodC5sZW5ndGg9PT0xJiZ0WzBdaW5zdGFuY2VvZiBPYmplY3QmJnRbMF0ubmFtZT09PSJwb2ludCIpe2xldHt4Om4seTpyfT10WzBdO3RoaXMueD1uLHRoaXMueT1yO3JldHVybn1pZih0Lmxlbmd0aD09PTImJnR5cGVvZiB0WzBdPT0ibnVtYmVyIiYmdHlwZW9mIHRbMV09PSJudW1iZXIiKXt0aGlzLng9dFswXSx0aGlzLnk9dFsxXTtyZXR1cm59dGhyb3cgVS5JTExFR0FMX1BBUkFNRVRFUlN9fWdldCBib3goKXtyZXR1cm4gbmV3IGEuQm94KHRoaXMueCx0aGlzLnksdGhpcy54LHRoaXMueSl9Y2xvbmUoKXtyZXR1cm4gbmV3IGEuUG9pbnQodGhpcy54LHRoaXMueSl9Z2V0IHZlcnRpY2VzKCl7cmV0dXJuW3RoaXMuY2xvbmUoKV19ZXF1YWxUbyh0KXtyZXR1cm4gYS5VdGlscy5FUSh0aGlzLngsdC54KSYmYS5VdGlscy5FUSh0aGlzLnksdC55KX1sZXNzVGhhbih0KXtyZXR1cm4hIShhLlV0aWxzLkxUKHRoaXMueSx0LnkpfHxhLlV0aWxzLkVRKHRoaXMueSx0LnkpJiZhLlV0aWxzLkxUKHRoaXMueCx0LngpKX10cmFuc2Zvcm0odCl7cmV0dXJuIG5ldyBhLlBvaW50KHQudHJhbnNmb3JtKFt0aGlzLngsdGhpcy55XSkpfXByb2plY3Rpb25Pbih0KXtpZih0aGlzLmVxdWFsVG8odC5wdCkpcmV0dXJuIHRoaXMuY2xvbmUoKTtsZXQgbj1uZXcgYS5WZWN0b3IodGhpcyx0LnB0KTtpZihhLlV0aWxzLkVRXzAobi5jcm9zcyh0Lm5vcm0pKSlyZXR1cm4gdC5wdC5jbG9uZSgpO2xldCByPW4uZG90KHQubm9ybSksaT10Lm5vcm0ubXVsdGlwbHkocik7cmV0dXJuIHRoaXMudHJhbnNsYXRlKGkpfWxlZnRUbyh0KXtsZXQgbj1uZXcgYS5WZWN0b3IodC5wdCx0aGlzKTtyZXR1cm4gYS5VdGlscy5HVChuLmRvdCh0Lm5vcm0pLDApfWRpc3RhbmNlVG8odCl7aWYodCBpbnN0YW5jZW9mIEJvKXtsZXQgbj10LngtdGhpcy54LHI9dC55LXRoaXMueTtyZXR1cm5bTWF0aC5zcXJ0KG4qbityKnIpLG5ldyBhLlNlZ21lbnQodGhpcyx0KV19aWYodCBpbnN0YW5jZW9mIGEuTGluZSlyZXR1cm4gYS5EaXN0YW5jZS5wb2ludDJsaW5lKHRoaXMsdCk7aWYodCBpbnN0YW5jZW9mIGEuQ2lyY2xlKXJldHVybiBhLkRpc3RhbmNlLnBvaW50MmNpcmNsZSh0aGlzLHQpO2lmKHQgaW5zdGFuY2VvZiBhLlNlZ21lbnQpcmV0dXJuIGEuRGlzdGFuY2UucG9pbnQyc2VnbWVudCh0aGlzLHQpO2lmKHQgaW5zdGFuY2VvZiBhLkFyYylyZXR1cm4gYS5EaXN0YW5jZS5wb2ludDJhcmModGhpcyx0KTtpZih0IGluc3RhbmNlb2YgYS5Qb2x5Z29uKXJldHVybiBhLkRpc3RhbmNlLnBvaW50MnBvbHlnb24odGhpcyx0KTtpZih0IGluc3RhbmNlb2YgYS5QbGFuYXJTZXQpcmV0dXJuIGEuRGlzdGFuY2Uuc2hhcGUycGxhbmFyU2V0KHRoaXMsdCk7aWYodCBpbnN0YW5jZW9mIGEuTXVsdGlsaW5lKXJldHVybiBhLkRpc3RhbmNlLnNoYXBlMm11bHRpbGluZSh0aGlzLHQpfW9uKHQpe2lmKHQgaW5zdGFuY2VvZiBhLlBvaW50KXJldHVybiB0aGlzLmVxdWFsVG8odCk7aWYodC5jb250YWlucyYmdC5jb250YWlucyBpbnN0YW5jZW9mIEZ1bmN0aW9uKXJldHVybiB0LmNvbnRhaW5zKHRoaXMpO3Rocm93IGEuRXJyb3JzLlVOU1VQUE9SVEVEX1NIQVBFX1RZUEV9Z2V0IG5hbWUoKXtyZXR1cm4icG9pbnQifXN2Zyh0PXt9KXtjb25zdCBuPXQucj8/MztyZXR1cm5gCjxjaXJjbGUgY3g9IiR7dGhpcy54fSIgY3k9IiR7dGhpcy55fSIgcj0iJHtufSIKICAgICAgICAgICAgJHtQdCh7ZmlsbDoicmVkIiwuLi50fSl9IC8+YH19O2EuUG9pbnQ9ZG47Y29uc3QgaHU9KC4uLmUpPT5uZXcgYS5Qb2ludCguLi5lKTthLnBvaW50PWh1O2xldCBmdT1jbGFzcyBleHRlbmRzIHZ0e2NvbnN0cnVjdG9yKC4uLnQpe2lmKHN1cGVyKCksdGhpcy54PTAsdGhpcy55PTAsdC5sZW5ndGghPT0wKXtpZih0Lmxlbmd0aD09PTEmJnRbMF1pbnN0YW5jZW9mIEFycmF5JiZ0WzBdLmxlbmd0aD09PTIpe2xldCBuPXRbMF07aWYodHlwZW9mIG5bMF09PSJudW1iZXIiJiZ0eXBlb2YgblsxXT09Im51bWJlciIpe3RoaXMueD1uWzBdLHRoaXMueT1uWzFdO3JldHVybn19aWYodC5sZW5ndGg9PT0xJiZ0WzBdaW5zdGFuY2VvZiBPYmplY3QmJnRbMF0ubmFtZT09PSJ2ZWN0b3IiKXtsZXR7eDpuLHk6cn09dFswXTt0aGlzLng9bix0aGlzLnk9cjtyZXR1cm59aWYodC5sZW5ndGg9PT0yKXtsZXQgbj10WzBdLHI9dFsxXTtpZih0eXBlb2Ygbj09Im51bWJlciImJnR5cGVvZiByPT0ibnVtYmVyIil7dGhpcy54PW4sdGhpcy55PXI7cmV0dXJufWlmKG4gaW5zdGFuY2VvZiBhLlBvaW50JiZyIGluc3RhbmNlb2YgYS5Qb2ludCl7dGhpcy54PXIueC1uLngsdGhpcy55PXIueS1uLnk7cmV0dXJufX10aHJvdyBVLklMTEVHQUxfUEFSQU1FVEVSU319Y2xvbmUoKXtyZXR1cm4gbmV3IGEuVmVjdG9yKHRoaXMueCx0aGlzLnkpfWdldCBzbG9wZSgpe2xldCB0PU1hdGguYXRhbjIodGhpcy55LHRoaXMueCk7cmV0dXJuIHQ8MCYmKHQ9MipNYXRoLlBJK3QpLHR9Z2V0IGxlbmd0aCgpe3JldHVybiBNYXRoLnNxcnQodGhpcy5kb3QodGhpcykpfWVxdWFsVG8odCl7cmV0dXJuIGEuVXRpbHMuRVEodGhpcy54LHQueCkmJmEuVXRpbHMuRVEodGhpcy55LHQueSl9bXVsdGlwbHkodCl7cmV0dXJuIG5ldyBhLlZlY3Rvcih0KnRoaXMueCx0KnRoaXMueSl9ZG90KHQpe3JldHVybiB0aGlzLngqdC54K3RoaXMueSp0Lnl9Y3Jvc3ModCl7cmV0dXJuIHRoaXMueCp0LnktdGhpcy55KnQueH1ub3JtYWxpemUoKXtpZighYS5VdGlscy5FUV8wKHRoaXMubGVuZ3RoKSlyZXR1cm4gbmV3IGEuVmVjdG9yKHRoaXMueC90aGlzLmxlbmd0aCx0aGlzLnkvdGhpcy5sZW5ndGgpO3Rocm93IFUuWkVST19ESVZJU0lPTn1yb3RhdGUodCxuPW5ldyBhLlBvaW50KXtpZihuLng9PT0wJiZuLnk9PT0wKXJldHVybiB0aGlzLnRyYW5zZm9ybShuZXcgcnQoKS5yb3RhdGUodCkpO3Rocm93IFUuT1BFUkFUSU9OX0lTX05PVF9TVVBQT1JURUR9dHJhbnNmb3JtKHQpe3JldHVybiBuZXcgYS5WZWN0b3IodC50cmFuc2Zvcm0oW3RoaXMueCx0aGlzLnldKSl9cm90YXRlOTBDQ1coKXtyZXR1cm4gbmV3IGEuVmVjdG9yKC10aGlzLnksdGhpcy54KX1yb3RhdGU5MENXKCl7cmV0dXJuIG5ldyBhLlZlY3Rvcih0aGlzLnksLXRoaXMueCl9aW52ZXJ0KCl7cmV0dXJuIG5ldyBhLlZlY3RvcigtdGhpcy54LC10aGlzLnkpfWFkZCh0KXtyZXR1cm4gbmV3IGEuVmVjdG9yKHRoaXMueCt0LngsdGhpcy55K3QueSl9c3VidHJhY3QodCl7cmV0dXJuIG5ldyBhLlZlY3Rvcih0aGlzLngtdC54LHRoaXMueS10LnkpfWFuZ2xlVG8odCl7bGV0IG49dGhpcy5ub3JtYWxpemUoKSxyPXQubm9ybWFsaXplKCksaT1NYXRoLmF0YW4yKG4uY3Jvc3Mociksbi5kb3QocikpO3JldHVybiBpPDAmJihpKz0yKk1hdGguUEkpLGl9cHJvamVjdGlvbk9uKHQpe2xldCBuPXQubm9ybWFsaXplKCkscj10aGlzLmRvdChuKTtyZXR1cm4gbi5tdWx0aXBseShyKX1nZXQgbmFtZSgpe3JldHVybiJ2ZWN0b3IifX07YS5WZWN0b3I9ZnU7Y29uc3QgRW89KC4uLmUpPT5uZXcgYS5WZWN0b3IoLi4uZSk7YS52ZWN0b3I9RW87bGV0IHV1PWNsYXNzIFZyIGV4dGVuZHMgdnR7Y29uc3RydWN0b3IoLi4udCl7aWYoc3VwZXIoKSx0aGlzLnBzPW5ldyBhLlBvaW50LHRoaXMucGU9bmV3IGEuUG9pbnQsdC5sZW5ndGghPT0wKXtpZih0Lmxlbmd0aD09PTEmJnRbMF1pbnN0YW5jZW9mIEFycmF5JiZ0WzBdLmxlbmd0aD09PTQpe2xldCBuPXRbMF07dGhpcy5wcz1uZXcgYS5Qb2ludChuWzBdLG5bMV0pLHRoaXMucGU9bmV3IGEuUG9pbnQoblsyXSxuWzNdKTtyZXR1cm59aWYodC5sZW5ndGg9PT0xJiZ0WzBdaW5zdGFuY2VvZiBPYmplY3QmJnRbMF0ubmFtZT09PSJzZWdtZW50Iil7bGV0e3BzOm4scGU6cn09dFswXTt0aGlzLnBzPW5ldyBhLlBvaW50KG4ueCxuLnkpLHRoaXMucGU9bmV3IGEuUG9pbnQoci54LHIueSk7cmV0dXJufWlmKHQubGVuZ3RoPT09MSYmdFswXWluc3RhbmNlb2YgYS5Qb2ludCl7dGhpcy5wcz10WzBdLmNsb25lKCk7cmV0dXJufWlmKHQubGVuZ3RoPT09MiYmdFswXWluc3RhbmNlb2YgYS5Qb2ludCYmdFsxXWluc3RhbmNlb2YgYS5Qb2ludCl7dGhpcy5wcz10WzBdLmNsb25lKCksdGhpcy5wZT10WzFdLmNsb25lKCk7cmV0dXJufWlmKHQubGVuZ3RoPT09NCl7dGhpcy5wcz1uZXcgYS5Qb2ludCh0WzBdLHRbMV0pLHRoaXMucGU9bmV3IGEuUG9pbnQodFsyXSx0WzNdKTtyZXR1cm59dGhyb3cgVS5JTExFR0FMX1BBUkFNRVRFUlN9fWNsb25lKCl7cmV0dXJuIG5ldyBhLlNlZ21lbnQodGhpcy5zdGFydCx0aGlzLmVuZCl9Z2V0IHN0YXJ0KCl7cmV0dXJuIHRoaXMucHN9Z2V0IGVuZCgpe3JldHVybiB0aGlzLnBlfWdldCB2ZXJ0aWNlcygpe3JldHVyblt0aGlzLnBzLmNsb25lKCksdGhpcy5wZS5jbG9uZSgpXX1nZXQgbGVuZ3RoKCl7cmV0dXJuIHRoaXMuc3RhcnQuZGlzdGFuY2VUbyh0aGlzLmVuZClbMF19Z2V0IHNsb3BlKCl7cmV0dXJuIG5ldyBhLlZlY3Rvcih0aGlzLnN0YXJ0LHRoaXMuZW5kKS5zbG9wZX1nZXQgYm94KCl7cmV0dXJuIG5ldyBhLkJveChNYXRoLm1pbih0aGlzLnN0YXJ0LngsdGhpcy5lbmQueCksTWF0aC5taW4odGhpcy5zdGFydC55LHRoaXMuZW5kLnkpLE1hdGgubWF4KHRoaXMuc3RhcnQueCx0aGlzLmVuZC54KSxNYXRoLm1heCh0aGlzLnN0YXJ0LnksdGhpcy5lbmQueSkpfWVxdWFsVG8odCl7cmV0dXJuIHRoaXMucHMuZXF1YWxUbyh0LnBzKSYmdGhpcy5wZS5lcXVhbFRvKHQucGUpfWNvbnRhaW5zKHQpe3JldHVybiBhLlV0aWxzLkVRXzAodGhpcy5kaXN0YW5jZVRvUG9pbnQodCkpfWludGVyc2VjdCh0KXtpZih0IGluc3RhbmNlb2YgYS5Qb2ludClyZXR1cm4gdGhpcy5jb250YWlucyh0KT9bdF06W107aWYodCBpbnN0YW5jZW9mIGEuTGluZSlyZXR1cm4gbWUodGhpcyx0KTtpZih0IGluc3RhbmNlb2YgYS5SYXkpcmV0dXJuIGZyKHQsdGhpcyk7aWYodCBpbnN0YW5jZW9mIGEuU2VnbWVudClyZXR1cm4gbG4odGhpcyx0KTtpZih0IGluc3RhbmNlb2YgYS5DaXJjbGUpcmV0dXJuIGhuKHRoaXMsdCk7aWYodCBpbnN0YW5jZW9mIGEuQm94KXJldHVybiBPZih0aGlzLHQpO2lmKHQgaW5zdGFuY2VvZiBhLkFyYylyZXR1cm4ganQodGhpcyx0KTtpZih0IGluc3RhbmNlb2YgYS5Qb2x5Z29uKXJldHVybiBscih0aGlzLHQpO2lmKHQgaW5zdGFuY2VvZiBhLk11bHRpbGluZSlyZXR1cm4gX2UodGhpcyx0KX1kaXN0YW5jZVRvKHQpe2lmKHQgaW5zdGFuY2VvZiBhLlBvaW50KXtsZXRbbixyXT1hLkRpc3RhbmNlLnBvaW50MnNlZ21lbnQodCx0aGlzKTtyZXR1cm4gcj1yLnJldmVyc2UoKSxbbixyXX1pZih0IGluc3RhbmNlb2YgYS5DaXJjbGUpe2xldFtuLHJdPWEuRGlzdGFuY2Uuc2VnbWVudDJjaXJjbGUodGhpcyx0KTtyZXR1cm5bbixyXX1pZih0IGluc3RhbmNlb2YgYS5MaW5lKXtsZXRbbixyXT1hLkRpc3RhbmNlLnNlZ21lbnQybGluZSh0aGlzLHQpO3JldHVybltuLHJdfWlmKHQgaW5zdGFuY2VvZiBhLlNlZ21lbnQpe2xldFtuLHJdPWEuRGlzdGFuY2Uuc2VnbWVudDJzZWdtZW50KHRoaXMsdCk7cmV0dXJuW24scl19aWYodCBpbnN0YW5jZW9mIGEuQXJjKXtsZXRbbixyXT1hLkRpc3RhbmNlLnNlZ21lbnQyYXJjKHRoaXMsdCk7cmV0dXJuW24scl19aWYodCBpbnN0YW5jZW9mIGEuUG9seWdvbil7bGV0W24scl09YS5EaXN0YW5jZS5zaGFwZTJwb2x5Z29uKHRoaXMsdCk7cmV0dXJuW24scl19aWYodCBpbnN0YW5jZW9mIGEuUGxhbmFyU2V0KXtsZXRbbixyXT1hLkRpc3RhbmNlLnNoYXBlMnBsYW5hclNldCh0aGlzLHQpO3JldHVybltuLHJdfWlmKHQgaW5zdGFuY2VvZiBhLk11bHRpbGluZSlyZXR1cm4gYS5EaXN0YW5jZS5zaGFwZTJtdWx0aWxpbmUodGhpcyx0KX10YW5nZW50SW5TdGFydCgpe3JldHVybiBuZXcgYS5WZWN0b3IodGhpcy5zdGFydCx0aGlzLmVuZCkubm9ybWFsaXplKCl9dGFuZ2VudEluRW5kKCl7cmV0dXJuIG5ldyBhLlZlY3Rvcih0aGlzLmVuZCx0aGlzLnN0YXJ0KS5ub3JtYWxpemUoKX1yZXZlcnNlKCl7cmV0dXJuIG5ldyBWcih0aGlzLmVuZCx0aGlzLnN0YXJ0KX1zcGxpdCh0KXtyZXR1cm4gdGhpcy5zdGFydC5lcXVhbFRvKHQpP1tudWxsLHRoaXMuY2xvbmUoKV06dGhpcy5lbmQuZXF1YWxUbyh0KT9bdGhpcy5jbG9uZSgpLG51bGxdOltuZXcgYS5TZWdtZW50KHRoaXMuc3RhcnQsdCksbmV3IGEuU2VnbWVudCh0LHRoaXMuZW5kKV19bWlkZGxlKCl7cmV0dXJuIG5ldyBhLlBvaW50KCh0aGlzLnN0YXJ0LngrdGhpcy5lbmQueCkvMiwodGhpcy5zdGFydC55K3RoaXMuZW5kLnkpLzIpfXBvaW50QXRMZW5ndGgodCl7aWYodD50aGlzLmxlbmd0aHx8dDwwKXJldHVybiBudWxsO2lmKHQ9PTApcmV0dXJuIHRoaXMuc3RhcnQ7aWYodD09dGhpcy5sZW5ndGgpcmV0dXJuIHRoaXMuZW5kO2xldCBuPXQvdGhpcy5sZW5ndGg7cmV0dXJuIG5ldyBhLlBvaW50KCh0aGlzLmVuZC54LXRoaXMuc3RhcnQueCkqbit0aGlzLnN0YXJ0LngsKHRoaXMuZW5kLnktdGhpcy5zdGFydC55KSpuK3RoaXMuc3RhcnQueSl9ZGlzdGFuY2VUb1BvaW50KHQpe2xldFtuLC4uLnJdPWEuRGlzdGFuY2UucG9pbnQyc2VnbWVudCh0LHRoaXMpO3JldHVybiBufWRlZmluaXRlSW50ZWdyYWwodD0wKXtsZXQgbj10aGlzLmVuZC54LXRoaXMuc3RhcnQueCxyPXRoaXMuc3RhcnQueS10LGk9dGhpcy5lbmQueS10O3JldHVybiBuKihyK2kpLzJ9dHJhbnNmb3JtKHQ9bmV3IGEuTWF0cml4KXtyZXR1cm4gbmV3IFZyKHRoaXMucHMudHJhbnNmb3JtKHQpLHRoaXMucGUudHJhbnNmb3JtKHQpKX1pc1plcm9MZW5ndGgoKXtyZXR1cm4gdGhpcy5wcy5lcXVhbFRvKHRoaXMucGUpfXNvcnRQb2ludHModCl7cmV0dXJuIG5ldyBhLkxpbmUodGhpcy5zdGFydCx0aGlzLmVuZCkuc29ydFBvaW50cyh0KX1nZXQgbmFtZSgpe3JldHVybiJzZWdtZW50In1zdmcodD17fSl7cmV0dXJuYAo8bGluZSB4MT0iJHt0aGlzLnN0YXJ0Lnh9IiB5MT0iJHt0aGlzLnN0YXJ0Lnl9IiB4Mj0iJHt0aGlzLmVuZC54fSIgeTI9IiR7dGhpcy5lbmQueX0iICR7UHQodCl9IC8+YH19O2EuU2VnbWVudD11dTtjb25zdCBkdT0oLi4uZSk9Pm5ldyBhLlNlZ21lbnQoLi4uZSk7YS5zZWdtZW50PWR1O2xldHt2ZWN0b3I6RWV9PWEsZ3U9Y2xhc3MgWW8gZXh0ZW5kcyB2dHtjb25zdHJ1Y3RvciguLi50KXtpZihzdXBlcigpLHRoaXMucHQ9bmV3IGEuUG9pbnQsdGhpcy5ub3JtPW5ldyBhLlZlY3RvcigwLDEpLHQubGVuZ3RoIT09MCl7aWYodC5sZW5ndGg9PT0xJiZ0WzBdaW5zdGFuY2VvZiBPYmplY3QmJnRbMF0ubmFtZT09PSJsaW5lIil7bGV0e3B0Om4sbm9ybTpyfT10WzBdO3RoaXMucHQ9bmV3IGEuUG9pbnQobiksdGhpcy5ub3JtPW5ldyBhLlZlY3RvcihyKTtyZXR1cm59aWYodC5sZW5ndGg9PT0yKXtsZXQgbj10WzBdLHI9dFsxXTtpZihuIGluc3RhbmNlb2YgYS5Qb2ludCYmciBpbnN0YW5jZW9mIGEuUG9pbnQpe3RoaXMucHQ9bix0aGlzLm5vcm09WW8ucG9pbnRzMm5vcm0obixyKSx0aGlzLm5vcm0uZG90KEVlKHRoaXMucHQueCx0aGlzLnB0LnkpKT49MCYmdGhpcy5ub3JtLmludmVydCgpO3JldHVybn1pZihuIGluc3RhbmNlb2YgYS5Qb2ludCYmciBpbnN0YW5jZW9mIGEuVmVjdG9yKXtpZihhLlV0aWxzLkVRXzAoci54KSYmYS5VdGlscy5FUV8wKHIueSkpdGhyb3cgVS5JTExFR0FMX1BBUkFNRVRFUlM7dGhpcy5wdD1uLmNsb25lKCksdGhpcy5ub3JtPXIuY2xvbmUoKSx0aGlzLm5vcm09dGhpcy5ub3JtLm5vcm1hbGl6ZSgpLHRoaXMubm9ybS5kb3QoRWUodGhpcy5wdC54LHRoaXMucHQueSkpPj0wJiZ0aGlzLm5vcm0uaW52ZXJ0KCk7cmV0dXJufWlmKG4gaW5zdGFuY2VvZiBhLlZlY3RvciYmciBpbnN0YW5jZW9mIGEuUG9pbnQpe2lmKGEuVXRpbHMuRVFfMChuLngpJiZhLlV0aWxzLkVRXzAobi55KSl0aHJvdyBVLklMTEVHQUxfUEFSQU1FVEVSUzt0aGlzLnB0PXIuY2xvbmUoKSx0aGlzLm5vcm09bi5jbG9uZSgpLHRoaXMubm9ybT10aGlzLm5vcm0ubm9ybWFsaXplKCksdGhpcy5ub3JtLmRvdChFZSh0aGlzLnB0LngsdGhpcy5wdC55KSk+PTAmJnRoaXMubm9ybS5pbnZlcnQoKTtyZXR1cm59fXRocm93IFUuSUxMRUdBTF9QQVJBTUVURVJTfX1jbG9uZSgpe3JldHVybiBuZXcgYS5MaW5lKHRoaXMucHQsdGhpcy5ub3JtKX1nZXQgc3RhcnQoKXt9Z2V0IGVuZCgpe31nZXQgbGVuZ3RoKCl7cmV0dXJuIE51bWJlci5QT1NJVElWRV9JTkZJTklUWX1nZXQgYm94KCl7cmV0dXJuIG5ldyBhLkJveChOdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFksTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZLE51bWJlci5QT1NJVElWRV9JTkZJTklUWSxOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFkpfWdldCBtaWRkbGUoKXt9Z2V0IHNsb3BlKCl7cmV0dXJuIG5ldyBhLlZlY3Rvcih0aGlzLm5vcm0ueSwtdGhpcy5ub3JtLngpLnNsb3BlfWdldCBzdGFuZGFyZCgpe2xldCB0PXRoaXMubm9ybS54LG49dGhpcy5ub3JtLnkscj10aGlzLm5vcm0uZG90KEVlKHRoaXMucHQueCx0aGlzLnB0LnkpKTtyZXR1cm5bdCxuLHJdfXBhcmFsbGVsVG8odCl7cmV0dXJuIGEuVXRpbHMuRVFfMCh0aGlzLm5vcm0uY3Jvc3ModC5ub3JtKSl9aW5jaWRlbnRUbyh0KXtyZXR1cm4gdGhpcy5wYXJhbGxlbFRvKHQpJiZ0aGlzLnB0Lm9uKHQpfWNvbnRhaW5zKHQpe2lmKHRoaXMucHQuZXF1YWxUbyh0KSlyZXR1cm4hMDtsZXQgbj1uZXcgYS5WZWN0b3IodGhpcy5wdCx0KTtyZXR1cm4gYS5VdGlscy5FUV8wKHRoaXMubm9ybS5kb3QobikpfWNvb3JkKHQpe3JldHVybiBFZSh0LngsdC55KS5jcm9zcyh0aGlzLm5vcm0pfWludGVyc2VjdCh0KXtpZih0IGluc3RhbmNlb2YgYS5Qb2ludClyZXR1cm4gdGhpcy5jb250YWlucyh0KT9bdF06W107aWYodCBpbnN0YW5jZW9mIGEuTGluZSlyZXR1cm4gR3QodGhpcyx0KTtpZih0IGluc3RhbmNlb2YgYS5SYXkpcmV0dXJuIHNvKHQsdGhpcyk7aWYodCBpbnN0YW5jZW9mIGEuQ2lyY2xlKXJldHVybiBSdCh0aGlzLHQpO2lmKHQgaW5zdGFuY2VvZiBhLkJveClyZXR1cm4gWHQodGhpcyx0KTtpZih0IGluc3RhbmNlb2YgYS5TZWdtZW50KXJldHVybiBtZSh0LHRoaXMpO2lmKHQgaW5zdGFuY2VvZiBhLkFyYylyZXR1cm4gYW4odGhpcyx0KTtpZih0IGluc3RhbmNlb2YgYS5Qb2x5Z29uKXJldHVybiBwZSh0aGlzLHQpO2lmKHQgaW5zdGFuY2VvZiBhLk11bHRpbGluZSlyZXR1cm4gX2UodGhpcyx0KX1kaXN0YW5jZVRvKHQpe2lmKHQgaW5zdGFuY2VvZiBhLlBvaW50KXtsZXRbbixyXT1hLkRpc3RhbmNlLnBvaW50MmxpbmUodCx0aGlzKTtyZXR1cm4gcj1yLnJldmVyc2UoKSxbbixyXX1pZih0IGluc3RhbmNlb2YgYS5DaXJjbGUpe2xldFtuLHJdPWEuRGlzdGFuY2UuY2lyY2xlMmxpbmUodCx0aGlzKTtyZXR1cm4gcj1yLnJldmVyc2UoKSxbbixyXX1pZih0IGluc3RhbmNlb2YgYS5TZWdtZW50KXtsZXRbbixyXT1hLkRpc3RhbmNlLnNlZ21lbnQybGluZSh0LHRoaXMpO3JldHVybltuLHIucmV2ZXJzZSgpXX1pZih0IGluc3RhbmNlb2YgYS5BcmMpe2xldFtuLHJdPWEuRGlzdGFuY2UuYXJjMmxpbmUodCx0aGlzKTtyZXR1cm5bbixyLnJldmVyc2UoKV19aWYodCBpbnN0YW5jZW9mIGEuUG9seWdvbil7bGV0W24scl09YS5EaXN0YW5jZS5zaGFwZTJwb2x5Z29uKHRoaXMsdCk7cmV0dXJuW24scl19fXNwbGl0KHQpe2lmKHQgaW5zdGFuY2VvZiBhLlBvaW50KXJldHVybltuZXcgYS5SYXkodCx0aGlzLm5vcm0pLG5ldyBhLlJheSh0LHRoaXMubm9ybSldO3tsZXQgbj1uZXcgYS5NdWx0aWxpbmUoW3RoaXNdKSxyPXRoaXMuc29ydFBvaW50cyh0KTtyZXR1cm4gbi5zcGxpdChyKSxuLnRvU2hhcGVzKCl9fXJvdGF0ZSh0LG49bmV3IGEuUG9pbnQpe3JldHVybiBuZXcgYS5MaW5lKHRoaXMucHQucm90YXRlKHQsbiksdGhpcy5ub3JtLnJvdGF0ZSh0KSl9dHJhbnNmb3JtKHQpe3JldHVybiBuZXcgYS5MaW5lKHRoaXMucHQudHJhbnNmb3JtKHQpLHRoaXMubm9ybS5jbG9uZSgpKX1zb3J0UG9pbnRzKHQpe3JldHVybiB0LnNsaWNlKCkuc29ydCgobixyKT0+dGhpcy5jb29yZChuKTx0aGlzLmNvb3JkKHIpPy0xOnRoaXMuY29vcmQobik+dGhpcy5jb29yZChyKT8xOjApfWdldCBuYW1lKCl7cmV0dXJuImxpbmUifXN2Zyh0LG49e30pe2xldCByPVh0KHRoaXMsdCk7aWYoci5sZW5ndGg9PT0wKXJldHVybiIiO2xldCBpPXJbMF0scz1yLmxlbmd0aD09PTI/clsxXTpyLmZpbmQoYz0+IWMuZXF1YWxUbyhpKSk7cmV0dXJuIHM9PT12b2lkIDAmJihzPWkpLG5ldyBhLlNlZ21lbnQoaSxzKS5zdmcobil9c3RhdGljIHBvaW50czJub3JtKHQsbil7aWYodC5lcXVhbFRvKG4pKXRocm93IFUuSUxMRUdBTF9QQVJBTUVURVJTO3JldHVybiBuZXcgYS5WZWN0b3IodCxuKS5ub3JtYWxpemUoKS5yb3RhdGU5MENDVygpfX07YS5MaW5lPWd1O2NvbnN0IG11PSguLi5lKT0+bmV3IGEuTGluZSguLi5lKTthLmxpbmU9bXU7bGV0IHB1PWNsYXNzIGV4dGVuZHMgdnR7Y29uc3RydWN0b3IoLi4udCl7aWYoc3VwZXIoKSx0aGlzLnBjPW5ldyBhLlBvaW50LHRoaXMucj0xLHQubGVuZ3RoPT09MSYmdFswXWluc3RhbmNlb2YgT2JqZWN0JiZ0WzBdLm5hbWU9PT0iY2lyY2xlIil7bGV0e3BjOm4scn09dFswXTt0aGlzLnBjPW5ldyBhLlBvaW50KG4pLHRoaXMucj1yfWVsc2V7bGV0W24scl09Wy4uLnRdO24mJm4gaW5zdGFuY2VvZiBhLlBvaW50JiYodGhpcy5wYz1uLmNsb25lKCkpLHIhPT12b2lkIDAmJih0aGlzLnI9cil9fWNsb25lKCl7cmV0dXJuIG5ldyBhLkNpcmNsZSh0aGlzLnBjLmNsb25lKCksdGhpcy5yKX1nZXQgY2VudGVyKCl7cmV0dXJuIHRoaXMucGN9Z2V0IGJveCgpe3JldHVybiBuZXcgYS5Cb3godGhpcy5wYy54LXRoaXMucix0aGlzLnBjLnktdGhpcy5yLHRoaXMucGMueCt0aGlzLnIsdGhpcy5wYy55K3RoaXMucil9Y29udGFpbnModCl7aWYodCBpbnN0YW5jZW9mIGEuUG9pbnQpcmV0dXJuIGEuVXRpbHMuTEUodC5kaXN0YW5jZVRvKHRoaXMuY2VudGVyKVswXSx0aGlzLnIpO2lmKHQgaW5zdGFuY2VvZiBhLlNlZ21lbnQpcmV0dXJuIGEuVXRpbHMuTEUodC5zdGFydC5kaXN0YW5jZVRvKHRoaXMuY2VudGVyKVswXSx0aGlzLnIpJiZhLlV0aWxzLkxFKHQuZW5kLmRpc3RhbmNlVG8odGhpcy5jZW50ZXIpWzBdLHRoaXMucik7aWYodCBpbnN0YW5jZW9mIGEuQXJjKXJldHVybiB0aGlzLmludGVyc2VjdCh0KS5sZW5ndGg9PT0wJiZhLlV0aWxzLkxFKHQuc3RhcnQuZGlzdGFuY2VUbyh0aGlzLmNlbnRlcilbMF0sdGhpcy5yKSYmYS5VdGlscy5MRSh0LmVuZC5kaXN0YW5jZVRvKHRoaXMuY2VudGVyKVswXSx0aGlzLnIpO2lmKHQgaW5zdGFuY2VvZiBhLkNpcmNsZSlyZXR1cm4gdGhpcy5pbnRlcnNlY3QodCkubGVuZ3RoPT09MCYmYS5VdGlscy5MRSh0LnIsdGhpcy5yKSYmYS5VdGlscy5MRSh0LmNlbnRlci5kaXN0YW5jZVRvKHRoaXMuY2VudGVyKVswXSx0aGlzLnIpfXRvQXJjKHQ9ITApe3JldHVybiBuZXcgYS5BcmModGhpcy5jZW50ZXIsdGhpcy5yLE1hdGguUEksLU1hdGguUEksdCl9c2NhbGUodCxuKXtpZih0IT09bnx8ISh0aGlzLnBjLng9PT0wJiZ0aGlzLnBjLnk9PT0wKSl0aHJvdyBVLk9QRVJBVElPTl9JU19OT1RfU1VQUE9SVEVEO3JldHVybiBuZXcgYS5DaXJjbGUodGhpcy5wYyx0aGlzLnIqdCl9dHJhbnNmb3JtKHQ9bmV3IGEuTWF0cml4KXtyZXR1cm4gbmV3IGEuQ2lyY2xlKHRoaXMucGMudHJhbnNmb3JtKHQpLHRoaXMucil9aW50ZXJzZWN0KHQpe2lmKHQgaW5zdGFuY2VvZiBhLlBvaW50KXJldHVybiB0aGlzLmNvbnRhaW5zKHQpP1t0XTpbXTtpZih0IGluc3RhbmNlb2YgYS5MaW5lKXJldHVybiBSdCh0LHRoaXMpO2lmKHQgaW5zdGFuY2VvZiBhLlJheSlyZXR1cm4gaW8odCx0aGlzKTtpZih0IGluc3RhbmNlb2YgYS5TZWdtZW50KXJldHVybiBobih0LHRoaXMpO2lmKHQgaW5zdGFuY2VvZiBhLkNpcmNsZSlyZXR1cm4ganModCx0aGlzKTtpZih0IGluc3RhbmNlb2YgYS5Cb3gpcmV0dXJuIHZmKHRoaXMsdCk7aWYodCBpbnN0YW5jZW9mIGEuQXJjKXJldHVybiBhcih0LHRoaXMpO2lmKHQgaW5zdGFuY2VvZiBhLlBvbHlnb24pcmV0dXJuIHRvKHRoaXMsdCk7aWYodCBpbnN0YW5jZW9mIGEuTXVsdGlsaW5lKXJldHVybiBfZSh0aGlzLHQpfWRpc3RhbmNlVG8odCl7aWYodCBpbnN0YW5jZW9mIGEuUG9pbnQpe2xldFtuLHJdPWEuRGlzdGFuY2UucG9pbnQyY2lyY2xlKHQsdGhpcyk7cmV0dXJuIHI9ci5yZXZlcnNlKCksW24scl19aWYodCBpbnN0YW5jZW9mIGEuQ2lyY2xlKXtsZXRbbixyXT1hLkRpc3RhbmNlLmNpcmNsZTJjaXJjbGUodGhpcyx0KTtyZXR1cm5bbixyXX1pZih0IGluc3RhbmNlb2YgYS5MaW5lKXtsZXRbbixyXT1hLkRpc3RhbmNlLmNpcmNsZTJsaW5lKHRoaXMsdCk7cmV0dXJuW24scl19aWYodCBpbnN0YW5jZW9mIGEuU2VnbWVudCl7bGV0W24scl09YS5EaXN0YW5jZS5zZWdtZW50MmNpcmNsZSh0LHRoaXMpO3JldHVybiByPXIucmV2ZXJzZSgpLFtuLHJdfWlmKHQgaW5zdGFuY2VvZiBhLkFyYyl7bGV0W24scl09YS5EaXN0YW5jZS5hcmMyY2lyY2xlKHQsdGhpcyk7cmV0dXJuIHI9ci5yZXZlcnNlKCksW24scl19aWYodCBpbnN0YW5jZW9mIGEuUG9seWdvbil7bGV0W24scl09YS5EaXN0YW5jZS5zaGFwZTJwb2x5Z29uKHRoaXMsdCk7cmV0dXJuW24scl19aWYodCBpbnN0YW5jZW9mIGEuUGxhbmFyU2V0KXtsZXRbbixyXT1hLkRpc3RhbmNlLnNoYXBlMnBsYW5hclNldCh0aGlzLHQpO3JldHVybltuLHJdfWlmKHQgaW5zdGFuY2VvZiBhLk11bHRpbGluZSl7bGV0W24scl09YS5EaXN0YW5jZS5zaGFwZTJtdWx0aWxpbmUodGhpcyx0KTtyZXR1cm5bbixyXX19Z2V0IG5hbWUoKXtyZXR1cm4iY2lyY2xlIn1zdmcodD17fSl7cmV0dXJuYAo8Y2lyY2xlIGN4PSIke3RoaXMucGMueH0iIGN5PSIke3RoaXMucGMueX0iIHI9IiR7dGhpcy5yfSIKICAgICAgICAgICAgICAgICR7UHQoe2ZpbGw6Im5vbmUiLC4uLnR9KX0gLz5gfX07YS5DaXJjbGU9cHU7Y29uc3QgX3U9KC4uLmUpPT5uZXcgYS5DaXJjbGUoLi4uZSk7YS5jaXJjbGU9X3U7Y2xhc3MgeXUgZXh0ZW5kcyB2dHtjb25zdHJ1Y3RvciguLi50KXtpZihzdXBlcigpLHRoaXMucGM9bmV3IGEuUG9pbnQsdGhpcy5yPTEsdGhpcy5zdGFydEFuZ2xlPTAsdGhpcy5lbmRBbmdsZT0yKk1hdGguUEksdGhpcy5jb3VudGVyQ2xvY2t3aXNlPWEuQ0NXLHQubGVuZ3RoIT09MClpZih0Lmxlbmd0aD09PTEmJnRbMF1pbnN0YW5jZW9mIE9iamVjdCYmdFswXS5uYW1lPT09ImFyYyIpe2xldHtwYzpuLHIsc3RhcnRBbmdsZTppLGVuZEFuZ2xlOnMsY291bnRlckNsb2Nrd2lzZTpvfT10WzBdO3RoaXMucGM9bmV3IGEuUG9pbnQobi54LG4ueSksdGhpcy5yPXIsdGhpcy5zdGFydEFuZ2xlPWksdGhpcy5lbmRBbmdsZT1zLHRoaXMuY291bnRlckNsb2Nrd2lzZT1vfWVsc2V7bGV0W24scixpLHMsb109Wy4uLnRdO24mJm4gaW5zdGFuY2VvZiBhLlBvaW50JiYodGhpcy5wYz1uLmNsb25lKCkpLHIhPT12b2lkIDAmJih0aGlzLnI9ciksaSE9PXZvaWQgMCYmKHRoaXMuc3RhcnRBbmdsZT1pKSxzIT09dm9pZCAwJiYodGhpcy5lbmRBbmdsZT1zKSxvIT09dm9pZCAwJiYodGhpcy5jb3VudGVyQ2xvY2t3aXNlPW8pfX1jbG9uZSgpe3JldHVybiBuZXcgYS5BcmModGhpcy5wYy5jbG9uZSgpLHRoaXMucix0aGlzLnN0YXJ0QW5nbGUsdGhpcy5lbmRBbmdsZSx0aGlzLmNvdW50ZXJDbG9ja3dpc2UpfWdldCBzd2VlcCgpe2lmKGEuVXRpbHMuRVEodGhpcy5zdGFydEFuZ2xlLHRoaXMuZW5kQW5nbGUpKXJldHVybiAwO2lmKGEuVXRpbHMuRVEoTWF0aC5hYnModGhpcy5zdGFydEFuZ2xlLXRoaXMuZW5kQW5nbGUpLGEuUEl4MikpcmV0dXJuIGEuUEl4MjtsZXQgdDtyZXR1cm4gdGhpcy5jb3VudGVyQ2xvY2t3aXNlP3Q9YS5VdGlscy5HVCh0aGlzLmVuZEFuZ2xlLHRoaXMuc3RhcnRBbmdsZSk/dGhpcy5lbmRBbmdsZS10aGlzLnN0YXJ0QW5nbGU6dGhpcy5lbmRBbmdsZS10aGlzLnN0YXJ0QW5nbGUrYS5QSXgyOnQ9YS5VdGlscy5HVCh0aGlzLnN0YXJ0QW5nbGUsdGhpcy5lbmRBbmdsZSk/dGhpcy5zdGFydEFuZ2xlLXRoaXMuZW5kQW5nbGU6dGhpcy5zdGFydEFuZ2xlLXRoaXMuZW5kQW5nbGUrYS5QSXgyLGEuVXRpbHMuR1QodCxhLlBJeDIpJiYodC09YS5QSXgyKSxhLlV0aWxzLkxUKHQsMCkmJih0Kz1hLlBJeDIpLHR9Z2V0IHN0YXJ0KCl7cmV0dXJuIG5ldyBhLlBvaW50KHRoaXMucGMueCt0aGlzLnIsdGhpcy5wYy55KS5yb3RhdGUodGhpcy5zdGFydEFuZ2xlLHRoaXMucGMpfWdldCBlbmQoKXtyZXR1cm4gbmV3IGEuUG9pbnQodGhpcy5wYy54K3RoaXMucix0aGlzLnBjLnkpLnJvdGF0ZSh0aGlzLmVuZEFuZ2xlLHRoaXMucGMpfWdldCBjZW50ZXIoKXtyZXR1cm4gdGhpcy5wYy5jbG9uZSgpfWdldCB2ZXJ0aWNlcygpe3JldHVyblt0aGlzLnN0YXJ0LmNsb25lKCksdGhpcy5lbmQuY2xvbmUoKV19Z2V0IGxlbmd0aCgpe3JldHVybiBNYXRoLmFicyh0aGlzLnN3ZWVwKnRoaXMucil9Z2V0IGJveCgpe2xldCBuPXRoaXMuYnJlYWtUb0Z1bmN0aW9uYWwoKS5yZWR1Y2UoKHIsaSk9PnIubWVyZ2UoaS5zdGFydC5ib3gpLG5ldyBhLkJveCk7cmV0dXJuIG49bi5tZXJnZSh0aGlzLmVuZC5ib3gpLG59Y29udGFpbnModCl7aWYoIWEuVXRpbHMuRVEodGhpcy5wYy5kaXN0YW5jZVRvKHQpWzBdLHRoaXMucikpcmV0dXJuITE7aWYodC5lcXVhbFRvKHRoaXMuc3RhcnQpKXJldHVybiEwO2xldCBuPW5ldyBhLlZlY3Rvcih0aGlzLnBjLHQpLnNsb3BlLHI9bmV3IGEuQXJjKHRoaXMucGMsdGhpcy5yLHRoaXMuc3RhcnRBbmdsZSxuLHRoaXMuY291bnRlckNsb2Nrd2lzZSk7cmV0dXJuIGEuVXRpbHMuTEUoci5sZW5ndGgsdGhpcy5sZW5ndGgpfXNwbGl0KHQpe2lmKHRoaXMuc3RhcnQuZXF1YWxUbyh0KSlyZXR1cm5bbnVsbCx0aGlzLmNsb25lKCldO2lmKHRoaXMuZW5kLmVxdWFsVG8odCkpcmV0dXJuW3RoaXMuY2xvbmUoKSxudWxsXTtsZXQgbj1uZXcgYS5WZWN0b3IodGhpcy5wYyx0KS5zbG9wZTtyZXR1cm5bbmV3IGEuQXJjKHRoaXMucGMsdGhpcy5yLHRoaXMuc3RhcnRBbmdsZSxuLHRoaXMuY291bnRlckNsb2Nrd2lzZSksbmV3IGEuQXJjKHRoaXMucGMsdGhpcy5yLG4sdGhpcy5lbmRBbmdsZSx0aGlzLmNvdW50ZXJDbG9ja3dpc2UpXX1taWRkbGUoKXtsZXQgdD10aGlzLmNvdW50ZXJDbG9ja3dpc2U/dGhpcy5zdGFydEFuZ2xlK3RoaXMuc3dlZXAvMjp0aGlzLnN0YXJ0QW5nbGUtdGhpcy5zd2VlcC8yO3JldHVybiBuZXcgYS5BcmModGhpcy5wYyx0aGlzLnIsdGhpcy5zdGFydEFuZ2xlLHQsdGhpcy5jb3VudGVyQ2xvY2t3aXNlKS5lbmR9cG9pbnRBdExlbmd0aCh0KXtpZih0PnRoaXMubGVuZ3RofHx0PDApcmV0dXJuIG51bGw7aWYodD09PTApcmV0dXJuIHRoaXMuc3RhcnQ7aWYodD09PXRoaXMubGVuZ3RoKXJldHVybiB0aGlzLmVuZDtsZXQgbj10L3RoaXMubGVuZ3RoLHI9dGhpcy5jb3VudGVyQ2xvY2t3aXNlP3RoaXMuc3RhcnRBbmdsZSt0aGlzLnN3ZWVwKm46dGhpcy5zdGFydEFuZ2xlLXRoaXMuc3dlZXAqbjtyZXR1cm4gbmV3IGEuQXJjKHRoaXMucGMsdGhpcy5yLHRoaXMuc3RhcnRBbmdsZSxyLHRoaXMuY291bnRlckNsb2Nrd2lzZSkuZW5kfWNob3JkSGVpZ2h0KCl7cmV0dXJuKDEtTWF0aC5jb3MoTWF0aC5hYnModGhpcy5zd2VlcC8yKSkpKnRoaXMucn1pbnRlcnNlY3QodCl7aWYodCBpbnN0YW5jZW9mIGEuUG9pbnQpcmV0dXJuIHRoaXMuY29udGFpbnModCk/W3RdOltdO2lmKHQgaW5zdGFuY2VvZiBhLkxpbmUpcmV0dXJuIGFuKHQsdGhpcyk7aWYodCBpbnN0YW5jZW9mIGEuUmF5KXJldHVybiB1cih0LHRoaXMpO2lmKHQgaW5zdGFuY2VvZiBhLkNpcmNsZSlyZXR1cm4gYXIodGhpcyx0KTtpZih0IGluc3RhbmNlb2YgYS5TZWdtZW50KXJldHVybiBqdCh0LHRoaXMpO2lmKHQgaW5zdGFuY2VvZiBhLkJveClyZXR1cm4gYmYodGhpcyx0KTtpZih0IGluc3RhbmNlb2YgYS5BcmMpcmV0dXJuIFFzKHRoaXMsdCk7aWYodCBpbnN0YW5jZW9mIGEuUG9seWdvbilyZXR1cm4gaHIodGhpcyx0KTtpZih0IGluc3RhbmNlb2YgYS5NdWx0aWxpbmUpcmV0dXJuIF9lKHRoaXMsdCl9ZGlzdGFuY2VUbyh0KXtpZih0IGluc3RhbmNlb2YgYS5Qb2ludCl7bGV0W24scl09YS5EaXN0YW5jZS5wb2ludDJhcmModCx0aGlzKTtyZXR1cm4gcj1yLnJldmVyc2UoKSxbbixyXX1pZih0IGluc3RhbmNlb2YgYS5DaXJjbGUpe2xldFtuLHJdPWEuRGlzdGFuY2UuYXJjMmNpcmNsZSh0aGlzLHQpO3JldHVybltuLHJdfWlmKHQgaW5zdGFuY2VvZiBhLkxpbmUpe2xldFtuLHJdPWEuRGlzdGFuY2UuYXJjMmxpbmUodGhpcyx0KTtyZXR1cm5bbixyXX1pZih0IGluc3RhbmNlb2YgYS5TZWdtZW50KXtsZXRbbixyXT1hLkRpc3RhbmNlLnNlZ21lbnQyYXJjKHQsdGhpcyk7cmV0dXJuIHI9ci5yZXZlcnNlKCksW24scl19aWYodCBpbnN0YW5jZW9mIGEuQXJjKXtsZXRbbixyXT1hLkRpc3RhbmNlLmFyYzJhcmModGhpcyx0KTtyZXR1cm5bbixyXX1pZih0IGluc3RhbmNlb2YgYS5Qb2x5Z29uKXtsZXRbbixyXT1hLkRpc3RhbmNlLnNoYXBlMnBvbHlnb24odGhpcyx0KTtyZXR1cm5bbixyXX1pZih0IGluc3RhbmNlb2YgYS5QbGFuYXJTZXQpe2xldFtuLHJdPWEuRGlzdGFuY2Uuc2hhcGUycGxhbmFyU2V0KHRoaXMsdCk7cmV0dXJuW24scl19aWYodCBpbnN0YW5jZW9mIGEuTXVsdGlsaW5lKXJldHVybiBhLkRpc3RhbmNlLnNoYXBlMm11bHRpbGluZSh0aGlzLHQpfWJyZWFrVG9GdW5jdGlvbmFsKCl7bGV0IHQ9W10sbj1bMCxNYXRoLlBJLzIsMipNYXRoLlBJLzIsMypNYXRoLlBJLzJdLHI9W3RoaXMucGMudHJhbnNsYXRlKHRoaXMuciwwKSx0aGlzLnBjLnRyYW5zbGF0ZSgwLHRoaXMuciksdGhpcy5wYy50cmFuc2xhdGUoLXRoaXMuciwwKSx0aGlzLnBjLnRyYW5zbGF0ZSgwLC10aGlzLnIpXSxpPVtdO2ZvcihsZXQgcz0wO3M8NDtzKyspcltzXS5vbih0aGlzKSYmaS5wdXNoKG5ldyBhLkFyYyh0aGlzLnBjLHRoaXMucix0aGlzLnN0YXJ0QW5nbGUsbltzXSx0aGlzLmNvdW50ZXJDbG9ja3dpc2UpKTtpZihpLmxlbmd0aD09PTApdC5wdXNoKHRoaXMuY2xvbmUoKSk7ZWxzZXtpLnNvcnQoKGMsbCk9PmMubGVuZ3RoLWwubGVuZ3RoKTtmb3IobGV0IGM9MDtjPGkubGVuZ3RoO2MrKyl7bGV0IGw9dC5sZW5ndGg+MD90W3QubGVuZ3RoLTFdOnZvaWQgMCxoO2w/aD1uZXcgYS5BcmModGhpcy5wYyx0aGlzLnIsbC5lbmRBbmdsZSxpW2NdLmVuZEFuZ2xlLHRoaXMuY291bnRlckNsb2Nrd2lzZSk6aD1uZXcgYS5BcmModGhpcy5wYyx0aGlzLnIsdGhpcy5zdGFydEFuZ2xlLGlbY10uZW5kQW5nbGUsdGhpcy5jb3VudGVyQ2xvY2t3aXNlKSxhLlV0aWxzLkVRXzAoaC5sZW5ndGgpfHx0LnB1c2goaC5jbG9uZSgpKX1sZXQgcz10Lmxlbmd0aD4wP3RbdC5sZW5ndGgtMV06dm9pZCAwLG87cz9vPW5ldyBhLkFyYyh0aGlzLnBjLHRoaXMucixzLmVuZEFuZ2xlLHRoaXMuZW5kQW5nbGUsdGhpcy5jb3VudGVyQ2xvY2t3aXNlKTpvPW5ldyBhLkFyYyh0aGlzLnBjLHRoaXMucix0aGlzLnN0YXJ0QW5nbGUsdGhpcy5lbmRBbmdsZSx0aGlzLmNvdW50ZXJDbG9ja3dpc2UpLCFhLlV0aWxzLkVRXzAoby5sZW5ndGgpJiYhYS5VdGlscy5FUShvLnN3ZWVwLDIqTWF0aC5QSSkmJnQucHVzaChvLmNsb25lKCkpfXJldHVybiB0fXRhbmdlbnRJblN0YXJ0KCl7bGV0IHQ9bmV3IGEuVmVjdG9yKHRoaXMucGMsdGhpcy5zdGFydCksbj10aGlzLmNvdW50ZXJDbG9ja3dpc2U/TWF0aC5QSS8yOi1NYXRoLlBJLzI7cmV0dXJuIHQucm90YXRlKG4pLm5vcm1hbGl6ZSgpfXRhbmdlbnRJbkVuZCgpe2xldCB0PW5ldyBhLlZlY3Rvcih0aGlzLnBjLHRoaXMuZW5kKSxuPXRoaXMuY291bnRlckNsb2Nrd2lzZT8tTWF0aC5QSS8yOk1hdGguUEkvMjtyZXR1cm4gdC5yb3RhdGUobikubm9ybWFsaXplKCl9cmV2ZXJzZSgpe3JldHVybiBuZXcgYS5BcmModGhpcy5wYyx0aGlzLnIsdGhpcy5lbmRBbmdsZSx0aGlzLnN0YXJ0QW5nbGUsIXRoaXMuY291bnRlckNsb2Nrd2lzZSl9dHJhbnNmb3JtKHQ9bmV3IGEuTWF0cml4KXtsZXQgbj10aGlzLnN0YXJ0LnRyYW5zZm9ybSh0KSxyPXRoaXMuZW5kLnRyYW5zZm9ybSh0KSxpPXRoaXMucGMudHJhbnNmb3JtKHQpLHM9dGhpcy5jb3VudGVyQ2xvY2t3aXNlO3JldHVybiB0LmEqdC5kPDAmJihzPSFzKSxhLkFyYy5hcmNTRShpLG4scixzKX1zdGF0aWMgYXJjU0UodCxuLHIsaSl7bGV0e3ZlY3RvcjpzfT1hLG89cyh0LG4pLnNsb3BlLGM9cyh0LHIpLnNsb3BlO2EuVXRpbHMuRVEobyxjKSYmKGMrPTIqTWF0aC5QSSxpPSEwKTtsZXQgbD1zKHQsbikubGVuZ3RoO3JldHVybiBuZXcgYS5BcmModCxsLG8sYyxpKX1kZWZpbml0ZUludGVncmFsKHQ9MCl7cmV0dXJuIHRoaXMuYnJlYWtUb0Z1bmN0aW9uYWwoKS5yZWR1Y2UoKGkscyk9Pmkrcy5jaXJjdWxhclNlZ21lbnREZWZpbml0ZUludGVncmFsKHQpLDApfWNpcmN1bGFyU2VnbWVudERlZmluaXRlSW50ZWdyYWwodCl7bGV0IG49bmV3IGEuTGluZSh0aGlzLnN0YXJ0LHRoaXMuZW5kKSxyPXRoaXMucGMubGVmdFRvKG4pLHM9bmV3IGEuU2VnbWVudCh0aGlzLnN0YXJ0LHRoaXMuZW5kKS5kZWZpbml0ZUludGVncmFsKHQpLG89dGhpcy5jaXJjdWxhclNlZ21lbnRBcmVhKCk7cmV0dXJuIHI/cy1vOnMrb31jaXJjdWxhclNlZ21lbnRBcmVhKCl7cmV0dXJuIC41KnRoaXMucip0aGlzLnIqKHRoaXMuc3dlZXAtTWF0aC5zaW4odGhpcy5zd2VlcCkpfXNvcnRQb2ludHModCl7bGV0e3ZlY3RvcjpufT1hO3JldHVybiB0LnNsaWNlKCkuc29ydCgocixpKT0+e2xldCBzPW4odGhpcy5wYyxyKS5zbG9wZSxvPW4odGhpcy5wYyxpKS5zbG9wZTtyZXR1cm4gczxvPy0xOnM+bz8xOjB9KX1nZXQgbmFtZSgpe3JldHVybiJhcmMifXN2Zyh0PXt9KXtsZXQgbj10aGlzLnN3ZWVwPD1NYXRoLlBJPyIwIjoiMSIscj10aGlzLmNvdW50ZXJDbG9ja3dpc2U/IjEiOiIwIjtyZXR1cm4gYS5VdGlscy5FUSh0aGlzLnN3ZWVwLDIqTWF0aC5QSSk/bmV3IGEuQ2lyY2xlKHRoaXMucGMsdGhpcy5yKS5zdmcodCk6YAo8cGF0aCBkPSJNJHt0aGlzLnN0YXJ0Lnh9LCR7dGhpcy5zdGFydC55fQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIEEke3RoaXMucn0sJHt0aGlzLnJ9IDAgJHtufSwke3J9ICR7dGhpcy5lbmQueH0sJHt0aGlzLmVuZC55fSIKICAgICAgICAgICAgICAgICAgICAke1B0KHtmaWxsOiJub25lIiwuLi50fSl9IC8+YH19YS5BcmM9eXU7Y29uc3QgeHU9KC4uLmUpPT5uZXcgYS5BcmMoLi4uZSk7YS5hcmM9eHU7Y2xhc3MgT2UgZXh0ZW5kcyB2dHtjb25zdHJ1Y3Rvcih0PXZvaWQgMCxuPXZvaWQgMCxyPXZvaWQgMCxpPXZvaWQgMCl7c3VwZXIoKSx0aGlzLnhtaW49dCx0aGlzLnltaW49bix0aGlzLnhtYXg9cix0aGlzLnltYXg9aX1jbG9uZSgpe3JldHVybiBuZXcgT2UodGhpcy54bWluLHRoaXMueW1pbix0aGlzLnhtYXgsdGhpcy55bWF4KX1nZXQgbG93KCl7cmV0dXJuIG5ldyBhLlBvaW50KHRoaXMueG1pbix0aGlzLnltaW4pfWdldCBoaWdoKCl7cmV0dXJuIG5ldyBhLlBvaW50KHRoaXMueG1heCx0aGlzLnltYXgpfWdldCBtYXgoKXtyZXR1cm4gdGhpcy5jbG9uZSgpfWdldCBjZW50ZXIoKXtyZXR1cm4gbmV3IGEuUG9pbnQoKHRoaXMueG1pbit0aGlzLnhtYXgpLzIsKHRoaXMueW1pbit0aGlzLnltYXgpLzIpfWdldCB3aWR0aCgpe3JldHVybiBNYXRoLmFicyh0aGlzLnhtYXgtdGhpcy54bWluKX1nZXQgaGVpZ2h0KCl7cmV0dXJuIE1hdGguYWJzKHRoaXMueW1heC10aGlzLnltaW4pfWdldCBib3goKXtyZXR1cm4gdGhpcy5jbG9uZSgpfW5vdF9pbnRlcnNlY3QodCl7cmV0dXJuIHRoaXMueG1heDx0LnhtaW58fHRoaXMueG1pbj50LnhtYXh8fHRoaXMueW1heDx0LnltaW58fHRoaXMueW1pbj50LnltYXh9aW50ZXJzZWN0KHQpe3JldHVybiF0aGlzLm5vdF9pbnRlcnNlY3QodCl9bWVyZ2UodCl7cmV0dXJuIG5ldyBPZSh0aGlzLnhtaW49PT12b2lkIDA/dC54bWluOk1hdGgubWluKHRoaXMueG1pbix0LnhtaW4pLHRoaXMueW1pbj09PXZvaWQgMD90LnltaW46TWF0aC5taW4odGhpcy55bWluLHQueW1pbiksdGhpcy54bWF4PT09dm9pZCAwP3QueG1heDpNYXRoLm1heCh0aGlzLnhtYXgsdC54bWF4KSx0aGlzLnltYXg9PT12b2lkIDA/dC55bWF4Ok1hdGgubWF4KHRoaXMueW1heCx0LnltYXgpKX1sZXNzX3RoYW4odCl7cmV0dXJuISEodGhpcy5sb3cubGVzc1RoYW4odC5sb3cpfHx0aGlzLmxvdy5lcXVhbFRvKHQubG93KSYmdGhpcy5oaWdoLmxlc3NUaGFuKHQuaGlnaCkpfWVxdWFsX3RvKHQpe3JldHVybiB0aGlzLmxvdy5lcXVhbFRvKHQubG93KSYmdGhpcy5oaWdoLmVxdWFsVG8odC5oaWdoKX1vdXRwdXQoKXtyZXR1cm4gdGhpcy5jbG9uZSgpfXN0YXRpYyBjb21wYXJhYmxlX21heCh0LG4pe3JldHVybiB0Lm1lcmdlKG4pfXN0YXRpYyBjb21wYXJhYmxlX2xlc3NfdGhhbih0LG4pe3JldHVybiB0Lmxlc3NUaGFuKG4pfXNldCh0LG4scixpKXt0aGlzLnhtaW49dCx0aGlzLnltaW49bix0aGlzLnhtYXg9cix0aGlzLnltYXg9aX10b1BvaW50cygpe3JldHVybltuZXcgYS5Qb2ludCh0aGlzLnhtaW4sdGhpcy55bWluKSxuZXcgYS5Qb2ludCh0aGlzLnhtYXgsdGhpcy55bWluKSxuZXcgYS5Qb2ludCh0aGlzLnhtYXgsdGhpcy55bWF4KSxuZXcgYS5Qb2ludCh0aGlzLnhtaW4sdGhpcy55bWF4KV19dG9TZWdtZW50cygpe2xldCB0PXRoaXMudG9Qb2ludHMoKTtyZXR1cm5bbmV3IGEuU2VnbWVudCh0WzBdLHRbMV0pLG5ldyBhLlNlZ21lbnQodFsxXSx0WzJdKSxuZXcgYS5TZWdtZW50KHRbMl0sdFszXSksbmV3IGEuU2VnbWVudCh0WzNdLHRbMF0pXX1yb3RhdGUodCxuPW5ldyBhLlBvaW50KXt0aHJvdyBVLk9QRVJBVElPTl9JU19OT1RfU1VQUE9SVEVEfXRyYW5zZm9ybSh0PW5ldyBhLk1hdHJpeCl7cmV0dXJuIHRoaXMudG9Qb2ludHMoKS5tYXAocj0+ci50cmFuc2Zvcm0odCkpLnJlZHVjZSgocixpKT0+ci5tZXJnZShpLmJveCksbmV3IE9lKX1jb250YWlucyh0KXtpZih0IGluc3RhbmNlb2YgYS5Qb2ludClyZXR1cm4gdC54Pj10aGlzLnhtaW4mJnQueDw9dGhpcy54bWF4JiZ0Lnk+PXRoaXMueW1pbiYmdC55PD10aGlzLnltYXg7aWYodCBpbnN0YW5jZW9mIGEuU2VnbWVudClyZXR1cm4gdC52ZXJ0aWNlcy5ldmVyeShuPT50aGlzLmNvbnRhaW5zKG4pKTtpZih0IGluc3RhbmNlb2YgYS5Cb3gpcmV0dXJuIHQudG9TZWdtZW50cygpLmV2ZXJ5KG49PnRoaXMuY29udGFpbnMobikpO2lmKHQgaW5zdGFuY2VvZiBhLkNpcmNsZSlyZXR1cm4gdGhpcy5jb250YWlucyh0LmJveCk7aWYodCBpbnN0YW5jZW9mIGEuQXJjKXJldHVybiB0LnZlcnRpY2VzLmV2ZXJ5KG49PnRoaXMuY29udGFpbnMobikpJiZ0LnRvU2VnbWVudHMoKS5ldmVyeShuPT5qdChuLHQpLmxlbmd0aD09PTApO2lmKHQgaW5zdGFuY2VvZiBhLkxpbmV8fHQgaW5zdGFuY2VvZiBhLlJheSlyZXR1cm4hMTtpZih0IGluc3RhbmNlb2YgYS5NdWx0aWxpbmUpcmV0dXJuIHQudG9TaGFwZXMoKS5ldmVyeShuPT50aGlzLmNvbnRhaW5zKG4pKTtpZih0IGluc3RhbmNlb2YgYS5Qb2x5Z29uKXJldHVybiB0aGlzLmNvbnRhaW5zKHQuYm94KX1kaXN0YW5jZVRvKHQpe2NvbnN0IG49dGhpcy50b1NlZ21lbnRzKCkubWFwKGk9PmkuZGlzdGFuY2VUbyh0KSk7bGV0IHI9W051bWJlci5NQVhfU0FGRV9JTlRFR0VSLG51bGxdO3JldHVybiBuLmZvckVhY2goaT0+e2lbMF08clswXSYmKHI9aSl9KSxyfWdldCBuYW1lKCl7cmV0dXJuImJveCJ9c3ZnKHQ9e30pe2NvbnN0IG49dGhpcy54bWF4LXRoaXMueG1pbixyPXRoaXMueW1heC10aGlzLnltaW47cmV0dXJuYAo8cmVjdCB4PSIke3RoaXMueG1pbn0iIHk9IiR7dGhpcy55bWlufSIgd2lkdGg9IiR7bn0iIGhlaWdodD0iJHtyfSIKICAgICAgICAgICAgICAgICR7UHQoe2ZpbGw6Im5vbmUiLC4uLnR9KX0gLz5gfX1hLkJveD1PZTtjb25zdCBNdT0oLi4uZSk9Pm5ldyBhLkJveCguLi5lKTthLmJveD1NdTtjbGFzcyB3dXtjb25zdHJ1Y3Rvcih0KXt0aGlzLnNoYXBlPXQsdGhpcy5uZXh0PXZvaWQgMCx0aGlzLnByZXY9dm9pZCAwLHRoaXMuZmFjZT12b2lkIDAsdGhpcy5hcmNfbGVuZ3RoPTAsdGhpcy5idlN0YXJ0PXZvaWQgMCx0aGlzLmJ2RW5kPXZvaWQgMCx0aGlzLmJ2PXZvaWQgMCx0aGlzLm92ZXJsYXA9dm9pZCAwfWdldCBzdGFydCgpe3JldHVybiB0aGlzLnNoYXBlLnN0YXJ0fWdldCBlbmQoKXtyZXR1cm4gdGhpcy5zaGFwZS5lbmR9Z2V0IGxlbmd0aCgpe3JldHVybiB0aGlzLnNoYXBlLmxlbmd0aH1nZXQgYm94KCl7cmV0dXJuIHRoaXMuc2hhcGUuYm94fWdldCBpc1NlZ21lbnQoKXtyZXR1cm4gdGhpcy5zaGFwZSBpbnN0YW5jZW9mIGEuU2VnbWVudH1nZXQgaXNBcmMoKXtyZXR1cm4gdGhpcy5zaGFwZSBpbnN0YW5jZW9mIGEuQXJjfWdldCBpc0xpbmUoKXtyZXR1cm4gdGhpcy5zaGFwZSBpbnN0YW5jZW9mIGEuTGluZX1nZXQgaXNSYXkoKXtyZXR1cm4gdGhpcy5zaGFwZSBpbnN0YW5jZW9mIGEuUmF5fW1pZGRsZSgpe3JldHVybiB0aGlzLnNoYXBlLm1pZGRsZSgpfXBvaW50QXRMZW5ndGgodCl7cmV0dXJuIHRoaXMuc2hhcGUucG9pbnRBdExlbmd0aCh0KX1jb250YWlucyh0KXtyZXR1cm4gdGhpcy5zaGFwZS5jb250YWlucyh0KX1zZXRJbmNsdXNpb24odCl7aWYodGhpcy5idiE9PXZvaWQgMClyZXR1cm4gdGhpcy5idjtpZih0aGlzLnNoYXBlIGluc3RhbmNlb2YgYS5MaW5lfHx0aGlzLnNoYXBlIGluc3RhbmNlb2YgYS5SYXkpcmV0dXJuIHRoaXMuYnY9YS5PVVRTSURFLHRoaXMuYnY7aWYodGhpcy5idlN0YXJ0PT09dm9pZCAwJiYodGhpcy5idlN0YXJ0PUFlKHQsdGhpcy5zdGFydCkpLHRoaXMuYnZFbmQ9PT12b2lkIDAmJih0aGlzLmJ2RW5kPUFlKHQsdGhpcy5lbmQpKSx0aGlzLmJ2U3RhcnQ9PT1hLk9VVFNJREV8fHRoaXMuYnZFbmQ9PWEuT1VUU0lERSl0aGlzLmJ2PWEuT1VUU0lERTtlbHNlIGlmKHRoaXMuYnZTdGFydD09PWEuSU5TSURFfHx0aGlzLmJ2RW5kPT1hLklOU0lERSl0aGlzLmJ2PWEuSU5TSURFO2Vsc2V7bGV0IG49QWUodCx0aGlzLm1pZGRsZSgpKTt0aGlzLmJ2PW59cmV0dXJuIHRoaXMuYnZ9c2V0T3ZlcmxhcCh0KXtsZXQgbixyPXRoaXMuc2hhcGUsaT10LnNoYXBlO3IgaW5zdGFuY2VvZiBhLlNlZ21lbnQmJmkgaW5zdGFuY2VvZiBhLlNlZ21lbnQ/ci5zdGFydC5lcXVhbFRvKGkuc3RhcnQpJiZyLmVuZC5lcXVhbFRvKGkuZW5kKT9uPWEuT1ZFUkxBUF9TQU1FOnIuc3RhcnQuZXF1YWxUbyhpLmVuZCkmJnIuZW5kLmVxdWFsVG8oaS5zdGFydCkmJihuPWEuT1ZFUkxBUF9PUFBPU0lURSk6KHIgaW5zdGFuY2VvZiBhLkFyYyYmaSBpbnN0YW5jZW9mIGEuQXJjfHxyIGluc3RhbmNlb2YgYS5TZWdtZW50JiZpIGluc3RhbmNlb2YgYS5BcmN8fHIgaW5zdGFuY2VvZiBhLkFyYyYmaSBpbnN0YW5jZW9mIGEuU2VnbWVudCkmJihyLnN0YXJ0LmVxdWFsVG8oaS5zdGFydCkmJnIuZW5kLmVxdWFsVG8oaS5lbmQpJiZyLm1pZGRsZSgpLmVxdWFsVG8oaS5taWRkbGUoKSk/bj1hLk9WRVJMQVBfU0FNRTpyLnN0YXJ0LmVxdWFsVG8oaS5lbmQpJiZyLmVuZC5lcXVhbFRvKGkuc3RhcnQpJiZyLm1pZGRsZSgpLmVxdWFsVG8oaS5taWRkbGUoKSkmJihuPWEuT1ZFUkxBUF9PUFBPU0lURSkpLHRoaXMub3ZlcmxhcD09PXZvaWQgMCYmKHRoaXMub3ZlcmxhcD1uKSx0Lm92ZXJsYXA9PT12b2lkIDAmJih0Lm92ZXJsYXA9bil9c3ZnKCl7aWYodGhpcy5zaGFwZSBpbnN0YW5jZW9mIGEuU2VnbWVudClyZXR1cm5gIEwke3RoaXMuc2hhcGUuZW5kLnh9LCR7dGhpcy5zaGFwZS5lbmQueX1gO2lmKHRoaXMuc2hhcGUgaW5zdGFuY2VvZiBhLkFyYyl7bGV0IHQ9dGhpcy5zaGFwZSxuLHI9dC5jb3VudGVyQ2xvY2t3aXNlPyIxIjoiMCI7aWYoYS5VdGlscy5FUSh0LnN3ZWVwLDIqTWF0aC5QSSkpe2xldCBpPXQuY291bnRlckNsb2Nrd2lzZT8xOi0xLHM9bmV3IGEuQXJjKHQucGMsdC5yLHQuc3RhcnRBbmdsZSx0LnN0YXJ0QW5nbGUraSpNYXRoLlBJLHQuY291bnRlckNsb2Nrd2lzZSksbz1uZXcgYS5BcmModC5wYyx0LnIsdC5zdGFydEFuZ2xlK2kqTWF0aC5QSSx0LmVuZEFuZ2xlLHQuY291bnRlckNsb2Nrd2lzZSk7cmV0dXJuIG49IjAiLGAgQSR7cy5yfSwke3Mucn0gMCAke259LCR7cn0gJHtzLmVuZC54fSwke3MuZW5kLnl9CiAgICAgICAgICAgICAgICAgICAgQSR7by5yfSwke28ucn0gMCAke259LCR7cn0gJHtvLmVuZC54fSwke28uZW5kLnl9YH1lbHNlIHJldHVybiBuPXQuc3dlZXA8PU1hdGguUEk/IjAiOiIxIixgIEEke3Qucn0sJHt0LnJ9IDAgJHtufSwke3J9ICR7dC5lbmQueH0sJHt0LmVuZC55fWB9fXRvSlNPTigpe3JldHVybiB0aGlzLnNoYXBlLnRvSlNPTigpfX1hLkVkZ2U9d3U7Y2xhc3MgQXUgZXh0ZW5kcyBjcntjb25zdHJ1Y3Rvcih0LG4pe3N1cGVyKHQsbiksdGhpcy5zZXRDaXJjdWxhckxpbmtzKCl9c2V0Q2lyY3VsYXJMaW5rcygpe3RoaXMuaXNFbXB0eSgpfHwodGhpcy5sYXN0Lm5leHQ9dGhpcy5maXJzdCx0aGlzLmZpcnN0LnByZXY9dGhpcy5sYXN0KX1bU3ltYm9sLml0ZXJhdG9yXSgpe2xldCB0O3JldHVybntuZXh0OigpPT57bGV0IG49dHx8dGhpcy5maXJzdCxyPXRoaXMuZmlyc3Q/dD90PT09dGhpcy5maXJzdDohMTohMDtyZXR1cm4gdD1uP24ubmV4dDp2b2lkIDAse3ZhbHVlOm4sZG9uZTpyfX19fWFwcGVuZCh0KXtyZXR1cm4gc3VwZXIuYXBwZW5kKHQpLHRoaXMuc2V0Q2lyY3VsYXJMaW5rcygpLHRoaXN9aW5zZXJ0KHQsbil7cmV0dXJuIHN1cGVyLmluc2VydCh0LG4pLHRoaXMuc2V0Q2lyY3VsYXJMaW5rcygpLHRoaXN9cmVtb3ZlKHQpe3JldHVybiBzdXBlci5yZW1vdmUodCksdGhpc319Y2xhc3MgbmUgZXh0ZW5kcyBBdXtjb25zdHJ1Y3Rvcih0LC4uLm4pe2lmKHN1cGVyKCksdGhpcy5fYm94PXZvaWQgMCx0aGlzLl9vcmllbnRhdGlvbj12b2lkIDAsbi5sZW5ndGghPT0wKXtpZihuLmxlbmd0aD09PTEpe2lmKG5bMF1pbnN0YW5jZW9mIEFycmF5KXtsZXQgcj1uWzBdO2lmKHIubGVuZ3RoPT09MClyZXR1cm47aWYoci5ldmVyeShpPT5pIGluc3RhbmNlb2YgYS5Qb2ludCkpe2xldCBpPW5lLnBvaW50czJzZWdtZW50cyhyKTt0aGlzLnNoYXBlczJmYWNlKHQuZWRnZXMsaSl9ZWxzZSBpZihyLmV2ZXJ5KGk9PmkgaW5zdGFuY2VvZiBBcnJheSYmaS5sZW5ndGg9PT0yKSl7bGV0IGk9ci5tYXAobz0+bmV3IGEuUG9pbnQob1swXSxvWzFdKSkscz1uZS5wb2ludHMyc2VnbWVudHMoaSk7dGhpcy5zaGFwZXMyZmFjZSh0LmVkZ2VzLHMpfWVsc2UgaWYoci5ldmVyeShpPT5pIGluc3RhbmNlb2YgYS5TZWdtZW50fHxpIGluc3RhbmNlb2YgYS5BcmMpKXRoaXMuc2hhcGVzMmZhY2UodC5lZGdlcyxyKTtlbHNlIGlmKHIuZXZlcnkoaT0+aS5uYW1lPT09InNlZ21lbnQifHxpLm5hbWU9PT0iYXJjIikpe2xldCBpPVtdO2ZvcihsZXQgcyBvZiByKXtsZXQgbztzLm5hbWU9PT0ic2VnbWVudCI/bz1uZXcgYS5TZWdtZW50KHMpOm89bmV3IGEuQXJjKHMpLGkucHVzaChvKX10aGlzLnNoYXBlczJmYWNlKHQuZWRnZXMsaSl9fWVsc2UgaWYoblswXWluc3RhbmNlb2YgbmUpe2xldCByPW5bMF07dGhpcy5maXJzdD1yLmZpcnN0LHRoaXMubGFzdD1yLmxhc3Q7Zm9yKGxldCBpIG9mIHIpdC5lZGdlcy5hZGQoaSl9ZWxzZSBpZihuWzBdaW5zdGFuY2VvZiBhLkNpcmNsZSl0aGlzLnNoYXBlczJmYWNlKHQuZWRnZXMsW25bMF0udG9BcmMoVXMpXSk7ZWxzZSBpZihuWzBdaW5zdGFuY2VvZiBhLkJveCl7bGV0IHI9blswXTt0aGlzLnNoYXBlczJmYWNlKHQuZWRnZXMsW25ldyBhLlNlZ21lbnQobmV3IGEuUG9pbnQoci54bWluLHIueW1pbiksbmV3IGEuUG9pbnQoci54bWF4LHIueW1pbikpLG5ldyBhLlNlZ21lbnQobmV3IGEuUG9pbnQoci54bWF4LHIueW1pbiksbmV3IGEuUG9pbnQoci54bWF4LHIueW1heCkpLG5ldyBhLlNlZ21lbnQobmV3IGEuUG9pbnQoci54bWF4LHIueW1heCksbmV3IGEuUG9pbnQoci54bWluLHIueW1heCkpLG5ldyBhLlNlZ21lbnQobmV3IGEuUG9pbnQoci54bWluLHIueW1heCksbmV3IGEuUG9pbnQoci54bWluLHIueW1pbikpXSl9fW4ubGVuZ3RoPT09MiYmblswXWluc3RhbmNlb2YgYS5FZGdlJiZuWzFdaW5zdGFuY2VvZiBhLkVkZ2UmJih0aGlzLmZpcnN0PW5bMF0sdGhpcy5sYXN0PW5bMV0sdGhpcy5sYXN0Lm5leHQ9dGhpcy5maXJzdCx0aGlzLmZpcnN0LnByZXY9dGhpcy5sYXN0LHRoaXMuc2V0QXJjTGVuZ3RoKCkpfX1nZXQgZWRnZXMoKXtyZXR1cm4gdGhpcy50b0FycmF5KCl9Z2V0IHNoYXBlcygpe3JldHVybiB0aGlzLmVkZ2VzLm1hcCh0PT50LnNoYXBlLmNsb25lKCkpfWdldCBib3goKXtpZih0aGlzLl9ib3g9PT12b2lkIDApe2xldCB0PW5ldyBhLkJveDtmb3IobGV0IG4gb2YgdGhpcyl0PXQubWVyZ2Uobi5ib3gpO3RoaXMuX2JveD10fXJldHVybiB0aGlzLl9ib3h9Z2V0IHBlcmltZXRlcigpe3JldHVybiB0aGlzLmxhc3QuYXJjX2xlbmd0aCt0aGlzLmxhc3QubGVuZ3RofXBvaW50QXRMZW5ndGgodCl7aWYodD50aGlzLnBlcmltZXRlcnx8dDwwKXJldHVybiBudWxsO2xldCBuPW51bGw7Zm9yKGxldCByIG9mIHRoaXMpaWYodD49ci5hcmNfbGVuZ3RoJiYocj09PXRoaXMubGFzdHx8dDxyLm5leHQuYXJjX2xlbmd0aCkpe249ci5wb2ludEF0TGVuZ3RoKHQtci5hcmNfbGVuZ3RoKTticmVha31yZXR1cm4gbn1zdGF0aWMgcG9pbnRzMnNlZ21lbnRzKHQpe2xldCBuPVtdO2ZvcihsZXQgcj0wO3I8dC5sZW5ndGg7cisrKXRbcl0uZXF1YWxUbyh0WyhyKzEpJXQubGVuZ3RoXSl8fG4ucHVzaChuZXcgYS5TZWdtZW50KHRbcl0sdFsocisxKSV0Lmxlbmd0aF0pKTtyZXR1cm4gbn1zaGFwZXMyZmFjZSh0LG4pe2ZvcihsZXQgciBvZiBuKXtsZXQgaT1uZXcgYS5FZGdlKHIpO3RoaXMuYXBwZW5kKGkpLHQuYWRkKGkpfX1hcHBlbmQodCl7cmV0dXJuIHN1cGVyLmFwcGVuZCh0KSx0aGlzLnNldE9uZUVkZ2VBcmNMZW5ndGgodCksdC5mYWNlPXRoaXMsdGhpc31pbnNlcnQodCxuKXtyZXR1cm4gc3VwZXIuaW5zZXJ0KHQsbiksdGhpcy5zZXRPbmVFZGdlQXJjTGVuZ3RoKHQpLHQuZmFjZT10aGlzLHRoaXN9cmVtb3ZlKHQpe3JldHVybiBzdXBlci5yZW1vdmUodCksdGhpcy5zZXRBcmNMZW5ndGgoKSx0aGlzfW1lcmdlX3dpdGhfbmV4dF9lZGdlKHQpe3JldHVybiB0LnNoYXBlLmVuZC54PXQubmV4dC5zaGFwZS5lbmQueCx0LnNoYXBlLmVuZC55PXQubmV4dC5zaGFwZS5lbmQueSx0aGlzLnJlbW92ZSh0Lm5leHQpLHRoaXN9cmV2ZXJzZSgpe2xldCB0PVtdLG49dGhpcy5sYXN0O2RvIG4uc2hhcGU9bi5zaGFwZS5yZXZlcnNlKCksdC5wdXNoKG4pLG49bi5wcmV2O3doaWxlKG4hPT10aGlzLmxhc3QpO3RoaXMuZmlyc3Q9dm9pZCAwLHRoaXMubGFzdD12b2lkIDA7Zm9yKGxldCByIG9mIHQpdGhpcy5maXJzdD09PXZvaWQgMD8oci5wcmV2PXIsci5uZXh0PXIsdGhpcy5maXJzdD1yLHRoaXMubGFzdD1yKTooci5wcmV2PXRoaXMubGFzdCx0aGlzLmxhc3QubmV4dD1yLHRoaXMubGFzdD1yLHRoaXMubGFzdC5uZXh0PXRoaXMuZmlyc3QsdGhpcy5maXJzdC5wcmV2PXRoaXMubGFzdCksdGhpcy5zZXRPbmVFZGdlQXJjTGVuZ3RoKHIpO3RoaXMuX29yaWVudGF0aW9uIT09dm9pZCAwJiYodGhpcy5fb3JpZW50YXRpb249dm9pZCAwLHRoaXMuX29yaWVudGF0aW9uPXRoaXMub3JpZW50YXRpb24oKSl9c2V0QXJjTGVuZ3RoKCl7Zm9yKGxldCB0IG9mIHRoaXMpdGhpcy5zZXRPbmVFZGdlQXJjTGVuZ3RoKHQpLHQuZmFjZT10aGlzfXNldE9uZUVkZ2VBcmNMZW5ndGgodCl7dD09PXRoaXMuZmlyc3Q/dC5hcmNfbGVuZ3RoPTA6dC5hcmNfbGVuZ3RoPXQucHJldi5hcmNfbGVuZ3RoK3QucHJldi5sZW5ndGh9YXJlYSgpe3JldHVybiBNYXRoLmFicyh0aGlzLnNpZ25lZEFyZWEoKSl9c2lnbmVkQXJlYSgpe2xldCB0PTAsbj10aGlzLmJveC55bWluO2ZvcihsZXQgciBvZiB0aGlzKXQrPXIuc2hhcGUuZGVmaW5pdGVJbnRlZ3JhbChuKTtyZXR1cm4gdH1vcmllbnRhdGlvbigpe2lmKHRoaXMuX29yaWVudGF0aW9uPT09dm9pZCAwKXtsZXQgdD10aGlzLnNpZ25lZEFyZWEoKTthLlV0aWxzLkVRXzAodCk/dGhpcy5fb3JpZW50YXRpb249c24uTk9UX09SSUVOVEFCTEU6YS5VdGlscy5MVCh0LDApP3RoaXMuX29yaWVudGF0aW9uPXNuLkNDVzp0aGlzLl9vcmllbnRhdGlvbj1zbi5DV31yZXR1cm4gdGhpcy5fb3JpZW50YXRpb259aXNTaW1wbGUodCl7cmV0dXJuIG5lLmdldFNlbGZJbnRlcnNlY3Rpb25zKHRoaXMsdCwhMCkubGVuZ3RoPT09MH1zdGF0aWMgZ2V0U2VsZkludGVyc2VjdGlvbnModCxuLHI9ITEpe2xldCBpPVtdO2ZvcihsZXQgcyBvZiB0KXtsZXQgbz1uLnNlYXJjaChzLmJveCk7Zm9yKGxldCBjIG9mIG8pe2lmKHM9PT1jfHxjLmZhY2UhPT10fHxzLnNoYXBlIGluc3RhbmNlb2YgYS5TZWdtZW50JiZjLnNoYXBlIGluc3RhbmNlb2YgYS5TZWdtZW50JiYocy5uZXh0PT09Y3x8cy5wcmV2PT09YykpY29udGludWU7bGV0IGw9cy5zaGFwZS5pbnRlcnNlY3QoYy5zaGFwZSk7Zm9yKGxldCBoIG9mIGwpaWYoIShoLmVxdWFsVG8ocy5zdGFydCkmJmguZXF1YWxUbyhjLmVuZCkmJmM9PT1zLnByZXYpJiYhKGguZXF1YWxUbyhzLmVuZCkmJmguZXF1YWxUbyhjLnN0YXJ0KSYmYz09PXMubmV4dCkmJihpLnB1c2goaCkscikpYnJlYWs7aWYoaS5sZW5ndGg+MCYmcilicmVha31pZihpLmxlbmd0aD4wJiZyKWJyZWFrfXJldHVybiBpfWZpbmRFZGdlQnlQb2ludCh0KXtsZXQgbjtmb3IobGV0IHIgb2YgdGhpcylpZighdC5lcXVhbFRvKHIuc2hhcGUuc3RhcnQpJiYodC5lcXVhbFRvKHIuc2hhcGUuZW5kKXx8ci5zaGFwZS5jb250YWlucyh0KSkpe249cjticmVha31yZXR1cm4gbn10b1BvbHlnb24oKXtyZXR1cm4gbmV3IGEuUG9seWdvbih0aGlzLnNoYXBlcyl9dG9KU09OKCl7cmV0dXJuIHRoaXMuZWRnZXMubWFwKHQ9PnQudG9KU09OKCkpfXN2Zygpe2xldCB0PWBNJHt0aGlzLmZpcnN0LnN0YXJ0Lnh9LCR7dGhpcy5maXJzdC5zdGFydC55fWA7Zm9yKGxldCBuIG9mIHRoaXMpdCs9bi5zdmcoKTtyZXR1cm4gdCs9IiB6Iix0fX1hLkZhY2U9bmU7Y2xhc3Mgd3IgZXh0ZW5kcyB2dHtjb25zdHJ1Y3RvciguLi50KXtpZihzdXBlcigpLHRoaXMucHQ9bmV3IGEuUG9pbnQsdGhpcy5ub3JtPW5ldyBhLlZlY3RvcigwLDEpLHQubGVuZ3RoIT09MCYmKHQubGVuZ3RoPj0xJiZ0WzBdaW5zdGFuY2VvZiBhLlBvaW50JiYodGhpcy5wdD10WzBdLmNsb25lKCkpLHQubGVuZ3RoIT09MSkpe2lmKHQubGVuZ3RoPT09MiYmdFsxXWluc3RhbmNlb2YgYS5WZWN0b3Ipe3RoaXMubm9ybT10WzFdLmNsb25lKCk7cmV0dXJufXRocm93IFUuSUxMRUdBTF9QQVJBTUVURVJTfX1jbG9uZSgpe3JldHVybiBuZXcgd3IodGhpcy5wdCx0aGlzLm5vcm0pfWdldCBzbG9wZSgpe3JldHVybiBuZXcgYS5WZWN0b3IodGhpcy5ub3JtLnksLXRoaXMubm9ybS54KS5zbG9wZX1nZXQgYm94KCl7bGV0IHQ9dGhpcy5zbG9wZTtyZXR1cm4gbmV3IGEuQm94KHQ+TWF0aC5QSS8yJiZ0PDMqTWF0aC5QSS8yP051bWJlci5ORUdBVElWRV9JTkZJTklUWTp0aGlzLnB0LngsdD49MCYmdDw9TWF0aC5QST90aGlzLnB0Lnk6TnVtYmVyLk5FR0FUSVZFX0lORklOSVRZLHQ+PU1hdGguUEkvMiYmdDw9MypNYXRoLlBJLzI/dGhpcy5wdC54Ok51bWJlci5QT1NJVElWRV9JTkZJTklUWSx0Pj1NYXRoLlBJJiZ0PD0yKk1hdGguUEl8fHQ9PT0wP3RoaXMucHQueTpOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFkpfWdldCBzdGFydCgpe3JldHVybiB0aGlzLnB0fWdldCBlbmQoKXt9Z2V0IGxlbmd0aCgpe3JldHVybiBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFl9Y29udGFpbnModCl7aWYodGhpcy5wdC5lcXVhbFRvKHQpKXJldHVybiEwO2xldCBuPW5ldyBhLlZlY3Rvcih0aGlzLnB0LHQpO3JldHVybiBhLlV0aWxzLkVRXzAodGhpcy5ub3JtLmRvdChuKSkmJmEuVXRpbHMuR0Uobi5jcm9zcyh0aGlzLm5vcm0pLDApfWNvb3JkKHQpe3JldHVybiBFbyh0LngsdC55KS5jcm9zcyh0aGlzLm5vcm0pfXNwbGl0KHQpe3JldHVybiB0aGlzLmNvbnRhaW5zKHQpP3RoaXMucHQuZXF1YWxUbyh0KT9bdGhpc106W25ldyBhLlNlZ21lbnQodGhpcy5wdCx0KSxuZXcgYS5SYXkodCx0aGlzLm5vcm0pXTpbXX1pbnRlcnNlY3QodCl7aWYodCBpbnN0YW5jZW9mIGEuUG9pbnQpcmV0dXJuIHRoaXMuY29udGFpbnModCk/W3RdOltdO2lmKHQgaW5zdGFuY2VvZiBhLlNlZ21lbnQpcmV0dXJuIGZyKHRoaXMsdCk7aWYodCBpbnN0YW5jZW9mIGEuQXJjKXJldHVybiB1cih0aGlzLHQpO2lmKHQgaW5zdGFuY2VvZiBhLkxpbmUpcmV0dXJuIHNvKHRoaXMsdCk7aWYodCBpbnN0YW5jZW9mIGEuUmF5KXJldHVybiBWZih0aGlzLHQpO2lmKHQgaW5zdGFuY2VvZiBhLkNpcmNsZSlyZXR1cm4gaW8odGhpcyx0KTtpZih0IGluc3RhbmNlb2YgYS5Cb3gpcmV0dXJuIENmKHRoaXMsdCk7aWYodCBpbnN0YW5jZW9mIGEuUG9seWdvbilyZXR1cm4gb28odGhpcyx0KX1yb3RhdGUodCxuPW5ldyBhLlBvaW50KXtyZXR1cm4gbmV3IGEuUmF5KHRoaXMucHQucm90YXRlKHQsbiksdGhpcy5ub3JtLnJvdGF0ZSh0KSl9dHJhbnNmb3JtKHQpe3JldHVybiBuZXcgYS5SYXkodGhpcy5wdC50cmFuc2Zvcm0odCksdGhpcy5ub3JtLmNsb25lKCkpfWdldCBuYW1lKCl7cmV0dXJuInJheSJ9c3ZnKHQsbj17fSl7bGV0IHI9bmV3IGEuTGluZSh0aGlzLnB0LHRoaXMubm9ybSksaT1YdChyLHQpO3JldHVybiBpPWkuZmlsdGVyKG89PnRoaXMuY29udGFpbnMobykpLGkubGVuZ3RoPT09MHx8aS5sZW5ndGg9PT0yPyIiOm5ldyBhLlNlZ21lbnQodGhpcy5wdCxpWzBdKS5zdmcobil9fWEuUmF5PXdyO2NvbnN0IFR1PSguLi5lKT0+bmV3IGEuUmF5KC4uLmUpO2EucmF5PVR1O2xldCB2ZT1jbGFzcyBpZXtjb25zdHJ1Y3Rvcigpe3RoaXMuZmFjZXM9bmV3IGEuUGxhbmFyU2V0LHRoaXMuZWRnZXM9bmV3IGEuUGxhbmFyU2V0O2xldCB0PVsuLi5hcmd1bWVudHNdO2lmKHQubGVuZ3RoPT09MSYmKHRbMF1pbnN0YW5jZW9mIEFycmF5JiZ0WzBdLmxlbmd0aD4wfHx0WzBdaW5zdGFuY2VvZiBhLkNpcmNsZXx8dFswXWluc3RhbmNlb2YgYS5Cb3gpKXtsZXQgbj10WzBdO2lmKHRbMF1pbnN0YW5jZW9mIEFycmF5JiZ0WzBdLmV2ZXJ5KHI9PnIgaW5zdGFuY2VvZiBBcnJheSkpaWYobi5ldmVyeShyPT5yIGluc3RhbmNlb2YgQXJyYXkmJnIubGVuZ3RoPT09MiYmdHlwZW9mIHJbMF09PSJudW1iZXIiJiZ0eXBlb2YgclsxXT09Im51bWJlciIpKXRoaXMuZmFjZXMuYWRkKG5ldyBhLkZhY2UodGhpcyxuKSk7ZWxzZSBmb3IobGV0IHIgb2YgbilpZihyIGluc3RhbmNlb2YgQXJyYXkmJnJbMF1pbnN0YW5jZW9mIEFycmF5JiZyWzBdLmV2ZXJ5KGk9PmkgaW5zdGFuY2VvZiBBcnJheSYmaS5sZW5ndGg9PT0yJiZ0eXBlb2YgaVswXT09Im51bWJlciImJnR5cGVvZiBpWzFdPT0ibnVtYmVyIikpZm9yKGxldCBpIG9mIHIpdGhpcy5mYWNlcy5hZGQobmV3IGEuRmFjZSh0aGlzLGkpKTtlbHNlIHRoaXMuZmFjZXMuYWRkKG5ldyBhLkZhY2UodGhpcyxyKSk7ZWxzZSB0aGlzLmZhY2VzLmFkZChuZXcgYS5GYWNlKHRoaXMsbikpfX1nZXQgYm94KCl7cmV0dXJuWy4uLnRoaXMuZmFjZXNdLnJlZHVjZSgodCxuKT0+dC5tZXJnZShuLmJveCksbmV3IGEuQm94KX1nZXQgdmVydGljZXMoKXtyZXR1cm5bLi4udGhpcy5lZGdlc10ubWFwKHQ9PnQuc3RhcnQpfWNsb25lKCl7bGV0IHQ9bmV3IGllO2ZvcihsZXQgbiBvZiB0aGlzLmZhY2VzKXQuYWRkRmFjZShuLnNoYXBlcyk7cmV0dXJuIHR9aXNFbXB0eSgpe3JldHVybiB0aGlzLmVkZ2VzLnNpemU9PT0wfWlzVmFsaWQoKXtsZXQgdD0hMDtmb3IobGV0IG4gb2YgdGhpcy5mYWNlcylpZighbi5pc1NpbXBsZSh0aGlzLmVkZ2VzKSl7dD0hMTticmVha31yZXR1cm4gdH1hcmVhKCl7bGV0IHQ9Wy4uLnRoaXMuZmFjZXNdLnJlZHVjZSgobixyKT0+bityLnNpZ25lZEFyZWEoKSwwKTtyZXR1cm4gTWF0aC5hYnModCl9YWRkRmFjZSguLi50KXtsZXQgbj1uZXcgYS5GYWNlKHRoaXMsLi4udCk7cmV0dXJuIHRoaXMuZmFjZXMuYWRkKG4pLG59ZGVsZXRlRmFjZSh0KXtmb3IobGV0IG4gb2YgdCl0aGlzLmVkZ2VzLmRlbGV0ZShuKTtyZXR1cm4gdGhpcy5mYWNlcy5kZWxldGUodCl9cmVjcmVhdGVGYWNlcygpe3RoaXMuZmFjZXMuY2xlYXIoKTtmb3IobGV0IHIgb2YgdGhpcy5lZGdlcylyLmZhY2U9bnVsbDtsZXQgdCxuPSEwO2Zvcig7bjspe249ITE7Zm9yKGxldCByIG9mIHRoaXMuZWRnZXMpaWYoci5mYWNlPT09bnVsbCl7dD1yLG49ITA7YnJlYWt9aWYobil7bGV0IHI9dDtkbyByPXIubmV4dDt3aGlsZShyLm5leHQhPT10KTt0aGlzLmFkZEZhY2UodCxyKX19fXJlbW92ZUNoYWluKHQsbixyKXtpZihyLm5leHQ9PT1uKXt0aGlzLmRlbGV0ZUZhY2UodCk7cmV0dXJufWZvcihsZXQgaT1uO2khPT1yLm5leHQ7aT1pLm5leHQpaWYodC5yZW1vdmUoaSksdGhpcy5lZGdlcy5kZWxldGUoaSksdC5pc0VtcHR5KCkpe3RoaXMuZGVsZXRlRmFjZSh0KTticmVha319YWRkVmVydGV4KHQsbil7bGV0IHI9bi5zaGFwZS5zcGxpdCh0KTtpZihyWzBdPT09bnVsbClyZXR1cm4gbi5wcmV2O2lmKHJbMV09PT1udWxsKXJldHVybiBuO2xldCBpPW5ldyBhLkVkZ2UoclswXSkscz1uLnByZXY7cmV0dXJuIG4uZmFjZS5pbnNlcnQoaSxzKSx0aGlzLmVkZ2VzLmRlbGV0ZShuKSx0aGlzLmVkZ2VzLmFkZChpKSxuLnNoYXBlPXJbMV0sdGhpcy5lZGdlcy5hZGQobiksaX1yZW1vdmVFbmRWZXJ0ZXgodCl7Y29uc3Qgbj10Lm5leHQ7biE9PXQmJih0LmZhY2UubWVyZ2Vfd2l0aF9uZXh0X2VkZ2UodCksdGhpcy5lZGdlcy5kZWxldGUobikpfWN1dCh0KXtsZXQgbj10aGlzLmNsb25lKCkscj17aW50X3BvaW50czE6W10saW50X3BvaW50czI6W10saW50X3BvaW50czFfc29ydGVkOltdLGludF9wb2ludHMyX3NvcnRlZDpbXX07Zm9yKGxldCBvIG9mIHQuZWRnZXMpZm9yKGxldCBjIG9mIG4uZWRnZXMpe2xldCBsPWVvKG8sYyk7Zm9yKGxldCBoIG9mIGwpUXQobyxoLHIuaW50X3BvaW50czEpLFF0KGMsaCxyLmludF9wb2ludHMyKX1pZihyLmludF9wb2ludHMxLmxlbmd0aD09PTApcmV0dXJuIG47ci5pbnRfcG9pbnRzMV9zb3J0ZWQ9T3Qoci5pbnRfcG9pbnRzMSksci5pbnRfcG9pbnRzMl9zb3J0ZWQ9T3Qoci5pbnRfcG9pbnRzMiksSnQodCxyLmludF9wb2ludHMxX3NvcnRlZCksSnQobixyLmludF9wb2ludHMyX3NvcnRlZCksZHIociksci5pbnRfcG9pbnRzMV9zb3J0ZWQ9T3Qoci5pbnRfcG9pbnRzMSksci5pbnRfcG9pbnRzMl9zb3J0ZWQ9T3Qoci5pbnRfcG9pbnRzMiksZ3Ioci5pbnRfcG9pbnRzMSksbXIoci5pbnRfcG9pbnRzMSxuKTtmb3IobGV0IG8gb2Ygci5pbnRfcG9pbnRzMV9zb3J0ZWQpby5lZGdlX2JlZm9yZSYmby5lZGdlX2FmdGVyJiZvLmVkZ2VfYmVmb3JlLmJ2PT09by5lZGdlX2FmdGVyLmJ2JiYoci5pbnRfcG9pbnRzMltvLmlkXT0tMSxvLmlkPS0xKTtpZihyLmludF9wb2ludHMxPXIuaW50X3BvaW50czEuZmlsdGVyKG89Pm8uaWQ+PTApLHIuaW50X3BvaW50czI9ci5pbnRfcG9pbnRzMi5maWx0ZXIobz0+by5pZD49MCksci5pbnRfcG9pbnRzMS5mb3JFYWNoKChvLGMpPT57by5pZD1jfSksci5pbnRfcG9pbnRzMi5mb3JFYWNoKChvLGMpPT57by5pZD1jfSksci5pbnRfcG9pbnRzMS5sZW5ndGg9PT0wKXJldHVybiBuO3IuaW50X3BvaW50czFfc29ydGVkPU90KHIuaW50X3BvaW50czEpLHIuaW50X3BvaW50czJfc29ydGVkPU90KHIuaW50X3BvaW50czIpO2xldCBpLHM7Zm9yKGxldCBvPTE7bzxyLmludF9wb2ludHMxX3NvcnRlZC5sZW5ndGg7bysrKWlmKHM9ci5pbnRfcG9pbnRzMV9zb3J0ZWRbb10saT1yLmludF9wb2ludHMxX3NvcnRlZFtvLTFdLHMuZWRnZV9iZWZvcmUmJnMuZWRnZV9iZWZvcmUuYnY9PT1vbil7bGV0IGM9aS5lZGdlX2FmdGVyLGw9cy5lZGdlX2JlZm9yZSxoPXQuZ2V0Q2hhaW4oYyxsKTthbyhyLmludF9wb2ludHMyW2kuaWRdLHIuaW50X3BvaW50czJbcy5pZF0saCksaC5mb3JFYWNoKGY9Pm4uZWRnZXMuYWRkKGYpKSxoPWgucmV2ZXJzZSgpLm1hcChmPT5uZXcgYS5FZGdlKGYuc2hhcGUucmV2ZXJzZSgpKSk7Zm9yKGxldCBmPTA7ZjxoLmxlbmd0aC0xO2YrKyloW2ZdLm5leHQ9aFtmKzFdLGhbZisxXS5wcmV2PWhbZl07YW8oci5pbnRfcG9pbnRzMltzLmlkXSxyLmludF9wb2ludHMyW2kuaWRdLGgpLGguZm9yRWFjaChmPT5uLmVkZ2VzLmFkZChmKSl9cmV0dXJuIG4ucmVjcmVhdGVGYWNlcygpLG59Y3V0V2l0aExpbmUodCl7bGV0IG49bmV3IEN0KFt0XSk7cmV0dXJuIHRoaXMuY3V0KG4pfWZpbmRFZGdlQnlQb2ludCh0KXtsZXQgbjtmb3IobGV0IHIgb2YgdGhpcy5mYWNlcylpZihuPXIuZmluZEVkZ2VCeVBvaW50KHQpLG4hPT12b2lkIDApYnJlYWs7cmV0dXJuIG59c3BsaXRUb0lzbGFuZHMoKXtpZih0aGlzLmlzRW1wdHkoKSlyZXR1cm5bXTtsZXQgdD10aGlzLnRvQXJyYXkoKTt0LnNvcnQoKGkscyk9PnMuYXJlYSgpLWkuYXJlYSgpKTtsZXQgbj1bLi4udFswXS5mYWNlc11bMF0ub3JpZW50YXRpb24oKSxyPXQuZmlsdGVyKGk9PlsuLi5pLmZhY2VzXVswXS5vcmllbnRhdGlvbigpPT09bik7Zm9yKGxldCBpIG9mIHQpe2xldCBzPVsuLi5pLmZhY2VzXVswXTtpZihzLm9yaWVudGF0aW9uKCkhPT1uKXtmb3IobGV0IG8gb2YgcilpZihzLnNoYXBlcy5ldmVyeShjPT5vLmNvbnRhaW5zKGMpKSl7by5hZGRGYWNlKHMuc2hhcGVzKTticmVha319fXJldHVybiByfXJldmVyc2UoKXtmb3IobGV0IHQgb2YgdGhpcy5mYWNlcyl0LnJldmVyc2UoKTtyZXR1cm4gdGhpc31jb250YWlucyh0KXtpZih0IGluc3RhbmNlb2YgYS5Qb2ludCl7bGV0IG49QWUodGhpcyx0KTtyZXR1cm4gbj09PW9ufHxuPT09dXR9ZWxzZSByZXR1cm4gQW8odGhpcyx0KX1kaXN0YW5jZVRvKHQpe2lmKHQgaW5zdGFuY2VvZiBhLlBvaW50KXtsZXRbbixyXT1hLkRpc3RhbmNlLnBvaW50MnBvbHlnb24odCx0aGlzKTtyZXR1cm4gcj1yLnJldmVyc2UoKSxbbixyXX1pZih0IGluc3RhbmNlb2YgYS5DaXJjbGV8fHQgaW5zdGFuY2VvZiBhLkxpbmV8fHQgaW5zdGFuY2VvZiBhLlNlZ21lbnR8fHQgaW5zdGFuY2VvZiBhLkFyYyl7bGV0W24scl09YS5EaXN0YW5jZS5zaGFwZTJwb2x5Z29uKHQsdGhpcyk7cmV0dXJuIHI9ci5yZXZlcnNlKCksW24scl19aWYodCBpbnN0YW5jZW9mIGEuUG9seWdvbil7bGV0IG49W051bWJlci5QT1NJVElWRV9JTkZJTklUWSxuZXcgYS5TZWdtZW50XSxyLGk7Zm9yKGxldCBzIG9mIHRoaXMuZWRnZXMpe2xldCBvPW5bMF07W3IsaV09YS5EaXN0YW5jZS5zaGFwZTJwbGFuYXJTZXQocy5zaGFwZSx0LmVkZ2VzLG8pLGEuVXRpbHMuTFQocixvKSYmKG49W3IsaV0pfXJldHVybiBufX1pbnRlcnNlY3QodCl7aWYodCBpbnN0YW5jZW9mIGEuUG9pbnQpcmV0dXJuIHRoaXMuY29udGFpbnModCk/W3RdOltdO2lmKHQgaW5zdGFuY2VvZiBhLkxpbmUpcmV0dXJuIHBlKHQsdGhpcyk7aWYodCBpbnN0YW5jZW9mIGEuUmF5KXJldHVybiBvbyh0LHRoaXMpO2lmKHQgaW5zdGFuY2VvZiBhLkNpcmNsZSlyZXR1cm4gdG8odCx0aGlzKTtpZih0IGluc3RhbmNlb2YgYS5TZWdtZW50KXJldHVybiBscih0LHRoaXMpO2lmKHQgaW5zdGFuY2VvZiBhLkFyYylyZXR1cm4gaHIodCx0aGlzKTtpZih0IGluc3RhbmNlb2YgYS5Qb2x5Z29uKXJldHVybiBQZih0LHRoaXMpO2lmKHQgaW5zdGFuY2VvZiBhLk11bHRpbGluZSlyZXR1cm4gTGYodCx0aGlzKX10cmFuc2xhdGUodCl7bGV0IG49bmV3IGllO2ZvcihsZXQgciBvZiB0aGlzLmZhY2VzKW4uYWRkRmFjZShyLnNoYXBlcy5tYXAoaT0+aS50cmFuc2xhdGUodCkpKTtyZXR1cm4gbn1yb3RhdGUodD0wLG49bmV3IGEuUG9pbnQpe2xldCByPW5ldyBpZTtmb3IobGV0IGkgb2YgdGhpcy5mYWNlcylyLmFkZEZhY2UoaS5zaGFwZXMubWFwKHM9PnMucm90YXRlKHQsbikpKTtyZXR1cm4gcn1zY2FsZSh0LG4pe2xldCByPW5ldyBpZTtmb3IobGV0IGkgb2YgdGhpcy5mYWNlcylyLmFkZEZhY2UoaS5zaGFwZXMubWFwKHM9PnMuc2NhbGUodCxuKSkpO3JldHVybiByfXRyYW5zZm9ybSh0PW5ldyBhLk1hdHJpeCl7bGV0IG49bmV3IGllO2ZvcihsZXQgciBvZiB0aGlzLmZhY2VzKW4uYWRkRmFjZShyLnNoYXBlcy5tYXAoaT0+aS50cmFuc2Zvcm0odCkpKTtyZXR1cm4gbn10b0pTT04oKXtyZXR1cm5bLi4udGhpcy5mYWNlc10ubWFwKHQ9PnQudG9KU09OKCkpfXRvQXJyYXkoKXtyZXR1cm5bLi4udGhpcy5mYWNlc10ubWFwKHQ9PnQudG9Qb2x5Z29uKCkpfWRwYXRoKCl7cmV0dXJuWy4uLnRoaXMuZmFjZXNdLnJlZHVjZSgodCxuKT0+dCtuLnN2ZygpLCIiKX1zdmcodD17fSl7bGV0IG49YAo8cGF0aCAke1B0KHtmaWxsUnVsZToiZXZlbm9kZCIsZmlsbDoibGlnaHRjeWFuIiwuLi50fSl9IGQ9ImA7Zm9yKGxldCByIG9mIHRoaXMuZmFjZXMpbis9YAoke3Iuc3ZnKCl9YDtyZXR1cm4gbis9YCIgPgo8L3BhdGg+YCxufX07YS5Qb2x5Z29uPXZlO2NvbnN0IEV1PSguLi5lKT0+bmV3IGEuUG9seWdvbiguLi5lKTthLnBvbHlnb249RXU7Y29uc3R7Q2lyY2xlOkFyLExpbmU6T28sUG9pbnQ6dm8sVmVjdG9yOmduLFV0aWxzOlRyfT1hO2NsYXNzIGJle2NvbnN0cnVjdG9yKHQpe3RoaXMuY2lyY2xlPXR9Z2V0IGludmVyc2lvbl9jaXJjbGUoKXtyZXR1cm4gdGhpcy5jaXJjbGV9c3RhdGljIGludmVyc2VQb2ludCh0LG4pe2NvbnN0IHI9bmV3IGduKHQucGMsbiksaT10LnIqdC5yLHM9ci5kb3Qocik7cmV0dXJuIFRyLkVRXzAocyk/bmV3IHZvKE51bWJlci5QT1NJVElWRV9JTkZJTklUWSxOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFkpOnQucGMudHJhbnNsYXRlKHIubXVsdGlwbHkoaS9zKSl9c3RhdGljIGludmVyc2VDaXJjbGUodCxuKXtjb25zdCByPXQucGMuZGlzdGFuY2VUbyhuLnBjKVswXTtpZihUci5FUShyLG4ucikpe2xldCBpPXQucip0LnIvKDIqbi5yKSxzPW5ldyBnbih0LnBjLG4ucGMpO3M9cy5ub3JtYWxpemUoKTtsZXQgbz10LnBjLnRyYW5zbGF0ZShzLm11bHRpcGx5KGkpKTtyZXR1cm4gbmV3IE9vKG8scyl9ZWxzZXtsZXQgaT1uZXcgZ24odC5wYyxuLnBjKSxzPXQucip0LnIvKGkuZG90KGkpLW4ucipuLnIpLG89dC5wYy50cmFuc2xhdGUoaS5tdWx0aXBseShzKSksYz1NYXRoLmFicyhzKSpuLnI7cmV0dXJuIG5ldyBBcihvLGMpfX1zdGF0aWMgaW52ZXJzZUxpbmUodCxuKXtjb25zdFtyLGldPXQucGMuZGlzdGFuY2VUbyhuKTtpZihUci5FUV8wKHIpKXJldHVybiBuLmNsb25lKCk7e2xldCBzPXQucip0LnIvKDIqciksbz1uZXcgZ24odC5wYyxpLmVuZCk7cmV0dXJuIG89by5tdWx0aXBseShzL3IpLG5ldyBBcih0LnBjLnRyYW5zbGF0ZShvKSxzKX19aW52ZXJzZSh0KXtpZih0IGluc3RhbmNlb2Ygdm8pcmV0dXJuIGJlLmludmVyc2VQb2ludCh0aGlzLmNpcmNsZSx0KTtpZih0IGluc3RhbmNlb2YgQXIpcmV0dXJuIGJlLmludmVyc2VDaXJjbGUodGhpcy5jaXJjbGUsdCk7aWYodCBpbnN0YW5jZW9mIE9vKXJldHVybiBiZS5pbnZlcnNlTGluZSh0aGlzLmNpcmNsZSx0KX19YS5JbnZlcnNpb249YmU7Y29uc3QgT3U9ZT0+bmV3IGEuSW52ZXJzaW9uKGUpO2EuaW52ZXJzaW9uPU91O2NsYXNzIHZ7c3RhdGljIHBvaW50MnBvaW50KHQsbil7cmV0dXJuIHQuZGlzdGFuY2VUbyhuKX1zdGF0aWMgcG9pbnQybGluZSh0LG4pe2xldCByPXQucHJvamVjdGlvbk9uKG4pO3JldHVybltuZXcgYS5WZWN0b3IodCxyKS5sZW5ndGgsbmV3IGEuU2VnbWVudCh0LHIpXX1zdGF0aWMgcG9pbnQyY2lyY2xlKHQsbil7bGV0W3IsaV09dC5kaXN0YW5jZVRvKG4uY2VudGVyKTtpZihhLlV0aWxzLkVRXzAocikpcmV0dXJuW24ucixuZXcgYS5TZWdtZW50KHQsbi50b0FyYygpLnN0YXJ0KV07e2xldCBzPU1hdGguYWJzKHItbi5yKSxvPW5ldyBhLlZlY3RvcihuLnBjLHQpLm5vcm1hbGl6ZSgpLm11bHRpcGx5KG4uciksYz1uLnBjLnRyYW5zbGF0ZShvKTtyZXR1cm5bcyxuZXcgYS5TZWdtZW50KHQsYyldfX1zdGF0aWMgcG9pbnQyc2VnbWVudCh0LG4pe2lmKG4uc3RhcnQuZXF1YWxUbyhuLmVuZCkpcmV0dXJuIHYucG9pbnQycG9pbnQodCxuLnN0YXJ0KTtsZXQgcj1uZXcgYS5WZWN0b3Iobi5zdGFydCxuLmVuZCksaT1uZXcgYS5WZWN0b3Iobi5zdGFydCx0KSxzPW5ldyBhLlZlY3RvcihuLmVuZCx0KSxvPXIuZG90KGkpLGM9LXIuZG90KHMpLGwsaDtpZihhLlV0aWxzLkdFKG8sMCkmJmEuVXRpbHMuR0UoYywwKSl7bGV0IGY9bi50YW5nZW50SW5TdGFydCgpO3JldHVybiBsPU1hdGguYWJzKGYuY3Jvc3MoaSkpLGg9bi5zdGFydC50cmFuc2xhdGUoZi5tdWx0aXBseShmLmRvdChpKSkpLFtsLG5ldyBhLlNlZ21lbnQodCxoKV19ZWxzZSByZXR1cm4gbzwwP3QuZGlzdGFuY2VUbyhuLnN0YXJ0KTp0LmRpc3RhbmNlVG8obi5lbmQpfXN0YXRpYyBwb2ludDJhcmModCxuKXtsZXQgcj1uZXcgYS5DaXJjbGUobi5wYyxuLnIpLGk9W10scyxvO3JldHVybltzLG9dPXYucG9pbnQyY2lyY2xlKHQsciksby5lbmQub24obikmJmkucHVzaCh2LnBvaW50MmNpcmNsZSh0LHIpKSxpLnB1c2godi5wb2ludDJwb2ludCh0LG4uc3RhcnQpKSxpLnB1c2godi5wb2ludDJwb2ludCh0LG4uZW5kKSksdi5zb3J0KGkpLGlbMF19c3RhdGljIHBvaW50MmVkZ2UodCxuKXtyZXR1cm4gbi5zaGFwZSBpbnN0YW5jZW9mIGEuU2VnbWVudD92LnBvaW50MnNlZ21lbnQodCxuLnNoYXBlKTp2LnBvaW50MmFyYyh0LG4uc2hhcGUpfXN0YXRpYyBzZWdtZW50MmxpbmUodCxuKXtsZXQgcj10LmludGVyc2VjdChuKTtpZihyLmxlbmd0aD4wKXJldHVyblswLG5ldyBhLlNlZ21lbnQoclswXSxyWzBdKV07bGV0IGk9W107cmV0dXJuIGkucHVzaCh2LnBvaW50MmxpbmUodC5zdGFydCxuKSksaS5wdXNoKHYucG9pbnQybGluZSh0LmVuZCxuKSksdi5zb3J0KGkpLGlbMF19c3RhdGljIHNlZ21lbnQyc2VnbWVudCh0LG4pe2xldCByPWxuKHQsbik7aWYoci5sZW5ndGg+MClyZXR1cm5bMCxuZXcgYS5TZWdtZW50KHJbMF0sclswXSldO2xldCBpPVtdLHMsbztyZXR1cm5bcyxvXT12LnBvaW50MnNlZ21lbnQobi5zdGFydCx0KSxpLnB1c2goW3Msby5yZXZlcnNlKCldKSxbcyxvXT12LnBvaW50MnNlZ21lbnQobi5lbmQsdCksaS5wdXNoKFtzLG8ucmV2ZXJzZSgpXSksaS5wdXNoKHYucG9pbnQyc2VnbWVudCh0LnN0YXJ0LG4pKSxpLnB1c2godi5wb2ludDJzZWdtZW50KHQuZW5kLG4pKSx2LnNvcnQoaSksaVswXX1zdGF0aWMgc2VnbWVudDJjaXJjbGUodCxuKXtsZXQgcj10LmludGVyc2VjdChuKTtpZihyLmxlbmd0aD4wKXJldHVyblswLG5ldyBhLlNlZ21lbnQoclswXSxyWzBdKV07bGV0IGk9bmV3IGEuTGluZSh0LnBzLHQucGUpLFtzLG9dPXYucG9pbnQybGluZShuLmNlbnRlcixpKTtpZihhLlV0aWxzLkdFKHMsbi5yKSYmby5lbmQub24odCkpcmV0dXJuIHYucG9pbnQyY2lyY2xlKG8uZW5kLG4pO3tsZXRbYyxsXT12LnBvaW50MmNpcmNsZSh0LnN0YXJ0LG4pLFtoLGZdPXYucG9pbnQyY2lyY2xlKHQuZW5kLG4pO3JldHVybiBhLlV0aWxzLkxUKGMsaCk/W2MsbF06W2gsZl19fXN0YXRpYyBzZWdtZW50MmFyYyh0LG4pe2xldCByPXQuaW50ZXJzZWN0KG4pO2lmKHIubGVuZ3RoPjApcmV0dXJuWzAsbmV3IGEuU2VnbWVudChyWzBdLHJbMF0pXTtsZXQgaT1uZXcgYS5MaW5lKHQucHMsdC5wZSkscz1uZXcgYS5DaXJjbGUobi5wYyxuLnIpLFtvLGNdPXYucG9pbnQybGluZShzLmNlbnRlcixpKTtpZihhLlV0aWxzLkdFKG8scy5yKSYmYy5lbmQub24odCkpe2xldFt1LGRdPXYucG9pbnQyY2lyY2xlKGMuZW5kLHMpO2lmKGQuZW5kLm9uKG4pKXJldHVyblt1LGRdfWxldCBsPVtdO2wucHVzaCh2LnBvaW50MmFyYyh0LnN0YXJ0LG4pKSxsLnB1c2godi5wb2ludDJhcmModC5lbmQsbikpO2xldCBoLGY7cmV0dXJuW2gsZl09di5wb2ludDJzZWdtZW50KG4uc3RhcnQsdCksbC5wdXNoKFtoLGYucmV2ZXJzZSgpXSksW2gsZl09di5wb2ludDJzZWdtZW50KG4uZW5kLHQpLGwucHVzaChbaCxmLnJldmVyc2UoKV0pLHYuc29ydChsKSxsWzBdfXN0YXRpYyBjaXJjbGUyY2lyY2xlKHQsbil7bGV0IHI9dC5pbnRlcnNlY3Qobik7aWYoci5sZW5ndGg+MClyZXR1cm5bMCxuZXcgYS5TZWdtZW50KHJbMF0sclswXSldO2lmKHQuY2VudGVyLmVxdWFsVG8obi5jZW50ZXIpKXtsZXQgaT10LnRvQXJjKCkscz1uLnRvQXJjKCk7cmV0dXJuIHYucG9pbnQycG9pbnQoaS5zdGFydCxzLnN0YXJ0KX1lbHNle2xldCBpPW5ldyBhLkxpbmUodC5jZW50ZXIsbi5jZW50ZXIpLHM9aS5pbnRlcnNlY3QodCksbz1pLmludGVyc2VjdChuKSxjPVtdO3JldHVybiBjLnB1c2godi5wb2ludDJwb2ludChzWzBdLG9bMF0pKSxjLnB1c2godi5wb2ludDJwb2ludChzWzBdLG9bMV0pKSxjLnB1c2godi5wb2ludDJwb2ludChzWzFdLG9bMF0pKSxjLnB1c2godi5wb2ludDJwb2ludChzWzFdLG9bMV0pKSx2LnNvcnQoYyksY1swXX19c3RhdGljIGNpcmNsZTJsaW5lKHQsbil7bGV0IHI9dC5pbnRlcnNlY3Qobik7aWYoci5sZW5ndGg+MClyZXR1cm5bMCxuZXcgYS5TZWdtZW50KHJbMF0sclswXSldO2xldFtpLHNdPXYucG9pbnQybGluZSh0LmNlbnRlcixuKSxbbyxjXT12LnBvaW50MmNpcmNsZShzLmVuZCx0KTtyZXR1cm4gYz1jLnJldmVyc2UoKSxbbyxjXX1zdGF0aWMgYXJjMmxpbmUodCxuKXtsZXQgcj1uLmludGVyc2VjdCh0KTtpZihyLmxlbmd0aD4wKXJldHVyblswLG5ldyBhLlNlZ21lbnQoclswXSxyWzBdKV07bGV0IGk9bmV3IGEuQ2lyY2xlKHQuY2VudGVyLHQuciksW3Msb109di5wb2ludDJsaW5lKGkuY2VudGVyLG4pO2lmKGEuVXRpbHMuR0UocyxpLnIpKXtsZXRbYyxsXT12LnBvaW50MmNpcmNsZShvLmVuZCxpKTtpZihsLmVuZC5vbih0KSlyZXR1cm5bYyxsXX1lbHNle2xldCBjPVtdO3JldHVybiBjLnB1c2godi5wb2ludDJsaW5lKHQuc3RhcnQsbikpLGMucHVzaCh2LnBvaW50MmxpbmUodC5lbmQsbikpLHYuc29ydChjKSxjWzBdfX1zdGF0aWMgYXJjMmNpcmNsZSh0LG4pe2xldCByPXQuaW50ZXJzZWN0KG4pO2lmKHIubGVuZ3RoPjApcmV0dXJuWzAsbmV3IGEuU2VnbWVudChyWzBdLHJbMF0pXTtsZXQgaT1uZXcgYS5DaXJjbGUodC5jZW50ZXIsdC5yKSxbcyxvXT12LmNpcmNsZTJjaXJjbGUoaSxuKTtpZihvLnN0YXJ0Lm9uKHQpKXJldHVybltzLG9dO3tsZXQgYz1bXTtyZXR1cm4gYy5wdXNoKHYucG9pbnQyY2lyY2xlKHQuc3RhcnQsbikpLGMucHVzaCh2LnBvaW50MmNpcmNsZSh0LmVuZCxuKSksdi5zb3J0KGMpLGNbMF19fXN0YXRpYyBhcmMyYXJjKHQsbil7bGV0IHI9dC5pbnRlcnNlY3Qobik7aWYoci5sZW5ndGg+MClyZXR1cm5bMCxuZXcgYS5TZWdtZW50KHJbMF0sclswXSldO2xldCBpPW5ldyBhLkNpcmNsZSh0LmNlbnRlcix0LnIpLHM9bmV3IGEuQ2lyY2xlKG4uY2VudGVyLG4uciksW28sY109di5jaXJjbGUyY2lyY2xlKGkscyk7aWYoYy5zdGFydC5vbih0KSYmYy5lbmQub24obikpcmV0dXJuW28sY107e2xldCBsPVtdLGgsZjtyZXR1cm5baCxmXT12LnBvaW50MmFyYyh0LnN0YXJ0LG4pLGYuZW5kLm9uKG4pJiZsLnB1c2goW2gsZl0pLFtoLGZdPXYucG9pbnQyYXJjKHQuZW5kLG4pLGYuZW5kLm9uKG4pJiZsLnB1c2goW2gsZl0pLFtoLGZdPXYucG9pbnQyYXJjKG4uc3RhcnQsdCksZi5lbmQub24odCkmJmwucHVzaChbaCxmLnJldmVyc2UoKV0pLFtoLGZdPXYucG9pbnQyYXJjKG4uZW5kLHQpLGYuZW5kLm9uKHQpJiZsLnB1c2goW2gsZi5yZXZlcnNlKCldKSxbaCxmXT12LnBvaW50MnBvaW50KHQuc3RhcnQsbi5zdGFydCksbC5wdXNoKFtoLGZdKSxbaCxmXT12LnBvaW50MnBvaW50KHQuc3RhcnQsbi5lbmQpLGwucHVzaChbaCxmXSksW2gsZl09di5wb2ludDJwb2ludCh0LmVuZCxuLnN0YXJ0KSxsLnB1c2goW2gsZl0pLFtoLGZdPXYucG9pbnQycG9pbnQodC5lbmQsbi5lbmQpLGwucHVzaChbaCxmXSksdi5zb3J0KGwpLGxbMF19fXN0YXRpYyBwb2ludDJwb2x5Z29uKHQsbil7bGV0IHI9W051bWJlci5QT1NJVElWRV9JTkZJTklUWSxuZXcgYS5TZWdtZW50XTtmb3IobGV0IGkgb2Ygbi5lZGdlcyl7bGV0W3Msb109di5wb2ludDJlZGdlKHQsaSk7YS5VdGlscy5MVChzLHJbMF0pJiYocj1bcyxvXSl9cmV0dXJuIHJ9c3RhdGljIHNoYXBlMnBvbHlnb24odCxuKXtsZXQgcj1bTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZLG5ldyBhLlNlZ21lbnRdO2ZvcihsZXQgaSBvZiBuLmVkZ2VzKXtsZXRbcyxvXT10LmRpc3RhbmNlVG8oaS5zaGFwZSk7YS5VdGlscy5MVChzLHJbMF0pJiYocj1bcyxvXSl9cmV0dXJuIHJ9c3RhdGljIHBvbHlnb24ycG9seWdvbih0LG4pe2xldCByPVtOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFksbmV3IGEuU2VnbWVudF07Zm9yKGxldCBpIG9mIHQuZWRnZXMpZm9yKGxldCBzIG9mIG4uZWRnZXMpe2xldFtvLGNdPWkuc2hhcGUuZGlzdGFuY2VUbyhzLnNoYXBlKTthLlV0aWxzLkxUKG8sclswXSkmJihyPVtvLGNdKX1yZXR1cm4gcn1zdGF0aWMgYm94MmJveF9taW5tYXgodCxuKXtsZXQgcj1NYXRoLm1heChNYXRoLm1heCh0LnhtaW4tbi54bWF4LDApLE1hdGgubWF4KG4ueG1pbi10LnhtYXgsMCkpLGk9TWF0aC5tYXgoTWF0aC5tYXgodC55bWluLW4ueW1heCwwKSxNYXRoLm1heChuLnltaW4tdC55bWF4LDApKSxzPXIqcitpKmksbz10Lm1lcmdlKG4pLGM9by54bWF4LW8ueG1pbixsPW8ueW1heC1vLnltaW4saD1jKmMrbCpsO3JldHVybltzLGhdfXN0YXRpYyBtaW5tYXhfdHJlZV9wcm9jZXNzX2xldmVsKHQsbixyLGkpe2xldCBzLG87Zm9yKGxldCBmIG9mIG4pW3Msb109di5ib3gyYm94X21pbm1heCh0LmJveCxmLml0ZW0ua2V5KSxmLml0ZW0udmFsdWUgaW5zdGFuY2VvZiBhLkVkZ2U/aS5pbnNlcnQoW3Msb10sZi5pdGVtLnZhbHVlLnNoYXBlKTppLmluc2VydChbcyxvXSxmLml0ZW0udmFsdWUpLGEuVXRpbHMuTFQobyxyKSYmKHI9byk7aWYobi5sZW5ndGg9PT0wKXJldHVybiByO2xldCBjPW4ubWFwKGY9PmYubGVmdC5pc05pbCgpP3ZvaWQgMDpmLmxlZnQpLmZpbHRlcihmPT5mIT09dm9pZCAwKSxsPW4ubWFwKGY9PmYucmlnaHQuaXNOaWwoKT92b2lkIDA6Zi5yaWdodCkuZmlsdGVyKGY9PmYhPT12b2lkIDApLGg9Wy4uLmMsLi4ubF0uZmlsdGVyKGY9PntsZXRbdSxkXT12LmJveDJib3hfbWlubWF4KHQuYm94LGYubWF4KTtyZXR1cm4gYS5VdGlscy5MRSh1LHIpfSk7cmV0dXJuIHI9di5taW5tYXhfdHJlZV9wcm9jZXNzX2xldmVsKHQsaCxyLGkpLHJ9c3RhdGljIG1pbm1heF90cmVlKHQsbixyKXtsZXQgaT1uZXcgVGUscz1bbi5pbmRleC5yb290XSxvPXI8TnVtYmVyLlBPU0lUSVZFX0lORklOSVRZP3IqcjpOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFk7cmV0dXJuIG89di5taW5tYXhfdHJlZV9wcm9jZXNzX2xldmVsKHQscyxvLGkpLGl9c3RhdGljIG1pbm1heF90cmVlX2NhbGNfZGlzdGFuY2UodCxuLHIpe2xldCBpLHM7aWYobiE9bnVsbCYmIW4uaXNOaWwoKSl7aWYoW2ksc109di5taW5tYXhfdHJlZV9jYWxjX2Rpc3RhbmNlKHQsbi5sZWZ0LHIpLHMpcmV0dXJuW2ksc107aWYoYS5VdGlscy5MVChpWzBdLE1hdGguc3FydChuLml0ZW0ua2V5LmxvdykpKXJldHVybltpLCEwXTtsZXRbbyxjXT12LmRpc3RhbmNlKHQsbi5pdGVtLnZhbHVlKTtyZXR1cm4gYS5VdGlscy5MVChvLGlbMF0pJiYoaT1bbyxjXSksW2ksc109di5taW5tYXhfdHJlZV9jYWxjX2Rpc3RhbmNlKHQsbi5yaWdodCxpKSxbaSxzXX1yZXR1cm5bciwhMV19c3RhdGljIHNoYXBlMnBsYW5hclNldCh0LG4scj1OdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFkpe2xldCBpPVtyLG5ldyBhLlNlZ21lbnRdLHM9ITE7aWYobiBpbnN0YW5jZW9mIGEuUGxhbmFyU2V0KXtsZXQgbz12Lm1pbm1heF90cmVlKHQsbixyKTtbaSxzXT12Lm1pbm1heF90cmVlX2NhbGNfZGlzdGFuY2UodCxvLnJvb3QsaSl9cmV0dXJuIGl9c3RhdGljIHNvcnQodCl7dC5zb3J0KChuLHIpPT5hLlV0aWxzLkxUKG5bMF0sclswXSk/LTE6YS5VdGlscy5HVChuWzBdLHJbMF0pPzE6MCl9c3RhdGljIGRpc3RhbmNlKHQsbil7cmV0dXJuIHQuZGlzdGFuY2VUbyhuKX1zdGF0aWMgc2hhcGUybXVsdGlsaW5lKHQsbil7bGV0IHI9W051bWJlci5QT1NJVElWRV9JTkZJTklUWSxuZXcgYS5TZWdtZW50XTtmb3IobGV0IGkgb2Ygbil7bGV0W3Msb109di5kaXN0YW5jZSh0LGkuc2hhcGUpO2EuVXRpbHMuTFQocyxyWzBdKSYmKHI9W3Msb10pfXJldHVybiByfXN0YXRpYyBtdWx0aWxpbmUybXVsdGlsaW5lKHQsbil7bGV0IHI9W051bWJlci5QT1NJVElWRV9JTkZJTklUWSxuZXcgYS5TZWdtZW50XTtmb3IobGV0IGkgb2YgdClmb3IobGV0IHMgb2Ygbil7bGV0W28sY109di5kaXN0YW5jZShpLnNoYXBlLHMuc2hhcGUpO2EuVXRpbHMuTFQobyxyWzBdKSYmKHI9W28sY10pfXJldHVybiByfX1hLkRpc3RhbmNlPXY7Y29uc3R7TXVsdGlsaW5lOnZ1LFBvaW50OmJvLFNlZ21lbnQ6YnUsUG9seWdvbjpJb309YTtmdW5jdGlvbiBFcihlKXtyZXR1cm4gbmV3IGJvKGUuc3BsaXQoIiAiKS5tYXAoTnVtYmVyKSl9ZnVuY3Rpb24gU28oZSl7cmV0dXJuIGUuc3BsaXQoIiwgIikubWFwKEVyKX1mdW5jdGlvbiBPcihlKXtjb25zdCB0PVNvKGUpO2xldCBuPVtdO2ZvcihsZXQgcj0wO3I8dC5sZW5ndGgtMTtyKyspbi5wdXNoKG5ldyBidSh0W3JdLHRbcisxXSkpO3JldHVybiBuZXcgdnUobil9ZnVuY3Rpb24gSXUoZSl7cmV0dXJuIGUucmVwbGFjZSgvXChcKC8sIiIpLnJlcGxhY2UoL1wpXCkkLywiIikuc3BsaXQoIiksICgiKS5tYXAoT3IpfWZ1bmN0aW9uIExvKGUpe2NvbnN0IHQ9ZS5yZXBsYWNlKC9cKFwoLywiIikucmVwbGFjZSgvXClcKSQvLCIiKS5zcGxpdCgiKSwgKCIpLG49bmV3IElvO2xldCByO3JldHVybiB0LmZvckVhY2goKGkscyk9PntsZXQgbz1pLnNwbGl0KCIsICIpLm1hcChsPT5uZXcgYm8obC5zcGxpdCgiICIpLm1hcChOdW1iZXIpKSk7Y29uc3QgYz1uLmFkZEZhY2Uobyk7cz09PTA/cj1jLm9yaWVudGF0aW9uKCk6Yy5vcmllbnRhdGlvbigpPT09ciYmYy5yZXZlcnNlKCl9KSxufWZ1bmN0aW9uIFN1KGUpe2NvbnN0IG49ZS5zcGxpdCgvXClcKSwgXChcKC8pLm1hcChzPT4iKCgiK3MrIikpIikubWFwKExvKSxyPW5ldyBJbztyZXR1cm4gbi5yZWR1Y2UoKHMsbyk9PlsuLi5zLC4uLm89PW51bGw/dm9pZCAwOm8uZmFjZXNdLFtdKS5mb3JFYWNoKHM9PnIuYWRkRmFjZShbLi4ucz09bnVsbD92b2lkIDA6cy5zaGFwZXNdKSkscn1mdW5jdGlvbiBMdShlKXtpZihlLnN0YXJ0c1dpdGgoIlBPTFlHT04iKSl7Y29uc3QgdD1lLnJlcGxhY2UoL15QT0xZR09OIC8sIiIpO3JldHVybiBMbyh0KX1lbHNle2NvbnN0IHQ9ZS5yZXBsYWNlKC9eTVVMVElQT0xZR09OIFwoXChcKCguKilcKVwpXCkkLywiJDEiKTtyZXR1cm4gU3UodCl9fWZ1bmN0aW9uIFB1KGUpe3JldHVybiBlLnNwbGl0KGAKYCkubWFwKG49Pm4ubWF0Y2goL1woKFteKV0rKVwpLylbMV0pLm1hcChFcil9ZnVuY3Rpb24gUnUoZSl7cmV0dXJuIGUuc3BsaXQoYApgKS5tYXAobj0+bi5tYXRjaCgvXCgoW14pXSspXCkvKVsxXSkubWFwKE9yKS5yZWR1Y2UoKG4scik9PlsuLi5uLC4uLnJdLFtdKX1mdW5jdGlvbiBQbyhlKXtpZihlLnN0YXJ0c1dpdGgoIlBPSU5UIikpe2NvbnN0IHQ9ZS5yZXBsYWNlKC9eUE9JTlQgXCgvLCIiKS5yZXBsYWNlKC9cKSQvLCIiKTtyZXR1cm4gRXIodCl9ZWxzZSBpZihlLnN0YXJ0c1dpdGgoIk1VTFRJUE9JTlQiKSl7Y29uc3QgdD1lLnJlcGxhY2UoL15NVUxUSVBPSU5UIFwoLywiIikucmVwbGFjZSgvXCkkLywiIik7cmV0dXJuIFNvKHQpfWVsc2UgaWYoZS5zdGFydHNXaXRoKCJMSU5FU1RSSU5HIikpe2NvbnN0IHQ9ZS5yZXBsYWNlKC9eTElORVNUUklORyBcKC8sIiIpLnJlcGxhY2UoL1wpJC8sIiIpO3JldHVybiBPcih0KX1lbHNlIGlmKGUuc3RhcnRzV2l0aCgiTVVMVElMSU5FU1RSSU5HIikpe2NvbnN0IHQ9ZS5yZXBsYWNlKC9eTVVMVElMSU5FU1RSSU5HIC8sIiIpO3JldHVybiBJdSh0KX1lbHNle2lmKGUuc3RhcnRzV2l0aCgiUE9MWUdPTiIpfHxlLnN0YXJ0c1dpdGgoIk1VTFRJUE9MWUdPTiIpKXJldHVybiBMdShlKTtpZihlLnN0YXJ0c1dpdGgoIkdFT01FVFJZQ09MTEVDVElPTiIpKXtjb25zdCB0PS8oPzx0eXBlPlBPSU5UfExJTkVTVFJJTkd8UE9MWUdPTnxNVUxUSVBPSU5UfE1VTFRJTElORVNUUklOR3xNVUxUSVBPTFlHT04pIFwoKD86W15cKFwpXXxcKFteXCldKlwpKSpcKS9nLG49ZS5tYXRjaCh0KTtyZXR1cm4gblswXS5zdGFydHNXaXRoKCJHRU9NRVRSWUNPTExFQ1RJT04iKSYmKG5bMF09blswXS5yZXBsYWNlKCJHRU9NRVRSWUNPTExFQ1RJT04gKCIsIiIpKSxuLm1hcChQbykubWFwKGk9PmkgaW5zdGFuY2VvZiBBcnJheT9pOltpXSkucmVkdWNlKChpLHMpPT5bLi4uaSwuLi5zXSxbXSl9ZWxzZXtpZihSbyhlKSlyZXR1cm4gUHUoZSk7aWYoQ28oZSkpcmV0dXJuIFJ1KGUpfX1yZXR1cm5bXX1mdW5jdGlvbiBSbyhlKXt2YXIgdDtyZXR1cm4odD1lLnNwbGl0KGAKYCkpPT1udWxsP3ZvaWQgMDp0LmV2ZXJ5KG49Pm4uaW5jbHVkZXMoIlBPSU5UIikpfWZ1bmN0aW9uIENvKGUpe3ZhciB0O3JldHVybih0PWUuc3BsaXQoYApgKSk9PW51bGw/dm9pZCAwOnQuZXZlcnkobj0+bi5pbmNsdWRlcygiTElORVNUUklORyIpKX1mdW5jdGlvbiBDdShlKXtyZXR1cm4gZS5zdGFydHNXaXRoKCJQT0lOVCIpfHxSbyhlKXx8ZS5zdGFydHNXaXRoKCJMSU5FU1RSSU5HIil8fENvKGUpfHxlLnN0YXJ0c1dpdGgoIk1VTFRJTElORVNUUklORyIpfHxlLnN0YXJ0c1dpdGgoIlBPTFlHT04iKXx8ZS5zdGFydHNXaXRoKCJNVUxUSVBPSU5UIil8fGUuc3RhcnRzV2l0aCgiTVVMVElQT0xZR09OIil8fGUuc3RhcnRzV2l0aCgiR0VPTUVUUllDT0xMRUNUSU9OIil9YS5pc1drdFN0cmluZz1DdSxhLnBhcnNlV0tUPVBvLGEuQm9vbGVhbk9wZXJhdGlvbnM9d2UsYS5SZWxhdGlvbnM9b3U7Y29uc3QgSWU9WyJwb3NpdGlvbiJdO2NsYXNzIFZve2NvbnN0cnVjdG9yKHQpe3EodGhpcywiZ2VvbWV0cnkiKTtxKHRoaXMsInBvc2l0aW9uTmFtZXMiLEllKTtxKHRoaXMsInJlZ2lvbiIpO3EodGhpcywicmVsYXRpb24iKTtxKHRoaXMsInJlbGF0aW9uRXF1YWwiKTtxKHRoaXMsIl9nZW9tZXRyeVBvbHlnb24iLG51bGwpO3EodGhpcywicG9zaXRpb25SZWxhdGlvbnMiKTtxKHRoaXMsImZhY2VSZWxhdGlvbnMiKTtxKHRoaXMsInJlbGF0aW9uSW5kZXhzV2l0aG91dFRocm91Z24iKTtxKHRoaXMsIl90aHJvdWdoSW5kZXhzIixbXSk7cSh0aGlzLCJfdGhyb3VnaEZhY2VzIixudWxsKTtxKHRoaXMsIl90aHJvdWdoRmFjZUFyZWFzIixudWxsKTtxKHRoaXMsIl9nZXRQb3NpdGlvbiIsbnVsbCk7cSh0aGlzLCJfcmVsYXRpb25BcmVhIixudWxsKTtxKHRoaXMsIl9hcmVhIixudWxsKTtxKHRoaXMsIl9yZWxhdGlvblZvbHVtZSIsbnVsbCk7cSh0aGlzLCJfdm9sdW1lIixudWxsKTt0JiZ0aGlzLnNldE9wdGlvbnModCl9Z2V0IGluY2x1ZGluZ1Rocm91Z2goKXtyZXR1cm4gdGhpcy5yZWxhdGlvbiZ5LlRocm91Z2hJbnRlcnNlY3R9c2V0T3B0aW9ucyh0KXtpZihPYmplY3QuYXNzaWduKHRoaXMsdCksdC5wb3NpdGlvbk5hbWVzJiYodGhpcy5fZ2V0UG9zaXRpb249bnVsbCksdC5nZW9tZXRyeXx8dC5wb3NpdGlvbk5hbWVzfHx0LnJlZ2lvbilyZXR1cm4odC5nZW9tZXRyeXx8dC5wb3NpdGlvbk5hbWVzKSYmKHRoaXMuX2dlb21ldHJ5UG9seWdvbj1udWxsKSx0aGlzLnVwZGF0ZSgpO2lmKHQucmVsYXRpb258fHQuc3RyaWN0KXJldHVybiB0aGlzLl9yZWxhdGlvbkFyZWE9bnVsbCx0aGlzLl9yZWxhdGlvblZvbHVtZT1udWxsLHRoaXMudXBkYXRlUmVsYXRpb25JbmRleHMoKX1nZXQgZ2VvbWV0cnlQb2x5Z29uKCl7cmV0dXJuIHRoaXMuX2dlb21ldHJ5UG9seWdvbnx8KHRoaXMuX2dlb21ldHJ5UG9seWdvbj10aGlzLmdlbmVyYXRlR2VvbWV0cnlQb2x5Z29uKCkpLHRoaXMuX2dlb21ldHJ5UG9seWdvbn1nZW5lcmF0ZUdlb21ldHJ5UG9seWdvbigpe2NvbnN0IHQ9bmV3IHZlO3JldHVybiB0aGlzLmdlb21ldHJ5Lm1hcEZhY2VGb3JBZ2dyZWdhdGUodGhpcy5wb3NpdGlvbk5hbWVzLG49Pntjb25zdCByPW4ubWFwKGk9Pm5ldyBkbihpWzBdLGlbMV0pKTt0LmFkZEZhY2Uocil9KSx0fWdldCB0aHJvdWdoSW5kZXhzKCl7cmV0dXJuIHRoaXMuX3Rocm91Z2hJbmRleHN9c2V0IHRocm91Z2hJbmRleHModCl7dGhpcy5fdGhyb3VnaEluZGV4cz10LHRoaXMuX3Rocm91Z2hGYWNlcz1udWxsLHRoaXMuX3Rocm91Z2hGYWNlQXJlYXM9bnVsbH1nZXQgdGhyb3VnaEZhY2VzKCl7cmV0dXJuIHRoaXMuX3Rocm91Z2hGYWNlc3x8KHRoaXMuX3Rocm91Z2hGYWNlcz10aGlzLmdlbmVyYXRlVGhyb3VnaEZhY2VzKCkpLHRoaXMuX3Rocm91Z2hGYWNlc31nZXQgdGhyb3VnaEZhY2VBcmVhcygpe3JldHVybiB0aGlzLl90aHJvdWdoRmFjZUFyZWFzfHwodGhpcy5fdGhyb3VnaEZhY2VBcmVhcz10aGlzLmdlbmVyYXRlVGhyb3VnaEZhY2VBcmVhcygpKSx0aGlzLl90aHJvdWdoRmFjZUFyZWFzfWdlbmVyYXRlVGhyb3VnaEZhY2VBcmVhcygpe3JldHVybiB0aGlzLnRocm91Z2hGYWNlcy5tYXAodD0+dC5hcmVhKCkpfXVwZGF0ZSgpe3RoaXMudXBkYXRlUG9zaXRpb25SZWxhdGlvbnMoKSx0aGlzLnVwZGF0ZUZhY2VSZWxhdGlvbnMoKSx0aGlzLnVwZGF0ZVJlbGF0aW9uSW5kZXhzKCksdGhpcy5pbmNsdWRpbmdUaHJvdWdoJiZ0aGlzLnVwZGF0ZVRocm91Z2hJbmRleHMoKSx0aGlzLnJlc2V0TWVhc3VyZSgpfXVwZGF0ZVBvc2l0aW9uUmVsYXRpb25zKCl7dGhpcy5wb3NpdGlvblJlbGF0aW9ucz10aGlzLmdlbmVyYXRlUG9zaXRpb25SZWxhdGlvbnMoKX11cGRhdGVGYWNlUmVsYXRpb25zKCl7dGhpcy5mYWNlUmVsYXRpb25zPXRoaXMuZ2VuZXJhdGVGYWNlUmVsYXRpb25zKCl9dXBkYXRlUmVsYXRpb25JbmRleHMoKXtjb25zdCB0PX55LlRocm91Z2hJbnRlcnNlY3QmdGhpcy5yZWxhdGlvbjt0aGlzLnJlbGF0aW9uSW5kZXhzV2l0aG91dFRocm91Z249dGhpcy5maWx0ZXJGYWNlcyh0LHRoaXMucmVsYXRpb25FcXVhbCl9dXBkYXRlVGhyb3VnaEluZGV4cygpe3RoaXMudGhyb3VnaEluZGV4cz10aGlzLmZpbHRlckZhY2VzKHkuVGhyb3VnaEludGVyc2VjdCxzZS5lcXVhbCksdGhpcy5fdGhyb3VnaEZhY2VzPW51bGwsdGhpcy5fdGhyb3VnaEZhY2VBcmVhcz1udWxsfXJlc2V0TWVhc3VyZSgpe3RoaXMuX3JlbGF0aW9uQXJlYT1udWxsLHRoaXMuX3JlbGF0aW9uVm9sdW1lPW51bGwsdGhpcy5fYXJlYT1udWxsLHRoaXMuX3ZvbHVtZT1udWxsfXVwZGF0ZU1lYXN1cmUoKXt0aGlzLnJlc2V0TWVhc3VyZSgpLHRoaXMucmVsYXRpb25BcmVhLHRoaXMucmVsYXRpb25Wb2x1bWUsdGhpcy5hcmVhLHRoaXMudm9sdW1lfWdldCBnZXRQb3NpdGlvbigpe3JldHVybiB0aGlzLl9nZXRQb3NpdGlvbnx8KHRoaXMuX2dldFBvc2l0aW9uPXRoaXMuZ2VvbWV0cnkuY3JlYXRlQWdncmVnYXRlVmVjdG9yR2V0dGVyKHRoaXMucG9zaXRpb25OYW1lcykpfWdldCByZWxhdGlvbkFyZWEoKXtyZXR1cm4gdGhpcy5fcmVsYXRpb25BcmVhPT1udWxsJiYodGhpcy5fcmVsYXRpb25BcmVhPXRoaXMuY29tcHV0ZVJlbGF0aW9uQXJlYSgpKSx0aGlzLl9yZWxhdGlvbkFyZWF9Y29tcHV0ZVJlbGF0aW9uQXJlYSgpe2NvbnN0e2dlb21ldHJ5OnR9PXRoaXMsbj10aGlzLnJlbGF0aW9uSW5kZXhzV2l0aG91dFRocm91Z24uZmxhdE1hcChpPT5bLi4udC5pbmRpY2VzLmdldFZlY3RvcihpKV0pO2xldCByPXJyKG4sdGhpcy5nZXRQb3NpdGlvbik7aWYodGhpcy5pbmNsdWRpbmdUaHJvdWdoKWZvcihjb25zdCBpIG9mIHRoaXMudGhyb3VnaEZhY2VBcmVhcylyKz1pO3JldHVybiByfWdldCBhcmVhKCl7cmV0dXJuIHRoaXMuX2FyZWE9PW51bGwmJih0aGlzLl9hcmVhPXRoaXMuY29tcHV0ZUFyZWEoKSksdGhpcy5fYXJlYX1jb21wdXRlQXJlYSgpe3JldHVybiBycih0aGlzLmdlb21ldHJ5LmluZGljZXMuYXJyYXksdGhpcy5nZXRQb3NpdGlvbil9Z2V0IHJlbGF0aW9uVm9sdW1lKCl7cmV0dXJuIHRoaXMuX3JlbGF0aW9uVm9sdW1lPT1udWxsJiYodGhpcy5fcmVsYXRpb25Wb2x1bWU9dGhpcy5jb21wdXRlUmVsYXRpb25UZXJyYWluVm9sdW1lKCkpLHRoaXMuX3JlbGF0aW9uVm9sdW1lfWNvbXB1dGVSZWxhdGlvblRlcnJhaW5Wb2x1bWUodD1bMCwxLzBdKXtjb25zdHtnZW9tZXRyeTpufT10aGlzLHI9dGhpcy5yZWxhdGlvbkluZGV4c1dpdGhvdXRUaHJvdWduLmZsYXRNYXAocz0+Wy4uLm4uaW5kaWNlcy5nZXRWZWN0b3IocyldKTtsZXQgaT1pcihyLHRoaXMuZ2V0UG9zaXRpb24sdCk7aWYodGhpcy5pbmNsdWRpbmdUaHJvdWdoKXtjb25zdFtzLG9dPXQsYz1vLXM7bGV0IGw9MDtjb25zdCBoPTEvMyx7Z2VvbWV0cnk6Zixwb3NpdGlvbk5hbWVzOnV9PXRoaXM7dGhpcy50aHJvdWdoRmFjZUFyZWFzLmZvckVhY2goKGQsZyk9Pntjb25zdCBtPXRoaXMudGhyb3VnaEluZGV4c1tnXSxbXyxwLE1dPWYuZ2V0RmFjZUFnZ3JlZ2F0ZVZlY3Rvcih1LG0pLEE9KF9bMl0rcFsyXStNWzJdKSpoLXM7QTw9MHx8KGwrPWQqTWF0aC5taW4oQSxjKSl9KSxsLz0yLGkrPWx9cmV0dXJuIGl9Z2V0IHZvbHVtZSgpe3JldHVybiB0aGlzLl92b2x1bWU9PW51bGwmJih0aGlzLl92b2x1bWU9dGhpcy5jb21wdXRlVGVycmFpblZvbHVtZShbLTEvMCwxLzBdKSksdGhpcy5fdm9sdW1lfWNvbXB1dGVUZXJyYWluVm9sdW1lKHQpe3JldHVybiBpcih0aGlzLmdlb21ldHJ5LmluZGljZXMuYXJyYXksdGhpcy5nZXRQb3NpdGlvbix0KX19Y2xhc3MgbW4gZXh0ZW5kcyBWb3tjb25zdHJ1Y3Rvcigpe3N1cGVyKC4uLmFyZ3VtZW50cyk7cSh0aGlzLCJfaXNDb252ZXgiLG51bGwpO3EodGhpcywiX3BvbHlnb25PdXRzaWRlR2VvbWV0cnkiLG51bGwpfWdldCBpc0NvbnZleCgpe3JldHVybiB0aGlzLl9pc0NvbnZleD09bnVsbCYmKHRoaXMuX2lzQ29udmV4PUFzKHRoaXMucmVnaW9uKSksdGhpcy5faXNDb252ZXh9c2V0IGlzQ29udmV4KG4pe3RoaXMuX2lzQ29udmV4PW59c2V0T3B0aW9ucyhuKXtpZihuLnJlZ2lvbil7Y29uc3Qgcj1uLnJlZ2lvbi5tYXAoaT0+bmV3IGRuKGkpKTt0aGlzLnBvbHlnb249bmV3IHZlKHIpLHRoaXMuaXNaZXJvUG9seWdvbj10aGlzLnBvbHlnb24uYXJlYSgpPT09MH1zdXBlci5zZXRPcHRpb25zKG4pfXJlc2V0TWVhc3VyZSgpe3N1cGVyLnJlc2V0TWVhc3VyZSgpLHRoaXMuX3BvbHlnb25PdXRzaWRlR2VvbWV0cnk9bnVsbH1nZW5lcmF0ZVBvc2l0aW9uUmVsYXRpb25zKCl7cmV0dXJuIHRoaXMuaXNDb252ZXg/YnModGhpcy5nZW9tZXRyeSx0aGlzLnJlZ2lvbix0aGlzLnBvc2l0aW9uTmFtZXMpOnZzKHRoaXMuZ2VvbWV0cnksdGhpcy5yZWdpb24sdGhpcy5wb3NpdGlvbk5hbWVzKX1nZW5lcmF0ZUZhY2VSZWxhdGlvbnMoKXtyZXR1cm4gSXModGhpcy5nZW9tZXRyeSx0aGlzLnJlZ2lvbix0aGlzLnBvc2l0aW9uTmFtZXMsdGhpcy5wb3NpdGlvblJlbGF0aW9ucyx0aGlzLmlzQ29udmV4KX1nZW5lcmF0ZVRocm91Z2hGYWNlcygpe2NvbnN0e2dlb21ldHJ5Om4scG9seWdvbjpyfT10aGlzLGk9dGhpcy5yZWxhdGlvbiZ5LkNvbnRhaW47bGV0IHM9aT93ZS5pbnRlcnNlY3Q6d2Uuc3VidHJhY3Q7cmV0dXJuIHRoaXMuaXNaZXJvUG9seWdvbiYmKHM9aT8obyxjKT0+cjoobyxjKT0+byksdGhpcy50aHJvdWdoSW5kZXhzLm1hcChvPT57Y29uc3QgbD1uLmdldEZhY2VBZ2dyZWdhdGVWZWN0b3IodGhpcy5wb3NpdGlvbk5hbWVzLG8pLm1hcChmPT5uZXcgZG4oZlswXSxmWzFdKSksaD1uZXcgdmUobCk7cmV0dXJuIHMoaCxyKX0pfWZpbHRlckZhY2VzKG4scil7cmV0dXJuIFBzKHRoaXMuZmFjZVJlbGF0aW9ucyxuLHIpfWdldCBwb2x5Z29uT3V0c2lkZUdlb21ldHJ5KCl7cmV0dXJuIHRoaXMuX3BvbHlnb25PdXRzaWRlR2VvbWV0cnk9PW51bGwmJih0aGlzLl9wb2x5Z29uT3V0c2lkZUdlb21ldHJ5PXRoaXMuaXNaZXJvUG9seWdvbj90aGlzLnBvbHlnb246d2Uuc3VidHJhY3QodGhpcy5wb2x5Z29uLHRoaXMuZ2VvbWV0cnlQb2x5Z29uKSksdGhpcy5fcG9seWdvbk91dHNpZGVHZW9tZXRyeX19Y29uc3QgVnU9NjM3ODEzNyxOdT02Mzc4MTM3LCR1PTYzNTY3NTIzMTQyNDUxNzllLTk7ZnVuY3Rpb24gcG4oZSl7cmV0dXJuIGV9bmV3IFI7ZnVuY3Rpb24genUoZSx0PVtdLG49cG4pe3JldHVybiJsb25naXR1ZGUiaW4gZT8odFswXT1uKGUubG9uZ2l0dWRlKSx0WzFdPW4oZS5sYXRpdHVkZSksdFsyXT1lLmhlaWdodCk6IngiaW4gZT8odFswXT1uKGUueCksdFsxXT1uKGUueSksdFsyXT1lLnopOih0WzBdPW4oZVswXSksdFsxXT1uKGVbMV0pLHRbMl09ZVsyXSksdH1mdW5jdGlvbiBrdShlLHQ9W10pe3JldHVybiB6dShlLHQsWi5fY2FydG9ncmFwaGljUmFkaWFucz9wbjpvZSl9ZnVuY3Rpb24gRnUoZSx0LG49cG4pe3JldHVybiJsb25naXR1ZGUiaW4gdD8odC5sb25naXR1ZGU9bihlWzBdKSx0LmxhdGl0dWRlPW4oZVsxXSksdC5oZWlnaHQ9ZVsyXSk6IngiaW4gdD8odC54PW4oZVswXSksdC55PW4oZVsxXSksdC56PWVbMl0pOih0WzBdPW4oZVswXSksdFsxXT1uKGVbMV0pLHRbMl09ZVsyXSksdH1mdW5jdGlvbiBxdShlLHQpe3JldHVybiBGdShlLHQsWi5fY2FydG9ncmFwaGljUmFkaWFucz9wbjpIbyl9Y29uc3QgTm89MWUtMTQsVXU9bmV3IFIsJG89e3VwOntzb3V0aDoiZWFzdCIsbm9ydGg6Indlc3QiLHdlc3Q6InNvdXRoIixlYXN0OiJub3J0aCJ9LGRvd246e3NvdXRoOiJ3ZXN0Iixub3J0aDoiZWFzdCIsd2VzdDoibm9ydGgiLGVhc3Q6InNvdXRoIn0sc291dGg6e3VwOiJ3ZXN0Iixkb3duOiJlYXN0Iix3ZXN0OiJkb3duIixlYXN0OiJ1cCJ9LG5vcnRoOnt1cDoiZWFzdCIsZG93bjoid2VzdCIsd2VzdDoidXAiLGVhc3Q6ImRvd24ifSx3ZXN0Ont1cDoibm9ydGgiLGRvd246InNvdXRoIixub3J0aDoiZG93biIsc291dGg6InVwIn0sZWFzdDp7dXA6InNvdXRoIixkb3duOiJub3J0aCIsbm9ydGg6InVwIixzb3V0aDoiZG93biJ9fSx2cj17bm9ydGg6Wy0xLDAsMF0sZWFzdDpbMCwxLDBdLHVwOlswLDAsMV0sc291dGg6WzEsMCwwXSx3ZXN0OlswLC0xLDBdLGRvd246WzAsMCwtMV19LFNlPXtlYXN0Om5ldyBSLG5vcnRoOm5ldyBSLHVwOm5ldyBSLHdlc3Q6bmV3IFIsc291dGg6bmV3IFIsZG93bjpuZXcgUn0sRHU9bmV3IFIsQnU9bmV3IFIsWXU9bmV3IFI7ZnVuY3Rpb24gem8oZSx0LG4scixpLHMpe2NvbnN0IG89JG9bdF0mJiRvW3RdW25dO3d0KG8mJighcnx8cj09PW8pKTtsZXQgYyxsLGg7Y29uc3QgZj1VdS5jb3B5KGkpO2lmKGsoZi54LDAsTm8pJiZrKGYueSwwLE5vKSl7Y29uc3QgZD1NYXRoLnNpZ24oZi56KTtjPUR1LmZyb21BcnJheSh2clt0XSksdCE9PSJlYXN0IiYmdCE9PSJ3ZXN0IiYmYy5zY2FsZShkKSxsPUJ1LmZyb21BcnJheSh2cltuXSksbiE9PSJlYXN0IiYmbiE9PSJ3ZXN0IiYmbC5zY2FsZShkKSxoPVl1LmZyb21BcnJheSh2cltyXSksciE9PSJlYXN0IiYmciE9PSJ3ZXN0IiYmaC5zY2FsZShkKX1lbHNle2NvbnN0e3VwOmQsZWFzdDpnLG5vcnRoOm19PVNlO2cuc2V0KC1mLnksZi54LDApLm5vcm1hbGl6ZSgpLGUuZ2VvZGV0aWNTdXJmYWNlTm9ybWFsKGYsZCksbS5jb3B5KGQpLmNyb3NzKGcpO2NvbnN0e2Rvd246Xyx3ZXN0OnAsc291dGg6TX09U2U7Xy5jb3B5KGQpLnNjYWxlKC0xKSxwLmNvcHkoZykuc2NhbGUoLTEpLE0uY29weShtKS5zY2FsZSgtMSksYz1TZVt0XSxsPVNlW25dLGg9U2Vbcl19cmV0dXJuIHNbMF09Yy54LHNbMV09Yy55LHNbMl09Yy56LHNbM109MCxzWzRdPWwueCxzWzVdPWwueSxzWzZdPWwueixzWzddPTAsc1s4XT1oLngsc1s5XT1oLnksc1sxMF09aC56LHNbMTFdPTAsc1sxMl09Zi54LHNbMTNdPWYueSxzWzE0XT1mLnosc1sxNV09MSxzfWNvbnN0IHJlPW5ldyBSLFd1PW5ldyBSLFp1PW5ldyBSO2Z1bmN0aW9uIEd1KGUsdCxuPVtdKXtjb25zdHtvbmVPdmVyUmFkaWk6cixvbmVPdmVyUmFkaWlTcXVhcmVkOmksY2VudGVyVG9sZXJhbmNlU3F1YXJlZDpzfT10O3JlLmZyb20oZSk7Y29uc3Qgbz1yZS54LGM9cmUueSxsPXJlLnosaD1yLngsZj1yLnksdT1yLnosZD1vKm8qaCpoLGc9YypjKmYqZixtPWwqbCp1KnUsXz1kK2crbSxwPU1hdGguc3FydCgxL18pO2lmKCFOdW1iZXIuaXNGaW5pdGUocCkpcmV0dXJuO2NvbnN0IE09V3U7aWYoTS5jb3B5KGUpLnNjYWxlKHApLF88cylyZXR1cm4gTS50byhuKTtjb25zdCBBPWkueCx4PWkueSxUPWkueixPPVp1O08uc2V0KE0ueCpBKjIsTS55KngqMixNLnoqVCoyKTtsZXQgdz0oMS1wKSpyZS5sZW4oKS8oLjUqTy5sZW4oKSksUz0wLGIsSSxFLFY7ZG97dy09UyxiPTEvKDErdypBKSxJPTEvKDErdyp4KSxFPTEvKDErdypUKTtjb25zdCBOPWIqYiwkPUkqSSxMPUUqRSxKPU4qYixOdD0kKkksJHQ9TCpFO1Y9ZCpOK2cqJCttKkwtMTtjb25zdCBNbj0tMiooZCpKKkErZypOdCp4K20qJHQqVCk7Uz1WL01ufXdoaWxlKE1hdGguYWJzKFYpPmloKTtyZXR1cm4gcmUuc2NhbGUoW2IsSSxFXSkudG8obil9Y29uc3QgX249bmV3IFIsa289bmV3IFIsWHU9bmV3IFIsaXQ9bmV3IFIsanU9bmV3IFIseW49bmV3IFI7Y2xhc3MgeG57Y29uc3RydWN0b3IodD0wLG49MCxyPTApe3RoaXMuY2VudGVyVG9sZXJhbmNlU3F1YXJlZD1yaCx3dCh0Pj0wKSx3dChuPj0wKSx3dChyPj0wKSx0aGlzLnJhZGlpPW5ldyBSKHQsbixyKSx0aGlzLnJhZGlpU3F1YXJlZD1uZXcgUih0KnQsbipuLHIqciksdGhpcy5yYWRpaVRvVGhlRm91cnRoPW5ldyBSKHQqdCp0KnQsbipuKm4qbixyKnIqcipyKSx0aGlzLm9uZU92ZXJSYWRpaT1uZXcgUih0PT09MD8wOjEvdCxuPT09MD8wOjEvbixyPT09MD8wOjEvciksdGhpcy5vbmVPdmVyUmFkaWlTcXVhcmVkPW5ldyBSKHQ9PT0wPzA6MS8odCp0KSxuPT09MD8wOjEvKG4qbikscj09PTA/MDoxLyhyKnIpKSx0aGlzLm1pbmltdW1SYWRpdXM9TWF0aC5taW4odCxuLHIpLHRoaXMubWF4aW11bVJhZGl1cz1NYXRoLm1heCh0LG4sciksdGhpcy5yYWRpaVNxdWFyZWQueiE9PTAmJih0aGlzLnNxdWFyZWRYT3ZlclNxdWFyZWRaPXRoaXMucmFkaWlTcXVhcmVkLngvdGhpcy5yYWRpaVNxdWFyZWQueiksT2JqZWN0LmZyZWV6ZSh0aGlzKX1lcXVhbHModCl7cmV0dXJuIHRoaXM9PT10fHwhISh0JiZ0aGlzLnJhZGlpLmVxdWFscyh0LnJhZGlpKSl9dG9TdHJpbmcoKXtyZXR1cm4gdGhpcy5yYWRpaS50b1N0cmluZygpfWNhcnRvZ3JhcGhpY1RvQ2FydGVzaWFuKHQsbj1bMCwwLDBdKXtjb25zdCByPWtvLGk9WHUsWywsc109dDt0aGlzLmdlb2RldGljU3VyZmFjZU5vcm1hbENhcnRvZ3JhcGhpYyh0LHIpLGkuY29weSh0aGlzLnJhZGlpU3F1YXJlZCkuc2NhbGUocik7Y29uc3Qgbz1NYXRoLnNxcnQoci5kb3QoaSkpO3JldHVybiBpLnNjYWxlKDEvbyksci5zY2FsZShzKSxpLmFkZChyKSxpLnRvKG4pfWNhcnRlc2lhblRvQ2FydG9ncmFwaGljKHQsbj1bMCwwLDBdKXt5bi5mcm9tKHQpO2NvbnN0IHI9dGhpcy5zY2FsZVRvR2VvZGV0aWNTdXJmYWNlKHluLGl0KTtpZighcilyZXR1cm47Y29uc3QgaT10aGlzLmdlb2RldGljU3VyZmFjZU5vcm1hbChyLGtvKSxzPWp1O3MuY29weSh5bikuc3VidHJhY3Qocik7Y29uc3Qgbz1NYXRoLmF0YW4yKGkueSxpLngpLGM9TWF0aC5hc2luKGkueiksbD1NYXRoLnNpZ24oVXQocyx5bikpKnplKHMpO3JldHVybiBxdShbbyxjLGxdLG4pfWVhc3ROb3J0aFVwVG9GaXhlZEZyYW1lKHQsbj1uZXcgdHQpe3JldHVybiB6byh0aGlzLCJlYXN0Iiwibm9ydGgiLCJ1cCIsdCxuKX1sb2NhbEZyYW1lVG9GaXhlZEZyYW1lKHQsbixyLGkscz1uZXcgdHQpe3JldHVybiB6byh0aGlzLHQsbixyLGkscyl9Z2VvY2VudHJpY1N1cmZhY2VOb3JtYWwodCxuPVswLDAsMF0pe3JldHVybiBfbi5mcm9tKHQpLm5vcm1hbGl6ZSgpLnRvKG4pfWdlb2RldGljU3VyZmFjZU5vcm1hbENhcnRvZ3JhcGhpYyh0LG49WzAsMCwwXSl7Y29uc3Qgcj1rdSh0KSxpPXJbMF0scz1yWzFdLG89TWF0aC5jb3Mocyk7cmV0dXJuIF9uLnNldChvKk1hdGguY29zKGkpLG8qTWF0aC5zaW4oaSksTWF0aC5zaW4ocykpLm5vcm1hbGl6ZSgpLF9uLnRvKG4pfWdlb2RldGljU3VyZmFjZU5vcm1hbCh0LG49WzAsMCwwXSl7cmV0dXJuIF9uLmZyb20odCkuc2NhbGUodGhpcy5vbmVPdmVyUmFkaWlTcXVhcmVkKS5ub3JtYWxpemUoKS50byhuKX1zY2FsZVRvR2VvZGV0aWNTdXJmYWNlKHQsbil7cmV0dXJuIEd1KHQsdGhpcyxuKX1zY2FsZVRvR2VvY2VudHJpY1N1cmZhY2UodCxuPVswLDAsMF0pe2l0LmZyb20odCk7Y29uc3Qgcj1pdC54LGk9aXQueSxzPWl0Lnosbz10aGlzLm9uZU92ZXJSYWRpaVNxdWFyZWQsYz0xL01hdGguc3FydChyKnIqby54K2kqaSpvLnkrcypzKm8ueik7cmV0dXJuIGl0Lm11bHRpcGx5U2NhbGFyKGMpLnRvKG4pfXRyYW5zZm9ybVBvc2l0aW9uVG9TY2FsZWRTcGFjZSh0LG49WzAsMCwwXSl7cmV0dXJuIGl0LmZyb20odCkuc2NhbGUodGhpcy5vbmVPdmVyUmFkaWkpLnRvKG4pfXRyYW5zZm9ybVBvc2l0aW9uRnJvbVNjYWxlZFNwYWNlKHQsbj1bMCwwLDBdKXtyZXR1cm4gaXQuZnJvbSh0KS5zY2FsZSh0aGlzLnJhZGlpKS50byhuKX1nZXRTdXJmYWNlTm9ybWFsSW50ZXJzZWN0aW9uV2l0aFpBeGlzKHQsbj0wLHI9WzAsMCwwXSl7d3Qoayh0aGlzLnJhZGlpLngsdGhpcy5yYWRpaS55LHNoKSksd3QodGhpcy5yYWRpaS56PjApLGl0LmZyb20odCk7Y29uc3QgaT1pdC56KigxLXRoaXMuc3F1YXJlZFhPdmVyU3F1YXJlZFopO2lmKCEoTWF0aC5hYnMoaSk+PXRoaXMucmFkaWkuei1uKSlyZXR1cm4gaXQuc2V0KDAsMCxpKS50byhyKX19eG4uV0dTODQ9bmV3IHhuKFZ1LE51LCR1KTtmdW5jdGlvbiBicihlLHQ9eG4uV0dTODQsbj1uZXcgUSl7Y29uc3Qgcj10LmdldFN1cmZhY2VOb3JtYWxJbnRlcnNlY3Rpb25XaXRoWkF4aXMoZSwwLGh0WzBdKSxpPVNuKGUscikscz10Lm1pbmltdW1SYWRpdXMqaS90Lm1heGltdW1SYWRpdXMqKjIsbz1pKnMqKjI7cmV0dXJuIG5bMF09aSxuWzBdPW8sbn1mdW5jdGlvbiBRdShlLHQsbil7cmV0dXJuIG49YnIoZSx0LG4pLEFuKFsxLDFdLG4sbiksbn1mdW5jdGlvbiBLdShlLHQsbil7bj1icihlLHQsbik7Y29uc3Qgcj1NYXRoLlBJLzE4MDtyZXR1cm4gRHIobixuLHIpfWZ1bmN0aW9uIEp1KGUpe2xldCB0PWUuZWFzdDtjb25zdCBuPWUud2VzdDtyZXR1cm4gdDxuJiYodCs9VyksdC1ufWZ1bmN0aW9uIEh1KGUpe3JldHVybiBlLm5vcnRoLWUuc291dGh9ZnVuY3Rpb24gdDAoZSx0LG4scixpPXt9KXtyZXR1cm4gaS53ZXN0PW9lKGU/PzApLGkuc291dGg9b2UodD8/MCksaS5lYXN0PW9lKG4/PzApLGkubm9ydGg9b2Uocj8/MCksaX1mdW5jdGlvbiBlMChlLHQ9e30pe2xldCBuPU51bWJlci5NQVhfVkFMVUUscj0tTnVtYmVyLk1BWF9WQUxVRSxpPU51bWJlci5NQVhfVkFMVUUscz0tTnVtYmVyLk1BWF9WQUxVRSxvPU51bWJlci5NQVhfVkFMVUUsYz0tTnVtYmVyLk1BWF9WQUxVRTtmb3IobGV0IGw9MCxoPWUubGVuZ3RoO2w8aDtsKyspe2NvbnN0W2YsdV09ZVtsXTtuPU1hdGgubWluKG4sZikscj1NYXRoLm1heChyLGYpLG89TWF0aC5taW4obyx1KSxjPU1hdGgubWF4KGMsdSk7Y29uc3QgZD1mPj0wP2Y6ZitXO2k9TWF0aC5taW4oaSxkKSxzPU1hdGgubWF4KHMsZCl9cmV0dXJuIHItbj5zLWkmJihuPWkscj1zLHI+TWF0aC5QSSYmKHI9ci1XKSxuPk1hdGguUEkmJihuPW4tVykpLHQud2VzdD1uLHQuc291dGg9byx0LmVhc3Q9cix0Lm5vcnRoPWMsdH1mdW5jdGlvbiBuMChlLHQsbj17fSl7dD10Pz94bi5XR1M4NDtsZXQgcj1OdW1iZXIuTUFYX1ZBTFVFLGk9LU51bWJlci5NQVhfVkFMVUUscz1OdW1iZXIuTUFYX1ZBTFVFLG89LU51bWJlci5NQVhfVkFMVUUsYz1OdW1iZXIuTUFYX1ZBTFVFLGw9LU51bWJlci5NQVhfVkFMVUU7Zm9yKGxldCBoPTAsZj1lLmxlbmd0aDtoPGY7aCsrKXtjb25zdFt1LGRdPXQuY2FydGVzaWFuVG9DYXJ0b2dyYXBoaWMoZVtoXSk7cj1NYXRoLm1pbihyLHUpLGk9TWF0aC5tYXgoaSx1KSxjPU1hdGgubWluKGMsZCksbD1NYXRoLm1heChsLGQpO2NvbnN0IGc9dT49MD91OnUrVztzPU1hdGgubWluKHMsZyksbz1NYXRoLm1heChvLGcpfXJldHVybiBpLXI+by1zJiYocj1zLGk9byxpPk1hdGguUEkmJihpPWktVykscj5NYXRoLlBJJiYocj1yLVcpKSxuLndlc3Q9cixuLnNvdXRoPWMsbi5lYXN0PWksbi5ub3J0aD1sLG59ZnVuY3Rpb24gcjAoZSx0LG49MCl7cmV0dXJuIGU9PT10fHxlJiZ0JiZNYXRoLmFicyhlLndlc3QtdC53ZXN0KTw9biYmTWF0aC5hYnMoZS5zb3V0aC10LnNvdXRoKTw9biYmTWF0aC5hYnMoZS5lYXN0LXQuZWFzdCk8PW4mJk1hdGguYWJzKGUubm9ydGgtdC5ub3J0aCk8PW59ZnVuY3Rpb24gaTAoZSx0KXtyZXR1cm4gZT09PXR8fGUmJnQmJmUud2VzdD09PXQud2VzdCYmZS5zb3V0aD09PXQuc291dGgmJmUuZWFzdD09PXQuZWFzdCYmZS5ub3J0aD09PXQubm9ydGh9ZnVuY3Rpb24gczAoZSx0PW5ldyBRKXtyZXR1cm4gdFswXT1lLndlc3QsdFsxXT1lLnNvdXRoLHR9ZnVuY3Rpb24gbzAoZSx0PW5ldyBRKXtyZXR1cm4gdFswXT1lLndlc3QsdFsxXT1lLm5vcnRoLHR9ZnVuY3Rpb24gYzAoZSx0PW5ldyBRKXtyZXR1cm4gdFswXT1lLmVhc3QsdFsxXT1lLm5vcnRoLHR9ZnVuY3Rpb24gYTAoZSx0PW5ldyBRKXtyZXR1cm4gdFswXT1lLmVhc3QsdFsxXT1lLnNvdXRoLHR9ZnVuY3Rpb24gRm8oZSl7Y29uc3R7d2VzdDp0LGVhc3Q6bixzb3V0aDpyLG5vcnRoOml9PWU7cmV0dXJuW25ldyBRKHQsciksbmV3IFEodCxpKSxuZXcgUShuLGkpLG5ldyBRKG4scildfWZ1bmN0aW9uIGwwKGUsdD1uZXcgUSl7bGV0IG49ZS5lYXN0O2NvbnN0IHI9ZS53ZXN0O248ciYmKG4rPVcpO2NvbnN0IGk9WXQoKHIrbikqLjUpLHM9KGUuc291dGgrZS5ub3J0aCkqLjU7cmV0dXJuIHRbMF09aSx0WzFdPXMsdH1mdW5jdGlvbiBoMChlLHQsbj17fSl7bGV0IHI9ZS5lYXN0LGk9ZS53ZXN0LHM9dC5lYXN0LG89dC53ZXN0O3I8aSYmcz4wP3IrPVc6czxvJiZyPjAmJihzKz1XKSxyPGkmJm88MD9vKz1XOnM8byYmaTwwJiYoaSs9Vyk7Y29uc3QgYz1ZdChNYXRoLm1heChpLG8pKSxsPVl0KE1hdGgubWluKHIscykpO2lmKChlLndlc3Q8ZS5lYXN0fHx0Lndlc3Q8dC5lYXN0KSYmbDw9YylyZXR1cm47Y29uc3QgaD1NYXRoLm1heChlLnNvdXRoLHQuc291dGgpLGY9TWF0aC5taW4oZS5ub3J0aCx0Lm5vcnRoKTtpZighKGg+PWYpKXJldHVybiBuLndlc3Q9YyxuLnNvdXRoPWgsbi5lYXN0PWwsbi5ub3J0aD1mLG59ZnVuY3Rpb24gZjAoZSx0LG4pe2NvbnN0IHI9TWF0aC5tYXgoZS53ZXN0LHQud2VzdCksaT1NYXRoLm1heChlLnNvdXRoLHQuc291dGgpLHM9TWF0aC5taW4oZS5lYXN0LHQuZWFzdCksbz1NYXRoLm1pbihlLm5vcnRoLHQubm9ydGgpO2lmKCEoaT49b3x8cj49cykpcmV0dXJuIG4/PyhuPXt9KSxuLndlc3Q9cixuLnNvdXRoPWksbi5lYXN0PXMsbi5ub3J0aD1vLG59ZnVuY3Rpb24gdTAoZSx0LG49e30pe2xldCByPWUuZWFzdCxpPWUud2VzdCxzPXQuZWFzdCxvPXQud2VzdDtyPGkmJnM+MD9yKz1XOnM8byYmcj4wJiYocys9VykscjxpJiZvPDA/bys9VzpzPG8mJmk8MCYmKGkrPVcpO2NvbnN0IGM9WXQoTWF0aC5taW4oaSxvKSksbD1ZdChNYXRoLm1heChyLHMpKTtyZXR1cm4gbi53ZXN0PWMsbi5zb3V0aD1NYXRoLm1pbihlLnNvdXRoLHQuc291dGgpLG4uZWFzdD1sLG4ubm9ydGg9TWF0aC5tYXgoZS5ub3J0aCx0Lm5vcnRoKSxufWZ1bmN0aW9uIGQwKGUsdCxuPXt9KXtyZXR1cm4gbi53ZXN0PU1hdGgubWluKGUud2VzdCx0WzBdKSxuLnNvdXRoPU1hdGgubWluKGUuc291dGgsdFsxXSksbi5lYXN0PU1hdGgubWF4KGUuZWFzdCx0WzBdKSxuLm5vcnRoPU1hdGgubWF4KGUubm9ydGgsdFsxXSksbn1mdW5jdGlvbiBnMChlLHQpe2xldCBuPXRbMF07Y29uc3Qgcj10WzFdLGk9ZS53ZXN0O2xldCBzPWUuZWFzdDtyZXR1cm4gczxpJiYocys9VyxuPDAmJihuKz1XKSksKG4+aXx8R24obixpLFFlKSkmJihuPHN8fEduKG4scyxRZSkpJiZyPj1lLnNvdXRoJiZyPD1lLm5vcnRofWNvbnN0IG0wPU9iamVjdC5mcmVlemUoe3dlc3Q6LU1hdGguUEksZWFzdDpNYXRoLlBJLHNvdXRoOi1KaSxub3J0aDpKaX0pO2Z1bmN0aW9uIHAwKGUpe2NvbnN0e21hdHJpeDp0LHBvc2l0aW9uTmFtZXM6bj1JZSxzY2FsZTpyfT1lLGk9bmV3IHJuKGUpO3QmJmkudHJhbnNmb3JtRm9yQWdncmVnYXRlKHQsbik7Y29uc3Qgbz1uZXcgbW4oey4uLmUsZ2VvbWV0cnk6aX0pLnJlbGF0aW9uQXJlYTtpZighcilyZXR1cm4gbztjb25zdCBjPU1hdGguaHlwb3QoclswXSxyWzJdKSpyWzFdO3JldHVybiBvKk1hdGguYWJzKGMpfWZ1bmN0aW9uIHFvKGUpe2NvbnN0e21hdHJpeDp0LHBvc2l0aW9uTmFtZXM6bj1JZSxzY2FsZTpyLGhlaWdodFJhbmdlOml9PWUscz1uZXcgcm4oZSk7dCYmcy50cmFuc2Zvcm1Gb3JBZ2dyZWdhdGUodCxuKTtjb25zdCBvPW5ldyBtbih7Li4uZSxnZW9tZXRyeTpzfSk7bGV0IGM9MTtpZihyKWZvcihsZXQgbCBvZiByKWMqPWw7cmV0dXJuIG8uY29tcHV0ZVJlbGF0aW9uVGVycmFpblZvbHVtZShpKSpjfWZ1bmN0aW9uIF8wKGUpe2NvbnN0e3JlY3RhbmdsZTp0LGhlaWdodFJhbmdlOm4scG9zaXRpb25OYW1lczpyPUllLHNjYWxlOml9PWUscz1uZXcgcm4oZSksbz1Ibih0LG4pO3MudHJhbnNmb3JtRm9yQWdncmVnYXRlKG8scik7Y29uc3QgYz1uZXcgbW4oey4uLmUsZ2VvbWV0cnk6c30pLGw9Rm8odCksaD1uZXcgdmUobCksZj13ZS5zdWJ0cmFjdChoLGMuZ2VvbWV0cnlQb2x5Z29uKSx1PWMucmVsYXRpb25BcmVhK2YuYXJlYSgpO2lmKCFpKXJldHVybiB1O2NvbnN0IGQ9TWF0aC5oeXBvdChpWzBdLGlbMl0pKmlbMV07cmV0dXJuIHUqTWF0aC5hYnMoZCl9ZnVuY3Rpb24geTAoZSl7Y29uc3R7cmVjdGFuZ2xlOnQsaGVpZ2h0UmFuZ2U6biwuLi5yfT1lLGk9SG4odCxuKTtyZXR1cm4gcW8oey4uLnIsbWF0cml4OmksaGVpZ2h0UmFuZ2U6bn0pfWZ1bmN0aW9uIElyKGUsdCl7cmV0dXJuIGUueSp0LngrZS54fWZ1bmN0aW9uIHgwKGUsdCl7Y29uc3R7eDpufT10LHI9TWF0aC50cnVuYyhlL24pO3JldHVybnt4OmUtcipuLHk6cn19ZnVuY3Rpb24gTTAoZSx0LG49MSl7bGV0e3g6cix5Oml9PXQ7Y29uc3Qgcz1lLnNpemU7cmV0dXJuIHI9TWF0aC5tYXgoMCxNYXRoLm1pbihzLngtMSxyKSksaT1NYXRoLm1heCgwLE1hdGgubWluKHMueS0xLGkpKSxVbyhlLHt4OnIseTppfSxuKX1mdW5jdGlvbiBVbyhlLHQsbj0xKXtjb25zdHtkYXRhOnIsc2l6ZTppfT1lLHM9SXIodCxpKTtsZXQgbz1bXTtpZihuPjApe2NvbnN0IGM9cypuO2ZvcihsZXQgbD0wO2w8bjtsKyspby5wdXNoKHJbYytsXSl9cmV0dXJue2luZGV4OnMsdmFsdWU6b319ZnVuY3Rpb24gdzAoZSx0KXtsZXR7eDpuLHk6cn09dDtjb25zdCBpPWUuc2l6ZTtyZXR1cm4gbj1NYXRoLm1heCgwLE1hdGgubWluKGkueC0xLG4pKSxyPU1hdGgubWF4KDAsTWF0aC5taW4oaS55LTEscikpLERvKGUse3g6bix5OnJ9KX1mdW5jdGlvbiBEbyhlLHQpe2NvbnN0e2RhdGE6bixzaXplOnJ9PWUsaT1Jcih0LHIpO3JldHVybntpbmRleDppLHZhbHVlOm5baV19fWZ1bmN0aW9uIEEwKGUsdCxuPTEpe2NvbnN0e2RhdGE6cixzaXplOml9PWUscz1pLngsbz10KnMsYz1vK3M7cmV0dXJuKHR5cGVvZiByLnNsaWNlPT0iZnVuY3Rpb24iP3I6QXJyYXkuZnJvbShyKSkuc2xpY2UobypuLGMqbil9ZnVuY3Rpb24gVDAoZSx0KXtmb3IoY29uc3RbbixyXW9mIE9iamVjdC5lbnRyaWVzKGUpKWlmKDA8PXImJnI8PXRbbl0pcmV0dXJuITA7cmV0dXJuITF9ZnVuY3Rpb24gU3IoZSx0KXtjb25zdHt4Om4seTpyfT10O3JldHVybiBlLnoqcipuK2UueSpuK2UueH1mdW5jdGlvbiBFMChlLHQpe2NvbnN0e3g6bix5OnJ9PXQsaT1NYXRoLnRydW5jKGUvbikscz1lLWkqbixvPU1hdGgudHJ1bmMoaS9yKSxjPWktbypyO3JldHVybnt4OnMseTpjLHo6b319ZnVuY3Rpb24gTzAoZSx0LG49MSl7bGV0e3g6cix5OmksejpzfT10O2NvbnN0IG89ZS5zaXplO3JldHVybiByPU1hdGgubWF4KDAsTWF0aC5taW4oby54LTEscikpLGk9TWF0aC5tYXgoMCxNYXRoLm1pbihvLnktMSxpKSkscz1NYXRoLm1heCgwLE1hdGgubWluKG8uei0xLHMpKSxMcihlLHt4OnIseTppLHo6c30sbil9ZnVuY3Rpb24gTHIoZSx0LG49MSl7Y29uc3R7ZGF0YTpyLHNpemU6aX09ZSxzPVNyKHQsaSk7bGV0IG89W107aWYobj4wKXtjb25zdCBjPXMqbjtmb3IobGV0IGw9MDtsPG47bCsrKW8ucHVzaChyW2MrbF0pfXJldHVybntpbmRleDpzLHZhbHVlOm99fWZ1bmN0aW9uIHYwKGUsdCl7bGV0e3g6bix5OnIsejppfT10O2NvbnN0IHM9ZS5zaXplO3JldHVybiBuPU1hdGgubWF4KDAsTWF0aC5taW4ocy54LTEsbikpLHI9TWF0aC5tYXgoMCxNYXRoLm1pbihzLnktMSxyKSksaT1NYXRoLm1heCgwLE1hdGgubWluKHMuei0xLGkpKSxQcihlLHt4Om4seTpyLHo6aX0pfWZ1bmN0aW9uIFByKGUsdCl7Y29uc3R7ZGF0YTpuLHNpemU6cn09ZSxpPVNyKHQscik7cmV0dXJue2luZGV4OmksdmFsdWU6bltpXX19ZnVuY3Rpb24gYjAoZSx0KXtjb25zdHt2b2lkVmFsdWU6bix2YWx1ZXNBY2N1bXVsYXRlOnIsdmVyaWZ5Vm9pZDppPSgpPT4hMX09dDtsZXR7eDpzLHk6byx6OmN9PWVbMF0uc2l6ZTtjb25zdCBsPWUubGVuZ3RoO2ZvcihsZXQgZD0xO2Q8bDtkKyspe2NvbnN0IGc9ZVtkXS5zaXplO3M9TWF0aC5tYXgocyxnLngpLG89TWF0aC5tYXgobyxnLnkpLGM9TWF0aC5tYXgoYyxnLnopfWNvbnN0IGg9cypvKmMsZj1uZXcgQXJyYXkoaCksdT1zKm87Zm9yKGxldCBkPTA7ZDxjO2QrKyl7Y29uc3QgZz1kKnU7Zm9yKGxldCBtPTA7bTxvO20rKyl7Y29uc3QgXz1nK20qcztmb3IobGV0IHA9MDtwPHM7cCsrKXtjb25zdCBNPV8rcCxBPXt4OnAseTptLHo6ZH0seD1bXTtmb3IoY29uc3QgdyBvZiBlKXtjb25zdCBTPXcuc2l6ZTtpZihwPFMueCYmbTxTLnkmJmQ8Uy56KWNvbnRpbnVlO2NvbnN0e2luZGV4OmIsdmFsdWU6SX09UHIodyxBKTtpKEksdyxiKXx8eC5wdXNoKHt2YWx1ZTpJLGluZGV4OmIsZGF0YTNEOncsY29vcmQ6QX0pfWNvbnN0IFQ9eC5sZW5ndGg7bGV0IE89bjtUPjE/Tz1yKHgpOlQ9PT0xJiYoTz14WzBdLnZhbHVlKSxmW01dPU99fX1yZXR1cm57ZGF0YTpmLHNpemU6e3g6cyx5Om8sejpjfX19ZnVuY3Rpb24gSTAoZSx0LG4scj0xKXtjb25zdHtzaXplOml9PWUscz1fdC50b0tleSh0KSxbbyxjXT1fdC5nZXRDcm9zc0F4aXNzKHQpLGw9X3QudG9LZXkobyksaD1fdC50b0tleShjKSxmPWlbbF0sdT1pW2hdLGQ9W10sZz1pW3NdO249TWF0aC50cnVuYyhuKSxuPU1hdGgubWF4KDAsTWF0aC5taW4oZy0xLG4pKTtsZXQgbT17eDowLHk6MCx6OjB9O21bc109bjtmb3IobGV0IF89MDtfPHU7XysrKXttW2hdPV87Zm9yKGxldCBwPTA7cDxmO3ArKyl7bVtsXT1wO2NvbnN0e3ZhbHVlOk19PUxyKGUsbSxyKTtkLnB1c2goLi4uTSl9fXJldHVybntkYXRhOmQsc2l6ZTp7eDpmLHk6dX19fXZhciBTMD1PYmplY3QuZnJlZXplKHtfX3Byb3RvX186bnVsbCxBdHRyaWJ1dGVOYW1lOkNzLEF0dHJpYnV0ZXM6VnMsZ2V0IEF4aXMoKXtyZXR1cm4gX3R9LGdldCBBeGlzNCgpe3JldHVybiBDZX0sR2VvbWV0cmljUmVsYXRpb246eSxHZW9tZXRyeTpybixHZW9tZXRyeVJlbGF0aW9uTWVhc3VyZTpWbyxNYXRoQXJyYXk6Y2UsTWF0cml4OkNuLGdldCBOdW1lcmljQXJyYXlUeXBlKCl7cmV0dXJuIEtlfSxnZXQgT3JpZW50YXRpb24oKXtyZXR1cm4gc3R9LFBvbHlnb24yR2VvbWV0cnlSZWxhdGlvbk1lYXN1cmU6bW4sVmVjdG9yOlZlLFZlY3RvckFycmF5Om5uLGFkZFZlY3RvckFycmF5OkhoLGFkanVzdEZyZW5ldEZyYW1lOmZzLGFkanVzdEZyb250VXBGcmFtZTp1cyxhZGp1c3RPcmllbnRhdGlvbjpUaCxhZ2dyZWdhdGVGYWNlUG9zaXRpb25SZWxhdGlvbnNPZkdlb21ldHJ5X1BvbHlnb246WGgsY2xpcEdlb21ldHJ5QnlCb3JkZXI6S24sY2xpcEdlb21ldHJ5QnlCb3JkZXJzOlpoLGNvbXB1dGVBcmVhT2ZHZW9tZXRyeTpycixjb21wdXRlQXJlYU9mVHJpYW5nbGUyOmRmLGNvbXB1dGVBcmVhT2ZUcmlhbmdsZTIzOmZmLGNvbXB1dGVBcmVhT2ZUcmlhbmdsZTM6dWYsY29tcHV0ZUNvbnZleEh1bGwyOnFoLGNvbXB1dGVDb252ZXhIdWxsMkZvclNvcnRlZDp3cyxjb21wdXRlRG91YmxlQXJlYU9mVHJpYW5nbGUyOm5yLGNvbXB1dGVEb3VibGVBcmVhT2ZUcmlhbmdsZTIzOmVyLGNvbXB1dGVEb3VibGVBcmVhT2ZUcmlhbmdsZTM6cXMsY29tcHV0ZURvdWJsZVNpZ25BcmVhT2ZQb2x5Z29uMjpOcyxjb21wdXRlRG91YmxlU2lnbkFyZWFPZlBvbHlnb24zOiRzLGNvbXB1dGVEb3VibGVTaWduQXJlYU9mVHJpYW5nbGUyOnpzLGNvbXB1dGVEb3VibGVTaWduQXJlYU9mVHJpYW5nbGUyMzpGcyxjb21wdXRlRG91YmxlU2lnbkFyZWFPZlRyaWFuZ2xlMzprcyxjb21wdXRlR2xvYmVPcmllbnRhdGlvbkZyYW1lT25Mb25MYXQ6Z3MsY29tcHV0ZUdsb2JlT3JpZW50YXRpb25GcmFtZU9uUG9zaXRpb246WG4sY29tcHV0ZUludGVyc2VjdGlvbkZhY3Rvck9mTGluZV9DaXJjbGU6V3QsY29tcHV0ZUludGVyc2VjdGlvbk9mMjNMaW5lU2VnbWVudF9MaW5lU2VnbWVudDp6aCxjb21wdXRlSW50ZXJzZWN0aW9uT2YyM0xpbmVfTGluZTpkZSxjb21wdXRlSW50ZXJzZWN0aW9uT2YyM1JheV9MaW5lU2VnbWVudDpOaCxjb21wdXRlSW50ZXJzZWN0aW9uT2YyTGluZVNlZ21lbnRfTGluZVNlZ21lbnQ6a2gsY29tcHV0ZUludGVyc2VjdGlvbk9mMkxpbmVfTGluZTplbixjb21wdXRlSW50ZXJzZWN0aW9uT2YyUG9seWdvbl9DaXJjbGU6WWgsY29tcHV0ZUludGVyc2VjdGlvbk9mMlJheV9MaW5lU2VnbWVudDokaCxjb21wdXRlSW50ZXJzZWN0aW9uT2ZMaW5lU2VnbWVudF9DaXJjbGU6X3MsY29tcHV0ZUludGVyc2VjdGlvbk9mTGluZV9DaXJjbGU6U2gsY29tcHV0ZUludGVyc2VjdGlvbk9mUmF5X0NpcmNsZTpQaCxjb21wdXRlUmVsYXRpb25BcmVhT2ZQb2x5Z29uMkdlb21ldHJ5OnAwLGNvbXB1dGVSZWxhdGlvbkFyZWFPZlBvbHlnb24yVGVycmFpbjpfMCxjb21wdXRlUmVsYXRpb25UZXJyYWluVm9sdW1lT2ZQb2x5Z29uMkdlb21ldHJ5OnFvLGNvbXB1dGVSZWxhdGlvblRlcnJhaW5Wb2x1bWVPZlBvbHlnb24yVGVycmFpbjp5MCxjb21wdXRlU2lnbkFyZWFPZlBvbHlnb24yOm9mLGNvbXB1dGVTaWduQXJlYU9mUG9seWdvbjM6Y2YsY29tcHV0ZVNpZ25BcmVhT2ZUcmlhbmdsZTI6YWYsY29tcHV0ZVNpZ25BcmVhT2ZUcmlhbmdsZTIzOmhmLGNvbXB1dGVTaWduQXJlYU9mVHJpYW5nbGUzOmxmLGNvbXB1dGVWb2x1bWVPZlRlcnJhaW46aXIsY3JlYXRlR2xvYmVPcmllbnRhdGlvbkZyYW1lTWF0cml4M09uTG9uTGF0OnZoLGNyZWF0ZUdsb2JlT3JpZW50YXRpb25GcmFtZU1hdHJpeDNPblBvc2l0aW9uOk9oLGNyZWF0ZUdsb2JlT3JpZW50YXRpb25GcmFtZU1hdHJpeDRPblBvc2l0aW9uOkVoLGNyZWF0ZU9yaWVudGF0aW9uRnJhbWVNYXRyaXgzOkhlLGNyZWF0ZU9yaWVudGF0aW9uRnJhbWVNYXRyaXg0Om1zLGNyZWF0ZVF1YW50aXplZE1lc2hUZXJyYWluVmVydGV4R2V0dGVyOmpoLGNyZWF0ZVZlY3RvcjpIaSxkYXRhMkRDb29yZFRvSW5kZXg6SXIsZGF0YTJESW5kZXhUb0Nvb3JkOngwLGRhdGEzRENvb3JkVG9JbmRleDpTcixkYXRhM0RJbmRleFRvQ29vcmQ6RTAsZGl2aWRlVmVjdG9yQXJyYXk6bmYsZWxsaXBzb2lkX2dldExvY2FsQ3VydmF0dXJlOlF1LGVsbGlwc29pZF9nZXRMb2NhbEN1cnZhdHVyZVJhZGl1czpicixlbGxpcHNvaWRfZ2V0TG9jYWxTaXplUGVyRGVncmVlczpLdSxlcXVhbHNFcHNpbG9uOkduLGZpbHRlckZhY2VCeVBvbHlnb25SZWxhdGlvbjpQcyxmaWx0ZXJHcm91cHM6c2YsZmluZENvbmNhdmVQb2ludEluZGV4T2ZQb2x5Z29uMjpVaCxmaW5kVGFuZ2VudFBvaW50T2YyQ29udmV4UG9seWdvbjpEaCxmbGF0TnVtZXJpY0FycmF5QXJyYXk6UnMsZnJhbWVMb29wOmJoLGZyZW5ldEZyYW1lVG9Gcm9udFVwRnJhbWU6d2gsZnJvbnRVcEZyYW1lVG9GcmVuZXRGcmFtZTpBaCxnZW5lcmF0ZUZhY2VSZWxhdGlvbnNPZkdlb21ldHJ5X1BvbHlnb246SXMsZ2VuZXJhdGVQb3NpdGlvblJlbGF0aW9uc09mR2VvbWV0cnlfQ29udmV4UG9seWdvbjpicyxnZW5lcmF0ZVBvc2l0aW9uUmVsYXRpb25zT2ZHZW9tZXRyeV9Qb2x5Z29uOnZzLGdldEF4aXNSb3RhdGlvbkFuZ2xlOnloLGdldEF6aW11dGhBbmdsZTp4aCxnZXREYXRhMkRJdGVtOlVvLGdldERhdGEyREl0ZW1TYWZlOk0wLGdldERhdGEyRFJvdzpBMCxnZXREYXRhMkRWYWx1ZTpEbyxnZXREYXRhMkRWYWx1ZVNhZmU6dzAsZ2V0RGF0YTNESXRlbTpMcixnZXREYXRhM0RJdGVtU2FmZTpPMCxnZXREYXRhM0RTbGljZTpJMCxnZXREYXRhM0RWYWx1ZTpQcixnZXREYXRhM0RWYWx1ZVNhZmU6djAsZ2V0SW5jbHVkZWRBbmdsZTpocyxnZXRNYXRyaXhPZlF1YW50aXplZE1lc2hUZXJyYWluRGF0YTpIbixnZXRQb2x5Z29uUmVsYXRpb25CeUFnZ3JlZ2F0ZVBvc2l0aW9uUmVsYXRpb246THMsZ2V0Um90YXRpb25BbmdsZTp1ZSxnZXRTY2FsZU9mUXVhbnRpemVkTWVzaFRlcnJhaW5EYXRhOnRyLGdldFRyYW5zZm9ybU1hdEZ1bjpoZSxnZXRWZWNGdW5zOlksZ2V0VmVjdG9yQ2xhc3M6b2gsaVZlY3RvclRvTnVtYmVyQXJyYXk6ZXMsaXNDb252ZXhQb2x5Z29uMjpBcyxpc091dE9mU2l6ZTpUMCxpdmVjdG9yTWVtYmVyVG9WZWN0b3I6ZmUsaXZlY3RvclRvVmVjdG9yOm5zLGxuZ0xhdFJlY3RhbmdsZV9IZWlnaHQ6SHUsbG5nTGF0UmVjdGFuZ2xlX1dpZHRoOkp1LGxuZ0xhdFJlY3RhbmdsZV9jZW50ZXI6bDAsbG5nTGF0UmVjdGFuZ2xlX2NvbnRhaW5zOmcwLGxuZ0xhdFJlY3RhbmdsZV9jb3JuZXJzOkZvLGxuZ0xhdFJlY3RhbmdsZV9lcXVhbHM6aTAsbG5nTGF0UmVjdGFuZ2xlX2VxdWFsc0Vwc2lsb246cjAsbG5nTGF0UmVjdGFuZ2xlX2V4cGFuZDpkMCxsbmdMYXRSZWN0YW5nbGVfZnJvbUNhcnRlc2lhbkFycmF5Om4wLGxuZ0xhdFJlY3RhbmdsZV9mcm9tQ2FydG9ncmFwaGljQXJyYXk6ZTAsbG5nTGF0UmVjdGFuZ2xlX2Zyb21EZWdyZWVzOnQwLGxuZ0xhdFJlY3RhbmdsZV9pbnRlcnNlY3Rpb246aDAsbG5nTGF0UmVjdGFuZ2xlX25vcnRoZWFzdDpjMCxsbmdMYXRSZWN0YW5nbGVfbm9ydGh3ZXN0Om8wLGxuZ0xhdFJlY3RhbmdsZV9zaW1wbGVJbnRlcnNlY3Rpb246ZjAsbG5nTGF0UmVjdGFuZ2xlX3NvdXRoZWFzdDphMCxsbmdMYXRSZWN0YW5nbGVfc291dGh3ZXN0OnMwLGxuZ0xhdFJlY3RhbmdsZV91bmlvbjp1MCxtYXBHcm91cHM6cmYsbWF0M19ub3JtYWxNYXRyaXg6WW4sbWF0NF9mcm9tTWF0cml4MzphaCxtYXhMbmdMYXRSZWN0YW5nbDptMCxtZXJnZURhdGEzRHM6YjAsbXVsdGlwbHlWZWN0b3JBcnJheTplZixuZWdhdGl2ZVBpVG9QaTpZdCxub3JtYWxpemVWZWN0b3JzOkdoLG51bWVyaWNBcnJheVR5cGVDbGFzc01hcDp0cyxwb3NpdGlvbk5hbWVzX2RlZmF1bHQ6SWUscXVhdF9mcm9tRXVsZXI6cGgscXVhdF9yb3RhdGlvbkJldHdlZW5WZWN0b3JzQXJvdW5kQXhpczpfaCxyZWxhdGlvbk9mMjNMaW5lU2VnbWVudF9MaW5lU2VnbWVudDpqbixyZWxhdGlvbk9mMjNSYXlfTGluZVNlZ21lbnQ6VmgscmVsYXRpb25PZjJDb252ZXhQb2x5Z29uX0NvbnZleFBvbHlnb246T3MscmVsYXRpb25PZjJDb252ZXhQb2x5Z29uX0xpbmVTZWdtZW50OlFuLHJlbGF0aW9uT2YyQ29udmV4UG9seWdvbl9Qb2ludDpNdCxyZWxhdGlvbk9mMkxpbmVTZWdtZW50X1BvaW50OnlzLHJlbGF0aW9uT2YyUG9seWdvbl9DaXJjbGU6QmgscmVsYXRpb25PZjJQb2x5Z29uX0NvbnZleFBvbHlnb246RXMscmVsYXRpb25PZjJQb2x5Z29uX0xpbmVTZWdtZW50OlRzLHJlbGF0aW9uT2YyUG9seWdvbl9Qb2ludDpmdCxyZWxhdGlvbk9mMlBvbHlnb25fUG9seWdvbjpXaCxyZWxhdGlvbk9mMlJheV9MaW5lU2VnbWVudDp4cyxyZWxhdGlvbk9mTGluZVNlZ21lbnRfQ2lyY2xlOnBzLHJlbGF0aW9uT2ZMaW5lU2VnbWVudF9Qb2ludDpDaCxyZWxhdGlvbk9mTGluZV9DaXJjbGU6SWgscmVsYXRpb25PZkxpbmVfTGluZTp0bixyZWxhdGlvbk9mTnVtYmVyUmFuZ2VzOkZoLHJlbGF0aW9uT2ZSYXlfQ2lyY2xlOkxoLHNhZmVNb2Q6bHMsc2NhbGVBbmRBZGRWZWN0b3JBcnJheTpKaCxzY2FsZVZlY3RvckFycmF5OktoLHNvcnRQb2ludHMyQ0NXOk1zLHN1YnRyYWN0VmVjdG9yQXJyYXk6dGYsdHJhbnNmb3JtVmVjdG9yQXJyYXk6UWgsdmVjMjNfYXJlYTpzcyx2ZWMyM19jcm9zczpsaCx2ZWMyM19pc0NvbGxpbmVhcjpoaCx2ZWMyM19zaWduQXJlYTphcyx2ZWMyX2FyZWE6Y3MsdmVjMl9pc0NvbGxpbmVhcjppcyx2ZWMyX3NpZ25BcmVhOkJ0LHZlYzNfYXJlYTpvcyx2ZWMzX2lzQ29sbGluZWFyOmZoLHZlYzNfc2lnbkFyZWE6V24sdmVjX2NvbXB1dGVWZWN0b3JTY2FsYXI6Qix2ZWNfaXNDb2xsaW5lYXI6SmUsdmVjX3Byb2plY3RPblBsYW5lOmF0LHZlY19wcm9qZWN0T25WZWN0b3I6cnMsd2hpY2hTaWRlT2YybGluZTp4dCx3aGljaFNpZGVPZjNsaW5lOlJofSk7T2JqZWN0LmFzc2lnbihnbG9iYWxUaGlzLFMwKSxjb25zb2xlLmxvZygi5Yqo5oCBV29ya2Vy5bey5Yqg6L29OiBAd2ViLTNkL3Rvb2xzIil9KSgpOwo=",jn&&jn.tagName.toUpperCase()==="SCRIPT"&&jn.src||new URL("tools.iife.js",document.baseURI).href).href,{name:n==null?void 0:n.name})}function vu(n="@web-3d/tools"){const t=new Bu({name:n});return dc(t)}const wu=vu();function ci(n,t,l){const{east:s,north:e,south:d,west:i}=t,c=Ni[0];c.longitude=i,c.latitude=d;const o=n.positionToTileXY(c,l,Dn[0]);c.longitude=s,c.latitude=e;const a=n.positionToTileXY(c,l,Dn[1]),[u,X]=o.x<a.x?[o.x,a.x]:[a.x,o.x],[r,m]=o.y<a.y?[o.y,a.y]:[a.y,o.y];return{min:[u,r],max:[X,m]}}const Uu=32767;function ju(n,t=new h.Cartesian3){return h.Matrix3.getScale(n.halfAxes,t),h.Cartesian3.multiplyByScalar(t,2*Uu,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 Eu(n,t,l){l=wn(n,t,l);const s=Math.PI/180;return h.Cartesian2.multiplyByScalar(l,s,l)}function bi(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 Ou(n,t,l,s){const e=await n.requestTileGeometry(t,l,s);if(!e)return null;const d=bi(e),i=[data._minimumHeight,data._maximumHeight],c=n.tilingScheme.tileXYToRectangle(t,l,s),o=ni(c,i),a=h.Matrix4.fromArray(o,void 0),u=["u","v","height"],X=new li({...d,positionNames:u}),r=new h.Cartesian3;return X.mapForAggregate(u,(m,Z)=>(h.Cartesian3.fromArray(m,0,r),h.Matrix4.multiplyByPoint(a,r,r),new h.Cartographic(r.x,r.y,r.z)))}async function Au(n,t,l){const{min:s,max:e}=ci(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 u=oi(n,o,a,l);u&&(d.push(u),i.push({x:o,y:a}))}return(await Promise.all(d)).map(function(o,a){const{x:u,y:X}=i[a];return{x:u,y:X,level:l,data:o}})}async function oi(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 Du(n,t){const l=h.Rectangle.fromCartesianArray(t),s=h.Cartographic.toCartesian(h.Rectangle.center(l)),e=wn(n.ellipsoid,s),d=[e.x,e.y,1],i=_n(n,l),c=qn(i),o=h.Transforms.eastNorthUpToFixedFrame(s);h.Matrix4.inverseTransformation(o,o);const a=t.map(r=>{const m=h.Matrix4.multiplyByPoint(o,r,rn[2]);return[m.x,m.y]});let u=0;const X=c.map(async r=>{const{data:m,...Z}=r,{position:W,uv:G,height:p}=m.attributes;u+=await wu.computeRelationAreaOfPolygon2Terrain({args:[{...m,...Z,positionNames:["position"],region:a,matrix:h.Matrix4.pack(o,[]),relation:K.Contain|K.Intersect,scale:d}],transfer:[W.array.buffer,G.array.buffer,p.array.buffer,m.indices.buffer]})});if(await Promise.all(X),u===0||isNaN(u)){console.warn("贴地面积计算异常,已回退到椭球面投影面积",u);const r=t.map(m=>h.Cartesian3.pack(m,[]));return u=si(r),Math.abs(u)}return u}function _u(n,t){const l=h.Rectangle.fromCartesianArray(t),s=h.Cartographic.toCartesian(h.Rectangle.center(l)),e=wn(n.ellipsoid,s),d=[e.x,e.y,1],i=_n(n,l),c=qn(i),o=h.Transforms.eastNorthUpToFixedFrame(s);h.Matrix4.inverseTransformation(o,o);const a=t.map(X=>{const r=h.Matrix4.multiplyByPoint(o,X,rn[2]);return[r.x,r.y]});let u=0;for(const X of c){const{data:r,...m}=X;u+=Qu({...r,...m,positionNames:["position"],region:a,matrix:h.Matrix4.pack(o,[]),relation:K.Contain|K.Intersect,scale:d})}if(u===0||isNaN(u)){console.warn("贴地面积计算异常,已回退到椭球面投影面积",u);const X=t.map(r=>h.Cartesian3.pack(r,[]));return u=si(X),Math.abs(u)}return u}return S.CartesianAxis=es,S.HeadingPitchRollComponent=ds,S.applyMatrixReferFrame=Vi,S.applyTransformInPrimitive=as,S.applyTransformInfoPrimitive=Yi,S.componentDatatypeTypedArrayMap=ss,S.computeAttributeSizeInBytes=Ci,S.computeNormalOfCoplanars=os,S.computeTerrainAreaOfPolygon=_u,S.computeTerrainAreaOfPolygon_worker=Du,S.computeVertexNumOfAttribute=Ti,S.createPlaneOfCoplanars=Wi,S.flatTransformInfoOptions=En,S.getAttributeData=Fi,S.getBoundingSphere=Si,S.getDecodePositionsOfTerrainMesh=Ji,S.getEntityInfo=fi,S.getGeometryDataOfQuantizedMeshTerrainData=bi,S.getGeometryDataOfTerrainMesh=Rs,S.getLevelRangeOfQuadtreeTiles=Ks,S.getLocalCurvatureRadius=wn,S.getLocalSizePerDegrees=Eu,S.getLocalTransformInfo=cs,S.getMatrix4OfTransformInfo=Ki,S.getNeighborPairs=pi,S.getPosition=zi,S.getPositionOfTerrainMesh=Hi,S.getRenderedQuadtreeTilesOfIntersectRectangle=_n,S.getRenderedTileLevelRange=Ii,S.getScaleOfTerrainDataByOrientedBoundingBox=ju,S.getTerrainData=oi,S.getTerrainDataOfQuadtreeTile=ki,S.getTerrainDatasOfIntersectRectangle=Au,S.getTerrainDatasOfQuadtreeTiles=qn,S.getTileRangeOfIntersectRectangle=ci,S.getTransform=Xs,S.getWorldDataOfQuantizedMeshTerrainData=Ou,S.getWorldMatrix=bs,S.getWorldTransformInfo=Xn,S.isMatrixPrimitive=an,S.isPositionListPrimitive=ls,S.isPositionPrimitive=un,S.isPrimitiveObject=ri,S.localQuaternionToWorld=is,S.makeMatrixReferFrame=vt,S.matrix4ToHeadingPitchRoll=On,S.quaternionToHeadingPitchRoll=hi,S.resetTransformInPrimitive=us,S.resetTransformInfoPrimitive=Mi,S.rotateMatrixReferFrame=Li,S.rotationInfoToQuaternion=Bt,S.scaleBoxGraphics=rs,S.scaleCylinderGraphics=hs,S.scaleEllipseGraphics=ms,S.scaleEllipsoidGraphics=Zs,S.scaleMatrixReferFrame=xi,S.scaleModelGraphics=Gs,S.scalePlaneGraphics=Ws,S.scalePoints=Ri,S.transformCorridorGraphics=ps,S.transformEntity=gi,S.transformInfoToMatrix=Gi,S.transformPolygonGraphics=Vs,S.transformPolygonHierarchy=An,S.transformPolylineGraphics=ys,S.transformPolylineVolumeGraphics=Ls,S.transformWallGraphics=xs,S.translationMatrixReferFrame=yi,S.worldMatrixToLocal=mi,S.worldQuaternionToLocal=Zi,Object.defineProperty(S,Symbol.toStringTag,{value:"Module"}),S}({},cesium);
|
|
27
|
+
</path>`,l}};b.Polygon=en;const Za=(...n)=>new b.Polygon(...n);b.polygon=Za;const{Circle:Pl,Line:Wd,Point:Vd,Vector:Hn,Utils:Ql}=b;class dn{constructor(t){this.circle=t}get inversion_circle(){return this.circle}static inversePoint(t,l){const s=new Hn(t.pc,l),e=t.r*t.r,d=s.dot(s);return Ql.EQ_0(d)?new Vd(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(Ql.EQ(s,l.r)){let e=t.r*t.r/(2*l.r),d=new Hn(t.pc,l.pc);d=d.normalize();let i=t.pc.translate(d.multiply(e));return new Wd(i,d)}else{let e=new Hn(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 Pl(i,c)}}static inverseLine(t,l){const[s,e]=t.pc.distanceTo(l);if(Ql.EQ_0(s))return l.clone();{let d=t.r*t.r/(2*s),i=new Hn(t.pc,e.end);return i=i.multiply(d/s),new Pl(t.pc.translate(i),d)}}inverse(t){if(t instanceof Vd)return dn.inversePoint(this.circle,t);if(t instanceof Pl)return dn.inverseCircle(this.circle,t);if(t instanceof Wd)return dn.inverseLine(this.circle,t)}}b.Inversion=dn;const Ga=n=>new b.Inversion(n);b.inversion=Ga;class Y{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 Y.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,a;if(b.Utils.GE(i,0)&&b.Utils.GE(c,0)){let X=l.tangentInStart();return o=Math.abs(X.cross(e)),a=l.start.translate(X.multiply(X.dot(e))),[o,new b.Segment(t,a)]}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]=Y.point2circle(t,s),i.end.on(l)&&e.push(Y.point2circle(t,s)),e.push(Y.point2point(t,l.start)),e.push(Y.point2point(t,l.end)),Y.sort(e),e[0]}static point2edge(t,l){return l.shape instanceof b.Segment?Y.point2segment(t,l.shape):Y.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(Y.point2line(t.start,l)),e.push(Y.point2line(t.end,l)),Y.sort(e),e[0]}static segment2segment(t,l){let s=Tn(t,l);if(s.length>0)return[0,new b.Segment(s[0],s[0])];let e=[],d,i;return[d,i]=Y.point2segment(l.start,t),e.push([d,i.reverse()]),[d,i]=Y.point2segment(l.end,t),e.push([d,i.reverse()]),e.push(Y.point2segment(t.start,l)),e.push(Y.point2segment(t.end,l)),Y.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]=Y.point2line(l.center,e);if(b.Utils.GE(d,l.r)&&i.end.on(t))return Y.point2circle(i.end,l);{let[c,o]=Y.point2circle(t.start,l),[a,X]=Y.point2circle(t.end,l);return b.Utils.LT(c,a)?[c,o]:[a,X]}}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]=Y.point2line(d.center,e);if(b.Utils.GE(i,d.r)&&c.end.on(t)){let[u,h]=Y.point2circle(c.end,d);if(h.end.on(l))return[u,h]}let o=[];o.push(Y.point2arc(t.start,l)),o.push(Y.point2arc(t.end,l));let a,X;return[a,X]=Y.point2segment(l.start,t),o.push([a,X.reverse()]),[a,X]=Y.point2segment(l.end,t),o.push([a,X.reverse()]),Y.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 Y.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(Y.point2point(d[0],i[0])),c.push(Y.point2point(d[0],i[1])),c.push(Y.point2point(d[1],i[0])),c.push(Y.point2point(d[1],i[1])),Y.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]=Y.point2line(t.center,l),[i,c]=Y.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]=Y.point2line(e.center,l);if(b.Utils.GE(d,e.r)){let[c,o]=Y.point2circle(i.end,e);if(o.end.on(t))return[c,o]}else{let c=[];return c.push(Y.point2line(t.start,l)),c.push(Y.point2line(t.end,l)),Y.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]=Y.circle2circle(e,l);if(i.start.on(t))return[d,i];{let c=[];return c.push(Y.point2circle(t.start,l)),c.push(Y.point2circle(t.end,l)),Y.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]=Y.circle2circle(e,d);if(c.start.on(t)&&c.end.on(l))return[i,c];{let o=[],a,X;return[a,X]=Y.point2arc(t.start,l),X.end.on(l)&&o.push([a,X]),[a,X]=Y.point2arc(t.end,l),X.end.on(l)&&o.push([a,X]),[a,X]=Y.point2arc(l.start,t),X.end.on(t)&&o.push([a,X.reverse()]),[a,X]=Y.point2arc(l.end,t),X.end.on(t)&&o.push([a,X.reverse()]),[a,X]=Y.point2point(t.start,l.start),o.push([a,X]),[a,X]=Y.point2point(t.start,l.end),o.push([a,X]),[a,X]=Y.point2point(t.end,l.start),o.push([a,X]),[a,X]=Y.point2point(t.end,l.end),o.push([a,X]),Y.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]=Y.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,a=c*c+o*o;return[d,a]}static minmax_tree_process_level(t,l,s,e){let d,i;for(let X of l){[d,i]=Y.box2box_minmax(t.box,X.item.key);for(let u of X.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(X=>X.left.isNil()?void 0:X.left).filter(X=>X!==void 0),o=l.map(X=>X.right.isNil()?void 0:X.right).filter(X=>X!==void 0),a=[...c,...o].filter(X=>{let[u,h]=Y.box2box_minmax(t.box,X.max);return b.Utils.LE(u,s)});return s=Y.minmax_tree_process_level(t,a,s,e),s}static minmax_tree(t,l,s){let e=new ln,d=[l.index.root],i=s<Number.POSITIVE_INFINITY?s*s:Number.POSITIVE_INFINITY;return i=Y.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]=Y.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]=Y.distanceToArray(t,l.item.values);return b.Utils.LT(i,e[0])&&(e=[i,c]),[e,d]=Y.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=Y.minmax_tree(t,l,s);[e,d]=Y.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]=Y.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]=Y.distance(e.shape,d.shape);b.Utils.LT(i,s[0])&&(s=[i,c])}return s}}b.Distance=Y;const{Multiline:pa,Point:yd,Segment:Wa,Polygon:Ld}=b;function vl(n){return new yd(n.split(" ").map(Number))}function xd(n){return n.split(", ").map(vl)}function Bl(n){const t=xd(n);let l=[];for(let s=0;s<t.length-1;s++)l.push(new Wa(t[s],t[s+1]));return new pa(l)}function Va(n){return n.replace(/\(\(/,"").replace(/\)\)$/,"").split("), (").map(Bl)}function Rd(n){const t=n.replace(/\(\(/,"").replace(/\)\)$/,"").split("), ("),l=new Ld;let s;return t.forEach((e,d)=>{let i=e.split(", ").map(o=>new yd(o.split(" ").map(Number)));const c=l.addFace(i);d===0?s=c.orientation():c.orientation()===s&&c.reverse()}),l}function ya(n){const l=n.split(/\)\), \(\(/).map(d=>"(("+d+"))").map(Rd),s=new Ld;return l.reduce((d,i)=>[...d,...i?.faces],[]).forEach(d=>s.addFace([...d?.shapes])),s}function La(n){if(n.startsWith("POLYGON")){const t=n.replace(/^POLYGON /,"");return Rd(t)}else{const t=n.replace(/^MULTIPOLYGON \(\(\((.*)\)\)\)$/,"$1");return ya(t)}}function xa(n){return n.split(`
|
|
28
|
+
`).map(l=>l.match(/\(([^)]+)\)/)[1]).map(vl)}function Ra(n){return n.split(`
|
|
29
|
+
`).map(l=>l.match(/\(([^)]+)\)/)[1]).map(Bl).reduce((l,s)=>[...l,...s],[])}function Kd(n){if(n.startsWith("POINT")){const t=n.replace(/^POINT \(/,"").replace(/\)$/,"");return vl(t)}else if(n.startsWith("MULTIPOINT")){const t=n.replace(/^MULTIPOINT \(/,"").replace(/\)$/,"");return xd(t)}else if(n.startsWith("LINESTRING")){const t=n.replace(/^LINESTRING \(/,"").replace(/\)$/,"");return Bl(t)}else if(n.startsWith("MULTILINESTRING")){const t=n.replace(/^MULTILINESTRING /,"");return Va(t)}else{if(n.startsWith("POLYGON")||n.startsWith("MULTIPOLYGON"))return La(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(Kd).map(e=>e instanceof Array?e:[e]).reduce((e,d)=>[...e,...d],[])}else{if(Sd(n))return xa(n);if(zd(n))return Ra(n)}}return[]}function Sd(n){return n.split(`
|
|
30
|
+
`)?.every(t=>t.includes("POINT"))}function zd(n){return n.split(`
|
|
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);
|